tizen 2.4 release accepted/tizen_2.4_mobile tizen_2.4 accepted/tizen/2.4/mobile/20151029.035329 submit/tizen_2.4/20151028.063349 tizen_2.4_mobile_release
authorjk7744.park <jk7744.park@samsung.com>
Sat, 24 Oct 2015 07:17:05 +0000 (16:17 +0900)
committerjk7744.park <jk7744.park@samsung.com>
Sat, 24 Oct 2015 07:17:05 +0000 (16:17 +0900)
1049 files changed:
.gitignore
.ycm_extra_conf.py
CODING_STYLE
Makefile-man.am
Makefile.am
NEWS
README
TODO
autogen.sh
configure.ac
docs/libudev/libudev-sections.txt
factory/etc/nsswitch.conf [new file with mode: 0644]
factory/etc/pam.d/other [new file with mode: 0644]
factory/etc/pam.d/system-auth [new file with mode: 0644]
hwdb/20-OUI.hwdb
hwdb/20-bluetooth-vendor-product.hwdb
hwdb/20-net-ifname.hwdb
hwdb/20-pci-classes.hwdb
hwdb/20-pci-vendor-model.hwdb
hwdb/20-usb-classes.hwdb
hwdb/20-usb-vendor-model.hwdb
hwdb/60-keyboard.hwdb
hwdb/ids-update.pl
m4/acx_libwrap.m4 [deleted file]
m4/attributes.m4
man/binfmt.d.xml
man/bootctl.xml
man/bootup.xml
man/coredump.conf.xml [new file with mode: 0644]
man/coredumpctl.xml [moved from man/systemd-coredumpctl.xml with 79% similarity]
man/crypttab.xml
man/custom-html.xsl
man/daemon.xml
man/file-hierarchy.xml [new file with mode: 0644]
man/halt.xml
man/hostname.xml
man/hostnamectl.xml
man/journalctl.xml
man/journald.conf.xml
man/kernel-command-line.xml
man/kernel-install.xml
man/libsystemd-pkgconfig.xml
man/locale.conf.xml
man/localectl.xml
man/localtime.xml
man/logind.conf.xml
man/machine-id.xml
man/machine-info.xml
man/machinectl.xml
man/nss-myhostname.xml
man/os-release.xml
man/pam_systemd.xml
man/resolved.conf.xml [new file with mode: 0644]
man/sd-daemon.xml
man/sd-id128.xml
man/sd-journal.xml
man/sd-login.xml
man/sd_bus_creds_get_pid.xml
man/sd_bus_creds_new_from_pid.xml
man/sd_bus_error.xml
man/sd_bus_label_escape.xml [deleted file]
man/sd_bus_message_append.xml [new file with mode: 0644]
man/sd_bus_message_append_array.xml [new file with mode: 0644]
man/sd_bus_message_append_basic.xml [new file with mode: 0644]
man/sd_bus_message_append_string_memfd.xml [new file with mode: 0644]
man/sd_bus_message_append_strv.xml [new file with mode: 0644]
man/sd_bus_message_get_cookie.xml
man/sd_bus_message_get_monotonic_usec.xml
man/sd_bus_negotiate_fds.xml [new file with mode: 0644]
man/sd_bus_new.xml
man/sd_bus_open_user.xml
man/sd_bus_path_encode.xml [new file with mode: 0644]
man/sd_bus_request_name.xml
man/sd_event_add_time.xml [new file with mode: 0644]
man/sd_event_new.xml [new file with mode: 0644]
man/sd_get_seats.xml
man/sd_id128_get_machine.xml
man/sd_id128_randomize.xml
man/sd_id128_to_string.xml
man/sd_is_fifo.xml
man/sd_journal_add_match.xml
man/sd_journal_get_catalog.xml
man/sd_journal_get_cursor.xml
man/sd_journal_get_cutoff_realtime_usec.xml
man/sd_journal_get_data.xml
man/sd_journal_get_fd.xml
man/sd_journal_get_realtime_usec.xml
man/sd_journal_get_usage.xml
man/sd_journal_next.xml
man/sd_journal_open.xml
man/sd_journal_print.xml
man/sd_journal_query_unique.xml
man/sd_journal_seek_head.xml
man/sd_journal_stream_fd.xml
man/sd_login_monitor_new.xml
man/sd_pid_get_session.xml
man/sd_seat_get_active.xml
man/sd_session_is_active.xml
man/sd_uid_get_state.xml
man/sd_watchdog_enabled.xml
man/shutdown.xml
man/sysctl.d.xml
man/systemctl.xml
man/systemd-analyze.xml
man/systemd-ask-password-console.service.xml
man/systemd-ask-password.xml
man/systemd-binfmt.service.xml
man/systemd-bootchart.xml
man/systemd-bus-proxyd@.service.xml
man/systemd-cat.xml
man/systemd-cgls.xml
man/systemd-cgtop.xml
man/systemd-coredump.xml [new file with mode: 0644]
man/systemd-debug-generator.xml [new file with mode: 0644]
man/systemd-escape.xml [new file with mode: 0644]
man/systemd-firstboot.xml [new file with mode: 0644]
man/systemd-fsck@.service.xml
man/systemd-getty-generator.xml
man/systemd-gpt-auto-generator.xml
man/systemd-inhibit.xml
man/systemd-journal-remote.xml [new file with mode: 0644]
man/systemd-journal-upload.xml [new file with mode: 0644]
man/systemd-journald.service.xml
man/systemd-machine-id-setup.xml
man/systemd-networkd-wait-online.service.xml [new file with mode: 0644]
man/systemd-networkd.service.xml
man/systemd-nspawn.xml
man/systemd-path.xml [new file with mode: 0644]
man/systemd-readahead-replay.service.xml
man/systemd-resolved.service.xml [new file with mode: 0644]
man/systemd-run.xml
man/systemd-sleep.conf.xml
man/systemd-suspend.service.xml
man/systemd-system.conf.xml
man/systemd-sysusers.xml [new file with mode: 0644]
man/systemd-timedated.service.xml
man/systemd-timesyncd.service.xml [new file with mode: 0644]
man/systemd-tmpfiles.xml
man/systemd-tty-ask-password-agent.xml
man/systemd-udevd.service.xml
man/systemd-update-done.service.xml [new file with mode: 0644]
man/systemd-update-utmp.service.xml
man/systemd-user-sessions.service.xml
man/systemd.exec.xml
man/systemd.journal-fields.xml
man/systemd.link.xml [new file with mode: 0644]
man/systemd.mount.xml
man/systemd.netdev.xml [new file with mode: 0644]
man/systemd.network.xml [new file with mode: 0644]
man/systemd.resource-control.xml
man/systemd.service.xml
man/systemd.slice.xml
man/systemd.socket.xml
man/systemd.special.xml
man/systemd.swap.xml
man/systemd.time.xml
man/systemd.timer.xml
man/systemd.unit.xml
man/systemd.xml
man/sysusers.d.xml [new file with mode: 0644]
man/telinit.xml
man/timedatectl.xml
man/timesyncd.conf.xml [new file with mode: 0644]
man/tmpfiles.d.xml
man/udev.conf.xml [new file with mode: 0644]
man/udev.xml
man/udevadm.xml
man/user-system-options.xml
network/80-container-host0.network
network/80-container-ve.network [moved from units/org.freedesktop.DBus.busname with 75% similarity]
network/99-default.link
network/Makefile [new symlink]
packaging/systemd.manifest
packaging/systemd.spec
packaging/tizen-journald.conf
po/LINGUAS
po/de.po [new file with mode: 0644]
po/el.po [new file with mode: 0644]
po/uk.po [new file with mode: 0644]
rules/42-usb-hid-pm.rules
rules/50-udev-default.rules
rules/60-keyboard.rules
rules/60-persistent-storage.rules
rules/99-systemd.rules.in
shell-completion/Makefile [new symlink]
shell-completion/bash/.gitignore [new file with mode: 0644]
shell-completion/bash/Makefile [moved from src/libsystemd-dhcp/Makefile with 100% similarity]
shell-completion/bash/busctl
shell-completion/bash/coredumpctl [moved from shell-completion/bash/systemd-coredumpctl with 90% similarity]
shell-completion/bash/hostnamectl
shell-completion/bash/journalctl
shell-completion/bash/systemctl.in [moved from shell-completion/bash/systemctl with 88% similarity]
shell-completion/bash/systemd-analyze
shell-completion/bash/systemd-cat [new file with mode: 0644]
shell-completion/bash/systemd-cgls [new file with mode: 0644]
shell-completion/bash/systemd-cgtop [new file with mode: 0644]
shell-completion/bash/systemd-detect-virt [new file with mode: 0644]
shell-completion/bash/systemd-nspawn [new file with mode: 0644]
shell-completion/bash/systemd-run
shell-completion/zsh/.gitignore [new file with mode: 0644]
shell-completion/zsh/Makefile [moved from src/bus-driverd/Makefile with 100% similarity]
shell-completion/zsh/_busctl
shell-completion/zsh/_coredumpctl [moved from shell-completion/zsh/_systemd-coredumpctl with 54% similarity]
shell-completion/zsh/_hostnamectl
shell-completion/zsh/_localectl
shell-completion/zsh/_loginctl
shell-completion/zsh/_machinectl
shell-completion/zsh/_sd_machines
shell-completion/zsh/_sd_unit_files [new file with mode: 0644]
shell-completion/zsh/_systemctl.in [moved from shell-completion/zsh/_systemctl with 88% similarity]
shell-completion/zsh/_systemd-analyze
shell-completion/zsh/_systemd-nspawn
src/activate/activate.c
src/analyze/analyze-verify.c [new file with mode: 0644]
src/analyze/analyze-verify.h [new file with mode: 0644]
src/analyze/analyze.c
src/ask-password/ask-password.c
src/backlight/backlight.c
src/binfmt/binfmt.c
src/boot/bootctl.c
src/bootchart/bootchart.c
src/bootchart/store.c
src/bootchart/svg.c
src/bus-driverd/bus-driverd.c [deleted file]
src/bus-proxyd/bus-policy.c [new file with mode: 0644]
src/bus-proxyd/bus-policy.h [new file with mode: 0644]
src/bus-proxyd/bus-proxyd.c
src/cgls/cgls.c
src/cgroups-agent/cgroups-agent.c
src/cgtop/cgtop.c
src/core/audit-fd.c
src/core/automount.c
src/core/build.h
src/core/busname.c
src/core/busname.h
src/core/cgroup.c
src/core/cgroup.h
src/core/condition.c
src/core/dbus-busname.c
src/core/dbus-cgroup.c
src/core/dbus-client-track.c [deleted file]
src/core/dbus-execute.c
src/core/dbus-job.c
src/core/dbus-job.h
src/core/dbus-manager.c
src/core/dbus-manager.h
src/core/dbus-mount.c
src/core/dbus-scope.c
src/core/dbus-service.c
src/core/dbus-snapshot.c
src/core/dbus-socket.c
src/core/dbus-timer.c
src/core/dbus-unit.c
src/core/dbus.c
src/core/dbus.h
src/core/device.c
src/core/execute.c
src/core/execute.h
src/core/ima-setup.c
src/core/job.c
src/core/job.h
src/core/killall.c
src/core/kmod-setup.c
src/core/load-dropin.c
src/core/load-fragment-gperf.gperf.m4
src/core/load-fragment.c
src/core/load-fragment.h
src/core/locale-setup.c
src/core/loopback-setup.c
src/core/machine-id-setup.c
src/core/machine-id-setup.h
src/core/macros.systemd.in
src/core/main.c
src/core/manager.c
src/core/manager.h
src/core/mount-setup.c
src/core/mount.c
src/core/mount.h
src/core/namespace.c
src/core/namespace.h
src/core/org.freedesktop.systemd1.conf
src/core/org.freedesktop.systemd1.policy.in.in
src/core/path.c
src/core/scope.c
src/core/selinux-access.c
src/core/selinux-access.h
src/core/selinux-setup.c
src/core/service.c
src/core/service.h
src/core/show-status.c [new file with mode: 0644]
src/core/show-status.h [new file with mode: 0644]
src/core/shutdown.c
src/core/slice.c
src/core/smack-setup.c
src/core/snapshot.c
src/core/socket.c
src/core/socket.h
src/core/swap.c
src/core/switch-root.c
src/core/system.conf
src/core/systemd.pc.in
src/core/tcpwrap.c [deleted file]
src/core/timer.c
src/core/timer.h
src/core/transaction.c
src/core/umount.c
src/core/unit-printf.c
src/core/unit.c
src/core/unit.h
src/core/user.conf
src/cryptsetup/cryptsetup-generator.c
src/cryptsetup/cryptsetup.c
src/dbus1-generator/dbus1-generator.c
src/debug-generator/Makefile [new symlink]
src/debug-generator/debug-generator.c [new file with mode: 0644]
src/delta/delta.c
src/detect-virt/detect-virt.c
src/efi-boot-generator/efi-boot-generator.c
src/escape/Makefile [new symlink]
src/escape/escape.c [new file with mode: 0644]
src/firstboot/Makefile [new symlink]
src/firstboot/firstboot.c [new file with mode: 0644]
src/fsck/fsck.c
src/fstab-generator/fstab-generator.c
src/getty-generator/getty-generator.c
src/gpt-auto-generator/gpt-auto-generator.c
src/gudev/gudevclient.c
src/gudev/gudevdevice.c
src/gudev/libgudev-1.0.sym [new file with mode: 0644]
src/hostname/hostnamectl.c
src/hostname/hostnamed.c
src/initctl/initctl.c
src/journal-remote/.gitignore [new file with mode: 0644]
src/journal-remote/Makefile [new symlink]
src/journal-remote/browse.html [moved from src/journal/browse.html with 100% similarity]
src/journal-remote/journal-gatewayd.c [moved from src/journal/journal-gatewayd.c with 87% similarity]
src/journal-remote/journal-remote-parse.c [new file with mode: 0644]
src/journal-remote/journal-remote-parse.h [new file with mode: 0644]
src/journal-remote/journal-remote-write.c [new file with mode: 0644]
src/journal-remote/journal-remote-write.h [new file with mode: 0644]
src/journal-remote/journal-remote.c [new file with mode: 0644]
src/journal-remote/journal-remote.conf.in [new file with mode: 0644]
src/journal-remote/journal-remote.h [new file with mode: 0644]
src/journal-remote/journal-upload-journal.c [new file with mode: 0644]
src/journal-remote/journal-upload.c [new file with mode: 0644]
src/journal-remote/journal-upload.conf.in [new file with mode: 0644]
src/journal-remote/journal-upload.h [new file with mode: 0644]
src/journal-remote/log-generator.py [new file with mode: 0755]
src/journal-remote/microhttpd-util.c [new file with mode: 0644]
src/journal-remote/microhttpd-util.h [new file with mode: 0644]
src/journal/cat.c
src/journal/catalog.c
src/journal/compress.c
src/journal/compress.h
src/journal/coredump-vacuum.c [new file with mode: 0644]
src/journal/coredump-vacuum.h [moved from src/journal/microhttpd-util.h with 82% similarity]
src/journal/coredump.c
src/journal/coredump.conf [new file with mode: 0644]
src/journal/coredumpctl.c
src/journal/journal-authenticate.c
src/journal/journal-def.h
src/journal/journal-file.c
src/journal/journal-file.h
src/journal/journal-internal.h
src/journal/journal-qrcode.h
src/journal/journal-send.c
src/journal/journal-vacuum.c
src/journal/journal-verify.c
src/journal/journalctl.c
src/journal/journald-console.c
src/journal/journald-gperf.gperf
src/journal/journald-kmsg.c
src/journal/journald-native.c
src/journal/journald-native.h
src/journal/journald-server.c
src/journal/journald-server.h
src/journal/journald-stream.c
src/journal/journald-syslog.c
src/journal/journald-wall.c [new file with mode: 0644]
src/journal/journald-wall.h [new file with mode: 0644]
src/journal/journald.c
src/journal/journald.conf
src/journal/sd-journal.c
src/journal/stacktrace.c [new file with mode: 0644]
src/journal/stacktrace.h [new file with mode: 0644]
src/journal/test-catalog.c
src/journal/test-compress-benchmark.c [new file with mode: 0644]
src/journal/test-compress.c [new file with mode: 0644]
src/journal/test-coredump-vacuum.c [new file with mode: 0644]
src/journal/test-journal-flush.c
src/journal/test-journal-init.c
src/journal/test-journal-interleaving.c
src/journal/test-journal-match.c
src/journal/test-journal-send.c
src/journal/test-journal-stream.c
src/journal/test-journal-verify.c
src/journal/test-journal.c
src/journal/test-mmap-cache.c
src/kernel-install/90-loaderentry.install
src/kernel-install/Makefile [new symlink]
src/libsystemd-dhcp/dhcp-lease.c [deleted file]
src/libsystemd-dhcp/dhcp-network.c [deleted file]
src/libsystemd-dhcp/dhcp-option.c [deleted file]
src/libsystemd-dhcp/dhcp-packet.c [deleted file]
src/libsystemd-dhcp/sd-dhcp-client.c [deleted file]
src/libsystemd-network/Makefile [new symlink]
src/libsystemd-network/dhcp-internal.h [moved from src/libsystemd-dhcp/dhcp-internal.h with 59% similarity]
src/libsystemd-network/dhcp-lease-internal.h [moved from src/libsystemd-dhcp/dhcp-lease.h with 65% similarity]
src/libsystemd-network/dhcp-network.c [new file with mode: 0644]
src/libsystemd-network/dhcp-option.c [new file with mode: 0644]
src/libsystemd-network/dhcp-packet.c [new file with mode: 0644]
src/libsystemd-network/dhcp-protocol.h [moved from src/libsystemd-dhcp/dhcp-protocol.h with 77% similarity]
src/libsystemd-network/dhcp-server-internal.h [new file with mode: 0644]
src/libsystemd-network/dhcp6-internal.h [new file with mode: 0644]
src/libsystemd-network/dhcp6-lease-internal.h [new file with mode: 0644]
src/libsystemd-network/dhcp6-network.c [new file with mode: 0644]
src/libsystemd-network/dhcp6-option.c [new file with mode: 0644]
src/libsystemd-network/dhcp6-protocol.h [new file with mode: 0644]
src/libsystemd-network/ipv4ll-internal.h [new file with mode: 0644]
src/libsystemd-network/ipv4ll-network.c [new file with mode: 0644]
src/libsystemd-network/ipv4ll-packet.c [new file with mode: 0644]
src/libsystemd-network/network-internal.c [moved from src/shared/net-util.c with 52% similarity]
src/libsystemd-network/network-internal.h [moved from src/shared/net-util.h with 76% similarity]
src/libsystemd-network/sd-dhcp-client.c [new file with mode: 0644]
src/libsystemd-network/sd-dhcp-lease.c [new file with mode: 0644]
src/libsystemd-network/sd-dhcp-server.c [new file with mode: 0644]
src/libsystemd-network/sd-dhcp6-client.c [new file with mode: 0644]
src/libsystemd-network/sd-dhcp6-lease.c [new file with mode: 0644]
src/libsystemd-network/sd-icmp6-nd.c [new file with mode: 0644]
src/libsystemd-network/sd-ipv4ll.c [new file with mode: 0644]
src/libsystemd-network/test-dhcp-client.c [moved from src/libsystemd-dhcp/test-dhcp-client.c with 86% similarity]
src/libsystemd-network/test-dhcp-option.c [moved from src/libsystemd-dhcp/test-dhcp-option.c with 73% similarity]
src/libsystemd-network/test-dhcp-server.c [new file with mode: 0644]
src/libsystemd-network/test-dhcp6-client.c [new file with mode: 0644]
src/libsystemd-network/test-icmp6-rs.c [new file with mode: 0644]
src/libsystemd-network/test-ipv4ll.c [new file with mode: 0644]
src/libsystemd-terminal/subterm.c [new file with mode: 0644]
src/libsystemd-terminal/term-charset.c [new file with mode: 0644]
src/libsystemd-terminal/term-internal.h [new file with mode: 0644]
src/libsystemd-terminal/term-page.c [new file with mode: 0644]
src/libsystemd-terminal/term-parser.c [new file with mode: 0644]
src/libsystemd-terminal/term-screen.c [new file with mode: 0644]
src/libsystemd-terminal/term-wcwidth.c [new file with mode: 0644]
src/libsystemd-terminal/test-term-page.c [new file with mode: 0644]
src/libsystemd-terminal/test-term-parser.c [new file with mode: 0644]
src/libsystemd-terminal/test-unifont.c [new file with mode: 0644]
src/libsystemd-terminal/unifont-def.h [new file with mode: 0644]
src/libsystemd-terminal/unifont-glyph-array.bin [new file with mode: 0644]
src/libsystemd-terminal/unifont-internal.h [new file with mode: 0644]
src/libsystemd-terminal/unifont.c [new file with mode: 0644]
src/libsystemd-terminal/unifont.hex [new file with mode: 0644]
src/libsystemd/libsystemd.sym.m4
src/libsystemd/sd-bus/PORTING-DBUS1
src/libsystemd/sd-bus/bus-bloom.c
src/libsystemd/sd-bus/bus-container.c
src/libsystemd/sd-bus/bus-control.c
src/libsystemd/sd-bus/bus-control.h
src/libsystemd/sd-bus/bus-convenience.c
src/libsystemd/sd-bus/bus-creds.c
src/libsystemd/sd-bus/bus-dump.c
src/libsystemd/sd-bus/bus-internal.h
src/libsystemd/sd-bus/bus-kernel.c
src/libsystemd/sd-bus/bus-kernel.h
src/libsystemd/sd-bus/bus-match.c
src/libsystemd/sd-bus/bus-match.h
src/libsystemd/sd-bus/bus-message.c
src/libsystemd/sd-bus/bus-message.h
src/libsystemd/sd-bus/bus-objects.c
src/libsystemd/sd-bus/bus-objects.h
src/libsystemd/sd-bus/bus-protocol.h
src/libsystemd/sd-bus/bus-slot.c [new file with mode: 0644]
src/libsystemd/sd-bus/bus-slot.h [new file with mode: 0644]
src/libsystemd/sd-bus/bus-socket.c
src/libsystemd/sd-bus/bus-track.c [new file with mode: 0644]
src/libsystemd/sd-bus/bus-track.h [new file with mode: 0644]
src/libsystemd/sd-bus/bus-util.c
src/libsystemd/sd-bus/bus-util.h
src/libsystemd/sd-bus/busctl.c
src/libsystemd/sd-bus/kdbus.h
src/libsystemd/sd-bus/sd-bus.c
src/libsystemd/sd-bus/sd-memfd.c
src/libsystemd/sd-bus/test-bus-chat.c
src/libsystemd/sd-bus/test-bus-gvariant.c
src/libsystemd/sd-bus/test-bus-kernel-benchmark.c
src/libsystemd/sd-bus/test-bus-kernel-bloom.c
src/libsystemd/sd-bus/test-bus-kernel.c
src/libsystemd/sd-bus/test-bus-marshal.c
src/libsystemd/sd-bus/test-bus-match.c
src/libsystemd/sd-bus/test-bus-objects.c
src/libsystemd/sd-daemon/Makefile [new symlink]
src/libsystemd/sd-daemon/sd-daemon.c
src/libsystemd/sd-event/event-util.h
src/libsystemd/sd-event/sd-event.c
src/libsystemd/sd-event/test-event.c
src/libsystemd/sd-login/Makefile [new symlink]
src/libsystemd/sd-login/sd-login.c [moved from src/login/sd-login.c with 77% similarity]
src/libsystemd/sd-login/test-login.c [moved from src/login/test-login.c with 92% similarity]
src/libsystemd/sd-network/Makefile [new symlink]
src/libsystemd/sd-network/network-util.c [new file with mode: 0644]
src/libsystemd/sd-network/network-util.h [new file with mode: 0644]
src/libsystemd/sd-network/sd-network.c [new file with mode: 0644]
src/libsystemd/sd-path/Makefile [new symlink]
src/libsystemd/sd-path/sd-path.c [new file with mode: 0644]
src/libsystemd/sd-resolve/resolve-util.h
src/libsystemd/sd-resolve/sd-resolve.c
src/libsystemd/sd-resolve/test-resolve.c
src/libsystemd/sd-rtnl/local-addresses.c [new file with mode: 0644]
src/libsystemd/sd-rtnl/local-addresses.h [new file with mode: 0644]
src/libsystemd/sd-rtnl/rtnl-internal.h
src/libsystemd/sd-rtnl/rtnl-message.c
src/libsystemd/sd-rtnl/rtnl-types.c [new file with mode: 0644]
src/libsystemd/sd-rtnl/rtnl-types.h [new file with mode: 0644]
src/libsystemd/sd-rtnl/rtnl-util.c
src/libsystemd/sd-rtnl/rtnl-util.h
src/libsystemd/sd-rtnl/sd-rtnl.c
src/libsystemd/sd-rtnl/test-rtnl.c
src/libudev/libudev-device-private.c
src/libudev/libudev-device.c
src/libudev/libudev-hwdb.c
src/libudev/libudev-monitor.c
src/libudev/libudev-private.h
src/libudev/libudev-queue-private.c [deleted file]
src/libudev/libudev-queue.c
src/libudev/libudev.h
src/libudev/libudev.sym
src/locale/generate-kbd-model-map [deleted file]
src/locale/localectl.c
src/locale/localed.c
src/login/70-uaccess.rules
src/login/inhibit.c
src/login/loginctl.c
src/login/logind-acl.c
src/login/logind-action.c
src/login/logind-button.c
src/login/logind-core.c
src/login/logind-dbus.c
src/login/logind-gperf.gperf
src/login/logind-inhibit.c
src/login/logind-seat-dbus.c
src/login/logind-seat.c
src/login/logind-session-dbus.c
src/login/logind-session.c
src/login/logind-session.h
src/login/logind-user-dbus.c
src/login/logind-user.c
src/login/logind-user.h
src/login/logind.c
src/login/logind.conf
src/login/logind.h
src/login/org.freedesktop.login1.conf
src/login/org.freedesktop.login1.policy.in
src/login/pam_systemd.c [moved from src/login/pam-module.c with 97% similarity]
src/login/pam_systemd.sym [new file with mode: 0644]
src/login/sysfs-show.c
src/login/systemd-user
src/login/test-inhibit.c
src/machine-id-setup/machine-id-setup-main.c
src/machine/machine-dbus.c
src/machine/machine.c
src/machine/machine.h
src/machine/machinectl.c
src/machine/machined-dbus.c
src/machine/machined.c
src/machine/machined.h
src/machine/org.freedesktop.machine1.conf
src/modules-load/modules-load.c
src/network/networkctl.c [new file with mode: 0644]
src/network/networkd-address-pool.c [new file with mode: 0644]
src/network/networkd-address.c
src/network/networkd-dhcp4.c [new file with mode: 0644]
src/network/networkd-ipv4ll.c [new file with mode: 0644]
src/network/networkd-link.c
src/network/networkd-link.h [new file with mode: 0644]
src/network/networkd-manager.c
src/network/networkd-netdev-bond.c [new file with mode: 0644]
src/network/networkd-netdev-bond.h [new file with mode: 0644]
src/network/networkd-netdev-bridge.c [new file with mode: 0644]
src/network/networkd-netdev-bridge.h [new file with mode: 0644]
src/network/networkd-netdev-dummy.c [new file with mode: 0644]
src/network/networkd-netdev-dummy.h [new file with mode: 0644]
src/network/networkd-netdev-gperf.gperf
src/network/networkd-netdev-macvlan.c [new file with mode: 0644]
src/network/networkd-netdev-macvlan.h [new file with mode: 0644]
src/network/networkd-netdev-tunnel.c [new file with mode: 0644]
src/network/networkd-netdev-tunnel.h [new file with mode: 0644]
src/network/networkd-netdev-tuntap.c [new file with mode: 0644]
src/network/networkd-netdev-tuntap.h [new file with mode: 0644]
src/network/networkd-netdev-veth.c [new file with mode: 0644]
src/network/networkd-netdev-veth.h [new file with mode: 0644]
src/network/networkd-netdev-vlan.c [new file with mode: 0644]
src/network/networkd-netdev-vlan.h [new file with mode: 0644]
src/network/networkd-netdev-vxlan.c [new file with mode: 0644]
src/network/networkd-netdev-vxlan.h [new file with mode: 0644]
src/network/networkd-netdev.c
src/network/networkd-netdev.h [new file with mode: 0644]
src/network/networkd-network-gperf.gperf
src/network/networkd-network.c
src/network/networkd-route.c
src/network/networkd-wait-online-link.c [new file with mode: 0644]
src/network/networkd-wait-online-link.h [new file with mode: 0644]
src/network/networkd-wait-online-manager.c [new file with mode: 0644]
src/network/networkd-wait-online.c [new file with mode: 0644]
src/network/networkd-wait-online.h [moved from src/core/dbus-client-track.h with 54% similarity]
src/network/networkd.c
src/network/networkd.h
src/network/test-network-tables.c [new file with mode: 0644]
src/network/test-network.c
src/notify/notify.c
src/nspawn/nspawn.c
src/nss-myhostname/ifconf.h [deleted file]
src/nss-myhostname/netlink.c [deleted file]
src/nss-myhostname/nss-myhostname.c
src/nss-myhostname/nss-myhostname.sym [new file with mode: 0644]
src/nss-mymachines/Makefile [new symlink]
src/nss-mymachines/nss-mymachines.c [new file with mode: 0644]
src/nss-mymachines/nss-mymachines.sym [new file with mode: 0644]
src/nss-resolve/Makefile [new symlink]
src/nss-resolve/nss-resolve.c [new file with mode: 0644]
src/nss-resolve/nss-resolve.sym [new file with mode: 0644]
src/path/Makefile [new symlink]
src/path/path.c [new file with mode: 0644]
src/python-systemd/_daemon.c
src/python-systemd/_journal.c
src/python-systemd/_reader.c
src/python-systemd/id128.c
src/python-systemd/journal.py
src/quotacheck/quotacheck.c
src/readahead/readahead-collect.c
src/readahead/readahead-common.c
src/readahead/readahead-replay.c
src/readahead/readahead.c
src/readahead/test-ssd.c [moved from src/journal/microhttpd-util.c with 60% similarity]
src/reply-password/reply-password.c
src/resolve-host/Makefile [new symlink]
src/resolve-host/resolve-host.c [new file with mode: 0644]
src/resolve/.gitignore [new file with mode: 0644]
src/resolve/Makefile [new symlink]
src/resolve/dns-type.c [new file with mode: 0644]
src/resolve/dns-type.h [new file with mode: 0644]
src/resolve/org.freedesktop.resolve1.conf [new file with mode: 0644]
src/resolve/org.freedesktop.resolve1.service [new file with mode: 0644]
src/resolve/resolved-bus.c [new file with mode: 0644]
src/resolve/resolved-bus.h [moved from src/core/tcpwrap.h with 87% similarity]
src/resolve/resolved-conf.c [new file with mode: 0644]
src/resolve/resolved-conf.h [new file with mode: 0644]
src/resolve/resolved-def.h [new file with mode: 0644]
src/resolve/resolved-dns-answer.c [new file with mode: 0644]
src/resolve/resolved-dns-answer.h [new file with mode: 0644]
src/resolve/resolved-dns-cache.c [new file with mode: 0644]
src/resolve/resolved-dns-cache.h [new file with mode: 0644]
src/resolve/resolved-dns-domain.c [new file with mode: 0644]
src/resolve/resolved-dns-domain.h [new file with mode: 0644]
src/resolve/resolved-dns-packet.c [new file with mode: 0644]
src/resolve/resolved-dns-packet.h [new file with mode: 0644]
src/resolve/resolved-dns-query.c [new file with mode: 0644]
src/resolve/resolved-dns-query.h [new file with mode: 0644]
src/resolve/resolved-dns-question.c [new file with mode: 0644]
src/resolve/resolved-dns-question.h [new file with mode: 0644]
src/resolve/resolved-dns-rr.c [new file with mode: 0644]
src/resolve/resolved-dns-rr.h [new file with mode: 0644]
src/resolve/resolved-dns-scope.c [new file with mode: 0644]
src/resolve/resolved-dns-scope.h [new file with mode: 0644]
src/resolve/resolved-dns-server.c [new file with mode: 0644]
src/resolve/resolved-dns-server.h [new file with mode: 0644]
src/resolve/resolved-dns-stream.c [new file with mode: 0644]
src/resolve/resolved-dns-stream.h [new file with mode: 0644]
src/resolve/resolved-dns-transaction.c [new file with mode: 0644]
src/resolve/resolved-dns-transaction.h [new file with mode: 0644]
src/resolve/resolved-dns-zone.c [new file with mode: 0644]
src/resolve/resolved-dns-zone.h [new file with mode: 0644]
src/resolve/resolved-gperf.gperf [new file with mode: 0644]
src/resolve/resolved-link.c [new file with mode: 0644]
src/resolve/resolved-link.h [new file with mode: 0644]
src/resolve/resolved-manager.c [new file with mode: 0644]
src/resolve/resolved-manager.h [new file with mode: 0644]
src/resolve/resolved.c [new file with mode: 0644]
src/resolve/resolved.conf.in [new file with mode: 0644]
src/resolve/test-dns-domain.c [new file with mode: 0644]
src/run/run.c
src/shared/.gitignore
src/shared/acl-util.c
src/shared/acl-util.h
src/shared/af-list.c [new file with mode: 0644]
src/shared/af-list.h [new file with mode: 0644]
src/shared/architecture.c
src/shared/architecture.h
src/shared/arphrd-list.c [new file with mode: 0644]
src/shared/arphrd-list.h [new file with mode: 0644]
src/shared/ask-password-api.c
src/shared/ask-password-api.h
src/shared/async.c [moved from src/core/async.c with 77% similarity]
src/shared/async.h [moved from src/core/async.h with 96% similarity]
src/shared/audit.c
src/shared/barrier.c [new file with mode: 0644]
src/shared/barrier.h [new file with mode: 0644]
src/shared/base-filesystem.c [new file with mode: 0644]
src/shared/base-filesystem.h [new file with mode: 0644]
src/shared/blkid-util.h [new file with mode: 0644]
src/shared/bus-errors.h
src/shared/calendarspec.c
src/shared/capability.c
src/shared/capability.h
src/shared/cgroup-show.c
src/shared/cgroup-util.c
src/shared/clean-ipc.c [new file with mode: 0644]
src/shared/clean-ipc.h [new file with mode: 0644]
src/shared/clock-util.c [moved from src/shared/hwclock.c with 84% similarity]
src/shared/clock-util.h [moved from src/shared/hwclock.h with 81% similarity]
src/shared/condition-util.c
src/shared/condition-util.h
src/shared/conf-files.c
src/shared/conf-parser.c
src/shared/conf-parser.h
src/shared/copy.c [new file with mode: 0644]
src/shared/copy.h [new file with mode: 0644]
src/shared/def.h
src/shared/dev-setup.c
src/shared/device-nodes.c
src/shared/dropin.c [new file with mode: 0644]
src/shared/dropin.h [new file with mode: 0644]
src/shared/efivars.c
src/shared/env-util.c
src/shared/exit-status.c
src/shared/exit-status.h
src/shared/fdset.c
src/shared/fileio-label.c
src/shared/fileio-label.h
src/shared/fileio.c
src/shared/fileio.h
src/shared/generator.c [new file with mode: 0644]
src/shared/generator.h [new file with mode: 0644]
src/shared/gpt.h [new file with mode: 0644]
src/shared/hashmap.c
src/shared/hashmap.h
src/shared/in-addr-util.c [new file with mode: 0644]
src/shared/in-addr-util.h [new file with mode: 0644]
src/shared/install.c
src/shared/install.h
src/shared/label.c
src/shared/label.h
src/shared/list.h
src/shared/locale-util.c [new file with mode: 0644]
src/shared/locale-util.h [new file with mode: 0644]
src/shared/log.c
src/shared/log.h
src/shared/login-shared.c [moved from src/login/login-shared.c with 100% similarity]
src/shared/login-shared.h [moved from src/login/login-shared.h with 100% similarity]
src/shared/logs-show.c
src/shared/logs-show.h
src/shared/macro.h
src/shared/missing.h
src/shared/mkdir.c
src/shared/mkdir.h
src/shared/nss-util.h [new file with mode: 0644]
src/shared/output-mode.h
src/shared/pager.c
src/shared/pager.h
src/shared/path-lookup.c
src/shared/path-lookup.h
src/shared/path-util.c
src/shared/path-util.h
src/shared/pty.c [new file with mode: 0644]
src/shared/pty.h [new file with mode: 0644]
src/shared/ring.c [new file with mode: 0644]
src/shared/ring.h [new file with mode: 0644]
src/shared/set.c
src/shared/set.h
src/shared/sleep-config.c
src/shared/smack-util.c
src/shared/smack-util.h
src/shared/socket-label.c
src/shared/socket-util.c
src/shared/socket-util.h
src/shared/spawn-polkit-agent.c
src/shared/special.h
src/shared/strv.c
src/shared/strv.h
src/shared/test-tables.h
src/shared/time-dst.c
src/shared/time-util.c
src/shared/time-util.h
src/shared/udev-util.h
src/shared/uid-range.c [new file with mode: 0644]
src/shared/uid-range.h [new file with mode: 0644]
src/shared/unit-name.c
src/shared/utf8.c
src/shared/utf8.h
src/shared/util.c
src/shared/util.h
src/shared/utmp-wtmp.c
src/shared/utmp-wtmp.h
src/shared/virt.c
src/shared/watchdog.c
src/shared/xml.c
src/shared/xml.h
src/shutdownd/shutdownd.c
src/sleep/sleep.c
src/socket-proxy/socket-proxyd.c
src/sysctl/sysctl.c
src/system-update-generator/system-update-generator.c
src/systemctl/systemctl.c
src/systemd/_sd-common.h
src/systemd/sd-bus.h
src/systemd/sd-daemon.h
src/systemd/sd-dhcp-client.h
src/systemd/sd-dhcp-lease.h [new file with mode: 0644]
src/systemd/sd-dhcp-server.h [new file with mode: 0644]
src/systemd/sd-dhcp6-client.h [new file with mode: 0644]
src/systemd/sd-dhcp6-lease.h [new file with mode: 0644]
src/systemd/sd-event.h
src/systemd/sd-icmp6-nd.h [new file with mode: 0644]
src/systemd/sd-id128.h
src/systemd/sd-ipv4ll.h [new file with mode: 0644]
src/systemd/sd-login.h
src/systemd/sd-network.h [new file with mode: 0644]
src/systemd/sd-path.h [new file with mode: 0644]
src/systemd/sd-readahead.h
src/systemd/sd-resolve.h
src/systemd/sd-rtnl.h
src/systemd/sd-shutdown.h
src/sysusers/Makefile [new symlink]
src/sysusers/sysusers.c [new file with mode: 0644]
src/sysv-generator/Makefile [new file with mode: 0644]
src/sysv-generator/sysv-generator.c [new file with mode: 0644]
src/test/test-architecture.c
src/test/test-async.c [new file with mode: 0644]
src/test/test-barrier.c [new file with mode: 0644]
src/test/test-capability.c [new file with mode: 0644]
src/test/test-cgroup-mask.c
src/test/test-cgroup-util.c
src/test/test-condition-util.c [new file with mode: 0644]
src/test/test-conf-files.c [new file with mode: 0644]
src/test/test-daemon.c
src/test/test-date.c
src/test/test-engine.c
src/test/test-fdset.c [new file with mode: 0644]
src/test/test-fileio.c
src/test/test-hashmap.c
src/test/test-id128.c
src/test/test-install.c
src/test/test-ipcrm.c [new file with mode: 0644]
src/test/test-libudev.c
src/test/test-log.c
src/test/test-namespace.c
src/test/test-ns.c
src/test/test-path-util.c
src/test/test-pty.c [new file with mode: 0644]
src/test/test-ratelimit.c [new file with mode: 0644]
src/test/test-ring.c [new file with mode: 0644]
src/test/test-rtnl-manual.c [new file with mode: 0644]
src/test/test-sched-prio.c
src/test/test-socket-util.c [new file with mode: 0644]
src/test/test-strv.c
src/test/test-tables.c
src/test/test-time.c
src/test/test-udev.c
src/test/test-uid-range.c [new file with mode: 0644]
src/test/test-unit-file.c
src/test/test-unit-name.c
src/test/test-util.c
src/test/test-xml.c
src/timedate/timedatectl.c
src/timedate/timedated.c
src/timesync/.gitignore [new file with mode: 0644]
src/timesync/90-systemd.list [new file with mode: 0644]
src/timesync/Makefile [new symlink]
src/timesync/timesyncd-conf.c [new file with mode: 0644]
src/timesync/timesyncd-conf.h [new file with mode: 0644]
src/timesync/timesyncd-gperf.gperf [new file with mode: 0644]
src/timesync/timesyncd-manager.c [new file with mode: 0644]
src/timesync/timesyncd-manager.h [new file with mode: 0644]
src/timesync/timesyncd-server.c [new file with mode: 0644]
src/timesync/timesyncd-server.h [new file with mode: 0644]
src/timesync/timesyncd.c [new file with mode: 0644]
src/timesync/timesyncd.conf.in [new file with mode: 0644]
src/tmpfiles/tmpfiles.c
src/tty-ask-password-agent/tty-ask-password-agent.c
src/udev/accelerometer/Makefile [new symlink]
src/udev/accelerometer/accelerometer.c
src/udev/ata_id/Makefile [new symlink]
src/udev/ata_id/ata_id.c
src/udev/cdrom_id/Makefile [new symlink]
src/udev/cdrom_id/cdrom_id.c
src/udev/net/ethtool-util.c
src/udev/net/link-config-gperf.gperf
src/udev/net/link-config.c
src/udev/net/link-config.h
src/udev/scsi_id/Makefile [new symlink]
src/udev/scsi_id/scsi_id.c
src/udev/scsi_id/scsi_serial.c
src/udev/udev-builtin-blkid.c
src/udev/udev-builtin-btrfs.c
src/udev/udev-builtin-firmware.c
src/udev/udev-builtin-hwdb.c
src/udev/udev-builtin-input_id.c
src/udev/udev-builtin-keyboard.c
src/udev/udev-builtin-kmod.c
src/udev/udev-builtin-net_id.c
src/udev/udev-builtin-net_setup_link.c
src/udev/udev-builtin-path_id.c
src/udev/udev-builtin-uaccess.c
src/udev/udev-builtin-usb_id.c
src/udev/udev-builtin.c
src/udev/udev-ctrl.c
src/udev/udev-event.c
src/udev/udev-node.c
src/udev/udev-rules.c
src/udev/udev-watch.c
src/udev/udev.conf
src/udev/udev.h
src/udev/udevadm-control.c
src/udev/udevadm-info.c
src/udev/udevadm-monitor.c
src/udev/udevadm-settle.c
src/udev/udevadm-test-builtin.c
src/udev/udevadm-test.c
src/udev/udevadm-trigger.c
src/udev/udevadm.c
src/udev/udevd.c
src/update-done/Makefile [new symlink]
src/update-done/update-done.c [new file with mode: 0644]
src/update-utmp/update-utmp.c
src/vconsole/vconsole-setup.c
sysctl.d/50-coredump.conf.in
sysctl.d/50-default.conf
system-preset/90-systemd.preset [new file with mode: 0644]
system-preset/Makefile [new symlink]
sysusers.d/.gitignore [new file with mode: 0644]
sysusers.d/Makefile [new symlink]
sysusers.d/basic.conf.in [new file with mode: 0644]
sysusers.d/systemd-remote.conf [new file with mode: 0644]
sysusers.d/systemd.conf [new file with mode: 0644]
test/TEST-01-BASIC/test.sh
test/TEST-02-CRYPTSETUP/test.sh
test/basic.target [new symlink]
test/loopy.service [new file with mode: 0644]
test/loopy.service.d/compat.conf [new file with mode: 0644]
test/loopy2.service [new symlink]
test/loopy3.service [new file with mode: 0644]
test/loopy4.service [new symlink]
test/paths.target [new symlink]
test/shutdown.target [new symlink]
test/sockets.target [new symlink]
test/sysinit.target [new symlink]
test/timers.target [new symlink]
tmpfiles.d/etc.conf [new file with mode: 0644]
tmpfiles.d/legacy.conf
tmpfiles.d/systemd-remote.conf [new file with mode: 0644]
tmpfiles.d/systemd.conf [deleted file]
tmpfiles.d/systemd.conf.m4 [new file with mode: 0644]
tmpfiles.d/var.conf [new file with mode: 0644]
tools/compile-unifont.py [new file with mode: 0755]
tools/make-directive-index.py
tools/make-man-rules.py
units/.gitignore
units/basic.target
units/console-getty.service.m4.in
units/console-shell.service.m4.in
units/container-getty@.service.m4.in
units/cryptsetup-pre.target [new file with mode: 0644]
units/debug-shell.service.m4.in [moved from units/debug-shell.service.in with 91% similarity]
units/emergency.service.m4.in [moved from units/emergency.service.in with 85% similarity]
units/getty@.service.m4
units/initrd-cleanup.service.m4.in [moved from units/initrd-cleanup.service.in with 81% similarity]
units/initrd-parse-etc.service.m4.in [moved from units/initrd-parse-etc.service.in with 92% similarity]
units/initrd-switch-root.service.m4.in [moved from units/initrd-switch-root.service.in with 90% similarity]
units/initrd-udevadm-cleanup-db.service.m4.in [moved from units/initrd-udevadm-cleanup-db.service.in with 90% similarity]
units/kmod-static-nodes.service.m4.in [moved from units/kmod-static-nodes.service.in with 86% similarity]
units/ldconfig.service [new file with mode: 0644]
units/local-fs.target
units/network-online.target
units/network-pre.target [new file with mode: 0644]
units/network.target
units/org.freedesktop.hostname1.busname
units/org.freedesktop.locale1.busname
units/org.freedesktop.login1.busname
units/org.freedesktop.machine1.busname
units/org.freedesktop.resolve1.busname [new file with mode: 0644]
units/org.freedesktop.systemd1.busname [moved from units/systemd-bus-driverd.service.in with 63% similarity]
units/org.freedesktop.timedate1.busname
units/quotaon.service.m4.in [moved from units/quotaon.service.in with 90% similarity]
units/rescue.service.m4.in
units/serial-getty@.service.m4
units/sys-kernel-config.mount
units/sys-kernel-debug.mount
units/sysinit.target
units/systemd-ask-password-console.service.m4.in [moved from units/systemd-ask-password-console.service.in with 90% similarity]
units/systemd-ask-password-wall.service.m4.in [moved from units/systemd-ask-password-wall.service.in with 90% similarity]
units/systemd-backlight@.service.in
units/systemd-bootchart.service.in [new file with mode: 0644]
units/systemd-bus-proxyd.socket
units/systemd-bus-proxyd@.service.in
units/systemd-firstboot.service.in [new file with mode: 0644]
units/systemd-fsck-root.service.m4.in [moved from units/systemd-fsck-root.service.in with 90% similarity]
units/systemd-fsck@.service.m4.in [moved from units/systemd-fsck@.service.in with 90% similarity]
units/systemd-halt.service.m4.in [moved from units/systemd-halt.service.in with 88% similarity]
units/systemd-hibernate.service.m4.in [moved from units/systemd-hibernate.service.in with 88% similarity]
units/systemd-hostnamed.service.in
units/systemd-hybrid-sleep.service.m4.in [moved from units/systemd-hybrid-sleep.service.in with 88% similarity]
units/systemd-initctl.service.m4.in [moved from units/systemd-initctl.service.in with 87% similarity]
units/systemd-initctl.socket
units/systemd-journal-catalog-update.service.m4.in [new file with mode: 0644]
units/systemd-journal-flush.service.m4.in [moved from units/systemd-journal-flush.service.in with 91% similarity]
units/systemd-journal-gatewayd.service.in
units/systemd-journal-remote.service.in [new file with mode: 0644]
units/systemd-journal-remote.socket [moved from units/user/systemd-bus-driverd.service.in with 69% similarity]
units/systemd-journal-upload.service.in [new file with mode: 0644]
units/systemd-journald-dev-log.socket [new file with mode: 0644]
units/systemd-journald.service.in
units/systemd-journald.socket
units/systemd-kexec.service.m4.in [moved from units/systemd-kexec.service.in with 89% similarity]
units/systemd-localed.service.in
units/systemd-logind.service.m4.in [moved from units/systemd-logind.service.in with 94% similarity]
units/systemd-machined.service.in
units/systemd-modules-load.service.m4.in [moved from units/systemd-modules-load.service.in with 93% similarity]
units/systemd-networkd-wait-online.service.in [new file with mode: 0644]
units/systemd-networkd.service.in
units/systemd-nspawn@.service.m4.in [moved from units/systemd-nspawn@.service.in with 80% similarity]
units/systemd-poweroff.service.m4.in [moved from units/systemd-poweroff.service.in with 88% similarity]
units/systemd-readahead-collect.service.m4.in [moved from units/systemd-readahead-collect.service.in with 92% similarity]
units/systemd-readahead-done.service.m4.in [moved from units/systemd-readahead-done.service.in with 90% similarity]
units/systemd-readahead-drop.service.m4 [moved from units/systemd-readahead-drop.service with 89% similarity]
units/systemd-readahead-replay.service.m4.in [moved from units/systemd-readahead-replay.service.in with 91% similarity]
units/systemd-reboot.service.m4.in [moved from units/systemd-reboot.service.in with 88% similarity]
units/systemd-remount-fs.service.m4.in [moved from units/systemd-remount-fs.service.in with 92% similarity]
units/systemd-resolved.service.in [new file with mode: 0644]
units/systemd-shutdownd.service.m4.in [moved from units/systemd-shutdownd.service.in with 87% similarity]
units/systemd-suspend.service.m4.in [moved from units/systemd-suspend.service.in with 88% similarity]
units/systemd-sysctl.service.m4.in [moved from units/systemd-sysctl.service.in with 75% similarity]
units/systemd-sysusers.service.m4.in [new file with mode: 0644]
units/systemd-timedated.service.in
units/systemd-timesyncd.service.in [new file with mode: 0644]
units/systemd-tmpfiles-clean.service.m4.in [moved from units/systemd-tmpfiles-clean.service.in with 67% similarity]
units/systemd-tmpfiles-setup-dev.service.m4.in [moved from units/systemd-tmpfiles-setup-dev.service.in with 57% similarity]
units/systemd-tmpfiles-setup.service.m4.in [moved from units/systemd-tmpfiles-setup.service.in with 70% similarity]
units/systemd-udev-hwdb-update.service.m4.in [new file with mode: 0644]
units/systemd-udev-settle.service.m4.in [moved from units/systemd-udev-settle.service.in with 92% similarity]
units/systemd-udev-trigger.service.m4.in [moved from units/systemd-udev-trigger.service.in with 91% similarity]
units/systemd-udevd.service.m4.in [moved from units/systemd-udevd.service.in with 77% similarity]
units/systemd-update-done.service.m4.in [new file with mode: 0644]
units/systemd-update-utmp-runlevel.service.m4.in [moved from units/systemd-update-utmp-runlevel.service.in with 91% similarity]
units/systemd-update-utmp.service.m4.in [moved from units/systemd-update-utmp.service.in with 86% similarity]
units/systemd-user-sessions.service.m4.in [moved from units/systemd-user-sessions.service.in with 89% similarity]
units/time-sync.target
units/tmp.mount
units/user/.gitignore
units/user/basic.target
units/user/systemd-bus-proxyd@.service.in
units/user@.service.m4.in [moved from units/user@.service.in with 88% similarity]

index 45d4ed2..3d4a072 100644 (file)
@@ -8,11 +8,14 @@
 *.plist
 *.pyc
 *.stamp
+*.swp
 *.trs
 *~
 .deps/
 .dirstamp
 .libs/
+/*.gcda
+/*.gcno
 /*.tar.bz2
 /*.tar.gz
 /*.tar.xz
@@ -25,6 +28,7 @@
 /busctl
 /cdrom_id
 /collect
+/coredumpctl
 /coverage/
 /defined
 /exported
@@ -39,6 +43,7 @@
 /loginctl
 /machinectl
 /mtd_probe
+/networkctl
 /scsi_id
 /systemadm
 /systemctl
 /systemd-binfmt
 /systemd-bootchart
 /systemd-bus-proxyd
-/systemd-bus-driverd
 /systemd-cat
 /systemd-cgls
 /systemd-cgroups-agent
 /systemd-cgtop
 /systemd-coredump
-/systemd-coredumpctl
 /systemd-cryptsetup
 /systemd-cryptsetup-generator
 /systemd-dbus1-generator
+/systemd-debug-generator
 /systemd-delta
 /systemd-detect-virt
 /systemd-efi-boot-generator
+/systemd-escape
+/systemd-firstboot
 /systemd-fsck
 /systemd-fstab-generator
 /systemd-getty-generator
@@ -73,6 +79,8 @@
 /systemd-inhibit
 /systemd-initctl
 /systemd-journal-gatewayd
+/systemd-journal-remote
+/systemd-journal-upload
 /systemd-journald
 /systemd-kmsg-syslogd
 /systemd-localed
 /systemd-modules-load
 /systemd-multi-seat-x
 /systemd-networkd
+/systemd-networkd-wait-online
 /systemd-notify
 /systemd-nspawn
+/systemd-path
 /systemd-quotacheck
 /systemd-random-seed
 /systemd-rc-local-generator
 /systemd-remount-api-vfs
 /systemd-remount-fs
 /systemd-reply-password
+/systemd-resolve-host
+/systemd-resolved
 /systemd-rfkill
 /systemd-run
 /systemd-shutdown
 /systemd-shutdownd
 /systemd-sleep
 /systemd-socket-proxyd
+/systemd-subterm
 /systemd-sysctl
 /systemd-system-update-generator
+/systemd-sysusers
+/systemd-sysv-generator
 /systemd-timedated
+/systemd-timesyncd
 /systemd-tmpfiles
 /systemd-tty-ask-password-agent
 /systemd-uaccess
 /systemd-udevd
+/systemd-update-done
 /systemd-update-utmp
 /systemd-user-sessions
 /systemd-vconsole-setup
 /tags
 /test-architecture
+/test-async
+/test-barrier
 /test-boot-timestamp
 /test-bus-chat
+/test-bus-cleanup
 /test-bus-creds
 /test-bus-error
 /test-bus-gvariant
-/test-bus-cleanup
 /test-bus-introspect
 /test-bus-kernel
 /test-bus-kernel-benchmark
 /test-bus-signature
 /test-bus-zero-copy
 /test-calendarspec
+/test-capability
 /test-catalog
 /test-cgroup
 /test-cgroup-mask
 /test-cgroup-util
+/test-compress
+/test-compress-benchmark
+/test-condition-util
+/test-conf-files
+/test-coredump-vacuum
 /test-daemon
 /test-date
 /test-device-nodes
 /test-dhcp-client
 /test-dhcp-option
-/test-resolve
+/test-dhcp-server
+/test-dhcp6-client
+/test-dns-domain
+/test-icmp6-rs
 /test-ellipsize
 /test-engine
 /test-env-replace
 /test-event
+/test-fdset
 /test-fileio
 /test-hashmap
 /test-hostname
 /test-id128
 /test-inhibit
 /test-install
+/test-ipcrm
+/test-ipv4ll
 /test-job-type
 /test-journal
 /test-journal-enum
 /test-mmap-cache
 /test-namespace
 /test-network
+/test-network-tables
 /test-ns
 /test-path-util
 /test-prioq
+/test-ratelimit
+/test-pty
 /test-replace-var
+/test-resolve
+/test-ring
 /test-rtnl
+/test-rtnl-manual
 /test-sched-prio
 /test-sleep
+/test-socket-util
+/test-ssd
 /test-strbuf
 /test-strip-tab-ansi
 /test-strv
 /test-strxcpyx
 /test-tables
+/test-term-page
+/test-term-parser
 /test-time
 /test-tmpfiles
 /test-udev
+/test-uid-range
+/test-unifont
 /test-unit-file
 /test-unit-name
 /test-utf8
index a90610d..4edd3c8 100644 (file)
@@ -62,5 +62,6 @@ flags = Flatten(map(GetFlagsFromMakefile, [
 # these flags cause crashes in libclang, so remove them
 flags.remove('-Wlogical-op')
 flags.remove('-Wsuggest-attribute=noreturn')
+flags.remove('-Wdate-time')
 
 # vim: set et ts=2 sw=2:
index 996897b..ca3b518 100644 (file)
 - The destructors always unregister the object from the next bigger
   object, not the other way around
 
-- To minimize strict aliasing violations we prefer unions over casting
+- To minimize strict aliasing violations, we prefer unions over casting
 
-- For robustness reasons destructors should be able to destruct
+- For robustness reasons, destructors should be able to destruct
   half-initialized objects, too
 
 - Error codes are returned as negative Exxx. i.e. return -EINVAL. There
-  are some exceptions: for constructors its is OK to return NULL on
-  OOM. For lookup functions NULL is fine too for "not found".
+  are some exceptions: for constructors, it is OK to return NULL on
+  OOM. For lookup functions, NULL is fine too for "not found".
 
   Be strict with this. When you write a function that can fail due to
   more than one cause, it *really* should have "int" as return value
   for the error code.
 
-- Don't bother with error checking whether writing to stdout/stderr
+- Do not bother with error checking whether writing to stdout/stderr
   worked.
 
 - Do not log errors from "library" code, only do so from "main
-  program" code. (With one exception: it's OK to log with DEBUG level
+  program" code. (With one exception: it is OK to log with DEBUG level
   from any code, with the exception of maybe inner loops).
 
-- Always check OOM. There's no excuse. In program code you can use
+- Always check OOM. There is no excuse. In program code, you can use
   "log_oom()" for then printing a short message, but not in "library" code.
 
 - Do not issue NSS requests (that includes user name and host name
   lookups involve synchronously talking to services that we would need
   to start up
 
-- Don't synchronously talk to any other service from PID 1, due to
+- Do not synchronously talk to any other service from PID 1, due to
   risk of deadlocks
 
-- Avoid fixed sized string buffers, unless you really know the maximum
+- Avoid fixed-size string buffers, unless you really know the maximum
   size and that maximum size is small. They are a source of errors,
-  since they possibly result in truncated strings. Often it is nicer
-  to use dynamic memory, alloca() or VLAs. If you do allocate fixed
-  size strings on the stack, then it's probably only OK if you either
+  since they possibly result in truncated strings. It is often nicer
+  to use dynamic memory, alloca() or VLAs. If you do allocate fixed-size
+  strings on the stack, then it is probably only OK if you either
   use a maximum size such as LINE_MAX, or count in detail the maximum
   size a string can have. (DECIMAL_STR_MAX and DECIMAL_STR_WIDTH
   macros are your friends for this!)
@@ -54,7 +54,7 @@
   doing something wrong!
 
 - Stay uniform. For example, always use "usec_t" for time
-  values. Don't usec mix msec, and usec and whatnot.
+  values. Do not usec mix msec, and usec and whatnot.
 
 - Make use of _cleanup_free_ and friends. It makes your code much
   nicer to read!
@@ -74,9 +74,9 @@
       {
       }
 
-  But it's OK if you don't.
+  But it is OK if you do not.
 
-- Don't write "foo ()", write "foo()".
+- Do not write "foo ()", write "foo()".
 
 - Please use streq() and strneq() instead of strcmp(), strncmp() where applicable.
 
 
 - Unless you allocate an array, "double" is always the better choice
   than "float". Processors speak "double" natively anyway, so this is
-  no speed benefit, and on calls like printf() "float"s get upgraded
+  no speed benefit, and on calls like printf() "float"s get promoted
   to "double"s anyway, so there is no point.
 
-- Don't invoke functions when you allocate variables on the stack. Wrong:
+- Do not invoke functions when you allocate variables on the stack. Wrong:
 
   {
           int a = foobar();
   backwards!
 
 - Think about the types you use. If a value cannot sensibly be
-  negative don't use "int", but use "unsigned".
+  negative, do not use "int", but use "unsigned".
 
-- Don't use types like "short". They *never* make sense. Use ints,
+- Do not use types like "short". They *never* make sense. Use ints,
   longs, long longs, all in unsigned+signed fashion, and the fixed
-  size types uint32_t and so on, as well as size_t but nothing else.
+  size types uint32_t and so on, as well as size_t, but nothing else.
 
 - Public API calls (i.e. functions exported by our shared libraries)
   must be marked "_public_" and need to be prefixed with "sd_". No
   other functions should be prefixed like that.
 
-- In public API calls you *must* validate all your input arguments for
+- In public API calls, you *must* validate all your input arguments for
   programming error with assert_return() and return a sensible return
-  code. In all other calls it is recommended to check for programming
+  code. In all other calls, it is recommended to check for programming
   errors with a more brutal assert(). We are more forgiving to public
   users then for ourselves! Note that assert() and assert_return()
   really only should be used for detecting programming errors, not for
   runtime errors. assert() and assert_return() by usage of _likely_()
-  inform the compiler that he shouldn't expect these checks to fail,
+  inform the compiler that he should not expect these checks to fail,
   and they inform fellow programmers about the expected validity and
   range of parameters.
 
   on their own, "non-logging" function never log on their own and
   expect their callers to log. All functions in "library" code,
   i.e. in src/shared/ and suchlike must be "non-logging". Everytime a
-  "logging" function calls a "non-logging" function it should log
+  "logging" function calls a "non-logging" function, it should log
   about the resulting errors. If a "logging" function calls another
   "logging" function, then it should not generate log messages, so
   that log messages are not generated twice for the same errors.
 
 - Avoid static variables, except for caches and very few other
   cases. Think about thread-safety! While most of our code is never
-  used in threaded environments at least the library code should make
+  used in threaded environments, at least the library code should make
   sure it works correctly in them. Instead of doing a lot of locking
-  for that we tend to prefer using TLS to do per-thread caching (which
+  for that, we tend to prefer using TLS to do per-thread caching (which
   only works for small, fixed-size cache objects), or we disable
   caching for any thread that is not the main thread. Use
   is_main_thread() to detect whether the calling thread is the main
   thread.
+
+- Option parsing:
+  - Do not print full help() on error, be specific about the error.
+  - Do not print messages to stdout on error.
+  - Do not POSIX_ME_HARDER unless necessary, i.e. avoid "+" in option string.
index aad3f44..562ecba 100644 (file)
@@ -1,10 +1,17 @@
 # Do not edit. Generated by make-man-rules.py.
-# Regenerate with 'make all update-man-list'.
-
+# To regenerate:
+#   1. Create, update, or remove source .xml files in man/
+#   2. Run 'make update-man-list'
+#   3. Run 'make man' to generate manpages
+#
+# To make a man page conditional on a configure switch add
+# attribute conditional="ENABLE_WHAT" or conditional="WITH_WHAT"
+# to <refentry> element.
 MANPAGES += \
        man/bootup.7 \
        man/busctl.1 \
        man/daemon.7 \
+       man/file-hierarchy.7 \
        man/halt.8 \
        man/hostname.5 \
        man/journalctl.1 \
@@ -52,9 +59,12 @@ MANPAGES += \
        man/systemd-cat.1 \
        man/systemd-cgls.1 \
        man/systemd-cgtop.1 \
+       man/systemd-debug-generator.8 \
        man/systemd-delta.1 \
        man/systemd-detect-virt.1 \
        man/systemd-efi-boot-generator.8 \
+       man/systemd-escape.1 \
+       man/systemd-firstboot.1 \
        man/systemd-fsck@.service.8 \
        man/systemd-fstab-generator.8 \
        man/systemd-getty-generator.8 \
@@ -66,6 +76,7 @@ MANPAGES += \
        man/systemd-machine-id-setup.1 \
        man/systemd-notify.1 \
        man/systemd-nspawn.1 \
+       man/systemd-path.1 \
        man/systemd-remount-fs.service.8 \
        man/systemd-run.1 \
        man/systemd-shutdownd.service.8 \
@@ -75,9 +86,11 @@ MANPAGES += \
        man/systemd-sysctl.service.8 \
        man/systemd-system-update-generator.8 \
        man/systemd-system.conf.5 \
+       man/systemd-sysusers.8 \
        man/systemd-tmpfiles.8 \
        man/systemd-tty-ask-password-agent.1 \
        man/systemd-udevd.service.8 \
+       man/systemd-update-done.service.8 \
        man/systemd-update-utmp.service.8 \
        man/systemd.1 \
        man/systemd.automount.5 \
@@ -85,6 +98,7 @@ MANPAGES += \
        man/systemd.exec.5 \
        man/systemd.journal-fields.7 \
        man/systemd.kill.5 \
+       man/systemd.link.5 \
        man/systemd.mount.5 \
        man/systemd.path.5 \
        man/systemd.preset.5 \
@@ -100,9 +114,11 @@ MANPAGES += \
        man/systemd.time.7 \
        man/systemd.timer.5 \
        man/systemd.unit.5 \
+       man/sysusers.d.5 \
        man/telinit.8 \
        man/tmpfiles.d.5 \
        man/udev.7 \
+       man/udev.conf.5 \
        man/udevadm.8
 MANPAGES_ALIAS += \
        man/SD_ALERT.3 \
@@ -180,12 +196,14 @@ MANPAGES_ALIAS += \
        man/systemd-ask-password-console.path.8 \
        man/systemd-ask-password-wall.path.8 \
        man/systemd-ask-password-wall.service.8 \
+       man/systemd-firstboot.service.1 \
        man/systemd-fsck-root.service.8 \
        man/systemd-fsck.8 \
        man/systemd-hibernate.service.8 \
        man/systemd-hybrid-sleep.service.8 \
        man/systemd-initctl.8 \
        man/systemd-initctl.socket.8 \
+       man/systemd-journald-dev-log.socket.8 \
        man/systemd-journald.8 \
        man/systemd-journald.socket.8 \
        man/systemd-kexec.service.8 \
@@ -197,6 +215,7 @@ MANPAGES_ALIAS += \
        man/systemd-shutdownd.socket.8 \
        man/systemd-sleep.8 \
        man/systemd-sysctl.8 \
+       man/systemd-sysusers.service.8 \
        man/systemd-tmpfiles-clean.service.8 \
        man/systemd-tmpfiles-clean.timer.8 \
        man/systemd-tmpfiles-setup-dev.service.8 \
@@ -204,6 +223,7 @@ MANPAGES_ALIAS += \
        man/systemd-udevd-control.socket.8 \
        man/systemd-udevd-kernel.socket.8 \
        man/systemd-udevd.8 \
+       man/systemd-update-done.8 \
        man/systemd-update-utmp-runlevel.service.8 \
        man/systemd-update-utmp.8 \
        man/systemd-user.conf.5
@@ -282,12 +302,14 @@ man/sd_notifyf.3: man/sd_notify.3
 man/systemd-ask-password-console.path.8: man/systemd-ask-password-console.service.8
 man/systemd-ask-password-wall.path.8: man/systemd-ask-password-console.service.8
 man/systemd-ask-password-wall.service.8: man/systemd-ask-password-console.service.8
+man/systemd-firstboot.service.1: man/systemd-firstboot.1
 man/systemd-fsck-root.service.8: man/systemd-fsck@.service.8
 man/systemd-fsck.8: man/systemd-fsck@.service.8
 man/systemd-hibernate.service.8: man/systemd-suspend.service.8
 man/systemd-hybrid-sleep.service.8: man/systemd-suspend.service.8
 man/systemd-initctl.8: man/systemd-initctl.service.8
 man/systemd-initctl.socket.8: man/systemd-initctl.service.8
+man/systemd-journald-dev-log.socket.8: man/systemd-journald.service.8
 man/systemd-journald.8: man/systemd-journald.service.8
 man/systemd-journald.socket.8: man/systemd-journald.service.8
 man/systemd-kexec.service.8: man/systemd-halt.service.8
@@ -299,6 +321,7 @@ man/systemd-shutdownd.8: man/systemd-shutdownd.service.8
 man/systemd-shutdownd.socket.8: man/systemd-shutdownd.service.8
 man/systemd-sleep.8: man/systemd-suspend.service.8
 man/systemd-sysctl.8: man/systemd-sysctl.service.8
+man/systemd-sysusers.service.8: man/systemd-sysusers.8
 man/systemd-tmpfiles-clean.service.8: man/systemd-tmpfiles.8
 man/systemd-tmpfiles-clean.timer.8: man/systemd-tmpfiles.8
 man/systemd-tmpfiles-setup-dev.service.8: man/systemd-tmpfiles.8
@@ -306,6 +329,7 @@ man/systemd-tmpfiles-setup.service.8: man/systemd-tmpfiles.8
 man/systemd-udevd-control.socket.8: man/systemd-udevd.service.8
 man/systemd-udevd-kernel.socket.8: man/systemd-udevd.service.8
 man/systemd-udevd.8: man/systemd-udevd.service.8
+man/systemd-update-done.8: man/systemd-update-done.service.8
 man/systemd-update-utmp-runlevel.service.8: man/systemd-update-utmp.service.8
 man/systemd-update-utmp.8: man/systemd-update-utmp.service.8
 man/systemd-user.conf.5: man/systemd-system.conf.5
@@ -534,6 +558,9 @@ man/systemd-ask-password-wall.path.html: man/systemd-ask-password-console.servic
 man/systemd-ask-password-wall.service.html: man/systemd-ask-password-console.service.html
        $(html-alias)
 
+man/systemd-firstboot.service.html: man/systemd-firstboot.html
+       $(html-alias)
+
 man/systemd-fsck-root.service.html: man/systemd-fsck@.service.html
        $(html-alias)
 
@@ -552,6 +579,9 @@ man/systemd-initctl.html: man/systemd-initctl.service.html
 man/systemd-initctl.socket.html: man/systemd-initctl.service.html
        $(html-alias)
 
+man/systemd-journald-dev-log.socket.html: man/systemd-journald.service.html
+       $(html-alias)
+
 man/systemd-journald.html: man/systemd-journald.service.html
        $(html-alias)
 
@@ -585,6 +615,9 @@ man/systemd-sleep.html: man/systemd-suspend.service.html
 man/systemd-sysctl.html: man/systemd-sysctl.service.html
        $(html-alias)
 
+man/systemd-sysusers.service.html: man/systemd-sysusers.html
+       $(html-alias)
+
 man/systemd-tmpfiles-clean.service.html: man/systemd-tmpfiles.html
        $(html-alias)
 
@@ -606,6 +639,9 @@ man/systemd-udevd-kernel.socket.html: man/systemd-udevd.service.html
 man/systemd-udevd.html: man/systemd-udevd.service.html
        $(html-alias)
 
+man/systemd-update-done.html: man/systemd-update-done.service.html
+       $(html-alias)
+
 man/systemd-update-utmp-runlevel.service.html: man/systemd-update-utmp.service.html
        $(html-alias)
 
@@ -651,7 +687,9 @@ endif
 
 if ENABLE_COREDUMP
 MANPAGES += \
-       man/systemd-coredumpctl.1
+       man/coredump.conf.5 \
+       man/coredumpctl.1 \
+       man/systemd-coredump.8
 MANPAGES_ALIAS += \
        #
 
@@ -684,12 +722,20 @@ MANPAGES += \
        man/sd_bus_creds_get_pid.3 \
        man/sd_bus_creds_new_from_pid.3 \
        man/sd_bus_error.3 \
-       man/sd_bus_label_escape.3 \
+       man/sd_bus_message_append.3 \
+       man/sd_bus_message_append_array.3 \
+       man/sd_bus_message_append_basic.3 \
+       man/sd_bus_message_append_string_memfd.3 \
+       man/sd_bus_message_append_strv.3 \
        man/sd_bus_message_get_cookie.3 \
        man/sd_bus_message_get_monotonic_usec.3 \
+       man/sd_bus_negotiate_fds.3 \
        man/sd_bus_new.3 \
        man/sd_bus_open_user.3 \
+       man/sd_bus_path_encode.3 \
        man/sd_bus_request_name.3 \
+       man/sd_event_add_time.3 \
+       man/sd_event_new.3 \
        man/systemd-bus-proxyd.8 \
        man/systemd-bus-proxyd@.service.8
 MANPAGES_ALIAS += \
@@ -730,16 +776,31 @@ MANPAGES_ALIAS += \
        man/sd_bus_error_set_const.3 \
        man/sd_bus_error_set_errno.3 \
        man/sd_bus_error_set_errnof.3 \
-       man/sd_bus_label_unescape.3 \
+       man/sd_bus_message_append_array_iovec.3 \
+       man/sd_bus_message_append_array_memfd.3 \
+       man/sd_bus_message_append_array_space.3 \
+       man/sd_bus_message_append_string_iovec.3 \
+       man/sd_bus_message_append_string_space.3 \
        man/sd_bus_message_get_realtime_usec.3 \
        man/sd_bus_message_get_reply_cookie.3 \
        man/sd_bus_message_get_seqnum.3 \
+       man/sd_bus_negotiate_creds.3 \
+       man/sd_bus_negotiate_timestamps.3 \
        man/sd_bus_open_system.3 \
        man/sd_bus_open_system_container.3 \
        man/sd_bus_open_system_remote.3 \
+       man/sd_bus_path_decode.3 \
        man/sd_bus_ref.3 \
        man/sd_bus_release_name.3 \
        man/sd_bus_unref.3 \
+       man/sd_event_default.3 \
+       man/sd_event_ref.3 \
+       man/sd_event_source_get_time.3 \
+       man/sd_event_source_get_time_accuracy.3 \
+       man/sd_event_source_get_time_clock.3 \
+       man/sd_event_source_set_time.3 \
+       man/sd_event_source_set_time_accuracy.3 \
+       man/sd_event_unref.3 \
        man/systemd-bus-proxyd.socket.8
 man/sd_bus_creds_get_audit_login_uid.3: man/sd_bus_creds_get_pid.3
 man/sd_bus_creds_get_audit_session_id.3: man/sd_bus_creds_get_pid.3
@@ -778,16 +839,31 @@ man/sd_bus_error_set.3: man/sd_bus_error.3
 man/sd_bus_error_set_const.3: man/sd_bus_error.3
 man/sd_bus_error_set_errno.3: man/sd_bus_error.3
 man/sd_bus_error_set_errnof.3: man/sd_bus_error.3
-man/sd_bus_label_unescape.3: man/sd_bus_label_escape.3
+man/sd_bus_message_append_array_iovec.3: man/sd_bus_message_append_array.3
+man/sd_bus_message_append_array_memfd.3: man/sd_bus_message_append_array.3
+man/sd_bus_message_append_array_space.3: man/sd_bus_message_append_array.3
+man/sd_bus_message_append_string_iovec.3: man/sd_bus_message_append_string_memfd.3
+man/sd_bus_message_append_string_space.3: man/sd_bus_message_append_string_memfd.3
 man/sd_bus_message_get_realtime_usec.3: man/sd_bus_message_get_monotonic_usec.3
 man/sd_bus_message_get_reply_cookie.3: man/sd_bus_message_get_cookie.3
 man/sd_bus_message_get_seqnum.3: man/sd_bus_message_get_monotonic_usec.3
+man/sd_bus_negotiate_creds.3: man/sd_bus_negotiate_fds.3
+man/sd_bus_negotiate_timestamps.3: man/sd_bus_negotiate_fds.3
 man/sd_bus_open_system.3: man/sd_bus_open_user.3
 man/sd_bus_open_system_container.3: man/sd_bus_open_user.3
 man/sd_bus_open_system_remote.3: man/sd_bus_open_user.3
+man/sd_bus_path_decode.3: man/sd_bus_path_encode.3
 man/sd_bus_ref.3: man/sd_bus_new.3
 man/sd_bus_release_name.3: man/sd_bus_request_name.3
 man/sd_bus_unref.3: man/sd_bus_new.3
+man/sd_event_default.3: man/sd_event_new.3
+man/sd_event_ref.3: man/sd_event_new.3
+man/sd_event_source_get_time.3: man/sd_event_add_time.3
+man/sd_event_source_get_time_accuracy.3: man/sd_event_add_time.3
+man/sd_event_source_get_time_clock.3: man/sd_event_add_time.3
+man/sd_event_source_set_time.3: man/sd_event_add_time.3
+man/sd_event_source_set_time_accuracy.3: man/sd_event_add_time.3
+man/sd_event_unref.3: man/sd_event_new.3
 man/systemd-bus-proxyd.socket.8: man/systemd-bus-proxyd@.service.8
 man/sd_bus_creds_get_audit_login_uid.html: man/sd_bus_creds_get_pid.html
        $(html-alias)
@@ -900,7 +976,19 @@ man/sd_bus_error_set_errno.html: man/sd_bus_error.html
 man/sd_bus_error_set_errnof.html: man/sd_bus_error.html
        $(html-alias)
 
-man/sd_bus_label_unescape.html: man/sd_bus_label_escape.html
+man/sd_bus_message_append_array_iovec.html: man/sd_bus_message_append_array.html
+       $(html-alias)
+
+man/sd_bus_message_append_array_memfd.html: man/sd_bus_message_append_array.html
+       $(html-alias)
+
+man/sd_bus_message_append_array_space.html: man/sd_bus_message_append_array.html
+       $(html-alias)
+
+man/sd_bus_message_append_string_iovec.html: man/sd_bus_message_append_string_memfd.html
+       $(html-alias)
+
+man/sd_bus_message_append_string_space.html: man/sd_bus_message_append_string_memfd.html
        $(html-alias)
 
 man/sd_bus_message_get_realtime_usec.html: man/sd_bus_message_get_monotonic_usec.html
@@ -912,6 +1000,12 @@ man/sd_bus_message_get_reply_cookie.html: man/sd_bus_message_get_cookie.html
 man/sd_bus_message_get_seqnum.html: man/sd_bus_message_get_monotonic_usec.html
        $(html-alias)
 
+man/sd_bus_negotiate_creds.html: man/sd_bus_negotiate_fds.html
+       $(html-alias)
+
+man/sd_bus_negotiate_timestamps.html: man/sd_bus_negotiate_fds.html
+       $(html-alias)
+
 man/sd_bus_open_system.html: man/sd_bus_open_user.html
        $(html-alias)
 
@@ -921,6 +1015,9 @@ man/sd_bus_open_system_container.html: man/sd_bus_open_user.html
 man/sd_bus_open_system_remote.html: man/sd_bus_open_user.html
        $(html-alias)
 
+man/sd_bus_path_decode.html: man/sd_bus_path_encode.html
+       $(html-alias)
+
 man/sd_bus_ref.html: man/sd_bus_new.html
        $(html-alias)
 
@@ -930,6 +1027,30 @@ man/sd_bus_release_name.html: man/sd_bus_request_name.html
 man/sd_bus_unref.html: man/sd_bus_new.html
        $(html-alias)
 
+man/sd_event_default.html: man/sd_event_new.html
+       $(html-alias)
+
+man/sd_event_ref.html: man/sd_event_new.html
+       $(html-alias)
+
+man/sd_event_source_get_time.html: man/sd_event_add_time.html
+       $(html-alias)
+
+man/sd_event_source_get_time_accuracy.html: man/sd_event_add_time.html
+       $(html-alias)
+
+man/sd_event_source_get_time_clock.html: man/sd_event_add_time.html
+       $(html-alias)
+
+man/sd_event_source_set_time.html: man/sd_event_add_time.html
+       $(html-alias)
+
+man/sd_event_source_set_time_accuracy.html: man/sd_event_add_time.html
+       $(html-alias)
+
+man/sd_event_unref.html: man/sd_event_new.html
+       $(html-alias)
+
 man/systemd-bus-proxyd.socket.html: man/systemd-bus-proxyd@.service.html
        $(html-alias)
 
@@ -974,10 +1095,18 @@ endif
 
 if ENABLE_NETWORKD
 MANPAGES += \
-       man/systemd-networkd.service.8
+       man/systemd-networkd-wait-online.service.8 \
+       man/systemd-networkd.service.8 \
+       man/systemd.netdev.5 \
+       man/systemd.network.5
 MANPAGES_ALIAS += \
+       man/systemd-networkd-wait-online.8 \
        man/systemd-networkd.8
+man/systemd-networkd-wait-online.8: man/systemd-networkd-wait-online.service.8
 man/systemd-networkd.8: man/systemd-networkd.service.8
+man/systemd-networkd-wait-online.html: man/systemd-networkd-wait-online.service.html
+       $(html-alias)
+
 man/systemd-networkd.html: man/systemd-networkd.service.html
        $(html-alias)
 
@@ -1033,6 +1162,18 @@ man/systemd-readahead.html: man/systemd-readahead-replay.service.html
 
 endif
 
+if ENABLE_RESOLVED
+MANPAGES += \
+       man/resolved.conf.5 \
+       man/systemd-resolved.service.8
+MANPAGES_ALIAS += \
+       man/systemd-resolved.8
+man/systemd-resolved.8: man/systemd-resolved.service.8
+man/systemd-resolved.html: man/systemd-resolved.service.html
+       $(html-alias)
+
+endif
+
 if ENABLE_RFKILL
 MANPAGES += \
        man/systemd-rfkill@.service.8
@@ -1056,6 +1197,18 @@ man/systemd-timedated.html: man/systemd-timedated.service.html
 
 endif
 
+if ENABLE_TIMESYNCD
+MANPAGES += \
+       man/systemd-timesyncd.service.8 \
+       man/timesyncd.conf.5
+MANPAGES_ALIAS += \
+       man/systemd-timesyncd.8
+man/systemd-timesyncd.8: man/systemd-timesyncd.service.8
+man/systemd-timesyncd.html: man/systemd-timesyncd.service.html
+       $(html-alias)
+
+endif
+
 if ENABLE_VCONSOLE
 MANPAGES += \
        man/systemd-vconsole-setup.service.8 \
@@ -1095,7 +1248,9 @@ endif
 
 if HAVE_MICROHTTPD
 MANPAGES += \
-       man/systemd-journal-gatewayd.service.8
+       man/systemd-journal-gatewayd.service.8 \
+       man/systemd-journal-remote.8 \
+       man/systemd-journal-upload.8
 MANPAGES_ALIAS += \
        man/systemd-journal-gatewayd.8 \
        man/systemd-journal-gatewayd.socket.8
@@ -1139,6 +1294,12 @@ MANPAGES_ALIAS += \
        man/sd_login_monitor_get_fd.3 \
        man/sd_login_monitor_get_timeout.3 \
        man/sd_login_monitor_unref.3 \
+       man/sd_peer_get_machine_name.3 \
+       man/sd_peer_get_owner_uid.3 \
+       man/sd_peer_get_session.3 \
+       man/sd_peer_get_slice.3 \
+       man/sd_peer_get_unit.3 \
+       man/sd_peer_get_user_unit.3 \
        man/sd_pid_get_machine_name.3 \
        man/sd_pid_get_owner_uid.3 \
        man/sd_pid_get_slice.3 \
@@ -1160,6 +1321,7 @@ MANPAGES_ALIAS += \
        man/sd_session_get_uid.3 \
        man/sd_session_get_vt.3 \
        man/sd_session_is_remote.3 \
+       man/sd_uid_get_display.3 \
        man/sd_uid_get_seats.3 \
        man/sd_uid_get_sessions.3 \
        man/sd_uid_is_on_seat.3 \
@@ -1173,6 +1335,12 @@ man/sd_login_monitor_get_events.3: man/sd_login_monitor_new.3
 man/sd_login_monitor_get_fd.3: man/sd_login_monitor_new.3
 man/sd_login_monitor_get_timeout.3: man/sd_login_monitor_new.3
 man/sd_login_monitor_unref.3: man/sd_login_monitor_new.3
+man/sd_peer_get_machine_name.3: man/sd_pid_get_session.3
+man/sd_peer_get_owner_uid.3: man/sd_pid_get_session.3
+man/sd_peer_get_session.3: man/sd_pid_get_session.3
+man/sd_peer_get_slice.3: man/sd_pid_get_session.3
+man/sd_peer_get_unit.3: man/sd_pid_get_session.3
+man/sd_peer_get_user_unit.3: man/sd_pid_get_session.3
 man/sd_pid_get_machine_name.3: man/sd_pid_get_session.3
 man/sd_pid_get_owner_uid.3: man/sd_pid_get_session.3
 man/sd_pid_get_slice.3: man/sd_pid_get_session.3
@@ -1194,6 +1362,7 @@ man/sd_session_get_type.3: man/sd_session_is_active.3
 man/sd_session_get_uid.3: man/sd_session_is_active.3
 man/sd_session_get_vt.3: man/sd_session_is_active.3
 man/sd_session_is_remote.3: man/sd_session_is_active.3
+man/sd_uid_get_display.3: man/sd_uid_get_state.3
 man/sd_uid_get_seats.3: man/sd_uid_get_state.3
 man/sd_uid_get_sessions.3: man/sd_uid_get_state.3
 man/sd_uid_is_on_seat.3: man/sd_uid_get_state.3
@@ -1225,6 +1394,24 @@ man/sd_login_monitor_get_timeout.html: man/sd_login_monitor_new.html
 man/sd_login_monitor_unref.html: man/sd_login_monitor_new.html
        $(html-alias)
 
+man/sd_peer_get_machine_name.html: man/sd_pid_get_session.html
+       $(html-alias)
+
+man/sd_peer_get_owner_uid.html: man/sd_pid_get_session.html
+       $(html-alias)
+
+man/sd_peer_get_session.html: man/sd_pid_get_session.html
+       $(html-alias)
+
+man/sd_peer_get_slice.html: man/sd_pid_get_session.html
+       $(html-alias)
+
+man/sd_peer_get_unit.html: man/sd_pid_get_session.html
+       $(html-alias)
+
+man/sd_peer_get_user_unit.html: man/sd_pid_get_session.html
+       $(html-alias)
+
 man/sd_pid_get_machine_name.html: man/sd_pid_get_session.html
        $(html-alias)
 
@@ -1288,6 +1475,9 @@ man/sd_session_get_vt.html: man/sd_session_is_active.html
 man/sd_session_is_remote.html: man/sd_session_is_active.html
        $(html-alias)
 
+man/sd_uid_get_display.html: man/sd_uid_get_state.html
+       $(html-alias)
+
 man/sd_uid_get_seats.html: man/sd_uid_get_state.html
        $(html-alias)
 
@@ -1312,14 +1502,19 @@ MANPAGES_ALIAS += \
 
 endif
 
+# Really, do not edit this file.
+
 EXTRA_DIST += \
-       man/binfmt.d.xml \
+       man/binfmt.d.xml \
        man/bootchart.conf.xml \
        man/bootctl.xml \
        man/bootup.xml \
        man/busctl.xml \
+       man/coredump.conf.xml \
+       man/coredumpctl.xml \
        man/crypttab.xml \
        man/daemon.xml \
+       man/file-hierarchy.xml \
        man/halt.xml \
        man/hostname.xml \
        man/hostnamectl.xml \
@@ -1341,6 +1536,7 @@ EXTRA_DIST += \
        man/nss-myhostname.xml \
        man/os-release.xml \
        man/pam_systemd.xml \
+       man/resolved.conf.xml \
        man/runlevel.xml \
        man/sd-daemon.xml \
        man/sd-id128.xml \
@@ -1351,12 +1547,20 @@ EXTRA_DIST += \
        man/sd_bus_creds_get_pid.xml \
        man/sd_bus_creds_new_from_pid.xml \
        man/sd_bus_error.xml \
-       man/sd_bus_label_escape.xml \
+       man/sd_bus_message_append.xml \
+       man/sd_bus_message_append_array.xml \
+       man/sd_bus_message_append_basic.xml \
+       man/sd_bus_message_append_string_memfd.xml \
+       man/sd_bus_message_append_strv.xml \
        man/sd_bus_message_get_cookie.xml \
        man/sd_bus_message_get_monotonic_usec.xml \
+       man/sd_bus_negotiate_fds.xml \
        man/sd_bus_new.xml \
        man/sd_bus_open_user.xml \
+       man/sd_bus_path_encode.xml \
        man/sd_bus_request_name.xml \
+       man/sd_event_add_time.xml \
+       man/sd_event_new.xml \
        man/sd_get_seats.xml \
        man/sd_id128_get_machine.xml \
        man/sd_id128_randomize.xml \
@@ -1401,12 +1605,15 @@ EXTRA_DIST += \
        man/systemd-cat.xml \
        man/systemd-cgls.xml \
        man/systemd-cgtop.xml \
-       man/systemd-coredumpctl.xml \
+       man/systemd-coredump.xml \
        man/systemd-cryptsetup-generator.xml \
        man/systemd-cryptsetup@.service.xml \
+       man/systemd-debug-generator.xml \
        man/systemd-delta.xml \
        man/systemd-detect-virt.xml \
        man/systemd-efi-boot-generator.xml \
+       man/systemd-escape.xml \
+       man/systemd-firstboot.xml \
        man/systemd-fsck@.service.xml \
        man/systemd-fstab-generator.xml \
        man/systemd-getty-generator.xml \
@@ -1416,19 +1623,24 @@ EXTRA_DIST += \
        man/systemd-inhibit.xml \
        man/systemd-initctl.service.xml \
        man/systemd-journal-gatewayd.service.xml \
+       man/systemd-journal-remote.xml \
+       man/systemd-journal-upload.xml \
        man/systemd-journald.service.xml \
        man/systemd-localed.service.xml \
        man/systemd-logind.service.xml \
        man/systemd-machine-id-setup.xml \
        man/systemd-machined.service.xml \
        man/systemd-modules-load.service.xml \
+       man/systemd-networkd-wait-online.service.xml \
        man/systemd-networkd.service.xml \
        man/systemd-notify.xml \
        man/systemd-nspawn.xml \
+       man/systemd-path.xml \
        man/systemd-quotacheck.service.xml \
        man/systemd-random-seed.service.xml \
        man/systemd-readahead-replay.service.xml \
        man/systemd-remount-fs.service.xml \
+       man/systemd-resolved.service.xml \
        man/systemd-rfkill@.service.xml \
        man/systemd-run.xml \
        man/systemd-shutdownd.service.xml \
@@ -1438,10 +1650,13 @@ EXTRA_DIST += \
        man/systemd-sysctl.service.xml \
        man/systemd-system-update-generator.xml \
        man/systemd-system.conf.xml \
+       man/systemd-sysusers.xml \
        man/systemd-timedated.service.xml \
+       man/systemd-timesyncd.service.xml \
        man/systemd-tmpfiles.xml \
        man/systemd-tty-ask-password-agent.xml \
        man/systemd-udevd.service.xml \
+       man/systemd-update-done.service.xml \
        man/systemd-update-utmp.service.xml \
        man/systemd-user-sessions.service.xml \
        man/systemd-vconsole-setup.service.xml \
@@ -1452,7 +1667,10 @@ EXTRA_DIST += \
        man/systemd.index.xml \
        man/systemd.journal-fields.xml \
        man/systemd.kill.xml \
+       man/systemd.link.xml \
        man/systemd.mount.xml \
+       man/systemd.netdev.xml \
+       man/systemd.network.xml \
        man/systemd.path.xml \
        man/systemd.preset.xml \
        man/systemd.resource-control.xml \
@@ -1468,9 +1686,12 @@ EXTRA_DIST += \
        man/systemd.timer.xml \
        man/systemd.unit.xml \
        man/systemd.xml \
+       man/sysusers.d.xml \
        man/telinit.xml \
        man/timedatectl.xml \
+       man/timesyncd.conf.xml \
        man/tmpfiles.d.xml \
+       man/udev.conf.xml \
        man/udev.xml \
        man/udevadm.xml \
        man/user-system-options.xml \
index 529b525..8490c67 100644 (file)
@@ -35,14 +35,20 @@ SUBDIRS = . po
 # Keep the test-suite.log
 .PRECIOUS: $(TEST_SUITE_LOG) Makefile
 
-LIBUDEV_CURRENT=5
+LIBUDEV_CURRENT=7
 LIBUDEV_REVISION=0
-LIBUDEV_AGE=4
+LIBUDEV_AGE=6
 
 LIBGUDEV_CURRENT=2
 LIBGUDEV_REVISION=0
 LIBGUDEV_AGE=2
 
+LIBSYSTEMD_CURRENT=4
+LIBSYSTEMD_REVISION=0
+LIBSYSTEMD_AGE=4
+
+# The following four libraries only exist for compatibility reasons,
+# their version info should not be bumped anymore
 LIBSYSTEMD_LOGIN_CURRENT=9
 LIBSYSTEMD_LOGIN_REVISION=3
 LIBSYSTEMD_LOGIN_AGE=9
@@ -59,10 +65,6 @@ LIBSYSTEMD_JOURNAL_CURRENT=11
 LIBSYSTEMD_JOURNAL_REVISION=5
 LIBSYSTEMD_JOURNAL_AGE=11
 
-LIBSYSTEMD_CURRENT=0
-LIBSYSTEMD_REVISION=1
-LIBSYSTEMD_AGE=0
-
 # Dirs of external packages
 dbuspolicydir=@dbuspolicydir@
 dbussessionservicedir=@dbussessionservicedir@
@@ -86,7 +88,10 @@ pkgsysconfdir=$(sysconfdir)/systemd
 userunitdir=$(prefix)/lib/systemd/user
 userpresetdir=$(prefix)/lib/systemd/user-preset
 tmpfilesdir=$(prefix)/lib/tmpfiles.d
+sysusersdir=$(prefix)/lib/sysusers.d
 sysctldir=$(prefix)/lib/sysctl.d
+binfmtdir=$(prefix)/lib/binfmt.d
+modulesloaddir=$(prefix)/lib/modules-load.d
 networkdir=$(rootprefix)/lib/systemd/network
 pkgincludedir=$(includedir)/systemd
 systemgeneratordir=$(rootlibexecdir)/system-generators
@@ -101,6 +106,8 @@ udevrulesdir=$(udevlibexecdir)/rules.d
 udevhwdbdir=$(udevlibexecdir)/hwdb.d
 catalogdir=$(prefix)/lib/systemd/catalog
 kernelinstalldir = $(prefix)/lib/kernel/install.d
+factory_etcdir = $(prefix)/share/factory/etc
+factory_pamdir = $(prefix)/share/factory/etc/pam.d
 
 # And these are the special ones for /
 rootprefix=@rootprefix@
@@ -129,6 +136,7 @@ polkitpolicy_files =
 dist_udevrules_DATA =
 nodist_udevrules_DATA =
 dist_pkgsysconf_DATA =
+nodist_pkgsysconf_DATA =
 dist_pkgdata_DATA =
 dist_dbuspolicy_DATA =
 dist_dbussystemservice_DATA =
@@ -158,6 +166,7 @@ AM_CPPFLAGS = \
        -DSYSTEM_SYSVRCND_PATH=\"$(SYSTEM_SYSVRCND_PATH)\" \
        -DUSER_CONFIG_UNIT_PATH=\"$(pkgsysconfdir)/user\" \
        -DUSER_DATA_UNIT_PATH=\"$(userunitdir)\" \
+       -DCERTIFICATE_ROOT=\"$(CERTIFICATEROOT)\" \
        -DCATALOG_DATABASE=\"$(catalogstatedir)/database\" \
        -DSYSTEMD_CGROUP_AGENT_PATH=\"$(rootlibexecdir)/systemd-cgroups-agent\" \
        -DSYSTEMD_BINARY_PATH=\"$(rootlibexecdir)/systemd\" \
@@ -180,12 +189,19 @@ AM_CPPFLAGS = \
        -DPOLKIT_AGENT_BINARY_PATH=\"$(bindir)/pkttyagent\" \
        -DQUOTACHECK=\"$(QUOTACHECK)\" \
        -DKEXEC=\"$(KEXEC)\" \
+       -DLIBDIR=\"$(libdir)\" \
+       -DROOTLIBDIR=\"$(rootlibdir)\" \
+       -DTEST_DIR=\"$(abs_top_srcdir)/test\" \
        -I $(top_srcdir)/src \
        -I $(top_builddir)/src/shared \
        -I $(top_srcdir)/src/shared \
        -I $(top_srcdir)/src/network \
        -I $(top_srcdir)/src/login \
        -I $(top_srcdir)/src/journal \
+       -I $(top_srcdir)/src/timedate \
+       -I $(top_srcdir)/src/timesync \
+       -I $(top_srcdir)/src/resolve \
+       -I $(top_builddir)/src/resolve \
        -I $(top_srcdir)/src/systemd \
        -I $(top_builddir)/src/core \
        -I $(top_srcdir)/src/core \
@@ -196,21 +212,36 @@ AM_CPPFLAGS = \
        -I $(top_srcdir)/src/libsystemd/sd-bus \
        -I $(top_srcdir)/src/libsystemd/sd-event \
        -I $(top_srcdir)/src/libsystemd/sd-rtnl \
+       -I $(top_srcdir)/src/libsystemd/sd-network \
+       -I $(top_srcdir)/src/libsystemd-network \
+       -I $(top_srcdir)/src/libsystemd-terminal \
        $(OUR_CPPFLAGS)
 
 AM_CFLAGS = $(OUR_CFLAGS)
 AM_LDFLAGS = $(OUR_LDFLAGS)
 
 # ------------------------------------------------------------------------------
+if CONFIG_TIZEN_WIP
+define move-to-rootlibdir
+       if test "$(libdir)" != "$(rootlibdir)"; then \
+               $(MKDIR_P) $(DESTDIR)$(rootlibdir) && \
+               so_img_name=$$(readlink $(DESTDIR)$(libdir)/$$libname) && \
+               rm -f $(DESTDIR)$(libdir)/$$libname && \
+               $(LN_S) -f $(rootlibdir)/$$so_img_name $(DESTDIR)$(libdir)/$$libname && \
+               mv $(DESTDIR)$(libdir)/$$libname.* $(DESTDIR)$(rootlibdir); \
+       fi
+endef
+else
 define move-to-rootlibdir
        if test "$(libdir)" != "$(rootlibdir)"; then \
                $(MKDIR_P) $(DESTDIR)$(rootlibdir) && \
                so_img_name=$$(readlink $(DESTDIR)$(libdir)/$$libname) && \
-               so_img_rel_target_prefix=$$(echo $(libdir) | sed 's,\(^/\|\)[^/][^/]*,..,g') && \
-               $(LN_S) -f $$so_img_rel_target_prefix$(rootlibdir)/$$so_img_name $(DESTDIR)$(libdir)/$$libname && \
+               rm -f $(DESTDIR)$(libdir)/$$libname && \
+               $(LN_S) --relative -f $(DESTDIR)$(rootlibdir)/$$so_img_name $(DESTDIR)$(libdir)/$$libname && \
                mv $(DESTDIR)$(libdir)/$$libname.* $(DESTDIR)$(rootlibdir); \
        fi
 endef
+endif
 
 INSTALL_DIRS =
 
@@ -231,7 +262,6 @@ USER_BUSNAMES_TARGET_WANTS =
 
 SYSTEM_UNIT_ALIASES =
 USER_UNIT_ALIASES =
-
 GENERAL_ALIASES =
 
 install-target-wants-hook:
@@ -267,9 +297,9 @@ install-aliases-hook:
        set -- $(SYSTEM_UNIT_ALIASES) && \
                dir=$(systemunitdir) && $(install-aliases)
        set -- $(USER_UNIT_ALIASES) && \
-               dir=$(userunitdir) && $(install-aliases)
+               dir=$(userunitdir) && $(install-relative-aliases)
        set -- $(GENERAL_ALIASES) && \
-               dir= && $(install-aliases)
+               dir= && $(install-relative-aliases)
 
 define install-aliases
        while [ -n "$$1" ]; do \
@@ -280,10 +310,34 @@ define install-aliases
        done
 endef
 
+if CONFIG_TIZEN_WIP
+define install-relative-aliases
+       while [ -n "$$1" ]; do \
+               $(MKDIR_P) `dirname $(DESTDIR)$$dir/$$2` && \
+               rm -f $(DESTDIR)$$dir/$$2 && \
+               $(LN_S) $$1 $(DESTDIR)$$dir/$$2 && \
+               shift 2 || exit $$?; \
+       done
+endef
+else
+define install-relative-aliases
+       while [ -n "$$1" ]; do \
+               $(MKDIR_P) `dirname $(DESTDIR)$$dir/$$2` && \
+               rm -f $(DESTDIR)$$dir/$$2 && \
+               $(LN_S) --relative $(DESTDIR)$$1 $(DESTDIR)$$dir/$$2 && \
+               shift 2 || exit $$?; \
+       done
+endef
+endif
+
+install-touch-usr-hook:
+       touch -c $(DESTDIR)/$(prefix)
+
 INSTALL_EXEC_HOOKS += \
        install-target-wants-hook \
        install-directories-hook \
-       install-aliases-hook
+       install-aliases-hook \
+       install-touch-usr-hook
 
 # ------------------------------------------------------------------------------
 AM_V_M4 = $(AM_V_M4_$(V))
@@ -302,13 +356,18 @@ AM_V_LN = $(AM_V_LN_$(V))
 AM_V_LN_ = $(AM_V_LN_$(AM_DEFAULT_VERBOSITY))
 AM_V_LN_0 = @echo "  LN      " $@;
 
+AM_V_RM = $(AM_V_RM_$(V))
+AM_V_RM_ = $(AM_V_RM_$(AM_DEFAULT_VERBOSITY))
+AM_V_RM_0 = @echo "  RM      " $@;
+
 # ------------------------------------------------------------------------------
 rootbin_PROGRAMS = \
        systemctl \
        systemd-notify \
        systemd-ask-password \
        systemd-tty-ask-password-agent \
-       systemd-machine-id-setup
+       systemd-machine-id-setup \
+       systemd-escape
 
 bin_PROGRAMS = \
        systemd-cgls \
@@ -317,7 +376,8 @@ bin_PROGRAMS = \
        systemd-detect-virt \
        systemd-delta \
        systemd-analyze \
-       systemd-run
+       systemd-run \
+       systemd-path
 
 dist_bin_SCRIPTS = \
        src/kernel-install/kernel-install
@@ -340,25 +400,33 @@ rootlibexec_PROGRAMS = \
        systemd-sysctl \
        systemd-sleep \
        systemd-bus-proxyd \
-       systemd-socket-proxyd
+       systemd-socket-proxyd \
+       systemd-update-done
 
 systemgenerator_PROGRAMS = \
        systemd-getty-generator \
        systemd-fstab-generator \
-       systemd-system-update-generator
+       systemd-system-update-generator \
+       systemd-debug-generator
 
 dist_bashcompletion_DATA = \
        shell-completion/bash/busctl \
        shell-completion/bash/journalctl \
-       shell-completion/bash/systemctl \
        shell-completion/bash/systemd-analyze \
+       shell-completion/bash/systemd-cat \
+       shell-completion/bash/systemd-cgls \
+       shell-completion/bash/systemd-cgtop \
        shell-completion/bash/systemd-delta \
+       shell-completion/bash/systemd-detect-virt \
+       shell-completion/bash/systemd-nspawn \
        shell-completion/bash/systemd-run \
        shell-completion/bash/udevadm \
        shell-completion/bash/kernel-install
 
+nodist_bashcompletion_DATA = \
+       shell-completion/bash/systemctl
+
 dist_zshcompletion_DATA = \
-       shell-completion/zsh/_systemctl \
        shell-completion/zsh/_journalctl \
        shell-completion/zsh/_udevadm \
        shell-completion/zsh/_kernel-install \
@@ -366,16 +434,28 @@ dist_zshcompletion_DATA = \
        shell-completion/zsh/_systemd-analyze \
        shell-completion/zsh/_systemd-run \
        shell-completion/zsh/_sd_hosts_or_user_at_host \
+       shell-completion/zsh/_sd_outputmodes \
+       shell-completion/zsh/_sd_unit_files \
        shell-completion/zsh/_systemd-delta \
        shell-completion/zsh/_systemd
 
+nodist_zshcompletion_DATA = \
+       shell-completion/zsh/_systemctl
+
+EXTRA_DIST += \
+       shell-completion/bash/systemctl.in \
+       shell-completion/zsh/_systemctl.in
+
+CLEANFILES += \
+       $(nodist_bashcompletion_DATA) \
+       $(nodist_zshcompletion_DATA)
+
 dist_sysctl_DATA = \
        sysctl.d/50-default.conf
 
 dist_systemunit_DATA = \
        units/graphical.target \
        units/multi-user.target \
-       units/emergency.service \
        units/emergency.target \
        units/sysinit.target \
        units/basic.target \
@@ -390,6 +470,7 @@ dist_systemunit_DATA = \
        units/remote-fs.target \
        units/remote-fs-pre.target \
        units/network.target \
+       units/network-pre.target \
        units/network-online.target \
        units/nss-lookup.target \
        units/nss-user-lookup.target \
@@ -463,12 +544,14 @@ nodist_systemunit_DATA = \
        units/systemd-udevd.service \
        units/systemd-udev-trigger.service \
        units/systemd-udev-settle.service \
+       units/systemd-udev-hwdb-update.service \
        units/debug-shell.service \
        units/initrd-parse-etc.service \
        units/initrd-cleanup.service \
        units/initrd-udevadm-cleanup-db.service \
        units/initrd-switch-root.service \
-       units/systemd-nspawn@.service
+       units/systemd-nspawn@.service \
+       units/systemd-update-done.service
 
 dist_userunit_DATA = \
        units/user/basic.target \
@@ -478,6 +561,9 @@ dist_userunit_DATA = \
 nodist_userunit_DATA = \
        units/user/systemd-exit.service
 
+dist_systempreset_DATA = \
+       system-preset/90-systemd.preset
+
 EXTRA_DIST += \
        units/getty@.service.m4 \
        units/serial-getty@.service.m4 \
@@ -485,36 +571,34 @@ EXTRA_DIST += \
        units/console-getty.service.m4.in \
        units/container-getty@.service.m4.in \
        units/rescue.service.m4.in \
-       units/systemd-initctl.service.in \
-       units/systemd-shutdownd.service.in \
-       units/systemd-remount-fs.service.in \
-       units/systemd-update-utmp.service.in \
-       units/systemd-update-utmp-runlevel.service.in \
-       units/systemd-ask-password-wall.service.in \
-       units/systemd-ask-password-console.service.in \
-       units/systemd-sysctl.service.in \
-       units/emergency.service.in \
-       units/systemd-halt.service.in \
-       units/systemd-poweroff.service.in \
-       units/systemd-reboot.service.in \
-       units/systemd-kexec.service.in \
+       units/systemd-initctl.service.m4.in \
+       units/systemd-shutdownd.service.m4.in \
+       units/systemd-remount-fs.service.m4.in \
+       units/systemd-update-utmp.service.m4.in \
+       units/systemd-update-utmp-runlevel.service.m4.in \
+       units/systemd-ask-password-wall.service.m4.in \
+       units/systemd-ask-password-console.service.m4.in \
+       units/systemd-sysctl.service.m4.in \
+       units/emergency.service.m4.in \
+       units/systemd-halt.service.m4.in \
+       units/systemd-poweroff.service.m4.in \
+       units/systemd-reboot.service.m4.in \
+       units/systemd-kexec.service.m4.in \
        units/user/systemd-exit.service.in \
-       units/systemd-fsck@.service.in \
-       units/systemd-fsck-root.service.in \
-       units/user@.service.in \
-       units/systemd-udevd.service \
-       units/systemd-udev-trigger.service \
-       units/systemd-udev-settle.service \
-       units/debug-shell.service.in \
-       units/systemd-hibernate.service.in \
-       units/systemd-hybrid-sleep.service.in \
-       units/systemd-suspend.service.in \
-       units/quotaon.service.in \
-       units/initrd-parse-etc.service.in \
-       units/initrd-cleanup.service.in \
-       units/initrd-udevadm-cleanup-db.service.in \
-       units/initrd-switch-root.service.in \
-       units/systemd-nspawn@.service.in
+       units/systemd-fsck@.service.m4.in \
+       units/systemd-fsck-root.service.m4.in \
+       units/user@.service.m4.in \
+       units/debug-shell.service.m4.in \
+       units/systemd-hibernate.service.m4.in \
+       units/systemd-hybrid-sleep.service.m4.in \
+       units/systemd-suspend.service.m4.in \
+       units/quotaon.service.m4.in \
+       units/initrd-parse-etc.service.m4.in \
+       units/initrd-cleanup.service.m4.in \
+       units/initrd-udevadm-cleanup-db.service.m4.in \
+       units/initrd-switch-root.service.m4.in \
+       units/systemd-nspawn@.service.m4.in \
+       units/systemd-update-done.service.m4.in
 
 CLEANFILES += \
        units/console-shell.service.m4 \
@@ -529,6 +613,7 @@ nodist_systemunit_DATA += \
        units/halt-local.service
 
 systemgenerator_PROGRAMS += \
+       systemd-sysv-generator \
        systemd-rc-local-generator
 endif
 
@@ -553,7 +638,10 @@ dist_doc_DATA = \
        LICENSE.LGPL2.1 \
        LICENSE.GPL2 \
        LICENSE.MIT \
-       DISTRO_PORTING
+       DISTRO_PORTING \
+       src/libsystemd/sd-bus/PORTING-DBUS1 \
+       src/libsystemd/sd-bus/DIFFERENCES \
+       src/libsystemd/sd-bus/GVARIANT-SERIALIZATION
 
 @INTLTOOL_POLICY_RULE@
 
@@ -681,6 +769,8 @@ libsystemd_shared_la_SOURCES = \
        src/shared/path-util.h \
        src/shared/time-util.c \
        src/shared/time-util.h \
+       src/shared/locale-util.c \
+       src/shared/locale-util.h \
        src/shared/hashmap.c \
        src/shared/hashmap.h \
        src/shared/siphash24.c \
@@ -717,6 +807,8 @@ libsystemd_shared_la_SOURCES = \
        src/shared/pager.h \
        src/shared/socket-util.c \
        src/shared/socket-util.h \
+       src/shared/in-addr-util.c \
+       src/shared/in-addr-util.h \
        src/shared/conf-files.c \
        src/shared/conf-files.h \
        src/shared/cgroup-util.c \
@@ -735,8 +827,8 @@ libsystemd_shared_la_SOURCES = \
        src/shared/replace-var.h \
        src/shared/spawn-polkit-agent.c \
        src/shared/spawn-polkit-agent.h \
-       src/shared/hwclock.c \
-       src/shared/hwclock.h \
+       src/shared/clock-util.c \
+       src/shared/clock-util.h \
        src/shared/time-dst.c \
        src/shared/time-dst.h \
        src/shared/calendarspec.c \
@@ -760,10 +852,12 @@ libsystemd_shared_la_SOURCES = \
        src/shared/ima-util.h \
        src/shared/ptyfwd.c \
        src/shared/ptyfwd.h \
-       src/shared/net-util.c \
-       src/shared/net-util.h \
        src/shared/errno-list.c \
        src/shared/errno-list.h \
+       src/shared/af-list.c \
+       src/shared/af-list.h \
+       src/shared/arphrd-list.c \
+       src/shared/arphrd-list.h \
        src/shared/audit.c \
        src/shared/audit.h \
        src/shared/xml.c \
@@ -771,15 +865,40 @@ libsystemd_shared_la_SOURCES = \
        src/shared/condition-util.c \
        src/shared/condition-util.h \
        src/shared/bus-label.c \
-       src/shared/bus-label.h
+       src/shared/bus-label.h \
+       src/shared/gpt.h \
+       src/shared/clean-ipc.h \
+       src/shared/clean-ipc.c \
+       src/shared/login-shared.c \
+       src/shared/login-shared.h \
+       src/shared/ring.c \
+       src/shared/ring.h \
+       src/shared/barrier.c \
+       src/shared/barrier.h \
+       src/shared/pty.c \
+       src/shared/pty.h \
+       src/shared/async.c \
+       src/shared/async.h \
+       src/shared/copy.c \
+       src/shared/copy.h \
+       src/shared/base-filesystem.c \
+       src/shared/base-filesystem.h \
+       src/shared/uid-range.c \
+       src/shared/uid-range.h \
+       src/shared/nss-util.h
 
 nodist_libsystemd_shared_la_SOURCES = \
        src/shared/errno-from-name.h \
-       src/shared/errno-to-name.h
+       src/shared/errno-to-name.h \
+       src/shared/af-from-name.h \
+       src/shared/af-to-name.h \
+       src/shared/arphrd-from-name.h \
+       src/shared/arphrd-to-name.h
 
 libsystemd_shared_la_CFLAGS = \
        $(AM_CFLAGS) \
-       $(SECCOMP_CFLAGS)
+       $(SECCOMP_CFLAGS) \
+       -pthread
 
 # ------------------------------------------------------------------------------
 noinst_LTLIBRARIES += \
@@ -811,7 +930,11 @@ libsystemd_label_la_SOURCES = \
        src/shared/fileio-label.c \
        src/shared/fileio-label.h \
        src/shared/dev-setup.c \
-       src/shared/dev-setup.h
+       src/shared/dev-setup.h \
+       src/shared/dropin.c \
+       src/shared/dropin.h \
+       src/shared/generator.h \
+       src/shared/generator.c
 
 libsystemd_label_la_CFLAGS = \
        $(AM_CFLAGS) \
@@ -820,6 +943,16 @@ libsystemd_label_la_CFLAGS = \
 libsystemd_label_la_LIBADD = \
        $(SELINUX_LIBS)
 
+# -----------------------------------------------------------------------------
+
+if ENABLE_LDCONFIG
+dist_systemunit_DATA += \
+       units/ldconfig.service
+
+SYSINIT_TARGET_WANTS += \
+       ldconfig.service
+endif
+
 # ------------------------------------------------------------------------------
 
 if HAVE_SECCOMP
@@ -967,8 +1100,6 @@ libsystemd_core_la_SOURCES = \
        src/core/dbus-kill.h \
        src/core/dbus-cgroup.c \
        src/core/dbus-cgroup.h \
-       src/core/dbus-client-track.c \
-       src/core/dbus-client-track.h \
        src/core/cgroup.c \
        src/core/cgroup.h \
        src/core/selinux-access.c \
@@ -993,8 +1124,6 @@ libsystemd_core_la_SOURCES = \
        src/core/condition.h \
        src/core/namespace.c \
        src/core/namespace.h \
-       src/core/tcpwrap.c \
-       src/core/tcpwrap.h \
        src/core/build.h \
        src/core/sysfs-show.h \
        src/core/switch-root.h \
@@ -1003,8 +1132,8 @@ libsystemd_core_la_SOURCES = \
        src/core/killall.c \
        src/core/audit-fd.c \
        src/core/audit-fd.h \
-       src/core/async.c \
-       src/core/async.h
+       src/core/show-status.c \
+       src/core/show-status.h
 
 if HAVE_KMOD
 libsystemd_core_la_SOURCES += \
@@ -1018,7 +1147,6 @@ nodist_libsystemd_core_la_SOURCES = \
 
 libsystemd_core_la_CFLAGS = \
        $(AM_CFLAGS) \
-       $(LIBWRAP_CFLAGS) \
        $(PAM_CFLAGS) \
        $(AUDIT_CFLAGS) \
        $(CAP_CFLAGS) \
@@ -1034,7 +1162,6 @@ libsystemd_core_la_LIBADD = \
        libudev-internal.la \
        libsystemd-shared.la \
        libsystemd-internal.la \
-       $(LIBWRAP_LIBS) \
        $(PAM_LIBS) \
        $(AUDIT_LIBS) \
        $(CAP_LIBS) \
@@ -1059,27 +1186,66 @@ CLEANFILES += \
        src/core/load-fragment-gperf.c \
        src/core/load-fragment-gperf-nulstr.c \
        src/shared/errno-list.txt \
-       src/shared/errno-from-name.gperf
+       src/shared/errno-from-name.gperf \
+       src/shared/af-list.txt \
+       src/shared/af-from-name.gperf \
+       src/shared/arphrd-list.txt \
+       src/shared/arphrd-from-name.gperf \
+       src/shared/dns_type-list.txt \
+       src/shared/dns_type-from-name.gperf
 
 BUILT_SOURCES += \
        src/shared/errno-from-name.h \
-       src/shared/errno-to-name.h
+       src/shared/errno-to-name.h \
+       src/shared/af-from-name.h \
+       src/shared/af-to-name.h \
+       src/shared/arphrd-from-name.h \
+       src/shared/arphrd-to-name.h \
+       src/resolve/dns_type-from-name.h \
+       src/resolve/dns_type-to-name.h
+
+%-from-name.gperf: %-list.txt
+       $(AM_V_GEN)$(AWK) 'BEGIN{ print "struct $(notdir $*)_name { const char* name; int id; };"; print "%null-strings"; print "%%";} { printf "%s, %s\n", $$1, $$1 }' <$< >$@
+
+%-from-name.h: %-from-name.gperf
+       $(AM_V_GPERF)$(GPERF) -L ANSI-C -t --ignore-case -N lookup_$(notdir $*) -H hash_$(notdir $*)_name -p -C <$< >$@
+
 
 src/shared/errno-list.txt:
        $(AM_V_at)$(MKDIR_P) $(dir $@)
-       $(AM_V_GEN)$(CPP) $(CFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) -dM -include errno.h - < /dev/null | $(AWK) '/^#define[ \t]+E[^ _]+[ \t]+[0-9]/ { print $$2; }'  > $@
+       $(AM_V_GEN)$(CPP) $(CFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) -dM -include errno.h - </dev/null | $(AWK) '/^#define[ \t]+E[^ _]+[ \t]+/ { print $$2; }' >$@
+
+src/shared/errno-to-name.h: src/shared/errno-list.txt
+       $(AM_V_GEN)$(AWK) 'BEGIN{ print "static const char* const errno_names[] = { "} !/EDEADLOCK/ && !/EWOULDBLOCK/ && !/ENOTSUP/ { printf "[%s] = \"%s\",\n", $$1, $$1 } END{print "};"}' <$< >$@
+
 
-src/shared/errno-from-name.gperf: src/shared/errno-list.txt
+src/shared/af-list.txt:
        $(AM_V_at)$(MKDIR_P) $(dir $@)
-       $(AM_V_GEN)$(AWK) 'BEGIN{ print "struct errno_name { const char* name; int id; };"; print "%null-strings"; print "%%";} { printf "%s, %s\n", $$1, $$1 }' < $< > $@
+       $(AM_V_GEN)$(CPP) $(CFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) -dM -include sys/socket.h - </dev/null | grep -v AF_UNSPEC | grep -v AF_MAX | $(AWK) '/^#define[ \t]+AF_[^ \t]+[ \t]+PF_[^ \t]/ { print $$2; }' >$@
 
-src/shared/errno-from-name.h: src/shared/errno-from-name.gperf
+src/shared/af-to-name.h: src/shared/af-list.txt
+       $(AM_V_GEN)$(AWK) 'BEGIN{ print "static const char* const af_names[] = { "} !/AF_FILE/ && !/AF_ROUTE/ && !/AF_LOCAL/ { printf "[%s] = \"%s\",\n", $$1, $$1 } END{print "};"}' <$< >$@
+
+src/shared/arphrd-list.txt:
        $(AM_V_at)$(MKDIR_P) $(dir $@)
-       $(AM_V_GPERF)$(GPERF) -L ANSI-C -t --ignore-case -N lookup_errno -H hash_errno_name -p -C < $< > $@
+       $(AM_V_GEN)$(CPP) $(CFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) -dM -include net/if_arp.h - </dev/null | $(AWK) '/^#define[ \t]+ARPHRD_[^ \t]+[ \t]+[^ \t]/ { print $$2; }' | sed -e 's/ARPHRD_//' >$@
 
-src/shared/errno-to-name.h: src/shared/errno-list.txt
+src/shared/arphrd-to-name.h: src/shared/arphrd-list.txt
+       $(AM_V_GEN)$(AWK) 'BEGIN{ print "static const char* const arphrd_names[] = { "} !/CISCO/ { printf "[ARPHRD_%s] = \"%s\",\n", $$1, $$1 } END{print "};"}' <$< >$@
+
+src/shared/arphrd-from-name.gperf: src/shared/arphrd-list.txt
+       $(AM_V_GEN)$(AWK) 'BEGIN{ print "struct arphrd_name { const char* name; int id; };"; print "%null-strings"; print "%%";} { printf "%s, ARPHRD_%s\n", $$1, $$1 }' <$< >$@
+
+
+src/resolve/dns_type-list.txt: src/resolve/dns-type.h
        $(AM_V_at)$(MKDIR_P) $(dir $@)
-       $(AM_V_GEN)$(AWK) 'BEGIN{ print "static const char* const errno_names[] = { "} { printf "[%s] = \"%s\",\n", $$1, $$1 } END{print "};"}' < $< > $@
+       $(AM_V_GEN)$(SED) -n -r 's/.* DNS_TYPE_(\w+).*/\1/p' <$< >$@
+
+src/resolve/dns_type-to-name.h: src/resolve/dns_type-list.txt
+       $(AM_V_GEN)$(AWK) 'BEGIN{ print "const char *dns_type_to_string(int type) {\n\tswitch(type) {" } {printf "        case DNS_TYPE_%s: return ", $$1; sub(/_/, "-"); printf "\"%s\";\n", $$1 } END{ print "\ndefault: return NULL;\n\t}\n}\n" }' <$< >$@
+
+src/resolve/dns_type-from-name.gperf: src/resolve/dns_type-list.txt
+       $(AM_V_GEN)$(AWK) 'BEGIN{ print "struct dns_type_name { const char* name; int id; };"; print "%null-strings"; print "%%";} { s=$$1; sub(/_/, "-", s); printf "%s, ", $$s; printf "DNS_TYPE_%s\n", $$1 }' <$< >$@
 
 # ------------------------------------------------------------------------------
 systemd_SOURCES = \
@@ -1121,8 +1287,8 @@ CLEANFILES += \
        src/core/org.freedesktop.systemd1.policy.in
 
 # ------------------------------------------------------------------------------
+
 manual_tests += \
-       test-engine \
        test-ns \
        test-loopback \
        test-hostname \
@@ -1130,9 +1296,17 @@ manual_tests += \
        test-cgroup \
        test-install \
        test-watchdog \
-       test-log
+       test-log \
+       test-ipcrm
+
+if HAVE_KMOD
+manual_tests += \
+       test-rtnl-manual
+endif
 
 tests += \
+       test-engine \
+       test-cgroup-mask \
        test-job-type \
        test-env-replace \
        test-strbuf \
@@ -1144,6 +1318,9 @@ tests += \
        test-utf8 \
        test-ellipsize \
        test-util \
+       test-ring \
+       test-barrier \
+       test-pty \
        test-tmpfiles \
        test-namespace \
        test-date \
@@ -1153,7 +1330,6 @@ tests += \
        test-calendarspec \
        test-strip-tab-ansi \
        test-cgroup-util \
-       test-cgroup-mask \
        test-prioq \
        test-fileio \
        test-time \
@@ -1162,17 +1338,47 @@ tests += \
        test-tables \
        test-device-nodes \
        test-xml \
-       test-architecture
+       test-architecture \
+       test-socket-util \
+       test-fdset \
+       test-conf-files \
+       test-capability \
+       test-async \
+       test-ratelimit \
+       test-condition-util \
+       test-uid-range
 
 EXTRA_DIST += \
+       test/a.service \
+       test/basic.target \
+       test/b.service \
+       test/c.service \
+       test/daughter.service \
+       test/d.service \
+       test/end.service \
+       test/e.service \
+       test/f.service \
+       test/grandchild.service \
+       test/g.service \
+       test/hello-after-sleep.target \
+       test/hello.service \
+       test/h.service \
+       test/parent-deep.slice \
+       test/parent.slice \
+       test/paths.target \
        test/sched_idle_bad.service \
        test/sched_idle_ok.service \
        test/sched_rr_bad.service \
-       test/sched_rr_ok.service \
        test/sched_rr_change.service \
+       test/sched_rr_ok.service \
+       test/shutdown.target \
+       test/sleep.service \
+       test/sockets.target \
        test/son.service \
-       test/daughter.service \
-       test/parent.slice
+       test/sysinit.target \
+       test/testsuite.target \
+       test/timers.target \
+       test/unstoppable.service
 
 EXTRA_DIST += \
        src/test/test-helper.h
@@ -1266,12 +1472,75 @@ test_utf8_SOURCES = \
 test_utf8_LDADD = \
        libsystemd-shared.la
 
+test_capability_SOURCES = \
+       src/test/test-capability.c
+
+test_capability_LDADD = \
+       libsystemd-shared.la \
+       libsystemd-capability.la
+
+test_async_SOURCES = \
+       src/test/test-async.c
+
+test_async_LDADD = \
+       libsystemd-shared.la
+
+test_condition_util_SOURCES = \
+       src/test/test-condition-util.c
+
+test_condition_util_LDADD = \
+       libsystemd-shared.la \
+       libsystemd-internal.la
+
+
+test_fdset_SOURCES = \
+       src/test/test-fdset.c
+
+test_fdset_LDADD = \
+       libsystemd-core.la
+
+test_ratelimit_SOURCES = \
+       src/test/test-ratelimit.c
+
+test_ratelimit_LDADD = \
+       libsystemd-shared.la
+
 test_util_SOURCES = \
        src/test/test-util.c
 
 test_util_LDADD = \
        libsystemd-core.la
 
+test_uid_range_SOURCES = \
+       src/test/test-uid-range.c
+
+test_uid_range_LDADD = \
+       libsystemd-core.la
+
+test_socket_util_SOURCES = \
+       src/test/test-socket-util.c
+
+test_socket_util_LDADD = \
+       libsystemd-core.la
+
+test_ring_SOURCES = \
+       src/test/test-ring.c
+
+test_ring_LDADD = \
+       libsystemd-core.la
+
+test_barrier_SOURCES = \
+       src/test/test-barrier.c
+
+test_barrier_LDADD = \
+       libsystemd-core.la
+
+test_pty_SOURCES = \
+       src/test/test-pty.c
+
+test_pty_LDADD = \
+       libsystemd-core.la
+
 test_tmpfiles_SOURCES = \
        src/test/test-tmpfiles.c
 
@@ -1304,7 +1573,15 @@ test_list_LDADD = \
 
 test_tables_SOURCES = \
        src/test/test-tables.c \
-       src/shared/test-tables.h
+       src/shared/test-tables.h \
+       src/bus-proxyd/bus-policy.c \
+       src/bus-proxyd/bus-policy.h \
+       src/journal/journald-server.c \
+       src/journal/journald-server.h
+
+test_tables_CPPFLAGS = \
+       $(AM_CPPFLAGS) \
+       -I$(top_srcdir)/src/bus-proxyd
 
 test_tables_CFLAGS = \
        $(AM_CFLAGS) \
@@ -1313,7 +1590,9 @@ test_tables_CFLAGS = \
 test_tables_LDADD = \
        libsystemd-logs.la \
        libsystemd-journal-internal.la \
+       libsystemd-journal-core.la \
        libsystemd-core.la \
+       libudev-core.la \
        $(RT_LIBS)
 
 test_prioq_SOURCES = \
@@ -1346,6 +1625,25 @@ test_log_SOURCES = \
 test_log_LDADD = \
        libsystemd-core.la
 
+test_ipcrm_SOURCES = \
+       src/test/test-ipcrm.c
+
+test_ipcrm_LDADD = \
+       libsystemd-shared.la \
+       -lrt
+
+test_rtnl_manual_SOURCES = \
+       src/test/test-rtnl-manual.c
+
+test_rtnl_manual_CFLAGS = \
+       $(AM_CFLAGS) \
+       $(KMOD_CFLAGS)
+
+test_rtnl_manual_LDADD = \
+       libsystemd-internal.la \
+       libsystemd-shared.la \
+       $(KMOD_LIBS)
+
 test_ellipsize_SOURCES = \
        src/test/test-ellipsize.c
 
@@ -1482,12 +1780,18 @@ test_sched_prio_LDADD = \
        libsystemd-core.la \
        $(RT_LIBS)
 
+test_conf_files_SOURCES = \
+       src/test/test-conf-files.c
+
+test_conf_files_LDADD = \
+       libsystemd-shared.la
+
 # ------------------------------------------------------------------------------
 ## .PHONY so it always rebuilds it
 .PHONY: coverage lcov-run lcov-report coverage-sync
 
 # run lcov from scratch, always
-coverage:
+coverage: all
        $(MAKE) lcov-run
        $(MAKE) lcov-report
 
@@ -1522,11 +1826,19 @@ endif
 
 # ------------------------------------------------------------------------------
 systemd_analyze_SOURCES = \
-       src/analyze/analyze.c
+       src/analyze/analyze.c \
+       src/analyze/analyze-verify.c \
+       src/analyze/analyze-verify.h
+
+systemd_verify_CFLAGS = \
+       $(AM_CFLAGS) \
+       $(SECCOMP_CFLAGS)
 
 systemd_analyze_LDADD = \
+       libsystemd-core.la \
        libsystemd-internal.la \
-       libsystemd-shared.la
+       libsystemd-shared.la \
+       $(RT_LIBS)
 
 # ------------------------------------------------------------------------------
 systemd_initctl_SOURCES = \
@@ -1550,6 +1862,15 @@ systemd_update_utmp_LDADD = \
        $(AUDIT_LIBS)
 
 # ------------------------------------------------------------------------------
+systemd_update_done_SOURCES = \
+       src/update-done/update-done.c
+
+systemd_update_done_LDADD = \
+       libsystemd-internal.la \
+       libsystemd-label.la \
+       libsystemd-shared.la
+
+# ------------------------------------------------------------------------------
 systemd_shutdownd_SOURCES = \
        src/shutdownd/shutdownd.c
 
@@ -1608,8 +1929,8 @@ endif
 endif
 
 EXTRA_DIST += \
-        units/systemd-modules-load.service.in \
-        units/kmod-static-nodes.service.in
+       units/systemd-modules-load.service.m4.in \
+       units/kmod-static-nodes.service.m4.in
 
 # ------------------------------------------------------------------------------
 if ENABLE_TMPFILES
@@ -1637,8 +1958,11 @@ nodist_systemunit_DATA += \
 dist_tmpfiles_DATA = \
        tmpfiles.d/systemd.conf \
        tmpfiles.d/systemd-nologin.conf \
+       tmpfiles.d/systemd-remote.conf \
        tmpfiles.d/tmp.conf \
-       tmpfiles.d/x11.conf
+       tmpfiles.d/x11.conf \
+       tmpfiles.d/var.conf \
+       tmpfiles.d/etc.conf
 
 if HAVE_SYSV_COMPAT
 dist_tmpfiles_DATA += \
@@ -1661,9 +1985,83 @@ INSTALL_DIRS += \
 endif
 
 EXTRA_DIST += \
-       units/systemd-tmpfiles-setup-dev.service.in \
-       units/systemd-tmpfiles-setup.service.in \
-       units/systemd-tmpfiles-clean.service.in
+       units/systemd-tmpfiles-setup-dev.service.m4.in \
+       units/systemd-tmpfiles-setup.service.m4.in \
+       units/systemd-tmpfiles-clean.service.m4.in
+
+# ------------------------------------------------------------------------------
+if ENABLE_SYSUSERS
+systemd_sysusers_SOURCES = \
+       src/sysusers/sysusers.c
+
+systemd_sysusers_LDADD = \
+       libsystemd-units.la \
+       libsystemd-label.la \
+       libsystemd-capability.la \
+       libsystemd-internal.la \
+       libsystemd-shared.la
+
+rootbin_PROGRAMS += \
+       systemd-sysusers
+
+nodist_systemunit_DATA += \
+       units/systemd-sysusers.service
+
+SYSINIT_TARGET_WANTS += \
+       systemd-sysusers.service
+
+dist_sysusers_DATA = \
+       sysusers.d/systemd.conf \
+       sysusers.d/systemd-remote.conf
+
+nodist_sysusers_DATA = \
+       sysusers.d/basic.conf
+
+EXTRA_DIST += \
+       sysusers.d/systemd.conf.m4 \
+       units/systemd-sysusers.service.m4.in \
+       sysusers.d/basic.conf.in
+
+CLEANFILES += \
+       sysusers.d/basic.conf
+
+INSTALL_DIRS += \
+       $(sysusersdir)
+endif
+
+# ------------------------------------------------------------------------------
+dist_factory_etc_DATA = \
+    factory/etc/nsswitch.conf
+
+dist_factory_pam_DATA = \
+       factory/etc/pam.d/system-auth \
+       factory/etc/pam.d/other
+
+# ------------------------------------------------------------------------------
+if ENABLE_FIRSTBOOT
+systemd_firstboot_SOURCES = \
+       src/firstboot/firstboot.c
+
+systemd_firstboot_LDADD = \
+       libsystemd-units.la \
+       libsystemd-label.la \
+       libsystemd-capability.la \
+       libsystemd-internal.la \
+       libsystemd-shared.la \
+       -lcrypt
+
+rootbin_PROGRAMS += \
+       systemd-firstboot
+
+nodist_systemunit_DATA += \
+       units/systemd-firstboot.service
+
+EXTRA_DIST += \
+       units/systemd-firstboot.service.in
+
+SYSINIT_TARGET_WANTS += \
+       systemd-firstboot.service
+endif
 
 # ------------------------------------------------------------------------------
 systemd_machine_id_setup_SOURCES = \
@@ -1714,9 +2112,6 @@ systemd_detect_virt_SOURCES = \
 systemd_detect_virt_LDADD = \
        libsystemd-shared.la
 
-systemd-detect-virt-install-hook:
-       -$(SETCAP) cap_dac_override,cap_sys_ptrace=ep $(DESTDIR)$(bindir)/systemd-detect-virt
-
 INSTALL_EXEC_HOOKS += \
        systemd-detect-virt-install-hook
 
@@ -1736,6 +2131,14 @@ systemd_getty_generator_LDADD = \
        libsystemd-shared.la
 
 # ------------------------------------------------------------------------------
+systemd_debug_generator_SOURCES = \
+       src/debug-generator/debug-generator.c
+
+systemd_debug_generator_LDADD = \
+       libsystemd-label.la \
+       libsystemd-shared.la
+
+# ------------------------------------------------------------------------------
 systemd_fstab_generator_SOURCES = \
        src/fstab-generator/fstab-generator.c \
        src/core/mount-setup.c
@@ -1793,7 +2196,8 @@ systemgenerator_PROGRAMS +=  \
        systemd-gpt-auto-generator
 
 systemd_gpt_auto_generator_SOURCES = \
-       src/gpt-auto-generator/gpt-auto-generator.c
+       src/gpt-auto-generator/gpt-auto-generator.c \
+       src/shared/blkid-util.h
 
 systemd_gpt_auto_generator_LDADD = \
        libsystemd-label.la \
@@ -1820,9 +2224,17 @@ systemd_dbus1_generator_LDADD = \
        libsystemd-shared.la \
        libsystemd-internal.la
 
+if CONFIG_TIZEN_WIP
 dbus1-generator-install-hook:
        $(AM_V_at)$(MKDIR_P) $(DESTDIR)$(usergeneratordir)
+       $(AM_V_RM)rm -f $(DESTDIR)$(usergeneratordir)/systemd-dbus1-generator
        $(AM_V_LN)$(LN_S) -f $(systemgeneratordir)/systemd-dbus1-generator $(DESTDIR)$(usergeneratordir)/systemd-dbus1-generator
+else
+dbus1-generator-install-hook:
+       $(AM_V_at)$(MKDIR_P) $(DESTDIR)$(usergeneratordir)
+       $(AM_V_RM)rm -f $(DESTDIR)$(usergeneratordir)/systemd-dbus1-generator
+       $(AM_V_LN)$(LN_S) --relative -f $(DESTDIR)$(systemgeneratordir)/systemd-dbus1-generator $(DESTDIR)$(usergeneratordir)/systemd-dbus1-generator
+endif
 
 dbus1-generator-uninstall-hook:
        rm -f $(DESTDIR)$(usergeneratordir)/systemd-dbus1-generator
@@ -1832,6 +2244,15 @@ UNINSTALL_EXEC_HOOKS += dbus1-generator-uninstall-hook
 endif
 
 # ------------------------------------------------------------------------------
+systemd_sysv_generator_SOURCES = \
+       src/sysv-generator/sysv-generator.c
+
+systemd_sysv_generator_LDADD = \
+       libsystemd-core.la \
+       libsystemd-label.la \
+       libsystemd-shared.la
+
+# ------------------------------------------------------------------------------
 systemd_rc_local_generator_SOURCES = \
        src/rc-local-generator/rc-local-generator.c
 
@@ -1858,6 +2279,13 @@ systemd_cgroups_agent_LDADD = \
        libsystemd-shared.la
 
 # ------------------------------------------------------------------------------
+systemd_escape_SOURCES = \
+       src/escape/escape.c
+
+systemd_escape_LDADD = \
+       libsystemd-shared.la
+
+# -----------------------------------------------------------------------------
 systemctl_SOURCES = \
        src/systemctl/systemctl.c
 
@@ -1879,6 +2307,14 @@ systemd_notify_LDADD = \
        libsystemd-shared.la
 
 # ------------------------------------------------------------------------------
+systemd_path_SOURCES = \
+       src/path/path.c
+
+systemd_path_LDADD = \
+       libsystemd-internal.la \
+       libsystemd-shared.la
+
+# ------------------------------------------------------------------------------
 systemd_ask_password_SOURCES = \
        src/ask-password/ask-password.c
 
@@ -1898,6 +2334,7 @@ systemd_cgls_SOURCES = \
        src/cgls/cgls.c
 
 systemd_cgls_LDADD = \
+       libsystemd-internal.la \
        libsystemd-shared.la
 
 # ------------------------------------------------------------------------------
@@ -1917,14 +2354,16 @@ systemd_nspawn_SOURCES = \
 
 systemd_nspawn_CFLAGS = \
        $(AM_CFLAGS) \
-       $(SECCOMP_CFLAGS)
+       $(SECCOMP_CFLAGS) \
+       $(BLKID_CFLAGS)
 
 systemd_nspawn_LDADD = \
        libsystemd-label.la \
        libsystemd-capability.la \
        libsystemd-internal.la \
        libudev-internal.la \
-       libsystemd-shared.la
+       libsystemd-shared.la \
+       $(BLKID_LIBS)
 
 if HAVE_SECCOMP
 systemd_nspawn_LDADD += \
@@ -1944,15 +2383,26 @@ systemd_run_LDADD = \
 
 # ------------------------------------------------------------------------------
 systemd_bus_proxyd_SOURCES = \
-       src/bus-proxyd/bus-proxyd.c
+       src/bus-proxyd/bus-proxyd.c \
+       src/bus-proxyd/bus-policy.c \
+       src/bus-proxyd/bus-policy.h
 
 systemd_bus_proxyd_LDADD = \
+       libsystemd-capability.la \
        libsystemd-internal.la \
        libsystemd-shared.la
 
+if CONFIG_TIZEN_WIP
 bus-proxyd-install-hook:
        $(AM_V_at)$(MKDIR_P) $(DESTDIR)$(bindir)
-       $(AM_V_LN)$(LN_S) -f ../lib/systemd/systemd-bus-proxyd $(DESTDIR)$(bindir)/systemd-stdio-bridge
+       $(AM_V_RM)rm -f $(DESTDIR)$(bindir)/systemd-stdio-bridge
+       $(AM_V_LN)$(LN_S) -f $(rootlibexecdir)/systemd-bus-proxyd $(DESTDIR)$(bindir)/systemd-stdio-bridge
+else
+bus-proxyd-install-hook:
+       $(AM_V_at)$(MKDIR_P) $(DESTDIR)$(bindir)
+       $(AM_V_RM)rm -f $(DESTDIR)$(bindir)/systemd-stdio-bridge
+       $(AM_V_LN)$(LN_S) --relative -f $(DESTDIR)$(rootlibexecdir)/systemd-bus-proxyd $(DESTDIR)$(bindir)/systemd-stdio-bridge
+endif
 
 bus-proxyd-uninstall-hook:
        rm -f $(DESTDIR)$(bindir)/systemd-stdio-bridge
@@ -1996,6 +2446,8 @@ libsystemd_internal_la_SOURCES = \
        src/systemd/sd-login.h \
        src/systemd/sd-id128.h \
        src/systemd/sd-daemon.h \
+       src/systemd/sd-path.h \
+       src/systemd/sd-network.h \
        src/libsystemd/sd-bus/sd-bus.c \
        src/libsystemd/sd-bus/bus-control.c \
        src/libsystemd/sd-bus/bus-control.h \
@@ -2028,8 +2480,12 @@ libsystemd_internal_la_SOURCES = \
        src/libsystemd/sd-bus/bus-gvariant.c \
        src/libsystemd/sd-bus/bus-gvariant.h \
        src/libsystemd/sd-bus/bus-convenience.c \
+       src/libsystemd/sd-bus/bus-track.c \
+       src/libsystemd/sd-bus/bus-track.h \
        src/libsystemd/sd-bus/bus-util.c \
        src/libsystemd/sd-bus/bus-util.h \
+       src/libsystemd/sd-bus/bus-slot.c \
+       src/libsystemd/sd-bus/bus-slot.h \
        src/libsystemd/sd-bus/bus-protocol.h \
        src/libsystemd/sd-bus/kdbus.h \
        src/libsystemd/sd-bus/sd-memfd.c \
@@ -2039,15 +2495,19 @@ libsystemd_internal_la_SOURCES = \
        src/libsystemd/sd-rtnl/sd-rtnl.c \
        src/libsystemd/sd-rtnl/rtnl-internal.h \
        src/libsystemd/sd-rtnl/rtnl-message.c \
+       src/libsystemd/sd-rtnl/rtnl-types.h \
+       src/libsystemd/sd-rtnl/rtnl-types.c \
        src/libsystemd/sd-rtnl/rtnl-util.h \
        src/libsystemd/sd-rtnl/rtnl-util.c \
-       src/libsystemd/sd-resolve/sd-resolve.c \
-       src/libsystemd/sd-resolve/resolve-util.h \
+       src/libsystemd/sd-rtnl/local-addresses.h \
+       src/libsystemd/sd-rtnl/local-addresses.c \
        src/libsystemd/sd-id128/sd-id128.c \
        src/libsystemd/sd-daemon/sd-daemon.c \
-       src/login/sd-login.c \
-       src/login/login-shared.c \
-       src/login/login-shared.h
+       src/libsystemd/sd-login/sd-login.c \
+       src/libsystemd/sd-path/sd-path.c \
+       src/libsystemd/sd-network/sd-network.c \
+       src/libsystemd/sd-network/network-util.h \
+       src/libsystemd/sd-network/network-util.c
 
 nodist_libsystemd_internal_la_SOURCES = \
        src/libsystemd/libsystemd.sym \
@@ -2060,8 +2520,20 @@ libsystemd_internal_la_CFLAGS = \
 libsystemd_internal_la_LIBADD = \
        $(RT_LIBS)
 
+libsystemd_resolve_la_SOURCES = \
+       src/libsystemd/sd-resolve/sd-resolve.c \
+       src/libsystemd/sd-resolve/resolve-util.h
+
+libsystemd_resolve_la_CFLAGS = \
+       $(AM_CFLAGS) \
+       -pthread
+
+libsystemd_resolve_la_LIBADD = \
+       -lresolv
+
 noinst_LTLIBRARIES += \
-       libsystemd-internal.la
+       libsystemd-internal.la \
+       libsystemd-resolve.la
 
 libsystemd_dump_la_SOURCES = \
        src/libsystemd/sd-bus/bus-dump.c \
@@ -2090,6 +2562,7 @@ BUILT_SOURCES += \
 
 libsystemd_la_SOURCES = \
        $(libsystemd_internal_la_SOURCES) \
+       $(libsystemd_resolve_la_SOURCES) \
        $(libsystemd_journal_internal_la_SOURCES)
 
 nodist_libsystemd_la_SOURCES = \
@@ -2097,6 +2570,7 @@ nodist_libsystemd_la_SOURCES = \
 
 libsystemd_la_CFLAGS = \
        $(libsystemd_internal_la_CFLAGS) \
+       $(libsystemd_resolve_la_CFLAGS) \
        $(libsystemd_journal_internal_la_CFLAGS)
 
 libsystemd_la_LDFLAGS = \
@@ -2106,9 +2580,9 @@ libsystemd_la_LDFLAGS = \
 
 libsystemd_la_LIBADD = \
        libsystemd-shared.la \
+       $(libsystemd_internal_la_LIBADD) \
        $(libsystemd_journal_internal_la_LIBADD) \
-       $(RT_LIBS) \
-       -lresolv
+       $(libsystemd_resolve_la_LIBADD)
 
 libsystemd-install-hook:
        libname=libsystemd.so && $(move-to-rootlibdir)
@@ -2136,7 +2610,8 @@ pkginclude_HEADERS += \
        src/systemd/sd-utf8.h \
        src/systemd/sd-event.h \
        src/systemd/sd-rtnl.h \
-       src/systemd/sd-resolve.h
+       src/systemd/sd-resolve.h \
+       src/systemd/sd-path.h
 endif
 
 lib_LTLIBRARIES += \
@@ -2349,13 +2824,12 @@ test_rtnl_LDADD = \
        libsystemd-shared.la
 
 test_resolve_SOURCES = \
-       src/systemd/sd-resolve.h \
        src/libsystemd/sd-resolve/test-resolve.c
 
 test_resolve_LDADD = \
+       libsystemd-resolve.la \
        libsystemd-internal.la \
-       libsystemd-shared.la \
-       -lresolv
+       libsystemd-shared.la
 
 test_resolve_CFLAGS = \
        $(AM_CFLAGS) \
@@ -2377,52 +2851,201 @@ busctl_CFLAGS = \
 
 # ------------------------------------------------------------------------------
 noinst_LTLIBRARIES += \
-       libsystemd-dhcp.la
+       libsystemd-network.la
 
-libsystemd_dhcp_la_SOURCES = \
+libsystemd_network_la_CFLAGS = \
+       $(AM_CFLAGS) \
+       $(KMOD_CFLAGS)
+
+libsystemd_network_la_SOURCES = \
        src/systemd/sd-dhcp-client.h \
-       src/libsystemd-dhcp/sd-dhcp-client.c \
-       src/libsystemd-dhcp/dhcp-lease.h \
-       src/libsystemd-dhcp/dhcp-lease.c \
-       src/libsystemd-dhcp/dhcp-network.c \
-       src/libsystemd-dhcp/dhcp-option.c \
-       src/libsystemd-dhcp/dhcp-packet.c \
-       src/libsystemd-dhcp/dhcp-internal.h \
-       src/libsystemd-dhcp/dhcp-protocol.h
-
-libsystemd_dhcp_la_LIBADD = \
+       src/systemd/sd-dhcp-server.h \
+       src/systemd/sd-dhcp-lease.h \
+       src/systemd/sd-ipv4ll.h \
+       src/systemd/sd-icmp6-nd.h \
+       src/systemd/sd-dhcp6-client.h \
+       src/systemd/sd-dhcp6-lease.h \
+       src/libsystemd-network/sd-dhcp-client.c \
+       src/libsystemd-network/sd-dhcp-server.c \
+       src/libsystemd-network/dhcp-network.c \
+       src/libsystemd-network/dhcp-option.c \
+       src/libsystemd-network/dhcp-packet.c \
+       src/libsystemd-network/dhcp-internal.h \
+       src/libsystemd-network/dhcp-server-internal.h \
+       src/libsystemd-network/dhcp-protocol.h \
+       src/libsystemd-network/dhcp-lease-internal.h \
+       src/libsystemd-network/sd-dhcp-lease.c \
+       src/libsystemd-network/sd-ipv4ll.c \
+       src/libsystemd-network/ipv4ll-network.c \
+       src/libsystemd-network/ipv4ll-packet.c \
+       src/libsystemd-network/ipv4ll-internal.h \
+       src/libsystemd-network/network-internal.c \
+       src/libsystemd-network/network-internal.h \
+       src/libsystemd-network/sd-icmp6-nd.c \
+       src/libsystemd-network/sd-dhcp6-client.c \
+       src/libsystemd-network/dhcp6-internal.h \
+       src/libsystemd-network/dhcp6-protocol.h \
+       src/libsystemd-network/dhcp6-network.c \
+       src/libsystemd-network/dhcp6-option.c \
+       src/libsystemd-network/dhcp6-lease-internal.h \
+       src/libsystemd-network/sd-dhcp6-lease.c
+
+libsystemd_network_la_LIBADD = \
+       libudev-internal.la \
+       libsystemd-label.la \
        libsystemd-internal.la \
-       libsystemd-shared.la
+       libsystemd-shared.la \
+       $(KMOD_LIBS)
 
 test_dhcp_option_SOURCES = \
-       src/libsystemd-dhcp/dhcp-protocol.h \
-       src/libsystemd-dhcp/dhcp-internal.h \
-       src/libsystemd-dhcp/test-dhcp-option.c
+       src/libsystemd-network/dhcp-protocol.h \
+       src/libsystemd-network/dhcp-internal.h \
+       src/libsystemd-network/test-dhcp-option.c
 
 test_dhcp_option_LDADD = \
-       libsystemd-dhcp.la \
+       libsystemd-network.la \
        libsystemd-internal.la \
        libsystemd-shared.la
 
 test_dhcp_client_SOURCES = \
        src/systemd/sd-dhcp-client.h \
-       src/libsystemd-dhcp/dhcp-protocol.h \
-       src/libsystemd-dhcp/dhcp-internal.h \
-       src/libsystemd-dhcp/test-dhcp-client.c
+       src/libsystemd-network/dhcp-protocol.h \
+       src/libsystemd-network/dhcp-internal.h \
+       src/libsystemd-network/test-dhcp-client.c
 
 test_dhcp_client_LDADD = \
-       libsystemd-dhcp.la \
+       libsystemd-network.la \
+       libsystemd-label.la \
        libsystemd-internal.la \
        libsystemd-shared.la
 
-tests += \
-       test-dhcp-option \
-       test-dhcp-client
-
-# ------------------------------------------------------------------------------
-if ENABLE_GTK_DOC
-SUBDIRS += \
-       docs/libudev
+test_dhcp_server_SOURCES = \
+       src/libsystemd-network/test-dhcp-server.c
+
+test_dhcp_server_LDADD = \
+       libsystemd-network.la \
+       libsystemd-internal.la \
+       libsystemd-shared.la
+
+test_ipv4ll_SOURCES = \
+       src/systemd/sd-ipv4ll.h \
+       src/libsystemd-network/ipv4ll-internal.h \
+       src/libsystemd-network/test-ipv4ll.c
+
+test_ipv4ll_LDADD = \
+       libsystemd-network.la \
+       libsystemd-label.la \
+       libsystemd-internal.la \
+       libsystemd-shared.la
+
+test_icmp6_rs_SOURCES = \
+       src/systemd/sd-dhcp6-client.h \
+       src/systemd/sd-icmp6-nd.h \
+       src/libsystemd-network/dhcp6-internal.h \
+       src/libsystemd-network/test-icmp6-rs.c
+
+test_icmp6_rs_LDADD = \
+       libsystemd-network.la \
+       libsystemd-internal.la \
+       libsystemd-shared.la
+
+test_dhcp6_client_SOURCES = \
+       src/systemd/sd-dhcp6-client.h \
+       src/libsystemd-network/dhcp6-internal.h \
+       src/libsystemd-network/test-dhcp6-client.c
+
+test_dhcp6_client_LDADD = \
+       libsystemd-network.la \
+       libsystemd-internal.la \
+       libsystemd-shared.la
+
+tests += \
+       test-dhcp-option \
+       test-dhcp-client \
+       test-dhcp-server \
+       test-ipv4ll \
+       test-icmp6-rs \
+       test-dhcp6-client
+
+# ------------------------------------------------------------------------------
+if ENABLE_TERMINAL
+noinst_LTLIBRARIES += \
+       libsystemd-terminal.la
+
+noinst_PROGRAMS += \
+       systemd-subterm
+
+unifontdatadir=$(datadir)/unifont
+
+dist_unifontdata_DATA = \
+       src/libsystemd-terminal/unifont-glyph-array.bin
+
+tests += \
+       test-term-page \
+       test-term-parser \
+       test-unifont
+endif
+
+libsystemd_terminal_la_CFLAGS = \
+       $(AM_CFLAGS)
+
+libsystemd_terminal_la_SOURCES = \
+       src/libsystemd-terminal/term-internal.h \
+       src/libsystemd-terminal/term-charset.c \
+       src/libsystemd-terminal/term-page.c \
+       src/libsystemd-terminal/term-parser.c \
+       src/libsystemd-terminal/term-screen.c \
+       src/libsystemd-terminal/term-wcwidth.c \
+       src/libsystemd-terminal/unifont-internal.h \
+       src/libsystemd-terminal/unifont.c
+
+libsystemd_terminal_la_LIBADD = \
+       libsystemd-internal.la \
+       libsystemd-shared.la
+
+systemd_subterm_SOURCES = \
+       src/libsystemd-terminal/subterm.c
+
+systemd_subterm_LDADD = \
+       libsystemd-terminal.la \
+       libsystemd-internal.la \
+       libsystemd-shared.la
+
+test_term_page_SOURCES = \
+       src/libsystemd-terminal/test-term-page.c
+
+test_term_page_LDADD = \
+       libsystemd-terminal.la \
+       libsystemd-internal.la \
+       libsystemd-shared.la
+
+test_term_parser_SOURCES = \
+       src/libsystemd-terminal/test-term-parser.c
+
+test_term_parser_LDADD = \
+       libsystemd-terminal.la \
+       libsystemd-internal.la \
+       libsystemd-shared.la
+
+test_unifont_SOURCES = \
+       src/libsystemd-terminal/test-unifont.c
+
+test_unifont_LDADD = \
+       libsystemd-terminal.la \
+       libsystemd-internal.la \
+       libsystemd-shared.la
+
+.PHONY: update-unifont
+update-unifont: tools/compile-unifont.py
+       $(AM_V_GEN)$(PYTHON) $< \
+               <$(top_srcdir)/src/libsystemd-terminal/unifont.hex \
+               >$(top_srcdir)/src/libsystemd-terminal/unifont-glyph-array.bin
+       @echo "unifont-glyph-array.bin has been regenerated"
+
+# ------------------------------------------------------------------------------
+if ENABLE_GTK_DOC
+SUBDIRS += \
+       docs/libudev
 
 noinst_DATA += \
        docs/html/libudev \
@@ -2496,8 +3119,7 @@ noinst_LTLIBRARIES += \
 
 libudev_internal_la_SOURCES =\
        $(libudev_la_SOURCES) \
-       src/libudev/libudev-device-private.c \
-       src/libudev/libudev-queue-private.c
+       src/libudev/libudev-device-private.c
 
 libudev_internal_la_CFLAGS = \
        $(AM_CFLAGS) \
@@ -2510,10 +3132,10 @@ INSTALL_DIRS += \
 
 dist_network_DATA = \
        network/99-default.link \
-       network/80-container-host0.network
+       network/80-container-host0.network \
+       network/80-container-ve.network
 
 dist_udevrules_DATA += \
-       rules/99-systemd.rules \
        rules/42-usb-hid-pm.rules \
        rules/50-udev-default.rules \
        rules/60-drm.rules \
@@ -2530,6 +3152,9 @@ dist_udevrules_DATA += \
        rules/80-net-setup-link.rules \
        rules/95-udev-late.rules
 
+nodist_udevrules_DATA += \
+       rules/99-systemd.rules
+
 dist_udevhwdb_DATA = \
        hwdb/20-pci-vendor-model.hwdb \
        hwdb/20-pci-classes.hwdb \
@@ -2560,21 +3185,25 @@ CLEANFILES += \
        src/udev/udev.pc
 
 EXTRA_DIST += \
-       units/systemd-udevd.service.in \
-       units/systemd-udev-trigger.service.in \
-       units/systemd-udev-settle.service.in
+       units/systemd-udevd.service.m4.in \
+       units/systemd-udev-trigger.service.m4.in \
+       units/systemd-udev-settle.service.m4.in \
+       units/systemd-udev-hwdb-update.service.m4.in
 
 CLEANFILES += \
        units/systemd-udevd.service \
        units/systemd-udev-trigger.service \
-       units/systemd-udev-settle.service
+       units/systemd-udev-settle.service \
+       units/systemd-udev-hwdb-update.service
 
 SOCKETS_TARGET_WANTS += \
        systemd-udevd-control.socket \
        systemd-udevd-kernel.socket
+
 SYSINIT_TARGET_WANTS += \
        systemd-udevd.service \
-       systemd-udev-trigger.service
+       systemd-udev-trigger.service \
+       systemd-udev-hwdb-update.service
 
 rootbin_PROGRAMS += \
        udevadm
@@ -2644,6 +3273,7 @@ libudev_core_la_LIBADD = \
        libudev-internal.la \
        libsystemd-label.la \
        libsystemd-internal.la \
+       libsystemd-network.la \
        libsystemd-shared.la \
        $(BLKID_LIBS) \
        $(KMOD_LIBS)
@@ -2677,10 +3307,8 @@ if HAVE_ACL
 libudev_core_la_SOURCES += \
        src/udev/udev-builtin-uaccess.c \
        src/login/logind-acl.c \
-       src/login/sd-login.c \
-       src/systemd/sd-login.h \
-       src/login/login-shared.c \
-       src/login/login-shared.h
+       src/libsystemd/sd-login/sd-login.c \
+       src/systemd/sd-login.h
 
 libudev_core_la_LIBADD += \
        libsystemd-acl.la
@@ -2874,6 +3502,7 @@ CLEANFILES += \
        src/gudev/gudev-1.0.pc
 
 libgudev_1_0_la_SOURCES = \
+       src/gudev/libgudev-1.0.sym \
        src/gudev/gudevenums.h \
        src/gudev/gudevenumtypes.h \
        src/gudev/gudevenumtypes.h\
@@ -2917,8 +3546,9 @@ libgudev_1_0_la_LIBADD = \
 libgudev_1_0_la_LDFLAGS = \
        $(AM_LDFLAGS) \
        -version-info $(LIBGUDEV_CURRENT):$(LIBGUDEV_REVISION):$(LIBGUDEV_AGE) \
-       -export-dynamic -no-undefined \
-       -export-symbols-regex '^g_udev_.*'
+       -export-dynamic \
+       -no-undefined \
+       -Wl,--version-script=$(top_srcdir)/src/gudev/libgudev-1.0.sym
 
 src/gudev/gudevmarshal.h: src/gudev/gudevmarshal.list
        $(AM_V_at)$(MKDIR_P) $(dir $@)
@@ -2981,16 +3611,6 @@ typelibs_DATA = \
 
 CLEANFILES += $(gir_DATA) $(typelibs_DATA)
 endif # HAVE_INTROSPECTION
-
-# move lib from $(libdir) to $(rootlibdir) and update devel link, if needed
-libgudev-install-hook:
-       libname=libgudev-1.0.so && $(move-to-rootlibdir)
-
-libgudev-uninstall-hook:
-       rm -f $(DESTDIR)$(rootlibdir)/libgudev-1.0.so*
-
-INSTALL_EXEC_HOOKS += libgudev-install-hook
-UNINSTALL_EXEC_HOOKS += libgudev-uninstall-hook
 endif
 
 EXTRA_DIST += \
@@ -3054,6 +3674,102 @@ systemd_cat_SOURCES = \
 systemd_cat_LDADD = \
        libsystemd-journal-core.la
 
+if HAVE_MICROHTTPD
+rootlibexec_PROGRAMS += \
+       systemd-journal-remote
+
+systemd_journal_remote_SOURCES = \
+       src/journal-remote/journal-remote-parse.h \
+       src/journal-remote/journal-remote-parse.c \
+       src/journal-remote/journal-remote-write.h \
+       src/journal-remote/journal-remote-write.c \
+       src/journal-remote/journal-remote.h \
+       src/journal-remote/journal-remote.c
+
+systemd_journal_remote_LDADD = \
+       libsystemd-internal.la \
+       libsystemd-journal-core.la
+
+systemd_journal_remote_SOURCES += \
+       src/journal-remote/microhttpd-util.h \
+       src/journal-remote/microhttpd-util.c
+
+systemd_journal_remote_CFLAGS = \
+       $(AM_CFLAGS) \
+       $(MICROHTTPD_CFLAGS)
+
+systemd_journal_remote_LDADD += \
+       $(MICROHTTPD_LIBS)
+
+if HAVE_GNUTLS
+systemd_journal_remote_LDADD += \
+       $(GNUTLS_LIBS)
+
+# systemd-journal-remote make sense mostly with full crypto stack
+dist_systemunit_DATA += \
+       units/systemd-journal-remote.socket
+
+nodist_systemunit_DATA += \
+       units/systemd-journal-remote.service
+
+EXTRA_DIST += \
+       units/systemd-journal-remote.service.in
+
+journal-remote-install-hook: journal-install-hook
+       -$(MKDIR_P) $(DESTDIR)/var/log/journal/remote
+       -chown 0:0 $(DESTDIR)/var/log/journal/remote
+       -chmod 755 $(DESTDIR)/var/log/journal/remote
+
+INSTALL_EXEC_HOOKS += journal-remote-install-hook
+
+endif
+
+nodist_pkgsysconf_DATA += \
+       src/journal-remote/journal-remote.conf
+
+EXTRA_DIST += \
+       src/journal-remote/journal-remote.conf.in
+
+CLEANFILES += \
+       src/journal-remote/journal-remote.conf
+endif
+
+if HAVE_LIBCURL
+rootlibexec_PROGRAMS += \
+       systemd-journal-upload
+
+systemd_journal_upload_SOURCES = \
+       src/journal-remote/journal-upload.h \
+       src/journal-remote/journal-upload.c \
+       src/journal-remote/journal-upload-journal.c
+
+systemd_journal_upload_CFLAGS = \
+       $(AM_CFLAGS) \
+       $(LIBCURL_CFLAGS)
+
+systemd_journal_upload_LDADD = \
+       libsystemd-core.la \
+       libsystemd-internal.la \
+       libsystemd-journal-internal.la \
+       libsystemd-shared.la \
+       $(LIBCURL_LIBS)
+
+nodist_systemunit_DATA += \
+       units/systemd-journal-upload.service
+
+EXTRA_DIST += \
+       units/systemd-journal-upload.service.in
+
+nodist_pkgsysconf_DATA += \
+       src/journal-remote/journal-upload.conf
+
+EXTRA_DIST += \
+       src/journal-remote/journal-upload.conf.in
+
+CLEANFILES += \
+       src/journal-remote/journal-upload.conf
+endif
+
 # using _CFLAGS = in the conditional below would suppress AM_CFLAGS
 journalctl_CFLAGS = \
        $(AM_CFLAGS)
@@ -3160,6 +3876,20 @@ test_catalog_CPPFLAGS = \
 test_catalog_LDADD = \
        libsystemd-journal-core.la
 
+test_compress_SOURCES = \
+       src/journal/test-compress.c
+
+test_compress_LDADD = \
+       libsystemd-journal-internal.la \
+       libsystemd-shared.la
+
+test_compress_benchmark_SOURCES = \
+       src/journal/test-compress-benchmark.c
+
+test_compress_benchmark_LDADD = \
+       libsystemd-journal-internal.la \
+       libsystemd-shared.la
+
 libsystemd_journal_core_la_SOURCES = \
        src/journal/journald-kmsg.c \
        src/journal/journald-kmsg.h \
@@ -3171,6 +3901,8 @@ libsystemd_journal_core_la_SOURCES = \
        src/journal/journald-server.h \
        src/journal/journald-console.c \
        src/journal/journald-console.h \
+       src/journal/journald-wall.c \
+       src/journal/journald-wall.h \
        src/journal/journald-native.c \
        src/journal/journald-native.h \
        src/journal/journald-rate-limit.c \
@@ -3204,6 +3936,7 @@ journal-install-hook:
        -setfacl -nm g:wheel:rx,d:g:wheel:rx $(DESTDIR)/var/log/journal/
 
 journal-uninstall-hook:
+       -rmdir $(DESTDIR)/var/log/journal/remote
        -rmdir $(DESTDIR)/var/log/journal/
 
 INSTALL_EXEC_HOOKS += journal-install-hook
@@ -3240,6 +3973,12 @@ tests += \
        test-mmap-cache \
        test-catalog
 
+if HAVE_COMPRESSION
+tests += \
+       test-compress \
+       test-compress-benchmark
+endif
+
 pkginclude_HEADERS += \
        src/systemd/sd-journal.h \
        src/systemd/sd-messages.h \
@@ -3266,15 +4005,15 @@ libsystemd_journal_internal_la_SOURCES = \
        src/journal/mmap-cache.h
 
 # using _CFLAGS = in the conditional below would suppress AM_CFLAGS
-libsystemd_journal_internal_la_CFLAGS =
+libsystemd_journal_internal_la_CFLAGS = \
        $(AM_CFLAGS)
 
 libsystemd_journal_internal_la_LIBADD =
 
-if HAVE_XZ
 libsystemd_journal_internal_la_SOURCES += \
        src/journal/compress.c
 
+if HAVE_XZ
 libsystemd_journal_internal_la_CFLAGS += \
        $(XZ_CFLAGS)
 
@@ -3282,6 +4021,11 @@ libsystemd_journal_internal_la_LIBADD += \
        $(XZ_LIBS)
 endif
 
+if HAVE_LZ4
+libsystemd_journal_internal_la_LIBADD += \
+       -llz4
+endif
+
 if HAVE_GCRYPT
 libsystemd_journal_internal_la_SOURCES += \
        src/journal/journal-authenticate.c \
@@ -3311,11 +4055,13 @@ bin_PROGRAMS += \
        systemd-cat
 
 dist_systemunit_DATA += \
-       units/systemd-journald.socket
+       units/systemd-journald.socket \
+       units/systemd-journald-dev-log.socket
 
 nodist_systemunit_DATA += \
        units/systemd-journald.service \
-       units/systemd-journal-flush.service
+       units/systemd-journal-flush.service \
+       units/systemd-journal-catalog-update.service
 
 dist_pkgsysconf_DATA += \
        src/journal/journald.conf
@@ -3327,14 +4073,18 @@ dist_catalog_DATA = \
        catalog/systemd.catalog
 
 SOCKETS_TARGET_WANTS += \
-       systemd-journald.socket
+       systemd-journald.socket \
+       systemd-journald-dev-log.socket
+
 SYSINIT_TARGET_WANTS += \
        systemd-journald.service \
-       systemd-journal-flush.service
+       systemd-journal-flush.service \
+       systemd-journal-catalog-update.service
 
 EXTRA_DIST += \
        units/systemd-journald.service.in \
-       units/systemd-journal-flush.service.in \
+       units/systemd-journal-flush.service.m4.in \
+       units/systemd-journal-catalog-update.service.m4.in \
        src/journal/journald-gperf.gperf
 
 CLEANFILES += \
@@ -3348,9 +4098,9 @@ rootlibexec_PROGRAMS += \
        systemd-journal-gatewayd
 
 systemd_journal_gatewayd_SOURCES = \
-       src/journal/journal-gatewayd.c \
-       src/journal/microhttpd-util.h \
-       src/journal/microhttpd-util.c
+       src/journal-remote/journal-gatewayd.c \
+       src/journal-remote/microhttpd-util.h \
+       src/journal-remote/microhttpd-util.c
 
 systemd_journal_gatewayd_LDADD = \
        libsystemd-logs.la \
@@ -3359,6 +4109,11 @@ systemd_journal_gatewayd_LDADD = \
        libsystemd-shared.la \
        $(MICROHTTPD_LIBS)
 
+if HAVE_GNUTLS
+systemd_journal_gatewayd_LDADD += \
+       $(GNUTLS_LIBS)
+endif
+
 systemd_journal_gatewayd_CFLAGS = \
        $(AM_CFLAGS) \
        $(MICROHTTPD_CFLAGS)
@@ -3374,7 +4129,7 @@ nodist_systemunit_DATA += \
        units/systemd-journal-gatewayd.service
 
 dist_gatewayddocumentroot_DATA = \
-       src/journal/browse.html
+       src/journal-remote/browse.html
 
 endif
 
@@ -3390,38 +4145,70 @@ systemd_socket_proxyd_LDADD = \
        libsystemd-logs.la \
        libsystemd-internal.la \
        libsystemd-journal-internal.la \
-       libsystemd-shared.la
+       libsystemd-shared.la \
+       libsystemd-resolve.la
 
 # ------------------------------------------------------------------------------
 if ENABLE_COREDUMP
 systemd_coredump_SOURCES = \
-       src/journal/coredump.c
+       src/journal/coredump.c \
+       src/journal/coredump-vacuum.c \
+       src/journal/coredump-vacuum.h
 
 systemd_coredump_LDADD = \
        libsystemd-journal-internal.la \
        libsystemd-label.la \
-       libsystemd-shared.la \
-       libsystemd-internal.la
+       libsystemd-internal.la \
+       libsystemd-shared.la
+
+if HAVE_ELFUTILS
+systemd_coredump_SOURCES += \
+       src/journal/stacktrace.c \
+       src/journal/stacktrace.h
+
+systemd_coredump_LDADD += \
+       $(ELFUTILS_LIBS)
+endif
 
 rootlibexec_PROGRAMS += \
        systemd-coredump
 
-systemd_coredumpctl_SOURCES = \
+dist_pkgsysconf_DATA += \
+       src/journal/coredump.conf
+
+if HAVE_ACL
+systemd_coredump_LDADD += \
+       libsystemd-acl.la
+endif
+
+coredumpctl_SOURCES = \
        src/journal/coredumpctl.c
 
-systemd_coredumpctl_LDADD = \
+coredumpctl_LDADD = \
        libsystemd-journal-internal.la \
        libsystemd-internal.la \
        libsystemd-shared.la
 
 bin_PROGRAMS += \
-       systemd-coredumpctl
+       coredumpctl
+
+manual_tests += \
+       test-coredump-vacuum
+
+test_coredump_vacuum_SOURCES = \
+       src/journal/test-coredump-vacuum.c  \
+       src/journal/coredump-vacuum.c \
+       src/journal/coredump-vacuum.h
+
+test_coredump_vacuum_LDADD = \
+       libsystemd-internal.la \
+       libsystemd-shared.la
 
 dist_bashcompletion_DATA += \
-       shell-completion/bash/systemd-coredumpctl
+       shell-completion/bash/coredumpctl
 
 dist_zshcompletion_DATA += \
-       shell-completion/zsh/_systemd-coredumpctl
+       shell-completion/zsh/_coredumpctl
 
 sysctl_DATA = \
        sysctl.d/50-coredump.conf
@@ -3516,12 +4303,26 @@ nodist_systemunit_DATA += \
        units/systemd-readahead-replay.service \
        units/systemd-readahead-done.service
 
+manual_tests += \
+       test-ssd
+
+test_ssd_SOURCES = \
+       src/readahead/test-ssd.c \
+       src/readahead/readahead-common.c \
+       src/readahead/readahead-common.h
+
+test_ssd_LDADD = \
+       libsystemd-internal.la \
+       libudev-internal.la \
+       libsystemd-shared.la
+
 endif
 
 EXTRA_DIST += \
-       units/systemd-readahead-collect.service.in \
-       units/systemd-readahead-replay.service.in \
-       units/systemd-readahead-done.service.in
+       units/systemd-readahead-collect.service.m4.in \
+       units/systemd-readahead-replay.service.m4.in \
+       units/systemd-readahead-done.service.m4.in \
+       units/systemd-readahead-drop.service.m4
 
 # ------------------------------------------------------------------------------
 if ENABLE_BOOTCHART
@@ -3542,6 +4343,15 @@ rootlibexec_PROGRAMS += \
 
 dist_pkgsysconf_DATA += \
        src/bootchart/bootchart.conf
+
+nodist_systemunit_DATA += \
+       units/systemd-bootchart.service
+
+EXTRA_DIST += \
+       units/systemd-bootchart.service.in
+
+CLEANFILES += \
+       units/systemd-bootchart.service
 endif
 
 # ------------------------------------------------------------------------------
@@ -3637,7 +4447,8 @@ systemgenerator_PROGRAMS += \
        systemd-cryptsetup-generator
 
 dist_systemunit_DATA += \
-       units/cryptsetup.target
+       units/cryptsetup.target \
+       units/cryptsetup-pre.target
 
 systemd_cryptsetup_SOURCES = \
        src/cryptsetup/cryptsetup.c
@@ -3724,39 +4535,13 @@ EXTRA_DIST += \
 
 # ------------------------------------------------------------------------------
 if ENABLE_KDBUS
-systemd_bus_driverd_SOURCES = \
-       src/bus-driverd/bus-driverd.c
-
-systemd_bus_driverd_LDADD = \
-       libsystemd-internal.la \
-       libsystemd-shared.la
-
-rootlibexec_PROGRAMS += \
-       systemd-bus-driverd
-
-nodist_systemunit_DATA += \
-       units/systemd-bus-driverd.service
-
 dist_systemunit_DATA += \
-       units/org.freedesktop.DBus.busname
+       units/org.freedesktop.systemd1.busname
 
 BUSNAMES_TARGET_WANTS += \
-       org.freedesktop.DBus.busname
-
-nodist_userunit_DATA += \
-       units/user/systemd-bus-driverd.service
-
-USER_BUSNAMES_TARGET_WANTS += \
-       org.freedesktop.DBus.busname
-
-USER_UNIT_ALIASES += \
-       $(systemunitdir)/org.freedesktop.DBus.busname org.freedesktop.DBus.busname
+       org.freedesktop.systemd1.busname
 endif
 
-EXTRA_DIST += \
-       units/systemd-bus-driverd.service.in \
-       units/user/systemd-bus-driverd.service.in
-
 # ------------------------------------------------------------------------------
 if ENABLE_LOCALED
 systemd_localed_SOURCES = \
@@ -3797,9 +4582,6 @@ dist_pkgdata_DATA += \
 dist_noinst_SCRIPT = \
        src/locale/generate-kbd-model-map
 
-update-kbd-model-map: src/locale/generate-kbd-model-map
-       $PYTHON $< >src/locale/kbd-model-map
-
 localectl_SOURCES = \
        src/locale/localectl.c
 
@@ -3854,10 +4636,6 @@ dist_systemunit_DATA += \
 polkitpolicy_files += \
        src/timedate/org.freedesktop.timedate1.policy
 
-INSTALL_DIRS += \
-       $(prefix)/lib/systemd/ntp-units.d \
-       $(sysconfdir)/systemd/ntp-units.d
-
 SYSTEM_UNIT_ALIASES += \
        systemd-timedated.service dbus-org.freedesktop.timedate1.service
 
@@ -3888,11 +4666,61 @@ EXTRA_DIST += \
        units/systemd-timedated.service.in
 
 # ------------------------------------------------------------------------------
+if ENABLE_TIMESYNCD
+systemd_timesyncd_SOURCES = \
+       src/timesync/timesyncd.c \
+       src/timesync/timesyncd-manager.c \
+       src/timesync/timesyncd-manager.h \
+       src/timesync/timesyncd-conf.c \
+       src/timesync/timesyncd-conf.h \
+       src/timesync/timesyncd-server.c \
+       src/timesync/timesyncd-server.h
+
+nodist_systemd_timesyncd_SOURCES = \
+       src/timesync/timesyncd-gperf.c
+
+EXTRA_DIST += \
+       src/timesync/timesyncd-gperf.gperf
+
+CLEANFILES += \
+       src/timesync/timesyncd-gperf.c
+
+systemd_timesyncd_LDADD = \
+       libsystemd-resolve.la \
+       libsystemd-network.la \
+       libsystemd-label.la \
+       libsystemd-capability.la \
+       libsystemd-internal.la \
+       libsystemd-shared.la \
+       -lm
+
+rootlibexec_PROGRAMS += \
+       systemd-timesyncd
+
+nodist_systemunit_DATA += \
+       units/systemd-timesyncd.service
+
+GENERAL_ALIASES += \
+       $(systemunitdir)/systemd-timesyncd.service $(pkgsysconfdir)/system/sysinit.target.wants/systemd-timesyncd.service
+
+EXTRA_DIST += \
+       units/systemd-timesyncd.service.in
+
+nodist_pkgsysconf_DATA += \
+       src/timesync/timesyncd.conf
+
+EXTRA_DIST += \
+       src/timesync/timesyncd.conf.in
+
+CLEANFILES += \
+       src/timesync/timesyncd.conf
+endif
+
+# ------------------------------------------------------------------------------
 if HAVE_MYHOSTNAME
 libnss_myhostname_la_SOURCES = \
-       src/nss-myhostname/nss-myhostname.c \
-       src/nss-myhostname/ifconf.h \
-       src/nss-myhostname/netlink.c
+       src/nss-myhostname/nss-myhostname.sym \
+       src/nss-myhostname/nss-myhostname.c
 
 libnss_myhostname_la_LDFLAGS = \
        $(AM_LDFLAGS) \
@@ -3900,7 +4728,12 @@ libnss_myhostname_la_LDFLAGS = \
        -export-dynamic \
        -avoid-version \
        -shared \
-       -shrext .so.2
+       -shrext .so.2 \
+       -Wl,--version-script=$(top_srcdir)/src/nss-myhostname/nss-myhostname.sym
+
+libnss_myhostname_la_LIBADD = \
+       libsystemd-shared.la \
+       libsystemd-internal.la
 
 lib_LTLIBRARIES += \
        libnss_myhostname.la
@@ -3969,7 +4802,8 @@ dist_dbuspolicy_DATA += \
        src/machine/org.freedesktop.machine1.conf
 
 dist_zshcompletion_DATA += \
-       shell-completion/zsh/_machinectl
+       shell-completion/zsh/_machinectl \
+       shell-completion/zsh/_sd_machines
 
 SYSTEM_UNIT_ALIASES += \
        systemd-machined.service dbus-org.freedesktop.machine1.service
@@ -3980,6 +4814,186 @@ BUSNAMES_TARGET_WANTS += \
 EXTRA_DIST += \
        units/systemd-machined.service.in
 
+libnss_mymachines_la_SOURCES = \
+       src/nss-mymachines/nss-mymachines.sym \
+       src/nss-mymachines/nss-mymachines.c
+
+libnss_mymachines_la_LDFLAGS = \
+       $(AM_LDFLAGS) \
+       -module \
+       -export-dynamic \
+       -avoid-version \
+       -shared \
+       -shrext .so.2 \
+       -Wl,--version-script=$(top_srcdir)/src/nss-mymachines/nss-mymachines.sym
+
+libnss_mymachines_la_LIBADD = \
+       libsystemd-shared.la \
+       libsystemd-internal.la
+
+lib_LTLIBRARIES += \
+       libnss_mymachines.la
+endif
+
+# ------------------------------------------------------------------------------
+if ENABLE_RESOLVED
+systemd_resolved_SOURCES = \
+       src/resolve/resolved.c \
+       src/resolve/resolved-manager.c \
+       src/resolve/resolved-manager.h \
+       src/resolve/resolved-conf.c \
+       src/resolve/resolved-conf.h \
+       src/resolve/resolved-bus.c \
+       src/resolve/resolved-bus.h \
+       src/resolve/resolved-link.h \
+       src/resolve/resolved-link.c \
+       src/resolve/resolved-def.h \
+       src/resolve/resolved-dns-domain.h \
+       src/resolve/resolved-dns-domain.c \
+       src/resolve/resolved-dns-rr.h \
+       src/resolve/resolved-dns-rr.c \
+       src/resolve/resolved-dns-question.h \
+       src/resolve/resolved-dns-question.c \
+       src/resolve/resolved-dns-answer.h \
+       src/resolve/resolved-dns-answer.c \
+       src/resolve/resolved-dns-packet.h \
+       src/resolve/resolved-dns-packet.c \
+       src/resolve/resolved-dns-query.h \
+       src/resolve/resolved-dns-query.c \
+       src/resolve/resolved-dns-transaction.h \
+       src/resolve/resolved-dns-transaction.c \
+       src/resolve/resolved-dns-scope.h \
+       src/resolve/resolved-dns-scope.c \
+       src/resolve/resolved-dns-server.h \
+       src/resolve/resolved-dns-server.c \
+       src/resolve/resolved-dns-cache.h \
+       src/resolve/resolved-dns-cache.c \
+       src/resolve/resolved-dns-zone.h \
+       src/resolve/resolved-dns-zone.c \
+       src/resolve/resolved-dns-stream.h \
+       src/resolve/resolved-dns-stream.c \
+       src/resolve/dns-type.c \
+       src/resolve/dns-type.h \
+       src/resolve/dns_type-from-name.h \
+       src/resolve/dns_type-to-name.h
+
+nodist_systemd_resolved_SOURCES = \
+       src/resolve/resolved-gperf.c
+
+EXTRA_DIST += \
+       src/resolve/resolved-gperf.gperf \
+       src/resolve/dns_type-from-name.gperf
+
+CLEANFILES += \
+       src/resolve/resolved-gperf.c
+
+systemd_resolved_LDADD = \
+       libsystemd-capability.la \
+       libsystemd-network.la \
+       libsystemd-label.la \
+       libsystemd-internal.la \
+       libsystemd-shared.la \
+       -lm \
+       $(LIBIDN_LIBS)
+
+rootlibexec_PROGRAMS += \
+       systemd-resolved
+
+nodist_systemunit_DATA += \
+       units/systemd-resolved.service
+
+dist_systemunit_DATA += \
+       units/org.freedesktop.resolve1.busname
+
+dist_dbuspolicy_DATA += \
+       src/resolve/org.freedesktop.resolve1.conf
+
+dist_dbussystemservice_DATA += \
+       src/resolve/org.freedesktop.resolve1.service
+
+EXTRA_DIST += \
+       units/systemd-resolved.service.in
+
+SYSTEM_UNIT_ALIASES += \
+       systemd-resolved.service dbus-org.freedesktop.resolve1.service
+
+BUSNAMES_TARGET_WANTS += \
+       org.freedesktop.resolve1.busname
+
+GENERAL_ALIASES += \
+       $(systemunitdir)/systemd-resolved.service $(pkgsysconfdir)/system/multi-user.target.wants/systemd-resolved.service
+
+nodist_pkgsysconf_DATA += \
+       src/resolve/resolved.conf
+
+EXTRA_DIST += \
+       src/resolve/resolved.conf.in
+
+CLEANFILES += \
+       src/resolve/resolved.conf
+
+tests += \
+       test-dns-domain
+
+test_dns_domain_SOURCES = \
+       src/resolve/resolved-dns-domain.h \
+       src/resolve/resolved-dns-domain.c \
+       src/resolve/test-dns-domain.c
+
+test_dns_domain_LDADD = \
+       libsystemd-capability.la \
+       libsystemd-network.la \
+       libsystemd-label.la \
+       libsystemd-internal.la \
+       libsystemd-shared.la \
+       $(LIBIDN_LIBS)
+
+libnss_resolve_la_SOURCES = \
+       src/nss-resolve/nss-resolve.sym \
+       src/nss-resolve/nss-resolve.c
+
+libnss_resolve_la_LDFLAGS = \
+       $(AM_LDFLAGS) \
+       -module \
+       -export-dynamic \
+       -avoid-version \
+       -shared \
+       -shrext .so.2 \
+       -Wl,--version-script=$(top_srcdir)/src/nss-resolve/nss-resolve.sym
+
+libnss_resolve_la_LIBADD = \
+       libsystemd-shared.la \
+       libsystemd-internal.la
+
+lib_LTLIBRARIES += \
+       libnss_resolve.la
+
+systemd_resolve_host_SOURCES = \
+       src/resolve-host/resolve-host.c \
+       src/resolve/resolved-dns-packet.c \
+       src/resolve/resolved-dns-packet.h \
+       src/resolve/resolved-dns-rr.c \
+       src/resolve/resolved-dns-rr.h \
+       src/resolve/resolved-dns-answer.c \
+       src/resolve/resolved-dns-answer.h \
+       src/resolve/resolved-dns-question.c \
+       src/resolve/resolved-dns-question.h \
+       src/resolve/resolved-dns-domain.c \
+       src/resolve/resolved-dns-domain.h \
+       src/resolve/dns-type.c \
+       src/resolve/dns-type.h \
+       src/resolve/dns_type-from-name.h \
+       src/resolve/dns_type-to-name.h
+
+systemd_resolve_host_LDADD = \
+       libsystemd-internal.la \
+       libsystemd-shared.la \
+       -lm \
+       $(LIBIDN_LIBS)
+
+rootlibexec_PROGRAMS += \
+       systemd-resolve-host
+
 endif
 
 # ------------------------------------------------------------------------------
@@ -3988,58 +5002,128 @@ rootlibexec_PROGRAMS += \
        systemd-networkd
 
 systemd_networkd_SOURCES = \
+       src/network/networkd.c
+
+systemd_networkd_LDADD = \
+       libsystemd-networkd-core.la \
+       libsystemd-capability.la
+
+noinst_LTLIBRARIES += \
+       libsystemd-networkd-core.la
+
+libsystemd_networkd_core_la_CFLAGS = \
+       $(AM_CFLAGS)
+
+libsystemd_networkd_core_la_SOURCES = \
+       src/libsystemd-network/network-internal.h \
        src/network/networkd.h \
-       src/network/networkd.c \
-       src/network/networkd-link.c \
+       src/network/networkd-link.h \
+       src/network/networkd-netdev.h \
+       src/network/networkd-netdev-tunnel.h \
+       src/network/networkd-netdev-veth.h \
+       src/network/networkd-netdev-vxlan.h \
+       src/network/networkd-netdev-vlan.h \
+       src/network/networkd-netdev-macvlan.h \
+       src/network/networkd-netdev-dummy.h \
+       src/network/networkd-netdev-tuntap.h \
+       src/network/networkd-netdev-bond.h \
+       src/network/networkd-netdev-bridge.h \
        src/network/networkd-netdev.c \
+       src/network/networkd-netdev-tunnel.c \
+       src/network/networkd-netdev-veth.c \
+       src/network/networkd-netdev-vxlan.c \
+       src/network/networkd-netdev-vlan.c \
+       src/network/networkd-netdev-macvlan.c \
+       src/network/networkd-netdev-dummy.c \
+       src/network/networkd-netdev-tuntap.c \
+       src/network/networkd-netdev-bond.c \
+       src/network/networkd-netdev-bridge.c \
+       src/network/networkd-link.c \
+       src/network/networkd-ipv4ll.c \
+       src/network/networkd-dhcp4.c \
        src/network/networkd-network.c \
        src/network/networkd-address.c \
        src/network/networkd-route.c \
-       src/network/networkd-manager.c
+       src/network/networkd-manager.c \
+       src/network/networkd-address-pool.c
 
-nodist_systemd_networkd_SOURCES = \
+nodist_libsystemd_networkd_core_la_SOURCES = \
        src/network/networkd-network-gperf.c \
        src/network/networkd-netdev-gperf.c
 
-systemd_networkd_LDADD = \
+libsystemd_networkd_core_la_LIBADD = \
        libudev-internal.la \
        libsystemd-internal.la \
-       libsystemd-dhcp.la \
+       libsystemd-network.la \
        libsystemd-label.la \
        libsystemd-shared.la
 
-nodist_systemunit_DATA += \
-       units/systemd-networkd.service
+rootlibexec_PROGRAMS += \
+       systemd-networkd-wait-online
 
-GENERAL_ALIASES += \
-       $(systemunitdir)/systemd-networkd.service $(pkgsysconfdir)/system/multi-user.target.wants/systemd-networkd.service
+systemd_networkd_wait_online_CFLAGS = \
+       $(AM_CFLAGS)
 
-test_network_SOURCES = \
-       src/network/test-network.c \
-       src/network/networkd.h \
-       src/network/networkd-link.c \
-       src/network/networkd-netdev.c \
-       src/network/networkd-network.c \
-       src/network/networkd-address.c \
-       src/network/networkd-route.c \
-       src/network/networkd-manager.c \
-       src/network/networkd-network-gperf.c \
-       src/network/networkd-netdev-gperf.c
+systemd_networkd_wait_online_SOURCES = \
+       src/libsystemd-network/network-internal.h \
+       src/network/networkd-wait-online.h \
+       src/network/networkd-wait-online-link.h \
+       src/network/networkd-wait-online.c \
+       src/network/networkd-wait-online-manager.c \
+       src/network/networkd-wait-online-link.c
 
-test_network_LDADD = \
+systemd_networkd_wait_online_LDADD = \
+       libsystemd-network.la \
        libudev-internal.la \
        libsystemd-internal.la \
-       libsystemd-dhcp.la \
-       libsystemd-label.la \
        libsystemd-shared.la
 
+rootbin_PROGRAMS += \
+       networkctl
+
+networkctl_SOURCES = \
+       src/network/networkctl.c
+
+networkctl_LDADD = \
+       libsystemd-internal.la \
+       libudev-internal.la \
+       libsystemd-shared.la \
+       libsystemd-network.la
+
+test_network_SOURCES = \
+       src/network/test-network.c
+
+test_network_CFLAGS = \
+       $(AM_CFLAGS)
+
+test_network_LDADD = \
+       libsystemd-networkd-core.la
+
+test_network_tables_SOURCES = \
+       src/network/test-network-tables.c \
+       src/shared/test-tables.h
+
+test_network_tables_LDADD = \
+       libsystemd-networkd-core.la \
+       libudev-core.la
+
 tests += \
-       test-network
+       test-network \
+       test-network-tables
+
+nodist_systemunit_DATA += \
+       units/systemd-networkd.service \
+       units/systemd-networkd-wait-online.service
+
+GENERAL_ALIASES += \
+       $(systemunitdir)/systemd-networkd.service $(pkgsysconfdir)/system/multi-user.target.wants/systemd-networkd.service \
+       $(systemunitdir)/systemd-networkd-wait-online.service $(pkgsysconfdir)/system/network-online.target.wants/systemd-networkd-wait-online.service
 
 EXTRA_DIST += \
        src/network/networkd-network-gperf.gperf \
        src/network/networkd-netdev-gperf.gperf \
-       units/systemd-networkd.service.in
+       units/systemd-networkd.service.in \
+       units/systemd-networkd-wait-online.service.in
 
 CLEANFILES += \
        src/network/networkd-network-gperf.c \
@@ -4080,9 +5164,7 @@ libsystemd_logind_core_la_SOURCES = \
        src/login/logind-session-dbus.c \
        src/login/logind-seat-dbus.c \
        src/login/logind-user-dbus.c \
-       src/login/logind-acl.h \
-       src/login/login-shared.c \
-       src/login/login-shared.h
+       src/login/logind-acl.h
 
 libsystemd_logind_core_la_LIBADD = \
        libsystemd-label.la \
@@ -4142,7 +5224,7 @@ rootbin_PROGRAMS += \
        systemd-inhibit
 
 test_login_SOURCES = \
-       src/login/test-login.c
+       src/libsystemd/sd-login/test-login.c
 
 test_login_LDADD = \
        libsystemd-internal.la \
@@ -4178,7 +5260,8 @@ tests += \
 
 if HAVE_PAM
 pam_systemd_la_SOURCES = \
-       src/login/pam-module.c
+       src/login/pam_systemd.sym \
+       src/login/pam_systemd.c
 
 pam_systemd_la_CFLAGS = \
        $(AM_CFLAGS) \
@@ -4191,7 +5274,7 @@ pam_systemd_la_LDFLAGS = \
        -export-dynamic \
        -avoid-version \
        -shared \
-       -export-symbols-regex '^pam_sm_.*'
+       -Wl,--version-script=$(top_srcdir)/src/login/pam_systemd.sym
 
 pam_systemd_la_LIBADD = \
        libsystemd-capability.la \
@@ -4274,8 +5357,8 @@ EXTRA_DIST += \
        src/login/logind-gperf.gperf \
        src/login/71-seat.rules.in \
        src/login/73-seat-late.rules.in \
-       units/systemd-logind.service.in \
-       units/systemd-user-sessions.service.in
+       units/systemd-logind.service.m4.in \
+       units/systemd-user-sessions.service.m4.in
 
 # ------------------------------------------------------------------------------
 if HAVE_PYTHON_DEVEL
@@ -4306,10 +5389,12 @@ _journal_la_LIBADD = \
 
 id128_la_SOURCES = \
        src/python-systemd/id128.c \
-       src/python-systemd/id128-constants.h \
        src/python-systemd/pyutil.c \
        src/python-systemd/pyutil.h
 
+nodist_id128_la_SOURCES = \
+       src/python-systemd/id128-constants.h
+
 id128_la_CFLAGS = \
        $(AM_CFLAGS) \
        -fvisibility=default \
@@ -4571,9 +5656,11 @@ substitutions = \
        '|udevrulesdir=$(udevrulesdir)|' \
        '|catalogdir=$(catalogdir)|' \
        '|tmpfilesdir=$(tmpfilesdir)|' \
+       '|sysusersdir=$(sysusersdir)|' \
        '|sysctldir=$(sysctldir)|' \
        '|systemgeneratordir=$(systemgeneratordir)|' \
        '|usergeneratordir=$(usergeneratordir)|' \
+       '|CERTIFICATEROOT=$(CERTIFICATEROOT)|' \
        '|PACKAGE_VERSION=$(PACKAGE_VERSION)|' \
        '|PACKAGE_NAME=$(PACKAGE_NAME)|' \
        '|PACKAGE_URL=$(PACKAGE_URL)|' \
@@ -4598,7 +5685,17 @@ substitutions = \
        '|RC_LOCAL_SCRIPT_PATH_START=$(RC_LOCAL_SCRIPT_PATH_START)|' \
        '|RC_LOCAL_SCRIPT_PATH_STOP=$(RC_LOCAL_SCRIPT_PATH_STOP)|' \
        '|PYTHON=$(PYTHON)|' \
-       '|PYTHON_BINARY=$(PYTHON_BINARY)|'
+       '|PYTHON_BINARY=$(PYTHON_BINARY)|' \
+       '|NTP_SERVERS=$(NTP_SERVERS)|' \
+       '|DNS_SERVERS=$(DNS_SERVERS)|' \
+       '|systemuidmax=$(SYSTEM_UID_MAX)|' \
+       '|systemgidmax=$(SYSTEM_GID_MAX)|' \
+       '|TTY_GID=$(TTY_GID)|' \
+       '|RUN_GID=$(RUN_GID)|' \
+       '|systemsleepdir=$(systemsleepdir)|' \
+       '|systemshutdowndir=$(systemshutdowndir)|' \
+       '|binfmtdir=$(binfmtdir)|' \
+       '|modulesloaddir=$(modulesloaddir)|'
 
 SED_PROCESS = \
        $(AM_V_GEN)$(MKDIR_P) $(dir $@) && \
@@ -4617,15 +5714,24 @@ sysctl.d/%: sysctl.d/%.in
 %.pc: %.pc.in
        $(SED_PROCESS)
 
+%.conf: %.conf.in
+       $(SED_PROCESS)
+
 src/core/macros.%: src/core/macros.%.in
        $(SED_PROCESS)
 
 src/%.policy.in: src/%.policy.in.in
        $(SED_PROCESS)
 
+shell-completion/%: shell-completion/%.in
+       $(SED_PROCESS)
+
 %.rules: %.rules.in
        $(SED_PROCESS)
 
+%.conf: %.conf.in
+       $(SED_PROCESS)
+
 %.sh: %.sh.in
        $(SED_PROCESS)
        $(AM_V_GEN)chmod +x $@
@@ -4638,6 +5744,11 @@ src/%: src/%.m4
        $(AM_V_at)$(MKDIR_P) $(dir $@)
        $(AM_V_M4)$(M4) -P $(M4_DEFINES) < $< > $@
 
+tmpfiles.d/%: tmpfiles.d/%.m4
+       $(AM_V_at)$(MKDIR_P) $(dir $@)
+       $(AM_V_M4)$(M4) -P $(M4_DEFINES) < $< > $@
+
+
 units/%: units/%.m4
        $(AM_V_at)$(MKDIR_P) $(dir $@)
        $(AM_V_M4)$(M4) -P $(M4_DEFINES) -DFOR_SYSTEM=1 < $< > $@
@@ -4665,7 +5776,7 @@ CLEANFILES += \
 
 # ------------------------------------------------------------------------------
 if ENABLE_MANPAGES
-man/custom-entities.ent:
+man/custom-entities.ent: configure.ac
        $(AM_V_GEN)$(MKDIR_P) $(dir $@)
        $(AM_V_GEN)(echo '<?xml version="1.0" encoding="utf-8" ?>' && \
         printf '$(subst '|,<!ENTITY ,$(subst =, ",$(subst |',">\n,$(substitutions))))') \
@@ -4757,14 +5868,19 @@ RUNLEVEL4_TARGET_WANTS += \
 RUNLEVEL5_TARGET_WANTS += \
        systemd-update-utmp-runlevel.service
 endif
+
 SYSINIT_TARGET_WANTS += \
-       systemd-update-utmp.service
+       systemd-update-utmp.service \
+       systemd-update-done.service
+
 LOCAL_FS_TARGET_WANTS += \
        systemd-remount-fs.service \
        tmp.mount
+
 MULTI_USER_TARGET_WANTS += \
        getty.target \
        systemd-ask-password-wall.path
+
 SYSINIT_TARGET_WANTS += \
        dev-hugepages.mount \
        dev-mqueue.mount \
@@ -4805,7 +5921,7 @@ GENERAL_ALIASES += \
        $(systemunitdir)/remote-fs.target $(pkgsysconfdir)/system/multi-user.target.wants/remote-fs.target \
        $(systemunitdir)/getty@.service $(pkgsysconfdir)/system/getty.target.wants/getty@tty1.service \
        $(pkgsysconfdir)/user $(sysconfdir)/xdg/systemd/user \
-       ../system-services/org.freedesktop.systemd1.service $(dbussessionservicedir)/org.freedesktop.systemd1.service
+       $(dbussystemservicedir)/org.freedesktop.systemd1.service $(dbussessionservicedir)/org.freedesktop.systemd1.service
 
 if HAVE_SYSV_COMPAT
 INSTALL_DIRS += \
@@ -4874,32 +5990,62 @@ DISTCHECK_CONFIGURE_FLAGS += \
        --with-sysvrcnd-path=
 endif
 
+if HAVE_PYTHON
+DISTCHECK_CONFIGURE_FLAGS += \
+       --with-python
+endif
+
 if ENABLE_GTK_DOC
 DISTCHECK_CONFIGURE_FLAGS += \
        --enable-gtk-doc
 endif
 
+#
+# Require python when making dist
+#
+.PHONY: dist-check-python
+dist-check-python:
+if !HAVE_PYTHON
+       @echo "*** python and python-lxml module must be installed and enabled in order to make dist"
+       @false
+endif
+
+dist-check-compat-libs:
+if !ENABLE_COMPAT_LIBS
+       @echo "*** compat-libs must be enabled in order to make dist"
+       @false
+endif
+
+dist: dist-check-python dist-check-compat-libs
+
+# check "broken" platforms limited toolchains for link breakage before we release
+.PHONY: linkcheck
+linkcheck:
+       $(MAKE) CFLAGS='-fno-lto' LDFLAGS='-Wl,-fuse-ld=gold -Wl,--as-needed -Wl,--no-gc-sections' distcheck
+
 .PHONY: hwdb-update
 hwdb-update:
        ( cd $(top_srcdir)/hwdb && \
        wget -N http://www.linux-usb.org/usb.ids \
-               http://pci-ids.ucw.cz/v2.2/pci.ids \
-               http://standards.ieee.org/develop/regauth/oui/oui.txt \
-               http://standards.ieee.org/develop/regauth/iab/iab.txt && \
+               http://pci-ids.ucw.cz/v2.2/pci.ids \
+               http://standards.ieee.org/develop/regauth/oui/oui.txt \
+               http://standards.ieee.org/develop/regauth/iab/iab.txt && \
        ./ids-update.pl )
 
 .PHONY: kdbus-update
 kdbus-update:
-       ( cd $(top_srcdir)/src/libsystemd/ && \
+       ( cd $(top_srcdir)/src/libsystemd/sd-bus/ && \
        wget -N https://d-bus.googlecode.com/git/kdbus.h )
 
-.PHONY: upload
-upload: all distcheck
-       cp -v systemd-$(VERSION).tar.xz /home/lennart/git.fedora/systemd/
-       scp systemd-$(VERSION).tar.xz fdo:/srv/www.freedesktop.org/www/software/systemd/
-       scp man/*.html tango:public/systemd-man/
+.PHONY: git-tag
+git-tag:
+       git tag -s "v$(VERSION)" -m "systemd $(VERSION)"
 
 www_target = www.freedesktop.org:/srv/www.freedesktop.org/www/software/systemd
+.PHONY: upload
+upload: all check dist
+       scp systemd-$(VERSION).tar.xz $(www_target)
+
 .PHONY: doc-sync
 doc-sync: all destdir-sphinx
        gtkdoc-rebase --html-dir=docs/libudev/html --online
@@ -4909,9 +6055,10 @@ doc-sync: all destdir-sphinx
        rsync -rlv --delete-excluded --include="*.html" --exclude="*" --omit-dir-times man/ $(www_target)/man/
        rsync -rlv --delete --omit-dir-times docs/html/python-systemd/ $(www_target)/python-systemd/
 
-.PHONY: git-tag
-git-tag:
-       git tag "v$(VERSION)" -m "systemd $(VERSION)"
+.PHONY: tango
+tango: upload
+       cp -v systemd-$(VERSION).tar.xz /home/lennart/git.fedora/systemd/
+       scp man/*.html tango:public/systemd-man/
 
 .PHONY: install-tree
 install-tree: all
@@ -4927,12 +6074,12 @@ valgrind-tests: $(TESTS)
                if file $$f | grep -q shell; then \
                echo -e "$${x}Skipping non-binary $$f"; else \
                echo -e "$${x}Running $$f"; \
-               libtool --mode=execute valgrind -q --leak-check=full --max-stackframe=5242880 --error-exitcode=55 $(builddir)/$$f ; fi; \
+               libtool --mode=execute valgrind -q --leak-check=full --max-stackframe=5242880 --error-exitcode=55 $(builddir)/$$f ; fi; \
                x="\n\n"; \
        done
 
 exported-%: %
-       $(AM_V_GEN)nm -g --defined-only $(builddir)/.libs/$(<:.la=.so) 2>&1 /dev/null | grep " T " | cut -d" " -f3 > $@
+       $(AM_V_GEN)$(NM) -g --defined-only $(builddir)/.libs/$(<:.la=.so) 2>&1 /dev/null | grep " T " | cut -d" " -f3 > $@
 
 exported: $(addprefix exported-, $(lib_LTLIBRARIES))
        $(AM_V_GEN)cat $^ > $@
@@ -4952,7 +6099,7 @@ ALL_OBJECTS:=$(foreach v,$(OBJECT_VARIABLES),$($(v)))
 
 undefined defined: $(ALL_OBJECTS)
        $(AM_V_GEN)for f in $(ALL_OBJECTS) ; do \
-               nm -g --$@-only `echo $(builddir)/"$$f" | sed -e 's,\([^/]*\).lo$$,.libs/\1.o,'` ; \
+               $(NM) -g --$@-only `echo $(builddir)/"$$f" | sed -e 's,\([^/]*\).lo$$,.libs/\1.o,'` ; \
        done | cut -c 20- | cut -d @ -f 1 | sort -u > $@
 
 CLEANFILES += \
@@ -4989,7 +6136,9 @@ test-libsystemd-sym.c: \
                src/systemd/sd-daemon.h \
                src/systemd/sd-login.h \
                src/systemd/sd-bus.h \
-               src/systemd/sd-utf8.h
+               src/systemd/sd-utf8.h \
+               src/systemd/sd-resolve.h \
+               src/systemd/sd-path.h
        $(generate-sym-test)
 
 test-libudev-sym.c: \
@@ -5004,6 +6153,9 @@ test_libsystemd_sym_LDADD = \
 
 test_libudev_sym_SOURCES = \
        test-libudev-sym.c
+test_libudev_sym_CFLAGS = \
+       $(AM_CFLAGS) \
+       -Wno-deprecated-declarations
 test_libudev_sym_LDADD = \
        libudev.la
 
@@ -5015,60 +6167,6 @@ tests += \
        test-libsystemd-sym \
        test-libudev-sym
 
-if ENABLE_COMPAT_LIBS
-test-libsystemd-daemon-sym.c: \
-               src/compat-libs/libsystemd-daemon.sym \
-               src/systemd/sd-daemon.h
-       $(generate-sym-test)
-
-test-libsystemd-id128-sym.c: \
-               src/compat-libs/libsystemd-id128.sym \
-               src/systemd/sd-id128.h
-       $(generate-sym-test)
-
-test-libsystemd-journal-sym.c: \
-               src/compat-libs/libsystemd-journal.sym \
-               src/systemd/sd-journal.h
-       $(generate-sym-test)
-
-test-libsystemd-login-sym.c: \
-               src/compat-libs/libsystemd-login.sym \
-               src/systemd/sd-login.h
-       $(generate-sym-test)
-
-test_libsystemd_daemon_sym_SOURCES = \
-       test-libsystemd-daemon-sym.c
-test_libsystemd_daemon_sym_LDADD = \
-       libsystemd-daemon.la
-
-test_libsystemd_id128_sym_SOURCES = \
-       test-libsystemd-id128-sym.c
-test_libsystemd_id128_sym_LDADD = \
-       libsystemd-id128.la
-
-test_libsystemd_journal_sym_SOURCES = \
-       test-libsystemd-journal-sym.c
-test_libsystemd_journal_sym_LDADD = \
-       libsystemd-journal.la
-
-test_libsystemd_login_sym_SOURCES = \
-       test-libsystemd-login-sym.c
-test_libsystemd_login_sym_LDADD = \
-       libsystemd-login.la
-
-BUILT_SOURCES += \
-       $(test_libsystemd_journal_sym_SOURCES) \
-       $(test_libsystemd_login_sym_SOURCES) \
-       $(test_libsystemd_id128_sym_SOURCES) \
-       $(test_libsystemd_daemon_sym_SOURCES)
-
-tests += \
-       test-libsystemd-journal-sym \
-       test-libsystemd-login-sym \
-       test-libsystemd-id128-sym \
-       test-libsystemd-daemon-sym
-endif
-
 .PHONY: cppcheck
 cppcheck:
        cppcheck --enable=all -q $(top_srcdir)
diff --git a/NEWS b/NEWS
index 46d2420..7dad765 100644 (file)
--- a/NEWS
+++ b/NEWS
 systemd System and Service Manager
 
+CHANGES WITH 216:
+
+        * timedated no longer reads NTP implementation unit names from
+          /usr/lib/systemd/ntp-units.d/*.list. Alternative NTP
+          implementations should add a
+
+            Conflicts=systemd-timesyncd.service
+
+          to their unit files to take over and replace systemd's NTP
+          default functionality.
+
+        * systemd-sysusers gained a new line type "r" for configuring
+          which UID/GID ranges to allocate system users/groups
+          from. Lines of type "u" may now add an additional column
+          that specifies the home directory for the system user to be
+          created. Also, systemd-sysusers may now optionally read user
+          information from STDIN instead of a file. This is useful for
+          invoking it from RPM preinst scriptlets that need to create
+          users before the first RPM file is installed since these
+          files might need to be owned by them. A new
+          %sysusers_create_inline RPM macro has been introduced to do
+          just that. systemd-sysusers now updates the shadow files as
+          well as the user/group databases, which should enhance
+          compatibility with certain tools like grpck.
+
+        * A number of bus APIs of PID 1 now optionally consult
+          PolicyKit to permit access for otherwise unprivileged
+          clients under certain conditions. Note that this currently
+          doesn't support interactive authentication yet, but this is
+          expected to be added eventually, too.
+
+        * /etc/machine-info now has new fields for configuring the
+          deployment environment of the machine, as well as the
+          location of the machine. hostnamectl has been updated with
+          new command to update these fields.
+
+        * systemd-timesyncd has been updated to automatically acquire
+          NTP server information from systemd-networkd, which might
+          have been discovered via DHCP.
+
+        * systemd-resolved now includes a caching DNS stub resolver
+          and a complete LLMNR name resolution implementation. A new
+          NSS module "nss-resolve" has been added which make be used
+          of glibc's own "nss-dns" to resolve hostnames via
+          systemd-resolved. Hostnames, addresses and arbitrary RRs may
+          be resolved via systemd-resolved D-Bus APIs. In contrast to
+          the glibc internal resolver systemd-resolved is aware of
+          multi-homed system, and keeps DNS server and caches separate
+          and per-interface. Queries are sent simultaneously on all
+          interfaces that have DNS servers configured, in order to
+          properly handle VPNs and local LANs which might resolve
+          separate sets of domain names. systemd-resolved may acquire
+          DNS server information from systemd-networkd automatically,
+          which in turn might have discovered them via DHCP. A tool
+          "systemd-resolve-host" has been added that may be used to
+          query the DNS logic in resolved. systemd-resolved implements
+          IDNA and automatically uses IDNA or UTF-8 encoding depending
+          on whether classic DNS or LLMNR is used as transport. In the
+          next releases we intend to add a DNSSEC and mDNS/DNS-SD
+          implementation to systemd-resolved.
+
+        * A new NSS module nss-mymachines has been added, that
+          automatically resolves the names of all local registered
+          containers to their respective IP addresses.
+
+        * A new client tool "networkctl" for systemd-networkd has been
+          added. It currently is entirely passive and will query
+          networking configuration from udev, rtnetlink and networkd,
+          and present it to the user in a very friendly
+          way. Eventually, we hope to extend it to become a full
+          control utility for networkd.
+
+        * .socket units gained a new DeferAcceptSec= setting that
+          controls the kernels' TCP_DEFER_ACCEPT sockopt for
+          TCP. Similar, support for controlling TCP keep-alive
+          settings has been added (KeepAliveTimeSec=,
+          KeepAliveIntervalSec=, KeepAliveProbes=). Also, support for
+          turning off Nagle's algorithm on TCP has been added
+          (NoDelay=).
+
+        * logind learned a new session type "web", for use in projects
+          like Cockpit which register web clients as PAM sessions.
+
+        * timer units with at least one OnCalendar= setting will now
+          be started only after timer-sync.target has been
+          reached. This way they will not elapse before the system
+          clock has been corrected by a local NTP client or
+          similar. This is particular useful on RTC-less embedded
+          machines, that come up with an invalid system clock.
+
+        * systemd-nspawn's --network-veth= switch should now result in
+          stable MAC addresses for both the outer and the inner side
+          of the link.
+
+        * systemd-nspawn gained a new --volatile= switch for running
+          container instances with /etc or /var unpopulated.
+
+        * The kdbus client code has been updated to use the new Linux
+          3.17 memfd subsystem instead of the old kdbus-specific one.
+
+        * systemd-networkd's DHCP client and server now support
+          FORCERENEW. There are also new configuration options to
+          configure the vendor client identifier and broadcast mode
+          for DHCP.
+
+        * systemd will no longer inform the kernel about the current
+          timezone, as this is necessarily incorrect and racy as the
+          kernel has no understanding of DST and similar
+          concepts. This hence means FAT timestamps will be always
+          considered UTC, similar to what Android is already
+          doing. Also, when the RTC is configured to the local time
+          (rather than UTC) systemd will never synchronize back to it,
+          as this might confuse Windows at a later boot.
+
+        * systemd-analyze gained a new command "verify" for offline
+          validation of unit files.
+
+        * systemd-networkd gained support for a couple of additional
+          settings for bonding networking setups. Also, the metric for
+          statically configured routes may now be configured. For
+          network interfaces where this is appropriate the peer IP
+          address may now be configured.
+
+        * systemd-networkd's DHCP client will no longer request
+          broadcasting by default, as this tripped up some networks.
+          For hardware where broadcast is required the feature should
+          be switched back on using RequestBroadcast=yes.
+
+        * systemd-networkd will now set up IPv4LL addresses (when
+          enabled) even if DHCP is configured successfully.
+
+        * udev will now default to respect network device names given
+          by the kernel when the kernel indicates that these are
+          predictable. This behavior can be tweaked by changing
+          NamePolicy= in the relevant .link file.
+
+        * A new library systemd-terminal has been added that
+          implements full TTY stream parsing and rendering. This
+          library is supposed to be used later on for implementing a
+          full userspace VT subsystem, replacing the current kernel
+          implementation.
+
+        * A new tool systemd-journal-upload has been added to push
+          journal data to a remote system running
+          systemd-journal-remote.
+
+        * journald will no longer forward all local data to another
+          running syslog daemon. This change has been made because
+          rsyslog (which appears to be the most commonly used syslog
+          implementation these days) no longer makes use of this, and
+          instead pulls the data out of the journal on its own. Since
+          forwarding the messages to a non-existent syslog server is
+          more expensive than we assumed we have now turned this
+          off. If you run a syslog server that is not a recent rsyslog
+          version, you have to turn this option on again
+          (ForwardToSyslog= in journald.conf).
+
+        * journald now optionally supports the LZ4 compressor for
+          larger journal fields. This compressor should perform much
+          better than XZ which was the previous default.
+
+        * machinectl now shows the IP addresses of local containers,
+          if it knows them, plus the interface name of the container.
+
+        * A new tool "systemd-escape" has been added that makes it
+          easy to escape strings to build unit names and similar.
+
+        * sd_notify() messages may now include a new ERRNO= field
+          which is parsed and collected by systemd and shown among the
+          "systemctl status" output for a service.
+
+        * A new component "systemd-firstboot" has been added that
+          queries the most basic systemd information (timezone,
+          hostname, root password) interactively on first
+          boot. Alternatively it may also be used to provision these
+          things offline on OS images installed into directories.
+
+        * The default sysctl.d/ snippets will now set
+
+                net.ipv4.conf.default.promote_secondaries=1
+
+          This has the benefit of no flushing secondary IP addresses
+          when primary addresses are removed.
+
+        Contributions from: Ansgar Burchardt, Bastien Nocera, Colin
+        Walters, Dan Dedrick, Daniel Buch, Daniel Korostil, Daniel
+        Mack, Dan Williams, Dave Reisner, David Herrmann, Denis
+        Kenzior, Eelco Dolstra, Eric Cook, Hannes Reinecke, Harald
+        Hoyer, Hong Shick Pak, Hui Wang, Jean-André Santoni, Jóhann
+        B. Guðmundsson, Jon Severinsson, Karel Zak, Kay Sievers, Kevin
+        Wells, Lennart Poettering, Lukas Nykryn, Mantas Mikulėnas,
+        Marc-Antoine Perennou, Martin Pitt, Michael Biebl, Michael
+        Marineau, Michael Olbrich, Michal Schmidt, Michal Sekletar,
+        Miguel Angel Ajo, Mike Gilbert, Olivier Brunel, Robert
+        Schiele, Ronny Chevalier, Simon McVittie, Sjoerd Simons, Stef
+        Walter, Steven Noonan, Susant Sahani, Tanu Kaskinen, Thomas
+        Blume, Thomas Hindoe Paaboel Andersen, Timofey Titovets,
+        Tobias Geerinckx-Rice, Tomasz Torcz, Tom Gundersen, Umut
+        Tezduyar Lindskog, Zbigniew Jędrzejewski-Szmek
+
+        -- Berlin, 2014-08-19
+
+CHANGES WITH 215:
+
+        * A new tool systemd-sysusers has been added. This tool
+          creates system users and groups in /etc/passwd and
+          /etc/group, based on static declarative system user/group
+          definitions in /usr/lib/sysusers.d/. This is useful to
+          enable factory resets and volatile systems that boot up with
+          an empty /etc directory, and thus need system users and
+          groups created during early boot. systemd now also ships
+          with two default sysusers.d/ files for the most basic
+          users and groups systemd and the core operating system
+          require.
+
+        * A new tmpfiles snippet has been added that rebuilds the
+          essential files in /etc on boot, should they be missing.
+
+        * A directive for ensuring automatic clean-up of
+          /var/cache/man/ has been removed from the default
+          configuration. This line should now be shipped by the man
+          implementation. The necessary change has been made to the
+          man-db implementation. Note that you need to update your man
+          implementation to one that ships this line, otherwise no
+          automatic clean-up of /var/cache/man will take place.
+
+        * A new condition ConditionNeedsUpdate= has been added that
+          may conditionalize services to only run when /etc or /var
+          are "older" than the vendor operating system resources in
+          /usr. This is useful for reconstructing or updating /etc
+          after an offline update of /usr or a factory reset, on the
+          next reboot. Services that want to run once after such an
+          update or reset should use this condition and order
+          themselves before the new systemd-update-done.service, which
+          will mark the two directories as fully updated. A number of
+          service files have been added making use of this, to rebuild
+          the udev hardware database, the journald message catalog and
+          dynamic loader cache (ldconfig). The systemd-sysusers tool
+          described above also makes use of this now. With this in
+          place it is now possible to start up a minimal operating
+          system with /etc empty cleanly. For more information on the
+          concepts involved see this recent blog story:
+
+          http://0pointer.de/blog/projects/stateless.html
+
+        * A new system group "input" has been introduced, and all
+          input device nodes get this group assigned. This is useful
+          for system-level software to get access to input devices. It
+          complements what is already done for "audio" and "video".
+
+        * systemd-networkd learnt minimal DHCPv4 server support in
+          addition to the existing DHCPv4 client support. It also
+          learnt DHCPv6 client and IPv6 Router Solicitation client
+          support. The DHCPv4 client gained support for static routes
+          passed in from the server. Note that the [DHCPv4] section
+          known in older systemd-networkd versions has been renamed to
+          [DHCP] and is now also used by the DHCPv6 client. Existing
+          .network files using settings of this section should be
+          updated, though compatibility is maintained. Optionally, the
+          client hostname may now be sent to the DHCP server.
+
+        * networkd gained support for vxlan virtual networks as well
+          as tun/tap and dummy devices.
+
+        * networkd gained support for automatic allocation of address
+          ranges for interfaces from a system-wide pool of
+          addresses. This is useful for dynamically managing a large
+          number of interfaces with a single network configuration
+          file. In particular this is useful to easily assign
+          appropriate IP addresses to the veth links of a large number
+          of nspawn instances.
+
+        * RPM macros for processing sysusers, sysctl and binfmt
+          drop-in snippets at package installation time have been
+          added.
+
+        * The /etc/os-release file should now be placed in
+          /usr/lib/os-release. The old location is automatically
+          created as symlink. /usr/lib is the more appropriate
+          location of this file, since it shall actually describe the
+          vendor operating system shipped in /usr, and not the
+          configuration stored in /etc.
+
+        * .mount units gained a new boolean SloppyOptions= setting
+          that maps to mount(8)'s -s option which enables permissive
+          parsing of unknown mount options.
+
+        * tmpfiles learnt a new "L+" directive which creates a symlink
+          but (unlike "L") deletes a pre-existing file first, should
+          it already exist and not already be the correct
+          symlink. Similar, "b+", "c+" and "p+" directives have been
+          added as well, which create block and character devices, as
+          well as fifos in the filesystem, possibly removing any
+          pre-existing files of different types.
+
+        * For tmpfiles' "L", "L+", "C" and "C+" directives the final
+          'argument' field (which so far specified the source to
+          symlink/copy the files from) is now optional. If omitted the
+          same file os copied from /usr/share/factory/ suffixed by the
+          full destination path. This is useful for populating /etc
+          with essential files, by copying them from vendor defaults
+          shipped in /usr/share/factory/etc.
+
+        * A new command "systemctl preset-all" has been added that
+          applies the service preset settings to all installed unit
+          files. A new switch --preset-mode= has been added that
+          controls whether only enable or only disable operations
+          shall be executed.
+
+        * A new command "systemctl is-system-running" has been added
+          that allows checking the overall state of the system, for
+          example whether it is fully up and running.
+
+        * When the system boots up with an empty /etc, the equivalent
+          to "systemctl preset-all" is executed during early boot, to
+          make sure all default services are enabled after a factory
+          reset.
+
+        * systemd now contains a minimal preset file that enables the
+          most basic services systemd ships by default.
+
+        * Unit files' [Install] section gained a new DefaultInstance=
+          field for defining the default instance to create if a
+          template unit is enabled with no instance specified.
+
+        * A new passive target cryptsetup-pre.target has been added
+          that may be used by services that need to make they run and
+          finish before the first LUKS cryptographic device is set up.
+
+        * The /dev/loop-control and /dev/btrfs-control device nodes
+          are now owned by the "disk" group by default, opening up
+          access to this group.
+
+        * systemd-coredump will now automatically generate a
+          stack trace of all core dumps taking place on the system,
+          based on elfutils' libdw library. This stack trace is logged
+          to the journal.
+
+        * systemd-coredump may now optionally store coredumps directly
+          on disk (in /var/lib/systemd/coredump, possibly compressed),
+          instead of storing them unconditionally in the journal. This
+          mode is the new default. A new configuration file
+          /etc/systemd/coredump.conf has been added to configure this
+          and other parameters of systemd-coredump.
+
+        * coredumpctl gained a new "info" verb to show details about a
+          specific coredump. A new switch "-1" has also been added
+          that makes sure to only show information about the most
+          recent entry instead of all entries. Also, as the tool is
+          generally useful now the "systemd-" prefix of the binary
+          name has been removed. Distributions that want to maintain
+          compatibility with the old name should add a symlink from
+          the old name to the new name.
+
+        * journald's SplitMode= now defaults to "uid". This makes sure
+          that unprivileged users can access their own coredumps with
+          coredumpctl without restrictions.
+
+        * New kernel command line options "systemd.wants=" (for
+          pulling an additional unit during boot), "systemd.mask="
+          (for masking a specific unit for the boot), and
+          "systemd.debug-shell" (for enabling the debug shell on tty9)
+          have been added. This is implemented in the new generator
+          "systemd-debug-generator".
+
+        * systemd-nspawn will now by default filter a couple of
+          syscalls for containers, among them those required for
+          kernel module loading, direct x86 IO port access, swap
+          management, and kexec. Most importantly though
+          open_by_handle_at() is now prohibited for containers,
+          closing a hole similar to a recently discussed vulnerability
+          in docker regarding access to files on file hierarchies the
+          container should normally not have access to. Note that for
+          nspawn we generally make no security claims anyway (and
+          this is explicitly documented in the man page), so this is
+          just a fix for one of the most obvious problems.
+
+        * A new man page file-hierarchy(7) has been added that
+          contains a minimized, modernized version of the file system
+          layout systemd expects, similar in style to the FHS
+          specification or hier(5). A new tool systemd-path(1) has
+          been added to query many of these paths for the local
+          machine and user.
+
+        * Automatic time-based clean-up of $XDG_RUNTIME_DIR is no
+          longer done. Since the directory now has a per-user size
+          limit, and is cleaned on logout this appears unnecessary,
+          in particular since this now brings the lifecycle of this
+          directory closer in line with how IPC objects are handled.
+
+        * systemd.pc now exports a number of additional directories,
+          including $libdir (which is useful to identify the library
+          path for the primary architecture of the system), and a
+          couple of drop-in directories.
+
+        * udev's predictable network interface names now use the dev_port
+          sysfs attribute, introduced in linux 3.15 instead of dev_id to
+          distinguish between ports of the same PCI function. dev_id should
+          only be used for ports using the same HW address, hence the need
+          for dev_port.
+
+        * machined has been updated to export the OS version of a
+          container (read from /etc/os-release and
+          /usr/lib/os-release) on the bus. This is now shown in
+          "machinectl status" for a machine.
+
+        * A new service setting RestartForceExitStatus= has been
+          added. If configured to a set of exit signals or process
+          return values, the service will be restarted when the main
+          daemon process exits with any of them, regardless of the
+          Restart= setting.
+
+        * systemctl's -H switch for connecting to remote systemd
+          machines has been extended so that it may be used to
+          directly connect to a specific container on the
+          host. "systemctl -H root@foobar:waldi" will now connect as
+          user "root" to host "foobar", and then proceed directly to
+          the container named "waldi". Note that currently you have to
+          authenticate as user "root" for this to work, as entering
+          containers is a privileged operation.
+
+        Contributions from: Andreas Henriksson, Benjamin Steinwender,
+        Carl Schaefer, Christian Hesse, Colin Ian King, Cristian
+        Rodríguez, Daniel Mack, Dave Reisner, David Herrmann, Eugene
+        Yakubovich, Filipe Brandenburger, Frederic Crozat, Hristo
+        Venev, Jan Engelhardt, Jonathan Boulle, Kay Sievers, Lennart
+        Poettering, Luke Shumaker, Mantas Mikulėnas, Marc-Antoine
+        Perennou, Marcel Holtmann, Michael Marineau, Michael Olbrich,
+        Michał Bartoszkiewicz, Michal Sekletar, Patrik Flykt, Ronan Le
+        Martret, Ronny Chevalier, Ruediger Oertel, Steven Noonan,
+        Susant Sahani, Thadeu Lima de Souza Cascardo, Thomas Hindoe
+        Paaboel Andersen, Tom Gundersen, Tom Hirst, Umut Tezduyar
+        Lindskog, Uoti Urpala, Zbigniew Jędrzejewski-Szmek
+
+        -- Berlin, 2014-07-03
+
+CHANGES WITH 214:
+
+        * As an experimental feature, udev now tries to lock the
+          disk device node (flock(LOCK_SH|LOCK_NB)) while it
+          executes events for the disk or any of its partitions.
+          Applications like partitioning programs can lock the
+          disk device node (flock(LOCK_EX)) and claim temporary
+          device ownership that way; udev will entirely skip all event
+          handling for this disk and its partitions. If the disk
+          was opened for writing, the close will trigger a partition
+          table rescan in udev's "watch" facility, and if needed
+          synthesize "change" events for the disk and all its partitions.
+          This is now unconditionally enabled, and if it turns out to
+          cause major problems, we might turn it on only for specific
+          devices, or might need to disable it entirely. Device Mapper
+          devices are excluded from this logic.
+
+        * We temporarily dropped the "-l" switch for fsck invocations,
+          since they collide with the flock() logic above. util-linux
+          upstream has been changed already to avoid this conflict,
+          and we will readd "-l" as soon as util-linux with this
+          change has been released.
+
+        * The dependency on libattr has been removed. Since a long
+          time, the extended attribute calls have moved to glibc, and
+          libattr is thus unnecessary.
+
+        * Virtualization detection works without priviliges now. This
+          means the systemd-detect-virt binary no longer requires
+          CAP_SYS_PTRACE file capabilities, and our daemons can run
+          with fewer privileges.
+
+        * systemd-networkd now runs under its own "systemd-network"
+          user. It retains the CAP_NET_ADMIN, CAP_NET_BIND_SERVICE,
+          CAP_NET_BROADCAST, CAP_NET_RAW capabilities though, but
+          loses the ability to write to files owned by root this way.
+
+        * Similar, systemd-resolved now runs under its own
+          "systemd-resolve" user with no capabilities remaining.
+
+        * Similar, systemd-bus-proxyd now runs under its own
+          "systemd-bus-proxy" user with only CAP_IPC_OWNER remaining.
+
+        * systemd-networkd gained support for setting up "veth"
+          virtual ethernet devices for container connectivity, as well
+          as GRE and VTI tunnels.
+
+        * systemd-networkd will no longer automatically attempt to
+          manually load kernel modules necessary for certain tunnel
+          transports. Instead, it is assumed the kernel loads them
+          automatically when required. This only works correctly on
+          very new kernels. On older kernels, please consider adding
+          the kernel modules to /etc/modules-load.d/ as a work-around.
+
+        * The resolv.conf file systemd-resolved generates has been
+          moved to /run/systemd/resolve/. If you have a symlink from
+          /etc/resolv.conf, it might be necessary to correct it.
+
+        * Two new service settings, ProtectHome= and ProtectSystem=,
+          have been added. When enabled, they will make the user data
+          (such as /home) inaccessible or read-only and the system
+          (such as /usr) read-only, for specific services. This allows
+          very light-weight per-service sandboxing to avoid
+          modifications of user data or system files from
+          services. These two new switches have been enabled for all
+          of systemd's long-running services, where appropriate.
+
+        * Socket units gained new SocketUser= and SocketGroup=
+          settings to set the owner user and group of AF_UNIX sockets
+          and FIFOs in the file system.
+
+        * Socket units gained a new RemoveOnStop= setting. If enabled,
+          all FIFOS and sockets in the file system will be removed
+          when the specific socket unit is stopped.
+
+        * Socket units gained a new Symlinks= setting. It takes a list
+          of symlinks to create to file system sockets or FIFOs
+          created by the specific Unix sockets. This is useful to
+          manage symlinks to socket nodes with the same life-cycle as
+          the socket itself.
+
+        * The /dev/log socket and /dev/initctl FIFO have been moved to
+          /run, and have been replaced by symlinks. This allows
+          connecting to these facilities even if PrivateDevices=yes is
+          used for a service (which makes /dev/log itself unavailable,
+          but /run is left). This also has the benefit of ensuring
+          that /dev only contains device nodes, directories and
+          symlinks, and nothing else.
+
+        * sd-daemon gained two new calls sd_pid_notify() and
+          sd_pid_notifyf(). They are similar to sd_notify() and
+          sd_notifyf(), but allow overriding of the source PID of
+          notification messages if permissions permit this. This is
+          useful to send notify messages on behalf of a different
+          process (for example, the parent process). The
+          systemd-notify tool has been updated to make use of this
+          when sending messages (so that notification messages now
+          originate from the shell script invoking systemd-notify and
+          not the systemd-notify process itself. This should minimize
+          a race where systemd fails to associate notification
+          messages to services when the originating process already
+          vanished.
+
+        * A new "on-abnormal" setting for Restart= has been added. If
+          set, it will result in automatic restarts on all "abnormal"
+          reasons for a process to exit, which includes unclean
+          signals, core dumps, timeouts and watchdog timeouts, but
+          does not include clean and unclean exit codes or clean
+          signals. Restart=on-abnormal is an alternative for
+          Restart=on-failure for services that shall be able to
+          terminate and avoid restarts on certain errors, by
+          indicating so with an unclean exit code. Restart=on-failure
+          or Restart=on-abnormal is now the recommended setting for
+          all long-running services.
+
+        * If the InaccessibleDirectories= service setting points to a
+          mount point (or if there are any submounts contained within
+          it), it is now attempted to completely unmount it, to make
+          the file systems truly unavailable for the respective
+          service.
+
+        * The ReadOnlyDirectories= service setting and
+          systemd-nspawn's --read-only parameter are now recursively
+          applied to all submounts, too.
+
+        * Mount units may now be created transiently via the bus APIs.
+
+        * The support for SysV and LSB init scripts has been removed
+          from the systemd daemon itself. Instead, it is now
+          implemented as a generator that creates native systemd units
+          from these scripts when needed. This enables us to remove a
+          substantial amount of legacy code from PID 1, following the
+          fact that many distributions only ship a very small number
+          of LSB/SysV init scripts nowadays.
+
+        * Priviliged Xen (dom0) domains are not considered
+          virtualization anymore by the virtualization detection
+          logic. After all, they generally have unrestricted access to
+          the hardware and usually are used to manage the unprivileged
+          (domU) domains.
+
+        * systemd-tmpfiles gained a new "C" line type, for copying
+          files or entire directories.
+
+        * systemd-tmpfiles "m" lines are now fully equivalent to "z"
+          lines. So far, they have been non-globbing versions of the
+          latter, and have thus been redundant. In future, it is
+          recommended to only use "z". "m" has hence been removed
+          from the documentation, even though it stays supported.
+
+        * A tmpfiles snippet to recreate the most basic structure in
+          /var has been added. This is enough to create the /var/run →
+          /run symlink and create a couple of structural
+          directories. This allows systems to boot up with an empty or
+          volatile /var. Of course, while with this change, the core OS
+          now is capable with dealing with a volatile /var, not all
+          user services are ready for it. However, we hope that sooner
+          or later, many service daemons will be changed upstream so
+          that they are able to automatically create their necessary
+          directories in /var at boot, should they be missing. This is
+          the first step to allow state-less systems that only require
+          the vendor image for /usr to boot.
+
+        * systemd-nspawn has gained a new --tmpfs= switch to mount an
+          empty tmpfs instance to a specific directory. This is
+          particularly useful for making use of the automatic
+          reconstruction of /var (see above), by passing --tmpfs=/var.
+
+        * Access modes specified in tmpfiles snippets may now be
+          prefixed with "~", which indicates that they shall be masked
+          by whether the existing file or directly is currently
+          writable, readable or executable at all. Also, if specified,
+          the sgid/suid/sticky bits will be masked for all
+          non-directories.
+
+        * A new passive target unit "network-pre.target" has been
+          added which is useful for services that shall run before any
+          network is configured, for example firewall scripts.
+
+        * The "floppy" group that previously owned the /dev/fd*
+          devices is no longer used. The "disk" group is now used
+          instead. Distributions should probably deprecate usage of
+          this group.
+
+        Contributions from: Camilo Aguilar, Christian Hesse, Colin Ian
+        King, Cristian Rodríguez, Daniel Buch, Dave Reisner, David
+        Strauss, Denis Tikhomirov, John, Jonathan Liu, Kay Sievers,
+        Lennart Poettering, Mantas Mikulėnas, Mark Eichin, Ronny
+        Chevalier, Susant Sahani, Thomas Blume, Thomas Hindoe Paaboel
+        Andersen, Tom Gundersen, Umut Tezduyar Lindskog, Zbigniew
+        Jędrzejewski-Szmek
+
+        -- Berlin, 2014-06-11
+
+CHANGES WITH 213:
+
+        * A new "systemd-timesyncd" daemon has been added for
+          synchronizing the system clock across the network. It
+          implements an SNTP client. In contrast to NTP
+          implementations such as chrony or the NTP reference server,
+          this only implements a client side, and does not bother with
+          the full NTP complexity, focusing only on querying time from
+          one remote server and synchronizing the local clock to
+          it. Unless you intend to serve NTP to networked clients or
+          want to connect to local hardware clocks, this simple NTP
+          client should be more than appropriate for most
+          installations. The daemon runs with minimal privileges, and
+          has been hooked up with networkd to only operate when
+          network connectivity is available. The daemon saves the
+          current clock to disk every time a new NTP sync has been
+          acquired, and uses this to possibly correct the system clock
+          early at bootup, in order to accommodate for systems that
+          lack an RTC such as the Raspberry Pi and embedded devices,
+          and to make sure that time monotonically progresses on these
+          systems, even if it is not always correct. To make use of
+          this daemon, a new system user and group "systemd-timesync"
+          needs to be created on installation of systemd.
+
+        * The queue "seqnum" interface of libudev has been disabled, as
+          it was generally incompatible with device namespacing as
+          sequence numbers of devices go "missing" if the devices are
+          part of a different namespace.
+
+        * "systemctl list-timers" and "systemctl list-sockets" gained
+          a --recursive switch for showing units of these types also
+          for all local containers, similar in style to the already
+          supported --recursive switch for "systemctl list-units".
+
+        * A new RebootArgument= setting has been added for service
+          units, which may be used to specify a kernel reboot argument
+          to use when triggering reboots with StartLimitAction=.
+
+        * A new FailureAction= setting has been added for service
+          units which may be used to specify an operation to trigger
+          when a service fails. This works similarly to
+          StartLimitAction=, but unlike it, controls what is done
+          immediately rather than only after several attempts to
+          restart the service in question.
+
+        * hostnamed got updated to also expose the kernel name,
+          release, and version on the bus. This is useful for
+          executing commands like hostnamectl with the -H switch.
+          systemd-analyze makes use of this to properly display
+          details when running non-locally.
+
+        * The bootchart tool can now show cgroup information in the
+          graphs it generates.
+
+        * The CFS CPU quota cgroup attribute is now exposed for
+          services. The new CPUQuota= switch has been added for this
+          which takes a percentage value. Setting this will have the
+          result that a service may never get more CPU time than the
+          specified percentage, even if the machine is otherwise idle.
+
+        * systemd-networkd learned IPIP and SIT tunnel support.
+
+        * LSB init scripts exposing a dependency on $network will now
+          get a dependency on network-online.target rather than simply
+          network.target. This should bring LSB handling closer to
+          what it was on SysV systems.
+
+        * A new fsck.repair= kernel option has been added to control
+          how fsck shall deal with unclean file systems at boot.
+
+        * The (.ini) configuration file parser will now silently
+          ignore sections whose name begins with "X-". This may be
+          used to maintain application-specific extension sections in unit
+          files.
+
+        * machined gained a new API to query the IP addresses of
+          registered containers. "machinectl status" has been updated
+          to show these addresses in its output.
+
+        * A new call sd_uid_get_display() has been added to the
+          sd-login APIs for querying the "primary" session of a
+          user. The "primary" session of the user is elected from the
+          user's sessions and generally a graphical session is
+          preferred over a text one.
+
+        * A minimal systemd-resolved daemon has been added. It
+          currently simply acts as a companion to systemd-networkd and
+          manages resolv.conf based on per-interface DNS
+          configuration, possibly supplied via DHCP. In the long run
+          we hope to extend this into a local DNSSEC enabled DNS and
+          mDNS cache.
+
+        * The systemd-networkd-wait-online tool is now enabled by
+          default. It will delay network-online.target until a network
+          connection has been configured. The tool primarily integrates
+          with networkd, but will also make a best effort to make sense
+          of network configuration performed in some other way.
+
+        * Two new service options StartupCPUShares= and
+          StartupBlockIOWeight= have been added that work similarly to
+          CPUShares= and BlockIOWeight= however only apply during
+          system startup. This is useful to prioritize certain services
+          differently during bootup than during normal runtime.
+
+        * hostnamed has been changed to prefer the statically
+          configured hostname in /etc/hostname (unless set to
+          'localhost' or empty) over any dynamic one supplied by
+          dhcp. With this change, the rules for picking the hostname
+          match more closely the rules of other configuration settings
+          where the local administrator's configuration in /etc always
+          overrides any other settings.
+
+        Contributions fron: Ali H. Caliskan, Alison Chaiken, Bas van
+        den Berg, Brandon Philips, Cristian Rodríguez, Daniel Buch,
+        Dan Kilman, Dave Reisner, David Härdeman, David Herrmann,
+        David Strauss, Dimitris Spingos, Djalal Harouni, Eelco
+        Dolstra, Evan Nemerson, Florian Albrechtskirchinger, Greg
+        Kroah-Hartman, Harald Hoyer, Holger Hans Peter Freyther, Jan
+        Engelhardt, Jani Nikula, Jason St. John, Jeffrey Clark,
+        Jonathan Boulle, Kay Sievers, Lennart Poettering, Lukas
+        Nykryn, Lukasz Skalski, Łukasz Stelmach, Mantas Mikulėnas,
+        Marcel Holtmann, Martin Pitt, Matthew Monaco, Michael
+        Marineau, Michael Olbrich, Michal Sekletar, Mike Gilbert, Nis
+        Martensen, Patrik Flykt, Philip Lorenz, poma, Ray Strode,
+        Reyad Attiyat, Robert Milasan, Scott Thrasher, Stef Walter,
+        Steven Siloti, Susant Sahani, Tanu Kaskinen, Thomas Bächler,
+        Thomas Hindoe Paaboel Andersen, Tom Gundersen, Umut Tezduyar
+        Lindskog, WaLyong Cho, Will Woods, Zbigniew
+        Jędrzejewski-Szmek
+
+        -- Beijing, 2014-05-28
+
+CHANGES WITH 212:
+
+        * When restoring the screen brightness at boot, stay away from
+          the darkest setting or from the lowest 5% of the available
+          range, depending on which is the larger value of both. This
+          should effectively protect the user from rebooting into a
+          black screen, should the brightness have been set to minimum
+          by accident.
+
+        * sd-login gained a new sd_machine_get_class() call to
+          determine the class ("vm" or "container") of a machine
+          registered with machined.
+
+        * sd-login gained new calls
+          sd_peer_get_{session,owner_uid,unit,user_unit,slice,machine_name}(),
+          to query the identity of the peer of a local AF_UNIX
+          connection. They operate similarly to their sd_pid_get_xyz()
+          counterparts.
+
+        * PID 1 will now maintain a system-wide system state engine
+          with the states "starting", "running", "degraded",
+          "maintenance", "stopping". These states are bound to system
+          startup, normal runtime, runtime with at least one failed
+          service, rescue/emergency mode and system shutdown. This
+          state is shown in the "systemctl status" output when no unit
+          name is passed. It is useful to determine system state, in
+          particularly when doing so for many systems or containers at
+          once.
+
+        * A new command "list-machines" has been added to "systemctl"
+          that lists all local OS containers and shows their system
+          state (see above), if systemd runs inside of them.
+
+        * systemctl gained a new "-r" switch to recursively enumerate
+          units on all local containers, when used with the
+          "list-unit" command (which is the default one that is
+          executed when no parameters are specified).
+
+        * The GPT automatic partition discovery logic will now honour
+          two GPT partition flags: one may be set on a partition to
+          cause it to be mounted read-only, and the other may be set
+          on a partition to ignore it during automatic discovery.
+
+        * Two new GPT type UUIDs have been added for automatic root
+          partition discovery, for 32-bit and 64-bit ARM. This is not
+          particularly useful for discovering the root directory on
+          these architectures during bare-metal boots (since UEFI is
+          not common there), but still very useful to allow booting of
+          ARM disk images in nspawn with the -i option.
+
+        * MAC addresses of interfaces created with nspawn's
+          --network-interface= switch will now be generated from the
+          machine name, and thus be stable between multiple invocations
+          of the container.
+
+        * logind will now automatically remove all IPC objects owned
+          by a user if she or he fully logs out. This makes sure that
+          users who are logged out cannot continue to consume IPC
+          resources. This covers SysV memory, semaphores and message
+          queues as well as POSIX shared memory and message
+          queues. Traditionally, SysV and POSIX IPC had no life-cycle
+          limits. With this functionality, that is corrected. This may
+          be turned off by using the RemoveIPC= switch of logind.conf.
+
+        * The systemd-machine-id-setup and tmpfiles tools gained a
+          --root= switch to operate on a specific root directory,
+          instead of /.
+
+        * journald can now forward logged messages to the TTYs of all
+          logged in users ("wall"). This is the default for all
+          emergency messages now.
+
+        * A new tool systemd-journal-remote has been added to stream
+          journal log messages across the network.
+
+        * /sys/fs/cgroup/ is now mounted read-only after all cgroup
+          controller trees are mounted into it. Note that the
+          directories mounted beneath it are not read-only. This is a
+          security measure and is particularly useful because glibc
+          actually includes a search logic to pick any tmpfs it can
+          find to implement shm_open() if /dev/shm is not available
+          (which it might very well be in namespaced setups).
+
+        * machinectl gained a new "poweroff" command to cleanly power
+          down a local OS container.
+
+        * The PrivateDevices= unit file setting will now also drop the
+          CAP_MKNOD capability from the capability bound set, and
+          imply DevicePolicy=closed.
+
+        * PrivateDevices=, PrivateNetwork= and PrivateTmp= is now used
+          comprehensively on all long-running systemd services where
+          this is appropriate.
+
+        * systemd-udevd will now run in a disassociated mount
+          namespace. To mount directories from udev rules, make sure to
+          pull in mount units via SYSTEMD_WANTS properties.
+
+        * The kdbus support gained support for uploading policy into
+          the kernel. sd-bus gained support for creating "monitoring"
+          connections that can eavesdrop into all bus communication
+          for debugging purposes.
+
+        * Timestamps may now be specified in seconds since the UNIX
+          epoch Jan 1st, 1970 by specifying "@" followed by the value
+          in seconds.
+
+        * Native tcpwrap support in systemd has been removed. tcpwrap
+          is old code, not really maintained anymore and has serious
+          shortcomings, and better options such as firewalls
+          exist. For setups that require tcpwrap usage, please
+          consider invoking your socket-activated service via tcpd,
+          like on traditional inetd.
+
+        * A new system.conf configuration option
+          DefaultTimerAccuracySec= has been added that controls the
+          default AccuracySec= setting of .timer units.
+
+        * Timer units gained a new WakeSystem= switch. If enabled,
+          timers configured this way will cause the system to resume
+          from system suspend (if the system supports that, which most
+          do these days).
+
+        * Timer units gained a new Persistent= switch. If enabled,
+          timers configured this way will save to disk when they have
+          been last triggered. This information is then used on next
+          reboot to possible execute overdue timer events, that
+          could not take place because the system was powered off.
+          This enables simple anacron-like behaviour for timer units.
+
+        * systemctl's "list-timers" will now also list the time a
+          timer unit was last triggered in addition to the next time
+          it will be triggered.
+
+        * systemd-networkd will now assign predictable IPv4LL
+          addresses to its local interfaces.
+
+        Contributions from: Brandon Philips, Daniel Buch, Daniel Mack,
+        Dave Reisner, David Herrmann, Gerd Hoffmann, Greg
+        Kroah-Hartman, Hendrik Brueckner, Jason St. John, Josh
+        Triplett, Kay Sievers, Lennart Poettering, Marc-Antoine
+        Perennou, Michael Marineau, Michael Olbrich, Miklos Vajna,
+        Patrik Flykt, poma, Sebastian Thorarensen, Thomas Bächler,
+        Thomas Hindoe Paaboel Andersen, Tomasz Torcz, Tom Gundersen,
+        Umut Tezduyar Lindskog, Wieland Hoffmann, Zbigniew
+        Jędrzejewski-Szmek
+
+        -- Berlin, 2014-03-25
+
+CHANGES WITH 211:
+
+        * A new unit file setting RestrictAddressFamilies= has been
+          added to restrict which socket address families unit
+          processes gain access to. This takes address family names
+          like "AF_INET" or "AF_UNIX", and is useful to minimize the
+          attack surface of services via exotic protocol stacks. This
+          is built on seccomp system call filters.
+
+        * Two new unit file settings RuntimeDirectory= and
+          RuntimeDirectoryMode= have been added that may be used to
+          manage a per-daemon runtime directories below /run. This is
+          an alternative for setting up directory permissions with
+          tmpfiles snippets, and has the advantage that the runtime
+          directory's lifetime is bound to the daemon runtime and that
+          the daemon starts up with an empty directory each time. This
+          is particularly useful when writing services that drop
+          privileges using the User= or Group= setting.
+
+        * The DeviceAllow= unit setting now supports globbing for
+          matching against device group names.
+
+        * The systemd configuration file system.conf gained new
+          settings DefaultCPUAccounting=, DefaultBlockIOAccounting=,
+          DefaultMemoryAccounting= to globally turn on/off accounting
+          for specific resources (cgroups) for all units. These
+          settings may still be overridden individually in each unit
+          though.
+
+        * systemd-gpt-auto-generator is now able to discover /srv and
+          root partitions in addition to /home and swap partitions. It
+          also supports LUKS-encrypted partitions now. With this in
+          place, automatic discovery of partitions to mount following
+          the Discoverable Partitions Specification
+          (http://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec)
+          is now a lot more complete. This allows booting without
+          /etc/fstab and without root= on the kernel command line on
+          systems prepared appropriately.
+
+        * systemd-nspawn gained a new --image= switch which allows
+          booting up disk images and Linux installations on any block
+          device that follow the Discoverable Partitions Specification
+          (see above). This means that installations made with
+          appropriately updated installers may now be started and
+          deployed using container managers, completely
+          unmodified. (We hope that libvirt-lxc will add support for
+          this feature soon, too.)
+
+        * systemd-nspawn gained a new --network-macvlan= setting to
+          set up a private macvlan interface for the
+          container. Similarly, systemd-networkd gained a new
+          Kind=macvlan setting in .netdev files.
+
+        * systemd-networkd now supports configuring local addresses
+          using IPv4LL.
+
+        * A new tool systemd-network-wait-online has been added to
+          synchronously wait for network connectivity using
+          systemd-networkd.
+
+        * The sd-bus.h bus API gained a new sd_bus_track object for
+          tracking the life-cycle of bus peers. Note that sd-bus.h is
+          still not a public API though (unless you specify
+          --enable-kdbus on the configure command line, which however
+          voids your warranty and you get no API stability guarantee).
+
+        * The $XDG_RUNTIME_DIR runtime directories for each user are
+          now individual tmpfs instances, which has the benefit of
+          introducing separate pools for each user, with individual
+          size limits, and thus making sure that unprivileged clients
+          can no longer negatively impact the system or other users by
+          filling up their $XDG_RUNTIME_DIR. A new logind.conf setting
+          RuntimeDirectorySize= has been introduced that allows
+          controlling the default size limit for all users. It
+          defaults to 10% of the available physical memory. This is no
+          replacement for quotas on tmpfs though (which the kernel
+          still does not support), as /dev/shm and /tmp are still
+          shared resources used by both the system and unprivileged
+          users.
+
+        * logind will now automatically turn off automatic suspending
+          on laptop lid close when more than one display is
+          connected. This was previously expected to be implemented
+          individually in desktop environments (such as GNOME),
+          however has been added to logind now, in order to fix a
+          boot-time race where a desktop environment might not have
+          been started yet and thus not been able to take an inhibitor
+          lock at the time where logind already suspends the system
+          due to a closed lid.
+
+        * logind will now wait at least 30s after each system
+          suspend/resume cycle, and 3min after system boot before
+          suspending the system due to a closed laptop lid. This
+          should give USB docking stations and similar enough time to
+          be probed and configured after system resume and boot in
+          order to then act as suspend blocker.
+
+        * systemd-run gained a new --property= setting which allows
+          initialization of resource control properties (and others)
+          for the created scope or service unit. Example: "systemd-run
+          --property=BlockIOWeight=10 updatedb" may be used to run
+          updatedb at a low block IO scheduling weight.
+
+        * systemd-run's --uid=, --gid=, --setenv=, --setenv= switches
+          now also work in --scope mode.
+
+        * When systemd is compiled with kdbus support, basic support
+          for enforced policies is now in place. (Note that enabling
+          kdbus still voids your warranty and no API compatibility
+          promises are made.)
+
+        Contributions from: Andrey Borzenkov, Ansgar Burchardt, Armin
+        K., Daniel Mack, Dave Reisner, David Herrmann, Djalal Harouni,
+        Harald Hoyer, Henrik Grindal Bakken, Jasper St. Pierre, Kay
+        Sievers, Kieran Clancy, Lennart Poettering, Lukas Nykryn,
+        Mantas Mikulėnas, Marcel Holtmann, Mark Oteiza, Martin Pitt,
+        Mike Gilbert, Peter Rajnoha, poma, Samuli Suominen, Stef
+        Walter, Susant Sahani, Tero Roponen, Thomas Andersen, Thomas
+        Bächler, Thomas Hindoe Paaboel Andersen, Tomasz Torcz, Tom
+        Gundersen, Umut Tezduyar Lindskog, Uoti Urpala, Zachary Cook,
+        Zbigniew Jędrzejewski-Szmek
+
+        -- Berlin, 2014-03-12
+
 CHANGES WITH 210:
 
         * systemd will now relabel /dev after loading the SMACK policy
           according to SMACK rules.
 
-        * A new unit file option AppArmoreProfile= has been added to
+        * A new unit file option AppArmorProfile= has been added to
           set the AppArmor profile for the processes of a unit.
 
         * A new condition check ConditionArchitecture= has been added
@@ -18,11 +1053,11 @@ CHANGES WITH 210:
 
         * logind is now a lot more aggressive when suspending the
           machine due to a closed laptop lid. Instead of acting only
-          on the lid close action it will continuously watch the lid
+          on the lid close action, it will continuously watch the lid
           status and act on it. This is useful for laptops where the
           power button is on the outside of the chassis so that it can
           be reached without opening the lid (such as the Lenovo
-          Yoga). On those machines logind will now immediately
+          Yoga). On those machines, logind will now immediately
           re-suspend the machine if the power button has been
           accidentally pressed while the laptop was suspended and in a
           backpack or similar.
@@ -30,7 +1065,7 @@ CHANGES WITH 210:
         * logind will now watch SW_DOCK switches and inhibit reaction
           to the lid switch if it is pressed. This means that logind
           will not suspend the machine anymore if the lid is closed
-          and the systemd is docked, if the laptop supports SW_DOCK
+          and the system is docked, if the laptop supports SW_DOCK
           notifications via the input layer. Note that ACPI docking
           stations do not generate this currently. Also note that this
           logic is usually not fully sufficient and Desktop
@@ -59,7 +1094,7 @@ CHANGES WITH 210:
         * The DeviceAllow= setting in unit files now supports a syntax
           to whitelist an entire group of devices node majors at once,
           based on the /proc/devices listing. For example, with the
-          string "char-pts" it is now possible to whitelist all
+          string "char-pts", it is now possible to whitelist all
           current and future pseudo-TTYs at once.
 
         * sd-event learned a new "post" event source. Event sources of
@@ -73,28 +1108,28 @@ CHANGES WITH 210:
           enabled/disabled using systemctl. It still is enabled by
           default however.
 
-        * When creating a veth interface pair with systemd-nspawn the
+        * When creating a veth interface pair with systemd-nspawn, the
           host side will now be prefixed with "vb-" if
           --network-bridge= is used, and with "ve-" if --network-veth
-          is used. This way it is easy to distinguish these cases on
+          is used. This way, it is easy to distinguish these cases on
           the host, for example to apply different configuration to
           them with systemd-networkd.
 
         * The compatibility libraries for libsystemd-journal.so,
           libsystem-id128.so, libsystemd-login.so and
           libsystemd-daemon.so do not make use of IFUNC
-          anymore. Instead we now build libsystemd.so multiple times
+          anymore. Instead, we now build libsystemd.so multiple times
           under these alternative names. This means that the footprint
           is drastically increased, but given that these are
-          transitional compatibility libraries this shouldn't matter
+          transitional compatibility libraries, this should not matter
           much. This change has been made necessary to support the ARM
           platform for these compatibility libraries, as the ARM
-          toolchain isn't really at the same level as the toolchain
+          toolchain is not really at the same level as the toolchain
           for other architectures like x86 and does not support
           IFUNC. Please make sure to use --enable-compat-libs only
           during a transitional period!
 
-        Contributions from: Andreas Fuchs, Armin K, Colin Walters,
+        Contributions from: Andreas Fuchs, Armin K., Colin Walters,
         Daniel Mack, Dave Reisner, David Herrmann, Djalal Harouni,
         Holger Schurig, Jason A. Donenfeld, Jason St. John, Jasper
         St. Pierre, Kay Sievers, Lennart Poettering, Łukasz Stelmach,
@@ -344,7 +1379,7 @@ CHANGES WITH 209:
           merged them into a single library, libsystemd.so, which
           provides all symbols. The reason for this is cyclic
           dependencies, as these libraries tend to use each other's
-          symbols. So far, we've managed to workaround that by linking
+          symbols. So far, we have managed to workaround that by linking
           a copy of a good part of our code into each of these
           libraries again and again, which, however, makes certain
           things hard to do, like sharing static variables. Also, it
@@ -496,9 +1531,9 @@ CHANGES WITH 209:
 
         * systemd-nspawn gained a new --personality= switch for
           setting the kernel personality for the container. This is
-          useful when running a 32bit container on a 64bit host. A
-          similar option Personality= is now also available in service
-          units.
+          useful when running a 32-bit container on a 64-bit host. A
+          similar option Personality= is now also available for service
+          units to use.
 
         * logind will now also track a "Desktop" identifier for each
           session which encodes the desktop environment of it. This is
@@ -522,8 +1557,8 @@ CHANGES WITH 209:
 
         * For usage together with SystemCallFilter=, a new
           SystemCallErrorNumber= setting has been introduced that
-          allows configuration of a system error number to return on
-          filtered system calls, instead of immediately killing the
+          allows configuration of a system error number to be returned
+          on filtered system calls, instead of immediately killing the
           process. Also, SystemCallArchitectures= has been added to
           limit access to system calls of a particular architecture
           (in order to turn off support for unused secondary
@@ -588,13 +1623,13 @@ CHANGES WITH 208:
 
         * A new tmpfiles.d(5) command "m" has been introduced which
           may be used to change the owner/group/access mode of a file
-          or directory if it exists, but do nothing if it doesn't.
+          or directory if it exists, but do nothing if it does not.
 
         * This release removes high-level support for the
           MemorySoftLimit= cgroup setting. The underlying kernel
           cgroup attribute memory.soft_limit= is currently badly
           designed and likely to be removed from the kernel API in its
-          current form, hence we shouldn't expose it for now.
+          current form, hence we should not expose it for now.
 
         * The memory.use_hierarchy cgroup attribute is now enabled for
           all cgroups systemd creates in the memory cgroup
@@ -677,7 +1712,7 @@ CHANGES WITH 207:
 
         * InaccessibleDirectories= and ReadOnlyDirectories= now take
           paths that are optionally prefixed with "-" to indicate that
-          it should not be considered a failure if they don't exist.
+          it should not be considered a failure if they do not exist.
 
         * journalctl -o (and similar commands) now understands a new
           output mode "short-precise", it is similar to "short" but
@@ -783,7 +1818,7 @@ CHANGES WITH 206:
           databases to pre-generate dead device nodes based on meta
           information contained in kernel modules, so that these would
           be auto-loaded on access rather then at boot. As this
-          doesn't really have much to do with the exposing actual
+          does not really have much to do with the exposing actual
           kernel devices to userspace this has always been slightly
           alien in the udev codebase. Following the new scheme kmod
           will now generate a runtime snippet for tmpfiles from the
@@ -940,7 +1975,7 @@ CHANGES WITH 205:
           not available as public API.
 
         * systemd will now look for the "debug" argument on the kernel
-          command line and enable debug logging, similar to
+          command line and enable debug logging, similar to what
           "systemd.log_level=debug" already did before.
 
         * "systemctl set-default", "systemctl get-default" has been
@@ -1203,7 +2238,7 @@ CHANGES WITH 201:
 
         * 'systemd-analyze dot' gained the ability to filter for
           specific units via shell-style globs, to create smaller,
-          more useful graphs. I.e. it's now possible to create simple
+          more useful graphs. I.e. it is now possible to create simple
           graphs of all the dependencies between only target units, or
           of all units that Avahi has dependencies with.
 
@@ -1379,7 +2414,7 @@ CHANGES WITH 198:
 
         * The various "environment" files, such as /etc/locale.conf
           now support continuation lines with a backslash ("\") as
-          last character in the line, similar in style (but different)
+          last character in the line, similarly in style (but different)
           to how this is supported in shells.
 
         * For normal user processes the _SYSTEMD_USER_UNIT= field is
@@ -1426,7 +2461,7 @@ CHANGES WITH 198:
 
         * "systemctl unlock-sessions" has been added, that allows
           unlocking the screens of all user sessions at once, similar
-          how "systemctl lock-sessions" already locked all users
+          to how "systemctl lock-sessions" already locked all users
           sessions. This is backed by a new D-Bus call UnlockSessions().
 
         * "loginctl seat-status" will now show the master device of a
@@ -1506,7 +2541,7 @@ CHANGES WITH 198:
           pager. This is only supported in conjunction with "less".
 
         * journalctl gained a new "--user-unit=" option, that works
-          similar to "--unit=" but filters for user units rather than
+          similarly to "--unit=" but filters for user units rather than
           system units.
 
         * A number of unit files to ease adoption of systemd in
@@ -1581,8 +2616,8 @@ CHANGES WITH 197:
           http://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames
 
         * Auke Kok's bootchart implementation has been added to the
-          systemd tree. It's an optional component that can graph the
-          boot in quite some detail. It's one of the best bootchart
+          systemd tree. It is an optional component that can graph the
+          boot in quite some detail. It is one of the best bootchart
           implementations around and minimal in its code and
           dependencies.
 
@@ -1783,7 +2818,7 @@ CHANGES WITH 196:
           PolicyKit-less systems. Quite frankly this should have been
           this way since day one. It is absolutely our intention to
           make systemd work fine on PolicyKit-less systems, and we
-          consider it a bug if something doesn't work as it should if
+          consider it a bug if something does not work as it should if
           PolicyKit is not around.
 
         * For embedded systems it is now possible to build udev and
@@ -1955,7 +2990,7 @@ CHANGES WITH 192:
         * The bash completion logic is now available for journalctl
           too.
 
-        * We don't mount the "cpuset" controller anymore together with
+        * We do not mount the "cpuset" controller anymore together with
           "cpu" and "cpuacct", as "cpuset" groups generally cannot be
           started if no parameters are assigned to it. "cpuset" hence
           broke code that assumed it it could create "cpu" groups and
@@ -2004,7 +3039,7 @@ CHANGES WITH 191:
 
 CHANGES WITH 190:
 
-        * Whenever a unit changes state we'll now log this to the
+        * Whenever a unit changes state we will now log this to the
           journal and show along the unit's own log output in
           "systemctl status".
 
@@ -2074,8 +3109,8 @@ CHANGES WITH 190:
         * There's now a new RPM macro definition for the system preset
           dir: %_presetdir.
 
-        * journald will now warn if it can't forward a message to the
-          syslog daemon because it's socket is full.
+        * journald will now warn if it ca not forward a message to the
+          syslog daemon because its socket is full.
 
         * timedated will no longer write or process /etc/timezone,
           except on Debian. As we do not support late mounted /usr
@@ -2603,7 +3638,7 @@ CHANGES WITH 183:
 
         * systemctl will now warn you if .mount units generated from
           /etc/fstab are out of date due to changes in fstab that
-          haven't been read by systemd yet.
+          have not been read by systemd yet.
 
         * systemd is now suitable for usage in initrds. Dracut has
           already been updated to make use of this. With this in place
@@ -2666,7 +3701,7 @@ CHANGES WITH 183:
         * We now mount /tmp as tmpfs by default, but this can be
           masked and /etc/fstab can override it.
 
-        * Since udisks doesn't make use of /media anymore we are not
+        * Since udisks does not make use of /media anymore we are not
           mounting a tmpfs on it anymore.
 
         * journalctl gained a new --local switch to only interleave
@@ -2707,7 +3742,7 @@ CHANGES WITH 44:
           folks
 
         * We now refuse non-UTF8 strings used in various configuration
-          and unit files. This is done to ensure we don't pass invalid
+          and unit files. This is done to ensure we do not pass invalid
           data over D-Bus or expose it elsewhere.
 
         * Register Mimo USB Screens as suitable for automatic seat
@@ -2868,7 +3903,7 @@ CHANGES WITH 39:
           death, since fanotify() will not see accesses done by blkid,
           or fsck.
 
-        * Don't show kernel threads in systemd-cgls anymore, unless
+        * Do not show kernel threads in systemd-cgls anymore, unless
           requested with new -k switch.
 
         Contributions from: Dan Horák, Kay Sievers, Lennart
@@ -2940,7 +3975,7 @@ CHANGES WITH 38:
           --with-rootprefix= to follow the naming used by udev and
           kmod
 
-        * Unless specified otherwise we'll now install to /usr instead
+        * Unless specified otherwise we will now install to /usr instead
           of /usr/local by default.
 
         * Processes with '@' in argv[0][0] are now excluded from the
diff --git a/README b/README
index b918132..d47ea45 100644 (file)
--- a/README
+++ b/README
@@ -38,8 +38,12 @@ LICENSE:
 
 REQUIREMENTS:
         Linux kernel >= 3.0
+        Linux kernel >= 3.3 for loop device partition support features with nspawn
+        Linux kernel >= 3.8 for Smack support
+
+        Kernel Config Options:
           CONFIG_DEVTMPFS
-          CONFIG_CGROUPS (it's OK to disable all controllers)
+          CONFIG_CGROUPS (it is OK to disable all controllers)
           CONFIG_INOTIFY_USER
           CONFIG_SIGNALFD
           CONFIG_TIMERFD
@@ -49,8 +53,6 @@ REQUIREMENTS:
           CONFIG_PROC_FS
           CONFIG_FHANDLE (libudev, mount and bind mount handling)
 
-        Linux kernel >= 3.8 for Smack support
-
         Udev will fail to work with the legacy layout:
           CONFIG_SYSFS_DEPRECATED=n
 
@@ -68,6 +70,9 @@ REQUIREMENTS:
         create additional symlinks in /dev/disk/ and /dev/tape:
           CONFIG_BLK_DEV_BSG
 
+        Required for PrivateNetwork in service units:
+          CONFIG_NET_NS
+
         Optional but strongly recommended:
           CONFIG_IPV6
           CONFIG_AUTOFS4_FS
@@ -75,12 +80,16 @@ REQUIREMENTS:
           CONFIG_TMPFS_XATTR
           CONFIG_SECCOMP
 
+        Required for CPUShares in resource control unit settings
+          CONFIG_CGROUP_SCHED
+          CONFIG_FAIR_GROUP_SCHED
+
         For systemd-bootchart, several proc debug interfaces are required:
           CONFIG_SCHEDSTATS
           CONFIG_SCHED_DEBUG
 
         For UEFI systems:
-          CONFIG_EFI_VARS
+          CONFIG_EFIVAR_FS
           CONFIG_EFI_PARTITION
 
         Note that kernel auditing is broken when used with systemd's
@@ -89,6 +98,13 @@ REQUIREMENTS:
         runtime using the kernel command line option "audit=0", or
         turn it off at kernel compile time using:
           CONFIG_AUDIT=n
+        If systemd is compiled with libseccomp support on
+        architectures which do not use socketcall() and where seccomp
+        is supported (this effectively means x86-64 and ARM, but
+        excludes 32-bit x86!), then nspawn will now install a
+        work-around seccomp filter that makes containers boot even
+        with audit being enabled. This works correctly only on kernels
+        3.14 and newer though. TL;DR: turn audit off, still.
 
         glibc >= 2.14
         libcap
@@ -99,18 +115,18 @@ REQUIREMENTS:
         libcryptsetup (optional)
         libaudit (optional)
         libacl (optional)
-        libattr (optional)
         libselinux (optional)
         liblzma (optional)
-        tcpwrappers (optional)
+        liblz4 >= 119 (optional)
         libgcrypt (optional)
         libqrencode (optional)
         libmicrohttpd (optional)
         libpython (optional)
+        libidn (optional)
+        gobject-introspection > 1.40.0 (optional)
+        elfutils >= 158 (optional)
         make, gcc, and similar tools
 
-        To sucessfully use --compat-libs, gcc >= 4.8 seems necessary.
-
         During runtime, you need the following additional
         dependencies:
 
@@ -155,7 +171,7 @@ USERS AND GROUPS:
         even in the very early boot stages, where no other databases
         and network are available:
 
-        tty, dialout, kmem, video, audio, lp, floppy, cdrom, tape, disk
+        audio, cdrom, dialout, disk, input, kmem, lp, tape, tty, video
 
         During runtime, the journal daemon requires the
         "systemd-journal" system group to exist. New journal files will
@@ -174,6 +190,39 @@ USERS AND GROUPS:
         exist. During execution this network facing service will drop
         privileges and assume this uid/gid for security reasons.
 
+        Similarly, the NTP daemon requires the "systemd-timesync" system
+        user and group to exist.
+
+        Similarly, the network management daemon requires the
+        "systemd-network" system user and group to exist.
+
+        Similarly, the name resolution daemon requires the
+        "systemd-resolve" system user and group to exist.
+
+        Similarly, the kdbus dbus1 proxy daemon requires the
+        "systemd-bus-proxy" system user and group to exist.
+
+NSS:
+        systemd ships with three NSS modules:
+
+        nss-myhostname resolves the local hostname to locally
+        configured IP addresses, as well as "localhost" to
+        127.0.0.1/::1.
+
+        nss-resolve enables DNS resolution via the systemd-resolved
+        DNS/LLMNR caching stub resolver "systemd-resolved".
+
+        nss-mymachines enables resolution of all local containers
+        registered with machined to their respective IP addresses.
+
+        To make use of these NSS modules, please add them to the
+        "hosts: " line in /etc/nsswitch.conf. The "resolve" module
+        should replace the glibc "dns" module in this file.
+
+        The three modules should be used in the following order:
+
+                hosts: files mymachines resolve myhostname
+
 WARNINGS:
         systemd will warn you during boot if /etc/mtab is not a
         symlink to /proc/mounts. Please ensure that /etc/mtab is a
@@ -190,6 +239,9 @@ WARNINGS:
         about this, since this kind of file system setup is not really
         supported anymore by the basic set of Linux OS components.
 
+        systemd requires that the /run mount point exists. systemd also
+        requires that /var/run is a a symlink to /run.
+
         For more information on this issue consult
         http://freedesktop.org/wiki/Software/systemd/separate-usr-is-broken
 
diff --git a/TODO b/TODO
index b7dff10..cbd8384 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,8 +1,8 @@
 Bugfixes:
-* enabling an instance unit creates a pointless link, and
-  the unit will be started with getty@getty.service:
-    $ systemctl enable getty@.service
-    ln -s '/usr/lib/systemd/system/getty@.service' '/etc/systemd/system/getty.target.wants/getty@.service'
+* Re-enable "fsck -l" when it is ready:
+   https://bugs.freedesktop.org/show_bug.cgi?id=79576#c5
+
+* Should systemctl status \* work on all unit types, not just .service?
 
 * Dangling symlinks of .automount unit files in .wants/ directories, set up
   automount points even when the original .automount file did not exist
@@ -10,14 +10,7 @@ Bugfixes:
 
 * properly handle .mount unit state tracking when two mount points are stacked one on top of another on the exact same mount point.
 
-* shorten the message to sane length:
-
-  Cannot add dependency job for unit display-manager.service, ignoring: Unit display-manager.service failed to load: No such file or directory. See system logs and 'systemctl status display-manager.service' for details.
-
-* systemctl --root=container/ set-default ... is totally borked.
-
 External:
-
 * Fedora: when installing fedora with yum --installroot /var/run is a directory, not a symlink
    https://bugzilla.redhat.com/show_bug.cgi?id=975864
 
@@ -25,23 +18,154 @@ External:
 
 * Fedora: post FPC ticket to move add %tmpfiles_create to the packaging guidelines
 
+* Fedora: move kernel image to /usr/lib/modules/, kernel-install will take care of populating /boot
+
+* Fedora: remove /etc/resolv.conf tmpfiles hack
+
 Features:
 
-* logind: watch drm connectors and if we see a number of connectors !=
-  1 avoid processing the lid switch.
+* journald: make use of uid-range.h to managed uid ranges to split
+  journals in.
+
+* tmpfiles: port to unquote_many_words(), similar to sysusers
+
+* unquote_many_words() should probably be used by a lot of code that
+  currently uses FOREACH_WORD and friends. For example, most conf
+  parsing callbacks should use it.
+
+* logind: make the Suspend()/Hibernate() bus calls wait for the for
+  the job to be completed. before returning, so that clients can wait
+  for "systemctl suspend" to finish to know when the suspending is
+  complete.
+
+* sd_notify("SHUTDOWN=1") to fix a dbus activation race.
+  http://lists.freedesktop.org/archives/systemd-devel/2014-July/020983.html
+
+* merge ~/.local/share and ~/.local/lib into one similar /usr/lib and /usr/share....
+
+* make "systemctl suspend" block until we are back from suspend
+
+* remove readahead in 217
+
+* journald: allows specification of UID range for splitting up journal files
+
+* systemd.show_status= should probably have a mode where only failed
+  units are shown.
+
+* sd-event:
+  - make it possible to embedd our event loop into foreign event loops
+    by passing out the epoll fd and providing three functions that fit
+    into GSource nicely.
+
+* networkd:
+  - add LLDP client side support
+  - ipv4ll with multiple interfaces doesn't work when both dhcp and
+    ipv4ll is used. for some reasons the kernel will currently pick an
+    ipv4ll source address to reach non-ipv4ll gateways.
+  - dhcp and ipv4ll should probably be skipped for "lo" devices, even
+    if the user has a catchall .network file installed, that might
+    theoretically match it.
+  - we probably should introduce a new operational state that
+    indicates that we are trying to acquire some configuration for a
+    link but haven't acquired any yet. Just to inform the admin that
+    networkd cares about an interface, but is still in progress..
+  - the DHCP lease data (such as NTP/DNS) is still made available when
+    a carrier is lost on a link. It should be removed instantly.
+  - .network setting that allows overriding of the hostname to send to the dhcp server
+    http://lists.freedesktop.org/archives/systemd-devel/2014-July/021550.html
+  - add per-network Domains= settings, with a special syntax Domains=*
+    for routing all non-otherwise routed traffic to this link
+  - add UseDomains= setting to [DHCP] to add dhcp supplied domains to
+    per-interface Domains= list.
+  - expose in the API the following bits:
+        - option 15, domain name and/or option 119, search list
+        - option 12, host name and/or option 81, fqdn
+        - option 100, 101, timezone
+        - option 123, 144, geolocation
+        - option 252, configure http proxy (PAC/wpad)
+  - networkd's dhcp server should transparently pass on the DNS and
+    NTP server list it got from user configuration and its dhcp client
+    to clients. It should also pass on its own timezone information.
+  - provide a way to define a per-network interface default metric value
+    for all routes to it. possibly a second default for DHCP routes.
+
+* resolved:
+  - put networkd events and rtnl events at a higher priority, so that
+    we always process them before we process client requests
+  - DNSSEC
+        - use base64 for key presentation?
+        - add display of private key types (http://tools.ietf.org/html/rfc4034#appendix-A.1.1)?
+        - add nice formatting of DNS timestamps
+  - DNS
+        - search paths
+  - mDNS/DNS-SD
+        - avahi compat
+  - DNS-SD service registration from socket units
+  - edns0
+  - dname
+  - cname on PTR (?)
+
+* Ignore .busname units on classic D-Bus boots, systemd-resolved cannot be started on kdbus
+  without the active policy and should get a Wants=org.freedesktop.resolve1.busname to
+  pull-in the policy.
+
+* Allow multiple ExecStart= for all Type= settings, so that we can cover rescue.service nicely
+
+* the resolv.conf tmpfiles line should be covered by ENABLE_NETWORKD...
+
+* Add a new verb "systemctl top"
+
+* logind: allow users to kill or lock their own sessions
+
+* add new gpt type for btrfs volumes
+
+* support empty /etc boots nicely:
+  - nspawn/gpt-generator: introduce new gpt partition type for /usr
+  - fstab-generator: support systemd.volatile=yes|no|state on the kernel cmdline, too, similar to nspawn's --volatile=
+  - fstab-generator: add support for usr= in addition to root= on the kernel cmdline
+
+* generator that automatically discovers btrfs subvolumes, identifies their purpose based on some xattr on them.
+
+* support setting empty environment variables with Environment= and EnvironmentFile=
+
+* timer units: actually add extra delays to timer units with high AccuracySec values, don't start them already when we are awake...
+
+* a way for container managers to turn off getty starting via $container_headless= or so...
+
+* figure out a nice way how we can let the admin know what child/sibling unit causes cgroup membership for a specific unit
+
+* journalctl: add the ability to look for the most recent process of a binary. journalctl /usr/bin/X11 --pid=-1 or so...
+
+* set NOTIFY_SOCKET also for control processes
+
+* mount_cgroup_controllers(): symlinks need to get the label applied
+
+* For timer units: add some mechanisms so that timer units that trigger immediately on boot do not have the services
+  they run added to the initial transaction and thus confuse Type=idle.
+
+* Add timeout to early-boot, and shut down the system if it is hit. Solves the laptop-in-bag problem and is useful for embedded cases
+
+* Run most system services with cgroupfs read-only and procfs with a more secure mode (doesn't work, since the hidepid= option is per-pid-namespace, not per-mount)
+
+* sd-event: generate a failure of a default event loop is executed out-of-thread
+
+* expose "Locked" property on logind sesison objects
+
+* add bus api to query unit file's X fields.
+
+* consider adding RuntimeDirectoryUser= + RuntimeDirectoryGroup=
+
+* sd-event: define more intervals where we will shift wakeup intervals around in, 1h, 6h, 24h, ...
 
-* logind: avoid processing the lid switch for 3min (or so) after
-  startup and 1min (or so) after coming back from suspend, in order to
-  give USB docking stations time to pop up a video device, which could
-  act as lid-switch blocker.
+* gpt-auto-generator:
+  - Support LUKS for root devices
+  - Define new partition type for encrypted swap? Support probed LUKS for encrypted swap?
+  - Make /home automount rather than mount?
 
-* machined: provide calls GetMachineByAddress() on the manager
-  interface to get the machine for a local IP address, and
-  GetAddress() on the Machine interface to get the Address for a
-  machine. Implement via forking off child process which quickly joins
-  the cotnainer and passes data to parent. Show this in "machinectl
-  status", and use it to implement NSS module to provide automatic
-  name resolution for containers.
+* improve journalctl performance by loading journal files
+  lazily. Encode just enough information in the file name, so that we
+  do not have to open it to know that it is not interesting for us, for
+  the most common operations.
 
 * add generator that pulls in systemd-network from containers when
   CAP_NET_ADMIN is set, more than the loopback device is defined, even
@@ -49,37 +173,13 @@ Features:
 
 * MessageQueueMessageSize= and RLimitFSIZE= (and suchlike) should use parse_iec_size().
 
-* man: move .link, .network and .netdev documentation into their own
-  man pages maybe called "systemd.link(5)", "systemd.network(5)" and
-  "systemd.netdev(5)" or so.
-
 * "busctl status" works only as root on dbus1, since we cannot read
   /proc/$PID/exe
 
-* systemctl (and possibly related tools): support a new switch that
-  allows enumerating units in local containers recursively. "systemctl
-  list-units -R" or so should not only lists on the host, but also the
-  services in all containers in a pretty way, to give an overview of
-  the entire system. Also, maybe add "systemctl list-machines" which
-  works like "machinectl list" but includes information about the
-  health status of each registered machine. For that we should
-  probably implement something that encodes the system health status
-  in a single enum state, i.e. something like a system-wide state
-  starting → running → failed → stopping, that is based on the current
-  job queue and a check for failed services. Maybe then change
-  "systemctl status" without args to output this state along with a
-  selection of other data, such as the uptime or so.
-
-* Add a seccomp-based filter for socket() calls to limit services to
-  specific address families (for example: AF_UNIX), inspired by
-  Android's sandboxing
-
 * implement Distribute= in socket units to allow running multiple
   service instances processing the listening socket, and open this up
   for ReusePort=
 
-* add a timelimit to generator invocation
-
 * socket units: support creating sockets in different namespace,
   opening it up for JoinsNamespaceOf=. This would require to fork off
   a tiny process that joins the namespace and creates/binds the socket
@@ -96,13 +196,9 @@ Features:
   on screen, not unlike how job control works on the shell
 
 * completions:
- - busctl zsh completion is outdated
- - systemd-nspawn -Z/-L/-q is missing for zsh
- - systemd-nspawn completion is missing for bash
  - manager property enumeration was broken when systemd moved to /usr/lib/
 
 * cgroups:
-  - implement system-wide DefaultCPUAccounting=1 switch (and similar for blockio, memory?)
   - implement per-slice CPUFairScheduling=1 switch
   - handle jointly mounted controllers correctly
   - introduce high-level settings for RT budget, swappiness
@@ -128,14 +224,8 @@ Features:
 
 * unify dispatch table in systemctl_main() and friends
 
-* Automatically configure swap partition to use for hibernation by looking for largest swap partition on the root disk?
-
-* socket-proxyd: Use sd-resolve to resolve the server address
-
 * rfkill,backlight: we probably should run the load tools inside of the udev rules so that the state is properly initialized by the time other software sees it
 
-* move config_parse_path_strv() out of conf-parser.c
-
 * After coming back from hibernation reset hibernation swap partition using the /dev/snapshot ioctl APIs
 
 * If we try to find a unit via a dangling symlink, generate a clean
@@ -150,46 +240,35 @@ Features:
 
 * btrfs raid assembly: some .device jobs stay stuck in the queue
 
-* make sure gdm doesn't use multi-user-x but the new default X configuration file, and then remove multi-user-x from systemd
+* make sure gdm does not use multi-user-x but the new default X configuration file, and then remove multi-user-x from systemd
 
 * man: the documentation of Restart= currently is very misleading and suggests the tools from ExecStartPre= might get restarted.
 
 * load .d/*.conf dropins for device units
 
-* gparted needs to disable auto-activation of mount units somehow, or
-  maybe we should stop doing auto-activation of this after boot
-  entirely. https://bugzilla.gnome.org/show_bug.cgi?id=701676
-  Maybe take a BSD lock at the disk device node and teach udev to
-  check for that and suppress event handling.
-
-* something pulls in pcre as shared object dependency into our daemons such as hostnamed.
-
 * allow implementation of InaccessibleDirectories=/ plus
   ReadOnlyDirectories=... for whitelisting files for a service.
 
 * sd-bus:
-  - when kdbus doesn't take our message without memfds, try again with memfds
-  - implement monitor logic
+  - when kdbus does not take our message without memfds, try again with memfds
+  - systemd-bus-proxyd needs to enforce good old XML policy
+  - allow updating attach flags during runtime
+  - pid1: peek into activating message when activating a service
+  - introduce sd_bus_emit_object_added()/sd_bus_emit_object_removed() that automatically includes the build-in interfaces in the list
+  - port to sd-resolve for connecting to TCP dbus servers
   - see if we can drop more message validation on the sending side
   - add API to clone sd_bus_message objects
-  - systemd-bus-proxyd needs to enforce good old XML policy
-  - upload minimal kdbus policy into the kernel at boot
+  - make AddMatch calls on dbus1 transports async?
   - kdbus: matches against source or destination pids for an "strace -p"-like feel. Problem: The PID info needs to be available in userspace too...
   - longer term: priority inheritance
-  - check sender of response messages
   - dbus spec updates:
        - kdbus mapping
        - NameLost/NameAcquired obsolete
        - GVariant
        - "const" properties (posted)
-  - port exit-on-idle logic to byebye ioctl
+       - path escaping
   - update systemd.special(7) to mention that dbus.socket is only about the compatibility socket now
-  - allow updating attach flags during runtime
-  - pid1: peek into activating message when activating a service
   - test bloom filter generation indexes
-  - introduce sd_bus_emit_object_added()/sd_bus_emit_object_removed() that automatically includes the build-in interfaces in the list
-  - port to sd-resolve for connecting to TCP dbus servers
-  - constructors for bus messages should probably not be OK with a NULL bus pointer
 
 * sd-event
   - allow multiple signal handlers per signal?
@@ -209,8 +288,6 @@ Features:
 
 * maybe add a generator that looks for "systemd.run=" on the kernel cmdline for container usercases...
 
-* timedatctl, localectl: possibly make some commands work without the daemon, for chroot situations...
-
 * timedatectl: print a nicer message when enabling ntp fails because ntpd/chrony are not installed
 
 * cgtop: make cgtop useful in a container
@@ -219,14 +296,8 @@ Features:
   - add 'set -e' to scripts in test/
   - make stuff in test/ work with separate output dir
 
-* systemctl delete x.snapshot leaves no trace in logs (at least at default level).
-
-* make the coredump collector tool move itself into the user's cgroup
-  so that the coredump is properly written to the user's own journal
-  file.
-
 * seems that when we follow symlinks to units we prefer the symlink
-  destination path over /etc and /usr. We shouldn't do that. Instead
+  destination path over /etc and /usr. We should not do that. Instead
   /etc should always override /run+/usr and also any symlink
   destination.
 
@@ -238,10 +309,10 @@ Features:
 * after all byte-wise realloc() is slow, even on glibc, so i guess we
   need manual exponential loops after all
 
-* BootLoaderSpec: drop allowing ext234 for $BOOT. Clarify that the
-  kernel has to be in $BOOT. Clarify that the boot loader should be
-  installed to the ESP. Define a way how an installer can figure out
-  whether a BLS compliant boot loader is installed.
+* BootLoaderSpec: Clarify that the kernel has to be in $BOOT. Clarify
+  that the boot loader should be installed to the ESP. Define a way
+  how an installer can figure out whether a BLS compliant boot loader
+  is installed.
 
 * think about requeuing jobs when daemon-reload is issued? usecase:
   the initrd issues a reload after fstab from the host is accessible
@@ -252,7 +323,7 @@ Features:
 
 * journal-or-kmsg is currently broken? See reverted commit 4a01181e460686d8b4a543b1dfa7f77c9e3c5ab8.
 
-* remove any syslog support from log.c -- we probably can't do this before split-off udev is gone for good
+* remove any syslog support from log.c -- we probably cannot do this before split-off udev is gone for good
 
 * shutdown logging: store to EFI var, and store to USB stick?
 
@@ -262,14 +333,11 @@ Features:
 
 * use "log level" rather than "log priority" everywhere
 
-* timedate: have global on/off switches for auto-time (NTP), and auto-timezone that connman can subscribe to.
-
 * merge unit_kill_common() and unit_kill_context()
 
 * introduce ExecCondition= in services
 
 * EFI:
-  - write man page for efi boot generator
   - honor language efi variables for default language selection (if there are any?)
   - honor timezone efi variables for default timezone selection (if there are any?)
   - change bootctl to be backed by systemd-bootd to control temporary and persistent default boot goal plus efi variables
@@ -291,9 +359,7 @@ Features:
   - logind: wakelock/opportunistic suspend support
   - Add pretty name for seats in logind
   - logind: allow showing logout dialog from system?
-  - logind: add equivalent to sd_pid_get_owner_uid() to the D-Bus API
   - we should probably handle SIGTERM/SIGINT to not leave dot files around, just in case
-  - when logging out, remove user-owned sysv and posix IPC objects
   - session scopes/user unit: add RequiresMountsFor for the home directory of the user
   - add Suspend() bus calls which take timestamps to fix double suspend issues when somebody hits suspend and closes laptop quickly.
   - if pam_systemd is invoked by su from a process that is outside of a
@@ -310,7 +376,7 @@ Features:
   - journald: also get thread ID from client, plus thread name
   - journal: when waiting for journal additions in the client always sleep at least 1s or so, in order to minimize wakeups
   - add API to close/reopen/get fd for journal client fd in libsystemd-journal.
-  - fallback to /dev/log based logging in libsystemd-journal, if we can't log natively?
+  - fallback to /dev/log based logging in libsystemd-journal, if we cannot log natively?
   - declare the local journal protocol stable in the wiki interface chart
   - journal: reuse XZ context
   - sd-journal: speed up sd_journal_get_data() with transparent hash table in bg
@@ -346,7 +412,7 @@ Features:
   - journald: make sure ratelimit is actually really per-service with the new cgroup changes
   - change systemd-journal-flush into a service that stays around during
     boot, and causes the journal to be moved back to /run on shutdown,
-    so that we don't keep /var busy. This needs to happen synchronously,
+    so that we do not keep /var busy. This needs to happen synchronously,
     hence doing this via signals is not going to work.
 
 * document:
@@ -373,39 +439,27 @@ Features:
     about it. Should fix both to print nice actionable messages.
   - print nice message from systemctl --failed if there are no entries shown, and hook that into ExecStartPre of rescue.service/emergency.service
   - add new command to systemctl: "systemctl system-reexec" which reexecs as many daemons as virtually possible
-  - systemctl enable: improve the success messages (i.e. more human readable, less shell-like)
-  - systemctl enable: fail if target to alias into doesn't exist? maybe show how many units are enabled afterwards?
+  - systemctl enable: fail if target to alias into does not exist? maybe show how many units are enabled afterwards?
   - systemctl: "Journal has been rotated since unit was started." message is misleading
   - support "systemctl stop foobar@.service" to stop all units matching a certain template
   - Something is wrong with symlink handling of "autovt@.service" in "systemctl list-unit-files"
-  - rework wait filter to not require match callback
   - better error message if you run systemctl without systemd running
   - systemctl status output should should include list of triggering units and their status
-  - in systemctl list-timers show time triggering units ran last
 
 * unit install:
   - "systemctl mask" should find all names by which a unit is accessible
     (i.e. by scanning for symlinks to it) and link them all to /dev/null
-  - "systemctl disable" of a unit instance removes all symlinks, but should
-    only remove the instance symlink (systemctl disable of a template
-    unit however should remove them all).
   - systemctl list-unit-files should list generated files (and probably with a new state "generated" for them, or so)
   - systemctl: maybe add "systemctl add-wants" or so...
 
-* introduce ntp.service (or suchlike) as symlink that is used to arbitrate between various NTP implementations
-
-* deal with sendmail/postfix exclusivity
-
 * timer units:
-  - timer events with system resume
   - timer units should get the ability to trigger when:
     o CLOCK_REALTIME makes jumps (TFD_TIMER_CANCEL_ON_SET)
     o DST changes
   - Support 2012-02~4 as syntax for specifying the fourth to last day of the month.
   - calendarspec: support value ranges with ".." notation. Example: 2013-4..8-1
-  - when parsing calendar timestamps support the UTC timezone (even if we won't support arbitrary timezone specs, support UTC itself certainly makes sense), also support syntaxes such as +0200
+  - when parsing calendar timestamps support the UTC timezone (even if we will not support arbitrary timezone specs, support UTC itself certainly makes sense), also support syntaxes such as +0200
   - Modulate timer frequency based on battery state
-  - anacron-like feature
 
 * update the kernel's TZ (sys_tz) when DST changes
 
@@ -416,54 +470,29 @@ Features:
   mode, it will never touch the RTC if the no reliable time source is active or the
   user did not request anything like it.
 
-* if booted in "quiet" mode, and an error happens, turn on status
-  output again, so that the emergency mode isn't totally
-  surprising. Also, terminate plymouth.
-
-* libunwind support for coredump pattern hook, and includes this in
-  the message for coredumps. After all, libunwind is now capable to
-  unwind coredumps since a few weeks ago. This probably requires that
-  we have nice support for multi-line messages on display in
-  logs-show.c. Alternatively: use libelfutil, which seems to be the
-  better supported alternative.
-
 * add libsystemd-password or so to query passwords during boot using the password agent logic
 
 * If we show an error about a unit (such as not showing up) and it has no Description string, then show a description string generated form the reverse of unit_name_mangle().
 
 * fedup: add --unit to systemctl switch-root somehow
-* fedup: don't delete initrd on switch-root
+* fedup: do not delete initrd on switch-root
 * fedup: generator
 
-* timedated: refuse time changes when NTP is on
-
 * clean up date formatting and parsing so that all absolute/relative timestamps we format can also be parsed
 
 * on shutdown: move utmp, wall, audit logic all into PID 1 (or logind?), get rid of systemd-update-utmp-runlevel
 
-* add "provisioning" instructions to setup an empty /etc + /var
-    - used to setup a new container from a shared /usr
-    - superset of tmpfiles model
-    - instructions shipped by packages and stored in /usr/lib/
-    - compose /etc/passwd and /etc/group, copy files
-    - able to create uid + gid used by packages, for file ownership
-
 * make repeated alt-ctrl-del presses printing a dump, or even force a reboot without
   waiting for the timeout
 
 * hostnamed: before returning information from /etc/machine-info.conf check the modification data and reread. Similar for localed, ...
 
-* currently x-systemd.timeout is lost in the initrd, since crypttab is copied into dracut, but fstab isn't
+* currently x-systemd.timeout is lost in the initrd, since crypttab is copied into dracut, but fstab is not
 
 * nspawn:
-  - nspawn: consider changing users for -u with /usr/bin/getent, so that NSS resolving works correctly
-  - nspawn: --read-only is not applied recursively to submounts
   - bind mount read-only the cgroup tree higher than nspawn
-  - nspawn: make it work for dwalsh and shared /usr containers -- tmpfs mounts as command line parameters
   - refuses to boot containers without /etc/machine-id (OK?), and with empty /etc/machine-id (not OK).
   - support taking a btrfs snapshot at startup and dropping it afterwards
-  - maybe: hookup nspawn and PrivateNetwork=yes with "ip netns"
-  - allow booting disk images with a GPT signature using the bootloaderspec partition uuids
 
 * cryptsetup:
   - cryptsetup-generator: allow specification of passwords in crypttab itself
@@ -478,30 +507,21 @@ Features:
 
 * make timer units go away after they elapsed
 
-* http://lists.freedesktop.org/archives/systemd-devel/2012-September/006502.html
-  (network and remote-fs on shutdown)
-
 * come up with a nice way to write queue/read_ahead_kb for a block device without interfering with readahead
 
 * move PID 1 segfaults to /var/lib/systemd/coredump?
 
 * create /sbin/init symlinks from the build system
 
-* Query Paul Moore about relabelling socket fds while they are open
-
 * allow writing multiple conditions in unit files on one line
 
-* explore multiple service instances per listening socket idea
-
 * MountFlags=shared acts as MountFlags=slave right now.
 
-* ReadOnlyDirectories= is not applied recursively to submounts
-
 * drop PID 1 reloading, only do reexecing (difficult: Reload()
   currently is properly synchronous, Reexec() is weird, because we
-  can't delay the response properly until we are back, so instead of
+  cannot delay the response properly until we are back, so instead of
   being properly synchronous we just keep open the fd and close it
-  when done. That means clients don't get a successful method reply,
+  when done. That means clients do not get a successful method reply,
   but much rather a disconnect on success.
 
 * properly handle loop back mounts via fstab, especially regards to fsck/passno
@@ -514,10 +534,8 @@ Features:
 
 * rename "userspace" to "core-os"
 
-* syscall filter: optionally don't enforce no new privs?
-
 * load-fragment: when loading a unit file via a chain of symlinks
-  verify that it isn't masked via any of the names traversed.
+  verify that it is not masked via any of the names traversed.
 
 * introduce Type=pid-file
 
@@ -549,8 +567,6 @@ Features:
 
 * introduce mix of BindTo and Requisite
 
-* add DeleteSocketsOnStop=yes|no option to socket units
-
 * There's currently no way to cancel fsck (used to be possible via C-c or c on the console)
 
 * add option to sockets to avoid activation. Instead just drop packets/connections, see http://cyberelk.net/tim/2012/02/15/portreserve-systemd-solution/
@@ -561,7 +577,7 @@ Features:
 
 * support crash reporting operation modes (https://live.gnome.org/GnomeOS/Design/Whiteboards/ProblemReporting)
 
-* default to actual 32bit PIDs, via /proc/sys/kernel/pid_max
+* default to actual 32-bit PIDs, via /proc/sys/kernel/pid_max
 
 * be able to specify a forced restart of service A where service B depends on, in case B
   needs to be auto-respawned?
@@ -569,12 +585,11 @@ Features:
 * when a bus name of a service disappears from the bus make sure to queue further activation requests
 
 * tmpfiles:
-  - check systemd-tmpfiles for selinux context hookup for mknod(), symlink() and similar
   - apply "x" on "D" too (see patch from William Douglas)
 
-* for services: don't set $HOME in services unless requested
+* for services: do not set $HOME in services unless requested
 
-* hide PAM/TCPWrap options in fragment parser when compile time disabled
+* hide PAM options in fragment parser when compile time disabled
 
 * when we automatically restart a service, ensure we restart its rdeps, too.
 
@@ -596,8 +611,6 @@ Features:
   when we start a service in order to avoid confusion when a user
   assumes starting a service is enough to make it accessible
 
-* support User= and Group= attributes for AF_UNIX sockets. (difficult, requires NSS from PID 1?)
-
 * Make it possible to set the keymap independently from the font on
   the kernel cmdline. Right now setting one resets also the other.
 
@@ -610,8 +623,6 @@ Features:
   - readahead: when bumping /sys readahead variable save mtime and compare later to detect changes
   - readahead: make use of EXT4_IOC_MOVE_EXT, as used by http://e4rat.sourceforge.net/
 
-* add support for /bin/mount -s
-
 * GC unreferenced jobs (such as .device jobs)
 
 * write blog stories about:
@@ -637,8 +648,6 @@ Features:
 
 * allow port=0 in .socket units
 
-* support systemd.mask= on the kernel command line.
-
 * recreate systemd's D-Bus private socket file on SIGUSR2
 
 * Support --test based on current system state
@@ -651,8 +660,6 @@ Features:
 
 * fingerprint.target, wireless.target, gps.target, netdevice.target
 
-* io priority during initialization
-
 * drop cap bounding set in readahead and other services
 
 * systemd-python:
@@ -670,16 +677,46 @@ Features:
    - Make sure ID_PATH is always exported and complete for
      network devices where possible, so we can safely rely
      on Path= matching
+   - check MTUBytes parsing (expecting size_t but we are using unsigned)
 
 * sd-rtnl:
-   - add support for exiting containers without reading them fully first
    - add support for more attribute types
+   - inbuilt piping support (essentially degenerate async)? see loopback-setup.c and other places
 
 * networkd:
    - add more keys to [Route] and [Address] sections
    - add support for more DHCPv4 options (and, longer term, other kinds of dynamic config)
    - add proper initrd support (in particular generate .network/.link files based on /proc/cmdline)
    - add reduced [Link] support to .network files
+   - add Scope= parsing option for [Network]
+   - properly handle routerless dhcp leases
+   - add more attribute support for SIT tunnel
+   - work with non-ethernet devices
+   - add support for more bond options
+
+* networkd-wait-online:
+   - make operstates to wait for configurable?
+
+* dhcp:
+   - figure out how much we can increase Maximum Message Size
+   - export timezone information
+   - support RFC4702 (pass FQDN)
+
+* dhcp6:
+   - add functions to set previously stored IPv6 addresses on startup and get
+     them at shutdown; store them in client->ia_na
+   - write more test cases
+   - implement and do duplicate address detection, see rfc 4862, 5.4.
+   - implement reconfigure support, see 5.3., 15.11. and 22.20.
+   - implement information request, see 1.2. and 18.1.5.
+   - implement support for temporary adressess (IA_TA)
+   - implement elapsed time option
+   - implement dhcpv6 authentication
+   - investigate the usefulness of Confirm messages; i.e. are there any
+     situations where the link changes without any loss in carrier detection
+     or interface down
+   - some servers don't do rapid commit without a filled in IA_NA, verify
+     this behavior
 
 External:
 
@@ -693,17 +730,11 @@ External:
 
 * patch kernel for xattr support in /dev, /proc/, /sys?
 
-* NTP: the kernel's 11-minutes-mode syncs the system time to the RTC, but only
-  in an ~30 minutes window. It does not adjust larger differences. Find a way
-  to tell the kernel, to always do a full time sync when the RTC is in UTC and
-  we are in 11-minutes-mode. When we trust the system time to NTP we also want
-  the RTC to sync up.
-
 * kernel: add device_type = "fb", "fbcon" to class "graphics"
 
 * drop accountsservice's StandardOutput=syslog and Type=dbus fields
 
-* dbus upstream still refers to dbus.target and shouldn't
+* dbus upstream still refers to dbus.target and should not
 
 * dbus: in fedora, make /var/lib/dbus/machine-id a symlink to /etc/machine-id
 
@@ -719,6 +750,11 @@ External:
 
 * fedora: update policy to declare access mode and ownership of unit files to root:root 0644, and add an rpmlint check for it
 
+* register catalog database signature as file magic
+
+* zsh shell completion: <command> <verb> -<TAB> should complete options, but currently
+  does not
+
 Regularly:
 
 * look for close() vs. close_nointr() vs. close_nointr_nofail()
@@ -729,7 +765,7 @@ Regularly:
 
 * pahole
 
-* set_put(), hashmap_put() return values check. i.e. == 0 doesn't free()!
+* set_put(), hashmap_put() return values check. i.e. == 0 does not free()!
 
 * use secure_getenv() instead of getenv() where appropriate
 
index 20f013a..744d13b 100755 (executable)
 
 set -e
 
+oldpwd=$(pwd)
+topdir=$(dirname $0)
+cd $topdir
+
 if [ -f .git/hooks/pre-commit.sample ] && [ ! -f .git/hooks/pre-commit ]; then
         # This part is allowed to fail
         cp -p .git/hooks/pre-commit.sample .git/hooks/pre-commit && \
@@ -53,20 +57,25 @@ args="$args \
 "
 fi
 
+cd $oldpwd
+
 if [ "x$1" = "xc" ]; then
-        ./configure CFLAGS='-g -O0 -ftrapv' --enable-compat-libs --enable-kdbus $args
+        $topdir/configure CFLAGS='-g -O0 -ftrapv' --enable-compat-libs --enable-kdbus $args
+        make clean
+elif [ "x$1" = "xt" ]; then
+        $topdir/configure CFLAGS='-g -O0 -ftrapv' --enable-compat-libs --enable-kdbus --enable-terminal $args
         make clean
 elif [ "x$1" = "xg" ]; then
-        ./configure CFLAGS='-g -Og -ftrapv' --enable-compat-libs --enable-kdbus $args
+        $topdir/configure CFLAGS='-g -Og -ftrapv' --enable-compat-libs --enable-kdbus $args
         make clean
 elif [ "x$1" = "xa" ]; then
-        ./configure CFLAGS='-g -O0 -Wsuggest-attribute=pure -Wsuggest-attribute=const -ftrapv' --enable-compat-libs --enable-kdbus $args
+        $topdir/configure CFLAGS='-g -O0 -Wsuggest-attribute=pure -Wsuggest-attribute=const -ftrapv' --enable-compat-libs --enable-kdbus $args
         make clean
 elif [ "x$1" = "xl" ]; then
-        ./configure CC=clang CFLAGS='-g -O0 -ftrapv -Wno-gnu' --enable-compat-libs --enable-kdbus $args
+        $topdir/configure CC=clang CFLAGS='-g -O0 -ftrapv -Wno-gnu' --enable-compat-libs --enable-kdbus $args
         make clean
 elif [ "x$1" = "xs" ]; then
-        scan-build ./configure CFLAGS='-g -O0 -ftrapv' --enable-compat-libs --enable-kdbus $args
+        scan-build $topdir/configure CFLAGS='-std=gnu99 -g -O0 -ftrapv' --enable-kdbus $args
         scan-build make
 else
         echo
@@ -74,6 +83,6 @@ else
         echo "Initialized build system. For a common configuration please run:"
         echo "----------------------------------------------------------------"
         echo
-        echo "./configure CFLAGS='-g -O0 -ftrapv' --enable-compat-libs --enable-kdbus $args"
+        echo "$topdir/configure CFLAGS='-g -O0 -ftrapv' --enable-compat-libs --enable-kdbus $args"
         echo
 fi
index 7920d6c..2f15199 100644 (file)
@@ -20,7 +20,7 @@
 AC_PREREQ([2.64])
 
 AC_INIT([systemd],
-        [210],
+        [216],
         [http://bugs.freedesktop.org/enter_bug.cgi?product=systemd],
         [systemd],
         [http://www.freedesktop.org/wiki/Software/systemd])
@@ -34,7 +34,7 @@ AC_USE_SYSTEM_EXTENSIONS
 AC_SYS_LARGEFILE
 AC_PREFIX_DEFAULT([/usr])
 AM_MAINTAINER_MODE([enable])
-AM_INIT_AUTOMAKE([foreign 1.11 -Wall -Wno-portability silent-rules tar-pax no-dist-gzip dist-xz subdir-objects check-news])
+AM_INIT_AUTOMAKE([foreign 1.11 -Wall -Wno-portability silent-rules tar-pax no-dist-gzip dist-xz subdir-objects])
 AM_SILENT_RULES([yes])
 AC_CANONICAL_HOST
 AC_DEFINE_UNQUOTED([CANONICAL_HOST], "$host", [Canonical host string.])
@@ -49,7 +49,29 @@ AS_IF([test "x$enable_static" = "xyes"], [AC_MSG_ERROR([--enable-static is not s
 AS_IF([test "x$enable_largefile" = "xno"], [AC_MSG_ERROR([--disable-largefile is not supported by systemd])])
 
 # i18n stuff for the PolicyKit policy files
+
+# Check whether intltool can be found, disable NLS otherwise
+AC_CHECK_PROG(intltool_found, [intltool-merge], [yes], [no])
+AS_IF([test x"$intltool_found" != xyes],
+      [AS_IF([test x"$enable_nls" = xyes],
+             [AC_MSG_ERROR([--enable-nls requested but intltool not found])],
+             [AS_IF([test x"$enable_nls" != xno],
+                    [AC_MSG_WARN([*** Disabling NLS support because intltool was not found])
+                     enable_nls=no])
+             ])
+      ])
+
+AM_NLS
+AS_IF([test x"$enable_nls" != xno -o "x$enable_polkit" != xno], [
+    # intltoolize greps for '^(AC|IT)_PROG_INTLTOOL', so it needs to be on its own line
 IT_PROG_INTLTOOL([0.40.0])
+])
+
+AS_IF([test -z "$INTLTOOL_POLICY_RULE"], [
+    # If intltool is not available, provide a dummy rule to fail generation of %.policy files with a meaningful error message
+    INTLTOOL_POLICY_RULE='%.policy: %.policy.in ; @echo "  ITMRG   " $@ && echo "*** intltool support required to build target $@" && false'
+    AC_SUBST(INTLTOOL_POLICY_RULE)
+])
 
 GETTEXT_PACKAGE=systemd
 AC_SUBST(GETTEXT_PACKAGE)
@@ -65,16 +87,18 @@ AC_PROG_CC_C99
 AC_PATH_PROG([M4], [m4])
 AC_PATH_PROG([XSLTPROC], [xsltproc])
 
-AC_PATH_PROG([QUOTAON], [quotaon], [/usr/sbin/quotaon])
-AC_PATH_PROG([QUOTACHECK], [quotacheck], [/usr/sbin/quotacheck])
+AC_PATH_PROG([QUOTAON], [quotaon], [/usr/sbin/quotaon], [$PATH:/usr/sbin:/sbin])
+AC_PATH_PROG([QUOTACHECK], [quotacheck], [/usr/sbin/quotacheck], [$PATH:/usr/sbin:/sbin])
 
-AC_PATH_PROG([SETCAP], [setcap], [/usr/sbin/setcap])
+AC_PATH_PROG([KILL], [kill], [/usr/bin/kill], [$PATH:/usr/sbin:/sbin])
 
-AC_PATH_PROG([KILL], [kill], [/usr/bin/kill])
+AC_PATH_PROG([KMOD], [kmod], [/usr/bin/kmod], [$PATH:/usr/sbin:/sbin])
 
-AC_PATH_PROG([KMOD], [kmod], [/usr/bin/kmod])
+AC_PATH_PROG([KEXEC], [kexec], [/usr/sbin/kexec], [$PATH:/usr/sbin:/sbin])
 
-AC_PATH_PROG([KEXEC], [kexec], [/usr/sbin/kexec])
+AS_IF([test x"$enable_tizen_wip" == xno], [
+AS_IF([! ln --relative --help > /dev/null 2>&1], [AC_MSG_ERROR([*** ln doesn't support --relative ***])])
+])
 
 M4_DEFINES=
 
@@ -101,6 +125,33 @@ if test -z "$GPERF" ; then
 fi
 
 # ------------------------------------------------------------------------------
+# TIZEN config
+config_tizen=no
+AC_ARG_ENABLE(tizen, AS_HELP_STRING([--enable-tizen], [enable tizen configs]))
+AS_IF([test "x$enable_tizen" != xno], [config_tizen=yes])
+      AS_IF([test "x$config_tizen" = "xyes"],
+            [CC_CHECK_FLAGS_APPEND([with_cflags], [CFLAGS], [-DCONFIG_TIZEN])],
+            [AC_MSG_RESULT([skipping -DCONFIG_TIZEN, tizen config not enabled])])
+AM_CONDITIONAL(CONFIG_TIZEN, [test "x$config_tizen" = "xyes"])
+
+config_tizen_wip=no
+AC_ARG_ENABLE(tizen-wip, AS_HELP_STRING([--enable-tizen-wip], [enable tizen wip configs]))
+AS_IF([test "x$enable_tizen_wip" != xno], [config_tizen_wip=yes])
+      AS_IF([test "x$config_tizen_wip" = "xyes"],
+            [CC_CHECK_FLAGS_APPEND([with_cflags], [CFLAGS], [-DCONFIG_TIZEN_WIP])],
+            [AC_MSG_RESULT([skipping -DCONFIG_TIZEN_WIP, tizen wip config not enabled])])
+AM_CONDITIONAL(CONFIG_TIZEN_WIP, [test "x$config_tizen_wip" = "xyes"])
+
+# ------------------------------------------------------------------------------
+AC_ARG_WITH([run-gid],
+        [AS_HELP_STRING([--with-run-gid=GID],
+                [Specify the numeric GID of the accessing group of /run])],
+        [RUN_GID="$withval"],
+        [RUN_GID="0"])
+AC_DEFINE_UNQUOTED(RUN_GID, [$RUN_GID], [GID of the accessing group of /run])
+AC_SUBST(RUN_GID)
+
+# ------------------------------------------------------------------------------
 address_sanitizer_cflags=
 address_sanitizer_cppflags=
 address_sanitizer_ldflags=
@@ -114,6 +165,23 @@ AS_IF([test "x$enable_address_sanitizer" = "xyes"], [
             address_sanitizer_ldflags="-Wc,-fsanitize=address"
       ])
 
+undefined_sanitizer_cflags=
+undefined_sanitizer_cppflags=
+undefined_sanitizer_ldflags=
+AC_ARG_ENABLE(undefined-sanitizer, AS_HELP_STRING([--enable-undefined-sanitizer], [enable -fsanitize=undefined]))
+AS_IF([test "x$enable_undefined_sanitizer" = "xyes"], [
+            CC_CHECK_FLAG_APPEND([with_us_cflags], [CFLAGS], [-fsanitize=undefined])
+            AS_IF([test -z "$with_us_cflags"],
+                  [AC_MSG_ERROR([*** -fsanitize=undefined is not supported])])
+            undefined_sanitizer_cflags="$with_us_cflags -fno-omit-frame-pointer -DVALGRIND=1"
+            undefined_sanitizer_cppflags="-DVALGRIND=1"
+            undefined_sanitizer_ldflags="-Wc,-fsanitize=undefined"
+      ])
+
+sanitizer_cflags="$address_sanitizer_cflags $undefined_sanitizer_cflags"
+sanitizer_cppflags="$address_sanitizer_cppflags $undefined_sanitizer_cppflags"
+sanitizer_ldflags="$address_sanitizer_ldflags $undefined_sanitizer_ldflags"
+
 CC_CHECK_FLAGS_APPEND([with_cflags], [CFLAGS], [\
         -pipe \
         -Wall \
@@ -144,6 +212,7 @@ CC_CHECK_FLAGS_APPEND([with_cflags], [CFLAGS], [\
         -Wno-unused-parameter \
         -Wno-missing-field-initializers \
         -Wno-unused-result \
+        -Wno-typedef-redefinition \
         -Werror=overflow \
         -Wdate-time \
         -Wnested-externs \
@@ -156,18 +225,20 @@ CC_CHECK_FLAGS_APPEND([with_cflags], [CFLAGS], [\
         -ffunction-sections \
         -fdata-sections \
         -fstack-protector \
+        -fstack-protector-strong \
+        -fPIE \
         --param=ssp-buffer-size=4])
 AS_CASE([$CFLAGS], [*-O[[12345\ ]]*],
         [CC_CHECK_FLAGS_APPEND([with_cflags], [CFLAGS], [\
-               -flto])],
+               -flto -ffat-lto-objects])],
         [AC_MSG_RESULT([skipping -flto, optimization not enabled])])
-AC_SUBST([OUR_CFLAGS], "$with_cflags $address_sanitizer_cflags")
+AC_SUBST([OUR_CFLAGS], "$with_cflags $sanitizer_cflags")
 
 AS_CASE([$CFLAGS], [*-O[[12345\ ]]*],
         [CC_CHECK_FLAGS_APPEND([with_cppflags], [CPPFLAGS], [\
                -Wp,-D_FORTIFY_SOURCE=2])],
         [AC_MSG_RESULT([skipping -D_FORTIFY_SOURCE, optimization not enabled])])
-AC_SUBST([OUR_CPPFLAGS], "$with_cppflags $address_sanitizer_cppflags")
+AC_SUBST([OUR_CPPFLAGS], "$with_cppflags $sanitizer_cppflags")
 
 CC_CHECK_FLAGS_APPEND([with_ldflags], [LDFLAGS], [\
         -Wl,--as-needed \
@@ -175,11 +246,19 @@ CC_CHECK_FLAGS_APPEND([with_ldflags], [LDFLAGS], [\
         -Wl,--gc-sections \
         -Wl,-z,relro \
         -Wl,-z,now \
+        -pie \
         -Wl,-fuse-ld=gold])
-AC_SUBST([OUR_LDFLAGS], "$with_ldflags $address_sanitizer_ldflags")
+AC_SUBST([OUR_LDFLAGS], "$with_ldflags $sanitizer_ldflags")
 
 AC_CHECK_SIZEOF(pid_t)
 AC_CHECK_SIZEOF(uid_t)
+AC_CHECK_SIZEOF(gid_t)
+AC_CHECK_SIZEOF(time_t)
+AC_CHECK_SIZEOF(dev_t)
+AC_CHECK_SIZEOF(rlim_t,,[
+       #include <sys/time.h>
+       #include <sys/resource.h>
+])
 
 # ------------------------------------------------------------------------------
 # we use python to build the man page index, and for systemd-python
@@ -190,9 +269,21 @@ AC_ARG_WITH([python],
 have_lxml=no
 AS_IF([test "x$with_python" != "xno"], [
         AM_PATH_PYTHON(,, [:])
-        AS_IF(["$PYTHON" -c 'import lxml' 2>/dev/null], [have_lxml=yes], [have_lxml=no])
-        AS_IF([test "$PYTHON" != : -a $have_lxml = yes], [have_python=yes])
+        AS_IF([test "x$PYTHON" != "x:"], [
+                AC_MSG_CHECKING([for python lxml module])
+                AS_IF(["$PYTHON" -c 'import lxml' 2>/dev/null], [have_lxml=yes])
+                AC_MSG_RESULT([$have_lxml])
+                AS_IF([test "x$have_lxml" = "xyes"], [have_python=yes],
+                      [AC_MSG_WARN([*** python support requires python-lxml module installed])])
+        ])
 ])
+AS_IF([test "$have_python" != "yes"], [
+      AS_IF([test "$with_python" = "yes"],
+            [AC_MSG_ERROR([*** python support requested but python support not found])])
+      AS_IF([test "$with_python" != "no"],
+            [AC_MSG_WARN([*** python support not found, some documentation cannot be built])])
+])
+
 AM_CONDITIONAL([HAVE_PYTHON], [test "x$have_python" = "xyes"])
 AS_IF([test "x$PYTHON_BINARY" = "x"],
       [AS_IF([test "x$have_python" = "xyes"],
@@ -240,11 +331,35 @@ LIBS="$save_LIBS"
 
 AC_CHECK_FUNCS([fanotify_init fanotify_mark])
 AC_CHECK_FUNCS([__secure_getenv secure_getenv])
-AC_CHECK_DECLS([gettid, pivot_root, name_to_handle_at, setns], [], [], [[#include <sys/types.h>
+AC_CHECK_DECLS([gettid, pivot_root, name_to_handle_at, setns, LO_FLAGS_PARTSCAN],
+               [], [], [[
+#include <sys/types.h>
 #include <unistd.h>
 #include <sys/mount.h>
 #include <fcntl.h>
-#include <sched.h>]])
+#include <sched.h>
+#include <linux/loop.h>
+]])
+
+AC_CHECK_DECLS([IFLA_MACVLAN_FLAGS,
+                IFLA_VTI_REMOTE,
+                IFLA_PHYS_PORT_ID,
+                IFLA_BOND_AD_INFO,
+                IFLA_VLAN_PROTOCOL,
+                IFLA_VXLAN_LOCAL6,
+                IFLA_IPTUN_6RD_RELAY_PREFIXLEN,
+                IFLA_BRIDGE_VLAN_INFO],
+[], [], [[
+#include <inttypes.h>
+#include <netinet/in.h>
+#include <netinet/ether.h>
+#include <linux/rtnetlink.h>
+#include <net/if.h>
+#include <linux/ip.h>
+#include <linux/if_tunnel.h>
+#include <linux/if_link.h>
+#include <linux/if_bridge.h>
+]])
 
 # This makes sure pkg.m4 is available.
 m4_pattern_forbid([^_?PKG_[A-Z_]+$],[*** pkg.m4 missing, please install pkg-config])
@@ -416,43 +531,37 @@ AC_ARG_WITH([debug-tty],
 
 AC_SUBST(DEBUGTTY)
 
+AC_ARG_WITH([certificate-root],
+        AS_HELP_STRING([--with-certificate-root=PATH],
+                [Specify the prefix for TLS certificates [/etc/ssl]]),
+        [CERTIFICATEROOT="$withval"],
+        [CERTIFICATEROOT="/etc/ssl"])
+
+AC_SUBST(CERTIFICATEROOT)
+
 # ------------------------------------------------------------------------------
 have_xz=no
 AC_ARG_ENABLE(xz, AS_HELP_STRING([--disable-xz], [Disable optional XZ support]))
 if test "x$enable_xz" != "xno"; then
         PKG_CHECK_MODULES(XZ, [ liblzma ],
-                [AC_DEFINE(HAVE_XZ, 1, [Define if XZ is available]) have_xz=yes], have_xz=no)
+                [AC_DEFINE(HAVE_XZ, 1, [Define if XZ is available]) have_xz=yes])
         if test "x$have_xz" = xno -a "x$enable_xz" = xyes; then
-                AC_MSG_ERROR([*** Xz support requested but libraries not found])
+                AC_MSG_ERROR([*** XZ support requested but libraries not found])
         fi
 fi
 AM_CONDITIONAL(HAVE_XZ, [test "$have_xz" = "yes"])
 
 # ------------------------------------------------------------------------------
-AC_ARG_ENABLE([tcpwrap],
-        AS_HELP_STRING([--disable-tcpwrap],[Disable optional TCP wrappers support]),
-                [case "${enableval}" in
-                        yes) have_tcpwrap=yes ;;
-                        no) have_tcpwrap=no ;;
-                        *) AC_MSG_ERROR(bad value ${enableval} for --disable-tcpwrap) ;;
-                esac],
-                [have_tcpwrap=auto])
+have_lz4=no
+AC_ARG_ENABLE(lz4, AS_HELP_STRING([--enable-lz4], [Enable optional LZ4 support]))
+AS_IF([test "x$enable_lz4" == "xyes"], [
+        AC_CHECK_HEADERS(lz4.h,
+               [AC_DEFINE(HAVE_LZ4, 1, [Define in LZ4 is available]) have_lz4=yes],
+               [AC_MSG_ERROR([*** LZ4 support requested but headers not found])])
+])
+AM_CONDITIONAL(HAVE_LZ4, [test "$have_lz4" = "yes"])
 
-if test "x${have_tcpwrap}" != xno ; then
-        ACX_LIBWRAP
-        if test "x${LIBWRAP_LIBS}" = x ; then
-                if test "x$have_tcpwrap" = xyes ; then
-                        AC_MSG_ERROR([*** TCP wrappers support not found.])
-                fi
-                have_tcpwrap=no
-        else
-                M4_DEFINES="$M4_DEFINES -DHAVE_LIBWRAP"
-                have_tcpwrap=yes
-        fi
-else
-        LIBWRAP_LIBS=
-fi
-AC_SUBST(LIBWRAP_LIBS)
+AM_CONDITIONAL(HAVE_COMPRESSION, [test "$have_xz" = "yes" -o "$have_lz4" = "yes"])
 
 # ------------------------------------------------------------------------------
 AC_ARG_ENABLE([pam],
@@ -532,44 +641,6 @@ AC_SUBST(ACL_LIBS)
 AM_CONDITIONAL([HAVE_ACL], [test "x$have_acl" != xno])
 
 # ------------------------------------------------------------------------------
-AC_ARG_ENABLE([xattr],
-        AS_HELP_STRING([--disable-xattr],[Disable optional XATTR support]),
-                [case "${enableval}" in
-                        yes) have_xattr=yes ;;
-                        no) have_xattr=no ;;
-                        *) AC_MSG_ERROR(bad value ${enableval} for --disable-xattr) ;;
-                esac],
-                [have_xattr=auto])
-
-if test "x${have_xattr}" != xno ; then
-        AC_CHECK_HEADERS(
-                [attr/xattr.h],
-                [have_xattr=yes],
-                [if test "x$have_xattr" = xyes ; then
-                        AC_MSG_ERROR([*** XATTR headers not found.])
-                fi])
-
-        AC_CHECK_LIB(
-                [attr],
-                [fsetxattr],
-                [have_xattr=yes],
-                [if test "x$have_xattr" = xyes ; then
-                        AC_MSG_ERROR([*** libattr not found.])
-                fi])
-
-        if test "x$have_xattr" = xyes ; then
-                XATTR_LIBS="-lattr"
-                AC_DEFINE(HAVE_XATTR, 1, [XATTR available])
-        else
-                have_xattr=no
-        fi
-else
-        XATTR_LIBS=
-fi
-AC_SUBST(XATTR_LIBS)
-AM_CONDITIONAL([HAVE_XATTR], [test "x$have_xattr" != xno])
-
-# ------------------------------------------------------------------------------
 AC_ARG_ENABLE([smack], AS_HELP_STRING([--disable-smack],[Disable optional SMACK support]),
                 [case "${enableval}" in
                         yes) have_smack=yes ;;
@@ -578,29 +649,41 @@ AC_ARG_ENABLE([smack], AS_HELP_STRING([--disable-smack],[Disable optional SMACK
                 esac],
                 [have_smack=auto])
 
-if test "x${have_xattr}" = xno; then
-        if test "x${have_smack}" = xyes; then
-                AC_MSG_ERROR(SMACK requires xattr support)
-        else
-                have_smack=no
-        fi
-else
-        if test "x${have_smack}" = xauto; then
-                M4_DEFINES="$M4_DEFINES -DHAVE_SMACK"
-                have_smack=yes
-        fi
+if test "x${have_smack}" = xauto; then
+        M4_DEFINES="$M4_DEFINES -DHAVE_SMACK"
+        have_smack=yes
 fi
 
 AC_ARG_WITH(smack-run-label,
 AS_HELP_STRING([--with-smack-run-label=STRING],
-        [run systemd --system with a specific SMACK label]),
-        [AC_DEFINE_UNQUOTED(SMACK_RUN_LABEL, ["$withval"], [Run with a smack label])],
+        [run systemd --system itself with a specific SMACK label]),
+        [AC_DEFINE_UNQUOTED(SMACK_RUN_LABEL, ["$withval"], [Run systemd itself with SMACK label])],
+        [])
+
+AC_ARG_WITH(smack-default-process-label,
+AS_HELP_STRING([--with-smack-default-process-label=STRING],
+        [default SMACK label for executed processes]),
+        [AC_DEFINE_UNQUOTED(SMACK_DEFAULT_PROCESS_LABEL, ["$withval"], [Default SMACK label for executed processes])],
         [])
 
 if test "x${have_smack}" = xyes ; then
         AC_DEFINE(HAVE_SMACK, 1, [Define if SMACK is available])
 fi
 
+AC_ARG_ENABLE([mobile],
+        AS_HELP_STRING([--with-process-label],
+                       [add process label]),
+                [case "${enableval}" in
+                        yes) with_process_label=yes ;;
+                        no) with_process_label=no ;;
+                        *) AC_MSG_ERROR(bad value ${enableval} for --enable-mobile) ;;
+                esac],
+                enable_mobile=no)
+if test "x${with_process_label}" = xyes ; then
+        M4_DEFINES="$M4_DEFINES -DDEFAULT_PROCESS_LABEL"
+fi
+
+
 # ------------------------------------------------------------------------------
 AC_ARG_ENABLE([gcrypt],
         AS_HELP_STRING([--disable-gcrypt],[Disable optional GCRYPT support]),
@@ -672,6 +755,52 @@ fi
 AC_SUBST(AUDIT_LIBS)
 
 # ------------------------------------------------------------------------------
+AC_ARG_ENABLE([elfutils],
+        AS_HELP_STRING([--disable-elfutils],[Disable optional ELFUTILS support]),
+                [case "${enableval}" in
+                        yes) have_elfutils=yes ;;
+                        no) have_elfutils=no ;;
+                        *) AC_MSG_ERROR(bad value ${enableval} for --disable-elfutils) ;;
+                esac],
+                [have_elfutils=auto])
+
+if test "x${have_elfutils}" != xno ; then
+        AC_CHECK_HEADERS(
+                [elfutils/libdwfl.h],
+                [],
+                [if test "x$have_elfutils" = xyes ; then
+                        AC_MSG_ERROR([*** ELFUTILS headers not found.])
+                fi])
+
+        AC_CHECK_LIB(
+                [dw],
+                [dwfl_begin],
+                [],
+                [if test "x$have_elfutils" = xyes ; then
+                        AC_MSG_ERROR([*** ELFUTILS libs not found.])
+                fi])
+
+        AC_CHECK_LIB(
+                [dw],
+                [dwfl_core_file_attach],
+                [have_elfutils=yes],
+                [if test "x$have_elfutils" = xyes ; then
+                        AC_MSG_ERROR([*** ELFUTILS >= 158 is required.])
+                fi])
+
+        if test "x$have_elfutils" = xyes ; then
+                ELFUTILS_LIBS="-lelf -ldw"
+                AC_DEFINE(HAVE_ELFUTILS, 1, [ELFUTILS available])
+        else
+                have_elfutils=no
+        fi
+else
+        ELFUTILS_LIBS=
+fi
+AC_SUBST(ELFUTILS_LIBS)
+AM_CONDITIONAL(HAVE_ELFUTILS, [test "$have_elfutils" = "yes"])
+
+# ------------------------------------------------------------------------------
 have_libcryptsetup=no
 AC_ARG_ENABLE(libcryptsetup, AS_HELP_STRING([--disable-libcryptsetup], [disable libcryptsetup tools]))
 if test "x$enable_libcryptsetup" != "xno"; then
@@ -699,7 +828,7 @@ AM_CONDITIONAL(HAVE_QRENCODE, [test "$have_qrencode" = "yes"])
 have_microhttpd=no
 AC_ARG_ENABLE(microhttpd, AS_HELP_STRING([--disable-microhttpd], [disable microhttpd support]))
 if test "x$enable_microhttpd" != "xno"; then
-        PKG_CHECK_MODULES(MICROHTTPD, [libmicrohttpd >= 0.9.5],
+        PKG_CHECK_MODULES(MICROHTTPD, [libmicrohttpd >= 0.9.33],
                 [AC_DEFINE(HAVE_MICROHTTPD, 1, [Define if microhttpd is available]) have_microhttpd=yes], have_microhttpd=no)
         if test "x$have_microhttpd" = xno -a "x$enable_microhttpd" = xyes; then
                 AC_MSG_ERROR([*** microhttpd support requested but libraries not found])
@@ -708,6 +837,45 @@ fi
 AM_CONDITIONAL(HAVE_MICROHTTPD, [test "$have_microhttpd" = "yes"])
 
 # ------------------------------------------------------------------------------
+have_gnutls=no
+AC_ARG_ENABLE(gnutls, AS_HELP_STRING([--disable-gnutls], [disable gnutls support]))
+if test "x$enable_gnutls" != "xno"; then
+        PKG_CHECK_MODULES(GNUTLS, [gnutls >= 3.1.4],
+                [AC_DEFINE(HAVE_GNUTLS, 1, [Define if gnutls is available]) have_gnutls=yes], have_gnutls=no)
+        if test "x$have_gnutls" = xno -a "x$enable_gnutls" = xyes; then
+                AC_MSG_ERROR([*** gnutls support requested but libraries not found])
+        fi
+fi
+AM_CONDITIONAL(HAVE_GNUTLS, [test "$have_gnutls" = "yes"])
+
+# ------------------------------------------------------------------------------
+have_libcurl=no
+AC_ARG_ENABLE(libcurl, AS_HELP_STRING([--disable-libcurl], [disable libcurl support]))
+if test "x$enable_libcurl" != "xno"; then
+        PKG_CHECK_MODULES(LIBCURL, [libcurl],
+                [AC_DEFINE(HAVE_LIBCURL, 1, [Define if libcurl is available]) have_libcurl=yes], have_libcurl=no)
+        if test "x$have_libcurl" = xno -a "x$enable_libcurl" = xyes; then
+                AC_MSG_ERROR([*** libcurl support requested but libraries not found])
+        fi
+fi
+AM_CONDITIONAL(HAVE_LIBCURL, [test "$have_libcurl" = "yes"])
+
+# ------------------------------------------------------------------------------
+have_libidn=no
+AC_ARG_ENABLE(libidn, AS_HELP_STRING([--disable-libidn], [Disable optional LIBIDN support]))
+if test "x$enable_libidn" != "xno"; then
+        PKG_CHECK_MODULES(LIBIDN, [libidn],
+               [AC_DEFINE(HAVE_LIBIDN, 1, [Define if libidn is available])
+                have_libidn=yes
+                M4_DEFINES="$M4_DEFINES -DHAVE_LIBIDN"],
+               [have_libidn=no])
+        if test "x$have_libidn" = "xno" -a "x$enable_libidn" = "xyes"; then
+                AC_MSG_ERROR([*** libidn support requested but libraries not found])
+        fi
+fi
+AM_CONDITIONAL(HAVE_LIBIDN, [test "$have_libidn" = "yes"])
+
+# ------------------------------------------------------------------------------
 have_binfmt=no
 AC_ARG_ENABLE(binfmt, AS_HELP_STRING([--disable-binfmt], [disable binfmt tool]))
 if test "x$enable_binfmt" != "xno"; then
@@ -756,6 +924,22 @@ fi
 AM_CONDITIONAL(ENABLE_TMPFILES, [test "$have_tmpfiles" = "yes"])
 
 # ------------------------------------------------------------------------------
+have_sysusers=no
+AC_ARG_ENABLE(sysusers, AS_HELP_STRING([--disable-sysusers], [disable sysusers support]))
+if test "x$enable_sysusers" != "xno"; then
+        have_sysusers=yes
+fi
+AM_CONDITIONAL(ENABLE_SYSUSERS, [test "$have_sysusers" = "yes"])
+
+# ------------------------------------------------------------------------------
+have_firstboot=no
+AC_ARG_ENABLE(firstboot, AS_HELP_STRING([--disable-firstboot], [disable firstboot support]))
+if test "x$enable_firstboot" != "xno"; then
+        have_firstboot=yes
+fi
+AM_CONDITIONAL(ENABLE_FIRSTBOOT, [test "$have_firstboot" = "yes"])
+
+# ------------------------------------------------------------------------------
 have_randomseed=no
 AC_ARG_ENABLE(randomseed, AS_HELP_STRING([--disable-randomseed], [disable randomseed tools]))
 if test "x$enable_randomseed" != "xno"; then
@@ -814,6 +998,51 @@ fi
 AM_CONDITIONAL(ENABLE_TIMEDATED, [test "$have_timedated" = "yes"])
 
 # ------------------------------------------------------------------------------
+have_timesyncd=no
+AC_ARG_ENABLE(timesyncd, AS_HELP_STRING([--disable-timesyncd], [disable timesync daemon]))
+if test "x$enable_timesyncd" != "xno"; then
+        have_timesyncd=yes
+fi
+AM_CONDITIONAL(ENABLE_TIMESYNCD, [test "$have_timesyncd" = "yes"])
+
+AC_ARG_WITH(ntp-servers,
+        AS_HELP_STRING([--with-ntp-servers=NTPSERVERS],
+                [Space-separated list of default NTP servers]),
+        [NTP_SERVERS="$withval"],
+        [NTP_SERVERS="time1.google.com time2.google.com time3.google.com time4.google.com"])
+
+AC_DEFINE_UNQUOTED(NTP_SERVERS, ["$NTP_SERVERS"], [Default NTP Servers])
+AC_SUBST(NTP_SERVERS)
+
+AC_ARG_WITH(time-epoch,
+        AS_HELP_STRING([--with-time-epoch=SECONDS],
+                [Time epoch for time clients]),
+        [TIME_EPOCH="$withval"],
+        [TIME_EPOCH="`stat -c %Y ${srcdir}/NEWS 2>/dev/null || echo 0`"])
+
+AC_DEFINE_UNQUOTED(TIME_EPOCH, [$TIME_EPOCH], [Time Epoch])
+
+# ------------------------------------------------------------------------------
+AC_ARG_WITH(system-uid-max,
+        AS_HELP_STRING([--with-system-uid-max=UID]
+                [Maximum UID for system users]),
+        [SYSTEM_UID_MAX="$withval"],
+        [SYSTEM_UID_MAX="`awk 'BEGIN { uid=999 } /^\s*SYS_UID_MAX\s+/ { uid=$2 } END { print uid }' /etc/login.defs 2>/dev/null || echo 999`"])
+
+AC_DEFINE_UNQUOTED(SYSTEM_UID_MAX, [$SYSTEM_UID_MAX], [Maximum System UID])
+AC_SUBST(SYSTEM_UID_MAX)
+
+# ------------------------------------------------------------------------------
+AC_ARG_WITH(system-gid-max,
+        AS_HELP_STRING([--with-system-gid-max=GID]
+                [Maximum GID for system groups]),
+        [SYSTEM_GID_MAX="$withval"],
+        [SYSTEM_GID_MAX="`awk 'BEGIN { gid=999 } /^\s*SYS_GID_MAX\s+/ { gid=$2 } END { print gid }' /etc/login.defs 2>/dev/null || echo 999`"])
+
+AC_DEFINE_UNQUOTED(SYSTEM_GID_MAX, [$SYSTEM_GID_MAX], [Maximum System GID])
+AC_SUBST(SYSTEM_GID_MAX)
+
+# ------------------------------------------------------------------------------
 have_localed=no
 AC_ARG_ENABLE(localed, AS_HELP_STRING([--disable-localed], [disable locale daemon]))
 if test "x$enable_localed" != "xno"; then
@@ -839,11 +1068,29 @@ fi
 AM_CONDITIONAL(ENABLE_POLKIT, [test "x$have_polkit" = "xyes"])
 
 # ------------------------------------------------------------------------------
+have_resolved=no
+AC_ARG_ENABLE(resolved, AS_HELP_STRING([--disable-resolved], [disable resolve daemon]))
+if test "x$enable_resolved" != "xno"; then
+        have_resolved=yes
+fi
+AM_CONDITIONAL(ENABLE_RESOLVED, [test "$have_resolved" = "yes"])
+
+AC_ARG_WITH(dns-servers,
+        AS_HELP_STRING([--with-dns-servers=DNSSERVERS],
+                [Space-separated list of default DNS servers]),
+        [DNS_SERVERS="$withval"],
+        [DNS_SERVERS="8.8.8.8 8.8.4.4 2001:4860:4860::8888 2001:4860:4860::8844"])
+
+AC_DEFINE_UNQUOTED(DNS_SERVERS, ["$DNS_SERVERS"], [Default DNS Servers])
+AC_SUBST(DNS_SERVERS)
+
+# ------------------------------------------------------------------------------
+have_networkd=no
 AC_ARG_ENABLE(networkd, AS_HELP_STRING([--disable-networkd], [disable networkd]))
-if test "x$enable_networkd" != "xno"; then
+AS_IF([test "x$enable_networkd" != "xno"], [
         AC_DEFINE(ENABLE_NETWORKD, 1, [Define if networkd support is to be enabled])
         have_networkd=yes
-fi
+])
 AM_CONDITIONAL(ENABLE_NETWORKD, [test "x$have_networkd" = "xyes"])
 
 # ------------------------------------------------------------------------------
@@ -864,6 +1111,15 @@ fi
 AM_CONDITIONAL(ENABLE_MULTI_SEAT_X, [test "$have_multi_seat_x" = "yes"])
 
 # ------------------------------------------------------------------------------
+have_terminal=no
+AC_ARG_ENABLE(terminal, AS_HELP_STRING([--enable-terminal], [enable terminal support]))
+if test "x$enable_terminal" = "xyes"; then
+        AC_DEFINE(ENABLE_TERMINAL, 1, [Define if terminal support is to be enabled])
+        have_terminal=yes
+fi
+AM_CONDITIONAL(ENABLE_TERMINAL, [test "x$have_terminal" = "xyes"])
+
+# ------------------------------------------------------------------------------
 have_kdbus=no
 AC_ARG_ENABLE(kdbus, AS_HELP_STRING([--enable-kdbus], [do connect to kdbus by default]))
 if test "x$enable_kdbus" = "xyes"; then
@@ -976,7 +1232,12 @@ AS_IF([test "x$enable_manpages" != xno], [have_manpages=yes])
 AM_CONDITIONAL(ENABLE_MANPAGES, [test "x$have_manpages" = "xyes"])
 
 # ------------------------------------------------------------------------------
+AC_ARG_ENABLE(ldconfig,
+       [AC_HELP_STRING([--disable-ldconfig], [disable ldconfig])],
+       enable_ldconfig=$enableval, enable_ldconfig=yes)
+AM_CONDITIONAL(ENABLE_LDCONFIG, [test x$enable_ldconfig = xyes])
 
+# ------------------------------------------------------------------------------
 # Location of the init scripts as mandated by LSB
 SYSTEM_SYSVINIT_PATH=/etc/init.d
 SYSTEM_SYSVRCND_PATH=/etc/rc.d
@@ -1012,8 +1273,11 @@ AM_CONDITIONAL(HAVE_SYSV_COMPAT, test "$SYSTEM_SYSV_COMPAT" = "yes")
 AC_ARG_WITH([tty-gid],
         [AS_HELP_STRING([--with-tty-gid=GID],
                 [Specify the numeric GID of the 'tty' group])],
-        [AC_DEFINE_UNQUOTED(TTY_GID, [$withval], [GID of the 'tty' group])],
-        [])
+        [TTY_GID="$withval"],
+        [TTY_GID="5"])
+
+AC_DEFINE_UNQUOTED(TTY_GID, [$TTY_GID], [GID of the 'tty' group])
+AC_SUBST(TTY_GID)
 
 AC_ARG_WITH([dbuspolicydir],
         AS_HELP_STRING([--with-dbuspolicydir=DIR], [D-Bus policy directory]),
@@ -1115,8 +1379,11 @@ AC_OUTPUT
 AC_MSG_RESULT([
         $PACKAGE_NAME $VERSION
 
+        CONFIG_TIZEN:            ${config_tizen}
+        CONFIG_TIZEN_WIP:        ${config_tizen_wip}
+        RUN GID:                 ${RUN_GID}
+
         libcryptsetup:           ${have_libcryptsetup}
-        tcpwrap:                 ${have_tcpwrap}
         PAM:                     ${have_pam}
         AUDIT:                   ${have_audit}
         IMA:                     ${have_ima}
@@ -1125,18 +1392,24 @@ AC_MSG_RESULT([
         SECCOMP:                 ${have_seccomp}
         SMACK:                   ${have_smack}
         XZ:                      ${have_xz}
+        LZ4:                     ${have_lz4}
         ACL:                     ${have_acl}
-        XATTR:                   ${have_xattr}
         GCRYPT:                  ${have_gcrypt}
         QRENCODE:                ${have_qrencode}
         MICROHTTPD:              ${have_microhttpd}
         CHKCONFIG:               ${have_chkconfig}
+        GNUTLS:                  ${have_gnutls}
+        libcurl:                 ${have_libcurl}
+        libidn:                  ${have_libidn}
+        ELFUTILS:                ${have_elfutils}
         binfmt:                  ${have_binfmt}
         vconsole:                ${have_vconsole}
         readahead:               ${have_readahead}
         bootchart:               ${have_bootchart}
         quotacheck:              ${have_quotacheck}
         tmpfiles:                ${have_tmpfiles}
+        sysusers:                ${have_sysusers}
+        firstboot:               ${have_firstboot}
         randomseed:              ${have_randomseed}
         backlight:               ${have_backlight}
         rfkill:                  ${have_rfkill}
@@ -1144,8 +1417,13 @@ AC_MSG_RESULT([
         machined:                ${have_machined}
         hostnamed:               ${have_hostnamed}
         timedated:               ${have_timedated}
+        timesyncd:               ${have_timesyncd}
+        default NTP servers:     ${NTP_SERVERS}
+        time epoch:              ${TIME_EPOCH}
         localed:                 ${have_localed}
         networkd:                ${have_networkd}
+        resolved:                ${have_resolved}
+        default DNS servers:     ${DNS_SERVERS}
         coredump:                ${have_coredump}
         polkit:                  ${have_polkit}
         efi:                     ${have_efi}
@@ -1156,6 +1434,7 @@ AC_MSG_RESULT([
         gudev:                   ${enable_gudev}
         gintrospection:          ${enable_introspection}
         multi-seat-x:            ${have_multi_seat_x}
+        terminal:                ${have_terminal}
         kdbus:                   ${have_kdbus}
         Python:                  ${have_python}
         Python Headers:          ${have_python_devel}
@@ -1191,6 +1470,10 @@ AC_MSG_RESULT([
         Extra start script:      ${RC_LOCAL_SCRIPT_PATH_START}
         Extra stop script:       ${RC_LOCAL_SCRIPT_PATH_STOP}
         Debug shell:             ${SUSHELL} @ ${DEBUGTTY}
+        TTY GID:                 ${TTY_GID}
+        Maximum System UID:      ${SYSTEM_UID_MAX}
+        Maximum System GID:      ${SYSTEM_GID_MAX}
+        Certificate root:        ${CERTIFICATEROOT}
 
         CFLAGS:                  ${OUR_CFLAGS} ${CFLAGS}
         CPPFLAGS:                ${OUR_CPPFLAGS} ${CPPFLAGS}
index c154645..8a31ded 100644 (file)
@@ -116,6 +116,8 @@ udev_queue_get_seqnum_sequence_is_finished
 udev_queue_get_queued_list_entry
 udev_queue_get_kernel_seqnum
 udev_queue_get_udev_seqnum
+udev_queue_get_fd
+udev_queue_flush
 </SECTION>
 
 <SECTION>
diff --git a/factory/etc/nsswitch.conf b/factory/etc/nsswitch.conf
new file mode 100644 (file)
index 0000000..5f2984e
--- /dev/null
@@ -0,0 +1,6 @@
+# This file is part of systemd.
+
+passwd: files
+shadow: files
+group:  files
+hosts:  files mymachines resolve myhostname
diff --git a/factory/etc/pam.d/other b/factory/etc/pam.d/other
new file mode 100644 (file)
index 0000000..c1f7296
--- /dev/null
@@ -0,0 +1,6 @@
+# This file is part of systemd.
+
+auth     include system-auth
+account  include system-auth
+password include system-auth
+session  include system-auth
diff --git a/factory/etc/pam.d/system-auth b/factory/etc/pam.d/system-auth
new file mode 100644 (file)
index 0000000..dec7a8f
--- /dev/null
@@ -0,0 +1,12 @@
+# This file is part of systemd.
+
+auth     sufficient pam_unix.so nullok try_first_pass
+
+account  required   pam_nologin.so
+account  sufficient pam_unix.so
+
+password sufficient pam_unix.so nullok sha512 shadow try_first_pass try_authtok
+
+-session optional   pam_loginuid.so
+-session optional   pam_systemd.so
+session  sufficient pam_unix.so
index a51a00a..e0c5fed 100644 (file)
@@ -6446,7 +6446,7 @@ OUI:0050C2871*
  ID_OUI_FROM_DATABASE=R-S-I Elektrotechnik GmbH & Co. KG
 
 OUI:0050C2872*
- ID_OUI_FROM_DATABASE=Oliotalo - Objecthouse Oy
+ ID_OUI_FROM_DATABASE=Oliotalo Oy
 
 OUI:0050C2873*
  ID_OUI_FROM_DATABASE=XRONET Corporation
@@ -6929,7 +6929,7 @@ OUI:0050C2912*
  ID_OUI_FROM_DATABASE=ASSET InterTech, Inc.
 
 OUI:0050C2913*
- ID_OUI_FROM_DATABASE=Selex Sensors & Airborne Systems
+ ID_OUI_FROM_DATABASE=Selex Ex Ltd
 
 OUI:0050C2914*
  ID_OUI_FROM_DATABASE=IO-Connect
@@ -13558,6 +13558,9 @@ OUI:40D8551CA*
 OUI:40D8551CB*
  ID_OUI_FROM_DATABASE=MG S.r.l.
 
+OUI:40D8551CC*
+ ID_OUI_FROM_DATABASE=NKT Photonics A/S
+
 OUI:40D8551CD*
  ID_OUI_FROM_DATABASE=YXLON International A/S
 
@@ -13630,6 +13633,9 @@ OUI:40D8551E3*
 OUI:40D8551E4*
  ID_OUI_FROM_DATABASE=STEK Ltd
 
+OUI:40D85550D*
+ ID_OUI_FROM_DATABASE=Shenzhen MaiWei Cable TV Equipment CO.,LTD.
+
 OUI:40D855EE6*
  ID_OUI_FROM_DATABASE=Narinet, Inc.
 
@@ -13703,7 +13709,7 @@ OUI:000016*
  ID_OUI_FROM_DATABASE=DU PONT PIXEL SYSTEMS     .
 
 OUI:000017*
- ID_OUI_FROM_DATABASE=TEKELEC
+ ID_OUI_FROM_DATABASE=Oracle
 
 OUI:000018*
  ID_OUI_FROM_DATABASE=WEBSTER COMPUTER CORPORATION
@@ -13934,7 +13940,7 @@ OUI:000063*
  ID_OUI_FROM_DATABASE=BARCO CONTROL ROOMS GMBH
 
 OUI:000064*
- ID_OUI_FROM_DATABASE=YOKOGAWA DIGITAL COMPUTER CORP
+ ID_OUI_FROM_DATABASE=Yokogawa Electric Corporation
 
 OUI:000065*
  ID_OUI_FROM_DATABASE=Network General Corporation
@@ -14921,7 +14927,7 @@ OUI:0001AE*
  ID_OUI_FROM_DATABASE=Trex Enterprises
 
 OUI:0001AF*
- ID_OUI_FROM_DATABASE=Emerson Network Power
+ ID_OUI_FROM_DATABASE=Artesyn Embedded Technologies
 
 OUI:0001B0*
  ID_OUI_FROM_DATABASE=Fulltek Technology Co., Ltd.
@@ -15938,7 +15944,7 @@ OUI:000300*
  ID_OUI_FROM_DATABASE=Barracuda Networks, Inc.
 
 OUI:000301*
- ID_OUI_FROM_DATABASE=Avantas Networks Corporation
+ ID_OUI_FROM_DATABASE=EXFO
 
 OUI:000302*
  ID_OUI_FROM_DATABASE=Charles Industries, Ltd.
@@ -18029,7 +18035,7 @@ OUI:0005BB*
  ID_OUI_FROM_DATABASE=Myspace AB
 
 OUI:0005BC*
- ID_OUI_FROM_DATABASE=Resorsys Ltd.
+ ID_OUI_FROM_DATABASE=Resource Data Management Ltd
 
 OUI:0005BD*
  ID_OUI_FROM_DATABASE=ROAX BV
@@ -18266,7 +18272,7 @@ OUI:00060A*
  ID_OUI_FROM_DATABASE=Blue2space
 
 OUI:00060B*
- ID_OUI_FROM_DATABASE=Emerson Network Power
+ ID_OUI_FROM_DATABASE=Artesyn Embedded Technologies
 
 OUI:00060C*
  ID_OUI_FROM_DATABASE=Melco Industries, Inc.
@@ -18977,7 +18983,7 @@ OUI:0006F7*
  ID_OUI_FROM_DATABASE=ALPS Co,. Ltd.
 
 OUI:0006F8*
- ID_OUI_FROM_DATABASE=CPU Technology, Inc.
+ ID_OUI_FROM_DATABASE=The Boeing Company
 
 OUI:0006F9*
  ID_OUI_FROM_DATABASE=Mitsui Zosen Systems Research Inc.
@@ -19337,7 +19343,7 @@ OUI:00076F*
  ID_OUI_FROM_DATABASE=Synoptics Limited
 
 OUI:000770*
- ID_OUI_FROM_DATABASE=Locusnetworks Corporation
+ ID_OUI_FROM_DATABASE=Ubiquoss Inc
 
 OUI:000771*
  ID_OUI_FROM_DATABASE=Embedded System Corporation
@@ -19616,7 +19622,7 @@ OUI:0007CC*
  ID_OUI_FROM_DATABASE=Kaba Benzing GmbH
 
 OUI:0007CD*
- ID_OUI_FROM_DATABASE=NMTEL Co., Ltd.
+ ID_OUI_FROM_DATABASE=Kumoh Electronic Co, Ltd
 
 OUI:0007CE*
  ID_OUI_FROM_DATABASE=Cabletime Limited
@@ -20435,7 +20441,7 @@ OUI:0008F8*
  ID_OUI_FROM_DATABASE=UTC CCS
 
 OUI:0008F9*
- ID_OUI_FROM_DATABASE=Emerson Network Power
+ ID_OUI_FROM_DATABASE=Artesyn Embedded Technologies
 
 OUI:0008FA*
  ID_OUI_FROM_DATABASE=Karl E.Brinkmann GmbH
@@ -21365,7 +21371,7 @@ OUI:000A2F*
  ID_OUI_FROM_DATABASE=Artnix Inc.
 
 OUI:000A30*
- ID_OUI_FROM_DATABASE=Johnson Controls-ASG
+ ID_OUI_FROM_DATABASE=Visteon Corporation
 
 OUI:000A31*
  ID_OUI_FROM_DATABASE=HCV Consulting
@@ -21584,7 +21590,7 @@ OUI:000A78*
  ID_OUI_FROM_DATABASE=OLITEC
 
 OUI:000A79*
- ID_OUI_FROM_DATABASE=Allied Telesis K.K. corega division
+ ID_OUI_FROM_DATABASE=corega K.K
 
 OUI:000A7A*
  ID_OUI_FROM_DATABASE=Kyoritsu Electric Co., Ltd.
@@ -22643,7 +22649,7 @@ OUI:000BDA*
  ID_OUI_FROM_DATABASE=EyeCross Co.,Inc.
 
 OUI:000BDB*
- ID_OUI_FROM_DATABASE=Dell ESG PCBA Test
+ ID_OUI_FROM_DATABASE=Dell Inc
 
 OUI:000BDC*
  ID_OUI_FROM_DATABASE=AKCP
@@ -23282,7 +23288,7 @@ OUI:000CB1*
  ID_OUI_FROM_DATABASE=Salland Engineering (Europe) BV
 
 OUI:000CB2*
- ID_OUI_FROM_DATABASE=Comstar Co., Ltd.
+ ID_OUI_FROM_DATABASE=UNION co., ltd.
 
 OUI:000CB3*
  ID_OUI_FROM_DATABASE=ROUND Co.,Ltd.
@@ -23522,7 +23528,7 @@ OUI:000D01*
  ID_OUI_FROM_DATABASE=P&E Microcomputer Systems, Inc.
 
 OUI:000D02*
- ID_OUI_FROM_DATABASE=NEC AccessTechnica, Ltd.
+ ID_OUI_FROM_DATABASE=NEC Platforms, Ltd.
 
 OUI:000D03*
  ID_OUI_FROM_DATABASE=Matrics, Inc.
@@ -23774,7 +23780,7 @@ OUI:000D55*
  ID_OUI_FROM_DATABASE=SANYCOM Technology Co.,Ltd
 
 OUI:000D56*
- ID_OUI_FROM_DATABASE=Dell ESG PCBA Test
+ ID_OUI_FROM_DATABASE=Dell Inc
 
 OUI:000D57*
  ID_OUI_FROM_DATABASE=Fujitsu I-Network Systems Limited.
@@ -24569,7 +24575,7 @@ OUI:000E65*
  ID_OUI_FROM_DATABASE=TransCore
 
 OUI:000E66*
- ID_OUI_FROM_DATABASE=Hitachi Advanced Digital, Inc.
+ ID_OUI_FROM_DATABASE=Hitachi Industry & Control Solutions, Ltd.
 
 OUI:000E67*
  ID_OUI_FROM_DATABASE=Eltis Microelectronics Ltd.
@@ -24941,7 +24947,7 @@ OUI:000EE1*
  ID_OUI_FROM_DATABASE=ExtremeSpeed Inc.
 
 OUI:000EE2*
- ID_OUI_FROM_DATABASE=Custom Engineering S.p.A.
+ ID_OUI_FROM_DATABASE=Custom Engineering
 
 OUI:000EE3*
  ID_OUI_FROM_DATABASE=Chiyu Technology Co.,Ltd
@@ -25118,7 +25124,7 @@ OUI:000F1E*
  ID_OUI_FROM_DATABASE=Chengdu KT Electric Co.of High & New Technology
 
 OUI:000F1F*
- ID_OUI_FROM_DATABASE=Dell ESG PCBA Test
+ ID_OUI_FROM_DATABASE=Dell Inc
 
 OUI:000F20*
  ID_OUI_FROM_DATABASE=Hewlett-Packard Company
@@ -26435,7 +26441,7 @@ OUI:0010D5*
  ID_OUI_FROM_DATABASE=IMASDE CANARIAS, S.A.
 
 OUI:0010D6*
- ID_OUI_FROM_DATABASE=ITT - A/CD
+ ID_OUI_FROM_DATABASE=Exelis
 
 OUI:0010D7*
  ID_OUI_FROM_DATABASE=ARGOSY RESEARCH INC.
@@ -26762,7 +26768,7 @@ OUI:001142*
  ID_OUI_FROM_DATABASE=e-SMARTCOM  INC.
 
 OUI:001143*
- ID_OUI_FROM_DATABASE=Dell ESG PCBA Test
+ ID_OUI_FROM_DATABASE=Dell Inc
 
 OUI:001144*
  ID_OUI_FROM_DATABASE=Assurance Technology Corp
@@ -27518,7 +27524,7 @@ OUI:00123E*
  ID_OUI_FROM_DATABASE=ERUNE technology Co., Ltd.
 
 OUI:00123F*
- ID_OUI_FROM_DATABASE=Dell ESG PCBA Test
+ ID_OUI_FROM_DATABASE=Dell Inc
 
 OUI:001240*
  ID_OUI_FROM_DATABASE=AMOI ELECTRONICS CO.,LTD
@@ -28439,7 +28445,7 @@ OUI:001371*
  ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
 
 OUI:001372*
- ID_OUI_FROM_DATABASE=Dell ESG PCBA Test
+ ID_OUI_FROM_DATABASE=Dell Inc
 
 OUI:001373*
  ID_OUI_FROM_DATABASE=BLwave Electronics Co., Ltd
@@ -28967,7 +28973,7 @@ OUI:001421*
  ID_OUI_FROM_DATABASE=Total Wireless Technologies Pte. Ltd.
 
 OUI:001422*
- ID_OUI_FROM_DATABASE=Dell ESG PCBA Test
+ ID_OUI_FROM_DATABASE=Dell Inc
 
 OUI:001423*
  ID_OUI_FROM_DATABASE=J-S Co. NEUROCOM
@@ -30104,7 +30110,7 @@ OUI:00159C*
  ID_OUI_FROM_DATABASE=B-KYUNG SYSTEM Co.,Ltd.
 
 OUI:00159D*
- ID_OUI_FROM_DATABASE=Minicom Advanced Systems ltd
+ ID_OUI_FROM_DATABASE=Tripp Lite
 
 OUI:00159E*
  ID_OUI_FROM_DATABASE=Mad Catz Interactive Inc
@@ -30224,7 +30230,7 @@ OUI:0015C4*
  ID_OUI_FROM_DATABASE=FLOVEL CO., LTD.
 
 OUI:0015C5*
- ID_OUI_FROM_DATABASE=Dell ESG PCBA Test
+ ID_OUI_FROM_DATABASE=Dell Inc
 
 OUI:0015C6*
  ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
@@ -30305,7 +30311,7 @@ OUI:0015DF*
  ID_OUI_FROM_DATABASE=Clivet S.p.A.
 
 OUI:0015E0*
- ID_OUI_FROM_DATABASE=ST-Ericsson
+ ID_OUI_FROM_DATABASE=Ericsson
 
 OUI:0015E1*
  ID_OUI_FROM_DATABASE=Picochip Ltd
@@ -30914,7 +30920,7 @@ OUI:0016AA*
  ID_OUI_FROM_DATABASE=Kei Communication Technology Inc.
 
 OUI:0016AB*
- ID_OUI_FROM_DATABASE=PBI-Dansensor A/S
+ ID_OUI_FROM_DATABASE=Dansensor A/S
 
 OUI:0016AC*
  ID_OUI_FROM_DATABASE=Toho Technology Corp.
@@ -32342,7 +32348,7 @@ OUI:00188A*
  ID_OUI_FROM_DATABASE=Infinova LLC
 
 OUI:00188B*
- ID_OUI_FROM_DATABASE=Dell ESG PCBA Test
+ ID_OUI_FROM_DATABASE=Dell Inc
 
 OUI:00188C*
  ID_OUI_FROM_DATABASE=Mobile Action Technology Inc.
@@ -32369,7 +32375,7 @@ OUI:001893*
  ID_OUI_FROM_DATABASE=SHENZHEN PHOTON BROADBAND TECHNOLOGY CO.,LTD
 
 OUI:001894*
- ID_OUI_FROM_DATABASE=zimocom
+ ID_OUI_FROM_DATABASE=NPCore, Inc.
 
 OUI:001895*
  ID_OUI_FROM_DATABASE=Hansun Technologies Inc.
@@ -33881,7 +33887,7 @@ OUI:001A8B*
  ID_OUI_FROM_DATABASE=CHUNIL ELECTRIC IND., CO.
 
 OUI:001A8C*
- ID_OUI_FROM_DATABASE=Astaro AG
+ ID_OUI_FROM_DATABASE=Sophos Ltd
 
 OUI:001A8D*
  ID_OUI_FROM_DATABASE=AVECS Bergen GmbH
@@ -34646,7 +34652,7 @@ OUI:001B8A*
  ID_OUI_FROM_DATABASE=2M Electronic A/S
 
 OUI:001B8B*
- ID_OUI_FROM_DATABASE=NEC AccessTechnica, Ltd.
+ ID_OUI_FROM_DATABASE=NEC Platforms, Ltd.
 
 OUI:001B8C*
  ID_OUI_FROM_DATABASE=JMicron Technology Corp.
@@ -35060,7 +35066,7 @@ OUI:001C14*
  ID_OUI_FROM_DATABASE=VMware, Inc
 
 OUI:001C15*
- ID_OUI_FROM_DATABASE=TXP Corporation
+ ID_OUI_FROM_DATABASE=iPhotonix LLC
 
 OUI:001C16*
  ID_OUI_FROM_DATABASE=ThyssenKrupp Elevator
@@ -35348,7 +35354,7 @@ OUI:001C74*
  ID_OUI_FROM_DATABASE=Syswan Technologies Inc.
 
 OUI:001C75*
- ID_OUI_FROM_DATABASE=RF Systems GmbH
+ ID_OUI_FROM_DATABASE=Segnet Ltd.
 
 OUI:001C76*
  ID_OUI_FROM_DATABASE=The Wandsworth Group Ltd
@@ -35831,7 +35837,7 @@ OUI:001D15*
  ID_OUI_FROM_DATABASE=Shenzhen Dolphin Electronic Co., Ltd
 
 OUI:001D16*
- ID_OUI_FROM_DATABASE=Efixo
+ ID_OUI_FROM_DATABASE=SFR
 
 OUI:001D17*
  ID_OUI_FROM_DATABASE=Digital Sky Corporation
@@ -35957,7 +35963,7 @@ OUI:001D3F*
  ID_OUI_FROM_DATABASE=Mitron Pty Ltd
 
 OUI:001D40*
- ID_OUI_FROM_DATABASE=Living Independently Group, Inc.
+ ID_OUI_FROM_DATABASE=Intel – GE Care Innovations LLC
 
 OUI:001D41*
  ID_OUI_FROM_DATABASE=Hardy Instruments
@@ -35969,7 +35975,7 @@ OUI:001D43*
  ID_OUI_FROM_DATABASE=Shenzhen G-link Digital Technology Co., Ltd.
 
 OUI:001D44*
- ID_OUI_FROM_DATABASE=Krohne
+ ID_OUI_FROM_DATABASE=KROHNE Messtechnik GmbH
 
 OUI:001D45*
  ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
@@ -36857,7 +36863,7 @@ OUI:001E6B*
  ID_OUI_FROM_DATABASE=Cisco SPVTG
 
 OUI:001E6C*
- ID_OUI_FROM_DATABASE=Carbon Mountain LLC
+ ID_OUI_FROM_DATABASE=Opaque Systems
 
 OUI:001E6D*
  ID_OUI_FROM_DATABASE=IT R&D Center
@@ -37133,76 +37139,76 @@ OUI:001EC7*
  ID_OUI_FROM_DATABASE=2Wire, Inc.
 
 OUI:001EC8*
- ID_OUI_FROM_DATABASE=2Wire, Inc.
+ ID_OUI_FROM_DATABASE=Rapid Mobile (Pty) Ltd
 
 OUI:001EC9*
- ID_OUI_FROM_DATABASE=2Wire, Inc.
+ ID_OUI_FROM_DATABASE=Dell Inc
 
 OUI:001ECA*
- ID_OUI_FROM_DATABASE=2Wire, Inc.
+ ID_OUI_FROM_DATABASE=Nortel
 
 OUI:001ECB*
- ID_OUI_FROM_DATABASE=2Wire, Inc.
+ ID_OUI_FROM_DATABASE="RPC "Energoautomatika" Ltd
 
 OUI:001ECC*
- ID_OUI_FROM_DATABASE=2Wire, Inc.
+ ID_OUI_FROM_DATABASE=CDVI
 
 OUI:001ECD*
  ID_OUI_FROM_DATABASE=KYLAND Technology Co. LTD
 
 OUI:001ECE*
- ID_OUI_FROM_DATABASE=2Wire, Inc.
+ ID_OUI_FROM_DATABASE=BISA Technologies (Hong Kong) Limited
 
 OUI:001ECF*
- ID_OUI_FROM_DATABASE=2Wire, Inc.
+ ID_OUI_FROM_DATABASE=PHILIPS ELECTRONICS UK LTD
 
 OUI:001ED0*
- ID_OUI_FROM_DATABASE=2Wire, Inc.
+ ID_OUI_FROM_DATABASE=Ingespace
 
 OUI:001ED1*
- ID_OUI_FROM_DATABASE=2Wire, Inc.
+ ID_OUI_FROM_DATABASE=Keyprocessor B.V.
 
 OUI:001ED2*
- ID_OUI_FROM_DATABASE=2Wire, Inc.
+ ID_OUI_FROM_DATABASE=Ray Shine Video Technology Inc
 
 OUI:001ED3*
- ID_OUI_FROM_DATABASE=2Wire, Inc.
+ ID_OUI_FROM_DATABASE=Dot Technology Int'l Co., Ltd.
 
 OUI:001ED4*
- ID_OUI_FROM_DATABASE=2Wire, Inc.
+ ID_OUI_FROM_DATABASE=Doble Engineering
 
 OUI:001ED5*
- ID_OUI_FROM_DATABASE=2Wire, Inc.
+ ID_OUI_FROM_DATABASE=Tekon-Automatics
 
 OUI:001ED6*
- ID_OUI_FROM_DATABASE=2Wire, Inc.
+ ID_OUI_FROM_DATABASE=Alentec & Orion AB
 
 OUI:001ED7*
- ID_OUI_FROM_DATABASE=2Wire, Inc.
+ ID_OUI_FROM_DATABASE=H-Stream Wireless, Inc.
 
 OUI:001ED8*
- ID_OUI_FROM_DATABASE=2Wire, Inc.
+ ID_OUI_FROM_DATABASE=Digital United Inc.
 
 OUI:001ED9*
- ID_OUI_FROM_DATABASE=2Wire, Inc.
+ ID_OUI_FROM_DATABASE=Mitsubishi Precision Co.,LTd.
 
 OUI:001EDA*
- ID_OUI_FROM_DATABASE=2Wire, Inc.
+ ID_OUI_FROM_DATABASE=Wesemann Elektrotechniek B.V.
 
 OUI:001EDB*
- ID_OUI_FROM_DATABASE=2Wire, Inc.
+ ID_OUI_FROM_DATABASE=Giken Trastem Co., Ltd.
 
 OUI:001EDC*
- ID_OUI_FROM_DATABASE=2Wire, Inc.
+ ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB
 
 OUI:001EDD*
- ID_OUI_FROM_DATABASE=2Wire, Inc.
+ ID_OUI_FROM_DATABASE=WASKO S.A.
 
 OUI:001EDE*
- ID_OUI_FROM_DATABASE=2Wire, Inc.
+ ID_OUI_FROM_DATABASE=BYD COMPANY LIMITED
 
 OUI:001EDF*
- ID_OUI_FROM_DATABASE=2Wire, Inc.
+ ID_OUI_FROM_DATABASE=Master Industrialization Center Kista
 
 OUI:001EE0*
  ID_OUI_FROM_DATABASE=Urmet Domus SpA
@@ -38465,7 +38471,7 @@ OUI:002084*
  ID_OUI_FROM_DATABASE=OCE PRINTING SYSTEMS, GMBH
 
 OUI:002085*
- ID_OUI_FROM_DATABASE=EXIDE ELECTRONICS
+ ID_OUI_FROM_DATABASE=Eaton Corporation
 
 OUI:002086*
  ID_OUI_FROM_DATABASE=MICROTECH ELECTRONICS LIMITED
@@ -40316,7 +40322,7 @@ OUI:0022EE*
  ID_OUI_FROM_DATABASE=Algo Communication Products Ltd
 
 OUI:0022EF*
- ID_OUI_FROM_DATABASE=Ibis Tek, LLC
+ ID_OUI_FROM_DATABASE=iWDL Technologies
 
 OUI:0022F0*
  ID_OUI_FROM_DATABASE=3 Greens Aviation Limited
@@ -40361,7 +40367,7 @@ OUI:0022FE*
  ID_OUI_FROM_DATABASE=Microprocessor Designs Inc
 
 OUI:0022FF*
- ID_OUI_FROM_DATABASE=NIVIS LLC
+ ID_OUI_FROM_DATABASE=iWDL Technologies
 
 OUI:002300*
  ID_OUI_FROM_DATABASE=Cayee Computer Ltd.
@@ -41258,7 +41264,7 @@ OUI:00242E*
  ID_OUI_FROM_DATABASE=Datastrip Inc.
 
 OUI:00242F*
- ID_OUI_FROM_DATABASE=VirtenSys Inc
+ ID_OUI_FROM_DATABASE=Micron
 
 OUI:002430*
  ID_OUI_FROM_DATABASE=Ruby Tech Corp.
@@ -43028,7 +43034,7 @@ OUI:002686*
  ID_OUI_FROM_DATABASE=Quantenna Communcations, Inc.
 
 OUI:002687*
- ID_OUI_FROM_DATABASE=ALLIED TELESIS, K.K corega division.
+ ID_OUI_FROM_DATABASE=Corega K.K
 
 OUI:002688*
  ID_OUI_FROM_DATABASE=Juniper Networks
@@ -44306,7 +44312,7 @@ OUI:003A9C*
  ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
 
 OUI:003A9D*
- ID_OUI_FROM_DATABASE=NEC AccessTechnica, Ltd.
+ ID_OUI_FROM_DATABASE=NEC Platforms, Ltd.
 
 OUI:003AAF*
  ID_OUI_FROM_DATABASE=BlueBit Ltd.
@@ -45794,7 +45800,7 @@ OUI:0050F8*
  ID_OUI_FROM_DATABASE=ENTREGA TECHNOLOGIES, INC.
 
 OUI:0050F9*
- ID_OUI_FROM_DATABASE=SENSORMATIC ACD
+ ID_OUI_FROM_DATABASE=Sensormatic Electronics LLC
 
 OUI:0050FA*
  ID_OUI_FROM_DATABASE=OXTEL, LTD.
@@ -45823,6 +45829,9 @@ OUI:0054AF*
 OUI:005907*
  ID_OUI_FROM_DATABASE=LenovoEMC Products USA, LLC
 
+OUI:005A39*
+ ID_OUI_FROM_DATABASE=SHENZHEN FAST TECHNOLOGIES CO., LTD.
+
 OUI:005CB1*
  ID_OUI_FROM_DATABASE=Gospell DIGITAL TECHNOLOGY CO., LTD
 
@@ -46118,7 +46127,7 @@ OUI:00605F*
  ID_OUI_FROM_DATABASE=NIPPON UNISOFT CORPORATION
 
 OUI:006060*
- ID_OUI_FROM_DATABASE=DAWNING TECHNOLOGIES, INC.
+ ID_OUI_FROM_DATABASE=Data Innovations North America
 
 OUI:006061*
  ID_OUI_FROM_DATABASE=WHISTLE COMMUNICATIONS CORP.
@@ -46385,7 +46394,7 @@ OUI:0060B8*
  ID_OUI_FROM_DATABASE=CORELIS Inc.
 
 OUI:0060B9*
- ID_OUI_FROM_DATABASE=NEC Infrontia Corporation
+ ID_OUI_FROM_DATABASE=NEC Platforms, Ltd
 
 OUI:0060BA*
  ID_OUI_FROM_DATABASE=SAHARA NETWORKS, INC.
@@ -46597,6 +46606,9 @@ OUI:0060FE*
 OUI:0060FF*
  ID_OUI_FROM_DATABASE=QuVis, Inc.
 
+OUI:006171*
+ ID_OUI_FROM_DATABASE=Apple
+
 OUI:006440*
  ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
 
@@ -46606,6 +46618,9 @@ OUI:0064A6*
 OUI:00664B*
  ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd
 
+OUI:006B8E*
+ ID_OUI_FROM_DATABASE=Shanghai Feixun Communication Co.,Ltd.
+
 OUI:006B9E*
  ID_OUI_FROM_DATABASE=VIZIO Inc
 
@@ -46621,12 +46636,18 @@ OUI:0070B0*
 OUI:0070B3*
  ID_OUI_FROM_DATABASE=DATA RECALL LTD.
 
+OUI:0071CC*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
 OUI:00738D*
  ID_OUI_FROM_DATABASE=Tinno Mobile Technology Corp
 
 OUI:0073E0*
  ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
 
+OUI:007532*
+ ID_OUI_FROM_DATABASE=INID BV
+
 OUI:0075E1*
  ID_OUI_FROM_DATABASE=Ampt, LLC
 
@@ -46838,7 +46859,7 @@ OUI:008041*
  ID_OUI_FROM_DATABASE=VEB KOMBINAT ROBOTRON
 
 OUI:008042*
- ID_OUI_FROM_DATABASE=Emerson Network Power
+ ID_OUI_FROM_DATABASE=Artesyn Embedded Technologies
 
 OUI:008043*
  ID_OUI_FROM_DATABASE=NETWORLD, INC.
@@ -48223,6 +48244,9 @@ OUI:009C02*
 OUI:009D8E*
  ID_OUI_FROM_DATABASE=CARDIAC RECORDERS, INC.
 
+OUI:009EC8*
+ ID_OUI_FROM_DATABASE=Beijing Xiaomi Electronic Products Co., Ltd.
+
 OUI:00A000*
  ID_OUI_FROM_DATABASE=CENTILLION NETWORKS, INC.
 
@@ -48623,7 +48647,7 @@ OUI:00A086*
  ID_OUI_FROM_DATABASE=AMBER WAVE SYSTEMS, INC.
 
 OUI:00A087*
- ID_OUI_FROM_DATABASE=Zarlink Semiconductor Ltd.
+ ID_OUI_FROM_DATABASE=Microsemi Corporation
 
 OUI:00A088*
  ID_OUI_FROM_DATABASE=ESSENTIAL COMMUNICATIONS
@@ -48991,6 +49015,9 @@ OUI:00A1DE*
 OUI:00A2DA*
  ID_OUI_FROM_DATABASE=INAT GmbH
 
+OUI:00A2F5*
+ ID_OUI_FROM_DATABASE=Guangzhou Yuanyun Network Technology Co.,Ltd
+
 OUI:00A2FF*
  ID_OUI_FROM_DATABASE=abatec group AG
 
@@ -49009,6 +49036,12 @@ OUI:00AA3C*
 OUI:00AA70*
  ID_OUI_FROM_DATABASE=LG Electronics
 
+OUI:00ACE0*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:00AEFA*
+ ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
+
 OUI:00B009*
  ID_OUI_FROM_DATABASE=Grass Valley Group
 
@@ -49904,7 +49937,7 @@ OUI:00C0F8*
  ID_OUI_FROM_DATABASE=ABOUT COMPUTING INC.
 
 OUI:00C0F9*
- ID_OUI_FROM_DATABASE=Emerson Network Power
+ ID_OUI_FROM_DATABASE=Artesyn Embedded Technologies
 
 OUI:00C0FA*
  ID_OUI_FROM_DATABASE=CANARY COMMUNICATIONS, INC.
@@ -50722,6 +50755,9 @@ OUI:00D38D*
 OUI:00D632*
  ID_OUI_FROM_DATABASE=GE Energy
 
+OUI:00D9D1*
+ ID_OUI_FROM_DATABASE=Sony Computer Entertainment Inc.
+
 OUI:00DB1E*
  ID_OUI_FROM_DATABASE=Albedo Telecom SL
 
@@ -50942,7 +50978,7 @@ OUI:00E034*
  ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
 
 OUI:00E035*
- ID_OUI_FROM_DATABASE=Emerson Network Power
+ ID_OUI_FROM_DATABASE=Artesyn Embedded Technologies
 
 OUI:00E036*
  ID_OUI_FROM_DATABASE=PIONEER CORPORATION
@@ -51550,6 +51586,9 @@ OUI:00E0FE*
 OUI:00E0FF*
  ID_OUI_FROM_DATABASE=SECURITY DYNAMICS TECHNOLOGIES, Inc.
 
+OUI:00E16D*
+ ID_OUI_FROM_DATABASE=Cisco
+
 OUI:00E175*
  ID_OUI_FROM_DATABASE=AK-Systems Ltd
 
@@ -51562,6 +51601,9 @@ OUI:00E666*
 OUI:00E6D3*
  ID_OUI_FROM_DATABASE=NIXDORF COMPUTER CORP.
 
+OUI:00E6E8*
+ ID_OUI_FROM_DATABASE=Netzin Technology Corporation,.Ltd.
+
 OUI:00E8AB*
  ID_OUI_FROM_DATABASE=Meggitt Training Systems, Inc.
 
@@ -51577,9 +51619,15 @@ OUI:00F051*
 OUI:00F403*
  ID_OUI_FROM_DATABASE=Orbis Systems Oy
 
+OUI:00F46F*
+ ID_OUI_FROM_DATABASE=Samsung Elec Co.,Ltd
+
 OUI:00F4B9*
  ID_OUI_FROM_DATABASE=Apple
 
+OUI:00F76F*
+ ID_OUI_FROM_DATABASE=Apple
+
 OUI:00F860*
  ID_OUI_FROM_DATABASE=PT. Panggung Electric Citrabuana
 
@@ -51703,6 +51751,9 @@ OUI:0444A1*
 OUI:044665*
  ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
 
+OUI:04489A*
+ ID_OUI_FROM_DATABASE=Apple
+
 OUI:044A50*
  ID_OUI_FROM_DATABASE=Ramaxel Technology (Shenzhen) limited company
 
@@ -51727,6 +51778,9 @@ OUI:045453*
 OUI:0455CA*
  ID_OUI_FROM_DATABASE=BriView (Xiamen) Corp.
 
+OUI:04572F*
+ ID_OUI_FROM_DATABASE=Sertel Electronics UK Ltd
+
 OUI:04586F*
  ID_OUI_FROM_DATABASE=Sichuan Whayer information industry Co.,LTD
 
@@ -51736,6 +51790,9 @@ OUI:045A95*
 OUI:045C06*
  ID_OUI_FROM_DATABASE=Zmodo Technology Corporation
 
+OUI:045C8E*
+ ID_OUI_FROM_DATABASE=gosund GROUP CO.,LTD
+
 OUI:045D56*
  ID_OUI_FROM_DATABASE=camtron industrial inc.
 
@@ -51748,6 +51805,9 @@ OUI:0462D7*
 OUI:0463E0*
  ID_OUI_FROM_DATABASE=Nome Oy
 
+OUI:046785*
+ ID_OUI_FROM_DATABASE=scemtec Hard- und Software fuer Mess- und Steuerungstechnik GmbH
+
 OUI:046D42*
  ID_OUI_FROM_DATABASE=Bryston Ltd.
 
@@ -51799,6 +51859,12 @@ OUI:0494A1*
 OUI:0498F3*
  ID_OUI_FROM_DATABASE=ALPS Electric Co,. Ltd.
 
+OUI:0499E6*
+ ID_OUI_FROM_DATABASE=Shenzhen Yoostar Technology Co., Ltd
+
+OUI:049B9C*
+ ID_OUI_FROM_DATABASE=Eadingcore  Intelligent Technology Co., Ltd.
+
 OUI:049C62*
  ID_OUI_FROM_DATABASE=BMT Medical Technology s.r.o.
 
@@ -51841,6 +51907,9 @@ OUI:04C5A4*
 OUI:04C880*
  ID_OUI_FROM_DATABASE=Samtec Inc
 
+OUI:04C991*
+ ID_OUI_FROM_DATABASE=Phistek INC.
+
 OUI:04CB1D*
  ID_OUI_FROM_DATABASE=Traka plc
 
@@ -51868,6 +51937,9 @@ OUI:04DB8A*
 OUI:04DD4C*
  ID_OUI_FROM_DATABASE=Velocytech
 
+OUI:04DEDB*
+ ID_OUI_FROM_DATABASE=Rockport Networks Inc
+
 OUI:04DF69*
  ID_OUI_FROM_DATABASE=Car Connectivity Consortium
 
@@ -51892,6 +51964,9 @@ OUI:04E548*
 OUI:04E662*
  ID_OUI_FROM_DATABASE=Acroname Inc.
 
+OUI:04E676*
+ ID_OUI_FROM_DATABASE=AMPAK Technology Inc.
+
 OUI:04E9E5*
  ID_OUI_FROM_DATABASE=PJRC.COM, LLC
 
@@ -52369,6 +52444,9 @@ OUI:0808C2*
 OUI:0808EA*
  ID_OUI_FROM_DATABASE=AMSC
 
+OUI:0809B6*
+ ID_OUI_FROM_DATABASE=Masimo Corp
+
 OUI:080C0B*
  ID_OUI_FROM_DATABASE=SysMik GmbH Dresden
 
@@ -52384,6 +52462,9 @@ OUI:080EA8*
 OUI:080FFA*
  ID_OUI_FROM_DATABASE=KSP INC.
 
+OUI:08115E*
+ ID_OUI_FROM_DATABASE=Bitel Co., Ltd.
+
 OUI:081196*
  ID_OUI_FROM_DATABASE=Intel Corporate
 
@@ -52444,6 +52525,9 @@ OUI:0838A5*
 OUI:083AB8*
  ID_OUI_FROM_DATABASE=Shinoda Plasma Co., Ltd.
 
+OUI:083D88*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
 OUI:083E0C*
  ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
 
@@ -52459,12 +52543,12 @@ OUI:083F76*
 OUI:084027*
  ID_OUI_FROM_DATABASE=Gridstore Inc.
 
+OUI:084656*
+ ID_OUI_FROM_DATABASE=VODALYS Ingénierie
+
 OUI:08482C*
  ID_OUI_FROM_DATABASE=Raycore Taiwan Co., LTD.
 
-OUI:084929*
- ID_OUI_FROM_DATABASE=CYBATI
-
 OUI:084E1C*
  ID_OUI_FROM_DATABASE=H2A Systems, LLC
 
@@ -52486,6 +52570,9 @@ OUI:085AE0*
 OUI:085B0E*
  ID_OUI_FROM_DATABASE=Fortinet, Inc.
 
+OUI:085DDD*
+ ID_OUI_FROM_DATABASE=Mercury Corporation
+
 OUI:08606E*
  ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
 
@@ -52504,6 +52591,9 @@ OUI:086DF2*
 OUI:087045*
  ID_OUI_FROM_DATABASE=Apple
 
+OUI:0874F6*
+ ID_OUI_FROM_DATABASE=Winterhalter Gastronom GmbH
+
 OUI:087572*
  ID_OUI_FROM_DATABASE=Obelux Oy
 
@@ -52534,6 +52624,9 @@ OUI:087D21*
 OUI:088039*
  ID_OUI_FROM_DATABASE=Cisco SPVTG
 
+OUI:0881BC*
+ ID_OUI_FROM_DATABASE=HongKong Ipro Technology Co., Limited
+
 OUI:0881F4*
  ID_OUI_FROM_DATABASE=Juniper Networks
 
@@ -52573,6 +52666,9 @@ OUI:08ACA5*
 OUI:08AF78*
  ID_OUI_FROM_DATABASE=Totus Solutions, Inc.
 
+OUI:08B2A3*
+ ID_OUI_FROM_DATABASE=Cynny Italia S.r.L.
+
 OUI:08B4CF*
  ID_OUI_FROM_DATABASE=Abicom International
 
@@ -52597,6 +52693,9 @@ OUI:08CA45*
 OUI:08CC68*
  ID_OUI_FROM_DATABASE=Cisco
 
+OUI:08CD9B*
+ ID_OUI_FROM_DATABASE=samtec automotive electronics & software GmbH
+
 OUI:08D09F*
  ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
 
@@ -52615,15 +52714,24 @@ OUI:08D5C0*
 OUI:08D833*
  ID_OUI_FROM_DATABASE=Shenzhen RF Technology Co,.Ltd
 
+OUI:08DF1F*
+ ID_OUI_FROM_DATABASE=Bose Corporation
+
 OUI:08E5DA*
  ID_OUI_FROM_DATABASE=NANJING FUJITSU COMPUTER PRODUCTS CO.,LTD.
 
 OUI:08E672*
  ID_OUI_FROM_DATABASE=JEBSEE ELECTRONICS CO.,LTD.
 
+OUI:08E84F*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
 OUI:08EA44*
  ID_OUI_FROM_DATABASE=Aerohive Networks, Inc.
 
+OUI:08EB29*
+ ID_OUI_FROM_DATABASE=Jiangsu Huitong Group Co.,Ltd.
+
 OUI:08EB74*
  ID_OUI_FROM_DATABASE=Humax
 
@@ -52633,6 +52741,9 @@ OUI:08EBED*
 OUI:08EDB9*
  ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
 
+OUI:08EE8B*
+ ID_OUI_FROM_DATABASE=Samsung Elec Co.,Ltd
+
 OUI:08EF3B*
  ID_OUI_FROM_DATABASE=MCS Logic Inc.
 
@@ -52645,6 +52756,9 @@ OUI:08F2F4*
 OUI:08F6F8*
  ID_OUI_FROM_DATABASE=GET Engineering
 
+OUI:08F728*
+ ID_OUI_FROM_DATABASE=GLOBO Multimedia Sp. z o.o. Sp.k.
+
 OUI:08FAE0*
  ID_OUI_FROM_DATABASE=Fohhn Audio AG
 
@@ -52684,9 +52798,15 @@ OUI:0C17F1*
 OUI:0C191F*
  ID_OUI_FROM_DATABASE=Inform Electronik
 
+OUI:0C1DAF*
+ ID_OUI_FROM_DATABASE=Beijing Xiaomi communications co.,ltd
+
 OUI:0C1DC2*
  ID_OUI_FROM_DATABASE=SeAH Networks
 
+OUI:0C2026*
+ ID_OUI_FROM_DATABASE=noax Technologies AG
+
 OUI:0C2724*
  ID_OUI_FROM_DATABASE=Cisco
 
@@ -52708,6 +52828,9 @@ OUI:0C3021*
 OUI:0C37DC*
  ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd
 
+OUI:0C383E*
+ ID_OUI_FROM_DATABASE=Fanvil Technology Co., Ltd.
+
 OUI:0C3956*
  ID_OUI_FROM_DATABASE=Observator instruments
 
@@ -52756,6 +52879,9 @@ OUI:0C5CD8*
 OUI:0C6076*
  ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
 
+OUI:0C63FC*
+ ID_OUI_FROM_DATABASE=Nanjing Signway Technology Co., Ltd
+
 OUI:0C6803*
  ID_OUI_FROM_DATABASE=Cisco
 
@@ -52807,6 +52933,9 @@ OUI:0C8910*
 OUI:0C8BFD*
  ID_OUI_FROM_DATABASE=Intel Corporate
 
+OUI:0C8C8F*
+ ID_OUI_FROM_DATABASE=Kamo Technology Limited
+
 OUI:0C8CDC*
  ID_OUI_FROM_DATABASE=Suunto Oy
 
@@ -52849,9 +52978,15 @@ OUI:0CA42A*
 OUI:0CA694*
  ID_OUI_FROM_DATABASE=Sunitec Enterprise Co.,Ltd
 
+OUI:0CAC05*
+ ID_OUI_FROM_DATABASE=Unitend Technologies Inc.
+
 OUI:0CAF5A*
  ID_OUI_FROM_DATABASE=GENUS POWER INFRASTRUCTURES LIMITED
 
+OUI:0CB319*
+ ID_OUI_FROM_DATABASE=Samsung Elec Co.,Ltd
+
 OUI:0CB4EF*
  ID_OUI_FROM_DATABASE=Digience Co.,Ltd.
 
@@ -52897,6 +53032,9 @@ OUI:0CCDD3*
 OUI:0CCDFB*
  ID_OUI_FROM_DATABASE=EDIC Systems Inc.
 
+OUI:0CCFD1*
+ ID_OUI_FROM_DATABASE=SPRINGWAVE Co., Ltd
+
 OUI:0CD292*
  ID_OUI_FROM_DATABASE=Intel Corporate
 
@@ -52916,7 +53054,7 @@ OUI:0CD996*
  ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
 
 OUI:0CD9C1*
- ID_OUI_FROM_DATABASE=Johnson Controls-ASG
+ ID_OUI_FROM_DATABASE=Visteon Corporation
 
 OUI:0CDA41*
  ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
@@ -52984,6 +53122,12 @@ OUI:1000FD*
 OUI:1001CA*
  ID_OUI_FROM_DATABASE=Ashley Butterworth
 
+OUI:1005CA*
+ ID_OUI_FROM_DATABASE=Cisco
+
+OUI:1008B1*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
 OUI:10090C*
  ID_OUI_FROM_DATABASE=Janome Sewing Machine Co., Ltd.
 
@@ -53008,12 +53152,18 @@ OUI:100E2B*
 OUI:100E7E*
  ID_OUI_FROM_DATABASE=Juniper networks
 
+OUI:100F18*
+ ID_OUI_FROM_DATABASE=Fu Gang Electronic(KunShan)CO.,LTD
+
 OUI:1010B6*
  ID_OUI_FROM_DATABASE=McCain Inc
 
 OUI:101212*
  ID_OUI_FROM_DATABASE=Vivo International Corporation Pty Ltd
 
+OUI:101218*
+ ID_OUI_FROM_DATABASE=Korins Inc.
+
 OUI:101248*
  ID_OUI_FROM_DATABASE=ITG, Inc.
 
@@ -53053,6 +53203,12 @@ OUI:102D96*
 OUI:102EAF*
  ID_OUI_FROM_DATABASE=Texas Instruments
 
+OUI:102F6B*
+ ID_OUI_FROM_DATABASE=Microsoft Corporation
+
+OUI:103047*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
 OUI:103378*
  ID_OUI_FROM_DATABASE=FLECTRON Co., LTD
 
@@ -53086,9 +53242,18 @@ OUI:104780*
 OUI:1048B1*
  ID_OUI_FROM_DATABASE=Beijing Duokan Technology Limited
 
+OUI:104B46*
+ ID_OUI_FROM_DATABASE=Mitsubishi Electric Corporation
+
 OUI:104D77*
  ID_OUI_FROM_DATABASE=Innovative Computer Engineering
 
+OUI:104E07*
+ ID_OUI_FROM_DATABASE=Shanghai Genvision Industries Co.,Ltd
+
+OUI:105172*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
 OUI:1056CA*
  ID_OUI_FROM_DATABASE=Peplink International Ltd.
 
@@ -53120,7 +53285,7 @@ OUI:1065CF*
  ID_OUI_FROM_DATABASE=IQSIM
 
 OUI:106682*
- ID_OUI_FROM_DATABASE=NEC AccessTechnica, Ltd.
+ ID_OUI_FROM_DATABASE=NEC Platforms, Ltd.
 
 OUI:10683F*
  ID_OUI_FROM_DATABASE=LG Electronics
@@ -53158,9 +53323,18 @@ OUI:1083D2*
 OUI:10880F*
  ID_OUI_FROM_DATABASE=Daruma Telecomunicações e Informática S.A.
 
+OUI:1088CE*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Tech.Co.,Ltd.
+
+OUI:108A1B*
+ ID_OUI_FROM_DATABASE=RAONIX Inc.
+
 OUI:108CCF*
  ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
 
+OUI:109266*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
 OUI:1093E9*
  ID_OUI_FROM_DATABASE=Apple
 
@@ -53206,6 +53380,9 @@ OUI:10BF48*
 OUI:10C2BA*
  ID_OUI_FROM_DATABASE=UTT Co., Ltd.
 
+OUI:10C37B*
+ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
+
 OUI:10C586*
  ID_OUI_FROM_DATABASE=BIO SOUND LAB CO., LTD.
 
@@ -53275,6 +53452,9 @@ OUI:10F96F*
 OUI:10F9EE*
  ID_OUI_FROM_DATABASE=Nokia Corporation
 
+OUI:10FACE*
+ ID_OUI_FROM_DATABASE=Reacheng Communication Technology Co.,Ltd
+
 OUI:10FBF0*
  ID_OUI_FROM_DATABASE=KangSheng LTD.
 
@@ -53311,12 +53491,18 @@ OUI:141BBD*
 OUI:141BF0*
  ID_OUI_FROM_DATABASE=Intellimedia Systems Ltd
 
+OUI:141FBA*
+ ID_OUI_FROM_DATABASE=IEEE REGISTRATION AUTHORITY  - Please see MAM public listing for more information.
+
 OUI:1423D7*
  ID_OUI_FROM_DATABASE=EUTRONIX CO., LTD.
 
 OUI:142BD2*
  ID_OUI_FROM_DATABASE=Armtel Ltd.
 
+OUI:142BD6*
+ ID_OUI_FROM_DATABASE=Guangdong Appscomm Co.,Ltd
+
 OUI:142D27*
  ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
 
@@ -53329,6 +53515,9 @@ OUI:142DF5*
 OUI:14307A*
  ID_OUI_FROM_DATABASE=Avermetrics
 
+OUI:1430C6*
+ ID_OUI_FROM_DATABASE=Motorola Mobility LLC
+
 OUI:14358B*
  ID_OUI_FROM_DATABASE=Mediabridge Products, LLC.
 
@@ -53344,6 +53533,9 @@ OUI:14373B*
 OUI:143AEA*
  ID_OUI_FROM_DATABASE=Dynapower Company LLC
 
+OUI:143DF2*
+ ID_OUI_FROM_DATABASE=Beijing Shidai Hongyuan Network Communication Co.,Ltd
+
 OUI:143E60*
  ID_OUI_FROM_DATABASE=Alcatel-Lucent
 
@@ -53356,6 +53548,9 @@ OUI:144319*
 OUI:1446E4*
  ID_OUI_FROM_DATABASE=AVISTEL
 
+OUI:14488B*
+ ID_OUI_FROM_DATABASE=Shenzhen Doov Technology Co.,Ltd
+
 OUI:144978*
  ID_OUI_FROM_DATABASE=Digital Control Incorporated
 
@@ -53368,6 +53563,12 @@ OUI:144C1A*
 OUI:145412*
  ID_OUI_FROM_DATABASE=Entis Co., Ltd.
 
+OUI:145645*
+ ID_OUI_FROM_DATABASE=Savitech Corp.
+
+OUI:1458D0*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
 OUI:145A05*
  ID_OUI_FROM_DATABASE=Apple
 
@@ -53389,6 +53590,9 @@ OUI:147373*
 OUI:147411*
  ID_OUI_FROM_DATABASE=RIM
 
+OUI:147590*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+
 OUI:147DB3*
  ID_OUI_FROM_DATABASE=JOA TELECOM.CO.,LTD
 
@@ -53422,6 +53626,9 @@ OUI:1499E2*
 OUI:149FE8*
  ID_OUI_FROM_DATABASE=Lenovo Mobile Communication Technology Ltd.
 
+OUI:14A364*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
 OUI:14A62C*
  ID_OUI_FROM_DATABASE=S.M. Dezac S.A.
 
@@ -53440,6 +53647,9 @@ OUI:14B126*
 OUI:14B1C8*
  ID_OUI_FROM_DATABASE=InfiniWing, Inc.
 
+OUI:14B484*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
 OUI:14B73D*
  ID_OUI_FROM_DATABASE=ARCHEAN Technologies
 
@@ -53449,6 +53659,9 @@ OUI:14B968*
 OUI:14C089*
  ID_OUI_FROM_DATABASE=DUNE HD LTD
 
+OUI:14C126*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
 OUI:14C21D*
  ID_OUI_FROM_DATABASE=Sabtech Industries
 
@@ -53489,7 +53702,10 @@ OUI:14EB33*
  ID_OUI_FROM_DATABASE=BSMediasoft Co., Ltd.
 
 OUI:14EDA5*
- ID_OUI_FROM_DATABASE=Wächter GmbH Sicherheitssysteme
+ ID_OUI_FROM_DATABASE=Wächter GmbH Sicherheitssysteme
+
+OUI:14EDE4*
+ ID_OUI_FROM_DATABASE=Kaiam Corporation
 
 OUI:14EE9D*
  ID_OUI_FROM_DATABASE=AirNav Systems LLC
@@ -53503,6 +53719,12 @@ OUI:14F28E*
 OUI:14F42A*
  ID_OUI_FROM_DATABASE=Samsung Electronics
 
+OUI:14F65A*
+ ID_OUI_FROM_DATABASE=Xiaomi inc.
+
+OUI:14F893*
+ ID_OUI_FROM_DATABASE=Wuhan FiberHome Digital Technology Co.,Ltd.
+
 OUI:14FEAF*
  ID_OUI_FROM_DATABASE=SAGITTAR LIMITED
 
@@ -53572,6 +53794,9 @@ OUI:182032*
 OUI:1820A6*
  ID_OUI_FROM_DATABASE=Sage Co., Ltd.
 
+OUI:18227E*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
 OUI:182666*
  ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
 
@@ -53587,6 +53812,9 @@ OUI:182B05*
 OUI:182C91*
  ID_OUI_FROM_DATABASE=Concept Development, Inc.
 
+OUI:183009*
+ ID_OUI_FROM_DATABASE=Woojin Industrial Systems Co., Ltd.
+
 OUI:1832A2*
  ID_OUI_FROM_DATABASE=LAON TECHNOLOGY CO., LTD.
 
@@ -53626,6 +53854,9 @@ OUI:184617*
 OUI:1848D8*
  ID_OUI_FROM_DATABASE=Fastback Networks
 
+OUI:184A6F*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd
+
 OUI:184E94*
  ID_OUI_FROM_DATABASE=MESSOA TECHNOLOGIES INC.
 
@@ -53665,6 +53896,9 @@ OUI:1867B0*
 OUI:186D99*
  ID_OUI_FROM_DATABASE=Adanis Inc.
 
+OUI:187117*
+ ID_OUI_FROM_DATABASE=eta plus electronic gmbh
+
 OUI:1879A2*
  ID_OUI_FROM_DATABASE=GMJ ELECTRIC LIMITED
 
@@ -53683,9 +53917,15 @@ OUI:1880CE*
 OUI:1880F5*
  ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd
 
+OUI:188219*
+ ID_OUI_FROM_DATABASE=Alibaba Cloud Computing Ltd.
+
 OUI:188331*
  ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
 
+OUI:1883BF*
+ ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation
+
 OUI:188410*
  ID_OUI_FROM_DATABASE=CoreTrust Inc.
 
@@ -53725,8 +53965,11 @@ OUI:189EFC*
 OUI:18A905*
  ID_OUI_FROM_DATABASE=Hewlett-Packard Company
 
+OUI:18A958*
+ ID_OUI_FROM_DATABASE=PROVISION THAI CO., LTD.
+
 OUI:18A99B*
- ID_OUI_FROM_DATABASE=Dell Inc PCBA Test
+ ID_OUI_FROM_DATABASE=Dell Inc
 
 OUI:18AA45*
  ID_OUI_FROM_DATABASE=Fon Technology
@@ -53776,9 +54019,15 @@ OUI:18C8E7*
 OUI:18CC23*
  ID_OUI_FROM_DATABASE=Philio Technology Corporation
 
+OUI:18CF5E*
+ ID_OUI_FROM_DATABASE=Liteon Technology Corporation
+
 OUI:18D071*
  ID_OUI_FROM_DATABASE=DASAN SMC, Inc.
 
+OUI:18D5B6*
+ ID_OUI_FROM_DATABASE=SMG Holdings LLC
+
 OUI:18D66A*
  ID_OUI_FROM_DATABASE=Inmarsat
 
@@ -53824,6 +54073,9 @@ OUI:18F87A*
 OUI:18FA6F*
  ID_OUI_FROM_DATABASE=ISC applied systems corp
 
+OUI:18FB7B*
+ ID_OUI_FROM_DATABASE=Dell Inc
+
 OUI:18FC9F*
  ID_OUI_FROM_DATABASE=Changhe Electronics Co., Ltd.
 
@@ -53863,9 +54115,15 @@ OUI:1C184A*
 OUI:1C19DE*
  ID_OUI_FROM_DATABASE=eyevis GmbH
 
+OUI:1C1AC0*
+ ID_OUI_FROM_DATABASE=Apple
+
 OUI:1C1B68*
  ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
 
+OUI:1C1CFD*
+ ID_OUI_FROM_DATABASE=Dalian Hi-Think Computer Technology, Corp
+
 OUI:1C1D67*
  ID_OUI_FROM_DATABASE=Shenzhen Huawei Communication Technologies Co., Ltd
 
@@ -53902,6 +54160,9 @@ OUI:1C43EC*
 OUI:1C4593*
  ID_OUI_FROM_DATABASE=Texas Instruments
 
+OUI:1C4840*
+ ID_OUI_FROM_DATABASE=IMS Messsysteme GmbH
+
 OUI:1C48F9*
  ID_OUI_FROM_DATABASE=GN Netcom A/S
 
@@ -53917,6 +54178,9 @@ OUI:1C4BD6*
 OUI:1C51B5*
  ID_OUI_FROM_DATABASE=Techaya LTD
 
+OUI:1C5216*
+ ID_OUI_FROM_DATABASE=DONGGUAN HELE ELECTRONICS CO., LTD
+
 OUI:1C52D6*
  ID_OUI_FROM_DATABASE=FLAT DISPLAY TECHNOLOGY CORPORATION
 
@@ -53953,6 +54217,9 @@ OUI:1C66AA*
 OUI:1C69A5*
  ID_OUI_FROM_DATABASE=Research In Motion
 
+OUI:1C6A7A*
+ ID_OUI_FROM_DATABASE=Cisco
+
 OUI:1C6BCA*
  ID_OUI_FROM_DATABASE=Mitsunami Co., Ltd.
 
@@ -53980,6 +54247,9 @@ OUI:1C7C45*
 OUI:1C7CC7*
  ID_OUI_FROM_DATABASE=Coriant GmbH
 
+OUI:1C7E51*
+ ID_OUI_FROM_DATABASE=3bumen.com
+
 OUI:1C7EE5*
  ID_OUI_FROM_DATABASE=D-Link International
 
@@ -54010,12 +54280,24 @@ OUI:1C955D*
 OUI:1C959F*
  ID_OUI_FROM_DATABASE=Veethree Electronics And Marine LLC
 
+OUI:1C965A*
+ ID_OUI_FROM_DATABASE=Weifang goertek Electronics CO.,LTD
+
 OUI:1C973D*
  ID_OUI_FROM_DATABASE=PRICOM Design
 
 OUI:1C994C*
  ID_OUI_FROM_DATABASE=Murata Manufactuaring Co.,Ltd.
 
+OUI:1C9C26*
+ ID_OUI_FROM_DATABASE=Zoovel Technologies
+
+OUI:1C9ECB*
+ ID_OUI_FROM_DATABASE=Beijing Nari Smartchip Microelectronics Company Limited
+
+OUI:1CA2B1*
+ ID_OUI_FROM_DATABASE=ruwido austria gmbh
+
 OUI:1CA770*
  ID_OUI_FROM_DATABASE=SHENZHEN CHUANGWEI-RGB ELECTRONICS CO.,LT
 
@@ -54038,7 +54320,7 @@ OUI:1CB094*
  ID_OUI_FROM_DATABASE=HTC Corporation
 
 OUI:1CB17F*
- ID_OUI_FROM_DATABASE=NEC AccessTechnica, Ltd.
+ ID_OUI_FROM_DATABASE=NEC Platforms, Ltd.
 
 OUI:1CB243*
  ID_OUI_FROM_DATABASE=TDC A/S
@@ -54070,6 +54352,9 @@ OUI:1CC63C*
 OUI:1CD40C*
  ID_OUI_FROM_DATABASE=Kriwan Industrie-Elektronik GmbH
 
+OUI:1CDEA7*
+ ID_OUI_FROM_DATABASE=Cisco
+
 OUI:1CDF0F*
  ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
 
@@ -54139,6 +54424,9 @@ OUI:20107A*
 OUI:201257*
  ID_OUI_FROM_DATABASE=Most Lucky Trading Ltd
 
+OUI:2012D5*
+ ID_OUI_FROM_DATABASE=Scientech Materials Corporation
+
 OUI:2013E0*
  ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
 
@@ -54157,6 +54445,9 @@ OUI:201D03*
 OUI:2021A5*
  ID_OUI_FROM_DATABASE=LG Electronics Inc
 
+OUI:202564*
+ ID_OUI_FROM_DATABASE=PEGATRON CORPORATION
+
 OUI:202598*
  ID_OUI_FROM_DATABASE=Teleview
 
@@ -54202,6 +54493,9 @@ OUI:204E6B*
 OUI:204E7F*
  ID_OUI_FROM_DATABASE=NETGEAR
 
+OUI:2053CA*
+ ID_OUI_FROM_DATABASE=Risk Technology Ltd
+
 OUI:205476*
  ID_OUI_FROM_DATABASE=Sony Mobile Communications AB
 
@@ -54211,9 +54505,15 @@ OUI:205721*
 OUI:2059A0*
  ID_OUI_FROM_DATABASE=Paragon Technologies Inc.
 
+OUI:205A00*
+ ID_OUI_FROM_DATABASE=Coval
+
 OUI:205B5E*
  ID_OUI_FROM_DATABASE=Shenzhen Wonhe Technology Co., Ltd
 
+OUI:205CFA*
+ ID_OUI_FROM_DATABASE=Yangzhou ChangLian Network Technology Co,ltd.
+
 OUI:206432*
  ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO MECHANICS CO.,LTD.
 
@@ -54229,6 +54529,9 @@ OUI:206A8A*
 OUI:206AFF*
  ID_OUI_FROM_DATABASE=Atlas Elektronik UK Limited
 
+OUI:206E9C*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
 OUI:206FEC*
  ID_OUI_FROM_DATABASE=Braemac CA LLC
 
@@ -54241,6 +54544,9 @@ OUI:2074CF*
 OUI:207600*
  ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc
 
+OUI:207693*
+ ID_OUI_FROM_DATABASE=Lenovo (Beijing) Limited.
+
 OUI:207C8F*
  ID_OUI_FROM_DATABASE=Quanta Microsystems,Inc.
 
@@ -54265,12 +54571,24 @@ OUI:20918A*
 OUI:2091D9*
  ID_OUI_FROM_DATABASE=I'M SPA
 
+OUI:20934D*
+ ID_OUI_FROM_DATABASE=Fujian Star-net Communication Co., Ltd
+
+OUI:209AE9*
+ ID_OUI_FROM_DATABASE=Volacomm Co., Ltd
+
 OUI:209BA5*
  ID_OUI_FROM_DATABASE=JIAXING GLEAD Electronics Co.,Ltd
 
 OUI:20A2E7*
  ID_OUI_FROM_DATABASE=Lee-Dickens Ltd
 
+OUI:20A787*
+ ID_OUI_FROM_DATABASE=Bointec Taiwan Corporation Limited
+
+OUI:20A99B*
+ ID_OUI_FROM_DATABASE=Microsoft Corporation
+
 OUI:20AA25*
  ID_OUI_FROM_DATABASE=IP-NET LLC
 
@@ -54301,6 +54619,9 @@ OUI:20BFDB*
 OUI:20C1AF*
  ID_OUI_FROM_DATABASE=i Wit Digital Co., Limited
 
+OUI:20C38F*
+ ID_OUI_FROM_DATABASE=Texas Instruments Inc
+
 OUI:20C60D*
  ID_OUI_FROM_DATABASE=Shanghai annijie Information technology Co.,LTD
 
@@ -54361,6 +54682,9 @@ OUI:20E791*
 OUI:20EAC7*
  ID_OUI_FROM_DATABASE=SHENZHEN RIOPINE ELECTRONICS CO., LTD
 
+OUI:20ED74*
+ ID_OUI_FROM_DATABASE=Ability enterprise co.,Ltd.
+
 OUI:20EEC6*
  ID_OUI_FROM_DATABASE=Elefirst Science & Tech Co ., ltd
 
@@ -54394,6 +54718,9 @@ OUI:24050F*
 OUI:240917*
  ID_OUI_FROM_DATABASE=Devlin Electronics Limited
 
+OUI:240A11*
+ ID_OUI_FROM_DATABASE=TCT Mobile Limited
+
 OUI:240A64*
  ID_OUI_FROM_DATABASE=AzureWaveTechnologies,Inc
 
@@ -54442,6 +54769,9 @@ OUI:2437EF*
 OUI:243C20*
  ID_OUI_FROM_DATABASE=Dynamode Group
 
+OUI:2442BC*
+ ID_OUI_FROM_DATABASE=Alinco,incorporated
+
 OUI:244597*
  ID_OUI_FROM_DATABASE=GEMUE Gebr. Mueller Apparatebau
 
@@ -54451,6 +54781,9 @@ OUI:24470E*
 OUI:24497B*
  ID_OUI_FROM_DATABASE=Innovative Converged Devices Inc
 
+OUI:244F1D*
+ ID_OUI_FROM_DATABASE=iRule LLC
+
 OUI:245FDF*
  ID_OUI_FROM_DATABASE=KYOCERA Corporation
 
@@ -54502,6 +54835,9 @@ OUI:249442*
 OUI:249504*
  ID_OUI_FROM_DATABASE=SFR
 
+OUI:2497ED*
+ ID_OUI_FROM_DATABASE=Techvision Intelligent Technology Limited
+
 OUI:24A2E1*
  ID_OUI_FROM_DATABASE=Apple, Inc
 
@@ -54580,6 +54916,9 @@ OUI:24CBE7*
 OUI:24CF21*
  ID_OUI_FROM_DATABASE=Shenzhen State Micro Technology Co., Ltd
 
+OUI:24D13F*
+ ID_OUI_FROM_DATABASE=MEXUS CO.,LTD
+
 OUI:24D2CC*
  ID_OUI_FROM_DATABASE=SmartDrive Systems Inc.
 
@@ -54604,6 +54943,9 @@ OUI:24DEC6*
 OUI:24E271*
  ID_OUI_FROM_DATABASE=Qingdao Hisense Communications Co.,Ltd
 
+OUI:24E314*
+ ID_OUI_FROM_DATABASE=Apple
+
 OUI:24E6BA*
  ID_OUI_FROM_DATABASE=JSC Zavod im. Kozitsky
 
@@ -54682,6 +55024,9 @@ OUI:2826A6*
 OUI:28285D*
  ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
 
+OUI:2829CC*
+ ID_OUI_FROM_DATABASE=Corsa Technology Incorporated
+
 OUI:2829D9*
  ID_OUI_FROM_DATABASE=GlobalBeiMing technology (Beijing)Co. Ltd
 
@@ -54691,9 +55036,15 @@ OUI:282CB2*
 OUI:283152*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
 
+OUI:2832C5*
+ ID_OUI_FROM_DATABASE=Humax.co.,ltd
+
 OUI:283410*
  ID_OUI_FROM_DATABASE=Enigma Diagnostics Limited
 
+OUI:2834A2*
+ ID_OUI_FROM_DATABASE=Cisco
+
 OUI:283737*
  ID_OUI_FROM_DATABASE=Apple
 
@@ -54730,6 +55081,9 @@ OUI:284C53*
 OUI:284D92*
  ID_OUI_FROM_DATABASE=Luminator
 
+OUI:284ED7*
+ ID_OUI_FROM_DATABASE=OutSmart Power Systems, Inc.
+
 OUI:284FCE*
  ID_OUI_FROM_DATABASE=Liaoning Wontel Science and Technology Development Co.,Ltd.
 
@@ -54778,6 +55132,9 @@ OUI:2872F0*
 OUI:287994*
  ID_OUI_FROM_DATABASE=Realplay Digital Technology(Shenzhen) Co.,Ltd
 
+OUI:288023*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
 OUI:28852D*
  ID_OUI_FROM_DATABASE=Touch Networks
 
@@ -54829,6 +55186,9 @@ OUI:28A241*
 OUI:28A574*
  ID_OUI_FROM_DATABASE=Miller Electric Mfg. Co.
 
+OUI:28A5EE*
+ ID_OUI_FROM_DATABASE=Shenzhen SDGI CATV Co., Ltd
+
 OUI:28AF0A*
  ID_OUI_FROM_DATABASE=Sirius XM Radio Inc
 
@@ -54865,6 +55225,9 @@ OUI:28C68E*
 OUI:28C718*
  ID_OUI_FROM_DATABASE=Altierre
 
+OUI:28C7CE*
+ ID_OUI_FROM_DATABASE=Cisco
+
 OUI:28C825*
  ID_OUI_FROM_DATABASE=DellKing Industrial Co., Ltd
 
@@ -54925,12 +55288,18 @@ OUI:28E14C*
 OUI:28E297*
  ID_OUI_FROM_DATABASE=Shanghai InfoTM Microelectronics Co.,Ltd.
 
+OUI:28E31F*
+ ID_OUI_FROM_DATABASE=Xiaomi inc.
+
 OUI:28E347*
  ID_OUI_FROM_DATABASE=Liteon Technology Corporation
 
 OUI:28E608*
  ID_OUI_FROM_DATABASE=Tokheim
 
+OUI:28E6E9*
+ ID_OUI_FROM_DATABASE=SIS Sat Internet Services GmbH
+
 OUI:28E794*
  ID_OUI_FROM_DATABASE=Microtime Computer Inc.
 
@@ -54958,6 +55327,9 @@ OUI:28FBD3*
 OUI:28FC51*
  ID_OUI_FROM_DATABASE=The Electric Controller and Manufacturing Co., LLC
 
+OUI:28FCF6*
+ ID_OUI_FROM_DATABASE=Shenzhen Xin KingBrand enterprises Co.,Ltd
+
 OUI:2C002C*
  ID_OUI_FROM_DATABASE=UNOWHY
 
@@ -54967,6 +55339,9 @@ OUI:2C0033*
 OUI:2C00F7*
  ID_OUI_FROM_DATABASE=XOS
 
+OUI:2C010B*
+ ID_OUI_FROM_DATABASE=NASCENT Technology, LLC - RemKon
+
 OUI:2C0623*
  ID_OUI_FROM_DATABASE=Win Leader Inc.
 
@@ -54982,6 +55357,9 @@ OUI:2C18AE*
 OUI:2C1984*
  ID_OUI_FROM_DATABASE=IDN Telecom, Inc.
 
+OUI:2C1A31*
+ ID_OUI_FROM_DATABASE=Electronics Company Limited
+
 OUI:2C1EEA*
  ID_OUI_FROM_DATABASE=AERODEV
 
@@ -55000,6 +55378,9 @@ OUI:2C27D7*
 OUI:2C282D*
  ID_OUI_FROM_DATABASE=BBK COMMUNICATIAO TECHNOLOGY CO.,LTD.
 
+OUI:2C2997*
+ ID_OUI_FROM_DATABASE=Microsoft Corporation
+
 OUI:2C2D48*
  ID_OUI_FROM_DATABASE=bct electronic GesmbH
 
@@ -55021,9 +55402,15 @@ OUI:2C36F8*
 OUI:2C3731*
  ID_OUI_FROM_DATABASE=ShenZhen Yifang Digital Technology Co.,LTD
 
+OUI:2C3796*
+ ID_OUI_FROM_DATABASE=CYBO CO.,LTD.
+
 OUI:2C3996*
  ID_OUI_FROM_DATABASE=SAGEMCOM
 
+OUI:2C39C1*
+ ID_OUI_FROM_DATABASE=Ciena Corporation
+
 OUI:2C3A28*
  ID_OUI_FROM_DATABASE=Fagor Electrónica
 
@@ -55051,12 +55438,18 @@ OUI:2C441B*
 OUI:2C44FD*
  ID_OUI_FROM_DATABASE=Hewlett Packard
 
+OUI:2C5089*
+ ID_OUI_FROM_DATABASE=Shenzhen Kaixuan Visual Technology Co.,Limited
+
 OUI:2C534A*
  ID_OUI_FROM_DATABASE=Shenzhen Winyao Electronic Limited
 
 OUI:2C542D*
  ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
 
+OUI:2C54CF*
+ ID_OUI_FROM_DATABASE=LG Electronics
+
 OUI:2C553C*
  ID_OUI_FROM_DATABASE=Gainspeed, Inc.
 
@@ -55069,12 +55462,18 @@ OUI:2C5A05*
 OUI:2C5AA3*
  ID_OUI_FROM_DATABASE=PROMATE ELECTRONIC CO.LTD
 
+OUI:2C5BE1*
+ ID_OUI_FROM_DATABASE=Centripetal Networks, Inc
+
 OUI:2C5D93*
  ID_OUI_FROM_DATABASE=Ruckus Wireless
 
 OUI:2C5FF3*
  ID_OUI_FROM_DATABASE=Pertronic Industries
 
+OUI:2C600C*
+ ID_OUI_FROM_DATABASE=QUANTA COMPUTER INC.
+
 OUI:2C625A*
  ID_OUI_FROM_DATABASE=Finest Security Systems Co., Ltd
 
@@ -55117,6 +55516,9 @@ OUI:2C8065*
 OUI:2C8158*
  ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd
 
+OUI:2C8A72*
+ ID_OUI_FROM_DATABASE=HTC Corporation
+
 OUI:2C8BF2*
  ID_OUI_FROM_DATABASE=Hitachi Metals America Ltd
 
@@ -55135,6 +55537,9 @@ OUI:2C957F*
 OUI:2C9717*
  ID_OUI_FROM_DATABASE=I.C.Y. B.V.
 
+OUI:2C9AA4*
+ ID_OUI_FROM_DATABASE=NGI SpA
+
 OUI:2C9E5F*
  ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
 
@@ -55144,6 +55549,9 @@ OUI:2C9EFC*
 OUI:2CA157*
  ID_OUI_FROM_DATABASE=acromate, Inc.
 
+OUI:2CA30E*
+ ID_OUI_FROM_DATABASE=POWER DRAGON DEVELOPMENT LIMITED
+
 OUI:2CA780*
  ID_OUI_FROM_DATABASE=True Technologies Inc.
 
@@ -55153,6 +55561,9 @@ OUI:2CA835*
 OUI:2CAB25*
  ID_OUI_FROM_DATABASE=Shenzhen Gongjin Electronics Co.,Ltd
 
+OUI:2CABA4*
+ ID_OUI_FROM_DATABASE=Cisco SPVTG
+
 OUI:2CB05D*
  ID_OUI_FROM_DATABASE=NETGEAR
 
@@ -55168,6 +55579,9 @@ OUI:2CB693*
 OUI:2CB69D*
  ID_OUI_FROM_DATABASE=RED Digital Cinema
 
+OUI:2CBE08*
+ ID_OUI_FROM_DATABASE=Apple
+
 OUI:2CBE97*
  ID_OUI_FROM_DATABASE=Ingenieurbuero Bickele und Buehler GmbH
 
@@ -55219,21 +55633,36 @@ OUI:2CEDEB*
 OUI:2CEE26*
  ID_OUI_FROM_DATABASE=Petroleum Geo-Services
 
+OUI:2CF0EE*
+ ID_OUI_FROM_DATABASE=Apple
+
 OUI:2CF203*
  ID_OUI_FROM_DATABASE=EMKO ELEKTRONIK SAN VE TIC AS
 
 OUI:2CF4C5*
  ID_OUI_FROM_DATABASE=Avaya, Inc
 
+OUI:2CF7F1*
+ ID_OUI_FROM_DATABASE=Seeed Technology Inc.
+
+OUI:2CFAA2*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent
+
 OUI:30055C*
  ID_OUI_FROM_DATABASE=Brother industries, LTD.
 
 OUI:300B9C*
  ID_OUI_FROM_DATABASE=Delta Mobile Systems, Inc.
 
+OUI:300D2A*
+ ID_OUI_FROM_DATABASE=Zhejiang Wellcom Technology Co.,Ltd.
+
 OUI:300ED5*
  ID_OUI_FROM_DATABASE=Hon Hai Precision Ind.Co.Ltd
 
+OUI:3010B3*
+ ID_OUI_FROM_DATABASE=Liteon Technology Corporation
+
 OUI:3010E4*
  ID_OUI_FROM_DATABASE=Apple, Inc.
 
@@ -55273,6 +55702,9 @@ OUI:303294*
 OUI:3032D4*
  ID_OUI_FROM_DATABASE=Hanilstm Co., Ltd.
 
+OUI:303335*
+ ID_OUI_FROM_DATABASE=Boosty
+
 OUI:3037A6*
  ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
 
@@ -55300,6 +55732,9 @@ OUI:303EAD*
 OUI:304174*
  ID_OUI_FROM_DATABASE=ALTEC LANSING LLC
 
+OUI:304225*
+ ID_OUI_FROM_DATABASE=BURG-WÄCHTER KG
+
 OUI:304449*
  ID_OUI_FROM_DATABASE=PLATH GmbH
 
@@ -55327,6 +55762,12 @@ OUI:3055ED*
 OUI:3057AC*
  ID_OUI_FROM_DATABASE=IRLAB LTD.
 
+OUI:30595B*
+ ID_OUI_FROM_DATABASE=streamnow AG
+
+OUI:3059B7*
+ ID_OUI_FROM_DATABASE=Microsoft
+
 OUI:305D38*
  ID_OUI_FROM_DATABASE=Beissbarth
 
@@ -55357,9 +55798,18 @@ OUI:306E5C*
 OUI:3071B2*
  ID_OUI_FROM_DATABASE=Hangzhou Prevail Optoelectronic Equipment Co.,LTD.
 
+OUI:307350*
+ ID_OUI_FROM_DATABASE=Inpeco SA
+
+OUI:307512*
+ ID_OUI_FROM_DATABASE=Sony Mobile Communications AB
+
 OUI:30766F*
  ID_OUI_FROM_DATABASE=LG Electronics
 
+OUI:3077CB*
+ ID_OUI_FROM_DATABASE=Maike Industry(Shenzhen)CO.,LTD
+
 OUI:30786B*
  ID_OUI_FROM_DATABASE=TIANJIN Golden Pentagon Electronics Co., Ltd.
 
@@ -55387,6 +55837,9 @@ OUI:308CFB*
 OUI:3090AB*
  ID_OUI_FROM_DATABASE=Apple
 
+OUI:30918F*
+ ID_OUI_FROM_DATABASE=Technicolor
+
 OUI:3092F6*
  ID_OUI_FROM_DATABASE=SHANGHAI SUNMON COMMUNICATION TECHNOGY CO.,LTD
 
@@ -55414,15 +55867,24 @@ OUI:30B3A2*
 OUI:30B5C2*
  ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
 
+OUI:30B5F1*
+ ID_OUI_FROM_DATABASE=Aitexin Technology Co., Ltd
+
 OUI:30C750*
  ID_OUI_FROM_DATABASE=MIC Technology Group
 
+OUI:30C7AE*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
 OUI:30C82A*
  ID_OUI_FROM_DATABASE=Wi-Next s.r.l.
 
 OUI:30CDA7*
  ID_OUI_FROM_DATABASE=Samsung Electronics ITS, Printer division
 
+OUI:30D17E*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
 OUI:30D357*
  ID_OUI_FROM_DATABASE=Logosol, Inc.
 
@@ -55462,18 +55924,36 @@ OUI:30F70D*
 OUI:30F7C5*
  ID_OUI_FROM_DATABASE=Apple
 
+OUI:30F7D7*
+ ID_OUI_FROM_DATABASE=Thread Technology Co., Ltd
+
 OUI:30F9ED*
  ID_OUI_FROM_DATABASE=Sony Corporation
 
+OUI:30FAB7*
+ ID_OUI_FROM_DATABASE=Tunai Creative
+
 OUI:30FD11*
  ID_OUI_FROM_DATABASE=MACROTECH (USA) INC.
 
+OUI:3400A3*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:340286*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:34029B*
+ ID_OUI_FROM_DATABASE=CloudBerry Technologies Private Limited
+
 OUI:3407FB*
  ID_OUI_FROM_DATABASE=Ericsson AB
 
 OUI:340804*
  ID_OUI_FROM_DATABASE=D-Link Corporation
 
+OUI:340AFF*
+ ID_OUI_FROM_DATABASE=Qingdao Hisense Communications Co.,Ltd
+
 OUI:3413A8*
  ID_OUI_FROM_DATABASE=Mediplan Limited
 
@@ -55484,7 +55964,7 @@ OUI:34159E*
  ID_OUI_FROM_DATABASE=Apple
 
 OUI:3417EB*
- ID_OUI_FROM_DATABASE=Dell Inc PCBA Test
+ ID_OUI_FROM_DATABASE=Dell Inc
 
 OUI:341A4C*
  ID_OUI_FROM_DATABASE=SHENZHEN WEIBU ELECTRONICS CO.,LTD.
@@ -55504,6 +55984,9 @@ OUI:3423BA*
 OUI:34255D*
  ID_OUI_FROM_DATABASE=Shenzhen Loadcom Technology Co.,Ltd
 
+OUI:3428F0*
+ ID_OUI_FROM_DATABASE=ATN International Limited
+
 OUI:3429EA*
  ID_OUI_FROM_DATABASE=MCD ELECTRONICS SP. Z O.O.
 
@@ -55513,6 +55996,12 @@ OUI:342F6E*
 OUI:343111*
  ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
 
+OUI:3431C4*
+ ID_OUI_FROM_DATABASE=AVM GmbH
+
+OUI:3438AF*
+ ID_OUI_FROM_DATABASE=Inlab Software GmbH
+
 OUI:3440B5*
  ID_OUI_FROM_DATABASE=IBM
 
@@ -55525,6 +56014,12 @@ OUI:344B3D*
 OUI:344B50*
  ID_OUI_FROM_DATABASE=ZTE Corporation
 
+OUI:344DEA*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:344DF7*
+ ID_OUI_FROM_DATABASE=LG Electronics
+
 OUI:344F3F*
  ID_OUI_FROM_DATABASE=IO-Power Technology Co., Ltd.
 
@@ -55534,6 +56029,9 @@ OUI:344F5C*
 OUI:344F69*
  ID_OUI_FROM_DATABASE=EKINOPS SAS
 
+OUI:3451AA*
+ ID_OUI_FROM_DATABASE=JID GLOBAL
+
 OUI:3451C9*
  ID_OUI_FROM_DATABASE=Apple
 
@@ -55543,9 +56041,18 @@ OUI:345B11*
 OUI:345C40*
  ID_OUI_FROM_DATABASE=Cargt Holdings LLC
 
+OUI:345D10*
+ ID_OUI_FROM_DATABASE=Wytek
+
 OUI:346178*
  ID_OUI_FROM_DATABASE=The Boeing Company
 
+OUI:346288*
+ ID_OUI_FROM_DATABASE=Cisco
+
+OUI:3464A9*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
 OUI:34684A*
  ID_OUI_FROM_DATABASE=Teraworks Co., Ltd.
 
@@ -55573,6 +56080,9 @@ OUI:347E39*
 OUI:348137*
  ID_OUI_FROM_DATABASE=UNICARD SA
 
+OUI:3481C4*
+ ID_OUI_FROM_DATABASE=AVM GmbH
+
 OUI:3482DE*
  ID_OUI_FROM_DATABASE=Kayo Technology, Inc.
 
@@ -55657,6 +56167,9 @@ OUI:34B1F7*
 OUI:34B571*
  ID_OUI_FROM_DATABASE=PLDS
 
+OUI:34B7FD*
+ ID_OUI_FROM_DATABASE=Guangzhou Younghead Electronic Technology Co.,Ltd
+
 OUI:34BA51*
  ID_OUI_FROM_DATABASE=Se-Kure Controls, Inc.
 
@@ -55666,6 +56179,9 @@ OUI:34BA9A*
 OUI:34BB1F*
  ID_OUI_FROM_DATABASE=Research In Motion
 
+OUI:34BB26*
+ ID_OUI_FROM_DATABASE=Motorola Mobility LLC
+
 OUI:34BCA6*
  ID_OUI_FROM_DATABASE=Beijing Ding Qing Technology, Ltd.
 
@@ -55690,6 +56206,9 @@ OUI:34C059*
 OUI:34C3AC*
  ID_OUI_FROM_DATABASE=Samsung Electronics
 
+OUI:34C5D0*
+ ID_OUI_FROM_DATABASE=Hagleitner Hygiene International GmbH
+
 OUI:34C69A*
  ID_OUI_FROM_DATABASE=Enecsys Ltd
 
@@ -55741,18 +56260,30 @@ OUI:34E0D7*
 OUI:34E2FD*
  ID_OUI_FROM_DATABASE=Apple
 
+OUI:34E42A*
+ ID_OUI_FROM_DATABASE=Automatic Bar Controls Inc.
+
+OUI:34E6AD*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
 OUI:34EF44*
  ID_OUI_FROM_DATABASE=2Wire
 
 OUI:34EF8B*
  ID_OUI_FROM_DATABASE=NTT Communications Corporation
 
+OUI:34F0CA*
+ ID_OUI_FROM_DATABASE=Shenzhen Linghangyuan Digital Technology Co.,Ltd.
+
 OUI:34F39B*
  ID_OUI_FROM_DATABASE=WizLAN Ltd.
 
 OUI:34F62D*
  ID_OUI_FROM_DATABASE=SHARP Corporation
 
+OUI:34F6D2*
+ ID_OUI_FROM_DATABASE=Panasonic Taiwan Co.,Ltd.
+
 OUI:34F968*
  ID_OUI_FROM_DATABASE=ATEK Products, LLC
 
@@ -55768,6 +56299,9 @@ OUI:380197*
 OUI:3806B4*
  ID_OUI_FROM_DATABASE=A.D.C. GmbH
 
+OUI:3808FD*
+ ID_OUI_FROM_DATABASE=Silca Spa
+
 OUI:380A0A*
  ID_OUI_FROM_DATABASE=Sky-City Communication and Electronics Limited Company
 
@@ -55780,6 +56314,9 @@ OUI:380B40*
 OUI:380DD4*
  ID_OUI_FROM_DATABASE=Primax Electronics LTD.
 
+OUI:380E7B*
+ ID_OUI_FROM_DATABASE=V.P.S. Thai Co., Ltd
+
 OUI:380F4A*
  ID_OUI_FROM_DATABASE=Apple
 
@@ -55795,6 +56332,9 @@ OUI:381766*
 OUI:38192F*
  ID_OUI_FROM_DATABASE=Nokia Corporation
 
+OUI:381C1A*
+ ID_OUI_FROM_DATABASE=Cisco
+
 OUI:381C4A*
  ID_OUI_FROM_DATABASE=SIMCom Wireless Solutions Co.,Ltd.
 
@@ -55804,15 +56344,27 @@ OUI:38229D*
 OUI:3822D6*
  ID_OUI_FROM_DATABASE=H3C Technologies Co., Limited
 
+OUI:38262B*
+ ID_OUI_FROM_DATABASE=UTran Technology
+
 OUI:3826CD*
  ID_OUI_FROM_DATABASE=ANDTEK
 
 OUI:3828EA*
  ID_OUI_FROM_DATABASE=Fujian Netcom Technology Co., LTD
 
+OUI:382C4A*
+ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
+
+OUI:382DD1*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
 OUI:3831AC*
  ID_OUI_FROM_DATABASE=WEG
 
+OUI:383BC8*
+ ID_OUI_FROM_DATABASE=2wire
+
 OUI:383F10*
  ID_OUI_FROM_DATABASE=DBL Technology Ltd.
 
@@ -55834,6 +56386,9 @@ OUI:384608*
 OUI:38484C*
  ID_OUI_FROM_DATABASE=Apple
 
+OUI:384B76*
+ ID_OUI_FROM_DATABASE=AIRTAME ApS
+
 OUI:384FF0*
  ID_OUI_FROM_DATABASE=Azurewave Technologies, Inc.
 
@@ -55897,6 +56452,9 @@ OUI:388EE7*
 OUI:3891FB*
  ID_OUI_FROM_DATABASE=Xenox Holding BV
 
+OUI:389496*
+ ID_OUI_FROM_DATABASE=Samsung Elec Co.,Ltd
+
 OUI:389592*
  ID_OUI_FROM_DATABASE=Beijing Tendyron Corporation
 
@@ -55924,6 +56482,9 @@ OUI:38AA3C*
 OUI:38B12D*
  ID_OUI_FROM_DATABASE=Sonotronic Nagel GmbH
 
+OUI:38B1DB*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
 OUI:38B5BD*
  ID_OUI_FROM_DATABASE=E.G.O. Elektro-Ger
 
@@ -55933,6 +56494,9 @@ OUI:38B74D*
 OUI:38BB23*
  ID_OUI_FROM_DATABASE=OzVision America LLC
 
+OUI:38BB3C*
+ ID_OUI_FROM_DATABASE=Avaya, Inc
+
 OUI:38BC1A*
  ID_OUI_FROM_DATABASE=Meizu technology co.,ltd
 
@@ -55996,12 +56560,18 @@ OUI:38EE9D*
 OUI:38F098*
  ID_OUI_FROM_DATABASE=Vapor Stone Rail Systems
 
+OUI:38F33F*
+ ID_OUI_FROM_DATABASE=TATSUNO CORPORATION
+
 OUI:38F597*
  ID_OUI_FROM_DATABASE=home2net GmbH
 
 OUI:38F708*
  ID_OUI_FROM_DATABASE=National Resource Management, Inc.
 
+OUI:38F889*
+ ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd
+
 OUI:38F8B7*
  ID_OUI_FROM_DATABASE=V2COM PARTICIPACOES S.A.
 
@@ -56053,6 +56623,9 @@ OUI:3C15C2*
 OUI:3C15EA*
  ID_OUI_FROM_DATABASE=TESCOM CO., LTD.
 
+OUI:3C189F*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
 OUI:3C18A0*
  ID_OUI_FROM_DATABASE=Luxshare Precision Industry Co.,Ltd.
 
@@ -56071,6 +56644,9 @@ OUI:3C1A79*
 OUI:3C1CBE*
  ID_OUI_FROM_DATABASE=JADAK LLC
 
+OUI:3C1E13*
+ ID_OUI_FROM_DATABASE=HANGZHOU SUNRISE TECHNOLOGY CO., LTD
+
 OUI:3C25D7*
  ID_OUI_FROM_DATABASE=Nokia Corporation
 
@@ -56110,6 +56686,9 @@ OUI:3C404F*
 OUI:3C438E*
  ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
 
+OUI:3C46D8*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+
 OUI:3C4A92*
  ID_OUI_FROM_DATABASE=Hewlett-Packard Company
 
@@ -56128,6 +56707,9 @@ OUI:3C57D5*
 OUI:3C5A37*
  ID_OUI_FROM_DATABASE=Samsung Electronics
 
+OUI:3C5AB4*
+ ID_OUI_FROM_DATABASE=Google
+
 OUI:3C5F01*
  ID_OUI_FROM_DATABASE=Synerchip Co., Ltd.
 
@@ -56215,6 +56797,9 @@ OUI:3C99F7*
 OUI:3C9F81*
  ID_OUI_FROM_DATABASE=Shenzhen CATIC Bit Communications Technology Co.,Ltd
 
+OUI:3CA10D*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
 OUI:3CA315*
  ID_OUI_FROM_DATABASE=Bless Information & Communications Co., Ltd
 
@@ -56224,6 +56809,12 @@ OUI:3CA72B*
 OUI:3CA9F4*
  ID_OUI_FROM_DATABASE=Intel Corporate
 
+OUI:3CAA3F*
+ ID_OUI_FROM_DATABASE=iKey, Ltd.
+
+OUI:3CAB8E*
+ ID_OUI_FROM_DATABASE=Apple
+
 OUI:3CB15B*
  ID_OUI_FROM_DATABASE=Avaya, Inc
 
@@ -56254,6 +56845,9 @@ OUI:3CC99E*
 OUI:3CCA87*
  ID_OUI_FROM_DATABASE=Iders Incorporated
 
+OUI:3CCD5A*
+ ID_OUI_FROM_DATABASE=Technische Alternative GmbH
+
 OUI:3CCD93*
  ID_OUI_FROM_DATABASE=LG ELECTRONICS INC
 
@@ -56275,6 +56869,9 @@ OUI:3CD7DA*
 OUI:3CD92B*
  ID_OUI_FROM_DATABASE=Hewlett-Packard Company
 
+OUI:3CD9CE*
+ ID_OUI_FROM_DATABASE=Eclipse WiFi
+
 OUI:3CDF1E*
  ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
 
@@ -56311,6 +56908,9 @@ OUI:3CF72A*
 OUI:3CF748*
  ID_OUI_FROM_DATABASE=Shenzhen Linsn Technology Development Co.,Ltd
 
+OUI:3CF808*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
 OUI:3CFB96*
  ID_OUI_FROM_DATABASE=Emcraft Systems LLC
 
@@ -56341,6 +56941,9 @@ OUI:4013D9*
 OUI:401597*
  ID_OUI_FROM_DATABASE=Protect America, Inc.
 
+OUI:40167E*
+ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
+
 OUI:40169F*
  ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO., LTD.
 
@@ -56392,6 +56995,9 @@ OUI:404022*
 OUI:40406B*
  ID_OUI_FROM_DATABASE=Icomera
 
+OUI:4045DA*
+ ID_OUI_FROM_DATABASE=Spreadtrum Communications (Shanghai) Co., Ltd.
+
 OUI:404A03*
  ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
 
@@ -56401,6 +57007,9 @@ OUI:404A18*
 OUI:404D8E*
  ID_OUI_FROM_DATABASE=Shenzhen Huawei Communication Technologies Co., Ltd
 
+OUI:404EEB*
+ ID_OUI_FROM_DATABASE=Higher Way Electronic Co., Ltd.
+
 OUI:4050E0*
  ID_OUI_FROM_DATABASE=Milton Security Group LLC
 
@@ -56461,6 +57070,9 @@ OUI:407074*
 OUI:407496*
  ID_OUI_FROM_DATABASE=aFUN TECHNOLOGY INC.
 
+OUI:40786A*
+ ID_OUI_FROM_DATABASE=Motorola Mobility LLC
+
 OUI:407875*
  ID_OUI_FROM_DATABASE=IMBEL - Industria de Material Belico do Brasil
 
@@ -56470,6 +57082,9 @@ OUI:407A80*
 OUI:407B1B*
  ID_OUI_FROM_DATABASE=Mettle Networks Inc.
 
+OUI:408256*
+ ID_OUI_FROM_DATABASE=Continental Automotive GmbH
+
 OUI:4083DE*
  ID_OUI_FROM_DATABASE=Motorola
 
@@ -56503,6 +57118,9 @@ OUI:40984E*
 OUI:40987B*
  ID_OUI_FROM_DATABASE=Aisino Corporation
 
+OUI:409B0D*
+ ID_OUI_FROM_DATABASE=Shenzhen Yourf Kwan Industrial Co., Ltd
+
 OUI:409FC7*
  ID_OUI_FROM_DATABASE=BAEKCHUN I&C Co., Ltd.
 
@@ -56527,6 +57145,9 @@ OUI:40B2C8*
 OUI:40B395*
  ID_OUI_FROM_DATABASE=Apple
 
+OUI:40B3CD*
+ ID_OUI_FROM_DATABASE=Chiyoda Electronics Co.,Ltd.
+
 OUI:40B3FC*
  ID_OUI_FROM_DATABASE=Logital Co. Limited
 
@@ -56560,6 +57181,9 @@ OUI:40C245*
 OUI:40C4D6*
  ID_OUI_FROM_DATABASE=ChongQing Camyu Technology Development Co.,Ltd.
 
+OUI:40C62A*
+ ID_OUI_FROM_DATABASE=Shanghai Jing Ren Electronic Technology Co., Ltd.
+
 OUI:40C7C9*
  ID_OUI_FROM_DATABASE=Naviit Inc.
 
@@ -56578,6 +57202,9 @@ OUI:40D40E*
 OUI:40D559*
  ID_OUI_FROM_DATABASE=MICRO S.E.R.I.
 
+OUI:40E230*
+ ID_OUI_FROM_DATABASE=AzureWave Technologies, Inc.
+
 OUI:40E730*
  ID_OUI_FROM_DATABASE=DEY Storage Systems, Inc.
 
@@ -56596,6 +57223,9 @@ OUI:40F02F*
 OUI:40F14C*
  ID_OUI_FROM_DATABASE=ISE Europe SPRL
 
+OUI:40F201*
+ ID_OUI_FROM_DATABASE=SAGEMCOM
+
 OUI:40F2E9*
  ID_OUI_FROM_DATABASE=IBM
 
@@ -56632,6 +57262,9 @@ OUI:44184F*
 OUI:4419B6*
  ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd.
 
+OUI:441E91*
+ ID_OUI_FROM_DATABASE=ARVIDA Intelligent Electronics Technology  Co.,Ltd.
+
 OUI:441EA1*
  ID_OUI_FROM_DATABASE=Hewlett-Packard Company
 
@@ -56737,6 +57370,9 @@ OUI:446132*
 OUI:44619C*
  ID_OUI_FROM_DATABASE=FONsystem co. ltd.
 
+OUI:44666E*
+ ID_OUI_FROM_DATABASE=IP-LINE
+
 OUI:446755*
  ID_OUI_FROM_DATABASE=Orbit Irrigation
 
@@ -56749,12 +57385,18 @@ OUI:446C24*
 OUI:446D57*
  ID_OUI_FROM_DATABASE=Liteon Technology Corporation
 
+OUI:446D6C*
+ ID_OUI_FROM_DATABASE=Samsung Elec Co.,Ltd
+
 OUI:44700B*
  ID_OUI_FROM_DATABASE=IFFU
 
 OUI:447098*
  ID_OUI_FROM_DATABASE=MING HONG TECHNOLOGY (SHEN ZHEN) LIMITED
 
+OUI:44746C*
+ ID_OUI_FROM_DATABASE=Sony Mobile Communications AB
+
 OUI:447BC4*
  ID_OUI_FROM_DATABASE=DualShine Technology(SZ)Co.,Ltd
 
@@ -56776,9 +57418,15 @@ OUI:448312*
 OUI:448500*
  ID_OUI_FROM_DATABASE=Intel Corporate
 
+OUI:4486C1*
+ ID_OUI_FROM_DATABASE=Siemens Low Voltage & Products
+
 OUI:4487FC*
  ID_OUI_FROM_DATABASE=ELITEGROUP COMPUTER SYSTEM CO., LTD.
 
+OUI:4488CB*
+ ID_OUI_FROM_DATABASE=Camco Technologies NV
+
 OUI:448A5B*
  ID_OUI_FROM_DATABASE=Micro-Star INT'L CO., LTD.
 
@@ -56812,6 +57460,9 @@ OUI:44A42D*
 OUI:44A689*
  ID_OUI_FROM_DATABASE=PROMAX ELECTRONICA SA
 
+OUI:44A6E5*
+ ID_OUI_FROM_DATABASE=THINKING TECHNOLOGY CO.,LTD
+
 OUI:44A7CF*
  ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
 
@@ -56851,6 +57502,9 @@ OUI:44C56F*
 OUI:44C9A2*
  ID_OUI_FROM_DATABASE=Greenwald Industries
 
+OUI:44CE7D*
+ ID_OUI_FROM_DATABASE=SFR
+
 OUI:44D15E*
  ID_OUI_FROM_DATABASE=Shanghai Kingto Information Technology Ltd
 
@@ -56860,6 +57514,9 @@ OUI:44D2CA*
 OUI:44D3CA*
  ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
 
+OUI:44D4E0*
+ ID_OUI_FROM_DATABASE=Sony Mobile Communications AB
+
 OUI:44D63D*
  ID_OUI_FROM_DATABASE=Talari Networks
 
@@ -56908,6 +57565,9 @@ OUI:48022A*
 OUI:480362*
  ID_OUI_FROM_DATABASE=DESAY ELECTRONICS(HUIZHOU)CO.,LTD
 
+OUI:480C49*
+ ID_OUI_FROM_DATABASE=NAKAYO TELECOMMUNICATIONS,INC
+
 OUI:481249*
  ID_OUI_FROM_DATABASE=Luxcom Technologies Inc.
 
@@ -56920,9 +57580,15 @@ OUI:48174C*
 OUI:481842*
  ID_OUI_FROM_DATABASE=Shanghai Winaas Co. Equipment Co. Ltd.
 
+OUI:481A84*
+ ID_OUI_FROM_DATABASE=Pointer Telocation Ltd
+
 OUI:481BD2*
  ID_OUI_FROM_DATABASE=Intron Scientific co., ltd.
 
+OUI:4826E8*
+ ID_OUI_FROM_DATABASE=Tek-Air Systems, Inc.
+
 OUI:48282F*
  ID_OUI_FROM_DATABASE=ZTE Corporation
 
@@ -56950,9 +57616,18 @@ OUI:4846F1*
 OUI:4846FB*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
 
+OUI:4851B7*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
 OUI:485261*
  ID_OUI_FROM_DATABASE=SOREEL
 
+OUI:4857DD*
+ ID_OUI_FROM_DATABASE=Facebook
+
+OUI:485929*
+ ID_OUI_FROM_DATABASE=LG Electronics
+
 OUI:485A3F*
  ID_OUI_FROM_DATABASE=WISOL
 
@@ -56971,6 +57646,12 @@ OUI:4860BC*
 OUI:4861A3*
  ID_OUI_FROM_DATABASE=Concern "Axion" JSC
 
+OUI:486276*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:486B2C*
+ ID_OUI_FROM_DATABASE=BBK Electronics Corp., Ltd.,
+
 OUI:486B91*
  ID_OUI_FROM_DATABASE=Fleetwood Group Inc.
 
@@ -56986,6 +57667,9 @@ OUI:487119*
 OUI:48746E*
  ID_OUI_FROM_DATABASE=Apple
 
+OUI:488244*
+ ID_OUI_FROM_DATABASE=Life Fitness / Div. of Brunswick
+
 OUI:488E42*
  ID_OUI_FROM_DATABASE=DIGALOG GmbH
 
@@ -56998,6 +57682,9 @@ OUI:4891F6*
 OUI:489BE2*
  ID_OUI_FROM_DATABASE=SCI Innovations Ltd
 
+OUI:489D18*
+ ID_OUI_FROM_DATABASE=Flashbay Limited
+
 OUI:489D24*
  ID_OUI_FROM_DATABASE=Research In Motion
 
@@ -57046,15 +57733,24 @@ OUI:48CB6E*
 OUI:48D0CF*
  ID_OUI_FROM_DATABASE=Universal Electronics, Inc.
 
+OUI:48D18E*
+ ID_OUI_FROM_DATABASE=Metis Communication Co.,Ltd
+
 OUI:48D224*
  ID_OUI_FROM_DATABASE=Liteon Technology Corporation
 
 OUI:48D54C*
  ID_OUI_FROM_DATABASE=Jeda Networks
 
+OUI:48D705*
+ ID_OUI_FROM_DATABASE=Apple
+
 OUI:48D7FF*
  ID_OUI_FROM_DATABASE=BLANKOM Antennentechnik GmbH
 
+OUI:48D855*
+ ID_OUI_FROM_DATABASE=Telvent
+
 OUI:48D8FE*
  ID_OUI_FROM_DATABASE=ClarIDy Solutions, Inc.
 
@@ -57127,6 +57823,9 @@ OUI:4C09B4*
 OUI:4C0B3A*
  ID_OUI_FROM_DATABASE=TCT Mobile Limited
 
+OUI:4C0BBE*
+ ID_OUI_FROM_DATABASE=Microsoft
+
 OUI:4C0DEE*
  ID_OUI_FROM_DATABASE=JABIL CIRCUIT (SHANGHAI) LTD.
 
@@ -57136,12 +57835,18 @@ OUI:4C0F6E*
 OUI:4C0FC7*
  ID_OUI_FROM_DATABASE=Earda Electronics Co.,Ltd
 
+OUI:4C11BF*
+ ID_OUI_FROM_DATABASE=ZHEJIANG DAHUA TECHNOLOGY CO.,LTD.
+
 OUI:4C1480*
  ID_OUI_FROM_DATABASE=NOREGON SYSTEMS, INC
 
 OUI:4C14A3*
  ID_OUI_FROM_DATABASE=TCL Technoly Electronics (Huizhou) Co., Ltd.
 
+OUI:4C16F1*
+ ID_OUI_FROM_DATABASE=zte corporation
+
 OUI:4C17EB*
  ID_OUI_FROM_DATABASE=SAGEMCOM
 
@@ -57163,9 +57868,15 @@ OUI:4C2258*
 OUI:4C2578*
  ID_OUI_FROM_DATABASE=Nokia Corporation
 
+OUI:4C26E7*
+ ID_OUI_FROM_DATABASE=Welgate Co., Ltd.
+
 OUI:4C2C80*
  ID_OUI_FROM_DATABASE=Beijing Skyway Technologies Co.,Ltd
 
+OUI:4C2C83*
+ ID_OUI_FROM_DATABASE=Zhejiang KaNong Network Technology Co.,Ltd.
+
 OUI:4C2F9D*
  ID_OUI_FROM_DATABASE=ICM Controls
 
@@ -57178,6 +57889,9 @@ OUI:4C322D*
 OUI:4C32D9*
  ID_OUI_FROM_DATABASE=M Rutty Holdings Pty. Ltd.
 
+OUI:4C3909*
+ ID_OUI_FROM_DATABASE=HPL Electric & Power Private Limited
+
 OUI:4C3910*
  ID_OUI_FROM_DATABASE=Newtek Electronics co., Ltd.
 
@@ -57187,6 +57901,9 @@ OUI:4C3B74*
 OUI:4C3C16*
  ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
 
+OUI:4C48DA*
+ ID_OUI_FROM_DATABASE=Beijing Autelan Technology Co.,Ltd
+
 OUI:4C4B68*
  ID_OUI_FROM_DATABASE=Mobile Device, Inc.
 
@@ -57232,6 +57949,9 @@ OUI:4C63EB*
 OUI:4C64D9*
  ID_OUI_FROM_DATABASE=Guangdong Leawin Group Co., Ltd
 
+OUI:4C6E6E*
+ ID_OUI_FROM_DATABASE=Comnect Technology CO.,LTD
+
 OUI:4C72B9*
  ID_OUI_FROM_DATABASE=Pegatron Corporation
 
@@ -57241,6 +57961,9 @@ OUI:4C7367*
 OUI:4C73A5*
  ID_OUI_FROM_DATABASE=KOVE
 
+OUI:4C7403*
+ ID_OUI_FROM_DATABASE=Mundo Reader (bq)
+
 OUI:4C774F*
  ID_OUI_FROM_DATABASE=Embedded Wireless Labs
 
@@ -57262,6 +57985,9 @@ OUI:4C8093*
 OUI:4C82CF*
  ID_OUI_FROM_DATABASE=Echostar Technologies
 
+OUI:4C83DE*
+ ID_OUI_FROM_DATABASE=Cisco SPVTG
+
 OUI:4C8B30*
  ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc
 
@@ -57289,6 +58015,9 @@ OUI:4C9E80*
 OUI:4C9EE4*
  ID_OUI_FROM_DATABASE=Hanyang Navicom Co.,Ltd.
 
+OUI:4C9EFF*
+ ID_OUI_FROM_DATABASE=ZyXEL Communications Corp
+
 OUI:4CA56D*
  ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
 
@@ -57322,6 +58051,12 @@ OUI:4CB9C8*
 OUI:4CBAA3*
  ID_OUI_FROM_DATABASE=Bison Electronics Inc.
 
+OUI:4CBB58*
+ ID_OUI_FROM_DATABASE=Chicony Electronics Co., Ltd.
+
+OUI:4CBC42*
+ ID_OUI_FROM_DATABASE=Shenzhen Hangsheng Electronics Co.,Ltd.
+
 OUI:4CBCA5*
  ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
 
@@ -57358,9 +58093,15 @@ OUI:4CDF3D*
 OUI:4CE1BB*
  ID_OUI_FROM_DATABASE=Zhuhai HiFocus Technology Co., Ltd.
 
+OUI:4CE2F1*
+ ID_OUI_FROM_DATABASE=sclak srl
+
 OUI:4CE676*
  ID_OUI_FROM_DATABASE=Buffalo Inc.
 
+OUI:4CE933*
+ ID_OUI_FROM_DATABASE=RailComm, LLC
+
 OUI:4CEB42*
  ID_OUI_FROM_DATABASE=Intel Corporate
 
@@ -57370,9 +58111,15 @@ OUI:4CEDDE*
 OUI:4CF02E*
  ID_OUI_FROM_DATABASE=Vifa Denmark A/S
 
+OUI:4CF2BF*
+ ID_OUI_FROM_DATABASE=Cambridge Industries(Group) Co.,Ltd.
+
 OUI:4CF45B*
  ID_OUI_FROM_DATABASE=Blue Clover Devices
 
+OUI:4CF5A0*
+ ID_OUI_FROM_DATABASE=Scalable Network Technologies Inc
+
 OUI:4CF737*
  ID_OUI_FROM_DATABASE=SamJi Electronics Co., Ltd
 
@@ -57397,6 +58144,9 @@ OUI:500E6D*
 OUI:5011EB*
  ID_OUI_FROM_DATABASE=SilverNet Ltd
 
+OUI:5014B5*
+ ID_OUI_FROM_DATABASE=Richfit Information Technology Co., Ltd
+
 OUI:5017FF*
  ID_OUI_FROM_DATABASE=Cisco
 
@@ -57421,6 +58171,9 @@ OUI:502690*
 OUI:5027C7*
  ID_OUI_FROM_DATABASE=TECHNART Co.,Ltd
 
+OUI:50294D*
+ ID_OUI_FROM_DATABASE=NANJING IOT SENSOR TECHNOLOGY CO,LTD
+
 OUI:502A7E*
  ID_OUI_FROM_DATABASE=Smart electronic GmbH
 
@@ -57472,15 +58225,24 @@ OUI:504A6E*
 OUI:504F94*
  ID_OUI_FROM_DATABASE=Loxone Electronics GmbH
 
+OUI:505065*
+ ID_OUI_FROM_DATABASE=TAKT Corporation
+
 OUI:505663*
  ID_OUI_FROM_DATABASE=Texas Instruments
 
 OUI:5056A8*
  ID_OUI_FROM_DATABASE=Jolla Ltd
 
+OUI:5056BF*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,LTD
+
 OUI:5057A8*
  ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
 
+OUI:505800*
+ ID_OUI_FROM_DATABASE=WyTec International, Inc.
+
 OUI:505AC6*
  ID_OUI_FROM_DATABASE=GUANGDONG SUPER TELECOM CO.,LTD.
 
@@ -57499,6 +58261,12 @@ OUI:506313*
 OUI:506441*
  ID_OUI_FROM_DATABASE=Greenlee
 
+OUI:506787*
+ ID_OUI_FROM_DATABASE=iTellus
+
+OUI:5067AE*
+ ID_OUI_FROM_DATABASE=Cisco
+
 OUI:5067F0*
  ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
 
@@ -57529,6 +58297,9 @@ OUI:507E5D*
 OUI:508569*
  ID_OUI_FROM_DATABASE=Samsung Electronics Co.,LTD
 
+OUI:508789*
+ ID_OUI_FROM_DATABASE=Cisco
+
 OUI:5087B8*
  ID_OUI_FROM_DATABASE=Nuvyyo Inc
 
@@ -57592,6 +58363,9 @@ OUI:50B888*
 OUI:50B8A2*
  ID_OUI_FROM_DATABASE=ImTech Technologies LLC,
 
+OUI:50BD5F*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+
 OUI:50C006*
  ID_OUI_FROM_DATABASE=Carmanah Signs
 
@@ -57601,6 +58375,9 @@ OUI:50C271*
 OUI:50C58D*
  ID_OUI_FROM_DATABASE=Juniper Networks
 
+OUI:50C7BF*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+
 OUI:50C971*
  ID_OUI_FROM_DATABASE=GN Netcom A/S
 
@@ -57643,6 +58420,9 @@ OUI:50ED94*
 OUI:50F003*
  ID_OUI_FROM_DATABASE=Open Stack, Inc.
 
+OUI:50F43C*
+ ID_OUI_FROM_DATABASE=Leeo Inc
+
 OUI:50F520*
  ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
 
@@ -57658,6 +58438,9 @@ OUI:50FC30*
 OUI:50FC9F*
  ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
 
+OUI:50FEF2*
+ ID_OUI_FROM_DATABASE=Sify Technologies Ltd
+
 OUI:5403F5*
  ID_OUI_FROM_DATABASE=EBN Technology Corp.
 
@@ -57673,6 +58456,9 @@ OUI:540536*
 OUI:54055F*
  ID_OUI_FROM_DATABASE=Alcatel Lucent
 
+OUI:54098D*
+ ID_OUI_FROM_DATABASE=deister electronic GmbH
+
 OUI:54112F*
  ID_OUI_FROM_DATABASE=Sulzer Pump Solutions Finland Oy
 
@@ -57706,6 +58492,9 @@ OUI:54271E*
 OUI:542A9C*
  ID_OUI_FROM_DATABASE=LSY Defense, LLC.
 
+OUI:542AA2*
+ ID_OUI_FROM_DATABASE=Alpha Networks Inc.
+
 OUI:542CEA*
  ID_OUI_FROM_DATABASE=PROTECTRON
 
@@ -57739,9 +58528,15 @@ OUI:544408*
 OUI:54466B*
  ID_OUI_FROM_DATABASE=Shenzhen CZTIC Electronic Technology Co., Ltd
 
+OUI:544A00*
+ ID_OUI_FROM_DATABASE=Cisco
+
 OUI:544A05*
  ID_OUI_FROM_DATABASE=wenglor sensoric gmbh
 
+OUI:544A16*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
 OUI:5453ED*
  ID_OUI_FROM_DATABASE=Sony Corporation
 
@@ -57817,9 +58612,15 @@ OUI:549B12*
 OUI:549D85*
  ID_OUI_FROM_DATABASE=EnerAccess inc
 
+OUI:549F35*
+ ID_OUI_FROM_DATABASE=Dell Inc.
+
 OUI:54A04F*
  ID_OUI_FROM_DATABASE=t-mac Technologies Ltd
 
+OUI:54A050*
+ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
+
 OUI:54A31B*
  ID_OUI_FROM_DATABASE=Shenzhen Linkworld Technology Co,.LTD
 
@@ -57841,9 +58642,15 @@ OUI:54AE27*
 OUI:54B620*
  ID_OUI_FROM_DATABASE=SUHDOL E&C Co.Ltd.
 
+OUI:54B753*
+ ID_OUI_FROM_DATABASE=Hunan Fenghui Yinjia Science And Technology Co.,Ltd
+
 OUI:54BEF7*
  ID_OUI_FROM_DATABASE=PEGATRON CORPORATION
 
+OUI:54C80F*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+
 OUI:54CDA7*
  ID_OUI_FROM_DATABASE=Fujian Shenzhou Electronic Co.,Ltd
 
@@ -57862,6 +58669,9 @@ OUI:54D1B0*
 OUI:54D46F*
  ID_OUI_FROM_DATABASE=Cisco SPVTG
 
+OUI:54DF00*
+ ID_OUI_FROM_DATABASE=Ulterius Technologies, LLC
+
 OUI:54DF63*
  ID_OUI_FROM_DATABASE=Intrakey technologies GmbH
 
@@ -57877,6 +58687,9 @@ OUI:54E3B0*
 OUI:54E43A*
  ID_OUI_FROM_DATABASE=Apple, Inc.
 
+OUI:54E4BD*
+ ID_OUI_FROM_DATABASE=FN-LINK TECHNOLOGY LIMITED
+
 OUI:54E63F*
  ID_OUI_FROM_DATABASE=ShenZhen LingKeWeiEr Technology Co., Ltd.
 
@@ -57886,18 +58699,33 @@ OUI:54E6FC*
 OUI:54EAA8*
  ID_OUI_FROM_DATABASE=Apple, Inc.
 
+OUI:54EE75*
+ ID_OUI_FROM_DATABASE=Wistron InfoComm(Kunshan)Co.,Ltd.
+
+OUI:54EF92*
+ ID_OUI_FROM_DATABASE=Shenzhen Elink Technology Co., LTD
+
 OUI:54F5B6*
  ID_OUI_FROM_DATABASE=ORIENTAL PACIFIC INTERNATIONAL LIMITED
 
 OUI:54F666*
  ID_OUI_FROM_DATABASE=Berthold Technologies GmbH and Co.KG
 
+OUI:54F876*
+ ID_OUI_FROM_DATABASE=ABB AG
+
+OUI:54FA3E*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,LTD
+
 OUI:54FB58*
  ID_OUI_FROM_DATABASE=WISEWARE, Lda
 
 OUI:54FDBF*
  ID_OUI_FROM_DATABASE=Scheidt & Bachmann GmbH
 
+OUI:54FFCF*
+ ID_OUI_FROM_DATABASE=Mopria Alliance
+
 OUI:580528*
  ID_OUI_FROM_DATABASE=LABRIS NETWORKS
 
@@ -57913,6 +58741,9 @@ OUI:5809E5*
 OUI:580A20*
  ID_OUI_FROM_DATABASE=Cisco
 
+OUI:58108C*
+ ID_OUI_FROM_DATABASE=Intelbras
+
 OUI:581243*
  ID_OUI_FROM_DATABASE=AcSiP Technology Corp.
 
@@ -57928,12 +58759,21 @@ OUI:581CBD*
 OUI:581D91*
  ID_OUI_FROM_DATABASE=Advanced Mobile Telecom co.,ltd.
 
+OUI:581F67*
+ ID_OUI_FROM_DATABASE=Open-m technology limited
+
 OUI:581FAA*
  ID_OUI_FROM_DATABASE=Apple
 
 OUI:581FEF*
  ID_OUI_FROM_DATABASE=Tuttnaer LTD
 
+OUI:582136*
+ ID_OUI_FROM_DATABASE=KMB systems, s.r.o.
+
+OUI:58238C*
+ ID_OUI_FROM_DATABASE=Technicolor CH USA
+
 OUI:582EFE*
  ID_OUI_FROM_DATABASE=Lighting Science Group
 
@@ -58021,12 +58861,21 @@ OUI:587521*
 OUI:587675*
  ID_OUI_FROM_DATABASE=Beijing ECHO Technologies Co.,Ltd
 
+OUI:5876C5*
+ ID_OUI_FROM_DATABASE=DIGI I'S LTD
+
 OUI:587A4D*
  ID_OUI_FROM_DATABASE=Stonesoft Corporation
 
+OUI:587BE9*
+ ID_OUI_FROM_DATABASE=AirPro Technology India Pvt. Ltd
+
 OUI:587E61*
  ID_OUI_FROM_DATABASE=Hisense Electric Co., Ltd
 
+OUI:587FB7*
+ ID_OUI_FROM_DATABASE=SONAR INDUSTRIAL CO., LTD.
+
 OUI:587FC8*
  ID_OUI_FROM_DATABASE=S2M
 
@@ -58123,6 +58972,9 @@ OUI:58DB8D*
 OUI:58E02C*
  ID_OUI_FROM_DATABASE=Micro Technic A/S
 
+OUI:58E326*
+ ID_OUI_FROM_DATABASE=Compass Technologies Inc.
+
 OUI:58E476*
  ID_OUI_FROM_DATABASE=CENTRON COMMUNICATIONS TECHNOLOGIES FUJIAN CO.,LTD
 
@@ -58147,6 +58999,9 @@ OUI:58EECE*
 OUI:58F387*
  ID_OUI_FROM_DATABASE=HCCP
 
+OUI:58F39C*
+ ID_OUI_FROM_DATABASE=Cisco
+
 OUI:58F67B*
  ID_OUI_FROM_DATABASE=Xia Men UnionCore Technology LTD.
 
@@ -58156,6 +59011,9 @@ OUI:58F6BF*
 OUI:58F98E*
  ID_OUI_FROM_DATABASE=SECUDOS GmbH
 
+OUI:58FCDB*
+ ID_OUI_FROM_DATABASE=IEEE REGISTRATION AUTHORITY  - Please see MAM public listing for more information.
+
 OUI:58FD20*
  ID_OUI_FROM_DATABASE=Bravida Sakerhet AB
 
@@ -58180,6 +59038,9 @@ OUI:5C1193*
 OUI:5C1437*
  ID_OUI_FROM_DATABASE=Thyssenkrupp Aufzugswerke GmbH
 
+OUI:5C1515*
+ ID_OUI_FROM_DATABASE=ADVAN
+
 OUI:5C15E1*
  ID_OUI_FROM_DATABASE=AIDC TECHNOLOGY (S) PTE LTD
 
@@ -58213,6 +59074,15 @@ OUI:5C260A*
 OUI:5C2AEF*
  ID_OUI_FROM_DATABASE=Open Access Pty Ltd
 
+OUI:5C2BF5*
+ ID_OUI_FROM_DATABASE=Vivint
+
+OUI:5C2E59*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:5C313E*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
 OUI:5C3327*
  ID_OUI_FROM_DATABASE=Spazio Italia srl
 
@@ -58267,6 +59137,9 @@ OUI:5C57C8*
 OUI:5C5948*
  ID_OUI_FROM_DATABASE=Apple
 
+OUI:5C5BC2*
+ ID_OUI_FROM_DATABASE=YIK Corporation
+
 OUI:5C5EAB*
  ID_OUI_FROM_DATABASE=Juniper Networks
 
@@ -58306,12 +59179,27 @@ OUI:5C8778*
 OUI:5C89D4*
  ID_OUI_FROM_DATABASE=Beijing Banner Electric Co.,Ltd
 
+OUI:5C8D4E*
+ ID_OUI_FROM_DATABASE=Apple
+
+OUI:5C8FE0*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:5C93A2*
+ ID_OUI_FROM_DATABASE=Liteon Technology Corporation
+
 OUI:5C95AE*
  ID_OUI_FROM_DATABASE=Apple
 
+OUI:5C966A*
+ ID_OUI_FROM_DATABASE=RTNET
+
 OUI:5C969D*
  ID_OUI_FROM_DATABASE=Apple
 
+OUI:5C97F3*
+ ID_OUI_FROM_DATABASE=Apple
+
 OUI:5C9AD8*
  ID_OUI_FROM_DATABASE=Fujitsu Limited
 
@@ -58324,12 +59212,21 @@ OUI:5CA3EB*
 OUI:5CA48A*
  ID_OUI_FROM_DATABASE=Cisco
 
+OUI:5CAAFD*
+ ID_OUI_FROM_DATABASE=Sonos, Inc.
+
 OUI:5CAC4C*
  ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
 
 OUI:5CB524*
  ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB
 
+OUI:5CB6CC*
+ ID_OUI_FROM_DATABASE=NovaComm Technologies Inc.
+
+OUI:5CB8CB*
+ ID_OUI_FROM_DATABASE=Allis Communications
+
 OUI:5CBD9E*
  ID_OUI_FROM_DATABASE=HONGKONG MIRACLE EAGLE TECHNOLOGY(GROUP) LIMITED
 
@@ -58411,6 +59308,9 @@ OUI:5CF370*
 OUI:5CF3FC*
  ID_OUI_FROM_DATABASE=IBM Corp
 
+OUI:5CF4AB*
+ ID_OUI_FROM_DATABASE=ZyXEL Communications Corp
+
 OUI:5CF50D*
  ID_OUI_FROM_DATABASE=Institute of microelectronic applications
 
@@ -58423,15 +59323,24 @@ OUI:5CF8A1*
 OUI:5CF938*
  ID_OUI_FROM_DATABASE=Apple, Inc
 
+OUI:5CF96A*
+ ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd
+
 OUI:5CF9DD*
  ID_OUI_FROM_DATABASE=Dell Inc
 
+OUI:5CF9F0*
+ ID_OUI_FROM_DATABASE=Atomos Engineering P/L
+
 OUI:5CFF35*
  ID_OUI_FROM_DATABASE=Wistron Corporation
 
 OUI:5CFFFF*
  ID_OUI_FROM_DATABASE=Shenzhen Kezhonglong Optoelectronic Technology Co., Ltd
 
+OUI:600292*
+ ID_OUI_FROM_DATABASE=PEGATRON CORPORATION
+
 OUI:6002B4*
  ID_OUI_FROM_DATABASE=Wistron NeWeb Corp.
 
@@ -58441,6 +59350,9 @@ OUI:600308*
 OUI:600347*
  ID_OUI_FROM_DATABASE=Billion Electric Co. Ltd.
 
+OUI:600417*
+ ID_OUI_FROM_DATABASE=POSBANK CO.,LTD
+
 OUI:600F77*
  ID_OUI_FROM_DATABASE=SilverPlus, Inc
 
@@ -58489,6 +59401,9 @@ OUI:60334B*
 OUI:603553*
  ID_OUI_FROM_DATABASE=Buwon Technology
 
+OUI:603696*
+ ID_OUI_FROM_DATABASE=The Sapling Company
+
 OUI:6036DD*
  ID_OUI_FROM_DATABASE=Intel Corporate
 
@@ -58516,9 +59431,18 @@ OUI:604616*
 OUI:6047D4*
  ID_OUI_FROM_DATABASE=FORICS Electronic Technology Co., Ltd.
 
+OUI:604826*
+ ID_OUI_FROM_DATABASE=Newbridge Technologies Int. Ltd.
+
 OUI:604A1C*
  ID_OUI_FROM_DATABASE=SUYIN Corporation
 
+OUI:6050C1*
+ ID_OUI_FROM_DATABASE=Kinetek Sports
+
+OUI:60512C*
+ ID_OUI_FROM_DATABASE=TCT mobile limited
+
 OUI:6052D0*
  ID_OUI_FROM_DATABASE=FACTS Engineering
 
@@ -58561,6 +59485,15 @@ OUI:60748D*
 OUI:607688*
  ID_OUI_FROM_DATABASE=Velodyne
 
+OUI:6077E2*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:60812B*
+ ID_OUI_FROM_DATABASE=Custom Control Concepts
+
+OUI:6081F9*
+ ID_OUI_FROM_DATABASE=Helium Systems, Inc
+
 OUI:6083B2*
  ID_OUI_FROM_DATABASE=GkWare e.K.
 
@@ -58585,9 +59518,18 @@ OUI:608C2B*
 OUI:608D17*
  ID_OUI_FROM_DATABASE=Sentrus Government Systems Division, Inc
 
+OUI:608F5C*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
 OUI:609084*
  ID_OUI_FROM_DATABASE=DSSD Inc
 
+OUI:609217*
+ ID_OUI_FROM_DATABASE=Apple
+
+OUI:6099D1*
+ ID_OUI_FROM_DATABASE=Vuzix / Lenovo
+
 OUI:609AA4*
  ID_OUI_FROM_DATABASE=GVI SECURITY INC.
 
@@ -58603,6 +59545,9 @@ OUI:60A10A*
 OUI:60A44C*
  ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
 
+OUI:60A8FE*
+ ID_OUI_FROM_DATABASE=Nokia Solutions and Networks
+
 OUI:60A9B0*
  ID_OUI_FROM_DATABASE=Merchandising Technologies, Inc
 
@@ -58615,6 +59560,9 @@ OUI:60B3C4*
 OUI:60B606*
  ID_OUI_FROM_DATABASE=Phorus
 
+OUI:60B617*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Tech.Co.,Ltd.
+
 OUI:60B933*
  ID_OUI_FROM_DATABASE=Deutron Electronics Corp.
 
@@ -58633,6 +59581,9 @@ OUI:60BD91*
 OUI:60BEB5*
  ID_OUI_FROM_DATABASE=Motorola Mobility LLC
 
+OUI:60C1CB*
+ ID_OUI_FROM_DATABASE=Fujian Great Power PLC Equipment Co.,Ltd
+
 OUI:60C397*
  ID_OUI_FROM_DATABASE=2Wire Inc
 
@@ -58642,12 +59593,18 @@ OUI:60C547*
 OUI:60C5A8*
  ID_OUI_FROM_DATABASE=Beijing LT Honway Technology Co.,Ltd
 
+OUI:60C798*
+ ID_OUI_FROM_DATABASE=Verifone, Inc.
+
 OUI:60C980*
  ID_OUI_FROM_DATABASE=Trymus
 
 OUI:60CBFB*
  ID_OUI_FROM_DATABASE=AirScape Inc.
 
+OUI:60CDA9*
+ ID_OUI_FROM_DATABASE=Abloomy
+
 OUI:60CDC5*
  ID_OUI_FROM_DATABASE=Taiwan Carol Electronics., Ltd
 
@@ -58681,6 +59638,12 @@ OUI:60DE44*
 OUI:60E00E*
  ID_OUI_FROM_DATABASE=SHINSEI ELECTRONICS CO LTD
 
+OUI:60E327*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+
+OUI:60E701*
+ ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd
+
 OUI:60E956*
  ID_OUI_FROM_DATABASE=Ayla Networks, Inc
 
@@ -58729,6 +59692,9 @@ OUI:60FEF9*
 OUI:60FFDD*
  ID_OUI_FROM_DATABASE=C.E. ELECTRONICS, INC
 
+OUI:64002D*
+ ID_OUI_FROM_DATABASE=Powerlinq Co., LTD
+
 OUI:6400F1*
  ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
 
@@ -58738,6 +59704,9 @@ OUI:6405BE*
 OUI:64094C*
  ID_OUI_FROM_DATABASE=Beijing Superbee Wireless Technology Co.,Ltd
 
+OUI:640980*
+ ID_OUI_FROM_DATABASE=XIAOMI Electronics,CO.,LTD
+
 OUI:640B4A*
  ID_OUI_FROM_DATABASE=Digital Telecom Technology Limited
 
@@ -58753,6 +59722,9 @@ OUI:640F28*
 OUI:641084*
  ID_OUI_FROM_DATABASE=HEXIUM Technical Development Co., Ltd.
 
+OUI:641225*
+ ID_OUI_FROM_DATABASE=Cisco
+
 OUI:64168D*
  ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
 
@@ -58816,6 +59788,12 @@ OUI:644D70*
 OUI:644F74*
  ID_OUI_FROM_DATABASE=LENUS Co., Ltd.
 
+OUI:644FB0*
+ ID_OUI_FROM_DATABASE=Hyunjin.com
+
+OUI:645106*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
 OUI:64517E*
  ID_OUI_FROM_DATABASE=LONG BEN (DONGGUAN) ELECTRONIC TECHNOLOGY CO.,LTD.
 
@@ -58855,6 +59833,9 @@ OUI:645FFF*
 OUI:646223*
  ID_OUI_FROM_DATABASE=Cellient Co., Ltd.
 
+OUI:64649B*
+ ID_OUI_FROM_DATABASE=juniper networks
+
 OUI:6465C0*
  ID_OUI_FROM_DATABASE=Nuvon, Inc
 
@@ -58870,6 +59851,9 @@ OUI:64680C*
 OUI:6469BC*
  ID_OUI_FROM_DATABASE=Hytera Communications Co .,ltd
 
+OUI:646CB2*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
 OUI:646E6C*
  ID_OUI_FROM_DATABASE=Radio Datacom LLC
 
@@ -58966,6 +59950,9 @@ OUI:64A3CB*
 OUI:64A769*
  ID_OUI_FROM_DATABASE=HTC Corporation
 
+OUI:64A7DD*
+ ID_OUI_FROM_DATABASE=Avaya, Inc
+
 OUI:64A837*
  ID_OUI_FROM_DATABASE=Juni Korea Co., Ltd
 
@@ -58975,15 +59962,24 @@ OUI:64AE0C*
 OUI:64AE88*
  ID_OUI_FROM_DATABASE=Polytec GmbH
 
+OUI:64B21D*
+ ID_OUI_FROM_DATABASE=Chengdu Phycom Tech Co., Ltd.
+
 OUI:64B310*
  ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
 
 OUI:64B370*
  ID_OUI_FROM_DATABASE=PowerComm Solutons LLC
 
+OUI:64B473*
+ ID_OUI_FROM_DATABASE=Xiaomi inc.
+
 OUI:64B64A*
  ID_OUI_FROM_DATABASE=ViVOtech, Inc.
 
+OUI:64B853*
+ ID_OUI_FROM_DATABASE=Samsung Elec Co.,Ltd
+
 OUI:64B9E8*
  ID_OUI_FROM_DATABASE=Apple
 
@@ -59026,6 +60022,9 @@ OUI:64D814*
 OUI:64D912*
  ID_OUI_FROM_DATABASE=Solidica, Inc.
 
+OUI:64D954*
+ ID_OUI_FROM_DATABASE=TAICANG AND W ELECTRONICS CO LTD
+
 OUI:64D989*
  ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
 
@@ -59062,6 +60061,9 @@ OUI:64E8E6*
 OUI:64E950*
  ID_OUI_FROM_DATABASE=Cisco
 
+OUI:64EAC5*
+ ID_OUI_FROM_DATABASE=SiboTech Automation Co., Ltd.
+
 OUI:64EB8C*
  ID_OUI_FROM_DATABASE=Seiko Epson Corporation
 
@@ -59086,6 +60088,9 @@ OUI:64F987*
 OUI:64FC8C*
  ID_OUI_FROM_DATABASE=Zonar Systems
 
+OUI:680571*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
 OUI:6805CA*
  ID_OUI_FROM_DATABASE=Intel Corporate
 
@@ -59131,9 +60136,15 @@ OUI:681FD8*
 OUI:68234B*
  ID_OUI_FROM_DATABASE=Nihon Dengyo Kousaku
 
+OUI:6828BA*
+ ID_OUI_FROM_DATABASE=Dejai
+
 OUI:682DDC*
  ID_OUI_FROM_DATABASE=Wuhan Changjiang Electro-Communication Equipment CO.,LTD
 
+OUI:6836B5*
+ ID_OUI_FROM_DATABASE=DriveScale, Inc.
+
 OUI:683B1E*
  ID_OUI_FROM_DATABASE=Countwise LTD
 
@@ -59188,9 +60199,15 @@ OUI:6869F2*
 OUI:686E23*
  ID_OUI_FROM_DATABASE=Wi3 Inc.
 
+OUI:686E48*
+ ID_OUI_FROM_DATABASE=Prophet Electronic Technology Corp.,Ltd
+
 OUI:687251*
  ID_OUI_FROM_DATABASE=Ubiquiti Networks
 
+OUI:6872DC*
+ ID_OUI_FROM_DATABASE=CETORY.TV Company Limited
+
 OUI:68764F*
  ID_OUI_FROM_DATABASE=Sony Mobile Communications AB
 
@@ -59254,12 +60271,18 @@ OUI:68974B*
 OUI:6897E8*
  ID_OUI_FROM_DATABASE=Society of Motion Picture &amp; Television Engineers
 
+OUI:6899CD*
+ ID_OUI_FROM_DATABASE=Cisco
+
 OUI:689C5E*
  ID_OUI_FROM_DATABASE=AcSiP Technology Corp.
 
 OUI:689C70*
  ID_OUI_FROM_DATABASE=Apple
 
+OUI:68A0F6*
+ ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd
+
 OUI:68A1B7*
  ID_OUI_FROM_DATABASE=Honghao Mingchuan Technology (Beijing) CO.,Ltd.
 
@@ -59278,6 +60301,9 @@ OUI:68AAD2*
 OUI:68AB8A*
  ID_OUI_FROM_DATABASE=RF IDeas
 
+OUI:68AE20*
+ ID_OUI_FROM_DATABASE=Apple
+
 OUI:68AF13*
  ID_OUI_FROM_DATABASE=Futura Mobility
 
@@ -59323,6 +60349,9 @@ OUI:68D247*
 OUI:68D925*
  ID_OUI_FROM_DATABASE=ProSys Development Services
 
+OUI:68D93C*
+ ID_OUI_FROM_DATABASE=Apple
+
 OUI:68DB67*
  ID_OUI_FROM_DATABASE=Nantong Coship Electronics Co., Ltd
 
@@ -59332,6 +60361,9 @@ OUI:68DB96*
 OUI:68DCE8*
  ID_OUI_FROM_DATABASE=PacketStorm Communications
 
+OUI:68DFDD*
+ ID_OUI_FROM_DATABASE=Xiaomi inc.
+
 OUI:68E41F*
  ID_OUI_FROM_DATABASE=Unglaube Identech GmbH
 
@@ -59353,9 +60385,15 @@ OUI:68EE96*
 OUI:68EFBD*
  ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
 
+OUI:68F06D*
+ ID_OUI_FROM_DATABASE=ALONG INDUSTRIAL CO., LIMITED
+
 OUI:68F125*
  ID_OUI_FROM_DATABASE=Data Controls Inc.
 
+OUI:68F728*
+ ID_OUI_FROM_DATABASE=LCFC(HeFei) Electronics Technology co., ltd
+
 OUI:68F895*
  ID_OUI_FROM_DATABASE=Redflow Limited
 
@@ -59365,24 +60403,36 @@ OUI:68FB95*
 OUI:68FCB3*
  ID_OUI_FROM_DATABASE=Next Level Security Systems, Inc.
 
+OUI:6C0273*
+ ID_OUI_FROM_DATABASE=Shenzhen Jin Yun Video Equipment Co., Ltd.
+
 OUI:6C0460*
  ID_OUI_FROM_DATABASE=RBH Access Technologies Inc.
 
 OUI:6C09D6*
  ID_OUI_FROM_DATABASE=Digiquest Electronics LTD
 
+OUI:6C0B84*
+ ID_OUI_FROM_DATABASE=Universal Global Scientific Industrial Co.,Ltd.
+
 OUI:6C0E0D*
  ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB
 
 OUI:6C0F6A*
  ID_OUI_FROM_DATABASE=JDC Tech Co., Ltd.
 
+OUI:6C14F7*
+ ID_OUI_FROM_DATABASE=Erhardt+Leimer GmbH
+
 OUI:6C15F9*
  ID_OUI_FROM_DATABASE=Nautronix Limited
 
 OUI:6C1811*
  ID_OUI_FROM_DATABASE=Decatur Electronics
 
+OUI:6C198F*
+ ID_OUI_FROM_DATABASE=D-Link International
+
 OUI:6C2056*
  ID_OUI_FROM_DATABASE=Cisco
 
@@ -59395,12 +60445,18 @@ OUI:6C23B9*
 OUI:6C2995*
  ID_OUI_FROM_DATABASE=Intel Corporate
 
+OUI:6C2C06*
+ ID_OUI_FROM_DATABASE=OOO NPP Systemotechnika-NN
+
 OUI:6C2E33*
  ID_OUI_FROM_DATABASE=Accelink Technologies Co.,Ltd.
 
 OUI:6C2E85*
  ID_OUI_FROM_DATABASE=SAGEMCOM
 
+OUI:6C2F2C*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
 OUI:6C32DE*
  ID_OUI_FROM_DATABASE=Indieon Technologies Pvt. Ltd.
 
@@ -59425,6 +60481,9 @@ OUI:6C3E6D*
 OUI:6C3E9C*
  ID_OUI_FROM_DATABASE=KE Knestel Elektronik GmbH
 
+OUI:6C4008*
+ ID_OUI_FROM_DATABASE=Apple
+
 OUI:6C40C6*
  ID_OUI_FROM_DATABASE=Nimbus Data Systems, Inc.
 
@@ -59467,6 +60526,9 @@ OUI:6C626D*
 OUI:6C641A*
  ID_OUI_FROM_DATABASE=Penguin Computing
 
+OUI:6C6EFE*
+ ID_OUI_FROM_DATABASE=Core Logic Inc.
+
 OUI:6C6F18*
  ID_OUI_FROM_DATABASE=Stereotaxis, Inc.
 
@@ -59479,6 +60541,9 @@ OUI:6C709F*
 OUI:6C71D9*
  ID_OUI_FROM_DATABASE=AzureWave Technologies, Inc
 
+OUI:6C7660*
+ ID_OUI_FROM_DATABASE=KYOCERA Corporation
+
 OUI:6C81FE*
  ID_OUI_FROM_DATABASE=Mitsuba Corporation
 
@@ -59510,7 +60575,7 @@ OUI:6C92BF*
  ID_OUI_FROM_DATABASE=Inspur Electronic Information Industry Co.,Ltd.
 
 OUI:6C98EB*
- ID_OUI_FROM_DATABASE=Xyne GmbH
+ ID_OUI_FROM_DATABASE=Ocedo GmbH
 
 OUI:6C9989*
  ID_OUI_FROM_DATABASE=Cisco
@@ -59539,6 +60604,9 @@ OUI:6CA906*
 OUI:6CA96F*
  ID_OUI_FROM_DATABASE=TransPacket AS
 
+OUI:6CAAB3*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
 OUI:6CAB4D*
  ID_OUI_FROM_DATABASE=Digital Payment Technologies
 
@@ -59557,6 +60625,9 @@ OUI:6CADF8*
 OUI:6CAE8B*
  ID_OUI_FROM_DATABASE=IBM Corporation
 
+OUI:6CB0CE*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
 OUI:6CB311*
  ID_OUI_FROM_DATABASE=Shenzhen Lianrui Electronics Co.,Ltd
 
@@ -59569,9 +60640,15 @@ OUI:6CB7F4*
 OUI:6CBEE9*
  ID_OUI_FROM_DATABASE=Alcatel-Lucent-IPD
 
+OUI:6CBFB5*
+ ID_OUI_FROM_DATABASE=Noon Technology Co., Ltd
+
 OUI:6CC1D2*
  ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
 
+OUI:6CC217*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
 OUI:6CC26B*
  ID_OUI_FROM_DATABASE=Apple
 
@@ -59608,6 +60685,9 @@ OUI:6CE983*
 OUI:6CECA1*
  ID_OUI_FROM_DATABASE=SHENZHEN CLOU ELECTRONICS CO. LTD.
 
+OUI:6CECEB*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
 OUI:6CF049*
  ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD.
 
@@ -59623,6 +60703,12 @@ OUI:6CF97C*
 OUI:6CFA58*
  ID_OUI_FROM_DATABASE=Avaya, Inc
 
+OUI:6CFA89*
+ ID_OUI_FROM_DATABASE=Cisco
+
+OUI:6CFAA7*
+ ID_OUI_FROM_DATABASE=AMPAK Technology Inc.
+
 OUI:6CFDB9*
  ID_OUI_FROM_DATABASE=Proware Technologies Co Ltd.
 
@@ -59677,6 +60763,9 @@ OUI:702B1D*
 OUI:702C1F*
  ID_OUI_FROM_DATABASE=Wisol
 
+OUI:702DD1*
+ ID_OUI_FROM_DATABASE=Newings Communication CO., LTD.
+
 OUI:702F4B*
  ID_OUI_FROM_DATABASE=PolyVision Inc.
 
@@ -59686,6 +60775,9 @@ OUI:702F97*
 OUI:703018*
  ID_OUI_FROM_DATABASE=Avaya, Inc
 
+OUI:70305D*
+ ID_OUI_FROM_DATABASE=Ubiquoss Inc
+
 OUI:70305E*
  ID_OUI_FROM_DATABASE=Nanjing Zhongke Menglian Information Technology Co.,LTD
 
@@ -59755,6 +60847,9 @@ OUI:705986*
 OUI:705AB6*
  ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD.
 
+OUI:705B2E*
+ ID_OUI_FROM_DATABASE=M2Communication Inc.
+
 OUI:705CAD*
  ID_OUI_FROM_DATABASE=Konami Gaming Inc
 
@@ -59767,6 +60862,9 @@ OUI:7060DE*
 OUI:706173*
  ID_OUI_FROM_DATABASE=Calantec GmbH
 
+OUI:7062B8*
+ ID_OUI_FROM_DATABASE=D-Link International
+
 OUI:706417*
  ID_OUI_FROM_DATABASE=ORBIS TECNOLOGIA ELECTRICA S.A.
 
@@ -59782,6 +60880,9 @@ OUI:7071B3*
 OUI:7071BC*
  ID_OUI_FROM_DATABASE=PEGATRON CORPORATION
 
+OUI:70720D*
+ ID_OUI_FROM_DATABASE=Lenovo Mobile Communication Technology Ltd.
+
 OUI:70723C*
  ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd
 
@@ -59869,6 +60970,9 @@ OUI:70A8E3*
 OUI:70AAB2*
  ID_OUI_FROM_DATABASE=Research In Motion
 
+OUI:70AF25*
+ ID_OUI_FROM_DATABASE=Nishiyama Industry Co.,LTD.
+
 OUI:70B035*
  ID_OUI_FROM_DATABASE=Shenzhen Zowee Technology Co., Ltd
 
@@ -59881,12 +60985,18 @@ OUI:70B14E*
 OUI:70B265*
  ID_OUI_FROM_DATABASE=Hiltron s.r.l.
 
+OUI:70B3D5*
+ ID_OUI_FROM_DATABASE=IEEE REGISTRATION AUTHORITY  - Please see OUI36 public listing for more information.
+
 OUI:70B599*
  ID_OUI_FROM_DATABASE=Embedded Technologies s.r.o.
 
 OUI:70B921*
  ID_OUI_FROM_DATABASE=FiberHome Telecommunication Technologies CO.,LTD
 
+OUI:70BAEF*
+ ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
+
 OUI:70C6AC*
  ID_OUI_FROM_DATABASE=Bosch Automotive Aftermarket
 
@@ -59938,6 +61048,9 @@ OUI:70EE50*
 OUI:70F176*
  ID_OUI_FROM_DATABASE=Data Modul AG
 
+OUI:70F196*
+ ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc
+
 OUI:70F1A1*
  ID_OUI_FROM_DATABASE=Liteon Technology Corporation
 
@@ -59950,6 +61063,15 @@ OUI:70F395*
 OUI:70F927*
  ID_OUI_FROM_DATABASE=Samsung Electronics
 
+OUI:70F96D*
+ ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
+
+OUI:70FC8C*
+ ID_OUI_FROM_DATABASE=OneAccess SA
+
+OUI:70FF5C*
+ ID_OUI_FROM_DATABASE=Cheerzing Communication(Xiamen)Technology Co.,Ltd
+
 OUI:70FF76*
  ID_OUI_FROM_DATABASE=Texas Instruments
 
@@ -59965,12 +61087,18 @@ OUI:741489*
 OUI:7415E2*
  ID_OUI_FROM_DATABASE=Tri-Sen Systems Corporation
 
+OUI:7419F8*
+ ID_OUI_FROM_DATABASE=IEEE REGISTRATION AUTHORITY  - Please see MAM public listing for more information.
+
 OUI:741E93*
  ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Tech.Co.,Ltd.
 
 OUI:74258A*
  ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
 
+OUI:7426AC*
+ ID_OUI_FROM_DATABASE=Cisco
+
 OUI:74273C*
  ID_OUI_FROM_DATABASE=ChangYang Technology (Nanjing) Co., LTD
 
@@ -60022,12 +61150,18 @@ OUI:744D79*
 OUI:745327*
  ID_OUI_FROM_DATABASE=COMMSEN CO., LIMITED
 
+OUI:74547D*
+ ID_OUI_FROM_DATABASE=Cisco SPVTG
+
 OUI:745612*
  ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
 
 OUI:745798*
  ID_OUI_FROM_DATABASE=TRUMPF Laser GmbH + Co. KG
 
+OUI:745C9F*
+ ID_OUI_FROM_DATABASE=TCT mobile ltd.
+
 OUI:745E1C*
  ID_OUI_FROM_DATABASE=PIONEER CORPORATION
 
@@ -60061,6 +61195,9 @@ OUI:746F3D*
 OUI:7472F2*
  ID_OUI_FROM_DATABASE=Chipsip Technology Co., Ltd.
 
+OUI:747548*
+ ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
+
 OUI:747818*
  ID_OUI_FROM_DATABASE=ServiceAssure
 
@@ -60077,7 +61214,7 @@ OUI:747E2D*
  ID_OUI_FROM_DATABASE=Beijing Thomson CITIC Digital Technology Co. LTD.
 
 OUI:74867A*
- ID_OUI_FROM_DATABASE=Dell Inc PCBA Test
+ ID_OUI_FROM_DATABASE=Dell Inc
 
 OUI:74882A*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
@@ -60094,6 +61231,9 @@ OUI:748EF8*
 OUI:748F1B*
  ID_OUI_FROM_DATABASE=MasterImage 3D
 
+OUI:748F4D*
+ ID_OUI_FROM_DATABASE=MEN Mikro Elektronik GmbH
+
 OUI:749050*
  ID_OUI_FROM_DATABASE=Renesas Electronics Corporation
 
@@ -60136,6 +61276,9 @@ OUI:74B00C*
 OUI:74B9EB*
  ID_OUI_FROM_DATABASE=Fujian JinQianMao Electronic Technology Co.,Ltd
 
+OUI:74BADB*
+ ID_OUI_FROM_DATABASE=Longconn Electornics(shenzhen)Co.,Ltd
+
 OUI:74BE08*
  ID_OUI_FROM_DATABASE=ATEK Products, LLC
 
@@ -60172,12 +61315,21 @@ OUI:74D675*
 OUI:74D850*
  ID_OUI_FROM_DATABASE=Evrisko Systems
 
+OUI:74DA38*
+ ID_OUI_FROM_DATABASE=Edimax Technology Co. Ltd.
+
+OUI:74DBD1*
+ ID_OUI_FROM_DATABASE=Ebay Inc
+
 OUI:74DE2B*
  ID_OUI_FROM_DATABASE=Liteon Technology Corporation
 
 OUI:74E06E*
  ID_OUI_FROM_DATABASE=Ergophone GmbH
 
+OUI:74E14A*
+ ID_OUI_FROM_DATABASE=IEEE REGISTRATION AUTHORITY  - Please see MAM public listing for more information.
+
 OUI:74E1B6*
  ID_OUI_FROM_DATABASE=Apple
 
@@ -60196,6 +61348,9 @@ OUI:74E537*
 OUI:74E543*
  ID_OUI_FROM_DATABASE=Liteon Technology Corporation
 
+OUI:74E6E2*
+ ID_OUI_FROM_DATABASE=Dell Inc.
+
 OUI:74E7C6*
  ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
 
@@ -60214,6 +61369,9 @@ OUI:74F07D*
 OUI:74F102*
  ID_OUI_FROM_DATABASE=Beijing HCHCOM Technology Co., Ltd
 
+OUI:74F413*
+ ID_OUI_FROM_DATABASE=Maxwell Forest
+
 OUI:74F612*
  ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
 
@@ -60268,6 +61426,9 @@ OUI:781FDB*
 OUI:78223D*
  ID_OUI_FROM_DATABASE=Affirmed Networks
 
+OUI:7824AF*
+ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
+
 OUI:782544*
  ID_OUI_FROM_DATABASE=Omnima Limited
 
@@ -60292,6 +61453,9 @@ OUI:7831C1*
 OUI:78324F*
  ID_OUI_FROM_DATABASE=Millennium Group, Inc.
 
+OUI:783A84*
+ ID_OUI_FROM_DATABASE=Apple
+
 OUI:783CE3*
  ID_OUI_FROM_DATABASE=Kai-EE
 
@@ -60310,6 +61474,9 @@ OUI:784405*
 OUI:784476*
  ID_OUI_FROM_DATABASE=Zioncom technology co.,ltd
 
+OUI:784561*
+ ID_OUI_FROM_DATABASE=CyberTAN Technology Inc.
+
 OUI:7845C4*
  ID_OUI_FROM_DATABASE=Dell Inc
 
@@ -60319,6 +61486,9 @@ OUI:7846C4*
 OUI:78471D*
  ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
 
+OUI:784859*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
 OUI:78491D*
  ID_OUI_FROM_DATABASE=The Will-Burt Company
 
@@ -60391,9 +61561,15 @@ OUI:788C54*
 OUI:788DF7*
  ID_OUI_FROM_DATABASE=Hitron Technologies. Inc
 
+OUI:78923E*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
 OUI:78929C*
  ID_OUI_FROM_DATABASE=Intel Corporate
 
+OUI:789684*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
 OUI:7898FD*
  ID_OUI_FROM_DATABASE=Q9 Networks Inc.
 
@@ -60406,6 +61582,9 @@ OUI:789966*
 OUI:78998F*
  ID_OUI_FROM_DATABASE=MEDILINE ITALIA SRL
 
+OUI:789CE7*
+ ID_OUI_FROM_DATABASE=Shenzhen Aikede Technology Co., Ltd
+
 OUI:789ED0*
  ID_OUI_FROM_DATABASE=Samsung Electronics
 
@@ -60523,6 +61702,9 @@ OUI:78D38D*
 OUI:78D5B5*
  ID_OUI_FROM_DATABASE=NAVIELEKTRO KY
 
+OUI:78D66F*
+ ID_OUI_FROM_DATABASE=Aristocrat Technologies Australia Pty. Ltd.
+
 OUI:78D6F0*
  ID_OUI_FROM_DATABASE=Samsung Electro Mechanics
 
@@ -60580,6 +61762,9 @@ OUI:78F7BE*
 OUI:78F7D0*
  ID_OUI_FROM_DATABASE=Silverbrook Research
 
+OUI:78FD94*
+ ID_OUI_FROM_DATABASE=Apple
+
 OUI:78FE3D*
  ID_OUI_FROM_DATABASE=Juniper Networks
 
@@ -60622,6 +61807,9 @@ OUI:7C092B*
 OUI:7C0A50*
  ID_OUI_FROM_DATABASE=J-MEX Inc.
 
+OUI:7C0ECE*
+ ID_OUI_FROM_DATABASE=Cisco
+
 OUI:7C11BE*
  ID_OUI_FROM_DATABASE=Apple
 
@@ -60649,6 +61837,9 @@ OUI:7C2048*
 OUI:7C2064*
  ID_OUI_FROM_DATABASE=Alcatel Lucent IPD
 
+OUI:7C2587*
+ ID_OUI_FROM_DATABASE=chaowifi.com
+
 OUI:7C2CF3*
  ID_OUI_FROM_DATABASE=Secure Electrans Ltd
 
@@ -60718,6 +61909,9 @@ OUI:7C69F6*
 OUI:7C6AB3*
  ID_OUI_FROM_DATABASE=IBC TECHNOLOGIES INC.
 
+OUI:7C6AC3*
+ ID_OUI_FROM_DATABASE=GatesAir, Inc
+
 OUI:7C6ADB*
  ID_OUI_FROM_DATABASE=SafeTone Technology Co.,Ltd
 
@@ -60736,12 +61930,18 @@ OUI:7C6C8F*
 OUI:7C6D62*
  ID_OUI_FROM_DATABASE=Apple
 
+OUI:7C6DF8*
+ ID_OUI_FROM_DATABASE=Apple
+
 OUI:7C6F06*
  ID_OUI_FROM_DATABASE=Caterpillar Trimble Control Technologies
 
 OUI:7C6FF8*
  ID_OUI_FROM_DATABASE=ShenZhen ACTO Digital Video Technology Co.,Ltd.
 
+OUI:7C70BC*
+ ID_OUI_FROM_DATABASE=IEEE REGISTRATION AUTHORITY  - Please see MAM public listing for more information.
+
 OUI:7C72E4*
  ID_OUI_FROM_DATABASE=Unikey Technologies
 
@@ -60799,6 +61999,9 @@ OUI:7CAD74*
 OUI:7CB03E*
  ID_OUI_FROM_DATABASE=OSRAM GmbH
 
+OUI:7CB177*
+ ID_OUI_FROM_DATABASE=Satelco AG
+
 OUI:7CB21B*
  ID_OUI_FROM_DATABASE=Cisco SPVTG
 
@@ -60829,6 +62032,9 @@ OUI:7CBFB1*
 OUI:7CC3A1*
  ID_OUI_FROM_DATABASE=Apple
 
+OUI:7CC4EF*
+ ID_OUI_FROM_DATABASE=Devialet
+
 OUI:7CC537*
  ID_OUI_FROM_DATABASE=Apple
 
@@ -60844,6 +62050,9 @@ OUI:7CC8D7*
 OUI:7CCB0D*
  ID_OUI_FROM_DATABASE=Antaira Technologies, LLC
 
+OUI:7CCCB8*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
 OUI:7CCD11*
  ID_OUI_FROM_DATABASE=MS-Magnet
 
@@ -60856,6 +62065,9 @@ OUI:7CCFCF*
 OUI:7CD1C3*
  ID_OUI_FROM_DATABASE=Apple
 
+OUI:7CD30A*
+ ID_OUI_FROM_DATABASE=INVENTEC Corporation
+
 OUI:7CD762*
  ID_OUI_FROM_DATABASE=Freestyle Technology Pty Ltd
 
@@ -60883,6 +62095,9 @@ OUI:7CE044*
 OUI:7CE1FF*
  ID_OUI_FROM_DATABASE=Computer Performance, Inc. DBA Digital Loggers, Inc.
 
+OUI:7CE524*
+ ID_OUI_FROM_DATABASE=Quirky, Inc.
+
 OUI:7CE56B*
  ID_OUI_FROM_DATABASE=ESEN Optoelectronics Technology Co.,Ltd.
 
@@ -60919,6 +62134,9 @@ OUI:7CFADF*
 OUI:7CFE28*
  ID_OUI_FROM_DATABASE=Salutron Inc.
 
+OUI:7CFE4E*
+ ID_OUI_FROM_DATABASE=Shenzhen Safe vision Technology Co.,LTD
+
 OUI:7CFF62*
  ID_OUI_FROM_DATABASE=Huizhou Super Electron Technology Co.,Ltd.
 
@@ -60937,12 +62155,21 @@ OUI:8005DF*
 OUI:8007A2*
  ID_OUI_FROM_DATABASE=Esson Technology Inc.
 
+OUI:800902*
+ ID_OUI_FROM_DATABASE=Keysight Technologies, Inc.
+
 OUI:800A06*
  ID_OUI_FROM_DATABASE=COMTEC co.,ltd
 
+OUI:800E24*
+ ID_OUI_FROM_DATABASE=ForgetBox
+
 OUI:801440*
  ID_OUI_FROM_DATABASE=Sunlit System Technology Corp
 
+OUI:8014A8*
+ ID_OUI_FROM_DATABASE=Guangzhou V-SOLUTION Electronic Technology Co., Ltd.
+
 OUI:8016B7*
  ID_OUI_FROM_DATABASE=Brunel University
 
@@ -60952,6 +62179,12 @@ OUI:80177D*
 OUI:8018A7*
  ID_OUI_FROM_DATABASE=Samsung Eletronics Co., Ltd
 
+OUI:801934*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:801967*
+ ID_OUI_FROM_DATABASE=Shanghai Reallytek Information Technology  Co.,Ltd
+
 OUI:801DAA*
  ID_OUI_FROM_DATABASE=Avaya Inc
 
@@ -60979,6 +62212,9 @@ OUI:802FDE*
 OUI:803457*
  ID_OUI_FROM_DATABASE=OT Systems Limited
 
+OUI:803773*
+ ID_OUI_FROM_DATABASE=Netgear Inc
+
 OUI:8038FD*
  ID_OUI_FROM_DATABASE=LeapFrog Enterprises, Inc.
 
@@ -60994,6 +62230,9 @@ OUI:803F5D*
 OUI:803FD6*
  ID_OUI_FROM_DATABASE=bytes at work AG
 
+OUI:80414E*
+ ID_OUI_FROM_DATABASE=BBK Electronics Corp., Ltd.,
+
 OUI:80427C*
  ID_OUI_FROM_DATABASE=Adolf Tedsen GmbH & Co. KG
 
@@ -61042,6 +62281,9 @@ OUI:8065E9*
 OUI:806629*
  ID_OUI_FROM_DATABASE=Prescope Technologies CO.,LTD.
 
+OUI:806C1B*
+ ID_OUI_FROM_DATABASE=Motorola Mobility LLC
+
 OUI:806C8B*
  ID_OUI_FROM_DATABASE=KAESER KOMPRESSOREN AG
 
@@ -61051,6 +62293,9 @@ OUI:806CBC*
 OUI:80711F*
  ID_OUI_FROM_DATABASE=Juniper Networks
 
+OUI:80717A*
+ ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd
+
 OUI:807693*
  ID_OUI_FROM_DATABASE=Newag SA
 
@@ -61102,6 +62347,9 @@ OUI:80946C*
 OUI:8096B1*
  ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
 
+OUI:8096CA*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind Co.,Ltd
+
 OUI:80971B*
  ID_OUI_FROM_DATABASE=Altenergy Power System,Inc.
 
@@ -61114,6 +62362,9 @@ OUI:80A1D7*
 OUI:80AAA4*
  ID_OUI_FROM_DATABASE=USAG
 
+OUI:80AD67*
+ ID_OUI_FROM_DATABASE=Kasda Digital Technology Co.,Ltd
+
 OUI:80B219*
  ID_OUI_FROM_DATABASE=ELEKTRON TECHNOLOGY UK LIMITED
 
@@ -61138,6 +62389,9 @@ OUI:80BAE6*
 OUI:80BBEB*
  ID_OUI_FROM_DATABASE=Satmap Systems Ltd
 
+OUI:80BE05*
+ ID_OUI_FROM_DATABASE=Apple
+
 OUI:80C16E*
  ID_OUI_FROM_DATABASE=Hewlett Packard
 
@@ -61165,6 +62419,9 @@ OUI:80D019*
 OUI:80D18B*
  ID_OUI_FROM_DATABASE=Hangzhou I'converge Technology Co.,Ltd
 
+OUI:80D21D*
+ ID_OUI_FROM_DATABASE=AzureWave Technologies, Inc
+
 OUI:80D433*
  ID_OUI_FROM_DATABASE=LzLabs GmbH
 
@@ -61174,9 +62431,15 @@ OUI:80D733*
 OUI:80DB31*
  ID_OUI_FROM_DATABASE=Power Quotient International Co., Ltd.
 
+OUI:80E650*
+ ID_OUI_FROM_DATABASE=Apple
+
 OUI:80EA96*
  ID_OUI_FROM_DATABASE=Apple
 
+OUI:80EACA*
+ ID_OUI_FROM_DATABASE=Dialog Semiconductor Hellas SA
+
 OUI:80EE73*
  ID_OUI_FROM_DATABASE=Shuttle Inc.
 
@@ -61189,6 +62452,9 @@ OUI:80F593*
 OUI:80F62E*
  ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
 
+OUI:80F8EB*
+ ID_OUI_FROM_DATABASE=RayTight
+
 OUI:80FA5B*
  ID_OUI_FROM_DATABASE=CLEVO CO.
 
@@ -61201,6 +62467,9 @@ OUI:80FFA8*
 OUI:8400D2*
  ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB
 
+OUI:8401A7*
+ ID_OUI_FROM_DATABASE=Greyware Automation Products, Inc
+
 OUI:840B2D*
  ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS CO., LTD
 
@@ -61213,6 +62482,12 @@ OUI:841715*
 OUI:841766*
  ID_OUI_FROM_DATABASE=Weifang GoerTek Electronics Co., Ltd
 
+OUI:841826*
+ ID_OUI_FROM_DATABASE=Osram GmbH
+
+OUI:84183A*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
 OUI:841888*
  ID_OUI_FROM_DATABASE=Juniper Networks
 
@@ -61246,6 +62521,9 @@ OUI:842615*
 OUI:84262B*
  ID_OUI_FROM_DATABASE=Alcatel-Lucent
 
+OUI:842690*
+ ID_OUI_FROM_DATABASE=BEIJING THOUGHT SCIENCE CO.,LTD.
+
 OUI:8427CE*
  ID_OUI_FROM_DATABASE=Corporation of the Presiding Bishop of The Church of Jesus Christ of Latter-day Saints
 
@@ -61270,6 +62548,9 @@ OUI:842F75*
 OUI:8430E5*
  ID_OUI_FROM_DATABASE=SkyHawke Technologies, LLC
 
+OUI:8432EA*
+ ID_OUI_FROM_DATABASE=ANHUI WANZTEN P&T CO., LTD
+
 OUI:843497*
  ID_OUI_FROM_DATABASE=Hewlett Packard
 
@@ -61279,6 +62560,9 @@ OUI:843611*
 OUI:843835*
  ID_OUI_FROM_DATABASE=Apple
 
+OUI:843838*
+ ID_OUI_FROM_DATABASE=Samsung Electro Mechanics co., LTD.
+
 OUI:843A4B*
  ID_OUI_FROM_DATABASE=Intel Corporate
 
@@ -61300,6 +62584,9 @@ OUI:844F03*
 OUI:845181*
  ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
 
+OUI:8455A5*
+ ID_OUI_FROM_DATABASE=Samsung Elec Co.,Ltd
+
 OUI:84569C*
  ID_OUI_FROM_DATABASE=Coho Data, Inc.,
 
@@ -61333,6 +62620,9 @@ OUI:84742A*
 OUI:847616*
  ID_OUI_FROM_DATABASE=Addat S.r.o.
 
+OUI:84788B*
+ ID_OUI_FROM_DATABASE=Apple
+
 OUI:8478AC*
  ID_OUI_FROM_DATABASE=Cisco
 
@@ -61357,9 +62647,18 @@ OUI:848433*
 OUI:848506*
  ID_OUI_FROM_DATABASE=Apple
 
+OUI:84850A*
+ ID_OUI_FROM_DATABASE=Hella Sonnen- und Wetterschutztechnik GmbH
+
+OUI:8486F3*
+ ID_OUI_FROM_DATABASE=Greenvity Communications
+
 OUI:848D84*
  ID_OUI_FROM_DATABASE=Rajant Corporation
 
+OUI:848DC7*
+ ID_OUI_FROM_DATABASE=Cisco SPVTG
+
 OUI:848E0C*
  ID_OUI_FROM_DATABASE=Apple
 
@@ -61372,6 +62671,18 @@ OUI:848F69*
 OUI:849000*
  ID_OUI_FROM_DATABASE=Arnold & Richter Cine Technik
 
+OUI:84930C*
+ ID_OUI_FROM_DATABASE=InCoax Networks Europe AB
+
+OUI:84948C*
+ ID_OUI_FROM_DATABASE=Hitron Technologies. Inc
+
+OUI:849681*
+ ID_OUI_FROM_DATABASE=Cathay Communication Co.,Ltd
+
+OUI:8496D8*
+ ID_OUI_FROM_DATABASE=Pace plc
+
 OUI:8497B8*
  ID_OUI_FROM_DATABASE=Memjet Inc.
 
@@ -61381,6 +62692,9 @@ OUI:849CA6*
 OUI:849DC5*
  ID_OUI_FROM_DATABASE=Centera Photonics Inc.
 
+OUI:84A466*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
 OUI:84A6C8*
  ID_OUI_FROM_DATABASE=Intel Corporate
 
@@ -61399,6 +62713,9 @@ OUI:84ACA4*
 OUI:84AF1F*
  ID_OUI_FROM_DATABASE=Beat System Service Co,. Ltd.
 
+OUI:84B153*
+ ID_OUI_FROM_DATABASE=Apple
+
 OUI:84B59C*
  ID_OUI_FROM_DATABASE=Juniper networks
 
@@ -61435,6 +62752,9 @@ OUI:84DE3D*
 OUI:84DF0C*
  ID_OUI_FROM_DATABASE=NET2GRID BV
 
+OUI:84E058*
+ ID_OUI_FROM_DATABASE=Pace plc
+
 OUI:84E4D9*
  ID_OUI_FROM_DATABASE=Shenzhen NEED technology Ltd.
 
@@ -61447,6 +62767,9 @@ OUI:84E714*
 OUI:84EA99*
  ID_OUI_FROM_DATABASE=Vieworks
 
+OUI:84EB18*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
 OUI:84ED33*
  ID_OUI_FROM_DATABASE=BBMC Co.,Ltd
 
@@ -61468,6 +62791,9 @@ OUI:880355*
 OUI:880905*
  ID_OUI_FROM_DATABASE=MTMCommunications
 
+OUI:880F10*
+ ID_OUI_FROM_DATABASE=Huami Information Technology Co.,Ltd.
+
 OUI:880FB6*
  ID_OUI_FROM_DATABASE=Jabil Circuits India Pvt Ltd,-EHTP unit
 
@@ -61504,6 +62830,9 @@ OUI:8823FE*
 OUI:88252C*
  ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation
 
+OUI:882950*
+ ID_OUI_FROM_DATABASE=Dalian Netmoon Tech Develop Co.,Ltd
+
 OUI:882E5A*
  ID_OUI_FROM_DATABASE=storONE
 
@@ -61558,18 +62887,30 @@ OUI:88576D*
 OUI:885A92*
  ID_OUI_FROM_DATABASE=Cisco
 
-OUI:885C4F*
+OUI:885BDD*
+ ID_OUI_FROM_DATABASE=Aerohive Networks Inc.
+
+OUI:885C47*
  ID_OUI_FROM_DATABASE=Alcatel Lucent
 
 OUI:88615A*
  ID_OUI_FROM_DATABASE=Siano Mobile Silicon Ltd.
 
+OUI:8863DF*
+ ID_OUI_FROM_DATABASE=Apple
+
 OUI:88685C*
  ID_OUI_FROM_DATABASE=Shenzhen ChuangDao & Perpetual Eternal Technology Co.,Ltd
 
 OUI:886B76*
  ID_OUI_FROM_DATABASE=CHINA HOPEFUL GROUP HOPEFUL ELECTRIC CO.,LTD
 
+OUI:88708C*
+ ID_OUI_FROM_DATABASE=Lenovo Mobile Communication Technology Ltd.
+
+OUI:8870EF*
+ ID_OUI_FROM_DATABASE=SC Professional Trading Co., Ltd.
+
 OUI:887398*
  ID_OUI_FROM_DATABASE=K2E Tekpoint
 
@@ -61654,6 +62995,9 @@ OUI:88AE1D*
 OUI:88B168*
  ID_OUI_FROM_DATABASE=Delta Control GmbH
 
+OUI:88B1E1*
+ ID_OUI_FROM_DATABASE=AirTight Networks, Inc.
+
 OUI:88B627*
  ID_OUI_FROM_DATABASE=Gembird Europe BV
 
@@ -61672,6 +63016,9 @@ OUI:88C626*
 OUI:88C663*
  ID_OUI_FROM_DATABASE=Apple
 
+OUI:88C9D0*
+ ID_OUI_FROM_DATABASE=LG Electronics
+
 OUI:88CB87*
  ID_OUI_FROM_DATABASE=Apple
 
@@ -61711,6 +63058,9 @@ OUI:88E917*
 OUI:88ED1C*
  ID_OUI_FROM_DATABASE=Cudo Communication Co., Ltd.
 
+OUI:88F031*
+ ID_OUI_FROM_DATABASE=Cisco
+
 OUI:88F077*
  ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
 
@@ -61735,6 +63085,9 @@ OUI:8C006D*
 OUI:8C04FF*
  ID_OUI_FROM_DATABASE=Technicolor USA Inc.
 
+OUI:8C0551*
+ ID_OUI_FROM_DATABASE=Koubachi AG
+
 OUI:8C078C*
  ID_OUI_FROM_DATABASE=FLOW DATA INC
 
@@ -61756,6 +63109,9 @@ OUI:8C0EE3*
 OUI:8C11CB*
  ID_OUI_FROM_DATABASE=ABUS Security-Center GmbH & Co. KG
 
+OUI:8C18D9*
+ ID_OUI_FROM_DATABASE=Shenzhen RF Technology Co., Ltd
+
 OUI:8C1F94*
  ID_OUI_FROM_DATABASE=RF Surgical System Inc.
 
@@ -61780,6 +63136,9 @@ OUI:8C2F39*
 OUI:8C3330*
  ID_OUI_FROM_DATABASE=EmFirst Co., Ltd.
 
+OUI:8C3357*
+ ID_OUI_FROM_DATABASE=HiteVision Digital Media Technology Co.,Ltd.
+
 OUI:8C3AE3*
  ID_OUI_FROM_DATABASE=LG Electronics
 
@@ -61840,6 +63199,9 @@ OUI:8C5AF0*
 OUI:8C5CA1*
  ID_OUI_FROM_DATABASE=d-broad,INC
 
+OUI:8C5D60*
+ ID_OUI_FROM_DATABASE=UCI Corporation Co.,Ltd.
+
 OUI:8C5FDF*
  ID_OUI_FROM_DATABASE=Beijing Railway Signal Factory
 
@@ -61891,6 +63253,9 @@ OUI:8C7CFF*
 OUI:8C7EB3*
  ID_OUI_FROM_DATABASE=Lytro, Inc.
 
+OUI:8C7F3B*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
 OUI:8C82A8*
  ID_OUI_FROM_DATABASE=Insigma Technology Co.,Ltd
 
@@ -61906,6 +63271,9 @@ OUI:8C8E76*
 OUI:8C90D3*
  ID_OUI_FROM_DATABASE=Alcatel Lucent
 
+OUI:8C9109*
+ ID_OUI_FROM_DATABASE=Toyoshima Electric Technoeogy(Suzhou) Co.,Ltd.
+
 OUI:8C9236*
  ID_OUI_FROM_DATABASE=Aus.Linx Technology Co., Ltd.
 
@@ -61924,6 +63292,9 @@ OUI:8CAE4C*
 OUI:8CAE89*
  ID_OUI_FROM_DATABASE=Y-cam Solutions Ltd
 
+OUI:8CB094*
+ ID_OUI_FROM_DATABASE=Airtech I&C Co., Ltd
+
 OUI:8CB64F*
  ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
 
@@ -61939,6 +63310,9 @@ OUI:8CB864*
 OUI:8CBEBE*
  ID_OUI_FROM_DATABASE=Xiaomi Technology Co.,Ltd
 
+OUI:8CBF9D*
+ ID_OUI_FROM_DATABASE=Shanghai Xinyou Information Technology Ltd. Co.
+
 OUI:8CC121*
  ID_OUI_FROM_DATABASE=Panasonic Corporation AVC Networks Company
 
@@ -61975,6 +63349,9 @@ OUI:8CD628*
 OUI:8CDB25*
  ID_OUI_FROM_DATABASE=ESG Solutions
 
+OUI:8CDCD4*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
 OUI:8CDD8D*
  ID_OUI_FROM_DATABASE=Wifly-City System Inc.
 
@@ -61984,6 +63361,9 @@ OUI:8CDE52*
 OUI:8CDE99*
  ID_OUI_FROM_DATABASE=Comlab Inc.
 
+OUI:8CDF9D*
+ ID_OUI_FROM_DATABASE=NEC Corporation
+
 OUI:8CE081*
  ID_OUI_FROM_DATABASE=zte corporation
 
@@ -61993,6 +63373,9 @@ OUI:8CE7B3*
 OUI:8CEEC6*
  ID_OUI_FROM_DATABASE=Precepscion Pty. Ltd.
 
+OUI:8CF813*
+ ID_OUI_FROM_DATABASE=ORANGE POLSKA
+
 OUI:8CF945*
  ID_OUI_FROM_DATABASE=Power Automation pte Ltd
 
@@ -62032,6 +63415,12 @@ OUI:900D66*
 OUI:900DCB*
  ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
 
+OUI:90179B*
+ ID_OUI_FROM_DATABASE=Nanomegas
+
+OUI:9017AC*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
 OUI:90185E*
  ID_OUI_FROM_DATABASE=Apex Tool Group GmbH & Co OHG
 
@@ -62056,18 +63445,27 @@ OUI:901D27*
 OUI:901EDD*
  ID_OUI_FROM_DATABASE=GREAT COMPUTER CORPORATION
 
+OUI:90203A*
+ ID_OUI_FROM_DATABASE=BYD Precision Manufacture Co.,Ltd
+
 OUI:902083*
  ID_OUI_FROM_DATABASE=General Engine Management Systems Ltd.
 
 OUI:902155*
  ID_OUI_FROM_DATABASE=HTC Corporation
 
+OUI:902181*
+ ID_OUI_FROM_DATABASE=Shanghai Huaqin Telecom Technology Co.,Ltd
+
 OUI:9027E4*
  ID_OUI_FROM_DATABASE=Apple
 
 OUI:902B34*
  ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD.
 
+OUI:902CC7*
+ ID_OUI_FROM_DATABASE=C-MAX Asia Limited
+
 OUI:902E87*
  ID_OUI_FROM_DATABASE=LabJack
 
@@ -62107,6 +63505,9 @@ OUI:9046B7*
 OUI:904716*
  ID_OUI_FROM_DATABASE=RORZE CORPORATION
 
+OUI:90489A*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
 OUI:9049FA*
  ID_OUI_FROM_DATABASE=Intel Corporation
 
@@ -62179,6 +63580,9 @@ OUI:907A28*
 OUI:907AF1*
  ID_OUI_FROM_DATABASE=SNUPI Technologies
 
+OUI:907EBA*
+ ID_OUI_FROM_DATABASE=UTEK TECHNOLOGY (SHENZHEN) CO.,LTD
+
 OUI:907F61*
  ID_OUI_FROM_DATABASE=Chicony Electronics Co., Ltd.
 
@@ -62194,15 +63598,18 @@ OUI:90840D*
 OUI:9088A2*
  ID_OUI_FROM_DATABASE=IONICS TECHNOLOGY ME LTDA
 
+OUI:908C09*
+ ID_OUI_FROM_DATABASE=Total Phase
+
 OUI:908C44*
  ID_OUI_FROM_DATABASE=H.K ZONGMU TECHNOLOGY CO., LTD.
 
+OUI:908C63*
+ ID_OUI_FROM_DATABASE=GZ Weedong Networks Technology Co. , Ltd
+
 OUI:908D1D*
  ID_OUI_FROM_DATABASE=GH Technologies
 
-OUI:908F93*
- ID_OUI_FROM_DATABASE=MakerBot Industries
-
 OUI:908FCF*
  ID_OUI_FROM_DATABASE=UNO System Co., Ltd
 
@@ -62227,6 +63634,9 @@ OUI:909916*
 OUI:909DE0*
  ID_OUI_FROM_DATABASE=Newland Design + Assoc. Inc.
 
+OUI:909F33*
+ ID_OUI_FROM_DATABASE=EFM Networks
+
 OUI:909F43*
  ID_OUI_FROM_DATABASE=Accutron Instruments Inc.
 
@@ -62245,6 +63655,9 @@ OUI:90A7C1*
 OUI:90AC3F*
  ID_OUI_FROM_DATABASE=BrightSign LLC
 
+OUI:90AE1B*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+
 OUI:90B11C*
  ID_OUI_FROM_DATABASE=Dell Inc.
 
@@ -62254,6 +63667,9 @@ OUI:90B134*
 OUI:90B21F*
  ID_OUI_FROM_DATABASE=Apple
 
+OUI:90B686*
+ ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
+
 OUI:90B8D0*
  ID_OUI_FROM_DATABASE=Joyent, Inc.
 
@@ -62266,6 +63682,9 @@ OUI:90B97D*
 OUI:90C115*
  ID_OUI_FROM_DATABASE=Sony Ericsson Mobile Communications AB
 
+OUI:90C792*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
 OUI:90CC24*
  ID_OUI_FROM_DATABASE=Synaptics, Inc
 
@@ -62296,6 +63715,9 @@ OUI:90D92C*
 OUI:90DA4E*
  ID_OUI_FROM_DATABASE=AVANU
 
+OUI:90DA6A*
+ ID_OUI_FROM_DATABASE=FOCUS H&S Co., Ltd.
+
 OUI:90DB46*
  ID_OUI_FROM_DATABASE=E-LEAD ELECTRONIC CO., LTD
 
@@ -62303,7 +63725,7 @@ OUI:90DFB7*
  ID_OUI_FROM_DATABASE=s.m.s smart microwave sensors GmbH
 
 OUI:90E0F0*
- ID_OUI_FROM_DATABASE=Harman International
+ ID_OUI_FROM_DATABASE=IEEE 1722a Working Group
 
 OUI:90E2BA*
  ID_OUI_FROM_DATABASE=Intel Corporate
@@ -62314,6 +63736,9 @@ OUI:90E6BA*
 OUI:90EA60*
  ID_OUI_FROM_DATABASE=SPI Lasers Ltd
 
+OUI:90EF68*
+ ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
+
 OUI:90F1AA*
  ID_OUI_FROM_DATABASE=Samsung Electronics Co.,LTD
 
@@ -62341,6 +63766,9 @@ OUI:90FB5B*
 OUI:90FBA6*
  ID_OUI_FROM_DATABASE=Hon Hai Precision Ind.Co.Ltd
 
+OUI:90FD61*
+ ID_OUI_FROM_DATABASE=Apple
+
 OUI:90FF79*
  ID_OUI_FROM_DATABASE=Metro Ethernet Forum
 
@@ -62434,6 +63862,9 @@ OUI:945103*
 OUI:9451BF*
  ID_OUI_FROM_DATABASE=Hyundai ESG
 
+OUI:945493*
+ ID_OUI_FROM_DATABASE=Rigado, LLC
+
 OUI:94592D*
  ID_OUI_FROM_DATABASE=EKE Building Technology Systems Ltd
 
@@ -62443,9 +63874,15 @@ OUI:945B7E*
 OUI:946124*
  ID_OUI_FROM_DATABASE=Pason Systems
 
+OUI:946269*
+ ID_OUI_FROM_DATABASE=Arris Group, Inc.
+
 OUI:9463D1*
  ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
 
+OUI:9470D2*
+ ID_OUI_FROM_DATABASE=WINFIRM TECHNOLOGY
+
 OUI:9471AC*
  ID_OUI_FROM_DATABASE=TCT Mobile Limited
 
@@ -62509,6 +63946,12 @@ OUI:94ACCA*
 OUI:94AE61*
  ID_OUI_FROM_DATABASE=Alcatel Lucent
 
+OUI:94AEE3*
+ ID_OUI_FROM_DATABASE=Belden Hirschmann Industries (Suzhou) Ltd.
+
+OUI:94B40F*
+ ID_OUI_FROM_DATABASE=Aruba Networks
+
 OUI:94B8C5*
  ID_OUI_FROM_DATABASE=RuggedCom Inc.
 
@@ -62524,9 +63967,15 @@ OUI:94BA56*
 OUI:94BF1E*
  ID_OUI_FROM_DATABASE=eflow Inc. / Smart Device Planning and Development Division
 
+OUI:94BF95*
+ ID_OUI_FROM_DATABASE=Shenzhen Coship Electronics Co., Ltd
+
 OUI:94C014*
  ID_OUI_FROM_DATABASE=Sorter Sp. j. Konrad Grzeszczyk MichaA, Ziomek
 
+OUI:94C038*
+ ID_OUI_FROM_DATABASE=Tallac Networks
+
 OUI:94C150*
  ID_OUI_FROM_DATABASE=2Wire Inc
 
@@ -62557,9 +64006,15 @@ OUI:94CDAC*
 OUI:94CE2C*
  ID_OUI_FROM_DATABASE=Sony Mobile Communications AB
 
+OUI:94CE31*
+ ID_OUI_FROM_DATABASE=CTS Limited
+
 OUI:94D019*
  ID_OUI_FROM_DATABASE=Cydle Corp.
 
+OUI:94D60E*
+ ID_OUI_FROM_DATABASE=shenzhen yunmao information technologies co., ltd
+
 OUI:94D723*
  ID_OUI_FROM_DATABASE=Shanghai DareGlobal Technologies Co., Ltd
 
@@ -62650,6 +64105,9 @@ OUI:980D2E*
 OUI:981094*
  ID_OUI_FROM_DATABASE=Shenzhen Vsun communication technology Co.,ltd
 
+OUI:9816EC*
+ ID_OUI_FROM_DATABASE=IC Intracom
+
 OUI:98208E*
  ID_OUI_FROM_DATABASE=Definium Technologies
 
@@ -62668,6 +64126,9 @@ OUI:982CBE*
 OUI:982D56*
  ID_OUI_FROM_DATABASE=Resolution Audio
 
+OUI:982F3C*
+ ID_OUI_FROM_DATABASE=Sichuan Changhong Electric Ltd.
+
 OUI:983000*
  ID_OUI_FROM_DATABASE=Beijing KEMACOM Technologies Co., Ltd.
 
@@ -62683,6 +64144,9 @@ OUI:983571*
 OUI:9835B8*
  ID_OUI_FROM_DATABASE=Assembled Products Corporation
 
+OUI:983713*
+ ID_OUI_FROM_DATABASE=PT.Navicom Indonesia
+
 OUI:983B16*
  ID_OUI_FROM_DATABASE=AMPAK Technology Inc
 
@@ -62746,6 +64210,9 @@ OUI:986022*
 OUI:9866EA*
  ID_OUI_FROM_DATABASE=Industrial Control Communications, Inc.
 
+OUI:986B3D*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
 OUI:986CF5*
  ID_OUI_FROM_DATABASE=zte corporation
 
@@ -62761,6 +64228,9 @@ OUI:9876B6*
 OUI:987770*
  ID_OUI_FROM_DATABASE=Pep Digital Technology (Guangzhou) Co., Ltd
 
+OUI:987E46*
+ ID_OUI_FROM_DATABASE=Emizon Networks Limited
+
 OUI:988217*
  ID_OUI_FROM_DATABASE=Disruptive Ltd
 
@@ -62788,6 +64258,9 @@ OUI:988EDD*
 OUI:989080*
  ID_OUI_FROM_DATABASE=Linkpower Network System Inc Ltd.
 
+OUI:989096*
+ ID_OUI_FROM_DATABASE=Dell Inc
+
 OUI:9893CC*
  ID_OUI_FROM_DATABASE=LG Electronics Inc.
 
@@ -62812,6 +64285,9 @@ OUI:98BC57*
 OUI:98BC99*
  ID_OUI_FROM_DATABASE=Edeltech Co.,Ltd.
 
+OUI:98BE94*
+ ID_OUI_FROM_DATABASE=IBM
+
 OUI:98C0EB*
  ID_OUI_FROM_DATABASE=Global Regency Ltd
 
@@ -62854,6 +64330,9 @@ OUI:98EC65*
 OUI:98F0AB*
  ID_OUI_FROM_DATABASE=Apple
 
+OUI:98F170*
+ ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
+
 OUI:98F537*
  ID_OUI_FROM_DATABASE=zte corporation
 
@@ -62863,6 +64342,9 @@ OUI:98F8C1*
 OUI:98F8DB*
  ID_OUI_FROM_DATABASE=Marini Impianti Industriali s.r.l.
 
+OUI:98FAE3*
+ ID_OUI_FROM_DATABASE=Xiaomi inc.
+
 OUI:98FB12*
  ID_OUI_FROM_DATABASE=Grand Electronics (HK) Ltd
 
@@ -62929,6 +64411,9 @@ OUI:9C2840*
 OUI:9C28BF*
  ID_OUI_FROM_DATABASE=Continental Automotive Czech Republic s.r.o.
 
+OUI:9C28EF*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
 OUI:9C2A70*
  ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
 
@@ -62938,6 +64423,9 @@ OUI:9C3178*
 OUI:9C31B6*
  ID_OUI_FROM_DATABASE=Kulite Semiconductor Products Inc
 
+OUI:9C3583*
+ ID_OUI_FROM_DATABASE=Nipro Diagnostics, Inc
+
 OUI:9C3AAF*
  ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
 
@@ -63088,6 +64576,9 @@ OUI:9CA577*
 OUI:9CA9E4*
  ID_OUI_FROM_DATABASE=zte corporation
 
+OUI:9CAD97*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
 OUI:9CADEF*
  ID_OUI_FROM_DATABASE=Obihai Technology, Inc.
 
@@ -63121,6 +64612,9 @@ OUI:9CC077*
 OUI:9CC0D2*
  ID_OUI_FROM_DATABASE=Conductix-Wampfler AG
 
+OUI:9CC172*
+ ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd
+
 OUI:9CC7A6*
  ID_OUI_FROM_DATABASE=AVM GmbH
 
@@ -63184,9 +64678,15 @@ OUI:9CFBF1*
 OUI:9CFFBE*
  ID_OUI_FROM_DATABASE=OTSL Inc.
 
+OUI:A002DC*
+ ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
+
 OUI:A00363*
  ID_OUI_FROM_DATABASE=Robert Bosch Healthcare GmbH
 
+OUI:A00627*
+ ID_OUI_FROM_DATABASE=NEXPA System
+
 OUI:A00798*
  ID_OUI_FROM_DATABASE=Samsung Electronics
 
@@ -63205,6 +64705,9 @@ OUI:A00CA1*
 OUI:A01290*
  ID_OUI_FROM_DATABASE=Avaya, Inc
 
+OUI:A012DB*
+ ID_OUI_FROM_DATABASE=TABUCHI ELECTRIC CO.,LTD
+
 OUI:A0133B*
  ID_OUI_FROM_DATABASE=Copyright © HiTi Digital, Inc.
 
@@ -63235,6 +64738,9 @@ OUI:A021B7*
 OUI:A0231B*
  ID_OUI_FROM_DATABASE=TeleComp R&D Corp.
 
+OUI:A02BB8*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
 OUI:A02EF3*
  ID_OUI_FROM_DATABASE=United Integrated Services Co., Led.
 
@@ -63280,6 +64786,9 @@ OUI:A051C6*
 OUI:A055DE*
  ID_OUI_FROM_DATABASE=Pace plc
 
+OUI:A056B2*
+ ID_OUI_FROM_DATABASE=Harman/Becker Automotive Systems GmbH
+
 OUI:A0593A*
  ID_OUI_FROM_DATABASE=V.D.S. Video Display Systems srl
 
@@ -63370,6 +64879,9 @@ OUI:A08C9B*
 OUI:A090DE*
  ID_OUI_FROM_DATABASE=VEEDIMS,LLC
 
+OUI:A09347*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD.
+
 OUI:A09805*
  ID_OUI_FROM_DATABASE=OpenVox Communication Co Ltd
 
@@ -63388,6 +64900,9 @@ OUI:A0A130*
 OUI:A0A23C*
  ID_OUI_FROM_DATABASE=GPMS
 
+OUI:A0A3E2*
+ ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc
+
 OUI:A0A763*
  ID_OUI_FROM_DATABASE=Polytron Vertrieb GmbH
 
@@ -63403,6 +64918,9 @@ OUI:A0B100*
 OUI:A0B3CC*
  ID_OUI_FROM_DATABASE=Hewlett Packard
 
+OUI:A0B4A5*
+ ID_OUI_FROM_DATABASE=Samsung Elec Co.,Ltd
+
 OUI:A0B5DA*
  ID_OUI_FROM_DATABASE=HongKong THTF Co., Ltd
 
@@ -63439,6 +64957,9 @@ OUI:A0D12A*
 OUI:A0D3C1*
  ID_OUI_FROM_DATABASE=Hewlett Packard
 
+OUI:A0DA92*
+ ID_OUI_FROM_DATABASE=Nanjing Glarun Atten Technology Co. Ltd.
+
 OUI:A0DC04*
  ID_OUI_FROM_DATABASE=Becker-Antriebe GmbH
 
@@ -63469,6 +64990,9 @@ OUI:A0E534*
 OUI:A0E5E9*
  ID_OUI_FROM_DATABASE=enimai Inc
 
+OUI:A0E6F8*
+ ID_OUI_FROM_DATABASE=Texas Instruments Inc
+
 OUI:A0E9DB*
  ID_OUI_FROM_DATABASE=Ningbo FreeWings Technologies Co.,Ltd
 
@@ -63502,6 +65026,9 @@ OUI:A0F450*
 OUI:A0F459*
  ID_OUI_FROM_DATABASE=FN-LINK TECHNOLOGY LIMITED
 
+OUI:A0FC6E*
+ ID_OUI_FROM_DATABASE=Telegrafia a.s.
+
 OUI:A0FE91*
  ID_OUI_FROM_DATABASE=AVAT Automation GmbH
 
@@ -63520,6 +65047,9 @@ OUI:A40BED*
 OUI:A40CC3*
  ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
 
+OUI:A41242*
+ ID_OUI_FROM_DATABASE=NEC Platforms, Ltd.
+
 OUI:A4134E*
  ID_OUI_FROM_DATABASE=Luxul
 
@@ -63547,6 +65077,9 @@ OUI:A42305*
 OUI:A424B3*
  ID_OUI_FROM_DATABASE=FlatFrog Laboratories AB
 
+OUI:A4251B*
+ ID_OUI_FROM_DATABASE=Avaya, Inc
+
 OUI:A42940*
  ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd
 
@@ -63565,12 +65098,21 @@ OUI:A438FC*
 OUI:A43A69*
  ID_OUI_FROM_DATABASE=Vers Inc
 
+OUI:A43BFA*
+ ID_OUI_FROM_DATABASE=IEEE REGISTRATION AUTHORITY  - Please see MAM public listing for more information.
+
+OUI:A43D78*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
 OUI:A4466B*
  ID_OUI_FROM_DATABASE=EOC Technology
 
 OUI:A446FA*
  ID_OUI_FROM_DATABASE=AmTRAN Video Corporation
 
+OUI:A44AD3*
+ ID_OUI_FROM_DATABASE=ST Electronics(Shanghai) Co.,Ltd
+
 OUI:A44B15*
  ID_OUI_FROM_DATABASE=Sun Cupid Technology (HK) LTD
 
@@ -63604,6 +65146,12 @@ OUI:A45C27*
 OUI:A45D36*
  ID_OUI_FROM_DATABASE=Hewlett Packard
 
+OUI:A45DA1*
+ ID_OUI_FROM_DATABASE=ADB Broadband Italia
+
+OUI:A46032*
+ ID_OUI_FROM_DATABASE=MRV Communications (Networks) LTD
+
 OUI:A46706*
  ID_OUI_FROM_DATABASE=Apple
 
@@ -63613,6 +65161,9 @@ OUI:A46CC1*
 OUI:A46E79*
  ID_OUI_FROM_DATABASE=DFT System Co.Ltd
 
+OUI:A470D6*
+ ID_OUI_FROM_DATABASE=Motorola Mobility LLC
+
 OUI:A47733*
  ID_OUI_FROM_DATABASE=Google
 
@@ -63632,7 +65183,13 @@ OUI:A47C14*
  ID_OUI_FROM_DATABASE=ChargeStorm AB
 
 OUI:A47C1F*
- ID_OUI_FROM_DATABASE=Global Microwave Systems Inc.
+ ID_OUI_FROM_DATABASE=Cobham plc
+
+OUI:A47E39*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:A481EE*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
 
 OUI:A4856B*
  ID_OUI_FROM_DATABASE=Q Electronics Ltd
@@ -63661,15 +65218,27 @@ OUI:A49A58*
 OUI:A49B13*
  ID_OUI_FROM_DATABASE=Burroughs Payment Systems, Inc.
 
+OUI:A49D49*
+ ID_OUI_FROM_DATABASE=Ketra, Inc.
+
 OUI:A49EDB*
  ID_OUI_FROM_DATABASE=AutoCrib, Inc.
 
+OUI:A49F85*
+ ID_OUI_FROM_DATABASE=Lyve Minds, Inc
+
 OUI:A49F89*
  ID_OUI_FROM_DATABASE=Shanghai Rui Rui Communication Technology Co.Ltd.
 
+OUI:A4A1C2*
+ ID_OUI_FROM_DATABASE=Ericsson AB (EAB)
+
 OUI:A4A24A*
  ID_OUI_FROM_DATABASE=Cisco SPVTG
 
+OUI:A4A4D3*
+ ID_OUI_FROM_DATABASE=Bluebank Communication Technology Co.Ltd
+
 OUI:A4A80F*
  ID_OUI_FROM_DATABASE=Shenzhen Coship Electronics Co., Ltd.
 
@@ -63746,7 +65315,7 @@ OUI:A4D3B5*
  ID_OUI_FROM_DATABASE=GLITEL Stropkov, s.r.o.
 
 OUI:A4D856*
- ID_OUI_FROM_DATABASE=Qualcomm Labs Inc.
+ ID_OUI_FROM_DATABASE=Gimbal, Inc
 
 OUI:A4DA3F*
  ID_OUI_FROM_DATABASE=Bionics Corp.
@@ -63820,6 +65389,9 @@ OUI:A80600*
 OUI:A80C0D*
  ID_OUI_FROM_DATABASE=Cisco
 
+OUI:A81374*
+ ID_OUI_FROM_DATABASE=Panasonic Corporation AVC Networks Company
+
 OUI:A8154D*
  ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
 
@@ -63832,6 +65404,9 @@ OUI:A81758*
 OUI:A81B18*
  ID_OUI_FROM_DATABASE=XTS CORP
 
+OUI:A81B5D*
+ ID_OUI_FROM_DATABASE=Foxtel Management Pty Ltd
+
 OUI:A81FAF*
  ID_OUI_FROM_DATABASE=KRYPTON POLSKA
 
@@ -63853,6 +65428,9 @@ OUI:A82BD6*
 OUI:A830AD*
  ID_OUI_FROM_DATABASE=Wei Fang Goertek Electronics Co.,Ltd
 
+OUI:A8329A*
+ ID_OUI_FROM_DATABASE=Digicom Futuristic Technologies Ltd.
+
 OUI:A83944*
  ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc
 
@@ -63916,6 +65494,9 @@ OUI:A8776F*
 OUI:A87B39*
  ID_OUI_FROM_DATABASE=Nokia Corporation
 
+OUI:A87C01*
+ ID_OUI_FROM_DATABASE=Samsung Elec Co.,Ltd
+
 OUI:A87E33*
  ID_OUI_FROM_DATABASE=Nokia Danmark A/S
 
@@ -63940,6 +65521,9 @@ OUI:A88CEE*
 OUI:A88D7B*
  ID_OUI_FROM_DATABASE=SunDroid Global limited.
 
+OUI:A88E24*
+ ID_OUI_FROM_DATABASE=Apple
+
 OUI:A8922C*
  ID_OUI_FROM_DATABASE=LG Electronics
 
@@ -63964,6 +65548,12 @@ OUI:A8995C*
 OUI:A89B10*
  ID_OUI_FROM_DATABASE=inMotion Ltd.
 
+OUI:A89DD2*
+ ID_OUI_FROM_DATABASE=Shanghai DareGlobal Technologies Co., Ltd
+
+OUI:A8A668*
+ ID_OUI_FROM_DATABASE=zte corporation
+
 OUI:A8AD3D*
  ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd
 
@@ -63997,6 +65587,9 @@ OUI:A8CCC5*
 OUI:A8CE90*
  ID_OUI_FROM_DATABASE=CVC
 
+OUI:A8D0E3*
+ ID_OUI_FROM_DATABASE=Systech Electronics Ltd.
+
 OUI:A8D0E5*
  ID_OUI_FROM_DATABASE=Juniper Networks
 
@@ -64006,12 +65599,18 @@ OUI:A8D236*
 OUI:A8D3C8*
  ID_OUI_FROM_DATABASE=Wachendorff Elektronik  GmbH & Co. KG
 
+OUI:A8D88A*
+ ID_OUI_FROM_DATABASE=Wyconn
+
 OUI:A8E018*
  ID_OUI_FROM_DATABASE=Nokia Corporation
 
 OUI:A8E3EE*
  ID_OUI_FROM_DATABASE=Sony Computer Entertainment Inc.
 
+OUI:A8E539*
+ ID_OUI_FROM_DATABASE=Moimstone Co.,Ltd
+
 OUI:A8EF26*
  ID_OUI_FROM_DATABASE=Tritonwave
 
@@ -64021,6 +65620,9 @@ OUI:A8F274*
 OUI:A8F470*
  ID_OUI_FROM_DATABASE=Fujian Newland Communication Science Technologies Co.,Ltd.
 
+OUI:A8F7E0*
+ ID_OUI_FROM_DATABASE=PLANET Technology Corporation
+
 OUI:A8F94B*
  ID_OUI_FROM_DATABASE=Eltex Enterprise Ltd.
 
@@ -64069,6 +65671,9 @@ OUI:AC0A61*
 OUI:AC0DFE*
  ID_OUI_FROM_DATABASE=Ekon GmbH - myGEKKO
 
+OUI:AC11D3*
+ ID_OUI_FROM_DATABASE=Suzhou HOTEK  Video Technology Co. Ltd
+
 OUI:AC1461*
  ID_OUI_FROM_DATABASE=ATAW  Co., Ltd.
 
@@ -64108,6 +65713,12 @@ OUI:AC34CB*
 OUI:AC3613*
  ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
 
+OUI:AC3870*
+ ID_OUI_FROM_DATABASE=Lenovo Mobile Communication Technology Ltd.
+
+OUI:AC3A7A*
+ ID_OUI_FROM_DATABASE=Roku
+
 OUI:AC3C0B*
  ID_OUI_FROM_DATABASE=Apple
 
@@ -64228,6 +65839,9 @@ OUI:AC8674*
 OUI:AC867E*
  ID_OUI_FROM_DATABASE=Create New Technology (HK) Limited Company
 
+OUI:AC87A3*
+ ID_OUI_FROM_DATABASE=Apple
+
 OUI:AC8ACD*
  ID_OUI_FROM_DATABASE=ROGER D.Wensker, G.Wensker sp.j.
 
@@ -64252,18 +65866,36 @@ OUI:AC9CE4*
 OUI:ACA016*
  ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
 
+OUI:ACA213*
+ ID_OUI_FROM_DATABASE=Shenzhen Bilian electronic CO.,LTD
+
 OUI:ACA22C*
  ID_OUI_FROM_DATABASE=Baycity Technologies Ltd
 
+OUI:ACA31E*
+ ID_OUI_FROM_DATABASE=Aruba Networks
+
 OUI:ACA430*
  ID_OUI_FROM_DATABASE=Peerless AV
 
+OUI:ACA919*
+ ID_OUI_FROM_DATABASE=TrekStor GmbH
+
+OUI:ACA9A0*
+ ID_OUI_FROM_DATABASE=Audioengine, Ltd.
+
 OUI:ACAB8D*
  ID_OUI_FROM_DATABASE=Lyngso Marine A/S
 
 OUI:ACB313*
  ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
 
+OUI:ACB74F*
+ ID_OUI_FROM_DATABASE=METEL s.r.o.
+
+OUI:ACB859*
+ ID_OUI_FROM_DATABASE=Uniband Electronic Corp,
+
 OUI:ACBD0B*
  ID_OUI_FROM_DATABASE=IMAC CO.,LTD
 
@@ -64372,12 +66004,24 @@ OUI:ACF7F3*
 OUI:ACF97E*
  ID_OUI_FROM_DATABASE=ELESYS INC.
 
+OUI:ACFDCE*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
 OUI:ACFDEC*
  ID_OUI_FROM_DATABASE=Apple, Inc
 
+OUI:B000B4*
+ ID_OUI_FROM_DATABASE=Cisco
+
 OUI:B00594*
  ID_OUI_FROM_DATABASE=Liteon Technology Corporation
 
+OUI:B009D3*
+ ID_OUI_FROM_DATABASE=Avizia
+
+OUI:B01041*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
 OUI:B01203*
  ID_OUI_FROM_DATABASE=Dynamics Hong Kong Limited
 
@@ -64396,6 +66040,9 @@ OUI:B01B7C*
 OUI:B01C91*
  ID_OUI_FROM_DATABASE=Elim Co
 
+OUI:B01F81*
+ ID_OUI_FROM_DATABASE=IEEE REGISTRATION AUTHORITY  - Please see MAM public listing for more information.
+
 OUI:B024F3*
  ID_OUI_FROM_DATABASE=Progeny Systems
 
@@ -64414,6 +66061,9 @@ OUI:B03850*
 OUI:B0435D*
  ID_OUI_FROM_DATABASE=NuLEDs, Inc.
 
+OUI:B04515*
+ ID_OUI_FROM_DATABASE=mira fitness,LLC.
+
 OUI:B04545*
  ID_OUI_FROM_DATABASE=YACOUB Automation GmbH
 
@@ -64441,6 +66091,9 @@ OUI:B058C4*
 OUI:B05B1F*
  ID_OUI_FROM_DATABASE=THERMO FISHER SCIENTIFIC S.P.A.
 
+OUI:B05B67*
+ ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd
+
 OUI:B05CE5*
  ID_OUI_FROM_DATABASE=Nokia Corporation
 
@@ -64465,6 +66118,9 @@ OUI:B06CBF*
 OUI:B0750C*
  ID_OUI_FROM_DATABASE=QA Cafe
 
+OUI:B0754D*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent
+
 OUI:B075D5*
  ID_OUI_FROM_DATABASE=ZTE Corporation
 
@@ -64489,6 +66145,9 @@ OUI:B0808C*
 OUI:B081D8*
  ID_OUI_FROM_DATABASE=I-sys Corp
 
+OUI:B083FE*
+ ID_OUI_FROM_DATABASE=Dell Inc
+
 OUI:B0869E*
  ID_OUI_FROM_DATABASE=Chloride S.r.L
 
@@ -64507,6 +66166,9 @@ OUI:B09074*
 OUI:B09134*
  ID_OUI_FROM_DATABASE=Taleo
 
+OUI:B09137*
+ ID_OUI_FROM_DATABASE=ISis ImageStream Internet Solutions, Inc
+
 OUI:B0973A*
  ID_OUI_FROM_DATABASE=E-Fuel Corporation
 
@@ -64528,9 +66190,15 @@ OUI:B09FBA*
 OUI:B0A10A*
  ID_OUI_FROM_DATABASE=Pivotal Systems Corporation
 
+OUI:B0A37E*
+ ID_OUI_FROM_DATABASE=Qingdao Haier Electronics Co.,Ltd
+
 OUI:B0A72A*
  ID_OUI_FROM_DATABASE=Ensemble Designs, Inc.
 
+OUI:B0A737*
+ ID_OUI_FROM_DATABASE=Roku, Inc.
+
 OUI:B0A86E*
  ID_OUI_FROM_DATABASE=Juniper Networks
 
@@ -64597,6 +66265,9 @@ OUI:B0D09C*
 OUI:B0D2F5*
  ID_OUI_FROM_DATABASE=Vello Systems, Inc.
 
+OUI:B0D59D*
+ ID_OUI_FROM_DATABASE=Shenzhen Zowee Technology Co., Ltd
+
 OUI:B0D7C5*
  ID_OUI_FROM_DATABASE=STP KFT
 
@@ -64651,6 +66322,12 @@ OUI:B407F9*
 OUI:B40832*
  ID_OUI_FROM_DATABASE=TC Communications
 
+OUI:B40AC6*
+ ID_OUI_FROM_DATABASE=DEXON Systems Ltd.
+
+OUI:B40B44*
+ ID_OUI_FROM_DATABASE=Smartisan Technology Co., Ltd.
+
 OUI:B40B7A*
  ID_OUI_FROM_DATABASE=Brusa Elektronik AG
 
@@ -64669,6 +66346,9 @@ OUI:B41489*
 OUI:B41513*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
 
+OUI:B41780*
+ ID_OUI_FROM_DATABASE=DTI Group Ltd
+
 OUI:B418D1*
  ID_OUI_FROM_DATABASE=Apple
 
@@ -64711,6 +66391,9 @@ OUI:B435F7*
 OUI:B43741*
  ID_OUI_FROM_DATABASE=Consert, Inc.
 
+OUI:B43934*
+ ID_OUI_FROM_DATABASE=Pen Generations, Inc.
+
 OUI:B439D6*
  ID_OUI_FROM_DATABASE=ProCurve Networking by HP
 
@@ -64729,6 +66412,9 @@ OUI:B4417A*
 OUI:B4430D*
  ID_OUI_FROM_DATABASE=Broadlink Pty Ltd
 
+OUI:B4475E*
+ ID_OUI_FROM_DATABASE=Avaya, Inc
+
 OUI:B44CC2*
  ID_OUI_FROM_DATABASE=NR ELECTRIC CO., LTD
 
@@ -64777,6 +66463,12 @@ OUI:B4749F*
 OUI:B4750E*
  ID_OUI_FROM_DATABASE=Belkin International Inc.
 
+OUI:B479A7*
+ ID_OUI_FROM_DATABASE=Samsung Electro Mechanics co., LTD.
+
+OUI:B47C29*
+ ID_OUI_FROM_DATABASE=Shenzhen Guzidi Technology Co.,Ltd
+
 OUI:B47F5E*
  ID_OUI_FROM_DATABASE=Foresight Manufacture (S) Pte Ltd
 
@@ -64813,6 +66505,9 @@ OUI:B499BA*
 OUI:B49DB4*
  ID_OUI_FROM_DATABASE=Axion Technologies Inc.
 
+OUI:B49EAC*
+ ID_OUI_FROM_DATABASE=Imagik Int'l Corp
+
 OUI:B49EE6*
  ID_OUI_FROM_DATABASE=SHENZHEN TECHNOLOGY CO LTD
 
@@ -64825,6 +66520,9 @@ OUI:B4A4E3*
 OUI:B4A5A9*
  ID_OUI_FROM_DATABASE=MODI GmbH
 
+OUI:B4A828*
+ ID_OUI_FROM_DATABASE=Shenzhen Concox Information Technology Co., Ltd
+
 OUI:B4A82B*
  ID_OUI_FROM_DATABASE=Histar Digital Electronics Co., Ltd.
 
@@ -64837,6 +66535,9 @@ OUI:B4AA4D*
 OUI:B4AB2C*
  ID_OUI_FROM_DATABASE=MtM Technology Corporation
 
+OUI:B4AE6F*
+ ID_OUI_FROM_DATABASE=Circle Reliance, Inc.
+
 OUI:B4B017*
  ID_OUI_FROM_DATABASE=Avaya, Inc
 
@@ -64855,6 +66556,9 @@ OUI:B4B5AF*
 OUI:B4B676*
  ID_OUI_FROM_DATABASE=Intel Corporate
 
+OUI:B4B859*
+ ID_OUI_FROM_DATABASE=Texa Spa
+
 OUI:B4B88D*
  ID_OUI_FROM_DATABASE=Thuh Company
 
@@ -64870,6 +66574,9 @@ OUI:B4C810*
 OUI:B4CCE9*
  ID_OUI_FROM_DATABASE=PROSYST
 
+OUI:B4CEF6*
+ ID_OUI_FROM_DATABASE=HTC Corporation
+
 OUI:B4CFDB*
  ID_OUI_FROM_DATABASE=Shenzhen Jiuzhou Electric Co.,LTD
 
@@ -64900,6 +66607,9 @@ OUI:B4ED19*
 OUI:B4ED54*
  ID_OUI_FROM_DATABASE=Wohler Technologies
 
+OUI:B4EEB4*
+ ID_OUI_FROM_DATABASE=ASKEY COMPUTER CORP
+
 OUI:B4EED4*
  ID_OUI_FROM_DATABASE=Texas Instruments
 
@@ -64924,6 +66634,9 @@ OUI:B80305*
 OUI:B80415*
  ID_OUI_FROM_DATABASE=Bayan Audio
 
+OUI:B808CF*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
 OUI:B80B9D*
  ID_OUI_FROM_DATABASE=ROPEX Industrie-Elektronik GmbH
 
@@ -64936,6 +66649,9 @@ OUI:B81619*
 OUI:B817C2*
  ID_OUI_FROM_DATABASE=Apple
 
+OUI:B8186F*
+ ID_OUI_FROM_DATABASE=ORIENTAL MOTOR CO., LTD.
+
 OUI:B81999*
  ID_OUI_FROM_DATABASE=Nesys
 
@@ -64963,6 +66679,9 @@ OUI:B8288B*
 OUI:B829F7*
  ID_OUI_FROM_DATABASE=Blaster Tech
 
+OUI:B82A72*
+ ID_OUI_FROM_DATABASE=Dell Inc
+
 OUI:B82ADC*
  ID_OUI_FROM_DATABASE=EFR Europäische Funk-Rundsteuerung GmbH
 
@@ -64999,6 +66718,9 @@ OUI:B843E4*
 OUI:B847C6*
  ID_OUI_FROM_DATABASE=SanJet Technology Corp.
 
+OUI:B84FD5*
+ ID_OUI_FROM_DATABASE=Microsoft Corporation
+
 OUI:B85510*
  ID_OUI_FROM_DATABASE=Zioncom Electronics (Shenzhen) Ltd.
 
@@ -65047,6 +66769,9 @@ OUI:B87424*
 OUI:B87447*
  ID_OUI_FROM_DATABASE=Convergence Technologies
 
+OUI:B875C0*
+ ID_OUI_FROM_DATABASE=PayPal, Inc.
+
 OUI:B8763F*
  ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
 
@@ -65062,6 +66787,9 @@ OUI:B8797E*
 OUI:B87AC9*
  ID_OUI_FROM_DATABASE=Siemens Ltd.
 
+OUI:B87CF2*
+ ID_OUI_FROM_DATABASE=Aerohive Networks Inc.
+
 OUI:B8871E*
  ID_OUI_FROM_DATABASE=Good Mind Industries Co., Ltd.
 
@@ -65104,12 +66832,18 @@ OUI:B898B0*
 OUI:B898F7*
  ID_OUI_FROM_DATABASE=Gionee Communication Equipment Co,Ltd.ShenZhen
 
+OUI:B89919*
+ ID_OUI_FROM_DATABASE=7signal Solutions, Inc
+
 OUI:B89AED*
  ID_OUI_FROM_DATABASE=OceanServer Technology, Inc
 
 OUI:B89BC9*
  ID_OUI_FROM_DATABASE=SMC Networks Inc
 
+OUI:B89BE4*
+ ID_OUI_FROM_DATABASE=ABB Power Systems Power Generation
+
 OUI:B8A386*
  ID_OUI_FROM_DATABASE=D-Link International
 
@@ -65122,9 +66856,15 @@ OUI:B8A8AF*
 OUI:B8AC6F*
  ID_OUI_FROM_DATABASE=Dell Inc
 
+OUI:B8AD3E*
+ ID_OUI_FROM_DATABASE=BLUECOM
+
 OUI:B8AE6E*
  ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
 
+OUI:B8AEED*
+ ID_OUI_FROM_DATABASE=Elitegroup Computer Systems Co., Ltd.
+
 OUI:B8AF67*
  ID_OUI_FROM_DATABASE=Hewlett-Packard Company
 
@@ -65149,9 +66889,15 @@ OUI:B8BA72*
 OUI:B8BB6D*
  ID_OUI_FROM_DATABASE=ENERES Co.,Ltd.
 
+OUI:B8BD79*
+ ID_OUI_FROM_DATABASE=TrendPoint Systems
+
 OUI:B8BEBF*
  ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
 
+OUI:B8BF83*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
 OUI:B8C1A2*
  ID_OUI_FROM_DATABASE=Dragon Path Technologies Co., Limited
 
@@ -65171,7 +66917,7 @@ OUI:B8C855*
  ID_OUI_FROM_DATABASE=Shanghai GBCOM Communication Technology Co.,Ltd.
 
 OUI:B8CA3A*
- ID_OUI_FROM_DATABASE=Dell PCBA Test
+ ID_OUI_FROM_DATABASE=Dell Inc
 
 OUI:B8CD93*
  ID_OUI_FROM_DATABASE=Penetek, Inc
@@ -65185,6 +66931,9 @@ OUI:B8D06F*
 OUI:B8D49D*
  ID_OUI_FROM_DATABASE=M Seven System Ltd.
 
+OUI:B8D812*
+ ID_OUI_FROM_DATABASE=IEEE REGISTRATION AUTHORITY  - Please see MAM public listing for more information.
+
 OUI:B8D9CE*
  ID_OUI_FROM_DATABASE=Samsung Electronics
 
@@ -65215,9 +66964,15 @@ OUI:B8E856*
 OUI:B8E937*
  ID_OUI_FROM_DATABASE=Sonos, Inc.
 
+OUI:B8EE65*
+ ID_OUI_FROM_DATABASE=Liteon Technology Corporation
+
 OUI:B8EE79*
  ID_OUI_FROM_DATABASE=YWire Technologies, Inc.
 
+OUI:B8F317*
+ ID_OUI_FROM_DATABASE=iSun Smasher Communications Private Limited
+
 OUI:B8F4D0*
  ID_OUI_FROM_DATABASE=Herrmann Ultraschalltechnik GmbH & Co. Kg
 
@@ -65275,6 +67030,9 @@ OUI:BC15A6*
 OUI:BC1665*
  ID_OUI_FROM_DATABASE=Cisco
 
+OUI:BC16F5*
+ ID_OUI_FROM_DATABASE=Cisco
+
 OUI:BC1A67*
  ID_OUI_FROM_DATABASE=YF Technology Co., Ltd
 
@@ -65284,6 +67042,9 @@ OUI:BC20A4*
 OUI:BC20BA*
  ID_OUI_FROM_DATABASE=Inspur (Shandong) Electronic Information Co., Ltd
 
+OUI:BC25F0*
+ ID_OUI_FROM_DATABASE=3D Display Technologies Co., Ltd.
+
 OUI:BC261D*
  ID_OUI_FROM_DATABASE=HONG KONG TECON TECHNOLOGY
 
@@ -65311,6 +67072,9 @@ OUI:BC305B*
 OUI:BC307D*
  ID_OUI_FROM_DATABASE=Wistron Neweb Corp.
 
+OUI:BC3400*
+ ID_OUI_FROM_DATABASE=IEEE REGISTRATION AUTHORITY  - Please see MAM public listing for more information.
+
 OUI:BC35E5*
  ID_OUI_FROM_DATABASE=Hydro Systems Company
 
@@ -65344,6 +67108,9 @@ OUI:BC4B79*
 OUI:BC4E3C*
  ID_OUI_FROM_DATABASE=CORE STAFF CO., LTD.
 
+OUI:BC4E5D*
+ ID_OUI_FROM_DATABASE=ZhongMiao Technology Co., Ltd.
+
 OUI:BC51FE*
  ID_OUI_FROM_DATABASE=Swann Communications Pty Ltd
 
@@ -65356,6 +67123,12 @@ OUI:BC5FF4*
 OUI:BC629F*
  ID_OUI_FROM_DATABASE=Telenet Systems P. Ltd.
 
+OUI:BC6641*
+ ID_OUI_FROM_DATABASE=IEEE REGISTRATION AUTHORITY  - Please see MAM public listing for more information.
+
+OUI:BC671C*
+ ID_OUI_FROM_DATABASE=Cisco
+
 OUI:BC6778*
  ID_OUI_FROM_DATABASE=Apple
 
@@ -65368,6 +67141,9 @@ OUI:BC6A16*
 OUI:BC6A29*
  ID_OUI_FROM_DATABASE=Texas Instruments
 
+OUI:BC6B4D*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent
+
 OUI:BC6E76*
  ID_OUI_FROM_DATABASE=Green Energy Options Ltd
 
@@ -65419,6 +67195,9 @@ OUI:BC8B55*
 OUI:BC8CCD*
  ID_OUI_FROM_DATABASE=Samsung Electro Mechanics co.,LTD.
 
+OUI:BC8D0E*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent
+
 OUI:BC926B*
  ID_OUI_FROM_DATABASE=Apple
 
@@ -65431,6 +67210,9 @@ OUI:BC9889*
 OUI:BC99BC*
  ID_OUI_FROM_DATABASE=FonSee Technology Inc.
 
+OUI:BC9CC5*
+ ID_OUI_FROM_DATABASE=Beijing Huafei Technology Co., Ltd.
+
 OUI:BC9DA5*
  ID_OUI_FROM_DATABASE=DASCOM Europe GmbH
 
@@ -65458,12 +67240,18 @@ OUI:BCBAE1*
 OUI:BCBBC9*
  ID_OUI_FROM_DATABASE=Kellendonk Elektronik GmbH
 
+OUI:BCBC46*
+ ID_OUI_FROM_DATABASE=SKS Welding Systems GmbH
+
 OUI:BCC168*
  ID_OUI_FROM_DATABASE=DinBox Sverige AB
 
 OUI:BCC23A*
  ID_OUI_FROM_DATABASE=Thomson Video Networks
 
+OUI:BCC342*
+ ID_OUI_FROM_DATABASE=Panasonic System Networks Co., Ltd.
+
 OUI:BCC61A*
  ID_OUI_FROM_DATABASE=SPECTRA EMBEDDED SYSTEMS
 
@@ -65473,6 +67261,9 @@ OUI:BCC6DB*
 OUI:BCC810*
  ID_OUI_FROM_DATABASE=Cisco SPVTG
 
+OUI:BCCAB5*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
 OUI:BCCD45*
  ID_OUI_FROM_DATABASE=VOISMART
 
@@ -65482,6 +67273,9 @@ OUI:BCCFCC*
 OUI:BCD177*
  ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
 
+OUI:BCD1D3*
+ ID_OUI_FROM_DATABASE=Tinno Mobile Technology Corp
+
 OUI:BCD5B6*
  ID_OUI_FROM_DATABASE=d2d technologies
 
@@ -65497,6 +67291,9 @@ OUI:BCE59F*
 OUI:BCEA2B*
  ID_OUI_FROM_DATABASE=CityCom GmbH
 
+OUI:BCEAFA*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
 OUI:BCEE7B*
  ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
 
@@ -65566,12 +67363,18 @@ OUI:C03580*
 OUI:C035BD*
  ID_OUI_FROM_DATABASE=Velocytech Aps
 
+OUI:C03896*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
 OUI:C038F9*
  ID_OUI_FROM_DATABASE=Nokia Danmark A/S
 
 OUI:C03B8F*
  ID_OUI_FROM_DATABASE=Minicom Digital Signage
 
+OUI:C03D46*
+ ID_OUI_FROM_DATABASE=Shanghai Mochui Network Technology Co., Ltd
+
 OUI:C03E0F*
  ID_OUI_FROM_DATABASE=BSkyB Ltd
 
@@ -65602,6 +67405,9 @@ OUI:C04A00*
 OUI:C04DF7*
  ID_OUI_FROM_DATABASE=SERELEC
 
+OUI:C056E3*
+ ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd.
+
 OUI:C057BC*
  ID_OUI_FROM_DATABASE=Avaya, Inc
 
@@ -65614,6 +67420,9 @@ OUI:C05E6F*
 OUI:C05E79*
  ID_OUI_FROM_DATABASE=SHENZHEN HUAXUN ARK TECHNOLOGIES CO.,LTD
 
+OUI:C06118*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+
 OUI:C0626B*
  ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
 
@@ -65668,6 +67477,9 @@ OUI:C09132*
 OUI:C09134*
  ID_OUI_FROM_DATABASE=ProCurve Networking by HP
 
+OUI:C09879*
+ ID_OUI_FROM_DATABASE=Acer Inc.
+
 OUI:C098E5*
  ID_OUI_FROM_DATABASE=University of Michigan
 
@@ -65767,9 +67579,15 @@ OUI:C0E54E*
 OUI:C0EAE4*
  ID_OUI_FROM_DATABASE=Sonicwall
 
+OUI:C0EEFB*
+ ID_OUI_FROM_DATABASE=OnePlus Tech (Shenzhen) Ltd
+
 OUI:C0F1C4*
  ID_OUI_FROM_DATABASE=Pacidal Corporation Ltd.
 
+OUI:C0F2FB*
+ ID_OUI_FROM_DATABASE=Apple
+
 OUI:C0F79D*
  ID_OUI_FROM_DATABASE=Powercode
 
@@ -65779,6 +67597,9 @@ OUI:C0F8DA*
 OUI:C0F991*
  ID_OUI_FROM_DATABASE=GME Standard Communications P/L
 
+OUI:C40006*
+ ID_OUI_FROM_DATABASE=Lipi Data Systems Ltd.
+
 OUI:C40142*
  ID_OUI_FROM_DATABASE=MaxMedia Technology Limited
 
@@ -65788,12 +67609,21 @@ OUI:C4017C*
 OUI:C401B1*
  ID_OUI_FROM_DATABASE=SeekTech INC
 
+OUI:C401CE*
+ ID_OUI_FROM_DATABASE=PRESITION (2000) CO., LTD.
+
 OUI:C40415*
  ID_OUI_FROM_DATABASE=NETGEAR INC.,
 
 OUI:C40528*
  ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd
 
+OUI:C4084A*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent
+
+OUI:C40880*
+ ID_OUI_FROM_DATABASE=Shenzhen UTEPO Tech Co., Ltd.
+
 OUI:C40938*
  ID_OUI_FROM_DATABASE=Fujian Star-net Communication Co., Ltd
 
@@ -65848,6 +67678,9 @@ OUI:C4291D*
 OUI:C42C03*
  ID_OUI_FROM_DATABASE=Apple
 
+OUI:C4346B*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
 OUI:C436DA*
  ID_OUI_FROM_DATABASE=Rusteletech Ltd.
 
@@ -65866,6 +67699,9 @@ OUI:C43C3C*
 OUI:C43DC7*
  ID_OUI_FROM_DATABASE=NETGEAR
 
+OUI:C44202*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
 OUI:C4438F*
  ID_OUI_FROM_DATABASE=LG Electronics
 
@@ -65887,6 +67723,9 @@ OUI:C44AD0*
 OUI:C44B44*
  ID_OUI_FROM_DATABASE=Omniprint Inc.
 
+OUI:C44BD1*
+ ID_OUI_FROM_DATABASE=Wallys Communications  Teachnologies Co.,Ltd.
+
 OUI:C44E1F*
  ID_OUI_FROM_DATABASE=BlueN
 
@@ -65908,6 +67747,12 @@ OUI:C455C2*
 OUI:C45600*
  ID_OUI_FROM_DATABASE=Galleon Embedded Computing
 
+OUI:C456FE*
+ ID_OUI_FROM_DATABASE=Lava International Ltd.
+
+OUI:C4576E*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,LTD
+
 OUI:C458C2*
  ID_OUI_FROM_DATABASE=Shenzhen TATFOOK Technology Co., Ltd.
 
@@ -65938,6 +67783,9 @@ OUI:C467B5*
 OUI:C46AB7*
  ID_OUI_FROM_DATABASE=Xiaomi Technology,Inc.
 
+OUI:C46BB4*
+ ID_OUI_FROM_DATABASE=myIDkey
+
 OUI:C46DF1*
  ID_OUI_FROM_DATABASE=DataGravity
 
@@ -65983,6 +67831,9 @@ OUI:C48508*
 OUI:C488E5*
  ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
 
+OUI:C4913A*
+ ID_OUI_FROM_DATABASE=Shenzhen Sanland Electronic Co., ltd.
+
 OUI:C49300*
  ID_OUI_FROM_DATABASE=8Devices
 
@@ -66013,6 +67864,9 @@ OUI:C4B512*
 OUI:C4BA99*
  ID_OUI_FROM_DATABASE=I+ME Actia Informatik und Mikro-Elektronik GmbH
 
+OUI:C4BD6A*
+ ID_OUI_FROM_DATABASE=SKF GmbH
+
 OUI:C4C0AE*
  ID_OUI_FROM_DATABASE=MIDORI ELECTRONIC CO., LTD.
 
@@ -66025,6 +67879,9 @@ OUI:C4C755*
 OUI:C4C919*
  ID_OUI_FROM_DATABASE=Energy Imports Ltd
 
+OUI:C4C9EC*
+ ID_OUI_FROM_DATABASE=D&D GROUP sp. z o.o.
+
 OUI:C4CAD9*
  ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
 
@@ -66079,6 +67936,9 @@ OUI:C4F57C*
 OUI:C4FCE4*
  ID_OUI_FROM_DATABASE=DishTV NZ Ltd
 
+OUI:C80210*
+ ID_OUI_FROM_DATABASE=LG Innotek
+
 OUI:C80258*
  ID_OUI_FROM_DATABASE=ITW GSE ApS
 
@@ -66109,11 +67969,14 @@ OUI:C819F7*
 OUI:C81AFE*
  ID_OUI_FROM_DATABASE=DLOGIC GmbH
 
+OUI:C81B6B*
+ ID_OUI_FROM_DATABASE=Innova Security
+
 OUI:C81E8E*
  ID_OUI_FROM_DATABASE=ADV Security (S) Pte Ltd
 
 OUI:C81F66*
- ID_OUI_FROM_DATABASE=Dell Inc PCBA Test
+ ID_OUI_FROM_DATABASE=Dell Inc
 
 OUI:C8208E*
  ID_OUI_FROM_DATABASE=Storagedata
@@ -66127,6 +67990,9 @@ OUI:C82A14*
 OUI:C82E94*
  ID_OUI_FROM_DATABASE=Halfa Enterprise Co., Ltd.
 
+OUI:C83168*
+ ID_OUI_FROM_DATABASE=eZEX corporation
+
 OUI:C83232*
  ID_OUI_FROM_DATABASE=Hunting Innova
 
@@ -66208,6 +68074,9 @@ OUI:C88439*
 OUI:C88447*
  ID_OUI_FROM_DATABASE=Beautiful Enterprise Co., Ltd
 
+OUI:C88550*
+ ID_OUI_FROM_DATABASE=Apple
+
 OUI:C8873B*
  ID_OUI_FROM_DATABASE=Net Optics
 
@@ -66220,6 +68089,9 @@ OUI:C88B47*
 OUI:C8903E*
  ID_OUI_FROM_DATABASE=Pakton Technologies
 
+OUI:C891F9*
+ ID_OUI_FROM_DATABASE=SAGEMCOM
+
 OUI:C89346*
  ID_OUI_FROM_DATABASE=MXCHIP Company Limited
 
@@ -66238,6 +68110,9 @@ OUI:C89C1D*
 OUI:C89CDC*
  ID_OUI_FROM_DATABASE=ELITEGROUP COMPUTER SYSTEM CO., LTD.
 
+OUI:C89F1D*
+ ID_OUI_FROM_DATABASE=SHENZHEN COMMUNICATION TECHNOLOGIES CO.,LTD
+
 OUI:C89F42*
  ID_OUI_FROM_DATABASE=VDII Innovation AB
 
@@ -66274,6 +68149,9 @@ OUI:C8B373*
 OUI:C8B5B7*
  ID_OUI_FROM_DATABASE=Apple
 
+OUI:C8BA94*
+ ID_OUI_FROM_DATABASE=Samsung Electro Mechanics co., LTD.
+
 OUI:C8BBD3*
  ID_OUI_FROM_DATABASE=Embrane
 
@@ -66298,6 +68176,9 @@ OUI:C8CBB8*
 OUI:C8CD72*
  ID_OUI_FROM_DATABASE=SAGEMCOM
 
+OUI:C8D019*
+ ID_OUI_FROM_DATABASE=Shanghai Tigercel Communication Technology Co.,Ltd
+
 OUI:C8D10B*
  ID_OUI_FROM_DATABASE=Nokia Corporation
 
@@ -66316,6 +68197,9 @@ OUI:C8D3A3*
 OUI:C8D429*
  ID_OUI_FROM_DATABASE=Muehlbauer AG
 
+OUI:C8D590*
+ ID_OUI_FROM_DATABASE=FLIGHT DATA SYSTEMS
+
 OUI:C8D5FE*
  ID_OUI_FROM_DATABASE=Shenzhen Zowee Technology Co., Ltd
 
@@ -66337,6 +68221,12 @@ OUI:C8E0EB*
 OUI:C8E1A7*
  ID_OUI_FROM_DATABASE=Vertu Corporation Limited
 
+OUI:C8E42F*
+ ID_OUI_FROM_DATABASE=Technical Research Design and Development
+
+OUI:C8E7D8*
+ ID_OUI_FROM_DATABASE=SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.
+
 OUI:C8EE08*
  ID_OUI_FROM_DATABASE=TANGTOP TECHNOLOGY CO.,LTD
 
@@ -66358,6 +68248,9 @@ OUI:C8F386*
 OUI:C8F406*
  ID_OUI_FROM_DATABASE=Avaya, Inc
 
+OUI:C8F650*
+ ID_OUI_FROM_DATABASE=Apple
+
 OUI:C8F68D*
  ID_OUI_FROM_DATABASE=S.E.TECHNOLOGIES LIMITED
 
@@ -66379,9 +68272,15 @@ OUI:C8FB26*
 OUI:C8FE30*
  ID_OUI_FROM_DATABASE=Bejing DAYO Mobile Communication Technology Ltd.
 
+OUI:C8FF77*
+ ID_OUI_FROM_DATABASE=Dyson Limited
+
 OUI:CC0080*
  ID_OUI_FROM_DATABASE=BETTINI SRL
 
+OUI:CC03FA*
+ ID_OUI_FROM_DATABASE=Technicolor CH USA
+
 OUI:CC047C*
  ID_OUI_FROM_DATABASE=G-WAY Microwave
 
@@ -66394,6 +68293,9 @@ OUI:CC051B*
 OUI:CC07AB*
  ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
 
+OUI:CC07E4*
+ ID_OUI_FROM_DATABASE=Lenovo Mobile Communication Technology Ltd.
+
 OUI:CC08E0*
  ID_OUI_FROM_DATABASE=Apple
 
@@ -66406,6 +68308,9 @@ OUI:CC0CDA*
 OUI:CC0DEC*
  ID_OUI_FROM_DATABASE=Cisco SPVTG
 
+OUI:CC10A3*
+ ID_OUI_FROM_DATABASE=Beijing Nan Bao Technology Co., Ltd.
+
 OUI:CC14A6*
  ID_OUI_FROM_DATABASE=Yichun MyEnergy Domain, Inc
 
@@ -66430,6 +68335,9 @@ OUI:CC2A80*
 OUI:CC2D8C*
  ID_OUI_FROM_DATABASE=LG ELECTRONICS INC
 
+OUI:CC3080*
+ ID_OUI_FROM_DATABASE=VAIO Corporation
+
 OUI:CC33BB*
  ID_OUI_FROM_DATABASE=SAGEMCOM SAS
 
@@ -66451,9 +68359,15 @@ OUI:CC3A61*
 OUI:CC3C3F*
  ID_OUI_FROM_DATABASE=SA.S.S. Datentechnik AG
 
+OUI:CC3D82*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
 OUI:CC3E5F*
  ID_OUI_FROM_DATABASE=Hewlett Packard
 
+OUI:CC3F1D*
+ ID_OUI_FROM_DATABASE=Intesis Software SL
+
 OUI:CC43E3*
  ID_OUI_FROM_DATABASE=Trump s.a.
 
@@ -66574,6 +68488,12 @@ OUI:CC9E00*
 OUI:CC9F35*
  ID_OUI_FROM_DATABASE=Transbit Sp. z o.o.
 
+OUI:CCA0E5*
+ ID_OUI_FROM_DATABASE=DZG Metering GmbH
+
+OUI:CCA223*
+ ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd
+
 OUI:CCA374*
  ID_OUI_FROM_DATABASE=Guangdong Guanglian Electronic Technology Co.Ltd
 
@@ -66595,6 +68515,9 @@ OUI:CCB3F8*
 OUI:CCB55A*
  ID_OUI_FROM_DATABASE=Fraunhofer ITWM
 
+OUI:CCB691*
+ ID_OUI_FROM_DATABASE=NECMagnusCommunications
+
 OUI:CCB888*
  ID_OUI_FROM_DATABASE=AnB Securite s.a.
 
@@ -66610,6 +68533,9 @@ OUI:CCBE71*
 OUI:CCC104*
  ID_OUI_FROM_DATABASE=Applied Technical Systems
 
+OUI:CCC3EA*
+ ID_OUI_FROM_DATABASE=Motorola Mobility LLC
+
 OUI:CCC50A*
  ID_OUI_FROM_DATABASE=SHENZHEN DAJIAHAO TECHNOLOGY CO.,LTD
 
@@ -66640,9 +68566,18 @@ OUI:CCD539*
 OUI:CCD811*
  ID_OUI_FROM_DATABASE=Aiconn Technology Corporation
 
+OUI:CCD8C1*
+ ID_OUI_FROM_DATABASE=Cisco
+
 OUI:CCD9E9*
  ID_OUI_FROM_DATABASE=SCR Engineers Ltd.
 
+OUI:CCE17F*
+ ID_OUI_FROM_DATABASE=juniper networks
+
+OUI:CCE1D5*
+ ID_OUI_FROM_DATABASE=Buffalo Inc.
+
 OUI:CCE798*
  ID_OUI_FROM_DATABASE=My Social Stuff
 
@@ -66667,6 +68602,9 @@ OUI:CCF3A5*
 OUI:CCF407*
  ID_OUI_FROM_DATABASE=EUKREA ELECTROMATIQUE SARL
 
+OUI:CCF538*
+ ID_OUI_FROM_DATABASE=3isysnetworks
+
 OUI:CCF67A*
  ID_OUI_FROM_DATABASE=Ayecka Communication Systems LTD
 
@@ -66700,9 +68638,15 @@ OUI:CCFE3C*
 OUI:D00790*
  ID_OUI_FROM_DATABASE=Texas Instruments
 
+OUI:D00AAB*
+ ID_OUI_FROM_DATABASE=Yokogawa Digital Computer Corporation
+
 OUI:D00EA4*
  ID_OUI_FROM_DATABASE=Porsche Cars North America
 
+OUI:D01242*
+ ID_OUI_FROM_DATABASE=BIOS Corporation
+
 OUI:D0131E*
  ID_OUI_FROM_DATABASE=Sunrex Technology Corp
 
@@ -66718,6 +68662,9 @@ OUI:D01AA7*
 OUI:D01CBB*
  ID_OUI_FROM_DATABASE=Beijing Ctimes Digital Technology Co., Ltd.
 
+OUI:D02212*
+ ID_OUI_FROM_DATABASE=IEEE REGISTRATION AUTHORITY  - Please see MAM public listing for more information.
+
 OUI:D022BE*
  ID_OUI_FROM_DATABASE=Samsung Electro Mechanics co.,LTD.
 
@@ -66742,6 +68689,9 @@ OUI:D03761*
 OUI:D03972*
  ID_OUI_FROM_DATABASE=Texas Instruments
 
+OUI:D039B3*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
 OUI:D046DC*
  ID_OUI_FROM_DATABASE=Southwest Research Institute
 
@@ -66775,12 +68725,24 @@ OUI:D05875*
 OUI:D059C3*
  ID_OUI_FROM_DATABASE=CeraMicro Technology Corporation
 
+OUI:D059E4*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
 OUI:D05A0F*
  ID_OUI_FROM_DATABASE=I-BT DIGITAL CO.,LTD
 
+OUI:D05AF1*
+ ID_OUI_FROM_DATABASE=Shenzhen Pulier Tech CO.,Ltd
+
+OUI:D05FB8*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
 OUI:D05FCE*
  ID_OUI_FROM_DATABASE=Hitachi Data Systems
 
+OUI:D062A0*
+ ID_OUI_FROM_DATABASE=China Essence Technology (Zhumadian) Co., Ltd.
+
 OUI:D0634D*
  ID_OUI_FROM_DATABASE=Meiko Maschinenbau GmbH &amp; Co. KG
 
@@ -66799,6 +68761,9 @@ OUI:D0699E*
 OUI:D069D0*
  ID_OUI_FROM_DATABASE=Verto Medical Solutions, LLC
 
+OUI:D072DC*
+ ID_OUI_FROM_DATABASE=Cisco
+
 OUI:D0737F*
  ID_OUI_FROM_DATABASE=Mini-Circuits
 
@@ -66811,6 +68776,9 @@ OUI:D073D5*
 OUI:D075BE*
  ID_OUI_FROM_DATABASE=Reno A&E
 
+OUI:D07650*
+ ID_OUI_FROM_DATABASE=IEEE REGISTRATION AUTHORITY  - Please see MAM public listing for more information.
+
 OUI:D07AB5*
  ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd
 
@@ -66823,6 +68791,9 @@ OUI:D07E28*
 OUI:D07E35*
  ID_OUI_FROM_DATABASE=Intel Corporate
 
+OUI:D084B0*
+ ID_OUI_FROM_DATABASE=Sagemcom
+
 OUI:D08999*
  ID_OUI_FROM_DATABASE=APCON, Inc.
 
@@ -66853,6 +68824,9 @@ OUI:D09C30*
 OUI:D09D0A*
  ID_OUI_FROM_DATABASE=LINKCOM
 
+OUI:D0A0D6*
+ ID_OUI_FROM_DATABASE=Chengdu TD Tech Ltd.
+
 OUI:D0A311*
  ID_OUI_FROM_DATABASE=Neuberger Gebäudeautomation GmbH
 
@@ -66895,6 +68869,9 @@ OUI:D0C42F*
 OUI:D0C789*
  ID_OUI_FROM_DATABASE=Cisco
 
+OUI:D0C7C0*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+
 OUI:D0CDE1*
  ID_OUI_FROM_DATABASE=Scientech Electronics
 
@@ -66964,6 +68941,9 @@ OUI:D0F27F*
 OUI:D0F73B*
  ID_OUI_FROM_DATABASE=Helmut Mauell GmbH
 
+OUI:D0FA1D*
+ ID_OUI_FROM_DATABASE=Qihoo  360  Technology Co.,Ltd
+
 OUI:D0FF50*
  ID_OUI_FROM_DATABASE=Texas Instruments, Inc
 
@@ -67018,6 +68998,9 @@ OUI:D41F0C*
 OUI:D4206D*
  ID_OUI_FROM_DATABASE=HTC Corporation
 
+OUI:D42122*
+ ID_OUI_FROM_DATABASE=Sercomm Corporation
+
 OUI:D4223F*
  ID_OUI_FROM_DATABASE=Lenovo Mobile Communication Technology Ltd.
 
@@ -67042,6 +69025,9 @@ OUI:D42F23*
 OUI:D4319D*
  ID_OUI_FROM_DATABASE=Sinwatec
 
+OUI:D437D7*
+ ID_OUI_FROM_DATABASE=zte corporation
+
 OUI:D43A65*
  ID_OUI_FROM_DATABASE=IGRS Engineering Lab Ltd.
 
@@ -67088,17 +69074,23 @@ OUI:D45AB2*
  ID_OUI_FROM_DATABASE=Galleon Systems
 
 OUI:D45C70*
- ID_OUI_FROM_DATABASE=Wireless Gigabit Alliance
+ ID_OUI_FROM_DATABASE=Wi-Fi Alliance
 
 OUI:D45D42*
  ID_OUI_FROM_DATABASE=Nokia Corporation
 
+OUI:D46132*
+ ID_OUI_FROM_DATABASE=Pro Concept Manufacturer Co.,Ltd.
+
 OUI:D464F7*
  ID_OUI_FROM_DATABASE=CHENGDU USEE DIGITAL TECHNOLOGY CO., LTD
 
 OUI:D466A8*
  ID_OUI_FROM_DATABASE=Riedo Networks GmbH
 
+OUI:D46761*
+ ID_OUI_FROM_DATABASE=SAHAB TECHNOLOGY
+
 OUI:D467E7*
  ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Tech.Co.,Ltd.
 
@@ -67126,6 +69118,9 @@ OUI:D46F42*
 OUI:D479C3*
  ID_OUI_FROM_DATABASE=Cameronet GmbH & Co. KG
 
+OUI:D47B35*
+ ID_OUI_FROM_DATABASE=NEO Monitors AS
+
 OUI:D47B75*
  ID_OUI_FROM_DATABASE=HARTING Electronics GmbH
 
@@ -67147,12 +69142,21 @@ OUI:D48890*
 OUI:D48CB5*
  ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
 
+OUI:D48DD9*
+ ID_OUI_FROM_DATABASE=Meld Technology, Inc
+
+OUI:D48F33*
+ ID_OUI_FROM_DATABASE=Microsoft Corporation
+
 OUI:D48FAA*
  ID_OUI_FROM_DATABASE=Sogecam Industrial, S.A.
 
 OUI:D491AF*
  ID_OUI_FROM_DATABASE=Electroacustica General Iberica, S.A.
 
+OUI:D49398*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
 OUI:D493A0*
  ID_OUI_FROM_DATABASE=Fidelix Oy
 
@@ -67168,6 +69172,9 @@ OUI:D49524*
 OUI:D496DF*
  ID_OUI_FROM_DATABASE=SUNGJIN C&T CO.,LTD
 
+OUI:D4970B*
+ ID_OUI_FROM_DATABASE=XIAOMI CORPORATION
+
 OUI:D49A20*
  ID_OUI_FROM_DATABASE=Apple
 
@@ -67207,6 +69214,9 @@ OUI:D4AE52*
 OUI:D4B110*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
 
+OUI:D4B43E*
+ ID_OUI_FROM_DATABASE=Messcomp Datentechnik GmbH
+
 OUI:D4BED9*
  ID_OUI_FROM_DATABASE=Dell Inc
 
@@ -67237,6 +69247,9 @@ OUI:D4CBAF*
 OUI:D4CEB8*
  ID_OUI_FROM_DATABASE=Enatel LTD
 
+OUI:D4CFF9*
+ ID_OUI_FROM_DATABASE=Shenzhen Sen5 Technology Co., Ltd.
+
 OUI:D4D184*
  ID_OUI_FROM_DATABASE=ADB Broadband Italia
 
@@ -67258,6 +69271,9 @@ OUI:D4D919*
 OUI:D4DF57*
  ID_OUI_FROM_DATABASE=Alpinion Medical Systems
 
+OUI:D4E08E*
+ ID_OUI_FROM_DATABASE=ValueHD Corporation
+
 OUI:D4E32C*
  ID_OUI_FROM_DATABASE=S. Siedle & Sohne
 
@@ -67273,6 +69289,9 @@ OUI:D4EA0E*
 OUI:D4EC0C*
  ID_OUI_FROM_DATABASE=Harley-Davidson Motor Company
 
+OUI:D4EC86*
+ ID_OUI_FROM_DATABASE=LinkedHope Intelligent Technologies Co., Ltd
+
 OUI:D4EE07*
  ID_OUI_FROM_DATABASE=HIWIFI Co., Ltd.
 
@@ -67285,6 +69304,9 @@ OUI:D4F0B4*
 OUI:D4F143*
  ID_OUI_FROM_DATABASE=IPROAD.,Inc
 
+OUI:D4F46F*
+ ID_OUI_FROM_DATABASE=Apple
+
 OUI:D4F63F*
  ID_OUI_FROM_DATABASE=IEA S.R.L.
 
@@ -67303,6 +69325,9 @@ OUI:D808F5*
 OUI:D809C3*
  ID_OUI_FROM_DATABASE=Cercacor Labs
 
+OUI:D80CCF*
+ ID_OUI_FROM_DATABASE=C.G.V. S.A.S.
+
 OUI:D80DE3*
  ID_OUI_FROM_DATABASE=FXI TECHNOLOGIES AS
 
@@ -67330,6 +69355,9 @@ OUI:D81EDE*
 OUI:D824BD*
  ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
 
+OUI:D82522*
+ ID_OUI_FROM_DATABASE=Pace plc
+
 OUI:D826B9*
  ID_OUI_FROM_DATABASE=Guangdong Coagent Electronics S &T Co., Ltd.
 
@@ -67366,6 +69394,9 @@ OUI:D831CF*
 OUI:D8337F*
  ID_OUI_FROM_DATABASE=Office FA.com Co.,Ltd.
 
+OUI:D83C69*
+ ID_OUI_FROM_DATABASE=Tinno Mobile Technology Corp
+
 OUI:D842AC*
  ID_OUI_FROM_DATABASE=Shanghai Feixun Communication Co.,Ltd.
 
@@ -67375,6 +69406,12 @@ OUI:D84606*
 OUI:D8490B*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
 
+OUI:D8492F*
+ ID_OUI_FROM_DATABASE=CANON INC.
+
+OUI:D84A87*
+ ID_OUI_FROM_DATABASE=OI ELECTRIC CO.,LTD
+
 OUI:D84B2A*
  ID_OUI_FROM_DATABASE=Cognitas Technologies, Inc.
 
@@ -67397,7 +69434,7 @@ OUI:D85D84*
  ID_OUI_FROM_DATABASE=CAx soft GmbH
 
 OUI:D86194*
- ID_OUI_FROM_DATABASE=Objetivos y Sevicios de Valor Añadido
+ ID_OUI_FROM_DATABASE=Objetivos y Sevicios de Valor Aadido
 
 OUI:D862DB*
  ID_OUI_FROM_DATABASE=Eno Inc.
@@ -67408,6 +69445,9 @@ OUI:D86595*
 OUI:D866C6*
  ID_OUI_FROM_DATABASE=Shenzhen Daystar Technology Co.,ltd
 
+OUI:D866EE*
+ ID_OUI_FROM_DATABASE=BOXIN COMMUNICATION CO.,LTD.
+
 OUI:D867D9*
  ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
 
@@ -67438,9 +69478,18 @@ OUI:D87988*
 OUI:D87CDD*
  ID_OUI_FROM_DATABASE=SANIX INCORPORATED
 
+OUI:D87EB1*
+ ID_OUI_FROM_DATABASE=x.o.ware, inc.
+
+OUI:D88039*
+ ID_OUI_FROM_DATABASE=Microchip Technology Inc.
+
 OUI:D881CE*
  ID_OUI_FROM_DATABASE=AHN INC.
 
+OUI:D88466*
+ ID_OUI_FROM_DATABASE=Extreme Networks
+
 OUI:D88A3B*
  ID_OUI_FROM_DATABASE=UNIT-EM
 
@@ -67456,12 +69505,21 @@ OUI:D89685*
 OUI:D89695*
  ID_OUI_FROM_DATABASE=Apple
 
+OUI:D896E0*
+ ID_OUI_FROM_DATABASE=Alibaba Cloud Computing Ltd.
+
 OUI:D8973B*
- ID_OUI_FROM_DATABASE=Emerson Network Power Embedded Power
+ ID_OUI_FROM_DATABASE=Artesyn Embedded Technologies
 
 OUI:D89760*
  ID_OUI_FROM_DATABASE=C2 Development, Inc.
 
+OUI:D8977C*
+ ID_OUI_FROM_DATABASE=Grey Innovation
+
+OUI:D897BA*
+ ID_OUI_FROM_DATABASE=PEGATRON CORPORATION
+
 OUI:D89D67*
  ID_OUI_FROM_DATABASE=Hewlett Packard
 
@@ -67495,6 +69553,9 @@ OUI:D8B12A*
 OUI:D8B377*
  ID_OUI_FROM_DATABASE=HTC Corporation
 
+OUI:D8B6B7*
+ ID_OUI_FROM_DATABASE=Comtrend Corporation
+
 OUI:D8B6C1*
  ID_OUI_FROM_DATABASE=NetworkAccountant, Inc.
 
@@ -67525,6 +69586,12 @@ OUI:D8C7C8*
 OUI:D8C99D*
  ID_OUI_FROM_DATABASE=EA DISPLAY LIMITED
 
+OUI:D8CB8A*
+ ID_OUI_FROM_DATABASE=Micro-Star INTL CO., LTD.
+
+OUI:D8CF9C*
+ ID_OUI_FROM_DATABASE=Apple
+
 OUI:D8D1CB*
  ID_OUI_FROM_DATABASE=Apple
 
@@ -67555,12 +69622,18 @@ OUI:D8DD5F*
 OUI:D8DDFD*
  ID_OUI_FROM_DATABASE=Texas Instruments
 
+OUI:D8DECE*
+ ID_OUI_FROM_DATABASE=ISUNG CO.,LTD
+
 OUI:D8DF0D*
  ID_OUI_FROM_DATABASE=beroNet GmbH
 
 OUI:D8E3AE*
  ID_OUI_FROM_DATABASE=CIRTEC MEDICAL SYSTEMS
 
+OUI:D8E56D*
+ ID_OUI_FROM_DATABASE=TCT Mobile Limited
+
 OUI:D8E72B*
  ID_OUI_FROM_DATABASE=OnPATH Technologies
 
@@ -67579,6 +69652,12 @@ OUI:D8EE78*
 OUI:D8F0F2*
  ID_OUI_FROM_DATABASE=Zeebo Inc
 
+OUI:D8F710*
+ ID_OUI_FROM_DATABASE=Libre Wireless Technologies Inc.
+
+OUI:D8FB11*
+ ID_OUI_FROM_DATABASE=AXACORE
+
 OUI:D8FC93*
  ID_OUI_FROM_DATABASE=Intel Corporate
 
@@ -67651,6 +69730,9 @@ OUI:DC2C26*
 OUI:DC2E6A*
  ID_OUI_FROM_DATABASE=HCT. Co., Ltd.
 
+OUI:DC2F03*
+ ID_OUI_FROM_DATABASE=Step forward Group Co., Ltd.
+
 OUI:DC309C*
  ID_OUI_FROM_DATABASE=Heyrex Limited
 
@@ -67660,6 +69742,12 @@ OUI:DC3350*
 OUI:DC37D2*
  ID_OUI_FROM_DATABASE=Hunan HKT Electronic Technology Co., Ltd
 
+OUI:DC38E1*
+ ID_OUI_FROM_DATABASE=Juniper networks
+
+OUI:DC3979*
+ ID_OUI_FROM_DATABASE=Skyport Systems
+
 OUI:DC3A5E*
  ID_OUI_FROM_DATABASE=Roku, Inc
 
@@ -67684,6 +69772,9 @@ OUI:DC49C9*
 OUI:DC4EDE*
  ID_OUI_FROM_DATABASE=SHINYEI TECHNOLOGY CO., LTD.
 
+OUI:DC537C*
+ ID_OUI_FROM_DATABASE=Compal Broadband Networks, Inc.
+
 OUI:DC5726*
  ID_OUI_FROM_DATABASE=Power-One
 
@@ -67693,6 +69784,9 @@ OUI:DC5E36*
 OUI:DC647C*
  ID_OUI_FROM_DATABASE=C.R.S. iiMotion GmbH
 
+OUI:DC663A*
+ ID_OUI_FROM_DATABASE=Apacer Technology Inc.
+
 OUI:DC6F00*
  ID_OUI_FROM_DATABASE=Livescribe, Inc.
 
@@ -67771,6 +69865,9 @@ OUI:DCC101*
 OUI:DCC422*
  ID_OUI_FROM_DATABASE=Systembase Limited
 
+OUI:DCC622*
+ ID_OUI_FROM_DATABASE=BUHEUNG SYSTEM
+
 OUI:DCC793*
  ID_OUI_FROM_DATABASE=Nokia Corporation
 
@@ -67801,6 +69898,9 @@ OUI:DCD52A*
 OUI:DCD87F*
  ID_OUI_FROM_DATABASE=Shenzhen JoinCyber Telecom Equipment Ltd
 
+OUI:DCDA4F*
+ ID_OUI_FROM_DATABASE=GETCK TECHNOLOGY,  INC
+
 OUI:DCDECA*
  ID_OUI_FROM_DATABASE=Akyllor
 
@@ -67813,9 +69913,15 @@ OUI:DCE578*
 OUI:DCE71C*
  ID_OUI_FROM_DATABASE=AUG Elektronik GmbH
 
+OUI:DCEC06*
+ ID_OUI_FROM_DATABASE=Heimi Network Technology Co., Ltd.
+
 OUI:DCF05D*
  ID_OUI_FROM_DATABASE=Letta Teknoloji
 
+OUI:DCF110*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
 OUI:DCF755*
  ID_OUI_FROM_DATABASE=SITRONIK
 
@@ -67840,6 +69946,9 @@ OUI:E00B28*
 OUI:E00C7F*
  ID_OUI_FROM_DATABASE=Nintendo Co., Ltd.
 
+OUI:E0107F*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
 OUI:E0143E*
  ID_OUI_FROM_DATABASE=Modoosis Inc.
 
@@ -67852,6 +69961,9 @@ OUI:E01C41*
 OUI:E01CEE*
  ID_OUI_FROM_DATABASE=Bravo Tech, Inc.
 
+OUI:E01D38*
+ ID_OUI_FROM_DATABASE=Beijing HuaqinWorld Technology Co.,Ltd
+
 OUI:E01D3B*
  ID_OUI_FROM_DATABASE=Cambridge Industries(Group) Co.,Ltd
 
@@ -67897,6 +70009,9 @@ OUI:E039D7*
 OUI:E03C5B*
  ID_OUI_FROM_DATABASE=SHENZHEN JIAXINJIE ELECTRON CO.,LTD
 
+OUI:E03E44*
+ ID_OUI_FROM_DATABASE=Broadcom Corporation
+
 OUI:E03E4A*
  ID_OUI_FROM_DATABASE=Cavanagh Group International
 
@@ -67939,6 +70054,9 @@ OUI:E063E5*
 OUI:E064BB*
  ID_OUI_FROM_DATABASE=DigiView S.r.l.
 
+OUI:E06678*
+ ID_OUI_FROM_DATABASE=Apple
+
 OUI:E067B3*
  ID_OUI_FROM_DATABASE=C-Data Technology Co., Ltd
 
@@ -67984,6 +70102,9 @@ OUI:E09467*
 OUI:E09579*
  ID_OUI_FROM_DATABASE=ORTHOsoft inc, d/b/a Zimmer CAS
 
+OUI:E09796*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
 OUI:E097F2*
  ID_OUI_FROM_DATABASE=Atomax Inc.
 
@@ -68011,6 +70132,9 @@ OUI:E0AAB0*
 OUI:E0ABFE*
  ID_OUI_FROM_DATABASE=Orb Networks, Inc.
 
+OUI:E0ACF1*
+ ID_OUI_FROM_DATABASE=Cisco
+
 OUI:E0AE5E*
  ID_OUI_FROM_DATABASE=ALPS Co,. Ltd.
 
@@ -68026,6 +70150,9 @@ OUI:E0AF4B*
 OUI:E0B2F1*
  ID_OUI_FROM_DATABASE=FN-LINK TECHNOLOGY LIMITED
 
+OUI:E0B52D*
+ ID_OUI_FROM_DATABASE=Apple
+
 OUI:E0B7B1*
  ID_OUI_FROM_DATABASE=Pace plc
 
@@ -68071,6 +70198,9 @@ OUI:E0CA94*
 OUI:E0CB4E*
  ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
 
+OUI:E0CBEE*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
 OUI:E0CEC3*
  ID_OUI_FROM_DATABASE=ASKEY COMPUTER CORP
 
@@ -68152,6 +70282,9 @@ OUI:E40439*
 OUI:E4115B*
  ID_OUI_FROM_DATABASE=Hewlett Packard
 
+OUI:E41218*
+ ID_OUI_FROM_DATABASE=ShenZhen Rapoo Technology Co., Ltd.
+
 OUI:E4121D*
  ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
 
@@ -68161,9 +70294,15 @@ OUI:E41289*
 OUI:E41C4B*
  ID_OUI_FROM_DATABASE=V2 TECHNOLOGY, INC.
 
+OUI:E41D2D*
+ ID_OUI_FROM_DATABASE=Mellanox Technologies, Inc.
+
 OUI:E41F13*
  ID_OUI_FROM_DATABASE=IBM Corp
 
+OUI:E42354*
+ ID_OUI_FROM_DATABASE=SHENZHEN FUZHI SOFTWARE TECHNOLOGY CO.,LTD
+
 OUI:E425E7*
  ID_OUI_FROM_DATABASE=Apple
 
@@ -68239,6 +70378,9 @@ OUI:E45614*
 OUI:E457A8*
  ID_OUI_FROM_DATABASE=Stuart Manufacturing, Inc.
 
+OUI:E45D52*
+ ID_OUI_FROM_DATABASE=Avaya, Inc
+
 OUI:E46449*
  ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
 
@@ -68272,6 +70414,9 @@ OUI:E47CF9*
 OUI:E47D5A*
  ID_OUI_FROM_DATABASE=Beijing Hanbang Technology Corp.
 
+OUI:E47FB2*
+ ID_OUI_FROM_DATABASE=Fujitsu Limited
+
 OUI:E48184*
  ID_OUI_FROM_DATABASE=Alcatel-Lucent
 
@@ -68287,6 +70432,9 @@ OUI:E48AD5*
 OUI:E48B7F*
  ID_OUI_FROM_DATABASE=Apple
 
+OUI:E48C0F*
+ ID_OUI_FROM_DATABASE=Discovery Insure
+
 OUI:E49069*
  ID_OUI_FROM_DATABASE=Rockwell Automation
 
@@ -68296,6 +70444,9 @@ OUI:E492E7*
 OUI:E492FB*
  ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
 
+OUI:E4956E*
+ ID_OUI_FROM_DATABASE=IEEE REGISTRATION AUTHORITY  - Please see MAM public listing for more information.
+
 OUI:E496AE*
  ID_OUI_FROM_DATABASE=ALTOGRAPHICS Inc.
 
@@ -68326,6 +70477,9 @@ OUI:E4B021*
 OUI:E4C146*
  ID_OUI_FROM_DATABASE=Objetivos y Servicios de Valor A
 
+OUI:E4C62B*
+ ID_OUI_FROM_DATABASE=Airware
+
 OUI:E4C63D*
  ID_OUI_FROM_DATABASE=Apple, Inc.
 
@@ -68341,6 +70495,9 @@ OUI:E4C806*
 OUI:E4CE8F*
  ID_OUI_FROM_DATABASE=Apple
 
+OUI:E4D332*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+
 OUI:E4D3F1*
  ID_OUI_FROM_DATABASE=Cisco
 
@@ -68371,9 +70528,15 @@ OUI:E4F365*
 OUI:E4F3E3*
  ID_OUI_FROM_DATABASE=Shanghai iComhome Co.,Ltd.
 
+OUI:E4F4C6*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
 OUI:E4F7A1*
  ID_OUI_FROM_DATABASE=Datafox GmbH
 
+OUI:E4F8EF*
+ ID_OUI_FROM_DATABASE=Samsung Elec Co.,Ltd
+
 OUI:E4FA1D*
  ID_OUI_FROM_DATABASE=PAD Peripheral Advanced Design Inc.
 
@@ -68419,9 +70582,15 @@ OUI:E81132*
 OUI:E81324*
  ID_OUI_FROM_DATABASE=GuangZhou Bonsoninfo System CO.,LTD
 
+OUI:E8150E*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
 OUI:E817FC*
  ID_OUI_FROM_DATABASE=NIFTY Corporation
 
+OUI:E81863*
+ ID_OUI_FROM_DATABASE=IEEE REGISTRATION AUTHORITY  - Please see MAM public listing for more information.
+
 OUI:E82877*
  ID_OUI_FROM_DATABASE=TMY Co., Ltd.
 
@@ -68494,6 +70663,9 @@ OUI:E85B5B*
 OUI:E85BF0*
  ID_OUI_FROM_DATABASE=Imaging Diagnostics
 
+OUI:E85D6B*
+ ID_OUI_FROM_DATABASE=Luminate Wireless
+
 OUI:E85E53*
  ID_OUI_FROM_DATABASE=Infratec Datentechnik GmbH
 
@@ -68530,9 +70702,15 @@ OUI:E878A1*
 OUI:E87AF3*
  ID_OUI_FROM_DATABASE=S5 Tech S.r.l.
 
+OUI:E8802E*
+ ID_OUI_FROM_DATABASE=Apple
+
 OUI:E880D8*
  ID_OUI_FROM_DATABASE=GNTEK Electronics Co.,Ltd.
 
+OUI:E887A3*
+ ID_OUI_FROM_DATABASE=Loxley Public Company Limited
+
 OUI:E8892C*
  ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
 
@@ -68554,6 +70732,9 @@ OUI:E8944C*
 OUI:E894F6*
  ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
 
+OUI:E89606*
+ ID_OUI_FROM_DATABASE=testo Instruments (Shenzhen) Co., Ltd.
+
 OUI:E8995A*
  ID_OUI_FROM_DATABASE=PiiGAB, Processinformation i Goteborg AB
 
@@ -68608,6 +70789,9 @@ OUI:E8C320*
 OUI:E8CBA1*
  ID_OUI_FROM_DATABASE=Nokia Corporation
 
+OUI:E8CC18*
+ ID_OUI_FROM_DATABASE=D-Link International
+
 OUI:E8CC32*
  ID_OUI_FROM_DATABASE=Micronet  LTD
 
@@ -68668,9 +70852,15 @@ OUI:E8EA6A*
 OUI:E8EADA*
  ID_OUI_FROM_DATABASE=Denkovi Assembly Electroncs LTD
 
+OUI:E8ED05*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
 OUI:E8EDF3*
  ID_OUI_FROM_DATABASE=Cisco
 
+OUI:E8EF89*
+ ID_OUI_FROM_DATABASE=OPMEX Tech.
+
 OUI:E8F1B0*
  ID_OUI_FROM_DATABASE=SAGEMCOM SAS
 
@@ -68683,12 +70873,21 @@ OUI:E8F928*
 OUI:E8FC60*
  ID_OUI_FROM_DATABASE=ELCOM Innovations Private Limited
 
+OUI:E8FCAF*
+ ID_OUI_FROM_DATABASE=NETGEAR INC.,
+
+OUI:EC0EC4*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
 OUI:EC0ED6*
  ID_OUI_FROM_DATABASE=ITECH INSTRUMENTS SAS
 
 OUI:EC1120*
  ID_OUI_FROM_DATABASE=FloDesign Wind Turbine Corporation
 
+OUI:EC13B2*
+ ID_OUI_FROM_DATABASE=Netonix
+
 OUI:EC14F6*
  ID_OUI_FROM_DATABASE=BioControl AS
 
@@ -68701,12 +70900,18 @@ OUI:EC1766*
 OUI:EC1A59*
  ID_OUI_FROM_DATABASE=Belkin International Inc.
 
+OUI:EC1D7F*
+ ID_OUI_FROM_DATABASE=zte corporation
+
 OUI:EC219F*
  ID_OUI_FROM_DATABASE=VidaBox LLC
 
 OUI:EC2257*
  ID_OUI_FROM_DATABASE=JiangSu NanJing University Electronic Information Technology Co.,Ltd
 
+OUI:EC2280*
+ ID_OUI_FROM_DATABASE=D-Link International
+
 OUI:EC233D*
  ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd
 
@@ -68719,6 +70924,9 @@ OUI:EC2AF0*
 OUI:EC2C49*
  ID_OUI_FROM_DATABASE=University of Tokyo
 
+OUI:EC2E4E*
+ ID_OUI_FROM_DATABASE=HITACHI-LG DATA STORAGE INC
+
 OUI:EC3091*
  ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
 
@@ -68728,6 +70936,9 @@ OUI:EC3586*
 OUI:EC3BF0*
  ID_OUI_FROM_DATABASE=NovelSat
 
+OUI:EC3C5A*
+ ID_OUI_FROM_DATABASE=SHEN ZHEN HENG SHENG HUI DIGITAL TECHNOLOGY CO.,LTD
+
 OUI:EC3E09*
  ID_OUI_FROM_DATABASE=PERFORMANCE DESIGNED PRODUCTS, LLC
 
@@ -68803,6 +71014,9 @@ OUI:EC888F*
 OUI:EC89F5*
  ID_OUI_FROM_DATABASE=Lenovo Mobile Communication Technology Ltd.
 
+OUI:EC8A4C*
+ ID_OUI_FROM_DATABASE=zte corporation
+
 OUI:EC8EAD*
  ID_OUI_FROM_DATABASE=DLX
 
@@ -68828,7 +71042,7 @@ OUI:EC9B5B*
  ID_OUI_FROM_DATABASE=Nokia Corporation
 
 OUI:EC9ECD*
- ID_OUI_FROM_DATABASE=Emerson Network Power and Embedded Computing
+ ID_OUI_FROM_DATABASE=Artesyn Embedded Technologies
 
 OUI:ECA29B*
  ID_OUI_FROM_DATABASE=Kemppi Oy
@@ -68842,6 +71056,9 @@ OUI:ECB106*
 OUI:ECB541*
  ID_OUI_FROM_DATABASE=SHINANO E and E Co.Ltd.
 
+OUI:ECB907*
+ ID_OUI_FROM_DATABASE=CloudGenix Inc
+
 OUI:ECBBAE*
  ID_OUI_FROM_DATABASE=Digivoice Tecnologia em Eletronica Ltda
 
@@ -68854,6 +71071,9 @@ OUI:ECC38A*
 OUI:ECC882*
  ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
 
+OUI:ECCB30*
+ ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd
+
 OUI:ECCD6D*
  ID_OUI_FROM_DATABASE=Allied Telesis, Inc.
 
@@ -68872,6 +71092,9 @@ OUI:ECD925*
 OUI:ECD950*
  ID_OUI_FROM_DATABASE=IRT SA
 
+OUI:ECD9D1*
+ ID_OUI_FROM_DATABASE=Shenzhen TG-NET Botone Technology Co.,Ltd.
+
 OUI:ECDE3D*
  ID_OUI_FROM_DATABASE=Lamprey Networks, Inc.
 
@@ -68881,6 +71104,9 @@ OUI:ECE09B*
 OUI:ECE1A9*
  ID_OUI_FROM_DATABASE=Cisco
 
+OUI:ECE512*
+ ID_OUI_FROM_DATABASE=tado GmbH
+
 OUI:ECE555*
  ID_OUI_FROM_DATABASE=Hirschmann Automation
 
@@ -68909,7 +71135,7 @@ OUI:ECF35B*
  ID_OUI_FROM_DATABASE=Nokia Corporation
 
 OUI:ECF4BB*
- ID_OUI_FROM_DATABASE=Dell Inc PCBA Test
+ ID_OUI_FROM_DATABASE=Dell Inc
 
 OUI:ECF72B*
  ID_OUI_FROM_DATABASE=HD DIGITAL TECH CO., LTD.
@@ -68947,8 +71173,11 @@ OUI:F015A0*
 OUI:F01C13*
  ID_OUI_FROM_DATABASE=LG Electronics
 
+OUI:F01C2D*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
 OUI:F01FAF*
- ID_OUI_FROM_DATABASE=Dell Inc PCBA Test
+ ID_OUI_FROM_DATABASE=Dell Inc
 
 OUI:F0219D*
  ID_OUI_FROM_DATABASE=Cal-Comp Electronics & Communications Company Ltd.
@@ -68995,6 +71224,9 @@ OUI:F03A4B*
 OUI:F03A55*
  ID_OUI_FROM_DATABASE=Omega Elektronik AS
 
+OUI:F03D29*
+ ID_OUI_FROM_DATABASE=Actility
+
 OUI:F03FF8*
  ID_OUI_FROM_DATABASE=R L Drake
 
@@ -69052,6 +71284,9 @@ OUI:F0728C*
 OUI:F073AE*
  ID_OUI_FROM_DATABASE=PEAK-System Technik
 
+OUI:F0761C*
+ ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD.
+
 OUI:F07765*
  ID_OUI_FROM_DATABASE=Sourcefire, Inc
 
@@ -69064,6 +71299,9 @@ OUI:F07BCB*
 OUI:F07D68*
  ID_OUI_FROM_DATABASE=D-Link Corporation
 
+OUI:F07F06*
+ ID_OUI_FROM_DATABASE=Cisco
+
 OUI:F07F0C*
  ID_OUI_FROM_DATABASE=Leopold Kostal GmbH &Co. KG
 
@@ -69085,6 +71323,9 @@ OUI:F08A28*
 OUI:F08BFE*
  ID_OUI_FROM_DATABASE=COSTEL.,CO.LTD
 
+OUI:F08CFB*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Tech.Co.,Ltd.
+
 OUI:F08EDB*
  ID_OUI_FROM_DATABASE=VeloCloud Networks
 
@@ -69103,6 +71344,9 @@ OUI:F09CBB*
 OUI:F09CE9*
  ID_OUI_FROM_DATABASE=Aerohive Networks Inc
 
+OUI:F09E63*
+ ID_OUI_FROM_DATABASE=Cisco
+
 OUI:F0A764*
  ID_OUI_FROM_DATABASE=GST Co., Ltd.
 
@@ -69238,12 +71482,27 @@ OUI:F40321*
 OUI:F4044C*
  ID_OUI_FROM_DATABASE=ValenceTech Limited
 
+OUI:F40669*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
 OUI:F4068D*
  ID_OUI_FROM_DATABASE=devolo AG
 
+OUI:F406A5*
+ ID_OUI_FROM_DATABASE=Hangzhou Bianfeng Networking Technology Co., Ltd.
+
+OUI:F409D8*
+ ID_OUI_FROM_DATABASE=Samsung Electro Mechanics co., LTD.
+
 OUI:F40B93*
  ID_OUI_FROM_DATABASE=Research In Motion
 
+OUI:F40E11*
+ ID_OUI_FROM_DATABASE=IEEE REGISTRATION AUTHORITY  - Please see MAM public listing for more information.
+
+OUI:F40F1B*
+ ID_OUI_FROM_DATABASE=Cisco
+
 OUI:F40F9B*
  ID_OUI_FROM_DATABASE=WAVELINK
 
@@ -69265,6 +71524,12 @@ OUI:F41FC2*
 OUI:F42012*
  ID_OUI_FROM_DATABASE=Cuciniale GmbH
 
+OUI:F42833*
+ ID_OUI_FROM_DATABASE=MMPC Inc.
+
+OUI:F42853*
+ ID_OUI_FROM_DATABASE=Zioncom Electronics (Shenzhen) Ltd.
+
 OUI:F42896*
  ID_OUI_FROM_DATABASE=SPECTO PAINEIS ELETRONICOS LTDA
 
@@ -69301,6 +71566,9 @@ OUI:F4472A*
 OUI:F44848*
  ID_OUI_FROM_DATABASE=Amscreen Group Ltd
 
+OUI:F44E05*
+ ID_OUI_FROM_DATABASE=Cisco
+
 OUI:F44EFD*
  ID_OUI_FROM_DATABASE=Actions Semiconductor Co.,Ltd.(Cayman Islands)
 
@@ -69394,6 +71662,9 @@ OUI:F499AC*
 OUI:F49F54*
  ID_OUI_FROM_DATABASE=Samsung Electronics
 
+OUI:F49FF3*
+ ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd
+
 OUI:F4A294*
  ID_OUI_FROM_DATABASE=EAGLE WORLD DEVELOPMENT CO., LIMITED
 
@@ -69424,9 +71695,15 @@ OUI:F4B72A*
 OUI:F4B7E2*
  ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
 
+OUI:F4B85E*
+ ID_OUI_FROM_DATABASE=Texas INstruments
+
 OUI:F4BD7C*
  ID_OUI_FROM_DATABASE=Chengdu jinshi communication Co., LTD
 
+OUI:F4C447*
+ ID_OUI_FROM_DATABASE=Coagent International Enterprise Limited
+
 OUI:F4C6D7*
  ID_OUI_FROM_DATABASE=blackned GmbH
 
@@ -69448,6 +71725,12 @@ OUI:F4CE46*
 OUI:F4CFE2*
  ID_OUI_FROM_DATABASE=Cisco
 
+OUI:F4D032*
+ ID_OUI_FROM_DATABASE=Yunnan Ideal Information&Technology.,Ltd
+
+OUI:F4D261*
+ ID_OUI_FROM_DATABASE=SEMOCON Co., Ltd
+
 OUI:F4D9FB*
  ID_OUI_FROM_DATABASE=Samsung Electronics CO., LTD
 
@@ -69460,6 +71743,9 @@ OUI:F4DCDA*
 OUI:F4DCF9*
  ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd
 
+OUI:F4DD9E*
+ ID_OUI_FROM_DATABASE=GoPro
+
 OUI:F4E142*
  ID_OUI_FROM_DATABASE=Delta Elektronika BV
 
@@ -69475,15 +71761,30 @@ OUI:F4EC38*
 OUI:F4F15A*
  ID_OUI_FROM_DATABASE=Apple
 
+OUI:F4F1E1*
+ ID_OUI_FROM_DATABASE=Motorola Mobility LLC
+
+OUI:F4F26D*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+
 OUI:F4F5A5*
  ID_OUI_FROM_DATABASE=Nokia corporation
 
+OUI:F4F5E8*
+ ID_OUI_FROM_DATABASE=Google
+
+OUI:F4F646*
+ ID_OUI_FROM_DATABASE=Dediprog Technology Co. Ltd.
+
 OUI:F4F951*
  ID_OUI_FROM_DATABASE=Apple
 
 OUI:F4FC32*
  ID_OUI_FROM_DATABASE=Texas Instruments
 
+OUI:F4FD2B*
+ ID_OUI_FROM_DATABASE=ZOYI Company
+
 OUI:F80113*
  ID_OUI_FROM_DATABASE=Huawei Technologies Co., Ltd
 
@@ -69502,6 +71803,9 @@ OUI:F80BD0*
 OUI:F80CF3*
  ID_OUI_FROM_DATABASE=LG Electronics
 
+OUI:F80D43*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co., Ltd.
+
 OUI:F80DEA*
  ID_OUI_FROM_DATABASE=ZyCast Technology Inc.
 
@@ -69535,6 +71839,9 @@ OUI:F81EDF*
 OUI:F82285*
  ID_OUI_FROM_DATABASE=Cypress Technology CO., LTD.
 
+OUI:F82441*
+ ID_OUI_FROM_DATABASE=Yeelink
+
 OUI:F82793*
  ID_OUI_FROM_DATABASE=Apple, Inc
 
@@ -69586,6 +71893,9 @@ OUI:F8472D*
 OUI:F84897*
  ID_OUI_FROM_DATABASE=Hitachi, Ltd.
 
+OUI:F84A73*
+ ID_OUI_FROM_DATABASE=EUMTECH CO., LTD
+
 OUI:F84A7F*
  ID_OUI_FROM_DATABASE=Innometriks Inc
 
@@ -69622,6 +71932,12 @@ OUI:F85F2A*
 OUI:F862AA*
  ID_OUI_FROM_DATABASE=xn systems
 
+OUI:F86601*
+ ID_OUI_FROM_DATABASE=Suzhou Chi-tek information technology Co., Ltd
+
+OUI:F866D1*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co., Ltd.
+
 OUI:F866F2*
  ID_OUI_FROM_DATABASE=CISCO SYSTEMS, INC.
 
@@ -69637,6 +71953,9 @@ OUI:F871FE*
 OUI:F872EA*
  ID_OUI_FROM_DATABASE=Cisco
 
+OUI:F87394*
+ ID_OUI_FROM_DATABASE=NETGEAR INC.,
+
 OUI:F8769B*
  ID_OUI_FROM_DATABASE=Neopis Co., Ltd.
 
@@ -69652,6 +71971,12 @@ OUI:F87B8C*
 OUI:F8811A*
  ID_OUI_FROM_DATABASE=OVERKIZ
 
+OUI:F88479*
+ ID_OUI_FROM_DATABASE=Yaojin Technology(Shenzhen)Co.,Ltd
+
+OUI:F884F2*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
 OUI:F88C1C*
  ID_OUI_FROM_DATABASE=KAISHUN ELECTRONIC TECHNOLOGY CO., LTD. BEIJING
 
@@ -69710,13 +72035,13 @@ OUI:F8AC6D*
  ID_OUI_FROM_DATABASE=Deltenna Ltd
 
 OUI:F8B156*
- ID_OUI_FROM_DATABASE=Dell Inc PCBA Test
+ ID_OUI_FROM_DATABASE=Dell Inc
 
 OUI:F8B599*
  ID_OUI_FROM_DATABASE=Guangzhou CHNAVS Digital Technology Co.,Ltd
 
 OUI:F8BC12*
- ID_OUI_FROM_DATABASE=Dell Inc PCBA Test
+ ID_OUI_FROM_DATABASE=Dell Inc
 
 OUI:F8C001*
  ID_OUI_FROM_DATABASE=Juniper Networks
@@ -69724,6 +72049,9 @@ OUI:F8C001*
 OUI:F8C091*
  ID_OUI_FROM_DATABASE=Highgates Technology
 
+OUI:F8C288*
+ ID_OUI_FROM_DATABASE=Cisco
+
 OUI:F8C678*
  ID_OUI_FROM_DATABASE=Carefusion
 
@@ -69764,7 +72092,7 @@ OUI:F8DB7F*
  ID_OUI_FROM_DATABASE=HTC Corporation
 
 OUI:F8DB88*
- ID_OUI_FROM_DATABASE=Dell Inc PCBA Test
+ ID_OUI_FROM_DATABASE=Dell Inc
 
 OUI:F8DC7A*
  ID_OUI_FROM_DATABASE=Variscite LTD
@@ -69781,6 +72109,12 @@ OUI:F8E4FB*
 OUI:F8E7B5*
  ID_OUI_FROM_DATABASE=µTech Tecnologia LTDA
 
+OUI:F8E811*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:F8E903*
+ ID_OUI_FROM_DATABASE=D-Link International
+
 OUI:F8E968*
  ID_OUI_FROM_DATABASE=Egker Kft.
 
@@ -69871,6 +72205,9 @@ OUI:FC1607*
 OUI:FC1794*
  ID_OUI_FROM_DATABASE=InterCreative Co., Ltd
 
+OUI:FC1910*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
 OUI:FC19D0*
  ID_OUI_FROM_DATABASE=Cloud Vision Networks Technology Co.,Ltd.
 
@@ -69880,6 +72217,9 @@ OUI:FC1BFF*
 OUI:FC1D59*
  ID_OUI_FROM_DATABASE=I Smart Cities HK Ltd
 
+OUI:FC1D84*
+ ID_OUI_FROM_DATABASE=Autobase
+
 OUI:FC1E16*
  ID_OUI_FROM_DATABASE=IPEVO corp
 
@@ -69892,6 +72232,9 @@ OUI:FC1FC0*
 OUI:FC229C*
  ID_OUI_FROM_DATABASE=Han Kyung I Net Co.,Ltd.
 
+OUI:FC2325*
+ ID_OUI_FROM_DATABASE=EosTek (Shenzhen) Co., Ltd.
+
 OUI:FC253F*
  ID_OUI_FROM_DATABASE=Apple
 
@@ -69917,7 +72260,7 @@ OUI:FC3FAB*
  ID_OUI_FROM_DATABASE=Henan Lanxin Technology Co., Ltd
 
 OUI:FC4463*
- ID_OUI_FROM_DATABASE=Universal Audio
+ ID_OUI_FROM_DATABASE=Universal Audio, Inc
 
 OUI:FC4499*
  ID_OUI_FROM_DATABASE=Swarco LEA d.o.o.
@@ -69928,6 +72271,9 @@ OUI:FC455F*
 OUI:FC48EF*
  ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
 
+OUI:FC4AE9*
+ ID_OUI_FROM_DATABASE=Castlenet Technology Inc.
+
 OUI:FC4B1C*
  ID_OUI_FROM_DATABASE=INTERSENSOR S.R.L.
 
@@ -69952,6 +72298,9 @@ OUI:FC5B24*
 OUI:FC5B26*
  ID_OUI_FROM_DATABASE=MikroBits
 
+OUI:FC5B39*
+ ID_OUI_FROM_DATABASE=Cisco
+
 OUI:FC6018*
  ID_OUI_FROM_DATABASE=Zhejiang Kangtai Electric Co., Ltd.
 
@@ -69967,12 +72316,18 @@ OUI:FC683E*
 OUI:FC6C31*
  ID_OUI_FROM_DATABASE=LXinstruments GmbH
 
+OUI:FC6DC0*
+ ID_OUI_FROM_DATABASE=BME CORPORATION
+
 OUI:FC7516*
  ID_OUI_FROM_DATABASE=D-Link International
 
 OUI:FC75E6*
  ID_OUI_FROM_DATABASE=Handreamnet
 
+OUI:FC790B*
+ ID_OUI_FROM_DATABASE=Hitachi High Technologies America, Inc.
+
 OUI:FC7CE7*
  ID_OUI_FROM_DATABASE=FCI USA LLC
 
@@ -70006,6 +72361,9 @@ OUI:FC9947*
 OUI:FC9FAE*
  ID_OUI_FROM_DATABASE=Fidus Systems Inc
 
+OUI:FC9FE1*
+ ID_OUI_FROM_DATABASE=CONWIN.Tech. Ltd
+
 OUI:FCA13E*
  ID_OUI_FROM_DATABASE=Samsung Electronics
 
@@ -70015,6 +72373,9 @@ OUI:FCA841*
 OUI:FCA9B0*
  ID_OUI_FROM_DATABASE=MIARTECH (SHANGHAI),INC.
 
+OUI:FCAA14*
+ ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD.
+
 OUI:FCAD0F*
  ID_OUI_FROM_DATABASE=QTS NETWORKS
 
@@ -70030,6 +72391,9 @@ OUI:FCBBA1*
 OUI:FCC23D*
  ID_OUI_FROM_DATABASE=Atmel Corporation
 
+OUI:FCC2DE*
+ ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
+
 OUI:FCC734*
  ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
 
@@ -70048,6 +72412,9 @@ OUI:FCD4F2*
 OUI:FCD4F6*
  ID_OUI_FROM_DATABASE=Messana Air.Ray Conditioning s.r.l.
 
+OUI:FCD5D9*
+ ID_OUI_FROM_DATABASE=Shenzhen SDMC Technology Co., Ltd.
+
 OUI:FCD6BD*
  ID_OUI_FROM_DATABASE=Robert Bosch GmbH
 
@@ -70057,9 +72424,15 @@ OUI:FCD817*
 OUI:FCDB96*
  ID_OUI_FROM_DATABASE=ENERVALLEY CO., LTD
 
+OUI:FCDBB3*
+ ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
+
 OUI:FCDD55*
  ID_OUI_FROM_DATABASE=Shenzhen WeWins wireless Co.,Ltd
 
+OUI:FCE186*
+ ID_OUI_FROM_DATABASE=A3M Co., LTD
+
 OUI:FCE192*
  ID_OUI_FROM_DATABASE=Sichuan Jinwangtong Electronic Science&Technology Co,.Ltd
 
@@ -70078,12 +72451,18 @@ OUI:FCE892*
 OUI:FCEDB9*
  ID_OUI_FROM_DATABASE=Arrayent
 
+OUI:FCF152*
+ ID_OUI_FROM_DATABASE=Sony Corporation
+
 OUI:FCF1CD*
  ID_OUI_FROM_DATABASE=OPTEX-FA CO.,LTD.
 
 OUI:FCF528*
  ID_OUI_FROM_DATABASE=ZyXEL Communications Corporation
 
+OUI:FCF647*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Tech.Co.,Ltd.
+
 OUI:FCF8AE*
  ID_OUI_FROM_DATABASE=Intel Corporate
 
@@ -70098,3 +72477,6 @@ OUI:FCFBFB*
 
 OUI:FCFE77*
  ID_OUI_FROM_DATABASE=Hitachi Reftechno, Inc.
+
+OUI:FCFFAA*
+ ID_OUI_FROM_DATABASE=IEEE REGISTRATION AUTHORITY  - Please see MAL public listing for more information.
index db3bc24..9f3136a 100644 (file)
@@ -115,7 +115,7 @@ bluetooth:v0024*
  ID_VENDOR_FROM_DATABASE=Alcatel
 
 bluetooth:v0025*
- ID_VENDOR_FROM_DATABASE=Philips Semiconductors
+ ID_VENDOR_FROM_DATABASE=NXP Semiconductors (formerly Philips Semiconductors)
 
 bluetooth:v0026*
  ID_VENDOR_FROM_DATABASE=C Technologies
@@ -427,7 +427,7 @@ bluetooth:v008B*
  ID_VENDOR_FROM_DATABASE=Topcorn Positioning Systems, LLC
 
 bluetooth:v008C*
- ID_VENDOR_FROM_DATABASE=Qualcomm Retail Solutions, Inc. (formerly Qualcomm Labs, Inc.)
+ ID_VENDOR_FROM_DATABASE=Gimbal Inc. (formerly Qualcomm Labs, Inc. and Qualcomm Retail Solutions, Inc.)
 
 bluetooth:v008D*
  ID_VENDOR_FROM_DATABASE=Zscan Software
@@ -733,7 +733,7 @@ bluetooth:v00F1*
  ID_VENDOR_FROM_DATABASE=Witron Technology Limited
 
 bluetooth:v00F2*
- ID_VENDOR_FROM_DATABASE=Morse Project Inc.
+ ID_VENDOR_FROM_DATABASE=Aether Things Inc. (formerly Morse Project Inc.)
 
 bluetooth:v00F3*
  ID_VENDOR_FROM_DATABASE=Kent Displays Inc.
@@ -902,3 +902,174 @@ bluetooth:v0129*
 
 bluetooth:v012A*
  ID_VENDOR_FROM_DATABASE=Changzhou Yongse Infotech Co., Ltd
+
+bluetooth:v012B*
+ ID_VENDOR_FROM_DATABASE=SportIQ
+
+bluetooth:v012C*
+ ID_VENDOR_FROM_DATABASE=TEMEC Instruments B.V.
+
+bluetooth:v012D*
+ ID_VENDOR_FROM_DATABASE=Sony Corporation
+
+bluetooth:v012E*
+ ID_VENDOR_FROM_DATABASE=ASSA ABLOY
+
+bluetooth:v012F*
+ ID_VENDOR_FROM_DATABASE=Clarion Co., Ltd.
+
+bluetooth:v0130*
+ ID_VENDOR_FROM_DATABASE=Warehouse Innovations
+
+bluetooth:v0131*
+ ID_VENDOR_FROM_DATABASE=Cypress Semiconductor Corporation
+
+bluetooth:v0132*
+ ID_VENDOR_FROM_DATABASE=MADS Inc
+
+bluetooth:v0133*
+ ID_VENDOR_FROM_DATABASE=Blue Maestro Limited
+
+bluetooth:v0134*
+ ID_VENDOR_FROM_DATABASE=Resolution Products, Inc.
+
+bluetooth:v0135*
+ ID_VENDOR_FROM_DATABASE=Airewear LLC
+
+bluetooth:v0136*
+ ID_VENDOR_FROM_DATABASE=ETC sp. z.o.o.
+
+bluetooth:v0137*
+ ID_VENDOR_FROM_DATABASE=Prestigio Plaza Ltd.
+
+bluetooth:v0138*
+ ID_VENDOR_FROM_DATABASE=NTEO Inc.
+
+bluetooth:v0139*
+ ID_VENDOR_FROM_DATABASE=Focus Systems Corporation
+
+bluetooth:v013A*
+ ID_VENDOR_FROM_DATABASE=Tencent Holdings Limited
+
+bluetooth:v013B*
+ ID_VENDOR_FROM_DATABASE=Allegion
+
+bluetooth:v013C*
+ ID_VENDOR_FROM_DATABASE=Murata Manufacuring Co., Ltd.
+
+bluetooth:v013D*
+ ID_VENDOR_FROM_DATABASE=WirelessWERX
+
+bluetooth:v013E*
+ ID_VENDOR_FROM_DATABASE=Nod, Inc.
+
+bluetooth:v013F*
+ ID_VENDOR_FROM_DATABASE=B&B Manufacturing Company
+
+bluetooth:v0140*
+ ID_VENDOR_FROM_DATABASE=Alpine Electronics (China) Co., Ltd
+
+bluetooth:v0141*
+ ID_VENDOR_FROM_DATABASE=FedEx Services
+
+bluetooth:v0142*
+ ID_VENDOR_FROM_DATABASE=Grape Systems Inc.
+
+bluetooth:v0143*
+ ID_VENDOR_FROM_DATABASE=Bkon Connect
+
+bluetooth:v0144*
+ ID_VENDOR_FROM_DATABASE=Lintech GmbH
+
+bluetooth:v0145*
+ ID_VENDOR_FROM_DATABASE=Novatel Wireless
+
+bluetooth:v0146*
+ ID_VENDOR_FROM_DATABASE=Ciright
+
+bluetooth:v0147*
+ ID_VENDOR_FROM_DATABASE=Mighty Cast, Inc.
+
+bluetooth:v0148*
+ ID_VENDOR_FROM_DATABASE=Ambimat Electronics
+
+bluetooth:v0149*
+ ID_VENDOR_FROM_DATABASE=Perytons Ltd.
+
+bluetooth:v014A*
+ ID_VENDOR_FROM_DATABASE=Tivoli Audio, LLC
+
+bluetooth:v014B*
+ ID_VENDOR_FROM_DATABASE=Master Lock
+
+bluetooth:v014C*
+ ID_VENDOR_FROM_DATABASE=Mesh-Net Ltd
+
+bluetooth:v014D*
+ ID_VENDOR_FROM_DATABASE=Huizhou Desay SV Automotive CO., LTD.
+
+bluetooth:v014E*
+ ID_VENDOR_FROM_DATABASE=Tangerine, Inc.
+
+bluetooth:v014F*
+ ID_VENDOR_FROM_DATABASE=B&W Group Ltd.
+
+bluetooth:v0150*
+ ID_VENDOR_FROM_DATABASE=Pioneer Corporation
+
+bluetooth:v0151*
+ ID_VENDOR_FROM_DATABASE=OnBeep
+
+bluetooth:v0152*
+ ID_VENDOR_FROM_DATABASE=Vernier Software & Technology
+
+bluetooth:v0153*
+ ID_VENDOR_FROM_DATABASE=ROL Ergo
+
+bluetooth:v0154*
+ ID_VENDOR_FROM_DATABASE=Pebble Technology
+
+bluetooth:v0155*
+ ID_VENDOR_FROM_DATABASE=NETATMO
+
+bluetooth:v0156*
+ ID_VENDOR_FROM_DATABASE=Accumulate AB
+
+bluetooth:v0157*
+ ID_VENDOR_FROM_DATABASE=Anhui Huami Information Technology Co., Ltd.
+
+bluetooth:v0158*
+ ID_VENDOR_FROM_DATABASE=Inmite s.r.o.
+
+bluetooth:v0159*
+ ID_VENDOR_FROM_DATABASE=ChefSteps, Inc.
+
+bluetooth:v015A*
+ ID_VENDOR_FROM_DATABASE=micas AG
+
+bluetooth:v015B*
+ ID_VENDOR_FROM_DATABASE=Biomedical Research Ltd.
+
+bluetooth:v015C*
+ ID_VENDOR_FROM_DATABASE=Pitius Tec S.L.
+
+bluetooth:v015D*
+ ID_VENDOR_FROM_DATABASE=Estimote, Inc.
+
+bluetooth:v015E*
+ ID_VENDOR_FROM_DATABASE=Unikey Technologies, Inc.
+
+bluetooth:v015F*
+ ID_VENDOR_FROM_DATABASE=Timer Cap Co.
+
+bluetooth:v0160*
+ ID_VENDOR_FROM_DATABASE=AwoX
+
+bluetooth:v0161*
+ ID_VENDOR_FROM_DATABASE=yikes
+
+bluetooth:v0162*
+ ID_VENDOR_FROM_DATABASE=MADSGlobal NZ Ltd.
+
+bluetooth:v0163*
+ ID_VENDOR_FROM_DATABASE=PCH International
index 29d2633..2408dc1 100644 (file)
@@ -2,4 +2,4 @@
 
 # Dell iDRAC Virtual USB NIC
 usb:v413CpA102*
- ID_NET_NAME_FROM_DATABASE=irdac
+ ID_NET_NAME_FROM_DATABASE=idrac
index fd1d5d0..5702c40 100644 (file)
@@ -47,12 +47,24 @@ pci:v*d*sv*sd*bc01sc06i00*
 pci:v*d*sv*sd*bc01sc06i01*
  ID_PCI_INTERFACE_FROM_DATABASE=AHCI 1.0
 
+pci:v*d*sv*sd*bc01sc06i02*
+ ID_PCI_INTERFACE_FROM_DATABASE=Serial Storage Bus
+
 pci:v*d*sv*sd*bc01sc07*
  ID_PCI_SUBCLASS_FROM_DATABASE=Serial Attached SCSI controller
 
+pci:v*d*sv*sd*bc01sc07i01*
+ ID_PCI_INTERFACE_FROM_DATABASE=Serial Storage Bus
+
 pci:v*d*sv*sd*bc01sc08*
  ID_PCI_SUBCLASS_FROM_DATABASE=Non-Volatile memory controller
 
+pci:v*d*sv*sd*bc01sc08i01*
+ ID_PCI_INTERFACE_FROM_DATABASE=NVMHCI
+
+pci:v*d*sv*sd*bc01sc08i02*
+ ID_PCI_INTERFACE_FROM_DATABASE=NVM Express
+
 pci:v*d*sv*sd*bc01sc80*
  ID_PCI_SUBCLASS_FROM_DATABASE=Mass storage controller
 
@@ -80,6 +92,9 @@ pci:v*d*sv*sd*bc02sc05*
 pci:v*d*sv*sd*bc02sc06*
  ID_PCI_SUBCLASS_FROM_DATABASE=PICMG controller
 
+pci:v*d*sv*sd*bc02sc07*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Infiniband controller
+
 pci:v*d*sv*sd*bc02sc80*
  ID_PCI_SUBCLASS_FROM_DATABASE=Network controller
 
@@ -311,6 +326,9 @@ pci:v*d*sv*sd*bc08sc02i01*
 pci:v*d*sv*sd*bc08sc02i02*
  ID_PCI_INTERFACE_FROM_DATABASE=EISA Timers
 
+pci:v*d*sv*sd*bc08sc02i03*
+ ID_PCI_INTERFACE_FROM_DATABASE=HPET
+
 pci:v*d*sv*sd*bc08sc03*
  ID_PCI_SUBCLASS_FROM_DATABASE=RTC
 
@@ -527,5 +545,14 @@ pci:v*d*sv*sd*bc11sc20*
 pci:v*d*sv*sd*bc11sc80*
  ID_PCI_SUBCLASS_FROM_DATABASE=Signal processing controller
 
+pci:v*d*sv*sd*bc12*
+ ID_PCI_CLASS_FROM_DATABASE=Processing accelerators
+
+pci:v*d*sv*sd*bc12sc00*
+ ID_PCI_SUBCLASS_FROM_DATABASE=Processing accelerators
+
+pci:v*d*sv*sd*bc13*
+ ID_PCI_CLASS_FROM_DATABASE=Non-Essential Instrumentation
+
 pci:v*d*sv*sd*bcFF*
  ID_PCI_CLASS_FROM_DATABASE=Unassigned class
index 7f833e3..3bcdbc0 100644 (file)
@@ -15,10 +15,10 @@ pci:v0000001Cd00000001*
  ID_MODEL_FROM_DATABASE=PCAN-PCI CAN-Bus controller
 
 pci:v0000001Cd00000001sv0000001Csd00000004*
- ID_MODEL_FROM_DATABASE=2 Channel CAN Bus SJC1000
+ ID_MODEL_FROM_DATABASE=PCAN-PCI CAN-Bus controller (2 Channel CAN Bus SJC1000)
 
 pci:v0000001Cd00000001sv0000001Csd00000005*
- ID_MODEL_FROM_DATABASE=2 Channel CAN Bus SJC1000 (Optically Isolated)
+ ID_MODEL_FROM_DATABASE=PCAN-PCI CAN-Bus controller (2 Channel CAN Bus SJC1000 (Optically Isolated))
 
 pci:v0000003D*
  ID_VENDOR_FROM_DATABASE=Lockheed Martin-Marietta Corp
@@ -189,19 +189,19 @@ pci:v00000E11d00000046*
  ID_MODEL_FROM_DATABASE=Smart Array 64xx
 
 pci:v00000E11d00000046sv00000E11sd00004091*
- ID_MODEL_FROM_DATABASE=Smart Array 6i
+ ID_MODEL_FROM_DATABASE=Smart Array 64xx (Smart Array 6i)
 
 pci:v00000E11d00000046sv00000E11sd0000409A*
- ID_MODEL_FROM_DATABASE=Smart Array 641
+ ID_MODEL_FROM_DATABASE=Smart Array 64xx (Smart Array 641)
 
 pci:v00000E11d00000046sv00000E11sd0000409B*
- ID_MODEL_FROM_DATABASE=Smart Array 642
+ ID_MODEL_FROM_DATABASE=Smart Array 64xx (Smart Array 642)
 
 pci:v00000E11d00000046sv00000E11sd0000409C*
- ID_MODEL_FROM_DATABASE=Smart Array 6400
+ ID_MODEL_FROM_DATABASE=Smart Array 64xx (Smart Array 6400)
 
 pci:v00000E11d00000046sv00000E11sd0000409D*
- ID_MODEL_FROM_DATABASE=Smart Array 6400 EM
+ ID_MODEL_FROM_DATABASE=Smart Array 64xx (Smart Array 6400 EM)
 
 pci:v00000E11d00000049*
  ID_MODEL_FROM_DATABASE=NC7132 Gigabit Upgrade Module
@@ -321,7 +321,7 @@ pci:v00000E11d0000A0F0*
  ID_MODEL_FROM_DATABASE=Advanced System Management Controller
 
 pci:v00000E11d0000A0F0sv00000E11sd0000B0F3*
- ID_MODEL_FROM_DATABASE=ProLiant DL360
+ ID_MODEL_FROM_DATABASE=Advanced System Management Controller (ProLiant DL360)
 
 pci:v00000E11d0000A0F3*
  ID_MODEL_FROM_DATABASE=Triflex PCI to ISA Bridge
@@ -330,10 +330,10 @@ pci:v00000E11d0000A0F7*
  ID_MODEL_FROM_DATABASE=PCI Hotplug Controller
 
 pci:v00000E11d0000A0F7sv00008086sd0000002A*
- ID_MODEL_FROM_DATABASE=PCI Hotplug Controller A
+ ID_MODEL_FROM_DATABASE=PCI Hotplug Controller (A)
 
 pci:v00000E11d0000A0F7sv00008086sd0000002B*
- ID_MODEL_FROM_DATABASE=PCI Hotplug Controller B
+ ID_MODEL_FROM_DATABASE=PCI Hotplug Controller (B)
 
 pci:v00000E11d0000A0F8*
  ID_MODEL_FROM_DATABASE=ZFMicro Chipset USB
@@ -345,19 +345,19 @@ pci:v00000E11d0000AE10*
  ID_MODEL_FROM_DATABASE=Smart-2/P RAID Controller
 
 pci:v00000E11d0000AE10sv00000E11sd00004030*
- ID_MODEL_FROM_DATABASE=Smart-2/P Array Controller
+ ID_MODEL_FROM_DATABASE=Smart-2/P RAID Controller (Smart-2/P Array Controller)
 
 pci:v00000E11d0000AE10sv00000E11sd00004031*
- ID_MODEL_FROM_DATABASE=Smart-2SL Array Controller
+ ID_MODEL_FROM_DATABASE=Smart-2/P RAID Controller (Smart-2SL Array Controller)
 
 pci:v00000E11d0000AE10sv00000E11sd00004032*
- ID_MODEL_FROM_DATABASE=Smart Array 3200 Controller
+ ID_MODEL_FROM_DATABASE=Smart-2/P RAID Controller (Smart Array 3200 Controller)
 
 pci:v00000E11d0000AE10sv00000E11sd00004033*
- ID_MODEL_FROM_DATABASE=Smart Array 3100ES Controller
+ ID_MODEL_FROM_DATABASE=Smart-2/P RAID Controller (Smart Array 3100ES Controller)
 
 pci:v00000E11d0000AE10sv00000E11sd00004034*
- ID_MODEL_FROM_DATABASE=Smart Array 221 Controller
+ ID_MODEL_FROM_DATABASE=Smart-2/P RAID Controller (Smart Array 221 Controller)
 
 pci:v00000E11d0000AE29*
  ID_MODEL_FROM_DATABASE=MIS-L
@@ -468,13 +468,13 @@ pci:v00000E11d0000B178*
  ID_MODEL_FROM_DATABASE=Smart Array 5i/532
 
 pci:v00000E11d0000B178sv00000E11sd00004080*
- ID_MODEL_FROM_DATABASE=Smart Array 5i
+ ID_MODEL_FROM_DATABASE=Smart Array 5i/532 (Smart Array 5i)
 
 pci:v00000E11d0000B178sv00000E11sd00004082*
- ID_MODEL_FROM_DATABASE=Smart Array 532
+ ID_MODEL_FROM_DATABASE=Smart Array 5i/532 (Smart Array 532)
 
 pci:v00000E11d0000B178sv00000E11sd00004083*
- ID_MODEL_FROM_DATABASE=Smart Array 5312
+ ID_MODEL_FROM_DATABASE=Smart Array 5i/532 (Smart Array 5312)
 
 pci:v00000E11d0000B1A4*
  ID_MODEL_FROM_DATABASE=NC7131 Gigabit Server Adapter
@@ -497,6 +497,9 @@ pci:v00000E11d0000F130*
 pci:v00000E11d0000F150*
  ID_MODEL_FROM_DATABASE=NetFlex-3/P ThunderLAN 2.3
 
+pci:v00000E55*
+ ID_VENDOR_FROM_DATABASE=HaSoTec GmbH
+
 pci:v00000EAC*
  ID_VENDOR_FROM_DATABASE=SHF Communication Technologies AG
 
@@ -513,7 +516,7 @@ pci:v00001000d00000001*
  ID_MODEL_FROM_DATABASE=53c810
 
 pci:v00001000d00000001sv00001000sd00001000*
- ID_MODEL_FROM_DATABASE=LSI53C810AE PCI to SCSI I/O Processor
+ ID_MODEL_FROM_DATABASE=53c810 (LSI53C810AE PCI to SCSI I/O Processor)
 
 pci:v00001000d00000002*
  ID_MODEL_FROM_DATABASE=53c820
@@ -522,7 +525,7 @@ pci:v00001000d00000003*
  ID_MODEL_FROM_DATABASE=53c825
 
 pci:v00001000d00000003sv00001000sd00001000*
- ID_MODEL_FROM_DATABASE=LSI53C825AE PCI to SCSI I/O Processor (Ultra Wide)
+ ID_MODEL_FROM_DATABASE=53c825 (LSI53C825AE PCI to SCSI I/O Processor (Ultra Wide))
 
 pci:v00001000d00000004*
  ID_MODEL_FROM_DATABASE=53c815
@@ -534,49 +537,49 @@ pci:v00001000d00000006*
  ID_MODEL_FROM_DATABASE=53c860
 
 pci:v00001000d00000006sv00001000sd00001000*
- ID_MODEL_FROM_DATABASE=LSI53C860E PCI to Ultra SCSI I/O Processor
+ ID_MODEL_FROM_DATABASE=53c860 (LSI53C860E PCI to Ultra SCSI I/O Processor)
 
 pci:v00001000d0000000A*
  ID_MODEL_FROM_DATABASE=53c1510
 
 pci:v00001000d0000000Asv00000E11sd0000B143*
- ID_MODEL_FROM_DATABASE=Integrated Dual Channel Wide Ultra2 SCSI Controller
+ ID_MODEL_FROM_DATABASE=53c1510 (Integrated Dual Channel Wide Ultra2 SCSI Controller)
 
 pci:v00001000d0000000Asv00001000sd00001000*
- ID_MODEL_FROM_DATABASE=LSI53C1510 PCI to Dual Channel Wide Ultra2 SCSI Controller (Nonintelligent mode)
+ ID_MODEL_FROM_DATABASE=53c1510 (LSI53C1510 PCI to Dual Channel Wide Ultra2 SCSI Controller (Nonintelligent mode))
 
 pci:v00001000d0000000B*
  ID_MODEL_FROM_DATABASE=53C896/897
 
 pci:v00001000d0000000Bsv00000E11sd00006004*
- ID_MODEL_FROM_DATABASE=EOB003 Series SCSI host adapter
+ ID_MODEL_FROM_DATABASE=53C896/897 (EOB003 Series SCSI host adapter)
 
 pci:v00001000d0000000Bsv00001000sd00001000*
- ID_MODEL_FROM_DATABASE=LSI53C896/7 PCI to Dual Channel Ultra2 SCSI Multifunction Controller
+ ID_MODEL_FROM_DATABASE=53C896/897 (LSI53C896/7 PCI to Dual Channel Ultra2 SCSI Multifunction Controller)
 
 pci:v00001000d0000000Bsv00001000sd00001010*
- ID_MODEL_FROM_DATABASE=LSI22910 PCI to Dual Channel Ultra2 SCSI host adapter
+ ID_MODEL_FROM_DATABASE=53C896/897 (LSI22910 PCI to Dual Channel Ultra2 SCSI host adapter)
 
 pci:v00001000d0000000Bsv00001000sd00001020*
- ID_MODEL_FROM_DATABASE=LSI21002 PCI to Dual Channel Ultra2 SCSI host adapter
+ ID_MODEL_FROM_DATABASE=53C896/897 (LSI21002 PCI to Dual Channel Ultra2 SCSI host adapter)
 
 pci:v00001000d0000000Bsv000013E9sd00001000*
- ID_MODEL_FROM_DATABASE=6221L-4U (Dual U2W SCSI, dual 10/100TX, graphics)
+ ID_MODEL_FROM_DATABASE=53C896/897 (6221L-4U (Dual U2W SCSI, dual 10/100TX, graphics))
 
 pci:v00001000d0000000C*
  ID_MODEL_FROM_DATABASE=53c895
 
 pci:v00001000d0000000Csv00001000sd00001010*
- ID_MODEL_FROM_DATABASE=LSI8951U PCI to Ultra2 SCSI host adapter
+ ID_MODEL_FROM_DATABASE=53c895 (LSI8951U PCI to Ultra2 SCSI host adapter)
 
 pci:v00001000d0000000Csv00001000sd00001020*
- ID_MODEL_FROM_DATABASE=LSI8952U PCI to Ultra2 SCSI host adapter
+ ID_MODEL_FROM_DATABASE=53c895 (LSI8952U PCI to Ultra2 SCSI host adapter)
 
 pci:v00001000d0000000Csv00001DE1sd00003906*
- ID_MODEL_FROM_DATABASE=DC-390U2B SCSI adapter
+ ID_MODEL_FROM_DATABASE=53c895 (DC-390U2B SCSI adapter)
 
 pci:v00001000d0000000Csv00001DE1sd00003907*
- ID_MODEL_FROM_DATABASE=DC-390U2W
+ ID_MODEL_FROM_DATABASE=53c895 (DC-390U2W)
 
 pci:v00001000d0000000D*
  ID_MODEL_FROM_DATABASE=53c885
@@ -585,151 +588,151 @@ pci:v00001000d0000000F*
  ID_MODEL_FROM_DATABASE=53c875
 
 pci:v00001000d0000000Fsv00000E11sd00007004*
- ID_MODEL_FROM_DATABASE=Embedded Ultra Wide SCSI Controller
+ ID_MODEL_FROM_DATABASE=53c875 (Embedded Ultra Wide SCSI Controller)
 
 pci:v00001000d0000000Fsv00001000sd00001000*
- ID_MODEL_FROM_DATABASE=LSI53C876/E PCI to Dual Channel SCSI Controller
+ ID_MODEL_FROM_DATABASE=53c875 (LSI53C876/E PCI to Dual Channel SCSI Controller)
 
 pci:v00001000d0000000Fsv00001000sd00001010*
- ID_MODEL_FROM_DATABASE=LSI22801 PCI to Dual Channel Ultra SCSI host adapter
+ ID_MODEL_FROM_DATABASE=53c875 (LSI22801 PCI to Dual Channel Ultra SCSI host adapter)
 
 pci:v00001000d0000000Fsv00001000sd00001020*
- ID_MODEL_FROM_DATABASE=LSI22802 PCI to Dual Channel Ultra SCSI host adapter
+ ID_MODEL_FROM_DATABASE=53c875 (LSI22802 PCI to Dual Channel Ultra SCSI host adapter)
 
 pci:v00001000d0000000Fsv00001092sd00008760*
- ID_MODEL_FROM_DATABASE=FirePort 40 Dual SCSI Controller
+ ID_MODEL_FROM_DATABASE=53c875 (FirePort 40 Dual SCSI Controller)
 
 pci:v00001000d0000000Fsv00001775sd000010D0*
- ID_MODEL_FROM_DATABASE=V5D Single Board Computer Wide Ultra SCSI
+ ID_MODEL_FROM_DATABASE=53c875 (V5D Single Board Computer Wide Ultra SCSI)
 
 pci:v00001000d0000000Fsv00001775sd000010D1*
- ID_MODEL_FROM_DATABASE=V5D Single Board Computer Ultra SCSI
+ ID_MODEL_FROM_DATABASE=53c875 (V5D Single Board Computer Ultra SCSI)
 
 pci:v00001000d0000000Fsv00001DE1sd00003904*
- ID_MODEL_FROM_DATABASE=DC390F/U Ultra Wide SCSI Adapter
+ ID_MODEL_FROM_DATABASE=53c875 (DC390F/U Ultra Wide SCSI Adapter)
 
 pci:v00001000d0000000Fsv00004C53sd00001000*
- ID_MODEL_FROM_DATABASE=CC7/CR7/CP7/VC7/VP7/VR7 mainboard
+ ID_MODEL_FROM_DATABASE=53c875 (CC7/CR7/CP7/VC7/VP7/VR7 mainboard)
 
 pci:v00001000d0000000Fsv00004C53sd00001050*
- ID_MODEL_FROM_DATABASE=CT7 mainboard
+ ID_MODEL_FROM_DATABASE=53c875 (CT7 mainboard)
 
 pci:v00001000d00000010*
  ID_MODEL_FROM_DATABASE=53C1510
 
 pci:v00001000d00000010sv00000E11sd00004040*
- ID_MODEL_FROM_DATABASE=Integrated Smart Array Controller
+ ID_MODEL_FROM_DATABASE=53C1510 (Integrated Smart Array Controller)
 
 pci:v00001000d00000010sv00000E11sd00004048*
- ID_MODEL_FROM_DATABASE=RAID LC2 Controller
+ ID_MODEL_FROM_DATABASE=53C1510 (RAID LC2 Controller)
 
 pci:v00001000d00000010sv00001000sd00001000*
- ID_MODEL_FROM_DATABASE=53C1510 PCI to Dual Channel Wide Ultra2 SCSI Controller (Intelligent mode)
+ ID_MODEL_FROM_DATABASE=53C1510 (PCI to Dual Channel Wide Ultra2 SCSI Controller (Intelligent mode))
 
 pci:v00001000d00000012*
  ID_MODEL_FROM_DATABASE=53c895a
 
 pci:v00001000d00000012sv00001000sd00001000*
- ID_MODEL_FROM_DATABASE=LSI53C895A PCI to Ultra2 SCSI Controller
+ ID_MODEL_FROM_DATABASE=53c895a (LSI53C895A PCI to Ultra2 SCSI Controller)
 
 pci:v00001000d00000013*
  ID_MODEL_FROM_DATABASE=53c875a
 
 pci:v00001000d00000013sv00001000sd00001000*
- ID_MODEL_FROM_DATABASE=LSI53C875A PCI to Ultra SCSI Controller
+ ID_MODEL_FROM_DATABASE=53c875a (LSI53C875A PCI to Ultra SCSI Controller)
 
 pci:v00001000d00000020*
  ID_MODEL_FROM_DATABASE=53c1010 Ultra3 SCSI Adapter
 
 pci:v00001000d00000020sv00001000sd00001000*
- ID_MODEL_FROM_DATABASE=LSI53C1010-33 PCI to Dual Channel Ultra160 SCSI Controller
+ ID_MODEL_FROM_DATABASE=53c1010 Ultra3 SCSI Adapter (LSI53C1010-33 PCI to Dual Channel Ultra160 SCSI Controller)
 
 pci:v00001000d00000020sv0000107Bsd00001040*
- ID_MODEL_FROM_DATABASE=Server Onboard 53C1010-33
+ ID_MODEL_FROM_DATABASE=53c1010 Ultra3 SCSI Adapter (Server Onboard 53C1010-33)
 
 pci:v00001000d00000020sv00001DE1sd00001020*
- ID_MODEL_FROM_DATABASE=DC-390U3W
+ ID_MODEL_FROM_DATABASE=53c1010 Ultra3 SCSI Adapter (DC-390U3W)
 
 pci:v00001000d00000021*
  ID_MODEL_FROM_DATABASE=53c1010 66MHz  Ultra3 SCSI Adapter
 
 pci:v00001000d00000021sv00001000sd00001000*
- ID_MODEL_FROM_DATABASE=LSI53C1000/1000R/1010R/1010-66 PCI to Ultra160 SCSI Controller
+ ID_MODEL_FROM_DATABASE=53c1010 66MHz  Ultra3 SCSI Adapter (LSI53C1000/1000R/1010R/1010-66 PCI to Ultra160 SCSI Controller)
 
 pci:v00001000d00000021sv00001000sd00001010*
- ID_MODEL_FROM_DATABASE=Asus TR-DLS onboard 53C1010-66
+ ID_MODEL_FROM_DATABASE=53c1010 66MHz  Ultra3 SCSI Adapter (Asus TR-DLS onboard 53C1010-66)
 
 pci:v00001000d00000021sv0000103Csd00001300*
- ID_MODEL_FROM_DATABASE=Ultra160 SCSI [AB306A]
+ ID_MODEL_FROM_DATABASE=53c1010 66MHz  Ultra3 SCSI Adapter (Ultra160 SCSI [AB306A])
 
 pci:v00001000d00000021sv0000103Csd00001310*
- ID_MODEL_FROM_DATABASE=Ultra160 SCSI [A9918A]
+ ID_MODEL_FROM_DATABASE=53c1010 66MHz  Ultra3 SCSI Adapter (Ultra160 SCSI [A9918A])
 
 pci:v00001000d00000021sv0000103Csd00001330*
- ID_MODEL_FROM_DATABASE=Ultra160 SCSI [A7059A]
+ ID_MODEL_FROM_DATABASE=53c1010 66MHz  Ultra3 SCSI Adapter (Ultra160 SCSI [A7059A])
 
 pci:v00001000d00000021sv0000103Csd00001340*
- ID_MODEL_FROM_DATABASE=Ultra160 SCSI [A7060A]
+ ID_MODEL_FROM_DATABASE=53c1010 66MHz  Ultra3 SCSI Adapter (Ultra160 SCSI [A7060A])
 
 pci:v00001000d00000021sv0000124Bsd00001070*
- ID_MODEL_FROM_DATABASE=PMC-USCSI3
+ ID_MODEL_FROM_DATABASE=53c1010 66MHz  Ultra3 SCSI Adapter (PMC-USCSI3)
 
 pci:v00001000d00000021sv00004C53sd00001080*
- ID_MODEL_FROM_DATABASE=CT8 mainboard
+ ID_MODEL_FROM_DATABASE=53c1010 66MHz  Ultra3 SCSI Adapter (CT8 mainboard)
 
 pci:v00001000d00000021sv00004C53sd00001300*
- ID_MODEL_FROM_DATABASE=P017 mezzanine (32-bit PMC)
+ ID_MODEL_FROM_DATABASE=53c1010 66MHz  Ultra3 SCSI Adapter (P017 mezzanine (32-bit PMC))
 
 pci:v00001000d00000021sv00004C53sd00001310*
- ID_MODEL_FROM_DATABASE=P017 mezzanine (64-bit PMC)
+ ID_MODEL_FROM_DATABASE=53c1010 66MHz  Ultra3 SCSI Adapter (P017 mezzanine (64-bit PMC))
 
 pci:v00001000d0000002F*
  ID_MODEL_FROM_DATABASE=MegaRAID SAS 2208 IOV [Thunderbolt]
 
 pci:v00001000d0000002Fsv00001028sd00001F3E*
- ID_MODEL_FROM_DATABASE=SPERC 8
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2208 IOV [Thunderbolt] (SPERC 8)
 
 pci:v00001000d00000030*
  ID_MODEL_FROM_DATABASE=53c1030 PCI-X Fusion-MPT Dual Ultra320 SCSI
 
 pci:v00001000d00000030sv00000E11sd000000DA*
- ID_MODEL_FROM_DATABASE=ProLiant ML 350
+ ID_MODEL_FROM_DATABASE=53c1030 PCI-X Fusion-MPT Dual Ultra320 SCSI (ProLiant ML 350)
 
 pci:v00001000d00000030sv00001028sd00000123*
- ID_MODEL_FROM_DATABASE=LSI Logic 1020/1030
+ ID_MODEL_FROM_DATABASE=53c1030 PCI-X Fusion-MPT Dual Ultra320 SCSI (LSI Logic 1020/1030)
 
 pci:v00001000d00000030sv00001028sd0000014A*
- ID_MODEL_FROM_DATABASE=LSI Logic 1020/1030
+ ID_MODEL_FROM_DATABASE=53c1030 PCI-X Fusion-MPT Dual Ultra320 SCSI (LSI Logic 1020/1030)
 
 pci:v00001000d00000030sv00001028sd0000016C*
- ID_MODEL_FROM_DATABASE=PowerEdge 1850 MPT Fusion SCSI/RAID (Perc 4)
+ ID_MODEL_FROM_DATABASE=53c1030 PCI-X Fusion-MPT Dual Ultra320 SCSI (PowerEdge 1850 MPT Fusion SCSI/RAID (Perc 4))
 
 pci:v00001000d00000030sv00001028sd00000183*
- ID_MODEL_FROM_DATABASE=LSI Logic 1020/1030
+ ID_MODEL_FROM_DATABASE=53c1030 PCI-X Fusion-MPT Dual Ultra320 SCSI (LSI Logic 1020/1030)
 
 pci:v00001000d00000030sv00001028sd0000018A*
- ID_MODEL_FROM_DATABASE=PERC 4/IM
+ ID_MODEL_FROM_DATABASE=53c1030 PCI-X Fusion-MPT Dual Ultra320 SCSI (PERC 4/IM)
 
 pci:v00001000d00000030sv00001028sd00001010*
- ID_MODEL_FROM_DATABASE=LSI U320 SCSI Controller
+ ID_MODEL_FROM_DATABASE=53c1030 PCI-X Fusion-MPT Dual Ultra320 SCSI (LSI U320 SCSI Controller)
 
 pci:v00001000d00000030sv0000103Csd000012C5*
- ID_MODEL_FROM_DATABASE=Ultra320 SCSI [A7173A]
+ ID_MODEL_FROM_DATABASE=53c1030 PCI-X Fusion-MPT Dual Ultra320 SCSI (Ultra320 SCSI [A7173A])
 
 pci:v00001000d00000030sv0000103Csd00001323*
- ID_MODEL_FROM_DATABASE=Core I/O LAN/SCSI Combo [AB314A]
+ ID_MODEL_FROM_DATABASE=53c1030 PCI-X Fusion-MPT Dual Ultra320 SCSI (Core I/O LAN/SCSI Combo [AB314A])
 
 pci:v00001000d00000030sv0000103Csd00003108*
- ID_MODEL_FROM_DATABASE=Single Channel Ultra320 SCSI HBA G2
+ ID_MODEL_FROM_DATABASE=53c1030 PCI-X Fusion-MPT Dual Ultra320 SCSI (Single Channel Ultra320 SCSI HBA G2)
 
 pci:v00001000d00000030sv0000124Bsd00001170*
- ID_MODEL_FROM_DATABASE=PMC-USCSI320
+ ID_MODEL_FROM_DATABASE=53c1030 PCI-X Fusion-MPT Dual Ultra320 SCSI (PMC-USCSI320)
 
 pci:v00001000d00000030sv000015ADsd00001976*
- ID_MODEL_FROM_DATABASE=LSI Logic Parallel SCSI Controller
+ ID_MODEL_FROM_DATABASE=53c1030 PCI-X Fusion-MPT Dual Ultra320 SCSI (LSI Logic Parallel SCSI Controller)
 
 pci:v00001000d00000030sv00001734sd00001052*
- ID_MODEL_FROM_DATABASE=PRIMERGY BX/RX/TX S2 series onboard SCSI(IME)
+ ID_MODEL_FROM_DATABASE=53c1030 PCI-X Fusion-MPT Dual Ultra320 SCSI (PRIMERGY BX/RX/TX S2 series onboard SCSI(IME))
 
 pci:v00001000d00000031*
  ID_MODEL_FROM_DATABASE=53c1030ZC PCI-X Fusion-MPT Dual Ultra320 SCSI
@@ -738,7 +741,7 @@ pci:v00001000d00000032*
  ID_MODEL_FROM_DATABASE=53c1035 PCI-X Fusion-MPT Dual Ultra320 SCSI
 
 pci:v00001000d00000032sv00001000sd00001000*
- ID_MODEL_FROM_DATABASE=LSI53C1020/1030 PCI-X to Ultra320 SCSI Controller
+ ID_MODEL_FROM_DATABASE=53c1035 PCI-X Fusion-MPT Dual Ultra320 SCSI (LSI53C1020/1030 PCI-X to Ultra320 SCSI Controller)
 
 pci:v00001000d00000033*
  ID_MODEL_FROM_DATABASE=1030ZC_53c1035 PCI-X Fusion-MPT Dual Ultra320 SCSI
@@ -747,10 +750,10 @@ pci:v00001000d00000040*
  ID_MODEL_FROM_DATABASE=53c1035 PCI-X Fusion-MPT Dual Ultra320 SCSI
 
 pci:v00001000d00000040sv00001000sd00000033*
- ID_MODEL_FROM_DATABASE=MegaRAID SCSI 320-2XR
+ ID_MODEL_FROM_DATABASE=53c1035 PCI-X Fusion-MPT Dual Ultra320 SCSI (MegaRAID SCSI 320-2XR)
 
 pci:v00001000d00000040sv00001000sd00000066*
- ID_MODEL_FROM_DATABASE=MegaRAID SCSI 320-2XRWS
+ ID_MODEL_FROM_DATABASE=53c1035 PCI-X Fusion-MPT Dual Ultra320 SCSI (MegaRAID SCSI 320-2XRWS)
 
 pci:v00001000d00000041*
  ID_MODEL_FROM_DATABASE=53C1035ZC PCI-X Fusion-MPT Dual Ultra320 SCSI
@@ -759,73 +762,73 @@ pci:v00001000d00000050*
  ID_MODEL_FROM_DATABASE=SAS1064 PCI-X Fusion-MPT SAS
 
 pci:v00001000d00000050sv00001028sd00001F04*
- ID_MODEL_FROM_DATABASE=SAS 5/E
+ ID_MODEL_FROM_DATABASE=SAS1064 PCI-X Fusion-MPT SAS (SAS 5/E)
 
 pci:v00001000d00000050sv00001028sd00001F09*
- ID_MODEL_FROM_DATABASE=SAS 5i/R
+ ID_MODEL_FROM_DATABASE=SAS1064 PCI-X Fusion-MPT SAS (SAS 5i/R)
 
 pci:v00001000d00000054*
  ID_MODEL_FROM_DATABASE=SAS1068 PCI-X Fusion-MPT SAS
 
 pci:v00001000d00000054sv00001028sd00001F04*
- ID_MODEL_FROM_DATABASE=SAS 5/E Adapter Controller
+ ID_MODEL_FROM_DATABASE=SAS1068 PCI-X Fusion-MPT SAS (SAS 5/E Adapter Controller)
 
 pci:v00001000d00000054sv00001028sd00001F05*
- ID_MODEL_FROM_DATABASE=SAS 5/i Adapter Controller
+ ID_MODEL_FROM_DATABASE=SAS1068 PCI-X Fusion-MPT SAS (SAS 5/i Adapter Controller)
 
 pci:v00001000d00000054sv00001028sd00001F06*
- ID_MODEL_FROM_DATABASE=SAS 5/i Integrated Controller
+ ID_MODEL_FROM_DATABASE=SAS1068 PCI-X Fusion-MPT SAS (SAS 5/i Integrated Controller)
 
 pci:v00001000d00000054sv00001028sd00001F07*
- ID_MODEL_FROM_DATABASE=SAS 5/iR Integrated RAID Controller
+ ID_MODEL_FROM_DATABASE=SAS1068 PCI-X Fusion-MPT SAS (SAS 5/iR Integrated RAID Controller)
 
 pci:v00001000d00000054sv00001028sd00001F08*
- ID_MODEL_FROM_DATABASE=SAS 5/iR Integrated RAID Controller
+ ID_MODEL_FROM_DATABASE=SAS1068 PCI-X Fusion-MPT SAS (SAS 5/iR Integrated RAID Controller)
 
 pci:v00001000d00000054sv00001028sd00001F09*
- ID_MODEL_FROM_DATABASE=SAS 5/iR Adapter RAID Controller
+ ID_MODEL_FROM_DATABASE=SAS1068 PCI-X Fusion-MPT SAS (SAS 5/iR Adapter RAID Controller)
 
 pci:v00001000d00000054sv000015ADsd00001976*
- ID_MODEL_FROM_DATABASE=SAS Controller
+ ID_MODEL_FROM_DATABASE=SAS1068 PCI-X Fusion-MPT SAS (SAS Controller)
 
 pci:v00001000d00000055*
  ID_MODEL_FROM_DATABASE=SAS1068 PCI-X Fusion-MPT SAS
 
 pci:v00001000d00000055sv00001033sd00008336*
- ID_MODEL_FROM_DATABASE=SAS1068
+ ID_MODEL_FROM_DATABASE=SAS1068 PCI-X Fusion-MPT SAS (SAS1068)
 
 pci:v00001000d00000056*
  ID_MODEL_FROM_DATABASE=SAS1064ET PCI-Express Fusion-MPT SAS
 
 pci:v00001000d00000056sv00001014sd000003BB*
- ID_MODEL_FROM_DATABASE=ServeRAID BR10il SAS/SATA Controller v2
+ ID_MODEL_FROM_DATABASE=SAS1064ET PCI-Express Fusion-MPT SAS (ServeRAID BR10il SAS/SATA Controller v2)
 
 pci:v00001000d00000057*
  ID_MODEL_FROM_DATABASE=M1064E MegaRAID SAS
 
 pci:v00001000d00000057sv00008086sd0000346C*
- ID_MODEL_FROM_DATABASE=Embedded Software RAID Technology II (ESTRII)
+ ID_MODEL_FROM_DATABASE=M1064E MegaRAID SAS (Embedded Software RAID Technology II (ESTRII))
 
 pci:v00001000d00000058*
  ID_MODEL_FROM_DATABASE=SAS1068E PCI-Express Fusion-MPT SAS
 
 pci:v00001000d00000058sv00001000sd00003140*
- ID_MODEL_FROM_DATABASE=SAS3081E-R 8-Port SAS/SATA Host Bus Adapter
+ ID_MODEL_FROM_DATABASE=SAS1068E PCI-Express Fusion-MPT SAS (SAS3081E-R 8-Port SAS/SATA Host Bus Adapter)
 
 pci:v00001000d00000058sv00001028sd0000021D*
- ID_MODEL_FROM_DATABASE=SAS 6/iR Integrated Workstations RAID Controller
+ ID_MODEL_FROM_DATABASE=SAS1068E PCI-Express Fusion-MPT SAS (SAS 6/iR Integrated Workstations RAID Controller)
 
 pci:v00001000d00000058sv00001028sd00001F0E*
- ID_MODEL_FROM_DATABASE=SAS 6/iR Adapter RAID Controller
+ ID_MODEL_FROM_DATABASE=SAS1068E PCI-Express Fusion-MPT SAS (SAS 6/iR Adapter RAID Controller)
 
 pci:v00001000d00000058sv00001028sd00001F0F*
- ID_MODEL_FROM_DATABASE=SAS 6/iR Integrated Blades RAID Controller
+ ID_MODEL_FROM_DATABASE=SAS1068E PCI-Express Fusion-MPT SAS (SAS 6/iR Integrated Blades RAID Controller)
 
 pci:v00001000d00000058sv00001028sd00001F10*
- ID_MODEL_FROM_DATABASE=SAS 6/iR Integrated RAID Controller
+ ID_MODEL_FROM_DATABASE=SAS1068E PCI-Express Fusion-MPT SAS (SAS 6/iR Integrated RAID Controller)
 
 pci:v00001000d00000058sv0000103Csd00003229*
- ID_MODEL_FROM_DATABASE=SC44Ge Host Bus Adapter
+ ID_MODEL_FROM_DATABASE=SAS1068E PCI-Express Fusion-MPT SAS (SC44Ge Host Bus Adapter)
 
 pci:v00001000d00000059*
  ID_MODEL_FROM_DATABASE=MegaRAID SAS 8208ELP/8208ELP
@@ -837,91 +840,97 @@ pci:v00001000d0000005B*
  ID_MODEL_FROM_DATABASE=MegaRAID SAS 2208 [Thunderbolt]
 
 pci:v00001000d0000005Bsv00001000sd00009265*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 9265-8i
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2208 [Thunderbolt] (MegaRAID SAS 9265-8i)
 
 pci:v00001000d0000005Bsv00001000sd00009266*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 9266-8i
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2208 [Thunderbolt] (MegaRAID SAS 9266-8i)
 
 pci:v00001000d0000005Bsv00001000sd00009267*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 9267-8i
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2208 [Thunderbolt] (MegaRAID SAS 9267-8i)
 
 pci:v00001000d0000005Bsv00001000sd00009268*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 9265CV-8i / 9270CV-8i
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2208 [Thunderbolt] (MegaRAID SAS 9265CV-8i / 9270CV-8i)
 
 pci:v00001000d0000005Bsv00001000sd00009269*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 9266-4i
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2208 [Thunderbolt] (MegaRAID SAS 9266-4i)
 
 pci:v00001000d0000005Bsv00001000sd00009270*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 9270-8i
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2208 [Thunderbolt] (MegaRAID SAS 9270-8i)
 
 pci:v00001000d0000005Bsv00001000sd00009271*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 9271-8i
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2208 [Thunderbolt] (MegaRAID SAS 9271-8i)
 
 pci:v00001000d0000005Bsv00001000sd00009272*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 9272-8i
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2208 [Thunderbolt] (MegaRAID SAS 9272-8i)
 
 pci:v00001000d0000005Bsv00001000sd00009273*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 9270CV-8i
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2208 [Thunderbolt] (MegaRAID SAS 9270CV-8i)
 
 pci:v00001000d0000005Bsv00001000sd00009274*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 9270-4i
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2208 [Thunderbolt] (MegaRAID SAS 9270-4i)
 
 pci:v00001000d0000005Bsv00001000sd00009275*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 9271-8iCC
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2208 [Thunderbolt] (MegaRAID SAS 9271-8iCC)
 
 pci:v00001000d0000005Bsv00001000sd00009276*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 9271-4i
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2208 [Thunderbolt] (MegaRAID SAS 9271-4i)
 
 pci:v00001000d0000005Bsv00001000sd00009285*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 9285-8e
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2208 [Thunderbolt] (MegaRAID SAS 9285-8e)
 
 pci:v00001000d0000005Bsv00001000sd00009288*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 9285CV-8e
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2208 [Thunderbolt] (MegaRAID SAS 9285CV-8e)
 
 pci:v00001000d0000005Bsv00001000sd00009290*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 9286-8e
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2208 [Thunderbolt] (MegaRAID SAS 9286-8e)
 
 pci:v00001000d0000005Bsv00001000sd00009291*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 9286CV-8e
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2208 [Thunderbolt] (MegaRAID SAS 9286CV-8e)
 
 pci:v00001000d0000005Bsv00001000sd00009295*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 9286CV-8eCC
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2208 [Thunderbolt] (MegaRAID SAS 9286CV-8eCC)
 
 pci:v00001000d0000005Bsv00001014sd0000040B*
- ID_MODEL_FROM_DATABASE=ServeRAID M5110 SAS/SATA Controller
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2208 [Thunderbolt] (ServeRAID M5110 SAS/SATA Controller)
+
+pci:v00001000d0000005Bsv00001014sd0000040C*
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2208 [Thunderbolt] (ServeRAID M5120 SAS/SATA Controller)
 
 pci:v00001000d0000005Bsv00001014sd00000412*
- ID_MODEL_FROM_DATABASE=ServeRAID M5110e SAS/SATA Controller
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2208 [Thunderbolt] (ServeRAID M5110e SAS/SATA Controller)
 
 pci:v00001000d0000005Bsv00001028sd00001F2D*
- ID_MODEL_FROM_DATABASE=PERC H810 Adapter
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2208 [Thunderbolt] (PERC H810 Adapter)
 
 pci:v00001000d0000005Bsv00001028sd00001F30*
- ID_MODEL_FROM_DATABASE=PERC H710 Embedded
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2208 [Thunderbolt] (PERC H710 Embedded)
 
 pci:v00001000d0000005Bsv00001028sd00001F31*
- ID_MODEL_FROM_DATABASE=PERC H710P Adapter
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2208 [Thunderbolt] (PERC H710P Adapter)
 
 pci:v00001000d0000005Bsv00001028sd00001F33*
- ID_MODEL_FROM_DATABASE=PERC H710P Mini (for blades)
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2208 [Thunderbolt] (PERC H710P Mini (for blades))
 
 pci:v00001000d0000005Bsv00001028sd00001F34*
- ID_MODEL_FROM_DATABASE=PERC H710P Mini (for monolithics)
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2208 [Thunderbolt] (PERC H710P Mini (for monolithics))
 
 pci:v00001000d0000005Bsv00001028sd00001F35*
- ID_MODEL_FROM_DATABASE=PERC H710 Adapter
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2208 [Thunderbolt] (PERC H710 Adapter)
 
 pci:v00001000d0000005Bsv00001028sd00001F37*
- ID_MODEL_FROM_DATABASE=PERC H710 Mini (for blades)
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2208 [Thunderbolt] (PERC H710 Mini (for blades))
 
 pci:v00001000d0000005Bsv00001028sd00001F38*
- ID_MODEL_FROM_DATABASE=PERC H710 Mini (for monolithics)
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2208 [Thunderbolt] (PERC H710 Mini (for monolithics))
+
+pci:v00001000d0000005Bsv000015D9sd00000690*
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2208 [Thunderbolt] (LSI MegaRAID ROMB)
 
 pci:v00001000d0000005Bsv00008086sd00003510*
- ID_MODEL_FROM_DATABASE=RMS25PB080 RAID Controller
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2208 [Thunderbolt] (RMS25PB080 RAID Controller)
 
 pci:v00001000d0000005Bsv00008086sd00003513*
- ID_MODEL_FROM_DATABASE=RMS25CB080 RAID Controller
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2208 [Thunderbolt] (RMS25CB080 RAID Controller)
 
 pci:v00001000d0000005C*
  ID_MODEL_FROM_DATABASE=SAS1064A PCI-X Fusion-MPT SAS
@@ -930,25 +939,40 @@ pci:v00001000d0000005D*
  ID_MODEL_FROM_DATABASE=MegaRAID SAS-3 3108 [Invader]
 
 pci:v00001000d0000005Dsv00001028sd00001F41*
- ID_MODEL_FROM_DATABASE=PERC H830 Adapter
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS-3 3108 [Invader] (PERC H830 Adapter)
 
 pci:v00001000d0000005Dsv00001028sd00001F42*
- ID_MODEL_FROM_DATABASE=PERC H730P Adapter
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS-3 3108 [Invader] (PERC H730P Adapter)
 
 pci:v00001000d0000005Dsv00001028sd00001F43*
- ID_MODEL_FROM_DATABASE=PERC H730 Adapter
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS-3 3108 [Invader] (PERC H730 Adapter)
 
 pci:v00001000d0000005Dsv00001028sd00001F47*
- ID_MODEL_FROM_DATABASE=PERC H730P Mini
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS-3 3108 [Invader] (PERC H730P Mini)
 
 pci:v00001000d0000005Dsv00001028sd00001F48*
- ID_MODEL_FROM_DATABASE=PERC H730P Mini (for blades)
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS-3 3108 [Invader] (PERC H730P Mini (for blades))
 
 pci:v00001000d0000005Dsv00001028sd00001F49*
- ID_MODEL_FROM_DATABASE=PERC H730 Mini
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS-3 3108 [Invader] (PERC H730 Mini)
 
 pci:v00001000d0000005Dsv00001028sd00001F4A*
- ID_MODEL_FROM_DATABASE=PERC H730 Mini (for blades)
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS-3 3108 [Invader] (PERC H730 Mini (for blades))
+
+pci:v00001000d0000005Dsv00001028sd00001F4D*
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS-3 3108 [Invader] (PERC FS33xS)
+
+pci:v00001000d0000005Dsv00001028sd00001F4F*
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS-3 3108 [Invader] (PERC H730P Slim)
+
+pci:v00001000d0000005Dsv00001028sd00001F54*
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS-3 3108 [Invader] (PERC FS33xD)
+
+pci:v00001000d0000005Dsv000017AAsd00001052*
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS-3 3108 [Invader] (ThinkServer RAID 720i)
+
+pci:v00001000d0000005Dsv000017AAsd00001053*
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS-3 3108 [Invader] (ThinkServer RAID 720ix)
 
 pci:v00001000d0000005E*
  ID_MODEL_FROM_DATABASE=SAS1066 PCI-X Fusion-MPT SAS
@@ -957,109 +981,109 @@ pci:v00001000d0000005F*
  ID_MODEL_FROM_DATABASE=MegaRAID SAS-3 3008 [Fury]
 
 pci:v00001000d0000005Fsv00001028sd00001F44*
- ID_MODEL_FROM_DATABASE=PERC H330 Adapter
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS-3 3008 [Fury] (PERC H330 Adapter)
 
 pci:v00001000d0000005Fsv00001028sd00001F4B*
- ID_MODEL_FROM_DATABASE=PERC H330 Mini
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS-3 3008 [Fury] (PERC H330 Mini)
 
 pci:v00001000d0000005Fsv00001028sd00001F4C*
- ID_MODEL_FROM_DATABASE=PERC H330 Mini (for blades)
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS-3 3008 [Fury] (PERC H330 Mini (for blades))
 
 pci:v00001000d0000005Fsv00001028sd00001F4D*
- ID_MODEL_FROM_DATABASE=PERC H330 Embedded (for monolithic)
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS-3 3008 [Fury] (PERC H330 Embedded (for monolithic))
 
 pci:v00001000d00000060*
  ID_MODEL_FROM_DATABASE=MegaRAID SAS 1078
 
 pci:v00001000d00000060sv00001000sd00001006*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 8888ELP
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1078 (MegaRAID SAS 8888ELP)
 
 pci:v00001000d00000060sv00001000sd0000100A*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 8708ELP
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1078 (MegaRAID SAS 8708ELP)
 
 pci:v00001000d00000060sv00001000sd0000100E*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 8884E
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1078 (MegaRAID SAS 8884E)
 
 pci:v00001000d00000060sv00001000sd0000100F*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 8708E
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1078 (MegaRAID SAS 8708E)
 
 pci:v00001000d00000060sv00001000sd00001010*
- ID_MODEL_FROM_DATABASE=MegaRAID SATA 350-8ELP
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1078 (MegaRAID SATA 350-8ELP)
 
 pci:v00001000d00000060sv00001000sd00001011*
- ID_MODEL_FROM_DATABASE=MegaRAID SATA 350-4ELP
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1078 (MegaRAID SATA 350-4ELP)
 
 pci:v00001000d00000060sv00001000sd00001012*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 8704ELP
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1078 (MegaRAID SAS 8704ELP)
 
 pci:v00001000d00000060sv00001000sd00001016*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 8880EM2
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1078 (MegaRAID SAS 8880EM2)
 
 pci:v00001000d00000060sv00001014sd00000363*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS PCI Express ROMB
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1078 (MegaRAID SAS PCI Express ROMB)
 
 pci:v00001000d00000060sv00001014sd00000364*
- ID_MODEL_FROM_DATABASE=SystemX MegaRAID SAS 8808E
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1078 (SystemX MegaRAID SAS 8808E)
 
 pci:v00001000d00000060sv00001014sd00000365*
- ID_MODEL_FROM_DATABASE=SystemX MegaRAID SAS 8884E
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1078 (SystemX MegaRAID SAS 8884E)
 
 pci:v00001000d00000060sv00001014sd00000379*
- ID_MODEL_FROM_DATABASE=SystemX MegaRAID SAS 8880EM2
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1078 (SystemX MegaRAID SAS 8880EM2)
 
 pci:v00001000d00000060sv00001028sd00001F0A*
- ID_MODEL_FROM_DATABASE=PERC 6/E Adapter RAID Controller
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1078 (PERC 6/E Adapter RAID Controller)
 
 pci:v00001000d00000060sv00001028sd00001F0B*
- ID_MODEL_FROM_DATABASE=PERC 6/i Adapter RAID Controller
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1078 (PERC 6/i Adapter RAID Controller)
 
 pci:v00001000d00000060sv00001028sd00001F0C*
- ID_MODEL_FROM_DATABASE=PERC 6/i Integrated RAID Controller
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1078 (PERC 6/i Integrated RAID Controller)
 
 pci:v00001000d00000060sv00001028sd00001F0D*
- ID_MODEL_FROM_DATABASE=PERC 6/i Integrated RAID Controller
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1078 (PERC 6/i Integrated RAID Controller)
 
 pci:v00001000d00000060sv00001028sd00001F11*
- ID_MODEL_FROM_DATABASE=CERC 6/i Integrated RAID Controller
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1078 (CERC 6/i Integrated RAID Controller)
 
 pci:v00001000d00000060sv00001033sd0000835A*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS PCI Express ROMB
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1078 (MegaRAID SAS PCI Express ROMB)
 
 pci:v00001000d00000060sv00001043sd0000824D*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS PCI Express ROMB
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1078 (MegaRAID SAS PCI Express ROMB)
 
 pci:v00001000d00000060sv00001170sd0000002F*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS PCI Express ROMB
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1078 (MegaRAID SAS PCI Express ROMB)
 
 pci:v00001000d00000060sv00001170sd00000036*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS PCI Express ROMB
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1078 (MegaRAID SAS PCI Express ROMB)
 
 pci:v00001000d00000060sv000015D9sd0000C080*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS PCI Express ROMB
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1078 (MegaRAID SAS PCI Express ROMB)
 
 pci:v00001000d00000060sv000017AAsd00006B7C*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS PCI Express ROMB
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1078 (MegaRAID SAS PCI Express ROMB)
 
 pci:v00001000d00000060sv000018A1sd00000003*
- ID_MODEL_FROM_DATABASE=LSI MegaRAID SAS PCI Express ROMB
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1078 (LSI MegaRAID SAS PCI Express ROMB)
 
 pci:v00001000d00000060sv00008086sd00001006*
- ID_MODEL_FROM_DATABASE=RAID Controller SRCSAS28EP
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1078 (RAID Controller SRCSAS28EP)
 
 pci:v00001000d00000060sv00008086sd0000100A*
- ID_MODEL_FROM_DATABASE=RAID Controller SRCSAS28EV
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1078 (RAID Controller SRCSAS28EV)
 
 pci:v00001000d00000060sv00008086sd00001010*
- ID_MODEL_FROM_DATABASE=RAID Controller SRCSATA28E
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1078 (RAID Controller SRCSATA28E)
 
 pci:v00001000d00000060sv00008086sd000034CC*
- ID_MODEL_FROM_DATABASE=Integrated RAID Controller SROMBSAS28E
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1078 (Integrated RAID Controller SROMBSAS28E)
 
 pci:v00001000d00000060sv00008086sd000034CD*
- ID_MODEL_FROM_DATABASE=Integrated RAID Controller SROMBSAS28E
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1078 (Integrated RAID Controller SROMBSAS28E)
 
 pci:v00001000d00000060sv00008086sd00003505*
- ID_MODEL_FROM_DATABASE=Integrated RAID Controller SROMBSASMP2
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1078 (Integrated RAID Controller SROMBSASMP2)
 
 pci:v00001000d00000062*
  ID_MODEL_FROM_DATABASE=SAS1078 PCI-Express Fusion-MPT SAS
@@ -1086,91 +1110,100 @@ pci:v00001000d00000072*
  ID_MODEL_FROM_DATABASE=SAS2008 PCI-Express Fusion-MPT SAS-2 [Falcon]
 
 pci:v00001000d00000072sv00001028sd00001F1C*
- ID_MODEL_FROM_DATABASE=6Gbps SAS HBA Adapter
+ ID_MODEL_FROM_DATABASE=SAS2008 PCI-Express Fusion-MPT SAS-2 [Falcon] (6Gbps SAS HBA Adapter)
 
 pci:v00001000d00000072sv00001028sd00001F1D*
- ID_MODEL_FROM_DATABASE=PERC H200 Adapter
+ ID_MODEL_FROM_DATABASE=SAS2008 PCI-Express Fusion-MPT SAS-2 [Falcon] (PERC H200 Adapter)
 
 pci:v00001000d00000072sv00001028sd00001F1E*
- ID_MODEL_FROM_DATABASE=PERC H200 Integrated
+ ID_MODEL_FROM_DATABASE=SAS2008 PCI-Express Fusion-MPT SAS-2 [Falcon] (PERC H200 Integrated)
 
 pci:v00001000d00000072sv00001028sd00001F1F*
- ID_MODEL_FROM_DATABASE=PERC H200 Modular
+ ID_MODEL_FROM_DATABASE=SAS2008 PCI-Express Fusion-MPT SAS-2 [Falcon] (PERC H200 Modular)
 
 pci:v00001000d00000072sv00001028sd00001F20*
- ID_MODEL_FROM_DATABASE=PERC H200 Embedded
+ ID_MODEL_FROM_DATABASE=SAS2008 PCI-Express Fusion-MPT SAS-2 [Falcon] (PERC H200 Embedded)
 
 pci:v00001000d00000072sv00001028sd00001F22*
- ID_MODEL_FROM_DATABASE=Internal Tape Adapter
+ ID_MODEL_FROM_DATABASE=SAS2008 PCI-Express Fusion-MPT SAS-2 [Falcon] (Internal Tape Adapter)
 
 pci:v00001000d00000072sv00008086sd0000350F*
- ID_MODEL_FROM_DATABASE=RMS2LL040 RAID Controller
+ ID_MODEL_FROM_DATABASE=SAS2008 PCI-Express Fusion-MPT SAS-2 [Falcon] (RMS2LL040 RAID Controller)
 
 pci:v00001000d00000073*
  ID_MODEL_FROM_DATABASE=MegaRAID SAS 2008 [Falcon]
 
 pci:v00001000d00000073sv00001000sd00009240*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 9240-8i
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2008 [Falcon] (MegaRAID SAS 9240-8i)
 
 pci:v00001000d00000073sv00001000sd00009241*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 9240-4i
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2008 [Falcon] (MegaRAID SAS 9240-4i)
 
 pci:v00001000d00000073sv00001000sd000092A0*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 9220-8i
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2008 [Falcon] (MegaRAID SAS 9220-8i)
 
 pci:v00001000d00000073sv00001014sd000003B1*
- ID_MODEL_FROM_DATABASE=ServeRAID M1015 SAS/SATA Controller
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2008 [Falcon] (ServeRAID M1015 SAS/SATA Controller)
 
 pci:v00001000d00000073sv00001028sd00001F4E*
- ID_MODEL_FROM_DATABASE=PERC H310 Adapter
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2008 [Falcon] (PERC H310 Adapter)
 
 pci:v00001000d00000073sv00001028sd00001F4F*
- ID_MODEL_FROM_DATABASE=PERC H310 Integrated
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2008 [Falcon] (PERC H310 Integrated)
 
 pci:v00001000d00000073sv00001028sd00001F50*
- ID_MODEL_FROM_DATABASE=PERC H310 Mini Blades
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2008 [Falcon] (PERC H310 Mini Blades)
 
 pci:v00001000d00000073sv00001028sd00001F51*
- ID_MODEL_FROM_DATABASE=PERC H310 Mini Monolithics
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2008 [Falcon] (PERC H310 Mini Monolithics)
 
 pci:v00001000d00000073sv00001028sd00001F52*
- ID_MODEL_FROM_DATABASE=PERC H310 Embedded1
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2008 [Falcon] (PERC H310 Embedded1)
 
 pci:v00001000d00000073sv00001028sd00001F53*
- ID_MODEL_FROM_DATABASE=PERC H310 Embedded2
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2008 [Falcon] (PERC H310 Embedded2)
 
 pci:v00001000d00000073sv00001028sd00001F54*
- ID_MODEL_FROM_DATABASE=PERC H310 Reserved
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2008 [Falcon] (PERC H310 Reserved)
 
 pci:v00001000d00000073sv00001054sd00003035*
- ID_MODEL_FROM_DATABASE=LSI MegaRAID SAS 9240-8i
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2008 [Falcon] (LSI MegaRAID SAS 9240-8i)
 
 pci:v00001000d00000073sv00001137sd00000072*
- ID_MODEL_FROM_DATABASE=2004 iMR ROMB
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2008 [Falcon] (2004 iMR ROMB)
 
 pci:v00001000d00000073sv00001137sd00000073*
- ID_MODEL_FROM_DATABASE=2008 ROMB
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2008 [Falcon] (2008 ROMB)
 
 pci:v00001000d00000073sv00001137sd000000B0*
- ID_MODEL_FROM_DATABASE=UCSC RAID SAS 2008M-8i
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2008 [Falcon] (UCSC RAID SAS 2008M-8i)
 
 pci:v00001000d00000073sv00001137sd000000B1*
- ID_MODEL_FROM_DATABASE=UCSC RAID SAS 2008M-8i
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2008 [Falcon] (UCSC RAID SAS 2008M-8i)
+
+pci:v00001000d00000073sv00001137sd000000C2*
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2008 [Falcon] (UCS E-Series Double Wide)
+
+pci:v00001000d00000073sv00001137sd000000C3*
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2008 [Falcon] (UCS E-Series Single Wide)
 
 pci:v00001000d00000073sv000015D9sd00000400*
- ID_MODEL_FROM_DATABASE=Supermicro SMC2008-iMR
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2008 [Falcon] (Supermicro SMC2008-iMR)
 
 pci:v00001000d00000073sv00001734sd00001177*
- ID_MODEL_FROM_DATABASE=RAID Ctrl SAS 6G 0/1 (D2607)
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2008 [Falcon] (RAID Ctrl SAS 6G 0/1 (D2607))
+
+pci:v00001000d00000073sv000017AAsd00001051*
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2008 [Falcon] (ThinkServer RAID 510i)
 
 pci:v00001000d00000073sv00008086sd0000350D*
- ID_MODEL_FROM_DATABASE=RMS2AF040 RAID Controller
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2008 [Falcon] (RMS2AF040 RAID Controller)
 
 pci:v00001000d00000073sv00008086sd00009240*
- ID_MODEL_FROM_DATABASE=RAID Controller RS2WC080
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2008 [Falcon] (RAID Controller RS2WC080)
 
 pci:v00001000d00000073sv00008086sd00009241*
- ID_MODEL_FROM_DATABASE=RAID Controller RS2WC040
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2008 [Falcon] (RAID Controller RS2WC040)
 
 pci:v00001000d00000074*
  ID_MODEL_FROM_DATABASE=SAS2108 PCI-Express Fusion-MPT SAS-2 [Liberator]
@@ -1185,106 +1218,106 @@ pci:v00001000d00000079*
  ID_MODEL_FROM_DATABASE=MegaRAID SAS 2108 [Liberator]
 
 pci:v00001000d00000079sv00001000sd00009251*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 9260-4ix
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2108 [Liberator] (MegaRAID SAS 9260-4ix)
 
 pci:v00001000d00000079sv00001000sd00009256*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 9260-8ix
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2108 [Liberator] (MegaRAID SAS 9260-8ix)
 
 pci:v00001000d00000079sv00001000sd00009260*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 9260-4i
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2108 [Liberator] (MegaRAID SAS 9260-4i)
 
 pci:v00001000d00000079sv00001000sd00009261*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 9260-8i
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2108 [Liberator] (MegaRAID SAS 9260-8i)
 
 pci:v00001000d00000079sv00001000sd00009262*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 9262-8i
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2108 [Liberator] (MegaRAID SAS 9262-8i)
 
 pci:v00001000d00000079sv00001000sd00009263*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 9261-8i
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2108 [Liberator] (MegaRAID SAS 9261-8i)
 
 pci:v00001000d00000079sv00001000sd00009264*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 9264-8i
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2108 [Liberator] (MegaRAID SAS 9264-8i)
 
 pci:v00001000d00000079sv00001000sd00009267*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 9260CV-4i
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2108 [Liberator] (MegaRAID SAS 9260CV-4i)
 
 pci:v00001000d00000079sv00001000sd00009268*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 9260CV-8i
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2108 [Liberator] (MegaRAID SAS 9260CV-8i)
 
 pci:v00001000d00000079sv00001000sd00009275*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 9280-8ex
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2108 [Liberator] (MegaRAID SAS 9280-8ex)
 
 pci:v00001000d00000079sv00001000sd00009276*
- ID_MODEL_FROM_DATABASE=MR9260-16i
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2108 [Liberator] (MR9260-16i)
 
 pci:v00001000d00000079sv00001000sd00009280*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 9280-8e
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2108 [Liberator] (MegaRAID SAS 9280-8e)
 
 pci:v00001000d00000079sv00001000sd00009281*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 9281-8E
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2108 [Liberator] (MegaRAID SAS 9281-8E)
 
 pci:v00001000d00000079sv00001000sd00009282*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 9280-4i4e
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2108 [Liberator] (MegaRAID SAS 9280-4i4e)
 
 pci:v00001000d00000079sv00001000sd00009290*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 9280DE-24i4e
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2108 [Liberator] (MegaRAID SAS 9280DE-24i4e)
 
 pci:v00001000d00000079sv00001014sd000003B2*
- ID_MODEL_FROM_DATABASE=ServeRAID M5015 SAS/SATA Controller
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2108 [Liberator] (ServeRAID M5015 SAS/SATA Controller)
 
 pci:v00001000d00000079sv00001014sd000003B3*
- ID_MODEL_FROM_DATABASE=ServeRAID M5025 SAS/SATA Controller
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2108 [Liberator] (ServeRAID M5025 SAS/SATA Controller)
 
 pci:v00001000d00000079sv00001028sd00001F15*
- ID_MODEL_FROM_DATABASE=PERC H800 Adapter
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2108 [Liberator] (PERC H800 Adapter)
 
 pci:v00001000d00000079sv00001028sd00001F16*
- ID_MODEL_FROM_DATABASE=PERC H700 Adapter
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2108 [Liberator] (PERC H700 Adapter)
 
 pci:v00001000d00000079sv00001028sd00001F17*
- ID_MODEL_FROM_DATABASE=PERC H700 Integrated
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2108 [Liberator] (PERC H700 Integrated)
 
 pci:v00001000d00000079sv00001028sd00001F18*
- ID_MODEL_FROM_DATABASE=PERC H700 Modular
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2108 [Liberator] (PERC H700 Modular)
 
 pci:v00001000d00000079sv00001028sd00001F1A*
- ID_MODEL_FROM_DATABASE=PERC H800 Proto Adapter
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2108 [Liberator] (PERC H800 Proto Adapter)
 
 pci:v00001000d00000079sv00001028sd00001F1B*
- ID_MODEL_FROM_DATABASE=PERC H700 Integrated
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2108 [Liberator] (PERC H700 Integrated)
 
 pci:v00001000d00000079sv00001043sd00008480*
- ID_MODEL_FROM_DATABASE=PIKE-2108 16PD
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2108 [Liberator] (PIKE-2108 16PD)
 
 pci:v00001000d00000079sv00001734sd00001176*
- ID_MODEL_FROM_DATABASE=RAID Ctrl SAS 6G 5/6 512MB (D2616)
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2108 [Liberator] (RAID Ctrl SAS 6G 5/6 512MB (D2616))
 
 pci:v00001000d00000079sv00001734sd00001177*
- ID_MODEL_FROM_DATABASE=RAID Ctrl SAS 6G 0/1 (D2607)
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2108 [Liberator] (RAID Ctrl SAS 6G 0/1 (D2607))
 
 pci:v00001000d00000079sv00008086sd00009256*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 9260DE-8i
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2108 [Liberator] (MegaRAID SAS 9260DE-8i)
 
 pci:v00001000d00000079sv00008086sd00009260*
- ID_MODEL_FROM_DATABASE=RAID Controller RS2BL040
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2108 [Liberator] (RAID Controller RS2BL040)
 
 pci:v00001000d00000079sv00008086sd00009261*
- ID_MODEL_FROM_DATABASE=RAID Controller RS2BL080
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2108 [Liberator] (RAID Controller RS2BL080)
 
 pci:v00001000d00000079sv00008086sd00009264*
- ID_MODEL_FROM_DATABASE=Warm Beach (Caster Lite)
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2108 [Liberator] (Warm Beach (Caster Lite))
 
 pci:v00001000d00000079sv00008086sd00009267*
- ID_MODEL_FROM_DATABASE=RAID Controller RS2VB040
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2108 [Liberator] (RAID Controller RS2VB040)
 
 pci:v00001000d00000079sv00008086sd00009268*
- ID_MODEL_FROM_DATABASE=RAID Controller RS2VB080
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 2108 [Liberator] (RAID Controller RS2VB080)
 
 pci:v00001000d0000007C*
  ID_MODEL_FROM_DATABASE=MegaRAID SAS 1078DE
 
 pci:v00001000d0000007Csv00001014sd00000395*
- ID_MODEL_FROM_DATABASE=ServeRAID-AR10is SAS/SATA Controller
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1078DE (ServeRAID-AR10is SAS/SATA Controller)
 
 pci:v00001000d0000007E*
  ID_MODEL_FROM_DATABASE=SSS6200 PCI-Express Flash SSD
@@ -1314,16 +1347,16 @@ pci:v00001000d00000087*
  ID_MODEL_FROM_DATABASE=SAS2308 PCI-Express Fusion-MPT SAS-2
 
 pci:v00001000d00000087sv00001590sd00000044*
- ID_MODEL_FROM_DATABASE=H220i
+ ID_MODEL_FROM_DATABASE=SAS2308 PCI-Express Fusion-MPT SAS-2 (H220i)
 
 pci:v00001000d0000008F*
  ID_MODEL_FROM_DATABASE=53c875J
 
 pci:v00001000d0000008Fsv00001092sd00008000*
- ID_MODEL_FROM_DATABASE=FirePort 40 SCSI Controller
+ ID_MODEL_FROM_DATABASE=53c875J (FirePort 40 SCSI Controller)
 
 pci:v00001000d0000008Fsv00001092sd00008760*
- ID_MODEL_FROM_DATABASE=FirePort 40 Dual SCSI Host Adapter
+ ID_MODEL_FROM_DATABASE=53c875J (FirePort 40 Dual SCSI Host Adapter)
 
 pci:v00001000d00000090*
  ID_MODEL_FROM_DATABASE=SAS3108 PCI-Express Fusion-MPT SAS-3
@@ -1344,151 +1377,151 @@ pci:v00001000d00000097*
  ID_MODEL_FROM_DATABASE=SAS3008 PCI-Express Fusion-MPT SAS-3
 
 pci:v00001000d00000097sv00001028sd00001F45*
- ID_MODEL_FROM_DATABASE=12GB/s HBA internal
+ ID_MODEL_FROM_DATABASE=SAS3008 PCI-Express Fusion-MPT SAS-3 (12GB/s HBA internal)
 
 pci:v00001000d00000097sv00001028sd00001F46*
- ID_MODEL_FROM_DATABASE=12GB/s HBA external
+ ID_MODEL_FROM_DATABASE=SAS3008 PCI-Express Fusion-MPT SAS-3 (12GB/s HBA external)
 
 pci:v00001000d00000407*
  ID_MODEL_FROM_DATABASE=MegaRAID
 
 pci:v00001000d00000407sv00001000sd00000530*
- ID_MODEL_FROM_DATABASE=MegaRAID 530 SCSI 320-0X RAID Controller
+ ID_MODEL_FROM_DATABASE=MegaRAID (530 SCSI 320-0X RAID Controller)
 
 pci:v00001000d00000407sv00001000sd00000531*
- ID_MODEL_FROM_DATABASE=MegaRAID 531 SCSI 320-4X RAID Controller
+ ID_MODEL_FROM_DATABASE=MegaRAID (531 SCSI 320-4X RAID Controller)
 
 pci:v00001000d00000407sv00001000sd00000532*
- ID_MODEL_FROM_DATABASE=MegaRAID 532 SCSI 320-2X RAID Controller
+ ID_MODEL_FROM_DATABASE=MegaRAID (532 SCSI 320-2X RAID Controller)
 
 pci:v00001000d00000407sv00001028sd00000531*
- ID_MODEL_FROM_DATABASE=PowerEdge Expandable RAID Controller 4/QC
+ ID_MODEL_FROM_DATABASE=MegaRAID (PowerEdge Expandable RAID Controller 4/QC)
 
 pci:v00001000d00000407sv00001028sd00000533*
- ID_MODEL_FROM_DATABASE=PowerEdge Expandable RAID Controller 4/QC
+ ID_MODEL_FROM_DATABASE=MegaRAID (PowerEdge Expandable RAID Controller 4/QC)
 
 pci:v00001000d00000407sv00008086sd00000530*
- ID_MODEL_FROM_DATABASE=MegaRAID Intel RAID Controller SRCZCRX
+ ID_MODEL_FROM_DATABASE=MegaRAID (Intel RAID Controller SRCZCRX)
 
 pci:v00001000d00000407sv00008086sd00000532*
- ID_MODEL_FROM_DATABASE=MegaRAID Intel RAID Controller SRCU42X
+ ID_MODEL_FROM_DATABASE=MegaRAID (Intel RAID Controller SRCU42X)
 
 pci:v00001000d00000408*
  ID_MODEL_FROM_DATABASE=MegaRAID
 
 pci:v00001000d00000408sv00001000sd00000001*
- ID_MODEL_FROM_DATABASE=MegaRAID SCSI 320-1E RAID Controller
+ ID_MODEL_FROM_DATABASE=MegaRAID (SCSI 320-1E RAID Controller)
 
 pci:v00001000d00000408sv00001000sd00000002*
- ID_MODEL_FROM_DATABASE=MegaRAID SCSI 320-2E RAID Controller
+ ID_MODEL_FROM_DATABASE=MegaRAID (SCSI 320-2E RAID Controller)
 
 pci:v00001000d00000408sv00001025sd0000004D*
- ID_MODEL_FROM_DATABASE=MegaRAID ACER ROMB-2E RAID Controller
+ ID_MODEL_FROM_DATABASE=MegaRAID (ACER ROMB-2E RAID Controller)
 
 pci:v00001000d00000408sv00001028sd00000001*
- ID_MODEL_FROM_DATABASE=PowerEdge RAID Controller PERC4e/SC
+ ID_MODEL_FROM_DATABASE=MegaRAID (PowerEdge RAID Controller PERC4e/SC)
 
 pci:v00001000d00000408sv00001028sd00000002*
- ID_MODEL_FROM_DATABASE=PowerEdge RAID Controller PERC4e/DC
+ ID_MODEL_FROM_DATABASE=MegaRAID (PowerEdge RAID Controller PERC4e/DC)
 
 pci:v00001000d00000408sv00001028sd00000012*
- ID_MODEL_FROM_DATABASE=PowerEdge RAID Controller RAC4
+ ID_MODEL_FROM_DATABASE=MegaRAID (PowerEdge RAID Controller RAC4)
 
 pci:v00001000d00000408sv00001028sd00000015*
- ID_MODEL_FROM_DATABASE=PowerEdge RAID Controller PERC5
+ ID_MODEL_FROM_DATABASE=MegaRAID (PowerEdge RAID Controller PERC5)
 
 pci:v00001000d00000408sv00001028sd00001F03*
- ID_MODEL_FROM_DATABASE=PowerEdge RAID Controller PERC5
+ ID_MODEL_FROM_DATABASE=MegaRAID (PowerEdge RAID Controller PERC5)
 
 pci:v00001000d00000408sv00001734sd00001065*
- ID_MODEL_FROM_DATABASE=FSC MegaRAID PCI Express ROMB
+ ID_MODEL_FROM_DATABASE=MegaRAID (FSC MegaRAID PCI Express ROMB)
 
 pci:v00001000d00000408sv00008086sd00000002*
- ID_MODEL_FROM_DATABASE=MegaRAID Intel RAID Controller SRCU42E
+ ID_MODEL_FROM_DATABASE=MegaRAID (Intel RAID Controller SRCU42E)
 
 pci:v00001000d00000408sv00008086sd00003449*
- ID_MODEL_FROM_DATABASE=MegaRAID Intel RAID Controller SROMBU
+ ID_MODEL_FROM_DATABASE=MegaRAID (Intel RAID Controller SROMBU)
 
 pci:v00001000d00000409*
  ID_MODEL_FROM_DATABASE=MegaRAID
 
 pci:v00001000d00000409sv00001000sd00003004*
- ID_MODEL_FROM_DATABASE=MegaRAID SATA 300-4X RAID Controller
+ ID_MODEL_FROM_DATABASE=MegaRAID (SATA 300-4X RAID Controller)
 
 pci:v00001000d00000409sv00001000sd00003008*
- ID_MODEL_FROM_DATABASE=MegaRAID SATA 300-8X RAID Controller
+ ID_MODEL_FROM_DATABASE=MegaRAID (SATA 300-8X RAID Controller)
 
 pci:v00001000d00000409sv00008086sd00003008*
- ID_MODEL_FROM_DATABASE=MegaRAID RAID Controller SRCS28X
+ ID_MODEL_FROM_DATABASE=MegaRAID (RAID Controller SRCS28X)
 
 pci:v00001000d00000409sv00008086sd00003431*
- ID_MODEL_FROM_DATABASE=MegaRAID RAID Controller Alief SROMBU42E
+ ID_MODEL_FROM_DATABASE=MegaRAID (RAID Controller Alief SROMBU42E)
 
 pci:v00001000d00000409sv00008086sd00003499*
- ID_MODEL_FROM_DATABASE=MegaRAID RAID Controller Harwich SROMBU42E
+ ID_MODEL_FROM_DATABASE=MegaRAID (RAID Controller Harwich SROMBU42E)
 
 pci:v00001000d00000411*
  ID_MODEL_FROM_DATABASE=MegaRAID SAS 1068
 
 pci:v00001000d00000411sv00001000sd00001001*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 8408E
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1068 (MegaRAID SAS 8408E)
 
 pci:v00001000d00000411sv00001000sd00001002*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 8480E
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1068 (MegaRAID SAS 8480E)
 
 pci:v00001000d00000411sv00001000sd00001003*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 8344ELP
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1068 (MegaRAID SAS 8344ELP)
 
 pci:v00001000d00000411sv00001000sd00001004*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 8308ELP
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1068 (MegaRAID SAS 8308ELP)
 
 pci:v00001000d00000411sv00001000sd00001008*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 84016E
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1068 (MegaRAID SAS 84016E)
 
 pci:v00001000d00000411sv00001000sd0000100C*
- ID_MODEL_FROM_DATABASE=MegaRAID SATA 300-12E
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1068 (MegaRAID SATA 300-12E)
 
 pci:v00001000d00000411sv00001000sd0000100D*
- ID_MODEL_FROM_DATABASE=MegaRAID SATA 300-16E
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1068 (MegaRAID SATA 300-16E)
 
 pci:v00001000d00000411sv00001000sd00002004*
- ID_MODEL_FROM_DATABASE=MegaRAID SATA 300-8ELP
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1068 (MegaRAID SATA 300-8ELP)
 
 pci:v00001000d00000411sv00001000sd00002005*
- ID_MODEL_FROM_DATABASE=MegaRAID SATA 300-4ELP
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1068 (MegaRAID SATA 300-4ELP)
 
 pci:v00001000d00000411sv00001033sd00008287*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS PCI Express ROMB
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1068 (MegaRAID SAS PCI Express ROMB)
 
 pci:v00001000d00000411sv00001054sd00003016*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS RoMB Server
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1068 (MegaRAID SAS RoMB Server)
 
 pci:v00001000d00000411sv00001734sd00001081*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS PCI Express ROMB
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1068 (MegaRAID SAS PCI Express ROMB)
 
 pci:v00001000d00000411sv00001734sd000010A3*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS PCI Express ROMB
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1068 (MegaRAID SAS PCI Express ROMB)
 
 pci:v00001000d00000411sv00008086sd00001001*
- ID_MODEL_FROM_DATABASE=RAID Controller SRCSAS18E
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1068 (RAID Controller SRCSAS18E)
 
 pci:v00001000d00000411sv00008086sd00001003*
- ID_MODEL_FROM_DATABASE=RAID Controller SRCSAS144E
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1068 (RAID Controller SRCSAS144E)
 
 pci:v00001000d00000411sv00008086sd00003500*
- ID_MODEL_FROM_DATABASE=SROMBSAS18E RAID Controller
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1068 (SROMBSAS18E RAID Controller)
 
 pci:v00001000d00000411sv00008086sd00003501*
- ID_MODEL_FROM_DATABASE=SROMBSAS18E RAID Controller
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1068 (SROMBSAS18E RAID Controller)
 
 pci:v00001000d00000411sv00008086sd00003504*
- ID_MODEL_FROM_DATABASE=SROMBSAS18E RAID Controller
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1068 (SROMBSAS18E RAID Controller)
 
 pci:v00001000d00000413*
  ID_MODEL_FROM_DATABASE=MegaRAID SAS 1068 [Verde ZCR]
 
 pci:v00001000d00000413sv00001000sd00001005*
- ID_MODEL_FROM_DATABASE=MegaRAID SAS 8300XLP
+ ID_MODEL_FROM_DATABASE=MegaRAID SAS 1068 [Verde ZCR] (MegaRAID SAS 8300XLP)
 
 pci:v00001000d00000621*
  ID_MODEL_FROM_DATABASE=FC909 Fibre Channel Adapter
@@ -1497,7 +1530,7 @@ pci:v00001000d00000622*
  ID_MODEL_FROM_DATABASE=FC929 Fibre Channel Adapter
 
 pci:v00001000d00000622sv00001000sd00001020*
- ID_MODEL_FROM_DATABASE=44929 O Dual Fibre Channel card
+ ID_MODEL_FROM_DATABASE=FC929 Fibre Channel Adapter (44929 O Dual Fibre Channel card)
 
 pci:v00001000d00000623*
  ID_MODEL_FROM_DATABASE=FC929 LAN
@@ -1512,7 +1545,7 @@ pci:v00001000d00000626*
  ID_MODEL_FROM_DATABASE=FC929X Fibre Channel Adapter
 
 pci:v00001000d00000626sv00001000sd00001010*
- ID_MODEL_FROM_DATABASE=7202-XP-LC Dual Fibre Channel card
+ ID_MODEL_FROM_DATABASE=FC929X Fibre Channel Adapter (7202-XP-LC Dual Fibre Channel card)
 
 pci:v00001000d00000627*
  ID_MODEL_FROM_DATABASE=FC929X LAN
@@ -1539,7 +1572,7 @@ pci:v00001000d00000702*
  ID_MODEL_FROM_DATABASE=Yellowfin G-NIC gigabit ethernet
 
 pci:v00001000d00000702sv00001318sd00000000*
- ID_MODEL_FROM_DATABASE=PEI100X
+ ID_MODEL_FROM_DATABASE=Yellowfin G-NIC gigabit ethernet (PEI100X)
 
 pci:v00001000d00000804*
  ID_MODEL_FROM_DATABASE=SA2010
@@ -1563,40 +1596,43 @@ pci:v00001000d00001960*
  ID_MODEL_FROM_DATABASE=MegaRAID
 
 pci:v00001000d00001960sv00001000sd00000518*
- ID_MODEL_FROM_DATABASE=MegaRAID 518 SCSI 320-2 Controller
+ ID_MODEL_FROM_DATABASE=MegaRAID (518 SCSI 320-2 Controller)
 
 pci:v00001000d00001960sv00001000sd00000520*
- ID_MODEL_FROM_DATABASE=MegaRAID 520 SCSI 320-1 Controller
+ ID_MODEL_FROM_DATABASE=MegaRAID (520 SCSI 320-1 Controller)
 
 pci:v00001000d00001960sv00001000sd00000522*
- ID_MODEL_FROM_DATABASE=MegaRAID 522 i4 133 RAID Controller
+ ID_MODEL_FROM_DATABASE=MegaRAID (522 i4 133 RAID Controller)
 
 pci:v00001000d00001960sv00001000sd00000523*
- ID_MODEL_FROM_DATABASE=MegaRAID SATA 150-6 RAID Controller
+ ID_MODEL_FROM_DATABASE=MegaRAID (SATA 150-6 RAID Controller)
 
 pci:v00001000d00001960sv00001000sd00004523*
- ID_MODEL_FROM_DATABASE=MegaRAID SATA 150-4 RAID Controller
+ ID_MODEL_FROM_DATABASE=MegaRAID (SATA 150-4 RAID Controller)
 
 pci:v00001000d00001960sv00001000sd0000A520*
- ID_MODEL_FROM_DATABASE=MegaRAID ZCR SCSI 320-0 Controller
+ ID_MODEL_FROM_DATABASE=MegaRAID (ZCR SCSI 320-0 Controller)
 
 pci:v00001000d00001960sv00001028sd00000518*
- ID_MODEL_FROM_DATABASE=MegaRAID 518 DELL PERC 4/DC RAID Controller
+ ID_MODEL_FROM_DATABASE=MegaRAID (518 DELL PERC 4/DC RAID Controller)
 
 pci:v00001000d00001960sv00001028sd00000520*
- ID_MODEL_FROM_DATABASE=MegaRAID 520 DELL PERC 4/SC RAID Controller
+ ID_MODEL_FROM_DATABASE=MegaRAID (520 DELL PERC 4/SC RAID Controller)
 
 pci:v00001000d00001960sv00001028sd00000531*
- ID_MODEL_FROM_DATABASE=PowerEdge Expandable RAID Controller 4/QC
+ ID_MODEL_FROM_DATABASE=MegaRAID (PowerEdge Expandable RAID Controller 4/QC)
 
 pci:v00001000d00001960sv00001028sd00000533*
- ID_MODEL_FROM_DATABASE=PowerEdge Expandable RAID Controller 4/QC
+ ID_MODEL_FROM_DATABASE=MegaRAID (PowerEdge Expandable RAID Controller 4/QC)
 
 pci:v00001000d00001960sv00008086sd00000520*
- ID_MODEL_FROM_DATABASE=MegaRAID RAID Controller SRCU41L
+ ID_MODEL_FROM_DATABASE=MegaRAID (RAID Controller SRCU41L)
 
 pci:v00001000d00001960sv00008086sd00000523*
- ID_MODEL_FROM_DATABASE=MegaRAID RAID Controller SRCS16
+ ID_MODEL_FROM_DATABASE=MegaRAID (RAID Controller SRCS16)
+
+pci:v00001000d00003050*
+ ID_MODEL_FROM_DATABASE=SAS2008 PCI-Express Fusion-MPT SAS-2
 
 pci:v00001000d00006001*
  ID_MODEL_FROM_DATABASE=DX1 Multiformat Broadcast HD/SD Encoder/Decoder
@@ -1646,26 +1682,29 @@ pci:v00001002d00001306*
 pci:v00001002d00001307*
  ID_MODEL_FROM_DATABASE=Kaveri
 
+pci:v00001002d00001308*
+ ID_MODEL_FROM_DATABASE=Kaveri HDMI/DP Audio Controller
+
 pci:v00001002d00001309*
- ID_MODEL_FROM_DATABASE=Kaveri
+ ID_MODEL_FROM_DATABASE=Kaveri [Radeon R6/R7 Graphics]
 
 pci:v00001002d0000130A*
- ID_MODEL_FROM_DATABASE=Kaveri
+ ID_MODEL_FROM_DATABASE=Kaveri [Radeon R6 Graphics]
 
 pci:v00001002d0000130B*
- ID_MODEL_FROM_DATABASE=Kaveri
+ ID_MODEL_FROM_DATABASE=Kaveri [Radeon R4 Graphics]
 
 pci:v00001002d0000130C*
- ID_MODEL_FROM_DATABASE=Kaveri
+ ID_MODEL_FROM_DATABASE=Kaveri [Radeon R7 Graphics]
 
 pci:v00001002d0000130D*
- ID_MODEL_FROM_DATABASE=Kaveri
+ ID_MODEL_FROM_DATABASE=Kaveri [Radeon R6 Graphics]
 
 pci:v00001002d0000130E*
- ID_MODEL_FROM_DATABASE=Kaveri
+ ID_MODEL_FROM_DATABASE=Kaveri [Radeon R5 Graphics]
 
 pci:v00001002d0000130F*
- ID_MODEL_FROM_DATABASE=Kaveri
+ ID_MODEL_FROM_DATABASE=Kaveri [Radeon R7 Graphics]
 
 pci:v00001002d00001310*
  ID_MODEL_FROM_DATABASE=Kaveri
@@ -1673,38 +1712,50 @@ pci:v00001002d00001310*
 pci:v00001002d00001311*
  ID_MODEL_FROM_DATABASE=Kaveri
 
-pci:v00001002d00001313*
+pci:v00001002d00001312*
  ID_MODEL_FROM_DATABASE=Kaveri
 
+pci:v00001002d00001313*
+ ID_MODEL_FROM_DATABASE=Kaveri [Radeon R7 Graphics]
+
 pci:v00001002d00001314*
  ID_MODEL_FROM_DATABASE=Wrestler HDMI Audio
 
 pci:v00001002d00001314sv0000174Bsd00001001*
- ID_MODEL_FROM_DATABASE=PURE Fusion Mini
+ ID_MODEL_FROM_DATABASE=Wrestler HDMI Audio (PURE Fusion Mini)
 
 pci:v00001002d00001315*
- ID_MODEL_FROM_DATABASE=Kaveri
+ ID_MODEL_FROM_DATABASE=Kaveri [Radeon R5 Graphics]
 
 pci:v00001002d00001316*
+ ID_MODEL_FROM_DATABASE=Kaveri [Radeon R5 Graphics]
+
+pci:v00001002d00001317*
  ID_MODEL_FROM_DATABASE=Kaveri
 
+pci:v00001002d00001318*
+ ID_MODEL_FROM_DATABASE=Kaveri [Radeon R5 Graphics]
+
 pci:v00001002d0000131B*
- ID_MODEL_FROM_DATABASE=Kaveri
+ ID_MODEL_FROM_DATABASE=Kaveri [Radeon R4 Graphics]
 
 pci:v00001002d0000131C*
- ID_MODEL_FROM_DATABASE=Kaveri
+ ID_MODEL_FROM_DATABASE=Kaveri [Radeon R7 Graphics]
+
+pci:v00001002d0000131D*
+ ID_MODEL_FROM_DATABASE=Kaveri [Radeon R6 Graphics]
 
 pci:v00001002d00001714*
  ID_MODEL_FROM_DATABASE=BeaverCreek HDMI Audio [Radeon HD 6500D and 6400G-6600G series]
 
 pci:v00001002d00001714sv0000103Csd0000168B*
- ID_MODEL_FROM_DATABASE=ProBook 4535s
+ ID_MODEL_FROM_DATABASE=BeaverCreek HDMI Audio [Radeon HD 6500D and 6400G-6600G series] (ProBook 4535s)
 
 pci:v00001002d00003150*
  ID_MODEL_FROM_DATABASE=RV380/M24 [Mobility Radeon X600]
 
 pci:v00001002d00003150sv0000103Csd00000934*
- ID_MODEL_FROM_DATABASE=nx8220
+ ID_MODEL_FROM_DATABASE=RV380/M24 [Mobility Radeon X600] (nx8220)
 
 pci:v00001002d00003151*
  ID_MODEL_FROM_DATABASE=RV380 GL [FireMV 2400]
@@ -1752,73 +1803,73 @@ pci:v00001002d00004150*
  ID_MODEL_FROM_DATABASE=RV350 [Radeon 9550/9600/X1050 Series]
 
 pci:v00001002d00004150sv00001002sd00000002*
- ID_MODEL_FROM_DATABASE=R9600 Pro primary (Asus OEM for HP)
+ ID_MODEL_FROM_DATABASE=RV350 [Radeon 9550/9600/X1050 Series] (R9600 Pro primary (Asus OEM for HP))
 
 pci:v00001002d00004150sv00001002sd00000003*
- ID_MODEL_FROM_DATABASE=R9600 Pro secondary (Asus OEM for HP)
+ ID_MODEL_FROM_DATABASE=RV350 [Radeon 9550/9600/X1050 Series] (R9600 Pro secondary (Asus OEM for HP))
 
 pci:v00001002d00004150sv00001002sd00004722*
- ID_MODEL_FROM_DATABASE=All-in-Wonder 2006 AGP Edition
+ ID_MODEL_FROM_DATABASE=RV350 [Radeon 9550/9600/X1050 Series] (All-in-Wonder 2006 AGP Edition)
 
 pci:v00001002d00004150sv00001458sd00004024*
- ID_MODEL_FROM_DATABASE=GV-R96128D
+ ID_MODEL_FROM_DATABASE=RV350 [Radeon 9550/9600/X1050 Series] (GV-R96128D)
 
 pci:v00001002d00004150sv0000148Csd00002064*
- ID_MODEL_FROM_DATABASE=R96A-C3N
+ ID_MODEL_FROM_DATABASE=RV350 [Radeon 9550/9600/X1050 Series] (R96A-C3N)
 
 pci:v00001002d00004150sv0000148Csd00002066*
- ID_MODEL_FROM_DATABASE=R96A-C3N
+ ID_MODEL_FROM_DATABASE=RV350 [Radeon 9550/9600/X1050 Series] (R96A-C3N)
 
 pci:v00001002d00004150sv0000174Bsd00007C19*
- ID_MODEL_FROM_DATABASE=Atlantis Radeon 9600 Pro
+ ID_MODEL_FROM_DATABASE=RV350 [Radeon 9550/9600/X1050 Series] (Atlantis Radeon 9600 Pro)
 
 pci:v00001002d00004150sv0000174Bsd00007C29*
- ID_MODEL_FROM_DATABASE=GC-R9600PRO
+ ID_MODEL_FROM_DATABASE=RV350 [Radeon 9550/9600/X1050 Series] (GC-R9600PRO)
 
 pci:v00001002d00004150sv000017EEsd00002002*
- ID_MODEL_FROM_DATABASE=Radeon 9600 256Mb Primary
+ ID_MODEL_FROM_DATABASE=RV350 [Radeon 9550/9600/X1050 Series] (Radeon 9600 256Mb Primary)
 
 pci:v00001002d00004150sv000018BCsd00000101*
- ID_MODEL_FROM_DATABASE=GC-R9600PRO (Primary)
+ ID_MODEL_FROM_DATABASE=RV350 [Radeon 9550/9600/X1050 Series] (GC-R9600PRO (Primary))
 
 pci:v00001002d00004151*
  ID_MODEL_FROM_DATABASE=RV350 [Radeon 9600 Series]
 
 pci:v00001002d00004151sv00001043sd0000C004*
- ID_MODEL_FROM_DATABASE=A9600SE
+ ID_MODEL_FROM_DATABASE=RV350 [Radeon 9600 Series] (A9600SE)
 
 pci:v00001002d00004152*
  ID_MODEL_FROM_DATABASE=RV360 [Radeon 9600/X1050 Series]
 
 pci:v00001002d00004152sv00001002sd00000002*
- ID_MODEL_FROM_DATABASE=Radeon 9600XT
+ ID_MODEL_FROM_DATABASE=RV360 [Radeon 9600/X1050 Series] (Radeon 9600XT)
 
 pci:v00001002d00004152sv00001002sd00004772*
- ID_MODEL_FROM_DATABASE=All-in-Wonder 9600 XT
+ ID_MODEL_FROM_DATABASE=RV360 [Radeon 9600/X1050 Series] (All-in-Wonder 9600 XT)
 
 pci:v00001002d00004152sv00001043sd0000C002*
- ID_MODEL_FROM_DATABASE=Radeon 9600 XT TVD
+ ID_MODEL_FROM_DATABASE=RV360 [Radeon 9600/X1050 Series] (Radeon 9600 XT TVD)
 
 pci:v00001002d00004152sv00001043sd0000C01A*
- ID_MODEL_FROM_DATABASE=A9600XT/TD
+ ID_MODEL_FROM_DATABASE=RV360 [Radeon 9600/X1050 Series] (A9600XT/TD)
 
 pci:v00001002d00004152sv00001462sd00009510*
- ID_MODEL_FROM_DATABASE=RX9600XT (MS-8951)
+ ID_MODEL_FROM_DATABASE=RV360 [Radeon 9600/X1050 Series] (RX9600XT (MS-8951))
 
 pci:v00001002d00004152sv0000174Bsd00007C29*
- ID_MODEL_FROM_DATABASE=Radeon 9600XT
+ ID_MODEL_FROM_DATABASE=RV360 [Radeon 9600/X1050 Series] (Radeon 9600XT)
 
 pci:v00001002d00004152sv00001787sd00004002*
- ID_MODEL_FROM_DATABASE=Radeon 9600 XT
+ ID_MODEL_FROM_DATABASE=RV360 [Radeon 9600/X1050 Series] (Radeon 9600 XT)
 
 pci:v00001002d00004153*
  ID_MODEL_FROM_DATABASE=RV350 [Radeon 9550]
 
 pci:v00001002d00004153sv00001043sd0000010C*
- ID_MODEL_FROM_DATABASE=A9550GE/TD
+ ID_MODEL_FROM_DATABASE=RV350 [Radeon 9550] (A9550GE/TD)
 
 pci:v00001002d00004153sv00001462sd0000932C*
- ID_MODEL_FROM_DATABASE=RX9550SE-TD128 (MS-8932)
+ ID_MODEL_FROM_DATABASE=RV350 [Radeon 9550] (RX9550SE-TD128 (MS-8932))
 
 pci:v00001002d00004154*
  ID_MODEL_FROM_DATABASE=RV350 GL [FireGL T2]
@@ -1848,64 +1899,64 @@ pci:v00001002d00004170*
  ID_MODEL_FROM_DATABASE=RV350 [Radeon 9550/9600/X1050 Series] (Secondary)
 
 pci:v00001002d00004170sv00001002sd00000003*
- ID_MODEL_FROM_DATABASE=R9600 Pro secondary (Asus OEM for HP)
+ ID_MODEL_FROM_DATABASE=RV350 [Radeon 9550/9600/X1050 Series] (Secondary) (R9600 Pro secondary (Asus OEM for HP))
 
 pci:v00001002d00004170sv00001002sd00004723*
- ID_MODEL_FROM_DATABASE=All-in-Wonder 2006 AGP Edition (Secondary)
+ ID_MODEL_FROM_DATABASE=RV350 [Radeon 9550/9600/X1050 Series] (Secondary) (All-in-Wonder 2006 AGP Edition (Secondary))
 
 pci:v00001002d00004170sv00001458sd00004025*
- ID_MODEL_FROM_DATABASE=GV-R96128D (Secondary)
+ ID_MODEL_FROM_DATABASE=RV350 [Radeon 9550/9600/X1050 Series] (Secondary) (GV-R96128D (Secondary))
 
 pci:v00001002d00004170sv0000148Csd00002067*
- ID_MODEL_FROM_DATABASE=R96A-C3N (Secondary)
+ ID_MODEL_FROM_DATABASE=RV350 [Radeon 9550/9600/X1050 Series] (Secondary) (R96A-C3N (Secondary))
 
 pci:v00001002d00004170sv0000174Bsd00007C28*
- ID_MODEL_FROM_DATABASE=GC-R9600PRO (Secondary)
+ ID_MODEL_FROM_DATABASE=RV350 [Radeon 9550/9600/X1050 Series] (Secondary) (GC-R9600PRO (Secondary))
 
 pci:v00001002d00004170sv000017EEsd00002003*
- ID_MODEL_FROM_DATABASE=Radeon 9600 256Mb (Secondary)
+ ID_MODEL_FROM_DATABASE=RV350 [Radeon 9550/9600/X1050 Series] (Secondary) (Radeon 9600 256Mb (Secondary))
 
 pci:v00001002d00004170sv000018BCsd00000100*
- ID_MODEL_FROM_DATABASE=GC-R9600PRO (Secondary)
+ ID_MODEL_FROM_DATABASE=RV350 [Radeon 9550/9600/X1050 Series] (Secondary) (GC-R9600PRO (Secondary))
 
 pci:v00001002d00004171*
  ID_MODEL_FROM_DATABASE=RV350 [Radeon 9600] (Secondary)
 
 pci:v00001002d00004171sv00001043sd0000C005*
- ID_MODEL_FROM_DATABASE=A9600SE (Secondary)
+ ID_MODEL_FROM_DATABASE=RV350 [Radeon 9600] (Secondary) (A9600SE (Secondary))
 
 pci:v00001002d00004172*
  ID_MODEL_FROM_DATABASE=RV350 [Radeon 9600/X1050 Series] (Secondary)
 
 pci:v00001002d00004172sv00001002sd00000003*
- ID_MODEL_FROM_DATABASE=Radeon 9600XT (Secondary)
+ ID_MODEL_FROM_DATABASE=RV350 [Radeon 9600/X1050 Series] (Secondary) (Radeon 9600XT (Secondary))
 
 pci:v00001002d00004172sv00001002sd00004773*
- ID_MODEL_FROM_DATABASE=All-in-Wonder 9600 XT (Secondary)
+ ID_MODEL_FROM_DATABASE=RV350 [Radeon 9600/X1050 Series] (Secondary) (All-in-Wonder 9600 XT (Secondary))
 
 pci:v00001002d00004172sv00001043sd0000C003*
- ID_MODEL_FROM_DATABASE=A9600XT (Secondary)
+ ID_MODEL_FROM_DATABASE=RV350 [Radeon 9600/X1050 Series] (Secondary) (A9600XT (Secondary))
 
 pci:v00001002d00004172sv00001043sd0000C01B*
- ID_MODEL_FROM_DATABASE=A9600XT/TD (Secondary)
+ ID_MODEL_FROM_DATABASE=RV350 [Radeon 9600/X1050 Series] (Secondary) (A9600XT/TD (Secondary))
 
 pci:v00001002d00004172sv0000174Bsd00007C28*
- ID_MODEL_FROM_DATABASE=Radeon 9600XT (Secondary)
+ ID_MODEL_FROM_DATABASE=RV350 [Radeon 9600/X1050 Series] (Secondary) (Radeon 9600XT (Secondary))
 
 pci:v00001002d00004172sv00001787sd00004003*
- ID_MODEL_FROM_DATABASE=Radeon 9600 XT (Secondary)
+ ID_MODEL_FROM_DATABASE=RV350 [Radeon 9600/X1050 Series] (Secondary) (Radeon 9600 XT (Secondary))
 
 pci:v00001002d00004173*
  ID_MODEL_FROM_DATABASE=RV350 [Radeon 9550] (Secondary)
 
 pci:v00001002d00004173sv00001043sd0000010D*
- ID_MODEL_FROM_DATABASE=A9550GE/TD (Secondary)
+ ID_MODEL_FROM_DATABASE=RV350 [Radeon 9550] (Secondary) (A9550GE/TD (Secondary))
 
 pci:v00001002d00004242*
  ID_MODEL_FROM_DATABASE=R200 [All-In-Wonder Radeon 8500 DV]
 
 pci:v00001002d00004242sv00001002sd000002AA*
- ID_MODEL_FROM_DATABASE=Radeon 8500 AIW DV Edition
+ ID_MODEL_FROM_DATABASE=R200 [All-In-Wonder Radeon 8500 DV] (Radeon 8500 AIW DV Edition)
 
 pci:v00001002d00004243*
  ID_MODEL_FROM_DATABASE=R200 PCI Bridge [All-in-Wonder Radeon 8500DV]
@@ -1914,22 +1965,22 @@ pci:v00001002d00004336*
  ID_MODEL_FROM_DATABASE=RS100 [Radeon IGP 320M]
 
 pci:v00001002d00004336sv00001002sd00004336*
- ID_MODEL_FROM_DATABASE=Pavilion ze4300 ATI Radeon Mobility U1 (IGP 320 M)
+ ID_MODEL_FROM_DATABASE=RS100 [Radeon IGP 320M] (Pavilion ze4300 ATI Radeon Mobility U1 (IGP 320 M))
 
 pci:v00001002d00004336sv0000103Csd00000024*
- ID_MODEL_FROM_DATABASE=Pavilion ze4400 builtin Video
+ ID_MODEL_FROM_DATABASE=RS100 [Radeon IGP 320M] (Pavilion ze4400 builtin Video)
 
 pci:v00001002d00004336sv0000161Fsd00002029*
- ID_MODEL_FROM_DATABASE=eMachines M5312 builtin Video
+ ID_MODEL_FROM_DATABASE=RS100 [Radeon IGP 320M] (eMachines M5312 builtin Video)
 
 pci:v00001002d00004337*
  ID_MODEL_FROM_DATABASE=RS200M [Radeon IGP 330M/340M/345M/350M]
 
 pci:v00001002d00004337sv00001014sd0000053A*
- ID_MODEL_FROM_DATABASE=ThinkPad R40e
+ ID_MODEL_FROM_DATABASE=RS200M [Radeon IGP 330M/340M/345M/350M] (ThinkPad R40e)
 
 pci:v00001002d00004337sv0000103Csd00000850*
- ID_MODEL_FROM_DATABASE=Radeon IGP 345M
+ ID_MODEL_FROM_DATABASE=RS200M [Radeon IGP 330M/340M/345M/350M] (Radeon IGP 345M)
 
 pci:v00001002d00004341*
  ID_MODEL_FROM_DATABASE=IXP150 AC'97 Audio Controller
@@ -1974,160 +2025,160 @@ pci:v00001002d00004370*
  ID_MODEL_FROM_DATABASE=IXP SB400 AC'97 Audio Controller
 
 pci:v00001002d00004370sv00001025sd00000079*
- ID_MODEL_FROM_DATABASE=Aspire 5024WLMMi
+ ID_MODEL_FROM_DATABASE=IXP SB400 AC'97 Audio Controller (Aspire 5024WLMMi)
 
 pci:v00001002d00004370sv00001025sd00000091*
- ID_MODEL_FROM_DATABASE=Aspire 5032WXMi
+ ID_MODEL_FROM_DATABASE=IXP SB400 AC'97 Audio Controller (Aspire 5032WXMi)
 
 pci:v00001002d00004370sv0000103Csd00002A05*
- ID_MODEL_FROM_DATABASE=Pavilion t3030.de Desktop PC
+ ID_MODEL_FROM_DATABASE=IXP SB400 AC'97 Audio Controller (Pavilion t3030.de Desktop PC)
 
 pci:v00001002d00004370sv0000103Csd0000308B*
- ID_MODEL_FROM_DATABASE=MX6125
+ ID_MODEL_FROM_DATABASE=IXP SB400 AC'97 Audio Controller (MX6125)
 
 pci:v00001002d00004370sv0000105Bsd00000C81*
- ID_MODEL_FROM_DATABASE=Realtek ALC 653
+ ID_MODEL_FROM_DATABASE=IXP SB400 AC'97 Audio Controller (Realtek ALC 653)
 
 pci:v00001002d00004370sv0000107Bsd00000300*
- ID_MODEL_FROM_DATABASE=MX6421
+ ID_MODEL_FROM_DATABASE=IXP SB400 AC'97 Audio Controller (MX6421)
 
 pci:v00001002d00004370sv00001462sd00000131*
- ID_MODEL_FROM_DATABASE=MS-1013 Notebook
+ ID_MODEL_FROM_DATABASE=IXP SB400 AC'97 Audio Controller (MS-1013 Notebook)
 
 pci:v00001002d00004371*
  ID_MODEL_FROM_DATABASE=IXP SB4x0 PCI-PCI Bridge
 
 pci:v00001002d00004371sv0000103Csd0000308B*
- ID_MODEL_FROM_DATABASE=MX6125
+ ID_MODEL_FROM_DATABASE=IXP SB4x0 PCI-PCI Bridge (MX6125)
 
 pci:v00001002d00004371sv00001462sd00007217*
- ID_MODEL_FROM_DATABASE=Aspire L250
+ ID_MODEL_FROM_DATABASE=IXP SB4x0 PCI-PCI Bridge (Aspire L250)
 
 pci:v00001002d00004372*
  ID_MODEL_FROM_DATABASE=IXP SB4x0 SMBus Controller
 
 pci:v00001002d00004372sv00001025sd00000080*
- ID_MODEL_FROM_DATABASE=Aspire 5024WLMMi
+ ID_MODEL_FROM_DATABASE=IXP SB4x0 SMBus Controller (Aspire 5024WLMMi)
 
 pci:v00001002d00004372sv0000103Csd00002A20*
- ID_MODEL_FROM_DATABASE=Pavilion t3030.de Desktop PC
+ ID_MODEL_FROM_DATABASE=IXP SB4x0 SMBus Controller (Pavilion t3030.de Desktop PC)
 
 pci:v00001002d00004372sv0000103Csd0000308B*
- ID_MODEL_FROM_DATABASE=MX6125
+ ID_MODEL_FROM_DATABASE=IXP SB4x0 SMBus Controller (MX6125)
 
 pci:v00001002d00004372sv00001462sd00000131*
- ID_MODEL_FROM_DATABASE=MS-1013 Notebook
+ ID_MODEL_FROM_DATABASE=IXP SB4x0 SMBus Controller (MS-1013 Notebook)
 
 pci:v00001002d00004372sv00001462sd00007217*
- ID_MODEL_FROM_DATABASE=Aspire L250
+ ID_MODEL_FROM_DATABASE=IXP SB4x0 SMBus Controller (Aspire L250)
 
 pci:v00001002d00004373*
  ID_MODEL_FROM_DATABASE=IXP SB4x0 USB2 Host Controller
 
 pci:v00001002d00004373sv00001025sd00000080*
- ID_MODEL_FROM_DATABASE=Aspire 5024WLMMi
+ ID_MODEL_FROM_DATABASE=IXP SB4x0 USB2 Host Controller (Aspire 5024WLMMi)
 
 pci:v00001002d00004373sv0000103Csd00002A20*
- ID_MODEL_FROM_DATABASE=Pavilion t3030.de Desktop PC
+ ID_MODEL_FROM_DATABASE=IXP SB4x0 USB2 Host Controller (Pavilion t3030.de Desktop PC)
 
 pci:v00001002d00004373sv0000103Csd0000308B*
- ID_MODEL_FROM_DATABASE=MX6125
+ ID_MODEL_FROM_DATABASE=IXP SB4x0 USB2 Host Controller (MX6125)
 
 pci:v00001002d00004373sv00001462sd00007217*
- ID_MODEL_FROM_DATABASE=Aspire L250
+ ID_MODEL_FROM_DATABASE=IXP SB4x0 USB2 Host Controller (Aspire L250)
 
 pci:v00001002d00004374*
  ID_MODEL_FROM_DATABASE=IXP SB4x0 USB Host Controller
 
 pci:v00001002d00004374sv0000103Csd00002A20*
- ID_MODEL_FROM_DATABASE=Pavilion t3030.de Desktop PC
+ ID_MODEL_FROM_DATABASE=IXP SB4x0 USB Host Controller (Pavilion t3030.de Desktop PC)
 
 pci:v00001002d00004374sv0000103Csd0000308B*
- ID_MODEL_FROM_DATABASE=MX6125
+ ID_MODEL_FROM_DATABASE=IXP SB4x0 USB Host Controller (MX6125)
 
 pci:v00001002d00004374sv00001462sd00007217*
- ID_MODEL_FROM_DATABASE=Aspire L250
+ ID_MODEL_FROM_DATABASE=IXP SB4x0 USB Host Controller (Aspire L250)
 
 pci:v00001002d00004375*
  ID_MODEL_FROM_DATABASE=IXP SB4x0 USB Host Controller
 
 pci:v00001002d00004375sv00001025sd00000080*
- ID_MODEL_FROM_DATABASE=Aspire 5024WLMMi
+ ID_MODEL_FROM_DATABASE=IXP SB4x0 USB Host Controller (Aspire 5024WLMMi)
 
 pci:v00001002d00004375sv0000103Csd00002A20*
- ID_MODEL_FROM_DATABASE=Pavilion t3030.de Desktop PC
+ ID_MODEL_FROM_DATABASE=IXP SB4x0 USB Host Controller (Pavilion t3030.de Desktop PC)
 
 pci:v00001002d00004375sv0000103Csd0000308B*
- ID_MODEL_FROM_DATABASE=MX6125
+ ID_MODEL_FROM_DATABASE=IXP SB4x0 USB Host Controller (MX6125)
 
 pci:v00001002d00004375sv00001462sd00007217*
- ID_MODEL_FROM_DATABASE=Aspire L250
+ ID_MODEL_FROM_DATABASE=IXP SB4x0 USB Host Controller (Aspire L250)
 
 pci:v00001002d00004376*
  ID_MODEL_FROM_DATABASE=IXP SB4x0 IDE Controller
 
 pci:v00001002d00004376sv00001025sd00000080*
- ID_MODEL_FROM_DATABASE=Aspire 5024WLMMi
+ ID_MODEL_FROM_DATABASE=IXP SB4x0 IDE Controller (Aspire 5024WLMMi)
 
 pci:v00001002d00004376sv0000103Csd00002A20*
- ID_MODEL_FROM_DATABASE=Pavilion t3030.de Desktop PC
+ ID_MODEL_FROM_DATABASE=IXP SB4x0 IDE Controller (Pavilion t3030.de Desktop PC)
 
 pci:v00001002d00004376sv0000103Csd0000308B*
- ID_MODEL_FROM_DATABASE=MX6125
+ ID_MODEL_FROM_DATABASE=IXP SB4x0 IDE Controller (MX6125)
 
 pci:v00001002d00004376sv00001462sd00000131*
- ID_MODEL_FROM_DATABASE=MS-1013 Notebook
+ ID_MODEL_FROM_DATABASE=IXP SB4x0 IDE Controller (MS-1013 Notebook)
 
 pci:v00001002d00004376sv00001462sd00007217*
- ID_MODEL_FROM_DATABASE=Aspire L250
+ ID_MODEL_FROM_DATABASE=IXP SB4x0 IDE Controller (Aspire L250)
 
 pci:v00001002d00004377*
  ID_MODEL_FROM_DATABASE=IXP SB4x0 PCI-ISA Bridge
 
 pci:v00001002d00004377sv00001025sd00000080*
- ID_MODEL_FROM_DATABASE=Aspire 5024WLMi
+ ID_MODEL_FROM_DATABASE=IXP SB4x0 PCI-ISA Bridge (Aspire 5024WLMi)
 
 pci:v00001002d00004377sv0000103Csd00002A20*
- ID_MODEL_FROM_DATABASE=Pavilion t3030.de Desktop PC
+ ID_MODEL_FROM_DATABASE=IXP SB4x0 PCI-ISA Bridge (Pavilion t3030.de Desktop PC)
 
 pci:v00001002d00004377sv0000103Csd0000308B*
- ID_MODEL_FROM_DATABASE=MX6125
+ ID_MODEL_FROM_DATABASE=IXP SB4x0 PCI-ISA Bridge (MX6125)
 
 pci:v00001002d00004377sv00001462sd00007217*
- ID_MODEL_FROM_DATABASE=Aspire L250
+ ID_MODEL_FROM_DATABASE=IXP SB4x0 PCI-ISA Bridge (Aspire L250)
 
 pci:v00001002d00004378*
  ID_MODEL_FROM_DATABASE=IXP SB400 AC'97 Modem Controller
 
 pci:v00001002d00004378sv00001025sd00000080*
- ID_MODEL_FROM_DATABASE=Aspire 5024WLMMi
+ ID_MODEL_FROM_DATABASE=IXP SB400 AC'97 Modem Controller (Aspire 5024WLMMi)
 
 pci:v00001002d00004378sv0000103Csd0000308B*
- ID_MODEL_FROM_DATABASE=MX6125
+ ID_MODEL_FROM_DATABASE=IXP SB400 AC'97 Modem Controller (MX6125)
 
 pci:v00001002d00004378sv00001462sd00000131*
- ID_MODEL_FROM_DATABASE=MS-1013 Notebook
+ ID_MODEL_FROM_DATABASE=IXP SB400 AC'97 Modem Controller (MS-1013 Notebook)
 
 pci:v00001002d00004379*
  ID_MODEL_FROM_DATABASE=IXP SB4x0 Serial ATA Controller
 
 pci:v00001002d00004379sv00001462sd00007141*
- ID_MODEL_FROM_DATABASE=Aspire L250
+ ID_MODEL_FROM_DATABASE=IXP SB4x0 Serial ATA Controller (Aspire L250)
 
 pci:v00001002d0000437A*
  ID_MODEL_FROM_DATABASE=IXP SB400 Serial ATA Controller
 
 pci:v00001002d0000437Asv00001002sd00004379*
- ID_MODEL_FROM_DATABASE=4379 Serial ATA Controller
+ ID_MODEL_FROM_DATABASE=IXP SB400 Serial ATA Controller (4379 Serial ATA Controller)
 
 pci:v00001002d0000437Asv00001002sd0000437A*
- ID_MODEL_FROM_DATABASE=437A Serial ATA Controller
+ ID_MODEL_FROM_DATABASE=IXP SB400 Serial ATA Controller (437A Serial ATA Controller)
 
 pci:v00001002d0000437Asv00001462sd00007141*
- ID_MODEL_FROM_DATABASE=Aspire L250
+ ID_MODEL_FROM_DATABASE=IXP SB400 Serial ATA Controller (Aspire L250)
 
 pci:v00001002d0000437Asv000014F1sd00008800*
- ID_MODEL_FROM_DATABASE=Leadtek WinFast TV2000XP Expert
+ ID_MODEL_FROM_DATABASE=IXP SB400 Serial ATA Controller (Leadtek WinFast TV2000XP Expert)
 
 pci:v00001002d0000437B*
  ID_MODEL_FROM_DATABASE=IXP SB4x0 High Definition Audio Controller
@@ -2136,31 +2187,31 @@ pci:v00001002d0000437Bsv00001002sd0000437B*
  ID_MODEL_FROM_DATABASE=IXP SB4x0 High Definition Audio Controller
 
 pci:v00001002d0000437Bsv000010CFsd00001326*
- ID_MODEL_FROM_DATABASE=Fujitsu Lifebook A3040
+ ID_MODEL_FROM_DATABASE=IXP SB4x0 High Definition Audio Controller (Fujitsu Lifebook A3040)
 
 pci:v00001002d0000437Bsv00001734sd000010B8*
- ID_MODEL_FROM_DATABASE=Realtek High Definition Audio
+ ID_MODEL_FROM_DATABASE=IXP SB4x0 High Definition Audio Controller (Realtek High Definition Audio)
 
 pci:v00001002d00004380*
  ID_MODEL_FROM_DATABASE=SB600 Non-Raid-5 SATA
 
 pci:v00001002d00004380sv0000103Csd00002813*
- ID_MODEL_FROM_DATABASE=DC5750 Microtower
+ ID_MODEL_FROM_DATABASE=SB600 Non-Raid-5 SATA (DC5750 Microtower)
 
 pci:v00001002d00004380sv00001179sd0000FF50*
- ID_MODEL_FROM_DATABASE=Satellite P305D-S8995E
+ ID_MODEL_FROM_DATABASE=SB600 Non-Raid-5 SATA (Satellite P305D-S8995E)
 
 pci:v00001002d00004380sv00001458sd0000B003*
- ID_MODEL_FROM_DATABASE=GA-MA790FX-DS5 (rev. 1.0)
+ ID_MODEL_FROM_DATABASE=SB600 Non-Raid-5 SATA (GA-MA790FX-DS5 (rev. 1.0))
 
 pci:v00001002d00004380sv00001458sd0000B005*
- ID_MODEL_FROM_DATABASE=Gigabyte GA-MA69G-S3H Motherboard
+ ID_MODEL_FROM_DATABASE=SB600 Non-Raid-5 SATA (Gigabyte GA-MA69G-S3H Motherboard)
 
 pci:v00001002d00004380sv00001462sd00007327*
- ID_MODEL_FROM_DATABASE=K9AG Neo2
+ ID_MODEL_FROM_DATABASE=SB600 Non-Raid-5 SATA (K9AG Neo2)
 
 pci:v00001002d00004380sv000017F2sd00005999*
- ID_MODEL_FROM_DATABASE=KI690-AM2 Motherboard
+ ID_MODEL_FROM_DATABASE=SB600 Non-Raid-5 SATA (KI690-AM2 Motherboard)
 
 pci:v00001002d00004381*
  ID_MODEL_FROM_DATABASE=SB600 SATA Controller (RAID 5 mode)
@@ -2172,34 +2223,34 @@ pci:v00001002d00004383*
  ID_MODEL_FROM_DATABASE=SBx00 Azalia (Intel HDA)
 
 pci:v00001002d00004383sv00001019sd00002120*
- ID_MODEL_FROM_DATABASE=A785GM-M
+ ID_MODEL_FROM_DATABASE=SBx00 Azalia (Intel HDA) (A785GM-M)
 
 pci:v00001002d00004383sv0000103Csd00001611*
- ID_MODEL_FROM_DATABASE=Pavilion DM1Z-3000
+ ID_MODEL_FROM_DATABASE=SBx00 Azalia (Intel HDA) (Pavilion DM1Z-3000)
 
 pci:v00001002d00004383sv0000103Csd0000280A*
- ID_MODEL_FROM_DATABASE=DC5750 Microtower
+ ID_MODEL_FROM_DATABASE=SBx00 Azalia (Intel HDA) (DC5750 Microtower)
 
 pci:v00001002d00004383sv00001043sd00008230*
- ID_MODEL_FROM_DATABASE=M3A78-EH Motherboard
+ ID_MODEL_FROM_DATABASE=SBx00 Azalia (Intel HDA) (M3A78-EH Motherboard)
 
 pci:v00001002d00004383sv00001043sd0000836C*
- ID_MODEL_FROM_DATABASE=M4A785TD Motherboard
+ ID_MODEL_FROM_DATABASE=SBx00 Azalia (Intel HDA) (M4A785TD Motherboard)
 
 pci:v00001002d00004383sv00001043sd00008410*
- ID_MODEL_FROM_DATABASE=M4A89GTD PRO/USB3 Motherboard
+ ID_MODEL_FROM_DATABASE=SBx00 Azalia (Intel HDA) (M4A89GTD PRO/USB3 Motherboard)
 
 pci:v00001002d00004383sv00001043sd0000841B*
- ID_MODEL_FROM_DATABASE=M5A88-V EVO
+ ID_MODEL_FROM_DATABASE=SBx00 Azalia (Intel HDA) (M5A88-V EVO)
 
 pci:v00001002d00004383sv00001179sd0000FF50*
- ID_MODEL_FROM_DATABASE=Satellite P305D-S8995E
+ ID_MODEL_FROM_DATABASE=SBx00 Azalia (Intel HDA) (Satellite P305D-S8995E)
 
 pci:v00001002d00004383sv00001458sd0000A022*
- ID_MODEL_FROM_DATABASE=GA-MA770-DS3rev2.0 Motherboard
+ ID_MODEL_FROM_DATABASE=SBx00 Azalia (Intel HDA) (GA-MA770-DS3rev2.0 Motherboard)
 
 pci:v00001002d00004383sv000017F2sd00005000*
- ID_MODEL_FROM_DATABASE=KI690-AM2 Motherboard
+ ID_MODEL_FROM_DATABASE=SBx00 Azalia (Intel HDA) (KI690-AM2 Motherboard)
 
 pci:v00001002d00004384*
  ID_MODEL_FROM_DATABASE=SBx00 PCI to PCI Bridge
@@ -2208,160 +2259,160 @@ pci:v00001002d00004385*
  ID_MODEL_FROM_DATABASE=SBx00 SMBus Controller
 
 pci:v00001002d00004385sv00001019sd00002120*
- ID_MODEL_FROM_DATABASE=A785GM-M
+ ID_MODEL_FROM_DATABASE=SBx00 SMBus Controller (A785GM-M)
 
 pci:v00001002d00004385sv0000103Csd00001611*
- ID_MODEL_FROM_DATABASE=Pavilion DM1Z-3000
+ ID_MODEL_FROM_DATABASE=SBx00 SMBus Controller (Pavilion DM1Z-3000)
 
 pci:v00001002d00004385sv0000103Csd0000280A*
- ID_MODEL_FROM_DATABASE=DC5750 Microtower
+ ID_MODEL_FROM_DATABASE=SBx00 SMBus Controller (DC5750 Microtower)
 
 pci:v00001002d00004385sv00001043sd000082EF*
- ID_MODEL_FROM_DATABASE=M3A78-EH Motherboard
+ ID_MODEL_FROM_DATABASE=SBx00 SMBus Controller (M3A78-EH Motherboard)
 
 pci:v00001002d00004385sv00001043sd00008389*
- ID_MODEL_FROM_DATABASE=M4A785TD Motherboard
+ ID_MODEL_FROM_DATABASE=SBx00 SMBus Controller (M4A785TD Motherboard)
 
 pci:v00001002d00004385sv00001179sd0000FF50*
- ID_MODEL_FROM_DATABASE=Satellite P305D-S8995E
+ ID_MODEL_FROM_DATABASE=SBx00 SMBus Controller (Satellite P305D-S8995E)
 
 pci:v00001002d00004385sv00001458sd00004385*
- ID_MODEL_FROM_DATABASE=GA-MA770-DS3rev2.0 Motherboard
+ ID_MODEL_FROM_DATABASE=SBx00 SMBus Controller (GA-MA770-DS3rev2.0 Motherboard)
 
 pci:v00001002d00004385sv00001462sd00007368*
- ID_MODEL_FROM_DATABASE=K9AG Neo2
+ ID_MODEL_FROM_DATABASE=SBx00 SMBus Controller (K9AG Neo2)
 
 pci:v00001002d00004385sv000015D9sd0000A811*
- ID_MODEL_FROM_DATABASE=H8DGU
+ ID_MODEL_FROM_DATABASE=SBx00 SMBus Controller (H8DGU)
 
 pci:v00001002d00004385sv0000174Bsd00001001*
- ID_MODEL_FROM_DATABASE=PURE Fusion Mini
+ ID_MODEL_FROM_DATABASE=SBx00 SMBus Controller (PURE Fusion Mini)
 
 pci:v00001002d00004385sv000017F2sd00005000*
- ID_MODEL_FROM_DATABASE=KI690-AM2 Motherboard
+ ID_MODEL_FROM_DATABASE=SBx00 SMBus Controller (KI690-AM2 Motherboard)
 
 pci:v00001002d00004386*
  ID_MODEL_FROM_DATABASE=SB600 USB Controller (EHCI)
 
 pci:v00001002d00004386sv0000103Csd0000280A*
- ID_MODEL_FROM_DATABASE=DC5750 Microtower
+ ID_MODEL_FROM_DATABASE=SB600 USB Controller (EHCI) (DC5750 Microtower)
 
 pci:v00001002d00004386sv00001179sd0000FF50*
- ID_MODEL_FROM_DATABASE=Satellite P305D-S8995E
+ ID_MODEL_FROM_DATABASE=SB600 USB Controller (EHCI) (Satellite P305D-S8995E)
 
 pci:v00001002d00004386sv00001462sd00007368*
- ID_MODEL_FROM_DATABASE=K9AG Neo2
+ ID_MODEL_FROM_DATABASE=SB600 USB Controller (EHCI) (K9AG Neo2)
 
 pci:v00001002d00004386sv000017F2sd00005000*
- ID_MODEL_FROM_DATABASE=KI690-AM2 Motherboard
+ ID_MODEL_FROM_DATABASE=SB600 USB Controller (EHCI) (KI690-AM2 Motherboard)
 
 pci:v00001002d00004387*
  ID_MODEL_FROM_DATABASE=SB600 USB (OHCI0)
 
 pci:v00001002d00004387sv0000103Csd0000280A*
- ID_MODEL_FROM_DATABASE=DC5750 Microtower
+ ID_MODEL_FROM_DATABASE=SB600 USB (OHCI0) (DC5750 Microtower)
 
 pci:v00001002d00004387sv00001179sd0000FF50*
- ID_MODEL_FROM_DATABASE=Satellite P305D-S8995E
+ ID_MODEL_FROM_DATABASE=SB600 USB (OHCI0) (Satellite P305D-S8995E)
 
 pci:v00001002d00004387sv00001462sd00007368*
- ID_MODEL_FROM_DATABASE=K9AG Neo2
+ ID_MODEL_FROM_DATABASE=SB600 USB (OHCI0) (K9AG Neo2)
 
 pci:v00001002d00004387sv000017F2sd00005000*
- ID_MODEL_FROM_DATABASE=KI690-AM2 Motherboard
+ ID_MODEL_FROM_DATABASE=SB600 USB (OHCI0) (KI690-AM2 Motherboard)
 
 pci:v00001002d00004388*
  ID_MODEL_FROM_DATABASE=SB600 USB (OHCI1)
 
 pci:v00001002d00004388sv0000103Csd0000280A*
- ID_MODEL_FROM_DATABASE=DC5750 Microtower
+ ID_MODEL_FROM_DATABASE=SB600 USB (OHCI1) (DC5750 Microtower)
 
 pci:v00001002d00004388sv00001179sd0000FF50*
- ID_MODEL_FROM_DATABASE=Satellite P305D-S8995E
+ ID_MODEL_FROM_DATABASE=SB600 USB (OHCI1) (Satellite P305D-S8995E)
 
 pci:v00001002d00004388sv00001462sd00007368*
- ID_MODEL_FROM_DATABASE=K9AG Neo2
+ ID_MODEL_FROM_DATABASE=SB600 USB (OHCI1) (K9AG Neo2)
 
 pci:v00001002d00004388sv000017F2sd00005000*
- ID_MODEL_FROM_DATABASE=KI690-AM2 Motherboard
+ ID_MODEL_FROM_DATABASE=SB600 USB (OHCI1) (KI690-AM2 Motherboard)
 
 pci:v00001002d00004389*
  ID_MODEL_FROM_DATABASE=SB600 USB (OHCI2)
 
 pci:v00001002d00004389sv0000103Csd0000280A*
- ID_MODEL_FROM_DATABASE=DC5750 Microtower
+ ID_MODEL_FROM_DATABASE=SB600 USB (OHCI2) (DC5750 Microtower)
 
 pci:v00001002d00004389sv00001179sd0000FF50*
- ID_MODEL_FROM_DATABASE=Satellite P305D-S8995E
+ ID_MODEL_FROM_DATABASE=SB600 USB (OHCI2) (Satellite P305D-S8995E)
 
 pci:v00001002d00004389sv00001462sd00007368*
- ID_MODEL_FROM_DATABASE=K9AG Neo2
+ ID_MODEL_FROM_DATABASE=SB600 USB (OHCI2) (K9AG Neo2)
 
 pci:v00001002d00004389sv000017F2sd00005000*
- ID_MODEL_FROM_DATABASE=KI690-AM2 Motherboard
+ ID_MODEL_FROM_DATABASE=SB600 USB (OHCI2) (KI690-AM2 Motherboard)
 
 pci:v00001002d0000438A*
  ID_MODEL_FROM_DATABASE=SB600 USB (OHCI3)
 
 pci:v00001002d0000438Asv0000103Csd0000280A*
- ID_MODEL_FROM_DATABASE=DC5750 Microtower
+ ID_MODEL_FROM_DATABASE=SB600 USB (OHCI3) (DC5750 Microtower)
 
 pci:v00001002d0000438Asv00001179sd0000FF50*
- ID_MODEL_FROM_DATABASE=Satellite P305D-S8995E
+ ID_MODEL_FROM_DATABASE=SB600 USB (OHCI3) (Satellite P305D-S8995E)
 
 pci:v00001002d0000438Asv00001462sd00007368*
- ID_MODEL_FROM_DATABASE=K9AG Neo2
+ ID_MODEL_FROM_DATABASE=SB600 USB (OHCI3) (K9AG Neo2)
 
 pci:v00001002d0000438Asv000017F2sd00005000*
- ID_MODEL_FROM_DATABASE=KI690-AM2 Motherboard
+ ID_MODEL_FROM_DATABASE=SB600 USB (OHCI3) (KI690-AM2 Motherboard)
 
 pci:v00001002d0000438B*
  ID_MODEL_FROM_DATABASE=SB600 USB (OHCI4)
 
 pci:v00001002d0000438Bsv0000103Csd0000280A*
- ID_MODEL_FROM_DATABASE=DC5750 Microtower
+ ID_MODEL_FROM_DATABASE=SB600 USB (OHCI4) (DC5750 Microtower)
 
 pci:v00001002d0000438Bsv00001179sd0000FF50*
- ID_MODEL_FROM_DATABASE=Satellite P305D-S8995E
+ ID_MODEL_FROM_DATABASE=SB600 USB (OHCI4) (Satellite P305D-S8995E)
 
 pci:v00001002d0000438Bsv00001462sd00007368*
- ID_MODEL_FROM_DATABASE=K9AG Neo2
+ ID_MODEL_FROM_DATABASE=SB600 USB (OHCI4) (K9AG Neo2)
 
 pci:v00001002d0000438Bsv000017F2sd00005000*
- ID_MODEL_FROM_DATABASE=KI690-AM2 Motherboard
+ ID_MODEL_FROM_DATABASE=SB600 USB (OHCI4) (KI690-AM2 Motherboard)
 
 pci:v00001002d0000438C*
  ID_MODEL_FROM_DATABASE=SB600 IDE
 
 pci:v00001002d0000438Csv0000103Csd0000280A*
- ID_MODEL_FROM_DATABASE=DC5750 Microtower
+ ID_MODEL_FROM_DATABASE=SB600 IDE (DC5750 Microtower)
 
 pci:v00001002d0000438Csv00001179sd0000FF50*
- ID_MODEL_FROM_DATABASE=Satellite P305D-S8995E
+ ID_MODEL_FROM_DATABASE=SB600 IDE (Satellite P305D-S8995E)
 
 pci:v00001002d0000438Csv00001458sd00005002*
- ID_MODEL_FROM_DATABASE=Gigabyte GA-MA69G-S3H Motherboard
+ ID_MODEL_FROM_DATABASE=SB600 IDE (Gigabyte GA-MA69G-S3H Motherboard)
 
 pci:v00001002d0000438Csv00001462sd00007368*
- ID_MODEL_FROM_DATABASE=K9AG Neo2
+ ID_MODEL_FROM_DATABASE=SB600 IDE (K9AG Neo2)
 
 pci:v00001002d0000438Csv000017F2sd00005000*
- ID_MODEL_FROM_DATABASE=KI690-AM2 Motherboard
+ ID_MODEL_FROM_DATABASE=SB600 IDE (KI690-AM2 Motherboard)
 
 pci:v00001002d0000438D*
  ID_MODEL_FROM_DATABASE=SB600 PCI to LPC Bridge
 
 pci:v00001002d0000438Dsv0000103Csd0000280A*
- ID_MODEL_FROM_DATABASE=DC5750 Microtower
+ ID_MODEL_FROM_DATABASE=SB600 PCI to LPC Bridge (DC5750 Microtower)
 
 pci:v00001002d0000438Dsv00001179sd0000FF50*
- ID_MODEL_FROM_DATABASE=Satellite P305D-S8995E
+ ID_MODEL_FROM_DATABASE=SB600 PCI to LPC Bridge (Satellite P305D-S8995E)
 
 pci:v00001002d0000438Dsv00001462sd00007368*
- ID_MODEL_FROM_DATABASE=K9AG Neo2
+ ID_MODEL_FROM_DATABASE=SB600 PCI to LPC Bridge (K9AG Neo2)
 
 pci:v00001002d0000438Dsv000017F2sd00005000*
- ID_MODEL_FROM_DATABASE=KI690-AM2 Motherboard
+ ID_MODEL_FROM_DATABASE=SB600 PCI to LPC Bridge (KI690-AM2 Motherboard)
 
 pci:v00001002d0000438E*
  ID_MODEL_FROM_DATABASE=SB600 AC97 Modem
@@ -2370,31 +2421,31 @@ pci:v00001002d00004390*
  ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 SATA Controller [IDE mode]
 
 pci:v00001002d00004390sv00001043sd000082EF*
- ID_MODEL_FROM_DATABASE=M3A78-EH Motherboard
+ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 SATA Controller [IDE mode] (M3A78-EH Motherboard)
 
 pci:v00001002d00004390sv00001043sd00008389*
- ID_MODEL_FROM_DATABASE=M4A785TD Motherboard
+ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 SATA Controller [IDE mode] (M4A785TD Motherboard)
 
 pci:v00001002d00004390sv00001458sd0000B002*
- ID_MODEL_FROM_DATABASE=GA-MA770-DS3rev2.0 Motherboard
+ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 SATA Controller [IDE mode] (GA-MA770-DS3rev2.0 Motherboard)
 
 pci:v00001002d00004390sv00001849sd00004390*
- ID_MODEL_FROM_DATABASE=Motherboard (one of many)
+ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 SATA Controller [IDE mode] (Motherboard (one of many))
 
 pci:v00001002d00004391*
  ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 SATA Controller [AHCI mode]
 
 pci:v00001002d00004391sv0000103Csd00001611*
- ID_MODEL_FROM_DATABASE=Pavilion DM1Z-3000
+ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 SATA Controller [AHCI mode] (Pavilion DM1Z-3000)
 
 pci:v00001002d00004391sv00001043sd000082EF*
- ID_MODEL_FROM_DATABASE=M3A78-EH Motherboard
+ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 SATA Controller [AHCI mode] (M3A78-EH Motherboard)
 
 pci:v00001002d00004391sv00001043sd00008443*
- ID_MODEL_FROM_DATABASE=M5A88-V EVO
+ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 SATA Controller [AHCI mode] (M5A88-V EVO)
 
 pci:v00001002d00004391sv0000174Bsd00001001*
- ID_MODEL_FROM_DATABASE=PURE Fusion Mini
+ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 SATA Controller [AHCI mode] (PURE Fusion Mini)
 
 pci:v00001002d00004392*
  ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 SATA Controller [Non-RAID5 mode]
@@ -2412,97 +2463,97 @@ pci:v00001002d00004396*
  ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB EHCI Controller
 
 pci:v00001002d00004396sv00001019sd00002120*
- ID_MODEL_FROM_DATABASE=A785GM-M
+ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB EHCI Controller (A785GM-M)
 
 pci:v00001002d00004396sv0000103Csd00001611*
- ID_MODEL_FROM_DATABASE=Pavilion DM1Z-3000
+ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB EHCI Controller (Pavilion DM1Z-3000)
 
 pci:v00001002d00004396sv00001043sd000082EF*
- ID_MODEL_FROM_DATABASE=M3A78-EH Motherboard
+ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB EHCI Controller (M3A78-EH Motherboard)
 
 pci:v00001002d00004396sv00001043sd00008443*
- ID_MODEL_FROM_DATABASE=M5A88-V EVO
+ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB EHCI Controller (M5A88-V EVO)
 
 pci:v00001002d00004396sv000015D9sd0000A811*
- ID_MODEL_FROM_DATABASE=H8DGU
+ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB EHCI Controller (H8DGU)
 
 pci:v00001002d00004396sv0000174Bsd00001001*
- ID_MODEL_FROM_DATABASE=PURE Fusion Mini
+ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB EHCI Controller (PURE Fusion Mini)
 
 pci:v00001002d00004397*
  ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB OHCI0 Controller
 
 pci:v00001002d00004397sv00001019sd00002120*
- ID_MODEL_FROM_DATABASE=A785GM-M
+ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB OHCI0 Controller (A785GM-M)
 
 pci:v00001002d00004397sv0000103Csd00001611*
- ID_MODEL_FROM_DATABASE=Pavilion DM1Z-3000
+ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB OHCI0 Controller (Pavilion DM1Z-3000)
 
 pci:v00001002d00004397sv00001043sd000082EF*
- ID_MODEL_FROM_DATABASE=M3A78-EH Motherboard
+ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB OHCI0 Controller (M3A78-EH Motherboard)
 
 pci:v00001002d00004397sv00001043sd00008443*
- ID_MODEL_FROM_DATABASE=M5A88-V EVO
+ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB OHCI0 Controller (M5A88-V EVO)
 
 pci:v00001002d00004397sv000015D9sd0000A811*
- ID_MODEL_FROM_DATABASE=H8DGU
+ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB OHCI0 Controller (H8DGU)
 
 pci:v00001002d00004397sv0000174Bsd00001001*
- ID_MODEL_FROM_DATABASE=PURE Fusion Mini
+ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB OHCI0 Controller (PURE Fusion Mini)
 
 pci:v00001002d00004398*
  ID_MODEL_FROM_DATABASE=SB7x0 USB OHCI1 Controller
 
 pci:v00001002d00004398sv00001019sd00002120*
- ID_MODEL_FROM_DATABASE=A785GM-M
+ ID_MODEL_FROM_DATABASE=SB7x0 USB OHCI1 Controller (A785GM-M)
 
 pci:v00001002d00004398sv00001043sd000082EF*
- ID_MODEL_FROM_DATABASE=M3A78-EH Motherboard
+ ID_MODEL_FROM_DATABASE=SB7x0 USB OHCI1 Controller (M3A78-EH Motherboard)
 
 pci:v00001002d00004398sv000015D9sd0000A811*
- ID_MODEL_FROM_DATABASE=H8DGU
+ ID_MODEL_FROM_DATABASE=SB7x0 USB OHCI1 Controller (H8DGU)
 
 pci:v00001002d00004399*
  ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB OHCI2 Controller
 
 pci:v00001002d00004399sv00001019sd00002120*
- ID_MODEL_FROM_DATABASE=A785GM-M
+ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB OHCI2 Controller (A785GM-M)
 
 pci:v00001002d00004399sv00001043sd000082EF*
- ID_MODEL_FROM_DATABASE=M3A78-EH Motherboard
+ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB OHCI2 Controller (M3A78-EH Motherboard)
 
 pci:v00001002d00004399sv00001043sd00008443*
- ID_MODEL_FROM_DATABASE=M5A88-V EVO
+ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB OHCI2 Controller (M5A88-V EVO)
 
 pci:v00001002d00004399sv0000174Bsd00001001*
- ID_MODEL_FROM_DATABASE=PURE Fusion Mini
+ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 USB OHCI2 Controller (PURE Fusion Mini)
 
 pci:v00001002d0000439C*
  ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 IDE Controller
 
 pci:v00001002d0000439Csv00001019sd00002120*
- ID_MODEL_FROM_DATABASE=A785GM-M
+ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 IDE Controller (A785GM-M)
 
 pci:v00001002d0000439Csv00001043sd000082EF*
- ID_MODEL_FROM_DATABASE=M3A78-EH Motherboard
+ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 IDE Controller (M3A78-EH Motherboard)
 
 pci:v00001002d0000439D*
  ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 LPC host controller
 
 pci:v00001002d0000439Dsv00001019sd00002120*
- ID_MODEL_FROM_DATABASE=A785GM-M
+ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 LPC host controller (A785GM-M)
 
 pci:v00001002d0000439Dsv0000103Csd00001611*
- ID_MODEL_FROM_DATABASE=Pavilion DM1Z-3000
+ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 LPC host controller (Pavilion DM1Z-3000)
 
 pci:v00001002d0000439Dsv00001043sd000082EF*
- ID_MODEL_FROM_DATABASE=M3A78-EH Motherboard
+ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 LPC host controller (M3A78-EH Motherboard)
 
 pci:v00001002d0000439Dsv00001043sd00008443*
- ID_MODEL_FROM_DATABASE=M5A88-V EVO
+ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 LPC host controller (M5A88-V EVO)
 
 pci:v00001002d0000439Dsv0000174Bsd00001001*
- ID_MODEL_FROM_DATABASE=PURE Fusion Mini
+ ID_MODEL_FROM_DATABASE=SB7x0/SB8x0/SB9x0 LPC host controller (PURE Fusion Mini)
 
 pci:v00001002d000043A0*
  ID_MODEL_FROM_DATABASE=SB700/SB800/SB900 PCI to PCI bridge (PCIE port 0)
@@ -2529,88 +2580,88 @@ pci:v00001002d00004742*
  ID_MODEL_FROM_DATABASE=3D Rage PRO AGP 2X
 
 pci:v00001002d00004742sv00001002sd00000040*
- ID_MODEL_FROM_DATABASE=Rage Pro Turbo AGP 2X
+ ID_MODEL_FROM_DATABASE=3D Rage PRO AGP 2X (Rage Pro Turbo AGP 2X)
 
 pci:v00001002d00004742sv00001002sd00000044*
- ID_MODEL_FROM_DATABASE=Rage Pro Turbo AGP 2X
+ ID_MODEL_FROM_DATABASE=3D Rage PRO AGP 2X (Rage Pro Turbo AGP 2X)
 
 pci:v00001002d00004742sv00001002sd00000061*
- ID_MODEL_FROM_DATABASE=Rage Pro AIW AGP 2X
+ ID_MODEL_FROM_DATABASE=3D Rage PRO AGP 2X (Rage Pro AIW AGP 2X)
 
 pci:v00001002d00004742sv00001002sd00000062*
- ID_MODEL_FROM_DATABASE=Rage Pro AIW AGP 2X
+ ID_MODEL_FROM_DATABASE=3D Rage PRO AGP 2X (Rage Pro AIW AGP 2X)
 
 pci:v00001002d00004742sv00001002sd00000063*
- ID_MODEL_FROM_DATABASE=Rage Pro AIW AGP 2X
+ ID_MODEL_FROM_DATABASE=3D Rage PRO AGP 2X (Rage Pro AIW AGP 2X)
 
 pci:v00001002d00004742sv00001002sd00000080*
- ID_MODEL_FROM_DATABASE=Rage Pro Turbo AGP 2X
+ ID_MODEL_FROM_DATABASE=3D Rage PRO AGP 2X (Rage Pro Turbo AGP 2X)
 
 pci:v00001002d00004742sv00001002sd00000084*
- ID_MODEL_FROM_DATABASE=Rage Pro Turbo AGP 2X
+ ID_MODEL_FROM_DATABASE=3D Rage PRO AGP 2X (Rage Pro Turbo AGP 2X)
 
 pci:v00001002d00004742sv00001002sd00004742*
- ID_MODEL_FROM_DATABASE=Rage Pro Turbo AGP 2X
+ ID_MODEL_FROM_DATABASE=3D Rage PRO AGP 2X (Rage Pro Turbo AGP 2X)
 
 pci:v00001002d00004742sv00001002sd00008001*
- ID_MODEL_FROM_DATABASE=Rage Pro Turbo AGP 2X
+ ID_MODEL_FROM_DATABASE=3D Rage PRO AGP 2X (Rage Pro Turbo AGP 2X)
 
 pci:v00001002d00004742sv00001028sd00000082*
- ID_MODEL_FROM_DATABASE=Rage Pro Turbo AGP 2X
+ ID_MODEL_FROM_DATABASE=3D Rage PRO AGP 2X (Rage Pro Turbo AGP 2X)
 
 pci:v00001002d00004742sv00001028sd00004082*
- ID_MODEL_FROM_DATABASE=Optiplex GX1 Onboard Display Adapter
+ ID_MODEL_FROM_DATABASE=3D Rage PRO AGP 2X (Optiplex GX1 Onboard Display Adapter)
 
 pci:v00001002d00004742sv00001028sd00008082*
- ID_MODEL_FROM_DATABASE=Rage Pro Turbo AGP 2X
+ ID_MODEL_FROM_DATABASE=3D Rage PRO AGP 2X (Rage Pro Turbo AGP 2X)
 
 pci:v00001002d00004742sv00001028sd0000C082*
- ID_MODEL_FROM_DATABASE=Rage Pro Turbo AGP 2X
+ ID_MODEL_FROM_DATABASE=3D Rage PRO AGP 2X (Rage Pro Turbo AGP 2X)
 
 pci:v00001002d00004742sv00008086sd00004152*
- ID_MODEL_FROM_DATABASE=Xpert 98D AGP 2X
+ ID_MODEL_FROM_DATABASE=3D Rage PRO AGP 2X (Xpert 98D AGP 2X)
 
 pci:v00001002d00004742sv00008086sd0000464A*
- ID_MODEL_FROM_DATABASE=Rage Pro Turbo AGP 2X
+ ID_MODEL_FROM_DATABASE=3D Rage PRO AGP 2X (Rage Pro Turbo AGP 2X)
 
 pci:v00001002d00004744*
  ID_MODEL_FROM_DATABASE=3D Rage PRO AGP 1X
 
 pci:v00001002d00004744sv00001002sd00004744*
- ID_MODEL_FROM_DATABASE=Rage Pro Turbo AGP
+ ID_MODEL_FROM_DATABASE=3D Rage PRO AGP 1X (Rage Pro Turbo AGP)
 
 pci:v00001002d00004744sv00008086sd00004D55*
- ID_MODEL_FROM_DATABASE=Rage 3D Pro AGP 1X [Intel MU440EX]
+ ID_MODEL_FROM_DATABASE=3D Rage PRO AGP 1X (Rage 3D Pro AGP 1X [Intel MU440EX])
 
 pci:v00001002d00004749*
  ID_MODEL_FROM_DATABASE=3D Rage PRO PCI
 
 pci:v00001002d00004749sv00001002sd00000061*
- ID_MODEL_FROM_DATABASE=Rage Pro AIW
+ ID_MODEL_FROM_DATABASE=3D Rage PRO PCI (Rage Pro AIW)
 
 pci:v00001002d00004749sv00001002sd00000062*
- ID_MODEL_FROM_DATABASE=Rage Pro AIW
+ ID_MODEL_FROM_DATABASE=3D Rage PRO PCI (Rage Pro AIW)
 
 pci:v00001002d0000474D*
  ID_MODEL_FROM_DATABASE=Rage XL AGP 2X
 
 pci:v00001002d0000474Dsv00001002sd00000004*
- ID_MODEL_FROM_DATABASE=Xpert 98 RXL AGP 2X
+ ID_MODEL_FROM_DATABASE=Rage XL AGP 2X (Xpert 98 RXL AGP 2X)
 
 pci:v00001002d0000474Dsv00001002sd00000008*
- ID_MODEL_FROM_DATABASE=Xpert 98 RXL AGP 2X
+ ID_MODEL_FROM_DATABASE=Rage XL AGP 2X (Xpert 98 RXL AGP 2X)
 
 pci:v00001002d0000474Dsv00001002sd00000080*
  ID_MODEL_FROM_DATABASE=Rage XL AGP 2X
 
 pci:v00001002d0000474Dsv00001002sd00000084*
- ID_MODEL_FROM_DATABASE=Xpert 98 AGP 2X
+ ID_MODEL_FROM_DATABASE=Rage XL AGP 2X (Xpert 98 AGP 2X)
 
 pci:v00001002d0000474Dsv00001002sd0000474D*
- ID_MODEL_FROM_DATABASE=Rage XL AGP
+ ID_MODEL_FROM_DATABASE=Rage XL AGP 2X (Rage XL AGP)
 
 pci:v00001002d0000474Dsv00001033sd0000806A*
- ID_MODEL_FROM_DATABASE=Rage XL AGP
+ ID_MODEL_FROM_DATABASE=Rage XL AGP 2X (Rage XL AGP)
 
 pci:v00001002d0000474E*
  ID_MODEL_FROM_DATABASE=Rage XC AGP
@@ -2631,79 +2682,79 @@ pci:v00001002d00004750*
  ID_MODEL_FROM_DATABASE=3D Rage Pro PCI
 
 pci:v00001002d00004750sv00001002sd00000040*
- ID_MODEL_FROM_DATABASE=Rage Pro Turbo
+ ID_MODEL_FROM_DATABASE=3D Rage Pro PCI (Rage Pro Turbo)
 
 pci:v00001002d00004750sv00001002sd00000044*
- ID_MODEL_FROM_DATABASE=Rage Pro Turbo
+ ID_MODEL_FROM_DATABASE=3D Rage Pro PCI (Rage Pro Turbo)
 
 pci:v00001002d00004750sv00001002sd00000080*
- ID_MODEL_FROM_DATABASE=Rage Pro Turbo
+ ID_MODEL_FROM_DATABASE=3D Rage Pro PCI (Rage Pro Turbo)
 
 pci:v00001002d00004750sv00001002sd00000084*
- ID_MODEL_FROM_DATABASE=Rage Pro Turbo
+ ID_MODEL_FROM_DATABASE=3D Rage Pro PCI (Rage Pro Turbo)
 
 pci:v00001002d00004750sv00001002sd00004750*
- ID_MODEL_FROM_DATABASE=Rage Pro Turbo
+ ID_MODEL_FROM_DATABASE=3D Rage Pro PCI (Rage Pro Turbo)
 
 pci:v00001002d00004752*
  ID_MODEL_FROM_DATABASE=Rage XL PCI
 
 pci:v00001002d00004752sv00000E11sd0000001E*
- ID_MODEL_FROM_DATABASE=Proliant Rage XL
+ ID_MODEL_FROM_DATABASE=Rage XL PCI (Proliant Rage XL)
 
 pci:v00001002d00004752sv00001002sd00000008*
- ID_MODEL_FROM_DATABASE=Rage XL
+ ID_MODEL_FROM_DATABASE=Rage XL PCI (Rage XL)
 
 pci:v00001002d00004752sv00001002sd00004752*
- ID_MODEL_FROM_DATABASE=Proliant Rage XL
+ ID_MODEL_FROM_DATABASE=Rage XL PCI (Proliant Rage XL)
 
 pci:v00001002d00004752sv00001002sd00008008*
- ID_MODEL_FROM_DATABASE=Rage XL
+ ID_MODEL_FROM_DATABASE=Rage XL PCI (Rage XL)
 
 pci:v00001002d00004752sv00001014sd00000240*
- ID_MODEL_FROM_DATABASE=eServer xSeries server mainboard
+ ID_MODEL_FROM_DATABASE=Rage XL PCI (eServer xSeries server mainboard)
 
 pci:v00001002d00004752sv00001028sd000000CE*
- ID_MODEL_FROM_DATABASE=PowerEdge 1400
+ ID_MODEL_FROM_DATABASE=Rage XL PCI (PowerEdge 1400)
 
 pci:v00001002d00004752sv00001028sd000000D1*
- ID_MODEL_FROM_DATABASE=PowerEdge 2550
+ ID_MODEL_FROM_DATABASE=Rage XL PCI (PowerEdge 2550)
 
 pci:v00001002d00004752sv00001028sd000000D9*
- ID_MODEL_FROM_DATABASE=PowerEdge 2500
+ ID_MODEL_FROM_DATABASE=Rage XL PCI (PowerEdge 2500)
 
 pci:v00001002d00004752sv00001028sd00000134*
- ID_MODEL_FROM_DATABASE=PowerEdge 600SC
+ ID_MODEL_FROM_DATABASE=Rage XL PCI (PowerEdge 600SC)
 
 pci:v00001002d00004752sv00001028sd0000014A*
- ID_MODEL_FROM_DATABASE=PowerEdge 1750
+ ID_MODEL_FROM_DATABASE=Rage XL PCI (PowerEdge 1750)
 
 pci:v00001002d00004752sv00001028sd00000165*
- ID_MODEL_FROM_DATABASE=PowerEdge 750
+ ID_MODEL_FROM_DATABASE=Rage XL PCI (PowerEdge 750)
 
 pci:v00001002d00004752sv0000103Csd000010E1*
- ID_MODEL_FROM_DATABASE=NetServer Rage XL
+ ID_MODEL_FROM_DATABASE=Rage XL PCI (NetServer Rage XL)
 
 pci:v00001002d00004752sv0000103Csd00003208*
- ID_MODEL_FROM_DATABASE=ProLiant DL140 G2
+ ID_MODEL_FROM_DATABASE=Rage XL PCI (ProLiant DL140 G2)
 
 pci:v00001002d00004752sv0000107Bsd00006400*
- ID_MODEL_FROM_DATABASE=6400 Server
+ ID_MODEL_FROM_DATABASE=Rage XL PCI (6400 Server)
 
 pci:v00001002d00004752sv00001734sd0000007A*
- ID_MODEL_FROM_DATABASE=PRIMERGY RX/TX series onboard VGA
+ ID_MODEL_FROM_DATABASE=Rage XL PCI (PRIMERGY RX/TX series onboard VGA)
 
 pci:v00001002d00004752sv00001734sd00001073*
- ID_MODEL_FROM_DATABASE=Primergy Econel 200 D2020 mainboard
+ ID_MODEL_FROM_DATABASE=Rage XL PCI (Primergy Econel 200 D2020 mainboard)
 
 pci:v00001002d00004752sv00008086sd00003411*
- ID_MODEL_FROM_DATABASE=SDS2 Mainboard
+ ID_MODEL_FROM_DATABASE=Rage XL PCI (SDS2 Mainboard)
 
 pci:v00001002d00004752sv00008086sd00003427*
- ID_MODEL_FROM_DATABASE=S875WP1-E mainboard
+ ID_MODEL_FROM_DATABASE=Rage XL PCI (S875WP1-E mainboard)
 
 pci:v00001002d00004752sv00008086sd00005744*
- ID_MODEL_FROM_DATABASE=S845WD1-E mainboard
+ ID_MODEL_FROM_DATABASE=Rage XL PCI (S845WD1-E mainboard)
 
 pci:v00001002d00004753*
  ID_MODEL_FROM_DATABASE=Rage XC
@@ -2721,28 +2772,28 @@ pci:v00001002d00004756*
  ID_MODEL_FROM_DATABASE=3D Rage IIC PCI [Mach64 GT IIC]
 
 pci:v00001002d00004756sv00001002sd00004756*
- ID_MODEL_FROM_DATABASE=Rage IIC
+ ID_MODEL_FROM_DATABASE=3D Rage IIC PCI [Mach64 GT IIC] (Rage IIC)
 
 pci:v00001002d00004757*
  ID_MODEL_FROM_DATABASE=3D Rage IIC AGP
 
 pci:v00001002d00004757sv00001002sd00004757*
- ID_MODEL_FROM_DATABASE=Rage IIC AGP
+ ID_MODEL_FROM_DATABASE=3D Rage IIC AGP (Rage IIC AGP)
 
 pci:v00001002d00004757sv00001028sd00000089*
- ID_MODEL_FROM_DATABASE=Rage 3D IIC
+ ID_MODEL_FROM_DATABASE=3D Rage IIC AGP (Rage 3D IIC)
 
 pci:v00001002d00004757sv00001028sd0000008E*
- ID_MODEL_FROM_DATABASE=PowerEdge 1300 onboard video
+ ID_MODEL_FROM_DATABASE=3D Rage IIC AGP (PowerEdge 1300 onboard video)
 
 pci:v00001002d00004757sv00001028sd00004082*
- ID_MODEL_FROM_DATABASE=Rage 3D IIC
+ ID_MODEL_FROM_DATABASE=3D Rage IIC AGP (Rage 3D IIC)
 
 pci:v00001002d00004757sv00001028sd00008082*
- ID_MODEL_FROM_DATABASE=Rage 3D IIC
+ ID_MODEL_FROM_DATABASE=3D Rage IIC AGP (Rage 3D IIC)
 
 pci:v00001002d00004757sv00001028sd0000C082*
- ID_MODEL_FROM_DATABASE=Rage 3D IIC
+ ID_MODEL_FROM_DATABASE=3D Rage IIC AGP (Rage 3D IIC)
 
 pci:v00001002d00004758*
  ID_MODEL_FROM_DATABASE=210888GX [Mach64 GX PCI]
@@ -2754,40 +2805,40 @@ pci:v00001002d0000475A*
  ID_MODEL_FROM_DATABASE=3D Rage IIC AGP
 
 pci:v00001002d0000475Asv00001002sd00000084*
- ID_MODEL_FROM_DATABASE=Rage 3D Pro AGP 2x XPERT 98
+ ID_MODEL_FROM_DATABASE=3D Rage IIC AGP (Rage 3D Pro AGP 2x XPERT 98)
 
 pci:v00001002d0000475Asv00001002sd00000087*
- ID_MODEL_FROM_DATABASE=Rage 3D IIC
+ ID_MODEL_FROM_DATABASE=3D Rage IIC AGP (Rage 3D IIC)
 
 pci:v00001002d0000475Asv00001002sd0000475A*
- ID_MODEL_FROM_DATABASE=Rage IIC AGP
+ ID_MODEL_FROM_DATABASE=3D Rage IIC AGP (Rage IIC AGP)
 
 pci:v00001002d00004966*
  ID_MODEL_FROM_DATABASE=RV250 [Radeon 9000 Series]
 
 pci:v00001002d00004966sv000010F1sd00000002*
- ID_MODEL_FROM_DATABASE=RV250 If [Tachyon G9000 PRO]
+ ID_MODEL_FROM_DATABASE=RV250 [Radeon 9000 Series] (RV250 If [Tachyon G9000 PRO])
 
 pci:v00001002d00004966sv0000148Csd00002039*
- ID_MODEL_FROM_DATABASE=RV250 If [Radeon 9000 Pro "Evil Commando"]
+ ID_MODEL_FROM_DATABASE=RV250 [Radeon 9000 Series] (RV250 If [Radeon 9000 Pro "Evil Commando"])
 
 pci:v00001002d00004966sv00001509sd00009A00*
- ID_MODEL_FROM_DATABASE=RV250 If [Radeon 9000 "AT009"]
+ ID_MODEL_FROM_DATABASE=RV250 [Radeon 9000 Series] (RV250 If [Radeon 9000 "AT009"])
 
 pci:v00001002d00004966sv00001681sd00000040*
- ID_MODEL_FROM_DATABASE=RV250 If [3D prophet 9000]
+ ID_MODEL_FROM_DATABASE=RV250 [Radeon 9000 Series] (RV250 If [3D prophet 9000])
 
 pci:v00001002d00004966sv0000174Bsd00007176*
- ID_MODEL_FROM_DATABASE=Radeon 9000 Pro
+ ID_MODEL_FROM_DATABASE=RV250 [Radeon 9000 Series] (Radeon 9000 Pro)
 
 pci:v00001002d00004966sv0000174Bsd00007192*
- ID_MODEL_FROM_DATABASE=RV250 If [Radeon 9000 "Atlantis"]
+ ID_MODEL_FROM_DATABASE=RV250 [Radeon 9000 Series] (RV250 If [Radeon 9000 "Atlantis"])
 
 pci:v00001002d00004966sv000017AFsd00002005*
- ID_MODEL_FROM_DATABASE=RV250 If [Excalibur Radeon 9000 Pro]
+ ID_MODEL_FROM_DATABASE=RV250 [Radeon 9000 Series] (RV250 If [Excalibur Radeon 9000 Pro])
 
 pci:v00001002d00004966sv000017AFsd00002006*
- ID_MODEL_FROM_DATABASE=RV250 If [Excalibur Radeon 9000]
+ ID_MODEL_FROM_DATABASE=RV250 [Radeon 9000 Series] (RV250 If [Excalibur Radeon 9000])
 
 pci:v00001002d0000496E*
  ID_MODEL_FROM_DATABASE=RV250 [Radeon 9000] (Secondary)
@@ -2796,7 +2847,7 @@ pci:v00001002d00004A49*
  ID_MODEL_FROM_DATABASE=R420 [Radeon X800 PRO/GTO AGP]
 
 pci:v00001002d00004A49sv0000174Bsd00002620*
- ID_MODEL_FROM_DATABASE=R420 [Radeon X800 GTO AGP]
+ ID_MODEL_FROM_DATABASE=R420 [Radeon X800 PRO/GTO AGP] (R420 [Radeon X800 GTO AGP])
 
 pci:v00001002d00004A4A*
  ID_MODEL_FROM_DATABASE=R420 [Radeon X800 GT AGP]
@@ -2820,7 +2871,7 @@ pci:v00001002d00004A54*
  ID_MODEL_FROM_DATABASE=R420 [Radeon X800 VE AGP]
 
 pci:v00001002d00004A54sv00001002sd00004422*
- ID_MODEL_FROM_DATABASE=All-In-Wonder X800 VE AGP
+ ID_MODEL_FROM_DATABASE=R420 [Radeon X800 VE AGP] (All-In-Wonder X800 VE AGP)
 
 pci:v00001002d00004A69*
  ID_MODEL_FROM_DATABASE=R420 [Radeon X800 PRO/GTO] (Secondary)
@@ -2859,40 +2910,40 @@ pci:v00001002d00004C42*
  ID_MODEL_FROM_DATABASE=3D Rage LT PRO AGP 2X
 
 pci:v00001002d00004C42sv00000E11sd0000B0E7*
- ID_MODEL_FROM_DATABASE=Rage LT Pro (Compaq Presario 5240)
+ ID_MODEL_FROM_DATABASE=3D Rage LT PRO AGP 2X (Rage LT Pro (Compaq Presario 5240))
 
 pci:v00001002d00004C42sv00000E11sd0000B0E8*
- ID_MODEL_FROM_DATABASE=Rage 3D LT Pro
+ ID_MODEL_FROM_DATABASE=3D Rage LT PRO AGP 2X (Rage 3D LT Pro)
 
 pci:v00001002d00004C42sv00000E11sd0000B10E*
- ID_MODEL_FROM_DATABASE=3D Rage LT Pro (Compaq Armada 1750)
+ ID_MODEL_FROM_DATABASE=3D Rage LT PRO AGP 2X (3D Rage LT Pro (Compaq Armada 1750))
 
 pci:v00001002d00004C42sv00001002sd00000040*
- ID_MODEL_FROM_DATABASE=Rage LT Pro AGP 2X
+ ID_MODEL_FROM_DATABASE=3D Rage LT PRO AGP 2X (Rage LT Pro AGP 2X)
 
 pci:v00001002d00004C42sv00001002sd00000044*
- ID_MODEL_FROM_DATABASE=Rage LT Pro AGP 2X
+ ID_MODEL_FROM_DATABASE=3D Rage LT PRO AGP 2X (Rage LT Pro AGP 2X)
 
 pci:v00001002d00004C42sv00001002sd00004C42*
- ID_MODEL_FROM_DATABASE=Rage LT Pro AGP 2X
+ ID_MODEL_FROM_DATABASE=3D Rage LT PRO AGP 2X (Rage LT Pro AGP 2X)
 
 pci:v00001002d00004C42sv00001002sd00008001*
- ID_MODEL_FROM_DATABASE=Rage LT Pro AGP 2X
+ ID_MODEL_FROM_DATABASE=3D Rage LT PRO AGP 2X (Rage LT Pro AGP 2X)
 
 pci:v00001002d00004C42sv00001028sd00000085*
- ID_MODEL_FROM_DATABASE=Rage 3D LT Pro
+ ID_MODEL_FROM_DATABASE=3D Rage LT PRO AGP 2X (Rage 3D LT Pro)
 
 pci:v00001002d00004C46*
  ID_MODEL_FROM_DATABASE=Rage Mobility 128 AGP 2X/Mobility M3
 
 pci:v00001002d00004C46sv00001002sd00000155*
- ID_MODEL_FROM_DATABASE=IBM Thinkpad A22p
+ ID_MODEL_FROM_DATABASE=Rage Mobility 128 AGP 2X/Mobility M3 (IBM Thinkpad A22p)
 
 pci:v00001002d00004C46sv00001014sd00000155*
- ID_MODEL_FROM_DATABASE=IBM Thinkpad A22p
+ ID_MODEL_FROM_DATABASE=Rage Mobility 128 AGP 2X/Mobility M3 (IBM Thinkpad A22p)
 
 pci:v00001002d00004C46sv00001028sd000000B1*
- ID_MODEL_FROM_DATABASE=Latitude C600
+ ID_MODEL_FROM_DATABASE=Rage Mobility 128 AGP 2X/Mobility M3 (Latitude C600)
 
 pci:v00001002d00004C47*
  ID_MODEL_FROM_DATABASE=3D Rage IIC PCI / Mobility Radeon 7500/7500C
@@ -2901,55 +2952,55 @@ pci:v00001002d00004C49*
  ID_MODEL_FROM_DATABASE=3D Rage LT PRO PCI
 
 pci:v00001002d00004C49sv00001002sd00000004*
- ID_MODEL_FROM_DATABASE=Rage LT Pro
+ ID_MODEL_FROM_DATABASE=3D Rage LT PRO PCI (Rage LT Pro)
 
 pci:v00001002d00004C49sv00001002sd00000040*
- ID_MODEL_FROM_DATABASE=Rage LT Pro
+ ID_MODEL_FROM_DATABASE=3D Rage LT PRO PCI (Rage LT Pro)
 
 pci:v00001002d00004C49sv00001002sd00000044*
- ID_MODEL_FROM_DATABASE=Rage LT Pro
+ ID_MODEL_FROM_DATABASE=3D Rage LT PRO PCI (Rage LT Pro)
 
 pci:v00001002d00004C49sv00001002sd00004C49*
- ID_MODEL_FROM_DATABASE=Rage LT Pro
+ ID_MODEL_FROM_DATABASE=3D Rage LT PRO PCI (Rage LT Pro)
 
 pci:v00001002d00004C4D*
  ID_MODEL_FROM_DATABASE=Rage Mobility AGP 2x Series
 
 pci:v00001002d00004C4Dsv00000E11sd0000B111*
- ID_MODEL_FROM_DATABASE=Armada M700
+ ID_MODEL_FROM_DATABASE=Rage Mobility AGP 2x Series (Armada M700)
 
 pci:v00001002d00004C4Dsv00000E11sd0000B160*
- ID_MODEL_FROM_DATABASE=Armada E500
+ ID_MODEL_FROM_DATABASE=Rage Mobility AGP 2x Series (Armada E500)
 
 pci:v00001002d00004C4Dsv00001002sd00000084*
- ID_MODEL_FROM_DATABASE=Xpert 98 AGP 2X (Mobility)
+ ID_MODEL_FROM_DATABASE=Rage Mobility AGP 2x Series (Xpert 98 AGP 2X (Mobility))
 
 pci:v00001002d00004C4Dsv00001014sd00000154*
- ID_MODEL_FROM_DATABASE=ThinkPad A20m/A21m
+ ID_MODEL_FROM_DATABASE=Rage Mobility AGP 2x Series (ThinkPad A20m/A21m)
 
 pci:v00001002d00004C4Dsv00001028sd000000AA*
- ID_MODEL_FROM_DATABASE=Latitude CPt
+ ID_MODEL_FROM_DATABASE=Rage Mobility AGP 2x Series (Latitude CPt)
 
 pci:v00001002d00004C4Dsv00001028sd000000BB*
- ID_MODEL_FROM_DATABASE=Latitude CPx
+ ID_MODEL_FROM_DATABASE=Rage Mobility AGP 2x Series (Latitude CPx)
 
 pci:v00001002d00004C4Dsv00001179sd0000FF00*
- ID_MODEL_FROM_DATABASE=Satellite 1715XCDS laptop
+ ID_MODEL_FROM_DATABASE=Rage Mobility AGP 2x Series (Satellite 1715XCDS laptop)
 
 pci:v00001002d00004C4Dsv000013BDsd00001019*
- ID_MODEL_FROM_DATABASE=PC-AR10
+ ID_MODEL_FROM_DATABASE=Rage Mobility AGP 2x Series (PC-AR10)
 
 pci:v00001002d00004C50*
  ID_MODEL_FROM_DATABASE=3D Rage LT PRO PCI
 
 pci:v00001002d00004C50sv00001002sd00004C50*
- ID_MODEL_FROM_DATABASE=Rage LT Pro
+ ID_MODEL_FROM_DATABASE=3D Rage LT PRO PCI (Rage LT Pro)
 
 pci:v00001002d00004C52*
  ID_MODEL_FROM_DATABASE=Rage Mobility-M1 PCI
 
 pci:v00001002d00004C52sv00001033sd00008112*
- ID_MODEL_FROM_DATABASE=Versa Note VXi
+ ID_MODEL_FROM_DATABASE=Rage Mobility-M1 PCI (Versa Note VXi)
 
 pci:v00001002d00004C54*
  ID_MODEL_FROM_DATABASE=264LT [Mach64 LT]
@@ -2958,22 +3009,22 @@ pci:v00001002d00004C57*
  ID_MODEL_FROM_DATABASE=RV200/M7 [Mobility Radeon 7500]
 
 pci:v00001002d00004C57sv00001014sd00000517*
- ID_MODEL_FROM_DATABASE=ThinkPad T30
+ ID_MODEL_FROM_DATABASE=RV200/M7 [Mobility Radeon 7500] (ThinkPad T30)
 
 pci:v00001002d00004C57sv00001014sd00000530*
- ID_MODEL_FROM_DATABASE=ThinkPad T42 2373-4WU
+ ID_MODEL_FROM_DATABASE=RV200/M7 [Mobility Radeon 7500] (ThinkPad T4x Series)
 
 pci:v00001002d00004C57sv00001028sd000000E6*
- ID_MODEL_FROM_DATABASE=Radeon Mobility M7 LW (Dell Inspiron 8100)
+ ID_MODEL_FROM_DATABASE=RV200/M7 [Mobility Radeon 7500] (Radeon Mobility M7 LW (Dell Inspiron 8100))
 
 pci:v00001002d00004C57sv00001028sd0000012A*
- ID_MODEL_FROM_DATABASE=Latitude C640
+ ID_MODEL_FROM_DATABASE=RV200/M7 [Mobility Radeon 7500] (Latitude C640)
 
 pci:v00001002d00004C57sv00001043sd00001622*
- ID_MODEL_FROM_DATABASE=Mobility Radeon M7 (L3C/S)
+ ID_MODEL_FROM_DATABASE=RV200/M7 [Mobility Radeon 7500] (Mobility Radeon M7 (L3C/S))
 
 pci:v00001002d00004C57sv0000144Dsd0000C006*
- ID_MODEL_FROM_DATABASE=Radeon Mobility M7 LW in vpr Matrix 170B4
+ ID_MODEL_FROM_DATABASE=RV200/M7 [Mobility Radeon 7500] (Radeon Mobility M7 LW in vpr Matrix 170B4)
 
 pci:v00001002d00004C58*
  ID_MODEL_FROM_DATABASE=RV200/M7 GL [Mobility FireGL 7800]
@@ -2982,31 +3033,31 @@ pci:v00001002d00004C59*
  ID_MODEL_FROM_DATABASE=RV100/M6 [Rage/Radeon Mobility Series]
 
 pci:v00001002d00004C59sv00000E11sd0000B111*
- ID_MODEL_FROM_DATABASE=Evo N600c
+ ID_MODEL_FROM_DATABASE=RV100/M6 [Rage/Radeon Mobility Series] (Evo N600c)
 
 pci:v00001002d00004C59sv00001014sd00000235*
- ID_MODEL_FROM_DATABASE=ThinkPad A30/A30p (2652/2653)
+ ID_MODEL_FROM_DATABASE=RV100/M6 [Rage/Radeon Mobility Series] (ThinkPad A30/A30p (2652/2653))
 
 pci:v00001002d00004C59sv00001014sd00000239*
- ID_MODEL_FROM_DATABASE=ThinkPad X22/X23/X24
+ ID_MODEL_FROM_DATABASE=RV100/M6 [Rage/Radeon Mobility Series] (ThinkPad X22/X23/X24)
 
 pci:v00001002d00004C59sv0000103Csd00000025*
- ID_MODEL_FROM_DATABASE=XE4500 Notebook
+ ID_MODEL_FROM_DATABASE=RV100/M6 [Rage/Radeon Mobility Series] (XE4500 Notebook)
 
 pci:v00001002d00004C59sv0000104Dsd000080E7*
- ID_MODEL_FROM_DATABASE=VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
+ ID_MODEL_FROM_DATABASE=RV100/M6 [Rage/Radeon Mobility Series] (VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP)
 
 pci:v00001002d00004C59sv0000104Dsd00008140*
- ID_MODEL_FROM_DATABASE=PCG-Z1SP laptop
+ ID_MODEL_FROM_DATABASE=RV100/M6 [Rage/Radeon Mobility Series] (PCG-Z1SP laptop)
 
 pci:v00001002d00004C59sv00001509sd00001930*
- ID_MODEL_FROM_DATABASE=Medion MD9703
+ ID_MODEL_FROM_DATABASE=RV100/M6 [Rage/Radeon Mobility Series] (Medion MD9703)
 
 pci:v00001002d00004C66*
  ID_MODEL_FROM_DATABASE=RV250/M9 GL [Mobility FireGL 9000/Radeon 9000]
 
 pci:v00001002d00004C66sv00001014sd0000054D*
- ID_MODEL_FROM_DATABASE=ThinkPad T41
+ ID_MODEL_FROM_DATABASE=RV250/M9 GL [Mobility FireGL 9000/Radeon 9000] (ThinkPad T41)
 
 pci:v00001002d00004C6E*
  ID_MODEL_FROM_DATABASE=RV250/M9 [Mobility Radeon 9000] (Secondary)
@@ -3024,19 +3075,19 @@ pci:v00001002d00004E44*
  ID_MODEL_FROM_DATABASE=R300 [Radeon 9700/9700 PRO]
 
 pci:v00001002d00004E44sv00001002sd0000515E*
- ID_MODEL_FROM_DATABASE=Radeon ES1000
+ ID_MODEL_FROM_DATABASE=R300 [Radeon 9700/9700 PRO] (Radeon ES1000)
 
 pci:v00001002d00004E44sv00001002sd00005965*
- ID_MODEL_FROM_DATABASE=Radeon ES1000
+ ID_MODEL_FROM_DATABASE=R300 [Radeon 9700/9700 PRO] (Radeon ES1000)
 
 pci:v00001002d00004E45*
  ID_MODEL_FROM_DATABASE=R300 [Radeon 9500 PRO/9700]
 
 pci:v00001002d00004E45sv00001002sd00000002*
- ID_MODEL_FROM_DATABASE=Radeon R300 NE [Radeon 9500 Pro]
+ ID_MODEL_FROM_DATABASE=R300 [Radeon 9500 PRO/9700] (Radeon R300 NE [Radeon 9500 Pro])
 
 pci:v00001002d00004E45sv00001681sd00000002*
- ID_MODEL_FROM_DATABASE=Hercules 3D Prophet 9500 PRO [Radeon 9500 Pro]
+ ID_MODEL_FROM_DATABASE=R300 [Radeon 9500 PRO/9700] (Hercules 3D Prophet 9500 PRO [Radeon 9500 Pro])
 
 pci:v00001002d00004E46*
  ID_MODEL_FROM_DATABASE=R300 [Radeon 9600 TX]
@@ -3054,7 +3105,7 @@ pci:v00001002d00004E4A*
  ID_MODEL_FROM_DATABASE=R360 [Radeon 9800 XXL/XT]
 
 pci:v00001002d00004E4Asv00001002sd00004E4A*
- ID_MODEL_FROM_DATABASE=R360 [Radeon 9800 XT]
+ ID_MODEL_FROM_DATABASE=R360 [Radeon 9800 XXL/XT] (R360 [Radeon 9800 XT])
 
 pci:v00001002d00004E4B*
  ID_MODEL_FROM_DATABASE=R350 GL [FireGL X2 AGP Pro]
@@ -3063,22 +3114,22 @@ pci:v00001002d00004E50*
  ID_MODEL_FROM_DATABASE=RV350/M10 [Mobility Radeon 9600 PRO Turbo]
 
 pci:v00001002d00004E50sv00001025sd0000005A*
- ID_MODEL_FROM_DATABASE=TravelMate 290
+ ID_MODEL_FROM_DATABASE=RV350/M10 [Mobility Radeon 9600 PRO Turbo] (TravelMate 290)
 
 pci:v00001002d00004E50sv0000103Csd0000088C*
- ID_MODEL_FROM_DATABASE=NC8000 laptop
+ ID_MODEL_FROM_DATABASE=RV350/M10 [Mobility Radeon 9600 PRO Turbo] (NC8000 laptop)
 
 pci:v00001002d00004E50sv0000103Csd00000890*
- ID_MODEL_FROM_DATABASE=NC6000 laptop
+ ID_MODEL_FROM_DATABASE=RV350/M10 [Mobility Radeon 9600 PRO Turbo] (NC6000 laptop)
 
 pci:v00001002d00004E50sv0000144Dsd0000C00C*
- ID_MODEL_FROM_DATABASE=P35 notebook
+ ID_MODEL_FROM_DATABASE=RV350/M10 [Mobility Radeon 9600 PRO Turbo] (P35 notebook)
 
 pci:v00001002d00004E50sv00001462sd00000311*
- ID_MODEL_FROM_DATABASE=MSI M510A
+ ID_MODEL_FROM_DATABASE=RV350/M10 [Mobility Radeon 9600 PRO Turbo] (MSI M510A)
 
 pci:v00001002d00004E50sv00001734sd00001055*
- ID_MODEL_FROM_DATABASE=Amilo M1420W
+ ID_MODEL_FROM_DATABASE=RV350/M10 [Mobility Radeon 9600 PRO Turbo] (Amilo M1420W)
 
 pci:v00001002d00004E51*
  ID_MODEL_FROM_DATABASE=RV350 [Radeon 9550/9600/X1050 Series]
@@ -3087,7 +3138,7 @@ pci:v00001002d00004E52*
  ID_MODEL_FROM_DATABASE=RV350/M10 [Mobility Radeon 9500/9700 SE]
 
 pci:v00001002d00004E52sv0000144Dsd0000C00C*
- ID_MODEL_FROM_DATABASE=P35 notebook
+ ID_MODEL_FROM_DATABASE=RV350/M10 [Mobility Radeon 9500/9700 SE] (P35 notebook)
 
 pci:v00001002d00004E54*
  ID_MODEL_FROM_DATABASE=RV350/M10 GL [Mobility FireGL T2]
@@ -3102,10 +3153,10 @@ pci:v00001002d00004E65*
  ID_MODEL_FROM_DATABASE=R300 [Radeon 9500 PRO] (Secondary)
 
 pci:v00001002d00004E65sv00001002sd00000003*
- ID_MODEL_FROM_DATABASE=Radeon R300 NE [Radeon 9500 Pro]
+ ID_MODEL_FROM_DATABASE=R300 [Radeon 9500 PRO] (Secondary) (Radeon R300 NE [Radeon 9500 Pro])
 
 pci:v00001002d00004E65sv00001681sd00000003*
- ID_MODEL_FROM_DATABASE=Hercules 3D Prophet 9500 PRO [Radeon 9500 Pro] (Secondary)
+ ID_MODEL_FROM_DATABASE=R300 [Radeon 9500 PRO] (Secondary) (Hercules 3D Prophet 9500 PRO [Radeon 9500 Pro] (Secondary))
 
 pci:v00001002d00004E66*
  ID_MODEL_FROM_DATABASE=RV350 [Radeon 9600] (Secondary)
@@ -3123,10 +3174,10 @@ pci:v00001002d00004E6A*
  ID_MODEL_FROM_DATABASE=RV350 [Radeon 9800 XT] (Secondary)
 
 pci:v00001002d00004E6Asv00001002sd00004E6A*
- ID_MODEL_FROM_DATABASE=R360 [Radeon 9800 XT] (Secondary)
+ ID_MODEL_FROM_DATABASE=RV350 [Radeon 9800 XT] (Secondary) (R360 [Radeon 9800 XT] (Secondary))
 
 pci:v00001002d00004E6Asv00001002sd00004E71*
- ID_MODEL_FROM_DATABASE=M10 NQ [Radeon Mobility 9600]
+ ID_MODEL_FROM_DATABASE=RV350 [Radeon 9800 XT] (Secondary) (M10 NQ [Radeon Mobility 9600])
 
 pci:v00001002d00004E71*
  ID_MODEL_FROM_DATABASE=RV350/M10 [Mobility Radeon 9600] (Secondary)
@@ -3141,46 +3192,46 @@ pci:v00001002d00005044*
  ID_MODEL_FROM_DATABASE=All-In-Wonder 128 PCI
 
 pci:v00001002d00005044sv00001002sd00000028*
- ID_MODEL_FROM_DATABASE=Rage 128 AIW
+ ID_MODEL_FROM_DATABASE=All-In-Wonder 128 PCI (Rage 128 AIW)
 
 pci:v00001002d00005044sv00001002sd00000029*
- ID_MODEL_FROM_DATABASE=Rage 128 AIW
+ ID_MODEL_FROM_DATABASE=All-In-Wonder 128 PCI (Rage 128 AIW)
 
 pci:v00001002d00005046*
  ID_MODEL_FROM_DATABASE=Rage 128 PRO AGP 4x TMDS
 
 pci:v00001002d00005046sv00001002sd00000004*
- ID_MODEL_FROM_DATABASE=Rage Fury Pro
+ ID_MODEL_FROM_DATABASE=Rage 128 PRO AGP 4x TMDS (Rage Fury Pro)
 
 pci:v00001002d00005046sv00001002sd00000008*
- ID_MODEL_FROM_DATABASE=Rage Fury Pro/Xpert 2000 Pro
+ ID_MODEL_FROM_DATABASE=Rage 128 PRO AGP 4x TMDS (Rage Fury Pro/Xpert 2000 Pro)
 
 pci:v00001002d00005046sv00001002sd00000014*
- ID_MODEL_FROM_DATABASE=Rage Fury Pro
+ ID_MODEL_FROM_DATABASE=Rage 128 PRO AGP 4x TMDS (Rage Fury Pro)
 
 pci:v00001002d00005046sv00001002sd00000018*
- ID_MODEL_FROM_DATABASE=Rage Fury Pro/Xpert 2000 Pro
+ ID_MODEL_FROM_DATABASE=Rage 128 PRO AGP 4x TMDS (Rage Fury Pro/Xpert 2000 Pro)
 
 pci:v00001002d00005046sv00001002sd00000028*
- ID_MODEL_FROM_DATABASE=Rage 128 Pro AIW AGP
+ ID_MODEL_FROM_DATABASE=Rage 128 PRO AGP 4x TMDS (Rage 128 Pro AIW AGP)
 
 pci:v00001002d00005046sv00001002sd0000002A*
- ID_MODEL_FROM_DATABASE=Rage 128 Pro AIW AGP
+ ID_MODEL_FROM_DATABASE=Rage 128 PRO AGP 4x TMDS (Rage 128 Pro AIW AGP)
 
 pci:v00001002d00005046sv00001002sd00000048*
- ID_MODEL_FROM_DATABASE=Rage Fury Pro
+ ID_MODEL_FROM_DATABASE=Rage 128 PRO AGP 4x TMDS (Rage Fury Pro)
 
 pci:v00001002d00005046sv00001002sd00002000*
- ID_MODEL_FROM_DATABASE=Rage Fury MAXX AGP 4x (TMDS) (VGA device)
+ ID_MODEL_FROM_DATABASE=Rage 128 PRO AGP 4x TMDS (Rage Fury MAXX AGP 4x (TMDS) (VGA device))
 
 pci:v00001002d00005046sv00001002sd00002001*
- ID_MODEL_FROM_DATABASE=Rage Fury MAXX AGP 4x (TMDS) (Extra device?!)
+ ID_MODEL_FROM_DATABASE=Rage 128 PRO AGP 4x TMDS (Rage Fury MAXX AGP 4x (TMDS) (Extra device?!))
 
 pci:v00001002d00005050*
  ID_MODEL_FROM_DATABASE=Rage128 [Xpert 128 PCI]
 
 pci:v00001002d00005050sv00001002sd00000008*
- ID_MODEL_FROM_DATABASE=Xpert 128
+ ID_MODEL_FROM_DATABASE=Rage128 [Xpert 128 PCI] (Xpert 128)
 
 pci:v00001002d00005052*
  ID_MODEL_FROM_DATABASE=Rage 128 PRO AGP 4X TMDS
@@ -3189,79 +3240,79 @@ pci:v00001002d00005144*
  ID_MODEL_FROM_DATABASE=R100 [Radeon 7200 / All-In-Wonder Radeon]
 
 pci:v00001002d00005144sv00001002sd00000008*
- ID_MODEL_FROM_DATABASE=Radeon 7000/Radeon VE
+ ID_MODEL_FROM_DATABASE=R100 [Radeon 7200 / All-In-Wonder Radeon] (Radeon 7000/Radeon VE)
 
 pci:v00001002d00005144sv00001002sd00000009*
- ID_MODEL_FROM_DATABASE=Radeon 7000/Radeon
+ ID_MODEL_FROM_DATABASE=R100 [Radeon 7200 / All-In-Wonder Radeon] (Radeon 7000/Radeon)
 
 pci:v00001002d00005144sv00001002sd0000000A*
- ID_MODEL_FROM_DATABASE=Radeon 7000/Radeon
+ ID_MODEL_FROM_DATABASE=R100 [Radeon 7200 / All-In-Wonder Radeon] (Radeon 7000/Radeon)
 
 pci:v00001002d00005144sv00001002sd0000001A*
- ID_MODEL_FROM_DATABASE=Radeon 7000/Radeon
+ ID_MODEL_FROM_DATABASE=R100 [Radeon 7200 / All-In-Wonder Radeon] (Radeon 7000/Radeon)
 
 pci:v00001002d00005144sv00001002sd00000029*
- ID_MODEL_FROM_DATABASE=Radeon AIW
+ ID_MODEL_FROM_DATABASE=R100 [Radeon 7200 / All-In-Wonder Radeon] (Radeon AIW)
 
 pci:v00001002d00005144sv00001002sd00000038*
- ID_MODEL_FROM_DATABASE=Radeon 7000/Radeon
+ ID_MODEL_FROM_DATABASE=R100 [Radeon 7200 / All-In-Wonder Radeon] (Radeon 7000/Radeon)
 
 pci:v00001002d00005144sv00001002sd00000039*
- ID_MODEL_FROM_DATABASE=Radeon 7000/Radeon
+ ID_MODEL_FROM_DATABASE=R100 [Radeon 7200 / All-In-Wonder Radeon] (Radeon 7000/Radeon)
 
 pci:v00001002d00005144sv00001002sd0000008A*
- ID_MODEL_FROM_DATABASE=Radeon 7000/Radeon
+ ID_MODEL_FROM_DATABASE=R100 [Radeon 7200 / All-In-Wonder Radeon] (Radeon 7000/Radeon)
 
 pci:v00001002d00005144sv00001002sd000000BA*
- ID_MODEL_FROM_DATABASE=Radeon 7000/Radeon
+ ID_MODEL_FROM_DATABASE=R100 [Radeon 7200 / All-In-Wonder Radeon] (Radeon 7000/Radeon)
 
 pci:v00001002d00005144sv00001002sd00000139*
- ID_MODEL_FROM_DATABASE=Radeon 7000/Radeon
+ ID_MODEL_FROM_DATABASE=R100 [Radeon 7200 / All-In-Wonder Radeon] (Radeon 7000/Radeon)
 
 pci:v00001002d00005144sv00001002sd0000028A*
- ID_MODEL_FROM_DATABASE=Radeon 7000/Radeon
+ ID_MODEL_FROM_DATABASE=R100 [Radeon 7200 / All-In-Wonder Radeon] (Radeon 7000/Radeon)
 
 pci:v00001002d00005144sv00001002sd000002AA*
- ID_MODEL_FROM_DATABASE=Radeon AIW
+ ID_MODEL_FROM_DATABASE=R100 [Radeon 7200 / All-In-Wonder Radeon] (Radeon AIW)
 
 pci:v00001002d00005144sv00001002sd0000053A*
- ID_MODEL_FROM_DATABASE=Radeon 7000/Radeon
+ ID_MODEL_FROM_DATABASE=R100 [Radeon 7200 / All-In-Wonder Radeon] (Radeon 7000/Radeon)
 
 pci:v00001002d00005148*
  ID_MODEL_FROM_DATABASE=R200 GL [FireGL 8800]
 
 pci:v00001002d00005148sv00001002sd0000010A*
- ID_MODEL_FROM_DATABASE=FireGL 8800 64Mb
+ ID_MODEL_FROM_DATABASE=R200 GL [FireGL 8800] (FireGL 8800 64Mb)
 
 pci:v00001002d00005148sv00001002sd00000152*
- ID_MODEL_FROM_DATABASE=FireGL 8800 128Mb
+ ID_MODEL_FROM_DATABASE=R200 GL [FireGL 8800] (FireGL 8800 128Mb)
 
 pci:v00001002d00005148sv00001002sd00000162*
- ID_MODEL_FROM_DATABASE=FireGL 8700 32Mb
+ ID_MODEL_FROM_DATABASE=R200 GL [FireGL 8800] (FireGL 8700 32Mb)
 
 pci:v00001002d00005148sv00001002sd00000172*
- ID_MODEL_FROM_DATABASE=FireGL 8700 64Mb
+ ID_MODEL_FROM_DATABASE=R200 GL [FireGL 8800] (FireGL 8700 64Mb)
 
 pci:v00001002d0000514C*
  ID_MODEL_FROM_DATABASE=R200 [Radeon 8500/8500 LE]
 
 pci:v00001002d0000514Csv00001002sd0000003A*
- ID_MODEL_FROM_DATABASE=Radeon R200 QL [Radeon 8500 LE]
+ ID_MODEL_FROM_DATABASE=R200 [Radeon 8500/8500 LE] (Radeon R200 QL [Radeon 8500 LE])
 
 pci:v00001002d0000514Csv00001002sd0000013A*
- ID_MODEL_FROM_DATABASE=Radeon 8500
+ ID_MODEL_FROM_DATABASE=R200 [Radeon 8500/8500 LE] (Radeon 8500)
 
 pci:v00001002d0000514Csv0000148Csd00002026*
- ID_MODEL_FROM_DATABASE=R200 QL [Radeon 8500 Evil Master II Multi Display Edition]
+ ID_MODEL_FROM_DATABASE=R200 [Radeon 8500/8500 LE] (R200 QL [Radeon 8500 Evil Master II Multi Display Edition])
 
 pci:v00001002d0000514Csv00001681sd00000010*
- ID_MODEL_FROM_DATABASE=Radeon 8500 [3D Prophet 8500 128Mb]
+ ID_MODEL_FROM_DATABASE=R200 [Radeon 8500/8500 LE] (Radeon 8500 [3D Prophet 8500 128Mb])
 
 pci:v00001002d0000514Csv0000174Bsd00007149*
- ID_MODEL_FROM_DATABASE=Radeon 8500 LE
+ ID_MODEL_FROM_DATABASE=R200 [Radeon 8500/8500 LE] (Radeon 8500 LE)
 
 pci:v00001002d0000514Csv00001787sd00000F08*
- ID_MODEL_FROM_DATABASE=Radeon R200 QL [PowerMagic Radeon 8500]
+ ID_MODEL_FROM_DATABASE=R200 [Radeon 8500/8500 LE] (Radeon R200 QL [PowerMagic Radeon 8500])
 
 pci:v00001002d0000514D*
  ID_MODEL_FROM_DATABASE=R200 [Radeon 9100]
@@ -3270,196 +3321,196 @@ pci:v00001002d00005157*
  ID_MODEL_FROM_DATABASE=RV200 [Radeon 7500/7500 LE]
 
 pci:v00001002d00005157sv00001002sd0000013A*
- ID_MODEL_FROM_DATABASE=Radeon 7500
+ ID_MODEL_FROM_DATABASE=RV200 [Radeon 7500/7500 LE] (Radeon 7500)
 
 pci:v00001002d00005157sv00001002sd00000F2B*
- ID_MODEL_FROM_DATABASE=ALL-IN-WONDER VE PCI
+ ID_MODEL_FROM_DATABASE=RV200 [Radeon 7500/7500 LE] (ALL-IN-WONDER VE PCI)
 
 pci:v00001002d00005157sv00001002sd0000103A*
- ID_MODEL_FROM_DATABASE=Dell Optiplex GX260
+ ID_MODEL_FROM_DATABASE=RV200 [Radeon 7500/7500 LE] (Dell Optiplex GX260)
 
 pci:v00001002d00005157sv00001458sd00004000*
- ID_MODEL_FROM_DATABASE=RV200 QW [RADEON 7500 PRO MAYA AR]
+ ID_MODEL_FROM_DATABASE=RV200 [Radeon 7500/7500 LE] (RV200 QW [RADEON 7500 PRO MAYA AR])
 
 pci:v00001002d00005157sv0000148Csd00002024*
- ID_MODEL_FROM_DATABASE=RV200 QW [Radeon 7500LE Dual Display]
+ ID_MODEL_FROM_DATABASE=RV200 [Radeon 7500/7500 LE] (RV200 QW [Radeon 7500LE Dual Display])
 
 pci:v00001002d00005157sv0000148Csd00002025*
- ID_MODEL_FROM_DATABASE=RV200 QW [Radeon 7500 Evil Master Multi Display Edition]
+ ID_MODEL_FROM_DATABASE=RV200 [Radeon 7500/7500 LE] (RV200 QW [Radeon 7500 Evil Master Multi Display Edition])
 
 pci:v00001002d00005157sv0000148Csd00002036*
- ID_MODEL_FROM_DATABASE=RV200 QW [Radeon 7500 PCI Dual Display]
+ ID_MODEL_FROM_DATABASE=RV200 [Radeon 7500/7500 LE] (RV200 QW [Radeon 7500 PCI Dual Display])
 
 pci:v00001002d00005157sv0000174Bsd00007146*
- ID_MODEL_FROM_DATABASE=RV200 QW [Radeon 7500 LE]
+ ID_MODEL_FROM_DATABASE=RV200 [Radeon 7500/7500 LE] (RV200 QW [Radeon 7500 LE])
 
 pci:v00001002d00005157sv0000174Bsd00007147*
- ID_MODEL_FROM_DATABASE=Radeon 7500 LE
+ ID_MODEL_FROM_DATABASE=RV200 [Radeon 7500/7500 LE] (Radeon 7500 LE)
 
 pci:v00001002d00005157sv0000174Bsd00007161*
- ID_MODEL_FROM_DATABASE=Radeon RV200 QW [Radeon 7500 LE]
+ ID_MODEL_FROM_DATABASE=RV200 [Radeon 7500/7500 LE] (Radeon RV200 QW [Radeon 7500 LE])
 
 pci:v00001002d00005157sv000017AFsd00000202*
- ID_MODEL_FROM_DATABASE=RV200 QW [Excalibur Radeon 7500LE]
+ ID_MODEL_FROM_DATABASE=RV200 [Radeon 7500/7500 LE] (RV200 QW [Excalibur Radeon 7500LE])
 
 pci:v00001002d00005159*
  ID_MODEL_FROM_DATABASE=RV100 [Radeon 7000 / Radeon VE]
 
 pci:v00001002d00005159sv00001002sd0000000A*
- ID_MODEL_FROM_DATABASE=Radeon 7000/Radeon VE
+ ID_MODEL_FROM_DATABASE=RV100 [Radeon 7000 / Radeon VE] (Radeon 7000/Radeon VE)
 
 pci:v00001002d00005159sv00001002sd0000000B*
- ID_MODEL_FROM_DATABASE=Radeon 7000
+ ID_MODEL_FROM_DATABASE=RV100 [Radeon 7000 / Radeon VE] (Radeon 7000)
 
 pci:v00001002d00005159sv00001002sd00000038*
- ID_MODEL_FROM_DATABASE=Radeon 7000/Radeon VE
+ ID_MODEL_FROM_DATABASE=RV100 [Radeon 7000 / Radeon VE] (Radeon 7000/Radeon VE)
 
 pci:v00001002d00005159sv00001002sd0000003A*
- ID_MODEL_FROM_DATABASE=Radeon 7000/Radeon VE
+ ID_MODEL_FROM_DATABASE=RV100 [Radeon 7000 / Radeon VE] (Radeon 7000/Radeon VE)
 
 pci:v00001002d00005159sv00001002sd000000BA*
- ID_MODEL_FROM_DATABASE=Radeon 7000/Radeon VE
+ ID_MODEL_FROM_DATABASE=RV100 [Radeon 7000 / Radeon VE] (Radeon 7000/Radeon VE)
 
 pci:v00001002d00005159sv00001002sd0000013A*
- ID_MODEL_FROM_DATABASE=Radeon 7000/Radeon VE
+ ID_MODEL_FROM_DATABASE=RV100 [Radeon 7000 / Radeon VE] (Radeon 7000/Radeon VE)
 
 pci:v00001002d00005159sv00001002sd00000908*
- ID_MODEL_FROM_DATABASE=XVR-100 (supplied by Sun)
+ ID_MODEL_FROM_DATABASE=RV100 [Radeon 7000 / Radeon VE] (XVR-100 (supplied by Sun))
 
 pci:v00001002d00005159sv00001014sd0000029A*
- ID_MODEL_FROM_DATABASE=Remote Supervisor Adapter II (RSA2)
+ ID_MODEL_FROM_DATABASE=RV100 [Radeon 7000 / Radeon VE] (Remote Supervisor Adapter II (RSA2))
 
 pci:v00001002d00005159sv00001014sd000002C8*
- ID_MODEL_FROM_DATABASE=eServer xSeries server mainboard
+ ID_MODEL_FROM_DATABASE=RV100 [Radeon 7000 / Radeon VE] (eServer xSeries server mainboard)
 
 pci:v00001002d00005159sv00001028sd0000016C*
- ID_MODEL_FROM_DATABASE=PowerEdge 1850 Embedded Radeon 7000/VE
+ ID_MODEL_FROM_DATABASE=RV100 [Radeon 7000 / Radeon VE] (PowerEdge 1850 Embedded Radeon 7000/VE)
 
 pci:v00001002d00005159sv00001028sd0000016D*
- ID_MODEL_FROM_DATABASE=PowerEdge 2850 Embedded Radeon 7000-M
+ ID_MODEL_FROM_DATABASE=RV100 [Radeon 7000 / Radeon VE] (PowerEdge 2850 Embedded Radeon 7000-M)
 
 pci:v00001002d00005159sv00001028sd00000170*
- ID_MODEL_FROM_DATABASE=PowerEdge 6850 Embedded Radeon 7000/VE
+ ID_MODEL_FROM_DATABASE=RV100 [Radeon 7000 / Radeon VE] (PowerEdge 6850 Embedded Radeon 7000/VE)
 
 pci:v00001002d00005159sv00001028sd0000019A*
- ID_MODEL_FROM_DATABASE=PowerEdge SC1425
+ ID_MODEL_FROM_DATABASE=RV100 [Radeon 7000 / Radeon VE] (PowerEdge SC1425)
 
 pci:v00001002d00005159sv0000103Csd00001292*
- ID_MODEL_FROM_DATABASE=Radeon 7000
+ ID_MODEL_FROM_DATABASE=RV100 [Radeon 7000 / Radeon VE] (Radeon 7000)
 
 pci:v00001002d00005159sv00001043sd0000C00A*
- ID_MODEL_FROM_DATABASE=A7000/T/64M
+ ID_MODEL_FROM_DATABASE=RV100 [Radeon 7000 / Radeon VE] (A7000/T/64M)
 
 pci:v00001002d00005159sv00001458sd00004002*
- ID_MODEL_FROM_DATABASE=RV100 QY [RADEON 7000 PRO MAYA AV Series]
+ ID_MODEL_FROM_DATABASE=RV100 [Radeon 7000 / Radeon VE] (RV100 QY [RADEON 7000 PRO MAYA AV Series])
 
 pci:v00001002d00005159sv0000148Csd00002003*
- ID_MODEL_FROM_DATABASE=RV100 QY [Radeon 7000 Multi-Display Edition]
+ ID_MODEL_FROM_DATABASE=RV100 [Radeon 7000 / Radeon VE] (RV100 QY [Radeon 7000 Multi-Display Edition])
 
 pci:v00001002d00005159sv0000148Csd00002023*
- ID_MODEL_FROM_DATABASE=RV100 QY [Radeon 7000 Evil Master Multi-Display]
+ ID_MODEL_FROM_DATABASE=RV100 [Radeon 7000 / Radeon VE] (RV100 QY [Radeon 7000 Evil Master Multi-Display])
 
 pci:v00001002d00005159sv0000174Bsd00000280*
- ID_MODEL_FROM_DATABASE=Radeon RV100 QY [Radeon 7000/VE]
+ ID_MODEL_FROM_DATABASE=RV100 [Radeon 7000 / Radeon VE] (Radeon RV100 QY [Radeon 7000/VE])
 
 pci:v00001002d00005159sv0000174Bsd00007112*
- ID_MODEL_FROM_DATABASE=Radeon VE 7000
+ ID_MODEL_FROM_DATABASE=RV100 [Radeon 7000 / Radeon VE] (Radeon VE 7000)
 
 pci:v00001002d00005159sv0000174Bsd00007C28*
- ID_MODEL_FROM_DATABASE=Radeon VE 7000 DDR
+ ID_MODEL_FROM_DATABASE=RV100 [Radeon 7000 / Radeon VE] (Radeon VE 7000 DDR)
 
 pci:v00001002d00005159sv00001787sd00000202*
- ID_MODEL_FROM_DATABASE=RV100 QY [Excalibur Radeon 7000]
+ ID_MODEL_FROM_DATABASE=RV100 [Radeon 7000 / Radeon VE] (RV100 QY [Excalibur Radeon 7000])
 
 pci:v00001002d00005159sv000017EEsd00001001*
- ID_MODEL_FROM_DATABASE=Radeon 7000 64MB DDR + DVI
+ ID_MODEL_FROM_DATABASE=RV100 [Radeon 7000 / Radeon VE] (Radeon 7000 64MB DDR + DVI)
 
 pci:v00001002d0000515E*
  ID_MODEL_FROM_DATABASE=ES1000
 
 pci:v00001002d0000515Esv00001028sd000001BB*
- ID_MODEL_FROM_DATABASE=PowerEdge 1955 Embedded ATI ES1000
+ ID_MODEL_FROM_DATABASE=ES1000 (PowerEdge 1955 Embedded ATI ES1000)
 
 pci:v00001002d0000515Esv00001028sd000001DF*
- ID_MODEL_FROM_DATABASE=PowerEdge SC440
+ ID_MODEL_FROM_DATABASE=ES1000 (PowerEdge SC440)
 
 pci:v00001002d0000515Esv00001028sd000001E6*
- ID_MODEL_FROM_DATABASE=PowerEdge 860
+ ID_MODEL_FROM_DATABASE=ES1000 (PowerEdge 860)
 
 pci:v00001002d0000515Esv00001028sd000001F0*
- ID_MODEL_FROM_DATABASE=PowerEdge R900 Embedded ATI ES1000
+ ID_MODEL_FROM_DATABASE=ES1000 (PowerEdge R900 Embedded ATI ES1000)
 
 pci:v00001002d0000515Esv00001028sd00000205*
- ID_MODEL_FROM_DATABASE=PowerEdge 2970 Embedded ATI ES1000
+ ID_MODEL_FROM_DATABASE=ES1000 (PowerEdge 2970 Embedded ATI ES1000)
 
 pci:v00001002d0000515Esv00001028sd0000020B*
- ID_MODEL_FROM_DATABASE=PowerEdge T605 Embedded ATI ES1000
+ ID_MODEL_FROM_DATABASE=ES1000 (PowerEdge T605 Embedded ATI ES1000)
 
 pci:v00001002d0000515Esv00001028sd0000020F*
- ID_MODEL_FROM_DATABASE=PowerEdge R300 Embedded ATI ES1000
+ ID_MODEL_FROM_DATABASE=ES1000 (PowerEdge R300 Embedded ATI ES1000)
 
 pci:v00001002d0000515Esv00001028sd00000210*
- ID_MODEL_FROM_DATABASE=PowerEdge T300 Embedded ATI ES1000
+ ID_MODEL_FROM_DATABASE=ES1000 (PowerEdge T300 Embedded ATI ES1000)
 
 pci:v00001002d0000515Esv00001028sd00000221*
- ID_MODEL_FROM_DATABASE=PowerEdge R805 Embedded ATI ES1000
+ ID_MODEL_FROM_DATABASE=ES1000 (PowerEdge R805 Embedded ATI ES1000)
 
 pci:v00001002d0000515Esv00001028sd00000223*
- ID_MODEL_FROM_DATABASE=PowerEdge R905 Embedded ATI ES1000
+ ID_MODEL_FROM_DATABASE=ES1000 (PowerEdge R905 Embedded ATI ES1000)
 
 pci:v00001002d0000515Esv00001028sd00000225*
- ID_MODEL_FROM_DATABASE=PowerEdge T105 Embedded ATI ES1000
+ ID_MODEL_FROM_DATABASE=ES1000 (PowerEdge T105 Embedded ATI ES1000)
 
 pci:v00001002d0000515Esv00001028sd0000023C*
- ID_MODEL_FROM_DATABASE=PowerEdge R200 Embedded ATI ES1000
+ ID_MODEL_FROM_DATABASE=ES1000 (PowerEdge R200 Embedded ATI ES1000)
 
 pci:v00001002d0000515Esv0000103Csd00001304*
- ID_MODEL_FROM_DATABASE=Integrity iLO2 Advanced KVM VGA [AD307A]
+ ID_MODEL_FROM_DATABASE=ES1000 (Integrity iLO2 Advanced KVM VGA [AD307A])
 
 pci:v00001002d0000515Esv000015D9sd00008680*
- ID_MODEL_FROM_DATABASE=X7DVL-E-O motherboard
+ ID_MODEL_FROM_DATABASE=ES1000 (X7DVL-E-O motherboard)
 
 pci:v00001002d0000515Esv000015D9sd00009680*
- ID_MODEL_FROM_DATABASE=X7DBN Motherboard
+ ID_MODEL_FROM_DATABASE=ES1000 (X7DBN Motherboard)
 
 pci:v00001002d0000515Esv00008086sd00003476*
- ID_MODEL_FROM_DATABASE=S5000PSLSATA Server Board
+ ID_MODEL_FROM_DATABASE=ES1000 (S5000PSLSATA Server Board)
 
 pci:v00001002d00005245*
  ID_MODEL_FROM_DATABASE=Rage 128 GL PCI
 
 pci:v00001002d00005245sv00001002sd00000008*
- ID_MODEL_FROM_DATABASE=Xpert 128
+ ID_MODEL_FROM_DATABASE=Rage 128 GL PCI (Xpert 128)
 
 pci:v00001002d00005245sv00001002sd00000028*
- ID_MODEL_FROM_DATABASE=Rage 128 AIW
+ ID_MODEL_FROM_DATABASE=Rage 128 GL PCI (Rage 128 AIW)
 
 pci:v00001002d00005245sv00001002sd00000029*
- ID_MODEL_FROM_DATABASE=Rage 128 AIW
+ ID_MODEL_FROM_DATABASE=Rage 128 GL PCI (Rage 128 AIW)
 
 pci:v00001002d00005245sv00001002sd00000068*
- ID_MODEL_FROM_DATABASE=Rage 128 AIW
+ ID_MODEL_FROM_DATABASE=Rage 128 GL PCI (Rage 128 AIW)
 
 pci:v00001002d00005246*
  ID_MODEL_FROM_DATABASE=Rage Fury/Xpert 128/Xpert 2000 AGP 2x
 
 pci:v00001002d00005246sv00001002sd00000004*
- ID_MODEL_FROM_DATABASE=Magnum/Xpert 128/Xpert 99
+ ID_MODEL_FROM_DATABASE=Rage Fury/Xpert 128/Xpert 2000 AGP 2x (Magnum/Xpert 128/Xpert 99)
 
 pci:v00001002d00005246sv00001002sd00000008*
- ID_MODEL_FROM_DATABASE=Magnum/Xpert128/X99/Xpert2000
+ ID_MODEL_FROM_DATABASE=Rage Fury/Xpert 128/Xpert 2000 AGP 2x (Magnum/Xpert128/X99/Xpert2000)
 
 pci:v00001002d00005246sv00001002sd00000028*
- ID_MODEL_FROM_DATABASE=Rage 128 AIW AGP
+ ID_MODEL_FROM_DATABASE=Rage Fury/Xpert 128/Xpert 2000 AGP 2x (Rage 128 AIW AGP)
 
 pci:v00001002d00005246sv00001002sd00000044*
- ID_MODEL_FROM_DATABASE=Rage Fury/Xpert 128/Xpert 2000
+ ID_MODEL_FROM_DATABASE=Rage Fury/Xpert 128/Xpert 2000 AGP 2x (Rage Fury/Xpert 128/Xpert 2000)
 
 pci:v00001002d00005246sv00001002sd00000068*
- ID_MODEL_FROM_DATABASE=Rage 128 AIW AGP
+ ID_MODEL_FROM_DATABASE=Rage Fury/Xpert 128/Xpert 2000 AGP 2x (Rage 128 AIW AGP)
 
 pci:v00001002d00005246sv00001002sd00000448*
- ID_MODEL_FROM_DATABASE=Rage Fury
+ ID_MODEL_FROM_DATABASE=Rage Fury/Xpert 128/Xpert 2000 AGP 2x (Rage Fury)
 
 pci:v00001002d0000524B*
  ID_MODEL_FROM_DATABASE=Rage 128 VR PCI
@@ -3468,73 +3519,73 @@ pci:v00001002d0000524C*
  ID_MODEL_FROM_DATABASE=Rage 128 VR AGP
 
 pci:v00001002d0000524Csv00001002sd00000008*
- ID_MODEL_FROM_DATABASE=Xpert 99/Xpert 2000
+ ID_MODEL_FROM_DATABASE=Rage 128 VR AGP (Xpert 99/Xpert 2000)
 
 pci:v00001002d0000524Csv00001002sd00000088*
- ID_MODEL_FROM_DATABASE=Xpert 99
+ ID_MODEL_FROM_DATABASE=Rage 128 VR AGP (Xpert 99)
 
 pci:v00001002d00005346*
  ID_MODEL_FROM_DATABASE=Rage 128 SF/4x AGP 2x
 
 pci:v00001002d00005346sv00001002sd00000048*
- ID_MODEL_FROM_DATABASE=RAGE 128 16MB VGA TVOUT AMC PAL
+ ID_MODEL_FROM_DATABASE=Rage 128 SF/4x AGP 2x (RAGE 128 16MB VGA TVOUT AMC PAL)
 
 pci:v00001002d0000534D*
  ID_MODEL_FROM_DATABASE=Rage 128 4X AGP 4x
 
 pci:v00001002d0000534Dsv00001002sd00000008*
- ID_MODEL_FROM_DATABASE=Xpert 99/Xpert 2000
+ ID_MODEL_FROM_DATABASE=Rage 128 4X AGP 4x (Xpert 99/Xpert 2000)
 
 pci:v00001002d0000534Dsv00001002sd00000018*
- ID_MODEL_FROM_DATABASE=Xpert 2000
+ ID_MODEL_FROM_DATABASE=Rage 128 4X AGP 4x (Xpert 2000)
 
 pci:v00001002d00005354*
  ID_MODEL_FROM_DATABASE=Mach 64 VT
 
 pci:v00001002d00005354sv00001002sd00005654*
- ID_MODEL_FROM_DATABASE=Mach 64 reference
+ ID_MODEL_FROM_DATABASE=Mach 64 VT (Mach 64 reference)
 
 pci:v00001002d00005446*
  ID_MODEL_FROM_DATABASE=Rage 128 PRO Ultra AGP 4x
 
 pci:v00001002d00005446sv00001002sd00000004*
- ID_MODEL_FROM_DATABASE=Rage Fury Pro
+ ID_MODEL_FROM_DATABASE=Rage 128 PRO Ultra AGP 4x (Rage Fury Pro)
 
 pci:v00001002d00005446sv00001002sd00000008*
- ID_MODEL_FROM_DATABASE=Rage Fury Pro/Xpert 2000 Pro
+ ID_MODEL_FROM_DATABASE=Rage 128 PRO Ultra AGP 4x (Rage Fury Pro/Xpert 2000 Pro)
 
 pci:v00001002d00005446sv00001002sd00000018*
- ID_MODEL_FROM_DATABASE=Rage Fury Pro/Xpert 2000 Pro
+ ID_MODEL_FROM_DATABASE=Rage 128 PRO Ultra AGP 4x (Rage Fury Pro/Xpert 2000 Pro)
 
 pci:v00001002d00005446sv00001002sd00000028*
- ID_MODEL_FROM_DATABASE=Rage 128 AIW Pro AGP
+ ID_MODEL_FROM_DATABASE=Rage 128 PRO Ultra AGP 4x (Rage 128 AIW Pro AGP)
 
 pci:v00001002d00005446sv00001002sd00000029*
- ID_MODEL_FROM_DATABASE=Rage 128 AIW
+ ID_MODEL_FROM_DATABASE=Rage 128 PRO Ultra AGP 4x (Rage 128 AIW)
 
 pci:v00001002d00005446sv00001002sd0000002A*
- ID_MODEL_FROM_DATABASE=Rage 128 AIW Pro AGP
+ ID_MODEL_FROM_DATABASE=Rage 128 PRO Ultra AGP 4x (Rage 128 AIW Pro AGP)
 
 pci:v00001002d00005446sv00001002sd0000002B*
- ID_MODEL_FROM_DATABASE=Rage 128 AIW
+ ID_MODEL_FROM_DATABASE=Rage 128 PRO Ultra AGP 4x (Rage 128 AIW)
 
 pci:v00001002d00005446sv00001002sd00000048*
- ID_MODEL_FROM_DATABASE=Xpert 2000 Pro
+ ID_MODEL_FROM_DATABASE=Rage 128 PRO Ultra AGP 4x (Xpert 2000 Pro)
 
 pci:v00001002d00005452*
  ID_MODEL_FROM_DATABASE=Rage 128 PRO Ultra4XL VR-R AGP
 
 pci:v00001002d00005452sv00001002sd0000001C*
- ID_MODEL_FROM_DATABASE=Rage 128 Pro 4XL
+ ID_MODEL_FROM_DATABASE=Rage 128 PRO Ultra4XL VR-R AGP (Rage 128 Pro 4XL)
 
 pci:v00001002d00005452sv0000103Csd00001279*
- ID_MODEL_FROM_DATABASE=Rage 128 Pro 4XL
+ ID_MODEL_FROM_DATABASE=Rage 128 PRO Ultra4XL VR-R AGP (Rage 128 Pro 4XL)
 
 pci:v00001002d00005460*
  ID_MODEL_FROM_DATABASE=RV370/M22 [Mobility Radeon X300]
 
 pci:v00001002d00005460sv00001775sd00001100*
- ID_MODEL_FROM_DATABASE=CR11/VR11 Single Board Computer
+ ID_MODEL_FROM_DATABASE=RV370/M22 [Mobility Radeon X300] (CR11/VR11 Single Board Computer)
 
 pci:v00001002d00005461*
  ID_MODEL_FROM_DATABASE=RV370/M22 [Mobility Radeon X300]
@@ -3555,16 +3606,16 @@ pci:v00001002d0000554B*
  ID_MODEL_FROM_DATABASE=R423 [Radeon X800 GT/SE]
 
 pci:v00001002d0000554Bsv00001002sd00000302*
- ID_MODEL_FROM_DATABASE=Radeon X800 SE
+ ID_MODEL_FROM_DATABASE=R423 [Radeon X800 GT/SE] (Radeon X800 SE)
 
 pci:v00001002d0000554D*
  ID_MODEL_FROM_DATABASE=R430 [Radeon X800 XL]
 
 pci:v00001002d0000554Dsv00001002sd00000322*
- ID_MODEL_FROM_DATABASE=All-In-Wonder X800 XL
+ ID_MODEL_FROM_DATABASE=R430 [Radeon X800 XL] (All-In-Wonder X800 XL)
 
 pci:v00001002d0000554Dsv00001458sd00002124*
- ID_MODEL_FROM_DATABASE=GV-R80L256V-B (AGP)
+ ID_MODEL_FROM_DATABASE=R430 [Radeon X800 XL] (GV-R80L256V-B (AGP))
 
 pci:v00001002d0000554E*
  ID_MODEL_FROM_DATABASE=R430 [All-In-Wonder X800 GT]
@@ -3588,7 +3639,7 @@ pci:v00001002d0000556D*
  ID_MODEL_FROM_DATABASE=R430 [Radeon X800 XL] (Secondary)
 
 pci:v00001002d0000556Dsv00001458sd00002125*
- ID_MODEL_FROM_DATABASE=GV-R80L256V-B (AGP)
+ ID_MODEL_FROM_DATABASE=R430 [Radeon X800 XL] (Secondary) (GV-R80L256V-B (AGP))
 
 pci:v00001002d0000556F*
  ID_MODEL_FROM_DATABASE=R430 [Radeon X800] (Secondary)
@@ -3609,16 +3660,16 @@ pci:v00001002d00005653*
  ID_MODEL_FROM_DATABASE=RV410/M26 [Mobility Radeon X700]
 
 pci:v00001002d00005653sv00001025sd00000080*
- ID_MODEL_FROM_DATABASE=Aspire 5024WLMi
+ ID_MODEL_FROM_DATABASE=RV410/M26 [Mobility Radeon X700] (Aspire 5024WLMi)
 
 pci:v00001002d00005653sv0000103Csd00000940*
- ID_MODEL_FROM_DATABASE=HP Compaq NW8240 Mobile Workstation
+ ID_MODEL_FROM_DATABASE=RV410/M26 [Mobility Radeon X700] (HP Compaq NW8240 Mobile Workstation)
 
 pci:v00001002d00005654*
  ID_MODEL_FROM_DATABASE=264VT [Mach64 VT]
 
 pci:v00001002d00005654sv00001002sd00005654*
- ID_MODEL_FROM_DATABASE=Mach64VT Reference
+ ID_MODEL_FROM_DATABASE=264VT [Mach64 VT] (Mach64VT Reference)
 
 pci:v00001002d00005655*
  ID_MODEL_FROM_DATABASE=264VT3 [Mach64 VT3]
@@ -3660,22 +3711,22 @@ pci:v00001002d00005940*
  ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200 PRO] (Secondary)
 
 pci:v00001002d00005940sv000017AFsd00002021*
- ID_MODEL_FROM_DATABASE=Excalibur Radeon 9250 (Secondary)
+ ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200 PRO] (Secondary) (Excalibur Radeon 9250 (Secondary))
 
 pci:v00001002d00005941*
  ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200] (Secondary)
 
 pci:v00001002d00005941sv00001458sd00004019*
- ID_MODEL_FROM_DATABASE=Radeon 9200
+ ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200] (Secondary) (Radeon 9200)
 
 pci:v00001002d00005941sv0000174Bsd00007C12*
- ID_MODEL_FROM_DATABASE=Radeon 9200
+ ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200] (Secondary) (Radeon 9200)
 
 pci:v00001002d00005941sv000017AFsd0000200D*
- ID_MODEL_FROM_DATABASE=Excalibur Radeon 9200
+ ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200] (Secondary) (Excalibur Radeon 9200)
 
 pci:v00001002d00005941sv000018BCsd00000050*
- ID_MODEL_FROM_DATABASE=GC-R9200-C3 (Secondary)
+ ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200] (Secondary) (GC-R9200-C3 (Secondary))
 
 pci:v00001002d00005944*
  ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200 SE PCI]
@@ -3684,22 +3735,22 @@ pci:v00001002d00005950*
  ID_MODEL_FROM_DATABASE=RS480/RS482/RS485 Host Bridge
 
 pci:v00001002d00005950sv00001025sd00000080*
- ID_MODEL_FROM_DATABASE=Aspire 5024WLMMi
+ ID_MODEL_FROM_DATABASE=RS480/RS482/RS485 Host Bridge (Aspire 5024WLMMi)
 
 pci:v00001002d00005950sv0000103Csd0000280A*
- ID_MODEL_FROM_DATABASE=DC5750 Microtower
+ ID_MODEL_FROM_DATABASE=RS480/RS482/RS485 Host Bridge (DC5750 Microtower)
 
 pci:v00001002d00005950sv0000103Csd00002A20*
- ID_MODEL_FROM_DATABASE=Pavilion t3030.de Desktop PC
+ ID_MODEL_FROM_DATABASE=RS480/RS482/RS485 Host Bridge (Pavilion t3030.de Desktop PC)
 
 pci:v00001002d00005950sv0000103Csd0000308B*
- ID_MODEL_FROM_DATABASE=MX6125
+ ID_MODEL_FROM_DATABASE=RS480/RS482/RS485 Host Bridge (MX6125)
 
 pci:v00001002d00005950sv00001462sd00000131*
- ID_MODEL_FROM_DATABASE=MS-1013 Notebook
+ ID_MODEL_FROM_DATABASE=RS480/RS482/RS485 Host Bridge (MS-1013 Notebook)
 
 pci:v00001002d00005950sv00001462sd00007217*
- ID_MODEL_FROM_DATABASE=Aspire L250
+ ID_MODEL_FROM_DATABASE=RS480/RS482/RS485 Host Bridge (Aspire L250)
 
 pci:v00001002d00005951*
  ID_MODEL_FROM_DATABASE=RX480/RX482 Host Bridge
@@ -3711,19 +3762,19 @@ pci:v00001002d00005954*
  ID_MODEL_FROM_DATABASE=RS480 [Radeon Xpress 200 Series]
 
 pci:v00001002d00005954sv00001002sd00005954*
- ID_MODEL_FROM_DATABASE=RV370 [Radeon Xpress 200G Series]
+ ID_MODEL_FROM_DATABASE=RS480 [Radeon Xpress 200 Series] (RV370 [Radeon Xpress 200G Series])
 
 pci:v00001002d00005955*
  ID_MODEL_FROM_DATABASE=RS480M [Mobility Radeon Xpress 200]
 
 pci:v00001002d00005955sv00001002sd00005955*
- ID_MODEL_FROM_DATABASE=RS480 0x5955 [Radeon XPRESS 200M 5955 (PCIE)]
+ ID_MODEL_FROM_DATABASE=RS480M [Mobility Radeon Xpress 200] (RS480 0x5955 [Radeon XPRESS 200M 5955 (PCIE)])
 
 pci:v00001002d00005955sv0000103Csd0000308B*
- ID_MODEL_FROM_DATABASE=MX6125
+ ID_MODEL_FROM_DATABASE=RS480M [Mobility Radeon Xpress 200] (MX6125)
 
 pci:v00001002d00005955sv00001462sd00000131*
- ID_MODEL_FROM_DATABASE=MS-1013 Notebook
+ ID_MODEL_FROM_DATABASE=RS480M [Mobility Radeon Xpress 200] (MS-1013 Notebook)
 
 pci:v00001002d00005956*
  ID_MODEL_FROM_DATABASE=RD790 Host Bridge
@@ -3732,7 +3783,7 @@ pci:v00001002d00005957*
  ID_MODEL_FROM_DATABASE=RX780/RX790 Host Bridge
 
 pci:v00001002d00005957sv00001849sd00005957*
- ID_MODEL_FROM_DATABASE=A770CrossFire Motherboard
+ ID_MODEL_FROM_DATABASE=RX780/RX790 Host Bridge (A770CrossFire Motherboard)
 
 pci:v00001002d00005958*
  ID_MODEL_FROM_DATABASE=RD780 Host Bridge
@@ -3741,37 +3792,37 @@ pci:v00001002d00005960*
  ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200 PRO]
 
 pci:v00001002d00005960sv000017AFsd00002020*
- ID_MODEL_FROM_DATABASE=Excalibur Radeon 9250
+ ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200 PRO] (Excalibur Radeon 9250)
 
 pci:v00001002d00005961*
  ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200]
 
 pci:v00001002d00005961sv00001002sd00002F72*
- ID_MODEL_FROM_DATABASE=All-in-Wonder 9200 Series
+ ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200] (All-in-Wonder 9200 Series)
 
 pci:v00001002d00005961sv00001019sd00004C30*
- ID_MODEL_FROM_DATABASE=Radeon 9200 VIVO
+ ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200] (Radeon 9200 VIVO)
 
 pci:v00001002d00005961sv000012ABsd00005961*
- ID_MODEL_FROM_DATABASE=YUAN SMARTVGA Radeon 9200
+ ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200] (YUAN SMARTVGA Radeon 9200)
 
 pci:v00001002d00005961sv00001458sd00004018*
- ID_MODEL_FROM_DATABASE=Radeon 9200
+ ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200] (Radeon 9200)
 
 pci:v00001002d00005961sv0000174Bsd00007C13*
- ID_MODEL_FROM_DATABASE=Radeon 9200
+ ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200] (Radeon 9200)
 
 pci:v00001002d00005961sv000017AFsd0000200C*
- ID_MODEL_FROM_DATABASE=Excalibur Radeon 9200
+ ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200] (Excalibur Radeon 9200)
 
 pci:v00001002d00005961sv000018BCsd00000050*
- ID_MODEL_FROM_DATABASE=Radeon 9200 Game Buster
+ ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200] (Radeon 9200 Game Buster)
 
 pci:v00001002d00005961sv000018BCsd00000051*
- ID_MODEL_FROM_DATABASE=GC-R9200-C3
+ ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200] (GC-R9200-C3)
 
 pci:v00001002d00005961sv000018BCsd00000053*
- ID_MODEL_FROM_DATABASE=Radeon 9200 Game Buster VIVO
+ ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200] (Radeon 9200 Game Buster VIVO)
 
 pci:v00001002d00005962*
  ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200]
@@ -3780,37 +3831,37 @@ pci:v00001002d00005964*
  ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200 SE]
 
 pci:v00001002d00005964sv00001002sd00005964*
- ID_MODEL_FROM_DATABASE=Radeon 9200 SE, 64-bit 128MB DDR, 200/166MHz
+ ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200 SE] (Radeon 9200 SE, 64-bit 128MB DDR, 200/166MHz)
 
 pci:v00001002d00005964sv00001043sd0000C006*
- ID_MODEL_FROM_DATABASE=Radeon 9200 SE / TD / 128M
+ ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200 SE] (Radeon 9200 SE / TD / 128M)
 
 pci:v00001002d00005964sv00001458sd00004018*
- ID_MODEL_FROM_DATABASE=Radeon 9200 SE
+ ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200 SE] (Radeon 9200 SE)
 
 pci:v00001002d00005964sv00001458sd00004032*
- ID_MODEL_FROM_DATABASE=Radeon 9200 SE 128MB
+ ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200 SE] (Radeon 9200 SE 128MB)
 
 pci:v00001002d00005964sv0000147Bsd00006191*
- ID_MODEL_FROM_DATABASE=R9200SE-DT
+ ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200 SE] (R9200SE-DT)
 
 pci:v00001002d00005964sv0000148Csd00002073*
- ID_MODEL_FROM_DATABASE=CN-AG92E
+ ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200 SE] (CN-AG92E)
 
 pci:v00001002d00005964sv0000174Bsd00007C13*
- ID_MODEL_FROM_DATABASE=Radeon 9200 SE
+ ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200 SE] (Radeon 9200 SE)
 
 pci:v00001002d00005964sv00001787sd00005964*
- ID_MODEL_FROM_DATABASE=Excalibur 9200SE VIVO 128M
+ ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200 SE] (Excalibur 9200SE VIVO 128M)
 
 pci:v00001002d00005964sv000017AFsd00002012*
- ID_MODEL_FROM_DATABASE=Radeon 9200 SE Excalibur
+ ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200 SE] (Radeon 9200 SE Excalibur)
 
 pci:v00001002d00005964sv000018BCsd00000170*
- ID_MODEL_FROM_DATABASE=Sapphire Radeon 9200 SE 128MB Game Buster
+ ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200 SE] (Sapphire Radeon 9200 SE 128MB Game Buster)
 
 pci:v00001002d00005964sv000018BCsd00000173*
- ID_MODEL_FROM_DATABASE=GC-R9200L(SE)-C3H [Radeon 9200 Game Buster]
+ ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200 SE] (GC-R9200L(SE)-C3H [Radeon 9200 Game Buster])
 
 pci:v00001002d00005965*
  ID_MODEL_FROM_DATABASE=RV280 GL [FireMV 2200 PCI]
@@ -3819,10 +3870,10 @@ pci:v00001002d00005974*
  ID_MODEL_FROM_DATABASE=RS482/RS485 [Radeon Xpress 1100/1150]
 
 pci:v00001002d00005974sv0000103Csd0000280A*
- ID_MODEL_FROM_DATABASE=DC5750 Microtower
+ ID_MODEL_FROM_DATABASE=RS482/RS485 [Radeon Xpress 1100/1150] (DC5750 Microtower)
 
 pci:v00001002d00005974sv00001462sd00007141*
- ID_MODEL_FROM_DATABASE=Aspire L250
+ ID_MODEL_FROM_DATABASE=RS482/RS485 [Radeon Xpress 1100/1150] (Aspire L250)
 
 pci:v00001002d00005975*
  ID_MODEL_FROM_DATABASE=RS482M [Mobility Radeon Xpress 200]
@@ -3831,7 +3882,7 @@ pci:v00001002d00005978*
  ID_MODEL_FROM_DATABASE=RX780/RD790 PCI to PCI bridge (external gfx0 port A)
 
 pci:v00001002d00005978sv00001849sd00005957*
- ID_MODEL_FROM_DATABASE=A770CrossFire Motherboard
+ ID_MODEL_FROM_DATABASE=RX780/RD790 PCI to PCI bridge (external gfx0 port A) (A770CrossFire Motherboard)
 
 pci:v00001002d00005979*
  ID_MODEL_FROM_DATABASE=RD790 PCI to PCI bridge (external gfx0 port B)
@@ -3852,13 +3903,13 @@ pci:v00001002d0000597E*
  ID_MODEL_FROM_DATABASE=RD790 PCI to PCI bridge (PCI express gpp port E)
 
 pci:v00001002d0000597Esv00001849sd00005957*
- ID_MODEL_FROM_DATABASE=A770CrossFire Motherboard
+ ID_MODEL_FROM_DATABASE=RD790 PCI to PCI bridge (PCI express gpp port E) (A770CrossFire Motherboard)
 
 pci:v00001002d0000597F*
  ID_MODEL_FROM_DATABASE=RD790 PCI to PCI bridge (PCI express gpp port F)
 
 pci:v00001002d0000597Fsv00001849sd00005957*
- ID_MODEL_FROM_DATABASE=A770CrossFire Motherboard
+ ID_MODEL_FROM_DATABASE=RD790 PCI to PCI bridge (PCI express gpp port F) (A770CrossFire Motherboard)
 
 pci:v00001002d00005980*
  ID_MODEL_FROM_DATABASE=RD790 PCI to PCI bridge (external gfx1 port A)
@@ -3879,7 +3930,7 @@ pci:v00001002d00005A12*
  ID_MODEL_FROM_DATABASE=RD890 Northbridge only dual slot (2x8) PCI-e GFX Hydra part
 
 pci:v00001002d00005A12sv000015D9sd0000A811*
- ID_MODEL_FROM_DATABASE=H8DGU
+ ID_MODEL_FROM_DATABASE=RD890 Northbridge only dual slot (2x8) PCI-e GFX Hydra part (H8DGU)
 
 pci:v00001002d00005A13*
  ID_MODEL_FROM_DATABASE=RD890 PCI to PCI bridge (external gfx0 port A)
@@ -3900,7 +3951,7 @@ pci:v00001002d00005A18*
  ID_MODEL_FROM_DATABASE=RD890 PCI to PCI bridge (PCI express gpp port D)
 
 pci:v00001002d00005A18sv000015D9sd0000A811*
- ID_MODEL_FROM_DATABASE=H8DGU
+ ID_MODEL_FROM_DATABASE=RD890 PCI to PCI bridge (PCI express gpp port D) (H8DGU)
 
 pci:v00001002d00005A19*
  ID_MODEL_FROM_DATABASE=RD890 PCI to PCI bridge (PCI express gpp port E)
@@ -3924,7 +3975,7 @@ pci:v00001002d00005A1F*
  ID_MODEL_FROM_DATABASE=RD890 PCI to PCI bridge (NB-SB link)
 
 pci:v00001002d00005A1Fsv000015D9sd0000A811*
- ID_MODEL_FROM_DATABASE=H8DGU
+ ID_MODEL_FROM_DATABASE=RD890 PCI to PCI bridge (NB-SB link) (H8DGU)
 
 pci:v00001002d00005A20*
  ID_MODEL_FROM_DATABASE=RD890S PCI Express bridge for GPP2 port 1
@@ -3957,7 +4008,7 @@ pci:v00001002d00005A3F*
  ID_MODEL_FROM_DATABASE=RC4xx/RS4xx PCI Bridge [int gfx]
 
 pci:v00001002d00005A3Fsv00001462sd00007217*
- ID_MODEL_FROM_DATABASE=Aspire L250
+ ID_MODEL_FROM_DATABASE=RC4xx/RS4xx PCI Bridge [int gfx] (Aspire L250)
 
 pci:v00001002d00005A41*
  ID_MODEL_FROM_DATABASE=RS400 [Radeon Xpress 200]
@@ -3975,25 +4026,25 @@ pci:v00001002d00005B60*
  ID_MODEL_FROM_DATABASE=RV370 [Radeon X300]
 
 pci:v00001002d00005B60sv00001043sd0000002A*
- ID_MODEL_FROM_DATABASE=Extreme AX300SE-X
+ ID_MODEL_FROM_DATABASE=RV370 [Radeon X300] (Extreme AX300SE-X)
 
 pci:v00001002d00005B60sv00001043sd0000032E*
- ID_MODEL_FROM_DATABASE=Extreme AX300/TD
+ ID_MODEL_FROM_DATABASE=RV370 [Radeon X300] (Extreme AX300/TD)
 
 pci:v00001002d00005B60sv00001458sd00002102*
- ID_MODEL_FROM_DATABASE=GV-RX30S128D (X300SE)
+ ID_MODEL_FROM_DATABASE=RV370 [Radeon X300] (GV-RX30S128D (X300SE))
 
 pci:v00001002d00005B60sv00001462sd00000400*
- ID_MODEL_FROM_DATABASE=RX300SE-TD128E (MS-8940 REV:200)
+ ID_MODEL_FROM_DATABASE=RV370 [Radeon X300] (RX300SE-TD128E (MS-8940 REV:200))
 
 pci:v00001002d00005B60sv00001462sd00000402*
- ID_MODEL_FROM_DATABASE=RX300SE-TD128E (MS-8940)
+ ID_MODEL_FROM_DATABASE=RV370 [Radeon X300] (RX300SE-TD128E (MS-8940))
 
 pci:v00001002d00005B60sv0000174Bsd00000500*
- ID_MODEL_FROM_DATABASE=Radeon X300 (PCIE)
+ ID_MODEL_FROM_DATABASE=RV370 [Radeon X300] (Radeon X300 (PCIE))
 
 pci:v00001002d00005B60sv0000196Dsd00001086*
- ID_MODEL_FROM_DATABASE=X300SE HM
+ ID_MODEL_FROM_DATABASE=RV370 [Radeon X300] (X300SE HM)
 
 pci:v00001002d00005B62*
  ID_MODEL_FROM_DATABASE=RV370 [Radeon X600/X600 SE]
@@ -4014,13 +4065,13 @@ pci:v00001002d00005B70*
  ID_MODEL_FROM_DATABASE=RV370 [Radeon X300 SE]
 
 pci:v00001002d00005B70sv00001462sd00000403*
- ID_MODEL_FROM_DATABASE=Radeon X300 SE 128MB DDR
+ ID_MODEL_FROM_DATABASE=RV370 [Radeon X300 SE] (Radeon X300 SE 128MB DDR)
 
 pci:v00001002d00005B70sv0000174Bsd00000501*
- ID_MODEL_FROM_DATABASE=Radeon X300 SE
+ ID_MODEL_FROM_DATABASE=RV370 [Radeon X300 SE] (Radeon X300 SE)
 
 pci:v00001002d00005B70sv0000196Dsd00001087*
- ID_MODEL_FROM_DATABASE=Radeon X300 SE HyperMemory
+ ID_MODEL_FROM_DATABASE=RV370 [Radeon X300 SE] (Radeon X300 SE HyperMemory)
 
 pci:v00001002d00005B72*
  ID_MODEL_FROM_DATABASE=RV380 [Radeon X300/X550/X1050 Series] (Secondary)
@@ -4041,37 +4092,37 @@ pci:v00001002d00005C63*
  ID_MODEL_FROM_DATABASE=RV280/M9+ [Mobility Radeon 9200 AGP]
 
 pci:v00001002d00005C63sv00001002sd00005C63*
- ID_MODEL_FROM_DATABASE=Apple iBook G4 2004
+ ID_MODEL_FROM_DATABASE=RV280/M9+ [Mobility Radeon 9200 AGP] (Apple iBook G4 2004)
 
 pci:v00001002d00005C63sv0000144Dsd0000C00C*
- ID_MODEL_FROM_DATABASE=P30 notebook
+ ID_MODEL_FROM_DATABASE=RV280/M9+ [Mobility Radeon 9200 AGP] (P30 notebook)
 
 pci:v00001002d00005D44*
  ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200 SE] (Secondary)
 
 pci:v00001002d00005D44sv00001458sd00004019*
- ID_MODEL_FROM_DATABASE=Radeon 9200 SE (Secondary)
+ ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200 SE] (Secondary) (Radeon 9200 SE (Secondary))
 
 pci:v00001002d00005D44sv00001458sd00004032*
- ID_MODEL_FROM_DATABASE=Radeon 9200 SE 128MB
+ ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200 SE] (Secondary) (Radeon 9200 SE 128MB)
 
 pci:v00001002d00005D44sv0000147Bsd00006190*
- ID_MODEL_FROM_DATABASE=R9200SE-DT (Secondary)
+ ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200 SE] (Secondary) (R9200SE-DT (Secondary))
 
 pci:v00001002d00005D44sv0000174Bsd00007C12*
- ID_MODEL_FROM_DATABASE=Radeon 9200 SE (Secondary)
+ ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200 SE] (Secondary) (Radeon 9200 SE (Secondary))
 
 pci:v00001002d00005D44sv00001787sd00005965*
- ID_MODEL_FROM_DATABASE=Excalibur 9200SE VIVO 128M (Secondary)
+ ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200 SE] (Secondary) (Excalibur 9200SE VIVO 128M (Secondary))
 
 pci:v00001002d00005D44sv000017AFsd00002013*
- ID_MODEL_FROM_DATABASE=Radeon 9200 SE Excalibur (Secondary)
+ ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200 SE] (Secondary) (Radeon 9200 SE Excalibur (Secondary))
 
 pci:v00001002d00005D44sv000018BCsd00000171*
- ID_MODEL_FROM_DATABASE=Radeon 9200 SE 128MB Game Buster (Secondary)
+ ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200 SE] (Secondary) (Radeon 9200 SE 128MB Game Buster (Secondary))
 
 pci:v00001002d00005D44sv000018BCsd00000172*
- ID_MODEL_FROM_DATABASE=GC-R9200L(SE)-C3H [Radeon 9200 Game Buster]
+ ID_MODEL_FROM_DATABASE=RV280 [Radeon 9200 SE] (Secondary) (GC-R9200L(SE)-C3H [Radeon 9200 Game Buster])
 
 pci:v00001002d00005D45*
  ID_MODEL_FROM_DATABASE=RV280 GL [FireMV 2200 PCI] (Secondary)
@@ -4101,7 +4152,7 @@ pci:v00001002d00005D52*
  ID_MODEL_FROM_DATABASE=R480 [Radeon X850 XT]
 
 pci:v00001002d00005D52sv00001002sd00000B12*
- ID_MODEL_FROM_DATABASE=PowerColor X850XT PCIe (Primary)
+ ID_MODEL_FROM_DATABASE=R480 [Radeon X850 XT] (PowerColor X850XT PCIe (Primary))
 
 pci:v00001002d00005D57*
  ID_MODEL_FROM_DATABASE=R423 [Radeon X800 XT]
@@ -4116,7 +4167,7 @@ pci:v00001002d00005D72*
  ID_MODEL_FROM_DATABASE=R480 [Radeon X850 XT] (Secondary)
 
 pci:v00001002d00005D72sv00001002sd00000B13*
- ID_MODEL_FROM_DATABASE=PowerColor X850XT PCIe (Secondary)
+ ID_MODEL_FROM_DATABASE=R480 [Radeon X850 XT] (Secondary) (PowerColor X850XT PCIe (Secondary))
 
 pci:v00001002d00005D77*
  ID_MODEL_FROM_DATABASE=R423 [Radeon X800 XT] (Secondary)
@@ -4140,13 +4191,13 @@ pci:v00001002d00005E4D*
  ID_MODEL_FROM_DATABASE=RV410 [Radeon X700]
 
 pci:v00001002d00005E4Dsv0000148Csd00002116*
- ID_MODEL_FROM_DATABASE=Bravo X700
+ ID_MODEL_FROM_DATABASE=RV410 [Radeon X700] (Bravo X700)
 
 pci:v00001002d00005E4F*
  ID_MODEL_FROM_DATABASE=RV410 [Radeon X700]
 
 pci:v00001002d00005E4Fsv00001569sd00001E4F*
- ID_MODEL_FROM_DATABASE=Radeon X550 XT
+ ID_MODEL_FROM_DATABASE=RV410 [Radeon X700] (Radeon X550 XT)
 
 pci:v00001002d00005E6B*
  ID_MODEL_FROM_DATABASE=RV410 [Radeon X700 PRO] (Secondary)
@@ -4155,7 +4206,7 @@ pci:v00001002d00005E6D*
  ID_MODEL_FROM_DATABASE=RV410 [Radeon X700] (Secondary)
 
 pci:v00001002d00005E6Dsv0000148Csd00002117*
- ID_MODEL_FROM_DATABASE=Bravo X700 (Secondary)
+ ID_MODEL_FROM_DATABASE=RV410 [Radeon X700] (Secondary) (Bravo X700 (Secondary))
 
 pci:v00001002d00005F57*
  ID_MODEL_FROM_DATABASE=R423 [Radeon X800 XT]
@@ -4163,11 +4214,14 @@ pci:v00001002d00005F57*
 pci:v00001002d00006600*
  ID_MODEL_FROM_DATABASE=Mars [Radeon HD 8670A/8670M/8750M]
 
+pci:v00001002d00006600sv0000103Csd00001952*
+ ID_MODEL_FROM_DATABASE=Mars [Radeon HD 8670A/8670M/8750M] (ProBook 455 G1)
+
 pci:v00001002d00006601*
  ID_MODEL_FROM_DATABASE=Mars [Radeon HD 8730M]
 
 pci:v00001002d00006601sv0000103Csd00002100*
- ID_MODEL_FROM_DATABASE=FirePro M4100
+ ID_MODEL_FROM_DATABASE=Mars [Radeon HD 8730M] (FirePro M4100)
 
 pci:v00001002d00006602*
  ID_MODEL_FROM_DATABASE=Mars
@@ -4176,38 +4230,62 @@ pci:v00001002d00006603*
  ID_MODEL_FROM_DATABASE=Mars
 
 pci:v00001002d00006604*
- ID_MODEL_FROM_DATABASE=Mars [Radeon R7 M265]
+ ID_MODEL_FROM_DATABASE=Opal XT [Radeon R7 M265]
 
 pci:v00001002d00006605*
- ID_MODEL_FROM_DATABASE=Mars [Radeon R7 M260]
+ ID_MODEL_FROM_DATABASE=Opal PRO [Radeon R7 M260]
 
 pci:v00001002d00006606*
  ID_MODEL_FROM_DATABASE=Mars XTX [Radeon HD 8790M]
 
 pci:v00001002d00006607*
- ID_MODEL_FROM_DATABASE=Mars LE [Radeon HD 8530M]
+ ID_MODEL_FROM_DATABASE=Mars LE [Radeon HD 8530M / R5 M240]
 
 pci:v00001002d00006610*
  ID_MODEL_FROM_DATABASE=Oland XT [Radeon HD 8670 / R7 250]
 
+pci:v00001002d00006610sv00001019sd00000030*
+ ID_MODEL_FROM_DATABASE=Oland XT [Radeon HD 8670 / R7 250] (Radeon HD 8670)
+
+pci:v00001002d00006610sv00001028sd00002120*
+ ID_MODEL_FROM_DATABASE=Oland XT [Radeon HD 8670 / R7 250] (Radeon R7 250)
+
+pci:v00001002d00006610sv00001028sd00002322*
+ ID_MODEL_FROM_DATABASE=Oland XT [Radeon HD 8670 / R7 250] (Radeon R7 250)
+
+pci:v00001002d00006610sv00001462sd00002910*
+ ID_MODEL_FROM_DATABASE=Oland XT [Radeon HD 8670 / R7 250] (Radeon HD 8670)
+
+pci:v00001002d00006610sv00001462sd00002911*
+ ID_MODEL_FROM_DATABASE=Oland XT [Radeon HD 8670 / R7 250] (Radeon HD 8670)
+
+pci:v00001002d00006610sv00001642sd00003C81*
+ ID_MODEL_FROM_DATABASE=Oland XT [Radeon HD 8670 / R7 250] (Radeon HD 8670)
+
+pci:v00001002d00006610sv00001642sd00003C91*
+ ID_MODEL_FROM_DATABASE=Oland XT [Radeon HD 8670 / R7 250] (Radeon HD 8670)
+
 pci:v00001002d00006611*
  ID_MODEL_FROM_DATABASE=Oland [Radeon HD 8570 / R7 240 OEM]
 
 pci:v00001002d00006611sv00001028sd0000210B*
- ID_MODEL_FROM_DATABASE=Radeon R5 240 OEM
+ ID_MODEL_FROM_DATABASE=Oland [Radeon HD 8570 / R7 240 OEM] (Radeon R5 240 OEM)
 
 pci:v00001002d00006611sv0000174Bsd00004248*
- ID_MODEL_FROM_DATABASE=Radeon R7 240 OEM
+ ID_MODEL_FROM_DATABASE=Oland [Radeon HD 8570 / R7 240 OEM] (Radeon R7 240 OEM)
 
 pci:v00001002d00006611sv0000174Bsd0000A240*
- ID_MODEL_FROM_DATABASE=Radeon R7 240 OEM
+ ID_MODEL_FROM_DATABASE=Oland [Radeon HD 8570 / R7 240 OEM] (Radeon R7 240 OEM)
 
 pci:v00001002d00006611sv00001B0Asd000090D3*
- ID_MODEL_FROM_DATABASE=Radeon R7 240 OEM
+ ID_MODEL_FROM_DATABASE=Oland [Radeon HD 8570 / R7 240 OEM] (Radeon R7 240 OEM)
 
 pci:v00001002d00006613*
  ID_MODEL_FROM_DATABASE=Oland PRO [Radeon R7 240]
 
+pci:v00001002d00006613sv00001682sd00007240*
+ ID_MODEL_FROM_DATABASE=Oland PRO [Radeon R7 240] (R7 240 2048 MB)
+
 pci:v00001002d00006620*
  ID_MODEL_FROM_DATABASE=Mars
 
@@ -4226,8 +4304,14 @@ pci:v00001002d00006640*
 pci:v00001002d00006641*
  ID_MODEL_FROM_DATABASE=Saturn PRO [Radeon HD 8930M]
 
+pci:v00001002d00006646*
+ ID_MODEL_FROM_DATABASE=Bonaire XT [Radeon R9 M280X]
+
+pci:v00001002d00006647*
+ ID_MODEL_FROM_DATABASE=Bonaire PRO [Radeon R9 M270X]
+
 pci:v00001002d00006649*
- ID_MODEL_FROM_DATABASE=Bonaire
+ ID_MODEL_FROM_DATABASE=Bonaire [FirePro W5100]
 
 pci:v00001002d00006650*
  ID_MODEL_FROM_DATABASE=Bonaire
@@ -4242,28 +4326,28 @@ pci:v00001002d0000665C*
  ID_MODEL_FROM_DATABASE=Bonaire XT [Radeon HD 7790/8770 / R9 260 OEM]
 
 pci:v00001002d0000665Csv00001043sd00000452*
- ID_MODEL_FROM_DATABASE=Radeon HD 7790 DirectCU II OC
+ ID_MODEL_FROM_DATABASE=Bonaire XT [Radeon HD 7790/8770 / R9 260 OEM] (Radeon HD 7790 DirectCU II OC)
 
 pci:v00001002d0000665Csv00001462sd00002930*
- ID_MODEL_FROM_DATABASE=Radeon HD 7790 OC
+ ID_MODEL_FROM_DATABASE=Bonaire XT [Radeon HD 7790/8770 / R9 260 OEM] (Radeon HD 7790 OC)
 
 pci:v00001002d0000665Csv00001462sd00002932*
- ID_MODEL_FROM_DATABASE=Radeon HD 8770
+ ID_MODEL_FROM_DATABASE=Bonaire XT [Radeon HD 7790/8770 / R9 260 OEM] (Radeon HD 8770)
 
 pci:v00001002d0000665Csv00001462sd00002934*
- ID_MODEL_FROM_DATABASE=Radeon R9 260 OEM
+ ID_MODEL_FROM_DATABASE=Bonaire XT [Radeon HD 7790/8770 / R9 260 OEM] (Radeon R9 260 OEM)
 
 pci:v00001002d0000665Csv0000148Csd00009260*
- ID_MODEL_FROM_DATABASE=Radeon R9 260 OEM
+ ID_MODEL_FROM_DATABASE=Bonaire XT [Radeon HD 7790/8770 / R9 260 OEM] (Radeon R9 260 OEM)
 
 pci:v00001002d0000665Csv00001682sd00003310*
- ID_MODEL_FROM_DATABASE=Radeon HD 7790 Black Edition 2 GB
+ ID_MODEL_FROM_DATABASE=Bonaire XT [Radeon HD 7790/8770 / R9 260 OEM] (Radeon HD 7790 Black Edition 2 GB)
 
 pci:v00001002d0000665Csv0000174Bsd0000E253*
- ID_MODEL_FROM_DATABASE=Radeon HD 7790 Dual-X OC
+ ID_MODEL_FROM_DATABASE=Bonaire XT [Radeon HD 7790/8770 / R9 260 OEM] (Radeon HD 7790 Dual-X OC)
 
 pci:v00001002d0000665Csv00001787sd00002329*
- ID_MODEL_FROM_DATABASE=Radeon HD 7790 TurboDuo
+ ID_MODEL_FROM_DATABASE=Bonaire XT [Radeon HD 7790/8770 / R9 260 OEM] (Radeon HD 7790 TurboDuo)
 
 pci:v00001002d0000665D*
  ID_MODEL_FROM_DATABASE=Bonaire [Radeon R7 200 Series]
@@ -4275,19 +4359,19 @@ pci:v00001002d00006663*
  ID_MODEL_FROM_DATABASE=Sun PRO [Radeon HD 8570A/8570M]
 
 pci:v00001002d00006663sv00001025sd00000846*
- ID_MODEL_FROM_DATABASE=Radeon HD 8570A
+ ID_MODEL_FROM_DATABASE=Sun PRO [Radeon HD 8570A/8570M] (Radeon HD 8570A)
 
 pci:v00001002d00006664*
- ID_MODEL_FROM_DATABASE=Jet XT [Radeon R5 M200 Series]
+ ID_MODEL_FROM_DATABASE=Jet XT [Radeon R5 M240]
 
 pci:v00001002d00006665*
- ID_MODEL_FROM_DATABASE=Jet PRO [Radeon R5 M200 Series]
+ ID_MODEL_FROM_DATABASE=Jet PRO [Radeon R5 M230]
 
 pci:v00001002d00006667*
- ID_MODEL_FROM_DATABASE=Jet ULT [Radeon R5 M200 Series]
+ ID_MODEL_FROM_DATABASE=Jet ULT [Radeon R5 M230]
 
 pci:v00001002d0000666F*
- ID_MODEL_FROM_DATABASE=Sun LE [Radeon HD 8550M]
+ ID_MODEL_FROM_DATABASE=Sun LE [Radeon HD 8550M / R5 M230]
 
 pci:v00001002d00006670*
  ID_MODEL_FROM_DATABASE=Hainan
@@ -4317,34 +4401,34 @@ pci:v00001002d00006720*
  ID_MODEL_FROM_DATABASE=Blackcomb [Radeon HD 6970M/6990M]
 
 pci:v00001002d00006720sv00001028sd0000048F*
- ID_MODEL_FROM_DATABASE=Radeon HD 6990M
+ ID_MODEL_FROM_DATABASE=Blackcomb [Radeon HD 6970M/6990M] (Radeon HD 6990M)
 
 pci:v00001002d00006720sv00001028sd00000490*
- ID_MODEL_FROM_DATABASE=Alienware M17x R3 Radeon HD 6970M
+ ID_MODEL_FROM_DATABASE=Blackcomb [Radeon HD 6970M/6990M] (Alienware M17x R3 Radeon HD 6970M)
 
 pci:v00001002d00006720sv00001028sd000004A4*
- ID_MODEL_FROM_DATABASE=FirePro M8900
+ ID_MODEL_FROM_DATABASE=Blackcomb [Radeon HD 6970M/6990M] (FirePro M8900)
 
 pci:v00001002d00006720sv00001028sd000004BA*
- ID_MODEL_FROM_DATABASE=Radeon HD 6990M
+ ID_MODEL_FROM_DATABASE=Blackcomb [Radeon HD 6970M/6990M] (Radeon HD 6990M)
 
 pci:v00001002d00006720sv00001028sd0000053F*
- ID_MODEL_FROM_DATABASE=FirePro M8900
+ ID_MODEL_FROM_DATABASE=Blackcomb [Radeon HD 6970M/6990M] (FirePro M8900)
 
 pci:v00001002d00006720sv0000106Bsd00000B00*
- ID_MODEL_FROM_DATABASE=Radeon HD 6970M
+ ID_MODEL_FROM_DATABASE=Blackcomb [Radeon HD 6970M/6990M] (Radeon HD 6970M)
 
 pci:v00001002d00006720sv00001558sd00005102*
- ID_MODEL_FROM_DATABASE=Radeon HD 6970M
+ ID_MODEL_FROM_DATABASE=Blackcomb [Radeon HD 6970M/6990M] (Radeon HD 6970M)
 
 pci:v00001002d00006720sv00001558sd00005104*
- ID_MODEL_FROM_DATABASE=Radeon HD 6990M
+ ID_MODEL_FROM_DATABASE=Blackcomb [Radeon HD 6970M/6990M] (Radeon HD 6990M)
 
 pci:v00001002d00006720sv00001558sd00007201*
- ID_MODEL_FROM_DATABASE=Radeon HD 6990M
+ ID_MODEL_FROM_DATABASE=Blackcomb [Radeon HD 6970M/6990M] (Radeon HD 6990M)
 
 pci:v00001002d00006720sv0000174Bsd0000E188*
- ID_MODEL_FROM_DATABASE=Radeon HD 6970M
+ ID_MODEL_FROM_DATABASE=Blackcomb [Radeon HD 6970M/6990M] (Radeon HD 6970M)
 
 pci:v00001002d00006724*
  ID_MODEL_FROM_DATABASE=Blackcomb [Mobility Radeon HD 6000 series]
@@ -4356,511 +4440,511 @@ pci:v00001002d00006738*
  ID_MODEL_FROM_DATABASE=Barts XT [Radeon HD 6870]
 
 pci:v00001002d00006738sv00001682sd00003103*
- ID_MODEL_FROM_DATABASE=Radeon HD 8670
+ ID_MODEL_FROM_DATABASE=Barts XT [Radeon HD 6870] (Radeon HD 8670)
 
 pci:v00001002d00006738sv00001787sd0000201A*
- ID_MODEL_FROM_DATABASE=Barts XT [Radeon HD 6870 X2]
+ ID_MODEL_FROM_DATABASE=Barts XT [Radeon HD 6870] (Barts XT [Radeon HD 6870 X2])
 
 pci:v00001002d00006738sv00001787sd0000201B*
- ID_MODEL_FROM_DATABASE=Barts XT [Radeon HD 6870 X2]
+ ID_MODEL_FROM_DATABASE=Barts XT [Radeon HD 6870] (Barts XT [Radeon HD 6870 X2])
 
 pci:v00001002d00006739*
  ID_MODEL_FROM_DATABASE=Barts PRO [Radeon HD 6850]
 
 pci:v00001002d00006739sv00001043sd000003B4*
- ID_MODEL_FROM_DATABASE=EAH6850 [Radeon HD 6850]
+ ID_MODEL_FROM_DATABASE=Barts PRO [Radeon HD 6850] (EAH6850 [Radeon HD 6850])
 
 pci:v00001002d0000673E*
  ID_MODEL_FROM_DATABASE=Barts LE [Radeon HD 6790]
 
 pci:v00001002d0000673Esv0000148Csd00007720*
- ID_MODEL_FROM_DATABASE=Radeon HD 7720 OEM
+ ID_MODEL_FROM_DATABASE=Barts LE [Radeon HD 6790] (Radeon HD 7720 OEM)
 
 pci:v00001002d00006740*
  ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6730M/6770M/7690M XT]
 
 pci:v00001002d00006740sv00001019sd0000238C*
- ID_MODEL_FROM_DATABASE=Radeon HD 6730M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6730M/6770M/7690M XT] (Radeon HD 6730M)
 
 pci:v00001002d00006740sv00001019sd0000238E*
- ID_MODEL_FROM_DATABASE=Radeon HD 6730M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6730M/6770M/7690M XT] (Radeon HD 6730M)
 
 pci:v00001002d00006740sv00001019sd00002391*
- ID_MODEL_FROM_DATABASE=Radeon HD 6730M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6730M/6770M/7690M XT] (Radeon HD 6730M)
 
 pci:v00001002d00006740sv00001019sd00002392*
- ID_MODEL_FROM_DATABASE=Radeon HD 6770M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6730M/6770M/7690M XT] (Radeon HD 6770M)
 
 pci:v00001002d00006740sv00001028sd000004A3*
- ID_MODEL_FROM_DATABASE=Precision M4600
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6730M/6770M/7690M XT] (Precision M4600)
 
 pci:v00001002d00006740sv00001028sd0000053E*
- ID_MODEL_FROM_DATABASE=FirePro M5950
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6730M/6770M/7690M XT] (FirePro M5950)
 
 pci:v00001002d00006740sv0000103Csd00001630*
- ID_MODEL_FROM_DATABASE=FirePro M5950
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6730M/6770M/7690M XT] (FirePro M5950)
 
 pci:v00001002d00006740sv0000103Csd00001631*
- ID_MODEL_FROM_DATABASE=FirePro M5950
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6730M/6770M/7690M XT] (FirePro M5950)
 
 pci:v00001002d00006740sv0000103Csd0000164B*
- ID_MODEL_FROM_DATABASE=Radeon HD 6730M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6730M/6770M/7690M XT] (Radeon HD 6730M)
 
 pci:v00001002d00006740sv0000103Csd0000164E*
- ID_MODEL_FROM_DATABASE=Radeon HD 6730M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6730M/6770M/7690M XT] (Radeon HD 6730M)
 
 pci:v00001002d00006740sv0000103Csd00001657*
- ID_MODEL_FROM_DATABASE=Radeon HD 6770M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6730M/6770M/7690M XT] (Radeon HD 6770M)
 
 pci:v00001002d00006740sv0000103Csd00001658*
- ID_MODEL_FROM_DATABASE=Radeon HD 6770M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6730M/6770M/7690M XT] (Radeon HD 6770M)
 
 pci:v00001002d00006740sv0000103Csd0000165A*
- ID_MODEL_FROM_DATABASE=Radeon HD 6770M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6730M/6770M/7690M XT] (Radeon HD 6770M)
 
 pci:v00001002d00006740sv0000103Csd0000165B*
- ID_MODEL_FROM_DATABASE=Radeon HD 6770M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6730M/6770M/7690M XT] (Radeon HD 6770M)
 
 pci:v00001002d00006740sv0000103Csd00001688*
- ID_MODEL_FROM_DATABASE=Radeon HD 6770M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6730M/6770M/7690M XT] (Radeon HD 6770M)
 
 pci:v00001002d00006740sv0000103Csd00001689*
- ID_MODEL_FROM_DATABASE=Radeon HD 6770M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6730M/6770M/7690M XT] (Radeon HD 6770M)
 
 pci:v00001002d00006740sv0000103Csd0000168A*
- ID_MODEL_FROM_DATABASE=Radeon HD 6770M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6730M/6770M/7690M XT] (Radeon HD 6770M)
 
 pci:v00001002d00006740sv0000103Csd0000185E*
- ID_MODEL_FROM_DATABASE=Radeon HD 7690M XT
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6730M/6770M/7690M XT] (Radeon HD 7690M XT)
 
 pci:v00001002d00006740sv0000103Csd00003388*
- ID_MODEL_FROM_DATABASE=Radeon HD 6770M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6730M/6770M/7690M XT] (Radeon HD 6770M)
 
 pci:v00001002d00006740sv0000103Csd00003389*
- ID_MODEL_FROM_DATABASE=Radeon HD 6770M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6730M/6770M/7690M XT] (Radeon HD 6770M)
 
 pci:v00001002d00006740sv0000103Csd00003582*
- ID_MODEL_FROM_DATABASE=Radeon HD 6770M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6730M/6770M/7690M XT] (Radeon HD 6770M)
 
 pci:v00001002d00006740sv0000103Csd0000366C*
- ID_MODEL_FROM_DATABASE=Radeon HD 6730M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6730M/6770M/7690M XT] (Radeon HD 6730M)
 
 pci:v00001002d00006740sv00001043sd00001D02*
- ID_MODEL_FROM_DATABASE=Radeon HD 6730M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6730M/6770M/7690M XT] (Radeon HD 6730M)
 
 pci:v00001002d00006740sv00001043sd00001D12*
- ID_MODEL_FROM_DATABASE=Radeon HD 6730M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6730M/6770M/7690M XT] (Radeon HD 6730M)
 
 pci:v00001002d00006740sv0000104Dsd00009084*
- ID_MODEL_FROM_DATABASE=Radeon HD 6730M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6730M/6770M/7690M XT] (Radeon HD 6730M)
 
 pci:v00001002d00006740sv0000104Dsd00009085*
- ID_MODEL_FROM_DATABASE=Radeon HD 6730M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6730M/6770M/7690M XT] (Radeon HD 6730M)
 
 pci:v00001002d00006740sv0000144Dsd0000B074*
- ID_MODEL_FROM_DATABASE=Radeon HD 6730M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6730M/6770M/7690M XT] (Radeon HD 6730M)
 
 pci:v00001002d00006740sv0000144Dsd0000B077*
- ID_MODEL_FROM_DATABASE=Radeon HD 6730M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6730M/6770M/7690M XT] (Radeon HD 6730M)
 
 pci:v00001002d00006740sv0000144Dsd0000B084*
- ID_MODEL_FROM_DATABASE=Radeon HD 6730M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6730M/6770M/7690M XT] (Radeon HD 6730M)
 
 pci:v00001002d00006740sv0000144Dsd0000B088*
- ID_MODEL_FROM_DATABASE=Radeon HD 6730M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6730M/6770M/7690M XT] (Radeon HD 6730M)
 
 pci:v00001002d00006740sv000017AAsd00003982*
- ID_MODEL_FROM_DATABASE=Radeon HD 6730M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6730M/6770M/7690M XT] (Radeon HD 6730M)
 
 pci:v00001002d00006741*
  ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M]
 
 pci:v00001002d00006741sv00001019sd0000238E*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001019sd0000238F*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001025sd00000379*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001025sd0000037B*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001025sd0000037E*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001025sd00000382*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001025sd00000384*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001025sd00000385*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001025sd00000386*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001025sd00000387*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001025sd00000388*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001025sd00000442*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001025sd00000451*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001025sd00000489*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001025sd0000048B*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001025sd0000048C*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001025sd0000050A*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001025sd0000050B*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001025sd0000050C*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001025sd0000050E*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001025sd0000050F*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001025sd00000513*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001025sd00000514*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001025sd00000515*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001025sd00000516*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001025sd0000051E*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001025sd0000051F*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001025sd00000520*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001025sd00000521*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001025sd0000052A*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001025sd00000555*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001025sd00000556*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001025sd0000055D*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001025sd0000055E*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001025sd0000056D*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001025sd0000059A*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001025sd0000059B*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001025sd0000059E*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001025sd0000059F*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001025sd00000600*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001025sd00000605*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001025sd00000606*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001025sd00000619*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001028sd000004C1*
- ID_MODEL_FROM_DATABASE=Radeon HD 6630M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6630M)
 
 pci:v00001002d00006741sv00001028sd000004C5*
- ID_MODEL_FROM_DATABASE=Radeon HD 6630M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6630M)
 
 pci:v00001002d00006741sv00001028sd000004CD*
- ID_MODEL_FROM_DATABASE=Radeon HD 6630M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6630M)
 
 pci:v00001002d00006741sv00001028sd000004D7*
- ID_MODEL_FROM_DATABASE=Radeon HD 6630M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6630M)
 
 pci:v00001002d00006741sv00001028sd000004D9*
- ID_MODEL_FROM_DATABASE=Radeon HD 6630M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6630M)
 
 pci:v00001002d00006741sv00001028sd0000052D*
- ID_MODEL_FROM_DATABASE=Radeon HD 6630M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6630M)
 
 pci:v00001002d00006741sv0000103Csd00001617*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv0000103Csd00001646*
- ID_MODEL_FROM_DATABASE=Radeon HD 6750M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6750M)
 
 pci:v00001002d00006741sv0000103Csd00001647*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv0000103Csd0000164B*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv0000103Csd0000164E*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv0000103Csd00001688*
- ID_MODEL_FROM_DATABASE=Radeon HD 6750M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6750M)
 
 pci:v00001002d00006741sv0000103Csd00001689*
- ID_MODEL_FROM_DATABASE=Radeon HD 6750M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6750M)
 
 pci:v00001002d00006741sv0000103Csd0000168A*
- ID_MODEL_FROM_DATABASE=Radeon HD 6750M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6750M)
 
 pci:v00001002d00006741sv0000103Csd00001860*
- ID_MODEL_FROM_DATABASE=Radeon HD 7690M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 7690M)
 
 pci:v00001002d00006741sv0000103Csd00003385*
- ID_MODEL_FROM_DATABASE=Radeon HD 6630M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6630M)
 
 pci:v00001002d00006741sv0000103Csd00003560*
- ID_MODEL_FROM_DATABASE=Radeon HD 6750M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6750M)
 
 pci:v00001002d00006741sv0000103Csd0000358D*
- ID_MODEL_FROM_DATABASE=Radeon HD 6750M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6750M)
 
 pci:v00001002d00006741sv0000103Csd00003590*
- ID_MODEL_FROM_DATABASE=Radeon HD 6750M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6750M)
 
 pci:v00001002d00006741sv0000103Csd00003593*
- ID_MODEL_FROM_DATABASE=Radeon HD 6750M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6750M)
 
 pci:v00001002d00006741sv0000103Csd0000366C*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001043sd00001CD2*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001043sd00002121*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001043sd00002122*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001043sd00002123*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001043sd00002125*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 7670M)
 
 pci:v00001002d00006741sv00001043sd00002127*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 7670M)
 
 pci:v00001002d00006741sv0000104Dsd0000907B*
- ID_MODEL_FROM_DATABASE=Radeon HD 6630M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6630M)
 
 pci:v00001002d00006741sv0000104Dsd00009080*
- ID_MODEL_FROM_DATABASE=Radeon HD 6630M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6630M)
 
 pci:v00001002d00006741sv0000104Dsd00009081*
- ID_MODEL_FROM_DATABASE=Radeon HD 6630M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6630M)
 
 pci:v00001002d00006741sv0000106Bsd000000E2*
- ID_MODEL_FROM_DATABASE=MacBookPro8,2 [Core i7, 15", Late 2011]
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (MacBookPro8,2 [Core i7, 15", Late 2011])
 
 pci:v00001002d00006741sv00001179sd0000FD63*
- ID_MODEL_FROM_DATABASE=Radeon HD 6630M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6630M)
 
 pci:v00001002d00006741sv00001179sd0000FD65*
- ID_MODEL_FROM_DATABASE=Radeon HD 6630M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6630M)
 
 pci:v00001002d00006741sv0000144Dsd0000C093*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv0000144Dsd0000C0AC*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv0000144Dsd0000C0B3*
- ID_MODEL_FROM_DATABASE=Radeon HD 6750M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6750M)
 
 pci:v00001002d00006741sv0000144Dsd0000C539*
- ID_MODEL_FROM_DATABASE=Radeon HD 6630M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6630M)
 
 pci:v00001002d00006741sv0000144Dsd0000C609*
- ID_MODEL_FROM_DATABASE=Radeon HD 6630M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6630M)
 
 pci:v00001002d00006741sv0000152Dsd00000914*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv000017AAsd000021E1*
- ID_MODEL_FROM_DATABASE=Radeon HD 6630M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6630M)
 
 pci:v00001002d00006741sv000017AAsd00003970*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv000017AAsd00003976*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006741sv00001854sd00000907*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650M
+ ID_MODEL_FROM_DATABASE=Whistler [Radeon HD 6630M/6650M/6750M/7670M/7690M] (Radeon HD 6650M)
 
 pci:v00001002d00006742*
  ID_MODEL_FROM_DATABASE=Whistler LE [Radeon HD 6610M/7610M]
 
 pci:v00001002d00006742sv00001002sd00006570*
- ID_MODEL_FROM_DATABASE=Turks [Radeon HD 6570]
+ ID_MODEL_FROM_DATABASE=Whistler LE [Radeon HD 6610M/7610M] (Turks [Radeon HD 6570])
 
 pci:v00001002d00006742sv00001019sd00002393*
- ID_MODEL_FROM_DATABASE=Radeon HD 6610M
+ ID_MODEL_FROM_DATABASE=Whistler LE [Radeon HD 6610M/7610M] (Radeon HD 6610M)
 
 pci:v00001002d00006742sv00001043sd00001D82*
- ID_MODEL_FROM_DATABASE=K53SK Laptop Radeon HD 7610M
+ ID_MODEL_FROM_DATABASE=Whistler LE [Radeon HD 6610M/7610M] (K53SK Laptop Radeon HD 7610M)
 
 pci:v00001002d00006742sv00001179sd0000FB22*
- ID_MODEL_FROM_DATABASE=Radeon HD 7610M
+ ID_MODEL_FROM_DATABASE=Whistler LE [Radeon HD 6610M/7610M] (Radeon HD 7610M)
 
 pci:v00001002d00006742sv00001179sd0000FB23*
- ID_MODEL_FROM_DATABASE=Radeon HD 7610M
+ ID_MODEL_FROM_DATABASE=Whistler LE [Radeon HD 6610M/7610M] (Radeon HD 7610M)
 
 pci:v00001002d00006742sv00001179sd0000FB27*
- ID_MODEL_FROM_DATABASE=Radeon HD 7610M
+ ID_MODEL_FROM_DATABASE=Whistler LE [Radeon HD 6610M/7610M] (Radeon HD 7610M)
 
 pci:v00001002d00006742sv00001179sd0000FB2A*
- ID_MODEL_FROM_DATABASE=Radeon HD 7610M
+ ID_MODEL_FROM_DATABASE=Whistler LE [Radeon HD 6610M/7610M] (Radeon HD 7610M)
 
 pci:v00001002d00006742sv00001179sd0000FB2C*
- ID_MODEL_FROM_DATABASE=Radeon HD 7610M
+ ID_MODEL_FROM_DATABASE=Whistler LE [Radeon HD 6610M/7610M] (Radeon HD 7610M)
 
 pci:v00001002d00006742sv00001179sd0000FB30*
- ID_MODEL_FROM_DATABASE=Radeon HD 7610M
+ ID_MODEL_FROM_DATABASE=Whistler LE [Radeon HD 6610M/7610M] (Radeon HD 7610M)
 
 pci:v00001002d00006742sv00001179sd0000FB31*
- ID_MODEL_FROM_DATABASE=Radeon HD 7610M
+ ID_MODEL_FROM_DATABASE=Whistler LE [Radeon HD 6610M/7610M] (Radeon HD 7610M)
 
 pci:v00001002d00006742sv00001179sd0000FB32*
- ID_MODEL_FROM_DATABASE=Radeon HD 7610M
+ ID_MODEL_FROM_DATABASE=Whistler LE [Radeon HD 6610M/7610M] (Radeon HD 7610M)
 
 pci:v00001002d00006742sv00001179sd0000FB38*
- ID_MODEL_FROM_DATABASE=Radeon HD 7610M
+ ID_MODEL_FROM_DATABASE=Whistler LE [Radeon HD 6610M/7610M] (Radeon HD 7610M)
 
 pci:v00001002d00006742sv00001179sd0000FB39*
- ID_MODEL_FROM_DATABASE=Radeon HD 7610M
+ ID_MODEL_FROM_DATABASE=Whistler LE [Radeon HD 6610M/7610M] (Radeon HD 7610M)
 
 pci:v00001002d00006742sv00001179sd0000FB3A*
- ID_MODEL_FROM_DATABASE=Radeon HD 7610M
+ ID_MODEL_FROM_DATABASE=Whistler LE [Radeon HD 6610M/7610M] (Radeon HD 7610M)
 
 pci:v00001002d00006742sv00001179sd0000FB3B*
- ID_MODEL_FROM_DATABASE=Radeon HD 7610M
+ ID_MODEL_FROM_DATABASE=Whistler LE [Radeon HD 6610M/7610M] (Radeon HD 7610M)
 
 pci:v00001002d00006742sv00001179sd0000FB40*
- ID_MODEL_FROM_DATABASE=Radeon HD 7610M
+ ID_MODEL_FROM_DATABASE=Whistler LE [Radeon HD 6610M/7610M] (Radeon HD 7610M)
 
 pci:v00001002d00006742sv00001179sd0000FB41*
- ID_MODEL_FROM_DATABASE=Radeon HD 7610M
+ ID_MODEL_FROM_DATABASE=Whistler LE [Radeon HD 6610M/7610M] (Radeon HD 7610M)
 
 pci:v00001002d00006742sv00001179sd0000FB47*
- ID_MODEL_FROM_DATABASE=Radeon HD 7610M
+ ID_MODEL_FROM_DATABASE=Whistler LE [Radeon HD 6610M/7610M] (Radeon HD 7610M)
 
 pci:v00001002d00006742sv00001179sd0000FB48*
- ID_MODEL_FROM_DATABASE=Radeon HD 7610M
+ ID_MODEL_FROM_DATABASE=Whistler LE [Radeon HD 6610M/7610M] (Radeon HD 7610M)
 
 pci:v00001002d00006742sv00001179sd0000FB49*
- ID_MODEL_FROM_DATABASE=Radeon HD 7610M
+ ID_MODEL_FROM_DATABASE=Whistler LE [Radeon HD 6610M/7610M] (Radeon HD 7610M)
 
 pci:v00001002d00006742sv00001179sd0000FB51*
- ID_MODEL_FROM_DATABASE=Radeon HD 7610M
+ ID_MODEL_FROM_DATABASE=Whistler LE [Radeon HD 6610M/7610M] (Radeon HD 7610M)
 
 pci:v00001002d00006742sv00001179sd0000FB52*
- ID_MODEL_FROM_DATABASE=Radeon HD 7610M
+ ID_MODEL_FROM_DATABASE=Whistler LE [Radeon HD 6610M/7610M] (Radeon HD 7610M)
 
 pci:v00001002d00006742sv00001179sd0000FB53*
- ID_MODEL_FROM_DATABASE=Radeon HD 7610M
+ ID_MODEL_FROM_DATABASE=Whistler LE [Radeon HD 6610M/7610M] (Radeon HD 7610M)
 
 pci:v00001002d00006742sv00001179sd0000FB56*
- ID_MODEL_FROM_DATABASE=Radeon HD 7610M
+ ID_MODEL_FROM_DATABASE=Whistler LE [Radeon HD 6610M/7610M] (Radeon HD 7610M)
 
 pci:v00001002d00006742sv00001179sd0000FB81*
- ID_MODEL_FROM_DATABASE=Radeon HD 7610M
+ ID_MODEL_FROM_DATABASE=Whistler LE [Radeon HD 6610M/7610M] (Radeon HD 7610M)
 
 pci:v00001002d00006742sv00001179sd0000FB82*
- ID_MODEL_FROM_DATABASE=Radeon HD 7610M
+ ID_MODEL_FROM_DATABASE=Whistler LE [Radeon HD 6610M/7610M] (Radeon HD 7610M)
 
 pci:v00001002d00006742sv00001179sd0000FB83*
- ID_MODEL_FROM_DATABASE=Radeon HD 7610M
+ ID_MODEL_FROM_DATABASE=Whistler LE [Radeon HD 6610M/7610M] (Radeon HD 7610M)
 
 pci:v00001002d00006742sv00001179sd0000FC56*
- ID_MODEL_FROM_DATABASE=Radeon HD 7610M
+ ID_MODEL_FROM_DATABASE=Whistler LE [Radeon HD 6610M/7610M] (Radeon HD 7610M)
 
 pci:v00001002d00006742sv00001179sd0000FCD4*
- ID_MODEL_FROM_DATABASE=Radeon HD 7610M
+ ID_MODEL_FROM_DATABASE=Whistler LE [Radeon HD 6610M/7610M] (Radeon HD 7610M)
 
 pci:v00001002d00006742sv00001179sd0000FCEE*
- ID_MODEL_FROM_DATABASE=Radeon HD 7610M
+ ID_MODEL_FROM_DATABASE=Whistler LE [Radeon HD 6610M/7610M] (Radeon HD 7610M)
 
 pci:v00001002d00006742sv00001458sd00006570*
- ID_MODEL_FROM_DATABASE=Turks [Radeon HD 6570]
+ ID_MODEL_FROM_DATABASE=Whistler LE [Radeon HD 6610M/7610M] (Turks [Radeon HD 6570])
 
 pci:v00001002d00006742sv00001462sd00006570*
- ID_MODEL_FROM_DATABASE=Turks [Radeon HD 6570]
+ ID_MODEL_FROM_DATABASE=Whistler LE [Radeon HD 6610M/7610M] (Turks [Radeon HD 6570])
 
 pci:v00001002d00006742sv0000148Csd00006570*
- ID_MODEL_FROM_DATABASE=Turks [Radeon HD 6570]
+ ID_MODEL_FROM_DATABASE=Whistler LE [Radeon HD 6610M/7610M] (Turks [Radeon HD 6570])
 
 pci:v00001002d00006742sv00001682sd00006570*
- ID_MODEL_FROM_DATABASE=Turks [Radeon HD 6570]
+ ID_MODEL_FROM_DATABASE=Whistler LE [Radeon HD 6610M/7610M] (Turks [Radeon HD 6570])
 
 pci:v00001002d00006742sv0000174Bsd00005570*
- ID_MODEL_FROM_DATABASE=Turks [Radeon HD 5570]
+ ID_MODEL_FROM_DATABASE=Whistler LE [Radeon HD 6610M/7610M] (Turks [Radeon HD 5570])
 
 pci:v00001002d00006742sv0000174Bsd00006570*
- ID_MODEL_FROM_DATABASE=Turks [Radeon HD 6570]
+ ID_MODEL_FROM_DATABASE=Whistler LE [Radeon HD 6610M/7610M] (Turks [Radeon HD 6570])
 
 pci:v00001002d00006742sv0000174Bsd00007570*
- ID_MODEL_FROM_DATABASE=Turks [Radeon HD 7570]
+ ID_MODEL_FROM_DATABASE=Whistler LE [Radeon HD 6610M/7610M] (Turks [Radeon HD 7570])
 
 pci:v00001002d00006742sv0000174Bsd00008510*
- ID_MODEL_FROM_DATABASE=Turks [Radeon HD 8510]
+ ID_MODEL_FROM_DATABASE=Whistler LE [Radeon HD 6610M/7610M] (Turks [Radeon HD 8510])
 
 pci:v00001002d00006742sv0000174Bsd00008570*
- ID_MODEL_FROM_DATABASE=Turks [Radeon HD 8570]
+ ID_MODEL_FROM_DATABASE=Whistler LE [Radeon HD 6610M/7610M] (Turks [Radeon HD 8570])
 
 pci:v00001002d00006742sv00001787sd00006570*
- ID_MODEL_FROM_DATABASE=Turks [Radeon HD 6570]
+ ID_MODEL_FROM_DATABASE=Whistler LE [Radeon HD 6610M/7610M] (Turks [Radeon HD 6570])
 
 pci:v00001002d00006742sv000017AFsd00006570*
- ID_MODEL_FROM_DATABASE=Turks [Radeon HD 6570]
+ ID_MODEL_FROM_DATABASE=Whistler LE [Radeon HD 6610M/7610M] (Turks [Radeon HD 6570])
 
 pci:v00001002d00006742sv00008086sd00002111*
- ID_MODEL_FROM_DATABASE=Radeon HD 6625M
+ ID_MODEL_FROM_DATABASE=Whistler LE [Radeon HD 6610M/7610M] (Radeon HD 6625M)
 
 pci:v00001002d00006743*
  ID_MODEL_FROM_DATABASE=Whistler [Radeon E6760]
@@ -4875,133 +4959,136 @@ pci:v00001002d00006750*
  ID_MODEL_FROM_DATABASE=Onega [Radeon HD 6650A/7650A]
 
 pci:v00001002d00006750sv00001462sd00002670*
- ID_MODEL_FROM_DATABASE=Radeon HD 6670A
+ ID_MODEL_FROM_DATABASE=Onega [Radeon HD 6650A/7650A] (Radeon HD 6670A)
 
 pci:v00001002d00006750sv000017AAsd00003079*
- ID_MODEL_FROM_DATABASE=Radeon HD 7650A
+ ID_MODEL_FROM_DATABASE=Onega [Radeon HD 6650A/7650A] (Radeon HD 7650A)
 
 pci:v00001002d00006750sv000017AAsd0000307A*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650A
+ ID_MODEL_FROM_DATABASE=Onega [Radeon HD 6650A/7650A] (Radeon HD 6650A)
 
 pci:v00001002d00006750sv000017AAsd00003087*
- ID_MODEL_FROM_DATABASE=Radeon HD 7650A
+ ID_MODEL_FROM_DATABASE=Onega [Radeon HD 6650A/7650A] (Radeon HD 7650A)
 
 pci:v00001002d00006750sv000017AAsd00003618*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650A
+ ID_MODEL_FROM_DATABASE=Onega [Radeon HD 6650A/7650A] (Radeon HD 6650A)
 
 pci:v00001002d00006750sv000017AAsd00003623*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650A
+ ID_MODEL_FROM_DATABASE=Onega [Radeon HD 6650A/7650A] (Radeon HD 6650A)
 
 pci:v00001002d00006750sv000017AAsd00003627*
- ID_MODEL_FROM_DATABASE=Radeon HD 6650A
+ ID_MODEL_FROM_DATABASE=Onega [Radeon HD 6650A/7650A] (Radeon HD 6650A)
 
 pci:v00001002d00006751*
  ID_MODEL_FROM_DATABASE=Turks [Radeon HD 7650A/7670A]
 
 pci:v00001002d00006751sv00001028sd00000548*
- ID_MODEL_FROM_DATABASE=Radeon HD 7650A
+ ID_MODEL_FROM_DATABASE=Turks [Radeon HD 7650A/7670A] (Radeon HD 7650A)
 
 pci:v00001002d00006751sv00001462sd00002671*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670A
+ ID_MODEL_FROM_DATABASE=Turks [Radeon HD 7650A/7670A] (Radeon HD 7670A)
 
 pci:v00001002d00006751sv00001462sd00002672*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670A
+ ID_MODEL_FROM_DATABASE=Turks [Radeon HD 7650A/7670A] (Radeon HD 7670A)
 
 pci:v00001002d00006751sv00001462sd00002680*
- ID_MODEL_FROM_DATABASE=Radeon HD 7650A
+ ID_MODEL_FROM_DATABASE=Turks [Radeon HD 7650A/7670A] (Radeon HD 7650A)
 
 pci:v00001002d00006751sv00001462sd00002681*
- ID_MODEL_FROM_DATABASE=Radeon HD 7650A
+ ID_MODEL_FROM_DATABASE=Turks [Radeon HD 7650A/7670A] (Radeon HD 7650A)
 
 pci:v00001002d00006751sv000017AAsd00003087*
- ID_MODEL_FROM_DATABASE=Radeon HD 7650A
+ ID_MODEL_FROM_DATABASE=Turks [Radeon HD 7650A/7670A] (Radeon HD 7650A)
 
 pci:v00001002d00006758*
  ID_MODEL_FROM_DATABASE=Turks XT [Radeon HD 6670/7670]
 
 pci:v00001002d00006758sv00001028sd00000B0E*
- ID_MODEL_FROM_DATABASE=Radeon HD 6670
+ ID_MODEL_FROM_DATABASE=Turks XT [Radeon HD 6670/7670] (Radeon HD 6670)
 
 pci:v00001002d00006758sv0000103Csd00006882*
- ID_MODEL_FROM_DATABASE=Radeon HD 6670
+ ID_MODEL_FROM_DATABASE=Turks XT [Radeon HD 6670/7670] (Radeon HD 6670)
 
 pci:v00001002d00006758sv00001462sd0000250A*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670
+ ID_MODEL_FROM_DATABASE=Turks XT [Radeon HD 6670/7670] (Radeon HD 7670)
 
 pci:v00001002d00006758sv0000148Csd00007670*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670
+ ID_MODEL_FROM_DATABASE=Turks XT [Radeon HD 6670/7670] (Radeon HD 7670)
 
 pci:v00001002d00006758sv00001545sd00007670*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670
+ ID_MODEL_FROM_DATABASE=Turks XT [Radeon HD 6670/7670] (Radeon HD 7670)
 
 pci:v00001002d00006758sv00001682sd00003300*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670
+ ID_MODEL_FROM_DATABASE=Turks XT [Radeon HD 6670/7670] (Radeon HD 7670)
 
 pci:v00001002d00006758sv0000174Bsd00007670*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670
+ ID_MODEL_FROM_DATABASE=Turks XT [Radeon HD 6670/7670] (Radeon HD 7670)
 
 pci:v00001002d00006758sv0000174Bsd0000E181*
- ID_MODEL_FROM_DATABASE=Radeon HD 6670
+ ID_MODEL_FROM_DATABASE=Turks XT [Radeon HD 6670/7670] (Radeon HD 6670)
 
 pci:v00001002d00006758sv00001787sd00002309*
- ID_MODEL_FROM_DATABASE=Radeon HD 6670
+ ID_MODEL_FROM_DATABASE=Turks XT [Radeon HD 6670/7670] (Radeon HD 6670)
 
 pci:v00001002d00006759*
  ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550]
 
 pci:v00001002d00006759sv0000103Csd00003130*
- ID_MODEL_FROM_DATABASE=Radeon HD 6570
+ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 6570)
 
 pci:v00001002d00006759sv00001043sd00000403*
- ID_MODEL_FROM_DATABASE=Radeon HD 6570
+ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 6570)
 
 pci:v00001002d00006759sv00001462sd00002500*
- ID_MODEL_FROM_DATABASE=Radeon HD 6570
+ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 6570)
 
 pci:v00001002d00006759sv00001462sd00002509*
- ID_MODEL_FROM_DATABASE=Radeon HD 7570
+ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 7570)
 
 pci:v00001002d00006759sv0000148Csd00007570*
- ID_MODEL_FROM_DATABASE=Radeon HD 7570
+ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 7570)
 
 pci:v00001002d00006759sv00001642sd00003A67*
- ID_MODEL_FROM_DATABASE=Radeon HD 6570
+ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 6570)
 
 pci:v00001002d00006759sv00001682sd00003280*
- ID_MODEL_FROM_DATABASE=Radeon HD 7570
+ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 7570)
 
 pci:v00001002d00006759sv00001682sd00003530*
- ID_MODEL_FROM_DATABASE=Radeon HD 8550
+ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 8550)
 
 pci:v00001002d00006759sv0000174Bsd00007570*
- ID_MODEL_FROM_DATABASE=Radeon HD 7570
+ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 7570)
 
 pci:v00001002d00006759sv0000174Bsd0000E142*
- ID_MODEL_FROM_DATABASE=Radeon HD 6570
+ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 6570)
 
 pci:v00001002d00006759sv0000174Bsd0000E181*
- ID_MODEL_FROM_DATABASE=Radeon HD 6570
+ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 6570)
 
 pci:v00001002d00006759sv00001B0Asd0000908F*
- ID_MODEL_FROM_DATABASE=Radeon HD 6570
+ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 6570)
 
 pci:v00001002d00006759sv00001B0Asd00009090*
- ID_MODEL_FROM_DATABASE=Radeon HD 6570
+ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 6570)
 
 pci:v00001002d00006759sv00001B0Asd00009091*
- ID_MODEL_FROM_DATABASE=Radeon HD 6570
+ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 6570)
 
 pci:v00001002d00006759sv00001B0Asd00009092*
- ID_MODEL_FROM_DATABASE=Radeon HD 6570
+ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 6570)
 
 pci:v00001002d00006759sv00001B0Asd0000909E*
- ID_MODEL_FROM_DATABASE=Radeon HD 6570
+ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 6570)
 
 pci:v00001002d00006759sv00001B0Asd000090B5*
- ID_MODEL_FROM_DATABASE=Radeon HD 7570
+ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 7570)
 
 pci:v00001002d00006759sv00001B0Asd000090B6*
- ID_MODEL_FROM_DATABASE=Radeon HD 7570
+ ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 6570/7570/8550] (Radeon HD 7570)
+
+pci:v00001002d0000675B*
+ ID_MODEL_FROM_DATABASE=Turks [Radeon HD 7600 Series]
 
 pci:v00001002d0000675D*
  ID_MODEL_FROM_DATABASE=Turks PRO [Radeon HD 7570]
@@ -5010,526 +5097,526 @@ pci:v00001002d0000675F*
  ID_MODEL_FROM_DATABASE=Turks LE [Radeon HD 5570/6510/7510/8510]
 
 pci:v00001002d0000675Fsv0000148Csd00006510*
- ID_MODEL_FROM_DATABASE=Radeon HD 6510
+ ID_MODEL_FROM_DATABASE=Turks LE [Radeon HD 5570/6510/7510/8510] (Radeon HD 6510)
 
 pci:v00001002d0000675Fsv0000148Csd00006530*
- ID_MODEL_FROM_DATABASE=Radeon HD 6530
+ ID_MODEL_FROM_DATABASE=Turks LE [Radeon HD 5570/6510/7510/8510] (Radeon HD 6530)
 
 pci:v00001002d0000675Fsv0000148Csd00007510*
- ID_MODEL_FROM_DATABASE=Radeon HD 7510
+ ID_MODEL_FROM_DATABASE=Turks LE [Radeon HD 5570/6510/7510/8510] (Radeon HD 7510)
 
 pci:v00001002d0000675Fsv00001545sd00007570*
- ID_MODEL_FROM_DATABASE=Radeon HD 7570
+ ID_MODEL_FROM_DATABASE=Turks LE [Radeon HD 5570/6510/7510/8510] (Radeon HD 7570)
 
 pci:v00001002d0000675Fsv0000174Bsd00006510*
- ID_MODEL_FROM_DATABASE=Radeon HD 6510
+ ID_MODEL_FROM_DATABASE=Turks LE [Radeon HD 5570/6510/7510/8510] (Radeon HD 6510)
 
 pci:v00001002d0000675Fsv0000174Bsd00007510*
- ID_MODEL_FROM_DATABASE=Radeon HD 7510
+ ID_MODEL_FROM_DATABASE=Turks LE [Radeon HD 5570/6510/7510/8510] (Radeon HD 7510)
 
 pci:v00001002d0000675Fsv0000174Bsd00008510*
- ID_MODEL_FROM_DATABASE=Radeon HD 8510
+ ID_MODEL_FROM_DATABASE=Turks LE [Radeon HD 5570/6510/7510/8510] (Radeon HD 8510)
 
 pci:v00001002d0000675Fsv00001787sd00002012*
- ID_MODEL_FROM_DATABASE=Radeon HD 5570 2GB GDDR3
+ ID_MODEL_FROM_DATABASE=Turks LE [Radeon HD 5570/6510/7510/8510] (Radeon HD 5570 2GB GDDR3)
 
 pci:v00001002d0000675Fsv00001787sd00002314*
- ID_MODEL_FROM_DATABASE=Radeon HD 5570 1GB DDR2/GDDR3
+ ID_MODEL_FROM_DATABASE=Turks LE [Radeon HD 5570/6510/7510/8510] (Radeon HD 5570 1GB DDR2/GDDR3)
 
 pci:v00001002d00006760*
  ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series]
 
 pci:v00001002d00006760sv00001002sd00000124*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv00001002sd00000134*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv00001019sd0000238B*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv00001019sd0000238E*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv00001019sd00002390*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv00001019sd00009985*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv00001028sd000004C1*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv00001028sd000004C3*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv00001028sd000004CA*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv00001028sd000004CB*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv00001028sd000004CC*
- ID_MODEL_FROM_DATABASE=Vostro 3350
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Vostro 3350)
 
 pci:v00001002d00006760sv00001028sd000004D1*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv00001028sd000004D3*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv00001028sd000004D7*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv00001028sd00000502*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv00001028sd00000503*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv00001028sd00000506*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv00001028sd00000507*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv00001028sd00000514*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv00001028sd0000051C*
- ID_MODEL_FROM_DATABASE=Radeon HD 6450M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6450M)
 
 pci:v00001002d00006760sv00001028sd0000051D*
- ID_MODEL_FROM_DATABASE=Radeon HD 6450M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6450M)
 
 pci:v00001002d00006760sv0000103Csd0000161A*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv0000103Csd0000161B*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv0000103Csd0000161E*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv0000103Csd0000161F*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv0000103Csd00001622*
- ID_MODEL_FROM_DATABASE=Radeon HD 6450M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6450M)
 
 pci:v00001002d00006760sv0000103Csd00001623*
- ID_MODEL_FROM_DATABASE=Radeon HD 6450M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6450M)
 
 pci:v00001002d00006760sv0000103Csd0000164A*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv0000103Csd0000164D*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv0000103Csd00001651*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv0000103Csd00001656*
- ID_MODEL_FROM_DATABASE=Radeon HD 6490M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6490M)
 
 pci:v00001002d00006760sv0000103Csd00001658*
- ID_MODEL_FROM_DATABASE=Radeon HD 6490M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6490M)
 
 pci:v00001002d00006760sv0000103Csd00001659*
- ID_MODEL_FROM_DATABASE=Radeon HD 6490M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6490M)
 
 pci:v00001002d00006760sv0000103Csd0000165B*
- ID_MODEL_FROM_DATABASE=Radeon HD 6490M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6490M)
 
 pci:v00001002d00006760sv0000103Csd0000165D*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv0000103Csd0000165F*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv0000103Csd00001661*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv0000103Csd00001663*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv0000103Csd00001665*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv0000103Csd00001667*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv0000103Csd00001669*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv0000103Csd0000166B*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv0000103Csd0000166C*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv0000103Csd0000166E*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv0000103Csd00001670*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv0000103Csd00001672*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv0000103Csd0000167A*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv0000103Csd0000167B*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv0000103Csd0000167D*
- ID_MODEL_FROM_DATABASE=Radeon HD 6490M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6490M)
 
 pci:v00001002d00006760sv0000103Csd0000167F*
- ID_MODEL_FROM_DATABASE=Radeon HD 6490M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6490M)
 
 pci:v00001002d00006760sv0000103Csd0000168C*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv0000103Csd0000168F*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv0000103Csd00001694*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv0000103Csd00001696*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv0000103Csd00001698*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv0000103Csd0000169A*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv0000103Csd0000169C*
- ID_MODEL_FROM_DATABASE=Radeon HD 6490M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6490M)
 
 pci:v00001002d00006760sv0000103Csd00001855*
- ID_MODEL_FROM_DATABASE=Radeon HD 7450M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7450M)
 
 pci:v00001002d00006760sv0000103Csd00001859*
- ID_MODEL_FROM_DATABASE=Radeon HD 7450M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7450M)
 
 pci:v00001002d00006760sv0000103Csd0000185C*
- ID_MODEL_FROM_DATABASE=Radeon HD 7450M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7450M)
 
 pci:v00001002d00006760sv0000103Csd0000185D*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7470M)
 
 pci:v00001002d00006760sv0000103Csd0000185F*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7470M)
 
 pci:v00001002d00006760sv0000103Csd00001863*
- ID_MODEL_FROM_DATABASE=Radeon HD 7450M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7450M)
 
 pci:v00001002d00006760sv0000103Csd0000355C*
- ID_MODEL_FROM_DATABASE=Radeon HD 6490M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6490M)
 
 pci:v00001002d00006760sv0000103Csd0000355F*
- ID_MODEL_FROM_DATABASE=Radeon HD 6490M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6490M)
 
 pci:v00001002d00006760sv0000103Csd00003563*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv0000103Csd00003565*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv0000103Csd00003567*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv0000103Csd00003569*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv0000103Csd00003581*
- ID_MODEL_FROM_DATABASE=Radeon HD 6490M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6490M)
 
 pci:v00001002d00006760sv0000103Csd00003584*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv0000103Csd0000358C*
- ID_MODEL_FROM_DATABASE=Radeon HD 6490M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6490M)
 
 pci:v00001002d00006760sv0000103Csd0000358F*
- ID_MODEL_FROM_DATABASE=Radeon HD 6490M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6490M)
 
 pci:v00001002d00006760sv0000103Csd00003592*
- ID_MODEL_FROM_DATABASE=Radeon HD 6490M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6490M)
 
 pci:v00001002d00006760sv0000103Csd00003596*
- ID_MODEL_FROM_DATABASE=Radeon HD 6490M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6490M)
 
 pci:v00001002d00006760sv0000103Csd0000366B*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv0000103Csd00003671*
- ID_MODEL_FROM_DATABASE=FirePro M3900
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (FirePro M3900)
 
 pci:v00001002d00006760sv0000103Csd00003673*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv00001043sd0000100A*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7470M)
 
 pci:v00001002d00006760sv00001043sd0000100C*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv00001043sd0000101B*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv00001043sd0000101C*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv00001043sd0000102A*
- ID_MODEL_FROM_DATABASE=Radeon HD 7450M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7450M)
 
 pci:v00001002d00006760sv00001043sd0000102C*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv00001043sd0000104B*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7470M)
 
 pci:v00001002d00006760sv00001043sd0000105D*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7470M)
 
 pci:v00001002d00006760sv00001043sd0000106B*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7470M)
 
 pci:v00001002d00006760sv00001043sd0000106D*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7470M)
 
 pci:v00001002d00006760sv00001043sd0000107D*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7470M)
 
 pci:v00001002d00006760sv00001043sd00001CB2*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv00001043sd00001D22*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv00001043sd00001D32*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv00001043sd00002001*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv00001043sd00002002*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7470M)
 
 pci:v00001002d00006760sv00001043sd00002107*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7470M)
 
 pci:v00001002d00006760sv00001043sd00002108*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7470M)
 
 pci:v00001002d00006760sv00001043sd00002109*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7470M)
 
 pci:v00001002d00006760sv00001043sd000084A0*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv00001043sd000084E9*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv00001043sd00008515*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7470M)
 
 pci:v00001002d00006760sv00001043sd00008517*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7470M)
 
 pci:v00001002d00006760sv00001043sd0000855A*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7470M)
 
 pci:v00001002d00006760sv0000104Dsd0000907B*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv0000104Dsd00009081*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv0000104Dsd00009084*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv0000104Dsd00009085*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv00001179sd00000001*
- ID_MODEL_FROM_DATABASE=Radeon HD 6450M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6450M)
 
 pci:v00001002d00006760sv00001179sd00000003*
- ID_MODEL_FROM_DATABASE=Radeon HD 6450M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6450M)
 
 pci:v00001002d00006760sv00001179sd00000004*
- ID_MODEL_FROM_DATABASE=Radeon HD 6450M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6450M)
 
 pci:v00001002d00006760sv00001179sd0000FB22*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7470M)
 
 pci:v00001002d00006760sv00001179sd0000FB23*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7470M)
 
 pci:v00001002d00006760sv00001179sd0000FB2C*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7470M)
 
 pci:v00001002d00006760sv00001179sd0000FB31*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7470M)
 
 pci:v00001002d00006760sv00001179sd0000FB32*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7470M)
 
 pci:v00001002d00006760sv00001179sd0000FB33*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7470M)
 
 pci:v00001002d00006760sv00001179sd0000FB38*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7470M)
 
 pci:v00001002d00006760sv00001179sd0000FB39*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7470M)
 
 pci:v00001002d00006760sv00001179sd0000FB3A*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7470M)
 
 pci:v00001002d00006760sv00001179sd0000FB40*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7470M)
 
 pci:v00001002d00006760sv00001179sd0000FB41*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7470M)
 
 pci:v00001002d00006760sv00001179sd0000FB42*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7470M)
 
 pci:v00001002d00006760sv00001179sd0000FB47*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7470M)
 
 pci:v00001002d00006760sv00001179sd0000FB48*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7470M)
 
 pci:v00001002d00006760sv00001179sd0000FB51*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7470M)
 
 pci:v00001002d00006760sv00001179sd0000FB52*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7470M)
 
 pci:v00001002d00006760sv00001179sd0000FB53*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7470M)
 
 pci:v00001002d00006760sv00001179sd0000FB81*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7470M)
 
 pci:v00001002d00006760sv00001179sd0000FB82*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7470M)
 
 pci:v00001002d00006760sv00001179sd0000FB83*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7470M)
 
 pci:v00001002d00006760sv00001179sd0000FC51*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv00001179sd0000FC52*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7470M)
 
 pci:v00001002d00006760sv00001179sd0000FC56*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7470M)
 
 pci:v00001002d00006760sv00001179sd0000FCD3*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7470M)
 
 pci:v00001002d00006760sv00001179sd0000FCD4*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7470M)
 
 pci:v00001002d00006760sv00001179sd0000FCEE*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7470M)
 
 pci:v00001002d00006760sv00001179sd0000FDEE*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7470M)
 
 pci:v00001002d00006760sv0000144Dsd0000B074*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv0000144Dsd0000B084*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv0000144Dsd0000C095*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv0000144Dsd0000C0B3*
- ID_MODEL_FROM_DATABASE=Radeon HD 6490M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6490M)
 
 pci:v00001002d00006760sv0000144Dsd0000C538*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv0000144Dsd0000C581*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv0000144Dsd0000C589*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv0000144Dsd0000C609*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7470M)
 
 pci:v00001002d00006760sv0000144Dsd0000C625*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7470M)
 
 pci:v00001002d00006760sv0000144Dsd0000C636*
- ID_MODEL_FROM_DATABASE=Radeon HD 7450M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7450M)
 
 pci:v00001002d00006760sv00001462sd000010AC*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv0000152Dsd00000916*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv000017AAsd000021E5*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv000017AAsd00003900*
- ID_MODEL_FROM_DATABASE=Radeon HD 7450M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7450M)
 
 pci:v00001002d00006760sv000017AAsd00003902*
- ID_MODEL_FROM_DATABASE=Radeon HD 7450M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7450M)
 
 pci:v00001002d00006760sv000017AAsd00003969*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv000017AAsd00003970*
- ID_MODEL_FROM_DATABASE=Radeon HD 7450M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7450M)
 
 pci:v00001002d00006760sv000017AAsd00003976*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv000017AAsd0000397B*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv000017AAsd0000397D*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv000017AAsd00005101*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7470M)
 
 pci:v00001002d00006760sv000017AAsd00005102*
- ID_MODEL_FROM_DATABASE=Radeon HD 7450M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7450M)
 
 pci:v00001002d00006760sv000017AAsd00005103*
- ID_MODEL_FROM_DATABASE=Radeon HD 7450M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7450M)
 
 pci:v00001002d00006760sv000017AAsd00005106*
- ID_MODEL_FROM_DATABASE=Radeon HD 7450M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 7450M)
 
 pci:v00001002d00006760sv00001854sd00000897*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv00001854sd00000900*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv00001854sd00000908*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006760sv00001854sd00002015*
- ID_MODEL_FROM_DATABASE=Radeon HD 6470M
+ ID_MODEL_FROM_DATABASE=Seymour [Radeon HD 6400M/7400M Series] (Radeon HD 6470M)
 
 pci:v00001002d00006761*
  ID_MODEL_FROM_DATABASE=Seymour LP [Radeon HD 6430M]
@@ -5556,22 +5643,22 @@ pci:v00001002d00006770*
  ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450A/7450A]
 
 pci:v00001002d00006770sv000017AAsd0000308D*
- ID_MODEL_FROM_DATABASE=Radeon HD 7450A
+ ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450A/7450A] (Radeon HD 7450A)
 
 pci:v00001002d00006770sv000017AAsd00003623*
- ID_MODEL_FROM_DATABASE=Radeon HD 6450A
+ ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450A/7450A] (Radeon HD 6450A)
 
 pci:v00001002d00006770sv000017AAsd00003627*
- ID_MODEL_FROM_DATABASE=Radeon HD 6450A
+ ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450A/7450A] (Radeon HD 6450A)
 
 pci:v00001002d00006770sv000017AAsd00003629*
- ID_MODEL_FROM_DATABASE=Radeon HD 6450A
+ ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450A/7450A] (Radeon HD 6450A)
 
 pci:v00001002d00006770sv000017AAsd0000363C*
- ID_MODEL_FROM_DATABASE=Radeon HD 6450A
+ ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450A/7450A] (Radeon HD 6450A)
 
 pci:v00001002d00006770sv000017AAsd00003658*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470A
+ ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450A/7450A] (Radeon HD 7470A)
 
 pci:v00001002d00006771*
  ID_MODEL_FROM_DATABASE=Caicos XTX [Radeon HD 8490 / R5 235X OEM]
@@ -5583,133 +5670,133 @@ pci:v00001002d00006778*
  ID_MODEL_FROM_DATABASE=Caicos XT [Radeon HD 7470/8470 / R5 235 OEM]
 
 pci:v00001002d00006778sv00001019sd00000024*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470
+ ID_MODEL_FROM_DATABASE=Caicos XT [Radeon HD 7470/8470 / R5 235 OEM] (Radeon HD 7470)
 
 pci:v00001002d00006778sv00001019sd00000027*
- ID_MODEL_FROM_DATABASE=Radeon HD 8470
+ ID_MODEL_FROM_DATABASE=Caicos XT [Radeon HD 7470/8470 / R5 235 OEM] (Radeon HD 8470)
 
 pci:v00001002d00006778sv00001028sd00002120*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470
+ ID_MODEL_FROM_DATABASE=Caicos XT [Radeon HD 7470/8470 / R5 235 OEM] (Radeon HD 7470)
 
 pci:v00001002d00006778sv00001462sd0000B491*
- ID_MODEL_FROM_DATABASE=Radeon HD 8470
+ ID_MODEL_FROM_DATABASE=Caicos XT [Radeon HD 7470/8470 / R5 235 OEM] (Radeon HD 8470)
 
 pci:v00001002d00006778sv00001462sd0000B492*
- ID_MODEL_FROM_DATABASE=Radeon HD 8470
+ ID_MODEL_FROM_DATABASE=Caicos XT [Radeon HD 7470/8470 / R5 235 OEM] (Radeon HD 8470)
 
 pci:v00001002d00006778sv00001462sd0000B493*
- ID_MODEL_FROM_DATABASE=Radeon HD 8470 OEM
+ ID_MODEL_FROM_DATABASE=Caicos XT [Radeon HD 7470/8470 / R5 235 OEM] (Radeon HD 8470 OEM)
 
 pci:v00001002d00006778sv00001642sd00003C65*
- ID_MODEL_FROM_DATABASE=Radeon HD 8470
+ ID_MODEL_FROM_DATABASE=Caicos XT [Radeon HD 7470/8470 / R5 235 OEM] (Radeon HD 8470)
 
 pci:v00001002d00006778sv00001642sd00003C75*
- ID_MODEL_FROM_DATABASE=Radeon HD 8470
+ ID_MODEL_FROM_DATABASE=Caicos XT [Radeon HD 7470/8470 / R5 235 OEM] (Radeon HD 8470)
 
 pci:v00001002d00006778sv0000174Bsd00008145*
- ID_MODEL_FROM_DATABASE=Radeon HD 8470
+ ID_MODEL_FROM_DATABASE=Caicos XT [Radeon HD 7470/8470 / R5 235 OEM] (Radeon HD 8470)
 
 pci:v00001002d00006778sv0000174Bsd0000E145*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470
+ ID_MODEL_FROM_DATABASE=Caicos XT [Radeon HD 7470/8470 / R5 235 OEM] (Radeon HD 7470)
 
 pci:v00001002d00006779*
  ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450/7450/8450 / R5 230 OEM]
 
 pci:v00001002d00006779sv00001019sd00000016*
- ID_MODEL_FROM_DATABASE=Radeon HD 6450
+ ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450/7450/8450 / R5 230 OEM] (Radeon HD 6450)
 
 pci:v00001002d00006779sv00001019sd00000017*
- ID_MODEL_FROM_DATABASE=Radeon HD 6450
+ ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450/7450/8450 / R5 230 OEM] (Radeon HD 6450)
 
 pci:v00001002d00006779sv00001019sd00000018*
- ID_MODEL_FROM_DATABASE=Radeon HD 6450
+ ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450/7450/8450 / R5 230 OEM] (Radeon HD 6450)
 
 pci:v00001002d00006779sv00001028sd00002120*
- ID_MODEL_FROM_DATABASE=Radeon HD 6450
+ ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450/7450/8450 / R5 230 OEM] (Radeon HD 6450)
 
 pci:v00001002d00006779sv0000103Csd00002128*
- ID_MODEL_FROM_DATABASE=Radeon HD 6450
+ ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450/7450/8450 / R5 230 OEM] (Radeon HD 6450)
 
 pci:v00001002d00006779sv0000103Csd00002AEE*
- ID_MODEL_FROM_DATABASE=Radeon HD 7450A
+ ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450/7450/8450 / R5 230 OEM] (Radeon HD 7450A)
 
 pci:v00001002d00006779sv00001462sd00002125*
- ID_MODEL_FROM_DATABASE=Radeon HD 6450
+ ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450/7450/8450 / R5 230 OEM] (Radeon HD 6450)
 
 pci:v00001002d00006779sv00001462sd00002346*
- ID_MODEL_FROM_DATABASE=Radeon HD 7450
+ ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450/7450/8450 / R5 230 OEM] (Radeon HD 7450)
 
 pci:v00001002d00006779sv00001462sd00002490*
- ID_MODEL_FROM_DATABASE=Radeon HD 6450
+ ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450/7450/8450 / R5 230 OEM] (Radeon HD 6450)
 
 pci:v00001002d00006779sv00001462sd00002494*
- ID_MODEL_FROM_DATABASE=Radeon HD 6450
+ ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450/7450/8450 / R5 230 OEM] (Radeon HD 6450)
 
 pci:v00001002d00006779sv00001462sd00002496*
- ID_MODEL_FROM_DATABASE=Radeon HD 7450
+ ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450/7450/8450 / R5 230 OEM] (Radeon HD 7450)
 
 pci:v00001002d00006779sv0000148Csd00007450*
- ID_MODEL_FROM_DATABASE=Radeon HD 7450
+ ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450/7450/8450 / R5 230 OEM] (Radeon HD 7450)
 
 pci:v00001002d00006779sv0000148Csd00008450*
- ID_MODEL_FROM_DATABASE=Radeon HD 8450 OEM
+ ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450/7450/8450 / R5 230 OEM] (Radeon HD 8450 OEM)
 
 pci:v00001002d00006779sv00001545sd00007470*
- ID_MODEL_FROM_DATABASE=Radeon HD 7470
+ ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450/7450/8450 / R5 230 OEM] (Radeon HD 7470)
 
 pci:v00001002d00006779sv00001642sd00003A65*
- ID_MODEL_FROM_DATABASE=Radeon HD 6450
+ ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450/7450/8450 / R5 230 OEM] (Radeon HD 6450)
 
 pci:v00001002d00006779sv00001642sd00003A66*
- ID_MODEL_FROM_DATABASE=Radeon HD 7450
+ ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450/7450/8450 / R5 230 OEM] (Radeon HD 7450)
 
 pci:v00001002d00006779sv00001642sd00003A75*
- ID_MODEL_FROM_DATABASE=Radeon HD 6450
+ ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450/7450/8450 / R5 230 OEM] (Radeon HD 6450)
 
 pci:v00001002d00006779sv00001642sd00003A76*
- ID_MODEL_FROM_DATABASE=Radeon HD 7450
+ ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450/7450/8450 / R5 230 OEM] (Radeon HD 7450)
 
 pci:v00001002d00006779sv00001682sd00003200*
- ID_MODEL_FROM_DATABASE=Radeon HD 7450
+ ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450/7450/8450 / R5 230 OEM] (Radeon HD 7450)
 
 pci:v00001002d00006779sv0000174Bsd00007450*
- ID_MODEL_FROM_DATABASE=Radeon HD 7450
+ ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450/7450/8450 / R5 230 OEM] (Radeon HD 7450)
 
 pci:v00001002d00006779sv0000174Bsd0000E127*
- ID_MODEL_FROM_DATABASE=Radeon HD 6450
+ ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450/7450/8450 / R5 230 OEM] (Radeon HD 6450)
 
 pci:v00001002d00006779sv0000174Bsd0000E153*
- ID_MODEL_FROM_DATABASE=Radeon HD 6450
+ ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450/7450/8450 / R5 230 OEM] (Radeon HD 6450)
 
 pci:v00001002d00006779sv0000174Bsd0000E164*
- ID_MODEL_FROM_DATABASE=Radeon HD 6450 1 GB DDR3
+ ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450/7450/8450 / R5 230 OEM] (Radeon HD 6450 1 GB DDR3)
 
 pci:v00001002d00006779sv0000174Bsd0000E180*
- ID_MODEL_FROM_DATABASE=Radeon HD 6450
+ ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450/7450/8450 / R5 230 OEM] (Radeon HD 6450)
 
 pci:v00001002d00006779sv0000174Bsd0000E201*
- ID_MODEL_FROM_DATABASE=Radeon HD 6450
+ ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450/7450/8450 / R5 230 OEM] (Radeon HD 6450)
 
 pci:v00001002d00006779sv000017AFsd00008450*
- ID_MODEL_FROM_DATABASE=Radeon HD 8450 OEM
+ ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450/7450/8450 / R5 230 OEM] (Radeon HD 8450 OEM)
 
 pci:v00001002d00006779sv00001B0Asd00009096*
- ID_MODEL_FROM_DATABASE=Radeon HD 6450
+ ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450/7450/8450 / R5 230 OEM] (Radeon HD 6450)
 
 pci:v00001002d00006779sv00001B0Asd00009097*
- ID_MODEL_FROM_DATABASE=Radeon HD 6450
+ ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450/7450/8450 / R5 230 OEM] (Radeon HD 6450)
 
 pci:v00001002d00006779sv00001B0Asd000090A8*
- ID_MODEL_FROM_DATABASE=Radeon HD 6450A
+ ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450/7450/8450 / R5 230 OEM] (Radeon HD 6450A)
 
 pci:v00001002d00006779sv00001B0Asd000090B1*
- ID_MODEL_FROM_DATABASE=Radeon HD 6450
+ ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450/7450/8450 / R5 230 OEM] (Radeon HD 6450)
 
 pci:v00001002d00006779sv00001B0Asd000090B3*
- ID_MODEL_FROM_DATABASE=Radeon HD 7450A
+ ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450/7450/8450 / R5 230 OEM] (Radeon HD 7450A)
 
 pci:v00001002d00006779sv00001B0Asd000090BB*
- ID_MODEL_FROM_DATABASE=Radeon HD 7450A
+ ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6450/7450/8450 / R5 230 OEM] (Radeon HD 7450A)
 
 pci:v00001002d0000677B*
  ID_MODEL_FROM_DATABASE=Caicos PRO [Radeon HD 7450]
@@ -5727,25 +5814,25 @@ pci:v00001002d0000678A*
  ID_MODEL_FROM_DATABASE=Tahiti PRO GL [FirePro Series]
 
 pci:v00001002d0000678Asv00001002sd0000030C*
- ID_MODEL_FROM_DATABASE=FirePro W8000
+ ID_MODEL_FROM_DATABASE=Tahiti PRO GL [FirePro Series] (FirePro W8000)
 
 pci:v00001002d0000678Asv00001002sd00000310*
- ID_MODEL_FROM_DATABASE=FirePro S9000
+ ID_MODEL_FROM_DATABASE=Tahiti PRO GL [FirePro Series] (FirePro S9000)
 
 pci:v00001002d0000678Asv00001002sd00000420*
- ID_MODEL_FROM_DATABASE=Radeon Sky 700
+ ID_MODEL_FROM_DATABASE=Tahiti PRO GL [FirePro Series] (Radeon Sky 700)
 
 pci:v00001002d0000678Asv00001002sd00000422*
- ID_MODEL_FROM_DATABASE=Radeon Sky 900
+ ID_MODEL_FROM_DATABASE=Tahiti PRO GL [FirePro Series] (Radeon Sky 900)
 
 pci:v00001002d0000678Asv00001002sd00000B0E*
- ID_MODEL_FROM_DATABASE=FirePro S10000 Passive
+ ID_MODEL_FROM_DATABASE=Tahiti PRO GL [FirePro Series] (FirePro S10000 Passive)
 
 pci:v00001002d0000678Asv00001002sd00000B2A*
- ID_MODEL_FROM_DATABASE=FirePro S10000
+ ID_MODEL_FROM_DATABASE=Tahiti PRO GL [FirePro Series] (FirePro S10000)
 
 pci:v00001002d0000678Asv00001028sd0000030C*
- ID_MODEL_FROM_DATABASE=FirePro W8000
+ ID_MODEL_FROM_DATABASE=Tahiti PRO GL [FirePro Series] (FirePro W8000)
 
 pci:v00001002d00006790*
  ID_MODEL_FROM_DATABASE=Tahiti
@@ -5757,97 +5844,100 @@ pci:v00001002d00006792*
  ID_MODEL_FROM_DATABASE=Tahiti
 
 pci:v00001002d00006798*
- ID_MODEL_FROM_DATABASE=Tahiti XT [Radeon HD 7970/R9 280X]
+ ID_MODEL_FROM_DATABASE=Tahiti XT [Radeon HD 7970/8970 OEM / R9 280X]
 
 pci:v00001002d00006798sv00001002sd00003000*
- ID_MODEL_FROM_DATABASE=Tahiti XT2 [Radeon HD 7970 GHz Edition]
+ ID_MODEL_FROM_DATABASE=Tahiti XT [Radeon HD 7970/8970 OEM / R9 280X] (Tahiti XT2 [Radeon HD 7970 GHz Edition])
 
 pci:v00001002d00006798sv00001002sd00003001*
- ID_MODEL_FROM_DATABASE=Tahiti XTL [Radeon R9 280X]
+ ID_MODEL_FROM_DATABASE=Tahiti XT [Radeon HD 7970/8970 OEM / R9 280X] (Tahiti XTL [Radeon R9 280X])
 
 pci:v00001002d00006798sv00001002sd00004000*
- ID_MODEL_FROM_DATABASE=Radeon HD 8970 OEM
+ ID_MODEL_FROM_DATABASE=Tahiti XT [Radeon HD 7970/8970 OEM / R9 280X] (Radeon HD 8970 OEM)
 
 pci:v00001002d00006798sv00001043sd0000041C*
- ID_MODEL_FROM_DATABASE=HD 7970 DirectCU II
+ ID_MODEL_FROM_DATABASE=Tahiti XT [Radeon HD 7970/8970 OEM / R9 280X] (HD 7970 DirectCU II)
 
 pci:v00001002d00006798sv00001043sd00000420*
- ID_MODEL_FROM_DATABASE=HD 7970 DirectCU II TOP
+ ID_MODEL_FROM_DATABASE=Tahiti XT [Radeon HD 7970/8970 OEM / R9 280X] (HD 7970 DirectCU II TOP)
 
 pci:v00001002d00006798sv00001043sd00000444*
- ID_MODEL_FROM_DATABASE=HD 7970 DirectCU II TOP
+ ID_MODEL_FROM_DATABASE=Tahiti XT [Radeon HD 7970/8970 OEM / R9 280X] (HD 7970 DirectCU II TOP)
 
 pci:v00001002d00006798sv00001043sd00000448*
- ID_MODEL_FROM_DATABASE=HD 7970 DirectCU II TOP
+ ID_MODEL_FROM_DATABASE=Tahiti XT [Radeon HD 7970/8970 OEM / R9 280X] (HD 7970 DirectCU II TOP)
 
 pci:v00001002d00006798sv00001043sd0000044A*
- ID_MODEL_FROM_DATABASE=Tahiti XT2 [Matrix HD 7970]
+ ID_MODEL_FROM_DATABASE=Tahiti XT [Radeon HD 7970/8970 OEM / R9 280X] (Tahiti XT2 [Matrix HD 7970])
 
 pci:v00001002d00006798sv00001043sd0000044C*
- ID_MODEL_FROM_DATABASE=Tahiti XT2 [Matrix HD 7970 Platinum]
+ ID_MODEL_FROM_DATABASE=Tahiti XT [Radeon HD 7970/8970 OEM / R9 280X] (Tahiti XT2 [Matrix HD 7970 Platinum])
 
 pci:v00001002d00006798sv00001043sd00003001*
- ID_MODEL_FROM_DATABASE=Tahiti XTL [ROG Matrix R9 280X]
+ ID_MODEL_FROM_DATABASE=Tahiti XT [Radeon HD 7970/8970 OEM / R9 280X] (Tahiti XTL [ROG Matrix R9 280X])
 
 pci:v00001002d00006798sv00001043sd00003006*
- ID_MODEL_FROM_DATABASE=Tahiti XTL [Radeon R9 280X DirectCU II TOP]
+ ID_MODEL_FROM_DATABASE=Tahiti XT [Radeon HD 7970/8970 OEM / R9 280X] (Tahiti XTL [Radeon R9 280X DirectCU II TOP])
 
 pci:v00001002d00006798sv00001043sd00009999*
- ID_MODEL_FROM_DATABASE=ARES II
+ ID_MODEL_FROM_DATABASE=Tahiti XT [Radeon HD 7970/8970 OEM / R9 280X] (ARES II)
 
 pci:v00001002d00006798sv00001092sd00003000*
- ID_MODEL_FROM_DATABASE=Tahiti XT2 [Radeon HD 7970 GHz Edition]
+ ID_MODEL_FROM_DATABASE=Tahiti XT [Radeon HD 7970/8970 OEM / R9 280X] (Tahiti XT2 [Radeon HD 7970 GHz Edition])
 
 pci:v00001002d00006798sv00001458sd00002261*
- ID_MODEL_FROM_DATABASE=Tahiti XT2 [Radeon HD 7970 GHz Edition OC]
+ ID_MODEL_FROM_DATABASE=Tahiti XT [Radeon HD 7970/8970 OEM / R9 280X] (Tahiti XT2 [Radeon HD 7970 GHz Edition OC])
+
+pci:v00001002d00006798sv00001462sd00002774*
+ ID_MODEL_FROM_DATABASE=Tahiti XT [Radeon HD 7970/8970 OEM / R9 280X] (MSI R7970 TF 3GD5/OC BE)
 
 pci:v00001002d00006798sv00001682sd00003211*
- ID_MODEL_FROM_DATABASE=Double D HD 7970 Black Edition
+ ID_MODEL_FROM_DATABASE=Tahiti XT [Radeon HD 7970/8970 OEM / R9 280X] (Double D HD 7970 Black Edition)
 
 pci:v00001002d00006798sv00001682sd00003213*
- ID_MODEL_FROM_DATABASE=HD 7970 Black Edition
+ ID_MODEL_FROM_DATABASE=Tahiti XT [Radeon HD 7970/8970 OEM / R9 280X] (HD 7970 Black Edition)
 
 pci:v00001002d00006798sv00001682sd00003214*
- ID_MODEL_FROM_DATABASE=Double D HD 7970
+ ID_MODEL_FROM_DATABASE=Tahiti XT [Radeon HD 7970/8970 OEM / R9 280X] (Double D HD 7970)
 
 pci:v00001002d00006798sv00001787sd0000201C*
- ID_MODEL_FROM_DATABASE=HD 7970 IceQ X²
+ ID_MODEL_FROM_DATABASE=Tahiti XT [Radeon HD 7970/8970 OEM / R9 280X] (HD 7970 IceQ X²)
 
 pci:v00001002d00006798sv00001787sd00002317*
- ID_MODEL_FROM_DATABASE=Radeon HD 7990
+ ID_MODEL_FROM_DATABASE=Tahiti XT [Radeon HD 7970/8970 OEM / R9 280X] (Radeon HD 7990)
 
 pci:v00001002d00006798sv00001787sd00003000*
- ID_MODEL_FROM_DATABASE=Tahiti XT2 [Radeon HD 7970 GHz Edition]
+ ID_MODEL_FROM_DATABASE=Tahiti XT [Radeon HD 7970/8970 OEM / R9 280X] (Tahiti XT2 [Radeon HD 7970 GHz Edition])
 
 pci:v00001002d00006799*
  ID_MODEL_FROM_DATABASE=New Zealand [Radeon HD 7900 Series]
 
 pci:v00001002d0000679A*
- ID_MODEL_FROM_DATABASE=Tahiti PRO [Radeon HD 7950]
+ ID_MODEL_FROM_DATABASE=Tahiti PRO [Radeon HD 7950/8950 OEM / R9 280]
 
 pci:v00001002d0000679Asv00001002sd00000B01*
- ID_MODEL_FROM_DATABASE=Radeon HD 8950 OEM
+ ID_MODEL_FROM_DATABASE=Tahiti PRO [Radeon HD 7950/8950 OEM / R9 280] (Radeon HD 8950 OEM)
 
 pci:v00001002d0000679Asv00001002sd00003000*
- ID_MODEL_FROM_DATABASE=Tahiti PRO2 [Radeon HD 7950 Boost]
+ ID_MODEL_FROM_DATABASE=Tahiti PRO [Radeon HD 7950/8950 OEM / R9 280] (Tahiti PRO2 [Radeon HD 7950 Boost])
 
 pci:v00001002d0000679Asv00001462sd00003000*
- ID_MODEL_FROM_DATABASE=Radeon HD 8950 OEM
+ ID_MODEL_FROM_DATABASE=Tahiti PRO [Radeon HD 7950/8950 OEM / R9 280] (Radeon HD 8950 OEM)
 
 pci:v00001002d0000679B*
  ID_MODEL_FROM_DATABASE=Malta [Radeon HD 7990]
 
 pci:v00001002d0000679Bsv00001002sd00000B28*
- ID_MODEL_FROM_DATABASE=Radeon HD 8990 OEM
+ ID_MODEL_FROM_DATABASE=Malta [Radeon HD 7990] (Radeon HD 8990 OEM)
 
 pci:v00001002d0000679Bsv00001002sd00000B2A*
- ID_MODEL_FROM_DATABASE=Radeon HD 7990
+ ID_MODEL_FROM_DATABASE=Malta [Radeon HD 7990] (Radeon HD 7990)
 
 pci:v00001002d0000679Bsv00001462sd00008036*
- ID_MODEL_FROM_DATABASE=Radeon HD 8990 OEM
+ ID_MODEL_FROM_DATABASE=Malta [Radeon HD 7990] (Radeon HD 8990 OEM)
 
 pci:v00001002d0000679Bsv0000148Csd00008990*
- ID_MODEL_FROM_DATABASE=Radeon HD 8990 OEM
+ ID_MODEL_FROM_DATABASE=Malta [Radeon HD 7990] (Radeon HD 8990 OEM)
 
 pci:v00001002d0000679E*
  ID_MODEL_FROM_DATABASE=Tahiti LE [Radeon HD 7870 XT]
@@ -5856,10 +5946,10 @@ pci:v00001002d0000679F*
  ID_MODEL_FROM_DATABASE=Tahiti
 
 pci:v00001002d000067A0*
- ID_MODEL_FROM_DATABASE=Hawaii XT GL
+ ID_MODEL_FROM_DATABASE=Hawaii XT GL [FirePro W9100]
 
 pci:v00001002d000067A1*
- ID_MODEL_FROM_DATABASE=Hawaii GL
+ ID_MODEL_FROM_DATABASE=Hawaii PRO GL [FirePro W8100]
 
 pci:v00001002d000067A2*
  ID_MODEL_FROM_DATABASE=Hawaii GL
@@ -5880,7 +5970,7 @@ pci:v00001002d000067B1*
  ID_MODEL_FROM_DATABASE=Hawaii PRO [Radeon R9 290]
 
 pci:v00001002d000067B9*
- ID_MODEL_FROM_DATABASE=Vesuvius
+ ID_MODEL_FROM_DATABASE=Vesuvius [Radeon R9 295X2]
 
 pci:v00001002d000067BE*
  ID_MODEL_FROM_DATABASE=Hawaii LE
@@ -5889,25 +5979,28 @@ pci:v00001002d00006800*
  ID_MODEL_FROM_DATABASE=Wimbledon XT [Radeon HD 7970M]
 
 pci:v00001002d00006800sv00001002sd00000124*
- ID_MODEL_FROM_DATABASE=Radeon HD 7970M
+ ID_MODEL_FROM_DATABASE=Wimbledon XT [Radeon HD 7970M] (Radeon HD 7970M)
 
 pci:v00001002d00006800sv00008086sd00002110*
- ID_MODEL_FROM_DATABASE=Radeon HD 7970M
+ ID_MODEL_FROM_DATABASE=Wimbledon XT [Radeon HD 7970M] (Radeon HD 7970M)
 
 pci:v00001002d00006800sv00008086sd00002111*
- ID_MODEL_FROM_DATABASE=Radeon HD 7970M
+ ID_MODEL_FROM_DATABASE=Wimbledon XT [Radeon HD 7970M] (Radeon HD 7970M)
 
 pci:v00001002d00006801*
- ID_MODEL_FROM_DATABASE=Neptune [Radeon HD 8970M]
+ ID_MODEL_FROM_DATABASE=Neptune XT [Radeon HD 8970M]
 
 pci:v00001002d00006801sv00001002sd00000124*
- ID_MODEL_FROM_DATABASE=Radeon HD 8970M
+ ID_MODEL_FROM_DATABASE=Neptune XT [Radeon HD 8970M] (Radeon HD 8970M)
+
+pci:v00001002d00006801sv00001462sd00001117*
+ ID_MODEL_FROM_DATABASE=Neptune XT [Radeon HD 8970M] (Radeon R9 M290X)
 
 pci:v00001002d00006801sv00008086sd00002110*
- ID_MODEL_FROM_DATABASE=Radeon HD 8970M
+ ID_MODEL_FROM_DATABASE=Neptune XT [Radeon HD 8970M] (Radeon HD 8970M)
 
 pci:v00001002d00006801sv00008086sd00002111*
- ID_MODEL_FROM_DATABASE=Radeon HD 8970M
+ ID_MODEL_FROM_DATABASE=Neptune XT [Radeon HD 8970M] (Radeon HD 8970M)
 
 pci:v00001002d00006802*
  ID_MODEL_FROM_DATABASE=Wimbledon
@@ -5919,10 +6012,10 @@ pci:v00001002d00006808*
  ID_MODEL_FROM_DATABASE=Pitcairn XT GL [FirePro W7000]
 
 pci:v00001002d00006808sv00001002sd00000310*
- ID_MODEL_FROM_DATABASE=FirePro S7000
+ ID_MODEL_FROM_DATABASE=Pitcairn XT GL [FirePro W7000] (FirePro S7000)
 
 pci:v00001002d00006808sv00001002sd00000420*
- ID_MODEL_FROM_DATABASE=Radeon Sky 500
+ ID_MODEL_FROM_DATABASE=Pitcairn XT GL [FirePro W7000] (Radeon Sky 500)
 
 pci:v00001002d00006809*
  ID_MODEL_FROM_DATABASE=Pitcairn LE GL [FirePro W5000]
@@ -5943,40 +6036,49 @@ pci:v00001002d00006818*
  ID_MODEL_FROM_DATABASE=Pitcairn XT [Radeon HD 7870 GHz Edition]
 
 pci:v00001002d00006818sv00001002sd00000B05*
- ID_MODEL_FROM_DATABASE=Radeon HD 8870 OEM
+ ID_MODEL_FROM_DATABASE=Pitcairn XT [Radeon HD 7870 GHz Edition] (Radeon HD 8870 OEM)
 
 pci:v00001002d00006818sv0000174Bsd00008B04*
- ID_MODEL_FROM_DATABASE=Radeon HD 8860
+ ID_MODEL_FROM_DATABASE=Pitcairn XT [Radeon HD 7870 GHz Edition] (Radeon HD 8860)
 
 pci:v00001002d00006819*
  ID_MODEL_FROM_DATABASE=Pitcairn PRO [Radeon HD 7850]
 
 pci:v00001002d00006819sv0000174Bsd0000E221*
- ID_MODEL_FROM_DATABASE=Radeon HD 7850 2GB GDDR5 DVI-I/DVI-D/HDMI/DP
+ ID_MODEL_FROM_DATABASE=Pitcairn PRO [Radeon HD 7850] (Radeon HD 7850 2GB GDDR5 DVI-I/DVI-D/HDMI/DP)
 
 pci:v00001002d00006820*
- ID_MODEL_FROM_DATABASE=Venus XTX [Radeon HD 8890M]
+ ID_MODEL_FROM_DATABASE=Venus XTX [Radeon HD 8890M / R9 M275X]
 
 pci:v00001002d00006820sv0000103Csd00001851*
- ID_MODEL_FROM_DATABASE=Radeon HD 7750M
+ ID_MODEL_FROM_DATABASE=Venus XTX [Radeon HD 8890M / R9 M275X] (Radeon HD 7750M)
+
+pci:v00001002d00006820sv000017AAsd00003801*
+ ID_MODEL_FROM_DATABASE=Venus XTX [Radeon HD 8890M / R9 M275X] (Radeon R9 M275)
 
 pci:v00001002d00006821*
- ID_MODEL_FROM_DATABASE=Venus XT [Radeon HD 8870M]
+ ID_MODEL_FROM_DATABASE=Venus XT [Radeon HD 8870M / R9 M270X]
 
 pci:v00001002d00006821sv00001002sd0000031E*
- ID_MODEL_FROM_DATABASE=FirePro SX4000
+ ID_MODEL_FROM_DATABASE=Venus XT [Radeon HD 8870M / R9 M270X] (FirePro SX4000)
+
+pci:v00001002d00006821sv00001028sd000005CC*
+ ID_MODEL_FROM_DATABASE=Venus XT [Radeon HD 8870M / R9 M270X] (FirePro M5100)
+
+pci:v00001002d00006821sv00001028sd000015CC*
+ ID_MODEL_FROM_DATABASE=Venus XT [Radeon HD 8870M / R9 M270X] (FirePro M5100)
 
 pci:v00001002d00006822*
  ID_MODEL_FROM_DATABASE=Venus PRO [Radeon E8860]
 
 pci:v00001002d00006823*
- ID_MODEL_FROM_DATABASE=Venus PRO [Radeon HD 8850M]
+ ID_MODEL_FROM_DATABASE=Venus PRO [Radeon HD 8850M / R9 M265X]
 
 pci:v00001002d00006825*
  ID_MODEL_FROM_DATABASE=Heathrow XT [Radeon HD 7870M]
 
 pci:v00001002d00006825sv00008086sd00002111*
- ID_MODEL_FROM_DATABASE=Chelsea PRO
+ ID_MODEL_FROM_DATABASE=Heathrow XT [Radeon HD 7870M] (Chelsea PRO)
 
 pci:v00001002d00006826*
  ID_MODEL_FROM_DATABASE=Chelsea LP [Radeon HD 7700M Series]
@@ -6003,7 +6105,7 @@ pci:v00001002d0000682F*
  ID_MODEL_FROM_DATABASE=Chelsea LP [Radeon HD 7730M]
 
 pci:v00001002d0000682Fsv0000103Csd00001851*
- ID_MODEL_FROM_DATABASE=Radeon HD 7750M
+ ID_MODEL_FROM_DATABASE=Chelsea LP [Radeon HD 7730M] (Radeon HD 7750M)
 
 pci:v00001002d00006830*
  ID_MODEL_FROM_DATABASE=Cape Verde [Radeon HD 7800M Series]
@@ -6018,16 +6120,16 @@ pci:v00001002d00006837*
  ID_MODEL_FROM_DATABASE=Cape Verde LE [Radeon HD 7730/8730]
 
 pci:v00001002d00006837sv00001462sd00002796*
- ID_MODEL_FROM_DATABASE=Radeon HD 8730
+ ID_MODEL_FROM_DATABASE=Cape Verde LE [Radeon HD 7730/8730] (Radeon HD 8730)
 
 pci:v00001002d00006837sv00001462sd00008092*
- ID_MODEL_FROM_DATABASE=Radeon HD 8730
+ ID_MODEL_FROM_DATABASE=Cape Verde LE [Radeon HD 7730/8730] (Radeon HD 8730)
 
 pci:v00001002d00006837sv0000148Csd00008730*
- ID_MODEL_FROM_DATABASE=Radeon HD 8730
+ ID_MODEL_FROM_DATABASE=Cape Verde LE [Radeon HD 7730/8730] (Radeon HD 8730)
 
 pci:v00001002d00006837sv00001787sd00003000*
- ID_MODEL_FROM_DATABASE=Radeon HD 6570
+ ID_MODEL_FROM_DATABASE=Cape Verde LE [Radeon HD 7730/8730] (Radeon HD 6570)
 
 pci:v00001002d00006838*
  ID_MODEL_FROM_DATABASE=Cape Verde
@@ -6039,340 +6141,349 @@ pci:v00001002d0000683B*
  ID_MODEL_FROM_DATABASE=Cape Verde [Radeon HD 7700 Series]
 
 pci:v00001002d0000683D*
- ID_MODEL_FROM_DATABASE=Cape Verde XT [Radeon HD 7770 GHz Edition]
+ ID_MODEL_FROM_DATABASE=Cape Verde XT [Radeon HD 7770/8760 / R7 250X]
 
 pci:v00001002d0000683Dsv00001002sd00000030*
- ID_MODEL_FROM_DATABASE=Radeon HD 8760 OEM
+ ID_MODEL_FROM_DATABASE=Cape Verde XT [Radeon HD 7770/8760 / R7 250X] (Radeon HD 8760 OEM)
 
 pci:v00001002d0000683Dsv00001019sd00000030*
- ID_MODEL_FROM_DATABASE=Radeon HD 8760 OEM
+ ID_MODEL_FROM_DATABASE=Cape Verde XT [Radeon HD 7770/8760 / R7 250X] (Radeon HD 8760 OEM)
 
 pci:v00001002d0000683Dsv0000103Csd00006890*
- ID_MODEL_FROM_DATABASE=Radeon HD 8760 OEM
+ ID_MODEL_FROM_DATABASE=Cape Verde XT [Radeon HD 7770/8760 / R7 250X] (Radeon HD 8760 OEM)
+
+pci:v00001002d0000683Dsv00001043sd00008760*
+ ID_MODEL_FROM_DATABASE=Cape Verde XT [Radeon HD 7770/8760 / R7 250X] (Radeon HD 8760 OEM)
+
+pci:v00001002d0000683Dsv00001462sd00002710*
+ ID_MODEL_FROM_DATABASE=Cape Verde XT [Radeon HD 7770/8760 / R7 250X] (R7770-PMD1GD5)
+
+pci:v00001002d0000683Dsv0000174Bsd00008304*
+ ID_MODEL_FROM_DATABASE=Cape Verde XT [Radeon HD 7770/8760 / R7 250X] (Radeon HD 8760 OEM)
 
 pci:v00001002d0000683F*
- ID_MODEL_FROM_DATABASE=Cape Verde PRO [Radeon HD 7750]
+ ID_MODEL_FROM_DATABASE=Cape Verde PRO [Radeon HD 7750 / R7 250E]
 
 pci:v00001002d00006840*
  ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series]
 
 pci:v00001002d00006840sv00001025sd0000050E*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001025sd0000050F*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001025sd00000513*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001025sd00000514*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001025sd0000056D*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001025sd0000059A*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001025sd0000059B*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001025sd0000059E*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001025sd00000600*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001025sd00000606*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001025sd00000696*
- ID_MODEL_FROM_DATABASE=Radeon HD 7650M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7650M)
 
 pci:v00001002d00006840sv00001025sd00000697*
- ID_MODEL_FROM_DATABASE=Radeon HD 7650M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7650M)
 
 pci:v00001002d00006840sv00001025sd00000698*
- ID_MODEL_FROM_DATABASE=Radeon HD 7650M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7650M)
 
 pci:v00001002d00006840sv00001025sd00000699*
- ID_MODEL_FROM_DATABASE=Radeon HD 7650M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7650M)
 
 pci:v00001002d00006840sv00001025sd00000757*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001028sd0000056A*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001028sd0000056E*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001028sd00000598*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001028sd0000059D*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001028sd000005A3*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001028sd000005B9*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001028sd000005BB*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv0000103Csd000017F1*
- ID_MODEL_FROM_DATABASE=Radeon HD 7570M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7570M)
 
 pci:v00001002d00006840sv0000103Csd000017F4*
- ID_MODEL_FROM_DATABASE=Radeon HD 7650M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7650M)
 
 pci:v00001002d00006840sv0000103Csd00001813*
- ID_MODEL_FROM_DATABASE=Radeon HD 7590M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7590M)
 
 pci:v00001002d00006840sv0000103Csd0000182F*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv0000103Csd00001830*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv0000103Csd00001835*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv0000103Csd0000183A*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv0000103Csd0000183C*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv0000103Csd0000183E*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv0000103Csd00001840*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv0000103Csd00001842*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv0000103Csd00001844*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv0000103Csd00001848*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv0000103Csd0000184A*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv0000103Csd0000184C*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv0000103Csd00001895*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv0000103Csd00001897*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv0000103Csd000018A5*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv0000103Csd000018A7*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv0000103Csd000018F4*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001043sd0000100A*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001043sd0000104B*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001043sd000010DC*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001043sd00002121*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001043sd00002122*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001043sd00002123*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001043sd00002125*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001043sd00002127*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001179sd0000FB11*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001179sd0000FB22*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001179sd0000FB23*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001179sd0000FB2C*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001179sd0000FB31*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001179sd0000FB32*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001179sd0000FB38*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001179sd0000FB39*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001179sd0000FB3A*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001179sd0000FB40*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001179sd0000FB41*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001179sd0000FB47*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001179sd0000FB48*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001179sd0000FB51*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001179sd0000FB52*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001179sd0000FB53*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001179sd0000FB81*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001179sd0000FB82*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001179sd0000FB83*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001179sd0000FC56*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001179sd0000FCD4*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv00001179sd0000FCEE*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv0000144Dsd0000C0C5*
- ID_MODEL_FROM_DATABASE=Radeon HD 7690M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7690M)
 
 pci:v00001002d00006840sv0000144Dsd0000C0CE*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv0000144Dsd0000C0DA*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv000017AAsd00003970*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv000017AAsd0000397B*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv000017AAsd00005101*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv000017AAsd00005102*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006840sv000017AAsd00005103*
- ID_MODEL_FROM_DATABASE=Radeon HD 7670M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7500M/7600M Series] (Radeon HD 7670M)
 
 pci:v00001002d00006841*
  ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7550M/7570M/7650M]
 
 pci:v00001002d00006841sv00001028sd00000561*
- ID_MODEL_FROM_DATABASE=Radeon HD 7650M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7550M/7570M/7650M] (Radeon HD 7650M)
 
 pci:v00001002d00006841sv00001028sd0000056C*
- ID_MODEL_FROM_DATABASE=Radeon HD 7650M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7550M/7570M/7650M] (Radeon HD 7650M)
 
 pci:v00001002d00006841sv00001028sd0000057F*
- ID_MODEL_FROM_DATABASE=Radeon HD 7570M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7550M/7570M/7650M] (Radeon HD 7570M)
 
 pci:v00001002d00006841sv0000103Csd000017F1*
- ID_MODEL_FROM_DATABASE=Radeon HD 7570M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7550M/7570M/7650M] (Radeon HD 7570M)
 
 pci:v00001002d00006841sv0000103Csd000017F4*
- ID_MODEL_FROM_DATABASE=Radeon HD 7650M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7550M/7570M/7650M] (Radeon HD 7650M)
 
 pci:v00001002d00006841sv0000103Csd00001813*
- ID_MODEL_FROM_DATABASE=Radeon HD 7570M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7550M/7570M/7650M] (Radeon HD 7570M)
 
 pci:v00001002d00006841sv0000103Csd0000183A*
- ID_MODEL_FROM_DATABASE=Radeon HD 7650M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7550M/7570M/7650M] (Radeon HD 7650M)
 
 pci:v00001002d00006841sv0000103Csd0000183C*
- ID_MODEL_FROM_DATABASE=Radeon HD 7650M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7550M/7570M/7650M] (Radeon HD 7650M)
 
 pci:v00001002d00006841sv0000103Csd0000183E*
- ID_MODEL_FROM_DATABASE=Radeon HD 7650M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7550M/7570M/7650M] (Radeon HD 7650M)
 
 pci:v00001002d00006841sv0000103Csd00001840*
- ID_MODEL_FROM_DATABASE=Radeon HD 7650M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7550M/7570M/7650M] (Radeon HD 7650M)
 
 pci:v00001002d00006841sv0000103Csd00001842*
- ID_MODEL_FROM_DATABASE=Radeon HD 7650M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7550M/7570M/7650M] (Radeon HD 7650M)
 
 pci:v00001002d00006841sv0000103Csd00001844*
- ID_MODEL_FROM_DATABASE=Radeon HD 7650M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7550M/7570M/7650M] (Radeon HD 7650M)
 
 pci:v00001002d00006841sv00001043sd0000100A*
- ID_MODEL_FROM_DATABASE=Radeon HD 7650M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7550M/7570M/7650M] (Radeon HD 7650M)
 
 pci:v00001002d00006841sv00001043sd0000104B*
- ID_MODEL_FROM_DATABASE=Radeon HD 7650M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7550M/7570M/7650M] (Radeon HD 7650M)
 
 pci:v00001002d00006841sv00001043sd000010DC*
- ID_MODEL_FROM_DATABASE=Radeon HD 7650M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7550M/7570M/7650M] (Radeon HD 7650M)
 
 pci:v00001002d00006841sv00001043sd00002134*
- ID_MODEL_FROM_DATABASE=Radeon HD 7650M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7550M/7570M/7650M] (Radeon HD 7650M)
 
 pci:v00001002d00006841sv00001179sd00000001*
- ID_MODEL_FROM_DATABASE=Radeon HD 7570M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7550M/7570M/7650M] (Radeon HD 7570M)
 
 pci:v00001002d00006841sv00001179sd00000002*
- ID_MODEL_FROM_DATABASE=Radeon HD 7570M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7550M/7570M/7650M] (Radeon HD 7570M)
 
 pci:v00001002d00006841sv00001179sd0000FB43*
- ID_MODEL_FROM_DATABASE=Radeon HD 7550M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7550M/7570M/7650M] (Radeon HD 7550M)
 
 pci:v00001002d00006841sv00001179sd0000FB91*
- ID_MODEL_FROM_DATABASE=Radeon HD 7550M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7550M/7570M/7650M] (Radeon HD 7550M)
 
 pci:v00001002d00006841sv00001179sd0000FB92*
- ID_MODEL_FROM_DATABASE=Radeon HD 7550M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7550M/7570M/7650M] (Radeon HD 7550M)
 
 pci:v00001002d00006841sv00001179sd0000FB93*
- ID_MODEL_FROM_DATABASE=Radeon HD 7550M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7550M/7570M/7650M] (Radeon HD 7550M)
 
 pci:v00001002d00006841sv00001179sd0000FBA2*
- ID_MODEL_FROM_DATABASE=Radeon HD 7550M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7550M/7570M/7650M] (Radeon HD 7550M)
 
 pci:v00001002d00006841sv00001179sd0000FBA3*
- ID_MODEL_FROM_DATABASE=Radeon HD 7550M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7550M/7570M/7650M] (Radeon HD 7550M)
 
 pci:v00001002d00006841sv0000144Dsd0000C0C7*
- ID_MODEL_FROM_DATABASE=Radeon HD 7550M
+ ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7550M/7570M/7650M] (Radeon HD 7550M)
 
 pci:v00001002d00006842*
  ID_MODEL_FROM_DATABASE=Thames LE [Radeon HD 7000M Series]
@@ -6387,13 +6498,13 @@ pci:v00001002d00006889*
  ID_MODEL_FROM_DATABASE=Cypress PRO [FirePro V7800]
 
 pci:v00001002d00006889sv00001002sd00000301*
- ID_MODEL_FROM_DATABASE=FirePro V7800P
+ ID_MODEL_FROM_DATABASE=Cypress PRO [FirePro V7800] (FirePro V7800P)
 
 pci:v00001002d0000688A*
  ID_MODEL_FROM_DATABASE=Cypress XT [FirePro V9800]
 
 pci:v00001002d0000688Asv00001002sd0000030C*
- ID_MODEL_FROM_DATABASE=FirePro V9800P
+ ID_MODEL_FROM_DATABASE=Cypress XT [FirePro V9800] (FirePro V9800P)
 
 pci:v00001002d0000688C*
  ID_MODEL_FROM_DATABASE=Cypress XT GL [FireStream 9370]
@@ -6405,28 +6516,28 @@ pci:v00001002d00006898*
  ID_MODEL_FROM_DATABASE=Cypress XT [Radeon HD 5870]
 
 pci:v00001002d00006898sv00001002sd00000B00*
- ID_MODEL_FROM_DATABASE=Radeon HD 5870 Eyefinity⁶ Edition
+ ID_MODEL_FROM_DATABASE=Cypress XT [Radeon HD 5870] (Radeon HD 5870 Eyefinity⁶ Edition)
 
 pci:v00001002d00006898sv0000106Bsd000000D0*
- ID_MODEL_FROM_DATABASE=Radeon HD 5870 Mac Edition
+ ID_MODEL_FROM_DATABASE=Cypress XT [Radeon HD 5870] (Radeon HD 5870 Mac Edition)
 
 pci:v00001002d00006898sv00001462sd00008032*
- ID_MODEL_FROM_DATABASE=Radeon HD 5870 1 GB GDDR5
+ ID_MODEL_FROM_DATABASE=Cypress XT [Radeon HD 5870] (Radeon HD 5870 1 GB GDDR5)
 
 pci:v00001002d00006898sv0000174Bsd00006870*
- ID_MODEL_FROM_DATABASE=Radeon HD 6870 1600SP Edition
+ ID_MODEL_FROM_DATABASE=Cypress XT [Radeon HD 5870] (Radeon HD 6870 1600SP Edition)
 
 pci:v00001002d00006899*
  ID_MODEL_FROM_DATABASE=Cypress PRO [Radeon HD 5850]
 
 pci:v00001002d00006899sv00001043sd00000330*
- ID_MODEL_FROM_DATABASE=Radeon HD 5850
+ ID_MODEL_FROM_DATABASE=Cypress PRO [Radeon HD 5850] (Radeon HD 5850)
 
 pci:v00001002d00006899sv0000174Bsd0000237B*
- ID_MODEL_FROM_DATABASE=Radeon HD 5850 X2
+ ID_MODEL_FROM_DATABASE=Cypress PRO [Radeon HD 5850] (Radeon HD 5850 X2)
 
 pci:v00001002d00006899sv0000174Bsd00006850*
- ID_MODEL_FROM_DATABASE=Radeon HD 6850 1440SP Edition
+ ID_MODEL_FROM_DATABASE=Cypress PRO [Radeon HD 5850] (Radeon HD 6850 1440SP Edition)
 
 pci:v00001002d0000689B*
  ID_MODEL_FROM_DATABASE=Cypress PRO [Radeon HD 6800 Series]
@@ -6435,7 +6546,7 @@ pci:v00001002d0000689C*
  ID_MODEL_FROM_DATABASE=Hemlock [Radeon HD 5970]
 
 pci:v00001002d0000689Csv00001043sd00000352*
- ID_MODEL_FROM_DATABASE=ARES
+ ID_MODEL_FROM_DATABASE=Hemlock [Radeon HD 5970] (ARES)
 
 pci:v00001002d0000689D*
  ID_MODEL_FROM_DATABASE=Hemlock [Radeon HD 5970]
@@ -6447,79 +6558,79 @@ pci:v00001002d000068A0*
  ID_MODEL_FROM_DATABASE=Broadway XT [Mobility Radeon HD 5870]
 
 pci:v00001002d000068A0sv00001028sd000012EF*
- ID_MODEL_FROM_DATABASE=FirePro M7820
+ ID_MODEL_FROM_DATABASE=Broadway XT [Mobility Radeon HD 5870] (FirePro M7820)
 
 pci:v00001002d000068A0sv0000103Csd00001520*
- ID_MODEL_FROM_DATABASE=FirePro M7820
+ ID_MODEL_FROM_DATABASE=Broadway XT [Mobility Radeon HD 5870] (FirePro M7820)
 
 pci:v00001002d000068A1*
  ID_MODEL_FROM_DATABASE=Broadway PRO [Mobility Radeon HD 5850]
 
 pci:v00001002d000068A1sv0000106Bsd000000CC*
- ID_MODEL_FROM_DATABASE=iMac MC511 Mobility Radeon HD 5850 MXM Module
+ ID_MODEL_FROM_DATABASE=Broadway PRO [Mobility Radeon HD 5850] (iMac MC511 Mobility Radeon HD 5850 MXM Module)
 
 pci:v00001002d000068A8*
  ID_MODEL_FROM_DATABASE=Granville [Radeon HD 6850M/6870M]
 
 pci:v00001002d000068A8sv00001025sd00000442*
- ID_MODEL_FROM_DATABASE=Radeon HD 6850M
+ ID_MODEL_FROM_DATABASE=Granville [Radeon HD 6850M/6870M] (Radeon HD 6850M)
 
 pci:v00001002d000068A8sv00001025sd00000451*
- ID_MODEL_FROM_DATABASE=Radeon HD 6850M
+ ID_MODEL_FROM_DATABASE=Granville [Radeon HD 6850M/6870M] (Radeon HD 6850M)
 
 pci:v00001002d000068A8sv00001025sd0000050A*
- ID_MODEL_FROM_DATABASE=Radeon HD 6850M
+ ID_MODEL_FROM_DATABASE=Granville [Radeon HD 6850M/6870M] (Radeon HD 6850M)
 
 pci:v00001002d000068A8sv00001025sd0000050B*
- ID_MODEL_FROM_DATABASE=Radeon HD 6850M
+ ID_MODEL_FROM_DATABASE=Granville [Radeon HD 6850M/6870M] (Radeon HD 6850M)
 
 pci:v00001002d000068A8sv00001025sd0000050C*
- ID_MODEL_FROM_DATABASE=Radeon HD 6850M
+ ID_MODEL_FROM_DATABASE=Granville [Radeon HD 6850M/6870M] (Radeon HD 6850M)
 
 pci:v00001002d000068A8sv00001025sd0000050E*
- ID_MODEL_FROM_DATABASE=Radeon HD 6850M
+ ID_MODEL_FROM_DATABASE=Granville [Radeon HD 6850M/6870M] (Radeon HD 6850M)
 
 pci:v00001002d000068A8sv00001025sd0000050F*
- ID_MODEL_FROM_DATABASE=Radeon HD 6850M
+ ID_MODEL_FROM_DATABASE=Granville [Radeon HD 6850M/6870M] (Radeon HD 6850M)
 
 pci:v00001002d000068A8sv00001025sd00000513*
- ID_MODEL_FROM_DATABASE=Radeon HD 6850M
+ ID_MODEL_FROM_DATABASE=Granville [Radeon HD 6850M/6870M] (Radeon HD 6850M)
 
 pci:v00001002d000068A8sv00001025sd00000514*
- ID_MODEL_FROM_DATABASE=Radeon HD 6850M
+ ID_MODEL_FROM_DATABASE=Granville [Radeon HD 6850M/6870M] (Radeon HD 6850M)
 
 pci:v00001002d000068A8sv00001025sd00000515*
- ID_MODEL_FROM_DATABASE=Radeon HD 6850M
+ ID_MODEL_FROM_DATABASE=Granville [Radeon HD 6850M/6870M] (Radeon HD 6850M)
 
 pci:v00001002d000068A8sv00001025sd00000516*
- ID_MODEL_FROM_DATABASE=Radeon HD 6850M
+ ID_MODEL_FROM_DATABASE=Granville [Radeon HD 6850M/6870M] (Radeon HD 6850M)
 
 pci:v00001002d000068A8sv00001025sd00000525*
- ID_MODEL_FROM_DATABASE=Radeon HD 6850M
+ ID_MODEL_FROM_DATABASE=Granville [Radeon HD 6850M/6870M] (Radeon HD 6850M)
 
 pci:v00001002d000068A8sv00001025sd00000526*
- ID_MODEL_FROM_DATABASE=Radeon HD 6850M
+ ID_MODEL_FROM_DATABASE=Granville [Radeon HD 6850M/6870M] (Radeon HD 6850M)
 
 pci:v00001002d000068A8sv00001025sd0000056D*
- ID_MODEL_FROM_DATABASE=Radeon HD 6850M
+ ID_MODEL_FROM_DATABASE=Granville [Radeon HD 6850M/6870M] (Radeon HD 6850M)
 
 pci:v00001002d000068A8sv00001028sd0000048F*
- ID_MODEL_FROM_DATABASE=Radeon HD 6870M
+ ID_MODEL_FROM_DATABASE=Granville [Radeon HD 6850M/6870M] (Radeon HD 6870M)
 
 pci:v00001002d000068A8sv00001028sd00000490*
- ID_MODEL_FROM_DATABASE=Radeon HD 6870M
+ ID_MODEL_FROM_DATABASE=Granville [Radeon HD 6850M/6870M] (Radeon HD 6870M)
 
 pci:v00001002d000068A8sv00001028sd000004B9*
- ID_MODEL_FROM_DATABASE=Radeon HD 6870M
+ ID_MODEL_FROM_DATABASE=Granville [Radeon HD 6850M/6870M] (Radeon HD 6870M)
 
 pci:v00001002d000068A8sv00001028sd000004BA*
- ID_MODEL_FROM_DATABASE=Radeon HD 6870M
+ ID_MODEL_FROM_DATABASE=Granville [Radeon HD 6850M/6870M] (Radeon HD 6870M)
 
 pci:v00001002d000068A8sv0000103Csd0000159B*
- ID_MODEL_FROM_DATABASE=Radeon HD 6850M
+ ID_MODEL_FROM_DATABASE=Granville [Radeon HD 6850M/6870M] (Radeon HD 6850M)
 
 pci:v00001002d000068A8sv0000144Dsd0000C0AD*
- ID_MODEL_FROM_DATABASE=Radeon HD 6850M
+ ID_MODEL_FROM_DATABASE=Granville [Radeon HD 6850M/6870M] (Radeon HD 6850M)
 
 pci:v00001002d000068A9*
  ID_MODEL_FROM_DATABASE=Juniper XT [FirePro V5800]
@@ -6528,7 +6639,7 @@ pci:v00001002d000068B8*
  ID_MODEL_FROM_DATABASE=Juniper XT [Radeon HD 5770]
 
 pci:v00001002d000068B8sv0000106Bsd000000CF*
- ID_MODEL_FROM_DATABASE=MacPro5,1 [Mac Pro 2.8GHz DDR3]
+ ID_MODEL_FROM_DATABASE=Juniper XT [Radeon HD 5770] (MacPro5,1 [Mac Pro 2.8GHz DDR3])
 
 pci:v00001002d000068B9*
  ID_MODEL_FROM_DATABASE=Juniper LE [Radeon HD 5670 640SP Edition]
@@ -6540,466 +6651,466 @@ pci:v00001002d000068BE*
  ID_MODEL_FROM_DATABASE=Juniper PRO [Radeon HD 5750]
 
 pci:v00001002d000068BEsv0000148Csd00003000*
- ID_MODEL_FROM_DATABASE=Radeon HD 6750
+ ID_MODEL_FROM_DATABASE=Juniper PRO [Radeon HD 5750] (Radeon HD 6750)
 
 pci:v00001002d000068BF*
  ID_MODEL_FROM_DATABASE=Juniper PRO [Radeon HD 6750]
 
 pci:v00001002d000068BFsv0000174Bsd00006750*
- ID_MODEL_FROM_DATABASE=Radeon HD 6750
+ ID_MODEL_FROM_DATABASE=Juniper PRO [Radeon HD 6750] (Radeon HD 6750)
 
 pci:v00001002d000068C0*
  ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5730 / 6570M]
 
 pci:v00001002d000068C0sv00001019sd00002383*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5730
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5730 / 6570M] (Mobility Radeon HD 5730)
 
 pci:v00001002d000068C0sv00001028sd000002A2*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5730
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5730 / 6570M] (Mobility Radeon HD 5730)
 
 pci:v00001002d000068C0sv00001028sd000002FE*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5730
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5730 / 6570M] (Mobility Radeon HD 5730)
 
 pci:v00001002d000068C0sv00001028sd00000419*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5730
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5730 / 6570M] (Mobility Radeon HD 5730)
 
 pci:v00001002d000068C0sv0000103Csd0000147D*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5730
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5730 / 6570M] (Mobility Radeon HD 5730)
 
 pci:v00001002d000068C0sv0000103Csd00001521*
- ID_MODEL_FROM_DATABASE=Madison XT [FirePro M5800]
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5730 / 6570M] (Madison XT [FirePro M5800])
 
 pci:v00001002d000068C0sv0000103Csd00001593*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 6570
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5730 / 6570M] (Mobility Radeon HD 6570)
 
 pci:v00001002d000068C0sv0000103Csd00001596*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 6570
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5730 / 6570M] (Mobility Radeon HD 6570)
 
 pci:v00001002d000068C0sv0000103Csd00001599*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 6570
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5730 / 6570M] (Mobility Radeon HD 6570)
 
 pci:v00001002d000068C0sv00001043sd00001C22*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5730
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5730 / 6570M] (Mobility Radeon HD 5730)
 
 pci:v00001002d000068C0sv000017AAsd00003927*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5730
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5730 / 6570M] (Mobility Radeon HD 5730)
 
 pci:v00001002d000068C0sv000017AAsd00003952*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5730
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5730 / 6570M] (Mobility Radeon HD 5730)
 
 pci:v00001002d000068C0sv000017AAsd00003978*
- ID_MODEL_FROM_DATABASE=Radeon HD 6570M
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5730 / 6570M] (Radeon HD 6570M)
 
 pci:v00001002d000068C1*
  ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M]
 
 pci:v00001002d000068C1sv00001025sd00000205*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000293*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000294*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000296*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000308*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd0000030A*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000311*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000312*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd0000031C*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd0000031D*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd0000033D*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd0000033E*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd0000033F*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000346*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000347*
- ID_MODEL_FROM_DATABASE=Aspire 7740G
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Aspire 7740G)
 
 pci:v00001002d000068C1sv00001025sd00000348*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000356*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000357*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000358*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000359*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd0000035A*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd0000035B*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd0000035C*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd0000035D*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd0000035E*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000360*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000362*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000364*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000365*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000366*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000367*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000368*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd0000036C*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd0000036D*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd0000036E*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd0000036F*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000372*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000373*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000377*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000378*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000379*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd0000037A*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd0000037B*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd0000037E*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd0000037F*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000382*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000383*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000384*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000385*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000386*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000387*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000388*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd0000038B*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd0000038C*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd0000039A*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000411*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000412*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000418*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000419*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000420*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000421*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000425*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd0000042A*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd0000042E*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd0000042F*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000432*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000433*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000442*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd0000044C*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd0000044E*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000451*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000454*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000455*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000475*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000476*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000487*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000489*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000498*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001025sd00000517*
- ID_MODEL_FROM_DATABASE=Radeon HD 6550M
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Radeon HD 6550M)
 
 pci:v00001002d000068C1sv00001025sd0000051A*
- ID_MODEL_FROM_DATABASE=Radeon HD 6550M
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Radeon HD 6550M)
 
 pci:v00001002d000068C1sv00001025sd0000051B*
- ID_MODEL_FROM_DATABASE=Radeon HD 6550M
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Radeon HD 6550M)
 
 pci:v00001002d000068C1sv00001025sd0000051C*
- ID_MODEL_FROM_DATABASE=Radeon HD 6550M
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Radeon HD 6550M)
 
 pci:v00001002d000068C1sv00001025sd0000051D*
- ID_MODEL_FROM_DATABASE=Radeon HD 6550M
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Radeon HD 6550M)
 
 pci:v00001002d000068C1sv00001025sd00000525*
- ID_MODEL_FROM_DATABASE=Radeon HD 6550M
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Radeon HD 6550M)
 
 pci:v00001002d000068C1sv00001025sd00000526*
- ID_MODEL_FROM_DATABASE=Radeon HD 6550M
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Radeon HD 6550M)
 
 pci:v00001002d000068C1sv00001025sd0000052B*
- ID_MODEL_FROM_DATABASE=Radeon HD 6550M
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Radeon HD 6550M)
 
 pci:v00001002d000068C1sv00001025sd0000052C*
- ID_MODEL_FROM_DATABASE=Radeon HD 6550M
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Radeon HD 6550M)
 
 pci:v00001002d000068C1sv00001025sd0000053C*
- ID_MODEL_FROM_DATABASE=Radeon HD 6550M
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Radeon HD 6550M)
 
 pci:v00001002d000068C1sv00001025sd0000053D*
- ID_MODEL_FROM_DATABASE=Radeon HD 6550M
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Radeon HD 6550M)
 
 pci:v00001002d000068C1sv00001025sd0000053E*
- ID_MODEL_FROM_DATABASE=Radeon HD 6550M
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Radeon HD 6550M)
 
 pci:v00001002d000068C1sv00001025sd0000053F*
- ID_MODEL_FROM_DATABASE=Radeon HD 6550M
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Radeon HD 6550M)
 
 pci:v00001002d000068C1sv00001025sd00000607*
- ID_MODEL_FROM_DATABASE=Radeon HD 6550M
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Radeon HD 6550M)
 
 pci:v00001002d000068C1sv00001028sd0000041B*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001028sd00000447*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001028sd00000448*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001028sd00000456*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001028sd00000457*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv0000103Csd00001436*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv0000103Csd00001437*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv0000103Csd00001440*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv0000103Csd00001448*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv0000103Csd00001449*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv0000103Csd0000144A*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv0000103Csd0000144B*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv0000103Csd0000147B*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv0000103Csd0000149C*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv0000103Csd0000149E*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv0000103Csd00001521*
- ID_MODEL_FROM_DATABASE=Madison Pro [FirePro M5800]
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Madison Pro [FirePro M5800])
 
 pci:v00001002d000068C1sv00001043sd00001BC2*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv0000104Dsd00009071*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv0000104Dsd00009077*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv0000104Dsd00009081*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001179sd0000FD00*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001179sd0000FD12*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001179sd0000FD1A*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001179sd0000FD30*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001179sd0000FD31*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001179sd0000FD50*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001179sd0000FD52*
- ID_MODEL_FROM_DATABASE=Radeon HD 6530M
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Radeon HD 6530M)
 
 pci:v00001002d000068C1sv00001179sd0000FD63*
- ID_MODEL_FROM_DATABASE=Radeon HD 6530M
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Radeon HD 6530M)
 
 pci:v00001002d000068C1sv00001179sd0000FD65*
- ID_MODEL_FROM_DATABASE=Radeon HD 6530M
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Radeon HD 6530M)
 
 pci:v00001002d000068C1sv00001179sd0000FDD0*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv00001179sd0000FDD2*
- ID_MODEL_FROM_DATABASE=Radeon HD 6530M
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Radeon HD 6530M)
 
 pci:v00001002d000068C1sv0000144Dsd0000C07E*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv0000144Dsd0000C085*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv000014C0sd00000043*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv000014C0sd0000004D*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv000017AAsd00003928*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv000017AAsd00003951*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Mobility Radeon HD 5650)
 
 pci:v00001002d000068C1sv000017AAsd00003977*
- ID_MODEL_FROM_DATABASE=Radeon HD 6550M
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5650/5750 / 6530M/6550M] (Radeon HD 6550M)
 
 pci:v00001002d000068C7*
  ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5570/6550A]
 
 pci:v00001002d000068C7sv00001462sd00002241*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5570
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5570/6550A] (Mobility Radeon HD 5570)
 
 pci:v00001002d000068C7sv00001462sd00002243*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5570
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5570/6550A] (Mobility Radeon HD 5570)
 
 pci:v00001002d000068C7sv00001462sd00002244*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5570
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5570/6550A] (Mobility Radeon HD 5570)
 
 pci:v00001002d000068C7sv00001462sd00002245*
- ID_MODEL_FROM_DATABASE=Radeon HD 6550A
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5570/6550A] (Radeon HD 6550A)
 
 pci:v00001002d000068C7sv00001462sd00002246*
- ID_MODEL_FROM_DATABASE=Radeon HD 6550A
+ ID_MODEL_FROM_DATABASE=Madison [Mobility Radeon HD 5570/6550A] (Radeon HD 6550A)
 
 pci:v00001002d000068C8*
  ID_MODEL_FROM_DATABASE=Redwood XT GL [FirePro V4800]
@@ -7011,115 +7122,115 @@ pci:v00001002d000068D8*
  ID_MODEL_FROM_DATABASE=Redwood XT [Radeon HD 5670/5690/5730]
 
 pci:v00001002d000068D8sv00001028sd000068E0*
- ID_MODEL_FROM_DATABASE=Radeon HD 5670
+ ID_MODEL_FROM_DATABASE=Redwood XT [Radeon HD 5670/5690/5730] (Radeon HD 5670)
 
 pci:v00001002d000068D8sv0000174Bsd00005690*
- ID_MODEL_FROM_DATABASE=Radeon HD 5690
+ ID_MODEL_FROM_DATABASE=Redwood XT [Radeon HD 5670/5690/5730] (Radeon HD 5690)
 
 pci:v00001002d000068D8sv0000174Bsd00005730*
- ID_MODEL_FROM_DATABASE=Radeon HD 5730
+ ID_MODEL_FROM_DATABASE=Redwood XT [Radeon HD 5670/5690/5730] (Radeon HD 5730)
 
 pci:v00001002d000068D8sv0000174Bsd0000E151*
- ID_MODEL_FROM_DATABASE=Radeon HD 5670
+ ID_MODEL_FROM_DATABASE=Redwood XT [Radeon HD 5670/5690/5730] (Radeon HD 5670)
 
 pci:v00001002d000068D8sv00001787sd00003000*
- ID_MODEL_FROM_DATABASE=Radeon HD 5730
+ ID_MODEL_FROM_DATABASE=Redwood XT [Radeon HD 5670/5690/5730] (Radeon HD 5730)
 
 pci:v00001002d000068D8sv000017AFsd00003010*
- ID_MODEL_FROM_DATABASE=Radeon HD 5730
+ ID_MODEL_FROM_DATABASE=Redwood XT [Radeon HD 5670/5690/5730] (Radeon HD 5730)
 
 pci:v00001002d000068D8sv000017AFsd00003011*
- ID_MODEL_FROM_DATABASE=Radeon HD 5690
+ ID_MODEL_FROM_DATABASE=Redwood XT [Radeon HD 5670/5690/5730] (Radeon HD 5690)
 
 pci:v00001002d000068D9*
  ID_MODEL_FROM_DATABASE=Redwood PRO [Radeon HD 5550/5570/5630/6510/6610/7570]
 
 pci:v00001002d000068D9sv0000103Csd00006870*
- ID_MODEL_FROM_DATABASE=Radeon HD 5570
+ ID_MODEL_FROM_DATABASE=Redwood PRO [Radeon HD 5550/5570/5630/6510/6610/7570] (Radeon HD 5570)
 
 pci:v00001002d000068D9sv0000103Csd00006872*
- ID_MODEL_FROM_DATABASE=Radeon HD 5570
+ ID_MODEL_FROM_DATABASE=Redwood PRO [Radeon HD 5550/5570/5630/6510/6610/7570] (Radeon HD 5570)
 
 pci:v00001002d000068D9sv00001043sd000003CE*
- ID_MODEL_FROM_DATABASE=Radeon HD 5550
+ ID_MODEL_FROM_DATABASE=Redwood PRO [Radeon HD 5550/5570/5630/6510/6610/7570] (Radeon HD 5550)
 
 pci:v00001002d000068D9sv00001462sd00002151*
- ID_MODEL_FROM_DATABASE=Radeon HD 5570
+ ID_MODEL_FROM_DATABASE=Redwood PRO [Radeon HD 5550/5570/5630/6510/6610/7570] (Radeon HD 5570)
 
 pci:v00001002d000068D9sv00001462sd00002240*
- ID_MODEL_FROM_DATABASE=Radeon HD 5570
+ ID_MODEL_FROM_DATABASE=Redwood PRO [Radeon HD 5550/5570/5630/6510/6610/7570] (Radeon HD 5570)
 
 pci:v00001002d000068D9sv0000148Csd00003000*
- ID_MODEL_FROM_DATABASE=Radeon HD 6510
+ ID_MODEL_FROM_DATABASE=Redwood PRO [Radeon HD 5550/5570/5630/6510/6610/7570] (Radeon HD 6510)
 
 pci:v00001002d000068D9sv0000148Csd00003001*
- ID_MODEL_FROM_DATABASE=Radeon HD 6610
+ ID_MODEL_FROM_DATABASE=Redwood PRO [Radeon HD 5550/5570/5630/6510/6610/7570] (Radeon HD 6610)
 
 pci:v00001002d000068D9sv00001545sd00005550*
- ID_MODEL_FROM_DATABASE=Radeon HD 5550
+ ID_MODEL_FROM_DATABASE=Redwood PRO [Radeon HD 5550/5570/5630/6510/6610/7570] (Radeon HD 5550)
 
 pci:v00001002d000068D9sv00001545sd00007570*
- ID_MODEL_FROM_DATABASE=Radeon HD 7570
+ ID_MODEL_FROM_DATABASE=Redwood PRO [Radeon HD 5550/5570/5630/6510/6610/7570] (Radeon HD 7570)
 
 pci:v00001002d000068D9sv00001642sd00003985*
- ID_MODEL_FROM_DATABASE=Radeon HD 5570
+ ID_MODEL_FROM_DATABASE=Redwood PRO [Radeon HD 5550/5570/5630/6510/6610/7570] (Radeon HD 5570)
 
 pci:v00001002d000068D9sv00001642sd00003996*
- ID_MODEL_FROM_DATABASE=Radeon HD 5570
+ ID_MODEL_FROM_DATABASE=Redwood PRO [Radeon HD 5550/5570/5630/6510/6610/7570] (Radeon HD 5570)
 
 pci:v00001002d000068D9sv0000174Bsd00003000*
- ID_MODEL_FROM_DATABASE=Radeon HD 6510
+ ID_MODEL_FROM_DATABASE=Redwood PRO [Radeon HD 5550/5570/5630/6510/6610/7570] (Radeon HD 6510)
 
 pci:v00001002d000068D9sv0000174Bsd00006510*
- ID_MODEL_FROM_DATABASE=Radeon HD 6510
+ ID_MODEL_FROM_DATABASE=Redwood PRO [Radeon HD 5550/5570/5630/6510/6610/7570] (Radeon HD 6510)
 
 pci:v00001002d000068D9sv0000174Bsd00006610*
- ID_MODEL_FROM_DATABASE=Radeon HD 6610
+ ID_MODEL_FROM_DATABASE=Redwood PRO [Radeon HD 5550/5570/5630/6510/6610/7570] (Radeon HD 6610)
 
 pci:v00001002d000068D9sv0000174Bsd0000E142*
- ID_MODEL_FROM_DATABASE=Radeon HD 5570
+ ID_MODEL_FROM_DATABASE=Redwood PRO [Radeon HD 5550/5570/5630/6510/6610/7570] (Radeon HD 5570)
 
 pci:v00001002d000068D9sv00001787sd00003000*
- ID_MODEL_FROM_DATABASE=Radeon HD 6510
+ ID_MODEL_FROM_DATABASE=Redwood PRO [Radeon HD 5550/5570/5630/6510/6610/7570] (Radeon HD 6510)
 
 pci:v00001002d000068D9sv000017AFsd00003000*
- ID_MODEL_FROM_DATABASE=Radeon HD 6510
+ ID_MODEL_FROM_DATABASE=Redwood PRO [Radeon HD 5550/5570/5630/6510/6610/7570] (Radeon HD 6510)
 
 pci:v00001002d000068D9sv000017AFsd00003010*
- ID_MODEL_FROM_DATABASE=Radeon HD 5630
+ ID_MODEL_FROM_DATABASE=Redwood PRO [Radeon HD 5550/5570/5630/6510/6610/7570] (Radeon HD 5630)
 
 pci:v00001002d000068DA*
  ID_MODEL_FROM_DATABASE=Redwood LE [Radeon HD 5550/5570/5630/6390/6490/7570]
 
 pci:v00001002d000068DAsv0000148Csd00003000*
- ID_MODEL_FROM_DATABASE=Radeon HD 6390
+ ID_MODEL_FROM_DATABASE=Redwood LE [Radeon HD 5550/5570/5630/6390/6490/7570] (Radeon HD 6390)
 
 pci:v00001002d000068DAsv0000148Csd00003001*
- ID_MODEL_FROM_DATABASE=Radeon HD 6490
+ ID_MODEL_FROM_DATABASE=Redwood LE [Radeon HD 5550/5570/5630/6390/6490/7570] (Radeon HD 6490)
 
 pci:v00001002d000068DAsv00001545sd00007570*
- ID_MODEL_FROM_DATABASE=Radeon HD 7570
+ ID_MODEL_FROM_DATABASE=Redwood LE [Radeon HD 5550/5570/5630/6390/6490/7570] (Radeon HD 7570)
 
 pci:v00001002d000068DAsv0000174Bsd00003000*
- ID_MODEL_FROM_DATABASE=Radeon HD 6390
+ ID_MODEL_FROM_DATABASE=Redwood LE [Radeon HD 5550/5570/5630/6390/6490/7570] (Radeon HD 6390)
 
 pci:v00001002d000068DAsv0000174Bsd00005570*
- ID_MODEL_FROM_DATABASE=Radeon HD 5570
+ ID_MODEL_FROM_DATABASE=Redwood LE [Radeon HD 5550/5570/5630/6390/6490/7570] (Radeon HD 5570)
 
 pci:v00001002d000068DAsv0000174Bsd00005630*
- ID_MODEL_FROM_DATABASE=Radeon HD 5630
+ ID_MODEL_FROM_DATABASE=Redwood LE [Radeon HD 5550/5570/5630/6390/6490/7570] (Radeon HD 5630)
 
 pci:v00001002d000068DAsv0000174Bsd00006490*
- ID_MODEL_FROM_DATABASE=Radeon HD 6490
+ ID_MODEL_FROM_DATABASE=Redwood LE [Radeon HD 5550/5570/5630/6390/6490/7570] (Radeon HD 6490)
 
 pci:v00001002d000068DAsv00001787sd00003000*
- ID_MODEL_FROM_DATABASE=Radeon HD 5630
+ ID_MODEL_FROM_DATABASE=Redwood LE [Radeon HD 5550/5570/5630/6390/6490/7570] (Radeon HD 5630)
 
 pci:v00001002d000068DAsv000017AFsd00003000*
- ID_MODEL_FROM_DATABASE=Radeon HD 6390
+ ID_MODEL_FROM_DATABASE=Redwood LE [Radeon HD 5550/5570/5630/6390/6490/7570] (Radeon HD 6390)
 
 pci:v00001002d000068DAsv000017AFsd00003010*
- ID_MODEL_FROM_DATABASE=Radeon HD 5630
+ ID_MODEL_FROM_DATABASE=Redwood LE [Radeon HD 5550/5570/5630/6390/6490/7570] (Radeon HD 5630)
 
 pci:v00001002d000068DE*
  ID_MODEL_FROM_DATABASE=Redwood
@@ -7128,349 +7239,349 @@ pci:v00001002d000068E0*
  ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430/5450/5470]
 
 pci:v00001002d000068E0sv00001028sd00000404*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5450
+ ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430/5450/5470] (Mobility Radeon HD 5450)
 
 pci:v00001002d000068E0sv00001028sd00000414*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5450
+ ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430/5450/5470] (Mobility Radeon HD 5450)
 
 pci:v00001002d000068E0sv00001028sd00000434*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5450
+ ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430/5450/5470] (Mobility Radeon HD 5450)
 
 pci:v00001002d000068E0sv0000103Csd00001433*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5450
+ ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430/5450/5470] (Mobility Radeon HD 5450)
 
 pci:v00001002d000068E0sv0000103Csd00001434*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5450
+ ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430/5450/5470] (Mobility Radeon HD 5450)
 
 pci:v00001002d000068E0sv0000103Csd00001469*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5450
+ ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430/5450/5470] (Mobility Radeon HD 5450)
 
 pci:v00001002d000068E0sv0000103Csd0000146B*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5450
+ ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430/5450/5470] (Mobility Radeon HD 5450)
 
 pci:v00001002d000068E0sv0000103Csd00001486*
- ID_MODEL_FROM_DATABASE=TouchSmart tm2-2050er discrete GPU (Mobility Radeon HD 5450)
+ ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430/5450/5470] (TouchSmart tm2-2050er discrete GPU (Mobility Radeon HD 5450))
 
 pci:v00001002d000068E0sv0000103Csd00001622*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5450
+ ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430/5450/5470] (Mobility Radeon HD 5450)
 
 pci:v00001002d000068E0sv0000103Csd00001623*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5450
+ ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430/5450/5470] (Mobility Radeon HD 5450)
 
 pci:v00001002d000068E0sv0000103Csd0000EEEE*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5450
+ ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430/5450/5470] (Mobility Radeon HD 5450)
 
 pci:v00001002d000068E0sv0000104Dsd00009076*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5450
+ ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430/5450/5470] (Mobility Radeon HD 5450)
 
 pci:v00001002d000068E0sv00001682sd0000304E*
- ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 5450]
+ ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430/5450/5470] (Caicos [Radeon HD 5450])
 
 pci:v00001002d000068E0sv00001682sd00006000*
- ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 5450]
+ ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430/5450/5470] (Caicos [Radeon HD 5450])
 
 pci:v00001002d000068E0sv000017AAsd00009E52*
- ID_MODEL_FROM_DATABASE=FirePro M3800
+ ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430/5450/5470] (FirePro M3800)
 
 pci:v00001002d000068E0sv000017AAsd00009E53*
- ID_MODEL_FROM_DATABASE=FirePro M3800
+ ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430/5450/5470] (FirePro M3800)
 
 pci:v00001002d000068E1*
  ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430]
 
 pci:v00001002d000068E1sv00001043sd0000041F*
- ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 7350]
+ ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430] (Caicos [Radeon HD 7350])
 
 pci:v00001002d000068E1sv00001043sd00003000*
- ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 5450]
+ ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430] (Caicos [Radeon HD 5450])
 
 pci:v00001002d000068E1sv0000148Csd00003000*
- ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 5450]
+ ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430] (Caicos [Radeon HD 5450])
 
 pci:v00001002d000068E1sv0000148Csd00003001*
- ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6230]
+ ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430] (Caicos [Radeon HD 6230])
 
 pci:v00001002d000068E1sv0000148Csd00003002*
- ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6250]
+ ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430] (Caicos [Radeon HD 6250])
 
 pci:v00001002d000068E1sv0000148Csd00003003*
- ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6350]
+ ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430] (Caicos [Radeon HD 6350])
 
 pci:v00001002d000068E1sv0000148Csd00007350*
- ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 7350]
+ ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430] (Caicos [Radeon HD 7350])
 
 pci:v00001002d000068E1sv0000148Csd00008350*
- ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 8350]
+ ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430] (Caicos [Radeon HD 8350])
 
 pci:v00001002d000068E1sv00001545sd00005450*
- ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 5450]
+ ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430] (Caicos [Radeon HD 5450])
 
 pci:v00001002d000068E1sv00001545sd00007350*
- ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 7350]
+ ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430] (Caicos [Radeon HD 7350])
 
 pci:v00001002d000068E1sv00001682sd00003000*
- ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 5450]
+ ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430] (Caicos [Radeon HD 5450])
 
 pci:v00001002d000068E1sv00001682sd00006000*
- ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 5450]
+ ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430] (Caicos [Radeon HD 5450])
 
 pci:v00001002d000068E1sv00001682sd00007350*
- ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 7350]
+ ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430] (Caicos [Radeon HD 7350])
 
 pci:v00001002d000068E1sv0000174Bsd00003000*
- ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 5450]
+ ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430] (Caicos [Radeon HD 5450])
 
 pci:v00001002d000068E1sv0000174Bsd00005470*
- ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 5470]
+ ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430] (Caicos [Radeon HD 5470])
 
 pci:v00001002d000068E1sv0000174Bsd00006000*
- ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 5450]
+ ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430] (Caicos [Radeon HD 5450])
 
 pci:v00001002d000068E1sv0000174Bsd00006230*
- ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6230]
+ ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430] (Caicos [Radeon HD 6230])
 
 pci:v00001002d000068E1sv0000174Bsd00006350*
- ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6350]
+ ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430] (Caicos [Radeon HD 6350])
 
 pci:v00001002d000068E1sv0000174Bsd00007350*
- ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 7350]
+ ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430] (Caicos [Radeon HD 7350])
 
 pci:v00001002d000068E1sv00001787sd00003000*
- ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 5450]
+ ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430] (Caicos [Radeon HD 5450])
 
 pci:v00001002d000068E1sv000017AFsd00003000*
- ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 5450]
+ ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430] (Caicos [Radeon HD 5450])
 
 pci:v00001002d000068E1sv000017AFsd00003001*
- ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6230]
+ ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430] (Caicos [Radeon HD 6230])
 
 pci:v00001002d000068E1sv000017AFsd00003014*
- ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 6350]
+ ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430] (Caicos [Radeon HD 6350])
 
 pci:v00001002d000068E1sv000017AFsd00003015*
- ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 7350]
+ ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430] (Caicos [Radeon HD 7350])
 
 pci:v00001002d000068E1sv000017AFsd00008350*
- ID_MODEL_FROM_DATABASE=Caicos [Radeon HD 8350 OEM]
+ ID_MODEL_FROM_DATABASE=Park [Mobility Radeon HD 5430] (Caicos [Radeon HD 8350 OEM])
 
 pci:v00001002d000068E4*
  ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M]
 
 pci:v00001002d000068E4sv00001019sd00002386*
- ID_MODEL_FROM_DATABASE=Radeon HD 6350M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6350M)
 
 pci:v00001002d000068E4sv00001019sd00002387*
- ID_MODEL_FROM_DATABASE=Radeon HD 6350M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6350M)
 
 pci:v00001002d000068E4sv00001019sd0000238D*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv00001019sd0000238E*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv00001025sd00000382*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv00001025sd00000489*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv00001025sd0000048A*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv00001025sd0000048B*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv00001025sd0000048C*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv00001028sd000004C1*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv00001028sd000004CA*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv00001028sd000004CC*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv00001028sd000004CD*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv00001028sd000004D7*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv0000103Csd00001411*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv0000103Csd00001421*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv0000103Csd00001426*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv0000103Csd00001428*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv0000103Csd0000142A*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv0000103Csd0000142B*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv0000103Csd0000143A*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv0000103Csd0000143C*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv0000103Csd00001445*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv0000103Csd0000162C*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv0000103Csd0000162D*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv0000103Csd0000162E*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv0000103Csd0000162F*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv0000103Csd00001639*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv0000103Csd0000163A*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv0000103Csd0000163B*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv0000103Csd0000163C*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv0000103Csd0000163D*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv0000103Csd0000163E*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv0000103Csd0000163F*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv0000103Csd00001641*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv0000103Csd00001643*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv0000103Csd00003578*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv0000103Csd0000357A*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv0000103Csd00003673*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv0000103Csd00003675*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv00001043sd00001C92*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv00001043sd000084A1*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv00001043sd000084AD*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv0000104Dsd00009081*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv00001545sd00007350*
- ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 7350]
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Cedar [Radeon HD 7350])
 
 pci:v00001002d000068E4sv00001558sd00004510*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv00001558sd00005505*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv0000174Bsd00005450*
- ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5450]
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Cedar [Radeon HD 5450])
 
 pci:v00001002d000068E4sv000017AAsd000021DD*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv000017AAsd000021E9*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv000017AAsd00003971*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M)
 
 pci:v00001002d000068E4sv000017AAsd00003972*
- ID_MODEL_FROM_DATABASE=Radeon HD 7370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 7370M)
 
 pci:v00001002d000068E4sv000017AAsd0000397A*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M/7370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M/7370M)
 
 pci:v00001002d000068E4sv000017AAsd0000397B*
- ID_MODEL_FROM_DATABASE=Radeon HD 6370M/7370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 6370M/7370M)
 
 pci:v00001002d000068E4sv000017AAsd0000397F*
- ID_MODEL_FROM_DATABASE=Radeon HD 7370M
+ ID_MODEL_FROM_DATABASE=Robson CE [Radeon HD 6370M/7370M] (Radeon HD 7370M)
 
 pci:v00001002d000068E5*
  ID_MODEL_FROM_DATABASE=Robson LE [Radeon HD 6330M]
 
 pci:v00001002d000068E5sv00001179sd0000FD3C*
- ID_MODEL_FROM_DATABASE=Radeon HD 6330M
+ ID_MODEL_FROM_DATABASE=Robson LE [Radeon HD 6330M] (Radeon HD 6330M)
 
 pci:v00001002d000068E5sv00001179sd0000FD50*
- ID_MODEL_FROM_DATABASE=Radeon HD 6330M
+ ID_MODEL_FROM_DATABASE=Robson LE [Radeon HD 6330M] (Radeon HD 6330M)
 
 pci:v00001002d000068E5sv00001179sd0000FD52*
- ID_MODEL_FROM_DATABASE=Radeon HD 6330M
+ ID_MODEL_FROM_DATABASE=Robson LE [Radeon HD 6330M] (Radeon HD 6330M)
 
 pci:v00001002d000068E5sv00001179sd0000FD63*
- ID_MODEL_FROM_DATABASE=Radeon HD 6330M
+ ID_MODEL_FROM_DATABASE=Robson LE [Radeon HD 6330M] (Radeon HD 6330M)
 
 pci:v00001002d000068E5sv00001179sd0000FD65*
- ID_MODEL_FROM_DATABASE=Radeon HD 6330M
+ ID_MODEL_FROM_DATABASE=Robson LE [Radeon HD 6330M] (Radeon HD 6330M)
 
 pci:v00001002d000068E5sv00001179sd0000FD73*
- ID_MODEL_FROM_DATABASE=Radeon HD 6330M
+ ID_MODEL_FROM_DATABASE=Robson LE [Radeon HD 6330M] (Radeon HD 6330M)
 
 pci:v00001002d000068E5sv00001179sd0000FD75*
- ID_MODEL_FROM_DATABASE=Radeon HD 6330M
+ ID_MODEL_FROM_DATABASE=Robson LE [Radeon HD 6330M] (Radeon HD 6330M)
 
 pci:v00001002d000068E5sv00001179sd0000FDD0*
- ID_MODEL_FROM_DATABASE=Radeon HD 6330M
+ ID_MODEL_FROM_DATABASE=Robson LE [Radeon HD 6330M] (Radeon HD 6330M)
 
 pci:v00001002d000068E5sv00001179sd0000FDD2*
- ID_MODEL_FROM_DATABASE=Radeon HD 6330M
+ ID_MODEL_FROM_DATABASE=Robson LE [Radeon HD 6330M] (Radeon HD 6330M)
 
 pci:v00001002d000068E5sv00001179sd0000FDEA*
- ID_MODEL_FROM_DATABASE=Radeon HD 6330M
+ ID_MODEL_FROM_DATABASE=Robson LE [Radeon HD 6330M] (Radeon HD 6330M)
 
 pci:v00001002d000068E5sv00001179sd0000FDF8*
- ID_MODEL_FROM_DATABASE=Radeon HD 6330M
+ ID_MODEL_FROM_DATABASE=Robson LE [Radeon HD 6330M] (Radeon HD 6330M)
 
 pci:v00001002d000068E5sv0000148Csd00005450*
- ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5450]
+ ID_MODEL_FROM_DATABASE=Robson LE [Radeon HD 6330M] (Cedar [Radeon HD 5450])
 
 pci:v00001002d000068E5sv0000148Csd00006350*
- ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 6350]
+ ID_MODEL_FROM_DATABASE=Robson LE [Radeon HD 6330M] (Cedar [Radeon HD 6350])
 
 pci:v00001002d000068E5sv0000148Csd00007350*
- ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 7350]
+ ID_MODEL_FROM_DATABASE=Robson LE [Radeon HD 6330M] (Cedar [Radeon HD 7350])
 
 pci:v00001002d000068E5sv0000148Csd00008350*
- ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 8350]
+ ID_MODEL_FROM_DATABASE=Robson LE [Radeon HD 6330M] (Cedar [Radeon HD 8350])
 
 pci:v00001002d000068E5sv00001545sd00007350*
- ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 7350]
+ ID_MODEL_FROM_DATABASE=Robson LE [Radeon HD 6330M] (Cedar [Radeon HD 7350])
 
 pci:v00001002d000068E8*
  ID_MODEL_FROM_DATABASE=Cedar
@@ -7491,266 +7602,296 @@ pci:v00001002d000068F9*
  ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series]
 
 pci:v00001002d000068F9sv00001019sd00000001*
- ID_MODEL_FROM_DATABASE=Radeon HD 5450
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 5450)
 
 pci:v00001002d000068F9sv00001019sd00000002*
- ID_MODEL_FROM_DATABASE=Radeon HD 5450
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 5450)
 
 pci:v00001002d000068F9sv00001019sd00000019*
- ID_MODEL_FROM_DATABASE=Radeon HD 6350
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 6350)
 
 pci:v00001002d000068F9sv00001025sd00000518*
- ID_MODEL_FROM_DATABASE=Radeon HD 5450
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 5450)
 
 pci:v00001002d000068F9sv00001025sd00000519*
- ID_MODEL_FROM_DATABASE=Radeon HD 5450
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 5450)
 
 pci:v00001002d000068F9sv00001028sd0000010E*
- ID_MODEL_FROM_DATABASE=XPS 8300
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (XPS 8300)
 
 pci:v00001002d000068F9sv00001028sd00002126*
- ID_MODEL_FROM_DATABASE=Radeon HD 6350
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 6350)
 
 pci:v00001002d000068F9sv0000103Csd00002126*
- ID_MODEL_FROM_DATABASE=Radeon HD 6350
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 6350)
 
 pci:v00001002d000068F9sv0000103Csd00002AAC*
- ID_MODEL_FROM_DATABASE=Radeon HD 5450
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 5450)
 
 pci:v00001002d000068F9sv0000103Csd00002AAE*
- ID_MODEL_FROM_DATABASE=Radeon HD 5450
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 5450)
 
 pci:v00001002d000068F9sv0000103Csd00003580*
- ID_MODEL_FROM_DATABASE=Radeon HD 5450
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 5450)
 
 pci:v00001002d000068F9sv00001043sd00000386*
- ID_MODEL_FROM_DATABASE=Radeon HD 5450
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 5450)
 
 pci:v00001002d000068F9sv00001043sd000003C2*
- ID_MODEL_FROM_DATABASE=EAH5450 SILENT/DI/512MD2 (LP)
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (EAH5450 SILENT/DI/512MD2 (LP))
 
 pci:v00001002d000068F9sv00001462sd00002130*
- ID_MODEL_FROM_DATABASE=Radeon HD 5450
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 5450)
 
 pci:v00001002d000068F9sv00001462sd00002131*
- ID_MODEL_FROM_DATABASE=Radeon HD 5450
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 5450)
 
 pci:v00001002d000068F9sv00001462sd00002133*
- ID_MODEL_FROM_DATABASE=Radeon HD 6350
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 6350)
 
 pci:v00001002d000068F9sv00001462sd00002180*
- ID_MODEL_FROM_DATABASE=Radeon HD 5450
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 5450)
 
 pci:v00001002d000068F9sv00001462sd00002181*
- ID_MODEL_FROM_DATABASE=Radeon HD 5450
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 5450)
 
 pci:v00001002d000068F9sv00001462sd00002182*
- ID_MODEL_FROM_DATABASE=Radeon HD 6350
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 6350)
 
 pci:v00001002d000068F9sv00001462sd00002183*
- ID_MODEL_FROM_DATABASE=Radeon HD 6350
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 6350)
 
 pci:v00001002d000068F9sv00001462sd00002230*
- ID_MODEL_FROM_DATABASE=Radeon HD 5450
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 5450)
 
 pci:v00001002d000068F9sv00001462sd00002231*
- ID_MODEL_FROM_DATABASE=Radeon HD 5450
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 5450)
 
 pci:v00001002d000068F9sv00001462sd00002495*
- ID_MODEL_FROM_DATABASE=Radeon HD 6350
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 6350)
 
 pci:v00001002d000068F9sv0000148Csd00003001*
- ID_MODEL_FROM_DATABASE=Radeon HD 5530/6250
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 5530/6250)
 
 pci:v00001002d000068F9sv0000148Csd00003002*
- ID_MODEL_FROM_DATABASE=Radeon HD 6290
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 6290)
 
 pci:v00001002d000068F9sv0000148Csd00003003*
- ID_MODEL_FROM_DATABASE=Radeon HD 6230
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 6230)
 
 pci:v00001002d000068F9sv0000148Csd00003004*
- ID_MODEL_FROM_DATABASE=Radeon HD 6350
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 6350)
 
 pci:v00001002d000068F9sv0000148Csd00007350*
- ID_MODEL_FROM_DATABASE=Radeon HD 7350
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 7350)
 
 pci:v00001002d000068F9sv0000148Csd00008350*
- ID_MODEL_FROM_DATABASE=Radeon HD 8350
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 8350)
 
 pci:v00001002d000068F9sv00001545sd00007350*
- ID_MODEL_FROM_DATABASE=Radeon HD 7350
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 7350)
 
 pci:v00001002d000068F9sv00001642sd00003983*
- ID_MODEL_FROM_DATABASE=Radeon HD 5450
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 5450)
 
 pci:v00001002d000068F9sv00001642sd00003984*
- ID_MODEL_FROM_DATABASE=Radeon HD 6350
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 6350)
 
 pci:v00001002d000068F9sv00001642sd00003987*
- ID_MODEL_FROM_DATABASE=Radeon HD 6350
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 6350)
 
 pci:v00001002d000068F9sv00001642sd00003997*
- ID_MODEL_FROM_DATABASE=Radeon HD 5450
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 5450)
 
 pci:v00001002d000068F9sv00001642sd00003A05*
- ID_MODEL_FROM_DATABASE=Radeon HD 5450
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 5450)
 
 pci:v00001002d000068F9sv00001642sd00003B31*
- ID_MODEL_FROM_DATABASE=Radeon HD 6350A
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 6350A)
 
 pci:v00001002d000068F9sv00001682sd00003270*
- ID_MODEL_FROM_DATABASE=Radeon HD 7350
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 7350)
 
 pci:v00001002d000068F9sv0000174Bsd00003000*
- ID_MODEL_FROM_DATABASE=Radeon HD 6230
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 6230)
 
 pci:v00001002d000068F9sv0000174Bsd00003987*
- ID_MODEL_FROM_DATABASE=Radeon HD 6350
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 6350)
 
 pci:v00001002d000068F9sv0000174Bsd00005470*
- ID_MODEL_FROM_DATABASE=Radeon HD 5470
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 5470)
 
 pci:v00001002d000068F9sv0000174Bsd00005490*
- ID_MODEL_FROM_DATABASE=Radeon HD 5490
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 5490)
 
 pci:v00001002d000068F9sv0000174Bsd00005530*
- ID_MODEL_FROM_DATABASE=Radeon HD 5530
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 5530)
 
 pci:v00001002d000068F9sv0000174Bsd00006230*
- ID_MODEL_FROM_DATABASE=Radeon HD 6230
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 6230)
 
 pci:v00001002d000068F9sv0000174Bsd00006250*
- ID_MODEL_FROM_DATABASE=Radeon HD 6250
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 6250)
 
 pci:v00001002d000068F9sv0000174Bsd00006290*
- ID_MODEL_FROM_DATABASE=Radeon HD 6290
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 6290)
 
 pci:v00001002d000068F9sv0000174Bsd00006350*
- ID_MODEL_FROM_DATABASE=Radeon HD 6350
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 6350)
 
 pci:v00001002d000068F9sv0000174Bsd00007350*
- ID_MODEL_FROM_DATABASE=Radeon HD 7350
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 7350)
 
 pci:v00001002d000068F9sv0000174Bsd00008350*
- ID_MODEL_FROM_DATABASE=Radeon HD 8350
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 8350)
 
 pci:v00001002d000068F9sv0000174Bsd0000E127*
- ID_MODEL_FROM_DATABASE=Radeon HD 5450
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 5450)
 
 pci:v00001002d000068F9sv0000174Bsd0000E145*
- ID_MODEL_FROM_DATABASE=Radeon HD 5450
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 5450)
 
 pci:v00001002d000068F9sv0000174Bsd0000E153*
- ID_MODEL_FROM_DATABASE=Radeon HD 5450
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 5450)
 
 pci:v00001002d000068F9sv00001787sd00003000*
- ID_MODEL_FROM_DATABASE=Radeon HD 5470
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 5470)
 
 pci:v00001002d000068F9sv00001787sd00003001*
- ID_MODEL_FROM_DATABASE=Radeon HD 5530
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 5530)
 
 pci:v00001002d000068F9sv00001787sd00003002*
- ID_MODEL_FROM_DATABASE=Radeon HD 5490
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 5490)
 
 pci:v00001002d000068F9sv000017AAsd00003602*
- ID_MODEL_FROM_DATABASE=Radeon HD 5450
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 5450)
 
 pci:v00001002d000068F9sv000017AAsd00003603*
- ID_MODEL_FROM_DATABASE=Radeon HD 5450
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 5450)
 
 pci:v00001002d000068F9sv000017AAsd0000360F*
- ID_MODEL_FROM_DATABASE=Radeon HD 5450
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 5450)
 
 pci:v00001002d000068F9sv000017AAsd00003619*
- ID_MODEL_FROM_DATABASE=Radeon HD 5450
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 5450)
 
 pci:v00001002d000068F9sv000017AFsd00003000*
- ID_MODEL_FROM_DATABASE=Radeon HD 6250
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 6250)
 
 pci:v00001002d000068F9sv000017AFsd00003001*
- ID_MODEL_FROM_DATABASE=Radeon HD 6230
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 6230)
 
 pci:v00001002d000068F9sv000017AFsd00003002*
- ID_MODEL_FROM_DATABASE=Radeon HD 6290
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 6290)
 
 pci:v00001002d000068F9sv000017AFsd00003011*
- ID_MODEL_FROM_DATABASE=Radeon HD 5470
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 5470)
 
 pci:v00001002d000068F9sv000017AFsd00003012*
- ID_MODEL_FROM_DATABASE=Radeon HD 5490
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 5490)
 
 pci:v00001002d000068F9sv000017AFsd00003013*
- ID_MODEL_FROM_DATABASE=Radeon HD 5470
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 5470)
 
 pci:v00001002d000068F9sv000017AFsd00003014*
- ID_MODEL_FROM_DATABASE=Radeon HD 6350
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 5000/6000/7350/8350 Series] (Radeon HD 6350)
 
 pci:v00001002d000068FA*
- ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 7350/8350]
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 7350/8350 / R5 220]
 
 pci:v00001002d000068FAsv00001019sd00000019*
- ID_MODEL_FROM_DATABASE=Radeon HD 7350
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 7350/8350 / R5 220] (Radeon HD 7350)
 
 pci:v00001002d000068FAsv00001019sd00000021*
- ID_MODEL_FROM_DATABASE=Radeon HD 7350
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 7350/8350 / R5 220] (Radeon HD 7350)
 
 pci:v00001002d000068FAsv00001019sd00000022*
- ID_MODEL_FROM_DATABASE=Radeon HD 7350
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 7350/8350 / R5 220] (Radeon HD 7350)
 
 pci:v00001002d000068FAsv00001019sd00000026*
- ID_MODEL_FROM_DATABASE=Radeon HD 8350
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 7350/8350 / R5 220] (Radeon HD 8350)
 
 pci:v00001002d000068FAsv0000103Csd00002ADF*
- ID_MODEL_FROM_DATABASE=Radeon HD 7350A
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 7350/8350 / R5 220] (Radeon HD 7350A)
 
 pci:v00001002d000068FAsv0000103Csd00002AE8*
- ID_MODEL_FROM_DATABASE=Radeon HD 7350A
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 7350/8350 / R5 220] (Radeon HD 7350A)
 
 pci:v00001002d000068FAsv00001043sd00008350*
- ID_MODEL_FROM_DATABASE=Radeon HD 8350
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 7350/8350 / R5 220] (Radeon HD 8350)
 
 pci:v00001002d000068FAsv00001462sd00002128*
- ID_MODEL_FROM_DATABASE=Radeon HD 7350
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 7350/8350 / R5 220] (Radeon HD 7350)
 
 pci:v00001002d000068FAsv00001462sd00002184*
- ID_MODEL_FROM_DATABASE=Radeon HD 7350
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 7350/8350 / R5 220] (Radeon HD 7350)
 
 pci:v00001002d000068FAsv00001462sd00002186*
- ID_MODEL_FROM_DATABASE=Radeon HD 7350
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 7350/8350 / R5 220] (Radeon HD 7350)
 
 pci:v00001002d000068FAsv00001462sd00002495*
- ID_MODEL_FROM_DATABASE=Radeon HD 7350
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 7350/8350 / R5 220] (Radeon HD 7350)
 
 pci:v00001002d000068FAsv00001462sd0000B490*
- ID_MODEL_FROM_DATABASE=Radeon HD 7350
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 7350/8350 / R5 220] (Radeon HD 7350)
 
 pci:v00001002d000068FAsv00001642sd00003985*
- ID_MODEL_FROM_DATABASE=Radeon HD 7350
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 7350/8350 / R5 220] (Radeon HD 7350)
+
+pci:v00001002d000068FAsv0000174Bsd00003510*
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 7350/8350 / R5 220] (Radeon HD 8350)
+
+pci:v00001002d000068FAsv0000174Bsd00003521*
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 7350/8350 / R5 220] (Radeon R5 220)
+
+pci:v00001002d000068FAsv0000174Bsd00003522*
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 7350/8350 / R5 220] (Radeon R5 220)
 
 pci:v00001002d000068FAsv0000174Bsd00007350*
- ID_MODEL_FROM_DATABASE=Radeon HD 7350
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 7350/8350 / R5 220] (Radeon HD 7350)
 
 pci:v00001002d000068FAsv0000174Bsd00008153*
- ID_MODEL_FROM_DATABASE=Radeon HD 8350
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 7350/8350 / R5 220] (Radeon HD 8350)
 
 pci:v00001002d000068FAsv0000174Bsd0000E127*
- ID_MODEL_FROM_DATABASE=Radeon HD 7350
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 7350/8350 / R5 220] (Radeon HD 7350)
 
 pci:v00001002d000068FAsv0000174Bsd0000E153*
- ID_MODEL_FROM_DATABASE=Radeon HD 7350
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 7350/8350 / R5 220] (Radeon HD 7350)
 
 pci:v00001002d000068FAsv0000174Bsd0000E180*
- ID_MODEL_FROM_DATABASE=Radeon HD 7350
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 7350/8350 / R5 220] (Radeon HD 7350)
 
 pci:v00001002d000068FAsv000017AFsd00003015*
- ID_MODEL_FROM_DATABASE=Radeon HD 7350
+ ID_MODEL_FROM_DATABASE=Cedar [Radeon HD 7350/8350 / R5 220] (Radeon HD 7350)
 
 pci:v00001002d000068FE*
  ID_MODEL_FROM_DATABASE=Cedar LE
 
+pci:v00001002d00006900*
+ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265]
+
+pci:v00001002d00006900sv00001028sd00000640*
+ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265] (Radeon R7 M265)
+
+pci:v00001002d00006900sv00001179sd0000F934*
+ ID_MODEL_FROM_DATABASE=Topaz XT [Radeon R7 M260/M265] (Radeon R7 M260)
+
+pci:v00001002d00006901*
+ ID_MODEL_FROM_DATABASE=Topaz PRO [Radeon R5 M255]
+
 pci:v00001002d00006920*
  ID_MODEL_FROM_DATABASE=Tonga
 
+pci:v00001002d00006921*
+ ID_MODEL_FROM_DATABASE=Amethyst XT [Radeon R9 M295X]
+
+pci:v00001002d0000692B*
+ ID_MODEL_FROM_DATABASE=Tonga XT GL [FirePro W8100]
+
+pci:v00001002d0000692F*
+ ID_MODEL_FROM_DATABASE=Tonga XT GL [FirePro W8100]
+
 pci:v00001002d0000700F*
  ID_MODEL_FROM_DATABASE=RS100 AGP Bridge
 
@@ -7773,16 +7914,16 @@ pci:v00001002d00007109*
  ID_MODEL_FROM_DATABASE=R520 [Radeon X1800 XL]
 
 pci:v00001002d00007109sv00001002sd00000322*
- ID_MODEL_FROM_DATABASE=All-in-Wonder X1800XL
+ ID_MODEL_FROM_DATABASE=R520 [Radeon X1800 XL] (All-in-Wonder X1800XL)
 
 pci:v00001002d00007109sv00001002sd00000D02*
- ID_MODEL_FROM_DATABASE=Radeon X1800 CrossFire Edition
+ ID_MODEL_FROM_DATABASE=R520 [Radeon X1800 XL] (Radeon X1800 CrossFire Edition)
 
 pci:v00001002d0000710A*
  ID_MODEL_FROM_DATABASE=R520 [Radeon X1800 GTO]
 
 pci:v00001002d0000710Asv00001002sd00000B12*
- ID_MODEL_FROM_DATABASE=Radeon X1800 GTO²
+ ID_MODEL_FROM_DATABASE=R520 [Radeon X1800 GTO] (Radeon X1800 GTO²)
 
 pci:v00001002d0000710B*
  ID_MODEL_FROM_DATABASE=R520 [Radeon X1800 GTO]
@@ -7797,10 +7938,10 @@ pci:v00001002d00007129*
  ID_MODEL_FROM_DATABASE=R520 [Radeon X1800] (Secondary)
 
 pci:v00001002d00007129sv00001002sd00000323*
- ID_MODEL_FROM_DATABASE=All-In-Wonder X1800 XL (Secondary)
+ ID_MODEL_FROM_DATABASE=R520 [Radeon X1800] (Secondary) (All-In-Wonder X1800 XL (Secondary))
 
 pci:v00001002d00007129sv00001002sd00000D03*
- ID_MODEL_FROM_DATABASE=Radeon X1800 CrossFire Edition (Secondary)
+ ID_MODEL_FROM_DATABASE=R520 [Radeon X1800] (Secondary) (Radeon X1800 CrossFire Edition (Secondary))
 
 pci:v00001002d00007140*
  ID_MODEL_FROM_DATABASE=RV515 [Radeon X1300/X1550/X1600 Series]
@@ -7809,10 +7950,10 @@ pci:v00001002d00007142*
  ID_MODEL_FROM_DATABASE=RV515 PRO [Radeon X1300/X1550 Series]
 
 pci:v00001002d00007142sv00001002sd00000322*
- ID_MODEL_FROM_DATABASE=All-in-Wonder 2006 PCI-E Edition
+ ID_MODEL_FROM_DATABASE=RV515 PRO [Radeon X1300/X1550 Series] (All-in-Wonder 2006 PCI-E Edition)
 
 pci:v00001002d00007142sv00001043sd00000142*
- ID_MODEL_FROM_DATABASE=EAX1300PRO/TD/256M
+ ID_MODEL_FROM_DATABASE=RV515 PRO [Radeon X1300/X1550 Series] (EAX1300PRO/TD/256M)
 
 pci:v00001002d00007143*
  ID_MODEL_FROM_DATABASE=RV505 [Radeon X1300/X1550 Series]
@@ -7821,16 +7962,16 @@ pci:v00001002d00007145*
  ID_MODEL_FROM_DATABASE=RV515/M54 [Mobility Radeon X1400]
 
 pci:v00001002d00007145sv000017AAsd00002006*
- ID_MODEL_FROM_DATABASE=Thinkpad T60 model 2007
+ ID_MODEL_FROM_DATABASE=RV515/M54 [Mobility Radeon X1400] (Thinkpad T60 model 2007)
 
 pci:v00001002d00007146*
  ID_MODEL_FROM_DATABASE=RV515 [Radeon X1300/X1550]
 
 pci:v00001002d00007146sv00001002sd00000322*
- ID_MODEL_FROM_DATABASE=All-in-Wonder 2006 PCI-E Edition
+ ID_MODEL_FROM_DATABASE=RV515 [Radeon X1300/X1550] (All-in-Wonder 2006 PCI-E Edition)
 
 pci:v00001002d00007146sv00001545sd00001996*
- ID_MODEL_FROM_DATABASE=Radeon X1300 512MB PCI-e
+ ID_MODEL_FROM_DATABASE=RV515 [Radeon X1300/X1550] (Radeon X1300 512MB PCI-e)
 
 pci:v00001002d00007147*
  ID_MODEL_FROM_DATABASE=RV505 [Radeon X1550 64-bit]
@@ -7854,7 +7995,7 @@ pci:v00001002d00007162*
  ID_MODEL_FROM_DATABASE=RV515 PRO [Radeon X1300/X1550 Series] (Secondary)
 
 pci:v00001002d00007162sv00001002sd00000323*
- ID_MODEL_FROM_DATABASE=All-in-Wonder 2006 PCI-E Edition (Secondary)
+ ID_MODEL_FROM_DATABASE=RV515 PRO [Radeon X1300/X1550 Series] (Secondary) (All-in-Wonder 2006 PCI-E Edition (Secondary))
 
 pci:v00001002d00007163*
  ID_MODEL_FROM_DATABASE=RV505 [Radeon X1550 Series] (Secondary)
@@ -7863,10 +8004,10 @@ pci:v00001002d00007166*
  ID_MODEL_FROM_DATABASE=RV515 [Radeon X1300/X1550 Series] (Secondary)
 
 pci:v00001002d00007166sv00001002sd00000323*
- ID_MODEL_FROM_DATABASE=All-in-Wonder 2006 PCI-E Edition (Secondary)
+ ID_MODEL_FROM_DATABASE=RV515 [Radeon X1300/X1550 Series] (Secondary) (All-in-Wonder 2006 PCI-E Edition (Secondary))
 
 pci:v00001002d00007166sv00001545sd00001997*
- ID_MODEL_FROM_DATABASE=Radeon X1300 512MB PCI-e (Secondary)
+ ID_MODEL_FROM_DATABASE=RV515 [Radeon X1300/X1550 Series] (Secondary) (Radeon X1300 512MB PCI-e (Secondary))
 
 pci:v00001002d00007167*
  ID_MODEL_FROM_DATABASE=RV515 [Radeon X1550 64-bit] (Secondary)
@@ -7893,7 +8034,7 @@ pci:v00001002d00007188*
  ID_MODEL_FROM_DATABASE=RV516/M64-S [Mobility Radeon X2300]
 
 pci:v00001002d00007188sv0000103Csd000030C1*
- ID_MODEL_FROM_DATABASE=6910p
+ ID_MODEL_FROM_DATABASE=RV516/M64-S [Mobility Radeon X2300] (6910p)
 
 pci:v00001002d0000718A*
  ID_MODEL_FROM_DATABASE=RV516/M64 [Mobility Radeon X2300]
@@ -7901,6 +8042,9 @@ pci:v00001002d0000718A*
 pci:v00001002d0000718B*
  ID_MODEL_FROM_DATABASE=RV516/M62 [Mobility Radeon X1350]
 
+pci:v00001002d0000718Bsv00001071sd00008209*
+ ID_MODEL_FROM_DATABASE=RV516/M62 [Mobility Radeon X1350] (Medion MIM 2240 Notebook PC [MD98100])
+
 pci:v00001002d0000718C*
  ID_MODEL_FROM_DATABASE=RV516/M62-CSP64 [Mobility Radeon X1350]
 
@@ -7938,16 +8082,16 @@ pci:v00001002d000071C0*
  ID_MODEL_FROM_DATABASE=RV530 [Radeon X1600 XT/X1650 GTO]
 
 pci:v00001002d000071C0sv00001002sd0000E160*
- ID_MODEL_FROM_DATABASE=Radeon X1650 GTO
+ ID_MODEL_FROM_DATABASE=RV530 [Radeon X1600 XT/X1650 GTO] (Radeon X1650 GTO)
 
 pci:v00001002d000071C0sv0000174Bsd0000E160*
- ID_MODEL_FROM_DATABASE=Radeon X1650 GTO
+ ID_MODEL_FROM_DATABASE=RV530 [Radeon X1600 XT/X1650 GTO] (Radeon X1650 GTO)
 
 pci:v00001002d000071C1*
  ID_MODEL_FROM_DATABASE=RV535 [Radeon X1650 PRO]
 
 pci:v00001002d000071C1sv0000174Bsd00000880*
- ID_MODEL_FROM_DATABASE=Radeon X1700 FSC
+ ID_MODEL_FROM_DATABASE=RV535 [Radeon X1650 PRO] (Radeon X1700 FSC)
 
 pci:v00001002d000071C2*
  ID_MODEL_FROM_DATABASE=RV530 [Radeon X1600 PRO]
@@ -7956,22 +8100,22 @@ pci:v00001002d000071C4*
  ID_MODEL_FROM_DATABASE=RV530/M56 GL [Mobility FireGL V5200]
 
 pci:v00001002d000071C4sv000017AAsd00002007*
- ID_MODEL_FROM_DATABASE=ThinkPad T60p
+ ID_MODEL_FROM_DATABASE=RV530/M56 GL [Mobility FireGL V5200] (ThinkPad T60p)
 
 pci:v00001002d000071C5*
  ID_MODEL_FROM_DATABASE=RV530/M56-P [Mobility Radeon X1600]
 
 pci:v00001002d000071C5sv0000103Csd0000309F*
- ID_MODEL_FROM_DATABASE=Compaq nx9420 Notebook
+ ID_MODEL_FROM_DATABASE=RV530/M56-P [Mobility Radeon X1600] (Compaq nx9420 Notebook)
 
 pci:v00001002d000071C5sv0000103Csd000030A3*
- ID_MODEL_FROM_DATABASE=Compaq NW8440
+ ID_MODEL_FROM_DATABASE=RV530/M56-P [Mobility Radeon X1600] (Compaq NW8440)
 
 pci:v00001002d000071C5sv00001043sd000010B2*
- ID_MODEL_FROM_DATABASE=A6J-Q008
+ ID_MODEL_FROM_DATABASE=RV530/M56-P [Mobility Radeon X1600] (A6J-Q008)
 
 pci:v00001002d000071C5sv0000106Bsd00000080*
- ID_MODEL_FROM_DATABASE=MacBook Pro
+ ID_MODEL_FROM_DATABASE=RV530/M56-P [Mobility Radeon X1600] (MacBook Pro)
 
 pci:v00001002d000071C6*
  ID_MODEL_FROM_DATABASE=RV530LE [Radeon X1600/X1650 PRO]
@@ -7980,7 +8124,7 @@ pci:v00001002d000071C7*
  ID_MODEL_FROM_DATABASE=RV535 [Radeon X1650 PRO]
 
 pci:v00001002d000071C7sv00001787sd00003000*
- ID_MODEL_FROM_DATABASE=PowerColor X1650 PRO AGP
+ ID_MODEL_FROM_DATABASE=RV535 [Radeon X1650 PRO] (PowerColor X1650 PRO AGP)
 
 pci:v00001002d000071CE*
  ID_MODEL_FROM_DATABASE=RV530 [Radeon X1300 XT/X1600 PRO]
@@ -8004,13 +8148,13 @@ pci:v00001002d000071E0*
  ID_MODEL_FROM_DATABASE=RV530 [Radeon X1600] (Secondary)
 
 pci:v00001002d000071E0sv0000174Bsd0000E161*
- ID_MODEL_FROM_DATABASE=Radeon X1600 GTO (Secondary)
+ ID_MODEL_FROM_DATABASE=RV530 [Radeon X1600] (Secondary) (Radeon X1600 GTO (Secondary))
 
 pci:v00001002d000071E1*
  ID_MODEL_FROM_DATABASE=RV535 [Radeon X1650 PRO] (Secondary)
 
 pci:v00001002d000071E1sv0000174Bsd00000881*
- ID_MODEL_FROM_DATABASE=Radeon X1700 FSC (Secondary)
+ ID_MODEL_FROM_DATABASE=RV535 [Radeon X1650 PRO] (Secondary) (Radeon X1700 FSC (Secondary))
 
 pci:v00001002d000071E2*
  ID_MODEL_FROM_DATABASE=RV530 [Radeon X1600] (Secondary)
@@ -8022,7 +8166,7 @@ pci:v00001002d000071E7*
  ID_MODEL_FROM_DATABASE=RV535 [Radeon X1650 PRO] (Secondary)
 
 pci:v00001002d000071E7sv00001787sd00003001*
- ID_MODEL_FROM_DATABASE=Radeon X1650 PRO AGP
+ ID_MODEL_FROM_DATABASE=RV535 [Radeon X1650 PRO] (Secondary) (Radeon X1650 PRO AGP)
 
 pci:v00001002d000071F2*
  ID_MODEL_FROM_DATABASE=RV530 GL [FireGL V3400] (Secondary)
@@ -8037,7 +8181,7 @@ pci:v00001002d00007240*
  ID_MODEL_FROM_DATABASE=R580+ [Radeon X1950 XTX]
 
 pci:v00001002d00007240sv00001002sd00000D02*
- ID_MODEL_FROM_DATABASE=Radeon X1950 CrossFire Edition
+ ID_MODEL_FROM_DATABASE=R580+ [Radeon X1950 XTX] (Radeon X1950 CrossFire Edition)
 
 pci:v00001002d00007244*
  ID_MODEL_FROM_DATABASE=R580+ [Radeon X1950 XT]
@@ -8049,25 +8193,25 @@ pci:v00001002d00007249*
  ID_MODEL_FROM_DATABASE=R580 [Radeon X1900 XT]
 
 pci:v00001002d00007249sv00001002sd00000412*
- ID_MODEL_FROM_DATABASE=All-In-Wonder X1900
+ ID_MODEL_FROM_DATABASE=R580 [Radeon X1900 XT] (All-In-Wonder X1900)
 
 pci:v00001002d00007249sv00001002sd00000B12*
- ID_MODEL_FROM_DATABASE=Radeon X1900 XT/XTX
+ ID_MODEL_FROM_DATABASE=R580 [Radeon X1900 XT] (Radeon X1900 XT/XTX)
 
 pci:v00001002d00007249sv00001002sd00000D02*
- ID_MODEL_FROM_DATABASE=Radeon X1900 CrossFire Edition
+ ID_MODEL_FROM_DATABASE=R580 [Radeon X1900 XT] (Radeon X1900 CrossFire Edition)
 
 pci:v00001002d00007249sv00001043sd00000160*
- ID_MODEL_FROM_DATABASE=Radeon X1900 XTX 512 MB GDDR3
+ ID_MODEL_FROM_DATABASE=R580 [Radeon X1900 XT] (Radeon X1900 XTX 512 MB GDDR3)
 
 pci:v00001002d0000724B*
  ID_MODEL_FROM_DATABASE=R580 [Radeon X1900 GT]
 
 pci:v00001002d0000724Bsv00001002sd00000B12*
- ID_MODEL_FROM_DATABASE=Radeon X1900 (Primary)
+ ID_MODEL_FROM_DATABASE=R580 [Radeon X1900 GT] (Radeon X1900 (Primary))
 
 pci:v00001002d0000724Bsv00001002sd00000B13*
- ID_MODEL_FROM_DATABASE=Radeon X1900 (Secondary)
+ ID_MODEL_FROM_DATABASE=R580 [Radeon X1900 GT] (Radeon X1900 (Secondary))
 
 pci:v00001002d0000724E*
  ID_MODEL_FROM_DATABASE=R580 GL [FireGL V7350]
@@ -8091,7 +8235,7 @@ pci:v00001002d00007291*
  ID_MODEL_FROM_DATABASE=RV560 [Radeon X1650 XT]
 
 pci:v00001002d00007291sv00001462sd00000810*
- ID_MODEL_FROM_DATABASE=Radeon X1700 SE
+ ID_MODEL_FROM_DATABASE=RV560 [Radeon X1650 XT] (Radeon X1700 SE)
 
 pci:v00001002d00007293*
  ID_MODEL_FROM_DATABASE=RV560 [Radeon X1650 GT]
@@ -8124,10 +8268,10 @@ pci:v00001002d00007910*
  ID_MODEL_FROM_DATABASE=RS690 Host Bridge
 
 pci:v00001002d00007910sv00001179sd0000FF50*
- ID_MODEL_FROM_DATABASE=Satellite P305D-S8995E
+ ID_MODEL_FROM_DATABASE=RS690 Host Bridge (Satellite P305D-S8995E)
 
 pci:v00001002d00007910sv000017F2sd00005000*
- ID_MODEL_FROM_DATABASE=KI690-AM2 Motherboard
+ ID_MODEL_FROM_DATABASE=RS690 Host Bridge (KI690-AM2 Motherboard)
 
 pci:v00001002d00007911*
  ID_MODEL_FROM_DATABASE=RS690 Host Bridge
@@ -8148,31 +8292,31 @@ pci:v00001002d00007917*
  ID_MODEL_FROM_DATABASE=RS690 PCI to PCI Bridge (PCI Express Port 3)
 
 pci:v00001002d00007917sv00001002sd00007910*
- ID_MODEL_FROM_DATABASE=RS690 PCI to PCI Bridge
+ ID_MODEL_FROM_DATABASE=RS690 PCI to PCI Bridge (PCI Express Port 3) (RS690 PCI to PCI Bridge)
 
 pci:v00001002d00007919*
  ID_MODEL_FROM_DATABASE=RS690 HDMI Audio [Radeon Xpress 1200 Series]
 
 pci:v00001002d00007919sv00001179sd00007919*
- ID_MODEL_FROM_DATABASE=Satellite P305D-S8995E
+ ID_MODEL_FROM_DATABASE=RS690 HDMI Audio [Radeon Xpress 1200 Series] (Satellite P305D-S8995E)
 
 pci:v00001002d00007919sv000017F2sd00005000*
- ID_MODEL_FROM_DATABASE=KI690-AM2 Motherboard
+ ID_MODEL_FROM_DATABASE=RS690 HDMI Audio [Radeon Xpress 1200 Series] (KI690-AM2 Motherboard)
 
 pci:v00001002d0000791E*
  ID_MODEL_FROM_DATABASE=RS690 [Radeon X1200]
 
 pci:v00001002d0000791Esv00001462sd00007327*
- ID_MODEL_FROM_DATABASE=K9AG Neo2
+ ID_MODEL_FROM_DATABASE=RS690 [Radeon X1200] (K9AG Neo2)
 
 pci:v00001002d0000791Esv000017F2sd00005000*
- ID_MODEL_FROM_DATABASE=KI690-AM2 Motherboard
+ ID_MODEL_FROM_DATABASE=RS690 [Radeon X1200] (KI690-AM2 Motherboard)
 
 pci:v00001002d0000791F*
  ID_MODEL_FROM_DATABASE=RS690M [Radeon Xpress 1200/1250/1270]
 
 pci:v00001002d0000791Fsv00001179sd0000FF50*
- ID_MODEL_FROM_DATABASE=Satellite P305D-S8995E
+ ID_MODEL_FROM_DATABASE=RS690M [Radeon Xpress 1200/1250/1270] (Satellite P305D-S8995E)
 
 pci:v00001002d00007930*
  ID_MODEL_FROM_DATABASE=RS600 Host Bridge
@@ -8211,13 +8355,13 @@ pci:v00001002d00009400*
  ID_MODEL_FROM_DATABASE=R600 [Radeon HD 2900 PRO/XT]
 
 pci:v00001002d00009400sv00001002sd00002552*
- ID_MODEL_FROM_DATABASE=Radeon HD 2900 XT
+ ID_MODEL_FROM_DATABASE=R600 [Radeon HD 2900 PRO/XT] (Radeon HD 2900 XT)
 
 pci:v00001002d00009400sv00001002sd00003000*
- ID_MODEL_FROM_DATABASE=Radeon HD 2900 PRO
+ ID_MODEL_FROM_DATABASE=R600 [Radeon HD 2900 PRO/XT] (Radeon HD 2900 PRO)
 
 pci:v00001002d00009400sv00001002sd00003142*
- ID_MODEL_FROM_DATABASE=HIS Radeon HD 2900XT 512MB GDDR3 VIVO PCIe
+ ID_MODEL_FROM_DATABASE=R600 [Radeon HD 2900 PRO/XT] (HIS Radeon HD 2900XT 512MB GDDR3 VIVO PCIe)
 
 pci:v00001002d00009401*
  ID_MODEL_FROM_DATABASE=R600 [Radeon HD 2900 XT]
@@ -8247,10 +8391,10 @@ pci:v00001002d00009442*
  ID_MODEL_FROM_DATABASE=RV770 [Radeon HD 4850]
 
 pci:v00001002d00009442sv00001002sd00000502*
- ID_MODEL_FROM_DATABASE=MSI Radeon HD 4850 512MB GDDR3
+ ID_MODEL_FROM_DATABASE=RV770 [Radeon HD 4850] (MSI Radeon HD 4850 512MB GDDR3)
 
 pci:v00001002d00009442sv0000174Bsd0000E810*
- ID_MODEL_FROM_DATABASE=Radeon HD 4850 512MB GDDR3
+ ID_MODEL_FROM_DATABASE=RV770 [Radeon HD 4850] (Radeon HD 4850 512MB GDDR3)
 
 pci:v00001002d00009443*
  ID_MODEL_FROM_DATABASE=R700 [Radeon HD 4850 X2]
@@ -8274,7 +8418,7 @@ pci:v00001002d0000944E*
  ID_MODEL_FROM_DATABASE=RV770 CE [Radeon HD 4710]
 
 pci:v00001002d0000944Esv0000174Bsd00003261*
- ID_MODEL_FROM_DATABASE=Radeon HD 4810
+ ID_MODEL_FROM_DATABASE=RV770 CE [Radeon HD 4710] (Radeon HD 4810)
 
 pci:v00001002d00009450*
  ID_MODEL_FROM_DATABASE=RV770 GL [FireStream 9270]
@@ -8301,7 +8445,7 @@ pci:v00001002d00009480*
  ID_MODEL_FROM_DATABASE=RV730/M96 [Mobility Radeon HD 4650/5165]
 
 pci:v00001002d00009480sv0000103Csd00003628*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 4650 [dv6-1190en]
+ ID_MODEL_FROM_DATABASE=RV730/M96 [Mobility Radeon HD 4650/5165] (Mobility Radeon HD 4650 [dv6-1190en])
 
 pci:v00001002d00009488*
  ID_MODEL_FROM_DATABASE=RV730/M96-XT [Mobility Radeon HD 4670]
@@ -8313,7 +8457,7 @@ pci:v00001002d00009490*
  ID_MODEL_FROM_DATABASE=RV730 XT [Radeon HD 4670]
 
 pci:v00001002d00009490sv0000174Bsd0000E880*
- ID_MODEL_FROM_DATABASE=Radeon HD 4670 512MB GDDR3 Dual DVI-I/TVO
+ ID_MODEL_FROM_DATABASE=RV730 XT [Radeon HD 4670] (Radeon HD 4670 512MB GDDR3 Dual DVI-I/TVO)
 
 pci:v00001002d00009491*
  ID_MODEL_FROM_DATABASE=RV730/M96-CSP [Radeon E4690]
@@ -8322,19 +8466,19 @@ pci:v00001002d00009495*
  ID_MODEL_FROM_DATABASE=RV730 [Radeon HD 4600 AGP Series]
 
 pci:v00001002d00009495sv00001002sd00000028*
- ID_MODEL_FROM_DATABASE=Radeon HD 4650/4670 AGP
+ ID_MODEL_FROM_DATABASE=RV730 [Radeon HD 4600 AGP Series] (Radeon HD 4650/4670 AGP)
 
 pci:v00001002d00009495sv00001092sd00000028*
- ID_MODEL_FROM_DATABASE=Radeon HD 4670 AGP 512MB DDR2
+ ID_MODEL_FROM_DATABASE=RV730 [Radeon HD 4600 AGP Series] (Radeon HD 4670 AGP 512MB DDR2)
 
 pci:v00001002d00009495sv00001458sd00000028*
- ID_MODEL_FROM_DATABASE=Radeon HD 4650 AGP
+ ID_MODEL_FROM_DATABASE=RV730 [Radeon HD 4600 AGP Series] (Radeon HD 4650 AGP)
 
 pci:v00001002d00009495sv00001682sd00000028*
- ID_MODEL_FROM_DATABASE=Radeon HD 4650 AGP
+ ID_MODEL_FROM_DATABASE=RV730 [Radeon HD 4600 AGP Series] (Radeon HD 4650 AGP)
 
 pci:v00001002d00009495sv0000174Bsd00000028*
- ID_MODEL_FROM_DATABASE=Radeon HD 4650 AGP DDR2
+ ID_MODEL_FROM_DATABASE=RV730 [Radeon HD 4600 AGP Series] (Radeon HD 4650 AGP DDR2)
 
 pci:v00001002d00009498*
  ID_MODEL_FROM_DATABASE=RV730 PRO [Radeon HD 4650]
@@ -8367,22 +8511,22 @@ pci:v00001002d000094C1*
  ID_MODEL_FROM_DATABASE=RV610 [Radeon HD 2400 PRO/XT]
 
 pci:v00001002d000094C1sv00001028sd00000211*
- ID_MODEL_FROM_DATABASE=Optiplex 755
+ ID_MODEL_FROM_DATABASE=RV610 [Radeon HD 2400 PRO/XT] (Optiplex 755)
 
 pci:v00001002d000094C1sv00001028sd00000D02*
- ID_MODEL_FROM_DATABASE=Optiplex 755
+ ID_MODEL_FROM_DATABASE=RV610 [Radeon HD 2400 PRO/XT] (Optiplex 755)
 
 pci:v00001002d000094C3*
  ID_MODEL_FROM_DATABASE=RV610 [Radeon HD 2400 PRO]
 
 pci:v00001002d000094C3sv00001028sd00000302*
- ID_MODEL_FROM_DATABASE=Radeon HD 2400 Pro
+ ID_MODEL_FROM_DATABASE=RV610 [Radeon HD 2400 PRO] (Radeon HD 2400 Pro)
 
 pci:v00001002d000094C3sv0000174Bsd0000E400*
- ID_MODEL_FROM_DATABASE=Radeon HD 2400 PRO
+ ID_MODEL_FROM_DATABASE=RV610 [Radeon HD 2400 PRO] (Radeon HD 2400 PRO)
 
 pci:v00001002d000094C3sv000018BCsd00003550*
- ID_MODEL_FROM_DATABASE=Radeon HD 2400 PRO
+ ID_MODEL_FROM_DATABASE=RV610 [Radeon HD 2400 PRO] (Radeon HD 2400 PRO)
 
 pci:v00001002d000094C4*
  ID_MODEL_FROM_DATABASE=RV610 LE [Radeon HD 2400 PRO AGP]
@@ -8400,7 +8544,7 @@ pci:v00001002d000094C9*
  ID_MODEL_FROM_DATABASE=RV610/M72-S [Mobility Radeon HD 2400]
 
 pci:v00001002d000094C9sv00001002sd000094C9*
- ID_MODEL_FROM_DATABASE=Radeon HD2400
+ ID_MODEL_FROM_DATABASE=RV610/M72-S [Mobility Radeon HD 2400] (Radeon HD2400)
 
 pci:v00001002d000094CB*
  ID_MODEL_FROM_DATABASE=RV610 [Radeon E2400]
@@ -8415,7 +8559,7 @@ pci:v00001002d00009501*
  ID_MODEL_FROM_DATABASE=RV670 [Radeon HD 3870]
 
 pci:v00001002d00009501sv0000174Bsd0000E620*
- ID_MODEL_FROM_DATABASE=Radeon HD 3870
+ ID_MODEL_FROM_DATABASE=RV670 [Radeon HD 3870] (Radeon HD 3870)
 
 pci:v00001002d00009504*
  ID_MODEL_FROM_DATABASE=RV670/M88 [Mobility Radeon HD 3850]
@@ -8424,13 +8568,13 @@ pci:v00001002d00009505*
  ID_MODEL_FROM_DATABASE=RV670 [Radeon HD 3690/3850]
 
 pci:v00001002d00009505sv0000148Csd00003000*
- ID_MODEL_FROM_DATABASE=Radeon HD 3850
+ ID_MODEL_FROM_DATABASE=RV670 [Radeon HD 3690/3850] (Radeon HD 3850)
 
 pci:v00001002d00009505sv0000174Bsd00003000*
- ID_MODEL_FROM_DATABASE=Radeon HD 3690/3850
+ ID_MODEL_FROM_DATABASE=RV670 [Radeon HD 3690/3850] (Radeon HD 3690/3850)
 
 pci:v00001002d00009505sv00001787sd00003000*
- ID_MODEL_FROM_DATABASE=Radeon HD 3690
+ ID_MODEL_FROM_DATABASE=RV670 [Radeon HD 3690/3850] (Radeon HD 3690)
 
 pci:v00001002d00009506*
  ID_MODEL_FROM_DATABASE=RV670/M88 [Mobility Radeon HD 3850 X2]
@@ -8466,76 +8610,76 @@ pci:v00001002d0000954F*
  ID_MODEL_FROM_DATABASE=RV710 [Radeon HD 4350/4550]
 
 pci:v00001002d0000954Fsv00001462sd00001618*
- ID_MODEL_FROM_DATABASE=R4350 MD512H (MS-V161)
+ ID_MODEL_FROM_DATABASE=RV710 [Radeon HD 4350/4550] (R4350 MD512H (MS-V161))
 
 pci:v00001002d00009552*
  ID_MODEL_FROM_DATABASE=RV710/M92 [Mobility Radeon HD 4330/4350/4550]
 
 pci:v00001002d00009552sv00001028sd00001103*
- ID_MODEL_FROM_DATABASE=M92 [Mobility Radeon HD 4330]
+ ID_MODEL_FROM_DATABASE=RV710/M92 [Mobility Radeon HD 4330/4350/4550] (M92 [Mobility Radeon HD 4330])
 
 pci:v00001002d00009552sv00001458sd000021AC*
- ID_MODEL_FROM_DATABASE=Radeon HD 4350
+ ID_MODEL_FROM_DATABASE=RV710/M92 [Mobility Radeon HD 4330/4350/4550] (Radeon HD 4350)
 
 pci:v00001002d00009552sv00001458sd000021ED*
- ID_MODEL_FROM_DATABASE=Radeon HD 4550
+ ID_MODEL_FROM_DATABASE=RV710/M92 [Mobility Radeon HD 4330/4350/4550] (Radeon HD 4550)
 
 pci:v00001002d00009552sv0000148Csd00003000*
- ID_MODEL_FROM_DATABASE=Radeon HD 4350 Go! Green 512MB GDDR3
+ ID_MODEL_FROM_DATABASE=RV710/M92 [Mobility Radeon HD 4330/4350/4550] (Radeon HD 4350 Go! Green 512MB GDDR3)
 
 pci:v00001002d00009552sv0000174Bsd00003000*
- ID_MODEL_FROM_DATABASE=Radeon HD 4350/4550 HyperMemory DDR2
+ ID_MODEL_FROM_DATABASE=RV710/M92 [Mobility Radeon HD 4330/4350/4550] (Radeon HD 4350/4550 HyperMemory DDR2)
 
 pci:v00001002d00009553*
  ID_MODEL_FROM_DATABASE=RV710/M92 [Mobility Radeon HD 4530/4570/545v]
 
 pci:v00001002d00009553sv00001025sd0000015E*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 4570
+ ID_MODEL_FROM_DATABASE=RV710/M92 [Mobility Radeon HD 4530/4570/545v] (Mobility Radeon HD 4570)
 
 pci:v00001002d00009553sv00001025sd0000017D*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 4570
+ ID_MODEL_FROM_DATABASE=RV710/M92 [Mobility Radeon HD 4530/4570/545v] (Mobility Radeon HD 4570)
 
 pci:v00001002d00009553sv00001025sd00000205*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 4570
+ ID_MODEL_FROM_DATABASE=RV710/M92 [Mobility Radeon HD 4530/4570/545v] (Mobility Radeon HD 4570)
 
 pci:v00001002d00009553sv00001025sd00000206*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 4570
+ ID_MODEL_FROM_DATABASE=RV710/M92 [Mobility Radeon HD 4530/4570/545v] (Mobility Radeon HD 4570)
 
 pci:v00001002d00009553sv00001025sd00000237*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 4570
+ ID_MODEL_FROM_DATABASE=RV710/M92 [Mobility Radeon HD 4530/4570/545v] (Mobility Radeon HD 4570)
 
 pci:v00001002d00009553sv00001028sd000002BE*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 4570
+ ID_MODEL_FROM_DATABASE=RV710/M92 [Mobility Radeon HD 4530/4570/545v] (Mobility Radeon HD 4570)
 
 pci:v00001002d00009553sv00001028sd000002E8*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 4530
+ ID_MODEL_FROM_DATABASE=RV710/M92 [Mobility Radeon HD 4530/4570/545v] (Mobility Radeon HD 4530)
 
 pci:v00001002d00009553sv0000103Csd00003624*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 4530
+ ID_MODEL_FROM_DATABASE=RV710/M92 [Mobility Radeon HD 4530/4570/545v] (Mobility Radeon HD 4530)
 
 pci:v00001002d00009553sv0000103Csd00003628*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 4530
+ ID_MODEL_FROM_DATABASE=RV710/M92 [Mobility Radeon HD 4530/4570/545v] (Mobility Radeon HD 4530)
 
 pci:v00001002d00009553sv0000103Csd00003636*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 4530
+ ID_MODEL_FROM_DATABASE=RV710/M92 [Mobility Radeon HD 4530/4570/545v] (Mobility Radeon HD 4530)
 
 pci:v00001002d00009553sv00001043sd00001B32*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 4570
+ ID_MODEL_FROM_DATABASE=RV710/M92 [Mobility Radeon HD 4530/4570/545v] (Mobility Radeon HD 4570)
 
 pci:v00001002d00009553sv00001043sd00001B42*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 4570
+ ID_MODEL_FROM_DATABASE=RV710/M92 [Mobility Radeon HD 4530/4570/545v] (Mobility Radeon HD 4570)
 
 pci:v00001002d00009553sv0000104Dsd00009056*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 4570
+ ID_MODEL_FROM_DATABASE=RV710/M92 [Mobility Radeon HD 4530/4570/545v] (Mobility Radeon HD 4570)
 
 pci:v00001002d00009553sv00001179sd0000FF82*
- ID_MODEL_FROM_DATABASE=Satellite L505-13T GPU (Mobility Radeon HD 5145)
+ ID_MODEL_FROM_DATABASE=RV710/M92 [Mobility Radeon HD 4530/4570/545v] (Satellite L505-13T GPU (Mobility Radeon HD 5145))
 
 pci:v00001002d00009555*
  ID_MODEL_FROM_DATABASE=RV710/M92 [Mobility Radeon HD 4350/4550]
 
 pci:v00001002d00009555sv0000103Csd00001411*
- ID_MODEL_FROM_DATABASE=ProBook 4720s GPU (Mobility Radeon HD 4350)
+ ID_MODEL_FROM_DATABASE=RV710/M92 [Mobility Radeon HD 4350/4550] (ProBook 4720s GPU (Mobility Radeon HD 4350))
 
 pci:v00001002d00009557*
  ID_MODEL_FROM_DATABASE=RV711 GL [FirePro RG220]
@@ -8553,10 +8697,10 @@ pci:v00001002d00009583*
  ID_MODEL_FROM_DATABASE=RV630/M76 [Mobility Radeon HD 2600 XT/2700]
 
 pci:v00001002d00009583sv0000106Bsd00000083*
- ID_MODEL_FROM_DATABASE=iMac 7,1
+ ID_MODEL_FROM_DATABASE=RV630/M76 [Mobility Radeon HD 2600 XT/2700] (iMac 7,1)
 
 pci:v00001002d00009583sv00001734sd00001107*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 2700
+ ID_MODEL_FROM_DATABASE=RV630/M76 [Mobility Radeon HD 2600 XT/2700] (Mobility Radeon HD 2700)
 
 pci:v00001002d00009586*
  ID_MODEL_FROM_DATABASE=RV630 XT [Radeon HD 2600 XT AGP]
@@ -8568,13 +8712,13 @@ pci:v00001002d00009588*
  ID_MODEL_FROM_DATABASE=RV630 XT [Radeon HD 2600 XT]
 
 pci:v00001002d00009588sv00001458sd0000216C*
- ID_MODEL_FROM_DATABASE=Radeon HD 2600 XT, 256MB GDDR3, 2x DVI, TV-out, PCIe (GV-RX26T256H)
+ ID_MODEL_FROM_DATABASE=RV630 XT [Radeon HD 2600 XT] (Radeon HD 2600 XT, 256MB GDDR3, 2x DVI, TV-out, PCIe (GV-RX26T256H))
 
 pci:v00001002d00009589*
  ID_MODEL_FROM_DATABASE=RV630 PRO [Radeon HD 2600 PRO]
 
 pci:v00001002d00009589sv00001787sd00003000*
- ID_MODEL_FROM_DATABASE=Radeon HD 3610
+ ID_MODEL_FROM_DATABASE=RV630 PRO [Radeon HD 2600 PRO] (Radeon HD 3610)
 
 pci:v00001002d0000958A*
  ID_MODEL_FROM_DATABASE=RV630 [Radeon HD 2600 X2]
@@ -8592,7 +8736,7 @@ pci:v00001002d00009591*
  ID_MODEL_FROM_DATABASE=RV635/M86 [Mobility Radeon HD 3650]
 
 pci:v00001002d00009591sv00001002sd00009591*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 3650
+ ID_MODEL_FROM_DATABASE=RV635/M86 [Mobility Radeon HD 3650] (Mobility Radeon HD 3650)
 
 pci:v00001002d00009593*
  ID_MODEL_FROM_DATABASE=RV635/M86 [Mobility Radeon HD 3670]
@@ -8604,7 +8748,7 @@ pci:v00001002d00009596*
  ID_MODEL_FROM_DATABASE=RV635 PRO [Radeon HD 3650 AGP]
 
 pci:v00001002d00009596sv00001043sd00000028*
- ID_MODEL_FROM_DATABASE=EAH3650 SILENT/HTDI/512M/A
+ ID_MODEL_FROM_DATABASE=RV635 PRO [Radeon HD 3650 AGP] (EAH3650 SILENT/HTDI/512M/A)
 
 pci:v00001002d00009597*
  ID_MODEL_FROM_DATABASE=RV635 PRO [Radeon HD 3650 AGP]
@@ -8613,19 +8757,19 @@ pci:v00001002d00009598*
  ID_MODEL_FROM_DATABASE=RV635 [Radeon HD 3650/3750/4570/4580]
 
 pci:v00001002d00009598sv00001002sd00009598*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 3600
+ ID_MODEL_FROM_DATABASE=RV635 [Radeon HD 3650/3750/4570/4580] (Mobility Radeon HD 3600)
 
 pci:v00001002d00009598sv00001043sd000001D6*
- ID_MODEL_FROM_DATABASE=EAH3650 Silent
+ ID_MODEL_FROM_DATABASE=RV635 [Radeon HD 3650/3750/4570/4580] (EAH3650 Silent)
 
 pci:v00001002d00009598sv00001043sd00003001*
- ID_MODEL_FROM_DATABASE=Radeon HD 4570
+ ID_MODEL_FROM_DATABASE=RV635 [Radeon HD 3650/3750/4570/4580] (Radeon HD 4570)
 
 pci:v00001002d00009598sv0000174Bsd00003001*
- ID_MODEL_FROM_DATABASE=Radeon HD 3750
+ ID_MODEL_FROM_DATABASE=RV635 [Radeon HD 3650/3750/4570/4580] (Radeon HD 3750)
 
 pci:v00001002d00009598sv0000174Bsd00004580*
- ID_MODEL_FROM_DATABASE=RV635 PRO [Radeon HD 4580]
+ ID_MODEL_FROM_DATABASE=RV635 [Radeon HD 3650/3750/4570/4580] (RV635 PRO [Radeon HD 4580])
 
 pci:v00001002d00009599*
  ID_MODEL_FROM_DATABASE=RV635 PRO [Radeon HD 3650 AGP]
@@ -8634,7 +8778,7 @@ pci:v00001002d000095C0*
  ID_MODEL_FROM_DATABASE=RV620 PRO [Radeon HD 3470]
 
 pci:v00001002d000095C0sv00001002sd000095C0*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 3470
+ ID_MODEL_FROM_DATABASE=RV620 PRO [Radeon HD 3470] (Mobility Radeon HD 3470)
 
 pci:v00001002d000095C2*
  ID_MODEL_FROM_DATABASE=RV620/M82 [Mobility Radeon HD 3410/3430]
@@ -8643,13 +8787,13 @@ pci:v00001002d000095C4*
  ID_MODEL_FROM_DATABASE=RV620/M82 [Mobility Radeon HD 3450/3470]
 
 pci:v00001002d000095C4sv00001002sd000095C4*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 3400
+ ID_MODEL_FROM_DATABASE=RV620/M82 [Mobility Radeon HD 3450/3470] (Mobility Radeon HD 3400)
 
 pci:v00001002d000095C5*
  ID_MODEL_FROM_DATABASE=RV620 LE [Radeon HD 3450]
 
 pci:v00001002d000095C5sv00001028sd00000342*
- ID_MODEL_FROM_DATABASE=OptiPlex 980
+ ID_MODEL_FROM_DATABASE=RV620 LE [Radeon HD 3450] (OptiPlex 980)
 
 pci:v00001002d000095C6*
  ID_MODEL_FROM_DATABASE=RV620 LE [Radeon HD 3450 AGP]
@@ -8670,7 +8814,7 @@ pci:v00001002d00009610*
  ID_MODEL_FROM_DATABASE=RS780 [Radeon HD 3200]
 
 pci:v00001002d00009610sv00001458sd0000D000*
- ID_MODEL_FROM_DATABASE=GA-MA78GM-S2H Motherboard
+ ID_MODEL_FROM_DATABASE=RS780 [Radeon HD 3200] (GA-MA78GM-S2H Motherboard)
 
 pci:v00001002d00009611*
  ID_MODEL_FROM_DATABASE=RS780C [Radeon 3100]
@@ -8733,22 +8877,22 @@ pci:v00001002d0000970F*
  ID_MODEL_FROM_DATABASE=RS880 HDMI Audio [Radeon HD 4200 Series]
 
 pci:v00001002d0000970Fsv00001019sd00002120*
- ID_MODEL_FROM_DATABASE=A785GM-M
+ ID_MODEL_FROM_DATABASE=RS880 HDMI Audio [Radeon HD 4200 Series] (A785GM-M)
 
 pci:v00001002d0000970Fsv00001043sd000083A2*
- ID_MODEL_FROM_DATABASE=M4A785TD Motherboard
+ ID_MODEL_FROM_DATABASE=RS880 HDMI Audio [Radeon HD 4200 Series] (M4A785TD Motherboard)
 
 pci:v00001002d0000970Fsv00001043sd0000843E*
- ID_MODEL_FROM_DATABASE=M5A88-V EVO
+ ID_MODEL_FROM_DATABASE=RS880 HDMI Audio [Radeon HD 4200 Series] (M5A88-V EVO)
 
 pci:v00001002d00009710*
  ID_MODEL_FROM_DATABASE=RS880 [Radeon HD 4200]
 
 pci:v00001002d00009710sv00001019sd00002120*
- ID_MODEL_FROM_DATABASE=A785GM-M
+ ID_MODEL_FROM_DATABASE=RS880 [Radeon HD 4200] (A785GM-M)
 
 pci:v00001002d00009710sv00001043sd000083A2*
- ID_MODEL_FROM_DATABASE=M4A785TD Motherboard
+ ID_MODEL_FROM_DATABASE=RS880 [Radeon HD 4200] (M4A785TD Motherboard)
 
 pci:v00001002d00009712*
  ID_MODEL_FROM_DATABASE=RS880M [Mobility Radeon HD 4225/4250]
@@ -8763,13 +8907,13 @@ pci:v00001002d00009715*
  ID_MODEL_FROM_DATABASE=RS880 [Radeon HD 4250]
 
 pci:v00001002d00009715sv00001043sd0000843E*
- ID_MODEL_FROM_DATABASE=M5A88-V EVO
+ ID_MODEL_FROM_DATABASE=RS880 [Radeon HD 4250] (M5A88-V EVO)
 
 pci:v00001002d00009802*
  ID_MODEL_FROM_DATABASE=Wrestler [Radeon HD 6310]
 
 pci:v00001002d00009802sv0000174Bsd00001001*
- ID_MODEL_FROM_DATABASE=PURE Fusion Mini
+ ID_MODEL_FROM_DATABASE=Wrestler [Radeon HD 6310] (PURE Fusion Mini)
 
 pci:v00001002d00009803*
  ID_MODEL_FROM_DATABASE=Wrestler [Radeon HD 6310]
@@ -8796,7 +8940,7 @@ pci:v00001002d0000980A*
  ID_MODEL_FROM_DATABASE=Wrestler [Radeon HD 7290]
 
 pci:v00001002d00009830*
- ID_MODEL_FROM_DATABASE=Kabini [Radeon HD 8400]
+ ID_MODEL_FROM_DATABASE=Kabini [Radeon HD 8400 / R3 Series]
 
 pci:v00001002d00009831*
  ID_MODEL_FROM_DATABASE=Kabini [Radeon HD 8400E]
@@ -8814,13 +8958,13 @@ pci:v00001002d00009835*
  ID_MODEL_FROM_DATABASE=Kabini [Radeon HD 8310E]
 
 pci:v00001002d00009836*
- ID_MODEL_FROM_DATABASE=Kabini [Radeon HD 8280]
+ ID_MODEL_FROM_DATABASE=Kabini [Radeon HD 8280 / R3 Series]
 
 pci:v00001002d00009837*
  ID_MODEL_FROM_DATABASE=Kabini [Radeon HD 8280E]
 
 pci:v00001002d00009838*
- ID_MODEL_FROM_DATABASE=Kabini [Radeon HD 8240]
+ ID_MODEL_FROM_DATABASE=Kabini [Radeon HD 8240 / R3 Series]
 
 pci:v00001002d00009839*
  ID_MODEL_FROM_DATABASE=Kabini [Radeon HD 8180]
@@ -8843,26 +8987,29 @@ pci:v00001002d0000983E*
 pci:v00001002d0000983F*
  ID_MODEL_FROM_DATABASE=Kabini
 
+pci:v00001002d00009840*
+ ID_MODEL_FROM_DATABASE=Kabini HDMI/DP Audio
+
 pci:v00001002d00009850*
- ID_MODEL_FROM_DATABASE=Mullins [Radeon APU A6-6200 with R3 Graphics]
+ ID_MODEL_FROM_DATABASE=Mullins [Radeon R3 Graphics]
 
 pci:v00001002d00009851*
- ID_MODEL_FROM_DATABASE=Mullins [Radeon APU A4-6000 with R2 Graphics]
+ ID_MODEL_FROM_DATABASE=Mullins [Radeon R4/R5 Graphics]
 
 pci:v00001002d00009852*
- ID_MODEL_FROM_DATABASE=Mullins [Radeon APU A4-6000 with R2 Graphics]
+ ID_MODEL_FROM_DATABASE=Mullins [Radeon R2 Graphics]
 
 pci:v00001002d00009853*
- ID_MODEL_FROM_DATABASE=Mullins [Radeon APU E2-4000 with R2 Graphics]
+ ID_MODEL_FROM_DATABASE=Mullins [Radeon R2 Graphics]
 
 pci:v00001002d00009854*
- ID_MODEL_FROM_DATABASE=Mullins [Radeon APU E2-3700 with R2 Graphics]
+ ID_MODEL_FROM_DATABASE=Mullins [Radeon R3 Graphics]
 
 pci:v00001002d00009855*
- ID_MODEL_FROM_DATABASE=Mullins [Radeon APU XX-2450M with R3 Graphics]
+ ID_MODEL_FROM_DATABASE=Mullins [Radeon R6 Graphics]
 
 pci:v00001002d00009856*
- ID_MODEL_FROM_DATABASE=Mullins [Radeon APU XX-2200M with R2 Graphics]
+ ID_MODEL_FROM_DATABASE=Mullins [Radeon R2 Graphics]
 
 pci:v00001002d00009857*
  ID_MODEL_FROM_DATABASE=Mullins [Radeon APU XX-2200M with R2 Graphics]
@@ -8891,6 +9038,9 @@ pci:v00001002d0000985E*
 pci:v00001002d0000985F*
  ID_MODEL_FROM_DATABASE=Mullins
 
+pci:v00001002d00009900*
+ ID_MODEL_FROM_DATABASE=Trinity [Radeon HD 7660G]
+
 pci:v00001002d00009901*
  ID_MODEL_FROM_DATABASE=Trinity [Radeon HD 7660D]
 
@@ -8898,16 +9048,16 @@ pci:v00001002d00009902*
  ID_MODEL_FROM_DATABASE=Trinity HDMI Audio Controller
 
 pci:v00001002d00009902sv0000103Csd0000194E*
- ID_MODEL_FROM_DATABASE=ProBook 455 G1 Notebook
+ ID_MODEL_FROM_DATABASE=Trinity HDMI Audio Controller (ProBook 455 G1 Notebook)
 
 pci:v00001002d00009903*
  ID_MODEL_FROM_DATABASE=Trinity [Radeon HD 7640G]
 
 pci:v00001002d00009903sv0000103Csd0000194E*
- ID_MODEL_FROM_DATABASE=ProBook 455 G1 Notebook
+ ID_MODEL_FROM_DATABASE=Trinity [Radeon HD 7640G] (ProBook 455 G1 Notebook)
 
 pci:v00001002d00009903sv0000103Csd00001952*
- ID_MODEL_FROM_DATABASE=ProBook 455 G1 Notebook
+ ID_MODEL_FROM_DATABASE=Trinity [Radeon HD 7640G] (ProBook 455 G1 Notebook)
 
 pci:v00001002d00009904*
  ID_MODEL_FROM_DATABASE=Trinity [Radeon HD 7560D]
@@ -9021,10 +9171,10 @@ pci:v00001002d0000AA10*
  ID_MODEL_FROM_DATABASE=RV610 HDMI Audio [Radeon HD 2350/2400 Series]
 
 pci:v00001002d0000AA10sv0000174Bsd0000AA10*
- ID_MODEL_FROM_DATABASE=Radeon HD 2400 PRO
+ ID_MODEL_FROM_DATABASE=RV610 HDMI Audio [Radeon HD 2350/2400 Series] (Radeon HD 2400 PRO)
 
 pci:v00001002d0000AA10sv000018BCsd0000AA10*
- ID_MODEL_FROM_DATABASE=Radeon HD 2400 PRO
+ ID_MODEL_FROM_DATABASE=RV610 HDMI Audio [Radeon HD 2350/2400 Series] (Radeon HD 2400 PRO)
 
 pci:v00001002d0000AA18*
  ID_MODEL_FROM_DATABASE=RV670/680 HDMI Audio [Radeon HD 3690/3800 Series]
@@ -9039,13 +9189,13 @@ pci:v00001002d0000AA30*
  ID_MODEL_FROM_DATABASE=RV770 HDMI Audio [Radeon HD 4850/4870]
 
 pci:v00001002d0000AA30sv0000174Bsd0000AA30*
- ID_MODEL_FROM_DATABASE=Radeon HD 4850 512MB GDDR3 PCI-E Dual Slot Fansink
+ ID_MODEL_FROM_DATABASE=RV770 HDMI Audio [Radeon HD 4850/4870] (Radeon HD 4850 512MB GDDR3 PCI-E Dual Slot Fansink)
 
 pci:v00001002d0000AA38*
  ID_MODEL_FROM_DATABASE=RV710/730 HDMI Audio [Radeon HD 4000 series]
 
 pci:v00001002d0000AA38sv0000103Csd00003628*
- ID_MODEL_FROM_DATABASE=dv6-1190en
+ ID_MODEL_FROM_DATABASE=RV710/730 HDMI Audio [Radeon HD 4000 series] (dv6-1190en)
 
 pci:v00001002d0000AA50*
  ID_MODEL_FROM_DATABASE=Cypress HDMI Audio [Radeon HD 5800 Series]
@@ -9057,16 +9207,16 @@ pci:v00001002d0000AA60*
  ID_MODEL_FROM_DATABASE=Redwood HDMI Audio [Radeon HD 5000 Series]
 
 pci:v00001002d0000AA60sv00001025sd0000033D*
- ID_MODEL_FROM_DATABASE=Mobility Radeon HD 5650
+ ID_MODEL_FROM_DATABASE=Redwood HDMI Audio [Radeon HD 5000 Series] (Mobility Radeon HD 5650)
 
 pci:v00001002d0000AA60sv00001025sd00000347*
- ID_MODEL_FROM_DATABASE=Aspire 7740G
+ ID_MODEL_FROM_DATABASE=Redwood HDMI Audio [Radeon HD 5000 Series] (Aspire 7740G)
 
 pci:v00001002d0000AA68*
  ID_MODEL_FROM_DATABASE=Cedar HDMI Audio [Radeon HD 5400/6300 Series]
 
 pci:v00001002d0000AA68sv00001028sd0000AA68*
- ID_MODEL_FROM_DATABASE=XPS 8300
+ ID_MODEL_FROM_DATABASE=Cedar HDMI Audio [Radeon HD 5400/6300 Series] (XPS 8300)
 
 pci:v00001002d0000AA80*
  ID_MODEL_FROM_DATABASE=Cayman/Antilles HDMI Audio [Radeon HD 6900 Series]
@@ -9078,13 +9228,13 @@ pci:v00001002d0000AA90*
  ID_MODEL_FROM_DATABASE=Turks/Whistler HDMI Audio [Radeon HD 6000 Series]
 
 pci:v00001002d0000AA90sv00001028sd000004A3*
- ID_MODEL_FROM_DATABASE=Precision M4600
+ ID_MODEL_FROM_DATABASE=Turks/Whistler HDMI Audio [Radeon HD 6000 Series] (Precision M4600)
 
 pci:v00001002d0000AA98*
  ID_MODEL_FROM_DATABASE=Caicos HDMI Audio [Radeon HD 6400 Series]
 
 pci:v00001002d0000AA98sv0000174Bsd0000AA98*
- ID_MODEL_FROM_DATABASE=Radeon HD 6450 1GB DDR3
+ ID_MODEL_FROM_DATABASE=Caicos HDMI Audio [Radeon HD 6400 Series] (Radeon HD 6450 1GB DDR3)
 
 pci:v00001002d0000AAA0*
  ID_MODEL_FROM_DATABASE=Tahiti XT HDMI Audio [Radeon HD 7970 Series]
@@ -9171,10 +9321,10 @@ pci:v00001004d00000304sv00001004sd00000304*
  ID_MODEL_FROM_DATABASE=QSound ThunderBird PCI Audio
 
 pci:v00001004d00000304sv0000122Dsd00001206*
- ID_MODEL_FROM_DATABASE=DSP368 Audio
+ ID_MODEL_FROM_DATABASE=QSound ThunderBird PCI Audio (DSP368 Audio)
 
 pci:v00001004d00000304sv00001483sd00005020*
- ID_MODEL_FROM_DATABASE=XWave Thunder 3D Audio
+ ID_MODEL_FROM_DATABASE=QSound ThunderBird PCI Audio (XWave Thunder 3D Audio)
 
 pci:v00001004d00000305*
  ID_MODEL_FROM_DATABASE=QSound ThunderBird PCI Audio Gameport
@@ -9183,10 +9333,10 @@ pci:v00001004d00000305sv00001004sd00000305*
  ID_MODEL_FROM_DATABASE=QSound ThunderBird PCI Audio Gameport
 
 pci:v00001004d00000305sv0000122Dsd00001207*
- ID_MODEL_FROM_DATABASE=DSP368 Audio Gameport
+ ID_MODEL_FROM_DATABASE=QSound ThunderBird PCI Audio Gameport (DSP368 Audio Gameport)
 
 pci:v00001004d00000305sv00001483sd00005021*
- ID_MODEL_FROM_DATABASE=XWave Thunder 3D Audio Gameport
+ ID_MODEL_FROM_DATABASE=QSound ThunderBird PCI Audio Gameport (XWave Thunder 3D Audio Gameport)
 
 pci:v00001004d00000306*
  ID_MODEL_FROM_DATABASE=QSound ThunderBird PCI Audio Support Registers
@@ -9195,22 +9345,22 @@ pci:v00001004d00000306sv00001004sd00000306*
  ID_MODEL_FROM_DATABASE=QSound ThunderBird PCI Audio Support Registers
 
 pci:v00001004d00000306sv0000122Dsd00001208*
- ID_MODEL_FROM_DATABASE=DSP368 Audio Support Registers
+ ID_MODEL_FROM_DATABASE=QSound ThunderBird PCI Audio Support Registers (DSP368 Audio Support Registers)
 
 pci:v00001004d00000306sv00001483sd00005022*
- ID_MODEL_FROM_DATABASE=XWave Thunder 3D Audio Support Registers
+ ID_MODEL_FROM_DATABASE=QSound ThunderBird PCI Audio Support Registers (XWave Thunder 3D Audio Support Registers)
 
 pci:v00001004d00000307*
  ID_MODEL_FROM_DATABASE=SAA7785 ThunderBird PCI Audio
 
 pci:v00001004d00000307sv00001004sd00000703*
- ID_MODEL_FROM_DATABASE=Philips Rhythmic Edge PSC703
+ ID_MODEL_FROM_DATABASE=SAA7785 ThunderBird PCI Audio (Philips Rhythmic Edge PSC703)
 
 pci:v00001004d00000307sv00001004sd00000705*
- ID_MODEL_FROM_DATABASE=Philips Seismic Edge PSC705
+ ID_MODEL_FROM_DATABASE=SAA7785 ThunderBird PCI Audio (Philips Seismic Edge PSC705)
 
 pci:v00001004d00000307sv00001004sd00000706*
- ID_MODEL_FROM_DATABASE=Philips Acoustic Edge PSC706
+ ID_MODEL_FROM_DATABASE=SAA7785 ThunderBird PCI Audio (Philips Acoustic Edge PSC706)
 
 pci:v00001004d00000308*
  ID_MODEL_FROM_DATABASE=SAA7785 ThunderBird PCI Audio Gameport
@@ -9282,16 +9432,16 @@ pci:v0000100Bd00000020*
  ID_MODEL_FROM_DATABASE=DP83815 (MacPhyter) Ethernet Controller
 
 pci:v0000100Bd00000020sv0000103Csd00000024*
- ID_MODEL_FROM_DATABASE=Pavilion ze4400 builtin Network
+ ID_MODEL_FROM_DATABASE=DP83815 (MacPhyter) Ethernet Controller (Pavilion ze4400 builtin Network)
 
 pci:v0000100Bd00000020sv000012D9sd0000000C*
- ID_MODEL_FROM_DATABASE=Aculab E1/T1 PMXc cPCI carrier card
+ ID_MODEL_FROM_DATABASE=DP83815 (MacPhyter) Ethernet Controller (Aculab E1/T1 PMXc cPCI carrier card)
 
 pci:v0000100Bd00000020sv00001385sd0000F311*
- ID_MODEL_FROM_DATABASE=FA311 / FA312 (FA311 with WoL HW)
+ ID_MODEL_FROM_DATABASE=DP83815 (MacPhyter) Ethernet Controller (FA311 / FA312 (FA311 with WoL HW))
 
 pci:v0000100Bd00000020sv00001385sd0000F312*
- ID_MODEL_FROM_DATABASE=FA312 (rev. A1) Fast Ethernet PCI Adapter
+ ID_MODEL_FROM_DATABASE=DP83815 (MacPhyter) Ethernet Controller (FA312 (rev. A1) Fast Ethernet PCI Adapter)
 
 pci:v0000100Bd00000021*
  ID_MODEL_FROM_DATABASE=PC87200 PCI to ISA Bridge
@@ -9300,13 +9450,13 @@ pci:v0000100Bd00000022*
  ID_MODEL_FROM_DATABASE=DP83820 10/100/1000 Ethernet Controller
 
 pci:v0000100Bd00000022sv00001186sd00004900*
- ID_MODEL_FROM_DATABASE=DGE-500T
+ ID_MODEL_FROM_DATABASE=DP83820 10/100/1000 Ethernet Controller (DGE-500T)
 
 pci:v0000100Bd00000022sv00001385sd0000621A*
- ID_MODEL_FROM_DATABASE=GA621
+ ID_MODEL_FROM_DATABASE=DP83820 10/100/1000 Ethernet Controller (GA621)
 
 pci:v0000100Bd00000022sv00001385sd0000622A*
- ID_MODEL_FROM_DATABASE=GA622T
+ ID_MODEL_FROM_DATABASE=DP83820 10/100/1000 Ethernet Controller (GA622T)
 
 pci:v0000100Bd00000028*
  ID_MODEL_FROM_DATABASE=Geode GX2 Host Bridge
@@ -9342,13 +9492,13 @@ pci:v0000100Bd00000502*
  ID_MODEL_FROM_DATABASE=SCx200, SC1100 IDE controller
 
 pci:v0000100Bd00000502sv0000100Bsd00000502*
- ID_MODEL_FROM_DATABASE=IDE Controller
+ ID_MODEL_FROM_DATABASE=SCx200, SC1100 IDE controller (IDE Controller)
 
 pci:v0000100Bd00000503*
  ID_MODEL_FROM_DATABASE=SCx200, SC1100 Audio Controller
 
 pci:v0000100Bd00000503sv0000100Bsd00000503*
- ID_MODEL_FROM_DATABASE=XpressAudio controller
+ ID_MODEL_FROM_DATABASE=SCx200, SC1100 Audio Controller (XpressAudio controller)
 
 pci:v0000100Bd00000504*
  ID_MODEL_FROM_DATABASE=SCx200 Video
@@ -9360,19 +9510,19 @@ pci:v0000100Bd00000510*
  ID_MODEL_FROM_DATABASE=SC1100 Bridge
 
 pci:v0000100Bd00000510sv0000100Bsd00000500*
- ID_MODEL_FROM_DATABASE=GPIO and LPC support bridge
+ ID_MODEL_FROM_DATABASE=SC1100 Bridge (GPIO and LPC support bridge)
 
 pci:v0000100Bd00000511*
  ID_MODEL_FROM_DATABASE=SC1100 SMI & ACPI
 
 pci:v0000100Bd00000511sv0000100Bsd00000501*
- ID_MODEL_FROM_DATABASE=SC1100 SMI & ACPI bridge
+ ID_MODEL_FROM_DATABASE=SC1100 SMI & ACPI (bridge)
 
 pci:v0000100Bd00000515*
  ID_MODEL_FROM_DATABASE=SC1100 XBus
 
 pci:v0000100Bd00000515sv0000100Bsd00000505*
- ID_MODEL_FROM_DATABASE=SC1100 PCI to XBus bridge
+ ID_MODEL_FROM_DATABASE=SC1100 XBus (SC1100 PCI to XBus bridge)
 
 pci:v0000100Bd0000D001*
  ID_MODEL_FROM_DATABASE=87410 IDE
@@ -9441,55 +9591,55 @@ pci:v00001011d00000009*
  ID_MODEL_FROM_DATABASE=DECchip 21140 [FasterNet]
 
 pci:v00001011d00000009sv00001025sd00000310*
- ID_MODEL_FROM_DATABASE=21140 Fast Ethernet
+ ID_MODEL_FROM_DATABASE=DECchip 21140 [FasterNet] (21140 Fast Ethernet)
 
 pci:v00001011d00000009sv000010B8sd00002001*
- ID_MODEL_FROM_DATABASE=SMC9332BDT EtherPower 10/100
+ ID_MODEL_FROM_DATABASE=DECchip 21140 [FasterNet] (SMC9332BDT EtherPower 10/100)
 
 pci:v00001011d00000009sv000010B8sd00002002*
- ID_MODEL_FROM_DATABASE=SMC9332BVT EtherPower T4 10/100
+ ID_MODEL_FROM_DATABASE=DECchip 21140 [FasterNet] (SMC9332BVT EtherPower T4 10/100)
 
 pci:v00001011d00000009sv000010B8sd00002003*
- ID_MODEL_FROM_DATABASE=SMC9334BDT EtherPower 10/100 (1-port)
+ ID_MODEL_FROM_DATABASE=DECchip 21140 [FasterNet] (SMC9334BDT EtherPower 10/100 (1-port))
 
 pci:v00001011d00000009sv00001109sd00002400*
- ID_MODEL_FROM_DATABASE=ANA-6944A/TX Fast Ethernet
+ ID_MODEL_FROM_DATABASE=DECchip 21140 [FasterNet] (ANA-6944A/TX Fast Ethernet)
 
 pci:v00001011d00000009sv00001112sd00002300*
- ID_MODEL_FROM_DATABASE=RNS2300 Fast Ethernet
+ ID_MODEL_FROM_DATABASE=DECchip 21140 [FasterNet] (RNS2300 Fast Ethernet)
 
 pci:v00001011d00000009sv00001112sd00002320*
- ID_MODEL_FROM_DATABASE=RNS2320 Fast Ethernet
+ ID_MODEL_FROM_DATABASE=DECchip 21140 [FasterNet] (RNS2320 Fast Ethernet)
 
 pci:v00001011d00000009sv00001112sd00002340*
- ID_MODEL_FROM_DATABASE=RNS2340 Fast Ethernet
+ ID_MODEL_FROM_DATABASE=DECchip 21140 [FasterNet] (RNS2340 Fast Ethernet)
 
 pci:v00001011d00000009sv00001113sd00001207*
- ID_MODEL_FROM_DATABASE=EN-1207-TX Fast Ethernet
+ ID_MODEL_FROM_DATABASE=DECchip 21140 [FasterNet] (EN-1207-TX Fast Ethernet)
 
 pci:v00001011d00000009sv00001186sd00001100*
- ID_MODEL_FROM_DATABASE=DFE-500TX Fast Ethernet
+ ID_MODEL_FROM_DATABASE=DECchip 21140 [FasterNet] (DFE-500TX Fast Ethernet)
 
 pci:v00001011d00000009sv00001186sd00001112*
- ID_MODEL_FROM_DATABASE=DFE-570TX Fast Ethernet
+ ID_MODEL_FROM_DATABASE=DECchip 21140 [FasterNet] (DFE-570TX Fast Ethernet)
 
 pci:v00001011d00000009sv00001186sd00001140*
- ID_MODEL_FROM_DATABASE=DFE-660 Cardbus Ethernet 10/100
+ ID_MODEL_FROM_DATABASE=DECchip 21140 [FasterNet] (DFE-660 Cardbus Ethernet 10/100)
 
 pci:v00001011d00000009sv00001186sd00001142*
- ID_MODEL_FROM_DATABASE=DFE-660 Cardbus Ethernet 10/100
+ ID_MODEL_FROM_DATABASE=DECchip 21140 [FasterNet] (DFE-660 Cardbus Ethernet 10/100)
 
 pci:v00001011d00000009sv000011F6sd00000503*
- ID_MODEL_FROM_DATABASE=Freedomline Fast Ethernet
+ ID_MODEL_FROM_DATABASE=DECchip 21140 [FasterNet] (Freedomline Fast Ethernet)
 
 pci:v00001011d00000009sv00001282sd00009100*
- ID_MODEL_FROM_DATABASE=AEF-380TXD Fast Ethernet
+ ID_MODEL_FROM_DATABASE=DECchip 21140 [FasterNet] (AEF-380TXD Fast Ethernet)
 
 pci:v00001011d00000009sv00001385sd00001100*
- ID_MODEL_FROM_DATABASE=FA310TX Fast Ethernet
+ ID_MODEL_FROM_DATABASE=DECchip 21140 [FasterNet] (FA310TX Fast Ethernet)
 
 pci:v00001011d00000009sv00002646sd00000001*
- ID_MODEL_FROM_DATABASE=KNE100TX Fast Ethernet
+ ID_MODEL_FROM_DATABASE=DECchip 21140 [FasterNet] (KNE100TX Fast Ethernet)
 
 pci:v00001011d0000000A*
  ID_MODEL_FROM_DATABASE=21230 Video Codec
@@ -9498,19 +9648,19 @@ pci:v00001011d0000000D*
  ID_MODEL_FROM_DATABASE=PBXGB [TGA2]
 
 pci:v00001011d0000000F*
- ID_MODEL_FROM_DATABASE=PCI-to-PDQ Interface Chip [PFI]
+ ID_MODEL_FROM_DATABASE=DEFPA FDDI PCI-to-PDQ Interface Chip [PFI]
 
 pci:v00001011d0000000Fsv00001011sd0000DEF1*
- ID_MODEL_FROM_DATABASE=FDDI controller (DEFPA)
+ ID_MODEL_FROM_DATABASE=DEFPA FDDI PCI-to-PDQ Interface Chip [PFI] (FDDI controller (DEFPA))
 
 pci:v00001011d0000000Fsv0000103Csd0000DEF1*
- ID_MODEL_FROM_DATABASE=FDDI controller (3X-DEFPA)
+ ID_MODEL_FROM_DATABASE=DEFPA FDDI PCI-to-PDQ Interface Chip [PFI] (FDDI controller (3X-DEFPA))
 
 pci:v00001011d00000014*
  ID_MODEL_FROM_DATABASE=DECchip 21041 [Tulip Pass 3]
 
 pci:v00001011d00000014sv00001186sd00000100*
- ID_MODEL_FROM_DATABASE=DE-530+
+ ID_MODEL_FROM_DATABASE=DECchip 21041 [Tulip Pass 3] (DE-530+)
 
 pci:v00001011d00000016*
  ID_MODEL_FROM_DATABASE=DGLPB [OPPO]
@@ -9525,130 +9675,133 @@ pci:v00001011d00000019*
  ID_MODEL_FROM_DATABASE=DECchip 21142/43
 
 pci:v00001011d00000019sv00001011sd0000500A*
- ID_MODEL_FROM_DATABASE=DE500A Fast Ethernet
+ ID_MODEL_FROM_DATABASE=DECchip 21142/43 (DE500A Fast Ethernet)
 
 pci:v00001011d00000019sv00001011sd0000500B*
- ID_MODEL_FROM_DATABASE=DE500B Fast Ethernet
+ ID_MODEL_FROM_DATABASE=DECchip 21142/43 (DE500B Fast Ethernet)
 
 pci:v00001011d00000019sv00001014sd00000001*
- ID_MODEL_FROM_DATABASE=10/100 EtherJet Cardbus
+ ID_MODEL_FROM_DATABASE=DECchip 21142/43 (10/100 EtherJet Cardbus)
 
 pci:v00001011d00000019sv00001025sd00000315*
- ID_MODEL_FROM_DATABASE=ALN315 Fast Ethernet
+ ID_MODEL_FROM_DATABASE=DECchip 21142/43 (ALN315 Fast Ethernet)
 
 pci:v00001011d00000019sv00001033sd0000800C*
- ID_MODEL_FROM_DATABASE=PC-9821-CS01 100BASE-TX Interface Card
+ ID_MODEL_FROM_DATABASE=DECchip 21142/43 (PC-9821-CS01 100BASE-TX Interface Card)
 
 pci:v00001011d00000019sv00001033sd0000800D*
- ID_MODEL_FROM_DATABASE=PC-9821NR-B06 100BASE-TX Interface Card
+ ID_MODEL_FROM_DATABASE=DECchip 21142/43 (PC-9821NR-B06 100BASE-TX Interface Card)
 
 pci:v00001011d00000019sv0000103Csd0000125A*
- ID_MODEL_FROM_DATABASE=10/100Base-TX (PCI) [A5506B]
+ ID_MODEL_FROM_DATABASE=DECchip 21142/43 (10/100Base-TX (PCI) [A5506B])
 
 pci:v00001011d00000019sv0000108Dsd00000016*
- ID_MODEL_FROM_DATABASE=Rapidfire 2327 10/100 Ethernet
+ ID_MODEL_FROM_DATABASE=DECchip 21142/43 (Rapidfire 2327 10/100 Ethernet)
 
 pci:v00001011d00000019sv0000108Dsd00000017*
- ID_MODEL_FROM_DATABASE=GoCard 2250 Ethernet 10/100 Cardbus
+ ID_MODEL_FROM_DATABASE=DECchip 21142/43 (GoCard 2250 Ethernet 10/100 Cardbus)
 
 pci:v00001011d00000019sv000010B8sd00002005*
- ID_MODEL_FROM_DATABASE=SMC8032DT Extreme Ethernet 10/100
+ ID_MODEL_FROM_DATABASE=DECchip 21142/43 (SMC8032DT Extreme Ethernet 10/100)
 
 pci:v00001011d00000019sv000010B8sd00008034*
- ID_MODEL_FROM_DATABASE=SMC8034 Extreme Ethernet 10/100
+ ID_MODEL_FROM_DATABASE=DECchip 21142/43 (SMC8034 Extreme Ethernet 10/100)
 
 pci:v00001011d00000019sv000010EFsd00008169*
- ID_MODEL_FROM_DATABASE=Cardbus Fast Ethernet
+ ID_MODEL_FROM_DATABASE=DECchip 21142/43 (Cardbus Fast Ethernet)
 
 pci:v00001011d00000019sv00001109sd00002A00*
- ID_MODEL_FROM_DATABASE=ANA-6911A/TX Fast Ethernet
+ ID_MODEL_FROM_DATABASE=DECchip 21142/43 (ANA-6911A/TX Fast Ethernet)
 
 pci:v00001011d00000019sv00001109sd00002B00*
- ID_MODEL_FROM_DATABASE=ANA-6911A/TXC Fast Ethernet
+ ID_MODEL_FROM_DATABASE=DECchip 21142/43 (ANA-6911A/TXC Fast Ethernet)
 
 pci:v00001011d00000019sv00001109sd00003000*
- ID_MODEL_FROM_DATABASE=ANA-6922/TX Fast Ethernet
+ ID_MODEL_FROM_DATABASE=DECchip 21142/43 (ANA-6922/TX Fast Ethernet)
 
 pci:v00001011d00000019sv00001113sd00001207*
- ID_MODEL_FROM_DATABASE=Cheetah Fast Ethernet
+ ID_MODEL_FROM_DATABASE=DECchip 21142/43 (Cheetah Fast Ethernet)
 
 pci:v00001011d00000019sv00001113sd00002220*
- ID_MODEL_FROM_DATABASE=Cardbus Fast Ethernet
+ ID_MODEL_FROM_DATABASE=DECchip 21142/43 (Cardbus Fast Ethernet)
 
 pci:v00001011d00000019sv0000115Dsd00000002*
- ID_MODEL_FROM_DATABASE=Cardbus Ethernet 10/100
+ ID_MODEL_FROM_DATABASE=DECchip 21142/43 (Cardbus Ethernet 10/100)
 
 pci:v00001011d00000019sv00001179sd00000203*
- ID_MODEL_FROM_DATABASE=Fast Ethernet
+ ID_MODEL_FROM_DATABASE=DECchip 21142/43 (Fast Ethernet)
 
 pci:v00001011d00000019sv00001179sd00000204*
- ID_MODEL_FROM_DATABASE=Cardbus Fast Ethernet
+ ID_MODEL_FROM_DATABASE=DECchip 21142/43 (Cardbus Fast Ethernet)
 
 pci:v00001011d00000019sv00001186sd00001100*
- ID_MODEL_FROM_DATABASE=DFE-500TX Fast Ethernet
+ ID_MODEL_FROM_DATABASE=DECchip 21142/43 (DFE-500TX Fast Ethernet)
 
 pci:v00001011d00000019sv00001186sd00001101*
- ID_MODEL_FROM_DATABASE=DFE-500TX Fast Ethernet
+ ID_MODEL_FROM_DATABASE=DECchip 21142/43 (DFE-500TX Fast Ethernet)
 
 pci:v00001011d00000019sv00001186sd00001102*
- ID_MODEL_FROM_DATABASE=DFE-500TX Fast Ethernet
+ ID_MODEL_FROM_DATABASE=DECchip 21142/43 (DFE-500TX Fast Ethernet)
 
 pci:v00001011d00000019sv00001186sd00001112*
- ID_MODEL_FROM_DATABASE=DFE-570TX Quad Fast Ethernet
+ ID_MODEL_FROM_DATABASE=DECchip 21142/43 (DFE-570TX Quad Fast Ethernet)
+
+pci:v00001011d00000019sv000011F0sd00004235*
+ ID_MODEL_FROM_DATABASE=DECchip 21142/43 (21143 [FASTLine-II UTP 10/100])
 
 pci:v00001011d00000019sv00001259sd00002800*
- ID_MODEL_FROM_DATABASE=AT-2800Tx Fast Ethernet
+ ID_MODEL_FROM_DATABASE=DECchip 21142/43 (AT-2800Tx Fast Ethernet)
 
 pci:v00001011d00000019sv00001266sd00000004*
- ID_MODEL_FROM_DATABASE=Eagle Fast EtherMAX
+ ID_MODEL_FROM_DATABASE=DECchip 21142/43 (Eagle Fast EtherMAX)
 
 pci:v00001011d00000019sv000012AFsd00000019*
- ID_MODEL_FROM_DATABASE=NetFlyer Cardbus Fast Ethernet
+ ID_MODEL_FROM_DATABASE=DECchip 21142/43 (NetFlyer Cardbus Fast Ethernet)
 
 pci:v00001011d00000019sv00001374sd00000001*
- ID_MODEL_FROM_DATABASE=Cardbus Ethernet Card 10/100
+ ID_MODEL_FROM_DATABASE=DECchip 21142/43 (Cardbus Ethernet Card 10/100)
 
 pci:v00001011d00000019sv00001374sd00000002*
- ID_MODEL_FROM_DATABASE=Cardbus Ethernet Card 10/100
+ ID_MODEL_FROM_DATABASE=DECchip 21142/43 (Cardbus Ethernet Card 10/100)
 
 pci:v00001011d00000019sv00001374sd00000007*
- ID_MODEL_FROM_DATABASE=Cardbus Ethernet Card 10/100
+ ID_MODEL_FROM_DATABASE=DECchip 21142/43 (Cardbus Ethernet Card 10/100)
 
 pci:v00001011d00000019sv00001374sd00000008*
- ID_MODEL_FROM_DATABASE=Cardbus Ethernet Card 10/100
+ ID_MODEL_FROM_DATABASE=DECchip 21142/43 (Cardbus Ethernet Card 10/100)
 
 pci:v00001011d00000019sv00001385sd00002100*
- ID_MODEL_FROM_DATABASE=FA510
+ ID_MODEL_FROM_DATABASE=DECchip 21142/43 (FA510)
 
 pci:v00001011d00000019sv00001395sd00000001*
- ID_MODEL_FROM_DATABASE=10/100 Ethernet CardBus PC Card
+ ID_MODEL_FROM_DATABASE=DECchip 21142/43 (10/100 Ethernet CardBus PC Card)
 
 pci:v00001011d00000019sv000013D1sd0000AB01*
- ID_MODEL_FROM_DATABASE=EtherFast 10/100 Cardbus (PCMPC200)
+ ID_MODEL_FROM_DATABASE=DECchip 21142/43 (EtherFast 10/100 Cardbus (PCMPC200))
 
 pci:v00001011d00000019sv00001498sd0000000A*
- ID_MODEL_FROM_DATABASE=TPMC880-10 10/100Base-T and 10Base2 PMC Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=DECchip 21142/43 (TPMC880-10 10/100Base-T and 10Base2 PMC Ethernet Adapter)
 
 pci:v00001011d00000019sv00001498sd0000000B*
- ID_MODEL_FROM_DATABASE=TPMC880-11 Single 10/100Base-T PMC Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=DECchip 21142/43 (TPMC880-11 Single 10/100Base-T PMC Ethernet Adapter)
 
 pci:v00001011d00000019sv00001498sd0000000C*
- ID_MODEL_FROM_DATABASE=TPMC880-12 Single 10Base2 PMC Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=DECchip 21142/43 (TPMC880-12 Single 10Base2 PMC Ethernet Adapter)
 
 pci:v00001011d00000019sv000014CBsd00000100*
- ID_MODEL_FROM_DATABASE=LNDL-100N 100Base-TX Ethernet PC Card
+ ID_MODEL_FROM_DATABASE=DECchip 21142/43 (LNDL-100N 100Base-TX Ethernet PC Card)
 
 pci:v00001011d00000019sv00001668sd00002000*
- ID_MODEL_FROM_DATABASE=FastNet Pro (PE2000)
+ ID_MODEL_FROM_DATABASE=DECchip 21142/43 (FastNet Pro (PE2000))
 
 pci:v00001011d00000019sv00002646sd00000001*
- ID_MODEL_FROM_DATABASE=KNE100TX
+ ID_MODEL_FROM_DATABASE=DECchip 21142/43 (KNE100TX)
 
 pci:v00001011d00000019sv00002646sd00000002*
- ID_MODEL_FROM_DATABASE=KNE-CB4TX
+ ID_MODEL_FROM_DATABASE=DECchip 21142/43 (KNE-CB4TX)
 
 pci:v00001011d00000019sv00008086sd00000001*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 Mobile CardBus 32
+ ID_MODEL_FROM_DATABASE=DECchip 21142/43 (EtherExpress PRO/100 Mobile CardBus 32)
 
 pci:v00001011d0000001A*
  ID_MODEL_FROM_DATABASE=Farallon PN9000SX Gigabit Ethernet
@@ -9684,46 +9837,46 @@ pci:v00001011d00000046*
  ID_MODEL_FROM_DATABASE=DECchip 21554
 
 pci:v00001011d00000046sv00000E11sd00004050*
- ID_MODEL_FROM_DATABASE=Smart Array 4200 Controller
+ ID_MODEL_FROM_DATABASE=DECchip 21554 (Smart Array 4200 Controller)
 
 pci:v00001011d00000046sv00000E11sd00004051*
- ID_MODEL_FROM_DATABASE=Smart Array 4250ES Controller
+ ID_MODEL_FROM_DATABASE=DECchip 21554 (Smart Array 4250ES Controller)
 
 pci:v00001011d00000046sv00000E11sd00004058*
- ID_MODEL_FROM_DATABASE=Smart Array 431 Controller
+ ID_MODEL_FROM_DATABASE=DECchip 21554 (Smart Array 431 Controller)
 
 pci:v00001011d00000046sv0000103Csd000010C2*
- ID_MODEL_FROM_DATABASE=NetRAID-4M
+ ID_MODEL_FROM_DATABASE=DECchip 21554 (NetRAID-4M)
 
 pci:v00001011d00000046sv000012D9sd0000000A*
- ID_MODEL_FROM_DATABASE=IP Telephony card
+ ID_MODEL_FROM_DATABASE=DECchip 21554 (IP Telephony card)
 
 pci:v00001011d00000046sv00004C53sd00001050*
- ID_MODEL_FROM_DATABASE=CT7 mainboard
+ ID_MODEL_FROM_DATABASE=DECchip 21554 (CT7 mainboard)
 
 pci:v00001011d00000046sv00004C53sd00001051*
- ID_MODEL_FROM_DATABASE=CE7 mainboard
+ ID_MODEL_FROM_DATABASE=DECchip 21554 (CE7 mainboard)
 
 pci:v00001011d00000046sv00009005sd00000364*
- ID_MODEL_FROM_DATABASE=5400S (Mustang)
+ ID_MODEL_FROM_DATABASE=DECchip 21554 (5400S (Mustang))
 
 pci:v00001011d00000046sv00009005sd00000365*
- ID_MODEL_FROM_DATABASE=5400S (Mustang)
+ ID_MODEL_FROM_DATABASE=DECchip 21554 (5400S (Mustang))
 
 pci:v00001011d00000046sv00009005sd00001364*
- ID_MODEL_FROM_DATABASE=Dell PowerEdge RAID Controller 2
+ ID_MODEL_FROM_DATABASE=DECchip 21554 (Dell PowerEdge RAID Controller 2)
 
 pci:v00001011d00000046sv00009005sd00001365*
- ID_MODEL_FROM_DATABASE=Dell PowerEdge RAID Controller 2
+ ID_MODEL_FROM_DATABASE=DECchip 21554 (Dell PowerEdge RAID Controller 2)
 
 pci:v00001011d00000046sv0000E4BFsd00001000*
- ID_MODEL_FROM_DATABASE=CC8-1-BLUES
+ ID_MODEL_FROM_DATABASE=DECchip 21554 (CC8-1-BLUES)
 
 pci:v00001011d00001065*
  ID_MODEL_FROM_DATABASE=StrongARM DC21285
 
 pci:v00001011d00001065sv00001069sd00000020*
- ID_MODEL_FROM_DATABASE=DAC960P / DAC1164P
+ ID_MODEL_FROM_DATABASE=StrongARM DC21285 (DAC960P / DAC1164P)
 
 pci:v00001012*
  ID_VENDOR_FROM_DATABASE=Micronics Computers Inc
@@ -9761,11 +9914,14 @@ pci:v00001013d000000B0*
 pci:v00001013d000000B8*
  ID_MODEL_FROM_DATABASE=GD 5446
 
+pci:v00001013d000000B8sv00001AF4sd00001100*
+ ID_MODEL_FROM_DATABASE=GD 5446 (QEMU Virtual Machine)
+
 pci:v00001013d000000BC*
  ID_MODEL_FROM_DATABASE=GD 5480
 
 pci:v00001013d000000BCsv00001013sd000000BC*
- ID_MODEL_FROM_DATABASE=CL-GD5480
+ ID_MODEL_FROM_DATABASE=GD 5480 (CL-GD5480)
 
 pci:v00001013d000000D0*
  ID_MODEL_FROM_DATABASE=GD 5462
@@ -9783,10 +9939,10 @@ pci:v00001013d000000D6*
  ID_MODEL_FROM_DATABASE=GD 5465 [Laguna]
 
 pci:v00001013d000000D6sv000013CEsd00008031*
- ID_MODEL_FROM_DATABASE=Barco Metheus 2 Megapixel, Dual Head
+ ID_MODEL_FROM_DATABASE=GD 5465 [Laguna] (Barco Metheus 2 Megapixel, Dual Head)
 
 pci:v00001013d000000D6sv000013CFsd00008031*
- ID_MODEL_FROM_DATABASE=Barco Metheus 2 Megapixel, Dual Head
+ ID_MODEL_FROM_DATABASE=GD 5465 [Laguna] (Barco Metheus 2 Megapixel, Dual Head)
 
 pci:v00001013d000000E8*
  ID_MODEL_FROM_DATABASE=GD 5436U
@@ -9822,34 +9978,34 @@ pci:v00001013d00006001*
  ID_MODEL_FROM_DATABASE=CS 4610/11 [CrystalClear SoundFusion Audio Accelerator]
 
 pci:v00001013d00006001sv00001014sd00001010*
- ID_MODEL_FROM_DATABASE=CS4610 SoundFusion Audio Accelerator
+ ID_MODEL_FROM_DATABASE=CS 4610/11 [CrystalClear SoundFusion Audio Accelerator] (CS4610 SoundFusion Audio Accelerator)
 
 pci:v00001013d00006003*
  ID_MODEL_FROM_DATABASE=CS 4614/22/24/30 [CrystalClear SoundFusion Audio Accelerator]
 
 pci:v00001013d00006003sv00001013sd00004280*
- ID_MODEL_FROM_DATABASE=Crystal SoundFusion PCI Audio Accelerator
+ ID_MODEL_FROM_DATABASE=CS 4614/22/24/30 [CrystalClear SoundFusion Audio Accelerator] (Crystal SoundFusion PCI Audio Accelerator)
 
 pci:v00001013d00006003sv00001014sd00000153*
- ID_MODEL_FROM_DATABASE=ThinkPad 600X/A20m
+ ID_MODEL_FROM_DATABASE=CS 4614/22/24/30 [CrystalClear SoundFusion Audio Accelerator] (ThinkPad 600X/A20m)
 
 pci:v00001013d00006003sv0000153Bsd0000112E*
- ID_MODEL_FROM_DATABASE=DMX XFire 1024
+ ID_MODEL_FROM_DATABASE=CS 4614/22/24/30 [CrystalClear SoundFusion Audio Accelerator] (DMX XFire 1024)
 
 pci:v00001013d00006003sv0000153Bsd00001136*
- ID_MODEL_FROM_DATABASE=SiXPack 5.1+
+ ID_MODEL_FROM_DATABASE=CS 4614/22/24/30 [CrystalClear SoundFusion Audio Accelerator] (SiXPack 5.1+)
 
 pci:v00001013d00006003sv00001681sd00000050*
- ID_MODEL_FROM_DATABASE=Game Theater XP
+ ID_MODEL_FROM_DATABASE=CS 4614/22/24/30 [CrystalClear SoundFusion Audio Accelerator] (Game Theater XP)
 
 pci:v00001013d00006003sv00001681sd0000A010*
- ID_MODEL_FROM_DATABASE=Gamesurround Fortissimo II
+ ID_MODEL_FROM_DATABASE=CS 4614/22/24/30 [CrystalClear SoundFusion Audio Accelerator] (Gamesurround Fortissimo II)
 
 pci:v00001013d00006003sv00001681sd0000A011*
- ID_MODEL_FROM_DATABASE=Gamesurround Fortissimo III 7.1
+ ID_MODEL_FROM_DATABASE=CS 4614/22/24/30 [CrystalClear SoundFusion Audio Accelerator] (Gamesurround Fortissimo III 7.1)
 
 pci:v00001013d00006003sv00005053sd00003357*
- ID_MODEL_FROM_DATABASE=Santa Cruz
+ ID_MODEL_FROM_DATABASE=CS 4614/22/24/30 [CrystalClear SoundFusion Audio Accelerator] (Santa Cruz)
 
 pci:v00001013d00006004*
  ID_MODEL_FROM_DATABASE=CS 4614/22/24 [CrystalClear SoundFusion Audio Accelerator]
@@ -9930,16 +10086,16 @@ pci:v00001014d0000002E*
  ID_MODEL_FROM_DATABASE=SCSI RAID Adapter [ServeRAID]
 
 pci:v00001014d0000002Esv00001014sd0000002E*
- ID_MODEL_FROM_DATABASE=ServeRAID-3x
+ ID_MODEL_FROM_DATABASE=SCSI RAID Adapter [ServeRAID] (ServeRAID-3x)
 
 pci:v00001014d0000002Esv00001014sd0000022E*
- ID_MODEL_FROM_DATABASE=ServeRAID-4H
+ ID_MODEL_FROM_DATABASE=SCSI RAID Adapter [ServeRAID] (ServeRAID-4H)
 
 pci:v00001014d00000031*
  ID_MODEL_FROM_DATABASE=2 Port Serial Adapter
 
 pci:v00001014d00000031sv00001014sd00000031*
- ID_MODEL_FROM_DATABASE=2721 WAN IOA - 2 Port Sync Serial Adapter
+ ID_MODEL_FROM_DATABASE=2 Port Serial Adapter (2721 WAN IOA - 2 Port Sync Serial Adapter)
 
 pci:v00001014d00000036*
  ID_MODEL_FROM_DATABASE=PCI to 32-bit LocalBus Bridge [Miami]
@@ -9957,25 +10113,25 @@ pci:v00001014d0000003E*
  ID_MODEL_FROM_DATABASE=16/4 Token ring UTP/STP controller
 
 pci:v00001014d0000003Esv00001014sd0000003E*
- ID_MODEL_FROM_DATABASE=Token-Ring Adapter
+ ID_MODEL_FROM_DATABASE=16/4 Token ring UTP/STP controller (Token-Ring Adapter)
 
 pci:v00001014d0000003Esv00001014sd000000CD*
- ID_MODEL_FROM_DATABASE=Token-Ring Adapter + Wake-On-LAN
+ ID_MODEL_FROM_DATABASE=16/4 Token ring UTP/STP controller (Token-Ring Adapter + Wake-On-LAN)
 
 pci:v00001014d0000003Esv00001014sd000000CE*
- ID_MODEL_FROM_DATABASE=16/4 Token-Ring Adapter 2
+ ID_MODEL_FROM_DATABASE=16/4 Token ring UTP/STP controller (16/4 Token-Ring Adapter 2)
 
 pci:v00001014d0000003Esv00001014sd000000CF*
- ID_MODEL_FROM_DATABASE=16/4 Token-Ring Adapter Special
+ ID_MODEL_FROM_DATABASE=16/4 Token ring UTP/STP controller (16/4 Token-Ring Adapter Special)
 
 pci:v00001014d0000003Esv00001014sd000000E4*
- ID_MODEL_FROM_DATABASE=High-Speed 100/16/4 Token-Ring Adapter
+ ID_MODEL_FROM_DATABASE=16/4 Token ring UTP/STP controller (High-Speed 100/16/4 Token-Ring Adapter)
 
 pci:v00001014d0000003Esv00001014sd000000E5*
- ID_MODEL_FROM_DATABASE=16/4 Token-Ring Adapter 2 + Wake-On-LAN
+ ID_MODEL_FROM_DATABASE=16/4 Token ring UTP/STP controller (16/4 Token-Ring Adapter 2 + Wake-On-LAN)
 
 pci:v00001014d0000003Esv00001014sd0000016D*
- ID_MODEL_FROM_DATABASE=iSeries 2744 Card
+ ID_MODEL_FROM_DATABASE=16/4 Token ring UTP/STP controller (iSeries 2744 Card)
 
 pci:v00001014d00000045*
  ID_MODEL_FROM_DATABASE=SSA Adapter
@@ -10032,7 +10188,7 @@ pci:v00001014d00000090*
  ID_MODEL_FROM_DATABASE=GXT 3000P
 
 pci:v00001014d00000090sv00001014sd0000008E*
- ID_MODEL_FROM_DATABASE=GXT-3000P
+ ID_MODEL_FROM_DATABASE=GXT 3000P (GXT-3000P)
 
 pci:v00001014d00000091*
  ID_MODEL_FROM_DATABASE=SSA Adapter
@@ -10044,13 +10200,13 @@ pci:v00001014d00000096*
  ID_MODEL_FROM_DATABASE=Chukar chipset SCSI controller
 
 pci:v00001014d00000096sv00001014sd00000097*
- ID_MODEL_FROM_DATABASE=iSeries 2778 DASD IOA
+ ID_MODEL_FROM_DATABASE=Chukar chipset SCSI controller (iSeries 2778 DASD IOA)
 
 pci:v00001014d00000096sv00001014sd00000098*
- ID_MODEL_FROM_DATABASE=iSeries 2763 DASD IOA
+ ID_MODEL_FROM_DATABASE=Chukar chipset SCSI controller (iSeries 2763 DASD IOA)
 
 pci:v00001014d00000096sv00001014sd00000099*
- ID_MODEL_FROM_DATABASE=iSeries 2748 DASD IOA
+ ID_MODEL_FROM_DATABASE=Chukar chipset SCSI controller (iSeries 2748 DASD IOA)
 
 pci:v00001014d0000009F*
  ID_MODEL_FROM_DATABASE=PCI 4758 Cryptographic Accelerator
@@ -10065,7 +10221,7 @@ pci:v00001014d000000B7*
  ID_MODEL_FROM_DATABASE=256-bit Graphics Rasterizer [FireGL1]
 
 pci:v00001014d000000B7sv00001092sd000000B8*
- ID_MODEL_FROM_DATABASE=FireGL1 AGP 32Mb
+ ID_MODEL_FROM_DATABASE=256-bit Graphics Rasterizer [FireGL1] (FireGL1 AGP 32Mb)
 
 pci:v00001014d000000B8*
  ID_MODEL_FROM_DATABASE=GXT2000P Graphics Adapter
@@ -10089,13 +10245,13 @@ pci:v00001014d00000142*
  ID_MODEL_FROM_DATABASE=Yotta Video Compositor Input
 
 pci:v00001014d00000142sv00001014sd00000143*
- ID_MODEL_FROM_DATABASE=Yotta Input Controller (ytin)
+ ID_MODEL_FROM_DATABASE=Yotta Video Compositor Input (Yotta Input Controller (ytin))
 
 pci:v00001014d00000144*
  ID_MODEL_FROM_DATABASE=Yotta Video Compositor Output
 
 pci:v00001014d00000144sv00001014sd00000145*
- ID_MODEL_FROM_DATABASE=Yotta Output Controller (ytout)
+ ID_MODEL_FROM_DATABASE=Yotta Video Compositor Output (Yotta Output Controller (ytout))
 
 pci:v00001014d00000156*
  ID_MODEL_FROM_DATABASE=405GP PLB to PCI Bridge
@@ -10119,10 +10275,10 @@ pci:v00001014d00000180*
  ID_MODEL_FROM_DATABASE=Snipe chipset SCSI controller
 
 pci:v00001014d00000180sv00001014sd00000241*
- ID_MODEL_FROM_DATABASE=iSeries 2757 DASD IOA
+ ID_MODEL_FROM_DATABASE=Snipe chipset SCSI controller (iSeries 2757 DASD IOA)
 
 pci:v00001014d00000180sv00001014sd00000264*
- ID_MODEL_FROM_DATABASE=Quad Channel PCI-X U320 SCSI RAID Adapter (2780)
+ ID_MODEL_FROM_DATABASE=Snipe chipset SCSI controller (Quad Channel PCI-X U320 SCSI RAID Adapter (2780))
 
 pci:v00001014d00000188*
  ID_MODEL_FROM_DATABASE=EADS-X PCI-X to PCI-X Bridge
@@ -10134,28 +10290,28 @@ pci:v00001014d000001BD*
  ID_MODEL_FROM_DATABASE=ServeRAID Controller
 
 pci:v00001014d000001BDsv00001014sd000001BD*
- ID_MODEL_FROM_DATABASE=ServeRAID 4Lx
+ ID_MODEL_FROM_DATABASE=ServeRAID Controller (ServeRAID 4Lx)
 
 pci:v00001014d000001BDsv00001014sd000001BE*
- ID_MODEL_FROM_DATABASE=ServeRAID-4M
+ ID_MODEL_FROM_DATABASE=ServeRAID Controller (ServeRAID-4M)
 
 pci:v00001014d000001BDsv00001014sd000001BF*
- ID_MODEL_FROM_DATABASE=ServeRAID-4L
+ ID_MODEL_FROM_DATABASE=ServeRAID Controller (ServeRAID-4L)
 
 pci:v00001014d000001BDsv00001014sd00000208*
- ID_MODEL_FROM_DATABASE=ServeRAID-4Mx
+ ID_MODEL_FROM_DATABASE=ServeRAID Controller (ServeRAID-4Mx)
 
 pci:v00001014d000001BDsv00001014sd0000020E*
- ID_MODEL_FROM_DATABASE=ServeRAID-4Lx
+ ID_MODEL_FROM_DATABASE=ServeRAID Controller (ServeRAID-4Lx)
 
 pci:v00001014d000001BDsv00001014sd0000022E*
- ID_MODEL_FROM_DATABASE=ServeRAID-4H
+ ID_MODEL_FROM_DATABASE=ServeRAID Controller (ServeRAID-4H)
 
 pci:v00001014d000001BDsv00001014sd00000258*
- ID_MODEL_FROM_DATABASE=ServeRAID-5i
+ ID_MODEL_FROM_DATABASE=ServeRAID Controller (ServeRAID-5i)
 
 pci:v00001014d000001BDsv00001014sd00000259*
- ID_MODEL_FROM_DATABASE=ServeRAID-5i
+ ID_MODEL_FROM_DATABASE=ServeRAID Controller (ServeRAID-5i)
 
 pci:v00001014d000001C1*
  ID_MODEL_FROM_DATABASE=64bit/66MHz PCI ATM 155 UTP
@@ -10167,10 +10323,10 @@ pci:v00001014d000001EF*
  ID_MODEL_FROM_DATABASE=PowerPC 440GP PCI Bridge
 
 pci:v00001014d000001EFsv00001734sd0000102B*
- ID_MODEL_FROM_DATABASE=PCEAS PCI-X Dual Port ESCON Adapter
+ ID_MODEL_FROM_DATABASE=PowerPC 440GP PCI Bridge (PCEAS PCI-X Dual Port ESCON Adapter)
 
 pci:v00001014d000001EFsv00001734sd000010F8*
- ID_MODEL_FROM_DATABASE=PCEAT PCI-Express Dual Port ESCON Adapter
+ ID_MODEL_FROM_DATABASE=PowerPC 440GP PCI Bridge (PCEAT PCI-Express Dual Port ESCON Adapter)
 
 pci:v00001014d000001FF*
  ID_MODEL_FROM_DATABASE=10/100 Mbps Ethernet
@@ -10179,13 +10335,13 @@ pci:v00001014d00000219*
  ID_MODEL_FROM_DATABASE=Multiport Serial Adapter
 
 pci:v00001014d00000219sv00001014sd0000021A*
- ID_MODEL_FROM_DATABASE=Dual RVX
+ ID_MODEL_FROM_DATABASE=Multiport Serial Adapter (Dual RVX)
 
 pci:v00001014d00000219sv00001014sd00000251*
- ID_MODEL_FROM_DATABASE=Internal Modem/RVX
+ ID_MODEL_FROM_DATABASE=Multiport Serial Adapter (Internal Modem/RVX)
 
 pci:v00001014d00000219sv00001014sd00000252*
- ID_MODEL_FROM_DATABASE=Quad Internal Modem
+ ID_MODEL_FROM_DATABASE=Multiport Serial Adapter (Quad Internal Modem)
 
 pci:v00001014d0000021B*
  ID_MODEL_FROM_DATABASE=GXT6500P Graphics Adapter
@@ -10200,16 +10356,16 @@ pci:v00001014d0000028C*
  ID_MODEL_FROM_DATABASE=Citrine chipset SCSI controller
 
 pci:v00001014d0000028Csv00001014sd0000028D*
- ID_MODEL_FROM_DATABASE=Dual Channel PCI-X DDR SAS RAID Adapter (572E)
+ ID_MODEL_FROM_DATABASE=Citrine chipset SCSI controller (Dual Channel PCI-X DDR SAS RAID Adapter (572E))
 
 pci:v00001014d0000028Csv00001014sd000002BE*
- ID_MODEL_FROM_DATABASE=Dual Channel PCI-X DDR U320 SCSI RAID Adapter (571B)
+ ID_MODEL_FROM_DATABASE=Citrine chipset SCSI controller (Dual Channel PCI-X DDR U320 SCSI RAID Adapter (571B))
 
 pci:v00001014d0000028Csv00001014sd000002C0*
- ID_MODEL_FROM_DATABASE=Dual Channel PCI-X DDR U320 SCSI Adapter (571A)
+ ID_MODEL_FROM_DATABASE=Citrine chipset SCSI controller (Dual Channel PCI-X DDR U320 SCSI Adapter (571A))
 
 pci:v00001014d0000028Csv00001014sd0000030D*
- ID_MODEL_FROM_DATABASE=PCI-X DDR Auxiliary Cache Adapter (575B)
+ ID_MODEL_FROM_DATABASE=Citrine chipset SCSI controller (PCI-X DDR Auxiliary Cache Adapter (575B))
 
 pci:v00001014d000002A1*
  ID_MODEL_FROM_DATABASE=Calgary PCI-X Host Bridge
@@ -10218,13 +10374,13 @@ pci:v00001014d000002BD*
  ID_MODEL_FROM_DATABASE=Obsidian chipset SCSI controller
 
 pci:v00001014d000002BDsv00001014sd000002C1*
- ID_MODEL_FROM_DATABASE=PCI-X DDR 3Gb SAS Adapter (572A/572C)
+ ID_MODEL_FROM_DATABASE=Obsidian chipset SCSI controller (PCI-X DDR 3Gb SAS Adapter (572A/572C))
 
 pci:v00001014d000002BDsv00001014sd000002C2*
- ID_MODEL_FROM_DATABASE=PCI-X DDR 3Gb SAS RAID Adapter (572B/571D)
+ ID_MODEL_FROM_DATABASE=Obsidian chipset SCSI controller (PCI-X DDR 3Gb SAS RAID Adapter (572B/571D))
 
 pci:v00001014d000002BDsv00001014sd00000338*
- ID_MODEL_FROM_DATABASE=PCI-X DDR Auxiliary Cache Adapter (575C)
+ ID_MODEL_FROM_DATABASE=Obsidian chipset SCSI controller (PCI-X DDR Auxiliary Cache Adapter (575C))
 
 pci:v00001014d00000302*
  ID_MODEL_FROM_DATABASE=Winnipeg PCI-X Host Bridge
@@ -10239,79 +10395,91 @@ pci:v00001014d0000032D*
  ID_MODEL_FROM_DATABASE=Axon - Cell Companion Chip
 
 pci:v00001014d0000032Dsv00001014sd000003A1*
- ID_MODEL_FROM_DATABASE=PCIe PowerXCell 8i Cell Accelerator Board
+ ID_MODEL_FROM_DATABASE=Axon - Cell Companion Chip (PCIe PowerXCell 8i Cell Accelerator Board)
 
 pci:v00001014d00000339*
  ID_MODEL_FROM_DATABASE=Obsidian-E PCI-E SCSI controller
 
 pci:v00001014d00000339sv00001014sd0000030A*
- ID_MODEL_FROM_DATABASE=PCIe 3Gb SAS RAID Adapter (574E)
+ ID_MODEL_FROM_DATABASE=Obsidian-E PCI-E SCSI controller (PCIe 3Gb SAS RAID Adapter (574E))
 
 pci:v00001014d00000339sv00001014sd0000033A*
- ID_MODEL_FROM_DATABASE=PCIe 3Gb SAS Adapter (57B3)
+ ID_MODEL_FROM_DATABASE=Obsidian-E PCI-E SCSI controller (PCIe 3Gb SAS Adapter (57B3))
 
 pci:v00001014d00000339sv00001014sd0000035C*
- ID_MODEL_FROM_DATABASE=PCIe x8 Internal 3Gb SAS adapter (57CC)
+ ID_MODEL_FROM_DATABASE=Obsidian-E PCI-E SCSI controller (PCIe x8 Internal 3Gb SAS adapter (57CC))
 
 pci:v00001014d00000339sv00001014sd00000360*
- ID_MODEL_FROM_DATABASE=PCI-E Auxiliary Cache Adapter (57B7)
+ ID_MODEL_FROM_DATABASE=Obsidian-E PCI-E SCSI controller (PCI-E Auxiliary Cache Adapter (57B7))
 
 pci:v00001014d0000033D*
  ID_MODEL_FROM_DATABASE=PCI-E IPR SAS Adapter (FPGA)
 
 pci:v00001014d0000033Dsv00001014sd0000033C*
- ID_MODEL_FROM_DATABASE=PCIe2 1.8GB Cache 6Gb SAS RAID Adapter Tri-port (57B5)
+ ID_MODEL_FROM_DATABASE=PCI-E IPR SAS Adapter (FPGA) (PCIe2 1.8GB Cache 6Gb SAS RAID Adapter Tri-port (57B5))
 
 pci:v00001014d0000033Dsv00001014sd00000353*
- ID_MODEL_FROM_DATABASE=PCIe2 3.1GB Cache 6Gb SAS RAID Enclosure (57C3)
+ ID_MODEL_FROM_DATABASE=PCI-E IPR SAS Adapter (FPGA) (PCIe2 3.1GB Cache 6Gb SAS RAID Enclosure (57C3))
 
 pci:v00001014d0000033Dsv00001014sd00000354*
- ID_MODEL_FROM_DATABASE=PCIe2 6Gb SAS Adapter Dual-port (57C4)
+ ID_MODEL_FROM_DATABASE=PCI-E IPR SAS Adapter (FPGA) (PCIe2 6Gb SAS Adapter Dual-port (57C4))
 
 pci:v00001014d0000033Dsv00001014sd00000356*
- ID_MODEL_FROM_DATABASE=PCIe2 1.8GB Cache 6Gb SAS RAID & SSD Adapter (574D)
+ ID_MODEL_FROM_DATABASE=PCI-E IPR SAS Adapter (FPGA) (PCIe2 1.8GB Cache 6Gb SAS RAID & SSD Adapter (574D))
 
 pci:v00001014d0000033Dsv00001014sd0000035F*
- ID_MODEL_FROM_DATABASE=PCIe2 6Gb SAS Adapter Quad-port (57B2)
+ ID_MODEL_FROM_DATABASE=PCI-E IPR SAS Adapter (FPGA) (PCIe2 6Gb SAS Adapter Quad-port (57B2))
 
 pci:v00001014d0000034A*
  ID_MODEL_FROM_DATABASE=PCI-E IPR SAS Adapter (ASIC)
 
 pci:v00001014d0000034Asv00001014sd0000033B*
- ID_MODEL_FROM_DATABASE=PCIe2 6Gb SAS RAID Adapter Quad-port (57B4)
+ ID_MODEL_FROM_DATABASE=PCI-E IPR SAS Adapter (ASIC) (PCIe2 6Gb SAS RAID Adapter Quad-port (57B4))
 
 pci:v00001014d0000034Asv00001014sd00000355*
- ID_MODEL_FROM_DATABASE=PCIe2 3.6GB Cache 6Gb SAS RAID Adapter Quad-port (57B1)
+ ID_MODEL_FROM_DATABASE=PCI-E IPR SAS Adapter (ASIC) (PCIe2 3.6GB Cache 6Gb SAS RAID Adapter Quad-port (57B1))
 
 pci:v00001014d0000034Asv00001014sd00000357*
- ID_MODEL_FROM_DATABASE=PCIe2 6Gb SAS Adapter Quad-port (57C6)
+ ID_MODEL_FROM_DATABASE=PCI-E IPR SAS Adapter (ASIC) (PCIe2 6Gb SAS Adapter Quad-port (57C6))
 
 pci:v00001014d0000034Asv00001014sd0000035D*
- ID_MODEL_FROM_DATABASE=PCIe3 1.8GB Cache RAID SAS Adapter Quad-port 6GB (57C8)
+ ID_MODEL_FROM_DATABASE=PCI-E IPR SAS Adapter (ASIC) (PCIe3 1.8GB Cache RAID SAS Adapter Quad-port 6GB (57C8))
 
 pci:v00001014d0000034Asv00001014sd0000035E*
- ID_MODEL_FROM_DATABASE=PCIe2 3.6GB Cache 6Gb SAS RAID Adapter Quad-port (57CE)
+ ID_MODEL_FROM_DATABASE=PCI-E IPR SAS Adapter (ASIC) (PCIe2 3.6GB Cache 6Gb SAS RAID Adapter Quad-port (57CE))
 
 pci:v00001014d0000034Asv00001014sd000003FB*
- ID_MODEL_FROM_DATABASE=PCIe3 28GB Cache RAID SAS Enclosure 6Gb x 16 (57D5)
+ ID_MODEL_FROM_DATABASE=PCI-E IPR SAS Adapter (ASIC) (PCIe3 28GB Cache RAID SAS Enclosure 6Gb x 16 (57D5))
 
 pci:v00001014d0000034Asv00001014sd000003FE*
- ID_MODEL_FROM_DATABASE=PCIe3 x8 Cache SAS RAID Internal Adapter 6Gb (57D8)
+ ID_MODEL_FROM_DATABASE=PCI-E IPR SAS Adapter (ASIC) (PCIe3 x8 Cache SAS RAID Internal Adapter 6Gb (57D8))
 
 pci:v00001014d0000034Asv00001014sd000003FF*
- ID_MODEL_FROM_DATABASE=PCIe3 x8 SAS RAID Internal Adapter 6Gb (57D7)
+ ID_MODEL_FROM_DATABASE=PCI-E IPR SAS Adapter (ASIC) (PCIe3 x8 SAS RAID Internal Adapter 6Gb (57D7))
 
 pci:v00001014d0000034Asv00001014sd00000474*
- ID_MODEL_FROM_DATABASE=PCIe3 x16 Cache SAS RAID Internal Adapter 6Gb (57EB)
+ ID_MODEL_FROM_DATABASE=PCI-E IPR SAS Adapter (ASIC) (PCIe3 x16 Cache SAS RAID Internal Adapter 6Gb (57EB))
 
 pci:v00001014d0000034Asv00001014sd00000475*
- ID_MODEL_FROM_DATABASE=PCIe3 x16 SAS RAID Internal Adapter 6Gb (57EC)
+ ID_MODEL_FROM_DATABASE=PCI-E IPR SAS Adapter (ASIC) (PCIe3 x16 SAS RAID Internal Adapter 6Gb (57EC))
 
 pci:v00001014d0000034Asv00001014sd00000499*
- ID_MODEL_FROM_DATABASE=PCIe3 x16 Cache SAS RAID Internal Adapter 6Gb (57ED)
+ ID_MODEL_FROM_DATABASE=PCI-E IPR SAS Adapter (ASIC) (PCIe3 x16 Cache SAS RAID Internal Adapter 6Gb (57ED))
 
 pci:v00001014d0000034Asv00001014sd0000049A*
- ID_MODEL_FROM_DATABASE=PCIe3 x16 SAS RAID Internal Adapter 6Gb (57EE)
+ ID_MODEL_FROM_DATABASE=PCI-E IPR SAS Adapter (ASIC) (PCIe3 x16 SAS RAID Internal Adapter 6Gb (57EE))
+
+pci:v00001014d0000034Asv00001014sd000004C7*
+ ID_MODEL_FROM_DATABASE=PCI-E IPR SAS Adapter (ASIC) (PCIe3 x 8 Cache SAS RAID Internal Adapter 6GB(2CCA))
+
+pci:v00001014d0000034Asv00001014sd000004C8*
+ ID_MODEL_FROM_DATABASE=PCI-E IPR SAS Adapter (ASIC) (PCIe3 x 8 Cache SAS RAID Internal Adapter 6GB(2CD2))
+
+pci:v00001014d0000034Asv00001014sd00000C49*
+ ID_MODEL_FROM_DATABASE=PCI-E IPR SAS Adapter (ASIC) (PCIe3 x 8 Cache SAS RAID Internal Adapter 6GB(2CCD))
+
+pci:v00001014d0000044B*
+ ID_MODEL_FROM_DATABASE=GenWQE Accelerator Adapter
 
 pci:v00001014d000004AA*
  ID_MODEL_FROM_DATABASE=Flash Adapter 90 (PCIe2 0.9TB)
@@ -10353,13 +10521,13 @@ pci:v0000101Ad00000007*
  ID_MODEL_FROM_DATABASE=BYNET BIC4G/2C/2G
 
 pci:v0000101Ad00000007sv0000101Asd00000019*
- ID_MODEL_FROM_DATABASE=BYNET BIC2C
+ ID_MODEL_FROM_DATABASE=BYNET BIC4G/2C/2G (BYNET BIC2C)
 
 pci:v0000101Ad00000007sv0000101Asd0000001C*
- ID_MODEL_FROM_DATABASE=BYNET BIC2G
+ ID_MODEL_FROM_DATABASE=BYNET BIC4G/2C/2G (BYNET BIC2G)
 
 pci:v0000101Ad00000007sv0000101Asd0000001F*
- ID_MODEL_FROM_DATABASE=BYNET BIC4G
+ ID_MODEL_FROM_DATABASE=BYNET BIC4G/2C/2G (BYNET BIC4G)
 
 pci:v0000101Ad00000009*
  ID_MODEL_FROM_DATABASE=PQS Memory Controller
@@ -10380,19 +10548,19 @@ pci:v0000101Ad00001DC1*
  ID_MODEL_FROM_DATABASE=BYNET BIC2M/BIC4M/BYA4M
 
 pci:v0000101Ad00001DC1sv0000101Asd00000019*
- ID_MODEL_FROM_DATABASE=BIC2M
+ ID_MODEL_FROM_DATABASE=BYNET BIC2M/BIC4M/BYA4M (BIC2M)
 
 pci:v0000101Ad00001DC1sv0000101Asd0000001F*
- ID_MODEL_FROM_DATABASE=BIC4M
+ ID_MODEL_FROM_DATABASE=BYNET BIC2M/BIC4M/BYA4M (BIC4M)
 
 pci:v0000101Ad00001DC1sv0000101Asd00000ECE*
- ID_MODEL_FROM_DATABASE=BYA4M
+ ID_MODEL_FROM_DATABASE=BYNET BIC2M/BIC4M/BYA4M (BYA4M)
 
 pci:v0000101Ad00001FA8*
  ID_MODEL_FROM_DATABASE=BYNET Multi-port BIC Adapter (XBIC Based)
 
 pci:v0000101Ad00001FA8sv0000101Asd000000C3*
- ID_MODEL_FROM_DATABASE=BYNET BIC2SE
+ ID_MODEL_FROM_DATABASE=BYNET Multi-port BIC Adapter (XBIC Based) (BYNET BIC2SE)
 
 pci:v0000101B*
  ID_VENDOR_FROM_DATABASE=Vitesse Semiconductor
@@ -10449,43 +10617,46 @@ pci:v0000101Ed00001960*
  ID_MODEL_FROM_DATABASE=MegaRAID
 
 pci:v0000101Ed00001960sv0000101Esd00000471*
- ID_MODEL_FROM_DATABASE=MegaRAID 471 Enterprise 1600 RAID Controller
+ ID_MODEL_FROM_DATABASE=MegaRAID (471 Enterprise 1600 RAID Controller)
 
 pci:v0000101Ed00001960sv0000101Esd00000475*
- ID_MODEL_FROM_DATABASE=MegaRAID 475 Express 500/500LC RAID Controller
+ ID_MODEL_FROM_DATABASE=MegaRAID (475 Express 500/500LC RAID Controller)
 
 pci:v0000101Ed00001960sv0000101Esd00000477*
- ID_MODEL_FROM_DATABASE=MegaRAID 477 Elite 3100 RAID Controller
+ ID_MODEL_FROM_DATABASE=MegaRAID (477 Elite 3100 RAID Controller)
 
 pci:v0000101Ed00001960sv0000101Esd00000493*
- ID_MODEL_FROM_DATABASE=MegaRAID 493 Elite 1600 RAID Controller
+ ID_MODEL_FROM_DATABASE=MegaRAID (493 Elite 1600 RAID Controller)
 
 pci:v0000101Ed00001960sv0000101Esd00000494*
- ID_MODEL_FROM_DATABASE=MegaRAID 494 Elite 1650 RAID Controller
+ ID_MODEL_FROM_DATABASE=MegaRAID (494 Elite 1650 RAID Controller)
 
 pci:v0000101Ed00001960sv0000101Esd00000503*
- ID_MODEL_FROM_DATABASE=MegaRAID 503 Enterprise 1650 RAID Controller
+ ID_MODEL_FROM_DATABASE=MegaRAID (503 Enterprise 1650 RAID Controller)
 
 pci:v0000101Ed00001960sv0000101Esd00000511*
- ID_MODEL_FROM_DATABASE=MegaRAID 511 i4 IDE RAID Controller
+ ID_MODEL_FROM_DATABASE=MegaRAID (511 i4 IDE RAID Controller)
 
 pci:v0000101Ed00001960sv0000101Esd00000522*
- ID_MODEL_FROM_DATABASE=MegaRAID 522 i4133 RAID Controller
+ ID_MODEL_FROM_DATABASE=MegaRAID (522 i4133 RAID Controller)
 
 pci:v0000101Ed00001960sv00001028sd00000471*
- ID_MODEL_FROM_DATABASE=PowerEdge RAID Controller 3/QC
+ ID_MODEL_FROM_DATABASE=MegaRAID (PowerEdge RAID Controller 3/QC)
 
 pci:v0000101Ed00001960sv00001028sd00000475*
- ID_MODEL_FROM_DATABASE=PowerEdge RAID Controller 3/SC
+ ID_MODEL_FROM_DATABASE=MegaRAID (PowerEdge RAID Controller 3/SC)
 
 pci:v0000101Ed00001960sv00001028sd00000493*
- ID_MODEL_FROM_DATABASE=PowerEdge RAID Controller 3/DC
+ ID_MODEL_FROM_DATABASE=MegaRAID (PowerEdge RAID Controller 3/DC)
 
 pci:v0000101Ed00001960sv00001028sd00000511*
- ID_MODEL_FROM_DATABASE=PowerEdge Cost Effective RAID Controller ATA100/4Ch
+ ID_MODEL_FROM_DATABASE=MegaRAID (PowerEdge Cost Effective RAID Controller ATA100/4Ch)
 
 pci:v0000101Ed00001960sv0000103Csd000060E7*
- ID_MODEL_FROM_DATABASE=NetRAID-1M
+ ID_MODEL_FROM_DATABASE=MegaRAID (NetRAID-1M)
+
+pci:v0000101Ed00001960sv0000103Csd000060E8*
+ ID_MODEL_FROM_DATABASE=MegaRAID (NetRaid 2M [AMI MegaRaid 493])
 
 pci:v0000101Ed00009010*
  ID_MODEL_FROM_DATABASE=MegaRAID 428 Ultra RAID Controller
@@ -10512,7 +10683,7 @@ pci:v0000101Ed00009063*
  ID_MODEL_FROM_DATABASE=MegaRAC
 
 pci:v0000101Ed00009063sv0000101Esd00000767*
- ID_MODEL_FROM_DATABASE=Dell Remote Assistant Card 2
+ ID_MODEL_FROM_DATABASE=MegaRAC (Dell Remote Assistant Card 2)
 
 pci:v0000101F*
  ID_VENDOR_FROM_DATABASE=PictureTel
@@ -10613,6 +10784,33 @@ pci:v00001022d00001418*
 pci:v00001022d00001419*
  ID_MODEL_FROM_DATABASE=Family 15h (Models 10h-1fh) I/O Memory Management Unit
 
+pci:v00001022d0000141A*
+ ID_MODEL_FROM_DATABASE=Family 15h (Models 30h-3fh) Processor Function 0
+
+pci:v00001022d0000141B*
+ ID_MODEL_FROM_DATABASE=Family 15h (Models 30h-3fh) Processor Function 1
+
+pci:v00001022d0000141C*
+ ID_MODEL_FROM_DATABASE=Family 15h (Models 30h-3fh) Processor Function 2
+
+pci:v00001022d0000141D*
+ ID_MODEL_FROM_DATABASE=Family 15h (Models 30h-3fh) Processor Function 3
+
+pci:v00001022d0000141E*
+ ID_MODEL_FROM_DATABASE=Family 15h (Models 30h-3fh) Processor Function 4
+
+pci:v00001022d0000141F*
+ ID_MODEL_FROM_DATABASE=Family 15h (Models 30h-3fh) Processor Function 5
+
+pci:v00001022d00001422*
+ ID_MODEL_FROM_DATABASE=Family 15h (Models 30h-3fh) Processor Root Complex
+
+pci:v00001022d00001423*
+ ID_MODEL_FROM_DATABASE=Family 15h (Models 30h-3fh) I/O Memory Management Unit
+
+pci:v00001022d00001426*
+ ID_MODEL_FROM_DATABASE=Family 15h (Models 30h-3fh) Processor Root Port
+
 pci:v00001022d00001439*
  ID_MODEL_FROM_DATABASE=Family 16h Processor Functions 5:1
 
@@ -10620,7 +10818,7 @@ pci:v00001022d00001510*
  ID_MODEL_FROM_DATABASE=Family 14h Processor Root Complex
 
 pci:v00001022d00001510sv0000174Bsd00001001*
- ID_MODEL_FROM_DATABASE=PURE Fusion Mini
+ ID_MODEL_FROM_DATABASE=Family 14h Processor Root Complex (PURE Fusion Mini)
 
 pci:v00001022d00001512*
  ID_MODEL_FROM_DATABASE=Family 14h Processor Root Port
@@ -10731,79 +10929,79 @@ pci:v00001022d00002000*
  ID_MODEL_FROM_DATABASE=79c970 [PCnet32 LANCE]
 
 pci:v00001022d00002000sv00001014sd00002000*
- ID_MODEL_FROM_DATABASE=NetFinity 10/100 Fast Ethernet
+ ID_MODEL_FROM_DATABASE=79c970 [PCnet32 LANCE] (NetFinity 10/100 Fast Ethernet)
 
 pci:v00001022d00002000sv00001022sd00002000*
- ID_MODEL_FROM_DATABASE=PCnet - Fast 79C971
+ ID_MODEL_FROM_DATABASE=79c970 [PCnet32 LANCE] (PCnet - Fast 79C971)
 
 pci:v00001022d00002000sv0000103Csd0000104C*
- ID_MODEL_FROM_DATABASE=Ethernet with LAN remote power Adapter
+ ID_MODEL_FROM_DATABASE=79c970 [PCnet32 LANCE] (Ethernet with LAN remote power Adapter)
 
 pci:v00001022d00002000sv0000103Csd00001064*
- ID_MODEL_FROM_DATABASE=Ethernet with LAN remote power Adapter
+ ID_MODEL_FROM_DATABASE=79c970 [PCnet32 LANCE] (Ethernet with LAN remote power Adapter)
 
 pci:v00001022d00002000sv0000103Csd00001065*
- ID_MODEL_FROM_DATABASE=Ethernet with LAN remote power Adapter
+ ID_MODEL_FROM_DATABASE=79c970 [PCnet32 LANCE] (Ethernet with LAN remote power Adapter)
 
 pci:v00001022d00002000sv0000103Csd0000106C*
- ID_MODEL_FROM_DATABASE=Ethernet with LAN remote power Adapter
+ ID_MODEL_FROM_DATABASE=79c970 [PCnet32 LANCE] (Ethernet with LAN remote power Adapter)
 
 pci:v00001022d00002000sv0000103Csd0000106E*
- ID_MODEL_FROM_DATABASE=Ethernet with LAN remote power Adapter
+ ID_MODEL_FROM_DATABASE=79c970 [PCnet32 LANCE] (Ethernet with LAN remote power Adapter)
 
 pci:v00001022d00002000sv0000103Csd000010EA*
- ID_MODEL_FROM_DATABASE=Ethernet with LAN remote power Adapter
+ ID_MODEL_FROM_DATABASE=79c970 [PCnet32 LANCE] (Ethernet with LAN remote power Adapter)
 
 pci:v00001022d00002000sv00001113sd00001220*
- ID_MODEL_FROM_DATABASE=EN1220 10/100 Fast Ethernet
+ ID_MODEL_FROM_DATABASE=79c970 [PCnet32 LANCE] (EN1220 10/100 Fast Ethernet)
 
 pci:v00001022d00002000sv00001259sd00002450*
- ID_MODEL_FROM_DATABASE=AT-2450 10/100 Fast Ethernet
+ ID_MODEL_FROM_DATABASE=79c970 [PCnet32 LANCE] (AT-2450 10/100 Fast Ethernet)
 
 pci:v00001022d00002000sv00001259sd00002454*
- ID_MODEL_FROM_DATABASE=AT-2450v4 10Mb Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=79c970 [PCnet32 LANCE] (AT-2450v4 10Mb Ethernet Adapter)
 
 pci:v00001022d00002000sv00001259sd00002700*
- ID_MODEL_FROM_DATABASE=AT-2700TX 10/100 Fast Ethernet
+ ID_MODEL_FROM_DATABASE=79c970 [PCnet32 LANCE] (AT-2700TX 10/100 Fast Ethernet)
 
 pci:v00001022d00002000sv00001259sd00002701*
- ID_MODEL_FROM_DATABASE=AT-2700FX 100Mb Ethernet
+ ID_MODEL_FROM_DATABASE=79c970 [PCnet32 LANCE] (AT-2700FX 100Mb Ethernet)
 
 pci:v00001022d00002000sv00001259sd00002702*
- ID_MODEL_FROM_DATABASE=AT-2700FTX 10/100 Mb Fiber/Copper Fast Ethernet
+ ID_MODEL_FROM_DATABASE=79c970 [PCnet32 LANCE] (AT-2700FTX 10/100 Mb Fiber/Copper Fast Ethernet)
 
 pci:v00001022d00002000sv00001259sd00002703*
- ID_MODEL_FROM_DATABASE=AT-2701FX
+ ID_MODEL_FROM_DATABASE=79c970 [PCnet32 LANCE] (AT-2701FX)
 
 pci:v00001022d00002000sv00001259sd00002704*
- ID_MODEL_FROM_DATABASE=AT-2701FTX 10/100 Mb Fiber/Copper Fast Ethernet
+ ID_MODEL_FROM_DATABASE=79c970 [PCnet32 LANCE] (AT-2701FTX 10/100 Mb Fiber/Copper Fast Ethernet)
 
 pci:v00001022d00002000sv00004C53sd00001000*
- ID_MODEL_FROM_DATABASE=CC7/CR7/CP7/VC7/VP7/VR7 mainboard
+ ID_MODEL_FROM_DATABASE=79c970 [PCnet32 LANCE] (CC7/CR7/CP7/VC7/VP7/VR7 mainboard)
 
 pci:v00001022d00002000sv00004C53sd00001010*
- ID_MODEL_FROM_DATABASE=CP5/CR6 mainboard
+ ID_MODEL_FROM_DATABASE=79c970 [PCnet32 LANCE] (CP5/CR6 mainboard)
 
 pci:v00001022d00002000sv00004C53sd00001020*
- ID_MODEL_FROM_DATABASE=VR6 mainboard
+ ID_MODEL_FROM_DATABASE=79c970 [PCnet32 LANCE] (VR6 mainboard)
 
 pci:v00001022d00002000sv00004C53sd00001030*
- ID_MODEL_FROM_DATABASE=PC5 mainboard
+ ID_MODEL_FROM_DATABASE=79c970 [PCnet32 LANCE] (PC5 mainboard)
 
 pci:v00001022d00002000sv00004C53sd00001040*
- ID_MODEL_FROM_DATABASE=CL7 mainboard
+ ID_MODEL_FROM_DATABASE=79c970 [PCnet32 LANCE] (CL7 mainboard)
 
 pci:v00001022d00002000sv00004C53sd00001060*
- ID_MODEL_FROM_DATABASE=PC7 mainboard
+ ID_MODEL_FROM_DATABASE=79c970 [PCnet32 LANCE] (PC7 mainboard)
 
 pci:v00001022d00002001*
  ID_MODEL_FROM_DATABASE=79c978 [HomePNA]
 
 pci:v00001022d00002001sv00001092sd00000A78*
- ID_MODEL_FROM_DATABASE=Multimedia Home Network Adapter
+ ID_MODEL_FROM_DATABASE=79c978 [HomePNA] (Multimedia Home Network Adapter)
 
 pci:v00001022d00002001sv00001668sd00000299*
- ID_MODEL_FROM_DATABASE=ActionLink Home Network Adapter
+ ID_MODEL_FROM_DATABASE=79c978 [HomePNA] (ActionLink Home Network Adapter)
 
 pci:v00001022d00002003*
  ID_MODEL_FROM_DATABASE=Am 1771 MBW [Alchemy]
@@ -10811,6 +11009,9 @@ pci:v00001022d00002003*
 pci:v00001022d00002020*
  ID_MODEL_FROM_DATABASE=53c974 [PCscsi]
 
+pci:v00001022d00002020sv00001AF4sd00001100*
+ ID_MODEL_FROM_DATABASE=53c974 [PCscsi] (QEMU Virtual Machine)
+
 pci:v00001022d00002040*
  ID_MODEL_FROM_DATABASE=79c974
 
@@ -10929,7 +11130,7 @@ pci:v00001022d00007440*
  ID_MODEL_FROM_DATABASE=AMD-768 [Opus] ISA
 
 pci:v00001022d00007440sv00001043sd00008044*
- ID_MODEL_FROM_DATABASE=A7M-D Mainboard
+ ID_MODEL_FROM_DATABASE=AMD-768 [Opus] ISA (A7M-D Mainboard)
 
 pci:v00001022d00007441*
  ID_MODEL_FROM_DATABASE=AMD-768 [Opus] IDE
@@ -10938,7 +11139,7 @@ pci:v00001022d00007443*
  ID_MODEL_FROM_DATABASE=AMD-768 [Opus] ACPI
 
 pci:v00001022d00007443sv00001043sd00008044*
- ID_MODEL_FROM_DATABASE=A7M-D Mainboard
+ ID_MODEL_FROM_DATABASE=AMD-768 [Opus] ACPI (A7M-D Mainboard)
 
 pci:v00001022d00007445*
  ID_MODEL_FROM_DATABASE=AMD-768 [Opus] Audio
@@ -10974,7 +11175,7 @@ pci:v00001022d00007460*
  ID_MODEL_FROM_DATABASE=AMD-8111 PCI
 
 pci:v00001022d00007460sv0000161Fsd00003017*
- ID_MODEL_FROM_DATABASE=HDAMB
+ ID_MODEL_FROM_DATABASE=AMD-8111 PCI (HDAMB)
 
 pci:v00001022d00007461*
  ID_MODEL_FROM_DATABASE=AMD-8111 USB
@@ -10989,22 +11190,22 @@ pci:v00001022d00007464*
  ID_MODEL_FROM_DATABASE=AMD-8111 USB OHCI
 
 pci:v00001022d00007464sv0000161Fsd00003017*
- ID_MODEL_FROM_DATABASE=HDAMB
+ ID_MODEL_FROM_DATABASE=AMD-8111 USB OHCI (HDAMB)
 
 pci:v00001022d00007468*
  ID_MODEL_FROM_DATABASE=AMD-8111 LPC
 
 pci:v00001022d00007468sv0000161Fsd00003017*
- ID_MODEL_FROM_DATABASE=HDAMB
+ ID_MODEL_FROM_DATABASE=AMD-8111 LPC (HDAMB)
 
 pci:v00001022d00007469*
  ID_MODEL_FROM_DATABASE=AMD-8111 IDE
 
 pci:v00001022d00007469sv00001022sd00002B80*
- ID_MODEL_FROM_DATABASE=AMD-8111 IDE [Quartet]
+ ID_MODEL_FROM_DATABASE=AMD-8111 IDE ([Quartet])
 
 pci:v00001022d00007469sv0000161Fsd00003017*
- ID_MODEL_FROM_DATABASE=HDAMB
+ ID_MODEL_FROM_DATABASE=AMD-8111 IDE (HDAMB)
 
 pci:v00001022d0000746A*
  ID_MODEL_FROM_DATABASE=AMD-8111 SMBus 2.0
@@ -11013,13 +11214,13 @@ pci:v00001022d0000746B*
  ID_MODEL_FROM_DATABASE=AMD-8111 ACPI
 
 pci:v00001022d0000746Bsv0000161Fsd00003017*
- ID_MODEL_FROM_DATABASE=HDAMB
+ ID_MODEL_FROM_DATABASE=AMD-8111 ACPI (HDAMB)
 
 pci:v00001022d0000746D*
  ID_MODEL_FROM_DATABASE=AMD-8111 AC97 Audio
 
 pci:v00001022d0000746Dsv0000161Fsd00003017*
- ID_MODEL_FROM_DATABASE=HDAMB
+ ID_MODEL_FROM_DATABASE=AMD-8111 AC97 Audio (HDAMB)
 
 pci:v00001022d0000746E*
  ID_MODEL_FROM_DATABASE=AMD-8111 MC97 Modem
@@ -11034,10 +11235,10 @@ pci:v00001022d00007801*
  ID_MODEL_FROM_DATABASE=FCH SATA Controller [AHCI mode]
 
 pci:v00001022d00007801sv0000103Csd0000168B*
- ID_MODEL_FROM_DATABASE=ProBook 4535s Notebook
+ ID_MODEL_FROM_DATABASE=FCH SATA Controller [AHCI mode] (ProBook 4535s Notebook)
 
 pci:v00001022d00007801sv0000103Csd0000194E*
- ID_MODEL_FROM_DATABASE=ProBook 455 G1 Notebook
+ ID_MODEL_FROM_DATABASE=FCH SATA Controller [AHCI mode] (ProBook 455 G1 Notebook)
 
 pci:v00001022d00007802*
  ID_MODEL_FROM_DATABASE=FCH SATA Controller [RAID mode]
@@ -11058,25 +11259,25 @@ pci:v00001022d00007807*
  ID_MODEL_FROM_DATABASE=FCH USB OHCI Controller
 
 pci:v00001022d00007807sv0000103Csd0000194E*
- ID_MODEL_FROM_DATABASE=ProBook 455 G1 Notebook
+ ID_MODEL_FROM_DATABASE=FCH USB OHCI Controller (ProBook 455 G1 Notebook)
 
 pci:v00001022d00007808*
  ID_MODEL_FROM_DATABASE=FCH USB EHCI Controller
 
 pci:v00001022d00007808sv0000103Csd0000194E*
- ID_MODEL_FROM_DATABASE=ProBook 455 G1 Notebook
+ ID_MODEL_FROM_DATABASE=FCH USB EHCI Controller (ProBook 455 G1 Notebook)
 
 pci:v00001022d00007809*
  ID_MODEL_FROM_DATABASE=FCH USB OHCI Controller
 
 pci:v00001022d00007809sv0000103Csd0000194E*
- ID_MODEL_FROM_DATABASE=ProBook 455 G1 Notebook
+ ID_MODEL_FROM_DATABASE=FCH USB OHCI Controller (ProBook 455 G1 Notebook)
 
 pci:v00001022d0000780B*
  ID_MODEL_FROM_DATABASE=FCH SMBus Controller
 
 pci:v00001022d0000780Bsv0000103Csd0000194E*
- ID_MODEL_FROM_DATABASE=ProBook 455 G1 Notebook
+ ID_MODEL_FROM_DATABASE=FCH SMBus Controller (ProBook 455 G1 Notebook)
 
 pci:v00001022d0000780C*
  ID_MODEL_FROM_DATABASE=FCH IDE Controller
@@ -11085,16 +11286,16 @@ pci:v00001022d0000780D*
  ID_MODEL_FROM_DATABASE=FCH Azalia Controller
 
 pci:v00001022d0000780Dsv0000103Csd0000194E*
- ID_MODEL_FROM_DATABASE=ProBook 455 G1 Notebook
+ ID_MODEL_FROM_DATABASE=FCH Azalia Controller (ProBook 455 G1 Notebook)
 
 pci:v00001022d0000780Dsv00001043sd00008444*
- ID_MODEL_FROM_DATABASE=F2A85-M Series
+ ID_MODEL_FROM_DATABASE=FCH Azalia Controller (F2A85-M Series)
 
 pci:v00001022d0000780E*
  ID_MODEL_FROM_DATABASE=FCH LPC Bridge
 
 pci:v00001022d0000780Esv0000103Csd0000194E*
- ID_MODEL_FROM_DATABASE=ProBook 455 G1 Notebook
+ ID_MODEL_FROM_DATABASE=FCH LPC Bridge (ProBook 455 G1 Notebook)
 
 pci:v00001022d0000780F*
  ID_MODEL_FROM_DATABASE=FCH PCI Bridge
@@ -11109,7 +11310,7 @@ pci:v00001022d00007814*
  ID_MODEL_FROM_DATABASE=FCH USB XHCI Controller
 
 pci:v00001022d00007814sv0000103Csd0000194E*
- ID_MODEL_FROM_DATABASE=ProBook 455 G1 Notebook
+ ID_MODEL_FROM_DATABASE=FCH USB XHCI Controller (ProBook 455 G1 Notebook)
 
 pci:v00001022d00007900*
  ID_MODEL_FROM_DATABASE=FCH SATA Controller [IDE mode]
@@ -11148,16 +11349,16 @@ pci:v00001022d00009600*
  ID_MODEL_FROM_DATABASE=RS780 Host Bridge
 
 pci:v00001022d00009600sv00001043sd000082F1*
- ID_MODEL_FROM_DATABASE=M3A78-EH Motherboard
+ ID_MODEL_FROM_DATABASE=RS780 Host Bridge (M3A78-EH Motherboard)
 
 pci:v00001022d00009601*
  ID_MODEL_FROM_DATABASE=RS880 Host Bridge
 
 pci:v00001022d00009601sv00001019sd00002120*
- ID_MODEL_FROM_DATABASE=A785GM-M
+ ID_MODEL_FROM_DATABASE=RS880 Host Bridge (A785GM-M)
 
 pci:v00001022d00009601sv00001043sd0000843E*
- ID_MODEL_FROM_DATABASE=M5A88-V EVO
+ ID_MODEL_FROM_DATABASE=RS880 Host Bridge (M5A88-V EVO)
 
 pci:v00001022d00009602*
  ID_MODEL_FROM_DATABASE=RS780/RS880 PCI to PCI bridge (int gfx)
@@ -11202,7 +11403,7 @@ pci:v00001023d00002001*
  ID_MODEL_FROM_DATABASE=4DWave NX
 
 pci:v00001023d00002001sv0000122Dsd00001400*
- ID_MODEL_FROM_DATABASE=Trident PCI288-Q3DII (NX)
+ ID_MODEL_FROM_DATABASE=4DWave NX (Trident PCI288-Q3DII (NX))
 
 pci:v00001023d00002100*
  ID_MODEL_FROM_DATABASE=CyberBlade XP4m32
@@ -11214,13 +11415,13 @@ pci:v00001023d00008400*
  ID_MODEL_FROM_DATABASE=CyberBlade/i7
 
 pci:v00001023d00008400sv00001023sd00008400*
- ID_MODEL_FROM_DATABASE=CyberBlade i7 AGP
+ ID_MODEL_FROM_DATABASE=CyberBlade/i7 (CyberBlade i7 AGP)
 
 pci:v00001023d00008420*
  ID_MODEL_FROM_DATABASE=CyberBlade/i7d
 
 pci:v00001023d00008420sv00000E11sd0000B15A*
- ID_MODEL_FROM_DATABASE=CyberBlade i7 AGP
+ ID_MODEL_FROM_DATABASE=CyberBlade/i7d (CyberBlade i7 AGP)
 
 pci:v00001023d00008500*
  ID_MODEL_FROM_DATABASE=CyberBlade/i1
@@ -11229,19 +11430,19 @@ pci:v00001023d00008520*
  ID_MODEL_FROM_DATABASE=CyberBlade i1
 
 pci:v00001023d00008520sv00000E11sd0000B16E*
- ID_MODEL_FROM_DATABASE=CyberBlade i1 AGP
+ ID_MODEL_FROM_DATABASE=CyberBlade i1 (AGP)
 
 pci:v00001023d00008520sv00001023sd00008520*
- ID_MODEL_FROM_DATABASE=CyberBlade i1 AGP
+ ID_MODEL_FROM_DATABASE=CyberBlade i1 (AGP)
 
 pci:v00001023d00008620*
  ID_MODEL_FROM_DATABASE=CyberBlade/i1
 
 pci:v00001023d00008620sv00001014sd00000502*
- ID_MODEL_FROM_DATABASE=ThinkPad R30/T30
+ ID_MODEL_FROM_DATABASE=CyberBlade/i1 (ThinkPad R30/T30)
 
 pci:v00001023d00008620sv00001014sd00001025*
- ID_MODEL_FROM_DATABASE=Travelmate 352TE
+ ID_MODEL_FROM_DATABASE=CyberBlade/i1 (Travelmate 352TE)
 
 pci:v00001023d00008820*
  ID_MODEL_FROM_DATABASE=CyberBlade XPAi1
@@ -11346,7 +11547,7 @@ pci:v00001023d00009880*
  ID_MODEL_FROM_DATABASE=Blade 3D PCI/AGP
 
 pci:v00001023d00009880sv00001023sd00009880*
- ID_MODEL_FROM_DATABASE=Blade 3D
+ ID_MODEL_FROM_DATABASE=Blade 3D PCI/AGP (Blade 3D)
 
 pci:v00001023d00009910*
  ID_MODEL_FROM_DATABASE=CyberBlade/XP
@@ -11409,7 +11610,7 @@ pci:v00001025d00001533*
  ID_MODEL_FROM_DATABASE=M1533 PCI-to-ISA Bridge
 
 pci:v00001025d00001533sv000010B9sd00001533*
- ID_MODEL_FROM_DATABASE=ALI M1533 Aladdin IV/V ISA South Bridge
+ ID_MODEL_FROM_DATABASE=M1533 PCI-to-ISA Bridge (ALI M1533 Aladdin IV/V ISA South Bridge)
 
 pci:v00001025d00001535*
  ID_MODEL_FROM_DATABASE=M1535 PCI Bridge + Super I/O + FIR
@@ -11418,7 +11619,7 @@ pci:v00001025d00001541*
  ID_MODEL_FROM_DATABASE=M1541 Northbridge [Aladdin V]
 
 pci:v00001025d00001541sv000010B9sd00001541*
- ID_MODEL_FROM_DATABASE=ALI M1541 Aladdin V/V+ AGP+PCI North Bridge
+ ID_MODEL_FROM_DATABASE=M1541 Northbridge [Aladdin V] (ALI M1541 Aladdin V/V+ AGP+PCI North Bridge)
 
 pci:v00001025d00001542*
  ID_MODEL_FROM_DATABASE=M1542 Northbridge [Aladdin V]
@@ -11544,31 +11745,31 @@ pci:v00001028d00000001*
  ID_MODEL_FROM_DATABASE=PowerEdge Expandable RAID Controller 2/Si
 
 pci:v00001028d00000001sv00001028sd00000001*
- ID_MODEL_FROM_DATABASE=PowerEdge 2400
+ ID_MODEL_FROM_DATABASE=PowerEdge Expandable RAID Controller 2/Si (PowerEdge 2400)
 
 pci:v00001028d00000002*
  ID_MODEL_FROM_DATABASE=PowerEdge Expandable RAID Controller 3/Di
 
 pci:v00001028d00000002sv00001028sd00000002*
- ID_MODEL_FROM_DATABASE=PowerEdge 4400
+ ID_MODEL_FROM_DATABASE=PowerEdge Expandable RAID Controller 3/Di (PowerEdge 4400)
 
 pci:v00001028d00000002sv00001028sd000000D1*
- ID_MODEL_FROM_DATABASE=PERC 3/DiV [Viper]
+ ID_MODEL_FROM_DATABASE=PowerEdge Expandable RAID Controller 3/Di (PERC 3/DiV [Viper])
 
 pci:v00001028d00000002sv00001028sd000000D9*
- ID_MODEL_FROM_DATABASE=PERC 3/DiL [Lexus]
+ ID_MODEL_FROM_DATABASE=PowerEdge Expandable RAID Controller 3/Di (PERC 3/DiL [Lexus])
 
 pci:v00001028d00000003*
  ID_MODEL_FROM_DATABASE=PowerEdge Expandable RAID Controller 3/Si
 
 pci:v00001028d00000003sv00001028sd00000003*
- ID_MODEL_FROM_DATABASE=PowerEdge 2450
+ ID_MODEL_FROM_DATABASE=PowerEdge Expandable RAID Controller 3/Si (PowerEdge 2450)
 
 pci:v00001028d00000004*
  ID_MODEL_FROM_DATABASE=PowerEdge Expandable RAID Controller 3/Di [Iguana]
 
 pci:v00001028d00000004sv00001028sd00000004*
- ID_MODEL_FROM_DATABASE=PERC 3/DiF [Iguana]
+ ID_MODEL_FROM_DATABASE=PowerEdge Expandable RAID Controller 3/Di [Iguana] (PERC 3/DiF [Iguana])
 
 pci:v00001028d00000006*
  ID_MODEL_FROM_DATABASE=PowerEdge Expandable RAID Controller 3/Di
@@ -11586,13 +11787,13 @@ pci:v00001028d0000000A*
  ID_MODEL_FROM_DATABASE=PowerEdge Expandable RAID Controller 3/Di
 
 pci:v00001028d0000000Asv00001028sd00000106*
- ID_MODEL_FROM_DATABASE=PERC 3/DiJ [Jaguar]
+ ID_MODEL_FROM_DATABASE=PowerEdge Expandable RAID Controller 3/Di (PERC 3/DiJ [Jaguar])
 
 pci:v00001028d0000000Asv00001028sd0000011B*
- ID_MODEL_FROM_DATABASE=PERC 3/DiD [Dagger]
+ ID_MODEL_FROM_DATABASE=PowerEdge Expandable RAID Controller 3/Di (PERC 3/DiD [Dagger])
 
 pci:v00001028d0000000Asv00001028sd00000121*
- ID_MODEL_FROM_DATABASE=PERC 3/DiB [Boxster]
+ ID_MODEL_FROM_DATABASE=PowerEdge Expandable RAID Controller 3/Di (PERC 3/DiB [Boxster])
 
 pci:v00001028d0000000C*
  ID_MODEL_FROM_DATABASE=Embedded Remote Access or ERA/O
@@ -11607,7 +11808,7 @@ pci:v00001028d0000000F*
  ID_MODEL_FROM_DATABASE=PowerEdge Expandable RAID controller 4/Di
 
 pci:v00001028d0000000Fsv00001028sd0000014A*
- ID_MODEL_FROM_DATABASE=PowerEdge 1750
+ ID_MODEL_FROM_DATABASE=PowerEdge Expandable RAID controller 4/Di (PowerEdge 1750)
 
 pci:v00001028d00000010*
  ID_MODEL_FROM_DATABASE=Remote Access Card 4
@@ -11622,19 +11823,19 @@ pci:v00001028d00000013*
  ID_MODEL_FROM_DATABASE=PowerEdge Expandable RAID controller 4
 
 pci:v00001028d00000013sv00001028sd0000016C*
- ID_MODEL_FROM_DATABASE=PowerEdge Expandable RAID Controller 4e/Si
+ ID_MODEL_FROM_DATABASE=PowerEdge Expandable RAID controller 4 (PowerEdge Expandable RAID Controller 4e/Si)
 
 pci:v00001028d00000013sv00001028sd0000016D*
- ID_MODEL_FROM_DATABASE=PowerEdge Expandable RAID Controller 4e/Di
+ ID_MODEL_FROM_DATABASE=PowerEdge Expandable RAID controller 4 (PowerEdge Expandable RAID Controller 4e/Di)
 
 pci:v00001028d00000013sv00001028sd0000016E*
- ID_MODEL_FROM_DATABASE=PowerEdge Expandable RAID Controller 4e/Di
+ ID_MODEL_FROM_DATABASE=PowerEdge Expandable RAID controller 4 (PowerEdge Expandable RAID Controller 4e/Di)
 
 pci:v00001028d00000013sv00001028sd0000016F*
- ID_MODEL_FROM_DATABASE=PowerEdge Expandable RAID Controller 4e/Di
+ ID_MODEL_FROM_DATABASE=PowerEdge Expandable RAID controller 4 (PowerEdge Expandable RAID Controller 4e/Di)
 
 pci:v00001028d00000013sv00001028sd00000170*
- ID_MODEL_FROM_DATABASE=PowerEdge Expandable RAID Controller 4e/Di
+ ID_MODEL_FROM_DATABASE=PowerEdge Expandable RAID controller 4 (PowerEdge Expandable RAID Controller 4e/Di)
 
 pci:v00001028d00000014*
  ID_MODEL_FROM_DATABASE=Remote Access Card 4 Daughter Card SMIC interface
@@ -11643,19 +11844,19 @@ pci:v00001028d00000015*
  ID_MODEL_FROM_DATABASE=PowerEdge Expandable RAID controller 5
 
 pci:v00001028d00000015sv00001028sd00001F01*
- ID_MODEL_FROM_DATABASE=PERC 5/E Adapter RAID Controller
+ ID_MODEL_FROM_DATABASE=PowerEdge Expandable RAID controller 5 (PERC 5/E Adapter RAID Controller)
 
 pci:v00001028d00000015sv00001028sd00001F02*
- ID_MODEL_FROM_DATABASE=PERC 5/i Adapter RAID Controller
+ ID_MODEL_FROM_DATABASE=PowerEdge Expandable RAID controller 5 (PERC 5/i Adapter RAID Controller)
 
 pci:v00001028d00000015sv00001028sd00001F03*
- ID_MODEL_FROM_DATABASE=PERC 5/i Integrated RAID Controller
+ ID_MODEL_FROM_DATABASE=PowerEdge Expandable RAID controller 5 (PERC 5/i Integrated RAID Controller)
 
 pci:v00001028d00000016*
  ID_MODEL_FROM_DATABASE=PowerEdge Expandable RAID controller S300
 
 pci:v00001028d00000016sv00001028sd00001F24*
- ID_MODEL_FROM_DATABASE=PERC S300 Controller
+ ID_MODEL_FROM_DATABASE=PowerEdge Expandable RAID controller S300 (PERC S300 Controller)
 
 pci:v00001029*
  ID_VENDOR_FROM_DATABASE=Siemens Nixdorf IS
@@ -11673,28 +11874,28 @@ pci:v0000102Ad0000001F*
  ID_MODEL_FROM_DATABASE=AHA-2940U2/U2W /7890/7891 SCSI Controllers
 
 pci:v0000102Ad0000001Fsv00009005sd0000000F*
- ID_MODEL_FROM_DATABASE=2940U2W SCSI Controller
+ ID_MODEL_FROM_DATABASE=AHA-2940U2/U2W /7890/7891 SCSI Controllers (2940U2W SCSI Controller)
 
 pci:v0000102Ad0000001Fsv00009005sd00000106*
- ID_MODEL_FROM_DATABASE=2940U2W SCSI Controller
+ ID_MODEL_FROM_DATABASE=AHA-2940U2/U2W /7890/7891 SCSI Controllers (2940U2W SCSI Controller)
 
 pci:v0000102Ad0000001Fsv00009005sd0000A180*
- ID_MODEL_FROM_DATABASE=2940U2W SCSI Controller
+ ID_MODEL_FROM_DATABASE=AHA-2940U2/U2W /7890/7891 SCSI Controllers (2940U2W SCSI Controller)
 
 pci:v0000102Ad000000C5*
  ID_MODEL_FROM_DATABASE=AIC-7899 U160/m SCSI Controller
 
 pci:v0000102Ad000000C5sv00001028sd000000C5*
- ID_MODEL_FROM_DATABASE=PowerEdge 2550/2650/4600
+ ID_MODEL_FROM_DATABASE=AIC-7899 U160/m SCSI Controller (PowerEdge 2550/2650/4600)
 
 pci:v0000102Ad000000CF*
  ID_MODEL_FROM_DATABASE=AIC-7899P U160/m
 
 pci:v0000102Ad000000CFsv00001028sd00000106*
- ID_MODEL_FROM_DATABASE=PowerEdge 4600
+ ID_MODEL_FROM_DATABASE=AIC-7899P U160/m (PowerEdge 4600)
 
 pci:v0000102Ad000000CFsv00001028sd00000121*
- ID_MODEL_FROM_DATABASE=PowerEdge 2650
+ ID_MODEL_FROM_DATABASE=AIC-7899P U160/m (PowerEdge 2650)
 
 pci:v0000102B*
  ID_VENDOR_FROM_DATABASE=Matrox Electronics Systems Ltd.
@@ -11715,34 +11916,34 @@ pci:v0000102Bd0000051A*
  ID_MODEL_FROM_DATABASE=MGA 1064SG [Mystique]
 
 pci:v0000102Bd0000051Asv0000102Bsd00000100*
- ID_MODEL_FROM_DATABASE=MGA-1064SG Mystique
+ ID_MODEL_FROM_DATABASE=MGA 1064SG [Mystique] (MGA-1064SG Mystique)
 
 pci:v0000102Bd0000051Asv0000102Bsd00001100*
- ID_MODEL_FROM_DATABASE=MGA-1084SG Mystique
+ ID_MODEL_FROM_DATABASE=MGA 1064SG [Mystique] (MGA-1084SG Mystique)
 
 pci:v0000102Bd0000051Asv0000102Bsd00001200*
- ID_MODEL_FROM_DATABASE=MGA-1084SG Mystique
+ ID_MODEL_FROM_DATABASE=MGA 1064SG [Mystique] (MGA-1084SG Mystique)
 
 pci:v0000102Bd0000051Asv00001100sd0000102B*
- ID_MODEL_FROM_DATABASE=MGA-1084SG Mystique
+ ID_MODEL_FROM_DATABASE=MGA 1064SG [Mystique] (MGA-1084SG Mystique)
 
 pci:v0000102Bd0000051Asv0000110Asd00000018*
- ID_MODEL_FROM_DATABASE=Scenic Pro C5 (D1025)
+ ID_MODEL_FROM_DATABASE=MGA 1064SG [Mystique] (Scenic Pro C5 (D1025))
 
 pci:v0000102Bd0000051B*
  ID_MODEL_FROM_DATABASE=MGA 2164W [Millennium II]
 
 pci:v0000102Bd0000051Bsv0000102Bsd0000051B*
- ID_MODEL_FROM_DATABASE=MGA-2164W Millennium II
+ ID_MODEL_FROM_DATABASE=MGA 2164W [Millennium II] (MGA-2164W Millennium II)
 
 pci:v0000102Bd0000051Bsv0000102Bsd00001100*
- ID_MODEL_FROM_DATABASE=MGA-2164W Millennium II
+ ID_MODEL_FROM_DATABASE=MGA 2164W [Millennium II] (MGA-2164W Millennium II)
 
 pci:v0000102Bd0000051Bsv0000102Bsd00001200*
- ID_MODEL_FROM_DATABASE=MGA-2164W Millennium II
+ ID_MODEL_FROM_DATABASE=MGA 2164W [Millennium II] (MGA-2164W Millennium II)
 
 pci:v0000102Bd0000051Bsv0000102Bsd00002100*
- ID_MODEL_FROM_DATABASE=MGA-2164W Millennium II
+ ID_MODEL_FROM_DATABASE=MGA 2164W [Millennium II] (MGA-2164W Millennium II)
 
 pci:v0000102Bd0000051E*
  ID_MODEL_FROM_DATABASE=MGA 1064SG [Mystique] AGP
@@ -11754,391 +11955,391 @@ pci:v0000102Bd00000520*
  ID_MODEL_FROM_DATABASE=MGA G200
 
 pci:v0000102Bd00000520sv0000102Bsd0000DBC2*
- ID_MODEL_FROM_DATABASE=G200 Multi-Monitor
+ ID_MODEL_FROM_DATABASE=MGA G200 (G200 Multi-Monitor)
 
 pci:v0000102Bd00000520sv0000102Bsd0000DBC8*
- ID_MODEL_FROM_DATABASE=G200 Multi-Monitor
+ ID_MODEL_FROM_DATABASE=MGA G200 (G200 Multi-Monitor)
 
 pci:v0000102Bd00000520sv0000102Bsd0000DBE2*
- ID_MODEL_FROM_DATABASE=G200 Multi-Monitor
+ ID_MODEL_FROM_DATABASE=MGA G200 (G200 Multi-Monitor)
 
 pci:v0000102Bd00000520sv0000102Bsd0000DBE8*
- ID_MODEL_FROM_DATABASE=G200 Multi-Monitor
+ ID_MODEL_FROM_DATABASE=MGA G200 (G200 Multi-Monitor)
 
 pci:v0000102Bd00000520sv0000102Bsd0000FF03*
- ID_MODEL_FROM_DATABASE=Millennium G200 SD
+ ID_MODEL_FROM_DATABASE=MGA G200 (Millennium G200 SD)
 
 pci:v0000102Bd00000520sv0000102Bsd0000FF04*
- ID_MODEL_FROM_DATABASE=Marvel G200
+ ID_MODEL_FROM_DATABASE=MGA G200 (Marvel G200)
 
 pci:v0000102Bd00000521*
  ID_MODEL_FROM_DATABASE=MGA G200 AGP
 
 pci:v0000102Bd00000521sv00001014sd0000FF03*
- ID_MODEL_FROM_DATABASE=Millennium G200 AGP
+ ID_MODEL_FROM_DATABASE=MGA G200 AGP (Millennium G200 AGP)
 
 pci:v0000102Bd00000521sv0000102Bsd000048E9*
- ID_MODEL_FROM_DATABASE=Mystique G200 AGP
+ ID_MODEL_FROM_DATABASE=MGA G200 AGP (Mystique G200 AGP)
 
 pci:v0000102Bd00000521sv0000102Bsd000048F8*
- ID_MODEL_FROM_DATABASE=Millennium G200 SD AGP
+ ID_MODEL_FROM_DATABASE=MGA G200 AGP (Millennium G200 SD AGP)
 
 pci:v0000102Bd00000521sv0000102Bsd00004A60*
- ID_MODEL_FROM_DATABASE=Millennium G200 LE AGP
+ ID_MODEL_FROM_DATABASE=MGA G200 AGP (Millennium G200 LE AGP)
 
 pci:v0000102Bd00000521sv0000102Bsd00004A64*
- ID_MODEL_FROM_DATABASE=Millennium G200 AGP
+ ID_MODEL_FROM_DATABASE=MGA G200 AGP (Millennium G200 AGP)
 
 pci:v0000102Bd00000521sv0000102Bsd0000C93C*
- ID_MODEL_FROM_DATABASE=Millennium G200 AGP
+ ID_MODEL_FROM_DATABASE=MGA G200 AGP (Millennium G200 AGP)
 
 pci:v0000102Bd00000521sv0000102Bsd0000C9B0*
- ID_MODEL_FROM_DATABASE=Millennium G200 AGP
+ ID_MODEL_FROM_DATABASE=MGA G200 AGP (Millennium G200 AGP)
 
 pci:v0000102Bd00000521sv0000102Bsd0000C9BC*
- ID_MODEL_FROM_DATABASE=Millennium G200 AGP
+ ID_MODEL_FROM_DATABASE=MGA G200 AGP (Millennium G200 AGP)
 
 pci:v0000102Bd00000521sv0000102Bsd0000CA60*
- ID_MODEL_FROM_DATABASE=Millennium G250 LE AGP
+ ID_MODEL_FROM_DATABASE=MGA G200 AGP (Millennium G250 LE AGP)
 
 pci:v0000102Bd00000521sv0000102Bsd0000CA6C*
- ID_MODEL_FROM_DATABASE=Millennium G250 AGP
+ ID_MODEL_FROM_DATABASE=MGA G200 AGP (Millennium G250 AGP)
 
 pci:v0000102Bd00000521sv0000102Bsd0000DBBC*
- ID_MODEL_FROM_DATABASE=Millennium G200 AGP
+ ID_MODEL_FROM_DATABASE=MGA G200 AGP (Millennium G200 AGP)
 
 pci:v0000102Bd00000521sv0000102Bsd0000DBC2*
- ID_MODEL_FROM_DATABASE=Millennium G200 MMS (Dual G200)
+ ID_MODEL_FROM_DATABASE=MGA G200 AGP (Millennium G200 MMS (Dual G200))
 
 pci:v0000102Bd00000521sv0000102Bsd0000DBC3*
- ID_MODEL_FROM_DATABASE=G200 Multi-Monitor
+ ID_MODEL_FROM_DATABASE=MGA G200 AGP (G200 Multi-Monitor)
 
 pci:v0000102Bd00000521sv0000102Bsd0000DBC8*
- ID_MODEL_FROM_DATABASE=Millennium G200 MMS (Dual G200)
+ ID_MODEL_FROM_DATABASE=MGA G200 AGP (Millennium G200 MMS (Dual G200))
 
 pci:v0000102Bd00000521sv0000102Bsd0000DBD2*
- ID_MODEL_FROM_DATABASE=G200 Multi-Monitor
+ ID_MODEL_FROM_DATABASE=MGA G200 AGP (G200 Multi-Monitor)
 
 pci:v0000102Bd00000521sv0000102Bsd0000DBD3*
- ID_MODEL_FROM_DATABASE=G200 Multi-Monitor
+ ID_MODEL_FROM_DATABASE=MGA G200 AGP (G200 Multi-Monitor)
 
 pci:v0000102Bd00000521sv0000102Bsd0000DBD4*
- ID_MODEL_FROM_DATABASE=G200 Multi-Monitor
+ ID_MODEL_FROM_DATABASE=MGA G200 AGP (G200 Multi-Monitor)
 
 pci:v0000102Bd00000521sv0000102Bsd0000DBD5*
- ID_MODEL_FROM_DATABASE=G200 Multi-Monitor
+ ID_MODEL_FROM_DATABASE=MGA G200 AGP (G200 Multi-Monitor)
 
 pci:v0000102Bd00000521sv0000102Bsd0000DBD8*
- ID_MODEL_FROM_DATABASE=G200 Multi-Monitor
+ ID_MODEL_FROM_DATABASE=MGA G200 AGP (G200 Multi-Monitor)
 
 pci:v0000102Bd00000521sv0000102Bsd0000DBD9*
- ID_MODEL_FROM_DATABASE=G200 Multi-Monitor
+ ID_MODEL_FROM_DATABASE=MGA G200 AGP (G200 Multi-Monitor)
 
 pci:v0000102Bd00000521sv0000102Bsd0000DBE2*
- ID_MODEL_FROM_DATABASE=Millennium G200 MMS (Quad G200)
+ ID_MODEL_FROM_DATABASE=MGA G200 AGP (Millennium G200 MMS (Quad G200))
 
 pci:v0000102Bd00000521sv0000102Bsd0000DBE3*
- ID_MODEL_FROM_DATABASE=G200 Multi-Monitor
+ ID_MODEL_FROM_DATABASE=MGA G200 AGP (G200 Multi-Monitor)
 
 pci:v0000102Bd00000521sv0000102Bsd0000DBE8*
- ID_MODEL_FROM_DATABASE=Millennium G200 MMS (Quad G200)
+ ID_MODEL_FROM_DATABASE=MGA G200 AGP (Millennium G200 MMS (Quad G200))
 
 pci:v0000102Bd00000521sv0000102Bsd0000DBF2*
- ID_MODEL_FROM_DATABASE=G200 Multi-Monitor
+ ID_MODEL_FROM_DATABASE=MGA G200 AGP (G200 Multi-Monitor)
 
 pci:v0000102Bd00000521sv0000102Bsd0000DBF3*
- ID_MODEL_FROM_DATABASE=G200 Multi-Monitor
+ ID_MODEL_FROM_DATABASE=MGA G200 AGP (G200 Multi-Monitor)
 
 pci:v0000102Bd00000521sv0000102Bsd0000DBF4*
- ID_MODEL_FROM_DATABASE=G200 Multi-Monitor
+ ID_MODEL_FROM_DATABASE=MGA G200 AGP (G200 Multi-Monitor)
 
 pci:v0000102Bd00000521sv0000102Bsd0000DBF5*
- ID_MODEL_FROM_DATABASE=G200 Multi-Monitor
+ ID_MODEL_FROM_DATABASE=MGA G200 AGP (G200 Multi-Monitor)
 
 pci:v0000102Bd00000521sv0000102Bsd0000DBF8*
- ID_MODEL_FROM_DATABASE=G200 Multi-Monitor
+ ID_MODEL_FROM_DATABASE=MGA G200 AGP (G200 Multi-Monitor)
 
 pci:v0000102Bd00000521sv0000102Bsd0000DBF9*
- ID_MODEL_FROM_DATABASE=G200 Multi-Monitor
+ ID_MODEL_FROM_DATABASE=MGA G200 AGP (G200 Multi-Monitor)
 
 pci:v0000102Bd00000521sv0000102Bsd0000F806*
- ID_MODEL_FROM_DATABASE=Mystique G200 Video AGP
+ ID_MODEL_FROM_DATABASE=MGA G200 AGP (Mystique G200 Video AGP)
 
 pci:v0000102Bd00000521sv0000102Bsd0000FF00*
- ID_MODEL_FROM_DATABASE=MGA-G200 AGP
+ ID_MODEL_FROM_DATABASE=MGA G200 AGP (MGA-G200 AGP)
 
 pci:v0000102Bd00000521sv0000102Bsd0000FF02*
- ID_MODEL_FROM_DATABASE=Mystique G200 AGP
+ ID_MODEL_FROM_DATABASE=MGA G200 AGP (Mystique G200 AGP)
 
 pci:v0000102Bd00000521sv0000102Bsd0000FF03*
- ID_MODEL_FROM_DATABASE=Millennium G200 AGP
+ ID_MODEL_FROM_DATABASE=MGA G200 AGP (Millennium G200 AGP)
 
 pci:v0000102Bd00000521sv0000102Bsd0000FF04*
- ID_MODEL_FROM_DATABASE=Marvel G200 AGP
+ ID_MODEL_FROM_DATABASE=MGA G200 AGP (Marvel G200 AGP)
 
 pci:v0000102Bd00000521sv0000110Asd00000032*
- ID_MODEL_FROM_DATABASE=MGA-G200 AGP
+ ID_MODEL_FROM_DATABASE=MGA G200 AGP (MGA-G200 AGP)
 
 pci:v0000102Bd00000522*
  ID_MODEL_FROM_DATABASE=MGA G200e [Pilot] ServerEngines (SEP1)
 
 pci:v0000102Bd00000522sv0000103Csd000031FA*
- ID_MODEL_FROM_DATABASE=ProLiant DL140 G3
+ ID_MODEL_FROM_DATABASE=MGA G200e [Pilot] ServerEngines (SEP1) (ProLiant DL140 G3)
 
 pci:v0000102Bd00000525*
  ID_MODEL_FROM_DATABASE=MGA G400/G450
 
 pci:v0000102Bd00000525sv00000E11sd0000B16F*
- ID_MODEL_FROM_DATABASE=MGA-G400 AGP
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (MGA-G400 AGP)
 
 pci:v0000102Bd00000525sv0000102Bsd00000328*
- ID_MODEL_FROM_DATABASE=Millennium G400 16Mb SDRAM
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (Millennium G400 16Mb SDRAM)
 
 pci:v0000102Bd00000525sv0000102Bsd00000338*
- ID_MODEL_FROM_DATABASE=Millennium G400 16Mb SDRAM
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (Millennium G400 16Mb SDRAM)
 
 pci:v0000102Bd00000525sv0000102Bsd00000378*
- ID_MODEL_FROM_DATABASE=Millennium G400 32Mb SDRAM
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (Millennium G400 32Mb SDRAM)
 
 pci:v0000102Bd00000525sv0000102Bsd00000541*
- ID_MODEL_FROM_DATABASE=Millennium G450 Dual Head
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (Millennium G450 Dual Head)
 
 pci:v0000102Bd00000525sv0000102Bsd00000542*
- ID_MODEL_FROM_DATABASE=Millennium G450 Dual Head LX
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (Millennium G450 Dual Head LX)
 
 pci:v0000102Bd00000525sv0000102Bsd00000543*
- ID_MODEL_FROM_DATABASE=Millennium G450 Single Head LX
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (Millennium G450 Single Head LX)
 
 pci:v0000102Bd00000525sv0000102Bsd00000641*
- ID_MODEL_FROM_DATABASE=Millennium G450 32Mb SDRAM Dual Head
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (Millennium G450 32Mb SDRAM Dual Head)
 
 pci:v0000102Bd00000525sv0000102Bsd00000642*
- ID_MODEL_FROM_DATABASE=Millennium G450 32Mb SDRAM Dual Head LX
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (Millennium G450 32Mb SDRAM Dual Head LX)
 
 pci:v0000102Bd00000525sv0000102Bsd00000643*
- ID_MODEL_FROM_DATABASE=Millennium G450 32Mb SDRAM Single Head LX
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (Millennium G450 32Mb SDRAM Single Head LX)
 
 pci:v0000102Bd00000525sv0000102Bsd000007C0*
- ID_MODEL_FROM_DATABASE=Millennium G450 Dual Head LE
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (Millennium G450 Dual Head LE)
 
 pci:v0000102Bd00000525sv0000102Bsd000007C1*
- ID_MODEL_FROM_DATABASE=Millennium G450 SDR Dual Head LE
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (Millennium G450 SDR Dual Head LE)
 
 pci:v0000102Bd00000525sv0000102Bsd00000D41*
- ID_MODEL_FROM_DATABASE=Millennium G450 Dual Head PCI
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (Millennium G450 Dual Head PCI)
 
 pci:v0000102Bd00000525sv0000102Bsd00000D42*
- ID_MODEL_FROM_DATABASE=Millennium G450 Dual Head LX PCI
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (Millennium G450 Dual Head LX PCI)
 
 pci:v0000102Bd00000525sv0000102Bsd00000D43*
- ID_MODEL_FROM_DATABASE=Millennium G450 32Mb Dual Head PCI
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (Millennium G450 32Mb Dual Head PCI)
 
 pci:v0000102Bd00000525sv0000102Bsd00000E00*
- ID_MODEL_FROM_DATABASE=Marvel G450 eTV
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (Marvel G450 eTV)
 
 pci:v0000102Bd00000525sv0000102Bsd00000E01*
- ID_MODEL_FROM_DATABASE=Marvel G450 eTV
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (Marvel G450 eTV)
 
 pci:v0000102Bd00000525sv0000102Bsd00000E02*
- ID_MODEL_FROM_DATABASE=Marvel G450 eTV
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (Marvel G450 eTV)
 
 pci:v0000102Bd00000525sv0000102Bsd00000E03*
- ID_MODEL_FROM_DATABASE=Marvel G450 eTV
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (Marvel G450 eTV)
 
 pci:v0000102Bd00000525sv0000102Bsd00000F80*
- ID_MODEL_FROM_DATABASE=Millennium G450 Low Profile
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (Millennium G450 Low Profile)
 
 pci:v0000102Bd00000525sv0000102Bsd00000F81*
- ID_MODEL_FROM_DATABASE=Millennium G450 Low Profile
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (Millennium G450 Low Profile)
 
 pci:v0000102Bd00000525sv0000102Bsd00000F82*
- ID_MODEL_FROM_DATABASE=Millennium G450 Low Profile DVI
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (Millennium G450 Low Profile DVI)
 
 pci:v0000102Bd00000525sv0000102Bsd00000F83*
- ID_MODEL_FROM_DATABASE=Millennium G450 Low Profile DVI
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (Millennium G450 Low Profile DVI)
 
 pci:v0000102Bd00000525sv0000102Bsd000019D8*
- ID_MODEL_FROM_DATABASE=Millennium G400 16Mb SGRAM
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (Millennium G400 16Mb SGRAM)
 
 pci:v0000102Bd00000525sv0000102Bsd000019F8*
- ID_MODEL_FROM_DATABASE=Millennium G400 32Mb SGRAM
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (Millennium G400 32Mb SGRAM)
 
 pci:v0000102Bd00000525sv0000102Bsd00002159*
- ID_MODEL_FROM_DATABASE=Millennium G400 Dual Head 16Mb
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (Millennium G400 Dual Head 16Mb)
 
 pci:v0000102Bd00000525sv0000102Bsd00002179*
- ID_MODEL_FROM_DATABASE=Millennium G400 MAX/Dual Head 32Mb
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (Millennium G400 MAX/Dual Head 32Mb)
 
 pci:v0000102Bd00000525sv0000102Bsd0000217D*
- ID_MODEL_FROM_DATABASE=Millennium G400 Dual Head Max
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (Millennium G400 Dual Head Max)
 
 pci:v0000102Bd00000525sv0000102Bsd000023C0*
- ID_MODEL_FROM_DATABASE=Millennium G450
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (Millennium G450)
 
 pci:v0000102Bd00000525sv0000102Bsd000023C1*
- ID_MODEL_FROM_DATABASE=Millennium G450
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (Millennium G450)
 
 pci:v0000102Bd00000525sv0000102Bsd000023C2*
- ID_MODEL_FROM_DATABASE=Millennium G450 DVI
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (Millennium G450 DVI)
 
 pci:v0000102Bd00000525sv0000102Bsd000023C3*
- ID_MODEL_FROM_DATABASE=Millennium G450 DVI
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (Millennium G450 DVI)
 
 pci:v0000102Bd00000525sv0000102Bsd00002F58*
- ID_MODEL_FROM_DATABASE=Millennium G400
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (Millennium G400)
 
 pci:v0000102Bd00000525sv0000102Bsd00002F78*
- ID_MODEL_FROM_DATABASE=Millennium G400
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (Millennium G400)
 
 pci:v0000102Bd00000525sv0000102Bsd00003693*
- ID_MODEL_FROM_DATABASE=Marvel G400 AGP
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (Marvel G400 AGP)
 
 pci:v0000102Bd00000525sv0000102Bsd00005DD0*
- ID_MODEL_FROM_DATABASE=4Sight II
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (4Sight II)
 
 pci:v0000102Bd00000525sv0000102Bsd00005F50*
- ID_MODEL_FROM_DATABASE=4Sight II
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (4Sight II)
 
 pci:v0000102Bd00000525sv0000102Bsd00005F51*
- ID_MODEL_FROM_DATABASE=4Sight II
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (4Sight II)
 
 pci:v0000102Bd00000525sv0000102Bsd00005F52*
- ID_MODEL_FROM_DATABASE=4Sight II
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (4Sight II)
 
 pci:v0000102Bd00000525sv0000102Bsd00009010*
- ID_MODEL_FROM_DATABASE=Millennium G400 Dual Head
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (Millennium G400 Dual Head)
 
 pci:v0000102Bd00000525sv00001458sd00000400*
- ID_MODEL_FROM_DATABASE=GA-G400
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (GA-G400)
 
 pci:v0000102Bd00000525sv00001705sd00000001*
- ID_MODEL_FROM_DATABASE=Millennium G450 32MB SGRAM
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (Millennium G450 32MB SGRAM)
 
 pci:v0000102Bd00000525sv00001705sd00000002*
- ID_MODEL_FROM_DATABASE=Millennium G450 16MB SGRAM
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (Millennium G450 16MB SGRAM)
 
 pci:v0000102Bd00000525sv00001705sd00000003*
- ID_MODEL_FROM_DATABASE=Millennium G450 32MB
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (Millennium G450 32MB)
 
 pci:v0000102Bd00000525sv00001705sd00000004*
- ID_MODEL_FROM_DATABASE=Millennium G450 16MB
+ ID_MODEL_FROM_DATABASE=MGA G400/G450 (Millennium G450 16MB)
 
 pci:v0000102Bd00000527*
  ID_MODEL_FROM_DATABASE=Parhelia
 
 pci:v0000102Bd00000527sv0000102Bsd00000840*
- ID_MODEL_FROM_DATABASE=Parhelia 128Mb
+ ID_MODEL_FROM_DATABASE=Parhelia (128Mb)
 
 pci:v0000102Bd00000527sv0000102Bsd00000850*
- ID_MODEL_FROM_DATABASE=Parhelia 256MB
+ ID_MODEL_FROM_DATABASE=Parhelia (256MB)
 
 pci:v0000102Bd00000527sv0000102Bsd00000870*
- ID_MODEL_FROM_DATABASE=MED2mp-DVI
+ ID_MODEL_FROM_DATABASE=Parhelia (MED2mp-DVI)
 
 pci:v0000102Bd00000527sv0000102Bsd00000880*
- ID_MODEL_FROM_DATABASE=P-256 Edge Overlap Controller
+ ID_MODEL_FROM_DATABASE=Parhelia (P-256 Edge Overlap Controller)
 
 pci:v0000102Bd00000528*
  ID_MODEL_FROM_DATABASE=Parhelia
 
 pci:v0000102Bd00000528sv0000102Bsd00001020*
- ID_MODEL_FROM_DATABASE=Parhelia 128MB
+ ID_MODEL_FROM_DATABASE=Parhelia (128MB)
 
 pci:v0000102Bd00000528sv0000102Bsd00001030*
- ID_MODEL_FROM_DATABASE=Parhelia 256 MB Dual DVI
+ ID_MODEL_FROM_DATABASE=Parhelia (256 MB Dual DVI)
 
 pci:v0000102Bd00000528sv0000102Bsd00001040*
- ID_MODEL_FROM_DATABASE=MED2mp-DVI
+ ID_MODEL_FROM_DATABASE=Parhelia (MED2mp-DVI)
 
 pci:v0000102Bd00000528sv0000102Bsd00001050*
- ID_MODEL_FROM_DATABASE=Sono S20
+ ID_MODEL_FROM_DATABASE=Parhelia (Sono S20)
 
 pci:v0000102Bd00000528sv0000102Bsd00001060*
- ID_MODEL_FROM_DATABASE=PJ-30L
+ ID_MODEL_FROM_DATABASE=Parhelia (PJ-30L)
 
 pci:v0000102Bd00000528sv0000102Bsd00001070*
- ID_MODEL_FROM_DATABASE=PJ-40L
+ ID_MODEL_FROM_DATABASE=Parhelia (PJ-40L)
 
 pci:v0000102Bd00000528sv0000102Bsd00001421*
- ID_MODEL_FROM_DATABASE=MED5mp
+ ID_MODEL_FROM_DATABASE=Parhelia (MED5mp)
 
 pci:v0000102Bd00000528sv0000102Bsd00001431*
- ID_MODEL_FROM_DATABASE=MED3mp-DVI
+ ID_MODEL_FROM_DATABASE=Parhelia (MED3mp-DVI)
 
 pci:v0000102Bd00000528sv0000102Bsd00001451*
- ID_MODEL_FROM_DATABASE=MED5mp-DVI
+ ID_MODEL_FROM_DATABASE=Parhelia (MED5mp-DVI)
 
 pci:v0000102Bd00000528sv0000102Bsd00001491*
- ID_MODEL_FROM_DATABASE=MED2mp-DVI
+ ID_MODEL_FROM_DATABASE=Parhelia (MED2mp-DVI)
 
 pci:v0000102Bd00000528sv0000102Bsd000014B1*
- ID_MODEL_FROM_DATABASE=MED3mp-DVI
+ ID_MODEL_FROM_DATABASE=Parhelia (MED3mp-DVI)
 
 pci:v0000102Bd00000528sv0000102Bsd000014C1*
- ID_MODEL_FROM_DATABASE=MED5mp-DVI
+ ID_MODEL_FROM_DATABASE=Parhelia (MED5mp-DVI)
 
 pci:v0000102Bd00000528sv0000102Bsd000014E1*
- ID_MODEL_FROM_DATABASE=Parhelia PCI 256MB
+ ID_MODEL_FROM_DATABASE=Parhelia (PCI 256MB)
 
 pci:v0000102Bd00000528sv0000102Bsd000014F1*
- ID_MODEL_FROM_DATABASE=Parhelia Precision SGT
+ ID_MODEL_FROM_DATABASE=Parhelia (Precision SGT)
 
 pci:v0000102Bd00000528sv0000102Bsd00001501*
- ID_MODEL_FROM_DATABASE=ATC-4MP
+ ID_MODEL_FROM_DATABASE=Parhelia (ATC-4MP)
 
 pci:v0000102Bd00000528sv0000102Bsd00001511*
- ID_MODEL_FROM_DATABASE=ATC-4MP
+ ID_MODEL_FROM_DATABASE=Parhelia (ATC-4MP)
 
 pci:v0000102Bd00000528sv0000102Bsd00001521*
- ID_MODEL_FROM_DATABASE=TheatreVUE T30
+ ID_MODEL_FROM_DATABASE=Parhelia (TheatreVUE T30)
 
 pci:v0000102Bd00000528sv0000102Bsd00001531*
- ID_MODEL_FROM_DATABASE=TheatreVUE T20
+ ID_MODEL_FROM_DATABASE=Parhelia (TheatreVUE T20)
 
 pci:v0000102Bd00000528sv0000102Bsd00001541*
- ID_MODEL_FROM_DATABASE=MED2mp-DVI
+ ID_MODEL_FROM_DATABASE=Parhelia (MED2mp-DVI)
 
 pci:v0000102Bd00000528sv0000102Bsd00001551*
- ID_MODEL_FROM_DATABASE=MED3mp-DVI
+ ID_MODEL_FROM_DATABASE=Parhelia (MED3mp-DVI)
 
 pci:v0000102Bd00000528sv0000102Bsd00001561*
- ID_MODEL_FROM_DATABASE=MED5mp-DVI
+ ID_MODEL_FROM_DATABASE=Parhelia (MED5mp-DVI)
 
 pci:v0000102Bd00000528sv0000102Bsd00001571*
- ID_MODEL_FROM_DATABASE=Parhelia DL256 PCI
+ ID_MODEL_FROM_DATABASE=Parhelia (DL256 PCI)
 
 pci:v0000102Bd00000528sv0000102Bsd00001591*
- ID_MODEL_FROM_DATABASE=Parhelia Precision SDT
+ ID_MODEL_FROM_DATABASE=Parhelia (Precision SDT)
 
 pci:v0000102Bd00000528sv0000102Bsd000015A1*
- ID_MODEL_FROM_DATABASE=MED4mp-DVI
+ ID_MODEL_FROM_DATABASE=Parhelia (MED4mp-DVI)
 
 pci:v0000102Bd00000528sv0000102Bsd00002011*
- ID_MODEL_FROM_DATABASE=Parhelia HR256
+ ID_MODEL_FROM_DATABASE=Parhelia (HR256)
 
 pci:v0000102Bd00000528sv0000102Bsd00002021*
- ID_MODEL_FROM_DATABASE=QID Pro
+ ID_MODEL_FROM_DATABASE=Parhelia (QID Pro)
 
 pci:v0000102Bd00000528sv0000102Bsd00002061*
- ID_MODEL_FROM_DATABASE=PJ-40LP
+ ID_MODEL_FROM_DATABASE=Parhelia (PJ-40LP)
 
 pci:v0000102Bd00000528sv0000102Bsd00002081*
- ID_MODEL_FROM_DATABASE=EWS Quad
+ ID_MODEL_FROM_DATABASE=Parhelia (EWS Quad)
 
 pci:v0000102Bd00000528sv0000102Bsd00002411*
- ID_MODEL_FROM_DATABASE=PPX-OUT8
+ ID_MODEL_FROM_DATABASE=Parhelia (PPX-OUT8)
 
 pci:v0000102Bd00000528sv0000102Bsd00002421*
- ID_MODEL_FROM_DATABASE=VPX-OUT8
+ ID_MODEL_FROM_DATABASE=Parhelia (VPX-OUT8)
 
 pci:v0000102Bd00000528sv0000102Bsd00002441*
- ID_MODEL_FROM_DATABASE=PPX-OUT4
+ ID_MODEL_FROM_DATABASE=Parhelia (PPX-OUT4)
 
 pci:v0000102Bd00000528sv0000102Bsd00002451*
- ID_MODEL_FROM_DATABASE=VPX-OUT4
+ ID_MODEL_FROM_DATABASE=Parhelia (VPX-OUT4)
 
 pci:v0000102Bd00000528sv0000102Bsd00002491*
- ID_MODEL_FROM_DATABASE=LPX-OUT4
+ ID_MODEL_FROM_DATABASE=Parhelia (LPX-OUT4)
 
 pci:v0000102Bd00000530*
  ID_MODEL_FROM_DATABASE=MGA G200EV
@@ -12147,37 +12348,40 @@ pci:v0000102Bd00000532*
  ID_MODEL_FROM_DATABASE=MGA G200eW WPCM450
 
 pci:v0000102Bd00000532sv00001028sd00000235*
- ID_MODEL_FROM_DATABASE=PowerEdge R710 MGA G200eW WPCM450
+ ID_MODEL_FROM_DATABASE=MGA G200eW WPCM450 (PowerEdge R710 MGA G200eW WPCM450)
 
 pci:v0000102Bd00000532sv00001028sd00000236*
- ID_MODEL_FROM_DATABASE=PowerEdge R610 MGA G200eW WPCM450
+ ID_MODEL_FROM_DATABASE=MGA G200eW WPCM450 (PowerEdge R610 MGA G200eW WPCM450)
 
 pci:v0000102Bd00000532sv00001028sd00000237*
- ID_MODEL_FROM_DATABASE=PowerEdge T610 MGA G200eW WPCM450
+ ID_MODEL_FROM_DATABASE=MGA G200eW WPCM450 (PowerEdge T610 MGA G200eW WPCM450)
 
 pci:v0000102Bd00000532sv00001028sd00000287*
- ID_MODEL_FROM_DATABASE=PowerEdge M610 MGA G200eW WPCM450
+ ID_MODEL_FROM_DATABASE=MGA G200eW WPCM450 (PowerEdge M610 MGA G200eW WPCM450)
 
 pci:v0000102Bd00000532sv00001028sd0000028C*
- ID_MODEL_FROM_DATABASE=PowerEdge R410 MGA G200eW WPCM450
+ ID_MODEL_FROM_DATABASE=MGA G200eW WPCM450 (PowerEdge R410 MGA G200eW WPCM450)
 
 pci:v0000102Bd00000532sv00001028sd0000028D*
- ID_MODEL_FROM_DATABASE=PowerEdge T410 MGA G200eW WPCM450
+ ID_MODEL_FROM_DATABASE=MGA G200eW WPCM450 (PowerEdge T410 MGA G200eW WPCM450)
 
 pci:v0000102Bd00000532sv00001028sd0000029C*
- ID_MODEL_FROM_DATABASE=PowerEdge M710 MGA G200eW WPCM450
+ ID_MODEL_FROM_DATABASE=MGA G200eW WPCM450 (PowerEdge M710 MGA G200eW WPCM450)
 
 pci:v0000102Bd00000532sv00001028sd000002A4*
- ID_MODEL_FROM_DATABASE=PowerEdge T310 MGA G200eW WPCM450
+ ID_MODEL_FROM_DATABASE=MGA G200eW WPCM450 (PowerEdge T310 MGA G200eW WPCM450)
+
+pci:v0000102Bd00000532sv000015D9sd00000624*
+ ID_MODEL_FROM_DATABASE=MGA G200eW WPCM450 (X9SCM-F Motherboard)
 
 pci:v0000102Bd00000532sv000015D9sd0000A811*
- ID_MODEL_FROM_DATABASE=H8DGU
+ ID_MODEL_FROM_DATABASE=MGA G200eW WPCM450 (H8DGU)
 
 pci:v0000102Bd00000533*
  ID_MODEL_FROM_DATABASE=MGA G200EH
 
 pci:v0000102Bd00000533sv0000103Csd00003381*
- ID_MODEL_FROM_DATABASE=iLO4
+ ID_MODEL_FROM_DATABASE=MGA G200EH (iLO4)
 
 pci:v0000102Bd00000534*
  ID_MODEL_FROM_DATABASE=G200eR2
@@ -12186,40 +12390,40 @@ pci:v0000102Bd00000540*
  ID_MODEL_FROM_DATABASE=M91XX
 
 pci:v0000102Bd00000540sv0000102Bsd00002080*
- ID_MODEL_FROM_DATABASE=M9140 LP PCIe x16
+ ID_MODEL_FROM_DATABASE=M91XX (M9140 LP PCIe x16)
 
 pci:v0000102Bd00000540sv0000102Bsd000020C0*
- ID_MODEL_FROM_DATABASE=Xenia
+ ID_MODEL_FROM_DATABASE=M91XX (Xenia)
 
 pci:v0000102Bd00000540sv0000102Bsd000020C1*
- ID_MODEL_FROM_DATABASE=Xenia Pro
+ ID_MODEL_FROM_DATABASE=M91XX (Xenia Pro)
 
 pci:v0000102Bd00000540sv0000102Bsd00002100*
- ID_MODEL_FROM_DATABASE=M9120 PCIe x16
+ ID_MODEL_FROM_DATABASE=M91XX (M9120 PCIe x16)
 
 pci:v0000102Bd00000540sv0000102Bsd00002140*
- ID_MODEL_FROM_DATABASE=M9125 PCIe x16
+ ID_MODEL_FROM_DATABASE=M91XX (M9125 PCIe x16)
 
 pci:v0000102Bd00000540sv0000102Bsd00002180*
- ID_MODEL_FROM_DATABASE=M9120 Plus LP PCIe x16
+ ID_MODEL_FROM_DATABASE=M91XX (M9120 Plus LP PCIe x16)
 
 pci:v0000102Bd00000540sv0000102Bsd000021C0*
- ID_MODEL_FROM_DATABASE=M9120 Plus LP PCIe x1
+ ID_MODEL_FROM_DATABASE=M91XX (M9120 Plus LP PCIe x1)
 
 pci:v0000102Bd00000540sv0000102Bsd00002200*
- ID_MODEL_FROM_DATABASE=VDA1164 Output Board
+ ID_MODEL_FROM_DATABASE=M91XX (VDA1164 Output Board)
 
 pci:v0000102Bd00000540sv0000102Bsd00002240*
- ID_MODEL_FROM_DATABASE=M9148 LP PCIe x16
+ ID_MODEL_FROM_DATABASE=M91XX (M9148 LP PCIe x16)
 
 pci:v0000102Bd00000540sv0000102Bsd00002241*
- ID_MODEL_FROM_DATABASE=M9138 LP PCIe x16
+ ID_MODEL_FROM_DATABASE=M91XX (M9138 LP PCIe x16)
 
 pci:v0000102Bd00000540sv0000102Bsd00002280*
- ID_MODEL_FROM_DATABASE=M9188 ATX PCIe x16
+ ID_MODEL_FROM_DATABASE=M91XX (M9188 ATX PCIe x16)
 
 pci:v0000102Bd00000540sv0000102Bsd000022C0*
- ID_MODEL_FROM_DATABASE=M9128 LP PCIe x16
+ ID_MODEL_FROM_DATABASE=M91XX (M9128 LP PCIe x16)
 
 pci:v0000102Bd00000D10*
  ID_MODEL_FROM_DATABASE=MGA Ultima/Impression
@@ -12228,34 +12432,34 @@ pci:v0000102Bd00001000*
  ID_MODEL_FROM_DATABASE=MGA G100 [Productiva]
 
 pci:v0000102Bd00001000sv0000102Bsd0000FF01*
- ID_MODEL_FROM_DATABASE=Productiva G100
+ ID_MODEL_FROM_DATABASE=MGA G100 [Productiva] (Productiva G100)
 
 pci:v0000102Bd00001000sv0000102Bsd0000FF05*
- ID_MODEL_FROM_DATABASE=Productiva G100 Multi-Monitor
+ ID_MODEL_FROM_DATABASE=MGA G100 [Productiva] (Productiva G100 Multi-Monitor)
 
 pci:v0000102Bd00001001*
  ID_MODEL_FROM_DATABASE=MGA G100 [Productiva] AGP
 
 pci:v0000102Bd00001001sv0000102Bsd00001001*
- ID_MODEL_FROM_DATABASE=MGA-G100 AGP
+ ID_MODEL_FROM_DATABASE=MGA G100 [Productiva] AGP (MGA-G100 AGP)
 
 pci:v0000102Bd00001001sv0000102Bsd0000FF00*
- ID_MODEL_FROM_DATABASE=MGA-G100 AGP
+ ID_MODEL_FROM_DATABASE=MGA G100 [Productiva] AGP (MGA-G100 AGP)
 
 pci:v0000102Bd00001001sv0000102Bsd0000FF01*
- ID_MODEL_FROM_DATABASE=MGA-G100 Productiva AGP
+ ID_MODEL_FROM_DATABASE=MGA G100 [Productiva] AGP (MGA-G100 Productiva AGP)
 
 pci:v0000102Bd00001001sv0000102Bsd0000FF03*
- ID_MODEL_FROM_DATABASE=Millennium G100 AGP
+ ID_MODEL_FROM_DATABASE=MGA G100 [Productiva] AGP (Millennium G100 AGP)
 
 pci:v0000102Bd00001001sv0000102Bsd0000FF04*
- ID_MODEL_FROM_DATABASE=MGA-G100 AGP
+ ID_MODEL_FROM_DATABASE=MGA G100 [Productiva] AGP (MGA-G100 AGP)
 
 pci:v0000102Bd00001001sv0000102Bsd0000FF05*
- ID_MODEL_FROM_DATABASE=MGA-G100 Productiva AGP Multi-Monitor
+ ID_MODEL_FROM_DATABASE=MGA G100 [Productiva] AGP (MGA-G100 Productiva AGP Multi-Monitor)
 
 pci:v0000102Bd00001001sv0000110Asd0000001E*
- ID_MODEL_FROM_DATABASE=MGA-G100 AGP
+ ID_MODEL_FROM_DATABASE=MGA G100 [Productiva] AGP (MGA-G100 AGP)
 
 pci:v0000102Bd00002007*
  ID_MODEL_FROM_DATABASE=MGA Mistral
@@ -12263,161 +12467,164 @@ pci:v0000102Bd00002007*
 pci:v0000102Bd00002527*
  ID_MODEL_FROM_DATABASE=Millennium G550
 
+pci:v0000102Bd00002527sv0000102Bsd00000F42*
+ ID_MODEL_FROM_DATABASE=Millennium G550 (Matrox G550 Low Profile PCI)
+
 pci:v0000102Bd00002527sv0000102Bsd00000F83*
  ID_MODEL_FROM_DATABASE=Millennium G550
 
 pci:v0000102Bd00002527sv0000102Bsd00000F84*
- ID_MODEL_FROM_DATABASE=Millennium G550 Dual Head DDR 32Mb
+ ID_MODEL_FROM_DATABASE=Millennium G550 (Dual Head DDR 32Mb)
 
 pci:v0000102Bd00002527sv0000102Bsd00001E41*
  ID_MODEL_FROM_DATABASE=Millennium G550
 
 pci:v0000102Bd00002527sv0000102Bsd00002300*
- ID_MODEL_FROM_DATABASE=Millennium G550 LP PCIE
+ ID_MODEL_FROM_DATABASE=Millennium G550 (LP PCIE)
 
 pci:v0000102Bd00002537*
  ID_MODEL_FROM_DATABASE=Millenium P650/P750
 
 pci:v0000102Bd00002537sv0000102Bsd00001820*
- ID_MODEL_FROM_DATABASE=Millennium P750 64MB
+ ID_MODEL_FROM_DATABASE=Millenium P650/P750 (Millennium P750 64MB)
 
 pci:v0000102Bd00002537sv0000102Bsd00001830*
- ID_MODEL_FROM_DATABASE=Millennium P650 64MB
+ ID_MODEL_FROM_DATABASE=Millenium P650/P750 (Millennium P650 64MB)
 
 pci:v0000102Bd00002537sv0000102Bsd00001850*
- ID_MODEL_FROM_DATABASE=RAD2mp
+ ID_MODEL_FROM_DATABASE=Millenium P650/P750 (RAD2mp)
 
 pci:v0000102Bd00002537sv0000102Bsd00001860*
- ID_MODEL_FROM_DATABASE=RAD3mp
+ ID_MODEL_FROM_DATABASE=Millenium P650/P750 (RAD3mp)
 
 pci:v0000102Bd00002537sv0000102Bsd00001880*
- ID_MODEL_FROM_DATABASE=Sono S10
+ ID_MODEL_FROM_DATABASE=Millenium P650/P750 (Sono S10)
 
 pci:v0000102Bd00002537sv0000102Bsd00001C10*
- ID_MODEL_FROM_DATABASE=QID 128MB
+ ID_MODEL_FROM_DATABASE=Millenium P650/P750 (QID 128MB)
 
 pci:v0000102Bd00002537sv0000102Bsd00002811*
- ID_MODEL_FROM_DATABASE=Millennium P650 Low-profile PCI 64MB
+ ID_MODEL_FROM_DATABASE=Millenium P650/P750 (Millennium P650 Low-profile PCI 64MB)
 
 pci:v0000102Bd00002537sv0000102Bsd00002821*
- ID_MODEL_FROM_DATABASE=Millenium P650 Low-profile PCI
+ ID_MODEL_FROM_DATABASE=Millenium P650/P750 (Millenium P650 Low-profile PCI)
 
 pci:v0000102Bd00002537sv0000102Bsd00002841*
- ID_MODEL_FROM_DATABASE=RAD PCI
+ ID_MODEL_FROM_DATABASE=Millenium P650/P750 (RAD PCI)
 
 pci:v0000102Bd00002537sv0000102Bsd00002851*
- ID_MODEL_FROM_DATABASE=Spectrum PCI
+ ID_MODEL_FROM_DATABASE=Millenium P650/P750 (Spectrum PCI)
 
 pci:v0000102Bd00002537sv0000102Bsd00002871*
- ID_MODEL_FROM_DATABASE=EpicA TC2
+ ID_MODEL_FROM_DATABASE=Millenium P650/P750 (EpicA TC2)
 
 pci:v0000102Bd00002537sv0000102Bsd00002C11*
- ID_MODEL_FROM_DATABASE=QID Low-profile PCI
+ ID_MODEL_FROM_DATABASE=Millenium P650/P750 (QID Low-profile PCI)
 
 pci:v0000102Bd00002537sv0000102Bsd00002C21*
- ID_MODEL_FROM_DATABASE=QID LP PCI LW
+ ID_MODEL_FROM_DATABASE=Millenium P650/P750 (QID LP PCI LW)
 
 pci:v0000102Bd00002537sv0000102Bsd00002C31*
- ID_MODEL_FROM_DATABASE=QID LP PCI
+ ID_MODEL_FROM_DATABASE=Millenium P650/P750 (QID LP PCI)
 
 pci:v0000102Bd00002537sv0000102Bsd00002C41*
- ID_MODEL_FROM_DATABASE=EpicA TC4
+ ID_MODEL_FROM_DATABASE=Millenium P650/P750 (EpicA TC4)
 
 pci:v0000102Bd00002537sv0000102Bsd00003001*
- ID_MODEL_FROM_DATABASE=Extio F1400
+ ID_MODEL_FROM_DATABASE=Millenium P650/P750 (Extio F1400)
 
 pci:v0000102Bd00002537sv0000102Bsd00003011*
- ID_MODEL_FROM_DATABASE=Extio F1220
+ ID_MODEL_FROM_DATABASE=Millenium P650/P750 (Extio F1220)
 
 pci:v0000102Bd00002537sv0000102Bsd00003041*
- ID_MODEL_FROM_DATABASE=RG-200DL
+ ID_MODEL_FROM_DATABASE=Millenium P650/P750 (RG-200DL)
 
 pci:v0000102Bd00002537sv0000102Bsd00003051*
- ID_MODEL_FROM_DATABASE=RG-400SL
+ ID_MODEL_FROM_DATABASE=Millenium P650/P750 (RG-400SL)
 
 pci:v0000102Bd00002537sv0000102Bsd00003061*
- ID_MODEL_FROM_DATABASE=Extio F1420
+ ID_MODEL_FROM_DATABASE=Millenium P650/P750 (Extio F1420)
 
 pci:v0000102Bd00002537sv0000102Bsd00003081*
- ID_MODEL_FROM_DATABASE=Extio F1240
+ ID_MODEL_FROM_DATABASE=Millenium P650/P750 (Extio F1240)
 
 pci:v0000102Bd00002538*
  ID_MODEL_FROM_DATABASE=Millenium P650 PCIe
 
 pci:v0000102Bd00002538sv0000102Bsd00000847*
- ID_MODEL_FROM_DATABASE=RAD PCIe
+ ID_MODEL_FROM_DATABASE=Millenium P650 PCIe (RAD PCIe)
 
 pci:v0000102Bd00002538sv0000102Bsd000008C7*
- ID_MODEL_FROM_DATABASE=Millennium P650 PCIe 128MB
+ ID_MODEL_FROM_DATABASE=Millenium P650 PCIe (Millennium P650 PCIe 128MB)
 
 pci:v0000102Bd00002538sv0000102Bsd00000907*
- ID_MODEL_FROM_DATABASE=Millennium P650 PCIe 64MB
+ ID_MODEL_FROM_DATABASE=Millenium P650 PCIe (Millennium P650 PCIe 64MB)
 
 pci:v0000102Bd00002538sv0000102Bsd00000947*
- ID_MODEL_FROM_DATABASE=Parhelia APVe
+ ID_MODEL_FROM_DATABASE=Millenium P650 PCIe (Parhelia APVe)
 
 pci:v0000102Bd00002538sv0000102Bsd00000987*
- ID_MODEL_FROM_DATABASE=ATC PCIe 4MP
+ ID_MODEL_FROM_DATABASE=Millenium P650 PCIe (ATC PCIe 4MP)
 
 pci:v0000102Bd00002538sv0000102Bsd00001047*
- ID_MODEL_FROM_DATABASE=Millennium P650 LP PCIe 128MB
+ ID_MODEL_FROM_DATABASE=Millenium P650 PCIe (Millennium P650 LP PCIe 128MB)
 
 pci:v0000102Bd00002538sv0000102Bsd00001087*
- ID_MODEL_FROM_DATABASE=Millennium P650 LP PCIe 64MB
+ ID_MODEL_FROM_DATABASE=Millenium P650 PCIe (Millennium P650 LP PCIe 64MB)
 
 pci:v0000102Bd00002538sv0000102Bsd00001801*
- ID_MODEL_FROM_DATABASE=Millenium P650 PCIe x1
+ ID_MODEL_FROM_DATABASE=Millenium P650 PCIe (x1)
 
 pci:v0000102Bd00002538sv0000102Bsd00002538*
- ID_MODEL_FROM_DATABASE=Parhelia APVe
+ ID_MODEL_FROM_DATABASE=Millenium P650 PCIe (Parhelia APVe)
 
 pci:v0000102Bd00002538sv0000102Bsd00003007*
- ID_MODEL_FROM_DATABASE=QID Low-profile PCIe
+ ID_MODEL_FROM_DATABASE=Millenium P650 PCIe (QID Low-profile PCIe)
 
 pci:v0000102Bd00002538sv0000102Bsd00003087*
- ID_MODEL_FROM_DATABASE=Aurora VX3mp
+ ID_MODEL_FROM_DATABASE=Millenium P650 PCIe (Aurora VX3mp)
 
 pci:v0000102Bd00002538sv0000102Bsd000030C7*
- ID_MODEL_FROM_DATABASE=QID LP PCIe
+ ID_MODEL_FROM_DATABASE=Millenium P650 PCIe (QID LP PCIe)
 
 pci:v0000102Bd00002539*
  ID_MODEL_FROM_DATABASE=Millennium P690
 
 pci:v0000102Bd00002539sv0000102Bsd00000040*
- ID_MODEL_FROM_DATABASE=Millenium P690 PCIe x16
+ ID_MODEL_FROM_DATABASE=Millennium P690 (Millenium P690 PCIe x16)
 
 pci:v0000102Bd00002539sv0000102Bsd00000042*
- ID_MODEL_FROM_DATABASE=ONYX
+ ID_MODEL_FROM_DATABASE=Millennium P690 (ONYX)
 
 pci:v0000102Bd00002539sv0000102Bsd00000043*
- ID_MODEL_FROM_DATABASE=SPECTRA
+ ID_MODEL_FROM_DATABASE=Millennium P690 (SPECTRA)
 
 pci:v0000102Bd00002539sv0000102Bsd00000080*
- ID_MODEL_FROM_DATABASE=Millenium P690 Plus LP PCIe x16
+ ID_MODEL_FROM_DATABASE=Millennium P690 (Millenium P690 Plus LP PCIe x16)
 
 pci:v0000102Bd00002539sv0000102Bsd00000081*
- ID_MODEL_FROM_DATABASE=Millenium P690 LP PCIe x16
+ ID_MODEL_FROM_DATABASE=Millennium P690 (Millenium P690 LP PCIe x16)
 
 pci:v0000102Bd00002539sv0000102Bsd00000082*
- ID_MODEL_FROM_DATABASE=RAD LPX PCIe x16
+ ID_MODEL_FROM_DATABASE=Millennium P690 (RAD LPX PCIe x16)
 
 pci:v0000102Bd00002539sv0000102Bsd000000C0*
- ID_MODEL_FROM_DATABASE=Millenium P690 Plus LP PCI
+ ID_MODEL_FROM_DATABASE=Millennium P690 (Millenium P690 Plus LP PCI)
 
 pci:v0000102Bd00002539sv0000102Bsd000000C2*
- ID_MODEL_FROM_DATABASE=Millenium P690 LP PCI
+ ID_MODEL_FROM_DATABASE=Millennium P690 (Millenium P690 LP PCI)
 
 pci:v0000102Bd00002539sv0000102Bsd000000C3*
- ID_MODEL_FROM_DATABASE=RAD LPX PCI
+ ID_MODEL_FROM_DATABASE=Millennium P690 (RAD LPX PCI)
 
 pci:v0000102Bd00002539sv0000102Bsd00000101*
- ID_MODEL_FROM_DATABASE=Millenium P690 PCI
+ ID_MODEL_FROM_DATABASE=Millennium P690 (Millenium P690 PCI)
 
 pci:v0000102Bd00002539sv0000102Bsd00000140*
- ID_MODEL_FROM_DATABASE=Millenium P690 LP PCIe x1
+ ID_MODEL_FROM_DATABASE=Millennium P690 (Millenium P690 LP PCIe x1)
 
 pci:v0000102Bd00002539sv0000102Bsd00000180*
- ID_MODEL_FROM_DATABASE=Display Wall IP Decode 128 MB
+ ID_MODEL_FROM_DATABASE=Millennium P690 (Display Wall IP Decode 128 MB)
 
 pci:v0000102Bd00004164*
  ID_MODEL_FROM_DATABASE=Morphis QxT frame grabber
@@ -12441,43 +12648,43 @@ pci:v0000102Bd0000475D*
  ID_MODEL_FROM_DATABASE=Vio frame grabber family
 
 pci:v0000102Bd0000475Dsv0000102Bsd00004B90*
- ID_MODEL_FROM_DATABASE=Vio Duo frame grabber (single channel)
+ ID_MODEL_FROM_DATABASE=Vio frame grabber family (Vio Duo frame grabber (single channel))
 
 pci:v0000102Bd0000475Dsv0000102Bsd00004B91*
- ID_MODEL_FROM_DATABASE=Vio Duo frame grabber
+ ID_MODEL_FROM_DATABASE=Vio frame grabber family (Vio Duo frame grabber)
 
 pci:v0000102Bd0000475Dsv0000102Bsd00004B92*
- ID_MODEL_FROM_DATABASE=Vio Analog frame grabber
+ ID_MODEL_FROM_DATABASE=Vio frame grabber family (Vio Analog frame grabber)
 
 pci:v0000102Bd0000475Dsv0000102Bsd00004B93*
- ID_MODEL_FROM_DATABASE=Vio SDI Frame Grabber
+ ID_MODEL_FROM_DATABASE=Vio frame grabber family (Vio SDI Frame Grabber)
 
 pci:v0000102Bd0000475Dsv0000102Bsd00004B94*
- ID_MODEL_FROM_DATABASE=Vio DVI-A frame grabber
+ ID_MODEL_FROM_DATABASE=Vio frame grabber family (Vio DVI-A frame grabber)
 
 pci:v0000102Bd0000475F*
  ID_MODEL_FROM_DATABASE=Solios (single-Full) CL frame grabber
 
 pci:v0000102Bd0000475Fsv0000102Bsd0000475F*
- ID_MODEL_FROM_DATABASE=Solios eCL/XCL-F frame grabber
+ ID_MODEL_FROM_DATABASE=Solios (single-Full) CL frame grabber (Solios eCL/XCL-F frame grabber)
 
 pci:v0000102Bd0000475Fsv0000102Bsd00004D5F*
- ID_MODEL_FROM_DATABASE=Solios eV-CL (single-Full) frame grabber
+ ID_MODEL_FROM_DATABASE=Solios (single-Full) CL frame grabber (Solios eV-CL (single-Full) frame grabber)
 
 pci:v0000102Bd0000475Fsv0000102Bsd00004E5F*
- ID_MODEL_FROM_DATABASE=Solios eM-CL (single-Full) frame grabber
+ ID_MODEL_FROM_DATABASE=Solios (single-Full) CL frame grabber (Solios eM-CL (single-Full) frame grabber)
 
 pci:v0000102Bd000047A1*
  ID_MODEL_FROM_DATABASE=Solios eA/XA frame grabber
 
 pci:v0000102Bd000047A1sv0000102Bsd00004BE0*
- ID_MODEL_FROM_DATABASE=Solios eA/XA (single) frame grabber
+ ID_MODEL_FROM_DATABASE=Solios eA/XA frame grabber (Solios eA/XA (single) frame grabber)
 
 pci:v0000102Bd000047A1sv0000102Bsd00004BE1*
- ID_MODEL_FROM_DATABASE=Solios eA/XA (dual) frame grabber
+ ID_MODEL_FROM_DATABASE=Solios eA/XA frame grabber (Solios eA/XA (dual) frame grabber)
 
 pci:v0000102Bd000047A1sv0000102Bsd00004BE2*
- ID_MODEL_FROM_DATABASE=Solios eA/XA (quad) frame grabber
+ ID_MODEL_FROM_DATABASE=Solios eA/XA frame grabber (Solios eA/XA (quad) frame grabber)
 
 pci:v0000102Bd000047A2*
  ID_MODEL_FROM_DATABASE=Solios COM port
@@ -12486,25 +12693,25 @@ pci:v0000102Bd000047C1*
  ID_MODEL_FROM_DATABASE=Solios (dual-Base/single-Medium) CL frame grabber
 
 pci:v0000102Bd000047C1sv0000102Bsd00000000*
- ID_MODEL_FROM_DATABASE=Solios frame grabber
+ ID_MODEL_FROM_DATABASE=Solios (dual-Base/single-Medium) CL frame grabber (Solios frame grabber)
 
 pci:v0000102Bd000047C1sv0000102Bsd00004B80*
- ID_MODEL_FROM_DATABASE=Solios eCL/XCL (single-Medium) frame grabber
+ ID_MODEL_FROM_DATABASE=Solios (dual-Base/single-Medium) CL frame grabber (Solios eCL/XCL (single-Medium) frame grabber)
 
 pci:v0000102Bd000047C1sv0000102Bsd00004B81*
- ID_MODEL_FROM_DATABASE=Solios eCL/XCL (dual-Base) frame grabber
+ ID_MODEL_FROM_DATABASE=Solios (dual-Base/single-Medium) CL frame grabber (Solios eCL/XCL (dual-Base) frame grabber)
 
 pci:v0000102Bd000047C1sv0000102Bsd00004D80*
- ID_MODEL_FROM_DATABASE=Solios eV-CL (single-Medium) frame grabber
+ ID_MODEL_FROM_DATABASE=Solios (dual-Base/single-Medium) CL frame grabber (Solios eV-CL (single-Medium) frame grabber)
 
 pci:v0000102Bd000047C1sv0000102Bsd00004D81*
- ID_MODEL_FROM_DATABASE=Solios eV-CL (dual-Base) frame grabber
+ ID_MODEL_FROM_DATABASE=Solios (dual-Base/single-Medium) CL frame grabber (Solios eV-CL (dual-Base) frame grabber)
 
 pci:v0000102Bd000047C1sv0000102Bsd00004E80*
- ID_MODEL_FROM_DATABASE=Solios eM-CL (single-Medium) frame grabber
+ ID_MODEL_FROM_DATABASE=Solios (dual-Base/single-Medium) CL frame grabber (Solios eM-CL (single-Medium) frame grabber)
 
 pci:v0000102Bd000047C1sv0000102Bsd00004E81*
- ID_MODEL_FROM_DATABASE=Solios eM-CL (dual-Base) frame grabber
+ ID_MODEL_FROM_DATABASE=Solios (dual-Base/single-Medium) CL frame grabber (Solios eM-CL (dual-Base) frame grabber)
 
 pci:v0000102Bd000047C2*
  ID_MODEL_FROM_DATABASE=Solios COM port
@@ -12513,19 +12720,34 @@ pci:v0000102Bd00004949*
  ID_MODEL_FROM_DATABASE=Radient frame grabber family
 
 pci:v0000102Bd00004949sv0000102Bsd00000010*
- ID_MODEL_FROM_DATABASE=Radient eCL (Single-full) frame grabber
+ ID_MODEL_FROM_DATABASE=Radient frame grabber family (Radient eCL (Single-full) frame grabber)
+
+pci:v0000102Bd00004949sv0000102Bsd00000011*
+ ID_MODEL_FROM_DATABASE=Radient frame grabber family (Radient eCLV (Single-full) frame grabber)
 
 pci:v0000102Bd00004949sv0000102Bsd00000020*
- ID_MODEL_FROM_DATABASE=Radient eCL (Dual-base) frame grabber
+ ID_MODEL_FROM_DATABASE=Radient frame grabber family (Radient eCL (Dual-base) frame grabber)
 
 pci:v0000102Bd00004949sv0000102Bsd00000030*
- ID_MODEL_FROM_DATABASE=Radient eCL (Dual-full) frame grabber
+ ID_MODEL_FROM_DATABASE=Radient frame grabber family (Radient eCL (Dual-full) frame grabber)
 
 pci:v0000102Bd00004949sv0000102Bsd00000040*
- ID_MODEL_FROM_DATABASE=Radient eCL (Quad-base) frame grabber
+ ID_MODEL_FROM_DATABASE=Radient frame grabber family (Radient eCL (Quad-base) frame grabber)
 
 pci:v0000102Bd00004949sv0000102Bsd00000050*
- ID_MODEL_FROM_DATABASE=Radient eCL (Golden) frame grabber
+ ID_MODEL_FROM_DATABASE=Radient frame grabber family (Radient eCL (Golden) frame grabber)
+
+pci:v0000102Bd00004949sv0000102Bsd00001010*
+ ID_MODEL_FROM_DATABASE=Radient frame grabber family (Radient eV-CXP (quad CXP-6) frame grabber)
+
+pci:v0000102Bd00004949sv0000102Bsd00001015*
+ ID_MODEL_FROM_DATABASE=Radient frame grabber family (Radient eV-CXP (dual CXP-6) frame grabber)
+
+pci:v0000102Bd00004949sv0000102Bsd00001020*
+ ID_MODEL_FROM_DATABASE=Radient frame grabber family (Radient eV-CXP (quad CXP-3) frame grabber)
+
+pci:v0000102Bd00004949sv0000102Bsd00001050*
+ ID_MODEL_FROM_DATABASE=Radient frame grabber family (Radient eV-CXP (Golden) frame grabber)
 
 pci:v0000102Bd00004CDC*
  ID_MODEL_FROM_DATABASE=Morphis JPEG2000 accelerator
@@ -12555,22 +12777,22 @@ pci:v0000102Cd000000C0sv0000102Csd000000C0*
  ID_MODEL_FROM_DATABASE=F69000 HiQVideo
 
 pci:v0000102Cd000000C0sv00004C53sd00001000*
- ID_MODEL_FROM_DATABASE=CC7/CR7/CP7/VC7/VP7/VR7 mainboard
+ ID_MODEL_FROM_DATABASE=F69000 HiQVideo (CC7/CR7/CP7/VC7/VP7/VR7 mainboard)
 
 pci:v0000102Cd000000C0sv00004C53sd00001010*
- ID_MODEL_FROM_DATABASE=CP5/CR6 mainboard
+ ID_MODEL_FROM_DATABASE=F69000 HiQVideo (CP5/CR6 mainboard)
 
 pci:v0000102Cd000000C0sv00004C53sd00001020*
- ID_MODEL_FROM_DATABASE=VR6 mainboard
+ ID_MODEL_FROM_DATABASE=F69000 HiQVideo (VR6 mainboard)
 
 pci:v0000102Cd000000C0sv00004C53sd00001030*
- ID_MODEL_FROM_DATABASE=PC5 mainboard
+ ID_MODEL_FROM_DATABASE=F69000 HiQVideo (PC5 mainboard)
 
 pci:v0000102Cd000000C0sv00004C53sd00001050*
- ID_MODEL_FROM_DATABASE=CT7 mainboard
+ ID_MODEL_FROM_DATABASE=F69000 HiQVideo (CT7 mainboard)
 
 pci:v0000102Cd000000C0sv00004C53sd00001051*
- ID_MODEL_FROM_DATABASE=CE7 mainboard
+ ID_MODEL_FROM_DATABASE=F69000 HiQVideo (CE7 mainboard)
 
 pci:v0000102Cd000000D0*
  ID_MODEL_FROM_DATABASE=F65545
@@ -12591,10 +12813,10 @@ pci:v0000102Cd000000E5*
  ID_MODEL_FROM_DATABASE=F65555 HiQVPro
 
 pci:v0000102Cd000000E5sv00000E11sd0000B049*
- ID_MODEL_FROM_DATABASE=Armada 1700 Laptop Display Controller
+ ID_MODEL_FROM_DATABASE=F65555 HiQVPro (Armada 1700 Laptop Display Controller)
 
 pci:v0000102Cd000000E5sv00001179sd00000001*
- ID_MODEL_FROM_DATABASE=Satellite Pro/Satellite
+ ID_MODEL_FROM_DATABASE=F65555 HiQVPro (Satellite Pro/Satellite)
 
 pci:v0000102Cd000000F0*
  ID_MODEL_FROM_DATABASE=F68554
@@ -12609,16 +12831,16 @@ pci:v0000102Cd00000C30*
  ID_MODEL_FROM_DATABASE=F69030
 
 pci:v0000102Cd00000C30sv00004C53sd00001000*
- ID_MODEL_FROM_DATABASE=CC7/CR7/CP7/VC7/VP7/VR7 mainboard
+ ID_MODEL_FROM_DATABASE=F69030 (CC7/CR7/CP7/VC7/VP7/VR7 mainboard)
 
 pci:v0000102Cd00000C30sv00004C53sd00001050*
- ID_MODEL_FROM_DATABASE=CT7 mainboard
+ ID_MODEL_FROM_DATABASE=F69030 (CT7 mainboard)
 
 pci:v0000102Cd00000C30sv00004C53sd00001051*
- ID_MODEL_FROM_DATABASE=CE7 mainboard
+ ID_MODEL_FROM_DATABASE=F69030 (CE7 mainboard)
 
 pci:v0000102Cd00000C30sv00004C53sd00001080*
- ID_MODEL_FROM_DATABASE=CT8 mainboard
+ ID_MODEL_FROM_DATABASE=F69030 (CT8 mainboard)
 
 pci:v0000102D*
  ID_VENDOR_FROM_DATABASE=Wyse Technology Inc.
@@ -12762,34 +12984,34 @@ pci:v00001033d00000035*
  ID_MODEL_FROM_DATABASE=OHCI USB Controller
 
 pci:v00001033d00000035sv00001033sd00000035*
- ID_MODEL_FROM_DATABASE=USB Controller
+ ID_MODEL_FROM_DATABASE=OHCI USB Controller (USB Controller)
 
 pci:v00001033d00000035sv0000103Csd00001293*
- ID_MODEL_FROM_DATABASE=USB add-in card
+ ID_MODEL_FROM_DATABASE=OHCI USB Controller (USB add-in card)
 
 pci:v00001033d00000035sv0000103Csd00001294*
- ID_MODEL_FROM_DATABASE=USB 2.0 add-in card
+ ID_MODEL_FROM_DATABASE=OHCI USB Controller (USB 2.0 add-in card)
 
 pci:v00001033d00000035sv00001179sd00000001*
- ID_MODEL_FROM_DATABASE=USB
+ ID_MODEL_FROM_DATABASE=OHCI USB Controller (USB)
 
 pci:v00001033d00000035sv000012EEsd00007000*
- ID_MODEL_FROM_DATABASE=Root Hub
+ ID_MODEL_FROM_DATABASE=OHCI USB Controller (Root Hub)
 
 pci:v00001033d00000035sv000014C2sd00000105*
- ID_MODEL_FROM_DATABASE=PTI-205N USB 2.0 Host Controller
+ ID_MODEL_FROM_DATABASE=OHCI USB Controller (PTI-205N USB 2.0 Host Controller)
 
 pci:v00001033d00000035sv00001799sd00000001*
- ID_MODEL_FROM_DATABASE=Root Hub
+ ID_MODEL_FROM_DATABASE=OHCI USB Controller (Root Hub)
 
 pci:v00001033d00000035sv00001931sd0000000A*
- ID_MODEL_FROM_DATABASE=GlobeTrotter Fusion Quad Lite (PPP data)
+ ID_MODEL_FROM_DATABASE=OHCI USB Controller (GlobeTrotter Fusion Quad Lite (PPP data))
 
 pci:v00001033d00000035sv00001931sd0000000B*
- ID_MODEL_FROM_DATABASE=GlobeTrotter Fusion Quad Lite (GSM data)
+ ID_MODEL_FROM_DATABASE=OHCI USB Controller (GlobeTrotter Fusion Quad Lite (GSM data))
 
 pci:v00001033d00000035sv0000807Dsd00000035*
- ID_MODEL_FROM_DATABASE=PCI-USB2 (OHCI subsystem)
+ ID_MODEL_FROM_DATABASE=OHCI USB Controller (PCI-USB2 (OHCI subsystem))
 
 pci:v00001033d0000003B*
  ID_MODEL_FROM_DATABASE=PCI to C-bus Bridge
@@ -12810,28 +13032,28 @@ pci:v00001033d00000067*
  ID_MODEL_FROM_DATABASE=PowerVR Neon 250 Chipset
 
 pci:v00001033d00000067sv00001010sd00000020*
- ID_MODEL_FROM_DATABASE=PowerVR Neon 250 AGP 32Mb
+ ID_MODEL_FROM_DATABASE=PowerVR Neon 250 Chipset (PowerVR Neon 250 AGP 32Mb)
 
 pci:v00001033d00000067sv00001010sd00000080*
- ID_MODEL_FROM_DATABASE=PowerVR Neon 250 AGP 16Mb
+ ID_MODEL_FROM_DATABASE=PowerVR Neon 250 Chipset (PowerVR Neon 250 AGP 16Mb)
 
 pci:v00001033d00000067sv00001010sd00000088*
- ID_MODEL_FROM_DATABASE=PowerVR Neon 250 16Mb
+ ID_MODEL_FROM_DATABASE=PowerVR Neon 250 Chipset (PowerVR Neon 250 16Mb)
 
 pci:v00001033d00000067sv00001010sd00000090*
- ID_MODEL_FROM_DATABASE=PowerVR Neon 250 AGP 16Mb
+ ID_MODEL_FROM_DATABASE=PowerVR Neon 250 Chipset (PowerVR Neon 250 AGP 16Mb)
 
 pci:v00001033d00000067sv00001010sd00000098*
- ID_MODEL_FROM_DATABASE=PowerVR Neon 250 16Mb
+ ID_MODEL_FROM_DATABASE=PowerVR Neon 250 Chipset (PowerVR Neon 250 16Mb)
 
 pci:v00001033d00000067sv00001010sd000000A0*
- ID_MODEL_FROM_DATABASE=PowerVR Neon 250 AGP 32Mb
+ ID_MODEL_FROM_DATABASE=PowerVR Neon 250 Chipset (PowerVR Neon 250 AGP 32Mb)
 
 pci:v00001033d00000067sv00001010sd000000A8*
- ID_MODEL_FROM_DATABASE=PowerVR Neon 250 32Mb
+ ID_MODEL_FROM_DATABASE=PowerVR Neon 250 Chipset (PowerVR Neon 250 32Mb)
 
 pci:v00001033d00000067sv00001010sd00000120*
- ID_MODEL_FROM_DATABASE=PowerVR Neon 250 AGP 32Mb
+ ID_MODEL_FROM_DATABASE=PowerVR Neon 250 Chipset (PowerVR Neon 250 AGP 32Mb)
 
 pci:v00001033d00000072*
  ID_MODEL_FROM_DATABASE=uPD72874 IEEE1394 OHCI 1.1 3-port PHY-Link Ctrlr
@@ -12840,7 +13062,7 @@ pci:v00001033d00000074*
  ID_MODEL_FROM_DATABASE=56k Voice Modem
 
 pci:v00001033d00000074sv00001033sd00008014*
- ID_MODEL_FROM_DATABASE=RCV56ACF 56k Voice Modem
+ ID_MODEL_FROM_DATABASE=56k Voice Modem (RCV56ACF 56k Voice Modem)
 
 pci:v00001033d0000009B*
  ID_MODEL_FROM_DATABASE=Vrc5476
@@ -12855,7 +13077,7 @@ pci:v00001033d000000CD*
  ID_MODEL_FROM_DATABASE=uPD72870 [Firewarden] IEEE1394a OHCI 1.0 Link/3-port PHY Controller
 
 pci:v00001033d000000CDsv000012EEsd00008011*
- ID_MODEL_FROM_DATABASE=Root hub
+ ID_MODEL_FROM_DATABASE=uPD72870 [Firewarden] IEEE1394a OHCI 1.0 Link/3-port PHY Controller (Root hub)
 
 pci:v00001033d000000CE*
  ID_MODEL_FROM_DATABASE=uPD72871 [Firewarden] IEEE1394a OHCI 1.0 Link/1-port PHY Controller
@@ -12867,16 +13089,16 @@ pci:v00001033d000000E0*
  ID_MODEL_FROM_DATABASE=uPD72010x USB 2.0 Controller
 
 pci:v00001033d000000E0sv000012EEsd00007001*
- ID_MODEL_FROM_DATABASE=Root hub
+ ID_MODEL_FROM_DATABASE=uPD72010x USB 2.0 Controller (Root hub)
 
 pci:v00001033d000000E0sv000014C2sd00000205*
- ID_MODEL_FROM_DATABASE=PTI-205N USB 2.0 Host Controller
+ ID_MODEL_FROM_DATABASE=uPD72010x USB 2.0 Controller (PTI-205N USB 2.0 Host Controller)
 
 pci:v00001033d000000E0sv00001799sd00000002*
- ID_MODEL_FROM_DATABASE=Root Hub
+ ID_MODEL_FROM_DATABASE=uPD72010x USB 2.0 Controller (Root Hub)
 
 pci:v00001033d000000E0sv0000807Dsd00001043*
- ID_MODEL_FROM_DATABASE=PCI-USB2 (EHCI subsystem)
+ ID_MODEL_FROM_DATABASE=uPD72010x USB 2.0 Controller (PCI-USB2 (EHCI subsystem))
 
 pci:v00001033d000000E7*
  ID_MODEL_FROM_DATABASE=uPD72873 [Firewarden] IEEE1394a OHCI 1.1 Link/2-port PHY Controller
@@ -12900,19 +13122,22 @@ pci:v00001033d00000194*
  ID_MODEL_FROM_DATABASE=uPD720200 USB 3.0 Host Controller
 
 pci:v00001033d00000194sv00001028sd000004A3*
- ID_MODEL_FROM_DATABASE=Precision M4600
+ ID_MODEL_FROM_DATABASE=uPD720200 USB 3.0 Host Controller (Precision M4600)
 
 pci:v00001033d00000194sv00001028sd000004B2*
- ID_MODEL_FROM_DATABASE=Vostro 3350
+ ID_MODEL_FROM_DATABASE=uPD720200 USB 3.0 Host Controller (Vostro 3350)
 
 pci:v00001033d00000194sv00001028sd000004DA*
- ID_MODEL_FROM_DATABASE=Vostro 3750
+ ID_MODEL_FROM_DATABASE=uPD720200 USB 3.0 Host Controller (Vostro 3750)
 
 pci:v00001033d00000194sv00001043sd00008413*
- ID_MODEL_FROM_DATABASE=P8P67 Deluxe Motherboard
+ ID_MODEL_FROM_DATABASE=uPD720200 USB 3.0 Host Controller (P8P67 Deluxe Motherboard)
+
+pci:v00001033d00000194sv00001AF4sd00001100*
+ ID_MODEL_FROM_DATABASE=uPD720200 USB 3.0 Host Controller (QEMU Virtual Machine)
 
 pci:v00001033d00000194sv00001B96sd00000001*
- ID_MODEL_FROM_DATABASE=USB 3.0 PCIe Card
+ ID_MODEL_FROM_DATABASE=uPD720200 USB 3.0 Host Controller (USB 3.0 PCIe Card)
 
 pci:v00001033d000001E7*
  ID_MODEL_FROM_DATABASE=uPD72873 [Firewarden] IEEE1394a OHCI 1.1 Link/2-port PHY Controller
@@ -12971,6 +13196,9 @@ pci:v00001039d00000016*
 pci:v00001039d00000018*
  ID_MODEL_FROM_DATABASE=SiS85C503/5513 (LPC Bridge)
 
+pci:v00001039d00000163*
+ ID_MODEL_FROM_DATABASE=163 802.11b/g Wireless LAN Adapter
+
 pci:v00001039d00000180*
  ID_MODEL_FROM_DATABASE=RAID bus controller 180 SATA/PATA  [SiS]
 
@@ -12981,7 +13209,7 @@ pci:v00001039d00000182*
  ID_MODEL_FROM_DATABASE=182 SATA/RAID Controller
 
 pci:v00001039d00000182sv00001734sd00001095*
- ID_MODEL_FROM_DATABASE=D2030-A1
+ ID_MODEL_FROM_DATABASE=182 SATA/RAID Controller (D2030-A1)
 
 pci:v00001039d00000186*
  ID_MODEL_FROM_DATABASE=AHCI Controller (0106)
@@ -12996,7 +13224,7 @@ pci:v00001039d00000200*
  ID_MODEL_FROM_DATABASE=5597/5598/6326 VGA
 
 pci:v00001039d00000200sv00001039sd00000000*
- ID_MODEL_FROM_DATABASE=SiS5597 SVGA (Shared RAM)
+ ID_MODEL_FROM_DATABASE=5597/5598/6326 VGA (SiS5597 SVGA (Shared RAM))
 
 pci:v00001039d00000204*
  ID_MODEL_FROM_DATABASE=82C204
@@ -13008,7 +13236,7 @@ pci:v00001039d00000300*
  ID_MODEL_FROM_DATABASE=300/305 PCI/AGP VGA Display Adapter
 
 pci:v00001039d00000300sv0000107Dsd00002720*
- ID_MODEL_FROM_DATABASE=Leadtek WinFast VR300
+ ID_MODEL_FROM_DATABASE=300/305 PCI/AGP VGA Display Adapter (Leadtek WinFast VR300)
 
 pci:v00001039d00000310*
  ID_MODEL_FROM_DATABASE=315H PCI/AGP VGA Display Adapter
@@ -13104,7 +13332,7 @@ pci:v00001039d00000741*
  ID_MODEL_FROM_DATABASE=741/741GX/M741 Host
 
 pci:v00001039d00000741sv00001849sd00000741*
- ID_MODEL_FROM_DATABASE=K7S41/K7S41GX motherboard
+ ID_MODEL_FROM_DATABASE=741/741GX/M741 Host (K7S41/K7S41GX motherboard)
 
 pci:v00001039d00000745*
  ID_MODEL_FROM_DATABASE=745 Host
@@ -13122,25 +13350,25 @@ pci:v00001039d00000761*
  ID_MODEL_FROM_DATABASE=761/M761 Host
 
 pci:v00001039d00000761sv00001734sd00001099*
- ID_MODEL_FROM_DATABASE=D2030-A1 Motherboard
+ ID_MODEL_FROM_DATABASE=761/M761 Host (D2030-A1 Motherboard)
 
 pci:v00001039d00000900*
  ID_MODEL_FROM_DATABASE=SiS900 PCI Fast Ethernet
 
 pci:v00001039d00000900sv00001019sd00000A14*
- ID_MODEL_FROM_DATABASE=K7S5A motherboard
+ ID_MODEL_FROM_DATABASE=SiS900 PCI Fast Ethernet (K7S5A motherboard)
 
 pci:v00001039d00000900sv00001039sd00000900*
- ID_MODEL_FROM_DATABASE=SiS900 10/100 Ethernet Adapter onboard [Asus P4SC-EA]
+ ID_MODEL_FROM_DATABASE=SiS900 PCI Fast Ethernet (SiS900 10/100 Ethernet Adapter onboard [Asus P4SC-EA])
 
 pci:v00001039d00000900sv00001043sd00008035*
- ID_MODEL_FROM_DATABASE=CUSI-FX motherboard
+ ID_MODEL_FROM_DATABASE=SiS900 PCI Fast Ethernet (CUSI-FX motherboard)
 
 pci:v00001039d00000900sv00001043sd000080A7*
- ID_MODEL_FROM_DATABASE=Motherboard P4S800D-X
+ ID_MODEL_FROM_DATABASE=SiS900 PCI Fast Ethernet (Motherboard P4S800D-X)
 
 pci:v00001039d00000900sv00001462sd00000900*
- ID_MODEL_FROM_DATABASE=MS-6701 motherboard
+ ID_MODEL_FROM_DATABASE=SiS900 PCI Fast Ethernet (MS-6701 motherboard)
 
 pci:v00001039d00000961*
  ID_MODEL_FROM_DATABASE=SiS961 [MuTIOL Media IO]
@@ -13200,22 +13428,22 @@ pci:v00001039d00005513*
  ID_MODEL_FROM_DATABASE=5513 IDE Controller
 
 pci:v00001039d00005513sv00001019sd00000970*
- ID_MODEL_FROM_DATABASE=P6STP-FL motherboard
+ ID_MODEL_FROM_DATABASE=5513 IDE Controller (P6STP-FL motherboard)
 
 pci:v00001039d00005513sv00001039sd00005513*
- ID_MODEL_FROM_DATABASE=SiS5513 EIDE Controller (A,B step)
+ ID_MODEL_FROM_DATABASE=5513 IDE Controller (SiS5513 EIDE Controller (A,B step))
 
 pci:v00001039d00005513sv00001043sd00008035*
- ID_MODEL_FROM_DATABASE=CUSI-FX motherboard
+ ID_MODEL_FROM_DATABASE=5513 IDE Controller (CUSI-FX motherboard)
 
 pci:v00001039d00005513sv00001462sd00007010*
- ID_MODEL_FROM_DATABASE=MS-6701 motherboard
+ ID_MODEL_FROM_DATABASE=5513 IDE Controller (MS-6701 motherboard)
 
 pci:v00001039d00005513sv00001631sd00005513*
- ID_MODEL_FROM_DATABASE=GA-8SIML Rev1.0 Motherboard
+ ID_MODEL_FROM_DATABASE=5513 IDE Controller (GA-8SIML Rev1.0 Motherboard)
 
 pci:v00001039d00005513sv00001734sd00001095*
- ID_MODEL_FROM_DATABASE=D2030-A1 Motherboard
+ ID_MODEL_FROM_DATABASE=5513 IDE Controller (D2030-A1 Motherboard)
 
 pci:v00001039d00005517*
  ID_MODEL_FROM_DATABASE=5517
@@ -13254,13 +13482,13 @@ pci:v00001039d00006300*
  ID_MODEL_FROM_DATABASE=630/730 PCI/AGP VGA Display Adapter
 
 pci:v00001039d00006300sv00001019sd00000970*
- ID_MODEL_FROM_DATABASE=P6STP-FL motherboard
+ ID_MODEL_FROM_DATABASE=630/730 PCI/AGP VGA Display Adapter (P6STP-FL motherboard)
 
 pci:v00001039d00006300sv00001043sd00008035*
- ID_MODEL_FROM_DATABASE=CUSI-FX motherboard
+ ID_MODEL_FROM_DATABASE=630/730 PCI/AGP VGA Display Adapter (CUSI-FX motherboard)
 
 pci:v00001039d00006300sv0000104Dsd000080E2*
- ID_MODEL_FROM_DATABASE=VAIO PCV-J200
+ ID_MODEL_FROM_DATABASE=630/730 PCI/AGP VGA Display Adapter (VAIO PCV-J200)
 
 pci:v00001039d00006306*
  ID_MODEL_FROM_DATABASE=530/620 PCI/AGP VGA Display Adapter
@@ -13269,49 +13497,49 @@ pci:v00001039d00006325*
  ID_MODEL_FROM_DATABASE=65x/M650/740 PCI/AGP VGA Display Adapter
 
 pci:v00001039d00006325sv00001039sd00006325*
- ID_MODEL_FROM_DATABASE=SiS 651 onboard [Asus P4SC-EA]
+ ID_MODEL_FROM_DATABASE=65x/M650/740 PCI/AGP VGA Display Adapter (SiS 651 onboard [Asus P4SC-EA])
 
 pci:v00001039d00006325sv00001631sd00001004*
- ID_MODEL_FROM_DATABASE=SiS 651C onboard [Gigabyte GA-8SIML Rev1.0]
+ ID_MODEL_FROM_DATABASE=65x/M650/740 PCI/AGP VGA Display Adapter (SiS 651C onboard [Gigabyte GA-8SIML Rev1.0])
 
 pci:v00001039d00006326*
  ID_MODEL_FROM_DATABASE=86C326 5598/6326
 
 pci:v00001039d00006326sv00001039sd00006326*
- ID_MODEL_FROM_DATABASE=SiS6326 GUI Accelerator
+ ID_MODEL_FROM_DATABASE=86C326 5598/6326 (SiS6326 GUI Accelerator)
 
 pci:v00001039d00006326sv00001092sd00000A50*
- ID_MODEL_FROM_DATABASE=SpeedStar A50
+ ID_MODEL_FROM_DATABASE=86C326 5598/6326 (SpeedStar A50)
 
 pci:v00001039d00006326sv00001092sd00000A70*
- ID_MODEL_FROM_DATABASE=SpeedStar A70
+ ID_MODEL_FROM_DATABASE=86C326 5598/6326 (SpeedStar A70)
 
 pci:v00001039d00006326sv00001092sd00004910*
- ID_MODEL_FROM_DATABASE=SpeedStar A70
+ ID_MODEL_FROM_DATABASE=86C326 5598/6326 (SpeedStar A70)
 
 pci:v00001039d00006326sv00001092sd00004920*
- ID_MODEL_FROM_DATABASE=SpeedStar A70
+ ID_MODEL_FROM_DATABASE=86C326 5598/6326 (SpeedStar A70)
 
 pci:v00001039d00006326sv000010B0sd00006326*
- ID_MODEL_FROM_DATABASE=S6110-B (AGP)
+ ID_MODEL_FROM_DATABASE=86C326 5598/6326 (S6110-B (AGP))
 
 pci:v00001039d00006326sv00001569sd00006326*
- ID_MODEL_FROM_DATABASE=SiS6326 GUI Accelerator
+ ID_MODEL_FROM_DATABASE=86C326 5598/6326 (SiS6326 GUI Accelerator)
 
 pci:v00001039d00006330*
  ID_MODEL_FROM_DATABASE=661/741/760 PCI/AGP or 662/761Gx PCIE VGA Display Adapter
 
 pci:v00001039d00006330sv00001039sd00006330*
- ID_MODEL_FROM_DATABASE=[M]661xX/[M]741[GX]/[M]760 PCI/AGP VGA Adapter
+ ID_MODEL_FROM_DATABASE=661/741/760 PCI/AGP or 662/761Gx PCIE VGA Display Adapter ([M]661xX/[M]741[GX]/[M]760 PCI/AGP VGA Adapter)
 
 pci:v00001039d00006330sv00001043sd00008113*
- ID_MODEL_FROM_DATABASE=SiS Real 256E (ASUS P5S800-VM motherboard)
+ ID_MODEL_FROM_DATABASE=661/741/760 PCI/AGP or 662/761Gx PCIE VGA Display Adapter (SiS Real 256E (ASUS P5S800-VM motherboard))
 
 pci:v00001039d00006330sv00001458sd0000D000*
- ID_MODEL_FROM_DATABASE=SiS661FX GUI 2D/3D Accelerator
+ ID_MODEL_FROM_DATABASE=661/741/760 PCI/AGP or 662/761Gx PCIE VGA Display Adapter (SiS661FX GUI 2D/3D Accelerator)
 
 pci:v00001039d00006330sv00001734sd00001099*
- ID_MODEL_FROM_DATABASE=D2030-A1
+ ID_MODEL_FROM_DATABASE=661/741/760 PCI/AGP or 662/761Gx PCIE VGA Display Adapter (D2030-A1)
 
 pci:v00001039d00006350*
  ID_MODEL_FROM_DATABASE=770/670 PCIE VGA Display Adapter
@@ -13323,70 +13551,70 @@ pci:v00001039d00007001*
  ID_MODEL_FROM_DATABASE=USB 1.1 Controller
 
 pci:v00001039d00007001sv00001019sd00000A14*
- ID_MODEL_FROM_DATABASE=K7S5A motherboard
+ ID_MODEL_FROM_DATABASE=USB 1.1 Controller (K7S5A motherboard)
 
 pci:v00001039d00007001sv00001039sd00007000*
- ID_MODEL_FROM_DATABASE=Onboard USB Controller
+ ID_MODEL_FROM_DATABASE=USB 1.1 Controller (Onboard USB Controller)
 
 pci:v00001039d00007001sv00001462sd00005470*
- ID_MODEL_FROM_DATABASE=ECS K7SOM+ motherboard
+ ID_MODEL_FROM_DATABASE=USB 1.1 Controller (ECS K7SOM+ motherboard)
 
 pci:v00001039d00007001sv00001462sd00007010*
- ID_MODEL_FROM_DATABASE=MS-6701 motherboard
+ ID_MODEL_FROM_DATABASE=USB 1.1 Controller (MS-6701 motherboard)
 
 pci:v00001039d00007001sv00001734sd00001095*
- ID_MODEL_FROM_DATABASE=D2030-A1 Motherboard
+ ID_MODEL_FROM_DATABASE=USB 1.1 Controller (D2030-A1 Motherboard)
 
 pci:v00001039d00007002*
  ID_MODEL_FROM_DATABASE=USB 2.0 Controller
 
 pci:v00001039d00007002sv00001462sd00005470*
- ID_MODEL_FROM_DATABASE=K7SOM+ 5.2C Motherboard
+ ID_MODEL_FROM_DATABASE=USB 2.0 Controller (K7SOM+ 5.2C Motherboard)
 
 pci:v00001039d00007002sv00001462sd00007010*
- ID_MODEL_FROM_DATABASE=MS-6701 motherboard
+ ID_MODEL_FROM_DATABASE=USB 2.0 Controller (MS-6701 motherboard)
 
 pci:v00001039d00007002sv00001509sd00007002*
- ID_MODEL_FROM_DATABASE=Onboard USB Controller
+ ID_MODEL_FROM_DATABASE=USB 2.0 Controller (Onboard USB Controller)
 
 pci:v00001039d00007002sv00001734sd00001095*
- ID_MODEL_FROM_DATABASE=D2030-A1
+ ID_MODEL_FROM_DATABASE=USB 2.0 Controller (D2030-A1)
 
 pci:v00001039d00007007*
  ID_MODEL_FROM_DATABASE=FireWire Controller
 
 pci:v00001039d00007007sv00001462sd0000701D*
- ID_MODEL_FROM_DATABASE=MS-6701
+ ID_MODEL_FROM_DATABASE=FireWire Controller (MS-6701)
 
 pci:v00001039d00007012*
  ID_MODEL_FROM_DATABASE=SiS7012 AC'97 Sound Controller
 
 pci:v00001039d00007012sv00001019sd00000F05*
- ID_MODEL_FROM_DATABASE=A928 (i-Buddie)
+ ID_MODEL_FROM_DATABASE=SiS7012 AC'97 Sound Controller (A928 (i-Buddie))
 
 pci:v00001039d00007012sv00001039sd00007012*
- ID_MODEL_FROM_DATABASE=SiS 7012 onboard [Asus P4SC-EA] AC'97 Sound Controller
+ ID_MODEL_FROM_DATABASE=SiS7012 AC'97 Sound Controller (SiS 7012 onboard [Asus P4SC-EA] AC'97 Sound Controller)
 
 pci:v00001039d00007012sv00001043sd0000818F*
- ID_MODEL_FROM_DATABASE=A8S-X Motherboard
+ ID_MODEL_FROM_DATABASE=SiS7012 AC'97 Sound Controller (A8S-X Motherboard)
 
 pci:v00001039d00007012sv000013F6sd00000300*
- ID_MODEL_FROM_DATABASE=CMI9739(A) on ECS K7SOM+ motherboard
+ ID_MODEL_FROM_DATABASE=SiS7012 AC'97 Sound Controller (CMI9739(A) on ECS K7SOM+ motherboard)
 
 pci:v00001039d00007012sv00001462sd00005850*
- ID_MODEL_FROM_DATABASE=MSI 648 Max (MS-6585)
+ ID_MODEL_FROM_DATABASE=SiS7012 AC'97 Sound Controller (MSI 648 Max (MS-6585))
 
 pci:v00001039d00007012sv00001462sd00007010*
- ID_MODEL_FROM_DATABASE=MS-6701 motherboard
+ ID_MODEL_FROM_DATABASE=SiS7012 AC'97 Sound Controller (MS-6701 motherboard)
 
 pci:v00001039d00007012sv000015BDsd00001001*
- ID_MODEL_FROM_DATABASE=DFI 661FX motherboard
+ ID_MODEL_FROM_DATABASE=SiS7012 AC'97 Sound Controller (DFI 661FX motherboard)
 
 pci:v00001039d00007012sv00001734sd0000109F*
- ID_MODEL_FROM_DATABASE=D2030-A1 Motherboard
+ ID_MODEL_FROM_DATABASE=SiS7012 AC'97 Sound Controller (D2030-A1 Motherboard)
 
 pci:v00001039d00007012sv00001849sd00007012*
- ID_MODEL_FROM_DATABASE=K7S41GX motherboard
+ ID_MODEL_FROM_DATABASE=SiS7012 AC'97 Sound Controller (K7S41GX motherboard)
 
 pci:v00001039d00007013*
  ID_MODEL_FROM_DATABASE=AC'97 Modem Controller
@@ -13395,7 +13623,7 @@ pci:v00001039d00007016*
  ID_MODEL_FROM_DATABASE=SiS7016 PCI Fast Ethernet Adapter
 
 pci:v00001039d00007016sv00001039sd00007016*
- ID_MODEL_FROM_DATABASE=SiS7016 10/100 Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=SiS7016 PCI Fast Ethernet Adapter (SiS7016 10/100 Ethernet Adapter)
 
 pci:v00001039d00007018*
  ID_MODEL_FROM_DATABASE=SiS PCI Audio Accelerator
@@ -13425,7 +13653,7 @@ pci:v00001039d00007018sv00001043sd0000800B*
  ID_MODEL_FROM_DATABASE=SiS PCI Audio Accelerator
 
 pci:v00001039d00007018sv0000104Dsd000080E2*
- ID_MODEL_FROM_DATABASE=VAIO PCV-J200
+ ID_MODEL_FROM_DATABASE=SiS PCI Audio Accelerator (VAIO PCV-J200)
 
 pci:v00001039d00007018sv00001054sd00007018*
  ID_MODEL_FROM_DATABASE=SiS PCI Audio Accelerator
@@ -13500,25 +13728,25 @@ pci:v0000103Cd00001029*
  ID_MODEL_FROM_DATABASE=Tach XL2 Fibre Channel Host Adapter
 
 pci:v0000103Cd00001029sv0000107Esd0000000F*
- ID_MODEL_FROM_DATABASE=Interphase 5560 Fibre Channel Adapter
+ ID_MODEL_FROM_DATABASE=Tach XL2 Fibre Channel Host Adapter (Interphase 5560 Fibre Channel Adapter)
 
 pci:v0000103Cd00001029sv00009004sd00009210*
- ID_MODEL_FROM_DATABASE=1Gb/2Gb Family Fibre Channel Controller
+ ID_MODEL_FROM_DATABASE=Tach XL2 Fibre Channel Host Adapter (1Gb/2Gb Family Fibre Channel Controller)
 
 pci:v0000103Cd00001029sv00009004sd00009211*
- ID_MODEL_FROM_DATABASE=1Gb/2Gb Family Fibre Channel Controller
+ ID_MODEL_FROM_DATABASE=Tach XL2 Fibre Channel Host Adapter (1Gb/2Gb Family Fibre Channel Controller)
 
 pci:v0000103Cd0000102A*
  ID_MODEL_FROM_DATABASE=Tach TS Fibre Channel Host Adapter
 
 pci:v0000103Cd0000102Asv0000107Esd0000000E*
- ID_MODEL_FROM_DATABASE=Interphase 5540/5541 Fibre Channel Adapter
+ ID_MODEL_FROM_DATABASE=Tach TS Fibre Channel Host Adapter (Interphase 5540/5541 Fibre Channel Adapter)
 
 pci:v0000103Cd0000102Asv00009004sd00009110*
- ID_MODEL_FROM_DATABASE=1Gb/2Gb Family Fibre Channel Controller
+ ID_MODEL_FROM_DATABASE=Tach TS Fibre Channel Host Adapter (1Gb/2Gb Family Fibre Channel Controller)
 
 pci:v0000103Cd0000102Asv00009004sd00009111*
- ID_MODEL_FROM_DATABASE=1Gb/2Gb Family Fibre Channel Controller
+ ID_MODEL_FROM_DATABASE=Tach TS Fibre Channel Host Adapter (1Gb/2Gb Family Fibre Channel Controller)
 
 pci:v0000103Cd00001030*
  ID_MODEL_FROM_DATABASE=J2585A DeskDirect 10/100VG NIC
@@ -13527,13 +13755,13 @@ pci:v0000103Cd00001031*
  ID_MODEL_FROM_DATABASE=J2585B HP 10/100VG PCI LAN Adapter
 
 pci:v0000103Cd00001031sv0000103Csd00001040*
- ID_MODEL_FROM_DATABASE=J2973A DeskDirect 10BaseT NIC
+ ID_MODEL_FROM_DATABASE=J2585B HP 10/100VG PCI LAN Adapter (J2973A DeskDirect 10BaseT NIC)
 
 pci:v0000103Cd00001031sv0000103Csd00001041*
- ID_MODEL_FROM_DATABASE=J2585B DeskDirect 10/100VG NIC
+ ID_MODEL_FROM_DATABASE=J2585B HP 10/100VG PCI LAN Adapter (J2585B DeskDirect 10/100VG NIC)
 
 pci:v0000103Cd00001031sv0000103Csd00001042*
- ID_MODEL_FROM_DATABASE=J2970A DeskDirect 10BaseT/2 NIC
+ ID_MODEL_FROM_DATABASE=J2585B HP 10/100VG PCI LAN Adapter (J2970A DeskDirect 10BaseT/2 NIC)
 
 pci:v0000103Cd00001040*
  ID_MODEL_FROM_DATABASE=J2973A DeskDirect 10BaseT NIC
@@ -13548,28 +13776,28 @@ pci:v0000103Cd00001048*
  ID_MODEL_FROM_DATABASE=Diva Serial [GSP] Multiport UART
 
 pci:v0000103Cd00001048sv0000103Csd00001049*
- ID_MODEL_FROM_DATABASE=Tosca Console
+ ID_MODEL_FROM_DATABASE=Diva Serial [GSP] Multiport UART (Tosca Console)
 
 pci:v0000103Cd00001048sv0000103Csd0000104A*
- ID_MODEL_FROM_DATABASE=Tosca Secondary
+ ID_MODEL_FROM_DATABASE=Diva Serial [GSP] Multiport UART (Tosca Secondary)
 
 pci:v0000103Cd00001048sv0000103Csd0000104B*
- ID_MODEL_FROM_DATABASE=Maestro SP2
+ ID_MODEL_FROM_DATABASE=Diva Serial [GSP] Multiport UART (Maestro SP2)
 
 pci:v0000103Cd00001048sv0000103Csd00001223*
- ID_MODEL_FROM_DATABASE=Superdome Console
+ ID_MODEL_FROM_DATABASE=Diva Serial [GSP] Multiport UART (Superdome Console)
 
 pci:v0000103Cd00001048sv0000103Csd00001226*
- ID_MODEL_FROM_DATABASE=Keystone SP2
+ ID_MODEL_FROM_DATABASE=Diva Serial [GSP] Multiport UART (Keystone SP2)
 
 pci:v0000103Cd00001048sv0000103Csd00001227*
- ID_MODEL_FROM_DATABASE=Powerbar SP2
+ ID_MODEL_FROM_DATABASE=Diva Serial [GSP] Multiport UART (Powerbar SP2)
 
 pci:v0000103Cd00001048sv0000103Csd00001282*
- ID_MODEL_FROM_DATABASE=Everest SP2
+ ID_MODEL_FROM_DATABASE=Diva Serial [GSP] Multiport UART (Everest SP2)
 
 pci:v0000103Cd00001048sv0000103Csd00001301*
- ID_MODEL_FROM_DATABASE=Diva RMP3
+ ID_MODEL_FROM_DATABASE=Diva Serial [GSP] Multiport UART (Diva RMP3)
 
 pci:v0000103Cd00001054*
  ID_MODEL_FROM_DATABASE=PCI Local Bus Adapter
@@ -13623,7 +13851,7 @@ pci:v0000103Cd00001290*
  ID_MODEL_FROM_DATABASE=Auxiliary Diva Serial Port
 
 pci:v0000103Cd00001290sv0000103Csd00001291*
- ID_MODEL_FROM_DATABASE=Diva SP2
+ ID_MODEL_FROM_DATABASE=Auxiliary Diva Serial Port (Diva SP2)
 
 pci:v0000103Cd00001291*
  ID_MODEL_FROM_DATABASE=Auxiliary Diva Serial Port
@@ -13659,151 +13887,208 @@ pci:v0000103Cd00003220*
  ID_MODEL_FROM_DATABASE=Smart Array P600
 
 pci:v0000103Cd00003220sv0000103Csd00003225*
- ID_MODEL_FROM_DATABASE=3 Gb/s SAS RAID
+ ID_MODEL_FROM_DATABASE=Smart Array P600 (3 Gb/s SAS RAID)
 
 pci:v0000103Cd00003230*
  ID_MODEL_FROM_DATABASE=Smart Array Controller
 
 pci:v0000103Cd00003230sv0000103Csd00003223*
- ID_MODEL_FROM_DATABASE=Smart Array P800
+ ID_MODEL_FROM_DATABASE=Smart Array Controller (Smart Array P800)
 
 pci:v0000103Cd00003230sv0000103Csd00003234*
- ID_MODEL_FROM_DATABASE=P400 SAS Controller
+ ID_MODEL_FROM_DATABASE=Smart Array Controller (P400 SAS Controller)
 
 pci:v0000103Cd00003230sv0000103Csd00003235*
- ID_MODEL_FROM_DATABASE=P400i SAS Controller
+ ID_MODEL_FROM_DATABASE=Smart Array Controller (P400i SAS Controller)
 
 pci:v0000103Cd00003230sv0000103Csd00003237*
- ID_MODEL_FROM_DATABASE=E500 SAS Controller
+ ID_MODEL_FROM_DATABASE=Smart Array Controller (E500 SAS Controller)
 
 pci:v0000103Cd00003230sv0000103Csd0000323D*
- ID_MODEL_FROM_DATABASE=P700m SAS Controller
+ ID_MODEL_FROM_DATABASE=Smart Array Controller (P700m SAS Controller)
 
 pci:v0000103Cd00003238*
  ID_MODEL_FROM_DATABASE=Smart Array E200i (SAS Controller)
 
 pci:v0000103Cd00003238sv0000103Csd00003211*
- ID_MODEL_FROM_DATABASE=Smart Array E200i
+ ID_MODEL_FROM_DATABASE=Smart Array E200i (SAS Controller) (Smart Array E200i)
 
 pci:v0000103Cd00003238sv0000103Csd00003212*
- ID_MODEL_FROM_DATABASE=Smart Array E200
+ ID_MODEL_FROM_DATABASE=Smart Array E200i (SAS Controller) (Smart Array E200)
+
+pci:v0000103Cd00003239*
+ ID_MODEL_FROM_DATABASE=Smart Array Gen9 Controllers
+
+pci:v0000103Cd00003239sv0000103Csd000021BD*
+ ID_MODEL_FROM_DATABASE=Smart Array Gen9 Controllers (Smart Array)
+
+pci:v0000103Cd00003239sv0000103Csd000021BE*
+ ID_MODEL_FROM_DATABASE=Smart Array Gen9 Controllers (Smart Array)
+
+pci:v0000103Cd00003239sv0000103Csd000021BF*
+ ID_MODEL_FROM_DATABASE=Smart Array Gen9 Controllers (Smart Array)
+
+pci:v0000103Cd00003239sv0000103Csd000021C0*
+ ID_MODEL_FROM_DATABASE=Smart Array Gen9 Controllers (Smart Array)
+
+pci:v0000103Cd00003239sv0000103Csd000021C1*
+ ID_MODEL_FROM_DATABASE=Smart Array Gen9 Controllers (Smart Array)
+
+pci:v0000103Cd00003239sv0000103Csd000021C2*
+ ID_MODEL_FROM_DATABASE=Smart Array Gen9 Controllers (Smart Array)
+
+pci:v0000103Cd00003239sv0000103Csd000021C3*
+ ID_MODEL_FROM_DATABASE=Smart Array Gen9 Controllers (Smart Array)
+
+pci:v0000103Cd00003239sv0000103Csd000021C4*
+ ID_MODEL_FROM_DATABASE=Smart Array Gen9 Controllers (Smart Array)
+
+pci:v0000103Cd00003239sv0000103Csd000021C5*
+ ID_MODEL_FROM_DATABASE=Smart Array Gen9 Controllers (Smart Array)
+
+pci:v0000103Cd00003239sv0000103Csd000021C6*
+ ID_MODEL_FROM_DATABASE=Smart Array Gen9 Controllers (Smart Array)
+
+pci:v0000103Cd00003239sv0000103Csd000021C7*
+ ID_MODEL_FROM_DATABASE=Smart Array Gen9 Controllers (Smart Array)
+
+pci:v0000103Cd00003239sv0000103Csd000021C8*
+ ID_MODEL_FROM_DATABASE=Smart Array Gen9 Controllers (Smart Array)
+
+pci:v0000103Cd00003239sv0000103Csd000021C9*
+ ID_MODEL_FROM_DATABASE=Smart Array Gen9 Controllers (Smart Array)
+
+pci:v0000103Cd00003239sv0000103Csd000021CA*
+ ID_MODEL_FROM_DATABASE=Smart Array Gen9 Controllers (Smart Array)
+
+pci:v0000103Cd00003239sv0000103Csd000021CB*
+ ID_MODEL_FROM_DATABASE=Smart Array Gen9 Controllers (Smart Array)
+
+pci:v0000103Cd00003239sv0000103Csd000021CC*
+ ID_MODEL_FROM_DATABASE=Smart Array Gen9 Controllers (Smart Array)
+
+pci:v0000103Cd00003239sv0000103Csd000021CD*
+ ID_MODEL_FROM_DATABASE=Smart Array Gen9 Controllers (Smart Array)
+
+pci:v0000103Cd00003239sv0000103Csd000021CE*
+ ID_MODEL_FROM_DATABASE=Smart Array Gen9 Controllers (Smart Array)
 
 pci:v0000103Cd0000323A*
  ID_MODEL_FROM_DATABASE=Smart Array G6 controllers
 
 pci:v0000103Cd0000323Asv0000103Csd00003241*
- ID_MODEL_FROM_DATABASE=Smart Array P212
+ ID_MODEL_FROM_DATABASE=Smart Array G6 controllers (Smart Array P212)
 
 pci:v0000103Cd0000323Asv0000103Csd00003243*
- ID_MODEL_FROM_DATABASE=Smart Array P410
+ ID_MODEL_FROM_DATABASE=Smart Array G6 controllers (Smart Array P410)
 
 pci:v0000103Cd0000323Asv0000103Csd00003245*
- ID_MODEL_FROM_DATABASE=Smart Array P410i
+ ID_MODEL_FROM_DATABASE=Smart Array G6 controllers (Smart Array P410i)
 
 pci:v0000103Cd0000323Asv0000103Csd00003247*
- ID_MODEL_FROM_DATABASE=Smart Array P411
+ ID_MODEL_FROM_DATABASE=Smart Array G6 controllers (Smart Array P411)
 
 pci:v0000103Cd0000323Asv0000103Csd00003249*
- ID_MODEL_FROM_DATABASE=Smart Array P812
+ ID_MODEL_FROM_DATABASE=Smart Array G6 controllers (Smart Array P812)
 
 pci:v0000103Cd0000323Asv0000103Csd0000324A*
- ID_MODEL_FROM_DATABASE=HP Smart Array 712m (Mezzanine RAID controller)
+ ID_MODEL_FROM_DATABASE=Smart Array G6 controllers (HP Smart Array 712m (Mezzanine RAID controller))
 
 pci:v0000103Cd0000323Asv0000103Csd0000324B*
- ID_MODEL_FROM_DATABASE=Smart Array P711m (Mezzanine RAID controller)
+ ID_MODEL_FROM_DATABASE=Smart Array G6 controllers (Smart Array P711m (Mezzanine RAID controller))
 
 pci:v0000103Cd0000323B*
  ID_MODEL_FROM_DATABASE=Smart Array Gen8 Controllers
 
 pci:v0000103Cd0000323Bsv0000103Csd00003350*
- ID_MODEL_FROM_DATABASE=P222
+ ID_MODEL_FROM_DATABASE=Smart Array Gen8 Controllers (P222)
 
 pci:v0000103Cd0000323Bsv0000103Csd00003351*
- ID_MODEL_FROM_DATABASE=P420
+ ID_MODEL_FROM_DATABASE=Smart Array Gen8 Controllers (P420)
 
 pci:v0000103Cd0000323Bsv0000103Csd00003352*
- ID_MODEL_FROM_DATABASE=P421
+ ID_MODEL_FROM_DATABASE=Smart Array Gen8 Controllers (P421)
 
 pci:v0000103Cd0000323Bsv0000103Csd00003354*
- ID_MODEL_FROM_DATABASE=P420i
+ ID_MODEL_FROM_DATABASE=Smart Array Gen8 Controllers (P420i)
 
 pci:v0000103Cd0000323Bsv0000103Csd00003355*
- ID_MODEL_FROM_DATABASE=P220i
+ ID_MODEL_FROM_DATABASE=Smart Array Gen8 Controllers (P220i)
 
 pci:v0000103Cd0000323C*
  ID_MODEL_FROM_DATABASE=Smart Array Gen8+ Controllers
 
 pci:v0000103Cd0000323Csv0000103Csd00001920*
- ID_MODEL_FROM_DATABASE=P430i
+ ID_MODEL_FROM_DATABASE=Smart Array Gen8+ Controllers (P430i)
 
 pci:v0000103Cd0000323Csv0000103Csd00001921*
- ID_MODEL_FROM_DATABASE=P830i
+ ID_MODEL_FROM_DATABASE=Smart Array Gen8+ Controllers (P830i)
 
 pci:v0000103Cd0000323Csv0000103Csd00001922*
- ID_MODEL_FROM_DATABASE=P430
+ ID_MODEL_FROM_DATABASE=Smart Array Gen8+ Controllers (P430)
 
 pci:v0000103Cd0000323Csv0000103Csd00001923*
- ID_MODEL_FROM_DATABASE=P431
+ ID_MODEL_FROM_DATABASE=Smart Array Gen8+ Controllers (P431)
 
 pci:v0000103Cd0000323Csv0000103Csd00001924*
- ID_MODEL_FROM_DATABASE=P830
+ ID_MODEL_FROM_DATABASE=Smart Array Gen8+ Controllers (P830)
 
 pci:v0000103Cd0000323Csv0000103Csd00001925*
- ID_MODEL_FROM_DATABASE=Smart Array
+ ID_MODEL_FROM_DATABASE=Smart Array Gen8+ Controllers (Smart Array)
 
 pci:v0000103Cd0000323Csv0000103Csd00001926*
- ID_MODEL_FROM_DATABASE=P731m
+ ID_MODEL_FROM_DATABASE=Smart Array Gen8+ Controllers (P731m)
 
 pci:v0000103Cd0000323Csv0000103Csd00001928*
- ID_MODEL_FROM_DATABASE=P230i
+ ID_MODEL_FROM_DATABASE=Smart Array Gen8+ Controllers (P230i)
 
 pci:v0000103Cd00003300*
  ID_MODEL_FROM_DATABASE=Integrated Lights-Out Standard Virtual USB Controller
 
 pci:v0000103Cd00003300sv0000103Csd00003304*
- ID_MODEL_FROM_DATABASE=iLO2
+ ID_MODEL_FROM_DATABASE=Integrated Lights-Out Standard Virtual USB Controller (iLO2)
 
 pci:v0000103Cd00003300sv0000103Csd00003305*
- ID_MODEL_FROM_DATABASE=iLO2
+ ID_MODEL_FROM_DATABASE=Integrated Lights-Out Standard Virtual USB Controller (iLO2)
 
 pci:v0000103Cd00003300sv0000103Csd00003309*
- ID_MODEL_FROM_DATABASE=iLO2 GXL/iLO3 GXE
+ ID_MODEL_FROM_DATABASE=Integrated Lights-Out Standard Virtual USB Controller (iLO2 GXL/iLO3 GXE)
 
 pci:v0000103Cd00003300sv0000103Csd0000330E*
- ID_MODEL_FROM_DATABASE=iLO3
+ ID_MODEL_FROM_DATABASE=Integrated Lights-Out Standard Virtual USB Controller (iLO3)
 
 pci:v0000103Cd00003300sv0000103Csd00003381*
- ID_MODEL_FROM_DATABASE=iLO4
+ ID_MODEL_FROM_DATABASE=Integrated Lights-Out Standard Virtual USB Controller (iLO4)
 
 pci:v0000103Cd00003301*
  ID_MODEL_FROM_DATABASE=Integrated Lights-Out Standard Serial Port
 
 pci:v0000103Cd00003301sv0000103Csd00003304*
- ID_MODEL_FROM_DATABASE=iLO2
+ ID_MODEL_FROM_DATABASE=Integrated Lights-Out Standard Serial Port (iLO2)
 
 pci:v0000103Cd00003301sv0000103Csd00003305*
- ID_MODEL_FROM_DATABASE=iLO2
+ ID_MODEL_FROM_DATABASE=Integrated Lights-Out Standard Serial Port (iLO2)
 
 pci:v0000103Cd00003301sv0000103Csd0000330E*
- ID_MODEL_FROM_DATABASE=iLO3
+ ID_MODEL_FROM_DATABASE=Integrated Lights-Out Standard Serial Port (iLO3)
 
 pci:v0000103Cd00003301sv0000103Csd00003381*
- ID_MODEL_FROM_DATABASE=iLO4
+ ID_MODEL_FROM_DATABASE=Integrated Lights-Out Standard Serial Port (iLO4)
 
 pci:v0000103Cd00003302*
  ID_MODEL_FROM_DATABASE=Integrated Lights-Out Standard KCS Interface
 
 pci:v0000103Cd00003302sv0000103Csd00003304*
- ID_MODEL_FROM_DATABASE=iLO2
+ ID_MODEL_FROM_DATABASE=Integrated Lights-Out Standard KCS Interface (iLO2)
 
 pci:v0000103Cd00003302sv0000103Csd00003305*
- ID_MODEL_FROM_DATABASE=iLO2
+ ID_MODEL_FROM_DATABASE=Integrated Lights-Out Standard KCS Interface (iLO2)
 
 pci:v0000103Cd00003302sv0000103Csd0000330E*
- ID_MODEL_FROM_DATABASE=iLO3
+ ID_MODEL_FROM_DATABASE=Integrated Lights-Out Standard KCS Interface (iLO3)
 
 pci:v0000103Cd00003302sv0000103Csd00003381*
- ID_MODEL_FROM_DATABASE=iLO4
+ ID_MODEL_FROM_DATABASE=Integrated Lights-Out Standard KCS Interface (iLO4)
 
 pci:v0000103Cd00003305*
  ID_MODEL_FROM_DATABASE=Integrated Lights-Out (iLO2) Controller
@@ -13812,31 +14097,31 @@ pci:v0000103Cd00003306*
  ID_MODEL_FROM_DATABASE=Integrated Lights-Out Standard Slave Instrumentation & System Support
 
 pci:v0000103Cd00003306sv0000103Csd0000330E*
- ID_MODEL_FROM_DATABASE=iLO3
+ ID_MODEL_FROM_DATABASE=Integrated Lights-Out Standard Slave Instrumentation & System Support (iLO3)
 
 pci:v0000103Cd00003306sv0000103Csd00003381*
- ID_MODEL_FROM_DATABASE=iLO4
+ ID_MODEL_FROM_DATABASE=Integrated Lights-Out Standard Slave Instrumentation & System Support (iLO4)
 
 pci:v0000103Cd00003307*
  ID_MODEL_FROM_DATABASE=Integrated Lights-Out Standard Management Processor Support and Messaging
 
 pci:v0000103Cd00003307sv0000103Csd00003309*
- ID_MODEL_FROM_DATABASE=iLO 2
+ ID_MODEL_FROM_DATABASE=Integrated Lights-Out Standard Management Processor Support and Messaging (iLO 2)
 
 pci:v0000103Cd00003307sv0000103Csd0000330E*
- ID_MODEL_FROM_DATABASE=iLO3
+ ID_MODEL_FROM_DATABASE=Integrated Lights-Out Standard Management Processor Support and Messaging (iLO3)
 
 pci:v0000103Cd00003307sv0000103Csd00003381*
- ID_MODEL_FROM_DATABASE=iLO4
+ ID_MODEL_FROM_DATABASE=Integrated Lights-Out Standard Management Processor Support and Messaging (iLO4)
 
 pci:v0000103Cd00003308*
  ID_MODEL_FROM_DATABASE=Integrated Lights-Out Standard MS Watchdog Timer
 
 pci:v0000103Cd00003308sv0000103Csd0000330E*
- ID_MODEL_FROM_DATABASE=iLO3
+ ID_MODEL_FROM_DATABASE=Integrated Lights-Out Standard MS Watchdog Timer (iLO3)
 
 pci:v0000103Cd00003308sv0000103Csd00003381*
- ID_MODEL_FROM_DATABASE=iLO4
+ ID_MODEL_FROM_DATABASE=Integrated Lights-Out Standard MS Watchdog Timer (iLO4)
 
 pci:v0000103Cd0000402F*
  ID_MODEL_FROM_DATABASE=PCIe Root Port
@@ -13853,9 +14138,6 @@ pci:v0000103Cd00004037*
 pci:v0000103Cd0000403B*
  ID_MODEL_FROM_DATABASE=PCIe Root Port
 
-pci:v0000103Cd000060E8*
- ID_MODEL_FROM_DATABASE=NetRAID-2M : ZX1/M (OEM AMI MegaRAID 493)
-
 pci:v0000103E*
  ID_VENDOR_FROM_DATABASE=Solliday Engineering
 
@@ -13889,23 +14171,26 @@ pci:v00001042d00003020*
 pci:v00001043*
  ID_VENDOR_FROM_DATABASE=ASUSTeK Computer Inc.
 
+pci:v00001043d00000464*
+ ID_MODEL_FROM_DATABASE=Radeon R9 270x GPU
+
 pci:v00001043d00000675*
  ID_MODEL_FROM_DATABASE=ISDNLink P-IN100-ST-D
 
 pci:v00001043d00000675sv00000675sd00001704*
- ID_MODEL_FROM_DATABASE=ISDN Adapter (PCI Bus, D, C)
+ ID_MODEL_FROM_DATABASE=ISDNLink P-IN100-ST-D (ISDN Adapter (PCI Bus, D, C))
 
 pci:v00001043d00000675sv00000675sd00001707*
- ID_MODEL_FROM_DATABASE=ISDN Adapter (PCI Bus, DV, W)
+ ID_MODEL_FROM_DATABASE=ISDNLink P-IN100-ST-D (ISDN Adapter (PCI Bus, DV, W))
 
 pci:v00001043d00000675sv000010CFsd0000105E*
- ID_MODEL_FROM_DATABASE=ISDN Adapter (PCI Bus, DV, W)
+ ID_MODEL_FROM_DATABASE=ISDNLink P-IN100-ST-D (ISDN Adapter (PCI Bus, DV, W))
 
 pci:v00001043d00009602*
  ID_MODEL_FROM_DATABASE=AMD RS780/RS880 PCI to PCI bridge (int gfx)
 
 pci:v00001043d00009602sv00001043sd000083A2*
- ID_MODEL_FROM_DATABASE=M4A785TD Motherboard
+ ID_MODEL_FROM_DATABASE=AMD RS780/RS880 PCI to PCI bridge (int gfx) (M4A785TD Motherboard)
 
 pci:v00001044*
  ID_VENDOR_FROM_DATABASE=Adaptec (formerly DPT)
@@ -13923,118 +14208,118 @@ pci:v00001044d0000A501*
  ID_MODEL_FROM_DATABASE=SmartRAID V Controller
 
 pci:v00001044d0000A501sv00001044sd0000C001*
- ID_MODEL_FROM_DATABASE=PM1554U2 Ultra2 Single Channel
+ ID_MODEL_FROM_DATABASE=SmartRAID V Controller (PM1554U2 Ultra2 Single Channel)
 
 pci:v00001044d0000A501sv00001044sd0000C002*
- ID_MODEL_FROM_DATABASE=PM1654U2 Ultra2 Single Channel
+ ID_MODEL_FROM_DATABASE=SmartRAID V Controller (PM1654U2 Ultra2 Single Channel)
 
 pci:v00001044d0000A501sv00001044sd0000C003*
- ID_MODEL_FROM_DATABASE=PM1564U3 Ultra3 Single Channel
+ ID_MODEL_FROM_DATABASE=SmartRAID V Controller (PM1564U3 Ultra3 Single Channel)
 
 pci:v00001044d0000A501sv00001044sd0000C004*
- ID_MODEL_FROM_DATABASE=PM1564U3 Ultra3 Dual Channel
+ ID_MODEL_FROM_DATABASE=SmartRAID V Controller (PM1564U3 Ultra3 Dual Channel)
 
 pci:v00001044d0000A501sv00001044sd0000C005*
- ID_MODEL_FROM_DATABASE=PM1554U2 Ultra2 Single Channel (NON ACPI)
+ ID_MODEL_FROM_DATABASE=SmartRAID V Controller (PM1554U2 Ultra2 Single Channel (NON ACPI))
 
 pci:v00001044d0000A501sv00001044sd0000C00A*
- ID_MODEL_FROM_DATABASE=PM2554U2 Ultra2 Single Channel
+ ID_MODEL_FROM_DATABASE=SmartRAID V Controller (PM2554U2 Ultra2 Single Channel)
 
 pci:v00001044d0000A501sv00001044sd0000C00B*
- ID_MODEL_FROM_DATABASE=PM2654U2 Ultra2 Single Channel
+ ID_MODEL_FROM_DATABASE=SmartRAID V Controller (PM2654U2 Ultra2 Single Channel)
 
 pci:v00001044d0000A501sv00001044sd0000C00C*
- ID_MODEL_FROM_DATABASE=PM2664U3 Ultra3 Single Channel
+ ID_MODEL_FROM_DATABASE=SmartRAID V Controller (PM2664U3 Ultra3 Single Channel)
 
 pci:v00001044d0000A501sv00001044sd0000C00D*
- ID_MODEL_FROM_DATABASE=PM2664U3 Ultra3 Dual Channel
+ ID_MODEL_FROM_DATABASE=SmartRAID V Controller (PM2664U3 Ultra3 Dual Channel)
 
 pci:v00001044d0000A501sv00001044sd0000C00E*
- ID_MODEL_FROM_DATABASE=PM2554U2 Ultra2 Single Channel (NON ACPI)
+ ID_MODEL_FROM_DATABASE=SmartRAID V Controller (PM2554U2 Ultra2 Single Channel (NON ACPI))
 
 pci:v00001044d0000A501sv00001044sd0000C00F*
- ID_MODEL_FROM_DATABASE=PM2654U2 Ultra2 Single Channel (NON ACPI)
+ ID_MODEL_FROM_DATABASE=SmartRAID V Controller (PM2654U2 Ultra2 Single Channel (NON ACPI))
 
 pci:v00001044d0000A501sv00001044sd0000C014*
- ID_MODEL_FROM_DATABASE=PM3754U2 Ultra2 Single Channel (NON ACPI)
+ ID_MODEL_FROM_DATABASE=SmartRAID V Controller (PM3754U2 Ultra2 Single Channel (NON ACPI))
 
 pci:v00001044d0000A501sv00001044sd0000C015*
- ID_MODEL_FROM_DATABASE=PM3755U2B Ultra2 Single Channel (NON ACPI)
+ ID_MODEL_FROM_DATABASE=SmartRAID V Controller (PM3755U2B Ultra2 Single Channel (NON ACPI))
 
 pci:v00001044d0000A501sv00001044sd0000C016*
- ID_MODEL_FROM_DATABASE=PM3755F Fibre Channel (NON ACPI)
+ ID_MODEL_FROM_DATABASE=SmartRAID V Controller (PM3755F Fibre Channel (NON ACPI))
 
 pci:v00001044d0000A501sv00001044sd0000C01E*
- ID_MODEL_FROM_DATABASE=PM3757U2 Ultra2 Single Channel
+ ID_MODEL_FROM_DATABASE=SmartRAID V Controller (PM3757U2 Ultra2 Single Channel)
 
 pci:v00001044d0000A501sv00001044sd0000C01F*
- ID_MODEL_FROM_DATABASE=PM3757U2 Ultra2 Dual Channel
+ ID_MODEL_FROM_DATABASE=SmartRAID V Controller (PM3757U2 Ultra2 Dual Channel)
 
 pci:v00001044d0000A501sv00001044sd0000C020*
- ID_MODEL_FROM_DATABASE=PM3767U3 Ultra3 Dual Channel
+ ID_MODEL_FROM_DATABASE=SmartRAID V Controller (PM3767U3 Ultra3 Dual Channel)
 
 pci:v00001044d0000A501sv00001044sd0000C021*
- ID_MODEL_FROM_DATABASE=PM3767U3 Ultra3 Quad Channel
+ ID_MODEL_FROM_DATABASE=SmartRAID V Controller (PM3767U3 Ultra3 Quad Channel)
 
 pci:v00001044d0000A501sv00001044sd0000C028*
- ID_MODEL_FROM_DATABASE=PM2865U3 Ultra3 Single Channel
+ ID_MODEL_FROM_DATABASE=SmartRAID V Controller (PM2865U3 Ultra3 Single Channel)
 
 pci:v00001044d0000A501sv00001044sd0000C029*
- ID_MODEL_FROM_DATABASE=PM2865U3 Ultra3 Dual Channel
+ ID_MODEL_FROM_DATABASE=SmartRAID V Controller (PM2865U3 Ultra3 Dual Channel)
 
 pci:v00001044d0000A501sv00001044sd0000C02A*
- ID_MODEL_FROM_DATABASE=PM2865F Fibre Channel
+ ID_MODEL_FROM_DATABASE=SmartRAID V Controller (PM2865F Fibre Channel)
 
 pci:v00001044d0000A501sv00001044sd0000C03C*
- ID_MODEL_FROM_DATABASE=2000S Ultra3 Single Channel
+ ID_MODEL_FROM_DATABASE=SmartRAID V Controller (2000S Ultra3 Single Channel)
 
 pci:v00001044d0000A501sv00001044sd0000C03D*
- ID_MODEL_FROM_DATABASE=2000S Ultra3 Dual Channel
+ ID_MODEL_FROM_DATABASE=SmartRAID V Controller (2000S Ultra3 Dual Channel)
 
 pci:v00001044d0000A501sv00001044sd0000C03E*
- ID_MODEL_FROM_DATABASE=2000F Fibre Channel
+ ID_MODEL_FROM_DATABASE=SmartRAID V Controller (2000F Fibre Channel)
 
 pci:v00001044d0000A501sv00001044sd0000C046*
- ID_MODEL_FROM_DATABASE=3000S Ultra3 Single Channel
+ ID_MODEL_FROM_DATABASE=SmartRAID V Controller (3000S Ultra3 Single Channel)
 
 pci:v00001044d0000A501sv00001044sd0000C047*
- ID_MODEL_FROM_DATABASE=3000S Ultra3 Dual Channel
+ ID_MODEL_FROM_DATABASE=SmartRAID V Controller (3000S Ultra3 Dual Channel)
 
 pci:v00001044d0000A501sv00001044sd0000C048*
- ID_MODEL_FROM_DATABASE=3000F Fibre Channel
+ ID_MODEL_FROM_DATABASE=SmartRAID V Controller (3000F Fibre Channel)
 
 pci:v00001044d0000A501sv00001044sd0000C050*
- ID_MODEL_FROM_DATABASE=5000S Ultra3 Single Channel
+ ID_MODEL_FROM_DATABASE=SmartRAID V Controller (5000S Ultra3 Single Channel)
 
 pci:v00001044d0000A501sv00001044sd0000C051*
- ID_MODEL_FROM_DATABASE=5000S Ultra3 Dual Channel
+ ID_MODEL_FROM_DATABASE=SmartRAID V Controller (5000S Ultra3 Dual Channel)
 
 pci:v00001044d0000A501sv00001044sd0000C052*
- ID_MODEL_FROM_DATABASE=5000F Fibre Channel
+ ID_MODEL_FROM_DATABASE=SmartRAID V Controller (5000F Fibre Channel)
 
 pci:v00001044d0000A501sv00001044sd0000C05A*
- ID_MODEL_FROM_DATABASE=2400A UDMA Four Channel
+ ID_MODEL_FROM_DATABASE=SmartRAID V Controller (2400A UDMA Four Channel)
 
 pci:v00001044d0000A501sv00001044sd0000C05B*
- ID_MODEL_FROM_DATABASE=2400A UDMA Four Channel DAC
+ ID_MODEL_FROM_DATABASE=SmartRAID V Controller (2400A UDMA Four Channel DAC)
 
 pci:v00001044d0000A501sv00001044sd0000C064*
- ID_MODEL_FROM_DATABASE=3010S Ultra3 Dual Channel
+ ID_MODEL_FROM_DATABASE=SmartRAID V Controller (3010S Ultra3 Dual Channel)
 
 pci:v00001044d0000A501sv00001044sd0000C065*
- ID_MODEL_FROM_DATABASE=3410S Ultra160 Four Channel
+ ID_MODEL_FROM_DATABASE=SmartRAID V Controller (3410S Ultra160 Four Channel)
 
 pci:v00001044d0000A501sv00001044sd0000C066*
- ID_MODEL_FROM_DATABASE=3010S Fibre Channel
+ ID_MODEL_FROM_DATABASE=SmartRAID V Controller (3010S Fibre Channel)
 
 pci:v00001044d0000A511*
  ID_MODEL_FROM_DATABASE=SmartRAID V Controller
 
 pci:v00001044d0000A511sv00001044sd0000C032*
- ID_MODEL_FROM_DATABASE=ASR-2005S I2O Zero Channel
+ ID_MODEL_FROM_DATABASE=SmartRAID V Controller (ASR-2005S I2O Zero Channel)
 
 pci:v00001044d0000A511sv00001044sd0000C035*
- ID_MODEL_FROM_DATABASE=ASR-2010S I2O Zero Channel
+ ID_MODEL_FROM_DATABASE=SmartRAID V Controller (ASR-2010S I2O Zero Channel)
 
 pci:v00001044d0000C066*
  ID_MODEL_FROM_DATABASE=3010S Ultra3 Dual Channel
@@ -14136,7 +14421,7 @@ pci:v00001048d00008901*
  ID_MODEL_FROM_DATABASE=Gloria XL
 
 pci:v00001048d00008901sv00001048sd00000935*
- ID_MODEL_FROM_DATABASE=GLoria XL (Virge)
+ ID_MODEL_FROM_DATABASE=Gloria XL (GLoria XL (Virge))
 
 pci:v00001049*
  ID_VENDOR_FROM_DATABASE=Fountain Technologies, Inc.
@@ -14157,16 +14442,19 @@ pci:v0000104Ad00000010*
  ID_MODEL_FROM_DATABASE=STG4000 [3D Prophet Kyro Series]
 
 pci:v0000104Ad00000010sv0000104Asd00004018*
- ID_MODEL_FROM_DATABASE=ST PowerVR Kyro (64MB AGP TVO)
+ ID_MODEL_FROM_DATABASE=STG4000 [3D Prophet Kyro Series] (ST PowerVR Kyro (64MB AGP TVO))
+
+pci:v0000104Ad00000010sv00001681sd00000010*
+ ID_MODEL_FROM_DATABASE=STG4000 [3D Prophet Kyro Series] (PowerVR Kyro II [3D Prophet 4500])
 
 pci:v0000104Ad00000010sv00001681sd00000028*
- ID_MODEL_FROM_DATABASE=3D Prophet 4000XT
+ ID_MODEL_FROM_DATABASE=STG4000 [3D Prophet Kyro Series] (3D Prophet 4000XT)
 
 pci:v0000104Ad00000010sv00001681sd0000C010*
- ID_MODEL_FROM_DATABASE=3D Prophet 4500 TV-Out
+ ID_MODEL_FROM_DATABASE=STG4000 [3D Prophet Kyro Series] (3D Prophet 4500 TV-Out)
 
 pci:v0000104Ad00000010sv00001681sd0000C069*
- ID_MODEL_FROM_DATABASE=3D Prophet 4000XT
+ ID_MODEL_FROM_DATABASE=STG4000 [3D Prophet Kyro Series] (3D Prophet 4000XT)
 
 pci:v0000104Ad00000201*
  ID_MODEL_FROM_DATABASE=STPC Vega Northbridge
@@ -14208,7 +14496,7 @@ pci:v0000104Ad00000500*
  ID_MODEL_FROM_DATABASE=ST70137 [Unicorn] ADSL DMT Transceiver
 
 pci:v0000104Ad00000500sv0000104Asd00000500*
- ID_MODEL_FROM_DATABASE=BeWAN ADSL PCI st
+ ID_MODEL_FROM_DATABASE=ST70137 [Unicorn] ADSL DMT Transceiver (BeWAN ADSL PCI st)
 
 pci:v0000104Ad00000564*
  ID_MODEL_FROM_DATABASE=STPC Client Northbridge
@@ -14262,115 +14550,115 @@ pci:v0000104Cd00003D07*
  ID_MODEL_FROM_DATABASE=TVP4020 [Permedia 2]
 
 pci:v0000104Cd00003D07sv00001011sd00004D10*
- ID_MODEL_FROM_DATABASE=Comet
+ ID_MODEL_FROM_DATABASE=TVP4020 [Permedia 2] (Comet)
 
 pci:v0000104Cd00003D07sv00001040sd0000000F*
- ID_MODEL_FROM_DATABASE=AccelStar II
+ ID_MODEL_FROM_DATABASE=TVP4020 [Permedia 2] (AccelStar II)
 
 pci:v0000104Cd00003D07sv00001040sd00000011*
- ID_MODEL_FROM_DATABASE=AccelStar II
+ ID_MODEL_FROM_DATABASE=TVP4020 [Permedia 2] (AccelStar II)
 
 pci:v0000104Cd00003D07sv00001048sd00000A31*
- ID_MODEL_FROM_DATABASE=WINNER 2000
+ ID_MODEL_FROM_DATABASE=TVP4020 [Permedia 2] (WINNER 2000)
 
 pci:v0000104Cd00003D07sv00001048sd00000A32*
- ID_MODEL_FROM_DATABASE=GLoria Synergy
+ ID_MODEL_FROM_DATABASE=TVP4020 [Permedia 2] (GLoria Synergy)
 
 pci:v0000104Cd00003D07sv00001048sd00000A34*
- ID_MODEL_FROM_DATABASE=GLoria Synergy
+ ID_MODEL_FROM_DATABASE=TVP4020 [Permedia 2] (GLoria Synergy)
 
 pci:v0000104Cd00003D07sv00001048sd00000A35*
- ID_MODEL_FROM_DATABASE=GLoria Synergy
+ ID_MODEL_FROM_DATABASE=TVP4020 [Permedia 2] (GLoria Synergy)
 
 pci:v0000104Cd00003D07sv00001048sd00000A36*
- ID_MODEL_FROM_DATABASE=GLoria Synergy
+ ID_MODEL_FROM_DATABASE=TVP4020 [Permedia 2] (GLoria Synergy)
 
 pci:v0000104Cd00003D07sv00001048sd00000A43*
- ID_MODEL_FROM_DATABASE=GLoria Synergy
+ ID_MODEL_FROM_DATABASE=TVP4020 [Permedia 2] (GLoria Synergy)
 
 pci:v0000104Cd00003D07sv00001048sd00000A44*
- ID_MODEL_FROM_DATABASE=GLoria Synergy
+ ID_MODEL_FROM_DATABASE=TVP4020 [Permedia 2] (GLoria Synergy)
 
 pci:v0000104Cd00003D07sv0000107Dsd00002633*
- ID_MODEL_FROM_DATABASE=WinFast 3D L2300
+ ID_MODEL_FROM_DATABASE=TVP4020 [Permedia 2] (WinFast 3D L2300)
 
 pci:v0000104Cd00003D07sv00001092sd00000126*
- ID_MODEL_FROM_DATABASE=FIRE GL 1000 PRO
+ ID_MODEL_FROM_DATABASE=TVP4020 [Permedia 2] (FIRE GL 1000 PRO)
 
 pci:v0000104Cd00003D07sv00001092sd00000127*
- ID_MODEL_FROM_DATABASE=FIRE GL 1000 PRO
+ ID_MODEL_FROM_DATABASE=TVP4020 [Permedia 2] (FIRE GL 1000 PRO)
 
 pci:v0000104Cd00003D07sv00001092sd00000136*
- ID_MODEL_FROM_DATABASE=FIRE GL 1000 PRO
+ ID_MODEL_FROM_DATABASE=TVP4020 [Permedia 2] (FIRE GL 1000 PRO)
 
 pci:v0000104Cd00003D07sv00001092sd00000141*
- ID_MODEL_FROM_DATABASE=FIRE GL 1000 PRO
+ ID_MODEL_FROM_DATABASE=TVP4020 [Permedia 2] (FIRE GL 1000 PRO)
 
 pci:v0000104Cd00003D07sv00001092sd00000146*
- ID_MODEL_FROM_DATABASE=FIRE GL 1000 PRO
+ ID_MODEL_FROM_DATABASE=TVP4020 [Permedia 2] (FIRE GL 1000 PRO)
 
 pci:v0000104Cd00003D07sv00001092sd00000148*
- ID_MODEL_FROM_DATABASE=FIRE GL 1000 PRO
+ ID_MODEL_FROM_DATABASE=TVP4020 [Permedia 2] (FIRE GL 1000 PRO)
 
 pci:v0000104Cd00003D07sv00001092sd00000149*
- ID_MODEL_FROM_DATABASE=FIRE GL 1000 PRO
+ ID_MODEL_FROM_DATABASE=TVP4020 [Permedia 2] (FIRE GL 1000 PRO)
 
 pci:v0000104Cd00003D07sv00001092sd00000152*
- ID_MODEL_FROM_DATABASE=FIRE GL 1000 PRO
+ ID_MODEL_FROM_DATABASE=TVP4020 [Permedia 2] (FIRE GL 1000 PRO)
 
 pci:v0000104Cd00003D07sv00001092sd00000154*
- ID_MODEL_FROM_DATABASE=FIRE GL 1000 PRO
+ ID_MODEL_FROM_DATABASE=TVP4020 [Permedia 2] (FIRE GL 1000 PRO)
 
 pci:v0000104Cd00003D07sv00001092sd00000155*
- ID_MODEL_FROM_DATABASE=FIRE GL 1000 PRO
+ ID_MODEL_FROM_DATABASE=TVP4020 [Permedia 2] (FIRE GL 1000 PRO)
 
 pci:v0000104Cd00003D07sv00001092sd00000156*
- ID_MODEL_FROM_DATABASE=FIRE GL 1000 PRO
+ ID_MODEL_FROM_DATABASE=TVP4020 [Permedia 2] (FIRE GL 1000 PRO)
 
 pci:v0000104Cd00003D07sv00001092sd00000157*
- ID_MODEL_FROM_DATABASE=FIRE GL 1000 PRO
+ ID_MODEL_FROM_DATABASE=TVP4020 [Permedia 2] (FIRE GL 1000 PRO)
 
 pci:v0000104Cd00003D07sv00001097sd00003D01*
- ID_MODEL_FROM_DATABASE=Jeronimo Pro
+ ID_MODEL_FROM_DATABASE=TVP4020 [Permedia 2] (Jeronimo Pro)
 
 pci:v0000104Cd00003D07sv00001102sd0000100F*
- ID_MODEL_FROM_DATABASE=Graphics Blaster Extreme
+ ID_MODEL_FROM_DATABASE=TVP4020 [Permedia 2] (Graphics Blaster Extreme)
 
 pci:v0000104Cd00003D07sv00003D3Dsd00000100*
- ID_MODEL_FROM_DATABASE=Reference Permedia 2 3D
+ ID_MODEL_FROM_DATABASE=TVP4020 [Permedia 2] (Reference Permedia 2 3D)
 
 pci:v0000104Cd00008000*
  ID_MODEL_FROM_DATABASE=PCILynx/PCILynx2 IEEE 1394 Link Layer Controller
 
 pci:v0000104Cd00008000sv0000105Esd00008003*
- ID_MODEL_FROM_DATABASE=FireBoard200
+ ID_MODEL_FROM_DATABASE=PCILynx/PCILynx2 IEEE 1394 Link Layer Controller (FireBoard200)
 
 pci:v0000104Cd00008000sv00001443sd00008003*
- ID_MODEL_FROM_DATABASE=FireBoard200
+ ID_MODEL_FROM_DATABASE=PCILynx/PCILynx2 IEEE 1394 Link Layer Controller (FireBoard200)
 
 pci:v0000104Cd00008000sv00001443sd00008005*
- ID_MODEL_FROM_DATABASE=FireBoard400
+ ID_MODEL_FROM_DATABASE=PCILynx/PCILynx2 IEEE 1394 Link Layer Controller (FireBoard400)
 
 pci:v0000104Cd00008000sv00001443sd00008006*
- ID_MODEL_FROM_DATABASE=FireBoard400
+ ID_MODEL_FROM_DATABASE=PCILynx/PCILynx2 IEEE 1394 Link Layer Controller (FireBoard400)
 
 pci:v0000104Cd00008000sv0000E4BFsd00001010*
- ID_MODEL_FROM_DATABASE=CF1-1-SNARE
+ ID_MODEL_FROM_DATABASE=PCILynx/PCILynx2 IEEE 1394 Link Layer Controller (CF1-1-SNARE)
 
 pci:v0000104Cd00008000sv0000E4BFsd00001020*
- ID_MODEL_FROM_DATABASE=CF1-2-SNARE
+ ID_MODEL_FROM_DATABASE=PCILynx/PCILynx2 IEEE 1394 Link Layer Controller (CF1-2-SNARE)
 
 pci:v0000104Cd00008000sv0000E4BFsd00001040*
- ID_MODEL_FROM_DATABASE=FireCompact400
+ ID_MODEL_FROM_DATABASE=PCILynx/PCILynx2 IEEE 1394 Link Layer Controller (FireCompact400)
 
 pci:v0000104Cd00008009*
  ID_MODEL_FROM_DATABASE=TSB12LV22 IEEE-1394 Controller
 
 pci:v0000104Cd00008009sv0000104Dsd00008032*
- ID_MODEL_FROM_DATABASE=8032 OHCI i.LINK (IEEE 1394) Controller
+ ID_MODEL_FROM_DATABASE=TSB12LV22 IEEE-1394 Controller (8032 OHCI i.LINK (IEEE 1394) Controller)
 
 pci:v0000104Cd00008009sv00001443sd00008010*
- ID_MODEL_FROM_DATABASE=FireBoard400-OHCI
+ ID_MODEL_FROM_DATABASE=TSB12LV22 IEEE-1394 Controller (FireBoard400-OHCI)
 
 pci:v0000104Cd00008017*
  ID_MODEL_FROM_DATABASE=PCI4410 FireWire Controller
@@ -14379,220 +14667,223 @@ pci:v0000104Cd00008019*
  ID_MODEL_FROM_DATABASE=TSB12LV23 IEEE-1394 Controller
 
 pci:v0000104Cd00008019sv000011BDsd0000000A*
- ID_MODEL_FROM_DATABASE=Studio DV500-1394
+ ID_MODEL_FROM_DATABASE=TSB12LV23 IEEE-1394 Controller (Studio DV500-1394)
 
 pci:v0000104Cd00008019sv000011BDsd0000000E*
- ID_MODEL_FROM_DATABASE=Studio DV
+ ID_MODEL_FROM_DATABASE=TSB12LV23 IEEE-1394 Controller (Studio DV)
 
 pci:v0000104Cd00008019sv00001443sd00008010*
- ID_MODEL_FROM_DATABASE=FireBoard400-OHCI
+ ID_MODEL_FROM_DATABASE=TSB12LV23 IEEE-1394 Controller (FireBoard400-OHCI)
 
 pci:v0000104Cd00008019sv0000E4BFsd00001010*
- ID_MODEL_FROM_DATABASE=CF2-1-CYMBAL
+ ID_MODEL_FROM_DATABASE=TSB12LV23 IEEE-1394 Controller (CF2-1-CYMBAL)
 
 pci:v0000104Cd00008020*
  ID_MODEL_FROM_DATABASE=TSB12LV26 IEEE-1394 Controller (Link)
 
 pci:v0000104Cd00008020sv00001028sd000000D8*
- ID_MODEL_FROM_DATABASE=Precision 530
+ ID_MODEL_FROM_DATABASE=TSB12LV26 IEEE-1394 Controller (Link) (Precision 530)
 
 pci:v0000104Cd00008020sv0000104Dsd000080E2*
- ID_MODEL_FROM_DATABASE=VAIO PCV-J200
+ ID_MODEL_FROM_DATABASE=TSB12LV26 IEEE-1394 Controller (Link) (VAIO PCV-J200)
 
 pci:v0000104Cd00008020sv000011BDsd0000000F*
- ID_MODEL_FROM_DATABASE=Studio DV500-1394
+ ID_MODEL_FROM_DATABASE=TSB12LV26 IEEE-1394 Controller (Link) (Studio DV500-1394)
 
 pci:v0000104Cd00008020sv000011BDsd0000001C*
- ID_MODEL_FROM_DATABASE=Excalibur 4.1
+ ID_MODEL_FROM_DATABASE=TSB12LV26 IEEE-1394 Controller (Link) (Excalibur 4.1)
 
 pci:v0000104Cd00008020sv00001443sd00008010*
- ID_MODEL_FROM_DATABASE=FireBoard400-OHCI
+ ID_MODEL_FROM_DATABASE=TSB12LV26 IEEE-1394 Controller (Link) (FireBoard400-OHCI)
 
 pci:v0000104Cd00008021*
  ID_MODEL_FROM_DATABASE=TSB43AA22 IEEE-1394 Controller (PHY/Link Integrated)
 
 pci:v0000104Cd00008021sv0000104Dsd000080DF*
- ID_MODEL_FROM_DATABASE=Vaio PCG-FX403
+ ID_MODEL_FROM_DATABASE=TSB43AA22 IEEE-1394 Controller (PHY/Link Integrated) (Vaio PCG-FX403)
 
 pci:v0000104Cd00008021sv0000104Dsd000080E7*
- ID_MODEL_FROM_DATABASE=VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
+ ID_MODEL_FROM_DATABASE=TSB43AA22 IEEE-1394 Controller (PHY/Link Integrated) (VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP)
 
 pci:v0000104Cd00008022*
  ID_MODEL_FROM_DATABASE=TSB43AB22 IEEE-1394a-2000 Controller (PHY/Link) [iOHCI-Lynx]
 
 pci:v0000104Cd00008022sv0000104Csd00008023*
- ID_MODEL_FROM_DATABASE=TSB43AB22/A IEEE-1394a-2000 Controller (PHY/Link)
+ ID_MODEL_FROM_DATABASE=TSB43AB22 IEEE-1394a-2000 Controller (PHY/Link) [iOHCI-Lynx] (TSB43AB22/A IEEE-1394a-2000 Controller (PHY/Link))
 
 pci:v0000104Cd00008023*
  ID_MODEL_FROM_DATABASE=TSB43AB22A IEEE-1394a-2000 Controller (PHY/Link) [iOHCI-Lynx]
 
+pci:v0000104Cd00008023sv00001028sd00000168*
+ ID_MODEL_FROM_DATABASE=TSB43AB22A IEEE-1394a-2000 Controller (PHY/Link) [iOHCI-Lynx] (Precision Workstation 670 Mainboard)
+
 pci:v0000104Cd00008023sv0000103Csd0000088C*
- ID_MODEL_FROM_DATABASE=NC8000 laptop
+ ID_MODEL_FROM_DATABASE=TSB43AB22A IEEE-1394a-2000 Controller (PHY/Link) [iOHCI-Lynx] (NC8000 laptop)
 
 pci:v0000104Cd00008023sv00001043sd0000808B*
- ID_MODEL_FROM_DATABASE=K8N4/A8N Series Mainboard
+ ID_MODEL_FROM_DATABASE=TSB43AB22A IEEE-1394a-2000 Controller (PHY/Link) [iOHCI-Lynx] (K8N4/A8N Series Mainboard)
 
 pci:v0000104Cd00008023sv00001043sd0000815B*
- ID_MODEL_FROM_DATABASE=P5W DH Deluxe Motherboard
+ ID_MODEL_FROM_DATABASE=TSB43AB22A IEEE-1394a-2000 Controller (PHY/Link) [iOHCI-Lynx] (P5W DH Deluxe Motherboard)
 
 pci:v0000104Cd00008023sv00001443sd00008023*
- ID_MODEL_FROM_DATABASE=FireCard400
+ ID_MODEL_FROM_DATABASE=TSB43AB22A IEEE-1394a-2000 Controller (PHY/Link) [iOHCI-Lynx] (FireCard400)
 
 pci:v0000104Cd00008023sv00008086sd00005044*
- ID_MODEL_FROM_DATABASE=Desktop Board DP35DP
+ ID_MODEL_FROM_DATABASE=TSB43AB22A IEEE-1394a-2000 Controller (PHY/Link) [iOHCI-Lynx] (Desktop Board DP35DP)
 
 pci:v0000104Cd00008024*
  ID_MODEL_FROM_DATABASE=TSB43AB23 IEEE-1394a-2000 Controller (PHY/Link)
 
 pci:v0000104Cd00008024sv0000107Dsd00006620*
- ID_MODEL_FROM_DATABASE=Winfast DV2000 FireWire Controller
+ ID_MODEL_FROM_DATABASE=TSB43AB23 IEEE-1394a-2000 Controller (PHY/Link) (Winfast DV2000 FireWire Controller)
 
 pci:v0000104Cd00008024sv00001443sd00008024*
- ID_MODEL_FROM_DATABASE=FireBoard Blue
+ ID_MODEL_FROM_DATABASE=TSB43AB23 IEEE-1394a-2000 Controller (PHY/Link) (FireBoard Blue)
 
 pci:v0000104Cd00008024sv00001458sd00001000*
- ID_MODEL_FROM_DATABASE=Motherboard
+ ID_MODEL_FROM_DATABASE=TSB43AB23 IEEE-1394a-2000 Controller (PHY/Link) (Motherboard)
 
 pci:v0000104Cd00008025*
  ID_MODEL_FROM_DATABASE=TSB82AA2 IEEE-1394b Link Layer Controller
 
 pci:v0000104Cd00008025sv00001043sd0000813C*
- ID_MODEL_FROM_DATABASE=P5P series mainboard
+ ID_MODEL_FROM_DATABASE=TSB82AA2 IEEE-1394b Link Layer Controller (P5P series mainboard)
 
 pci:v0000104Cd00008025sv00001443sd00008025*
- ID_MODEL_FROM_DATABASE=FireBoard800
+ ID_MODEL_FROM_DATABASE=TSB82AA2 IEEE-1394b Link Layer Controller (FireBoard800)
 
 pci:v0000104Cd00008025sv00001458sd00001000*
- ID_MODEL_FROM_DATABASE=GA-K8N Ultra-9 Mainboard
+ ID_MODEL_FROM_DATABASE=TSB82AA2 IEEE-1394b Link Layer Controller (GA-K8N Ultra-9 Mainboard)
 
 pci:v0000104Cd00008025sv00001546sd00008025*
- ID_MODEL_FROM_DATABASE=FWB-PCI01
+ ID_MODEL_FROM_DATABASE=TSB82AA2 IEEE-1394b Link Layer Controller (FWB-PCI01)
 
 pci:v0000104Cd00008025sv000017FCsd00008025*
- ID_MODEL_FROM_DATABASE=GIC3800
+ ID_MODEL_FROM_DATABASE=TSB82AA2 IEEE-1394b Link Layer Controller (GIC3800)
 
 pci:v0000104Cd00008026*
  ID_MODEL_FROM_DATABASE=TSB43AB21 IEEE-1394a-2000 Controller (PHY/Link)
 
 pci:v0000104Cd00008026sv00001025sd00000035*
- ID_MODEL_FROM_DATABASE=TravelMate 660
+ ID_MODEL_FROM_DATABASE=TSB43AB21 IEEE-1394a-2000 Controller (PHY/Link) (TravelMate 660)
 
 pci:v0000104Cd00008026sv00001025sd0000003C*
- ID_MODEL_FROM_DATABASE=Aspire 2001WLCi (Compaq CL50 motherboard)
+ ID_MODEL_FROM_DATABASE=TSB43AB21 IEEE-1394a-2000 Controller (PHY/Link) (Aspire 2001WLCi (Compaq CL50 motherboard))
 
 pci:v0000104Cd00008026sv0000103Csd00000025*
- ID_MODEL_FROM_DATABASE=XE4500 Notebook
+ ID_MODEL_FROM_DATABASE=TSB43AB21 IEEE-1394a-2000 Controller (PHY/Link) (XE4500 Notebook)
 
 pci:v0000104Cd00008026sv0000103Csd0000006A*
- ID_MODEL_FROM_DATABASE=NX9500
+ ID_MODEL_FROM_DATABASE=TSB43AB21 IEEE-1394a-2000 Controller (PHY/Link) (NX9500)
 
 pci:v0000104Cd00008026sv00001043sd0000808D*
- ID_MODEL_FROM_DATABASE=A7V333 mainboard.
+ ID_MODEL_FROM_DATABASE=TSB43AB21 IEEE-1394a-2000 Controller (PHY/Link) (A7V333 mainboard.)
 
 pci:v0000104Cd00008027*
  ID_MODEL_FROM_DATABASE=PCI4451 IEEE-1394 Controller
 
 pci:v0000104Cd00008027sv00001028sd000000E5*
- ID_MODEL_FROM_DATABASE=Latitude C810
+ ID_MODEL_FROM_DATABASE=PCI4451 IEEE-1394 Controller (Latitude C810)
 
 pci:v0000104Cd00008027sv00001028sd000000E6*
- ID_MODEL_FROM_DATABASE=PCI4451 IEEE-1394 Controller (Dell Inspiron 8100)
+ ID_MODEL_FROM_DATABASE=PCI4451 IEEE-1394 Controller ((Dell Inspiron 8100))
 
 pci:v0000104Cd00008029*
  ID_MODEL_FROM_DATABASE=PCI4510 IEEE-1394 Controller
 
 pci:v0000104Cd00008029sv00001028sd00000163*
- ID_MODEL_FROM_DATABASE=Latitude D505
+ ID_MODEL_FROM_DATABASE=PCI4510 IEEE-1394 Controller (Latitude D505)
 
 pci:v0000104Cd00008029sv00001028sd00000196*
- ID_MODEL_FROM_DATABASE=Inspiron 5160
+ ID_MODEL_FROM_DATABASE=PCI4510 IEEE-1394 Controller (Inspiron 5160)
 
 pci:v0000104Cd00008029sv00001071sd00008160*
- ID_MODEL_FROM_DATABASE=MIM2900
+ ID_MODEL_FROM_DATABASE=PCI4510 IEEE-1394 Controller (MIM2900)
 
 pci:v0000104Cd0000802B*
  ID_MODEL_FROM_DATABASE=PCI7410,7510,7610 OHCI-Lynx Controller
 
 pci:v0000104Cd0000802Bsv00001028sd00000139*
- ID_MODEL_FROM_DATABASE=Latitude D400
+ ID_MODEL_FROM_DATABASE=PCI7410,7510,7610 OHCI-Lynx Controller (Latitude D400)
 
 pci:v0000104Cd0000802Bsv00001028sd0000014E*
- ID_MODEL_FROM_DATABASE=PCI7410,7510,7610 OHCI-Lynx Controller (Latitude D800)
+ ID_MODEL_FROM_DATABASE=PCI7410,7510,7610 OHCI-Lynx Controller ((Latitude D800))
 
 pci:v0000104Cd0000802E*
  ID_MODEL_FROM_DATABASE=PCI7x20 1394a-2000 OHCI Two-Port PHY/Link-Layer Controller
 
 pci:v0000104Cd0000802Esv00001028sd0000018D*
- ID_MODEL_FROM_DATABASE=Inspiron 700m/710m
+ ID_MODEL_FROM_DATABASE=PCI7x20 1394a-2000 OHCI Two-Port PHY/Link-Layer Controller (Inspiron 700m/710m)
 
 pci:v0000104Cd00008031*
  ID_MODEL_FROM_DATABASE=PCIxx21/x515 Cardbus Controller
 
 pci:v0000104Cd00008031sv00001025sd00000080*
- ID_MODEL_FROM_DATABASE=Aspire 5024WLMi
+ ID_MODEL_FROM_DATABASE=PCIxx21/x515 Cardbus Controller (Aspire 5024WLMi)
 
 pci:v0000104Cd00008031sv0000103Csd00000934*
- ID_MODEL_FROM_DATABASE=Compaq nw8240/nx8220
+ ID_MODEL_FROM_DATABASE=PCIxx21/x515 Cardbus Controller (Compaq nw8240/nx8220)
 
 pci:v0000104Cd00008031sv0000103Csd0000099C*
- ID_MODEL_FROM_DATABASE=NX6110/NC6120
+ ID_MODEL_FROM_DATABASE=PCIxx21/x515 Cardbus Controller (NX6110/NC6120)
 
 pci:v0000104Cd00008031sv0000103Csd0000308B*
- ID_MODEL_FROM_DATABASE=MX6125
+ ID_MODEL_FROM_DATABASE=PCIxx21/x515 Cardbus Controller (MX6125)
 
 pci:v0000104Cd00008032*
  ID_MODEL_FROM_DATABASE=OHCI Compliant IEEE 1394 Host Controller
 
 pci:v0000104Cd00008032sv00001025sd00000080*
- ID_MODEL_FROM_DATABASE=Aspire 5024WLMi
+ ID_MODEL_FROM_DATABASE=OHCI Compliant IEEE 1394 Host Controller (Aspire 5024WLMi)
 
 pci:v0000104Cd00008032sv0000103Csd00000934*
- ID_MODEL_FROM_DATABASE=Compaq nw8240/nx8220
+ ID_MODEL_FROM_DATABASE=OHCI Compliant IEEE 1394 Host Controller (Compaq nw8240/nx8220)
 
 pci:v0000104Cd00008032sv0000103Csd0000099C*
- ID_MODEL_FROM_DATABASE=NX6110/NC6120
+ ID_MODEL_FROM_DATABASE=OHCI Compliant IEEE 1394 Host Controller (NX6110/NC6120)
 
 pci:v0000104Cd00008032sv0000103Csd0000308B*
- ID_MODEL_FROM_DATABASE=MX6125
+ ID_MODEL_FROM_DATABASE=OHCI Compliant IEEE 1394 Host Controller (MX6125)
 
 pci:v0000104Cd00008033*
  ID_MODEL_FROM_DATABASE=PCIxx21 Integrated FlashMedia Controller
 
 pci:v0000104Cd00008033sv00001025sd00000080*
- ID_MODEL_FROM_DATABASE=Aspire 5024WLMi
+ ID_MODEL_FROM_DATABASE=PCIxx21 Integrated FlashMedia Controller (Aspire 5024WLMi)
 
 pci:v0000104Cd00008033sv0000103Csd00000934*
- ID_MODEL_FROM_DATABASE=Compaq nw8240/nx8220
+ ID_MODEL_FROM_DATABASE=PCIxx21 Integrated FlashMedia Controller (Compaq nw8240/nx8220)
 
 pci:v0000104Cd00008033sv0000103Csd0000099C*
- ID_MODEL_FROM_DATABASE=NX6110/NC6120
+ ID_MODEL_FROM_DATABASE=PCIxx21 Integrated FlashMedia Controller (NX6110/NC6120)
 
 pci:v0000104Cd00008033sv0000103Csd0000308B*
- ID_MODEL_FROM_DATABASE=MX6125
+ ID_MODEL_FROM_DATABASE=PCIxx21 Integrated FlashMedia Controller (MX6125)
 
 pci:v0000104Cd00008034*
  ID_MODEL_FROM_DATABASE=PCI6411/6421/6611/6621/7411/7421/7611/7621 Secure Digital Controller
 
 pci:v0000104Cd00008034sv00001025sd00000080*
- ID_MODEL_FROM_DATABASE=Aspire 5024WLMi
+ ID_MODEL_FROM_DATABASE=PCI6411/6421/6611/6621/7411/7421/7611/7621 Secure Digital Controller (Aspire 5024WLMi)
 
 pci:v0000104Cd00008034sv0000103Csd00000934*
- ID_MODEL_FROM_DATABASE=Compaq nw8240/nx8220
+ ID_MODEL_FROM_DATABASE=PCI6411/6421/6611/6621/7411/7421/7611/7621 Secure Digital Controller (Compaq nw8240/nx8220)
 
 pci:v0000104Cd00008034sv0000103Csd0000099C*
- ID_MODEL_FROM_DATABASE=NX6110/NC6120
+ ID_MODEL_FROM_DATABASE=PCI6411/6421/6611/6621/7411/7421/7611/7621 Secure Digital Controller (NX6110/NC6120)
 
 pci:v0000104Cd00008034sv0000103Csd0000308B*
- ID_MODEL_FROM_DATABASE=MX6125
+ ID_MODEL_FROM_DATABASE=PCI6411/6421/6611/6621/7411/7421/7611/7621 Secure Digital Controller (MX6125)
 
 pci:v0000104Cd00008035*
  ID_MODEL_FROM_DATABASE=PCI6411/6421/6611/6621/7411/7421/7611/7621 Smart Card Controller
 
 pci:v0000104Cd00008035sv0000103Csd00000934*
- ID_MODEL_FROM_DATABASE=Compaq nw8240/nx8220
+ ID_MODEL_FROM_DATABASE=PCI6411/6421/6611/6621/7411/7421/7611/7621 Smart Card Controller (Compaq nw8240/nx8220)
 
 pci:v0000104Cd00008035sv0000103Csd0000099C*
- ID_MODEL_FROM_DATABASE=NX6110/NC6120
+ ID_MODEL_FROM_DATABASE=PCI6411/6421/6611/6621/7411/7421/7611/7621 Smart Card Controller (NX6110/NC6120)
 
 pci:v0000104Cd00008036*
  ID_MODEL_FROM_DATABASE=PCI6515 Cardbus Controller
@@ -14604,67 +14895,67 @@ pci:v0000104Cd00008039*
  ID_MODEL_FROM_DATABASE=PCIxx12 Cardbus Controller
 
 pci:v0000104Cd00008039sv0000103Csd0000309F*
- ID_MODEL_FROM_DATABASE=Compaq nx9420 Notebook
+ ID_MODEL_FROM_DATABASE=PCIxx12 Cardbus Controller (Compaq nx9420 Notebook)
 
 pci:v0000104Cd00008039sv0000103Csd000030A1*
- ID_MODEL_FROM_DATABASE=NC2400
+ ID_MODEL_FROM_DATABASE=PCIxx12 Cardbus Controller (NC2400)
 
 pci:v0000104Cd00008039sv0000103Csd000030A3*
- ID_MODEL_FROM_DATABASE=Compaq nw8440
+ ID_MODEL_FROM_DATABASE=PCIxx12 Cardbus Controller (Compaq nw8440)
 
 pci:v0000104Cd00008039sv0000104Dsd0000902D*
- ID_MODEL_FROM_DATABASE=VAIO VGN-NR120E
+ ID_MODEL_FROM_DATABASE=PCIxx12 Cardbus Controller (VAIO VGN-NR120E)
 
 pci:v0000104Cd0000803A*
  ID_MODEL_FROM_DATABASE=PCIxx12 OHCI Compliant IEEE 1394 Host Controller
 
 pci:v0000104Cd0000803Asv0000103Csd0000309F*
- ID_MODEL_FROM_DATABASE=nx9420
+ ID_MODEL_FROM_DATABASE=PCIxx12 OHCI Compliant IEEE 1394 Host Controller (nx9420)
 
 pci:v0000104Cd0000803Asv0000103Csd000030A1*
- ID_MODEL_FROM_DATABASE=NC2400
+ ID_MODEL_FROM_DATABASE=PCIxx12 OHCI Compliant IEEE 1394 Host Controller (NC2400)
 
 pci:v0000104Cd0000803Asv0000103Csd000030A3*
- ID_MODEL_FROM_DATABASE=Compaq nw8440
+ ID_MODEL_FROM_DATABASE=PCIxx12 OHCI Compliant IEEE 1394 Host Controller (Compaq nw8440)
 
 pci:v0000104Cd0000803Asv0000104Dsd0000902D*
- ID_MODEL_FROM_DATABASE=VAIO VGN-NR120E
+ ID_MODEL_FROM_DATABASE=PCIxx12 OHCI Compliant IEEE 1394 Host Controller (VAIO VGN-NR120E)
 
 pci:v0000104Cd0000803B*
  ID_MODEL_FROM_DATABASE=5-in-1 Multimedia Card Reader (SD/MMC/MS/MS PRO/xD)
 
 pci:v0000104Cd0000803Bsv0000103Csd0000309F*
- ID_MODEL_FROM_DATABASE=nx9420
+ ID_MODEL_FROM_DATABASE=5-in-1 Multimedia Card Reader (SD/MMC/MS/MS PRO/xD) (nx9420)
 
 pci:v0000104Cd0000803Bsv0000103Csd000030A3*
- ID_MODEL_FROM_DATABASE=Compaq nw8440
+ ID_MODEL_FROM_DATABASE=5-in-1 Multimedia Card Reader (SD/MMC/MS/MS PRO/xD) (Compaq nw8440)
 
 pci:v0000104Cd0000803Bsv0000104Dsd0000902D*
- ID_MODEL_FROM_DATABASE=VAIO VGN-NR120E
+ ID_MODEL_FROM_DATABASE=5-in-1 Multimedia Card Reader (SD/MMC/MS/MS PRO/xD) (VAIO VGN-NR120E)
 
 pci:v0000104Cd0000803C*
  ID_MODEL_FROM_DATABASE=PCIxx12 SDA Standard Compliant SD Host Controller
 
 pci:v0000104Cd0000803Csv0000103Csd0000309F*
- ID_MODEL_FROM_DATABASE=nx9420
+ ID_MODEL_FROM_DATABASE=PCIxx12 SDA Standard Compliant SD Host Controller (nx9420)
 
 pci:v0000104Cd0000803Csv0000103Csd000030A3*
- ID_MODEL_FROM_DATABASE=Compaq nw8440
+ ID_MODEL_FROM_DATABASE=PCIxx12 SDA Standard Compliant SD Host Controller (Compaq nw8440)
 
 pci:v0000104Cd0000803D*
  ID_MODEL_FROM_DATABASE=PCIxx12 GemCore based SmartCard controller
 
 pci:v0000104Cd0000803Dsv0000103Csd0000309F*
- ID_MODEL_FROM_DATABASE=Compaq nx9420 Notebook
+ ID_MODEL_FROM_DATABASE=PCIxx12 GemCore based SmartCard controller (Compaq nx9420 Notebook)
 
 pci:v0000104Cd0000803Dsv0000103Csd000030A1*
- ID_MODEL_FROM_DATABASE=NC2400
+ ID_MODEL_FROM_DATABASE=PCIxx12 GemCore based SmartCard controller (NC2400)
 
 pci:v0000104Cd0000803Dsv0000103Csd000030A3*
- ID_MODEL_FROM_DATABASE=nc8430
+ ID_MODEL_FROM_DATABASE=PCIxx12 GemCore based SmartCard controller (nc8430)
 
 pci:v0000104Cd0000803Dsv0000103Csd000030AA*
- ID_MODEL_FROM_DATABASE=nc6310
+ ID_MODEL_FROM_DATABASE=PCIxx12 GemCore based SmartCard controller (nc6310)
 
 pci:v0000104Cd00008101*
  ID_MODEL_FROM_DATABASE=TSB43DB42 IEEE-1394a-2000 Controller (PHY/Link)
@@ -14676,16 +14967,16 @@ pci:v0000104Cd00008204*
  ID_MODEL_FROM_DATABASE=PCI7410/7510/7610 PCI Firmware Loading Function
 
 pci:v0000104Cd00008204sv00001028sd00000139*
- ID_MODEL_FROM_DATABASE=Latitude D400
+ ID_MODEL_FROM_DATABASE=PCI7410/7510/7610 PCI Firmware Loading Function (Latitude D400)
 
 pci:v0000104Cd00008204sv00001028sd0000014E*
- ID_MODEL_FROM_DATABASE=Latitude D800
+ ID_MODEL_FROM_DATABASE=PCI7410/7510/7610 PCI Firmware Loading Function (Latitude D800)
 
 pci:v0000104Cd00008231*
  ID_MODEL_FROM_DATABASE=XIO2000(A)/XIO2200A PCI Express-to-PCI Bridge
 
 pci:v0000104Cd00008231sv00005678sd00001234*
- ID_MODEL_FROM_DATABASE=DC-1394 PCIe
+ ID_MODEL_FROM_DATABASE=XIO2000(A)/XIO2200A PCI Express-to-PCI Bridge (DC-1394 PCIe)
 
 pci:v0000104Cd00008232*
  ID_MODEL_FROM_DATABASE=XIO3130 PCI Express Switch (Upstream)
@@ -14697,7 +14988,7 @@ pci:v0000104Cd00008235*
  ID_MODEL_FROM_DATABASE=XIO2200A IEEE-1394a-2000 Controller (PHY/Link)
 
 pci:v0000104Cd00008235sv00005678sd00001234*
- ID_MODEL_FROM_DATABASE=DC-1394 PCIe
+ ID_MODEL_FROM_DATABASE=XIO2200A IEEE-1394a-2000 Controller (PHY/Link) (DC-1394 PCIe)
 
 pci:v0000104Cd0000823E*
  ID_MODEL_FROM_DATABASE=XIO2213A/B/XIO2221 PCI Express to PCI Bridge [Cheetah Express]
@@ -14706,7 +14997,7 @@ pci:v0000104Cd0000823F*
  ID_MODEL_FROM_DATABASE=XIO2213A/B/XIO2221 IEEE-1394b OHCI Controller [Cheetah Express]
 
 pci:v0000104Cd0000823Fsv00001546sd0000803C*
- ID_MODEL_FROM_DATABASE=FWB-PCIE1X11B
+ ID_MODEL_FROM_DATABASE=XIO2213A/B/XIO2221 IEEE-1394b OHCI Controller [Cheetah Express] (FWB-PCIE1X11B)
 
 pci:v0000104Cd00008240*
  ID_MODEL_FROM_DATABASE=XIO2001 PCI Express-to-PCI Bridge
@@ -14718,16 +15009,16 @@ pci:v0000104Cd00008400*
  ID_MODEL_FROM_DATABASE=ACX 100 22Mbps Wireless Interface
 
 pci:v0000104Cd00008400sv00001186sd00003B00*
- ID_MODEL_FROM_DATABASE=DWL-650+ PC Card cardbus 22Mbs Wireless Adapter [AirPlus]
+ ID_MODEL_FROM_DATABASE=ACX 100 22Mbps Wireless Interface (DWL-650+ PC Card cardbus 22Mbs Wireless Adapter [AirPlus])
 
 pci:v0000104Cd00008400sv00001186sd00003B01*
- ID_MODEL_FROM_DATABASE=DWL-520+ 22Mbps PCI Wireless Adapter
+ ID_MODEL_FROM_DATABASE=ACX 100 22Mbps Wireless Interface (DWL-520+ 22Mbps PCI Wireless Adapter)
 
 pci:v0000104Cd00008400sv00001395sd00002201*
- ID_MODEL_FROM_DATABASE=WL22-PC
+ ID_MODEL_FROM_DATABASE=ACX 100 22Mbps Wireless Interface (WL22-PC)
 
 pci:v0000104Cd00008400sv000016ABsd00008501*
- ID_MODEL_FROM_DATABASE=WL-8305 IEEE802.11b+ Wireless LAN PCI Adapter
+ ID_MODEL_FROM_DATABASE=ACX 100 22Mbps Wireless Interface (WL-8305 IEEE802.11b+ Wireless LAN PCI Adapter)
 
 pci:v0000104Cd00008401*
  ID_MODEL_FROM_DATABASE=ACX 100 22Mbps Wireless Interface
@@ -14742,58 +15033,58 @@ pci:v0000104Cd00009066*
  ID_MODEL_FROM_DATABASE=ACX 111 54Mbps Wireless Interface
 
 pci:v0000104Cd00009066sv00000308sd00003404*
- ID_MODEL_FROM_DATABASE=G-102 v1 802.11g Wireless Cardbus Adapter
+ ID_MODEL_FROM_DATABASE=ACX 111 54Mbps Wireless Interface (G-102 v1 802.11g Wireless Cardbus Adapter)
 
 pci:v0000104Cd00009066sv00000308sd00003406*
- ID_MODEL_FROM_DATABASE=G-162 v2 802.11g Wireless Cardbus Adapter
+ ID_MODEL_FROM_DATABASE=ACX 111 54Mbps Wireless Interface (G-162 v2 802.11g Wireless Cardbus Adapter)
 
 pci:v0000104Cd00009066sv0000104Csd00009066*
- ID_MODEL_FROM_DATABASE=WL212 Sitecom Wireless Network PCI-Card 100M (Version 1)
+ ID_MODEL_FROM_DATABASE=ACX 111 54Mbps Wireless Interface (WL212 Sitecom Wireless Network PCI-Card 100M (Version 1))
 
 pci:v0000104Cd00009066sv0000104Csd00009067*
- ID_MODEL_FROM_DATABASE=TNETW1130GVF
+ ID_MODEL_FROM_DATABASE=ACX 111 54Mbps Wireless Interface (TNETW1130GVF)
 
 pci:v0000104Cd00009066sv0000104Csd00009096*
- ID_MODEL_FROM_DATABASE=Trendnet TEW-412PC Wireless PCI Adapter (Version A)
+ ID_MODEL_FROM_DATABASE=ACX 111 54Mbps Wireless Interface (Trendnet TEW-412PC Wireless PCI Adapter (Version A))
 
 pci:v0000104Cd00009066sv00001186sd00003B04*
- ID_MODEL_FROM_DATABASE=DWL-G520+ Wireless PCI Adapter
+ ID_MODEL_FROM_DATABASE=ACX 111 54Mbps Wireless Interface (DWL-G520+ Wireless PCI Adapter)
 
 pci:v0000104Cd00009066sv00001186sd00003B05*
- ID_MODEL_FROM_DATABASE=DWL-G650+ AirPlusG+ CardBus Wireless LAN
+ ID_MODEL_FROM_DATABASE=ACX 111 54Mbps Wireless Interface (DWL-G650+ AirPlusG+ CardBus Wireless LAN)
 
 pci:v0000104Cd00009066sv00001186sd00003B08*
- ID_MODEL_FROM_DATABASE=AirPlus G DWL-G630 Wireless Cardbus Adapter (rev.B1)
+ ID_MODEL_FROM_DATABASE=ACX 111 54Mbps Wireless Interface (AirPlus G DWL-G630 Wireless Cardbus Adapter (rev.B1))
 
 pci:v0000104Cd00009066sv00001385sd00004C00*
- ID_MODEL_FROM_DATABASE=WG311v2 802.11g Wireless PCI Adapter
+ ID_MODEL_FROM_DATABASE=ACX 111 54Mbps Wireless Interface (WG311v2 802.11g Wireless PCI Adapter)
 
 pci:v0000104Cd00009066sv000013D1sd0000ABA0*
- ID_MODEL_FROM_DATABASE=SWLMP-54108 108Mbps Wireless mini PCI card 802.11g+
+ ID_MODEL_FROM_DATABASE=ACX 111 54Mbps Wireless Interface (SWLMP-54108 108Mbps Wireless mini PCI card 802.11g+)
 
 pci:v0000104Cd00009066sv000014EAsd0000AB07*
- ID_MODEL_FROM_DATABASE=GW-NS54GM Wireless Cardbus Adapter
+ ID_MODEL_FROM_DATABASE=ACX 111 54Mbps Wireless Interface (GW-NS54GM Wireless Cardbus Adapter)
 
 pci:v0000104Cd00009066sv000016ECsd0000010D*
- ID_MODEL_FROM_DATABASE=USR5416 802.11g Wireless Turbo PCI Adapter
+ ID_MODEL_FROM_DATABASE=ACX 111 54Mbps Wireless Interface (USR5416 802.11g Wireless Turbo PCI Adapter)
 
 pci:v0000104Cd00009066sv000016ECsd0000010E*
- ID_MODEL_FROM_DATABASE=USR5410 802.11g Wireless Cardbus Adapter
+ ID_MODEL_FROM_DATABASE=ACX 111 54Mbps Wireless Interface (USR5410 802.11g Wireless Cardbus Adapter)
 
 pci:v0000104Cd00009066sv00001737sd00000033*
- ID_MODEL_FROM_DATABASE=WPC54G v2 802.11g Wireless-G Notebook Adapter
+ ID_MODEL_FROM_DATABASE=ACX 111 54Mbps Wireless Interface (WPC54G v2 802.11g Wireless-G Notebook Adapter)
 
 pci:v0000104Cd00009066sv000017CFsd00000032*
- ID_MODEL_FROM_DATABASE=G-162 v1 802.11g Wireless Cardbus Adapter
+ ID_MODEL_FROM_DATABASE=ACX 111 54Mbps Wireless Interface (G-162 v1 802.11g Wireless Cardbus Adapter)
 
 pci:v0000104Cd00009066sv000017CFsd00000033*
- ID_MODEL_FROM_DATABASE=Z-Com XG650 Wireless miniPCI 802.11b/g
+ ID_MODEL_FROM_DATABASE=ACX 111 54Mbps Wireless Interface (Z-Com XG650 Wireless miniPCI 802.11b/g)
 
 pci:v0000104Cd00009066sv0000187Esd0000340B*
- ID_MODEL_FROM_DATABASE=G-302 v2 802.11g Wireless PCI Adapter
+ ID_MODEL_FROM_DATABASE=ACX 111 54Mbps Wireless Interface (G-302 v2 802.11g Wireless PCI Adapter)
 
 pci:v0000104Cd00009066sv0000187Esd0000340C*
- ID_MODEL_FROM_DATABASE=G-360 v2 802.11g Wireless PCI Adapter
+ ID_MODEL_FROM_DATABASE=ACX 111 54Mbps Wireless Interface (G-360 v2 802.11g Wireless PCI Adapter)
 
 pci:v0000104Cd0000A001*
  ID_MODEL_FROM_DATABASE=TDC1570
@@ -14808,13 +15099,13 @@ pci:v0000104Cd0000A106*
  ID_MODEL_FROM_DATABASE=TMS320C6414 TMS320C6415 TMS320C6416
 
 pci:v0000104Cd0000A106sv0000175Csd00005000*
- ID_MODEL_FROM_DATABASE=ASI50xx Audio Adapter
+ ID_MODEL_FROM_DATABASE=TMS320C6414 TMS320C6415 TMS320C6416 (ASI50xx Audio Adapter)
 
 pci:v0000104Cd0000A106sv0000175Csd00006400*
- ID_MODEL_FROM_DATABASE=ASI6400 Cobranet series
+ ID_MODEL_FROM_DATABASE=TMS320C6414 TMS320C6415 TMS320C6416 (ASI6400 Cobranet series)
 
 pci:v0000104Cd0000A106sv0000175Csd00008700*
- ID_MODEL_FROM_DATABASE=ASI87xx Radio Tuner card
+ ID_MODEL_FROM_DATABASE=TMS320C6414 TMS320C6415 TMS320C6416 (ASI87xx Radio Tuner card)
 
 pci:v0000104Cd0000AC10*
  ID_MODEL_FROM_DATABASE=PCI1050
@@ -14835,7 +15126,7 @@ pci:v0000104Cd0000AC16*
  ID_MODEL_FROM_DATABASE=PCI1250
 
 pci:v0000104Cd0000AC16sv00001014sd00000092*
- ID_MODEL_FROM_DATABASE=ThinkPad 600
+ ID_MODEL_FROM_DATABASE=PCI1250 (ThinkPad 600)
 
 pci:v0000104Cd0000AC17*
  ID_MODEL_FROM_DATABASE=PCI1220
@@ -14853,19 +15144,19 @@ pci:v0000104Cd0000AC1B*
  ID_MODEL_FROM_DATABASE=PCI1450
 
 pci:v0000104Cd0000AC1Bsv00000E11sd0000B113*
- ID_MODEL_FROM_DATABASE=Armada M700
+ ID_MODEL_FROM_DATABASE=PCI1450 (Armada M700)
 
 pci:v0000104Cd0000AC1Bsv00001014sd00000130*
- ID_MODEL_FROM_DATABASE=ThinkPad 600X/A21m/T20/T22
+ ID_MODEL_FROM_DATABASE=PCI1450 (ThinkPad 600X/A21m/T20/T22)
 
 pci:v0000104Cd0000AC1C*
  ID_MODEL_FROM_DATABASE=PCI1225
 
 pci:v0000104Cd0000AC1Csv00000E11sd0000B121*
- ID_MODEL_FROM_DATABASE=Armada E500
+ ID_MODEL_FROM_DATABASE=PCI1225 (Armada E500)
 
 pci:v0000104Cd0000AC1Csv00001028sd00000088*
- ID_MODEL_FROM_DATABASE=Latitude CPi A400XT
+ ID_MODEL_FROM_DATABASE=PCI1225 (Latitude CPi A400XT)
 
 pci:v0000104Cd0000AC1D*
  ID_MODEL_FROM_DATABASE=PCI1251A
@@ -14907,40 +15198,40 @@ pci:v0000104Cd0000AC42*
  ID_MODEL_FROM_DATABASE=PCI4451 PC card Cardbus Controller
 
 pci:v0000104Cd0000AC42sv00001028sd000000E6*
- ID_MODEL_FROM_DATABASE=PCI4451 PC card CardBus Controller (Inspiron 8100)
+ ID_MODEL_FROM_DATABASE=PCI4451 PC card Cardbus Controller (PCI4451 PC card CardBus Controller (Inspiron 8100))
 
 pci:v0000104Cd0000AC44*
  ID_MODEL_FROM_DATABASE=PCI4510 PC card Cardbus Controller
 
 pci:v0000104Cd0000AC44sv00001028sd00000149*
- ID_MODEL_FROM_DATABASE=Inspiron 5100
+ ID_MODEL_FROM_DATABASE=PCI4510 PC card Cardbus Controller (Inspiron 5100)
 
 pci:v0000104Cd0000AC44sv00001028sd00000163*
- ID_MODEL_FROM_DATABASE=Latitude D505
+ ID_MODEL_FROM_DATABASE=PCI4510 PC card Cardbus Controller (Latitude D505)
 
 pci:v0000104Cd0000AC44sv00001028sd00000196*
- ID_MODEL_FROM_DATABASE=Inspiron 5160
+ ID_MODEL_FROM_DATABASE=PCI4510 PC card Cardbus Controller (Inspiron 5160)
 
 pci:v0000104Cd0000AC44sv00001071sd00008160*
- ID_MODEL_FROM_DATABASE=MIM2000
+ ID_MODEL_FROM_DATABASE=PCI4510 PC card Cardbus Controller (MIM2000)
 
 pci:v0000104Cd0000AC46*
  ID_MODEL_FROM_DATABASE=PCI4520 PC card Cardbus Controller
 
 pci:v0000104Cd0000AC46sv00001014sd00000552*
- ID_MODEL_FROM_DATABASE=ThinkPad
+ ID_MODEL_FROM_DATABASE=PCI4520 PC card Cardbus Controller (ThinkPad)
 
 pci:v0000104Cd0000AC47*
  ID_MODEL_FROM_DATABASE=PCI7510 PC card Cardbus Controller
 
 pci:v0000104Cd0000AC47sv00001028sd00000139*
- ID_MODEL_FROM_DATABASE=Latitude D400
+ ID_MODEL_FROM_DATABASE=PCI7510 PC card Cardbus Controller (Latitude D400)
 
 pci:v0000104Cd0000AC47sv00001028sd0000013F*
- ID_MODEL_FROM_DATABASE=Precision M60
+ ID_MODEL_FROM_DATABASE=PCI7510 PC card Cardbus Controller (Precision M60)
 
 pci:v0000104Cd0000AC47sv00001028sd0000014E*
- ID_MODEL_FROM_DATABASE=Latitude D800
+ ID_MODEL_FROM_DATABASE=PCI7510 PC card Cardbus Controller (Latitude D800)
 
 pci:v0000104Cd0000AC48*
  ID_MODEL_FROM_DATABASE=PCI7610 PC Card Cardbus Controller
@@ -14952,10 +15243,10 @@ pci:v0000104Cd0000AC4A*
  ID_MODEL_FROM_DATABASE=PCI7510/7610 CardBus Bridge
 
 pci:v0000104Cd0000AC4Asv00001028sd00000139*
- ID_MODEL_FROM_DATABASE=Latitude D400
+ ID_MODEL_FROM_DATABASE=PCI7510/7610 CardBus Bridge (Latitude D400)
 
 pci:v0000104Cd0000AC4Asv00001028sd0000014E*
- ID_MODEL_FROM_DATABASE=Latitude D800
+ ID_MODEL_FROM_DATABASE=PCI7510/7610 CardBus Bridge (Latitude D800)
 
 pci:v0000104Cd0000AC4B*
  ID_MODEL_FROM_DATABASE=PCI7610 SD/MMC controller
@@ -14970,28 +15261,28 @@ pci:v0000104Cd0000AC51*
  ID_MODEL_FROM_DATABASE=PCI1420 PC card Cardbus Controller
 
 pci:v0000104Cd0000AC51sv00000E11sd0000004E*
- ID_MODEL_FROM_DATABASE=Evo N600c
+ ID_MODEL_FROM_DATABASE=PCI1420 PC card Cardbus Controller (Evo N600c)
 
 pci:v0000104Cd0000AC51sv00001014sd00000148*
- ID_MODEL_FROM_DATABASE=ThinkPad A20m
+ ID_MODEL_FROM_DATABASE=PCI1420 PC card Cardbus Controller (ThinkPad A20m)
 
 pci:v0000104Cd0000AC51sv00001014sd0000023B*
- ID_MODEL_FROM_DATABASE=ThinkPad T23
+ ID_MODEL_FROM_DATABASE=PCI1420 PC card Cardbus Controller (ThinkPad T23)
 
 pci:v0000104Cd0000AC51sv00001028sd000000B1*
- ID_MODEL_FROM_DATABASE=Latitude C600
+ ID_MODEL_FROM_DATABASE=PCI1420 PC card Cardbus Controller (Latitude C600)
 
 pci:v0000104Cd0000AC51sv00001028sd0000012A*
- ID_MODEL_FROM_DATABASE=Latitude C640
+ ID_MODEL_FROM_DATABASE=PCI1420 PC card Cardbus Controller (Latitude C640)
 
 pci:v0000104Cd0000AC51sv00001033sd000080CD*
- ID_MODEL_FROM_DATABASE=Versa Note VXi
+ ID_MODEL_FROM_DATABASE=PCI1420 PC card Cardbus Controller (Versa Note VXi)
 
 pci:v0000104Cd0000AC51sv000010CFsd00001095*
- ID_MODEL_FROM_DATABASE=Lifebook S-4510/C6155
+ ID_MODEL_FROM_DATABASE=PCI1420 PC card Cardbus Controller (Lifebook S-4510/C6155)
 
 pci:v0000104Cd0000AC51sv0000E4BFsd00001000*
- ID_MODEL_FROM_DATABASE=CP2-2-HIPHOP
+ ID_MODEL_FROM_DATABASE=PCI1420 PC card Cardbus Controller (CP2-2-HIPHOP)
 
 pci:v0000104Cd0000AC52*
  ID_MODEL_FROM_DATABASE=PCI1451 PC card Cardbus Controller
@@ -15003,55 +15294,55 @@ pci:v0000104Cd0000AC54*
  ID_MODEL_FROM_DATABASE=PCI1620 PC Card Controller
 
 pci:v0000104Cd0000AC54sv0000103Csd000008B0*
- ID_MODEL_FROM_DATABASE=tc1100 tablet
+ ID_MODEL_FROM_DATABASE=PCI1620 PC Card Controller (tc1100 tablet)
 
 pci:v0000104Cd0000AC55*
  ID_MODEL_FROM_DATABASE=PCI1520 PC card Cardbus Controller
 
 pci:v0000104Cd0000AC55sv00001014sd00000512*
- ID_MODEL_FROM_DATABASE=ThinkPad T30/T40
+ ID_MODEL_FROM_DATABASE=PCI1520 PC card Cardbus Controller (ThinkPad T30/T40)
 
 pci:v0000104Cd0000AC55sv0000103Csd00000025*
- ID_MODEL_FROM_DATABASE=XE4500 Notebook
+ ID_MODEL_FROM_DATABASE=PCI1520 PC card Cardbus Controller (XE4500 Notebook)
 
 pci:v0000104Cd0000AC56*
  ID_MODEL_FROM_DATABASE=PCI1510 PC card Cardbus Controller
 
 pci:v0000104Cd0000AC56sv00001014sd00000512*
- ID_MODEL_FROM_DATABASE=ThinkPad R50e
+ ID_MODEL_FROM_DATABASE=PCI1510 PC card Cardbus Controller (ThinkPad R50e)
 
 pci:v0000104Cd0000AC56sv00001014sd00000528*
- ID_MODEL_FROM_DATABASE=ThinkPad R40e
+ ID_MODEL_FROM_DATABASE=PCI1510 PC card Cardbus Controller (ThinkPad R40e)
 
 pci:v0000104Cd0000AC56sv000017AAsd00002012*
- ID_MODEL_FROM_DATABASE=ThinkPad T60/R60 series
+ ID_MODEL_FROM_DATABASE=PCI1510 PC card Cardbus Controller (ThinkPad T60/R60 series)
 
 pci:v0000104Cd0000AC60*
  ID_MODEL_FROM_DATABASE=PCI2040 PCI to DSP Bridge Controller
 
 pci:v0000104Cd0000AC60sv0000175Csd00005100*
- ID_MODEL_FROM_DATABASE=ASI51xx Audio Adapter
+ ID_MODEL_FROM_DATABASE=PCI2040 PCI to DSP Bridge Controller (ASI51xx Audio Adapter)
 
 pci:v0000104Cd0000AC60sv0000175Csd00006100*
- ID_MODEL_FROM_DATABASE=ASI61xx Audio Adapter
+ ID_MODEL_FROM_DATABASE=PCI2040 PCI to DSP Bridge Controller (ASI61xx Audio Adapter)
 
 pci:v0000104Cd0000AC60sv0000175Csd00006200*
- ID_MODEL_FROM_DATABASE=ASI62xx Audio Adapter
+ ID_MODEL_FROM_DATABASE=PCI2040 PCI to DSP Bridge Controller (ASI62xx Audio Adapter)
 
 pci:v0000104Cd0000AC60sv0000175Csd00008800*
- ID_MODEL_FROM_DATABASE=ASI88xx Audio Adapter
+ ID_MODEL_FROM_DATABASE=PCI2040 PCI to DSP Bridge Controller (ASI88xx Audio Adapter)
 
 pci:v0000104Cd0000AC60sv0000186Fsd00003001*
- ID_MODEL_FROM_DATABASE=WR-G303 PCI radio receiver
+ ID_MODEL_FROM_DATABASE=PCI2040 PCI to DSP Bridge Controller (WR-G303 PCI radio receiver)
 
 pci:v0000104Cd0000AC60sv0000186Fsd00003005*
- ID_MODEL_FROM_DATABASE=WR-G305 PCI radio receiver
+ ID_MODEL_FROM_DATABASE=PCI2040 PCI to DSP Bridge Controller (WR-G305 PCI radio receiver)
 
 pci:v0000104Cd0000AC60sv0000186Fsd00003101*
- ID_MODEL_FROM_DATABASE=WR-G313 PCI radio receiver
+ ID_MODEL_FROM_DATABASE=PCI2040 PCI to DSP Bridge Controller (WR-G313 PCI radio receiver)
 
 pci:v0000104Cd0000AC60sv0000186Fsd00003105*
- ID_MODEL_FROM_DATABASE=WR-G315 PCI radio receiver
+ ID_MODEL_FROM_DATABASE=PCI2040 PCI to DSP Bridge Controller (WR-G315 PCI radio receiver)
 
 pci:v0000104Cd0000AC8D*
  ID_MODEL_FROM_DATABASE=PCI 7620
@@ -15060,13 +15351,13 @@ pci:v0000104Cd0000AC8E*
  ID_MODEL_FROM_DATABASE=PCI7420 CardBus Controller
 
 pci:v0000104Cd0000AC8Esv00001028sd0000018D*
- ID_MODEL_FROM_DATABASE=Inspiron 700m/710m
+ ID_MODEL_FROM_DATABASE=PCI7420 CardBus Controller (Inspiron 700m/710m)
 
 pci:v0000104Cd0000AC8F*
  ID_MODEL_FROM_DATABASE=PCI7420/7620 SD/MS-Pro Controller
 
 pci:v0000104Cd0000AC8Fsv00001028sd0000018D*
- ID_MODEL_FROM_DATABASE=Inspiron 700m/710m
+ ID_MODEL_FROM_DATABASE=PCI7420/7620 SD/MS-Pro Controller (Inspiron 700m/710m)
 
 pci:v0000104Cd0000B001*
  ID_MODEL_FROM_DATABASE=TMS320C6424
@@ -15141,10 +15432,10 @@ pci:v00001050d00000840*
  ID_MODEL_FROM_DATABASE=W89C840
 
 pci:v00001050d00000840sv00001050sd00000001*
- ID_MODEL_FROM_DATABASE=W89C840 Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=W89C840 (Ethernet Adapter)
 
 pci:v00001050d00000840sv00001050sd00000840*
- ID_MODEL_FROM_DATABASE=W89C840 Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=W89C840 (Ethernet Adapter)
 
 pci:v00001050d00000940*
  ID_MODEL_FROM_DATABASE=W89C940
@@ -15156,22 +15447,22 @@ pci:v00001050d00006692*
  ID_MODEL_FROM_DATABASE=W6692
 
 pci:v00001050d00006692sv00001043sd00001702*
- ID_MODEL_FROM_DATABASE=ISDN Adapter (PCI Bus, D, W)
+ ID_MODEL_FROM_DATABASE=W6692 (ISDN Adapter (PCI Bus, D, W))
 
 pci:v00001050d00006692sv00001043sd00001703*
- ID_MODEL_FROM_DATABASE=ISDN Adapter (PCI Bus, DV, W)
+ ID_MODEL_FROM_DATABASE=W6692 (ISDN Adapter (PCI Bus, DV, W))
 
 pci:v00001050d00006692sv00001043sd00001707*
- ID_MODEL_FROM_DATABASE=ISDN Adapter (PCI Bus, DV, W)
+ ID_MODEL_FROM_DATABASE=W6692 (ISDN Adapter (PCI Bus, DV, W))
 
 pci:v00001050d00006692sv0000144Fsd00001702*
- ID_MODEL_FROM_DATABASE=ISDN Adapter (PCI Bus, D, W)
+ ID_MODEL_FROM_DATABASE=W6692 (ISDN Adapter (PCI Bus, D, W))
 
 pci:v00001050d00006692sv0000144Fsd00001703*
- ID_MODEL_FROM_DATABASE=ISDN Adapter (PCI Bus, DV, W)
+ ID_MODEL_FROM_DATABASE=W6692 (ISDN Adapter (PCI Bus, DV, W))
 
 pci:v00001050d00006692sv0000144Fsd00001707*
- ID_MODEL_FROM_DATABASE=ISDN Adapter (PCI Bus, DV, W)
+ ID_MODEL_FROM_DATABASE=W6692 (ISDN Adapter (PCI Bus, DV, W))
 
 pci:v00001050d00009921*
  ID_MODEL_FROM_DATABASE=W99200F MPEG-1 Video Encoder
@@ -15233,6 +15524,9 @@ pci:v00001054d0000302C*
 pci:v00001054d0000302D*
  ID_MODEL_FROM_DATABASE=M001 PCI Express Switch Downstream Port
 
+pci:v00001054d00003070*
+ ID_MODEL_FROM_DATABASE=Hitachi FIVE-FX Fibre Channel to PCIe HBA
+
 pci:v00001054d00003505*
  ID_MODEL_FROM_DATABASE=SH7751 PCI Controller (PCIC)
 
@@ -15303,76 +15597,76 @@ pci:v00001057d00001801*
  ID_MODEL_FROM_DATABASE=DSP56301 Digital Signal Processor
 
 pci:v00001057d00001801sv000014FBsd00000101*
- ID_MODEL_FROM_DATABASE=Transas Radar Imitator Board [RIM]
+ ID_MODEL_FROM_DATABASE=DSP56301 Digital Signal Processor (Transas Radar Imitator Board [RIM])
 
 pci:v00001057d00001801sv000014FBsd00000102*
- ID_MODEL_FROM_DATABASE=Transas Radar Imitator Board [RIM-2]
+ ID_MODEL_FROM_DATABASE=DSP56301 Digital Signal Processor (Transas Radar Imitator Board [RIM-2])
 
 pci:v00001057d00001801sv000014FBsd00000202*
- ID_MODEL_FROM_DATABASE=Transas Radar Integrator Board [RIB-2]
+ ID_MODEL_FROM_DATABASE=DSP56301 Digital Signal Processor (Transas Radar Integrator Board [RIB-2])
 
 pci:v00001057d00001801sv000014FBsd00000611*
- ID_MODEL_FROM_DATABASE=1 channel CAN bus Controller [CanPci-1]
+ ID_MODEL_FROM_DATABASE=DSP56301 Digital Signal Processor (1 channel CAN bus Controller [CanPci-1])
 
 pci:v00001057d00001801sv000014FBsd00000612*
- ID_MODEL_FROM_DATABASE=2 channels CAN bus Controller [CanPci-2]
+ ID_MODEL_FROM_DATABASE=DSP56301 Digital Signal Processor (2 channels CAN bus Controller [CanPci-2])
 
 pci:v00001057d00001801sv000014FBsd00000613*
- ID_MODEL_FROM_DATABASE=3 channels CAN bus Controller [CanPci-3]
+ ID_MODEL_FROM_DATABASE=DSP56301 Digital Signal Processor (3 channels CAN bus Controller [CanPci-3])
 
 pci:v00001057d00001801sv000014FBsd00000614*
- ID_MODEL_FROM_DATABASE=4 channels CAN bus Controller [CanPci-4]
+ ID_MODEL_FROM_DATABASE=DSP56301 Digital Signal Processor (4 channels CAN bus Controller [CanPci-4])
 
 pci:v00001057d00001801sv000014FBsd00000621*
- ID_MODEL_FROM_DATABASE=1 channel CAN bus Controller [CanPci2-1]
+ ID_MODEL_FROM_DATABASE=DSP56301 Digital Signal Processor (1 channel CAN bus Controller [CanPci2-1])
 
 pci:v00001057d00001801sv000014FBsd00000622*
- ID_MODEL_FROM_DATABASE=2 channels CAN bus Controller [CanPci2-2]
+ ID_MODEL_FROM_DATABASE=DSP56301 Digital Signal Processor (2 channels CAN bus Controller [CanPci2-2])
 
 pci:v00001057d00001801sv000014FBsd00000810*
- ID_MODEL_FROM_DATABASE=Transas VTS Radar Integrator Board [RIB-4]
+ ID_MODEL_FROM_DATABASE=DSP56301 Digital Signal Processor (Transas VTS Radar Integrator Board [RIB-4])
 
 pci:v00001057d00001801sv0000175Csd00004200*
- ID_MODEL_FROM_DATABASE=ASI4215 Audio Adapter
+ ID_MODEL_FROM_DATABASE=DSP56301 Digital Signal Processor (ASI4215 Audio Adapter)
 
 pci:v00001057d00001801sv0000175Csd00004300*
- ID_MODEL_FROM_DATABASE=ASI43xx Audio Adapter
+ ID_MODEL_FROM_DATABASE=DSP56301 Digital Signal Processor (ASI43xx Audio Adapter)
 
 pci:v00001057d00001801sv0000175Csd00004400*
- ID_MODEL_FROM_DATABASE=ASI4401 Audio Adapter
+ ID_MODEL_FROM_DATABASE=DSP56301 Digital Signal Processor (ASI4401 Audio Adapter)
 
 pci:v00001057d00001801sv0000ECC0sd00000010*
- ID_MODEL_FROM_DATABASE=Darla
+ ID_MODEL_FROM_DATABASE=DSP56301 Digital Signal Processor (Darla)
 
 pci:v00001057d00001801sv0000ECC0sd00000020*
- ID_MODEL_FROM_DATABASE=Gina
+ ID_MODEL_FROM_DATABASE=DSP56301 Digital Signal Processor (Gina)
 
 pci:v00001057d00001801sv0000ECC0sd00000030*
- ID_MODEL_FROM_DATABASE=Layla rev.0
+ ID_MODEL_FROM_DATABASE=DSP56301 Digital Signal Processor (Layla rev.0)
 
 pci:v00001057d00001801sv0000ECC0sd00000031*
- ID_MODEL_FROM_DATABASE=Layla rev.1
+ ID_MODEL_FROM_DATABASE=DSP56301 Digital Signal Processor (Layla rev.1)
 
 pci:v00001057d00001801sv0000ECC0sd00000040*
- ID_MODEL_FROM_DATABASE=Darla24 rev.0
+ ID_MODEL_FROM_DATABASE=DSP56301 Digital Signal Processor (Darla24 rev.0)
 
 pci:v00001057d00001801sv0000ECC0sd00000041*
- ID_MODEL_FROM_DATABASE=Darla24 rev.1
+ ID_MODEL_FROM_DATABASE=DSP56301 Digital Signal Processor (Darla24 rev.1)
 
 pci:v00001057d00001801sv0000ECC0sd00000050*
- ID_MODEL_FROM_DATABASE=Gina24 rev.0
+ ID_MODEL_FROM_DATABASE=DSP56301 Digital Signal Processor (Gina24 rev.0)
 
 pci:v00001057d00001801sv0000ECC0sd00000051*
- ID_MODEL_FROM_DATABASE=Gina24 rev.1
+ ID_MODEL_FROM_DATABASE=DSP56301 Digital Signal Processor (Gina24 rev.1)
 
 pci:v00001057d00001801sv0000ECC0sd00000070*
- ID_MODEL_FROM_DATABASE=Mona rev.0
+ ID_MODEL_FROM_DATABASE=DSP56301 Digital Signal Processor (Mona rev.0)
 
 pci:v00001057d00001801sv0000ECC0sd00000071*
- ID_MODEL_FROM_DATABASE=Mona rev.1
+ ID_MODEL_FROM_DATABASE=DSP56301 Digital Signal Processor (Mona rev.1)
 
 pci:v00001057d00001801sv0000ECC0sd00000072*
- ID_MODEL_FROM_DATABASE=Mona rev.2
+ ID_MODEL_FROM_DATABASE=DSP56301 Digital Signal Processor (Mona rev.2)
 
 pci:v00001057d000018C0*
  ID_MODEL_FROM_DATABASE=MPC8265A/8266/8272
@@ -15387,40 +15681,40 @@ pci:v00001057d00003410*
  ID_MODEL_FROM_DATABASE=DSP56361 Digital Signal Processor
 
 pci:v00001057d00003410sv0000ECC0sd00000050*
- ID_MODEL_FROM_DATABASE=Gina24 rev.0
+ ID_MODEL_FROM_DATABASE=DSP56361 Digital Signal Processor (Gina24 rev.0)
 
 pci:v00001057d00003410sv0000ECC0sd00000051*
- ID_MODEL_FROM_DATABASE=Gina24 rev.1
+ ID_MODEL_FROM_DATABASE=DSP56361 Digital Signal Processor (Gina24 rev.1)
 
 pci:v00001057d00003410sv0000ECC0sd00000060*
- ID_MODEL_FROM_DATABASE=Layla24
+ ID_MODEL_FROM_DATABASE=DSP56361 Digital Signal Processor (Layla24)
 
 pci:v00001057d00003410sv0000ECC0sd00000070*
- ID_MODEL_FROM_DATABASE=Mona rev.0
+ ID_MODEL_FROM_DATABASE=DSP56361 Digital Signal Processor (Mona rev.0)
 
 pci:v00001057d00003410sv0000ECC0sd00000071*
- ID_MODEL_FROM_DATABASE=Mona rev.1
+ ID_MODEL_FROM_DATABASE=DSP56361 Digital Signal Processor (Mona rev.1)
 
 pci:v00001057d00003410sv0000ECC0sd00000072*
- ID_MODEL_FROM_DATABASE=Mona rev.2
+ ID_MODEL_FROM_DATABASE=DSP56361 Digital Signal Processor (Mona rev.2)
 
 pci:v00001057d00003410sv0000ECC0sd00000080*
- ID_MODEL_FROM_DATABASE=Mia rev.0
+ ID_MODEL_FROM_DATABASE=DSP56361 Digital Signal Processor (Mia rev.0)
 
 pci:v00001057d00003410sv0000ECC0sd00000081*
- ID_MODEL_FROM_DATABASE=Mia rev.1
+ ID_MODEL_FROM_DATABASE=DSP56361 Digital Signal Processor (Mia rev.1)
 
 pci:v00001057d00003410sv0000ECC0sd00000090*
- ID_MODEL_FROM_DATABASE=Indigo
+ ID_MODEL_FROM_DATABASE=DSP56361 Digital Signal Processor (Indigo)
 
 pci:v00001057d00003410sv0000ECC0sd000000A0*
- ID_MODEL_FROM_DATABASE=Indigo IO
+ ID_MODEL_FROM_DATABASE=DSP56361 Digital Signal Processor (Indigo IO)
 
 pci:v00001057d00003410sv0000ECC0sd000000B0*
- ID_MODEL_FROM_DATABASE=Indigo DJ
+ ID_MODEL_FROM_DATABASE=DSP56361 Digital Signal Processor (Indigo DJ)
 
 pci:v00001057d00003410sv0000ECC0sd00000100*
- ID_MODEL_FROM_DATABASE=3G
+ ID_MODEL_FROM_DATABASE=DSP56361 Digital Signal Processor (3G)
 
 pci:v00001057d00004801*
  ID_MODEL_FROM_DATABASE=Raven
@@ -15441,55 +15735,55 @@ pci:v00001057d00005600*
  ID_MODEL_FROM_DATABASE=SM56 PCI Modem
 
 pci:v00001057d00005600sv00001057sd00000300*
- ID_MODEL_FROM_DATABASE=SM56 PCI Speakerphone Modem
+ ID_MODEL_FROM_DATABASE=SM56 PCI Modem (SM56 PCI Speakerphone Modem)
 
 pci:v00001057d00005600sv00001057sd00000301*
- ID_MODEL_FROM_DATABASE=SM56 PCI Voice Modem
+ ID_MODEL_FROM_DATABASE=SM56 PCI Modem (SM56 PCI Voice Modem)
 
 pci:v00001057d00005600sv00001057sd00000302*
- ID_MODEL_FROM_DATABASE=SM56 PCI Fax Modem
+ ID_MODEL_FROM_DATABASE=SM56 PCI Modem (SM56 PCI Fax Modem)
 
 pci:v00001057d00005600sv00001057sd00005600*
- ID_MODEL_FROM_DATABASE=SM56 PCI Voice modem
+ ID_MODEL_FROM_DATABASE=SM56 PCI Modem (SM56 PCI Voice modem)
 
 pci:v00001057d00005600sv000013D2sd00000300*
- ID_MODEL_FROM_DATABASE=SM56 PCI Speakerphone Modem
+ ID_MODEL_FROM_DATABASE=SM56 PCI Modem (SM56 PCI Speakerphone Modem)
 
 pci:v00001057d00005600sv000013D2sd00000301*
- ID_MODEL_FROM_DATABASE=SM56 PCI Voice modem
+ ID_MODEL_FROM_DATABASE=SM56 PCI Modem (SM56 PCI Voice modem)
 
 pci:v00001057d00005600sv000013D2sd00000302*
- ID_MODEL_FROM_DATABASE=SM56 PCI Fax Modem
+ ID_MODEL_FROM_DATABASE=SM56 PCI Modem (SM56 PCI Fax Modem)
 
 pci:v00001057d00005600sv00001436sd00000300*
- ID_MODEL_FROM_DATABASE=SM56 PCI Speakerphone Modem
+ ID_MODEL_FROM_DATABASE=SM56 PCI Modem (SM56 PCI Speakerphone Modem)
 
 pci:v00001057d00005600sv00001436sd00000301*
- ID_MODEL_FROM_DATABASE=SM56 PCI Voice modem
+ ID_MODEL_FROM_DATABASE=SM56 PCI Modem (SM56 PCI Voice modem)
 
 pci:v00001057d00005600sv00001436sd00000302*
- ID_MODEL_FROM_DATABASE=SM56 PCI Fax Modem
+ ID_MODEL_FROM_DATABASE=SM56 PCI Modem (SM56 PCI Fax Modem)
 
 pci:v00001057d00005600sv0000144Fsd0000100C*
- ID_MODEL_FROM_DATABASE=SM56 PCI Fax Modem
+ ID_MODEL_FROM_DATABASE=SM56 PCI Modem (SM56 PCI Fax Modem)
 
 pci:v00001057d00005600sv00001494sd00000300*
- ID_MODEL_FROM_DATABASE=SM56 PCI Speakerphone Modem
+ ID_MODEL_FROM_DATABASE=SM56 PCI Modem (SM56 PCI Speakerphone Modem)
 
 pci:v00001057d00005600sv00001494sd00000301*
- ID_MODEL_FROM_DATABASE=SM56 PCI Voice modem
+ ID_MODEL_FROM_DATABASE=SM56 PCI Modem (SM56 PCI Voice modem)
 
 pci:v00001057d00005600sv000014C8sd00000300*
- ID_MODEL_FROM_DATABASE=SM56 PCI Speakerphone Modem
+ ID_MODEL_FROM_DATABASE=SM56 PCI Modem (SM56 PCI Speakerphone Modem)
 
 pci:v00001057d00005600sv000014C8sd00000302*
- ID_MODEL_FROM_DATABASE=SM56 PCI Fax Modem
+ ID_MODEL_FROM_DATABASE=SM56 PCI Modem (SM56 PCI Fax Modem)
 
 pci:v00001057d00005600sv00001668sd00000300*
- ID_MODEL_FROM_DATABASE=SM56 PCI Speakerphone Modem
+ ID_MODEL_FROM_DATABASE=SM56 PCI Modem (SM56 PCI Speakerphone Modem)
 
 pci:v00001057d00005600sv00001668sd00000302*
- ID_MODEL_FROM_DATABASE=SM56 PCI Fax Modem
+ ID_MODEL_FROM_DATABASE=SM56 PCI Modem (SM56 PCI Fax Modem)
 
 pci:v00001057d00005608*
  ID_MODEL_FROM_DATABASE=Wildcard X100P
@@ -15525,16 +15819,16 @@ pci:v0000105Ad00000D30*
  ID_MODEL_FROM_DATABASE=PDC20265 (FastTrak100 Lite/Ultra100)
 
 pci:v0000105Ad00000D30sv00001043sd00008042*
- ID_MODEL_FROM_DATABASE=AV7266-E South Bridge Promise RAID
+ ID_MODEL_FROM_DATABASE=PDC20265 (FastTrak100 Lite/Ultra100) (AV7266-E South Bridge Promise RAID)
 
 pci:v0000105Ad00000D30sv0000105Asd00004D33*
- ID_MODEL_FROM_DATABASE=Ultra100
+ ID_MODEL_FROM_DATABASE=PDC20265 (FastTrak100 Lite/Ultra100) (Ultra100)
 
 pci:v0000105Ad00000D38*
  ID_MODEL_FROM_DATABASE=20263
 
 pci:v0000105Ad00000D38sv0000105Asd00004D39*
- ID_MODEL_FROM_DATABASE=Fasttrak66
+ ID_MODEL_FROM_DATABASE=20263 (Fasttrak66)
 
 pci:v0000105Ad00001275*
  ID_MODEL_FROM_DATABASE=20275
@@ -15546,10 +15840,10 @@ pci:v0000105Ad00003319*
  ID_MODEL_FROM_DATABASE=PDC20319 (FastTrak S150 TX4)
 
 pci:v0000105Ad00003319sv0000105Asd00003319*
- ID_MODEL_FROM_DATABASE=FastTrak S150 TX4 4 port SATA PCI board
+ ID_MODEL_FROM_DATABASE=PDC20319 (FastTrak S150 TX4) (FastTrak S150 TX4 4 port SATA PCI board)
 
 pci:v0000105Ad00003319sv00008086sd00003427*
- ID_MODEL_FROM_DATABASE=S875WP1-E mainboard
+ ID_MODEL_FROM_DATABASE=PDC20319 (FastTrak S150 TX4) (S875WP1-E mainboard)
 
 pci:v0000105Ad00003371*
  ID_MODEL_FROM_DATABASE=PDC20371 (FastTrak S150 TX2plus)
@@ -15558,13 +15852,13 @@ pci:v0000105Ad00003373*
  ID_MODEL_FROM_DATABASE=PDC20378 (FastTrak 378/SATA 378)
 
 pci:v0000105Ad00003373sv00001043sd000080F5*
- ID_MODEL_FROM_DATABASE=K8V Deluxe/PC-DL Deluxe motherboard
+ ID_MODEL_FROM_DATABASE=PDC20378 (FastTrak 378/SATA 378) (K8V Deluxe/PC-DL Deluxe motherboard)
 
 pci:v0000105Ad00003373sv00001462sd0000590D*
- ID_MODEL_FROM_DATABASE=KT6 Delta-FIS2R (MS-6590)
+ ID_MODEL_FROM_DATABASE=PDC20378 (FastTrak 378/SATA 378) (KT6 Delta-FIS2R (MS-6590))
 
 pci:v0000105Ad00003373sv00001462sd0000702E*
- ID_MODEL_FROM_DATABASE=K8T NEO FIS2R motherboard
+ ID_MODEL_FROM_DATABASE=PDC20378 (FastTrak 378/SATA 378) (K8T NEO FIS2R motherboard)
 
 pci:v0000105Ad00003375*
  ID_MODEL_FROM_DATABASE=PDC20375 (SATA150 TX2plus)
@@ -15573,7 +15867,7 @@ pci:v0000105Ad00003376*
  ID_MODEL_FROM_DATABASE=PDC20376 (FastTrak 376)
 
 pci:v0000105Ad00003376sv00001043sd0000809E*
- ID_MODEL_FROM_DATABASE=A7V8X motherboard
+ ID_MODEL_FROM_DATABASE=PDC20376 (FastTrak 376) (A7V8X motherboard)
 
 pci:v0000105Ad00003515*
  ID_MODEL_FROM_DATABASE=PDC40719 [FastTrak TX4300/TX4310]
@@ -15615,58 +15909,58 @@ pci:v0000105Ad00004D30*
  ID_MODEL_FROM_DATABASE=PDC20267 (FastTrak100/Ultra100)
 
 pci:v0000105Ad00004D30sv0000105Asd00004D33*
- ID_MODEL_FROM_DATABASE=Ultra100
+ ID_MODEL_FROM_DATABASE=PDC20267 (FastTrak100/Ultra100) (Ultra100)
 
 pci:v0000105Ad00004D30sv0000105Asd00004D39*
- ID_MODEL_FROM_DATABASE=FastTrak100
+ ID_MODEL_FROM_DATABASE=PDC20267 (FastTrak100/Ultra100) (FastTrak100)
 
 pci:v0000105Ad00004D30sv00008086sd00005744*
- ID_MODEL_FROM_DATABASE=S845WD1-E mainboard
+ ID_MODEL_FROM_DATABASE=PDC20267 (FastTrak100/Ultra100) (S845WD1-E mainboard)
 
 pci:v0000105Ad00004D33*
  ID_MODEL_FROM_DATABASE=20246
 
 pci:v0000105Ad00004D33sv0000105Asd00004D33*
- ID_MODEL_FROM_DATABASE=20246 IDE Controller
+ ID_MODEL_FROM_DATABASE=20246 (IDE Controller)
 
 pci:v0000105Ad00004D38*
  ID_MODEL_FROM_DATABASE=PDC20262 (FastTrak66/Ultra66)
 
 pci:v0000105Ad00004D38sv0000105Asd00004D30*
- ID_MODEL_FROM_DATABASE=Ultra Device on SuperTrak
+ ID_MODEL_FROM_DATABASE=PDC20262 (FastTrak66/Ultra66) (Ultra Device on SuperTrak)
 
 pci:v0000105Ad00004D38sv0000105Asd00004D33*
- ID_MODEL_FROM_DATABASE=Ultra66
+ ID_MODEL_FROM_DATABASE=PDC20262 (FastTrak66/Ultra66) (Ultra66)
 
 pci:v0000105Ad00004D38sv0000105Asd00004D39*
- ID_MODEL_FROM_DATABASE=FastTrak66
+ ID_MODEL_FROM_DATABASE=PDC20262 (FastTrak66/Ultra66) (FastTrak66)
 
 pci:v0000105Ad00004D68*
  ID_MODEL_FROM_DATABASE=PDC20268 [Ultra100 TX2]
 
 pci:v0000105Ad00004D68sv0000105Asd00004D68*
- ID_MODEL_FROM_DATABASE=Ultra100 TX2
+ ID_MODEL_FROM_DATABASE=PDC20268 [Ultra100 TX2] (Ultra100 TX2)
 
 pci:v0000105Ad00004D69*
  ID_MODEL_FROM_DATABASE=20269
 
 pci:v0000105Ad00004D69sv0000105Asd00004D68*
- ID_MODEL_FROM_DATABASE=Ultra133TX2
+ ID_MODEL_FROM_DATABASE=20269 (Ultra133TX2)
 
 pci:v0000105Ad00005275*
  ID_MODEL_FROM_DATABASE=PDC20276 (MBFastTrak133 Lite)
 
 pci:v0000105Ad00005275sv00001043sd0000807E*
- ID_MODEL_FROM_DATABASE=A7V333 motherboard.
+ ID_MODEL_FROM_DATABASE=PDC20276 (MBFastTrak133 Lite) (A7V333 motherboard.)
 
 pci:v0000105Ad00005275sv0000105Asd00000275*
- ID_MODEL_FROM_DATABASE=SuperTrak SX6000 IDE
+ ID_MODEL_FROM_DATABASE=PDC20276 (MBFastTrak133 Lite) (SuperTrak SX6000 IDE)
 
 pci:v0000105Ad00005275sv0000105Asd00001275*
- ID_MODEL_FROM_DATABASE=MBFastTrak133 Lite (tm) Controller (RAID mode)
+ ID_MODEL_FROM_DATABASE=PDC20276 (MBFastTrak133 Lite) (MBFastTrak133 Lite (tm) Controller (RAID mode))
 
 pci:v0000105Ad00005275sv00001458sd0000B001*
- ID_MODEL_FROM_DATABASE=MBUltra 133
+ ID_MODEL_FROM_DATABASE=PDC20276 (MBFastTrak133 Lite) (MBUltra 133)
 
 pci:v0000105Ad00005300*
  ID_MODEL_FROM_DATABASE=DC5300
@@ -15675,13 +15969,13 @@ pci:v0000105Ad00006268*
  ID_MODEL_FROM_DATABASE=PDC20270 (FastTrak100 LP/TX2/TX4)
 
 pci:v0000105Ad00006268sv0000105Asd00004D68*
- ID_MODEL_FROM_DATABASE=FastTrak100 TX2
+ ID_MODEL_FROM_DATABASE=PDC20270 (FastTrak100 LP/TX2/TX4) (FastTrak100 TX2)
 
 pci:v0000105Ad00006269*
  ID_MODEL_FROM_DATABASE=PDC20271 (FastTrak TX2000)
 
 pci:v0000105Ad00006269sv0000105Asd00006269*
- ID_MODEL_FROM_DATABASE=FastTrak TX2/TX2000
+ ID_MODEL_FROM_DATABASE=PDC20271 (FastTrak TX2000) (FastTrak TX2/TX2000)
 
 pci:v0000105Ad00006300*
  ID_MODEL_FROM_DATABASE=PDC81731 [FastTrak SX8300]
@@ -15714,43 +16008,43 @@ pci:v0000105Ad00008650*
  ID_MODEL_FROM_DATABASE=81384 [SuperTrak EX SAS and SATA RAID Controller]
 
 pci:v0000105Ad00008650sv0000105Asd00004600*
- ID_MODEL_FROM_DATABASE=SuperTrak EX4650A
+ ID_MODEL_FROM_DATABASE=81384 [SuperTrak EX SAS and SATA RAID Controller] (SuperTrak EX4650A)
 
 pci:v0000105Ad00008650sv0000105Asd00004601*
- ID_MODEL_FROM_DATABASE=SuperTrak EX4650
+ ID_MODEL_FROM_DATABASE=81384 [SuperTrak EX SAS and SATA RAID Controller] (SuperTrak EX4650)
 
 pci:v0000105Ad00008650sv0000105Asd00004610*
- ID_MODEL_FROM_DATABASE=SuperTrak EX4650EL
+ ID_MODEL_FROM_DATABASE=81384 [SuperTrak EX SAS and SATA RAID Controller] (SuperTrak EX4650EL)
 
 pci:v0000105Ad00008650sv0000105Asd00008600*
- ID_MODEL_FROM_DATABASE=SuperTrak EX8650EL
+ ID_MODEL_FROM_DATABASE=81384 [SuperTrak EX SAS and SATA RAID Controller] (SuperTrak EX8650EL)
 
 pci:v0000105Ad00008650sv0000105Asd00008601*
- ID_MODEL_FROM_DATABASE=SuperTrak EX8650A
+ ID_MODEL_FROM_DATABASE=81384 [SuperTrak EX SAS and SATA RAID Controller] (SuperTrak EX8650A)
 
 pci:v0000105Ad00008650sv0000105Asd00008602*
- ID_MODEL_FROM_DATABASE=SuperTrak EX8654
+ ID_MODEL_FROM_DATABASE=81384 [SuperTrak EX SAS and SATA RAID Controller] (SuperTrak EX8654)
 
 pci:v0000105Ad00008650sv0000105Asd00008603*
- ID_MODEL_FROM_DATABASE=SuperTrak EX8658
+ ID_MODEL_FROM_DATABASE=81384 [SuperTrak EX SAS and SATA RAID Controller] (SuperTrak EX8658)
 
 pci:v0000105Ad00008650sv0000105Asd00008604*
- ID_MODEL_FROM_DATABASE=SuperTrak EX8650
+ ID_MODEL_FROM_DATABASE=81384 [SuperTrak EX SAS and SATA RAID Controller] (SuperTrak EX8650)
 
 pci:v0000105Ad00008650sv0000105Asd00008610*
- ID_MODEL_FROM_DATABASE=SuperTrak EX8650M
+ ID_MODEL_FROM_DATABASE=81384 [SuperTrak EX SAS and SATA RAID Controller] (SuperTrak EX8650M)
 
 pci:v0000105Ad00008650sv0000105Asd0000A600*
- ID_MODEL_FROM_DATABASE=SuperTrak EX12650
+ ID_MODEL_FROM_DATABASE=81384 [SuperTrak EX SAS and SATA RAID Controller] (SuperTrak EX12650)
 
 pci:v0000105Ad00008650sv0000105Asd0000B600*
- ID_MODEL_FROM_DATABASE=SuperTrak EX16650
+ ID_MODEL_FROM_DATABASE=81384 [SuperTrak EX SAS and SATA RAID Controller] (SuperTrak EX16650)
 
 pci:v0000105Ad00008650sv0000105Asd0000B601*
- ID_MODEL_FROM_DATABASE=SuperTrak EX16654
+ ID_MODEL_FROM_DATABASE=81384 [SuperTrak EX SAS and SATA RAID Controller] (SuperTrak EX16654)
 
 pci:v0000105Ad00008650sv0000105Asd0000B602*
- ID_MODEL_FROM_DATABASE=SuperTrak EX16658
+ ID_MODEL_FROM_DATABASE=81384 [SuperTrak EX SAS and SATA RAID Controller] (SuperTrak EX16658)
 
 pci:v0000105Ad00008760*
  ID_MODEL_FROM_DATABASE=PM8010 [SuperTrak EX SAS and SATA 6G RAID Controller]
@@ -15777,106 +16071,106 @@ pci:v0000105Dd00002339*
  ID_MODEL_FROM_DATABASE=Imagine 128-II
 
 pci:v0000105Dd00002339sv0000105Dsd00000000*
- ID_MODEL_FROM_DATABASE=Imagine 128 series 2 4Mb VRAM
+ ID_MODEL_FROM_DATABASE=Imagine 128-II (Imagine 128 series 2 4Mb VRAM)
 
 pci:v0000105Dd00002339sv0000105Dsd00000001*
- ID_MODEL_FROM_DATABASE=Imagine 128 series 2 4Mb VRAM
+ ID_MODEL_FROM_DATABASE=Imagine 128-II (Imagine 128 series 2 4Mb VRAM)
 
 pci:v0000105Dd00002339sv0000105Dsd00000002*
- ID_MODEL_FROM_DATABASE=Imagine 128 series 2 4Mb VRAM
+ ID_MODEL_FROM_DATABASE=Imagine 128-II (Imagine 128 series 2 4Mb VRAM)
 
 pci:v0000105Dd00002339sv0000105Dsd00000003*
- ID_MODEL_FROM_DATABASE=Imagine 128 series 2 4Mb VRAM
+ ID_MODEL_FROM_DATABASE=Imagine 128-II (Imagine 128 series 2 4Mb VRAM)
 
 pci:v0000105Dd00002339sv0000105Dsd00000004*
- ID_MODEL_FROM_DATABASE=Imagine 128 series 2 4Mb VRAM
+ ID_MODEL_FROM_DATABASE=Imagine 128-II (Imagine 128 series 2 4Mb VRAM)
 
 pci:v0000105Dd00002339sv0000105Dsd00000005*
- ID_MODEL_FROM_DATABASE=Imagine 128 series 2 4Mb VRAM
+ ID_MODEL_FROM_DATABASE=Imagine 128-II (Imagine 128 series 2 4Mb VRAM)
 
 pci:v0000105Dd00002339sv0000105Dsd00000006*
- ID_MODEL_FROM_DATABASE=Imagine 128 series 2 4Mb VRAM
+ ID_MODEL_FROM_DATABASE=Imagine 128-II (Imagine 128 series 2 4Mb VRAM)
 
 pci:v0000105Dd00002339sv0000105Dsd00000007*
- ID_MODEL_FROM_DATABASE=Imagine 128 series 2 4Mb VRAM
+ ID_MODEL_FROM_DATABASE=Imagine 128-II (Imagine 128 series 2 4Mb VRAM)
 
 pci:v0000105Dd00002339sv0000105Dsd00000008*
- ID_MODEL_FROM_DATABASE=Imagine 128 series 2e 4Mb DRAM
+ ID_MODEL_FROM_DATABASE=Imagine 128-II (Imagine 128 series 2e 4Mb DRAM)
 
 pci:v0000105Dd00002339sv0000105Dsd00000009*
- ID_MODEL_FROM_DATABASE=Imagine 128 series 2e 4Mb DRAM
+ ID_MODEL_FROM_DATABASE=Imagine 128-II (Imagine 128 series 2e 4Mb DRAM)
 
 pci:v0000105Dd00002339sv0000105Dsd0000000A*
- ID_MODEL_FROM_DATABASE=Imagine 128 series 2 8Mb VRAM
+ ID_MODEL_FROM_DATABASE=Imagine 128-II (Imagine 128 series 2 8Mb VRAM)
 
 pci:v0000105Dd00002339sv0000105Dsd0000000B*
- ID_MODEL_FROM_DATABASE=Imagine 128 series 2 8Mb H-VRAM
+ ID_MODEL_FROM_DATABASE=Imagine 128-II (Imagine 128 series 2 8Mb H-VRAM)
 
 pci:v0000105Dd00002339sv000011A4sd0000000A*
- ID_MODEL_FROM_DATABASE=Barco Metheus 5 Megapixel
+ ID_MODEL_FROM_DATABASE=Imagine 128-II (Barco Metheus 5 Megapixel)
 
 pci:v0000105Dd00002339sv000013CCsd00000000*
- ID_MODEL_FROM_DATABASE=Barco Metheus 5 Megapixel
+ ID_MODEL_FROM_DATABASE=Imagine 128-II (Barco Metheus 5 Megapixel)
 
 pci:v0000105Dd00002339sv000013CCsd00000004*
- ID_MODEL_FROM_DATABASE=Barco Metheus 5 Megapixel
+ ID_MODEL_FROM_DATABASE=Imagine 128-II (Barco Metheus 5 Megapixel)
 
 pci:v0000105Dd00002339sv000013CCsd00000005*
- ID_MODEL_FROM_DATABASE=Barco Metheus 5 Megapixel
+ ID_MODEL_FROM_DATABASE=Imagine 128-II (Barco Metheus 5 Megapixel)
 
 pci:v0000105Dd00002339sv000013CCsd00000006*
- ID_MODEL_FROM_DATABASE=Barco Metheus 5 Megapixel
+ ID_MODEL_FROM_DATABASE=Imagine 128-II (Barco Metheus 5 Megapixel)
 
 pci:v0000105Dd00002339sv000013CCsd00000008*
- ID_MODEL_FROM_DATABASE=Barco Metheus 5 Megapixel
+ ID_MODEL_FROM_DATABASE=Imagine 128-II (Barco Metheus 5 Megapixel)
 
 pci:v0000105Dd00002339sv000013CCsd00000009*
- ID_MODEL_FROM_DATABASE=Barco Metheus 5 Megapixel
+ ID_MODEL_FROM_DATABASE=Imagine 128-II (Barco Metheus 5 Megapixel)
 
 pci:v0000105Dd00002339sv000013CCsd0000000A*
- ID_MODEL_FROM_DATABASE=Barco Metheus 5 Megapixel
+ ID_MODEL_FROM_DATABASE=Imagine 128-II (Barco Metheus 5 Megapixel)
 
 pci:v0000105Dd00002339sv000013CCsd0000000C*
- ID_MODEL_FROM_DATABASE=Barco Metheus 5 Megapixel
+ ID_MODEL_FROM_DATABASE=Imagine 128-II (Barco Metheus 5 Megapixel)
 
 pci:v0000105Dd0000493D*
  ID_MODEL_FROM_DATABASE=Imagine 128 T2R [Ticket to Ride]
 
 pci:v0000105Dd0000493Dsv000011A4sd0000000A*
- ID_MODEL_FROM_DATABASE=Barco Metheus 5 Megapixel, Dual Head
+ ID_MODEL_FROM_DATABASE=Imagine 128 T2R [Ticket to Ride] (Barco Metheus 5 Megapixel, Dual Head)
 
 pci:v0000105Dd0000493Dsv000011A4sd0000000B*
- ID_MODEL_FROM_DATABASE=Barco Metheus 5 Megapixel, Dual Head
+ ID_MODEL_FROM_DATABASE=Imagine 128 T2R [Ticket to Ride] (Barco Metheus 5 Megapixel, Dual Head)
 
 pci:v0000105Dd0000493Dsv000013CCsd00000002*
- ID_MODEL_FROM_DATABASE=Barco Metheus 4 Megapixel, Dual Head
+ ID_MODEL_FROM_DATABASE=Imagine 128 T2R [Ticket to Ride] (Barco Metheus 4 Megapixel, Dual Head)
 
 pci:v0000105Dd0000493Dsv000013CCsd00000003*
- ID_MODEL_FROM_DATABASE=Barco Metheus 5 Megapixel, Dual Head
+ ID_MODEL_FROM_DATABASE=Imagine 128 T2R [Ticket to Ride] (Barco Metheus 5 Megapixel, Dual Head)
 
 pci:v0000105Dd0000493Dsv000013CCsd00000007*
- ID_MODEL_FROM_DATABASE=Barco Metheus 5 Megapixel, Dual Head
+ ID_MODEL_FROM_DATABASE=Imagine 128 T2R [Ticket to Ride] (Barco Metheus 5 Megapixel, Dual Head)
 
 pci:v0000105Dd0000493Dsv000013CCsd00000008*
- ID_MODEL_FROM_DATABASE=Barco Metheus 5 Megapixel, Dual Head
+ ID_MODEL_FROM_DATABASE=Imagine 128 T2R [Ticket to Ride] (Barco Metheus 5 Megapixel, Dual Head)
 
 pci:v0000105Dd0000493Dsv000013CCsd00000009*
- ID_MODEL_FROM_DATABASE=Barco Metheus 5 Megapixel, Dual Head
+ ID_MODEL_FROM_DATABASE=Imagine 128 T2R [Ticket to Ride] (Barco Metheus 5 Megapixel, Dual Head)
 
 pci:v0000105Dd0000493Dsv000013CCsd0000000A*
- ID_MODEL_FROM_DATABASE=Barco Metheus 5 Megapixel, Dual Head
+ ID_MODEL_FROM_DATABASE=Imagine 128 T2R [Ticket to Ride] (Barco Metheus 5 Megapixel, Dual Head)
 
 pci:v0000105Dd00005348*
  ID_MODEL_FROM_DATABASE=Revolution 4
 
 pci:v0000105Dd00005348sv0000105Dsd00000037*
- ID_MODEL_FROM_DATABASE=Revolution IV-FP AGP (For SGI 1600SW)
+ ID_MODEL_FROM_DATABASE=Revolution 4 (Revolution IV-FP AGP (For SGI 1600SW))
 
 pci:v0000105Dd00005348sv000011A4sd00000028*
- ID_MODEL_FROM_DATABASE=PVS5600M
+ ID_MODEL_FROM_DATABASE=Revolution 4 (PVS5600M)
 
 pci:v0000105Dd00005348sv000011A4sd00000038*
- ID_MODEL_FROM_DATABASE=PVS5600D
+ ID_MODEL_FROM_DATABASE=Revolution 4 (PVS5600D)
 
 pci:v0000105E*
  ID_VENDOR_FROM_DATABASE=Vtech Computers Ltd
@@ -16038,43 +16332,43 @@ pci:v00001069d00000050*
  ID_MODEL_FROM_DATABASE=AcceleRAID 352/170/160 support Device
 
 pci:v00001069d00000050sv00001069sd00000050*
- ID_MODEL_FROM_DATABASE=AcceleRAID 352 support Device
+ ID_MODEL_FROM_DATABASE=AcceleRAID 352/170/160 support Device (AcceleRAID 352 support Device)
 
 pci:v00001069d00000050sv00001069sd00000052*
- ID_MODEL_FROM_DATABASE=AcceleRAID 170 support Device
+ ID_MODEL_FROM_DATABASE=AcceleRAID 352/170/160 support Device (AcceleRAID 170 support Device)
 
 pci:v00001069d00000050sv00001069sd00000054*
- ID_MODEL_FROM_DATABASE=AcceleRAID 160 support Device
+ ID_MODEL_FROM_DATABASE=AcceleRAID 352/170/160 support Device (AcceleRAID 160 support Device)
 
 pci:v00001069d0000B166*
  ID_MODEL_FROM_DATABASE=AcceleRAID 600/500/400/Sapphire support Device
 
 pci:v00001069d0000B166sv00001014sd00000242*
- ID_MODEL_FROM_DATABASE=iSeries 2872 DASD IOA
+ ID_MODEL_FROM_DATABASE=AcceleRAID 600/500/400/Sapphire support Device (iSeries 2872 DASD IOA)
 
 pci:v00001069d0000B166sv00001014sd00000266*
- ID_MODEL_FROM_DATABASE=Dual Channel PCI-X U320 SCSI Adapter
+ ID_MODEL_FROM_DATABASE=AcceleRAID 600/500/400/Sapphire support Device (Dual Channel PCI-X U320 SCSI Adapter)
 
 pci:v00001069d0000B166sv00001014sd00000278*
- ID_MODEL_FROM_DATABASE=Dual Channel PCI-X U320 SCSI RAID Adapter
+ ID_MODEL_FROM_DATABASE=AcceleRAID 600/500/400/Sapphire support Device (Dual Channel PCI-X U320 SCSI RAID Adapter)
 
 pci:v00001069d0000B166sv00001014sd000002D3*
- ID_MODEL_FROM_DATABASE=Dual Channel PCI-X U320 SCSI Adapter
+ ID_MODEL_FROM_DATABASE=AcceleRAID 600/500/400/Sapphire support Device (Dual Channel PCI-X U320 SCSI Adapter)
 
 pci:v00001069d0000B166sv00001014sd000002D4*
- ID_MODEL_FROM_DATABASE=Dual Channel PCI-X U320 SCSI RAID Adapter
+ ID_MODEL_FROM_DATABASE=AcceleRAID 600/500/400/Sapphire support Device (Dual Channel PCI-X U320 SCSI RAID Adapter)
 
 pci:v00001069d0000B166sv00001069sd00000200*
- ID_MODEL_FROM_DATABASE=AcceleRAID 400, Single Channel, PCI-X, U320, SCSI RAID
+ ID_MODEL_FROM_DATABASE=AcceleRAID 600/500/400/Sapphire support Device (AcceleRAID 400, Single Channel, PCI-X, U320, SCSI RAID)
 
 pci:v00001069d0000B166sv00001069sd00000202*
- ID_MODEL_FROM_DATABASE=AcceleRAID Sapphire, Dual Channel, PCI-X, U320, SCSI RAID
+ ID_MODEL_FROM_DATABASE=AcceleRAID 600/500/400/Sapphire support Device (AcceleRAID Sapphire, Dual Channel, PCI-X, U320, SCSI RAID)
 
 pci:v00001069d0000B166sv00001069sd00000204*
- ID_MODEL_FROM_DATABASE=AcceleRAID 500, Dual Channel, Low-Profile, PCI-X, U320, SCSI RAID
+ ID_MODEL_FROM_DATABASE=AcceleRAID 600/500/400/Sapphire support Device (AcceleRAID 500, Dual Channel, Low-Profile, PCI-X, U320, SCSI RAID)
 
 pci:v00001069d0000B166sv00001069sd00000206*
- ID_MODEL_FROM_DATABASE=AcceleRAID 600, Dual Channel, PCI-X, U320, SCSI RAID
+ ID_MODEL_FROM_DATABASE=AcceleRAID 600/500/400/Sapphire support Device (AcceleRAID 600, Dual Channel, PCI-X, U320, SCSI RAID)
 
 pci:v00001069d0000BA55*
  ID_MODEL_FROM_DATABASE=eXtremeRAID 1100 support Device
@@ -16083,16 +16377,16 @@ pci:v00001069d0000BA56*
  ID_MODEL_FROM_DATABASE=eXtremeRAID 2000/3000 support Device
 
 pci:v00001069d0000BA56sv00001069sd00000030*
- ID_MODEL_FROM_DATABASE=eXtremeRAID 3000 support Device
+ ID_MODEL_FROM_DATABASE=eXtremeRAID 2000/3000 support Device (eXtremeRAID 3000 support Device)
 
 pci:v00001069d0000BA56sv00001069sd00000040*
- ID_MODEL_FROM_DATABASE=eXtremeRAID 2000 support Device
+ ID_MODEL_FROM_DATABASE=eXtremeRAID 2000/3000 support Device (eXtremeRAID 2000 support Device)
 
 pci:v00001069d0000BA57*
  ID_MODEL_FROM_DATABASE=eXtremeRAID 4000/5000 support Device
 
 pci:v00001069d0000BA57sv00001069sd00000072*
- ID_MODEL_FROM_DATABASE=eXtremeRAID 5000 support Device
+ ID_MODEL_FROM_DATABASE=eXtremeRAID 4000/5000 support Device (eXtremeRAID 5000 support Device)
 
 pci:v0000106A*
  ID_VENDOR_FROM_DATABASE=Aten Research Inc
@@ -16182,7 +16476,7 @@ pci:v0000106Bd00000031*
  ID_MODEL_FROM_DATABASE=UniNorth 2 FireWire
 
 pci:v0000106Bd00000031sv0000106Bsd00005811*
- ID_MODEL_FROM_DATABASE=iBook G4 2004
+ ID_MODEL_FROM_DATABASE=UniNorth 2 FireWire (iBook G4 2004)
 
 pci:v0000106Bd00000032*
  ID_MODEL_FROM_DATABASE=UniNorth 2 GMAC (Sun GEM)
@@ -16208,6 +16502,9 @@ pci:v0000106Bd0000003E*
 pci:v0000106Bd0000003F*
  ID_MODEL_FROM_DATABASE=KeyLargo/Intrepid USB
 
+pci:v0000106Bd0000003Fsv00001AF4sd00001100*
+ ID_MODEL_FROM_DATABASE=KeyLargo/Intrepid USB (QEMU Virtual Machine)
+
 pci:v0000106Bd00000040*
  ID_MODEL_FROM_DATABASE=K2 KeyLargo USB
 
@@ -16362,13 +16659,13 @@ pci:v00001073d00000004*
  ID_MODEL_FROM_DATABASE=YMF-724
 
 pci:v00001073d00000004sv00001073sd00000004*
- ID_MODEL_FROM_DATABASE=YMF724-Based PCI Audio Adapter
+ ID_MODEL_FROM_DATABASE=YMF-724 (YMF724-Based PCI Audio Adapter)
 
 pci:v00001073d00000005*
  ID_MODEL_FROM_DATABASE=DS1 Audio
 
 pci:v00001073d00000005sv00001073sd00000005*
- ID_MODEL_FROM_DATABASE=DS-XG PCI Audio CODEC
+ ID_MODEL_FROM_DATABASE=DS1 Audio (DS-XG PCI Audio CODEC)
 
 pci:v00001073d00000006*
  ID_MODEL_FROM_DATABASE=DS1 Audio
@@ -16377,46 +16674,46 @@ pci:v00001073d00000008*
  ID_MODEL_FROM_DATABASE=DS1 Audio
 
 pci:v00001073d00000008sv00001073sd00000008*
- ID_MODEL_FROM_DATABASE=DS-XG PCI Audio CODEC
+ ID_MODEL_FROM_DATABASE=DS1 Audio (DS-XG PCI Audio CODEC)
 
 pci:v00001073d0000000A*
  ID_MODEL_FROM_DATABASE=DS1L Audio
 
 pci:v00001073d0000000Asv00001073sd00000004*
- ID_MODEL_FROM_DATABASE=DS-XG PCI Audio CODEC
+ ID_MODEL_FROM_DATABASE=DS1L Audio (DS-XG PCI Audio CODEC)
 
 pci:v00001073d0000000Asv00001073sd0000000A*
- ID_MODEL_FROM_DATABASE=DS-XG PCI Audio CODEC
+ ID_MODEL_FROM_DATABASE=DS1L Audio (DS-XG PCI Audio CODEC)
 
 pci:v00001073d0000000Asv00008086sd00004D55*
- ID_MODEL_FROM_DATABASE=DS-XG PCI Audio CODEC [Intel MU440EX]
+ ID_MODEL_FROM_DATABASE=DS1L Audio (DS-XG PCI Audio CODEC [Intel MU440EX])
 
 pci:v00001073d0000000C*
  ID_MODEL_FROM_DATABASE=YMF-740C [DS-1L Audio Controller]
 
 pci:v00001073d0000000Csv0000107Asd0000000C*
- ID_MODEL_FROM_DATABASE=DS-XG PCI Audio CODEC
+ ID_MODEL_FROM_DATABASE=YMF-740C [DS-1L Audio Controller] (DS-XG PCI Audio CODEC)
 
 pci:v00001073d0000000D*
  ID_MODEL_FROM_DATABASE=YMF-724F [DS-1 Audio Controller]
 
 pci:v00001073d0000000Dsv00001073sd0000000D*
- ID_MODEL_FROM_DATABASE=DS-XG PCI Audio CODEC
+ ID_MODEL_FROM_DATABASE=YMF-724F [DS-1 Audio Controller] (DS-XG PCI Audio CODEC)
 
 pci:v00001073d00000010*
  ID_MODEL_FROM_DATABASE=YMF-744B [DS-1S Audio Controller]
 
 pci:v00001073d00000010sv00001073sd00000006*
- ID_MODEL_FROM_DATABASE=DS-XG PCI Audio CODEC
+ ID_MODEL_FROM_DATABASE=YMF-744B [DS-1S Audio Controller] (DS-XG PCI Audio CODEC)
 
 pci:v00001073d00000010sv00001073sd00000010*
- ID_MODEL_FROM_DATABASE=DS-XG PCI Audio CODEC
+ ID_MODEL_FROM_DATABASE=YMF-744B [DS-1S Audio Controller] (DS-XG PCI Audio CODEC)
 
 pci:v00001073d00000012*
  ID_MODEL_FROM_DATABASE=YMF-754 [DS-1E Audio Controller]
 
 pci:v00001073d00000012sv00001073sd00000012*
- ID_MODEL_FROM_DATABASE=DS-XG PCI Audio Codec
+ ID_MODEL_FROM_DATABASE=YMF-754 [DS-1E Audio Controller] (DS-XG PCI Audio Codec)
 
 pci:v00001073d00000020*
  ID_MODEL_FROM_DATABASE=DS-1 Audio
@@ -16461,10 +16758,10 @@ pci:v00001077d00001216*
  ID_MODEL_FROM_DATABASE=ISP12160 Dual Channel Ultra3 SCSI Processor
 
 pci:v00001077d00001216sv0000101Esd00008471*
- ID_MODEL_FROM_DATABASE=QLA12160 on AMI MegaRAID
+ ID_MODEL_FROM_DATABASE=ISP12160 Dual Channel Ultra3 SCSI Processor (QLA12160 on AMI MegaRAID)
 
 pci:v00001077d00001216sv0000101Esd00008493*
- ID_MODEL_FROM_DATABASE=QLA12160 on AMI MegaRAID
+ ID_MODEL_FROM_DATABASE=ISP12160 Dual Channel Ultra3 SCSI Processor (QLA12160 on AMI MegaRAID)
 
 pci:v00001077d00001240*
  ID_MODEL_FROM_DATABASE=ISP1240 SCSI Host Adapter
@@ -16488,7 +16785,7 @@ pci:v00001077d00002200*
  ID_MODEL_FROM_DATABASE=QLA2200 64-bit Fibre Channel Adapter
 
 pci:v00001077d00002200sv00001077sd00000002*
- ID_MODEL_FROM_DATABASE=QLA2200
+ ID_MODEL_FROM_DATABASE=QLA2200 64-bit Fibre Channel Adapter (QLA2200)
 
 pci:v00001077d00002300*
  ID_MODEL_FROM_DATABASE=QLA2300 64-bit Fibre Channel Adapter
@@ -16497,10 +16794,10 @@ pci:v00001077d00002312*
  ID_MODEL_FROM_DATABASE=ISP2312-based 2Gb Fibre Channel to PCI-X HBA
 
 pci:v00001077d00002312sv0000103Csd00000131*
- ID_MODEL_FROM_DATABASE=2Gb Fibre Channel - Single port [A7538A]
+ ID_MODEL_FROM_DATABASE=ISP2312-based 2Gb Fibre Channel to PCI-X HBA (2Gb Fibre Channel - Single port [A7538A])
 
 pci:v00001077d00002312sv0000103Csd000012BA*
- ID_MODEL_FROM_DATABASE=2Gb Fibre Channel - Dual port [A6826A]
+ ID_MODEL_FROM_DATABASE=ISP2312-based 2Gb Fibre Channel to PCI-X HBA (2Gb Fibre Channel - Dual port [A6826A])
 
 pci:v00001077d00002322*
  ID_MODEL_FROM_DATABASE=ISP2322-based 2Gb Fibre Channel to PCI-X HBA
@@ -16509,22 +16806,25 @@ pci:v00001077d00002422*
  ID_MODEL_FROM_DATABASE=ISP2422-based 4Gb Fibre Channel to PCI-X HBA
 
 pci:v00001077d00002422sv0000103Csd000012D7*
- ID_MODEL_FROM_DATABASE=4Gb Fibre Channel [AB379A]
+ ID_MODEL_FROM_DATABASE=ISP2422-based 4Gb Fibre Channel to PCI-X HBA (4Gb Fibre Channel [AB379A])
 
 pci:v00001077d00002422sv0000103Csd000012DD*
- ID_MODEL_FROM_DATABASE=4Gb Fibre Channel [AB429A]
+ ID_MODEL_FROM_DATABASE=ISP2422-based 4Gb Fibre Channel to PCI-X HBA (4Gb Fibre Channel [AB429A])
 
 pci:v00001077d00002432*
  ID_MODEL_FROM_DATABASE=ISP2432-based 4Gb Fibre Channel to PCI Express HBA
 
+pci:v00001077d00002432sv0000103Csd00007040*
+ ID_MODEL_FROM_DATABASE=ISP2432-based 4Gb Fibre Channel to PCI Express HBA (FC1142SR 4Gb 1-port PCIe Fibre Channel Host Bus Adapter [HPAE311A])
+
 pci:v00001077d00002532*
  ID_MODEL_FROM_DATABASE=ISP2532-based 8Gb Fibre Channel to PCI Express HBA
 
 pci:v00001077d00002532sv0000103Csd00003262*
- ID_MODEL_FROM_DATABASE=StorageWorks 81Q
+ ID_MODEL_FROM_DATABASE=ISP2532-based 8Gb Fibre Channel to PCI Express HBA (StorageWorks 81Q)
 
 pci:v00001077d00002532sv00001077sd00000167*
- ID_MODEL_FROM_DATABASE=QME2572 Dual Port FC8 HBA Mezzanine
+ ID_MODEL_FROM_DATABASE=ISP2532-based 8Gb Fibre Channel to PCI Express HBA (QME2572 Dual Port FC8 HBA Mezzanine)
 
 pci:v00001077d00003022*
  ID_MODEL_FROM_DATABASE=ISP4022-based Ethernet NIC
@@ -16566,55 +16866,55 @@ pci:v00001077d00008020*
  ID_MODEL_FROM_DATABASE=cLOM8214 1/10GbE Controller
 
 pci:v00001077d00008020sv0000103Csd00003346*
- ID_MODEL_FROM_DATABASE=CN1000Q Dual Port Converged Network Adapter
+ ID_MODEL_FROM_DATABASE=cLOM8214 1/10GbE Controller (CN1000Q Dual Port Converged Network Adapter)
 
 pci:v00001077d00008020sv0000103Csd00003733*
- ID_MODEL_FROM_DATABASE=NC523SFP 10Gb 2-port Server Adapter
+ ID_MODEL_FROM_DATABASE=cLOM8214 1/10GbE Controller (NC523SFP 10Gb 2-port Server Adapter)
 
 pci:v00001077d00008020sv00001077sd00000203*
- ID_MODEL_FROM_DATABASE=8200 Series Single Port 10GbE Converged Network Adapter (TCP/IP Networking)
+ ID_MODEL_FROM_DATABASE=cLOM8214 1/10GbE Controller (8200 Series Single Port 10GbE Converged Network Adapter (TCP/IP Networking))
 
 pci:v00001077d00008020sv00001077sd00000207*
- ID_MODEL_FROM_DATABASE=8200 Series Dual Port 10GbE Converged Network Adapter (TCP/IP Networking)
+ ID_MODEL_FROM_DATABASE=cLOM8214 1/10GbE Controller (8200 Series Dual Port 10GbE Converged Network Adapter (TCP/IP Networking))
 
 pci:v00001077d00008020sv00001077sd0000020B*
- ID_MODEL_FROM_DATABASE=3200 Series Dual Port 10Gb Intelligent Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=cLOM8214 1/10GbE Controller (3200 Series Dual Port 10Gb Intelligent Ethernet Adapter)
 
 pci:v00001077d00008020sv00001077sd0000020C*
- ID_MODEL_FROM_DATABASE=3200 Series Quad Port 1Gb Intelligent Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=cLOM8214 1/10GbE Controller (3200 Series Quad Port 1Gb Intelligent Ethernet Adapter)
 
 pci:v00001077d00008020sv00001077sd0000020F*
- ID_MODEL_FROM_DATABASE=3200 Series Single Port 10Gb Intelligent Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=cLOM8214 1/10GbE Controller (3200 Series Single Port 10Gb Intelligent Ethernet Adapter)
 
 pci:v00001077d00008020sv00001077sd00000210*
- ID_MODEL_FROM_DATABASE=QME8242-k 10GbE Dual Port Mezzanine Card
+ ID_MODEL_FROM_DATABASE=cLOM8214 1/10GbE Controller (QME8242-k 10GbE Dual Port Mezzanine Card)
 
 pci:v00001077d00008021*
  ID_MODEL_FROM_DATABASE=8200 Series 10GbE Converged Network Adapter (FCoE)
 
 pci:v00001077d00008021sv0000103Csd00003348*
- ID_MODEL_FROM_DATABASE=CN1000Q Dual Port Converged Network Adapter
+ ID_MODEL_FROM_DATABASE=8200 Series 10GbE Converged Network Adapter (FCoE) (CN1000Q Dual Port Converged Network Adapter)
 
 pci:v00001077d00008021sv00001077sd00000211*
- ID_MODEL_FROM_DATABASE=QME8242-k 10GbE Dual Port Mezzanine Card, FCoE
+ ID_MODEL_FROM_DATABASE=8200 Series 10GbE Converged Network Adapter (FCoE) (QME8242-k 10GbE Dual Port Mezzanine Card, FCoE)
 
 pci:v00001077d00008022*
  ID_MODEL_FROM_DATABASE=8200 Series 10GbE Converged Network Adapter (iSCSI)
 
 pci:v00001077d00008022sv0000103Csd00003347*
- ID_MODEL_FROM_DATABASE=CN1000Q Dual Port Converged Network Adapter
+ ID_MODEL_FROM_DATABASE=8200 Series 10GbE Converged Network Adapter (iSCSI) (CN1000Q Dual Port Converged Network Adapter)
 
 pci:v00001077d00008022sv00001077sd00000212*
- ID_MODEL_FROM_DATABASE=QME8242-k 10GbE Dual Port Mezzanine Card, iSCSI
+ ID_MODEL_FROM_DATABASE=8200 Series 10GbE Converged Network Adapter (iSCSI) (QME8242-k 10GbE Dual Port Mezzanine Card, iSCSI)
 
 pci:v00001077d00008030*
  ID_MODEL_FROM_DATABASE=ISP8324 1/10GbE Converged Network Controller
 
 pci:v00001077d00008030sv00001077sd00000243*
- ID_MODEL_FROM_DATABASE=8300 Series Single Port 10GbE Converged Network Adapter (TCP/IP Networking)
+ ID_MODEL_FROM_DATABASE=ISP8324 1/10GbE Converged Network Controller (8300 Series Single Port 10GbE Converged Network Adapter (TCP/IP Networking))
 
 pci:v00001077d00008030sv00001077sd00000246*
- ID_MODEL_FROM_DATABASE=8300 Series Dual Port 10GbE Converged Network Adapter (TCP/IP Networking)
+ ID_MODEL_FROM_DATABASE=ISP8324 1/10GbE Converged Network Controller (8300 Series Dual Port 10GbE Converged Network Adapter (TCP/IP Networking))
 
 pci:v00001077d00008031*
  ID_MODEL_FROM_DATABASE=8300 Series 10GbE Converged Network Adapter (FCoE)
@@ -16815,10 +17115,10 @@ pci:v0000108Dd00000002*
  ID_MODEL_FROM_DATABASE=16/4 Token Ring
 
 pci:v0000108Dd00000004*
- ID_MODEL_FROM_DATABASE=RapidFire 3139 Token-Ring 16/4 PCI Adapter
+ ID_MODEL_FROM_DATABASE=RapidFire OC-3139/3140 Token-Ring 16/4 PCI Adapter
 
 pci:v0000108Dd00000004sv0000108Dsd00000004*
- ID_MODEL_FROM_DATABASE=OC-3139/3140 RapidFire Token-Ring 16/4 Adapter
+ ID_MODEL_FROM_DATABASE=RapidFire OC-3139/3140 Token-Ring 16/4 PCI Adapter (OC-3139/3140 RapidFire Token-Ring 16/4 Adapter)
 
 pci:v0000108Dd00000005*
  ID_MODEL_FROM_DATABASE=GoCard 3250 Token-Ring 16/4 CardBus PC Card
@@ -16830,13 +17130,13 @@ pci:v0000108Dd00000007*
  ID_MODEL_FROM_DATABASE=RapidFire 3141 Token-Ring 16/4 PCI Fiber Adapter
 
 pci:v0000108Dd00000007sv0000108Dsd00000007*
- ID_MODEL_FROM_DATABASE=OC-3141 RapidFire Token-Ring 16/4 Adapter
+ ID_MODEL_FROM_DATABASE=RapidFire 3141 Token-Ring 16/4 PCI Fiber Adapter (OC-3141 RapidFire Token-Ring 16/4 Adapter)
 
 pci:v0000108Dd00000008*
  ID_MODEL_FROM_DATABASE=RapidFire 3540 HSTR 100/16/4 PCI Adapter
 
 pci:v0000108Dd00000008sv0000108Dsd00000008*
- ID_MODEL_FROM_DATABASE=OC-3540 RapidFire HSTR 100/16/4 Adapter
+ ID_MODEL_FROM_DATABASE=RapidFire 3540 HSTR 100/16/4 PCI Adapter (OC-3540 RapidFire HSTR 100/16/4 Adapter)
 
 pci:v0000108Dd00000011*
  ID_MODEL_FROM_DATABASE=OC-2315
@@ -16854,10 +17154,10 @@ pci:v0000108Dd00000019*
  ID_MODEL_FROM_DATABASE=OC-2327/2250 10/100 Ethernet Adapter
 
 pci:v0000108Dd00000019sv0000108Dsd00000016*
- ID_MODEL_FROM_DATABASE=OC-2327 Rapidfire 10/100 Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=OC-2327/2250 10/100 Ethernet Adapter (OC-2327 Rapidfire 10/100 Ethernet Adapter)
 
 pci:v0000108Dd00000019sv0000108Dsd00000017*
- ID_MODEL_FROM_DATABASE=OC-2250 GoCard 10/100 Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=OC-2327/2250 10/100 Ethernet Adapter (OC-2250 GoCard 10/100 Ethernet Adapter)
 
 pci:v0000108Dd00000021*
  ID_MODEL_FROM_DATABASE=OC-6151/6152 [RapidFire ATM 155]
@@ -16881,25 +17181,25 @@ pci:v0000108Ed00001100*
  ID_MODEL_FROM_DATABASE=RIO EBUS
 
 pci:v0000108Ed00001100sv0000108Esd00001100*
- ID_MODEL_FROM_DATABASE=RIO EBUS on Blade 100 motherboard
+ ID_MODEL_FROM_DATABASE=RIO EBUS (on Blade 100 motherboard)
 
 pci:v0000108Ed00001101*
  ID_MODEL_FROM_DATABASE=RIO 10/100 Ethernet [eri]
 
 pci:v0000108Ed00001101sv0000108Esd00001101*
- ID_MODEL_FROM_DATABASE=RIO GEM on Blade 100 motherboard
+ ID_MODEL_FROM_DATABASE=RIO 10/100 Ethernet [eri] (RIO GEM on Blade 100 motherboard)
 
 pci:v0000108Ed00001102*
  ID_MODEL_FROM_DATABASE=RIO 1394
 
 pci:v0000108Ed00001102sv0000108Esd00001102*
- ID_MODEL_FROM_DATABASE=RIO 1394 on Blade 100 motherboard
+ ID_MODEL_FROM_DATABASE=RIO 1394 (on Blade 100 motherboard)
 
 pci:v0000108Ed00001103*
  ID_MODEL_FROM_DATABASE=RIO USB
 
 pci:v0000108Ed00001103sv0000108Esd00001103*
- ID_MODEL_FROM_DATABASE=RIO USB on Blade 100 motherboard
+ ID_MODEL_FROM_DATABASE=RIO USB (on Blade 100 motherboard)
 
 pci:v0000108Ed00001647*
  ID_MODEL_FROM_DATABASE=Broadcom 570x 10/100/1000 Ethernet [bge]
@@ -16920,7 +17220,7 @@ pci:v0000108Ed00005000*
  ID_MODEL_FROM_DATABASE=Simba Advanced PCI Bridge
 
 pci:v0000108Ed00005000sv0000108Esd00005000*
- ID_MODEL_FROM_DATABASE=Netra AX1105-500
+ ID_MODEL_FROM_DATABASE=Simba Advanced PCI Bridge (Netra AX1105-500)
 
 pci:v0000108Ed00005043*
  ID_MODEL_FROM_DATABASE=SunPCI Co-processor
@@ -17022,7 +17322,7 @@ pci:v0000108Ed0000A001*
  ID_MODEL_FROM_DATABASE=Psycho UPA-PCI Bus Module [pcipsy]
 
 pci:v0000108Ed0000A001sv0000108Esd0000A001*
- ID_MODEL_FROM_DATABASE=Ultra IIe on Blade 100 motherboard
+ ID_MODEL_FROM_DATABASE=Psycho UPA-PCI Bus Module [pcipsy] (Ultra IIe on Blade 100 motherboard)
 
 pci:v0000108Ed0000A801*
  ID_MODEL_FROM_DATABASE=Schizo Fireplane-PCI bus bridge module [pcisch]
@@ -17091,7 +17391,7 @@ pci:v00001092d00000028*
  ID_MODEL_FROM_DATABASE=Viper V770
 
 pci:v00001092d00000028sv00001092sd00004A00*
- ID_MODEL_FROM_DATABASE=Viper V770 32MB
+ ID_MODEL_FROM_DATABASE=Viper V770 (32MB)
 
 pci:v00001092d000000A0*
  ID_MODEL_FROM_DATABASE=Speedstar Pro SE
@@ -17294,6 +17594,30 @@ pci:v00001093d00002CC0*
 pci:v00001093d00002DB0*
  ID_MODEL_FROM_DATABASE=PCI-6608
 
+pci:v00001093d0000702C*
+ ID_MODEL_FROM_DATABASE=PXI-7831R
+
+pci:v00001093d0000702D*
+ ID_MODEL_FROM_DATABASE=PCI-7831R
+
+pci:v00001093d0000702E*
+ ID_MODEL_FROM_DATABASE=PXI-7811R
+
+pci:v00001093d0000702F*
+ ID_MODEL_FROM_DATABASE=PCI-7811R
+
+pci:v00001093d00007055*
+ ID_MODEL_FROM_DATABASE=PXI-7830R
+
+pci:v00001093d00007056*
+ ID_MODEL_FROM_DATABASE=PCI-7830R
+
+pci:v00001093d00007074*
+ ID_MODEL_FROM_DATABASE=PXI-7833R
+
+pci:v00001093d00007083*
+ ID_MODEL_FROM_DATABASE=PCI-7833R
+
 pci:v00001093d00007085*
  ID_MODEL_FROM_DATABASE=PCI-6509
 
@@ -17369,6 +17693,9 @@ pci:v00001093d0000714C*
 pci:v00001093d0000714D*
  ID_MODEL_FROM_DATABASE=PCI-5114
 
+pci:v00001093d00007152*
+ ID_MODEL_FROM_DATABASE=PCI-5640R
+
 pci:v00001093d0000716C*
  ID_MODEL_FROM_DATABASE=PCI-6225
 
@@ -17378,12 +17705,21 @@ pci:v00001093d0000717D*
 pci:v00001093d0000717F*
  ID_MODEL_FROM_DATABASE=PCIe-6259
 
+pci:v00001093d00007193*
+ ID_MODEL_FROM_DATABASE=PXI-7813R
+
+pci:v00001093d00007194*
+ ID_MODEL_FROM_DATABASE=PCI-7813R
+
 pci:v00001093d000071BC*
  ID_MODEL_FROM_DATABASE=PCI-6221 (37pin)
 
 pci:v00001093d000071D0*
  ID_MODEL_FROM_DATABASE=PXI-6143
 
+pci:v00001093d000071DC*
+ ID_MODEL_FROM_DATABASE=PCI-1588
+
 pci:v00001093d00007260*
  ID_MODEL_FROM_DATABASE=PXI-5142
 
@@ -17402,6 +17738,9 @@ pci:v00001093d000072AA*
 pci:v00001093d000072AB*
  ID_MODEL_FROM_DATABASE=PCI-5105
 
+pci:v00001093d000072B8*
+ ID_MODEL_FROM_DATABASE=PXI-6682
+
 pci:v00001093d0000730F*
  ID_MODEL_FROM_DATABASE=PXI-5922EX
 
@@ -17420,12 +17759,60 @@ pci:v00001093d0000734A*
 pci:v00001093d0000737D*
  ID_MODEL_FROM_DATABASE=PXI-5124EX
 
+pci:v00001093d00007384*
+ ID_MODEL_FROM_DATABASE=PXI-7851R
+
+pci:v00001093d00007385*
+ ID_MODEL_FROM_DATABASE=PXI-7852R
+
+pci:v00001093d00007386*
+ ID_MODEL_FROM_DATABASE=PCIe-7851R
+
+pci:v00001093d00007387*
+ ID_MODEL_FROM_DATABASE=PCIe-7852R
+
+pci:v00001093d00007390*
+ ID_MODEL_FROM_DATABASE=PXI-7841R
+
+pci:v00001093d00007391*
+ ID_MODEL_FROM_DATABASE=PXI-7842R
+
+pci:v00001093d00007392*
+ ID_MODEL_FROM_DATABASE=PXI-7853R
+
+pci:v00001093d00007393*
+ ID_MODEL_FROM_DATABASE=PCIe-7841R
+
+pci:v00001093d00007394*
+ ID_MODEL_FROM_DATABASE=PCIe-7842R
+
+pci:v00001093d000073A5*
+ ID_MODEL_FROM_DATABASE=PXIe-5641R
+
+pci:v00001093d000073D5*
+ ID_MODEL_FROM_DATABASE=PXI-7951R
+
+pci:v00001093d000073D6*
+ ID_MODEL_FROM_DATABASE=PXI-7952R
+
+pci:v00001093d000073D7*
+ ID_MODEL_FROM_DATABASE=PXI-7953R
+
+pci:v00001093d000073E1*
+ ID_MODEL_FROM_DATABASE=PXI-7854R
+
+pci:v00001093d000073EC*
+ ID_MODEL_FROM_DATABASE=PXI-7954R
+
 pci:v00001093d000073F0*
  ID_MODEL_FROM_DATABASE=PXI-5153
 
 pci:v00001093d000073F1*
  ID_MODEL_FROM_DATABASE=PCI-5153
 
+pci:v00001093d00007405*
+ ID_MODEL_FROM_DATABASE=PXIe-6674T
+
 pci:v00001093d0000745E*
  ID_MODEL_FROM_DATABASE=PXI-5153EX
 
@@ -17438,6 +17825,24 @@ pci:v00001093d00007460*
 pci:v00001093d00007461*
  ID_MODEL_FROM_DATABASE=PCI-5154EX
 
+pci:v00001093d00007539*
+ ID_MODEL_FROM_DATABASE=NI 9157
+
+pci:v00001093d0000753A*
+ ID_MODEL_FROM_DATABASE=NI 9159
+
+pci:v00001093d000075E5*
+ ID_MODEL_FROM_DATABASE=PXI-6683
+
+pci:v00001093d000075E6*
+ ID_MODEL_FROM_DATABASE=PXI-6683H
+
+pci:v00001093d00007626*
+ ID_MODEL_FROM_DATABASE=NI 9154
+
+pci:v00001093d00007627*
+ ID_MODEL_FROM_DATABASE=NI 9155
+
 pci:v00001093d0000B001*
  ID_MODEL_FROM_DATABASE=IMAQ-PCI-1408
 
@@ -17469,10 +17874,31 @@ pci:v00001093d0000B091*
  ID_MODEL_FROM_DATABASE=IMAQ-PXI-1411
 
 pci:v00001093d0000C4C4*
- ID_MODEL_FROM_DATABASE=PXIe-4353/5160
+ ID_MODEL_FROM_DATABASE=PXIe/PCIe Device
+
+pci:v00001093d0000C4C4sv00001093sd000074B2*
+ ID_MODEL_FROM_DATABASE=PXIe/PCIe Device (PXIe-4353)
+
+pci:v00001093d0000C4C4sv00001093sd000074D0*
+ ID_MODEL_FROM_DATABASE=PXIe/PCIe Device (PXIe-7961R)
+
+pci:v00001093d0000C4C4sv00001093sd000074E2*
+ ID_MODEL_FROM_DATABASE=PXIe/PCIe Device (PXIe-7962R)
+
+pci:v00001093d0000C4C4sv00001093sd000074E3*
+ ID_MODEL_FROM_DATABASE=PXIe/PCIe Device (PXIe-7965R)
+
+pci:v00001093d0000C4C4sv00001093sd00007553*
+ ID_MODEL_FROM_DATABASE=PXIe/PCIe Device (PCIe-1473R)
+
+pci:v00001093d0000C4C4sv00001093sd000075CE*
+ ID_MODEL_FROM_DATABASE=PXIe/PCIe Device (PXIe-7966R)
+
+pci:v00001093d0000C4C4sv00001093sd000076B7*
+ ID_MODEL_FROM_DATABASE=PXIe/PCIe Device (PXIe-7975R)
 
 pci:v00001093d0000C4C4sv00001093sd000076D0*
- ID_MODEL_FROM_DATABASE=PXIe-5160
+ ID_MODEL_FROM_DATABASE=PXIe/PCIe Device (PXIe-5160)
 
 pci:v00001093d0000C801*
  ID_MODEL_FROM_DATABASE=PCI-GPIB
@@ -17505,19 +17931,19 @@ pci:v00001095d00000648*
  ID_MODEL_FROM_DATABASE=PCI0648
 
 pci:v00001095d00000648sv00001043sd00008025*
- ID_MODEL_FROM_DATABASE=CUBX motherboard
+ ID_MODEL_FROM_DATABASE=PCI0648 (CUBX motherboard)
 
 pci:v00001095d00000649*
  ID_MODEL_FROM_DATABASE=SiI 0649 Ultra ATA/100 PCI to ATA Host Controller
 
 pci:v00001095d00000649sv00000E11sd0000005D*
- ID_MODEL_FROM_DATABASE=Integrated Ultra ATA-100 Dual Channel Controller
+ ID_MODEL_FROM_DATABASE=SiI 0649 Ultra ATA/100 PCI to ATA Host Controller (Integrated Ultra ATA-100 Dual Channel Controller)
 
 pci:v00001095d00000649sv00000E11sd0000007E*
- ID_MODEL_FROM_DATABASE=Integrated Ultra ATA-100 IDE RAID Controller
+ ID_MODEL_FROM_DATABASE=SiI 0649 Ultra ATA/100 PCI to ATA Host Controller (Integrated Ultra ATA-100 IDE RAID Controller)
 
 pci:v00001095d00000649sv0000101Esd00000649*
- ID_MODEL_FROM_DATABASE=AMI MegaRAID IDE 100 Controller
+ ID_MODEL_FROM_DATABASE=SiI 0649 Ultra ATA/100 PCI to ATA Host Controller (AMI MegaRAID IDE 100 Controller)
 
 pci:v00001095d00000650*
  ID_MODEL_FROM_DATABASE=PBC0650A
@@ -17535,34 +17961,34 @@ pci:v00001095d00000680*
  ID_MODEL_FROM_DATABASE=PCI0680 Ultra ATA-133 Host Controller
 
 pci:v00001095d00000680sv00001095sd00000680*
- ID_MODEL_FROM_DATABASE=SiI 0680 ATA/133 Controller
+ ID_MODEL_FROM_DATABASE=PCI0680 Ultra ATA-133 Host Controller (SiI 0680 ATA/133 Controller)
 
 pci:v00001095d00000680sv00001095sd00003680*
- ID_MODEL_FROM_DATABASE=Winic W-680 (Silicon Image 680 based)
+ ID_MODEL_FROM_DATABASE=PCI0680 Ultra ATA-133 Host Controller (Winic W-680 (Silicon Image 680 based))
 
 pci:v00001095d00003112*
  ID_MODEL_FROM_DATABASE=SiI 3112 [SATALink/SATARaid] Serial ATA Controller
 
 pci:v00001095d00003112sv00001095sd00003112*
- ID_MODEL_FROM_DATABASE=SiI 3112 SATALink Controller
+ ID_MODEL_FROM_DATABASE=SiI 3112 [SATALink/SATARaid] Serial ATA Controller (SiI 3112 SATALink Controller)
 
 pci:v00001095d00003112sv00001095sd00006112*
- ID_MODEL_FROM_DATABASE=SiI 3112 SATARaid Controller
+ ID_MODEL_FROM_DATABASE=SiI 3112 [SATALink/SATARaid] Serial ATA Controller (SiI 3112 SATARaid Controller)
 
 pci:v00001095d00003112sv00009005sd00000250*
- ID_MODEL_FROM_DATABASE=SATAConnect 1205SA Host Controller
+ ID_MODEL_FROM_DATABASE=SiI 3112 [SATALink/SATARaid] Serial ATA Controller (SATAConnect 1205SA Host Controller)
 
 pci:v00001095d00003114*
  ID_MODEL_FROM_DATABASE=SiI 3114 [SATALink/SATARaid] Serial ATA Controller
 
 pci:v00001095d00003114sv00001043sd00008167*
- ID_MODEL_FROM_DATABASE=A8N-SLI Deluxe/Premium Mainboard
+ ID_MODEL_FROM_DATABASE=SiI 3114 [SATALink/SATARaid] Serial ATA Controller (A8N-SLI Deluxe/Premium Mainboard)
 
 pci:v00001095d00003114sv00001095sd00003114*
- ID_MODEL_FROM_DATABASE=SiI 3114 SATALink Controller
+ ID_MODEL_FROM_DATABASE=SiI 3114 [SATALink/SATARaid] Serial ATA Controller (SiI 3114 SATALink Controller)
 
 pci:v00001095d00003114sv00001095sd00006114*
- ID_MODEL_FROM_DATABASE=SiI 3114 SATARaid Controller
+ ID_MODEL_FROM_DATABASE=SiI 3114 [SATALink/SATARaid] Serial ATA Controller (SiI 3114 SATARaid Controller)
 
 pci:v00001095d00003124*
  ID_MODEL_FROM_DATABASE=SiI 3124 PCI-X Serial ATA Controller
@@ -17577,14 +18003,17 @@ pci:v00001095d00003512*
  ID_MODEL_FROM_DATABASE=SiI 3512 [SATALink/SATARaid] Serial ATA Controller
 
 pci:v00001095d00003512sv00001095sd00003512*
- ID_MODEL_FROM_DATABASE=SiI 3512 SATALink Controller
+ ID_MODEL_FROM_DATABASE=SiI 3512 [SATALink/SATARaid] Serial ATA Controller (SiI 3512 SATALink Controller)
 
 pci:v00001095d00003512sv00001095sd00006512*
- ID_MODEL_FROM_DATABASE=SiI 3512 SATARaid Controller
+ ID_MODEL_FROM_DATABASE=SiI 3512 [SATALink/SATARaid] Serial ATA Controller (SiI 3512 SATARaid Controller)
 
 pci:v00001095d00003531*
  ID_MODEL_FROM_DATABASE=SiI 3531 [SATALink/SATARaid] Serial ATA Controller
 
+pci:v00001095d00003531sv000017C0sd00004083*
+ ID_MODEL_FROM_DATABASE=SiI 3531 [SATALink/SATARaid] Serial ATA Controller (Medion WIM 2210 Notebook PC [MD96850])
+
 pci:v00001096*
  ID_VENDOR_FROM_DATABASE=Alacron
 
@@ -17634,367 +18063,412 @@ pci:v0000109Ed00000369*
  ID_MODEL_FROM_DATABASE=Bt878 Video Capture
 
 pci:v0000109Ed00000369sv00001002sd00000001*
- ID_MODEL_FROM_DATABASE=TV-Wonder
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (TV-Wonder)
 
 pci:v0000109Ed00000369sv00001002sd00000003*
- ID_MODEL_FROM_DATABASE=TV-Wonder/VE
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (TV-Wonder/VE)
 
 pci:v0000109Ed0000036C*
  ID_MODEL_FROM_DATABASE=Bt879(??) Video Capture
 
 pci:v0000109Ed0000036Csv000013E9sd00000070*
- ID_MODEL_FROM_DATABASE=Win/TV (Video Section)
+ ID_MODEL_FROM_DATABASE=Bt879(??) Video Capture (Win/TV (Video Section))
 
 pci:v0000109Ed0000036E*
  ID_MODEL_FROM_DATABASE=Bt878 Video Capture
 
 pci:v0000109Ed0000036Esv00000070sd000013EB*
- ID_MODEL_FROM_DATABASE=WinTV Series
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (WinTV Series)
 
 pci:v0000109Ed0000036Esv00000070sd0000FF01*
- ID_MODEL_FROM_DATABASE=Viewcast Osprey 200
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (Viewcast Osprey 200)
 
 pci:v0000109Ed0000036Esv00000071sd00000101*
- ID_MODEL_FROM_DATABASE=DigiTV PCI
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (DigiTV PCI)
 
 pci:v0000109Ed0000036Esv0000107Dsd00006606*
- ID_MODEL_FROM_DATABASE=WinFast TV 2000
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (WinFast TV 2000)
 
 pci:v0000109Ed0000036Esv000011BDsd00000012*
- ID_MODEL_FROM_DATABASE=PCTV pro (TV + FM stereo receiver)
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (PCTV pro (TV + FM stereo receiver))
 
 pci:v0000109Ed0000036Esv000011BDsd0000001C*
- ID_MODEL_FROM_DATABASE=PCTV Sat (DBC receiver)
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (PCTV Sat (DBC receiver))
 
 pci:v0000109Ed0000036Esv0000127Asd00000001*
- ID_MODEL_FROM_DATABASE=Bt878 Mediastream Controller NTSC
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (Bt878 Mediastream Controller NTSC)
 
 pci:v0000109Ed0000036Esv0000127Asd00000002*
- ID_MODEL_FROM_DATABASE=Bt878 Mediastream Controller PAL BG
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (Bt878 Mediastream Controller PAL BG)
 
 pci:v0000109Ed0000036Esv0000127Asd00000003*
- ID_MODEL_FROM_DATABASE=Bt878a Mediastream Controller PAL BG
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (Bt878a Mediastream Controller PAL BG)
 
 pci:v0000109Ed0000036Esv0000127Asd00000048*
- ID_MODEL_FROM_DATABASE=Bt878/832 Mediastream Controller
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (Bt878/832 Mediastream Controller)
 
 pci:v0000109Ed0000036Esv0000144Fsd00003000*
- ID_MODEL_FROM_DATABASE=MagicTView CPH060 - Video
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (MagicTView CPH060 - Video)
 
 pci:v0000109Ed0000036Esv00001461sd00000002*
- ID_MODEL_FROM_DATABASE=TV98 Series (TV/No FM/Remote)
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (TV98 Series (TV/No FM/Remote))
 
 pci:v0000109Ed0000036Esv00001461sd00000003*
- ID_MODEL_FROM_DATABASE=AverMedia UltraTV PCI 350
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (AverMedia UltraTV PCI 350)
 
 pci:v0000109Ed0000036Esv00001461sd00000004*
- ID_MODEL_FROM_DATABASE=AVerTV WDM Video Capture
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (AVerTV WDM Video Capture)
 
 pci:v0000109Ed0000036Esv00001461sd00000761*
- ID_MODEL_FROM_DATABASE=AverTV DVB-T
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (AverTV DVB-T)
 
 pci:v0000109Ed0000036Esv00001461sd00000771*
- ID_MODEL_FROM_DATABASE=AverMedia AVerTV DVB-T 771
-
-pci:v0000109Ed0000036Esv00001464sd0000AA00*
- ID_MODEL_FROM_DATABASE=iTuner Spectra8
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (AverMedia AVerTV DVB-T 771)
 
 pci:v0000109Ed0000036Esv000014F1sd00000001*
- ID_MODEL_FROM_DATABASE=Bt878 Mediastream Controller NTSC
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (Bt878 Mediastream Controller NTSC)
 
 pci:v0000109Ed0000036Esv000014F1sd00000002*
- ID_MODEL_FROM_DATABASE=Bt878 Mediastream Controller PAL BG
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (Bt878 Mediastream Controller PAL BG)
 
 pci:v0000109Ed0000036Esv000014F1sd00000003*
- ID_MODEL_FROM_DATABASE=Bt878a Mediastream Controller PAL BG
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (Bt878a Mediastream Controller PAL BG)
 
 pci:v0000109Ed0000036Esv000014F1sd00000048*
- ID_MODEL_FROM_DATABASE=Bt878/832 Mediastream Controller
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (Bt878/832 Mediastream Controller)
 
 pci:v0000109Ed0000036Esv00001822sd00000001*
- ID_MODEL_FROM_DATABASE=VisionPlus DVB card
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (VisionPlus DVB card)
 
 pci:v0000109Ed0000036Esv00001851sd00001850*
- ID_MODEL_FROM_DATABASE=FlyVideo'98 - Video
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (FlyVideo'98 - Video)
 
 pci:v0000109Ed0000036Esv00001851sd00001851*
- ID_MODEL_FROM_DATABASE=FlyVideo II
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (FlyVideo II)
 
 pci:v0000109Ed0000036Esv00001852sd00001852*
- ID_MODEL_FROM_DATABASE=FlyVideo'98 - Video (with FM Tuner)
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (FlyVideo'98 - Video (with FM Tuner))
 
 pci:v0000109Ed0000036Esv000018ACsd0000D500*
- ID_MODEL_FROM_DATABASE=DViCO FusionHDTV5 Lite
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (DViCO FusionHDTV5 Lite)
 
 pci:v0000109Ed0000036Esv0000270Fsd0000FC00*
- ID_MODEL_FROM_DATABASE=Digitop DTT-1000
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (Digitop DTT-1000)
+
+pci:v0000109Ed0000036Esv0000AA00sd00001460*
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (Spectra8 CardA Input0)
+
+pci:v0000109Ed0000036Esv0000AA01sd00001461*
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (Spectra8 CardA Input1)
+
+pci:v0000109Ed0000036Esv0000AA02sd00001462*
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (Spectra8 CardA Input2)
+
+pci:v0000109Ed0000036Esv0000AA03sd00001463*
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (Spectra8 CardA Input3)
+
+pci:v0000109Ed0000036Esv0000AA04sd00001464*
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (Spectra8 CardB Input0)
+
+pci:v0000109Ed0000036Esv0000AA05sd00001465*
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (Spectra8 CardB Input1)
+
+pci:v0000109Ed0000036Esv0000AA06sd00001466*
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (Spectra8 CardB Input2)
+
+pci:v0000109Ed0000036Esv0000AA07sd00001467*
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (Spectra8 CardB Input3)
+
+pci:v0000109Ed0000036Esv0000AA08sd00001468*
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (Spectra8 CardC Input0)
+
+pci:v0000109Ed0000036Esv0000AA09sd00001469*
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (Spectra8 CardC Input1)
+
+pci:v0000109Ed0000036Esv0000AA0Asd0000146A*
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (Spectra8 CardC Input2)
+
+pci:v0000109Ed0000036Esv0000AA0Bsd0000146B*
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (Spectra8 CardC Input3)
+
+pci:v0000109Ed0000036Esv0000AA0Csd0000146C*
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (Spectra8 CardD Input0)
+
+pci:v0000109Ed0000036Esv0000AA0Dsd0000146D*
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (Spectra8 CardD Input1)
+
+pci:v0000109Ed0000036Esv0000AA0Esd0000146E*
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (Spectra8 CardD Input2)
+
+pci:v0000109Ed0000036Esv0000AA0Fsd0000146F*
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (Spectra8 CardD Input3)
 
 pci:v0000109Ed0000036Esv0000BD11sd00001200*
- ID_MODEL_FROM_DATABASE=PCTV pro (TV + FM stereo receiver)
+ ID_MODEL_FROM_DATABASE=Bt878 Video Capture (PCTV pro (TV + FM stereo receiver))
 
 pci:v0000109Ed0000036F*
  ID_MODEL_FROM_DATABASE=Bt879 Video Capture
 
 pci:v0000109Ed0000036Fsv0000127Asd00000044*
- ID_MODEL_FROM_DATABASE=Bt879 Video Capture NTSC
+ ID_MODEL_FROM_DATABASE=Bt879 Video Capture (NTSC)
 
 pci:v0000109Ed0000036Fsv0000127Asd00000122*
- ID_MODEL_FROM_DATABASE=Bt879 Video Capture PAL I
+ ID_MODEL_FROM_DATABASE=Bt879 Video Capture (PAL I)
 
 pci:v0000109Ed0000036Fsv0000127Asd00000144*
- ID_MODEL_FROM_DATABASE=Bt879 Video Capture NTSC
+ ID_MODEL_FROM_DATABASE=Bt879 Video Capture (NTSC)
 
 pci:v0000109Ed0000036Fsv0000127Asd00000222*
- ID_MODEL_FROM_DATABASE=Bt879 Video Capture PAL BG
+ ID_MODEL_FROM_DATABASE=Bt879 Video Capture (PAL BG)
 
 pci:v0000109Ed0000036Fsv0000127Asd00000244*
- ID_MODEL_FROM_DATABASE=Bt879a Video Capture NTSC
+ ID_MODEL_FROM_DATABASE=Bt879 Video Capture (Bt879a Video Capture NTSC)
 
 pci:v0000109Ed0000036Fsv0000127Asd00000322*
- ID_MODEL_FROM_DATABASE=Bt879 Video Capture NTSC
+ ID_MODEL_FROM_DATABASE=Bt879 Video Capture (NTSC)
 
 pci:v0000109Ed0000036Fsv0000127Asd00000422*
- ID_MODEL_FROM_DATABASE=Bt879 Video Capture NTSC
+ ID_MODEL_FROM_DATABASE=Bt879 Video Capture (NTSC)
 
 pci:v0000109Ed0000036Fsv0000127Asd00001122*
- ID_MODEL_FROM_DATABASE=Bt879 Video Capture PAL I
+ ID_MODEL_FROM_DATABASE=Bt879 Video Capture (PAL I)
 
 pci:v0000109Ed0000036Fsv0000127Asd00001222*
- ID_MODEL_FROM_DATABASE=Bt879 Video Capture PAL BG
+ ID_MODEL_FROM_DATABASE=Bt879 Video Capture (PAL BG)
 
 pci:v0000109Ed0000036Fsv0000127Asd00001322*
- ID_MODEL_FROM_DATABASE=Bt879 Video Capture NTSC
+ ID_MODEL_FROM_DATABASE=Bt879 Video Capture (NTSC)
 
 pci:v0000109Ed0000036Fsv0000127Asd00001522*
- ID_MODEL_FROM_DATABASE=Bt879a Video Capture PAL I
+ ID_MODEL_FROM_DATABASE=Bt879 Video Capture (Bt879a Video Capture PAL I)
 
 pci:v0000109Ed0000036Fsv0000127Asd00001622*
- ID_MODEL_FROM_DATABASE=Bt879a Video Capture PAL BG
+ ID_MODEL_FROM_DATABASE=Bt879 Video Capture (Bt879a Video Capture PAL BG)
 
 pci:v0000109Ed0000036Fsv0000127Asd00001722*
- ID_MODEL_FROM_DATABASE=Bt879a Video Capture NTSC
+ ID_MODEL_FROM_DATABASE=Bt879 Video Capture (Bt879a Video Capture NTSC)
 
 pci:v0000109Ed0000036Fsv000014F1sd00000044*
- ID_MODEL_FROM_DATABASE=Bt879 Video Capture NTSC
+ ID_MODEL_FROM_DATABASE=Bt879 Video Capture (NTSC)
 
 pci:v0000109Ed0000036Fsv000014F1sd00000122*
- ID_MODEL_FROM_DATABASE=Bt879 Video Capture PAL I
+ ID_MODEL_FROM_DATABASE=Bt879 Video Capture (PAL I)
 
 pci:v0000109Ed0000036Fsv000014F1sd00000144*
- ID_MODEL_FROM_DATABASE=Bt879 Video Capture NTSC
+ ID_MODEL_FROM_DATABASE=Bt879 Video Capture (NTSC)
 
 pci:v0000109Ed0000036Fsv000014F1sd00000222*
- ID_MODEL_FROM_DATABASE=Bt879 Video Capture PAL BG
+ ID_MODEL_FROM_DATABASE=Bt879 Video Capture (PAL BG)
 
 pci:v0000109Ed0000036Fsv000014F1sd00000244*
- ID_MODEL_FROM_DATABASE=Bt879a Video Capture NTSC
+ ID_MODEL_FROM_DATABASE=Bt879 Video Capture (Bt879a Video Capture NTSC)
 
 pci:v0000109Ed0000036Fsv000014F1sd00000322*
- ID_MODEL_FROM_DATABASE=Bt879 Video Capture NTSC
+ ID_MODEL_FROM_DATABASE=Bt879 Video Capture (NTSC)
 
 pci:v0000109Ed0000036Fsv000014F1sd00000422*
- ID_MODEL_FROM_DATABASE=Bt879 Video Capture NTSC
+ ID_MODEL_FROM_DATABASE=Bt879 Video Capture (NTSC)
 
 pci:v0000109Ed0000036Fsv000014F1sd00001122*
- ID_MODEL_FROM_DATABASE=Bt879 Video Capture PAL I
+ ID_MODEL_FROM_DATABASE=Bt879 Video Capture (PAL I)
 
 pci:v0000109Ed0000036Fsv000014F1sd00001222*
- ID_MODEL_FROM_DATABASE=Bt879 Video Capture PAL BG
+ ID_MODEL_FROM_DATABASE=Bt879 Video Capture (PAL BG)
 
 pci:v0000109Ed0000036Fsv000014F1sd00001322*
- ID_MODEL_FROM_DATABASE=Bt879 Video Capture NTSC
+ ID_MODEL_FROM_DATABASE=Bt879 Video Capture (NTSC)
 
 pci:v0000109Ed0000036Fsv000014F1sd00001522*
- ID_MODEL_FROM_DATABASE=Bt879a Video Capture PAL I
+ ID_MODEL_FROM_DATABASE=Bt879 Video Capture (Bt879a Video Capture PAL I)
 
 pci:v0000109Ed0000036Fsv000014F1sd00001622*
- ID_MODEL_FROM_DATABASE=Bt879a Video Capture PAL BG
+ ID_MODEL_FROM_DATABASE=Bt879 Video Capture (Bt879a Video Capture PAL BG)
 
 pci:v0000109Ed0000036Fsv000014F1sd00001722*
- ID_MODEL_FROM_DATABASE=Bt879a Video Capture NTSC
+ ID_MODEL_FROM_DATABASE=Bt879 Video Capture (Bt879a Video Capture NTSC)
 
 pci:v0000109Ed0000036Fsv00001851sd00001850*
- ID_MODEL_FROM_DATABASE=FlyVideo'98 - Video
+ ID_MODEL_FROM_DATABASE=Bt879 Video Capture (FlyVideo'98 - Video)
 
 pci:v0000109Ed0000036Fsv00001851sd00001851*
- ID_MODEL_FROM_DATABASE=FlyVideo II
+ ID_MODEL_FROM_DATABASE=Bt879 Video Capture (FlyVideo II)
 
 pci:v0000109Ed0000036Fsv00001852sd00001852*
- ID_MODEL_FROM_DATABASE=FlyVideo'98 - Video (with FM Tuner)
+ ID_MODEL_FROM_DATABASE=Bt879 Video Capture (FlyVideo'98 - Video (with FM Tuner))
 
 pci:v0000109Ed00000370*
  ID_MODEL_FROM_DATABASE=Bt880 Video Capture
 
 pci:v0000109Ed00000370sv00001851sd00001850*
- ID_MODEL_FROM_DATABASE=FlyVideo'98
+ ID_MODEL_FROM_DATABASE=Bt880 Video Capture (FlyVideo'98)
 
 pci:v0000109Ed00000370sv00001851sd00001851*
- ID_MODEL_FROM_DATABASE=FlyVideo'98 EZ - video
+ ID_MODEL_FROM_DATABASE=Bt880 Video Capture (FlyVideo'98 EZ - video)
 
 pci:v0000109Ed00000370sv00001852sd00001852*
- ID_MODEL_FROM_DATABASE=FlyVideo'98 (with FM Tuner)
+ ID_MODEL_FROM_DATABASE=Bt880 Video Capture (FlyVideo'98 (with FM Tuner))
 
 pci:v0000109Ed00000878*
  ID_MODEL_FROM_DATABASE=Bt878 Audio Capture
 
 pci:v0000109Ed00000878sv00000070sd000013EB*
- ID_MODEL_FROM_DATABASE=WinTV Series
+ ID_MODEL_FROM_DATABASE=Bt878 Audio Capture (WinTV Series)
 
 pci:v0000109Ed00000878sv00000070sd0000FF01*
- ID_MODEL_FROM_DATABASE=Viewcast Osprey 200
+ ID_MODEL_FROM_DATABASE=Bt878 Audio Capture (Viewcast Osprey 200)
 
 pci:v0000109Ed00000878sv00000071sd00000101*
- ID_MODEL_FROM_DATABASE=DigiTV PCI
+ ID_MODEL_FROM_DATABASE=Bt878 Audio Capture (DigiTV PCI)
 
 pci:v0000109Ed00000878sv00001002sd00000001*
- ID_MODEL_FROM_DATABASE=TV-Wonder
+ ID_MODEL_FROM_DATABASE=Bt878 Audio Capture (TV-Wonder)
 
 pci:v0000109Ed00000878sv00001002sd00000003*
- ID_MODEL_FROM_DATABASE=TV-Wonder/VE
+ ID_MODEL_FROM_DATABASE=Bt878 Audio Capture (TV-Wonder/VE)
 
 pci:v0000109Ed00000878sv000011BDsd00000012*
- ID_MODEL_FROM_DATABASE=PCTV pro (TV + FM stereo receiver, audio section)
+ ID_MODEL_FROM_DATABASE=Bt878 Audio Capture (PCTV pro (TV + FM stereo receiver, audio section))
 
 pci:v0000109Ed00000878sv000011BDsd0000001C*
- ID_MODEL_FROM_DATABASE=PCTV Sat (DBC receiver)
+ ID_MODEL_FROM_DATABASE=Bt878 Audio Capture (PCTV Sat (DBC receiver))
 
 pci:v0000109Ed00000878sv0000127Asd00000001*
- ID_MODEL_FROM_DATABASE=Bt878 Video Capture (Audio Section)
+ ID_MODEL_FROM_DATABASE=Bt878 Audio Capture (Bt878 Video Capture (Audio Section))
 
 pci:v0000109Ed00000878sv0000127Asd00000002*
- ID_MODEL_FROM_DATABASE=Bt878 Video Capture (Audio Section)
+ ID_MODEL_FROM_DATABASE=Bt878 Audio Capture (Bt878 Video Capture (Audio Section))
 
 pci:v0000109Ed00000878sv0000127Asd00000003*
- ID_MODEL_FROM_DATABASE=Bt878 Video Capture (Audio Section)
+ ID_MODEL_FROM_DATABASE=Bt878 Audio Capture (Bt878 Video Capture (Audio Section))
 
 pci:v0000109Ed00000878sv0000127Asd00000048*
- ID_MODEL_FROM_DATABASE=Bt878 Video Capture (Audio Section)
+ ID_MODEL_FROM_DATABASE=Bt878 Audio Capture (Bt878 Video Capture (Audio Section))
 
 pci:v0000109Ed00000878sv000013E9sd00000070*
- ID_MODEL_FROM_DATABASE=Win/TV (Audio Section)
+ ID_MODEL_FROM_DATABASE=Bt878 Audio Capture (Win/TV (Audio Section))
 
 pci:v0000109Ed00000878sv0000144Fsd00003000*
- ID_MODEL_FROM_DATABASE=MagicTView CPH060 - Audio
+ ID_MODEL_FROM_DATABASE=Bt878 Audio Capture (MagicTView CPH060 - Audio)
 
 pci:v0000109Ed00000878sv00001461sd00000002*
- ID_MODEL_FROM_DATABASE=Avermedia PCTV98 Audio Capture
+ ID_MODEL_FROM_DATABASE=Bt878 Audio Capture (Avermedia PCTV98 Audio Capture)
 
 pci:v0000109Ed00000878sv00001461sd00000003*
- ID_MODEL_FROM_DATABASE=UltraTV PCI 350
+ ID_MODEL_FROM_DATABASE=Bt878 Audio Capture (UltraTV PCI 350)
 
 pci:v0000109Ed00000878sv00001461sd00000004*
- ID_MODEL_FROM_DATABASE=AVerTV WDM Audio Capture
+ ID_MODEL_FROM_DATABASE=Bt878 Audio Capture (AVerTV WDM Audio Capture)
 
 pci:v0000109Ed00000878sv00001461sd00000761*
- ID_MODEL_FROM_DATABASE=AVerTV DVB-T
+ ID_MODEL_FROM_DATABASE=Bt878 Audio Capture (AVerTV DVB-T)
 
 pci:v0000109Ed00000878sv00001461sd00000771*
- ID_MODEL_FROM_DATABASE=AverMedia AVerTV DVB-T 771
+ ID_MODEL_FROM_DATABASE=Bt878 Audio Capture (AverMedia AVerTV DVB-T 771)
 
 pci:v0000109Ed00000878sv000014F1sd00000001*
- ID_MODEL_FROM_DATABASE=Bt878 Video Capture (Audio Section)
+ ID_MODEL_FROM_DATABASE=Bt878 Audio Capture (Bt878 Video Capture (Audio Section))
 
 pci:v0000109Ed00000878sv000014F1sd00000002*
- ID_MODEL_FROM_DATABASE=Bt878 Video Capture (Audio Section)
+ ID_MODEL_FROM_DATABASE=Bt878 Audio Capture (Bt878 Video Capture (Audio Section))
 
 pci:v0000109Ed00000878sv000014F1sd00000003*
- ID_MODEL_FROM_DATABASE=Bt878 Video Capture (Audio Section)
+ ID_MODEL_FROM_DATABASE=Bt878 Audio Capture (Bt878 Video Capture (Audio Section))
 
 pci:v0000109Ed00000878sv000014F1sd00000048*
- ID_MODEL_FROM_DATABASE=Bt878 Video Capture (Audio Section)
+ ID_MODEL_FROM_DATABASE=Bt878 Audio Capture (Bt878 Video Capture (Audio Section))
 
 pci:v0000109Ed00000878sv00001822sd00000001*
- ID_MODEL_FROM_DATABASE=VisionPlus DVB Card
+ ID_MODEL_FROM_DATABASE=Bt878 Audio Capture (VisionPlus DVB Card)
 
 pci:v0000109Ed00000878sv000018ACsd0000D500*
- ID_MODEL_FROM_DATABASE=DViCO FusionHDTV5 Lite
+ ID_MODEL_FROM_DATABASE=Bt878 Audio Capture (DViCO FusionHDTV5 Lite)
 
 pci:v0000109Ed00000878sv0000270Fsd0000FC00*
- ID_MODEL_FROM_DATABASE=Digitop DTT-1000
+ ID_MODEL_FROM_DATABASE=Bt878 Audio Capture (Digitop DTT-1000)
 
 pci:v0000109Ed00000878sv0000BD11sd00001200*
- ID_MODEL_FROM_DATABASE=PCTV pro (TV + FM stereo receiver, audio section)
+ ID_MODEL_FROM_DATABASE=Bt878 Audio Capture (PCTV pro (TV + FM stereo receiver, audio section))
 
 pci:v0000109Ed00000879*
  ID_MODEL_FROM_DATABASE=Bt879 Audio Capture
 
 pci:v0000109Ed00000879sv0000127Asd00000044*
- ID_MODEL_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+ ID_MODEL_FROM_DATABASE=Bt879 Audio Capture (Bt879 Video Capture (Audio Section))
 
 pci:v0000109Ed00000879sv0000127Asd00000122*
- ID_MODEL_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+ ID_MODEL_FROM_DATABASE=Bt879 Audio Capture (Bt879 Video Capture (Audio Section))
 
 pci:v0000109Ed00000879sv0000127Asd00000144*
- ID_MODEL_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+ ID_MODEL_FROM_DATABASE=Bt879 Audio Capture (Bt879 Video Capture (Audio Section))
 
 pci:v0000109Ed00000879sv0000127Asd00000222*
- ID_MODEL_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+ ID_MODEL_FROM_DATABASE=Bt879 Audio Capture (Bt879 Video Capture (Audio Section))
 
 pci:v0000109Ed00000879sv0000127Asd00000244*
- ID_MODEL_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+ ID_MODEL_FROM_DATABASE=Bt879 Audio Capture (Bt879 Video Capture (Audio Section))
 
 pci:v0000109Ed00000879sv0000127Asd00000322*
- ID_MODEL_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+ ID_MODEL_FROM_DATABASE=Bt879 Audio Capture (Bt879 Video Capture (Audio Section))
 
 pci:v0000109Ed00000879sv0000127Asd00000422*
- ID_MODEL_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+ ID_MODEL_FROM_DATABASE=Bt879 Audio Capture (Bt879 Video Capture (Audio Section))
 
 pci:v0000109Ed00000879sv0000127Asd00001122*
- ID_MODEL_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+ ID_MODEL_FROM_DATABASE=Bt879 Audio Capture (Bt879 Video Capture (Audio Section))
 
 pci:v0000109Ed00000879sv0000127Asd00001222*
- ID_MODEL_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+ ID_MODEL_FROM_DATABASE=Bt879 Audio Capture (Bt879 Video Capture (Audio Section))
 
 pci:v0000109Ed00000879sv0000127Asd00001322*
- ID_MODEL_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+ ID_MODEL_FROM_DATABASE=Bt879 Audio Capture (Bt879 Video Capture (Audio Section))
 
 pci:v0000109Ed00000879sv0000127Asd00001522*
- ID_MODEL_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+ ID_MODEL_FROM_DATABASE=Bt879 Audio Capture (Bt879 Video Capture (Audio Section))
 
 pci:v0000109Ed00000879sv0000127Asd00001622*
- ID_MODEL_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+ ID_MODEL_FROM_DATABASE=Bt879 Audio Capture (Bt879 Video Capture (Audio Section))
 
 pci:v0000109Ed00000879sv0000127Asd00001722*
- ID_MODEL_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+ ID_MODEL_FROM_DATABASE=Bt879 Audio Capture (Bt879 Video Capture (Audio Section))
 
 pci:v0000109Ed00000879sv000014F1sd00000044*
- ID_MODEL_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+ ID_MODEL_FROM_DATABASE=Bt879 Audio Capture (Bt879 Video Capture (Audio Section))
 
 pci:v0000109Ed00000879sv000014F1sd00000122*
- ID_MODEL_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+ ID_MODEL_FROM_DATABASE=Bt879 Audio Capture (Bt879 Video Capture (Audio Section))
 
 pci:v0000109Ed00000879sv000014F1sd00000144*
- ID_MODEL_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+ ID_MODEL_FROM_DATABASE=Bt879 Audio Capture (Bt879 Video Capture (Audio Section))
 
 pci:v0000109Ed00000879sv000014F1sd00000222*
- ID_MODEL_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+ ID_MODEL_FROM_DATABASE=Bt879 Audio Capture (Bt879 Video Capture (Audio Section))
 
 pci:v0000109Ed00000879sv000014F1sd00000244*
- ID_MODEL_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+ ID_MODEL_FROM_DATABASE=Bt879 Audio Capture (Bt879 Video Capture (Audio Section))
 
 pci:v0000109Ed00000879sv000014F1sd00000322*
- ID_MODEL_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+ ID_MODEL_FROM_DATABASE=Bt879 Audio Capture (Bt879 Video Capture (Audio Section))
 
 pci:v0000109Ed00000879sv000014F1sd00000422*
- ID_MODEL_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+ ID_MODEL_FROM_DATABASE=Bt879 Audio Capture (Bt879 Video Capture (Audio Section))
 
 pci:v0000109Ed00000879sv000014F1sd00001122*
- ID_MODEL_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+ ID_MODEL_FROM_DATABASE=Bt879 Audio Capture (Bt879 Video Capture (Audio Section))
 
 pci:v0000109Ed00000879sv000014F1sd00001222*
- ID_MODEL_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+ ID_MODEL_FROM_DATABASE=Bt879 Audio Capture (Bt879 Video Capture (Audio Section))
 
 pci:v0000109Ed00000879sv000014F1sd00001322*
- ID_MODEL_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+ ID_MODEL_FROM_DATABASE=Bt879 Audio Capture (Bt879 Video Capture (Audio Section))
 
 pci:v0000109Ed00000879sv000014F1sd00001522*
- ID_MODEL_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+ ID_MODEL_FROM_DATABASE=Bt879 Audio Capture (Bt879 Video Capture (Audio Section))
 
 pci:v0000109Ed00000879sv000014F1sd00001622*
- ID_MODEL_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+ ID_MODEL_FROM_DATABASE=Bt879 Audio Capture (Bt879 Video Capture (Audio Section))
 
 pci:v0000109Ed00000879sv000014F1sd00001722*
- ID_MODEL_FROM_DATABASE=Bt879 Video Capture (Audio Section)
+ ID_MODEL_FROM_DATABASE=Bt879 Audio Capture (Bt879 Video Capture (Audio Section))
 
 pci:v0000109Ed00000880*
  ID_MODEL_FROM_DATABASE=Bt880 Audio Capture
@@ -18152,6 +18626,9 @@ pci:v000010A9d00008001*
 pci:v000010A9d00008002*
  ID_MODEL_FROM_DATABASE=G-net NT
 
+pci:v000010A9d0000802B*
+ ID_MODEL_FROM_DATABASE=REACT external interrupt controller
+
 pci:v000010AA*
  ID_VENDOR_FROM_DATABASE=ACC Microelectronics
 
@@ -18222,7 +18699,7 @@ pci:v000010B4d00001B1D*
  ID_MODEL_FROM_DATABASE=Velocity 128 3D
 
 pci:v000010B4d00001B1Dsv000010B4sd0000237E*
- ID_MODEL_FROM_DATABASE=Velocity 4400
+ ID_MODEL_FROM_DATABASE=Velocity 128 3D (Velocity 4400)
 
 pci:v000010B5*
  ID_VENDOR_FROM_DATABASE=PLX Technology, Inc.
@@ -18234,13 +18711,13 @@ pci:v000010B5d00000557*
  ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge
 
 pci:v000010B5d00000557sv000010B5sd00009030*
- ID_MODEL_FROM_DATABASE=Digium Tormenta 2 T400P-SS7 or E400P-SS7 Quad T1 or E1 PCI card
+ ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge (Digium Tormenta 2 T400P-SS7 or E400P-SS7 Quad T1 or E1 PCI card)
 
 pci:v000010B5d00001000*
  ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge
 
 pci:v000010B5d00001000sv000010B5sd00009030*
- ID_MODEL_FROM_DATABASE=ATCOM AT400P Quad T1 PCI card
+ ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge (ATCOM AT400P Quad T1 PCI card)
 
 pci:v000010B5d00001024*
  ID_MODEL_FROM_DATABASE=Acromag, Inc. IndustryPack Carrier Card
@@ -18273,7 +18750,7 @@ pci:v000010B5d00002000*
  ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge
 
 pci:v000010B5d00002000sv000010B5sd00009030*
- ID_MODEL_FROM_DATABASE=ATCOM AE400P Quad E1 PCI card
+ ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge (ATCOM AE400P Quad E1 PCI card)
 
 pci:v000010B5d00002540*
  ID_MODEL_FROM_DATABASE=IXXAT CAN-Interface PC-I 04/PCI
@@ -18288,19 +18765,19 @@ pci:v000010B5d00004000*
  ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge
 
 pci:v000010B5d00004000sv000010B5sd00009030*
- ID_MODEL_FROM_DATABASE=Tormenta 3 Varion V400P/ATCOM TE400P Quad E1/T1/J1 PCI card
+ ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge (Tormenta 3 Varion V400P/ATCOM TE400P Quad E1/T1/J1 PCI card)
 
 pci:v000010B5d00004001*
  ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge
 
 pci:v000010B5d00004001sv000010B5sd00009030*
- ID_MODEL_FROM_DATABASE=ATCOM A400PE Quad E1 PCI card
+ ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge (ATCOM A400PE Quad E1 PCI card)
 
 pci:v000010B5d00004002*
  ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge
 
 pci:v000010B5d00004002sv000010B5sd00009030*
- ID_MODEL_FROM_DATABASE=ATCOM A400PT Quad T1 PCI card
+ ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge (ATCOM A400PT Quad T1 PCI card)
 
 pci:v000010B5d00006140*
  ID_MODEL_FROM_DATABASE=PCI6140 32-bit 33MHz PCI-to-PCI Bridge
@@ -18327,28 +18804,28 @@ pci:v000010B5d00006540*
  ID_MODEL_FROM_DATABASE=PCI6540 64-bit 133MHz PCI-X-to-PCI-X Bridge
 
 pci:v000010B5d00006540sv00001775sd00001100*
- ID_MODEL_FROM_DATABASE=CR11 Single Board Computer
+ ID_MODEL_FROM_DATABASE=PCI6540 64-bit 133MHz PCI-X-to-PCI-X Bridge (CR11 Single Board Computer)
 
 pci:v000010B5d00006540sv00004C53sd000010E0*
- ID_MODEL_FROM_DATABASE=PSL09 PrPMC
+ ID_MODEL_FROM_DATABASE=PCI6540 64-bit 133MHz PCI-X-to-PCI-X Bridge (PSL09 PrPMC)
 
 pci:v000010B5d00006541*
  ID_MODEL_FROM_DATABASE=PCI6540/6466 PCI-PCI bridge (non-transparent mode, primary side)
 
 pci:v000010B5d00006541sv00001775sd00001100*
- ID_MODEL_FROM_DATABASE=CR11 Single Board Computer
+ ID_MODEL_FROM_DATABASE=PCI6540/6466 PCI-PCI bridge (non-transparent mode, primary side) (CR11 Single Board Computer)
 
 pci:v000010B5d00006541sv00004C53sd000010E0*
- ID_MODEL_FROM_DATABASE=PSL09 PrPMC
+ ID_MODEL_FROM_DATABASE=PCI6540/6466 PCI-PCI bridge (non-transparent mode, primary side) (PSL09 PrPMC)
 
 pci:v000010B5d00006542*
  ID_MODEL_FROM_DATABASE=PCI6540/6466 PCI-PCI bridge (non-transparent mode, secondary side)
 
 pci:v000010B5d00006542sv00001775sd00001100*
- ID_MODEL_FROM_DATABASE=CR11 Single Board Computer
+ ID_MODEL_FROM_DATABASE=PCI6540/6466 PCI-PCI bridge (non-transparent mode, secondary side) (CR11 Single Board Computer)
 
 pci:v000010B5d00006542sv00004C53sd000010E0*
- ID_MODEL_FROM_DATABASE=PSL09 PrPMC
+ ID_MODEL_FROM_DATABASE=PCI6540/6466 PCI-PCI bridge (non-transparent mode, secondary side) (PSL09 PrPMC)
 
 pci:v000010B5d00008111*
  ID_MODEL_FROM_DATABASE=PEX 8111 PCI Express-to-PCI Bridge
@@ -18444,7 +18921,7 @@ pci:v000010B5d00008624*
  ID_MODEL_FROM_DATABASE=PEX 8624 24-lane, 6-Port PCI Express Gen 2 (5.0 GT/s) Switch [ExpressLane]
 
 pci:v000010B5d00008624sv000013A3sd00001845*
- ID_MODEL_FROM_DATABASE=DX1845 Acceleration Card
+ ID_MODEL_FROM_DATABASE=PEX 8624 24-lane, 6-Port PCI Express Gen 2 (5.0 GT/s) Switch [ExpressLane] (DX1845 Acceleration Card)
 
 pci:v000010B5d00008625*
  ID_MODEL_FROM_DATABASE=PEX 8625 24-lane, 24-Port PCI Express Gen 2 (5.0 GT/s) Switch
@@ -18485,6 +18962,9 @@ pci:v000010B5d00008732*
 pci:v000010B5d00008734*
  ID_MODEL_FROM_DATABASE=PEX 8734 32-lane, 8-Port PCI Express Gen 3 (8.0GT/s) Switch
 
+pci:v000010B5d00008747*
+ ID_MODEL_FROM_DATABASE=PEX 8747 48-Lane, 5-Port PCI Express Gen 3 (8.0 GT/s) Switch
+
 pci:v000010B5d000087B0*
  ID_MODEL_FROM_DATABASE=PEX 8732 32-lane, 8-Port PCI Express Gen 3 (8.0 GT/s) Switch
 
@@ -18495,85 +18975,85 @@ pci:v000010B5d00009030*
  ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge
 
 pci:v000010B5d00009030sv000010B5sd00002695*
- ID_MODEL_FROM_DATABASE=Hilscher CIF50-PB/DPS Profibus
+ ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge (Hilscher CIF50-PB/DPS Profibus)
 
 pci:v000010B5d00009030sv000010B5sd00002862*
- ID_MODEL_FROM_DATABASE=Alpermann+Velte PCL PCI LV (3V/5V): Timecode Reader Board
+ ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge (Alpermann+Velte PCL PCI LV (3V/5V): Timecode Reader Board)
 
 pci:v000010B5d00009030sv000010B5sd00002906*
- ID_MODEL_FROM_DATABASE=Alpermann+Velte PCI TS (3V/5V): Time Synchronisation Board
+ ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge (Alpermann+Velte PCI TS (3V/5V): Time Synchronisation Board)
 
 pci:v000010B5d00009030sv000010B5sd00002940*
- ID_MODEL_FROM_DATABASE=Alpermann+Velte PCL PCI D (3V/5V): Timecode Reader Board
+ ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge (Alpermann+Velte PCL PCI D (3V/5V): Timecode Reader Board)
 
 pci:v000010B5d00009030sv000010B5sd00002977*
- ID_MODEL_FROM_DATABASE=IXXAT iPC-I XC16/PCI CAN Board
+ ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge (IXXAT iPC-I XC16/PCI CAN Board)
 
 pci:v000010B5d00009030sv000010B5sd00002978*
- ID_MODEL_FROM_DATABASE=SH ARC-PCIu/SH ARC-PCI104/SH ARC-PCIe SOHARD ARCNET card
+ ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge (SH ARC-PCIu/SH ARC-PCI104/SH ARC-PCIe SOHARD ARCNET card)
 
 pci:v000010B5d00009030sv000010B5sd00003025*
- ID_MODEL_FROM_DATABASE=Alpermann+Velte PCL PCI L (3V/5V): Timecode Reader Board
+ ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge (Alpermann+Velte PCL PCI L (3V/5V): Timecode Reader Board)
 
 pci:v000010B5d00009030sv000010B5sd00003068*
- ID_MODEL_FROM_DATABASE=Alpermann+Velte PCL PCI HD (3V/5V): Timecode Reader Board
+ ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge (Alpermann+Velte PCL PCI HD (3V/5V): Timecode Reader Board)
 
 pci:v000010B5d00009030sv000010B5sd00003463*
- ID_MODEL_FROM_DATABASE=Alpermann+Velte PCL PCI D (v2) (3V/5V): Timecode Reader Board
+ ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge (Alpermann+Velte PCL PCI D (v2) (3V/5V): Timecode Reader Board)
 
 pci:v000010B5d00009030sv000012FEsd00000111*
- ID_MODEL_FROM_DATABASE=CPCI-ASIO4 (ESD 4-port Serial Interface Board)
+ ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge (CPCI-ASIO4 (ESD 4-port Serial Interface Board))
 
 pci:v000010B5d00009030sv00001369sd00009C01*
- ID_MODEL_FROM_DATABASE=VX222v2
+ ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge (VX222v2)
 
 pci:v000010B5d00009030sv00001369sd00009D01*
- ID_MODEL_FROM_DATABASE=VX222-Mic
+ ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge (VX222-Mic)
 
 pci:v000010B5d00009030sv00001369sd00009D02*
- ID_MODEL_FROM_DATABASE=VX222-Mic
+ ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge (VX222-Mic)
 
 pci:v000010B5d00009030sv00001369sd00009E01*
- ID_MODEL_FROM_DATABASE=PCX924v2
+ ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge (PCX924v2)
 
 pci:v000010B5d00009030sv00001369sd00009F01*
- ID_MODEL_FROM_DATABASE=PCX924-Mic
+ ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge (PCX924-Mic)
 
 pci:v000010B5d00009030sv00001369sd00009F02*
- ID_MODEL_FROM_DATABASE=PCX924-Mic
+ ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge (PCX924-Mic)
 
 pci:v000010B5d00009030sv00001369sd0000A001*
- ID_MODEL_FROM_DATABASE=PCX22v2
+ ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge (PCX22v2)
 
 pci:v000010B5d00009030sv00001369sd0000A701*
- ID_MODEL_FROM_DATABASE=LCM220v2
+ ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge (LCM220v2)
 
 pci:v000010B5d00009030sv00001369sd0000A801*
- ID_MODEL_FROM_DATABASE=LCM200
+ ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge (LCM200)
 
 pci:v000010B5d00009030sv00001397sd00003136*
- ID_MODEL_FROM_DATABASE=4xS0-ISDN PCI Adapter
+ ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge (4xS0-ISDN PCI Adapter)
 
 pci:v000010B5d00009030sv00001397sd00003137*
- ID_MODEL_FROM_DATABASE=S2M-E1-ISDN PCI Adapter
+ ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge (S2M-E1-ISDN PCI Adapter)
 
 pci:v000010B5d00009030sv00001518sd00000200*
- ID_MODEL_FROM_DATABASE=Kontron ThinkIO-C
+ ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge (Kontron ThinkIO-C)
 
 pci:v000010B5d00009030sv000015EDsd00001002*
- ID_MODEL_FROM_DATABASE=MCCS 8-port Serial Hot Swap
+ ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge (MCCS 8-port Serial Hot Swap)
 
 pci:v000010B5d00009030sv000015EDsd00001003*
- ID_MODEL_FROM_DATABASE=MCCS 16-port Serial Hot Swap
+ ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge (MCCS 16-port Serial Hot Swap)
 
 pci:v000010B5d00009030sv0000E1C5sd00000001*
- ID_MODEL_FROM_DATABASE=TE1-PCI
+ ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge (TE1-PCI)
 
 pci:v000010B5d00009030sv0000E1C5sd00000005*
- ID_MODEL_FROM_DATABASE=TA1-PCI
+ ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge (TA1-PCI)
 
 pci:v000010B5d00009030sv0000E1C5sd00000006*
- ID_MODEL_FROM_DATABASE=TA1-PCI4
+ ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge (TA1-PCI4)
 
 pci:v000010B5d00009036*
  ID_MODEL_FROM_DATABASE=9036
@@ -18582,145 +19062,145 @@ pci:v000010B5d00009050*
  ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge
 
 pci:v000010B5d00009050sv000010B5sd00001067*
- ID_MODEL_FROM_DATABASE=IXXAT CAN i165
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (IXXAT CAN i165)
 
 pci:v000010B5d00009050sv000010B5sd0000114E*
- ID_MODEL_FROM_DATABASE=Wasco WITIO PCI168extended
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (Wasco WITIO PCI168extended)
 
 pci:v000010B5d00009050sv000010B5sd00001169*
- ID_MODEL_FROM_DATABASE=Wasco OPTOIO32standard 32 digital in, 32 digital out
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (Wasco OPTOIO32standard 32 digital in, 32 digital out)
 
 pci:v000010B5d00009050sv000010B5sd00001172*
- ID_MODEL_FROM_DATABASE=IK220 (Heidenhain)
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (IK220 (Heidenhain))
 
 pci:v000010B5d00009050sv000010B5sd00002036*
- ID_MODEL_FROM_DATABASE=SatPak GPS
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (SatPak GPS)
 
 pci:v000010B5d00009050sv000010B5sd00002221*
- ID_MODEL_FROM_DATABASE=Alpermann+Velte PCL PCI LV: Timecode Reader Board
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (Alpermann+Velte PCL PCI LV: Timecode Reader Board)
 
 pci:v000010B5d00009050sv000010B5sd00002273*
- ID_MODEL_FROM_DATABASE=SH ARC-PCI SOHARD ARCNET card
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (SH ARC-PCI SOHARD ARCNET card)
 
 pci:v000010B5d00009050sv000010B5sd00002431*
- ID_MODEL_FROM_DATABASE=Alpermann+Velte PCL PCI D: Timecode Reader Board
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (Alpermann+Velte PCL PCI D: Timecode Reader Board)
 
 pci:v000010B5d00009050sv000010B5sd00002905*
- ID_MODEL_FROM_DATABASE=Alpermann+Velte PCI TS: Time Synchronisation Board
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (Alpermann+Velte PCI TS: Time Synchronisation Board)
 
 pci:v000010B5d00009050sv000010B5sd00003196*
- ID_MODEL_FROM_DATABASE=Goramo PLX200SYN sync serial card
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (Goramo PLX200SYN sync serial card)
 
 pci:v000010B5d00009050sv000010B5sd00009050*
- ID_MODEL_FROM_DATABASE=PCI-I04 PCI Passive PC/CAN Interface
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (PCI-I04 PCI Passive PC/CAN Interface)
 
 pci:v000010B5d00009050sv00001369sd00008901*
- ID_MODEL_FROM_DATABASE=PCX11+ PCI
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (PCX11+ PCI)
 
 pci:v000010B5d00009050sv00001369sd00008F01*
- ID_MODEL_FROM_DATABASE=VX222
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (VX222)
 
 pci:v000010B5d00009050sv00001369sd00009401*
- ID_MODEL_FROM_DATABASE=PCX924
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (PCX924)
 
 pci:v000010B5d00009050sv00001369sd00009501*
- ID_MODEL_FROM_DATABASE=PCX22
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (PCX22)
 
 pci:v000010B5d00009050sv00001498sd00000362*
- ID_MODEL_FROM_DATABASE=TPMC866 8 Channel Serial Card
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (TPMC866 8 Channel Serial Card)
 
 pci:v000010B5d00009050sv00001522sd00000001*
- ID_MODEL_FROM_DATABASE=RockForce 4 Port V.90 Data/Fax/Voice Modem
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (RockForce 4 Port V.90 Data/Fax/Voice Modem)
 
 pci:v000010B5d00009050sv00001522sd00000002*
- ID_MODEL_FROM_DATABASE=RockForce 2 Port V.90 Data/Fax/Voice Modem
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (RockForce 2 Port V.90 Data/Fax/Voice Modem)
 
 pci:v000010B5d00009050sv00001522sd00000003*
- ID_MODEL_FROM_DATABASE=RockForce 6 Port V.90 Data/Fax/Voice Modem
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (RockForce 6 Port V.90 Data/Fax/Voice Modem)
 
 pci:v000010B5d00009050sv00001522sd00000004*
- ID_MODEL_FROM_DATABASE=RockForce 8 Port V.90 Data/Fax/Voice Modem
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (RockForce 8 Port V.90 Data/Fax/Voice Modem)
 
 pci:v000010B5d00009050sv00001522sd00000010*
- ID_MODEL_FROM_DATABASE=RockForce2000 4 Port V.90 Data/Fax/Voice Modem
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (RockForce2000 4 Port V.90 Data/Fax/Voice Modem)
 
 pci:v000010B5d00009050sv00001522sd00000020*
- ID_MODEL_FROM_DATABASE=RockForce2000 2 Port V.90 Data/Fax/Voice Modem
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (RockForce2000 2 Port V.90 Data/Fax/Voice Modem)
 
 pci:v000010B5d00009050sv000015EDsd00001000*
- ID_MODEL_FROM_DATABASE=Macrolink MCCS 8-port Serial
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (Macrolink MCCS 8-port Serial)
 
 pci:v000010B5d00009050sv000015EDsd00001001*
- ID_MODEL_FROM_DATABASE=Macrolink MCCS 16-port Serial
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (Macrolink MCCS 16-port Serial)
 
 pci:v000010B5d00009050sv000015EDsd00001002*
- ID_MODEL_FROM_DATABASE=Macrolink MCCS 8-port Serial Hot Swap
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (Macrolink MCCS 8-port Serial Hot Swap)
 
 pci:v000010B5d00009050sv000015EDsd00001003*
- ID_MODEL_FROM_DATABASE=Macrolink MCCS 16-port Serial Hot Swap
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (Macrolink MCCS 16-port Serial Hot Swap)
 
 pci:v000010B5d00009050sv00005654sd00002036*
- ID_MODEL_FROM_DATABASE=OpenSwitch 6 Telephony card
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (OpenSwitch 6 Telephony card)
 
 pci:v000010B5d00009050sv00005654sd00003132*
- ID_MODEL_FROM_DATABASE=OpenSwitch 12 Telephony card
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (OpenSwitch 12 Telephony card)
 
 pci:v000010B5d00009050sv00005654sd00005634*
- ID_MODEL_FROM_DATABASE=OpenLine4 Telephony Card
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (OpenLine4 Telephony Card)
 
 pci:v000010B5d00009050sv0000D531sd0000C002*
- ID_MODEL_FROM_DATABASE=PCIntelliCAN 2xSJA1000 CAN bus
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (PCIntelliCAN 2xSJA1000 CAN bus)
 
 pci:v000010B5d00009050sv0000D84Dsd00004006*
- ID_MODEL_FROM_DATABASE=EX-4006 1P
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (EX-4006 1P)
 
 pci:v000010B5d00009050sv0000D84Dsd00004008*
- ID_MODEL_FROM_DATABASE=EX-4008 1P EPP/ECP
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (EX-4008 1P EPP/ECP)
 
 pci:v000010B5d00009050sv0000D84Dsd00004014*
- ID_MODEL_FROM_DATABASE=EX-4014 2P
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (EX-4014 2P)
 
 pci:v000010B5d00009050sv0000D84Dsd00004018*
- ID_MODEL_FROM_DATABASE=EX-4018 3P EPP/ECP
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (EX-4018 3P EPP/ECP)
 
 pci:v000010B5d00009050sv0000D84Dsd00004025*
- ID_MODEL_FROM_DATABASE=EX-4025 1S(16C550) RS-232
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (EX-4025 1S(16C550) RS-232)
 
 pci:v000010B5d00009050sv0000D84Dsd00004027*
- ID_MODEL_FROM_DATABASE=EX-4027 1S(16C650) RS-232
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (EX-4027 1S(16C650) RS-232)
 
 pci:v000010B5d00009050sv0000D84Dsd00004028*
- ID_MODEL_FROM_DATABASE=EX-4028 1S(16C850) RS-232
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (EX-4028 1S(16C850) RS-232)
 
 pci:v000010B5d00009050sv0000D84Dsd00004036*
- ID_MODEL_FROM_DATABASE=EX-4036 2S(16C650) RS-232
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (EX-4036 2S(16C650) RS-232)
 
 pci:v000010B5d00009050sv0000D84Dsd00004037*
- ID_MODEL_FROM_DATABASE=EX-4037 2S(16C650) RS-232
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (EX-4037 2S(16C650) RS-232)
 
 pci:v000010B5d00009050sv0000D84Dsd00004038*
- ID_MODEL_FROM_DATABASE=EX-4038 2S(16C850) RS-232
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (EX-4038 2S(16C850) RS-232)
 
 pci:v000010B5d00009050sv0000D84Dsd00004052*
- ID_MODEL_FROM_DATABASE=EX-4052 1S(16C550) RS-422/485
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (EX-4052 1S(16C550) RS-422/485)
 
 pci:v000010B5d00009050sv0000D84Dsd00004053*
- ID_MODEL_FROM_DATABASE=EX-4053 2S(16C550) RS-422/485
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (EX-4053 2S(16C550) RS-422/485)
 
 pci:v000010B5d00009050sv0000D84Dsd00004055*
- ID_MODEL_FROM_DATABASE=EX-4055 4S(16C550) RS-232
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (EX-4055 4S(16C550) RS-232)
 
 pci:v000010B5d00009050sv0000D84Dsd00004058*
- ID_MODEL_FROM_DATABASE=EX-4055 4S(16C650) RS-232
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (EX-4055 4S(16C650) RS-232)
 
 pci:v000010B5d00009050sv0000D84Dsd00004065*
- ID_MODEL_FROM_DATABASE=EX-4065 8S(16C550) RS-232
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (EX-4065 8S(16C550) RS-232)
 
 pci:v000010B5d00009050sv0000D84Dsd00004068*
- ID_MODEL_FROM_DATABASE=EX-4068 8S(16C650) RS-232
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (EX-4068 8S(16C650) RS-232)
 
 pci:v000010B5d00009050sv0000D84Dsd00004078*
- ID_MODEL_FROM_DATABASE=EX-4078 2S(16C552) RS-232+1P
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (EX-4078 2S(16C552) RS-232+1P)
 
 pci:v000010B5d00009052*
  ID_MODEL_FROM_DATABASE=PCI9052 PCI <-> IOBus Bridge
@@ -18729,88 +19209,88 @@ pci:v000010B5d00009054*
  ID_MODEL_FROM_DATABASE=PCI9054 32-bit 33MHz PCI <-> IOBus Bridge
 
 pci:v000010B5d00009054sv000010B5sd00002455*
- ID_MODEL_FROM_DATABASE=Wessex Techology PHIL-PCI
+ ID_MODEL_FROM_DATABASE=PCI9054 32-bit 33MHz PCI <-> IOBus Bridge (Wessex Techology PHIL-PCI)
 
 pci:v000010B5d00009054sv000010B5sd00002696*
- ID_MODEL_FROM_DATABASE=Innes Corp AM Radcap card
+ ID_MODEL_FROM_DATABASE=PCI9054 32-bit 33MHz PCI <-> IOBus Bridge (Innes Corp AM Radcap card)
 
 pci:v000010B5d00009054sv000010B5sd00002717*
- ID_MODEL_FROM_DATABASE=Innes Corp Auricon card
+ ID_MODEL_FROM_DATABASE=PCI9054 32-bit 33MHz PCI <-> IOBus Bridge (Innes Corp Auricon card)
 
 pci:v000010B5d00009054sv000010B5sd00002844*
- ID_MODEL_FROM_DATABASE=Innes Corp TVS Encoder card
+ ID_MODEL_FROM_DATABASE=PCI9054 32-bit 33MHz PCI <-> IOBus Bridge (Innes Corp TVS Encoder card)
 
 pci:v000010B5d00009054sv000012C7sd00004001*
- ID_MODEL_FROM_DATABASE=Intel Dialogic DM/V960-4T1 PCI
+ ID_MODEL_FROM_DATABASE=PCI9054 32-bit 33MHz PCI <-> IOBus Bridge (Intel Dialogic DM/V960-4T1 PCI)
 
 pci:v000010B5d00009054sv000012D9sd00000002*
- ID_MODEL_FROM_DATABASE=PCI Prosody Card rev 1.5
+ ID_MODEL_FROM_DATABASE=PCI9054 32-bit 33MHz PCI <-> IOBus Bridge (PCI Prosody Card rev 1.5)
 
 pci:v000010B5d00009054sv000014B4sd0000D100*
- ID_MODEL_FROM_DATABASE=Dektec DTA-100
+ ID_MODEL_FROM_DATABASE=PCI9054 32-bit 33MHz PCI <-> IOBus Bridge (Dektec DTA-100)
 
 pci:v000010B5d00009054sv000014B4sd0000D114*
- ID_MODEL_FROM_DATABASE=Dektec DTA-120
+ ID_MODEL_FROM_DATABASE=PCI9054 32-bit 33MHz PCI <-> IOBus Bridge (Dektec DTA-120)
 
 pci:v000010B5d00009054sv000016DFsd00000011*
- ID_MODEL_FROM_DATABASE=PIKA PrimeNet MM PCI
+ ID_MODEL_FROM_DATABASE=PCI9054 32-bit 33MHz PCI <-> IOBus Bridge (PIKA PrimeNet MM PCI)
 
 pci:v000010B5d00009054sv000016DFsd00000012*
- ID_MODEL_FROM_DATABASE=PIKA PrimeNet MM cPCI 8
+ ID_MODEL_FROM_DATABASE=PCI9054 32-bit 33MHz PCI <-> IOBus Bridge (PIKA PrimeNet MM cPCI 8)
 
 pci:v000010B5d00009054sv000016DFsd00000013*
- ID_MODEL_FROM_DATABASE=PIKA PrimeNet MM cPCI 8 (without CAS Signaling)
+ ID_MODEL_FROM_DATABASE=PCI9054 32-bit 33MHz PCI <-> IOBus Bridge (PIKA PrimeNet MM cPCI 8 (without CAS Signaling))
 
 pci:v000010B5d00009054sv000016DFsd00000014*
- ID_MODEL_FROM_DATABASE=PIKA PrimeNet MM cPCI 4
+ ID_MODEL_FROM_DATABASE=PCI9054 32-bit 33MHz PCI <-> IOBus Bridge (PIKA PrimeNet MM cPCI 4)
 
 pci:v000010B5d00009054sv000016DFsd00000015*
- ID_MODEL_FROM_DATABASE=PIKA Daytona MM
+ ID_MODEL_FROM_DATABASE=PCI9054 32-bit 33MHz PCI <-> IOBus Bridge (PIKA Daytona MM)
 
 pci:v000010B5d00009054sv000016DFsd00000016*
- ID_MODEL_FROM_DATABASE=PIKA InLine MM
+ ID_MODEL_FROM_DATABASE=PCI9054 32-bit 33MHz PCI <-> IOBus Bridge (PIKA InLine MM)
 
 pci:v000010B5d00009056*
  ID_MODEL_FROM_DATABASE=PCI9056 32-bit 66MHz PCI <-> IOBus Bridge
 
 pci:v000010B5d00009056sv000010B5sd00002979*
- ID_MODEL_FROM_DATABASE=CellinkBlade 11 - CPCI board VoATM AAL1
+ ID_MODEL_FROM_DATABASE=PCI9056 32-bit 66MHz PCI <-> IOBus Bridge (CellinkBlade 11 - CPCI board VoATM AAL1)
 
 pci:v000010B5d00009056sv000010B5sd00003268*
- ID_MODEL_FROM_DATABASE=IXXAT iPC-I XC16/PCIe CAN Board
+ ID_MODEL_FROM_DATABASE=PCI9056 32-bit 66MHz PCI <-> IOBus Bridge (IXXAT iPC-I XC16/PCIe CAN Board)
 
 pci:v000010B5d00009056sv000010B5sd00003352*
- ID_MODEL_FROM_DATABASE=Alpermann+Velte PCL PCIe HD: Timecode Reader Board
+ ID_MODEL_FROM_DATABASE=PCI9056 32-bit 66MHz PCI <-> IOBus Bridge (Alpermann+Velte PCL PCIe HD: Timecode Reader Board)
 
 pci:v000010B5d00009056sv000010B5sd00003353*
- ID_MODEL_FROM_DATABASE=Alpermann+Velte PCL PCIe D: Timecode Reader Board
+ ID_MODEL_FROM_DATABASE=PCI9056 32-bit 66MHz PCI <-> IOBus Bridge (Alpermann+Velte PCL PCIe D: Timecode Reader Board)
 
 pci:v000010B5d00009056sv000010B5sd00003354*
- ID_MODEL_FROM_DATABASE=Alpermann+Velte PCL PCIe LV: Timecode Reader Board
+ ID_MODEL_FROM_DATABASE=PCI9056 32-bit 66MHz PCI <-> IOBus Bridge (Alpermann+Velte PCL PCIe LV: Timecode Reader Board)
 
 pci:v000010B5d00009056sv000010B5sd00003355*
- ID_MODEL_FROM_DATABASE=Alpermann+Velte PCL PCIe L: Timecode Reader Board
+ ID_MODEL_FROM_DATABASE=PCI9056 32-bit 66MHz PCI <-> IOBus Bridge (Alpermann+Velte PCL PCIe L: Timecode Reader Board)
 
 pci:v000010B5d00009056sv000010B5sd00003415*
- ID_MODEL_FROM_DATABASE=Alpermann+Velte PCIe TS: Time Synchronisation Board
+ ID_MODEL_FROM_DATABASE=PCI9056 32-bit 66MHz PCI <-> IOBus Bridge (Alpermann+Velte PCIe TS: Time Synchronisation Board)
 
 pci:v000010B5d00009056sv000010B5sd00003493*
- ID_MODEL_FROM_DATABASE=Alpermann+Velte PCL PCIe 3G: Timecode Reader Board
+ ID_MODEL_FROM_DATABASE=PCI9056 32-bit 66MHz PCI <-> IOBus Bridge (Alpermann+Velte PCL PCIe 3G: Timecode Reader Board)
 
 pci:v000010B5d00009056sv00001369sd0000C001*
- ID_MODEL_FROM_DATABASE=LX6464ES
+ ID_MODEL_FROM_DATABASE=PCI9056 32-bit 66MHz PCI <-> IOBus Bridge (LX6464ES)
 
 pci:v000010B5d00009056sv00001369sd0000C201*
- ID_MODEL_FROM_DATABASE=LX1616ES
+ ID_MODEL_FROM_DATABASE=PCI9056 32-bit 66MHz PCI <-> IOBus Bridge (LX1616ES)
 
 pci:v000010B5d00009056sv000014B4sd0000D10A*
- ID_MODEL_FROM_DATABASE=DekTec DTA-110T
+ ID_MODEL_FROM_DATABASE=PCI9056 32-bit 66MHz PCI <-> IOBus Bridge (DekTec DTA-110T)
 
 pci:v000010B5d00009056sv000014B4sd0000D140*
- ID_MODEL_FROM_DATABASE=Dektec DTA-140
+ ID_MODEL_FROM_DATABASE=PCI9056 32-bit 66MHz PCI <-> IOBus Bridge (Dektec DTA-140)
 
 pci:v000010B5d00009056sv00001A0Esd0000006F*
- ID_MODEL_FROM_DATABASE=Dektec DTA-111
+ ID_MODEL_FROM_DATABASE=PCI9056 32-bit 66MHz PCI <-> IOBus Bridge (Dektec DTA-111)
 
 pci:v000010B5d00009060*
  ID_MODEL_FROM_DATABASE=PCI9060 32-bit 33MHz PCI <-> IOBus Bridge
@@ -18819,7 +19299,7 @@ pci:v000010B5d0000906D*
  ID_MODEL_FROM_DATABASE=9060SD
 
 pci:v000010B5d0000906Dsv0000125Csd00000640*
- ID_MODEL_FROM_DATABASE=Aries 16000P
+ ID_MODEL_FROM_DATABASE=9060SD (Aries 16000P)
 
 pci:v000010B5d0000906E*
  ID_MODEL_FROM_DATABASE=9060ES
@@ -18828,61 +19308,61 @@ pci:v000010B5d00009080*
  ID_MODEL_FROM_DATABASE=PCI9080 32-bit; 33MHz PCI <-> IOBus Bridge
 
 pci:v000010B5d00009080sv0000103Csd000010EB*
- ID_MODEL_FROM_DATABASE=(Agilent) E2777B 83K Series Optical Communication Interface
+ ID_MODEL_FROM_DATABASE=PCI9080 32-bit; 33MHz PCI <-> IOBus Bridge ((Agilent) E2777B 83K Series Optical Communication Interface)
 
 pci:v000010B5d00009080sv0000103Csd000010EC*
- ID_MODEL_FROM_DATABASE=(Agilent) E6978-66442 PCI CIC
+ ID_MODEL_FROM_DATABASE=PCI9080 32-bit; 33MHz PCI <-> IOBus Bridge ((Agilent) E6978-66442 PCI CIC)
 
 pci:v000010B5d00009080sv000010B5sd00001123*
- ID_MODEL_FROM_DATABASE=Sectra KK631 encryption board
+ ID_MODEL_FROM_DATABASE=PCI9080 32-bit; 33MHz PCI <-> IOBus Bridge (Sectra KK631 encryption board)
 
 pci:v000010B5d00009080sv000010B5sd00009080*
- ID_MODEL_FROM_DATABASE=9080 [real subsystem ID not set]
+ ID_MODEL_FROM_DATABASE=PCI9080 32-bit; 33MHz PCI <-> IOBus Bridge (9080 [real subsystem ID not set])
 
 pci:v000010B5d00009080sv000012D9sd00000002*
- ID_MODEL_FROM_DATABASE=PCI Prosody Card
+ ID_MODEL_FROM_DATABASE=PCI9080 32-bit; 33MHz PCI <-> IOBus Bridge (PCI Prosody Card)
 
 pci:v000010B5d00009080sv000012DFsd00004422*
- ID_MODEL_FROM_DATABASE=4422PCI ["Do-All" Telemetry Data Aquisition System]
+ ID_MODEL_FROM_DATABASE=PCI9080 32-bit; 33MHz PCI <-> IOBus Bridge (4422PCI ["Do-All" Telemetry Data Aquisition System])
 
 pci:v000010B5d00009080sv00001369sd00009601*
- ID_MODEL_FROM_DATABASE=PCX822np
+ ID_MODEL_FROM_DATABASE=PCI9080 32-bit; 33MHz PCI <-> IOBus Bridge (PCX822np)
 
 pci:v000010B5d00009080sv00001369sd0000A102*
- ID_MODEL_FROM_DATABASE=PCX822v2
+ ID_MODEL_FROM_DATABASE=PCI9080 32-bit; 33MHz PCI <-> IOBus Bridge (PCX822v2)
 
 pci:v000010B5d00009080sv00001369sd0000A201*
- ID_MODEL_FROM_DATABASE=PCX442
+ ID_MODEL_FROM_DATABASE=PCI9080 32-bit; 33MHz PCI <-> IOBus Bridge (PCX442)
 
 pci:v000010B5d00009080sv00001369sd0000A301*
- ID_MODEL_FROM_DATABASE=LCM440v2
+ ID_MODEL_FROM_DATABASE=PCI9080 32-bit; 33MHz PCI <-> IOBus Bridge (LCM440v2)
 
 pci:v000010B5d00009080sv00001369sd0000A401*
- ID_MODEL_FROM_DATABASE=VX822
+ ID_MODEL_FROM_DATABASE=PCI9080 32-bit; 33MHz PCI <-> IOBus Bridge (VX822)
 
 pci:v000010B5d00009080sv00001369sd0000A402*
- ID_MODEL_FROM_DATABASE=VX822v2
+ ID_MODEL_FROM_DATABASE=PCI9080 32-bit; 33MHz PCI <-> IOBus Bridge (VX822v2)
 
 pci:v000010B5d00009080sv00001369sd0000A901*
- ID_MODEL_FROM_DATABASE=LCM420
+ ID_MODEL_FROM_DATABASE=PCI9080 32-bit; 33MHz PCI <-> IOBus Bridge (LCM420)
 
 pci:v000010B5d00009080sv00001369sd0000AA01*
- ID_MODEL_FROM_DATABASE=VX820v2
+ ID_MODEL_FROM_DATABASE=PCI9080 32-bit; 33MHz PCI <-> IOBus Bridge (VX820v2)
 
 pci:v000010B5d00009080sv00001517sd0000000B*
- ID_MODEL_FROM_DATABASE=ECSG-1R3ADC-PMC Clock synthesizer
+ ID_MODEL_FROM_DATABASE=PCI9080 32-bit; 33MHz PCI <-> IOBus Bridge (ECSG-1R3ADC-PMC Clock synthesizer)
 
 pci:v000010B5d00009656*
  ID_MODEL_FROM_DATABASE=PCI9656 PCI <-> IOBus Bridge
 
 pci:v000010B5d00009656sv00001517sd0000000F*
- ID_MODEL_FROM_DATABASE=ECDR-GC314-PMC Receiver
+ ID_MODEL_FROM_DATABASE=PCI9656 PCI <-> IOBus Bridge (ECDR-GC314-PMC Receiver)
 
 pci:v000010B5d00009656sv00001885sd00000700*
- ID_MODEL_FROM_DATABASE=Tsunami FPGA PMC with Altera Stratix S40
+ ID_MODEL_FROM_DATABASE=PCI9656 PCI <-> IOBus Bridge (Tsunami FPGA PMC with Altera Stratix S40)
 
 pci:v000010B5d00009656sv00001885sd00000701*
- ID_MODEL_FROM_DATABASE=Tsunami FPGA PMC with Altera Stratix S30
+ ID_MODEL_FROM_DATABASE=PCI9656 PCI <-> IOBus Bridge (Tsunami FPGA PMC with Altera Stratix S30)
 
 pci:v000010B5d0000A100*
  ID_MODEL_FROM_DATABASE=Blackmagic Design DeckLink
@@ -18897,28 +19377,28 @@ pci:v000010B5d0000D00D*
  ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge
 
 pci:v000010B5d0000D00Dsv000010B5sd00009030*
- ID_MODEL_FROM_DATABASE=Digium Tormenta 2 T400P or E400P Quad T1 or E1 PCI card
+ ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge (Digium Tormenta 2 T400P or E400P Quad T1 or E1 PCI card)
 
 pci:v000010B5d0000D33D*
  ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge
 
 pci:v000010B5d0000D33Dsv000010B5sd00009030*
- ID_MODEL_FROM_DATABASE=Tormenta 3 Varion V401PT Quad T1/J1 PCI card
+ ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge (Tormenta 3 Varion V401PT Quad T1/J1 PCI card)
 
 pci:v000010B5d0000D44D*
  ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge
 
 pci:v000010B5d0000D44Dsv000010B5sd000017F6*
- ID_MODEL_FROM_DATABASE=Allo CP100P/E 1-port E1/T1/J1 PCI/PCIe card
+ ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge (Allo CP100P/E 1-port E1/T1/J1 PCI/PCIe card)
 
 pci:v000010B5d0000D44Dsv000010B5sd000017F7*
- ID_MODEL_FROM_DATABASE=Allo CP400P/E 4-port E1/T1/J1 PCI/PCIe card
+ ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge (Allo CP400P/E 4-port E1/T1/J1 PCI/PCIe card)
 
 pci:v000010B5d0000D44Dsv000010B5sd000017F8*
- ID_MODEL_FROM_DATABASE=Allo CP200P/E 2-port E1/T1/J1 PCI/PCIe card
+ ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge (Allo CP200P/E 2-port E1/T1/J1 PCI/PCIe card)
 
 pci:v000010B5d0000D44Dsv000010B5sd00009030*
- ID_MODEL_FROM_DATABASE=Tormenta 3 Varion V401PE Quad E1 PCI card
+ ID_MODEL_FROM_DATABASE=PCI9030 32-bit 33MHz PCI <-> IOBus Bridge (Tormenta 3 Varion V401PE Quad E1 PCI card)
 
 pci:v000010B6*
  ID_VENDOR_FROM_DATABASE=Madge Networks
@@ -18933,19 +19413,19 @@ pci:v000010B6d00000002sv000010B6sd00000002*
  ID_MODEL_FROM_DATABASE=Smart 16/4 PCI Ringnode Mk2
 
 pci:v000010B6d00000002sv000010B6sd00000006*
- ID_MODEL_FROM_DATABASE=16/4 CardBus Adapter
+ ID_MODEL_FROM_DATABASE=Smart 16/4 PCI Ringnode Mk2 (16/4 CardBus Adapter)
 
 pci:v000010B6d00000003*
  ID_MODEL_FROM_DATABASE=Smart 16/4 PCI Ringnode Mk3
 
 pci:v000010B6d00000003sv00000E11sd0000B0FD*
- ID_MODEL_FROM_DATABASE=Compaq NC4621 PCI, 4/16, WOL
+ ID_MODEL_FROM_DATABASE=Smart 16/4 PCI Ringnode Mk3 (Compaq NC4621 PCI, 4/16, WOL)
 
 pci:v000010B6d00000003sv000010B6sd00000003*
  ID_MODEL_FROM_DATABASE=Smart 16/4 PCI Ringnode Mk3
 
 pci:v000010B6d00000003sv000010B6sd00000007*
- ID_MODEL_FROM_DATABASE=Presto PCI Plus Adapter
+ ID_MODEL_FROM_DATABASE=Smart 16/4 PCI Ringnode Mk3 (Presto PCI Plus Adapter)
 
 pci:v000010B6d00000004*
  ID_MODEL_FROM_DATABASE=Smart 16/4 PCI Ringnode Mk1
@@ -18954,13 +19434,13 @@ pci:v000010B6d00000006*
  ID_MODEL_FROM_DATABASE=16/4 Cardbus Adapter
 
 pci:v000010B6d00000006sv000010B6sd00000006*
- ID_MODEL_FROM_DATABASE=16/4 CardBus Adapter
+ ID_MODEL_FROM_DATABASE=16/4 Cardbus Adapter (16/4 CardBus Adapter)
 
 pci:v000010B6d00000007*
  ID_MODEL_FROM_DATABASE=Presto PCI Adapter
 
 pci:v000010B6d00000007sv000010B6sd00000007*
- ID_MODEL_FROM_DATABASE=Presto PCI
+ ID_MODEL_FROM_DATABASE=Presto PCI Adapter (Presto PCI)
 
 pci:v000010B6d00000009*
  ID_MODEL_FROM_DATABASE=Smart 100/16/4 PCI-HS Ringnode
@@ -18969,10 +19449,10 @@ pci:v000010B6d00000009sv000010B6sd00000009*
  ID_MODEL_FROM_DATABASE=Smart 100/16/4 PCI-HS Ringnode
 
 pci:v000010B6d0000000A*
- ID_MODEL_FROM_DATABASE=Smart 100/16/4 PCI Ringnode
+ ID_MODEL_FROM_DATABASE=Token Ring 100/16/4 Ringnode/Ringrunner
 
 pci:v000010B6d0000000Asv000010B6sd0000000A*
- ID_MODEL_FROM_DATABASE=Smart 100/16/4 PCI Ringnode
+ ID_MODEL_FROM_DATABASE=Token Ring 100/16/4 Ringnode/Ringrunner
 
 pci:v000010B6d0000000B*
  ID_MODEL_FROM_DATABASE=16/4 CardBus Adapter Mk2
@@ -18981,7 +19461,7 @@ pci:v000010B6d0000000Bsv000010B6sd00000008*
  ID_MODEL_FROM_DATABASE=16/4 CardBus Adapter Mk2
 
 pci:v000010B6d0000000Bsv000010B6sd0000000B*
- ID_MODEL_FROM_DATABASE=16/4 Cardbus Adapter Mk2
+ ID_MODEL_FROM_DATABASE=16/4 CardBus Adapter Mk2 (16/4 Cardbus Adapter Mk2)
 
 pci:v000010B6d0000000C*
  ID_MODEL_FROM_DATABASE=RapidFire 3140V2 16/4 TR Adapter
@@ -19001,11 +19481,14 @@ pci:v000010B7*
 pci:v000010B7d00000001*
  ID_MODEL_FROM_DATABASE=3c985 1000BaseSX (SX/TX)
 
+pci:v000010B7d00000001sv00009850sd00000001*
+ ID_MODEL_FROM_DATABASE=3c985 1000BaseSX (SX/TX) (3c985B-SX)
+
 pci:v000010B7d00000013*
  ID_MODEL_FROM_DATABASE=AR5212 802.11abg NIC (3CRDAG675)
 
 pci:v000010B7d00000013sv000010B7sd00002031*
- ID_MODEL_FROM_DATABASE=3CRDAG675 11a/b/g Wireless PCI Adapter
+ ID_MODEL_FROM_DATABASE=AR5212 802.11abg NIC (3CRDAG675) (3CRDAG675 11a/b/g Wireless PCI Adapter)
 
 pci:v000010B7d00000910*
  ID_MODEL_FROM_DATABASE=3C910-A01
@@ -19017,10 +19500,10 @@ pci:v000010B7d00001007*
  ID_MODEL_FROM_DATABASE=Mini PCI 56k Winmodem
 
 pci:v000010B7d00001007sv000010B7sd0000615B*
- ID_MODEL_FROM_DATABASE=Mini PCI 56K Modem
+ ID_MODEL_FROM_DATABASE=Mini PCI 56k Winmodem (Mini PCI 56K Modem)
 
 pci:v000010B7d00001007sv000010B7sd0000615C*
- ID_MODEL_FROM_DATABASE=Mini PCI 56K Modem
+ ID_MODEL_FROM_DATABASE=Mini PCI 56k Winmodem (Mini PCI 56K Modem)
 
 pci:v000010B7d00001201*
  ID_MODEL_FROM_DATABASE=3c982-TXM 10/100baseTX Dual Port A [Hydra]
@@ -19032,16 +19515,16 @@ pci:v000010B7d00001700*
  ID_MODEL_FROM_DATABASE=3c940 10/100/1000Base-T [Marvell]
 
 pci:v000010B7d00001700sv00001043sd000080EB*
- ID_MODEL_FROM_DATABASE=A7V600/P4P800/K8V motherboard
+ ID_MODEL_FROM_DATABASE=3c940 10/100/1000Base-T [Marvell] (A7V600/P4P800/K8V motherboard)
 
 pci:v000010B7d00001700sv000010B7sd00000010*
- ID_MODEL_FROM_DATABASE=3C940 Gigabit LOM Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=3c940 10/100/1000Base-T [Marvell] (3C940 Gigabit LOM Ethernet Adapter)
 
 pci:v000010B7d00001700sv000010B7sd00000020*
- ID_MODEL_FROM_DATABASE=3C941 Gigabit LOM Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=3c940 10/100/1000Base-T [Marvell] (3C941 Gigabit LOM Ethernet Adapter)
 
 pci:v000010B7d00001700sv0000147Bsd00001407*
- ID_MODEL_FROM_DATABASE=KV8-MAX3 motherboard
+ ID_MODEL_FROM_DATABASE=3c940 10/100/1000Base-T [Marvell] (KV8-MAX3 motherboard)
 
 pci:v000010B7d00003390*
  ID_MODEL_FROM_DATABASE=3c339 TokenLink Velocity
@@ -19050,7 +19533,7 @@ pci:v000010B7d00003590*
  ID_MODEL_FROM_DATABASE=3c359 TokenLink Velocity XL
 
 pci:v000010B7d00003590sv000010B7sd00003590*
- ID_MODEL_FROM_DATABASE=TokenLink Velocity XL Adapter (3C359/359B)
+ ID_MODEL_FROM_DATABASE=3c359 TokenLink Velocity XL (TokenLink Velocity XL Adapter (3C359/359B))
 
 pci:v000010B7d00004500*
  ID_MODEL_FROM_DATABASE=3c450 HomePNA [Tornado]
@@ -19062,19 +19545,19 @@ pci:v000010B7d00005057*
  ID_MODEL_FROM_DATABASE=3c575 Megahertz 10/100 LAN CardBus [Boomerang]
 
 pci:v000010B7d00005057sv000010B7sd00005A57*
- ID_MODEL_FROM_DATABASE=3C575 Megahertz 10/100 LAN Cardbus PC Card
+ ID_MODEL_FROM_DATABASE=3c575 Megahertz 10/100 LAN CardBus [Boomerang] (3C575 Megahertz 10/100 LAN Cardbus PC Card)
 
 pci:v000010B7d00005157*
  ID_MODEL_FROM_DATABASE=3cCFE575BT Megahertz 10/100 LAN CardBus [Cyclone]
 
 pci:v000010B7d00005157sv000010B7sd00005B57*
- ID_MODEL_FROM_DATABASE=3C575 Megahertz 10/100 LAN Cardbus PC Card
+ ID_MODEL_FROM_DATABASE=3cCFE575BT Megahertz 10/100 LAN CardBus [Cyclone] (3C575 Megahertz 10/100 LAN Cardbus PC Card)
 
 pci:v000010B7d00005257*
  ID_MODEL_FROM_DATABASE=3cCFE575CT CardBus [Cyclone]
 
 pci:v000010B7d00005257sv000010B7sd00005C57*
- ID_MODEL_FROM_DATABASE=FE575C-3Com 10/100 LAN CardBus-Fast Ethernet
+ ID_MODEL_FROM_DATABASE=3cCFE575CT CardBus [Cyclone] (FE575C-3Com 10/100 LAN CardBus-Fast Ethernet)
 
 pci:v000010B7d00005900*
  ID_MODEL_FROM_DATABASE=3c590 10BaseT [Vortex]
@@ -19098,7 +19581,7 @@ pci:v000010B7d00005B57*
  ID_MODEL_FROM_DATABASE=3c595 Megahertz 10/100 LAN CardBus [Boomerang]
 
 pci:v000010B7d00005B57sv000010B7sd00005B57*
- ID_MODEL_FROM_DATABASE=3C575 Megahertz 10/100 LAN Cardbus PC Card
+ ID_MODEL_FROM_DATABASE=3c595 Megahertz 10/100 LAN CardBus [Boomerang] (3C575 Megahertz 10/100 LAN Cardbus PC Card)
 
 pci:v000010B7d00006000*
  ID_MODEL_FROM_DATABASE=3CRSHPW796 [OfficeConnect Wireless CardBus]
@@ -19113,31 +19596,31 @@ pci:v000010B7d00006056*
  ID_MODEL_FROM_DATABASE=3c556B CardBus [Tornado]
 
 pci:v000010B7d00006056sv000010B7sd00006556*
- ID_MODEL_FROM_DATABASE=10/100 Mini PCI Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=3c556B CardBus [Tornado] (10/100 Mini PCI Ethernet Adapter)
 
 pci:v000010B7d00006560*
  ID_MODEL_FROM_DATABASE=3cCFE656 CardBus [Cyclone]
 
 pci:v000010B7d00006560sv000010B7sd0000656A*
- ID_MODEL_FROM_DATABASE=3CCFEM656 10/100 LAN+56K Modem CardBus
+ ID_MODEL_FROM_DATABASE=3cCFE656 CardBus [Cyclone] (3CCFEM656 10/100 LAN+56K Modem CardBus)
 
 pci:v000010B7d00006561*
  ID_MODEL_FROM_DATABASE=3cCFEM656 10/100 LAN+56K Modem CardBus
 
 pci:v000010B7d00006561sv000010B7sd0000656B*
- ID_MODEL_FROM_DATABASE=3CCFEM656 10/100 LAN+56K Modem CardBus
+ ID_MODEL_FROM_DATABASE=3cCFEM656 10/100 LAN+56K Modem CardBus (3CCFEM656 10/100 LAN+56K Modem CardBus)
 
 pci:v000010B7d00006562*
  ID_MODEL_FROM_DATABASE=3cCFEM656B 10/100 LAN+Winmodem CardBus [Cyclone]
 
 pci:v000010B7d00006562sv000010B7sd0000656B*
- ID_MODEL_FROM_DATABASE=3CCFEM656B 10/100 LAN+56K Modem CardBus
+ ID_MODEL_FROM_DATABASE=3cCFEM656B 10/100 LAN+Winmodem CardBus [Cyclone] (3CCFEM656B 10/100 LAN+56K Modem CardBus)
 
 pci:v000010B7d00006563*
  ID_MODEL_FROM_DATABASE=3cCFEM656B 10/100 LAN+56K Modem CardBus
 
 pci:v000010B7d00006563sv000010B7sd0000656B*
- ID_MODEL_FROM_DATABASE=3CCFEM656 10/100 LAN+56K Modem CardBus
+ ID_MODEL_FROM_DATABASE=3cCFEM656B 10/100 LAN+56K Modem CardBus (3CCFEM656 10/100 LAN+56K Modem CardBus)
 
 pci:v000010B7d00006564*
  ID_MODEL_FROM_DATABASE=3cXFEM656C 10/100 LAN+Winmodem CardBus [Tornado]
@@ -19173,13 +19656,13 @@ pci:v000010B7d00009004*
  ID_MODEL_FROM_DATABASE=3c900B-TPO Etherlink XL [Cyclone]
 
 pci:v000010B7d00009004sv000010B7sd00009004*
- ID_MODEL_FROM_DATABASE=3C900B-TPO Etherlink XL TPO 10Mb
+ ID_MODEL_FROM_DATABASE=3c900B-TPO Etherlink XL [Cyclone] (3C900B-TPO Etherlink XL TPO 10Mb)
 
 pci:v000010B7d00009005*
  ID_MODEL_FROM_DATABASE=3c900B-Combo Etherlink XL [Cyclone]
 
 pci:v000010B7d00009005sv000010B7sd00009005*
- ID_MODEL_FROM_DATABASE=3C900B-Combo Etherlink XL Combo
+ ID_MODEL_FROM_DATABASE=3c900B-Combo Etherlink XL [Cyclone] (3C900B-Combo Etherlink XL Combo)
 
 pci:v000010B7d00009006*
  ID_MODEL_FROM_DATABASE=3c900B-TPC Etherlink XL [Cyclone]
@@ -19203,67 +19686,67 @@ pci:v000010B7d00009055*
  ID_MODEL_FROM_DATABASE=3c905B 100BaseTX [Cyclone]
 
 pci:v000010B7d00009055sv00001028sd00000080*
- ID_MODEL_FROM_DATABASE=3C905B Fast Etherlink XL 10/100
+ ID_MODEL_FROM_DATABASE=3c905B 100BaseTX [Cyclone] (3C905B Fast Etherlink XL 10/100)
 
 pci:v000010B7d00009055sv00001028sd00000081*
- ID_MODEL_FROM_DATABASE=3C905B Fast Etherlink XL 10/100
+ ID_MODEL_FROM_DATABASE=3c905B 100BaseTX [Cyclone] (3C905B Fast Etherlink XL 10/100)
 
 pci:v000010B7d00009055sv00001028sd00000082*
- ID_MODEL_FROM_DATABASE=3C905B Fast Etherlink XL 10/100
+ ID_MODEL_FROM_DATABASE=3c905B 100BaseTX [Cyclone] (3C905B Fast Etherlink XL 10/100)
 
 pci:v000010B7d00009055sv00001028sd00000083*
- ID_MODEL_FROM_DATABASE=3C905B Fast Etherlink XL 10/100
+ ID_MODEL_FROM_DATABASE=3c905B 100BaseTX [Cyclone] (3C905B Fast Etherlink XL 10/100)
 
 pci:v000010B7d00009055sv00001028sd00000084*
- ID_MODEL_FROM_DATABASE=3C905B Fast Etherlink XL 10/100
+ ID_MODEL_FROM_DATABASE=3c905B 100BaseTX [Cyclone] (3C905B Fast Etherlink XL 10/100)
 
 pci:v000010B7d00009055sv00001028sd00000085*
- ID_MODEL_FROM_DATABASE=3C905B Fast Etherlink XL 10/100
+ ID_MODEL_FROM_DATABASE=3c905B 100BaseTX [Cyclone] (3C905B Fast Etherlink XL 10/100)
 
 pci:v000010B7d00009055sv00001028sd00000086*
- ID_MODEL_FROM_DATABASE=3C905B Fast Etherlink XL 10/100
+ ID_MODEL_FROM_DATABASE=3c905B 100BaseTX [Cyclone] (3C905B Fast Etherlink XL 10/100)
 
 pci:v000010B7d00009055sv00001028sd00000087*
- ID_MODEL_FROM_DATABASE=3C905B Fast Etherlink XL 10/100
+ ID_MODEL_FROM_DATABASE=3c905B 100BaseTX [Cyclone] (3C905B Fast Etherlink XL 10/100)
 
 pci:v000010B7d00009055sv00001028sd00000088*
- ID_MODEL_FROM_DATABASE=3C905B Fast Etherlink XL 10/100
+ ID_MODEL_FROM_DATABASE=3c905B 100BaseTX [Cyclone] (3C905B Fast Etherlink XL 10/100)
 
 pci:v000010B7d00009055sv00001028sd00000089*
- ID_MODEL_FROM_DATABASE=3C905B Fast Etherlink XL 10/100
+ ID_MODEL_FROM_DATABASE=3c905B 100BaseTX [Cyclone] (3C905B Fast Etherlink XL 10/100)
 
 pci:v000010B7d00009055sv00001028sd00000090*
- ID_MODEL_FROM_DATABASE=3C905B Fast Etherlink XL 10/100
+ ID_MODEL_FROM_DATABASE=3c905B 100BaseTX [Cyclone] (3C905B Fast Etherlink XL 10/100)
 
 pci:v000010B7d00009055sv00001028sd00000091*
- ID_MODEL_FROM_DATABASE=3C905B Fast Etherlink XL 10/100
+ ID_MODEL_FROM_DATABASE=3c905B 100BaseTX [Cyclone] (3C905B Fast Etherlink XL 10/100)
 
 pci:v000010B7d00009055sv00001028sd00000092*
- ID_MODEL_FROM_DATABASE=3C905B Fast Etherlink XL 10/100
+ ID_MODEL_FROM_DATABASE=3c905B 100BaseTX [Cyclone] (3C905B Fast Etherlink XL 10/100)
 
 pci:v000010B7d00009055sv00001028sd00000093*
- ID_MODEL_FROM_DATABASE=3C905B Fast Etherlink XL 10/100
+ ID_MODEL_FROM_DATABASE=3c905B 100BaseTX [Cyclone] (3C905B Fast Etherlink XL 10/100)
 
 pci:v000010B7d00009055sv00001028sd00000094*
- ID_MODEL_FROM_DATABASE=3C905B Fast Etherlink XL 10/100
+ ID_MODEL_FROM_DATABASE=3c905B 100BaseTX [Cyclone] (3C905B Fast Etherlink XL 10/100)
 
 pci:v000010B7d00009055sv00001028sd00000095*
- ID_MODEL_FROM_DATABASE=3C905B Fast Etherlink XL 10/100
+ ID_MODEL_FROM_DATABASE=3c905B 100BaseTX [Cyclone] (3C905B Fast Etherlink XL 10/100)
 
 pci:v000010B7d00009055sv00001028sd00000096*
- ID_MODEL_FROM_DATABASE=3C905B Fast Etherlink XL 10/100
+ ID_MODEL_FROM_DATABASE=3c905B 100BaseTX [Cyclone] (3C905B Fast Etherlink XL 10/100)
 
 pci:v000010B7d00009055sv00001028sd00000097*
- ID_MODEL_FROM_DATABASE=3C905B Fast Etherlink XL 10/100
+ ID_MODEL_FROM_DATABASE=3c905B 100BaseTX [Cyclone] (3C905B Fast Etherlink XL 10/100)
 
 pci:v000010B7d00009055sv00001028sd00000098*
- ID_MODEL_FROM_DATABASE=3C905B Fast Etherlink XL 10/100
+ ID_MODEL_FROM_DATABASE=3c905B 100BaseTX [Cyclone] (3C905B Fast Etherlink XL 10/100)
 
 pci:v000010B7d00009055sv00001028sd00000099*
- ID_MODEL_FROM_DATABASE=3C905B Fast Etherlink XL 10/100
+ ID_MODEL_FROM_DATABASE=3c905B 100BaseTX [Cyclone] (3C905B Fast Etherlink XL 10/100)
 
 pci:v000010B7d00009055sv000010B7sd00009055*
- ID_MODEL_FROM_DATABASE=3C905B Fast Etherlink XL 10/100
+ ID_MODEL_FROM_DATABASE=3c905B 100BaseTX [Cyclone] (3C905B Fast Etherlink XL 10/100)
 
 pci:v000010B7d00009056*
  ID_MODEL_FROM_DATABASE=3c905B-T4 Fast EtherLink XL [Cyclone]
@@ -19278,40 +19761,40 @@ pci:v000010B7d00009200*
  ID_MODEL_FROM_DATABASE=3c905C-TX/TX-M [Tornado]
 
 pci:v000010B7d00009200sv00001028sd00000095*
- ID_MODEL_FROM_DATABASE=3C920 Integrated Fast Ethernet Controller
+ ID_MODEL_FROM_DATABASE=3c905C-TX/TX-M [Tornado] (3C920 Integrated Fast Ethernet Controller)
 
 pci:v000010B7d00009200sv00001028sd00000097*
- ID_MODEL_FROM_DATABASE=3C920 Integrated Fast Ethernet Controller
+ ID_MODEL_FROM_DATABASE=3c905C-TX/TX-M [Tornado] (3C920 Integrated Fast Ethernet Controller)
 
 pci:v000010B7d00009200sv00001028sd000000B4*
- ID_MODEL_FROM_DATABASE=OptiPlex GX110
+ ID_MODEL_FROM_DATABASE=3c905C-TX/TX-M [Tornado] (OptiPlex GX110)
 
 pci:v000010B7d00009200sv00001028sd000000D8*
- ID_MODEL_FROM_DATABASE=Precision 530
+ ID_MODEL_FROM_DATABASE=3c905C-TX/TX-M [Tornado] (Precision 530)
 
 pci:v000010B7d00009200sv00001028sd000000FE*
- ID_MODEL_FROM_DATABASE=Optiplex GX240
+ ID_MODEL_FROM_DATABASE=3c905C-TX/TX-M [Tornado] (Optiplex GX240)
 
 pci:v000010B7d00009200sv00001028sd0000012A*
- ID_MODEL_FROM_DATABASE=3C920 Integrated Fast Ethernet Controller [Latitude C640]
+ ID_MODEL_FROM_DATABASE=3c905C-TX/TX-M [Tornado] (3C920 Integrated Fast Ethernet Controller [Latitude C640])
 
 pci:v000010B7d00009200sv000010B7sd00001000*
- ID_MODEL_FROM_DATABASE=3C905CX-TX/TX-M Fast Etherlink for PC Management NIC
+ ID_MODEL_FROM_DATABASE=3c905C-TX/TX-M [Tornado] (3C905CX-TX/TX-M Fast Etherlink for PC Management NIC)
 
 pci:v000010B7d00009200sv000010B7sd00007000*
- ID_MODEL_FROM_DATABASE=10/100 Mini PCI Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=3c905C-TX/TX-M [Tornado] (10/100 Mini PCI Ethernet Adapter)
 
 pci:v000010B7d00009200sv000010F1sd00002466*
- ID_MODEL_FROM_DATABASE=Tiger MPX S2466 (3C920 Integrated Fast Ethernet Controller)
+ ID_MODEL_FROM_DATABASE=3c905C-TX/TX-M [Tornado] (Tiger MPX S2466 (3C920 Integrated Fast Ethernet Controller))
 
 pci:v000010B7d00009200sv0000144Dsd0000C005*
- ID_MODEL_FROM_DATABASE=X10 Laptop
+ ID_MODEL_FROM_DATABASE=3c905C-TX/TX-M [Tornado] (X10 Laptop)
 
 pci:v000010B7d00009201*
  ID_MODEL_FROM_DATABASE=3C920B-EMB Integrated Fast Ethernet Controller [Tornado]
 
 pci:v000010B7d00009201sv00001043sd000080AB*
- ID_MODEL_FROM_DATABASE=A7N8X Deluxe onboard 3C920B-EMB Integrated Fast Ethernet Controller
+ ID_MODEL_FROM_DATABASE=3C920B-EMB Integrated Fast Ethernet Controller [Tornado] (A7N8X Deluxe onboard 3C920B-EMB Integrated Fast Ethernet Controller)
 
 pci:v000010B7d00009202*
  ID_MODEL_FROM_DATABASE=3Com 3C920B-EMB-WNM Integrated Fast Ethernet Controller
@@ -19326,22 +19809,22 @@ pci:v000010B7d00009800*
  ID_MODEL_FROM_DATABASE=3c980-TX Fast Etherlink XL Server Adapter [Cyclone]
 
 pci:v000010B7d00009800sv000010B7sd00009800*
- ID_MODEL_FROM_DATABASE=3c980-TX Fast Etherlink XL Server Adapter
+ ID_MODEL_FROM_DATABASE=3c980-TX Fast Etherlink XL Server Adapter [Cyclone] (3c980-TX Fast Etherlink XL Server Adapter)
 
 pci:v000010B7d00009805*
  ID_MODEL_FROM_DATABASE=3c980-C 10/100baseTX NIC [Python-T]
 
 pci:v000010B7d00009805sv000010B7sd00001201*
- ID_MODEL_FROM_DATABASE=EtherLink Server 10/100 Dual Port A
+ ID_MODEL_FROM_DATABASE=3c980-C 10/100baseTX NIC [Python-T] (EtherLink Server 10/100 Dual Port A)
 
 pci:v000010B7d00009805sv000010B7sd00001202*
- ID_MODEL_FROM_DATABASE=EtherLink Server 10/100 Dual Port B
+ ID_MODEL_FROM_DATABASE=3c980-C 10/100baseTX NIC [Python-T] (EtherLink Server 10/100 Dual Port B)
 
 pci:v000010B7d00009805sv000010B7sd00009805*
- ID_MODEL_FROM_DATABASE=3c980 10/100baseTX NIC [Python-T]
+ ID_MODEL_FROM_DATABASE=3c980-C 10/100baseTX NIC [Python-T] (3c980 10/100baseTX NIC [Python-T])
 
 pci:v000010B7d00009805sv000010F1sd00002462*
- ID_MODEL_FROM_DATABASE=Thunder K7 S2462
+ ID_MODEL_FROM_DATABASE=3c980-C 10/100baseTX NIC [Python-T] (Thunder K7 S2462)
 
 pci:v000010B7d00009900*
  ID_MODEL_FROM_DATABASE=3C990-TX [Typhoon]
@@ -19356,25 +19839,25 @@ pci:v000010B7d00009904*
  ID_MODEL_FROM_DATABASE=3C990B-TX-M/3C990BSVR [Typhoon2]
 
 pci:v000010B7d00009904sv000010B7sd00001000*
- ID_MODEL_FROM_DATABASE=3CR990B-TX-M [Typhoon2]
+ ID_MODEL_FROM_DATABASE=3C990B-TX-M/3C990BSVR [Typhoon2] (3CR990B-TX-M [Typhoon2])
 
 pci:v000010B7d00009904sv000010B7sd00002000*
- ID_MODEL_FROM_DATABASE=3CR990BSVR [Typhoon2 Server]
+ ID_MODEL_FROM_DATABASE=3C990B-TX-M/3C990BSVR [Typhoon2] (3CR990BSVR [Typhoon2 Server])
 
 pci:v000010B7d00009905*
  ID_MODEL_FROM_DATABASE=3CR990-FX-95/97/95 [Typhon Fiber]
 
 pci:v000010B7d00009905sv000010B7sd00001101*
- ID_MODEL_FROM_DATABASE=3CR990-FX-95 [Typhoon Fiber 56-bit]
+ ID_MODEL_FROM_DATABASE=3CR990-FX-95/97/95 [Typhon Fiber] (3CR990-FX-95 [Typhoon Fiber 56-bit])
 
 pci:v000010B7d00009905sv000010B7sd00001102*
- ID_MODEL_FROM_DATABASE=3CR990-FX-97 [Typhoon Fiber 168-bit]
+ ID_MODEL_FROM_DATABASE=3CR990-FX-95/97/95 [Typhon Fiber] (3CR990-FX-97 [Typhoon Fiber 168-bit])
 
 pci:v000010B7d00009905sv000010B7sd00002101*
- ID_MODEL_FROM_DATABASE=3CR990-FX-95 Server [Typhoon Fiber 56-bit]
+ ID_MODEL_FROM_DATABASE=3CR990-FX-95/97/95 [Typhon Fiber] (3CR990-FX-95 Server [Typhoon Fiber 56-bit])
 
 pci:v000010B7d00009905sv000010B7sd00002102*
- ID_MODEL_FROM_DATABASE=3CR990-FX-97 Server [Typhoon Fiber 168-bit]
+ ID_MODEL_FROM_DATABASE=3CR990-FX-95/97/95 [Typhon Fiber] (3CR990-FX-97 Server [Typhoon Fiber 168-bit])
 
 pci:v000010B7d00009908*
  ID_MODEL_FROM_DATABASE=3CR990SVR95 [Typhoon Server 56-bit]
@@ -19395,49 +19878,49 @@ pci:v000010B8d00000005*
  ID_MODEL_FROM_DATABASE=83c170 EPIC/100 Fast Ethernet Adapter
 
 pci:v000010B8d00000005sv00001055sd0000E000*
- ID_MODEL_FROM_DATABASE=LANEPIC 10/100 [EVB171Q-PCI]
+ ID_MODEL_FROM_DATABASE=83c170 EPIC/100 Fast Ethernet Adapter (LANEPIC 10/100 [EVB171Q-PCI])
 
 pci:v000010B8d00000005sv00001055sd0000E002*
- ID_MODEL_FROM_DATABASE=LANEPIC 10/100 [EVB171G-PCI]
+ ID_MODEL_FROM_DATABASE=83c170 EPIC/100 Fast Ethernet Adapter (LANEPIC 10/100 [EVB171G-PCI])
 
 pci:v000010B8d00000005sv000010B8sd0000A011*
- ID_MODEL_FROM_DATABASE=EtherPower II 10/100
+ ID_MODEL_FROM_DATABASE=83c170 EPIC/100 Fast Ethernet Adapter (EtherPower II 10/100)
 
 pci:v000010B8d00000005sv000010B8sd0000A014*
- ID_MODEL_FROM_DATABASE=EtherPower II 10/100
+ ID_MODEL_FROM_DATABASE=83c170 EPIC/100 Fast Ethernet Adapter (EtherPower II 10/100)
 
 pci:v000010B8d00000005sv000010B8sd0000A015*
- ID_MODEL_FROM_DATABASE=EtherPower II 10/100
+ ID_MODEL_FROM_DATABASE=83c170 EPIC/100 Fast Ethernet Adapter (EtherPower II 10/100)
 
 pci:v000010B8d00000005sv000010B8sd0000A016*
- ID_MODEL_FROM_DATABASE=EtherPower II 10/100
+ ID_MODEL_FROM_DATABASE=83c170 EPIC/100 Fast Ethernet Adapter (EtherPower II 10/100)
 
 pci:v000010B8d00000005sv000010B8sd0000A017*
- ID_MODEL_FROM_DATABASE=EtherPower II 10/100
+ ID_MODEL_FROM_DATABASE=83c170 EPIC/100 Fast Ethernet Adapter (EtherPower II 10/100)
 
 pci:v000010B8d00000006*
  ID_MODEL_FROM_DATABASE=83c175 EPIC/100 Fast Ethernet Adapter
 
 pci:v000010B8d00000006sv00001055sd0000E100*
- ID_MODEL_FROM_DATABASE=LANEPIC Cardbus Fast Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=83c175 EPIC/100 Fast Ethernet Adapter (LANEPIC Cardbus Fast Ethernet Adapter)
 
 pci:v000010B8d00000006sv00001055sd0000E102*
- ID_MODEL_FROM_DATABASE=LANEPIC Cardbus Fast Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=83c175 EPIC/100 Fast Ethernet Adapter (LANEPIC Cardbus Fast Ethernet Adapter)
 
 pci:v000010B8d00000006sv00001055sd0000E300*
- ID_MODEL_FROM_DATABASE=LANEPIC Cardbus Fast Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=83c175 EPIC/100 Fast Ethernet Adapter (LANEPIC Cardbus Fast Ethernet Adapter)
 
 pci:v000010B8d00000006sv00001055sd0000E302*
- ID_MODEL_FROM_DATABASE=LANEPIC Cardbus Fast Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=83c175 EPIC/100 Fast Ethernet Adapter (LANEPIC Cardbus Fast Ethernet Adapter)
 
 pci:v000010B8d00000006sv000010B8sd0000A012*
- ID_MODEL_FROM_DATABASE=LANEPIC Cardbus Fast Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=83c175 EPIC/100 Fast Ethernet Adapter (LANEPIC Cardbus Fast Ethernet Adapter)
 
 pci:v000010B8d00000006sv000013A2sd00008002*
- ID_MODEL_FROM_DATABASE=LANEPIC Cardbus Fast Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=83c175 EPIC/100 Fast Ethernet Adapter (LANEPIC Cardbus Fast Ethernet Adapter)
 
 pci:v000010B8d00000006sv000013A2sd00008006*
- ID_MODEL_FROM_DATABASE=LANEPIC Cardbus Fast Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=83c175 EPIC/100 Fast Ethernet Adapter (LANEPIC Cardbus Fast Ethernet Adapter)
 
 pci:v000010B8d00001000*
  ID_MODEL_FROM_DATABASE=FDC 37c665
@@ -19500,13 +19983,13 @@ pci:v000010B9d00001521*
  ID_MODEL_FROM_DATABASE=M1521 [Aladdin III]
 
 pci:v000010B9d00001521sv000010B9sd00001521*
- ID_MODEL_FROM_DATABASE=ALI M1521 Aladdin III CPU Bridge
+ ID_MODEL_FROM_DATABASE=M1521 [Aladdin III] (ALI M1521 Aladdin III CPU Bridge)
 
 pci:v000010B9d00001523*
  ID_MODEL_FROM_DATABASE=M1523
 
 pci:v000010B9d00001523sv000010B9sd00001523*
- ID_MODEL_FROM_DATABASE=ALI M1523 ISA Bridge
+ ID_MODEL_FROM_DATABASE=M1523 (ALI M1523 ISA Bridge)
 
 pci:v000010B9d00001531*
  ID_MODEL_FROM_DATABASE=M1531 [Aladdin IV]
@@ -19515,16 +19998,16 @@ pci:v000010B9d00001533*
  ID_MODEL_FROM_DATABASE=M1533/M1535/M1543 PCI to ISA Bridge [Aladdin IV/V/V+]
 
 pci:v000010B9d00001533sv00001014sd0000053B*
- ID_MODEL_FROM_DATABASE=ThinkPad R40e
+ ID_MODEL_FROM_DATABASE=M1533/M1535/M1543 PCI to ISA Bridge [Aladdin IV/V/V+] (ThinkPad R40e)
 
 pci:v000010B9d00001533sv000010B9sd00001533*
- ID_MODEL_FROM_DATABASE=ALi M1533 Aladdin IV/V ISA Bridge
+ ID_MODEL_FROM_DATABASE=M1533/M1535/M1543 PCI to ISA Bridge [Aladdin IV/V/V+] (ALi M1533 Aladdin IV/V ISA Bridge)
 
 pci:v000010B9d00001541*
  ID_MODEL_FROM_DATABASE=M1541
 
 pci:v000010B9d00001541sv000010B9sd00001541*
- ID_MODEL_FROM_DATABASE=ALI M1541 Aladdin V/V+ AGP System Controller
+ ID_MODEL_FROM_DATABASE=M1541 (ALI M1541 Aladdin V/V+ AGP System Controller)
 
 pci:v000010B9d00001543*
  ID_MODEL_FROM_DATABASE=M1543
@@ -19533,10 +20016,10 @@ pci:v000010B9d00001563*
  ID_MODEL_FROM_DATABASE=M1563 HyperTransport South Bridge
 
 pci:v000010B9d00001563sv000010B9sd00001563*
- ID_MODEL_FROM_DATABASE=ASRock 939Dual-SATA2 Motherboard
+ ID_MODEL_FROM_DATABASE=M1563 HyperTransport South Bridge (ASRock 939Dual-SATA2 Motherboard)
 
 pci:v000010B9d00001563sv00001849sd00001563*
- ID_MODEL_FROM_DATABASE=ASRock 939Dual-SATA2 Motherboard
+ ID_MODEL_FROM_DATABASE=M1563 HyperTransport South Bridge (ASRock 939Dual-SATA2 Motherboard)
 
 pci:v000010B9d00001573*
  ID_MODEL_FROM_DATABASE=PCI to LPC Controller
@@ -19638,22 +20121,22 @@ pci:v000010B9d00005229*
  ID_MODEL_FROM_DATABASE=M5229 IDE
 
 pci:v000010B9d00005229sv00001014sd0000050F*
- ID_MODEL_FROM_DATABASE=ThinkPad R30
+ ID_MODEL_FROM_DATABASE=M5229 IDE (ThinkPad R30)
 
 pci:v000010B9d00005229sv00001014sd0000053D*
- ID_MODEL_FROM_DATABASE=ThinkPad R40e
+ ID_MODEL_FROM_DATABASE=M5229 IDE (ThinkPad R40e)
 
 pci:v000010B9d00005229sv0000103Csd00000024*
- ID_MODEL_FROM_DATABASE=Pavilion ze4400 builtin IDE
+ ID_MODEL_FROM_DATABASE=M5229 IDE (Pavilion ze4400 builtin IDE)
 
 pci:v000010B9d00005229sv0000103Csd00000025*
- ID_MODEL_FROM_DATABASE=XE4500 Notebook
+ ID_MODEL_FROM_DATABASE=M5229 IDE (XE4500 Notebook)
 
 pci:v000010B9d00005229sv00001043sd00008053*
- ID_MODEL_FROM_DATABASE=A7A266 Motherboard IDE
+ ID_MODEL_FROM_DATABASE=M5229 IDE (A7A266 Motherboard IDE)
 
 pci:v000010B9d00005229sv00001849sd00005229*
- ID_MODEL_FROM_DATABASE=ASRock 939Dual-SATA2 Motherboard IDE (PATA)
+ ID_MODEL_FROM_DATABASE=M5229 IDE (ASRock 939Dual-SATA2 Motherboard IDE (PATA))
 
 pci:v000010B9d00005235*
  ID_MODEL_FROM_DATABASE=M5225
@@ -19662,31 +20145,31 @@ pci:v000010B9d00005237*
  ID_MODEL_FROM_DATABASE=USB 1.1 Controller
 
 pci:v000010B9d00005237sv00001014sd00000540*
- ID_MODEL_FROM_DATABASE=ThinkPad R40e
+ ID_MODEL_FROM_DATABASE=USB 1.1 Controller (ThinkPad R40e)
 
 pci:v000010B9d00005237sv0000103Csd00000024*
- ID_MODEL_FROM_DATABASE=Pavilion ze4400 builtin USB
+ ID_MODEL_FROM_DATABASE=USB 1.1 Controller (Pavilion ze4400 builtin USB)
 
 pci:v000010B9d00005237sv0000103Csd00000025*
- ID_MODEL_FROM_DATABASE=XE4500 Notebook
+ ID_MODEL_FROM_DATABASE=USB 1.1 Controller (XE4500 Notebook)
 
 pci:v000010B9d00005237sv0000104Dsd0000810F*
- ID_MODEL_FROM_DATABASE=VAIO PCG-U1 USB/OHCI Revision 1.0
+ ID_MODEL_FROM_DATABASE=USB 1.1 Controller (VAIO PCG-U1 USB/OHCI Revision 1.0)
 
 pci:v000010B9d00005237sv000010B9sd00005237*
- ID_MODEL_FROM_DATABASE=ASRock 939Dual-SATA2 Motherboard
+ ID_MODEL_FROM_DATABASE=USB 1.1 Controller (ASRock 939Dual-SATA2 Motherboard)
 
 pci:v000010B9d00005237sv00001849sd00005237*
- ID_MODEL_FROM_DATABASE=ASRock 939Dual-SATA2 Motherboard
+ ID_MODEL_FROM_DATABASE=USB 1.1 Controller (ASRock 939Dual-SATA2 Motherboard)
 
 pci:v000010B9d00005239*
  ID_MODEL_FROM_DATABASE=USB 2.0 Controller
 
 pci:v000010B9d00005239sv000010B9sd00005239*
- ID_MODEL_FROM_DATABASE=ASRock 939Dual-SATA2 Motherboard
+ ID_MODEL_FROM_DATABASE=USB 2.0 Controller (ASRock 939Dual-SATA2 Motherboard)
 
 pci:v000010B9d00005239sv00001849sd00005239*
- ID_MODEL_FROM_DATABASE=ASRock 939Dual-SATA2 Motherboard
+ ID_MODEL_FROM_DATABASE=USB 2.0 Controller (ASRock 939Dual-SATA2 Motherboard)
 
 pci:v000010B9d00005243*
  ID_MODEL_FROM_DATABASE=M1541 PCI to AGP Controller
@@ -19734,7 +20217,7 @@ pci:v000010B9d00005288*
  ID_MODEL_FROM_DATABASE=ULi M5288 SATA
 
 pci:v000010B9d00005288sv00001043sd00008056*
- ID_MODEL_FROM_DATABASE=A8R-MVP Mainboard
+ ID_MODEL_FROM_DATABASE=ULi M5288 SATA (A8R-MVP Mainboard)
 
 pci:v000010B9d00005289*
  ID_MODEL_FROM_DATABASE=ULi 5289 SATA
@@ -19746,16 +20229,16 @@ pci:v000010B9d00005451*
  ID_MODEL_FROM_DATABASE=M5451 PCI AC-Link Controller Audio Device
 
 pci:v000010B9d00005451sv00001014sd00000506*
- ID_MODEL_FROM_DATABASE=ThinkPad R30
+ ID_MODEL_FROM_DATABASE=M5451 PCI AC-Link Controller Audio Device (ThinkPad R30)
 
 pci:v000010B9d00005451sv00001014sd0000053E*
- ID_MODEL_FROM_DATABASE=ThinkPad R40e
+ ID_MODEL_FROM_DATABASE=M5451 PCI AC-Link Controller Audio Device (ThinkPad R40e)
 
 pci:v000010B9d00005451sv0000103Csd00000024*
- ID_MODEL_FROM_DATABASE=Pavilion ze4400 builtin Audio
+ ID_MODEL_FROM_DATABASE=M5451 PCI AC-Link Controller Audio Device (Pavilion ze4400 builtin Audio)
 
 pci:v000010B9d00005451sv0000103Csd00000025*
- ID_MODEL_FROM_DATABASE=XE4500 Notebook
+ ID_MODEL_FROM_DATABASE=M5451 PCI AC-Link Controller Audio Device (XE4500 Notebook)
 
 pci:v000010B9d00005453*
  ID_MODEL_FROM_DATABASE=M5453 PCI AC-Link Controller Modem Device
@@ -19764,22 +20247,22 @@ pci:v000010B9d00005455*
  ID_MODEL_FROM_DATABASE=M5455 PCI AC-Link Controller Audio Device
 
 pci:v000010B9d00005455sv000010B9sd00005455*
- ID_MODEL_FROM_DATABASE=ASRock 939Dual-SATA2 Motherboard
+ ID_MODEL_FROM_DATABASE=M5455 PCI AC-Link Controller Audio Device (ASRock 939Dual-SATA2 Motherboard)
 
 pci:v000010B9d00005455sv00001849sd00000850*
- ID_MODEL_FROM_DATABASE=ASRock 939Dual-SATA2 Motherboard
+ ID_MODEL_FROM_DATABASE=M5455 PCI AC-Link Controller Audio Device (ASRock 939Dual-SATA2 Motherboard)
 
 pci:v000010B9d00005457*
  ID_MODEL_FROM_DATABASE=M5457 AC'97 Modem Controller
 
 pci:v000010B9d00005457sv00001014sd00000535*
- ID_MODEL_FROM_DATABASE=ThinkPad R40e
+ ID_MODEL_FROM_DATABASE=M5457 AC'97 Modem Controller (ThinkPad R40e)
 
 pci:v000010B9d00005457sv0000103Csd00000024*
- ID_MODEL_FROM_DATABASE=Pavilion ze4400 builtin Modem Device
+ ID_MODEL_FROM_DATABASE=M5457 AC'97 Modem Controller (Pavilion ze4400 builtin Modem Device)
 
 pci:v000010B9d00005457sv0000103Csd00000025*
- ID_MODEL_FROM_DATABASE=XE4500 Notebook
+ ID_MODEL_FROM_DATABASE=M5457 AC'97 Modem Controller (XE4500 Notebook)
 
 pci:v000010B9d00005459*
  ID_MODEL_FROM_DATABASE=SmartLink SmartPCI561 56K Modem
@@ -19800,19 +20283,19 @@ pci:v000010B9d00007101*
  ID_MODEL_FROM_DATABASE=M7101 Power Management Controller [PMU]
 
 pci:v000010B9d00007101sv00001014sd00000510*
- ID_MODEL_FROM_DATABASE=ThinkPad R30
+ ID_MODEL_FROM_DATABASE=M7101 Power Management Controller [PMU] (ThinkPad R30)
 
 pci:v000010B9d00007101sv00001014sd0000053C*
- ID_MODEL_FROM_DATABASE=ThinkPad R40e
+ ID_MODEL_FROM_DATABASE=M7101 Power Management Controller [PMU] (ThinkPad R40e)
 
 pci:v000010B9d00007101sv0000103Csd00000024*
- ID_MODEL_FROM_DATABASE=Pavilion ze4400
+ ID_MODEL_FROM_DATABASE=M7101 Power Management Controller [PMU] (Pavilion ze4400)
 
 pci:v000010B9d00007101sv0000103Csd00000025*
- ID_MODEL_FROM_DATABASE=XE4500 Notebook
+ ID_MODEL_FROM_DATABASE=M7101 Power Management Controller [PMU] (XE4500 Notebook)
 
 pci:v000010B9d00007101sv00001849sd00007101*
- ID_MODEL_FROM_DATABASE=ASRock 939Dual-SATA2 Motherboard
+ ID_MODEL_FROM_DATABASE=M7101 Power Management Controller [PMU] (ASRock 939Dual-SATA2 Motherboard)
 
 pci:v000010BA*
  ID_VENDOR_FROM_DATABASE=Mitsubishi Electric Corp.
@@ -19827,7 +20310,7 @@ pci:v000010BAd00000308*
  ID_MODEL_FROM_DATABASE=Tornado 3000 [OEM Evans & Sutherland]
 
 pci:v000010BAd00000308sv000010DDsd00000024*
- ID_MODEL_FROM_DATABASE=Tornado 3000
+ ID_MODEL_FROM_DATABASE=Tornado 3000 [OEM Evans & Sutherland] (Tornado 3000)
 
 pci:v000010BAd00001002*
  ID_MODEL_FROM_DATABASE=VG500 [VolumePro Volume Rendering Accelerator]
@@ -19890,79 +20373,79 @@ pci:v000010C8d00000004*
  ID_MODEL_FROM_DATABASE=NM2160 [MagicGraph 128XD]
 
 pci:v000010C8d00000004sv00001014sd000000BA*
- ID_MODEL_FROM_DATABASE=MagicGraph 128XD
+ ID_MODEL_FROM_DATABASE=NM2160 [MagicGraph 128XD] (MagicGraph 128XD)
 
 pci:v000010C8d00000004sv00001025sd00001007*
- ID_MODEL_FROM_DATABASE=MagicGraph 128XD
+ ID_MODEL_FROM_DATABASE=NM2160 [MagicGraph 128XD] (MagicGraph 128XD)
 
 pci:v000010C8d00000004sv00001028sd00000074*
- ID_MODEL_FROM_DATABASE=MagicGraph 128XD
+ ID_MODEL_FROM_DATABASE=NM2160 [MagicGraph 128XD] (MagicGraph 128XD)
 
 pci:v000010C8d00000004sv00001028sd00000075*
- ID_MODEL_FROM_DATABASE=MagicGraph 128XD
+ ID_MODEL_FROM_DATABASE=NM2160 [MagicGraph 128XD] (MagicGraph 128XD)
 
 pci:v000010C8d00000004sv00001028sd0000007D*
- ID_MODEL_FROM_DATABASE=MagicGraph 128XD
+ ID_MODEL_FROM_DATABASE=NM2160 [MagicGraph 128XD] (MagicGraph 128XD)
 
 pci:v000010C8d00000004sv00001028sd0000007E*
- ID_MODEL_FROM_DATABASE=MagicGraph 128XD
+ ID_MODEL_FROM_DATABASE=NM2160 [MagicGraph 128XD] (MagicGraph 128XD)
 
 pci:v000010C8d00000004sv00001033sd0000802F*
- ID_MODEL_FROM_DATABASE=MagicGraph 128XD
+ ID_MODEL_FROM_DATABASE=NM2160 [MagicGraph 128XD] (MagicGraph 128XD)
 
 pci:v000010C8d00000004sv0000104Dsd0000801B*
- ID_MODEL_FROM_DATABASE=MagicGraph 128XD
+ ID_MODEL_FROM_DATABASE=NM2160 [MagicGraph 128XD] (MagicGraph 128XD)
 
 pci:v000010C8d00000004sv0000104Dsd0000802F*
- ID_MODEL_FROM_DATABASE=MagicGraph 128XD
+ ID_MODEL_FROM_DATABASE=NM2160 [MagicGraph 128XD] (MagicGraph 128XD)
 
 pci:v000010C8d00000004sv0000104Dsd0000830B*
- ID_MODEL_FROM_DATABASE=MagicGraph 128XD
+ ID_MODEL_FROM_DATABASE=NM2160 [MagicGraph 128XD] (MagicGraph 128XD)
 
 pci:v000010C8d00000004sv000010BAsd00000E00*
- ID_MODEL_FROM_DATABASE=MagicGraph 128XD
+ ID_MODEL_FROM_DATABASE=NM2160 [MagicGraph 128XD] (MagicGraph 128XD)
 
 pci:v000010C8d00000004sv000010C8sd00000004*
- ID_MODEL_FROM_DATABASE=MagicGraph 128XD
+ ID_MODEL_FROM_DATABASE=NM2160 [MagicGraph 128XD] (MagicGraph 128XD)
 
 pci:v000010C8d00000004sv000010CFsd00001029*
- ID_MODEL_FROM_DATABASE=MagicGraph 128XD
+ ID_MODEL_FROM_DATABASE=NM2160 [MagicGraph 128XD] (MagicGraph 128XD)
 
 pci:v000010C8d00000004sv000010F7sd00008308*
- ID_MODEL_FROM_DATABASE=MagicGraph 128XD
+ ID_MODEL_FROM_DATABASE=NM2160 [MagicGraph 128XD] (MagicGraph 128XD)
 
 pci:v000010C8d00000004sv000010F7sd00008309*
- ID_MODEL_FROM_DATABASE=MagicGraph 128XD
+ ID_MODEL_FROM_DATABASE=NM2160 [MagicGraph 128XD] (MagicGraph 128XD)
 
 pci:v000010C8d00000004sv000010F7sd0000830B*
- ID_MODEL_FROM_DATABASE=MagicGraph 128XD
+ ID_MODEL_FROM_DATABASE=NM2160 [MagicGraph 128XD] (MagicGraph 128XD)
 
 pci:v000010C8d00000004sv000010F7sd0000830D*
- ID_MODEL_FROM_DATABASE=MagicGraph 128XD
+ ID_MODEL_FROM_DATABASE=NM2160 [MagicGraph 128XD] (MagicGraph 128XD)
 
 pci:v000010C8d00000004sv000010F7sd00008312*
- ID_MODEL_FROM_DATABASE=MagicGraph 128XD
+ ID_MODEL_FROM_DATABASE=NM2160 [MagicGraph 128XD] (MagicGraph 128XD)
 
 pci:v000010C8d00000005*
  ID_MODEL_FROM_DATABASE=NM2200 [MagicGraph 256AV]
 
 pci:v000010C8d00000005sv00001014sd000000DD*
- ID_MODEL_FROM_DATABASE=ThinkPad 570
+ ID_MODEL_FROM_DATABASE=NM2200 [MagicGraph 256AV] (ThinkPad 570)
 
 pci:v000010C8d00000005sv00001028sd00000088*
- ID_MODEL_FROM_DATABASE=Latitude CPi A
+ ID_MODEL_FROM_DATABASE=NM2200 [MagicGraph 256AV] (Latitude CPi A)
 
 pci:v000010C8d00000006*
  ID_MODEL_FROM_DATABASE=NM2360 [MagicMedia 256ZX]
 
 pci:v000010C8d00000006sv00001014sd00000152*
- ID_MODEL_FROM_DATABASE=ThinkPad 600X
+ ID_MODEL_FROM_DATABASE=NM2360 [MagicMedia 256ZX] (ThinkPad 600X)
 
 pci:v000010C8d00000016*
  ID_MODEL_FROM_DATABASE=NM2380 [MagicMedia 256XL+]
 
 pci:v000010C8d00000016sv000010C8sd00000016*
- ID_MODEL_FROM_DATABASE=MagicMedia 256XL+
+ ID_MODEL_FROM_DATABASE=NM2380 [MagicMedia 256XL+] (MagicMedia 256XL+)
 
 pci:v000010C8d00000025*
  ID_MODEL_FROM_DATABASE=NM2230 [MagicGraph 256AV+]
@@ -19974,40 +20457,40 @@ pci:v000010C8d00008005*
  ID_MODEL_FROM_DATABASE=NM2200 [MagicMedia 256AV Audio]
 
 pci:v000010C8d00008005sv00000E11sd0000B0D1*
- ID_MODEL_FROM_DATABASE=MagicMedia 256AV Audio Device on Discovery
+ ID_MODEL_FROM_DATABASE=NM2200 [MagicMedia 256AV Audio] (MagicMedia 256AV Audio Device on Discovery)
 
 pci:v000010C8d00008005sv00000E11sd0000B126*
- ID_MODEL_FROM_DATABASE=MagicMedia 256AV Audio Device on Durango
+ ID_MODEL_FROM_DATABASE=NM2200 [MagicMedia 256AV Audio] (MagicMedia 256AV Audio Device on Durango)
 
 pci:v000010C8d00008005sv00001014sd000000DD*
- ID_MODEL_FROM_DATABASE=ThinkPad 390/i1720/i1721
+ ID_MODEL_FROM_DATABASE=NM2200 [MagicMedia 256AV Audio] (ThinkPad 390/i1720/i1721)
 
 pci:v000010C8d00008005sv00001025sd00001003*
- ID_MODEL_FROM_DATABASE=MagicMedia 256AV Audio Device on TravelMate 720
+ ID_MODEL_FROM_DATABASE=NM2200 [MagicMedia 256AV Audio] (MagicMedia 256AV Audio Device on TravelMate 720)
 
 pci:v000010C8d00008005sv00001028sd00000088*
- ID_MODEL_FROM_DATABASE=Latitude CPi A
+ ID_MODEL_FROM_DATABASE=NM2200 [MagicMedia 256AV Audio] (Latitude CPi A)
 
 pci:v000010C8d00008005sv00001028sd0000008F*
- ID_MODEL_FROM_DATABASE=MagicMedia 256AV Audio Device on Colorado Inspiron
+ ID_MODEL_FROM_DATABASE=NM2200 [MagicMedia 256AV Audio] (MagicMedia 256AV Audio Device on Colorado Inspiron)
 
 pci:v000010C8d00008005sv0000103Csd00000007*
- ID_MODEL_FROM_DATABASE=MagicMedia 256AV Audio Device on Voyager II
+ ID_MODEL_FROM_DATABASE=NM2200 [MagicMedia 256AV Audio] (MagicMedia 256AV Audio Device on Voyager II)
 
 pci:v000010C8d00008005sv0000103Csd00000008*
- ID_MODEL_FROM_DATABASE=MagicMedia 256AV Audio Device on Voyager III
+ ID_MODEL_FROM_DATABASE=NM2200 [MagicMedia 256AV Audio] (MagicMedia 256AV Audio Device on Voyager III)
 
 pci:v000010C8d00008005sv0000103Csd0000000D*
- ID_MODEL_FROM_DATABASE=MagicMedia 256AV Audio Device on Omnibook 900
+ ID_MODEL_FROM_DATABASE=NM2200 [MagicMedia 256AV Audio] (MagicMedia 256AV Audio Device on Omnibook 900)
 
 pci:v000010C8d00008005sv000010C8sd00008005*
- ID_MODEL_FROM_DATABASE=MagicMedia 256AV Audio Device on FireAnt
+ ID_MODEL_FROM_DATABASE=NM2200 [MagicMedia 256AV Audio] (MagicMedia 256AV Audio Device on FireAnt)
 
 pci:v000010C8d00008005sv0000110Asd00008005*
- ID_MODEL_FROM_DATABASE=MagicMedia 256AV Audio Device
+ ID_MODEL_FROM_DATABASE=NM2200 [MagicMedia 256AV Audio] (MagicMedia 256AV Audio Device)
 
 pci:v000010C8d00008005sv000014C0sd00000004*
- ID_MODEL_FROM_DATABASE=MagicMedia 256AV Audio Device
+ ID_MODEL_FROM_DATABASE=NM2200 [MagicMedia 256AV Audio] (MagicMedia 256AV Audio Device)
 
 pci:v000010C8d00008006*
  ID_MODEL_FROM_DATABASE=NM2360 [MagicMedia 256ZX Audio]
@@ -20046,10 +20529,10 @@ pci:v000010CDd00001300*
  ID_MODEL_FROM_DATABASE=ABP940-U / ABP960-U
 
 pci:v000010CDd00001300sv000010CDsd00001310*
- ID_MODEL_FROM_DATABASE=ASC1300 SCSI Adapter
+ ID_MODEL_FROM_DATABASE=ABP940-U / ABP960-U (ASC1300 SCSI Adapter)
 
 pci:v000010CDd00001300sv00001195sd00001320*
- ID_MODEL_FROM_DATABASE=Ultra-SCSI CardBus PC Card REX CB31
+ ID_MODEL_FROM_DATABASE=ABP940-U / ABP960-U (Ultra-SCSI CardBus PC Card REX CB31)
 
 pci:v000010CDd00002300*
  ID_MODEL_FROM_DATABASE=ABP940-UW
@@ -20142,7 +20625,7 @@ pci:v000010D9d00000531*
  ID_MODEL_FROM_DATABASE=MX987x5
 
 pci:v000010D9d00000531sv00001186sd00001200*
- ID_MODEL_FROM_DATABASE=DFE-540TX ProFAST 10/100 Adapter
+ ID_MODEL_FROM_DATABASE=MX987x5 (DFE-540TX ProFAST 10/100 Adapter)
 
 pci:v000010D9d00008625*
  ID_MODEL_FROM_DATABASE=MX86250
@@ -20190,7 +20673,7 @@ pci:v000010DDd00000100*
  ID_MODEL_FROM_DATABASE=Lightning 1200
 
 pci:v000010DDd00000100sv000010DDsd00000023*
- ID_MODEL_FROM_DATABASE=Lightning 1200 15+16M
+ ID_MODEL_FROM_DATABASE=Lightning 1200 (15+16M)
 
 pci:v000010DE*
  ID_VENDOR_FROM_DATABASE=NVIDIA Corporation
@@ -20205,193 +20688,193 @@ pci:v000010DEd00000020*
  ID_MODEL_FROM_DATABASE=NV4 [Riva TNT]
 
 pci:v000010DEd00000020sv00001043sd00000200*
- ID_MODEL_FROM_DATABASE=V3400 TNT
+ ID_MODEL_FROM_DATABASE=NV4 [Riva TNT] (V3400 TNT)
 
 pci:v000010DEd00000020sv00001048sd00000C18*
- ID_MODEL_FROM_DATABASE=Erazor II SGRAM
+ ID_MODEL_FROM_DATABASE=NV4 [Riva TNT] (Erazor II SGRAM)
 
 pci:v000010DEd00000020sv00001048sd00000C19*
- ID_MODEL_FROM_DATABASE=Erazor II
+ ID_MODEL_FROM_DATABASE=NV4 [Riva TNT] (Erazor II)
 
 pci:v000010DEd00000020sv00001048sd00000C1B*
- ID_MODEL_FROM_DATABASE=Erazor II
+ ID_MODEL_FROM_DATABASE=NV4 [Riva TNT] (Erazor II)
 
 pci:v000010DEd00000020sv00001048sd00000C1C*
- ID_MODEL_FROM_DATABASE=Erazor II
+ ID_MODEL_FROM_DATABASE=NV4 [Riva TNT] (Erazor II)
 
 pci:v000010DEd00000020sv00001092sd00000550*
- ID_MODEL_FROM_DATABASE=Viper V550
+ ID_MODEL_FROM_DATABASE=NV4 [Riva TNT] (Viper V550)
 
 pci:v000010DEd00000020sv00001092sd00000552*
- ID_MODEL_FROM_DATABASE=Viper V550
+ ID_MODEL_FROM_DATABASE=NV4 [Riva TNT] (Viper V550)
 
 pci:v000010DEd00000020sv00001092sd00004804*
- ID_MODEL_FROM_DATABASE=Viper V550
+ ID_MODEL_FROM_DATABASE=NV4 [Riva TNT] (Viper V550)
 
 pci:v000010DEd00000020sv00001092sd00004808*
- ID_MODEL_FROM_DATABASE=Viper V550
+ ID_MODEL_FROM_DATABASE=NV4 [Riva TNT] (Viper V550)
 
 pci:v000010DEd00000020sv00001092sd00004810*
- ID_MODEL_FROM_DATABASE=Viper V550
+ ID_MODEL_FROM_DATABASE=NV4 [Riva TNT] (Viper V550)
 
 pci:v000010DEd00000020sv00001092sd00004812*
- ID_MODEL_FROM_DATABASE=Viper V550
+ ID_MODEL_FROM_DATABASE=NV4 [Riva TNT] (Viper V550)
 
 pci:v000010DEd00000020sv00001092sd00004815*
- ID_MODEL_FROM_DATABASE=Viper V550
+ ID_MODEL_FROM_DATABASE=NV4 [Riva TNT] (Viper V550)
 
 pci:v000010DEd00000020sv00001092sd00004820*
- ID_MODEL_FROM_DATABASE=Viper V550 with TV out
+ ID_MODEL_FROM_DATABASE=NV4 [Riva TNT] (Viper V550 with TV out)
 
 pci:v000010DEd00000020sv00001092sd00004822*
- ID_MODEL_FROM_DATABASE=Viper V550
+ ID_MODEL_FROM_DATABASE=NV4 [Riva TNT] (Viper V550)
 
 pci:v000010DEd00000020sv00001092sd00004904*
- ID_MODEL_FROM_DATABASE=Viper V550
+ ID_MODEL_FROM_DATABASE=NV4 [Riva TNT] (Viper V550)
 
 pci:v000010DEd00000020sv00001092sd00004914*
- ID_MODEL_FROM_DATABASE=Viper V550
+ ID_MODEL_FROM_DATABASE=NV4 [Riva TNT] (Viper V550)
 
 pci:v000010DEd00000020sv00001092sd00008225*
- ID_MODEL_FROM_DATABASE=Viper V550
+ ID_MODEL_FROM_DATABASE=NV4 [Riva TNT] (Viper V550)
 
 pci:v000010DEd00000020sv000010B4sd0000273D*
- ID_MODEL_FROM_DATABASE=Velocity 4400
+ ID_MODEL_FROM_DATABASE=NV4 [Riva TNT] (Velocity 4400)
 
 pci:v000010DEd00000020sv000010B4sd0000273E*
- ID_MODEL_FROM_DATABASE=Velocity 4400
+ ID_MODEL_FROM_DATABASE=NV4 [Riva TNT] (Velocity 4400)
 
 pci:v000010DEd00000020sv000010B4sd00002740*
- ID_MODEL_FROM_DATABASE=Velocity 4400
+ ID_MODEL_FROM_DATABASE=NV4 [Riva TNT] (Velocity 4400)
 
 pci:v000010DEd00000020sv000010DEsd00000020*
- ID_MODEL_FROM_DATABASE=Riva TNT
+ ID_MODEL_FROM_DATABASE=NV4 [Riva TNT] (Riva TNT)
 
 pci:v000010DEd00000020sv00001102sd00001015*
- ID_MODEL_FROM_DATABASE=Graphics Blaster CT6710
+ ID_MODEL_FROM_DATABASE=NV4 [Riva TNT] (Graphics Blaster CT6710)
 
 pci:v000010DEd00000020sv00001102sd00001016*
- ID_MODEL_FROM_DATABASE=Graphics Blaster RIVA TNT
+ ID_MODEL_FROM_DATABASE=NV4 [Riva TNT] (Graphics Blaster RIVA TNT)
 
 pci:v000010DEd00000028*
  ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 / TNT2 Pro]
 
 pci:v000010DEd00000028sv00001043sd00000200*
- ID_MODEL_FROM_DATABASE=AGP-V3800 SGRAM
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 / TNT2 Pro] (AGP-V3800 SGRAM)
 
 pci:v000010DEd00000028sv00001043sd00000201*
- ID_MODEL_FROM_DATABASE=AGP-V3800 SDRAM
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 / TNT2 Pro] (AGP-V3800 SDRAM)
 
 pci:v000010DEd00000028sv00001043sd00000205*
- ID_MODEL_FROM_DATABASE=PCI-V3800
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 / TNT2 Pro] (PCI-V3800)
 
 pci:v000010DEd00000028sv00001043sd00004000*
- ID_MODEL_FROM_DATABASE=AGP-V3800PRO
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 / TNT2 Pro] (AGP-V3800PRO)
 
 pci:v000010DEd00000028sv00001048sd00000C21*
- ID_MODEL_FROM_DATABASE=Synergy II
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 / TNT2 Pro] (Synergy II)
 
 pci:v000010DEd00000028sv00001048sd00000C28*
- ID_MODEL_FROM_DATABASE=Erazor III
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 / TNT2 Pro] (Erazor III)
 
 pci:v000010DEd00000028sv00001048sd00000C29*
- ID_MODEL_FROM_DATABASE=Erazor III
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 / TNT2 Pro] (Erazor III)
 
 pci:v000010DEd00000028sv00001048sd00000C2A*
- ID_MODEL_FROM_DATABASE=Erazor III
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 / TNT2 Pro] (Erazor III)
 
 pci:v000010DEd00000028sv00001048sd00000C2B*
- ID_MODEL_FROM_DATABASE=Erazor III
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 / TNT2 Pro] (Erazor III)
 
 pci:v000010DEd00000028sv00001048sd00000C31*
- ID_MODEL_FROM_DATABASE=Erazor III Pro
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 / TNT2 Pro] (Erazor III Pro)
 
 pci:v000010DEd00000028sv00001048sd00000C32*
- ID_MODEL_FROM_DATABASE=Erazor III Pro
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 / TNT2 Pro] (Erazor III Pro)
 
 pci:v000010DEd00000028sv00001048sd00000C33*
- ID_MODEL_FROM_DATABASE=Erazor III Pro
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 / TNT2 Pro] (Erazor III Pro)
 
 pci:v000010DEd00000028sv00001048sd00000C34*
- ID_MODEL_FROM_DATABASE=Erazor III Pro
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 / TNT2 Pro] (Erazor III Pro)
 
 pci:v000010DEd00000028sv0000107Dsd00002134*
- ID_MODEL_FROM_DATABASE=WinFast 3D S320 II + TV-Out
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 / TNT2 Pro] (WinFast 3D S320 II + TV-Out)
 
 pci:v000010DEd00000028sv00001092sd00004804*
- ID_MODEL_FROM_DATABASE=Viper V770
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 / TNT2 Pro] (Viper V770)
 
 pci:v000010DEd00000028sv00001092sd00004A00*
- ID_MODEL_FROM_DATABASE=Viper V770
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 / TNT2 Pro] (Viper V770)
 
 pci:v000010DEd00000028sv00001092sd00004A02*
- ID_MODEL_FROM_DATABASE=Viper V770 Ultra
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 / TNT2 Pro] (Viper V770 Ultra)
 
 pci:v000010DEd00000028sv00001092sd00005A00*
- ID_MODEL_FROM_DATABASE=RIVA TNT2/TNT2 Pro
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 / TNT2 Pro] (RIVA TNT2/TNT2 Pro)
 
 pci:v000010DEd00000028sv00001092sd00005A40*
- ID_MODEL_FROM_DATABASE=Viper V770D AGP
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 / TNT2 Pro] (Viper V770D AGP)
 
 pci:v000010DEd00000028sv00001092sd00006A02*
- ID_MODEL_FROM_DATABASE=Viper V770 Ultra
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 / TNT2 Pro] (Viper V770 Ultra)
 
 pci:v000010DEd00000028sv00001092sd00007A02*
- ID_MODEL_FROM_DATABASE=Viper V770 Ultra
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 / TNT2 Pro] (Viper V770 Ultra)
 
 pci:v000010DEd00000028sv000010DEsd00000005*
- ID_MODEL_FROM_DATABASE=RIVA TNT2 Pro
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 / TNT2 Pro] (RIVA TNT2 Pro)
 
 pci:v000010DEd00000028sv000010DEsd0000000F*
- ID_MODEL_FROM_DATABASE=Compaq NVIDIA TNT2 Pro
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 / TNT2 Pro] (Compaq NVIDIA TNT2 Pro)
 
 pci:v000010DEd00000028sv00001102sd00001020*
- ID_MODEL_FROM_DATABASE=3D Blaster RIVA TNT2
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 / TNT2 Pro] (3D Blaster RIVA TNT2)
 
 pci:v000010DEd00000028sv00001102sd00001026*
- ID_MODEL_FROM_DATABASE=3D Blaster RIVA TNT2 Digital
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 / TNT2 Pro] (3D Blaster RIVA TNT2 Digital)
 
 pci:v000010DEd00000028sv00001462sd00008806*
- ID_MODEL_FROM_DATABASE=MS-8806 AGPhantom Graphics Card
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 / TNT2 Pro] (MS-8806 AGPhantom Graphics Card)
 
 pci:v000010DEd00000028sv000014AFsd00005810*
- ID_MODEL_FROM_DATABASE=Maxi Gamer Xentor
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 / TNT2 Pro] (Maxi Gamer Xentor)
 
 pci:v000010DEd00000029*
  ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 Ultra]
 
 pci:v000010DEd00000029sv00001043sd00000200*
- ID_MODEL_FROM_DATABASE=AGP-V3800 Deluxe
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 Ultra] (AGP-V3800 Deluxe)
 
 pci:v000010DEd00000029sv00001043sd00000201*
- ID_MODEL_FROM_DATABASE=AGP-V3800 Ultra SDRAM
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 Ultra] (AGP-V3800 Ultra SDRAM)
 
 pci:v000010DEd00000029sv00001043sd00000205*
- ID_MODEL_FROM_DATABASE=PCI-V3800 Ultra
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 Ultra] (PCI-V3800 Ultra)
 
 pci:v000010DEd00000029sv00001048sd00000C2E*
- ID_MODEL_FROM_DATABASE=Erazor III Ultra
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 Ultra] (Erazor III Ultra)
 
 pci:v000010DEd00000029sv00001048sd00000C2F*
- ID_MODEL_FROM_DATABASE=Erazor III Ultra
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 Ultra] (Erazor III Ultra)
 
 pci:v000010DEd00000029sv00001048sd00000C30*
- ID_MODEL_FROM_DATABASE=Erazor III Ultra
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 Ultra] (Erazor III Ultra)
 
 pci:v000010DEd00000029sv00001102sd00001021*
- ID_MODEL_FROM_DATABASE=3D Blaster RIVA TNT2 Ultra
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 Ultra] (3D Blaster RIVA TNT2 Ultra)
 
 pci:v000010DEd00000029sv00001102sd00001029*
- ID_MODEL_FROM_DATABASE=3D Blaster RIVA TNT2 Ultra
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 Ultra] (3D Blaster RIVA TNT2 Ultra)
 
 pci:v000010DEd00000029sv00001102sd0000102F*
- ID_MODEL_FROM_DATABASE=3D Blaster RIVA TNT2 Ultra
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 Ultra] (3D Blaster RIVA TNT2 Ultra)
 
 pci:v000010DEd00000029sv000014AFsd00005820*
- ID_MODEL_FROM_DATABASE=Maxi Gamer Xentor 32
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 Ultra] (Maxi Gamer Xentor 32)
 
 pci:v000010DEd00000029sv00004843sd00004F34*
- ID_MODEL_FROM_DATABASE=Dynamite
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 Ultra] (Dynamite)
 
 pci:v000010DEd0000002A*
  ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2]
@@ -20403,85 +20886,85 @@ pci:v000010DEd0000002C*
  ID_MODEL_FROM_DATABASE=NV5 [Vanta / Vanta LT]
 
 pci:v000010DEd0000002Csv00001043sd00000200*
- ID_MODEL_FROM_DATABASE=AGP-V3800 Combat SDRAM
+ ID_MODEL_FROM_DATABASE=NV5 [Vanta / Vanta LT] (AGP-V3800 Combat SDRAM)
 
 pci:v000010DEd0000002Csv00001043sd00000201*
- ID_MODEL_FROM_DATABASE=AGP-V3800 Combat
+ ID_MODEL_FROM_DATABASE=NV5 [Vanta / Vanta LT] (AGP-V3800 Combat)
 
 pci:v000010DEd0000002Csv00001048sd00000C20*
- ID_MODEL_FROM_DATABASE=TNT2 Vanta
+ ID_MODEL_FROM_DATABASE=NV5 [Vanta / Vanta LT] (TNT2 Vanta)
 
 pci:v000010DEd0000002Csv00001048sd00000C21*
- ID_MODEL_FROM_DATABASE=TNT2 Vanta
+ ID_MODEL_FROM_DATABASE=NV5 [Vanta / Vanta LT] (TNT2 Vanta)
 
 pci:v000010DEd0000002Csv00001048sd00000C25*
- ID_MODEL_FROM_DATABASE=TNT2 Vanta 16MB
+ ID_MODEL_FROM_DATABASE=NV5 [Vanta / Vanta LT] (TNT2 Vanta 16MB)
 
 pci:v000010DEd0000002Csv00001092sd00006820*
- ID_MODEL_FROM_DATABASE=Viper V730
+ ID_MODEL_FROM_DATABASE=NV5 [Vanta / Vanta LT] (Viper V730)
 
 pci:v000010DEd0000002Csv00001102sd00001031*
- ID_MODEL_FROM_DATABASE=CT6938 VANTA 8MB
+ ID_MODEL_FROM_DATABASE=NV5 [Vanta / Vanta LT] (CT6938 VANTA 8MB)
 
 pci:v000010DEd0000002Csv00001102sd00001034*
- ID_MODEL_FROM_DATABASE=CT6894 VANTA 16MB
+ ID_MODEL_FROM_DATABASE=NV5 [Vanta / Vanta LT] (CT6894 VANTA 16MB)
 
 pci:v000010DEd0000002Csv000014AFsd00005008*
- ID_MODEL_FROM_DATABASE=Maxi Gamer Phoenix 2
+ ID_MODEL_FROM_DATABASE=NV5 [Vanta / Vanta LT] (Maxi Gamer Phoenix 2)
 
 pci:v000010DEd0000002D*
  ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 Model 64 / Model 64 Pro]
 
 pci:v000010DEd0000002Dsv00001043sd00000200*
- ID_MODEL_FROM_DATABASE=AGP-V3800M
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 Model 64 / Model 64 Pro] (AGP-V3800M)
 
 pci:v000010DEd0000002Dsv00001043sd00000201*
- ID_MODEL_FROM_DATABASE=AGP-V3800M
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 Model 64 / Model 64 Pro] (AGP-V3800M)
 
 pci:v000010DEd0000002Dsv00001048sd00000C3A*
- ID_MODEL_FROM_DATABASE=Erazor III LT
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 Model 64 / Model 64 Pro] (Erazor III LT)
 
 pci:v000010DEd0000002Dsv00001048sd00000C3B*
- ID_MODEL_FROM_DATABASE=Erazor III LT
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 Model 64 / Model 64 Pro] (Erazor III LT)
 
 pci:v000010DEd0000002Dsv0000107Dsd00002137*
- ID_MODEL_FROM_DATABASE=WinFast 3D S325
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 Model 64 / Model 64 Pro] (WinFast 3D S325)
 
 pci:v000010DEd0000002Dsv000010DEsd00000006*
- ID_MODEL_FROM_DATABASE=RIVA TNT2 Model 64/Model 64 Pro
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 Model 64 / Model 64 Pro] (RIVA TNT2 Model 64/Model 64 Pro)
 
 pci:v000010DEd0000002Dsv000010DEsd0000001E*
- ID_MODEL_FROM_DATABASE=M64 AGP4x
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 Model 64 / Model 64 Pro] (M64 AGP4x)
 
 pci:v000010DEd0000002Dsv00001102sd00001023*
- ID_MODEL_FROM_DATABASE=CT6892 RIVA TNT2 Value
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 Model 64 / Model 64 Pro] (CT6892 RIVA TNT2 Value)
 
 pci:v000010DEd0000002Dsv00001102sd00001024*
- ID_MODEL_FROM_DATABASE=CT6932 RIVA TNT2 Value 32Mb
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 Model 64 / Model 64 Pro] (CT6932 RIVA TNT2 Value 32Mb)
 
 pci:v000010DEd0000002Dsv00001102sd0000102C*
- ID_MODEL_FROM_DATABASE=CT6931 RIVA TNT2 Value [Jumper]
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 Model 64 / Model 64 Pro] (CT6931 RIVA TNT2 Value [Jumper])
 
 pci:v000010DEd0000002Dsv00001102sd00001030*
- ID_MODEL_FROM_DATABASE=CT6931 RIVA TNT2 Value
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 Model 64 / Model 64 Pro] (CT6931 RIVA TNT2 Value)
 
 pci:v000010DEd0000002Dsv0000110Asd0000006F*
- ID_MODEL_FROM_DATABASE=GM1000-16
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 Model 64 / Model 64 Pro] (GM1000-16)
 
 pci:v000010DEd0000002Dsv0000110Asd00000081*
- ID_MODEL_FROM_DATABASE=GM1000-16
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 Model 64 / Model 64 Pro] (GM1000-16)
 
 pci:v000010DEd0000002Dsv00001462sd00008808*
- ID_MODEL_FROM_DATABASE=MSI-8808
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 Model 64 / Model 64 Pro] (MSI-8808)
 
 pci:v000010DEd0000002Dsv000014AFsd00005620*
- ID_MODEL_FROM_DATABASE=Gamer Cougar Video Edition
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 Model 64 / Model 64 Pro] (Gamer Cougar Video Edition)
 
 pci:v000010DEd0000002Dsv00001554sd00001041*
- ID_MODEL_FROM_DATABASE=Pixelview RIVA TNT2 M64
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 Model 64 / Model 64 Pro] (Pixelview RIVA TNT2 M64)
 
 pci:v000010DEd0000002Dsv00001569sd0000002D*
- ID_MODEL_FROM_DATABASE=Palit Microsystems Daytona TNT2 M64
+ ID_MODEL_FROM_DATABASE=NV5 [Riva TNT2 Model 64 / Model 64 Pro] (Palit Microsystems Daytona TNT2 M64)
 
 pci:v000010DEd00000034*
  ID_MODEL_FROM_DATABASE=MCP04 SMBus
@@ -20520,19 +21003,19 @@ pci:v000010DEd00000041*
  ID_MODEL_FROM_DATABASE=NV40 [GeForce 6800]
 
 pci:v000010DEd00000041sv00001043sd0000817B*
- ID_MODEL_FROM_DATABASE=V9999 Gamer Edition
+ ID_MODEL_FROM_DATABASE=NV40 [GeForce 6800] (V9999 Gamer Edition)
 
 pci:v000010DEd00000041sv0000107Dsd00002992*
- ID_MODEL_FROM_DATABASE=WinFast A400
+ ID_MODEL_FROM_DATABASE=NV40 [GeForce 6800] (WinFast A400)
 
 pci:v000010DEd00000041sv00001458sd0000310F*
- ID_MODEL_FROM_DATABASE=Geforce 6800 GV-N6812
+ ID_MODEL_FROM_DATABASE=NV40 [GeForce 6800] (Geforce 6800 GV-N6812)
 
 pci:v000010DEd00000042*
  ID_MODEL_FROM_DATABASE=NV40 [GeForce 6800 LE]
 
 pci:v000010DEd00000042sv0000107Dsd0000299B*
- ID_MODEL_FROM_DATABASE=WinFast A400 LE
+ ID_MODEL_FROM_DATABASE=NV40 [GeForce 6800 LE] (WinFast A400 LE)
 
 pci:v000010DEd00000043*
  ID_MODEL_FROM_DATABASE=NV40 [GeForce 6800 XE]
@@ -20544,16 +21027,16 @@ pci:v000010DEd00000045*
  ID_MODEL_FROM_DATABASE=NV40 [GeForce 6800 GT]
 
 pci:v000010DEd00000045sv00001043sd0000817D*
- ID_MODEL_FROM_DATABASE=V9999GT
+ ID_MODEL_FROM_DATABASE=NV40 [GeForce 6800 GT] (V9999GT)
 
 pci:v000010DEd00000045sv00001458sd00003140*
- ID_MODEL_FROM_DATABASE=GV-N68T256D
+ ID_MODEL_FROM_DATABASE=NV40 [GeForce 6800 GT] (GV-N68T256D)
 
 pci:v000010DEd00000047*
  ID_MODEL_FROM_DATABASE=NV40 [GeForce 6800 GS]
 
 pci:v000010DEd00000047sv00001682sd00002109*
- ID_MODEL_FROM_DATABASE=GeForce 6800 GS
+ ID_MODEL_FROM_DATABASE=NV40 [GeForce 6800 GS] (GeForce 6800 GS)
 
 pci:v000010DEd00000048*
  ID_MODEL_FROM_DATABASE=NV40 [GeForce 6800 XT]
@@ -20565,133 +21048,133 @@ pci:v000010DEd00000050*
  ID_MODEL_FROM_DATABASE=CK804 ISA Bridge
 
 pci:v000010DEd00000050sv00001043sd0000815A*
- ID_MODEL_FROM_DATABASE=K8N4/A8N Series Mainboard
+ ID_MODEL_FROM_DATABASE=CK804 ISA Bridge (K8N4/A8N Series Mainboard)
 
 pci:v000010DEd00000050sv000010F1sd00002865*
- ID_MODEL_FROM_DATABASE=Tomcat K8E (S2865)
+ ID_MODEL_FROM_DATABASE=CK804 ISA Bridge (Tomcat K8E (S2865))
 
 pci:v000010DEd00000050sv00001458sd00000C11*
- ID_MODEL_FROM_DATABASE=GA-K8N Ultra-9 Mainboard
+ ID_MODEL_FROM_DATABASE=CK804 ISA Bridge (GA-K8N Ultra-9 Mainboard)
 
 pci:v000010DEd00000050sv00001462sd00007100*
- ID_MODEL_FROM_DATABASE=MSI K8N Diamond
+ ID_MODEL_FROM_DATABASE=CK804 ISA Bridge (MSI K8N Diamond)
 
 pci:v000010DEd00000050sv00001462sd00007125*
- ID_MODEL_FROM_DATABASE=K8N Neo4-F mainboard
+ ID_MODEL_FROM_DATABASE=CK804 ISA Bridge (K8N Neo4-F mainboard)
 
 pci:v000010DEd00000050sv0000147Bsd00001C1A*
- ID_MODEL_FROM_DATABASE=KN8-Ultra Mainboard
+ ID_MODEL_FROM_DATABASE=CK804 ISA Bridge (KN8-Ultra Mainboard)
 
 pci:v000010DEd00000050sv00001565sd00003402*
- ID_MODEL_FROM_DATABASE=NF4 AM2L Mainboard
+ ID_MODEL_FROM_DATABASE=CK804 ISA Bridge (NF4 AM2L Mainboard)
 
 pci:v000010DEd00000051*
  ID_MODEL_FROM_DATABASE=CK804 ISA Bridge
 
 pci:v000010DEd00000051sv00001028sd00000225*
- ID_MODEL_FROM_DATABASE=PowerEdge T105 ISA Bridge
+ ID_MODEL_FROM_DATABASE=CK804 ISA Bridge (PowerEdge T105 ISA Bridge)
 
 pci:v000010DEd00000052*
  ID_MODEL_FROM_DATABASE=CK804 SMBus
 
 pci:v000010DEd00000052sv00001028sd00000225*
- ID_MODEL_FROM_DATABASE=PowerEdge T105 SMBus
+ ID_MODEL_FROM_DATABASE=CK804 SMBus (PowerEdge T105 SMBus)
 
 pci:v000010DEd00000052sv00001043sd0000815A*
- ID_MODEL_FROM_DATABASE=K8N4/A8N Series Mainboard
+ ID_MODEL_FROM_DATABASE=CK804 SMBus (K8N4/A8N Series Mainboard)
 
 pci:v000010DEd00000052sv000010F1sd00002865*
- ID_MODEL_FROM_DATABASE=Tomcat K8E (S2865)
+ ID_MODEL_FROM_DATABASE=CK804 SMBus (Tomcat K8E (S2865))
 
 pci:v000010DEd00000052sv00001458sd00000C11*
- ID_MODEL_FROM_DATABASE=GA-K8N Ultra-9 Mainboard
+ ID_MODEL_FROM_DATABASE=CK804 SMBus (GA-K8N Ultra-9 Mainboard)
 
 pci:v000010DEd00000052sv00001462sd00007100*
- ID_MODEL_FROM_DATABASE=MSI K8N Diamond
+ ID_MODEL_FROM_DATABASE=CK804 SMBus (MSI K8N Diamond)
 
 pci:v000010DEd00000052sv00001462sd00007125*
- ID_MODEL_FROM_DATABASE=K8N Neo4-F mainboard
+ ID_MODEL_FROM_DATABASE=CK804 SMBus (K8N Neo4-F mainboard)
 
 pci:v000010DEd00000052sv0000147Bsd00001C1A*
- ID_MODEL_FROM_DATABASE=KN8-Ultra Mainboard
+ ID_MODEL_FROM_DATABASE=CK804 SMBus (KN8-Ultra Mainboard)
 
 pci:v000010DEd00000052sv00001565sd00003402*
- ID_MODEL_FROM_DATABASE=NF4 AM2L Mainboard
+ ID_MODEL_FROM_DATABASE=CK804 SMBus (NF4 AM2L Mainboard)
 
 pci:v000010DEd00000053*
  ID_MODEL_FROM_DATABASE=CK804 IDE
 
 pci:v000010DEd00000053sv00001043sd0000815A*
- ID_MODEL_FROM_DATABASE=K8N4/A8N Series Mainboard
+ ID_MODEL_FROM_DATABASE=CK804 IDE (K8N4/A8N Series Mainboard)
 
 pci:v000010DEd00000053sv000010F1sd00002865*
- ID_MODEL_FROM_DATABASE=Tomcat K8E (S2865)
+ ID_MODEL_FROM_DATABASE=CK804 IDE (Tomcat K8E (S2865))
 
 pci:v000010DEd00000053sv00001458sd00005002*
- ID_MODEL_FROM_DATABASE=GA-K8N Ultra-9 Mainboard
+ ID_MODEL_FROM_DATABASE=CK804 IDE (GA-K8N Ultra-9 Mainboard)
 
 pci:v000010DEd00000053sv00001462sd00007100*
- ID_MODEL_FROM_DATABASE=MSI K8N Diamond
+ ID_MODEL_FROM_DATABASE=CK804 IDE (MSI K8N Diamond)
 
 pci:v000010DEd00000053sv00001462sd00007125*
- ID_MODEL_FROM_DATABASE=K8N Neo4-F mainboard
+ ID_MODEL_FROM_DATABASE=CK804 IDE (K8N Neo4-F mainboard)
 
 pci:v000010DEd00000053sv0000147Bsd00001C1A*
- ID_MODEL_FROM_DATABASE=KN8-Ultra Mainboard
+ ID_MODEL_FROM_DATABASE=CK804 IDE (KN8-Ultra Mainboard)
 
 pci:v000010DEd00000053sv00001565sd00003402*
- ID_MODEL_FROM_DATABASE=NF4 AM2L Mainboard
+ ID_MODEL_FROM_DATABASE=CK804 IDE (NF4 AM2L Mainboard)
 
 pci:v000010DEd00000054*
  ID_MODEL_FROM_DATABASE=CK804 Serial ATA Controller
 
 pci:v000010DEd00000054sv00001028sd00000225*
- ID_MODEL_FROM_DATABASE=PowerEdge T105 Serial ATA
+ ID_MODEL_FROM_DATABASE=CK804 Serial ATA Controller (PowerEdge T105 Serial ATA)
 
 pci:v000010DEd00000054sv00001043sd0000815A*
- ID_MODEL_FROM_DATABASE=A8N Series Mainboard
+ ID_MODEL_FROM_DATABASE=CK804 Serial ATA Controller (A8N Series Mainboard)
 
 pci:v000010DEd00000054sv000010F1sd00002865*
- ID_MODEL_FROM_DATABASE=Tomcat K8E (S2865)
+ ID_MODEL_FROM_DATABASE=CK804 Serial ATA Controller (Tomcat K8E (S2865))
 
 pci:v000010DEd00000054sv00001458sd0000B003*
- ID_MODEL_FROM_DATABASE=GA-K8N Ultra-9 Mainboard
+ ID_MODEL_FROM_DATABASE=CK804 Serial ATA Controller (GA-K8N Ultra-9 Mainboard)
 
 pci:v000010DEd00000054sv00001462sd00007100*
- ID_MODEL_FROM_DATABASE=MSI K8N Diamond
+ ID_MODEL_FROM_DATABASE=CK804 Serial ATA Controller (MSI K8N Diamond)
 
 pci:v000010DEd00000054sv00001462sd00007125*
- ID_MODEL_FROM_DATABASE=K8N Neo4-F mainboard
+ ID_MODEL_FROM_DATABASE=CK804 Serial ATA Controller (K8N Neo4-F mainboard)
 
 pci:v000010DEd00000054sv0000147Bsd00001C1A*
- ID_MODEL_FROM_DATABASE=KN8-Ultra Mainboard
+ ID_MODEL_FROM_DATABASE=CK804 Serial ATA Controller (KN8-Ultra Mainboard)
 
 pci:v000010DEd00000054sv00001565sd00005401*
- ID_MODEL_FROM_DATABASE=NF4 AM2L Mainboard
+ ID_MODEL_FROM_DATABASE=CK804 Serial ATA Controller (NF4 AM2L Mainboard)
 
 pci:v000010DEd00000055*
  ID_MODEL_FROM_DATABASE=CK804 Serial ATA Controller
 
 pci:v000010DEd00000055sv00001028sd00000225*
- ID_MODEL_FROM_DATABASE=PowerEdge T105 Serial ATA
+ ID_MODEL_FROM_DATABASE=CK804 Serial ATA Controller (PowerEdge T105 Serial ATA)
 
 pci:v000010DEd00000055sv00001043sd0000815A*
- ID_MODEL_FROM_DATABASE=K8N4/A8N Series Mainboard
+ ID_MODEL_FROM_DATABASE=CK804 Serial ATA Controller (K8N4/A8N Series Mainboard)
 
 pci:v000010DEd00000055sv000010F1sd00002865*
- ID_MODEL_FROM_DATABASE=Tomcat K8E (S2865)
+ ID_MODEL_FROM_DATABASE=CK804 Serial ATA Controller (Tomcat K8E (S2865))
 
 pci:v000010DEd00000055sv00001458sd0000B003*
- ID_MODEL_FROM_DATABASE=GA-K8N Ultra-9 Mainboard
+ ID_MODEL_FROM_DATABASE=CK804 Serial ATA Controller (GA-K8N Ultra-9 Mainboard)
 
 pci:v000010DEd00000055sv00001462sd00007125*
- ID_MODEL_FROM_DATABASE=K8N Neo4-F mainboard
+ ID_MODEL_FROM_DATABASE=CK804 Serial ATA Controller (K8N Neo4-F mainboard)
 
 pci:v000010DEd00000055sv0000147Bsd00001C1A*
- ID_MODEL_FROM_DATABASE=KN8-Ultra Mainboard
+ ID_MODEL_FROM_DATABASE=CK804 Serial ATA Controller (KN8-Ultra Mainboard)
 
 pci:v000010DEd00000055sv00001565sd00005401*
- ID_MODEL_FROM_DATABASE=NF4 AM2L Mainboard
+ ID_MODEL_FROM_DATABASE=CK804 Serial ATA Controller (NF4 AM2L Mainboard)
 
 pci:v000010DEd00000056*
  ID_MODEL_FROM_DATABASE=CK804 Ethernet Controller
@@ -20700,28 +21183,28 @@ pci:v000010DEd00000057*
  ID_MODEL_FROM_DATABASE=CK804 Ethernet Controller
 
 pci:v000010DEd00000057sv00001043sd00008141*
- ID_MODEL_FROM_DATABASE=K8N4/A8N Series Mainboard
+ ID_MODEL_FROM_DATABASE=CK804 Ethernet Controller (K8N4/A8N Series Mainboard)
 
 pci:v000010DEd00000057sv000010DEsd0000CB84*
- ID_MODEL_FROM_DATABASE=NF4 Lanparty
+ ID_MODEL_FROM_DATABASE=CK804 Ethernet Controller (NF4 Lanparty)
 
 pci:v000010DEd00000057sv000010F1sd00002865*
- ID_MODEL_FROM_DATABASE=Tomcat K8E (S2865)
+ ID_MODEL_FROM_DATABASE=CK804 Ethernet Controller (Tomcat K8E (S2865))
 
 pci:v000010DEd00000057sv00001458sd0000E000*
- ID_MODEL_FROM_DATABASE=GA-K8N Ultra-9 Mainboard
+ ID_MODEL_FROM_DATABASE=CK804 Ethernet Controller (GA-K8N Ultra-9 Mainboard)
 
 pci:v000010DEd00000057sv00001462sd00007100*
- ID_MODEL_FROM_DATABASE=MSI K8N Diamond
+ ID_MODEL_FROM_DATABASE=CK804 Ethernet Controller (MSI K8N Diamond)
 
 pci:v000010DEd00000057sv00001462sd00007125*
- ID_MODEL_FROM_DATABASE=K8N Neo4-F mainboard
+ ID_MODEL_FROM_DATABASE=CK804 Ethernet Controller (K8N Neo4-F mainboard)
 
 pci:v000010DEd00000057sv0000147Bsd00001C1A*
- ID_MODEL_FROM_DATABASE=KN8-Ultra Mainboard
+ ID_MODEL_FROM_DATABASE=CK804 Ethernet Controller (KN8-Ultra Mainboard)
 
 pci:v000010DEd00000057sv00001565sd00002501*
- ID_MODEL_FROM_DATABASE=NF4 AM2L Mainboard
+ ID_MODEL_FROM_DATABASE=CK804 Ethernet Controller (NF4 AM2L Mainboard)
 
 pci:v000010DEd00000058*
  ID_MODEL_FROM_DATABASE=CK804 AC'97 Modem
@@ -20730,73 +21213,73 @@ pci:v000010DEd00000059*
  ID_MODEL_FROM_DATABASE=CK804 AC'97 Audio Controller
 
 pci:v000010DEd00000059sv00001043sd0000812A*
- ID_MODEL_FROM_DATABASE=K8N4/A8N Series Mainboard
+ ID_MODEL_FROM_DATABASE=CK804 AC'97 Audio Controller (K8N4/A8N Series Mainboard)
 
 pci:v000010DEd00000059sv000010F1sd00002865*
- ID_MODEL_FROM_DATABASE=Tomcat K8E (S2865)
+ ID_MODEL_FROM_DATABASE=CK804 AC'97 Audio Controller (Tomcat K8E (S2865))
 
 pci:v000010DEd00000059sv00001462sd00007585*
- ID_MODEL_FROM_DATABASE=K8N Neo4-F mainboard
+ ID_MODEL_FROM_DATABASE=CK804 AC'97 Audio Controller (K8N Neo4-F mainboard)
 
 pci:v000010DEd00000059sv0000147Bsd00001C1A*
- ID_MODEL_FROM_DATABASE=KN8-Ultra Mainboard
+ ID_MODEL_FROM_DATABASE=CK804 AC'97 Audio Controller (KN8-Ultra Mainboard)
 
 pci:v000010DEd00000059sv00001565sd00008211*
- ID_MODEL_FROM_DATABASE=NF4 AM2L Mainboard
+ ID_MODEL_FROM_DATABASE=CK804 AC'97 Audio Controller (NF4 AM2L Mainboard)
 
 pci:v000010DEd0000005A*
  ID_MODEL_FROM_DATABASE=CK804 USB Controller
 
 pci:v000010DEd0000005Asv00001028sd00000225*
- ID_MODEL_FROM_DATABASE=PowerEdge T105 onboard USB
+ ID_MODEL_FROM_DATABASE=CK804 USB Controller (PowerEdge T105 onboard USB)
 
 pci:v000010DEd0000005Asv00001043sd0000815A*
- ID_MODEL_FROM_DATABASE=K8N4/A8N Series Mainboard
+ ID_MODEL_FROM_DATABASE=CK804 USB Controller (K8N4/A8N Series Mainboard)
 
 pci:v000010DEd0000005Asv000010F1sd00002865*
- ID_MODEL_FROM_DATABASE=Tomcat K8E (S2865)
+ ID_MODEL_FROM_DATABASE=CK804 USB Controller (Tomcat K8E (S2865))
 
 pci:v000010DEd0000005Asv00001458sd00005004*
- ID_MODEL_FROM_DATABASE=GA-K8N Ultra-9 Mainboard
+ ID_MODEL_FROM_DATABASE=CK804 USB Controller (GA-K8N Ultra-9 Mainboard)
 
 pci:v000010DEd0000005Asv00001462sd00007100*
- ID_MODEL_FROM_DATABASE=MSI K8N Diamond
+ ID_MODEL_FROM_DATABASE=CK804 USB Controller (MSI K8N Diamond)
 
 pci:v000010DEd0000005Asv00001462sd00007125*
- ID_MODEL_FROM_DATABASE=K8N Neo4-F mainboard
+ ID_MODEL_FROM_DATABASE=CK804 USB Controller (K8N Neo4-F mainboard)
 
 pci:v000010DEd0000005Asv0000147Bsd00001C1A*
- ID_MODEL_FROM_DATABASE=KN8-Ultra Mainboard
+ ID_MODEL_FROM_DATABASE=CK804 USB Controller (KN8-Ultra Mainboard)
 
 pci:v000010DEd0000005Asv00001565sd00003402*
- ID_MODEL_FROM_DATABASE=NF4 AM2L Mainboard
+ ID_MODEL_FROM_DATABASE=CK804 USB Controller (NF4 AM2L Mainboard)
 
 pci:v000010DEd0000005B*
  ID_MODEL_FROM_DATABASE=CK804 USB Controller
 
 pci:v000010DEd0000005Bsv00001028sd00000225*
- ID_MODEL_FROM_DATABASE=PowerEdge T105 onboard USB
+ ID_MODEL_FROM_DATABASE=CK804 USB Controller (PowerEdge T105 onboard USB)
 
 pci:v000010DEd0000005Bsv00001043sd0000815A*
- ID_MODEL_FROM_DATABASE=K8N4/A8N Series Mainboard
+ ID_MODEL_FROM_DATABASE=CK804 USB Controller (K8N4/A8N Series Mainboard)
 
 pci:v000010DEd0000005Bsv000010F1sd00002865*
- ID_MODEL_FROM_DATABASE=Tomcat K8E (S2865)
+ ID_MODEL_FROM_DATABASE=CK804 USB Controller (Tomcat K8E (S2865))
 
 pci:v000010DEd0000005Bsv00001458sd00005004*
- ID_MODEL_FROM_DATABASE=GA-K8N Ultra-9 Mainboard
+ ID_MODEL_FROM_DATABASE=CK804 USB Controller (GA-K8N Ultra-9 Mainboard)
 
 pci:v000010DEd0000005Bsv00001462sd00007100*
- ID_MODEL_FROM_DATABASE=MSI K8N Diamond
+ ID_MODEL_FROM_DATABASE=CK804 USB Controller (MSI K8N Diamond)
 
 pci:v000010DEd0000005Bsv00001462sd00007125*
- ID_MODEL_FROM_DATABASE=K8N Neo4-F mainboard
+ ID_MODEL_FROM_DATABASE=CK804 USB Controller (K8N Neo4-F mainboard)
 
 pci:v000010DEd0000005Bsv0000147Bsd00001C1A*
- ID_MODEL_FROM_DATABASE=KN8-Ultra Mainboard
+ ID_MODEL_FROM_DATABASE=CK804 USB Controller (KN8-Ultra Mainboard)
 
 pci:v000010DEd0000005Bsv00001565sd00003402*
- ID_MODEL_FROM_DATABASE=NF4 AM2L Mainboard
+ ID_MODEL_FROM_DATABASE=CK804 USB Controller (NF4 AM2L Mainboard)
 
 pci:v000010DEd0000005C*
  ID_MODEL_FROM_DATABASE=CK804 PCI Bridge
@@ -20808,34 +21291,34 @@ pci:v000010DEd0000005E*
  ID_MODEL_FROM_DATABASE=CK804 Memory Controller
 
 pci:v000010DEd0000005Esv00001028sd00000225*
- ID_MODEL_FROM_DATABASE=PowerEdge T105 Memory Controller
+ ID_MODEL_FROM_DATABASE=CK804 Memory Controller (PowerEdge T105 Memory Controller)
 
 pci:v000010DEd0000005Esv00001043sd0000815A*
- ID_MODEL_FROM_DATABASE=A8N Series Mainboard
+ ID_MODEL_FROM_DATABASE=CK804 Memory Controller (A8N Series Mainboard)
 
 pci:v000010DEd0000005Esv000010DEsd0000005E*
- ID_MODEL_FROM_DATABASE=ECS Elitegroup NFORCE3-A939 motherboard.
+ ID_MODEL_FROM_DATABASE=CK804 Memory Controller (ECS Elitegroup NFORCE3-A939 motherboard.)
 
 pci:v000010DEd0000005Esv000010F1sd00002865*
- ID_MODEL_FROM_DATABASE=Tomcat K8E (S2865)
+ ID_MODEL_FROM_DATABASE=CK804 Memory Controller (Tomcat K8E (S2865))
 
 pci:v000010DEd0000005Esv000010F1sd00002891*
- ID_MODEL_FROM_DATABASE=Thunder K8SRE Mainboard
+ ID_MODEL_FROM_DATABASE=CK804 Memory Controller (Thunder K8SRE Mainboard)
 
 pci:v000010DEd0000005Esv00001458sd00005000*
- ID_MODEL_FROM_DATABASE=GA-K8N Ultra-9 Mainboard
+ ID_MODEL_FROM_DATABASE=CK804 Memory Controller (GA-K8N Ultra-9 Mainboard)
 
 pci:v000010DEd0000005Esv00001462sd00007100*
- ID_MODEL_FROM_DATABASE=K8N Diamond Mainboard
+ ID_MODEL_FROM_DATABASE=CK804 Memory Controller (K8N Diamond Mainboard)
 
 pci:v000010DEd0000005Esv00001462sd00007125*
- ID_MODEL_FROM_DATABASE=K8N Neo4-F Mainboard
+ ID_MODEL_FROM_DATABASE=CK804 Memory Controller (K8N Neo4-F Mainboard)
 
 pci:v000010DEd0000005Esv0000147Bsd00001C1A*
- ID_MODEL_FROM_DATABASE=KN8-Ultra Mainboard
+ ID_MODEL_FROM_DATABASE=CK804 Memory Controller (KN8-Ultra Mainboard)
 
 pci:v000010DEd0000005Esv00001565sd00003402*
- ID_MODEL_FROM_DATABASE=NF4 AM2L Mainboard
+ ID_MODEL_FROM_DATABASE=CK804 Memory Controller (NF4 AM2L Mainboard)
 
 pci:v000010DEd0000005F*
  ID_MODEL_FROM_DATABASE=CK804 Memory Controller
@@ -20844,61 +21327,61 @@ pci:v000010DEd00000060*
  ID_MODEL_FROM_DATABASE=nForce2 ISA Bridge
 
 pci:v000010DEd00000060sv00001043sd000080AD*
- ID_MODEL_FROM_DATABASE=A7N8X Mainboard
+ ID_MODEL_FROM_DATABASE=nForce2 ISA Bridge (A7N8X Mainboard)
 
 pci:v000010DEd00000060sv0000147Bsd00001C02*
- ID_MODEL_FROM_DATABASE=NF7-S/NF7 (nVidia-nForce2) 2.X
+ ID_MODEL_FROM_DATABASE=nForce2 ISA Bridge (NF7-S/NF7 (nVidia-nForce2) 2.X)
 
 pci:v000010DEd00000060sv0000A0A0sd000003BA*
- ID_MODEL_FROM_DATABASE=UK79G-1394 motherboard
+ ID_MODEL_FROM_DATABASE=nForce2 ISA Bridge (UK79G-1394 motherboard)
 
 pci:v000010DEd00000064*
  ID_MODEL_FROM_DATABASE=nForce2 SMBus (MCP)
 
 pci:v000010DEd00000064sv0000147Bsd00001C02*
- ID_MODEL_FROM_DATABASE=NF7-S/NF7 (nVidia-nForce2) 2.X
+ ID_MODEL_FROM_DATABASE=nForce2 SMBus (MCP) (NF7-S/NF7 (nVidia-nForce2) 2.X)
 
 pci:v000010DEd00000064sv0000A0A0sd000003BB*
- ID_MODEL_FROM_DATABASE=UK79G-1394 motherboard
+ ID_MODEL_FROM_DATABASE=nForce2 SMBus (MCP) (UK79G-1394 motherboard)
 
 pci:v000010DEd00000065*
  ID_MODEL_FROM_DATABASE=nForce2 IDE
 
 pci:v000010DEd00000065sv000010DEsd00000C11*
- ID_MODEL_FROM_DATABASE=nForce 2 EIDE Controller
+ ID_MODEL_FROM_DATABASE=nForce2 IDE (nForce 2 EIDE Controller)
 
 pci:v000010DEd00000065sv0000A0A0sd000003B2*
- ID_MODEL_FROM_DATABASE=UK79G-1394 motherboard
+ ID_MODEL_FROM_DATABASE=nForce2 IDE (UK79G-1394 motherboard)
 
 pci:v000010DEd00000066*
  ID_MODEL_FROM_DATABASE=nForce2 Ethernet Controller
 
 pci:v000010DEd00000066sv00001043sd000080A7*
- ID_MODEL_FROM_DATABASE=A7N8X Mainboard onboard nForce2 Ethernet
+ ID_MODEL_FROM_DATABASE=nForce2 Ethernet Controller (A7N8X Mainboard onboard nForce2 Ethernet)
 
 pci:v000010DEd00000066sv000010DEsd00000C11*
- ID_MODEL_FROM_DATABASE=nForce MCP-T Networking Adapter
+ ID_MODEL_FROM_DATABASE=nForce2 Ethernet Controller (nForce MCP-T Networking Adapter)
 
 pci:v000010DEd00000066sv0000A0A0sd000003B3*
- ID_MODEL_FROM_DATABASE=UK79G-1394 motherboard
+ ID_MODEL_FROM_DATABASE=nForce2 Ethernet Controller (UK79G-1394 motherboard)
 
 pci:v000010DEd00000067*
  ID_MODEL_FROM_DATABASE=nForce2 USB Controller
 
 pci:v000010DEd00000067sv00001043sd00000C11*
- ID_MODEL_FROM_DATABASE=A7N8X Mainboard
+ ID_MODEL_FROM_DATABASE=nForce2 USB Controller (A7N8X Mainboard)
 
 pci:v000010DEd00000067sv0000A0A0sd000003B4*
- ID_MODEL_FROM_DATABASE=UK79G-1394 motherboard
+ ID_MODEL_FROM_DATABASE=nForce2 USB Controller (UK79G-1394 motherboard)
 
 pci:v000010DEd00000068*
  ID_MODEL_FROM_DATABASE=nForce2 USB Controller
 
 pci:v000010DEd00000068sv00001043sd00000C11*
- ID_MODEL_FROM_DATABASE=A7N8X Mainboard
+ ID_MODEL_FROM_DATABASE=nForce2 USB Controller (A7N8X Mainboard)
 
 pci:v000010DEd00000068sv0000A0A0sd000003B4*
- ID_MODEL_FROM_DATABASE=UK79G-1394 motherboard
+ ID_MODEL_FROM_DATABASE=nForce2 USB Controller (UK79G-1394 motherboard)
 
 pci:v000010DEd0000006A*
  ID_MODEL_FROM_DATABASE=nForce2 AC97 Audio Controler (MCP)
@@ -20907,16 +21390,16 @@ pci:v000010DEd0000006Asv00001043sd00008095*
  ID_MODEL_FROM_DATABASE=nForce2 AC97 Audio Controler (MCP)
 
 pci:v000010DEd0000006Asv0000A0A0sd00000304*
- ID_MODEL_FROM_DATABASE=UK79G-1394 motherboard
+ ID_MODEL_FROM_DATABASE=nForce2 AC97 Audio Controler (MCP) (UK79G-1394 motherboard)
 
 pci:v000010DEd0000006B*
  ID_MODEL_FROM_DATABASE=nForce Audio Processing Unit
 
 pci:v000010DEd0000006Bsv000010DEsd0000006B*
- ID_MODEL_FROM_DATABASE=nForce2 MCP Audio Processing Unit
+ ID_MODEL_FROM_DATABASE=nForce Audio Processing Unit (nForce2 MCP Audio Processing Unit)
 
 pci:v000010DEd0000006Bsv0000A0A0sd00000304*
- ID_MODEL_FROM_DATABASE=UK79G-1394 motherboard
+ ID_MODEL_FROM_DATABASE=nForce Audio Processing Unit (UK79G-1394 motherboard)
 
 pci:v000010DEd0000006C*
  ID_MODEL_FROM_DATABASE=nForce2 External PCI Bridge
@@ -20928,25 +21411,25 @@ pci:v000010DEd0000006E*
  ID_MODEL_FROM_DATABASE=nForce2 FireWire (IEEE 1394) Controller
 
 pci:v000010DEd0000006Esv0000A0A0sd00000306*
- ID_MODEL_FROM_DATABASE=UK79G-1394 motherboard
+ ID_MODEL_FROM_DATABASE=nForce2 FireWire (IEEE 1394) Controller (UK79G-1394 motherboard)
 
 pci:v000010DEd00000080*
  ID_MODEL_FROM_DATABASE=MCP2A ISA bridge
 
 pci:v000010DEd00000080sv0000147Bsd00001C09*
- ID_MODEL_FROM_DATABASE=NV7 Motherboard
+ ID_MODEL_FROM_DATABASE=MCP2A ISA bridge (NV7 Motherboard)
 
 pci:v000010DEd00000084*
  ID_MODEL_FROM_DATABASE=MCP2A SMBus
 
 pci:v000010DEd00000084sv0000147Bsd00001C09*
- ID_MODEL_FROM_DATABASE=NV7 Motherboard
+ ID_MODEL_FROM_DATABASE=MCP2A SMBus (NV7 Motherboard)
 
 pci:v000010DEd00000085*
  ID_MODEL_FROM_DATABASE=MCP2A IDE
 
 pci:v000010DEd00000085sv0000147Bsd00001C09*
- ID_MODEL_FROM_DATABASE=NV7 Motherboard
+ ID_MODEL_FROM_DATABASE=MCP2A IDE (NV7 Motherboard)
 
 pci:v000010DEd00000086*
  ID_MODEL_FROM_DATABASE=MCP2A Ethernet Controller
@@ -20955,19 +21438,19 @@ pci:v000010DEd00000087*
  ID_MODEL_FROM_DATABASE=MCP2A USB Controller
 
 pci:v000010DEd00000087sv0000147Bsd00001C09*
- ID_MODEL_FROM_DATABASE=NV7 Motherboard
+ ID_MODEL_FROM_DATABASE=MCP2A USB Controller (NV7 Motherboard)
 
 pci:v000010DEd00000088*
  ID_MODEL_FROM_DATABASE=MCP2A USB Controller
 
 pci:v000010DEd00000088sv0000147Bsd00001C09*
- ID_MODEL_FROM_DATABASE=NV7 Motherboard
+ ID_MODEL_FROM_DATABASE=MCP2A USB Controller (NV7 Motherboard)
 
 pci:v000010DEd0000008A*
  ID_MODEL_FROM_DATABASE=MCP2S AC'97 Audio Controller
 
 pci:v000010DEd0000008Asv0000147Bsd00001C09*
- ID_MODEL_FROM_DATABASE=NV7 Motherboard
+ ID_MODEL_FROM_DATABASE=MCP2S AC'97 Audio Controller (NV7 Motherboard)
 
 pci:v000010DEd0000008B*
  ID_MODEL_FROM_DATABASE=MCP2A PCI Bridge
@@ -21009,7 +21492,7 @@ pci:v000010DEd000000A0*
  ID_MODEL_FROM_DATABASE=NV5 [Aladdin TNT2]
 
 pci:v000010DEd000000A0sv000014AFsd00005810*
- ID_MODEL_FROM_DATABASE=Maxi Gamer Xentor
+ ID_MODEL_FROM_DATABASE=NV5 [Aladdin TNT2] (Maxi Gamer Xentor)
 
 pci:v000010DEd000000C0*
  ID_MODEL_FROM_DATABASE=NV41 [GeForce 6800 GS]
@@ -21042,10 +21525,7 @@ pci:v000010DEd000000CC*
  ID_MODEL_FROM_DATABASE=NV41GLM [Quadro FX Go1400]
 
 pci:v000010DEd000000CD*
- ID_MODEL_FROM_DATABASE=NV41GL [Quadro FX 3450/4000 SDI]
-
-pci:v000010DEd000000CDsv000010DEsd0000029B*
- ID_MODEL_FROM_DATABASE=wx4300 Workstation
+ ID_MODEL_FROM_DATABASE=NV42GL [Quadro FX 3450/4000 SDI]
 
 pci:v000010DEd000000CE*
  ID_MODEL_FROM_DATABASE=NV41GL [Quadro FX 1400]
@@ -21093,46 +21573,46 @@ pci:v000010DEd000000DF*
  ID_MODEL_FROM_DATABASE=CK8S Ethernet Controller
 
 pci:v000010DEd000000DFsv00001043sd000080A7*
- ID_MODEL_FROM_DATABASE=K8N-E
+ ID_MODEL_FROM_DATABASE=CK8S Ethernet Controller (K8N-E)
 
 pci:v000010DEd000000DFsv0000105Bsd00000C43*
- ID_MODEL_FROM_DATABASE=Winfast NF3250K8AA
+ ID_MODEL_FROM_DATABASE=CK8S Ethernet Controller (Winfast NF3250K8AA)
 
 pci:v000010DEd000000DFsv0000147Bsd00001C0B*
- ID_MODEL_FROM_DATABASE=NF8 Mainboard
+ ID_MODEL_FROM_DATABASE=CK8S Ethernet Controller (NF8 Mainboard)
 
 pci:v000010DEd000000E0*
  ID_MODEL_FROM_DATABASE=nForce3 250Gb LPC Bridge
 
 pci:v000010DEd000000E0sv00001043sd0000813F*
- ID_MODEL_FROM_DATABASE=K8N-E
+ ID_MODEL_FROM_DATABASE=nForce3 250Gb LPC Bridge (K8N-E)
 
 pci:v000010DEd000000E0sv000010DEsd00000C11*
- ID_MODEL_FROM_DATABASE=Winfast NF3250K8AA
+ ID_MODEL_FROM_DATABASE=nForce3 250Gb LPC Bridge (Winfast NF3250K8AA)
 
 pci:v000010DEd000000E0sv00001462sd00007030*
- ID_MODEL_FROM_DATABASE=K8N Neo-FSR v2.0
+ ID_MODEL_FROM_DATABASE=nForce3 250Gb LPC Bridge (K8N Neo-FSR v2.0)
 
 pci:v000010DEd000000E0sv0000147Bsd00001C0B*
- ID_MODEL_FROM_DATABASE=NF8 Mainboard
+ ID_MODEL_FROM_DATABASE=nForce3 250Gb LPC Bridge (NF8 Mainboard)
 
 pci:v000010DEd000000E0sv00001849sd000000E0*
- ID_MODEL_FROM_DATABASE=Motherboard (one of many)
+ ID_MODEL_FROM_DATABASE=nForce3 250Gb LPC Bridge (Motherboard (one of many))
 
 pci:v000010DEd000000E1*
  ID_MODEL_FROM_DATABASE=nForce3 250Gb Host Bridge
 
 pci:v000010DEd000000E1sv00001043sd0000813F*
- ID_MODEL_FROM_DATABASE=K8N-E
+ ID_MODEL_FROM_DATABASE=nForce3 250Gb Host Bridge (K8N-E)
 
 pci:v000010DEd000000E1sv00001462sd00007030*
- ID_MODEL_FROM_DATABASE=K8N Neo-FSR v2.0
+ ID_MODEL_FROM_DATABASE=nForce3 250Gb Host Bridge (K8N Neo-FSR v2.0)
 
 pci:v000010DEd000000E1sv0000147Bsd00001C0B*
- ID_MODEL_FROM_DATABASE=NF8 Mainboard
+ ID_MODEL_FROM_DATABASE=nForce3 250Gb Host Bridge (NF8 Mainboard)
 
 pci:v000010DEd000000E1sv00001849sd000000E1*
- ID_MODEL_FROM_DATABASE=Motherboard (one of many)
+ ID_MODEL_FROM_DATABASE=nForce3 250Gb Host Bridge (Motherboard (one of many))
 
 pci:v000010DEd000000E2*
  ID_MODEL_FROM_DATABASE=nForce3 250Gb AGP Host to PCI Bridge
@@ -21141,55 +21621,55 @@ pci:v000010DEd000000E3*
  ID_MODEL_FROM_DATABASE=nForce3 Serial ATA Controller
 
 pci:v000010DEd000000E3sv00001043sd0000813F*
- ID_MODEL_FROM_DATABASE=K8N-E
+ ID_MODEL_FROM_DATABASE=nForce3 Serial ATA Controller (K8N-E)
 
 pci:v000010DEd000000E3sv0000105Bsd00000C43*
- ID_MODEL_FROM_DATABASE=Winfast NF3250K8AA
+ ID_MODEL_FROM_DATABASE=nForce3 Serial ATA Controller (Winfast NF3250K8AA)
 
 pci:v000010DEd000000E3sv0000147Bsd00001C0B*
- ID_MODEL_FROM_DATABASE=NF8 Mainboard
+ ID_MODEL_FROM_DATABASE=nForce3 Serial ATA Controller (NF8 Mainboard)
 
 pci:v000010DEd000000E3sv00001849sd000000E3*
- ID_MODEL_FROM_DATABASE=Motherboard (one of many)
+ ID_MODEL_FROM_DATABASE=nForce3 Serial ATA Controller (Motherboard (one of many))
 
 pci:v000010DEd000000E4*
  ID_MODEL_FROM_DATABASE=nForce 250Gb PCI System Management
 
 pci:v000010DEd000000E4sv00001043sd0000813F*
- ID_MODEL_FROM_DATABASE=K8N-E
+ ID_MODEL_FROM_DATABASE=nForce 250Gb PCI System Management (K8N-E)
 
 pci:v000010DEd000000E4sv0000105Bsd00000C43*
- ID_MODEL_FROM_DATABASE=Winfast NF3250K8AA
+ ID_MODEL_FROM_DATABASE=nForce 250Gb PCI System Management (Winfast NF3250K8AA)
 
 pci:v000010DEd000000E4sv00001462sd00007030*
- ID_MODEL_FROM_DATABASE=K8N Neo-FSR v2.0
+ ID_MODEL_FROM_DATABASE=nForce 250Gb PCI System Management (K8N Neo-FSR v2.0)
 
 pci:v000010DEd000000E4sv0000147Bsd00001C0B*
- ID_MODEL_FROM_DATABASE=NF8 Mainboard
+ ID_MODEL_FROM_DATABASE=nForce 250Gb PCI System Management (NF8 Mainboard)
 
 pci:v000010DEd000000E4sv00001849sd000000E4*
- ID_MODEL_FROM_DATABASE=Motherboard (one of many)
+ ID_MODEL_FROM_DATABASE=nForce 250Gb PCI System Management (Motherboard (one of many))
 
 pci:v000010DEd000000E5*
  ID_MODEL_FROM_DATABASE=CK8S Parallel ATA Controller (v2.5)
 
 pci:v000010DEd000000E5sv00001043sd0000813F*
- ID_MODEL_FROM_DATABASE=K8N-E
+ ID_MODEL_FROM_DATABASE=CK8S Parallel ATA Controller (v2.5) (K8N-E)
 
 pci:v000010DEd000000E5sv0000105Bsd00000C43*
- ID_MODEL_FROM_DATABASE=Winfast NF3250K8AA
+ ID_MODEL_FROM_DATABASE=CK8S Parallel ATA Controller (v2.5) (Winfast NF3250K8AA)
 
 pci:v000010DEd000000E5sv00001462sd00007030*
- ID_MODEL_FROM_DATABASE=K8N Neo-FSR v2.0
+ ID_MODEL_FROM_DATABASE=CK8S Parallel ATA Controller (v2.5) (K8N Neo-FSR v2.0)
 
 pci:v000010DEd000000E5sv0000147Bsd00001C0B*
- ID_MODEL_FROM_DATABASE=NF8 Mainboard
+ ID_MODEL_FROM_DATABASE=CK8S Parallel ATA Controller (v2.5) (NF8 Mainboard)
 
 pci:v000010DEd000000E5sv00001849sd000000E5*
- ID_MODEL_FROM_DATABASE=Motherboard (one of many)
+ ID_MODEL_FROM_DATABASE=CK8S Parallel ATA Controller (v2.5) (Motherboard (one of many))
 
 pci:v000010DEd000000E5sv0000F849sd000000E5*
- ID_MODEL_FROM_DATABASE=Motherboard (one of many)
+ ID_MODEL_FROM_DATABASE=CK8S Parallel ATA Controller (v2.5) (Motherboard (one of many))
 
 pci:v000010DEd000000E6*
  ID_MODEL_FROM_DATABASE=CK8S Ethernet Controller
@@ -21198,52 +21678,52 @@ pci:v000010DEd000000E7*
  ID_MODEL_FROM_DATABASE=CK8S USB Controller
 
 pci:v000010DEd000000E7sv00001043sd0000813F*
- ID_MODEL_FROM_DATABASE=K8N-E
+ ID_MODEL_FROM_DATABASE=CK8S USB Controller (K8N-E)
 
 pci:v000010DEd000000E7sv0000105Bsd00000C43*
- ID_MODEL_FROM_DATABASE=Winfast NF3250K8AA
+ ID_MODEL_FROM_DATABASE=CK8S USB Controller (Winfast NF3250K8AA)
 
 pci:v000010DEd000000E7sv00001462sd00007030*
- ID_MODEL_FROM_DATABASE=K8N Neo-FSR v2.0
+ ID_MODEL_FROM_DATABASE=CK8S USB Controller (K8N Neo-FSR v2.0)
 
 pci:v000010DEd000000E7sv0000147Bsd00001C0B*
- ID_MODEL_FROM_DATABASE=NF8 Mainboard
+ ID_MODEL_FROM_DATABASE=CK8S USB Controller (NF8 Mainboard)
 
 pci:v000010DEd000000E7sv00001849sd000000E7*
- ID_MODEL_FROM_DATABASE=Motherboard (one of many)
+ ID_MODEL_FROM_DATABASE=CK8S USB Controller (Motherboard (one of many))
 
 pci:v000010DEd000000E8*
  ID_MODEL_FROM_DATABASE=nForce3 EHCI USB 2.0 Controller
 
 pci:v000010DEd000000E8sv00001043sd0000813F*
- ID_MODEL_FROM_DATABASE=K8N-E
+ ID_MODEL_FROM_DATABASE=nForce3 EHCI USB 2.0 Controller (K8N-E)
 
 pci:v000010DEd000000E8sv0000105Bsd00000C43*
- ID_MODEL_FROM_DATABASE=Winfast NF3250K8AA
+ ID_MODEL_FROM_DATABASE=nForce3 EHCI USB 2.0 Controller (Winfast NF3250K8AA)
 
 pci:v000010DEd000000E8sv00001462sd00007030*
- ID_MODEL_FROM_DATABASE=K8N Neo-FSR v2.0
+ ID_MODEL_FROM_DATABASE=nForce3 EHCI USB 2.0 Controller (K8N Neo-FSR v2.0)
 
 pci:v000010DEd000000E8sv0000147Bsd00001C0B*
- ID_MODEL_FROM_DATABASE=NF8 Mainboard
+ ID_MODEL_FROM_DATABASE=nForce3 EHCI USB 2.0 Controller (NF8 Mainboard)
 
 pci:v000010DEd000000E8sv00001849sd000000E8*
- ID_MODEL_FROM_DATABASE=Motherboard (one of many)
+ ID_MODEL_FROM_DATABASE=nForce3 EHCI USB 2.0 Controller (Motherboard (one of many))
 
 pci:v000010DEd000000EA*
  ID_MODEL_FROM_DATABASE=nForce3 250Gb AC'97 Audio Controller
 
 pci:v000010DEd000000EAsv00001043sd0000819D*
- ID_MODEL_FROM_DATABASE=K8N-E
+ ID_MODEL_FROM_DATABASE=nForce3 250Gb AC'97 Audio Controller (K8N-E)
 
 pci:v000010DEd000000EAsv0000105Bsd00000C43*
- ID_MODEL_FROM_DATABASE=Winfast NF3250K8AA
+ ID_MODEL_FROM_DATABASE=nForce3 250Gb AC'97 Audio Controller (Winfast NF3250K8AA)
 
 pci:v000010DEd000000EAsv00001462sd0000B010*
- ID_MODEL_FROM_DATABASE=K8N Neo-FSR v2.0
+ ID_MODEL_FROM_DATABASE=nForce3 250Gb AC'97 Audio Controller (K8N Neo-FSR v2.0)
 
 pci:v000010DEd000000EAsv0000147Bsd00001C0B*
- ID_MODEL_FROM_DATABASE=NF8 Mainboard
+ ID_MODEL_FROM_DATABASE=nForce3 250Gb AC'97 Audio Controller (NF8 Mainboard)
 
 pci:v000010DEd000000ED*
  ID_MODEL_FROM_DATABASE=nForce3 250Gb PCI-to-PCI Bridge
@@ -21255,28 +21735,28 @@ pci:v000010DEd000000F1*
  ID_MODEL_FROM_DATABASE=NV43 [GeForce 6600 GT]
 
 pci:v000010DEd000000F1sv00001043sd000081A6*
- ID_MODEL_FROM_DATABASE=N6600GT TD 128M AGP
+ ID_MODEL_FROM_DATABASE=NV43 [GeForce 6600 GT] (N6600GT TD 128M AGP)
 
 pci:v000010DEd000000F1sv00001043sd000081C6*
- ID_MODEL_FROM_DATABASE=N6600GT TD 128M AGP
+ ID_MODEL_FROM_DATABASE=NV43 [GeForce 6600 GT] (N6600GT TD 128M AGP)
 
 pci:v000010DEd000000F1sv00001458sd00003150*
- ID_MODEL_FROM_DATABASE=GV-N66T128VP
+ ID_MODEL_FROM_DATABASE=NV43 [GeForce 6600 GT] (GV-N66T128VP)
 
 pci:v000010DEd000000F1sv00001554sd00001191*
- ID_MODEL_FROM_DATABASE=PixelView PV-N43UA (128KD)
+ ID_MODEL_FROM_DATABASE=NV43 [GeForce 6600 GT] (PixelView PV-N43UA (128KD))
 
 pci:v000010DEd000000F1sv00001682sd00002119*
- ID_MODEL_FROM_DATABASE=GeForce 6600 GT AGP
+ ID_MODEL_FROM_DATABASE=NV43 [GeForce 6600 GT] (GeForce 6600 GT AGP)
 
 pci:v000010DEd000000F2*
  ID_MODEL_FROM_DATABASE=NV43 [GeForce 6600]
 
 pci:v000010DEd000000F2sv00001554sd00001194*
- ID_MODEL_FROM_DATABASE=PixelView PV-N43AT (256KD)
+ ID_MODEL_FROM_DATABASE=NV43 [GeForce 6600] (PixelView PV-N43AT (256KD))
 
 pci:v000010DEd000000F2sv00001682sd0000211C*
- ID_MODEL_FROM_DATABASE=GeForce 6600 256MB DDR DUAL DVI TV
+ ID_MODEL_FROM_DATABASE=NV43 [GeForce 6600] (GeForce 6600 256MB DDR DUAL DVI TV)
 
 pci:v000010DEd000000F3*
  ID_MODEL_FROM_DATABASE=NV43 [GeForce 6200]
@@ -21291,7 +21771,7 @@ pci:v000010DEd000000F6*
  ID_MODEL_FROM_DATABASE=NV43 [GeForce 6800 GS/XT]
 
 pci:v000010DEd000000F6sv00001682sd0000217E*
- ID_MODEL_FROM_DATABASE=XFX GeForce 6800 XTreme 256MB DDR3 AGP
+ ID_MODEL_FROM_DATABASE=NV43 [GeForce 6800 GS/XT] (XFX GeForce 6800 XTreme 256MB DDR3 AGP)
 
 pci:v000010DEd000000F8*
  ID_MODEL_FROM_DATABASE=NV40GL [Quadro FX 3400/4400]
@@ -21300,10 +21780,10 @@ pci:v000010DEd000000F9*
  ID_MODEL_FROM_DATABASE=NV40 [GeForce 6800 GT/GTO/Ultra]
 
 pci:v000010DEd000000F9sv000010DEsd000000F9*
- ID_MODEL_FROM_DATABASE=NV40 [GeForce 6800 GT]
+ ID_MODEL_FROM_DATABASE=NV40 [GeForce 6800 GT/GTO/Ultra] (NV40 [GeForce 6800 GT])
 
 pci:v000010DEd000000F9sv00001682sd00002120*
- ID_MODEL_FROM_DATABASE=GEFORCE 6800 GT PCI-E
+ ID_MODEL_FROM_DATABASE=NV40 [GeForce 6800 GT/GTO/Ultra] (GEFORCE 6800 GT PCI-E)
 
 pci:v000010DEd000000FA*
  ID_MODEL_FROM_DATABASE=NV36 [GeForce PCX 5750]
@@ -21327,130 +21807,130 @@ pci:v000010DEd00000100*
  ID_MODEL_FROM_DATABASE=NV10 [GeForce 256 SDR]
 
 pci:v000010DEd00000100sv00001043sd00000200*
- ID_MODEL_FROM_DATABASE=AGP-V6600 SGRAM
+ ID_MODEL_FROM_DATABASE=NV10 [GeForce 256 SDR] (AGP-V6600 SGRAM)
 
 pci:v000010DEd00000100sv00001043sd00000201*
- ID_MODEL_FROM_DATABASE=AGP-V6600 SDRAM
+ ID_MODEL_FROM_DATABASE=NV10 [GeForce 256 SDR] (AGP-V6600 SDRAM)
 
 pci:v000010DEd00000100sv00001043sd00004008*
- ID_MODEL_FROM_DATABASE=AGP-V6600 SGRAM
+ ID_MODEL_FROM_DATABASE=NV10 [GeForce 256 SDR] (AGP-V6600 SGRAM)
 
 pci:v000010DEd00000100sv00001043sd00004009*
- ID_MODEL_FROM_DATABASE=AGP-V6600 SDRAM
+ ID_MODEL_FROM_DATABASE=NV10 [GeForce 256 SDR] (AGP-V6600 SDRAM)
 
 pci:v000010DEd00000100sv00001048sd00000C41*
- ID_MODEL_FROM_DATABASE=Erazor X
+ ID_MODEL_FROM_DATABASE=NV10 [GeForce 256 SDR] (Erazor X)
 
 pci:v000010DEd00000100sv00001048sd00000C43*
- ID_MODEL_FROM_DATABASE=ERAZOR X PCI
+ ID_MODEL_FROM_DATABASE=NV10 [GeForce 256 SDR] (ERAZOR X PCI)
 
 pci:v000010DEd00000100sv00001048sd00000C48*
- ID_MODEL_FROM_DATABASE=Synergy Force
+ ID_MODEL_FROM_DATABASE=NV10 [GeForce 256 SDR] (Synergy Force)
 
 pci:v000010DEd00000100sv00001102sd0000102D*
- ID_MODEL_FROM_DATABASE=CT6941 GeForce 256
+ ID_MODEL_FROM_DATABASE=NV10 [GeForce 256 SDR] (CT6941 GeForce 256)
 
 pci:v000010DEd00000100sv000014AFsd00005022*
- ID_MODEL_FROM_DATABASE=3D Prophet SE
+ ID_MODEL_FROM_DATABASE=NV10 [GeForce 256 SDR] (3D Prophet SE)
 
 pci:v000010DEd00000101*
  ID_MODEL_FROM_DATABASE=NV10 [GeForce 256 DDR]
 
 pci:v000010DEd00000101sv00001043sd00000202*
- ID_MODEL_FROM_DATABASE=AGP-V6800 DDR
+ ID_MODEL_FROM_DATABASE=NV10 [GeForce 256 DDR] (AGP-V6800 DDR)
 
 pci:v000010DEd00000101sv00001043sd0000400A*
- ID_MODEL_FROM_DATABASE=AGP-V6800 DDR SGRAM
+ ID_MODEL_FROM_DATABASE=NV10 [GeForce 256 DDR] (AGP-V6800 DDR SGRAM)
 
 pci:v000010DEd00000101sv00001043sd0000400B*
- ID_MODEL_FROM_DATABASE=AGP-V6800 DDR SDRAM
+ ID_MODEL_FROM_DATABASE=NV10 [GeForce 256 DDR] (AGP-V6800 DDR SDRAM)
 
 pci:v000010DEd00000101sv00001048sd00000C42*
- ID_MODEL_FROM_DATABASE=Erazor X
+ ID_MODEL_FROM_DATABASE=NV10 [GeForce 256 DDR] (Erazor X)
 
 pci:v000010DEd00000101sv0000107Dsd00002822*
- ID_MODEL_FROM_DATABASE=WinFast GeForce 256
+ ID_MODEL_FROM_DATABASE=NV10 [GeForce 256 DDR] (WinFast GeForce 256)
 
 pci:v000010DEd00000101sv00001102sd0000102E*
- ID_MODEL_FROM_DATABASE=CT6970/CT6971
+ ID_MODEL_FROM_DATABASE=NV10 [GeForce 256 DDR] (CT6970/CT6971)
 
 pci:v000010DEd00000101sv000014AFsd00005021*
- ID_MODEL_FROM_DATABASE=3D Prophet DDR-DVI
+ ID_MODEL_FROM_DATABASE=NV10 [GeForce 256 DDR] (3D Prophet DDR-DVI)
 
 pci:v000010DEd00000103*
  ID_MODEL_FROM_DATABASE=NV10GL [Quadro]
 
 pci:v000010DEd00000103sv00001048sd00000C40*
- ID_MODEL_FROM_DATABASE=GLoria II-64
+ ID_MODEL_FROM_DATABASE=NV10GL [Quadro] (GLoria II-64)
 
 pci:v000010DEd00000103sv00001048sd00000C44*
- ID_MODEL_FROM_DATABASE=GLoria II
+ ID_MODEL_FROM_DATABASE=NV10GL [Quadro] (GLoria II)
 
 pci:v000010DEd00000103sv00001048sd00000C45*
- ID_MODEL_FROM_DATABASE=GLoria II
+ ID_MODEL_FROM_DATABASE=NV10GL [Quadro] (GLoria II)
 
 pci:v000010DEd00000103sv00001048sd00000C4A*
- ID_MODEL_FROM_DATABASE=GLoria II-64 Pro
+ ID_MODEL_FROM_DATABASE=NV10GL [Quadro] (GLoria II-64 Pro)
 
 pci:v000010DEd00000103sv00001048sd00000C4B*
- ID_MODEL_FROM_DATABASE=GLoria II-64 Pro DVII
+ ID_MODEL_FROM_DATABASE=NV10GL [Quadro] (GLoria II-64 Pro DVII)
 
 pci:v000010DEd00000110*
  ID_MODEL_FROM_DATABASE=NV11 [GeForce2 MX/MX 400]
 
 pci:v000010DEd00000110sv00001043sd00004015*
- ID_MODEL_FROM_DATABASE=AGP-V7100 Pro
+ ID_MODEL_FROM_DATABASE=NV11 [GeForce2 MX/MX 400] (AGP-V7100 Pro)
 
 pci:v000010DEd00000110sv00001043sd00004021*
- ID_MODEL_FROM_DATABASE=V7100 Deluxe Combo
+ ID_MODEL_FROM_DATABASE=NV11 [GeForce2 MX/MX 400] (V7100 Deluxe Combo)
 
 pci:v000010DEd00000110sv00001043sd00004031*
- ID_MODEL_FROM_DATABASE=V7100 Pro with TV output
+ ID_MODEL_FROM_DATABASE=NV11 [GeForce2 MX/MX 400] (V7100 Pro with TV output)
 
 pci:v000010DEd00000110sv00001048sd00000C60*
- ID_MODEL_FROM_DATABASE=Gladiac MX
+ ID_MODEL_FROM_DATABASE=NV11 [GeForce2 MX/MX 400] (Gladiac MX)
 
 pci:v000010DEd00000110sv00001048sd00000C61*
- ID_MODEL_FROM_DATABASE=Gladiac 511PCI
+ ID_MODEL_FROM_DATABASE=NV11 [GeForce2 MX/MX 400] (Gladiac 511PCI)
 
 pci:v000010DEd00000110sv00001048sd00000C63*
- ID_MODEL_FROM_DATABASE=Gladiac 511TV-OUT 32MB
+ ID_MODEL_FROM_DATABASE=NV11 [GeForce2 MX/MX 400] (Gladiac 511TV-OUT 32MB)
 
 pci:v000010DEd00000110sv00001048sd00000C64*
- ID_MODEL_FROM_DATABASE=Gladiac 511TV-OUT 64MB
+ ID_MODEL_FROM_DATABASE=NV11 [GeForce2 MX/MX 400] (Gladiac 511TV-OUT 64MB)
 
 pci:v000010DEd00000110sv00001048sd00000C65*
- ID_MODEL_FROM_DATABASE=Gladiac 511TWIN
+ ID_MODEL_FROM_DATABASE=NV11 [GeForce2 MX/MX 400] (Gladiac 511TWIN)
 
 pci:v000010DEd00000110sv00001048sd00000C66*
- ID_MODEL_FROM_DATABASE=Gladiac 311
+ ID_MODEL_FROM_DATABASE=NV11 [GeForce2 MX/MX 400] (Gladiac 311)
 
 pci:v000010DEd00000110sv000010B0sd00000001*
- ID_MODEL_FROM_DATABASE=GeForce2 MX Jumbo TV
+ ID_MODEL_FROM_DATABASE=NV11 [GeForce2 MX/MX 400] (GeForce2 MX Jumbo TV)
 
 pci:v000010DEd00000110sv000010DEsd00000091*
- ID_MODEL_FROM_DATABASE=Dell OEM GeForce 2 MX 400
+ ID_MODEL_FROM_DATABASE=NV11 [GeForce2 MX/MX 400] (Dell OEM GeForce 2 MX 400)
 
 pci:v000010DEd00000110sv000010DEsd000000A1*
- ID_MODEL_FROM_DATABASE=Apple OEM GeForce2 MX
+ ID_MODEL_FROM_DATABASE=NV11 [GeForce2 MX/MX 400] (Apple OEM GeForce2 MX)
 
 pci:v000010DEd00000110sv00001462sd00008523*
- ID_MODEL_FROM_DATABASE=MS-8852
+ ID_MODEL_FROM_DATABASE=NV11 [GeForce2 MX/MX 400] (MS-8852)
 
 pci:v000010DEd00000110sv00001462sd00008817*
- ID_MODEL_FROM_DATABASE=MSI GeForce2 MX400 Pro32S [MS-8817]
+ ID_MODEL_FROM_DATABASE=NV11 [GeForce2 MX/MX 400] (MSI GeForce2 MX400 Pro32S [MS-8817])
 
 pci:v000010DEd00000110sv000014AFsd00007102*
- ID_MODEL_FROM_DATABASE=3D Prophet II MX
+ ID_MODEL_FROM_DATABASE=NV11 [GeForce2 MX/MX 400] (3D Prophet II MX)
 
 pci:v000010DEd00000110sv000014AFsd00007103*
- ID_MODEL_FROM_DATABASE=3D Prophet II MX Dual-Display
+ ID_MODEL_FROM_DATABASE=NV11 [GeForce2 MX/MX 400] (3D Prophet II MX Dual-Display)
 
 pci:v000010DEd00000110sv00001545sd00000023*
- ID_MODEL_FROM_DATABASE=Xtasy Rev. B2
+ ID_MODEL_FROM_DATABASE=NV11 [GeForce2 MX/MX 400] (Xtasy Rev. B2)
 
 pci:v000010DEd00000110sv00001554sd00001081*
- ID_MODEL_FROM_DATABASE=MVGA-NVG11AM(400)
+ ID_MODEL_FROM_DATABASE=NV11 [GeForce2 MX/MX 400] (MVGA-NVG11AM(400))
 
 pci:v000010DEd00000111*
  ID_MODEL_FROM_DATABASE=NV11 [GeForce2 MX200]
@@ -21465,28 +21945,28 @@ pci:v000010DEd00000140*
  ID_MODEL_FROM_DATABASE=NV43 [GeForce 6600 GT]
 
 pci:v000010DEd00000140sv00001458sd00003125*
- ID_MODEL_FROM_DATABASE=GV-NX66T128D
+ ID_MODEL_FROM_DATABASE=NV43 [GeForce 6600 GT] (GV-NX66T128D)
 
 pci:v000010DEd00000140sv00001458sd00003126*
- ID_MODEL_FROM_DATABASE=GV-NX66T256DE
+ ID_MODEL_FROM_DATABASE=NV43 [GeForce 6600 GT] (GV-NX66T256DE)
 
 pci:v000010DEd00000140sv00001462sd00008939*
- ID_MODEL_FROM_DATABASE=MS-8983
+ ID_MODEL_FROM_DATABASE=NV43 [GeForce 6600 GT] (MS-8983)
 
 pci:v000010DEd00000141*
  ID_MODEL_FROM_DATABASE=NV43 [GeForce 6600]
 
 pci:v000010DEd00000141sv00001043sd000081B0*
- ID_MODEL_FROM_DATABASE=EN6600 Silencer
+ ID_MODEL_FROM_DATABASE=NV43 [GeForce 6600] (EN6600 Silencer)
 
 pci:v000010DEd00000141sv0000107Dsd0000593A*
- ID_MODEL_FROM_DATABASE=LR2A22 128MB TV OUT
+ ID_MODEL_FROM_DATABASE=NV43 [GeForce 6600] (LR2A22 128MB TV OUT)
 
 pci:v000010DEd00000141sv0000107Dsd0000597B*
- ID_MODEL_FROM_DATABASE=WINFAST PX6600
+ ID_MODEL_FROM_DATABASE=NV43 [GeForce 6600] (WINFAST PX6600)
 
 pci:v000010DEd00000141sv00001458sd00003124*
- ID_MODEL_FROM_DATABASE=GV-NX66128DP Turbo Force Edition
+ ID_MODEL_FROM_DATABASE=NV43 [GeForce 6600] (GV-NX66128DP Turbo Force Edition)
 
 pci:v000010DEd00000142*
  ID_MODEL_FROM_DATABASE=NV43 [GeForce 6600 LE]
@@ -21531,49 +22011,49 @@ pci:v000010DEd00000150*
  ID_MODEL_FROM_DATABASE=NV15 [GeForce2 GTS/Pro]
 
 pci:v000010DEd00000150sv00001043sd00004016*
- ID_MODEL_FROM_DATABASE=V7700 AGP Video Card
+ ID_MODEL_FROM_DATABASE=NV15 [GeForce2 GTS/Pro] (V7700 AGP Video Card)
 
 pci:v000010DEd00000150sv00001043sd0000402A*
- ID_MODEL_FROM_DATABASE=AGP-V7700
+ ID_MODEL_FROM_DATABASE=NV15 [GeForce2 GTS/Pro] (AGP-V7700)
 
 pci:v000010DEd00000150sv00001048sd00000C50*
- ID_MODEL_FROM_DATABASE=Gladiac
+ ID_MODEL_FROM_DATABASE=NV15 [GeForce2 GTS/Pro] (Gladiac)
 
 pci:v000010DEd00000150sv00001048sd00000C52*
- ID_MODEL_FROM_DATABASE=Gladiac-64
+ ID_MODEL_FROM_DATABASE=NV15 [GeForce2 GTS/Pro] (Gladiac-64)
 
 pci:v000010DEd00000150sv0000107Dsd00002840*
- ID_MODEL_FROM_DATABASE=WinFast GeForce2 GTS with TV output
+ ID_MODEL_FROM_DATABASE=NV15 [GeForce2 GTS/Pro] (WinFast GeForce2 GTS with TV output)
 
 pci:v000010DEd00000150sv0000107Dsd00002842*
- ID_MODEL_FROM_DATABASE=WinFast GeForce 2 Pro
+ ID_MODEL_FROM_DATABASE=NV15 [GeForce2 GTS/Pro] (WinFast GeForce 2 Pro)
 
 pci:v000010DEd00000150sv000010DEsd0000002E*
- ID_MODEL_FROM_DATABASE=GeForce2 GTS
+ ID_MODEL_FROM_DATABASE=NV15 [GeForce2 GTS/Pro] (GeForce2 GTS)
 
 pci:v000010DEd00000150sv00001462sd0000815A*
- ID_MODEL_FROM_DATABASE=MS-8815
+ ID_MODEL_FROM_DATABASE=NV15 [GeForce2 GTS/Pro] (MS-8815)
 
 pci:v000010DEd00000150sv00001462sd00008831*
- ID_MODEL_FROM_DATABASE=Creative GeForce2 Pro
+ ID_MODEL_FROM_DATABASE=NV15 [GeForce2 GTS/Pro] (Creative GeForce2 Pro)
 
 pci:v000010DEd00000151*
  ID_MODEL_FROM_DATABASE=NV15 [GeForce2 Ti]
 
 pci:v000010DEd00000151sv00001043sd0000405F*
- ID_MODEL_FROM_DATABASE=V7700Ti
+ ID_MODEL_FROM_DATABASE=NV15 [GeForce2 Ti] (V7700Ti)
 
 pci:v000010DEd00000151sv00001462sd00005506*
- ID_MODEL_FROM_DATABASE=Creative 3D Blaster GeForce2 Titanium
+ ID_MODEL_FROM_DATABASE=NV15 [GeForce2 Ti] (Creative 3D Blaster GeForce2 Titanium)
 
 pci:v000010DEd00000151sv00001462sd00008364*
- ID_MODEL_FROM_DATABASE=MS-8836
+ ID_MODEL_FROM_DATABASE=NV15 [GeForce2 Ti] (MS-8836)
 
 pci:v000010DEd00000152*
  ID_MODEL_FROM_DATABASE=NV15 [GeForce2 Ultra]
 
 pci:v000010DEd00000152sv00001048sd00000C56*
- ID_MODEL_FROM_DATABASE=GLADIAC Ultra
+ ID_MODEL_FROM_DATABASE=NV15 [GeForce2 Ultra] (GLADIAC Ultra)
 
 pci:v000010DEd00000153*
  ID_MODEL_FROM_DATABASE=NV15GL [Quadro2 Pro]
@@ -21624,40 +22104,40 @@ pci:v000010DEd00000170*
  ID_MODEL_FROM_DATABASE=NV17 [GeForce4 MX 460]
 
 pci:v000010DEd00000170sv00001462sd00008630*
- ID_MODEL_FROM_DATABASE=MS-8863
+ ID_MODEL_FROM_DATABASE=NV17 [GeForce4 MX 460] (MS-8863)
 
 pci:v000010DEd00000171*
  ID_MODEL_FROM_DATABASE=NV17 [GeForce4 MX 440]
 
 pci:v000010DEd00000171sv000010B0sd00000002*
- ID_MODEL_FROM_DATABASE=Gainward Pro/600 TV
+ ID_MODEL_FROM_DATABASE=NV17 [GeForce4 MX 440] (Gainward Pro/600 TV)
 
 pci:v000010DEd00000171sv000010DEsd00000008*
- ID_MODEL_FROM_DATABASE=Apple OEM GeForce4 MX 440
+ ID_MODEL_FROM_DATABASE=NV17 [GeForce4 MX 440] (Apple OEM GeForce4 MX 440)
 
 pci:v000010DEd00000171sv00001462sd00008661*
- ID_MODEL_FROM_DATABASE=G4MX440-VTP
+ ID_MODEL_FROM_DATABASE=NV17 [GeForce4 MX 440] (G4MX440-VTP)
 
 pci:v000010DEd00000171sv00001462sd00008730*
- ID_MODEL_FROM_DATABASE=MX440SES-T (MS-8873)
+ ID_MODEL_FROM_DATABASE=NV17 [GeForce4 MX 440] (MX440SES-T (MS-8873))
 
 pci:v000010DEd00000171sv00001462sd00008743*
- ID_MODEL_FROM_DATABASE=MS-8874
+ ID_MODEL_FROM_DATABASE=NV17 [GeForce4 MX 440] (MS-8874)
 
 pci:v000010DEd00000171sv00001462sd00008852*
- ID_MODEL_FROM_DATABASE=GeForce4 MX440 PCI
+ ID_MODEL_FROM_DATABASE=NV17 [GeForce4 MX 440] (GeForce4 MX440 PCI)
 
 pci:v000010DEd00000171sv0000147Bsd00008F00*
- ID_MODEL_FROM_DATABASE=Abit Siluro GeForce4MX440
+ ID_MODEL_FROM_DATABASE=NV17 [GeForce4 MX 440] (Abit Siluro GeForce4MX440)
 
 pci:v000010DEd00000172*
  ID_MODEL_FROM_DATABASE=NV17 [GeForce4 MX 420]
 
 pci:v000010DEd00000172sv00001462sd00008730*
- ID_MODEL_FROM_DATABASE=MS-8873
+ ID_MODEL_FROM_DATABASE=NV17 [GeForce4 MX 420] (MS-8873)
 
 pci:v000010DEd00000172sv00001462sd00008784*
- ID_MODEL_FROM_DATABASE=MS-8878
+ ID_MODEL_FROM_DATABASE=NV17 [GeForce4 MX 420] (MS-8878)
 
 pci:v000010DEd00000173*
  ID_MODEL_FROM_DATABASE=NV17 [GeForce4 MX 440-SE]
@@ -21672,13 +22152,13 @@ pci:v000010DEd00000176*
  ID_MODEL_FROM_DATABASE=NV17M [GeForce4 420 Go 32M]
 
 pci:v000010DEd00000176sv0000103Csd000008B0*
- ID_MODEL_FROM_DATABASE=tc1100 tablet
+ ID_MODEL_FROM_DATABASE=NV17M [GeForce4 420 Go 32M] (tc1100 tablet)
 
 pci:v000010DEd00000176sv0000144Dsd0000C005*
- ID_MODEL_FROM_DATABASE=X10 Laptop
+ ID_MODEL_FROM_DATABASE=NV17M [GeForce4 420 Go 32M] (X10 Laptop)
 
 pci:v000010DEd00000176sv00004C53sd00001090*
- ID_MODEL_FROM_DATABASE=Cx9 / Vx9 mainboard
+ ID_MODEL_FROM_DATABASE=NV17M [GeForce4 420 Go 32M] (Cx9 / Vx9 mainboard)
 
 pci:v000010DEd00000177*
  ID_MODEL_FROM_DATABASE=NV17M [GeForce4 460 Go]
@@ -21690,7 +22170,7 @@ pci:v000010DEd00000179*
  ID_MODEL_FROM_DATABASE=NV17M [GeForce4 440 Go 64M]
 
 pci:v000010DEd00000179sv000010DEsd00000179*
- ID_MODEL_FROM_DATABASE=GeForce4 MX (Mac)
+ ID_MODEL_FROM_DATABASE=NV17M [GeForce4 440 Go 64M] (GeForce4 MX (Mac))
 
 pci:v000010DEd0000017A*
  ID_MODEL_FROM_DATABASE=NV17GL [Quadro NVS]
@@ -21708,25 +22188,25 @@ pci:v000010DEd00000181*
  ID_MODEL_FROM_DATABASE=NV18 [GeForce4 MX 440 AGP 8x]
 
 pci:v000010DEd00000181sv00001043sd00008063*
- ID_MODEL_FROM_DATABASE=GeForce4 MX 440 AGP 8X
+ ID_MODEL_FROM_DATABASE=NV18 [GeForce4 MX 440 AGP 8x] (GeForce4 MX 440 AGP 8X)
 
 pci:v000010DEd00000181sv00001043sd0000806F*
- ID_MODEL_FROM_DATABASE=V9180 Magic
+ ID_MODEL_FROM_DATABASE=NV18 [GeForce4 MX 440 AGP 8x] (V9180 Magic)
 
 pci:v000010DEd00000181sv00001462sd00008880*
- ID_MODEL_FROM_DATABASE=MS-StarForce GeForce4 MX 440 with AGP8X
+ ID_MODEL_FROM_DATABASE=NV18 [GeForce4 MX 440 AGP 8x] (MS-StarForce GeForce4 MX 440 with AGP8X)
 
 pci:v000010DEd00000181sv00001462sd00008900*
- ID_MODEL_FROM_DATABASE=MS-8890 GeForce 4 MX440 AGP8X
+ ID_MODEL_FROM_DATABASE=NV18 [GeForce4 MX 440 AGP 8x] (MS-8890 GeForce 4 MX440 AGP8X)
 
 pci:v000010DEd00000181sv00001462sd00009350*
- ID_MODEL_FROM_DATABASE=MSI GeForce4 MX T8X with AGP8X
+ ID_MODEL_FROM_DATABASE=NV18 [GeForce4 MX 440 AGP 8x] (MSI GeForce4 MX T8X with AGP8X)
 
 pci:v000010DEd00000181sv0000147Bsd00008F0D*
- ID_MODEL_FROM_DATABASE=Siluro GF4 MX-8X
+ ID_MODEL_FROM_DATABASE=NV18 [GeForce4 MX 440 AGP 8x] (Siluro GF4 MX-8X)
 
 pci:v000010DEd00000181sv00001554sd00001111*
- ID_MODEL_FROM_DATABASE=PixelView MVGA-NVG18A
+ ID_MODEL_FROM_DATABASE=NV18 [GeForce4 MX 440 AGP 8x] (PixelView MVGA-NVG18A)
 
 pci:v000010DEd00000182*
  ID_MODEL_FROM_DATABASE=NV18 [GeForce4 MX 440SE AGP 8x]
@@ -21780,7 +22260,7 @@ pci:v000010DEd00000193*
  ID_MODEL_FROM_DATABASE=G80 [GeForce 8800 GTS]
 
 pci:v000010DEd00000193sv0000107Dsd000020BD*
- ID_MODEL_FROM_DATABASE=WinFast PX 8800 GTS TDH
+ ID_MODEL_FROM_DATABASE=G80 [GeForce 8800 GTS] (WinFast PX 8800 GTS TDH)
 
 pci:v000010DEd00000194*
  ID_MODEL_FROM_DATABASE=G80 [GeForce 8800 Ultra]
@@ -21846,13 +22326,13 @@ pci:v000010DEd000001D1*
  ID_MODEL_FROM_DATABASE=G72 [GeForce 7300 LE]
 
 pci:v000010DEd000001D1sv0000107Dsd00005EFA*
- ID_MODEL_FROM_DATABASE=WinFast PX7300LE-TD128
+ ID_MODEL_FROM_DATABASE=G72 [GeForce 7300 LE] (WinFast PX7300LE-TD128)
 
 pci:v000010DEd000001D1sv0000107Dsd00005EFB*
- ID_MODEL_FROM_DATABASE=WinFast PX7300LE-TD256
+ ID_MODEL_FROM_DATABASE=G72 [GeForce 7300 LE] (WinFast PX7300LE-TD256)
 
 pci:v000010DEd000001D1sv00001462sd00000345*
- ID_MODEL_FROM_DATABASE=7300LE PCI Express Graphics Adapter
+ ID_MODEL_FROM_DATABASE=G72 [GeForce 7300 LE] (7300LE PCI Express Graphics Adapter)
 
 pci:v000010DEd000001D2*
  ID_MODEL_FROM_DATABASE=G72 [GeForce 7550 LE]
@@ -21873,7 +22353,7 @@ pci:v000010DEd000001D8*
  ID_MODEL_FROM_DATABASE=G72M [GeForce Go 7400]
 
 pci:v000010DEd000001D8sv00001028sd000001D7*
- ID_MODEL_FROM_DATABASE=XPS M1210
+ ID_MODEL_FROM_DATABASE=G72M [GeForce Go 7400] (XPS M1210)
 
 pci:v000010DEd000001D9*
  ID_MODEL_FROM_DATABASE=G72M [GeForce Go 7450]
@@ -21894,7 +22374,7 @@ pci:v000010DEd000001DE*
  ID_MODEL_FROM_DATABASE=G72GL [Quadro FX 350]
 
 pci:v000010DEd000001DEsv000010DEsd000001DC*
- ID_MODEL_FROM_DATABASE=Quadro  FX Go350M
+ ID_MODEL_FROM_DATABASE=G72GL [Quadro FX 350] (Quadro  FX Go350M)
 
 pci:v000010DEd000001DF*
  ID_MODEL_FROM_DATABASE=G72 [GeForce 7300 GS]
@@ -21903,7 +22383,7 @@ pci:v000010DEd000001E0*
  ID_MODEL_FROM_DATABASE=nForce2 IGP2
 
 pci:v000010DEd000001E0sv0000147Bsd00001C09*
- ID_MODEL_FROM_DATABASE=NV7 Motherboard
+ ID_MODEL_FROM_DATABASE=nForce2 IGP2 (NV7 Motherboard)
 
 pci:v000010DEd000001E8*
  ID_MODEL_FROM_DATABASE=nForce2 AGP
@@ -21912,55 +22392,55 @@ pci:v000010DEd000001EA*
  ID_MODEL_FROM_DATABASE=nForce2 Memory Controller 0
 
 pci:v000010DEd000001EAsv0000A0A0sd000003B9*
- ID_MODEL_FROM_DATABASE=UK79G-1394 motherboard
+ ID_MODEL_FROM_DATABASE=nForce2 Memory Controller 0 (UK79G-1394 motherboard)
 
 pci:v000010DEd000001EB*
  ID_MODEL_FROM_DATABASE=nForce2 Memory Controller 1
 
 pci:v000010DEd000001EBsv0000A0A0sd000003B9*
- ID_MODEL_FROM_DATABASE=UK79G-1394 motherboard
+ ID_MODEL_FROM_DATABASE=nForce2 Memory Controller 1 (UK79G-1394 motherboard)
 
 pci:v000010DEd000001EC*
  ID_MODEL_FROM_DATABASE=nForce2 Memory Controller 2
 
 pci:v000010DEd000001ECsv0000A0A0sd000003B9*
- ID_MODEL_FROM_DATABASE=UK79G-1394 motherboard
+ ID_MODEL_FROM_DATABASE=nForce2 Memory Controller 2 (UK79G-1394 motherboard)
 
 pci:v000010DEd000001ED*
  ID_MODEL_FROM_DATABASE=nForce2 Memory Controller 3
 
 pci:v000010DEd000001EDsv0000A0A0sd000003B9*
- ID_MODEL_FROM_DATABASE=UK79G-1394 motherboard
+ ID_MODEL_FROM_DATABASE=nForce2 Memory Controller 3 (UK79G-1394 motherboard)
 
 pci:v000010DEd000001EE*
  ID_MODEL_FROM_DATABASE=nForce2 Memory Controller 4
 
 pci:v000010DEd000001EEsv000010DEsd000001EE*
- ID_MODEL_FROM_DATABASE=MSI Delta-L nForce2 memory controller
+ ID_MODEL_FROM_DATABASE=nForce2 Memory Controller 4 (MSI Delta-L nForce2 memory controller)
 
 pci:v000010DEd000001EEsv0000A0A0sd000003B9*
- ID_MODEL_FROM_DATABASE=UK79G-1394 motherboard
+ ID_MODEL_FROM_DATABASE=nForce2 Memory Controller 4 (UK79G-1394 motherboard)
 
 pci:v000010DEd000001EF*
  ID_MODEL_FROM_DATABASE=nForce2 Memory Controller 5
 
 pci:v000010DEd000001EFsv0000A0A0sd000003B9*
- ID_MODEL_FROM_DATABASE=UK79G-1394 motherboard
+ ID_MODEL_FROM_DATABASE=nForce2 Memory Controller 5 (UK79G-1394 motherboard)
 
 pci:v000010DEd000001F0*
  ID_MODEL_FROM_DATABASE=C17 [GeForce4 MX IGP]
 
 pci:v000010DEd000001F0sv0000A0A0sd000003B5*
- ID_MODEL_FROM_DATABASE=UK79G-1394 motherboard
+ ID_MODEL_FROM_DATABASE=C17 [GeForce4 MX IGP] (UK79G-1394 motherboard)
 
 pci:v000010DEd00000200*
  ID_MODEL_FROM_DATABASE=NV20 [GeForce3]
 
 pci:v000010DEd00000200sv00001043sd0000402F*
- ID_MODEL_FROM_DATABASE=AGP-V8200 DDR
+ ID_MODEL_FROM_DATABASE=NV20 [GeForce3] (AGP-V8200 DDR)
 
 pci:v000010DEd00000200sv00001048sd00000C70*
- ID_MODEL_FROM_DATABASE=GLADIAC 920
+ ID_MODEL_FROM_DATABASE=NV20 [GeForce3] (GLADIAC 920)
 
 pci:v000010DEd00000201*
  ID_MODEL_FROM_DATABASE=NV20 [GeForce3 Ti 200]
@@ -21969,10 +22449,10 @@ pci:v000010DEd00000202*
  ID_MODEL_FROM_DATABASE=NV20 [GeForce3 Ti 500]
 
 pci:v000010DEd00000202sv00001043sd0000405B*
- ID_MODEL_FROM_DATABASE=V8200 T5
+ ID_MODEL_FROM_DATABASE=NV20 [GeForce3 Ti 500] (V8200 T5)
 
 pci:v000010DEd00000202sv00001545sd0000002F*
- ID_MODEL_FROM_DATABASE=Xtasy 6964
+ ID_MODEL_FROM_DATABASE=NV20 [GeForce3 Ti 500] (Xtasy 6964)
 
 pci:v000010DEd00000203*
  ID_MODEL_FROM_DATABASE=NV20GL [Quadro DCC]
@@ -21993,10 +22473,10 @@ pci:v000010DEd00000221*
  ID_MODEL_FROM_DATABASE=NV44A [GeForce 6200]
 
 pci:v000010DEd00000221sv00001043sd000081E1*
- ID_MODEL_FROM_DATABASE=N6200/TD/256M/A
+ ID_MODEL_FROM_DATABASE=NV44A [GeForce 6200] (N6200/TD/256M/A)
 
 pci:v000010DEd00000221sv00003842sd0000A341*
- ID_MODEL_FROM_DATABASE=256A8N341DX
+ ID_MODEL_FROM_DATABASE=NV44A [GeForce 6200] (256A8N341DX)
 
 pci:v000010DEd00000222*
  ID_MODEL_FROM_DATABASE=NV44 [GeForce 6200 A-LE]
@@ -22008,10 +22488,10 @@ pci:v000010DEd00000240*
  ID_MODEL_FROM_DATABASE=C51PV [GeForce 6150]
 
 pci:v000010DEd00000240sv00001043sd000081CD*
- ID_MODEL_FROM_DATABASE=A8N-VM CSM
+ ID_MODEL_FROM_DATABASE=C51PV [GeForce 6150] (A8N-VM CSM)
 
 pci:v000010DEd00000240sv00001462sd00007207*
- ID_MODEL_FROM_DATABASE=K8NGM2 series
+ ID_MODEL_FROM_DATABASE=C51PV [GeForce 6150] (K8NGM2 series)
 
 pci:v000010DEd00000241*
  ID_MODEL_FROM_DATABASE=C51 [GeForce 6150 LE]
@@ -22020,7 +22500,7 @@ pci:v000010DEd00000242*
  ID_MODEL_FROM_DATABASE=C51G [GeForce 6100]
 
 pci:v000010DEd00000242sv0000105Bsd00000CAD*
- ID_MODEL_FROM_DATABASE=Winfast 6100K8MB
+ ID_MODEL_FROM_DATABASE=C51G [GeForce 6100] (Winfast 6100K8MB)
 
 pci:v000010DEd00000243*
  ID_MODEL_FROM_DATABASE=C51 PCI Express Bridge
@@ -22029,13 +22509,13 @@ pci:v000010DEd00000244*
  ID_MODEL_FROM_DATABASE=C51 [GeForce Go 6150]
 
 pci:v000010DEd00000244sv0000103Csd000030B5*
- ID_MODEL_FROM_DATABASE=Presario V3242AU
+ ID_MODEL_FROM_DATABASE=C51 [GeForce Go 6150] (Presario V3242AU)
 
 pci:v000010DEd00000244sv0000103Csd000030B7*
- ID_MODEL_FROM_DATABASE=Presario V6133CL
+ ID_MODEL_FROM_DATABASE=C51 [GeForce Go 6150] (Presario V6133CL)
 
 pci:v000010DEd00000244sv000010DEsd00000244*
- ID_MODEL_FROM_DATABASE=GeForce Go 6150
+ ID_MODEL_FROM_DATABASE=C51 [GeForce Go 6150] (GeForce Go 6150)
 
 pci:v000010DEd00000245*
  ID_MODEL_FROM_DATABASE=C51 [Quadro NVS 210S/GeForce 6150LE]
@@ -22047,7 +22527,7 @@ pci:v000010DEd00000247*
  ID_MODEL_FROM_DATABASE=C51 [GeForce Go 6100]
 
 pci:v000010DEd00000247sv00001043sd00001382*
- ID_MODEL_FROM_DATABASE=MCP51 PCI-X GeForce Go 6100
+ ID_MODEL_FROM_DATABASE=C51 [GeForce Go 6100] (MCP51 PCI-X GeForce Go 6100)
 
 pci:v000010DEd00000248*
  ID_MODEL_FROM_DATABASE=C51 PCI Express Bridge
@@ -22080,13 +22560,13 @@ pci:v000010DEd00000251*
  ID_MODEL_FROM_DATABASE=NV25 [GeForce4 Ti 4400]
 
 pci:v000010DEd00000251sv00001043sd00008023*
- ID_MODEL_FROM_DATABASE=v8440 GeForce 4 Ti4400
+ ID_MODEL_FROM_DATABASE=NV25 [GeForce4 Ti 4400] (v8440 GeForce 4 Ti4400)
 
 pci:v000010DEd00000251sv000010DEsd00000251*
- ID_MODEL_FROM_DATABASE=PNY GeForce4 Ti 4400
+ ID_MODEL_FROM_DATABASE=NV25 [GeForce4 Ti 4400] (PNY GeForce4 Ti 4400)
 
 pci:v000010DEd00000251sv00001462sd00008710*
- ID_MODEL_FROM_DATABASE=PNY GeForce4 Ti 4400
+ ID_MODEL_FROM_DATABASE=NV25 [GeForce4 Ti 4400] (PNY GeForce4 Ti 4400)
 
 pci:v000010DEd00000252*
  ID_MODEL_FROM_DATABASE=NV25 [GeForce4 Ti]
@@ -22095,10 +22575,10 @@ pci:v000010DEd00000253*
  ID_MODEL_FROM_DATABASE=NV25 [GeForce4 Ti 4200]
 
 pci:v000010DEd00000253sv0000107Dsd00002896*
- ID_MODEL_FROM_DATABASE=WinFast A250 LE TD (Dual VGA/TV-out/DVI)
+ ID_MODEL_FROM_DATABASE=NV25 [GeForce4 Ti 4200] (WinFast A250 LE TD (Dual VGA/TV-out/DVI))
 
 pci:v000010DEd00000253sv0000147Bsd00008F09*
- ID_MODEL_FROM_DATABASE=Siluro (Dual VGA/TV-out/DVI)
+ ID_MODEL_FROM_DATABASE=NV25 [GeForce4 Ti 4200] (Siluro (Dual VGA/TV-out/DVI))
 
 pci:v000010DEd00000258*
  ID_MODEL_FROM_DATABASE=NV25GL [Quadro4 900 XGL]
@@ -22113,25 +22593,25 @@ pci:v000010DEd00000260*
  ID_MODEL_FROM_DATABASE=MCP51 LPC Bridge
 
 pci:v000010DEd00000260sv0000103Csd00002A34*
- ID_MODEL_FROM_DATABASE=Pavilion a1677c
+ ID_MODEL_FROM_DATABASE=MCP51 LPC Bridge (Pavilion a1677c)
 
 pci:v000010DEd00000260sv0000103Csd000030B7*
- ID_MODEL_FROM_DATABASE=Presario V6133CL
+ ID_MODEL_FROM_DATABASE=MCP51 LPC Bridge (Presario V6133CL)
 
 pci:v000010DEd00000260sv00001043sd000081BC*
- ID_MODEL_FROM_DATABASE=A8N-VM CSM Mainboard
+ ID_MODEL_FROM_DATABASE=MCP51 LPC Bridge (A8N-VM CSM Mainboard)
 
 pci:v000010DEd00000260sv00001458sd00005001*
- ID_MODEL_FROM_DATABASE=GA-M55plus-S3G
+ ID_MODEL_FROM_DATABASE=MCP51 LPC Bridge (GA-M55plus-S3G)
 
 pci:v000010DEd00000260sv00001462sd00007207*
- ID_MODEL_FROM_DATABASE=K8NGM2 series
+ ID_MODEL_FROM_DATABASE=MCP51 LPC Bridge (K8NGM2 series)
 
 pci:v000010DEd00000261*
  ID_MODEL_FROM_DATABASE=MCP51 LPC Bridge
 
 pci:v000010DEd00000261sv0000105Bsd00000CAD*
- ID_MODEL_FROM_DATABASE=Winfast 6100K8MB
+ ID_MODEL_FROM_DATABASE=MCP51 LPC Bridge (Winfast 6100K8MB)
 
 pci:v000010DEd00000262*
  ID_MODEL_FROM_DATABASE=MCP51 LPC Bridge
@@ -22143,64 +22623,64 @@ pci:v000010DEd00000264*
  ID_MODEL_FROM_DATABASE=MCP51 SMBus
 
 pci:v000010DEd00000264sv0000103Csd00002A34*
- ID_MODEL_FROM_DATABASE=Pavilion a1677c
+ ID_MODEL_FROM_DATABASE=MCP51 SMBus (Pavilion a1677c)
 
 pci:v000010DEd00000264sv0000103Csd000030B7*
- ID_MODEL_FROM_DATABASE=Presario V6133CL
+ ID_MODEL_FROM_DATABASE=MCP51 SMBus (Presario V6133CL)
 
 pci:v000010DEd00000264sv00001043sd000081BC*
- ID_MODEL_FROM_DATABASE=A8N-VM CSM Mainboard
+ ID_MODEL_FROM_DATABASE=MCP51 SMBus (A8N-VM CSM Mainboard)
 
 pci:v000010DEd00000264sv0000105Bsd00000CAD*
- ID_MODEL_FROM_DATABASE=Winfast 6100K8MB
+ ID_MODEL_FROM_DATABASE=MCP51 SMBus (Winfast 6100K8MB)
 
 pci:v000010DEd00000264sv00001462sd00007207*
- ID_MODEL_FROM_DATABASE=K8NGM2 series
+ ID_MODEL_FROM_DATABASE=MCP51 SMBus (K8NGM2 series)
 
 pci:v000010DEd00000265*
  ID_MODEL_FROM_DATABASE=MCP51 IDE
 
 pci:v000010DEd00000265sv0000103Csd00002A34*
- ID_MODEL_FROM_DATABASE=Pavilion a1677c
+ ID_MODEL_FROM_DATABASE=MCP51 IDE (Pavilion a1677c)
 
 pci:v000010DEd00000265sv0000103Csd000030B7*
- ID_MODEL_FROM_DATABASE=Presario V6133CL
+ ID_MODEL_FROM_DATABASE=MCP51 IDE (Presario V6133CL)
 
 pci:v000010DEd00000265sv00001043sd000081BC*
- ID_MODEL_FROM_DATABASE=A8N-VM CSM Mainboard
+ ID_MODEL_FROM_DATABASE=MCP51 IDE (A8N-VM CSM Mainboard)
 
 pci:v000010DEd00000265sv00001462sd00007207*
- ID_MODEL_FROM_DATABASE=K8NGM2 series
+ ID_MODEL_FROM_DATABASE=MCP51 IDE (K8NGM2 series)
 
 pci:v000010DEd00000265sv0000F05Bsd00000CAD*
- ID_MODEL_FROM_DATABASE=Winfast 6100K8MB
+ ID_MODEL_FROM_DATABASE=MCP51 IDE (Winfast 6100K8MB)
 
 pci:v000010DEd00000266*
  ID_MODEL_FROM_DATABASE=MCP51 Serial ATA Controller
 
 pci:v000010DEd00000266sv0000103Csd00002A34*
- ID_MODEL_FROM_DATABASE=Pavilion a1677c
+ ID_MODEL_FROM_DATABASE=MCP51 Serial ATA Controller (Pavilion a1677c)
 
 pci:v000010DEd00000266sv0000103Csd000030B7*
- ID_MODEL_FROM_DATABASE=Presario V6133CL
+ ID_MODEL_FROM_DATABASE=MCP51 Serial ATA Controller (Presario V6133CL)
 
 pci:v000010DEd00000266sv00001043sd000081BC*
- ID_MODEL_FROM_DATABASE=A8N-VM CSM Mainboard
+ ID_MODEL_FROM_DATABASE=MCP51 Serial ATA Controller (A8N-VM CSM Mainboard)
 
 pci:v000010DEd00000266sv00001462sd00007207*
- ID_MODEL_FROM_DATABASE=K8NGM2 series
+ ID_MODEL_FROM_DATABASE=MCP51 Serial ATA Controller (K8NGM2 series)
 
 pci:v000010DEd00000267*
  ID_MODEL_FROM_DATABASE=MCP51 Serial ATA Controller
 
 pci:v000010DEd00000267sv0000103Csd00002A34*
- ID_MODEL_FROM_DATABASE=Pavilion a1677c
+ ID_MODEL_FROM_DATABASE=MCP51 Serial ATA Controller (Pavilion a1677c)
 
 pci:v000010DEd00000267sv00001043sd000081BC*
- ID_MODEL_FROM_DATABASE=A8N-VM CSM Mainboard
+ ID_MODEL_FROM_DATABASE=MCP51 Serial ATA Controller (A8N-VM CSM Mainboard)
 
 pci:v000010DEd00000267sv00001462sd00007207*
- ID_MODEL_FROM_DATABASE=K8NGM2 series
+ ID_MODEL_FROM_DATABASE=MCP51 Serial ATA Controller (K8NGM2 series)
 
 pci:v000010DEd00000268*
  ID_MODEL_FROM_DATABASE=MCP51 Ethernet Controller
@@ -22209,16 +22689,16 @@ pci:v000010DEd00000269*
  ID_MODEL_FROM_DATABASE=MCP51 Ethernet Controller
 
 pci:v000010DEd00000269sv0000103Csd00002A34*
- ID_MODEL_FROM_DATABASE=Pavilion a1677c
+ ID_MODEL_FROM_DATABASE=MCP51 Ethernet Controller (Pavilion a1677c)
 
 pci:v000010DEd00000269sv0000103Csd000030B7*
- ID_MODEL_FROM_DATABASE=Presario V6133CL
+ ID_MODEL_FROM_DATABASE=MCP51 Ethernet Controller (Presario V6133CL)
 
 pci:v000010DEd00000269sv00001043sd00008141*
- ID_MODEL_FROM_DATABASE=A8N-VM CSM Mainboard
+ ID_MODEL_FROM_DATABASE=MCP51 Ethernet Controller (A8N-VM CSM Mainboard)
 
 pci:v000010DEd00000269sv00001462sd00007207*
- ID_MODEL_FROM_DATABASE=K8NGM2 series
+ ID_MODEL_FROM_DATABASE=MCP51 Ethernet Controller (K8NGM2 series)
 
 pci:v000010DEd0000026A*
  ID_MODEL_FROM_DATABASE=MCP51 MCI
@@ -22227,142 +22707,142 @@ pci:v000010DEd0000026B*
  ID_MODEL_FROM_DATABASE=MCP51 AC97 Audio Controller
 
 pci:v000010DEd0000026Bsv0000105Bsd00000CAD*
- ID_MODEL_FROM_DATABASE=Winfast 6100K8MB
+ ID_MODEL_FROM_DATABASE=MCP51 AC97 Audio Controller (Winfast 6100K8MB)
 
 pci:v000010DEd0000026C*
  ID_MODEL_FROM_DATABASE=MCP51 High Definition Audio
 
 pci:v000010DEd0000026Csv0000103Csd00002A34*
- ID_MODEL_FROM_DATABASE=Pavilion a1677c
+ ID_MODEL_FROM_DATABASE=MCP51 High Definition Audio (Pavilion a1677c)
 
 pci:v000010DEd0000026Csv0000103Csd000030B5*
- ID_MODEL_FROM_DATABASE=Presario V3242AU
+ ID_MODEL_FROM_DATABASE=MCP51 High Definition Audio (Presario V3242AU)
 
 pci:v000010DEd0000026Csv0000103Csd000030B7*
- ID_MODEL_FROM_DATABASE=Presario V6133CL
+ ID_MODEL_FROM_DATABASE=MCP51 High Definition Audio (Presario V6133CL)
 
 pci:v000010DEd0000026Csv000010DEsd0000CB84*
- ID_MODEL_FROM_DATABASE=ASUSTeK Computer Inc. A8N-VM CSM Mainboard
+ ID_MODEL_FROM_DATABASE=MCP51 High Definition Audio (ASUSTeK Computer Inc. A8N-VM CSM Mainboard)
 
 pci:v000010DEd0000026Csv00001462sd00007207*
- ID_MODEL_FROM_DATABASE=K8NGM2 series
+ ID_MODEL_FROM_DATABASE=MCP51 High Definition Audio (K8NGM2 series)
 
 pci:v000010DEd0000026D*
  ID_MODEL_FROM_DATABASE=MCP51 USB Controller
 
 pci:v000010DEd0000026Dsv0000103Csd00002A34*
- ID_MODEL_FROM_DATABASE=Pavilion a1677c
+ ID_MODEL_FROM_DATABASE=MCP51 USB Controller (Pavilion a1677c)
 
 pci:v000010DEd0000026Dsv0000103Csd000030B7*
- ID_MODEL_FROM_DATABASE=Presario V6133CL
+ ID_MODEL_FROM_DATABASE=MCP51 USB Controller (Presario V6133CL)
 
 pci:v000010DEd0000026Dsv00001043sd000081BC*
- ID_MODEL_FROM_DATABASE=A8N-VM CSM Mainboard
+ ID_MODEL_FROM_DATABASE=MCP51 USB Controller (A8N-VM CSM Mainboard)
 
 pci:v000010DEd0000026Dsv0000105Bsd00000CAD*
- ID_MODEL_FROM_DATABASE=Winfast 6100K8MB
+ ID_MODEL_FROM_DATABASE=MCP51 USB Controller (Winfast 6100K8MB)
 
 pci:v000010DEd0000026Dsv00001462sd00007207*
- ID_MODEL_FROM_DATABASE=K8NGM2 series
+ ID_MODEL_FROM_DATABASE=MCP51 USB Controller (K8NGM2 series)
 
 pci:v000010DEd0000026E*
  ID_MODEL_FROM_DATABASE=MCP51 USB Controller
 
 pci:v000010DEd0000026Esv0000103Csd00002A34*
- ID_MODEL_FROM_DATABASE=Pavilion a1677c
+ ID_MODEL_FROM_DATABASE=MCP51 USB Controller (Pavilion a1677c)
 
 pci:v000010DEd0000026Esv0000103Csd000030B7*
- ID_MODEL_FROM_DATABASE=Presario V6133CL
+ ID_MODEL_FROM_DATABASE=MCP51 USB Controller (Presario V6133CL)
 
 pci:v000010DEd0000026Esv00001043sd000081BC*
- ID_MODEL_FROM_DATABASE=A8N-VM CSM Mainboard
+ ID_MODEL_FROM_DATABASE=MCP51 USB Controller (A8N-VM CSM Mainboard)
 
 pci:v000010DEd0000026Esv0000105Bsd00000CAD*
- ID_MODEL_FROM_DATABASE=Winfast 6100K8MB
+ ID_MODEL_FROM_DATABASE=MCP51 USB Controller (Winfast 6100K8MB)
 
 pci:v000010DEd0000026Esv00001462sd00007207*
- ID_MODEL_FROM_DATABASE=K8NGM2 series
+ ID_MODEL_FROM_DATABASE=MCP51 USB Controller (K8NGM2 series)
 
 pci:v000010DEd0000026F*
  ID_MODEL_FROM_DATABASE=MCP51 PCI Bridge
 
 pci:v000010DEd0000026Fsv0000103Csd000030B7*
- ID_MODEL_FROM_DATABASE=Presario V6133CL
+ ID_MODEL_FROM_DATABASE=MCP51 PCI Bridge (Presario V6133CL)
 
 pci:v000010DEd00000270*
  ID_MODEL_FROM_DATABASE=MCP51 Host Bridge
 
 pci:v000010DEd00000270sv0000103Csd00002A34*
- ID_MODEL_FROM_DATABASE=Pavilion a1677c
+ ID_MODEL_FROM_DATABASE=MCP51 Host Bridge (Pavilion a1677c)
 
 pci:v000010DEd00000270sv0000103Csd000030B7*
- ID_MODEL_FROM_DATABASE=Presario V6133CL
+ ID_MODEL_FROM_DATABASE=MCP51 Host Bridge (Presario V6133CL)
 
 pci:v000010DEd00000270sv00001043sd000081BC*
- ID_MODEL_FROM_DATABASE=A8N-VM CSM Mainboard
+ ID_MODEL_FROM_DATABASE=MCP51 Host Bridge (A8N-VM CSM Mainboard)
 
 pci:v000010DEd00000270sv0000105Bsd00000CAD*
- ID_MODEL_FROM_DATABASE=Winfast 6100K8MB
+ ID_MODEL_FROM_DATABASE=MCP51 Host Bridge (Winfast 6100K8MB)
 
 pci:v000010DEd00000270sv00001458sd00005001*
- ID_MODEL_FROM_DATABASE=GA-M55plus-S3G
+ ID_MODEL_FROM_DATABASE=MCP51 Host Bridge (GA-M55plus-S3G)
 
 pci:v000010DEd00000270sv00001462sd00007207*
- ID_MODEL_FROM_DATABASE=K8NGM2 series
+ ID_MODEL_FROM_DATABASE=MCP51 Host Bridge (K8NGM2 series)
 
 pci:v000010DEd00000271*
  ID_MODEL_FROM_DATABASE=MCP51 PMU
 
 pci:v000010DEd00000271sv0000103Csd000030B5*
- ID_MODEL_FROM_DATABASE=Presario V3242AU
+ ID_MODEL_FROM_DATABASE=MCP51 PMU (Presario V3242AU)
 
 pci:v000010DEd00000271sv0000103Csd000030B7*
- ID_MODEL_FROM_DATABASE=Presario V6133CL
+ ID_MODEL_FROM_DATABASE=MCP51 PMU (Presario V6133CL)
 
 pci:v000010DEd00000272*
  ID_MODEL_FROM_DATABASE=MCP51 Memory Controller 0
 
 pci:v000010DEd00000272sv0000103Csd00002A34*
- ID_MODEL_FROM_DATABASE=Pavilion a1677c
+ ID_MODEL_FROM_DATABASE=MCP51 Memory Controller 0 (Pavilion a1677c)
 
 pci:v000010DEd00000272sv0000105Bsd00000CAD*
- ID_MODEL_FROM_DATABASE=Winfast 6100K8MB
+ ID_MODEL_FROM_DATABASE=MCP51 Memory Controller 0 (Winfast 6100K8MB)
 
 pci:v000010DEd0000027E*
  ID_MODEL_FROM_DATABASE=C51 Memory Controller 2
 
 pci:v000010DEd0000027Esv0000103Csd00002A34*
- ID_MODEL_FROM_DATABASE=Pavilion a1677c
+ ID_MODEL_FROM_DATABASE=C51 Memory Controller 2 (Pavilion a1677c)
 
 pci:v000010DEd0000027Esv0000103Csd000030B7*
- ID_MODEL_FROM_DATABASE=Presario V6133CL
+ ID_MODEL_FROM_DATABASE=C51 Memory Controller 2 (Presario V6133CL)
 
 pci:v000010DEd0000027Esv00001043sd000081CD*
- ID_MODEL_FROM_DATABASE=A8N-VM CSM Mainboard
+ ID_MODEL_FROM_DATABASE=C51 Memory Controller 2 (A8N-VM CSM Mainboard)
 
 pci:v000010DEd0000027Esv00001458sd00005000*
- ID_MODEL_FROM_DATABASE=GA-M55plus-S3G
+ ID_MODEL_FROM_DATABASE=C51 Memory Controller 2 (GA-M55plus-S3G)
 
 pci:v000010DEd0000027Esv00001462sd00007207*
- ID_MODEL_FROM_DATABASE=K8NGM2 series
+ ID_MODEL_FROM_DATABASE=C51 Memory Controller 2 (K8NGM2 series)
 
 pci:v000010DEd0000027F*
  ID_MODEL_FROM_DATABASE=C51 Memory Controller 3
 
 pci:v000010DEd0000027Fsv0000103Csd00002A34*
- ID_MODEL_FROM_DATABASE=Pavilion a1677c
+ ID_MODEL_FROM_DATABASE=C51 Memory Controller 3 (Pavilion a1677c)
 
 pci:v000010DEd0000027Fsv0000103Csd000030B7*
- ID_MODEL_FROM_DATABASE=Presario V6133CL
+ ID_MODEL_FROM_DATABASE=C51 Memory Controller 3 (Presario V6133CL)
 
 pci:v000010DEd0000027Fsv00001043sd000081CD*
- ID_MODEL_FROM_DATABASE=A8N-VM CSM Mainboard
+ ID_MODEL_FROM_DATABASE=C51 Memory Controller 3 (A8N-VM CSM Mainboard)
 
 pci:v000010DEd0000027Fsv00001458sd00005000*
- ID_MODEL_FROM_DATABASE=GA-M55plus-S3G
+ ID_MODEL_FROM_DATABASE=C51 Memory Controller 3 (GA-M55plus-S3G)
 
 pci:v000010DEd0000027Fsv00001462sd00007207*
- ID_MODEL_FROM_DATABASE=K8NGM2 series
+ ID_MODEL_FROM_DATABASE=C51 Memory Controller 3 (K8NGM2 series)
 
 pci:v000010DEd00000280*
  ID_MODEL_FROM_DATABASE=NV28 [GeForce4 Ti 4800]
@@ -22392,7 +22872,7 @@ pci:v000010DEd00000291*
  ID_MODEL_FROM_DATABASE=G71 [GeForce 7900 GT/GTO]
 
 pci:v000010DEd00000291sv000010DEsd0000042B*
- ID_MODEL_FROM_DATABASE=NX7900GTO-T2D512E [7900 GTO]
+ ID_MODEL_FROM_DATABASE=G71 [GeForce 7900 GT/GTO] (NX7900GTO-T2D512E [7900 GTO])
 
 pci:v000010DEd00000292*
  ID_MODEL_FROM_DATABASE=G71 [GeForce 7900 GS]
@@ -22407,13 +22887,13 @@ pci:v000010DEd00000295*
  ID_MODEL_FROM_DATABASE=G71 [GeForce 7950 GT]
 
 pci:v000010DEd00000295sv00001043sd00008225*
- ID_MODEL_FROM_DATABASE=GeForce 7950 GT
+ ID_MODEL_FROM_DATABASE=G71 [GeForce 7950 GT] (GeForce 7950 GT)
 
 pci:v000010DEd00000295sv0000107Dsd00002A68*
- ID_MODEL_FROM_DATABASE=WinFast PX7950GT TDH
+ ID_MODEL_FROM_DATABASE=G71 [GeForce 7950 GT] (WinFast PX7950GT TDH)
 
 pci:v000010DEd00000295sv00001462sd00000663*
- ID_MODEL_FROM_DATABASE=NX7950GT-VT2D512EZ-HD
+ ID_MODEL_FROM_DATABASE=G71 [GeForce 7950 GT] (NX7950GT-VT2D512EZ-HD)
 
 pci:v000010DEd00000297*
  ID_MODEL_FROM_DATABASE=G71M [GeForce Go 7950 GTX]
@@ -22437,7 +22917,7 @@ pci:v000010DEd0000029D*
  ID_MODEL_FROM_DATABASE=G71GL [Quadro FX 3500]
 
 pci:v000010DEd0000029Dsv00001028sd0000019B*
- ID_MODEL_FROM_DATABASE=G71GLM [Quadro FX 3500M]
+ ID_MODEL_FROM_DATABASE=G71GL [Quadro FX 3500] (G71GLM [Quadro FX 3500M])
 
 pci:v000010DEd0000029E*
  ID_MODEL_FROM_DATABASE=G71GL [Quadro FX 1500]
@@ -22458,16 +22938,16 @@ pci:v000010DEd000002E0*
  ID_MODEL_FROM_DATABASE=G73 [GeForce 7600 GT]
 
 pci:v000010DEd000002E0sv000002E0sd00002249*
- ID_MODEL_FROM_DATABASE=GF 7600GT 560M 256MB DDR3 DUAL DVI TV
+ ID_MODEL_FROM_DATABASE=G73 [GeForce 7600 GT] (GF 7600GT 560M 256MB DDR3 DUAL DVI TV)
 
 pci:v000010DEd000002E1*
  ID_MODEL_FROM_DATABASE=G73 [GeForce 7600 GS]
 
 pci:v000010DEd000002E1sv00001682sd0000222B*
- ID_MODEL_FROM_DATABASE=PV-T73K-UAL3 (256MB)
+ ID_MODEL_FROM_DATABASE=G73 [GeForce 7600 GS] (PV-T73K-UAL3 (256MB))
 
 pci:v000010DEd000002E1sv00001682sd00002247*
- ID_MODEL_FROM_DATABASE=GF 7600GS 512MB DDR2
+ ID_MODEL_FROM_DATABASE=G73 [GeForce 7600 GS] (GF 7600GS 512MB DDR2)
 
 pci:v000010DEd000002E2*
  ID_MODEL_FROM_DATABASE=G73 [GeForce 7300 GT]
@@ -22479,28 +22959,28 @@ pci:v000010DEd000002E4*
  ID_MODEL_FROM_DATABASE=G71 [GeForce 7950 GT]
 
 pci:v000010DEd000002E4sv00001682sd00002271*
- ID_MODEL_FROM_DATABASE=PV-T71A-YDF7 (512MB)
+ ID_MODEL_FROM_DATABASE=G71 [GeForce 7950 GT] (PV-T71A-YDF7 (512MB))
 
 pci:v000010DEd000002F0*
  ID_MODEL_FROM_DATABASE=C51 Host Bridge
 
 pci:v000010DEd000002F0sv0000103Csd00002A34*
- ID_MODEL_FROM_DATABASE=Pavilion a1677c
+ ID_MODEL_FROM_DATABASE=C51 Host Bridge (Pavilion a1677c)
 
 pci:v000010DEd000002F0sv0000103Csd000030B7*
- ID_MODEL_FROM_DATABASE=Presario V6133CL
+ ID_MODEL_FROM_DATABASE=C51 Host Bridge (Presario V6133CL)
 
 pci:v000010DEd000002F0sv00001043sd000081CD*
- ID_MODEL_FROM_DATABASE=A8N-VM CSM Mainboard
+ ID_MODEL_FROM_DATABASE=C51 Host Bridge (A8N-VM CSM Mainboard)
 
 pci:v000010DEd000002F0sv00001462sd00007207*
- ID_MODEL_FROM_DATABASE=K8NGM2 series
+ ID_MODEL_FROM_DATABASE=C51 Host Bridge (K8NGM2 series)
 
 pci:v000010DEd000002F1*
  ID_MODEL_FROM_DATABASE=C51 Host Bridge
 
 pci:v000010DEd000002F1sv00001458sd00005000*
- ID_MODEL_FROM_DATABASE=GA-M55plus-S3G
+ ID_MODEL_FROM_DATABASE=C51 Host Bridge (GA-M55plus-S3G)
 
 pci:v000010DEd000002F2*
  ID_MODEL_FROM_DATABASE=C51 Host Bridge
@@ -22524,55 +23004,55 @@ pci:v000010DEd000002F8*
  ID_MODEL_FROM_DATABASE=C51 Memory Controller 5
 
 pci:v000010DEd000002F8sv0000103Csd00002A34*
- ID_MODEL_FROM_DATABASE=Pavilion a1677c
+ ID_MODEL_FROM_DATABASE=C51 Memory Controller 5 (Pavilion a1677c)
 
 pci:v000010DEd000002F8sv0000103Csd000030B7*
- ID_MODEL_FROM_DATABASE=Presario V6133CL
+ ID_MODEL_FROM_DATABASE=C51 Memory Controller 5 (Presario V6133CL)
 
 pci:v000010DEd000002F8sv00001043sd000081CD*
- ID_MODEL_FROM_DATABASE=A8N-VM CSM Mainboard
+ ID_MODEL_FROM_DATABASE=C51 Memory Controller 5 (A8N-VM CSM Mainboard)
 
 pci:v000010DEd000002F8sv00001458sd00005000*
- ID_MODEL_FROM_DATABASE=GA-M55plus-S3G
+ ID_MODEL_FROM_DATABASE=C51 Memory Controller 5 (GA-M55plus-S3G)
 
 pci:v000010DEd000002F8sv00001462sd00007207*
- ID_MODEL_FROM_DATABASE=K8NGM2 series
+ ID_MODEL_FROM_DATABASE=C51 Memory Controller 5 (K8NGM2 series)
 
 pci:v000010DEd000002F9*
  ID_MODEL_FROM_DATABASE=C51 Memory Controller 4
 
 pci:v000010DEd000002F9sv0000103Csd00002A34*
- ID_MODEL_FROM_DATABASE=Pavilion a1677c
+ ID_MODEL_FROM_DATABASE=C51 Memory Controller 4 (Pavilion a1677c)
 
 pci:v000010DEd000002F9sv0000103Csd000030B7*
- ID_MODEL_FROM_DATABASE=Presario V6133CL
+ ID_MODEL_FROM_DATABASE=C51 Memory Controller 4 (Presario V6133CL)
 
 pci:v000010DEd000002F9sv00001043sd000081CD*
- ID_MODEL_FROM_DATABASE=A8N-VM CSM Mainboard
+ ID_MODEL_FROM_DATABASE=C51 Memory Controller 4 (A8N-VM CSM Mainboard)
 
 pci:v000010DEd000002F9sv00001458sd00005000*
- ID_MODEL_FROM_DATABASE=GA-M55plus-S3G
+ ID_MODEL_FROM_DATABASE=C51 Memory Controller 4 (GA-M55plus-S3G)
 
 pci:v000010DEd000002F9sv00001462sd00007207*
- ID_MODEL_FROM_DATABASE=K8NGM2 series
+ ID_MODEL_FROM_DATABASE=C51 Memory Controller 4 (K8NGM2 series)
 
 pci:v000010DEd000002FA*
  ID_MODEL_FROM_DATABASE=C51 Memory Controller 0
 
 pci:v000010DEd000002FAsv0000103Csd00002A34*
- ID_MODEL_FROM_DATABASE=Pavilion a1677c
+ ID_MODEL_FROM_DATABASE=C51 Memory Controller 0 (Pavilion a1677c)
 
 pci:v000010DEd000002FAsv0000103Csd000030B7*
- ID_MODEL_FROM_DATABASE=Presario V6133CL
+ ID_MODEL_FROM_DATABASE=C51 Memory Controller 0 (Presario V6133CL)
 
 pci:v000010DEd000002FAsv00001043sd000081CD*
- ID_MODEL_FROM_DATABASE=A8N-VM CSM Mainboard
+ ID_MODEL_FROM_DATABASE=C51 Memory Controller 0 (A8N-VM CSM Mainboard)
 
 pci:v000010DEd000002FAsv00001458sd00005000*
- ID_MODEL_FROM_DATABASE=GA-M55plus-S3G
+ ID_MODEL_FROM_DATABASE=C51 Memory Controller 0 (GA-M55plus-S3G)
 
 pci:v000010DEd000002FAsv00001462sd00007207*
- ID_MODEL_FROM_DATABASE=K8NGM2 series
+ ID_MODEL_FROM_DATABASE=C51 Memory Controller 0 (K8NGM2 series)
 
 pci:v000010DEd000002FB*
  ID_MODEL_FROM_DATABASE=C51 PCI Express Bridge
@@ -22581,49 +23061,49 @@ pci:v000010DEd000002FC*
  ID_MODEL_FROM_DATABASE=C51 PCI Express Bridge
 
 pci:v000010DEd000002FCsv0000103Csd000030B7*
- ID_MODEL_FROM_DATABASE=Presario V6133CL
+ ID_MODEL_FROM_DATABASE=C51 PCI Express Bridge (Presario V6133CL)
 
 pci:v000010DEd000002FD*
  ID_MODEL_FROM_DATABASE=C51 PCI Express Bridge
 
 pci:v000010DEd000002FDsv0000103Csd000030B7*
- ID_MODEL_FROM_DATABASE=Presario V6133CL
+ ID_MODEL_FROM_DATABASE=C51 PCI Express Bridge (Presario V6133CL)
 
 pci:v000010DEd000002FE*
  ID_MODEL_FROM_DATABASE=C51 Memory Controller 1
 
 pci:v000010DEd000002FEsv0000103Csd00002A34*
- ID_MODEL_FROM_DATABASE=Pavilion a1677c
+ ID_MODEL_FROM_DATABASE=C51 Memory Controller 1 (Pavilion a1677c)
 
 pci:v000010DEd000002FEsv0000103Csd000030B7*
- ID_MODEL_FROM_DATABASE=Presario V6133CL
+ ID_MODEL_FROM_DATABASE=C51 Memory Controller 1 (Presario V6133CL)
 
 pci:v000010DEd000002FEsv00001043sd000081CD*
- ID_MODEL_FROM_DATABASE=A8N-VM CSM Mainboard
+ ID_MODEL_FROM_DATABASE=C51 Memory Controller 1 (A8N-VM CSM Mainboard)
 
 pci:v000010DEd000002FEsv00001458sd00005000*
- ID_MODEL_FROM_DATABASE=GA-M55plus-S3G
+ ID_MODEL_FROM_DATABASE=C51 Memory Controller 1 (GA-M55plus-S3G)
 
 pci:v000010DEd000002FEsv00001462sd00007207*
- ID_MODEL_FROM_DATABASE=K8NGM2 series
+ ID_MODEL_FROM_DATABASE=C51 Memory Controller 1 (K8NGM2 series)
 
 pci:v000010DEd000002FF*
  ID_MODEL_FROM_DATABASE=C51 Host Bridge
 
 pci:v000010DEd000002FFsv0000103Csd00002A34*
- ID_MODEL_FROM_DATABASE=Pavilion a1677c
+ ID_MODEL_FROM_DATABASE=C51 Host Bridge (Pavilion a1677c)
 
 pci:v000010DEd000002FFsv0000103Csd000030B7*
- ID_MODEL_FROM_DATABASE=Presario V6133CL
+ ID_MODEL_FROM_DATABASE=C51 Host Bridge (Presario V6133CL)
 
 pci:v000010DEd000002FFsv00001043sd000081CD*
- ID_MODEL_FROM_DATABASE=A8N-VM CSM Mainboard
+ ID_MODEL_FROM_DATABASE=C51 Host Bridge (A8N-VM CSM Mainboard)
 
 pci:v000010DEd000002FFsv00001458sd00005000*
- ID_MODEL_FROM_DATABASE=GA-M55plus-S3G
+ ID_MODEL_FROM_DATABASE=C51 Host Bridge (GA-M55plus-S3G)
 
 pci:v000010DEd000002FFsv00001462sd00007207*
- ID_MODEL_FROM_DATABASE=K8NGM2 series
+ ID_MODEL_FROM_DATABASE=C51 Host Bridge (K8NGM2 series)
 
 pci:v000010DEd00000300*
  ID_MODEL_FROM_DATABASE=NV30 [GeForce FX]
@@ -22650,7 +23130,7 @@ pci:v000010DEd00000314*
  ID_MODEL_FROM_DATABASE=NV31 [GeForce FX 5600XT]
 
 pci:v000010DEd00000314sv00001043sd0000814A*
- ID_MODEL_FROM_DATABASE=V9560XT/TD
+ ID_MODEL_FROM_DATABASE=NV31 [GeForce FX 5600XT] (V9560XT/TD)
 
 pci:v000010DEd00000316*
  ID_MODEL_FROM_DATABASE=NV31M
@@ -22677,25 +23157,25 @@ pci:v000010DEd00000322*
  ID_MODEL_FROM_DATABASE=NV34 [GeForce FX 5200]
 
 pci:v000010DEd00000322sv00001043sd000002FB*
- ID_MODEL_FROM_DATABASE=V9250 Magic
+ ID_MODEL_FROM_DATABASE=NV34 [GeForce FX 5200] (V9250 Magic)
 
 pci:v000010DEd00000322sv00001043sd00008180*
- ID_MODEL_FROM_DATABASE=V9520-X/TD/128M
+ ID_MODEL_FROM_DATABASE=NV34 [GeForce FX 5200] (V9520-X/TD/128M)
 
 pci:v000010DEd00000322sv0000107Dsd00002967*
- ID_MODEL_FROM_DATABASE=WinFast A340T 128MB
+ ID_MODEL_FROM_DATABASE=NV34 [GeForce FX 5200] (WinFast A340T 128MB)
 
 pci:v000010DEd00000322sv00001462sd00009110*
- ID_MODEL_FROM_DATABASE=MS-8911 (FX5200-TD128)
+ ID_MODEL_FROM_DATABASE=NV34 [GeForce FX 5200] (MS-8911 (FX5200-TD128))
 
 pci:v000010DEd00000322sv00001462sd00009171*
- ID_MODEL_FROM_DATABASE=MS-8917 (FX5200-T128)
+ ID_MODEL_FROM_DATABASE=NV34 [GeForce FX 5200] (MS-8917 (FX5200-T128))
 
 pci:v000010DEd00000322sv00001462sd00009360*
- ID_MODEL_FROM_DATABASE=MS-8936 (FX5200-T128)
+ ID_MODEL_FROM_DATABASE=NV34 [GeForce FX 5200] (MS-8936 (FX5200-T128))
 
 pci:v000010DEd00000322sv00001682sd00001351*
- ID_MODEL_FROM_DATABASE=GeForce FX 5200
+ ID_MODEL_FROM_DATABASE=NV34 [GeForce FX 5200] (GeForce FX 5200)
 
 pci:v000010DEd00000323*
  ID_MODEL_FROM_DATABASE=NV34 [GeForce FX 5200LE]
@@ -22704,13 +23184,13 @@ pci:v000010DEd00000324*
  ID_MODEL_FROM_DATABASE=NV34M [GeForce FX Go5200 64M]
 
 pci:v000010DEd00000324sv00001028sd00000196*
- ID_MODEL_FROM_DATABASE=Inspiron 5160
+ ID_MODEL_FROM_DATABASE=NV34M [GeForce FX Go5200 64M] (Inspiron 5160)
 
 pci:v000010DEd00000324sv0000103Csd0000006A*
- ID_MODEL_FROM_DATABASE=Pavilion ZD7000 laptop
+ ID_MODEL_FROM_DATABASE=NV34M [GeForce FX Go5200 64M] (Pavilion ZD7000 laptop)
 
 pci:v000010DEd00000324sv00001071sd00008160*
- ID_MODEL_FROM_DATABASE=MIM2000
+ ID_MODEL_FROM_DATABASE=NV34M [GeForce FX Go5200 64M] (MIM2000)
 
 pci:v000010DEd00000325*
  ID_MODEL_FROM_DATABASE=NV34M [GeForce FX Go5250]
@@ -22719,10 +23199,10 @@ pci:v000010DEd00000326*
  ID_MODEL_FROM_DATABASE=NV34 [GeForce FX 5500]
 
 pci:v000010DEd00000326sv00001458sd0000310D*
- ID_MODEL_FROM_DATABASE=GeForce FX 5500 128 MB
+ ID_MODEL_FROM_DATABASE=NV34 [GeForce FX 5500] (GeForce FX 5500 128 MB)
 
 pci:v000010DEd00000326sv00001682sd00002034*
- ID_MODEL_FROM_DATABASE=GeForce 5500 256 MB
+ ID_MODEL_FROM_DATABASE=NV34 [GeForce FX 5500] (GeForce 5500 256 MB)
 
 pci:v000010DEd00000327*
  ID_MODEL_FROM_DATABASE=NV34 [GeForce FX 5100]
@@ -22734,7 +23214,7 @@ pci:v000010DEd00000329*
  ID_MODEL_FROM_DATABASE=NV34M [GeForce FX Go5200]
 
 pci:v000010DEd00000329sv000010DEsd00000010*
- ID_MODEL_FROM_DATABASE=Powerbook G4
+ ID_MODEL_FROM_DATABASE=NV34M [GeForce FX Go5200] (Powerbook G4)
 
 pci:v000010DEd0000032A*
  ID_MODEL_FROM_DATABASE=NV34GL [Quadro NVS 280 PCI]
@@ -22758,13 +23238,13 @@ pci:v000010DEd00000330*
  ID_MODEL_FROM_DATABASE=NV35 [GeForce FX 5900 Ultra]
 
 pci:v000010DEd00000330sv00001043sd00008137*
- ID_MODEL_FROM_DATABASE=V9950 Ultra / 256 MB
+ ID_MODEL_FROM_DATABASE=NV35 [GeForce FX 5900 Ultra] (V9950 Ultra / 256 MB)
 
 pci:v000010DEd00000331*
  ID_MODEL_FROM_DATABASE=NV35 [GeForce FX 5900]
 
 pci:v000010DEd00000331sv00001043sd00008145*
- ID_MODEL_FROM_DATABASE=V9950GE
+ ID_MODEL_FROM_DATABASE=NV35 [GeForce FX 5900] (V9950GE)
 
 pci:v000010DEd00000332*
  ID_MODEL_FROM_DATABASE=NV35 [GeForce FX 5900XT]
@@ -22776,7 +23256,7 @@ pci:v000010DEd00000334*
  ID_MODEL_FROM_DATABASE=NV35 [GeForce FX 5900ZT]
 
 pci:v000010DEd00000334sv00001462sd00009373*
- ID_MODEL_FROM_DATABASE=FX5900ZT-VTD128 (MS-8937)
+ ID_MODEL_FROM_DATABASE=NV35 [GeForce FX 5900ZT] (FX5900ZT-VTD128 (MS-8937))
 
 pci:v000010DEd00000338*
  ID_MODEL_FROM_DATABASE=NV35GL [Quadro FX 3000]
@@ -22788,7 +23268,7 @@ pci:v000010DEd00000341*
  ID_MODEL_FROM_DATABASE=NV36 [GeForce FX 5700 Ultra]
 
 pci:v000010DEd00000341sv00001462sd00009380*
- ID_MODEL_FROM_DATABASE=MS-8938 (FX5700U-TD128)
+ ID_MODEL_FROM_DATABASE=NV36 [GeForce FX 5700 Ultra] (MS-8938 (FX5700U-TD128))
 
 pci:v000010DEd00000342*
  ID_MODEL_FROM_DATABASE=NV36 [GeForce FX 5700]
@@ -22803,7 +23283,7 @@ pci:v000010DEd00000347*
  ID_MODEL_FROM_DATABASE=NV36M [GeForce FX Go5700]
 
 pci:v000010DEd00000347sv0000103Csd0000006A*
- ID_MODEL_FROM_DATABASE=NX9500
+ ID_MODEL_FROM_DATABASE=NV36M [GeForce FX Go5700] (NX9500)
 
 pci:v000010DEd00000348*
  ID_MODEL_FROM_DATABASE=NV36M [GeForce FX Go5700]
@@ -22824,13 +23304,13 @@ pci:v000010DEd00000361*
  ID_MODEL_FROM_DATABASE=MCP55 LPC Bridge
 
 pci:v000010DEd00000361sv00001028sd00000221*
- ID_MODEL_FROM_DATABASE=PowerEdge R805 MCP55 LPC Bridge
+ ID_MODEL_FROM_DATABASE=MCP55 LPC Bridge (PowerEdge R805 MCP55 LPC Bridge)
 
 pci:v000010DEd00000362*
  ID_MODEL_FROM_DATABASE=MCP55 LPC Bridge
 
 pci:v000010DEd00000362sv0000147Bsd00001C24*
- ID_MODEL_FROM_DATABASE=KN9 series mainboard
+ ID_MODEL_FROM_DATABASE=MCP55 LPC Bridge (KN9 series mainboard)
 
 pci:v000010DEd00000363*
  ID_MODEL_FROM_DATABASE=MCP55 LPC Bridge
@@ -22839,7 +23319,7 @@ pci:v000010DEd00000364*
  ID_MODEL_FROM_DATABASE=MCP55 LPC Bridge
 
 pci:v000010DEd00000364sv00001028sd00000221*
- ID_MODEL_FROM_DATABASE=PowerEdge R805 MCP55 LPC Bridge
+ ID_MODEL_FROM_DATABASE=MCP55 LPC Bridge (PowerEdge R805 MCP55 LPC Bridge)
 
 pci:v000010DEd00000365*
  ID_MODEL_FROM_DATABASE=MCP55 LPC Bridge
@@ -22854,19 +23334,19 @@ pci:v000010DEd00000368*
  ID_MODEL_FROM_DATABASE=MCP55 SMBus
 
 pci:v000010DEd00000368sv00001028sd0000020C*
- ID_MODEL_FROM_DATABASE=PowerEdge M605 MCP55 SMBus
+ ID_MODEL_FROM_DATABASE=MCP55 SMBus (PowerEdge M605 MCP55 SMBus)
 
 pci:v000010DEd00000368sv00001028sd00000221*
- ID_MODEL_FROM_DATABASE=PowerEdge R805 MCP55 SMBus
+ ID_MODEL_FROM_DATABASE=MCP55 SMBus (PowerEdge R805 MCP55 SMBus)
 
 pci:v000010DEd00000368sv0000147Bsd00001C24*
- ID_MODEL_FROM_DATABASE=KN9 series mainboard
+ ID_MODEL_FROM_DATABASE=MCP55 SMBus (KN9 series mainboard)
 
 pci:v000010DEd00000369*
  ID_MODEL_FROM_DATABASE=MCP55 Memory Controller
 
 pci:v000010DEd00000369sv0000147Bsd00001C24*
- ID_MODEL_FROM_DATABASE=KN9 series mainboard
+ ID_MODEL_FROM_DATABASE=MCP55 Memory Controller (KN9 series mainboard)
 
 pci:v000010DEd0000036A*
  ID_MODEL_FROM_DATABASE=MCP55 Memory Controller
@@ -22878,31 +23358,31 @@ pci:v000010DEd0000036C*
  ID_MODEL_FROM_DATABASE=MCP55 USB Controller
 
 pci:v000010DEd0000036Csv00001028sd0000020C*
- ID_MODEL_FROM_DATABASE=PowerEdge M605 MCP55 USB Controller
+ ID_MODEL_FROM_DATABASE=MCP55 USB Controller (PowerEdge M605 MCP55 USB Controller)
 
 pci:v000010DEd0000036Csv00001028sd00000221*
- ID_MODEL_FROM_DATABASE=PowerEdge R805 MCP55 USB Controller
+ ID_MODEL_FROM_DATABASE=MCP55 USB Controller (PowerEdge R805 MCP55 USB Controller)
 
 pci:v000010DEd0000036Csv0000147Bsd00001C24*
- ID_MODEL_FROM_DATABASE=KN9 series mainboard
+ ID_MODEL_FROM_DATABASE=MCP55 USB Controller (KN9 series mainboard)
 
 pci:v000010DEd0000036D*
  ID_MODEL_FROM_DATABASE=MCP55 USB Controller
 
 pci:v000010DEd0000036Dsv00001028sd0000020C*
- ID_MODEL_FROM_DATABASE=PowerEdge M605 MCP55 USB Controller
+ ID_MODEL_FROM_DATABASE=MCP55 USB Controller (PowerEdge M605 MCP55 USB Controller)
 
 pci:v000010DEd0000036Dsv00001028sd00000221*
- ID_MODEL_FROM_DATABASE=PowerEdge R805 MCP55 USB Controller
+ ID_MODEL_FROM_DATABASE=MCP55 USB Controller (PowerEdge R805 MCP55 USB Controller)
 
 pci:v000010DEd0000036Dsv0000147Bsd00001C24*
- ID_MODEL_FROM_DATABASE=KN9 series mainboard
+ ID_MODEL_FROM_DATABASE=MCP55 USB Controller (KN9 series mainboard)
 
 pci:v000010DEd0000036E*
  ID_MODEL_FROM_DATABASE=MCP55 IDE
 
 pci:v000010DEd0000036Esv0000147Bsd00001C24*
- ID_MODEL_FROM_DATABASE=KN9 series mainboard
+ ID_MODEL_FROM_DATABASE=MCP55 IDE (KN9 series mainboard)
 
 pci:v000010DEd00000370*
  ID_MODEL_FROM_DATABASE=MCP55 PCI bridge
@@ -22911,7 +23391,7 @@ pci:v000010DEd00000371*
  ID_MODEL_FROM_DATABASE=MCP55 High Definition Audio
 
 pci:v000010DEd00000371sv0000147Bsd00001C24*
- ID_MODEL_FROM_DATABASE=KN9 series mainboard
+ ID_MODEL_FROM_DATABASE=MCP55 High Definition Audio (KN9 series mainboard)
 
 pci:v000010DEd00000372*
  ID_MODEL_FROM_DATABASE=MCP55 Ethernet
@@ -22920,7 +23400,7 @@ pci:v000010DEd00000373*
  ID_MODEL_FROM_DATABASE=MCP55 Ethernet
 
 pci:v000010DEd00000373sv0000147Bsd00001C24*
- ID_MODEL_FROM_DATABASE=KN9 series mainboard
+ ID_MODEL_FROM_DATABASE=MCP55 Ethernet (KN9 series mainboard)
 
 pci:v000010DEd00000374*
  ID_MODEL_FROM_DATABASE=MCP55 PCI Express bridge
@@ -22947,10 +23427,10 @@ pci:v000010DEd0000037F*
  ID_MODEL_FROM_DATABASE=MCP55 SATA Controller
 
 pci:v000010DEd0000037Fsv00001028sd00000221*
- ID_MODEL_FROM_DATABASE=PowerEdge R805 MCP55 SATA Controller
+ ID_MODEL_FROM_DATABASE=MCP55 SATA Controller (PowerEdge R805 MCP55 SATA Controller)
 
 pci:v000010DEd0000037Fsv0000147Bsd00001C24*
- ID_MODEL_FROM_DATABASE=KN9 series mainboard
+ ID_MODEL_FROM_DATABASE=MCP55 SATA Controller (KN9 series mainboard)
 
 pci:v000010DEd0000038B*
  ID_MODEL_FROM_DATABASE=G73 [GeForce 7650 GS]
@@ -22962,25 +23442,25 @@ pci:v000010DEd00000391*
  ID_MODEL_FROM_DATABASE=G73 [GeForce 7600 GT]
 
 pci:v000010DEd00000391sv00001458sd00003427*
- ID_MODEL_FROM_DATABASE=GV-NX76T128D-RH
+ ID_MODEL_FROM_DATABASE=G73 [GeForce 7600 GT] (GV-NX76T128D-RH)
 
 pci:v000010DEd00000391sv00001462sd00000452*
- ID_MODEL_FROM_DATABASE=NX7600GT-VT2D256E
+ ID_MODEL_FROM_DATABASE=G73 [GeForce 7600 GT] (NX7600GT-VT2D256E)
 
 pci:v000010DEd00000392*
  ID_MODEL_FROM_DATABASE=G73 [GeForce 7600 GS]
 
 pci:v000010DEd00000392sv00001462sd00000622*
- ID_MODEL_FROM_DATABASE=NX7600GS-T2D256EH
+ ID_MODEL_FROM_DATABASE=G73 [GeForce 7600 GS] (NX7600GS-T2D256EH)
 
 pci:v000010DEd00000393*
  ID_MODEL_FROM_DATABASE=G73 [GeForce 7300 GT]
 
 pci:v000010DEd00000393sv000010DEsd00000412*
- ID_MODEL_FROM_DATABASE=NX7300GT-TD256EH
+ ID_MODEL_FROM_DATABASE=G73 [GeForce 7300 GT] (NX7300GT-TD256EH)
 
 pci:v000010DEd00000393sv00001462sd00000412*
- ID_MODEL_FROM_DATABASE=NX7300GT-TD256EH
+ ID_MODEL_FROM_DATABASE=G73 [GeForce 7300 GT] (NX7300GT-TD256EH)
 
 pci:v000010DEd00000394*
  ID_MODEL_FROM_DATABASE=G73 [GeForce 7600 LE]
@@ -22998,7 +23478,7 @@ pci:v000010DEd00000398*
  ID_MODEL_FROM_DATABASE=G73M [GeForce Go 7600]
 
 pci:v000010DEd00000398sv00001025sd0000006C*
- ID_MODEL_FROM_DATABASE=Acer 9814 WKMI
+ ID_MODEL_FROM_DATABASE=G73M [GeForce Go 7600] (Acer 9814 WKMI)
 
 pci:v000010DEd00000399*
  ID_MODEL_FROM_DATABASE=G73M [GeForce Go 7600 GT]
@@ -23013,7 +23493,7 @@ pci:v000010DEd0000039C*
  ID_MODEL_FROM_DATABASE=G73GLM [Quadro FX 550M]
 
 pci:v000010DEd0000039Csv000010DEsd0000039C*
- ID_MODEL_FROM_DATABASE=Quadro FX 560M
+ ID_MODEL_FROM_DATABASE=G73GLM [Quadro FX 550M] (Quadro FX 560M)
 
 pci:v000010DEd0000039D*
  ID_MODEL_FROM_DATABASE=G73
@@ -23115,7 +23595,7 @@ pci:v000010DEd000003D0*
  ID_MODEL_FROM_DATABASE=C61 [GeForce 6150SE nForce 430]
 
 pci:v000010DEd000003D0sv00001028sd0000020E*
- ID_MODEL_FROM_DATABASE=Inspiron 531
+ ID_MODEL_FROM_DATABASE=C61 [GeForce 6150SE nForce 430] (Inspiron 531)
 
 pci:v000010DEd000003D1*
  ID_MODEL_FROM_DATABASE=C61 [GeForce 6100 nForce 405]
@@ -23133,22 +23613,22 @@ pci:v000010DEd000003E0*
  ID_MODEL_FROM_DATABASE=MCP61 LPC Bridge
 
 pci:v000010DEd000003E0sv00001028sd0000020E*
- ID_MODEL_FROM_DATABASE=Inspiron 531
+ ID_MODEL_FROM_DATABASE=MCP61 LPC Bridge (Inspiron 531)
 
 pci:v000010DEd000003E0sv00001849sd000003E0*
- ID_MODEL_FROM_DATABASE=939NF6G-VSTA Board
+ ID_MODEL_FROM_DATABASE=MCP61 LPC Bridge (939NF6G-VSTA Board)
 
 pci:v000010DEd000003E1*
  ID_MODEL_FROM_DATABASE=MCP61 LPC Bridge
 
 pci:v000010DEd000003E1sv00001043sd000083A4*
- ID_MODEL_FROM_DATABASE=M4N68T series motherboard
+ ID_MODEL_FROM_DATABASE=MCP61 LPC Bridge (M4N68T series motherboard)
 
 pci:v000010DEd000003E2*
  ID_MODEL_FROM_DATABASE=MCP61 Host Bridge
 
 pci:v000010DEd000003E2sv00001043sd000083A4*
- ID_MODEL_FROM_DATABASE=M4N68T series motherboard
+ ID_MODEL_FROM_DATABASE=MCP61 Host Bridge (M4N68T series motherboard)
 
 pci:v000010DEd000003E3*
  ID_MODEL_FROM_DATABASE=MCP61 LPC Bridge
@@ -23169,55 +23649,55 @@ pci:v000010DEd000003E8*
  ID_MODEL_FROM_DATABASE=MCP61 PCI Express bridge
 
 pci:v000010DEd000003E8sv00001028sd0000020E*
- ID_MODEL_FROM_DATABASE=Inspiron 531
+ ID_MODEL_FROM_DATABASE=MCP61 PCI Express bridge (Inspiron 531)
 
 pci:v000010DEd000003E8sv00001849sd000003E8*
- ID_MODEL_FROM_DATABASE=939NF6G-VSTA Board
+ ID_MODEL_FROM_DATABASE=MCP61 PCI Express bridge (939NF6G-VSTA Board)
 
 pci:v000010DEd000003E9*
  ID_MODEL_FROM_DATABASE=MCP61 PCI Express bridge
 
 pci:v000010DEd000003E9sv00001028sd0000020E*
- ID_MODEL_FROM_DATABASE=Inspiron 531
+ ID_MODEL_FROM_DATABASE=MCP61 PCI Express bridge (Inspiron 531)
 
 pci:v000010DEd000003E9sv00001849sd000003E9*
- ID_MODEL_FROM_DATABASE=939NF6G-VSTA Board
+ ID_MODEL_FROM_DATABASE=MCP61 PCI Express bridge (939NF6G-VSTA Board)
 
 pci:v000010DEd000003EA*
  ID_MODEL_FROM_DATABASE=MCP61 Memory Controller
 
 pci:v000010DEd000003EAsv00001028sd0000020E*
- ID_MODEL_FROM_DATABASE=Inspiron 531
+ ID_MODEL_FROM_DATABASE=MCP61 Memory Controller (Inspiron 531)
 
 pci:v000010DEd000003EAsv00001849sd000003EA*
- ID_MODEL_FROM_DATABASE=939NF6G-VSTA Board
+ ID_MODEL_FROM_DATABASE=MCP61 Memory Controller (939NF6G-VSTA Board)
 
 pci:v000010DEd000003EB*
  ID_MODEL_FROM_DATABASE=MCP61 SMBus
 
 pci:v000010DEd000003EBsv00001028sd0000020E*
- ID_MODEL_FROM_DATABASE=Inspiron 531
+ ID_MODEL_FROM_DATABASE=MCP61 SMBus (Inspiron 531)
 
 pci:v000010DEd000003EBsv00001043sd000083A4*
- ID_MODEL_FROM_DATABASE=M4N68T series motherboard
+ ID_MODEL_FROM_DATABASE=MCP61 SMBus (M4N68T series motherboard)
 
 pci:v000010DEd000003EBsv00001849sd000003EB*
- ID_MODEL_FROM_DATABASE=939NF6G-VSTA Board
+ ID_MODEL_FROM_DATABASE=MCP61 SMBus (939NF6G-VSTA Board)
 
 pci:v000010DEd000003EC*
  ID_MODEL_FROM_DATABASE=MCP61 IDE
 
 pci:v000010DEd000003ECsv00001025sd00000392*
- ID_MODEL_FROM_DATABASE=ET1350
+ ID_MODEL_FROM_DATABASE=MCP61 IDE (ET1350)
 
 pci:v000010DEd000003ECsv00001028sd0000020E*
- ID_MODEL_FROM_DATABASE=Inspiron 531
+ ID_MODEL_FROM_DATABASE=MCP61 IDE (Inspiron 531)
 
 pci:v000010DEd000003ECsv00001043sd000083A4*
- ID_MODEL_FROM_DATABASE=M4N68T series motherboard
+ ID_MODEL_FROM_DATABASE=MCP61 IDE (M4N68T series motherboard)
 
 pci:v000010DEd000003ECsv00001849sd000003EC*
- ID_MODEL_FROM_DATABASE=939NF6G-VSTA Board
+ ID_MODEL_FROM_DATABASE=MCP61 IDE (939NF6G-VSTA Board)
 
 pci:v000010DEd000003EE*
  ID_MODEL_FROM_DATABASE=MCP61 Ethernet
@@ -23226,61 +23706,61 @@ pci:v000010DEd000003EF*
  ID_MODEL_FROM_DATABASE=MCP61 Ethernet
 
 pci:v000010DEd000003EFsv00001025sd00008000*
- ID_MODEL_FROM_DATABASE=ET1350
+ ID_MODEL_FROM_DATABASE=MCP61 Ethernet (ET1350)
 
 pci:v000010DEd000003EFsv00001028sd0000020E*
- ID_MODEL_FROM_DATABASE=Inspiron 531
+ ID_MODEL_FROM_DATABASE=MCP61 Ethernet (Inspiron 531)
 
 pci:v000010DEd000003EFsv00001043sd000083A4*
- ID_MODEL_FROM_DATABASE=M4N68T series motherboard
+ ID_MODEL_FROM_DATABASE=MCP61 Ethernet (M4N68T series motherboard)
 
 pci:v000010DEd000003EFsv00001849sd000003EF*
- ID_MODEL_FROM_DATABASE=939NF6G-VSTA Board
+ ID_MODEL_FROM_DATABASE=MCP61 Ethernet (939NF6G-VSTA Board)
 
 pci:v000010DEd000003F0*
  ID_MODEL_FROM_DATABASE=MCP61 High Definition Audio
 
 pci:v000010DEd000003F0sv00001028sd0000020E*
- ID_MODEL_FROM_DATABASE=Inspiron 531
+ ID_MODEL_FROM_DATABASE=MCP61 High Definition Audio (Inspiron 531)
 
 pci:v000010DEd000003F0sv00001043sd00008415*
- ID_MODEL_FROM_DATABASE=M4N68T series motherboard
+ ID_MODEL_FROM_DATABASE=MCP61 High Definition Audio (M4N68T series motherboard)
 
 pci:v000010DEd000003F0sv00001849sd00000888*
- ID_MODEL_FROM_DATABASE=939NF6G-VSTA Board
+ ID_MODEL_FROM_DATABASE=MCP61 High Definition Audio (939NF6G-VSTA Board)
 
 pci:v000010DEd000003F1*
  ID_MODEL_FROM_DATABASE=MCP61 USB 1.1 Controller
 
 pci:v000010DEd000003F1sv00001028sd0000020E*
- ID_MODEL_FROM_DATABASE=Inspiron 531
+ ID_MODEL_FROM_DATABASE=MCP61 USB 1.1 Controller (Inspiron 531)
 
 pci:v000010DEd000003F1sv00001043sd000083A4*
- ID_MODEL_FROM_DATABASE=M4N68T series motherboard
+ ID_MODEL_FROM_DATABASE=MCP61 USB 1.1 Controller (M4N68T series motherboard)
 
 pci:v000010DEd000003F1sv00001849sd000003F1*
- ID_MODEL_FROM_DATABASE=939NF6G-VSTA Board
+ ID_MODEL_FROM_DATABASE=MCP61 USB 1.1 Controller (939NF6G-VSTA Board)
 
 pci:v000010DEd000003F2*
  ID_MODEL_FROM_DATABASE=MCP61 USB 2.0 Controller
 
 pci:v000010DEd000003F2sv00001028sd0000020E*
- ID_MODEL_FROM_DATABASE=Inspiron 531
+ ID_MODEL_FROM_DATABASE=MCP61 USB 2.0 Controller (Inspiron 531)
 
 pci:v000010DEd000003F2sv00001043sd000083A4*
- ID_MODEL_FROM_DATABASE=M4N68T series motherboard
+ ID_MODEL_FROM_DATABASE=MCP61 USB 2.0 Controller (M4N68T series motherboard)
 
 pci:v000010DEd000003F2sv00001849sd000003F2*
- ID_MODEL_FROM_DATABASE=939NF6G-VSTA Board
+ ID_MODEL_FROM_DATABASE=MCP61 USB 2.0 Controller (939NF6G-VSTA Board)
 
 pci:v000010DEd000003F3*
  ID_MODEL_FROM_DATABASE=MCP61 PCI bridge
 
 pci:v000010DEd000003F3sv00001028sd0000020E*
- ID_MODEL_FROM_DATABASE=Inspiron 531
+ ID_MODEL_FROM_DATABASE=MCP61 PCI bridge (Inspiron 531)
 
 pci:v000010DEd000003F3sv00001849sd000003F3*
- ID_MODEL_FROM_DATABASE=939NF6G-VSTA Board
+ ID_MODEL_FROM_DATABASE=MCP61 PCI bridge (939NF6G-VSTA Board)
 
 pci:v000010DEd000003F4*
  ID_MODEL_FROM_DATABASE=MCP61 SMU
@@ -23289,25 +23769,25 @@ pci:v000010DEd000003F5*
  ID_MODEL_FROM_DATABASE=MCP61 Memory Controller
 
 pci:v000010DEd000003F5sv00001028sd0000020E*
- ID_MODEL_FROM_DATABASE=Inspiron 531
+ ID_MODEL_FROM_DATABASE=MCP61 Memory Controller (Inspiron 531)
 
 pci:v000010DEd000003F5sv00001043sd000083A4*
- ID_MODEL_FROM_DATABASE=M4N68T series motherboard
+ ID_MODEL_FROM_DATABASE=MCP61 Memory Controller (M4N68T series motherboard)
 
 pci:v000010DEd000003F5sv00001849sd000003EB*
- ID_MODEL_FROM_DATABASE=939NF6G-VSTA Board
+ ID_MODEL_FROM_DATABASE=MCP61 Memory Controller (939NF6G-VSTA Board)
 
 pci:v000010DEd000003F6*
  ID_MODEL_FROM_DATABASE=MCP61 SATA Controller
 
 pci:v000010DEd000003F6sv00001028sd0000020E*
- ID_MODEL_FROM_DATABASE=Inspiron 531
+ ID_MODEL_FROM_DATABASE=MCP61 SATA Controller (Inspiron 531)
 
 pci:v000010DEd000003F6sv00001043sd000083A4*
- ID_MODEL_FROM_DATABASE=M4N68T series motherboard
+ ID_MODEL_FROM_DATABASE=MCP61 SATA Controller (M4N68T series motherboard)
 
 pci:v000010DEd000003F6sv00001849sd000003F6*
- ID_MODEL_FROM_DATABASE=939NF6G-VSTA Board
+ ID_MODEL_FROM_DATABASE=MCP61 SATA Controller (939NF6G-VSTA Board)
 
 pci:v000010DEd000003F7*
  ID_MODEL_FROM_DATABASE=MCP61 SATA Controller
@@ -23316,7 +23796,7 @@ pci:v000010DEd00000400*
  ID_MODEL_FROM_DATABASE=G84 [GeForce 8600 GTS]
 
 pci:v000010DEd00000400sv00001043sd00008241*
- ID_MODEL_FROM_DATABASE=EN8600GTS
+ ID_MODEL_FROM_DATABASE=G84 [GeForce 8600 GTS] (EN8600GTS)
 
 pci:v000010DEd00000401*
  ID_MODEL_FROM_DATABASE=G84 [GeForce 8600 GT]
@@ -23325,10 +23805,10 @@ pci:v000010DEd00000402*
  ID_MODEL_FROM_DATABASE=G84 [GeForce 8600 GT]
 
 pci:v000010DEd00000402sv00001458sd00003455*
- ID_MODEL_FROM_DATABASE=GV-NX86T512H
+ ID_MODEL_FROM_DATABASE=G84 [GeForce 8600 GT] (GV-NX86T512H)
 
 pci:v000010DEd00000402sv00001462sd00000910*
- ID_MODEL_FROM_DATABASE=NX8600GT-T2D256EZ
+ ID_MODEL_FROM_DATABASE=G84 [GeForce 8600 GT] (NX8600GT-T2D256EZ)
 
 pci:v000010DEd00000403*
  ID_MODEL_FROM_DATABASE=G84 [GeForce 8600 GS]
@@ -23337,7 +23817,7 @@ pci:v000010DEd00000404*
  ID_MODEL_FROM_DATABASE=G84 [GeForce 8400 GS]
 
 pci:v000010DEd00000404sv00001462sd00001230*
- ID_MODEL_FROM_DATABASE=NX8400GS-TD256E
+ ID_MODEL_FROM_DATABASE=G84 [GeForce 8400 GS] (NX8400GS-TD256E)
 
 pci:v000010DEd00000405*
  ID_MODEL_FROM_DATABASE=G84M [GeForce 9500M GS]
@@ -23364,7 +23844,7 @@ pci:v000010DEd0000040C*
  ID_MODEL_FROM_DATABASE=G84GLM [Quadro FX 570M]
 
 pci:v000010DEd0000040Csv000017AAsd000020D9*
- ID_MODEL_FROM_DATABASE=ThinkPad T61p
+ ID_MODEL_FROM_DATABASE=G84GLM [Quadro FX 570M] (ThinkPad T61p)
 
 pci:v000010DEd0000040D*
  ID_MODEL_FROM_DATABASE=G84GLM [Quadro FX 1600M]
@@ -23388,7 +23868,7 @@ pci:v000010DEd00000421*
  ID_MODEL_FROM_DATABASE=G86 [GeForce 8500 GT]
 
 pci:v000010DEd00000421sv00001462sd00000960*
- ID_MODEL_FROM_DATABASE=NX8500GT-TD512EH/M2
+ ID_MODEL_FROM_DATABASE=G86 [GeForce 8500 GT] (NX8500GT-TD512EH/M2)
 
 pci:v000010DEd00000422*
  ID_MODEL_FROM_DATABASE=G86 [GeForce 8400 GS]
@@ -23403,7 +23883,7 @@ pci:v000010DEd00000425*
  ID_MODEL_FROM_DATABASE=G86M [GeForce 8600M GS]
 
 pci:v000010DEd00000425sv00001025sd00000121*
- ID_MODEL_FROM_DATABASE=Aspire 5920G
+ ID_MODEL_FROM_DATABASE=G86M [GeForce 8600M GS] (Aspire 5920G)
 
 pci:v000010DEd00000426*
  ID_MODEL_FROM_DATABASE=G86M [GeForce 8400M GT]
@@ -23412,10 +23892,10 @@ pci:v000010DEd00000427*
  ID_MODEL_FROM_DATABASE=G86M [GeForce 8400M GS]
 
 pci:v000010DEd00000427sv0000103Csd000030CC*
- ID_MODEL_FROM_DATABASE=Pavilion dv6700
+ ID_MODEL_FROM_DATABASE=G86M [GeForce 8400M GS] (Pavilion dv6700)
 
 pci:v000010DEd00000427sv0000103Csd000030CF*
- ID_MODEL_FROM_DATABASE=Pavilion dv9668eg Laptop
+ ID_MODEL_FROM_DATABASE=G86M [GeForce 8400M GS] (Pavilion dv9668eg Laptop)
 
 pci:v000010DEd00000428*
  ID_MODEL_FROM_DATABASE=G86M [GeForce 8400M G]
@@ -23424,7 +23904,7 @@ pci:v000010DEd00000429*
  ID_MODEL_FROM_DATABASE=G86M [Quadro NVS 140M]
 
 pci:v000010DEd00000429sv000017AAsd000020D8*
- ID_MODEL_FROM_DATABASE=ThinkPad T61
+ ID_MODEL_FROM_DATABASE=G86M [Quadro NVS 140M] (ThinkPad T61)
 
 pci:v000010DEd0000042A*
  ID_MODEL_FROM_DATABASE=G86M [Quadro NVS 130M]
@@ -23454,7 +23934,7 @@ pci:v000010DEd00000442*
  ID_MODEL_FROM_DATABASE=MCP65 LPC Bridge
 
 pci:v000010DEd00000442sv0000103Csd000030CF*
- ID_MODEL_FROM_DATABASE=Pavilion dv9668eg Laptop
+ ID_MODEL_FROM_DATABASE=MCP65 LPC Bridge (Pavilion dv9668eg Laptop)
 
 pci:v000010DEd00000443*
  ID_MODEL_FROM_DATABASE=MCP65 LPC Bridge
@@ -23463,7 +23943,7 @@ pci:v000010DEd00000444*
  ID_MODEL_FROM_DATABASE=MCP65 Memory Controller
 
 pci:v000010DEd00000444sv0000103Csd000030CF*
- ID_MODEL_FROM_DATABASE=Pavilion dv9668eg Laptop
+ ID_MODEL_FROM_DATABASE=MCP65 Memory Controller (Pavilion dv9668eg Laptop)
 
 pci:v000010DEd00000445*
  ID_MODEL_FROM_DATABASE=MCP65 Memory Controller
@@ -23472,31 +23952,31 @@ pci:v000010DEd00000446*
  ID_MODEL_FROM_DATABASE=MCP65 SMBus
 
 pci:v000010DEd00000446sv0000103Csd000030CF*
- ID_MODEL_FROM_DATABASE=Pavilion dv9668eg Laptop
+ ID_MODEL_FROM_DATABASE=MCP65 SMBus (Pavilion dv9668eg Laptop)
 
 pci:v000010DEd00000447*
  ID_MODEL_FROM_DATABASE=MCP65 SMU
 
 pci:v000010DEd00000447sv0000103Csd000030CF*
- ID_MODEL_FROM_DATABASE=Pavilion dv9668eg Laptop
+ ID_MODEL_FROM_DATABASE=MCP65 SMU (Pavilion dv9668eg Laptop)
 
 pci:v000010DEd00000448*
  ID_MODEL_FROM_DATABASE=MCP65 IDE
 
 pci:v000010DEd00000448sv0000103Csd000030CF*
- ID_MODEL_FROM_DATABASE=Pavilion dv9668eg Laptop
+ ID_MODEL_FROM_DATABASE=MCP65 IDE (Pavilion dv9668eg Laptop)
 
 pci:v000010DEd00000449*
  ID_MODEL_FROM_DATABASE=MCP65 PCI bridge
 
 pci:v000010DEd00000449sv000010DEsd0000CB84*
- ID_MODEL_FROM_DATABASE=HP Pavilion dv9668eg Laptop
+ ID_MODEL_FROM_DATABASE=MCP65 PCI bridge (HP Pavilion dv9668eg Laptop)
 
 pci:v000010DEd0000044A*
  ID_MODEL_FROM_DATABASE=MCP65 High Definition Audio
 
 pci:v000010DEd0000044Asv0000103Csd000030CF*
- ID_MODEL_FROM_DATABASE=Pavilion dv9668eg Laptop
+ ID_MODEL_FROM_DATABASE=MCP65 High Definition Audio (Pavilion dv9668eg Laptop)
 
 pci:v000010DEd0000044B*
  ID_MODEL_FROM_DATABASE=MCP65 High Definition Audio
@@ -23517,7 +23997,7 @@ pci:v000010DEd00000450*
  ID_MODEL_FROM_DATABASE=MCP65 Ethernet
 
 pci:v000010DEd00000450sv0000103Csd000030CF*
- ID_MODEL_FROM_DATABASE=Pavilion dv9668eg Laptop
+ ID_MODEL_FROM_DATABASE=MCP65 Ethernet (Pavilion dv9668eg Laptop)
 
 pci:v000010DEd00000451*
  ID_MODEL_FROM_DATABASE=MCP65 Ethernet
@@ -23532,13 +24012,13 @@ pci:v000010DEd00000454*
  ID_MODEL_FROM_DATABASE=MCP65 USB 1.1 OHCI Controller
 
 pci:v000010DEd00000454sv0000103Csd000030CF*
- ID_MODEL_FROM_DATABASE=Pavilion dv9668eg Laptop
+ ID_MODEL_FROM_DATABASE=MCP65 USB 1.1 OHCI Controller (Pavilion dv9668eg Laptop)
 
 pci:v000010DEd00000455*
  ID_MODEL_FROM_DATABASE=MCP65 USB 2.0 EHCI Controller
 
 pci:v000010DEd00000455sv0000103Csd000030CF*
- ID_MODEL_FROM_DATABASE=Pavilion dv9668eg Laptop
+ ID_MODEL_FROM_DATABASE=MCP65 USB 2.0 EHCI Controller (Pavilion dv9668eg Laptop)
 
 pci:v000010DEd00000456*
  ID_MODEL_FROM_DATABASE=MCP65 USB Controller
@@ -23577,7 +24057,7 @@ pci:v000010DEd0000045D*
  ID_MODEL_FROM_DATABASE=MCP65 SATA Controller
 
 pci:v000010DEd0000045Dsv0000103Csd000030CF*
- ID_MODEL_FROM_DATABASE=Pavilion dv9668eg Laptop
+ ID_MODEL_FROM_DATABASE=MCP65 SATA Controller (Pavilion dv9668eg Laptop)
 
 pci:v000010DEd0000045E*
  ID_MODEL_FROM_DATABASE=MCP65 SATA Controller
@@ -23598,7 +24078,7 @@ pci:v000010DEd0000053B*
  ID_MODEL_FROM_DATABASE=C68 [GeForce 7050 PV / nForce 630a]
 
 pci:v000010DEd0000053Bsv00001043sd00008308*
- ID_MODEL_FROM_DATABASE=M2N68-AM Motherbord
+ ID_MODEL_FROM_DATABASE=C68 [GeForce 7050 PV / nForce 630a] (M2N68-AM Motherbord)
 
 pci:v000010DEd0000053E*
  ID_MODEL_FROM_DATABASE=C68 [GeForce 7025 / nForce 630a]
@@ -23610,7 +24090,7 @@ pci:v000010DEd00000542*
  ID_MODEL_FROM_DATABASE=MCP67 SMBus
 
 pci:v000010DEd00000542sv00001043sd00008308*
- ID_MODEL_FROM_DATABASE=M2N68-AM Motherbord
+ ID_MODEL_FROM_DATABASE=MCP67 SMBus (M2N68-AM Motherbord)
 
 pci:v000010DEd00000543*
  ID_MODEL_FROM_DATABASE=MCP67 Co-processor
@@ -23619,25 +24099,25 @@ pci:v000010DEd00000547*
  ID_MODEL_FROM_DATABASE=MCP67 Memory Controller
 
 pci:v000010DEd00000547sv00001043sd00008308*
- ID_MODEL_FROM_DATABASE=M2N68-AM Motherbord
+ ID_MODEL_FROM_DATABASE=MCP67 Memory Controller (M2N68-AM Motherbord)
 
 pci:v000010DEd00000547sv00001849sd00000547*
- ID_MODEL_FROM_DATABASE=ALiveNF7G-HDready
+ ID_MODEL_FROM_DATABASE=MCP67 Memory Controller (ALiveNF7G-HDready)
 
 pci:v000010DEd00000548*
  ID_MODEL_FROM_DATABASE=MCP67 ISA Bridge
 
 pci:v000010DEd00000548sv00001043sd00008308*
- ID_MODEL_FROM_DATABASE=M2N68-AM Motherboard
+ ID_MODEL_FROM_DATABASE=MCP67 ISA Bridge (M2N68-AM Motherboard)
 
 pci:v000010DEd0000054C*
  ID_MODEL_FROM_DATABASE=MCP67 Ethernet
 
 pci:v000010DEd0000054Csv00001043sd00008308*
- ID_MODEL_FROM_DATABASE=M2N68-AM Motherbord
+ ID_MODEL_FROM_DATABASE=MCP67 Ethernet (M2N68-AM Motherbord)
 
 pci:v000010DEd0000054Csv00001849sd0000054C*
- ID_MODEL_FROM_DATABASE=ALiveNF7G-HDready, MCP67 Gigabit Ethernet
+ ID_MODEL_FROM_DATABASE=MCP67 Ethernet (ALiveNF7G-HDready, MCP67 Gigabit Ethernet)
 
 pci:v000010DEd0000054D*
  ID_MODEL_FROM_DATABASE=MCP67 Ethernet
@@ -23652,25 +24132,25 @@ pci:v000010DEd00000550*
  ID_MODEL_FROM_DATABASE=MCP67 AHCI Controller
 
 pci:v000010DEd00000550sv00001043sd00008308*
- ID_MODEL_FROM_DATABASE=M2N68-AM Motherboard
+ ID_MODEL_FROM_DATABASE=MCP67 AHCI Controller (M2N68-AM Motherboard)
 
 pci:v000010DEd00000554*
  ID_MODEL_FROM_DATABASE=MCP67 AHCI Controller
 
 pci:v000010DEd00000554sv00001043sd00008308*
- ID_MODEL_FROM_DATABASE=M2N68-AM Motherboard
+ ID_MODEL_FROM_DATABASE=MCP67 AHCI Controller (M2N68-AM Motherboard)
 
 pci:v000010DEd00000555*
  ID_MODEL_FROM_DATABASE=MCP67 SATA Controller
 
 pci:v000010DEd00000555sv00001043sd00008308*
- ID_MODEL_FROM_DATABASE=M2N68-AM Motherboard
+ ID_MODEL_FROM_DATABASE=MCP67 SATA Controller (M2N68-AM Motherboard)
 
 pci:v000010DEd0000055C*
  ID_MODEL_FROM_DATABASE=MCP67 High Definition Audio
 
 pci:v000010DEd0000055Csv00001043sd00008290*
- ID_MODEL_FROM_DATABASE=M2N68-AM Motherboard
+ ID_MODEL_FROM_DATABASE=MCP67 High Definition Audio (M2N68-AM Motherboard)
 
 pci:v000010DEd0000055D*
  ID_MODEL_FROM_DATABASE=MCP67 High Definition Audio
@@ -23679,19 +24159,19 @@ pci:v000010DEd0000055E*
  ID_MODEL_FROM_DATABASE=MCP67 OHCI USB 1.1 Controller
 
 pci:v000010DEd0000055Esv00001043sd00008308*
- ID_MODEL_FROM_DATABASE=M2N68-AM Motherboard
+ ID_MODEL_FROM_DATABASE=MCP67 OHCI USB 1.1 Controller (M2N68-AM Motherboard)
 
 pci:v000010DEd0000055F*
  ID_MODEL_FROM_DATABASE=MCP67 EHCI USB 2.0 Controller
 
 pci:v000010DEd0000055Fsv00001043sd00008308*
- ID_MODEL_FROM_DATABASE=M2N68-AM Motherboard
+ ID_MODEL_FROM_DATABASE=MCP67 EHCI USB 2.0 Controller (M2N68-AM Motherboard)
 
 pci:v000010DEd00000560*
  ID_MODEL_FROM_DATABASE=MCP67 IDE Controller
 
 pci:v000010DEd00000560sv0000F043sd00008308*
- ID_MODEL_FROM_DATABASE=M2N68-AM Motherboard
+ ID_MODEL_FROM_DATABASE=MCP67 IDE Controller (M2N68-AM Motherboard)
 
 pci:v000010DEd00000561*
  ID_MODEL_FROM_DATABASE=MCP67 PCI Bridge
@@ -23700,7 +24180,7 @@ pci:v000010DEd00000562*
  ID_MODEL_FROM_DATABASE=MCP67 PCI Express Bridge
 
 pci:v000010DEd00000562sv00001849sd00000562*
- ID_MODEL_FROM_DATABASE=ALiveNF7G-HDready
+ ID_MODEL_FROM_DATABASE=MCP67 PCI Express Bridge (ALiveNF7G-HDready)
 
 pci:v000010DEd00000563*
  ID_MODEL_FROM_DATABASE=MCP67 PCI Express Bridge
@@ -23709,64 +24189,64 @@ pci:v000010DEd00000568*
  ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] Memory Controller
 
 pci:v000010DEd00000568sv0000103Csd00002A9E*
- ID_MODEL_FROM_DATABASE=Pavilion p6310f
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] Memory Controller (Pavilion p6310f)
 
 pci:v000010DEd00000568sv00001043sd000082E8*
- ID_MODEL_FROM_DATABASE=M3N72-D
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] Memory Controller (M3N72-D)
 
 pci:v000010DEd00000568sv00001462sd00007508*
- ID_MODEL_FROM_DATABASE=K9N2GM-FIH
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] Memory Controller (K9N2GM-FIH)
 
 pci:v000010DEd00000568sv00001849sd00000568*
- ID_MODEL_FROM_DATABASE=K10N78FullHD-hSLI R3.0 Memory Controller
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] Memory Controller (K10N78FullHD-hSLI R3.0 Memory Controller)
 
 pci:v000010DEd00000569*
  ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] PCI Express Bridge
 
 pci:v000010DEd00000569sv0000103Csd00002A9E*
- ID_MODEL_FROM_DATABASE=Pavilion p6310f
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] PCI Express Bridge (Pavilion p6310f)
 
 pci:v000010DEd00000569sv00001043sd000082E8*
- ID_MODEL_FROM_DATABASE=M3N72-D
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] PCI Express Bridge (M3N72-D)
 
 pci:v000010DEd00000569sv00001462sd00007508*
- ID_MODEL_FROM_DATABASE=K9N2GM-FIH
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] PCI Express Bridge (K9N2GM-FIH)
 
 pci:v000010DEd00000569sv00001849sd00000569*
- ID_MODEL_FROM_DATABASE=K10N78FullHD-hSLI R3.0 PCI Express Bridge
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] PCI Express Bridge (K10N78FullHD-hSLI R3.0 PCI Express Bridge)
 
 pci:v000010DEd0000056A*
  ID_MODEL_FROM_DATABASE=MCP73 [nForce 630i] USB 2.0 Controller (EHCI)
 
 pci:v000010DEd0000056Asv00001019sd0000297A*
- ID_MODEL_FROM_DATABASE=MCP73PVT-SM
+ ID_MODEL_FROM_DATABASE=MCP73 [nForce 630i] USB 2.0 Controller (EHCI) (MCP73PVT-SM)
 
 pci:v000010DEd0000056C*
  ID_MODEL_FROM_DATABASE=MCP73 IDE
 
 pci:v000010DEd0000056Csv00001019sd0000297A*
- ID_MODEL_FROM_DATABASE=MCP73PVT-SM
+ ID_MODEL_FROM_DATABASE=MCP73 IDE (MCP73PVT-SM)
 
 pci:v000010DEd0000056Csv00001AFAsd00007150*
- ID_MODEL_FROM_DATABASE=JW-IN7150-HD
+ ID_MODEL_FROM_DATABASE=MCP73 IDE (JW-IN7150-HD)
 
 pci:v000010DEd0000056D*
  ID_MODEL_FROM_DATABASE=MCP73 PCI Express bridge
 
 pci:v000010DEd0000056Dsv00001019sd0000297A*
- ID_MODEL_FROM_DATABASE=MCP73PVT-SM
+ ID_MODEL_FROM_DATABASE=MCP73 PCI Express bridge (MCP73PVT-SM)
 
 pci:v000010DEd0000056E*
  ID_MODEL_FROM_DATABASE=MCP73 PCI Express bridge
 
 pci:v000010DEd0000056Esv00001019sd0000297A*
- ID_MODEL_FROM_DATABASE=MCP73PVT-SM
+ ID_MODEL_FROM_DATABASE=MCP73 PCI Express bridge (MCP73PVT-SM)
 
 pci:v000010DEd0000056F*
  ID_MODEL_FROM_DATABASE=MCP73 PCI Express bridge
 
 pci:v000010DEd0000056Fsv00001019sd0000297A*
- ID_MODEL_FROM_DATABASE=MCP73PVT-SM
+ ID_MODEL_FROM_DATABASE=MCP73 PCI Express bridge (MCP73PVT-SM)
 
 pci:v000010DEd000005B1*
  ID_MODEL_FROM_DATABASE=NF200 PCIe 2.0 switch
@@ -23790,7 +24270,7 @@ pci:v000010DEd000005E3*
  ID_MODEL_FROM_DATABASE=GT200b [GeForce GTX 285]
 
 pci:v000010DEd000005E3sv00001682sd00002490*
- ID_MODEL_FROM_DATABASE=GX-285N-ZDF
+ ID_MODEL_FROM_DATABASE=GT200b [GeForce GTX 285] (GX-285N-ZDF)
 
 pci:v000010DEd000005E6*
  ID_MODEL_FROM_DATABASE=GT200b [GeForce GTX 275]
@@ -23799,19 +24279,19 @@ pci:v000010DEd000005E7*
  ID_MODEL_FROM_DATABASE=GT200GL [Tesla C1060 / M1060]
 
 pci:v000010DEd000005E7sv000010DEsd00000595*
- ID_MODEL_FROM_DATABASE=Tesla T10 Processor
+ ID_MODEL_FROM_DATABASE=GT200GL [Tesla C1060 / M1060] (Tesla T10 Processor)
 
 pci:v000010DEd000005E7sv000010DEsd0000068F*
- ID_MODEL_FROM_DATABASE=Tesla T10 Processor
+ ID_MODEL_FROM_DATABASE=GT200GL [Tesla C1060 / M1060] (Tesla T10 Processor)
 
 pci:v000010DEd000005E7sv000010DEsd00000697*
- ID_MODEL_FROM_DATABASE=Tesla M1060
+ ID_MODEL_FROM_DATABASE=GT200GL [Tesla C1060 / M1060] (Tesla M1060)
 
 pci:v000010DEd000005E7sv000010DEsd00000714*
- ID_MODEL_FROM_DATABASE=Tesla M1060
+ ID_MODEL_FROM_DATABASE=GT200GL [Tesla C1060 / M1060] (Tesla M1060)
 
 pci:v000010DEd000005E7sv000010DEsd00000743*
- ID_MODEL_FROM_DATABASE=Tesla M1060
+ ID_MODEL_FROM_DATABASE=GT200GL [Tesla C1060 / M1060] (Tesla M1060)
 
 pci:v000010DEd000005EA*
  ID_MODEL_FROM_DATABASE=GT200 [GeForce GTX 260]
@@ -23874,7 +24354,7 @@ pci:v000010DEd00000609*
  ID_MODEL_FROM_DATABASE=G92M [GeForce 8800M GTS]
 
 pci:v000010DEd00000609sv0000106Bsd000000A7*
- ID_MODEL_FROM_DATABASE=GeForce 8800 GS
+ ID_MODEL_FROM_DATABASE=G92M [GeForce 8800M GTS] (GeForce 8800 GS)
 
 pci:v000010DEd0000060A*
  ID_MODEL_FROM_DATABASE=G92M [GeForce GTX 280M]
@@ -23895,16 +24375,16 @@ pci:v000010DEd00000610*
  ID_MODEL_FROM_DATABASE=G92 [GeForce 9600 GSO]
 
 pci:v000010DEd00000610sv00001682sd00002385*
- ID_MODEL_FROM_DATABASE=GeForce 9600 GSO 768mb
+ ID_MODEL_FROM_DATABASE=G92 [GeForce 9600 GSO] (GeForce 9600 GSO 768mb)
 
 pci:v000010DEd00000611*
  ID_MODEL_FROM_DATABASE=G92 [GeForce 8800 GT]
 
 pci:v000010DEd00000611sv0000107Dsd00002AB0*
- ID_MODEL_FROM_DATABASE=Winfast PX8800 GT PCI-E
+ ID_MODEL_FROM_DATABASE=G92 [GeForce 8800 GT] (Winfast PX8800 GT PCI-E)
 
 pci:v000010DEd00000611sv000019DAsd00001040*
- ID_MODEL_FROM_DATABASE=ZT-88TES2P-FSP
+ ID_MODEL_FROM_DATABASE=G92 [GeForce 8800 GT] (ZT-88TES2P-FSP)
 
 pci:v000010DEd00000612*
  ID_MODEL_FROM_DATABASE=G92 [GeForce 9800 GTX / 9800 GTX+]
@@ -23916,22 +24396,22 @@ pci:v000010DEd00000614*
  ID_MODEL_FROM_DATABASE=G92 [GeForce 9800 GT]
 
 pci:v000010DEd00000614sv0000107Dsd00002AB3*
- ID_MODEL_FROM_DATABASE=WinFast PX9800 GT (S-Fanpipe)
+ ID_MODEL_FROM_DATABASE=G92 [GeForce 9800 GT] (WinFast PX9800 GT (S-Fanpipe))
 
 pci:v000010DEd00000615*
  ID_MODEL_FROM_DATABASE=G92 [GeForce GTS 250]
 
 pci:v000010DEd00000615sv00003842sd00001150*
- ID_MODEL_FROM_DATABASE=GeForce GTS 250 P/N 512-P3-1150-TR
+ ID_MODEL_FROM_DATABASE=G92 [GeForce GTS 250] (GeForce GTS 250 P/N 512-P3-1150-TR)
 
 pci:v000010DEd00000615sv00003842sd00001151*
- ID_MODEL_FROM_DATABASE=GeForce GTS 250 P/N 512-P3-1151-TR
+ ID_MODEL_FROM_DATABASE=G92 [GeForce GTS 250] (GeForce GTS 250 P/N 512-P3-1151-TR)
 
 pci:v000010DEd00000615sv00003842sd00001155*
- ID_MODEL_FROM_DATABASE=GeForce GTS 250 P/N 01G-P3-1155-TR
+ ID_MODEL_FROM_DATABASE=G92 [GeForce GTS 250] (GeForce GTS 250 P/N 01G-P3-1155-TR)
 
 pci:v000010DEd00000615sv00003842sd00001156*
- ID_MODEL_FROM_DATABASE=GeForce GTS 250 P/N 01G-P3-1156-TR
+ ID_MODEL_FROM_DATABASE=G92 [GeForce GTS 250] (GeForce GTS 250 P/N 01G-P3-1156-TR)
 
 pci:v000010DEd00000617*
  ID_MODEL_FROM_DATABASE=G92M [GeForce 9800M GTX]
@@ -23970,10 +24450,10 @@ pci:v000010DEd00000622*
  ID_MODEL_FROM_DATABASE=G94 [GeForce 9600 GT]
 
 pci:v000010DEd00000622sv0000107Dsd00002AC1*
- ID_MODEL_FROM_DATABASE=WinFast PX9600GT 1024MB
+ ID_MODEL_FROM_DATABASE=G94 [GeForce 9600 GT] (WinFast PX9600GT 1024MB)
 
 pci:v000010DEd00000622sv00001458sd00003481*
- ID_MODEL_FROM_DATABASE=GV-NX96T512HP
+ ID_MODEL_FROM_DATABASE=G94 [GeForce 9600 GT] (GV-NX96T512HP)
 
 pci:v000010DEd00000623*
  ID_MODEL_FROM_DATABASE=G94 [GeForce 9600 GS]
@@ -24009,7 +24489,7 @@ pci:v000010DEd0000062E*
  ID_MODEL_FROM_DATABASE=G94 [GeForce 9600 GT]
 
 pci:v000010DEd0000062Esv0000106Bsd00000605*
- ID_MODEL_FROM_DATABASE=GeForce GT 130
+ ID_MODEL_FROM_DATABASE=G94 [GeForce 9600 GT] (GeForce GT 130)
 
 pci:v000010DEd0000062F*
  ID_MODEL_FROM_DATABASE=G94 [GeForce 9800 S]
@@ -24047,6 +24527,9 @@ pci:v000010DEd00000640*
 pci:v000010DEd00000641*
  ID_MODEL_FROM_DATABASE=G96 [GeForce 9400 GT]
 
+pci:v000010DEd00000641sv00001682sd00004009*
+ ID_MODEL_FROM_DATABASE=G96 [GeForce 9400 GT] (PV-T94G-ZAFG)
+
 pci:v000010DEd00000643*
  ID_MODEL_FROM_DATABASE=G96 [GeForce 9500 GT]
 
@@ -24069,7 +24552,7 @@ pci:v000010DEd00000649*
  ID_MODEL_FROM_DATABASE=G96M [GeForce 9600M GT]
 
 pci:v000010DEd00000649sv00001043sd0000202D*
- ID_MODEL_FROM_DATABASE=GeForce GT 220M
+ ID_MODEL_FROM_DATABASE=G96M [GeForce 9600M GT] (GeForce GT 220M)
 
 pci:v000010DEd0000064A*
  ID_MODEL_FROM_DATABASE=G96M [GeForce 9700M GT]
@@ -24093,7 +24576,7 @@ pci:v000010DEd00000652*
  ID_MODEL_FROM_DATABASE=G96M [GeForce GT 130M]
 
 pci:v000010DEd00000652sv0000152Dsd00000850*
- ID_MODEL_FROM_DATABASE=GeForce GT 240M LE
+ ID_MODEL_FROM_DATABASE=G96M [GeForce GT 130M] (GeForce GT 240M LE)
 
 pci:v000010DEd00000653*
  ID_MODEL_FROM_DATABASE=G96M [GeForce GT 120M]
@@ -24102,10 +24585,10 @@ pci:v000010DEd00000654*
  ID_MODEL_FROM_DATABASE=G96M [GeForce GT 220M]
 
 pci:v000010DEd00000654sv00001043sd000014A2*
- ID_MODEL_FROM_DATABASE=GeForce GT 320M
+ ID_MODEL_FROM_DATABASE=G96M [GeForce GT 220M] (GeForce GT 320M)
 
 pci:v000010DEd00000654sv00001043sd000014D2*
- ID_MODEL_FROM_DATABASE=GeForce GT 320M
+ ID_MODEL_FROM_DATABASE=G96M [GeForce GT 220M] (GeForce GT 320M)
 
 pci:v000010DEd00000655*
  ID_MODEL_FROM_DATABASE=G96 [GeForce GT 120]
@@ -24153,28 +24636,28 @@ pci:v000010DEd000006D1*
  ID_MODEL_FROM_DATABASE=GF100GL [Tesla C2050 / C2070]
 
 pci:v000010DEd000006D1sv000010DEsd00000771*
- ID_MODEL_FROM_DATABASE=Tesla C2050
+ ID_MODEL_FROM_DATABASE=GF100GL [Tesla C2050 / C2070] (Tesla C2050)
 
 pci:v000010DEd000006D1sv000010DEsd00000772*
- ID_MODEL_FROM_DATABASE=Tesla C2070
+ ID_MODEL_FROM_DATABASE=GF100GL [Tesla C2050 / C2070] (Tesla C2070)
 
 pci:v000010DEd000006D2*
  ID_MODEL_FROM_DATABASE=GF100GL [Tesla M2070]
 
 pci:v000010DEd000006D2sv000010DEsd00000774*
- ID_MODEL_FROM_DATABASE=Tesla M2070
+ ID_MODEL_FROM_DATABASE=GF100GL [Tesla M2070] (Tesla M2070)
 
 pci:v000010DEd000006D2sv000010DEsd00000830*
- ID_MODEL_FROM_DATABASE=Tesla M2070
+ ID_MODEL_FROM_DATABASE=GF100GL [Tesla M2070] (Tesla M2070)
 
 pci:v000010DEd000006D2sv000010DEsd00000842*
- ID_MODEL_FROM_DATABASE=Tesla M2070
+ ID_MODEL_FROM_DATABASE=GF100GL [Tesla M2070] (Tesla M2070)
 
 pci:v000010DEd000006D2sv000010DEsd0000088F*
- ID_MODEL_FROM_DATABASE=Tesla X2070
+ ID_MODEL_FROM_DATABASE=GF100GL [Tesla M2070] (Tesla X2070)
 
 pci:v000010DEd000006D2sv000010DEsd00000908*
- ID_MODEL_FROM_DATABASE=Tesla M2070
+ ID_MODEL_FROM_DATABASE=GF100GL [Tesla M2070] (Tesla M2070)
 
 pci:v000010DEd000006D8*
  ID_MODEL_FROM_DATABASE=GF100GL [Quadro 6000]
@@ -24195,37 +24678,37 @@ pci:v000010DEd000006DE*
  ID_MODEL_FROM_DATABASE=GF100GL [Tesla T20 Processor]
 
 pci:v000010DEd000006DEsv000010DEsd00000773*
- ID_MODEL_FROM_DATABASE=Tesla S2050
+ ID_MODEL_FROM_DATABASE=GF100GL [Tesla T20 Processor] (Tesla S2050)
 
 pci:v000010DEd000006DEsv000010DEsd0000082F*
- ID_MODEL_FROM_DATABASE=Tesla M2050
+ ID_MODEL_FROM_DATABASE=GF100GL [Tesla T20 Processor] (Tesla M2050)
 
 pci:v000010DEd000006DEsv000010DEsd00000840*
- ID_MODEL_FROM_DATABASE=Tesla X2070
+ ID_MODEL_FROM_DATABASE=GF100GL [Tesla T20 Processor] (Tesla X2070)
 
 pci:v000010DEd000006DEsv000010DEsd00000842*
- ID_MODEL_FROM_DATABASE=Tesla M2050
+ ID_MODEL_FROM_DATABASE=GF100GL [Tesla T20 Processor] (Tesla M2050)
 
 pci:v000010DEd000006DEsv000010DEsd00000846*
- ID_MODEL_FROM_DATABASE=Tesla M2050
+ ID_MODEL_FROM_DATABASE=GF100GL [Tesla T20 Processor] (Tesla M2050)
 
 pci:v000010DEd000006DEsv000010DEsd00000866*
- ID_MODEL_FROM_DATABASE=Tesla M2050
+ ID_MODEL_FROM_DATABASE=GF100GL [Tesla T20 Processor] (Tesla M2050)
 
 pci:v000010DEd000006DEsv000010DEsd00000907*
- ID_MODEL_FROM_DATABASE=Tesla M2050
+ ID_MODEL_FROM_DATABASE=GF100GL [Tesla T20 Processor] (Tesla M2050)
 
 pci:v000010DEd000006DEsv000010DEsd0000091E*
- ID_MODEL_FROM_DATABASE=Tesla M2050
+ ID_MODEL_FROM_DATABASE=GF100GL [Tesla T20 Processor] (Tesla M2050)
 
 pci:v000010DEd000006DF*
  ID_MODEL_FROM_DATABASE=GF100GL [Tesla M2070-Q]
 
 pci:v000010DEd000006DFsv000010DEsd0000084D*
- ID_MODEL_FROM_DATABASE=Tesla M2070-Q
+ ID_MODEL_FROM_DATABASE=GF100GL [Tesla M2070-Q] (Tesla M2070-Q)
 
 pci:v000010DEd000006DFsv000010DEsd0000087F*
- ID_MODEL_FROM_DATABASE=Tesla M2070-Q
+ ID_MODEL_FROM_DATABASE=GF100GL [Tesla M2070-Q] (Tesla M2070-Q)
 
 pci:v000010DEd000006E0*
  ID_MODEL_FROM_DATABASE=G98 [GeForce 9300 GE]
@@ -24243,7 +24726,7 @@ pci:v000010DEd000006E4*
  ID_MODEL_FROM_DATABASE=G98 [GeForce 8400 GS Rev. 2]
 
 pci:v000010DEd000006E4sv00001458sd00003475*
- ID_MODEL_FROM_DATABASE=GV-NX84S256HE [GeForce 8400 GS]
+ ID_MODEL_FROM_DATABASE=G98 [GeForce 8400 GS Rev. 2] (GV-NX84S256HE [GeForce 8400 GS])
 
 pci:v000010DEd000006E5*
  ID_MODEL_FROM_DATABASE=G98M [GeForce 9300M GS]
@@ -24258,13 +24741,13 @@ pci:v000010DEd000006E8*
  ID_MODEL_FROM_DATABASE=G98M [GeForce 9200M GS]
 
 pci:v000010DEd000006E8sv0000103Csd0000360B*
- ID_MODEL_FROM_DATABASE=GeForce 9200M GE
+ ID_MODEL_FROM_DATABASE=G98M [GeForce 9200M GS] (GeForce 9200M GE)
 
 pci:v000010DEd000006E9*
  ID_MODEL_FROM_DATABASE=G98M [GeForce 9300M GS]
 
 pci:v000010DEd000006E9sv00001043sd000019B2*
- ID_MODEL_FROM_DATABASE=U6V laptop
+ ID_MODEL_FROM_DATABASE=G98M [GeForce 9300M GS] (U6V laptop)
 
 pci:v000010DEd000006EA*
  ID_MODEL_FROM_DATABASE=G98M [Quadro NVS 150M]
@@ -24306,139 +24789,139 @@ pci:v000010DEd000006FF*
  ID_MODEL_FROM_DATABASE=G98 [HICx16 + Graphics]
 
 pci:v000010DEd000006FFsv000010DEsd00000711*
- ID_MODEL_FROM_DATABASE=HICx8 + Graphics
+ ID_MODEL_FROM_DATABASE=G98 [HICx16 + Graphics] (HICx8 + Graphics)
 
 pci:v000010DEd00000751*
  ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] Memory Controller
 
 pci:v000010DEd00000751sv0000103Csd00002A9E*
- ID_MODEL_FROM_DATABASE=Pavilion p6310f
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] Memory Controller (Pavilion p6310f)
 
 pci:v000010DEd00000751sv00001043sd000082E8*
- ID_MODEL_FROM_DATABASE=M3N72-D
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] Memory Controller (M3N72-D)
 
 pci:v000010DEd00000751sv00001462sd00007508*
- ID_MODEL_FROM_DATABASE=K9N2GM-FIH
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] Memory Controller (K9N2GM-FIH)
 
 pci:v000010DEd00000751sv00001849sd00000751*
- ID_MODEL_FROM_DATABASE=K10N78FullHD-hSLI R3.0 Memory Controller
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] Memory Controller (K10N78FullHD-hSLI R3.0 Memory Controller)
 
 pci:v000010DEd00000752*
  ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] SMBus
 
 pci:v000010DEd00000752sv0000103Csd00002A9E*
- ID_MODEL_FROM_DATABASE=Pavilion p6310f
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] SMBus (Pavilion p6310f)
 
 pci:v000010DEd00000752sv00001043sd000082E8*
- ID_MODEL_FROM_DATABASE=M3N72-D
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] SMBus (M3N72-D)
 
 pci:v000010DEd00000752sv00001462sd00007508*
- ID_MODEL_FROM_DATABASE=K9N2GM-FIH
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] SMBus (K9N2GM-FIH)
 
 pci:v000010DEd00000752sv00001849sd00000752*
- ID_MODEL_FROM_DATABASE=K10N78FullHD-hSLI R3.0 SMBus
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] SMBus (K10N78FullHD-hSLI R3.0 SMBus)
 
 pci:v000010DEd00000753*
  ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] Co-Processor
 
 pci:v000010DEd00000753sv0000103Csd00002A9E*
- ID_MODEL_FROM_DATABASE=Pavilion p6310f
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] Co-Processor (Pavilion p6310f)
 
 pci:v000010DEd00000753sv00001043sd000082E8*
- ID_MODEL_FROM_DATABASE=M3N72-D
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] Co-Processor (M3N72-D)
 
 pci:v000010DEd00000753sv00001462sd00007508*
- ID_MODEL_FROM_DATABASE=K9N2GM-FIH
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] Co-Processor (K9N2GM-FIH)
 
 pci:v000010DEd00000753sv00001849sd00000753*
- ID_MODEL_FROM_DATABASE=K10N78FullHD-hSLI R3.0 Co-Processor
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] Co-Processor (K10N78FullHD-hSLI R3.0 Co-Processor)
 
 pci:v000010DEd00000754*
  ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] Memory Controller
 
 pci:v000010DEd00000754sv0000103Csd00002A9E*
- ID_MODEL_FROM_DATABASE=Pavilion p6310f
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] Memory Controller (Pavilion p6310f)
 
 pci:v000010DEd00000754sv00001043sd000082E8*
- ID_MODEL_FROM_DATABASE=M3N72-D
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] Memory Controller (M3N72-D)
 
 pci:v000010DEd00000754sv00001462sd00007508*
- ID_MODEL_FROM_DATABASE=K9N2GM-FIH
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] Memory Controller (K9N2GM-FIH)
 
 pci:v000010DEd00000754sv00001849sd00000754*
- ID_MODEL_FROM_DATABASE=K10N78FullHD-hSLI R3.0 Memory Controller
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] Memory Controller (K10N78FullHD-hSLI R3.0 Memory Controller)
 
 pci:v000010DEd00000759*
  ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] IDE
 
 pci:v000010DEd00000759sv00001043sd000082E8*
- ID_MODEL_FROM_DATABASE=M3N72-D
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] IDE (M3N72-D)
 
 pci:v000010DEd00000759sv00001462sd00007508*
- ID_MODEL_FROM_DATABASE=K9N2GM-FIH
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] IDE (K9N2GM-FIH)
 
 pci:v000010DEd00000759sv00001849sd00000759*
- ID_MODEL_FROM_DATABASE=K10N78FullHD-hSLI R3.0 IDE
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] IDE (K10N78FullHD-hSLI R3.0 IDE)
 
 pci:v000010DEd0000075A*
  ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] PCI Bridge
 
 pci:v000010DEd0000075Asv0000103Csd00002A9E*
- ID_MODEL_FROM_DATABASE=Pavilion p6310f
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] PCI Bridge (Pavilion p6310f)
 
 pci:v000010DEd0000075Asv00001043sd000082E8*
- ID_MODEL_FROM_DATABASE=M3N72-D
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] PCI Bridge (M3N72-D)
 
 pci:v000010DEd0000075Asv00001849sd0000075A*
- ID_MODEL_FROM_DATABASE=K10N78FullHD-hSLI R3.0 PCI Bridge
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] PCI Bridge (K10N78FullHD-hSLI R3.0 PCI Bridge)
 
 pci:v000010DEd0000075B*
  ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] PCI Express Bridge
 
 pci:v000010DEd0000075Bsv0000103Csd00002A9E*
- ID_MODEL_FROM_DATABASE=Pavilion p6310f
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] PCI Express Bridge (Pavilion p6310f)
 
 pci:v000010DEd0000075Bsv00001043sd000082E8*
- ID_MODEL_FROM_DATABASE=M3N72-D
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] PCI Express Bridge (M3N72-D)
 
 pci:v000010DEd0000075Bsv00001462sd00007508*
- ID_MODEL_FROM_DATABASE=K9N2GM-FIH
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] PCI Express Bridge (K9N2GM-FIH)
 
 pci:v000010DEd0000075Bsv00001849sd0000075B*
- ID_MODEL_FROM_DATABASE=K10N78FullHD-hSLI R3.0 PCI Express Bridge
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] PCI Express Bridge (K10N78FullHD-hSLI R3.0 PCI Express Bridge)
 
 pci:v000010DEd0000075C*
  ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] LPC Bridge
 
 pci:v000010DEd0000075Csv0000103Csd00002A9E*
- ID_MODEL_FROM_DATABASE=Pavilion p6310f
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] LPC Bridge (Pavilion p6310f)
 
 pci:v000010DEd0000075Csv00001462sd00007508*
- ID_MODEL_FROM_DATABASE=K9N2GM-FIH
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] LPC Bridge (K9N2GM-FIH)
 
 pci:v000010DEd0000075Csv00001849sd0000075C*
- ID_MODEL_FROM_DATABASE=K10N78FullHD-hSLI R3.0 LPC Bridge
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] LPC Bridge (K10N78FullHD-hSLI R3.0 LPC Bridge)
 
 pci:v000010DEd0000075D*
  ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] LPC Bridge
 
 pci:v000010DEd0000075Dsv00001043sd000082E8*
- ID_MODEL_FROM_DATABASE=M3N72-D
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] LPC Bridge (M3N72-D)
 
 pci:v000010DEd00000760*
  ID_MODEL_FROM_DATABASE=MCP77 Ethernet
 
 pci:v000010DEd00000760sv0000103Csd00002A9E*
- ID_MODEL_FROM_DATABASE=Pavilion p6310f
+ ID_MODEL_FROM_DATABASE=MCP77 Ethernet (Pavilion p6310f)
 
 pci:v000010DEd00000760sv00001043sd000082E8*
- ID_MODEL_FROM_DATABASE=M3N72-D
+ ID_MODEL_FROM_DATABASE=MCP77 Ethernet (M3N72-D)
 
 pci:v000010DEd00000760sv00001462sd00007508*
- ID_MODEL_FROM_DATABASE=K9N2GM-FIH
+ ID_MODEL_FROM_DATABASE=MCP77 Ethernet (K9N2GM-FIH)
 
 pci:v000010DEd00000760sv00001849sd00000760*
- ID_MODEL_FROM_DATABASE=K10N78FullHD-hSLI R3.0 Ethernet
+ ID_MODEL_FROM_DATABASE=MCP77 Ethernet (K10N78FullHD-hSLI R3.0 Ethernet)
 
 pci:v000010DEd00000761*
  ID_MODEL_FROM_DATABASE=MCP77 Ethernet
@@ -24453,118 +24936,118 @@ pci:v000010DEd00000774*
  ID_MODEL_FROM_DATABASE=MCP72XE/MCP72P/MCP78U/MCP78S High Definition Audio
 
 pci:v000010DEd00000774sv0000103Csd00002A9E*
- ID_MODEL_FROM_DATABASE=Pavilion p6310f
+ ID_MODEL_FROM_DATABASE=MCP72XE/MCP72P/MCP78U/MCP78S High Definition Audio (Pavilion p6310f)
 
 pci:v000010DEd00000774sv00001043sd000082FE*
- ID_MODEL_FROM_DATABASE=M3N72-D
+ ID_MODEL_FROM_DATABASE=MCP72XE/MCP72P/MCP78U/MCP78S High Definition Audio (M3N72-D)
 
 pci:v000010DEd00000774sv00001462sd00007508*
- ID_MODEL_FROM_DATABASE=K9N2GM-FIH
+ ID_MODEL_FROM_DATABASE=MCP72XE/MCP72P/MCP78U/MCP78S High Definition Audio (K9N2GM-FIH)
 
 pci:v000010DEd00000774sv00001849sd00003662*
- ID_MODEL_FROM_DATABASE=K10N78FullHD-hSLI R3.0 High Definition Audio
+ ID_MODEL_FROM_DATABASE=MCP72XE/MCP72P/MCP78U/MCP78S High Definition Audio (K10N78FullHD-hSLI R3.0 High Definition Audio)
 
 pci:v000010DEd00000778*
  ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] PCI Express Bridge
 
 pci:v000010DEd00000778sv0000103Csd00002A9E*
- ID_MODEL_FROM_DATABASE=Pavilion p6310f
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] PCI Express Bridge (Pavilion p6310f)
 
 pci:v000010DEd00000778sv00001043sd000082E8*
- ID_MODEL_FROM_DATABASE=M3N72-D
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] PCI Express Bridge (M3N72-D)
 
 pci:v000010DEd00000778sv00001462sd00007508*
- ID_MODEL_FROM_DATABASE=K9N2GM-FIH
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] PCI Express Bridge (K9N2GM-FIH)
 
 pci:v000010DEd00000778sv00001849sd00000778*
- ID_MODEL_FROM_DATABASE=K10N78FullHD-hSLI R3.0 PCI Express Bridge
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] PCI Express Bridge (K10N78FullHD-hSLI R3.0 PCI Express Bridge)
 
 pci:v000010DEd0000077A*
  ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] PCI Bridge
 
 pci:v000010DEd0000077Asv0000103Csd00002A9E*
- ID_MODEL_FROM_DATABASE=Pavilion p6310f
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] PCI Bridge (Pavilion p6310f)
 
 pci:v000010DEd0000077Asv00001043sd000082E8*
- ID_MODEL_FROM_DATABASE=M3N72-D
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] PCI Bridge (M3N72-D)
 
 pci:v000010DEd0000077Asv00001462sd00007508*
- ID_MODEL_FROM_DATABASE=K9N2GM-FIH
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] PCI Bridge (K9N2GM-FIH)
 
 pci:v000010DEd0000077Asv00001849sd0000077A*
- ID_MODEL_FROM_DATABASE=K10N78FullHD-hSLI R3.0 PCI Bridge
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] PCI Bridge (K10N78FullHD-hSLI R3.0 PCI Bridge)
 
 pci:v000010DEd0000077B*
  ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] OHCI USB 1.1 Controller
 
 pci:v000010DEd0000077Bsv0000103Csd00002A9E*
- ID_MODEL_FROM_DATABASE=Pavilion p6310f
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] OHCI USB 1.1 Controller (Pavilion p6310f)
 
 pci:v000010DEd0000077Bsv00001043sd000082E8*
- ID_MODEL_FROM_DATABASE=M3N72-D
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] OHCI USB 1.1 Controller (M3N72-D)
 
 pci:v000010DEd0000077Bsv00001462sd00007508*
- ID_MODEL_FROM_DATABASE=K9N2GM-FIH
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] OHCI USB 1.1 Controller (K9N2GM-FIH)
 
 pci:v000010DEd0000077Bsv00001849sd0000077B*
- ID_MODEL_FROM_DATABASE=K10N78FullHD-hSLI R3.0 OHCI USB 1.1 Controller
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] OHCI USB 1.1 Controller (K10N78FullHD-hSLI R3.0 OHCI USB 1.1 Controller)
 
 pci:v000010DEd0000077C*
  ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] EHCI USB 2.0 Controller
 
 pci:v000010DEd0000077Csv0000103Csd00002A9E*
- ID_MODEL_FROM_DATABASE=Pavilion p6310f
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] EHCI USB 2.0 Controller (Pavilion p6310f)
 
 pci:v000010DEd0000077Csv00001043sd000082E8*
- ID_MODEL_FROM_DATABASE=M3N72-D
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] EHCI USB 2.0 Controller (M3N72-D)
 
 pci:v000010DEd0000077Csv00001462sd00007508*
- ID_MODEL_FROM_DATABASE=K9N2GM-FIH
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] EHCI USB 2.0 Controller (K9N2GM-FIH)
 
 pci:v000010DEd0000077Csv00001849sd0000077C*
- ID_MODEL_FROM_DATABASE=K10N78FullHD-hSLI R3.0 EHCI USB 2.0 Controller
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] EHCI USB 2.0 Controller (K10N78FullHD-hSLI R3.0 EHCI USB 2.0 Controller)
 
 pci:v000010DEd0000077D*
  ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] OHCI USB 1.1 Controller
 
 pci:v000010DEd0000077Dsv0000103Csd00002A9E*
- ID_MODEL_FROM_DATABASE=Pavilion p6310f
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] OHCI USB 1.1 Controller (Pavilion p6310f)
 
 pci:v000010DEd0000077Dsv00001043sd000082E8*
- ID_MODEL_FROM_DATABASE=M3N72-D
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] OHCI USB 1.1 Controller (M3N72-D)
 
 pci:v000010DEd0000077Dsv00001462sd00007508*
- ID_MODEL_FROM_DATABASE=K9N2GM-FIH
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] OHCI USB 1.1 Controller (K9N2GM-FIH)
 
 pci:v000010DEd0000077Dsv00001849sd0000077D*
- ID_MODEL_FROM_DATABASE=K10N78FullHD-hSLI R3.0 OHCI USB 1.1 Controller
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] OHCI USB 1.1 Controller (K10N78FullHD-hSLI R3.0 OHCI USB 1.1 Controller)
 
 pci:v000010DEd0000077E*
  ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] EHCI USB 2.0 Controller
 
 pci:v000010DEd0000077Esv0000103Csd00002A9E*
- ID_MODEL_FROM_DATABASE=Pavilion p6310f
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] EHCI USB 2.0 Controller (Pavilion p6310f)
 
 pci:v000010DEd0000077Esv00001043sd000082E8*
- ID_MODEL_FROM_DATABASE=M3N72-D
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] EHCI USB 2.0 Controller (M3N72-D)
 
 pci:v000010DEd0000077Esv00001462sd00007508*
- ID_MODEL_FROM_DATABASE=K9N2GM-FIH
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] EHCI USB 2.0 Controller (K9N2GM-FIH)
 
 pci:v000010DEd0000077Esv00001849sd0000077E*
- ID_MODEL_FROM_DATABASE=K10N78FullHD-hSLI R3.0 EHCI USB 2.0 Controller
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] EHCI USB 2.0 Controller (K10N78FullHD-hSLI R3.0 EHCI USB 2.0 Controller)
 
 pci:v000010DEd000007C0*
  ID_MODEL_FROM_DATABASE=MCP73 Host Bridge
 
 pci:v000010DEd000007C0sv00001AFAsd00007150*
- ID_MODEL_FROM_DATABASE=JW-IN7150-HD
+ ID_MODEL_FROM_DATABASE=MCP73 Host Bridge (JW-IN7150-HD)
 
 pci:v000010DEd000007C1*
  ID_MODEL_FROM_DATABASE=MCP73 Host Bridge
 
 pci:v000010DEd000007C1sv00001019sd0000297A*
- ID_MODEL_FROM_DATABASE=MCP73PVT-SM
+ ID_MODEL_FROM_DATABASE=MCP73 Host Bridge (MCP73PVT-SM)
 
 pci:v000010DEd000007C2*
  ID_MODEL_FROM_DATABASE=MCP73 Host Bridge
@@ -24576,124 +25059,124 @@ pci:v000010DEd000007C8*
  ID_MODEL_FROM_DATABASE=MCP73 Memory Controller
 
 pci:v000010DEd000007C8sv00001019sd0000297A*
- ID_MODEL_FROM_DATABASE=MCP73PVT-SM
+ ID_MODEL_FROM_DATABASE=MCP73 Memory Controller (MCP73PVT-SM)
 
 pci:v000010DEd000007C8sv00001AFAsd00007150*
- ID_MODEL_FROM_DATABASE=JW-IN7150-HD
+ ID_MODEL_FROM_DATABASE=MCP73 Memory Controller (JW-IN7150-HD)
 
 pci:v000010DEd000007CB*
  ID_MODEL_FROM_DATABASE=nForce 630i memory controller
 
 pci:v000010DEd000007CBsv00001019sd0000297A*
- ID_MODEL_FROM_DATABASE=MCP73PVT-SM
+ ID_MODEL_FROM_DATABASE=nForce 630i memory controller (MCP73PVT-SM)
 
 pci:v000010DEd000007CBsv00001AFAsd00007150*
- ID_MODEL_FROM_DATABASE=JW-IN7150-HD
+ ID_MODEL_FROM_DATABASE=nForce 630i memory controller (JW-IN7150-HD)
 
 pci:v000010DEd000007CD*
  ID_MODEL_FROM_DATABASE=nForce 630i memory controller
 
 pci:v000010DEd000007CDsv00001019sd0000297A*
- ID_MODEL_FROM_DATABASE=MCP73PVT-SM
+ ID_MODEL_FROM_DATABASE=nForce 630i memory controller (MCP73PVT-SM)
 
 pci:v000010DEd000007CDsv00001AFAsd00007150*
- ID_MODEL_FROM_DATABASE=JW-IN7150-HD
+ ID_MODEL_FROM_DATABASE=nForce 630i memory controller (JW-IN7150-HD)
 
 pci:v000010DEd000007CE*
  ID_MODEL_FROM_DATABASE=nForce 630i memory controller
 
 pci:v000010DEd000007CEsv00001019sd0000297A*
- ID_MODEL_FROM_DATABASE=MCP73PVT-SM
+ ID_MODEL_FROM_DATABASE=nForce 630i memory controller (MCP73PVT-SM)
 
 pci:v000010DEd000007CEsv00001AFAsd00007150*
- ID_MODEL_FROM_DATABASE=JW-IN7150-HD
+ ID_MODEL_FROM_DATABASE=nForce 630i memory controller (JW-IN7150-HD)
 
 pci:v000010DEd000007CF*
  ID_MODEL_FROM_DATABASE=nForce 630i memory controller
 
 pci:v000010DEd000007CFsv00001019sd0000297A*
- ID_MODEL_FROM_DATABASE=MCP73PVT-SM
+ ID_MODEL_FROM_DATABASE=nForce 630i memory controller (MCP73PVT-SM)
 
 pci:v000010DEd000007CFsv00001AFAsd00007150*
- ID_MODEL_FROM_DATABASE=JW-IN7150-HD
+ ID_MODEL_FROM_DATABASE=nForce 630i memory controller (JW-IN7150-HD)
 
 pci:v000010DEd000007D0*
  ID_MODEL_FROM_DATABASE=nForce 630i memory controller
 
 pci:v000010DEd000007D0sv00001019sd0000297A*
- ID_MODEL_FROM_DATABASE=MCP73PVT-SM
+ ID_MODEL_FROM_DATABASE=nForce 630i memory controller (MCP73PVT-SM)
 
 pci:v000010DEd000007D0sv00001AFAsd00007150*
- ID_MODEL_FROM_DATABASE=JW-IN7150-HD
+ ID_MODEL_FROM_DATABASE=nForce 630i memory controller (JW-IN7150-HD)
 
 pci:v000010DEd000007D1*
  ID_MODEL_FROM_DATABASE=nForce 630i memory controller
 
 pci:v000010DEd000007D1sv00001019sd0000297A*
- ID_MODEL_FROM_DATABASE=MCP73PVT-SM
+ ID_MODEL_FROM_DATABASE=nForce 630i memory controller (MCP73PVT-SM)
 
 pci:v000010DEd000007D1sv00001AFAsd00007150*
- ID_MODEL_FROM_DATABASE=JW-IN7150-HD
+ ID_MODEL_FROM_DATABASE=nForce 630i memory controller (JW-IN7150-HD)
 
 pci:v000010DEd000007D2*
  ID_MODEL_FROM_DATABASE=nForce 630i memory controller
 
 pci:v000010DEd000007D2sv00001019sd0000297A*
- ID_MODEL_FROM_DATABASE=MCP73PVT-SM
+ ID_MODEL_FROM_DATABASE=nForce 630i memory controller (MCP73PVT-SM)
 
 pci:v000010DEd000007D2sv00001AFAsd00007150*
- ID_MODEL_FROM_DATABASE=JW-IN7150-HD
+ ID_MODEL_FROM_DATABASE=nForce 630i memory controller (JW-IN7150-HD)
 
 pci:v000010DEd000007D3*
  ID_MODEL_FROM_DATABASE=nForce 630i memory controller
 
 pci:v000010DEd000007D3sv00001019sd0000297A*
- ID_MODEL_FROM_DATABASE=MCP73PVT-SM
+ ID_MODEL_FROM_DATABASE=nForce 630i memory controller (MCP73PVT-SM)
 
 pci:v000010DEd000007D3sv00001AFAsd00007150*
- ID_MODEL_FROM_DATABASE=JW-IN7150-HD
+ ID_MODEL_FROM_DATABASE=nForce 630i memory controller (JW-IN7150-HD)
 
 pci:v000010DEd000007D6*
  ID_MODEL_FROM_DATABASE=nForce 630i memory controller
 
 pci:v000010DEd000007D6sv00001019sd0000297A*
- ID_MODEL_FROM_DATABASE=MCP73PVT-SM
+ ID_MODEL_FROM_DATABASE=nForce 630i memory controller (MCP73PVT-SM)
 
 pci:v000010DEd000007D6sv00001AFAsd00007150*
- ID_MODEL_FROM_DATABASE=JW-IN7150-HD
+ ID_MODEL_FROM_DATABASE=nForce 630i memory controller (JW-IN7150-HD)
 
 pci:v000010DEd000007D7*
  ID_MODEL_FROM_DATABASE=MCP73 LPC Bridge
 
 pci:v000010DEd000007D7sv00001019sd0000297A*
- ID_MODEL_FROM_DATABASE=MCP73PVT-SM
+ ID_MODEL_FROM_DATABASE=MCP73 LPC Bridge (MCP73PVT-SM)
 
 pci:v000010DEd000007D7sv00001AFAsd00007150*
- ID_MODEL_FROM_DATABASE=JW-IN7150-HD
+ ID_MODEL_FROM_DATABASE=MCP73 LPC Bridge (JW-IN7150-HD)
 
 pci:v000010DEd000007D8*
  ID_MODEL_FROM_DATABASE=MCP73 SMBus
 
 pci:v000010DEd000007D8sv00001019sd0000297A*
- ID_MODEL_FROM_DATABASE=MCP73PVT-SM
+ ID_MODEL_FROM_DATABASE=MCP73 SMBus (MCP73PVT-SM)
 
 pci:v000010DEd000007D8sv00001AFAsd00007150*
- ID_MODEL_FROM_DATABASE=JW-IN7150-HD
+ ID_MODEL_FROM_DATABASE=MCP73 SMBus (JW-IN7150-HD)
 
 pci:v000010DEd000007D9*
  ID_MODEL_FROM_DATABASE=MCP73 Memory Controller
 
 pci:v000010DEd000007D9sv00001019sd0000297A*
- ID_MODEL_FROM_DATABASE=MCP73PVT-SM
+ ID_MODEL_FROM_DATABASE=MCP73 Memory Controller (MCP73PVT-SM)
 
 pci:v000010DEd000007D9sv00001AFAsd00007150*
- ID_MODEL_FROM_DATABASE=JW-IN7150-HD
+ ID_MODEL_FROM_DATABASE=MCP73 Memory Controller (JW-IN7150-HD)
 
 pci:v000010DEd000007DA*
  ID_MODEL_FROM_DATABASE=MCP73 Co-processor
 
 pci:v000010DEd000007DAsv00001AFAsd00007150*
- ID_MODEL_FROM_DATABASE=JW-IN7150-HD
+ ID_MODEL_FROM_DATABASE=MCP73 Co-processor (JW-IN7150-HD)
 
 pci:v000010DEd000007DC*
  ID_MODEL_FROM_DATABASE=MCP73 Ethernet
@@ -24711,13 +25194,13 @@ pci:v000010DEd000007E0*
  ID_MODEL_FROM_DATABASE=C73 [GeForce 7150 / nForce 630i]
 
 pci:v000010DEd000007E0sv00001AFAsd00007150*
- ID_MODEL_FROM_DATABASE=JW-IN7150-HD
+ ID_MODEL_FROM_DATABASE=C73 [GeForce 7150 / nForce 630i] (JW-IN7150-HD)
 
 pci:v000010DEd000007E1*
  ID_MODEL_FROM_DATABASE=C73 [GeForce 7100 / nForce 630i]
 
 pci:v000010DEd000007E1sv00001019sd0000297A*
- ID_MODEL_FROM_DATABASE=MCP73PVT-SM
+ ID_MODEL_FROM_DATABASE=C73 [GeForce 7100 / nForce 630i] (MCP73PVT-SM)
 
 pci:v000010DEd000007E2*
  ID_MODEL_FROM_DATABASE=C73 [GeForce 7050 / nForce 630i]
@@ -24735,7 +25218,7 @@ pci:v000010DEd000007F4*
  ID_MODEL_FROM_DATABASE=GeForce 7100/nForce 630i SATA
 
 pci:v000010DEd000007F4sv00001019sd0000297A*
- ID_MODEL_FROM_DATABASE=MCP73PVT-SM
+ ID_MODEL_FROM_DATABASE=GeForce 7100/nForce 630i SATA (MCP73PVT-SM)
 
 pci:v000010DEd000007F8*
  ID_MODEL_FROM_DATABASE=MCP73 SATA RAID Controller
@@ -24744,7 +25227,7 @@ pci:v000010DEd000007FC*
  ID_MODEL_FROM_DATABASE=MCP73 High Definition Audio
 
 pci:v000010DEd000007FCsv00001019sd0000297A*
- ID_MODEL_FROM_DATABASE=MCP73PVT-SM
+ ID_MODEL_FROM_DATABASE=MCP73 High Definition Audio (MCP73PVT-SM)
 
 pci:v000010DEd000007FCsv000010DEsd000007FC*
  ID_MODEL_FROM_DATABASE=MCP73 High Definition Audio
@@ -24753,10 +25236,10 @@ pci:v000010DEd000007FE*
  ID_MODEL_FROM_DATABASE=GeForce 7100/nForce 630i USB
 
 pci:v000010DEd000007FEsv00001019sd0000297A*
- ID_MODEL_FROM_DATABASE=MCP73PVT-SM
+ ID_MODEL_FROM_DATABASE=GeForce 7100/nForce 630i USB (MCP73PVT-SM)
 
 pci:v000010DEd000007FEsv00001AFAsd00007150*
- ID_MODEL_FROM_DATABASE=JW-IN7150-HD
+ ID_MODEL_FROM_DATABASE=GeForce 7100/nForce 630i USB (JW-IN7150-HD)
 
 pci:v000010DEd00000840*
  ID_MODEL_FROM_DATABASE=C77 [GeForce 8200M]
@@ -24774,7 +25257,7 @@ pci:v000010DEd00000847*
  ID_MODEL_FROM_DATABASE=C78 [GeForce 9100]
 
 pci:v000010DEd00000847sv0000103Csd00002A9E*
- ID_MODEL_FROM_DATABASE=Pavilion p6310f
+ ID_MODEL_FROM_DATABASE=C78 [GeForce 9100] (Pavilion p6310f)
 
 pci:v000010DEd00000848*
  ID_MODEL_FROM_DATABASE=C77 [GeForce 8300]
@@ -24783,10 +25266,10 @@ pci:v000010DEd00000849*
  ID_MODEL_FROM_DATABASE=C77 [GeForce 8200]
 
 pci:v000010DEd00000849sv00001462sd00007508*
- ID_MODEL_FROM_DATABASE=K9N2GM-FIH
+ ID_MODEL_FROM_DATABASE=C77 [GeForce 8200] (K9N2GM-FIH)
 
 pci:v000010DEd00000849sv00001849sd00000849*
- ID_MODEL_FROM_DATABASE=K10N78FullHD-hSLI R3.0 GeForce 8200
+ ID_MODEL_FROM_DATABASE=C77 [GeForce 8200] (K10N78FullHD-hSLI R3.0 GeForce 8200)
 
 pci:v000010DEd0000084A*
  ID_MODEL_FROM_DATABASE=C77 [nForce 730a]
@@ -24801,7 +25284,7 @@ pci:v000010DEd0000084D*
  ID_MODEL_FROM_DATABASE=C77 [nForce 750a SLI]
 
 pci:v000010DEd0000084Dsv00001043sd000082E8*
- ID_MODEL_FROM_DATABASE=M3N72-D mGPU
+ ID_MODEL_FROM_DATABASE=C77 [nForce 750a SLI] (M3N72-D mGPU)
 
 pci:v000010DEd0000084F*
  ID_MODEL_FROM_DATABASE=C77 [GeForce 8100 / nForce 720a]
@@ -24819,7 +25302,7 @@ pci:v000010DEd00000863*
  ID_MODEL_FROM_DATABASE=C79 [GeForce 9400M]
 
 pci:v000010DEd00000863sv0000106Bsd000000AA*
- ID_MODEL_FROM_DATABASE=MacBook5,1
+ ID_MODEL_FROM_DATABASE=C79 [GeForce 9400M] (MacBook5,1)
 
 pci:v000010DEd00000864*
  ID_MODEL_FROM_DATABASE=C79 [GeForce 9300]
@@ -24831,13 +25314,13 @@ pci:v000010DEd00000866*
  ID_MODEL_FROM_DATABASE=C79 [GeForce 9400M G]
 
 pci:v000010DEd00000866sv0000106Bsd000000B1*
- ID_MODEL_FROM_DATABASE=GeForce 9400M
+ ID_MODEL_FROM_DATABASE=C79 [GeForce 9400M G] (GeForce 9400M)
 
 pci:v000010DEd00000867*
  ID_MODEL_FROM_DATABASE=C79 [GeForce 9400]
 
 pci:v000010DEd00000867sv0000106Bsd000000AD*
- ID_MODEL_FROM_DATABASE=iMac 9,1
+ ID_MODEL_FROM_DATABASE=C79 [GeForce 9400] (iMac 9,1)
 
 pci:v000010DEd00000868*
  ID_MODEL_FROM_DATABASE=C79 [nForce 760i SLI]
@@ -24858,7 +25341,7 @@ pci:v000010DEd0000086E*
  ID_MODEL_FROM_DATABASE=C79 [GeForce 9100M G]
 
 pci:v000010DEd0000086F*
- ID_MODEL_FROM_DATABASE=C79 [GeForce 9200M G]
+ ID_MODEL_FROM_DATABASE=MCP79 [GeForce 8200M G]
 
 pci:v000010DEd00000870*
  ID_MODEL_FROM_DATABASE=C79 [GeForce 9400M]
@@ -24870,28 +25353,28 @@ pci:v000010DEd00000872*
  ID_MODEL_FROM_DATABASE=C79 [GeForce G102M]
 
 pci:v000010DEd00000872sv00001043sd000019B4*
- ID_MODEL_FROM_DATABASE=GeForce G102M
+ ID_MODEL_FROM_DATABASE=C79 [GeForce G102M] (GeForce G102M)
 
 pci:v000010DEd00000872sv00001043sd00001AA2*
- ID_MODEL_FROM_DATABASE=GeForce G102M
+ ID_MODEL_FROM_DATABASE=C79 [GeForce G102M] (GeForce G102M)
 
 pci:v000010DEd00000872sv00001043sd00001C02*
- ID_MODEL_FROM_DATABASE=GeForce G102M
+ ID_MODEL_FROM_DATABASE=C79 [GeForce G102M] (GeForce G102M)
 
 pci:v000010DEd00000872sv00001043sd00001C42*
- ID_MODEL_FROM_DATABASE=GeForce G205M
+ ID_MODEL_FROM_DATABASE=C79 [GeForce G102M] (GeForce G205M)
 
 pci:v000010DEd00000873*
  ID_MODEL_FROM_DATABASE=C79 [GeForce G102M]
 
 pci:v000010DEd00000873sv00001043sd000019B4*
- ID_MODEL_FROM_DATABASE=GeForce G102M
+ ID_MODEL_FROM_DATABASE=C79 [GeForce G102M] (GeForce G102M)
 
 pci:v000010DEd00000873sv00001043sd00001C12*
- ID_MODEL_FROM_DATABASE=GeForce G102M
+ ID_MODEL_FROM_DATABASE=C79 [GeForce G102M] (GeForce G102M)
 
 pci:v000010DEd00000873sv00001043sd00001C52*
- ID_MODEL_FROM_DATABASE=GeForce G205M
+ ID_MODEL_FROM_DATABASE=C79 [GeForce G102M] (GeForce G205M)
 
 pci:v000010DEd00000874*
  ID_MODEL_FROM_DATABASE=C79 [ION]
@@ -24906,7 +25389,7 @@ pci:v000010DEd0000087D*
  ID_MODEL_FROM_DATABASE=ION VGA
 
 pci:v000010DEd0000087Dsv000019DAsd0000A123*
- ID_MODEL_FROM_DATABASE=IONITX-F-E
+ ID_MODEL_FROM_DATABASE=ION VGA (IONITX-F-E)
 
 pci:v000010DEd0000087E*
  ID_MODEL_FROM_DATABASE=ION LE VGA
@@ -24933,7 +25416,7 @@ pci:v000010DEd00000A20*
  ID_MODEL_FROM_DATABASE=GT216 [GeForce GT 220]
 
 pci:v000010DEd00000A20sv00001043sd00008311*
- ID_MODEL_FROM_DATABASE=ENGT220/DI/1GD3(LP)/V2
+ ID_MODEL_FROM_DATABASE=GT216 [GeForce GT 220] (ENGT220/DI/1GD3(LP)/V2)
 
 pci:v000010DEd00000A21*
  ID_MODEL_FROM_DATABASE=GT216M [GeForce GT 330M]
@@ -25002,7 +25485,7 @@ pci:v000010DEd00000A65*
  ID_MODEL_FROM_DATABASE=GT218 [GeForce 210]
 
 pci:v000010DEd00000A65sv00001043sd00008334*
- ID_MODEL_FROM_DATABASE=EN210 SILENT
+ ID_MODEL_FROM_DATABASE=GT218 [GeForce 210] (EN210 SILENT)
 
 pci:v000010DEd00000A66*
  ID_MODEL_FROM_DATABASE=GT218 [GeForce 310]
@@ -25023,10 +25506,10 @@ pci:v000010DEd00000A6C*
  ID_MODEL_FROM_DATABASE=GT218M [NVS 3100M]
 
 pci:v000010DEd00000A6Csv00001028sd0000040B*
- ID_MODEL_FROM_DATABASE=Latitude E6510
+ ID_MODEL_FROM_DATABASE=GT218M [NVS 3100M] (Latitude E6510)
 
 pci:v000010DEd00000A6Csv000017AAsd00002142*
- ID_MODEL_FROM_DATABASE=ThinkPad T410
+ ID_MODEL_FROM_DATABASE=GT218M [NVS 3100M] (ThinkPad T410)
 
 pci:v000010DEd00000A6E*
  ID_MODEL_FROM_DATABASE=GT218M [GeForce 305M]
@@ -25050,7 +25533,7 @@ pci:v000010DEd00000A74*
  ID_MODEL_FROM_DATABASE=GT218M [GeForce G210M]
 
 pci:v000010DEd00000A74sv00001B0Asd0000903A*
- ID_MODEL_FROM_DATABASE=GeForce G210
+ ID_MODEL_FROM_DATABASE=GT218M [GeForce G210M] (GeForce G210)
 
 pci:v000010DEd00000A75*
  ID_MODEL_FROM_DATABASE=GT218M [GeForce 310M]
@@ -25065,127 +25548,127 @@ pci:v000010DEd00000A7A*
  ID_MODEL_FROM_DATABASE=GT218M [GeForce 315M]
 
 pci:v000010DEd00000A7Asv0000104Dsd0000907E*
- ID_MODEL_FROM_DATABASE=GeForce 315M
+ ID_MODEL_FROM_DATABASE=GT218M [GeForce 315M] (GeForce 315M)
 
 pci:v000010DEd00000A7Asv00001179sd0000FC50*
- ID_MODEL_FROM_DATABASE=GeForce 315M
+ ID_MODEL_FROM_DATABASE=GT218M [GeForce 315M] (GeForce 315M)
 
 pci:v000010DEd00000A7Asv00001179sd0000FC61*
- ID_MODEL_FROM_DATABASE=GeForce 315M
+ ID_MODEL_FROM_DATABASE=GT218M [GeForce 315M] (GeForce 315M)
 
 pci:v000010DEd00000A7Asv00001179sd0000FC71*
- ID_MODEL_FROM_DATABASE=GeForce 315M
+ ID_MODEL_FROM_DATABASE=GT218M [GeForce 315M] (GeForce 315M)
 
 pci:v000010DEd00000A7Asv00001179sd0000FC90*
- ID_MODEL_FROM_DATABASE=GeForce 315M
+ ID_MODEL_FROM_DATABASE=GT218M [GeForce 315M] (GeForce 315M)
 
 pci:v000010DEd00000A7Asv00001179sd0000FCC0*
- ID_MODEL_FROM_DATABASE=GeForce 315M
+ ID_MODEL_FROM_DATABASE=GT218M [GeForce 315M] (GeForce 315M)
 
 pci:v000010DEd00000A7Asv00001179sd0000FCD0*
- ID_MODEL_FROM_DATABASE=GeForce 315M
+ ID_MODEL_FROM_DATABASE=GT218M [GeForce 315M] (GeForce 315M)
 
 pci:v000010DEd00000A7Asv00001179sd0000FCE2*
- ID_MODEL_FROM_DATABASE=GeForce 315M
+ ID_MODEL_FROM_DATABASE=GT218M [GeForce 315M] (GeForce 315M)
 
 pci:v000010DEd00000A7Asv00001179sd0000FCF2*
- ID_MODEL_FROM_DATABASE=GeForce 315M
+ ID_MODEL_FROM_DATABASE=GT218M [GeForce 315M] (GeForce 315M)
 
 pci:v000010DEd00000A7Asv00001179sd0000FD16*
- ID_MODEL_FROM_DATABASE=GeForce 315M
+ ID_MODEL_FROM_DATABASE=GT218M [GeForce 315M] (GeForce 315M)
 
 pci:v000010DEd00000A7Asv00001179sd0000FD40*
- ID_MODEL_FROM_DATABASE=GeForce 315M
+ ID_MODEL_FROM_DATABASE=GT218M [GeForce 315M] (GeForce 315M)
 
 pci:v000010DEd00000A7Asv00001179sd0000FD50*
- ID_MODEL_FROM_DATABASE=GeForce 315M
+ ID_MODEL_FROM_DATABASE=GT218M [GeForce 315M] (GeForce 315M)
 
 pci:v000010DEd00000A7Asv00001179sd0000FD52*
- ID_MODEL_FROM_DATABASE=GeForce 315M
+ ID_MODEL_FROM_DATABASE=GT218M [GeForce 315M] (GeForce 315M)
 
 pci:v000010DEd00000A7Asv00001179sd0000FD61*
- ID_MODEL_FROM_DATABASE=GeForce 315M
+ ID_MODEL_FROM_DATABASE=GT218M [GeForce 315M] (GeForce 315M)
 
 pci:v000010DEd00000A7Asv00001179sd0000FD71*
- ID_MODEL_FROM_DATABASE=GeForce 315M
+ ID_MODEL_FROM_DATABASE=GT218M [GeForce 315M] (GeForce 315M)
 
 pci:v000010DEd00000A7Asv00001179sd0000FD92*
- ID_MODEL_FROM_DATABASE=GeForce 315M
+ ID_MODEL_FROM_DATABASE=GT218M [GeForce 315M] (GeForce 315M)
 
 pci:v000010DEd00000A7Asv00001179sd0000FD96*
- ID_MODEL_FROM_DATABASE=GeForce 315M
+ ID_MODEL_FROM_DATABASE=GT218M [GeForce 315M] (GeForce 315M)
 
 pci:v000010DEd00000A7Asv00001179sd0000FDD0*
- ID_MODEL_FROM_DATABASE=GeForce 315M
+ ID_MODEL_FROM_DATABASE=GT218M [GeForce 315M] (GeForce 315M)
 
 pci:v000010DEd00000A7Asv00001179sd0000FDD2*
- ID_MODEL_FROM_DATABASE=GeForce 315M
+ ID_MODEL_FROM_DATABASE=GT218M [GeForce 315M] (GeForce 315M)
 
 pci:v000010DEd00000A7Asv00001179sd0000FDFE*
- ID_MODEL_FROM_DATABASE=GeForce 315M
+ ID_MODEL_FROM_DATABASE=GT218M [GeForce 315M] (GeForce 315M)
 
 pci:v000010DEd00000A7Asv0000144Dsd0000C0A2*
- ID_MODEL_FROM_DATABASE=GeForce 315M
+ ID_MODEL_FROM_DATABASE=GT218M [GeForce 315M] (GeForce 315M)
 
 pci:v000010DEd00000A7Asv0000144Dsd0000C0B2*
- ID_MODEL_FROM_DATABASE=GeForce 315M
+ ID_MODEL_FROM_DATABASE=GT218M [GeForce 315M] (GeForce 315M)
 
 pci:v000010DEd00000A7Asv0000144Dsd0000C581*
- ID_MODEL_FROM_DATABASE=GeForce 315M
+ ID_MODEL_FROM_DATABASE=GT218M [GeForce 315M] (GeForce 315M)
 
 pci:v000010DEd00000A7Asv0000144Dsd0000C587*
- ID_MODEL_FROM_DATABASE=GeForce 315M
+ ID_MODEL_FROM_DATABASE=GT218M [GeForce 315M] (GeForce 315M)
 
 pci:v000010DEd00000A7Asv0000144Dsd0000C588*
- ID_MODEL_FROM_DATABASE=GeForce 315M
+ ID_MODEL_FROM_DATABASE=GT218M [GeForce 315M] (GeForce 315M)
 
 pci:v000010DEd00000A7Asv0000144Dsd0000C597*
- ID_MODEL_FROM_DATABASE=GeForce 315M
+ ID_MODEL_FROM_DATABASE=GT218M [GeForce 315M] (GeForce 315M)
 
 pci:v000010DEd00000A7Asv0000144Dsd0000C606*
- ID_MODEL_FROM_DATABASE=GeForce 315M
+ ID_MODEL_FROM_DATABASE=GT218M [GeForce 315M] (GeForce 315M)
 
 pci:v000010DEd00000A7Asv00001462sd0000AA51*
- ID_MODEL_FROM_DATABASE=GeForce 405
+ ID_MODEL_FROM_DATABASE=GT218M [GeForce 315M] (GeForce 405)
 
 pci:v000010DEd00000A7Asv00001462sd0000AA58*
- ID_MODEL_FROM_DATABASE=GeForce 405
+ ID_MODEL_FROM_DATABASE=GT218M [GeForce 315M] (GeForce 405)
 
 pci:v000010DEd00000A7Asv00001462sd0000AC71*
- ID_MODEL_FROM_DATABASE=GeForce 405
+ ID_MODEL_FROM_DATABASE=GT218M [GeForce 315M] (GeForce 405)
 
 pci:v000010DEd00000A7Asv00001462sd0000AC81*
- ID_MODEL_FROM_DATABASE=GeForce 315M
+ ID_MODEL_FROM_DATABASE=GT218M [GeForce 315M] (GeForce 315M)
 
 pci:v000010DEd00000A7Asv00001462sd0000AC82*
- ID_MODEL_FROM_DATABASE=GeForce 405
+ ID_MODEL_FROM_DATABASE=GT218M [GeForce 315M] (GeForce 405)
 
 pci:v000010DEd00000A7Asv00001462sd0000AE33*
- ID_MODEL_FROM_DATABASE=GeForce 405
+ ID_MODEL_FROM_DATABASE=GT218M [GeForce 315M] (GeForce 405)
 
 pci:v000010DEd00000A7Asv00001642sd00003980*
- ID_MODEL_FROM_DATABASE=GeForce 405
+ ID_MODEL_FROM_DATABASE=GT218M [GeForce 315M] (GeForce 405)
 
 pci:v000010DEd00000A7Asv000017AAsd00003950*
- ID_MODEL_FROM_DATABASE=GeForce 405M
+ ID_MODEL_FROM_DATABASE=GT218M [GeForce 315M] (GeForce 405M)
 
 pci:v000010DEd00000A7Asv000017AAsd0000397D*
- ID_MODEL_FROM_DATABASE=GeForce 405M
+ ID_MODEL_FROM_DATABASE=GT218M [GeForce 315M] (GeForce 405M)
 
 pci:v000010DEd00000A7Asv00001B0Asd00002091*
- ID_MODEL_FROM_DATABASE=GeForce 315M
+ ID_MODEL_FROM_DATABASE=GT218M [GeForce 315M] (GeForce 315M)
 
 pci:v000010DEd00000A7Asv00001B0Asd000090B4*
- ID_MODEL_FROM_DATABASE=GeForce 405
+ ID_MODEL_FROM_DATABASE=GT218M [GeForce 315M] (GeForce 405)
 
 pci:v000010DEd00000A7Asv00001BFDsd00000003*
- ID_MODEL_FROM_DATABASE=GeForce 405
+ ID_MODEL_FROM_DATABASE=GT218M [GeForce 315M] (GeForce 405)
 
 pci:v000010DEd00000A7Asv00001BFDsd00008006*
- ID_MODEL_FROM_DATABASE=GeForce 405
+ ID_MODEL_FROM_DATABASE=GT218M [GeForce 315M] (GeForce 405)
 
 pci:v000010DEd00000A7Asv00001BFDsd00008007*
- ID_MODEL_FROM_DATABASE=GeForce 315M
+ ID_MODEL_FROM_DATABASE=GT218M [GeForce 315M] (GeForce 315M)
 
 pci:v000010DEd00000A7B*
  ID_MODEL_FROM_DATABASE=GT218 [GeForce 505]
@@ -25227,64 +25710,64 @@ pci:v000010DEd00000A98*
  ID_MODEL_FROM_DATABASE=MCP79 Memory Controller
 
 pci:v000010DEd00000A98sv000010DEsd0000CB79*
- ID_MODEL_FROM_DATABASE=iMac 9,1
+ ID_MODEL_FROM_DATABASE=MCP79 Memory Controller (iMac 9,1)
 
 pci:v000010DEd00000AA0*
  ID_MODEL_FROM_DATABASE=MCP79 PCI Express Bridge
 
 pci:v000010DEd00000AA0sv000010DEsd0000CB79*
- ID_MODEL_FROM_DATABASE=Apple iMac 9,1
+ ID_MODEL_FROM_DATABASE=MCP79 PCI Express Bridge (Apple iMac 9,1)
 
 pci:v000010DEd00000AA2*
  ID_MODEL_FROM_DATABASE=MCP79 SMBus
 
 pci:v000010DEd00000AA2sv000010DEsd0000CB79*
- ID_MODEL_FROM_DATABASE=Apple iMac 9,1
+ ID_MODEL_FROM_DATABASE=MCP79 SMBus (Apple iMac 9,1)
 
 pci:v000010DEd00000AA2sv000019DAsd0000A123*
- ID_MODEL_FROM_DATABASE=IONITX-F-E
+ ID_MODEL_FROM_DATABASE=MCP79 SMBus (IONITX-F-E)
 
 pci:v000010DEd00000AA3*
  ID_MODEL_FROM_DATABASE=MCP79 Co-processor
 
 pci:v000010DEd00000AA3sv000010DEsd0000CB79*
- ID_MODEL_FROM_DATABASE=Apple iMac 9,1
+ ID_MODEL_FROM_DATABASE=MCP79 Co-processor (Apple iMac 9,1)
 
 pci:v000010DEd00000AA3sv000019DAsd0000A123*
- ID_MODEL_FROM_DATABASE=IONITX-F-E
+ ID_MODEL_FROM_DATABASE=MCP79 Co-processor (IONITX-F-E)
 
 pci:v000010DEd00000AA4*
  ID_MODEL_FROM_DATABASE=MCP79 Memory Controller
 
 pci:v000010DEd00000AA4sv000019DAsd0000A123*
- ID_MODEL_FROM_DATABASE=IONITX-F-E
+ ID_MODEL_FROM_DATABASE=MCP79 Memory Controller (IONITX-F-E)
 
 pci:v000010DEd00000AA5*
  ID_MODEL_FROM_DATABASE=MCP79 OHCI USB 1.1 Controller
 
 pci:v000010DEd00000AA5sv000010DEsd0000CB79*
- ID_MODEL_FROM_DATABASE=Apple iMac 9,1
+ ID_MODEL_FROM_DATABASE=MCP79 OHCI USB 1.1 Controller (Apple iMac 9,1)
 
 pci:v000010DEd00000AA5sv000019DAsd0000A123*
- ID_MODEL_FROM_DATABASE=IONITX-F-E
+ ID_MODEL_FROM_DATABASE=MCP79 OHCI USB 1.1 Controller (IONITX-F-E)
 
 pci:v000010DEd00000AA6*
  ID_MODEL_FROM_DATABASE=MCP79 EHCI USB 2.0 Controller
 
 pci:v000010DEd00000AA6sv000010DEsd0000CB79*
- ID_MODEL_FROM_DATABASE=Apple iMac 9,1
+ ID_MODEL_FROM_DATABASE=MCP79 EHCI USB 2.0 Controller (Apple iMac 9,1)
 
 pci:v000010DEd00000AA6sv000019DAsd0000A123*
- ID_MODEL_FROM_DATABASE=IONITX-F-E
+ ID_MODEL_FROM_DATABASE=MCP79 EHCI USB 2.0 Controller (IONITX-F-E)
 
 pci:v000010DEd00000AA7*
  ID_MODEL_FROM_DATABASE=MCP79 OHCI USB 1.1 Controller
 
 pci:v000010DEd00000AA7sv000010DEsd0000CB79*
- ID_MODEL_FROM_DATABASE=Apple iMac 9,1
+ ID_MODEL_FROM_DATABASE=MCP79 OHCI USB 1.1 Controller (Apple iMac 9,1)
 
 pci:v000010DEd00000AA7sv000019DAsd0000A123*
- ID_MODEL_FROM_DATABASE=IONITX-F-E
+ ID_MODEL_FROM_DATABASE=MCP79 OHCI USB 1.1 Controller (IONITX-F-E)
 
 pci:v000010DEd00000AA8*
  ID_MODEL_FROM_DATABASE=MCP79 OHCI USB 1.1 Controller
@@ -25293,10 +25776,10 @@ pci:v000010DEd00000AA9*
  ID_MODEL_FROM_DATABASE=MCP79 EHCI USB 2.0 Controller
 
 pci:v000010DEd00000AA9sv000010DEsd0000CB79*
- ID_MODEL_FROM_DATABASE=Apple iMac 9,1
+ ID_MODEL_FROM_DATABASE=MCP79 EHCI USB 2.0 Controller (Apple iMac 9,1)
 
 pci:v000010DEd00000AA9sv000019DAsd0000A123*
- ID_MODEL_FROM_DATABASE=IONITX-F-E
+ ID_MODEL_FROM_DATABASE=MCP79 EHCI USB 2.0 Controller (IONITX-F-E)
 
 pci:v000010DEd00000AAA*
  ID_MODEL_FROM_DATABASE=MCP79 EHCI USB 2.0 Controller
@@ -25305,7 +25788,7 @@ pci:v000010DEd00000AAB*
  ID_MODEL_FROM_DATABASE=MCP79 PCI Bridge
 
 pci:v000010DEd00000AABsv000010DEsd0000CB79*
- ID_MODEL_FROM_DATABASE=Apple iMac 9,1
+ ID_MODEL_FROM_DATABASE=MCP79 PCI Bridge (Apple iMac 9,1)
 
 pci:v000010DEd00000AAC*
  ID_MODEL_FROM_DATABASE=MCP79 LPC Bridge
@@ -25314,13 +25797,13 @@ pci:v000010DEd00000AAD*
  ID_MODEL_FROM_DATABASE=MCP79 LPC Bridge
 
 pci:v000010DEd00000AADsv000019DAsd0000A123*
- ID_MODEL_FROM_DATABASE=IONITX-F-E
+ ID_MODEL_FROM_DATABASE=MCP79 LPC Bridge (IONITX-F-E)
 
 pci:v000010DEd00000AAE*
  ID_MODEL_FROM_DATABASE=MCP79 LPC Bridge
 
 pci:v000010DEd00000AAEsv000010DEsd0000CB79*
- ID_MODEL_FROM_DATABASE=Apple iMac 9,1
+ ID_MODEL_FROM_DATABASE=MCP79 LPC Bridge (Apple iMac 9,1)
 
 pci:v000010DEd00000AAF*
  ID_MODEL_FROM_DATABASE=MCP79 LPC Bridge
@@ -25329,10 +25812,10 @@ pci:v000010DEd00000AB0*
  ID_MODEL_FROM_DATABASE=MCP79 Ethernet
 
 pci:v000010DEd00000AB0sv000010DEsd0000CB79*
- ID_MODEL_FROM_DATABASE=Apple iMac 9,1
+ ID_MODEL_FROM_DATABASE=MCP79 Ethernet (Apple iMac 9,1)
 
 pci:v000010DEd00000AB0sv000019DAsd0000A123*
- ID_MODEL_FROM_DATABASE=IONITX-F-E
+ ID_MODEL_FROM_DATABASE=MCP79 Ethernet (IONITX-F-E)
 
 pci:v000010DEd00000AB1*
  ID_MODEL_FROM_DATABASE=MCP79 Ethernet
@@ -25347,7 +25830,7 @@ pci:v000010DEd00000AB4*
  ID_MODEL_FROM_DATABASE=MCP79 SATA Controller
 
 pci:v000010DEd00000AB4sv000019DAsd0000A123*
- ID_MODEL_FROM_DATABASE=IONITX-F-E
+ ID_MODEL_FROM_DATABASE=MCP79 SATA Controller (IONITX-F-E)
 
 pci:v000010DEd00000AB5*
  ID_MODEL_FROM_DATABASE=MCP79 SATA Controller
@@ -25365,7 +25848,7 @@ pci:v000010DEd00000AB9*
  ID_MODEL_FROM_DATABASE=MCP79 AHCI Controller
 
 pci:v000010DEd00000AB9sv000010DEsd0000CB79*
- ID_MODEL_FROM_DATABASE=Apple iMac 9,1
+ ID_MODEL_FROM_DATABASE=MCP79 AHCI Controller (Apple iMac 9,1)
 
 pci:v000010DEd00000ABA*
  ID_MODEL_FROM_DATABASE=MCP79 AHCI Controller
@@ -25389,7 +25872,7 @@ pci:v000010DEd00000AC0*
  ID_MODEL_FROM_DATABASE=MCP79 High Definition Audio
 
 pci:v000010DEd00000AC0sv000010DEsd0000CB79*
- ID_MODEL_FROM_DATABASE=Apple iMac 9,1
+ ID_MODEL_FROM_DATABASE=MCP79 High Definition Audio (Apple iMac 9,1)
 
 pci:v000010DEd00000AC1*
  ID_MODEL_FROM_DATABASE=MCP79 High Definition Audio
@@ -25404,7 +25887,7 @@ pci:v000010DEd00000AC4*
  ID_MODEL_FROM_DATABASE=MCP79 PCI Express Bridge
 
 pci:v000010DEd00000AC4sv000010DEsd0000CB79*
- ID_MODEL_FROM_DATABASE=Apple iMac 9,1
+ ID_MODEL_FROM_DATABASE=MCP79 PCI Express Bridge (Apple iMac 9,1)
 
 pci:v000010DEd00000AC5*
  ID_MODEL_FROM_DATABASE=MCP79 PCI Express Bridge
@@ -25413,13 +25896,13 @@ pci:v000010DEd00000AC6*
  ID_MODEL_FROM_DATABASE=MCP79 PCI Express Bridge
 
 pci:v000010DEd00000AC6sv000010DEsd0000CB79*
- ID_MODEL_FROM_DATABASE=Apple iMac 9,1
+ ID_MODEL_FROM_DATABASE=MCP79 PCI Express Bridge (Apple iMac 9,1)
 
 pci:v000010DEd00000AC7*
  ID_MODEL_FROM_DATABASE=MCP79 PCI Express Bridge
 
 pci:v000010DEd00000AC7sv000010DEsd0000CB79*
- ID_MODEL_FROM_DATABASE=Apple iMac 9,1
+ ID_MODEL_FROM_DATABASE=MCP79 PCI Express Bridge (Apple iMac 9,1)
 
 pci:v000010DEd00000AC8*
  ID_MODEL_FROM_DATABASE=MCP79 PCI Express Bridge
@@ -25428,22 +25911,22 @@ pci:v000010DEd00000AD0*
  ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] SATA Controller (non-AHCI mode)
 
 pci:v000010DEd00000AD0sv00001462sd00007508*
- ID_MODEL_FROM_DATABASE=K9N2GM-FIH
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] SATA Controller (non-AHCI mode) (K9N2GM-FIH)
 
 pci:v000010DEd00000AD0sv00001849sd00000AD0*
- ID_MODEL_FROM_DATABASE=K10N78FullHD-hSLI R3.0 IDE
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] SATA Controller (non-AHCI mode) (K10N78FullHD-hSLI R3.0 IDE)
 
 pci:v000010DEd00000AD4*
  ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] AHCI Controller
 
 pci:v000010DEd00000AD4sv0000103Csd00002A9E*
- ID_MODEL_FROM_DATABASE=Pavilion p6310f
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] AHCI Controller (Pavilion p6310f)
 
 pci:v000010DEd00000AD4sv00001043sd000082E8*
- ID_MODEL_FROM_DATABASE=M3N72-D
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] AHCI Controller (M3N72-D)
 
 pci:v000010DEd00000AD4sv00001849sd00000AD4*
- ID_MODEL_FROM_DATABASE=K10N78FullHD-hSLI R3.0 AHCI Controller
+ ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] AHCI Controller (K10N78FullHD-hSLI R3.0 AHCI Controller)
 
 pci:v000010DEd00000AD8*
  ID_MODEL_FROM_DATABASE=MCP78S [GeForce 8200] SATA Controller (RAID mode)
@@ -25452,16 +25935,16 @@ pci:v000010DEd00000BE2*
  ID_MODEL_FROM_DATABASE=GT216 HDMI Audio Controller
 
 pci:v000010DEd00000BE2sv00001043sd00008311*
- ID_MODEL_FROM_DATABASE=ENGT220/DI/1GD3(LP)/V2
+ ID_MODEL_FROM_DATABASE=GT216 HDMI Audio Controller (ENGT220/DI/1GD3(LP)/V2)
 
 pci:v000010DEd00000BE3*
  ID_MODEL_FROM_DATABASE=High Definition Audio Controller
 
 pci:v000010DEd00000BE3sv00001028sd0000040B*
- ID_MODEL_FROM_DATABASE=Latitude E6510
+ ID_MODEL_FROM_DATABASE=High Definition Audio Controller (Latitude E6510)
 
 pci:v000010DEd00000BE3sv000010DEsd0000066D*
- ID_MODEL_FROM_DATABASE=G98 [GeForce 8400GS]
+ ID_MODEL_FROM_DATABASE=High Definition Audio Controller (G98 [GeForce 8400GS])
 
 pci:v000010DEd00000BE4*
  ID_MODEL_FROM_DATABASE=High Definition Audio Controller
@@ -25473,22 +25956,22 @@ pci:v000010DEd00000BE9*
  ID_MODEL_FROM_DATABASE=GF106 High Definition Audio Controller
 
 pci:v000010DEd00000BE9sv00001558sd00008687*
- ID_MODEL_FROM_DATABASE=CLEVO/KAPOK W860CU
+ ID_MODEL_FROM_DATABASE=GF106 High Definition Audio Controller (CLEVO/KAPOK W860CU)
 
 pci:v000010DEd00000BE9sv00003842sd00001452*
- ID_MODEL_FROM_DATABASE=GeForce GTS 450
+ ID_MODEL_FROM_DATABASE=GF106 High Definition Audio Controller (GeForce GTS 450)
 
 pci:v000010DEd00000BEA*
  ID_MODEL_FROM_DATABASE=GF108 High Definition Audio Controller
 
 pci:v000010DEd00000BEAsv00003842sd00001430*
- ID_MODEL_FROM_DATABASE=GeForce GT 430
+ ID_MODEL_FROM_DATABASE=GF108 High Definition Audio Controller (GeForce GT 430)
 
 pci:v000010DEd00000BEB*
  ID_MODEL_FROM_DATABASE=GF104 High Definition Audio Controller
 
 pci:v000010DEd00000BEBsv00001462sd00002322*
- ID_MODEL_FROM_DATABASE=N460GTX Cyclone 1GD5/OC
+ ID_MODEL_FROM_DATABASE=GF104 High Definition Audio Controller (N460GTX Cyclone 1GD5/OC)
 
 pci:v000010DEd00000BEE*
  ID_MODEL_FROM_DATABASE=GF116 High Definition Audio Controller
@@ -25602,7 +26085,7 @@ pci:v000010DEd00000DD1*
  ID_MODEL_FROM_DATABASE=GF106M [GeForce GTX 460M]
 
 pci:v000010DEd00000DD1sv00001558sd00008687*
- ID_MODEL_FROM_DATABASE=CLEVO/KAPOK W860CU
+ ID_MODEL_FROM_DATABASE=GF106M [GeForce GTX 460M] (CLEVO/KAPOK W860CU)
 
 pci:v000010DEd00000DD2*
  ID_MODEL_FROM_DATABASE=GF106M [GeForce GT 445M]
@@ -25617,7 +26100,7 @@ pci:v000010DEd00000DD8*
  ID_MODEL_FROM_DATABASE=GF106GL [Quadro 2000]
 
 pci:v000010DEd00000DD8sv000010DEsd00000914*
- ID_MODEL_FROM_DATABASE=Quadro 2000D
+ ID_MODEL_FROM_DATABASE=GF106GL [Quadro 2000] (Quadro 2000D)
 
 pci:v000010DEd00000DDA*
  ID_MODEL_FROM_DATABASE=GF106GLM [Quadro 2000M]
@@ -25629,7 +26112,7 @@ pci:v000010DEd00000DE1*
  ID_MODEL_FROM_DATABASE=GF108 [GeForce GT 430]
 
 pci:v000010DEd00000DE1sv00003842sd00001430*
- ID_MODEL_FROM_DATABASE=GeForce GT 430
+ ID_MODEL_FROM_DATABASE=GF108 [GeForce GT 430] (GeForce GT 430)
 
 pci:v000010DEd00000DE2*
  ID_MODEL_FROM_DATABASE=GF108 [GeForce GT 420]
@@ -25653,49 +26136,49 @@ pci:v000010DEd00000DE9*
  ID_MODEL_FROM_DATABASE=GF108M [GeForce GT 630M]
 
 pci:v000010DEd00000DE9sv00001025sd00000692*
- ID_MODEL_FROM_DATABASE=GeForce GT 620M
+ ID_MODEL_FROM_DATABASE=GF108M [GeForce GT 630M] (GeForce GT 620M)
 
 pci:v000010DEd00000DE9sv00001025sd00000725*
- ID_MODEL_FROM_DATABASE=GeForce GT 620M
+ ID_MODEL_FROM_DATABASE=GF108M [GeForce GT 630M] (GeForce GT 620M)
 
 pci:v000010DEd00000DE9sv00001025sd00000728*
- ID_MODEL_FROM_DATABASE=GeForce GT 620M
+ ID_MODEL_FROM_DATABASE=GF108M [GeForce GT 630M] (GeForce GT 620M)
 
 pci:v000010DEd00000DE9sv00001025sd0000072B*
- ID_MODEL_FROM_DATABASE=GeForce GT 620M
+ ID_MODEL_FROM_DATABASE=GF108M [GeForce GT 630M] (GeForce GT 620M)
 
 pci:v000010DEd00000DE9sv00001025sd0000072E*
- ID_MODEL_FROM_DATABASE=GeForce GT 620M
+ ID_MODEL_FROM_DATABASE=GF108M [GeForce GT 630M] (GeForce GT 620M)
 
 pci:v000010DEd00000DE9sv00001025sd00000753*
- ID_MODEL_FROM_DATABASE=GeForce GT 620M
+ ID_MODEL_FROM_DATABASE=GF108M [GeForce GT 630M] (GeForce GT 620M)
 
 pci:v000010DEd00000DE9sv00001025sd00000754*
- ID_MODEL_FROM_DATABASE=GeForce GT 620M
+ ID_MODEL_FROM_DATABASE=GF108M [GeForce GT 630M] (GeForce GT 620M)
 
 pci:v000010DEd00000DE9sv000017AAsd00003977*
- ID_MODEL_FROM_DATABASE=GeForce GT 640M LE
+ ID_MODEL_FROM_DATABASE=GF108M [GeForce GT 630M] (GeForce GT 640M LE)
 
 pci:v000010DEd00000DE9sv00001B0Asd00002210*
- ID_MODEL_FROM_DATABASE=GeForce GT 635M
+ ID_MODEL_FROM_DATABASE=GF108M [GeForce GT 630M] (GeForce GT 635M)
 
 pci:v000010DEd00000DEA*
  ID_MODEL_FROM_DATABASE=GF108M [GeForce 610M]
 
 pci:v000010DEd00000DEAsv000017AAsd0000365A*
- ID_MODEL_FROM_DATABASE=GeForce 615
+ ID_MODEL_FROM_DATABASE=GF108M [GeForce 610M] (GeForce 615)
 
 pci:v000010DEd00000DEAsv000017AAsd0000365B*
- ID_MODEL_FROM_DATABASE=GeForce 615
+ ID_MODEL_FROM_DATABASE=GF108M [GeForce 610M] (GeForce 615)
 
 pci:v000010DEd00000DEAsv000017AAsd0000365E*
- ID_MODEL_FROM_DATABASE=GeForce 615
+ ID_MODEL_FROM_DATABASE=GF108M [GeForce 610M] (GeForce 615)
 
 pci:v000010DEd00000DEAsv000017AAsd00003660*
- ID_MODEL_FROM_DATABASE=GeForce 615
+ ID_MODEL_FROM_DATABASE=GF108M [GeForce 610M] (GeForce 615)
 
 pci:v000010DEd00000DEAsv000017AAsd0000366C*
- ID_MODEL_FROM_DATABASE=GeForce 615
+ ID_MODEL_FROM_DATABASE=GF108M [GeForce 610M] (GeForce 615)
 
 pci:v000010DEd00000DEB*
  ID_MODEL_FROM_DATABASE=GF108M [GeForce GT 555M]
@@ -25728,10 +26211,10 @@ pci:v000010DEd00000DF4*
  ID_MODEL_FROM_DATABASE=GF108M [GeForce GT 540M]
 
 pci:v000010DEd00000DF4sv0000152Dsd00000952*
- ID_MODEL_FROM_DATABASE=GeForce GT 630M
+ ID_MODEL_FROM_DATABASE=GF108M [GeForce GT 540M] (GeForce GT 630M)
 
 pci:v000010DEd00000DF4sv0000152Dsd00000953*
- ID_MODEL_FROM_DATABASE=GeForce GT 630M
+ ID_MODEL_FROM_DATABASE=GF108M [GeForce GT 540M] (GeForce GT 630M)
 
 pci:v000010DEd00000DF5*
  ID_MODEL_FROM_DATABASE=GF108M [GeForce GT 525M]
@@ -25758,7 +26241,7 @@ pci:v000010DEd00000E08*
  ID_MODEL_FROM_DATABASE=GF119 HDMI Audio Controller
 
 pci:v000010DEd00000E08sv000010B0sd0000104A*
- ID_MODEL_FROM_DATABASE=Gainward GeForce GT 610
+ ID_MODEL_FROM_DATABASE=GF119 HDMI Audio Controller (Gainward GeForce GT 610)
 
 pci:v000010DEd00000E09*
  ID_MODEL_FROM_DATABASE=GF110 High Definition Audio Controller
@@ -25778,14 +26261,17 @@ pci:v000010DEd00000E1A*
 pci:v000010DEd00000E1B*
  ID_MODEL_FROM_DATABASE=GK107 HDMI Audio Controller
 
+pci:v000010DEd00000E1Bsv0000103Csd0000197B*
+ ID_MODEL_FROM_DATABASE=GK107 HDMI Audio Controller (ZBook 15)
+
 pci:v000010DEd00000E1Bsv00001043sd00008428*
- ID_MODEL_FROM_DATABASE=GTX650-DC-1GD5
+ ID_MODEL_FROM_DATABASE=GK107 HDMI Audio Controller (GTX650-DC-1GD5)
 
 pci:v000010DEd00000E22*
  ID_MODEL_FROM_DATABASE=GF104 [GeForce GTX 460]
 
 pci:v000010DEd00000E22sv00001462sd00002322*
- ID_MODEL_FROM_DATABASE=N460GTX Cyclone 1GD5/OC
+ ID_MODEL_FROM_DATABASE=GF104 [GeForce GTX 460] (N460GTX Cyclone 1GD5/OC)
 
 pci:v000010DEd00000E23*
  ID_MODEL_FROM_DATABASE=GF104 [GeForce GTX 460 SE]
@@ -25811,6 +26297,9 @@ pci:v000010DEd00000F00*
 pci:v000010DEd00000F01*
  ID_MODEL_FROM_DATABASE=GF108 [GeForce GT 620]
 
+pci:v000010DEd00000F02*
+ ID_MODEL_FROM_DATABASE=GF108 [GeForce GT 730]
+
 pci:v000010DEd00000FC0*
  ID_MODEL_FROM_DATABASE=GK107 [GeForce GT 640 OEM]
 
@@ -25824,7 +26313,10 @@ pci:v000010DEd00000FC6*
  ID_MODEL_FROM_DATABASE=GK107 [GeForce GTX 650]
 
 pci:v000010DEd00000FC6sv00001043sd00008428*
- ID_MODEL_FROM_DATABASE=GTX650-DC-1GD5
+ ID_MODEL_FROM_DATABASE=GK107 [GeForce GTX 650] (GTX650-DC-1GD5)
+
+pci:v000010DEd00000FC8*
+ ID_MODEL_FROM_DATABASE=GK107 [GeForce GT 740]
 
 pci:v000010DEd00000FCD*
  ID_MODEL_FROM_DATABASE=GK107M [GeForce GT 755M]
@@ -25836,34 +26328,34 @@ pci:v000010DEd00000FD1*
  ID_MODEL_FROM_DATABASE=GK107M [GeForce GT 650M]
 
 pci:v000010DEd00000FD1sv00001043sd00001597*
- ID_MODEL_FROM_DATABASE=GeForce GT 650M
+ ID_MODEL_FROM_DATABASE=GK107M [GeForce GT 650M] (GeForce GT 650M)
 
 pci:v000010DEd00000FD1sv00001043sd000015A7*
- ID_MODEL_FROM_DATABASE=GeForce GT 650M
+ ID_MODEL_FROM_DATABASE=GK107M [GeForce GT 650M] (GeForce GT 650M)
 
 pci:v000010DEd00000FD1sv00001043sd00002103*
- ID_MODEL_FROM_DATABASE=N56VZ
+ ID_MODEL_FROM_DATABASE=GK107M [GeForce GT 650M] (N56VZ)
 
 pci:v000010DEd00000FD1sv00001043sd00002105*
- ID_MODEL_FROM_DATABASE=GeForce GT 650M
+ ID_MODEL_FROM_DATABASE=GK107M [GeForce GT 650M] (GeForce GT 650M)
 
 pci:v000010DEd00000FD1sv00001043sd00002141*
- ID_MODEL_FROM_DATABASE=GeForce GT 650M
+ ID_MODEL_FROM_DATABASE=GK107M [GeForce GT 650M] (GeForce GT 650M)
 
 pci:v000010DEd00000FD2*
  ID_MODEL_FROM_DATABASE=GK107M [GeForce GT 640M]
 
 pci:v000010DEd00000FD2sv00001028sd0000054F*
- ID_MODEL_FROM_DATABASE=GeForce GT 640M
+ ID_MODEL_FROM_DATABASE=GK107M [GeForce GT 640M] (GeForce GT 640M)
 
 pci:v000010DEd00000FD2sv00001028sd0000055F*
- ID_MODEL_FROM_DATABASE=GeForce GT 640M
+ ID_MODEL_FROM_DATABASE=GK107M [GeForce GT 640M] (GeForce GT 640M)
 
 pci:v000010DEd00000FD2sv00001028sd00000595*
- ID_MODEL_FROM_DATABASE=GeForce GT 640M LE
+ ID_MODEL_FROM_DATABASE=GK107M [GeForce GT 640M] (GeForce GT 640M LE)
 
 pci:v000010DEd00000FD2sv00001028sd000005B2*
- ID_MODEL_FROM_DATABASE=GeForce GT 640M LE
+ ID_MODEL_FROM_DATABASE=GK107M [GeForce GT 640M] (GeForce GT 640M LE)
 
 pci:v000010DEd00000FD3*
  ID_MODEL_FROM_DATABASE=GK107M [GeForce GT 640M LE]
@@ -25880,6 +26372,9 @@ pci:v000010DEd00000FD8*
 pci:v000010DEd00000FD9*
  ID_MODEL_FROM_DATABASE=GK107M [GeForce GT 645M]
 
+pci:v000010DEd00000FDB*
+ ID_MODEL_FROM_DATABASE=GK107M
+
 pci:v000010DEd00000FDF*
  ID_MODEL_FROM_DATABASE=GK107M [GeForce GT 740M]
 
@@ -25895,8 +26390,11 @@ pci:v000010DEd00000FE2*
 pci:v000010DEd00000FE3*
  ID_MODEL_FROM_DATABASE=GK107M [GeForce GT 745M]
 
+pci:v000010DEd00000FE3sv0000103Csd00002B16*
+ ID_MODEL_FROM_DATABASE=GK107M [GeForce GT 745M] (GeForce GT 745A)
+
 pci:v000010DEd00000FE3sv000017AAsd00003675*
- ID_MODEL_FROM_DATABASE=GeForce GT 745A
+ ID_MODEL_FROM_DATABASE=GK107M [GeForce GT 745M] (GeForce GT 745A)
 
 pci:v000010DEd00000FE4*
  ID_MODEL_FROM_DATABASE=GK107M [GeForce GT 750M]
@@ -25911,7 +26409,7 @@ pci:v000010DEd00000FE7*
  ID_MODEL_FROM_DATABASE=GK107GL [GRID K100 vGPU]
 
 pci:v000010DEd00000FE7sv000010DEsd0000101E*
- ID_MODEL_FROM_DATABASE=GRID K100
+ ID_MODEL_FROM_DATABASE=GK107GL [GRID K100 vGPU] (GRID K100)
 
 pci:v000010DEd00000FE9*
  ID_MODEL_FROM_DATABASE=GK107M [GeForce GT 750M Mac Edition]
@@ -25928,17 +26426,23 @@ pci:v000010DEd00000FF1*
 pci:v000010DEd00000FF2*
  ID_MODEL_FROM_DATABASE=GK107GL [GRID K1]
 
+pci:v000010DEd00000FF3*
+ ID_MODEL_FROM_DATABASE=GK107GL [Quadro K420]
+
 pci:v000010DEd00000FF5*
  ID_MODEL_FROM_DATABASE=GK107GL [GRID K1 Tesla USM]
 
 pci:v000010DEd00000FF6*
  ID_MODEL_FROM_DATABASE=GK107GLM [Quadro K1100M]
 
+pci:v000010DEd00000FF6sv0000103Csd0000197B*
+ ID_MODEL_FROM_DATABASE=GK107GLM [Quadro K1100M] (ZBook 15)
+
 pci:v000010DEd00000FF7*
  ID_MODEL_FROM_DATABASE=GK107GL [GRID K140Q vGPU]
 
 pci:v000010DEd00000FF7sv000010DEsd00001037*
- ID_MODEL_FROM_DATABASE=GRID K140Q
+ ID_MODEL_FROM_DATABASE=GK107GL [GRID K140Q vGPU] (GRID K140Q)
 
 pci:v000010DEd00000FF8*
  ID_MODEL_FROM_DATABASE=GK107GLM [Quadro K500M]
@@ -25964,6 +26468,9 @@ pci:v000010DEd00000FFE*
 pci:v000010DEd00000FFF*
  ID_MODEL_FROM_DATABASE=GK107GL [Quadro 410]
 
+pci:v000010DEd00001001*
+ ID_MODEL_FROM_DATABASE=GK110B [GeForce GTX TITAN Z]
+
 pci:v000010DEd00001003*
  ID_MODEL_FROM_DATABASE=GK110 [GeForce GTX Titan LE]
 
@@ -25971,41 +26478,50 @@ pci:v000010DEd00001004*
  ID_MODEL_FROM_DATABASE=GK110 [GeForce GTX 780]
 
 pci:v000010DEd00001004sv00003842sd00000784*
- ID_MODEL_FROM_DATABASE=GK110B [GeForce GTX 780 SC w/ ACX Cooler]
+ ID_MODEL_FROM_DATABASE=GK110 [GeForce GTX 780] (GK110B [GeForce GTX 780 SC w/ ACX Cooler])
 
 pci:v000010DEd00001004sv00003842sd00001784*
- ID_MODEL_FROM_DATABASE=GK110B [GeForce GTX 780 Dual FTW w/ ACX Cooler]
+ ID_MODEL_FROM_DATABASE=GK110 [GeForce GTX 780] (GK110B [GeForce GTX 780 Dual FTW w/ ACX Cooler])
 
 pci:v000010DEd00001004sv00003842sd00001788*
- ID_MODEL_FROM_DATABASE=GK110B [GeForce GTX 780 Dual Classified w/ ACX Cooler]
+ ID_MODEL_FROM_DATABASE=GK110 [GeForce GTX 780] (GK110B [GeForce GTX 780 Dual Classified w/ ACX Cooler])
 
 pci:v000010DEd00001005*
  ID_MODEL_FROM_DATABASE=GK110 [GeForce GTX Titan]
 
 pci:v000010DEd00001005sv00001043sd00008451*
- ID_MODEL_FROM_DATABASE=GTXTITAN-6GD5
+ ID_MODEL_FROM_DATABASE=GK110 [GeForce GTX Titan] (GTXTITAN-6GD5)
 
 pci:v000010DEd00001005sv000010DEsd00001035*
- ID_MODEL_FROM_DATABASE=GeForce GTX Titan
+ ID_MODEL_FROM_DATABASE=GK110 [GeForce GTX Titan] (GeForce GTX Titan)
 
 pci:v000010DEd00001005sv00003842sd00002790*
- ID_MODEL_FROM_DATABASE=GeForce GTX Titan
+ ID_MODEL_FROM_DATABASE=GK110 [GeForce GTX Titan] (GeForce GTX Titan)
 
 pci:v000010DEd00001005sv00003842sd00002791*
- ID_MODEL_FROM_DATABASE=GeForce GTX Titan SC
+ ID_MODEL_FROM_DATABASE=GK110 [GeForce GTX Titan] (GeForce GTX Titan SC)
 
 pci:v000010DEd00001005sv00003842sd00002793*
- ID_MODEL_FROM_DATABASE=GeForce GTX Titan SC Signature
+ ID_MODEL_FROM_DATABASE=GK110 [GeForce GTX Titan] (GeForce GTX Titan SC Signature)
 
 pci:v000010DEd00001005sv00003842sd00002794*
- ID_MODEL_FROM_DATABASE=GeForce GTX Titan SC Hydro Copper
+ ID_MODEL_FROM_DATABASE=GK110 [GeForce GTX Titan] (GeForce GTX Titan SC Hydro Copper)
 
 pci:v000010DEd00001005sv00003842sd00002795*
- ID_MODEL_FROM_DATABASE=GeForce GTX Titan SC Hydro Copper Signature
+ ID_MODEL_FROM_DATABASE=GK110 [GeForce GTX Titan] (GeForce GTX Titan SC Hydro Copper Signature)
+
+pci:v000010DEd00001007*
+ ID_MODEL_FROM_DATABASE=GK110 [GeForce GTX 780 Rev. 2]
+
+pci:v000010DEd00001008*
+ ID_MODEL_FROM_DATABASE=GK110 [GeForce GTX 780 Ti Rev. 2]
 
 pci:v000010DEd0000100A*
  ID_MODEL_FROM_DATABASE=GK110B [GeForce GTX 780 Ti]
 
+pci:v000010DEd0000100C*
+ ID_MODEL_FROM_DATABASE=GK110B [GeForce GTX Titan Black]
+
 pci:v000010DEd0000101F*
  ID_MODEL_FROM_DATABASE=GK110GL [Tesla K20]
 
@@ -26039,6 +26555,9 @@ pci:v000010DEd00001029*
 pci:v000010DEd0000103A*
  ID_MODEL_FROM_DATABASE=GK110GL [Quadro K6000]
 
+pci:v000010DEd0000103C*
+ ID_MODEL_FROM_DATABASE=GK110GL [Quadro K5200]
+
 pci:v000010DEd00001040*
  ID_MODEL_FROM_DATABASE=GF119 [GeForce GT 520]
 
@@ -26055,11 +26574,14 @@ pci:v000010DEd0000104A*
  ID_MODEL_FROM_DATABASE=GF119 [GeForce GT 610]
 
 pci:v000010DEd0000104Asv000010B0sd0000104A*
- ID_MODEL_FROM_DATABASE=Gainward GeForce GT 610
+ ID_MODEL_FROM_DATABASE=GF119 [GeForce GT 610] (Gainward GeForce GT 610)
 
 pci:v000010DEd0000104B*
  ID_MODEL_FROM_DATABASE=GF119 [GeForce GT 625 OEM]
 
+pci:v000010DEd0000104C*
+ ID_MODEL_FROM_DATABASE=GF119 [GeForce GT 705]
+
 pci:v000010DEd00001050*
  ID_MODEL_FROM_DATABASE=GF119M [GeForce GT 520M]
 
@@ -26085,19 +26607,37 @@ pci:v000010DEd00001058*
  ID_MODEL_FROM_DATABASE=GF119M [GeForce 610M]
 
 pci:v000010DEd00001058sv0000103Csd00002AED*
- ID_MODEL_FROM_DATABASE=GeForce 610
+ ID_MODEL_FROM_DATABASE=GF119M [GeForce 610M] (GeForce 610)
 
 pci:v000010DEd00001058sv0000103Csd00002AF1*
- ID_MODEL_FROM_DATABASE=GeForce 610
+ ID_MODEL_FROM_DATABASE=GF119M [GeForce 610M] (GeForce 610)
 
 pci:v000010DEd00001058sv00001043sd000010AC*
- ID_MODEL_FROM_DATABASE=GeForce GT 610M
+ ID_MODEL_FROM_DATABASE=GF119M [GeForce 610M] (GeForce GT 610M)
 
 pci:v000010DEd00001058sv00001043sd000010BC*
- ID_MODEL_FROM_DATABASE=GeForce GT 610M
+ ID_MODEL_FROM_DATABASE=GF119M [GeForce 610M] (GeForce GT 610M)
 
 pci:v000010DEd00001058sv00001043sd00001652*
- ID_MODEL_FROM_DATABASE=GeForce GT 610M
+ ID_MODEL_FROM_DATABASE=GF119M [GeForce 610M] (GeForce GT 610M)
+
+pci:v000010DEd00001058sv000017AAsd0000367A*
+ ID_MODEL_FROM_DATABASE=GF119M [GeForce 610M] (GeForce 610M)
+
+pci:v000010DEd00001058sv000017AAsd00003682*
+ ID_MODEL_FROM_DATABASE=GF119M [GeForce 610M] (GeForce 800A)
+
+pci:v000010DEd00001058sv000017AAsd00003687*
+ ID_MODEL_FROM_DATABASE=GF119M [GeForce 610M] (GeForce 800A)
+
+pci:v000010DEd00001058sv000017AAsd00003692*
+ ID_MODEL_FROM_DATABASE=GF119M [GeForce 610M] (GeForce 705A)
+
+pci:v000010DEd00001058sv000017AAsd00003695*
+ ID_MODEL_FROM_DATABASE=GF119M [GeForce 610M] (GeForce 800A)
+
+pci:v000010DEd00001058sv000017AAsd0000A117*
+ ID_MODEL_FROM_DATABASE=GF119M [GeForce 610M] (GeForce 610M)
 
 pci:v000010DEd00001059*
  ID_MODEL_FROM_DATABASE=GF119M [GeForce 610M]
@@ -26106,16 +26646,25 @@ pci:v000010DEd0000105A*
  ID_MODEL_FROM_DATABASE=GF119M [GeForce 610M]
 
 pci:v000010DEd0000105Asv00001043sd00002111*
- ID_MODEL_FROM_DATABASE=GeForce GT 610M
+ ID_MODEL_FROM_DATABASE=GF119M [GeForce 610M] (GeForce GT 610M)
 
 pci:v000010DEd0000105Asv00001043sd00002112*
- ID_MODEL_FROM_DATABASE=GeForce GT 610M
+ ID_MODEL_FROM_DATABASE=GF119M [GeForce 610M] (GeForce GT 610M)
 
 pci:v000010DEd0000105B*
  ID_MODEL_FROM_DATABASE=GF119M [GeForce 705M]
 
 pci:v000010DEd0000105Bsv0000103Csd00002AFB*
- ID_MODEL_FROM_DATABASE=GeForce 705A
+ ID_MODEL_FROM_DATABASE=GF119M [GeForce 705M] (GeForce 705A)
+
+pci:v000010DEd0000105Bsv000017AAsd0000309D*
+ ID_MODEL_FROM_DATABASE=GF119M [GeForce 705M] (GeForce 705A)
+
+pci:v000010DEd0000105Bsv000017AAsd000030B1*
+ ID_MODEL_FROM_DATABASE=GF119M [GeForce 705M] (GeForce 800A)
+
+pci:v000010DEd0000105Bsv000017AAsd000036A1*
+ ID_MODEL_FROM_DATABASE=GF119M [GeForce 705M] (GeForce 800A)
 
 pci:v000010DEd0000107C*
  ID_MODEL_FROM_DATABASE=GF119 [NVS 315]
@@ -26130,7 +26679,7 @@ pci:v000010DEd00001081*
  ID_MODEL_FROM_DATABASE=GF110 [GeForce GTX 570]
 
 pci:v000010DEd00001081sv000010DEsd0000087E*
- ID_MODEL_FROM_DATABASE=Leadtek WinFast GTX 570
+ ID_MODEL_FROM_DATABASE=GF110 [GeForce GTX 570] (Leadtek WinFast GTX 570)
 
 pci:v000010DEd00001082*
  ID_MODEL_FROM_DATABASE=GF110 [GeForce GTX 560 Ti OEM]
@@ -26160,31 +26709,31 @@ pci:v000010DEd00001091*
  ID_MODEL_FROM_DATABASE=GF110GL [Tesla M2090]
 
 pci:v000010DEd00001091sv000010DEsd0000088E*
- ID_MODEL_FROM_DATABASE=Tesla X2090
+ ID_MODEL_FROM_DATABASE=GF110GL [Tesla M2090] (Tesla X2090)
 
 pci:v000010DEd00001091sv000010DEsd00000891*
- ID_MODEL_FROM_DATABASE=Tesla X2090
+ ID_MODEL_FROM_DATABASE=GF110GL [Tesla M2090] (Tesla X2090)
 
 pci:v000010DEd00001091sv000010DEsd00000974*
- ID_MODEL_FROM_DATABASE=Tesla X2090
+ ID_MODEL_FROM_DATABASE=GF110GL [Tesla M2090] (Tesla X2090)
 
 pci:v000010DEd00001091sv000010DEsd0000098D*
- ID_MODEL_FROM_DATABASE=Tesla X2090
+ ID_MODEL_FROM_DATABASE=GF110GL [Tesla M2090] (Tesla X2090)
 
 pci:v000010DEd00001094*
  ID_MODEL_FROM_DATABASE=GF110GL [Tesla M2075]
 
 pci:v000010DEd00001094sv000010DEsd00000888*
- ID_MODEL_FROM_DATABASE=Tesla M2075
+ ID_MODEL_FROM_DATABASE=GF110GL [Tesla M2075] (Tesla M2075)
 
 pci:v000010DEd00001096*
  ID_MODEL_FROM_DATABASE=GF110GL [Tesla C2050 / C2075]
 
 pci:v000010DEd00001096sv000010DEsd00000910*
- ID_MODEL_FROM_DATABASE=Tesla C2075
+ ID_MODEL_FROM_DATABASE=GF110GL [Tesla C2050 / C2075] (Tesla C2075)
 
 pci:v000010DEd00001096sv000010DEsd00000911*
- ID_MODEL_FROM_DATABASE=Tesla C2050
+ ID_MODEL_FROM_DATABASE=GF110GL [Tesla C2050 / C2075] (Tesla C2050)
 
 pci:v000010DEd0000109A*
  ID_MODEL_FROM_DATABASE=GF100GLM [Quadro 5010M]
@@ -26193,7 +26742,7 @@ pci:v000010DEd0000109B*
  ID_MODEL_FROM_DATABASE=GF100GL [Quadro 7000]
 
 pci:v000010DEd0000109Bsv000010DEsd00000918*
- ID_MODEL_FROM_DATABASE=Quadro 7000
+ ID_MODEL_FROM_DATABASE=GF100GL [Quadro 7000] (Quadro 7000)
 
 pci:v000010DEd000010C0*
  ID_MODEL_FROM_DATABASE=GT218 [GeForce 9300 GS Rev. 2]
@@ -26211,547 +26760,748 @@ pci:v000010DEd00001140*
  ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M]
 
 pci:v000010DEd00001140sv00001025sd00000600*
- ID_MODEL_FROM_DATABASE=GeForce GT 620M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 620M)
 
 pci:v000010DEd00001140sv00001025sd00000606*
- ID_MODEL_FROM_DATABASE=GeForce GT 620M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 620M)
 
 pci:v000010DEd00001140sv00001025sd0000064A*
- ID_MODEL_FROM_DATABASE=GeForce GT 620M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 620M)
 
 pci:v000010DEd00001140sv00001025sd0000064C*
- ID_MODEL_FROM_DATABASE=GeForce GT 620M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 620M)
 
 pci:v000010DEd00001140sv00001025sd0000067A*
- ID_MODEL_FROM_DATABASE=GeForce GT 620M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 620M)
 
 pci:v000010DEd00001140sv00001025sd00000680*
- ID_MODEL_FROM_DATABASE=GeForce GT 620M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 620M)
 
 pci:v000010DEd00001140sv00001025sd00000686*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv00001025sd00000689*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv00001025sd0000068B*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv00001025sd0000068D*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv00001025sd0000068E*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv00001025sd00000691*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv00001025sd00000692*
- ID_MODEL_FROM_DATABASE=GeForce GT 620M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 620M)
 
 pci:v000010DEd00001140sv00001025sd00000694*
- ID_MODEL_FROM_DATABASE=GeForce GT 620M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 620M)
 
 pci:v000010DEd00001140sv00001025sd00000702*
- ID_MODEL_FROM_DATABASE=GeForce GT 620M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 620M)
 
 pci:v000010DEd00001140sv00001025sd00000719*
- ID_MODEL_FROM_DATABASE=GeForce GT 620M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 620M)
 
 pci:v000010DEd00001140sv00001025sd00000725*
- ID_MODEL_FROM_DATABASE=GeForce GT 620M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 620M)
 
 pci:v000010DEd00001140sv00001025sd00000728*
- ID_MODEL_FROM_DATABASE=GeForce GT 620M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 620M)
 
 pci:v000010DEd00001140sv00001025sd0000072B*
- ID_MODEL_FROM_DATABASE=GeForce GT 620M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 620M)
 
 pci:v000010DEd00001140sv00001025sd0000072E*
- ID_MODEL_FROM_DATABASE=GeForce GT 620M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 620M)
 
 pci:v000010DEd00001140sv00001025sd00000732*
- ID_MODEL_FROM_DATABASE=GeForce GT 620M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 620M)
 
 pci:v000010DEd00001140sv00001025sd00000763*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
 
 pci:v000010DEd00001140sv00001025sd00000773*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv00001025sd00000774*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv00001025sd00000776*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
 
 pci:v000010DEd00001140sv00001025sd0000077A*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv00001025sd0000077B*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv00001025sd0000077C*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv00001025sd0000077D*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv00001025sd0000077E*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv00001025sd0000077F*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv00001025sd00000781*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
 
 pci:v000010DEd00001140sv00001025sd00000798*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
 
 pci:v000010DEd00001140sv00001025sd00000799*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
 
 pci:v000010DEd00001140sv00001025sd0000079B*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
 
 pci:v000010DEd00001140sv00001025sd0000079C*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
 
 pci:v000010DEd00001140sv00001025sd00000807*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
 
 pci:v000010DEd00001140sv00001025sd00000821*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
 
 pci:v000010DEd00001140sv00001025sd00000823*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
 
 pci:v000010DEd00001140sv00001025sd00000830*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
 
 pci:v000010DEd00001140sv00001025sd00000837*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
+
+pci:v000010DEd00001140sv00001025sd0000083E*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
 
 pci:v000010DEd00001140sv00001025sd00000841*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
+
+pci:v000010DEd00001140sv00001025sd00000854*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
+
+pci:v000010DEd00001140sv00001025sd00000855*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
+
+pci:v000010DEd00001140sv00001025sd00000856*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
+
+pci:v000010DEd00001140sv00001025sd00000857*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
+
+pci:v000010DEd00001140sv00001025sd00000858*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
+
+pci:v000010DEd00001140sv00001025sd00000868*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
+
+pci:v000010DEd00001140sv00001025sd00000869*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 810M)
+
+pci:v000010DEd00001140sv00001025sd00000873*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
+
+pci:v000010DEd00001140sv00001025sd00000878*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
+
+pci:v000010DEd00001140sv00001025sd0000087B*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
+
+pci:v000010DEd00001140sv00001025sd0000087C*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 810M)
+
+pci:v000010DEd00001140sv00001025sd00000881*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
+
+pci:v000010DEd00001140sv00001025sd0000088A*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
+
+pci:v000010DEd00001140sv00001025sd0000090F*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
+
+pci:v000010DEd00001140sv00001025sd00000921*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
 
 pci:v000010DEd00001140sv00001028sd0000054D*
- ID_MODEL_FROM_DATABASE=GeForce GT 630M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 630M)
 
 pci:v000010DEd00001140sv00001028sd0000054E*
- ID_MODEL_FROM_DATABASE=GeForce GT 630M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 630M)
 
 pci:v000010DEd00001140sv00001028sd00000554*
- ID_MODEL_FROM_DATABASE=GeForce GT 620M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 620M)
 
 pci:v000010DEd00001140sv00001028sd00000557*
- ID_MODEL_FROM_DATABASE=GeForce GT 620M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 620M)
 
 pci:v000010DEd00001140sv00001028sd00000562*
- ID_MODEL_FROM_DATABASE=GeForce GT 625M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 625M)
 
 pci:v000010DEd00001140sv00001028sd00000565*
- ID_MODEL_FROM_DATABASE=GeForce GT 630M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 630M)
 
 pci:v000010DEd00001140sv00001028sd00000568*
- ID_MODEL_FROM_DATABASE=GeForce GT 630M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 630M)
 
 pci:v000010DEd00001140sv00001028sd00000590*
- ID_MODEL_FROM_DATABASE=GeForce GT 630M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 630M)
 
 pci:v000010DEd00001140sv00001028sd00000592*
- ID_MODEL_FROM_DATABASE=GeForce GT 625M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 625M)
 
 pci:v000010DEd00001140sv00001028sd00000594*
- ID_MODEL_FROM_DATABASE=GeForce GT 625M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 625M)
 
 pci:v000010DEd00001140sv00001028sd00000595*
- ID_MODEL_FROM_DATABASE=GeForce GT 625M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 625M)
 
 pci:v000010DEd00001140sv00001028sd000005A2*
- ID_MODEL_FROM_DATABASE=GeForce GT 625M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 625M)
 
 pci:v000010DEd00001140sv00001028sd000005B1*
- ID_MODEL_FROM_DATABASE=GeForce GT 625M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 625M)
 
 pci:v000010DEd00001140sv00001028sd000005B3*
- ID_MODEL_FROM_DATABASE=GeForce GT 625M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 625M)
 
 pci:v000010DEd00001140sv00001028sd000005DA*
- ID_MODEL_FROM_DATABASE=GeForce GT 630M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 630M)
 
 pci:v000010DEd00001140sv00001028sd000005DE*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
 
 pci:v000010DEd00001140sv00001028sd000005E0*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
 
 pci:v000010DEd00001140sv00001028sd000005E8*
- ID_MODEL_FROM_DATABASE=GeForce GT 630M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 630M)
 
 pci:v000010DEd00001140sv00001028sd000005F4*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
+
+pci:v000010DEd00001140sv00001028sd0000064E*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
+
+pci:v000010DEd00001140sv00001028sd00000652*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
+
+pci:v000010DEd00001140sv00001028sd00000662*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
+
+pci:v000010DEd00001140sv00001028sd0000068D*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
 
 pci:v000010DEd00001140sv0000103Csd000018EF*
- ID_MODEL_FROM_DATABASE=GeForce GT 630M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 630M)
 
 pci:v000010DEd00001140sv0000103Csd000018F9*
- ID_MODEL_FROM_DATABASE=GeForce GT 630M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 630M)
 
 pci:v000010DEd00001140sv0000103Csd000018FB*
- ID_MODEL_FROM_DATABASE=GeForce GT 630M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 630M)
 
 pci:v000010DEd00001140sv0000103Csd000018FD*
- ID_MODEL_FROM_DATABASE=GeForce GT 630M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 630M)
 
 pci:v000010DEd00001140sv0000103Csd000018FF*
- ID_MODEL_FROM_DATABASE=GeForce GT 630M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 630M)
 
 pci:v000010DEd00001140sv0000103Csd00002AEF*
- ID_MODEL_FROM_DATABASE=GeForce GT 720A
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720A)
 
 pci:v000010DEd00001140sv0000103Csd00002AF9*
- ID_MODEL_FROM_DATABASE=GeForce 710A
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710A)
 
 pci:v000010DEd00001140sv00001043sd000010DD*
- ID_MODEL_FROM_DATABASE=NVS 5200M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (NVS 5200M)
 
 pci:v000010DEd00001140sv00001043sd000010ED*
- ID_MODEL_FROM_DATABASE=NVS 5200M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (NVS 5200M)
 
 pci:v000010DEd00001140sv00001043sd000011FD*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
 
 pci:v000010DEd00001140sv00001043sd0000124D*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
 
 pci:v000010DEd00001140sv00001043sd0000126D*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
 
 pci:v000010DEd00001140sv00001043sd0000131D*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
 
 pci:v000010DEd00001140sv00001043sd000013FD*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
 
 pci:v000010DEd00001140sv00001043sd000014C7*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
 
 pci:v000010DEd00001140sv00001043sd00001507*
- ID_MODEL_FROM_DATABASE=GeForce GT 620M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 620M)
+
+pci:v000010DEd00001140sv00001043sd000015AD*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
+
+pci:v000010DEd00001140sv00001043sd000015ED*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
+
+pci:v000010DEd00001140sv00001043sd0000160D*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
+
+pci:v000010DEd00001140sv00001043sd0000163D*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
+
+pci:v000010DEd00001140sv00001043sd0000166D*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
+
+pci:v000010DEd00001140sv00001043sd000016CD*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
+
+pci:v000010DEd00001140sv00001043sd000016DD*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
+
+pci:v000010DEd00001140sv00001043sd0000170D*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
+
+pci:v000010DEd00001140sv00001043sd0000176D*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
+
+pci:v000010DEd00001140sv00001043sd0000178D*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
+
+pci:v000010DEd00001140sv00001043sd0000179D*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
+
+pci:v000010DEd00001140sv00001043sd000017DD*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
 
 pci:v000010DEd00001140sv00001043sd00002132*
- ID_MODEL_FROM_DATABASE=GeForce GT 620M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 620M)
 
 pci:v000010DEd00001140sv00001043sd00002136*
- ID_MODEL_FROM_DATABASE=NVS 5200M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (NVS 5200M)
 
 pci:v000010DEd00001140sv00001043sd000021BA*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
 
 pci:v000010DEd00001140sv00001043sd000021FA*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
 
 pci:v000010DEd00001140sv00001043sd0000220A*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
 
 pci:v000010DEd00001140sv00001043sd0000221A*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
 
 pci:v000010DEd00001140sv00001043sd0000223A*
- ID_MODEL_FROM_DATABASE=GeForce GT 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 710M)
 
 pci:v000010DEd00001140sv00001043sd0000224A*
- ID_MODEL_FROM_DATABASE=GeForce GT 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 710M)
+
+pci:v000010DEd00001140sv00001043sd0000227A*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
+
+pci:v000010DEd00001140sv00001043sd0000228A*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
 
 pci:v000010DEd00001140sv00001043sd00008595*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
 
 pci:v000010DEd00001140sv00001072sd0000152D*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
 
 pci:v000010DEd00001140sv000010CFsd000017F5*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
 
 pci:v000010DEd00001140sv00001179sd0000FA01*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv00001179sd0000FA02*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv00001179sd0000FA03*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv00001179sd0000FA05*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv00001179sd0000FA11*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv00001179sd0000FA13*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv00001179sd0000FA18*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv00001179sd0000FA19*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv00001179sd0000FA21*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv00001179sd0000FA23*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv00001179sd0000FA2A*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv00001179sd0000FA32*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv00001179sd0000FA33*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv00001179sd0000FA36*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv00001179sd0000FA38*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv00001179sd0000FA42*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv00001179sd0000FA43*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv00001179sd0000FA45*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv00001179sd0000FA47*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv00001179sd0000FA49*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv00001179sd0000FA58*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv00001179sd0000FA59*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv00001179sd0000FA88*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv00001179sd0000FA89*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv0000144Dsd0000B092*
- ID_MODEL_FROM_DATABASE=GeForce GT 620M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 620M)
 
 pci:v000010DEd00001140sv0000144Dsd0000C0D5*
- ID_MODEL_FROM_DATABASE=GeForce GT 630M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 630M)
 
 pci:v000010DEd00001140sv0000144Dsd0000C0D7*
- ID_MODEL_FROM_DATABASE=GeForce GT 620M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 620M)
 
 pci:v000010DEd00001140sv0000144Dsd0000C0E2*
- ID_MODEL_FROM_DATABASE=NVS 5200M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (NVS 5200M)
 
 pci:v000010DEd00001140sv0000144Dsd0000C0E3*
- ID_MODEL_FROM_DATABASE=NVS 5200M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (NVS 5200M)
 
 pci:v000010DEd00001140sv0000144Dsd0000C0E4*
- ID_MODEL_FROM_DATABASE=NVS 5200M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (NVS 5200M)
 
 pci:v000010DEd00001140sv0000144Dsd0000C652*
- ID_MODEL_FROM_DATABASE=GeForce GT 620M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 620M)
 
 pci:v000010DEd00001140sv0000144Dsd0000C709*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv0000144Dsd0000C711*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv0000144Dsd0000C736*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv00001462sd000010B8*
- ID_MODEL_FROM_DATABASE=GeForce GT 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 710M)
 
 pci:v000010DEd00001140sv00001462sd000010E9*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
+
+pci:v000010DEd00001140sv00001462sd00001116*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
 
 pci:v000010DEd00001140sv00001462sd0000AA33*
- ID_MODEL_FROM_DATABASE=GeForce 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 720M)
 
 pci:v000010DEd00001140sv00001462sd0000AAA2*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
 
 pci:v000010DEd00001140sv00001462sd0000AAA3*
- ID_MODEL_FROM_DATABASE=GeForce 820M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
 
 pci:v000010DEd00001140sv00001462sd0000AE71*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
 
 pci:v000010DEd00001140sv0000152Dsd00000926*
- ID_MODEL_FROM_DATABASE=GeForce 620M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 620M)
 
 pci:v000010DEd00001140sv0000152Dsd00000982*
- ID_MODEL_FROM_DATABASE=GeForce GT 630M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 630M)
 
 pci:v000010DEd00001140sv0000152Dsd00000983*
- ID_MODEL_FROM_DATABASE=GeForce GT 630M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 630M)
+
+pci:v000010DEd00001140sv0000152Dsd00001005*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 820M)
 
 pci:v000010DEd00001140sv0000152Dsd00001012*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
+
+pci:v000010DEd00001140sv0000152Dsd00001019*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
 
 pci:v000010DEd00001140sv0000152Dsd00001030*
- ID_MODEL_FROM_DATABASE=GeForce GT 630M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 630M)
 
 pci:v000010DEd00001140sv0000152Dsd00001055*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv0000152Dsd00001067*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
 
 pci:v000010DEd00001140sv0000152Dsd00001072*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
+
+pci:v000010DEd00001140sv0000152Dsd00001086*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
 
 pci:v000010DEd00001140sv000017AAsd00002200*
- ID_MODEL_FROM_DATABASE=NVS 5200M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (NVS 5200M)
 
 pci:v000010DEd00001140sv000017AAsd00002213*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
 
 pci:v000010DEd00001140sv000017AAsd00002220*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
+
+pci:v000010DEd00001140sv000017AAsd0000309C*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720A)
+
+pci:v000010DEd00001140sv000017AAsd000030B4*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820A)
 
 pci:v000010DEd00001140sv000017AAsd00003656*
- ID_MODEL_FROM_DATABASE=GeForce GT 620M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 620M)
+
+pci:v000010DEd00001140sv000017AAsd0000365A*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 705M)
+
+pci:v000010DEd00001140sv000017AAsd0000365E*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 800M)
+
+pci:v000010DEd00001140sv000017AAsd0000366C*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 800M)
+
+pci:v000010DEd00001140sv000017AAsd00003685*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 800M)
+
+pci:v000010DEd00001140sv000017AAsd00003686*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 800M)
+
+pci:v000010DEd00001140sv000017AAsd00003687*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 705A)
+
+pci:v000010DEd00001140sv000017AAsd00003696*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820A)
+
+pci:v000010DEd00001140sv000017AAsd0000369B*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820A)
+
+pci:v000010DEd00001140sv000017AAsd0000369C*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820A)
+
+pci:v000010DEd00001140sv000017AAsd0000369D*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820A)
+
+pci:v000010DEd00001140sv000017AAsd0000369E*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820A)
 
 pci:v000010DEd00001140sv000017AAsd00003800*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
 
 pci:v000010DEd00001140sv000017AAsd00003801*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
 
 pci:v000010DEd00001140sv000017AAsd00003802*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
 
 pci:v000010DEd00001140sv000017AAsd00003803*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
 
 pci:v000010DEd00001140sv000017AAsd00003804*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
+
+pci:v000010DEd00001140sv000017AAsd00003806*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
+
+pci:v000010DEd00001140sv000017AAsd00003808*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
+
+pci:v000010DEd00001140sv000017AAsd0000380D*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
+
+pci:v000010DEd00001140sv000017AAsd0000380E*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
+
+pci:v000010DEd00001140sv000017AAsd0000380F*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
+
+pci:v000010DEd00001140sv000017AAsd00003811*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
+
+pci:v000010DEd00001140sv000017AAsd00003812*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
+
+pci:v000010DEd00001140sv000017AAsd00003813*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
+
+pci:v000010DEd00001140sv000017AAsd00003816*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
+
+pci:v000010DEd00001140sv000017AAsd00003818*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
 
 pci:v000010DEd00001140sv000017AAsd00003901*
- ID_MODEL_FROM_DATABASE=GeForce 610M / GT 620M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 610M / GT 620M)
 
 pci:v000010DEd00001140sv000017AAsd00003902*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv000017AAsd00003903*
- ID_MODEL_FROM_DATABASE=GeForce 610M/710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 610M/710M)
 
 pci:v000010DEd00001140sv000017AAsd00003904*
- ID_MODEL_FROM_DATABASE=GeForce GT 620M/625M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 620M/625M)
 
 pci:v000010DEd00001140sv000017AAsd00003905*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
 
 pci:v000010DEd00001140sv000017AAsd00003910*
- ID_MODEL_FROM_DATABASE=GeForce 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 720M)
 
 pci:v000010DEd00001140sv000017AAsd00003912*
- ID_MODEL_FROM_DATABASE=GeForce 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 720M)
 
 pci:v000010DEd00001140sv000017AAsd00003977*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
 
 pci:v000010DEd00001140sv000017AAsd00003983*
- ID_MODEL_FROM_DATABASE=GeForce 610M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 610M)
 
 pci:v000010DEd00001140sv000017AAsd00005001*
- ID_MODEL_FROM_DATABASE=GeForce 610M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 610M)
 
 pci:v000010DEd00001140sv000017AAsd00005003*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
 
 pci:v000010DEd00001140sv000017AAsd00005005*
- ID_MODEL_FROM_DATABASE=GeForce 705M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 705M)
 
 pci:v000010DEd00001140sv000017AAsd0000500D*
- ID_MODEL_FROM_DATABASE=GeForce GT 620M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 620M)
 
 pci:v000010DEd00001140sv000017AAsd00005014*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv000017AAsd00005017*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv000017AAsd00005019*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv000017AAsd0000501A*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv000017AAsd0000501F*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
 
 pci:v000010DEd00001140sv000017AAsd00005025*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv000017AAsd00005027*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv000017AAsd0000502A*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv000017AAsd0000502B*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
 
 pci:v000010DEd00001140sv000017AAsd0000502D*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv000017AAsd0000502E*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
 
 pci:v000010DEd00001140sv000017AAsd0000502F*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
+
+pci:v000010DEd00001140sv000017AAsd00005030*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 705M)
+
+pci:v000010DEd00001140sv000017AAsd00005031*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 705M)
+
+pci:v000010DEd00001140sv000017AAsd00005032*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
+
+pci:v000010DEd00001140sv000017AAsd00005033*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
 
 pci:v000010DEd00001140sv000017AAsd0000503E*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv000017AAsd0000503F*
- ID_MODEL_FROM_DATABASE=GeForce 820M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
+
+pci:v000010DEd00001140sv000017AAsd00005040*
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 820M)
 
 pci:v000010DEd00001140sv00001854sd00000177*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv00001854sd00000180*
- ID_MODEL_FROM_DATABASE=GeForce 710M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce 710M)
 
 pci:v000010DEd00001140sv00001854sd00000190*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
 
 pci:v000010DEd00001140sv00001854sd00000192*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
 
 pci:v000010DEd00001140sv00001B0Asd000020DD*
- ID_MODEL_FROM_DATABASE=GeForce GT 620M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 620M)
 
 pci:v000010DEd00001140sv00001B0Asd000020DF*
- ID_MODEL_FROM_DATABASE=GeForce GT 620M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 620M)
 
 pci:v000010DEd00001140sv00001B0Asd00002202*
- ID_MODEL_FROM_DATABASE=GeForce GT 720M
+ ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/820M / GT 620M/625M/630M/720M] (GeForce GT 720M)
 
 pci:v000010DEd00001180*
  ID_MODEL_FROM_DATABASE=GK104 [GeForce GTX 680]
 
+pci:v000010DEd00001180sv00001043sd000083F1*
+ ID_MODEL_FROM_DATABASE=GK104 [GeForce GTX 680] (GTX680-DC2-2GD5)
+
 pci:v000010DEd00001180sv00003842sd00003682*
- ID_MODEL_FROM_DATABASE=GeForce GTX 680 Mac Edition
+ ID_MODEL_FROM_DATABASE=GK104 [GeForce GTX 680] (GeForce GTX 680 Mac Edition)
 
 pci:v000010DEd00001182*
  ID_MODEL_FROM_DATABASE=GK104 [GeForce GTX 760 Ti]
@@ -26766,7 +27516,7 @@ pci:v000010DEd00001185*
  ID_MODEL_FROM_DATABASE=GK104 [GeForce GTX 660 OEM]
 
 pci:v000010DEd00001185sv000010DEsd0000106F*
- ID_MODEL_FROM_DATABASE=GK104 [GeForce GTX 760 OEM]
+ ID_MODEL_FROM_DATABASE=GK104 [GeForce GTX 660 OEM] (GK104 [GeForce GTX 760 OEM])
 
 pci:v000010DEd00001187*
  ID_MODEL_FROM_DATABASE=GK104 [GeForce GTX 760]
@@ -26778,7 +27528,7 @@ pci:v000010DEd00001189*
  ID_MODEL_FROM_DATABASE=GK104 [GeForce GTX 670]
 
 pci:v000010DEd00001189sv000010DEsd00001074*
- ID_MODEL_FROM_DATABASE=GK104 [GeForce GTX 760 Ti OEM]
+ ID_MODEL_FROM_DATABASE=GK104 [GeForce GTX 670] (GK104 [GeForce GTX 760 Ti OEM])
 
 pci:v000010DEd0000118A*
  ID_MODEL_FROM_DATABASE=GK104GL [GRID K520]
@@ -26793,7 +27543,7 @@ pci:v000010DEd0000118D*
  ID_MODEL_FROM_DATABASE=GK104GL [GRID K200 vGPU]
 
 pci:v000010DEd0000118Dsv000010DEsd0000101D*
- ID_MODEL_FROM_DATABASE=GRID K200
+ ID_MODEL_FROM_DATABASE=GK104GL [GRID K200 vGPU] (GRID K200)
 
 pci:v000010DEd0000118E*
  ID_MODEL_FROM_DATABASE=GK104 [GeForce GTX 760 OEM]
@@ -26804,6 +27554,18 @@ pci:v000010DEd0000118F*
 pci:v000010DEd00001193*
  ID_MODEL_FROM_DATABASE=GK104 [GeForce GTX 760 Ti OEM]
 
+pci:v000010DEd00001195*
+ ID_MODEL_FROM_DATABASE=GK104 [GeForce GTX 660 Rev. 2]
+
+pci:v000010DEd00001198*
+ ID_MODEL_FROM_DATABASE=GK104M [GeForce GTX 880M]
+
+pci:v000010DEd00001199*
+ ID_MODEL_FROM_DATABASE=GK104M [GeForce GTX 870M]
+
+pci:v000010DEd0000119A*
+ ID_MODEL_FROM_DATABASE=GK104M [GeForce GTX 860M]
+
 pci:v000010DEd0000119D*
  ID_MODEL_FROM_DATABASE=GK104M [GeForce GTX 775M Mac Edition]
 
@@ -26826,7 +27588,7 @@ pci:v000010DEd000011A3*
  ID_MODEL_FROM_DATABASE=GK104M [GeForce GTX 680MX]
 
 pci:v000010DEd000011A3sv0000106Bsd0000010D*
- ID_MODEL_FROM_DATABASE=iMac 13,2
+ ID_MODEL_FROM_DATABASE=GK104M [GeForce GTX 680MX] (iMac 13,2)
 
 pci:v000010DEd000011A7*
  ID_MODEL_FROM_DATABASE=GK104M [GeForce GTX 675MX]
@@ -26835,14 +27597,17 @@ pci:v000010DEd000011B0*
  ID_MODEL_FROM_DATABASE=GK104GL [GRID K240Q\K260Q vGPU]
 
 pci:v000010DEd000011B0sv000010DEsd0000101A*
- ID_MODEL_FROM_DATABASE=GRID K240Q
+ ID_MODEL_FROM_DATABASE=GK104GL [GRID K240Q\K260Q vGPU] (GRID K240Q)
 
 pci:v000010DEd000011B0sv000010DEsd0000101B*
- ID_MODEL_FROM_DATABASE=GRID K260Q
+ ID_MODEL_FROM_DATABASE=GK104GL [GRID K240Q\K260Q vGPU] (GRID K260Q)
 
 pci:v000010DEd000011B1*
  ID_MODEL_FROM_DATABASE=GK104GL [GRID K2 Tesla USM]
 
+pci:v000010DEd000011B4*
+ ID_MODEL_FROM_DATABASE=GK104GL [Quadro K4200]
+
 pci:v000010DEd000011B6*
  ID_MODEL_FROM_DATABASE=GK104GLM [Quadro K3100M]
 
@@ -26877,28 +27642,28 @@ pci:v000010DEd000011C2*
  ID_MODEL_FROM_DATABASE=GK106 [GeForce GTX 650 Ti Boost]
 
 pci:v000010DEd000011C2sv00001043sd0000845B*
- ID_MODEL_FROM_DATABASE=GeForce GTX 650 Ti Boost DirectCU II OC
+ ID_MODEL_FROM_DATABASE=GK106 [GeForce GTX 650 Ti Boost] (GeForce GTX 650 Ti Boost DirectCU II OC)
 
 pci:v000010DEd000011C2sv00001462sd00002874*
- ID_MODEL_FROM_DATABASE=GeForce GTX 650 Ti Boost TwinFrozr II OC
+ ID_MODEL_FROM_DATABASE=GK106 [GeForce GTX 650 Ti Boost] (GeForce GTX 650 Ti Boost TwinFrozr II OC)
 
 pci:v000010DEd000011C2sv00001569sd000011C2*
- ID_MODEL_FROM_DATABASE=GeForce GTX 650 Ti Boost OC
+ ID_MODEL_FROM_DATABASE=GK106 [GeForce GTX 650 Ti Boost] (GeForce GTX 650 Ti Boost OC)
 
 pci:v000010DEd000011C2sv000019DAsd00001281*
- ID_MODEL_FROM_DATABASE=GeForce GTX 650 Ti Boost OC
+ ID_MODEL_FROM_DATABASE=GK106 [GeForce GTX 650 Ti Boost] (GeForce GTX 650 Ti Boost OC)
 
 pci:v000010DEd000011C2sv00003842sd00003657*
- ID_MODEL_FROM_DATABASE=GeForce GTX 650 Ti Boost
+ ID_MODEL_FROM_DATABASE=GK106 [GeForce GTX 650 Ti Boost] (GeForce GTX 650 Ti Boost)
 
 pci:v000010DEd000011C2sv00003842sd00003658*
- ID_MODEL_FROM_DATABASE=GeForce GTX 650 Ti Boost Superclocked
+ ID_MODEL_FROM_DATABASE=GK106 [GeForce GTX 650 Ti Boost] (GeForce GTX 650 Ti Boost Superclocked)
 
 pci:v000010DEd000011C3*
  ID_MODEL_FROM_DATABASE=GK106 [GeForce GTX 650 Ti OEM]
 
 pci:v000010DEd000011C3sv000010DEsd00001030*
- ID_MODEL_FROM_DATABASE=GeForce GTX 650 Ti OEM
+ ID_MODEL_FROM_DATABASE=GK106 [GeForce GTX 650 Ti OEM] (GeForce GTX 650 Ti OEM)
 
 pci:v000010DEd000011C4*
  ID_MODEL_FROM_DATABASE=GK106 [GeForce GTX 645 OEM]
@@ -26924,6 +27689,9 @@ pci:v000010DEd000011E2*
 pci:v000010DEd000011E3*
  ID_MODEL_FROM_DATABASE=GK106M [GeForce GTX 760M]
 
+pci:v000010DEd000011E3sv000017AAsd00003683*
+ ID_MODEL_FROM_DATABASE=GK106M [GeForce GTX 760M] (GeForce GTX 760A)
+
 pci:v000010DEd000011FA*
  ID_MODEL_FROM_DATABASE=GK106GL [Quadro K4000]
 
@@ -26985,55 +27753,55 @@ pci:v000010DEd00001247*
  ID_MODEL_FROM_DATABASE=GF116M [GeForce GT 555M/635M]
 
 pci:v000010DEd00001247sv00001043sd00001752*
- ID_MODEL_FROM_DATABASE=GeForce GT 555M
+ ID_MODEL_FROM_DATABASE=GF116M [GeForce GT 555M/635M] (GeForce GT 555M)
 
 pci:v000010DEd00001247sv00001043sd00002050*
- ID_MODEL_FROM_DATABASE=GeForce GT 555M
+ ID_MODEL_FROM_DATABASE=GF116M [GeForce GT 555M/635M] (GeForce GT 555M)
 
 pci:v000010DEd00001247sv00001043sd00002051*
- ID_MODEL_FROM_DATABASE=GeForce GT 555M
+ ID_MODEL_FROM_DATABASE=GF116M [GeForce GT 555M/635M] (GeForce GT 555M)
 
 pci:v000010DEd00001247sv00001043sd0000212A*
- ID_MODEL_FROM_DATABASE=GeForce GT 635M
+ ID_MODEL_FROM_DATABASE=GF116M [GeForce GT 555M/635M] (GeForce GT 635M)
 
 pci:v000010DEd00001247sv00001043sd0000212B*
- ID_MODEL_FROM_DATABASE=GeForce GT 635M
+ ID_MODEL_FROM_DATABASE=GF116M [GeForce GT 555M/635M] (GeForce GT 635M)
 
 pci:v000010DEd00001247sv00001043sd0000212C*
- ID_MODEL_FROM_DATABASE=GeForce GT 635M
+ ID_MODEL_FROM_DATABASE=GF116M [GeForce GT 555M/635M] (GeForce GT 635M)
 
 pci:v000010DEd00001247sv0000152Dsd00000930*
- ID_MODEL_FROM_DATABASE=GeForce GT 635M
+ ID_MODEL_FROM_DATABASE=GF116M [GeForce GT 555M/635M] (GeForce GT 635M)
 
 pci:v000010DEd00001248*
  ID_MODEL_FROM_DATABASE=GF116M [GeForce GT 555M/635M]
 
 pci:v000010DEd00001248sv0000152Dsd00000930*
- ID_MODEL_FROM_DATABASE=GeForce GT 635M
+ ID_MODEL_FROM_DATABASE=GF116M [GeForce GT 555M/635M] (GeForce GT 635M)
 
 pci:v000010DEd00001248sv000017C0sd000010E7*
- ID_MODEL_FROM_DATABASE=GeForce GT 555M
+ ID_MODEL_FROM_DATABASE=GF116M [GeForce GT 555M/635M] (GeForce GT 555M)
 
 pci:v000010DEd00001248sv000017C0sd000010E8*
- ID_MODEL_FROM_DATABASE=GeForce GT 555M
+ ID_MODEL_FROM_DATABASE=GF116M [GeForce GT 555M/635M] (GeForce GT 555M)
 
 pci:v000010DEd00001248sv000017C0sd000010EA*
- ID_MODEL_FROM_DATABASE=GeForce GT 555M
+ ID_MODEL_FROM_DATABASE=GF116M [GeForce GT 555M/635M] (GeForce GT 555M)
 
 pci:v000010DEd00001248sv00001854sd00000890*
- ID_MODEL_FROM_DATABASE=GeForce GT 555M
+ ID_MODEL_FROM_DATABASE=GF116M [GeForce GT 555M/635M] (GeForce GT 555M)
 
 pci:v000010DEd00001248sv00001854sd00000891*
- ID_MODEL_FROM_DATABASE=GeForce GT 555M
+ ID_MODEL_FROM_DATABASE=GF116M [GeForce GT 555M/635M] (GeForce GT 555M)
 
 pci:v000010DEd00001248sv00001854sd00001795*
- ID_MODEL_FROM_DATABASE=GeForce GT 555M
+ ID_MODEL_FROM_DATABASE=GF116M [GeForce GT 555M/635M] (GeForce GT 555M)
 
 pci:v000010DEd00001248sv00001854sd00001796*
- ID_MODEL_FROM_DATABASE=GeForce GT 555M
+ ID_MODEL_FROM_DATABASE=GF116M [GeForce GT 555M/635M] (GeForce GT 555M)
 
 pci:v000010DEd00001248sv00001854sd00003005*
- ID_MODEL_FROM_DATABASE=GeForce GT 555M
+ ID_MODEL_FROM_DATABASE=GF116M [GeForce GT 555M/635M] (GeForce GT 555M)
 
 pci:v000010DEd00001249*
  ID_MODEL_FROM_DATABASE=GF116 [GeForce GTS 450 Rev. 3]
@@ -27045,19 +27813,19 @@ pci:v000010DEd0000124D*
  ID_MODEL_FROM_DATABASE=GF116M [GeForce GT 555M/635M]
 
 pci:v000010DEd0000124Dsv00001028sd00000491*
- ID_MODEL_FROM_DATABASE=GeForce GT 555M
+ ID_MODEL_FROM_DATABASE=GF116M [GeForce GT 555M/635M] (GeForce GT 555M)
 
 pci:v000010DEd0000124Dsv00001028sd00000570*
- ID_MODEL_FROM_DATABASE=GeForce GT 555M
+ ID_MODEL_FROM_DATABASE=GF116M [GeForce GT 555M/635M] (GeForce GT 555M)
 
 pci:v000010DEd0000124Dsv00001028sd00000571*
- ID_MODEL_FROM_DATABASE=GeForce GT 555M
+ ID_MODEL_FROM_DATABASE=GF116M [GeForce GT 555M/635M] (GeForce GT 555M)
 
 pci:v000010DEd0000124Dsv00001462sd0000108D*
- ID_MODEL_FROM_DATABASE=GeForce GT 555M
+ ID_MODEL_FROM_DATABASE=GF116M [GeForce GT 555M/635M] (GeForce GT 555M)
 
 pci:v000010DEd0000124Dsv00001462sd000010CC*
- ID_MODEL_FROM_DATABASE=GeForce GT 635M
+ ID_MODEL_FROM_DATABASE=GF116M [GeForce GT 555M/635M] (GeForce GT 635M)
 
 pci:v000010DEd00001251*
  ID_MODEL_FROM_DATABASE=GF116M [GeForce GT 560M]
@@ -27065,26 +27833,35 @@ pci:v000010DEd00001251*
 pci:v000010DEd00001280*
  ID_MODEL_FROM_DATABASE=GK208 [GeForce GT 635]
 
+pci:v000010DEd00001281*
+ ID_MODEL_FROM_DATABASE=GK208 [GeForce GT 710]
+
 pci:v000010DEd00001282*
  ID_MODEL_FROM_DATABASE=GK208 [GeForce GT 640 Rev. 2]
 
 pci:v000010DEd00001284*
  ID_MODEL_FROM_DATABASE=GK208 [GeForce GT 630 Rev. 2]
 
+pci:v000010DEd00001286*
+ ID_MODEL_FROM_DATABASE=GK208 [GeForce GT 720]
+
+pci:v000010DEd00001287*
+ ID_MODEL_FROM_DATABASE=GK208 [GeForce GT 730]
+
 pci:v000010DEd00001290*
  ID_MODEL_FROM_DATABASE=GK208M [GeForce GT 730M]
 
 pci:v000010DEd00001290sv0000103Csd00002AFA*
- ID_MODEL_FROM_DATABASE=GeForce GT 730A
+ ID_MODEL_FROM_DATABASE=GK208M [GeForce GT 730M] (GeForce GT 730A)
 
 pci:v000010DEd00001290sv0000103Csd00002B04*
- ID_MODEL_FROM_DATABASE=GeForce GT 730A
+ ID_MODEL_FROM_DATABASE=GK208M [GeForce GT 730M] (GeForce GT 730A)
 
 pci:v000010DEd00001290sv00001043sd000013AD*
- ID_MODEL_FROM_DATABASE=GeForce GT 730M
+ ID_MODEL_FROM_DATABASE=GK208M [GeForce GT 730M] (GeForce GT 730M)
 
 pci:v000010DEd00001290sv00001043sd000013CD*
- ID_MODEL_FROM_DATABASE=GeForce GT 730M
+ ID_MODEL_FROM_DATABASE=GK208M [GeForce GT 730M] (GeForce GT 730M)
 
 pci:v000010DEd00001291*
  ID_MODEL_FROM_DATABASE=GK208M [GeForce GT 735M]
@@ -27093,10 +27870,10 @@ pci:v000010DEd00001292*
  ID_MODEL_FROM_DATABASE=GK208M [GeForce GT 740M]
 
 pci:v000010DEd00001292sv000017AAsd00003675*
- ID_MODEL_FROM_DATABASE=GeForce GT 740A
+ ID_MODEL_FROM_DATABASE=GK208M [GeForce GT 740M] (GeForce GT 740A)
 
 pci:v000010DEd00001292sv000017AAsd00003684*
- ID_MODEL_FROM_DATABASE=GeForce GT 740A
+ ID_MODEL_FROM_DATABASE=GK208M [GeForce GT 740M] (GeForce GT 740A)
 
 pci:v000010DEd00001293*
  ID_MODEL_FROM_DATABASE=GK208M [GeForce GT 730M]
@@ -27107,6 +27884,27 @@ pci:v000010DEd00001294*
 pci:v000010DEd00001295*
  ID_MODEL_FROM_DATABASE=GK208M [GeForce 710M]
 
+pci:v000010DEd00001295sv0000103Csd00002B0D*
+ ID_MODEL_FROM_DATABASE=GK208M [GeForce 710M] (GeForce GT 710A)
+
+pci:v000010DEd00001295sv0000103Csd00002B0F*
+ ID_MODEL_FROM_DATABASE=GK208M [GeForce 710M] (GeForce GT 710A)
+
+pci:v000010DEd00001295sv0000103Csd00002B11*
+ ID_MODEL_FROM_DATABASE=GK208M [GeForce 710M] (GeForce GT 710A)
+
+pci:v000010DEd00001295sv0000103Csd00002B20*
+ ID_MODEL_FROM_DATABASE=GK208M [GeForce 710M] (GeForce 810A)
+
+pci:v000010DEd00001295sv0000103Csd00002B21*
+ ID_MODEL_FROM_DATABASE=GK208M [GeForce 710M] (GeForce GT 810A)
+
+pci:v000010DEd00001295sv0000103Csd00002B22*
+ ID_MODEL_FROM_DATABASE=GK208M [GeForce 710M] (GeForce GT 810A)
+
+pci:v000010DEd00001296*
+ ID_MODEL_FROM_DATABASE=GK208M [GeForce 825M]
+
 pci:v000010DEd00001298*
  ID_MODEL_FROM_DATABASE=GK208M [GeForce GT 720M]
 
@@ -27119,12 +27917,75 @@ pci:v000010DEd000012B9*
 pci:v000010DEd000012BA*
  ID_MODEL_FROM_DATABASE=GK208GLM [Quadro K510M]
 
+pci:v000010DEd00001340*
+ ID_MODEL_FROM_DATABASE=GM108M [GeForce 830M]
+
+pci:v000010DEd00001340sv0000103Csd00002B2B*
+ ID_MODEL_FROM_DATABASE=GM108M [GeForce 830M] (GeForce 830A)
+
+pci:v000010DEd00001341*
+ ID_MODEL_FROM_DATABASE=GM108M [GeForce 840M]
+
+pci:v000010DEd00001341sv000017AAsd00003697*
+ ID_MODEL_FROM_DATABASE=GM108M [GeForce 840M] (GeForce 840A)
+
+pci:v000010DEd00001341sv000017AAsd00003699*
+ ID_MODEL_FROM_DATABASE=GM108M [GeForce 840M] (GeForce 840A)
+
+pci:v000010DEd00001341sv000017AAsd0000369C*
+ ID_MODEL_FROM_DATABASE=GM108M [GeForce 840M] (GeForce 840A)
+
+pci:v000010DEd00001380*
+ ID_MODEL_FROM_DATABASE=GM107 [GeForce GTX 750 Ti]
+
+pci:v000010DEd00001381*
+ ID_MODEL_FROM_DATABASE=GM107 [GeForce GTX 750]
+
+pci:v000010DEd00001382*
+ ID_MODEL_FROM_DATABASE=GM107 [GeForce GTX 745]
+
+pci:v000010DEd00001390*
+ ID_MODEL_FROM_DATABASE=GM107M [GeForce 845M]
+
+pci:v000010DEd00001391*
+ ID_MODEL_FROM_DATABASE=GM107M [GeForce GTX 850M]
+
+pci:v000010DEd00001391sv000017AAsd00003697*
+ ID_MODEL_FROM_DATABASE=GM107M [GeForce GTX 850M] (GeForce GTX 850A)
+
+pci:v000010DEd00001391sv000017AAsd0000A125*
+ ID_MODEL_FROM_DATABASE=GM107M [GeForce GTX 850M] (GeForce GTX 850A)
+
+pci:v000010DEd00001392*
+ ID_MODEL_FROM_DATABASE=GM107M [GeForce GTX 860M]
+
+pci:v000010DEd00001393*
+ ID_MODEL_FROM_DATABASE=GM107M [GeForce 840M]
+
+pci:v000010DEd000013B3*
+ ID_MODEL_FROM_DATABASE=GM107GLM [Quadro K2200M]
+
+pci:v000010DEd000013BA*
+ ID_MODEL_FROM_DATABASE=GM107GL [Quadro K2200]
+
+pci:v000010DEd000013BB*
+ ID_MODEL_FROM_DATABASE=GM107GL [Quadro K620]
+
 pci:v000010DF*
  ID_VENDOR_FROM_DATABASE=Emulex Corporation
 
 pci:v000010DFd00000720*
  ID_MODEL_FROM_DATABASE=OneConnect NIC (Skyhawk)
 
+pci:v000010DFd00000720sv000017AAsd00001056*
+ ID_MODEL_FROM_DATABASE=OneConnect NIC (Skyhawk) (ThinkServer OCm14102-UX-L AnyFabric)
+
+pci:v000010DFd00000720sv000017AAsd00001057*
+ ID_MODEL_FROM_DATABASE=OneConnect NIC (Skyhawk) (ThinkServer OCm14104-UX-L AnyFabric)
+
+pci:v000010DFd00000720sv000017AAsd00001059*
+ ID_MODEL_FROM_DATABASE=OneConnect NIC (Skyhawk) (ThinkServer OCm14104-UT-L AnyFabric)
+
 pci:v000010DFd00000722*
  ID_MODEL_FROM_DATABASE=OneConnect iSCSI Initiator (Skyhawk)
 
@@ -27167,6 +28028,12 @@ pci:v000010DFd0000E208*
 pci:v000010DFd0000E220*
  ID_MODEL_FROM_DATABASE=OneConnect NIC (Lancer)
 
+pci:v000010DFd0000E220sv000017AAsd00001054*
+ ID_MODEL_FROM_DATABASE=OneConnect NIC (Lancer) (ThinkServer LPm16002B-M6-L AnyFabric)
+
+pci:v000010DFd0000E220sv000017AAsd00001055*
+ ID_MODEL_FROM_DATABASE=OneConnect NIC (Lancer) (ThinkServer LPm16004B-M8-L AnyFabric)
+
 pci:v000010DFd0000E240*
  ID_MODEL_FROM_DATABASE=OneConnect iSCSI Initiator (Lancer)
 
@@ -27264,7 +28131,7 @@ pci:v000010DFd0000FC00*
  ID_MODEL_FROM_DATABASE=Thor-X LightPulse Fibre Channel Host Adapter
 
 pci:v000010DFd0000FC00sv000010DFsd0000FC00*
- ID_MODEL_FROM_DATABASE=LP10000 LightPulse Fibre Channel Host Adapter
+ ID_MODEL_FROM_DATABASE=Thor-X LightPulse Fibre Channel Host Adapter (LP10000 LightPulse Fibre Channel Host Adapter)
 
 pci:v000010DFd0000FC10*
  ID_MODEL_FROM_DATABASE=Helios-X LightPulse Fibre Channel Host Adapter
@@ -27330,7 +28197,7 @@ pci:v000010E1d00000391*
  ID_MODEL_FROM_DATABASE=TRM-S1040
 
 pci:v000010E1d00000391sv000010E1sd00000391*
- ID_MODEL_FROM_DATABASE=DC-315U SCSI-3 Host Adapter
+ ID_MODEL_FROM_DATABASE=TRM-S1040 (DC-315U SCSI-3 Host Adapter)
 
 pci:v000010E1d0000690C*
  ID_MODEL_FROM_DATABASE=DC-690c
@@ -27354,7 +28221,7 @@ pci:v000010E3d00000148*
  ID_MODEL_FROM_DATABASE=Tsi148 [Tempe]
 
 pci:v000010E3d00000148sv00001775sd00001100*
- ID_MODEL_FROM_DATABASE=VR11 Single Board Computer
+ ID_MODEL_FROM_DATABASE=Tsi148 [Tempe] (VR11 Single Board Computer)
 
 pci:v000010E3d00000860*
  ID_MODEL_FROM_DATABASE=CA91C860 [QSpan]
@@ -27533,6 +28400,9 @@ pci:v000010EC*
 pci:v000010ECd00000139*
  ID_MODEL_FROM_DATABASE=RTL-8139/8139C/8139C+ Ethernet Controller
 
+pci:v000010ECd00005208*
+ ID_MODEL_FROM_DATABASE=RTS5208 PCI Express Card Reader
+
 pci:v000010ECd00005209*
  ID_MODEL_FROM_DATABASE=RTS5209 PCI Express Card Reader
 
@@ -27540,340 +28410,364 @@ pci:v000010ECd00005227*
  ID_MODEL_FROM_DATABASE=RTS5227 PCI Express Card Reader
 
 pci:v000010ECd00005227sv000017AAsd0000220E*
- ID_MODEL_FROM_DATABASE=ThinkPad T440p
+ ID_MODEL_FROM_DATABASE=RTS5227 PCI Express Card Reader (ThinkPad T440p)
+
+pci:v000010ECd00005227sv000017AAsd00002214*
+ ID_MODEL_FROM_DATABASE=RTS5227 PCI Express Card Reader (ThinkPad X240)
 
 pci:v000010ECd00005229*
  ID_MODEL_FROM_DATABASE=RTS5229 PCI Express Card Reader
 
 pci:v000010ECd00005229sv00001025sd00000813*
- ID_MODEL_FROM_DATABASE=Aspire R7-571
+ ID_MODEL_FROM_DATABASE=RTS5229 PCI Express Card Reader (Aspire R7-571)
 
 pci:v000010ECd00005229sv0000103Csd0000194E*
- ID_MODEL_FROM_DATABASE=ProBook 455 G1 Notebook
+ ID_MODEL_FROM_DATABASE=RTS5229 PCI Express Card Reader (ProBook 455 G1 Notebook)
+
+pci:v000010ECd00005249*
+ ID_MODEL_FROM_DATABASE=RTS5249 PCI Express Card Reader
+
+pci:v000010ECd00005249sv0000103Csd00001909*
+ ID_MODEL_FROM_DATABASE=RTS5249 PCI Express Card Reader (ZBook 15)
 
 pci:v000010ECd00005288*
- ID_MODEL_FROM_DATABASE=Barossa PCI Express Card Reader
+ ID_MODEL_FROM_DATABASE=RTS5288 PCI Express Card Reader
 
 pci:v000010ECd00008029*
  ID_MODEL_FROM_DATABASE=RTL-8029(AS)
 
 pci:v000010ECd00008029sv000010B8sd00002011*
- ID_MODEL_FROM_DATABASE=EZ-Card (SMC1208)
+ ID_MODEL_FROM_DATABASE=RTL-8029(AS) (EZ-Card (SMC1208))
 
 pci:v000010ECd00008029sv000010ECsd00008029*
  ID_MODEL_FROM_DATABASE=RTL-8029(AS)
 
 pci:v000010ECd00008029sv00001113sd00001208*
- ID_MODEL_FROM_DATABASE=EN1208
+ ID_MODEL_FROM_DATABASE=RTL-8029(AS) (EN1208)
 
 pci:v000010ECd00008029sv00001186sd00000300*
- ID_MODEL_FROM_DATABASE=DE-528
+ ID_MODEL_FROM_DATABASE=RTL-8029(AS) (DE-528)
 
 pci:v000010ECd00008029sv00001259sd00002400*
- ID_MODEL_FROM_DATABASE=AT-2400
+ ID_MODEL_FROM_DATABASE=RTL-8029(AS) (AT-2400)
 
 pci:v000010ECd00008029sv00001AF4sd00001100*
- ID_MODEL_FROM_DATABASE=Qemu virtual machine
+ ID_MODEL_FROM_DATABASE=RTL-8029(AS) (QEMU Virtual Machine)
 
 pci:v000010ECd00008129*
  ID_MODEL_FROM_DATABASE=RTL-8129
 
 pci:v000010ECd00008129sv000010ECsd00008129*
- ID_MODEL_FROM_DATABASE=RT8129 Fast Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=RTL-8129 (RT8129 Fast Ethernet Adapter)
 
 pci:v000010ECd00008129sv000011ECsd00008129*
- ID_MODEL_FROM_DATABASE=RTL8111/8168 PCIe Gigabit Ethernet (misconfigured)
+ ID_MODEL_FROM_DATABASE=RTL-8129 (RTL8111/8168 PCIe Gigabit Ethernet (misconfigured))
 
 pci:v000010ECd00008136*
  ID_MODEL_FROM_DATABASE=RTL8101E/RTL8102E PCI Express Fast Ethernet controller
 
 pci:v000010ECd00008136sv0000103Csd00002AB1*
- ID_MODEL_FROM_DATABASE=Pavillion p6774
+ ID_MODEL_FROM_DATABASE=RTL8101E/RTL8102E PCI Express Fast Ethernet controller (Pavilion p6774)
 
 pci:v000010ECd00008136sv0000103Csd000030CC*
- ID_MODEL_FROM_DATABASE=Pavilion dv6700
+ ID_MODEL_FROM_DATABASE=RTL8101E/RTL8102E PCI Express Fast Ethernet controller (Pavilion dv6700)
 
 pci:v000010ECd00008136sv00001179sd0000FF64*
- ID_MODEL_FROM_DATABASE=RTL8102E PCI-E Fast Ethernet NIC
+ ID_MODEL_FROM_DATABASE=RTL8101E/RTL8102E PCI Express Fast Ethernet controller (RTL8102E PCI-E Fast Ethernet NIC)
+
+pci:v000010ECd00008136sv000017C0sd00001053*
+ ID_MODEL_FROM_DATABASE=RTL8101E/RTL8102E PCI Express Fast Ethernet controller (AzureWave AW-NE766 802.11B/G/N Mini PCIe Card Model RT2700E)
 
 pci:v000010ECd00008138*
  ID_MODEL_FROM_DATABASE=RT8139 (B/C) Cardbus Fast Ethernet Adapter
 
 pci:v000010ECd00008138sv000010ECsd00008138*
- ID_MODEL_FROM_DATABASE=RT8139 (B/C) Fast Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=RT8139 (B/C) Cardbus Fast Ethernet Adapter (RT8139 (B/C) Fast Ethernet Adapter)
 
 pci:v000010ECd00008139*
- ID_MODEL_FROM_DATABASE=RTL-8139/8139C/8139C+
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter
 
 pci:v000010ECd00008139sv00000357sd0000000A*
- ID_MODEL_FROM_DATABASE=TTP-Monitoring Card V2.0
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (TTP-Monitoring Card V2.0)
 
 pci:v000010ECd00008139sv00001025sd0000005A*
- ID_MODEL_FROM_DATABASE=TravelMate 290
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (TravelMate 290)
 
 pci:v000010ECd00008139sv00001025sd00008920*
- ID_MODEL_FROM_DATABASE=ALN-325
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (ALN-325)
 
 pci:v000010ECd00008139sv00001025sd00008921*
- ID_MODEL_FROM_DATABASE=ALN-325
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (ALN-325)
 
 pci:v000010ECd00008139sv0000103Csd0000006A*
- ID_MODEL_FROM_DATABASE=NX9500
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (NX9500)
 
 pci:v000010ECd00008139sv0000103Csd00002A20*
- ID_MODEL_FROM_DATABASE=Pavilion t3030.de Desktop PC
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (Pavilion t3030.de Desktop PC)
 
 pci:v000010ECd00008139sv0000103Csd000030D9*
- ID_MODEL_FROM_DATABASE=Presario C700
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (Presario C700)
 
 pci:v000010ECd00008139sv00001043sd00001045*
- ID_MODEL_FROM_DATABASE=L8400B or L3C/S notebook
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (L8400B or L3C/S notebook)
 
 pci:v000010ECd00008139sv00001043sd00008109*
- ID_MODEL_FROM_DATABASE=P5P800-MX Mainboard
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (P5P800-MX Mainboard)
 
 pci:v000010ECd00008139sv00001071sd00008160*
- ID_MODEL_FROM_DATABASE=MIM2000
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (MIM2000)
 
 pci:v000010ECd00008139sv000010BDsd00000320*
- ID_MODEL_FROM_DATABASE=EP-320X-R
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (EP-320X-R)
+
+pci:v000010ECd00008139sv000010ECsd00008139*
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter
 
 pci:v000010ECd00008139sv000010F7sd00008338*
- ID_MODEL_FROM_DATABASE=Panasonic CF-Y5 laptop
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (Panasonic CF-Y5 laptop)
 
 pci:v000010ECd00008139sv00001113sd0000EC01*
- ID_MODEL_FROM_DATABASE=FNC-0107TX
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (LevelOne FNC-0107TX/FNC-0109TX)
 
 pci:v000010ECd00008139sv00001186sd00001300*
- ID_MODEL_FROM_DATABASE=DFE-538TX
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (DFE-538TX)
 
 pci:v000010ECd00008139sv00001186sd00001320*
- ID_MODEL_FROM_DATABASE=SN5200
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (SN5200)
 
 pci:v000010ECd00008139sv00001186sd00008139*
- ID_MODEL_FROM_DATABASE=DRN-32TX
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (DRN-32TX)
 
 pci:v000010ECd00008139sv000011F6sd00008139*
- ID_MODEL_FROM_DATABASE=FN22-3(A) LinxPRO Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (FN22-3(A) LinxPRO Ethernet Adapter)
 
 pci:v000010ECd00008139sv00001259sd00002500*
- ID_MODEL_FROM_DATABASE=AT-2500TX
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (AT-2500TX)
 
 pci:v000010ECd00008139sv00001259sd00002503*
- ID_MODEL_FROM_DATABASE=AT-2500TX/ACPI
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (AT-2500TX/ACPI)
 
 pci:v000010ECd00008139sv00001385sd0000F31D*
- ID_MODEL_FROM_DATABASE=FA311 v2
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (FA311 v2)
 
 pci:v000010ECd00008139sv00001395sd00002100*
- ID_MODEL_FROM_DATABASE=AMB2100
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (AMB2100)
 
 pci:v000010ECd00008139sv00001429sd0000D010*
- ID_MODEL_FROM_DATABASE=ND010/ND012
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (ND010/ND012)
 
 pci:v000010ECd00008139sv00001432sd00009130*
- ID_MODEL_FROM_DATABASE=EN-9130TX
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (EN-9130TX)
 
 pci:v000010ECd00008139sv00001436sd00008139*
- ID_MODEL_FROM_DATABASE=RT8139
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (RT8139)
 
 pci:v000010ECd00008139sv0000144Dsd0000C00C*
- ID_MODEL_FROM_DATABASE=P30/P35 notebook
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (P30/P35 notebook)
 
 pci:v000010ECd00008139sv00001458sd0000E000*
- ID_MODEL_FROM_DATABASE=GA-7VM400M/7VT600 Motherboard
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (GA-7VM400M/7VT600 Motherboard)
 
 pci:v000010ECd00008139sv00001462sd00000131*
- ID_MODEL_FROM_DATABASE=MS-1013 Notebook
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (MS-1013 Notebook)
 
 pci:v000010ECd00008139sv00001462sd0000217C*
- ID_MODEL_FROM_DATABASE=Aspire L250
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (Aspire L250)
 
 pci:v000010ECd00008139sv00001462sd0000788C*
- ID_MODEL_FROM_DATABASE=865PE Neo2-V Mainboard
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (865PE Neo2-V Mainboard)
 
 pci:v000010ECd00008139sv0000146Csd00001439*
- ID_MODEL_FROM_DATABASE=FE-1439TX
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (FE-1439TX)
 
 pci:v000010ECd00008139sv00001489sd00006001*
- ID_MODEL_FROM_DATABASE=GF100TXRII
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (GF100TXRII)
 
 pci:v000010ECd00008139sv00001489sd00006002*
- ID_MODEL_FROM_DATABASE=GF100TXRA
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (GF100TXRA)
 
 pci:v000010ECd00008139sv0000149Csd0000139A*
- ID_MODEL_FROM_DATABASE=LFE-8139ATX
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (LFE-8139ATX)
 
 pci:v000010ECd00008139sv0000149Csd00008139*
- ID_MODEL_FROM_DATABASE=LFE-8139TX
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (LFE-8139TX)
 
 pci:v000010ECd00008139sv000014CBsd00000200*
- ID_MODEL_FROM_DATABASE=LNR-100 Family 10/100 Base-TX Ethernet
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (LNR-100 Family 10/100 Base-TX Ethernet)
 
 pci:v000010ECd00008139sv00001565sd00002300*
- ID_MODEL_FROM_DATABASE=P4TSV Onboard LAN (RTL8100B)
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (P4TSV Onboard LAN (RTL8100B))
 
 pci:v000010ECd00008139sv00001631sd00007003*
- ID_MODEL_FROM_DATABASE=Onboard RTL8111 on GA-8SIML Rev1.0 Mainboard
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (Onboard RTL8111 on GA-8SIML Rev1.0 Mainboard)
 
 pci:v000010ECd00008139sv00001695sd00009001*
- ID_MODEL_FROM_DATABASE=Onboard RTL8101L 10/100 MBit
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (Onboard RTL8101L 10/100 MBit)
 
 pci:v000010ECd00008139sv000016ECsd000000FF*
- ID_MODEL_FROM_DATABASE=USR997900A
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (USR997900A)
 
 pci:v000010ECd00008139sv00001799sd00005000*
- ID_MODEL_FROM_DATABASE=F5D5000 PCI Card/Desktop Network PCI Card
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (F5D5000 PCI Card/Desktop Network PCI Card)
 
 pci:v000010ECd00008139sv00001799sd00005010*
- ID_MODEL_FROM_DATABASE=F5D5010 CardBus Notebook Network Card
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (F5D5010 CardBus Notebook Network Card)
 
 pci:v000010ECd00008139sv0000187Esd00003303*
- ID_MODEL_FROM_DATABASE=FN312
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (FN312)
 
 pci:v000010ECd00008139sv00001904sd00008139*
- ID_MODEL_FROM_DATABASE=RTL8139D Fast Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (RTL8139D Fast Ethernet Adapter)
+
+pci:v000010ECd00008139sv00001AF4sd00001100*
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (QEMU Virtual Machine)
 
 pci:v000010ECd00008139sv00002646sd00000001*
- ID_MODEL_FROM_DATABASE=KNE120TX
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (KNE120TX)
 
 pci:v000010ECd00008139sv00008E2Esd00007000*
- ID_MODEL_FROM_DATABASE=KF-230TX
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (KF-230TX)
 
 pci:v000010ECd00008139sv00008E2Esd00007100*
- ID_MODEL_FROM_DATABASE=KF-230TX/2
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (KF-230TX/2)
 
 pci:v000010ECd00008139sv0000A0A0sd00000007*
- ID_MODEL_FROM_DATABASE=ALN-325C
+ ID_MODEL_FROM_DATABASE=RTL-8100/8101L/8139 PCI Fast Ethernet Adapter (ALN-325C)
 
 pci:v000010ECd00008167*
  ID_MODEL_FROM_DATABASE=RTL-8110SC/8169SC Gigabit Ethernet
 
 pci:v000010ECd00008167sv00001458sd0000E000*
- ID_MODEL_FROM_DATABASE=GA-MA69G-S3H Motherboard
+ ID_MODEL_FROM_DATABASE=RTL-8110SC/8169SC Gigabit Ethernet (GA-MA69G-S3H Motherboard)
 
 pci:v000010ECd00008167sv00001462sd0000235C*
- ID_MODEL_FROM_DATABASE=P965 Neo MS-7235 mainboard
+ ID_MODEL_FROM_DATABASE=RTL-8110SC/8169SC Gigabit Ethernet (P965 Neo MS-7235 mainboard)
 
 pci:v000010ECd00008167sv00001462sd0000236C*
- ID_MODEL_FROM_DATABASE=945P Neo3-F motherboard
+ ID_MODEL_FROM_DATABASE=RTL-8110SC/8169SC Gigabit Ethernet (945P Neo3-F motherboard)
 
 pci:v000010ECd00008168*
  ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller
 
 pci:v000010ECd00008168sv00001019sd00008168*
- ID_MODEL_FROM_DATABASE=RTL8111/8168 PCI Express Gigabit Ethernet controller
+ ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (RTL8111/8168 PCI Express Gigabit Ethernet controller)
 
 pci:v000010ECd00008168sv00001028sd00000283*
- ID_MODEL_FROM_DATABASE=Vostro 220
+ ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (Vostro 220)
 
 pci:v000010ECd00008168sv00001028sd000004B2*
- ID_MODEL_FROM_DATABASE=Vostro 3350
+ ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (Vostro 3350)
 
 pci:v000010ECd00008168sv00001028sd000004DA*
- ID_MODEL_FROM_DATABASE=Vostro 3750
+ ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (Vostro 3750)
 
 pci:v000010ECd00008168sv0000103Csd00001611*
- ID_MODEL_FROM_DATABASE=Pavilion DM1Z-3000
+ ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (Pavilion DM1Z-3000)
 
 pci:v000010ECd00008168sv0000103Csd00001950*
- ID_MODEL_FROM_DATABASE=ProBook 450/455
+ ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (ProBook 450/455)
+
+pci:v000010ECd00008168sv0000103Csd00002A6F*
+ ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (Asus IPIBL-LB Motherboard)
 
 pci:v000010ECd00008168sv00001043sd000011F5*
- ID_MODEL_FROM_DATABASE=A6J-Q008
+ ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (A6J-Q008)
 
 pci:v000010ECd00008168sv00001043sd000016D5*
- ID_MODEL_FROM_DATABASE=U6V/U31J laptop
+ ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (U6V/U31J laptop)
 
 pci:v000010ECd00008168sv00001043sd000081AA*
- ID_MODEL_FROM_DATABASE=P5B
+ ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (P5B)
 
 pci:v000010ECd00008168sv00001043sd000082C6*
- ID_MODEL_FROM_DATABASE=M3A78-EH Motherboard
+ ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (M3A78-EH Motherboard)
 
 pci:v000010ECd00008168sv00001043sd000083A3*
- ID_MODEL_FROM_DATABASE=M4A785TD Motherboard
+ ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (M4A785TD Motherboard)
 
 pci:v000010ECd00008168sv00001043sd00008432*
- ID_MODEL_FROM_DATABASE=P8P67 and other motherboards
+ ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (P8P67 and other motherboards)
 
 pci:v000010ECd00008168sv00001043sd00008505*
- ID_MODEL_FROM_DATABASE=P8H77-I Motherboard
+ ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (P8 series motherboard)
 
 pci:v000010ECd00008168sv0000105Bsd00000D7C*
- ID_MODEL_FROM_DATABASE=D270S/D250S Motherboard
+ ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (D270S/D250S Motherboard)
 
 pci:v000010ECd00008168sv000010ECsd00008168*
- ID_MODEL_FROM_DATABASE=RTL8111/8168 PCI Express Gigabit Ethernet controller
+ ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (RTL8111/8168 PCI Express Gigabit Ethernet controller)
 
 pci:v000010ECd00008168sv00001458sd0000E000*
- ID_MODEL_FROM_DATABASE=Motherboard
+ ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (Motherboard)
 
 pci:v000010ECd00008168sv00001462sd0000238C*
- ID_MODEL_FROM_DATABASE=Onboard RTL8111b on MSI P965 Platinum Mainboard
+ ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (Onboard RTL8111b on MSI P965 Platinum Mainboard)
 
 pci:v000010ECd00008168sv00001462sd0000368C*
- ID_MODEL_FROM_DATABASE=K9AG Neo2
+ ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (K9AG Neo2)
+
+pci:v000010ECd00008168sv00001462sd00004180*
+ ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (Wind PC MS-7418)
 
 pci:v000010ECd00008168sv00001462sd00007522*
- ID_MODEL_FROM_DATABASE=X58 Pro-E
+ ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (X58 Pro-E)
 
 pci:v000010ECd00008168sv00001775sd000011CC*
- ID_MODEL_FROM_DATABASE=CC11/CL11
+ ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (CC11/CL11)
 
 pci:v000010ECd00008168sv00001849sd00008168*
- ID_MODEL_FROM_DATABASE=Motherboard (one of many)
+ ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (Motherboard (one of many))
 
 pci:v000010ECd00008168sv00008086sd0000D615*
- ID_MODEL_FROM_DATABASE=Desktop Board D510MO/D525MW
+ ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (Desktop Board D510MO/D525MW)
 
 pci:v000010ECd00008169*
  ID_MODEL_FROM_DATABASE=RTL8169 PCI Gigabit Ethernet Controller
 
 pci:v000010ECd00008169sv00001025sd00000079*
- ID_MODEL_FROM_DATABASE=Aspire 5024WLMi
+ ID_MODEL_FROM_DATABASE=RTL8169 PCI Gigabit Ethernet Controller (Aspire 5024WLMi)
 
 pci:v000010ECd00008169sv000010BDsd00003202*
- ID_MODEL_FROM_DATABASE=EP-320G-TX1 32-bit PCI Gigabit Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=RTL8169 PCI Gigabit Ethernet Controller (EP-320G-TX1 32-bit PCI Gigabit Ethernet Adapter)
 
 pci:v000010ECd00008169sv000010ECsd00008169*
- ID_MODEL_FROM_DATABASE=RTL8169/8110 Family PCI Gigabit Ethernet NIC
+ ID_MODEL_FROM_DATABASE=RTL8169 PCI Gigabit Ethernet Controller (RTL8169/8110 Family PCI Gigabit Ethernet NIC)
 
 pci:v000010ECd00008169sv00001259sd0000C107*
- ID_MODEL_FROM_DATABASE=CG-LAPCIGT
+ ID_MODEL_FROM_DATABASE=RTL8169 PCI Gigabit Ethernet Controller (CG-LAPCIGT)
 
 pci:v000010ECd00008169sv00001371sd0000434E*
- ID_MODEL_FROM_DATABASE=ProG-2000L
+ ID_MODEL_FROM_DATABASE=RTL8169 PCI Gigabit Ethernet Controller (ProG-2000L)
 
 pci:v000010ECd00008169sv00001385sd0000311A*
- ID_MODEL_FROM_DATABASE=GA311
+ ID_MODEL_FROM_DATABASE=RTL8169 PCI Gigabit Ethernet Controller (GA311)
 
 pci:v000010ECd00008169sv00001385sd00005200*
- ID_MODEL_FROM_DATABASE=GA511 Gigabit PC Card
+ ID_MODEL_FROM_DATABASE=RTL8169 PCI Gigabit Ethernet Controller (GA511 Gigabit PC Card)
 
 pci:v000010ECd00008169sv00001458sd0000E000*
- ID_MODEL_FROM_DATABASE=GA-8I915ME-G Mainboard
+ ID_MODEL_FROM_DATABASE=RTL8169 PCI Gigabit Ethernet Controller (GA-8I915ME-G Mainboard)
 
 pci:v000010ECd00008169sv00001462sd0000030C*
- ID_MODEL_FROM_DATABASE=K8N Neo-FSR v2.0 mainboard
+ ID_MODEL_FROM_DATABASE=RTL8169 PCI Gigabit Ethernet Controller (K8N Neo-FSR v2.0 mainboard)
 
 pci:v000010ECd00008169sv00001462sd0000065C*
- ID_MODEL_FROM_DATABASE=Hetis 865GV-E (MS-7065)
+ ID_MODEL_FROM_DATABASE=RTL8169 PCI Gigabit Ethernet Controller (Hetis 865GV-E (MS-7065))
 
 pci:v000010ECd00008169sv00001462sd0000702C*
- ID_MODEL_FROM_DATABASE=K8T NEO 2 motherboard
+ ID_MODEL_FROM_DATABASE=RTL8169 PCI Gigabit Ethernet Controller (K8T NEO 2 motherboard)
 
 pci:v000010ECd00008169sv00001462sd00007094*
- ID_MODEL_FROM_DATABASE=K8T Neo2-F V2.0
+ ID_MODEL_FROM_DATABASE=RTL8169 PCI Gigabit Ethernet Controller (K8T Neo2-F V2.0)
 
 pci:v000010ECd00008169sv000016ECsd0000011F*
- ID_MODEL_FROM_DATABASE=USR997903
+ ID_MODEL_FROM_DATABASE=RTL8169 PCI Gigabit Ethernet Controller (USR997903)
 
 pci:v000010ECd00008169sv00001734sd00001091*
- ID_MODEL_FROM_DATABASE=D2030-A1
+ ID_MODEL_FROM_DATABASE=RTL8169 PCI Gigabit Ethernet Controller (D2030-A1)
 
 pci:v000010ECd00008169sv0000A0A0sd00000449*
- ID_MODEL_FROM_DATABASE=AK86-L motherboard
+ ID_MODEL_FROM_DATABASE=RTL8169 PCI Gigabit Ethernet Controller (AK86-L motherboard)
 
 pci:v000010ECd00008171*
  ID_MODEL_FROM_DATABASE=RTL8191SEvA Wireless LAN Controller
@@ -27891,13 +28785,13 @@ pci:v000010ECd00008176*
  ID_MODEL_FROM_DATABASE=RTL8188CE 802.11b/g/n WiFi Adapter
 
 pci:v000010ECd00008176sv00001A3Bsd00001139*
- ID_MODEL_FROM_DATABASE=AW-NE139H Half-size Mini PCIe Card
+ ID_MODEL_FROM_DATABASE=RTL8188CE 802.11b/g/n WiFi Adapter (AW-NE139H Half-size Mini PCIe Card)
 
 pci:v000010ECd00008177*
- ID_MODEL_FROM_DATABASE=RTL8188CE 802.11b/g/n WiFi Adapter
+ ID_MODEL_FROM_DATABASE=RTL8191CE PCIe Wireless Network Adapter
 
 pci:v000010ECd00008178*
- ID_MODEL_FROM_DATABASE=RTL8188CE 802.11b/g/n WiFi Adapter
+ ID_MODEL_FROM_DATABASE=RTL8192CE PCIe Wireless Network Adapter
 
 pci:v000010ECd00008179*
  ID_MODEL_FROM_DATABASE=RTL8188EE Wireless Network Adapter
@@ -27906,19 +28800,22 @@ pci:v000010ECd00008180*
  ID_MODEL_FROM_DATABASE=RTL8180L 802.11b MAC
 
 pci:v000010ECd00008180sv00001385sd00004700*
- ID_MODEL_FROM_DATABASE=MA521 802.11b Wireless PC Card
+ ID_MODEL_FROM_DATABASE=RTL8180L 802.11b MAC (MA521 802.11b Wireless PC Card)
 
 pci:v000010ECd00008180sv00001737sd00000019*
- ID_MODEL_FROM_DATABASE=WPC11v4 802.11b Wireless-B Notebook Adapter
+ ID_MODEL_FROM_DATABASE=RTL8180L 802.11b MAC (WPC11v4 802.11b Wireless-B Notebook Adapter)
 
 pci:v000010ECd00008185*
  ID_MODEL_FROM_DATABASE=RTL-8185 IEEE 802.11a/b/g Wireless LAN Controller
 
+pci:v000010ECd0000818B*
+ ID_MODEL_FROM_DATABASE=RTL8192EE PCIe Wireless Network Adapter
+
 pci:v000010ECd00008190*
- ID_MODEL_FROM_DATABASE=RTL8190 802.11n Wireless LAN
+ ID_MODEL_FROM_DATABASE=RTL8190 802.11n PCI Wireless Network Adapter
 
 pci:v000010ECd00008191*
- ID_MODEL_FROM_DATABASE=RTL8188CE 802.11b/g/n WiFi Adapter
+ ID_MODEL_FROM_DATABASE=RTL8192CE PCIe Wireless Network Adapter
 
 pci:v000010ECd00008192*
  ID_MODEL_FROM_DATABASE=RTL8192E/RTL8192SE Wireless LAN Controller
@@ -27933,11 +28830,20 @@ pci:v000010ECd00008199*
  ID_MODEL_FROM_DATABASE=RTL8187SE Wireless LAN Controller
 
 pci:v000010ECd00008199sv00001462sd00006894*
- ID_MODEL_FROM_DATABASE=MN54G2 / MS-6894 Wireless Mini PCIe Card
+ ID_MODEL_FROM_DATABASE=RTL8187SE Wireless LAN Controller (MN54G2 / MS-6894 Wireless Mini PCIe Card)
 
 pci:v000010ECd00008723*
  ID_MODEL_FROM_DATABASE=RTL8723AE PCIe Wireless Network Adapter
 
+pci:v000010ECd00008812*
+ ID_MODEL_FROM_DATABASE=RTL8812AE 802.11ac PCIe Wireless Network Adapter
+
+pci:v000010ECd00008813*
+ ID_MODEL_FROM_DATABASE=RTL8813AE 802.11ac PCIe Wireless Network Adapter
+
+pci:v000010ECd00008821*
+ ID_MODEL_FROM_DATABASE=RTL8821AE 802.11ac PCIe Wireless Network Adapter
+
 pci:v000010ECd0000B723*
  ID_MODEL_FROM_DATABASE=RTL8723BE PCIe Wireless Network Adapter
 
@@ -28134,112 +29040,115 @@ pci:v00001102d00000002*
  ID_MODEL_FROM_DATABASE=SB Live! EMU10k1
 
 pci:v00001102d00000002sv0000100Asd00001102*
- ID_MODEL_FROM_DATABASE=SB Live! 5.1 Digital OEM SB0220 EMU10K1-JFF
+ ID_MODEL_FROM_DATABASE=SB Live! EMU10k1 (SB Live! 5.1 Digital OEM SB0220 EMU10K1-JFF)
 
 pci:v00001102d00000002sv00001102sd00000020*
- ID_MODEL_FROM_DATABASE=CT4850 SBLive! Value
+ ID_MODEL_FROM_DATABASE=SB Live! EMU10k1 (CT4850 SBLive! Value)
 
 pci:v00001102d00000002sv00001102sd00000021*
- ID_MODEL_FROM_DATABASE=CT4620 SBLive!
+ ID_MODEL_FROM_DATABASE=SB Live! EMU10k1 (CT4620 SBLive!)
 
 pci:v00001102d00000002sv00001102sd0000002F*
- ID_MODEL_FROM_DATABASE=SBLive! mainboard implementation
+ ID_MODEL_FROM_DATABASE=SB Live! EMU10k1 (SBLive! mainboard implementation)
 
 pci:v00001102d00000002sv00001102sd0000100A*
- ID_MODEL_FROM_DATABASE=SB Live! 5.1 Digital OEM [SB0220]
+ ID_MODEL_FROM_DATABASE=SB Live! EMU10k1 (SB Live! 5.1 Digital OEM [SB0220])
 
 pci:v00001102d00000002sv00001102sd00004001*
- ID_MODEL_FROM_DATABASE=E-mu APS
+ ID_MODEL_FROM_DATABASE=SB Live! EMU10k1 (E-mu APS)
 
 pci:v00001102d00000002sv00001102sd00008022*
- ID_MODEL_FROM_DATABASE=CT4780 SBLive! Value
+ ID_MODEL_FROM_DATABASE=SB Live! EMU10k1 (CT4780 SBLive! Value)
 
 pci:v00001102d00000002sv00001102sd00008023*
- ID_MODEL_FROM_DATABASE=CT4790 SoundBlaster PCI512
+ ID_MODEL_FROM_DATABASE=SB Live! EMU10k1 (CT4790 SoundBlaster PCI512)
 
 pci:v00001102d00000002sv00001102sd00008024*
- ID_MODEL_FROM_DATABASE=CT4760 SBLive!
+ ID_MODEL_FROM_DATABASE=SB Live! EMU10k1 (CT4760 SBLive!)
 
 pci:v00001102d00000002sv00001102sd00008025*
- ID_MODEL_FROM_DATABASE=SBLive! Mainboard Implementation
+ ID_MODEL_FROM_DATABASE=SB Live! EMU10k1 (SBLive! Mainboard Implementation)
 
 pci:v00001102d00000002sv00001102sd00008026*
- ID_MODEL_FROM_DATABASE=CT4830 SBLive! Value
+ ID_MODEL_FROM_DATABASE=SB Live! EMU10k1 (CT4830 SBLive! Value)
 
 pci:v00001102d00000002sv00001102sd00008027*
- ID_MODEL_FROM_DATABASE=CT4832 SBLive! Value
+ ID_MODEL_FROM_DATABASE=SB Live! EMU10k1 (CT4832 SBLive! Value)
 
 pci:v00001102d00000002sv00001102sd00008028*
- ID_MODEL_FROM_DATABASE=CT4760 SBLive! OEM version
+ ID_MODEL_FROM_DATABASE=SB Live! EMU10k1 (CT4760 SBLive! OEM version)
 
 pci:v00001102d00000002sv00001102sd00008031*
- ID_MODEL_FROM_DATABASE=CT4831 SBLive! Value
+ ID_MODEL_FROM_DATABASE=SB Live! EMU10k1 (CT4831 SBLive! Value)
 
 pci:v00001102d00000002sv00001102sd00008040*
- ID_MODEL_FROM_DATABASE=CT4760 SBLive!
+ ID_MODEL_FROM_DATABASE=SB Live! EMU10k1 (CT4760 SBLive!)
 
 pci:v00001102d00000002sv00001102sd00008051*
- ID_MODEL_FROM_DATABASE=CT4850 SBLive! Value
+ ID_MODEL_FROM_DATABASE=SB Live! EMU10k1 (CT4850 SBLive! Value)
 
 pci:v00001102d00000002sv00001102sd00008061*
- ID_MODEL_FROM_DATABASE=SBLive! Player 5.1
+ ID_MODEL_FROM_DATABASE=SB Live! EMU10k1 (SBLive! Player 5.1)
 
 pci:v00001102d00000002sv00001102sd00008064*
- ID_MODEL_FROM_DATABASE=SBLive! 5.1 Model SB0100
+ ID_MODEL_FROM_DATABASE=SB Live! EMU10k1 (SBLive! 5.1 Model SB0100)
 
 pci:v00001102d00000002sv00001102sd00008065*
- ID_MODEL_FROM_DATABASE=SBLive! 5.1 Digital Model SB0220
+ ID_MODEL_FROM_DATABASE=SB Live! EMU10k1 (SBLive! 5.1 Digital Model SB0220)
 
 pci:v00001102d00000002sv00001102sd00008066*
- ID_MODEL_FROM_DATABASE=Live! 5.1 Digital [SB0228]
+ ID_MODEL_FROM_DATABASE=SB Live! EMU10k1 (Live! 5.1 Digital [SB0228])
 
 pci:v00001102d00000002sv00001102sd00008067*
- ID_MODEL_FROM_DATABASE=SBLive! 5.1 eMicro 28028
+ ID_MODEL_FROM_DATABASE=SB Live! EMU10k1 (SBLive! 5.1 eMicro 28028)
 
 pci:v00001102d00000004*
  ID_MODEL_FROM_DATABASE=SB Audigy
 
 pci:v00001102d00000004sv00001102sd00000051*
- ID_MODEL_FROM_DATABASE=SB0090 Audigy Player
+ ID_MODEL_FROM_DATABASE=SB Audigy (SB0090 Audigy Player)
 
 pci:v00001102d00000004sv00001102sd00000053*
- ID_MODEL_FROM_DATABASE=SB0090 Audigy Player/OEM
+ ID_MODEL_FROM_DATABASE=SB Audigy (SB0090 Audigy Player/OEM)
 
 pci:v00001102d00000004sv00001102sd00000058*
- ID_MODEL_FROM_DATABASE=SB0090 Audigy Player/OEM
+ ID_MODEL_FROM_DATABASE=SB Audigy (SB0090 Audigy Player/OEM)
 
 pci:v00001102d00000004sv00001102sd00001002*
- ID_MODEL_FROM_DATABASE=SB Audigy2 Platinum
+ ID_MODEL_FROM_DATABASE=SB Audigy (2 Platinum)
+
+pci:v00001102d00000004sv00001102sd00001003*
+ ID_MODEL_FROM_DATABASE=SB Audigy (SB0350 Audigy 2)
 
 pci:v00001102d00000004sv00001102sd00001007*
- ID_MODEL_FROM_DATABASE=SB0240 Audigy 2 Platinum 6.1
+ ID_MODEL_FROM_DATABASE=SB Audigy (SB0240 Audigy 2 Platinum 6.1)
 
 pci:v00001102d00000004sv00001102sd00001009*
- ID_MODEL_FROM_DATABASE=SB Audigy2 OEM HP
+ ID_MODEL_FROM_DATABASE=SB Audigy (2 OEM HP)
 
 pci:v00001102d00000004sv00001102sd00002001*
- ID_MODEL_FROM_DATABASE=SB Audigy 2 ZS Platinum Pro
+ ID_MODEL_FROM_DATABASE=SB Audigy (2 ZS Platinum Pro)
 
 pci:v00001102d00000004sv00001102sd00002002*
- ID_MODEL_FROM_DATABASE=SB Audigy 2 ZS (SB0350)
+ ID_MODEL_FROM_DATABASE=SB Audigy (2 ZS (SB0350))
 
 pci:v00001102d00000004sv00001102sd00004001*
- ID_MODEL_FROM_DATABASE=E-MU 1010
+ ID_MODEL_FROM_DATABASE=SB Audigy (E-MU 1010)
 
 pci:v00001102d00000004sv00001102sd00004002*
- ID_MODEL_FROM_DATABASE=E-MU 0404
+ ID_MODEL_FROM_DATABASE=SB Audigy (E-MU 0404)
 
 pci:v00001102d00000005*
  ID_MODEL_FROM_DATABASE=SB X-Fi
 
 pci:v00001102d00000005sv00001102sd00000021*
- ID_MODEL_FROM_DATABASE=X-Fi Platinum
+ ID_MODEL_FROM_DATABASE=SB X-Fi (X-Fi Platinum)
 
 pci:v00001102d00000005sv00001102sd0000002C*
- ID_MODEL_FROM_DATABASE=X-Fi XtremeGamer FATAL1TY PRO
+ ID_MODEL_FROM_DATABASE=SB X-Fi (X-Fi XtremeGamer FATAL1TY PRO)
 
 pci:v00001102d00000005sv00001102sd00001003*
- ID_MODEL_FROM_DATABASE=X-Fi XtremeMusic
+ ID_MODEL_FROM_DATABASE=SB X-Fi (X-Fi XtremeMusic)
 
 pci:v00001102d00000006*
  ID_MODEL_FROM_DATABASE=[SB Live! Value] EMU10k1X
@@ -28248,37 +29157,37 @@ pci:v00001102d00000007*
  ID_MODEL_FROM_DATABASE=CA0106 Soundblaster
 
 pci:v00001102d00000007sv00001102sd00000007*
- ID_MODEL_FROM_DATABASE=SBLive! 24bit
+ ID_MODEL_FROM_DATABASE=CA0106 Soundblaster (SBLive! 24bit)
 
 pci:v00001102d00000007sv00001102sd00001001*
- ID_MODEL_FROM_DATABASE=SB0310 Audigy LS
+ ID_MODEL_FROM_DATABASE=CA0106 Soundblaster (SB0310 Audigy LS)
 
 pci:v00001102d00000007sv00001102sd00001002*
- ID_MODEL_FROM_DATABASE=SB0312 Audigy LS
+ ID_MODEL_FROM_DATABASE=CA0106 Soundblaster (SB0312 Audigy LS)
 
 pci:v00001102d00000007sv00001102sd00001006*
- ID_MODEL_FROM_DATABASE=SB0410 SBLive! 24-bit
+ ID_MODEL_FROM_DATABASE=CA0106 Soundblaster (SB0410 SBLive! 24-bit)
 
 pci:v00001102d00000007sv00001102sd0000100A*
- ID_MODEL_FROM_DATABASE=SB0570 [SB Audigy SE]
+ ID_MODEL_FROM_DATABASE=CA0106 Soundblaster (SB0570 [SB Audigy SE])
 
 pci:v00001102d00000007sv00001102sd00001012*
- ID_MODEL_FROM_DATABASE=SB0790 X-Fi XA
+ ID_MODEL_FROM_DATABASE=CA0106 Soundblaster (SB0790 X-Fi XA)
 
 pci:v00001102d00000007sv00001102sd00001013*
- ID_MODEL_FROM_DATABASE=Soundblaster X-Fi Xtreme Audio
+ ID_MODEL_FROM_DATABASE=CA0106 Soundblaster (Soundblaster X-Fi Xtreme Audio)
 
 pci:v00001102d00000007sv00001462sd00001009*
- ID_MODEL_FROM_DATABASE=K8N Diamond
+ ID_MODEL_FROM_DATABASE=CA0106 Soundblaster (K8N Diamond)
 
 pci:v00001102d00000008*
  ID_MODEL_FROM_DATABASE=SB0400 Audigy2 Value
 
 pci:v00001102d00000008sv00001102sd00000008*
- ID_MODEL_FROM_DATABASE=EMU0404 Digital Audio System
+ ID_MODEL_FROM_DATABASE=SB0400 Audigy2 Value (EMU0404 Digital Audio System)
 
 pci:v00001102d00000008sv00001102sd00004004*
- ID_MODEL_FROM_DATABASE=EMU1010 Digital Audio System [MAEM8960]
+ ID_MODEL_FROM_DATABASE=SB0400 Audigy2 Value (EMU1010 Digital Audio System [MAEM8960])
 
 pci:v00001102d00000009*
  ID_MODEL_FROM_DATABASE=[SB X-Fi Xtreme Audio] CA0110-IBG
@@ -28287,13 +29196,16 @@ pci:v00001102d00000009sv00001102sd00000010*
  ID_MODEL_FROM_DATABASE=[SB X-Fi Xtreme Audio] CA0110-IBG
 
 pci:v00001102d00000009sv00001102sd00000018*
- ID_MODEL_FROM_DATABASE=SB1040
+ ID_MODEL_FROM_DATABASE=[SB X-Fi Xtreme Audio] CA0110-IBG (SB1040)
 
 pci:v00001102d0000000B*
  ID_MODEL_FROM_DATABASE=EMU20k2 [X-Fi Titanium Series]
 
 pci:v00001102d0000000Bsv00001102sd00000041*
- ID_MODEL_FROM_DATABASE=SB0880 [SoundBlaster X-Fi Titanium PCI-e]
+ ID_MODEL_FROM_DATABASE=EMU20k2 [X-Fi Titanium Series] (SB0880 [SoundBlaster X-Fi Titanium PCI-e])
+
+pci:v00001102d00000012*
+ ID_MODEL_FROM_DATABASE=SB Recon3D
 
 pci:v00001102d00004001*
  ID_MODEL_FROM_DATABASE=SB Audigy FireWire Port
@@ -28305,7 +29217,7 @@ pci:v00001102d00007002*
  ID_MODEL_FROM_DATABASE=SB Live! Game Port
 
 pci:v00001102d00007002sv00001102sd00000020*
- ID_MODEL_FROM_DATABASE=Gameport Joystick
+ ID_MODEL_FROM_DATABASE=SB Live! Game Port (Gameport Joystick)
 
 pci:v00001102d00007003*
  ID_MODEL_FROM_DATABASE=SB Audigy Game Port
@@ -28314,7 +29226,7 @@ pci:v00001102d00007003sv00001102sd00000040*
  ID_MODEL_FROM_DATABASE=SB Audigy Game Port
 
 pci:v00001102d00007003sv00001102sd00000060*
- ID_MODEL_FROM_DATABASE=SB Audigy2 MIDI/Game Port
+ ID_MODEL_FROM_DATABASE=SB Audigy Game Port (SB Audigy2 MIDI/Game Port)
 
 pci:v00001102d00007004*
  ID_MODEL_FROM_DATABASE=[SB Live! Value] Input device controller
@@ -28323,10 +29235,10 @@ pci:v00001102d00007005*
  ID_MODEL_FROM_DATABASE=SB Audigy LS Game Port
 
 pci:v00001102d00007005sv00001102sd00001001*
- ID_MODEL_FROM_DATABASE=SB0310 Audigy LS MIDI/Game port
+ ID_MODEL_FROM_DATABASE=SB Audigy LS Game Port (SB0310 Audigy LS MIDI/Game port)
 
 pci:v00001102d00007005sv00001102sd00001002*
- ID_MODEL_FROM_DATABASE=SB0312 Audigy LS MIDI/Game port
+ ID_MODEL_FROM_DATABASE=SB Audigy LS Game Port (SB0312 Audigy LS MIDI/Game port)
 
 pci:v00001102d00007006*
  ID_MODEL_FROM_DATABASE=[SB X-Fi Xtreme Audio] CA0110-IBG PCI to PCIe Bridge
@@ -28335,49 +29247,49 @@ pci:v00001102d00008938*
  ID_MODEL_FROM_DATABASE=Ectiva EV1938
 
 pci:v00001102d00008938sv00001033sd000080E5*
- ID_MODEL_FROM_DATABASE=SlimTower-Jim (NEC)
+ ID_MODEL_FROM_DATABASE=Ectiva EV1938 (SlimTower-Jim (NEC))
 
 pci:v00001102d00008938sv00001071sd00007150*
- ID_MODEL_FROM_DATABASE=Mitac 7150
+ ID_MODEL_FROM_DATABASE=Ectiva EV1938 (Mitac 7150)
 
 pci:v00001102d00008938sv0000110Asd00005938*
- ID_MODEL_FROM_DATABASE=Siemens Scenic Mobile 510PIII
+ ID_MODEL_FROM_DATABASE=Ectiva EV1938 (Siemens Scenic Mobile 510PIII)
 
 pci:v00001102d00008938sv000013BDsd0000100C*
- ID_MODEL_FROM_DATABASE=Ceres-C (Sharp, Intel BX)
+ ID_MODEL_FROM_DATABASE=Ectiva EV1938 (Ceres-C (Sharp, Intel BX))
 
 pci:v00001102d00008938sv000013BDsd0000100D*
- ID_MODEL_FROM_DATABASE=Sharp, Intel Banister
+ ID_MODEL_FROM_DATABASE=Ectiva EV1938 (Sharp, Intel Banister)
 
 pci:v00001102d00008938sv000013BDsd0000100E*
- ID_MODEL_FROM_DATABASE=TwinHead P09S/P09S3 (Sharp)
+ ID_MODEL_FROM_DATABASE=Ectiva EV1938 (TwinHead P09S/P09S3 (Sharp))
 
 pci:v00001102d00008938sv000013BDsd0000F6F1*
- ID_MODEL_FROM_DATABASE=Marlin (Sharp)
+ ID_MODEL_FROM_DATABASE=Ectiva EV1938 (Marlin (Sharp))
 
 pci:v00001102d00008938sv000014FFsd00000E70*
- ID_MODEL_FROM_DATABASE=P88TE (TWINHEAD INTERNATIONAL Corp)
+ ID_MODEL_FROM_DATABASE=Ectiva EV1938 (P88TE (TWINHEAD INTERNATIONAL Corp))
 
 pci:v00001102d00008938sv000014FFsd0000C401*
- ID_MODEL_FROM_DATABASE=Notebook 9100/9200/2000 (TWINHEAD INTERNATIONAL Corp)
+ ID_MODEL_FROM_DATABASE=Ectiva EV1938 (Notebook 9100/9200/2000 (TWINHEAD INTERNATIONAL Corp))
 
 pci:v00001102d00008938sv0000156Dsd0000B400*
- ID_MODEL_FROM_DATABASE=G400 - Geo (AlphaTop (Taiwan))
+ ID_MODEL_FROM_DATABASE=Ectiva EV1938 (G400 - Geo (AlphaTop (Taiwan)))
 
 pci:v00001102d00008938sv0000156Dsd0000B550*
- ID_MODEL_FROM_DATABASE=G560  (AlphaTop (Taiwan))
+ ID_MODEL_FROM_DATABASE=Ectiva EV1938 (G560  (AlphaTop (Taiwan)))
 
 pci:v00001102d00008938sv0000156Dsd0000B560*
- ID_MODEL_FROM_DATABASE=G560  (AlphaTop (Taiwan))
+ ID_MODEL_FROM_DATABASE=Ectiva EV1938 (G560  (AlphaTop (Taiwan)))
 
 pci:v00001102d00008938sv0000156Dsd0000B700*
- ID_MODEL_FROM_DATABASE=G700/U700  (AlphaTop (Taiwan))
+ ID_MODEL_FROM_DATABASE=Ectiva EV1938 (G700/U700  (AlphaTop (Taiwan)))
 
 pci:v00001102d00008938sv0000156Dsd0000B795*
- ID_MODEL_FROM_DATABASE=G795  (AlphaTop (Taiwan))
+ ID_MODEL_FROM_DATABASE=Ectiva EV1938 (G795  (AlphaTop (Taiwan)))
 
 pci:v00001102d00008938sv0000156Dsd0000B797*
- ID_MODEL_FROM_DATABASE=G797  (AlphaTop (Taiwan))
+ ID_MODEL_FROM_DATABASE=Ectiva EV1938 (G797  (AlphaTop (Taiwan)))
 
 pci:v00001103*
  ID_VENDOR_FROM_DATABASE=HighPoint Technologies, Inc.
@@ -28389,16 +29301,16 @@ pci:v00001103d00000004*
  ID_MODEL_FROM_DATABASE=HPT366/368/370/370A/372/372N
 
 pci:v00001103d00000004sv00001103sd00000001*
- ID_MODEL_FROM_DATABASE=HPT370A
+ ID_MODEL_FROM_DATABASE=HPT366/368/370/370A/372/372N (HPT370A)
 
 pci:v00001103d00000004sv00001103sd00000004*
- ID_MODEL_FROM_DATABASE=HPT366 UDMA66 (r1) / HPT368 UDMA66 (r2) / HPT370 UDMA100 (r3) / HPT370 UDMA100 RAID (r4)
+ ID_MODEL_FROM_DATABASE=HPT366/368/370/370A/372/372N (HPT366 UDMA66 (r1) / HPT368 UDMA66 (r2) / HPT370 UDMA100 (r3) / HPT370 UDMA100 RAID (r4))
 
 pci:v00001103d00000004sv00001103sd00000005*
- ID_MODEL_FROM_DATABASE=HPT370 UDMA100
+ ID_MODEL_FROM_DATABASE=HPT366/368/370/370A/372/372N (HPT370 UDMA100)
 
 pci:v00001103d00000004sv00001103sd00000006*
- ID_MODEL_FROM_DATABASE=HPT302/302N
+ ID_MODEL_FROM_DATABASE=HPT366/368/370/370A/372/372N (HPT302/302N)
 
 pci:v00001103d00000005*
  ID_MODEL_FROM_DATABASE=HPT372A/372N
@@ -28424,6 +29336,9 @@ pci:v00001103d00000622*
 pci:v00001103d00000640*
  ID_MODEL_FROM_DATABASE=RocketRAID 640 4 Port SATA-III Controller
 
+pci:v00001103d00000644*
+ ID_MODEL_FROM_DATABASE=RocketRAID 644 4 Port SATA-III Controller (eSATA)
+
 pci:v00001103d00001720*
  ID_MODEL_FROM_DATABASE=RocketRAID 1720 (2x SATA II RAID Controller)
 
@@ -28436,6 +29351,9 @@ pci:v00001103d00001742*
 pci:v00001103d00002210*
  ID_MODEL_FROM_DATABASE=RocketRAID 2210 SATA-II Controller
 
+pci:v00001103d00002210sv000011ABsd000011AB*
+ ID_MODEL_FROM_DATABASE=RocketRAID 2210 SATA-II Controller (88SX6042)
+
 pci:v00001103d00002300*
  ID_MODEL_FROM_DATABASE=RocketRAID 230x 4 Port SATA-II Controller
 
@@ -28506,13 +29424,13 @@ pci:v00001105d00008475*
  ID_MODEL_FROM_DATABASE=EM8475 REALmagic DVD/MPEG-4 A/V Decoder
 
 pci:v00001105d00008475sv00001105sd00000001*
- ID_MODEL_FROM_DATABASE=REALmagic X-Card
+ ID_MODEL_FROM_DATABASE=EM8475 REALmagic DVD/MPEG-4 A/V Decoder (REALmagic X-Card)
 
 pci:v00001105d00008476*
  ID_MODEL_FROM_DATABASE=EM8476 REALmagic DVD/MPEG-4 A/V Decoder
 
 pci:v00001105d00008476sv0000127Dsd00000000*
- ID_MODEL_FROM_DATABASE=CineView II
+ ID_MODEL_FROM_DATABASE=EM8476 REALmagic DVD/MPEG-4 A/V Decoder (CineView II)
 
 pci:v00001105d00008485*
  ID_MODEL_FROM_DATABASE=EM8485 REALmagic DVD/MPEG-4 A/V Decoder
@@ -28557,7 +29475,7 @@ pci:v00001106d00000282*
  ID_MODEL_FROM_DATABASE=K8T800Pro Host Bridge
 
 pci:v00001106d00000282sv00001043sd000080A3*
- ID_MODEL_FROM_DATABASE=A8V Deluxe
+ ID_MODEL_FROM_DATABASE=K8T800Pro Host Bridge (A8V Deluxe)
 
 pci:v00001106d00000290*
  ID_MODEL_FROM_DATABASE=K8M890 Host Bridge
@@ -28572,28 +29490,28 @@ pci:v00001106d00000305*
  ID_MODEL_FROM_DATABASE=VT8363/8365 [KT133/KM133]
 
 pci:v00001106d00000305sv00001019sd00000987*
- ID_MODEL_FROM_DATABASE=K7VZA Mainboard
+ ID_MODEL_FROM_DATABASE=VT8363/8365 [KT133/KM133] (K7VZA Mainboard)
 
 pci:v00001106d00000305sv00001043sd00008033*
- ID_MODEL_FROM_DATABASE=A7V Mainboard
+ ID_MODEL_FROM_DATABASE=VT8363/8365 [KT133/KM133] (A7V Mainboard)
 
 pci:v00001106d00000305sv00001043sd0000803E*
- ID_MODEL_FROM_DATABASE=A7V-E Mainboard
+ ID_MODEL_FROM_DATABASE=VT8363/8365 [KT133/KM133] (A7V-E Mainboard)
 
 pci:v00001106d00000305sv00001043sd00008042*
- ID_MODEL_FROM_DATABASE=A7V133/A7V133-C Mainboard
+ ID_MODEL_FROM_DATABASE=VT8363/8365 [KT133/KM133] (A7V133/A7V133-C Mainboard)
 
 pci:v00001106d00000305sv0000147Bsd0000A401*
- ID_MODEL_FROM_DATABASE=KT7/KT7-RAID/KT7A/KT7A-RAID Mainboard
+ ID_MODEL_FROM_DATABASE=VT8363/8365 [KT133/KM133] (KT7/KT7-RAID/KT7A/KT7A-RAID Mainboard)
 
 pci:v00001106d00000308*
  ID_MODEL_FROM_DATABASE=PT880 Ultra/PT894 Host Bridge
 
 pci:v00001106d00000308sv00001043sd00008199*
- ID_MODEL_FROM_DATABASE=P4V800D-X Mainboard
+ ID_MODEL_FROM_DATABASE=PT880 Ultra/PT894 Host Bridge (P4V800D-X Mainboard)
 
 pci:v00001106d00000308sv00001849sd00000308*
- ID_MODEL_FROM_DATABASE=Motherboard
+ ID_MODEL_FROM_DATABASE=PT880 Ultra/PT894 Host Bridge (Motherboard)
 
 pci:v00001106d00000314*
  ID_MODEL_FROM_DATABASE=CN700/VN800/P4M800CE/Pro Host Bridge
@@ -28620,7 +29538,7 @@ pci:v00001106d00000364*
  ID_MODEL_FROM_DATABASE=CN896/VN896/P4M900 Host Bridge
 
 pci:v00001106d00000364sv00001043sd000081CE*
- ID_MODEL_FROM_DATABASE=P5VD2-VM mothervoard
+ ID_MODEL_FROM_DATABASE=CN896/VN896/P4M900 Host Bridge (P5VD2-VM mothervoard)
 
 pci:v00001106d00000391*
  ID_MODEL_FROM_DATABASE=VT8371 [KX133]
@@ -28635,7 +29553,7 @@ pci:v00001106d00000415*
  ID_MODEL_FROM_DATABASE=VT6415 PATA IDE Host Controller
 
 pci:v00001106d00000415sv00001043sd0000838F*
- ID_MODEL_FROM_DATABASE=M5A88-V EVO
+ ID_MODEL_FROM_DATABASE=VT6415 PATA IDE Host Controller (Motherboard)
 
 pci:v00001106d00000501*
  ID_MODEL_FROM_DATABASE=VT8501 [Apollo MVP4]
@@ -28650,55 +29568,55 @@ pci:v00001106d00000571*
  ID_MODEL_FROM_DATABASE=VT82C586A/B/VT82C686/A/B/VT823x/A/C PIPC Bus Master IDE
 
 pci:v00001106d00000571sv00001019sd00000985*
- ID_MODEL_FROM_DATABASE=P6VXA Motherboard
+ ID_MODEL_FROM_DATABASE=VT82C586A/B/VT82C686/A/B/VT823x/A/C PIPC Bus Master IDE (P6VXA Motherboard)
 
 pci:v00001106d00000571sv00001019sd00000A81*
- ID_MODEL_FROM_DATABASE=L7VTA v1.0 Motherboard (KT400-8235)
+ ID_MODEL_FROM_DATABASE=VT82C586A/B/VT82C686/A/B/VT823x/A/C PIPC Bus Master IDE (L7VTA v1.0 Motherboard (KT400-8235))
 
 pci:v00001106d00000571sv00001043sd00008052*
- ID_MODEL_FROM_DATABASE=VT8233A Bus Master ATA100/66/33 IDE
+ ID_MODEL_FROM_DATABASE=VT82C586A/B/VT82C686/A/B/VT823x/A/C PIPC Bus Master IDE (VT8233A Bus Master ATA100/66/33 IDE)
 
 pci:v00001106d00000571sv00001043sd0000808C*
- ID_MODEL_FROM_DATABASE=A7V8X / A7V333 motherboard
+ ID_MODEL_FROM_DATABASE=VT82C586A/B/VT82C686/A/B/VT823x/A/C PIPC Bus Master IDE (A7V8X / A7V333 motherboard)
 
 pci:v00001106d00000571sv00001043sd000080A1*
- ID_MODEL_FROM_DATABASE=A7V8X-X motherboard rev. 1.01
+ ID_MODEL_FROM_DATABASE=VT82C586A/B/VT82C686/A/B/VT823x/A/C PIPC Bus Master IDE (A7V8X-X motherboard rev. 1.01)
 
 pci:v00001106d00000571sv00001043sd000080ED*
- ID_MODEL_FROM_DATABASE=A7V600/K8V-X/A8V Deluxe motherboard
+ ID_MODEL_FROM_DATABASE=VT82C586A/B/VT82C686/A/B/VT823x/A/C PIPC Bus Master IDE (A7V600/K8V-X/A8V Deluxe motherboard)
 
 pci:v00001106d00000571sv00001106sd00000571*
- ID_MODEL_FROM_DATABASE=VT82C586/B/VT82C686/A/B/VT8233/A/C/VT8235 PIPC Bus Master IDE
+ ID_MODEL_FROM_DATABASE=VT82C586A/B/VT82C686/A/B/VT823x/A/C PIPC Bus Master IDE (VT82C586/B/VT82C686/A/B/VT8233/A/C/VT8235 PIPC Bus Master IDE)
 
 pci:v00001106d00000571sv00001179sd00000001*
- ID_MODEL_FROM_DATABASE=Magnia Z310
+ ID_MODEL_FROM_DATABASE=VT82C586A/B/VT82C686/A/B/VT823x/A/C PIPC Bus Master IDE (Magnia Z310)
 
 pci:v00001106d00000571sv00001297sd0000F641*
- ID_MODEL_FROM_DATABASE=FX41 motherboard
+ ID_MODEL_FROM_DATABASE=VT82C586A/B/VT82C686/A/B/VT823x/A/C PIPC Bus Master IDE (FX41 motherboard)
 
 pci:v00001106d00000571sv00001458sd00005002*
- ID_MODEL_FROM_DATABASE=GA-7VAX Mainboard
+ ID_MODEL_FROM_DATABASE=VT82C586A/B/VT82C686/A/B/VT823x/A/C PIPC Bus Master IDE (GA-7VAX Mainboard)
 
 pci:v00001106d00000571sv00001462sd00005901*
- ID_MODEL_FROM_DATABASE=KT6 Delta-FIS2R (MS-6590)
+ ID_MODEL_FROM_DATABASE=VT82C586A/B/VT82C686/A/B/VT823x/A/C PIPC Bus Master IDE (KT6 Delta-FIS2R (MS-6590))
 
 pci:v00001106d00000571sv00001462sd00007020*
- ID_MODEL_FROM_DATABASE=K8T NEO 2 motherboard
+ ID_MODEL_FROM_DATABASE=VT82C586A/B/VT82C686/A/B/VT823x/A/C PIPC Bus Master IDE (K8T NEO 2 motherboard)
 
 pci:v00001106d00000571sv00001462sd00007094*
- ID_MODEL_FROM_DATABASE=K8T Neo2-F V2.0
+ ID_MODEL_FROM_DATABASE=VT82C586A/B/VT82C686/A/B/VT823x/A/C PIPC Bus Master IDE (K8T Neo2-F V2.0)
 
 pci:v00001106d00000571sv00001462sd00007120*
- ID_MODEL_FROM_DATABASE=KT4AV motherboard
+ ID_MODEL_FROM_DATABASE=VT82C586A/B/VT82C686/A/B/VT823x/A/C PIPC Bus Master IDE (KT4AV motherboard)
 
 pci:v00001106d00000571sv00001462sd00007181*
- ID_MODEL_FROM_DATABASE=K8MM3-V mainboard
+ ID_MODEL_FROM_DATABASE=VT82C586A/B/VT82C686/A/B/VT823x/A/C PIPC Bus Master IDE (K8MM3-V mainboard)
 
 pci:v00001106d00000571sv0000147Bsd00001407*
- ID_MODEL_FROM_DATABASE=KV8-MAX3 motherboard
+ ID_MODEL_FROM_DATABASE=VT82C586A/B/VT82C686/A/B/VT823x/A/C PIPC Bus Master IDE (KV8-MAX3 motherboard)
 
 pci:v00001106d00000571sv00001849sd00000571*
- ID_MODEL_FROM_DATABASE=K7VT series Motherboards
+ ID_MODEL_FROM_DATABASE=VT82C586A/B/VT82C686/A/B/VT823x/A/C PIPC Bus Master IDE (K7VT series Motherboards)
 
 pci:v00001106d00000576*
  ID_MODEL_FROM_DATABASE=VT82C576 3V [Apollo Master]
@@ -28707,7 +29625,7 @@ pci:v00001106d00000581*
  ID_MODEL_FROM_DATABASE=CX700/VX700 RAID Controller
 
 pci:v00001106d00000581sv00001106sd00000581*
- ID_MODEL_FROM_DATABASE=Wrong IDE ID
+ ID_MODEL_FROM_DATABASE=CX700/VX700 RAID Controller (Wrong IDE ID)
 
 pci:v00001106d00000585*
  ID_MODEL_FROM_DATABASE=VT82C585VP [Apollo VP1/VPX]
@@ -28716,7 +29634,7 @@ pci:v00001106d00000586*
  ID_MODEL_FROM_DATABASE=VT82C586/A/B PCI-to-ISA [Apollo VP]
 
 pci:v00001106d00000586sv00001106sd00000000*
- ID_MODEL_FROM_DATABASE=MVP3 ISA Bridge
+ ID_MODEL_FROM_DATABASE=VT82C586/A/B PCI-to-ISA [Apollo VP] (MVP3 ISA Bridge)
 
 pci:v00001106d00000591*
  ID_MODEL_FROM_DATABASE=VT8237A SATA 2-Port Controller
@@ -28728,10 +29646,10 @@ pci:v00001106d00000596*
  ID_MODEL_FROM_DATABASE=VT82C596 ISA [Mobile South]
 
 pci:v00001106d00000596sv00001106sd00000000*
- ID_MODEL_FROM_DATABASE=VT82C596/A/B PCI to ISA Bridge
+ ID_MODEL_FROM_DATABASE=VT82C596 ISA [Mobile South] (VT82C596/A/B PCI to ISA Bridge)
 
 pci:v00001106d00000596sv00001458sd00000596*
- ID_MODEL_FROM_DATABASE=VT82C596/A/B PCI to ISA Bridge
+ ID_MODEL_FROM_DATABASE=VT82C596 ISA [Mobile South] (VT82C596/A/B PCI to ISA Bridge)
 
 pci:v00001106d00000597*
  ID_MODEL_FROM_DATABASE=VT82C597 [Apollo VP3]
@@ -28746,10 +29664,10 @@ pci:v00001106d00000605*
  ID_MODEL_FROM_DATABASE=VT8605 [ProSavage PM133]
 
 pci:v00001106d00000605sv0000103Csd00001254*
- ID_MODEL_FROM_DATABASE=D9840-60001 [Brio BA410 Motherboard]
+ ID_MODEL_FROM_DATABASE=VT8605 [ProSavage PM133] (D9840-60001 [Brio BA410 Motherboard])
 
 pci:v00001106d00000605sv00001043sd0000802C*
- ID_MODEL_FROM_DATABASE=CUV4X mainboard
+ ID_MODEL_FROM_DATABASE=VT8605 [ProSavage PM133] (CUV4X mainboard)
 
 pci:v00001106d00000680*
  ID_MODEL_FROM_DATABASE=VT82C680 [Apollo P6]
@@ -28758,49 +29676,49 @@ pci:v00001106d00000686*
  ID_MODEL_FROM_DATABASE=VT82C686 [Apollo Super South]
 
 pci:v00001106d00000686sv00001019sd00000985*
- ID_MODEL_FROM_DATABASE=P6VXA Motherboard
+ ID_MODEL_FROM_DATABASE=VT82C686 [Apollo Super South] (P6VXA Motherboard)
 
 pci:v00001106d00000686sv0000103Csd00001256*
- ID_MODEL_FROM_DATABASE=D9840-60001 [Brio BA410 Motherboard]
+ ID_MODEL_FROM_DATABASE=VT82C686 [Apollo Super South] (D9840-60001 [Brio BA410 Motherboard])
 
 pci:v00001106d00000686sv00001043sd0000802C*
- ID_MODEL_FROM_DATABASE=CUV4X mainboard
+ ID_MODEL_FROM_DATABASE=VT82C686 [Apollo Super South] (CUV4X mainboard)
 
 pci:v00001106d00000686sv00001043sd00008033*
- ID_MODEL_FROM_DATABASE=A7V Mainboard
+ ID_MODEL_FROM_DATABASE=VT82C686 [Apollo Super South] (A7V Mainboard)
 
 pci:v00001106d00000686sv00001043sd0000803E*
- ID_MODEL_FROM_DATABASE=A7V-E Mainboard
+ ID_MODEL_FROM_DATABASE=VT82C686 [Apollo Super South] (A7V-E Mainboard)
 
 pci:v00001106d00000686sv00001043sd00008040*
- ID_MODEL_FROM_DATABASE=A7M266 Mainboard
+ ID_MODEL_FROM_DATABASE=VT82C686 [Apollo Super South] (A7M266 Mainboard)
 
 pci:v00001106d00000686sv00001043sd00008042*
- ID_MODEL_FROM_DATABASE=A7V133/A7V133-C Mainboard
+ ID_MODEL_FROM_DATABASE=VT82C686 [Apollo Super South] (A7V133/A7V133-C Mainboard)
 
 pci:v00001106d00000686sv00001106sd00000000*
- ID_MODEL_FROM_DATABASE=VT82C686/A PCI to ISA Bridge
+ ID_MODEL_FROM_DATABASE=VT82C686 [Apollo Super South] (VT82C686/A PCI to ISA Bridge)
 
 pci:v00001106d00000686sv00001106sd00000686*
- ID_MODEL_FROM_DATABASE=VT82C686/A PCI to ISA Bridge
+ ID_MODEL_FROM_DATABASE=VT82C686 [Apollo Super South] (VT82C686/A PCI to ISA Bridge)
 
 pci:v00001106d00000686sv00001179sd00000001*
- ID_MODEL_FROM_DATABASE=Magnia Z310
+ ID_MODEL_FROM_DATABASE=VT82C686 [Apollo Super South] (Magnia Z310)
 
 pci:v00001106d00000686sv0000147Bsd0000A702*
- ID_MODEL_FROM_DATABASE=KG7-Lite Mainboard
+ ID_MODEL_FROM_DATABASE=VT82C686 [Apollo Super South] (KG7-Lite Mainboard)
 
 pci:v00001106d00000691*
  ID_MODEL_FROM_DATABASE=VT82C693A/694x [Apollo PRO133x]
 
 pci:v00001106d00000691sv00001019sd00000985*
- ID_MODEL_FROM_DATABASE=P6VXA Motherboard
+ ID_MODEL_FROM_DATABASE=VT82C693A/694x [Apollo PRO133x] (P6VXA Motherboard)
 
 pci:v00001106d00000691sv00001179sd00000001*
- ID_MODEL_FROM_DATABASE=Magnia Z310
+ ID_MODEL_FROM_DATABASE=VT82C693A/694x [Apollo PRO133x] (Magnia Z310)
 
 pci:v00001106d00000691sv00001458sd00000691*
- ID_MODEL_FROM_DATABASE=VT82C691 Apollo Pro System Controller
+ ID_MODEL_FROM_DATABASE=VT82C693A/694x [Apollo PRO133x] (VT82C691 Apollo Pro System Controller)
 
 pci:v00001106d00000693*
  ID_MODEL_FROM_DATABASE=VT82C693 [Apollo Pro Plus]
@@ -28980,58 +29898,61 @@ pci:v00001106d00003038*
  ID_MODEL_FROM_DATABASE=VT82xxxxx UHCI USB 1.1 Controller
 
 pci:v00001106d00003038sv00000925sd00001234*
- ID_MODEL_FROM_DATABASE=VA-502 Mainboard
+ ID_MODEL_FROM_DATABASE=VT82xxxxx UHCI USB 1.1 Controller (VA-502 Mainboard)
 
 pci:v00001106d00003038sv00001019sd00000985*
- ID_MODEL_FROM_DATABASE=P6VXA Motherboard
+ ID_MODEL_FROM_DATABASE=VT82xxxxx UHCI USB 1.1 Controller (P6VXA Motherboard)
 
 pci:v00001106d00003038sv00001019sd00000A81*
- ID_MODEL_FROM_DATABASE=L7VTA v1.0 Motherboard (KT400-8235)
+ ID_MODEL_FROM_DATABASE=VT82xxxxx UHCI USB 1.1 Controller (L7VTA v1.0 Motherboard (KT400-8235))
 
 pci:v00001106d00003038sv00001043sd00008080*
- ID_MODEL_FROM_DATABASE=A7V333 motherboard
+ ID_MODEL_FROM_DATABASE=VT82xxxxx UHCI USB 1.1 Controller (A7V333 motherboard)
 
 pci:v00001106d00003038sv00001043sd0000808C*
- ID_MODEL_FROM_DATABASE=VT6202 USB2.0 4 port controller
+ ID_MODEL_FROM_DATABASE=VT82xxxxx UHCI USB 1.1 Controller (VT6202 USB2.0 4 port controller)
 
 pci:v00001106d00003038sv00001043sd000080A1*
- ID_MODEL_FROM_DATABASE=A7V8X-X motherboard
+ ID_MODEL_FROM_DATABASE=VT82xxxxx UHCI USB 1.1 Controller (A7V8X-X motherboard)
 
 pci:v00001106d00003038sv00001043sd000080ED*
- ID_MODEL_FROM_DATABASE=A7V600/K8V-X/A8V Deluxe motherboard
+ ID_MODEL_FROM_DATABASE=VT82xxxxx UHCI USB 1.1 Controller (A7V600/K8V-X/A8V Deluxe motherboard)
 
 pci:v00001106d00003038sv00001179sd00000001*
- ID_MODEL_FROM_DATABASE=Magnia Z310
+ ID_MODEL_FROM_DATABASE=VT82xxxxx UHCI USB 1.1 Controller (Magnia Z310)
 
 pci:v00001106d00003038sv00001458sd00005004*
- ID_MODEL_FROM_DATABASE=GA-7VAX Mainboard
+ ID_MODEL_FROM_DATABASE=VT82xxxxx UHCI USB 1.1 Controller (GA-7VAX Mainboard)
 
 pci:v00001106d00003038sv00001462sd00005901*
- ID_MODEL_FROM_DATABASE=KT6 Delta-FIS2R (MS-6590)
+ ID_MODEL_FROM_DATABASE=VT82xxxxx UHCI USB 1.1 Controller (KT6 Delta-FIS2R (MS-6590))
 
 pci:v00001106d00003038sv00001462sd00007020*
- ID_MODEL_FROM_DATABASE=K8T NEO 2 motherboard
+ ID_MODEL_FROM_DATABASE=VT82xxxxx UHCI USB 1.1 Controller (K8T NEO 2 motherboard)
 
 pci:v00001106d00003038sv00001462sd00007094*
- ID_MODEL_FROM_DATABASE=K8T Neo2-F V2.0
+ ID_MODEL_FROM_DATABASE=VT82xxxxx UHCI USB 1.1 Controller (K8T Neo2-F V2.0)
 
 pci:v00001106d00003038sv00001462sd00007120*
- ID_MODEL_FROM_DATABASE=KT4AV motherboard
+ ID_MODEL_FROM_DATABASE=VT82xxxxx UHCI USB 1.1 Controller (KT4AV motherboard)
 
 pci:v00001106d00003038sv00001462sd00007181*
- ID_MODEL_FROM_DATABASE=K8MM3-V mainboard
+ ID_MODEL_FROM_DATABASE=VT82xxxxx UHCI USB 1.1 Controller (K8MM3-V mainboard)
 
 pci:v00001106d00003038sv0000147Bsd00001407*
- ID_MODEL_FROM_DATABASE=KV8-MAX3 motherboard
+ ID_MODEL_FROM_DATABASE=VT82xxxxx UHCI USB 1.1 Controller (KV8-MAX3 motherboard)
 
 pci:v00001106d00003038sv0000182Dsd0000201D*
- ID_MODEL_FROM_DATABASE=CN-029 USB2.0 4 port PCI Card
+ ID_MODEL_FROM_DATABASE=VT82xxxxx UHCI USB 1.1 Controller (CN-029 USB2.0 4 port PCI Card)
 
 pci:v00001106d00003038sv00001849sd00003038*
- ID_MODEL_FROM_DATABASE=K7VT series Motherboards
+ ID_MODEL_FROM_DATABASE=VT82xxxxx UHCI USB 1.1 Controller (K7VT series Motherboards)
 
 pci:v00001106d00003038sv000019DAsd0000A179*
- ID_MODEL_FROM_DATABASE=ZBOX nano VD01
+ ID_MODEL_FROM_DATABASE=VT82xxxxx UHCI USB 1.1 Controller (ZBOX nano VD01)
+
+pci:v00001106d00003038sv00001AF4sd00001100*
+ ID_MODEL_FROM_DATABASE=VT82xxxxx UHCI USB 1.1 Controller (QEMU Virtual Machine)
 
 pci:v00001106d00003040*
  ID_MODEL_FROM_DATABASE=VT82C586B ACPI
@@ -29040,52 +29961,52 @@ pci:v00001106d00003043*
  ID_MODEL_FROM_DATABASE=VT86C100A [Rhine]
 
 pci:v00001106d00003043sv000010BDsd00000000*
- ID_MODEL_FROM_DATABASE=VT86C100A Fast Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=VT86C100A [Rhine] (VT86C100A Fast Ethernet Adapter)
 
 pci:v00001106d00003043sv00001106sd00000100*
- ID_MODEL_FROM_DATABASE=VT86C100A Fast Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=VT86C100A [Rhine] (VT86C100A Fast Ethernet Adapter)
 
 pci:v00001106d00003043sv00001186sd00001400*
- ID_MODEL_FROM_DATABASE=DFE-530TX rev A
+ ID_MODEL_FROM_DATABASE=VT86C100A [Rhine] (DFE-530TX rev A)
 
 pci:v00001106d00003044*
  ID_MODEL_FROM_DATABASE=VT6306/7/8 [Fire II(M)] IEEE 1394 OHCI Controller
 
 pci:v00001106d00003044sv00000010sd00000001*
- ID_MODEL_FROM_DATABASE=IEEE 1394 4port DCST 1394-3+1B
+ ID_MODEL_FROM_DATABASE=VT6306/7/8 [Fire II(M)] IEEE 1394 OHCI Controller (IEEE 1394 4port DCST 1394-3+1B)
 
 pci:v00001106d00003044sv00001025sd0000005A*
- ID_MODEL_FROM_DATABASE=TravelMate 290
+ ID_MODEL_FROM_DATABASE=VT6306/7/8 [Fire II(M)] IEEE 1394 OHCI Controller (TravelMate 290)
 
 pci:v00001106d00003044sv0000103Csd00002A20*
- ID_MODEL_FROM_DATABASE=Pavilion t3030.de Desktop PC
+ ID_MODEL_FROM_DATABASE=VT6306/7/8 [Fire II(M)] IEEE 1394 OHCI Controller (Pavilion t3030.de Desktop PC)
 
 pci:v00001106d00003044sv0000103Csd00002A3B*
- ID_MODEL_FROM_DATABASE=Media Center PC m7590n
+ ID_MODEL_FROM_DATABASE=VT6306/7/8 [Fire II(M)] IEEE 1394 OHCI Controller (Media Center PC m7590n)
 
 pci:v00001106d00003044sv00001043sd0000808A*
- ID_MODEL_FROM_DATABASE=A8V/A8N/P4P800 series motherboard
+ ID_MODEL_FROM_DATABASE=VT6306/7/8 [Fire II(M)] IEEE 1394 OHCI Controller (A8V/A8N/P4P800 series motherboard)
 
 pci:v00001106d00003044sv00001043sd000081FE*
- ID_MODEL_FROM_DATABASE=Motherboard
+ ID_MODEL_FROM_DATABASE=VT6306/7/8 [Fire II(M)] IEEE 1394 OHCI Controller (Motherboard)
 
 pci:v00001106d00003044sv00001458sd00001000*
- ID_MODEL_FROM_DATABASE=GA-7VT600-1394 Motherboard
+ ID_MODEL_FROM_DATABASE=VT6306/7/8 [Fire II(M)] IEEE 1394 OHCI Controller (GA-7VT600-1394 Motherboard)
 
 pci:v00001106d00003044sv00001462sd0000207D*
- ID_MODEL_FROM_DATABASE=K8NGM2 series motherboard
+ ID_MODEL_FROM_DATABASE=VT6306/7/8 [Fire II(M)] IEEE 1394 OHCI Controller (K8NGM2 series motherboard)
 
 pci:v00001106d00003044sv00001462sd0000217D*
- ID_MODEL_FROM_DATABASE=Aspire L250
+ ID_MODEL_FROM_DATABASE=VT6306/7/8 [Fire II(M)] IEEE 1394 OHCI Controller (Aspire L250)
 
 pci:v00001106d00003044sv00001462sd0000590D*
- ID_MODEL_FROM_DATABASE=KT6 Delta-FIS2R (MS-6590)
+ ID_MODEL_FROM_DATABASE=VT6306/7/8 [Fire II(M)] IEEE 1394 OHCI Controller (KT6 Delta-FIS2R (MS-6590))
 
 pci:v00001106d00003044sv00001462sd0000702D*
- ID_MODEL_FROM_DATABASE=K8T NEO 2 motherboard
+ ID_MODEL_FROM_DATABASE=VT6306/7/8 [Fire II(M)] IEEE 1394 OHCI Controller (K8T NEO 2 motherboard)
 
 pci:v00001106d00003044sv00001462sd0000971D*
- ID_MODEL_FROM_DATABASE=MS-6917
+ ID_MODEL_FROM_DATABASE=VT6306/7/8 [Fire II(M)] IEEE 1394 OHCI Controller (MS-6917)
 
 pci:v00001106d00003050*
  ID_MODEL_FROM_DATABASE=VT82C596 Power Management
@@ -29100,205 +30021,205 @@ pci:v00001106d00003057*
  ID_MODEL_FROM_DATABASE=VT82C686 [Apollo Super ACPI]
 
 pci:v00001106d00003057sv00001019sd00000985*
- ID_MODEL_FROM_DATABASE=P6VXA Motherboard
+ ID_MODEL_FROM_DATABASE=VT82C686 [Apollo Super ACPI] (P6VXA Motherboard)
 
 pci:v00001106d00003057sv00001019sd00000987*
- ID_MODEL_FROM_DATABASE=K7VZA Motherboard
+ ID_MODEL_FROM_DATABASE=VT82C686 [Apollo Super ACPI] (K7VZA Motherboard)
 
 pci:v00001106d00003057sv00001043sd00008033*
- ID_MODEL_FROM_DATABASE=A7V Mainboard
+ ID_MODEL_FROM_DATABASE=VT82C686 [Apollo Super ACPI] (A7V Mainboard)
 
 pci:v00001106d00003057sv00001043sd0000803E*
- ID_MODEL_FROM_DATABASE=A7V-E Mainboard
+ ID_MODEL_FROM_DATABASE=VT82C686 [Apollo Super ACPI] (A7V-E Mainboard)
 
 pci:v00001106d00003057sv00001043sd00008040*
- ID_MODEL_FROM_DATABASE=A7M266 Mainboard
+ ID_MODEL_FROM_DATABASE=VT82C686 [Apollo Super ACPI] (A7M266 Mainboard)
 
 pci:v00001106d00003057sv00001043sd00008042*
- ID_MODEL_FROM_DATABASE=A7V133/A7V133-C Mainboard
+ ID_MODEL_FROM_DATABASE=VT82C686 [Apollo Super ACPI] (A7V133/A7V133-C Mainboard)
 
 pci:v00001106d00003057sv00001179sd00000001*
- ID_MODEL_FROM_DATABASE=Magnia Z310
+ ID_MODEL_FROM_DATABASE=VT82C686 [Apollo Super ACPI] (Magnia Z310)
 
 pci:v00001106d00003058*
  ID_MODEL_FROM_DATABASE=VT82C686 AC97 Audio Controller
 
 pci:v00001106d00003058sv00000E11sd00000097*
- ID_MODEL_FROM_DATABASE=SoundMax Digital Integrated Audio
+ ID_MODEL_FROM_DATABASE=VT82C686 AC97 Audio Controller (SoundMax Digital Integrated Audio)
 
 pci:v00001106d00003058sv00000E11sd0000B194*
- ID_MODEL_FROM_DATABASE=Soundmax integrated digital audio
+ ID_MODEL_FROM_DATABASE=VT82C686 AC97 Audio Controller (Soundmax integrated digital audio)
 
 pci:v00001106d00003058sv00001019sd00000985*
- ID_MODEL_FROM_DATABASE=P6VXA Motherboard
+ ID_MODEL_FROM_DATABASE=VT82C686 AC97 Audio Controller (P6VXA Motherboard)
 
 pci:v00001106d00003058sv00001019sd00000987*
- ID_MODEL_FROM_DATABASE=K7VZA Motherboard
+ ID_MODEL_FROM_DATABASE=VT82C686 AC97 Audio Controller (K7VZA Motherboard)
 
 pci:v00001106d00003058sv0000103Csd00001251*
- ID_MODEL_FROM_DATABASE=D9840-60001 [Brio BA410 Motherboard]
+ ID_MODEL_FROM_DATABASE=VT82C686 AC97 Audio Controller (D9840-60001 [Brio BA410 Motherboard])
 
 pci:v00001106d00003058sv00001043sd00001106*
- ID_MODEL_FROM_DATABASE=A7V133/A7V133-C Mainboard
+ ID_MODEL_FROM_DATABASE=VT82C686 AC97 Audio Controller (A7V133/A7V133-C Mainboard)
 
 pci:v00001106d00003058sv00001106sd00004511*
- ID_MODEL_FROM_DATABASE=Onboard Audio on EP7KXA
+ ID_MODEL_FROM_DATABASE=VT82C686 AC97 Audio Controller (Onboard Audio on EP7KXA)
 
 pci:v00001106d00003058sv00001106sd0000AA03*
- ID_MODEL_FROM_DATABASE=VT1612A AC'97 Audio Controller
+ ID_MODEL_FROM_DATABASE=VT82C686 AC97 Audio Controller (VT1612A AC'97 Audio Controller)
 
 pci:v00001106d00003058sv000011D4sd00005348*
- ID_MODEL_FROM_DATABASE=AD1881A audio
+ ID_MODEL_FROM_DATABASE=VT82C686 AC97 Audio Controller (AD1881A audio)
 
 pci:v00001106d00003058sv00001458sd00007600*
- ID_MODEL_FROM_DATABASE=Onboard Audio
+ ID_MODEL_FROM_DATABASE=VT82C686 AC97 Audio Controller (Onboard Audio)
 
 pci:v00001106d00003058sv00001462sd00003091*
- ID_MODEL_FROM_DATABASE=MS-6309 Onboard Audio
+ ID_MODEL_FROM_DATABASE=VT82C686 AC97 Audio Controller (MS-6309 Onboard Audio)
 
 pci:v00001106d00003058sv00001462sd00003092*
- ID_MODEL_FROM_DATABASE=MS-6309 v2.x Mainboard (VIA VT1611A codec)
+ ID_MODEL_FROM_DATABASE=VT82C686 AC97 Audio Controller (MS-6309 v2.x Mainboard (VIA VT1611A codec))
 
 pci:v00001106d00003058sv00001462sd00003300*
- ID_MODEL_FROM_DATABASE=MS-6330 Onboard Audio
+ ID_MODEL_FROM_DATABASE=VT82C686 AC97 Audio Controller (MS-6330 Onboard Audio)
 
 pci:v00001106d00003058sv000015DDsd00007609*
- ID_MODEL_FROM_DATABASE=Onboard Audio
+ ID_MODEL_FROM_DATABASE=VT82C686 AC97 Audio Controller (Onboard Audio)
 
 pci:v00001106d00003059*
  ID_MODEL_FROM_DATABASE=VT8233/A/8235/8237 AC97 Audio Controller
 
 pci:v00001106d00003059sv00001019sd00000A81*
- ID_MODEL_FROM_DATABASE=L7VTA v1.0 Motherboard (KT400-8235)
+ ID_MODEL_FROM_DATABASE=VT8233/A/8235/8237 AC97 Audio Controller (L7VTA v1.0 Motherboard (KT400-8235))
 
 pci:v00001106d00003059sv00001019sd00001877*
- ID_MODEL_FROM_DATABASE=K8M800-M2 (V2.0) onboard audio
+ ID_MODEL_FROM_DATABASE=VT8233/A/8235/8237 AC97 Audio Controller (K8M800-M2 (V2.0) onboard audio)
 
 pci:v00001106d00003059sv00001043sd00008095*
- ID_MODEL_FROM_DATABASE=A7V8X Motherboard (Realtek ALC650 codec)
+ ID_MODEL_FROM_DATABASE=VT8233/A/8235/8237 AC97 Audio Controller (A7V8X Motherboard (Realtek ALC650 codec))
 
 pci:v00001106d00003059sv00001043sd000080A1*
- ID_MODEL_FROM_DATABASE=A7V8X-X Motherboard
+ ID_MODEL_FROM_DATABASE=VT8233/A/8235/8237 AC97 Audio Controller (A7V8X-X Motherboard)
 
 pci:v00001106d00003059sv00001043sd000080B0*
- ID_MODEL_FROM_DATABASE=A7V600/K8V-X/K8V Deluxe motherboard (ADI AD1980 codec [SoundMAX])
+ ID_MODEL_FROM_DATABASE=VT8233/A/8235/8237 AC97 Audio Controller (A7V600/K8V-X/K8V Deluxe motherboard (ADI AD1980 codec [SoundMAX]))
 
 pci:v00001106d00003059sv00001043sd0000810D*
- ID_MODEL_FROM_DATABASE=Asus P5VD1-X (AD1888 codec [SoundMax])
+ ID_MODEL_FROM_DATABASE=VT8233/A/8235/8237 AC97 Audio Controller (Asus P5VD1-X (AD1888 codec [SoundMax]))
 
 pci:v00001106d00003059sv00001043sd0000812A*
- ID_MODEL_FROM_DATABASE=A8V Deluxe motherboard (Realtek ALC850 codec)
+ ID_MODEL_FROM_DATABASE=VT8233/A/8235/8237 AC97 Audio Controller (A8V Deluxe motherboard (Realtek ALC850 codec))
 
 pci:v00001106d00003059sv000010ECsd00008168*
- ID_MODEL_FROM_DATABASE=High Definition Audio
+ ID_MODEL_FROM_DATABASE=VT8233/A/8235/8237 AC97 Audio Controller (High Definition Audio)
 
 pci:v00001106d00003059sv00001106sd00003059*
- ID_MODEL_FROM_DATABASE=L7VMM2 Motherboard
+ ID_MODEL_FROM_DATABASE=VT8233/A/8235/8237 AC97 Audio Controller (L7VMM2 Motherboard)
 
 pci:v00001106d00003059sv00001106sd00004161*
- ID_MODEL_FROM_DATABASE=K7VT2 motherboard
+ ID_MODEL_FROM_DATABASE=VT8233/A/8235/8237 AC97 Audio Controller (K7VT2 motherboard)
 
 pci:v00001106d00003059sv00001106sd00004170*
- ID_MODEL_FROM_DATABASE=PCPartner P4M800-8237R Motherboard
+ ID_MODEL_FROM_DATABASE=VT8233/A/8235/8237 AC97 Audio Controller (PCPartner P4M800-8237R Motherboard)
 
 pci:v00001106d00003059sv00001106sd00004552*
- ID_MODEL_FROM_DATABASE=Soyo KT-600 Dragon Plus (Realtek ALC 650)
+ ID_MODEL_FROM_DATABASE=VT8233/A/8235/8237 AC97 Audio Controller (Soyo KT-600 Dragon Plus (Realtek ALC 650))
 
 pci:v00001106d00003059sv00001297sd0000C160*
- ID_MODEL_FROM_DATABASE=FX41 motherboard (Realtek ALC650 codec)
+ ID_MODEL_FROM_DATABASE=VT8233/A/8235/8237 AC97 Audio Controller (FX41 motherboard (Realtek ALC650 codec))
 
 pci:v00001106d00003059sv00001413sd0000147B*
- ID_MODEL_FROM_DATABASE=KV8 Pro motherboard onboard audio
+ ID_MODEL_FROM_DATABASE=VT8233/A/8235/8237 AC97 Audio Controller (KV8 Pro motherboard onboard audio)
 
 pci:v00001106d00003059sv00001458sd0000A002*
- ID_MODEL_FROM_DATABASE=GA-7VAX Onboard Audio (Realtek ALC650)
+ ID_MODEL_FROM_DATABASE=VT8233/A/8235/8237 AC97 Audio Controller (GA-7VAX Onboard Audio (Realtek ALC650))
 
 pci:v00001106d00003059sv00001462sd00000080*
- ID_MODEL_FROM_DATABASE=K8T NEO 2 motherboard
+ ID_MODEL_FROM_DATABASE=VT8233/A/8235/8237 AC97 Audio Controller (K8T NEO 2 motherboard)
 
 pci:v00001106d00003059sv00001462sd00003800*
- ID_MODEL_FROM_DATABASE=KT266 onboard audio
+ ID_MODEL_FROM_DATABASE=VT8233/A/8235/8237 AC97 Audio Controller (KT266 onboard audio)
 
 pci:v00001106d00003059sv00001462sd00005901*
- ID_MODEL_FROM_DATABASE=KT6 Delta-FIS2R (MS-6590)
+ ID_MODEL_FROM_DATABASE=VT8233/A/8235/8237 AC97 Audio Controller (KT6 Delta-FIS2R (MS-6590))
 
 pci:v00001106d00003059sv00001462sd00007181*
- ID_MODEL_FROM_DATABASE=K8MM3-V mainboard
+ ID_MODEL_FROM_DATABASE=VT8233/A/8235/8237 AC97 Audio Controller (K8MM3-V mainboard)
 
 pci:v00001106d00003059sv0000147Bsd00001407*
- ID_MODEL_FROM_DATABASE=KV8-MAX3 motherboard
+ ID_MODEL_FROM_DATABASE=VT8233/A/8235/8237 AC97 Audio Controller (KV8-MAX3 motherboard)
 
 pci:v00001106d00003059sv00001695sd0000300C*
- ID_MODEL_FROM_DATABASE=EP-8KRA2+ Mainboard
+ ID_MODEL_FROM_DATABASE=VT8233/A/8235/8237 AC97 Audio Controller (EP-8KRA2+ Mainboard)
 
 pci:v00001106d00003059sv00001849sd00000850*
- ID_MODEL_FROM_DATABASE=ASRock 775Dual-880 Pro onboard audio (Realtek ALC850)
+ ID_MODEL_FROM_DATABASE=VT8233/A/8235/8237 AC97 Audio Controller (ASRock 775Dual-880 Pro onboard audio (Realtek ALC850))
 
 pci:v00001106d00003059sv00001849sd00009739*
- ID_MODEL_FROM_DATABASE=P4VT8 Mainboard (C-Media CMI9739A codec)
+ ID_MODEL_FROM_DATABASE=VT8233/A/8235/8237 AC97 Audio Controller (P4VT8 Mainboard (C-Media CMI9739A codec))
 
 pci:v00001106d00003059sv00001849sd00009761*
- ID_MODEL_FROM_DATABASE=K7VT series Motherboards
+ ID_MODEL_FROM_DATABASE=VT8233/A/8235/8237 AC97 Audio Controller (K7VT series Motherboards)
 
 pci:v00001106d00003059sv00004005sd00004710*
- ID_MODEL_FROM_DATABASE=MSI K7T266 Pro2-RU (MSI-6380 v2) onboard audio (Realtek/ALC 200/200P)
+ ID_MODEL_FROM_DATABASE=VT8233/A/8235/8237 AC97 Audio Controller (MSI K7T266 Pro2-RU (MSI-6380 v2) onboard audio (Realtek/ALC 200/200P))
 
 pci:v00001106d00003059sv0000A0A0sd000001B6*
- ID_MODEL_FROM_DATABASE=AK77-8XN onboard audio
+ ID_MODEL_FROM_DATABASE=VT8233/A/8235/8237 AC97 Audio Controller (AK77-8XN onboard audio)
 
 pci:v00001106d00003059sv0000A0A0sd00000342*
- ID_MODEL_FROM_DATABASE=AK86-L motherboard
+ ID_MODEL_FROM_DATABASE=VT8233/A/8235/8237 AC97 Audio Controller (AK86-L motherboard)
 
 pci:v00001106d00003065*
  ID_MODEL_FROM_DATABASE=VT6102 [Rhine-II]
 
 pci:v00001106d00003065sv00001043sd000080A1*
- ID_MODEL_FROM_DATABASE=A7V8X-X Motherboard
+ ID_MODEL_FROM_DATABASE=VT6102 [Rhine-II] (A7V8X-X Motherboard)
 
 pci:v00001106d00003065sv00001043sd000080ED*
- ID_MODEL_FROM_DATABASE=A7V600-X Motherboard
+ ID_MODEL_FROM_DATABASE=VT6102 [Rhine-II] (A7V600-X Motherboard)
 
 pci:v00001106d00003065sv00001106sd00000102*
- ID_MODEL_FROM_DATABASE=VT6102 [Rhine II] Embeded Ethernet Controller on VT8235
+ ID_MODEL_FROM_DATABASE=VT6102 [Rhine-II] (VT6102 [Rhine II] Embeded Ethernet Controller on VT8235)
 
 pci:v00001106d00003065sv00001186sd00001400*
- ID_MODEL_FROM_DATABASE=DFE-530TX rev A
+ ID_MODEL_FROM_DATABASE=VT6102 [Rhine-II] (DFE-530TX rev A)
 
 pci:v00001106d00003065sv00001186sd00001401*
- ID_MODEL_FROM_DATABASE=DFE-530TX rev B
+ ID_MODEL_FROM_DATABASE=VT6102 [Rhine-II] (DFE-530TX rev B)
 
 pci:v00001106d00003065sv000013B9sd00001421*
- ID_MODEL_FROM_DATABASE=LD-10/100AL PCI Fast Ethernet Adapter (rev.B)
+ ID_MODEL_FROM_DATABASE=VT6102 [Rhine-II] (LD-10/100AL PCI Fast Ethernet Adapter (rev.B))
 
 pci:v00001106d00003065sv00001462sd00007061*
- ID_MODEL_FROM_DATABASE=MS-7061
+ ID_MODEL_FROM_DATABASE=VT6102 [Rhine-II] (MS-7061)
 
 pci:v00001106d00003065sv00001462sd00007181*
- ID_MODEL_FROM_DATABASE=K8MM3-V mainboard
+ ID_MODEL_FROM_DATABASE=VT6102 [Rhine-II] (K8MM3-V mainboard)
 
 pci:v00001106d00003065sv0000147Bsd00001C09*
- ID_MODEL_FROM_DATABASE=NV7 Motherboard
+ ID_MODEL_FROM_DATABASE=VT6102 [Rhine-II] (NV7 Motherboard)
 
 pci:v00001106d00003065sv00001695sd00003005*
- ID_MODEL_FROM_DATABASE=VT6103
+ ID_MODEL_FROM_DATABASE=VT6102 [Rhine-II] (VT6103)
 
 pci:v00001106d00003065sv00001695sd0000300C*
- ID_MODEL_FROM_DATABASE=Realtek ALC655 sound chip
+ ID_MODEL_FROM_DATABASE=VT6102 [Rhine-II] (Realtek ALC655 sound chip)
 
 pci:v00001106d00003065sv00001849sd00003065*
- ID_MODEL_FROM_DATABASE=K7VT series Motherboards
+ ID_MODEL_FROM_DATABASE=VT6102 [Rhine-II] (K7VT series Motherboards)
 
 pci:v00001106d00003068*
  ID_MODEL_FROM_DATABASE=AC'97 Modem Controller
 
 pci:v00001106d00003068sv00001462sd0000309E*
- ID_MODEL_FROM_DATABASE=MS-6309 Saturn Motherboard
+ ID_MODEL_FROM_DATABASE=AC'97 Modem Controller (MS-6309 Saturn Motherboard)
 
 pci:v00001106d00003074*
  ID_MODEL_FROM_DATABASE=VT8233 PCI to ISA Bridge
 
 pci:v00001106d00003074sv00001043sd00008052*
- ID_MODEL_FROM_DATABASE=VT8233A
+ ID_MODEL_FROM_DATABASE=VT8233 PCI to ISA Bridge (VT8233A)
 
 pci:v00001106d00003091*
  ID_MODEL_FROM_DATABASE=VT8633 [Apollo Pro266]
@@ -29307,13 +30228,13 @@ pci:v00001106d00003099*
  ID_MODEL_FROM_DATABASE=VT8366/A/7 [Apollo KT266/A/333]
 
 pci:v00001106d00003099sv00001043sd00008064*
- ID_MODEL_FROM_DATABASE=A7V266-E Mainboard
+ ID_MODEL_FROM_DATABASE=VT8366/A/7 [Apollo KT266/A/333] (A7V266-E Mainboard)
 
 pci:v00001106d00003099sv00001043sd0000807F*
- ID_MODEL_FROM_DATABASE=A7V333 Mainboard
+ ID_MODEL_FROM_DATABASE=VT8366/A/7 [Apollo KT266/A/333] (A7V333 Mainboard)
 
 pci:v00001106d00003099sv00001849sd00003099*
- ID_MODEL_FROM_DATABASE=K7VT2 motherboard
+ ID_MODEL_FROM_DATABASE=VT8366/A/7 [Apollo KT266/A/333] (K7VT2 motherboard)
 
 pci:v00001106d00003101*
  ID_MODEL_FROM_DATABASE=VT8653 Host Bridge
@@ -29328,70 +30249,70 @@ pci:v00001106d00003104*
  ID_MODEL_FROM_DATABASE=USB 2.0
 
 pci:v00001106d00003104sv00001019sd00000A81*
- ID_MODEL_FROM_DATABASE=L7VTA v1.0 Motherboard (KT400-8235)
+ ID_MODEL_FROM_DATABASE=USB 2.0 (L7VTA v1.0 Motherboard (KT400-8235))
 
 pci:v00001106d00003104sv00001043sd0000808C*
- ID_MODEL_FROM_DATABASE=A7V8X motherboard
+ ID_MODEL_FROM_DATABASE=USB 2.0 (A7V8X motherboard)
 
 pci:v00001106d00003104sv00001043sd000080A1*
- ID_MODEL_FROM_DATABASE=A7V8X-X motherboard rev 1.01
+ ID_MODEL_FROM_DATABASE=USB 2.0 (A7V8X-X motherboard rev 1.01)
 
 pci:v00001106d00003104sv00001043sd000080ED*
- ID_MODEL_FROM_DATABASE=A7V600/K8V-X/A8V Deluxe motherboard
+ ID_MODEL_FROM_DATABASE=USB 2.0 (A7V600/K8V-X/A8V Deluxe motherboard)
 
 pci:v00001106d00003104sv00001106sd00003104*
- ID_MODEL_FROM_DATABASE=USB 2.0 Controller
+ ID_MODEL_FROM_DATABASE=USB 2.0 (Controller)
 
 pci:v00001106d00003104sv00001297sd0000F641*
- ID_MODEL_FROM_DATABASE=FX41 motherboard
+ ID_MODEL_FROM_DATABASE=USB 2.0 (FX41 motherboard)
 
 pci:v00001106d00003104sv00001458sd00005004*
- ID_MODEL_FROM_DATABASE=GA-7VAX Mainboard
+ ID_MODEL_FROM_DATABASE=USB 2.0 (GA-7VAX Mainboard)
 
 pci:v00001106d00003104sv00001462sd00005901*
- ID_MODEL_FROM_DATABASE=KT6 Delta-FIS2R (MS-6590)
+ ID_MODEL_FROM_DATABASE=USB 2.0 (KT6 Delta-FIS2R (MS-6590))
 
 pci:v00001106d00003104sv00001462sd00007020*
- ID_MODEL_FROM_DATABASE=K8T NEO 2 motherboard
+ ID_MODEL_FROM_DATABASE=USB 2.0 (K8T NEO 2 motherboard)
 
 pci:v00001106d00003104sv00001462sd00007094*
- ID_MODEL_FROM_DATABASE=K8T Neo2-F V2.0
+ ID_MODEL_FROM_DATABASE=USB 2.0 (K8T Neo2-F V2.0)
 
 pci:v00001106d00003104sv00001462sd00007120*
- ID_MODEL_FROM_DATABASE=KT4AV motherboard
+ ID_MODEL_FROM_DATABASE=USB 2.0 (KT4AV motherboard)
 
 pci:v00001106d00003104sv00001462sd00007181*
- ID_MODEL_FROM_DATABASE=K8MM3-V mainboard
+ ID_MODEL_FROM_DATABASE=USB 2.0 (K8MM3-V mainboard)
 
 pci:v00001106d00003104sv0000147Bsd00001407*
- ID_MODEL_FROM_DATABASE=KV8-MAX3 motherboard
+ ID_MODEL_FROM_DATABASE=USB 2.0 (KV8-MAX3 motherboard)
 
 pci:v00001106d00003104sv0000182Dsd0000201D*
- ID_MODEL_FROM_DATABASE=CN-029 USB 2.0 4 port PCI Card
+ ID_MODEL_FROM_DATABASE=USB 2.0 (CN-029 USB 2.0 4 port PCI Card)
 
 pci:v00001106d00003104sv00001849sd00003104*
- ID_MODEL_FROM_DATABASE=K7VT series Motherboards
+ ID_MODEL_FROM_DATABASE=USB 2.0 (K7VT series Motherboards)
 
 pci:v00001106d00003104sv000019DAsd0000A179*
- ID_MODEL_FROM_DATABASE=ZBOX nano VD01
+ ID_MODEL_FROM_DATABASE=USB 2.0 (ZBOX nano VD01)
 
 pci:v00001106d00003106*
  ID_MODEL_FROM_DATABASE=VT6105/VT6106S [Rhine-III]
 
 pci:v00001106d00003106sv00001106sd00000105*
- ID_MODEL_FROM_DATABASE=VT6106S [Rhine-III]
+ ID_MODEL_FROM_DATABASE=VT6105/VT6106S [Rhine-III] (VT6106S [Rhine-III])
 
 pci:v00001106d00003106sv00001186sd00001403*
- ID_MODEL_FROM_DATABASE=DFE-530TX rev C
+ ID_MODEL_FROM_DATABASE=VT6105/VT6106S [Rhine-III] (DFE-530TX rev C)
 
 pci:v00001106d00003106sv00001186sd00001405*
- ID_MODEL_FROM_DATABASE=DFE-520TX Fast Ethernet PCI Adapter
+ ID_MODEL_FROM_DATABASE=VT6105/VT6106S [Rhine-III] (DFE-520TX Fast Ethernet PCI Adapter)
 
 pci:v00001106d00003106sv00001186sd00001406*
- ID_MODEL_FROM_DATABASE=DFE-530TX+ rev F2
+ ID_MODEL_FROM_DATABASE=VT6105/VT6106S [Rhine-III] (DFE-530TX+ rev F2)
 
 pci:v00001106d00003106sv00001186sd00001407*
- ID_MODEL_FROM_DATABASE=DFE-538TX
+ ID_MODEL_FROM_DATABASE=VT6105/VT6106S [Rhine-III] (DFE-538TX)
 
 pci:v00001106d00003108*
  ID_MODEL_FROM_DATABASE=K8M800/K8N800/K8N800A [S3 UniChrome Pro]
@@ -29409,7 +30330,7 @@ pci:v00001106d00003116*
  ID_MODEL_FROM_DATABASE=VT8375 [KM266/KL266] Host Bridge
 
 pci:v00001106d00003116sv00001297sd0000F641*
- ID_MODEL_FROM_DATABASE=FX41 motherboard
+ ID_MODEL_FROM_DATABASE=VT8375 [KM266/KL266] Host Bridge (FX41 motherboard)
 
 pci:v00001106d00003118*
  ID_MODEL_FROM_DATABASE=CN400/PM800/PM880/PN800/PN880 [S3 UniChrome Pro]
@@ -29436,7 +30357,7 @@ pci:v00001106d00003147*
  ID_MODEL_FROM_DATABASE=VT8233A ISA Bridge
 
 pci:v00001106d00003147sv00001043sd0000808C*
- ID_MODEL_FROM_DATABASE=A7V333 motherboard
+ ID_MODEL_FROM_DATABASE=VT8233A ISA Bridge (A7V333 motherboard)
 
 pci:v00001106d00003148*
  ID_MODEL_FROM_DATABASE=P4M266 Host Bridge
@@ -29445,34 +30366,34 @@ pci:v00001106d00003149*
  ID_MODEL_FROM_DATABASE=VIA VT6420 SATA RAID Controller
 
 pci:v00001106d00003149sv00001043sd000080ED*
- ID_MODEL_FROM_DATABASE=A7V600/K8V Deluxe/K8V-X/A8V Deluxe motherboard
+ ID_MODEL_FROM_DATABASE=VIA VT6420 SATA RAID Controller (A7V600/K8V Deluxe/K8V-X/A8V Deluxe motherboard)
 
 pci:v00001106d00003149sv00001458sd0000B003*
- ID_MODEL_FROM_DATABASE=GA-7VM400AM(F) Motherboard
+ ID_MODEL_FROM_DATABASE=VIA VT6420 SATA RAID Controller (GA-7VM400AM(F) Motherboard)
 
 pci:v00001106d00003149sv00001462sd00005901*
- ID_MODEL_FROM_DATABASE=KT6 Delta-FIS2R (MS-6590)
+ ID_MODEL_FROM_DATABASE=VIA VT6420 SATA RAID Controller (KT6 Delta-FIS2R (MS-6590))
 
 pci:v00001106d00003149sv00001462sd00007020*
- ID_MODEL_FROM_DATABASE=K8T Neo 2 Motherboard
+ ID_MODEL_FROM_DATABASE=VIA VT6420 SATA RAID Controller (K8T Neo 2 Motherboard)
 
 pci:v00001106d00003149sv00001462sd00007094*
- ID_MODEL_FROM_DATABASE=K8T Neo2-F V2.0
+ ID_MODEL_FROM_DATABASE=VIA VT6420 SATA RAID Controller (K8T Neo2-F V2.0)
 
 pci:v00001106d00003149sv00001462sd00007181*
- ID_MODEL_FROM_DATABASE=K8MM3-V mainboard
+ ID_MODEL_FROM_DATABASE=VIA VT6420 SATA RAID Controller (K8MM3-V mainboard)
 
 pci:v00001106d00003149sv0000147Bsd00001407*
- ID_MODEL_FROM_DATABASE=KV8-MAX3 motherboard
+ ID_MODEL_FROM_DATABASE=VIA VT6420 SATA RAID Controller (KV8-MAX3 motherboard)
 
 pci:v00001106d00003149sv0000147Bsd00001408*
- ID_MODEL_FROM_DATABASE=KV7
+ ID_MODEL_FROM_DATABASE=VIA VT6420 SATA RAID Controller (KV7)
 
 pci:v00001106d00003149sv00001849sd00003149*
- ID_MODEL_FROM_DATABASE=K7VT6 motherboard
+ ID_MODEL_FROM_DATABASE=VIA VT6420 SATA RAID Controller (K7VT6 motherboard)
 
 pci:v00001106d00003149sv0000A0A0sd000004AD*
- ID_MODEL_FROM_DATABASE=AK86-L motherboard
+ ID_MODEL_FROM_DATABASE=VIA VT6420 SATA RAID Controller (AK86-L motherboard)
 
 pci:v00001106d00003156*
  ID_MODEL_FROM_DATABASE=P/KN266 Host Bridge
@@ -29484,40 +30405,40 @@ pci:v00001106d00003164*
  ID_MODEL_FROM_DATABASE=VT6410 ATA133 RAID controller
 
 pci:v00001106d00003164sv00001043sd000080F4*
- ID_MODEL_FROM_DATABASE=P4P800 Mainboard Deluxe ATX
+ ID_MODEL_FROM_DATABASE=VT6410 ATA133 RAID controller (P4P800 Mainboard Deluxe ATX)
 
 pci:v00001106d00003164sv00001462sd00007028*
- ID_MODEL_FROM_DATABASE=915P/G Neo2
+ ID_MODEL_FROM_DATABASE=VT6410 ATA133 RAID controller (915P/G Neo2)
 
 pci:v00001106d00003168*
  ID_MODEL_FROM_DATABASE=P4X333/P4X400/PT800 AGP Bridge
 
 pci:v00001106d00003168sv00001849sd00003168*
- ID_MODEL_FROM_DATABASE=P4VT8 Mainboard
+ ID_MODEL_FROM_DATABASE=P4X333/P4X400/PT800 AGP Bridge (P4VT8 Mainboard)
 
 pci:v00001106d00003177*
  ID_MODEL_FROM_DATABASE=VT8235 ISA Bridge
 
 pci:v00001106d00003177sv00001019sd00000A81*
- ID_MODEL_FROM_DATABASE=L7VTA v1.0 Motherboard (KT400-8235)
+ ID_MODEL_FROM_DATABASE=VT8235 ISA Bridge (L7VTA v1.0 Motherboard (KT400-8235))
 
 pci:v00001106d00003177sv00001043sd0000808C*
- ID_MODEL_FROM_DATABASE=A7V8X motherboard
+ ID_MODEL_FROM_DATABASE=VT8235 ISA Bridge (A7V8X motherboard)
 
 pci:v00001106d00003177sv00001043sd000080A1*
- ID_MODEL_FROM_DATABASE=A7V8X-X motherboard
+ ID_MODEL_FROM_DATABASE=VT8235 ISA Bridge (A7V8X-X motherboard)
 
 pci:v00001106d00003177sv00001106sd00000000*
- ID_MODEL_FROM_DATABASE=KT4AV motherboard
+ ID_MODEL_FROM_DATABASE=VT8235 ISA Bridge (KT4AV motherboard)
 
 pci:v00001106d00003177sv00001297sd0000F641*
- ID_MODEL_FROM_DATABASE=FX41 motherboard
+ ID_MODEL_FROM_DATABASE=VT8235 ISA Bridge (FX41 motherboard)
 
 pci:v00001106d00003177sv00001458sd00005001*
- ID_MODEL_FROM_DATABASE=GA-7VAX Mainboard
+ ID_MODEL_FROM_DATABASE=VT8235 ISA Bridge (GA-7VAX Mainboard)
 
 pci:v00001106d00003177sv00001849sd00003177*
- ID_MODEL_FROM_DATABASE=K7VT series Motherboards
+ ID_MODEL_FROM_DATABASE=VT8235 ISA Bridge (K7VT series Motherboards)
 
 pci:v00001106d00003178*
  ID_MODEL_FROM_DATABASE=ProSavageDDR P4N333 Host Bridge
@@ -29526,25 +30447,25 @@ pci:v00001106d00003188*
  ID_MODEL_FROM_DATABASE=VT8385 [K8T800 AGP] Host Bridge
 
 pci:v00001106d00003188sv00001043sd000080A3*
- ID_MODEL_FROM_DATABASE=K8V Deluxe/K8V-X motherboard
+ ID_MODEL_FROM_DATABASE=VT8385 [K8T800 AGP] Host Bridge (K8V Deluxe/K8V-X motherboard)
 
 pci:v00001106d00003188sv0000147Bsd00001407*
- ID_MODEL_FROM_DATABASE=KV8-MAX3 motherboard
+ ID_MODEL_FROM_DATABASE=VT8385 [K8T800 AGP] Host Bridge (KV8-MAX3 motherboard)
 
 pci:v00001106d00003189*
  ID_MODEL_FROM_DATABASE=VT8377 [KT400/KT600 AGP] Host Bridge
 
 pci:v00001106d00003189sv00001043sd0000807F*
- ID_MODEL_FROM_DATABASE=A7V8X motherboard
+ ID_MODEL_FROM_DATABASE=VT8377 [KT400/KT600 AGP] Host Bridge (A7V8X motherboard)
 
 pci:v00001106d00003189sv00001106sd00000000*
- ID_MODEL_FROM_DATABASE=KT4AV motherboard (KT400A)
+ ID_MODEL_FROM_DATABASE=VT8377 [KT400/KT600 AGP] Host Bridge (KT4AV motherboard (KT400A))
 
 pci:v00001106d00003189sv00001458sd00005000*
- ID_MODEL_FROM_DATABASE=GA-7VAX Mainboard
+ ID_MODEL_FROM_DATABASE=VT8377 [KT400/KT600 AGP] Host Bridge (GA-7VAX Mainboard)
 
 pci:v00001106d00003189sv00001849sd00003189*
- ID_MODEL_FROM_DATABASE=K7VT series Motherboards
+ ID_MODEL_FROM_DATABASE=VT8377 [KT400/KT600 AGP] Host Bridge (K7VT series Motherboards)
 
 pci:v00001106d00003204*
  ID_MODEL_FROM_DATABASE=K8M800 Host Bridge
@@ -29553,7 +30474,7 @@ pci:v00001106d00003205*
  ID_MODEL_FROM_DATABASE=VT8378 [KM400/A] Chipset Host Bridge
 
 pci:v00001106d00003205sv00001458sd00005000*
- ID_MODEL_FROM_DATABASE=GA-7VM400M Motherboard
+ ID_MODEL_FROM_DATABASE=VT8378 [KM400/A] Chipset Host Bridge (GA-7VM400M Motherboard)
 
 pci:v00001106d00003208*
  ID_MODEL_FROM_DATABASE=PT890 Host Bridge
@@ -29568,19 +30489,19 @@ pci:v00001106d00003227*
  ID_MODEL_FROM_DATABASE=VT8237 ISA bridge [KT600/K8T800/K8T890 South]
 
 pci:v00001106d00003227sv00001043sd000080ED*
- ID_MODEL_FROM_DATABASE=A7V600/K8V-X/A8V Deluxe motherboard
+ ID_MODEL_FROM_DATABASE=VT8237 ISA bridge [KT600/K8T800/K8T890 South] (A7V600/K8V-X/A8V Deluxe motherboard)
 
 pci:v00001106d00003227sv00001106sd00003227*
- ID_MODEL_FROM_DATABASE=DFI KT600-AL / Soltek SL-B9D-FGR Motherboard
+ ID_MODEL_FROM_DATABASE=VT8237 ISA bridge [KT600/K8T800/K8T890 South] (DFI KT600-AL / Soltek SL-B9D-FGR Motherboard)
 
 pci:v00001106d00003227sv00001458sd00005001*
- ID_MODEL_FROM_DATABASE=GA-7VT600 Motherboard
+ ID_MODEL_FROM_DATABASE=VT8237 ISA bridge [KT600/K8T800/K8T890 South] (GA-7VT600 Motherboard)
 
 pci:v00001106d00003227sv0000147Bsd00001407*
- ID_MODEL_FROM_DATABASE=KV8-MAX3 motherboard
+ ID_MODEL_FROM_DATABASE=VT8237 ISA bridge [KT600/K8T800/K8T890 South] (KV8-MAX3 motherboard)
 
 pci:v00001106d00003227sv00001849sd00003227*
- ID_MODEL_FROM_DATABASE=K7VT4 motherboard
+ ID_MODEL_FROM_DATABASE=VT8237 ISA bridge [KT600/K8T800/K8T890 South] (K7VT4 motherboard)
 
 pci:v00001106d00003230*
  ID_MODEL_FROM_DATABASE=K8M890CE/K8N890CE [Chrome 9]
@@ -29591,6 +30512,9 @@ pci:v00001106d00003238*
 pci:v00001106d00003249*
  ID_MODEL_FROM_DATABASE=VT6421 IDE/SATA Controller
 
+pci:v00001106d00003249sv00001106sd00003249*
+ ID_MODEL_FROM_DATABASE=VT6421 IDE/SATA Controller
+
 pci:v00001106d0000324A*
  ID_MODEL_FROM_DATABASE=CX700/VX700 PCI to PCI Bridge
 
@@ -29625,7 +30549,7 @@ pci:v00001106d00003288*
  ID_MODEL_FROM_DATABASE=VT8237A/VT8251 HDA Controller
 
 pci:v00001106d00003288sv000019DAsd0000A179*
- ID_MODEL_FROM_DATABASE=ZBOX VD01
+ ID_MODEL_FROM_DATABASE=VT8237A/VT8251 HDA Controller (ZBOX VD01)
 
 pci:v00001106d00003290*
  ID_MODEL_FROM_DATABASE=K8M890 Host Bridge
@@ -29682,10 +30606,10 @@ pci:v00001106d00003403*
  ID_MODEL_FROM_DATABASE=VT6315 Series Firewire Controller
 
 pci:v00001106d00003403sv00001043sd00008374*
- ID_MODEL_FROM_DATABASE=M5A88-V EVO
+ ID_MODEL_FROM_DATABASE=VT6315 Series Firewire Controller (M5A88-V EVO)
 
 pci:v00001106d00003403sv00001043sd00008384*
- ID_MODEL_FROM_DATABASE=P8P67 Deluxe Motherboard
+ ID_MODEL_FROM_DATABASE=VT6315 Series Firewire Controller (P8P67 Deluxe Motherboard)
 
 pci:v00001106d00003409*
  ID_MODEL_FROM_DATABASE=VX855/VX875 DRAM Bus Control
@@ -29694,7 +30618,7 @@ pci:v00001106d00003410*
  ID_MODEL_FROM_DATABASE=VX900 DRAM Bus Control
 
 pci:v00001106d00003410sv000019DAsd0000A179*
- ID_MODEL_FROM_DATABASE=ZBOX nano VD01
+ ID_MODEL_FROM_DATABASE=VX900 DRAM Bus Control (ZBOX nano VD01)
 
 pci:v00001106d00003432*
  ID_MODEL_FROM_DATABASE=VL80x xHCI USB 3.0 Controller
@@ -29766,7 +30690,7 @@ pci:v00001106d00004410*
  ID_MODEL_FROM_DATABASE=VX900 Power Management and Chip Testing Control
 
 pci:v00001106d00004410sv000019DAsd0000A179*
- ID_MODEL_FROM_DATABASE=ZBOX nano VD01
+ ID_MODEL_FROM_DATABASE=VX900 Power Management and Chip Testing Control (ZBOX nano VD01)
 
 pci:v00001106d00005030*
  ID_MODEL_FROM_DATABASE=VT82C596 ACPI [Apollo PRO]
@@ -29844,7 +30768,7 @@ pci:v00001106d00006410*
  ID_MODEL_FROM_DATABASE=VX900 Scratch Registers
 
 pci:v00001106d00006410sv000019DAsd0000A179*
- ID_MODEL_FROM_DATABASE=ZBOX nano VD01
+ ID_MODEL_FROM_DATABASE=VX900 Scratch Registers (ZBOX nano VD01)
 
 pci:v00001106d00007122*
  ID_MODEL_FROM_DATABASE=VX900 Graphics [Chrome9 HD]
@@ -29856,10 +30780,10 @@ pci:v00001106d00007205*
  ID_MODEL_FROM_DATABASE=KM400/KN400/P4M800 [S3 UniChrome]
 
 pci:v00001106d00007205sv00001458sd0000D000*
- ID_MODEL_FROM_DATABASE=Gigabyte GA-7VM400(A)M(F) Motherboard
+ ID_MODEL_FROM_DATABASE=KM400/KN400/P4M800 [S3 UniChrome] (Gigabyte GA-7VM400(A)M(F) Motherboard)
 
 pci:v00001106d00007205sv00001462sd00007061*
- ID_MODEL_FROM_DATABASE=MS-7061
+ ID_MODEL_FROM_DATABASE=KM400/KN400/P4M800 [S3 UniChrome] (MS-7061)
 
 pci:v00001106d00007208*
  ID_MODEL_FROM_DATABASE=PT890 Host Bridge
@@ -29922,7 +30846,7 @@ pci:v00001106d00007410*
  ID_MODEL_FROM_DATABASE=VX900 North-South Module Interface Control
 
 pci:v00001106d00007410sv000019DAsd0000A179*
- ID_MODEL_FROM_DATABASE=ZBOX nano VD01
+ ID_MODEL_FROM_DATABASE=VX900 North-South Module Interface Control (ZBOX nano VD01)
 
 pci:v00001106d00008231*
  ID_MODEL_FROM_DATABASE=VT8231 [PCI-to-ISA Bridge]
@@ -29952,7 +30876,7 @@ pci:v00001106d00008410*
  ID_MODEL_FROM_DATABASE=VX900 Bus Control and Power Management
 
 pci:v00001106d00008410sv000019DAsd0000A179*
- ID_MODEL_FROM_DATABASE=ZBOX VD01
+ ID_MODEL_FROM_DATABASE=VX900 Bus Control and Power Management (ZBOX VD01)
 
 pci:v00001106d00008500*
  ID_MODEL_FROM_DATABASE=KLE133/PLE133/PLE133T
@@ -29970,7 +30894,7 @@ pci:v00001106d00008598*
  ID_MODEL_FROM_DATABASE=VT82C598/694x [Apollo MVP3/Pro133x AGP]
 
 pci:v00001106d00008598sv00001019sd00000985*
- ID_MODEL_FROM_DATABASE=P6VXA Motherboard
+ ID_MODEL_FROM_DATABASE=VT82C598/694x [Apollo MVP3/Pro133x AGP] (P6VXA Motherboard)
 
 pci:v00001106d00008601*
  ID_MODEL_FROM_DATABASE=VT8601 [Apollo ProMedia AGP]
@@ -30057,7 +30981,7 @@ pci:v00001106d0000B188*
  ID_MODEL_FROM_DATABASE=VT8237/8251 PCI bridge [K8M890/K8T800/K8T890 South]
 
 pci:v00001106d0000B188sv0000147Bsd00001407*
- ID_MODEL_FROM_DATABASE=KV8-MAX3 motherboard
+ ID_MODEL_FROM_DATABASE=VT8237/8251 PCI bridge [K8M890/K8T800/K8T890 South] (KV8-MAX3 motherboard)
 
 pci:v00001106d0000B198*
  ID_MODEL_FROM_DATABASE=VT8237/VX700 PCI Bridge
@@ -30128,6 +31052,9 @@ pci:v00001106d0000E340*
 pci:v00001106d0000E353*
  ID_MODEL_FROM_DATABASE=VX800/VX820 PCI Express Root Port
 
+pci:v00001106d0000E410*
+ ID_MODEL_FROM_DATABASE=VX900 PCI Express Physical Layer Electrical Sub-block
+
 pci:v00001106d0000F208*
  ID_MODEL_FROM_DATABASE=PT890 PCI to PCI Bridge Controller
 
@@ -30180,7 +31107,7 @@ pci:v00001109d00001400*
  ID_MODEL_FROM_DATABASE=EM110TX [EX110TX]
 
 pci:v0000110A*
- ID_VENDOR_FROM_DATABASE=Siemens Nixdorf AG
+ ID_VENDOR_FROM_DATABASE=Siemens AG
 
 pci:v0000110Ad00000002*
  ID_MODEL_FROM_DATABASE=Pirahna 2-port
@@ -30216,20 +31143,59 @@ pci:v0000110Ad00002104*
  ID_MODEL_FROM_DATABASE=Eicon Diva 2.02 compatible passive ISDN card
 
 pci:v0000110Ad00003141*
- ID_MODEL_FROM_DATABASE=SIMATIC NET CP 5611 (Profibus Adapter)
+ ID_MODEL_FROM_DATABASE=SIMATIC NET CP 5611 / 5621
 
 pci:v0000110Ad00003142*
- ID_MODEL_FROM_DATABASE=SIMATIC NET CP 5613A1 (Profibus Adapter)
+ ID_MODEL_FROM_DATABASE=SIMATIC NET CP 5613 / 5614
+
+pci:v0000110Ad00003143*
+ ID_MODEL_FROM_DATABASE=SIMATIC NET CP 1613
 
 pci:v0000110Ad00004021*
  ID_MODEL_FROM_DATABASE=SIMATIC NET CP 5512 (Profibus and MPI Cardbus Adapter)
 
 pci:v0000110Ad00004029*
- ID_MODEL_FROM_DATABASE=SIMATIC NET CP 5613A2 (Profibus Adapter)
+ ID_MODEL_FROM_DATABASE=SIMATIC NET CP 5613 A2
+
+pci:v0000110Ad00004029sv0000110Asd00004029*
+ ID_MODEL_FROM_DATABASE=SIMATIC NET CP 5613 A2
+
+pci:v0000110Ad00004029sv0000110Asd0000C029*
+ ID_MODEL_FROM_DATABASE=SIMATIC NET CP 5613 A2 (SIMATIC NET CP 5614 A2)
 
 pci:v0000110Ad00004035*
  ID_MODEL_FROM_DATABASE=SIMATIC NET CP 1613 A2
 
+pci:v0000110Ad00004036*
+ ID_MODEL_FROM_DATABASE=SIMATIC NET CP 1616
+
+pci:v0000110Ad00004038*
+ ID_MODEL_FROM_DATABASE=SIMATIC NET CP 1604
+
+pci:v0000110Ad00004069*
+ ID_MODEL_FROM_DATABASE=SIMATIC NET CP 5623
+
+pci:v0000110Ad00004069sv0000110Asd00004069*
+ ID_MODEL_FROM_DATABASE=SIMATIC NET CP 5623
+
+pci:v0000110Ad00004069sv0000110Asd0000C069*
+ ID_MODEL_FROM_DATABASE=SIMATIC NET CP 5623 (SIMATIC NET CP 5624)
+
+pci:v0000110Ad0000407C*
+ ID_MODEL_FROM_DATABASE=SIMATIC NET CP 5612
+
+pci:v0000110Ad0000407D*
+ ID_MODEL_FROM_DATABASE=SIMATIC NET CP 5613 A3
+
+pci:v0000110Ad0000407E*
+ ID_MODEL_FROM_DATABASE=SIMATIC NET CP 5622
+
+pci:v0000110Ad00004083*
+ ID_MODEL_FROM_DATABASE=SIMATIC NET CP 5614 A3
+
+pci:v0000110Ad00004084*
+ ID_MODEL_FROM_DATABASE=SIMATIC NET CP 1626
+
 pci:v0000110Ad00004942*
  ID_MODEL_FROM_DATABASE=FPGA I-Bus Tracer for MBD
 
@@ -30291,25 +31257,25 @@ pci:v00001113d00001211*
  ID_MODEL_FROM_DATABASE=SMC2-1211TX
 
 pci:v00001113d00001211sv0000103Csd00001207*
- ID_MODEL_FROM_DATABASE=EN-1207D Fast Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=SMC2-1211TX (EN-1207D Fast Ethernet Adapter)
 
 pci:v00001113d00001211sv00001113sd00001211*
- ID_MODEL_FROM_DATABASE=EN-1207D Fast Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=SMC2-1211TX (EN-1207D Fast Ethernet Adapter)
 
 pci:v00001113d00001216*
  ID_MODEL_FROM_DATABASE=EN-1216 Ethernet Adapter
 
 pci:v00001113d00001216sv00001113sd00001216*
- ID_MODEL_FROM_DATABASE=EN1207F series PCI Fast Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=EN-1216 Ethernet Adapter (EN1207F series PCI Fast Ethernet Adapter)
 
 pci:v00001113d00001216sv00001113sd00002220*
- ID_MODEL_FROM_DATABASE=EN2220A Cardbus Fast Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=EN-1216 Ethernet Adapter (EN2220A Cardbus Fast Ethernet Adapter)
 
 pci:v00001113d00001216sv00001113sd00002242*
- ID_MODEL_FROM_DATABASE=EN2242 10/100 Ethernet Mini-PCI Card
+ ID_MODEL_FROM_DATABASE=EN-1216 Ethernet Adapter (EN2242 10/100 Ethernet Mini-PCI Card)
 
 pci:v00001113d00001216sv0000111Asd00001020*
- ID_MODEL_FROM_DATABASE=SpeedStream 1020 PCI 10/100 Ethernet Adaptor [EN-1207F-TX ?]
+ ID_MODEL_FROM_DATABASE=EN-1216 Ethernet Adapter (SpeedStream 1020 PCI 10/100 Ethernet Adaptor [EN-1207F-TX ?])
 
 pci:v00001113d00001217*
  ID_MODEL_FROM_DATABASE=EN-1217 Ethernet Adapter
@@ -30621,37 +31587,37 @@ pci:v0000111Ad00000003*
  ID_MODEL_FROM_DATABASE=ENI-25P ATM
 
 pci:v0000111Ad00000003sv0000111Asd00000000*
- ID_MODEL_FROM_DATABASE=ENI-25p Miniport ATM Adapter
+ ID_MODEL_FROM_DATABASE=ENI-25P ATM (ENI-25p Miniport ATM Adapter)
 
 pci:v0000111Ad00000005*
  ID_MODEL_FROM_DATABASE=SpeedStream (LANAI)
 
 pci:v0000111Ad00000005sv0000111Asd00000001*
- ID_MODEL_FROM_DATABASE=ENI-3010 ATM
+ ID_MODEL_FROM_DATABASE=SpeedStream (LANAI) (ENI-3010 ATM)
 
 pci:v0000111Ad00000005sv0000111Asd00000009*
- ID_MODEL_FROM_DATABASE=ENI-3060 ADSL (VPI=0)
+ ID_MODEL_FROM_DATABASE=SpeedStream (LANAI) (ENI-3060 ADSL (VPI=0))
 
 pci:v0000111Ad00000005sv0000111Asd00000101*
- ID_MODEL_FROM_DATABASE=ENI-3010 ATM
+ ID_MODEL_FROM_DATABASE=SpeedStream (LANAI) (ENI-3010 ATM)
 
 pci:v0000111Ad00000005sv0000111Asd00000109*
- ID_MODEL_FROM_DATABASE=ENI-3060CO ADSL (VPI=0)
+ ID_MODEL_FROM_DATABASE=SpeedStream (LANAI) (ENI-3060CO ADSL (VPI=0))
 
 pci:v0000111Ad00000005sv0000111Asd00000809*
- ID_MODEL_FROM_DATABASE=ENI-3060 ADSL (VPI=0 or 8)
+ ID_MODEL_FROM_DATABASE=SpeedStream (LANAI) (ENI-3060 ADSL (VPI=0 or 8))
 
 pci:v0000111Ad00000005sv0000111Asd00000909*
- ID_MODEL_FROM_DATABASE=ENI-3060CO ADSL (VPI=0 or 8)
+ ID_MODEL_FROM_DATABASE=SpeedStream (LANAI) (ENI-3060CO ADSL (VPI=0 or 8))
 
 pci:v0000111Ad00000005sv0000111Asd00000A09*
- ID_MODEL_FROM_DATABASE=ENI-3060 ADSL (VPI=<0..15>)
+ ID_MODEL_FROM_DATABASE=SpeedStream (LANAI) (ENI-3060 ADSL (VPI=<0..15>))
 
 pci:v0000111Ad00000007*
  ID_MODEL_FROM_DATABASE=SpeedStream ADSL
 
 pci:v0000111Ad00000007sv0000111Asd00001001*
- ID_MODEL_FROM_DATABASE=ENI-3061 ADSL [ASIC]
+ ID_MODEL_FROM_DATABASE=SpeedStream ADSL (ENI-3061 ADSL [ASIC])
 
 pci:v0000111Ad00001020*
  ID_MODEL_FROM_DATABASE=SpeedStream PCI 10/100 Network Card
@@ -30795,7 +31761,7 @@ pci:v0000111Dd0000806A*
  ID_MODEL_FROM_DATABASE=PES24T3G2 PCI Express Gen2 Switch
 
 pci:v0000111Dd0000806Asv000014C1sd0000000C*
- ID_MODEL_FROM_DATABASE=10G-PCIE2-8B2
+ ID_MODEL_FROM_DATABASE=PES24T3G2 PCI Express Gen2 Switch (10G-PCIE2-8B2)
 
 pci:v0000111Dd0000806C*
  ID_MODEL_FROM_DATABASE=PES16T4A/4T4G2 PCI Express Gen2 Switch
@@ -30864,7 +31830,7 @@ pci:v00001127d00000400*
  ID_MODEL_FROM_DATABASE=ForeRunnerHE ATM Adapter
 
 pci:v00001127d00000400sv00001127sd00000400*
- ID_MODEL_FROM_DATABASE=ForeRunnerHE ATM
+ ID_MODEL_FROM_DATABASE=ForeRunnerHE ATM Adapter (ForeRunnerHE ATM)
 
 pci:v00001129*
  ID_VENDOR_FROM_DATABASE=Firmworks
@@ -30906,13 +31872,13 @@ pci:v00001131d00001561*
  ID_MODEL_FROM_DATABASE=USB 1.1 Host Controller
 
 pci:v00001131d00001561sv00001775sd0000C200*
- ID_MODEL_FROM_DATABASE=C2K onboard USB 1.1 host controller
+ ID_MODEL_FROM_DATABASE=USB 1.1 Host Controller (C2K onboard USB 1.1 host controller)
 
 pci:v00001131d00001562*
  ID_MODEL_FROM_DATABASE=USB 2.0 Host Controller
 
 pci:v00001131d00001562sv00001775sd0000C200*
- ID_MODEL_FROM_DATABASE=C2K onboard USB 2.0 host controller
+ ID_MODEL_FROM_DATABASE=USB 2.0 Host Controller (C2K onboard USB 2.0 host controller)
 
 pci:v00001131d00003400*
  ID_MODEL_FROM_DATABASE=SmartPCI56(UCB1500) 56K Modem
@@ -30921,49 +31887,49 @@ pci:v00001131d00005400*
  ID_MODEL_FROM_DATABASE=TriMedia TM1000/1100
 
 pci:v00001131d00005400sv000012CAsd00000000*
- ID_MODEL_FROM_DATABASE=BlueICE
+ ID_MODEL_FROM_DATABASE=TriMedia TM1000/1100 (BlueICE)
 
 pci:v00001131d00005402*
  ID_MODEL_FROM_DATABASE=TriMedia TM1300
 
 pci:v00001131d00005402sv00001244sd00000F00*
- ID_MODEL_FROM_DATABASE=Fritz!Card DSL
+ ID_MODEL_FROM_DATABASE=TriMedia TM1300 (Fritz!Card DSL)
 
 pci:v00001131d00005402sv000015EBsd00001300*
- ID_MODEL_FROM_DATABASE=DT1300
+ ID_MODEL_FROM_DATABASE=TriMedia TM1300 (DT1300)
 
 pci:v00001131d00005402sv000015EBsd00001302*
- ID_MODEL_FROM_DATABASE=DT1302
+ ID_MODEL_FROM_DATABASE=TriMedia TM1300 (DT1302)
 
 pci:v00001131d00005402sv000015EBsd00001304*
- ID_MODEL_FROM_DATABASE=DT1304
+ ID_MODEL_FROM_DATABASE=TriMedia TM1300 (DT1304)
 
 pci:v00001131d00005402sv000015EBsd00001305*
- ID_MODEL_FROM_DATABASE=DT1305
+ ID_MODEL_FROM_DATABASE=TriMedia TM1300 (DT1305)
 
 pci:v00001131d00005402sv000015EBsd00001306*
- ID_MODEL_FROM_DATABASE=PMCDT1306
+ ID_MODEL_FROM_DATABASE=TriMedia TM1300 (PMCDT1306)
 
 pci:v00001131d00005402sv000015EBsd00001308*
- ID_MODEL_FROM_DATABASE=DT1308
+ ID_MODEL_FROM_DATABASE=TriMedia TM1300 (DT1308)
 
 pci:v00001131d00005402sv000015EBsd00001331*
- ID_MODEL_FROM_DATABASE=DT1301 with SAA7121
+ ID_MODEL_FROM_DATABASE=TriMedia TM1300 (DT1301 with SAA7121)
 
 pci:v00001131d00005402sv000015EBsd00001337*
- ID_MODEL_FROM_DATABASE=DT1301 with SAA7127
+ ID_MODEL_FROM_DATABASE=TriMedia TM1300 (DT1301 with SAA7127)
 
 pci:v00001131d00005402sv000015EBsd00002D3D*
- ID_MODEL_FROM_DATABASE=X3D
+ ID_MODEL_FROM_DATABASE=TriMedia TM1300 (X3D)
 
 pci:v00001131d00005402sv000015EBsd00007022*
- ID_MODEL_FROM_DATABASE=PTM1300
+ ID_MODEL_FROM_DATABASE=TriMedia TM1300 (PTM1300)
 
 pci:v00001131d00005405*
  ID_MODEL_FROM_DATABASE=TriMedia TM1500
 
 pci:v00001131d00005405sv00001136sd00000005*
- ID_MODEL_FROM_DATABASE=LCP-1500
+ ID_MODEL_FROM_DATABASE=TriMedia TM1500 (LCP-1500)
 
 pci:v00001131d00005406*
  ID_MODEL_FROM_DATABASE=TriMedia TM1700
@@ -30972,391 +31938,409 @@ pci:v00001131d0000540B*
  ID_MODEL_FROM_DATABASE=PNX1005 Media Processor
 
 pci:v00001131d0000540Bsv00001131sd00000020*
- ID_MODEL_FROM_DATABASE=PNXLite PCI Demo Board
+ ID_MODEL_FROM_DATABASE=PNX1005 Media Processor (PNXLite PCI Demo Board)
 
 pci:v00001131d00007130*
  ID_MODEL_FROM_DATABASE=SAA7130 Video Broadcast Decoder
 
 pci:v00001131d00007130sv00000000sd00004016*
- ID_MODEL_FROM_DATABASE=Behold TV 401
+ ID_MODEL_FROM_DATABASE=SAA7130 Video Broadcast Decoder (Behold TV 401)
 
 pci:v00001131d00007130sv00000000sd00004051*
- ID_MODEL_FROM_DATABASE=Behold TV 405 FM
+ ID_MODEL_FROM_DATABASE=SAA7130 Video Broadcast Decoder (Behold TV 405 FM)
 
 pci:v00001131d00007130sv00000000sd00005051*
- ID_MODEL_FROM_DATABASE=Behold TV 505 RDS
+ ID_MODEL_FROM_DATABASE=SAA7130 Video Broadcast Decoder (Behold TV 505 RDS)
 
 pci:v00001131d00007130sv00000000sd0000505B*
- ID_MODEL_FROM_DATABASE=Behold TV 505 RDS
+ ID_MODEL_FROM_DATABASE=SAA7130 Video Broadcast Decoder (Behold TV 505 RDS)
 
 pci:v00001131d00007130sv0000102Bsd000048D0*
- ID_MODEL_FROM_DATABASE=Matrox CronosPlus
+ ID_MODEL_FROM_DATABASE=SAA7130 Video Broadcast Decoder (Matrox CronosPlus)
 
 pci:v00001131d00007130sv00001048sd0000226B*
- ID_MODEL_FROM_DATABASE=ELSA EX-VISION 300TV
+ ID_MODEL_FROM_DATABASE=SAA7130 Video Broadcast Decoder (ELSA EX-VISION 300TV)
 
 pci:v00001131d00007130sv0000107Dsd00006655*
- ID_MODEL_FROM_DATABASE=WinFast DTV1000S
+ ID_MODEL_FROM_DATABASE=SAA7130 Video Broadcast Decoder (WinFast DTV1000S)
 
 pci:v00001131d00007130sv00001131sd00000000*
- ID_MODEL_FROM_DATABASE=SAA7130-based TV tuner card
+ ID_MODEL_FROM_DATABASE=SAA7130 Video Broadcast Decoder (SAA7130-based TV tuner card)
 
 pci:v00001131d00007130sv00001131sd00002001*
- ID_MODEL_FROM_DATABASE=10MOONS PCI TV CAPTURE CARD
+ ID_MODEL_FROM_DATABASE=SAA7130 Video Broadcast Decoder (10MOONS PCI TV CAPTURE CARD)
 
 pci:v00001131d00007130sv00001131sd00002005*
- ID_MODEL_FROM_DATABASE=Techcom (India) TV Tuner Card (SSD-TV-670)
+ ID_MODEL_FROM_DATABASE=SAA7130 Video Broadcast Decoder (Techcom (India) TV Tuner Card (SSD-TV-670))
 
 pci:v00001131d00007130sv00001458sd00009006*
- ID_MODEL_FROM_DATABASE=GT-PS700 DVB-S tuner
+ ID_MODEL_FROM_DATABASE=SAA7130 Video Broadcast Decoder (GT-PS700 DVB-S tuner)
 
 pci:v00001131d00007130sv00001461sd0000050C*
- ID_MODEL_FROM_DATABASE=Nagase Sangyo TransGear 3000TV
+ ID_MODEL_FROM_DATABASE=SAA7130 Video Broadcast Decoder (Nagase Sangyo TransGear 3000TV)
 
 pci:v00001131d00007130sv00001461sd000010FF*
- ID_MODEL_FROM_DATABASE=AVerMedia DVD EZMaker
+ ID_MODEL_FROM_DATABASE=SAA7130 Video Broadcast Decoder (AVerMedia DVD EZMaker)
 
 pci:v00001131d00007130sv00001461sd00002108*
- ID_MODEL_FROM_DATABASE=AverMedia AverTV/305
+ ID_MODEL_FROM_DATABASE=SAA7130 Video Broadcast Decoder (AverMedia AverTV/305)
 
 pci:v00001131d00007130sv00001461sd00002115*
- ID_MODEL_FROM_DATABASE=AverMedia AverTV Studio 305
+ ID_MODEL_FROM_DATABASE=SAA7130 Video Broadcast Decoder (AverMedia AverTV Studio 305)
 
 pci:v00001131d00007130sv0000153Bsd00001152*
- ID_MODEL_FROM_DATABASE=Terratec Cinergy 200 TV
+ ID_MODEL_FROM_DATABASE=SAA7130 Video Broadcast Decoder (Terratec Cinergy 200 TV)
 
 pci:v00001131d00007130sv0000185Bsd0000C100*
- ID_MODEL_FROM_DATABASE=Compro VideoMate TV PVR/FM
+ ID_MODEL_FROM_DATABASE=SAA7130 Video Broadcast Decoder (Compro VideoMate TV PVR/FM)
 
 pci:v00001131d00007130sv0000185Bsd0000C901*
- ID_MODEL_FROM_DATABASE=Videomate DVB-T200
+ ID_MODEL_FROM_DATABASE=SAA7130 Video Broadcast Decoder (Videomate DVB-T200)
 
 pci:v00001131d00007130sv00005168sd00000138*
- ID_MODEL_FROM_DATABASE=LifeView FlyVIDEO2000
+ ID_MODEL_FROM_DATABASE=SAA7130 Video Broadcast Decoder (LifeView FlyVIDEO2000)
 
 pci:v00001131d00007130sv00005ACEsd00005010*
- ID_MODEL_FROM_DATABASE=Behold TV 501
+ ID_MODEL_FROM_DATABASE=SAA7130 Video Broadcast Decoder (Behold TV 501)
 
 pci:v00001131d00007130sv00005ACEsd00005050*
- ID_MODEL_FROM_DATABASE=Behold TV 505 FM
+ ID_MODEL_FROM_DATABASE=SAA7130 Video Broadcast Decoder (Behold TV 505 FM)
 
 pci:v00001131d00007133*
  ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder
 
 pci:v00001131d00007133sv00000000sd00004091*
- ID_MODEL_FROM_DATABASE=Beholder BeholdTV 409 FM
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (Beholder BeholdTV 409 FM)
 
 pci:v00001131d00007133sv00000000sd00005071*
- ID_MODEL_FROM_DATABASE=Behold TV 507 RDS
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (Behold TV 507 RDS)
 
 pci:v00001131d00007133sv00000000sd0000507B*
- ID_MODEL_FROM_DATABASE=Behold TV 507 RDS
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (Behold TV 507 RDS)
 
 pci:v00001131d00007133sv00000000sd00005201*
- ID_MODEL_FROM_DATABASE=Behold TV Columbus
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (Behold TV Columbus)
 
 pci:v00001131d00007133sv00000070sd00006701*
- ID_MODEL_FROM_DATABASE=WinTV HVR-1110
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (WinTV HVR-1110)
 
 pci:v00001131d00007133sv00001019sd00004CB5*
- ID_MODEL_FROM_DATABASE=Elitegroup ECS TVP3XP FM1236 Tuner Card (NTSC,FM)
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (Elitegroup ECS TVP3XP FM1236 Tuner Card (NTSC,FM))
 
 pci:v00001131d00007133sv00001043sd00000210*
- ID_MODEL_FROM_DATABASE=FlyTV mini Asus Digimatrix
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (FlyTV mini Asus Digimatrix)
 
 pci:v00001131d00007133sv00001043sd00004843*
- ID_MODEL_FROM_DATABASE=ASUS TV-FM 7133
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (ASUS TV-FM 7133)
 
 pci:v00001131d00007133sv00001043sd00004845*
- ID_MODEL_FROM_DATABASE=TV-FM 7135
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (TV-FM 7135)
 
 pci:v00001131d00007133sv00001043sd00004862*
- ID_MODEL_FROM_DATABASE=P7131 Dual
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (P7131 Dual)
 
 pci:v00001131d00007133sv00001043sd00004876*
- ID_MODEL_FROM_DATABASE=My Cinema-P7131 Hybrid
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (My Cinema-P7131 Hybrid)
 
 pci:v00001131d00007133sv00001131sd00000000*
- ID_MODEL_FROM_DATABASE=SAA713x-based TV tuner card
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (SAA713x-based TV tuner card)
 
 pci:v00001131d00007133sv00001131sd00002001*
- ID_MODEL_FROM_DATABASE=Proteus Pro [philips reference design]
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (Proteus Pro [philips reference design])
 
 pci:v00001131d00007133sv00001131sd00002018*
- ID_MODEL_FROM_DATABASE=Tiger reference design
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (Tiger reference design)
 
 pci:v00001131d00007133sv00001131sd00004EE9*
- ID_MODEL_FROM_DATABASE=MonsterTV Mobile
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (MonsterTV Mobile)
 
 pci:v00001131d00007133sv00001131sd00007133*
- ID_MODEL_FROM_DATABASE=Pinnacle PCTV 301i
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (Pinnacle PCTV 301i)
 
 pci:v00001131d00007133sv000011BDsd0000002B*
- ID_MODEL_FROM_DATABASE=PCTV Stereo
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (PCTV Stereo)
 
 pci:v00001131d00007133sv000011BDsd0000002E*
- ID_MODEL_FROM_DATABASE=PCTV 110i (saa7133)
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (PCTV 110i (saa7133))
 
 pci:v00001131d00007133sv000012ABsd00000800*
- ID_MODEL_FROM_DATABASE=PURPLE TV
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (PURPLE TV)
 
 pci:v00001131d00007133sv000013C2sd00002804*
- ID_MODEL_FROM_DATABASE=Technotrend Budget T-3000 Hybrid
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (Technotrend Budget T-3000 Hybrid)
 
 pci:v00001131d00007133sv00001421sd00000335*
- ID_MODEL_FROM_DATABASE=Instant TV DVB-T Cardbus
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (Instant TV DVB-T Cardbus)
 
 pci:v00001131d00007133sv00001421sd00001370*
- ID_MODEL_FROM_DATABASE=Instant TV (saa7135)
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (Instant TV (saa7135))
 
 pci:v00001131d00007133sv00001435sd00007330*
- ID_MODEL_FROM_DATABASE=VFG7330
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (VFG7330)
 
 pci:v00001131d00007133sv00001435sd00007350*
- ID_MODEL_FROM_DATABASE=VFG7350
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (VFG7350)
 
 pci:v00001131d00007133sv00001458sd00009001*
- ID_MODEL_FROM_DATABASE=GC-PTV-TAF Hybrid TV card
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (GC-PTV-TAF Hybrid TV card)
 
 pci:v00001131d00007133sv00001458sd00009002*
- ID_MODEL_FROM_DATABASE=GT-PTV-TAF-RH DVB-T/Analog TV/FM tuner
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (GT-PTV-TAF-RH DVB-T/Analog TV/FM tuner)
 
 pci:v00001131d00007133sv00001458sd00009003*
- ID_MODEL_FROM_DATABASE=GT-PTV-AF-RH Analog TV/FM tuner
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (GT-PTV-AF-RH Analog TV/FM tuner)
 
 pci:v00001131d00007133sv00001458sd00009004*
- ID_MODEL_FROM_DATABASE=GT-P8000 DVB-T/Analog TV/FM tuner
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (GT-P8000 DVB-T/Analog TV/FM tuner)
 
 pci:v00001131d00007133sv00001458sd00009005*
- ID_MODEL_FROM_DATABASE=GT-P6000 Analog TV/FM tuner
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (GT-P6000 Analog TV/FM tuner)
 
 pci:v00001131d00007133sv00001458sd00009008*
- ID_MODEL_FROM_DATABASE=GT-P5100 Analog TV tuner
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (GT-P5100 Analog TV tuner)
 
 pci:v00001131d00007133sv00001461sd00001044*
- ID_MODEL_FROM_DATABASE=AVerTVHD MCE A180
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (AVerTVHD MCE A180)
 
 pci:v00001131d00007133sv00001461sd00004836*
- ID_MODEL_FROM_DATABASE=M10D Hybrid DVBT
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (M10D Hybrid DVBT)
 
 pci:v00001131d00007133sv00001461sd0000861E*
- ID_MODEL_FROM_DATABASE=M105 PAL/SECAM/NTSC/FM Tuner
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (M105 PAL/SECAM/NTSC/FM Tuner)
 
 pci:v00001131d00007133sv00001461sd0000A14B*
- ID_MODEL_FROM_DATABASE=AVerTV Studio 509
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (AVerTV Studio 509)
 
 pci:v00001131d00007133sv00001461sd0000A836*
- ID_MODEL_FROM_DATABASE=M115 DVB-T, PAL/SECAM/NTSC Tuner
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (M115 DVB-T, PAL/SECAM/NTSC Tuner)
 
 pci:v00001131d00007133sv00001461sd0000F01D*
- ID_MODEL_FROM_DATABASE=DVB-T Super 007
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (DVB-T Super 007)
 
 pci:v00001131d00007133sv00001461sd0000F31F*
- ID_MODEL_FROM_DATABASE=Avermedia AVerTV GO 007 FM
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (Avermedia AVerTV GO 007 FM)
 
 pci:v00001131d00007133sv00001461sd0000F936*
- ID_MODEL_FROM_DATABASE=Hybrid+FM PCI (rev A16D)
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (Hybrid+FM PCI (rev A16D))
 
 pci:v00001131d00007133sv00001462sd00006231*
- ID_MODEL_FROM_DATABASE=TV@nywhere Plus
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (TV@nywhere Plus)
 
 pci:v00001131d00007133sv00001489sd00000214*
- ID_MODEL_FROM_DATABASE=LifeView FlyTV Platinum FM
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (LifeView FlyTV Platinum FM)
 
 pci:v00001131d00007133sv000014C0sd00001212*
- ID_MODEL_FROM_DATABASE=LifeView FlyTV Platinum Mini2
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (LifeView FlyTV Platinum Mini2)
 
 pci:v00001131d00007133sv0000153Bsd00001160*
- ID_MODEL_FROM_DATABASE=Cinergy 250 PCI TV
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (Cinergy 250 PCI TV)
 
 pci:v00001131d00007133sv0000153Bsd00001162*
- ID_MODEL_FROM_DATABASE=Terratec Cinergy 400 mobile
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (Terratec Cinergy 400 mobile)
+
+pci:v00001131d00007133sv000017DEsd00007256*
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (PlusTV All In One PI610 card)
 
 pci:v00001131d00007133sv000017DEsd00007350*
- ID_MODEL_FROM_DATABASE=ATSC 110 Digital / Analog HDTV Tuner
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (ATSC 110 Digital / Analog HDTV Tuner)
 
 pci:v00001131d00007133sv000017DEsd00007352*
- ID_MODEL_FROM_DATABASE=ATSC 115 Digital / Analog HDTV Tuner
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (ATSC 115 Digital / Analog HDTV Tuner)
 
 pci:v00001131d00007133sv0000185Bsd0000C100*
- ID_MODEL_FROM_DATABASE=VideoMate TV
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (VideoMate TV)
 
 pci:v00001131d00007133sv0000185Bsd0000C900*
- ID_MODEL_FROM_DATABASE=VideoMate T750
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (VideoMate T750)
 
 pci:v00001131d00007133sv00005168sd00000306*
- ID_MODEL_FROM_DATABASE=LifeView FlyDVB-T DUO
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (LifeView FlyDVB-T DUO)
 
 pci:v00001131d00007133sv00005168sd00000319*
- ID_MODEL_FROM_DATABASE=LifeView FlyDVB Trio
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (LifeView FlyDVB Trio)
 
 pci:v00001131d00007133sv00005168sd00000502*
- ID_MODEL_FROM_DATABASE=LifeView FlyDVB-T Duo CardBus
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (LifeView FlyDVB-T Duo CardBus)
 
 pci:v00001131d00007133sv00005168sd00000520*
- ID_MODEL_FROM_DATABASE=LifeView FlyDVB Trio CardBus
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (LifeView FlyDVB Trio CardBus)
 
 pci:v00001131d00007133sv00005168sd00001502*
- ID_MODEL_FROM_DATABASE=LifeView FlyTV CardBus
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (LifeView FlyTV CardBus)
 
 pci:v00001131d00007133sv00005168sd00002502*
- ID_MODEL_FROM_DATABASE=LifeView FlyDVB-T CardBus
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (LifeView FlyDVB-T CardBus)
 
 pci:v00001131d00007133sv00005168sd00002520*
- ID_MODEL_FROM_DATABASE=LifeView FlyDVB-S Duo CardBus
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (LifeView FlyDVB-S Duo CardBus)
 
 pci:v00001131d00007133sv00005168sd00003502*
- ID_MODEL_FROM_DATABASE=LifeView FlyDVB-T Hybrid CardBus
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (LifeView FlyDVB-T Hybrid CardBus)
 
 pci:v00001131d00007133sv00005168sd00003520*
- ID_MODEL_FROM_DATABASE=LifeView FlyDVB Trio N CardBus
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (LifeView FlyDVB Trio N CardBus)
 
 pci:v00001131d00007133sv00005ACEsd00005030*
- ID_MODEL_FROM_DATABASE=Behold TV 503 FM
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (Behold TV 503 FM)
 
 pci:v00001131d00007133sv00005ACEsd00005090*
- ID_MODEL_FROM_DATABASE=Behold TV 509 FM
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (Behold TV 509 FM)
 
 pci:v00001131d00007133sv00005ACEsd00006090*
- ID_MODEL_FROM_DATABASE=Behold TV 609 FM
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (Behold TV 609 FM)
 
 pci:v00001131d00007133sv00005ACEsd00006091*
- ID_MODEL_FROM_DATABASE=Behold TV 609 FM
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (Behold TV 609 FM)
 
 pci:v00001131d00007133sv00005ACEsd00006092*
- ID_MODEL_FROM_DATABASE=Behold TV 609 RDS
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (Behold TV 609 RDS)
 
 pci:v00001131d00007133sv00005ACEsd00006093*
- ID_MODEL_FROM_DATABASE=Behold TV 609 RDS
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (Behold TV 609 RDS)
 
 pci:v00001131d00007133sv00005ACEsd00006190*
- ID_MODEL_FROM_DATABASE=Behold TV M6
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (Behold TV M6)
 
 pci:v00001131d00007133sv00005ACEsd00006191*
- ID_MODEL_FROM_DATABASE=Behold TV M63
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (Behold TV M63)
 
 pci:v00001131d00007133sv00005ACEsd00006193*
- ID_MODEL_FROM_DATABASE=Behold TV M6 Extra
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (Behold TV M6 Extra)
 
 pci:v00001131d00007133sv00005ACEsd00006290*
- ID_MODEL_FROM_DATABASE=Behold TV H6
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (Behold TV H6)
 
 pci:v00001131d00007133sv00005ACEsd00007090*
- ID_MODEL_FROM_DATABASE=Behold TV A7
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (Behold TV A7)
+
+pci:v00001131d00007133sv00005ACEsd00007150*
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (Behold TV H75)
+
+pci:v00001131d00007133sv00005ACEsd00007151*
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (Behold TV H75)
 
 pci:v00001131d00007133sv00005ACEsd00007190*
- ID_MODEL_FROM_DATABASE=Behold TV H7
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (Behold TV H7)
+
+pci:v00001131d00007133sv00005ACEsd00007191*
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (Behold TV H7)
+
+pci:v00001131d00007133sv00005ACEsd00007290*
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (Behold TV T7)
+
+pci:v00001131d00007133sv00005ACEsd00007591*
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (Behold TV X7)
 
 pci:v00001131d00007133sv00005ACEsd00007595*
- ID_MODEL_FROM_DATABASE=Behold TV X7
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (Behold TV X7)
 
 pci:v00001131d00007134*
  ID_MODEL_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder
 
 pci:v00001131d00007134sv00000000sd00004036*
- ID_MODEL_FROM_DATABASE=Behold TV 403
+ ID_MODEL_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder (Behold TV 403)
 
 pci:v00001131d00007134sv00000000sd00004037*
- ID_MODEL_FROM_DATABASE=Behold TV 403 FM
+ ID_MODEL_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder (Behold TV 403 FM)
 
 pci:v00001131d00007134sv00000000sd00004071*
- ID_MODEL_FROM_DATABASE=Behold TV 407 FM
+ ID_MODEL_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder (Behold TV 407 FM)
 
 pci:v00001131d00007134sv00001019sd00004CB4*
- ID_MODEL_FROM_DATABASE=Elitegroup ECS TVP3XP FM1216 Tuner Card(PAL-BG,FM)
+ ID_MODEL_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder (Elitegroup ECS TVP3XP FM1216 Tuner Card(PAL-BG,FM))
 
 pci:v00001131d00007134sv00001043sd00000210*
- ID_MODEL_FROM_DATABASE=Digimatrix TV
+ ID_MODEL_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder (Digimatrix TV)
 
 pci:v00001131d00007134sv00001043sd00004840*
- ID_MODEL_FROM_DATABASE=ASUS TV-FM 7134
+ ID_MODEL_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder (ASUS TV-FM 7134)
 
 pci:v00001131d00007134sv00001043sd00004842*
- ID_MODEL_FROM_DATABASE=TV-FM 7134
+ ID_MODEL_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder (TV-FM 7134)
 
 pci:v00001131d00007134sv00001131sd00000000*
- ID_MODEL_FROM_DATABASE=SAA713x-based TV tuner card
+ ID_MODEL_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder (SAA713x-based TV tuner card)
 
 pci:v00001131d00007134sv00001131sd00002004*
- ID_MODEL_FROM_DATABASE=EUROPA V3 reference design
+ ID_MODEL_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder (EUROPA V3 reference design)
 
 pci:v00001131d00007134sv00001131sd00004E85*
- ID_MODEL_FROM_DATABASE=SKNet Monster TV
+ ID_MODEL_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder (SKNet Monster TV)
 
 pci:v00001131d00007134sv00001131sd00006752*
- ID_MODEL_FROM_DATABASE=EMPRESS
+ ID_MODEL_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder (EMPRESS)
 
 pci:v00001131d00007134sv000011BDsd0000002B*
- ID_MODEL_FROM_DATABASE=PCTV Stereo
+ ID_MODEL_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder (PCTV Stereo)
 
 pci:v00001131d00007134sv000011BDsd0000002D*
- ID_MODEL_FROM_DATABASE=PCTV 300i DVB-T + PAL
+ ID_MODEL_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder (PCTV 300i DVB-T + PAL)
 
 pci:v00001131d00007134sv00001461sd00002C00*
- ID_MODEL_FROM_DATABASE=AverTV Hybrid+FM PCI
+ ID_MODEL_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder (AverTV Hybrid+FM PCI)
 
 pci:v00001131d00007134sv00001461sd00009715*
- ID_MODEL_FROM_DATABASE=AVerTV Studio 307
+ ID_MODEL_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder (AVerTV Studio 307)
 
 pci:v00001131d00007134sv00001461sd0000A70A*
- ID_MODEL_FROM_DATABASE=Avermedia AVerTV 307
+ ID_MODEL_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder (Avermedia AVerTV 307)
 
 pci:v00001131d00007134sv00001461sd0000A70B*
- ID_MODEL_FROM_DATABASE=AverMedia M156 / Medion 2819
+ ID_MODEL_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder (AverMedia M156 / Medion 2819)
 
 pci:v00001131d00007134sv00001461sd0000D6EE*
- ID_MODEL_FROM_DATABASE=Cardbus TV/Radio (E500)
+ ID_MODEL_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder (Cardbus TV/Radio (E500))
 
 pci:v00001131d00007134sv00001471sd0000B7E9*
- ID_MODEL_FROM_DATABASE=AVerTV Cardbus plus
+ ID_MODEL_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder (AVerTV Cardbus plus)
 
 pci:v00001131d00007134sv0000153Bsd00001142*
- ID_MODEL_FROM_DATABASE=Terratec Cinergy 400 TV
+ ID_MODEL_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder (Terratec Cinergy 400 TV)
 
 pci:v00001131d00007134sv0000153Bsd00001143*
- ID_MODEL_FROM_DATABASE=Terratec Cinergy 600 TV
+ ID_MODEL_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder (Terratec Cinergy 600 TV)
 
 pci:v00001131d00007134sv0000153Bsd00001158*
- ID_MODEL_FROM_DATABASE=Terratec Cinergy 600 TV MK3
+ ID_MODEL_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder (Terratec Cinergy 600 TV MK3)
 
 pci:v00001131d00007134sv00001540sd00009524*
- ID_MODEL_FROM_DATABASE=ProVideo PV952
+ ID_MODEL_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder (ProVideo PV952)
 
 pci:v00001131d00007134sv000016BEsd00000003*
- ID_MODEL_FROM_DATABASE=Medion 7134
+ ID_MODEL_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder (Medion 7134)
 
 pci:v00001131d00007134sv0000185Bsd0000C200*
- ID_MODEL_FROM_DATABASE=Compro VideoMate Gold+ Pal
+ ID_MODEL_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder (Compro VideoMate Gold+ Pal)
 
 pci:v00001131d00007134sv0000185Bsd0000C900*
- ID_MODEL_FROM_DATABASE=Videomate DVB-T300
+ ID_MODEL_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder (Videomate DVB-T300)
 
 pci:v00001131d00007134sv00001894sd0000A006*
- ID_MODEL_FROM_DATABASE=KNC One TV-Station DVR
+ ID_MODEL_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder (KNC One TV-Station DVR)
 
 pci:v00001131d00007134sv00001894sd0000FE01*
- ID_MODEL_FROM_DATABASE=KNC One TV-Station RDS / Typhoon TV Tuner RDS
+ ID_MODEL_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder (KNC One TV-Station RDS / Typhoon TV Tuner RDS)
 
 pci:v00001131d00007134sv00005168sd00000138*
- ID_MODEL_FROM_DATABASE=FLY TV PRIME 34FM
+ ID_MODEL_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder (FLY TV PRIME 34FM)
 
 pci:v00001131d00007134sv00005168sd00000300*
- ID_MODEL_FROM_DATABASE=FlyDVB-S
+ ID_MODEL_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder (FlyDVB-S)
 
 pci:v00001131d00007134sv00005ACEsd00005070*
- ID_MODEL_FROM_DATABASE=Behold TV 507 FM
+ ID_MODEL_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder (Behold TV 507 FM)
 
 pci:v00001131d00007134sv00005ACEsd00006070*
- ID_MODEL_FROM_DATABASE=Behold TV 607 FM
+ ID_MODEL_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder (Behold TV 607 FM)
 
 pci:v00001131d00007134sv00005ACEsd00006071*
- ID_MODEL_FROM_DATABASE=Behold TV 607 FM
+ ID_MODEL_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder (Behold TV 607 FM)
 
 pci:v00001131d00007134sv00005ACEsd00006072*
- ID_MODEL_FROM_DATABASE=Behold TV 607 RDS
+ ID_MODEL_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder (Behold TV 607 RDS)
 
 pci:v00001131d00007134sv00005ACEsd00006073*
- ID_MODEL_FROM_DATABASE=Behold TV 607 RDS
+ ID_MODEL_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder (Behold TV 607 RDS)
 
 pci:v00001131d00007145*
  ID_MODEL_FROM_DATABASE=SAA7145
@@ -31365,202 +32349,229 @@ pci:v00001131d00007146*
  ID_MODEL_FROM_DATABASE=SAA7146
 
 pci:v00001131d00007146sv0000110Asd00000000*
- ID_MODEL_FROM_DATABASE=Fujitsu/Siemens DVB-C card rev1.5
+ ID_MODEL_FROM_DATABASE=SAA7146 (Fujitsu/Siemens DVB-C card rev1.5)
 
 pci:v00001131d00007146sv0000110Asd0000FFFF*
- ID_MODEL_FROM_DATABASE=Fujitsu/Siemens DVB-C card rev1.5
+ ID_MODEL_FROM_DATABASE=SAA7146 (Fujitsu/Siemens DVB-C card rev1.5)
 
 pci:v00001131d00007146sv00001124sd00002581*
- ID_MODEL_FROM_DATABASE=Leutron Vision PicPort
+ ID_MODEL_FROM_DATABASE=SAA7146 (Leutron Vision PicPort)
 
 pci:v00001131d00007146sv00001131sd00004F56*
- ID_MODEL_FROM_DATABASE=KNC1 DVB-S Budget
+ ID_MODEL_FROM_DATABASE=SAA7146 (KNC1 DVB-S Budget)
 
 pci:v00001131d00007146sv00001131sd00004F60*
- ID_MODEL_FROM_DATABASE=Fujitsu-Siemens Activy DVB-S Budget Rev AL
+ ID_MODEL_FROM_DATABASE=SAA7146 (Fujitsu-Siemens Activy DVB-S Budget Rev AL)
 
 pci:v00001131d00007146sv00001131sd00004F61*
- ID_MODEL_FROM_DATABASE=Activy DVB-S Budget Rev GR
+ ID_MODEL_FROM_DATABASE=SAA7146 (Activy DVB-S Budget Rev GR)
 
 pci:v00001131d00007146sv00001131sd00005F61*
- ID_MODEL_FROM_DATABASE=Activy DVB-T Budget
+ ID_MODEL_FROM_DATABASE=SAA7146 (Activy DVB-T Budget)
 
 pci:v00001131d00007146sv0000114Bsd00002003*
- ID_MODEL_FROM_DATABASE=DVRaptor Video Edit/Capture Card
+ ID_MODEL_FROM_DATABASE=SAA7146 (DVRaptor Video Edit/Capture Card)
 
 pci:v00001131d00007146sv000011BDsd00000006*
- ID_MODEL_FROM_DATABASE=DV500 Overlay
+ ID_MODEL_FROM_DATABASE=SAA7146 (DV500 Overlay)
 
 pci:v00001131d00007146sv000011BDsd0000000A*
- ID_MODEL_FROM_DATABASE=DV500 Overlay
+ ID_MODEL_FROM_DATABASE=SAA7146 (DV500 Overlay)
 
 pci:v00001131d00007146sv000011BDsd0000000F*
- ID_MODEL_FROM_DATABASE=DV500 Overlay
+ ID_MODEL_FROM_DATABASE=SAA7146 (DV500 Overlay)
 
 pci:v00001131d00007146sv000013C2sd00000000*
- ID_MODEL_FROM_DATABASE=Siemens/Technotrend/Hauppauge DVB card rev1.3 or rev1.5
+ ID_MODEL_FROM_DATABASE=SAA7146 (Siemens/Technotrend/Hauppauge DVB card rev1.3 or rev1.5)
 
 pci:v00001131d00007146sv000013C2sd00000001*
- ID_MODEL_FROM_DATABASE=Technotrend/Hauppauge DVB card rev1.3 or rev1.6
+ ID_MODEL_FROM_DATABASE=SAA7146 (Technotrend/Hauppauge DVB card rev1.3 or rev1.6)
 
 pci:v00001131d00007146sv000013C2sd00000002*
- ID_MODEL_FROM_DATABASE=Technotrend/Hauppauge DVB card rev2.1
+ ID_MODEL_FROM_DATABASE=SAA7146 (Technotrend/Hauppauge DVB card rev2.1)
 
 pci:v00001131d00007146sv000013C2sd00000003*
- ID_MODEL_FROM_DATABASE=Technotrend/Hauppauge DVB card rev2.1
+ ID_MODEL_FROM_DATABASE=SAA7146 (Technotrend/Hauppauge DVB card rev2.1)
 
 pci:v00001131d00007146sv000013C2sd00000004*
- ID_MODEL_FROM_DATABASE=Technotrend/Hauppauge DVB card rev2.1
+ ID_MODEL_FROM_DATABASE=SAA7146 (Technotrend/Hauppauge DVB card rev2.1)
 
 pci:v00001131d00007146sv000013C2sd00000006*
- ID_MODEL_FROM_DATABASE=Technotrend/Hauppauge DVB card rev1.3 or rev1.6
+ ID_MODEL_FROM_DATABASE=SAA7146 (Technotrend/Hauppauge DVB card rev1.3 or rev1.6)
 
 pci:v00001131d00007146sv000013C2sd00000008*
- ID_MODEL_FROM_DATABASE=Technotrend/Hauppauge DVB-T
+ ID_MODEL_FROM_DATABASE=SAA7146 (Technotrend/Hauppauge DVB-T)
 
 pci:v00001131d00007146sv000013C2sd0000000A*
- ID_MODEL_FROM_DATABASE=Octal/Technotrend DVB-C for iTV
+ ID_MODEL_FROM_DATABASE=SAA7146 (Octal/Technotrend DVB-C for iTV)
 
 pci:v00001131d00007146sv000013C2sd0000000E*
- ID_MODEL_FROM_DATABASE=Technotrend/Hauppauge DVB card rev2.3
+ ID_MODEL_FROM_DATABASE=SAA7146 (Technotrend/Hauppauge DVB card rev2.3)
 
 pci:v00001131d00007146sv000013C2sd00001003*
- ID_MODEL_FROM_DATABASE=Technotrend-Budget/Hauppauge WinTV-NOVA-S DVB card
+ ID_MODEL_FROM_DATABASE=SAA7146 (Technotrend-Budget/Hauppauge WinTV-NOVA-S DVB card)
 
 pci:v00001131d00007146sv000013C2sd00001004*
- ID_MODEL_FROM_DATABASE=Technotrend-Budget/Hauppauge WinTV-NOVA-C DVB card
+ ID_MODEL_FROM_DATABASE=SAA7146 (Technotrend-Budget/Hauppauge WinTV-NOVA-C DVB card)
 
 pci:v00001131d00007146sv000013C2sd00001005*
- ID_MODEL_FROM_DATABASE=Technotrend-Budget/Hauppauge WinTV-NOVA-T DVB card
+ ID_MODEL_FROM_DATABASE=SAA7146 (Technotrend-Budget/Hauppauge WinTV-NOVA-T DVB card)
 
 pci:v00001131d00007146sv000013C2sd0000100C*
- ID_MODEL_FROM_DATABASE=Technotrend-Budget/Hauppauge WinTV-NOVA-CI DVB card
+ ID_MODEL_FROM_DATABASE=SAA7146 (Technotrend-Budget/Hauppauge WinTV-NOVA-CI DVB card)
 
 pci:v00001131d00007146sv000013C2sd0000100F*
- ID_MODEL_FROM_DATABASE=Technotrend-Budget/Hauppauge WinTV-NOVA-CI DVB card
+ ID_MODEL_FROM_DATABASE=SAA7146 (Technotrend-Budget/Hauppauge WinTV-NOVA-CI DVB card)
 
 pci:v00001131d00007146sv000013C2sd00001010*
- ID_MODEL_FROM_DATABASE=DVB C-1500
+ ID_MODEL_FROM_DATABASE=SAA7146 (DVB C-1500)
 
 pci:v00001131d00007146sv000013C2sd00001011*
- ID_MODEL_FROM_DATABASE=Technotrend-Budget/Hauppauge WinTV-NOVA-T DVB card
+ ID_MODEL_FROM_DATABASE=SAA7146 (Technotrend-Budget/Hauppauge WinTV-NOVA-T DVB card)
 
 pci:v00001131d00007146sv000013C2sd00001012*
- ID_MODEL_FROM_DATABASE=DVB T-1500
+ ID_MODEL_FROM_DATABASE=SAA7146 (DVB T-1500)
 
 pci:v00001131d00007146sv000013C2sd00001013*
- ID_MODEL_FROM_DATABASE=SATELCO Multimedia DVB
+ ID_MODEL_FROM_DATABASE=SAA7146 (SATELCO Multimedia DVB)
 
 pci:v00001131d00007146sv000013C2sd00001016*
- ID_MODEL_FROM_DATABASE=WinTV-NOVA-SE DVB card
+ ID_MODEL_FROM_DATABASE=SAA7146 (WinTV-NOVA-SE DVB card)
 
 pci:v00001131d00007146sv000013C2sd00001018*
- ID_MODEL_FROM_DATABASE=DVB S-1401
+ ID_MODEL_FROM_DATABASE=SAA7146 (DVB S-1401)
 
 pci:v00001131d00007146sv000013C2sd00001019*
- ID_MODEL_FROM_DATABASE=S2-3200
+ ID_MODEL_FROM_DATABASE=SAA7146 (S2-3200)
 
 pci:v00001131d00007146sv000013C2sd00001102*
- ID_MODEL_FROM_DATABASE=Technotrend/Hauppauge DVB card rev2.1
+ ID_MODEL_FROM_DATABASE=SAA7146 (Technotrend/Hauppauge DVB card rev2.1)
 
 pci:v00001131d00007146sv0000153Bsd00001155*
- ID_MODEL_FROM_DATABASE=Cinergy 1200 DVB-S
+ ID_MODEL_FROM_DATABASE=SAA7146 (Cinergy 1200 DVB-S)
 
 pci:v00001131d00007146sv0000153Bsd00001156*
- ID_MODEL_FROM_DATABASE=Terratec Cynergy 1200C
+ ID_MODEL_FROM_DATABASE=SAA7146 (Cinergy 1200 DVB-C)
 
 pci:v00001131d00007146sv0000153Bsd00001157*
- ID_MODEL_FROM_DATABASE=Cinergy 1200 DVB-T
+ ID_MODEL_FROM_DATABASE=SAA7146 (Cinergy 1200 DVB-T)
+
+pci:v00001131d00007146sv0000153Bsd00001176*
+ ID_MODEL_FROM_DATABASE=SAA7146 (Cinergy 1200 DVB-C (MK3))
 
 pci:v00001131d00007146sv00001894sd00000020*
- ID_MODEL_FROM_DATABASE=KNC One DVB-C V1.0
+ ID_MODEL_FROM_DATABASE=SAA7146 (KNC One DVB-C V1.0)
 
 pci:v00001131d00007146sv00001894sd00000023*
- ID_MODEL_FROM_DATABASE=TVStation DVB-C plus
+ ID_MODEL_FROM_DATABASE=SAA7146 (TVStation DVB-C plus)
 
 pci:v00001131d00007160*
  ID_MODEL_FROM_DATABASE=SAA7160
 
 pci:v00001131d00007160sv00001458sd00009009*
- ID_MODEL_FROM_DATABASE=E8000 DVB-T/Analog TV/FM tuner
+ ID_MODEL_FROM_DATABASE=SAA7160 (E8000 DVB-T/Analog TV/FM tuner)
+
+pci:v00001131d00007160sv00001461sd00001455*
+ ID_MODEL_FROM_DATABASE=SAA7160 (AVerTV Hybrid Speedy PCI-E (H788))
 
 pci:v00001131d00007162*
  ID_MODEL_FROM_DATABASE=SAA7162
 
 pci:v00001131d00007162sv000011BDsd00000101*
- ID_MODEL_FROM_DATABASE=Pinnacle PCTV 7010iX TV Card
+ ID_MODEL_FROM_DATABASE=SAA7162 (Pinnacle PCTV 7010iX TV Card)
 
 pci:v00001131d00007164*
  ID_MODEL_FROM_DATABASE=SAA7164
 
 pci:v00001131d00007164sv00000070sd00008800*
- ID_MODEL_FROM_DATABASE=WinTV HVR-2250
+ ID_MODEL_FROM_DATABASE=SAA7164 (WinTV HVR-2250)
 
 pci:v00001131d00007164sv00000070sd00008810*
- ID_MODEL_FROM_DATABASE=WinTV HVR-2250
+ ID_MODEL_FROM_DATABASE=SAA7164 (WinTV HVR-2250)
 
 pci:v00001131d00007164sv00000070sd00008851*
- ID_MODEL_FROM_DATABASE=WinTV HVR-2250
+ ID_MODEL_FROM_DATABASE=SAA7164 (WinTV HVR-2250)
 
 pci:v00001131d00007164sv00000070sd00008853*
- ID_MODEL_FROM_DATABASE=WinTV HVR-2250
+ ID_MODEL_FROM_DATABASE=SAA7164 (WinTV HVR-2250)
 
 pci:v00001131d00007164sv00000070sd00008880*
- ID_MODEL_FROM_DATABASE=WinTV HVR-2250
+ ID_MODEL_FROM_DATABASE=SAA7164 (WinTV HVR-2250)
 
 pci:v00001131d00007164sv00000070sd00008891*
- ID_MODEL_FROM_DATABASE=WinTV HVR-2250
+ ID_MODEL_FROM_DATABASE=SAA7164 (WinTV HVR-2250)
 
 pci:v00001131d00007164sv00000070sd000088A0*
- ID_MODEL_FROM_DATABASE=WinTV HVR-2250
+ ID_MODEL_FROM_DATABASE=SAA7164 (WinTV HVR-2250)
 
 pci:v00001131d00007164sv00000070sd000088A1*
- ID_MODEL_FROM_DATABASE=WinTV HVR-2250
+ ID_MODEL_FROM_DATABASE=SAA7164 (WinTV HVR-2250)
 
 pci:v00001131d00007164sv00000070sd00008900*
- ID_MODEL_FROM_DATABASE=WinTV HVR-2200
+ ID_MODEL_FROM_DATABASE=SAA7164 (WinTV HVR-2200)
 
 pci:v00001131d00007164sv00000070sd00008901*
- ID_MODEL_FROM_DATABASE=WinTV HVR-2200
+ ID_MODEL_FROM_DATABASE=SAA7164 (WinTV HVR-2200)
 
 pci:v00001131d00007164sv00000070sd00008940*
- ID_MODEL_FROM_DATABASE=WinTV HVR-2200 (submodel 89619)
+ ID_MODEL_FROM_DATABASE=SAA7164 (WinTV HVR-2200 (submodel 89619))
 
 pci:v00001131d00007164sv00000070sd00008951*
- ID_MODEL_FROM_DATABASE=WinTV HVR-2200
+ ID_MODEL_FROM_DATABASE=SAA7164 (WinTV HVR-2200)
 
 pci:v00001131d00007164sv00000070sd00008953*
- ID_MODEL_FROM_DATABASE=WinTV HVR-2200
+ ID_MODEL_FROM_DATABASE=SAA7164 (WinTV HVR-2200)
 
 pci:v00001131d00007164sv00000070sd00008980*
- ID_MODEL_FROM_DATABASE=WinTV HVR-2200
+ ID_MODEL_FROM_DATABASE=SAA7164 (WinTV HVR-2200)
 
 pci:v00001131d00007164sv00000070sd00008991*
- ID_MODEL_FROM_DATABASE=WinTV HVR-2200
+ ID_MODEL_FROM_DATABASE=SAA7164 (WinTV HVR-2200)
 
 pci:v00001131d00007164sv00000070sd00008993*
- ID_MODEL_FROM_DATABASE=WinTV HVR-2200
+ ID_MODEL_FROM_DATABASE=SAA7164 (WinTV HVR-2200)
 
 pci:v00001131d00007164sv00000070sd000089A0*
- ID_MODEL_FROM_DATABASE=WinTV HVR-2200
+ ID_MODEL_FROM_DATABASE=SAA7164 (WinTV HVR-2200)
 
 pci:v00001131d00007164sv00000070sd000089A1*
- ID_MODEL_FROM_DATABASE=WinTV HVR-2200
+ ID_MODEL_FROM_DATABASE=SAA7164 (WinTV HVR-2200)
 
 pci:v00001131d00007231*
  ID_MODEL_FROM_DATABASE=SAA7231
 
 pci:v00001131d00007231sv00005ACEsd00008000*
- ID_MODEL_FROM_DATABASE=Behold TV H8
+ ID_MODEL_FROM_DATABASE=SAA7231 (Behold TV H8)
+
+pci:v00001131d00007231sv00005ACEsd00008001*
+ ID_MODEL_FROM_DATABASE=SAA7231 (Behold TV H8)
+
+pci:v00001131d00007231sv00005ACEsd00008050*
+ ID_MODEL_FROM_DATABASE=SAA7231 (Behold TV H85)
+
+pci:v00001131d00007231sv00005ACEsd00008051*
+ ID_MODEL_FROM_DATABASE=SAA7231 (Behold TV H85)
 
 pci:v00001131d00007231sv00005ACEsd00008100*
- ID_MODEL_FROM_DATABASE=Behold TV A8
+ ID_MODEL_FROM_DATABASE=SAA7231 (Behold TV A8)
+
+pci:v00001131d00007231sv00005ACEsd00008101*
+ ID_MODEL_FROM_DATABASE=SAA7231 (Behold TV A8)
+
+pci:v00001131d00007231sv00005ACEsd00008150*
+ ID_MODEL_FROM_DATABASE=SAA7231 (Behold TV A85)
+
+pci:v00001131d00007231sv00005ACEsd00008151*
+ ID_MODEL_FROM_DATABASE=SAA7231 (Behold TV A85)
+
+pci:v00001131d00007231sv00005ACEsd00008201*
+ ID_MODEL_FROM_DATABASE=SAA7231 (Behold TV T8)
 
 pci:v00001131d00009730*
  ID_MODEL_FROM_DATABASE=SAA9730 Integrated Multimedia and Peripheral Controller
 
 pci:v00001131d00009730sv00001131sd00000000*
- ID_MODEL_FROM_DATABASE=Integrated Multimedia and Peripheral Controller
+ ID_MODEL_FROM_DATABASE=SAA9730 Integrated Multimedia and Peripheral Controller (Integrated Multimedia and Peripheral Controller)
 
 pci:v00001132*
  ID_VENDOR_FROM_DATABASE=Mitel Corp.
@@ -31674,7 +32685,7 @@ pci:v00001133d0000E010*
  ID_MODEL_FROM_DATABASE=Diva Server BRI-2M PCI
 
 pci:v00001133d0000E010sv0000110Asd00000021*
- ID_MODEL_FROM_DATABASE=Fujitsu Siemens ISDN S0
+ ID_MODEL_FROM_DATABASE=Diva Server BRI-2M PCI (Fujitsu Siemens ISDN S0)
 
 pci:v00001133d0000E011*
  ID_MODEL_FROM_DATABASE=Diva Server BRI S/T Rev 2
@@ -31686,10 +32697,10 @@ pci:v00001133d0000E013*
  ID_MODEL_FROM_DATABASE=4BRI
 
 pci:v00001133d0000E013sv00001133sd00001300*
- ID_MODEL_FROM_DATABASE=Diva V-4BRI-8 PCI v2
+ ID_MODEL_FROM_DATABASE=4BRI (Diva V-4BRI-8 PCI v2)
 
 pci:v00001133d0000E013sv00001133sd0000E013*
- ID_MODEL_FROM_DATABASE=Diva 4BRI-8 PCI v2
+ ID_MODEL_FROM_DATABASE=4BRI (Diva 4BRI-8 PCI v2)
 
 pci:v00001133d0000E014*
  ID_MODEL_FROM_DATABASE=Diva Server PRI-30M PCI
@@ -31704,22 +32715,22 @@ pci:v00001133d0000E017*
  ID_MODEL_FROM_DATABASE=Diva Server Voice 4BRI Rev 2
 
 pci:v00001133d0000E017sv00001133sd0000E017*
- ID_MODEL_FROM_DATABASE=Diva Server Voice 4BRI-8M 2.0 PCI
+ ID_MODEL_FROM_DATABASE=Diva Server Voice 4BRI Rev 2 (Diva Server Voice 4BRI-8M 2.0 PCI)
 
 pci:v00001133d0000E018*
  ID_MODEL_FROM_DATABASE=BRI
 
 pci:v00001133d0000E018sv00001133sd00001800*
- ID_MODEL_FROM_DATABASE=Diva V-BRI-2 PCI v2
+ ID_MODEL_FROM_DATABASE=BRI (Diva V-BRI-2 PCI v2)
 
 pci:v00001133d0000E018sv00001133sd0000E018*
- ID_MODEL_FROM_DATABASE=Diva BRI-2 PCI v2
+ ID_MODEL_FROM_DATABASE=BRI (Diva BRI-2 PCI v2)
 
 pci:v00001133d0000E019*
  ID_MODEL_FROM_DATABASE=Diva Server Voice PRI Rev 2
 
 pci:v00001133d0000E019sv00001133sd0000E019*
- ID_MODEL_FROM_DATABASE=Diva Server Voice PRI 2.0 PCI
+ ID_MODEL_FROM_DATABASE=Diva Server Voice PRI Rev 2 (Diva Server Voice PRI 2.0 PCI)
 
 pci:v00001133d0000E01A*
  ID_MODEL_FROM_DATABASE=Diva BRI-2FX PCI v2
@@ -31734,85 +32745,85 @@ pci:v00001133d0000E01C*
  ID_MODEL_FROM_DATABASE=PRI
 
 pci:v00001133d0000E01Csv00001133sd00001C01*
- ID_MODEL_FROM_DATABASE=Diva PRI/E1/T1-8 PCI v3
+ ID_MODEL_FROM_DATABASE=PRI (Diva PRI/E1/T1-8 PCI v3)
 
 pci:v00001133d0000E01Csv00001133sd00001C02*
- ID_MODEL_FROM_DATABASE=Diva PRI/T1-24 PCI(e) v3
+ ID_MODEL_FROM_DATABASE=PRI (Diva PRI/T1-24 PCI(e) v3)
 
 pci:v00001133d0000E01Csv00001133sd00001C03*
- ID_MODEL_FROM_DATABASE=Diva PRI/E1-30 PCI(e) v3
+ ID_MODEL_FROM_DATABASE=PRI (Diva PRI/E1-30 PCI(e) v3)
 
 pci:v00001133d0000E01Csv00001133sd00001C04*
- ID_MODEL_FROM_DATABASE=Diva PRI/E1/T1-CTI PCI(e) v3
+ ID_MODEL_FROM_DATABASE=PRI (Diva PRI/E1/T1-CTI PCI(e) v3)
 
 pci:v00001133d0000E01Csv00001133sd00001C05*
- ID_MODEL_FROM_DATABASE=Diva V-PRI/T1-24 PCI(e) v3
+ ID_MODEL_FROM_DATABASE=PRI (Diva V-PRI/T1-24 PCI(e) v3)
 
 pci:v00001133d0000E01Csv00001133sd00001C06*
- ID_MODEL_FROM_DATABASE=Diva V-PRI/E1-30 PCI(e) v3
+ ID_MODEL_FROM_DATABASE=PRI (Diva V-PRI/E1-30 PCI(e) v3)
 
 pci:v00001133d0000E01Csv00001133sd00001C07*
- ID_MODEL_FROM_DATABASE=Diva Server PRI/E1/T1-8 Cornet NQ
+ ID_MODEL_FROM_DATABASE=PRI (Diva Server PRI/E1/T1-8 Cornet NQ)
 
 pci:v00001133d0000E01Csv00001133sd00001C08*
- ID_MODEL_FROM_DATABASE=Diva Server PRI/T1-24 Cornet NQ
+ ID_MODEL_FROM_DATABASE=PRI (Diva Server PRI/T1-24 Cornet NQ)
 
 pci:v00001133d0000E01Csv00001133sd00001C09*
- ID_MODEL_FROM_DATABASE=Diva Server PRI/E1-30 Cornet NQ
+ ID_MODEL_FROM_DATABASE=PRI (Diva Server PRI/E1-30 Cornet NQ)
 
 pci:v00001133d0000E01Csv00001133sd00001C0A*
- ID_MODEL_FROM_DATABASE=Diva Server PRI/E1/T1 Cornet NQ
+ ID_MODEL_FROM_DATABASE=PRI (Diva Server PRI/E1/T1 Cornet NQ)
 
 pci:v00001133d0000E01Csv00001133sd00001C0B*
- ID_MODEL_FROM_DATABASE=Diva Server V-PRI/T1-24 Cornet NQ
+ ID_MODEL_FROM_DATABASE=PRI (Diva Server V-PRI/T1-24 Cornet NQ)
 
 pci:v00001133d0000E01Csv00001133sd00001C0C*
- ID_MODEL_FROM_DATABASE=Diva Server V-PRI/E1-30 Cornet NQ
+ ID_MODEL_FROM_DATABASE=PRI (Diva Server V-PRI/E1-30 Cornet NQ)
 
 pci:v00001133d0000E01E*
  ID_MODEL_FROM_DATABASE=2PRI
 
 pci:v00001133d0000E01Esv00001133sd00001E01*
- ID_MODEL_FROM_DATABASE=Diva 2PRI/E1/T1-60 PCI v1
+ ID_MODEL_FROM_DATABASE=2PRI (Diva 2PRI/E1/T1-60 PCI v1)
 
 pci:v00001133d0000E01Esv00001133sd0000E01E*
- ID_MODEL_FROM_DATABASE=Diva V-2PRI/E1/T1-60 PCI v1
+ ID_MODEL_FROM_DATABASE=2PRI (Diva V-2PRI/E1/T1-60 PCI v1)
 
 pci:v00001133d0000E020*
  ID_MODEL_FROM_DATABASE=4PRI
 
 pci:v00001133d0000E020sv00001133sd00002001*
- ID_MODEL_FROM_DATABASE=Diva 4PRI/E1/T1-120 PCI v1
+ ID_MODEL_FROM_DATABASE=4PRI (Diva 4PRI/E1/T1-120 PCI v1)
 
 pci:v00001133d0000E020sv00001133sd0000E020*
- ID_MODEL_FROM_DATABASE=Diva V-4PRI/E1/T1-120 PCI v1
+ ID_MODEL_FROM_DATABASE=4PRI (Diva V-4PRI/E1/T1-120 PCI v1)
 
 pci:v00001133d0000E022*
  ID_MODEL_FROM_DATABASE=Analog-2
 
 pci:v00001133d0000E022sv00001133sd00002200*
- ID_MODEL_FROM_DATABASE=Diva V-Analog-2 PCI v1
+ ID_MODEL_FROM_DATABASE=Analog-2 (Diva V-Analog-2 PCI v1)
 
 pci:v00001133d0000E022sv00001133sd0000E022*
- ID_MODEL_FROM_DATABASE=Diva Analog-2 PCI v1
+ ID_MODEL_FROM_DATABASE=Analog-2 (Diva Analog-2 PCI v1)
 
 pci:v00001133d0000E024*
  ID_MODEL_FROM_DATABASE=Analog-4
 
 pci:v00001133d0000E024sv00001133sd00002400*
- ID_MODEL_FROM_DATABASE=Diva V-Analog-4 PCI v1
+ ID_MODEL_FROM_DATABASE=Analog-4 (Diva V-Analog-4 PCI v1)
 
 pci:v00001133d0000E024sv00001133sd0000E024*
- ID_MODEL_FROM_DATABASE=Diva Analog-4 PCI v1
+ ID_MODEL_FROM_DATABASE=Analog-4 (Diva Analog-4 PCI v1)
 
 pci:v00001133d0000E028*
  ID_MODEL_FROM_DATABASE=Analog-8
 
 pci:v00001133d0000E028sv00001133sd00002800*
- ID_MODEL_FROM_DATABASE=Diva V-Analog-8 PCI v1
+ ID_MODEL_FROM_DATABASE=Analog-8 (Diva V-Analog-8 PCI v1)
 
 pci:v00001133d0000E028sv00001133sd0000E028*
- ID_MODEL_FROM_DATABASE=Diva Analog-8 PCI v1
+ ID_MODEL_FROM_DATABASE=Analog-8 (Diva Analog-8 PCI v1)
 
 pci:v00001133d0000E02A*
  ID_MODEL_FROM_DATABASE=Diva IPM-300 PCI v1
@@ -31824,19 +32835,19 @@ pci:v00001133d0000E02E*
  ID_MODEL_FROM_DATABASE=4BRI
 
 pci:v00001133d0000E02Esv00001133sd00002E01*
- ID_MODEL_FROM_DATABASE=Diva V-4BRI-8 PCIe v2
+ ID_MODEL_FROM_DATABASE=4BRI (Diva V-4BRI-8 PCIe v2)
 
 pci:v00001133d0000E02Esv00001133sd0000E02E*
- ID_MODEL_FROM_DATABASE=Diva 4BRI-8 PCIe v2
+ ID_MODEL_FROM_DATABASE=4BRI (Diva 4BRI-8 PCIe v2)
 
 pci:v00001133d0000E032*
  ID_MODEL_FROM_DATABASE=BRI
 
 pci:v00001133d0000E032sv00001133sd00003201*
- ID_MODEL_FROM_DATABASE=Diva V-BRI-2 PCIe v2
+ ID_MODEL_FROM_DATABASE=BRI (Diva V-BRI-2 PCIe v2)
 
 pci:v00001133d0000E032sv00001133sd0000E032*
- ID_MODEL_FROM_DATABASE=Diva BRI-2 PCIe v2
+ ID_MODEL_FROM_DATABASE=BRI (Diva BRI-2 PCIe v2)
 
 pci:v00001133d0000E034*
  ID_MODEL_FROM_DATABASE=Diva BRI-CTI PCI v2
@@ -31884,88 +32895,88 @@ pci:v00001137d00000042*
  ID_MODEL_FROM_DATABASE=VIC Management Controller
 
 pci:v00001137d00000042sv00001137sd00000047*
- ID_MODEL_FROM_DATABASE=VIC P81E PCIe Management Controller
+ ID_MODEL_FROM_DATABASE=VIC Management Controller (VIC P81E PCIe Management Controller)
 
 pci:v00001137d00000042sv00001137sd00000085*
- ID_MODEL_FROM_DATABASE=VIC 1225 PCIe Management Controller
+ ID_MODEL_FROM_DATABASE=VIC Management Controller (VIC 1225 PCIe Management Controller)
 
 pci:v00001137d00000042sv00001137sd000000CD*
- ID_MODEL_FROM_DATABASE=VIC 1285 PCIe Management Controller
+ ID_MODEL_FROM_DATABASE=VIC Management Controller (VIC 1285 PCIe Management Controller)
 
 pci:v00001137d00000042sv00001137sd000000CE*
- ID_MODEL_FROM_DATABASE=VIC 1225T PCIe Management Controller
+ ID_MODEL_FROM_DATABASE=VIC Management Controller (VIC 1225T PCIe Management Controller)
 
 pci:v00001137d00000043*
  ID_MODEL_FROM_DATABASE=VIC Ethernet NIC
 
 pci:v00001137d00000043sv00001137sd00000047*
- ID_MODEL_FROM_DATABASE=VIC P81E PCIe Ethernet NIC
+ ID_MODEL_FROM_DATABASE=VIC Ethernet NIC (VIC P81E PCIe Ethernet NIC)
 
 pci:v00001137d00000043sv00001137sd00000048*
- ID_MODEL_FROM_DATABASE=VIC M81KR Mezzanine Ethernet NIC
+ ID_MODEL_FROM_DATABASE=VIC Ethernet NIC (VIC M81KR Mezzanine Ethernet NIC)
 
 pci:v00001137d00000043sv00001137sd0000004F*
- ID_MODEL_FROM_DATABASE=VIC 1280 Mezzanine Ethernet NIC
+ ID_MODEL_FROM_DATABASE=VIC Ethernet NIC (VIC 1280 Mezzanine Ethernet NIC)
 
 pci:v00001137d00000043sv00001137sd00000084*
- ID_MODEL_FROM_DATABASE=VIC 1240 MLOM Ethernet NIC
+ ID_MODEL_FROM_DATABASE=VIC Ethernet NIC (VIC 1240 MLOM Ethernet NIC)
 
 pci:v00001137d00000043sv00001137sd00000085*
- ID_MODEL_FROM_DATABASE=VIC 1225 PCIe Ethernet NIC
+ ID_MODEL_FROM_DATABASE=VIC Ethernet NIC (VIC 1225 PCIe Ethernet NIC)
 
 pci:v00001137d00000043sv00001137sd000000CD*
- ID_MODEL_FROM_DATABASE=VIC 1285 PCIe Ethernet NIC
+ ID_MODEL_FROM_DATABASE=VIC Ethernet NIC (VIC 1285 PCIe Ethernet NIC)
 
 pci:v00001137d00000043sv00001137sd000000CE*
- ID_MODEL_FROM_DATABASE=VIC 1225T PCIe Ethernet NIC
+ ID_MODEL_FROM_DATABASE=VIC Ethernet NIC (VIC 1225T PCIe Ethernet NIC)
 
 pci:v00001137d00000044*
  ID_MODEL_FROM_DATABASE=VIC Ethernet NIC Dynamic
 
 pci:v00001137d00000044sv00001137sd00000047*
- ID_MODEL_FROM_DATABASE=VIC P81E PCIe Ethernet NIC Dynamic
+ ID_MODEL_FROM_DATABASE=VIC Ethernet NIC Dynamic (VIC P81E PCIe Ethernet NIC Dynamic)
 
 pci:v00001137d00000044sv00001137sd00000048*
- ID_MODEL_FROM_DATABASE=VIC M81KR Mezzanine Ethernet NIC Dynamic
+ ID_MODEL_FROM_DATABASE=VIC Ethernet NIC Dynamic (VIC M81KR Mezzanine Ethernet NIC Dynamic)
 
 pci:v00001137d00000044sv00001137sd0000004F*
- ID_MODEL_FROM_DATABASE=VIC 1280 Mezzanine Ethernet NIC Dynamic
+ ID_MODEL_FROM_DATABASE=VIC Ethernet NIC Dynamic (VIC 1280 Mezzanine Ethernet NIC Dynamic)
 
 pci:v00001137d00000044sv00001137sd00000084*
- ID_MODEL_FROM_DATABASE=VIC 1240 MLOM Ethernet NIC Dynamic
+ ID_MODEL_FROM_DATABASE=VIC Ethernet NIC Dynamic (VIC 1240 MLOM Ethernet NIC Dynamic)
 
 pci:v00001137d00000044sv00001137sd00000085*
- ID_MODEL_FROM_DATABASE=VIC 1225 PCIe Ethernet NIC Dynamic
+ ID_MODEL_FROM_DATABASE=VIC Ethernet NIC Dynamic (VIC 1225 PCIe Ethernet NIC Dynamic)
 
 pci:v00001137d00000044sv00001137sd000000CD*
- ID_MODEL_FROM_DATABASE=VIC 1285 PCIe Ethernet NIC Dynamic
+ ID_MODEL_FROM_DATABASE=VIC Ethernet NIC Dynamic (VIC 1285 PCIe Ethernet NIC Dynamic)
 
 pci:v00001137d00000044sv00001137sd000000CE*
- ID_MODEL_FROM_DATABASE=VIC 1225T PCIe Ethernet NIC Dynamic
+ ID_MODEL_FROM_DATABASE=VIC Ethernet NIC Dynamic (VIC 1225T PCIe Ethernet NIC Dynamic)
 
 pci:v00001137d00000045*
  ID_MODEL_FROM_DATABASE=VIC FCoE HBA
 
 pci:v00001137d00000045sv00001137sd00000047*
- ID_MODEL_FROM_DATABASE=VIC P81E PCIe FCoE HBA
+ ID_MODEL_FROM_DATABASE=VIC FCoE HBA (VIC P81E PCIe FCoE HBA)
 
 pci:v00001137d00000045sv00001137sd00000048*
- ID_MODEL_FROM_DATABASE=VIC M81KR Mezzanine FCoE HBA
+ ID_MODEL_FROM_DATABASE=VIC FCoE HBA (VIC M81KR Mezzanine FCoE HBA)
 
 pci:v00001137d00000045sv00001137sd0000004F*
- ID_MODEL_FROM_DATABASE=VIC 1280 Mezzanine FCoE HBA
+ ID_MODEL_FROM_DATABASE=VIC FCoE HBA (VIC 1280 Mezzanine FCoE HBA)
 
 pci:v00001137d00000045sv00001137sd00000084*
- ID_MODEL_FROM_DATABASE=VIC 1240 MLOM FCoE HBA
+ ID_MODEL_FROM_DATABASE=VIC FCoE HBA (VIC 1240 MLOM FCoE HBA)
 
 pci:v00001137d00000045sv00001137sd00000085*
- ID_MODEL_FROM_DATABASE=VIC 1225 PCIe FCoE HBA
+ ID_MODEL_FROM_DATABASE=VIC FCoE HBA (VIC 1225 PCIe FCoE HBA)
 
 pci:v00001137d00000045sv00001137sd000000CD*
- ID_MODEL_FROM_DATABASE=VIC 1285 PCIe FCoE HBA
+ ID_MODEL_FROM_DATABASE=VIC FCoE HBA (VIC 1285 PCIe FCoE HBA)
 
 pci:v00001137d00000045sv00001137sd000000CE*
- ID_MODEL_FROM_DATABASE=VIC 1225T PCIe FCoE HBA
+ ID_MODEL_FROM_DATABASE=VIC FCoE HBA (VIC 1225T PCIe FCoE HBA)
 
 pci:v00001137d0000004E*
  ID_MODEL_FROM_DATABASE=VIC 82 PCIe Upstream Port
@@ -32124,49 +33135,49 @@ pci:v00001148d00004000*
  ID_MODEL_FROM_DATABASE=FDDI Adapter
 
 pci:v00001148d00004000sv00000E11sd0000B03B*
- ID_MODEL_FROM_DATABASE=Netelligent 100 FDDI DAS Fibre SC
+ ID_MODEL_FROM_DATABASE=FDDI Adapter (Netelligent 100 FDDI DAS Fibre SC)
 
 pci:v00001148d00004000sv00000E11sd0000B03C*
- ID_MODEL_FROM_DATABASE=Netelligent 100 FDDI SAS Fibre SC
+ ID_MODEL_FROM_DATABASE=FDDI Adapter (Netelligent 100 FDDI SAS Fibre SC)
 
 pci:v00001148d00004000sv00000E11sd0000B03D*
- ID_MODEL_FROM_DATABASE=Netelligent 100 FDDI DAS UTP
+ ID_MODEL_FROM_DATABASE=FDDI Adapter (Netelligent 100 FDDI DAS UTP)
 
 pci:v00001148d00004000sv00000E11sd0000B03E*
- ID_MODEL_FROM_DATABASE=Netelligent 100 FDDI SAS UTP
+ ID_MODEL_FROM_DATABASE=FDDI Adapter (Netelligent 100 FDDI SAS UTP)
 
 pci:v00001148d00004000sv00000E11sd0000B03F*
- ID_MODEL_FROM_DATABASE=Netelligent 100 FDDI SAS Fibre MIC
+ ID_MODEL_FROM_DATABASE=FDDI Adapter (Netelligent 100 FDDI SAS Fibre MIC)
 
 pci:v00001148d00004000sv00001148sd00005521*
- ID_MODEL_FROM_DATABASE=FDDI SK-5521 (SK-NET FDDI-UP)
+ ID_MODEL_FROM_DATABASE=FDDI Adapter (FDDI SK-5521 (SK-NET FDDI-UP))
 
 pci:v00001148d00004000sv00001148sd00005522*
- ID_MODEL_FROM_DATABASE=FDDI SK-5522 (SK-NET FDDI-UP DAS)
+ ID_MODEL_FROM_DATABASE=FDDI Adapter (FDDI SK-5522 (SK-NET FDDI-UP DAS))
 
 pci:v00001148d00004000sv00001148sd00005541*
- ID_MODEL_FROM_DATABASE=FDDI SK-5541 (SK-NET FDDI-FP)
+ ID_MODEL_FROM_DATABASE=FDDI Adapter (FDDI SK-5541 (SK-NET FDDI-FP))
 
 pci:v00001148d00004000sv00001148sd00005543*
- ID_MODEL_FROM_DATABASE=FDDI SK-5543 (SK-NET FDDI-LP)
+ ID_MODEL_FROM_DATABASE=FDDI Adapter (FDDI SK-5543 (SK-NET FDDI-LP))
 
 pci:v00001148d00004000sv00001148sd00005544*
- ID_MODEL_FROM_DATABASE=FDDI SK-5544 (SK-NET FDDI-LP DAS)
+ ID_MODEL_FROM_DATABASE=FDDI Adapter (FDDI SK-5544 (SK-NET FDDI-LP DAS))
 
 pci:v00001148d00004000sv00001148sd00005821*
- ID_MODEL_FROM_DATABASE=FDDI SK-5821 (SK-NET FDDI-UP64)
+ ID_MODEL_FROM_DATABASE=FDDI Adapter (FDDI SK-5821 (SK-NET FDDI-UP64))
 
 pci:v00001148d00004000sv00001148sd00005822*
- ID_MODEL_FROM_DATABASE=FDDI SK-5822 (SK-NET FDDI-UP64 DAS)
+ ID_MODEL_FROM_DATABASE=FDDI Adapter (FDDI SK-5822 (SK-NET FDDI-UP64 DAS))
 
 pci:v00001148d00004000sv00001148sd00005841*
- ID_MODEL_FROM_DATABASE=FDDI SK-5841 (SK-NET FDDI-FP64)
+ ID_MODEL_FROM_DATABASE=FDDI Adapter (FDDI SK-5841 (SK-NET FDDI-FP64))
 
 pci:v00001148d00004000sv00001148sd00005843*
- ID_MODEL_FROM_DATABASE=FDDI SK-5843 (SK-NET FDDI-LP64)
+ ID_MODEL_FROM_DATABASE=FDDI Adapter (FDDI SK-5843 (SK-NET FDDI-LP64))
 
 pci:v00001148d00004000sv00001148sd00005844*
- ID_MODEL_FROM_DATABASE=FDDI SK-5844 (SK-NET FDDI-LP64 DAS)
+ ID_MODEL_FROM_DATABASE=FDDI Adapter (FDDI SK-5844 (SK-NET FDDI-LP64 DAS))
 
 pci:v00001148d00004200*
  ID_MODEL_FROM_DATABASE=Token Ring adapter
@@ -32175,115 +33186,115 @@ pci:v00001148d00004300*
  ID_MODEL_FROM_DATABASE=SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link)
 
 pci:v00001148d00004300sv00001148sd00009821*
- ID_MODEL_FROM_DATABASE=SK-9821 Gigabit Ethernet Server Adapter (SK-NET GE-T)
+ ID_MODEL_FROM_DATABASE=SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link) (SK-9821 Gigabit Ethernet Server Adapter (SK-NET GE-T))
 
 pci:v00001148d00004300sv00001148sd00009822*
- ID_MODEL_FROM_DATABASE=SK-9822 Gigabit Ethernet Server Adapter (SK-NET GE-T dual link)
+ ID_MODEL_FROM_DATABASE=SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link) (SK-9822 Gigabit Ethernet Server Adapter (SK-NET GE-T dual link))
 
 pci:v00001148d00004300sv00001148sd00009841*
- ID_MODEL_FROM_DATABASE=SK-9841 Gigabit Ethernet Server Adapter (SK-NET GE-LX)
+ ID_MODEL_FROM_DATABASE=SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link) (SK-9841 Gigabit Ethernet Server Adapter (SK-NET GE-LX))
 
 pci:v00001148d00004300sv00001148sd00009842*
- ID_MODEL_FROM_DATABASE=SK-9842 Gigabit Ethernet Server Adapter (SK-NET GE-LX dual link)
+ ID_MODEL_FROM_DATABASE=SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link) (SK-9842 Gigabit Ethernet Server Adapter (SK-NET GE-LX dual link))
 
 pci:v00001148d00004300sv00001148sd00009843*
- ID_MODEL_FROM_DATABASE=SK-9843 Gigabit Ethernet Server Adapter (SK-NET GE-SX)
+ ID_MODEL_FROM_DATABASE=SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link) (SK-9843 Gigabit Ethernet Server Adapter (SK-NET GE-SX))
 
 pci:v00001148d00004300sv00001148sd00009844*
- ID_MODEL_FROM_DATABASE=SK-9844 Gigabit Ethernet Server Adapter (SK-NET GE-SX dual link)
+ ID_MODEL_FROM_DATABASE=SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link) (SK-9844 Gigabit Ethernet Server Adapter (SK-NET GE-SX dual link))
 
 pci:v00001148d00004300sv00001148sd00009861*
- ID_MODEL_FROM_DATABASE=SK-9861 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition)
+ ID_MODEL_FROM_DATABASE=SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link) (SK-9861 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition))
 
 pci:v00001148d00004300sv00001148sd00009862*
- ID_MODEL_FROM_DATABASE=SK-9862 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition dual link)
+ ID_MODEL_FROM_DATABASE=SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link) (SK-9862 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition dual link))
 
 pci:v00001148d00004300sv00001148sd00009871*
- ID_MODEL_FROM_DATABASE=SK-9871 Gigabit Ethernet Server Adapter (SK-NET GE-ZX)
+ ID_MODEL_FROM_DATABASE=SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link) (SK-9871 Gigabit Ethernet Server Adapter (SK-NET GE-ZX))
 
 pci:v00001148d00004300sv00001148sd00009872*
  ID_MODEL_FROM_DATABASE=SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link)
 
 pci:v00001148d00004300sv00001259sd00002970*
- ID_MODEL_FROM_DATABASE=AT-2970SX Gigabit Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link) (AT-2970SX Gigabit Ethernet Adapter)
 
 pci:v00001148d00004300sv00001259sd00002971*
- ID_MODEL_FROM_DATABASE=AT-2970LX Gigabit Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link) (AT-2970LX Gigabit Ethernet Adapter)
 
 pci:v00001148d00004300sv00001259sd00002972*
- ID_MODEL_FROM_DATABASE=AT-2970TX Gigabit Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link) (AT-2970TX Gigabit Ethernet Adapter)
 
 pci:v00001148d00004300sv00001259sd00002973*
- ID_MODEL_FROM_DATABASE=AT-2971SX Gigabit Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link) (AT-2971SX Gigabit Ethernet Adapter)
 
 pci:v00001148d00004300sv00001259sd00002974*
- ID_MODEL_FROM_DATABASE=AT-2971T Gigabit Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link) (AT-2971T Gigabit Ethernet Adapter)
 
 pci:v00001148d00004300sv00001259sd00002975*
- ID_MODEL_FROM_DATABASE=AT-2970SX/2SC Gigabit Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link) (AT-2970SX/2SC Gigabit Ethernet Adapter)
 
 pci:v00001148d00004300sv00001259sd00002976*
- ID_MODEL_FROM_DATABASE=AT-2970LX/2SC Gigabit Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link) (AT-2970LX/2SC Gigabit Ethernet Adapter)
 
 pci:v00001148d00004300sv00001259sd00002977*
- ID_MODEL_FROM_DATABASE=AT-2970TX/2TX Gigabit Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link) (AT-2970TX/2TX Gigabit Ethernet Adapter)
 
 pci:v00001148d00004320*
  ID_MODEL_FROM_DATABASE=SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter, PCI64, Fiber ZX/SC
 
 pci:v00001148d00004320sv00001148sd00000121*
- ID_MODEL_FROM_DATABASE=Marvell RDK-8001 Adapter
+ ID_MODEL_FROM_DATABASE=SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter, PCI64, Fiber ZX/SC (Marvell RDK-8001 Adapter)
 
 pci:v00001148d00004320sv00001148sd00000221*
- ID_MODEL_FROM_DATABASE=Marvell RDK-8002 Adapter
+ ID_MODEL_FROM_DATABASE=SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter, PCI64, Fiber ZX/SC (Marvell RDK-8002 Adapter)
 
 pci:v00001148d00004320sv00001148sd00000321*
- ID_MODEL_FROM_DATABASE=Marvell RDK-8003 Adapter
+ ID_MODEL_FROM_DATABASE=SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter, PCI64, Fiber ZX/SC (Marvell RDK-8003 Adapter)
 
 pci:v00001148d00004320sv00001148sd00000421*
- ID_MODEL_FROM_DATABASE=Marvell RDK-8004 Adapter
+ ID_MODEL_FROM_DATABASE=SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter, PCI64, Fiber ZX/SC (Marvell RDK-8004 Adapter)
 
 pci:v00001148d00004320sv00001148sd00000621*
- ID_MODEL_FROM_DATABASE=Marvell RDK-8006 Adapter
+ ID_MODEL_FROM_DATABASE=SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter, PCI64, Fiber ZX/SC (Marvell RDK-8006 Adapter)
 
 pci:v00001148d00004320sv00001148sd00000721*
- ID_MODEL_FROM_DATABASE=Marvell RDK-8007 Adapter
+ ID_MODEL_FROM_DATABASE=SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter, PCI64, Fiber ZX/SC (Marvell RDK-8007 Adapter)
 
 pci:v00001148d00004320sv00001148sd00000821*
- ID_MODEL_FROM_DATABASE=Marvell RDK-8008 Adapter
+ ID_MODEL_FROM_DATABASE=SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter, PCI64, Fiber ZX/SC (Marvell RDK-8008 Adapter)
 
 pci:v00001148d00004320sv00001148sd00000921*
- ID_MODEL_FROM_DATABASE=Marvell RDK-8009 Adapter
+ ID_MODEL_FROM_DATABASE=SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter, PCI64, Fiber ZX/SC (Marvell RDK-8009 Adapter)
 
 pci:v00001148d00004320sv00001148sd00001121*
- ID_MODEL_FROM_DATABASE=Marvell RDK-8011 Adapter
+ ID_MODEL_FROM_DATABASE=SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter, PCI64, Fiber ZX/SC (Marvell RDK-8011 Adapter)
 
 pci:v00001148d00004320sv00001148sd00001221*
- ID_MODEL_FROM_DATABASE=Marvell RDK-8012 Adapter
+ ID_MODEL_FROM_DATABASE=SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter, PCI64, Fiber ZX/SC (Marvell RDK-8012 Adapter)
 
 pci:v00001148d00004320sv00001148sd00003221*
- ID_MODEL_FROM_DATABASE=SK-9521 V2.0 10/100/1000Base-T Adapter
+ ID_MODEL_FROM_DATABASE=SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter, PCI64, Fiber ZX/SC (SK-9521 V2.0 10/100/1000Base-T Adapter)
 
 pci:v00001148d00004320sv00001148sd00005021*
- ID_MODEL_FROM_DATABASE=SK-9821 V2.0 Gigabit Ethernet 10/100/1000Base-T Adapter
+ ID_MODEL_FROM_DATABASE=SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter, PCI64, Fiber ZX/SC (SK-9821 V2.0 Gigabit Ethernet 10/100/1000Base-T Adapter)
 
 pci:v00001148d00004320sv00001148sd00005041*
- ID_MODEL_FROM_DATABASE=SK-9841 V2.0 Gigabit Ethernet 1000Base-LX Adapter
+ ID_MODEL_FROM_DATABASE=SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter, PCI64, Fiber ZX/SC (SK-9841 V2.0 Gigabit Ethernet 1000Base-LX Adapter)
 
 pci:v00001148d00004320sv00001148sd00005043*
- ID_MODEL_FROM_DATABASE=SK-9843 V2.0 Gigabit Ethernet 1000Base-SX Adapter
+ ID_MODEL_FROM_DATABASE=SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter, PCI64, Fiber ZX/SC (SK-9843 V2.0 Gigabit Ethernet 1000Base-SX Adapter)
 
 pci:v00001148d00004320sv00001148sd00005051*
- ID_MODEL_FROM_DATABASE=SK-9851 V2.0 Gigabit Ethernet 1000Base-SX Adapter
+ ID_MODEL_FROM_DATABASE=SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter, PCI64, Fiber ZX/SC (SK-9851 V2.0 Gigabit Ethernet 1000Base-SX Adapter)
 
 pci:v00001148d00004320sv00001148sd00005061*
- ID_MODEL_FROM_DATABASE=SK-9861 V2.0 Gigabit Ethernet 1000Base-SX Adapter
+ ID_MODEL_FROM_DATABASE=SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter, PCI64, Fiber ZX/SC (SK-9861 V2.0 Gigabit Ethernet 1000Base-SX Adapter)
 
 pci:v00001148d00004320sv00001148sd00005071*
- ID_MODEL_FROM_DATABASE=SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter
+ ID_MODEL_FROM_DATABASE=SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter, PCI64, Fiber ZX/SC (SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter)
 
 pci:v00001148d00004320sv00001148sd00009521*
- ID_MODEL_FROM_DATABASE=SK-9521 10/100/1000Base-T Adapter
+ ID_MODEL_FROM_DATABASE=SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter, PCI64, Fiber ZX/SC (SK-9521 10/100/1000Base-T Adapter)
 
 pci:v00001148d00004400*
  ID_MODEL_FROM_DATABASE=SK-9Dxx Gigabit Ethernet Adapter
@@ -32301,25 +33312,25 @@ pci:v00001148d00009E00*
  ID_MODEL_FROM_DATABASE=SK-9E21D 10/100/1000Base-T Adapter, Copper RJ-45
 
 pci:v00001148d00009E00sv00001148sd00002100*
- ID_MODEL_FROM_DATABASE=SK-9E21 Server Adapter
+ ID_MODEL_FROM_DATABASE=SK-9E21D 10/100/1000Base-T Adapter, Copper RJ-45 (SK-9E21 Server Adapter)
 
 pci:v00001148d00009E00sv00001148sd000021D0*
- ID_MODEL_FROM_DATABASE=SK-9E21D 10/100/1000Base-T Adapter
+ ID_MODEL_FROM_DATABASE=SK-9E21D 10/100/1000Base-T Adapter, Copper RJ-45 (SK-9E21D 10/100/1000Base-T Adapter)
 
 pci:v00001148d00009E00sv00001148sd00002200*
- ID_MODEL_FROM_DATABASE=SK-9E22 Server Adapter
+ ID_MODEL_FROM_DATABASE=SK-9E21D 10/100/1000Base-T Adapter, Copper RJ-45 (SK-9E22 Server Adapter)
 
 pci:v00001148d00009E00sv00001148sd00008100*
- ID_MODEL_FROM_DATABASE=SK-9E81 Server Adapter
+ ID_MODEL_FROM_DATABASE=SK-9E21D 10/100/1000Base-T Adapter, Copper RJ-45 (SK-9E81 Server Adapter)
 
 pci:v00001148d00009E00sv00001148sd00008200*
- ID_MODEL_FROM_DATABASE=SK-9E82 Server Adapter
+ ID_MODEL_FROM_DATABASE=SK-9E21D 10/100/1000Base-T Adapter, Copper RJ-45 (SK-9E82 Server Adapter)
 
 pci:v00001148d00009E00sv00001148sd00009100*
- ID_MODEL_FROM_DATABASE=SK-9E91 Server Adapter
+ ID_MODEL_FROM_DATABASE=SK-9E21D 10/100/1000Base-T Adapter, Copper RJ-45 (SK-9E91 Server Adapter)
 
 pci:v00001148d00009E00sv00001148sd00009200*
- ID_MODEL_FROM_DATABASE=SK-9E92 Server Adapter
+ ID_MODEL_FROM_DATABASE=SK-9E21D 10/100/1000Base-T Adapter, Copper RJ-45 (SK-9E92 Server Adapter)
 
 pci:v00001148d00009E01*
  ID_MODEL_FROM_DATABASE=SK-9E21M 10/100/1000Base-T Adapter
@@ -32421,16 +33432,16 @@ pci:v0000114Fd0000001D*
  ID_MODEL_FROM_DATABASE=DataFire RAS T1/E1/PRI
 
 pci:v0000114Fd0000001Dsv0000114Fsd00000050*
- ID_MODEL_FROM_DATABASE=DataFire RAS E1 Adapter
+ ID_MODEL_FROM_DATABASE=DataFire RAS T1/E1/PRI (DataFire RAS E1 Adapter)
 
 pci:v0000114Fd0000001Dsv0000114Fsd00000051*
- ID_MODEL_FROM_DATABASE=DataFire RAS Dual E1 Adapter
+ ID_MODEL_FROM_DATABASE=DataFire RAS T1/E1/PRI (DataFire RAS Dual E1 Adapter)
 
 pci:v0000114Fd0000001Dsv0000114Fsd00000052*
- ID_MODEL_FROM_DATABASE=DataFire RAS T1 Adapter
+ ID_MODEL_FROM_DATABASE=DataFire RAS T1/E1/PRI (DataFire RAS T1 Adapter)
 
 pci:v0000114Fd0000001Dsv0000114Fsd00000053*
- ID_MODEL_FROM_DATABASE=DataFire RAS Dual T1 Adapter
+ ID_MODEL_FROM_DATABASE=DataFire RAS T1/E1/PRI (DataFire RAS Dual T1 Adapter)
 
 pci:v0000114Fd00000023*
  ID_MODEL_FROM_DATABASE=AccelePort RAS
@@ -32439,10 +33450,10 @@ pci:v0000114Fd00000024*
  ID_MODEL_FROM_DATABASE=DataFire RAS B4 ST/U
 
 pci:v0000114Fd00000024sv0000114Fsd00000030*
- ID_MODEL_FROM_DATABASE=DataFire RAS BRI U Adapter
+ ID_MODEL_FROM_DATABASE=DataFire RAS B4 ST/U (DataFire RAS BRI U Adapter)
 
 pci:v0000114Fd00000024sv0000114Fsd00000031*
- ID_MODEL_FROM_DATABASE=DataFire RAS BRI S/T Adapter
+ ID_MODEL_FROM_DATABASE=DataFire RAS B4 ST/U (DataFire RAS BRI S/T Adapter)
 
 pci:v0000114Fd00000026*
  ID_MODEL_FROM_DATABASE=AccelePort 4r 920
@@ -32466,19 +33477,19 @@ pci:v0000114Fd00000040*
  ID_MODEL_FROM_DATABASE=AccelePort Xp
 
 pci:v0000114Fd00000040sv0000114Fsd00000042*
- ID_MODEL_FROM_DATABASE=AccelePort 2p PCI
+ ID_MODEL_FROM_DATABASE=AccelePort Xp (AccelePort 2p PCI)
 
 pci:v0000114Fd00000040sv0000114Fsd00000043*
- ID_MODEL_FROM_DATABASE=AccelePort 4p PCI
+ ID_MODEL_FROM_DATABASE=AccelePort Xp (AccelePort 4p PCI)
 
 pci:v0000114Fd00000040sv0000114Fsd00000044*
- ID_MODEL_FROM_DATABASE=AccelePort 8p PCI
+ ID_MODEL_FROM_DATABASE=AccelePort Xp (AccelePort 8p PCI)
 
 pci:v0000114Fd00000040sv0000114Fsd00000045*
- ID_MODEL_FROM_DATABASE=AccelePort 16p PCI
+ ID_MODEL_FROM_DATABASE=AccelePort Xp (AccelePort 16p PCI)
 
 pci:v0000114Fd00000040sv0000114Fsd0000004E*
- ID_MODEL_FROM_DATABASE=AccelePort 32p PCI
+ ID_MODEL_FROM_DATABASE=AccelePort Xp (AccelePort 32p PCI)
 
 pci:v0000114Fd00000042*
  ID_MODEL_FROM_DATABASE=AccelePort 2p
@@ -32610,22 +33621,22 @@ pci:v0000115Dd00000003*
  ID_MODEL_FROM_DATABASE=Cardbus Ethernet 10/100
 
 pci:v0000115Dd00000003sv00001014sd00000181*
- ID_MODEL_FROM_DATABASE=10/100 EtherJet Cardbus Adapter
+ ID_MODEL_FROM_DATABASE=Cardbus Ethernet 10/100 (10/100 EtherJet Cardbus Adapter)
 
 pci:v0000115Dd00000003sv00001014sd00001181*
- ID_MODEL_FROM_DATABASE=10/100 EtherJet Cardbus Adapter
+ ID_MODEL_FROM_DATABASE=Cardbus Ethernet 10/100 (10/100 EtherJet Cardbus Adapter)
 
 pci:v0000115Dd00000003sv00001014sd00008181*
- ID_MODEL_FROM_DATABASE=10/100 EtherJet Cardbus Adapter
+ ID_MODEL_FROM_DATABASE=Cardbus Ethernet 10/100 (10/100 EtherJet Cardbus Adapter)
 
 pci:v0000115Dd00000003sv00001014sd00009181*
- ID_MODEL_FROM_DATABASE=10/100 EtherJet Cardbus Adapter
+ ID_MODEL_FROM_DATABASE=Cardbus Ethernet 10/100 (10/100 EtherJet Cardbus Adapter)
 
 pci:v0000115Dd00000003sv0000115Dsd00000181*
  ID_MODEL_FROM_DATABASE=Cardbus Ethernet 10/100
 
 pci:v0000115Dd00000003sv0000115Dsd00000182*
- ID_MODEL_FROM_DATABASE=RealPort2 CardBus Ethernet 10/100 (R2BE-100)
+ ID_MODEL_FROM_DATABASE=Cardbus Ethernet 10/100 (RealPort2 CardBus Ethernet 10/100 (R2BE-100))
 
 pci:v0000115Dd00000003sv0000115Dsd00001181*
  ID_MODEL_FROM_DATABASE=Cardbus Ethernet 10/100
@@ -32634,19 +33645,19 @@ pci:v0000115Dd00000003sv00001179sd00000181*
  ID_MODEL_FROM_DATABASE=Cardbus Ethernet 10/100
 
 pci:v0000115Dd00000003sv00008086sd00008181*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 Mobile CardBus 32 Adapter
+ ID_MODEL_FROM_DATABASE=Cardbus Ethernet 10/100 (EtherExpress PRO/100 Mobile CardBus 32 Adapter)
 
 pci:v0000115Dd00000003sv00008086sd00009181*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 Mobile CardBus 32 Adapter
+ ID_MODEL_FROM_DATABASE=Cardbus Ethernet 10/100 (EtherExpress PRO/100 Mobile CardBus 32 Adapter)
 
 pci:v0000115Dd00000005*
  ID_MODEL_FROM_DATABASE=Cardbus Ethernet 10/100
 
 pci:v0000115Dd00000005sv00001014sd00000182*
- ID_MODEL_FROM_DATABASE=10/100 EtherJet Cardbus Adapter
+ ID_MODEL_FROM_DATABASE=Cardbus Ethernet 10/100 (10/100 EtherJet Cardbus Adapter)
 
 pci:v0000115Dd00000005sv00001014sd00001182*
- ID_MODEL_FROM_DATABASE=10/100 EtherJet Cardbus Adapter
+ ID_MODEL_FROM_DATABASE=Cardbus Ethernet 10/100 (10/100 EtherJet Cardbus Adapter)
 
 pci:v0000115Dd00000005sv0000115Dsd00000182*
  ID_MODEL_FROM_DATABASE=Cardbus Ethernet 10/100
@@ -32658,10 +33669,10 @@ pci:v0000115Dd00000007*
  ID_MODEL_FROM_DATABASE=Cardbus Ethernet 10/100
 
 pci:v0000115Dd00000007sv00001014sd00000182*
- ID_MODEL_FROM_DATABASE=10/100 EtherJet Cardbus Adapter
+ ID_MODEL_FROM_DATABASE=Cardbus Ethernet 10/100 (10/100 EtherJet Cardbus Adapter)
 
 pci:v0000115Dd00000007sv00001014sd00001182*
- ID_MODEL_FROM_DATABASE=10/100 EtherJet Cardbus Adapter
+ ID_MODEL_FROM_DATABASE=Cardbus Ethernet 10/100 (10/100 EtherJet Cardbus Adapter)
 
 pci:v0000115Dd00000007sv0000115Dsd00000182*
  ID_MODEL_FROM_DATABASE=Cardbus Ethernet 10/100
@@ -32673,7 +33684,7 @@ pci:v0000115Dd0000000B*
  ID_MODEL_FROM_DATABASE=Cardbus Ethernet 10/100
 
 pci:v0000115Dd0000000Bsv00001014sd00000183*
- ID_MODEL_FROM_DATABASE=10/100 EtherJet Cardbus Adapter
+ ID_MODEL_FROM_DATABASE=Cardbus Ethernet 10/100 (10/100 EtherJet Cardbus Adapter)
 
 pci:v0000115Dd0000000Bsv0000115Dsd00000183*
  ID_MODEL_FROM_DATABASE=Cardbus Ethernet 10/100
@@ -32685,7 +33696,7 @@ pci:v0000115Dd0000000F*
  ID_MODEL_FROM_DATABASE=Cardbus Ethernet 10/100
 
 pci:v0000115Dd0000000Fsv00001014sd00000183*
- ID_MODEL_FROM_DATABASE=10/100 EtherJet Cardbus Adapter
+ ID_MODEL_FROM_DATABASE=Cardbus Ethernet 10/100 (10/100 EtherJet Cardbus Adapter)
 
 pci:v0000115Dd0000000Fsv0000115Dsd00000183*
  ID_MODEL_FROM_DATABASE=Cardbus Ethernet 10/100
@@ -32697,22 +33708,22 @@ pci:v0000115Dd00000101*
  ID_MODEL_FROM_DATABASE=Cardbus 56k modem
 
 pci:v0000115Dd00000101sv0000115Dsd00001081*
- ID_MODEL_FROM_DATABASE=Cardbus 56k Modem
+ ID_MODEL_FROM_DATABASE=Cardbus 56k modem (Cardbus 56k Modem)
 
 pci:v0000115Dd00000103*
  ID_MODEL_FROM_DATABASE=Cardbus Ethernet + 56k Modem
 
 pci:v0000115Dd00000103sv00001014sd00009181*
- ID_MODEL_FROM_DATABASE=Cardbus 56k Modem
+ ID_MODEL_FROM_DATABASE=Cardbus Ethernet + 56k Modem (Cardbus 56k Modem)
 
 pci:v0000115Dd00000103sv00001115sd00001181*
- ID_MODEL_FROM_DATABASE=Cardbus Ethernet 100 + 56k Modem
+ ID_MODEL_FROM_DATABASE=Cardbus Ethernet + 56k Modem (Cardbus Ethernet 100 + 56k Modem)
 
 pci:v0000115Dd00000103sv0000115Dsd00001181*
- ID_MODEL_FROM_DATABASE=CBEM56G-100 Ethernet + 56k Modem
+ ID_MODEL_FROM_DATABASE=Cardbus Ethernet + 56k Modem (CBEM56G-100 Ethernet + 56k Modem)
 
 pci:v0000115Dd00000103sv00008086sd00009181*
- ID_MODEL_FROM_DATABASE=PRO/100 LAN + Modem56 CardBus
+ ID_MODEL_FROM_DATABASE=Cardbus Ethernet + 56k Modem (PRO/100 LAN + Modem56 CardBus)
 
 pci:v0000115E*
  ID_VENDOR_FROM_DATABASE=Peer Protocols Inc
@@ -32739,7 +33750,7 @@ pci:v00001163d00002000*
  ID_MODEL_FROM_DATABASE=Verite V2000/V2100/V2200
 
 pci:v00001163d00002000sv00001092sd00002000*
- ID_MODEL_FROM_DATABASE=Stealth II S220
+ ID_MODEL_FROM_DATABASE=Verite V2000/V2100/V2200 (Stealth II S220)
 
 pci:v00001164*
  ID_VENDOR_FROM_DATABASE=Advanced Peripherals Technologies
@@ -32820,7 +33831,7 @@ pci:v00001166d00000132*
  ID_MODEL_FROM_DATABASE=BCM5780 [HT2000] PCI-Express Bridge
 
 pci:v00001166d00000132sv00001166sd00000132*
- ID_MODEL_FROM_DATABASE=HT2000 PCI-Express bridge
+ ID_MODEL_FROM_DATABASE=BCM5780 [HT2000] PCI-Express Bridge (HT2000 PCI-Express bridge)
 
 pci:v00001166d00000140*
  ID_MODEL_FROM_DATABASE=HT2100 PCI-Express Bridge
@@ -32841,13 +33852,13 @@ pci:v00001166d00000201*
  ID_MODEL_FROM_DATABASE=CSB5 South Bridge
 
 pci:v00001166d00000201sv00004C53sd00001080*
- ID_MODEL_FROM_DATABASE=CT8 mainboard
+ ID_MODEL_FROM_DATABASE=CSB5 South Bridge (CT8 mainboard)
 
 pci:v00001166d00000203*
  ID_MODEL_FROM_DATABASE=CSB6 South Bridge
 
 pci:v00001166d00000203sv00001734sd00001012*
- ID_MODEL_FROM_DATABASE=PRIMERGY RX/TX series
+ ID_MODEL_FROM_DATABASE=CSB6 South Bridge (PRIMERGY RX/TX series)
 
 pci:v00001166d00000205*
  ID_MODEL_FROM_DATABASE=BCM5785 [HT1000] Legacy South Bridge
@@ -32859,37 +33870,37 @@ pci:v00001166d00000212*
  ID_MODEL_FROM_DATABASE=CSB5 IDE Controller
 
 pci:v00001166d00000212sv00001028sd0000014A*
- ID_MODEL_FROM_DATABASE=PowerEdge 1750
+ ID_MODEL_FROM_DATABASE=CSB5 IDE Controller (PowerEdge 1750)
 
 pci:v00001166d00000212sv00001028sd0000810B*
- ID_MODEL_FROM_DATABASE=PowerEdge 1650/2550
+ ID_MODEL_FROM_DATABASE=CSB5 IDE Controller (PowerEdge 1650/2550)
 
 pci:v00001166d00000212sv00004C53sd00001080*
- ID_MODEL_FROM_DATABASE=CT8 mainboard
+ ID_MODEL_FROM_DATABASE=CSB5 IDE Controller (CT8 mainboard)
 
 pci:v00001166d00000213*
  ID_MODEL_FROM_DATABASE=CSB6 RAID/IDE Controller
 
 pci:v00001166d00000213sv00001028sd00004134*
- ID_MODEL_FROM_DATABASE=PowerEdge 600SC
+ ID_MODEL_FROM_DATABASE=CSB6 RAID/IDE Controller (PowerEdge 600SC)
 
 pci:v00001166d00000213sv00001028sd0000C134*
- ID_MODEL_FROM_DATABASE=Poweredge SC600
+ ID_MODEL_FROM_DATABASE=CSB6 RAID/IDE Controller (Poweredge SC600)
 
 pci:v00001166d00000213sv00001734sd00001012*
- ID_MODEL_FROM_DATABASE=PRIMERGY RX/TX series onboard IDE
+ ID_MODEL_FROM_DATABASE=CSB6 RAID/IDE Controller (PRIMERGY RX/TX series onboard IDE)
 
 pci:v00001166d00000214*
  ID_MODEL_FROM_DATABASE=BCM5785 [HT1000] IDE
 
 pci:v00001166d00000214sv00001028sd00000205*
- ID_MODEL_FROM_DATABASE=PowerEdge 2970 HT1000 IDE
+ ID_MODEL_FROM_DATABASE=BCM5785 [HT1000] IDE (PowerEdge 2970 HT1000 IDE)
 
 pci:v00001166d00000217*
  ID_MODEL_FROM_DATABASE=CSB6 IDE Controller
 
 pci:v00001166d00000217sv00001028sd00004134*
- ID_MODEL_FROM_DATABASE=Poweredge SC600
+ ID_MODEL_FROM_DATABASE=CSB6 IDE Controller (Poweredge SC600)
 
 pci:v00001166d0000021B*
  ID_MODEL_FROM_DATABASE=HT1100 HD Audio
@@ -32898,22 +33909,22 @@ pci:v00001166d00000220*
  ID_MODEL_FROM_DATABASE=OSB4/CSB5 OHCI USB Controller
 
 pci:v00001166d00000220sv00004C53sd00001080*
- ID_MODEL_FROM_DATABASE=CT8 mainboard
+ ID_MODEL_FROM_DATABASE=OSB4/CSB5 OHCI USB Controller (CT8 mainboard)
 
 pci:v00001166d00000221*
  ID_MODEL_FROM_DATABASE=CSB6 OHCI USB Controller
 
 pci:v00001166d00000221sv00001734sd00001012*
- ID_MODEL_FROM_DATABASE=PRIMERGY RX/TX series onboard OHCI
+ ID_MODEL_FROM_DATABASE=CSB6 OHCI USB Controller (PRIMERGY RX/TX series onboard OHCI)
 
 pci:v00001166d00000223*
  ID_MODEL_FROM_DATABASE=BCM5785 [HT1000] USB
 
 pci:v00001166d00000223sv00001028sd00000205*
- ID_MODEL_FROM_DATABASE=PowerEdge 2970 HT1000 USB Controller
+ ID_MODEL_FROM_DATABASE=BCM5785 [HT1000] USB (PowerEdge 2970 HT1000 USB Controller)
 
 pci:v00001166d00000223sv00001028sd0000020B*
- ID_MODEL_FROM_DATABASE=PowerEdge T605 HT1000 USB Controller
+ ID_MODEL_FROM_DATABASE=BCM5785 [HT1000] USB (PowerEdge T605 HT1000 USB Controller)
 
 pci:v00001166d00000225*
  ID_MODEL_FROM_DATABASE=CSB5 LPC bridge
@@ -32922,22 +33933,22 @@ pci:v00001166d00000227*
  ID_MODEL_FROM_DATABASE=GCLE-2 Host Bridge
 
 pci:v00001166d00000227sv00001734sd00001012*
- ID_MODEL_FROM_DATABASE=PRIMERGY RX/TX series
+ ID_MODEL_FROM_DATABASE=GCLE-2 Host Bridge (PRIMERGY RX/TX series)
 
 pci:v00001166d00000230*
  ID_MODEL_FROM_DATABASE=CSB5 LPC bridge
 
 pci:v00001166d00000230sv00004C53sd00001080*
- ID_MODEL_FROM_DATABASE=CT8 mainboard
+ ID_MODEL_FROM_DATABASE=CSB5 LPC bridge (CT8 mainboard)
 
 pci:v00001166d00000234*
  ID_MODEL_FROM_DATABASE=BCM5785 [HT1000] LPC
 
 pci:v00001166d00000234sv00001028sd00000205*
- ID_MODEL_FROM_DATABASE=PowerEdge 2970 HT1000 LPC
+ ID_MODEL_FROM_DATABASE=BCM5785 [HT1000] LPC (PowerEdge 2970 HT1000 LPC)
 
 pci:v00001166d00000234sv00001028sd0000020B*
- ID_MODEL_FROM_DATABASE=PowerEdge T605 HT1000 LPC
+ ID_MODEL_FROM_DATABASE=BCM5785 [HT1000] LPC (PowerEdge T605 HT1000 LPC)
 
 pci:v00001166d00000235*
  ID_MODEL_FROM_DATABASE=BCM5785 [HT1000] XIOAPIC0-2
@@ -32958,13 +33969,13 @@ pci:v00001166d0000024A*
  ID_MODEL_FROM_DATABASE=BCM5785 [HT1000] SATA (Native SATA Mode)
 
 pci:v00001166d0000024Asv00001028sd0000020B*
- ID_MODEL_FROM_DATABASE=PowerEdge T605 onboard SATA Controller
+ ID_MODEL_FROM_DATABASE=BCM5785 [HT1000] SATA (Native SATA Mode) (PowerEdge T605 onboard SATA Controller)
 
 pci:v00001166d0000024B*
  ID_MODEL_FROM_DATABASE=BCM5785 [HT1000] SATA (PATA/IDE Mode)
 
 pci:v00001166d0000024Bsv00001028sd00000205*
- ID_MODEL_FROM_DATABASE=PowerEdge 2970 HT1000 SATA controller
+ ID_MODEL_FROM_DATABASE=BCM5785 [HT1000] SATA (PATA/IDE Mode) (PowerEdge 2970 HT1000 SATA controller)
 
 pci:v00001166d00000406*
  ID_MODEL_FROM_DATABASE=HT1100 PCI-X Bridge
@@ -32976,7 +33987,7 @@ pci:v00001166d0000040A*
  ID_MODEL_FROM_DATABASE=HT1100 ISA-LPC Bridge
 
 pci:v00001166d0000040Asv00001028sd00000223*
- ID_MODEL_FROM_DATABASE=PowerEdge R905 HT1100 ISA-LPC Bridge
+ ID_MODEL_FROM_DATABASE=HT1100 ISA-LPC Bridge (PowerEdge R905 HT1100 ISA-LPC Bridge)
 
 pci:v00001166d00000410*
  ID_MODEL_FROM_DATABASE=HT1100 SATA Controller (Native SATA Mode)
@@ -33093,7 +34104,7 @@ pci:v00001179d00000601*
  ID_MODEL_FROM_DATABASE=CPU to PCI bridge
 
 pci:v00001179d00000601sv00001179sd00000001*
- ID_MODEL_FROM_DATABASE=Satellite Pro
+ ID_MODEL_FROM_DATABASE=CPU to PCI bridge (Satellite Pro)
 
 pci:v00001179d00000602*
  ID_MODEL_FROM_DATABASE=PCI to ISA bridge
@@ -33108,13 +34119,13 @@ pci:v00001179d0000060A*
  ID_MODEL_FROM_DATABASE=ToPIC95
 
 pci:v00001179d0000060Asv00001179sd00000001*
- ID_MODEL_FROM_DATABASE=Satellite Pro
+ ID_MODEL_FROM_DATABASE=ToPIC95 (Satellite Pro)
 
 pci:v00001179d0000060F*
  ID_MODEL_FROM_DATABASE=ToPIC97
 
 pci:v00001179d0000060Fsv00001179sd00000001*
- ID_MODEL_FROM_DATABASE=Satellite 4010
+ ID_MODEL_FROM_DATABASE=ToPIC97 (Satellite 4010)
 
 pci:v00001179d00000617*
  ID_MODEL_FROM_DATABASE=ToPIC100 PCI to Cardbus Bridge with ZV Support
@@ -33156,16 +34167,16 @@ pci:v0000117Cd00000030*
  ID_MODEL_FROM_DATABASE=Ultra320 SCSI Host Adapter
 
 pci:v0000117Cd00000030sv0000117Csd00008013*
- ID_MODEL_FROM_DATABASE=ExpressPCI UL4D
+ ID_MODEL_FROM_DATABASE=Ultra320 SCSI Host Adapter (ExpressPCI UL4D)
 
 pci:v0000117Cd00000030sv0000117Csd00008014*
- ID_MODEL_FROM_DATABASE=ExpressPCI UL4S
+ ID_MODEL_FROM_DATABASE=Ultra320 SCSI Host Adapter (ExpressPCI UL4S)
 
 pci:v0000117Cd00000030sv0000117Csd00008027*
- ID_MODEL_FROM_DATABASE=ExpressPCI UL5D
+ ID_MODEL_FROM_DATABASE=Ultra320 SCSI Host Adapter (ExpressPCI UL5D)
 
 pci:v0000117Cd00000030sv0000117Csd0000802F*
- ID_MODEL_FROM_DATABASE=ExpressPCI UL5D Low Profile
+ ID_MODEL_FROM_DATABASE=Ultra320 SCSI Host Adapter (ExpressPCI UL5D Low Profile)
 
 pci:v0000117Cd00000033*
  ID_MODEL_FROM_DATABASE=SAS Adapter
@@ -33192,67 +34203,67 @@ pci:v00001180d00000475*
  ID_MODEL_FROM_DATABASE=RL5c475
 
 pci:v00001180d00000475sv0000144Dsd0000C006*
- ID_MODEL_FROM_DATABASE=vpr Matrix 170B4 CardBus bridge
+ ID_MODEL_FROM_DATABASE=RL5c475 (vpr Matrix 170B4 CardBus bridge)
 
 pci:v00001180d00000476*
  ID_MODEL_FROM_DATABASE=RL5c476 II
 
 pci:v00001180d00000476sv00001014sd00000185*
- ID_MODEL_FROM_DATABASE=ThinkPad A/T/X Series
+ ID_MODEL_FROM_DATABASE=RL5c476 II (ThinkPad A/T/X Series)
 
 pci:v00001180d00000476sv00001014sd0000056C*
- ID_MODEL_FROM_DATABASE=ThinkPad Z60t
+ ID_MODEL_FROM_DATABASE=RL5c476 II (ThinkPad Z60t)
 
 pci:v00001180d00000476sv00001028sd0000014F*
- ID_MODEL_FROM_DATABASE=Latitude X300 laptop
+ ID_MODEL_FROM_DATABASE=RL5c476 II (Latitude X300 laptop)
 
 pci:v00001180d00000476sv00001028sd00000188*
- ID_MODEL_FROM_DATABASE=Inspiron 6000 laptop
+ ID_MODEL_FROM_DATABASE=RL5c476 II (Inspiron 6000 laptop)
 
 pci:v00001180d00000476sv0000103Csd000030C0*
- ID_MODEL_FROM_DATABASE=Compaq 6710b
+ ID_MODEL_FROM_DATABASE=RL5c476 II (Compaq 6710b)
 
 pci:v00001180d00000476sv0000103Csd000030C1*
- ID_MODEL_FROM_DATABASE=Compaq 6910p
+ ID_MODEL_FROM_DATABASE=RL5c476 II (Compaq 6910p)
 
 pci:v00001180d00000476sv00001043sd00001237*
- ID_MODEL_FROM_DATABASE=A6J-Q008
+ ID_MODEL_FROM_DATABASE=RL5c476 II (A6J-Q008)
 
 pci:v00001180d00000476sv00001043sd00001967*
- ID_MODEL_FROM_DATABASE=V6800V
+ ID_MODEL_FROM_DATABASE=RL5c476 II (V6800V)
 
 pci:v00001180d00000476sv00001043sd00001987*
- ID_MODEL_FROM_DATABASE=Asus A4K and Z81K notebooks, possibly others ( mid-2005 machines )
+ ID_MODEL_FROM_DATABASE=RL5c476 II (Asus A4K and Z81K notebooks, possibly others ( mid-2005 machines ))
 
 pci:v00001180d00000476sv0000104Dsd000080DF*
- ID_MODEL_FROM_DATABASE=Vaio PCG-FX403
+ ID_MODEL_FROM_DATABASE=RL5c476 II (Vaio PCG-FX403)
 
 pci:v00001180d00000476sv0000104Dsd000080E7*
- ID_MODEL_FROM_DATABASE=VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
+ ID_MODEL_FROM_DATABASE=RL5c476 II (VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP)
 
 pci:v00001180d00000476sv0000104Dsd0000814E*
- ID_MODEL_FROM_DATABASE=VAIO GRZ390Z
+ ID_MODEL_FROM_DATABASE=RL5c476 II (VAIO GRZ390Z)
 
 pci:v00001180d00000476sv000010F7sd00008338*
- ID_MODEL_FROM_DATABASE=Panasonic CF-Y5 laptop
+ ID_MODEL_FROM_DATABASE=RL5c476 II (Panasonic CF-Y5 laptop)
 
 pci:v00001180d00000476sv0000144Dsd0000C005*
- ID_MODEL_FROM_DATABASE=X10 Laptop
+ ID_MODEL_FROM_DATABASE=RL5c476 II (X10 Laptop)
 
 pci:v00001180d00000476sv0000144Dsd0000C00C*
- ID_MODEL_FROM_DATABASE=P30/P35 notebook
+ ID_MODEL_FROM_DATABASE=RL5c476 II (P30/P35 notebook)
 
 pci:v00001180d00000476sv000014EFsd00000220*
- ID_MODEL_FROM_DATABASE=PCD-RP-220S
+ ID_MODEL_FROM_DATABASE=RL5c476 II (PCD-RP-220S)
 
 pci:v00001180d00000476sv000017AAsd0000201C*
- ID_MODEL_FROM_DATABASE=ThinkPad X60s
+ ID_MODEL_FROM_DATABASE=RL5c476 II (ThinkPad X60/X60s)
 
 pci:v00001180d00000476sv000017AAsd000020C4*
- ID_MODEL_FROM_DATABASE=ThinkPad T61
+ ID_MODEL_FROM_DATABASE=RL5c476 II (ThinkPad T61)
 
 pci:v00001180d00000476sv000017AAsd000020C6*
- ID_MODEL_FROM_DATABASE=ThinkPad R61
+ ID_MODEL_FROM_DATABASE=RL5c476 II (ThinkPad R61)
 
 pci:v00001180d00000477*
  ID_MODEL_FROM_DATABASE=RL5c477
@@ -33261,7 +34272,7 @@ pci:v00001180d00000478*
  ID_MODEL_FROM_DATABASE=RL5c478
 
 pci:v00001180d00000478sv00001014sd00000184*
- ID_MODEL_FROM_DATABASE=ThinkPad A30p
+ ID_MODEL_FROM_DATABASE=RL5c478 (ThinkPad A30p)
 
 pci:v00001180d00000511*
  ID_MODEL_FROM_DATABASE=R5C511
@@ -33270,43 +34281,43 @@ pci:v00001180d00000522*
  ID_MODEL_FROM_DATABASE=R5C522 IEEE 1394 Controller
 
 pci:v00001180d00000522sv00001014sd000001CF*
- ID_MODEL_FROM_DATABASE=ThinkPad A30p
+ ID_MODEL_FROM_DATABASE=R5C522 IEEE 1394 Controller (ThinkPad A30p)
 
 pci:v00001180d00000522sv00001043sd00001967*
- ID_MODEL_FROM_DATABASE=V6800V
+ ID_MODEL_FROM_DATABASE=R5C522 IEEE 1394 Controller (V6800V)
 
 pci:v00001180d00000551*
  ID_MODEL_FROM_DATABASE=R5C551 IEEE 1394 Controller
 
 pci:v00001180d00000551sv0000144Dsd0000C006*
- ID_MODEL_FROM_DATABASE=vpr Matrix 170B4
+ ID_MODEL_FROM_DATABASE=R5C551 IEEE 1394 Controller (vpr Matrix 170B4)
 
 pci:v00001180d00000552*
  ID_MODEL_FROM_DATABASE=R5C552 IEEE 1394 Controller
 
 pci:v00001180d00000552sv00001014sd00000511*
- ID_MODEL_FROM_DATABASE=ThinkPad A/T/X Series
+ ID_MODEL_FROM_DATABASE=R5C552 IEEE 1394 Controller (ThinkPad A/T/X Series)
 
 pci:v00001180d00000552sv00001028sd0000014F*
- ID_MODEL_FROM_DATABASE=Latitude X300 laptop
+ ID_MODEL_FROM_DATABASE=R5C552 IEEE 1394 Controller (Latitude X300 laptop)
 
 pci:v00001180d00000552sv00001028sd00000188*
- ID_MODEL_FROM_DATABASE=Inspiron 6000 laptop
+ ID_MODEL_FROM_DATABASE=R5C552 IEEE 1394 Controller (Inspiron 6000 laptop)
 
 pci:v00001180d00000552sv00001043sd00001237*
- ID_MODEL_FROM_DATABASE=A6J-Q008
+ ID_MODEL_FROM_DATABASE=R5C552 IEEE 1394 Controller (A6J-Q008)
 
 pci:v00001180d00000552sv00001043sd00001757*
- ID_MODEL_FROM_DATABASE=M2400N laptop
+ ID_MODEL_FROM_DATABASE=R5C552 IEEE 1394 Controller (M2400N laptop)
 
 pci:v00001180d00000552sv0000144Dsd0000C005*
- ID_MODEL_FROM_DATABASE=X10 Laptop
+ ID_MODEL_FROM_DATABASE=R5C552 IEEE 1394 Controller (X10 Laptop)
 
 pci:v00001180d00000552sv0000144Dsd0000C00C*
- ID_MODEL_FROM_DATABASE=P30/P35 notebook
+ ID_MODEL_FROM_DATABASE=R5C552 IEEE 1394 Controller (P30/P35 notebook)
 
 pci:v00001180d00000552sv000017AAsd0000201E*
- ID_MODEL_FROM_DATABASE=ThinkPad X60s
+ ID_MODEL_FROM_DATABASE=R5C552 IEEE 1394 Controller (ThinkPad X60/X60s)
 
 pci:v00001180d00000554*
  ID_MODEL_FROM_DATABASE=R5C554
@@ -33321,37 +34332,37 @@ pci:v00001180d00000592*
  ID_MODEL_FROM_DATABASE=R5C592 Memory Stick Bus Host Adapter
 
 pci:v00001180d00000592sv00001025sd00000121*
- ID_MODEL_FROM_DATABASE=Aspire 5920G
+ ID_MODEL_FROM_DATABASE=R5C592 Memory Stick Bus Host Adapter (Aspire 5920G)
 
 pci:v00001180d00000592sv00001028sd000001D7*
- ID_MODEL_FROM_DATABASE=XPS M1210
+ ID_MODEL_FROM_DATABASE=R5C592 Memory Stick Bus Host Adapter (XPS M1210)
 
 pci:v00001180d00000592sv00001028sd000001F3*
- ID_MODEL_FROM_DATABASE=Inspiron 1420
+ ID_MODEL_FROM_DATABASE=R5C592 Memory Stick Bus Host Adapter (Inspiron 1420)
 
 pci:v00001180d00000592sv0000103Csd000030B5*
- ID_MODEL_FROM_DATABASE=Presario V3242AU
+ ID_MODEL_FROM_DATABASE=R5C592 Memory Stick Bus Host Adapter (Presario V3242AU)
 
 pci:v00001180d00000592sv0000103Csd000030B7*
- ID_MODEL_FROM_DATABASE=Presario V6133CL
+ ID_MODEL_FROM_DATABASE=R5C592 Memory Stick Bus Host Adapter (Presario V6133CL)
 
 pci:v00001180d00000592sv0000103Csd000030CC*
- ID_MODEL_FROM_DATABASE=Pavilion dv6700
+ ID_MODEL_FROM_DATABASE=R5C592 Memory Stick Bus Host Adapter (Pavilion dv6700)
 
 pci:v00001180d00000592sv0000103Csd000030CF*
- ID_MODEL_FROM_DATABASE=Pavilion dv9668eg Laptop
+ ID_MODEL_FROM_DATABASE=R5C592 Memory Stick Bus Host Adapter (Pavilion dv9668eg Laptop)
 
 pci:v00001180d00000592sv00001043sd00001237*
- ID_MODEL_FROM_DATABASE=A6J-Q008
+ ID_MODEL_FROM_DATABASE=R5C592 Memory Stick Bus Host Adapter (A6J-Q008)
 
 pci:v00001180d00000592sv00001043sd00001967*
- ID_MODEL_FROM_DATABASE=V6800V
+ ID_MODEL_FROM_DATABASE=R5C592 Memory Stick Bus Host Adapter (V6800V)
 
 pci:v00001180d00000592sv0000144Dsd0000C018*
- ID_MODEL_FROM_DATABASE=X20 IV
+ ID_MODEL_FROM_DATABASE=R5C592 Memory Stick Bus Host Adapter (X20 IV)
 
 pci:v00001180d00000592sv000017AAsd000020CA*
- ID_MODEL_FROM_DATABASE=ThinkPad T61
+ ID_MODEL_FROM_DATABASE=R5C592 Memory Stick Bus Host Adapter (ThinkPad T61)
 
 pci:v00001180d00000811*
  ID_MODEL_FROM_DATABASE=R5C811
@@ -33360,91 +34371,94 @@ pci:v00001180d00000822*
  ID_MODEL_FROM_DATABASE=R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter
 
 pci:v00001180d00000822sv00001014sd00000556*
- ID_MODEL_FROM_DATABASE=ThinkPad X60s / Z60t
+ ID_MODEL_FROM_DATABASE=R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter (ThinkPad X60s / Z60t)
 
 pci:v00001180d00000822sv00001014sd00000598*
- ID_MODEL_FROM_DATABASE=ThinkPad Z60m
+ ID_MODEL_FROM_DATABASE=R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter (ThinkPad Z60m)
 
 pci:v00001180d00000822sv00001025sd00000121*
- ID_MODEL_FROM_DATABASE=Aspire 5920G
+ ID_MODEL_FROM_DATABASE=R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter (Aspire 5920G)
 
 pci:v00001180d00000822sv00001028sd00000188*
- ID_MODEL_FROM_DATABASE=Inspiron 6000 laptop
+ ID_MODEL_FROM_DATABASE=R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter (Inspiron 6000 laptop)
 
 pci:v00001180d00000822sv00001028sd000001A2*
- ID_MODEL_FROM_DATABASE=Inspiron 9200
+ ID_MODEL_FROM_DATABASE=R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter (Inspiron 9200)
 
 pci:v00001180d00000822sv00001028sd000001D7*
- ID_MODEL_FROM_DATABASE=XPS M1210
+ ID_MODEL_FROM_DATABASE=R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter (XPS M1210)
 
 pci:v00001180d00000822sv00001028sd000001F3*
- ID_MODEL_FROM_DATABASE=Inspiron 1420
+ ID_MODEL_FROM_DATABASE=R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter (Inspiron 1420)
 
 pci:v00001180d00000822sv0000103Csd000003B5*
- ID_MODEL_FROM_DATABASE=Presario V3242AU
+ ID_MODEL_FROM_DATABASE=R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter (Presario V3242AU)
 
 pci:v00001180d00000822sv0000103Csd000030B7*
- ID_MODEL_FROM_DATABASE=Presario V6133CL
+ ID_MODEL_FROM_DATABASE=R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter (Presario V6133CL)
 
 pci:v00001180d00000822sv0000103Csd000030C1*
- ID_MODEL_FROM_DATABASE=Compaq 6910p
+ ID_MODEL_FROM_DATABASE=R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter (Compaq 6910p)
 
 pci:v00001180d00000822sv0000103Csd000030CC*
- ID_MODEL_FROM_DATABASE=Pavilion dv6700
+ ID_MODEL_FROM_DATABASE=R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter (Pavilion dv6700)
 
 pci:v00001180d00000822sv0000103Csd000030CF*
- ID_MODEL_FROM_DATABASE=Pavilion dv9668eg Laptop
+ ID_MODEL_FROM_DATABASE=R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter (Pavilion dv9668eg Laptop)
 
 pci:v00001180d00000822sv00001043sd00001237*
- ID_MODEL_FROM_DATABASE=A6J-Q008
+ ID_MODEL_FROM_DATABASE=R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter (A6J-Q008)
 
 pci:v00001180d00000822sv00001043sd00001967*
- ID_MODEL_FROM_DATABASE=ASUS V6800V
+ ID_MODEL_FROM_DATABASE=R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter (ASUS V6800V)
 
 pci:v00001180d00000822sv000010F7sd00008338*
- ID_MODEL_FROM_DATABASE=Panasonic CF-Y5 laptop
+ ID_MODEL_FROM_DATABASE=R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter (Panasonic CF-Y5 laptop)
 
 pci:v00001180d00000822sv0000144Dsd0000C018*
- ID_MODEL_FROM_DATABASE=X20 IV
+ ID_MODEL_FROM_DATABASE=R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter (X20 IV)
 
 pci:v00001180d00000822sv000017AAsd0000201D*
- ID_MODEL_FROM_DATABASE=ThinkPad X60s
+ ID_MODEL_FROM_DATABASE=R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter (ThinkPad X60/X60s)
 
 pci:v00001180d00000822sv000017AAsd000020C7*
- ID_MODEL_FROM_DATABASE=ThinkPad T61
+ ID_MODEL_FROM_DATABASE=R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter (ThinkPad T61)
 
 pci:v00001180d00000822sv000017AAsd000020C8*
- ID_MODEL_FROM_DATABASE=ThinkPad W500
+ ID_MODEL_FROM_DATABASE=R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter (ThinkPad W500)
 
 pci:v00001180d00000832*
  ID_MODEL_FROM_DATABASE=R5C832 IEEE 1394 Controller
 
 pci:v00001180d00000832sv00001025sd00000121*
- ID_MODEL_FROM_DATABASE=Aspire 5920G
+ ID_MODEL_FROM_DATABASE=R5C832 IEEE 1394 Controller (Aspire 5920G)
 
 pci:v00001180d00000832sv00001028sd000001D7*
- ID_MODEL_FROM_DATABASE=XPS M1210
+ ID_MODEL_FROM_DATABASE=R5C832 IEEE 1394 Controller (XPS M1210)
 
 pci:v00001180d00000832sv00001028sd000001F3*
- ID_MODEL_FROM_DATABASE=Inspiron 1420
+ ID_MODEL_FROM_DATABASE=R5C832 IEEE 1394 Controller (Inspiron 1420)
+
+pci:v00001180d00000832sv00001028sd0000024D*
+ ID_MODEL_FROM_DATABASE=R5C832 IEEE 1394 Controller (Latitude E4300)
 
 pci:v00001180d00000832sv0000103Csd000030B5*
- ID_MODEL_FROM_DATABASE=Presario V3242AU
+ ID_MODEL_FROM_DATABASE=R5C832 IEEE 1394 Controller (Presario V3242AU)
 
 pci:v00001180d00000832sv0000103Csd000030B7*
- ID_MODEL_FROM_DATABASE=Presario V6133CL
+ ID_MODEL_FROM_DATABASE=R5C832 IEEE 1394 Controller (Presario V6133CL)
 
 pci:v00001180d00000832sv0000103Csd000030C1*
- ID_MODEL_FROM_DATABASE=Compaq 6910p
+ ID_MODEL_FROM_DATABASE=R5C832 IEEE 1394 Controller (Compaq 6910p)
 
 pci:v00001180d00000832sv0000103Csd000030CC*
- ID_MODEL_FROM_DATABASE=Pavilion dv6700
+ ID_MODEL_FROM_DATABASE=R5C832 IEEE 1394 Controller (Pavilion dv6700)
 
 pci:v00001180d00000832sv0000103Csd000030CF*
- ID_MODEL_FROM_DATABASE=Pavilion dv9668eg Laptop
+ ID_MODEL_FROM_DATABASE=R5C832 IEEE 1394 Controller (Pavilion dv9668eg Laptop)
 
 pci:v00001180d00000832sv000017AAsd000020C7*
- ID_MODEL_FROM_DATABASE=ThinkPad R61
+ ID_MODEL_FROM_DATABASE=R5C832 IEEE 1394 Controller (ThinkPad R61)
 
 pci:v00001180d00000841*
  ID_MODEL_FROM_DATABASE=R5C841 CardBus/SD/SDIO/MMC/MS/MSPro/xD/IEEE1394
@@ -33453,58 +34467,58 @@ pci:v00001180d00000843*
  ID_MODEL_FROM_DATABASE=R5C843 MMC Host Controller
 
 pci:v00001180d00000843sv00001025sd00000121*
- ID_MODEL_FROM_DATABASE=Aspire 5920G
+ ID_MODEL_FROM_DATABASE=R5C843 MMC Host Controller (Aspire 5920G)
 
 pci:v00001180d00000843sv00001028sd000001D7*
- ID_MODEL_FROM_DATABASE=XPS M1210
+ ID_MODEL_FROM_DATABASE=R5C843 MMC Host Controller (XPS M1210)
 
 pci:v00001180d00000843sv00001028sd000001F3*
- ID_MODEL_FROM_DATABASE=Inspiron 1420
+ ID_MODEL_FROM_DATABASE=R5C843 MMC Host Controller (Inspiron 1420)
 
 pci:v00001180d00000843sv00001028sd000001F5*
- ID_MODEL_FROM_DATABASE=Dell Inspiron 1501
+ ID_MODEL_FROM_DATABASE=R5C843 MMC Host Controller (Dell Inspiron 1501)
 
 pci:v00001180d00000843sv00001028sd0000024F*
- ID_MODEL_FROM_DATABASE=Dell Latitude e6500
+ ID_MODEL_FROM_DATABASE=R5C843 MMC Host Controller (Dell Latitude e6500)
 
 pci:v00001180d00000843sv0000103Csd000003B5*
- ID_MODEL_FROM_DATABASE=Presario V3242AU
+ ID_MODEL_FROM_DATABASE=R5C843 MMC Host Controller (Presario V3242AU)
 
 pci:v00001180d00000843sv0000103Csd000030B7*
- ID_MODEL_FROM_DATABASE=Presario V6133CL
+ ID_MODEL_FROM_DATABASE=R5C843 MMC Host Controller (Presario V6133CL)
 
 pci:v00001180d00000843sv00001183sd00000843*
- ID_MODEL_FROM_DATABASE=Alienware Aurora m9700
+ ID_MODEL_FROM_DATABASE=R5C843 MMC Host Controller (Alienware Aurora m9700)
 
 pci:v00001180d00000852*
  ID_MODEL_FROM_DATABASE=xD-Picture Card Controller
 
 pci:v00001180d00000852sv00001025sd00000121*
- ID_MODEL_FROM_DATABASE=Aspire 5920G
+ ID_MODEL_FROM_DATABASE=xD-Picture Card Controller (Aspire 5920G)
 
 pci:v00001180d00000852sv00001028sd000001F3*
- ID_MODEL_FROM_DATABASE=Inspiron 1420
+ ID_MODEL_FROM_DATABASE=xD-Picture Card Controller (Inspiron 1420)
 
 pci:v00001180d00000852sv0000103Csd000030B5*
- ID_MODEL_FROM_DATABASE=Presario V3242AU
+ ID_MODEL_FROM_DATABASE=xD-Picture Card Controller (Presario V3242AU)
 
 pci:v00001180d00000852sv0000103Csd000030B7*
- ID_MODEL_FROM_DATABASE=Presario V6133CL
+ ID_MODEL_FROM_DATABASE=xD-Picture Card Controller (Presario V6133CL)
 
 pci:v00001180d00000852sv0000103Csd000030CC*
- ID_MODEL_FROM_DATABASE=Pavilion dv6700
+ ID_MODEL_FROM_DATABASE=xD-Picture Card Controller (Pavilion dv6700)
 
 pci:v00001180d00000852sv0000103Csd000030CF*
- ID_MODEL_FROM_DATABASE=Pavilion dv9668eg Laptop
+ ID_MODEL_FROM_DATABASE=xD-Picture Card Controller (Pavilion dv9668eg Laptop)
 
 pci:v00001180d00000852sv00001043sd00001967*
- ID_MODEL_FROM_DATABASE=V6800V
+ ID_MODEL_FROM_DATABASE=xD-Picture Card Controller (V6800V)
 
 pci:v00001180d00000852sv00001180sd00000852*
- ID_MODEL_FROM_DATABASE=Pavilion 2410us
+ ID_MODEL_FROM_DATABASE=xD-Picture Card Controller (Pavilion 2410us)
 
 pci:v00001180d00000852sv00001324sd000010CF*
- ID_MODEL_FROM_DATABASE=P7120
+ ID_MODEL_FROM_DATABASE=xD-Picture Card Controller (P7120)
 
 pci:v00001180d0000E230*
  ID_MODEL_FROM_DATABASE=R5U2xx (R5U230 / R5U231 / R5U241) [Memory Stick Host Controller]
@@ -33513,19 +34527,19 @@ pci:v00001180d0000E476*
  ID_MODEL_FROM_DATABASE=CardBus bridge
 
 pci:v00001180d0000E476sv00001028sd0000040A*
- ID_MODEL_FROM_DATABASE=Latitude E6410
+ ID_MODEL_FROM_DATABASE=CardBus bridge (Latitude E6410)
 
 pci:v00001180d0000E476sv00001028sd0000040B*
- ID_MODEL_FROM_DATABASE=Latitude E6510
+ ID_MODEL_FROM_DATABASE=CardBus bridge (Latitude E6510)
 
 pci:v00001180d0000E822*
  ID_MODEL_FROM_DATABASE=MMC/SD Host Controller
 
 pci:v00001180d0000E822sv00001028sd0000040A*
- ID_MODEL_FROM_DATABASE=Latitude E6410
+ ID_MODEL_FROM_DATABASE=MMC/SD Host Controller (Latitude E6410)
 
 pci:v00001180d0000E822sv00001028sd0000040B*
- ID_MODEL_FROM_DATABASE=Latitude E6510
+ ID_MODEL_FROM_DATABASE=MMC/SD Host Controller (Latitude E6510)
 
 pci:v00001180d0000E823*
  ID_MODEL_FROM_DATABASE=PCIe SDXC/MMC Host Controller
@@ -33534,10 +34548,10 @@ pci:v00001180d0000E832*
  ID_MODEL_FROM_DATABASE=R5C832 PCIe IEEE 1394 Controller
 
 pci:v00001180d0000E832sv00001028sd0000040A*
- ID_MODEL_FROM_DATABASE=Latitude E6410
+ ID_MODEL_FROM_DATABASE=R5C832 PCIe IEEE 1394 Controller (Latitude E6410)
 
 pci:v00001180d0000E832sv00001028sd0000040B*
- ID_MODEL_FROM_DATABASE=Latitude E6510
+ ID_MODEL_FROM_DATABASE=R5C832 PCIe IEEE 1394 Controller (Latitude E6510)
 
 pci:v00001180d0000E852*
  ID_MODEL_FROM_DATABASE=PCIe xD-Picture Card Controller
@@ -33561,10 +34575,10 @@ pci:v00001186d00001002*
  ID_MODEL_FROM_DATABASE=DL10050 Sundance Ethernet
 
 pci:v00001186d00001002sv00001186sd00001002*
- ID_MODEL_FROM_DATABASE=DFE-550TX/FX
+ ID_MODEL_FROM_DATABASE=DL10050 Sundance Ethernet (DFE-550TX/FX)
 
 pci:v00001186d00001002sv00001186sd00001012*
- ID_MODEL_FROM_DATABASE=DFE-580TX
+ ID_MODEL_FROM_DATABASE=DL10050 Sundance Ethernet (DFE-580TX)
 
 pci:v00001186d00001025*
  ID_MODEL_FROM_DATABASE=AirPlus Xtreme G DWL-G650 Adapter
@@ -33579,13 +34593,13 @@ pci:v00001186d00001300*
  ID_MODEL_FROM_DATABASE=RTL8139 Ethernet
 
 pci:v00001186d00001300sv00001186sd00001300*
- ID_MODEL_FROM_DATABASE=DFE-538TX 10/100 Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=RTL8139 Ethernet (DFE-538TX 10/100 Ethernet Adapter)
 
 pci:v00001186d00001300sv00001186sd00001301*
- ID_MODEL_FROM_DATABASE=DFE-530TX+ 10/100 Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=RTL8139 Ethernet (DFE-530TX+ 10/100 Ethernet Adapter)
 
 pci:v00001186d00001300sv00001186sd00001303*
- ID_MODEL_FROM_DATABASE=DFE-528TX 10/100 Fast Ethernet PCI Adapter
+ ID_MODEL_FROM_DATABASE=RTL8139 Ethernet (DFE-528TX 10/100 Fast Ethernet PCI Adapter)
 
 pci:v00001186d00001340*
  ID_MODEL_FROM_DATABASE=DFE-690TXD CardBus PC Card
@@ -33603,10 +34617,10 @@ pci:v00001186d00003300*
  ID_MODEL_FROM_DATABASE=DWL-510 / DWL-610 802.11b [Realtek RTL8180L]
 
 pci:v00001186d00003300sv00001186sd00003300*
- ID_MODEL_FROM_DATABASE=DWL-610 Wireless Cardbus Adapter
+ ID_MODEL_FROM_DATABASE=DWL-510 / DWL-610 802.11b [Realtek RTL8180L] (DWL-610 Wireless Cardbus Adapter)
 
 pci:v00001186d00003300sv00001186sd00003301*
- ID_MODEL_FROM_DATABASE=DWL-510 Wireless PCI Adapter
+ ID_MODEL_FROM_DATABASE=DWL-510 / DWL-610 802.11b [Realtek RTL8180L] (DWL-510 Wireless PCI Adapter)
 
 pci:v00001186d00003A10*
  ID_MODEL_FROM_DATABASE=AirXpert DWL-AG650 Wireless Cardbus Adapter(rev.B)
@@ -33624,7 +34638,7 @@ pci:v00001186d00004300*
  ID_MODEL_FROM_DATABASE=DGE-528T Gigabit Ethernet Adapter
 
 pci:v00001186d00004300sv00001186sd00004B10*
- ID_MODEL_FROM_DATABASE=DGE-560T PCI Express (x1) Gigabit Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=DGE-528T Gigabit Ethernet Adapter (DGE-560T PCI Express (x1) Gigabit Ethernet Adapter)
 
 pci:v00001186d00004302*
  ID_MODEL_FROM_DATABASE=DGE-530T Gigabit Ethernet Adapter (rev.C1) [Realtek RTL8169]
@@ -33645,7 +34659,7 @@ pci:v00001186d00004C00*
  ID_MODEL_FROM_DATABASE=Gigabit Ethernet Adapter
 
 pci:v00001186d00004C00sv00001186sd00004C00*
- ID_MODEL_FROM_DATABASE=DGE-530T Gigabit Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=Gigabit Ethernet Adapter (DGE-530T Gigabit Ethernet Adapter)
 
 pci:v00001186d00008400*
  ID_MODEL_FROM_DATABASE=D-Link DWL-650+ CardBus PC Card
@@ -33927,7 +34941,7 @@ pci:v000011ABd00001FA6*
  ID_MODEL_FROM_DATABASE=Marvell W8300 802.11 Adapter
 
 pci:v000011ABd00001FA6sv00001186sd00003B08*
- ID_MODEL_FROM_DATABASE=AirPlus G DWL-G630 Wireless Cardbus Adapter (rev.A1)
+ ID_MODEL_FROM_DATABASE=Marvell W8300 802.11 Adapter (AirPlus G DWL-G630 Wireless Cardbus Adapter (rev.A1))
 
 pci:v000011ABd00001FA7*
  ID_MODEL_FROM_DATABASE=88W8310 and 88W8000G [Libertas] 802.11g client chipset
@@ -33936,13 +34950,13 @@ pci:v000011ABd00001FAA*
  ID_MODEL_FROM_DATABASE=88w8335 [Libertas] 802.11b/g Wireless
 
 pci:v000011ABd00001FAAsv00001385sd00004E00*
- ID_MODEL_FROM_DATABASE=WG511v2 54 Mbps Wireless PC Card
+ ID_MODEL_FROM_DATABASE=88w8335 [Libertas] 802.11b/g Wireless (WG511v2 54 Mbps Wireless PC Card)
 
 pci:v000011ABd00001FAAsv00001385sd00006B00*
- ID_MODEL_FROM_DATABASE=WG311v3 802.11g Wireless PCI Adapter
+ ID_MODEL_FROM_DATABASE=88w8335 [Libertas] 802.11b/g Wireless (WG311v3 802.11g Wireless PCI Adapter)
 
 pci:v000011ABd00001FAAsv00001737sd00000040*
- ID_MODEL_FROM_DATABASE=WPC54G v5 802.11g Wireless-G Notebook Adapter
+ ID_MODEL_FROM_DATABASE=88w8335 [Libertas] 802.11b/g Wireless (WPC54G v5 802.11g Wireless-G Notebook Adapter)
 
 pci:v000011ABd00002211*
  ID_MODEL_FROM_DATABASE=88SB2211 PCI Express to PCI Bridge
@@ -33954,19 +34968,19 @@ pci:v000011ABd00002A02*
  ID_MODEL_FROM_DATABASE=88W8361 [TopDog] 802.11n Wireless
 
 pci:v000011ABd00002A02sv000007D1sd00003B02*
- ID_MODEL_FROM_DATABASE=DIR-615 rev. A1 Mini PCI Wireless Module
+ ID_MODEL_FROM_DATABASE=88W8361 [TopDog] 802.11n Wireless (DIR-615 rev. A1 Mini PCI Wireless Module)
 
 pci:v000011ABd00002A02sv00001385sd00007C00*
- ID_MODEL_FROM_DATABASE=WN511T RangeMax Next 300 Mbps Wireless PC Card
+ ID_MODEL_FROM_DATABASE=88W8361 [TopDog] 802.11n Wireless (WN511T RangeMax Next 300 Mbps Wireless PC Card)
 
 pci:v000011ABd00002A02sv00001385sd00007C01*
- ID_MODEL_FROM_DATABASE=WN511T RangeMax Next 300 Mbps Wireless Notebook Adapter
+ ID_MODEL_FROM_DATABASE=88W8361 [TopDog] 802.11n Wireless (WN511T RangeMax Next 300 Mbps Wireless Notebook Adapter)
 
 pci:v000011ABd00002A02sv00001385sd00007E00*
- ID_MODEL_FROM_DATABASE=WN311T RangeMax Next 300 Mbps Wireless PCI Adapter
+ ID_MODEL_FROM_DATABASE=88W8361 [TopDog] 802.11n Wireless (WN311T RangeMax Next 300 Mbps Wireless PCI Adapter)
 
 pci:v000011ABd00002A02sv00001799sd0000801B*
- ID_MODEL_FROM_DATABASE=F5D8011 v2 802.11n N1 Wireless Notebook Card
+ ID_MODEL_FROM_DATABASE=88W8361 [TopDog] 802.11n Wireless (F5D8011 v2 802.11n N1 Wireless Notebook Card)
 
 pci:v000011ABd00002A08*
  ID_MODEL_FROM_DATABASE=88W8362e [TopDog] 802.11a/b/g/n Wireless
@@ -33998,6 +35012,9 @@ pci:v000011ABd00002A42*
 pci:v000011ABd00002A43*
  ID_MODEL_FROM_DATABASE=88W8366 [TopDog] 802.11n Wireless
 
+pci:v000011ABd00002A55*
+ ID_MODEL_FROM_DATABASE=88W8864 [Avastar] 802.11ac Wireless
+
 pci:v000011ABd00002B36*
  ID_MODEL_FROM_DATABASE=88W8764 [Avastar] 802.11n Wireless
 
@@ -34008,58 +35025,58 @@ pci:v000011ABd00004320*
  ID_MODEL_FROM_DATABASE=88E8001 Gigabit Ethernet Controller
 
 pci:v000011ABd00004320sv00001019sd00000F38*
- ID_MODEL_FROM_DATABASE=Marvell 88E8001 Gigabit Ethernet Controller (ECS)
+ ID_MODEL_FROM_DATABASE=88E8001 Gigabit Ethernet Controller (Marvell 88E8001 Gigabit Ethernet Controller (ECS))
 
 pci:v000011ABd00004320sv00001019sd00008001*
- ID_MODEL_FROM_DATABASE=Marvell 88E8001 Gigabit Ethernet Controller (ECS)
+ ID_MODEL_FROM_DATABASE=88E8001 Gigabit Ethernet Controller (Marvell 88E8001 Gigabit Ethernet Controller (ECS))
 
 pci:v000011ABd00004320sv00001043sd0000173C*
- ID_MODEL_FROM_DATABASE=Marvell 88E8001 Gigabit Ethernet Controller (Asus)
+ ID_MODEL_FROM_DATABASE=88E8001 Gigabit Ethernet Controller (Marvell 88E8001 Gigabit Ethernet Controller (Asus))
 
 pci:v000011ABd00004320sv00001043sd0000811A*
- ID_MODEL_FROM_DATABASE=Marvell 88E8001 Gigabit Ethernet Controller (Asus)
+ ID_MODEL_FROM_DATABASE=88E8001 Gigabit Ethernet Controller (Marvell 88E8001 Gigabit Ethernet Controller (Asus))
 
 pci:v000011ABd00004320sv0000105Bsd00000C19*
- ID_MODEL_FROM_DATABASE=Marvell 88E8001 Gigabit Ethernet Controller (Foxconn)
+ ID_MODEL_FROM_DATABASE=88E8001 Gigabit Ethernet Controller (Marvell 88E8001 Gigabit Ethernet Controller (Foxconn))
 
 pci:v000011ABd00004320sv000010B8sd0000B452*
- ID_MODEL_FROM_DATABASE=EZ Card 1000 (SMC9452TXV.2)
+ ID_MODEL_FROM_DATABASE=88E8001 Gigabit Ethernet Controller (EZ Card 1000 (SMC9452TXV.2))
 
 pci:v000011ABd00004320sv000011ABsd00000121*
- ID_MODEL_FROM_DATABASE=Marvell RDK-8001
+ ID_MODEL_FROM_DATABASE=88E8001 Gigabit Ethernet Controller (Marvell RDK-8001)
 
 pci:v000011ABd00004320sv000011ABsd00000321*
- ID_MODEL_FROM_DATABASE=Marvell RDK-8003
+ ID_MODEL_FROM_DATABASE=88E8001 Gigabit Ethernet Controller (Marvell RDK-8003)
 
 pci:v000011ABd00004320sv000011ABsd00001021*
- ID_MODEL_FROM_DATABASE=Marvell RDK-8010
+ ID_MODEL_FROM_DATABASE=88E8001 Gigabit Ethernet Controller (Marvell RDK-8010)
 
 pci:v000011ABd00004320sv000011ABsd00004320*
- ID_MODEL_FROM_DATABASE=Marvell Yukon Gigabit Ethernet 10/100/1000Baset-T Constroller (Asus)
+ ID_MODEL_FROM_DATABASE=88E8001 Gigabit Ethernet Controller (Marvell Yukon Gigabit Ethernet 10/100/1000Baset-T Constroller (Asus))
 
 pci:v000011ABd00004320sv000011ABsd00005021*
- ID_MODEL_FROM_DATABASE=Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Controller (64 bit)
+ ID_MODEL_FROM_DATABASE=88E8001 Gigabit Ethernet Controller (Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Controller (64 bit))
 
 pci:v000011ABd00004320sv000011ABsd00009521*
- ID_MODEL_FROM_DATABASE=Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Controller (32 bit)
+ ID_MODEL_FROM_DATABASE=88E8001 Gigabit Ethernet Controller (Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Controller (32 bit))
 
 pci:v000011ABd00004320sv00001458sd0000E000*
- ID_MODEL_FROM_DATABASE=Marvell 88E8001 Gigabit Ethernet Controller (Gigabyte)
+ ID_MODEL_FROM_DATABASE=88E8001 Gigabit Ethernet Controller (Marvell 88E8001 Gigabit Ethernet Controller (Gigabyte))
 
 pci:v000011ABd00004320sv0000147Bsd00001406*
- ID_MODEL_FROM_DATABASE=Marvell 88E8001 Gigabit Ethernet Controller (Abit)
+ ID_MODEL_FROM_DATABASE=88E8001 Gigabit Ethernet Controller (Marvell 88E8001 Gigabit Ethernet Controller (Abit))
 
 pci:v000011ABd00004320sv000015D4sd00000047*
- ID_MODEL_FROM_DATABASE=Marvell 88E8001 Gigabit Ethernet Controller (Iwill)
+ ID_MODEL_FROM_DATABASE=88E8001 Gigabit Ethernet Controller (Marvell 88E8001 Gigabit Ethernet Controller (Iwill))
 
 pci:v000011ABd00004320sv00001695sd00009025*
- ID_MODEL_FROM_DATABASE=Marvell 88E8001 Gigabit Ethernet Controller (Epox)
+ ID_MODEL_FROM_DATABASE=88E8001 Gigabit Ethernet Controller (Marvell 88E8001 Gigabit Ethernet Controller (Epox))
 
 pci:v000011ABd00004320sv000017F2sd00001C03*
- ID_MODEL_FROM_DATABASE=Marvell 88E8001 Gigabit Ethernet Controller (Albatron)
+ ID_MODEL_FROM_DATABASE=88E8001 Gigabit Ethernet Controller (Marvell 88E8001 Gigabit Ethernet Controller (Albatron))
 
 pci:v000011ABd00004320sv0000270Fsd00002803*
- ID_MODEL_FROM_DATABASE=Marvell 88E8001 Gigabit Ethernet Controller (Chaintech)
+ ID_MODEL_FROM_DATABASE=88E8001 Gigabit Ethernet Controller (Marvell 88E8001 Gigabit Ethernet Controller (Chaintech))
 
 pci:v000011ABd00004340*
  ID_MODEL_FROM_DATABASE=88E8021 PCI-X IPMI Gigabit Ethernet Controller
@@ -34086,115 +35103,115 @@ pci:v000011ABd00004347*
  ID_MODEL_FROM_DATABASE=88E8062 PCI-E IPMI Gigabit Ethernet Controller
 
 pci:v000011ABd00004347sv00004C53sd000010D0*
- ID_MODEL_FROM_DATABASE=Telum ASLP10 PrAMC Gigabit Ethernet
+ ID_MODEL_FROM_DATABASE=88E8062 PCI-E IPMI Gigabit Ethernet Controller (Telum ASLP10 PrAMC Gigabit Ethernet)
 
 pci:v000011ABd00004350*
  ID_MODEL_FROM_DATABASE=88E8035 PCI-E Fast Ethernet Controller
 
 pci:v000011ABd00004350sv00001179sd00000001*
- ID_MODEL_FROM_DATABASE=Marvell 88E8035 Fast Ethernet Controller (Toshiba)
+ ID_MODEL_FROM_DATABASE=88E8035 PCI-E Fast Ethernet Controller (Marvell 88E8035 Fast Ethernet Controller (Toshiba))
 
 pci:v000011ABd00004350sv000011ABsd00003521*
- ID_MODEL_FROM_DATABASE=Marvell RDK-8035
+ ID_MODEL_FROM_DATABASE=88E8035 PCI-E Fast Ethernet Controller (Marvell RDK-8035)
 
 pci:v000011ABd00004350sv00001854sd0000000D*
- ID_MODEL_FROM_DATABASE=Marvell 88E8035 Fast Ethernet Controller (LGE)
+ ID_MODEL_FROM_DATABASE=88E8035 PCI-E Fast Ethernet Controller (Marvell 88E8035 Fast Ethernet Controller (LGE))
 
 pci:v000011ABd00004350sv00001854sd0000000E*
- ID_MODEL_FROM_DATABASE=Marvell 88E8035 Fast Ethernet Controller (LGE)
+ ID_MODEL_FROM_DATABASE=88E8035 PCI-E Fast Ethernet Controller (Marvell 88E8035 Fast Ethernet Controller (LGE))
 
 pci:v000011ABd00004350sv00001854sd0000000F*
- ID_MODEL_FROM_DATABASE=Marvell 88E8035 Fast Ethernet Controller (LGE)
+ ID_MODEL_FROM_DATABASE=88E8035 PCI-E Fast Ethernet Controller (Marvell 88E8035 Fast Ethernet Controller (LGE))
 
 pci:v000011ABd00004350sv00001854sd00000011*
- ID_MODEL_FROM_DATABASE=Marvell 88E8035 Fast Ethernet Controller (LGE)
+ ID_MODEL_FROM_DATABASE=88E8035 PCI-E Fast Ethernet Controller (Marvell 88E8035 Fast Ethernet Controller (LGE))
 
 pci:v000011ABd00004350sv00001854sd00000012*
- ID_MODEL_FROM_DATABASE=Marvell 88E8035 Fast Ethernet Controller (LGE)
+ ID_MODEL_FROM_DATABASE=88E8035 PCI-E Fast Ethernet Controller (Marvell 88E8035 Fast Ethernet Controller (LGE))
 
 pci:v000011ABd00004350sv00001854sd00000016*
- ID_MODEL_FROM_DATABASE=Marvell 88E8035 Fast Ethernet Controller (LGE)
+ ID_MODEL_FROM_DATABASE=88E8035 PCI-E Fast Ethernet Controller (Marvell 88E8035 Fast Ethernet Controller (LGE))
 
 pci:v000011ABd00004350sv00001854sd00000017*
- ID_MODEL_FROM_DATABASE=Marvell 88E8035 Fast Ethernet Controller (LGE)
+ ID_MODEL_FROM_DATABASE=88E8035 PCI-E Fast Ethernet Controller (Marvell 88E8035 Fast Ethernet Controller (LGE))
 
 pci:v000011ABd00004350sv00001854sd00000018*
- ID_MODEL_FROM_DATABASE=Marvell 88E8035 Fast Ethernet Controller (LGE)
+ ID_MODEL_FROM_DATABASE=88E8035 PCI-E Fast Ethernet Controller (Marvell 88E8035 Fast Ethernet Controller (LGE))
 
 pci:v000011ABd00004350sv00001854sd00000019*
- ID_MODEL_FROM_DATABASE=Marvell 88E8035 Fast Ethernet Controller (LGE)
+ ID_MODEL_FROM_DATABASE=88E8035 PCI-E Fast Ethernet Controller (Marvell 88E8035 Fast Ethernet Controller (LGE))
 
 pci:v000011ABd00004350sv00001854sd0000001C*
- ID_MODEL_FROM_DATABASE=Marvell 88E8035 Fast Ethernet Controller (LGE)
+ ID_MODEL_FROM_DATABASE=88E8035 PCI-E Fast Ethernet Controller (Marvell 88E8035 Fast Ethernet Controller (LGE))
 
 pci:v000011ABd00004350sv00001854sd0000001E*
- ID_MODEL_FROM_DATABASE=Marvell 88E8035 Fast Ethernet Controller (LGE)
+ ID_MODEL_FROM_DATABASE=88E8035 PCI-E Fast Ethernet Controller (Marvell 88E8035 Fast Ethernet Controller (LGE))
 
 pci:v000011ABd00004350sv00001854sd00000020*
- ID_MODEL_FROM_DATABASE=Marvell 88E8035 Fast Ethernet Controller (LGE)
+ ID_MODEL_FROM_DATABASE=88E8035 PCI-E Fast Ethernet Controller (Marvell 88E8035 Fast Ethernet Controller (LGE))
 
 pci:v000011ABd00004351*
  ID_MODEL_FROM_DATABASE=88E8036 PCI-E Fast Ethernet Controller
 
 pci:v000011ABd00004351sv0000107Bsd00004009*
- ID_MODEL_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (Wistron)
+ ID_MODEL_FROM_DATABASE=88E8036 PCI-E Fast Ethernet Controller (Marvell 88E8036 Fast Ethernet Controller (Wistron))
 
 pci:v000011ABd00004351sv000010F7sd00008338*
- ID_MODEL_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (Panasonic)
+ ID_MODEL_FROM_DATABASE=88E8036 PCI-E Fast Ethernet Controller (Marvell 88E8036 Fast Ethernet Controller (Panasonic))
 
 pci:v000011ABd00004351sv00001179sd00000001*
- ID_MODEL_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (Toshiba)
+ ID_MODEL_FROM_DATABASE=88E8036 PCI-E Fast Ethernet Controller (Marvell 88E8036 Fast Ethernet Controller (Toshiba))
 
 pci:v000011ABd00004351sv00001179sd0000FF00*
- ID_MODEL_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (Compal)
+ ID_MODEL_FROM_DATABASE=88E8036 PCI-E Fast Ethernet Controller (Marvell 88E8036 Fast Ethernet Controller (Compal))
 
 pci:v000011ABd00004351sv00001179sd0000FF10*
- ID_MODEL_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (Inventec)
+ ID_MODEL_FROM_DATABASE=88E8036 PCI-E Fast Ethernet Controller (Marvell 88E8036 Fast Ethernet Controller (Inventec))
 
 pci:v000011ABd00004351sv000011ABsd00003621*
- ID_MODEL_FROM_DATABASE=Marvell RDK-8036
+ ID_MODEL_FROM_DATABASE=88E8036 PCI-E Fast Ethernet Controller (Marvell RDK-8036)
 
 pci:v000011ABd00004351sv000013D1sd0000AC12*
- ID_MODEL_FROM_DATABASE=Abocom EFE3K - 10/100 Ethernet Expresscard
+ ID_MODEL_FROM_DATABASE=88E8036 PCI-E Fast Ethernet Controller (Abocom EFE3K - 10/100 Ethernet Expresscard)
 
 pci:v000011ABd00004351sv0000161Fsd0000203D*
- ID_MODEL_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (Arima)
+ ID_MODEL_FROM_DATABASE=88E8036 PCI-E Fast Ethernet Controller (Marvell 88E8036 Fast Ethernet Controller (Arima))
 
 pci:v000011ABd00004351sv00001854sd0000000D*
- ID_MODEL_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (LGE)
+ ID_MODEL_FROM_DATABASE=88E8036 PCI-E Fast Ethernet Controller (Marvell 88E8036 Fast Ethernet Controller (LGE))
 
 pci:v000011ABd00004351sv00001854sd0000000E*
- ID_MODEL_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (LGE)
+ ID_MODEL_FROM_DATABASE=88E8036 PCI-E Fast Ethernet Controller (Marvell 88E8036 Fast Ethernet Controller (LGE))
 
 pci:v000011ABd00004351sv00001854sd0000000F*
- ID_MODEL_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (LGE)
+ ID_MODEL_FROM_DATABASE=88E8036 PCI-E Fast Ethernet Controller (Marvell 88E8036 Fast Ethernet Controller (LGE))
 
 pci:v000011ABd00004351sv00001854sd00000011*
- ID_MODEL_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (LGE)
+ ID_MODEL_FROM_DATABASE=88E8036 PCI-E Fast Ethernet Controller (Marvell 88E8036 Fast Ethernet Controller (LGE))
 
 pci:v000011ABd00004351sv00001854sd00000012*
- ID_MODEL_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (LGE)
+ ID_MODEL_FROM_DATABASE=88E8036 PCI-E Fast Ethernet Controller (Marvell 88E8036 Fast Ethernet Controller (LGE))
 
 pci:v000011ABd00004351sv00001854sd00000016*
- ID_MODEL_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (LGE)
+ ID_MODEL_FROM_DATABASE=88E8036 PCI-E Fast Ethernet Controller (Marvell 88E8036 Fast Ethernet Controller (LGE))
 
 pci:v000011ABd00004351sv00001854sd00000017*
- ID_MODEL_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (LGE)
+ ID_MODEL_FROM_DATABASE=88E8036 PCI-E Fast Ethernet Controller (Marvell 88E8036 Fast Ethernet Controller (LGE))
 
 pci:v000011ABd00004351sv00001854sd00000018*
- ID_MODEL_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (LGE)
+ ID_MODEL_FROM_DATABASE=88E8036 PCI-E Fast Ethernet Controller (Marvell 88E8036 Fast Ethernet Controller (LGE))
 
 pci:v000011ABd00004351sv00001854sd00000019*
- ID_MODEL_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (LGE)
+ ID_MODEL_FROM_DATABASE=88E8036 PCI-E Fast Ethernet Controller (Marvell 88E8036 Fast Ethernet Controller (LGE))
 
 pci:v000011ABd00004351sv00001854sd0000001C*
- ID_MODEL_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (LGE)
+ ID_MODEL_FROM_DATABASE=88E8036 PCI-E Fast Ethernet Controller (Marvell 88E8036 Fast Ethernet Controller (LGE))
 
 pci:v000011ABd00004351sv00001854sd0000001E*
- ID_MODEL_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (LGE)
+ ID_MODEL_FROM_DATABASE=88E8036 PCI-E Fast Ethernet Controller (Marvell 88E8036 Fast Ethernet Controller (LGE))
 
 pci:v000011ABd00004351sv00001854sd00000020*
- ID_MODEL_FROM_DATABASE=Marvell 88E8036 Fast Ethernet Controller (LGE)
+ ID_MODEL_FROM_DATABASE=88E8036 PCI-E Fast Ethernet Controller (Marvell 88E8036 Fast Ethernet Controller (LGE))
 
 pci:v000011ABd00004352*
  ID_MODEL_FROM_DATABASE=88E8038 PCI-E Fast Ethernet Controller
@@ -34203,19 +35220,22 @@ pci:v000011ABd00004353*
  ID_MODEL_FROM_DATABASE=88E8039 PCI-E Fast Ethernet Controller
 
 pci:v000011ABd00004353sv0000104Dsd0000902D*
- ID_MODEL_FROM_DATABASE=VAIO VGN-NR120E
+ ID_MODEL_FROM_DATABASE=88E8039 PCI-E Fast Ethernet Controller (VAIO VGN-NR120E)
 
 pci:v000011ABd00004354*
  ID_MODEL_FROM_DATABASE=88E8040 PCI-E Fast Ethernet Controller
 
+pci:v000011ABd00004354sv0000144Dsd0000C06A*
+ ID_MODEL_FROM_DATABASE=88E8040 PCI-E Fast Ethernet Controller (R730 Laptop)
+
 pci:v000011ABd00004354sv0000144Dsd0000C072*
- ID_MODEL_FROM_DATABASE=Notebook N150P
+ ID_MODEL_FROM_DATABASE=88E8040 PCI-E Fast Ethernet Controller (Notebook N150P)
 
 pci:v000011ABd00004355*
  ID_MODEL_FROM_DATABASE=88E8040T PCI-E Fast Ethernet Controller
 
 pci:v000011ABd00004355sv00001179sd0000FF50*
- ID_MODEL_FROM_DATABASE=Satellite P305D-S8995E
+ ID_MODEL_FROM_DATABASE=88E8040T PCI-E Fast Ethernet Controller (Satellite P305D-S8995E)
 
 pci:v000011ABd00004356*
  ID_MODEL_FROM_DATABASE=88EC033 PCI-E Fast Ethernet Controller
@@ -34230,163 +35250,163 @@ pci:v000011ABd00004360*
  ID_MODEL_FROM_DATABASE=88E8052 PCI-E ASF Gigabit Ethernet Controller
 
 pci:v000011ABd00004360sv00001043sd00008134*
- ID_MODEL_FROM_DATABASE=Marvell 88E8052 Gigabit Ethernet Controller (Asus)
+ ID_MODEL_FROM_DATABASE=88E8052 PCI-E ASF Gigabit Ethernet Controller (Marvell 88E8052 Gigabit Ethernet Controller (Asus))
 
 pci:v000011ABd00004360sv0000107Bsd00004009*
- ID_MODEL_FROM_DATABASE=Marvell 88E8052 Gigabit Ethernet Controller (Wistron)
+ ID_MODEL_FROM_DATABASE=88E8052 PCI-E ASF Gigabit Ethernet Controller (Marvell 88E8052 Gigabit Ethernet Controller (Wistron))
 
 pci:v000011ABd00004360sv000011ABsd00005221*
- ID_MODEL_FROM_DATABASE=Marvell RDK-8052
+ ID_MODEL_FROM_DATABASE=88E8052 PCI-E ASF Gigabit Ethernet Controller (Marvell RDK-8052)
 
 pci:v000011ABd00004360sv00001458sd0000E000*
- ID_MODEL_FROM_DATABASE=Marvell 88E8052 Gigabit Ethernet Controller (Gigabyte)
+ ID_MODEL_FROM_DATABASE=88E8052 PCI-E ASF Gigabit Ethernet Controller (Marvell 88E8052 Gigabit Ethernet Controller (Gigabyte))
 
 pci:v000011ABd00004360sv00001462sd0000052C*
- ID_MODEL_FROM_DATABASE=Marvell 88E8052 Gigabit Ethernet Controller (MSI)
+ ID_MODEL_FROM_DATABASE=88E8052 PCI-E ASF Gigabit Ethernet Controller (Marvell 88E8052 Gigabit Ethernet Controller (MSI))
 
 pci:v000011ABd00004360sv00001849sd00008052*
- ID_MODEL_FROM_DATABASE=Marvell 88E8052 Gigabit Ethernet Controller (ASRock)
+ ID_MODEL_FROM_DATABASE=88E8052 PCI-E ASF Gigabit Ethernet Controller (Marvell 88E8052 Gigabit Ethernet Controller (ASRock))
 
 pci:v000011ABd00004360sv0000A0A0sd00000509*
- ID_MODEL_FROM_DATABASE=Marvell 88E8052 Gigabit Ethernet Controller (Aopen)
+ ID_MODEL_FROM_DATABASE=88E8052 PCI-E ASF Gigabit Ethernet Controller (Marvell 88E8052 Gigabit Ethernet Controller (Aopen))
 
 pci:v000011ABd00004361*
  ID_MODEL_FROM_DATABASE=88E8050 PCI-E ASF Gigabit Ethernet Controller
 
 pci:v000011ABd00004361sv0000107Bsd00003015*
- ID_MODEL_FROM_DATABASE=Marvell 88E8050 Gigabit Ethernet Controller (Gateway)
+ ID_MODEL_FROM_DATABASE=88E8050 PCI-E ASF Gigabit Ethernet Controller (Marvell 88E8050 Gigabit Ethernet Controller (Gateway))
 
 pci:v000011ABd00004361sv000011ABsd00005021*
- ID_MODEL_FROM_DATABASE=Marvell 88E8050 Gigabit Ethernet Controller (Intel)
+ ID_MODEL_FROM_DATABASE=88E8050 PCI-E ASF Gigabit Ethernet Controller (Marvell 88E8050 Gigabit Ethernet Controller (Intel))
 
 pci:v000011ABd00004361sv00008086sd00003063*
- ID_MODEL_FROM_DATABASE=D925XCVLK mainboard
+ ID_MODEL_FROM_DATABASE=88E8050 PCI-E ASF Gigabit Ethernet Controller (D925XCVLK mainboard)
 
 pci:v000011ABd00004361sv00008086sd00003439*
- ID_MODEL_FROM_DATABASE=Marvell 88E8050 Gigabit Ethernet Controller (Intel)
+ ID_MODEL_FROM_DATABASE=88E8050 PCI-E ASF Gigabit Ethernet Controller (Marvell 88E8050 Gigabit Ethernet Controller (Intel))
 
 pci:v000011ABd00004362*
  ID_MODEL_FROM_DATABASE=88E8053 PCI-E Gigabit Ethernet Controller
 
 pci:v000011ABd00004362sv0000103Csd00002A0D*
- ID_MODEL_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Asus)
+ ID_MODEL_FROM_DATABASE=88E8053 PCI-E Gigabit Ethernet Controller (Marvell 88E8053 Gigabit Ethernet Controller (Asus))
 
 pci:v000011ABd00004362sv00001043sd00008142*
- ID_MODEL_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet controller PCIe (Asus)
+ ID_MODEL_FROM_DATABASE=88E8053 PCI-E Gigabit Ethernet Controller (Marvell 88E8053 Gigabit Ethernet controller PCIe (Asus))
 
 pci:v000011ABd00004362sv0000109Fsd00003197*
- ID_MODEL_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Trigem)
+ ID_MODEL_FROM_DATABASE=88E8053 PCI-E Gigabit Ethernet Controller (Marvell 88E8053 Gigabit Ethernet Controller (Trigem))
 
 pci:v000011ABd00004362sv000010F7sd00008338*
- ID_MODEL_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Panasonic)
+ ID_MODEL_FROM_DATABASE=88E8053 PCI-E Gigabit Ethernet Controller (Marvell 88E8053 Gigabit Ethernet Controller (Panasonic))
 
 pci:v000011ABd00004362sv000010FDsd0000A430*
- ID_MODEL_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (SOYO)
+ ID_MODEL_FROM_DATABASE=88E8053 PCI-E Gigabit Ethernet Controller (Marvell 88E8053 Gigabit Ethernet Controller (SOYO))
 
 pci:v000011ABd00004362sv00001179sd00000001*
- ID_MODEL_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Toshiba)
+ ID_MODEL_FROM_DATABASE=88E8053 PCI-E Gigabit Ethernet Controller (Marvell 88E8053 Gigabit Ethernet Controller (Toshiba))
 
 pci:v000011ABd00004362sv00001179sd0000FF00*
- ID_MODEL_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Compal)
+ ID_MODEL_FROM_DATABASE=88E8053 PCI-E Gigabit Ethernet Controller (Marvell 88E8053 Gigabit Ethernet Controller (Compal))
 
 pci:v000011ABd00004362sv00001179sd0000FF10*
- ID_MODEL_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Inventec)
+ ID_MODEL_FROM_DATABASE=88E8053 PCI-E Gigabit Ethernet Controller (Marvell 88E8053 Gigabit Ethernet Controller (Inventec))
 
 pci:v000011ABd00004362sv000011ABsd00005321*
- ID_MODEL_FROM_DATABASE=Marvell RDK-8053
+ ID_MODEL_FROM_DATABASE=88E8053 PCI-E Gigabit Ethernet Controller (Marvell RDK-8053)
 
 pci:v000011ABd00004362sv00001297sd0000C240*
- ID_MODEL_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Shuttle)
+ ID_MODEL_FROM_DATABASE=88E8053 PCI-E Gigabit Ethernet Controller (Marvell 88E8053 Gigabit Ethernet Controller (Shuttle))
 
 pci:v000011ABd00004362sv00001297sd0000C241*
- ID_MODEL_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Shuttle)
+ ID_MODEL_FROM_DATABASE=88E8053 PCI-E Gigabit Ethernet Controller (Marvell 88E8053 Gigabit Ethernet Controller (Shuttle))
 
 pci:v000011ABd00004362sv00001297sd0000C242*
- ID_MODEL_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Shuttle)
+ ID_MODEL_FROM_DATABASE=88E8053 PCI-E Gigabit Ethernet Controller (Marvell 88E8053 Gigabit Ethernet Controller (Shuttle))
 
 pci:v000011ABd00004362sv00001297sd0000C243*
- ID_MODEL_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Shuttle)
+ ID_MODEL_FROM_DATABASE=88E8053 PCI-E Gigabit Ethernet Controller (Marvell 88E8053 Gigabit Ethernet Controller (Shuttle))
 
 pci:v000011ABd00004362sv00001297sd0000C244*
- ID_MODEL_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Shuttle)
+ ID_MODEL_FROM_DATABASE=88E8053 PCI-E Gigabit Ethernet Controller (Marvell 88E8053 Gigabit Ethernet Controller (Shuttle))
 
 pci:v000011ABd00004362sv000013D1sd0000AC11*
- ID_MODEL_FROM_DATABASE=EGE5K - Giga Ethernet Expresscard
+ ID_MODEL_FROM_DATABASE=88E8053 PCI-E Gigabit Ethernet Controller (EGE5K - Giga Ethernet Expresscard)
 
 pci:v000011ABd00004362sv00001458sd0000E000*
- ID_MODEL_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Gigabyte)
+ ID_MODEL_FROM_DATABASE=88E8053 PCI-E Gigabit Ethernet Controller (Marvell 88E8053 Gigabit Ethernet Controller (Gigabyte))
 
 pci:v000011ABd00004362sv00001462sd0000058C*
- ID_MODEL_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (MSI)
+ ID_MODEL_FROM_DATABASE=88E8053 PCI-E Gigabit Ethernet Controller (Marvell 88E8053 Gigabit Ethernet Controller (MSI))
 
 pci:v000011ABd00004362sv000014C0sd00000012*
- ID_MODEL_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Compal)
+ ID_MODEL_FROM_DATABASE=88E8053 PCI-E Gigabit Ethernet Controller (Marvell 88E8053 Gigabit Ethernet Controller (Compal))
 
 pci:v000011ABd00004362sv00001558sd000004A0*
- ID_MODEL_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Clevo)
+ ID_MODEL_FROM_DATABASE=88E8053 PCI-E Gigabit Ethernet Controller (Marvell 88E8053 Gigabit Ethernet Controller (Clevo))
 
 pci:v000011ABd00004362sv000015BDsd00001003*
- ID_MODEL_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (DFI)
+ ID_MODEL_FROM_DATABASE=88E8053 PCI-E Gigabit Ethernet Controller (Marvell 88E8053 Gigabit Ethernet Controller (DFI))
 
 pci:v000011ABd00004362sv0000161Fsd0000203C*
- ID_MODEL_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Arima)
+ ID_MODEL_FROM_DATABASE=88E8053 PCI-E Gigabit Ethernet Controller (Marvell 88E8053 Gigabit Ethernet Controller (Arima))
 
 pci:v000011ABd00004362sv0000161Fsd0000203D*
- ID_MODEL_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Arima)
+ ID_MODEL_FROM_DATABASE=88E8053 PCI-E Gigabit Ethernet Controller (Marvell 88E8053 Gigabit Ethernet Controller (Arima))
 
 pci:v000011ABd00004362sv00001695sd00009029*
- ID_MODEL_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Epox)
+ ID_MODEL_FROM_DATABASE=88E8053 PCI-E Gigabit Ethernet Controller (Marvell 88E8053 Gigabit Ethernet Controller (Epox))
 
 pci:v000011ABd00004362sv000017F2sd00002C08*
- ID_MODEL_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Albatron)
+ ID_MODEL_FROM_DATABASE=88E8053 PCI-E Gigabit Ethernet Controller (Marvell 88E8053 Gigabit Ethernet Controller (Albatron))
 
 pci:v000011ABd00004362sv000017FFsd00000585*
- ID_MODEL_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Quanta)
+ ID_MODEL_FROM_DATABASE=88E8053 PCI-E Gigabit Ethernet Controller (Marvell 88E8053 Gigabit Ethernet Controller (Quanta))
 
 pci:v000011ABd00004362sv00001849sd00008053*
- ID_MODEL_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (ASRock)
+ ID_MODEL_FROM_DATABASE=88E8053 PCI-E Gigabit Ethernet Controller (Marvell 88E8053 Gigabit Ethernet Controller (ASRock))
 
 pci:v000011ABd00004362sv00001854sd0000000B*
- ID_MODEL_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (LGE)
+ ID_MODEL_FROM_DATABASE=88E8053 PCI-E Gigabit Ethernet Controller (Marvell 88E8053 Gigabit Ethernet Controller (LGE))
 
 pci:v000011ABd00004362sv00001854sd0000000C*
- ID_MODEL_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (LGE)
+ ID_MODEL_FROM_DATABASE=88E8053 PCI-E Gigabit Ethernet Controller (Marvell 88E8053 Gigabit Ethernet Controller (LGE))
 
 pci:v000011ABd00004362sv00001854sd00000010*
- ID_MODEL_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (LGE)
+ ID_MODEL_FROM_DATABASE=88E8053 PCI-E Gigabit Ethernet Controller (Marvell 88E8053 Gigabit Ethernet Controller (LGE))
 
 pci:v000011ABd00004362sv00001854sd00000013*
- ID_MODEL_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (LGE)
+ ID_MODEL_FROM_DATABASE=88E8053 PCI-E Gigabit Ethernet Controller (Marvell 88E8053 Gigabit Ethernet Controller (LGE))
 
 pci:v000011ABd00004362sv00001854sd00000014*
- ID_MODEL_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (LGE)
+ ID_MODEL_FROM_DATABASE=88E8053 PCI-E Gigabit Ethernet Controller (Marvell 88E8053 Gigabit Ethernet Controller (LGE))
 
 pci:v000011ABd00004362sv00001854sd00000015*
- ID_MODEL_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (LGE)
+ ID_MODEL_FROM_DATABASE=88E8053 PCI-E Gigabit Ethernet Controller (Marvell 88E8053 Gigabit Ethernet Controller (LGE))
 
 pci:v000011ABd00004362sv00001854sd0000001A*
- ID_MODEL_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (LGE)
+ ID_MODEL_FROM_DATABASE=88E8053 PCI-E Gigabit Ethernet Controller (Marvell 88E8053 Gigabit Ethernet Controller (LGE))
 
 pci:v000011ABd00004362sv00001854sd0000001B*
- ID_MODEL_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (LGE)
+ ID_MODEL_FROM_DATABASE=88E8053 PCI-E Gigabit Ethernet Controller (Marvell 88E8053 Gigabit Ethernet Controller (LGE))
 
 pci:v000011ABd00004362sv00001854sd0000001D*
- ID_MODEL_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (LGE)
+ ID_MODEL_FROM_DATABASE=88E8053 PCI-E Gigabit Ethernet Controller (Marvell 88E8053 Gigabit Ethernet Controller (LGE))
 
 pci:v000011ABd00004362sv00001854sd0000001F*
- ID_MODEL_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (LGE)
+ ID_MODEL_FROM_DATABASE=88E8053 PCI-E Gigabit Ethernet Controller (Marvell 88E8053 Gigabit Ethernet Controller (LGE))
 
 pci:v000011ABd00004362sv00001854sd00000021*
- ID_MODEL_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (LGE)
+ ID_MODEL_FROM_DATABASE=88E8053 PCI-E Gigabit Ethernet Controller (Marvell 88E8053 Gigabit Ethernet Controller (LGE))
 
 pci:v000011ABd00004362sv00001854sd00000022*
- ID_MODEL_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (LGE)
+ ID_MODEL_FROM_DATABASE=88E8053 PCI-E Gigabit Ethernet Controller (Marvell 88E8053 Gigabit Ethernet Controller (LGE))
 
 pci:v000011ABd00004362sv0000270Fsd00002801*
- ID_MODEL_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Chaintech)
+ ID_MODEL_FROM_DATABASE=88E8053 PCI-E Gigabit Ethernet Controller (Marvell 88E8053 Gigabit Ethernet Controller (Chaintech))
 
 pci:v000011ABd00004362sv0000A0A0sd00000506*
- ID_MODEL_FROM_DATABASE=Marvell 88E8053 Gigabit Ethernet Controller (Aopen)
+ ID_MODEL_FROM_DATABASE=88E8053 PCI-E Gigabit Ethernet Controller (Marvell 88E8053 Gigabit Ethernet Controller (Aopen))
 
 pci:v000011ABd00004363*
  ID_MODEL_FROM_DATABASE=88E8055 PCI-E Gigabit Ethernet Controller
@@ -34395,10 +35415,10 @@ pci:v000011ABd00004364*
  ID_MODEL_FROM_DATABASE=88E8056 PCI-E Gigabit Ethernet Controller
 
 pci:v000011ABd00004364sv00001043sd000081F8*
- ID_MODEL_FROM_DATABASE=Motherboard
+ ID_MODEL_FROM_DATABASE=88E8056 PCI-E Gigabit Ethernet Controller (Motherboard)
 
 pci:v000011ABd00004364sv000011BAsd000000BA*
- ID_MODEL_FROM_DATABASE=8056 Gigabit Ethernet Controller
+ ID_MODEL_FROM_DATABASE=88E8056 PCI-E Gigabit Ethernet Controller (8056 Gigabit Ethernet Controller)
 
 pci:v000011ABd00004365*
  ID_MODEL_FROM_DATABASE=88E8070 based Ethernet Controller
@@ -34419,7 +35439,7 @@ pci:v000011ABd0000436A*
  ID_MODEL_FROM_DATABASE=88E8058 PCI-E Gigabit Ethernet Controller
 
 pci:v000011ABd0000436Asv000011ABsd000000BA*
- ID_MODEL_FROM_DATABASE=Imac 8,1 Wired Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=88E8058 PCI-E Gigabit Ethernet Controller (Imac 8,1 Wired Ethernet Adapter)
 
 pci:v000011ABd0000436B*
  ID_MODEL_FROM_DATABASE=88E8071 PCI-E Gigabit Ethernet Controller
@@ -34485,7 +35505,7 @@ pci:v000011ABd00006101*
  ID_MODEL_FROM_DATABASE=88SE6101/6102 single-port PATA133 interface
 
 pci:v000011ABd00006101sv00001043sd000082E0*
- ID_MODEL_FROM_DATABASE=P5K PRO Motherboard
+ ID_MODEL_FROM_DATABASE=88SE6101/6102 single-port PATA133 interface (P5K PRO Motherboard)
 
 pci:v000011ABd00006111*
  ID_MODEL_FROM_DATABASE=88SE6111 1-port PATA133(IDE) and 1-port SATA II Controllers
@@ -34524,7 +35544,7 @@ pci:v000011ABd00006480*
  ID_MODEL_FROM_DATABASE=MV64460/64461/64462 System Controller
 
 pci:v000011ABd00006480sv00001775sd0000C200*
- ID_MODEL_FROM_DATABASE=C2K CompactPCI single board computer
+ ID_MODEL_FROM_DATABASE=MV64460/64461/64462 System Controller (C2K CompactPCI single board computer)
 
 pci:v000011ABd00006485*
  ID_MODEL_FROM_DATABASE=MV64460/64461/64462 System Controller, Revision B
@@ -34533,7 +35553,7 @@ pci:v000011ABd00007042*
  ID_MODEL_FROM_DATABASE=88SX7042 PCI-e 4-port SATA-II
 
 pci:v000011ABd00007042sv000016B8sd0000434B*
- ID_MODEL_FROM_DATABASE=Tempo SATA E4P
+ ID_MODEL_FROM_DATABASE=88SX7042 PCI-e 4-port SATA-II (Tempo SATA E4P)
 
 pci:v000011ABd00007810*
  ID_MODEL_FROM_DATABASE=MV78100 [Discovery Innovation] ARM SoC
@@ -34541,6 +35561,9 @@ pci:v000011ABd00007810*
 pci:v000011ABd00007820*
  ID_MODEL_FROM_DATABASE=MV78200 [Discovery Innovation] ARM SoC
 
+pci:v000011ABd00007823*
+ ID_MODEL_FROM_DATABASE=MV78230 [Armada XP] ARM SoC
+
 pci:v000011ABd0000F003*
  ID_MODEL_FROM_DATABASE=GT-64010 Primary Image Piranha Image Generator
 
@@ -34566,19 +35589,19 @@ pci:v000011ADd00000002sv000011ADsd0000FFFF*
  ID_MODEL_FROM_DATABASE=LNE100TX
 
 pci:v000011ADd00000002sv00001385sd0000F004*
- ID_MODEL_FROM_DATABASE=FA310TX
+ ID_MODEL_FROM_DATABASE=LNE100TX (FA310TX)
 
 pci:v000011ADd00000002sv00002646sd0000F002*
- ID_MODEL_FROM_DATABASE=KNE110TX EtheRx Fast Ethernet
+ ID_MODEL_FROM_DATABASE=LNE100TX (KNE110TX EtheRx Fast Ethernet)
 
 pci:v000011ADd0000C115*
  ID_MODEL_FROM_DATABASE=LNE100TX [Linksys EtherFast 10/100]
 
 pci:v000011ADd0000C115sv000011ADsd0000C001*
- ID_MODEL_FROM_DATABASE=LNE100TX [ver 2.0]
+ ID_MODEL_FROM_DATABASE=LNE100TX [Linksys EtherFast 10/100] (LNE100TX [ver 2.0])
 
 pci:v000011ADd0000C115sv00002646sd0000000B*
- ID_MODEL_FROM_DATABASE=KNE111TX
+ ID_MODEL_FROM_DATABASE=LNE100TX [Linksys EtherFast 10/100] (KNE111TX)
 
 pci:v000011AE*
  ID_VENDOR_FROM_DATABASE=Aztech System Ltd
@@ -34662,28 +35685,28 @@ pci:v000011BDd00000040*
  ID_MODEL_FROM_DATABASE=Royal TS Function 1
 
 pci:v000011BDd00000040sv000011BDsd00000044*
- ID_MODEL_FROM_DATABASE=PCTV 2000i Dual DVB-T Pro PCI Tuner 1
+ ID_MODEL_FROM_DATABASE=Royal TS Function 1 (PCTV 2000i Dual DVB-T Pro PCI Tuner 1)
 
 pci:v000011BDd00000040sv000011BDsd00000045*
- ID_MODEL_FROM_DATABASE=PCTV Dual Sat Pro PCI 4000i Tuner 1
+ ID_MODEL_FROM_DATABASE=Royal TS Function 1 (PCTV Dual Sat Pro PCI 4000i Tuner 1)
 
 pci:v000011BDd00000041*
  ID_MODEL_FROM_DATABASE=RoyalTS Function 2
 
 pci:v000011BDd00000041sv000011BDsd00000044*
- ID_MODEL_FROM_DATABASE=PCTV 2000i Dual DVB-T Pro PCI Tuner 2
+ ID_MODEL_FROM_DATABASE=RoyalTS Function 2 (PCTV 2000i Dual DVB-T Pro PCI Tuner 2)
 
 pci:v000011BDd00000041sv000011BDsd00000045*
- ID_MODEL_FROM_DATABASE=PCTV Dual Sat Pro PCI 4000i Tuner 2
+ ID_MODEL_FROM_DATABASE=RoyalTS Function 2 (PCTV Dual Sat Pro PCI 4000i Tuner 2)
 
 pci:v000011BDd00000042*
  ID_MODEL_FROM_DATABASE=Royal TS Function 3
 
 pci:v000011BDd00000042sv000011BDsd00000044*
- ID_MODEL_FROM_DATABASE=PCTV 2000i Dual DVB-T Pro PCI Common
+ ID_MODEL_FROM_DATABASE=Royal TS Function 3 (PCTV 2000i Dual DVB-T Pro PCI Common)
 
 pci:v000011BDd00000042sv000011BDsd00000045*
- ID_MODEL_FROM_DATABASE=PCTV Dual Sat Pro PCI 4000i Common
+ ID_MODEL_FROM_DATABASE=Royal TS Function 3 (PCTV Dual Sat Pro PCI 4000i Common)
 
 pci:v000011BDd00000051*
  ID_MODEL_FROM_DATABASE=PCTV HD 800i
@@ -34707,154 +35730,154 @@ pci:v000011C1d00000440*
  ID_MODEL_FROM_DATABASE=56k WinModem
 
 pci:v000011C1d00000440sv00001033sd00008015*
- ID_MODEL_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+Dsvd
+ ID_MODEL_FROM_DATABASE=56k WinModem (LT WinModem 56k Data+Fax+Voice+Dsvd)
 
 pci:v000011C1d00000440sv00001033sd00008047*
- ID_MODEL_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+Dsvd
+ ID_MODEL_FROM_DATABASE=56k WinModem (LT WinModem 56k Data+Fax+Voice+Dsvd)
 
 pci:v000011C1d00000440sv00001033sd0000804F*
- ID_MODEL_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+Dsvd
+ ID_MODEL_FROM_DATABASE=56k WinModem (LT WinModem 56k Data+Fax+Voice+Dsvd)
 
 pci:v000011C1d00000440sv000010CFsd0000102C*
- ID_MODEL_FROM_DATABASE=LB LT Modem V.90 56k
+ ID_MODEL_FROM_DATABASE=56k WinModem (LB LT Modem V.90 56k)
 
 pci:v000011C1d00000440sv000010CFsd0000104A*
- ID_MODEL_FROM_DATABASE=BIBLO LT Modem 56k
+ ID_MODEL_FROM_DATABASE=56k WinModem (BIBLO LT Modem 56k)
 
 pci:v000011C1d00000440sv000010CFsd0000105F*
- ID_MODEL_FROM_DATABASE=LB2 LT Modem V.90 56k
+ ID_MODEL_FROM_DATABASE=56k WinModem (LB2 LT Modem V.90 56k)
 
 pci:v000011C1d00000440sv00001179sd00000001*
- ID_MODEL_FROM_DATABASE=Internal V.90 Modem
+ ID_MODEL_FROM_DATABASE=56k WinModem (Internal V.90 Modem)
 
 pci:v000011C1d00000440sv000011C1sd00000440*
- ID_MODEL_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+Dsvd
+ ID_MODEL_FROM_DATABASE=56k WinModem (LT WinModem 56k Data+Fax+Voice+Dsvd)
 
 pci:v000011C1d00000440sv0000122Dsd00004101*
- ID_MODEL_FROM_DATABASE=MDP7800-U Modem
+ ID_MODEL_FROM_DATABASE=56k WinModem (MDP7800-U Modem)
 
 pci:v000011C1d00000440sv0000122Dsd00004102*
- ID_MODEL_FROM_DATABASE=MDP7800SP-U Modem
+ ID_MODEL_FROM_DATABASE=56k WinModem (MDP7800SP-U Modem)
 
 pci:v000011C1d00000440sv000013E0sd00000040*
- ID_MODEL_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+Dsvd
+ ID_MODEL_FROM_DATABASE=56k WinModem (LT WinModem 56k Data+Fax+Voice+Dsvd)
 
 pci:v000011C1d00000440sv000013E0sd00000440*
- ID_MODEL_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+Dsvd
+ ID_MODEL_FROM_DATABASE=56k WinModem (LT WinModem 56k Data+Fax+Voice+Dsvd)
 
 pci:v000011C1d00000440sv000013E0sd00000441*
- ID_MODEL_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+Dsvd
+ ID_MODEL_FROM_DATABASE=56k WinModem (LT WinModem 56k Data+Fax+Voice+Dsvd)
 
 pci:v000011C1d00000440sv000013E0sd00000450*
- ID_MODEL_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+Dsvd
+ ID_MODEL_FROM_DATABASE=56k WinModem (LT WinModem 56k Data+Fax+Voice+Dsvd)
 
 pci:v000011C1d00000440sv000013E0sd0000F100*
- ID_MODEL_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+Dsvd
+ ID_MODEL_FROM_DATABASE=56k WinModem (LT WinModem 56k Data+Fax+Voice+Dsvd)
 
 pci:v000011C1d00000440sv000013E0sd0000F101*
- ID_MODEL_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+Dsvd
+ ID_MODEL_FROM_DATABASE=56k WinModem (LT WinModem 56k Data+Fax+Voice+Dsvd)
 
 pci:v000011C1d00000440sv0000144Dsd00002101*
- ID_MODEL_FROM_DATABASE=LT56PV Modem
+ ID_MODEL_FROM_DATABASE=56k WinModem (LT56PV Modem)
 
 pci:v000011C1d00000440sv0000149Fsd00000440*
- ID_MODEL_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+Dsvd
+ ID_MODEL_FROM_DATABASE=56k WinModem (LT WinModem 56k Data+Fax+Voice+Dsvd)
 
 pci:v000011C1d00000441*
  ID_MODEL_FROM_DATABASE=56k WinModem
 
 pci:v000011C1d00000441sv00001033sd0000804D*
- ID_MODEL_FROM_DATABASE=LT WinModem 56k Data+Fax
+ ID_MODEL_FROM_DATABASE=56k WinModem (LT WinModem 56k Data+Fax)
 
 pci:v000011C1d00000441sv00001033sd00008065*
- ID_MODEL_FROM_DATABASE=LT WinModem 56k Data+Fax
+ ID_MODEL_FROM_DATABASE=56k WinModem (LT WinModem 56k Data+Fax)
 
 pci:v000011C1d00000441sv00001092sd00000440*
- ID_MODEL_FROM_DATABASE=Supra 56i
+ ID_MODEL_FROM_DATABASE=56k WinModem (Supra 56i)
 
 pci:v000011C1d00000441sv00001179sd00000001*
- ID_MODEL_FROM_DATABASE=Internal V.90 Modem
+ ID_MODEL_FROM_DATABASE=56k WinModem (Internal V.90 Modem)
 
 pci:v000011C1d00000441sv000011C1sd00000440*
- ID_MODEL_FROM_DATABASE=LT WinModem 56k Data+Fax
+ ID_MODEL_FROM_DATABASE=56k WinModem (LT WinModem 56k Data+Fax)
 
 pci:v000011C1d00000441sv000011C1sd00000441*
- ID_MODEL_FROM_DATABASE=LT WinModem 56k Data+Fax
+ ID_MODEL_FROM_DATABASE=56k WinModem (LT WinModem 56k Data+Fax)
 
 pci:v000011C1d00000441sv0000122Dsd00004100*
- ID_MODEL_FROM_DATABASE=MDP7800-U Modem
+ ID_MODEL_FROM_DATABASE=56k WinModem (MDP7800-U Modem)
 
 pci:v000011C1d00000441sv000013E0sd00000040*
- ID_MODEL_FROM_DATABASE=LT WinModem 56k Data+Fax
+ ID_MODEL_FROM_DATABASE=56k WinModem (LT WinModem 56k Data+Fax)
 
 pci:v000011C1d00000441sv000013E0sd00000100*
- ID_MODEL_FROM_DATABASE=LT WinModem 56k Data+Fax
+ ID_MODEL_FROM_DATABASE=56k WinModem (LT WinModem 56k Data+Fax)
 
 pci:v000011C1d00000441sv000013E0sd00000410*
- ID_MODEL_FROM_DATABASE=LT WinModem 56k Data+Fax
+ ID_MODEL_FROM_DATABASE=56k WinModem (LT WinModem 56k Data+Fax)
 
 pci:v000011C1d00000441sv000013E0sd00000420*
- ID_MODEL_FROM_DATABASE=TelePath Internet 56k WinModem
+ ID_MODEL_FROM_DATABASE=56k WinModem (TelePath Internet 56k WinModem)
 
 pci:v000011C1d00000441sv000013E0sd00000440*
- ID_MODEL_FROM_DATABASE=LT WinModem 56k Data+Fax
+ ID_MODEL_FROM_DATABASE=56k WinModem (LT WinModem 56k Data+Fax)
 
 pci:v000011C1d00000441sv000013E0sd00000443*
- ID_MODEL_FROM_DATABASE=LT WinModem 56k Data+Fax
+ ID_MODEL_FROM_DATABASE=56k WinModem (LT WinModem 56k Data+Fax)
 
 pci:v000011C1d00000441sv000013E0sd0000F102*
- ID_MODEL_FROM_DATABASE=LT WinModem 56k Data+Fax
+ ID_MODEL_FROM_DATABASE=56k WinModem (LT WinModem 56k Data+Fax)
 
 pci:v000011C1d00000441sv00001416sd00009804*
- ID_MODEL_FROM_DATABASE=CommWave 56k Modem
+ ID_MODEL_FROM_DATABASE=56k WinModem (CommWave 56k Modem)
 
 pci:v000011C1d00000441sv0000141Dsd00000440*
- ID_MODEL_FROM_DATABASE=LT WinModem 56k Data+Fax
+ ID_MODEL_FROM_DATABASE=56k WinModem (LT WinModem 56k Data+Fax)
 
 pci:v000011C1d00000441sv0000144Fsd00000441*
- ID_MODEL_FROM_DATABASE=Lucent 56k V.90 DF Modem
+ ID_MODEL_FROM_DATABASE=56k WinModem (Lucent 56k V.90 DF Modem)
 
 pci:v000011C1d00000441sv0000144Fsd00000449*
- ID_MODEL_FROM_DATABASE=Lucent 56k V.90 DF Modem
+ ID_MODEL_FROM_DATABASE=56k WinModem (Lucent 56k V.90 DF Modem)
 
 pci:v000011C1d00000441sv0000144Fsd0000110D*
- ID_MODEL_FROM_DATABASE=Lucent Win Modem
+ ID_MODEL_FROM_DATABASE=56k WinModem (Lucent Win Modem)
 
 pci:v000011C1d00000441sv00001468sd00000441*
- ID_MODEL_FROM_DATABASE=Presario 56k V.90 DF Modem
+ ID_MODEL_FROM_DATABASE=56k WinModem (Presario 56k V.90 DF Modem)
 
 pci:v000011C1d00000441sv00001668sd00000440*
- ID_MODEL_FROM_DATABASE=Lucent Win Modem
+ ID_MODEL_FROM_DATABASE=56k WinModem (Lucent Win Modem)
 
 pci:v000011C1d00000442*
  ID_MODEL_FROM_DATABASE=56k WinModem
 
 pci:v000011C1d00000442sv000011C1sd00000440*
- ID_MODEL_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
+ ID_MODEL_FROM_DATABASE=56k WinModem (LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd)
 
 pci:v000011C1d00000442sv000011C1sd00000442*
- ID_MODEL_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
+ ID_MODEL_FROM_DATABASE=56k WinModem (LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd)
 
 pci:v000011C1d00000442sv000013E0sd00000412*
- ID_MODEL_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
+ ID_MODEL_FROM_DATABASE=56k WinModem (LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd)
 
 pci:v000011C1d00000442sv000013E0sd00000442*
- ID_MODEL_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
+ ID_MODEL_FROM_DATABASE=56k WinModem (LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd)
 
 pci:v000011C1d00000442sv000013FCsd00002471*
- ID_MODEL_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
+ ID_MODEL_FROM_DATABASE=56k WinModem (LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd)
 
 pci:v000011C1d00000442sv0000144Dsd00002104*
- ID_MODEL_FROM_DATABASE=LT56PT Modem
+ ID_MODEL_FROM_DATABASE=56k WinModem (LT56PT Modem)
 
 pci:v000011C1d00000442sv0000144Fsd00001104*
- ID_MODEL_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
+ ID_MODEL_FROM_DATABASE=56k WinModem (LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd)
 
 pci:v000011C1d00000442sv0000149Fsd00000440*
- ID_MODEL_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
+ ID_MODEL_FROM_DATABASE=56k WinModem (LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd)
 
 pci:v000011C1d00000442sv00001668sd00000440*
- ID_MODEL_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
+ ID_MODEL_FROM_DATABASE=56k WinModem (LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd)
 
 pci:v000011C1d00000443*
  ID_MODEL_FROM_DATABASE=LT WinModem
@@ -34866,10 +35889,10 @@ pci:v000011C1d00000445*
  ID_MODEL_FROM_DATABASE=LT WinModem
 
 pci:v000011C1d00000445sv00008086sd00002203*
- ID_MODEL_FROM_DATABASE=PRO/100+ MiniPCI (probably an Ambit U98.003.C.00 combo card)
+ ID_MODEL_FROM_DATABASE=LT WinModem (PRO/100+ MiniPCI (probably an Ambit U98.003.C.00 combo card))
 
 pci:v000011C1d00000445sv00008086sd00002204*
- ID_MODEL_FROM_DATABASE=PRO/100+ MiniPCI on Armada E500
+ ID_MODEL_FROM_DATABASE=LT WinModem (PRO/100+ MiniPCI on Armada E500)
 
 pci:v000011C1d00000446*
  ID_MODEL_FROM_DATABASE=LT WinModem
@@ -34881,64 +35904,64 @@ pci:v000011C1d00000448*
  ID_MODEL_FROM_DATABASE=WinModem 56k
 
 pci:v000011C1d00000448sv00001014sd00000131*
- ID_MODEL_FROM_DATABASE=Lucent Win Modem
+ ID_MODEL_FROM_DATABASE=WinModem 56k (Lucent Win Modem)
 
 pci:v000011C1d00000448sv00001033sd00008066*
- ID_MODEL_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+Dsvd
+ ID_MODEL_FROM_DATABASE=WinModem 56k (LT WinModem 56k Data+Fax+Voice+Dsvd)
 
 pci:v000011C1d00000448sv000013E0sd00000030*
- ID_MODEL_FROM_DATABASE=56k Voice Modem
+ ID_MODEL_FROM_DATABASE=WinModem 56k (56k Voice Modem)
 
 pci:v000011C1d00000448sv000013E0sd00000040*
- ID_MODEL_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+Dsvd
+ ID_MODEL_FROM_DATABASE=WinModem 56k (LT WinModem 56k Data+Fax+Voice+Dsvd)
 
 pci:v000011C1d00000448sv00001668sd00002400*
- ID_MODEL_FROM_DATABASE=LT WinModem 56k (MiniPCI Ethernet+Modem)
+ ID_MODEL_FROM_DATABASE=WinModem 56k (LT WinModem 56k (MiniPCI Ethernet+Modem))
 
 pci:v000011C1d00000449*
  ID_MODEL_FROM_DATABASE=L56xM+S [Mars-2] WinModem 56k
 
 pci:v000011C1d00000449sv00000E11sd0000B14D*
- ID_MODEL_FROM_DATABASE=56k V.90 Modem
+ ID_MODEL_FROM_DATABASE=L56xM+S [Mars-2] WinModem 56k (56k V.90 Modem)
 
 pci:v000011C1d00000449sv00001014sd0000018C*
- ID_MODEL_FROM_DATABASE=ThinkPad 600X
+ ID_MODEL_FROM_DATABASE=L56xM+S [Mars-2] WinModem 56k (ThinkPad 600X)
 
 pci:v000011C1d00000449sv000013E0sd00000020*
- ID_MODEL_FROM_DATABASE=LT WinModem 56k Data+Fax
+ ID_MODEL_FROM_DATABASE=L56xM+S [Mars-2] WinModem 56k (LT WinModem 56k Data+Fax)
 
 pci:v000011C1d00000449sv000013E0sd00000041*
- ID_MODEL_FROM_DATABASE=TelePath Internet 56k WinModem
+ ID_MODEL_FROM_DATABASE=L56xM+S [Mars-2] WinModem 56k (TelePath Internet 56k WinModem)
 
 pci:v000011C1d00000449sv00001436sd00000440*
- ID_MODEL_FROM_DATABASE=Lucent Win Modem
+ ID_MODEL_FROM_DATABASE=L56xM+S [Mars-2] WinModem 56k (Lucent Win Modem)
 
 pci:v000011C1d00000449sv0000144Fsd00000449*
- ID_MODEL_FROM_DATABASE=Lucent 56k V.90 DFi Modem
+ ID_MODEL_FROM_DATABASE=L56xM+S [Mars-2] WinModem 56k (Lucent 56k V.90 DFi Modem)
 
 pci:v000011C1d00000449sv00001468sd00000410*
- ID_MODEL_FROM_DATABASE=IBM ThinkPad T23
+ ID_MODEL_FROM_DATABASE=L56xM+S [Mars-2] WinModem 56k (IBM ThinkPad T23)
 
 pci:v000011C1d00000449sv00001468sd00000440*
- ID_MODEL_FROM_DATABASE=Lucent Win Modem
+ ID_MODEL_FROM_DATABASE=L56xM+S [Mars-2] WinModem 56k (Lucent Win Modem)
 
 pci:v000011C1d00000449sv00001468sd00000449*
- ID_MODEL_FROM_DATABASE=Presario 56k V.90 DFi Modem
+ ID_MODEL_FROM_DATABASE=L56xM+S [Mars-2] WinModem 56k (Presario 56k V.90 DFi Modem)
 
 pci:v000011C1d0000044A*
  ID_MODEL_FROM_DATABASE=F-1156IV WinModem (V90, 56KFlex)
 
 pci:v000011C1d0000044Asv000010CFsd00001072*
- ID_MODEL_FROM_DATABASE=LB Global LT Modem
+ ID_MODEL_FROM_DATABASE=F-1156IV WinModem (V90, 56KFlex) (LB Global LT Modem)
 
 pci:v000011C1d0000044Asv000013E0sd00000012*
- ID_MODEL_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
+ ID_MODEL_FROM_DATABASE=F-1156IV WinModem (V90, 56KFlex) (LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd)
 
 pci:v000011C1d0000044Asv000013E0sd00000042*
- ID_MODEL_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
+ ID_MODEL_FROM_DATABASE=F-1156IV WinModem (V90, 56KFlex) (LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd)
 
 pci:v000011C1d0000044Asv0000144Fsd00001005*
- ID_MODEL_FROM_DATABASE=LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd
+ ID_MODEL_FROM_DATABASE=F-1156IV WinModem (V90, 56KFlex) (LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd)
 
 pci:v000011C1d0000044B*
  ID_MODEL_FROM_DATABASE=LT WinModem
@@ -34959,13 +35982,13 @@ pci:v000011C1d00000450*
  ID_MODEL_FROM_DATABASE=LT WinModem
 
 pci:v000011C1d00000450sv00001033sd000080A8*
- ID_MODEL_FROM_DATABASE=Versa Note Vxi
+ ID_MODEL_FROM_DATABASE=LT WinModem (Versa Note Vxi)
 
 pci:v000011C1d00000450sv0000144Fsd00004005*
- ID_MODEL_FROM_DATABASE=Magnia SG20
+ ID_MODEL_FROM_DATABASE=LT WinModem (Magnia SG20)
 
 pci:v000011C1d00000450sv00001468sd00000450*
- ID_MODEL_FROM_DATABASE=Evo N600c
+ ID_MODEL_FROM_DATABASE=LT WinModem (Evo N600c)
 
 pci:v000011C1d00000451*
  ID_MODEL_FROM_DATABASE=LT WinModem
@@ -35040,19 +36063,22 @@ pci:v000011C1d00005811*
  ID_MODEL_FROM_DATABASE=FW322/323 [TrueFire] 1394a Controller
 
 pci:v000011C1d00005811sv0000103Csd00002A34*
- ID_MODEL_FROM_DATABASE=Pavilion a1677c
+ ID_MODEL_FROM_DATABASE=FW322/323 [TrueFire] 1394a Controller (Pavilion a1677c)
+
+pci:v000011C1d00005811sv0000103Csd00002A6F*
+ ID_MODEL_FROM_DATABASE=FW322/323 [TrueFire] 1394a Controller (Asus IPIBL-LB Motherboard)
 
 pci:v000011C1d00005811sv0000103Csd00002A9E*
- ID_MODEL_FROM_DATABASE=Pavilion p6310f
+ ID_MODEL_FROM_DATABASE=FW322/323 [TrueFire] 1394a Controller (Pavilion p6310f)
 
 pci:v000011C1d00005811sv00001043sd00008294*
- ID_MODEL_FROM_DATABASE=LSI FW322/323 IEEE 1394a FireWire Controller
+ ID_MODEL_FROM_DATABASE=FW322/323 [TrueFire] 1394a Controller (LSI FW322/323 IEEE 1394a FireWire Controller)
 
 pci:v000011C1d00005811sv00008086sd0000524C*
- ID_MODEL_FROM_DATABASE=D865PERL mainboard
+ ID_MODEL_FROM_DATABASE=FW322/323 [TrueFire] 1394a Controller (D865PERL mainboard)
 
 pci:v000011C1d00005811sv0000DEADsd00000800*
- ID_MODEL_FROM_DATABASE=FireWire Host Bus Adapter
+ ID_MODEL_FROM_DATABASE=FW322/323 [TrueFire] 1394a Controller (FireWire Host Bus Adapter)
 
 pci:v000011C1d00005901*
  ID_MODEL_FROM_DATABASE=FW643 [TrueFire] PCIe 1394b Controller
@@ -35061,10 +36087,10 @@ pci:v000011C1d00005901sv000011C1sd00005900*
  ID_MODEL_FROM_DATABASE=FW643 [TrueFire] PCIe 1394b Controller
 
 pci:v000011C1d00005901sv00001443sd00000643*
- ID_MODEL_FROM_DATABASE=FireBoard800-e V.2
+ ID_MODEL_FROM_DATABASE=FW643 [TrueFire] PCIe 1394b Controller (FireBoard800-e V.2)
 
 pci:v000011C1d00005901sv00001546sd00000643*
- ID_MODEL_FROM_DATABASE=FWB-PCIE1X2x
+ ID_MODEL_FROM_DATABASE=FW643 [TrueFire] PCIe 1394b Controller (FWB-PCIE1X2x)
 
 pci:v000011C1d00005903*
  ID_MODEL_FROM_DATABASE=FW533 [TrueFire] PCIe 1394a Controller
@@ -35073,7 +36099,7 @@ pci:v000011C1d00008110*
  ID_MODEL_FROM_DATABASE=T8110 H.100/H.110 TDM switch
 
 pci:v000011C1d00008110sv000012D9sd0000000C*
- ID_MODEL_FROM_DATABASE=E1/T1 PMXc cPCI carrier card
+ ID_MODEL_FROM_DATABASE=T8110 H.100/H.110 TDM switch (E1/T1 PMXc cPCI carrier card)
 
 pci:v000011C1d0000AB10*
  ID_MODEL_FROM_DATABASE=WL60010 Wireless LAN MAC
@@ -35082,16 +36108,16 @@ pci:v000011C1d0000AB11*
  ID_MODEL_FROM_DATABASE=WL60040 Multimode Wireles LAN MAC
 
 pci:v000011C1d0000AB11sv000011C1sd0000AB12*
- ID_MODEL_FROM_DATABASE=WaveLAN 11abg Cardbus card (Model 1102)
+ ID_MODEL_FROM_DATABASE=WL60040 Multimode Wireles LAN MAC (WaveLAN 11abg Cardbus card (Model 1102))
 
 pci:v000011C1d0000AB11sv000011C1sd0000AB13*
- ID_MODEL_FROM_DATABASE=WaveLAN 11abg MiniPCI card (Model 0512)
+ ID_MODEL_FROM_DATABASE=WL60040 Multimode Wireles LAN MAC (WaveLAN 11abg MiniPCI card (Model 0512))
 
 pci:v000011C1d0000AB11sv000011C1sd0000AB15*
- ID_MODEL_FROM_DATABASE=WaveLAN 11abg Cardbus card (Model 1106)
+ ID_MODEL_FROM_DATABASE=WL60040 Multimode Wireles LAN MAC (WaveLAN 11abg Cardbus card (Model 1106))
 
 pci:v000011C1d0000AB11sv000011C1sd0000AB16*
- ID_MODEL_FROM_DATABASE=WaveLAN 11abg MiniPCI card (Model 0516)
+ ID_MODEL_FROM_DATABASE=WL60040 Multimode Wireles LAN MAC (WaveLAN 11abg MiniPCI card (Model 0516))
 
 pci:v000011C1d0000AB20*
  ID_MODEL_FROM_DATABASE=ORiNOCO PCI Adapter
@@ -35160,10 +36186,10 @@ pci:v000011CBd00002000*
  ID_MODEL_FROM_DATABASE=PCI_9050
 
 pci:v000011CBd00002000sv000011CBsd00000200*
- ID_MODEL_FROM_DATABASE=SX
+ ID_MODEL_FROM_DATABASE=PCI_9050 (SX)
 
 pci:v000011CBd00002000sv000011CBsd0000B008*
- ID_MODEL_FROM_DATABASE=I/O8+
+ ID_MODEL_FROM_DATABASE=PCI_9050 (I/O8+)
 
 pci:v000011CBd00004000*
  ID_MODEL_FROM_DATABASE=SUPI_1
@@ -35253,28 +36279,28 @@ pci:v000011DEd00006057*
  ID_MODEL_FROM_DATABASE=ZR36057PQC Video cutting chipset
 
 pci:v000011DEd00006057sv00001031sd00007EFE*
- ID_MODEL_FROM_DATABASE=DC10 Plus
+ ID_MODEL_FROM_DATABASE=ZR36057PQC Video cutting chipset (DC10 Plus)
 
 pci:v000011DEd00006057sv00001031sd0000FC00*
- ID_MODEL_FROM_DATABASE=MiroVIDEO DC50, Motion JPEG Capture/CODEC Board
+ ID_MODEL_FROM_DATABASE=ZR36057PQC Video cutting chipset (MiroVIDEO DC50, Motion JPEG Capture/CODEC Board)
 
 pci:v000011DEd00006057sv000012F8sd00008A02*
- ID_MODEL_FROM_DATABASE=Tekram Video Kit
+ ID_MODEL_FROM_DATABASE=ZR36057PQC Video cutting chipset (Tekram Video Kit)
 
 pci:v000011DEd00006057sv000013CAsd00004231*
- ID_MODEL_FROM_DATABASE=JPEG/TV Card
+ ID_MODEL_FROM_DATABASE=ZR36057PQC Video cutting chipset (JPEG/TV Card)
 
 pci:v000011DEd00006120*
  ID_MODEL_FROM_DATABASE=ZR36120
 
 pci:v000011DEd00006120sv00001328sd0000F001*
- ID_MODEL_FROM_DATABASE=Cinemaster C DVD Decoder
+ ID_MODEL_FROM_DATABASE=ZR36120 (Cinemaster C DVD Decoder)
 
 pci:v000011DEd00006120sv000013C2sd00000000*
- ID_MODEL_FROM_DATABASE=MediaFocus Satellite TV Card
+ ID_MODEL_FROM_DATABASE=ZR36120 (MediaFocus Satellite TV Card)
 
 pci:v000011DEd00006120sv00001DE1sd00009FFF*
- ID_MODEL_FROM_DATABASE=Video Kit C210
+ ID_MODEL_FROM_DATABASE=ZR36120 (Video Kit C210)
 
 pci:v000011DF*
  ID_VENDOR_FROM_DATABASE=New Wave PDG
@@ -35406,13 +36432,13 @@ pci:v000011F6d00002011*
  ID_MODEL_FROM_DATABASE=RL100-ATX 10/100
 
 pci:v000011F6d00002011sv000011F6sd00002011*
- ID_MODEL_FROM_DATABASE=RL100-ATX
+ ID_MODEL_FROM_DATABASE=RL100-ATX 10/100 (RL100-ATX)
 
 pci:v000011F6d00002201*
  ID_MODEL_FROM_DATABASE=ReadyLink 100TX (Winbond W89C840)
 
 pci:v000011F6d00002201sv000011F6sd00002011*
- ID_MODEL_FROM_DATABASE=ReadyLink 100TX
+ ID_MODEL_FROM_DATABASE=ReadyLink 100TX (Winbond W89C840) (ReadyLink 100TX)
 
 pci:v000011F6d00009881*
  ID_MODEL_FROM_DATABASE=RL100TX Fast Ethernet
@@ -35442,10 +36468,10 @@ pci:v000011F8d00008032*
  ID_MODEL_FROM_DATABASE=ATTO Celerity FC8xEN
 
 pci:v000011F8d00008032sv0000117Csd0000003B*
- ID_MODEL_FROM_DATABASE=Celerity FC-82EN Fibre Channel Adapter
+ ID_MODEL_FROM_DATABASE=ATTO Celerity FC8xEN (Celerity FC-82EN Fibre Channel Adapter)
 
 pci:v000011F8d00008032sv0000117Csd0000003C*
- ID_MODEL_FROM_DATABASE=Celerity FC-84EN Fibre Channel Adapter
+ ID_MODEL_FROM_DATABASE=ATTO Celerity FC8xEN (Celerity FC-84EN Fibre Channel Adapter)
 
 pci:v000011F9*
  ID_VENDOR_FROM_DATABASE=I-Cube Inc
@@ -35589,16 +36615,16 @@ pci:v00001202d00004300*
  ID_MODEL_FROM_DATABASE=Gigabit Ethernet Adapter
 
 pci:v00001202d00004300sv00001202sd00009841*
- ID_MODEL_FROM_DATABASE=SK-9841 LX
+ ID_MODEL_FROM_DATABASE=Gigabit Ethernet Adapter (SK-9841 LX)
 
 pci:v00001202d00004300sv00001202sd00009842*
- ID_MODEL_FROM_DATABASE=SK-9841 LX dual link
+ ID_MODEL_FROM_DATABASE=Gigabit Ethernet Adapter (SK-9841 LX dual link)
 
 pci:v00001202d00004300sv00001202sd00009843*
- ID_MODEL_FROM_DATABASE=SK-9843 SX
+ ID_MODEL_FROM_DATABASE=Gigabit Ethernet Adapter (SK-9843 SX)
 
 pci:v00001202d00004300sv00001202sd00009844*
- ID_MODEL_FROM_DATABASE=SK-9843 SX dual link
+ ID_MODEL_FROM_DATABASE=Gigabit Ethernet Adapter (SK-9843 SX dual link)
 
 pci:v00001203*
  ID_VENDOR_FROM_DATABASE=Bayer Corporation, Agfa Division
@@ -35714,8 +36740,11 @@ pci:v00001217*
 pci:v00001217d000000F7*
  ID_MODEL_FROM_DATABASE=Firewire (IEEE 1394)
 
+pci:v00001217d000000F7sv00001071sd00008209*
+ ID_MODEL_FROM_DATABASE=Firewire (IEEE 1394) (Medion MIM 2240 Notebook PC [MD98100])
+
 pci:v00001217d000000F7sv00001179sd0000FF50*
- ID_MODEL_FROM_DATABASE=Satellite P305D-S8995E
+ ID_MODEL_FROM_DATABASE=Firewire (IEEE 1394) (Satellite P305D-S8995E)
 
 pci:v00001217d000010F7*
  ID_MODEL_FROM_DATABASE=1394 OHCI Compliant Host Controller
@@ -35724,7 +36753,7 @@ pci:v00001217d000011F7*
  ID_MODEL_FROM_DATABASE=OZ600 1394a-2000 Controller
 
 pci:v00001217d000011F7sv00001028sd000004A3*
- ID_MODEL_FROM_DATABASE=Precision M4600
+ ID_MODEL_FROM_DATABASE=OZ600 1394a-2000 Controller (Precision M4600)
 
 pci:v00001217d000013F7*
  ID_MODEL_FROM_DATABASE=1394 OHCI Compliant Host Controller
@@ -35751,31 +36780,31 @@ pci:v00001217d00006933*
  ID_MODEL_FROM_DATABASE=OZ6933/711E1 CardBus/SmartCardBus Controller
 
 pci:v00001217d00006933sv00001025sd00001016*
- ID_MODEL_FROM_DATABASE=Travelmate 612 TX
+ ID_MODEL_FROM_DATABASE=OZ6933/711E1 CardBus/SmartCardBus Controller (Travelmate 612 TX)
 
 pci:v00001217d00006972*
  ID_MODEL_FROM_DATABASE=OZ601/6912/711E0 CardBus/SmartCardBus Controller
 
 pci:v00001217d00006972sv00001014sd0000020C*
- ID_MODEL_FROM_DATABASE=ThinkPad R30
+ ID_MODEL_FROM_DATABASE=OZ601/6912/711E0 CardBus/SmartCardBus Controller (ThinkPad R30)
 
 pci:v00001217d00006972sv00001028sd00000152*
- ID_MODEL_FROM_DATABASE=Latitude D500
+ ID_MODEL_FROM_DATABASE=OZ601/6912/711E0 CardBus/SmartCardBus Controller (Latitude D500)
 
 pci:v00001217d00006972sv00001179sd00000001*
- ID_MODEL_FROM_DATABASE=Magnia Z310
+ ID_MODEL_FROM_DATABASE=OZ601/6912/711E0 CardBus/SmartCardBus Controller (Magnia Z310)
 
 pci:v00001217d00007110*
  ID_MODEL_FROM_DATABASE=OZ711Mx 4-in-1 MemoryCardBus Accelerator
 
 pci:v00001217d00007110sv0000103Csd0000088C*
- ID_MODEL_FROM_DATABASE=NC8000 laptop
+ ID_MODEL_FROM_DATABASE=OZ711Mx 4-in-1 MemoryCardBus Accelerator (NC8000 laptop)
 
 pci:v00001217d00007110sv0000103Csd00000890*
- ID_MODEL_FROM_DATABASE=NC6000 laptop
+ ID_MODEL_FROM_DATABASE=OZ711Mx 4-in-1 MemoryCardBus Accelerator (NC6000 laptop)
 
 pci:v00001217d00007110sv00001734sd0000106C*
- ID_MODEL_FROM_DATABASE=Amilo A1645
+ ID_MODEL_FROM_DATABASE=OZ711Mx 4-in-1 MemoryCardBus Accelerator (Amilo A1645)
 
 pci:v00001217d00007112*
  ID_MODEL_FROM_DATABASE=OZ711EC1/M1 SmartCardBus/MemoryCardBus Controller
@@ -35784,7 +36813,7 @@ pci:v00001217d00007113*
  ID_MODEL_FROM_DATABASE=OZ711EC1 SmartCardBus Controller
 
 pci:v00001217d00007113sv00001025sd00000035*
- ID_MODEL_FROM_DATABASE=TravelMate 660
+ ID_MODEL_FROM_DATABASE=OZ711EC1 SmartCardBus Controller (TravelMate 660)
 
 pci:v00001217d00007114*
  ID_MODEL_FROM_DATABASE=OZ711M1/MC1 4-in-1 MemoryCardBus Controller
@@ -35792,14 +36821,20 @@ pci:v00001217d00007114*
 pci:v00001217d00007120*
  ID_MODEL_FROM_DATABASE=Integrated MMC/SD Controller
 
+pci:v00001217d00007120sv00001071sd00008209*
+ ID_MODEL_FROM_DATABASE=Integrated MMC/SD Controller (Medion MIM 2240 Notebook PC [MD98100])
+
 pci:v00001217d00007120sv00001179sd0000FF50*
- ID_MODEL_FROM_DATABASE=Satellite P305D-S8995E
+ ID_MODEL_FROM_DATABASE=Integrated MMC/SD Controller (Satellite P305D-S8995E)
 
 pci:v00001217d00007130*
  ID_MODEL_FROM_DATABASE=Integrated MS/xD Controller
 
+pci:v00001217d00007130sv00001071sd00008209*
+ ID_MODEL_FROM_DATABASE=Integrated MS/xD Controller (Medion MIM 2240 Notebook PC [MD98100])
+
 pci:v00001217d00007130sv00001179sd0000FF50*
- ID_MODEL_FROM_DATABASE=Satellite P305D-S8995E
+ ID_MODEL_FROM_DATABASE=Integrated MS/xD Controller (Satellite P305D-S8995E)
 
 pci:v00001217d00007134*
  ID_MODEL_FROM_DATABASE=OZ711MP1/MS1 MemoryCardBus Controller
@@ -35823,13 +36858,13 @@ pci:v00001217d00007223*
  ID_MODEL_FROM_DATABASE=OZ711M3/MC3 4-in-1 MemoryCardBus Controller
 
 pci:v00001217d00007223sv0000103Csd0000088C*
- ID_MODEL_FROM_DATABASE=NC8000 laptop
+ ID_MODEL_FROM_DATABASE=OZ711M3/MC3 4-in-1 MemoryCardBus Controller (NC8000 laptop)
 
 pci:v00001217d00007223sv0000103Csd00000890*
- ID_MODEL_FROM_DATABASE=NC6000 laptop
+ ID_MODEL_FROM_DATABASE=OZ711M3/MC3 4-in-1 MemoryCardBus Controller (NC6000 laptop)
 
 pci:v00001217d00007223sv000010CFsd000011C4*
- ID_MODEL_FROM_DATABASE=Lifebook P5020D Laptop
+ ID_MODEL_FROM_DATABASE=OZ711M3/MC3 4-in-1 MemoryCardBus Controller (Lifebook P5020D Laptop)
 
 pci:v00001217d00007233*
  ID_MODEL_FROM_DATABASE=OZ711MP3/MS3 4-in-1 MemoryCardBus Controller
@@ -35840,24 +36875,33 @@ pci:v00001217d00008120*
 pci:v00001217d00008130*
  ID_MODEL_FROM_DATABASE=Integrated MS/MSPRO/xD Controller
 
+pci:v00001217d00008220*
+ ID_MODEL_FROM_DATABASE=OZ600FJ1/OZ900FJ1 SD/MMC Card Reader Controller
+
+pci:v00001217d00008221*
+ ID_MODEL_FROM_DATABASE=OZ600FJ0/OZ900FJ0/OZ600FJS SD/MMC Card Reader Controller
+
 pci:v00001217d00008320*
- ID_MODEL_FROM_DATABASE=OZ600 MMC/SD Controller
+ ID_MODEL_FROM_DATABASE=OZ600RJ1/OZ900RJ1 SD/MMC Card Reader Controller
 
 pci:v00001217d00008320sv00001028sd000004A3*
- ID_MODEL_FROM_DATABASE=Precision M4600
+ ID_MODEL_FROM_DATABASE=OZ600RJ1/OZ900RJ1 SD/MMC Card Reader Controller (Precision M4600)
 
 pci:v00001217d00008321*
- ID_MODEL_FROM_DATABASE=Integrated MMC/SD controller
+ ID_MODEL_FROM_DATABASE=OZ600RJ0/OZ900RJ0/OZ600RJS SD/MMC Card Reader Controller
 
 pci:v00001217d00008330*
  ID_MODEL_FROM_DATABASE=OZ600 MS/xD Controller
 
 pci:v00001217d00008330sv00001028sd000004A3*
- ID_MODEL_FROM_DATABASE=Precision M4600
+ ID_MODEL_FROM_DATABASE=OZ600 MS/xD Controller (Precision M4600)
 
 pci:v00001217d00008331*
  ID_MODEL_FROM_DATABASE=O2 Flash Memory Card
 
+pci:v00001217d00008520*
+ ID_MODEL_FROM_DATABASE=SD/MMC Card Reader Controller
+
 pci:v00001218*
  ID_VENDOR_FROM_DATABASE=Hybricon Corp.
 
@@ -35877,52 +36921,52 @@ pci:v0000121Ad00000003*
  ID_MODEL_FROM_DATABASE=Voodoo Banshee
 
 pci:v0000121Ad00000003sv00001092sd00000003*
- ID_MODEL_FROM_DATABASE=Monster Fusion
+ ID_MODEL_FROM_DATABASE=Voodoo Banshee (Monster Fusion)
 
 pci:v0000121Ad00000003sv00001092sd00004000*
- ID_MODEL_FROM_DATABASE=Monster Fusion
+ ID_MODEL_FROM_DATABASE=Voodoo Banshee (Monster Fusion)
 
 pci:v0000121Ad00000003sv00001092sd00004002*
- ID_MODEL_FROM_DATABASE=Monster Fusion
+ ID_MODEL_FROM_DATABASE=Voodoo Banshee (Monster Fusion)
 
 pci:v0000121Ad00000003sv00001092sd00004801*
- ID_MODEL_FROM_DATABASE=Monster Fusion AGP
+ ID_MODEL_FROM_DATABASE=Voodoo Banshee (Monster Fusion AGP)
 
 pci:v0000121Ad00000003sv00001092sd00004803*
- ID_MODEL_FROM_DATABASE=Monster Fusion AGP
+ ID_MODEL_FROM_DATABASE=Voodoo Banshee (Monster Fusion AGP)
 
 pci:v0000121Ad00000003sv00001092sd00008030*
- ID_MODEL_FROM_DATABASE=Monster Fusion
+ ID_MODEL_FROM_DATABASE=Voodoo Banshee (Monster Fusion)
 
 pci:v0000121Ad00000003sv00001092sd00008035*
- ID_MODEL_FROM_DATABASE=Monster Fusion AGP
+ ID_MODEL_FROM_DATABASE=Voodoo Banshee (Monster Fusion AGP)
 
 pci:v0000121Ad00000003sv000010B0sd00000001*
- ID_MODEL_FROM_DATABASE=Dragon 4000
+ ID_MODEL_FROM_DATABASE=Voodoo Banshee (Dragon 4000)
 
 pci:v0000121Ad00000003sv00001102sd00001017*
- ID_MODEL_FROM_DATABASE=3D Blaster Banshee PCI (CT6760)
+ ID_MODEL_FROM_DATABASE=Voodoo Banshee (3D Blaster Banshee PCI (CT6760))
 
 pci:v0000121Ad00000003sv00001102sd00001018*
- ID_MODEL_FROM_DATABASE=3D Blaster Banshee VE
+ ID_MODEL_FROM_DATABASE=Voodoo Banshee (3D Blaster Banshee VE)
 
 pci:v0000121Ad00000003sv0000121Asd00000001*
- ID_MODEL_FROM_DATABASE=Voodoo Banshee AGP
+ ID_MODEL_FROM_DATABASE=Voodoo Banshee (AGP)
 
 pci:v0000121Ad00000003sv0000121Asd00000003*
- ID_MODEL_FROM_DATABASE=Voodoo Banshee AGP SGRAM
+ ID_MODEL_FROM_DATABASE=Voodoo Banshee (AGP SGRAM)
 
 pci:v0000121Ad00000003sv0000121Asd00000004*
  ID_MODEL_FROM_DATABASE=Voodoo Banshee
 
 pci:v0000121Ad00000003sv0000139Csd00000016*
- ID_MODEL_FROM_DATABASE=Raven
+ ID_MODEL_FROM_DATABASE=Voodoo Banshee (Raven)
 
 pci:v0000121Ad00000003sv0000139Csd00000017*
- ID_MODEL_FROM_DATABASE=Raven
+ ID_MODEL_FROM_DATABASE=Voodoo Banshee (Raven)
 
 pci:v0000121Ad00000003sv000014AFsd00000002*
- ID_MODEL_FROM_DATABASE=Maxi Gamer Phoenix
+ ID_MODEL_FROM_DATABASE=Voodoo Banshee (Maxi Gamer Phoenix)
 
 pci:v0000121Ad00000004*
  ID_MODEL_FROM_DATABASE=Voodoo Banshee [Velocity 100]
@@ -35931,70 +36975,70 @@ pci:v0000121Ad00000005*
  ID_MODEL_FROM_DATABASE=Voodoo 3
 
 pci:v0000121Ad00000005sv0000121Asd00000004*
- ID_MODEL_FROM_DATABASE=Voodoo3 AGP
+ ID_MODEL_FROM_DATABASE=Voodoo 3 (Voodoo3 AGP)
 
 pci:v0000121Ad00000005sv0000121Asd00000030*
- ID_MODEL_FROM_DATABASE=Voodoo3 AGP
+ ID_MODEL_FROM_DATABASE=Voodoo 3 (Voodoo3 AGP)
 
 pci:v0000121Ad00000005sv0000121Asd00000031*
- ID_MODEL_FROM_DATABASE=Voodoo3 AGP
+ ID_MODEL_FROM_DATABASE=Voodoo 3 (Voodoo3 AGP)
 
 pci:v0000121Ad00000005sv0000121Asd00000034*
- ID_MODEL_FROM_DATABASE=Voodoo3 AGP
+ ID_MODEL_FROM_DATABASE=Voodoo 3 (Voodoo3 AGP)
 
 pci:v0000121Ad00000005sv0000121Asd00000036*
- ID_MODEL_FROM_DATABASE=Voodoo3 2000 PCI
+ ID_MODEL_FROM_DATABASE=Voodoo 3 (Voodoo3 2000 PCI)
 
 pci:v0000121Ad00000005sv0000121Asd00000037*
- ID_MODEL_FROM_DATABASE=Voodoo3 AGP
+ ID_MODEL_FROM_DATABASE=Voodoo 3 (Voodoo3 AGP)
 
 pci:v0000121Ad00000005sv0000121Asd00000038*
- ID_MODEL_FROM_DATABASE=Voodoo3 AGP
+ ID_MODEL_FROM_DATABASE=Voodoo 3 (Voodoo3 AGP)
 
 pci:v0000121Ad00000005sv0000121Asd0000003A*
- ID_MODEL_FROM_DATABASE=Voodoo3 AGP
+ ID_MODEL_FROM_DATABASE=Voodoo 3 (Voodoo3 AGP)
 
 pci:v0000121Ad00000005sv0000121Asd00000044*
- ID_MODEL_FROM_DATABASE=Voodoo3
+ ID_MODEL_FROM_DATABASE=Voodoo 3 (Voodoo3)
 
 pci:v0000121Ad00000005sv0000121Asd0000004B*
- ID_MODEL_FROM_DATABASE=Velocity 100
+ ID_MODEL_FROM_DATABASE=Voodoo 3 (Velocity 100)
 
 pci:v0000121Ad00000005sv0000121Asd0000004C*
- ID_MODEL_FROM_DATABASE=Velocity 200
+ ID_MODEL_FROM_DATABASE=Voodoo 3 (Velocity 200)
 
 pci:v0000121Ad00000005sv0000121Asd0000004D*
- ID_MODEL_FROM_DATABASE=Voodoo3 AGP
+ ID_MODEL_FROM_DATABASE=Voodoo 3 (Voodoo3 AGP)
 
 pci:v0000121Ad00000005sv0000121Asd0000004E*
- ID_MODEL_FROM_DATABASE=Voodoo3 AGP
+ ID_MODEL_FROM_DATABASE=Voodoo 3 (Voodoo3 AGP)
 
 pci:v0000121Ad00000005sv0000121Asd00000051*
- ID_MODEL_FROM_DATABASE=Voodoo3 AGP
+ ID_MODEL_FROM_DATABASE=Voodoo 3 (Voodoo3 AGP)
 
 pci:v0000121Ad00000005sv0000121Asd00000052*
- ID_MODEL_FROM_DATABASE=Voodoo3 AGP
+ ID_MODEL_FROM_DATABASE=Voodoo 3 (Voodoo3 AGP)
 
 pci:v0000121Ad00000005sv0000121Asd00000057*
- ID_MODEL_FROM_DATABASE=Voodoo3 3000 PCI
+ ID_MODEL_FROM_DATABASE=Voodoo 3 (Voodoo3 3000 PCI)
 
 pci:v0000121Ad00000005sv0000121Asd00000060*
- ID_MODEL_FROM_DATABASE=Voodoo3 3500 TV (NTSC)
+ ID_MODEL_FROM_DATABASE=Voodoo 3 (Voodoo3 3500 TV (NTSC))
 
 pci:v0000121Ad00000005sv0000121Asd00000061*
- ID_MODEL_FROM_DATABASE=Voodoo3 3500 TV (PAL)
+ ID_MODEL_FROM_DATABASE=Voodoo 3 (Voodoo3 3500 TV (PAL))
 
 pci:v0000121Ad00000005sv0000121Asd00000062*
- ID_MODEL_FROM_DATABASE=Voodoo3 3500 TV (SECAM)
+ ID_MODEL_FROM_DATABASE=Voodoo 3 (Voodoo3 3500 TV (SECAM))
 
 pci:v0000121Ad00000009*
  ID_MODEL_FROM_DATABASE=Voodoo 4 / Voodoo 5
 
 pci:v0000121Ad00000009sv0000121Asd00000003*
- ID_MODEL_FROM_DATABASE=Voodoo5 PCI 5500
+ ID_MODEL_FROM_DATABASE=Voodoo 4 / Voodoo 5 (Voodoo5 PCI 5500)
 
 pci:v0000121Ad00000009sv0000121Asd00000009*
- ID_MODEL_FROM_DATABASE=Voodoo5 AGP 5500/6000
+ ID_MODEL_FROM_DATABASE=Voodoo 4 / Voodoo 5 (Voodoo5 AGP 5500/6000)
 
 pci:v0000121Ad00000057*
  ID_MODEL_FROM_DATABASE=Voodoo 3/3000 [Avenger]
@@ -36231,31 +37275,31 @@ pci:v0000123Fd00008120*
  ID_MODEL_FROM_DATABASE=DVxplore Codec
 
 pci:v0000123Fd00008120sv000010DEsd000001E1*
- ID_MODEL_FROM_DATABASE=NVTV PAL
+ ID_MODEL_FROM_DATABASE=DVxplore Codec (NVTV PAL)
 
 pci:v0000123Fd00008120sv000010DEsd000001E2*
- ID_MODEL_FROM_DATABASE=NVTV NTSC
+ ID_MODEL_FROM_DATABASE=DVxplore Codec (NVTV NTSC)
 
 pci:v0000123Fd00008120sv000010DEsd000001E3*
- ID_MODEL_FROM_DATABASE=NVTV PAL
+ ID_MODEL_FROM_DATABASE=DVxplore Codec (NVTV PAL)
 
 pci:v0000123Fd00008120sv000010DEsd00000248*
- ID_MODEL_FROM_DATABASE=NVTV NTSC
+ ID_MODEL_FROM_DATABASE=DVxplore Codec (NVTV NTSC)
 
 pci:v0000123Fd00008120sv000010DEsd00000249*
- ID_MODEL_FROM_DATABASE=NVTV PAL
+ ID_MODEL_FROM_DATABASE=DVxplore Codec (NVTV PAL)
 
 pci:v0000123Fd00008120sv000011BDsd00000006*
- ID_MODEL_FROM_DATABASE=DV500 E4
+ ID_MODEL_FROM_DATABASE=DVxplore Codec (DV500 E4)
 
 pci:v0000123Fd00008120sv000011BDsd0000000A*
- ID_MODEL_FROM_DATABASE=DV500 E4
+ ID_MODEL_FROM_DATABASE=DVxplore Codec (DV500 E4)
 
 pci:v0000123Fd00008120sv000011BDsd0000000F*
- ID_MODEL_FROM_DATABASE=DV500 E4
+ ID_MODEL_FROM_DATABASE=DVxplore Codec (DV500 E4)
 
 pci:v0000123Fd00008120sv00001809sd00000016*
- ID_MODEL_FROM_DATABASE=Emuzed MAUI-III PCI PVR FM TV
+ ID_MODEL_FROM_DATABASE=DVxplore Codec (Emuzed MAUI-III PCI PVR FM TV)
 
 pci:v0000123Fd00008888*
  ID_MODEL_FROM_DATABASE=Cinemaster C 3.0 DVD Decoder
@@ -36282,10 +37326,10 @@ pci:v00001242d00001560*
  ID_MODEL_FROM_DATABASE=JNIC-1560 PCI-X Fibre Channel Controller
 
 pci:v00001242d00001560sv00001242sd00006562*
- ID_MODEL_FROM_DATABASE=FCX2-6562 Dual Channel PCI-X Fibre Channel Adapter
+ ID_MODEL_FROM_DATABASE=JNIC-1560 PCI-X Fibre Channel Controller (FCX2-6562 Dual Channel PCI-X Fibre Channel Adapter)
 
 pci:v00001242d00001560sv00001242sd0000656A*
- ID_MODEL_FROM_DATABASE=FCX-6562 PCI-X Fibre Channel Adapter
+ ID_MODEL_FROM_DATABASE=JNIC-1560 PCI-X Fibre Channel Controller (FCX-6562 PCI-X Fibre Channel Adapter)
 
 pci:v00001242d00004643*
  ID_MODEL_FROM_DATABASE=FCI-1063 Fibre Channel Adapter
@@ -36312,7 +37356,7 @@ pci:v00001244d00000A00*
  ID_MODEL_FROM_DATABASE=A1 ISDN [Fritz]
 
 pci:v00001244d00000A00sv00001244sd00000A00*
- ID_MODEL_FROM_DATABASE=FRITZ!Card ISDN Controller
+ ID_MODEL_FROM_DATABASE=A1 ISDN [Fritz] (FRITZ!Card ISDN Controller)
 
 pci:v00001244d00000E00*
  ID_MODEL_FROM_DATABASE=Fritz!PCI v2.0 ISDN
@@ -36354,7 +37398,7 @@ pci:v0000124Bd00000040*
  ID_MODEL_FROM_DATABASE=PCI-40A or cPCI-200 Quad IndustryPack carrier
 
 pci:v0000124Bd00000040sv0000124Bsd00009080*
- ID_MODEL_FROM_DATABASE=PCI9080 Bridge
+ ID_MODEL_FROM_DATABASE=PCI-40A or cPCI-200 Quad IndustryPack carrier (PCI9080 Bridge)
 
 pci:v0000124C*
  ID_VENDOR_FROM_DATABASE=Solitron Technologies, Inc.
@@ -36465,7 +37509,7 @@ pci:v0000125Bd00001400*
  ID_MODEL_FROM_DATABASE=AX88141 Fast Ethernet Controller
 
 pci:v0000125Bd00001400sv00001186sd00001100*
- ID_MODEL_FROM_DATABASE=AX8814X Based PCI Fast Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=AX88141 Fast Ethernet Controller (AX8814X Based PCI Fast Ethernet Adapter)
 
 pci:v0000125C*
  ID_VENDOR_FROM_DATABASE=Aurora Technologies, Inc.
@@ -36489,61 +37533,61 @@ pci:v0000125Dd00001968*
  ID_MODEL_FROM_DATABASE=ES1968 Maestro 2
 
 pci:v0000125Dd00001968sv00001028sd00000085*
- ID_MODEL_FROM_DATABASE=ES1968 Maestro-2 PCI
+ ID_MODEL_FROM_DATABASE=ES1968 Maestro 2 (ES1968 Maestro-2 PCI)
 
 pci:v0000125Dd00001968sv00001033sd00008051*
- ID_MODEL_FROM_DATABASE=ES1968 Maestro-2 Audiodrive
+ ID_MODEL_FROM_DATABASE=ES1968 Maestro 2 (ES1968 Maestro-2 Audiodrive)
 
 pci:v0000125Dd00001969*
  ID_MODEL_FROM_DATABASE=ES1938/ES1946/ES1969 Solo-1 Audiodrive
 
 pci:v0000125Dd00001969sv00001014sd00000166*
- ID_MODEL_FROM_DATABASE=ES1969 SOLO-1 AudioDrive on IBM Aptiva Mainboard
+ ID_MODEL_FROM_DATABASE=ES1938/ES1946/ES1969 Solo-1 Audiodrive (ES1969 SOLO-1 AudioDrive on IBM Aptiva Mainboard)
 
 pci:v0000125Dd00001969sv0000125Dsd00008888*
- ID_MODEL_FROM_DATABASE=Solo-1 Audio Adapter
+ ID_MODEL_FROM_DATABASE=ES1938/ES1946/ES1969 Solo-1 Audiodrive (Solo-1 Audio Adapter)
 
 pci:v0000125Dd00001969sv0000153Bsd0000111B*
- ID_MODEL_FROM_DATABASE=Terratec 128i PCI
+ ID_MODEL_FROM_DATABASE=ES1938/ES1946/ES1969 Solo-1 Audiodrive (Terratec 128i PCI)
 
 pci:v0000125Dd00001978*
  ID_MODEL_FROM_DATABASE=ES1978 Maestro 2E
 
 pci:v0000125Dd00001978sv00000E11sd0000B112*
- ID_MODEL_FROM_DATABASE=Armada M700/E500
+ ID_MODEL_FROM_DATABASE=ES1978 Maestro 2E (Armada M700/E500)
 
 pci:v0000125Dd00001978sv00001033sd0000803C*
- ID_MODEL_FROM_DATABASE=ES1978 Maestro-2E Audiodrive
+ ID_MODEL_FROM_DATABASE=ES1978 Maestro 2E (ES1978 Maestro-2E Audiodrive)
 
 pci:v0000125Dd00001978sv00001033sd00008058*
- ID_MODEL_FROM_DATABASE=ES1978 Maestro-2E Audiodrive
+ ID_MODEL_FROM_DATABASE=ES1978 Maestro 2E (ES1978 Maestro-2E Audiodrive)
 
 pci:v0000125Dd00001978sv00001092sd00004000*
- ID_MODEL_FROM_DATABASE=Monster Sound MX400
+ ID_MODEL_FROM_DATABASE=ES1978 Maestro 2E (Monster Sound MX400)
 
 pci:v0000125Dd00001978sv00001179sd00000001*
- ID_MODEL_FROM_DATABASE=ES1978 Maestro-2E Audiodrive
+ ID_MODEL_FROM_DATABASE=ES1978 Maestro 2E (ES1978 Maestro-2E Audiodrive)
 
 pci:v0000125Dd00001988*
  ID_MODEL_FROM_DATABASE=ES1988 Allegro-1
 
 pci:v0000125Dd00001988sv00000E11sd00000098*
- ID_MODEL_FROM_DATABASE=Evo N600c
+ ID_MODEL_FROM_DATABASE=ES1988 Allegro-1 (Evo N600c)
 
 pci:v0000125Dd00001988sv00001092sd00004100*
- ID_MODEL_FROM_DATABASE=Sonic Impact S100
+ ID_MODEL_FROM_DATABASE=ES1988 Allegro-1 (Sonic Impact S100)
 
 pci:v0000125Dd00001988sv0000125Dsd00000431*
- ID_MODEL_FROM_DATABASE=Allegro AudioDrive
+ ID_MODEL_FROM_DATABASE=ES1988 Allegro-1 (Allegro AudioDrive)
 
 pci:v0000125Dd00001988sv0000125Dsd00001988*
- ID_MODEL_FROM_DATABASE=ESS Allegro-1 Audiodrive
+ ID_MODEL_FROM_DATABASE=ES1988 Allegro-1 (ESS Allegro-1 Audiodrive)
 
 pci:v0000125Dd00001988sv0000125Dsd00001998*
- ID_MODEL_FROM_DATABASE=Allegro AudioDrive
+ ID_MODEL_FROM_DATABASE=ES1988 Allegro-1 (Allegro AudioDrive)
 
 pci:v0000125Dd00001988sv0000125Dsd00001999*
- ID_MODEL_FROM_DATABASE=Allegro-1 AudioDrive
+ ID_MODEL_FROM_DATABASE=ES1988 Allegro-1 (Allegro-1 AudioDrive)
 
 pci:v0000125Dd00001989*
  ID_MODEL_FROM_DATABASE=ESS Modem
@@ -36555,13 +37599,13 @@ pci:v0000125Dd00001998*
  ID_MODEL_FROM_DATABASE=ES1983S Maestro-3i PCI Audio Accelerator
 
 pci:v0000125Dd00001998sv00001028sd000000B1*
- ID_MODEL_FROM_DATABASE=Latitude C600
+ ID_MODEL_FROM_DATABASE=ES1983S Maestro-3i PCI Audio Accelerator (Latitude C600)
 
 pci:v0000125Dd00001998sv00001028sd000000E5*
- ID_MODEL_FROM_DATABASE=Latitude C810
+ ID_MODEL_FROM_DATABASE=ES1983S Maestro-3i PCI Audio Accelerator (Latitude C810)
 
 pci:v0000125Dd00001998sv00001028sd000000E6*
- ID_MODEL_FROM_DATABASE=ES1983S Maestro-3i (Dell Inspiron 8100)
+ ID_MODEL_FROM_DATABASE=ES1983S Maestro-3i PCI Audio Accelerator (ES1983S Maestro-3i (Dell Inspiron 8100))
 
 pci:v0000125Dd00001999*
  ID_MODEL_FROM_DATABASE=ES1983S Maestro-3i PCI Modem Accelerator
@@ -36582,34 +37626,34 @@ pci:v0000125Dd00002898*
  ID_MODEL_FROM_DATABASE=ES2898 Modem
 
 pci:v0000125Dd00002898sv0000125Dsd00000424*
- ID_MODEL_FROM_DATABASE=ES56-PI Data Fax Modem
+ ID_MODEL_FROM_DATABASE=ES2898 Modem (ES56-PI Data Fax Modem)
 
 pci:v0000125Dd00002898sv0000125Dsd00000425*
- ID_MODEL_FROM_DATABASE=ES56T-PI Data Fax Modem
+ ID_MODEL_FROM_DATABASE=ES2898 Modem (ES56T-PI Data Fax Modem)
 
 pci:v0000125Dd00002898sv0000125Dsd00000426*
- ID_MODEL_FROM_DATABASE=ES56V-PI Data Fax Modem
+ ID_MODEL_FROM_DATABASE=ES2898 Modem (ES56V-PI Data Fax Modem)
 
 pci:v0000125Dd00002898sv0000125Dsd00000427*
- ID_MODEL_FROM_DATABASE=VW-PI Data Fax Modem
+ ID_MODEL_FROM_DATABASE=ES2898 Modem (VW-PI Data Fax Modem)
 
 pci:v0000125Dd00002898sv0000125Dsd00000428*
- ID_MODEL_FROM_DATABASE=ES56ST-PI Data Fax Modem
+ ID_MODEL_FROM_DATABASE=ES2898 Modem (ES56ST-PI Data Fax Modem)
 
 pci:v0000125Dd00002898sv0000125Dsd00000429*
- ID_MODEL_FROM_DATABASE=ES56SV-PI Data Fax Modem
+ ID_MODEL_FROM_DATABASE=ES2898 Modem (ES56SV-PI Data Fax Modem)
 
 pci:v0000125Dd00002898sv0000147Asd0000C001*
- ID_MODEL_FROM_DATABASE=ES56-PI Data Fax Modem
+ ID_MODEL_FROM_DATABASE=ES2898 Modem (ES56-PI Data Fax Modem)
 
 pci:v0000125Dd00002898sv0000148Dsd00001030*
- ID_MODEL_FROM_DATABASE=HCF WV-PI56 [ESS ES56-PI Data Fax Modem]
+ ID_MODEL_FROM_DATABASE=ES2898 Modem (HCF WV-PI56 [ESS ES56-PI Data Fax Modem])
 
 pci:v0000125Dd00002898sv000014FEsd00000428*
- ID_MODEL_FROM_DATABASE=ES56-PI Data Fax Modem
+ ID_MODEL_FROM_DATABASE=ES2898 Modem (ES56-PI Data Fax Modem)
 
 pci:v0000125Dd00002898sv000014FEsd00000429*
- ID_MODEL_FROM_DATABASE=ES56-PI Data Fax Modem
+ ID_MODEL_FROM_DATABASE=ES2898 Modem (ES56-PI Data Fax Modem)
 
 pci:v0000125E*
  ID_VENDOR_FROM_DATABASE=Specialvideo Engineering SRL
@@ -36624,40 +37668,40 @@ pci:v00001260d00003872*
  ID_MODEL_FROM_DATABASE=ISL3872 [Prism 3]
 
 pci:v00001260d00003872sv00001468sd00000202*
- ID_MODEL_FROM_DATABASE=LAN-Express IEEE 802.11b Wireless LAN
+ ID_MODEL_FROM_DATABASE=ISL3872 [Prism 3] (LAN-Express IEEE 802.11b Wireless LAN)
 
 pci:v00001260d00003873*
  ID_MODEL_FROM_DATABASE=ISL3874 [Prism 2.5]/ISL3872 [Prism 3]
 
 pci:v00001260d00003873sv000010CFsd00001169*
- ID_MODEL_FROM_DATABASE=MBH7WM01-8734 802.11b Wireless Mini PCI Card [ISL3874]
+ ID_MODEL_FROM_DATABASE=ISL3874 [Prism 2.5]/ISL3872 [Prism 3] (MBH7WM01-8734 802.11b Wireless Mini PCI Card [ISL3874])
 
 pci:v00001260d00003873sv00001186sd00003501*
- ID_MODEL_FROM_DATABASE=DWL-520 Wireless PCI Adapter (rev A or B) [ISL3874]
+ ID_MODEL_FROM_DATABASE=ISL3874 [Prism 2.5]/ISL3872 [Prism 3] (DWL-520 Wireless PCI Adapter (rev A or B) [ISL3874])
 
 pci:v00001260d00003873sv00001186sd00003700*
- ID_MODEL_FROM_DATABASE=DWL-520 Wireless PCI Adapter (rev E1) [ISL3872]
+ ID_MODEL_FROM_DATABASE=ISL3874 [Prism 2.5]/ISL3872 [Prism 3] (DWL-520 Wireless PCI Adapter (rev E1) [ISL3872])
 
 pci:v00001260d00003873sv00001385sd00004105*
- ID_MODEL_FROM_DATABASE=MA311 802.11b wireless adapter [ISL3874]
+ ID_MODEL_FROM_DATABASE=ISL3874 [Prism 2.5]/ISL3872 [Prism 3] (MA311 802.11b wireless adapter [ISL3874])
 
 pci:v00001260d00003873sv00001668sd00000414*
- ID_MODEL_FROM_DATABASE=HWP01170-01 802.11b PCI Wireless Adapter
+ ID_MODEL_FROM_DATABASE=ISL3874 [Prism 2.5]/ISL3872 [Prism 3] (HWP01170-01 802.11b PCI Wireless Adapter)
 
 pci:v00001260d00003873sv000016A5sd00001601*
- ID_MODEL_FROM_DATABASE=AIR.mate PC-400 PCI Wireless LAN Adapter
+ ID_MODEL_FROM_DATABASE=ISL3874 [Prism 2.5]/ISL3872 [Prism 3] (AIR.mate PC-400 PCI Wireless LAN Adapter)
 
 pci:v00001260d00003873sv00001737sd00003874*
- ID_MODEL_FROM_DATABASE=WMP11 v1 802.11b Wireless-B PCI Adapter [ISL3874]
+ ID_MODEL_FROM_DATABASE=ISL3874 [Prism 2.5]/ISL3872 [Prism 3] (WMP11 v1 802.11b Wireless-B PCI Adapter [ISL3874])
 
 pci:v00001260d00003873sv00004033sd00007033*
- ID_MODEL_FROM_DATABASE=PCW200 802.11b Wireless PCI Adapter [ISL3874]
+ ID_MODEL_FROM_DATABASE=ISL3874 [Prism 2.5]/ISL3872 [Prism 3] (PCW200 802.11b Wireless PCI Adapter [ISL3874])
 
 pci:v00001260d00003873sv00008086sd00002510*
- ID_MODEL_FROM_DATABASE=M3AWEB Wireless 802.11b MiniPCI Adapter
+ ID_MODEL_FROM_DATABASE=ISL3874 [Prism 2.5]/ISL3872 [Prism 3] (M3AWEB Wireless 802.11b MiniPCI Adapter)
 
 pci:v00001260d00003873sv00008086sd00002513*
- ID_MODEL_FROM_DATABASE=Wireless 802.11b MiniPCI Adapter
+ ID_MODEL_FROM_DATABASE=ISL3874 [Prism 2.5]/ISL3872 [Prism 3] (Wireless 802.11b MiniPCI Adapter)
 
 pci:v00001260d00003877*
  ID_MODEL_FROM_DATABASE=ISL3877 [Prism Indigo]
@@ -36666,58 +37710,58 @@ pci:v00001260d00003886*
  ID_MODEL_FROM_DATABASE=ISL3886 [Prism Javelin/Prism Xbow]
 
 pci:v00001260d00003886sv000017CFsd00000037*
- ID_MODEL_FROM_DATABASE=XG-901 and clones Wireless Adapter
+ ID_MODEL_FROM_DATABASE=ISL3886 [Prism Javelin/Prism Xbow] (XG-901 and clones Wireless Adapter)
 
 pci:v00001260d00003890*
  ID_MODEL_FROM_DATABASE=ISL3890 [Prism GT/Prism Duette]/ISL3886 [Prism Javelin/Prism Xbow]
 
 pci:v00001260d00003890sv000010B8sd00002802*
- ID_MODEL_FROM_DATABASE=SMC2802W V1 Wireless PCI Adapter [ISL3890]
+ ID_MODEL_FROM_DATABASE=ISL3890 [Prism GT/Prism Duette]/ISL3886 [Prism Javelin/Prism Xbow] (SMC2802W V1 Wireless PCI Adapter [ISL3890])
 
 pci:v00001260d00003890sv000010B8sd00002835*
- ID_MODEL_FROM_DATABASE=SMC2835W Wireless Cardbus Adapter
+ ID_MODEL_FROM_DATABASE=ISL3890 [Prism GT/Prism Duette]/ISL3886 [Prism Javelin/Prism Xbow] (SMC2835W Wireless Cardbus Adapter)
 
 pci:v00001260d00003890sv000010B8sd0000A835*
- ID_MODEL_FROM_DATABASE=SMC2835W V2 Wireless Cardbus Adapter
+ ID_MODEL_FROM_DATABASE=ISL3890 [Prism GT/Prism Duette]/ISL3886 [Prism Javelin/Prism Xbow] (SMC2835W V2 Wireless Cardbus Adapter)
 
 pci:v00001260d00003890sv00001113sd00004203*
- ID_MODEL_FROM_DATABASE=WN4201B
+ ID_MODEL_FROM_DATABASE=ISL3890 [Prism GT/Prism Duette]/ISL3886 [Prism Javelin/Prism Xbow] (WN4201B)
 
 pci:v00001260d00003890sv00001113sd00008201*
- ID_MODEL_FROM_DATABASE=T-Com T-Sinus 154pcicard Wireless PCI Adapter
+ ID_MODEL_FROM_DATABASE=ISL3890 [Prism GT/Prism Duette]/ISL3886 [Prism Javelin/Prism Xbow] (T-Com T-Sinus 154pcicard Wireless PCI Adapter)
 
 pci:v00001260d00003890sv00001113sd0000B301*
- ID_MODEL_FROM_DATABASE=T-Sinus 154card Cardbus
+ ID_MODEL_FROM_DATABASE=ISL3890 [Prism GT/Prism Duette]/ISL3886 [Prism Javelin/Prism Xbow] (T-Sinus 154card Cardbus)
 
 pci:v00001260d00003890sv00001113sd0000EE03*
- ID_MODEL_FROM_DATABASE=SMC2802W V2 Wireless PCI Adapter [ISL3886]
+ ID_MODEL_FROM_DATABASE=ISL3890 [Prism GT/Prism Duette]/ISL3886 [Prism Javelin/Prism Xbow] (SMC2802W V2 Wireless PCI Adapter [ISL3886])
 
 pci:v00001260d00003890sv00001113sd0000EE08*
- ID_MODEL_FROM_DATABASE=SMC2835W V3 EU Wireless Cardbus Adapter
+ ID_MODEL_FROM_DATABASE=ISL3890 [Prism GT/Prism Duette]/ISL3886 [Prism Javelin/Prism Xbow] (SMC2835W V3 EU Wireless Cardbus Adapter)
 
 pci:v00001260d00003890sv00001186sd00003202*
- ID_MODEL_FROM_DATABASE=DWL-G650 A1 Wireless Adapter
+ ID_MODEL_FROM_DATABASE=ISL3890 [Prism GT/Prism Duette]/ISL3886 [Prism Javelin/Prism Xbow] (DWL-G650 A1 Wireless Adapter)
 
 pci:v00001260d00003890sv00001259sd0000C104*
- ID_MODEL_FROM_DATABASE=CG-WLCB54GT Wireless Adapter
+ ID_MODEL_FROM_DATABASE=ISL3890 [Prism GT/Prism Duette]/ISL3886 [Prism Javelin/Prism Xbow] (CG-WLCB54GT Wireless Adapter)
 
 pci:v00001260d00003890sv00001260sd00000000*
- ID_MODEL_FROM_DATABASE=WG511 v1 54 Mbps Wireless PC Card
+ ID_MODEL_FROM_DATABASE=ISL3890 [Prism GT/Prism Duette]/ISL3886 [Prism Javelin/Prism Xbow] (WG511 v1 54 Mbps Wireless PC Card)
 
 pci:v00001260d00003890sv00001385sd00004800*
- ID_MODEL_FROM_DATABASE=WG511 v2/v3 54 Mbps Wireless PC Card
+ ID_MODEL_FROM_DATABASE=ISL3890 [Prism GT/Prism Duette]/ISL3886 [Prism Javelin/Prism Xbow] (WG511 v2/v3 54 Mbps Wireless PC Card)
 
 pci:v00001260d00003890sv000016A5sd00001605*
- ID_MODEL_FROM_DATABASE=ALLNET ALL0271 Wireless PCI Adapter
+ ID_MODEL_FROM_DATABASE=ISL3890 [Prism GT/Prism Duette]/ISL3886 [Prism Javelin/Prism Xbow] (ALLNET ALL0271 Wireless PCI Adapter)
 
 pci:v00001260d00003890sv000017CFsd00000014*
- ID_MODEL_FROM_DATABASE=XG-600 and clones Wireless Adapter
+ ID_MODEL_FROM_DATABASE=ISL3890 [Prism GT/Prism Duette]/ISL3886 [Prism Javelin/Prism Xbow] (XG-600 and clones Wireless Adapter)
 
 pci:v00001260d00003890sv000017CFsd00000020*
- ID_MODEL_FROM_DATABASE=XG-900 and clones Wireless Adapter
+ ID_MODEL_FROM_DATABASE=ISL3890 [Prism GT/Prism Duette]/ISL3886 [Prism Javelin/Prism Xbow] (XG-900 and clones Wireless Adapter)
 
 pci:v00001260d00003890sv0000187Esd00003403*
- ID_MODEL_FROM_DATABASE=G-110 802.11g Wireless Cardbus Adapter
+ ID_MODEL_FROM_DATABASE=ISL3890 [Prism GT/Prism Duette]/ISL3886 [Prism Javelin/Prism Xbow] (G-110 802.11g Wireless Cardbus Adapter)
 
 pci:v00001260d00008130*
  ID_MODEL_FROM_DATABASE=HMP8130 NTSC/PAL Video Decoder
@@ -36729,7 +37773,7 @@ pci:v00001260d0000FFFF*
  ID_MODEL_FROM_DATABASE=ISL3886IK
 
 pci:v00001260d0000FFFFsv00001260sd00000000*
- ID_MODEL_FROM_DATABASE=Senao 3054MP+ (J) mini-PCI WLAN 802.11g adapter
+ ID_MODEL_FROM_DATABASE=ISL3886IK (Senao 3054MP+ (J) mini-PCI WLAN 802.11g adapter)
 
 pci:v00001261*
  ID_VENDOR_FROM_DATABASE=Matsushita-Kotobuki Electronics Industries, Ltd.
@@ -36756,7 +37800,7 @@ pci:v00001266d00001910*
  ID_MODEL_FROM_DATABASE=NE2000Plus (RT8029) Ethernet Adapter
 
 pci:v00001266d00001910sv00001266sd00001910*
- ID_MODEL_FROM_DATABASE=NE2000Plus Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=NE2000Plus (RT8029) Ethernet Adapter (NE2000Plus Ethernet Adapter)
 
 pci:v00001267*
  ID_VENDOR_FROM_DATABASE=S. A. Telecommunications
@@ -36852,172 +37896,172 @@ pci:v00001274d00001171*
  ID_MODEL_FROM_DATABASE=ES1373 [AudioPCI] (also Creative Labs CT5803)
 
 pci:v00001274d00001371*
- ID_MODEL_FROM_DATABASE=ES1371 [AudioPCI-97]
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97]
 
 pci:v00001274d00001371sv00000E11sd00000024*
- ID_MODEL_FROM_DATABASE=AudioPCI on Motherboard Compaq Deskpro
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (AudioPCI on Motherboard Compaq Deskpro)
 
 pci:v00001274d00001371sv00000E11sd0000B1A7*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI)
 
 pci:v00001274d00001371sv00001033sd000080AC*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI)
 
 pci:v00001274d00001371sv00001042sd00001854*
- ID_MODEL_FROM_DATABASE=Tazer
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (Tazer)
 
 pci:v00001274d00001371sv0000107Bsd00008054*
- ID_MODEL_FROM_DATABASE=Tabor2
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (Tabor2)
 
 pci:v00001274d00001371sv00001274sd00001371*
- ID_MODEL_FROM_DATABASE=Creative Sound Blaster AudioPCI64V, AudioPCI128
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (AudioPCI 64V/128 / Creative Sound Blaster CT4810)
 
 pci:v00001274d00001371sv00001274sd00008001*
- ID_MODEL_FROM_DATABASE=CT4751 board
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (CT4751 board)
 
 pci:v00001274d00001371sv00001462sd00006470*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6147 1.1A
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard MS-6147 1.1A)
 
 pci:v00001274d00001371sv00001462sd00006560*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6156 1.10
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard MS-6156 1.10)
 
 pci:v00001274d00001371sv00001462sd00006630*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6163BX 1.0A
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard MS-6163BX 1.0A)
 
 pci:v00001274d00001371sv00001462sd00006631*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6163VIA 1.0A
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard MS-6163VIA 1.0A)
 
 pci:v00001274d00001371sv00001462sd00006632*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6163BX 2.0A
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard MS-6163BX 2.0A)
 
 pci:v00001274d00001371sv00001462sd00006633*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6163VIA 2.0A
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard MS-6163VIA 2.0A)
 
 pci:v00001274d00001371sv00001462sd00006820*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6182 1.00
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard MS-6182 1.00)
 
 pci:v00001274d00001371sv00001462sd00006822*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6182 1.00A
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard MS-6182 1.00A)
 
 pci:v00001274d00001371sv00001462sd00006830*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6183 1.00
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard MS-6183 1.00)
 
 pci:v00001274d00001371sv00001462sd00006880*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6188 1.00
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard MS-6188 1.00)
 
 pci:v00001274d00001371sv00001462sd00006900*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6190 1.00
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard MS-6190 1.00)
 
 pci:v00001274d00001371sv00001462sd00006910*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6191
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard MS-6191)
 
 pci:v00001274d00001371sv00001462sd00006930*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6193
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard MS-6193)
 
 pci:v00001274d00001371sv00001462sd00006990*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6199BX 2.0A
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard MS-6199BX 2.0A)
 
 pci:v00001274d00001371sv00001462sd00006991*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MS-6199VIA 2.0A
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard MS-6199VIA 2.0A)
 
 pci:v00001274d00001371sv000014A4sd00002077*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard KR639
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard KR639)
 
 pci:v00001274d00001371sv000014A4sd00002105*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MR800
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard MR800)
 
 pci:v00001274d00001371sv000014A4sd00002107*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard MR801
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard MR801)
 
 pci:v00001274d00001371sv000014A4sd00002172*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard DR739
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard DR739)
 
 pci:v00001274d00001371sv00001509sd00009902*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard KW11
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard KW11)
 
 pci:v00001274d00001371sv00001509sd00009903*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard KW31
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard KW31)
 
 pci:v00001274d00001371sv00001509sd00009904*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard KA11
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard KA11)
 
 pci:v00001274d00001371sv00001509sd00009905*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard KC13
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard KC13)
 
 pci:v00001274d00001371sv0000152Dsd00008801*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard CP810E
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard CP810E)
 
 pci:v00001274d00001371sv0000152Dsd00008802*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard CP810
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard CP810)
 
 pci:v00001274d00001371sv0000152Dsd00008803*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard P3810E
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard P3810E)
 
 pci:v00001274d00001371sv0000152Dsd00008804*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard P3810-S
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard P3810-S)
 
 pci:v00001274d00001371sv0000152Dsd00008805*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard P3820-S
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard P3820-S)
 
 pci:v00001274d00001371sv0000270Fsd00002001*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard 6CTR
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard 6CTR)
 
 pci:v00001274d00001371sv0000270Fsd00002200*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard 6WTX
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard 6WTX)
 
 pci:v00001274d00001371sv0000270Fsd00003000*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard 6WSV
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard 6WSV)
 
 pci:v00001274d00001371sv0000270Fsd00003100*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard 6WIV2
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard 6WIV2)
 
 pci:v00001274d00001371sv0000270Fsd00003102*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard 6WIV
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard 6WIV)
 
 pci:v00001274d00001371sv0000270Fsd00007060*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard 6ASA2
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard 6ASA2)
 
 pci:v00001274d00001371sv00008086sd00004249*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard BI440ZX
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard BI440ZX)
 
 pci:v00001274d00001371sv00008086sd0000424C*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard BL440ZX
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard BL440ZX)
 
 pci:v00001274d00001371sv00008086sd0000425A*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard BZ440ZX
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard BZ440ZX)
 
 pci:v00001274d00001371sv00008086sd00004341*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard Cayman
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard Cayman)
 
 pci:v00001274d00001371sv00008086sd00004343*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard Cape Cod
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard Cape Cod)
 
 pci:v00001274d00001371sv00008086sd00004541*
- ID_MODEL_FROM_DATABASE=D815EEA Motherboard
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (D815EEA Motherboard)
 
 pci:v00001274d00001371sv00008086sd00004649*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard Fire Island
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard Fire Island)
 
 pci:v00001274d00001371sv00008086sd0000464A*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard FJ440ZX
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard FJ440ZX)
 
 pci:v00001274d00001371sv00008086sd00004D4F*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard Montreal
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard Montreal)
 
 pci:v00001274d00001371sv00008086sd00004F43*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard OC440LX
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard OC440LX)
 
 pci:v00001274d00001371sv00008086sd00005243*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard RC440BX
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard RC440BX)
 
 pci:v00001274d00001371sv00008086sd00005352*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard SunRiver
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard SunRiver)
 
 pci:v00001274d00001371sv00008086sd00005643*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard Vancouver
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard Vancouver)
 
 pci:v00001274d00001371sv00008086sd00005753*
- ID_MODEL_FROM_DATABASE=ES1371, ES1373 AudioPCI On Motherboard WS440BX
+ ID_MODEL_FROM_DATABASE=ES1371 / Creative Labs CT2518 [AudioPCI-97] (ES1371, ES1373 AudioPCI On Motherboard WS440BX)
 
 pci:v00001274d00005000*
  ID_MODEL_FROM_DATABASE=ES1370 [AudioPCI]
@@ -37026,31 +38070,31 @@ pci:v00001274d00005880*
  ID_MODEL_FROM_DATABASE=5880B [AudioPCI]
 
 pci:v00001274d00005880sv00001274sd00002000*
- ID_MODEL_FROM_DATABASE=Creative Sound Blaster AudioPCI128
+ ID_MODEL_FROM_DATABASE=5880B [AudioPCI] (Creative Sound Blaster AudioPCI128)
 
 pci:v00001274d00005880sv00001274sd00002003*
- ID_MODEL_FROM_DATABASE=Creative SoundBlaster AudioPCI 128
+ ID_MODEL_FROM_DATABASE=5880B [AudioPCI] (Creative SoundBlaster AudioPCI 128)
 
 pci:v00001274d00005880sv00001274sd00005880*
- ID_MODEL_FROM_DATABASE=Creative Sound Blaster AudioPCI128
+ ID_MODEL_FROM_DATABASE=5880B [AudioPCI] (Creative Sound Blaster AudioPCI128)
 
 pci:v00001274d00005880sv00001274sd00008001*
- ID_MODEL_FROM_DATABASE=Sound Blaster 16PCI 4.1ch
+ ID_MODEL_FROM_DATABASE=5880B [AudioPCI] (Sound Blaster 16PCI 4.1ch)
 
 pci:v00001274d00005880sv00001458sd0000A000*
- ID_MODEL_FROM_DATABASE=5880 AudioPCI On Motherboard 6OXET
+ ID_MODEL_FROM_DATABASE=5880B [AudioPCI] (5880 AudioPCI On Motherboard 6OXET)
 
 pci:v00001274d00005880sv00001462sd00006880*
- ID_MODEL_FROM_DATABASE=5880 AudioPCI On Motherboard MS-6188 1.00
+ ID_MODEL_FROM_DATABASE=5880B [AudioPCI] (5880 AudioPCI On Motherboard MS-6188 1.00)
 
 pci:v00001274d00005880sv0000270Fsd00002001*
- ID_MODEL_FROM_DATABASE=5880 AudioPCI On Motherboard 6CTR
+ ID_MODEL_FROM_DATABASE=5880B [AudioPCI] (5880 AudioPCI On Motherboard 6CTR)
 
 pci:v00001274d00005880sv0000270Fsd00002200*
- ID_MODEL_FROM_DATABASE=5880 AudioPCI On Motherboard 6WTX
+ ID_MODEL_FROM_DATABASE=5880B [AudioPCI] (5880 AudioPCI On Motherboard 6WTX)
 
 pci:v00001274d00005880sv0000270Fsd00007040*
- ID_MODEL_FROM_DATABASE=5880 AudioPCI On Motherboard 6ATA4
+ ID_MODEL_FROM_DATABASE=5880B [AudioPCI] (5880 AudioPCI On Motherboard 6ATA4)
 
 pci:v00001274d00008001*
  ID_MODEL_FROM_DATABASE=CT5880 [AudioPCI]
@@ -37110,181 +38154,181 @@ pci:v0000127Ad00001002*
  ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem
 
 pci:v0000127Ad00001002sv00001092sd0000094C*
- ID_MODEL_FROM_DATABASE=SupraExpress 56i PRO [Diamond SUP2380]
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (SupraExpress 56i PRO [Diamond SUP2380])
 
 pci:v0000127Ad00001002sv0000122Dsd00004002*
- ID_MODEL_FROM_DATABASE=HPG / MDP3858-U
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (HPG / MDP3858-U)
 
 pci:v0000127Ad00001002sv0000122Dsd00004005*
- ID_MODEL_FROM_DATABASE=MDP3858-E
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (MDP3858-E)
 
 pci:v0000127Ad00001002sv0000122Dsd00004007*
- ID_MODEL_FROM_DATABASE=MDP3858-A/-NZ
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (MDP3858-A/-NZ)
 
 pci:v0000127Ad00001002sv0000122Dsd00004012*
- ID_MODEL_FROM_DATABASE=MDP3858-SA
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (MDP3858-SA)
 
 pci:v0000127Ad00001002sv0000122Dsd00004017*
- ID_MODEL_FROM_DATABASE=MDP3858-W
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (MDP3858-W)
 
 pci:v0000127Ad00001002sv0000122Dsd00004018*
- ID_MODEL_FROM_DATABASE=MDP3858-W
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (MDP3858-W)
 
 pci:v0000127Ad00001002sv0000127Asd00001002*
- ID_MODEL_FROM_DATABASE=Rockwell 56K D/F HCF Modem
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (Rockwell 56K D/F HCF Modem)
 
 pci:v0000127Ad00001003*
  ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem
 
 pci:v0000127Ad00001003sv00000E11sd0000B0BC*
- ID_MODEL_FROM_DATABASE=229-DF Zephyr
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (229-DF Zephyr)
 
 pci:v0000127Ad00001003sv00000E11sd0000B114*
- ID_MODEL_FROM_DATABASE=229-DF Cheetah
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (229-DF Cheetah)
 
 pci:v0000127Ad00001003sv00001033sd0000802B*
- ID_MODEL_FROM_DATABASE=229-DF
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (229-DF)
 
 pci:v0000127Ad00001003sv000013DFsd00001003*
- ID_MODEL_FROM_DATABASE=PCI56RX Modem
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (PCI56RX Modem)
 
 pci:v0000127Ad00001003sv000013E0sd00000117*
- ID_MODEL_FROM_DATABASE=IBM
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (IBM)
 
 pci:v0000127Ad00001003sv000013E0sd00000147*
- ID_MODEL_FROM_DATABASE=IBM F-1156IV+/R3 Spain V.90 Modem
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (IBM F-1156IV+/R3 Spain V.90 Modem)
 
 pci:v0000127Ad00001003sv000013E0sd00000197*
- ID_MODEL_FROM_DATABASE=IBM
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (IBM)
 
 pci:v0000127Ad00001003sv000013E0sd000001C7*
- ID_MODEL_FROM_DATABASE=IBM F-1156IV+/R3 WW V.90 Modem
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (IBM F-1156IV+/R3 WW V.90 Modem)
 
 pci:v0000127Ad00001003sv000013E0sd000001F7*
- ID_MODEL_FROM_DATABASE=IBM
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (IBM)
 
 pci:v0000127Ad00001003sv00001436sd00001003*
- ID_MODEL_FROM_DATABASE=IBM
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (IBM)
 
 pci:v0000127Ad00001003sv00001436sd00001103*
- ID_MODEL_FROM_DATABASE=IBM 5614PM3G V.90 Modem
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (IBM 5614PM3G V.90 Modem)
 
 pci:v0000127Ad00001003sv00001436sd00001602*
- ID_MODEL_FROM_DATABASE=Compaq 229-DF Ducati
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (Compaq 229-DF Ducati)
 
 pci:v0000127Ad00001004*
  ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice Modem
 
 pci:v0000127Ad00001004sv00001048sd00001500*
- ID_MODEL_FROM_DATABASE=MicroLink 56k Modem
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice Modem (MicroLink 56k Modem)
 
 pci:v0000127Ad00001004sv000010CFsd00001059*
- ID_MODEL_FROM_DATABASE=Fujitsu 229-DFRT
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice Modem (Fujitsu 229-DFRT)
 
 pci:v0000127Ad00001005*
  ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
 
 pci:v0000127Ad00001005sv00001005sd0000127A*
- ID_MODEL_FROM_DATABASE=AOpen FM56-P
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (AOpen FM56-P)
 
 pci:v0000127Ad00001005sv00001033sd00008029*
- ID_MODEL_FROM_DATABASE=229-DFSV
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (229-DFSV)
 
 pci:v0000127Ad00001005sv00001033sd00008054*
- ID_MODEL_FROM_DATABASE=Modem
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (Modem)
 
 pci:v0000127Ad00001005sv000010CFsd0000103C*
- ID_MODEL_FROM_DATABASE=Fujitsu
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (Fujitsu)
 
 pci:v0000127Ad00001005sv000010CFsd00001055*
- ID_MODEL_FROM_DATABASE=Fujitsu 229-DFSV
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (Fujitsu 229-DFSV)
 
 pci:v0000127Ad00001005sv000010CFsd00001056*
- ID_MODEL_FROM_DATABASE=Fujitsu 229-DFSV
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (Fujitsu 229-DFSV)
 
 pci:v0000127Ad00001005sv0000122Dsd00004003*
- ID_MODEL_FROM_DATABASE=MDP3858SP-U
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (MDP3858SP-U)
 
 pci:v0000127Ad00001005sv0000122Dsd00004006*
- ID_MODEL_FROM_DATABASE=Packard Bell MDP3858V-E
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (Packard Bell MDP3858V-E)
 
 pci:v0000127Ad00001005sv0000122Dsd00004008*
- ID_MODEL_FROM_DATABASE=MDP3858SP-A/SP-NZ
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (MDP3858SP-A/SP-NZ)
 
 pci:v0000127Ad00001005sv0000122Dsd00004009*
- ID_MODEL_FROM_DATABASE=MDP3858SP-E
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (MDP3858SP-E)
 
 pci:v0000127Ad00001005sv0000122Dsd00004010*
- ID_MODEL_FROM_DATABASE=MDP3858V-U
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (MDP3858V-U)
 
 pci:v0000127Ad00001005sv0000122Dsd00004011*
- ID_MODEL_FROM_DATABASE=MDP3858SP-SA
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (MDP3858SP-SA)
 
 pci:v0000127Ad00001005sv0000122Dsd00004013*
- ID_MODEL_FROM_DATABASE=MDP3858V-A/V-NZ
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (MDP3858V-A/V-NZ)
 
 pci:v0000127Ad00001005sv0000122Dsd00004015*
- ID_MODEL_FROM_DATABASE=MDP3858SP-W
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (MDP3858SP-W)
 
 pci:v0000127Ad00001005sv0000122Dsd00004016*
- ID_MODEL_FROM_DATABASE=MDP3858V-W
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (MDP3858V-W)
 
 pci:v0000127Ad00001005sv0000122Dsd00004019*
- ID_MODEL_FROM_DATABASE=MDP3858V-SA
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (MDP3858V-SA)
 
 pci:v0000127Ad00001005sv000013DFsd00001005*
- ID_MODEL_FROM_DATABASE=PCI56RVP Modem
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (PCI56RVP Modem)
 
 pci:v0000127Ad00001005sv000013E0sd00000187*
- ID_MODEL_FROM_DATABASE=IBM
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (IBM)
 
 pci:v0000127Ad00001005sv000013E0sd000001A7*
- ID_MODEL_FROM_DATABASE=IBM
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (IBM)
 
 pci:v0000127Ad00001005sv000013E0sd000001B7*
- ID_MODEL_FROM_DATABASE=IBM DF-1156IV+/R3 Spain V.90 Modem
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (IBM DF-1156IV+/R3 Spain V.90 Modem)
 
 pci:v0000127Ad00001005sv000013E0sd000001D7*
- ID_MODEL_FROM_DATABASE=IBM DF-1156IV+/R3 WW V.90 Modem
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (IBM DF-1156IV+/R3 WW V.90 Modem)
 
 pci:v0000127Ad00001005sv00001436sd00001005*
- ID_MODEL_FROM_DATABASE=IBM
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (IBM)
 
 pci:v0000127Ad00001005sv00001436sd00001105*
- ID_MODEL_FROM_DATABASE=IBM
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (IBM)
 
 pci:v0000127Ad00001005sv00001437sd00001105*
- ID_MODEL_FROM_DATABASE=IBM 5614PS3G V.90 Modem
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (IBM 5614PS3G V.90 Modem)
 
 pci:v0000127Ad00001022*
  ID_MODEL_FROM_DATABASE=HCF 56k Modem
 
 pci:v0000127Ad00001022sv00001436sd00001303*
- ID_MODEL_FROM_DATABASE=M3-5614PM3G V.90 Modem
+ ID_MODEL_FROM_DATABASE=HCF 56k Modem (M3-5614PM3G V.90 Modem)
 
 pci:v0000127Ad00001023*
  ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem
 
 pci:v0000127Ad00001023sv0000122Dsd00004020*
- ID_MODEL_FROM_DATABASE=Packard Bell MDP3858-WE
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (Packard Bell MDP3858-WE)
 
 pci:v0000127Ad00001023sv0000122Dsd00004023*
- ID_MODEL_FROM_DATABASE=MDP3858-UE
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (MDP3858-UE)
 
 pci:v0000127Ad00001023sv000013E0sd00000247*
- ID_MODEL_FROM_DATABASE=IBM F-1156IV+/R6 Spain V.90 Modem
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (IBM F-1156IV+/R6 Spain V.90 Modem)
 
 pci:v0000127Ad00001023sv000013E0sd00000297*
- ID_MODEL_FROM_DATABASE=IBM
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (IBM)
 
 pci:v0000127Ad00001023sv000013E0sd000002C7*
- ID_MODEL_FROM_DATABASE=IBM F-1156IV+/R6 WW V.90 Modem
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (IBM F-1156IV+/R6 WW V.90 Modem)
 
 pci:v0000127Ad00001023sv00001436sd00001203*
- ID_MODEL_FROM_DATABASE=IBM
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (IBM)
 
 pci:v0000127Ad00001023sv00001436sd00001303*
- ID_MODEL_FROM_DATABASE=IBM
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (IBM)
 
 pci:v0000127Ad00001024*
  ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice Modem
@@ -37293,19 +38337,19 @@ pci:v0000127Ad00001025*
  ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
 
 pci:v0000127Ad00001025sv000010CFsd0000106A*
- ID_MODEL_FROM_DATABASE=Fujitsu 235-DFSV
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (Fujitsu 235-DFSV)
 
 pci:v0000127Ad00001025sv0000122Dsd00004021*
- ID_MODEL_FROM_DATABASE=Packard Bell MDP3858V-WE
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (Packard Bell MDP3858V-WE)
 
 pci:v0000127Ad00001025sv0000122Dsd00004022*
- ID_MODEL_FROM_DATABASE=MDP3858SP-WE
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (MDP3858SP-WE)
 
 pci:v0000127Ad00001025sv0000122Dsd00004024*
- ID_MODEL_FROM_DATABASE=MDP3858V-UE
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (MDP3858V-UE)
 
 pci:v0000127Ad00001025sv0000122Dsd00004025*
- ID_MODEL_FROM_DATABASE=MDP3858SP-UE
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (MDP3858SP-UE)
 
 pci:v0000127Ad00001026*
  ID_MODEL_FROM_DATABASE=HCF 56k PCI Speakerphone Modem
@@ -37335,85 +38379,85 @@ pci:v0000127Ad00002005*
  ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem
 
 pci:v0000127Ad00002005sv0000104Dsd00008044*
- ID_MODEL_FROM_DATABASE=229-DFSV
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (229-DFSV)
 
 pci:v0000127Ad00002005sv0000104Dsd00008045*
- ID_MODEL_FROM_DATABASE=229-DFSV
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (229-DFSV)
 
 pci:v0000127Ad00002005sv0000104Dsd00008055*
- ID_MODEL_FROM_DATABASE=PBE/Aztech 235W-DFSV
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (PBE/Aztech 235W-DFSV)
 
 pci:v0000127Ad00002005sv0000104Dsd00008056*
- ID_MODEL_FROM_DATABASE=235-DFSV
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (235-DFSV)
 
 pci:v0000127Ad00002005sv0000104Dsd0000805A*
- ID_MODEL_FROM_DATABASE=Modem
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (Modem)
 
 pci:v0000127Ad00002005sv0000104Dsd0000805F*
- ID_MODEL_FROM_DATABASE=Modem
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (Modem)
 
 pci:v0000127Ad00002005sv0000104Dsd00008074*
- ID_MODEL_FROM_DATABASE=Modem
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (Modem)
 
 pci:v0000127Ad00002013*
  ID_MODEL_FROM_DATABASE=HSF 56k Data/Fax Modem
 
 pci:v0000127Ad00002013sv00001179sd00000001*
- ID_MODEL_FROM_DATABASE=Modem
+ ID_MODEL_FROM_DATABASE=HSF 56k Data/Fax Modem (Modem)
 
 pci:v0000127Ad00002013sv00001179sd0000FF00*
- ID_MODEL_FROM_DATABASE=Modem
+ ID_MODEL_FROM_DATABASE=HSF 56k Data/Fax Modem (Modem)
 
 pci:v0000127Ad00002014*
  ID_MODEL_FROM_DATABASE=HSF 56k Data/Fax/Voice Modem
 
 pci:v0000127Ad00002014sv000010CFsd00001057*
- ID_MODEL_FROM_DATABASE=Fujitsu Citicorp III
+ ID_MODEL_FROM_DATABASE=HSF 56k Data/Fax/Voice Modem (Fujitsu Citicorp III)
 
 pci:v0000127Ad00002014sv0000122Dsd00004050*
- ID_MODEL_FROM_DATABASE=MSP3880-U
+ ID_MODEL_FROM_DATABASE=HSF 56k Data/Fax/Voice Modem (MSP3880-U)
 
 pci:v0000127Ad00002014sv0000122Dsd00004055*
- ID_MODEL_FROM_DATABASE=MSP3880-W
+ ID_MODEL_FROM_DATABASE=HSF 56k Data/Fax/Voice Modem (MSP3880-W)
 
 pci:v0000127Ad00002015*
  ID_MODEL_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
 
 pci:v0000127Ad00002015sv000010CFsd00001063*
- ID_MODEL_FROM_DATABASE=Fujitsu
+ ID_MODEL_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (Fujitsu)
 
 pci:v0000127Ad00002015sv000010CFsd00001064*
- ID_MODEL_FROM_DATABASE=Fujitsu
+ ID_MODEL_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (Fujitsu)
 
 pci:v0000127Ad00002015sv00001468sd00002015*
- ID_MODEL_FROM_DATABASE=Fujitsu
+ ID_MODEL_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (Fujitsu)
 
 pci:v0000127Ad00002016*
  ID_MODEL_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp Modem
 
 pci:v0000127Ad00002016sv0000122Dsd00004051*
- ID_MODEL_FROM_DATABASE=MSP3880V-W
+ ID_MODEL_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp Modem (MSP3880V-W)
 
 pci:v0000127Ad00002016sv0000122Dsd00004052*
- ID_MODEL_FROM_DATABASE=MSP3880SP-W
+ ID_MODEL_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp Modem (MSP3880SP-W)
 
 pci:v0000127Ad00002016sv0000122Dsd00004054*
- ID_MODEL_FROM_DATABASE=MSP3880V-U
+ ID_MODEL_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp Modem (MSP3880V-U)
 
 pci:v0000127Ad00002016sv0000122Dsd00004056*
- ID_MODEL_FROM_DATABASE=MSP3880SP-U
+ ID_MODEL_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp Modem (MSP3880SP-U)
 
 pci:v0000127Ad00002016sv0000122Dsd00004057*
- ID_MODEL_FROM_DATABASE=MSP3880SP-A
+ ID_MODEL_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp Modem (MSP3880SP-A)
 
 pci:v0000127Ad00004311*
  ID_MODEL_FROM_DATABASE=Riptide HSF 56k PCI Modem
 
 pci:v0000127Ad00004311sv0000127Asd00004311*
- ID_MODEL_FROM_DATABASE=Ring Modular? Riptide HSF RT HP Dom
+ ID_MODEL_FROM_DATABASE=Riptide HSF 56k PCI Modem (Ring Modular? Riptide HSF RT HP Dom)
 
 pci:v0000127Ad00004311sv000013E0sd00000210*
- ID_MODEL_FROM_DATABASE=HP-GVC
+ ID_MODEL_FROM_DATABASE=Riptide HSF 56k PCI Modem (HP-GVC)
 
 pci:v0000127Ad00004320*
  ID_MODEL_FROM_DATABASE=Riptide PCI Audio Controller
@@ -37425,16 +38469,16 @@ pci:v0000127Ad00004321*
  ID_MODEL_FROM_DATABASE=Riptide HCF 56k PCI Modem
 
 pci:v0000127Ad00004321sv00001235sd00004321*
- ID_MODEL_FROM_DATABASE=Hewlett Packard DF
+ ID_MODEL_FROM_DATABASE=Riptide HCF 56k PCI Modem (Hewlett Packard DF)
 
 pci:v0000127Ad00004321sv00001235sd00004324*
- ID_MODEL_FROM_DATABASE=Hewlett Packard DF
+ ID_MODEL_FROM_DATABASE=Riptide HCF 56k PCI Modem (Hewlett Packard DF)
 
 pci:v0000127Ad00004321sv000013E0sd00000210*
- ID_MODEL_FROM_DATABASE=Hewlett Packard DF
+ ID_MODEL_FROM_DATABASE=Riptide HCF 56k PCI Modem (Hewlett Packard DF)
 
 pci:v0000127Ad00004321sv0000144Dsd00002321*
- ID_MODEL_FROM_DATABASE=Riptide
+ ID_MODEL_FROM_DATABASE=Riptide HCF 56k PCI Modem (Riptide)
 
 pci:v0000127Ad00004322*
  ID_MODEL_FROM_DATABASE=Riptide PCI Game Controller
@@ -37491,7 +38535,7 @@ pci:v00001282d00009102*
  ID_MODEL_FROM_DATABASE=21x4x DEC-Tulip compatible 10/100 Ethernet
 
 pci:v00001282d00009102sv00000291sd00008212*
- ID_MODEL_FROM_DATABASE=DM9102A (DM9102AE, SM9102AF) Ethernet 100/10 MBit
+ ID_MODEL_FROM_DATABASE=21x4x DEC-Tulip compatible 10/100 Ethernet (DM9102A (DM9102AE, SM9102AF) Ethernet 100/10 MBit)
 
 pci:v00001282d00009132*
  ID_MODEL_FROM_DATABASE=Ethernet 100/10 MBit
@@ -37509,19 +38553,19 @@ pci:v00001283d00008211*
  ID_MODEL_FROM_DATABASE=ITE 8211F Single Channel UDMA 133
 
 pci:v00001283d00008211sv00001043sd00008138*
- ID_MODEL_FROM_DATABASE=P5GD1-VW Mainboard
+ ID_MODEL_FROM_DATABASE=ITE 8211F Single Channel UDMA 133 (P5GD1-VW Mainboard)
 
 pci:v00001283d00008212*
  ID_MODEL_FROM_DATABASE=IT8212 Dual channel ATA RAID controller
 
 pci:v00001283d00008212sv00001283sd00000001*
- ID_MODEL_FROM_DATABASE=IT/ITE8212 Dual channel ATA RAID controller
+ ID_MODEL_FROM_DATABASE=IT8212 Dual channel ATA RAID controller (IT/ITE8212 Dual channel ATA RAID controller)
 
 pci:v00001283d00008213*
  ID_MODEL_FROM_DATABASE=IT8213 IDE Controller
 
 pci:v00001283d00008213sv00001458sd0000B000*
- ID_MODEL_FROM_DATABASE=GA-EG45M-DS2H Mainboard
+ ID_MODEL_FROM_DATABASE=IT8213 IDE Controller (GA-EG45M-DS2H Mainboard)
 
 pci:v00001283d00008330*
  ID_MODEL_FROM_DATABASE=IT8330G
@@ -37752,19 +38796,19 @@ pci:v000012AEd00000001*
  ID_MODEL_FROM_DATABASE=AceNIC Gigabit Ethernet
 
 pci:v000012AEd00000001sv00001014sd00000104*
- ID_MODEL_FROM_DATABASE=Gigabit Ethernet-SX PCI Adapter
+ ID_MODEL_FROM_DATABASE=AceNIC Gigabit Ethernet (Gigabit Ethernet-SX PCI Adapter)
 
 pci:v000012AEd00000001sv000012AEsd00000001*
- ID_MODEL_FROM_DATABASE=Gigabit Ethernet-SX (Universal)
+ ID_MODEL_FROM_DATABASE=AceNIC Gigabit Ethernet (Gigabit Ethernet-SX (Universal))
 
 pci:v000012AEd00000002*
  ID_MODEL_FROM_DATABASE=AceNIC Gigabit Ethernet (Copper)
 
 pci:v000012AEd00000002sv000010A9sd00008002*
- ID_MODEL_FROM_DATABASE=Acenic Gigabit Ethernet
+ ID_MODEL_FROM_DATABASE=AceNIC Gigabit Ethernet (Copper) (Acenic Gigabit Ethernet)
 
 pci:v000012AEd00000002sv000012AEsd00000002*
- ID_MODEL_FROM_DATABASE=Gigabit Ethernet-T (3C986-T)
+ ID_MODEL_FROM_DATABASE=AceNIC Gigabit Ethernet (Copper) (Gigabit Ethernet-T (3C986-T))
 
 pci:v000012AEd000000FA*
  ID_MODEL_FROM_DATABASE=Farallon PN9100-T Gigabit Ethernet
@@ -37806,64 +38850,64 @@ pci:v000012B9d00001006*
  ID_MODEL_FROM_DATABASE=WinModem
 
 pci:v000012B9d00001006sv000012B9sd0000005C*
- ID_MODEL_FROM_DATABASE=USR 56k Internal Voice WinModem (Model 3472)
+ ID_MODEL_FROM_DATABASE=WinModem (USR 56k Internal Voice WinModem (Model 3472))
 
 pci:v000012B9d00001006sv000012B9sd0000005E*
- ID_MODEL_FROM_DATABASE=USR 56k Internal WinModem (Models 662975)
+ ID_MODEL_FROM_DATABASE=WinModem (USR 56k Internal WinModem (Models 662975))
 
 pci:v000012B9d00001006sv000012B9sd00000062*
- ID_MODEL_FROM_DATABASE=USR 56k Internal Voice WinModem (Model 662978)
+ ID_MODEL_FROM_DATABASE=WinModem (USR 56k Internal Voice WinModem (Model 662978))
 
 pci:v000012B9d00001006sv000012B9sd00000068*
- ID_MODEL_FROM_DATABASE=USR 56k Internal Voice WinModem (Model 5690)
+ ID_MODEL_FROM_DATABASE=WinModem (USR 56k Internal Voice WinModem (Model 5690))
 
 pci:v000012B9d00001006sv000012B9sd0000007A*
- ID_MODEL_FROM_DATABASE=USR 56k Internal Voice WinModem (Model 662974)
+ ID_MODEL_FROM_DATABASE=WinModem (USR 56k Internal Voice WinModem (Model 662974))
 
 pci:v000012B9d00001006sv000012B9sd0000007F*
- ID_MODEL_FROM_DATABASE=USR 56k Internal WinModem (Models 5698, 5699)
+ ID_MODEL_FROM_DATABASE=WinModem (USR 56k Internal WinModem (Models 5698, 5699))
 
 pci:v000012B9d00001006sv000012B9sd00000080*
- ID_MODEL_FROM_DATABASE=USR 56k Internal WinModem (Models 2975, 3528)
+ ID_MODEL_FROM_DATABASE=WinModem (USR 56k Internal WinModem (Models 2975, 3528))
 
 pci:v000012B9d00001006sv000012B9sd00000081*
- ID_MODEL_FROM_DATABASE=USR 56k Internal Voice WinModem (Models 2974, 3529)
+ ID_MODEL_FROM_DATABASE=WinModem (USR 56k Internal Voice WinModem (Models 2974, 3529))
 
 pci:v000012B9d00001006sv000012B9sd00000091*
- ID_MODEL_FROM_DATABASE=USR 56k Internal Voice WinModem (Model 2978)
+ ID_MODEL_FROM_DATABASE=WinModem (USR 56k Internal Voice WinModem (Model 2978))
 
 pci:v000012B9d00001007*
  ID_MODEL_FROM_DATABASE=USR 56k Internal WinModem
 
 pci:v000012B9d00001007sv000012B9sd000000A3*
- ID_MODEL_FROM_DATABASE=USR 56k Internal WinModem (Model 3595)
+ ID_MODEL_FROM_DATABASE=USR 56k Internal WinModem ((Model 3595))
 
 pci:v000012B9d00001007sv000012B9sd000000C4*
- ID_MODEL_FROM_DATABASE=U.S. Robotics V.92 Voice Faxmodem (2884A/B/C)
+ ID_MODEL_FROM_DATABASE=USR 56k Internal WinModem (U.S. Robotics V.92 Voice Faxmodem (2884A/B/C))
 
 pci:v000012B9d00001008*
  ID_MODEL_FROM_DATABASE=56K FaxModem Model 5610
 
 pci:v000012B9d00001008sv000012B9sd000000A2*
- ID_MODEL_FROM_DATABASE=USR 56k Internal FAX Modem (Model 2977)
+ ID_MODEL_FROM_DATABASE=56K FaxModem Model 5610 (USR 56k Internal FAX Modem (Model 2977))
 
 pci:v000012B9d00001008sv000012B9sd000000AA*
- ID_MODEL_FROM_DATABASE=USR 56k Internal Voice Modem (Model 2976)
+ ID_MODEL_FROM_DATABASE=56K FaxModem Model 5610 (USR 56k Internal Voice Modem (Model 2976))
 
 pci:v000012B9d00001008sv000012B9sd000000AB*
- ID_MODEL_FROM_DATABASE=USR 56k Internal Voice Modem (Model 5609)
+ ID_MODEL_FROM_DATABASE=56K FaxModem Model 5610 (USR 56k Internal Voice Modem (Model 5609))
 
 pci:v000012B9d00001008sv000012B9sd000000AC*
- ID_MODEL_FROM_DATABASE=USR 56k Internal Voice Modem (Model 3298)
+ ID_MODEL_FROM_DATABASE=56K FaxModem Model 5610 (USR 56k Internal Voice Modem (Model 3298))
 
 pci:v000012B9d00001008sv000012B9sd000000AD*
- ID_MODEL_FROM_DATABASE=USR 56k Internal FAX Modem (Model 5610)
+ ID_MODEL_FROM_DATABASE=56K FaxModem Model 5610 (USR 56k Internal FAX Modem (Model 5610))
 
 pci:v000012B9d00001008sv000012B9sd000000D3*
- ID_MODEL_FROM_DATABASE=USR 56K Internal V92 FAX Modem (Model 5610)
+ ID_MODEL_FROM_DATABASE=56K FaxModem Model 5610 (USR 56K Internal V92 FAX Modem (Model 5610))
 
 pci:v000012B9d00001008sv000012B9sd0000BABA*
- ID_MODEL_FROM_DATABASE=USR 56K Internal Voice Modem 3CP3298-DEL (Model 5601) [Hawk]
+ ID_MODEL_FROM_DATABASE=56K FaxModem Model 5610 (USR 56K Internal Voice Modem 3CP3298-DEL (Model 5601) [Hawk])
 
 pci:v000012BA*
  ID_VENDOR_FROM_DATABASE=BittWare, Inc.
@@ -37887,7 +38931,7 @@ pci:v000012BEd00003042*
  ID_MODEL_FROM_DATABASE=AN3042Q CO-MEM Lite
 
 pci:v000012BEd00003042sv000012BEsd00003042*
- ID_MODEL_FROM_DATABASE=Anchor Chips Lite Evaluation Board
+ ID_MODEL_FROM_DATABASE=AN3042Q CO-MEM Lite (Anchor Chips Lite Evaluation Board)
 
 pci:v000012BF*
  ID_VENDOR_FROM_DATABASE=Fujifilm Microdevices
@@ -38082,58 +39126,58 @@ pci:v000012D2d00000018*
  ID_MODEL_FROM_DATABASE=Riva128
 
 pci:v000012D2d00000018sv00001048sd00000C10*
- ID_MODEL_FROM_DATABASE=VICTORY Erazor
+ ID_MODEL_FROM_DATABASE=Riva128 (VICTORY Erazor)
 
 pci:v000012D2d00000018sv0000107Bsd00008030*
- ID_MODEL_FROM_DATABASE=STB Velocity 128
+ ID_MODEL_FROM_DATABASE=Riva128 (STB Velocity 128)
 
 pci:v000012D2d00000018sv00001092sd00000350*
- ID_MODEL_FROM_DATABASE=Viper V330
+ ID_MODEL_FROM_DATABASE=Riva128 (Viper V330)
 
 pci:v000012D2d00000018sv00001092sd00001092*
- ID_MODEL_FROM_DATABASE=Viper V330
+ ID_MODEL_FROM_DATABASE=Riva128 (Viper V330)
 
 pci:v000012D2d00000018sv000010B4sd00001B1B*
- ID_MODEL_FROM_DATABASE=STB Velocity 128
+ ID_MODEL_FROM_DATABASE=Riva128 (STB Velocity 128)
 
 pci:v000012D2d00000018sv000010B4sd00001B1D*
- ID_MODEL_FROM_DATABASE=STB Velocity 128
+ ID_MODEL_FROM_DATABASE=Riva128 (STB Velocity 128)
 
 pci:v000012D2d00000018sv000010B4sd00001B1E*
- ID_MODEL_FROM_DATABASE=STB Velocity 128, PAL TV-Out
+ ID_MODEL_FROM_DATABASE=Riva128 (STB Velocity 128, PAL TV-Out)
 
 pci:v000012D2d00000018sv000010B4sd00001B20*
- ID_MODEL_FROM_DATABASE=STB Velocity 128 Sapphire
+ ID_MODEL_FROM_DATABASE=Riva128 (STB Velocity 128 Sapphire)
 
 pci:v000012D2d00000018sv000010B4sd00001B21*
- ID_MODEL_FROM_DATABASE=STB Velocity 128
+ ID_MODEL_FROM_DATABASE=Riva128 (STB Velocity 128)
 
 pci:v000012D2d00000018sv000010B4sd00001B22*
- ID_MODEL_FROM_DATABASE=STB Velocity 128 AGP, NTSC TV-Out
+ ID_MODEL_FROM_DATABASE=Riva128 (STB Velocity 128 AGP, NTSC TV-Out)
 
 pci:v000012D2d00000018sv000010B4sd00001B23*
- ID_MODEL_FROM_DATABASE=STB Velocity 128 AGP, PAL TV-Out
+ ID_MODEL_FROM_DATABASE=Riva128 (STB Velocity 128 AGP, PAL TV-Out)
 
 pci:v000012D2d00000018sv000010B4sd00001B27*
- ID_MODEL_FROM_DATABASE=STB Velocity 128 DVD
+ ID_MODEL_FROM_DATABASE=Riva128 (STB Velocity 128 DVD)
 
 pci:v000012D2d00000018sv000010B4sd00001B88*
- ID_MODEL_FROM_DATABASE=MVP Pro 128
+ ID_MODEL_FROM_DATABASE=Riva128 (MVP Pro 128)
 
 pci:v000012D2d00000018sv000010B4sd0000222A*
- ID_MODEL_FROM_DATABASE=STB Velocity 128 AGP
+ ID_MODEL_FROM_DATABASE=Riva128 (STB Velocity 128 AGP)
 
 pci:v000012D2d00000018sv000010B4sd00002230*
- ID_MODEL_FROM_DATABASE=STB Velocity 128
+ ID_MODEL_FROM_DATABASE=Riva128 (STB Velocity 128)
 
 pci:v000012D2d00000018sv000010B4sd00002232*
- ID_MODEL_FROM_DATABASE=STB Velocity 128
+ ID_MODEL_FROM_DATABASE=Riva128 (STB Velocity 128)
 
 pci:v000012D2d00000018sv000010B4sd00002235*
- ID_MODEL_FROM_DATABASE=STB Velocity 128 AGP
+ ID_MODEL_FROM_DATABASE=Riva128 (STB Velocity 128 AGP)
 
 pci:v000012D2d00000018sv00002A15sd000054A3*
- ID_MODEL_FROM_DATABASE=3DVision-SAGP / 3DexPlorer 3000
+ ID_MODEL_FROM_DATABASE=Riva128 (3DVision-SAGP / 3DexPlorer 3000)
 
 pci:v000012D2d00000019*
  ID_MODEL_FROM_DATABASE=Riva128ZX
@@ -38217,7 +39261,7 @@ pci:v000012D8d0000E110*
  ID_MODEL_FROM_DATABASE=PI7C9X110 PCI Express to PCI bridge
 
 pci:v000012D8d0000E110sv00001775sd000011CC*
- ID_MODEL_FROM_DATABASE=CC11/CL11 CompactPCI Bridge
+ ID_MODEL_FROM_DATABASE=PI7C9X110 PCI Express to PCI bridge (CC11/CL11 CompactPCI Bridge)
 
 pci:v000012D8d0000E111*
  ID_MODEL_FROM_DATABASE=PI7C9X111SL PCIe-to-PCI Reversible Bridge
@@ -38241,10 +39285,10 @@ pci:v000012D9d00001078*
  ID_MODEL_FROM_DATABASE=Prosody X class e1000 device
 
 pci:v000012D9d00001078sv000012D9sd0000000D*
- ID_MODEL_FROM_DATABASE=Prosody X PCI
+ ID_MODEL_FROM_DATABASE=Prosody X class e1000 device (Prosody X PCI)
 
 pci:v000012D9d00001078sv000012D9sd0000000E*
- ID_MODEL_FROM_DATABASE=Prosody X cPCI
+ ID_MODEL_FROM_DATABASE=Prosody X class e1000 device (Prosody X cPCI)
 
 pci:v000012DA*
  ID_VENDOR_FROM_DATABASE=True Time Inc.
@@ -38316,67 +39360,67 @@ pci:v000012EBd00000001*
  ID_MODEL_FROM_DATABASE=Vortex 1
 
 pci:v000012EBd00000001sv0000104Dsd00008036*
- ID_MODEL_FROM_DATABASE=AU8820 Vortex Digital Audio Processor
+ ID_MODEL_FROM_DATABASE=Vortex 1 (AU8820 Vortex Digital Audio Processor)
 
 pci:v000012EBd00000001sv00001092sd00002000*
- ID_MODEL_FROM_DATABASE=Sonic Impact A3D
+ ID_MODEL_FROM_DATABASE=Vortex 1 (Sonic Impact A3D)
 
 pci:v000012EBd00000001sv00001092sd00002100*
- ID_MODEL_FROM_DATABASE=Sonic Impact A3D
+ ID_MODEL_FROM_DATABASE=Vortex 1 (Sonic Impact A3D)
 
 pci:v000012EBd00000001sv00001092sd00002110*
- ID_MODEL_FROM_DATABASE=Sonic Impact A3D
+ ID_MODEL_FROM_DATABASE=Vortex 1 (Sonic Impact A3D)
 
 pci:v000012EBd00000001sv00001092sd00002200*
- ID_MODEL_FROM_DATABASE=Sonic Impact A3D
+ ID_MODEL_FROM_DATABASE=Vortex 1 (Sonic Impact A3D)
 
 pci:v000012EBd00000001sv0000122Dsd00001002*
- ID_MODEL_FROM_DATABASE=AU8820 Vortex Digital Audio Processor
+ ID_MODEL_FROM_DATABASE=Vortex 1 (AU8820 Vortex Digital Audio Processor)
 
 pci:v000012EBd00000001sv000012EBsd00000001*
- ID_MODEL_FROM_DATABASE=AU8820 Vortex Digital Audio Processor
+ ID_MODEL_FROM_DATABASE=Vortex 1 (AU8820 Vortex Digital Audio Processor)
 
 pci:v000012EBd00000001sv00005053sd00003355*
- ID_MODEL_FROM_DATABASE=Montego
+ ID_MODEL_FROM_DATABASE=Vortex 1 (Montego)
 
 pci:v000012EBd00000001sv000050B2sd00001111*
- ID_MODEL_FROM_DATABASE=XLerate
+ ID_MODEL_FROM_DATABASE=Vortex 1 (XLerate)
 
 pci:v000012EBd00000002*
  ID_MODEL_FROM_DATABASE=Vortex 2
 
 pci:v000012EBd00000002sv0000104Dsd00008049*
- ID_MODEL_FROM_DATABASE=AU8830 Vortex 3D Digital Audio Processor
+ ID_MODEL_FROM_DATABASE=Vortex 2 (AU8830 Vortex 3D Digital Audio Processor)
 
 pci:v000012EBd00000002sv0000104Dsd0000807B*
- ID_MODEL_FROM_DATABASE=AU8830 Vortex 3D Digital Audio Processor
+ ID_MODEL_FROM_DATABASE=Vortex 2 (AU8830 Vortex 3D Digital Audio Processor)
 
 pci:v000012EBd00000002sv00001092sd00003000*
- ID_MODEL_FROM_DATABASE=Monster Sound II
+ ID_MODEL_FROM_DATABASE=Vortex 2 (Monster Sound II)
 
 pci:v000012EBd00000002sv00001092sd00003001*
- ID_MODEL_FROM_DATABASE=Monster Sound II
+ ID_MODEL_FROM_DATABASE=Vortex 2 (Monster Sound II)
 
 pci:v000012EBd00000002sv00001092sd00003002*
- ID_MODEL_FROM_DATABASE=Monster Sound II
+ ID_MODEL_FROM_DATABASE=Vortex 2 (Monster Sound II)
 
 pci:v000012EBd00000002sv00001092sd00003003*
- ID_MODEL_FROM_DATABASE=Monster Sound II
+ ID_MODEL_FROM_DATABASE=Vortex 2 (Monster Sound II)
 
 pci:v000012EBd00000002sv00001092sd00003004*
- ID_MODEL_FROM_DATABASE=Monster Sound II
+ ID_MODEL_FROM_DATABASE=Vortex 2 (Monster Sound II)
 
 pci:v000012EBd00000002sv000012EBsd00000002*
- ID_MODEL_FROM_DATABASE=AU8830 Vortex 3D Digital Audio Processor
+ ID_MODEL_FROM_DATABASE=Vortex 2 (AU8830 Vortex 3D Digital Audio Processor)
 
 pci:v000012EBd00000002sv000012EBsd00000088*
- ID_MODEL_FROM_DATABASE=AU8830 Vortex 3D Digital Audio Processor
+ ID_MODEL_FROM_DATABASE=Vortex 2 (AU8830 Vortex 3D Digital Audio Processor)
 
 pci:v000012EBd00000002sv0000144Dsd00003510*
- ID_MODEL_FROM_DATABASE=AU8830 Vortex 3D Digital Audio Processor
+ ID_MODEL_FROM_DATABASE=Vortex 2 (AU8830 Vortex 3D Digital Audio Processor)
 
 pci:v000012EBd00000002sv00005053sd00003356*
- ID_MODEL_FROM_DATABASE=Montego II
+ ID_MODEL_FROM_DATABASE=Vortex 2 (Montego II)
 
 pci:v000012EBd00000003*
  ID_MODEL_FROM_DATABASE=AU8810 Vortex Digital Audio Processor
@@ -38766,16 +39810,16 @@ pci:v00001317d00000985*
  ID_MODEL_FROM_DATABASE=NC100 Network Everywhere Fast Ethernet 10/100
 
 pci:v00001317d00000985sv00001734sd0000100C*
- ID_MODEL_FROM_DATABASE=Scenic N300 ADMtek AN983 10/100 Mbps PCI Adapter
+ ID_MODEL_FROM_DATABASE=NC100 Network Everywhere Fast Ethernet 10/100 (Scenic N300 ADMtek AN983 10/100 Mbps PCI Adapter)
 
 pci:v00001317d00001985*
  ID_MODEL_FROM_DATABASE=21x4x DEC-Tulip compatible 10/100 Ethernet
 
 pci:v00001317d00001985sv00001385sd0000511A*
- ID_MODEL_FROM_DATABASE=FA511
+ ID_MODEL_FROM_DATABASE=21x4x DEC-Tulip compatible 10/100 Ethernet (FA511)
 
 pci:v00001317d00001985sv00001395sd00002103*
- ID_MODEL_FROM_DATABASE=CB100-EZ (4-LED version)
+ ID_MODEL_FROM_DATABASE=21x4x DEC-Tulip compatible 10/100 Ethernet (CB100-EZ (4-LED version))
 
 pci:v00001317d00002850*
  ID_MODEL_FROM_DATABASE=HSP MicroModem 56
@@ -38787,10 +39831,10 @@ pci:v00001317d00008201*
  ID_MODEL_FROM_DATABASE=ADM8211 802.11b Wireless Interface
 
 pci:v00001317d00008201sv000010B8sd00002635*
- ID_MODEL_FROM_DATABASE=SMC2635W v1 802.11b Wireless Cardbus Adapter
+ ID_MODEL_FROM_DATABASE=ADM8211 802.11b Wireless Interface (SMC2635W v1 802.11b Wireless Cardbus Adapter)
 
 pci:v00001317d00008201sv00001317sd00008201*
- ID_MODEL_FROM_DATABASE=SMC2635W v2 802.11b Wireless Cardbus Adapter
+ ID_MODEL_FROM_DATABASE=ADM8211 802.11b Wireless Interface (SMC2635W v2 802.11b Wireless Cardbus Adapter)
 
 pci:v00001317d00008211*
  ID_MODEL_FROM_DATABASE=ADM8211 802.11b Wireless Interface
@@ -38811,13 +39855,13 @@ pci:v00001319d00000801*
  ID_MODEL_FROM_DATABASE=Xwave QS3000A [FM801]
 
 pci:v00001319d00000801sv00001319sd00001319*
- ID_MODEL_FROM_DATABASE=FM801 PCI Audio
+ ID_MODEL_FROM_DATABASE=Xwave QS3000A [FM801] (FM801 PCI Audio)
 
 pci:v00001319d00000802*
  ID_MODEL_FROM_DATABASE=Xwave QS3000A [FM801 game port]
 
 pci:v00001319d00000802sv00001319sd00001319*
- ID_MODEL_FROM_DATABASE=FM801 PCI Joystick
+ ID_MODEL_FROM_DATABASE=Xwave QS3000A [FM801 game port] (FM801 PCI Joystick)
 
 pci:v00001319d00001000*
  ID_MODEL_FROM_DATABASE=FM801 PCI Audio
@@ -38919,7 +39963,7 @@ pci:v0000131Fd00002030*
  ID_MODEL_FROM_DATABASE=CyberSerial (2-port) 16550
 
 pci:v0000131Fd00002030sv0000131Fsd00002030*
- ID_MODEL_FROM_DATABASE=PCI Serial Card
+ ID_MODEL_FROM_DATABASE=CyberSerial (2-port) 16550 (PCI Serial Card)
 
 pci:v0000131Fd00002031*
  ID_MODEL_FROM_DATABASE=CyberSerial (2-port) 16650
@@ -39135,7 +40179,7 @@ pci:v0000134Dd00007890*
  ID_MODEL_FROM_DATABASE=HSP MicroModem 56
 
 pci:v0000134Dd00007890sv0000134Dsd00000001*
- ID_MODEL_FROM_DATABASE=PCT789 adapter
+ ID_MODEL_FROM_DATABASE=HSP MicroModem 56 (PCT789 adapter)
 
 pci:v0000134Dd00007891*
  ID_MODEL_FROM_DATABASE=HSP MicroModem 56
@@ -39329,6 +40373,12 @@ pci:v00001360d00000205*
 pci:v00001360d00000206*
  ID_MODEL_FROM_DATABASE=GPS180PEX GPS Receiver (PCI Express)
 
+pci:v00001360d00000207*
+ ID_MODEL_FROM_DATABASE=GLN180PEX GPS/GLONASS receiver (PCI Express)
+
+pci:v00001360d00000208*
+ ID_MODEL_FROM_DATABASE=GPS180AMC GPS Receiver (PCI Express / MicroTCA / AdvancedMC)
+
 pci:v00001360d00000301*
  ID_MODEL_FROM_DATABASE=TCR510PCI IRIG Timecode Reader
 
@@ -39420,7 +40470,7 @@ pci:v00001371d0000434E*
  ID_MODEL_FROM_DATABASE=GigaCard Network Adapter
 
 pci:v00001371d0000434Esv00001371sd0000434E*
- ID_MODEL_FROM_DATABASE=N-Way PCI-Bus Giga-Card 1000/100/10Mbps(L)
+ ID_MODEL_FROM_DATABASE=GigaCard Network Adapter (N-Way PCI-Bus Giga-Card 1000/100/10Mbps(L))
 
 pci:v00001373*
  ID_VENDOR_FROM_DATABASE=Silicon Vision Inc
@@ -39816,10 +40866,10 @@ pci:v00001394d00000001*
  ID_MODEL_FROM_DATABASE=LXT1001 Gigabit Ethernet
 
 pci:v00001394d00000001sv00001186sd00004800*
- ID_MODEL_FROM_DATABASE=DGE-500SX
+ ID_MODEL_FROM_DATABASE=LXT1001 Gigabit Ethernet (DGE-500SX)
 
 pci:v00001394d00000001sv00001394sd00000001*
- ID_MODEL_FROM_DATABASE=NetCelerator Adapter
+ ID_MODEL_FROM_DATABASE=LXT1001 Gigabit Ethernet (NetCelerator Adapter)
 
 pci:v00001395*
  ID_VENDOR_FROM_DATABASE=Ambicom Inc
@@ -39834,40 +40884,40 @@ pci:v00001397d000008B4*
  ID_MODEL_FROM_DATABASE=ISDN network Controller [HFC-4S]
 
 pci:v00001397d000008B4sv00001397sd0000B520*
- ID_MODEL_FROM_DATABASE=HFC-4S [IOB4ST]
+ ID_MODEL_FROM_DATABASE=ISDN network Controller [HFC-4S] (HFC-4S [IOB4ST])
 
 pci:v00001397d000008B4sv00001397sd0000B540*
- ID_MODEL_FROM_DATABASE=HFC-4S [Swyx 4xS0 SX2 QuadBri]
+ ID_MODEL_FROM_DATABASE=ISDN network Controller [HFC-4S] (HFC-4S [Swyx 4xS0 SX2 QuadBri])
 
 pci:v00001397d000008B4sv00001397sd0000B550*
- ID_MODEL_FROM_DATABASE=HFC-4S [Junghanns quadBRI]
+ ID_MODEL_FROM_DATABASE=ISDN network Controller [HFC-4S] (HFC-4S [Junghanns quadBRI])
 
 pci:v00001397d000008B4sv00001397sd0000B556*
- ID_MODEL_FROM_DATABASE=HFC-4S [Junghanns DuoDBRI]
+ ID_MODEL_FROM_DATABASE=ISDN network Controller [HFC-4S] (HFC-4S [Junghanns DuoDBRI])
 
 pci:v00001397d000008B4sv00001397sd0000E888*
- ID_MODEL_FROM_DATABASE=HFC-4S [OpenVox B200P / B400P]
+ ID_MODEL_FROM_DATABASE=ISDN network Controller [HFC-4S] (HFC-4S [OpenVox B200P / B400P])
 
 pci:v00001397d000016B8*
  ID_MODEL_FROM_DATABASE=ISDN network Controller [HFC-8S]
 
 pci:v00001397d000016B8sv00001397sd0000B562*
- ID_MODEL_FROM_DATABASE=HFC-8S [IOB8ST]
+ ID_MODEL_FROM_DATABASE=ISDN network Controller [HFC-8S] (HFC-8S [IOB8ST])
 
 pci:v00001397d00002BD0*
  ID_MODEL_FROM_DATABASE=ISDN network controller [HFC-PCI]
 
 pci:v00001397d00002BD0sv00000675sd00001704*
- ID_MODEL_FROM_DATABASE=ISDN Adapter (PCI Bus, D, C)
+ ID_MODEL_FROM_DATABASE=ISDN network controller [HFC-PCI] (ISDN Adapter (PCI Bus, D, C))
 
 pci:v00001397d00002BD0sv00000675sd00001708*
- ID_MODEL_FROM_DATABASE=ISDN Adapter (PCI Bus, D, C, ACPI)
+ ID_MODEL_FROM_DATABASE=ISDN network controller [HFC-PCI] (ISDN Adapter (PCI Bus, D, C, ACPI))
 
 pci:v00001397d00002BD0sv00001397sd00002BD0*
- ID_MODEL_FROM_DATABASE=ISDN Board
+ ID_MODEL_FROM_DATABASE=ISDN network controller [HFC-PCI] (ISDN Board)
 
 pci:v00001397d00002BD0sv0000E4BFsd00001000*
- ID_MODEL_FROM_DATABASE=CI1-1-Harp
+ ID_MODEL_FROM_DATABASE=ISDN network controller [HFC-PCI] (CI1-1-Harp)
 
 pci:v00001397d000030B1*
  ID_MODEL_FROM_DATABASE=ISDN network Controller [HFC-E1]
@@ -39966,46 +41016,46 @@ pci:v000013A3d0000002F*
  ID_MODEL_FROM_DATABASE=9725 Compression and Security Processor
 
 pci:v000013A3d0000002Fsv000013A3sd00001600*
- ID_MODEL_FROM_DATABASE=DR1600 Acceleration Card
+ ID_MODEL_FROM_DATABASE=9725 Compression and Security Processor (DR1600 Acceleration Card)
 
 pci:v000013A3d0000002Fsv000013A3sd00001605*
- ID_MODEL_FROM_DATABASE=DR1605 Acceleration Card
+ ID_MODEL_FROM_DATABASE=9725 Compression and Security Processor (DR1605 Acceleration Card)
 
 pci:v000013A3d0000002Fsv000013A3sd00001610*
- ID_MODEL_FROM_DATABASE=DR1610 Acceleration Card
+ ID_MODEL_FROM_DATABASE=9725 Compression and Security Processor (DR1610 Acceleration Card)
 
 pci:v000013A3d0000002Fsv000013A3sd00001615*
- ID_MODEL_FROM_DATABASE=DR1615 Acceleration Card
+ ID_MODEL_FROM_DATABASE=9725 Compression and Security Processor (DR1615 Acceleration Card)
 
 pci:v000013A3d0000002Fsv000013A3sd00001620*
- ID_MODEL_FROM_DATABASE=DR1620 Acceleration Card
+ ID_MODEL_FROM_DATABASE=9725 Compression and Security Processor (DR1620 Acceleration Card)
 
 pci:v000013A3d0000002Fsv000013A3sd00001625*
- ID_MODEL_FROM_DATABASE=DR1625 Acceleration Card
+ ID_MODEL_FROM_DATABASE=9725 Compression and Security Processor (DR1625 Acceleration Card)
 
 pci:v000013A3d00000033*
  ID_MODEL_FROM_DATABASE=8201 Acceleration Processor
 
 pci:v000013A3d00000033sv000013A3sd00000036*
- ID_MODEL_FROM_DATABASE=DX1710 Acceleration Card
+ ID_MODEL_FROM_DATABASE=8201 Acceleration Processor (DX1710 Acceleration Card)
 
 pci:v000013A3d00000034*
  ID_MODEL_FROM_DATABASE=8202 Acceleration Processor
 
 pci:v000013A3d00000034sv000013A3sd00000036*
- ID_MODEL_FROM_DATABASE=DX1720 Acceleration Card
+ ID_MODEL_FROM_DATABASE=8202 Acceleration Processor (DX1720 Acceleration Card)
 
 pci:v000013A3d00000035*
  ID_MODEL_FROM_DATABASE=8203 Acceleration Processor
 
 pci:v000013A3d00000035sv000013A3sd00000036*
- ID_MODEL_FROM_DATABASE=DX1730 Acceleration Card
+ ID_MODEL_FROM_DATABASE=8203 Acceleration Processor (DX1730 Acceleration Card)
 
 pci:v000013A3d00000037*
  ID_MODEL_FROM_DATABASE=8204 Acceleration Processor
 
 pci:v000013A3d00000037sv000013A3sd00000036*
- ID_MODEL_FROM_DATABASE=DX1740 Acceleration Card
+ ID_MODEL_FROM_DATABASE=8204 Acceleration Processor (DX1740 Acceleration Card)
 
 pci:v000013A4*
  ID_VENDOR_FROM_DATABASE=Rascom Inc
@@ -40368,7 +41418,7 @@ pci:v000013F0d00000200*
  ID_MODEL_FROM_DATABASE=IC Plus IP100A Integrated 10/100 Ethernet MAC + PHY
 
 pci:v000013F0d00000200sv00001043sd00008213*
- ID_MODEL_FROM_DATABASE=NX1001
+ ID_MODEL_FROM_DATABASE=IC Plus IP100A Integrated 10/100 Ethernet MAC + PHY (NX1001)
 
 pci:v000013F0d00000201*
  ID_MODEL_FROM_DATABASE=ST201 Sundance Ethernet
@@ -40380,7 +41430,7 @@ pci:v000013F0d00001023*
  ID_MODEL_FROM_DATABASE=IP1000 Family Gigabit Ethernet
 
 pci:v000013F0d00001023sv00001043sd00008180*
- ID_MODEL_FROM_DATABASE=NX1101
+ ID_MODEL_FROM_DATABASE=IP1000 Family Gigabit Ethernet (NX1101)
 
 pci:v000013F1*
  ID_VENDOR_FROM_DATABASE=Oce' - Technologies B.V.
@@ -40410,76 +41460,76 @@ pci:v000013F6d00000100*
  ID_MODEL_FROM_DATABASE=CM8338A
 
 pci:v000013F6d00000100sv000013F6sd0000FFFF*
- ID_MODEL_FROM_DATABASE=CMI8338/C3DX PCI Audio Device
+ ID_MODEL_FROM_DATABASE=CM8338A (CMI8338/C3DX PCI Audio Device)
 
 pci:v000013F6d00000101*
  ID_MODEL_FROM_DATABASE=CM8338B
 
 pci:v000013F6d00000101sv000013F6sd00000101*
- ID_MODEL_FROM_DATABASE=CMI8338-031 PCI Audio Device
+ ID_MODEL_FROM_DATABASE=CM8338B (CMI8338-031 PCI Audio Device)
 
 pci:v000013F6d00000111*
  ID_MODEL_FROM_DATABASE=CMI8738/CMI8768 PCI Audio
 
 pci:v000013F6d00000111sv00001019sd00000970*
- ID_MODEL_FROM_DATABASE=P6STP-FL motherboard
+ ID_MODEL_FROM_DATABASE=CMI8738/CMI8768 PCI Audio (P6STP-FL motherboard)
 
 pci:v000013F6d00000111sv00001043sd00008035*
- ID_MODEL_FROM_DATABASE=CUSI-FX motherboard
+ ID_MODEL_FROM_DATABASE=CMI8738/CMI8768 PCI Audio (CUSI-FX motherboard)
 
 pci:v000013F6d00000111sv00001043sd00008077*
- ID_MODEL_FROM_DATABASE=CMI8738 6-channel audio controller
+ ID_MODEL_FROM_DATABASE=CMI8738/CMI8768 PCI Audio (CMI8738 6-channel audio controller)
 
 pci:v000013F6d00000111sv00001043sd000080E2*
- ID_MODEL_FROM_DATABASE=CMI8738 6ch-MX
+ ID_MODEL_FROM_DATABASE=CMI8738/CMI8768 PCI Audio (CMI8738 6ch-MX)
 
 pci:v000013F6d00000111sv000013F6sd00000111*
- ID_MODEL_FROM_DATABASE=CMI8738/C3DX PCI Audio Device
+ ID_MODEL_FROM_DATABASE=CMI8738/CMI8768 PCI Audio (CMI8738/C3DX PCI Audio Device)
 
 pci:v000013F6d00000111sv000013F6sd00009761*
- ID_MODEL_FROM_DATABASE=Theatron Agrippa
+ ID_MODEL_FROM_DATABASE=CMI8738/CMI8768 PCI Audio (Theatron Agrippa)
 
 pci:v000013F6d00000111sv0000153Bsd00001144*
- ID_MODEL_FROM_DATABASE=Aureon 5.1
+ ID_MODEL_FROM_DATABASE=CMI8738/CMI8768 PCI Audio (Aureon 5.1)
 
 pci:v000013F6d00000111sv0000153Bsd00001170*
- ID_MODEL_FROM_DATABASE=Aureon 7.1
+ ID_MODEL_FROM_DATABASE=CMI8738/CMI8768 PCI Audio (Aureon 7.1)
 
 pci:v000013F6d00000111sv00001681sd0000A000*
- ID_MODEL_FROM_DATABASE=Gamesurround MUSE XL
+ ID_MODEL_FROM_DATABASE=CMI8738/CMI8768 PCI Audio (Gamesurround MUSE XL)
 
 pci:v000013F6d00000111sv000017ABsd00000604*
- ID_MODEL_FROM_DATABASE=PSC604 Dynamic Edge
+ ID_MODEL_FROM_DATABASE=CMI8738/CMI8768 PCI Audio (PSC604 Dynamic Edge)
 
 pci:v000013F6d00000111sv000017ABsd00000605*
- ID_MODEL_FROM_DATABASE=PSC605 Sonic Edge
+ ID_MODEL_FROM_DATABASE=CMI8738/CMI8768 PCI Audio (PSC605 Sonic Edge)
 
 pci:v000013F6d00000111sv000017ABsd00007777*
- ID_MODEL_FROM_DATABASE=PSC605 Sonic Edge
+ ID_MODEL_FROM_DATABASE=CMI8738/CMI8768 PCI Audio (PSC605 Sonic Edge)
 
 pci:v000013F6d00000111sv0000270Fsd00001103*
- ID_MODEL_FROM_DATABASE=CT-7NJS Ultra motherboard
+ ID_MODEL_FROM_DATABASE=CMI8738/CMI8768 PCI Audio (CT-7NJS Ultra motherboard)
 
 pci:v000013F6d00000111sv0000270Fsd0000F462*
- ID_MODEL_FROM_DATABASE=7NJL1 motherboard
+ ID_MODEL_FROM_DATABASE=CMI8738/CMI8768 PCI Audio (7NJL1 motherboard)
 
 pci:v000013F6d00000111sv0000584Dsd00003731*
- ID_MODEL_FROM_DATABASE=Digital X-Mystique
+ ID_MODEL_FROM_DATABASE=CMI8738/CMI8768 PCI Audio (Digital X-Mystique)
 
 pci:v000013F6d00000111sv0000584Dsd00003741*
- ID_MODEL_FROM_DATABASE=X-Plosion 7.1
+ ID_MODEL_FROM_DATABASE=CMI8738/CMI8768 PCI Audio (X-Plosion 7.1)
 
 pci:v000013F6d00000111sv0000584Dsd00003751*
- ID_MODEL_FROM_DATABASE=X-Raider 7.1
+ ID_MODEL_FROM_DATABASE=CMI8738/CMI8768 PCI Audio (X-Raider 7.1)
 
 pci:v000013F6d00000111sv0000584Dsd00003761*
- ID_MODEL_FROM_DATABASE=X-Mystique 7.1 LP
+ ID_MODEL_FROM_DATABASE=CMI8738/CMI8768 PCI Audio (X-Mystique 7.1 LP)
 
 pci:v000013F6d00000111sv0000584Dsd00003771*
- ID_MODEL_FROM_DATABASE=X-Mystique 7.1 LP Value
+ ID_MODEL_FROM_DATABASE=CMI8738/CMI8768 PCI Audio (X-Mystique 7.1 LP Value)
 
 pci:v000013F6d00000111sv00007284sd00008384*
- ID_MODEL_FROM_DATABASE=Striker 7.1
+ ID_MODEL_FROM_DATABASE=CMI8738/CMI8768 PCI Audio (Striker 7.1)
 
 pci:v000013F6d00000211*
  ID_MODEL_FROM_DATABASE=CM8738
@@ -40488,85 +41538,88 @@ pci:v000013F6d00005011*
  ID_MODEL_FROM_DATABASE=CM8888 [Oxygen Express]
 
 pci:v000013F6d00005011sv000013F6sd00005011*
- ID_MODEL_FROM_DATABASE=HDA Controller
+ ID_MODEL_FROM_DATABASE=CM8888 [Oxygen Express] (HDA Controller)
 
 pci:v000013F6d00008788*
  ID_MODEL_FROM_DATABASE=CMI8788 [Oxygen HD Audio]
 
 pci:v000013F6d00008788sv00001043sd00008269*
- ID_MODEL_FROM_DATABASE=Virtuoso 200 (Xonar D2)
+ ID_MODEL_FROM_DATABASE=CMI8788 [Oxygen HD Audio] (Virtuoso 200 (Xonar D2))
 
 pci:v000013F6d00008788sv00001043sd00008275*
- ID_MODEL_FROM_DATABASE=Virtuoso 100 (Xonar DX)
+ ID_MODEL_FROM_DATABASE=CMI8788 [Oxygen HD Audio] (Virtuoso 100 (Xonar DX))
 
 pci:v000013F6d00008788sv00001043sd000082B7*
- ID_MODEL_FROM_DATABASE=Virtuoso 200 (Xonar D2X)
+ ID_MODEL_FROM_DATABASE=CMI8788 [Oxygen HD Audio] (Virtuoso 200 (Xonar D2X))
 
 pci:v000013F6d00008788sv00001043sd00008314*
- ID_MODEL_FROM_DATABASE=Virtuoso 200 (Xonar HDAV1.3)
+ ID_MODEL_FROM_DATABASE=CMI8788 [Oxygen HD Audio] (Virtuoso 200 (Xonar HDAV1.3))
 
 pci:v000013F6d00008788sv00001043sd00008327*
- ID_MODEL_FROM_DATABASE=Virtuoso 100 (Xonar DX)
+ ID_MODEL_FROM_DATABASE=CMI8788 [Oxygen HD Audio] (Virtuoso 100 (Xonar DX))
 
 pci:v000013F6d00008788sv00001043sd0000834F*
- ID_MODEL_FROM_DATABASE=Virtuoso 100 (Xonar D1)
+ ID_MODEL_FROM_DATABASE=CMI8788 [Oxygen HD Audio] (Virtuoso 100 (Xonar D1))
 
 pci:v000013F6d00008788sv00001043sd0000835C*
- ID_MODEL_FROM_DATABASE=Virtuoso 100 (Xonar Essence STX)
+ ID_MODEL_FROM_DATABASE=CMI8788 [Oxygen HD Audio] (Virtuoso 100 (Xonar Essence STX))
 
 pci:v000013F6d00008788sv00001043sd0000835D*
- ID_MODEL_FROM_DATABASE=Virtuoso 100 (Xonar ST)
+ ID_MODEL_FROM_DATABASE=CMI8788 [Oxygen HD Audio] (Virtuoso 100 (Xonar ST))
 
 pci:v000013F6d00008788sv00001043sd0000835E*
- ID_MODEL_FROM_DATABASE=Virtuoso 200 (Xonar HDAV1.3 Slim)
+ ID_MODEL_FROM_DATABASE=CMI8788 [Oxygen HD Audio] (Virtuoso 200 (Xonar HDAV1.3 Slim))
 
 pci:v000013F6d00008788sv00001043sd0000838E*
- ID_MODEL_FROM_DATABASE=Virtuoso 66 (Xonar DS)
+ ID_MODEL_FROM_DATABASE=CMI8788 [Oxygen HD Audio] (Virtuoso 66 (Xonar DS))
 
 pci:v000013F6d00008788sv00001043sd00008428*
- ID_MODEL_FROM_DATABASE=Virtuoso 100 (Xonar Xense)
+ ID_MODEL_FROM_DATABASE=CMI8788 [Oxygen HD Audio] (Virtuoso 100 (Xonar Xense))
 
 pci:v000013F6d00008788sv00001043sd00008467*
- ID_MODEL_FROM_DATABASE=CMI8786 (Xonar DG)
+ ID_MODEL_FROM_DATABASE=CMI8788 [Oxygen HD Audio] (CMI8786 (Xonar DG))
+
+pci:v000013F6d00008788sv00001043sd000085F4*
+ ID_MODEL_FROM_DATABASE=CMI8788 [Oxygen HD Audio] (Virtuoso 100 (Xonar Essence STX II))
 
 pci:v000013F6d00008788sv000013F6sd00008782*
- ID_MODEL_FROM_DATABASE=PCI 2.0 HD Audio
+ ID_MODEL_FROM_DATABASE=CMI8788 [Oxygen HD Audio] (PCI 2.0 HD Audio)
 
 pci:v000013F6d00008788sv000013F6sd0000FFFF*
- ID_MODEL_FROM_DATABASE=CMI8787-HG2PCI
+ ID_MODEL_FROM_DATABASE=CMI8788 [Oxygen HD Audio] (CMI8787-HG2PCI)
 
 pci:v000013F6d00008788sv000014C3sd00001710*
- ID_MODEL_FROM_DATABASE=HiFier Fantasia
+ ID_MODEL_FROM_DATABASE=CMI8788 [Oxygen HD Audio] (HiFier Fantasia)
 
 pci:v000013F6d00008788sv000014C3sd00001711*
- ID_MODEL_FROM_DATABASE=HiFier Serenade
+ ID_MODEL_FROM_DATABASE=CMI8788 [Oxygen HD Audio] (HiFier Serenade)
 
 pci:v000013F6d00008788sv000014C3sd00001713*
- ID_MODEL_FROM_DATABASE=HiFier Serenade III
+ ID_MODEL_FROM_DATABASE=CMI8788 [Oxygen HD Audio] (HiFier Serenade III)
 
 pci:v000013F6d00008788sv00001A58sd00000910*
- ID_MODEL_FROM_DATABASE=Barracuda AC-1
+ ID_MODEL_FROM_DATABASE=CMI8788 [Oxygen HD Audio] (Barracuda AC-1)
 
 pci:v000013F6d00008788sv0000415Asd00005431*
- ID_MODEL_FROM_DATABASE=X-Meridian 7.1
+ ID_MODEL_FROM_DATABASE=CMI8788 [Oxygen HD Audio] (X-Meridian 7.1)
 
 pci:v000013F6d00008788sv00005431sd0000017A*
- ID_MODEL_FROM_DATABASE=X-Meridian 7.1 2G
+ ID_MODEL_FROM_DATABASE=CMI8788 [Oxygen HD Audio] (X-Meridian 7.1 2G)
 
 pci:v000013F6d00008788sv0000584Dsd00003781*
- ID_MODEL_FROM_DATABASE=HDA X-Purity 7.1 Platinum
+ ID_MODEL_FROM_DATABASE=CMI8788 [Oxygen HD Audio] (HDA X-Purity 7.1 Platinum)
 
 pci:v000013F6d00008788sv00007284sd00009761*
- ID_MODEL_FROM_DATABASE=CLARO
+ ID_MODEL_FROM_DATABASE=CMI8788 [Oxygen HD Audio] (CLARO)
 
 pci:v000013F6d00008788sv00007284sd00009781*
- ID_MODEL_FROM_DATABASE=CLARO halo
+ ID_MODEL_FROM_DATABASE=CMI8788 [Oxygen HD Audio] (CLARO halo)
 
 pci:v000013F6d00008788sv00007284sd00009783*
- ID_MODEL_FROM_DATABASE=eCLARO
+ ID_MODEL_FROM_DATABASE=CMI8788 [Oxygen HD Audio] (eCLARO)
 
 pci:v000013F6d00008788sv00007284sd00009787*
- ID_MODEL_FROM_DATABASE=CLARO II
+ ID_MODEL_FROM_DATABASE=CMI8788 [Oxygen HD Audio] (CLARO II)
 
 pci:v000013F7*
  ID_VENDOR_FROM_DATABASE=Wildfire Communications
@@ -40599,13 +41652,13 @@ pci:v000013FEd00001600*
  ID_MODEL_FROM_DATABASE=PCI-16xx series PCI multiport serial board (function 0)
 
 pci:v000013FEd00001600sv00001601sd00000002*
- ID_MODEL_FROM_DATABASE=PCI-1601 2-port unisolated RS-422/485
+ ID_MODEL_FROM_DATABASE=PCI-16xx series PCI multiport serial board (function 0) (PCI-1601 2-port unisolated RS-422/485)
 
 pci:v000013FEd00001600sv00001602sd00000002*
- ID_MODEL_FROM_DATABASE=PCI-1602 2-port isolated RS-422/485
+ ID_MODEL_FROM_DATABASE=PCI-16xx series PCI multiport serial board (function 0) (PCI-1602 2-port isolated RS-422/485)
 
 pci:v000013FEd00001600sv00001612sd00000004*
- ID_MODEL_FROM_DATABASE=PCI-1612 4-port RS-232/422/485
+ ID_MODEL_FROM_DATABASE=PCI-16xx series PCI multiport serial board (function 0) (PCI-1612 4-port RS-232/422/485)
 
 pci:v000013FEd00001603*
  ID_MODEL_FROM_DATABASE=PCI-1603 2-port isolated RS-232/current loop
@@ -40617,13 +41670,13 @@ pci:v000013FEd000016FF*
  ID_MODEL_FROM_DATABASE=PCI-16xx series PCI multiport serial board (function 1: RX/TX steering CPLD)
 
 pci:v000013FEd000016FFsv00001601sd00000000*
- ID_MODEL_FROM_DATABASE=PCI-1601 2-port unisolated RS-422/485 PCI communications card
+ ID_MODEL_FROM_DATABASE=PCI-16xx series PCI multiport serial board (function 1: RX/TX steering CPLD) (PCI-1601 2-port unisolated RS-422/485 PCI communications card)
 
 pci:v000013FEd000016FFsv00001602sd00000000*
- ID_MODEL_FROM_DATABASE=PCI-1602 2-port isolated RS-422/485
+ ID_MODEL_FROM_DATABASE=PCI-16xx series PCI multiport serial board (function 1: RX/TX steering CPLD) (PCI-1602 2-port isolated RS-422/485)
 
 pci:v000013FEd000016FFsv00001612sd00000000*
- ID_MODEL_FROM_DATABASE=PCI-1612 4-port RS-232/422/485
+ ID_MODEL_FROM_DATABASE=PCI-16xx series PCI multiport serial board (function 1: RX/TX steering CPLD) (PCI-1612 4-port RS-232/422/485)
 
 pci:v000013FEd00001711*
  ID_MODEL_FROM_DATABASE=PCI-1711 16-channel data acquisition card 12-bit, 100kS/s
@@ -40977,37 +42030,37 @@ pci:v00001409d00007168*
  ID_MODEL_FROM_DATABASE=PCI2S550 (Dual 16550 UART)
 
 pci:v00001409d00007168sv00001409sd00000002*
- ID_MODEL_FROM_DATABASE=SER4036A3V (2x RS232 port)
+ ID_MODEL_FROM_DATABASE=PCI2S550 (Dual 16550 UART) (SER4036A3V (2x RS232 port))
 
 pci:v00001409d00007168sv00001409sd00004027*
- ID_MODEL_FROM_DATABASE=SER4027A (1x RS232 port)
+ ID_MODEL_FROM_DATABASE=PCI2S550 (Dual 16550 UART) (SER4027A (1x RS232 port))
 
 pci:v00001409d00007168sv00001409sd00004037*
- ID_MODEL_FROM_DATABASE=SER4037A (2x RS232 port)
+ ID_MODEL_FROM_DATABASE=PCI2S550 (Dual 16550 UART) (SER4037A (2x RS232 port))
 
 pci:v00001409d00007168sv00001409sd00004056*
- ID_MODEL_FROM_DATABASE=SER4056A (4x RS232)
+ ID_MODEL_FROM_DATABASE=PCI2S550 (Dual 16550 UART) (SER4056A (4x RS232))
 
 pci:v00001409d00007168sv00001409sd00005027*
- ID_MODEL_FROM_DATABASE=SER4027D
+ ID_MODEL_FROM_DATABASE=PCI2S550 (Dual 16550 UART) (SER4027D)
 
 pci:v00001409d00007168sv00001409sd00005037*
- ID_MODEL_FROM_DATABASE=SER4037D (2x RS232 port)
+ ID_MODEL_FROM_DATABASE=PCI2S550 (Dual 16550 UART) (SER4037D (2x RS232 port))
 
 pci:v00001409d00007168sv00001409sd00005066*
- ID_MODEL_FROM_DATABASE=SER4066R (8x RS232)
+ ID_MODEL_FROM_DATABASE=PCI2S550 (Dual 16550 UART) (SER4066R (8x RS232))
 
 pci:v00001409d00007168sv00001409sd00006056*
- ID_MODEL_FROM_DATABASE=SER4056D (4x RS232 port)
+ ID_MODEL_FROM_DATABASE=PCI2S550 (Dual 16550 UART) (SER4056D (4x RS232 port))
 
 pci:v00001409d00007268*
  ID_MODEL_FROM_DATABASE=SUN1888 (Dual IEEE1284 parallel port)
 
 pci:v00001409d00007268sv00001409sd00000103*
- ID_MODEL_FROM_DATABASE=PAR4008A
+ ID_MODEL_FROM_DATABASE=SUN1888 (Dual IEEE1284 parallel port) (PAR4008A)
 
 pci:v00001409d00007268sv00001409sd00000104*
- ID_MODEL_FROM_DATABASE=PAR4018A
+ ID_MODEL_FROM_DATABASE=SUN1888 (Dual IEEE1284 parallel port) (PAR4018A)
 
 pci:v0000140A*
  ID_VENDOR_FROM_DATABASE=DSP Research Inc
@@ -41040,106 +42093,106 @@ pci:v00001412d00001712*
  ID_MODEL_FROM_DATABASE=ICE1712 [Envy24] PCI Multi-Channel I/O Controller
 
 pci:v00001412d00001712sv00001412sd00001712*
- ID_MODEL_FROM_DATABASE=Hoontech ST Audio DSP 24
+ ID_MODEL_FROM_DATABASE=ICE1712 [Envy24] PCI Multi-Channel I/O Controller (Hoontech ST Audio DSP 24)
 
 pci:v00001412d00001712sv00001412sd00003632*
- ID_MODEL_FROM_DATABASE=M-Audio Delta Audiophile 192
+ ID_MODEL_FROM_DATABASE=ICE1712 [Envy24] PCI Multi-Channel I/O Controller (M-Audio Delta Audiophile 192)
 
 pci:v00001412d00001712sv00001412sd0000D630*
- ID_MODEL_FROM_DATABASE=M-Audio Delta 1010
+ ID_MODEL_FROM_DATABASE=ICE1712 [Envy24] PCI Multi-Channel I/O Controller (M-Audio Delta 1010)
 
 pci:v00001412d00001712sv00001412sd0000D631*
- ID_MODEL_FROM_DATABASE=M-Audio Delta DiO
+ ID_MODEL_FROM_DATABASE=ICE1712 [Envy24] PCI Multi-Channel I/O Controller (M-Audio Delta DiO)
 
 pci:v00001412d00001712sv00001412sd0000D632*
- ID_MODEL_FROM_DATABASE=M-Audio Delta 66
+ ID_MODEL_FROM_DATABASE=ICE1712 [Envy24] PCI Multi-Channel I/O Controller (M-Audio Delta 66)
 
 pci:v00001412d00001712sv00001412sd0000D633*
- ID_MODEL_FROM_DATABASE=M-Audio Delta 44
+ ID_MODEL_FROM_DATABASE=ICE1712 [Envy24] PCI Multi-Channel I/O Controller (M-Audio Delta 44)
 
 pci:v00001412d00001712sv00001412sd0000D634*
- ID_MODEL_FROM_DATABASE=M-Audio Delta Audiophile 2496
+ ID_MODEL_FROM_DATABASE=ICE1712 [Envy24] PCI Multi-Channel I/O Controller (M-Audio Delta Audiophile 2496)
 
 pci:v00001412d00001712sv00001412sd0000D635*
- ID_MODEL_FROM_DATABASE=M-Audio Delta TDIF
+ ID_MODEL_FROM_DATABASE=ICE1712 [Envy24] PCI Multi-Channel I/O Controller (M-Audio Delta TDIF)
 
 pci:v00001412d00001712sv00001412sd0000D637*
- ID_MODEL_FROM_DATABASE=M-Audio Delta RBUS
+ ID_MODEL_FROM_DATABASE=ICE1712 [Envy24] PCI Multi-Channel I/O Controller (M-Audio Delta RBUS)
 
 pci:v00001412d00001712sv00001412sd0000D638*
- ID_MODEL_FROM_DATABASE=M-Audio Delta 410
+ ID_MODEL_FROM_DATABASE=ICE1712 [Envy24] PCI Multi-Channel I/O Controller (M-Audio Delta 410)
 
 pci:v00001412d00001712sv00001412sd0000D63B*
- ID_MODEL_FROM_DATABASE=M-Audio Delta 1010LT
+ ID_MODEL_FROM_DATABASE=ICE1712 [Envy24] PCI Multi-Channel I/O Controller (M-Audio Delta 1010LT)
 
 pci:v00001412d00001712sv00001412sd0000D63C*
- ID_MODEL_FROM_DATABASE=Digigram VX442
+ ID_MODEL_FROM_DATABASE=ICE1712 [Envy24] PCI Multi-Channel I/O Controller (Digigram VX442)
 
 pci:v00001412d00001712sv00001416sd00001712*
- ID_MODEL_FROM_DATABASE=Hoontech ST Audio DSP 24 Media 7.1
+ ID_MODEL_FROM_DATABASE=ICE1712 [Envy24] PCI Multi-Channel I/O Controller (Hoontech ST Audio DSP 24 Media 7.1)
 
 pci:v00001412d00001712sv0000153Bsd00001115*
- ID_MODEL_FROM_DATABASE=EWS88 MT
+ ID_MODEL_FROM_DATABASE=ICE1712 [Envy24] PCI Multi-Channel I/O Controller (EWS88 MT)
 
 pci:v00001412d00001712sv0000153Bsd00001125*
- ID_MODEL_FROM_DATABASE=EWS88 MT (Master)
+ ID_MODEL_FROM_DATABASE=ICE1712 [Envy24] PCI Multi-Channel I/O Controller (EWS88 MT (Master))
 
 pci:v00001412d00001712sv0000153Bsd0000112B*
- ID_MODEL_FROM_DATABASE=EWS88 D
+ ID_MODEL_FROM_DATABASE=ICE1712 [Envy24] PCI Multi-Channel I/O Controller (EWS88 D)
 
 pci:v00001412d00001712sv0000153Bsd0000112C*
- ID_MODEL_FROM_DATABASE=EWS88 D (Master)
+ ID_MODEL_FROM_DATABASE=ICE1712 [Envy24] PCI Multi-Channel I/O Controller (EWS88 D (Master))
 
 pci:v00001412d00001712sv0000153Bsd00001130*
- ID_MODEL_FROM_DATABASE=EWX 24/96
+ ID_MODEL_FROM_DATABASE=ICE1712 [Envy24] PCI Multi-Channel I/O Controller (EWX 24/96)
 
 pci:v00001412d00001712sv0000153Bsd00001138*
- ID_MODEL_FROM_DATABASE=DMX 6fire 24/96
+ ID_MODEL_FROM_DATABASE=ICE1712 [Envy24] PCI Multi-Channel I/O Controller (DMX 6fire 24/96)
 
 pci:v00001412d00001712sv0000153Bsd00001151*
- ID_MODEL_FROM_DATABASE=PHASE88
+ ID_MODEL_FROM_DATABASE=ICE1712 [Envy24] PCI Multi-Channel I/O Controller (PHASE88)
 
 pci:v00001412d00001712sv000016CEsd00001040*
- ID_MODEL_FROM_DATABASE=Edirol DA-2496
+ ID_MODEL_FROM_DATABASE=ICE1712 [Envy24] PCI Multi-Channel I/O Controller (Edirol DA-2496)
 
 pci:v00001412d00001724*
  ID_MODEL_FROM_DATABASE=VT1720/24 [Envy24PT/HT] PCI Multi-Channel Audio Controller
 
 pci:v00001412d00001724sv000010B0sd00000200*
- ID_MODEL_FROM_DATABASE=Hollywood@Home 7.1
+ ID_MODEL_FROM_DATABASE=VT1720/24 [Envy24PT/HT] PCI Multi-Channel Audio Controller (Hollywood@Home 7.1)
 
 pci:v00001412d00001724sv00001412sd00001724*
- ID_MODEL_FROM_DATABASE=Albatron PX865PE 7.1
+ ID_MODEL_FROM_DATABASE=VT1720/24 [Envy24PT/HT] PCI Multi-Channel Audio Controller (Albatron PX865PE 7.1)
 
 pci:v00001412d00001724sv00001412sd00003630*
- ID_MODEL_FROM_DATABASE=M-Audio Revolution 7.1
+ ID_MODEL_FROM_DATABASE=VT1720/24 [Envy24PT/HT] PCI Multi-Channel Audio Controller (M-Audio Revolution 7.1)
 
 pci:v00001412d00001724sv00001412sd00003631*
- ID_MODEL_FROM_DATABASE=M-Audio Revolution 5.1
+ ID_MODEL_FROM_DATABASE=VT1720/24 [Envy24PT/HT] PCI Multi-Channel Audio Controller (M-Audio Revolution 5.1)
 
 pci:v00001412d00001724sv0000153Bsd00001145*
- ID_MODEL_FROM_DATABASE=Aureon 7.1 Space
+ ID_MODEL_FROM_DATABASE=VT1720/24 [Envy24PT/HT] PCI Multi-Channel Audio Controller (Aureon 7.1 Space)
 
 pci:v00001412d00001724sv0000153Bsd00001147*
- ID_MODEL_FROM_DATABASE=Aureon 5.1 Sky
+ ID_MODEL_FROM_DATABASE=VT1720/24 [Envy24PT/HT] PCI Multi-Channel Audio Controller (Aureon 5.1 Sky)
 
 pci:v00001412d00001724sv0000153Bsd00001150*
- ID_MODEL_FROM_DATABASE=PHASE 22
+ ID_MODEL_FROM_DATABASE=VT1720/24 [Envy24PT/HT] PCI Multi-Channel Audio Controller (PHASE 22)
 
 pci:v00001412d00001724sv0000153Bsd00001153*
- ID_MODEL_FROM_DATABASE=Aureon 7.1 Universe
+ ID_MODEL_FROM_DATABASE=VT1720/24 [Envy24PT/HT] PCI Multi-Channel Audio Controller (Aureon 7.1 Universe)
 
 pci:v00001412d00001724sv000017ABsd00001906*
- ID_MODEL_FROM_DATABASE=PSC 724 [Ultimate Edge]
+ ID_MODEL_FROM_DATABASE=VT1720/24 [Envy24PT/HT] PCI Multi-Channel Audio Controller (PSC 724 [Ultimate Edge])
 
 pci:v00001412d00001724sv0000270Fsd0000F641*
- ID_MODEL_FROM_DATABASE=ZNF3-150
+ ID_MODEL_FROM_DATABASE=VT1720/24 [Envy24PT/HT] PCI Multi-Channel Audio Controller (ZNF3-150)
 
 pci:v00001412d00001724sv0000270Fsd0000F645*
- ID_MODEL_FROM_DATABASE=ZNF3-250
+ ID_MODEL_FROM_DATABASE=VT1720/24 [Envy24PT/HT] PCI Multi-Channel Audio Controller (ZNF3-250)
 
 pci:v00001412d00001724sv00003130sd00004154*
- ID_MODEL_FROM_DATABASE=MAYA 44 MKII
+ ID_MODEL_FROM_DATABASE=VT1720/24 [Envy24PT/HT] PCI Multi-Channel Audio Controller (MAYA 44 MKII)
 
 pci:v00001413*
  ID_VENDOR_FROM_DATABASE=Addonics
@@ -41205,28 +42258,28 @@ pci:v00001415d00009501*
  ID_MODEL_FROM_DATABASE=OX16PCI954 (Quad 16950 UART) function 0 (Uart)
 
 pci:v00001415d00009501sv000012C4sd00000201*
- ID_MODEL_FROM_DATABASE=Titan/cPCI (2 port)
+ ID_MODEL_FROM_DATABASE=OX16PCI954 (Quad 16950 UART) function 0 (Uart) (Titan/cPCI (2 port))
 
 pci:v00001415d00009501sv000012C4sd00000202*
- ID_MODEL_FROM_DATABASE=Titan/cPCI (4 port)
+ ID_MODEL_FROM_DATABASE=OX16PCI954 (Quad 16950 UART) function 0 (Uart) (Titan/cPCI (4 port))
 
 pci:v00001415d00009501sv000012C4sd00000203*
- ID_MODEL_FROM_DATABASE=Titan/cPCI (8 port)
+ ID_MODEL_FROM_DATABASE=OX16PCI954 (Quad 16950 UART) function 0 (Uart) (Titan/cPCI (8 port))
 
 pci:v00001415d00009501sv000012C4sd00000210*
- ID_MODEL_FROM_DATABASE=Titan/104-Plus (8 port, p1-4)
+ ID_MODEL_FROM_DATABASE=OX16PCI954 (Quad 16950 UART) function 0 (Uart) (Titan/104-Plus (8 port, p1-4))
 
 pci:v00001415d00009501sv0000131Fsd00002050*
- ID_MODEL_FROM_DATABASE=CyberPro (4-port)
+ ID_MODEL_FROM_DATABASE=OX16PCI954 (Quad 16950 UART) function 0 (Uart) (CyberPro (4-port))
 
 pci:v00001415d00009501sv0000131Fsd00002051*
- ID_MODEL_FROM_DATABASE=CyberSerial 4S Plus
+ ID_MODEL_FROM_DATABASE=OX16PCI954 (Quad 16950 UART) function 0 (Uart) (CyberSerial 4S Plus)
 
 pci:v00001415d00009501sv000015EDsd00002000*
- ID_MODEL_FROM_DATABASE=MCCR Serial p0-3 of 8
+ ID_MODEL_FROM_DATABASE=OX16PCI954 (Quad 16950 UART) function 0 (Uart) (MCCR Serial p0-3 of 8)
 
 pci:v00001415d00009501sv000015EDsd00002001*
- ID_MODEL_FROM_DATABASE=MCCR Serial p0-3 of 16
+ ID_MODEL_FROM_DATABASE=OX16PCI954 (Quad 16950 UART) function 0 (Uart) (MCCR Serial p0-3 of 16)
 
 pci:v00001415d00009505*
  ID_MODEL_FROM_DATABASE=OXuPCI952 (Dual 16C950 UART)
@@ -41241,19 +42294,19 @@ pci:v00001415d00009510*
  ID_MODEL_FROM_DATABASE=OX16PCI954 (Quad 16950 UART) function 1 (Disabled)
 
 pci:v00001415d00009510sv000012C4sd00000200*
- ID_MODEL_FROM_DATABASE=Titan/cPCI (Unused)
+ ID_MODEL_FROM_DATABASE=OX16PCI954 (Quad 16950 UART) function 1 (Disabled) (Titan/cPCI (Unused))
 
 pci:v00001415d00009511*
  ID_MODEL_FROM_DATABASE=OX16PCI954 (Quad 16950 UART) function 1 (8bit bus)
 
 pci:v00001415d00009511sv000012C4sd00000211*
- ID_MODEL_FROM_DATABASE=Titan/104-Plus (8 port, p5-8)
+ ID_MODEL_FROM_DATABASE=OX16PCI954 (Quad 16950 UART) function 1 (8bit bus) (Titan/104-Plus (8 port, p5-8))
 
 pci:v00001415d00009511sv000015EDsd00002000*
- ID_MODEL_FROM_DATABASE=MCCR Serial p4-7 of 8
+ ID_MODEL_FROM_DATABASE=OX16PCI954 (Quad 16950 UART) function 1 (8bit bus) (MCCR Serial p4-7 of 8)
 
 pci:v00001415d00009511sv000015EDsd00002001*
- ID_MODEL_FROM_DATABASE=MCCR Serial p4-15 of 16
+ ID_MODEL_FROM_DATABASE=OX16PCI954 (Quad 16950 UART) function 1 (8bit bus) (MCCR Serial p4-15 of 16)
 
 pci:v00001415d00009512*
  ID_MODEL_FROM_DATABASE=OX16PCI954 (Quad 16950 UART) function 1 (32bit bus)
@@ -41271,10 +42324,10 @@ pci:v00001415d0000C158*
  ID_MODEL_FROM_DATABASE=OXPCIe952 Dual 16C950 UART
 
 pci:v00001415d0000C158sv0000E4BFsd0000C504*
- ID_MODEL_FROM_DATABASE=CP4-SCAT Wireless Technologies Carrier Board
+ ID_MODEL_FROM_DATABASE=OXPCIe952 Dual 16C950 UART (CP4-SCAT Wireless Technologies Carrier Board)
 
 pci:v00001415d0000C158sv0000E4BFsd0000D551*
- ID_MODEL_FROM_DATABASE=DU1-MUSTANG Dual-Port RS-485 Interface
+ ID_MODEL_FROM_DATABASE=OXPCIe952 Dual 16C950 UART (DU1-MUSTANG Dual-Port RS-485 Interface)
 
 pci:v00001415d0000C308*
  ID_MODEL_FROM_DATABASE=EX-44016 16-port serial
@@ -41343,7 +42396,7 @@ pci:v00001425d00000030*
  ID_MODEL_FROM_DATABASE=T310 10GbE Single Port Adapter
 
 pci:v00001425d00000030sv0000103Csd0000705E*
- ID_MODEL_FROM_DATABASE=PCIe 10GBase-SR [AD386A]
+ ID_MODEL_FROM_DATABASE=T310 10GbE Single Port Adapter (PCIe 10GBase-SR [AD386A])
 
 pci:v00001425d00000031*
  ID_MODEL_FROM_DATABASE=T320 10GbE Dual Port Adapter
@@ -41424,7 +42477,7 @@ pci:v00001425d00004083*
  ID_MODEL_FROM_DATABASE=T420X-4083 Unified Wire Ethernet Controller
 
 pci:v00001425d00004084*
- ID_MODEL_FROM_DATABASE=T420-4084 Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T440-4084 Unified Wire Ethernet Controller
 
 pci:v00001425d00004085*
  ID_MODEL_FROM_DATABASE=T420-4085 SFP+ Unified Wire Ethernet Controller
@@ -41496,7 +42549,7 @@ pci:v00001425d00004483*
  ID_MODEL_FROM_DATABASE=T420X-4083 Unified Wire Ethernet Controller
 
 pci:v00001425d00004484*
- ID_MODEL_FROM_DATABASE=T420-4084 Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T440-4084 Unified Wire Ethernet Controller
 
 pci:v00001425d00004485*
  ID_MODEL_FROM_DATABASE=T420-4085 SFP+ Unified Wire Ethernet Controller
@@ -41568,7 +42621,7 @@ pci:v00001425d00004583*
  ID_MODEL_FROM_DATABASE=T420X-4083 Unified Wire Storage Controller
 
 pci:v00001425d00004584*
- ID_MODEL_FROM_DATABASE=T420-4084 Unified Wire Storage Controller
+ ID_MODEL_FROM_DATABASE=T440-4084 Unified Wire Storage Controller
 
 pci:v00001425d00004585*
  ID_MODEL_FROM_DATABASE=T420-4085 SFP+ Unified Wire Storage Controller
@@ -41640,7 +42693,7 @@ pci:v00001425d00004683*
  ID_MODEL_FROM_DATABASE=T420X-4083 Unified Wire Storage Controller
 
 pci:v00001425d00004684*
- ID_MODEL_FROM_DATABASE=T420-4084 Unified Wire Storage Controller
+ ID_MODEL_FROM_DATABASE=T440-4084 Unified Wire Storage Controller
 
 pci:v00001425d00004685*
  ID_MODEL_FROM_DATABASE=T420-4085 SFP+ Unified Wire Storage Controller
@@ -41712,7 +42765,7 @@ pci:v00001425d00004783*
  ID_MODEL_FROM_DATABASE=T420X-4083 Unified Wire Ethernet Controller
 
 pci:v00001425d00004784*
- ID_MODEL_FROM_DATABASE=T420-4084 Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T440-4084 Unified Wire Ethernet Controller
 
 pci:v00001425d00004785*
  ID_MODEL_FROM_DATABASE=T420-4085 SFP+ Unified Wire Ethernet Controller
@@ -41727,76 +42780,76 @@ pci:v00001425d00004788*
  ID_MODEL_FROM_DATABASE=T440-4088 Unified Wire Ethernet Controller
 
 pci:v00001425d00004801*
- ID_MODEL_FROM_DATABASE=T420-CR Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T420-CR Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d00004802*
- ID_MODEL_FROM_DATABASE=T422-CR Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T422-CR Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d00004803*
- ID_MODEL_FROM_DATABASE=T440-CR Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T440-CR Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d00004804*
- ID_MODEL_FROM_DATABASE=T420-BCH Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T420-BCH Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d00004805*
- ID_MODEL_FROM_DATABASE=T440-BCH Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T440-BCH Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d00004806*
- ID_MODEL_FROM_DATABASE=T440-CH Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T440-CH Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d00004807*
- ID_MODEL_FROM_DATABASE=T420-SO Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T420-SO Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d00004808*
- ID_MODEL_FROM_DATABASE=T420-CX Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T420-CX Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d00004809*
- ID_MODEL_FROM_DATABASE=T420-BT Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T420-BT Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d0000480A*
- ID_MODEL_FROM_DATABASE=T404-BT Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T404-BT Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d0000480B*
- ID_MODEL_FROM_DATABASE=B420-SR Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=B420-SR Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d0000480C*
- ID_MODEL_FROM_DATABASE=B404-BT Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=B404-BT Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d0000480D*
- ID_MODEL_FROM_DATABASE=T480 Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T480 Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d0000480E*
- ID_MODEL_FROM_DATABASE=T440-LP-CR Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T440-LP-CR Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d0000480F*
- ID_MODEL_FROM_DATABASE=T440 [Amsterdam] Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T440 [Amsterdam] Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d00004880*
- ID_MODEL_FROM_DATABASE=T480-4080 T480 Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T480-4080 T480 Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d00004881*
- ID_MODEL_FROM_DATABASE=T440F-4081 T440-FCoE Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T440F-4081 T440-FCoE Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d00004882*
- ID_MODEL_FROM_DATABASE=T420-4082  Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T420-4082 Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d00004883*
- ID_MODEL_FROM_DATABASE=T420X-4083 Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T420X-4083 Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d00004884*
- ID_MODEL_FROM_DATABASE=T420-4084 Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T440-4084 Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d00004885*
- ID_MODEL_FROM_DATABASE=T420-4085 SFP+ Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T420-4085 SFP+ Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d00004886*
- ID_MODEL_FROM_DATABASE=T440-4086 10Gbase-T Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T440-4086 10Gbase-T Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d00004887*
- ID_MODEL_FROM_DATABASE=T440T-4087 Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T440T-4087 Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d00004888*
- ID_MODEL_FROM_DATABASE=T440-4088 Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T440-4088 Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d00005001*
  ID_MODEL_FROM_DATABASE=T520-CR Unified Wire Ethernet Controller
@@ -41853,17 +42906,29 @@ pci:v00001425d00005012*
  ID_MODEL_FROM_DATABASE=T560-CR Unified Wire Ethernet Controller
 
 pci:v00001425d00005013*
- ID_MODEL_FROM_DATABASE=T580-CR Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T580-CHR Unified Wire Ethernet Controller
 
 pci:v00001425d00005014*
  ID_MODEL_FROM_DATABASE=T580-LP-SO-CR Unified Wire Ethernet Controller
 
+pci:v00001425d00005015*
+ ID_MODEL_FROM_DATABASE=T502-BT Unified Wire Ethernet Controller
+
 pci:v00001425d00005080*
  ID_MODEL_FROM_DATABASE=T540-5080 Unified Wire Ethernet Controller
 
 pci:v00001425d00005081*
  ID_MODEL_FROM_DATABASE=T540-5081 Unified Wire Ethernet Controller
 
+pci:v00001425d00005083*
+ ID_MODEL_FROM_DATABASE=T540-5083 Unified Wire Ethernet Controller
+
+pci:v00001425d00005084*
+ ID_MODEL_FROM_DATABASE=T580-5084 Unified Wire Ethernet Controller
+
+pci:v00001425d00005085*
+ ID_MODEL_FROM_DATABASE=T580-5085 Unified Wire Ethernet Controller
+
 pci:v00001425d00005401*
  ID_MODEL_FROM_DATABASE=T520-CR Unified Wire Ethernet Controller
 
@@ -41919,17 +42984,29 @@ pci:v00001425d00005412*
  ID_MODEL_FROM_DATABASE=T560-CR Unified Wire Ethernet Controller
 
 pci:v00001425d00005413*
- ID_MODEL_FROM_DATABASE=T580-CR Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T580-CHR Unified Wire Ethernet Controller
 
 pci:v00001425d00005414*
  ID_MODEL_FROM_DATABASE=T580-LP-SO-CR Unified Wire Ethernet Controller
 
+pci:v00001425d00005415*
+ ID_MODEL_FROM_DATABASE=T502-BT Unified Wire Ethernet Controller
+
 pci:v00001425d00005480*
  ID_MODEL_FROM_DATABASE=T540-5080 Unified Wire Ethernet Controller
 
 pci:v00001425d00005481*
  ID_MODEL_FROM_DATABASE=T540-5081 Unified Wire Ethernet Controller
 
+pci:v00001425d00005483*
+ ID_MODEL_FROM_DATABASE=T540-5083 Unified Wire Ethernet Controller
+
+pci:v00001425d00005484*
+ ID_MODEL_FROM_DATABASE=T580-5084 Unified Wire Ethernet Controller
+
+pci:v00001425d00005485*
+ ID_MODEL_FROM_DATABASE=T580-5085 Unified Wire Ethernet Controller
+
 pci:v00001425d00005501*
  ID_MODEL_FROM_DATABASE=T520-CR Unified Wire Storage Controller
 
@@ -41985,17 +43062,29 @@ pci:v00001425d00005512*
  ID_MODEL_FROM_DATABASE=T560-CR Unified Wire Storage Controller
 
 pci:v00001425d00005513*
- ID_MODEL_FROM_DATABASE=T580-CR Unified Wire Storage Controller
+ ID_MODEL_FROM_DATABASE=T580-CHR Unified Wire Storage Controller
 
 pci:v00001425d00005514*
  ID_MODEL_FROM_DATABASE=T580-LP-SO-CR Unified Wire Storage Controller
 
+pci:v00001425d00005515*
+ ID_MODEL_FROM_DATABASE=T502-BT Unified Wire Storage Controller
+
 pci:v00001425d00005580*
  ID_MODEL_FROM_DATABASE=T540-5080 Unified Wire Storage Controller
 
 pci:v00001425d00005581*
  ID_MODEL_FROM_DATABASE=T540-5081 Unified Wire Storage Controller
 
+pci:v00001425d00005583*
+ ID_MODEL_FROM_DATABASE=T540-5083 Unified Wire Storage Controller
+
+pci:v00001425d00005584*
+ ID_MODEL_FROM_DATABASE=T580-5084 Unified Wire Storage Controller
+
+pci:v00001425d00005585*
+ ID_MODEL_FROM_DATABASE=T580-5085 Unified Wire Storage Controller
+
 pci:v00001425d00005601*
  ID_MODEL_FROM_DATABASE=T520-CR Unified Wire Storage Controller
 
@@ -42051,17 +43140,29 @@ pci:v00001425d00005612*
  ID_MODEL_FROM_DATABASE=T560-CR Unified Wire Storage Controller
 
 pci:v00001425d00005613*
- ID_MODEL_FROM_DATABASE=T580-CR Unified Wire Storage Controller
+ ID_MODEL_FROM_DATABASE=T580-CHR Unified Wire Storage Controller
 
 pci:v00001425d00005614*
  ID_MODEL_FROM_DATABASE=T580-LP-SO-CR Unified Wire Storage Controller
 
+pci:v00001425d00005615*
+ ID_MODEL_FROM_DATABASE=T502-BT Unified Wire Storage Controller
+
 pci:v00001425d00005680*
  ID_MODEL_FROM_DATABASE=T540-5080 Unified Wire Storage Controller
 
 pci:v00001425d00005681*
  ID_MODEL_FROM_DATABASE=T540-5081 Unified Wire Storage Controller
 
+pci:v00001425d00005683*
+ ID_MODEL_FROM_DATABASE=T540-5083 Unified Wire Storage Controller
+
+pci:v00001425d00005684*
+ ID_MODEL_FROM_DATABASE=T580-5084 Unified Wire Storage Controller
+
+pci:v00001425d00005685*
+ ID_MODEL_FROM_DATABASE=T580-5085 Unified Wire Storage Controller
+
 pci:v00001425d00005701*
  ID_MODEL_FROM_DATABASE=T520-CR Unified Wire Ethernet Controller
 
@@ -42122,77 +43223,101 @@ pci:v00001425d00005713*
 pci:v00001425d00005714*
  ID_MODEL_FROM_DATABASE=T580-LP-SO-CR Unified Wire Ethernet Controller
 
+pci:v00001425d00005715*
+ ID_MODEL_FROM_DATABASE=T502-BT Unified Wire Ethernet Controller
+
 pci:v00001425d00005780*
  ID_MODEL_FROM_DATABASE=T540-5080 Unified Wire Ethernet Controller
 
 pci:v00001425d00005781*
  ID_MODEL_FROM_DATABASE=T540-5081 Unified Wire Ethernet Controller
 
+pci:v00001425d00005783*
+ ID_MODEL_FROM_DATABASE=T540-5083 Unified Wire Ethernet Controller
+
+pci:v00001425d00005784*
+ ID_MODEL_FROM_DATABASE=T580-5084 Unified Wire Ethernet Controller
+
+pci:v00001425d00005785*
+ ID_MODEL_FROM_DATABASE=T580-5085 Unified Wire Ethernet Controller
+
 pci:v00001425d00005801*
- ID_MODEL_FROM_DATABASE=T520-CR Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T520-CR Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d00005802*
- ID_MODEL_FROM_DATABASE=T522-CR Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T522-CR Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d00005803*
- ID_MODEL_FROM_DATABASE=T540-CR Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T540-CR Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d00005804*
- ID_MODEL_FROM_DATABASE=T520-BCH Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T520-BCH Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d00005805*
- ID_MODEL_FROM_DATABASE=T540-BCH Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T540-BCH Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d00005806*
- ID_MODEL_FROM_DATABASE=T540-CH Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T540-CH Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d00005807*
- ID_MODEL_FROM_DATABASE=T520-SO Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T520-SO Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d00005808*
- ID_MODEL_FROM_DATABASE=T520-CX Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T520-CX Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d00005809*
- ID_MODEL_FROM_DATABASE=T520-BT Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T520-BT Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d0000580A*
- ID_MODEL_FROM_DATABASE=T504-BT Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T504-BT Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d0000580B*
- ID_MODEL_FROM_DATABASE=B520-SR Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=B520-SR Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d0000580C*
- ID_MODEL_FROM_DATABASE=B504-BT Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=B504-BT Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d0000580D*
- ID_MODEL_FROM_DATABASE=T580-CR Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T580-CR Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d0000580E*
- ID_MODEL_FROM_DATABASE=T540-LP-CR Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T540-LP-CR Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d0000580F*
- ID_MODEL_FROM_DATABASE=T540 [Amsterdam] Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T540 [Amsterdam] Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d00005810*
- ID_MODEL_FROM_DATABASE=T580-LP-CR Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T580-LP-CR Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d00005811*
- ID_MODEL_FROM_DATABASE=T520-LL-CR Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T520-LL-CR Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d00005812*
- ID_MODEL_FROM_DATABASE=T560-CR Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T560-CR Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d00005813*
- ID_MODEL_FROM_DATABASE=T580-CR Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T580-CHR Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d00005814*
- ID_MODEL_FROM_DATABASE=T580-LP-SO-CR Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T580-LP-SO-CR Unified Wire Ethernet Controller [VF]
+
+pci:v00001425d00005815*
+ ID_MODEL_FROM_DATABASE=T502-BT Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d00005880*
- ID_MODEL_FROM_DATABASE=T540-5080 Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T540-5080 Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d00005881*
- ID_MODEL_FROM_DATABASE=T540-5081 Unified Wire Ethernet Controller
+ ID_MODEL_FROM_DATABASE=T540-5081 Unified Wire Ethernet Controller [VF]
+
+pci:v00001425d00005883*
+ ID_MODEL_FROM_DATABASE=T540-5083 Unified Wire Ethernet Controller [VF]
+
+pci:v00001425d00005884*
+ ID_MODEL_FROM_DATABASE=T580-5084 Unified Wire Ethernet Controller [VF]
+
+pci:v00001425d00005885*
+ ID_MODEL_FROM_DATABASE=T580-5085 Unified Wire Ethernet Controller [VF]
 
 pci:v00001425d0000A000*
  ID_MODEL_FROM_DATABASE=PE10K Unified Wire Ethernet Controller
@@ -42399,13 +43524,13 @@ pci:v0000144Dd0000A820*
  ID_MODEL_FROM_DATABASE=NVMe SSD Controller 171X
 
 pci:v0000144Dd0000A820sv00001028sd00001F95*
- ID_MODEL_FROM_DATABASE=Express Flash NVMe XS1715 SSD 400GB
+ ID_MODEL_FROM_DATABASE=NVMe SSD Controller 171X (Express Flash NVMe XS1715 SSD 400GB)
 
 pci:v0000144Dd0000A820sv00001028sd00001F96*
- ID_MODEL_FROM_DATABASE=Express Flash NVMe XS1715 SSD 800GB
+ ID_MODEL_FROM_DATABASE=NVMe SSD Controller 171X (Express Flash NVMe XS1715 SSD 800GB)
 
 pci:v0000144Dd0000A820sv00001028sd00001F97*
- ID_MODEL_FROM_DATABASE=Express Flash NVMe XS1715 SSD 1600GB
+ ID_MODEL_FROM_DATABASE=NVMe SSD Controller 171X (Express Flash NVMe XS1715 SSD 1600GB)
 
 pci:v0000144E*
  ID_VENDOR_FROM_DATABASE=OLITEC
@@ -42483,7 +43608,7 @@ pci:v00001461d0000F436*
  ID_MODEL_FROM_DATABASE=AVerTV Hybrid+FM
 
 pci:v00001462*
- ID_VENDOR_FROM_DATABASE=Micro-Star International Co., Ltd.
+ ID_VENDOR_FROM_DATABASE=Micro-Star International Co., Ltd. [MSI]
 
 pci:v00001463*
  ID_VENDOR_FROM_DATABASE=Fast Corporation
@@ -42507,7 +43632,13 @@ pci:v00001469*
  ID_VENDOR_FROM_DATABASE=Cleveland Motion Controls
 
 pci:v0000146A*
- ID_VENDOR_FROM_DATABASE=IFR
+ ID_VENDOR_FROM_DATABASE=Aeroflex
+
+pci:v0000146Ad00003010*
+ ID_MODEL_FROM_DATABASE=3010 RF Synthesizer
+
+pci:v0000146Ad00003A11*
+ ID_MODEL_FROM_DATABASE=3011A PXI RF Synthesizer
 
 pci:v0000146B*
  ID_VENDOR_FROM_DATABASE=Parascan Technologies Ltd
@@ -42632,6 +43763,9 @@ pci:v0000148E*
 pci:v0000148F*
  ID_VENDOR_FROM_DATABASE=Plant Equipment, Inc.
 
+pci:v0000148Fd00005370*
+ ID_MODEL_FROM_DATABASE=Dexlink AUWL15I1
+
 pci:v00001490*
  ID_VENDOR_FROM_DATABASE=Stone Microsystems PTY Ltd.
 
@@ -42885,19 +44019,19 @@ pci:v000014C1d00000008*
  ID_MODEL_FROM_DATABASE=Myri-10G Dual-Protocol NIC
 
 pci:v000014C1d00000008sv000014C1sd00000008*
- ID_MODEL_FROM_DATABASE=10G-PCIE-8A
+ ID_MODEL_FROM_DATABASE=Myri-10G Dual-Protocol NIC (10G-PCIE-8A)
 
 pci:v000014C1d00000008sv000014C1sd00000009*
- ID_MODEL_FROM_DATABASE=10G-PCIE-8A (MSI-X firmware)
+ ID_MODEL_FROM_DATABASE=Myri-10G Dual-Protocol NIC (10G-PCIE-8A (MSI-X firmware))
 
 pci:v000014C1d00000008sv000014C1sd0000000A*
- ID_MODEL_FROM_DATABASE=10G-PCIE-8B
+ ID_MODEL_FROM_DATABASE=Myri-10G Dual-Protocol NIC (10G-PCIE-8B)
 
 pci:v000014C1d00008043*
  ID_MODEL_FROM_DATABASE=Myrinet 2000 Scalable Cluster Interconnect
 
 pci:v000014C1d00008043sv0000103Csd00001240*
- ID_MODEL_FROM_DATABASE=Myrinet M2L-PCI64/2-3.0 LANai 7.4 (HP OEM)
+ ID_MODEL_FROM_DATABASE=Myrinet 2000 Scalable Cluster Interconnect (Myrinet M2L-PCI64/2-3.0 LANai 7.4 (HP OEM))
 
 pci:v000014C2*
  ID_VENDOR_FROM_DATABASE=DTK Computer
@@ -43158,19 +44292,19 @@ pci:v000014E4d00001600*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM5752 Gigabit Ethernet PCI Express
 
 pci:v000014E4d00001600sv00001028sd000001C1*
- ID_MODEL_FROM_DATABASE=Precision 490
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5752 Gigabit Ethernet PCI Express (Precision 490)
 
 pci:v000014E4d00001600sv00001028sd000001C2*
- ID_MODEL_FROM_DATABASE=Latitude D620
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5752 Gigabit Ethernet PCI Express (Latitude D620)
 
 pci:v000014E4d00001600sv0000103Csd00003015*
- ID_MODEL_FROM_DATABASE=PCIe LAN on Motherboard
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5752 Gigabit Ethernet PCI Express (PCIe LAN on Motherboard)
 
 pci:v000014E4d00001600sv0000107Bsd00005048*
- ID_MODEL_FROM_DATABASE=E4500 Onboard
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5752 Gigabit Ethernet PCI Express (E4500 Onboard)
 
 pci:v000014E4d00001600sv00001259sd00002705*
- ID_MODEL_FROM_DATABASE=AT-2711FX
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5752 Gigabit Ethernet PCI Express (AT-2711FX)
 
 pci:v000014E4d00001601*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM5752M Gigabit Ethernet PCI Express
@@ -43185,52 +44319,52 @@ pci:v000014E4d00001639*
  ID_MODEL_FROM_DATABASE=NetXtreme II BCM5709 Gigabit Ethernet
 
 pci:v000014E4d00001639sv00001028sd00000235*
- ID_MODEL_FROM_DATABASE=PowerEdge R710 BCM5709 Gigabit Ethernet
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM5709 Gigabit Ethernet (PowerEdge R710 BCM5709 Gigabit Ethernet)
 
 pci:v000014E4d00001639sv00001028sd00000236*
- ID_MODEL_FROM_DATABASE=PowerEdge R610 BCM5709 Gigabit Ethernet
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM5709 Gigabit Ethernet (PowerEdge R610 BCM5709 Gigabit Ethernet)
 
 pci:v000014E4d00001639sv00001028sd00000237*
- ID_MODEL_FROM_DATABASE=PowerEdge T610 BCM5709 Gigabit Ethernet
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM5709 Gigabit Ethernet (PowerEdge T610 BCM5709 Gigabit Ethernet)
 
 pci:v000014E4d00001639sv0000103Csd00007055*
- ID_MODEL_FROM_DATABASE=NC382i Integrated Multi-port PCI Express Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM5709 Gigabit Ethernet (NC382i Integrated Multi-port PCI Express Gigabit Server Adapter)
 
 pci:v000014E4d00001639sv0000103Csd00007059*
- ID_MODEL_FROM_DATABASE=NC382T PCI Express Dual Port Multifunction Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM5709 Gigabit Ethernet (NC382T PCI Express Dual Port Multifunction Gigabit Server Adapter)
 
 pci:v000014E4d00001639sv000010A9sd00008027*
- ID_MODEL_FROM_DATABASE=Quad port Gigabit Ethernet Controller
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM5709 Gigabit Ethernet (Quad port Gigabit Ethernet Controller)
 
 pci:v000014E4d0000163A*
  ID_MODEL_FROM_DATABASE=NetXtreme II BCM5709S Gigabit Ethernet
 
 pci:v000014E4d0000163Asv00001028sd0000027B*
- ID_MODEL_FROM_DATABASE=PowerEdge M805 Broadcom NetXtreme II BCM5709S
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM5709S Gigabit Ethernet (PowerEdge M805 Broadcom NetXtreme II BCM5709S)
 
 pci:v000014E4d0000163Asv00001028sd0000029C*
- ID_MODEL_FROM_DATABASE=PowerEdge M710 BCM5709S Gigabit Ethernet
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM5709S Gigabit Ethernet (PowerEdge M710 BCM5709S Gigabit Ethernet)
 
 pci:v000014E4d0000163Asv0000103Csd0000171D*
- ID_MODEL_FROM_DATABASE=NC382m Dual Port 1GbE Multifunction BL-c Adapter
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM5709S Gigabit Ethernet (NC382m Dual Port 1GbE Multifunction BL-c Adapter)
 
 pci:v000014E4d0000163Asv0000103Csd00007056*
- ID_MODEL_FROM_DATABASE=NC382i Integrated Quad Port PCI Express Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM5709S Gigabit Ethernet (NC382i Integrated Quad Port PCI Express Gigabit Server Adapter)
 
 pci:v000014E4d0000163Asv00001259sd00002984*
- ID_MODEL_FROM_DATABASE=AT-2973SX
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM5709S Gigabit Ethernet (AT-2973SX)
 
 pci:v000014E4d0000163B*
  ID_MODEL_FROM_DATABASE=NetXtreme II BCM5716 Gigabit Ethernet
 
 pci:v000014E4d0000163Bsv00001028sd0000028C*
- ID_MODEL_FROM_DATABASE=PowerEdge R410 BCM5716 Gigabit Ethernet
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM5716 Gigabit Ethernet (PowerEdge R410 BCM5716 Gigabit Ethernet)
 
 pci:v000014E4d0000163Bsv00001028sd0000028D*
- ID_MODEL_FROM_DATABASE=PowerEdge T410 BCM5716 Gigabit Ethernet
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM5716 Gigabit Ethernet (PowerEdge T410 BCM5716 Gigabit Ethernet)
 
 pci:v000014E4d0000163Bsv00001028sd000002F1*
- ID_MODEL_FROM_DATABASE=PowerEdge R510 BCM5716 Gigabit Ethernet
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM5716 Gigabit Ethernet (PowerEdge R510 BCM5716 Gigabit Ethernet)
 
 pci:v000014E4d0000163C*
  ID_MODEL_FROM_DATABASE=NetXtreme II BCM5716S Gigabit Ethernet
@@ -43257,220 +44391,220 @@ pci:v000014E4d00001644*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM5700 Gigabit Ethernet
 
 pci:v000014E4d00001644sv00001014sd00000277*
- ID_MODEL_FROM_DATABASE=Broadcom Vigil B5700 1000Base-T
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5700 Gigabit Ethernet (Broadcom Vigil B5700 1000Base-T)
 
 pci:v000014E4d00001644sv00001028sd000000D1*
- ID_MODEL_FROM_DATABASE=Broadcom BCM5700
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5700 Gigabit Ethernet (Broadcom BCM5700)
 
 pci:v000014E4d00001644sv00001028sd00000106*
- ID_MODEL_FROM_DATABASE=Broadcom BCM5700
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5700 Gigabit Ethernet (Broadcom BCM5700)
 
 pci:v000014E4d00001644sv00001028sd00000109*
- ID_MODEL_FROM_DATABASE=Broadcom BCM5700 1000Base-T
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5700 Gigabit Ethernet (Broadcom BCM5700 1000Base-T)
 
 pci:v000014E4d00001644sv00001028sd0000010A*
- ID_MODEL_FROM_DATABASE=Broadcom BCM5700 1000BaseTX
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5700 Gigabit Ethernet (Broadcom BCM5700 1000BaseTX)
 
 pci:v000014E4d00001644sv000010B7sd00001000*
- ID_MODEL_FROM_DATABASE=3C996-T 1000Base-T
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5700 Gigabit Ethernet (3C996-T 1000Base-T)
 
 pci:v000014E4d00001644sv000010B7sd00001001*
- ID_MODEL_FROM_DATABASE=3C996B-T 1000Base-T
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5700 Gigabit Ethernet (3C996B-T 1000Base-T)
 
 pci:v000014E4d00001644sv000010B7sd00001002*
- ID_MODEL_FROM_DATABASE=3C996C-T 1000Base-T
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5700 Gigabit Ethernet (3C996C-T 1000Base-T)
 
 pci:v000014E4d00001644sv000010B7sd00001003*
- ID_MODEL_FROM_DATABASE=3C997-T 1000Base-T Dual Port
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5700 Gigabit Ethernet (3C997-T 1000Base-T Dual Port)
 
 pci:v000014E4d00001644sv000010B7sd00001004*
- ID_MODEL_FROM_DATABASE=3C996-SX 1000Base-SX
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5700 Gigabit Ethernet (3C996-SX 1000Base-SX)
 
 pci:v000014E4d00001644sv000010B7sd00001005*
- ID_MODEL_FROM_DATABASE=3C997-SX 1000Base-SX Dual Port
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5700 Gigabit Ethernet (3C997-SX 1000Base-SX Dual Port)
 
 pci:v000014E4d00001644sv000010B7sd00001008*
- ID_MODEL_FROM_DATABASE=3C942 Gigabit LOM (31X31)
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5700 Gigabit Ethernet (3C942 Gigabit LOM (31X31))
 
 pci:v000014E4d00001644sv000014E4sd00000002*
- ID_MODEL_FROM_DATABASE=NetXtreme 1000Base-SX
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5700 Gigabit Ethernet (NetXtreme 1000Base-SX)
 
 pci:v000014E4d00001644sv000014E4sd00000003*
- ID_MODEL_FROM_DATABASE=NetXtreme 1000Base-SX
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5700 Gigabit Ethernet (NetXtreme 1000Base-SX)
 
 pci:v000014E4d00001644sv000014E4sd00000004*
- ID_MODEL_FROM_DATABASE=NetXtreme 1000Base-T
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5700 Gigabit Ethernet (NetXtreme 1000Base-T)
 
 pci:v000014E4d00001644sv000014E4sd00001028*
- ID_MODEL_FROM_DATABASE=NetXtreme 1000BaseTX
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5700 Gigabit Ethernet (NetXtreme 1000BaseTX)
 
 pci:v000014E4d00001644sv000014E4sd00001644*
- ID_MODEL_FROM_DATABASE=BCM5700 1000Base-T
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5700 Gigabit Ethernet (BCM5700 1000Base-T)
 
 pci:v000014E4d00001645*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM5701 Gigabit Ethernet
 
 pci:v000014E4d00001645sv00000E11sd0000007C*
- ID_MODEL_FROM_DATABASE=NC7770 Gigabit Server Adapter (PCI-X, 10/100/1000-T)
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5701 Gigabit Ethernet (NC7770 Gigabit Server Adapter (PCI-X, 10/100/1000-T))
 
 pci:v000014E4d00001645sv00000E11sd0000007D*
- ID_MODEL_FROM_DATABASE=NC6770 Gigabit Server Adapter (PCI-X, 1000-SX)
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5701 Gigabit Ethernet (NC6770 Gigabit Server Adapter (PCI-X, 1000-SX))
 
 pci:v000014E4d00001645sv00000E11sd00000085*
- ID_MODEL_FROM_DATABASE=NC7780 Gigabit Server Adapter (embedded, WOL)
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5701 Gigabit Ethernet (NC7780 Gigabit Server Adapter (embedded, WOL))
 
 pci:v000014E4d00001645sv00000E11sd00000099*
- ID_MODEL_FROM_DATABASE=NC7780 Gigabit Server Adapter (embedded, WOL)
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5701 Gigabit Ethernet (NC7780 Gigabit Server Adapter (embedded, WOL))
 
 pci:v000014E4d00001645sv00000E11sd0000009A*
- ID_MODEL_FROM_DATABASE=NC7770 Gigabit Server Adapter (PCI-X, 10/100/1000-T)
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5701 Gigabit Ethernet (NC7770 Gigabit Server Adapter (PCI-X, 10/100/1000-T))
 
 pci:v000014E4d00001645sv00000E11sd000000C1*
- ID_MODEL_FROM_DATABASE=NC6770 Gigabit Server Adapter (PCI-X, 1000-SX)
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5701 Gigabit Ethernet (NC6770 Gigabit Server Adapter (PCI-X, 1000-SX))
 
 pci:v000014E4d00001645sv00001028sd00000121*
- ID_MODEL_FROM_DATABASE=Broadcom BCM5701 1000Base-T
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5701 Gigabit Ethernet (Broadcom BCM5701 1000Base-T)
 
 pci:v000014E4d00001645sv0000103Csd0000128A*
- ID_MODEL_FROM_DATABASE=BCM5701 1000Base-T (HP, OEM 3COM)
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5701 Gigabit Ethernet (BCM5701 1000Base-T (HP, OEM 3COM))
 
 pci:v000014E4d00001645sv0000103Csd0000128B*
- ID_MODEL_FROM_DATABASE=1000Base-SX (PCI) [A7073A]
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5701 Gigabit Ethernet (1000Base-SX (PCI) [A7073A])
 
 pci:v000014E4d00001645sv0000103Csd000012A4*
- ID_MODEL_FROM_DATABASE=Core Lan 1000Base-T
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5701 Gigabit Ethernet (Core Lan 1000Base-T)
 
 pci:v000014E4d00001645sv0000103Csd000012C1*
- ID_MODEL_FROM_DATABASE=IOX Core Lan 1000Base-T [A7109AX]
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5701 Gigabit Ethernet (IOX Core Lan 1000Base-T [A7109AX])
 
 pci:v000014E4d00001645sv0000103Csd00001300*
- ID_MODEL_FROM_DATABASE=Core LAN/SCSI Combo [A6794A]
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5701 Gigabit Ethernet (Core LAN/SCSI Combo [A6794A])
 
 pci:v000014E4d00001645sv000010A9sd00008010*
- ID_MODEL_FROM_DATABASE=IO9/IO10 Gigabit Ethernet (Copper)
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5701 Gigabit Ethernet (IO9/IO10 Gigabit Ethernet (Copper))
 
 pci:v000014E4d00001645sv000010A9sd00008011*
- ID_MODEL_FROM_DATABASE=Gigabit Ethernet (Copper)
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5701 Gigabit Ethernet (Gigabit Ethernet (Copper))
 
 pci:v000014E4d00001645sv000010A9sd00008012*
- ID_MODEL_FROM_DATABASE=Gigabit Ethernet (Fiber)
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5701 Gigabit Ethernet (Gigabit Ethernet (Fiber))
 
 pci:v000014E4d00001645sv000010B7sd00001004*
- ID_MODEL_FROM_DATABASE=3C996-SX 1000Base-SX
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5701 Gigabit Ethernet (3C996-SX 1000Base-SX)
 
 pci:v000014E4d00001645sv000010B7sd00001006*
- ID_MODEL_FROM_DATABASE=3C996B-T 1000Base-T
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5701 Gigabit Ethernet (3C996B-T 1000Base-T)
 
 pci:v000014E4d00001645sv000010B7sd00001007*
- ID_MODEL_FROM_DATABASE=3C1000-T 1000Base-T
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5701 Gigabit Ethernet (3C1000-T 1000Base-T)
 
 pci:v000014E4d00001645sv000010B7sd00001008*
- ID_MODEL_FROM_DATABASE=3C940-BR01 1000Base-T
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5701 Gigabit Ethernet (3C940-BR01 1000Base-T)
 
 pci:v000014E4d00001645sv000014E4sd00000001*
- ID_MODEL_FROM_DATABASE=BCM5701 1000Base-T
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5701 Gigabit Ethernet (BCM5701 1000Base-T)
 
 pci:v000014E4d00001645sv000014E4sd00000005*
- ID_MODEL_FROM_DATABASE=BCM5701 1000Base-T
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5701 Gigabit Ethernet (BCM5701 1000Base-T)
 
 pci:v000014E4d00001645sv000014E4sd00000006*
- ID_MODEL_FROM_DATABASE=BCM5701 1000Base-T
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5701 Gigabit Ethernet (BCM5701 1000Base-T)
 
 pci:v000014E4d00001645sv000014E4sd00000007*
- ID_MODEL_FROM_DATABASE=BCM5701 1000Base-SX
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5701 Gigabit Ethernet (BCM5701 1000Base-SX)
 
 pci:v000014E4d00001645sv000014E4sd00000008*
- ID_MODEL_FROM_DATABASE=BCM5701 1000Base-T
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5701 Gigabit Ethernet (BCM5701 1000Base-T)
 
 pci:v000014E4d00001645sv000014E4sd00001645*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM5701 Gigabit Ethernet
 
 pci:v000014E4d00001645sv000014E4sd00008008*
- ID_MODEL_FROM_DATABASE=BCM5701 1000Base-T
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5701 Gigabit Ethernet (BCM5701 1000Base-T)
 
 pci:v000014E4d00001646*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM5702 Gigabit Ethernet
 
 pci:v000014E4d00001646sv00000E11sd000000BB*
- ID_MODEL_FROM_DATABASE=NC7760 1000BaseTX
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5702 Gigabit Ethernet (NC7760 1000BaseTX)
 
 pci:v000014E4d00001646sv00001028sd00000126*
- ID_MODEL_FROM_DATABASE=Broadcom BCM5702 1000BaseTX
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5702 Gigabit Ethernet (Broadcom BCM5702 1000BaseTX)
 
 pci:v000014E4d00001646sv000014E4sd00008009*
- ID_MODEL_FROM_DATABASE=BCM5702 1000BaseTX
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5702 Gigabit Ethernet (BCM5702 1000BaseTX)
 
 pci:v000014E4d00001647*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM5703 Gigabit Ethernet
 
 pci:v000014E4d00001647sv00000E11sd00000099*
- ID_MODEL_FROM_DATABASE=NC7780 1000BaseTX
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5703 Gigabit Ethernet (NC7780 1000BaseTX)
 
 pci:v000014E4d00001647sv00000E11sd0000009A*
- ID_MODEL_FROM_DATABASE=NC7770 1000BaseTX
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5703 Gigabit Ethernet (NC7770 1000BaseTX)
 
 pci:v000014E4d00001647sv000010A9sd00008010*
- ID_MODEL_FROM_DATABASE=SGI IO9 Gigabit Ethernet (Copper)
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5703 Gigabit Ethernet (SGI IO9 Gigabit Ethernet (Copper))
 
 pci:v000014E4d00001647sv000014E4sd00000009*
- ID_MODEL_FROM_DATABASE=BCM5703 1000BaseTX
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5703 Gigabit Ethernet (BCM5703 1000BaseTX)
 
 pci:v000014E4d00001647sv000014E4sd0000000A*
- ID_MODEL_FROM_DATABASE=BCM5703 1000BaseSX
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5703 Gigabit Ethernet (BCM5703 1000BaseSX)
 
 pci:v000014E4d00001647sv000014E4sd0000000B*
- ID_MODEL_FROM_DATABASE=BCM5703 1000BaseTX
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5703 Gigabit Ethernet (BCM5703 1000BaseTX)
 
 pci:v000014E4d00001647sv000014E4sd00008009*
- ID_MODEL_FROM_DATABASE=BCM5703 1000BaseTX
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5703 Gigabit Ethernet (BCM5703 1000BaseTX)
 
 pci:v000014E4d00001647sv000014E4sd0000800A*
- ID_MODEL_FROM_DATABASE=BCM5703 1000BaseTX
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5703 Gigabit Ethernet (BCM5703 1000BaseTX)
 
 pci:v000014E4d00001648*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM5704 Gigabit Ethernet
 
 pci:v000014E4d00001648sv00000E11sd000000CF*
- ID_MODEL_FROM_DATABASE=NC7772 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5704 Gigabit Ethernet (NC7772 Gigabit Server Adapter (PCI-X, 10,100,1000-T))
 
 pci:v000014E4d00001648sv00000E11sd000000D0*
- ID_MODEL_FROM_DATABASE=NC7782 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5704 Gigabit Ethernet (NC7782 Gigabit Server Adapter (PCI-X, 10,100,1000-T))
 
 pci:v000014E4d00001648sv00000E11sd000000D1*
- ID_MODEL_FROM_DATABASE=NC7783 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5704 Gigabit Ethernet (NC7783 Gigabit Server Adapter (PCI-X, 10,100,1000-T))
 
 pci:v000014E4d00001648sv00001028sd0000014A*
- ID_MODEL_FROM_DATABASE=PowerEdge 1750
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5704 Gigabit Ethernet (PowerEdge 1750)
 
 pci:v000014E4d00001648sv00001028sd00000170*
- ID_MODEL_FROM_DATABASE=PowerEdge 6850 Broadcom NetXtreme BCM5704
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5704 Gigabit Ethernet (PowerEdge 6850 Broadcom NetXtreme BCM5704)
 
 pci:v000014E4d00001648sv0000103Csd0000310F*
- ID_MODEL_FROM_DATABASE=NC7782 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5704 Gigabit Ethernet (NC7782 Gigabit Server Adapter (PCI-X, 10,100,1000-T))
 
 pci:v000014E4d00001648sv000010A9sd00008013*
- ID_MODEL_FROM_DATABASE=Dual Port Gigabit Ethernet (PCI-X,Copper)
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5704 Gigabit Ethernet (Dual Port Gigabit Ethernet (PCI-X,Copper))
 
 pci:v000014E4d00001648sv000010A9sd00008018*
- ID_MODEL_FROM_DATABASE=Dual Port Gigabit Ethernet (A330)
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5704 Gigabit Ethernet (Dual Port Gigabit Ethernet (A330))
 
 pci:v000014E4d00001648sv000010A9sd0000801A*
- ID_MODEL_FROM_DATABASE=Dual Port Gigabit Ethernet (IA-blade)
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5704 Gigabit Ethernet (Dual Port Gigabit Ethernet (IA-blade))
 
 pci:v000014E4d00001648sv000010A9sd0000801B*
- ID_MODEL_FROM_DATABASE=Quad Port Gigabit Ethernet (PCI-E,Copper)
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5704 Gigabit Ethernet (Quad Port Gigabit Ethernet (PCI-E,Copper))
 
 pci:v000014E4d00001648sv000010B7sd00002000*
- ID_MODEL_FROM_DATABASE=3C998-T Dual Port 10/100/1000 PCI-X
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5704 Gigabit Ethernet (3C998-T Dual Port 10/100/1000 PCI-X)
 
 pci:v000014E4d00001648sv000010B7sd00003000*
- ID_MODEL_FROM_DATABASE=3C999-T Quad Port 10/100/1000 PCI-X
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5704 Gigabit Ethernet (3C999-T Quad Port 10/100/1000 PCI-X)
 
 pci:v000014E4d00001648sv00001166sd00001648*
- ID_MODEL_FROM_DATABASE=NetXtreme CIOB-E 1000Base-T
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5704 Gigabit Ethernet (NetXtreme CIOB-E 1000Base-T)
 
 pci:v000014E4d00001648sv00001734sd0000100B*
- ID_MODEL_FROM_DATABASE=PRIMERGY RX/TX series onboard LAN
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5704 Gigabit Ethernet (PRIMERGY RX/TX series onboard LAN)
 
 pci:v000014E4d00001649*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM5704S_2 Gigabit Ethernet
@@ -43479,46 +44613,46 @@ pci:v000014E4d0000164A*
  ID_MODEL_FROM_DATABASE=NetXtreme II BCM5706 Gigabit Ethernet
 
 pci:v000014E4d0000164Asv0000103Csd00001709*
- ID_MODEL_FROM_DATABASE=NC371i Integrated PCI-X Multifunction Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM5706 Gigabit Ethernet (NC371i Integrated PCI-X Multifunction Gigabit Server Adapter)
 
 pci:v000014E4d0000164Asv0000103Csd00003070*
- ID_MODEL_FROM_DATABASE=NC380T PCI Express Dual Port Multifunction Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM5706 Gigabit Ethernet (NC380T PCI Express Dual Port Multifunction Gigabit Server Adapter)
 
 pci:v000014E4d0000164Asv0000103Csd00003101*
- ID_MODEL_FROM_DATABASE=NC370T MultifuNCtion Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM5706 Gigabit Ethernet (NC370T MultifuNCtion Gigabit Server Adapter)
 
 pci:v000014E4d0000164Asv0000103Csd00003106*
- ID_MODEL_FROM_DATABASE=NC370i Multifunction Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM5706 Gigabit Ethernet (NC370i Multifunction Gigabit Server Adapter)
 
 pci:v000014E4d0000164C*
  ID_MODEL_FROM_DATABASE=NetXtreme II BCM5708 Gigabit Ethernet
 
 pci:v000014E4d0000164Csv00001028sd000001F0*
- ID_MODEL_FROM_DATABASE=PowerEdge R900 Broadcom NetXtreme II BCM5708
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM5708 Gigabit Ethernet (PowerEdge R900 Broadcom NetXtreme II BCM5708)
 
 pci:v000014E4d0000164Csv00001028sd00000205*
- ID_MODEL_FROM_DATABASE=PowerEdge 2970 Broadcom NetXtreme II BCM5708
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM5708 Gigabit Ethernet (PowerEdge 2970 Broadcom NetXtreme II BCM5708)
 
 pci:v000014E4d0000164Csv00001028sd0000020B*
- ID_MODEL_FROM_DATABASE=PowerEdge T605 Broadcom NetXtreme II BCM5708
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM5708 Gigabit Ethernet (PowerEdge T605 Broadcom NetXtreme II BCM5708)
 
 pci:v000014E4d0000164Csv00001028sd00000221*
- ID_MODEL_FROM_DATABASE=PowerEdge R805 Broadcom NetXtreme II BCM5708
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM5708 Gigabit Ethernet (PowerEdge R805 Broadcom NetXtreme II BCM5708)
 
 pci:v000014E4d0000164Csv00001028sd00000223*
- ID_MODEL_FROM_DATABASE=PowerEdge R905 Broadcom NetXtreme II BCM5708
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM5708 Gigabit Ethernet (PowerEdge R905 Broadcom NetXtreme II BCM5708)
 
 pci:v000014E4d0000164Csv00001028sd00001F12*
- ID_MODEL_FROM_DATABASE=PowerEdge R805/R905 Broadcom NetXtreme II BCM5708
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM5708 Gigabit Ethernet (PowerEdge R805/R905 Broadcom NetXtreme II BCM5708)
 
 pci:v000014E4d0000164Csv0000103Csd00007037*
- ID_MODEL_FROM_DATABASE=NC373T PCI Express Multifunction Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM5708 Gigabit Ethernet (NC373T PCI Express Multifunction Gigabit Server Adapter)
 
 pci:v000014E4d0000164Csv0000103Csd00007038*
- ID_MODEL_FROM_DATABASE=NC373i Integrated Multifunction Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM5708 Gigabit Ethernet (NC373i Integrated Multifunction Gigabit Server Adapter)
 
 pci:v000014E4d0000164Csv0000103Csd00007045*
- ID_MODEL_FROM_DATABASE=NC374m PCI Express Dual Port Multifunction Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM5708 Gigabit Ethernet (NC374m PCI Express Dual Port Multifunction Gigabit Server Adapter)
 
 pci:v000014E4d0000164D*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM5702FE Gigabit Ethernet
@@ -43527,10 +44661,10 @@ pci:v000014E4d0000164E*
  ID_MODEL_FROM_DATABASE=NetXtreme II BCM57710 10-Gigabit PCIe [Everest]
 
 pci:v000014E4d0000164Esv0000103Csd0000171C*
- ID_MODEL_FROM_DATABASE=NC532m Dual Port 10GbE Multifunction BL-C Adapter
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57710 10-Gigabit PCIe [Everest] (NC532m Dual Port 10GbE Multifunction BL-C Adapter)
 
 pci:v000014E4d0000164Esv0000103Csd00007058*
- ID_MODEL_FROM_DATABASE=NC532i Dual Port 10GbE Multifunction BL-C Adapter
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57710 10-Gigabit PCIe [Everest] (NC532i Dual Port 10GbE Multifunction BL-C Adapter)
 
 pci:v000014E4d0000164F*
  ID_MODEL_FROM_DATABASE=NetXtreme II BCM57711 10-Gigabit PCIe
@@ -43539,31 +44673,31 @@ pci:v000014E4d00001650*
  ID_MODEL_FROM_DATABASE=NetXtreme II BCM57711E 10-Gigabit PCIe
 
 pci:v000014E4d00001650sv0000103Csd0000171C*
- ID_MODEL_FROM_DATABASE=NC532m Dual Port 10GbE Multifunction BL-C Adapter
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57711E 10-Gigabit PCIe (NC532m Dual Port 10GbE Multifunction BL-C Adapter)
 
 pci:v000014E4d00001650sv0000103Csd00007058*
- ID_MODEL_FROM_DATABASE=NC532i Dual Port 10GbE Multifunction BL-C Adapter
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57711E 10-Gigabit PCIe (NC532i Dual Port 10GbE Multifunction BL-C Adapter)
 
 pci:v000014E4d00001653*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM5705 Gigabit Ethernet
 
 pci:v000014E4d00001653sv00000E11sd000000E3*
- ID_MODEL_FROM_DATABASE=NC7761 Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5705 Gigabit Ethernet (NC7761 Gigabit Server Adapter)
 
 pci:v000014E4d00001653sv00001734sd00001073*
- ID_MODEL_FROM_DATABASE=Primergy Econel 200 D2020 mainboard
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5705 Gigabit Ethernet (Primergy Econel 200 D2020 mainboard)
 
 pci:v000014E4d00001654*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM5705_2 Gigabit Ethernet
 
 pci:v000014E4d00001654sv00000E11sd000000E3*
- ID_MODEL_FROM_DATABASE=NC7761 Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5705_2 Gigabit Ethernet (NC7761 Gigabit Server Adapter)
 
 pci:v000014E4d00001654sv0000103Csd00003100*
- ID_MODEL_FROM_DATABASE=NC1020 ProLiant Gigabit Server Adapter 32 PCI
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5705_2 Gigabit Ethernet (NC1020 ProLiant Gigabit Server Adapter 32 PCI)
 
 pci:v000014E4d00001654sv0000103Csd00003226*
- ID_MODEL_FROM_DATABASE=NC150T 4-port Gigabit Combo Switch & Adapter
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5705_2 Gigabit Ethernet (NC150T 4-port Gigabit Combo Switch & Adapter)
 
 pci:v000014E4d00001655*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM5717 Gigabit Ethernet PCIe
@@ -43578,52 +44712,52 @@ pci:v000014E4d00001659*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM5721 Gigabit Ethernet PCI Express
 
 pci:v000014E4d00001659sv00001014sd000002C6*
- ID_MODEL_FROM_DATABASE=eServer xSeries server mainboard
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5721 Gigabit Ethernet PCI Express (eServer xSeries server mainboard)
 
 pci:v000014E4d00001659sv00001028sd000001E6*
- ID_MODEL_FROM_DATABASE=PowerEdge 860
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5721 Gigabit Ethernet PCI Express (PowerEdge 860)
 
 pci:v000014E4d00001659sv00001028sd0000023C*
- ID_MODEL_FROM_DATABASE=PowerEdge R200 Broadcom NetXtreme BCM5721
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5721 Gigabit Ethernet PCI Express (PowerEdge R200 Broadcom NetXtreme BCM5721)
 
 pci:v000014E4d00001659sv0000103Csd0000170B*
- ID_MODEL_FROM_DATABASE=NC320m PCI Express Dual Port Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5721 Gigabit Ethernet PCI Express (NC320m PCI Express Dual Port Gigabit Server Adapter)
 
 pci:v000014E4d00001659sv0000103Csd00007031*
- ID_MODEL_FROM_DATABASE=NC320T PCIe Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5721 Gigabit Ethernet PCI Express (NC320T PCIe Gigabit Server Adapter)
 
 pci:v000014E4d00001659sv0000103Csd00007032*
- ID_MODEL_FROM_DATABASE=NC320i PCIe Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5721 Gigabit Ethernet PCI Express (NC320i PCIe Gigabit Server Adapter)
 
 pci:v000014E4d00001659sv00001734sd00001061*
- ID_MODEL_FROM_DATABASE=PRIMERGY RX/TX S2 series onboard LAN
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5721 Gigabit Ethernet PCI Express (PRIMERGY RX/TX S2 series onboard LAN)
 
 pci:v000014E4d0000165A*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM5722 Gigabit Ethernet PCI Express
 
 pci:v000014E4d0000165Asv00001014sd00000378*
- ID_MODEL_FROM_DATABASE=IBM System x3350 (Machine type 4192)
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5722 Gigabit Ethernet PCI Express (IBM System x3350 (Machine type 4192))
 
 pci:v000014E4d0000165Asv00001028sd0000020F*
- ID_MODEL_FROM_DATABASE=PowerEdge R300 Broadcom NetXtreme 5722
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5722 Gigabit Ethernet PCI Express (PowerEdge R300 Broadcom NetXtreme 5722)
 
 pci:v000014E4d0000165Asv00001028sd00000210*
- ID_MODEL_FROM_DATABASE=PowerEdge T300 Broadcom NetXtreme 5722
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5722 Gigabit Ethernet PCI Express (PowerEdge T300 Broadcom NetXtreme 5722)
 
 pci:v000014E4d0000165Asv00001028sd00000225*
- ID_MODEL_FROM_DATABASE=PowerEdge T105 Broadcom NetXtreme 5722
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5722 Gigabit Ethernet PCI Express (PowerEdge T105 Broadcom NetXtreme 5722)
 
 pci:v000014E4d0000165Asv0000103Csd00007051*
- ID_MODEL_FROM_DATABASE=NC105i PCIe Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5722 Gigabit Ethernet PCI Express (NC105i PCIe Gigabit Server Adapter)
 
 pci:v000014E4d0000165Asv0000103Csd00007052*
- ID_MODEL_FROM_DATABASE=NC105T PCIe Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5722 Gigabit Ethernet PCI Express (NC105T PCIe Gigabit Server Adapter)
 
 pci:v000014E4d0000165B*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM5723 Gigabit Ethernet PCIe
 
 pci:v000014E4d0000165Bsv0000103Csd0000705D*
- ID_MODEL_FROM_DATABASE=NC107i Integrated PCI Express Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5723 Gigabit Ethernet PCIe (NC107i Integrated PCI Express Gigabit Server Adapter)
 
 pci:v000014E4d0000165C*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM5724 Gigabit Ethernet PCIe
@@ -43632,25 +44766,25 @@ pci:v000014E4d0000165D*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM5705M Gigabit Ethernet
 
 pci:v000014E4d0000165Dsv00001028sd0000865D*
- ID_MODEL_FROM_DATABASE=Latitude D400
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5705M Gigabit Ethernet (Latitude D400)
 
 pci:v000014E4d0000165Dsv000014E4sd0000165D*
- ID_MODEL_FROM_DATABASE=Dell Latitude D600
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5705M Gigabit Ethernet (Dell Latitude D600)
 
 pci:v000014E4d0000165E*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM5705M_2 Gigabit Ethernet
 
 pci:v000014E4d0000165Esv0000103Csd0000088C*
- ID_MODEL_FROM_DATABASE=NC8000 laptop
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5705M_2 Gigabit Ethernet (NC8000 laptop)
 
 pci:v000014E4d0000165Esv0000103Csd00000890*
- ID_MODEL_FROM_DATABASE=NC6000 laptop
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5705M_2 Gigabit Ethernet (NC6000 laptop)
 
 pci:v000014E4d0000165Esv0000103Csd0000099C*
- ID_MODEL_FROM_DATABASE=NX6110/NC6120
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5705M_2 Gigabit Ethernet (NX6110/NC6120)
 
 pci:v000014E4d0000165Esv000010CFsd00001279*
- ID_MODEL_FROM_DATABASE=LifeBook E8010D
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5705M_2 Gigabit Ethernet (LifeBook E8010D)
 
 pci:v000014E4d0000165F*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM5720 Gigabit Ethernet PCIe
@@ -43668,7 +44802,7 @@ pci:v000014E4d00001668*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM5714 Gigabit Ethernet
 
 pci:v000014E4d00001668sv0000103Csd00007039*
- ID_MODEL_FROM_DATABASE=NC324i PCIe Dual Port Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5714 Gigabit Ethernet (NC324i PCIe Dual Port Gigabit Server Adapter)
 
 pci:v000014E4d00001669*
  ID_MODEL_FROM_DATABASE=NetXtreme 5714S Gigabit Ethernet
@@ -43677,7 +44811,7 @@ pci:v000014E4d0000166A*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM5780 Gigabit Ethernet
 
 pci:v000014E4d0000166Asv0000103Csd00007035*
- ID_MODEL_FROM_DATABASE=NC325i Integrated Dual port PCIe Express Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5780 Gigabit Ethernet (NC325i Integrated Dual port PCIe Express Gigabit Server Adapter)
 
 pci:v000014E4d0000166B*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM5780S Gigabit Ethernet
@@ -43701,91 +44835,91 @@ pci:v000014E4d00001677*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM5751 Gigabit Ethernet PCI Express
 
 pci:v000014E4d00001677sv00001028sd00000176*
- ID_MODEL_FROM_DATABASE=Dimension XPS Gen 4
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5751 Gigabit Ethernet PCI Express (Dimension XPS Gen 4)
 
 pci:v000014E4d00001677sv00001028sd00000177*
- ID_MODEL_FROM_DATABASE=Dimension 8400
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5751 Gigabit Ethernet PCI Express (Dimension 8400)
 
 pci:v000014E4d00001677sv00001028sd00000179*
- ID_MODEL_FROM_DATABASE=Optiplex GX280
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5751 Gigabit Ethernet PCI Express (Optiplex GX280)
 
 pci:v000014E4d00001677sv00001028sd00000182*
- ID_MODEL_FROM_DATABASE=Latitude D610
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5751 Gigabit Ethernet PCI Express (Latitude D610)
 
 pci:v000014E4d00001677sv00001028sd00000187*
- ID_MODEL_FROM_DATABASE=Precision M70
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5751 Gigabit Ethernet PCI Express (Precision M70)
 
 pci:v000014E4d00001677sv00001028sd000001A8*
- ID_MODEL_FROM_DATABASE=Precision 380
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5751 Gigabit Ethernet PCI Express (Precision 380)
 
 pci:v000014E4d00001677sv00001028sd000001AD*
- ID_MODEL_FROM_DATABASE=OptiPlex GX620
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5751 Gigabit Ethernet PCI Express (OptiPlex GX620)
 
 pci:v000014E4d00001677sv0000103Csd00003006*
- ID_MODEL_FROM_DATABASE=DC7100 SFF(DX878AV)
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5751 Gigabit Ethernet PCI Express (DC7100 SFF(DX878AV))
 
 pci:v000014E4d00001677sv00001462sd0000028C*
- ID_MODEL_FROM_DATABASE=915P/G Neo2
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5751 Gigabit Ethernet PCI Express (915P/G Neo2)
 
 pci:v000014E4d00001677sv00001734sd0000105D*
- ID_MODEL_FROM_DATABASE=Scenic W620
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5751 Gigabit Ethernet PCI Express (Scenic W620)
 
 pci:v000014E4d00001678*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM5715 Gigabit Ethernet
 
 pci:v000014E4d00001678sv0000103Csd0000703E*
- ID_MODEL_FROM_DATABASE=NC326i PCIe Dual Port Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5715 Gigabit Ethernet (NC326i PCIe Dual Port Gigabit Server Adapter)
 
 pci:v000014E4d00001679*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM5715S Gigabit Ethernet
 
 pci:v000014E4d00001679sv0000103Csd00001707*
- ID_MODEL_FROM_DATABASE=NC326m PCIe Dual Port Adapter
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5715S Gigabit Ethernet (NC326m PCIe Dual Port Adapter)
 
 pci:v000014E4d00001679sv0000103Csd0000170C*
- ID_MODEL_FROM_DATABASE=NC325m PCIe Quad Port Adapter
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5715S Gigabit Ethernet (NC325m PCIe Quad Port Adapter)
 
 pci:v000014E4d00001679sv0000103Csd0000703C*
- ID_MODEL_FROM_DATABASE=NC326i PCIe Dual Port Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5715S Gigabit Ethernet (NC326i PCIe Dual Port Gigabit Server Adapter)
 
 pci:v000014E4d0000167A*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM5754 Gigabit Ethernet PCI Express
 
 pci:v000014E4d0000167Asv00001028sd000001DA*
- ID_MODEL_FROM_DATABASE=OptiPlex 745
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5754 Gigabit Ethernet PCI Express (OptiPlex 745)
 
 pci:v000014E4d0000167Asv00001028sd000001DE*
- ID_MODEL_FROM_DATABASE=Precision 390
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5754 Gigabit Ethernet PCI Express (Precision 390)
 
 pci:v000014E4d0000167Asv00001028sd000001DF*
- ID_MODEL_FROM_DATABASE=PowerEdge SC440
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5754 Gigabit Ethernet PCI Express (PowerEdge SC440)
 
 pci:v000014E4d0000167Asv00001028sd00000214*
- ID_MODEL_FROM_DATABASE=Precision T3400
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5754 Gigabit Ethernet PCI Express (Precision T3400)
 
 pci:v000014E4d0000167Asv00001028sd0000021E*
- ID_MODEL_FROM_DATABASE=Precision T5400
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5754 Gigabit Ethernet PCI Express (Precision T5400)
 
 pci:v000014E4d0000167B*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM5755 Gigabit Ethernet PCI Express
 
 pci:v000014E4d0000167Bsv0000103Csd0000280A*
- ID_MODEL_FROM_DATABASE=DC5750 Microtower
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5755 Gigabit Ethernet PCI Express (DC5750 Microtower)
 
 pci:v000014E4d0000167D*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM5751M Gigabit Ethernet PCI Express
 
 pci:v000014E4d0000167Dsv00001014sd00000577*
- ID_MODEL_FROM_DATABASE=ThinkPad Z60t
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5751M Gigabit Ethernet PCI Express (ThinkPad Z60t)
 
 pci:v000014E4d0000167Dsv0000103Csd00000934*
- ID_MODEL_FROM_DATABASE=HP nx8220
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5751M Gigabit Ethernet PCI Express (HP nx8220)
 
 pci:v000014E4d0000167Dsv0000103Csd00000940*
- ID_MODEL_FROM_DATABASE=HP Compaq nw8240 Mobile Workstation
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5751M Gigabit Ethernet PCI Express (HP Compaq nw8240 Mobile Workstation)
 
 pci:v000014E4d0000167Dsv000017AAsd00002081*
- ID_MODEL_FROM_DATABASE=ThinkPad R60e
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5751M Gigabit Ethernet PCI Express (ThinkPad R60e)
 
 pci:v000014E4d0000167E*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM5751F Fast Ethernet PCI Express
@@ -43821,22 +44955,22 @@ pci:v000014E4d00001688*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM5761 10/100/1000BASE-T Ethernet
 
 pci:v000014E4d00001688sv00001259sd00002708*
- ID_MODEL_FROM_DATABASE=AT-2712 FX
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5761 10/100/1000BASE-T Ethernet (AT-2712 FX)
 
 pci:v000014E4d0000168A*
  ID_MODEL_FROM_DATABASE=NetXtreme II BCM57800 1/10 Gigabit Ethernet
 
 pci:v000014E4d0000168Asv00001028sd00001F5C*
- ID_MODEL_FROM_DATABASE=BCM57800 10-Gigabit Ethernet
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57800 1/10 Gigabit Ethernet (BCM57800 10-Gigabit Ethernet)
 
 pci:v000014E4d0000168Asv00001028sd00001F5D*
- ID_MODEL_FROM_DATABASE=BCM57800 10-Gigabit Ethernet
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57800 1/10 Gigabit Ethernet (BCM57800 10-Gigabit Ethernet)
 
 pci:v000014E4d0000168Asv00001028sd00001F67*
- ID_MODEL_FROM_DATABASE=BCM57800 1-Gigabit Ethernet
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57800 1/10 Gigabit Ethernet (BCM57800 1-Gigabit Ethernet)
 
 pci:v000014E4d0000168Asv00001028sd00001F68*
- ID_MODEL_FROM_DATABASE=BCM57800 1-Gigabit Ethernet
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57800 1/10 Gigabit Ethernet (BCM57800 1-Gigabit Ethernet)
 
 pci:v000014E4d0000168D*
  ID_MODEL_FROM_DATABASE=NetXtreme II BCM57840 10/20 Gigabit Ethernet
@@ -43845,7 +44979,34 @@ pci:v000014E4d0000168E*
  ID_MODEL_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet
 
 pci:v000014E4d0000168Esv0000103Csd00001798*
- ID_MODEL_FROM_DATABASE=Flex-10 10Gb 2-port 530FLB Adapter [Meru]
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet (Flex-10 10Gb 2-port 530FLB Adapter [Meru])
+
+pci:v000014E4d0000168Esv0000103Csd000017A5*
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet (HP Flex-10 10Gb 2-port 530M Adapter)
+
+pci:v000014E4d0000168Esv0000103Csd000018D3*
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet (HP Ethernet 10Gb 2-port 530T Adapter)
+
+pci:v000014E4d0000168Esv0000103Csd00001930*
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet (HP FlexFabric 10Gb 2-port 534FLR-SFP+ Adapter)
+
+pci:v000014E4d0000168Esv0000103Csd00001931*
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet (HP StoreFabric CN1100R Dual Port Converged Network Adapter)
+
+pci:v000014E4d0000168Esv0000103Csd00001932*
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet (HP FlexFabric 10Gb 2-port 534FLB Adapter)
+
+pci:v000014E4d0000168Esv0000103Csd00001933*
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet (HP FlexFabric 10Gb 2-port 534M Adapter)
+
+pci:v000014E4d0000168Esv0000103Csd0000193A*
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet (HP FlexFabric 10Gb 2-port 533FLR-T Adapter)
+
+pci:v000014E4d0000168Esv0000103Csd00003382*
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet (HP Ethernet 10Gb 2-port 530FLR-SFP+ Adapter)
+
+pci:v000014E4d0000168Esv0000103Csd0000339D*
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet (HP Ethernet 10Gb 2-port 530SFP+ Adapter)
 
 pci:v000014E4d00001690*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM57760 Gigabit Ethernet PCIe
@@ -43854,22 +45015,22 @@ pci:v000014E4d00001691*
  ID_MODEL_FROM_DATABASE=NetLink BCM57788 Gigabit Ethernet PCIe
 
 pci:v000014E4d00001691sv00001028sd000004AA*
- ID_MODEL_FROM_DATABASE=XPS 8300
+ ID_MODEL_FROM_DATABASE=NetLink BCM57788 Gigabit Ethernet PCIe (XPS 8300)
 
 pci:v000014E4d00001692*
  ID_MODEL_FROM_DATABASE=NetLink BCM57780 Gigabit Ethernet PCIe
 
 pci:v000014E4d00001692sv00001025sd0000033D*
- ID_MODEL_FROM_DATABASE=Aspire 7740G
+ ID_MODEL_FROM_DATABASE=NetLink BCM57780 Gigabit Ethernet PCIe (Aspire 7740G)
 
 pci:v000014E4d00001693*
  ID_MODEL_FROM_DATABASE=NetLink BCM5787M Gigabit Ethernet PCI Express
 
 pci:v000014E4d00001693sv00001025sd00000121*
- ID_MODEL_FROM_DATABASE=Aspire 5920G
+ ID_MODEL_FROM_DATABASE=NetLink BCM5787M Gigabit Ethernet PCI Express (Aspire 5920G)
 
 pci:v000014E4d00001693sv0000103Csd000030C0*
- ID_MODEL_FROM_DATABASE=6710b
+ ID_MODEL_FROM_DATABASE=NetLink BCM5787M Gigabit Ethernet PCI Express (6710b)
 
 pci:v000014E4d00001694*
  ID_MODEL_FROM_DATABASE=NetLink BCM57790 Gigabit Ethernet PCIe
@@ -43878,10 +45039,10 @@ pci:v000014E4d00001696*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM5782 Gigabit Ethernet
 
 pci:v000014E4d00001696sv0000103Csd000012BC*
- ID_MODEL_FROM_DATABASE=d530 CMT (DG746A)
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5782 Gigabit Ethernet (d530 CMT (DG746A))
 
 pci:v000014E4d00001696sv000014E4sd0000000D*
- ID_MODEL_FROM_DATABASE=NetXtreme BCM5782 1000Base-T
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5782 Gigabit Ethernet (NetXtreme BCM5782 1000Base-T)
 
 pci:v000014E4d00001698*
  ID_MODEL_FROM_DATABASE=NetLink BCM5784M Gigabit Ethernet PCIe
@@ -43899,16 +45060,16 @@ pci:v000014E4d0000169C*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM5788 Gigabit Ethernet
 
 pci:v000014E4d0000169Csv0000103Csd0000308B*
- ID_MODEL_FROM_DATABASE=MX6125
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5788 Gigabit Ethernet (MX6125)
 
 pci:v000014E4d0000169Csv0000103Csd000030A1*
- ID_MODEL_FROM_DATABASE=NC2400
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5788 Gigabit Ethernet (NC2400)
 
 pci:v000014E4d0000169Csv0000144Dsd0000C018*
- ID_MODEL_FROM_DATABASE=X20
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5788 Gigabit Ethernet (X20)
 
 pci:v000014E4d0000169Csv00001462sd0000590C*
- ID_MODEL_FROM_DATABASE=KT6 Delta-FIS2R (MS-6590)
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5788 Gigabit Ethernet (KT6 Delta-FIS2R (MS-6590))
 
 pci:v000014E4d0000169D*
  ID_MODEL_FROM_DATABASE=NetLink BCM5789 Gigabit Ethernet PCI Express
@@ -43922,101 +45083,116 @@ pci:v000014E4d000016A1*
 pci:v000014E4d000016A2*
  ID_MODEL_FROM_DATABASE=BCM57840 NetXtreme II 10/20-Gigabit Ethernet
 
+pci:v000014E4d000016A2sv0000103Csd00001916*
+ ID_MODEL_FROM_DATABASE=BCM57840 NetXtreme II 10/20-Gigabit Ethernet (HP FlexFabric 20Gb 2-port 630FLB Adapter)
+
+pci:v000014E4d000016A2sv0000103Csd00001917*
+ ID_MODEL_FROM_DATABASE=BCM57840 NetXtreme II 10/20-Gigabit Ethernet (HP FlexFabric 20Gb 2-port 630M Adapter)
+
+pci:v000014E4d000016A3*
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM57786 Gigabit Ethernet PCIe
+
 pci:v000014E4d000016A4*
  ID_MODEL_FROM_DATABASE=BCM57840 NetXtreme II Ethernet Multi Function
 
+pci:v000014E4d000016A4sv0000103Csd00001916*
+ ID_MODEL_FROM_DATABASE=BCM57840 NetXtreme II Ethernet Multi Function (HP NPAR 20Gb 2-port 630FLB Adapter)
+
+pci:v000014E4d000016A4sv0000103Csd00001917*
+ ID_MODEL_FROM_DATABASE=BCM57840 NetXtreme II Ethernet Multi Function (HP NPAR 20Gb 2-port 630M Adapter)
+
 pci:v000014E4d000016A5*
  ID_MODEL_FROM_DATABASE=NetXtreme II BCM57800 1/10 Gigabit Ethernet Multi Function
 
 pci:v000014E4d000016A5sv00001028sd00001F5C*
- ID_MODEL_FROM_DATABASE=NetXtreme II BCM57800 10-Gigabit Ethernet Multi Function
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57800 1/10 Gigabit Ethernet Multi Function (NetXtreme II BCM57800 10-Gigabit Ethernet Multi Function)
 
 pci:v000014E4d000016A5sv00001028sd00001F5D*
- ID_MODEL_FROM_DATABASE=NetXtreme II BCM57800 10-Gigabit Ethernet Multi Function
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57800 1/10 Gigabit Ethernet Multi Function (NetXtreme II BCM57800 10-Gigabit Ethernet Multi Function)
 
 pci:v000014E4d000016A5sv00001028sd00001F67*
- ID_MODEL_FROM_DATABASE=NetXtreme II BCM57800 1-Gigabit Ethernet Multi Function
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57800 1/10 Gigabit Ethernet Multi Function (NetXtreme II BCM57800 1-Gigabit Ethernet Multi Function)
 
 pci:v000014E4d000016A5sv00001028sd00001F68*
- ID_MODEL_FROM_DATABASE=NetXtreme II BCM57800 1-Gigabit Ethernet Multi Function
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57800 1/10 Gigabit Ethernet Multi Function (NetXtreme II BCM57800 1-Gigabit Ethernet Multi Function)
 
 pci:v000014E4d000016A6*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM5702X Gigabit Ethernet
 
 pci:v000014E4d000016A6sv00000E11sd000000BB*
- ID_MODEL_FROM_DATABASE=NC7760 Gigabit Server Adapter (PCI-X, 10/100/1000-T)
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5702X Gigabit Ethernet (NC7760 Gigabit Server Adapter (PCI-X, 10/100/1000-T))
 
 pci:v000014E4d000016A6sv00001028sd00000126*
- ID_MODEL_FROM_DATABASE=BCM5702 1000Base-T
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5702X Gigabit Ethernet (BCM5702 1000Base-T)
 
 pci:v000014E4d000016A6sv000014E4sd0000000C*
- ID_MODEL_FROM_DATABASE=BCM5702 1000Base-T
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5702X Gigabit Ethernet (BCM5702 1000Base-T)
 
 pci:v000014E4d000016A6sv000014E4sd00008009*
- ID_MODEL_FROM_DATABASE=BCM5702 1000Base-T
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5702X Gigabit Ethernet (BCM5702 1000Base-T)
 
 pci:v000014E4d000016A7*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM5703X Gigabit Ethernet
 
 pci:v000014E4d000016A7sv00000E11sd000000CA*
- ID_MODEL_FROM_DATABASE=NC7771 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5703X Gigabit Ethernet (NC7771 Gigabit Server Adapter (PCI-X, 10,100,1000-T))
 
 pci:v000014E4d000016A7sv00000E11sd000000CB*
- ID_MODEL_FROM_DATABASE=NC7781 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5703X Gigabit Ethernet (NC7781 Gigabit Server Adapter (PCI-X, 10,100,1000-T))
 
 pci:v000014E4d000016A7sv00001014sd0000026F*
- ID_MODEL_FROM_DATABASE=eServer xSeries server mainboard
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5703X Gigabit Ethernet (eServer xSeries server mainboard)
 
 pci:v000014E4d000016A7sv000014E4sd00000009*
- ID_MODEL_FROM_DATABASE=NetXtreme BCM5703 1000Base-T
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5703X Gigabit Ethernet (NetXtreme BCM5703 1000Base-T)
 
 pci:v000014E4d000016A7sv000014E4sd0000000A*
- ID_MODEL_FROM_DATABASE=NetXtreme BCM5703 1000Base-SX
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5703X Gigabit Ethernet (NetXtreme BCM5703 1000Base-SX)
 
 pci:v000014E4d000016A7sv000014E4sd0000000B*
- ID_MODEL_FROM_DATABASE=NetXtreme BCM5703 1000Base-T
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5703X Gigabit Ethernet (NetXtreme BCM5703 1000Base-T)
 
 pci:v000014E4d000016A7sv000014E4sd0000800A*
- ID_MODEL_FROM_DATABASE=NetXtreme BCM5703 1000Base-T
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5703X Gigabit Ethernet (NetXtreme BCM5703 1000Base-T)
 
 pci:v000014E4d000016A8*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM5704S Gigabit Ethernet
 
 pci:v000014E4d000016A8sv0000103Csd0000132B*
- ID_MODEL_FROM_DATABASE=PCI-X 1000Mbps Dual-port Built-in
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5704S Gigabit Ethernet (PCI-X 1000Mbps Dual-port Built-in)
 
 pci:v000014E4d000016A8sv000010A9sd00008014*
- ID_MODEL_FROM_DATABASE=Dual Port Gigabit Ethernet (PCI-X,Fiber)
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5704S Gigabit Ethernet (Dual Port Gigabit Ethernet (PCI-X,Fiber))
 
 pci:v000014E4d000016A8sv000010A9sd0000801C*
- ID_MODEL_FROM_DATABASE=Quad Port Gigabit Ethernet (PCI-E,Fiber)
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5704S Gigabit Ethernet (Quad Port Gigabit Ethernet (PCI-E,Fiber))
 
 pci:v000014E4d000016A8sv000010B7sd00002001*
- ID_MODEL_FROM_DATABASE=3C998-SX Dual Port 1000-SX PCI-X
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5704S Gigabit Ethernet (3C998-SX Dual Port 1000-SX PCI-X)
 
 pci:v000014E4d000016A9*
  ID_MODEL_FROM_DATABASE=NetXtreme II BCM57800 1/10 Gigabit Ethernet Virtual Function
 
 pci:v000014E4d000016A9sv00001028sd00001F5C*
- ID_MODEL_FROM_DATABASE=NetXtreme II BCM57800 10-Gigabit Ethernet Virtual Function
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57800 1/10 Gigabit Ethernet Virtual Function (NetXtreme II BCM57800 10-Gigabit Ethernet Virtual Function)
 
 pci:v000014E4d000016A9sv00001028sd00001F5D*
- ID_MODEL_FROM_DATABASE=NetXtreme II BCM57800 10-Gigabit Ethernet Virtual Function
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57800 1/10 Gigabit Ethernet Virtual Function (NetXtreme II BCM57800 10-Gigabit Ethernet Virtual Function)
 
 pci:v000014E4d000016A9sv00001028sd00001F67*
- ID_MODEL_FROM_DATABASE=NetXtreme II BCM57800 1-Gigabit Ethernet Virtual Function
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57800 1/10 Gigabit Ethernet Virtual Function (NetXtreme II BCM57800 1-Gigabit Ethernet Virtual Function)
 
 pci:v000014E4d000016A9sv00001028sd00001F68*
- ID_MODEL_FROM_DATABASE=NetXtreme II BCM57800 1-Gigabit Ethernet Virtual Function
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57800 1/10 Gigabit Ethernet Virtual Function (NetXtreme II BCM57800 1-Gigabit Ethernet Virtual Function)
 
 pci:v000014E4d000016AA*
  ID_MODEL_FROM_DATABASE=NetXtreme II BCM5706S Gigabit Ethernet
 
 pci:v000014E4d000016AAsv0000103Csd00003102*
- ID_MODEL_FROM_DATABASE=NC370F MultifuNCtion Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM5706S Gigabit Ethernet (NC370F MultifuNCtion Gigabit Server Adapter)
 
 pci:v000014E4d000016AAsv0000103Csd0000310C*
- ID_MODEL_FROM_DATABASE=NC370i Multifunction Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM5706S Gigabit Ethernet (NC370i Multifunction Gigabit Server Adapter)
 
 pci:v000014E4d000016AB*
  ID_MODEL_FROM_DATABASE=NetXtreme II BCM57840 10/20 Gigabit Ethernet Multi Function
@@ -44028,32 +45204,98 @@ pci:v000014E4d000016ACsv00001014sd00000304*
  ID_MODEL_FROM_DATABASE=NetXtreme II BCM5708S Gigabit Ethernet
 
 pci:v000014E4d000016ACsv00001028sd000001BB*
- ID_MODEL_FROM_DATABASE=PowerEdge 1955 Broadcom NetXtreme II BCM5708S
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM5708S Gigabit Ethernet (PowerEdge 1955 Broadcom NetXtreme II BCM5708S)
 
 pci:v000014E4d000016ACsv00001028sd0000020C*
- ID_MODEL_FROM_DATABASE=PowerEdge M605 Broadcom NetXtreme II BCM5708S
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM5708S Gigabit Ethernet (PowerEdge M605 Broadcom NetXtreme II BCM5708S)
 
 pci:v000014E4d000016ACsv0000103Csd00001706*
- ID_MODEL_FROM_DATABASE=NC373m Multifunction Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM5708S Gigabit Ethernet (NC373m Multifunction Gigabit Server Adapter)
 
 pci:v000014E4d000016ACsv0000103Csd00007038*
- ID_MODEL_FROM_DATABASE=NC373i PCI Express Multifunction Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM5708S Gigabit Ethernet (NC373i PCI Express Multifunction Gigabit Server Adapter)
 
 pci:v000014E4d000016ACsv0000103Csd0000703B*
- ID_MODEL_FROM_DATABASE=NC373i Integrated Multifunction Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM5708S Gigabit Ethernet (NC373i Integrated Multifunction Gigabit Server Adapter)
 
 pci:v000014E4d000016ACsv0000103Csd0000703D*
- ID_MODEL_FROM_DATABASE=NC373F PCI Express Multifunction Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM5708S Gigabit Ethernet (NC373F PCI Express Multifunction Gigabit Server Adapter)
 
 pci:v000014E4d000016AD*
  ID_MODEL_FROM_DATABASE=NetXtreme II BCM57840 10/20 Gigabit Ethernet Virtual Function
 
+pci:v000014E4d000016ADsv0000103Csd00001916*
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57840 10/20 Gigabit Ethernet Virtual Function (HP FlexFabric 20Gb 2-port 630FLB Adapter)
+
+pci:v000014E4d000016ADsv0000103Csd00001917*
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57840 10/20 Gigabit Ethernet Virtual Function (HP FlexFabric 20Gb 2-port 630M Adapter)
+
 pci:v000014E4d000016AE*
  ID_MODEL_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet Multi Function
 
+pci:v000014E4d000016AEsv0000103Csd00001798*
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet Multi Function (HP NPAR 10Gb 2-port 530FLB Adapter)
+
+pci:v000014E4d000016AEsv0000103Csd000017A5*
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet Multi Function (HP NPAR 10Gb 2-port 530M Adapter)
+
+pci:v000014E4d000016AEsv0000103Csd000018D3*
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet Multi Function (HP NPAR 10Gb 2-port 530T Adapter)
+
+pci:v000014E4d000016AEsv0000103Csd00001930*
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet Multi Function (HP NPAR 10Gb 2-port 534FLR-SFP+ Adapter)
+
+pci:v000014E4d000016AEsv0000103Csd00001931*
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet Multi Function (HP NPAR CN1100R Dual Port Converged Network Adapter)
+
+pci:v000014E4d000016AEsv0000103Csd00001932*
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet Multi Function (HP NPAR 10Gb 2-port 534FLB Adapter)
+
+pci:v000014E4d000016AEsv0000103Csd00001933*
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet Multi Function (HP NPAR 10Gb 2-port 534M Adapter)
+
+pci:v000014E4d000016AEsv0000103Csd0000193A*
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet Multi Function (HP NPAR 10Gb 2-port 533FLR-T Adapter)
+
+pci:v000014E4d000016AEsv0000103Csd00003382*
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet Multi Function (HP NPAR 10Gb 2-port 530FLR-SFP+ Adapter)
+
+pci:v000014E4d000016AEsv0000103Csd0000339D*
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet Multi Function (HP NPAR 10Gb 2-port 530SFP+ Adapter)
+
 pci:v000014E4d000016AF*
  ID_MODEL_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet Virtual Function
 
+pci:v000014E4d000016AFsv0000103Csd00001798*
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet Virtual Function (HP Flex-10 10Gb 2-port 530FLB Adapter)
+
+pci:v000014E4d000016AFsv0000103Csd000017A5*
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet Virtual Function (HP Flex-10 10Gb 2-port 530M Adapter)
+
+pci:v000014E4d000016AFsv0000103Csd000018D3*
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet Virtual Function (HP Ethernet 10Gb 2-port 530T Adapter)
+
+pci:v000014E4d000016AFsv0000103Csd00001930*
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet Virtual Function (HP FlexFabric 10Gb 2-port 534FLR-SFP+ Adapter)
+
+pci:v000014E4d000016AFsv0000103Csd00001931*
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet Virtual Function (HP StoreFabric CN1100R Dual Port Converged Network Adapter)
+
+pci:v000014E4d000016AFsv0000103Csd00001932*
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet Virtual Function (HP FlexFabric 10Gb 2-port 534FLB Adapter)
+
+pci:v000014E4d000016AFsv0000103Csd00001933*
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet Virtual Function (HP FlexFabric 10Gb 2-port 534M Adapter)
+
+pci:v000014E4d000016AFsv0000103Csd0000193A*
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet Virtual Function (HP FlexFabric 10Gb 2-port 533FLR-T Adapter)
+
+pci:v000014E4d000016AFsv0000103Csd00003382*
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet Virtual Function (HP Ethernet 10Gb 2-port 530FLR-SFP+ Adapter)
+
+pci:v000014E4d000016AFsv0000103Csd0000339D*
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet Virtual Function (HP Ethernet 10Gb 2-port 530SFP+ Adapter)
+
 pci:v000014E4d000016B0*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM57761 Gigabit Ethernet PCIe
 
@@ -44061,7 +45303,7 @@ pci:v000014E4d000016B1*
  ID_MODEL_FROM_DATABASE=NetLink BCM57781 Gigabit Ethernet PCIe
 
 pci:v000014E4d000016B1sv00001849sd000096B1*
- ID_MODEL_FROM_DATABASE=Z77 Extreme4 motherboard
+ ID_MODEL_FROM_DATABASE=NetLink BCM57781 Gigabit Ethernet PCIe (Z77 Extreme4 motherboard)
 
 pci:v000014E4d000016B2*
  ID_MODEL_FROM_DATABASE=NetLink BCM57791 Gigabit Ethernet PCIe
@@ -44094,37 +45336,37 @@ pci:v000014E4d000016C6*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM5702A3 Gigabit Ethernet
 
 pci:v000014E4d000016C6sv000010B7sd00001100*
- ID_MODEL_FROM_DATABASE=3C1000B-T 10/100/1000 PCI
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5702A3 Gigabit Ethernet (3C1000B-T 10/100/1000 PCI)
 
 pci:v000014E4d000016C6sv000014E4sd0000000C*
- ID_MODEL_FROM_DATABASE=BCM5702 1000Base-T
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5702A3 Gigabit Ethernet (BCM5702 1000Base-T)
 
 pci:v000014E4d000016C6sv000014E4sd00008009*
- ID_MODEL_FROM_DATABASE=BCM5702 1000Base-T
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5702A3 Gigabit Ethernet (BCM5702 1000Base-T)
 
 pci:v000014E4d000016C7*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM5703 Gigabit Ethernet
 
 pci:v000014E4d000016C7sv00000E11sd000000CA*
- ID_MODEL_FROM_DATABASE=NC7771 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5703 Gigabit Ethernet (NC7771 Gigabit Server Adapter (PCI-X, 10,100,1000-T))
 
 pci:v000014E4d000016C7sv00000E11sd000000CB*
- ID_MODEL_FROM_DATABASE=NC7781 Gigabit Server Adapter (PCI-X, 10,100,1000-T)
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5703 Gigabit Ethernet (NC7781 Gigabit Server Adapter (PCI-X, 10,100,1000-T))
 
 pci:v000014E4d000016C7sv0000103Csd000012C3*
- ID_MODEL_FROM_DATABASE=Combo FC/GigE-SX [A9782A]
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5703 Gigabit Ethernet (Combo FC/GigE-SX [A9782A])
 
 pci:v000014E4d000016C7sv0000103Csd000012CA*
- ID_MODEL_FROM_DATABASE=Combo FC/GigE-T [A9784A]
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5703 Gigabit Ethernet (Combo FC/GigE-T [A9784A])
 
 pci:v000014E4d000016C7sv0000103Csd00001321*
- ID_MODEL_FROM_DATABASE=Core I/O LAN/SCSI Combo [AB314A]
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5703 Gigabit Ethernet (Core I/O LAN/SCSI Combo [AB314A])
 
 pci:v000014E4d000016C7sv000014E4sd00000009*
- ID_MODEL_FROM_DATABASE=NetXtreme BCM5703 1000Base-T
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5703 Gigabit Ethernet (NetXtreme BCM5703 1000Base-T)
 
 pci:v000014E4d000016C7sv000014E4sd0000000A*
- ID_MODEL_FROM_DATABASE=NetXtreme BCM5703 1000Base-SX
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5703 Gigabit Ethernet (NetXtreme BCM5703 1000Base-SX)
 
 pci:v000014E4d000016DD*
  ID_MODEL_FROM_DATABASE=NetLink BCM5781 Gigabit Ethernet PCI Express
@@ -44139,10 +45381,10 @@ pci:v000014E4d000016FD*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM5753M Gigabit Ethernet PCI Express
 
 pci:v000014E4d000016FDsv0000103Csd0000309F*
- ID_MODEL_FROM_DATABASE=Compaq nx9420 Notebook
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5753M Gigabit Ethernet PCI Express (Compaq nx9420 Notebook)
 
 pci:v000014E4d000016FDsv0000103Csd000030A3*
- ID_MODEL_FROM_DATABASE=Compaq nw8440
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5753M Gigabit Ethernet PCI Express (Compaq nw8440)
 
 pci:v000014E4d000016FE*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM5753F Fast Ethernet PCI Express
@@ -44151,40 +45393,40 @@ pci:v000014E4d0000170C*
  ID_MODEL_FROM_DATABASE=BCM4401-B0 100Base-TX
 
 pci:v000014E4d0000170Csv00001028sd00000188*
- ID_MODEL_FROM_DATABASE=Inspiron 6000 laptop
+ ID_MODEL_FROM_DATABASE=BCM4401-B0 100Base-TX (Inspiron 6000 laptop)
 
 pci:v000014E4d0000170Csv00001028sd0000018D*
- ID_MODEL_FROM_DATABASE=Inspiron 700m/710m
+ ID_MODEL_FROM_DATABASE=BCM4401-B0 100Base-TX (Inspiron 700m/710m)
 
 pci:v000014E4d0000170Csv00001028sd00000196*
- ID_MODEL_FROM_DATABASE=Inspiron 5160
+ ID_MODEL_FROM_DATABASE=BCM4401-B0 100Base-TX (Inspiron 5160)
 
 pci:v000014E4d0000170Csv00001028sd000001AF*
- ID_MODEL_FROM_DATABASE=Inspiron 6400
+ ID_MODEL_FROM_DATABASE=BCM4401-B0 100Base-TX (Inspiron 6400)
 
 pci:v000014E4d0000170Csv00001028sd000001CD*
- ID_MODEL_FROM_DATABASE=Inspiron 9400 Laptop
+ ID_MODEL_FROM_DATABASE=BCM4401-B0 100Base-TX (Inspiron 9400 Laptop)
 
 pci:v000014E4d0000170Csv00001028sd000001D7*
- ID_MODEL_FROM_DATABASE=XPS M1210
+ ID_MODEL_FROM_DATABASE=BCM4401-B0 100Base-TX (XPS M1210)
 
 pci:v000014E4d0000170Csv00001028sd000001D8*
- ID_MODEL_FROM_DATABASE=Inspiron E1405
+ ID_MODEL_FROM_DATABASE=BCM4401-B0 100Base-TX (Inspiron E1405)
 
 pci:v000014E4d0000170Csv0000103Csd0000099C*
- ID_MODEL_FROM_DATABASE=NX6110/NC6120
+ ID_MODEL_FROM_DATABASE=BCM4401-B0 100Base-TX (NX6110/NC6120)
 
 pci:v000014E4d0000170Csv0000103Csd000030A2*
- ID_MODEL_FROM_DATABASE=NX7300 laptop
+ ID_MODEL_FROM_DATABASE=BCM4401-B0 100Base-TX (NX7300 laptop)
 
 pci:v000014E4d0000170Csv000014E4sd0000170C*
- ID_MODEL_FROM_DATABASE=HP Compaq 6720t Mobile Thin Client
+ ID_MODEL_FROM_DATABASE=BCM4401-B0 100Base-TX (HP Compaq 6720t Mobile Thin Client)
 
 pci:v000014E4d0000170D*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM5901 100Base-TX
 
 pci:v000014E4d0000170Dsv00001014sd00000545*
- ID_MODEL_FROM_DATABASE=ThinkPad R40e
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5901 100Base-TX (ThinkPad R40e)
 
 pci:v000014E4d0000170E*
  ID_MODEL_FROM_DATABASE=NetXtreme BCM5901 100Base-TX
@@ -44196,16 +45438,16 @@ pci:v000014E4d00001713*
  ID_MODEL_FROM_DATABASE=NetLink BCM5906M Fast Ethernet PCI Express
 
 pci:v000014E4d00001713sv00001028sd000001F3*
- ID_MODEL_FROM_DATABASE=Inspiron 1420
+ ID_MODEL_FROM_DATABASE=NetLink BCM5906M Fast Ethernet PCI Express (Inspiron 1420)
 
 pci:v000014E4d00001713sv00001028sd00000209*
- ID_MODEL_FROM_DATABASE=XPS M1330
+ ID_MODEL_FROM_DATABASE=NetLink BCM5906M Fast Ethernet PCI Express (XPS M1330)
 
 pci:v000014E4d00001713sv0000103Csd000030C0*
- ID_MODEL_FROM_DATABASE=Compaq 6710b
+ ID_MODEL_FROM_DATABASE=NetLink BCM5906M Fast Ethernet PCI Express (Compaq 6710b)
 
 pci:v000014E4d00001713sv000017AAsd00003A23*
- ID_MODEL_FROM_DATABASE=IdeaPad S10e
+ ID_MODEL_FROM_DATABASE=NetLink BCM5906M Fast Ethernet PCI Express (IdeaPad S10e)
 
 pci:v000014E4d00003352*
  ID_MODEL_FROM_DATABASE=BCM3352
@@ -44232,16 +45474,16 @@ pci:v000014E4d00004301*
  ID_MODEL_FROM_DATABASE=BCM4301 802.11b Wireless LAN Controller
 
 pci:v000014E4d00004301sv00001028sd00000407*
- ID_MODEL_FROM_DATABASE=TrueMobile 1180 Onboard WLAN
+ ID_MODEL_FROM_DATABASE=BCM4301 802.11b Wireless LAN Controller (TrueMobile 1180 Onboard WLAN)
 
 pci:v000014E4d00004301sv00001043sd00000120*
- ID_MODEL_FROM_DATABASE=WL-103b Wireless LAN PC Card
+ ID_MODEL_FROM_DATABASE=BCM4301 802.11b Wireless LAN Controller (WL-103b Wireless LAN PC Card)
 
 pci:v000014E4d00004301sv000016A5sd00001602*
- ID_MODEL_FROM_DATABASE=B-300 802.11b Wireless CardBus Adapter
+ ID_MODEL_FROM_DATABASE=BCM4301 802.11b Wireless LAN Controller (B-300 802.11b Wireless CardBus Adapter)
 
 pci:v000014E4d00004301sv00001737sd00004301*
- ID_MODEL_FROM_DATABASE=WMP11 v2.7 802.11b Wireless-B PCI Adapter
+ ID_MODEL_FROM_DATABASE=BCM4301 802.11b Wireless LAN Controller (WMP11 v2.7 802.11b Wireless-B PCI Adapter)
 
 pci:v000014E4d00004305*
  ID_MODEL_FROM_DATABASE=BCM4307 V.90 56k Modem
@@ -44259,85 +45501,85 @@ pci:v000014E4d00004311*
  ID_MODEL_FROM_DATABASE=BCM4311 802.11b/g WLAN
 
 pci:v000014E4d00004311sv00001028sd00000007*
- ID_MODEL_FROM_DATABASE=Wireless 1390 WLAN Mini-Card
+ ID_MODEL_FROM_DATABASE=BCM4311 802.11b/g WLAN (Wireless 1390 WLAN Mini-Card)
 
 pci:v000014E4d00004311sv00001028sd00000008*
- ID_MODEL_FROM_DATABASE=Wireless 1390 WLAN ExpressCard
+ ID_MODEL_FROM_DATABASE=BCM4311 802.11b/g WLAN (Wireless 1390 WLAN ExpressCard)
 
 pci:v000014E4d00004311sv0000103Csd00001363*
- ID_MODEL_FROM_DATABASE=BCM4311 802.11b/g Wireless LAN Controller
+ ID_MODEL_FROM_DATABASE=BCM4311 802.11b/g WLAN (BCM4311 802.11b/g Wireless LAN Controller)
 
 pci:v000014E4d00004311sv0000103Csd00001364*
- ID_MODEL_FROM_DATABASE=BCM4311 802.11b/g Wireless LAN Controller
+ ID_MODEL_FROM_DATABASE=BCM4311 802.11b/g WLAN (BCM4311 802.11b/g Wireless LAN Controller)
 
 pci:v000014E4d00004311sv0000103Csd00001365*
- ID_MODEL_FROM_DATABASE=BCM4311 802.11b/g Wireless LAN Controller
+ ID_MODEL_FROM_DATABASE=BCM4311 802.11b/g WLAN (BCM4311 802.11b/g Wireless LAN Controller)
 
 pci:v000014E4d00004311sv0000103Csd00001374*
- ID_MODEL_FROM_DATABASE=BCM4311 802.11b/g Wireless LAN Controller
+ ID_MODEL_FROM_DATABASE=BCM4311 802.11b/g WLAN (BCM4311 802.11b/g Wireless LAN Controller)
 
 pci:v000014E4d00004311sv0000103Csd00001375*
- ID_MODEL_FROM_DATABASE=BCM4311 802.11b/g Wireless LAN Controller
+ ID_MODEL_FROM_DATABASE=BCM4311 802.11b/g WLAN (BCM4311 802.11b/g Wireless LAN Controller)
 
 pci:v000014E4d00004311sv0000103Csd00001376*
- ID_MODEL_FROM_DATABASE=BCM4311 802.11b/g Wireless LAN Controller
+ ID_MODEL_FROM_DATABASE=BCM4311 802.11b/g WLAN (BCM4311 802.11b/g Wireless LAN Controller)
 
 pci:v000014E4d00004311sv0000103Csd00001377*
- ID_MODEL_FROM_DATABASE=BCM4311 802.11b/g Wireless LAN Controller
+ ID_MODEL_FROM_DATABASE=BCM4311 802.11b/g WLAN (BCM4311 802.11b/g Wireless LAN Controller)
 
 pci:v000014E4d00004311sv0000103Csd0000137F*
- ID_MODEL_FROM_DATABASE=BCM4322 802.11a/b/g/n Wireless LAN Controller
+ ID_MODEL_FROM_DATABASE=BCM4311 802.11b/g WLAN (BCM4322 802.11a/b/g/n Wireless LAN Controller)
 
 pci:v000014E4d00004311sv0000103Csd00001380*
- ID_MODEL_FROM_DATABASE=BCM4322 802.11a/b/g/n Wireless LAN Controller
+ ID_MODEL_FROM_DATABASE=BCM4311 802.11b/g WLAN (BCM4322 802.11a/b/g/n Wireless LAN Controller)
 
 pci:v000014E4d00004311sv000014E4sd00004311*
- ID_MODEL_FROM_DATABASE=BCM94311MCG
+ ID_MODEL_FROM_DATABASE=BCM4311 802.11b/g WLAN (BCM94311MCG)
 
 pci:v000014E4d00004312*
  ID_MODEL_FROM_DATABASE=BCM4311 802.11a/b/g
 
 pci:v000014E4d00004312sv00001028sd00000007*
- ID_MODEL_FROM_DATABASE=Wireless 1490 Dual Band WLAN Mini-Card
+ ID_MODEL_FROM_DATABASE=BCM4311 802.11a/b/g (Wireless 1490 Dual Band WLAN Mini-Card)
 
 pci:v000014E4d00004312sv00001028sd00000008*
- ID_MODEL_FROM_DATABASE=Wireless 1490 Dual Band WLAN ExpressCard
+ ID_MODEL_FROM_DATABASE=BCM4311 802.11a/b/g (Wireless 1490 Dual Band WLAN ExpressCard)
 
 pci:v000014E4d00004312sv0000103Csd0000135A*
- ID_MODEL_FROM_DATABASE=Broadcom 802.11a/b/g WLAN
+ ID_MODEL_FROM_DATABASE=BCM4311 802.11a/b/g (Broadcom 802.11a/b/g WLAN)
 
 pci:v000014E4d00004312sv0000103Csd0000135F*
- ID_MODEL_FROM_DATABASE=Broadcom 802.11a/b/g WLAN
+ ID_MODEL_FROM_DATABASE=BCM4311 802.11a/b/g (Broadcom 802.11a/b/g WLAN)
 
 pci:v000014E4d00004312sv0000103Csd00001360*
- ID_MODEL_FROM_DATABASE=Broadcom 802.11a/b/g WLAN
+ ID_MODEL_FROM_DATABASE=BCM4311 802.11a/b/g (Broadcom 802.11a/b/g WLAN)
 
 pci:v000014E4d00004312sv0000103Csd00001361*
- ID_MODEL_FROM_DATABASE=Broadcom 802.11a/b/g WLAN
+ ID_MODEL_FROM_DATABASE=BCM4311 802.11a/b/g (Broadcom 802.11a/b/g WLAN)
 
 pci:v000014E4d00004312sv0000103Csd00001362*
- ID_MODEL_FROM_DATABASE=Broadcom 802.11a/b/g WLAN
+ ID_MODEL_FROM_DATABASE=BCM4311 802.11a/b/g (Broadcom 802.11a/b/g WLAN)
 
 pci:v000014E4d00004312sv0000103Csd00001370*
- ID_MODEL_FROM_DATABASE=Broadcom 802.11a/b/g WLAN
+ ID_MODEL_FROM_DATABASE=BCM4311 802.11a/b/g (Broadcom 802.11a/b/g WLAN)
 
 pci:v000014E4d00004312sv0000103Csd00001371*
- ID_MODEL_FROM_DATABASE=Broadcom 802.11a/b/g WLAN
+ ID_MODEL_FROM_DATABASE=BCM4311 802.11a/b/g (Broadcom 802.11a/b/g WLAN)
 
 pci:v000014E4d00004312sv0000103Csd00001372*
- ID_MODEL_FROM_DATABASE=Broadcom 802.11a/b/g WLAN
+ ID_MODEL_FROM_DATABASE=BCM4311 802.11a/b/g (Broadcom 802.11a/b/g WLAN)
 
 pci:v000014E4d00004312sv0000103Csd00001373*
- ID_MODEL_FROM_DATABASE=Broadcom 802.11a/b/g WLAN
+ ID_MODEL_FROM_DATABASE=BCM4311 802.11a/b/g (Broadcom 802.11a/b/g WLAN)
 
 pci:v000014E4d00004312sv0000103Csd000030B5*
- ID_MODEL_FROM_DATABASE=Presario V3242AU
+ ID_MODEL_FROM_DATABASE=BCM4311 802.11a/b/g (Presario V3242AU)
 
 pci:v000014E4d00004312sv0000106Bsd00000089*
- ID_MODEL_FROM_DATABASE=AirPort Extreme
+ ID_MODEL_FROM_DATABASE=BCM4311 802.11a/b/g (AirPort Extreme)
 
 pci:v000014E4d00004312sv00001371sd0000103C*
- ID_MODEL_FROM_DATABASE=Broadcom 802.11 Multiband-netwerkadapter(6715s)
+ ID_MODEL_FROM_DATABASE=BCM4311 802.11a/b/g (Broadcom 802.11 Multiband-netwerkadapter(6715s))
 
 pci:v000014E4d00004313*
  ID_MODEL_FROM_DATABASE=BCM4311 802.11a
@@ -44346,175 +45588,175 @@ pci:v000014E4d00004315*
  ID_MODEL_FROM_DATABASE=BCM4312 802.11b/g LP-PHY
 
 pci:v000014E4d00004315sv00001028sd0000000B*
- ID_MODEL_FROM_DATABASE=Wireless 1395 WLAN Mini-Card
+ ID_MODEL_FROM_DATABASE=BCM4312 802.11b/g LP-PHY (Wireless 1395 WLAN Mini-Card)
 
 pci:v000014E4d00004315sv00001028sd0000000C*
- ID_MODEL_FROM_DATABASE=Wireless 1397 WLAN Mini-Card
+ ID_MODEL_FROM_DATABASE=BCM4312 802.11b/g LP-PHY (Wireless 1397 WLAN Mini-Card)
 
 pci:v000014E4d00004315sv0000103Csd0000137C*
- ID_MODEL_FROM_DATABASE=BCM4312 802.11b/g Wireless LAN Controller
+ ID_MODEL_FROM_DATABASE=BCM4312 802.11b/g LP-PHY (BCM4312 802.11b/g Wireless LAN Controller)
 
 pci:v000014E4d00004315sv0000103Csd0000137D*
- ID_MODEL_FROM_DATABASE=BCM4312 802.11b/g Wireless LAN Controller
+ ID_MODEL_FROM_DATABASE=BCM4312 802.11b/g LP-PHY (BCM4312 802.11b/g Wireless LAN Controller)
 
 pci:v000014E4d00004315sv0000103Csd00001507*
- ID_MODEL_FROM_DATABASE=U98Z049.00 Wireless Mini PCIe Card
+ ID_MODEL_FROM_DATABASE=BCM4312 802.11b/g LP-PHY (U98Z049.00 Wireless Mini PCIe Card)
 
 pci:v000014E4d00004315sv0000105Bsd0000E003*
- ID_MODEL_FROM_DATABASE=T77H030.00 Wireless Mini PCIe Card
+ ID_MODEL_FROM_DATABASE=BCM4312 802.11b/g LP-PHY (T77H030.00 Wireless Mini PCIe Card)
 
 pci:v000014E4d00004315sv0000105Bsd0000E01B*
- ID_MODEL_FROM_DATABASE=T77H106.00 Wireless Half-size Mini PCIe Card
+ ID_MODEL_FROM_DATABASE=BCM4312 802.11b/g LP-PHY (T77H106.00 Wireless Half-size Mini PCIe Card)
 
 pci:v000014E4d00004318*
  ID_MODEL_FROM_DATABASE=BCM4318 [AirForce One 54g] 802.11g Wireless LAN Controller
 
 pci:v000014E4d00004318sv00001028sd00000005*
- ID_MODEL_FROM_DATABASE=Wireless 1370 WLAN Mini-PCI Card
+ ID_MODEL_FROM_DATABASE=BCM4318 [AirForce One 54g] 802.11g Wireless LAN Controller (Wireless 1370 WLAN Mini-PCI Card)
 
 pci:v000014E4d00004318sv00001028sd00000006*
- ID_MODEL_FROM_DATABASE=Wireless 1370 WLAN PC Card
+ ID_MODEL_FROM_DATABASE=BCM4318 [AirForce One 54g] 802.11g Wireless LAN Controller (Wireless 1370 WLAN PC Card)
 
 pci:v000014E4d00004318sv0000103Csd00001355*
- ID_MODEL_FROM_DATABASE=Broadcom 802.11b/g WLAN
+ ID_MODEL_FROM_DATABASE=BCM4318 [AirForce One 54g] 802.11g Wireless LAN Controller (Broadcom 802.11b/g WLAN)
 
 pci:v000014E4d00004318sv0000103Csd00001356*
- ID_MODEL_FROM_DATABASE=Broadcom 802.11b/g WLAN
+ ID_MODEL_FROM_DATABASE=BCM4318 [AirForce One 54g] 802.11g Wireless LAN Controller (Broadcom 802.11b/g WLAN)
 
 pci:v000014E4d00004318sv0000103Csd00001357*
- ID_MODEL_FROM_DATABASE=Broadcom 802.11b/g WLAN
+ ID_MODEL_FROM_DATABASE=BCM4318 [AirForce One 54g] 802.11g Wireless LAN Controller (Broadcom 802.11b/g WLAN)
 
 pci:v000014E4d00004318sv00001043sd0000100F*
- ID_MODEL_FROM_DATABASE=WL-138G v2 / WL-138gE / WL-100gE
+ ID_MODEL_FROM_DATABASE=BCM4318 [AirForce One 54g] 802.11g Wireless LAN Controller (WL-138G v2 / WL-138gE / WL-100gE)
 
 pci:v000014E4d00004318sv00001043sd0000120F*
- ID_MODEL_FROM_DATABASE=A6U notebook embedded card
+ ID_MODEL_FROM_DATABASE=BCM4318 [AirForce One 54g] 802.11g Wireless LAN Controller (A6U notebook embedded card)
 
 pci:v000014E4d00004318sv00001154sd00000355*
- ID_MODEL_FROM_DATABASE=Buffalo WLI2-PCI-G54S High Speed Mode Wireless Adapter
+ ID_MODEL_FROM_DATABASE=BCM4318 [AirForce One 54g] 802.11g Wireless LAN Controller (Buffalo WLI2-PCI-G54S High Speed Mode Wireless Adapter)
 
 pci:v000014E4d00004318sv00001468sd00000311*
- ID_MODEL_FROM_DATABASE=Aspire 3022WLMi, 5024WLMi, 5020
+ ID_MODEL_FROM_DATABASE=BCM4318 [AirForce One 54g] 802.11g Wireless LAN Controller (Aspire 3022WLMi, 5024WLMi, 5020)
 
 pci:v000014E4d00004318sv00001468sd00000312*
- ID_MODEL_FROM_DATABASE=TravelMate 2410
+ ID_MODEL_FROM_DATABASE=BCM4318 [AirForce One 54g] 802.11g Wireless LAN Controller (TravelMate 2410)
 
 pci:v000014E4d00004318sv000014E4sd00000449*
- ID_MODEL_FROM_DATABASE=Gateway 7510GX
+ ID_MODEL_FROM_DATABASE=BCM4318 [AirForce One 54g] 802.11g Wireless LAN Controller (Gateway 7510GX)
 
 pci:v000014E4d00004318sv000016ECsd00000119*
- ID_MODEL_FROM_DATABASE=U.S.Robotics Wireless MAXg PC Card
+ ID_MODEL_FROM_DATABASE=BCM4318 [AirForce One 54g] 802.11g Wireless LAN Controller (U.S.Robotics Wireless MAXg PC Card)
 
 pci:v000014E4d00004318sv00001737sd00000042*
- ID_MODEL_FROM_DATABASE=WMP54GS v1.1 802.11g Wireless-G PCI Adapter with SpeedBooster
+ ID_MODEL_FROM_DATABASE=BCM4318 [AirForce One 54g] 802.11g Wireless LAN Controller (WMP54GS v1.1 802.11g Wireless-G PCI Adapter with SpeedBooster)
 
 pci:v000014E4d00004318sv00001737sd00000048*
- ID_MODEL_FROM_DATABASE=WPC54G v3 802.11g Wireless-G Notebook Adapter
+ ID_MODEL_FROM_DATABASE=BCM4318 [AirForce One 54g] 802.11g Wireless LAN Controller (WPC54G v3 802.11g Wireless-G Notebook Adapter)
 
 pci:v000014E4d00004318sv00001737sd00000049*
- ID_MODEL_FROM_DATABASE=WPC54GS v2 802.11g Wireless-G Notebook Adapter with SpeedBooster
+ ID_MODEL_FROM_DATABASE=BCM4318 [AirForce One 54g] 802.11g Wireless LAN Controller (WPC54GS v2 802.11g Wireless-G Notebook Adapter with SpeedBooster)
 
 pci:v000014E4d00004318sv00001799sd00007000*
- ID_MODEL_FROM_DATABASE=F5D7000 v4000 Wireless G Desktop Card
+ ID_MODEL_FROM_DATABASE=BCM4318 [AirForce One 54g] 802.11g Wireless LAN Controller (F5D7000 v4000 Wireless G Desktop Card)
 
 pci:v000014E4d00004318sv00001799sd00007001*
- ID_MODEL_FROM_DATABASE=F5D7001 v2000 Wireless G Plus Desktop Card
+ ID_MODEL_FROM_DATABASE=BCM4318 [AirForce One 54g] 802.11g Wireless LAN Controller (F5D7001 v2000 Wireless G Plus Desktop Card)
 
 pci:v000014E4d00004318sv00001799sd00007010*
- ID_MODEL_FROM_DATABASE=F5D7010 v4000 Wireless G Notebook Card
+ ID_MODEL_FROM_DATABASE=BCM4318 [AirForce One 54g] 802.11g Wireless LAN Controller (F5D7010 v4000 Wireless G Notebook Card)
 
 pci:v000014E4d00004318sv00001799sd00007011*
- ID_MODEL_FROM_DATABASE=F5D7011 v2000 High-Speed Mode Wireless G Notebook Card
+ ID_MODEL_FROM_DATABASE=BCM4318 [AirForce One 54g] 802.11g Wireless LAN Controller (F5D7011 v2000 High-Speed Mode Wireless G Notebook Card)
 
 pci:v000014E4d00004319*
  ID_MODEL_FROM_DATABASE=BCM4318 [AirForce 54g] 802.11a/b/g PCI Express Transceiver
 
 pci:v000014E4d00004319sv00001028sd00000005*
- ID_MODEL_FROM_DATABASE=Wireless 1470 Dual Band WLAN Mini-PCI Card
+ ID_MODEL_FROM_DATABASE=BCM4318 [AirForce 54g] 802.11a/b/g PCI Express Transceiver (Wireless 1470 Dual Band WLAN Mini-PCI Card)
 
 pci:v000014E4d00004319sv00001028sd00000006*
- ID_MODEL_FROM_DATABASE=Wireless 1470 Dual Band WLAN PC Card
+ ID_MODEL_FROM_DATABASE=BCM4318 [AirForce 54g] 802.11a/b/g PCI Express Transceiver (Wireless 1470 Dual Band WLAN PC Card)
 
 pci:v000014E4d00004319sv0000103Csd00001358*
- ID_MODEL_FROM_DATABASE=Broadcom 802.11a/b/g WLAN
+ ID_MODEL_FROM_DATABASE=BCM4318 [AirForce 54g] 802.11a/b/g PCI Express Transceiver (Broadcom 802.11a/b/g WLAN)
 
 pci:v000014E4d00004319sv0000103Csd00001359*
- ID_MODEL_FROM_DATABASE=Broadcom 802.11a/b/g WLAN
+ ID_MODEL_FROM_DATABASE=BCM4318 [AirForce 54g] 802.11a/b/g PCI Express Transceiver (Broadcom 802.11a/b/g WLAN)
 
 pci:v000014E4d00004319sv0000103Csd0000135A*
- ID_MODEL_FROM_DATABASE=Broadcom 802.11a/b/g WLAN
+ ID_MODEL_FROM_DATABASE=BCM4318 [AirForce 54g] 802.11a/b/g PCI Express Transceiver (Broadcom 802.11a/b/g WLAN)
 
 pci:v000014E4d00004320*
  ID_MODEL_FROM_DATABASE=BCM4306 802.11b/g Wireless LAN Controller
 
 pci:v000014E4d00004320sv00001028sd00000001*
- ID_MODEL_FROM_DATABASE=TrueMobile 1300 WLAN Mini-PCI Card
+ ID_MODEL_FROM_DATABASE=BCM4306 802.11b/g Wireless LAN Controller (TrueMobile 1300 WLAN Mini-PCI Card)
 
 pci:v000014E4d00004320sv00001028sd00000002*
- ID_MODEL_FROM_DATABASE=TrueMobile 1300 WLAN PC Card
+ ID_MODEL_FROM_DATABASE=BCM4306 802.11b/g Wireless LAN Controller (TrueMobile 1300 WLAN PC Card)
 
 pci:v000014E4d00004320sv00001028sd00000003*
- ID_MODEL_FROM_DATABASE=Wireless 1350 WLAN Mini-PCI Card
+ ID_MODEL_FROM_DATABASE=BCM4306 802.11b/g Wireless LAN Controller (Wireless 1350 WLAN Mini-PCI Card)
 
 pci:v000014E4d00004320sv00001028sd00000004*
- ID_MODEL_FROM_DATABASE=Wireless 1350 WLAN PC Card
+ ID_MODEL_FROM_DATABASE=BCM4306 802.11b/g Wireless LAN Controller (Wireless 1350 WLAN PC Card)
 
 pci:v000014E4d00004320sv0000103Csd000012F4*
- ID_MODEL_FROM_DATABASE=Broadcom 802.11b/g WLAN
+ ID_MODEL_FROM_DATABASE=BCM4306 802.11b/g Wireless LAN Controller (Broadcom 802.11b/g WLAN)
 
 pci:v000014E4d00004320sv0000103Csd000012F8*
- ID_MODEL_FROM_DATABASE=Broadcom 802.11b/g WLAN
+ ID_MODEL_FROM_DATABASE=BCM4306 802.11b/g Wireless LAN Controller (Broadcom 802.11b/g WLAN)
 
 pci:v000014E4d00004320sv0000103Csd000012FA*
- ID_MODEL_FROM_DATABASE=Broadcom 802.11b/g WLAN
+ ID_MODEL_FROM_DATABASE=BCM4306 802.11b/g Wireless LAN Controller (Broadcom 802.11b/g WLAN)
 
 pci:v000014E4d00004320sv0000103Csd000012FB*
- ID_MODEL_FROM_DATABASE=Broadcom 802.11b/g WLAN
+ ID_MODEL_FROM_DATABASE=BCM4306 802.11b/g Wireless LAN Controller (Broadcom 802.11b/g WLAN)
 
 pci:v000014E4d00004320sv00001043sd0000100F*
- ID_MODEL_FROM_DATABASE=WL-100G
+ ID_MODEL_FROM_DATABASE=BCM4306 802.11b/g Wireless LAN Controller (WL-100G)
 
 pci:v000014E4d00004320sv00001057sd00007025*
- ID_MODEL_FROM_DATABASE=WN825G
+ ID_MODEL_FROM_DATABASE=BCM4306 802.11b/g Wireless LAN Controller (WN825G)
 
 pci:v000014E4d00004320sv0000106Bsd0000004E*
- ID_MODEL_FROM_DATABASE=AirPort Extreme
+ ID_MODEL_FROM_DATABASE=BCM4306 802.11b/g Wireless LAN Controller (AirPort Extreme)
 
 pci:v000014E4d00004320sv00001154sd00000330*
- ID_MODEL_FROM_DATABASE=Buffalo WLI2-PCI-G54S High Speed Mode Wireless Desktop Adapter
+ ID_MODEL_FROM_DATABASE=BCM4306 802.11b/g Wireless LAN Controller (Buffalo WLI2-PCI-G54S High Speed Mode Wireless Desktop Adapter)
 
 pci:v000014E4d00004320sv0000144Fsd00007050*
- ID_MODEL_FROM_DATABASE=eMachines M6805 802.11g Built-in Wireless
+ ID_MODEL_FROM_DATABASE=BCM4306 802.11b/g Wireless LAN Controller (eMachines M6805 802.11g Built-in Wireless)
 
 pci:v000014E4d00004320sv0000144Fsd00007051*
- ID_MODEL_FROM_DATABASE=Sonnet Aria Extreme PCI
+ ID_MODEL_FROM_DATABASE=BCM4306 802.11b/g Wireless LAN Controller (Sonnet Aria Extreme PCI)
 
 pci:v000014E4d00004320sv00001737sd00000013*
- ID_MODEL_FROM_DATABASE=WMP54G v1 802.11g PCI Adapter
+ ID_MODEL_FROM_DATABASE=BCM4306 802.11b/g Wireless LAN Controller (WMP54G v1 802.11g PCI Adapter)
 
 pci:v000014E4d00004320sv00001737sd00000014*
- ID_MODEL_FROM_DATABASE=WMP54G v2 802.11g PCI Adapter
+ ID_MODEL_FROM_DATABASE=BCM4306 802.11b/g Wireless LAN Controller (WMP54G v2 802.11g PCI Adapter)
 
 pci:v000014E4d00004320sv00001737sd00000015*
- ID_MODEL_FROM_DATABASE=WMP54GS v1.0 802.11g Wireless-G PCI Adapter with SpeedBooster
+ ID_MODEL_FROM_DATABASE=BCM4306 802.11b/g Wireless LAN Controller (WMP54GS v1.0 802.11g Wireless-G PCI Adapter with SpeedBooster)
 
 pci:v000014E4d00004320sv00001737sd00004320*
- ID_MODEL_FROM_DATABASE=WPC54G v1 / WPC54GS v1 802.11g Wireless-G Notebook Adapter
+ ID_MODEL_FROM_DATABASE=BCM4306 802.11b/g Wireless LAN Controller (WPC54G v1 / WPC54GS v1 802.11g Wireless-G Notebook Adapter)
 
 pci:v000014E4d00004320sv00001799sd00007000*
- ID_MODEL_FROM_DATABASE=F5D7000 v1000 Wireless G Desktop Card
+ ID_MODEL_FROM_DATABASE=BCM4306 802.11b/g Wireless LAN Controller (F5D7000 v1000 Wireless G Desktop Card)
 
 pci:v000014E4d00004320sv00001799sd00007001*
- ID_MODEL_FROM_DATABASE=F5D7001 v1000 Wireless G Plus Desktop Card
+ ID_MODEL_FROM_DATABASE=BCM4306 802.11b/g Wireless LAN Controller (F5D7001 v1000 Wireless G Plus Desktop Card)
 
 pci:v000014E4d00004320sv00001799sd00007010*
- ID_MODEL_FROM_DATABASE=F5D7010 v1000 Wireless G Notebook Card
+ ID_MODEL_FROM_DATABASE=BCM4306 802.11b/g Wireless LAN Controller (F5D7010 v1000 Wireless G Notebook Card)
 
 pci:v000014E4d00004320sv00001799sd00007011*
- ID_MODEL_FROM_DATABASE=F5D7011 v1000 High-Speed Mode Wireless G Notebook Card
+ ID_MODEL_FROM_DATABASE=BCM4306 802.11b/g Wireless LAN Controller (F5D7011 v1000 High-Speed Mode Wireless G Notebook Card)
 
 pci:v000014E4d00004320sv0000185Fsd00001220*
- ID_MODEL_FROM_DATABASE=TravelMate 290E WLAN Mini-PCI Card
+ ID_MODEL_FROM_DATABASE=BCM4306 802.11b/g Wireless LAN Controller (TravelMate 290E WLAN Mini-PCI Card)
 
 pci:v000014E4d00004321*
  ID_MODEL_FROM_DATABASE=BCM4321 802.11a Wireless Network Controller
@@ -44526,31 +45768,31 @@ pci:v000014E4d00004324*
  ID_MODEL_FROM_DATABASE=BCM4309 802.11abg Wireless Network Controller
 
 pci:v000014E4d00004324sv00001028sd00000001*
- ID_MODEL_FROM_DATABASE=Truemobile 1400
+ ID_MODEL_FROM_DATABASE=BCM4309 802.11abg Wireless Network Controller (Truemobile 1400)
 
 pci:v000014E4d00004324sv00001028sd00000002*
- ID_MODEL_FROM_DATABASE=TrueMobile 1400 Dual Band WLAN PC Card
+ ID_MODEL_FROM_DATABASE=BCM4309 802.11abg Wireless Network Controller (TrueMobile 1400 Dual Band WLAN PC Card)
 
 pci:v000014E4d00004324sv00001028sd00000003*
- ID_MODEL_FROM_DATABASE=Truemobile 1450 MiniPCI
+ ID_MODEL_FROM_DATABASE=BCM4309 802.11abg Wireless Network Controller (Truemobile 1450 MiniPCI)
 
 pci:v000014E4d00004324sv00001028sd00000004*
- ID_MODEL_FROM_DATABASE=Wireless 1450 Dual Band WLAN PC Card
+ ID_MODEL_FROM_DATABASE=BCM4309 802.11abg Wireless Network Controller (Wireless 1450 Dual Band WLAN PC Card)
 
 pci:v000014E4d00004324sv0000103Csd000012F9*
- ID_MODEL_FROM_DATABASE=Broadcom 802.11a/b/g WLAN
+ ID_MODEL_FROM_DATABASE=BCM4309 802.11abg Wireless Network Controller (Broadcom 802.11a/b/g WLAN)
 
 pci:v000014E4d00004324sv0000103Csd000012FC*
- ID_MODEL_FROM_DATABASE=Broadcom 802.11a/b/g WLAN
+ ID_MODEL_FROM_DATABASE=BCM4309 802.11abg Wireless Network Controller (Broadcom 802.11a/b/g WLAN)
 
 pci:v000014E4d00004325*
  ID_MODEL_FROM_DATABASE=BCM4306 802.11bg Wireless Network Controller
 
 pci:v000014E4d00004325sv00001414sd00000003*
- ID_MODEL_FROM_DATABASE=Wireless Notebook Adapter MN-720
+ ID_MODEL_FROM_DATABASE=BCM4306 802.11bg Wireless Network Controller (Wireless Notebook Adapter MN-720)
 
 pci:v000014E4d00004325sv00001414sd00000004*
- ID_MODEL_FROM_DATABASE=Wireless PCI Adapter MN-730
+ ID_MODEL_FROM_DATABASE=BCM4306 802.11bg Wireless Network Controller (Wireless PCI Adapter MN-730)
 
 pci:v000014E4d00004326*
  ID_MODEL_FROM_DATABASE=BCM4307 Chipcommon I/O Controller?
@@ -44559,58 +45801,58 @@ pci:v000014E4d00004328*
  ID_MODEL_FROM_DATABASE=BCM4321 802.11a/b/g/n
 
 pci:v000014E4d00004328sv00001028sd00000009*
- ID_MODEL_FROM_DATABASE=Wireless 1500 Draft 802.11n WLAN Mini-Card
+ ID_MODEL_FROM_DATABASE=BCM4321 802.11a/b/g/n (Wireless 1500 Draft 802.11n WLAN Mini-Card)
 
 pci:v000014E4d00004328sv00001028sd0000000A*
- ID_MODEL_FROM_DATABASE=Wireless 1500 Draft 802.11n WLAN Mini-card
+ ID_MODEL_FROM_DATABASE=BCM4321 802.11a/b/g/n (Wireless 1500 Draft 802.11n WLAN Mini-card)
 
 pci:v000014E4d00004328sv0000103Csd00001366*
- ID_MODEL_FROM_DATABASE=BCM4321 802.11a/b/g/n Wireless LAN Controller
+ ID_MODEL_FROM_DATABASE=BCM4321 802.11a/b/g/n (Wireless LAN Controller)
 
 pci:v000014E4d00004328sv0000103Csd00001367*
- ID_MODEL_FROM_DATABASE=BCM4321 802.11a/b/g/n Wireless LAN Controller
+ ID_MODEL_FROM_DATABASE=BCM4321 802.11a/b/g/n (Wireless LAN Controller)
 
 pci:v000014E4d00004328sv0000103Csd00001368*
- ID_MODEL_FROM_DATABASE=BCM4321 802.11a/b/g/n Wireless LAN Controller
+ ID_MODEL_FROM_DATABASE=BCM4321 802.11a/b/g/n (Wireless LAN Controller)
 
 pci:v000014E4d00004328sv0000103Csd00001369*
- ID_MODEL_FROM_DATABASE=BCM4321 802.11a/b/g/n Wireless LAN Controller
+ ID_MODEL_FROM_DATABASE=BCM4321 802.11a/b/g/n (Wireless LAN Controller)
 
 pci:v000014E4d00004328sv0000106Bsd00000087*
- ID_MODEL_FROM_DATABASE=AirPort Extreme
+ ID_MODEL_FROM_DATABASE=BCM4321 802.11a/b/g/n (AirPort Extreme)
 
 pci:v000014E4d00004328sv0000106Bsd00000088*
- ID_MODEL_FROM_DATABASE=AirPort Extreme
+ ID_MODEL_FROM_DATABASE=BCM4321 802.11a/b/g/n (AirPort Extreme)
 
 pci:v000014E4d00004328sv0000106Bsd0000008B*
- ID_MODEL_FROM_DATABASE=AirPort Extreme
+ ID_MODEL_FROM_DATABASE=BCM4321 802.11a/b/g/n (AirPort Extreme)
 
 pci:v000014E4d00004328sv0000106Bsd0000008C*
- ID_MODEL_FROM_DATABASE=AirPort Extreme
+ ID_MODEL_FROM_DATABASE=BCM4321 802.11a/b/g/n (AirPort Extreme)
 
 pci:v000014E4d00004328sv0000106Bsd00000090*
- ID_MODEL_FROM_DATABASE=AirPort Extreme
+ ID_MODEL_FROM_DATABASE=BCM4321 802.11a/b/g/n (AirPort Extreme)
 
 pci:v000014E4d00004328sv000014E4sd00004328*
- ID_MODEL_FROM_DATABASE=BCM4328 802.11a/b/g/n
+ ID_MODEL_FROM_DATABASE=BCM4321 802.11a/b/g/n (BCM4328 802.11a/b/g/n)
 
 pci:v000014E4d00004328sv00001737sd00000066*
- ID_MODEL_FROM_DATABASE=WPC600N v1 802.11a/b/g/n Wireless-N CardBus Adapter
+ ID_MODEL_FROM_DATABASE=BCM4321 802.11a/b/g/n (WPC600N v1 802.11a/b/g/n Wireless-N CardBus Adapter)
 
 pci:v000014E4d00004328sv00001737sd00000068*
- ID_MODEL_FROM_DATABASE=WEC600N v1 802.11a/b/g/n Wireless-N ExpressCard
+ ID_MODEL_FROM_DATABASE=BCM4321 802.11a/b/g/n (WEC600N v1 802.11a/b/g/n Wireless-N ExpressCard)
 
 pci:v000014E4d00004329*
  ID_MODEL_FROM_DATABASE=BCM4321 802.11b/g/n
 
 pci:v000014E4d00004329sv00001385sd00007B00*
- ID_MODEL_FROM_DATABASE=WN511B RangeMax NEXT Wireless Notebook Adapter
+ ID_MODEL_FROM_DATABASE=BCM4321 802.11b/g/n (WN511B RangeMax NEXT Wireless Notebook Adapter)
 
 pci:v000014E4d00004329sv00001385sd00007D00*
- ID_MODEL_FROM_DATABASE=WN311B RangeMax Next 270 Mbps Wireless PCI Adapter
+ ID_MODEL_FROM_DATABASE=BCM4321 802.11b/g/n (WN311B RangeMax Next 270 Mbps Wireless PCI Adapter)
 
 pci:v000014E4d00004329sv00001737sd00000058*
- ID_MODEL_FROM_DATABASE=WPC300N v1 Wireless-N Notebook Adapter
+ ID_MODEL_FROM_DATABASE=BCM4321 802.11b/g/n (WPC300N v1 Wireless-N Notebook Adapter)
 
 pci:v000014E4d0000432A*
  ID_MODEL_FROM_DATABASE=BCM4321 802.11an Wireless Network Controller
@@ -44619,19 +45861,19 @@ pci:v000014E4d0000432B*
  ID_MODEL_FROM_DATABASE=BCM4322 802.11a/b/g/n Wireless LAN Controller
 
 pci:v000014E4d0000432Bsv00001028sd0000000D*
- ID_MODEL_FROM_DATABASE=Wireless 1510 Wireless-N WLAN Mini-Card
+ ID_MODEL_FROM_DATABASE=BCM4322 802.11a/b/g/n Wireless LAN Controller (Wireless 1510 Wireless-N WLAN Mini-Card)
 
 pci:v000014E4d0000432Bsv0000106Bsd0000008D*
- ID_MODEL_FROM_DATABASE=AirPort Extreme
+ ID_MODEL_FROM_DATABASE=BCM4322 802.11a/b/g/n Wireless LAN Controller (AirPort Extreme)
 
 pci:v000014E4d0000432Bsv0000106Bsd0000008E*
- ID_MODEL_FROM_DATABASE=AirPort Extreme
+ ID_MODEL_FROM_DATABASE=BCM4322 802.11a/b/g/n Wireless LAN Controller (AirPort Extreme)
 
 pci:v000014E4d0000432C*
  ID_MODEL_FROM_DATABASE=BCM4322 802.11b/g/n
 
 pci:v000014E4d0000432Csv00001799sd0000D311*
- ID_MODEL_FROM_DATABASE=Dynex DX-NNBX 802.11n WLAN Cardbus Card
+ ID_MODEL_FROM_DATABASE=BCM4322 802.11b/g/n (Dynex DX-NNBX 802.11n WLAN Cardbus Card)
 
 pci:v000014E4d0000432D*
  ID_MODEL_FROM_DATABASE=BCM4322 802.11an Wireless Network Controller
@@ -44640,25 +45882,25 @@ pci:v000014E4d00004331*
  ID_MODEL_FROM_DATABASE=BCM4331 802.11a/b/g/n
 
 pci:v000014E4d00004331sv0000106Bsd000000D6*
- ID_MODEL_FROM_DATABASE=AirPort Extreme
+ ID_MODEL_FROM_DATABASE=BCM4331 802.11a/b/g/n (AirPort Extreme)
 
 pci:v000014E4d00004331sv0000106Bsd000000E4*
- ID_MODEL_FROM_DATABASE=AirPort Extreme
+ ID_MODEL_FROM_DATABASE=BCM4331 802.11a/b/g/n (AirPort Extreme)
 
 pci:v000014E4d00004331sv0000106Bsd000000EF*
- ID_MODEL_FROM_DATABASE=AirPort Extreme
+ ID_MODEL_FROM_DATABASE=BCM4331 802.11a/b/g/n (AirPort Extreme)
 
 pci:v000014E4d00004331sv0000106Bsd000000F4*
- ID_MODEL_FROM_DATABASE=AirPort Extreme
+ ID_MODEL_FROM_DATABASE=BCM4331 802.11a/b/g/n (AirPort Extreme)
 
 pci:v000014E4d00004331sv0000106Bsd000000F5*
- ID_MODEL_FROM_DATABASE=AirPort Extreme
+ ID_MODEL_FROM_DATABASE=BCM4331 802.11a/b/g/n (AirPort Extreme)
 
 pci:v000014E4d00004331sv0000106Bsd0000010E*
- ID_MODEL_FROM_DATABASE=AirPort Extreme
+ ID_MODEL_FROM_DATABASE=BCM4331 802.11a/b/g/n (AirPort Extreme)
 
 pci:v000014E4d00004331sv0000106Bsd0000010F*
- ID_MODEL_FROM_DATABASE=AirPort Extreme
+ ID_MODEL_FROM_DATABASE=BCM4331 802.11a/b/g/n (AirPort Extreme)
 
 pci:v000014E4d00004333*
  ID_MODEL_FROM_DATABASE=Serial (EDGE/GPRS modem part of Option GT Combo Edge)
@@ -44673,25 +45915,25 @@ pci:v000014E4d00004353*
  ID_MODEL_FROM_DATABASE=BCM43224 802.11a/b/g/n
 
 pci:v000014E4d00004353sv00001028sd0000000E*
- ID_MODEL_FROM_DATABASE=Wireless 1520 Half-size Mini PCIe Card
+ ID_MODEL_FROM_DATABASE=BCM43224 802.11a/b/g/n (Wireless 1520 Half-size Mini PCIe Card)
 
 pci:v000014E4d00004353sv0000103Csd00001509*
- ID_MODEL_FROM_DATABASE=WMIB-275N Half-size Mini PCIe Card
+ ID_MODEL_FROM_DATABASE=BCM43224 802.11a/b/g/n (WMIB-275N Half-size Mini PCIe Card)
 
 pci:v000014E4d00004353sv0000106Bsd00000093*
- ID_MODEL_FROM_DATABASE=AirPort Extreme
+ ID_MODEL_FROM_DATABASE=BCM43224 802.11a/b/g/n (AirPort Extreme)
 
 pci:v000014E4d00004353sv0000106Bsd000000D1*
- ID_MODEL_FROM_DATABASE=AirPort Extreme
+ ID_MODEL_FROM_DATABASE=BCM43224 802.11a/b/g/n (AirPort Extreme)
 
 pci:v000014E4d00004353sv0000106Bsd000000E9*
- ID_MODEL_FROM_DATABASE=AirPort Extreme
+ ID_MODEL_FROM_DATABASE=BCM43224 802.11a/b/g/n (AirPort Extreme)
 
 pci:v000014E4d00004357*
  ID_MODEL_FROM_DATABASE=BCM43225 802.11b/g/n
 
 pci:v000014E4d00004357sv0000105Bsd0000E021*
- ID_MODEL_FROM_DATABASE=T77H103.00 Wireless Half-size Mini PCIe Card
+ ID_MODEL_FROM_DATABASE=BCM43225 802.11b/g/n (T77H103.00 Wireless Half-size Mini PCIe Card)
 
 pci:v000014E4d00004358*
  ID_MODEL_FROM_DATABASE=BCM43227 802.11b/g/n
@@ -44700,20 +45942,29 @@ pci:v000014E4d00004359*
  ID_MODEL_FROM_DATABASE=BCM43228 802.11a/b/g/n
 
 pci:v000014E4d00004359sv00001028sd00000011*
- ID_MODEL_FROM_DATABASE=Wireless 1530 Half-size Mini PCIe Card
+ ID_MODEL_FROM_DATABASE=BCM43228 802.11a/b/g/n (Wireless 1530 Half-size Mini PCIe Card)
 
 pci:v000014E4d00004359sv0000103Csd0000182C*
- ID_MODEL_FROM_DATABASE=BCM943228HM4L 802.11a/b/g/n 2x2 Wi-Fi Adapter
+ ID_MODEL_FROM_DATABASE=BCM43228 802.11a/b/g/n (BCM943228HM4L 802.11a/b/g/n 2x2 Wi-Fi Adapter)
+
+pci:v000014E4d00004360*
+ ID_MODEL_FROM_DATABASE=BCM4360 802.11ac Wireless Network Adapter
 
 pci:v000014E4d00004365*
  ID_MODEL_FROM_DATABASE=BCM43142 802.11b/g/n
 
 pci:v000014E4d00004365sv00001028sd00000016*
- ID_MODEL_FROM_DATABASE=Wireless 1704 802.11n + BT 4.0
+ ID_MODEL_FROM_DATABASE=BCM43142 802.11b/g/n (Wireless 1704 802.11n + BT 4.0)
 
 pci:v000014E4d000043A0*
  ID_MODEL_FROM_DATABASE=BCM4360 802.11ac Wireless Network Adapter
 
+pci:v000014E4d000043A9*
+ ID_MODEL_FROM_DATABASE=BCM43217 802.11b/g/n
+
+pci:v000014E4d000043AA*
+ ID_MODEL_FROM_DATABASE=BCM43131 802.11b/g/n
+
 pci:v000014E4d000043B1*
  ID_MODEL_FROM_DATABASE=BCM4352 802.11ac Wireless Network Adapter
 
@@ -44721,13 +45972,13 @@ pci:v000014E4d00004401*
  ID_MODEL_FROM_DATABASE=BCM4401 100Base-T
 
 pci:v000014E4d00004401sv00001025sd00000035*
- ID_MODEL_FROM_DATABASE=TravelMate 660
+ ID_MODEL_FROM_DATABASE=BCM4401 100Base-T (TravelMate 660)
 
 pci:v000014E4d00004401sv0000103Csd000008B0*
- ID_MODEL_FROM_DATABASE=tc1100 tablet
+ ID_MODEL_FROM_DATABASE=BCM4401 100Base-T (tc1100 tablet)
 
 pci:v000014E4d00004401sv00001043sd000080A8*
- ID_MODEL_FROM_DATABASE=A7V8X motherboard
+ ID_MODEL_FROM_DATABASE=BCM4401 100Base-T (A7V8X motherboard)
 
 pci:v000014E4d00004402*
  ID_MODEL_FROM_DATABASE=BCM4402 Integrated 10/100BaseT
@@ -44820,7 +46071,7 @@ pci:v000014E4d00004727*
  ID_MODEL_FROM_DATABASE=BCM4313 802.11bgn Wireless Network Adapter
 
 pci:v000014E4d00004727sv00001028sd00000010*
- ID_MODEL_FROM_DATABASE=Inspiron M5010 / XPS 8300
+ ID_MODEL_FROM_DATABASE=BCM4313 802.11bgn Wireless Network Adapter (Inspiron M5010 / XPS 8300)
 
 pci:v000014E4d00005365*
  ID_MODEL_FROM_DATABASE=BCM5365P Sentry5 Host Bridge
@@ -44991,55 +46242,55 @@ pci:v000014F1d00001033*
  ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem
 
 pci:v000014F1d00001033sv00001033sd00008077*
- ID_MODEL_FROM_DATABASE=NEC
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (NEC)
 
 pci:v000014F1d00001033sv0000122Dsd00004027*
- ID_MODEL_FROM_DATABASE=Dell Zeus - MDP3880-W(B) Data Fax Modem
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (Dell Zeus - MDP3880-W(B) Data Fax Modem)
 
 pci:v000014F1d00001033sv0000122Dsd00004030*
- ID_MODEL_FROM_DATABASE=Dell Mercury - MDP3880-U(B) Data Fax Modem
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (Dell Mercury - MDP3880-U(B) Data Fax Modem)
 
 pci:v000014F1d00001033sv0000122Dsd00004034*
- ID_MODEL_FROM_DATABASE=Dell Thor - MDP3880-W(U) Data Fax Modem
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (Dell Thor - MDP3880-W(U) Data Fax Modem)
 
 pci:v000014F1d00001033sv000013E0sd0000020D*
- ID_MODEL_FROM_DATABASE=Dell Copper
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (Dell Copper)
 
 pci:v000014F1d00001033sv000013E0sd0000020E*
- ID_MODEL_FROM_DATABASE=Dell Silver
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (Dell Silver)
 
 pci:v000014F1d00001033sv000013E0sd00000261*
- ID_MODEL_FROM_DATABASE=IBM
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (IBM)
 
 pci:v000014F1d00001033sv000013E0sd00000290*
- ID_MODEL_FROM_DATABASE=Compaq Goldwing
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (Compaq Goldwing)
 
 pci:v000014F1d00001033sv000013E0sd000002A0*
- ID_MODEL_FROM_DATABASE=IBM
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (IBM)
 
 pci:v000014F1d00001033sv000013E0sd000002B0*
- ID_MODEL_FROM_DATABASE=IBM
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (IBM)
 
 pci:v000014F1d00001033sv000013E0sd000002C0*
- ID_MODEL_FROM_DATABASE=Compaq Scooter
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (Compaq Scooter)
 
 pci:v000014F1d00001033sv000013E0sd000002D0*
- ID_MODEL_FROM_DATABASE=IBM
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (IBM)
 
 pci:v000014F1d00001033sv0000144Fsd00001500*
- ID_MODEL_FROM_DATABASE=IBM P85-DF (1)
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (IBM P85-DF (1))
 
 pci:v000014F1d00001033sv0000144Fsd00001501*
- ID_MODEL_FROM_DATABASE=IBM P85-DF (2)
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (IBM P85-DF (2))
 
 pci:v000014F1d00001033sv0000144Fsd0000150A*
- ID_MODEL_FROM_DATABASE=IBM P85-DF (3)
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (IBM P85-DF (3))
 
 pci:v000014F1d00001033sv0000144Fsd0000150B*
- ID_MODEL_FROM_DATABASE=IBM P85-DF Low Profile (1)
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (IBM P85-DF Low Profile (1))
 
 pci:v000014F1d00001033sv0000144Fsd00001510*
- ID_MODEL_FROM_DATABASE=IBM P85-DF Low Profile (2)
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (IBM P85-DF Low Profile (2))
 
 pci:v000014F1d00001034*
  ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice Modem
@@ -45048,31 +46299,31 @@ pci:v000014F1d00001035*
  ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem
 
 pci:v000014F1d00001035sv000010CFsd00001098*
- ID_MODEL_FROM_DATABASE=Fujitsu P85-DFSV
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (Fujitsu P85-DFSV)
 
 pci:v000014F1d00001036*
  ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp Modem
 
 pci:v000014F1d00001036sv0000104Dsd00008067*
- ID_MODEL_FROM_DATABASE=HCF 56k Modem
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp Modem (HCF 56k Modem)
 
 pci:v000014F1d00001036sv0000122Dsd00004029*
- ID_MODEL_FROM_DATABASE=MDP3880SP-W
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp Modem (MDP3880SP-W)
 
 pci:v000014F1d00001036sv0000122Dsd00004031*
- ID_MODEL_FROM_DATABASE=MDP3880SP-U
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp Modem (MDP3880SP-U)
 
 pci:v000014F1d00001036sv000013E0sd00000209*
- ID_MODEL_FROM_DATABASE=Dell Titanium
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp Modem (Dell Titanium)
 
 pci:v000014F1d00001036sv000013E0sd0000020A*
- ID_MODEL_FROM_DATABASE=Dell Graphite
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp Modem (Dell Graphite)
 
 pci:v000014F1d00001036sv000013E0sd00000260*
- ID_MODEL_FROM_DATABASE=Gateway Red Owl
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp Modem (Gateway Red Owl)
 
 pci:v000014F1d00001036sv000013E0sd00000270*
- ID_MODEL_FROM_DATABASE=Gateway White Horse
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp Modem (Gateway White Horse)
 
 pci:v000014F1d00001052*
  ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (Worldwide)
@@ -45090,7 +46341,7 @@ pci:v000014F1d00001056*
  ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp Modem (Worldwide)
 
 pci:v000014F1d00001056sv0000122Dsd00004035*
- ID_MODEL_FROM_DATABASE=MDP3900V-W
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp Modem (Worldwide) (MDP3900V-W)
 
 pci:v000014F1d00001057*
  ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp Modem (Worldwide)
@@ -45111,7 +46362,7 @@ pci:v000014F1d00001066*
  ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp Modem
 
 pci:v000014F1d00001066sv0000122Dsd00004033*
- ID_MODEL_FROM_DATABASE=Dell Athena - MDP3900V-U
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp Modem (Dell Athena - MDP3900V-U)
 
 pci:v000014F1d00001085*
  ID_MODEL_FROM_DATABASE=HCF V90 56k Data/Fax/Voice/Spkp PCI Modem
@@ -45135,16 +46386,16 @@ pci:v000014F1d00001453*
  ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem
 
 pci:v000014F1d00001453sv000013E0sd00000240*
- ID_MODEL_FROM_DATABASE=IBM
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (IBM)
 
 pci:v000014F1d00001453sv000013E0sd00000250*
- ID_MODEL_FROM_DATABASE=IBM
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (IBM)
 
 pci:v000014F1d00001453sv0000144Fsd00001502*
- ID_MODEL_FROM_DATABASE=IBM P95-DF (1)
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (IBM P95-DF (1))
 
 pci:v000014F1d00001453sv0000144Fsd00001503*
- ID_MODEL_FROM_DATABASE=IBM P95-DF (2)
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax Modem (IBM P95-DF (2))
 
 pci:v000014F1d00001454*
  ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice Modem
@@ -45156,10 +46407,10 @@ pci:v000014F1d00001456*
  ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp Modem
 
 pci:v000014F1d00001456sv0000122Dsd00004035*
- ID_MODEL_FROM_DATABASE=Dell Europa - MDP3900V-W
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp Modem (Dell Europa - MDP3900V-W)
 
 pci:v000014F1d00001456sv0000122Dsd00004302*
- ID_MODEL_FROM_DATABASE=Dell MP3930V-W(C) MiniPCI
+ ID_MODEL_FROM_DATABASE=HCF 56k Data/Fax/Voice/Spkp Modem (Dell MP3930V-W(C) MiniPCI)
 
 pci:v000014F1d00001610*
  ID_MODEL_FROM_DATABASE=ADSL AccessRunner PCI Arbitration Device
@@ -45180,10 +46431,10 @@ pci:v000014F1d00001803*
  ID_MODEL_FROM_DATABASE=HCF 56k Modem
 
 pci:v000014F1d00001803sv00000E11sd00000023*
- ID_MODEL_FROM_DATABASE=623-LAN Grizzly
+ ID_MODEL_FROM_DATABASE=HCF 56k Modem (623-LAN Grizzly)
 
 pci:v000014F1d00001803sv00000E11sd00000043*
- ID_MODEL_FROM_DATABASE=623-LAN Yogi
+ ID_MODEL_FROM_DATABASE=HCF 56k Modem (623-LAN Yogi)
 
 pci:v000014F1d00001811*
  ID_MODEL_FROM_DATABASE=MiniPCI Network Adapter
@@ -45192,10 +46443,10 @@ pci:v000014F1d00001815*
  ID_MODEL_FROM_DATABASE=HCF 56k Modem
 
 pci:v000014F1d00001815sv00000E11sd00000022*
- ID_MODEL_FROM_DATABASE=Grizzly
+ ID_MODEL_FROM_DATABASE=HCF 56k Modem (Grizzly)
 
 pci:v000014F1d00001815sv00000E11sd00000042*
- ID_MODEL_FROM_DATABASE=Yogi
+ ID_MODEL_FROM_DATABASE=HCF 56k Modem (Yogi)
 
 pci:v000014F1d00002003*
  ID_MODEL_FROM_DATABASE=HSF 56k Data/Fax Modem
@@ -45213,28 +46464,28 @@ pci:v000014F1d00002013*
  ID_MODEL_FROM_DATABASE=HSF 56k Data/Fax Modem
 
 pci:v000014F1d00002013sv00000E11sd0000B195*
- ID_MODEL_FROM_DATABASE=Bear
+ ID_MODEL_FROM_DATABASE=HSF 56k Data/Fax Modem (Bear)
 
 pci:v000014F1d00002013sv00000E11sd0000B196*
- ID_MODEL_FROM_DATABASE=Seminole 1
+ ID_MODEL_FROM_DATABASE=HSF 56k Data/Fax Modem (Seminole 1)
 
 pci:v000014F1d00002013sv00000E11sd0000B1BE*
- ID_MODEL_FROM_DATABASE=Seminole 2
+ ID_MODEL_FROM_DATABASE=HSF 56k Data/Fax Modem (Seminole 2)
 
 pci:v000014F1d00002013sv00001025sd00008013*
- ID_MODEL_FROM_DATABASE=Acer
+ ID_MODEL_FROM_DATABASE=HSF 56k Data/Fax Modem (Acer)
 
 pci:v000014F1d00002013sv00001033sd0000809D*
- ID_MODEL_FROM_DATABASE=NEC
+ ID_MODEL_FROM_DATABASE=HSF 56k Data/Fax Modem (NEC)
 
 pci:v000014F1d00002013sv00001033sd000080BC*
- ID_MODEL_FROM_DATABASE=NEC
+ ID_MODEL_FROM_DATABASE=HSF 56k Data/Fax Modem (NEC)
 
 pci:v000014F1d00002013sv0000155Dsd00006793*
- ID_MODEL_FROM_DATABASE=HP
+ ID_MODEL_FROM_DATABASE=HSF 56k Data/Fax Modem (HP)
 
 pci:v000014F1d00002013sv0000155Dsd00008850*
- ID_MODEL_FROM_DATABASE=E Machines
+ ID_MODEL_FROM_DATABASE=HSF 56k Data/Fax Modem (E Machines)
 
 pci:v000014F1d00002014*
  ID_MODEL_FROM_DATABASE=HSF 56k Data/Fax/Voice Modem
@@ -45255,7 +46506,7 @@ pci:v000014F1d00002045*
  ID_MODEL_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (WorldW SmartDAA)
 
 pci:v000014F1d00002045sv000014F1sd00002045*
- ID_MODEL_FROM_DATABASE=Generic SoftK56
+ ID_MODEL_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (WorldW SmartDAA) (Generic SoftK56)
 
 pci:v000014F1d00002046*
  ID_MODEL_FROM_DATABASE=HSF 56k Data/Fax/Voice/Spkp Modem (WorldW SmartDAA)
@@ -45276,7 +46527,7 @@ pci:v000014F1d00002093*
  ID_MODEL_FROM_DATABASE=HSF 56k Modem
 
 pci:v000014F1d00002093sv0000155Dsd00002F07*
- ID_MODEL_FROM_DATABASE=Legend
+ ID_MODEL_FROM_DATABASE=HSF 56k Modem (Legend)
 
 pci:v000014F1d00002143*
  ID_MODEL_FROM_DATABASE=HSF 56k Data/Fax/Cell Modem (Mob WorldW SmartDAA)
@@ -45330,13 +46581,13 @@ pci:v000014F1d00002443*
  ID_MODEL_FROM_DATABASE=HSF 56k Data/Fax Modem (Mob WorldW SmartDAA)
 
 pci:v000014F1d00002443sv0000104Dsd00008075*
- ID_MODEL_FROM_DATABASE=Modem
+ ID_MODEL_FROM_DATABASE=HSF 56k Data/Fax Modem (Mob WorldW SmartDAA) (Modem)
 
 pci:v000014F1d00002443sv0000104Dsd00008083*
- ID_MODEL_FROM_DATABASE=Modem
+ ID_MODEL_FROM_DATABASE=HSF 56k Data/Fax Modem (Mob WorldW SmartDAA) (Modem)
 
 pci:v000014F1d00002443sv0000104Dsd00008097*
- ID_MODEL_FROM_DATABASE=Modem
+ ID_MODEL_FROM_DATABASE=HSF 56k Data/Fax Modem (Mob WorldW SmartDAA) (Modem)
 
 pci:v000014F1d00002444*
  ID_MODEL_FROM_DATABASE=HSF 56k Data/Fax/Voice Modem (Mob WorldW SmartDAA)
@@ -45363,13 +46614,13 @@ pci:v000014F1d00002F00*
  ID_MODEL_FROM_DATABASE=HSF 56k HSFi Modem
 
 pci:v000014F1d00002F00sv000013E0sd00008D84*
- ID_MODEL_FROM_DATABASE=IBM HSFi V.90
+ ID_MODEL_FROM_DATABASE=HSF 56k HSFi Modem (IBM HSFi V.90)
 
 pci:v000014F1d00002F00sv000013E0sd00008D85*
- ID_MODEL_FROM_DATABASE=Compaq Stinger
+ ID_MODEL_FROM_DATABASE=HSF 56k HSFi Modem (Compaq Stinger)
 
 pci:v000014F1d00002F00sv000014F1sd00002004*
- ID_MODEL_FROM_DATABASE=Dynalink 56PMi
+ ID_MODEL_FROM_DATABASE=HSF 56k HSFi Modem (Dynalink 56PMi)
 
 pci:v000014F1d00002F02*
  ID_MODEL_FROM_DATABASE=HSF 56k HSFi Data/Fax
@@ -45381,16 +46632,16 @@ pci:v000014F1d00002F20*
  ID_MODEL_FROM_DATABASE=HSF 56k Data/Fax Modem
 
 pci:v000014F1d00002F20sv000014F1sd0000200C*
- ID_MODEL_FROM_DATABASE=Soft Data Fax Modem with SmartCP
+ ID_MODEL_FROM_DATABASE=HSF 56k Data/Fax Modem (Soft Data Fax Modem with SmartCP)
 
 pci:v000014F1d00002F20sv000014F1sd0000200F*
- ID_MODEL_FROM_DATABASE=Dimension 3000
+ ID_MODEL_FROM_DATABASE=HSF 56k Data/Fax Modem (Dimension 3000)
 
 pci:v000014F1d00002F30*
  ID_MODEL_FROM_DATABASE=SoftV92 SpeakerPhone SoftRing Modem with SmartSP
 
 pci:v000014F1d00002F30sv000014F1sd00002014*
- ID_MODEL_FROM_DATABASE=Devolo MikroLink 56K Modem PCI
+ ID_MODEL_FROM_DATABASE=SoftV92 SpeakerPhone SoftRing Modem with SmartSP (Devolo MikroLink 56K Modem PCI)
 
 pci:v000014F1d00002F50*
  ID_MODEL_FROM_DATABASE=Conexant SoftK56 Data/Fax Modem
@@ -45399,13 +46650,13 @@ pci:v000014F1d00005B7A*
  ID_MODEL_FROM_DATABASE=CX23418 Single-Chip MPEG-2 Encoder with Integrated Analog Video/Broadcast Audio Decoder
 
 pci:v000014F1d00005B7Asv00000070sd00007444*
- ID_MODEL_FROM_DATABASE=WinTV HVR-1600
+ ID_MODEL_FROM_DATABASE=CX23418 Single-Chip MPEG-2 Encoder with Integrated Analog Video/Broadcast Audio Decoder (WinTV HVR-1600)
 
 pci:v000014F1d00005B7Asv0000107Dsd00006F34*
- ID_MODEL_FROM_DATABASE=WinFast DVR3100 H
+ ID_MODEL_FROM_DATABASE=CX23418 Single-Chip MPEG-2 Encoder with Integrated Analog Video/Broadcast Audio Decoder (WinFast DVR3100 H)
 
 pci:v000014F1d00005B7Asv00005854sd00003343*
- ID_MODEL_FROM_DATABASE=GoTView PCI DVD3 Hybrid
+ ID_MODEL_FROM_DATABASE=CX23418 Single-Chip MPEG-2 Encoder with Integrated Analog Video/Broadcast Audio Decoder (GoTView PCI DVD3 Hybrid)
 
 pci:v000014F1d00008200*
  ID_MODEL_FROM_DATABASE=CX25850
@@ -45417,304 +46668,310 @@ pci:v000014F1d00008800*
  ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder
 
 pci:v000014F1d00008800sv00000070sd00002801*
- ID_MODEL_FROM_DATABASE=Hauppauge WinTV 28xxx (Roslyn) models
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (Hauppauge WinTV 28xxx (Roslyn) models)
 
 pci:v000014F1d00008800sv00000070sd00003400*
- ID_MODEL_FROM_DATABASE=WinTV 34604
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (WinTV 34604)
 
 pci:v000014F1d00008800sv00000070sd00003401*
- ID_MODEL_FROM_DATABASE=Hauppauge WinTV 34xxx models
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (Hauppauge WinTV 34xxx models)
 
 pci:v000014F1d00008800sv00000070sd00006902*
- ID_MODEL_FROM_DATABASE=WinTV HVR-4000-HD
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (WinTV HVR-4000-HD)
 
 pci:v000014F1d00008800sv00000070sd00007801*
- ID_MODEL_FROM_DATABASE=WinTV HVR-1800 MCE
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (WinTV HVR-1800 MCE)
 
 pci:v000014F1d00008800sv00000070sd00009001*
- ID_MODEL_FROM_DATABASE=Nova-T DVB-T
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (Nova-T DVB-T)
 
 pci:v000014F1d00008800sv00000070sd00009200*
- ID_MODEL_FROM_DATABASE=Nova-SE2 DVB-S
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (Nova-SE2 DVB-S)
 
 pci:v000014F1d00008800sv00000070sd00009202*
- ID_MODEL_FROM_DATABASE=Nova-S-Plus DVB-S
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (Nova-S-Plus DVB-S)
 
 pci:v000014F1d00008800sv00000070sd00009402*
- ID_MODEL_FROM_DATABASE=WinTV-HVR1100 DVB-T/Hybrid
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (WinTV-HVR1100 DVB-T/Hybrid)
 
 pci:v000014F1d00008800sv00000070sd00009600*
- ID_MODEL_FROM_DATABASE=WinTV 88x Video
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (WinTV 88x Video)
 
 pci:v000014F1d00008800sv00000070sd00009802*
- ID_MODEL_FROM_DATABASE=WinTV-HVR1100 DVB-T/Hybrid (Low Profile)
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (WinTV-HVR1100 DVB-T/Hybrid (Low Profile))
 
 pci:v000014F1d00008800sv00001002sd000000F8*
- ID_MODEL_FROM_DATABASE=ATI TV Wonder Pro
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (ATI TV Wonder Pro)
+
+pci:v000014F1d00008800sv00001002sd000000F9*
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (ATI TV Wonder)
 
 pci:v000014F1d00008800sv00001002sd0000A101*
- ID_MODEL_FROM_DATABASE=HDTV Wonder
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (HDTV Wonder)
 
 pci:v000014F1d00008800sv00001043sd00004823*
- ID_MODEL_FROM_DATABASE=ASUS PVR-416
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (ASUS PVR-416)
 
 pci:v000014F1d00008800sv0000107Dsd00006611*
- ID_MODEL_FROM_DATABASE=Winfast TV 2000XP Expert
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (Winfast TV 2000XP Expert)
 
 pci:v000014F1d00008800sv0000107Dsd00006613*
- ID_MODEL_FROM_DATABASE=Leadtek Winfast 2000XP Expert
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (Leadtek Winfast 2000XP Expert)
 
 pci:v000014F1d00008800sv0000107Dsd00006620*
- ID_MODEL_FROM_DATABASE=Leadtek Winfast DV2000
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (Leadtek Winfast DV2000)
 
 pci:v000014F1d00008800sv0000107Dsd0000663C*
- ID_MODEL_FROM_DATABASE=Leadtek PVR 2000
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (Leadtek PVR 2000)
 
 pci:v000014F1d00008800sv0000107Dsd0000665F*
- ID_MODEL_FROM_DATABASE=WinFast DTV1000-T
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (WinFast DTV1000-T)
 
 pci:v000014F1d00008800sv000010FCsd0000D003*
- ID_MODEL_FROM_DATABASE=IODATA GV-VCP3/PCI
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (IODATA GV-VCP3/PCI)
 
 pci:v000014F1d00008800sv000010FCsd0000D035*
- ID_MODEL_FROM_DATABASE=IODATA GV/BCTV7E
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (IODATA GV/BCTV7E)
 
 pci:v000014F1d00008800sv00001421sd00000334*
- ID_MODEL_FROM_DATABASE=Instant TV DVB-T PCI
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (Instant TV DVB-T PCI)
 
 pci:v000014F1d00008800sv00001461sd0000000A*
- ID_MODEL_FROM_DATABASE=AVerTV 303 (M126)
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (AVerTV 303 (M126))
 
 pci:v000014F1d00008800sv00001461sd0000000B*
- ID_MODEL_FROM_DATABASE=AverTV Studio 303 (M126)
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (AverTV Studio 303 (M126))
 
 pci:v000014F1d00008800sv00001461sd00008011*
- ID_MODEL_FROM_DATABASE=UltraTV Media Center PCI 550
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (UltraTV Media Center PCI 550)
 
 pci:v000014F1d00008800sv00001462sd00008606*
- ID_MODEL_FROM_DATABASE=MSI TV-@nywhere Master
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (MSI TV-@nywhere Master)
 
 pci:v000014F1d00008800sv000014C7sd00000107*
- ID_MODEL_FROM_DATABASE=GDI Black Gold
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (GDI Black Gold)
 
 pci:v000014F1d00008800sv000014F1sd00000187*
- ID_MODEL_FROM_DATABASE=Conexant DVB-T reference design
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (Conexant DVB-T reference design)
 
 pci:v000014F1d00008800sv000014F1sd00000342*
- ID_MODEL_FROM_DATABASE=Digital-Logic MICROSPACE Entertainment Center (MEC)
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (Digital-Logic MICROSPACE Entertainment Center (MEC))
 
 pci:v000014F1d00008800sv0000153Bsd00001166*
- ID_MODEL_FROM_DATABASE=Cinergy 1400 DVB-T
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (Cinergy 1400 DVB-T)
 
 pci:v000014F1d00008800sv00001540sd00002580*
- ID_MODEL_FROM_DATABASE=Provideo PV259
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (Provideo PV259)
 
 pci:v000014F1d00008800sv00001554sd00004811*
- ID_MODEL_FROM_DATABASE=PixelView
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (PixelView)
 
 pci:v000014F1d00008800sv00001554sd00004813*
- ID_MODEL_FROM_DATABASE=Club 3D  ZAP1000 MCE Edition
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (Club 3D  ZAP1000 MCE Edition)
 
 pci:v000014F1d00008800sv000017DEsd000008A1*
- ID_MODEL_FROM_DATABASE=KWorld/VStream XPert DVB-T with cx22702
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (KWorld/VStream XPert DVB-T with cx22702)
 
 pci:v000014F1d00008800sv000017DEsd000008A6*
- ID_MODEL_FROM_DATABASE=KWorld/VStream XPert DVB-T
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (KWorld/VStream XPert DVB-T)
 
 pci:v000014F1d00008800sv000017DEsd000008B2*
- ID_MODEL_FROM_DATABASE=KWorld DVB-S 100
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (KWorld DVB-S 100)
 
 pci:v000014F1d00008800sv000017DEsd0000A8A6*
- ID_MODEL_FROM_DATABASE=digitalnow DNTV Live! DVB-T
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (digitalnow DNTV Live! DVB-T)
 
 pci:v000014F1d00008800sv00001822sd00000025*
- ID_MODEL_FROM_DATABASE=digitalnow DNTV Live! DVB-T Pro
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (digitalnow DNTV Live! DVB-T Pro)
 
 pci:v000014F1d00008800sv0000185Bsd0000E000*
- ID_MODEL_FROM_DATABASE=VideoMate X500
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (VideoMate X500)
 
 pci:v000014F1d00008800sv000018ACsd0000D500*
- ID_MODEL_FROM_DATABASE=FusionHDTV 5 Gold
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (FusionHDTV 5 Gold)
 
 pci:v000014F1d00008800sv000018ACsd0000D810*
- ID_MODEL_FROM_DATABASE=FusionHDTV 3 Gold-Q
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (FusionHDTV 3 Gold-Q)
 
 pci:v000014F1d00008800sv000018ACsd0000D820*
- ID_MODEL_FROM_DATABASE=FusionHDTV 3 Gold-T
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (FusionHDTV 3 Gold-T)
 
 pci:v000014F1d00008800sv000018ACsd0000DB00*
- ID_MODEL_FROM_DATABASE=FusionHDTV DVB-T1
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (FusionHDTV DVB-T1)
 
 pci:v000014F1d00008800sv000018ACsd0000DB11*
- ID_MODEL_FROM_DATABASE=FusionHDTV DVB-T Plus
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (FusionHDTV DVB-T Plus)
 
 pci:v000014F1d00008800sv000018ACsd0000DB50*
- ID_MODEL_FROM_DATABASE=FusionHDTV DVB-T Dual Digital
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (FusionHDTV DVB-T Dual Digital)
 
 pci:v000014F1d00008800sv00005654sd00002388*
- ID_MODEL_FROM_DATABASE=GoTView PCI Hybrid TV Tuner Card
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (GoTView PCI Hybrid TV Tuner Card)
 
 pci:v000014F1d00008800sv00007063sd00003000*
- ID_MODEL_FROM_DATABASE=pcHDTV HD3000 HDTV
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (pcHDTV HD3000 HDTV)
 
 pci:v000014F1d00008800sv00007063sd00005500*
- ID_MODEL_FROM_DATABASE=pcHDTV HD-5500
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (pcHDTV HD-5500)
 
 pci:v000014F1d00008801*
  ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [Audio Port]
 
 pci:v000014F1d00008801sv00000070sd00002801*
- ID_MODEL_FROM_DATABASE=Hauppauge WinTV 28xxx (Roslyn) models
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [Audio Port] (Hauppauge WinTV 28xxx (Roslyn) models)
 
 pci:v000014F1d00008801sv0000185Bsd0000E000*
- ID_MODEL_FROM_DATABASE=VideoMate X500
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [Audio Port] (VideoMate X500)
 
 pci:v000014F1d00008801sv00005654sd00002388*
- ID_MODEL_FROM_DATABASE=GoTView PCI Hybrid Audio AVStream Device
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [Audio Port] (GoTView PCI Hybrid Audio AVStream Device)
 
 pci:v000014F1d00008801sv00007063sd00005500*
- ID_MODEL_FROM_DATABASE=pcHDTV HD-5500
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [Audio Port] (pcHDTV HD-5500)
 
 pci:v000014F1d00008802*
  ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [MPEG Port]
 
 pci:v000014F1d00008802sv00000070sd00002801*
- ID_MODEL_FROM_DATABASE=Hauppauge WinTV 28xxx (Roslyn) models
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [MPEG Port] (Hauppauge WinTV 28xxx (Roslyn) models)
 
 pci:v000014F1d00008802sv00000070sd00006902*
- ID_MODEL_FROM_DATABASE=WinTV HVR-4000-HD
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [MPEG Port] (WinTV HVR-4000-HD)
 
 pci:v000014F1d00008802sv00000070sd00009002*
- ID_MODEL_FROM_DATABASE=Nova-T DVB-T Model 909
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [MPEG Port] (Nova-T DVB-T Model 909)
 
 pci:v000014F1d00008802sv00000070sd00009402*
- ID_MODEL_FROM_DATABASE=WinTV-HVR1100 DVB-T/Hybrid
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [MPEG Port] (WinTV-HVR1100 DVB-T/Hybrid)
 
 pci:v000014F1d00008802sv00000070sd00009600*
- ID_MODEL_FROM_DATABASE=WinTV 88x MPEG Encoder
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [MPEG Port] (WinTV 88x MPEG Encoder)
 
 pci:v000014F1d00008802sv00001043sd00004823*
- ID_MODEL_FROM_DATABASE=ASUS PVR-416
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [MPEG Port] (ASUS PVR-416)
 
 pci:v000014F1d00008802sv0000107Dsd0000663C*
- ID_MODEL_FROM_DATABASE=Leadtek PVR 2000
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [MPEG Port] (Leadtek PVR 2000)
 
 pci:v000014F1d00008802sv0000107Dsd0000665F*
- ID_MODEL_FROM_DATABASE=WinFast DTV1000-T
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [MPEG Port] (WinFast DTV1000-T)
 
 pci:v000014F1d00008802sv000014F1sd00000187*
- ID_MODEL_FROM_DATABASE=Conexant DVB-T reference design
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [MPEG Port] (Conexant DVB-T reference design)
 
 pci:v000014F1d00008802sv000017DEsd000008A1*
- ID_MODEL_FROM_DATABASE=XPert DVB-T PCI BDA DVBT 23880 Transport Stream Capture
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [MPEG Port] (XPert DVB-T PCI BDA DVBT 23880 Transport Stream Capture)
 
 pci:v000014F1d00008802sv000017DEsd000008A6*
- ID_MODEL_FROM_DATABASE=KWorld/VStream XPert DVB-T
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [MPEG Port] (KWorld/VStream XPert DVB-T)
 
 pci:v000014F1d00008802sv000018ACsd0000D500*
- ID_MODEL_FROM_DATABASE=DViCO FusionHDTV5 Gold
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [MPEG Port] (DViCO FusionHDTV5 Gold)
 
 pci:v000014F1d00008802sv000018ACsd0000D810*
- ID_MODEL_FROM_DATABASE=DViCO FusionHDTV3 Gold-Q
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [MPEG Port] (DViCO FusionHDTV3 Gold-Q)
 
 pci:v000014F1d00008802sv000018ACsd0000D820*
- ID_MODEL_FROM_DATABASE=DViCO FusionHDTV3 Gold-T
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [MPEG Port] (DViCO FusionHDTV3 Gold-T)
 
 pci:v000014F1d00008802sv000018ACsd0000DB00*
- ID_MODEL_FROM_DATABASE=DVICO FusionHDTV DVB-T1
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [MPEG Port] (DVICO FusionHDTV DVB-T1)
 
 pci:v000014F1d00008802sv000018ACsd0000DB10*
- ID_MODEL_FROM_DATABASE=DVICO FusionHDTV DVB-T Plus
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [MPEG Port] (DVICO FusionHDTV DVB-T Plus)
 
 pci:v000014F1d00008802sv00005654sd00002388*
- ID_MODEL_FROM_DATABASE=GoTView PCI Hybrid TS Capture Device
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [MPEG Port] (GoTView PCI Hybrid TS Capture Device)
 
 pci:v000014F1d00008802sv00007063sd00003000*
- ID_MODEL_FROM_DATABASE=pcHDTV HD3000 HDTV
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [MPEG Port] (pcHDTV HD3000 HDTV)
 
 pci:v000014F1d00008802sv00007063sd00005500*
- ID_MODEL_FROM_DATABASE=pcHDTV HD-5500
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [MPEG Port] (pcHDTV HD-5500)
 
 pci:v000014F1d00008804*
  ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [IR Port]
 
 pci:v000014F1d00008804sv00000070sd00006902*
- ID_MODEL_FROM_DATABASE=WinTV HVR-4000-HD
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [IR Port] (WinTV HVR-4000-HD)
 
 pci:v000014F1d00008804sv00000070sd00009002*
- ID_MODEL_FROM_DATABASE=Nova-T DVB-T Model 909
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [IR Port] (Nova-T DVB-T Model 909)
 
 pci:v000014F1d00008804sv00000070sd00009402*
- ID_MODEL_FROM_DATABASE=WinTV-HVR1100 DVB-T/Hybrid
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [IR Port] (WinTV-HVR1100 DVB-T/Hybrid)
 
 pci:v000014F1d00008804sv00007063sd00005500*
- ID_MODEL_FROM_DATABASE=pcHDTV HD-5500
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [IR Port] (pcHDTV HD-5500)
 
 pci:v000014F1d00008811*
  ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [Audio Port]
 
 pci:v000014F1d00008811sv00000070sd00003400*
- ID_MODEL_FROM_DATABASE=WinTV 34604
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [Audio Port] (WinTV 34604)
 
 pci:v000014F1d00008811sv00000070sd00003401*
- ID_MODEL_FROM_DATABASE=Hauppauge WinTV 34xxx models
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [Audio Port] (Hauppauge WinTV 34xxx models)
 
 pci:v000014F1d00008811sv00000070sd00006902*
- ID_MODEL_FROM_DATABASE=WinTV HVR-4000-HD
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [Audio Port] (WinTV HVR-4000-HD)
 
 pci:v000014F1d00008811sv00000070sd00009402*
- ID_MODEL_FROM_DATABASE=WinTV-HVR1100 DVB-T/Hybrid
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [Audio Port] (WinTV-HVR1100 DVB-T/Hybrid)
 
 pci:v000014F1d00008811sv00000070sd00009600*
- ID_MODEL_FROM_DATABASE=WinTV 88x Audio
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [Audio Port] (WinTV 88x Audio)
 
 pci:v000014F1d00008811sv00001462sd00008606*
- ID_MODEL_FROM_DATABASE=MSI TV-@nywhere Master
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [Audio Port] (MSI TV-@nywhere Master)
 
 pci:v000014F1d00008811sv000018ACsd0000D500*
- ID_MODEL_FROM_DATABASE=DViCO FusionHDTV5 Gold
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [Audio Port] (DViCO FusionHDTV5 Gold)
 
 pci:v000014F1d00008811sv000018ACsd0000D810*
- ID_MODEL_FROM_DATABASE=DViCO FusionHDTV3 Gold-Q
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [Audio Port] (DViCO FusionHDTV3 Gold-Q)
 
 pci:v000014F1d00008811sv000018ACsd0000D820*
- ID_MODEL_FROM_DATABASE=DViCO FusionHDTV3 Gold-T
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [Audio Port] (DViCO FusionHDTV3 Gold-T)
 
 pci:v000014F1d00008811sv000018ACsd0000DB00*
- ID_MODEL_FROM_DATABASE=DVICO FusionHDTV DVB-T1
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [Audio Port] (DVICO FusionHDTV DVB-T1)
 
 pci:v000014F1d00008811sv00005654sd00002388*
- ID_MODEL_FROM_DATABASE=GoTView PCI Hybrid Audio Capture Device
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [Audio Port] (GoTView PCI Hybrid Audio Capture Device)
 
 pci:v000014F1d00008852*
  ID_MODEL_FROM_DATABASE=CX23885 PCI Video and Audio Decoder
 
 pci:v000014F1d00008852sv00000070sd00008010*
- ID_MODEL_FROM_DATABASE=Hauppauge WinTV HVR-1400 ExpressCard
+ ID_MODEL_FROM_DATABASE=CX23885 PCI Video and Audio Decoder (WinTV HVR-1400 ExpressCard)
 
 pci:v000014F1d00008852sv0000107Dsd00006F22*
- ID_MODEL_FROM_DATABASE=WinFast PxTV1200
+ ID_MODEL_FROM_DATABASE=CX23885 PCI Video and Audio Decoder (WinFast PxTV1200)
 
 pci:v000014F1d00008852sv00001461sd0000C039*
- ID_MODEL_FROM_DATABASE=AVerTV Hybrid Express (A577)
+ ID_MODEL_FROM_DATABASE=CX23885 PCI Video and Audio Decoder (AVerTV Hybrid Express (A577))
 
 pci:v000014F1d00008852sv0000153Bsd0000117E*
- ID_MODEL_FROM_DATABASE=Cinergy T PCIe Dual
+ ID_MODEL_FROM_DATABASE=CX23885 PCI Video and Audio Decoder (Cinergy T PCIe Dual)
 
 pci:v000014F1d00008852sv000018ACsd0000DB78*
- ID_MODEL_FROM_DATABASE=FusionHDTV DVB-T Dual Express
+ ID_MODEL_FROM_DATABASE=CX23885 PCI Video and Audio Decoder (FusionHDTV DVB-T Dual Express)
+
+pci:v000014F1d00008852sv00004254sd00009580*
+ ID_MODEL_FROM_DATABASE=CX23885 PCI Video and Audio Decoder (T9580)
 
 pci:v000014F1d00008880*
  ID_MODEL_FROM_DATABASE=CX23887/8 PCIe Broadcast Audio and Video Decoder with 3D Comb
 
 pci:v000014F1d00008880sv00000070sd0000C108*
- ID_MODEL_FROM_DATABASE=WinTV-HVR-4400-HD model 1278
+ ID_MODEL_FROM_DATABASE=CX23887/8 PCIe Broadcast Audio and Video Decoder with 3D Comb (WinTV-HVR-4400-HD model 1278)
 
 pci:v000014F1d00008880sv00005654sd00002389*
- ID_MODEL_FROM_DATABASE=GoTView X5 DVD Hybrid PCI-E
+ ID_MODEL_FROM_DATABASE=CX23887/8 PCIe Broadcast Audio and Video Decoder with 3D Comb (GoTView X5 DVD Hybrid PCI-E)
 
 pci:v000014F1d00008880sv00005654sd00002390*
- ID_MODEL_FROM_DATABASE=GoTView X5 3D HYBRID PCI-E
+ ID_MODEL_FROM_DATABASE=CX23887/8 PCIe Broadcast Audio and Video Decoder with 3D Comb (GoTView X5 3D HYBRID PCI-E)
 
 pci:v000014F2*
  ID_VENDOR_FROM_DATABASE=MOBILITY Electronics
@@ -45966,100 +47223,100 @@ pci:v00001522d00000100*
  ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge
 
 pci:v00001522d00000100sv00001522sd00000200*
- ID_MODEL_FROM_DATABASE=RockForceDUO 2 Port V.92/V.44 Data/Fax/Voice Modem
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (RockForceDUO 2 Port V.92/V.44 Data/Fax/Voice Modem)
 
 pci:v00001522d00000100sv00001522sd00000300*
- ID_MODEL_FROM_DATABASE=RockForceQUATRO 4 Port V.92/V.44 Data/Fax/Voice Modem
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (RockForceQUATRO 4 Port V.92/V.44 Data/Fax/Voice Modem)
 
 pci:v00001522d00000100sv00001522sd00000400*
- ID_MODEL_FROM_DATABASE=RockForceDUO+ 2 Port V.92/V.44 Data/Fax/Voice Modem
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (RockForceDUO+ 2 Port V.92/V.44 Data/Fax/Voice Modem)
 
 pci:v00001522d00000100sv00001522sd00000500*
- ID_MODEL_FROM_DATABASE=RockForceQUATRO+ 4 Port V.92/V.44 Data/Fax/Voice Modem
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (RockForceQUATRO+ 4 Port V.92/V.44 Data/Fax/Voice Modem)
 
 pci:v00001522d00000100sv00001522sd00000600*
- ID_MODEL_FROM_DATABASE=RockForce+ 2 Port V.90 Data/Fax/Voice Modem
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (RockForce+ 2 Port V.90 Data/Fax/Voice Modem)
 
 pci:v00001522d00000100sv00001522sd00000700*
- ID_MODEL_FROM_DATABASE=RockForce+ 4 Port V.90 Data/Fax/Voice Modem
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (RockForce+ 4 Port V.90 Data/Fax/Voice Modem)
 
 pci:v00001522d00000100sv00001522sd00000800*
- ID_MODEL_FROM_DATABASE=RockForceOCTO+ 8 Port V.92/V.44 Data/Fax/Voice Modem
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (RockForceOCTO+ 8 Port V.92/V.44 Data/Fax/Voice Modem)
 
 pci:v00001522d00000100sv00001522sd00000C00*
- ID_MODEL_FROM_DATABASE=RockForceDUO+ 2 Port V.92/V.44 Data, V.34 Super-G3 Fax, Voice Modem
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (RockForceDUO+ 2 Port V.92/V.44 Data, V.34 Super-G3 Fax, Voice Modem)
 
 pci:v00001522d00000100sv00001522sd00000D00*
- ID_MODEL_FROM_DATABASE=RockForceQUATRO+ 4 Port V.92/V.44 Data, V.34 Super-G3 Fax, Voice Modem
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (RockForceQUATRO+ 4 Port V.92/V.44 Data, V.34 Super-G3 Fax, Voice Modem)
 
 pci:v00001522d00000100sv00001522sd00001D00*
- ID_MODEL_FROM_DATABASE=RockForceOCTO+ 8 Port V.92/V.44 Data, V.34 Super-G3 Fax, Voice Modem
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (RockForceOCTO+ 8 Port V.92/V.44 Data, V.34 Super-G3 Fax, Voice Modem)
 
 pci:v00001522d00000100sv00001522sd00002000*
- ID_MODEL_FROM_DATABASE=RockForceD1 1 Port V.90 Data Modem
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (RockForceD1 1 Port V.90 Data Modem)
 
 pci:v00001522d00000100sv00001522sd00002100*
- ID_MODEL_FROM_DATABASE=RockForceF1 1 Port V.34 Super-G3 Fax Modem
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (RockForceF1 1 Port V.34 Super-G3 Fax Modem)
 
 pci:v00001522d00000100sv00001522sd00002200*
- ID_MODEL_FROM_DATABASE=RockForceD2 2 Port V.90 Data Modem
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (RockForceD2 2 Port V.90 Data Modem)
 
 pci:v00001522d00000100sv00001522sd00002300*
- ID_MODEL_FROM_DATABASE=RockForceF2 2 Port V.34 Super-G3 Fax Modem
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (RockForceF2 2 Port V.34 Super-G3 Fax Modem)
 
 pci:v00001522d00000100sv00001522sd00002400*
- ID_MODEL_FROM_DATABASE=RockForceD4 4 Port V.90 Data Modem
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (RockForceD4 4 Port V.90 Data Modem)
 
 pci:v00001522d00000100sv00001522sd00002500*
- ID_MODEL_FROM_DATABASE=RockForceF4 4 Port V.34 Super-G3 Fax Modem
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (RockForceF4 4 Port V.34 Super-G3 Fax Modem)
 
 pci:v00001522d00000100sv00001522sd00002600*
- ID_MODEL_FROM_DATABASE=RockForceD8 8 Port V.90 Data Modem
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (RockForceD8 8 Port V.90 Data Modem)
 
 pci:v00001522d00000100sv00001522sd00002700*
- ID_MODEL_FROM_DATABASE=RockForceF8 8 Port V.34 Super-G3 Fax Modem
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (RockForceF8 8 Port V.34 Super-G3 Fax Modem)
 
 pci:v00001522d00000100sv00001522sd00003000*
- ID_MODEL_FROM_DATABASE=IQ Express D1 - 1 Port V.92 Data Modem
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (IQ Express D1 - 1 Port V.92 Data Modem)
 
 pci:v00001522d00000100sv00001522sd00003100*
- ID_MODEL_FROM_DATABASE=IQ Express F1 - 1 Port V.34 Super-G3 Fax Modem
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (IQ Express F1 - 1 Port V.34 Super-G3 Fax Modem)
 
 pci:v00001522d00000100sv00001522sd00003200*
- ID_MODEL_FROM_DATABASE=IQ Express D2 - 2 Port V.92 Data Modem
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (IQ Express D2 - 2 Port V.92 Data Modem)
 
 pci:v00001522d00000100sv00001522sd00003300*
- ID_MODEL_FROM_DATABASE=IQ Express F2 - 2 Port V.34 Super-G3 Fax Modem
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (IQ Express F2 - 2 Port V.34 Super-G3 Fax Modem)
 
 pci:v00001522d00000100sv00001522sd00003400*
- ID_MODEL_FROM_DATABASE=IQ Express D4 - 4 Port V.92 Data Modem
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (IQ Express D4 - 4 Port V.92 Data Modem)
 
 pci:v00001522d00000100sv00001522sd00003500*
- ID_MODEL_FROM_DATABASE=IQ Express F4 - 4 Port V.34 Super-G3 Fax Modem
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (IQ Express F4 - 4 Port V.34 Super-G3 Fax Modem)
 
 pci:v00001522d00000100sv00001522sd00003C00*
- ID_MODEL_FROM_DATABASE=IQ Express D8 - 8 Port V.92 Data Modem
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (IQ Express D8 - 8 Port V.92 Data Modem)
 
 pci:v00001522d00000100sv00001522sd00003D00*
- ID_MODEL_FROM_DATABASE=IQ Express F8 - 8 Port V.34 Super-G3 Fax Modem
+ ID_MODEL_FROM_DATABASE=PCI <-> IOBus Bridge (IQ Express F8 - 8 Port V.34 Super-G3 Fax Modem)
 
 pci:v00001522d00004000*
  ID_MODEL_FROM_DATABASE=PCI Express UART
 
 pci:v00001522d00004000sv00001522sd00004001*
- ID_MODEL_FROM_DATABASE=IQ Express 1-port V.34 Super-G3 Fax
+ ID_MODEL_FROM_DATABASE=PCI Express UART (IQ Express 1-port V.34 Super-G3 Fax)
 
 pci:v00001522d00004000sv00001522sd00004002*
- ID_MODEL_FROM_DATABASE=IQ Express 2-port V.34 Super-G3 Fax
+ ID_MODEL_FROM_DATABASE=PCI Express UART (IQ Express 2-port V.34 Super-G3 Fax)
 
 pci:v00001522d00004000sv00001522sd00004004*
- ID_MODEL_FROM_DATABASE=IQ Express 4-port V.34 Super-G3 Fax
+ ID_MODEL_FROM_DATABASE=PCI Express UART (IQ Express 4-port V.34 Super-G3 Fax)
 
 pci:v00001522d00004000sv00001522sd00004008*
- ID_MODEL_FROM_DATABASE=IQ Express 8-port V.34 Super-G3 Fax
+ ID_MODEL_FROM_DATABASE=PCI Express UART (IQ Express 8-port V.34 Super-G3 Fax)
 
 pci:v00001522d00004000sv00001522sd00004100*
- ID_MODEL_FROM_DATABASE=IQ Express SideBand
+ ID_MODEL_FROM_DATABASE=PCI Express UART (IQ Express SideBand)
 
 pci:v00001523*
  ID_VENDOR_FROM_DATABASE=MUSIC Semiconductors
@@ -46071,7 +47328,7 @@ pci:v00001524d00000510*
  ID_MODEL_FROM_DATABASE=CB710 Memory Card Reader Controller
 
 pci:v00001524d00000510sv0000103Csd0000006A*
- ID_MODEL_FROM_DATABASE=NX9500
+ ID_MODEL_FROM_DATABASE=CB710 Memory Card Reader Controller (NX9500)
 
 pci:v00001524d00000520*
  ID_MODEL_FROM_DATABASE=FLASH memory: ENE Technology Inc:
@@ -46110,16 +47367,16 @@ pci:v00001524d00001410*
  ID_MODEL_FROM_DATABASE=CB1410 Cardbus Controller
 
 pci:v00001524d00001410sv00001025sd0000003C*
- ID_MODEL_FROM_DATABASE=CL50 motherboard
+ ID_MODEL_FROM_DATABASE=CB1410 Cardbus Controller (CL50 motherboard)
 
 pci:v00001524d00001410sv00001025sd0000005A*
- ID_MODEL_FROM_DATABASE=TravelMate 290
+ ID_MODEL_FROM_DATABASE=CB1410 Cardbus Controller (TravelMate 290)
 
 pci:v00001524d00001411*
  ID_MODEL_FROM_DATABASE=CB-710/2/4 Cardbus Controller
 
 pci:v00001524d00001411sv0000103Csd0000006A*
- ID_MODEL_FROM_DATABASE=NX9500
+ ID_MODEL_FROM_DATABASE=CB-710/2/4 Cardbus Controller (NX9500)
 
 pci:v00001524d00001412*
  ID_MODEL_FROM_DATABASE=CB-712/4 Cardbus Controller
@@ -46244,6 +47501,18 @@ pci:v00001542*
 pci:v00001542d00009260*
  ID_MODEL_FROM_DATABASE=RCIM-II Real-Time Clock & Interrupt Module
 
+pci:v00001542d00009272*
+ ID_MODEL_FROM_DATABASE=Pulse Width Modulator Card
+
+pci:v00001542d00009277*
+ ID_MODEL_FROM_DATABASE=5 Volt Delta Sigma Converter Card
+
+pci:v00001542d00009278*
+ ID_MODEL_FROM_DATABASE=10 Volt Delta Sigma Converter Card
+
+pci:v00001542d00009287*
+ ID_MODEL_FROM_DATABASE=Analog Output Card
+
 pci:v00001543*
  ID_VENDOR_FROM_DATABASE=SILICON Laboratories
 
@@ -46701,7 +47970,10 @@ pci:v000015ADd00000774*
  ID_MODEL_FROM_DATABASE=USB1.1 UHCI Controller
 
 pci:v000015ADd00000778*
- ID_MODEL_FROM_DATABASE=USB3 xHCI Controller
+ ID_MODEL_FROM_DATABASE=USB3 xHCI 0.96 Controller
+
+pci:v000015ADd00000779*
+ ID_MODEL_FROM_DATABASE=USB3 xHCI 1.0 Controller
 
 pci:v000015ADd00000790*
  ID_MODEL_FROM_DATABASE=PCI bridge
@@ -46722,7 +47994,7 @@ pci:v000015ADd00000801*
  ID_MODEL_FROM_DATABASE=Virtual Machine Interface
 
 pci:v000015ADd00000801sv000015ADsd00000800*
- ID_MODEL_FROM_DATABASE=Hypervisor ROM Interface
+ ID_MODEL_FROM_DATABASE=Virtual Machine Interface (Hypervisor ROM Interface)
 
 pci:v000015ADd00001977*
  ID_MODEL_FROM_DATABASE=HD Audio Controller
@@ -46758,7 +48030,7 @@ pci:v000015B3d00001003*
  ID_MODEL_FROM_DATABASE=MT27500 Family [ConnectX-3]
 
 pci:v000015B3d00001004*
- ID_MODEL_FROM_DATABASE=MT27500 Family [ConnectX-3 Virtual Function]
+ ID_MODEL_FROM_DATABASE=MT27500/MT27520 Family [ConnectX-3/ConnectX-3 Pro Virtual Function]
 
 pci:v000015B3d00001005*
  ID_MODEL_FROM_DATABASE=MT27510 Family
@@ -46769,9 +48041,6 @@ pci:v000015B3d00001006*
 pci:v000015B3d00001007*
  ID_MODEL_FROM_DATABASE=MT27520 Family [ConnectX-3 Pro]
 
-pci:v000015B3d00001008*
- ID_MODEL_FROM_DATABASE=MT27520 Family [ConnectX-3 Pro Virtual Function]
-
 pci:v000015B3d00001009*
  ID_MODEL_FROM_DATABASE=MT27530 Family
 
@@ -46872,10 +48141,10 @@ pci:v000015B3d00006746*
  ID_MODEL_FROM_DATABASE=MT26438 [ConnectX VPI PCIe 2.0 5GT/s - IB QDR / 10GigE Virtualization+]
 
 pci:v000015B3d00006746sv0000103Csd00001781*
- ID_MODEL_FROM_DATABASE=NC543i 1-port 4x QDR IB/Flex-10 10Gb Adapter
+ ID_MODEL_FROM_DATABASE=MT26438 [ConnectX VPI PCIe 2.0 5GT/s - IB QDR / 10GigE Virtualization+] (NC543i 1-port 4x QDR IB/Flex-10 10Gb Adapter)
 
 pci:v000015B3d00006746sv0000103Csd00003349*
- ID_MODEL_FROM_DATABASE=NC543i 2-port 4xQDR IB/10Gb Adapter
+ ID_MODEL_FROM_DATABASE=MT26438 [ConnectX VPI PCIe 2.0 5GT/s - IB QDR / 10GigE Virtualization+] (NC543i 2-port 4xQDR IB/10Gb Adapter)
 
 pci:v000015B3d00006750*
  ID_MODEL_FROM_DATABASE=MT26448 [ConnectX EN 10GigE, PCIe 2.0 5GT/s]
@@ -46887,7 +48156,7 @@ pci:v000015B3d00006764*
  ID_MODEL_FROM_DATABASE=MT26468 [ConnectX EN 10GigE, PCIe 2.0 5GT/s Virtualization+]
 
 pci:v000015B3d00006764sv0000103Csd00003313*
- ID_MODEL_FROM_DATABASE=HP NC542m Dual Port Flex-10 10GbE BLc Adapter
+ ID_MODEL_FROM_DATABASE=MT26468 [ConnectX EN 10GigE, PCIe 2.0 5GT/s Virtualization+] (HP NC542m Dual Port Flex-10 10GbE BLc Adapter)
 
 pci:v000015B3d0000676E*
  ID_MODEL_FROM_DATABASE=MT26478 [ConnectX EN 40GigE, PCIe 2.0 5GT/s]
@@ -47010,13 +48279,13 @@ pci:v000015BCd00000105*
  ID_MODEL_FROM_DATABASE=Celerity FC-44XS/FC-42XS/FC-41XS/FC-44ES/FC-42ES/FC-41ES
 
 pci:v000015BCd00000105sv0000117Csd00000022*
- ID_MODEL_FROM_DATABASE=Celerity FC-42XS Fibre Channel Adapter
+ ID_MODEL_FROM_DATABASE=Celerity FC-44XS/FC-42XS/FC-41XS/FC-44ES/FC-42ES/FC-41ES (Celerity FC-42XS Fibre Channel Adapter)
 
 pci:v000015BCd00000105sv0000117Csd00000025*
- ID_MODEL_FROM_DATABASE=Celerity FC-44ES Fibre Channel Adapter
+ ID_MODEL_FROM_DATABASE=Celerity FC-44XS/FC-42XS/FC-41XS/FC-44ES/FC-42ES/FC-41ES (Celerity FC-44ES Fibre Channel Adapter)
 
 pci:v000015BCd00000105sv0000117Csd00000026*
- ID_MODEL_FROM_DATABASE=Celerity FC-42ES Fibre Channel Adapter
+ ID_MODEL_FROM_DATABASE=Celerity FC-44XS/FC-42XS/FC-41XS/FC-44ES/FC-42ES/FC-41ES (Celerity FC-42ES Fibre Channel Adapter)
 
 pci:v000015BCd00001100*
  ID_MODEL_FROM_DATABASE=E8001-66442 PCI Express CIC
@@ -47430,34 +48699,34 @@ pci:v00001657d00000013*
  ID_MODEL_FROM_DATABASE=425/825/42B/82B 4Gbps/8Gbps PCIe dual port FC HBA
 
 pci:v00001657d00000013sv0000103Csd00001742*
- ID_MODEL_FROM_DATABASE=HP 82B 8Gbps dual port FC HBA
+ ID_MODEL_FROM_DATABASE=425/825/42B/82B 4Gbps/8Gbps PCIe dual port FC HBA (HP 82B 8Gbps dual port FC HBA)
 
 pci:v00001657d00000013sv0000103Csd00001744*
- ID_MODEL_FROM_DATABASE=HP 42B 4Gbps dual port FC HBA
+ ID_MODEL_FROM_DATABASE=425/825/42B/82B 4Gbps/8Gbps PCIe dual port FC HBA (HP 42B 4Gbps dual port FC HBA)
 
 pci:v00001657d00000013sv00001657sd00000014*
- ID_MODEL_FROM_DATABASE=425/825 4Gbps/8Gbps PCIe dual port FC HBA
+ ID_MODEL_FROM_DATABASE=425/825/42B/82B 4Gbps/8Gbps PCIe dual port FC HBA (425/825 4Gbps/8Gbps PCIe dual port FC HBA)
 
 pci:v00001657d00000014*
  ID_MODEL_FROM_DATABASE=1010/1020/1007/1741 10Gbps CNA
 
 pci:v00001657d00000014sv00001657sd00000014*
- ID_MODEL_FROM_DATABASE=1010/1020/1007/1741 10Gbps CNA - FCOE
+ ID_MODEL_FROM_DATABASE=1010/1020/1007/1741 10Gbps CNA (- FCOE)
 
 pci:v00001657d00000014sv00001657sd00000015*
- ID_MODEL_FROM_DATABASE=1010/1020/1007/1741 10Gbps CNA - LL
+ ID_MODEL_FROM_DATABASE=1010/1020/1007/1741 10Gbps CNA (- LL)
 
 pci:v00001657d00000017*
  ID_MODEL_FROM_DATABASE=415/815/41B/81B 4Gbps/8Gbps PCIe single port FC HBA
 
 pci:v00001657d00000017sv0000103Csd00001741*
- ID_MODEL_FROM_DATABASE=HP 41B 4Gbps single port FC HBA
+ ID_MODEL_FROM_DATABASE=415/815/41B/81B 4Gbps/8Gbps PCIe single port FC HBA (HP 41B 4Gbps single port FC HBA)
 
 pci:v00001657d00000017sv0000103Csd00001743*
- ID_MODEL_FROM_DATABASE=HP 81B 8Gbps single port FC HBA
+ ID_MODEL_FROM_DATABASE=415/815/41B/81B 4Gbps/8Gbps PCIe single port FC HBA (HP 81B 8Gbps single port FC HBA)
 
 pci:v00001657d00000017sv00001657sd00000014*
- ID_MODEL_FROM_DATABASE=415/815 4Gbps/8Gbps single port PCIe FC HBA
+ ID_MODEL_FROM_DATABASE=415/815/41B/81B 4Gbps/8Gbps PCIe single port FC HBA (415/815 4Gbps/8Gbps single port PCIe FC HBA)
 
 pci:v00001657d00000021*
  ID_MODEL_FROM_DATABASE=804 8Gbps FC HBA for HP Bladesystem c-class
@@ -47466,13 +48735,13 @@ pci:v00001657d00000022*
  ID_MODEL_FROM_DATABASE=1860 16Gbps/10Gbps Fabric Adapter
 
 pci:v00001657d00000022sv00001657sd00000022*
- ID_MODEL_FROM_DATABASE=10Gbps CNA - FCOE
+ ID_MODEL_FROM_DATABASE=1860 16Gbps/10Gbps Fabric Adapter (10Gbps CNA - FCOE)
 
 pci:v00001657d00000022sv00001657sd00000023*
- ID_MODEL_FROM_DATABASE=10Gbps CNA - LL
+ ID_MODEL_FROM_DATABASE=1860 16Gbps/10Gbps Fabric Adapter (10Gbps CNA - LL)
 
 pci:v00001657d00000022sv00001657sd00000024*
- ID_MODEL_FROM_DATABASE=16Gbps FC HBA
+ ID_MODEL_FROM_DATABASE=1860 16Gbps/10Gbps Fabric Adapter (16Gbps FC HBA)
 
 pci:v00001657d00000023*
  ID_MODEL_FROM_DATABASE=1867/1869 16Gbps FC HBA
@@ -47559,10 +48828,10 @@ pci:v0000167Bd00002102*
  ID_MODEL_FROM_DATABASE=ZyDAS ZD1202
 
 pci:v0000167Bd00002102sv0000187Esd00003406*
- ID_MODEL_FROM_DATABASE=ZyAIR B-122 CardBus 11Mbs Wireless LAN Card
+ ID_MODEL_FROM_DATABASE=ZyDAS ZD1202 (ZyAIR B-122 CardBus 11Mbs Wireless LAN Card)
 
 pci:v0000167Bd00002102sv0000187Esd00003407*
- ID_MODEL_FROM_DATABASE=ZyAIR B-320 802.11b Wireless PCI Adapter
+ ID_MODEL_FROM_DATABASE=ZyDAS ZD1202 (ZyAIR B-320 802.11b Wireless PCI Adapter)
 
 pci:v0000167Bd00002116*
  ID_MODEL_FROM_DATABASE=ZD1212B Wireless Adapter
@@ -47595,16 +48864,16 @@ pci:v0000168Cd00000007*
  ID_MODEL_FROM_DATABASE=AR5210 Wireless Network Adapter [AR5000 802.11a]
 
 pci:v0000168Cd00000007sv00001737sd00000007*
- ID_MODEL_FROM_DATABASE=WPC54A Wireless PC Card
+ ID_MODEL_FROM_DATABASE=AR5210 Wireless Network Adapter [AR5000 802.11a] (WPC54A Wireless PC Card)
 
 pci:v0000168Cd00000007sv00001B47sd00000100*
- ID_MODEL_FROM_DATABASE=Harmony 8450CN Wireless CardBus Module
+ ID_MODEL_FROM_DATABASE=AR5210 Wireless Network Adapter [AR5000 802.11a] (Harmony 8450CN Wireless CardBus Module)
 
 pci:v0000168Cd00000007sv00001B47sd00000110*
- ID_MODEL_FROM_DATABASE=Skyline 4030 / Harmony 8450 802.11a Wireless CardBus Adapter
+ ID_MODEL_FROM_DATABASE=AR5210 Wireless Network Adapter [AR5000 802.11a] (Skyline 4030 / Harmony 8450 802.11a Wireless CardBus Adapter)
 
 pci:v0000168Cd00000007sv00008086sd00002501*
- ID_MODEL_FROM_DATABASE=PRO/Wireless 5000 LAN PCI Adapter Module
+ ID_MODEL_FROM_DATABASE=AR5210 Wireless Network Adapter [AR5000 802.11a] (PRO/Wireless 5000 LAN PCI Adapter Module)
 
 pci:v0000168Cd00000011*
  ID_MODEL_FROM_DATABASE=AR5211 Wireless Network Adapter [AR5001A 802.11a]
@@ -47613,562 +48882,565 @@ pci:v0000168Cd00000012*
  ID_MODEL_FROM_DATABASE=AR5211 Wireless Network Adapter [AR5001X 802.11ab]
 
 pci:v0000168Cd00000012sv00001186sd00003A03*
- ID_MODEL_FROM_DATABASE=AirPro DWL-A650 Wireless Cardbus Adapter (rev.B)
+ ID_MODEL_FROM_DATABASE=AR5211 Wireless Network Adapter [AR5001X 802.11ab] (AirPro DWL-A650 Wireless Cardbus Adapter (rev.B))
 
 pci:v0000168Cd00000012sv00001186sd00003A04*
- ID_MODEL_FROM_DATABASE=AirPro DWL-AB650 Multimode Wireless Cardbus Adapter
+ ID_MODEL_FROM_DATABASE=AR5211 Wireless Network Adapter [AR5001X 802.11ab] (AirPro DWL-AB650 Multimode Wireless Cardbus Adapter)
 
 pci:v0000168Cd00000012sv00001186sd00003A05*
- ID_MODEL_FROM_DATABASE=AirPro DWL-AB520 Multimode Wireless PCI Adapter
+ ID_MODEL_FROM_DATABASE=AR5211 Wireless Network Adapter [AR5001X 802.11ab] (AirPro DWL-AB520 Multimode Wireless PCI Adapter)
 
 pci:v0000168Cd00000012sv0000126Csd00008031*
- ID_MODEL_FROM_DATABASE=2201 Mobile Adapter
+ ID_MODEL_FROM_DATABASE=AR5211 Wireless Network Adapter [AR5001X 802.11ab] (2201 Mobile Adapter)
 
 pci:v0000168Cd00000012sv00001385sd00004400*
- ID_MODEL_FROM_DATABASE=WAB501 802.11ab Wireless CardBus Card
+ ID_MODEL_FROM_DATABASE=AR5211 Wireless Network Adapter [AR5001X 802.11ab] (WAB501 802.11ab Wireless CardBus Card)
 
 pci:v0000168Cd00000012sv00001B47sd0000AA00*
- ID_MODEL_FROM_DATABASE=8460 802.11ab Wireless CardBus Adapter
+ ID_MODEL_FROM_DATABASE=AR5211 Wireless Network Adapter [AR5001X 802.11ab] (8460 802.11ab Wireless CardBus Adapter)
 
 pci:v0000168Cd00000013*
  ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter
 
 pci:v0000168Cd00000013sv00000308sd00003402*
- ID_MODEL_FROM_DATABASE=AG-100 802.11ag Wireless Cardbus Adapter
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (AG-100 802.11ag Wireless Cardbus Adapter)
 
 pci:v0000168Cd00000013sv00000308sd00003405*
- ID_MODEL_FROM_DATABASE=G-102 v2 802.11g Wireless Cardbus Adapter
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (G-102 v2 802.11g Wireless Cardbus Adapter)
 
 pci:v0000168Cd00000013sv00000308sd00003408*
- ID_MODEL_FROM_DATABASE=G-170S 802.11g Wireless CardBus Adapter
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (G-170S 802.11g Wireless CardBus Adapter)
 
 pci:v0000168Cd00000013sv00000E11sd000000E5*
- ID_MODEL_FROM_DATABASE=NC6000/NC8000 laptop
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (NC6000/NC8000 laptop)
 
 pci:v0000168Cd00000013sv000010B7sd00006002*
- ID_MODEL_FROM_DATABASE=3CRWE154A72 802.11abg Cardbus Adapter
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (3CRWE154A72 802.11abg Cardbus Adapter)
 
 pci:v0000168Cd00000013sv00001113sd0000D301*
- ID_MODEL_FROM_DATABASE=Philips CPWNA100 Wireless CardBus adapter
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (Philips CPWNA100 Wireless CardBus adapter)
 
 pci:v0000168Cd00000013sv00001113sd0000EE23*
- ID_MODEL_FROM_DATABASE=SMCWPCIT-G 108Mbps Wireless PCI adapter
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (SMCWPCIT-G 108Mbps Wireless PCI adapter)
 
 pci:v0000168Cd00000013sv00001154sd0000033B*
- ID_MODEL_FROM_DATABASE=Buffalo WLI-CB-AMG54
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (Buffalo WLI-CB-AMG54)
 
 pci:v0000168Cd00000013sv00001154sd0000034E*
- ID_MODEL_FROM_DATABASE=Buffalo WLI-CB-AG108HP 802.11abg Cardbus Adapter
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (Buffalo WLI-CB-AG108HP 802.11abg Cardbus Adapter)
 
 pci:v0000168Cd00000013sv00001186sd00003202*
- ID_MODEL_FROM_DATABASE=DWL-G650 (Rev B3,B5) Wireless cardbus adapter
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (DWL-G650 (Rev B3,B5) Wireless cardbus adapter)
 
 pci:v0000168Cd00000013sv00001186sd00003203*
- ID_MODEL_FROM_DATABASE=AirPlus DWL-G520 Wireless PCI Adapter (rev. A)
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (AirPlus DWL-G520 Wireless PCI Adapter (rev. A))
 
 pci:v0000168Cd00000013sv00001186sd00003A07*
- ID_MODEL_FROM_DATABASE=AirXpert DWL-AG650 Wireless Cardbus Adapter
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (AirXpert DWL-AG650 Wireless Cardbus Adapter)
 
 pci:v0000168Cd00000013sv00001186sd00003A08*
- ID_MODEL_FROM_DATABASE=AirXpert DWL-AG520 Wireless PCI Adapter
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (AirXpert DWL-AG520 Wireless PCI Adapter)
 
 pci:v0000168Cd00000013sv00001186sd00003A12*
- ID_MODEL_FROM_DATABASE=D-Link AirPlus DWL-G650 Wireless Cardbus Adapter(rev.C)
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (D-Link AirPlus DWL-G650 Wireless Cardbus Adapter(rev.C))
 
 pci:v0000168Cd00000013sv00001186sd00003A13*
- ID_MODEL_FROM_DATABASE=AirPlus DWL-G520 Wireless PCI Adapter (rev. B)
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (AirPlus DWL-G520 Wireless PCI Adapter (rev. B))
 
 pci:v0000168Cd00000013sv00001186sd00003A14*
- ID_MODEL_FROM_DATABASE=AirPremier AG DWL-AG530 Wireless PCI Adapter (rev.A)
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (AirPremier AG DWL-AG530 Wireless PCI Adapter (rev.A))
 
 pci:v0000168Cd00000013sv00001186sd00003A17*
- ID_MODEL_FROM_DATABASE=D-Link AirPremier DWL-G680 Wireless Cardbus Adapter
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (D-Link AirPremier DWL-G680 Wireless Cardbus Adapter)
 
 pci:v0000168Cd00000013sv00001186sd00003A18*
- ID_MODEL_FROM_DATABASE=D-Link AirPremier DWL-G550 Wireless PCI Adapter
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (D-Link AirPremier DWL-G550 Wireless PCI Adapter)
 
 pci:v0000168Cd00000013sv00001186sd00003A1A*
- ID_MODEL_FROM_DATABASE=WNA-2330 802.11bg Wireless CardBus Adapter
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (WNA-2330 802.11bg Wireless CardBus Adapter)
 
 pci:v0000168Cd00000013sv00001186sd00003A63*
- ID_MODEL_FROM_DATABASE=D-Link AirPremier DWL-AG660 Wireless Cardbus Adapter
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (D-Link AirPremier DWL-AG660 Wireless Cardbus Adapter)
 
 pci:v0000168Cd00000013sv00001186sd00003A93*
- ID_MODEL_FROM_DATABASE=Conceptronic C54I Wireless 801.11g PCI card
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (Conceptronic C54I Wireless 801.11g PCI card)
 
 pci:v0000168Cd00000013sv00001186sd00003A94*
- ID_MODEL_FROM_DATABASE=Conceptronic C54C 802.11g Wireless Cardbus Adapter
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (Conceptronic C54C 802.11g Wireless Cardbus Adapter)
 
 pci:v0000168Cd00000013sv00001186sd00003AB0*
- ID_MODEL_FROM_DATABASE=Allnet ALL0281 Wireless PCI Card
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (Allnet ALL0281 Wireless PCI Card)
 
 pci:v0000168Cd00000013sv00001385sd00004600*
- ID_MODEL_FROM_DATABASE=WAG511 802.11a/b/g Dual Band Wireless PC Card
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (WAG511 802.11a/b/g Dual Band Wireless PC Card)
 
 pci:v0000168Cd00000013sv00001385sd00004610*
- ID_MODEL_FROM_DATABASE=WAG511 802.11a/b/g Dual Band Wireless PC Card
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (WAG511 802.11a/b/g Dual Band Wireless PC Card)
 
 pci:v0000168Cd00000013sv00001385sd00004900*
- ID_MODEL_FROM_DATABASE=WG311v1 802.11g Wireless PCI Adapter
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (WG311v1 802.11g Wireless PCI Adapter)
 
 pci:v0000168Cd00000013sv00001385sd00004A00*
- ID_MODEL_FROM_DATABASE=WAG311 802.11a/g Wireless PCI Adapter
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (WAG311 802.11a/g Wireless PCI Adapter)
 
 pci:v0000168Cd00000013sv00001385sd00004B00*
- ID_MODEL_FROM_DATABASE=WG511T 108 Mbps Wireless PC Card (rev.A/B)
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (WG511T 108 Mbps Wireless PC Card (rev.A/B))
 
 pci:v0000168Cd00000013sv00001385sd00004D00*
- ID_MODEL_FROM_DATABASE=WG311T 108 Mbps Wireless PCI Adapter (rev.A2)
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (WG311T 108 Mbps Wireless PCI Adapter (rev.A2))
 
 pci:v0000168Cd00000013sv00001385sd00004F00*
- ID_MODEL_FROM_DATABASE=WG511U Double 108 Mbps Wireless PC Card
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (WG511U Double 108 Mbps Wireless PC Card)
 
 pci:v0000168Cd00000013sv00001385sd00005A00*
- ID_MODEL_FROM_DATABASE=WG311T 108 Mbps Wireless PCI Adapter (rev.A3)
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (WG311T 108 Mbps Wireless PCI Adapter (rev.A3))
 
 pci:v0000168Cd00000013sv00001385sd00005B00*
- ID_MODEL_FROM_DATABASE=WG511T 108 Mbps Wireless PC Card (rev.C)
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (WG511T 108 Mbps Wireless PC Card (rev.C))
 
 pci:v0000168Cd00000013sv00001385sd00005D00*
- ID_MODEL_FROM_DATABASE=WPN511 RangeMax Wireless PC Card
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (WPN511 RangeMax Wireless PC Card)
 
 pci:v0000168Cd00000013sv00001458sd0000E911*
- ID_MODEL_FROM_DATABASE=GN-WIAG02
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (GN-WIAG02)
 
 pci:v0000168Cd00000013sv00001468sd00000403*
- ID_MODEL_FROM_DATABASE=U10H014 802.11g Cardbus Adapter
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (U10H014 802.11g Cardbus Adapter)
 
 pci:v0000168Cd00000013sv00001468sd00000408*
- ID_MODEL_FROM_DATABASE=ThinkPad 11b/g Wireless LAN Mini PCI Adapter
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (ThinkPad 11b/g Wireless LAN Mini PCI Adapter)
 
 pci:v0000168Cd00000013sv000014B7sd00000A10*
- ID_MODEL_FROM_DATABASE=8480-WD 802.11abg Cardbus Adapter
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (8480-WD 802.11abg Cardbus Adapter)
 
 pci:v0000168Cd00000013sv000014B7sd00000A60*
- ID_MODEL_FROM_DATABASE=8482-WD ORiNOCO 11a/b/g Wireless PCI Adapter
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (8482-WD ORiNOCO 11a/b/g Wireless PCI Adapter)
 
 pci:v0000168Cd00000013sv000014B7sd0000AA30*
- ID_MODEL_FROM_DATABASE=8800-FC 802.11bg Cardbus Adapter
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (8800-FC 802.11bg Cardbus Adapter)
 
 pci:v0000168Cd00000013sv000014B7sd0000AA40*
- ID_MODEL_FROM_DATABASE=8470-WD 802.11bg Cardbus Adapter
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (8470-WD 802.11bg Cardbus Adapter)
 
 pci:v0000168Cd00000013sv000014B9sd0000CB21*
- ID_MODEL_FROM_DATABASE=CB21 802.11a/b/g Cardbus Adapter
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (CB21 802.11a/b/g Cardbus Adapter)
 
 pci:v0000168Cd00000013sv00001668sd00001026*
- ID_MODEL_FROM_DATABASE=IBM HighRate 11 a/b/g Wireless CardBus Adapter
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (IBM HighRate 11 a/b/g Wireless CardBus Adapter)
 
 pci:v0000168Cd00000013sv0000168Csd00000013*
- ID_MODEL_FROM_DATABASE=AirPlus XtremeG DWL-G650 Wireless PCMCIA Adapter
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (AirPlus XtremeG DWL-G650 Wireless PCMCIA Adapter)
 
 pci:v0000168Cd00000013sv0000168Csd00001025*
- ID_MODEL_FROM_DATABASE=DWL-G650B2 Wireless CardBus Adapter
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (DWL-G650B2 Wireless CardBus Adapter)
 
 pci:v0000168Cd00000013sv0000168Csd00001027*
- ID_MODEL_FROM_DATABASE=Engenius NL-3054CB ARIES b/g CardBus Adapter
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (Engenius NL-3054CB ARIES b/g CardBus Adapter)
 
 pci:v0000168Cd00000013sv0000168Csd00001042*
- ID_MODEL_FROM_DATABASE=Ubiquiti Networks SuperRange a/b/g Cardbus Adapter
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (Ubiquiti Networks SuperRange a/b/g Cardbus Adapter)
 
 pci:v0000168Cd00000013sv0000168Csd00001051*
- ID_MODEL_FROM_DATABASE=EZ Connect g 802.11g 108Mbps Wireless PCI Adapter
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (EZ Connect g 802.11g 108Mbps Wireless PCI Adapter)
 
 pci:v0000168Cd00000013sv0000168Csd00002026*
- ID_MODEL_FROM_DATABASE=Netgate 5354MP ARIES a(108Mb turbo)/b/g MiniPCI Adapter
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (Netgate 5354MP ARIES a(108Mb turbo)/b/g MiniPCI Adapter)
 
 pci:v0000168Cd00000013sv0000168Csd00002027*
- ID_MODEL_FROM_DATABASE=D-Link AirPlus DWL-G520 Wireless PCI Adapter (rev. A)
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (D-Link AirPlus DWL-G520 Wireless PCI Adapter (rev. A))
 
 pci:v0000168Cd00000013sv0000168Csd00002041*
- ID_MODEL_FROM_DATABASE=Engenius 5354MP Plus ARIES2 b/g MiniPCI Adapter
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (Engenius 5354MP Plus ARIES2 b/g MiniPCI Adapter)
 
 pci:v0000168Cd00000013sv0000168Csd00002042*
- ID_MODEL_FROM_DATABASE=Engenius 5354MP Plus ARIES2 a/b/g MiniPCI Adapter
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (Engenius 5354MP Plus ARIES2 a/b/g MiniPCI Adapter)
 
 pci:v0000168Cd00000013sv0000168Csd00002051*
- ID_MODEL_FROM_DATABASE=TRENDnet TEW-443PI Wireless PCI Adapter
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (TRENDnet TEW-443PI Wireless PCI Adapter)
 
 pci:v0000168Cd00000013sv000016A5sd0000160A*
- ID_MODEL_FROM_DATABASE=BWP712 802.11bg Wireless CardBus Adapter
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (BWP712 802.11bg Wireless CardBus Adapter)
 
 pci:v0000168Cd00000013sv000016ABsd00007302*
- ID_MODEL_FROM_DATABASE=Trust Speedshare Turbo Pro Wireless PCI Adapter
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (Trust Speedshare Turbo Pro Wireless PCI Adapter)
 
 pci:v0000168Cd00000013sv00001737sd00000017*
- ID_MODEL_FROM_DATABASE=WPC55AG
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (WPC55AG)
 
 pci:v0000168Cd00000013sv00001737sd00000026*
- ID_MODEL_FROM_DATABASE=WMP55AG v1.1
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (WMP55AG v1.1)
 
 pci:v0000168Cd00000013sv00001737sd00000035*
- ID_MODEL_FROM_DATABASE=WPC55AG v1.2 802.11abg Cardbus Adapter
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (WPC55AG v1.2 802.11abg Cardbus Adapter)
 
 pci:v0000168Cd00000013sv00001737sd00000036*
- ID_MODEL_FROM_DATABASE=WMP55AG v1.2 802.11abg PCI Adapter
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (WMP55AG v1.2 802.11abg PCI Adapter)
 
 pci:v0000168Cd00000013sv00001799sd00003000*
- ID_MODEL_FROM_DATABASE=F6D3000 Dual-Band Wireless A+G Desktop Card
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (F6D3000 Dual-Band Wireless A+G Desktop Card)
 
 pci:v0000168Cd00000013sv00001799sd00003010*
- ID_MODEL_FROM_DATABASE=F6D3010 Dual-Band Wireless A+G Notebook Card
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (F6D3010 Dual-Band Wireless A+G Notebook Card)
 
 pci:v0000168Cd00000013sv000017CFsd00000042*
- ID_MODEL_FROM_DATABASE=Z-COMAX Highpower XG-622H (400mw) 802.11b/g mini-PCI Adapter
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (Z-COMAX Highpower XG-622H (400mw) 802.11b/g mini-PCI Adapter)
 
 pci:v0000168Cd00000013sv0000185Fsd00001012*
- ID_MODEL_FROM_DATABASE=CM9 Wireless a/b/g MiniPCI Adapter
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (CM9 Wireless a/b/g MiniPCI Adapter)
 
 pci:v0000168Cd00000013sv0000185Fsd00002012*
- ID_MODEL_FROM_DATABASE=Wistron NeWeb WLAN a+b+g model CB9
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (Wistron NeWeb WLAN a+b+g model CB9)
 
 pci:v0000168Cd00000013sv0000A727sd00006801*
- ID_MODEL_FROM_DATABASE=3CRXJK10075 OfficeConnect Wireless 108Mbps 11g XJACK PC Card
+ ID_MODEL_FROM_DATABASE=AR5212/AR5213 Wireless Network Adapter (3CRXJK10075 OfficeConnect Wireless 108Mbps 11g XJACK PC Card)
 
 pci:v0000168Cd0000001A*
  ID_MODEL_FROM_DATABASE=AR2413/AR2414 Wireless Network Adapter [AR5005G(S) 802.11bg]
 
 pci:v0000168Cd0000001Asv00001052sd0000168C*
- ID_MODEL_FROM_DATABASE=Sweex Wireless Lan PC Card 54Mbps
+ ID_MODEL_FROM_DATABASE=AR2413/AR2414 Wireless Network Adapter [AR5005G(S) 802.11bg] (Sweex Wireless Lan PC Card 54Mbps)
 
 pci:v0000168Cd0000001Asv00001113sd0000EE20*
- ID_MODEL_FROM_DATABASE=SMC Wireless CardBus Adapter 802.11g (SMCWCB-G EU)
+ ID_MODEL_FROM_DATABASE=AR2413/AR2414 Wireless Network Adapter [AR5005G(S) 802.11bg] (SMC Wireless CardBus Adapter 802.11g (SMCWCB-G EU))
 
 pci:v0000168Cd0000001Asv00001113sd0000EE24*
- ID_MODEL_FROM_DATABASE=SMC Wireless PCI Card WPCI-G
+ ID_MODEL_FROM_DATABASE=AR2413/AR2414 Wireless Network Adapter [AR5005G(S) 802.11bg] (SMC Wireless PCI Card WPCI-G)
 
 pci:v0000168Cd0000001Asv00001186sd00003A15*
- ID_MODEL_FROM_DATABASE=AirPlus G DWL-G630 Wireless Cardbus Adapter (rev.D1)
+ ID_MODEL_FROM_DATABASE=AR2413/AR2414 Wireless Network Adapter [AR5005G(S) 802.11bg] (AirPlus G DWL-G630 Wireless Cardbus Adapter (rev.D1))
 
 pci:v0000168Cd0000001Asv00001186sd00003A16*
- ID_MODEL_FROM_DATABASE=AirPlus G DWL-G510 Wireless PCI Adapter(rev.B)
+ ID_MODEL_FROM_DATABASE=AR2413/AR2414 Wireless Network Adapter [AR5005G(S) 802.11bg] (AirPlus G DWL-G510 Wireless PCI Adapter(rev.B))
 
 pci:v0000168Cd0000001Asv00001186sd00003A1C*
- ID_MODEL_FROM_DATABASE=WNA-1330 Notebook Adapter
+ ID_MODEL_FROM_DATABASE=AR2413/AR2414 Wireless Network Adapter [AR5005G(S) 802.11bg] (WNA-1330 Notebook Adapter)
 
 pci:v0000168Cd0000001Asv00001186sd00003A1D*
- ID_MODEL_FROM_DATABASE=WDA-1320 Desktop Adapter
+ ID_MODEL_FROM_DATABASE=AR2413/AR2414 Wireless Network Adapter [AR5005G(S) 802.11bg] (WDA-1320 Desktop Adapter)
 
 pci:v0000168Cd0000001Asv00001186sd00003A23*
- ID_MODEL_FROM_DATABASE=AirPlus G DWL-G520+A Wireless PCI Adapter
+ ID_MODEL_FROM_DATABASE=AR2413/AR2414 Wireless Network Adapter [AR5005G(S) 802.11bg] (AirPlus G DWL-G520+A Wireless PCI Adapter)
 
 pci:v0000168Cd0000001Asv00001186sd00003A24*
- ID_MODEL_FROM_DATABASE=AirPlus G DWL-G650+A Wireless Cardbus Adapter
+ ID_MODEL_FROM_DATABASE=AR2413/AR2414 Wireless Network Adapter [AR5005G(S) 802.11bg] (AirPlus G DWL-G650+A Wireless Cardbus Adapter)
 
 pci:v0000168Cd0000001Asv00001186sd00003B08*
- ID_MODEL_FROM_DATABASE=AirPlus G DWL-G630 Wireless Cardbus Adapter (rev.C1)
+ ID_MODEL_FROM_DATABASE=AR2413/AR2414 Wireless Network Adapter [AR5005G(S) 802.11bg] (AirPlus G DWL-G630 Wireless Cardbus Adapter (rev.C1))
 
 pci:v0000168Cd0000001Asv0000168Csd0000001A*
- ID_MODEL_FROM_DATABASE=Belkin FD7000
+ ID_MODEL_FROM_DATABASE=AR2413/AR2414 Wireless Network Adapter [AR5005G(S) 802.11bg] (Belkin FD7000)
 
 pci:v0000168Cd0000001Asv0000168Csd00001052*
- ID_MODEL_FROM_DATABASE=TP-Link TL-WN510G Wireless CardBus Adapter
+ ID_MODEL_FROM_DATABASE=AR2413/AR2414 Wireless Network Adapter [AR5005G(S) 802.11bg] (TP-Link TL-WN510G Wireless CardBus Adapter)
 
 pci:v0000168Cd0000001Asv0000168Csd00002052*
- ID_MODEL_FROM_DATABASE=Compex Wireless 802.11 b/g  MiniPCI Adapter, Rev A1 [WLM54G]
+ ID_MODEL_FROM_DATABASE=AR2413/AR2414 Wireless Network Adapter [AR5005G(S) 802.11bg] (Compex Wireless 802.11 b/g  MiniPCI Adapter, Rev A1 [WLM54G])
 
 pci:v0000168Cd0000001Asv000016ECsd00000122*
- ID_MODEL_FROM_DATABASE=Wireless PCI Adapter Model 5418
+ ID_MODEL_FROM_DATABASE=AR2413/AR2414 Wireless Network Adapter [AR5005G(S) 802.11bg] (Wireless PCI Adapter Model 5418)
 
 pci:v0000168Cd0000001Asv00001737sd00000053*
- ID_MODEL_FROM_DATABASE=WPC54G v7 802.11g Wireless-G Notebook Adapter
+ ID_MODEL_FROM_DATABASE=AR2413/AR2414 Wireless Network Adapter [AR5005G(S) 802.11bg] (WPC54G v7 802.11g Wireless-G Notebook Adapter)
 
 pci:v0000168Cd0000001Asv00001799sd0000700C*
- ID_MODEL_FROM_DATABASE=F5D7000 v5000 Wireless G Desktop Card
+ ID_MODEL_FROM_DATABASE=AR2413/AR2414 Wireless Network Adapter [AR5005G(S) 802.11bg] (F5D7000 v5000 Wireless G Desktop Card)
 
 pci:v0000168Cd0000001Asv00001799sd0000701D*
- ID_MODEL_FROM_DATABASE=F5D7010 v5000 Wireless G Notebook Card
+ ID_MODEL_FROM_DATABASE=AR2413/AR2414 Wireless Network Adapter [AR5005G(S) 802.11bg] (F5D7010 v5000 Wireless G Notebook Card)
 
 pci:v0000168Cd0000001Asv000017F9sd00000008*
- ID_MODEL_FROM_DATABASE=DX-WGNBC 802.11bg Wireless CardBus Adapter
+ ID_MODEL_FROM_DATABASE=AR2413/AR2414 Wireless Network Adapter [AR5005G(S) 802.11bg] (DX-WGNBC 802.11bg Wireless CardBus Adapter)
 
 pci:v0000168Cd0000001Asv000017F9sd00000018*
- ID_MODEL_FROM_DATABASE=DX-WGDTC 802.11bg Wireless PCI Adapter
+ ID_MODEL_FROM_DATABASE=AR2413/AR2414 Wireless Network Adapter [AR5005G(S) 802.11bg] (DX-WGDTC 802.11bg Wireless PCI Adapter)
 
 pci:v0000168Cd0000001B*
  ID_MODEL_FROM_DATABASE=AR5413/AR5414 Wireless Network Adapter [AR5006X(S) 802.11abg]
 
 pci:v0000168Cd0000001Bsv00000777sd00001107*
- ID_MODEL_FROM_DATABASE=UB5 802.11a Wireless Mini PCI Adapter
+ ID_MODEL_FROM_DATABASE=AR5413/AR5414 Wireless Network Adapter [AR5006X(S) 802.11abg] (UB5 802.11a Wireless Mini PCI Adapter)
 
 pci:v0000168Cd0000001Bsv00000777sd00003002*
- ID_MODEL_FROM_DATABASE=XR2 802.11g Wireless Mini PCI Adapter
+ ID_MODEL_FROM_DATABASE=AR5413/AR5414 Wireless Network Adapter [AR5006X(S) 802.11abg] (XR2 802.11g Wireless Mini PCI Adapter)
 
 pci:v0000168Cd0000001Bsv00000777sd00003005*
- ID_MODEL_FROM_DATABASE=XR5 802.11a Wireless Mini PCI Adapter
+ ID_MODEL_FROM_DATABASE=AR5413/AR5414 Wireless Network Adapter [AR5006X(S) 802.11abg] (XR5 802.11a Wireless Mini PCI Adapter)
 
 pci:v0000168Cd0000001Bsv00000777sd00003009*
- ID_MODEL_FROM_DATABASE=XR9 900MHz Wireless Mini PCI Adapter
+ ID_MODEL_FROM_DATABASE=AR5413/AR5414 Wireless Network Adapter [AR5006X(S) 802.11abg] (XR9 900MHz Wireless Mini PCI Adapter)
 
 pci:v0000168Cd0000001Bsv00001154sd0000034E*
- ID_MODEL_FROM_DATABASE=WLI-CB-AG108HP 802.11abg Wireless CardBus Adapter
+ ID_MODEL_FROM_DATABASE=AR5413/AR5414 Wireless Network Adapter [AR5006X(S) 802.11abg] (WLI-CB-AG108HP 802.11abg Wireless CardBus Adapter)
 
 pci:v0000168Cd0000001Bsv00001186sd00003A19*
- ID_MODEL_FROM_DATABASE=D-Link AirPremier AG DWL-AG660 Wireless Cardbus Adapter
+ ID_MODEL_FROM_DATABASE=AR5413/AR5414 Wireless Network Adapter [AR5006X(S) 802.11abg] (D-Link AirPremier AG DWL-AG660 Wireless Cardbus Adapter)
 
 pci:v0000168Cd0000001Bsv00001186sd00003A22*
- ID_MODEL_FROM_DATABASE=AirPremier AG DWL-AG530 Wireless PCI Adapter (rev.B)
+ ID_MODEL_FROM_DATABASE=AR5413/AR5414 Wireless Network Adapter [AR5006X(S) 802.11abg] (AirPremier AG DWL-AG530 Wireless PCI Adapter (rev.B))
 
 pci:v0000168Cd0000001Bsv000011ADsd00005001*
- ID_MODEL_FROM_DATABASE=WN5301A 802.11bg Wireless PCI Adapter
+ ID_MODEL_FROM_DATABASE=AR5413/AR5414 Wireless Network Adapter [AR5006X(S) 802.11abg] (WN5301A 802.11bg Wireless PCI Adapter)
 
 pci:v0000168Cd0000001Bsv00001458sd0000E901*
- ID_MODEL_FROM_DATABASE=GN-WI01HT Wireless a/b/g MiniPCI Adapter
+ ID_MODEL_FROM_DATABASE=AR5413/AR5414 Wireless Network Adapter [AR5006X(S) 802.11abg] (GN-WI01HT Wireless a/b/g MiniPCI Adapter)
 
 pci:v0000168Cd0000001Bsv0000168Csd0000001B*
- ID_MODEL_FROM_DATABASE=Wireless LAN PCI LiteOn
+ ID_MODEL_FROM_DATABASE=AR5413/AR5414 Wireless Network Adapter [AR5006X(S) 802.11abg] (Wireless LAN PCI LiteOn)
 
 pci:v0000168Cd0000001Bsv0000168Csd00001062*
- ID_MODEL_FROM_DATABASE=IPN-W100CB 802.11abg Wireless CardBus Adapter
+ ID_MODEL_FROM_DATABASE=AR5413/AR5414 Wireless Network Adapter [AR5006X(S) 802.11abg] (IPN-W100CB 802.11abg Wireless CardBus Adapter)
 
 pci:v0000168Cd0000001Bsv0000168Csd00002062*
- ID_MODEL_FROM_DATABASE=EnGenius EMP-8602 (400mw) or Compex WLM54AG (SuperAG)
+ ID_MODEL_FROM_DATABASE=AR5413/AR5414 Wireless Network Adapter [AR5006X(S) 802.11abg] (EnGenius EMP-8602 (400mw) or Compex WLM54AG (SuperAG))
 
 pci:v0000168Cd0000001Bsv0000168Csd00002063*
- ID_MODEL_FROM_DATABASE=EnGenius EMP-8602 (400mw) or Compex WLM54AG
+ ID_MODEL_FROM_DATABASE=AR5413/AR5414 Wireless Network Adapter [AR5006X(S) 802.11abg] (EnGenius EMP-8602 (400mw) or Compex WLM54AG)
 
 pci:v0000168Cd0000001Bsv000017F9sd0000000B*
- ID_MODEL_FROM_DATABASE=WL-711A 802.11abg Wireless CardBus Adapter
+ ID_MODEL_FROM_DATABASE=AR5413/AR5414 Wireless Network Adapter [AR5006X(S) 802.11abg] (WL-711A 802.11abg Wireless CardBus Adapter)
 
 pci:v0000168Cd0000001Bsv000017F9sd0000000C*
- ID_MODEL_FROM_DATABASE=WPIA-112AG 802.11abg Wireless PCI Adapter
+ ID_MODEL_FROM_DATABASE=AR5413/AR5414 Wireless Network Adapter [AR5006X(S) 802.11abg] (WPIA-112AG 802.11abg Wireless PCI Adapter)
 
 pci:v0000168Cd0000001Bsv000017F9sd0000000D*
- ID_MODEL_FROM_DATABASE=PC-686X 802.11abg Wireless Mini PCI Adapter
+ ID_MODEL_FROM_DATABASE=AR5413/AR5414 Wireless Network Adapter [AR5006X(S) 802.11abg] (PC-686X 802.11abg Wireless Mini PCI Adapter)
 
 pci:v0000168Cd0000001Bsv0000185Fsd00001600*
- ID_MODEL_FROM_DATABASE=DCMA-82 High Power WLAN 802.11a/b/g mini-PCI Module (Super A/G, eXtended Range, 400mW)
+ ID_MODEL_FROM_DATABASE=AR5413/AR5414 Wireless Network Adapter [AR5006X(S) 802.11abg] (DCMA-82 High Power WLAN 802.11a/b/g mini-PCI Module (Super A/G, eXtended Range, 400mW))
 
 pci:v0000168Cd0000001Bsv00001948sd00003ABA*
- ID_MODEL_FROM_DATABASE=RBTBJ-AW 802.11abg Wireless Cardbus Adapter
+ ID_MODEL_FROM_DATABASE=AR5413/AR5414 Wireless Network Adapter [AR5006X(S) 802.11abg] (RBTBJ-AW 802.11abg Wireless Cardbus Adapter)
 
 pci:v0000168Cd0000001Bsv0000A727sd00006804*
- ID_MODEL_FROM_DATABASE=Wireless 11a/b/g PC Card with XJACK(r) Antenna
+ ID_MODEL_FROM_DATABASE=AR5413/AR5414 Wireless Network Adapter [AR5006X(S) 802.11abg] (Wireless 11a/b/g PC Card with XJACK(r) Antenna)
 
 pci:v0000168Cd0000001C*
  ID_MODEL_FROM_DATABASE=AR242x / AR542x Wireless Network Adapter (PCI-Express)
 
 pci:v0000168Cd0000001Csv00000777sd00003006*
- ID_MODEL_FROM_DATABASE=SRX 802.11abg Wireless ExpressCard Adapter
+ ID_MODEL_FROM_DATABASE=AR242x / AR542x Wireless Network Adapter (PCI-Express) (SRX 802.11abg Wireless ExpressCard Adapter)
 
 pci:v0000168Cd0000001Csv0000103Csd0000137A*
- ID_MODEL_FROM_DATABASE=AR5BXB63 (Foxconn) 802.11bg Mini PCIe NIC
+ ID_MODEL_FROM_DATABASE=AR242x / AR542x Wireless Network Adapter (PCI-Express) (AR5BXB63 (Foxconn) 802.11bg Mini PCIe NIC)
 
 pci:v0000168Cd0000001Csv0000106Bsd00000086*
- ID_MODEL_FROM_DATABASE=AirPort Extreme
+ ID_MODEL_FROM_DATABASE=AR242x / AR542x Wireless Network Adapter (PCI-Express) (AirPort Extreme)
 
 pci:v0000168Cd0000001Csv0000144Fsd00007106*
- ID_MODEL_FROM_DATABASE=WLL3140 (Toshiba PA3501U-1MPC) 802.11bg Wireless Mini PCIe Card
+ ID_MODEL_FROM_DATABASE=AR242x / AR542x Wireless Network Adapter (PCI-Express) (WLL3140 (Toshiba PA3501U-1MPC) 802.11bg Wireless Mini PCIe Card)
 
 pci:v0000168Cd0000001Csv0000144Fsd00007128*
- ID_MODEL_FROM_DATABASE=WLL3141 (Toshiba PA3613U-1MPC) 802.11bg Wireless Mini PCIe Card
+ ID_MODEL_FROM_DATABASE=AR242x / AR542x Wireless Network Adapter (PCI-Express) (WLL3141 (Toshiba PA3613U-1MPC) 802.11bg Wireless Mini PCIe Card)
 
 pci:v0000168Cd0000001Csv00001468sd00000428*
- ID_MODEL_FROM_DATABASE=AR5BXB63 802.11bg NIC
+ ID_MODEL_FROM_DATABASE=AR242x / AR542x Wireless Network Adapter (PCI-Express) (AR5BXB63 802.11bg NIC)
 
 pci:v0000168Cd0000001Csv00001468sd0000042A*
- ID_MODEL_FROM_DATABASE=AR5007EG 802.11bg NIC
+ ID_MODEL_FROM_DATABASE=AR242x / AR542x Wireless Network Adapter (PCI-Express) (AR5007EG 802.11bg NIC)
 
 pci:v0000168Cd0000001Csv0000147Bsd00001033*
- ID_MODEL_FROM_DATABASE=AirPace Wi-Fi
+ ID_MODEL_FROM_DATABASE=AR242x / AR542x Wireless Network Adapter (PCI-Express) (AirPace Wi-Fi)
 
 pci:v0000168Cd0000001Csv0000168Csd0000001C*
- ID_MODEL_FROM_DATABASE=AR242x 802.11abg NIC (PCI Express)
+ ID_MODEL_FROM_DATABASE=AR242x / AR542x Wireless Network Adapter (PCI-Express) (AR242x 802.11abg NIC (PCI Express))
 
 pci:v0000168Cd0000001Csv0000168Csd00003061*
- ID_MODEL_FROM_DATABASE=AR5006EGS 802.11bg NIC (2.4GHz, PCI Express)
+ ID_MODEL_FROM_DATABASE=AR242x / AR542x Wireless Network Adapter (PCI-Express) (AR5006EGS 802.11bg NIC (2.4GHz, PCI Express))
 
 pci:v0000168Cd0000001Csv0000168Csd00003062*
- ID_MODEL_FROM_DATABASE=AR5006EXS 802.11abg NIC (2.4/5.0GHz, PCI Express)
+ ID_MODEL_FROM_DATABASE=AR242x / AR542x Wireless Network Adapter (PCI-Express) (AR5006EXS 802.11abg NIC (2.4/5.0GHz, PCI Express))
 
 pci:v0000168Cd0000001Csv0000168Csd00003063*
- ID_MODEL_FROM_DATABASE=AR5006EX 802.11abg NIC (2.4/5.0GHz, PCI Express)
+ ID_MODEL_FROM_DATABASE=AR242x / AR542x Wireless Network Adapter (PCI-Express) (AR5006EX 802.11abg NIC (2.4/5.0GHz, PCI Express))
 
 pci:v0000168Cd0000001Csv0000168Csd00003065*
- ID_MODEL_FROM_DATABASE=AR5006EG 802.11bg NIC (2.4GHz, PCI Express)
+ ID_MODEL_FROM_DATABASE=AR242x / AR542x Wireless Network Adapter (PCI-Express) (AR5006EG 802.11bg NIC (2.4GHz, PCI Express))
 
 pci:v0000168Cd0000001Csv0000168Csd00003067*
- ID_MODEL_FROM_DATABASE=AR242x 802.11abg Wireless PCI Express Adapter (rev 01)
+ ID_MODEL_FROM_DATABASE=AR242x / AR542x Wireless Network Adapter (PCI-Express) (AR242x 802.11abg Wireless PCI Express Adapter (rev 01))
 
 pci:v0000168Cd0000001Csv00001A3Bsd00001026*
- ID_MODEL_FROM_DATABASE=AW-GE780 802.11bg Wireless Mini PCIe Card
+ ID_MODEL_FROM_DATABASE=AR242x / AR542x Wireless Network Adapter (PCI-Express) (AW-GE780 802.11bg Wireless Mini PCIe Card)
 
 pci:v0000168Cd0000001D*
  ID_MODEL_FROM_DATABASE=AR2417 Wireless Network Adapter [AR5007G 802.11bg]
 
 pci:v0000168Cd0000001Dsv00001799sd0000720B*
- ID_MODEL_FROM_DATABASE=F5D7000 v8000 Wireless G Desktop Card
+ ID_MODEL_FROM_DATABASE=AR2417 Wireless Network Adapter [AR5007G 802.11bg] (F5D7000 v8000 Wireless G Desktop Card)
 
 pci:v0000168Cd0000001Dsv00001799sd0000721B*
- ID_MODEL_FROM_DATABASE=F5D7010 v8000 Wireless G Notebook Card
+ ID_MODEL_FROM_DATABASE=AR2417 Wireless Network Adapter [AR5007G 802.11bg] (F5D7010 v8000 Wireless G Notebook Card)
 
 pci:v0000168Cd00000020*
  ID_MODEL_FROM_DATABASE=AR5513 802.11abg Wireless NIC
 
 pci:v0000168Cd00000020sv00000308sd00003407*
- ID_MODEL_FROM_DATABASE=M-102 802.11g Wireless Cardbus Adapter
+ ID_MODEL_FROM_DATABASE=AR5513 802.11abg Wireless NIC (M-102 802.11g Wireless Cardbus Adapter)
 
 pci:v0000168Cd00000020sv00001186sd00003A67*
- ID_MODEL_FROM_DATABASE=DWL-G650M Super G MIMO Wireless Notebook Adapter
+ ID_MODEL_FROM_DATABASE=AR5513 802.11abg Wireless NIC (DWL-G650M Super G MIMO Wireless Notebook Adapter)
 
 pci:v0000168Cd00000020sv00001186sd00003A68*
- ID_MODEL_FROM_DATABASE=DWL-G520M Wireless 108G MIMO Desktop Adapter
+ ID_MODEL_FROM_DATABASE=AR5513 802.11abg Wireless NIC (DWL-G520M Wireless 108G MIMO Desktop Adapter)
 
 pci:v0000168Cd00000020sv0000187Esd0000340E*
- ID_MODEL_FROM_DATABASE=M-302 802.11g Wireless PCI Adapter
+ ID_MODEL_FROM_DATABASE=AR5513 802.11abg Wireless NIC (M-302 802.11g Wireless PCI Adapter)
 
 pci:v0000168Cd00000020sv00001976sd00002003*
- ID_MODEL_FROM_DATABASE=TEW-601PC 802.11g Wireless CardBus Adapter
+ ID_MODEL_FROM_DATABASE=AR5513 802.11abg Wireless NIC (TEW-601PC 802.11g Wireless CardBus Adapter)
 
 pci:v0000168Cd00000023*
  ID_MODEL_FROM_DATABASE=AR5416 Wireless Network Adapter [AR5008 802.11(a)bgn]
 
 pci:v0000168Cd00000023sv00000308sd0000340B*
- ID_MODEL_FROM_DATABASE=NWD-170N 802.11bgn Wireless CardBus Adapter
+ ID_MODEL_FROM_DATABASE=AR5416 Wireless Network Adapter [AR5008 802.11(a)bgn] (NWD-170N 802.11bgn Wireless CardBus Adapter)
 
 pci:v0000168Cd00000023sv00001154sd00000365*
- ID_MODEL_FROM_DATABASE=Buffalo WLP-CB-AG300 802.11abgn Cardbus Adapter
+ ID_MODEL_FROM_DATABASE=AR5416 Wireless Network Adapter [AR5008 802.11(a)bgn] (Buffalo WLP-CB-AG300 802.11abgn Cardbus Adapter)
 
 pci:v0000168Cd00000023sv00001154sd00000367*
- ID_MODEL_FROM_DATABASE=WLI-CB-AG301N 802.11abgn Wireless CardBus Adapter
+ ID_MODEL_FROM_DATABASE=AR5416 Wireless Network Adapter [AR5008 802.11(a)bgn] (WLI-CB-AG301N 802.11abgn Wireless CardBus Adapter)
 
 pci:v0000168Cd00000023sv00001186sd00003A6A*
- ID_MODEL_FROM_DATABASE=DWA-642 802.11n RangeBooster N CardBus Adapter
+ ID_MODEL_FROM_DATABASE=AR5416 Wireless Network Adapter [AR5008 802.11(a)bgn] (DWA-642 802.11n RangeBooster N CardBus Adapter)
 
 pci:v0000168Cd00000023sv00001186sd00003A6B*
- ID_MODEL_FROM_DATABASE=DWA-547 802.11n RangeBooster N 650 DeskTop Adapter
+ ID_MODEL_FROM_DATABASE=AR5416 Wireless Network Adapter [AR5008 802.11(a)bgn] (DWA-547 802.11n RangeBooster N 650 DeskTop Adapter)
 
 pci:v0000168Cd00000023sv00001186sd00003A6D*
- ID_MODEL_FROM_DATABASE=DWA-552 802.11n Xtreme N Desktop Adapter (rev A1)
+ ID_MODEL_FROM_DATABASE=AR5416 Wireless Network Adapter [AR5008 802.11(a)bgn] (DWA-552 802.11n Xtreme N Desktop Adapter (rev A1))
 
 pci:v0000168Cd00000023sv00001186sd00003A76*
- ID_MODEL_FROM_DATABASE=DWA-645 802.11n RangeBooster N 650 Notebook Adapter (rev A1)
+ ID_MODEL_FROM_DATABASE=AR5416 Wireless Network Adapter [AR5008 802.11(a)bgn] (DWA-645 802.11n RangeBooster N 650 Notebook Adapter (rev A1))
 
 pci:v0000168Cd00000023sv00001737sd00000059*
- ID_MODEL_FROM_DATABASE=WPC300N v2 Wireless-N Notebook Adapter
+ ID_MODEL_FROM_DATABASE=AR5416 Wireless Network Adapter [AR5008 802.11(a)bgn] (WPC300N v2 Wireless-N Notebook Adapter)
 
 pci:v0000168Cd00000023sv00001737sd00000069*
- ID_MODEL_FROM_DATABASE=WPC100 v1 802.11n RangePlus Wireless Notebook Adapter
+ ID_MODEL_FROM_DATABASE=AR5416 Wireless Network Adapter [AR5008 802.11(a)bgn] (WPC100 v1 802.11n RangePlus Wireless Notebook Adapter)
 
 pci:v0000168Cd00000023sv00001737sd00000072*
- ID_MODEL_FROM_DATABASE=WMP110 v1 802.11n RangePlus Wireless PCI Adapter
+ ID_MODEL_FROM_DATABASE=AR5416 Wireless Network Adapter [AR5008 802.11(a)bgn] (WMP110 v1 802.11n RangePlus Wireless PCI Adapter)
 
 pci:v0000168Cd00000023sv00001799sd00008011*
- ID_MODEL_FROM_DATABASE=F5D8011 v1 802.11n N1 Wireless Notebook Card
+ ID_MODEL_FROM_DATABASE=AR5416 Wireless Network Adapter [AR5008 802.11(a)bgn] (F5D8011 v1 802.11n N1 Wireless Notebook Card)
 
 pci:v0000168Cd00000023sv0000187Esd00003411*
- ID_MODEL_FROM_DATABASE=NWD-370N 802.11n Wireless PCI Adapter
+ ID_MODEL_FROM_DATABASE=AR5416 Wireless Network Adapter [AR5008 802.11(a)bgn] (NWD-370N 802.11n Wireless PCI Adapter)
 
 pci:v0000168Cd00000023sv00001976sd00002008*
- ID_MODEL_FROM_DATABASE=TEW-621PC 802.11bgn Wireless CardBus Adapter
+ ID_MODEL_FROM_DATABASE=AR5416 Wireless Network Adapter [AR5008 802.11(a)bgn] (TEW-621PC 802.11bgn Wireless CardBus Adapter)
 
 pci:v0000168Cd00000024*
  ID_MODEL_FROM_DATABASE=AR5418 Wireless Network Adapter [AR5008E 802.11(a)bgn] (PCI-Express)
 
 pci:v0000168Cd00000024sv0000106Bsd00000087*
- ID_MODEL_FROM_DATABASE=AirPort Extreme
+ ID_MODEL_FROM_DATABASE=AR5418 Wireless Network Adapter [AR5008E 802.11(a)bgn] (PCI-Express) (AirPort Extreme)
 
 pci:v0000168Cd00000024sv00001186sd00003A70*
- ID_MODEL_FROM_DATABASE=DWA-556 Xtreme N PCI Express Desktop Adapter
+ ID_MODEL_FROM_DATABASE=AR5418 Wireless Network Adapter [AR5008E 802.11(a)bgn] (PCI-Express) (DWA-556 Xtreme N PCI Express Desktop Adapter)
 
 pci:v0000168Cd00000027*
  ID_MODEL_FROM_DATABASE=AR9160 Wireless Network Adapter [AR9001 802.11(a)bgn]
 
 pci:v0000168Cd00000027sv00000777sd00004082*
- ID_MODEL_FROM_DATABASE=SR71-A 802.11abgn Wireless Mini PCI Adapter
+ ID_MODEL_FROM_DATABASE=AR9160 Wireless Network Adapter [AR9001 802.11(a)bgn] (SR71-A 802.11abgn Wireless Mini PCI Adapter)
 
 pci:v0000168Cd00000029*
  ID_MODEL_FROM_DATABASE=AR922X Wireless Network Adapter
 
 pci:v0000168Cd00000029sv00000777sd00004005*
- ID_MODEL_FROM_DATABASE=SR71-15 802.11an Mini PCI Adapter
+ ID_MODEL_FROM_DATABASE=AR922X Wireless Network Adapter (SR71-15 802.11an Mini PCI Adapter)
 
 pci:v0000168Cd00000029sv00001186sd00003A7A*
- ID_MODEL_FROM_DATABASE=DWA-552 802.11n Xtreme N Desktop Adapter (rev A2)
+ ID_MODEL_FROM_DATABASE=AR922X Wireless Network Adapter (DWA-552 802.11n Xtreme N Desktop Adapter (rev A2))
 
 pci:v0000168Cd00000029sv00001186sd00003A7D*
- ID_MODEL_FROM_DATABASE=DWA-552 802.11n Xtreme N Desktop Adapter (rev A3)
+ ID_MODEL_FROM_DATABASE=AR922X Wireless Network Adapter (DWA-552 802.11n Xtreme N Desktop Adapter (rev A3))
 
 pci:v0000168Cd0000002A*
  ID_MODEL_FROM_DATABASE=AR928X Wireless Network Adapter (PCI-Express)
 
 pci:v0000168Cd0000002Asv00000777sd00004F05*
- ID_MODEL_FROM_DATABASE=SR71-X 802.11abgn Wireless ExpressCard Adapter [AR9280]
+ ID_MODEL_FROM_DATABASE=AR928X Wireless Network Adapter (PCI-Express) (SR71-X 802.11abgn Wireless ExpressCard Adapter [AR9280])
 
 pci:v0000168Cd0000002Asv0000103Csd00003041*
- ID_MODEL_FROM_DATABASE=AR5BHB92-H 802.11abgn Wireless Half-size Mini PCIe Card [AR9280]
+ ID_MODEL_FROM_DATABASE=AR928X Wireless Network Adapter (PCI-Express) (AR5BHB92-H 802.11abgn Wireless Half-size Mini PCIe Card [AR9280])
 
 pci:v0000168Cd0000002Asv0000105Bsd0000E006*
- ID_MODEL_FROM_DATABASE=T77H053.00 802.11bgn Wireless Mini PCIe Card [AR9281]
+ ID_MODEL_FROM_DATABASE=AR928X Wireless Network Adapter (PCI-Express) (T77H053.00 802.11bgn Wireless Mini PCIe Card [AR9281])
 
 pci:v0000168Cd0000002Asv0000105Bsd0000E01F*
- ID_MODEL_FROM_DATABASE=T77H047.31 802.11bgn Wireless Half-size Mini PCIe Card [AR9283]
+ ID_MODEL_FROM_DATABASE=AR928X Wireless Network Adapter (PCI-Express) (T77H047.31 802.11bgn Wireless Half-size Mini PCIe Card [AR9283])
 
 pci:v0000168Cd0000002Asv0000106Bsd0000008F*
- ID_MODEL_FROM_DATABASE=AirPort Extreme
+ ID_MODEL_FROM_DATABASE=AR928X Wireless Network Adapter (PCI-Express) (AirPort Extreme)
 
 pci:v0000168Cd0000002Asv000011ADsd00006600*
- ID_MODEL_FROM_DATABASE=WN6600A 802.11bgn Wireless Mini PCIe Card [AR9281]
+ ID_MODEL_FROM_DATABASE=AR928X Wireless Network Adapter (PCI-Express) (WN6600A 802.11bgn Wireless Mini PCIe Card [AR9281])
 
 pci:v0000168Cd0000002Asv0000144Fsd00007141*
- ID_MODEL_FROM_DATABASE=WLL6080 802.11bgn Wireless Mini PCIe Card [AR9281]
+ ID_MODEL_FROM_DATABASE=AR928X Wireless Network Adapter (PCI-Express) (WLL6080 802.11bgn Wireless Mini PCIe Card [AR9281])
 
 pci:v0000168Cd0000002Asv0000168Csd00000203*
- ID_MODEL_FROM_DATABASE=DW1525 802.11abgn WLAN PCIe Card [AR9280]
+ ID_MODEL_FROM_DATABASE=AR928X Wireless Network Adapter (PCI-Express) (DW1525 802.11abgn WLAN PCIe Card [AR9280])
 
 pci:v0000168Cd0000002Asv00001A32sd00000303*
- ID_MODEL_FROM_DATABASE=EM303 802.11bgn Wireless Mini PCIe Card [AR9281]
+ ID_MODEL_FROM_DATABASE=AR928X Wireless Network Adapter (PCI-Express) (EM303 802.11bgn Wireless Mini PCIe Card [AR9281])
 
 pci:v0000168Cd0000002Asv00001A32sd00000306*
- ID_MODEL_FROM_DATABASE=EM306 802.11bgn Wireless Half-size Mini PCIe Card [AR9283]
+ ID_MODEL_FROM_DATABASE=AR928X Wireless Network Adapter (PCI-Express) (EM306 802.11bgn Wireless Half-size Mini PCIe Card [AR9283])
 
 pci:v0000168Cd0000002Asv00001A3Bsd00001067*
- ID_MODEL_FROM_DATABASE=AW-NE771 802.11bgn Wireless Mini PCIe Card [AR9281]
+ ID_MODEL_FROM_DATABASE=AR928X Wireless Network Adapter (PCI-Express) (AW-NE771 802.11bgn Wireless Mini PCIe Card [AR9281])
 
 pci:v0000168Cd0000002Asv00001A3Bsd00001081*
- ID_MODEL_FROM_DATABASE=AW-NE773 802.11abgn Wireless Half-size Mini PCIe Card [AR9280]
+ ID_MODEL_FROM_DATABASE=AR928X Wireless Network Adapter (PCI-Express) (AW-NE773 802.11abgn Wireless Half-size Mini PCIe Card [AR9280])
 
 pci:v0000168Cd0000002B*
  ID_MODEL_FROM_DATABASE=AR9285 Wireless Network Adapter (PCI-Express)
 
 pci:v0000168Cd0000002Bsv00001028sd00000204*
- ID_MODEL_FROM_DATABASE=Wireless 1502 802.11bgn Half-size Mini PCIe Card
+ ID_MODEL_FROM_DATABASE=AR9285 Wireless Network Adapter (PCI-Express) (Wireless 1502 802.11bgn Half-size Mini PCIe Card)
 
 pci:v0000168Cd0000002Bsv00001028sd00000205*
- ID_MODEL_FROM_DATABASE=Wireless 1702 802.11bgn Half-size Mini PCIe Card [AR9002WB-1NGCD]
+ ID_MODEL_FROM_DATABASE=AR9285 Wireless Network Adapter (PCI-Express) (Wireless 1702 802.11bgn Half-size Mini PCIe Card [AR9002WB-1NGCD])
 
 pci:v0000168Cd0000002Bsv0000103Csd0000303F*
- ID_MODEL_FROM_DATABASE=U98Z062.10 802.11bgn Wireless Half-size Mini PCIe Card
+ ID_MODEL_FROM_DATABASE=AR9285 Wireless Network Adapter (PCI-Express) (U98Z062.10 802.11bgn Wireless Half-size Mini PCIe Card)
 
 pci:v0000168Cd0000002Bsv0000103Csd00003040*
- ID_MODEL_FROM_DATABASE=U98Z062.12 802.11bgn Wireless Half-size Mini PCIe Card
+ ID_MODEL_FROM_DATABASE=AR9285 Wireless Network Adapter (PCI-Express) (U98Z062.12 802.11bgn Wireless Half-size Mini PCIe Card)
 
 pci:v0000168Cd0000002Bsv0000105Bsd0000E017*
- ID_MODEL_FROM_DATABASE=T77H126.00 802.11bgn Wireless Half-size Mini PCIe Card
+ ID_MODEL_FROM_DATABASE=AR9285 Wireless Network Adapter (PCI-Express) (T77H126.00 802.11bgn Wireless Half-size Mini PCIe Card)
 
 pci:v0000168Cd0000002Bsv0000105Bsd0000E023*
- ID_MODEL_FROM_DATABASE=T77H121.04 802.11bgn Wireless Half-size Mini PCIe Card
+ ID_MODEL_FROM_DATABASE=AR9285 Wireless Network Adapter (PCI-Express) (T77H121.04 802.11bgn Wireless Half-size Mini PCIe Card)
+
+pci:v0000168Cd0000002Bsv0000105Bsd0000E025*
+ ID_MODEL_FROM_DATABASE=AR9285 Wireless Network Adapter (PCI-Express) (T77H121.05 802.11bgn Wireless Half-size Mini PCIe Card)
 
 pci:v0000168Cd0000002Bsv00001113sd0000E811*
- ID_MODEL_FROM_DATABASE=WN7811A (Toshiba PA3722U-1MPC) 802.11bgn Wireless Half-size Mini PCIe Card
+ ID_MODEL_FROM_DATABASE=AR9285 Wireless Network Adapter (PCI-Express) (WN7811A (Toshiba PA3722U-1MPC) 802.11bgn Wireless Half-size Mini PCIe Card)
 
 pci:v0000168Cd0000002Bsv0000185Fsd000030AF*
- ID_MODEL_FROM_DATABASE=DNXA-95 802.11bgn Wireless Half-size Mini PCIe Card
+ ID_MODEL_FROM_DATABASE=AR9285 Wireless Network Adapter (PCI-Express) (DNXA-95 802.11bgn Wireless Half-size Mini PCIe Card)
 
 pci:v0000168Cd0000002Bsv00001931sd00000023*
- ID_MODEL_FROM_DATABASE=Option GTM67x PCIe WiFi Adapter
+ ID_MODEL_FROM_DATABASE=AR9285 Wireless Network Adapter (PCI-Express) (Option GTM67x PCIe WiFi Adapter)
 
 pci:v0000168Cd0000002Bsv00001A3Bsd00001089*
- ID_MODEL_FROM_DATABASE=AW-NE785 / AW-NE785H 802.11bgn Wireless Full or Half-size Mini PCIe Card
+ ID_MODEL_FROM_DATABASE=AR9285 Wireless Network Adapter (PCI-Express) (AW-NE785 / AW-NE785H 802.11bgn Wireless Full or Half-size Mini PCIe Card)
 
 pci:v0000168Cd0000002Bsv00001A3Bsd00002C37*
- ID_MODEL_FROM_DATABASE=AW-NB037H 802.11bgn Wireless Half-size Mini PCIe Card [AR9002WB-1NGCD]
+ ID_MODEL_FROM_DATABASE=AR9285 Wireless Network Adapter (PCI-Express) (AW-NB037H 802.11bgn Wireless Half-size Mini PCIe Card [AR9002WB-1NGCD])
 
 pci:v0000168Cd0000002Bsv00001B9Asd00000401*
- ID_MODEL_FROM_DATABASE=XW204E 802.11bgn Wireless Half-size Mini PCIe Card
+ ID_MODEL_FROM_DATABASE=AR9285 Wireless Network Adapter (PCI-Express) (XW204E 802.11bgn Wireless Half-size Mini PCIe Card)
 
 pci:v0000168Cd0000002Bsv00001B9Asd00000C03*
- ID_MODEL_FROM_DATABASE=WB214E 802.11bgn Wireless Half-size Mini PCIe Card [AR9002WB-1NGCD]
+ ID_MODEL_FROM_DATABASE=AR9285 Wireless Network Adapter (PCI-Express) (WB214E 802.11bgn Wireless Half-size Mini PCIe Card [AR9002WB-1NGCD])
 
 pci:v0000168Cd0000002C*
  ID_MODEL_FROM_DATABASE=AR2427 802.11bg Wireless Network Adapter (PCI-Express)
@@ -48183,25 +49455,25 @@ pci:v0000168Cd00000030*
  ID_MODEL_FROM_DATABASE=AR93xx Wireless Network Adapter
 
 pci:v0000168Cd00000030sv0000103Csd00001627*
- ID_MODEL_FROM_DATABASE=AR9380/HB112 802.11abgn 3×3 Wi-Fi Adapter
+ ID_MODEL_FROM_DATABASE=AR93xx Wireless Network Adapter (AR9380/HB112 802.11abgn 3×3 Wi-Fi Adapter)
 
 pci:v0000168Cd00000030sv0000106Bsd0000009A*
- ID_MODEL_FROM_DATABASE=AirPort Extreme
+ ID_MODEL_FROM_DATABASE=AR93xx Wireless Network Adapter (AirPort Extreme)
 
 pci:v0000168Cd00000030sv00001186sd00003A7E*
- ID_MODEL_FROM_DATABASE=DWA-566 Wireless N 300 Dual Band PCIe Desktop Adapter
+ ID_MODEL_FROM_DATABASE=AR93xx Wireless Network Adapter (DWA-566 Wireless N 300 Dual Band PCIe Desktop Adapter)
 
 pci:v0000168Cd00000030sv00001A56sd00002000*
- ID_MODEL_FROM_DATABASE=Killer Wireless-N 1102 Half-size Mini PCIe Card [AR9382]
+ ID_MODEL_FROM_DATABASE=AR93xx Wireless Network Adapter (Killer Wireless-N 1102 Half-size Mini PCIe Card [AR9382])
 
 pci:v0000168Cd00000030sv00001A56sd00002001*
- ID_MODEL_FROM_DATABASE=Killer Wireless-N 1103 Half-size Mini PCIe Card [AR9380]
+ ID_MODEL_FROM_DATABASE=AR93xx Wireless Network Adapter (Killer Wireless-N 1103 Half-size Mini PCIe Card [AR9380])
 
 pci:v0000168Cd00000032*
  ID_MODEL_FROM_DATABASE=AR9485 Wireless Network Adapter
 
 pci:v0000168Cd00000032sv0000103Csd00001838*
- ID_MODEL_FROM_DATABASE=AR9485/HB125 802.11bgn 1×1 Wi-Fi Adapter
+ ID_MODEL_FROM_DATABASE=AR9485 Wireless Network Adapter (AR9485/HB125 802.11bgn 1×1 Wi-Fi Adapter)
 
 pci:v0000168Cd00000033*
  ID_MODEL_FROM_DATABASE=AR9580 Wireless Network Adapter
@@ -48210,7 +49482,7 @@ pci:v0000168Cd00000034*
  ID_MODEL_FROM_DATABASE=AR9462 Wireless Network Adapter
 
 pci:v0000168Cd00000034sv00001A56sd00002003*
- ID_MODEL_FROM_DATABASE=Killer Wireless-N 1202 Half-size Mini PCIe Card
+ ID_MODEL_FROM_DATABASE=AR9462 Wireless Network Adapter (Killer Wireless-N 1202 Half-size Mini PCIe Card)
 
 pci:v0000168Cd00000036*
  ID_MODEL_FROM_DATABASE=QCA9565 / AR9565 Wireless Network Adapter
@@ -48219,7 +49491,7 @@ pci:v0000168Cd00000037*
  ID_MODEL_FROM_DATABASE=AR9485 Wireless Network Adapter
 
 pci:v0000168Cd00000037sv00001A3Bsd00002100*
- ID_MODEL_FROM_DATABASE=AW-NB100H 802.11n Wireless Mini PCIe Card
+ ID_MODEL_FROM_DATABASE=AR9485 Wireless Network Adapter (AW-NB100H 802.11n Wireless Mini PCIe Card)
 
 pci:v0000168Cd0000003C*
  ID_MODEL_FROM_DATABASE=QCA988x 802.11ac Wireless Network Adapter
@@ -48231,7 +49503,7 @@ pci:v0000168Cd00001014*
  ID_MODEL_FROM_DATABASE=AR5212 802.11abg NIC
 
 pci:v0000168Cd00001014sv00001014sd0000058A*
- ID_MODEL_FROM_DATABASE=ThinkPad 11a/b/g Wireless LAN Mini Express Adapter (AR5BXB6)
+ ID_MODEL_FROM_DATABASE=AR5212 802.11abg NIC (ThinkPad 11a/b/g Wireless LAN Mini Express Adapter (AR5BXB6))
 
 pci:v0000168Cd00009013*
  ID_MODEL_FROM_DATABASE=AR5002X Wireless Network Adapter
@@ -48249,7 +49521,7 @@ pci:v0000168Cd0000FF1D*
  ID_MODEL_FROM_DATABASE=AR922x Wireless Network Adapter
 
 pci:v0000168Cd0000FF1Dsv0000168Csd0000EE1C*
- ID_MODEL_FROM_DATABASE=AR9220-AC1A [AVM Fritz!Box FON WLAN 7270 v3]
+ ID_MODEL_FROM_DATABASE=AR922x Wireless Network Adapter (AR9220-AC1A [AVM Fritz!Box FON WLAN 7270 v3])
 
 pci:v00001695*
  ID_VENDOR_FROM_DATABASE=EPoX Computer Co., Ltd.
@@ -48308,6 +49580,9 @@ pci:v000016B8*
 pci:v000016BE*
  ID_VENDOR_FROM_DATABASE=Creatix Polymedia GmbH
 
+pci:v000016C3*
+ ID_VENDOR_FROM_DATABASE=Synopsys, Inc.
+
 pci:v000016C6*
  ID_VENDOR_FROM_DATABASE=Micrel-Kendin
 
@@ -48648,16 +49923,16 @@ pci:v00001737d00001032*
  ID_MODEL_FROM_DATABASE=Gigabit Network Adapter
 
 pci:v00001737d00001032sv00001737sd00000015*
- ID_MODEL_FROM_DATABASE=EG1032 v2 Instant Gigabit Network Adapter
+ ID_MODEL_FROM_DATABASE=Gigabit Network Adapter (EG1032 v2 Instant Gigabit Network Adapter)
 
 pci:v00001737d00001032sv00001737sd00000024*
- ID_MODEL_FROM_DATABASE=EG1032 v3 Instant Gigabit Network Adapter
+ ID_MODEL_FROM_DATABASE=Gigabit Network Adapter (EG1032 v3 Instant Gigabit Network Adapter)
 
 pci:v00001737d00001064*
  ID_MODEL_FROM_DATABASE=Gigabit Network Adapter
 
 pci:v00001737d00001064sv00001737sd00000016*
- ID_MODEL_FROM_DATABASE=EG1064 v2 Instant Gigabit Network Adapter
+ ID_MODEL_FROM_DATABASE=Gigabit Network Adapter (EG1064 v2 Instant Gigabit Network Adapter)
 
 pci:v00001737d0000AB08*
  ID_MODEL_FROM_DATABASE=21x4x DEC-Tulip compatible 10/100 Ethernet
@@ -48678,7 +49953,7 @@ pci:v0000173Bd000003EA*
  ID_MODEL_FROM_DATABASE=AC9100 Gigabit Ethernet
 
 pci:v0000173Bd000003EAsv0000173Bsd00000001*
- ID_MODEL_FROM_DATABASE=AC1002
+ ID_MODEL_FROM_DATABASE=AC9100 Gigabit Ethernet (AC1002)
 
 pci:v0000173Bd000003EB*
  ID_MODEL_FROM_DATABASE=AC1003 Gigabit Ethernet
@@ -48854,6 +50129,18 @@ pci:v00001797d00006812*
 pci:v00001797d00006813*
  ID_MODEL_FROM_DATABASE=TW6816 multimedia video controller
 
+pci:v00001797d00006814*
+ ID_MODEL_FROM_DATABASE=TW6816 multimedia video controller
+
+pci:v00001797d00006815*
+ ID_MODEL_FROM_DATABASE=TW6816 multimedia video controller
+
+pci:v00001797d00006816*
+ ID_MODEL_FROM_DATABASE=TW6816 multimedia video controller
+
+pci:v00001797d00006817*
+ ID_MODEL_FROM_DATABASE=TW6816 multimedia video controller
+
 pci:v00001799*
  ID_VENDOR_FROM_DATABASE=Belkin
 
@@ -48963,19 +50250,19 @@ pci:v000017CBd00000001*
  ID_MODEL_FROM_DATABASE=AGN100 802.11 a/b/g True MIMO Wireless Card
 
 pci:v000017CBd00000001sv00001385sd00005C00*
- ID_MODEL_FROM_DATABASE=WGM511 Pre-N 802.11g Wireless CardBus Adapter
+ ID_MODEL_FROM_DATABASE=AGN100 802.11 a/b/g True MIMO Wireless Card (WGM511 Pre-N 802.11g Wireless CardBus Adapter)
 
 pci:v000017CBd00000001sv00001737sd00000045*
- ID_MODEL_FROM_DATABASE=WMP54GX v1 802.11g Wireless-G PCI Adapter with SRX
+ ID_MODEL_FROM_DATABASE=AGN100 802.11 a/b/g True MIMO Wireless Card (WMP54GX v1 802.11g Wireless-G PCI Adapter with SRX)
 
 pci:v000017CBd00000002*
  ID_MODEL_FROM_DATABASE=AGN300 802.11 a/b/g True MIMO Wireless Card
 
 pci:v000017CBd00000002sv00001385sd00006D00*
- ID_MODEL_FROM_DATABASE=WPNT511 RangeMax 240 Mbps Wireless CardBus Adapter
+ ID_MODEL_FROM_DATABASE=AGN300 802.11 a/b/g True MIMO Wireless Card (WPNT511 RangeMax 240 Mbps Wireless CardBus Adapter)
 
 pci:v000017CBd00000002sv00001737sd00000054*
- ID_MODEL_FROM_DATABASE=WPC54GX4 v1 802.11g Wireless-G Notebook Adapter with SRX400
+ ID_MODEL_FROM_DATABASE=AGN300 802.11 a/b/g True MIMO Wireless Card (WPC54GX4 v1 802.11g Wireless-G Notebook Adapter with SRX400)
 
 pci:v000017CC*
  ID_VENDOR_FROM_DATABASE=NetChip Technology, Inc
@@ -49026,7 +50313,7 @@ pci:v000017D3d00001280*
  ID_MODEL_FROM_DATABASE=ARC-1280/1280ML 24-Port PCI-Express to SATA II RAID Controller
 
 pci:v000017D3d00001280sv000017D3sd00001221*
- ID_MODEL_FROM_DATABASE=ARC-1221 8-Port PCI-Express to SATA RAID Controller
+ ID_MODEL_FROM_DATABASE=ARC-1280/1280ML 24-Port PCI-Express to SATA II RAID Controller (ARC-1221 8-Port PCI-Express to SATA RAID Controller)
 
 pci:v000017D3d00001300*
  ID_MODEL_FROM_DATABASE=ARC-1300ix-16 16-Port PCI-Express to SAS Non-RAID Host Adapter
@@ -49035,7 +50322,7 @@ pci:v000017D3d00001680*
  ID_MODEL_FROM_DATABASE=ARC-1680 8 port PCIe/PCI-X to SAS/SATA II RAID Controller
 
 pci:v000017D3d00001680sv000017D3sd00001212*
- ID_MODEL_FROM_DATABASE=ARC-1212 4-Port PCIe to SAS/SATA II RAID Controller
+ ID_MODEL_FROM_DATABASE=ARC-1680 8 port PCIe/PCI-X to SAS/SATA II RAID Controller (ARC-1212 4-Port PCIe to SAS/SATA II RAID Controller)
 
 pci:v000017D3d00001880*
  ID_MODEL_FROM_DATABASE=ARC-1880 8/12 port PCIe/PCI-X to SAS/SATA II RAID Controller
@@ -49053,82 +50340,82 @@ pci:v000017D5d00005831*
  ID_MODEL_FROM_DATABASE=Xframe 10-Gigabit Ethernet PCI-X
 
 pci:v000017D5d00005831sv0000103Csd000012D5*
- ID_MODEL_FROM_DATABASE=PCI-X 133MHz 10GbE SR Fiber
+ ID_MODEL_FROM_DATABASE=Xframe 10-Gigabit Ethernet PCI-X (PCI-X 133MHz 10GbE SR Fiber)
 
 pci:v000017D5d00005831sv000010A9sd00008020*
- ID_MODEL_FROM_DATABASE=Single Port 10-Gigabit Ethernet (PCI-X, Fiber)
+ ID_MODEL_FROM_DATABASE=Xframe 10-Gigabit Ethernet PCI-X (Single Port 10-Gigabit Ethernet (PCI-X, Fiber))
 
 pci:v000017D5d00005831sv000010A9sd00008024*
- ID_MODEL_FROM_DATABASE=Single Port 10-Gigabit Ethernet (PCI-X, Fiber)
+ ID_MODEL_FROM_DATABASE=Xframe 10-Gigabit Ethernet PCI-X (Single Port 10-Gigabit Ethernet (PCI-X, Fiber))
 
 pci:v000017D5d00005832*
  ID_MODEL_FROM_DATABASE=Xframe II 10-Gigabit Ethernet PCI-X 2.0
 
 pci:v000017D5d00005832sv0000103Csd00001337*
- ID_MODEL_FROM_DATABASE=PCI-X 266MHz 10GigE SR [AD385A]
+ ID_MODEL_FROM_DATABASE=Xframe II 10-Gigabit Ethernet PCI-X 2.0 (PCI-X 266MHz 10GigE SR [AD385A])
 
 pci:v000017D5d00005832sv000010A9sd00008021*
- ID_MODEL_FROM_DATABASE=Single Port 10-Gigabit Ethernet II (PCI-X, Fiber)
+ ID_MODEL_FROM_DATABASE=Xframe II 10-Gigabit Ethernet PCI-X 2.0 (Single Port 10-Gigabit Ethernet II (PCI-X, Fiber))
 
 pci:v000017D5d00005832sv000017D5sd00006020*
- ID_MODEL_FROM_DATABASE=Xframe II SR
+ ID_MODEL_FROM_DATABASE=Xframe II 10-Gigabit Ethernet PCI-X 2.0 (Xframe II SR)
 
 pci:v000017D5d00005832sv000017D5sd00006021*
- ID_MODEL_FROM_DATABASE=Xframe II SR, Low Profile
+ ID_MODEL_FROM_DATABASE=Xframe II 10-Gigabit Ethernet PCI-X 2.0 (Xframe II SR, Low Profile)
 
 pci:v000017D5d00005832sv000017D5sd00006022*
- ID_MODEL_FROM_DATABASE=Xframe E SR
+ ID_MODEL_FROM_DATABASE=Xframe II 10-Gigabit Ethernet PCI-X 2.0 (Xframe E SR)
 
 pci:v000017D5d00005832sv000017D5sd00006420*
- ID_MODEL_FROM_DATABASE=Xframe II LR
+ ID_MODEL_FROM_DATABASE=Xframe II 10-Gigabit Ethernet PCI-X 2.0 (Xframe II LR)
 
 pci:v000017D5d00005832sv000017D5sd00006421*
- ID_MODEL_FROM_DATABASE=Xframe II LR, Low Profile
+ ID_MODEL_FROM_DATABASE=Xframe II 10-Gigabit Ethernet PCI-X 2.0 (Xframe II LR, Low Profile)
 
 pci:v000017D5d00005832sv000017D5sd00006422*
- ID_MODEL_FROM_DATABASE=Xframe E LR
+ ID_MODEL_FROM_DATABASE=Xframe II 10-Gigabit Ethernet PCI-X 2.0 (Xframe E LR)
 
 pci:v000017D5d00005832sv000017D5sd00006C20*
- ID_MODEL_FROM_DATABASE=Xframe II CX4
+ ID_MODEL_FROM_DATABASE=Xframe II 10-Gigabit Ethernet PCI-X 2.0 (Xframe II CX4)
 
 pci:v000017D5d00005832sv000017D5sd00006C21*
- ID_MODEL_FROM_DATABASE=Xframe II CX4, Low Profile
+ ID_MODEL_FROM_DATABASE=Xframe II 10-Gigabit Ethernet PCI-X 2.0 (Xframe II CX4, Low Profile)
 
 pci:v000017D5d00005832sv000017D5sd00006C22*
- ID_MODEL_FROM_DATABASE=Xframe E CX4
+ ID_MODEL_FROM_DATABASE=Xframe II 10-Gigabit Ethernet PCI-X 2.0 (Xframe E CX4)
 
 pci:v000017D5d00005833*
  ID_MODEL_FROM_DATABASE=X3100 Series 10 Gigabit Ethernet PCIe
 
 pci:v000017D5d00005833sv000017D5sd00006030*
- ID_MODEL_FROM_DATABASE=X3110 Single Port SR
+ ID_MODEL_FROM_DATABASE=X3100 Series 10 Gigabit Ethernet PCIe (X3110 Single Port SR)
 
 pci:v000017D5d00005833sv000017D5sd00006031*
- ID_MODEL_FROM_DATABASE=X3120 Dual Port SR
+ ID_MODEL_FROM_DATABASE=X3100 Series 10 Gigabit Ethernet PCIe (X3120 Dual Port SR)
 
 pci:v000017D5d00005833sv000017D5sd00006430*
- ID_MODEL_FROM_DATABASE=X3110 Single Port LR
+ ID_MODEL_FROM_DATABASE=X3100 Series 10 Gigabit Ethernet PCIe (X3110 Single Port LR)
 
 pci:v000017D5d00005833sv000017D5sd00006431*
- ID_MODEL_FROM_DATABASE=X3120 Dual Port LR
+ ID_MODEL_FROM_DATABASE=X3100 Series 10 Gigabit Ethernet PCIe (X3120 Dual Port LR)
 
 pci:v000017D5d00005833sv000017D5sd00007030*
- ID_MODEL_FROM_DATABASE=X3110 Single Port LRM
+ ID_MODEL_FROM_DATABASE=X3100 Series 10 Gigabit Ethernet PCIe (X3110 Single Port LRM)
 
 pci:v000017D5d00005833sv000017D5sd00007031*
- ID_MODEL_FROM_DATABASE=X3120 Dual Port LRM
+ ID_MODEL_FROM_DATABASE=X3100 Series 10 Gigabit Ethernet PCIe (X3120 Dual Port LRM)
 
 pci:v000017D5d00005833sv000017D5sd00007430*
- ID_MODEL_FROM_DATABASE=X3110 Single Port 10GBase-T
+ ID_MODEL_FROM_DATABASE=X3100 Series 10 Gigabit Ethernet PCIe (X3110 Single Port 10GBase-T)
 
 pci:v000017D5d00005833sv000017D5sd00007431*
- ID_MODEL_FROM_DATABASE=X3120 Dual Port 10GBase-T
+ ID_MODEL_FROM_DATABASE=X3100 Series 10 Gigabit Ethernet PCIe (X3120 Dual Port 10GBase-T)
 
 pci:v000017D5d00005833sv000017D5sd00007830*
- ID_MODEL_FROM_DATABASE=X3110 Single Port 10GBase-CR
+ ID_MODEL_FROM_DATABASE=X3100 Series 10 Gigabit Ethernet PCIe (X3110 Single Port 10GBase-CR)
 
 pci:v000017D5d00005833sv000017D5sd00007831*
- ID_MODEL_FROM_DATABASE=X3120 Dual Port 10GBase-CR
+ ID_MODEL_FROM_DATABASE=X3100 Series 10 Gigabit Ethernet PCIe (X3120 Dual Port 10GBase-CR)
 
 pci:v000017DB*
  ID_VENDOR_FROM_DATABASE=Cray Inc
@@ -49215,16 +50502,16 @@ pci:v000017FEd00002120*
  ID_MODEL_FROM_DATABASE=IPN 2120 802.11b
 
 pci:v000017FEd00002120sv00001737sd00000020*
- ID_MODEL_FROM_DATABASE=WMP11 v4 802.11b Wireless-B PCI Adapter
+ ID_MODEL_FROM_DATABASE=IPN 2120 802.11b (WMP11 v4 802.11b Wireless-B PCI Adapter)
 
 pci:v000017FEd00002220*
  ID_MODEL_FROM_DATABASE=IPN 2220 802.11g
 
 pci:v000017FEd00002220sv00001468sd00000305*
- ID_MODEL_FROM_DATABASE=T60N871 802.11g Mini PCI Wireless Adapter
+ ID_MODEL_FROM_DATABASE=IPN 2220 802.11g (T60N871 802.11g Mini PCI Wireless Adapter)
 
 pci:v000017FEd00002220sv00001737sd00000029*
- ID_MODEL_FROM_DATABASE=WPC54G v4 802.11g Wireless-G Notebook Adapter
+ ID_MODEL_FROM_DATABASE=IPN 2220 802.11g (WPC54G v4 802.11g Wireless-G Notebook Adapter)
 
 pci:v000017FF*
  ID_VENDOR_FROM_DATABASE=Benq Corporation
@@ -49245,13 +50532,13 @@ pci:v00001813d00004000*
  ID_MODEL_FROM_DATABASE=HaM controllerless modem
 
 pci:v00001813d00004000sv000016BEsd00000001*
- ID_MODEL_FROM_DATABASE=V9x HAM Data Fax Modem
+ ID_MODEL_FROM_DATABASE=HaM controllerless modem (V9x HAM Data Fax Modem)
 
 pci:v00001813d00004100*
  ID_MODEL_FROM_DATABASE=HaM plus Data Fax Modem
 
 pci:v00001813d00004100sv000016BEsd00000002*
- ID_MODEL_FROM_DATABASE=V9x HAM 1394
+ ID_MODEL_FROM_DATABASE=HaM plus Data Fax Modem (V9x HAM 1394)
 
 pci:v00001814*
  ID_VENDOR_FROM_DATABASE=Ralink corp.
@@ -49260,13 +50547,13 @@ pci:v00001814d00000101*
  ID_MODEL_FROM_DATABASE=Wireless PCI Adapter RT2400 / RT2460
 
 pci:v00001814d00000101sv00001043sd00000127*
- ID_MODEL_FROM_DATABASE=WiFi-b add-on Card
+ ID_MODEL_FROM_DATABASE=Wireless PCI Adapter RT2400 / RT2460 (WiFi-b add-on Card)
 
 pci:v00001814d00000101sv00001371sd00000010*
- ID_MODEL_FROM_DATABASE=Minitar MNW2BPCI Wireless PCI Card
+ ID_MODEL_FROM_DATABASE=Wireless PCI Adapter RT2400 / RT2460 (Minitar MNW2BPCI Wireless PCI Card)
 
 pci:v00001814d00000101sv00001462sd00006828*
- ID_MODEL_FROM_DATABASE=PC11B2 (MS-6828) Wireless 11b PCI Card
+ ID_MODEL_FROM_DATABASE=Wireless PCI Adapter RT2400 / RT2460 (PC11B2 (MS-6828) Wireless 11b PCI Card)
 
 pci:v00001814d00000200*
  ID_MODEL_FROM_DATABASE=RT2500 802.11g PCI [PC54G2]
@@ -49275,58 +50562,58 @@ pci:v00001814d00000201*
  ID_MODEL_FROM_DATABASE=RT2500 Wireless 802.11bg
 
 pci:v00001814d00000201sv00001043sd0000130F*
- ID_MODEL_FROM_DATABASE=WL-130g
+ ID_MODEL_FROM_DATABASE=RT2500 Wireless 802.11bg (WL-130g)
 
 pci:v00001814d00000201sv00001186sd00003C00*
- ID_MODEL_FROM_DATABASE=DWL-G650X Wireless 11g CardBus Adapter
+ ID_MODEL_FROM_DATABASE=RT2500 Wireless 802.11bg (DWL-G650X Wireless 11g CardBus Adapter)
 
 pci:v00001814d00000201sv00001371sd0000001E*
- ID_MODEL_FROM_DATABASE=CWC-854 Wireless-G CardBus Adapter
+ ID_MODEL_FROM_DATABASE=RT2500 Wireless 802.11bg (CWC-854 Wireless-G CardBus Adapter)
 
 pci:v00001814d00000201sv00001371sd0000001F*
- ID_MODEL_FROM_DATABASE=CWM-854 Wireless-G Mini PCI Adapter
+ ID_MODEL_FROM_DATABASE=RT2500 Wireless 802.11bg (CWM-854 Wireless-G Mini PCI Adapter)
 
 pci:v00001814d00000201sv00001371sd00000020*
- ID_MODEL_FROM_DATABASE=CWP-854 Wireless-G PCI Adapter
+ ID_MODEL_FROM_DATABASE=RT2500 Wireless 802.11bg (CWP-854 Wireless-G PCI Adapter)
 
 pci:v00001814d00000201sv00001458sd0000E381*
- ID_MODEL_FROM_DATABASE=GN-WMKG 802.11b/g Wireless CardBus Adapter
+ ID_MODEL_FROM_DATABASE=RT2500 Wireless 802.11bg (GN-WMKG 802.11b/g Wireless CardBus Adapter)
 
 pci:v00001814d00000201sv00001458sd0000E931*
- ID_MODEL_FROM_DATABASE=GN-WIKG 802.11b/g mini-PCI Adapter
+ ID_MODEL_FROM_DATABASE=RT2500 Wireless 802.11bg (GN-WIKG 802.11b/g mini-PCI Adapter)
 
 pci:v00001814d00000201sv00001462sd00006833*
- ID_MODEL_FROM_DATABASE=Unknown 802.11g mini-PCI Adapter
+ ID_MODEL_FROM_DATABASE=RT2500 Wireless 802.11bg (Unknown 802.11g mini-PCI Adapter)
 
 pci:v00001814d00000201sv00001462sd00006835*
- ID_MODEL_FROM_DATABASE=Wireless 11G CardBus CB54G2
+ ID_MODEL_FROM_DATABASE=RT2500 Wireless 802.11bg (Wireless 11G CardBus CB54G2)
 
 pci:v00001814d00000201sv00001737sd00000032*
- ID_MODEL_FROM_DATABASE=WMP54G v4.0 PCI Adapter
+ ID_MODEL_FROM_DATABASE=RT2500 Wireless 802.11bg (WMP54G v4.0 PCI Adapter)
 
 pci:v00001814d00000201sv00001799sd0000700A*
- ID_MODEL_FROM_DATABASE=F5D7000 v2000/v3000 Wireless G Desktop Card
+ ID_MODEL_FROM_DATABASE=RT2500 Wireless 802.11bg (F5D7000 v2000/v3000 Wireless G Desktop Card)
 
 pci:v00001814d00000201sv00001799sd0000701A*
- ID_MODEL_FROM_DATABASE=F5D7010 v2000/v3000 Wireless G Notebook Card
+ ID_MODEL_FROM_DATABASE=RT2500 Wireless 802.11bg (F5D7010 v2000/v3000 Wireless G Notebook Card)
 
 pci:v00001814d00000201sv00001814sd00002560*
  ID_MODEL_FROM_DATABASE=RT2500 Wireless 802.11bg
 
 pci:v00001814d00000201sv0000182Dsd00009073*
- ID_MODEL_FROM_DATABASE=WL-115 Wireless Network PCI Adapter
+ ID_MODEL_FROM_DATABASE=RT2500 Wireless 802.11bg (WL-115 Wireless Network PCI Adapter)
 
 pci:v00001814d00000201sv0000185Fsd000022A0*
- ID_MODEL_FROM_DATABASE=CN-WF513 Wireless Cardbus Adapter
+ ID_MODEL_FROM_DATABASE=RT2500 Wireless 802.11bg (CN-WF513 Wireless Cardbus Adapter)
 
 pci:v00001814d00000201sv000018EBsd00005312*
- ID_MODEL_FROM_DATABASE=WL531P IEEE 802.11g PCI Card-EU
+ ID_MODEL_FROM_DATABASE=RT2500 Wireless 802.11bg (WL531P IEEE 802.11g PCI Card-EU)
 
 pci:v00001814d00000201sv00001948sd00003C00*
- ID_MODEL_FROM_DATABASE=C54RC v1 Wireless 11g CardBus Adapter
+ ID_MODEL_FROM_DATABASE=RT2500 Wireless 802.11bg (C54RC v1 Wireless 11g CardBus Adapter)
 
 pci:v00001814d00000201sv00001948sd00003C01*
- ID_MODEL_FROM_DATABASE=C54Ri v1 Wireless 11g PCI Adapter
+ ID_MODEL_FROM_DATABASE=RT2500 Wireless 802.11bg (C54Ri v1 Wireless 11g PCI Adapter)
 
 pci:v00001814d00000300*
  ID_MODEL_FROM_DATABASE=Wireless Adapter Canyon CN-WF511
@@ -49335,97 +50622,100 @@ pci:v00001814d00000301*
  ID_MODEL_FROM_DATABASE=RT2561/RT61 802.11g PCI
 
 pci:v00001814d00000301sv00001186sd00003C08*
- ID_MODEL_FROM_DATABASE=AirPlus G DWL-G630 Wireless Cardbus Adapter (rev.E1)
+ ID_MODEL_FROM_DATABASE=RT2561/RT61 802.11g PCI (AirPlus G DWL-G630 Wireless Cardbus Adapter (rev.E1))
 
 pci:v00001814d00000301sv00001186sd00003C09*
- ID_MODEL_FROM_DATABASE=DWL-G510 Rev C
+ ID_MODEL_FROM_DATABASE=RT2561/RT61 802.11g PCI (DWL-G510 Rev C)
 
 pci:v00001814d00000301sv000013D1sd0000ABE3*
- ID_MODEL_FROM_DATABASE=miniPCI Pluscom 802.11 a/b/g
+ ID_MODEL_FROM_DATABASE=RT2561/RT61 802.11g PCI (miniPCI Pluscom 802.11 a/b/g)
 
 pci:v00001814d00000301sv00001458sd0000E933*
- ID_MODEL_FROM_DATABASE=GN-WI01GS
+ ID_MODEL_FROM_DATABASE=RT2561/RT61 802.11g PCI (GN-WI01GS)
 
 pci:v00001814d00000301sv00001458sd0000E934*
- ID_MODEL_FROM_DATABASE=GN-WP01GS
+ ID_MODEL_FROM_DATABASE=RT2561/RT61 802.11g PCI (GN-WP01GS)
 
 pci:v00001814d00000301sv00001737sd00000055*
- ID_MODEL_FROM_DATABASE=WMP54G v4.1
+ ID_MODEL_FROM_DATABASE=RT2561/RT61 802.11g PCI (WMP54G v4.1)
 
 pci:v00001814d00000301sv00001799sd0000700E*
- ID_MODEL_FROM_DATABASE=F5D7000 v6000 Wireless G Desktop Card
+ ID_MODEL_FROM_DATABASE=RT2561/RT61 802.11g PCI (F5D7000 v6000 Wireless G Desktop Card)
 
 pci:v00001814d00000301sv00001799sd0000701E*
- ID_MODEL_FROM_DATABASE=F5D7010 v6000 Wireless G Notebook Card
+ ID_MODEL_FROM_DATABASE=RT2561/RT61 802.11g PCI (F5D7010 v6000 Wireless G Notebook Card)
 
 pci:v00001814d00000301sv000017F9sd00000012*
- ID_MODEL_FROM_DATABASE=AWLC3026T 802.11g Wireless CardBus Adapter
+ ID_MODEL_FROM_DATABASE=RT2561/RT61 802.11g PCI (AWLC3026T 802.11g Wireless CardBus Adapter)
 
 pci:v00001814d00000301sv00001814sd00002561*
- ID_MODEL_FROM_DATABASE=EW-7108PCg/EW-7128g
+ ID_MODEL_FROM_DATABASE=RT2561/RT61 802.11g PCI (EW-7108PCg/EW-7128g)
 
 pci:v00001814d00000302*
  ID_MODEL_FROM_DATABASE=RT2561/RT61 rev B 802.11g
 
 pci:v00001814d00000302sv00001186sd00003A71*
- ID_MODEL_FROM_DATABASE=DWA-510 Wireless G Desktop Adapter
+ ID_MODEL_FROM_DATABASE=RT2561/RT61 rev B 802.11g (DWA-510 Wireless G Desktop Adapter)
 
 pci:v00001814d00000302sv00001186sd00003C08*
- ID_MODEL_FROM_DATABASE=AirPlus G DWL-G630 Wireless Cardbus Adapter (rev.E2)
+ ID_MODEL_FROM_DATABASE=RT2561/RT61 rev B 802.11g (AirPlus G DWL-G630 Wireless Cardbus Adapter (rev.E2))
 
 pci:v00001814d00000302sv00001186sd00003C09*
- ID_MODEL_FROM_DATABASE=AirPlus G DWL-G510 Wireless Network Adapter (Rev.C)
+ ID_MODEL_FROM_DATABASE=RT2561/RT61 rev B 802.11g (AirPlus G DWL-G510 Wireless Network Adapter (Rev.C))
 
 pci:v00001814d00000302sv00001462sd0000B834*
- ID_MODEL_FROM_DATABASE=PC54G3 Wireless 11g PCI Card
+ ID_MODEL_FROM_DATABASE=RT2561/RT61 rev B 802.11g (PC54G3 Wireless 11g PCI Card)
 
 pci:v00001814d00000302sv00001948sd00003C23*
- ID_MODEL_FROM_DATABASE=C54RC v2 Wireless 11g CardBus Adapter
+ ID_MODEL_FROM_DATABASE=RT2561/RT61 rev B 802.11g (C54RC v2 Wireless 11g CardBus Adapter)
 
 pci:v00001814d00000302sv00001948sd00003C24*
- ID_MODEL_FROM_DATABASE=C54Ri v2 Wireless 11g PCI Adapter
+ ID_MODEL_FROM_DATABASE=RT2561/RT61 rev B 802.11g (C54Ri v2 Wireless 11g PCI Adapter)
 
 pci:v00001814d00000401*
  ID_MODEL_FROM_DATABASE=RT2600 802.11 MIMO
 
 pci:v00001814d00000401sv00001737sd00000052*
- ID_MODEL_FROM_DATABASE=WPC54GR v1 802.11g Wireless-G Notebook Adapter with RangeBooster
+ ID_MODEL_FROM_DATABASE=RT2600 802.11 MIMO (WPC54GR v1 802.11g Wireless-G Notebook Adapter with RangeBooster)
 
 pci:v00001814d00000401sv000017F9sd00000011*
- ID_MODEL_FROM_DATABASE=WPCR-137G 802.11bg Wireless CardBus Adapter
+ ID_MODEL_FROM_DATABASE=RT2600 802.11 MIMO (WPCR-137G 802.11bg Wireless CardBus Adapter)
 
 pci:v00001814d00000401sv000017F9sd00000016*
- ID_MODEL_FROM_DATABASE=WPIR-119GH 802.11bg Wireless Desktop Adapter
+ ID_MODEL_FROM_DATABASE=RT2600 802.11 MIMO (WPIR-119GH 802.11bg Wireless Desktop Adapter)
 
 pci:v00001814d00000601*
  ID_MODEL_FROM_DATABASE=RT2800 802.11n PCI
 
 pci:v00001814d00000601sv00001799sd0000801C*
- ID_MODEL_FROM_DATABASE=F5D8011 v3 802.11n N1 Wireless Notebook Card
+ ID_MODEL_FROM_DATABASE=RT2800 802.11n PCI (F5D8011 v3 802.11n N1 Wireless Notebook Card)
 
 pci:v00001814d00000601sv0000187Esd00003412*
- ID_MODEL_FROM_DATABASE=NWD-310N 802.11n Wireless PCI Adapter
+ ID_MODEL_FROM_DATABASE=RT2800 802.11n PCI (NWD-310N 802.11n Wireless PCI Adapter)
 
 pci:v00001814d00000681*
  ID_MODEL_FROM_DATABASE=RT2890 Wireless 802.11n PCIe
 
 pci:v00001814d00000681sv00001458sd0000E939*
- ID_MODEL_FROM_DATABASE=GN-WS30N-RH 802.11bgn Mini PCIe Card
+ ID_MODEL_FROM_DATABASE=RT2890 Wireless 802.11n PCIe (GN-WS30N-RH 802.11bgn Mini PCIe Card)
 
 pci:v00001814d00000701*
  ID_MODEL_FROM_DATABASE=RT2760 Wireless 802.11n 1T/2R
 
 pci:v00001814d00000701sv00001737sd00000074*
- ID_MODEL_FROM_DATABASE=WMP110 v2 802.11n RangePlus Wireless PCI Adapter
+ ID_MODEL_FROM_DATABASE=RT2760 Wireless 802.11n 1T/2R (WMP110 v2 802.11n RangePlus Wireless PCI Adapter)
 
 pci:v00001814d00000781*
  ID_MODEL_FROM_DATABASE=RT2790 Wireless 802.11n 1T/2R PCIe
 
+pci:v00001814d00000781sv00001814sd00002790*
+ ID_MODEL_FROM_DATABASE=RT2790 Wireless 802.11n 1T/2R PCIe
+
 pci:v00001814d00003060*
  ID_MODEL_FROM_DATABASE=RT3060 Wireless 802.11n 1T/1R
 
 pci:v00001814d00003060sv00001186sd00003C04*
- ID_MODEL_FROM_DATABASE=DWA-525 Wireless N 150 Desktop Adapter (rev.A1)
+ ID_MODEL_FROM_DATABASE=RT3060 Wireless 802.11n 1T/1R (DWA-525 Wireless N 150 Desktop Adapter (rev.A1))
 
 pci:v00001814d00003062*
  ID_MODEL_FROM_DATABASE=RT3062 Wireless 802.11n 2T/2R
@@ -49434,7 +50724,7 @@ pci:v00001814d00003090*
  ID_MODEL_FROM_DATABASE=RT3090 Wireless 802.11n 1T/1R PCIe
 
 pci:v00001814d00003090sv000013BDsd00001057*
- ID_MODEL_FROM_DATABASE=GN-WS32L-RH Half-size Mini PCIe Card
+ ID_MODEL_FROM_DATABASE=RT3090 Wireless 802.11n 1T/1R PCIe (GN-WS32L-RH Half-size Mini PCIe Card)
 
 pci:v00001814d00003091*
  ID_MODEL_FROM_DATABASE=RT3091 Wireless 802.11n 1T/2R PCIe
@@ -49446,13 +50736,13 @@ pci:v00001814d00003290*
  ID_MODEL_FROM_DATABASE=RT3290 Wireless 802.11n 1T/1R PCIe
 
 pci:v00001814d00003290sv0000103Csd000018EC*
- ID_MODEL_FROM_DATABASE=Ralink RT3290LE 802.11bgn 1x1 Wi-Fi and Bluetooth 4.0 Combo Adapter
+ ID_MODEL_FROM_DATABASE=RT3290 Wireless 802.11n 1T/1R PCIe (Ralink RT3290LE 802.11bgn 1x1 Wi-Fi and Bluetooth 4.0 Combo Adapter)
 
 pci:v00001814d00003298*
  ID_MODEL_FROM_DATABASE=RT3290 Bluetooth
 
 pci:v00001814d00003298sv0000103Csd000018EC*
- ID_MODEL_FROM_DATABASE=Ralink RT3290LE 802.11bgn 1x1 Wi-Fi and Bluetooth 4.0 Combo Adapter
+ ID_MODEL_FROM_DATABASE=RT3290 Bluetooth (Ralink RT3290LE 802.11bgn 1x1 Wi-Fi and Bluetooth 4.0 Combo Adapter)
 
 pci:v00001814d00003592*
  ID_MODEL_FROM_DATABASE=RT3592 Wireless 802.11abgn 2T/2R PCIe
@@ -49464,16 +50754,16 @@ pci:v00001814d00005360*
  ID_MODEL_FROM_DATABASE=RT5360 Wireless 802.11n 1T/1R
 
 pci:v00001814d00005360sv00001186sd00003C05*
- ID_MODEL_FROM_DATABASE=DWA-525 Wireless N 150 Desktop Adapter (rev.A2)
+ ID_MODEL_FROM_DATABASE=RT5360 Wireless 802.11n 1T/1R (DWA-525 Wireless N 150 Desktop Adapter (rev.A2))
 
 pci:v00001814d00005360sv000020F4sd0000703A*
- ID_MODEL_FROM_DATABASE=TEW-703PI N150 Wireless PCI Adapter
+ ID_MODEL_FROM_DATABASE=RT5360 Wireless 802.11n 1T/1R (TEW-703PI N150 Wireless PCI Adapter)
 
 pci:v00001814d00005390*
  ID_MODEL_FROM_DATABASE=RT5390 Wireless 802.11n 1T/1R PCIe
 
 pci:v00001814d00005390sv0000103Csd00001636*
- ID_MODEL_FROM_DATABASE=U98Z077.00 Half-size Mini PCIe Card
+ ID_MODEL_FROM_DATABASE=RT5390 Wireless 802.11n 1T/1R PCIe (U98Z077.00 Half-size Mini PCIe Card)
 
 pci:v00001814d00005392*
  ID_MODEL_FROM_DATABASE=RT5392 PCIe Wireless Network Adapter
@@ -49482,7 +50772,10 @@ pci:v00001814d0000539F*
  ID_MODEL_FROM_DATABASE=RT5390 [802.11 b/g/n 1T1R G-band PCI Express Single Chip]
 
 pci:v00001814d0000539Fsv0000103Csd00001637*
- ID_MODEL_FROM_DATABASE=Pavilion DM1Z-3000 PCIe wireless card
+ ID_MODEL_FROM_DATABASE=RT5390 [802.11 b/g/n 1T1R G-band PCI Express Single Chip] (Pavilion DM1Z-3000 PCIe wireless card)
+
+pci:v00001814d00005592*
+ ID_MODEL_FROM_DATABASE=RT5592 PCIe Wireless Network Adapter
 
 pci:v00001814d0000E932*
  ID_MODEL_FROM_DATABASE=RT2560F 802.11 b/g PCI
@@ -49746,7 +51039,7 @@ pci:v000018C3d00000720*
  ID_MODEL_FROM_DATABASE=nGene PCI-Express Multimedia Controller
 
 pci:v000018C3d00000720sv000007CAsd0000032E*
- ID_MODEL_FROM_DATABASE=Hybrid M779 PCI-E
+ ID_MODEL_FROM_DATABASE=nGene PCI-Express Multimedia Controller (Hybrid M779 PCI-E)
 
 pci:v000018C8*
  ID_VENDOR_FROM_DATABASE=Cray Inc
@@ -49806,70 +51099,70 @@ pci:v000018ECd00006D05*
  ID_MODEL_FROM_DATABASE=ML555
 
 pci:v000018ECd00006D05sv000018ECsd00000100*
- ID_MODEL_FROM_DATABASE=NIC (ethernet interfaces)
+ ID_MODEL_FROM_DATABASE=ML555 (NIC (ethernet interfaces))
 
 pci:v000018ECd00006D05sv000018ECsd00000200*
- ID_MODEL_FROM_DATABASE=NIC (szedata2) 4x1G
+ ID_MODEL_FROM_DATABASE=ML555 (NIC (szedata2) 4x1G)
 
 pci:v000018ECd00006D05sv000018ECsd00000201*
- ID_MODEL_FROM_DATABASE=NIC (szedata2) 2x10G
+ ID_MODEL_FROM_DATABASE=ML555 (NIC (szedata2) 2x10G)
 
 pci:v000018ECd00006D05sv000018ECsd00000300*
- ID_MODEL_FROM_DATABASE=NIFIC (szedata2) 4x1G
+ ID_MODEL_FROM_DATABASE=ML555 (NIFIC (szedata2) 4x1G)
 
 pci:v000018ECd00006D05sv000018ECsd00000302*
- ID_MODEL_FROM_DATABASE=NIFIC (szedata2) 2x10G
+ ID_MODEL_FROM_DATABASE=ML555 (NIFIC (szedata2) 2x10G)
 
 pci:v000018ECd00006D05sv000018ECsd00004200*
- ID_MODEL_FROM_DATABASE=Flexible FlowMon (szedata2) 1x10G
+ ID_MODEL_FROM_DATABASE=ML555 (Flexible FlowMon (szedata2) 1x10G)
 
 pci:v000018ECd00006D05sv000018ECsd0000FF00*
- ID_MODEL_FROM_DATABASE=Testing design
+ ID_MODEL_FROM_DATABASE=ML555 (Testing design)
 
 pci:v000018ECd00006D05sv000018ECsd0000FF01*
- ID_MODEL_FROM_DATABASE=Boot design
+ ID_MODEL_FROM_DATABASE=ML555 (Boot design)
 
 pci:v000018ECd0000C006*
  ID_MODEL_FROM_DATABASE=COMBO6
 
 pci:v000018ECd0000C006sv000018ECsd0000D001*
- ID_MODEL_FROM_DATABASE=COMBO-4MTX
+ ID_MODEL_FROM_DATABASE=COMBO6 (COMBO-4MTX)
 
 pci:v000018ECd0000C006sv000018ECsd0000D002*
- ID_MODEL_FROM_DATABASE=COMBO-4SFP
+ ID_MODEL_FROM_DATABASE=COMBO6 (COMBO-4SFP)
 
 pci:v000018ECd0000C006sv000018ECsd0000D003*
- ID_MODEL_FROM_DATABASE=COMBO-4SFPRO
+ ID_MODEL_FROM_DATABASE=COMBO6 (COMBO-4SFPRO)
 
 pci:v000018ECd0000C006sv000018ECsd0000D004*
- ID_MODEL_FROM_DATABASE=COMBO-2XFP
+ ID_MODEL_FROM_DATABASE=COMBO6 (COMBO-2XFP)
 
 pci:v000018ECd0000C032*
  ID_MODEL_FROM_DATABASE=COMBO-LXT110
 
 pci:v000018ECd0000C032sv000018ECsd00000100*
- ID_MODEL_FROM_DATABASE=NIC (ethernet interfaces)
+ ID_MODEL_FROM_DATABASE=COMBO-LXT110 (NIC (ethernet interfaces))
 
 pci:v000018ECd0000C032sv000018ECsd00000200*
- ID_MODEL_FROM_DATABASE=NIC (szedata2) 4x1G
+ ID_MODEL_FROM_DATABASE=COMBO-LXT110 (NIC (szedata2) 4x1G)
 
 pci:v000018ECd0000C032sv000018ECsd00000201*
- ID_MODEL_FROM_DATABASE=NIC (szedata2) 2x10G
+ ID_MODEL_FROM_DATABASE=COMBO-LXT110 (NIC (szedata2) 2x10G)
 
 pci:v000018ECd0000C032sv000018ECsd00000300*
- ID_MODEL_FROM_DATABASE=NIFIC (szedata2) 4x1G
+ ID_MODEL_FROM_DATABASE=COMBO-LXT110 (NIFIC (szedata2) 4x1G)
 
 pci:v000018ECd0000C032sv000018ECsd00000302*
- ID_MODEL_FROM_DATABASE=NIFIC (szedata2) 2x10G
+ ID_MODEL_FROM_DATABASE=COMBO-LXT110 (NIFIC (szedata2) 2x10G)
 
 pci:v000018ECd0000C032sv000018ECsd00004200*
- ID_MODEL_FROM_DATABASE=Flexible FlowMon (szedata2) 1x10G
+ ID_MODEL_FROM_DATABASE=COMBO-LXT110 (Flexible FlowMon (szedata2) 1x10G)
 
 pci:v000018ECd0000C032sv000018ECsd0000FF00*
- ID_MODEL_FROM_DATABASE=Testing design
+ ID_MODEL_FROM_DATABASE=COMBO-LXT110 (Testing design)
 
 pci:v000018ECd0000C032sv000018ECsd0000FF01*
- ID_MODEL_FROM_DATABASE=Boot design
+ ID_MODEL_FROM_DATABASE=COMBO-LXT110 (Boot design)
 
 pci:v000018ECd0000C045*
  ID_MODEL_FROM_DATABASE=COMBO6E
@@ -49881,70 +51174,70 @@ pci:v000018ECd0000C058*
  ID_MODEL_FROM_DATABASE=COMBO6X
 
 pci:v000018ECd0000C058sv000018ECsd0000D001*
- ID_MODEL_FROM_DATABASE=COMBO-4MTX
+ ID_MODEL_FROM_DATABASE=COMBO6X (COMBO-4MTX)
 
 pci:v000018ECd0000C058sv000018ECsd0000D002*
- ID_MODEL_FROM_DATABASE=COMBO-4SFP
+ ID_MODEL_FROM_DATABASE=COMBO6X (COMBO-4SFP)
 
 pci:v000018ECd0000C058sv000018ECsd0000D003*
- ID_MODEL_FROM_DATABASE=COMBO-4SFPRO
+ ID_MODEL_FROM_DATABASE=COMBO6X (COMBO-4SFPRO)
 
 pci:v000018ECd0000C058sv000018ECsd0000D004*
- ID_MODEL_FROM_DATABASE=COMBO-2XFP
+ ID_MODEL_FROM_DATABASE=COMBO6X (COMBO-2XFP)
 
 pci:v000018ECd0000C132*
  ID_MODEL_FROM_DATABASE=COMBO-LXT155
 
 pci:v000018ECd0000C132sv000018ECsd00000100*
- ID_MODEL_FROM_DATABASE=NIC (ethernet interfaces)
+ ID_MODEL_FROM_DATABASE=COMBO-LXT155 (NIC (ethernet interfaces))
 
 pci:v000018ECd0000C132sv000018ECsd00000200*
- ID_MODEL_FROM_DATABASE=NIC (szedata2) 4x1G
+ ID_MODEL_FROM_DATABASE=COMBO-LXT155 (NIC (szedata2) 4x1G)
 
 pci:v000018ECd0000C132sv000018ECsd00000201*
- ID_MODEL_FROM_DATABASE=NIC (szedata2) 2x10G
+ ID_MODEL_FROM_DATABASE=COMBO-LXT155 (NIC (szedata2) 2x10G)
 
 pci:v000018ECd0000C132sv000018ECsd00000300*
- ID_MODEL_FROM_DATABASE=NIFIC (szedata2) 4x1G
+ ID_MODEL_FROM_DATABASE=COMBO-LXT155 (NIFIC (szedata2) 4x1G)
 
 pci:v000018ECd0000C132sv000018ECsd00000302*
- ID_MODEL_FROM_DATABASE=NIFIC (szedata2) 2x10G
+ ID_MODEL_FROM_DATABASE=COMBO-LXT155 (NIFIC (szedata2) 2x10G)
 
 pci:v000018ECd0000C132sv000018ECsd00004200*
- ID_MODEL_FROM_DATABASE=Flexible FlowMon (szedata2) 1x10G
+ ID_MODEL_FROM_DATABASE=COMBO-LXT155 (Flexible FlowMon (szedata2) 1x10G)
 
 pci:v000018ECd0000C132sv000018ECsd0000FF00*
- ID_MODEL_FROM_DATABASE=Testing design
+ ID_MODEL_FROM_DATABASE=COMBO-LXT155 (Testing design)
 
 pci:v000018ECd0000C132sv000018ECsd0000FF01*
- ID_MODEL_FROM_DATABASE=Boot design
+ ID_MODEL_FROM_DATABASE=COMBO-LXT155 (Boot design)
 
 pci:v000018ECd0000C232*
  ID_MODEL_FROM_DATABASE=COMBO-FXT100
 
 pci:v000018ECd0000C232sv000018ECsd00000100*
- ID_MODEL_FROM_DATABASE=NIC (ethernet interfaces)
+ ID_MODEL_FROM_DATABASE=COMBO-FXT100 (NIC (ethernet interfaces))
 
 pci:v000018ECd0000C232sv000018ECsd00000200*
- ID_MODEL_FROM_DATABASE=NIC (szedata2) 4x1G
+ ID_MODEL_FROM_DATABASE=COMBO-FXT100 (NIC (szedata2) 4x1G)
 
 pci:v000018ECd0000C232sv000018ECsd00000201*
- ID_MODEL_FROM_DATABASE=NIC (szedata2) 2x10G
+ ID_MODEL_FROM_DATABASE=COMBO-FXT100 (NIC (szedata2) 2x10G)
 
 pci:v000018ECd0000C232sv000018ECsd00000300*
- ID_MODEL_FROM_DATABASE=NIFIC (szedata2) 4x1G
+ ID_MODEL_FROM_DATABASE=COMBO-FXT100 (NIFIC (szedata2) 4x1G)
 
 pci:v000018ECd0000C232sv000018ECsd00000302*
- ID_MODEL_FROM_DATABASE=NIFIC (szedata2) 2x10G
+ ID_MODEL_FROM_DATABASE=COMBO-FXT100 (NIFIC (szedata2) 2x10G)
 
 pci:v000018ECd0000C232sv000018ECsd00004200*
- ID_MODEL_FROM_DATABASE=Flexible FlowMon (szedata2) 1x10G
+ ID_MODEL_FROM_DATABASE=COMBO-FXT100 (Flexible FlowMon (szedata2) 1x10G)
 
 pci:v000018ECd0000C232sv000018ECsd0000FF00*
- ID_MODEL_FROM_DATABASE=Testing design
+ ID_MODEL_FROM_DATABASE=COMBO-FXT100 (Testing design)
 
 pci:v000018ECd0000C232sv000018ECsd0000FF01*
- ID_MODEL_FROM_DATABASE=Boot design
+ ID_MODEL_FROM_DATABASE=COMBO-FXT100 (Boot design)
 
 pci:v000018EE*
  ID_VENDOR_FROM_DATABASE=Chenming Mold Ind. Corp.
@@ -50012,6 +51305,12 @@ pci:v000018F4d00000125*
 pci:v000018F4d00000135*
  ID_MODEL_FROM_DATABASE=NT20E2-PTP Network Adapter 2x10Gb
 
+pci:v000018F4d00000145*
+ ID_MODEL_FROM_DATABASE=NT40E3-4-PTP Network Adapter 4x10Gb
+
+pci:v000018F4d00000155*
+ ID_MODEL_FROM_DATABASE=NT100E3-1-PTP Network Adapter 1x100Gb
+
 pci:v000018F6*
  ID_VENDOR_FROM_DATABASE=NextIO
 
@@ -50184,214 +51483,235 @@ pci:v00001924d00000703*
  ID_MODEL_FROM_DATABASE=SFC4000 rev A net [Solarstorm]
 
 pci:v00001924d00000703sv000010B8sd00000102*
- ID_MODEL_FROM_DATABASE=SMC10GPCIe-10BT (A2) [TigerCard]
+ ID_MODEL_FROM_DATABASE=SFC4000 rev A net [Solarstorm] (SMC10GPCIe-10BT (A2) [TigerCard])
 
 pci:v00001924d00000703sv000010B8sd00000103*
- ID_MODEL_FROM_DATABASE=SMC10GPCIe-10BT (A3) [TigerCard]
+ ID_MODEL_FROM_DATABASE=SFC4000 rev A net [Solarstorm] (SMC10GPCIe-10BT (A3) [TigerCard])
 
 pci:v00001924d00000703sv000010B8sd00000201*
- ID_MODEL_FROM_DATABASE=SMC10GPCIe-XFP (A1) [TigerCard]
+ ID_MODEL_FROM_DATABASE=SFC4000 rev A net [Solarstorm] (SMC10GPCIe-XFP (A1) [TigerCard])
 
 pci:v00001924d00000703sv00001924sd00000101*
- ID_MODEL_FROM_DATABASE=SFE4001-A1
+ ID_MODEL_FROM_DATABASE=SFC4000 rev A net [Solarstorm] (SFE4001-A1)
 
 pci:v00001924d00000703sv00001924sd00000102*
- ID_MODEL_FROM_DATABASE=SFE4001-A2
+ ID_MODEL_FROM_DATABASE=SFC4000 rev A net [Solarstorm] (SFE4001-A2)
 
 pci:v00001924d00000703sv00001924sd00000103*
- ID_MODEL_FROM_DATABASE=SFE4001-A3
+ ID_MODEL_FROM_DATABASE=SFC4000 rev A net [Solarstorm] (SFE4001-A3)
 
 pci:v00001924d00000703sv00001924sd00000201*
- ID_MODEL_FROM_DATABASE=SFE4002-A1
+ ID_MODEL_FROM_DATABASE=SFC4000 rev A net [Solarstorm] (SFE4002-A1)
 
 pci:v00001924d00000703sv00001924sd00000301*
- ID_MODEL_FROM_DATABASE=SFE4003-A1
+ ID_MODEL_FROM_DATABASE=SFC4000 rev A net [Solarstorm] (SFE4003-A1)
 
 pci:v00001924d00000703sv00001924sd00000302*
- ID_MODEL_FROM_DATABASE=SFE4003-A2
+ ID_MODEL_FROM_DATABASE=SFC4000 rev A net [Solarstorm] (SFE4003-A2)
 
 pci:v00001924d00000703sv00001924sd00000303*
- ID_MODEL_FROM_DATABASE=SFE4003-A3
+ ID_MODEL_FROM_DATABASE=SFC4000 rev A net [Solarstorm] (SFE4003-A3)
 
 pci:v00001924d00000703sv00001924sd00000304*
- ID_MODEL_FROM_DATABASE=SFE4003-A4
+ ID_MODEL_FROM_DATABASE=SFC4000 rev A net [Solarstorm] (SFE4003-A4)
 
 pci:v00001924d00000703sv00001924sd00000500*
- ID_MODEL_FROM_DATABASE=SFE4005-A0
+ ID_MODEL_FROM_DATABASE=SFC4000 rev A net [Solarstorm] (SFE4005-A0)
 
 pci:v00001924d00000710*
  ID_MODEL_FROM_DATABASE=SFC4000 rev B [Solarstorm]
 
 pci:v00001924d00000710sv000010B8sd00000103*
- ID_MODEL_FROM_DATABASE=SMC10GPCIe-10BT (A3) [TigerCard]
+ ID_MODEL_FROM_DATABASE=SFC4000 rev B [Solarstorm] (SMC10GPCIe-10BT (A3) [TigerCard])
 
 pci:v00001924d00000710sv000010B8sd00000201*
- ID_MODEL_FROM_DATABASE=SMC10GPCIe-XFP (A1) [TigerCard]
+ ID_MODEL_FROM_DATABASE=SFC4000 rev B [Solarstorm] (SMC10GPCIe-XFP (A1) [TigerCard])
 
 pci:v00001924d00000710sv00001924sd00000102*
- ID_MODEL_FROM_DATABASE=SFE4001-A2
+ ID_MODEL_FROM_DATABASE=SFC4000 rev B [Solarstorm] (SFE4001-A2)
 
 pci:v00001924d00000710sv00001924sd00000103*
- ID_MODEL_FROM_DATABASE=SFE4001-A3
+ ID_MODEL_FROM_DATABASE=SFC4000 rev B [Solarstorm] (SFE4001-A3)
 
 pci:v00001924d00000710sv00001924sd00000201*
- ID_MODEL_FROM_DATABASE=SFE4002-A1
+ ID_MODEL_FROM_DATABASE=SFC4000 rev B [Solarstorm] (SFE4002-A1)
 
 pci:v00001924d00000710sv00001924sd00000302*
- ID_MODEL_FROM_DATABASE=SFE4003-A2
+ ID_MODEL_FROM_DATABASE=SFC4000 rev B [Solarstorm] (SFE4003-A2)
 
 pci:v00001924d00000710sv00001924sd00000303*
- ID_MODEL_FROM_DATABASE=SFE4003-A3
+ ID_MODEL_FROM_DATABASE=SFC4000 rev B [Solarstorm] (SFE4003-A3)
 
 pci:v00001924d00000710sv00001924sd00000304*
- ID_MODEL_FROM_DATABASE=SFE4003-A4
+ ID_MODEL_FROM_DATABASE=SFC4000 rev B [Solarstorm] (SFE4003-A4)
 
 pci:v00001924d00000710sv00001924sd00000500*
- ID_MODEL_FROM_DATABASE=SFE4005-A0
+ ID_MODEL_FROM_DATABASE=SFC4000 rev B [Solarstorm] (SFE4005-A0)
 
 pci:v00001924d00000710sv00001924sd00005102*
- ID_MODEL_FROM_DATABASE=SFN4111T-A2
+ ID_MODEL_FROM_DATABASE=SFC4000 rev B [Solarstorm] (SFN4111T-A2)
 
 pci:v00001924d00000710sv00001924sd00005103*
- ID_MODEL_FROM_DATABASE=SFN4111T-R3
+ ID_MODEL_FROM_DATABASE=SFC4000 rev B [Solarstorm] (SFN4111T-R3)
 
 pci:v00001924d00000710sv00001924sd00005104*
- ID_MODEL_FROM_DATABASE=SFN4111T-R4
+ ID_MODEL_FROM_DATABASE=SFC4000 rev B [Solarstorm] (SFN4111T-R4)
 
 pci:v00001924d00000710sv00001924sd00005105*
- ID_MODEL_FROM_DATABASE=SFN4111T-R5
+ ID_MODEL_FROM_DATABASE=SFC4000 rev B [Solarstorm] (SFN4111T-R5)
 
 pci:v00001924d00000710sv00001924sd00005201*
- ID_MODEL_FROM_DATABASE=SFN4112F-R1
+ ID_MODEL_FROM_DATABASE=SFC4000 rev B [Solarstorm] (SFN4112F-R1)
 
 pci:v00001924d00000710sv00001924sd00005202*
- ID_MODEL_FROM_DATABASE=SFN4112F-R2
+ ID_MODEL_FROM_DATABASE=SFC4000 rev B [Solarstorm] (SFN4112F-R2)
 
 pci:v00001924d00000803*
  ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm]
 
 pci:v00001924d00000803sv00001014sd00000478*
- ID_MODEL_FROM_DATABASE=2-port 10GbE Low-Latency (R7)
+ ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (2-port 10GbE Low-Latency (R7))
 
 pci:v00001924d00000803sv00001014sd00000479*
- ID_MODEL_FROM_DATABASE=2-port 10GbE OpenOnload (R7)
+ ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (2-port 10GbE OpenOnload (R7))
 
 pci:v00001924d00000803sv00001014sd000004A7*
- ID_MODEL_FROM_DATABASE=Solarflare 10Gb Low-latency Dual-port HBA (R7)
+ ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (Solarflare 10Gb Low-latency Dual-port HBA (R7))
 
 pci:v00001924d00000803sv00001014sd000004A8*
- ID_MODEL_FROM_DATABASE=Solarflare 10Gb Dual-port HBA (R7)
+ ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (Solarflare 10Gb Dual-port HBA (R7))
 
 pci:v00001924d00000803sv0000103Csd00002132*
- ID_MODEL_FROM_DATABASE=Ethernet 10Gb 2-port 570FLR-SFP+ Adapter (R1)
+ ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (Ethernet 10Gb 2-port 570FLR-SFP+ Adapter (R1))
 
 pci:v00001924d00000803sv0000103Csd00002136*
- ID_MODEL_FROM_DATABASE=Ethernet 10Gb 2-port 570SFP+ Adapter (R7)
+ ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (Ethernet 10Gb 2-port 570SFP+ Adapter (R7))
 
 pci:v00001924d00000803sv00001924sd00001201*
- ID_MODEL_FROM_DATABASE=SFA6902F-R1 SFP+ AOE Adapter
+ ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFA6902F-R1 SFP+ AOE Adapter)
 
 pci:v00001924d00000803sv00001924sd00006200*
- ID_MODEL_FROM_DATABASE=SFN5122F-R0 SFP+ Server Adapter
+ ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFN5122F-R0 SFP+ Server Adapter)
 
 pci:v00001924d00000803sv00001924sd00006201*
- ID_MODEL_FROM_DATABASE=SFN5122F-R1 SFP+ Server Adapter
+ ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFN5122F-R1 SFP+ Server Adapter)
 
 pci:v00001924d00000803sv00001924sd00006202*
- ID_MODEL_FROM_DATABASE=SFN5122F-R2 SFP+ Server Adapter
+ ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFN5122F-R2 SFP+ Server Adapter)
 
 pci:v00001924d00000803sv00001924sd00006204*
- ID_MODEL_FROM_DATABASE=SFN5122F-R4 SFP+ Server Adapter
+ ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFN5122F-R4 SFP+ Server Adapter)
 
 pci:v00001924d00000803sv00001924sd00006205*
- ID_MODEL_FROM_DATABASE=SFN5122F-R5 SFP+ Server Adapter
+ ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFN5122F-R5 SFP+ Server Adapter)
 
 pci:v00001924d00000803sv00001924sd00006206*
- ID_MODEL_FROM_DATABASE=SFN5122F-R6 SFP+ Server Adapter
+ ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFN5122F-R6 SFP+ Server Adapter)
 
 pci:v00001924d00000803sv00001924sd00006207*
- ID_MODEL_FROM_DATABASE=SFN5122F-R7 SFP+ Server Adapter
+ ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFN5122F-R7 SFP+ Server Adapter)
 
 pci:v00001924d00000803sv00001924sd00006210*
- ID_MODEL_FROM_DATABASE=SFN5322F-R0 SFP+ Precision Time Synchronization Server Adapter
+ ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFN5322F-R0 SFP+ Precision Time Synchronization Server Adapter)
 
 pci:v00001924d00000803sv00001924sd00006211*
- ID_MODEL_FROM_DATABASE=SFN5322F-R1 SFP+ Precision Time Synchronization Server Adapter
+ ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFN5322F-R1 SFP+ Precision Time Synchronization Server Adapter)
 
 pci:v00001924d00000803sv00001924sd00006217*
- ID_MODEL_FROM_DATABASE=SFN5322F-R7 SFP+ Precision Time Synchronization Server Adapter
+ ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFN5322F-R7 SFP+ Precision Time Synchronization Server Adapter)
 
 pci:v00001924d00000803sv00001924sd00006227*
- ID_MODEL_FROM_DATABASE=SFN6122F-R7 SFP+ Server Adapter
+ ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFN6122F-R7 SFP+ Server Adapter)
 
 pci:v00001924d00000803sv00001924sd00006237*
- ID_MODEL_FROM_DATABASE=SFN6322F-R7 SFP+ Precision Time Synchronization Server Adapter
+ ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFN6322F-R7 SFP+ Precision Time Synchronization Server Adapter)
 
 pci:v00001924d00000803sv00001924sd00006501*
- ID_MODEL_FROM_DATABASE=SFN5802K-R1 Mezzanine Adapter
+ ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFN5802K-R1 Mezzanine Adapter)
 
 pci:v00001924d00000803sv00001924sd00006511*
- ID_MODEL_FROM_DATABASE=SFN5814H-R1 Mezzanine Adapter
+ ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFN5814H-R1 Mezzanine Adapter)
 
 pci:v00001924d00000803sv00001924sd00006521*
- ID_MODEL_FROM_DATABASE=SFN5812H-R1 Mezzanine Adapter
+ ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFN5812H-R1 Mezzanine Adapter)
 
 pci:v00001924d00000803sv00001924sd00006562*
- ID_MODEL_FROM_DATABASE=SFN6832F-R2 SFP+ Mezzanine Adapter
+ ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFN6832F-R2 SFP+ Mezzanine Adapter)
 
 pci:v00001924d00000803sv00001924sd00006A05*
- ID_MODEL_FROM_DATABASE=SFN5112F-R5 SFP+ Server Adapter
+ ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFN5112F-R5 SFP+ Server Adapter)
 
 pci:v00001924d00000803sv00001924sd00006A06*
- ID_MODEL_FROM_DATABASE=SFN5112F-R6 SFP+ Server Adapter
+ ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFN5112F-R6 SFP+ Server Adapter)
 
 pci:v00001924d00000803sv00001924sd00007206*
- ID_MODEL_FROM_DATABASE=SFN5162F-R6 SFP+ Server Adapter
+ ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFN5162F-R6 SFP+ Server Adapter)
 
 pci:v00001924d00000803sv00001924sd00007207*
- ID_MODEL_FROM_DATABASE=SFN5162F-R7 SFP+ Server Adapter
+ ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFN5162F-R7 SFP+ Server Adapter)
 
 pci:v00001924d00000803sv00001924sd00007A06*
- ID_MODEL_FROM_DATABASE=SFN5152F-R6 SFP+ Server Adapter
+ ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFN5152F-R6 SFP+ Server Adapter)
 
 pci:v00001924d00000803sv00001924sd00007A07*
- ID_MODEL_FROM_DATABASE=SFN5152F-R7 SFP+ Server Adapter
+ ID_MODEL_FROM_DATABASE=SFC9020 [Solarstorm] (SFN5152F-R7 SFP+ Server Adapter)
 
 pci:v00001924d00000813*
  ID_MODEL_FROM_DATABASE=SFL9021 [Solarstorm]
 
 pci:v00001924d00000813sv00001924sd00006100*
- ID_MODEL_FROM_DATABASE=SFN5121T-R0 10GBASE-T Server Adapter
+ ID_MODEL_FROM_DATABASE=SFL9021 [Solarstorm] (SFN5121T-R0 10GBASE-T Server Adapter)
 
 pci:v00001924d00000813sv00001924sd00006102*
- ID_MODEL_FROM_DATABASE=SFN5121T-R2 10GBASE-T Server Adapter
+ ID_MODEL_FROM_DATABASE=SFL9021 [Solarstorm] (SFN5121T-R2 10GBASE-T Server Adapter)
 
 pci:v00001924d00000813sv00001924sd00006103*
- ID_MODEL_FROM_DATABASE=SFN5121T-R3 10GBASE-T Server Adapter
+ ID_MODEL_FROM_DATABASE=SFL9021 [Solarstorm] (SFN5121T-R3 10GBASE-T Server Adapter)
 
 pci:v00001924d00000813sv00001924sd00006104*
- ID_MODEL_FROM_DATABASE=SFN5121T-R4 10GBASE-T Server Adapter
+ ID_MODEL_FROM_DATABASE=SFL9021 [Solarstorm] (SFN5121T-R4 10GBASE-T Server Adapter)
 
 pci:v00001924d00000813sv00001924sd00006902*
- ID_MODEL_FROM_DATABASE=SFN5111T-R2 10GBASE-T Server Adapter
+ ID_MODEL_FROM_DATABASE=SFL9021 [Solarstorm] (SFN5111T-R2 10GBASE-T Server Adapter)
 
 pci:v00001924d00000813sv00001924sd00006904*
- ID_MODEL_FROM_DATABASE=SFN5111T-R4 10GBASE-T Server Adapter
+ ID_MODEL_FROM_DATABASE=SFL9021 [Solarstorm] (SFN5111T-R4 10GBASE-T Server Adapter)
 
 pci:v00001924d00000813sv00001924sd00007104*
- ID_MODEL_FROM_DATABASE=SFN5161T-R4 10GBASE-T Server Adapter
+ ID_MODEL_FROM_DATABASE=SFL9021 [Solarstorm] (SFN5161T-R4 10GBASE-T Server Adapter)
 
 pci:v00001924d00000813sv00001924sd00007904*
- ID_MODEL_FROM_DATABASE=SFN5151T-R4 10GBASE-T Server Adapter
+ ID_MODEL_FROM_DATABASE=SFL9021 [Solarstorm] (SFN5151T-R4 10GBASE-T Server Adapter)
 
 pci:v00001924d00000903*
  ID_MODEL_FROM_DATABASE=SFC9120
 
+pci:v00001924d00000903sv00001014sd000004CC*
+ ID_MODEL_FROM_DATABASE=SFC9120 (SFN7122F-R2 2x10GbE SFP+ Flareon Ultra)
+
 pci:v00001924d00000903sv00001924sd00008002*
- ID_MODEL_FROM_DATABASE=SFN7122F-R1 SFP+ Server Adapter
+ ID_MODEL_FROM_DATABASE=SFC9120 (SFN7122F-R1 SFP+ Server Adapter)
+
+pci:v00001924d00000903sv00001924sd00008003*
+ ID_MODEL_FROM_DATABASE=SFC9120 (SFN7x41Q-R1 Flareon Ultra 7000 Series 10/40G Adapter)
 
 pci:v00001924d00000903sv00001924sd00008006*
- ID_MODEL_FROM_DATABASE=SFN7022F-R1 SFP+ Server Adapter
+ ID_MODEL_FROM_DATABASE=SFC9120 (SFN7022F-R1 SFP+ Server Adapter)
+
+pci:v00001924d00000903sv00001924sd00008007*
+ ID_MODEL_FROM_DATABASE=SFC9120 (SFN7322F-R2 Precision Time SFP+ Server Adapter)
+
+pci:v00001924d00000903sv00001924sd00008009*
+ ID_MODEL_FROM_DATABASE=SFC9120 (SFN7x22F-R2 Flareon Ultra 7000 Series 10G Adapter)
+
+pci:v00001924d00000903sv00001924sd0000800A*
+ ID_MODEL_FROM_DATABASE=SFC9120 (SFN7x02F-R2 Flareon 7000 Series 10G Adapter)
+
+pci:v00001924d00000923*
+ ID_MODEL_FROM_DATABASE=SFC9140
+
+pci:v00001924d00000923sv00001924sd0000800B*
+ ID_MODEL_FROM_DATABASE=SFC9140 (SFN7x42Q-R1 Flareon Ultra 7000 Series 10/40G Adapter)
 
 pci:v00001924d00001803*
  ID_MODEL_FROM_DATABASE=SFC9020 Virtual Function [Solarstorm]
@@ -50403,40 +51723,40 @@ pci:v00001924d00006703*
  ID_MODEL_FROM_DATABASE=SFC4000 rev A iSCSI/Onload [Solarstorm]
 
 pci:v00001924d00006703sv000010B8sd00000102*
- ID_MODEL_FROM_DATABASE=SMC10GPCIe-10BT (A2) [TigerCard]
+ ID_MODEL_FROM_DATABASE=SFC4000 rev A iSCSI/Onload [Solarstorm] (SMC10GPCIe-10BT (A2) [TigerCard])
 
 pci:v00001924d00006703sv000010B8sd00000103*
- ID_MODEL_FROM_DATABASE=SMC10GPCIe-10BT (A3) [TigerCard]
+ ID_MODEL_FROM_DATABASE=SFC4000 rev A iSCSI/Onload [Solarstorm] (SMC10GPCIe-10BT (A3) [TigerCard])
 
 pci:v00001924d00006703sv000010B8sd00000201*
- ID_MODEL_FROM_DATABASE=SMC10GPCIe-XFP (A1) [TigerCard]
+ ID_MODEL_FROM_DATABASE=SFC4000 rev A iSCSI/Onload [Solarstorm] (SMC10GPCIe-XFP (A1) [TigerCard])
 
 pci:v00001924d00006703sv00001924sd00000101*
- ID_MODEL_FROM_DATABASE=SFE4001-A1
+ ID_MODEL_FROM_DATABASE=SFC4000 rev A iSCSI/Onload [Solarstorm] (SFE4001-A1)
 
 pci:v00001924d00006703sv00001924sd00000102*
- ID_MODEL_FROM_DATABASE=SFE4001-A2
+ ID_MODEL_FROM_DATABASE=SFC4000 rev A iSCSI/Onload [Solarstorm] (SFE4001-A2)
 
 pci:v00001924d00006703sv00001924sd00000103*
- ID_MODEL_FROM_DATABASE=SFE4001-A3
+ ID_MODEL_FROM_DATABASE=SFC4000 rev A iSCSI/Onload [Solarstorm] (SFE4001-A3)
 
 pci:v00001924d00006703sv00001924sd00000201*
- ID_MODEL_FROM_DATABASE=SFE4002-A1
+ ID_MODEL_FROM_DATABASE=SFC4000 rev A iSCSI/Onload [Solarstorm] (SFE4002-A1)
 
 pci:v00001924d00006703sv00001924sd00000301*
- ID_MODEL_FROM_DATABASE=SFE4003-A1
+ ID_MODEL_FROM_DATABASE=SFC4000 rev A iSCSI/Onload [Solarstorm] (SFE4003-A1)
 
 pci:v00001924d00006703sv00001924sd00000302*
- ID_MODEL_FROM_DATABASE=SFE4003-A2
+ ID_MODEL_FROM_DATABASE=SFC4000 rev A iSCSI/Onload [Solarstorm] (SFE4003-A2)
 
 pci:v00001924d00006703sv00001924sd00000303*
- ID_MODEL_FROM_DATABASE=SFE4003-A3
+ ID_MODEL_FROM_DATABASE=SFC4000 rev A iSCSI/Onload [Solarstorm] (SFE4003-A3)
 
 pci:v00001924d00006703sv00001924sd00000304*
- ID_MODEL_FROM_DATABASE=SFE4003-A4
+ ID_MODEL_FROM_DATABASE=SFC4000 rev A iSCSI/Onload [Solarstorm] (SFE4003-A4)
 
 pci:v00001924d00006703sv00001924sd00000500*
- ID_MODEL_FROM_DATABASE=SFE4005-A0
+ ID_MODEL_FROM_DATABASE=SFC4000 rev A iSCSI/Onload [Solarstorm] (SFE4005-A0)
 
 pci:v00001924d0000C101*
  ID_MODEL_FROM_DATABASE=EF1-21022T [EtherFabric]
@@ -50480,6 +51800,12 @@ pci:v0000193Fd00000367*
 pci:v0000193Fd00000370*
  ID_MODEL_FROM_DATABASE=AHA370-PCIe
 
+pci:v0000193Fd00003641*
+ ID_MODEL_FROM_DATABASE=AHA3641
+
+pci:v0000193Fd00003642*
+ ID_MODEL_FROM_DATABASE=AHA3642
+
 pci:v00001942*
  ID_VENDOR_FROM_DATABASE=ClearSpeed Technology plc
 
@@ -50630,9 +51956,15 @@ pci:v00001957d00000083*
 pci:v00001957d00000084*
  ID_MODEL_FROM_DATABASE=MPC8347E PBGA
 
+pci:v00001957d00000084sv0000110Asd00004074*
+ ID_MODEL_FROM_DATABASE=MPC8347E PBGA (SIMATIC NET CP 1628)
+
 pci:v00001957d00000085*
  ID_MODEL_FROM_DATABASE=MPC8347 PBGA
 
+pci:v00001957d00000085sv0000110Asd00004046*
+ ID_MODEL_FROM_DATABASE=MPC8347 PBGA (SIMATIC NET CP 1623)
+
 pci:v00001957d00000086*
  ID_MODEL_FROM_DATABASE=MPC8343E
 
@@ -50646,7 +51978,7 @@ pci:v00001957d000000B6*
  ID_MODEL_FROM_DATABASE=MPC8314E
 
 pci:v00001957d000000B6sv00001A56sd00001101*
- ID_MODEL_FROM_DATABASE=Killer Xeno Pro Gigabit Ethernet Controller
+ ID_MODEL_FROM_DATABASE=MPC8314E (Killer Xeno Pro Gigabit Ethernet Controller)
 
 pci:v00001957d000000C2*
  ID_MODEL_FROM_DATABASE=MPC8379E
@@ -50697,7 +52029,7 @@ pci:v00001957d00000111*
  ID_MODEL_FROM_DATABASE=P1022
 
 pci:v00001957d00000111sv00001C7Fsd00005200*
- ID_MODEL_FROM_DATABASE=EB5200
+ ID_MODEL_FROM_DATABASE=P1022 (EB5200)
 
 pci:v00001957d00000118*
  ID_MODEL_FROM_DATABASE=P1013E
@@ -50736,7 +52068,7 @@ pci:v00001957d0000C006*
  ID_MODEL_FROM_DATABASE=MPC8308
 
 pci:v00001957d0000C006sv00001A56sd00001201*
- ID_MODEL_FROM_DATABASE=Killer E2100 Gigabit Ethernet Controller
+ ID_MODEL_FROM_DATABASE=MPC8308 (Killer E2100 Gigabit Ethernet Controller)
 
 pci:v00001958*
  ID_VENDOR_FROM_DATABASE=Faster Technology, LLC.
@@ -50802,13 +52134,13 @@ pci:v00001969d00001026*
  ID_MODEL_FROM_DATABASE=AR8121/AR8113/AR8114 Gigabit or Fast Ethernet
 
 pci:v00001969d00001026sv00001043sd00008304*
- ID_MODEL_FROM_DATABASE=P5KPL-CM Motherboard
+ ID_MODEL_FROM_DATABASE=AR8121/AR8113/AR8114 Gigabit or Fast Ethernet (P5KPL-CM Motherboard)
 
 pci:v00001969d00001048*
  ID_MODEL_FROM_DATABASE=Attansic L1 Gigabit Ethernet
 
 pci:v00001969d00001048sv00001043sd00008226*
- ID_MODEL_FROM_DATABASE=P5KPL-VM Motherboard
+ ID_MODEL_FROM_DATABASE=Attansic L1 Gigabit Ethernet (P5KPL-VM Motherboard)
 
 pci:v00001969d00001062*
  ID_MODEL_FROM_DATABASE=AR8132 Fast Ethernet
@@ -50817,7 +52149,10 @@ pci:v00001969d00001063*
  ID_MODEL_FROM_DATABASE=AR8131 Gigabit Ethernet
 
 pci:v00001969d00001063sv00001458sd0000E000*
- ID_MODEL_FROM_DATABASE=GA-G31M-ES2L Motherboard
+ ID_MODEL_FROM_DATABASE=AR8131 Gigabit Ethernet (GA-G31M-ES2L Motherboard)
+
+pci:v00001969d00001063sv000017C0sd000010D2*
+ ID_MODEL_FROM_DATABASE=AR8131 Gigabit Ethernet (Medion Akoya E7214 Notebook PC [MD98410])
 
 pci:v00001969d00001066*
  ID_MODEL_FROM_DATABASE=Attansic L2c Gigabit Ethernet
@@ -50838,7 +52173,7 @@ pci:v00001969d00001091*
  ID_MODEL_FROM_DATABASE=AR8161 Gigabit Ethernet
 
 pci:v00001969d00001091sv00001043sd00001477*
- ID_MODEL_FROM_DATABASE=N56VZ
+ ID_MODEL_FROM_DATABASE=AR8161 Gigabit Ethernet (N56VZ)
 
 pci:v00001969d000010A0*
  ID_MODEL_FROM_DATABASE=QCA8172 Fast Ethernet
@@ -50856,7 +52191,7 @@ pci:v00001969d00002062*
  ID_MODEL_FROM_DATABASE=AR8152 v2.0 Fast Ethernet
 
 pci:v00001969d0000E091*
- ID_MODEL_FROM_DATABASE=Killer E2200 Gigabit Ethernet Controller
+ ID_MODEL_FROM_DATABASE=Killer E220x Gigabit Ethernet Controller
 
 pci:v0000196A*
  ID_VENDOR_FROM_DATABASE=Sensory Networks Inc.
@@ -50880,7 +52215,7 @@ pci:v00001971d00001011*
  ID_MODEL_FROM_DATABASE=Physics Processing Unit [PhysX]
 
 pci:v00001971d00001011sv00001043sd00000001*
- ID_MODEL_FROM_DATABASE=PhysX P1
+ ID_MODEL_FROM_DATABASE=Physics Processing Unit [PhysX] (PhysX P1)
 
 pci:v00001974*
  ID_VENDOR_FROM_DATABASE=Eberspaecher Electronics
@@ -50910,25 +52245,25 @@ pci:v0000197Bd00002361*
  ID_MODEL_FROM_DATABASE=JMB361 AHCI/IDE
 
 pci:v0000197Bd00002361sv00001462sd00007235*
- ID_MODEL_FROM_DATABASE=P965 Neo MS-7235 mainboard
+ ID_MODEL_FROM_DATABASE=JMB361 AHCI/IDE (P965 Neo MS-7235 mainboard)
 
 pci:v0000197Bd00002362*
  ID_MODEL_FROM_DATABASE=JMB362 SATA Controller
 
 pci:v0000197Bd00002362sv00001043sd00008460*
- ID_MODEL_FROM_DATABASE=P8P67 Deluxe Motherboard
+ ID_MODEL_FROM_DATABASE=JMB362 SATA Controller (P8P67 Deluxe Motherboard)
 
 pci:v0000197Bd00002363*
  ID_MODEL_FROM_DATABASE=JMB363 SATA/IDE Controller
 
 pci:v0000197Bd00002363sv00001043sd000081E4*
- ID_MODEL_FROM_DATABASE=P5B [JMB363]
+ ID_MODEL_FROM_DATABASE=JMB363 SATA/IDE Controller (P5B [JMB363])
 
 pci:v0000197Bd00002363sv00001458sd0000B000*
- ID_MODEL_FROM_DATABASE=Motherboard
+ ID_MODEL_FROM_DATABASE=JMB363 SATA/IDE Controller (Motherboard)
 
 pci:v0000197Bd00002363sv00001849sd00002363*
- ID_MODEL_FROM_DATABASE=Motherboard (one of many)
+ ID_MODEL_FROM_DATABASE=JMB363 SATA/IDE Controller (Motherboard (one of many))
 
 pci:v0000197Bd00002364*
  ID_MODEL_FROM_DATABASE=JMB364 AHCI Controller
@@ -51060,19 +52395,19 @@ pci:v000019A2d00000700*
  ID_MODEL_FROM_DATABASE=OneConnect 10Gb NIC
 
 pci:v000019A2d00000700sv0000103Csd00001747*
- ID_MODEL_FROM_DATABASE=NC550SFP DualPort 10GbE Server Adapter
+ ID_MODEL_FROM_DATABASE=OneConnect 10Gb NIC (NC550SFP DualPort 10GbE Server Adapter)
 
 pci:v000019A2d00000700sv0000103Csd00001749*
- ID_MODEL_FROM_DATABASE=NC550SFP Dual Port Server Adapter
+ ID_MODEL_FROM_DATABASE=OneConnect 10Gb NIC (NC550SFP Dual Port Server Adapter)
 
 pci:v000019A2d00000700sv0000103Csd0000174A*
- ID_MODEL_FROM_DATABASE=NC551m Dual Port FlexFabric 10Gb Adapter
+ ID_MODEL_FROM_DATABASE=OneConnect 10Gb NIC (NC551m Dual Port FlexFabric 10Gb Adapter)
 
 pci:v000019A2d00000700sv0000103Csd0000174B*
- ID_MODEL_FROM_DATABASE=StorageWorks NC550 DualPort Converged Network Adapter
+ ID_MODEL_FROM_DATABASE=OneConnect 10Gb NIC (StorageWorks NC550 DualPort Converged Network Adapter)
 
 pci:v000019A2d00000700sv0000103Csd00003314*
- ID_MODEL_FROM_DATABASE=NC551i Dual Port FlexFabric 10Gb Adapter
+ ID_MODEL_FROM_DATABASE=OneConnect 10Gb NIC (NC551i Dual Port FlexFabric 10Gb Adapter)
 
 pci:v000019A2d00000702*
  ID_MODEL_FROM_DATABASE=OneConnect 10Gb iSCSI Initiator
@@ -51084,16 +52419,19 @@ pci:v000019A2d00000710*
  ID_MODEL_FROM_DATABASE=OneConnect 10Gb NIC (be3)
 
 pci:v000019A2d00000710sv0000103Csd00003315*
- ID_MODEL_FROM_DATABASE=NC553i 10Gb 2-port FlexFabric Converged Network Adapter
+ ID_MODEL_FROM_DATABASE=OneConnect 10Gb NIC (be3) (NC553i 10Gb 2-port FlexFabric Converged Network Adapter)
 
 pci:v000019A2d00000710sv0000103Csd00003340*
- ID_MODEL_FROM_DATABASE=NC552SFP 2-port 10Gb Server Adapter
+ ID_MODEL_FROM_DATABASE=OneConnect 10Gb NIC (be3) (NC552SFP 2-port 10Gb Server Adapter)
 
 pci:v000019A2d00000710sv0000103Csd00003341*
- ID_MODEL_FROM_DATABASE=NC552m 10Gb 2-port FlexFabric Converged Network Adapter
+ ID_MODEL_FROM_DATABASE=OneConnect 10Gb NIC (be3) (NC552m 10Gb 2-port FlexFabric Converged Network Adapter)
 
 pci:v000019A2d00000710sv0000103Csd00003345*
- ID_MODEL_FROM_DATABASE=NC553m 10Gb 2-port FlexFabric Converged Network Adapter
+ ID_MODEL_FROM_DATABASE=OneConnect 10Gb NIC (be3) (NC553m 10Gb 2-port FlexFabric Converged Network Adapter)
+
+pci:v000019A2d00000710sv0000103Csd0000337B*
+ ID_MODEL_FROM_DATABASE=OneConnect 10Gb NIC (be3) (NC554FLB 10Gb 2-port FlexFabric Converged Network Adapter)
 
 pci:v000019A2d00000712*
  ID_MODEL_FROM_DATABASE=OneConnect 10Gb iSCSI Initiator (be3)
@@ -51102,7 +52440,10 @@ pci:v000019A2d00000714*
  ID_MODEL_FROM_DATABASE=OneConnect 10Gb FCoE Initiator (be3)
 
 pci:v000019A2d00000714sv0000103Csd00003315*
- ID_MODEL_FROM_DATABASE=NC553i 10Gb 2-port FlexFabric Converged Network Adapter
+ ID_MODEL_FROM_DATABASE=OneConnect 10Gb FCoE Initiator (be3) (NC553i 10Gb 2-port FlexFabric Converged Network Adapter)
+
+pci:v000019A2d00000714sv0000103Csd0000337B*
+ ID_MODEL_FROM_DATABASE=OneConnect 10Gb FCoE Initiator (be3) (NC554FLB 10Gb 2-port FlexFabric Converged Network Adapter)
 
 pci:v000019A8*
  ID_VENDOR_FROM_DATABASE=DAQDATA GmbH
@@ -51236,6 +52577,12 @@ pci:v00001A22*
 pci:v00001A29*
  ID_VENDOR_FROM_DATABASE=Fortinet, Inc.
 
+pci:v00001A29d00004338*
+ ID_MODEL_FROM_DATABASE=CP8 Content Processor ASIC
+
+pci:v00001A29d00004E36*
+ ID_MODEL_FROM_DATABASE=NP6 Network Processor
+
 pci:v00001A2B*
  ID_VENDOR_FROM_DATABASE=Ascom AG
 
@@ -51257,6 +52604,18 @@ pci:v00001A2Bd0000000A*
 pci:v00001A2Bd0000000E*
  ID_MODEL_FROM_DATABASE=DSLP-104 v1.1
 
+pci:v00001A30*
+ ID_VENDOR_FROM_DATABASE=Lantiq
+
+pci:v00001A30d00000680*
+ ID_MODEL_FROM_DATABASE=MtW8171 [Hyperion II]
+
+pci:v00001A30d00000700*
+ ID_MODEL_FROM_DATABASE=Wave300 PSB8224 [Hyperion III]
+
+pci:v00001A30d00000710*
+ ID_MODEL_FROM_DATABASE=Wave300 PSB8231 [Hyperion III]
+
 pci:v00001A32*
  ID_VENDOR_FROM_DATABASE=Quanta Microsystems, Inc
 
@@ -51396,19 +52755,19 @@ pci:v00001A78*
  ID_VENDOR_FROM_DATABASE=Virident Systems Inc.
 
 pci:v00001A78d00000031*
- ID_MODEL_FROM_DATABASE=Virident FlashMAX Drive
+ ID_MODEL_FROM_DATABASE=FlashMAX Drive
 
 pci:v00001A78d00000031sv00001A78sd00000034*
- ID_MODEL_FROM_DATABASE=FlashMAX PCIe SSD [rev 3]
+ ID_MODEL_FROM_DATABASE=FlashMAX Drive (FlashMAX PCIe SSD [rev 3])
 
 pci:v00001A78d00000031sv00001A78sd00000037*
- ID_MODEL_FROM_DATABASE=FlashMAX PCIe SSD [rev 3D]
+ ID_MODEL_FROM_DATABASE=FlashMAX Drive (FlashMAX PCIe SSD [rev 3D])
 
 pci:v00001A78d00000031sv00001A78sd00000038*
- ID_MODEL_FROM_DATABASE=FlashMAX PCIe SSD [rev 4]
+ ID_MODEL_FROM_DATABASE=FlashMAX Drive (FlashMAX PCIe SSD [rev 4])
 
 pci:v00001A78d00000031sv00001A78sd00000039*
- ID_MODEL_FROM_DATABASE=FlashMAX PCIe SSD [rev 4D]
+ ID_MODEL_FROM_DATABASE=FlashMAX Drive (FlashMAX PCIe SSD [rev 4D])
 
 pci:v00001A78d00000040*
  ID_MODEL_FROM_DATABASE=FlashMAX II
@@ -51419,6 +52778,9 @@ pci:v00001A78d00000041*
 pci:v00001A78d00000042*
  ID_MODEL_FROM_DATABASE=FlashMAX II
 
+pci:v00001A78d00000050*
+ ID_MODEL_FROM_DATABASE=FlashMAX III
+
 pci:v00001A84*
  ID_VENDOR_FROM_DATABASE=Commex Technologies
 
@@ -51476,6 +52838,9 @@ pci:v00001AB8d00004006*
 pci:v00001AB9*
  ID_VENDOR_FROM_DATABASE=Espia Srl
 
+pci:v00001AC8*
+ ID_VENDOR_FROM_DATABASE=Aeroflex Gaisler
+
 pci:v00001ACC*
  ID_VENDOR_FROM_DATABASE=Point of View BV
 
@@ -51546,25 +52911,25 @@ pci:v00001AEDd00001005*
  ID_MODEL_FROM_DATABASE=ioDimm3
 
 pci:v00001AEDd00001005sv00001014sd000003C3*
- ID_MODEL_FROM_DATABASE=High IOPS SSD PCIe Adapter
+ ID_MODEL_FROM_DATABASE=ioDimm3 (High IOPS SSD PCIe Adapter)
 
 pci:v00001AEDd00001005sv0000103Csd0000176F*
- ID_MODEL_FROM_DATABASE=1.28TB MLC PCIe ioDrive Duo
+ ID_MODEL_FROM_DATABASE=ioDimm3 (1.28TB MLC PCIe ioDrive Duo)
 
 pci:v00001AEDd00001005sv0000103Csd00001770*
- ID_MODEL_FROM_DATABASE=5.2TB MLC PCIe ioDrive Octal
+ ID_MODEL_FROM_DATABASE=ioDimm3 (5.2TB MLC PCIe ioDrive Octal)
 
 pci:v00001AEDd00001005sv0000103Csd0000178B*
- ID_MODEL_FROM_DATABASE=160GB SLC PCIe ioDrive
+ ID_MODEL_FROM_DATABASE=ioDimm3 (160GB SLC PCIe ioDrive)
 
 pci:v00001AEDd00001005sv0000103Csd0000178C*
- ID_MODEL_FROM_DATABASE=320GB MLC PCIe ioDrive
+ ID_MODEL_FROM_DATABASE=ioDimm3 (320GB MLC PCIe ioDrive)
 
 pci:v00001AEDd00001005sv0000103Csd0000178D*
- ID_MODEL_FROM_DATABASE=320GB SLC PCIe ioDrive Duo
+ ID_MODEL_FROM_DATABASE=ioDimm3 (320GB SLC PCIe ioDrive Duo)
 
 pci:v00001AEDd00001005sv0000103Csd0000178E*
- ID_MODEL_FROM_DATABASE=640GB MLC PCIe ioDrive Duo
+ ID_MODEL_FROM_DATABASE=ioDimm3 (640GB MLC PCIe ioDrive Duo)
 
 pci:v00001AEDd00001006*
  ID_MODEL_FROM_DATABASE=ioXtreme
@@ -51578,6 +52943,15 @@ pci:v00001AEDd00001008*
 pci:v00001AEDd00002001*
  ID_MODEL_FROM_DATABASE=ioDrive2
 
+pci:v00001AEDd00003001*
+ ID_MODEL_FROM_DATABASE=ioMemory FHHL
+
+pci:v00001AEDd00003002*
+ ID_MODEL_FROM_DATABASE=ioMemory HHHL
+
+pci:v00001AEDd00003003*
+ ID_MODEL_FROM_DATABASE=ioMemory Mezzanine
+
 pci:v00001AEE*
  ID_VENDOR_FROM_DATABASE=Caustic Graphics Inc.
 
@@ -51605,6 +52979,18 @@ pci:v00001AF4d00001005*
 pci:v00001AF4d00001009*
  ID_MODEL_FROM_DATABASE=Virtio filesystem
 
+pci:v00001AF4d00001010*
+ ID_MODEL_FROM_DATABASE=Virtio GPU
+
+pci:v00001AF4d00001012*
+ ID_MODEL_FROM_DATABASE=Virtio input device
+
+pci:v00001AF4d00001110*
+ ID_MODEL_FROM_DATABASE=Inter-VM shared memory
+
+pci:v00001AF4d00001110sv00001AF4sd00001100*
+ ID_MODEL_FROM_DATABASE=Inter-VM shared memory (QEMU Virtual Machine)
+
 pci:v00001AF5*
  ID_VENDOR_FROM_DATABASE=Netezza Corp.
 
@@ -51642,19 +53028,25 @@ pci:v00001B21d00000612*
  ID_MODEL_FROM_DATABASE=ASM1062 Serial ATA Controller
 
 pci:v00001B21d00000612sv00001849sd00000612*
- ID_MODEL_FROM_DATABASE=Motherboard
+ ID_MODEL_FROM_DATABASE=ASM1062 Serial ATA Controller (Motherboard)
 
 pci:v00001B21d00001042*
  ID_MODEL_FROM_DATABASE=ASM1042 SuperSpeed USB Host Controller
 
+pci:v00001B21d00001042sv00001043sd00008488*
+ ID_MODEL_FROM_DATABASE=ASM1042 SuperSpeed USB Host Controller (P8B WS Motherboard)
+
 pci:v00001B21d00001042sv00001849sd00001042*
- ID_MODEL_FROM_DATABASE=Motherboard
+ ID_MODEL_FROM_DATABASE=ASM1042 SuperSpeed USB Host Controller (Motherboard)
 
 pci:v00001B21d00001080*
  ID_MODEL_FROM_DATABASE=ASM1083/1085 PCIe to PCI Bridge
 
 pci:v00001B21d00001080sv00001849sd00001080*
- ID_MODEL_FROM_DATABASE=Motherboard
+ ID_MODEL_FROM_DATABASE=ASM1083/1085 PCIe to PCI Bridge (Motherboard)
+
+pci:v00001B21d00001142*
+ ID_MODEL_FROM_DATABASE=ASM1042A USB 3.0 Host Controller
 
 pci:v00001B2C*
  ID_VENDOR_FROM_DATABASE=Opal-RT Technologies Inc.
@@ -51662,6 +53054,39 @@ pci:v00001B2C*
 pci:v00001B36*
  ID_VENDOR_FROM_DATABASE=Red Hat, Inc.
 
+pci:v00001B36d00000001*
+ ID_MODEL_FROM_DATABASE=QEMU PCI-PCI bridge
+
+pci:v00001B36d00000002*
+ ID_MODEL_FROM_DATABASE=QEMU PCI 16550A Adapter
+
+pci:v00001B36d00000002sv00001AF4sd00001100*
+ ID_MODEL_FROM_DATABASE=QEMU PCI 16550A Adapter (QEMU Virtual Machine)
+
+pci:v00001B36d00000003*
+ ID_MODEL_FROM_DATABASE=QEMU PCI Dual-port 16550A Adapter
+
+pci:v00001B36d00000003sv00001AF4sd00001100*
+ ID_MODEL_FROM_DATABASE=QEMU PCI Dual-port 16550A Adapter (QEMU Virtual Machine)
+
+pci:v00001B36d00000004*
+ ID_MODEL_FROM_DATABASE=QEMU PCI Quad-port 16550A Adapter
+
+pci:v00001B36d00000004sv00001AF4sd00001100*
+ ID_MODEL_FROM_DATABASE=QEMU PCI Quad-port 16550A Adapter (QEMU Virtual Machine)
+
+pci:v00001B36d00000005*
+ ID_MODEL_FROM_DATABASE=QEMU PCI Test Device
+
+pci:v00001B36d00000005sv00001AF4sd00001100*
+ ID_MODEL_FROM_DATABASE=QEMU PCI Test Device (QEMU Virtual Machine)
+
+pci:v00001B36d00000100*
+ ID_MODEL_FROM_DATABASE=QXL paravirtual graphic card
+
+pci:v00001B36d00000100sv00001AF4sd00001100*
+ ID_MODEL_FROM_DATABASE=QXL paravirtual graphic card (QEMU Virtual Machine)
+
 pci:v00001B37*
  ID_VENDOR_FROM_DATABASE=Signal Processing Devices Sweden AB
 
@@ -51681,10 +53106,10 @@ pci:v00001B3Ed00001FA8*
  ID_MODEL_FROM_DATABASE=BYNET BIC2SE/X
 
 pci:v00001B3Ed00001FA8sv00001B3Esd000000A3*
- ID_MODEL_FROM_DATABASE=BYNET BIC2SX
+ ID_MODEL_FROM_DATABASE=BYNET BIC2SE/X (BYNET BIC2SX)
 
 pci:v00001B3Ed00001FA8sv00001B3Esd000000C3*
- ID_MODEL_FROM_DATABASE=BYNET BIC2SE
+ ID_MODEL_FROM_DATABASE=BYNET BIC2SE/X (BYNET BIC2SE)
 
 pci:v00001B40*
  ID_VENDOR_FROM_DATABASE=Schooner Information Technology, Inc.
@@ -51720,11 +53145,14 @@ pci:v00001B4Bd00009130*
  ID_MODEL_FROM_DATABASE=88SE9128 PCIe SATA 6 Gb/s RAID controller with HyperDuo
 
 pci:v00001B4Bd00009130sv00001043sd00008438*
- ID_MODEL_FROM_DATABASE=P8P67 Deluxe Motherboard
+ ID_MODEL_FROM_DATABASE=88SE9128 PCIe SATA 6 Gb/s RAID controller with HyperDuo (P8P67 Deluxe Motherboard)
 
 pci:v00001B4Bd00009172*
  ID_MODEL_FROM_DATABASE=88SE9172 SATA 6Gb/s Controller
 
+pci:v00001B4Bd00009178*
+ ID_MODEL_FROM_DATABASE=88SE9170 PCIe SATA 6Gb/s Controller
+
 pci:v00001B4Bd0000917A*
  ID_MODEL_FROM_DATABASE=88SE9172 SATA III 6Gb/s RAID Controller
 
@@ -51740,9 +53168,18 @@ pci:v00001B4Bd000091A0*
 pci:v00001B4Bd000091A4*
  ID_MODEL_FROM_DATABASE=88SE912x IDE Controller
 
+pci:v00001B4Bd00009220*
+ ID_MODEL_FROM_DATABASE=88SE9220 PCIe 2.0 x2 2-port SATA 6 Gb/s RAID Controller
+
 pci:v00001B4Bd00009230*
  ID_MODEL_FROM_DATABASE=88SE9230 PCIe SATA 6Gb/s Controller
 
+pci:v00001B4Bd00009235*
+ ID_MODEL_FROM_DATABASE=88SE9235 PCIe 2.0 x2 4-port SATA 6 Gb/s Controller
+
+pci:v00001B4Bd00009445*
+ ID_MODEL_FROM_DATABASE=88SE9445 PCIe 2.0 x4 4-Port SAS/SATA 6 Gbps RAID Controller
+
 pci:v00001B4Bd00009480*
  ID_MODEL_FROM_DATABASE=88SE9480 SAS/SATA 6Gb/s RAID controller
 
@@ -51752,6 +53189,9 @@ pci:v00001B4Bd00009485*
 pci:v00001B55*
  ID_VENDOR_FROM_DATABASE=NetUP Inc.
 
+pci:v00001B55d000018F6*
+ ID_MODEL_FROM_DATABASE=Dual DVB Universal CI card
+
 pci:v00001B55d00002A2C*
  ID_MODEL_FROM_DATABASE=Dual DVB-S2-CI card
 
@@ -51780,7 +53220,7 @@ pci:v00001B73d00001000*
  ID_MODEL_FROM_DATABASE=FL1000G USB 3.0 Host Controller
 
 pci:v00001B73d00001000sv00001D5Csd00001000*
- ID_MODEL_FROM_DATABASE=Anker USB 3.0 Express Card
+ ID_MODEL_FROM_DATABASE=FL1000G USB 3.0 Host Controller (Anker USB 3.0 Express Card)
 
 pci:v00001B73d00001009*
  ID_MODEL_FROM_DATABASE=FL1009 USB 3.0 Host Controller
@@ -51875,6 +53315,9 @@ pci:v00001BBFd00000004*
 pci:v00001BF4*
  ID_VENDOR_FROM_DATABASE=VTI Instruments Corporation
 
+pci:v00001BF4d00000001*
+ ID_MODEL_FROM_DATABASE=SentinelEX
+
 pci:v00001BFD*
  ID_VENDOR_FROM_DATABASE=EeeTOP
 
@@ -51902,6 +53345,18 @@ pci:v00001C2Cd000000A1*
 pci:v00001C2Cd000000A2*
  ID_MODEL_FROM_DATABASE=FBC8XG Capture 8x10Gb
 
+pci:v00001C2Cd000000A3*
+ ID_MODEL_FROM_DATABASE=FBC2XG Capture 2x10Gb
+
+pci:v00001C2Cd000000A4*
+ ID_MODEL_FROM_DATABASE=FBC4XGG3 Capture 4x10Gb
+
+pci:v00001C2Cd000000A5*
+ ID_MODEL_FROM_DATABASE=FBC2XLG Capture 2x40Gb
+
+pci:v00001C2Cd000000A6*
+ ID_MODEL_FROM_DATABASE=FBC1CG Capture 1x100Gb
+
 pci:v00001C32*
  ID_VENDOR_FROM_DATABASE=Highland Technology, Inc.
 
@@ -51956,6 +53411,9 @@ pci:v00001CE4d00000002*
 pci:v00001CF7*
  ID_VENDOR_FROM_DATABASE=Subspace Dynamics
 
+pci:v00001D21*
+ ID_VENDOR_FROM_DATABASE=Allo
+
 pci:v00001D44*
  ID_VENDOR_FROM_DATABASE=DPT
 
@@ -52008,67 +53466,67 @@ pci:v00001FC9d00003010*
  ID_MODEL_FROM_DATABASE=10-Giga TOE SmartNIC
 
 pci:v00001FC9d00003010sv00000000sd00003002*
- ID_MODEL_FROM_DATABASE=10-Giga TOE Single Port XFP SmartNIC
+ ID_MODEL_FROM_DATABASE=10-Giga TOE SmartNIC (10-Giga TOE Single Port XFP SmartNIC)
 
 pci:v00001FC9d00003010sv00000000sd00003004*
- ID_MODEL_FROM_DATABASE=10-Giga TOE Single Port SFP+ SmartNIC
+ ID_MODEL_FROM_DATABASE=10-Giga TOE SmartNIC (10-Giga TOE Single Port SFP+ SmartNIC)
 
 pci:v00001FC9d00003010sv00000000sd00003008*
- ID_MODEL_FROM_DATABASE=10-Giga TOE Single Port CX4 SmartNIC
+ ID_MODEL_FROM_DATABASE=10-Giga TOE SmartNIC (10-Giga TOE Single Port CX4 SmartNIC)
 
 pci:v00001FC9d00003014*
  ID_MODEL_FROM_DATABASE=10-Giga TOE SmartNIC 2-Port
 
 pci:v00001FC9d00003014sv00000000sd00003003*
- ID_MODEL_FROM_DATABASE=10-Giga TOE Dual Port XFP Low Profile SmartNIC
+ ID_MODEL_FROM_DATABASE=10-Giga TOE SmartNIC 2-Port (10-Giga TOE Dual Port XFP Low Profile SmartNIC)
 
 pci:v00001FC9d00003014sv00000000sd00003005*
- ID_MODEL_FROM_DATABASE=10-Giga TOE Dual Port SFP+ Low Profile SmartNIC
+ ID_MODEL_FROM_DATABASE=10-Giga TOE SmartNIC 2-Port (10-Giga TOE Dual Port SFP+ Low Profile SmartNIC)
 
 pci:v00001FC9d00003014sv00000000sd00003014*
- ID_MODEL_FROM_DATABASE=10-Giga TOE Dual Port CX4 Low Profile SmartNIC
+ ID_MODEL_FROM_DATABASE=10-Giga TOE SmartNIC 2-Port (10-Giga TOE Dual Port CX4 Low Profile SmartNIC)
 
 pci:v00001FC9d00003110*
  ID_MODEL_FROM_DATABASE=10-Giga TOE Single Port SmartNIC
 
 pci:v00001FC9d00003110sv00000000sd00003004*
- ID_MODEL_FROM_DATABASE=10-Giga TOE Single Port SFP+ SmartNIC
+ ID_MODEL_FROM_DATABASE=10-Giga TOE Single Port SmartNIC (10-Giga TOE Single Port SFP+ SmartNIC)
 
 pci:v00001FC9d00003114*
  ID_MODEL_FROM_DATABASE=10-Giga TOE Dual Port Low Profile SmartNIC
 
 pci:v00001FC9d00003114sv00000000sd00003005*
- ID_MODEL_FROM_DATABASE=10-Giga TOE Dual Port SFP+ Low Profile SmartNIC
+ ID_MODEL_FROM_DATABASE=10-Giga TOE Dual Port Low Profile SmartNIC (10-Giga TOE Dual Port SFP+ Low Profile SmartNIC)
 
 pci:v00001FC9d00003114sv00000000sd00003011*
- ID_MODEL_FROM_DATABASE=10-Giga TOE Dual Port SFP+/CX4 Low Profile SmartNIC
+ ID_MODEL_FROM_DATABASE=10-Giga TOE Dual Port Low Profile SmartNIC (10-Giga TOE Dual Port SFP+/CX4 Low Profile SmartNIC)
 
 pci:v00001FC9d00003114sv00000000sd00003012*
- ID_MODEL_FROM_DATABASE=10-Giga TOE Dual Port CX4/SFP+ Low Profile SmartNIC
+ ID_MODEL_FROM_DATABASE=10-Giga TOE Dual Port Low Profile SmartNIC (10-Giga TOE Dual Port CX4/SFP+ Low Profile SmartNIC)
 
 pci:v00001FC9d00003114sv00000000sd00003014*
- ID_MODEL_FROM_DATABASE=10-Giga TOE Dual Port CX4 Low Profile SmartNIC
+ ID_MODEL_FROM_DATABASE=10-Giga TOE Dual Port Low Profile SmartNIC (10-Giga TOE Dual Port CX4 Low Profile SmartNIC)
 
 pci:v00001FC9d00003310*
  ID_MODEL_FROM_DATABASE=10-Giga TOE SFP+ Single Port SmartNIC
 
 pci:v00001FC9d00003310sv00000000sd00003004*
- ID_MODEL_FROM_DATABASE=10-Giga TOE Single Port SFP+ SmartNIC
+ ID_MODEL_FROM_DATABASE=10-Giga TOE SFP+ Single Port SmartNIC (10-Giga TOE Single Port SFP+ SmartNIC)
 
 pci:v00001FC9d00003314*
  ID_MODEL_FROM_DATABASE=10-Giga TOE Dual Port Low Profile SmartNIC
 
 pci:v00001FC9d00003314sv00000000sd00003005*
- ID_MODEL_FROM_DATABASE=10-Giga TOE Dual Port SFP+ Low Profile SmartNIC
+ ID_MODEL_FROM_DATABASE=10-Giga TOE Dual Port Low Profile SmartNIC (10-Giga TOE Dual Port SFP+ Low Profile SmartNIC)
 
 pci:v00001FC9d00003314sv00000000sd00003011*
- ID_MODEL_FROM_DATABASE=10-Giga TOE Dual Port SFP+/CX4 Low Profile SmartNIC
+ ID_MODEL_FROM_DATABASE=10-Giga TOE Dual Port Low Profile SmartNIC (10-Giga TOE Dual Port SFP+/CX4 Low Profile SmartNIC)
 
 pci:v00001FC9d00003314sv00000000sd00003012*
- ID_MODEL_FROM_DATABASE=10-Giga TOE Dual Port CX4/SFP+ Low Profile SmartNIC
+ ID_MODEL_FROM_DATABASE=10-Giga TOE Dual Port Low Profile SmartNIC (10-Giga TOE Dual Port CX4/SFP+ Low Profile SmartNIC)
 
 pci:v00001FC9d00003314sv00000000sd00003014*
- ID_MODEL_FROM_DATABASE=10-Giga TOE Dual Port CX4 Low Profile SmartNIC
+ ID_MODEL_FROM_DATABASE=10-Giga TOE Dual Port Low Profile SmartNIC (10-Giga TOE Dual Port CX4 Low Profile SmartNIC)
 
 pci:v00001FCE*
  ID_VENDOR_FROM_DATABASE=Cognio Inc.
@@ -52170,31 +53628,31 @@ pci:v00003388d00000021*
  ID_MODEL_FROM_DATABASE=HB6 Universal PCI-PCI bridge (non-transparent mode)
 
 pci:v00003388d00000021sv00001775sd0000C200*
- ID_MODEL_FROM_DATABASE=C2K CompactPCI interface bridge
+ ID_MODEL_FROM_DATABASE=HB6 Universal PCI-PCI bridge (non-transparent mode) (C2K CompactPCI interface bridge)
 
 pci:v00003388d00000021sv00001775sd0000CE90*
- ID_MODEL_FROM_DATABASE=CE9
+ ID_MODEL_FROM_DATABASE=HB6 Universal PCI-PCI bridge (non-transparent mode) (CE9)
 
 pci:v00003388d00000021sv00004C53sd00001050*
- ID_MODEL_FROM_DATABASE=CT7 mainboard
+ ID_MODEL_FROM_DATABASE=HB6 Universal PCI-PCI bridge (non-transparent mode) (CT7 mainboard)
 
 pci:v00003388d00000021sv00004C53sd00001080*
- ID_MODEL_FROM_DATABASE=CT8 mainboard
+ ID_MODEL_FROM_DATABASE=HB6 Universal PCI-PCI bridge (non-transparent mode) (CT8 mainboard)
 
 pci:v00003388d00000021sv00004C53sd00001090*
- ID_MODEL_FROM_DATABASE=Cx9 mainboard
+ ID_MODEL_FROM_DATABASE=HB6 Universal PCI-PCI bridge (non-transparent mode) (Cx9 mainboard)
 
 pci:v00003388d00000021sv00004C53sd000010A0*
- ID_MODEL_FROM_DATABASE=CA3/CR3 mainboard
+ ID_MODEL_FROM_DATABASE=HB6 Universal PCI-PCI bridge (non-transparent mode) (CA3/CR3 mainboard)
 
 pci:v00003388d00000021sv00004C53sd00003010*
- ID_MODEL_FROM_DATABASE=PPCI mezzanine (32-bit PMC)
+ ID_MODEL_FROM_DATABASE=HB6 Universal PCI-PCI bridge (non-transparent mode) (PPCI mezzanine (32-bit PMC))
 
 pci:v00003388d00000021sv00004C53sd00003011*
- ID_MODEL_FROM_DATABASE=PPCI mezzanine (64-bit PMC)
+ ID_MODEL_FROM_DATABASE=HB6 Universal PCI-PCI bridge (non-transparent mode) (PPCI mezzanine (64-bit PMC))
 
 pci:v00003388d00000021sv00004C53sd00004000*
- ID_MODEL_FROM_DATABASE=PMCCARR1 carrier board
+ ID_MODEL_FROM_DATABASE=HB6 Universal PCI-PCI bridge (non-transparent mode) (PMCCARR1 carrier board)
 
 pci:v00003388d00000022*
  ID_MODEL_FROM_DATABASE=HiNT HB4 PCI-PCI Bridge (PCI6150)
@@ -52218,19 +53676,19 @@ pci:v00003388d00008011*
  ID_MODEL_FROM_DATABASE=VXPro II Chipset
 
 pci:v00003388d00008011sv00003388sd00008011*
- ID_MODEL_FROM_DATABASE=VXPro II Chipset CPU to PCI Bridge
+ ID_MODEL_FROM_DATABASE=VXPro II Chipset (CPU to PCI Bridge)
 
 pci:v00003388d00008012*
  ID_MODEL_FROM_DATABASE=VXPro II Chipset
 
 pci:v00003388d00008012sv00003388sd00008012*
- ID_MODEL_FROM_DATABASE=VXPro II Chipset PCI to ISA Bridge
+ ID_MODEL_FROM_DATABASE=VXPro II Chipset (PCI to ISA Bridge)
 
 pci:v00003388d00008013*
  ID_MODEL_FROM_DATABASE=VXPro II IDE
 
 pci:v00003388d00008013sv00003388sd00008013*
- ID_MODEL_FROM_DATABASE=VXPro II Chipset EIDE Controller
+ ID_MODEL_FROM_DATABASE=VXPro II IDE (VXPro II Chipset EIDE Controller)
 
 pci:v00003388d0000A103*
  ID_MODEL_FROM_DATABASE=Blackmagic Design DeckLink HD Pro
@@ -52275,13 +53733,13 @@ pci:v00003D3Dd00000002*
  ID_MODEL_FROM_DATABASE=GLINT 500TX
 
 pci:v00003D3Dd00000002sv00000000sd00000000*
- ID_MODEL_FROM_DATABASE=GLoria L
+ ID_MODEL_FROM_DATABASE=GLINT 500TX (GLoria L)
 
 pci:v00003D3Dd00000003*
  ID_MODEL_FROM_DATABASE=GLINT Delta
 
 pci:v00003D3Dd00000003sv00000000sd00000000*
- ID_MODEL_FROM_DATABASE=GLoria XL
+ ID_MODEL_FROM_DATABASE=GLINT Delta (GLoria XL)
 
 pci:v00003D3Dd00000004*
  ID_MODEL_FROM_DATABASE=Permedia
@@ -52293,10 +53751,10 @@ pci:v00003D3Dd00000006*
  ID_MODEL_FROM_DATABASE=GLINT MX
 
 pci:v00003D3Dd00000006sv00000000sd00000000*
- ID_MODEL_FROM_DATABASE=GLoria XL
+ ID_MODEL_FROM_DATABASE=GLINT MX (GLoria XL)
 
 pci:v00003D3Dd00000006sv00001048sd00000A42*
- ID_MODEL_FROM_DATABASE=GLoria XXL
+ ID_MODEL_FROM_DATABASE=GLINT MX (GLoria XXL)
 
 pci:v00003D3Dd00000007*
  ID_MODEL_FROM_DATABASE=3D Extreme
@@ -52305,55 +53763,55 @@ pci:v00003D3Dd00000008*
  ID_MODEL_FROM_DATABASE=GLINT Gamma G1
 
 pci:v00003D3Dd00000008sv00001048sd00000A42*
- ID_MODEL_FROM_DATABASE=GLoria XXL
+ ID_MODEL_FROM_DATABASE=GLINT Gamma G1 (GLoria XXL)
 
 pci:v00003D3Dd00000009*
  ID_MODEL_FROM_DATABASE=Permedia II 2D+3D
 
 pci:v00003D3Dd00000009sv00001040sd00000011*
- ID_MODEL_FROM_DATABASE=AccelStar II
+ ID_MODEL_FROM_DATABASE=Permedia II 2D+3D (AccelStar II)
 
 pci:v00003D3Dd00000009sv00001048sd00000A42*
- ID_MODEL_FROM_DATABASE=GLoria XXL
+ ID_MODEL_FROM_DATABASE=Permedia II 2D+3D (GLoria XXL)
 
 pci:v00003D3Dd00000009sv000013E9sd00001000*
- ID_MODEL_FROM_DATABASE=6221L-4U
+ ID_MODEL_FROM_DATABASE=Permedia II 2D+3D (6221L-4U)
 
 pci:v00003D3Dd00000009sv00003D3Dsd00000100*
- ID_MODEL_FROM_DATABASE=AccelStar II 3D Accelerator
+ ID_MODEL_FROM_DATABASE=Permedia II 2D+3D (AccelStar II 3D Accelerator)
 
 pci:v00003D3Dd00000009sv00003D3Dsd00000111*
- ID_MODEL_FROM_DATABASE=Permedia 3:16
+ ID_MODEL_FROM_DATABASE=Permedia II 2D+3D (Permedia 3:16)
 
 pci:v00003D3Dd00000009sv00003D3Dsd00000114*
- ID_MODEL_FROM_DATABASE=Santa Ana
+ ID_MODEL_FROM_DATABASE=Permedia II 2D+3D (Santa Ana)
 
 pci:v00003D3Dd00000009sv00003D3Dsd00000116*
- ID_MODEL_FROM_DATABASE=Oxygen GVX1
+ ID_MODEL_FROM_DATABASE=Permedia II 2D+3D (Oxygen GVX1)
 
 pci:v00003D3Dd00000009sv00003D3Dsd00000119*
- ID_MODEL_FROM_DATABASE=Scirocco
+ ID_MODEL_FROM_DATABASE=Permedia II 2D+3D (Scirocco)
 
 pci:v00003D3Dd00000009sv00003D3Dsd00000120*
- ID_MODEL_FROM_DATABASE=Santa Ana PCL
+ ID_MODEL_FROM_DATABASE=Permedia II 2D+3D (Santa Ana PCL)
 
 pci:v00003D3Dd00000009sv00003D3Dsd00000125*
- ID_MODEL_FROM_DATABASE=Oxygen VX1
+ ID_MODEL_FROM_DATABASE=Permedia II 2D+3D (Oxygen VX1)
 
 pci:v00003D3Dd00000009sv00003D3Dsd00000127*
- ID_MODEL_FROM_DATABASE=Permedia3 Create!
+ ID_MODEL_FROM_DATABASE=Permedia II 2D+3D (Permedia3 Create!)
 
 pci:v00003D3Dd0000000A*
  ID_MODEL_FROM_DATABASE=GLINT R3
 
 pci:v00003D3Dd0000000Asv00003D3Dsd00000121*
- ID_MODEL_FROM_DATABASE=Oxygen VX1
+ ID_MODEL_FROM_DATABASE=GLINT R3 (Oxygen VX1)
 
 pci:v00003D3Dd0000000C*
  ID_MODEL_FROM_DATABASE=GLINT R3 [Oxygen VX1]
 
 pci:v00003D3Dd0000000Csv00003D3Dsd00000144*
- ID_MODEL_FROM_DATABASE=Oxygen VX1-4X AGP [Permedia 4]
+ ID_MODEL_FROM_DATABASE=GLINT R3 [Oxygen VX1] (Oxygen VX1-4X AGP [Permedia 4])
 
 pci:v00003D3Dd0000000D*
  ID_MODEL_FROM_DATABASE=GLint R4 rev A
@@ -52470,13 +53928,13 @@ pci:v00004040d00000001*
  ID_MODEL_FROM_DATABASE=NXB-10GXSR 10-Gigabit Ethernet PCIe Adapter with SR-XFP optical interface
 
 pci:v00004040d00000001sv0000103Csd00007047*
- ID_MODEL_FROM_DATABASE=NC510F PCIe 10-Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=NXB-10GXSR 10-Gigabit Ethernet PCIe Adapter with SR-XFP optical interface (NC510F PCIe 10-Gigabit Server Adapter)
 
 pci:v00004040d00000002*
  ID_MODEL_FROM_DATABASE=NXB-10GCX4 10-Gigabit Ethernet PCIe Adapter with CX4 copper interface
 
 pci:v00004040d00000002sv0000103Csd00007048*
- ID_MODEL_FROM_DATABASE=NC510c PCIe 10-Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=NXB-10GCX4 10-Gigabit Ethernet PCIe Adapter with CX4 copper interface (NC510c PCIe 10-Gigabit Server Adapter)
 
 pci:v00004040d00000003*
  ID_MODEL_FROM_DATABASE=NXB-4GCU Quad Gigabit Ethernet PCIe Adapter with 1000-BASE-T interface
@@ -52488,7 +53946,7 @@ pci:v00004040d00000005*
  ID_MODEL_FROM_DATABASE=NetXen Dual Port 10GbE Multifunction Adapter for c-Class
 
 pci:v00004040d00000005sv0000103Csd0000170E*
- ID_MODEL_FROM_DATABASE=NC512m Dual Port 10GbE Multifunction BL-C Adapter
+ ID_MODEL_FROM_DATABASE=NetXen Dual Port 10GbE Multifunction Adapter for c-Class (NC512m Dual Port 10GbE Multifunction BL-C Adapter)
 
 pci:v00004040d00000024*
  ID_MODEL_FROM_DATABASE=XG Mgmt
@@ -52500,28 +53958,28 @@ pci:v00004040d00000100*
  ID_MODEL_FROM_DATABASE=NX3031 Multifunction 1/10-Gigabit Server Adapter
 
 pci:v00004040d00000100sv0000103Csd0000171B*
- ID_MODEL_FROM_DATABASE=NC522m Dual Port 10GbE Multifunction BL-c Adapter
+ ID_MODEL_FROM_DATABASE=NX3031 Multifunction 1/10-Gigabit Server Adapter (NC522m Dual Port 10GbE Multifunction BL-c Adapter)
 
 pci:v00004040d00000100sv0000103Csd00001740*
- ID_MODEL_FROM_DATABASE=NC375T PCI Express Quad Port Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=NX3031 Multifunction 1/10-Gigabit Server Adapter (NC375T PCI Express Quad Port Gigabit Server Adapter)
 
 pci:v00004040d00000100sv0000103Csd00003251*
- ID_MODEL_FROM_DATABASE=NC375i 1G w/NC524SFP 10G Module
+ ID_MODEL_FROM_DATABASE=NX3031 Multifunction 1/10-Gigabit Server Adapter (NC375i 1G w/NC524SFP 10G Module)
 
 pci:v00004040d00000100sv0000103Csd0000705A*
- ID_MODEL_FROM_DATABASE=NC375i Integrated Quad Port Multifunction Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=NX3031 Multifunction 1/10-Gigabit Server Adapter (NC375i Integrated Quad Port Multifunction Gigabit Server Adapter)
 
 pci:v00004040d00000100sv0000103Csd0000705B*
- ID_MODEL_FROM_DATABASE=NC522SFP Dual Port 10GbE Server Adapter
+ ID_MODEL_FROM_DATABASE=NX3031 Multifunction 1/10-Gigabit Server Adapter (NC522SFP Dual Port 10GbE Server Adapter)
 
 pci:v00004040d00000100sv0000152Dsd0000896B*
- ID_MODEL_FROM_DATABASE=TG20 Dual Port 10GbE Server/Storage Adapter
+ ID_MODEL_FROM_DATABASE=NX3031 Multifunction 1/10-Gigabit Server Adapter (TG20 Dual Port 10GbE Server/Storage Adapter)
 
 pci:v00004040d00000100sv00004040sd00000124*
- ID_MODEL_FROM_DATABASE=NX3031 Quad Port Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=NX3031 Multifunction 1/10-Gigabit Server Adapter (NX3031 Quad Port Gigabit Server Adapter)
 
 pci:v00004040d00000100sv00004040sd00000126*
- ID_MODEL_FROM_DATABASE=Dual Port SFP+ 10GbE Server Adapter
+ ID_MODEL_FROM_DATABASE=NX3031 Multifunction 1/10-Gigabit Server Adapter (Dual Port SFP+ 10GbE Server Adapter)
 
 pci:v00004143*
  ID_VENDOR_FROM_DATABASE=Digital Equipment Corp
@@ -52556,6 +54014,9 @@ pci:v0000416Cd00000100*
 pci:v0000416Cd00000200*
  ID_MODEL_FROM_DATABASE=CPC
 
+pci:v00004254*
+ ID_VENDOR_FROM_DATABASE=DVBSky
+
 pci:v00004321*
  ID_VENDOR_FROM_DATABASE=Tata Power Strategic Electronics Division
 
@@ -52569,190 +54030,190 @@ pci:v00004444d00000016*
  ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder
 
 pci:v00004444d00000016sv00000070sd00000003*
- ID_MODEL_FROM_DATABASE=WinTV PVR 250
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (WinTV PVR 250)
 
 pci:v00004444d00000016sv00000070sd00000009*
- ID_MODEL_FROM_DATABASE=WinTV PVR 150
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (WinTV PVR 150)
 
 pci:v00004444d00000016sv00000070sd00000801*
- ID_MODEL_FROM_DATABASE=WinTV PVR 150
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (WinTV PVR 150)
 
 pci:v00004444d00000016sv00000070sd00000807*
- ID_MODEL_FROM_DATABASE=WinTV PVR 150
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (WinTV PVR 150)
 
 pci:v00004444d00000016sv00000070sd00004001*
- ID_MODEL_FROM_DATABASE=WinTV PVR 250
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (WinTV PVR 250)
 
 pci:v00004444d00000016sv00000070sd00004009*
- ID_MODEL_FROM_DATABASE=WinTV PVR 250
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (WinTV PVR 250)
 
 pci:v00004444d00000016sv00000070sd00004801*
- ID_MODEL_FROM_DATABASE=WinTV PVR 250
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (WinTV PVR 250)
 
 pci:v00004444d00000016sv00000070sd00004803*
- ID_MODEL_FROM_DATABASE=WinTV PVR 250
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (WinTV PVR 250)
 
 pci:v00004444d00000016sv00000070sd00008003*
- ID_MODEL_FROM_DATABASE=WinTV PVR 150
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (WinTV PVR 150)
 
 pci:v00004444d00000016sv00000070sd00008801*
- ID_MODEL_FROM_DATABASE=WinTV PVR 150
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (WinTV PVR 150)
 
 pci:v00004444d00000016sv00000070sd0000C801*
- ID_MODEL_FROM_DATABASE=WinTV PVR 150
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (WinTV PVR 150)
 
 pci:v00004444d00000016sv00000070sd0000E807*
- ID_MODEL_FROM_DATABASE=WinTV PVR 500 (1st unit)
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (WinTV PVR 500 (1st unit))
 
 pci:v00004444d00000016sv00000070sd0000E817*
- ID_MODEL_FROM_DATABASE=WinTV PVR 500 (2nd unit)
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (WinTV PVR 500 (2nd unit))
 
 pci:v00004444d00000016sv00000070sd0000FF92*
- ID_MODEL_FROM_DATABASE=WiNTV PVR-550
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (WiNTV PVR-550)
 
 pci:v00004444d00000016sv00000270sd00000801*
- ID_MODEL_FROM_DATABASE=WinTV PVR 150
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (WinTV PVR 150)
 
 pci:v00004444d00000016sv0000104Dsd0000013D*
- ID_MODEL_FROM_DATABASE=ENX-26 TV Encoder
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (ENX-26 TV Encoder)
 
 pci:v00004444d00000016sv000010FCsd0000D038*
- ID_MODEL_FROM_DATABASE=GV-MVP/RX2W (1st unit)
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (GV-MVP/RX2W (1st unit))
 
 pci:v00004444d00000016sv000010FCsd0000D039*
- ID_MODEL_FROM_DATABASE=GV-MVP/RX2W (2nd unit)
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (GV-MVP/RX2W (2nd unit))
 
 pci:v00004444d00000016sv000012ABsd0000FFF3*
- ID_MODEL_FROM_DATABASE=MPG600
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (MPG600)
 
 pci:v00004444d00000016sv000012ABsd0000FFFF*
- ID_MODEL_FROM_DATABASE=MPG600
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (MPG600)
 
 pci:v00004444d00000016sv00001461sd0000C00A*
- ID_MODEL_FROM_DATABASE=M113 PCI Analog TV (PAL/SECAM, Philips FQ1216MK3 tuner)
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (M113 PCI Analog TV (PAL/SECAM, Philips FQ1216MK3 tuner))
 
 pci:v00004444d00000016sv00001461sd0000C00B*
- ID_MODEL_FROM_DATABASE=M113 PCI Analog TV (PAL/SECAM+FM, Philips FM1216MK3 tuner)
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (M113 PCI Analog TV (PAL/SECAM+FM, Philips FM1216MK3 tuner))
 
 pci:v00004444d00000016sv00001461sd0000C00C*
- ID_MODEL_FROM_DATABASE=M113 PCI Analog TV (NTSC, JAPAN version, Philips FI1286MK2 tuner)
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (M113 PCI Analog TV (NTSC, JAPAN version, Philips FI1286MK2 tuner))
 
 pci:v00004444d00000016sv00001461sd0000C010*
- ID_MODEL_FROM_DATABASE=M113 PCI Analog TV (NTSC, Philips FI1236MK3 tuner)
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (M113 PCI Analog TV (NTSC, Philips FI1236MK3 tuner))
 
 pci:v00004444d00000016sv00001461sd0000C011*
- ID_MODEL_FROM_DATABASE=M113 PCI Analog TV (NTSC+FM, Philips FM1236MK3 tuner)
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (M113 PCI Analog TV (NTSC+FM, Philips FM1236MK3 tuner))
 
 pci:v00004444d00000016sv00001461sd0000C018*
- ID_MODEL_FROM_DATABASE=M113 PCI Analog TV (NTSC, Philips FQ1236MK5 tuner)
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (M113 PCI Analog TV (NTSC, Philips FQ1236MK5 tuner))
 
 pci:v00004444d00000016sv00001461sd0000C019*
- ID_MODEL_FROM_DATABASE=UltraTV 1500 MCE, a.k.a. M113 PCI Analog TV (NTSC+FM, Philips FQ1236MK5 tuner)
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (UltraTV 1500 MCE, a.k.a. M113 PCI Analog TV (NTSC+FM, Philips FQ1236MK5 tuner))
 
 pci:v00004444d00000016sv00001461sd0000C01A*
- ID_MODEL_FROM_DATABASE=M113 PCI Analog TV (PAL/SECAM, Philips FQ1216MK5 tuner)
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (M113 PCI Analog TV (PAL/SECAM, Philips FQ1216MK5 tuner))
 
 pci:v00004444d00000016sv00001461sd0000C01B*
- ID_MODEL_FROM_DATABASE=M113 PCI Analog TV (PAL/SECAM+FM, Philips FM1216MK5 tuner)
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (M113 PCI Analog TV (PAL/SECAM+FM, Philips FM1216MK5 tuner))
 
 pci:v00004444d00000016sv00001461sd0000C030*
- ID_MODEL_FROM_DATABASE=M113 PCI Analog TV (NTSC-J, Partsnic tuner)
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (M113 PCI Analog TV (NTSC-J, Partsnic tuner))
 
 pci:v00004444d00000016sv00001461sd0000C031*
- ID_MODEL_FROM_DATABASE=M113 PCI Analog TV (NTSC-J+FM, Partsnic tuner)
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (M113 PCI Analog TV (NTSC-J+FM, Partsnic tuner))
 
 pci:v00004444d00000016sv00001461sd0000C032*
- ID_MODEL_FROM_DATABASE=M113 PCI Analog TV (PAL/SECAM, Partsnic tuner)
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (M113 PCI Analog TV (PAL/SECAM, Partsnic tuner))
 
 pci:v00004444d00000016sv00001461sd0000C033*
- ID_MODEL_FROM_DATABASE=M113 PCI Analog TV (PAL/SECAM+FM, Partsnic tuner)
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (M113 PCI Analog TV (PAL/SECAM+FM, Partsnic tuner))
 
 pci:v00004444d00000016sv00001461sd0000C034*
- ID_MODEL_FROM_DATABASE=M113 PCI Analog TV (NTSC, Partsnic tuner)
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (M113 PCI Analog TV (NTSC, Partsnic tuner))
 
 pci:v00004444d00000016sv00001461sd0000C035*
- ID_MODEL_FROM_DATABASE=M113 PCI Analog TV (NTSC+FM, Partsnic tuner)
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (M113 PCI Analog TV (NTSC+FM, Partsnic tuner))
 
 pci:v00004444d00000016sv00001461sd0000C03F*
- ID_MODEL_FROM_DATABASE=C115 PCI video capture card (no tuner)
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (C115 PCI video capture card (no tuner))
 
 pci:v00004444d00000016sv00001461sd0000C136*
- ID_MODEL_FROM_DATABASE=M104 mini-PCI Analog TV
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (M104 mini-PCI Analog TV)
 
 pci:v00004444d00000016sv00001461sd0000C20A*
- ID_MODEL_FROM_DATABASE=M755 AVerTV Video Capture (PAL/SECAM, Philips FQ1216MK3 tuner)
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (M755 AVerTV Video Capture (PAL/SECAM, Philips FQ1216MK3 tuner))
 
 pci:v00004444d00000016sv00001461sd0000C218*
- ID_MODEL_FROM_DATABASE=M755 AVerTV Video Capture (NTSC, Philips FQ1236MK5 tuner)
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (M755 AVerTV Video Capture (NTSC, Philips FQ1236MK5 tuner))
 
 pci:v00004444d00000016sv00001461sd0000C219*
- ID_MODEL_FROM_DATABASE=M755 AVerTV Video Capture (NTSC+FM, Philips FQ1236MK5 tuner)
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (M755 AVerTV Video Capture (NTSC+FM, Philips FQ1236MK5 tuner))
 
 pci:v00004444d00000016sv00001461sd0000C21A*
- ID_MODEL_FROM_DATABASE=M755 AVerTV Video Capture (PAL/SECAM, Philips FQ1216MK5 tuner)
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (M755 AVerTV Video Capture (PAL/SECAM, Philips FQ1216MK5 tuner))
 
 pci:v00004444d00000016sv00001461sd0000C21B*
- ID_MODEL_FROM_DATABASE=M755 AVerTV Video Capture (PAL/SECAM+FM, Philips FM1216MK5 tuner)
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (M755 AVerTV Video Capture (PAL/SECAM+FM, Philips FM1216MK5 tuner))
 
 pci:v00004444d00000016sv00001461sd0000C230*
- ID_MODEL_FROM_DATABASE=M755 AVerTV Video Capture (NTSC-J, Partsnic tuner)
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (M755 AVerTV Video Capture (NTSC-J, Partsnic tuner))
 
 pci:v00004444d00000016sv00001461sd0000C231*
- ID_MODEL_FROM_DATABASE=M755 AVerTV Video Capture (NTSC-J+FM, Partsnic tuner)
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (M755 AVerTV Video Capture (NTSC-J+FM, Partsnic tuner))
 
 pci:v00004444d00000016sv00001461sd0000C232*
- ID_MODEL_FROM_DATABASE=M755 AVerTV Video Capture (PAL/SECAM, Partsnic tuner)
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (M755 AVerTV Video Capture (PAL/SECAM, Partsnic tuner))
 
 pci:v00004444d00000016sv00001461sd0000C233*
- ID_MODEL_FROM_DATABASE=M755 AVerTV Video Capture (PAL/SECAM+FM, Partsnic tuner)
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (M755 AVerTV Video Capture (PAL/SECAM+FM, Partsnic tuner))
 
 pci:v00004444d00000016sv00001461sd0000C234*
- ID_MODEL_FROM_DATABASE=M755 AVerTV Video Capture (NTSC, Partsnic tuner)
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (M755 AVerTV Video Capture (NTSC, Partsnic tuner))
 
 pci:v00004444d00000016sv00001461sd0000C235*
- ID_MODEL_FROM_DATABASE=M755 AVerTV Video Capture (NTSC+FM, Partsnic tuner)
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (M755 AVerTV Video Capture (NTSC+FM, Partsnic tuner))
 
 pci:v00004444d00000016sv00001461sd0000C337*
- ID_MODEL_FROM_DATABASE=E106 AVerMedia AVerTV Video Capture
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (E106 AVerMedia AVerTV Video Capture)
 
 pci:v00004444d00000016sv00001461sd0000C439*
- ID_MODEL_FROM_DATABASE=M116 AVerMedia AVerTV MCE 116 Plus (NTSC/PAL/SECAM+FM+REMOTE, Xceive 2028 tuner)
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (M116 AVerMedia AVerTV MCE 116 Plus (NTSC/PAL/SECAM+FM+REMOTE, Xceive 2028 tuner))
 
 pci:v00004444d00000016sv00001461sd0000C5FF*
- ID_MODEL_FROM_DATABASE=C755 AVerTV Video Capture card (no tuner)
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (C755 AVerTV Video Capture card (no tuner))
 
 pci:v00004444d00000016sv00001461sd0000C6FF*
- ID_MODEL_FROM_DATABASE=C115 PCI video capture card (no tuner)
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (C115 PCI video capture card (no tuner))
 
 pci:v00004444d00000016sv00001461sd0000C739*
- ID_MODEL_FROM_DATABASE=M785 AVerMedia PCI Analog TV (NTSC/PAL/SECAM+FM, Xceive 2028 tuner)
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (M785 AVerMedia PCI Analog TV (NTSC/PAL/SECAM+FM, Xceive 2028 tuner))
 
 pci:v00004444d00000016sv00009005sd00000092*
- ID_MODEL_FROM_DATABASE=VideOh! AVC-2010
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (VideOh! AVC-2010)
 
 pci:v00004444d00000016sv00009005sd00000093*
- ID_MODEL_FROM_DATABASE=VideOh! AVC-2410
+ ID_MODEL_FROM_DATABASE=iTVC16 (CX23416) Video Decoder (VideOh! AVC-2410)
 
 pci:v00004444d00000803*
  ID_MODEL_FROM_DATABASE=iTVC15 (CX23415) Video Decoder
 
 pci:v00004444d00000803sv00000070sd00004000*
- ID_MODEL_FROM_DATABASE=WinTV PVR-350
+ ID_MODEL_FROM_DATABASE=iTVC15 (CX23415) Video Decoder (WinTV PVR-350)
 
 pci:v00004444d00000803sv00000070sd00004001*
- ID_MODEL_FROM_DATABASE=WinTV PVR-250
+ ID_MODEL_FROM_DATABASE=iTVC15 (CX23415) Video Decoder (WinTV PVR-250)
 
 pci:v00004444d00000803sv00000070sd00004800*
- ID_MODEL_FROM_DATABASE=WinTV PVR-350 (V1)
+ ID_MODEL_FROM_DATABASE=iTVC15 (CX23415) Video Decoder (WinTV PVR-350 (V1))
 
 pci:v00004444d00000803sv000012ABsd00000000*
- ID_MODEL_FROM_DATABASE=MPG160
+ ID_MODEL_FROM_DATABASE=iTVC15 (CX23415) Video Decoder (MPG160)
 
 pci:v00004444d00000803sv00001461sd0000A3CE*
- ID_MODEL_FROM_DATABASE=M179
+ ID_MODEL_FROM_DATABASE=iTVC15 (CX23415) Video Decoder (M179)
 
 pci:v00004444d00000803sv00001461sd0000A3CF*
- ID_MODEL_FROM_DATABASE=M179
+ ID_MODEL_FROM_DATABASE=iTVC15 (CX23415) Video Decoder (M179)
 
 pci:v00004468*
  ID_VENDOR_FROM_DATABASE=Bridgeport machines
@@ -52959,7 +54420,7 @@ pci:v00004A14d00005000*
  ID_MODEL_FROM_DATABASE=NV5000SC
 
 pci:v00004A14d00005000sv00004A14sd00005000*
- ID_MODEL_FROM_DATABASE=RT8029-Based Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=NV5000SC (RT8029-Based Ethernet Adapter)
 
 pci:v00004B10*
  ID_VENDOR_FROM_DATABASE=Buslogic Inc.
@@ -52974,16 +54435,16 @@ pci:v00004C53d00000000*
  ID_MODEL_FROM_DATABASE=PLUSTEST device
 
 pci:v00004C53d00000000sv00004C53sd00003000*
- ID_MODEL_FROM_DATABASE=PLUSTEST card (PC104+)
+ ID_MODEL_FROM_DATABASE=PLUSTEST device (PLUSTEST card (PC104+))
 
 pci:v00004C53d00000000sv00004C53sd00003001*
- ID_MODEL_FROM_DATABASE=PLUSTEST card (PMC)
+ ID_MODEL_FROM_DATABASE=PLUSTEST device (PLUSTEST card (PMC))
 
 pci:v00004C53d00000001*
  ID_MODEL_FROM_DATABASE=PLUSTEST-MM device
 
 pci:v00004C53d00000001sv00004C53sd00003002*
- ID_MODEL_FROM_DATABASE=PLUSTEST-MM card (PMC)
+ ID_MODEL_FROM_DATABASE=PLUSTEST-MM device (PLUSTEST-MM card (PMC))
 
 pci:v00004CA1*
  ID_VENDOR_FROM_DATABASE=Seanix Technology Inc
@@ -53220,13 +54681,13 @@ pci:v00005333d00008900*
  ID_MODEL_FROM_DATABASE=86c755 [Trio 64V2/DX]
 
 pci:v00005333d00008900sv00005333sd00008900*
- ID_MODEL_FROM_DATABASE=86C775 Trio64V2/DX
+ ID_MODEL_FROM_DATABASE=86c755 [Trio 64V2/DX] (86C775 Trio64V2/DX)
 
 pci:v00005333d00008901*
  ID_MODEL_FROM_DATABASE=86c775/86c785 [Trio 64V2/DX or /GX]
 
 pci:v00005333d00008901sv00005333sd00008901*
- ID_MODEL_FROM_DATABASE=86C775 Trio64V2/DX, 86C785 Trio64V2/GX
+ ID_MODEL_FROM_DATABASE=86c775/86c785 [Trio 64V2/DX or /GX] (86C775 Trio64V2/DX, 86C785 Trio64V2/GX)
 
 pci:v00005333d00008902*
  ID_MODEL_FROM_DATABASE=Plato/PX
@@ -53238,13 +54699,13 @@ pci:v00005333d00008904*
  ID_MODEL_FROM_DATABASE=86c365, 86c366 [Trio 3D]
 
 pci:v00005333d00008904sv00001014sd000000DB*
- ID_MODEL_FROM_DATABASE=Integrated Trio3D
+ ID_MODEL_FROM_DATABASE=86c365, 86c366 [Trio 3D] (Integrated Trio3D)
 
 pci:v00005333d00008904sv00004843sd0000314A*
- ID_MODEL_FROM_DATABASE=Terminator 128/3D GLH
+ ID_MODEL_FROM_DATABASE=86c365, 86c366 [Trio 3D] (Terminator 128/3D GLH)
 
 pci:v00005333d00008904sv00005333sd00008904*
- ID_MODEL_FROM_DATABASE=86C365 Trio3D AGP
+ ID_MODEL_FROM_DATABASE=86c365, 86c366 [Trio 3D] (86C365 Trio3D AGP)
 
 pci:v00005333d00008905*
  ID_MODEL_FROM_DATABASE=Trio 64V+ family
@@ -53283,40 +54744,40 @@ pci:v00005333d00008A01*
  ID_MODEL_FROM_DATABASE=86c375 [ViRGE/DX] or 86c385 [ViRGE/GX]
 
 pci:v00005333d00008A01sv00000E11sd0000B032*
- ID_MODEL_FROM_DATABASE=ViRGE/GX
+ ID_MODEL_FROM_DATABASE=86c375 [ViRGE/DX] or 86c385 [ViRGE/GX] (ViRGE/GX)
 
 pci:v00005333d00008A01sv000010B4sd00001617*
- ID_MODEL_FROM_DATABASE=Nitro 3D
+ ID_MODEL_FROM_DATABASE=86c375 [ViRGE/DX] or 86c385 [ViRGE/GX] (Nitro 3D)
 
 pci:v00005333d00008A01sv000010B4sd00001717*
- ID_MODEL_FROM_DATABASE=Nitro 3D
+ ID_MODEL_FROM_DATABASE=86c375 [ViRGE/DX] or 86c385 [ViRGE/GX] (Nitro 3D)
 
 pci:v00005333d00008A01sv00005333sd00008A01*
- ID_MODEL_FROM_DATABASE=ViRGE/DX
+ ID_MODEL_FROM_DATABASE=86c375 [ViRGE/DX] or 86c385 [ViRGE/GX] (ViRGE/DX)
 
 pci:v00005333d00008A10*
  ID_MODEL_FROM_DATABASE=ViRGE/GX2
 
 pci:v00005333d00008A10sv00001092sd00008A10*
- ID_MODEL_FROM_DATABASE=Stealth 3D 4000
+ ID_MODEL_FROM_DATABASE=ViRGE/GX2 (Stealth 3D 4000)
 
 pci:v00005333d00008A13*
  ID_MODEL_FROM_DATABASE=86c360 [Trio 3D/1X], 86c362, 86c368 [Trio 3D/2X]
 
 pci:v00005333d00008A13sv00005333sd00008A13*
- ID_MODEL_FROM_DATABASE=Trio3D/2X
+ ID_MODEL_FROM_DATABASE=86c360 [Trio 3D/1X], 86c362, 86c368 [Trio 3D/2X] (Trio3D/2X)
 
 pci:v00005333d00008A20*
  ID_MODEL_FROM_DATABASE=86c794 [Savage 3D]
 
 pci:v00005333d00008A20sv00005333sd00008A20*
- ID_MODEL_FROM_DATABASE=86C391 Savage3D
+ ID_MODEL_FROM_DATABASE=86c794 [Savage 3D] (86C391 Savage3D)
 
 pci:v00005333d00008A21*
  ID_MODEL_FROM_DATABASE=86c390 [Savage 3D/MV]
 
 pci:v00005333d00008A21sv00005333sd00008A21*
- ID_MODEL_FROM_DATABASE=86C390 Savage3D/MV
+ ID_MODEL_FROM_DATABASE=86c390 [Savage 3D/MV] (86C390 Savage3D/MV)
 
 pci:v00005333d00008A22*
  ID_MODEL_FROM_DATABASE=Savage 4
@@ -53328,85 +54789,85 @@ pci:v00005333d00008A22sv00001033sd00008069*
  ID_MODEL_FROM_DATABASE=Savage 4
 
 pci:v00005333d00008A22sv00001033sd00008110*
- ID_MODEL_FROM_DATABASE=Savage 4 LT
+ ID_MODEL_FROM_DATABASE=Savage 4 (LT)
 
 pci:v00005333d00008A22sv0000105Dsd00000018*
- ID_MODEL_FROM_DATABASE=SR9 8Mb SDRAM
+ ID_MODEL_FROM_DATABASE=Savage 4 (SR9 8Mb SDRAM)
 
 pci:v00005333d00008A22sv0000105Dsd0000002A*
- ID_MODEL_FROM_DATABASE=SR9 Pro 16Mb SDRAM
+ ID_MODEL_FROM_DATABASE=Savage 4 (SR9 Pro 16Mb SDRAM)
 
 pci:v00005333d00008A22sv0000105Dsd0000003A*
- ID_MODEL_FROM_DATABASE=SR9 Pro 32Mb SDRAM
+ ID_MODEL_FROM_DATABASE=Savage 4 (SR9 Pro 32Mb SDRAM)
 
 pci:v00005333d00008A22sv0000105Dsd0000092F*
- ID_MODEL_FROM_DATABASE=SR9 Pro+ 16Mb SGRAM
+ ID_MODEL_FROM_DATABASE=Savage 4 (SR9 Pro+ 16Mb SGRAM)
 
 pci:v00005333d00008A22sv00001092sd00004207*
- ID_MODEL_FROM_DATABASE=Stealth III S540
+ ID_MODEL_FROM_DATABASE=Savage 4 (Stealth III S540)
 
 pci:v00005333d00008A22sv00001092sd00004800*
- ID_MODEL_FROM_DATABASE=Stealth III S540
+ ID_MODEL_FROM_DATABASE=Savage 4 (Stealth III S540)
 
 pci:v00005333d00008A22sv00001092sd00004807*
- ID_MODEL_FROM_DATABASE=SpeedStar A90
+ ID_MODEL_FROM_DATABASE=Savage 4 (SpeedStar A90)
 
 pci:v00005333d00008A22sv00001092sd00004808*
- ID_MODEL_FROM_DATABASE=Stealth III S540
+ ID_MODEL_FROM_DATABASE=Savage 4 (Stealth III S540)
 
 pci:v00005333d00008A22sv00001092sd00004809*
- ID_MODEL_FROM_DATABASE=Stealth III S540
+ ID_MODEL_FROM_DATABASE=Savage 4 (Stealth III S540)
 
 pci:v00005333d00008A22sv00001092sd0000480E*
- ID_MODEL_FROM_DATABASE=Stealth III S540
+ ID_MODEL_FROM_DATABASE=Savage 4 (Stealth III S540)
 
 pci:v00005333d00008A22sv00001092sd00004904*
- ID_MODEL_FROM_DATABASE=Stealth III S520
+ ID_MODEL_FROM_DATABASE=Savage 4 (Stealth III S520)
 
 pci:v00005333d00008A22sv00001092sd00004905*
- ID_MODEL_FROM_DATABASE=SpeedStar A200
+ ID_MODEL_FROM_DATABASE=Savage 4 (SpeedStar A200)
 
 pci:v00005333d00008A22sv00001092sd00004A09*
- ID_MODEL_FROM_DATABASE=Stealth III S540
+ ID_MODEL_FROM_DATABASE=Savage 4 (Stealth III S540)
 
 pci:v00005333d00008A22sv00001092sd00004A0B*
- ID_MODEL_FROM_DATABASE=Stealth III S540 Xtreme
+ ID_MODEL_FROM_DATABASE=Savage 4 (Stealth III S540 Xtreme)
 
 pci:v00005333d00008A22sv00001092sd00004A0F*
- ID_MODEL_FROM_DATABASE=Stealth III S540
+ ID_MODEL_FROM_DATABASE=Savage 4 (Stealth III S540)
 
 pci:v00005333d00008A22sv00001092sd00004E01*
- ID_MODEL_FROM_DATABASE=Stealth III S540
+ ID_MODEL_FROM_DATABASE=Savage 4 (Stealth III S540)
 
 pci:v00005333d00008A22sv00001102sd0000101D*
- ID_MODEL_FROM_DATABASE=3d Blaster Savage 4
+ ID_MODEL_FROM_DATABASE=Savage 4 (3d Blaster Savage 4)
 
 pci:v00005333d00008A22sv00001102sd0000101E*
- ID_MODEL_FROM_DATABASE=3d Blaster Savage 4
+ ID_MODEL_FROM_DATABASE=Savage 4 (3d Blaster Savage 4)
 
 pci:v00005333d00008A22sv00005333sd00008100*
- ID_MODEL_FROM_DATABASE=86C394-397 Savage4 SDRAM 100
+ ID_MODEL_FROM_DATABASE=Savage 4 (86C394-397 Savage4 SDRAM 100)
 
 pci:v00005333d00008A22sv00005333sd00008110*
- ID_MODEL_FROM_DATABASE=86C394-397 Savage4 SDRAM 110
+ ID_MODEL_FROM_DATABASE=Savage 4 (86C394-397 Savage4 SDRAM 110)
 
 pci:v00005333d00008A22sv00005333sd00008125*
- ID_MODEL_FROM_DATABASE=86C394-397 Savage4 SDRAM 125
+ ID_MODEL_FROM_DATABASE=Savage 4 (86C394-397 Savage4 SDRAM 125)
 
 pci:v00005333d00008A22sv00005333sd00008143*
- ID_MODEL_FROM_DATABASE=86C394-397 Savage4 SDRAM 143
+ ID_MODEL_FROM_DATABASE=Savage 4 (86C394-397 Savage4 SDRAM 143)
 
 pci:v00005333d00008A22sv00005333sd00008A22*
- ID_MODEL_FROM_DATABASE=86C394-397 Savage4
+ ID_MODEL_FROM_DATABASE=Savage 4 (86C394-397 Savage4)
 
 pci:v00005333d00008A22sv00005333sd00008A2E*
- ID_MODEL_FROM_DATABASE=86C394-397 Savage4 32bit
+ ID_MODEL_FROM_DATABASE=Savage 4 (86C394-397 Savage4 32bit)
 
 pci:v00005333d00008A22sv00005333sd00009125*
- ID_MODEL_FROM_DATABASE=86C394-397 Savage4 SGRAM 125
+ ID_MODEL_FROM_DATABASE=Savage 4 (86C394-397 Savage4 SGRAM 125)
 
 pci:v00005333d00008A22sv00005333sd00009143*
- ID_MODEL_FROM_DATABASE=86C394-397 Savage4 SGRAM 143
+ ID_MODEL_FROM_DATABASE=Savage 4 (86C394-397 Savage4 SGRAM 143)
 
 pci:v00005333d00008A23*
  ID_MODEL_FROM_DATABASE=Savage 4
@@ -53415,7 +54876,7 @@ pci:v00005333d00008A25*
  ID_MODEL_FROM_DATABASE=ProSavage PM133
 
 pci:v00005333d00008A25sv00000303sd00000303*
- ID_MODEL_FROM_DATABASE=D9840-60001 [Brio BA410 Motherboard]
+ ID_MODEL_FROM_DATABASE=ProSavage PM133 (D9840-60001 [Brio BA410 Motherboard])
 
 pci:v00005333d00008A26*
  ID_MODEL_FROM_DATABASE=ProSavage KM133
@@ -53445,16 +54906,16 @@ pci:v00005333d00008C12*
  ID_MODEL_FROM_DATABASE=86C270-294 [SavageIX-MV]
 
 pci:v00005333d00008C12sv00001014sd0000017F*
- ID_MODEL_FROM_DATABASE=ThinkPad T20/T22
+ ID_MODEL_FROM_DATABASE=86C270-294 [SavageIX-MV] (ThinkPad T20/T22)
 
 pci:v00005333d00008C12sv00001179sd00000001*
- ID_MODEL_FROM_DATABASE=86C584 SuperSavage/IXC Toshiba
+ ID_MODEL_FROM_DATABASE=86C270-294 [SavageIX-MV] (86C584 SuperSavage/IXC Toshiba)
 
 pci:v00005333d00008C13*
  ID_MODEL_FROM_DATABASE=86C270-294 [SavageIX]
 
 pci:v00005333d00008C13sv00001179sd00000001*
- ID_MODEL_FROM_DATABASE=Magnia Z310
+ ID_MODEL_FROM_DATABASE=86C270-294 [SavageIX] (Magnia Z310)
 
 pci:v00005333d00008C22*
  ID_MODEL_FROM_DATABASE=SuperSavage MX/128
@@ -53481,7 +54942,7 @@ pci:v00005333d00008C2E*
  ID_MODEL_FROM_DATABASE=SuperSavage IX/C SDR
 
 pci:v00005333d00008C2Esv00001014sd000001FC*
- ID_MODEL_FROM_DATABASE=ThinkPad T23
+ ID_MODEL_FROM_DATABASE=SuperSavage IX/C SDR (ThinkPad T23)
 
 pci:v00005333d00008C2F*
  ID_MODEL_FROM_DATABASE=SuperSavage IX/C DDR
@@ -53511,7 +54972,7 @@ pci:v00005333d00008E48*
  ID_MODEL_FROM_DATABASE=Matrix [Chrome S25 / S27]
 
 pci:v00005333d00008E48sv00005333sd00000130*
- ID_MODEL_FROM_DATABASE=Chrome S27 256M DDR2
+ ID_MODEL_FROM_DATABASE=Matrix [Chrome S25 / S27] (Chrome S27 256M DDR2)
 
 pci:v00005333d00009043*
  ID_MODEL_FROM_DATABASE=Chrome 430 GT
@@ -53526,28 +54987,28 @@ pci:v00005333d00009102*
  ID_MODEL_FROM_DATABASE=86C410 [Savage 2000]
 
 pci:v00005333d00009102sv00001092sd00005932*
- ID_MODEL_FROM_DATABASE=Viper II Z200
+ ID_MODEL_FROM_DATABASE=86C410 [Savage 2000] (Viper II Z200)
 
 pci:v00005333d00009102sv00001092sd00005934*
- ID_MODEL_FROM_DATABASE=Viper II Z200
+ ID_MODEL_FROM_DATABASE=86C410 [Savage 2000] (Viper II Z200)
 
 pci:v00005333d00009102sv00001092sd00005952*
- ID_MODEL_FROM_DATABASE=Viper II Z200
+ ID_MODEL_FROM_DATABASE=86C410 [Savage 2000] (Viper II Z200)
 
 pci:v00005333d00009102sv00001092sd00005954*
- ID_MODEL_FROM_DATABASE=Viper II Z200
+ ID_MODEL_FROM_DATABASE=86C410 [Savage 2000] (Viper II Z200)
 
 pci:v00005333d00009102sv00001092sd00005A35*
- ID_MODEL_FROM_DATABASE=Viper II Z200
+ ID_MODEL_FROM_DATABASE=86C410 [Savage 2000] (Viper II Z200)
 
 pci:v00005333d00009102sv00001092sd00005A37*
- ID_MODEL_FROM_DATABASE=Viper II Z200
+ ID_MODEL_FROM_DATABASE=86C410 [Savage 2000] (Viper II Z200)
 
 pci:v00005333d00009102sv00001092sd00005A55*
- ID_MODEL_FROM_DATABASE=Viper II Z200
+ ID_MODEL_FROM_DATABASE=86C410 [Savage 2000] (Viper II Z200)
 
 pci:v00005333d00009102sv00001092sd00005A57*
- ID_MODEL_FROM_DATABASE=Viper II Z200
+ ID_MODEL_FROM_DATABASE=86C410 [Savage 2000] (Viper II Z200)
 
 pci:v00005333d0000CA00*
  ID_MODEL_FROM_DATABASE=SonicVibes
@@ -53691,7 +55152,7 @@ pci:v00006688*
  ID_VENDOR_FROM_DATABASE=Zycoo Co., Ltd
 
 pci:v00006688d00001200*
- ID_MODEL_FROM_DATABASE=CooVOX TDM Analog Module
+ ID_MODEL_FROM_DATABASE=CooVox TDM Analog Module
 
 pci:v00006688d00001400*
  ID_MODEL_FROM_DATABASE=CooVOX TDM GSM Module
@@ -53772,22 +55233,37 @@ pci:v00008086d00000044*
  ID_MODEL_FROM_DATABASE=Core Processor DRAM Controller
 
 pci:v00008086d00000044sv00001025sd00000347*
- ID_MODEL_FROM_DATABASE=Aspire 7740G
+ ID_MODEL_FROM_DATABASE=Core Processor DRAM Controller (Aspire 7740G)
 
 pci:v00008086d00000044sv00001025sd00000487*
- ID_MODEL_FROM_DATABASE=TravelMate 5742
+ ID_MODEL_FROM_DATABASE=Core Processor DRAM Controller (TravelMate 5742)
+
+pci:v00008086d00000044sv0000144Dsd0000C06A*
+ ID_MODEL_FROM_DATABASE=Core Processor DRAM Controller (R730 Laptop)
+
+pci:v00008086d00000044sv000017C0sd000010D2*
+ ID_MODEL_FROM_DATABASE=Core Processor DRAM Controller (Medion Akoya E7214 Notebook PC [MD98410])
 
 pci:v00008086d00000044sv0000E4BFsd000050C1*
- ID_MODEL_FROM_DATABASE=PC1-GROOVE
+ ID_MODEL_FROM_DATABASE=Core Processor DRAM Controller (PC1-GROOVE)
 
 pci:v00008086d00000045*
  ID_MODEL_FROM_DATABASE=Core Processor PCI Express x16 Root Port
 
+pci:v00008086d00000045sv000017C0sd000010D2*
+ ID_MODEL_FROM_DATABASE=Core Processor PCI Express x16 Root Port (Medion Akoya E7214 Notebook PC [MD98410])
+
 pci:v00008086d00000046*
  ID_MODEL_FROM_DATABASE=Core Processor Integrated Graphics Controller
 
+pci:v00008086d00000046sv0000144Dsd0000C06A*
+ ID_MODEL_FROM_DATABASE=Core Processor Integrated Graphics Controller (R730 Laptop)
+
+pci:v00008086d00000046sv000017C0sd000010D9*
+ ID_MODEL_FROM_DATABASE=Core Processor Integrated Graphics Controller (Medion Akoya E7214 Notebook PC [MD98410])
+
 pci:v00008086d00000046sv0000E4BFsd000050C1*
- ID_MODEL_FROM_DATABASE=PC1-GROOVE
+ ID_MODEL_FROM_DATABASE=Core Processor Integrated Graphics Controller (PC1-GROOVE)
 
 pci:v00008086d00000047*
  ID_MODEL_FROM_DATABASE=Core Processor Secondary PCI Express Root Port
@@ -53814,199 +55290,202 @@ pci:v00008086d00000082*
  ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6205 [Taylor Peak]
 
 pci:v00008086d00000082sv00008086sd00001301*
- ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6205 AGN
+ ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6205 [Taylor Peak] (Centrino Advanced-N 6205 AGN)
 
 pci:v00008086d00000082sv00008086sd00001306*
- ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6205 ABG
+ ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6205 [Taylor Peak] (Centrino Advanced-N 6205 ABG)
 
 pci:v00008086d00000082sv00008086sd00001307*
- ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6205 BG
+ ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6205 [Taylor Peak] (Centrino Advanced-N 6205 BG)
 
 pci:v00008086d00000082sv00008086sd00001321*
- ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6205 AGN
+ ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6205 [Taylor Peak] (Centrino Advanced-N 6205 AGN)
 
 pci:v00008086d00000082sv00008086sd00001326*
- ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6205 ABG
+ ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6205 [Taylor Peak] (Centrino Advanced-N 6205 ABG)
 
 pci:v00008086d00000083*
  ID_MODEL_FROM_DATABASE=Centrino Wireless-N 1000 [Condor Peak]
 
 pci:v00008086d00000083sv00008086sd00001205*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N 1000 BGN
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N 1000 [Condor Peak] (Centrino Wireless-N 1000 BGN)
 
 pci:v00008086d00000083sv00008086sd00001206*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N 1000 BG
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N 1000 [Condor Peak] (Centrino Wireless-N 1000 BG)
 
 pci:v00008086d00000083sv00008086sd00001225*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N 1000 BGN
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N 1000 [Condor Peak] (Centrino Wireless-N 1000 BGN)
 
 pci:v00008086d00000083sv00008086sd00001226*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N 1000 BG
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N 1000 [Condor Peak] (Centrino Wireless-N 1000 BG)
 
 pci:v00008086d00000083sv00008086sd00001305*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N 1000 BGN
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N 1000 [Condor Peak] (Centrino Wireless-N 1000 BGN)
 
 pci:v00008086d00000083sv00008086sd00001306*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N 1000 BG
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N 1000 [Condor Peak] (Centrino Wireless-N 1000 BG)
 
 pci:v00008086d00000083sv00008086sd00001325*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N 1000 BGN
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N 1000 [Condor Peak] (Centrino Wireless-N 1000 BGN)
 
 pci:v00008086d00000083sv00008086sd00001326*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N 1000 BG
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N 1000 [Condor Peak] (Centrino Wireless-N 1000 BG)
 
 pci:v00008086d00000084*
  ID_MODEL_FROM_DATABASE=Centrino Wireless-N 1000 [Condor Peak]
 
 pci:v00008086d00000084sv00008086sd00001215*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N 1000 BGN
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N 1000 [Condor Peak] (Centrino Wireless-N 1000 BGN)
 
 pci:v00008086d00000084sv00008086sd00001216*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N 1000 BG
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N 1000 [Condor Peak] (Centrino Wireless-N 1000 BG)
 
 pci:v00008086d00000084sv00008086sd00001315*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N 1000 BGN
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N 1000 [Condor Peak] (Centrino Wireless-N 1000 BGN)
 
 pci:v00008086d00000084sv00008086sd00001316*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N 1000 BG
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N 1000 [Condor Peak] (Centrino Wireless-N 1000 BG)
 
 pci:v00008086d00000085*
  ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6205 [Taylor Peak]
 
 pci:v00008086d00000085sv00008086sd00001311*
- ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6205 AGN
+ ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6205 [Taylor Peak] (Centrino Advanced-N 6205 AGN)
 
 pci:v00008086d00000085sv00008086sd00001316*
- ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6205 ABG
+ ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6205 [Taylor Peak] (Centrino Advanced-N 6205 ABG)
 
 pci:v00008086d00000087*
  ID_MODEL_FROM_DATABASE=Centrino Advanced-N + WiMAX 6250 [Kilmer Peak]
 
 pci:v00008086d00000087sv00008086sd00001301*
- ID_MODEL_FROM_DATABASE=Centrino Advanced-N + WiMAX 6250 2x2 AGN
+ ID_MODEL_FROM_DATABASE=Centrino Advanced-N + WiMAX 6250 [Kilmer Peak] (Centrino Advanced-N + WiMAX 6250 2x2 AGN)
 
 pci:v00008086d00000087sv00008086sd00001306*
- ID_MODEL_FROM_DATABASE=Centrino Advanced-N + WiMAX 6250 2x2 ABG
+ ID_MODEL_FROM_DATABASE=Centrino Advanced-N + WiMAX 6250 [Kilmer Peak] (Centrino Advanced-N + WiMAX 6250 2x2 ABG)
 
 pci:v00008086d00000087sv00008086sd00001321*
- ID_MODEL_FROM_DATABASE=Centrino Advanced-N + WiMAX 6250 2x2 AGN
+ ID_MODEL_FROM_DATABASE=Centrino Advanced-N + WiMAX 6250 [Kilmer Peak] (Centrino Advanced-N + WiMAX 6250 2x2 AGN)
 
 pci:v00008086d00000087sv00008086sd00001326*
- ID_MODEL_FROM_DATABASE=Centrino Advanced-N + WiMAX 6250 2x2 ABG
+ ID_MODEL_FROM_DATABASE=Centrino Advanced-N + WiMAX 6250 [Kilmer Peak] (Centrino Advanced-N + WiMAX 6250 2x2 ABG)
 
 pci:v00008086d00000089*
  ID_MODEL_FROM_DATABASE=Centrino Advanced-N + WiMAX 6250 [Kilmer Peak]
 
 pci:v00008086d00000089sv00008086sd00001311*
- ID_MODEL_FROM_DATABASE=Centrino Advanced-N + WiMAX 6250 2x2 AGN
+ ID_MODEL_FROM_DATABASE=Centrino Advanced-N + WiMAX 6250 [Kilmer Peak] (Centrino Advanced-N + WiMAX 6250 2x2 AGN)
 
 pci:v00008086d00000089sv00008086sd00001316*
- ID_MODEL_FROM_DATABASE=Centrino Advanced-N + WiMAX 6250 2x2 ABG
+ ID_MODEL_FROM_DATABASE=Centrino Advanced-N + WiMAX 6250 [Kilmer Peak] (Centrino Advanced-N + WiMAX 6250 2x2 ABG)
 
 pci:v00008086d0000008A*
  ID_MODEL_FROM_DATABASE=Centrino Wireless-N 1030 [Rainbow Peak]
 
 pci:v00008086d0000008Asv00008086sd00005305*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N 1030 BGN
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N 1030 [Rainbow Peak] (Centrino Wireless-N 1030 BGN)
 
 pci:v00008086d0000008Asv00008086sd00005307*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N 1030 BG
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N 1030 [Rainbow Peak] (Centrino Wireless-N 1030 BG)
 
 pci:v00008086d0000008Asv00008086sd00005325*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N 1030 BGN
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N 1030 [Rainbow Peak] (Centrino Wireless-N 1030 BGN)
 
 pci:v00008086d0000008Asv00008086sd00005327*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N 1030 BG
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N 1030 [Rainbow Peak] (Centrino Wireless-N 1030 BG)
 
 pci:v00008086d0000008B*
  ID_MODEL_FROM_DATABASE=Centrino Wireless-N 1030 [Rainbow Peak]
 
 pci:v00008086d0000008Bsv00008086sd00005315*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N 1030 BGN
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N 1030 [Rainbow Peak] (Centrino Wireless-N 1030 BGN)
 
 pci:v00008086d0000008Bsv00008086sd00005317*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N 1030 BG
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N 1030 [Rainbow Peak] (Centrino Wireless-N 1030 BG)
 
 pci:v00008086d00000090*
  ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6230 [Rainbow Peak]
 
 pci:v00008086d00000090sv00008086sd00005211*
- ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6230 AGN
+ ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6230 [Rainbow Peak] (Centrino Advanced-N 6230 AGN)
 
 pci:v00008086d00000090sv00008086sd00005215*
- ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6230 BGN
+ ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6230 [Rainbow Peak] (Centrino Advanced-N 6230 BGN)
 
 pci:v00008086d00000090sv00008086sd00005216*
- ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6230 ABG
+ ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6230 [Rainbow Peak] (Centrino Advanced-N 6230 ABG)
 
 pci:v00008086d00000091*
  ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6230 [Rainbow Peak]
 
 pci:v00008086d00000091sv00008086sd00005201*
- ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6230 AGN
+ ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6230 [Rainbow Peak] (Centrino Advanced-N 6230 AGN)
 
 pci:v00008086d00000091sv00008086sd00005205*
- ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6230 BGN
+ ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6230 [Rainbow Peak] (Centrino Advanced-N 6230 BGN)
 
 pci:v00008086d00000091sv00008086sd00005206*
- ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6230 ABG
+ ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6230 [Rainbow Peak] (Centrino Advanced-N 6230 ABG)
 
 pci:v00008086d00000091sv00008086sd00005207*
- ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6230 BG
+ ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6230 [Rainbow Peak] (Centrino Advanced-N 6230 BG)
 
 pci:v00008086d00000091sv00008086sd00005221*
- ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6230 AGN
+ ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6230 [Rainbow Peak] (Centrino Advanced-N 6230 AGN)
 
 pci:v00008086d00000091sv00008086sd00005225*
- ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6230 BGN
+ ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6230 [Rainbow Peak] (Centrino Advanced-N 6230 BGN)
 
 pci:v00008086d00000091sv00008086sd00005226*
- ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6230 ABG
+ ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6230 [Rainbow Peak] (Centrino Advanced-N 6230 ABG)
 
 pci:v00008086d00000100*
  ID_MODEL_FROM_DATABASE=2nd Generation Core Processor Family DRAM Controller
 
 pci:v00008086d00000100sv00001028sd000004AA*
- ID_MODEL_FROM_DATABASE=XPS 8300
+ ID_MODEL_FROM_DATABASE=2nd Generation Core Processor Family DRAM Controller (XPS 8300)
 
 pci:v00008086d00000100sv00001043sd0000844D*
- ID_MODEL_FROM_DATABASE=P8P67 Deluxe Motherboard
+ ID_MODEL_FROM_DATABASE=2nd Generation Core Processor Family DRAM Controller (P8P67/P8H67 Series Motherboard)
 
 pci:v00008086d00000101*
  ID_MODEL_FROM_DATABASE=Xeon E3-1200/2nd Generation Core Processor Family PCI Express Root Port
 
 pci:v00008086d00000101sv00001028sd000004B2*
- ID_MODEL_FROM_DATABASE=Vostro 3350
+ ID_MODEL_FROM_DATABASE=Xeon E3-1200/2nd Generation Core Processor Family PCI Express Root Port (Vostro 3350)
 
 pci:v00008086d00000101sv0000106Bsd000000DC*
- ID_MODEL_FROM_DATABASE=MacBookPro8,2 [Core i7, 15", 2011]
+ ID_MODEL_FROM_DATABASE=Xeon E3-1200/2nd Generation Core Processor Family PCI Express Root Port (MacBookPro8,2 [Core i7, 15", 2011])
 
 pci:v00008086d00000102*
  ID_MODEL_FROM_DATABASE=2nd Generation Core Processor Family Integrated Graphics Controller
 
 pci:v00008086d00000102sv00001028sd000004AA*
- ID_MODEL_FROM_DATABASE=XPS 8300
+ ID_MODEL_FROM_DATABASE=2nd Generation Core Processor Family Integrated Graphics Controller (XPS 8300)
+
+pci:v00008086d00000102sv00001043sd00000102*
+ ID_MODEL_FROM_DATABASE=2nd Generation Core Processor Family Integrated Graphics Controller (P8H67 Series Motherboard)
 
 pci:v00008086d00000104*
  ID_MODEL_FROM_DATABASE=2nd Generation Core Processor Family DRAM Controller
 
 pci:v00008086d00000104sv00001028sd000004A3*
- ID_MODEL_FROM_DATABASE=Precision M4600
+ ID_MODEL_FROM_DATABASE=2nd Generation Core Processor Family DRAM Controller (Precision M4600)
 
 pci:v00008086d00000104sv00001028sd000004B2*
- ID_MODEL_FROM_DATABASE=Vostro 3350
+ ID_MODEL_FROM_DATABASE=2nd Generation Core Processor Family DRAM Controller (Vostro 3350)
 
 pci:v00008086d00000104sv00001028sd000004DA*
- ID_MODEL_FROM_DATABASE=Vostro 3750
+ ID_MODEL_FROM_DATABASE=2nd Generation Core Processor Family DRAM Controller (Vostro 3750)
 
 pci:v00008086d00000104sv0000106Bsd000000DC*
- ID_MODEL_FROM_DATABASE=MacBookPro8,2 [Core i7, 15", 2011]
+ ID_MODEL_FROM_DATABASE=2nd Generation Core Processor Family DRAM Controller (MacBookPro8,2 [Core i7, 15", 2011])
 
 pci:v00008086d00000105*
  ID_MODEL_FROM_DATABASE=Xeon E3-1200/2nd Generation Core Processor Family PCI Express Root Port
 
 pci:v00008086d00000105sv0000106Bsd000000DC*
- ID_MODEL_FROM_DATABASE=MacBookPro8,2 [Core i7, 15", 2011]
+ ID_MODEL_FROM_DATABASE=Xeon E3-1200/2nd Generation Core Processor Family PCI Express Root Port (MacBookPro8,2 [Core i7, 15", 2011])
 
 pci:v00008086d00000106*
  ID_MODEL_FROM_DATABASE=2nd Generation Core Processor Family Integrated Graphics Controller
@@ -54039,7 +55518,7 @@ pci:v00008086d00000116*
  ID_MODEL_FROM_DATABASE=2nd Generation Core Processor Family Integrated Graphics Controller
 
 pci:v00008086d00000116sv00001028sd000004DA*
- ID_MODEL_FROM_DATABASE=Vostro 3750
+ ID_MODEL_FROM_DATABASE=2nd Generation Core Processor Family Integrated Graphics Controller (Vostro 3750)
 
 pci:v00008086d00000122*
  ID_MODEL_FROM_DATABASE=2nd Generation Core Processor Family Integrated Graphics Controller
@@ -54048,62 +55527,80 @@ pci:v00008086d00000126*
  ID_MODEL_FROM_DATABASE=2nd Generation Core Processor Family Integrated Graphics Controller
 
 pci:v00008086d00000126sv00001028sd000004CC*
- ID_MODEL_FROM_DATABASE=Vostro 3350
+ ID_MODEL_FROM_DATABASE=2nd Generation Core Processor Family Integrated Graphics Controller (Vostro 3350)
 
 pci:v00008086d00000150*
  ID_MODEL_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor DRAM Controller
 
 pci:v00008086d00000150sv00001043sd000084CA*
- ID_MODEL_FROM_DATABASE=P8H77-I Motherboard
+ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor DRAM Controller (P8 series motherboard)
+
+pci:v00008086d00000150sv000015D9sd00000624*
+ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor DRAM Controller (X9SCM-F Motherboard)
 
 pci:v00008086d00000150sv00001849sd00000150*
- ID_MODEL_FROM_DATABASE=Motherboard
+ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor DRAM Controller (Motherboard)
 
 pci:v00008086d00000151*
  ID_MODEL_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor PCI Express Root Port
 
 pci:v00008086d00000151sv00001043sd00001477*
- ID_MODEL_FROM_DATABASE=N56VZ
+ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor PCI Express Root Port (N56VZ)
+
+pci:v00008086d00000151sv00001043sd0000844D*
+ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor PCI Express Root Port (P8 series motherboard)
 
 pci:v00008086d00000151sv00001043sd000084CA*
- ID_MODEL_FROM_DATABASE=P8H77-I Motherboard
+ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor PCI Express Root Port (P8H77-I Motherboard)
+
+pci:v00008086d00000151sv00008086sd00002010*
+ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor PCI Express Root Port (Server Board S1200BTS)
 
 pci:v00008086d00000152*
  ID_MODEL_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor Graphics Controller
 
 pci:v00008086d00000152sv00001043sd000084CA*
- ID_MODEL_FROM_DATABASE=P8H77-I Motherboard
+ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor Graphics Controller (P8H77-I Motherboard)
 
 pci:v00008086d00000153*
  ID_MODEL_FROM_DATABASE=3rd Gen Core Processor Thermal Subsystem
 
 pci:v00008086d00000153sv00001043sd00001517*
- ID_MODEL_FROM_DATABASE=Zenbook Prime UX31A
+ ID_MODEL_FROM_DATABASE=3rd Gen Core Processor Thermal Subsystem (Zenbook Prime UX31A)
 
 pci:v00008086d00000154*
  ID_MODEL_FROM_DATABASE=3rd Gen Core processor DRAM Controller
 
 pci:v00008086d00000154sv00001025sd00000813*
- ID_MODEL_FROM_DATABASE=Aspire R7-571
+ ID_MODEL_FROM_DATABASE=3rd Gen Core processor DRAM Controller (Aspire R7-571)
 
 pci:v00008086d00000154sv0000103Csd000017F6*
- ID_MODEL_FROM_DATABASE=ProBook 4540s
+ ID_MODEL_FROM_DATABASE=3rd Gen Core processor DRAM Controller (ProBook 4540s)
 
 pci:v00008086d00000154sv00001043sd00001477*
- ID_MODEL_FROM_DATABASE=N56VZ
+ ID_MODEL_FROM_DATABASE=3rd Gen Core processor DRAM Controller (N56VZ)
 
 pci:v00008086d00000154sv00001043sd00001517*
- ID_MODEL_FROM_DATABASE=Zenbook Prime UX31A
+ ID_MODEL_FROM_DATABASE=3rd Gen Core processor DRAM Controller (Zenbook Prime UX31A)
 
 pci:v00008086d00000155*
  ID_MODEL_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor PCI Express Root Port
 
+pci:v00008086d00000155sv00008086sd00002010*
+ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor PCI Express Root Port (Server Board S1200BTS)
+
 pci:v00008086d00000156*
  ID_MODEL_FROM_DATABASE=3rd Gen Core processor Graphics Controller
 
 pci:v00008086d00000158*
  ID_MODEL_FROM_DATABASE=Xeon E3-1200 v2/Ivy Bridge DRAM Controller
 
+pci:v00008086d00000158sv00001043sd0000844D*
+ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v2/Ivy Bridge DRAM Controller (P8 series motherboard)
+
+pci:v00008086d00000158sv00008086sd00002010*
+ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v2/Ivy Bridge DRAM Controller (Server Board S1200BTS)
+
 pci:v00008086d00000159*
  ID_MODEL_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor PCI Express Root Port
 
@@ -54116,27 +55613,36 @@ pci:v00008086d0000015C*
 pci:v00008086d0000015D*
  ID_MODEL_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor PCI Express Root Port
 
+pci:v00008086d0000015Dsv00001043sd0000844D*
+ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor PCI Express Root Port (P8 series motherboard)
+
 pci:v00008086d0000015E*
  ID_MODEL_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor Graphics Controller
 
 pci:v00008086d00000162*
  ID_MODEL_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor Graphics Controller
 
+pci:v00008086d00000162sv00001043sd000084CA*
+ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor Graphics Controller (P8 series motherboard)
+
 pci:v00008086d00000162sv00001849sd00000162*
- ID_MODEL_FROM_DATABASE=Motherboard
+ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor Graphics Controller (Motherboard)
 
 pci:v00008086d00000166*
  ID_MODEL_FROM_DATABASE=3rd Gen Core processor Graphics Controller
 
 pci:v00008086d00000166sv00001043sd00001517*
- ID_MODEL_FROM_DATABASE=Zenbook Prime UX31A
+ ID_MODEL_FROM_DATABASE=3rd Gen Core processor Graphics Controller (Zenbook Prime UX31A)
 
 pci:v00008086d00000166sv00001043sd00002103*
- ID_MODEL_FROM_DATABASE=N56VZ
+ ID_MODEL_FROM_DATABASE=3rd Gen Core processor Graphics Controller (N56VZ)
 
 pci:v00008086d0000016A*
  ID_MODEL_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor Graphics Controller
 
+pci:v00008086d0000016Asv00001043sd0000844D*
+ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor Graphics Controller (P8B WS Motherboard)
+
 pci:v00008086d00000172*
  ID_MODEL_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor Graphics Controller
 
@@ -54153,19 +55659,19 @@ pci:v00008086d00000326*
  ID_MODEL_FROM_DATABASE=6700/6702PXH I/OxAPIC Interrupt Controller A
 
 pci:v00008086d00000326sv0000103Csd00003208*
- ID_MODEL_FROM_DATABASE=ProLiant DL140 G2
+ ID_MODEL_FROM_DATABASE=6700/6702PXH I/OxAPIC Interrupt Controller A (ProLiant DL140 G2)
 
 pci:v00008086d00000326sv00001775sd00001100*
- ID_MODEL_FROM_DATABASE=CR11/VR11 Single Board Computer
+ ID_MODEL_FROM_DATABASE=6700/6702PXH I/OxAPIC Interrupt Controller A (CR11/VR11 Single Board Computer)
 
 pci:v00008086d00000327*
  ID_MODEL_FROM_DATABASE=6700PXH I/OxAPIC Interrupt Controller B
 
 pci:v00008086d00000327sv0000103Csd00003208*
- ID_MODEL_FROM_DATABASE=ProLiant DL140 G2
+ ID_MODEL_FROM_DATABASE=6700PXH I/OxAPIC Interrupt Controller B (ProLiant DL140 G2)
 
 pci:v00008086d00000327sv00001775sd00001100*
- ID_MODEL_FROM_DATABASE=CR11/VR11 Single Board Computer
+ ID_MODEL_FROM_DATABASE=6700PXH I/OxAPIC Interrupt Controller B (CR11/VR11 Single Board Computer)
 
 pci:v00008086d00000329*
  ID_MODEL_FROM_DATABASE=6700PXH PCI Express-to-PCI Bridge A
@@ -54234,11 +55740,14 @@ pci:v00008086d00000416*
  ID_MODEL_FROM_DATABASE=4th Gen Core Processor Integrated Graphics Controller
 
 pci:v00008086d00000416sv000017AAsd0000220E*
- ID_MODEL_FROM_DATABASE=ThinkPad T440p
+ ID_MODEL_FROM_DATABASE=4th Gen Core Processor Integrated Graphics Controller (ThinkPad T440p)
 
 pci:v00008086d0000041A*
  ID_MODEL_FROM_DATABASE=Xeon E3-1200 v3 Processor Integrated Graphics Controller
 
+pci:v00008086d0000041E*
+ ID_MODEL_FROM_DATABASE=4th Generation Core Processor Family Integrated Graphics Controller
+
 pci:v00008086d00000433*
  ID_MODEL_FROM_DATABASE=Coleto Creek ACC - ME/CPM interface
 
@@ -54339,16 +55848,16 @@ pci:v00008086d00000600*
  ID_MODEL_FROM_DATABASE=RAID Controller
 
 pci:v00008086d00000600sv00008086sd00000136*
- ID_MODEL_FROM_DATABASE=SRCU31L
+ ID_MODEL_FROM_DATABASE=RAID Controller (SRCU31L)
 
 pci:v00008086d00000600sv00008086sd000001AF*
- ID_MODEL_FROM_DATABASE=SRCZCR
+ ID_MODEL_FROM_DATABASE=RAID Controller (SRCZCR)
 
 pci:v00008086d00000600sv00008086sd000001C1*
- ID_MODEL_FROM_DATABASE=ICP Vortex GDT8546RZ
+ ID_MODEL_FROM_DATABASE=RAID Controller (ICP Vortex GDT8546RZ)
 
 pci:v00008086d00000600sv00008086sd000001F7*
- ID_MODEL_FROM_DATABASE=SCRU32
+ ID_MODEL_FROM_DATABASE=RAID Controller (SCRU32)
 
 pci:v00008086d0000061F*
  ID_MODEL_FROM_DATABASE=80303 I/O Processor
@@ -54441,301 +55950,301 @@ pci:v00008086d00000885*
  ID_MODEL_FROM_DATABASE=Centrino Wireless-N + WiMAX 6150
 
 pci:v00008086d00000885sv00008086sd00001305*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N + WiMAX 6150 BGN
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N + WiMAX 6150 (BGN)
 
 pci:v00008086d00000885sv00008086sd00001307*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N + WiMAX 6150 BG
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N + WiMAX 6150 (BG)
 
 pci:v00008086d00000885sv00008086sd00001325*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N + WiMAX 6150 BGN
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N + WiMAX 6150 (BGN)
 
 pci:v00008086d00000885sv00008086sd00001327*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N + WiMAX 6150 BG
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N + WiMAX 6150 (BG)
 
 pci:v00008086d00000886*
  ID_MODEL_FROM_DATABASE=Centrino Wireless-N + WiMAX 6150
 
 pci:v00008086d00000886sv00008086sd00001315*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N + WiMAX 6150 BGN
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N + WiMAX 6150 (BGN)
 
 pci:v00008086d00000886sv00008086sd00001317*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N + WiMAX 6150 BG
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N + WiMAX 6150 (BG)
 
 pci:v00008086d00000887*
  ID_MODEL_FROM_DATABASE=Centrino Wireless-N 2230
 
 pci:v00008086d00000887sv00008086sd00004062*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N 2230 BGN
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N 2230 (BGN)
 
 pci:v00008086d00000887sv00008086sd00004462*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N 2230 BGN
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N 2230 (BGN)
 
 pci:v00008086d00000888*
  ID_MODEL_FROM_DATABASE=Centrino Wireless-N 2230
 
 pci:v00008086d00000888sv00008086sd00004262*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N 2230 BGN
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N 2230 (BGN)
 
 pci:v00008086d0000088E*
  ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6235
 
 pci:v00008086d0000088Esv00008086sd00004060*
- ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6235 AGN
+ ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6235 (AGN)
 
 pci:v00008086d0000088Esv00008086sd00004460*
- ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6235 AGN
+ ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6235 (AGN)
 
 pci:v00008086d0000088F*
  ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6235
 
 pci:v00008086d0000088Fsv00008086sd00004260*
- ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6235 AGN
+ ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6235 (AGN)
 
 pci:v00008086d00000890*
  ID_MODEL_FROM_DATABASE=Centrino Wireless-N 2200
 
 pci:v00008086d00000890sv00008086sd00004022*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N 2200 BGN
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N 2200 (BGN)
 
 pci:v00008086d00000890sv00008086sd00004422*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N 2200 BGN
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N 2200 (BGN)
 
 pci:v00008086d00000890sv00008086sd00004822*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N 2200 BGN
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N 2200 (BGN)
 
 pci:v00008086d00000891*
  ID_MODEL_FROM_DATABASE=Centrino Wireless-N 2200
 
 pci:v00008086d00000891sv00008086sd00004222*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N 2200 BGN
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N 2200 (BGN)
 
 pci:v00008086d00000892*
  ID_MODEL_FROM_DATABASE=Centrino Wireless-N 135
 
 pci:v00008086d00000892sv00008086sd00000062*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N 135 BGN
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N 135 (BGN)
 
 pci:v00008086d00000892sv00008086sd00000462*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N 135 BGN
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N 135 (BGN)
 
 pci:v00008086d00000893*
  ID_MODEL_FROM_DATABASE=Centrino Wireless-N 135
 
 pci:v00008086d00000893sv00008086sd00000262*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N 135 BGN
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N 135 (BGN)
 
 pci:v00008086d00000894*
  ID_MODEL_FROM_DATABASE=Centrino Wireless-N 105
 
 pci:v00008086d00000894sv00008086sd00000022*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N 105 BGN
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N 105 (BGN)
 
 pci:v00008086d00000894sv00008086sd00000422*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N 105 BGN
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N 105 (BGN)
 
 pci:v00008086d00000894sv00008086sd00000822*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N 105 BGN
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N 105 (BGN)
 
 pci:v00008086d00000895*
  ID_MODEL_FROM_DATABASE=Centrino Wireless-N 105
 
 pci:v00008086d00000895sv00008086sd00000222*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N 105 BGN
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N 105 (BGN)
 
 pci:v00008086d00000896*
  ID_MODEL_FROM_DATABASE=Centrino Wireless-N 130
 
 pci:v00008086d00000896sv00008086sd00005005*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N 130 BGN
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N 130 (BGN)
 
 pci:v00008086d00000896sv00008086sd00005007*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N 130 BG
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N 130 (BG)
 
 pci:v00008086d00000896sv00008086sd00005025*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N 130 BGN
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N 130 (BGN)
 
 pci:v00008086d00000896sv00008086sd00005027*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N 130 BG
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N 130 (BG)
 
 pci:v00008086d00000897*
  ID_MODEL_FROM_DATABASE=Centrino Wireless-N 130
 
 pci:v00008086d00000897sv00008086sd00005015*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N 130 BGN
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N 130 (BGN)
 
 pci:v00008086d00000897sv00008086sd00005017*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N 130 BG
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N 130 (BG)
 
 pci:v00008086d000008AE*
  ID_MODEL_FROM_DATABASE=Centrino Wireless-N 100
 
 pci:v00008086d000008AEsv00008086sd00001005*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N 100 BGN
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N 100 (BGN)
 
 pci:v00008086d000008AEsv00008086sd00001007*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N 100 BG
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N 100 (BG)
 
 pci:v00008086d000008AEsv00008086sd00001025*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N 100 BGN
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N 100 (BGN)
 
 pci:v00008086d000008AEsv00008086sd00001027*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N 100 BG
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N 100 (BG)
 
 pci:v00008086d000008AF*
  ID_MODEL_FROM_DATABASE=Centrino Wireless-N 100
 
 pci:v00008086d000008AFsv00008086sd00001015*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N 100 BGN
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N 100 (BGN)
 
 pci:v00008086d000008AFsv00008086sd00001017*
- ID_MODEL_FROM_DATABASE=Centrino Wireless-N 100 BG
+ ID_MODEL_FROM_DATABASE=Centrino Wireless-N 100 (BG)
 
 pci:v00008086d000008B1*
  ID_MODEL_FROM_DATABASE=Wireless 7260
 
 pci:v00008086d000008B1sv00008086sd00004060*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-N 7260
+ ID_MODEL_FROM_DATABASE=Wireless 7260 (Dual Band Wireless-N 7260)
 
 pci:v00008086d000008B1sv00008086sd00004062*
- ID_MODEL_FROM_DATABASE=Wireless-N 7260
+ ID_MODEL_FROM_DATABASE=Wireless 7260 (Wireless-N 7260)
 
 pci:v00008086d000008B1sv00008086sd00004070*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-AC 7260
+ ID_MODEL_FROM_DATABASE=Wireless 7260 (Dual Band Wireless-AC 7260)
 
 pci:v00008086d000008B1sv00008086sd00004160*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-N 7260
+ ID_MODEL_FROM_DATABASE=Wireless 7260 (Dual Band Wireless-N 7260)
 
 pci:v00008086d000008B1sv00008086sd00004162*
- ID_MODEL_FROM_DATABASE=Wireless-N 7260
+ ID_MODEL_FROM_DATABASE=Wireless 7260 (Wireless-N 7260)
 
 pci:v00008086d000008B1sv00008086sd00004170*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-AC 7260
+ ID_MODEL_FROM_DATABASE=Wireless 7260 (Dual Band Wireless-AC 7260)
 
 pci:v00008086d000008B1sv00008086sd00004460*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-N 7260
+ ID_MODEL_FROM_DATABASE=Wireless 7260 (Dual Band Wireless-N 7260)
 
 pci:v00008086d000008B1sv00008086sd00004462*
- ID_MODEL_FROM_DATABASE=Wireless-N 7260
+ ID_MODEL_FROM_DATABASE=Wireless 7260 (Wireless-N 7260)
 
 pci:v00008086d000008B1sv00008086sd00004470*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-AC 7260
+ ID_MODEL_FROM_DATABASE=Wireless 7260 (Dual Band Wireless-AC 7260)
 
 pci:v00008086d000008B1sv00008086sd0000486E*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-AC 7260
+ ID_MODEL_FROM_DATABASE=Wireless 7260 (Dual Band Wireless-AC 7260)
 
 pci:v00008086d000008B1sv00008086sd00004870*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-AC 7260
+ ID_MODEL_FROM_DATABASE=Wireless 7260 (Dual Band Wireless-AC 7260)
 
 pci:v00008086d000008B1sv00008086sd00004A6C*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-AC 7260
+ ID_MODEL_FROM_DATABASE=Wireless 7260 (Dual Band Wireless-AC 7260)
 
 pci:v00008086d000008B1sv00008086sd00004A6E*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-AC 7260
+ ID_MODEL_FROM_DATABASE=Wireless 7260 (Dual Band Wireless-AC 7260)
 
 pci:v00008086d000008B1sv00008086sd00004A70*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-AC 7260
+ ID_MODEL_FROM_DATABASE=Wireless 7260 (Dual Band Wireless-AC 7260)
 
 pci:v00008086d000008B1sv00008086sd0000C020*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-N 7260
+ ID_MODEL_FROM_DATABASE=Wireless 7260 (Dual Band Wireless-N 7260)
 
 pci:v00008086d000008B1sv00008086sd0000C060*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-N 7260
+ ID_MODEL_FROM_DATABASE=Wireless 7260 (Dual Band Wireless-N 7260)
 
 pci:v00008086d000008B1sv00008086sd0000C062*
- ID_MODEL_FROM_DATABASE=Wireless-N 7260
+ ID_MODEL_FROM_DATABASE=Wireless 7260 (Wireless-N 7260)
 
 pci:v00008086d000008B1sv00008086sd0000C070*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-AC 7260
+ ID_MODEL_FROM_DATABASE=Wireless 7260 (Dual Band Wireless-AC 7260)
 
 pci:v00008086d000008B1sv00008086sd0000C160*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-N 7260
+ ID_MODEL_FROM_DATABASE=Wireless 7260 (Dual Band Wireless-N 7260)
 
 pci:v00008086d000008B1sv00008086sd0000C162*
- ID_MODEL_FROM_DATABASE=Wireless-N 7260
+ ID_MODEL_FROM_DATABASE=Wireless 7260 (Wireless-N 7260)
 
 pci:v00008086d000008B1sv00008086sd0000C170*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-AC 7260
+ ID_MODEL_FROM_DATABASE=Wireless 7260 (Dual Band Wireless-AC 7260)
 
 pci:v00008086d000008B1sv00008086sd0000C420*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-N 7260
+ ID_MODEL_FROM_DATABASE=Wireless 7260 (Dual Band Wireless-N 7260)
 
 pci:v00008086d000008B1sv00008086sd0000C460*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-N 7260
+ ID_MODEL_FROM_DATABASE=Wireless 7260 (Dual Band Wireless-N 7260)
 
 pci:v00008086d000008B1sv00008086sd0000C462*
- ID_MODEL_FROM_DATABASE=Wireless-N 7260
+ ID_MODEL_FROM_DATABASE=Wireless 7260 (Wireless-N 7260)
 
 pci:v00008086d000008B1sv00008086sd0000C470*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-AC 7260
+ ID_MODEL_FROM_DATABASE=Wireless 7260 (Dual Band Wireless-AC 7260)
 
 pci:v00008086d000008B2*
  ID_MODEL_FROM_DATABASE=Wireless 7260
 
 pci:v00008086d000008B2sv00008086sd00004220*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-N 7260
+ ID_MODEL_FROM_DATABASE=Wireless 7260 (Dual Band Wireless-N 7260)
 
 pci:v00008086d000008B2sv00008086sd00004260*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-N 7260
+ ID_MODEL_FROM_DATABASE=Wireless 7260 (Dual Band Wireless-N 7260)
 
 pci:v00008086d000008B2sv00008086sd00004262*
- ID_MODEL_FROM_DATABASE=Wireless-N 7260
+ ID_MODEL_FROM_DATABASE=Wireless 7260 (Wireless-N 7260)
 
 pci:v00008086d000008B2sv00008086sd00004270*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-AC 7260
+ ID_MODEL_FROM_DATABASE=Wireless 7260 (Dual Band Wireless-AC 7260)
 
 pci:v00008086d000008B2sv00008086sd0000C220*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-N 7260
+ ID_MODEL_FROM_DATABASE=Wireless 7260 (Dual Band Wireless-N 7260)
 
 pci:v00008086d000008B2sv00008086sd0000C260*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-N 7260
+ ID_MODEL_FROM_DATABASE=Wireless 7260 (Dual Band Wireless-N 7260)
 
 pci:v00008086d000008B2sv00008086sd0000C262*
- ID_MODEL_FROM_DATABASE=Wireless-N 7260
+ ID_MODEL_FROM_DATABASE=Wireless 7260 (Wireless-N 7260)
 
 pci:v00008086d000008B2sv00008086sd0000C270*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-AC 7260
+ ID_MODEL_FROM_DATABASE=Wireless 7260 (Dual Band Wireless-AC 7260)
 
 pci:v00008086d000008B3*
  ID_MODEL_FROM_DATABASE=Wireless 3160
 
 pci:v00008086d000008B3sv00008086sd00000060*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-N 3160
+ ID_MODEL_FROM_DATABASE=Wireless 3160 (Dual Band Wireless-N 3160)
 
 pci:v00008086d000008B3sv00008086sd00000062*
- ID_MODEL_FROM_DATABASE=Wireless-N 3160
+ ID_MODEL_FROM_DATABASE=Wireless 3160 (Wireless-N 3160)
 
 pci:v00008086d000008B3sv00008086sd00000070*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-AC 3160
+ ID_MODEL_FROM_DATABASE=Wireless 3160 (Dual Band Wireless-AC 3160)
 
 pci:v00008086d000008B3sv00008086sd00000170*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-AC 3160
+ ID_MODEL_FROM_DATABASE=Wireless 3160 (Dual Band Wireless-AC 3160)
 
 pci:v00008086d000008B3sv00008086sd00000470*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-AC 3160
+ ID_MODEL_FROM_DATABASE=Wireless 3160 (Dual Band Wireless-AC 3160)
 
 pci:v00008086d000008B3sv00008086sd00008060*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless N-3160
+ ID_MODEL_FROM_DATABASE=Wireless 3160 (Dual Band Wireless N-3160)
 
 pci:v00008086d000008B3sv00008086sd00008062*
- ID_MODEL_FROM_DATABASE=Wireless N-3160
+ ID_MODEL_FROM_DATABASE=Wireless 3160 (Wireless N-3160)
 
 pci:v00008086d000008B3sv00008086sd00008070*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless AC 3160
+ ID_MODEL_FROM_DATABASE=Wireless 3160 (Dual Band Wireless AC 3160)
 
 pci:v00008086d000008B3sv00008086sd00008170*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless AC 3160
+ ID_MODEL_FROM_DATABASE=Wireless 3160 (Dual Band Wireless AC 3160)
 
 pci:v00008086d000008B3sv00008086sd00008470*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless AC 3160
+ ID_MODEL_FROM_DATABASE=Wireless 3160 (Dual Band Wireless AC 3160)
 
 pci:v00008086d000008B4*
  ID_MODEL_FROM_DATABASE=Wireless 3160
 
 pci:v00008086d000008B4sv00008086sd00000270*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-AC 3160
+ ID_MODEL_FROM_DATABASE=Wireless 3160 (Dual Band Wireless-AC 3160)
 
 pci:v00008086d000008B4sv00008086sd00008270*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless AC 3160
+ ID_MODEL_FROM_DATABASE=Wireless 3160 (Dual Band Wireless AC 3160)
 
 pci:v00008086d000008CF*
  ID_MODEL_FROM_DATABASE=Atom Processor Z2760 Integrated Graphics Controller
@@ -54744,91 +56253,106 @@ pci:v00008086d0000095A*
  ID_MODEL_FROM_DATABASE=Wireless 7265
 
 pci:v00008086d0000095Asv00008086sd00001010*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-AC 7265
+ ID_MODEL_FROM_DATABASE=Wireless 7265 (Dual Band Wireless-AC 7265)
 
 pci:v00008086d0000095Asv00008086sd00005000*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-N 7265
+ ID_MODEL_FROM_DATABASE=Wireless 7265 (Dual Band Wireless-N 7265)
 
 pci:v00008086d0000095Asv00008086sd00005002*
- ID_MODEL_FROM_DATABASE=Wireless-N 7265
+ ID_MODEL_FROM_DATABASE=Wireless 7265 (Wireless-N 7265)
 
 pci:v00008086d0000095Asv00008086sd0000500A*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-AC 7265
+ ID_MODEL_FROM_DATABASE=Wireless 7265 (Dual Band Wireless-N 7265)
 
 pci:v00008086d0000095Asv00008086sd00005010*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-AC 7265
+ ID_MODEL_FROM_DATABASE=Wireless 7265 (Dual Band Wireless-AC 7265)
 
 pci:v00008086d0000095Asv00008086sd00005012*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-AC 7265
+ ID_MODEL_FROM_DATABASE=Wireless 7265 (Dual Band Wireless-AC 7265)
 
 pci:v00008086d0000095Asv00008086sd00005020*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-N 7265
+ ID_MODEL_FROM_DATABASE=Wireless 7265 (Dual Band Wireless-N 7265)
 
 pci:v00008086d0000095Asv00008086sd0000502A*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-N 7265
+ ID_MODEL_FROM_DATABASE=Wireless 7265 (Dual Band Wireless-N 7265)
 
 pci:v00008086d0000095Asv00008086sd00005090*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-AC 7265
+ ID_MODEL_FROM_DATABASE=Wireless 7265 (Dual Band Wireless-AC 7265)
+
+pci:v00008086d0000095Asv00008086sd00005100*
+ ID_MODEL_FROM_DATABASE=Wireless 7265 (Dual Band Wireless-AC 7265)
+
+pci:v00008086d0000095Asv00008086sd0000510A*
+ ID_MODEL_FROM_DATABASE=Wireless 7265 (Dual Band Wireless-AC 7265)
 
 pci:v00008086d0000095Asv00008086sd00005110*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-AC 7265
+ ID_MODEL_FROM_DATABASE=Wireless 7265 (Dual Band Wireless-AC 7265)
+
+pci:v00008086d0000095Asv00008086sd00005112*
+ ID_MODEL_FROM_DATABASE=Wireless 7265 (Dual Band Wireless-AC 7265)
 
 pci:v00008086d0000095Asv00008086sd00005190*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-AC 7265
+ ID_MODEL_FROM_DATABASE=Wireless 7265 (Dual Band Wireless-AC 7265)
 
 pci:v00008086d0000095Asv00008086sd00005400*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-AC 7265
+ ID_MODEL_FROM_DATABASE=Wireless 7265 (Dual Band Wireless-AC 7265)
 
 pci:v00008086d0000095Asv00008086sd00005410*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-AC 7265
+ ID_MODEL_FROM_DATABASE=Wireless 7265 (Dual Band Wireless-AC 7265)
 
 pci:v00008086d0000095Asv00008086sd00005420*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-N 7265
+ ID_MODEL_FROM_DATABASE=Wireless 7265 (Dual Band Wireless-N 7265)
 
 pci:v00008086d0000095Asv00008086sd00005490*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-AC 7265
+ ID_MODEL_FROM_DATABASE=Wireless 7265 (Dual Band Wireless-AC 7265)
 
 pci:v00008086d0000095Asv00008086sd00005590*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-AC 7265
+ ID_MODEL_FROM_DATABASE=Wireless 7265 (Dual Band Wireless-AC 7265)
 
 pci:v00008086d0000095Asv00008086sd00009010*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-AC 7265
+ ID_MODEL_FROM_DATABASE=Wireless 7265 (Dual Band Wireless-AC 7265)
+
+pci:v00008086d0000095Asv00008086sd00009012*
+ ID_MODEL_FROM_DATABASE=Wireless 7265 (Dual Band Wireless-AC 7265)
 
 pci:v00008086d0000095Asv00008086sd00009110*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-AC 7265
+ ID_MODEL_FROM_DATABASE=Wireless 7265 (Dual Band Wireless-AC 7265)
+
+pci:v00008086d0000095Asv00008086sd00009112*
+ ID_MODEL_FROM_DATABASE=Wireless 7265 (Dual Band Wireless-AC 7265)
 
 pci:v00008086d0000095Asv00008086sd00009210*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-AC 7265
+ ID_MODEL_FROM_DATABASE=Wireless 7265 (Dual Band Wireless-AC 7265)
 
 pci:v00008086d0000095Asv00008086sd00009310*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-AC 7265
+ ID_MODEL_FROM_DATABASE=Wireless 7265 (Dual Band Wireless-AC 7265)
 
 pci:v00008086d0000095Asv00008086sd00009410*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-AC 7265
+ ID_MODEL_FROM_DATABASE=Wireless 7265 (Dual Band Wireless-AC 7265)
 
 pci:v00008086d0000095Asv00008086sd00009510*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-AC 7265
+ ID_MODEL_FROM_DATABASE=Wireless 7265 (Dual Band Wireless-AC 7265)
 
 pci:v00008086d0000095B*
  ID_MODEL_FROM_DATABASE=Wireless 7265
 
 pci:v00008086d0000095Bsv00008086sd00005200*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-N 7265
+ ID_MODEL_FROM_DATABASE=Wireless 7265 (Dual Band Wireless-N 7265)
 
 pci:v00008086d0000095Bsv00008086sd00005202*
- ID_MODEL_FROM_DATABASE=Wireless-N 7265
+ ID_MODEL_FROM_DATABASE=Wireless 7265 (Wireless-N 7265)
 
 pci:v00008086d0000095Bsv00008086sd00005210*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-AC 7265
+ ID_MODEL_FROM_DATABASE=Wireless 7265 (Dual Band Wireless-AC 7265)
 
 pci:v00008086d0000095Bsv00008086sd00005290*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-AC 7265
+ ID_MODEL_FROM_DATABASE=Wireless 7265 (Dual Band Wireless-AC 7265)
 
 pci:v00008086d0000095Bsv00008086sd00005302*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-AC 7265
+ ID_MODEL_FROM_DATABASE=Wireless 7265 (Dual Band Wireless-AC 7265)
 
 pci:v00008086d0000095Bsv00008086sd00005310*
- ID_MODEL_FROM_DATABASE=Dual Band Wireless-AC 7265
+ ID_MODEL_FROM_DATABASE=Wireless 7265 (Dual Band Wireless-AC 7265)
 
 pci:v00008086d00000960*
  ID_MODEL_FROM_DATABASE=80960RP (i960RP) Microprocessor/Bridge
@@ -54842,15 +56366,24 @@ pci:v00008086d00000964*
 pci:v00008086d00000A04*
  ID_MODEL_FROM_DATABASE=Haswell-ULT DRAM Controller
 
+pci:v00008086d00000A04sv000017AAsd00002214*
+ ID_MODEL_FROM_DATABASE=Haswell-ULT DRAM Controller (ThinkPad X240)
+
 pci:v00008086d00000A06*
  ID_MODEL_FROM_DATABASE=Haswell-ULT Integrated Graphics Controller
 
 pci:v00008086d00000A0C*
  ID_MODEL_FROM_DATABASE=Haswell-ULT HD Audio Controller
 
+pci:v00008086d00000A0Csv000017AAsd00002214*
+ ID_MODEL_FROM_DATABASE=Haswell-ULT HD Audio Controller (ThinkPad X240)
+
 pci:v00008086d00000A16*
  ID_MODEL_FROM_DATABASE=Haswell-ULT Integrated Graphics Controller
 
+pci:v00008086d00000A16sv000017AAsd00002214*
+ ID_MODEL_FROM_DATABASE=Haswell-ULT Integrated Graphics Controller (ThinkPad X240)
+
 pci:v00008086d00000A22*
  ID_MODEL_FROM_DATABASE=Haswell-ULT Integrated Graphics Controller
 
@@ -54867,7 +56400,7 @@ pci:v00008086d00000BE1*
  ID_MODEL_FROM_DATABASE=Atom Processor D2xxx/N2xxx Integrated Graphics Controller
 
 pci:v00008086d00000BE1sv0000105Bsd00000D7C*
- ID_MODEL_FROM_DATABASE=D270S/D250S Motherboard
+ ID_MODEL_FROM_DATABASE=Atom Processor D2xxx/N2xxx Integrated Graphics Controller (D270S/D250S Motherboard)
 
 pci:v00008086d00000BE2*
  ID_MODEL_FROM_DATABASE=Atom Processor D2xxx/N2xxx Integrated Graphics Controller
@@ -54930,7 +56463,7 @@ pci:v00008086d00000BF5*
  ID_MODEL_FROM_DATABASE=Atom Processor D2xxx/N2xxx DRAM Controller
 
 pci:v00008086d00000BF5sv0000105Bsd00000D7C*
- ID_MODEL_FROM_DATABASE=D270S/D250S Motherboard
+ ID_MODEL_FROM_DATABASE=Atom Processor D2xxx/N2xxx DRAM Controller (D270S/D250S Motherboard)
 
 pci:v00008086d00000BF6*
  ID_MODEL_FROM_DATABASE=Atom Processor D2xxx/N2xxx DRAM Controller
@@ -54947,8 +56480,11 @@ pci:v00008086d00000C01*
 pci:v00008086d00000C04*
  ID_MODEL_FROM_DATABASE=Xeon E3-1200 v3/4th Gen Core Processor DRAM Controller
 
+pci:v00008086d00000C04sv0000103Csd00001909*
+ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v3/4th Gen Core Processor DRAM Controller (ZBook 15)
+
 pci:v00008086d00000C04sv000017AAsd0000220E*
- ID_MODEL_FROM_DATABASE=ThinkPad T440p
+ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v3/4th Gen Core Processor DRAM Controller (ThinkPad T440p)
 
 pci:v00008086d00000C05*
  ID_MODEL_FROM_DATABASE=Xeon E3-1200 v3/4th Gen Core Processor PCI Express x8 Controller
@@ -54963,7 +56499,7 @@ pci:v00008086d00000C0C*
  ID_MODEL_FROM_DATABASE=Xeon E3-1200 v3/4th Gen Core Processor HD Audio Controller
 
 pci:v00008086d00000C0Csv000017AAsd0000220E*
- ID_MODEL_FROM_DATABASE=ThinkPad T440p
+ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v3/4th Gen Core Processor HD Audio Controller (ThinkPad T440p)
 
 pci:v00008086d00000C46*
  ID_MODEL_FROM_DATABASE=Atom Processor S1200 PCI Express Root Port 1
@@ -55089,667 +56625,523 @@ pci:v00008086d00000D36*
  ID_MODEL_FROM_DATABASE=Crystal Well Integrated Graphics Controller
 
 pci:v00008086d00000E00*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 DMI2
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 DMI2
 
 pci:v00008086d00000E01*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 PCI Express Root Port in DMI2 Mode
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 PCI Express Root Port in DMI2 Mode
 
 pci:v00008086d00000E02*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 PCI Express Root Port 1a
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 PCI Express Root Port 1a
 
 pci:v00008086d00000E03*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 PCI Express Root Port 1b
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 PCI Express Root Port 1b
 
 pci:v00008086d00000E04*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 PCI Express Root Port 2a
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 PCI Express Root Port 2a
 
 pci:v00008086d00000E05*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 PCI Express Root Port 2b
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 PCI Express Root Port 2b
 
 pci:v00008086d00000E06*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 PCI Express Root Port 2c
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 PCI Express Root Port 2c
 
 pci:v00008086d00000E07*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 PCI Express Root Port 2d
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 PCI Express Root Port 2d
 
 pci:v00008086d00000E08*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 PCI Express Root Port 3a
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 PCI Express Root Port 3a
 
 pci:v00008086d00000E09*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 PCI Express Root Port 3b
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 PCI Express Root Port 3b
 
 pci:v00008086d00000E0A*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 PCI Express Root Port 3c
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 PCI Express Root Port 3c
 
 pci:v00008086d00000E0B*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 PCI Express Root Port 3d
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 PCI Express Root Port 3d
 
 pci:v00008086d00000E10*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 IIO Configuration Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 IIO Configuration Registers
 
 pci:v00008086d00000E13*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 IIO Configuration Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 IIO Configuration Registers
 
 pci:v00008086d00000E17*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 IIO Configuration Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 IIO Configuration Registers
 
 pci:v00008086d00000E18*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 IIO Configuration Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 IIO Configuration Registers
 
 pci:v00008086d00000E1C*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 IIO Configuration Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 IIO Configuration Registers
 
 pci:v00008086d00000E1D*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 R2PCIe
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 R2PCIe
 
 pci:v00008086d00000E1E*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 UBOX Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 UBOX Registers
 
 pci:v00008086d00000E1F*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 UBOX Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 UBOX Registers
 
 pci:v00008086d00000E20*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Crystal Beach DMA Channel 0
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Crystal Beach DMA Channel 0
 
 pci:v00008086d00000E21*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Crystal Beach DMA Channel 1
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Crystal Beach DMA Channel 1
 
 pci:v00008086d00000E22*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Crystal Beach DMA Channel 2
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Crystal Beach DMA Channel 2
 
 pci:v00008086d00000E23*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Crystal Beach DMA Channel 3
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Crystal Beach DMA Channel 3
 
 pci:v00008086d00000E24*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Crystal Beach DMA Channel 4
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Crystal Beach DMA Channel 4
 
 pci:v00008086d00000E25*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Crystal Beach DMA Channel 5
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Crystal Beach DMA Channel 5
 
 pci:v00008086d00000E26*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Crystal Beach DMA Channel 6
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Crystal Beach DMA Channel 6
 
 pci:v00008086d00000E27*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Crystal Beach DMA Channel 7
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Crystal Beach DMA Channel 7
 
 pci:v00008086d00000E28*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 VTd/Memory Map/Misc
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 VTd/Memory Map/Misc
 
 pci:v00008086d00000E29*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Memory Hotplug
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Memory Hotplug
 
 pci:v00008086d00000E2A*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 IIO RAS
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 IIO RAS
 
 pci:v00008086d00000E2C*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 IOAPIC
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 IOAPIC
 
 pci:v00008086d00000E2E*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 CBDMA
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 CBDMA
 
 pci:v00008086d00000E2F*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 CBDMA
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 CBDMA
 
 pci:v00008086d00000E30*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Home Agent 0
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Home Agent 0
 
 pci:v00008086d00000E32*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 QPI Link 0
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 QPI Link 0
 
 pci:v00008086d00000E33*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 QPI Link 1
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 QPI Link 1
 
 pci:v00008086d00000E34*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 R2PCIe
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 R2PCIe
 
 pci:v00008086d00000E36*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 QPI Ring Performance Ring Monitoring
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 QPI Ring Performance Ring Monitoring
 
 pci:v00008086d00000E37*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 QPI Ring Performance Ring Monitoring
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 QPI Ring Performance Ring Monitoring
 
 pci:v00008086d00000E38*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Home Agent 1
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Home Agent 1
 
 pci:v00008086d00000E3A*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 QPI Link 2
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 QPI Link 2
 
 pci:v00008086d00000E3E*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 QPI Ring Performance Ring Monitoring
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 QPI Ring Performance Ring Monitoring
 
 pci:v00008086d00000E3F*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 QPI Ring Performance Ring Monitoring
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 QPI Ring Performance Ring Monitoring
 
 pci:v00008086d00000E40*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 QPI Link 2
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 QPI Link 2
 
 pci:v00008086d00000E41*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 QPI Ring Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 QPI Ring Registers
 
 pci:v00008086d00000E43*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 QPI Link Reut 2
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 QPI Link Reut 2
 
 pci:v00008086d00000E44*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 QPI Link Reut 2
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 QPI Link Reut 2
+
+pci:v00008086d00000E45*
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 QPI Link Agent Register
+
+pci:v00008086d00000E47*
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 QPI Link Agent Register
 
 pci:v00008086d00000E60*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Home Agent 1
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Home Agent 1
 
 pci:v00008086d00000E68*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 1 Target Address/Thermal Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Integrated Memory Controller 1 Target Address/Thermal Registers
 
 pci:v00008086d00000E6A*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 1 Channel Target Address Decoder Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Integrated Memory Controller 1 Channel Target Address Decoder Registers
 
 pci:v00008086d00000E6B*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 1 Channel Target Address Decoder Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Integrated Memory Controller 1 Channel Target Address Decoder Registers
 
 pci:v00008086d00000E6C*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 1 Channel Target Address Decoder Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Integrated Memory Controller 1 Channel Target Address Decoder Registers
 
 pci:v00008086d00000E6D*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 1 Channel Target Address Decoder Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Integrated Memory Controller 1 Channel Target Address Decoder Registers
 
 pci:v00008086d00000E71*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 0 RAS Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Integrated Memory Controller 0 RAS Registers
 
 pci:v00008086d00000E74*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 R2PCIe
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 R2PCIe
 
 pci:v00008086d00000E75*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 R2PCIe
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 R2PCIe
 
 pci:v00008086d00000E77*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 QPI Ring Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 QPI Ring Registers
 
 pci:v00008086d00000E79*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 1 RAS Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Integrated Memory Controller 1 RAS Registers
 
 pci:v00008086d00000E7D*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 UBOX Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 UBOX Registers
 
 pci:v00008086d00000E7F*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 QPI Ring Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 QPI Ring Registers
 
 pci:v00008086d00000E80*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 QPI Link 0
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 QPI Link 0
 
 pci:v00008086d00000E81*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 QPI Ring Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 QPI Ring Registers
 
 pci:v00008086d00000E83*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 QPI Link Reut 0
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 QPI Link Reut 0
 
 pci:v00008086d00000E84*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 QPI Link Reut 0
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 QPI Link Reut 0
+
+pci:v00008086d00000E85*
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 QPI Link Agent Register
 
 pci:v00008086d00000E87*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 QPI Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 QPI Registers
 
 pci:v00008086d00000E90*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 QPI Link 1
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 QPI Link 1
 
 pci:v00008086d00000E93*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 QPI Link 1
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 QPI Link 1
 
 pci:v00008086d00000E94*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 QPI Link Reut 1
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 QPI Link Reut 1
+
+pci:v00008086d00000E95*
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 QPI Link Agent Register
 
 pci:v00008086d00000EA0*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Home Agent 0
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Home Agent 0
 
 pci:v00008086d00000EA8*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 0 Target Address/Thermal Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Integrated Memory Controller 0 Target Address/Thermal Registers
 
 pci:v00008086d00000EAA*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 0 Channel Target Address Decoder Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Integrated Memory Controller 0 Channel Target Address Decoder Registers
 
 pci:v00008086d00000EAB*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 0 Channel Target Address Decoder Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Integrated Memory Controller 0 Channel Target Address Decoder Registers
 
 pci:v00008086d00000EAC*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 0 Channel Target Address Decoder Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Integrated Memory Controller 0 Channel Target Address Decoder Registers
 
 pci:v00008086d00000EAD*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 0 Channel Target Address Decoder Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Integrated Memory Controller 0 Channel Target Address Decoder Registers
 
 pci:v00008086d00000EAE*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 DDRIO Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 DDRIO Registers
 
 pci:v00008086d00000EAF*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 DDRIO Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 DDRIO Registers
 
 pci:v00008086d00000EB0*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 1 Channel 0-3 Thermal Control 0
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Integrated Memory Controller 1 Channel 0-3 Thermal Control 0
 
 pci:v00008086d00000EB1*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 1 Channel 0-3 Thermal Control 1
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Integrated Memory Controller 1 Channel 0-3 Thermal Control 1
 
 pci:v00008086d00000EB2*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 1 Channel 0-3 ERROR Registers 0
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Integrated Memory Controller 1 Channel 0-3 ERROR Registers 0
 
 pci:v00008086d00000EB3*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 1 Channel 0-3 ERROR Registers 1
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Integrated Memory Controller 1 Channel 0-3 ERROR Registers 1
 
 pci:v00008086d00000EB4*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 1 Channel 0-3 Thermal Control 2
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Integrated Memory Controller 1 Channel 0-3 Thermal Control 2
 
 pci:v00008086d00000EB5*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 1 Channel 0-3 Thermal Control 3
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Integrated Memory Controller 1 Channel 0-3 Thermal Control 3
 
 pci:v00008086d00000EB6*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 1 Channel 0-3 ERROR Registers 2
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Integrated Memory Controller 1 Channel 0-3 ERROR Registers 2
 
 pci:v00008086d00000EB7*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 1 Channel 0-3 ERROR Registers 3
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Integrated Memory Controller 1 Channel 0-3 ERROR Registers 3
 
 pci:v00008086d00000EBC*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 DDRIO Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 DDRIO Registers
 
 pci:v00008086d00000EBE*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 DDRIO Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 DDRIO Registers
 
 pci:v00008086d00000EBF*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 DDRIO Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 DDRIO Registers
 
 pci:v00008086d00000EC0*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Power Control Unit 0
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Power Control Unit 0
 
 pci:v00008086d00000EC1*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Power Control Unit 1
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Power Control Unit 1
 
 pci:v00008086d00000EC2*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Power Control Unit 2
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Power Control Unit 2
 
 pci:v00008086d00000EC3*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Power Control Unit 3
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Power Control Unit 3
 
 pci:v00008086d00000EC4*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Power Control Unit 4
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Power Control Unit 4
 
 pci:v00008086d00000EC8*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 System Address Decoder
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 System Address Decoder
 
 pci:v00008086d00000EC9*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Broadcast Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Broadcast Registers
 
 pci:v00008086d00000ECA*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Broadcast Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Broadcast Registers
 
 pci:v00008086d00000ED8*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 DDRIO
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 DDRIO
 
 pci:v00008086d00000ED9*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 DDRIO
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 DDRIO
 
 pci:v00008086d00000EDC*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 DDRIO
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 DDRIO
 
 pci:v00008086d00000EDD*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 DDRIO
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 DDRIO
 
 pci:v00008086d00000EDE*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 DDRIO
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 DDRIO
 
 pci:v00008086d00000EDF*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 DDRIO
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 DDRIO
 
 pci:v00008086d00000EE0*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Unicast Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Unicast Registers
 
 pci:v00008086d00000EE1*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Unicast Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Unicast Registers
 
 pci:v00008086d00000EE2*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Unicast Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Unicast Registers
 
 pci:v00008086d00000EE3*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Unicast Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Unicast Registers
 
 pci:v00008086d00000EE4*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Unicast Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Unicast Registers
 
 pci:v00008086d00000EE5*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Unicast Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Unicast Registers
 
 pci:v00008086d00000EE6*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Unicast Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Unicast Registers
 
 pci:v00008086d00000EE7*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Unicast Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Unicast Registers
 
 pci:v00008086d00000EE8*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Unicast Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Unicast Registers
 
 pci:v00008086d00000EE9*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Unicast Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Unicast Registers
 
 pci:v00008086d00000EEA*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Unicast Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Unicast Registers
 
 pci:v00008086d00000EEB*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Unicast Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Unicast Registers
 
 pci:v00008086d00000EEC*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Unicast Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Unicast Registers
 
 pci:v00008086d00000EED*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Unicast Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Unicast Registers
 
 pci:v00008086d00000EEE*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Unicast Registers
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Unicast Registers
 
 pci:v00008086d00000EF0*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 0 Channel 0-3 Thermal Control 0
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Integrated Memory Controller 0 Channel 0-3 Thermal Control 0
 
 pci:v00008086d00000EF1*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 0 Channel 0-3 Thermal Control 1
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Integrated Memory Controller 0 Channel 0-3 Thermal Control 1
 
 pci:v00008086d00000EF2*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 0 Channel 0-3 ERROR Registers 0
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Integrated Memory Controller 0 Channel 0-3 ERROR Registers 0
 
 pci:v00008086d00000EF3*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 0 Channel 0-3 ERROR Registers 1
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Integrated Memory Controller 0 Channel 0-3 ERROR Registers 1
 
 pci:v00008086d00000EF4*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 0 Channel 0-3 Thermal Control 2
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Integrated Memory Controller 0 Channel 0-3 Thermal Control 2
 
 pci:v00008086d00000EF5*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 0 Channel 0-3 Thermal Control 3
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Integrated Memory Controller 0 Channel 0-3 Thermal Control 3
 
 pci:v00008086d00000EF6*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 0 Channel 0-3 ERROR Registers 2
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Integrated Memory Controller 0 Channel 0-3 ERROR Registers 2
 
 pci:v00008086d00000EF7*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 Integrated Memory Controller 0 Channel 0-3 ERROR Registers 3
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 Integrated Memory Controller 0 Channel 0-3 ERROR Registers 3
 
 pci:v00008086d00000EF8*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 DDRIO
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 DDRIO
 
 pci:v00008086d00000EF9*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 DDRIO
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 DDRIO
 
 pci:v00008086d00000EFA*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 DDRIO
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 DDRIO
 
 pci:v00008086d00000EFB*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 DDRIO
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 DDRIO
 
 pci:v00008086d00000EFC*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 DDRIO
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 DDRIO
 
 pci:v00008086d00000EFD*
- ID_MODEL_FROM_DATABASE=Xeon E5 v2/Core i7 DDRIO
+ ID_MODEL_FROM_DATABASE=Xeon E7 v2/Xeon E5 v2/Core i7 DDRIO
 
 pci:v00008086d00000F00*
- ID_MODEL_FROM_DATABASE=ValleyView SSA-CUnit
-
-pci:v00008086d00000F01*
- ID_MODEL_FROM_DATABASE=ValleyView SSA-CUnit
-
-pci:v00008086d00000F02*
- ID_MODEL_FROM_DATABASE=ValleyView SSA-CUnit
-
-pci:v00008086d00000F03*
- ID_MODEL_FROM_DATABASE=ValleyView SSA-CUnit
+ ID_MODEL_FROM_DATABASE=Atom Processor Z36xxx/Z37xxx Series SoC Transaction Register
 
 pci:v00008086d00000F04*
- ID_MODEL_FROM_DATABASE=ValleyView High Definition Audio Controller
-
-pci:v00008086d00000F05*
- ID_MODEL_FROM_DATABASE=ValleyView High Definition Audio Controller
+ ID_MODEL_FROM_DATABASE=Atom Processor Z36xxx/Z37xxx Series High Definition Audio Controller
 
 pci:v00008086d00000F06*
- ID_MODEL_FROM_DATABASE=ValleyView LPIO1 DMA Controller
-
-pci:v00008086d00000F07*
- ID_MODEL_FROM_DATABASE=ValleyView LPIO1 DMA Controller
+ ID_MODEL_FROM_DATABASE=Atom Processor Z36xxx/Z37xxx Series LPIO1 DMA Controller
 
 pci:v00008086d00000F08*
- ID_MODEL_FROM_DATABASE=ValleyView LPIO1 PWM Controller
+ ID_MODEL_FROM_DATABASE=Atom Processor Z36xxx/Z37xxx Series LPIO1 PWM Controller
 
 pci:v00008086d00000F09*
- ID_MODEL_FROM_DATABASE=ValleyView LPIO1 PWM Controller
+ ID_MODEL_FROM_DATABASE=Atom Processor Z36xxx/Z37xxx Series LPIO1 PWM Controller
 
 pci:v00008086d00000F0A*
- ID_MODEL_FROM_DATABASE=ValleyView LPIO1 HSUART Controller #1
-
-pci:v00008086d00000F0B*
- ID_MODEL_FROM_DATABASE=ValleyView LPIO1 HSUART Controller #1
+ ID_MODEL_FROM_DATABASE=Atom Processor Z36xxx/Z37xxx Series LPIO1 HSUART Controller #1
 
 pci:v00008086d00000F0C*
- ID_MODEL_FROM_DATABASE=ValleyView LPIO1 HSUART Controller #2
-
-pci:v00008086d00000F0D*
- ID_MODEL_FROM_DATABASE=ValleyView LPIO1 HSUART Controller #2
+ ID_MODEL_FROM_DATABASE=Atom Processor Z36xxx/Z37xxx Series LPIO1 HSUART Controller #2
 
 pci:v00008086d00000F0E*
- ID_MODEL_FROM_DATABASE=ValleyView LPIO1 SPI Controller
-
-pci:v00008086d00000F0F*
- ID_MODEL_FROM_DATABASE=ValleyView LPIO1 SPI Controller
-
-pci:v00008086d00000F10*
- ID_MODEL_FROM_DATABASE=ValleyView LPIO1 Controller
-
-pci:v00008086d00000F11*
- ID_MODEL_FROM_DATABASE=ValleyView LPIO1 Controller
-
-pci:v00008086d00000F12*
- ID_MODEL_FROM_DATABASE=ValleyView SMBus Controller
-
-pci:v00008086d00000F13*
- ID_MODEL_FROM_DATABASE=ValleyView SMBus Controller
+ ID_MODEL_FROM_DATABASE=Atom Processor Z36xxx/Z37xxx Series LPIO1 SPI Controller
 
 pci:v00008086d00000F14*
- ID_MODEL_FROM_DATABASE=ValleyView SDIO Controller
+ ID_MODEL_FROM_DATABASE=Atom Processor Z36xxx/Z37xxx Series SDIO Controller
 
 pci:v00008086d00000F15*
- ID_MODEL_FROM_DATABASE=ValleyView SDIO Controller
+ ID_MODEL_FROM_DATABASE=Atom Processor Z36xxx/Z37xxx Series SDIO Controller
 
 pci:v00008086d00000F16*
- ID_MODEL_FROM_DATABASE=ValleyView SDIO Controller
-
-pci:v00008086d00000F17*
- ID_MODEL_FROM_DATABASE=ValleyView SDIO Controller
+ ID_MODEL_FROM_DATABASE=Atom Processor Z36xxx/Z37xxx Series SDIO Controller
 
 pci:v00008086d00000F18*
- ID_MODEL_FROM_DATABASE=ValleyView SEC
-
-pci:v00008086d00000F19*
- ID_MODEL_FROM_DATABASE=ValleyView SEC
-
-pci:v00008086d00000F1A*
- ID_MODEL_FROM_DATABASE=ValleyView SEC
-
-pci:v00008086d00000F1B*
- ID_MODEL_FROM_DATABASE=ValleyView SEC
+ ID_MODEL_FROM_DATABASE=Atom Processor Z36xxx/Z37xxx Series Trusted Execution Engine
 
 pci:v00008086d00000F1C*
- ID_MODEL_FROM_DATABASE=ValleyView Power Control Unit
-
-pci:v00008086d00000F1D*
- ID_MODEL_FROM_DATABASE=ValleyView Power Control Unit
-
-pci:v00008086d00000F1E*
- ID_MODEL_FROM_DATABASE=ValleyView Power Control Unit
-
-pci:v00008086d00000F1F*
- ID_MODEL_FROM_DATABASE=ValleyView Power Control Unit
-
-pci:v00008086d00000F20*
- ID_MODEL_FROM_DATABASE=ValleyView 4-Port SATA Storage Controller
-
-pci:v00008086d00000F21*
- ID_MODEL_FROM_DATABASE=ValleyView 4-Port SATA Storage Controller
-
-pci:v00008086d00000F22*
- ID_MODEL_FROM_DATABASE=ValleyView 6-Port SATA AHCI Controller
-
-pci:v00008086d00000F23*
- ID_MODEL_FROM_DATABASE=ValleyView 6-Port SATA AHCI Controller
-
-pci:v00008086d00000F24*
- ID_MODEL_FROM_DATABASE=ValleyView SATA RAID Storage Controller
-
-pci:v00008086d00000F25*
- ID_MODEL_FROM_DATABASE=ValleyView SATA RAID Storage Controller
-
-pci:v00008086d00000F26*
- ID_MODEL_FROM_DATABASE=ValleyView 2-Port SATA Storage Controller
-
-pci:v00008086d00000F27*
- ID_MODEL_FROM_DATABASE=ValleyView 2-Port SATA Storage Controller
+ ID_MODEL_FROM_DATABASE=Atom Processor Z36xxx/Z37xxx Series Power Control Unit
 
 pci:v00008086d00000F28*
- ID_MODEL_FROM_DATABASE=ValleyView LPE Audio Controller
-
-pci:v00008086d00000F29*
- ID_MODEL_FROM_DATABASE=ValleyView LPE Audio Controller
-
-pci:v00008086d00000F2A*
- ID_MODEL_FROM_DATABASE=ValleyView LPE Audio Controller
-
-pci:v00008086d00000F2B*
- ID_MODEL_FROM_DATABASE=ValleyView LPE Audio Controller
-
-pci:v00008086d00000F2E*
- ID_MODEL_FROM_DATABASE=ValleyView SATA RAID Storage Controller
-
-pci:v00008086d00000F2F*
- ID_MODEL_FROM_DATABASE=ValleyView SATA RAID Storage Controller
-
-pci:v00008086d00000F30*
- ID_MODEL_FROM_DATABASE=ValleyView Gen7
+ ID_MODEL_FROM_DATABASE=Atom Processor Z36xxx/Z37xxx Series LPE Audio Controller
 
 pci:v00008086d00000F31*
- ID_MODEL_FROM_DATABASE=ValleyView Gen7
-
-pci:v00008086d00000F32*
- ID_MODEL_FROM_DATABASE=ValleyView Gen7
-
-pci:v00008086d00000F33*
- ID_MODEL_FROM_DATABASE=ValleyView Gen7
+ ID_MODEL_FROM_DATABASE=Atom Processor Z36xxx/Z37xxx Series Graphics & Display
 
 pci:v00008086d00000F34*
- ID_MODEL_FROM_DATABASE=ValleyView USB Enhanced Host Controller
+ ID_MODEL_FROM_DATABASE=Atom Processor Z36xxx/Z37xxx Series USB EHCI
 
 pci:v00008086d00000F35*
- ID_MODEL_FROM_DATABASE=ValleyView USB xHCI Host Controller
-
-pci:v00008086d00000F36*
- ID_MODEL_FROM_DATABASE=ValleyView USB xHCI Host Controller
+ ID_MODEL_FROM_DATABASE=Atom Processor Z36xxx/Z37xxx Series USB xHCI
 
 pci:v00008086d00000F37*
- ID_MODEL_FROM_DATABASE=ValleyView OTG
+ ID_MODEL_FROM_DATABASE=Atom Processor Z36xxx/Z37xxx Series OTG USB Device
 
 pci:v00008086d00000F38*
- ID_MODEL_FROM_DATABASE=ValleyView ISP
-
-pci:v00008086d00000F39*
- ID_MODEL_FROM_DATABASE=ValleyView ISP
-
-pci:v00008086d00000F3A*
- ID_MODEL_FROM_DATABASE=ValleyView ISP
-
-pci:v00008086d00000F3B*
- ID_MODEL_FROM_DATABASE=ValleyView ISP
-
-pci:v00008086d00000F3C*
- ID_MODEL_FROM_DATABASE=ValleyView ISP
-
-pci:v00008086d00000F3D*
- ID_MODEL_FROM_DATABASE=ValleyView ISP
-
-pci:v00008086d00000F3E*
- ID_MODEL_FROM_DATABASE=ValleyView ISP
-
-pci:v00008086d00000F3F*
- ID_MODEL_FROM_DATABASE=ValleyView ISP
+ ID_MODEL_FROM_DATABASE=Atom Processor Z36xxx/Z37xxx Series Camera ISP
 
 pci:v00008086d00000F40*
- ID_MODEL_FROM_DATABASE=ValleyView LPIO2 DMA Controller
+ ID_MODEL_FROM_DATABASE=Atom Processor Z36xxx/Z37xxx Series LPIO2 DMA Controller
 
 pci:v00008086d00000F41*
- ID_MODEL_FROM_DATABASE=ValleyView LPIO2 I2C Controller #1
+ ID_MODEL_FROM_DATABASE=Atom Processor Z36xxx/Z37xxx Series LPIO2 I2C Controller #1
 
 pci:v00008086d00000F42*
- ID_MODEL_FROM_DATABASE=ValleyView LPIO2 I2C Controller #2
+ ID_MODEL_FROM_DATABASE=Atom Processor Z36xxx/Z37xxx Series LPIO2 I2C Controller #2
 
 pci:v00008086d00000F43*
- ID_MODEL_FROM_DATABASE=ValleyView LPIO2 I2C Controller #3
+ ID_MODEL_FROM_DATABASE=Atom Processor Z36xxx/Z37xxx Series LPIO2 I2C Controller #3
 
 pci:v00008086d00000F44*
- ID_MODEL_FROM_DATABASE=ValleyView LPIO2 I2C Controller #4
+ ID_MODEL_FROM_DATABASE=Atom Processor Z36xxx/Z37xxx Series LPIO2 I2C Controller #4
 
 pci:v00008086d00000F45*
- ID_MODEL_FROM_DATABASE=ValleyView LPIO2 I2C Controller #5
+ ID_MODEL_FROM_DATABASE=Atom Processor Z36xxx/Z37xxx Series LPIO2 I2C Controller #5
 
 pci:v00008086d00000F46*
- ID_MODEL_FROM_DATABASE=ValleyView LPIO2 I2C Controller #6
+ ID_MODEL_FROM_DATABASE=Atom Processor Z36xxx/Z37xxx Series LPIO2 I2C Controller #6
 
 pci:v00008086d00000F47*
- ID_MODEL_FROM_DATABASE=ValleyView LPIO2 I2C Controller #7
-
-pci:v00008086d00000F48*
- ID_MODEL_FROM_DATABASE=ValleyView PCI Express Root Port
-
-pci:v00008086d00000F49*
- ID_MODEL_FROM_DATABASE=ValleyView PCI Express Root Port
-
-pci:v00008086d00000F4A*
- ID_MODEL_FROM_DATABASE=ValleyView PCI Express Root Port
-
-pci:v00008086d00000F4B*
- ID_MODEL_FROM_DATABASE=ValleyView PCI Express Root Port
-
-pci:v00008086d00000F4C*
- ID_MODEL_FROM_DATABASE=ValleyView PCI Express Root Port
-
-pci:v00008086d00000F4D*
- ID_MODEL_FROM_DATABASE=ValleyView PCI Express Root Port
-
-pci:v00008086d00000F4E*
- ID_MODEL_FROM_DATABASE=ValleyView PCI Express Root Port
-
-pci:v00008086d00000F4F*
- ID_MODEL_FROM_DATABASE=ValleyView PCI Express Root Port
-
-pci:v00008086d00000F50*
- ID_MODEL_FROM_DATABASE=ValleyView MIPI-HSI Controller
+ ID_MODEL_FROM_DATABASE=Atom Processor Z36xxx/Z37xxx Series LPIO2 I2C Controller #7
 
 pci:v00008086d00001000*
  ID_MODEL_FROM_DATABASE=82542 Gigabit Ethernet Controller (Fiber)
 
 pci:v00008086d00001000sv00000E11sd0000B0DF*
- ID_MODEL_FROM_DATABASE=NC6132 Gigabit Ethernet Adapter (1000-SX)
+ ID_MODEL_FROM_DATABASE=82542 Gigabit Ethernet Controller (Fiber) (NC6132 Gigabit Ethernet Adapter (1000-SX))
 
 pci:v00008086d00001000sv00000E11sd0000B0E0*
- ID_MODEL_FROM_DATABASE=NC6133 Gigabit Ethernet Adapter (1000-LX)
+ ID_MODEL_FROM_DATABASE=82542 Gigabit Ethernet Controller (Fiber) (NC6133 Gigabit Ethernet Adapter (1000-LX))
 
 pci:v00008086d00001000sv00000E11sd0000B123*
- ID_MODEL_FROM_DATABASE=NC6134 Gigabit Ethernet Adapter (1000-LX)
+ ID_MODEL_FROM_DATABASE=82542 Gigabit Ethernet Controller (Fiber) (NC6134 Gigabit Ethernet Adapter (1000-LX))
 
 pci:v00008086d00001000sv00001014sd00000119*
- ID_MODEL_FROM_DATABASE=Netfinity Gigabit Ethernet SX Adapter
+ ID_MODEL_FROM_DATABASE=82542 Gigabit Ethernet Controller (Fiber) (Netfinity Gigabit Ethernet SX Adapter)
 
 pci:v00008086d00001000sv00008086sd00001000*
- ID_MODEL_FROM_DATABASE=PRO/1000 Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=82542 Gigabit Ethernet Controller (Fiber) (PRO/1000 Gigabit Server Adapter)
 
 pci:v00008086d00001001*
  ID_MODEL_FROM_DATABASE=82543GC Gigabit Ethernet Controller (Fiber)
 
 pci:v00008086d00001001sv00000E11sd0000004A*
- ID_MODEL_FROM_DATABASE=NC6136 Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=82543GC Gigabit Ethernet Controller (Fiber) (NC6136 Gigabit Server Adapter)
 
 pci:v00008086d00001001sv00001014sd000001EA*
- ID_MODEL_FROM_DATABASE=Netfinity Gigabit Ethernet SX Adapter
+ ID_MODEL_FROM_DATABASE=82543GC Gigabit Ethernet Controller (Fiber) (Netfinity Gigabit Ethernet SX Adapter)
 
 pci:v00008086d00001001sv00008086sd00001002*
- ID_MODEL_FROM_DATABASE=PRO/1000 F Server Adapter
+ ID_MODEL_FROM_DATABASE=82543GC Gigabit Ethernet Controller (Fiber) (PRO/1000 F Server Adapter)
 
 pci:v00008086d00001001sv00008086sd00001003*
- ID_MODEL_FROM_DATABASE=PRO/1000 F Server Adapter
+ ID_MODEL_FROM_DATABASE=82543GC Gigabit Ethernet Controller (Fiber) (PRO/1000 F Server Adapter)
 
 pci:v00008086d00001002*
  ID_MODEL_FROM_DATABASE=Pro 100 LAN+Modem 56 Cardbus II
@@ -55758,64 +57150,64 @@ pci:v00008086d00001002sv00008086sd0000200E*
  ID_MODEL_FROM_DATABASE=Pro 100 LAN+Modem 56 Cardbus II
 
 pci:v00008086d00001002sv00008086sd00002013*
- ID_MODEL_FROM_DATABASE=Pro 100 SR Mobile Combo Adapter
+ ID_MODEL_FROM_DATABASE=Pro 100 LAN+Modem 56 Cardbus II (Pro 100 SR Mobile Combo Adapter)
 
 pci:v00008086d00001002sv00008086sd00002017*
- ID_MODEL_FROM_DATABASE=Pro 100 S Combo Mobile Adapter
+ ID_MODEL_FROM_DATABASE=Pro 100 LAN+Modem 56 Cardbus II (Pro 100 S Combo Mobile Adapter)
 
 pci:v00008086d00001004*
  ID_MODEL_FROM_DATABASE=82543GC Gigabit Ethernet Controller (Copper)
 
 pci:v00008086d00001004sv00000E11sd00000049*
- ID_MODEL_FROM_DATABASE=NC7132 Gigabit Upgrade Module
+ ID_MODEL_FROM_DATABASE=82543GC Gigabit Ethernet Controller (Copper) (NC7132 Gigabit Upgrade Module)
 
 pci:v00008086d00001004sv00000E11sd0000B1A4*
- ID_MODEL_FROM_DATABASE=NC7131 Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=82543GC Gigabit Ethernet Controller (Copper) (NC7131 Gigabit Server Adapter)
 
 pci:v00008086d00001004sv00001014sd000010F2*
- ID_MODEL_FROM_DATABASE=Gigabit Ethernet Server Adapter
+ ID_MODEL_FROM_DATABASE=82543GC Gigabit Ethernet Controller (Copper) (Gigabit Ethernet Server Adapter)
 
 pci:v00008086d00001004sv00008086sd00001004*
- ID_MODEL_FROM_DATABASE=PRO/1000 T Server Adapter
+ ID_MODEL_FROM_DATABASE=82543GC Gigabit Ethernet Controller (Copper) (PRO/1000 T Server Adapter)
 
 pci:v00008086d00001004sv00008086sd00002004*
- ID_MODEL_FROM_DATABASE=PRO/1000 T Server Adapter
+ ID_MODEL_FROM_DATABASE=82543GC Gigabit Ethernet Controller (Copper) (PRO/1000 T Server Adapter)
 
 pci:v00008086d00001008*
  ID_MODEL_FROM_DATABASE=82544EI Gigabit Ethernet Controller (Copper)
 
 pci:v00008086d00001008sv00001014sd00000269*
- ID_MODEL_FROM_DATABASE=iSeries 1000/100/10 Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=82544EI Gigabit Ethernet Controller (Copper) (iSeries 1000/100/10 Ethernet Adapter)
 
 pci:v00008086d00001008sv00001028sd0000011B*
- ID_MODEL_FROM_DATABASE=PowerEdge 1650/2550
+ ID_MODEL_FROM_DATABASE=82544EI Gigabit Ethernet Controller (Copper) (PowerEdge 1650/2550)
 
 pci:v00008086d00001008sv00001028sd0000011C*
- ID_MODEL_FROM_DATABASE=PRO/1000 XT Network Connection
+ ID_MODEL_FROM_DATABASE=82544EI Gigabit Ethernet Controller (Copper) (PRO/1000 XT Network Connection)
 
 pci:v00008086d00001008sv00008086sd00001107*
- ID_MODEL_FROM_DATABASE=PRO/1000 XT Server Adapter
+ ID_MODEL_FROM_DATABASE=82544EI Gigabit Ethernet Controller (Copper) (PRO/1000 XT Server Adapter)
 
 pci:v00008086d00001008sv00008086sd00002107*
- ID_MODEL_FROM_DATABASE=PRO/1000 XT Server Adapter
+ ID_MODEL_FROM_DATABASE=82544EI Gigabit Ethernet Controller (Copper) (PRO/1000 XT Server Adapter)
 
 pci:v00008086d00001008sv00008086sd00002110*
- ID_MODEL_FROM_DATABASE=PRO/1000 XT Desktop Adapter
+ ID_MODEL_FROM_DATABASE=82544EI Gigabit Ethernet Controller (Copper) (PRO/1000 XT Desktop Adapter)
 
 pci:v00008086d00001008sv00008086sd00003108*
- ID_MODEL_FROM_DATABASE=PRO/1000 XT Network Connection
+ ID_MODEL_FROM_DATABASE=82544EI Gigabit Ethernet Controller (Copper) (PRO/1000 XT Network Connection)
 
 pci:v00008086d00001009*
  ID_MODEL_FROM_DATABASE=82544EI Gigabit Ethernet Controller (Fiber)
 
 pci:v00008086d00001009sv00001014sd00000268*
- ID_MODEL_FROM_DATABASE=iSeries Gigabit Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=82544EI Gigabit Ethernet Controller (Fiber) (iSeries Gigabit Ethernet Adapter)
 
 pci:v00008086d00001009sv00008086sd00001109*
- ID_MODEL_FROM_DATABASE=PRO/1000 XF Server Adapter
+ ID_MODEL_FROM_DATABASE=82544EI Gigabit Ethernet Controller (Fiber) (PRO/1000 XF Server Adapter)
 
 pci:v00008086d00001009sv00008086sd00002109*
- ID_MODEL_FROM_DATABASE=PRO/1000 XF Server Adapter
+ ID_MODEL_FROM_DATABASE=82544EI Gigabit Ethernet Controller (Fiber) (PRO/1000 XF Server Adapter)
 
 pci:v00008086d0000100A*
  ID_MODEL_FROM_DATABASE=82540EM Gigabit Ethernet Controller
@@ -55824,280 +57216,286 @@ pci:v00008086d0000100C*
  ID_MODEL_FROM_DATABASE=82544GC Gigabit Ethernet Controller (Copper)
 
 pci:v00008086d0000100Csv00008086sd00001112*
- ID_MODEL_FROM_DATABASE=PRO/1000 T Desktop Adapter
+ ID_MODEL_FROM_DATABASE=82544GC Gigabit Ethernet Controller (Copper) (PRO/1000 T Desktop Adapter)
 
 pci:v00008086d0000100Csv00008086sd00002112*
- ID_MODEL_FROM_DATABASE=PRO/1000 T Desktop Adapter
+ ID_MODEL_FROM_DATABASE=82544GC Gigabit Ethernet Controller (Copper) (PRO/1000 T Desktop Adapter)
 
 pci:v00008086d0000100D*
  ID_MODEL_FROM_DATABASE=82544GC Gigabit Ethernet Controller (LOM)
 
 pci:v00008086d0000100Dsv00001028sd00000123*
- ID_MODEL_FROM_DATABASE=PRO/1000 XT Network Connection
+ ID_MODEL_FROM_DATABASE=82544GC Gigabit Ethernet Controller (LOM) (PRO/1000 XT Network Connection)
 
 pci:v00008086d0000100Dsv00001079sd0000891F*
- ID_MODEL_FROM_DATABASE=82544GC Based Network Connection
+ ID_MODEL_FROM_DATABASE=82544GC Gigabit Ethernet Controller (LOM) (82544GC Based Network Connection)
 
 pci:v00008086d0000100Dsv00004C53sd00001080*
- ID_MODEL_FROM_DATABASE=CT8 mainboard
+ ID_MODEL_FROM_DATABASE=82544GC Gigabit Ethernet Controller (LOM) (CT8 mainboard)
 
 pci:v00008086d0000100Dsv00008086sd0000110D*
- ID_MODEL_FROM_DATABASE=82544GC Based Network Connection
+ ID_MODEL_FROM_DATABASE=82544GC Gigabit Ethernet Controller (LOM) (82544GC Based Network Connection)
 
 pci:v00008086d0000100E*
  ID_MODEL_FROM_DATABASE=82540EM Gigabit Ethernet Controller
 
 pci:v00008086d0000100Esv00001014sd00000265*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Network Connection
+ ID_MODEL_FROM_DATABASE=82540EM Gigabit Ethernet Controller (PRO/1000 MT Network Connection)
 
 pci:v00008086d0000100Esv00001014sd00000267*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Network Connection
+ ID_MODEL_FROM_DATABASE=82540EM Gigabit Ethernet Controller (PRO/1000 MT Network Connection)
 
 pci:v00008086d0000100Esv00001014sd0000026A*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Network Connection
+ ID_MODEL_FROM_DATABASE=82540EM Gigabit Ethernet Controller (PRO/1000 MT Network Connection)
 
 pci:v00008086d0000100Esv00001028sd0000002E*
- ID_MODEL_FROM_DATABASE=Optiplex GX260
+ ID_MODEL_FROM_DATABASE=82540EM Gigabit Ethernet Controller (Optiplex GX260)
 
 pci:v00008086d0000100Esv00001028sd00000134*
- ID_MODEL_FROM_DATABASE=PowerEdge 600SC
+ ID_MODEL_FROM_DATABASE=82540EM Gigabit Ethernet Controller (PowerEdge 600SC)
 
 pci:v00008086d0000100Esv00001028sd00000151*
- ID_MODEL_FROM_DATABASE=Optiplex GX270
+ ID_MODEL_FROM_DATABASE=82540EM Gigabit Ethernet Controller (Optiplex GX270)
 
 pci:v00008086d0000100Esv0000107Bsd00008920*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Desktop Adapter
+ ID_MODEL_FROM_DATABASE=82540EM Gigabit Ethernet Controller (PRO/1000 MT Desktop Adapter)
+
+pci:v00008086d0000100Esv00001AF4sd00001100*
+ ID_MODEL_FROM_DATABASE=82540EM Gigabit Ethernet Controller (QEMU Virtual Machine)
 
 pci:v00008086d0000100Esv00008086sd0000001E*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Desktop Adapter
+ ID_MODEL_FROM_DATABASE=82540EM Gigabit Ethernet Controller (PRO/1000 MT Desktop Adapter)
 
 pci:v00008086d0000100Esv00008086sd0000002E*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Desktop Adapter
+ ID_MODEL_FROM_DATABASE=82540EM Gigabit Ethernet Controller (PRO/1000 MT Desktop Adapter)
 
 pci:v00008086d0000100Esv00008086sd00001376*
- ID_MODEL_FROM_DATABASE=PRO/1000 GT Desktop Adapter
+ ID_MODEL_FROM_DATABASE=82540EM Gigabit Ethernet Controller (PRO/1000 GT Desktop Adapter)
 
 pci:v00008086d0000100Esv00008086sd00001476*
- ID_MODEL_FROM_DATABASE=PRO/1000 GT Desktop Adapter
+ ID_MODEL_FROM_DATABASE=82540EM Gigabit Ethernet Controller (PRO/1000 GT Desktop Adapter)
 
 pci:v00008086d0000100F*
  ID_MODEL_FROM_DATABASE=82545EM Gigabit Ethernet Controller (Copper)
 
 pci:v00008086d0000100Fsv00001014sd00000269*
- ID_MODEL_FROM_DATABASE=iSeries 1000/100/10 Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=82545EM Gigabit Ethernet Controller (Copper) (iSeries 1000/100/10 Ethernet Adapter)
 
 pci:v00008086d0000100Fsv00001014sd0000028E*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Network Connection
+ ID_MODEL_FROM_DATABASE=82545EM Gigabit Ethernet Controller (Copper) (PRO/1000 MT Network Connection)
 
 pci:v00008086d0000100Fsv000015ADsd00000750*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Single Port Adapter
+ ID_MODEL_FROM_DATABASE=82545EM Gigabit Ethernet Controller (Copper) (PRO/1000 MT Single Port Adapter)
 
 pci:v00008086d0000100Fsv00008086sd00001000*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Network Connection
+ ID_MODEL_FROM_DATABASE=82545EM Gigabit Ethernet Controller (Copper) (PRO/1000 MT Network Connection)
 
 pci:v00008086d0000100Fsv00008086sd00001001*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Server Adapter
+ ID_MODEL_FROM_DATABASE=82545EM Gigabit Ethernet Controller (Copper) (PRO/1000 MT Server Adapter)
 
 pci:v00008086d00001010*
  ID_MODEL_FROM_DATABASE=82546EB Gigabit Ethernet Controller (Copper)
 
 pci:v00008086d00001010sv00000E11sd000000DB*
- ID_MODEL_FROM_DATABASE=NC7170 Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=82546EB Gigabit Ethernet Controller (Copper) (NC7170 Gigabit Server Adapter)
 
 pci:v00008086d00001010sv00001014sd0000027C*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Dual Port Network Adapter
+ ID_MODEL_FROM_DATABASE=82546EB Gigabit Ethernet Controller (Copper) (PRO/1000 MT Dual Port Network Adapter)
 
 pci:v00008086d00001010sv000015ADsd00000760*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Dual Port Adapter
+ ID_MODEL_FROM_DATABASE=82546EB Gigabit Ethernet Controller (Copper) (PRO/1000 MT Dual Port Adapter)
 
 pci:v00008086d00001010sv000018FBsd00007872*
- ID_MODEL_FROM_DATABASE=RESlink-X
+ ID_MODEL_FROM_DATABASE=82546EB Gigabit Ethernet Controller (Copper) (RESlink-X)
 
 pci:v00008086d00001010sv00001FC1sd00000026*
- ID_MODEL_FROM_DATABASE=Niagara 2260 Bypass Card
+ ID_MODEL_FROM_DATABASE=82546EB Gigabit Ethernet Controller (Copper) (Niagara 2260 Bypass Card)
 
 pci:v00008086d00001010sv00004C53sd00001080*
- ID_MODEL_FROM_DATABASE=CT8 mainboard
+ ID_MODEL_FROM_DATABASE=82546EB Gigabit Ethernet Controller (Copper) (CT8 mainboard)
 
 pci:v00008086d00001010sv00004C53sd000010A0*
- ID_MODEL_FROM_DATABASE=CA3/CR3 mainboard
+ ID_MODEL_FROM_DATABASE=82546EB Gigabit Ethernet Controller (Copper) (CA3/CR3 mainboard)
 
 pci:v00008086d00001010sv00008086sd00001011*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Dual Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82546EB Gigabit Ethernet Controller (Copper) (PRO/1000 MT Dual Port Server Adapter)
 
 pci:v00008086d00001010sv00008086sd00001012*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Dual Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82546EB Gigabit Ethernet Controller (Copper) (PRO/1000 MT Dual Port Server Adapter)
 
 pci:v00008086d00001010sv00008086sd0000101A*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Dual Port Network Connection
+ ID_MODEL_FROM_DATABASE=82546EB Gigabit Ethernet Controller (Copper) (PRO/1000 MT Dual Port Network Connection)
 
 pci:v00008086d00001010sv00008086sd00003424*
- ID_MODEL_FROM_DATABASE=SE7501HG2 Mainboard
+ ID_MODEL_FROM_DATABASE=82546EB Gigabit Ethernet Controller (Copper) (SE7501HG2 Mainboard)
 
 pci:v00008086d00001011*
  ID_MODEL_FROM_DATABASE=82545EM Gigabit Ethernet Controller (Fiber)
 
 pci:v00008086d00001011sv00001014sd00000268*
- ID_MODEL_FROM_DATABASE=iSeries Gigabit Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=82545EM Gigabit Ethernet Controller (Fiber) (iSeries Gigabit Ethernet Adapter)
 
 pci:v00008086d00001011sv00008086sd00001002*
- ID_MODEL_FROM_DATABASE=PRO/1000 MF Server Adapter
+ ID_MODEL_FROM_DATABASE=82545EM Gigabit Ethernet Controller (Fiber) (PRO/1000 MF Server Adapter)
 
 pci:v00008086d00001011sv00008086sd00001003*
- ID_MODEL_FROM_DATABASE=PRO/1000 MF Server Adapter (LX)
+ ID_MODEL_FROM_DATABASE=82545EM Gigabit Ethernet Controller (Fiber) (PRO/1000 MF Server Adapter (LX))
 
 pci:v00008086d00001012*
  ID_MODEL_FROM_DATABASE=82546EB Gigabit Ethernet Controller (Fiber)
 
 pci:v00008086d00001012sv00000E11sd000000DC*
- ID_MODEL_FROM_DATABASE=NC6170 Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=82546EB Gigabit Ethernet Controller (Fiber) (NC6170 Gigabit Server Adapter)
 
 pci:v00008086d00001012sv00008086sd00001012*
- ID_MODEL_FROM_DATABASE=PRO/1000 MF Dual Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82546EB Gigabit Ethernet Controller (Fiber) (PRO/1000 MF Dual Port Server Adapter)
 
 pci:v00008086d00001013*
  ID_MODEL_FROM_DATABASE=82541EI Gigabit Ethernet Controller
 
 pci:v00008086d00001013sv00008086sd00000013*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Network Connection
+ ID_MODEL_FROM_DATABASE=82541EI Gigabit Ethernet Controller (PRO/1000 MT Network Connection)
 
 pci:v00008086d00001013sv00008086sd00001013*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Network Connection
+ ID_MODEL_FROM_DATABASE=82541EI Gigabit Ethernet Controller (PRO/1000 MT Network Connection)
 
 pci:v00008086d00001013sv00008086sd00001113*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Desktop Adapter
+ ID_MODEL_FROM_DATABASE=82541EI Gigabit Ethernet Controller (PRO/1000 MT Desktop Adapter)
 
 pci:v00008086d00001014*
  ID_MODEL_FROM_DATABASE=82541ER Gigabit Ethernet Controller
 
 pci:v00008086d00001014sv00008086sd00000014*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Desktop Connection
+ ID_MODEL_FROM_DATABASE=82541ER Gigabit Ethernet Controller (PRO/1000 MT Desktop Connection)
 
 pci:v00008086d00001014sv00008086sd00001014*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Network Connection
+ ID_MODEL_FROM_DATABASE=82541ER Gigabit Ethernet Controller (PRO/1000 MT Network Connection)
 
 pci:v00008086d00001015*
  ID_MODEL_FROM_DATABASE=82540EM Gigabit Ethernet Controller (LOM)
 
 pci:v00008086d00001015sv00008086sd00001015*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Mobile Connection
+ ID_MODEL_FROM_DATABASE=82540EM Gigabit Ethernet Controller (LOM) (PRO/1000 MT Mobile Connection)
 
 pci:v00008086d00001016*
  ID_MODEL_FROM_DATABASE=82540EP Gigabit Ethernet Controller (Mobile)
 
 pci:v00008086d00001016sv00001014sd0000052C*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Mobile Connection
+ ID_MODEL_FROM_DATABASE=82540EP Gigabit Ethernet Controller (Mobile) (PRO/1000 MT Mobile Connection)
 
 pci:v00008086d00001016sv00001179sd00000001*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Mobile Connection
+ ID_MODEL_FROM_DATABASE=82540EP Gigabit Ethernet Controller (Mobile) (PRO/1000 MT Mobile Connection)
 
 pci:v00008086d00001016sv00008086sd00001016*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Mobile Connection
+ ID_MODEL_FROM_DATABASE=82540EP Gigabit Ethernet Controller (Mobile) (PRO/1000 MT Mobile Connection)
 
 pci:v00008086d00001017*
  ID_MODEL_FROM_DATABASE=82540EP Gigabit Ethernet Controller
 
 pci:v00008086d00001017sv00008086sd00001017*
- ID_MODEL_FROM_DATABASE=PR0/1000 MT Desktop Connection
+ ID_MODEL_FROM_DATABASE=82540EP Gigabit Ethernet Controller (PR0/1000 MT Desktop Connection)
 
 pci:v00008086d00001018*
  ID_MODEL_FROM_DATABASE=82541EI Gigabit Ethernet Controller
 
 pci:v00008086d00001018sv00008086sd00001018*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Mobile Connection
+ ID_MODEL_FROM_DATABASE=82541EI Gigabit Ethernet Controller (PRO/1000 MT Mobile Connection)
 
 pci:v00008086d00001019*
  ID_MODEL_FROM_DATABASE=82547EI Gigabit Ethernet Controller
 
 pci:v00008086d00001019sv00001458sd00001019*
- ID_MODEL_FROM_DATABASE=GA-8IPE1000 Pro2 motherboard (865PE)
+ ID_MODEL_FROM_DATABASE=82547EI Gigabit Ethernet Controller (GA-8IPE1000 Pro2 motherboard (865PE))
 
 pci:v00008086d00001019sv00001458sd0000E000*
- ID_MODEL_FROM_DATABASE=Intel Gigabit Ethernet (Kenai II)
+ ID_MODEL_FROM_DATABASE=82547EI Gigabit Ethernet Controller (Intel Gigabit Ethernet (Kenai II))
 
 pci:v00008086d00001019sv00008086sd00001019*
- ID_MODEL_FROM_DATABASE=PRO/1000 CT Desktop Connection
+ ID_MODEL_FROM_DATABASE=82547EI Gigabit Ethernet Controller (PRO/1000 CT Desktop Connection)
 
 pci:v00008086d00001019sv00008086sd0000301F*
- ID_MODEL_FROM_DATABASE=D865PERL mainboard
+ ID_MODEL_FROM_DATABASE=82547EI Gigabit Ethernet Controller (D865PERL mainboard)
 
 pci:v00008086d00001019sv00008086sd00003025*
- ID_MODEL_FROM_DATABASE=D875PBZ motherboard
+ ID_MODEL_FROM_DATABASE=82547EI Gigabit Ethernet Controller (D875PBZ motherboard)
 
 pci:v00008086d00001019sv00008086sd0000302C*
- ID_MODEL_FROM_DATABASE=Intel 82865G Mainboard (D865GBF)
+ ID_MODEL_FROM_DATABASE=82547EI Gigabit Ethernet Controller (Intel 82865G Mainboard (D865GBF))
 
 pci:v00008086d00001019sv00008086sd00003427*
- ID_MODEL_FROM_DATABASE=S875WP1-E mainboard
+ ID_MODEL_FROM_DATABASE=82547EI Gigabit Ethernet Controller (S875WP1-E mainboard)
 
 pci:v00008086d0000101A*
  ID_MODEL_FROM_DATABASE=82547EI Gigabit Ethernet Controller (Mobile)
 
 pci:v00008086d0000101Asv00008086sd0000101A*
- ID_MODEL_FROM_DATABASE=PRO/1000 CT Mobile Connection
+ ID_MODEL_FROM_DATABASE=82547EI Gigabit Ethernet Controller (Mobile) (PRO/1000 CT Mobile Connection)
 
 pci:v00008086d0000101D*
  ID_MODEL_FROM_DATABASE=82546EB Gigabit Ethernet Controller
 
 pci:v00008086d0000101Dsv00008086sd00001000*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Quad Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82546EB Gigabit Ethernet Controller (PRO/1000 MT Quad Port Server Adapter)
 
 pci:v00008086d0000101E*
  ID_MODEL_FROM_DATABASE=82540EP Gigabit Ethernet Controller (Mobile)
 
 pci:v00008086d0000101Esv00001014sd00000549*
- ID_MODEL_FROM_DATABASE=Thinkpad
+ ID_MODEL_FROM_DATABASE=82540EP Gigabit Ethernet Controller (Mobile) (Thinkpad)
 
 pci:v00008086d0000101Esv00001179sd00000001*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Mobile Connection
+ ID_MODEL_FROM_DATABASE=82540EP Gigabit Ethernet Controller (Mobile) (PRO/1000 MT Mobile Connection)
 
 pci:v00008086d0000101Esv00008086sd0000101E*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Mobile Connection
+ ID_MODEL_FROM_DATABASE=82540EP Gigabit Ethernet Controller (Mobile) (PRO/1000 MT Mobile Connection)
 
 pci:v00008086d00001026*
  ID_MODEL_FROM_DATABASE=82545GM Gigabit Ethernet Controller
 
+pci:v00008086d00001026sv00001028sd00000168*
+ ID_MODEL_FROM_DATABASE=82545GM Gigabit Ethernet Controller (Precision Workstation 670 Mainboard)
+
 pci:v00008086d00001026sv00001028sd00000169*
- ID_MODEL_FROM_DATABASE=Precision 470
+ ID_MODEL_FROM_DATABASE=82545GM Gigabit Ethernet Controller (Precision 470)
 
 pci:v00008086d00001026sv00008086sd00001000*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Server Connection
+ ID_MODEL_FROM_DATABASE=82545GM Gigabit Ethernet Controller (PRO/1000 MT Server Connection)
 
 pci:v00008086d00001026sv00008086sd00001001*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Server Adapter
+ ID_MODEL_FROM_DATABASE=82545GM Gigabit Ethernet Controller (PRO/1000 MT Server Adapter)
 
 pci:v00008086d00001026sv00008086sd00001002*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Server Adapter
+ ID_MODEL_FROM_DATABASE=82545GM Gigabit Ethernet Controller (PRO/1000 MT Server Adapter)
 
 pci:v00008086d00001026sv00008086sd00001003*
- ID_MODEL_FROM_DATABASE=PRO/1000 GT Server Adapter
+ ID_MODEL_FROM_DATABASE=82545GM Gigabit Ethernet Controller (PRO/1000 GT Server Adapter)
 
 pci:v00008086d00001026sv00008086sd00001026*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Server Connection
+ ID_MODEL_FROM_DATABASE=82545GM Gigabit Ethernet Controller (PRO/1000 MT Server Connection)
 
 pci:v00008086d00001027*
  ID_MODEL_FROM_DATABASE=82545GM Gigabit Ethernet Controller
 
 pci:v00008086d00001027sv0000103Csd00003103*
- ID_MODEL_FROM_DATABASE=NC310F PCI-X Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=82545GM Gigabit Ethernet Controller (NC310F PCI-X Gigabit Server Adapter)
 
 pci:v00008086d00001027sv00008086sd00001001*
- ID_MODEL_FROM_DATABASE=PRO/1000 MF Server Adapter(LX)
+ ID_MODEL_FROM_DATABASE=82545GM Gigabit Ethernet Controller (PRO/1000 MF Server Adapter(LX))
 
 pci:v00008086d00001027sv00008086sd00001002*
- ID_MODEL_FROM_DATABASE=PRO/1000 MF Server Adapter(LX)
+ ID_MODEL_FROM_DATABASE=82545GM Gigabit Ethernet Controller (PRO/1000 MF Server Adapter(LX))
 
 pci:v00008086d00001027sv00008086sd00001003*
- ID_MODEL_FROM_DATABASE=PRO/1000 MF Server Adapter(LX)
+ ID_MODEL_FROM_DATABASE=82545GM Gigabit Ethernet Controller (PRO/1000 MF Server Adapter(LX))
 
 pci:v00008086d00001027sv00008086sd00001027*
- ID_MODEL_FROM_DATABASE=PRO/1000 MF Server Adapter
+ ID_MODEL_FROM_DATABASE=82545GM Gigabit Ethernet Controller (PRO/1000 MF Server Adapter)
 
 pci:v00008086d00001028*
  ID_MODEL_FROM_DATABASE=82545GM Gigabit Ethernet Controller
 
 pci:v00008086d00001028sv00008086sd00001028*
- ID_MODEL_FROM_DATABASE=PRO/1000 MB Server Connection
+ ID_MODEL_FROM_DATABASE=82545GM Gigabit Ethernet Controller (PRO/1000 MB Server Connection)
 
 pci:v00008086d00001029*
  ID_MODEL_FROM_DATABASE=82559 Ethernet Controller
@@ -56109,31 +57507,31 @@ pci:v00008086d00001031*
  ID_MODEL_FROM_DATABASE=82801CAM (ICH3) PRO/100 VE (LOM) Ethernet Controller
 
 pci:v00008086d00001031sv00001014sd00000209*
- ID_MODEL_FROM_DATABASE=ThinkPad A/T/X Series
+ ID_MODEL_FROM_DATABASE=82801CAM (ICH3) PRO/100 VE (LOM) Ethernet Controller (ThinkPad A/T/X Series)
 
 pci:v00008086d00001031sv0000104Dsd000080E7*
- ID_MODEL_FROM_DATABASE=Vaio PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
+ ID_MODEL_FROM_DATABASE=82801CAM (ICH3) PRO/100 VE (LOM) Ethernet Controller (Vaio PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP)
 
 pci:v00008086d00001031sv0000104Dsd0000813C*
- ID_MODEL_FROM_DATABASE=Vaio PCG-GRV616G
+ ID_MODEL_FROM_DATABASE=82801CAM (ICH3) PRO/100 VE (LOM) Ethernet Controller (Vaio PCG-GRV616G)
 
 pci:v00008086d00001031sv0000107Bsd00005350*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 VE
+ ID_MODEL_FROM_DATABASE=82801CAM (ICH3) PRO/100 VE (LOM) Ethernet Controller (EtherExpress PRO/100 VE)
 
 pci:v00008086d00001031sv00001179sd00000001*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 VE
+ ID_MODEL_FROM_DATABASE=82801CAM (ICH3) PRO/100 VE (LOM) Ethernet Controller (EtherExpress PRO/100 VE)
 
 pci:v00008086d00001031sv0000144Dsd0000C000*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 VE
+ ID_MODEL_FROM_DATABASE=82801CAM (ICH3) PRO/100 VE (LOM) Ethernet Controller (EtherExpress PRO/100 VE)
 
 pci:v00008086d00001031sv0000144Dsd0000C001*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 VE
+ ID_MODEL_FROM_DATABASE=82801CAM (ICH3) PRO/100 VE (LOM) Ethernet Controller (EtherExpress PRO/100 VE)
 
 pci:v00008086d00001031sv0000144Dsd0000C003*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 VE
+ ID_MODEL_FROM_DATABASE=82801CAM (ICH3) PRO/100 VE (LOM) Ethernet Controller (EtherExpress PRO/100 VE)
 
 pci:v00008086d00001031sv0000144Dsd0000C006*
- ID_MODEL_FROM_DATABASE=vpr Matrix 170B4
+ ID_MODEL_FROM_DATABASE=82801CAM (ICH3) PRO/100 VE (LOM) Ethernet Controller (vpr Matrix 170B4)
 
 pci:v00008086d00001032*
  ID_MODEL_FROM_DATABASE=82801CAM (ICH3) PRO/100 VE Ethernet Controller
@@ -56157,16 +57555,16 @@ pci:v00008086d00001038*
  ID_MODEL_FROM_DATABASE=82801CAM (ICH3) PRO/100 VM (KM) Ethernet Controller
 
 pci:v00008086d00001038sv00000E11sd00000098*
- ID_MODEL_FROM_DATABASE=Evo N600c
+ ID_MODEL_FROM_DATABASE=82801CAM (ICH3) PRO/100 VM (KM) Ethernet Controller (Evo N600c)
 
 pci:v00008086d00001039*
  ID_MODEL_FROM_DATABASE=82801DB PRO/100 VE (LOM) Ethernet Controller
 
 pci:v00008086d00001039sv00001014sd00000267*
- ID_MODEL_FROM_DATABASE=NetVista A30p
+ ID_MODEL_FROM_DATABASE=82801DB PRO/100 VE (LOM) Ethernet Controller (NetVista A30p)
 
 pci:v00008086d00001039sv0000114Asd00000582*
- ID_MODEL_FROM_DATABASE=PC8 onboard ethernet ETH1
+ ID_MODEL_FROM_DATABASE=82801DB PRO/100 VE (LOM) Ethernet Controller (PC8 onboard ethernet ETH1)
 
 pci:v00008086d0000103A*
  ID_MODEL_FROM_DATABASE=82801DB PRO/100 VE (CNR) Ethernet Controller
@@ -56181,13 +57579,13 @@ pci:v00008086d0000103D*
  ID_MODEL_FROM_DATABASE=82801DB PRO/100 VE (MOB) Ethernet Controller
 
 pci:v00008086d0000103Dsv00001014sd00000522*
- ID_MODEL_FROM_DATABASE=ThinkPad R40
+ ID_MODEL_FROM_DATABASE=82801DB PRO/100 VE (MOB) Ethernet Controller (ThinkPad R40)
 
 pci:v00008086d0000103Dsv00001028sd00002002*
- ID_MODEL_FROM_DATABASE=Latitude D500
+ ID_MODEL_FROM_DATABASE=82801DB PRO/100 VE (MOB) Ethernet Controller (Latitude D500)
 
 pci:v00008086d0000103Dsv00008086sd0000103D*
- ID_MODEL_FROM_DATABASE=82562EZ 10/100 Ethernet Controller
+ ID_MODEL_FROM_DATABASE=82801DB PRO/100 VE (MOB) Ethernet Controller (82562EZ 10/100 Ethernet Controller)
 
 pci:v00008086d0000103E*
  ID_MODEL_FROM_DATABASE=82801DB PRO/100 VM (MOB) Ethernet Controller
@@ -56196,43 +57594,43 @@ pci:v00008086d00001040*
  ID_MODEL_FROM_DATABASE=536EP Data Fax Modem
 
 pci:v00008086d00001040sv000016BEsd00001040*
- ID_MODEL_FROM_DATABASE=V.9X DSP Data Fax Modem
+ ID_MODEL_FROM_DATABASE=536EP Data Fax Modem (V.9X DSP Data Fax Modem)
 
 pci:v00008086d00001043*
  ID_MODEL_FROM_DATABASE=PRO/Wireless LAN 2100 3B Mini PCI Adapter
 
 pci:v00008086d00001043sv0000103Csd000008B0*
- ID_MODEL_FROM_DATABASE=tc1100 tablet
+ ID_MODEL_FROM_DATABASE=PRO/Wireless LAN 2100 3B Mini PCI Adapter (tc1100 tablet)
 
 pci:v00008086d00001043sv00008086sd00002522*
- ID_MODEL_FROM_DATABASE=Samsung X10/P30 integrated WLAN
+ ID_MODEL_FROM_DATABASE=PRO/Wireless LAN 2100 3B Mini PCI Adapter (Samsung X10/P30 integrated WLAN)
 
 pci:v00008086d00001043sv00008086sd00002527*
- ID_MODEL_FROM_DATABASE=MIM2000/Centrino
+ ID_MODEL_FROM_DATABASE=PRO/Wireless LAN 2100 3B Mini PCI Adapter (MIM2000/Centrino)
 
 pci:v00008086d00001043sv00008086sd00002561*
- ID_MODEL_FROM_DATABASE=Dell Latitude D800
+ ID_MODEL_FROM_DATABASE=PRO/Wireless LAN 2100 3B Mini PCI Adapter (Dell Latitude D800)
 
 pci:v00008086d00001043sv00008086sd00002581*
- ID_MODEL_FROM_DATABASE=Toshiba Satellite M10
+ ID_MODEL_FROM_DATABASE=PRO/Wireless LAN 2100 3B Mini PCI Adapter (Toshiba Satellite M10)
 
 pci:v00008086d00001048*
  ID_MODEL_FROM_DATABASE=82597EX 10GbE Ethernet Controller
 
 pci:v00008086d00001048sv00008086sd0000A01F*
- ID_MODEL_FROM_DATABASE=PRO/10GbE LR Server Adapter
+ ID_MODEL_FROM_DATABASE=82597EX 10GbE Ethernet Controller (PRO/10GbE LR Server Adapter)
 
 pci:v00008086d00001048sv00008086sd0000A11F*
- ID_MODEL_FROM_DATABASE=PRO/10GbE LR Server Adapter
+ ID_MODEL_FROM_DATABASE=82597EX 10GbE Ethernet Controller (PRO/10GbE LR Server Adapter)
 
 pci:v00008086d00001049*
  ID_MODEL_FROM_DATABASE=82566MM Gigabit Network Connection
 
 pci:v00008086d00001049sv0000103Csd000030C1*
- ID_MODEL_FROM_DATABASE=Compaq 6910p
+ ID_MODEL_FROM_DATABASE=82566MM Gigabit Network Connection (Compaq 6910p)
 
 pci:v00008086d00001049sv000017AAsd000020B9*
- ID_MODEL_FROM_DATABASE=ThinkPad T61/R61
+ ID_MODEL_FROM_DATABASE=82566MM Gigabit Network Connection (ThinkPad T61/R61)
 
 pci:v00008086d0000104A*
  ID_MODEL_FROM_DATABASE=82566DM Gigabit Network Connection
@@ -56250,22 +57648,22 @@ pci:v00008086d00001050*
  ID_MODEL_FROM_DATABASE=82562EZ 10/100 Ethernet Controller
 
 pci:v00008086d00001050sv00001028sd0000019D*
- ID_MODEL_FROM_DATABASE=Dimension 3000
+ ID_MODEL_FROM_DATABASE=82562EZ 10/100 Ethernet Controller (Dimension 3000)
 
 pci:v00008086d00001050sv00001462sd0000728C*
- ID_MODEL_FROM_DATABASE=865PE Neo2 (MS-6728)
+ ID_MODEL_FROM_DATABASE=82562EZ 10/100 Ethernet Controller (865PE Neo2 (MS-6728))
 
 pci:v00008086d00001050sv00001462sd0000758C*
- ID_MODEL_FROM_DATABASE=MS-6758 (875P Neo)
+ ID_MODEL_FROM_DATABASE=82562EZ 10/100 Ethernet Controller (MS-6758 (875P Neo))
 
 pci:v00008086d00001050sv00008086sd00003020*
- ID_MODEL_FROM_DATABASE=D865PERL mainboard
+ ID_MODEL_FROM_DATABASE=82562EZ 10/100 Ethernet Controller (D865PERL mainboard)
 
 pci:v00008086d00001050sv00008086sd0000302F*
- ID_MODEL_FROM_DATABASE=Desktop Board D865GBF
+ ID_MODEL_FROM_DATABASE=82562EZ 10/100 Ethernet Controller (Desktop Board D865GBF)
 
 pci:v00008086d00001050sv00008086sd00003427*
- ID_MODEL_FROM_DATABASE=S875WP1-E mainboard
+ ID_MODEL_FROM_DATABASE=82562EZ 10/100 Ethernet Controller (S875WP1-E mainboard)
 
 pci:v00008086d00001051*
  ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) integrated LAN Controller
@@ -56298,70 +57696,70 @@ pci:v00008086d0000105E*
  ID_MODEL_FROM_DATABASE=82571EB Gigabit Ethernet Controller
 
 pci:v00008086d0000105Esv0000103Csd00007044*
- ID_MODEL_FROM_DATABASE=NC360T PCI Express Dual Port Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=82571EB Gigabit Ethernet Controller (NC360T PCI Express Dual Port Gigabit Server Adapter)
 
 pci:v00008086d0000105Esv0000103Csd0000704E*
- ID_MODEL_FROM_DATABASE=Dual Port 1000Base-T (PCIe) [AD337A]
+ ID_MODEL_FROM_DATABASE=82571EB Gigabit Ethernet Controller (Dual Port 1000Base-T (PCIe) [AD337A])
 
 pci:v00008086d0000105Esv00001775sd00001100*
- ID_MODEL_FROM_DATABASE=CR11/VR11 Single Board Computer
+ ID_MODEL_FROM_DATABASE=82571EB Gigabit Ethernet Controller (CR11/VR11 Single Board Computer)
 
 pci:v00008086d0000105Esv00001775sd00006003*
- ID_MODEL_FROM_DATABASE=Telum GE-QT
+ ID_MODEL_FROM_DATABASE=82571EB Gigabit Ethernet Controller (Telum GE-QT)
 
 pci:v00008086d0000105Esv000018DFsd00001214*
- ID_MODEL_FROM_DATABASE=2x 1GbE, PCIe x1, dual Intel 82571EB chips
+ ID_MODEL_FROM_DATABASE=82571EB Gigabit Ethernet Controller (2x 1GbE, PCIe x1, dual Intel 82571EB chips)
 
 pci:v00008086d0000105Esv00008086sd0000005E*
- ID_MODEL_FROM_DATABASE=PRO/1000 PT Dual Port Server Connection
+ ID_MODEL_FROM_DATABASE=82571EB Gigabit Ethernet Controller (PRO/1000 PT Dual Port Server Connection)
 
 pci:v00008086d0000105Esv00008086sd0000105E*
- ID_MODEL_FROM_DATABASE=PRO/1000 PT Dual Port Network Connection
+ ID_MODEL_FROM_DATABASE=82571EB Gigabit Ethernet Controller (PRO/1000 PT Dual Port Network Connection)
 
 pci:v00008086d0000105Esv00008086sd000010D5*
- ID_MODEL_FROM_DATABASE=82571PT Gigabit PT Quad Port Server ExpressModule
+ ID_MODEL_FROM_DATABASE=82571EB Gigabit Ethernet Controller (82571PT Gigabit PT Quad Port Server ExpressModule)
 
 pci:v00008086d0000105Esv00008086sd0000115E*
- ID_MODEL_FROM_DATABASE=PRO/1000 PT Dual Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82571EB Gigabit Ethernet Controller (PRO/1000 PT Dual Port Server Adapter)
 
 pci:v00008086d0000105Esv00008086sd0000125E*
- ID_MODEL_FROM_DATABASE=PRO/1000 PT Dual Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82571EB Gigabit Ethernet Controller (PRO/1000 PT Dual Port Server Adapter)
 
 pci:v00008086d0000105Esv00008086sd0000135E*
- ID_MODEL_FROM_DATABASE=PRO/1000 PT Dual Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82571EB Gigabit Ethernet Controller (PRO/1000 PT Dual Port Server Adapter)
 
 pci:v00008086d0000105F*
  ID_MODEL_FROM_DATABASE=82571EB Gigabit Ethernet Controller
 
 pci:v00008086d0000105Fsv0000103Csd0000704F*
- ID_MODEL_FROM_DATABASE=Dual Port 1000Base-SX (PCIe) [AD338A]
+ ID_MODEL_FROM_DATABASE=82571EB Gigabit Ethernet Controller (Dual Port 1000Base-SX (PCIe) [AD338A])
 
 pci:v00008086d0000105Fsv00008086sd0000005A*
- ID_MODEL_FROM_DATABASE=PRO/1000 PF Dual Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82571EB Gigabit Ethernet Controller (PRO/1000 PF Dual Port Server Adapter)
 
 pci:v00008086d0000105Fsv00008086sd0000115F*
- ID_MODEL_FROM_DATABASE=PRO/1000 PF Dual Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82571EB Gigabit Ethernet Controller (PRO/1000 PF Dual Port Server Adapter)
 
 pci:v00008086d0000105Fsv00008086sd0000125F*
- ID_MODEL_FROM_DATABASE=PRO/1000 PF Dual Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82571EB Gigabit Ethernet Controller (PRO/1000 PF Dual Port Server Adapter)
 
 pci:v00008086d0000105Fsv00008086sd0000135F*
- ID_MODEL_FROM_DATABASE=PRO/1000 PF Dual Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82571EB Gigabit Ethernet Controller (PRO/1000 PF Dual Port Server Adapter)
 
 pci:v00008086d00001060*
  ID_MODEL_FROM_DATABASE=82571EB Gigabit Ethernet Controller
 
 pci:v00008086d00001060sv00008086sd00000060*
- ID_MODEL_FROM_DATABASE=PRO/1000 PB Dual Port Server Connection
+ ID_MODEL_FROM_DATABASE=82571EB Gigabit Ethernet Controller (PRO/1000 PB Dual Port Server Connection)
 
 pci:v00008086d00001060sv00008086sd00001060*
- ID_MODEL_FROM_DATABASE=PRO/1000 PB Dual Port Server Connection
+ ID_MODEL_FROM_DATABASE=82571EB Gigabit Ethernet Controller (PRO/1000 PB Dual Port Server Connection)
 
 pci:v00008086d00001064*
  ID_MODEL_FROM_DATABASE=82562ET/EZ/GT/GZ - PRO/100 VE (LOM) Ethernet Controller
 
 pci:v00008086d00001064sv00001043sd000080F8*
- ID_MODEL_FROM_DATABASE=P5GD1-VW Mainboard
+ ID_MODEL_FROM_DATABASE=82562ET/EZ/GT/GZ - PRO/100 VE (LOM) Ethernet Controller (P5GD1-VW Mainboard)
 
 pci:v00008086d00001065*
  ID_MODEL_FROM_DATABASE=82562ET/EZ/GT/GZ - PRO/100 VE Ethernet Controller
@@ -56388,148 +57786,148 @@ pci:v00008086d00001075*
  ID_MODEL_FROM_DATABASE=82547GI Gigabit Ethernet Controller
 
 pci:v00008086d00001075sv00001028sd00000165*
- ID_MODEL_FROM_DATABASE=PowerEdge 750
+ ID_MODEL_FROM_DATABASE=82547GI Gigabit Ethernet Controller (PowerEdge 750)
 
 pci:v00008086d00001075sv00008086sd00000075*
- ID_MODEL_FROM_DATABASE=PRO/1000 CT Network Connection
+ ID_MODEL_FROM_DATABASE=82547GI Gigabit Ethernet Controller (PRO/1000 CT Network Connection)
 
 pci:v00008086d00001075sv00008086sd00001075*
- ID_MODEL_FROM_DATABASE=PRO/1000 CT Network Connection
+ ID_MODEL_FROM_DATABASE=82547GI Gigabit Ethernet Controller (PRO/1000 CT Network Connection)
 
 pci:v00008086d00001076*
  ID_MODEL_FROM_DATABASE=82541GI Gigabit Ethernet Controller
 
 pci:v00008086d00001076sv00001028sd00000165*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Network Connection
+ ID_MODEL_FROM_DATABASE=82541GI Gigabit Ethernet Controller (PRO/1000 MT Network Connection)
 
 pci:v00008086d00001076sv00001028sd0000016D*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Network Connection
+ ID_MODEL_FROM_DATABASE=82541GI Gigabit Ethernet Controller (PRO/1000 MT Network Connection)
 
 pci:v00008086d00001076sv00001028sd0000019A*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Network Connection
+ ID_MODEL_FROM_DATABASE=82541GI Gigabit Ethernet Controller (PRO/1000 MT Network Connection)
 
 pci:v00008086d00001076sv00001028sd0000106D*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Network Connection
+ ID_MODEL_FROM_DATABASE=82541GI Gigabit Ethernet Controller (PRO/1000 MT Network Connection)
 
 pci:v00008086d00001076sv00008086sd00000076*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Network Connection
+ ID_MODEL_FROM_DATABASE=82541GI Gigabit Ethernet Controller (PRO/1000 MT Network Connection)
 
 pci:v00008086d00001076sv00008086sd00001076*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Network Connection
+ ID_MODEL_FROM_DATABASE=82541GI Gigabit Ethernet Controller (PRO/1000 MT Network Connection)
 
 pci:v00008086d00001076sv00008086sd00001176*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Desktop Adapter
+ ID_MODEL_FROM_DATABASE=82541GI Gigabit Ethernet Controller (PRO/1000 MT Desktop Adapter)
 
 pci:v00008086d00001076sv00008086sd00001276*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Network Adapter
+ ID_MODEL_FROM_DATABASE=82541GI Gigabit Ethernet Controller (PRO/1000 MT Network Adapter)
 
 pci:v00008086d00001077*
  ID_MODEL_FROM_DATABASE=82541GI Gigabit Ethernet Controller
 
 pci:v00008086d00001077sv00001179sd00000001*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Mobile Connection
+ ID_MODEL_FROM_DATABASE=82541GI Gigabit Ethernet Controller (PRO/1000 MT Mobile Connection)
 
 pci:v00008086d00001077sv00008086sd00000077*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Mobile Connection
+ ID_MODEL_FROM_DATABASE=82541GI Gigabit Ethernet Controller (PRO/1000 MT Mobile Connection)
 
 pci:v00008086d00001077sv00008086sd00001077*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Mobile Connection
+ ID_MODEL_FROM_DATABASE=82541GI Gigabit Ethernet Controller (PRO/1000 MT Mobile Connection)
 
 pci:v00008086d00001078*
  ID_MODEL_FROM_DATABASE=82541ER Gigabit Ethernet Controller
 
 pci:v00008086d00001078sv00008086sd00001078*
- ID_MODEL_FROM_DATABASE=82541ER-based Network Connection
+ ID_MODEL_FROM_DATABASE=82541ER Gigabit Ethernet Controller (82541ER-based Network Connection)
 
 pci:v00008086d00001079*
  ID_MODEL_FROM_DATABASE=82546GB Gigabit Ethernet Controller
 
 pci:v00008086d00001079sv0000103Csd000012A6*
- ID_MODEL_FROM_DATABASE=Dual Port 1000Base-T [A9900A]
+ ID_MODEL_FROM_DATABASE=82546GB Gigabit Ethernet Controller (Dual Port 1000Base-T [A9900A])
 
 pci:v00008086d00001079sv0000103Csd000012CF*
- ID_MODEL_FROM_DATABASE=Core Dual Port 1000Base-T [AB352A]
+ ID_MODEL_FROM_DATABASE=82546GB Gigabit Ethernet Controller (Core Dual Port 1000Base-T [AB352A])
 
 pci:v00008086d00001079sv00001775sd000010D0*
- ID_MODEL_FROM_DATABASE=V5D Single Board Computer Gigabit Ethernet
+ ID_MODEL_FROM_DATABASE=82546GB Gigabit Ethernet Controller (V5D Single Board Computer Gigabit Ethernet)
 
 pci:v00008086d00001079sv00001775sd0000CE90*
- ID_MODEL_FROM_DATABASE=CE9
+ ID_MODEL_FROM_DATABASE=82546GB Gigabit Ethernet Controller (CE9)
 
 pci:v00008086d00001079sv00001FC1sd00000027*
- ID_MODEL_FROM_DATABASE=Niagara 2261 Failover NIC
+ ID_MODEL_FROM_DATABASE=82546GB Gigabit Ethernet Controller (Niagara 2261 Failover NIC)
 
 pci:v00008086d00001079sv00004C53sd00001090*
- ID_MODEL_FROM_DATABASE=Cx9 / Vx9 mainboard
+ ID_MODEL_FROM_DATABASE=82546GB Gigabit Ethernet Controller (Cx9 / Vx9 mainboard)
 
 pci:v00008086d00001079sv00004C53sd000010B0*
- ID_MODEL_FROM_DATABASE=CL9 mainboard
+ ID_MODEL_FROM_DATABASE=82546GB Gigabit Ethernet Controller (CL9 mainboard)
 
 pci:v00008086d00001079sv00008086sd00000079*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Dual Port Network Connection
+ ID_MODEL_FROM_DATABASE=82546GB Gigabit Ethernet Controller (PRO/1000 MT Dual Port Network Connection)
 
 pci:v00008086d00001079sv00008086sd00001079*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Dual Port Network Connection
+ ID_MODEL_FROM_DATABASE=82546GB Gigabit Ethernet Controller (PRO/1000 MT Dual Port Network Connection)
 
 pci:v00008086d00001079sv00008086sd00001179*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Dual Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82546GB Gigabit Ethernet Controller (PRO/1000 MT Dual Port Server Adapter)
 
 pci:v00008086d00001079sv00008086sd0000117A*
- ID_MODEL_FROM_DATABASE=PRO/1000 MT Dual Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82546GB Gigabit Ethernet Controller (PRO/1000 MT Dual Port Server Adapter)
 
 pci:v00008086d0000107A*
  ID_MODEL_FROM_DATABASE=82546GB Gigabit Ethernet Controller
 
 pci:v00008086d0000107Asv0000103Csd000012A8*
- ID_MODEL_FROM_DATABASE=Dual Port 1000base-SX [A9899A]
+ ID_MODEL_FROM_DATABASE=82546GB Gigabit Ethernet Controller (Dual Port 1000base-SX [A9899A])
 
 pci:v00008086d0000107Asv00008086sd0000107A*
- ID_MODEL_FROM_DATABASE=PRO/1000 MF Dual Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82546GB Gigabit Ethernet Controller (PRO/1000 MF Dual Port Server Adapter)
 
 pci:v00008086d0000107Asv00008086sd0000127A*
- ID_MODEL_FROM_DATABASE=PRO/1000 MF Dual Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82546GB Gigabit Ethernet Controller (PRO/1000 MF Dual Port Server Adapter)
 
 pci:v00008086d0000107B*
  ID_MODEL_FROM_DATABASE=82546GB Gigabit Ethernet Controller
 
 pci:v00008086d0000107Bsv00008086sd0000007B*
- ID_MODEL_FROM_DATABASE=PRO/1000 MB Dual Port Server Connection
+ ID_MODEL_FROM_DATABASE=82546GB Gigabit Ethernet Controller (PRO/1000 MB Dual Port Server Connection)
 
 pci:v00008086d0000107Bsv00008086sd0000107B*
- ID_MODEL_FROM_DATABASE=PRO/1000 MB Dual Port Server Connection
+ ID_MODEL_FROM_DATABASE=82546GB Gigabit Ethernet Controller (PRO/1000 MB Dual Port Server Connection)
 
 pci:v00008086d0000107C*
  ID_MODEL_FROM_DATABASE=82541PI Gigabit Ethernet Controller
 
 pci:v00008086d0000107Csv00008086sd00001376*
- ID_MODEL_FROM_DATABASE=PRO/1000 GT Desktop Adapter
+ ID_MODEL_FROM_DATABASE=82541PI Gigabit Ethernet Controller (PRO/1000 GT Desktop Adapter)
 
 pci:v00008086d0000107Csv00008086sd00001476*
- ID_MODEL_FROM_DATABASE=PRO/1000 GT Desktop Adapter
+ ID_MODEL_FROM_DATABASE=82541PI Gigabit Ethernet Controller (PRO/1000 GT Desktop Adapter)
 
 pci:v00008086d0000107D*
  ID_MODEL_FROM_DATABASE=82572EI Gigabit Ethernet Controller (Copper)
 
 pci:v00008086d0000107Dsv00008086sd00001082*
- ID_MODEL_FROM_DATABASE=PRO/1000 PT Server Adapter
+ ID_MODEL_FROM_DATABASE=82572EI Gigabit Ethernet Controller (Copper) (PRO/1000 PT Server Adapter)
 
 pci:v00008086d0000107Dsv00008086sd00001084*
- ID_MODEL_FROM_DATABASE=PRO/1000 PT Server Adapter
+ ID_MODEL_FROM_DATABASE=82572EI Gigabit Ethernet Controller (Copper) (PRO/1000 PT Server Adapter)
 
 pci:v00008086d0000107Dsv00008086sd00001092*
- ID_MODEL_FROM_DATABASE=PRO/1000 PT Server Adapter
+ ID_MODEL_FROM_DATABASE=82572EI Gigabit Ethernet Controller (Copper) (PRO/1000 PT Server Adapter)
 
 pci:v00008086d0000107E*
  ID_MODEL_FROM_DATABASE=82572EI Gigabit Ethernet Controller (Fiber)
 
 pci:v00008086d0000107Esv00008086sd00001084*
- ID_MODEL_FROM_DATABASE=PRO/1000 PF Server Adapter
+ ID_MODEL_FROM_DATABASE=82572EI Gigabit Ethernet Controller (Fiber) (PRO/1000 PF Server Adapter)
 
 pci:v00008086d0000107Esv00008086sd00001085*
- ID_MODEL_FROM_DATABASE=PRO/1000 PF Server Adapter
+ ID_MODEL_FROM_DATABASE=82572EI Gigabit Ethernet Controller (Fiber) (PRO/1000 PF Server Adapter)
 
 pci:v00008086d0000107Esv00008086sd00001094*
- ID_MODEL_FROM_DATABASE=PRO/1000 PF Server Adapter
+ ID_MODEL_FROM_DATABASE=82572EI Gigabit Ethernet Controller (Fiber) (PRO/1000 PF Server Adapter)
 
 pci:v00008086d0000107F*
  ID_MODEL_FROM_DATABASE=82572EI Gigabit Ethernet Controller
@@ -56565,16 +57963,16 @@ pci:v00008086d0000108A*
  ID_MODEL_FROM_DATABASE=82546GB Gigabit Ethernet Controller
 
 pci:v00008086d0000108Asv00008086sd0000108A*
- ID_MODEL_FROM_DATABASE=PRO/1000 P Dual Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82546GB Gigabit Ethernet Controller (PRO/1000 P Dual Port Server Adapter)
 
 pci:v00008086d0000108Asv00008086sd0000118A*
- ID_MODEL_FROM_DATABASE=PRO/1000 P Dual Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82546GB Gigabit Ethernet Controller (PRO/1000 P Dual Port Server Adapter)
 
 pci:v00008086d0000108B*
  ID_MODEL_FROM_DATABASE=82573V Gigabit Ethernet Controller (Copper)
 
 pci:v00008086d0000108Bsv00001462sd0000176C*
- ID_MODEL_FROM_DATABASE=on board on MSI 945P - NEO (MS-7176)
+ ID_MODEL_FROM_DATABASE=82573V Gigabit Ethernet Controller (Copper) (on board on MSI 945P - NEO (MS-7176))
 
 pci:v00008086d0000108C*
  ID_MODEL_FROM_DATABASE=82573E Gigabit Ethernet Controller (Copper)
@@ -56591,6 +57989,9 @@ pci:v00008086d00001091*
 pci:v00008086d00001092*
  ID_MODEL_FROM_DATABASE=PRO/100 VE Network Connection
 
+pci:v00008086d00001092sv00001071sd00008209*
+ ID_MODEL_FROM_DATABASE=PRO/100 VE Network Connection (Medion MIM 2240 Notebook PC [MD98100])
+
 pci:v00008086d00001093*
  ID_MODEL_FROM_DATABASE=PRO/100 VM Network Connection
 
@@ -56604,13 +58005,13 @@ pci:v00008086d00001096*
  ID_MODEL_FROM_DATABASE=80003ES2LAN Gigabit Ethernet Controller (Copper)
 
 pci:v00008086d00001096sv000015D9sd00001096*
- ID_MODEL_FROM_DATABASE=Motherboard
+ ID_MODEL_FROM_DATABASE=80003ES2LAN Gigabit Ethernet Controller (Copper) (Motherboard)
 
 pci:v00008086d00001096sv000015D9sd00008680*
- ID_MODEL_FROM_DATABASE=X7DVL-E-O motherboard
+ ID_MODEL_FROM_DATABASE=80003ES2LAN Gigabit Ethernet Controller (Copper) (X7DVL-E-O motherboard)
 
 pci:v00008086d00001096sv00008086sd00003476*
- ID_MODEL_FROM_DATABASE=Intel S5000PSLSATA Server Board
+ ID_MODEL_FROM_DATABASE=80003ES2LAN Gigabit Ethernet Controller (Copper) (Intel S5000PSLSATA Server Board)
 
 pci:v00008086d00001097*
  ID_MODEL_FROM_DATABASE=631xESB/632xESB DPT LAN Controller (Fiber)
@@ -56622,28 +58023,28 @@ pci:v00008086d00001099*
  ID_MODEL_FROM_DATABASE=82546GB Gigabit Ethernet Controller (Copper)
 
 pci:v00008086d00001099sv00008086sd00001099*
- ID_MODEL_FROM_DATABASE=PRO/1000 GT Quad Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82546GB Gigabit Ethernet Controller (Copper) (PRO/1000 GT Quad Port Server Adapter)
 
 pci:v00008086d0000109A*
  ID_MODEL_FROM_DATABASE=82573L Gigabit Ethernet Controller
 
 pci:v00008086d0000109Asv00001179sd0000FF10*
- ID_MODEL_FROM_DATABASE=PRO/1000 PL
+ ID_MODEL_FROM_DATABASE=82573L Gigabit Ethernet Controller (PRO/1000 PL)
 
 pci:v00008086d0000109Asv000017AAsd00002001*
- ID_MODEL_FROM_DATABASE=ThinkPad T60
+ ID_MODEL_FROM_DATABASE=82573L Gigabit Ethernet Controller (ThinkPad T60)
 
 pci:v00008086d0000109Asv000017AAsd0000207E*
- ID_MODEL_FROM_DATABASE=ThinkPad X60s
+ ID_MODEL_FROM_DATABASE=82573L Gigabit Ethernet Controller (ThinkPad X60/X60s)
 
 pci:v00008086d0000109Asv00008086sd0000109A*
- ID_MODEL_FROM_DATABASE=PRO/1000 PL Network Connection
+ ID_MODEL_FROM_DATABASE=82573L Gigabit Ethernet Controller (PRO/1000 PL Network Connection)
 
 pci:v00008086d0000109Asv00008086sd0000309C*
- ID_MODEL_FROM_DATABASE=Desktop Board D945GTP
+ ID_MODEL_FROM_DATABASE=82573L Gigabit Ethernet Controller (Desktop Board D945GTP)
 
 pci:v00008086d0000109Asv00008086sd000030A5*
- ID_MODEL_FROM_DATABASE=Desktop Board D975XBX
+ ID_MODEL_FROM_DATABASE=82573L Gigabit Ethernet Controller (Desktop Board D975XBX)
 
 pci:v00008086d0000109B*
  ID_MODEL_FROM_DATABASE=82546GB PRO/1000 GF Quad Port Server Adapter
@@ -56652,10 +58053,10 @@ pci:v00008086d0000109E*
  ID_MODEL_FROM_DATABASE=82597EX 10GbE Ethernet Controller
 
 pci:v00008086d0000109Esv00008086sd0000A01F*
- ID_MODEL_FROM_DATABASE=PRO/10GbE CX4 Server Adapter
+ ID_MODEL_FROM_DATABASE=82597EX 10GbE Ethernet Controller (PRO/10GbE CX4 Server Adapter)
 
 pci:v00008086d0000109Esv00008086sd0000A11F*
- ID_MODEL_FROM_DATABASE=PRO/10GbE CX4 Server Adapter
+ ID_MODEL_FROM_DATABASE=82597EX 10GbE Ethernet Controller (PRO/10GbE CX4 Server Adapter)
 
 pci:v00008086d000010A0*
  ID_MODEL_FROM_DATABASE=82571EB PRO/1000 AT Quad Port Bypass Adapter
@@ -56667,19 +58068,19 @@ pci:v00008086d000010A4*
  ID_MODEL_FROM_DATABASE=82571EB Gigabit Ethernet Controller
 
 pci:v00008086d000010A4sv00008086sd000010A4*
- ID_MODEL_FROM_DATABASE=PRO/1000 PT Quad Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82571EB Gigabit Ethernet Controller (PRO/1000 PT Quad Port Server Adapter)
 
 pci:v00008086d000010A4sv00008086sd000011A4*
- ID_MODEL_FROM_DATABASE=PRO/1000 PT Quad Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82571EB Gigabit Ethernet Controller (PRO/1000 PT Quad Port Server Adapter)
 
 pci:v00008086d000010A5*
  ID_MODEL_FROM_DATABASE=82571EB Gigabit Ethernet Controller (Fiber)
 
 pci:v00008086d000010A5sv00008086sd000010A5*
- ID_MODEL_FROM_DATABASE=PRO/1000 PF Quad Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82571EB Gigabit Ethernet Controller (Fiber) (PRO/1000 PF Quad Port Server Adapter)
 
 pci:v00008086d000010A5sv00008086sd000010A6*
- ID_MODEL_FROM_DATABASE=PRO/1000 PF Quad Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82571EB Gigabit Ethernet Controller (Fiber) (PRO/1000 PF Quad Port Server Adapter)
 
 pci:v00008086d000010A6*
  ID_MODEL_FROM_DATABASE=82599EB 10-Gigabit Dummy Function
@@ -56688,7 +58089,7 @@ pci:v00008086d000010A7*
  ID_MODEL_FROM_DATABASE=82575EB Gigabit Network Connection
 
 pci:v00008086d000010A7sv00008086sd000010A8*
- ID_MODEL_FROM_DATABASE=82575EB Gigabit Riser Card
+ ID_MODEL_FROM_DATABASE=82575EB Gigabit Network Connection (82575EB Gigabit Riser Card)
 
 pci:v00008086d000010A9*
  ID_MODEL_FROM_DATABASE=82575EB Gigabit Backplane Connection
@@ -56709,13 +58110,13 @@ pci:v00008086d000010B5*
  ID_MODEL_FROM_DATABASE=82546GB Gigabit Ethernet Controller (Copper)
 
 pci:v00008086d000010B5sv0000103Csd00003109*
- ID_MODEL_FROM_DATABASE=NC340T PCI-X Quad-port Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=82546GB Gigabit Ethernet Controller (Copper) (NC340T PCI-X Quad-port Gigabit Server Adapter)
 
 pci:v00008086d000010B5sv00008086sd00001099*
- ID_MODEL_FROM_DATABASE=PRO/1000 GT Quad Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82546GB Gigabit Ethernet Controller (Copper) (PRO/1000 GT Quad Port Server Adapter)
 
 pci:v00008086d000010B5sv00008086sd00001199*
- ID_MODEL_FROM_DATABASE=PRO/1000 GT Quad Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82546GB Gigabit Ethernet Controller (Copper) (PRO/1000 GT Quad Port Server Adapter)
 
 pci:v00008086d000010B6*
  ID_MODEL_FROM_DATABASE=82598 10GbE PCI-Express Ethernet Controller
@@ -56724,13 +58125,13 @@ pci:v00008086d000010B9*
  ID_MODEL_FROM_DATABASE=82572EI Gigabit Ethernet Controller (Copper)
 
 pci:v00008086d000010B9sv0000103Csd0000704A*
- ID_MODEL_FROM_DATABASE=HP 110T PCIe Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=82572EI Gigabit Ethernet Controller (Copper) (HP 110T PCIe Gigabit Server Adapter)
 
 pci:v00008086d000010B9sv00008086sd00001083*
- ID_MODEL_FROM_DATABASE=PRO/1000 PT Desktop Adapter
+ ID_MODEL_FROM_DATABASE=82572EI Gigabit Ethernet Controller (Copper) (PRO/1000 PT Desktop Adapter)
 
 pci:v00008086d000010B9sv00008086sd00001093*
- ID_MODEL_FROM_DATABASE=PRO/1000 PT Desktop Adapter
+ ID_MODEL_FROM_DATABASE=82572EI Gigabit Ethernet Controller (Copper) (PRO/1000 PT Desktop Adapter)
 
 pci:v00008086d000010BA*
  ID_MODEL_FROM_DATABASE=80003ES2LAN Gigabit Ethernet Controller (Copper)
@@ -56742,22 +58143,22 @@ pci:v00008086d000010BC*
  ID_MODEL_FROM_DATABASE=82571EB Gigabit Ethernet Controller (Copper)
 
 pci:v00008086d000010BCsv0000103Csd0000704B*
- ID_MODEL_FROM_DATABASE=NC364T PCI Express Quad Port Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=82571EB Gigabit Ethernet Controller (Copper) (NC364T PCI Express Quad Port Gigabit Server Adapter)
 
 pci:v00008086d000010BCsv0000108Esd000011BC*
- ID_MODEL_FROM_DATABASE=x4 PCI-Express Quad Gigabit Ethernet UTP Low Profile Adapter
+ ID_MODEL_FROM_DATABASE=82571EB Gigabit Ethernet Controller (Copper) (x4 PCI-Express Quad Gigabit Ethernet UTP Low Profile Adapter)
 
 pci:v00008086d000010BCsv00008086sd000010BC*
- ID_MODEL_FROM_DATABASE=PRO/1000 PT Quad Port LP Server Adapter
+ ID_MODEL_FROM_DATABASE=82571EB Gigabit Ethernet Controller (Copper) (PRO/1000 PT Quad Port LP Server Adapter)
 
 pci:v00008086d000010BCsv00008086sd000011BC*
- ID_MODEL_FROM_DATABASE=PRO/1000 PT Quad Port LP Server Adapter
+ ID_MODEL_FROM_DATABASE=82571EB Gigabit Ethernet Controller (Copper) (PRO/1000 PT Quad Port LP Server Adapter)
 
 pci:v00008086d000010BD*
  ID_MODEL_FROM_DATABASE=82566DM-2 Gigabit Network Connection
 
 pci:v00008086d000010BDsv00001028sd00000211*
- ID_MODEL_FROM_DATABASE=OptiPlex 755
+ ID_MODEL_FROM_DATABASE=82566DM-2 Gigabit Network Connection (OptiPlex 755)
 
 pci:v00008086d000010BF*
  ID_MODEL_FROM_DATABASE=82567LF Gigabit Network Connection
@@ -56766,7 +58167,7 @@ pci:v00008086d000010C0*
  ID_MODEL_FROM_DATABASE=82562V-2 10/100 Network Connection
 
 pci:v00008086d000010C0sv00001028sd0000020D*
- ID_MODEL_FROM_DATABASE=Inspiron 530
+ ID_MODEL_FROM_DATABASE=82562V-2 10/100 Network Connection (Inspiron 530)
 
 pci:v00008086d000010C2*
  ID_MODEL_FROM_DATABASE=82562G-2 10/100 Network Connection
@@ -56784,67 +58185,67 @@ pci:v00008086d000010C6*
  ID_MODEL_FROM_DATABASE=82598EB 10-Gigabit AF Dual Port Network Connection
 
 pci:v00008086d000010C6sv00008086sd0000A05F*
- ID_MODEL_FROM_DATABASE=10-Gigabit XF SR Dual Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82598EB 10-Gigabit AF Dual Port Network Connection (10-Gigabit XF SR Dual Port Server Adapter)
 
 pci:v00008086d000010C6sv00008086sd0000A15F*
- ID_MODEL_FROM_DATABASE=10-Gigabit XF SR Dual Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82598EB 10-Gigabit AF Dual Port Network Connection (10-Gigabit XF SR Dual Port Server Adapter)
 
 pci:v00008086d000010C7*
  ID_MODEL_FROM_DATABASE=82598EB 10-Gigabit AF Network Connection
 
 pci:v00008086d000010C7sv00001014sd0000037F*
- ID_MODEL_FROM_DATABASE=10-Gigabit XF SR Server Adapter
+ ID_MODEL_FROM_DATABASE=82598EB 10-Gigabit AF Network Connection (10-Gigabit XF SR Server Adapter)
 
 pci:v00008086d000010C7sv00001014sd00000380*
- ID_MODEL_FROM_DATABASE=10-Gigabit XF LR Server Adapter
+ ID_MODEL_FROM_DATABASE=82598EB 10-Gigabit AF Network Connection (10-Gigabit XF LR Server Adapter)
 
 pci:v00008086d000010C7sv00008086sd0000A05F*
- ID_MODEL_FROM_DATABASE=10-Gigabit XF SR Server Adapter
+ ID_MODEL_FROM_DATABASE=82598EB 10-Gigabit AF Network Connection (10-Gigabit XF SR Server Adapter)
 
 pci:v00008086d000010C7sv00008086sd0000A15F*
- ID_MODEL_FROM_DATABASE=10-Gigabit XF SR Server Adapter
+ ID_MODEL_FROM_DATABASE=82598EB 10-Gigabit AF Network Connection (10-Gigabit XF SR Server Adapter)
 
 pci:v00008086d000010C7sv00008086sd0000A16F*
- ID_MODEL_FROM_DATABASE=10-Gigabit XF SR Server Adapter
+ ID_MODEL_FROM_DATABASE=82598EB 10-Gigabit AF Network Connection (10-Gigabit XF SR Server Adapter)
 
 pci:v00008086d000010C8*
  ID_MODEL_FROM_DATABASE=82598EB 10-Gigabit AT Network Connection
 
 pci:v00008086d000010C8sv00008086sd0000A10C*
- ID_MODEL_FROM_DATABASE=10-Gigabit AT Server Adapter
+ ID_MODEL_FROM_DATABASE=82598EB 10-Gigabit AT Network Connection (10-Gigabit AT Server Adapter)
 
 pci:v00008086d000010C8sv00008086sd0000A11C*
- ID_MODEL_FROM_DATABASE=10-Gigabit AT Server Adapter
+ ID_MODEL_FROM_DATABASE=82598EB 10-Gigabit AT Network Connection (10-Gigabit AT Server Adapter)
 
 pci:v00008086d000010C8sv00008086sd0000A12C*
- ID_MODEL_FROM_DATABASE=10-Gigabit AT Server Adapter
+ ID_MODEL_FROM_DATABASE=82598EB 10-Gigabit AT Network Connection (10-Gigabit AT Server Adapter)
 
 pci:v00008086d000010C9*
  ID_MODEL_FROM_DATABASE=82576 Gigabit Network Connection
 
 pci:v00008086d000010C9sv0000103Csd000031EF*
- ID_MODEL_FROM_DATABASE=NC362i Integrated Dual port Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=82576 Gigabit Network Connection (NC362i Integrated Dual port Gigabit Server Adapter)
 
 pci:v00008086d000010C9sv0000103Csd0000323F*
- ID_MODEL_FROM_DATABASE=NC362i Integrated Dual port Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=82576 Gigabit Network Connection (NC362i Integrated Dual port Gigabit Server Adapter)
 
 pci:v00008086d000010C9sv000010A9sd00008028*
- ID_MODEL_FROM_DATABASE=UV-BaseIO dual-port GbE
+ ID_MODEL_FROM_DATABASE=82576 Gigabit Network Connection (UV-BaseIO dual-port GbE)
 
 pci:v00008086d000010C9sv000013A3sd00000037*
- ID_MODEL_FROM_DATABASE=DS4100 Secure Multi-Gigabit Server Adapter with Compression
+ ID_MODEL_FROM_DATABASE=82576 Gigabit Network Connection (DS4100 Secure Multi-Gigabit Server Adapter with Compression)
 
 pci:v00008086d000010C9sv000015D9sd0000A811*
- ID_MODEL_FROM_DATABASE=H8DGU
+ ID_MODEL_FROM_DATABASE=82576 Gigabit Network Connection (H8DGU)
 
 pci:v00008086d000010C9sv00008086sd0000A01C*
- ID_MODEL_FROM_DATABASE=Gigabit ET Dual Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82576 Gigabit Network Connection (Gigabit ET Dual Port Server Adapter)
 
 pci:v00008086d000010C9sv00008086sd0000A03C*
- ID_MODEL_FROM_DATABASE=Gigabit ET Dual Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82576 Gigabit Network Connection (Gigabit ET Dual Port Server Adapter)
 
 pci:v00008086d000010C9sv00008086sd0000A04C*
- ID_MODEL_FROM_DATABASE=Gigabit ET Dual Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82576 Gigabit Network Connection (Gigabit ET Dual Port Server Adapter)
 
 pci:v00008086d000010CA*
  ID_MODEL_FROM_DATABASE=82576 Virtual Function
@@ -56865,25 +58266,34 @@ pci:v00008086d000010D3*
  ID_MODEL_FROM_DATABASE=82574L Gigabit Network Connection
 
 pci:v00008086d000010D3sv0000103Csd00003250*
- ID_MODEL_FROM_DATABASE=NC112T PCI Express single Port Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=82574L Gigabit Network Connection (NC112T PCI Express single Port Gigabit Server Adapter)
+
+pci:v00008086d000010D3sv00001043sd00008369*
+ ID_MODEL_FROM_DATABASE=82574L Gigabit Network Connection (Motherboard)
 
 pci:v00008086d000010D3sv000010A9sd00008029*
- ID_MODEL_FROM_DATABASE=Prism XL Single Port Gigabit Ethernet
+ ID_MODEL_FROM_DATABASE=82574L Gigabit Network Connection (Prism XL Single Port Gigabit Ethernet)
 
 pci:v00008086d000010D3sv000015D9sd0000060A*
- ID_MODEL_FROM_DATABASE=X7SPA-H/X7SPA-HF Motherboard
+ ID_MODEL_FROM_DATABASE=82574L Gigabit Network Connection (X7SPA-H/X7SPA-HF Motherboard)
+
+pci:v00008086d000010D3sv000015D9sd0000060D*
+ ID_MODEL_FROM_DATABASE=82574L Gigabit Network Connection (C7SIM-Q Motherboard)
 
 pci:v00008086d000010D3sv00008086sd00000001*
- ID_MODEL_FROM_DATABASE=Gigabit CT2 Desktop Adapter
+ ID_MODEL_FROM_DATABASE=82574L Gigabit Network Connection (Gigabit CT2 Desktop Adapter)
+
+pci:v00008086d000010D3sv00008086sd0000357A*
+ ID_MODEL_FROM_DATABASE=82574L Gigabit Network Connection (Server Board S1200BTS)
 
 pci:v00008086d000010D3sv00008086sd0000A01F*
- ID_MODEL_FROM_DATABASE=Gigabit CT Desktop Adapter
+ ID_MODEL_FROM_DATABASE=82574L Gigabit Network Connection (Gigabit CT Desktop Adapter)
 
 pci:v00008086d000010D3sv0000E4BFsd000050C1*
- ID_MODEL_FROM_DATABASE=PC1-GROOVE
+ ID_MODEL_FROM_DATABASE=82574L Gigabit Network Connection (PC1-GROOVE)
 
 pci:v00008086d000010D3sv0000E4BFsd000050C2*
- ID_MODEL_FROM_DATABASE=PC2-LIMBO
+ ID_MODEL_FROM_DATABASE=82574L Gigabit Network Connection (PC2-LIMBO)
 
 pci:v00008086d000010D4*
  ID_MODEL_FROM_DATABASE=Matrox Concord GE (customized Intel 82574)
@@ -56895,13 +58305,13 @@ pci:v00008086d000010D6*
  ID_MODEL_FROM_DATABASE=82575GB Gigabit Network Connection
 
 pci:v00008086d000010D6sv00008086sd000010D6*
- ID_MODEL_FROM_DATABASE=Gigabit VT Quad Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82575GB Gigabit Network Connection (Gigabit VT Quad Port Server Adapter)
 
 pci:v00008086d000010D6sv00008086sd0000145A*
- ID_MODEL_FROM_DATABASE=Gigabit VT Quad Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82575GB Gigabit Network Connection (Gigabit VT Quad Port Server Adapter)
 
 pci:v00008086d000010D6sv00008086sd0000147A*
- ID_MODEL_FROM_DATABASE=Gigabit VT Quad Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82575GB Gigabit Network Connection (Gigabit VT Quad Port Server Adapter)
 
 pci:v00008086d000010D8*
  ID_MODEL_FROM_DATABASE=82599EB 10 Gigabit Unprogrammed
@@ -56910,13 +58320,13 @@ pci:v00008086d000010D9*
  ID_MODEL_FROM_DATABASE=82571EB Dual Port Gigabit Mezzanine Adapter
 
 pci:v00008086d000010D9sv0000103Csd00001716*
- ID_MODEL_FROM_DATABASE=NC360m Dual Port 1GbE BL-c Adapter
+ ID_MODEL_FROM_DATABASE=82571EB Dual Port Gigabit Mezzanine Adapter (NC360m Dual Port 1GbE BL-c Adapter)
 
 pci:v00008086d000010DA*
  ID_MODEL_FROM_DATABASE=82571EB Quad Port Gigabit Mezzanine Adapter
 
 pci:v00008086d000010DAsv0000103Csd00001717*
- ID_MODEL_FROM_DATABASE=NC364m Quad Port 1GbE BL-c Adapter
+ ID_MODEL_FROM_DATABASE=82571EB Quad Port Gigabit Mezzanine Adapter (NC364m Quad Port 1GbE BL-c Adapter)
 
 pci:v00008086d000010DB*
  ID_MODEL_FROM_DATABASE=82598EB 10-Gigabit Dual Port Network Connection
@@ -56934,13 +58344,13 @@ pci:v00008086d000010E1*
  ID_MODEL_FROM_DATABASE=82598EB 10-Gigabit AF Dual Port Network Connection
 
 pci:v00008086d000010E1sv00008086sd0000A15F*
- ID_MODEL_FROM_DATABASE=10-Gigabit SR Dual Port Express Module
+ ID_MODEL_FROM_DATABASE=82598EB 10-Gigabit AF Dual Port Network Connection (10-Gigabit SR Dual Port Express Module)
 
 pci:v00008086d000010E2*
  ID_MODEL_FROM_DATABASE=82575GB Gigabit Network Connection
 
 pci:v00008086d000010E2sv00008086sd000010E2*
- ID_MODEL_FROM_DATABASE=Gigabit VT Quad Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82575GB Gigabit Network Connection (Gigabit VT Quad Port Server Adapter)
 
 pci:v00008086d000010E5*
  ID_MODEL_FROM_DATABASE=82567LM-4 Gigabit Network Connection
@@ -56949,37 +58359,37 @@ pci:v00008086d000010E6*
  ID_MODEL_FROM_DATABASE=82576 Gigabit Network Connection
 
 pci:v00008086d000010E6sv00008086sd0000A01F*
- ID_MODEL_FROM_DATABASE=Gigabit EF Dual Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82576 Gigabit Network Connection (Gigabit EF Dual Port Server Adapter)
 
 pci:v00008086d000010E6sv00008086sd0000A02F*
- ID_MODEL_FROM_DATABASE=Gigabit EF Dual Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82576 Gigabit Network Connection (Gigabit EF Dual Port Server Adapter)
 
 pci:v00008086d000010E7*
  ID_MODEL_FROM_DATABASE=82576 Gigabit Network Connection
 
 pci:v00008086d000010E7sv0000103Csd000031FF*
- ID_MODEL_FROM_DATABASE=NC362i Integrated Dual Port BL-c Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=82576 Gigabit Network Connection (NC362i Integrated Dual Port BL-c Gigabit Server Adapter)
 
 pci:v00008086d000010E8*
  ID_MODEL_FROM_DATABASE=82576 Gigabit Network Connection
 
 pci:v00008086d000010E8sv00008086sd0000A02B*
- ID_MODEL_FROM_DATABASE=Gigabit ET Quad Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82576 Gigabit Network Connection (Gigabit ET Quad Port Server Adapter)
 
 pci:v00008086d000010E8sv00008086sd0000A02C*
- ID_MODEL_FROM_DATABASE=Gigabit ET Quad Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82576 Gigabit Network Connection (Gigabit ET Quad Port Server Adapter)
 
 pci:v00008086d000010EA*
  ID_MODEL_FROM_DATABASE=82577LM Gigabit Network Connection
 
 pci:v00008086d000010EAsv00001028sd0000040A*
- ID_MODEL_FROM_DATABASE=Latitude E6410
+ ID_MODEL_FROM_DATABASE=82577LM Gigabit Network Connection (Latitude E6410)
 
 pci:v00008086d000010EAsv00001028sd0000040B*
- ID_MODEL_FROM_DATABASE=Latitude E6510
+ ID_MODEL_FROM_DATABASE=82577LM Gigabit Network Connection (Latitude E6510)
 
 pci:v00008086d000010EAsv0000E4BFsd000050C1*
- ID_MODEL_FROM_DATABASE=PC1-GROOVE
+ ID_MODEL_FROM_DATABASE=82577LM Gigabit Network Connection (PC1-GROOVE)
 
 pci:v00008086d000010EB*
  ID_MODEL_FROM_DATABASE=82577LC Gigabit Network Connection
@@ -56988,10 +58398,10 @@ pci:v00008086d000010EC*
  ID_MODEL_FROM_DATABASE=82598EB 10-Gigabit AT CX4 Network Connection
 
 pci:v00008086d000010ECsv00008086sd0000A01F*
- ID_MODEL_FROM_DATABASE=10-Gigabit CX4 Dual Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82598EB 10-Gigabit AT CX4 Network Connection (10-Gigabit CX4 Dual Port Server Adapter)
 
 pci:v00008086d000010ECsv00008086sd0000A11F*
- ID_MODEL_FROM_DATABASE=10-Gigabit CX4 Dual Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82598EB 10-Gigabit AT CX4 Network Connection (10-Gigabit CX4 Dual Port Server Adapter)
 
 pci:v00008086d000010ED*
  ID_MODEL_FROM_DATABASE=82599 Ethernet Controller Virtual Function
@@ -57000,7 +58410,10 @@ pci:v00008086d000010EF*
  ID_MODEL_FROM_DATABASE=82578DM Gigabit Network Connection
 
 pci:v00008086d000010EFsv00001028sd000002DA*
- ID_MODEL_FROM_DATABASE=OptiPlex 980
+ ID_MODEL_FROM_DATABASE=82578DM Gigabit Network Connection (OptiPlex 980)
+
+pci:v00008086d000010EFsv000015D9sd0000060D*
+ ID_MODEL_FROM_DATABASE=82578DM Gigabit Network Connection (C7SIM-Q Motherboard)
 
 pci:v00008086d000010F0*
  ID_MODEL_FROM_DATABASE=82578DC Gigabit Network Connection
@@ -57009,19 +58422,19 @@ pci:v00008086d000010F1*
  ID_MODEL_FROM_DATABASE=82598EB 10-Gigabit AF Dual Port Network Connection
 
 pci:v00008086d000010F1sv00008086sd0000A20F*
- ID_MODEL_FROM_DATABASE=10-Gigabit AF DA Dual Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82598EB 10-Gigabit AF Dual Port Network Connection (10-Gigabit AF DA Dual Port Server Adapter)
 
 pci:v00008086d000010F1sv00008086sd0000A21F*
- ID_MODEL_FROM_DATABASE=10-Gigabit AF DA Dual Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82598EB 10-Gigabit AF Dual Port Network Connection (10-Gigabit AF DA Dual Port Server Adapter)
 
 pci:v00008086d000010F4*
  ID_MODEL_FROM_DATABASE=82598EB 10-Gigabit AF Network Connection
 
 pci:v00008086d000010F4sv00008086sd0000106F*
- ID_MODEL_FROM_DATABASE=10-Gigabit XF LR Server Adapter
+ ID_MODEL_FROM_DATABASE=82598EB 10-Gigabit AF Network Connection (10-Gigabit XF LR Server Adapter)
 
 pci:v00008086d000010F4sv00008086sd0000A06F*
- ID_MODEL_FROM_DATABASE=10-Gigabit XF LR Server Adapter
+ ID_MODEL_FROM_DATABASE=82598EB 10-Gigabit AF Network Connection (10-Gigabit XF LR Server Adapter)
 
 pci:v00008086d000010F5*
  ID_MODEL_FROM_DATABASE=82567LM Gigabit Network Connection
@@ -57033,25 +58446,25 @@ pci:v00008086d000010F7*
  ID_MODEL_FROM_DATABASE=10 Gigabit BR KX4 Dual Port Network Connection
 
 pci:v00008086d000010F7sv0000108Esd00007B12*
- ID_MODEL_FROM_DATABASE=Sun Dual 10GbE PCIe 2.0 FEM
+ ID_MODEL_FROM_DATABASE=10 Gigabit BR KX4 Dual Port Network Connection (Sun Dual 10GbE PCIe 2.0 FEM)
 
 pci:v00008086d000010F7sv00008086sd0000000D*
- ID_MODEL_FROM_DATABASE=Ethernet Mezzanine Adapter X520-KX4-2
+ ID_MODEL_FROM_DATABASE=10 Gigabit BR KX4 Dual Port Network Connection (Ethernet Mezzanine Adapter X520-KX4-2)
 
 pci:v00008086d000010F8*
  ID_MODEL_FROM_DATABASE=82599 10 Gigabit Dual Port Backplane Connection
 
 pci:v00008086d000010F8sv00001028sd00001F63*
- ID_MODEL_FROM_DATABASE=10GbE 2P X520k bNDC
+ ID_MODEL_FROM_DATABASE=82599 10 Gigabit Dual Port Backplane Connection (10GbE 2P X520k bNDC)
 
 pci:v00008086d000010F8sv0000103Csd000017D2*
- ID_MODEL_FROM_DATABASE=Ethernet 10Gb 2-port 560M Adapter
+ ID_MODEL_FROM_DATABASE=82599 10 Gigabit Dual Port Backplane Connection (Ethernet 10Gb 2-port 560M Adapter)
 
 pci:v00008086d000010F8sv0000103Csd000018D0*
- ID_MODEL_FROM_DATABASE=Ethernet 10Gb 2-port 560FLB Adapter
+ ID_MODEL_FROM_DATABASE=82599 10 Gigabit Dual Port Backplane Connection (Ethernet 10Gb 2-port 560FLB Adapter)
 
 pci:v00008086d000010F8sv00008086sd0000000C*
- ID_MODEL_FROM_DATABASE=Ethernet X520 10GbE Dual Port KX4-KR Mezz
+ ID_MODEL_FROM_DATABASE=82599 10 Gigabit Dual Port Backplane Connection (Ethernet X520 10GbE Dual Port KX4-KR Mezz)
 
 pci:v00008086d000010F9*
  ID_MODEL_FROM_DATABASE=82599 10 Gigabit Dual Port Network Connection
@@ -57060,55 +58473,58 @@ pci:v00008086d000010FB*
  ID_MODEL_FROM_DATABASE=82599ES 10-Gigabit SFI/SFP+ Network Connection
 
 pci:v00008086d000010FBsv00001028sd00001F72*
- ID_MODEL_FROM_DATABASE=Ethernet 10G 4P X520/I350 rNDC
+ ID_MODEL_FROM_DATABASE=82599ES 10-Gigabit SFI/SFP+ Network Connection (Ethernet 10G 4P X520/I350 rNDC)
 
 pci:v00008086d000010FBsv0000103Csd000017D0*
- ID_MODEL_FROM_DATABASE=Ethernet 10Gb 2-port 560FLR-SFP+ Adapter
+ ID_MODEL_FROM_DATABASE=82599ES 10-Gigabit SFI/SFP+ Network Connection (Ethernet 10Gb 2-port 560FLR-SFP+ Adapter)
 
 pci:v00008086d000010FBsv0000103Csd000017D2*
- ID_MODEL_FROM_DATABASE=Ethernet 10Gb 2-port 560M Adapter
+ ID_MODEL_FROM_DATABASE=82599ES 10-Gigabit SFI/SFP+ Network Connection (Ethernet 10Gb 2-port 560M Adapter)
 
 pci:v00008086d000010FBsv0000103Csd000017D3*
- ID_MODEL_FROM_DATABASE=Ethernet 10Gb 2-port 560SFP+ Adapter
+ ID_MODEL_FROM_DATABASE=82599ES 10-Gigabit SFI/SFP+ Network Connection (Ethernet 10Gb 2-port 560SFP+ Adapter)
 
 pci:v00008086d000010FBsv0000103Csd0000211B*
- ID_MODEL_FROM_DATABASE=Ethernet 10Gb 1-port P560FLR-SFP+ Adapter
+ ID_MODEL_FROM_DATABASE=82599ES 10-Gigabit SFI/SFP+ Network Connection (Ethernet 10Gb 1-port P560FLR-SFP+ Adapter)
 
 pci:v00008086d000010FBsv0000103Csd00002147*
- ID_MODEL_FROM_DATABASE=Ethernet 10Gb 1-port 561i Adapter
+ ID_MODEL_FROM_DATABASE=82599ES 10-Gigabit SFI/SFP+ Network Connection (Ethernet 10Gb 1-port 561i Adapter)
 
 pci:v00008086d000010FBsv0000103Csd00002159*
- ID_MODEL_FROM_DATABASE=Ethernet 10Gb 2-port 562i Adapter
+ ID_MODEL_FROM_DATABASE=82599ES 10-Gigabit SFI/SFP+ Network Connection (Ethernet 10Gb 2-port 562i Adapter)
 
 pci:v00008086d000010FBsv0000108Esd00007B11*
- ID_MODEL_FROM_DATABASE=Ethernet Server Adapter X520-2
+ ID_MODEL_FROM_DATABASE=82599ES 10-Gigabit SFI/SFP+ Network Connection (Ethernet Server Adapter X520-2)
 
 pci:v00008086d000010FBsv00001734sd000011A9*
- ID_MODEL_FROM_DATABASE=10 Gigabit Dual Port Network Connection
+ ID_MODEL_FROM_DATABASE=82599ES 10-Gigabit SFI/SFP+ Network Connection (10 Gigabit Dual Port Network Connection)
+
+pci:v00008086d000010FBsv000017AAsd00001071*
+ ID_MODEL_FROM_DATABASE=82599ES 10-Gigabit SFI/SFP+ Network Connection (ThinkServer X520-2 AnyFabric)
 
 pci:v00008086d000010FBsv00008086sd00000002*
- ID_MODEL_FROM_DATABASE=Ethernet Server Adapter X520-DA2
+ ID_MODEL_FROM_DATABASE=82599ES 10-Gigabit SFI/SFP+ Network Connection (Ethernet Server Adapter X520-DA2)
 
 pci:v00008086d000010FBsv00008086sd00000003*
- ID_MODEL_FROM_DATABASE=Ethernet Server Adapter X520-2
+ ID_MODEL_FROM_DATABASE=82599ES 10-Gigabit SFI/SFP+ Network Connection (Ethernet Server Adapter X520-2)
 
 pci:v00008086d000010FBsv00008086sd00000006*
- ID_MODEL_FROM_DATABASE=Ethernet Server Adapter X520-1
+ ID_MODEL_FROM_DATABASE=82599ES 10-Gigabit SFI/SFP+ Network Connection (Ethernet Server Adapter X520-1)
 
 pci:v00008086d000010FBsv00008086sd00000008*
- ID_MODEL_FROM_DATABASE=Ethernet OCP Server Adapter X520-2
+ ID_MODEL_FROM_DATABASE=82599ES 10-Gigabit SFI/SFP+ Network Connection (Ethernet OCP Server Adapter X520-2)
 
 pci:v00008086d000010FBsv00008086sd0000000A*
- ID_MODEL_FROM_DATABASE=Ethernet Server Adapter X520-1
+ ID_MODEL_FROM_DATABASE=82599ES 10-Gigabit SFI/SFP+ Network Connection (Ethernet Server Adapter X520-1)
 
 pci:v00008086d000010FBsv00008086sd0000000C*
- ID_MODEL_FROM_DATABASE=Ethernet Server Adapter X520-2
+ ID_MODEL_FROM_DATABASE=82599ES 10-Gigabit SFI/SFP+ Network Connection (Ethernet Server Adapter X520-2)
 
 pci:v00008086d000010FBsv00008086sd00007A11*
- ID_MODEL_FROM_DATABASE=Ethernet Server Adapter X520-2
+ ID_MODEL_FROM_DATABASE=82599ES 10-Gigabit SFI/SFP+ Network Connection (Ethernet Server Adapter X520-2)
 
 pci:v00008086d000010FBsv00008086sd00007A12*
- ID_MODEL_FROM_DATABASE=Ethernet Server Adapter X520-2
+ ID_MODEL_FROM_DATABASE=82599ES 10-Gigabit SFI/SFP+ Network Connection (Ethernet Server Adapter X520-2)
 
 pci:v00008086d000010FC*
  ID_MODEL_FROM_DATABASE=82599 10 Gigabit Dual Port Network Connection
@@ -57123,19 +58539,19 @@ pci:v00008086d00001130*
  ID_MODEL_FROM_DATABASE=82815 815 Chipset Host Bridge and Memory Controller Hub
 
 pci:v00008086d00001130sv00001025sd00001016*
- ID_MODEL_FROM_DATABASE=Travelmate 612 TX
+ ID_MODEL_FROM_DATABASE=82815 815 Chipset Host Bridge and Memory Controller Hub (Travelmate 612 TX)
 
 pci:v00008086d00001130sv00001043sd00008027*
- ID_MODEL_FROM_DATABASE=TUSL2-C Mainboard
+ ID_MODEL_FROM_DATABASE=82815 815 Chipset Host Bridge and Memory Controller Hub (TUSL2-C Mainboard)
 
 pci:v00008086d00001130sv0000104Dsd000080DF*
- ID_MODEL_FROM_DATABASE=Vaio PCG-FX403
+ ID_MODEL_FROM_DATABASE=82815 815 Chipset Host Bridge and Memory Controller Hub (Vaio PCG-FX403)
 
 pci:v00008086d00001130sv00008086sd00004532*
- ID_MODEL_FROM_DATABASE=D815EEA2 mainboard
+ ID_MODEL_FROM_DATABASE=82815 815 Chipset Host Bridge and Memory Controller Hub (D815EEA2 mainboard)
 
 pci:v00008086d00001130sv00008086sd00004557*
- ID_MODEL_FROM_DATABASE=D815EGEW Mainboard
+ ID_MODEL_FROM_DATABASE=82815 815 Chipset Host Bridge and Memory Controller Hub (D815EGEW Mainboard)
 
 pci:v00008086d00001131*
  ID_MODEL_FROM_DATABASE=82815 815 Chipset AGP Bridge
@@ -57144,28 +58560,28 @@ pci:v00008086d00001132*
  ID_MODEL_FROM_DATABASE=82815 Chipset Graphics Controller (CGC)
 
 pci:v00008086d00001132sv00001025sd00001016*
- ID_MODEL_FROM_DATABASE=Travelmate 612 TX
+ ID_MODEL_FROM_DATABASE=82815 Chipset Graphics Controller (CGC) (Travelmate 612 TX)
 
 pci:v00008086d00001132sv0000103Csd00002001*
- ID_MODEL_FROM_DATABASE=e-pc 40
+ ID_MODEL_FROM_DATABASE=82815 Chipset Graphics Controller (CGC) (e-pc 40)
 
 pci:v00008086d00001132sv0000104Dsd000080DF*
- ID_MODEL_FROM_DATABASE=Vaio PCG-FX403
+ ID_MODEL_FROM_DATABASE=82815 Chipset Graphics Controller (CGC) (Vaio PCG-FX403)
 
 pci:v00008086d00001132sv00008086sd00004532*
- ID_MODEL_FROM_DATABASE=D815EEA2 Mainboard
+ ID_MODEL_FROM_DATABASE=82815 Chipset Graphics Controller (CGC) (D815EEA2 Mainboard)
 
 pci:v00008086d00001132sv00008086sd00004541*
- ID_MODEL_FROM_DATABASE=D815EEA Motherboard
+ ID_MODEL_FROM_DATABASE=82815 Chipset Graphics Controller (CGC) (D815EEA Motherboard)
 
 pci:v00008086d00001132sv00008086sd00004557*
- ID_MODEL_FROM_DATABASE=D815EGEW Mainboard
+ ID_MODEL_FROM_DATABASE=82815 Chipset Graphics Controller (CGC) (D815EGEW Mainboard)
 
 pci:v00008086d00001161*
  ID_MODEL_FROM_DATABASE=82806AA PCI64 Hub Advanced Programmable Interrupt Controller
 
 pci:v00008086d00001161sv00008086sd00001161*
- ID_MODEL_FROM_DATABASE=82806AA PCI64 Hub APIC
+ ID_MODEL_FROM_DATABASE=82806AA PCI64 Hub Advanced Programmable Interrupt Controller (82806AA PCI64 Hub APIC)
 
 pci:v00008086d00001162*
  ID_MODEL_FROM_DATABASE=Xscale 80200 Big Endian Companion Chip
@@ -57174,22 +58590,25 @@ pci:v00008086d00001200*
  ID_MODEL_FROM_DATABASE=IXP1200 Network Processor
 
 pci:v00008086d00001200sv0000172Asd00000000*
- ID_MODEL_FROM_DATABASE=AEP SSL Accelerator
+ ID_MODEL_FROM_DATABASE=IXP1200 Network Processor (AEP SSL Accelerator)
 
 pci:v00008086d00001209*
  ID_MODEL_FROM_DATABASE=8255xER/82551IT Fast Ethernet Controller
 
 pci:v00008086d00001209sv0000140Bsd00000610*
- ID_MODEL_FROM_DATABASE=PMC610 quad Ethernet board
+ ID_MODEL_FROM_DATABASE=8255xER/82551IT Fast Ethernet Controller (PMC610 quad Ethernet board)
+
+pci:v00008086d00001209sv00001AF4sd00001100*
+ ID_MODEL_FROM_DATABASE=8255xER/82551IT Fast Ethernet Controller (QEMU Virtual Machine)
 
 pci:v00008086d00001209sv00004C53sd00001050*
- ID_MODEL_FROM_DATABASE=CT7 mainboard
+ ID_MODEL_FROM_DATABASE=8255xER/82551IT Fast Ethernet Controller (CT7 mainboard)
 
 pci:v00008086d00001209sv00004C53sd00001051*
- ID_MODEL_FROM_DATABASE=CE7 mainboard
+ ID_MODEL_FROM_DATABASE=8255xER/82551IT Fast Ethernet Controller (CE7 mainboard)
 
 pci:v00008086d00001209sv00004C53sd00001070*
- ID_MODEL_FROM_DATABASE=PC6 mainboard
+ ID_MODEL_FROM_DATABASE=8255xER/82551IT Fast Ethernet Controller (PC6 mainboard)
 
 pci:v00008086d00001221*
  ID_MODEL_FROM_DATABASE=82092AA PCI to PCMCIA Bridge
@@ -57216,484 +58635,487 @@ pci:v00008086d00001229*
  ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100
 
 pci:v00008086d00001229sv00000E11sd00003001*
- ID_MODEL_FROM_DATABASE=82559 Fast Ethernet LOM with Alert on LAN*
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (82559 Fast Ethernet LOM with Alert on LAN*)
 
 pci:v00008086d00001229sv00000E11sd00003002*
- ID_MODEL_FROM_DATABASE=82559 Fast Ethernet LOM with Alert on LAN*
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (82559 Fast Ethernet LOM with Alert on LAN*)
 
 pci:v00008086d00001229sv00000E11sd00003003*
- ID_MODEL_FROM_DATABASE=82559 Fast Ethernet LOM with Alert on LAN*
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (82559 Fast Ethernet LOM with Alert on LAN*)
 
 pci:v00008086d00001229sv00000E11sd00003004*
- ID_MODEL_FROM_DATABASE=82559 Fast Ethernet LOM with Alert on LAN*
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (82559 Fast Ethernet LOM with Alert on LAN*)
 
 pci:v00008086d00001229sv00000E11sd00003005*
- ID_MODEL_FROM_DATABASE=82559 Fast Ethernet LOM with Alert on LAN*
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (82559 Fast Ethernet LOM with Alert on LAN*)
 
 pci:v00008086d00001229sv00000E11sd00003006*
- ID_MODEL_FROM_DATABASE=82559 Fast Ethernet LOM with Alert on LAN*
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (82559 Fast Ethernet LOM with Alert on LAN*)
 
 pci:v00008086d00001229sv00000E11sd00003007*
- ID_MODEL_FROM_DATABASE=82559 Fast Ethernet LOM with Alert on LAN*
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (82559 Fast Ethernet LOM with Alert on LAN*)
 
 pci:v00008086d00001229sv00000E11sd0000B01E*
- ID_MODEL_FROM_DATABASE=NC3120 Fast Ethernet NIC
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (NC3120 Fast Ethernet NIC)
 
 pci:v00008086d00001229sv00000E11sd0000B01F*
- ID_MODEL_FROM_DATABASE=NC3122 Fast Ethernet NIC (dual port)
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (NC3122 Fast Ethernet NIC (dual port))
 
 pci:v00008086d00001229sv00000E11sd0000B02F*
- ID_MODEL_FROM_DATABASE=NC1120 Ethernet NIC
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (NC1120 Ethernet NIC)
 
 pci:v00008086d00001229sv00000E11sd0000B04A*
- ID_MODEL_FROM_DATABASE=Netelligent 10/100TX NIC with Wake on LAN
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (Netelligent 10/100TX NIC with Wake on LAN)
 
 pci:v00008086d00001229sv00000E11sd0000B0C6*
- ID_MODEL_FROM_DATABASE=NC3161 Fast Ethernet NIC (embedded, WOL)
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (NC3161 Fast Ethernet NIC (embedded, WOL))
 
 pci:v00008086d00001229sv00000E11sd0000B0C7*
- ID_MODEL_FROM_DATABASE=NC3160 Fast Ethernet NIC (embedded)
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (NC3160 Fast Ethernet NIC (embedded))
 
 pci:v00008086d00001229sv00000E11sd0000B0D7*
- ID_MODEL_FROM_DATABASE=NC3121 Fast Ethernet NIC (WOL)
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (NC3121 Fast Ethernet NIC (WOL))
 
 pci:v00008086d00001229sv00000E11sd0000B0DD*
- ID_MODEL_FROM_DATABASE=NC3131 Fast Ethernet NIC (dual port)
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (NC3131 Fast Ethernet NIC (dual port))
 
 pci:v00008086d00001229sv00000E11sd0000B0DE*
- ID_MODEL_FROM_DATABASE=NC3132 Fast Ethernet Module (dual port)
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (NC3132 Fast Ethernet Module (dual port))
 
 pci:v00008086d00001229sv00000E11sd0000B0E1*
- ID_MODEL_FROM_DATABASE=NC3133 Fast Ethernet Module (100-FX)
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (NC3133 Fast Ethernet Module (100-FX))
 
 pci:v00008086d00001229sv00000E11sd0000B134*
- ID_MODEL_FROM_DATABASE=NC3163 Fast Ethernet NIC (embedded, WOL)
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (NC3163 Fast Ethernet NIC (embedded, WOL))
 
 pci:v00008086d00001229sv00000E11sd0000B13C*
- ID_MODEL_FROM_DATABASE=NC3162 Fast Ethernet NIC (embedded)
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (NC3162 Fast Ethernet NIC (embedded))
 
 pci:v00008086d00001229sv00000E11sd0000B144*
- ID_MODEL_FROM_DATABASE=NC3123 Fast Ethernet NIC (WOL)
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (NC3123 Fast Ethernet NIC (WOL))
 
 pci:v00008086d00001229sv00000E11sd0000B163*
- ID_MODEL_FROM_DATABASE=NC3134 Fast Ethernet NIC (dual port)
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (NC3134 Fast Ethernet NIC (dual port))
 
 pci:v00008086d00001229sv00000E11sd0000B164*
- ID_MODEL_FROM_DATABASE=NC3135 Fast Ethernet Upgrade Module (dual port)
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (NC3135 Fast Ethernet Upgrade Module (dual port))
 
 pci:v00008086d00001229sv00000E11sd0000B1A4*
- ID_MODEL_FROM_DATABASE=NC7131 Gigabit Server Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (NC7131 Gigabit Server Adapter)
 
 pci:v00008086d00001229sv00001014sd0000005C*
- ID_MODEL_FROM_DATABASE=82558B Ethernet Pro 10/100
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (82558B Ethernet Pro 10/100)
 
 pci:v00008086d00001229sv00001014sd000001BC*
- ID_MODEL_FROM_DATABASE=82559 Fast Ethernet LAN On Motherboard
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (82559 Fast Ethernet LAN On Motherboard)
 
 pci:v00008086d00001229sv00001014sd000001F1*
- ID_MODEL_FROM_DATABASE=10/100 Ethernet Server Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (10/100 Ethernet Server Adapter)
 
 pci:v00008086d00001229sv00001014sd000001F2*
- ID_MODEL_FROM_DATABASE=10/100 Ethernet Server Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (10/100 Ethernet Server Adapter)
 
 pci:v00008086d00001229sv00001014sd00000207*
- ID_MODEL_FROM_DATABASE=Ethernet Pro/100 S
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (Ethernet Pro/100 S)
 
 pci:v00008086d00001229sv00001014sd00000232*
- ID_MODEL_FROM_DATABASE=10/100 Dual Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (10/100 Dual Port Server Adapter)
 
 pci:v00008086d00001229sv00001014sd0000023A*
- ID_MODEL_FROM_DATABASE=ThinkPad R30
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (ThinkPad R30)
 
 pci:v00008086d00001229sv00001014sd0000105C*
- ID_MODEL_FROM_DATABASE=Netfinity 10/100
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (Netfinity 10/100)
 
 pci:v00008086d00001229sv00001014sd00002205*
- ID_MODEL_FROM_DATABASE=ThinkPad A22p
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (ThinkPad A22p)
 
 pci:v00008086d00001229sv00001014sd0000305C*
- ID_MODEL_FROM_DATABASE=10/100 EtherJet Management Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (10/100 EtherJet Management Adapter)
 
 pci:v00008086d00001229sv00001014sd0000405C*
- ID_MODEL_FROM_DATABASE=10/100 EtherJet Adapter with Alert on LAN
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (10/100 EtherJet Adapter with Alert on LAN)
 
 pci:v00008086d00001229sv00001014sd0000505C*
- ID_MODEL_FROM_DATABASE=10/100 EtherJet Secure Management Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (10/100 EtherJet Secure Management Adapter)
 
 pci:v00008086d00001229sv00001014sd0000605C*
- ID_MODEL_FROM_DATABASE=10/100 EtherJet Secure Management Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (10/100 EtherJet Secure Management Adapter)
 
 pci:v00008086d00001229sv00001014sd0000705C*
- ID_MODEL_FROM_DATABASE=10/100 Netfinity 10/100 Ethernet Security Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (10/100 Netfinity 10/100 Ethernet Security Adapter)
 
 pci:v00008086d00001229sv00001014sd0000805C*
- ID_MODEL_FROM_DATABASE=10/100 Netfinity 10/100 Ethernet Security Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (10/100 Netfinity 10/100 Ethernet Security Adapter)
 
 pci:v00008086d00001229sv00001028sd0000009B*
- ID_MODEL_FROM_DATABASE=10/100 Ethernet Server Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (10/100 Ethernet Server Adapter)
 
 pci:v00008086d00001229sv00001028sd000000CE*
- ID_MODEL_FROM_DATABASE=10/100 Ethernet Server Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (10/100 Ethernet Server Adapter)
 
 pci:v00008086d00001229sv00001033sd00008000*
- ID_MODEL_FROM_DATABASE=PC-9821X-B06
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (PC-9821X-B06)
 
 pci:v00008086d00001229sv00001033sd00008016*
- ID_MODEL_FROM_DATABASE=PK-UG-X006
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (PK-UG-X006)
 
 pci:v00008086d00001229sv00001033sd0000801F*
- ID_MODEL_FROM_DATABASE=PK-UG-X006
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (PK-UG-X006)
 
 pci:v00008086d00001229sv00001033sd00008026*
- ID_MODEL_FROM_DATABASE=PK-UG-X006
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (PK-UG-X006)
 
 pci:v00008086d00001229sv00001033sd00008063*
- ID_MODEL_FROM_DATABASE=82559-based Fast Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (82559-based Fast Ethernet Adapter)
 
 pci:v00008086d00001229sv00001033sd00008064*
- ID_MODEL_FROM_DATABASE=82559-based Fast Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (82559-based Fast Ethernet Adapter)
 
 pci:v00008086d00001229sv0000103Csd000010C0*
- ID_MODEL_FROM_DATABASE=NetServer 10/100TX
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (NetServer 10/100TX)
 
 pci:v00008086d00001229sv0000103Csd000010C3*
- ID_MODEL_FROM_DATABASE=NetServer 10/100TX
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (NetServer 10/100TX)
 
 pci:v00008086d00001229sv0000103Csd000010CA*
- ID_MODEL_FROM_DATABASE=NetServer 10/100TX
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (NetServer 10/100TX)
 
 pci:v00008086d00001229sv0000103Csd000010CB*
- ID_MODEL_FROM_DATABASE=NetServer 10/100TX
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (NetServer 10/100TX)
 
 pci:v00008086d00001229sv0000103Csd000010E3*
- ID_MODEL_FROM_DATABASE=NetServer 10/100TX
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (NetServer 10/100TX)
 
 pci:v00008086d00001229sv0000103Csd000010E4*
- ID_MODEL_FROM_DATABASE=NetServer 10/100TX
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (NetServer 10/100TX)
 
 pci:v00008086d00001229sv0000103Csd00001200*
- ID_MODEL_FROM_DATABASE=NetServer 10/100TX
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (NetServer 10/100TX)
 
 pci:v00008086d00001229sv0000108Esd000010CF*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100(B)
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100(B))
 
 pci:v00008086d00001229sv000010C3sd00001100*
- ID_MODEL_FROM_DATABASE=SmartEther100 SC1100
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (SmartEther100 SC1100)
 
 pci:v00008086d00001229sv000010CFsd00001115*
- ID_MODEL_FROM_DATABASE=8255x-based Ethernet Adapter (10/100)
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (8255x-based Ethernet Adapter (10/100))
 
 pci:v00008086d00001229sv000010CFsd00001143*
- ID_MODEL_FROM_DATABASE=8255x-based Ethernet Adapter (10/100)
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (8255x-based Ethernet Adapter (10/100))
 
 pci:v00008086d00001229sv0000110Asd0000008B*
- ID_MODEL_FROM_DATABASE=82551QM Fast Ethernet Multifuction PCI/CardBus Controller
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (82551QM Fast Ethernet Multifuction PCI/CardBus Controller)
 
 pci:v00008086d00001229sv0000114Asd00000582*
- ID_MODEL_FROM_DATABASE=PC8 onboard ethernet ETH2
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (PC8 onboard ethernet ETH2)
 
 pci:v00008086d00001229sv00001179sd00000001*
- ID_MODEL_FROM_DATABASE=8255x-based Ethernet Adapter (10/100)
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (8255x-based Ethernet Adapter (10/100))
 
 pci:v00008086d00001229sv00001179sd00000002*
- ID_MODEL_FROM_DATABASE=PCI FastEther LAN on Docker
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (PCI FastEther LAN on Docker)
 
 pci:v00008086d00001229sv00001179sd00000003*
- ID_MODEL_FROM_DATABASE=8255x-based Fast Ethernet
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (8255x-based Fast Ethernet)
 
 pci:v00008086d00001229sv00001259sd00002560*
- ID_MODEL_FROM_DATABASE=AT-2560 100
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (AT-2560 100)
 
 pci:v00008086d00001229sv00001259sd00002561*
- ID_MODEL_FROM_DATABASE=AT-2560 100 FX Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (AT-2560 100 FX Ethernet Adapter)
 
 pci:v00008086d00001229sv00001266sd00000001*
- ID_MODEL_FROM_DATABASE=NE10/100 Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (NE10/100 Adapter)
 
 pci:v00008086d00001229sv000013E9sd00001000*
- ID_MODEL_FROM_DATABASE=6221L-4U
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (6221L-4U)
 
 pci:v00008086d00001229sv0000144Dsd00002501*
- ID_MODEL_FROM_DATABASE=SEM-2000 MiniPCI LAN Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (SEM-2000 MiniPCI LAN Adapter)
 
 pci:v00008086d00001229sv0000144Dsd00002502*
- ID_MODEL_FROM_DATABASE=SEM-2100IL MiniPCI LAN Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (SEM-2100IL MiniPCI LAN Adapter)
 
 pci:v00008086d00001229sv00001668sd00001100*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100B (TX) (MiniPCI Ethernet+Modem)
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100B (TX) (MiniPCI Ethernet+Modem))
 
 pci:v00008086d00001229sv00001775sd00001100*
- ID_MODEL_FROM_DATABASE=CR11/VR11 Single Board Computer
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (CR11/VR11 Single Board Computer)
 
 pci:v00008086d00001229sv00001775sd0000CE90*
- ID_MODEL_FROM_DATABASE=CE9
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (CE9)
+
+pci:v00008086d00001229sv00001AF4sd00001100*
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (QEMU Virtual Machine)
 
 pci:v00008086d00001229sv00004C53sd00001080*
- ID_MODEL_FROM_DATABASE=CT8 mainboard
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (CT8 mainboard)
 
 pci:v00008086d00001229sv00004C53sd000010E0*
- ID_MODEL_FROM_DATABASE=PSL09 PrPMC
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (PSL09 PrPMC)
 
 pci:v00008086d00001229sv00008086sd00000001*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100B (TX)
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100B (TX))
 
 pci:v00008086d00001229sv00008086sd00000002*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100B (T4)
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100B (T4))
 
 pci:v00008086d00001229sv00008086sd00000003*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/10+
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/10+)
 
 pci:v00008086d00001229sv00008086sd00000004*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 WfM
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 WfM)
 
 pci:v00008086d00001229sv00008086sd00000005*
- ID_MODEL_FROM_DATABASE=82557 10/100
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (82557 10/100)
 
 pci:v00008086d00001229sv00008086sd00000006*
- ID_MODEL_FROM_DATABASE=82557 10/100 with Wake on LAN
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (82557 10/100 with Wake on LAN)
 
 pci:v00008086d00001229sv00008086sd00000007*
- ID_MODEL_FROM_DATABASE=82558 10/100 Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (82558 10/100 Adapter)
 
 pci:v00008086d00001229sv00008086sd00000008*
- ID_MODEL_FROM_DATABASE=82558 10/100 with Wake on LAN
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (82558 10/100 with Wake on LAN)
 
 pci:v00008086d00001229sv00008086sd00000009*
- ID_MODEL_FROM_DATABASE=82558B PRO/100+ PCI (TP)
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (82558B PRO/100+ PCI (TP))
 
 pci:v00008086d00001229sv00008086sd0000000A*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100+ Management Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100+ Management Adapter)
 
 pci:v00008086d00001229sv00008086sd0000000B*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100+
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100+)
 
 pci:v00008086d00001229sv00008086sd0000000C*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100+ Management Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100+ Management Adapter)
 
 pci:v00008086d00001229sv00008086sd0000000D*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100+ Alert On LAN II* Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100+ Alert On LAN II* Adapter)
 
 pci:v00008086d00001229sv00008086sd0000000E*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100+ Management Adapter with Alert On LAN*
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100+ Management Adapter with Alert On LAN*)
 
 pci:v00008086d00001229sv00008086sd0000000F*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 Desktop Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 Desktop Adapter)
 
 pci:v00008086d00001229sv00008086sd00000010*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 S Management Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 S Management Adapter)
 
 pci:v00008086d00001229sv00008086sd00000011*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 S Management Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 S Management Adapter)
 
 pci:v00008086d00001229sv00008086sd00000012*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 S Advanced Management Adapter (D)
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 S Advanced Management Adapter (D))
 
 pci:v00008086d00001229sv00008086sd00000013*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 S Advanced Management Adapter (E)
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 S Advanced Management Adapter (E))
 
 pci:v00008086d00001229sv00008086sd00000030*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100  Management Adapter with Alert On LAN* GC
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100  Management Adapter with Alert On LAN* GC)
 
 pci:v00008086d00001229sv00008086sd00000031*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 Desktop Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 Desktop Adapter)
 
 pci:v00008086d00001229sv00008086sd00000040*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 S Desktop Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 S Desktop Adapter)
 
 pci:v00008086d00001229sv00008086sd00000041*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 S Desktop Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 S Desktop Adapter)
 
 pci:v00008086d00001229sv00008086sd00000042*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 Desktop Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 Desktop Adapter)
 
 pci:v00008086d00001229sv00008086sd00000050*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 S Desktop Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 S Desktop Adapter)
 
 pci:v00008086d00001229sv00008086sd00001009*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100+ Server Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100+ Server Adapter)
 
 pci:v00008086d00001229sv00008086sd0000100C*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100+ Server Adapter (PILA8470B)
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100+ Server Adapter (PILA8470B))
 
 pci:v00008086d00001229sv00008086sd00001012*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 S Server Adapter (D)
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 S Server Adapter (D))
 
 pci:v00008086d00001229sv00008086sd00001013*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 S Server Adapter (E)
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 S Server Adapter (E))
 
 pci:v00008086d00001229sv00008086sd00001015*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 S Dual Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 S Dual Port Server Adapter)
 
 pci:v00008086d00001229sv00008086sd00001017*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100+ Dual Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100+ Dual Port Server Adapter)
 
 pci:v00008086d00001229sv00008086sd00001030*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100+ Management Adapter with Alert On LAN* G Server
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100+ Management Adapter with Alert On LAN* G Server)
 
 pci:v00008086d00001229sv00008086sd00001040*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 S Server Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 S Server Adapter)
 
 pci:v00008086d00001229sv00008086sd00001041*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 S Server Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 S Server Adapter)
 
 pci:v00008086d00001229sv00008086sd00001042*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 Server Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 Server Adapter)
 
 pci:v00008086d00001229sv00008086sd00001050*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 S Server Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 S Server Adapter)
 
 pci:v00008086d00001229sv00008086sd00001051*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 Server Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 Server Adapter)
 
 pci:v00008086d00001229sv00008086sd00001052*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 Server Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 Server Adapter)
 
 pci:v00008086d00001229sv00008086sd000010F0*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100+ Dual Port Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100+ Dual Port Adapter)
 
 pci:v00008086d00001229sv00008086sd00001229*
- ID_MODEL_FROM_DATABASE=82557/8/9 [Ethernet Pro 100]
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (82557/8/9 [Ethernet Pro 100])
 
 pci:v00008086d00001229sv00008086sd00002009*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 S Mobile Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 S Mobile Adapter)
 
 pci:v00008086d00001229sv00008086sd0000200D*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 Cardbus
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 Cardbus)
 
 pci:v00008086d00001229sv00008086sd0000200E*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 LAN+V90 Cardbus Modem
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 LAN+V90 Cardbus Modem)
 
 pci:v00008086d00001229sv00008086sd0000200F*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 SR Mobile Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 SR Mobile Adapter)
 
 pci:v00008086d00001229sv00008086sd00002010*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 S Mobile Combo Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 S Mobile Combo Adapter)
 
 pci:v00008086d00001229sv00008086sd00002013*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 SR Mobile Combo Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 SR Mobile Combo Adapter)
 
 pci:v00008086d00001229sv00008086sd00002016*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 S Mobile Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 S Mobile Adapter)
 
 pci:v00008086d00001229sv00008086sd00002017*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 S Combo Mobile Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 S Combo Mobile Adapter)
 
 pci:v00008086d00001229sv00008086sd00002018*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 SR Mobile Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 SR Mobile Adapter)
 
 pci:v00008086d00001229sv00008086sd00002019*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 SR Combo Mobile Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 SR Combo Mobile Adapter)
 
 pci:v00008086d00001229sv00008086sd00002101*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 P Mobile Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 P Mobile Adapter)
 
 pci:v00008086d00001229sv00008086sd00002102*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 SP Mobile Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 SP Mobile Adapter)
 
 pci:v00008086d00001229sv00008086sd00002103*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 SP Mobile Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 SP Mobile Adapter)
 
 pci:v00008086d00001229sv00008086sd00002104*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 SP Mobile Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 SP Mobile Adapter)
 
 pci:v00008086d00001229sv00008086sd00002105*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 SP Mobile Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 SP Mobile Adapter)
 
 pci:v00008086d00001229sv00008086sd00002106*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 P Mobile Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 P Mobile Adapter)
 
 pci:v00008086d00001229sv00008086sd00002107*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 Network Connection
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 Network Connection)
 
 pci:v00008086d00001229sv00008086sd00002108*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 Network Connection
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 Network Connection)
 
 pci:v00008086d00001229sv00008086sd00002200*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 P Mobile Combo Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 P Mobile Combo Adapter)
 
 pci:v00008086d00001229sv00008086sd00002201*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 P Mobile Combo Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 P Mobile Combo Adapter)
 
 pci:v00008086d00001229sv00008086sd00002202*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 SP Mobile Combo Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 SP Mobile Combo Adapter)
 
 pci:v00008086d00001229sv00008086sd00002203*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100+ MiniPCI
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100+ MiniPCI)
 
 pci:v00008086d00001229sv00008086sd00002204*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100+ MiniPCI
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100+ MiniPCI)
 
 pci:v00008086d00001229sv00008086sd00002205*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 SP Mobile Combo Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 SP Mobile Combo Adapter)
 
 pci:v00008086d00001229sv00008086sd00002206*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 SP Mobile Combo Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 SP Mobile Combo Adapter)
 
 pci:v00008086d00001229sv00008086sd00002207*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 SP Mobile Combo Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 SP Mobile Combo Adapter)
 
 pci:v00008086d00001229sv00008086sd00002208*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 P Mobile Combo Adapter
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 P Mobile Combo Adapter)
 
 pci:v00008086d00001229sv00008086sd00002402*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100+ MiniPCI
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100+ MiniPCI)
 
 pci:v00008086d00001229sv00008086sd00002407*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100+ MiniPCI
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100+ MiniPCI)
 
 pci:v00008086d00001229sv00008086sd00002408*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100+ MiniPCI
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100+ MiniPCI)
 
 pci:v00008086d00001229sv00008086sd00002409*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100+ MiniPCI
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100+ MiniPCI)
 
 pci:v00008086d00001229sv00008086sd0000240F*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100+ MiniPCI
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100+ MiniPCI)
 
 pci:v00008086d00001229sv00008086sd00002410*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100+ MiniPCI
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100+ MiniPCI)
 
 pci:v00008086d00001229sv00008086sd00002411*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100+ MiniPCI
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100+ MiniPCI)
 
 pci:v00008086d00001229sv00008086sd00002412*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100+ MiniPCI
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100+ MiniPCI)
 
 pci:v00008086d00001229sv00008086sd00002413*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100+ MiniPCI
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100+ MiniPCI)
 
 pci:v00008086d00001229sv00008086sd00003000*
- ID_MODEL_FROM_DATABASE=82559 Fast Ethernet LAN on Motherboard
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (82559 Fast Ethernet LAN on Motherboard)
 
 pci:v00008086d00001229sv00008086sd00003001*
- ID_MODEL_FROM_DATABASE=82559 Fast Ethernet LOM with Basic Alert on LAN*
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (82559 Fast Ethernet LOM with Basic Alert on LAN*)
 
 pci:v00008086d00001229sv00008086sd00003002*
- ID_MODEL_FROM_DATABASE=82559 Fast Ethernet LOM with Alert on LAN II*
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (82559 Fast Ethernet LOM with Alert on LAN II*)
 
 pci:v00008086d00001229sv00008086sd00003006*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 S Network Connection
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 S Network Connection)
 
 pci:v00008086d00001229sv00008086sd00003007*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 S Network Connection
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 S Network Connection)
 
 pci:v00008086d00001229sv00008086sd00003008*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 Network Connection
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 Network Connection)
 
 pci:v00008086d00001229sv00008086sd00003010*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 S Network Connection
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 S Network Connection)
 
 pci:v00008086d00001229sv00008086sd00003011*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 S Network Connection
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 S Network Connection)
 
 pci:v00008086d00001229sv00008086sd00003012*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 Network Connection
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (EtherExpress PRO/100 Network Connection)
 
 pci:v00008086d00001229sv00008086sd0000301A*
- ID_MODEL_FROM_DATABASE=S845WD1-E mainboard
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (S845WD1-E mainboard)
 
 pci:v00008086d00001229sv00008086sd00003411*
- ID_MODEL_FROM_DATABASE=SDS2 Mainboard
+ ID_MODEL_FROM_DATABASE=82557/8/9/0/1 Ethernet Pro 100 (SDS2 Mainboard)
 
 pci:v00008086d0000122D*
  ID_MODEL_FROM_DATABASE=430FX - 82437FX TSC [Triton I]
@@ -57717,7 +59139,7 @@ pci:v00008086d00001237*
  ID_MODEL_FROM_DATABASE=440FX - 82441FX PMC [Natoma]
 
 pci:v00008086d00001237sv00001AF4sd00001100*
- ID_MODEL_FROM_DATABASE=Qemu virtual machine
+ ID_MODEL_FROM_DATABASE=440FX - 82441FX PMC [Natoma] (Qemu virtual machine)
 
 pci:v00008086d00001239*
  ID_MODEL_FROM_DATABASE=82371FB PIIX IDE Interface
@@ -57765,10 +59187,10 @@ pci:v00008086d00001461*
  ID_MODEL_FROM_DATABASE=82870P2 P64H2 I/OxAPIC
 
 pci:v00008086d00001461sv000015D9sd00003480*
- ID_MODEL_FROM_DATABASE=P4DP6
+ ID_MODEL_FROM_DATABASE=82870P2 P64H2 I/OxAPIC (P4DP6)
 
 pci:v00008086d00001461sv00004C53sd00001090*
- ID_MODEL_FROM_DATABASE=Cx9/Vx9 mainboard
+ ID_MODEL_FROM_DATABASE=82870P2 P64H2 I/OxAPIC (Cx9/Vx9 mainboard)
 
 pci:v00008086d00001462*
  ID_MODEL_FROM_DATABASE=82870P2 P64H2 Hot Plug Controller
@@ -57780,13 +59202,16 @@ pci:v00008086d00001502*
  ID_MODEL_FROM_DATABASE=82579LM Gigabit Network Connection
 
 pci:v00008086d00001502sv00001028sd000004A3*
- ID_MODEL_FROM_DATABASE=Precision M4600
+ ID_MODEL_FROM_DATABASE=82579LM Gigabit Network Connection (Precision M4600)
+
+pci:v00008086d00001502sv00008086sd0000357A*
+ ID_MODEL_FROM_DATABASE=82579LM Gigabit Network Connection (Server Board S1200BTS)
 
 pci:v00008086d00001503*
  ID_MODEL_FROM_DATABASE=82579V Gigabit Network Connection
 
 pci:v00008086d00001503sv00001043sd0000849C*
- ID_MODEL_FROM_DATABASE=P8P67 Deluxe Motherboard
+ ID_MODEL_FROM_DATABASE=82579V Gigabit Network Connection (P8P67 Deluxe Motherboard)
 
 pci:v00008086d00001507*
  ID_MODEL_FROM_DATABASE=Ethernet Express Module X520-P2
@@ -57816,19 +59241,19 @@ pci:v00008086d0000150D*
  ID_MODEL_FROM_DATABASE=82576 Gigabit Backplane Connection
 
 pci:v00008086d0000150Dsv00008086sd0000A10C*
- ID_MODEL_FROM_DATABASE=Gigabit ET Quad Port Mezzanine Card
+ ID_MODEL_FROM_DATABASE=82576 Gigabit Backplane Connection (Gigabit ET Quad Port Mezzanine Card)
 
 pci:v00008086d0000150E*
  ID_MODEL_FROM_DATABASE=82580 Gigabit Network Connection
 
 pci:v00008086d0000150Esv0000103Csd00001780*
- ID_MODEL_FROM_DATABASE=NC365T 4-port Ethernet Server Adapter
+ ID_MODEL_FROM_DATABASE=82580 Gigabit Network Connection (NC365T 4-port Ethernet Server Adapter)
 
 pci:v00008086d0000150Esv00008086sd000012A1*
- ID_MODEL_FROM_DATABASE=Ethernet Server Adapter I340-T4
+ ID_MODEL_FROM_DATABASE=82580 Gigabit Network Connection (Ethernet Server Adapter I340-T4)
 
 pci:v00008086d0000150Esv00008086sd000012A2*
- ID_MODEL_FROM_DATABASE=Ethernet Server Adapter I340-T4
+ ID_MODEL_FROM_DATABASE=82580 Gigabit Network Connection (Ethernet Server Adapter I340-T4)
 
 pci:v00008086d0000150F*
  ID_MODEL_FROM_DATABASE=82580 Gigabit Fiber Network Connection
@@ -57852,16 +59277,16 @@ pci:v00008086d00001516*
  ID_MODEL_FROM_DATABASE=82580 Gigabit Network Connection
 
 pci:v00008086d00001516sv00008086sd000012B1*
- ID_MODEL_FROM_DATABASE=Ethernet Server Adapter I340-T2
+ ID_MODEL_FROM_DATABASE=82580 Gigabit Network Connection (Ethernet Server Adapter I340-T2)
 
 pci:v00008086d00001516sv00008086sd000012B2*
- ID_MODEL_FROM_DATABASE=Ethernet Server Adapter I340-T2
+ ID_MODEL_FROM_DATABASE=82580 Gigabit Network Connection (Ethernet Server Adapter I340-T2)
 
 pci:v00008086d00001517*
  ID_MODEL_FROM_DATABASE=82599ES 10 Gigabit Network Connection
 
 pci:v00008086d00001517sv00001137sd0000006A*
- ID_MODEL_FROM_DATABASE=UCS CNA M61KR-I Intel Converged Network Adapter
+ ID_MODEL_FROM_DATABASE=82599ES 10 Gigabit Network Connection (UCS CNA M61KR-I Intel Converged Network Adapter)
 
 pci:v00008086d00001518*
  ID_MODEL_FROM_DATABASE=82576NS SerDes Gigabit Network Connection
@@ -57870,7 +59295,7 @@ pci:v00008086d0000151C*
  ID_MODEL_FROM_DATABASE=82599 10 Gigabit TN Network Connection
 
 pci:v00008086d0000151Csv0000108Esd00007B13*
- ID_MODEL_FROM_DATABASE=Dual 10GBASE-T LP
+ ID_MODEL_FROM_DATABASE=82599 10 Gigabit TN Network Connection (Dual 10GBASE-T LP)
 
 pci:v00008086d00001520*
  ID_MODEL_FROM_DATABASE=I350 Ethernet Controller Virtual Function
@@ -57878,104 +59303,119 @@ pci:v00008086d00001520*
 pci:v00008086d00001521*
  ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection
 
+pci:v00008086d00001521sv00001028sd00000602*
+ ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (Gigabit 2P I350-t LOM)
+
 pci:v00008086d00001521sv00001028sd00001F60*
- ID_MODEL_FROM_DATABASE=Intel GbE 4P I350crNDC
+ ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (Gigabit 4P I350-t rNDC)
 
 pci:v00008086d00001521sv00001028sd00001F62*
- ID_MODEL_FROM_DATABASE=Intel GbE 2P I350crNDC
+ ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (Gigabit 4P X540/I350 rNDC)
+
+pci:v00008086d00001521sv00001028sd0000FF9A*
+ ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (Gigabit 4P X710/I350 rNDC)
 
 pci:v00008086d00001521sv0000103Csd000017D1*
- ID_MODEL_FROM_DATABASE=Ethernet 1Gb 4-port 366FLR Adapter
+ ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (Ethernet 1Gb 4-port 366FLR Adapter)
 
 pci:v00008086d00001521sv0000103Csd00002003*
- ID_MODEL_FROM_DATABASE=Ethernet 1Gb 2-port 367i Adapter
+ ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (Ethernet 1Gb 2-port 367i Adapter)
 
 pci:v00008086d00001521sv0000103Csd00002226*
- ID_MODEL_FROM_DATABASE=Ethernet 1Gb 1-port 364i Adapter
+ ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (Ethernet 1Gb 1-port 364i Adapter)
 
 pci:v00008086d00001521sv0000103Csd0000337F*
- ID_MODEL_FROM_DATABASE=Ethernet 1Gb 2-port 361i Adapter
+ ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (Ethernet 1Gb 2-port 361i Adapter)
 
 pci:v00008086d00001521sv0000103Csd00003380*
- ID_MODEL_FROM_DATABASE=Ethernet 1Gb 4-port 366i Adapter
+ ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (Ethernet 1Gb 4-port 366i Adapter)
 
 pci:v00008086d00001521sv0000103Csd0000339E*
- ID_MODEL_FROM_DATABASE=Ethernet 1Gb 2-port 361T Adapter
+ ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (Ethernet 1Gb 2-port 361T Adapter)
 
 pci:v00008086d00001521sv0000108Esd00007B16*
- ID_MODEL_FROM_DATABASE=Quad Port GbE PCIe 2.0 ExpressModule, UTP
+ ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (Quad Port GbE PCIe 2.0 ExpressModule, UTP)
 
 pci:v00008086d00001521sv0000108Esd00007B18*
- ID_MODEL_FROM_DATABASE=Quad Port GbE PCIe 2.0 Low Profile Adapter, UTP
+ ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (Quad Port GbE PCIe 2.0 Low Profile Adapter, UTP)
 
 pci:v00008086d00001521sv000010A9sd0000802A*
- ID_MODEL_FROM_DATABASE=UV2-BaseIO dual-port GbE
+ ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (UV2-BaseIO dual-port GbE)
+
+pci:v00008086d00001521sv000017AAsd00001074*
+ ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (ThinkServer I350-T4 AnyFabric)
 
 pci:v00008086d00001521sv00008086sd00000001*
- ID_MODEL_FROM_DATABASE=Ethernet Server Adapter I350-T4
+ ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (Ethernet Server Adapter I350-T4)
 
 pci:v00008086d00001521sv00008086sd00000002*
- ID_MODEL_FROM_DATABASE=Ethernet Server Adapter I350-T2
+ ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (Ethernet Server Adapter I350-T2)
 
 pci:v00008086d00001521sv00008086sd000000A1*
- ID_MODEL_FROM_DATABASE=Ethernet Server Adapter I350-T4
+ ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (Ethernet Server Adapter I350-T4)
 
 pci:v00008086d00001521sv00008086sd000000A2*
- ID_MODEL_FROM_DATABASE=Ethernet Server Adapter I350-T2
+ ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (Ethernet Server Adapter I350-T2)
 
 pci:v00008086d00001521sv00008086sd00005001*
- ID_MODEL_FROM_DATABASE=Ethernet Server Adapter I350-T4
+ ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (Ethernet Server Adapter I350-T4)
 
 pci:v00008086d00001521sv00008086sd00005002*
- ID_MODEL_FROM_DATABASE=Ethernet Server Adapter I350-T2
+ ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection (Ethernet Server Adapter I350-T2)
 
 pci:v00008086d00001522*
  ID_MODEL_FROM_DATABASE=I350 Gigabit Fiber Network Connection
 
 pci:v00008086d00001522sv0000108Esd00007B17*
- ID_MODEL_FROM_DATABASE=Quad Port GbE PCIe 2.0 ExpressModule, MMF
+ ID_MODEL_FROM_DATABASE=I350 Gigabit Fiber Network Connection (Quad Port GbE PCIe 2.0 ExpressModule, MMF)
 
 pci:v00008086d00001522sv0000108Esd00007B19*
- ID_MODEL_FROM_DATABASE=Dual Port GbE PCIe 2.0 Low Profile Adapter, MMF
+ ID_MODEL_FROM_DATABASE=I350 Gigabit Fiber Network Connection (Dual Port GbE PCIe 2.0 Low Profile Adapter, MMF)
 
 pci:v00008086d00001522sv00008086sd00000002*
- ID_MODEL_FROM_DATABASE=Ethernet Server Adapter I350-T2
+ ID_MODEL_FROM_DATABASE=I350 Gigabit Fiber Network Connection (Ethernet Server Adapter I350-T2)
 
 pci:v00008086d00001522sv00008086sd00000003*
- ID_MODEL_FROM_DATABASE=Ethernet Server Adapter I350-F4
+ ID_MODEL_FROM_DATABASE=I350 Gigabit Fiber Network Connection (Ethernet Server Adapter I350-F4)
 
 pci:v00008086d00001522sv00008086sd00000004*
- ID_MODEL_FROM_DATABASE=Ethernet Server Adapter I350-F2
+ ID_MODEL_FROM_DATABASE=I350 Gigabit Fiber Network Connection (Ethernet Server Adapter I350-F2)
 
 pci:v00008086d00001522sv00008086sd00000005*
- ID_MODEL_FROM_DATABASE=Ethernet Server Adapter I350-F1
+ ID_MODEL_FROM_DATABASE=I350 Gigabit Fiber Network Connection (Ethernet Server Adapter I350-F1)
 
 pci:v00008086d00001522sv00008086sd000000A2*
- ID_MODEL_FROM_DATABASE=Ethernet Server Adapter I350-T2
+ ID_MODEL_FROM_DATABASE=I350 Gigabit Fiber Network Connection (Ethernet Server Adapter I350-T2)
 
 pci:v00008086d00001522sv00008086sd000000A3*
- ID_MODEL_FROM_DATABASE=Ethernet Server Adapter I350-F4
+ ID_MODEL_FROM_DATABASE=I350 Gigabit Fiber Network Connection (Ethernet Server Adapter I350-F4)
 
 pci:v00008086d00001522sv00008086sd000000A4*
- ID_MODEL_FROM_DATABASE=Ethernet Server Adapter I350-F2
+ ID_MODEL_FROM_DATABASE=I350 Gigabit Fiber Network Connection (Ethernet Server Adapter I350-F2)
 
 pci:v00008086d00001523*
  ID_MODEL_FROM_DATABASE=I350 Gigabit Backplane Connection
 
+pci:v00008086d00001523sv00001028sd00000060*
+ ID_MODEL_FROM_DATABASE=I350 Gigabit Backplane Connection (Gigabit 2P I350 LOM)
+
+pci:v00008086d00001523sv00001028sd00001F9B*
+ ID_MODEL_FROM_DATABASE=I350 Gigabit Backplane Connection (Gigabit 4P I350-t bNDC)
+
 pci:v00008086d00001523sv0000103Csd00001784*
- ID_MODEL_FROM_DATABASE=Ethernet 1Gb 2-port 361FLB Adapter
+ ID_MODEL_FROM_DATABASE=I350 Gigabit Backplane Connection (Ethernet 1Gb 2-port 361FLB Adapter)
 
 pci:v00008086d00001523sv0000103Csd000018D1*
- ID_MODEL_FROM_DATABASE=Ethernet 1Gb 2-port 361FLB Adapter
+ ID_MODEL_FROM_DATABASE=I350 Gigabit Backplane Connection (Ethernet 1Gb 2-port 361FLB Adapter)
 
 pci:v00008086d00001523sv0000103Csd00001989*
- ID_MODEL_FROM_DATABASE=Ethernet 1Gb 2-port 363i Adapter
+ ID_MODEL_FROM_DATABASE=I350 Gigabit Backplane Connection (Ethernet 1Gb 2-port 363i Adapter)
 
 pci:v00008086d00001523sv0000103Csd0000339F*
- ID_MODEL_FROM_DATABASE=Ethernet 1Gb 4-port 366M Adapter
+ ID_MODEL_FROM_DATABASE=I350 Gigabit Backplane Connection (Ethernet 1Gb 4-port 366M Adapter)
 
 pci:v00008086d00001523sv00008086sd00001F52*
- ID_MODEL_FROM_DATABASE=1GbE 4P I350 Mezz
+ ID_MODEL_FROM_DATABASE=I350 Gigabit Backplane Connection (1GbE 4P I350 Mezz)
 
 pci:v00008086d00001524*
  ID_MODEL_FROM_DATABASE=I350 Gigabit Connection
@@ -57987,61 +59427,64 @@ pci:v00008086d00001526*
  ID_MODEL_FROM_DATABASE=82576 Gigabit Network Connection
 
 pci:v00008086d00001526sv00008086sd0000A05C*
- ID_MODEL_FROM_DATABASE=Gigabit ET2 Quad Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82576 Gigabit Network Connection (Gigabit ET2 Quad Port Server Adapter)
 
 pci:v00008086d00001526sv00008086sd0000A06C*
- ID_MODEL_FROM_DATABASE=Gigabit ET2 Quad Port Server Adapter
+ ID_MODEL_FROM_DATABASE=82576 Gigabit Network Connection (Gigabit ET2 Quad Port Server Adapter)
 
 pci:v00008086d00001527*
  ID_MODEL_FROM_DATABASE=82580 Gigabit Fiber Network Connection
 
 pci:v00008086d00001527sv00008086sd00000001*
- ID_MODEL_FROM_DATABASE=Ethernet Server Adapter I340-F4
+ ID_MODEL_FROM_DATABASE=82580 Gigabit Fiber Network Connection (Ethernet Server Adapter I340-F4)
 
 pci:v00008086d00001527sv00008086sd00000002*
- ID_MODEL_FROM_DATABASE=Ethernet Server Adapter I340-F4
+ ID_MODEL_FROM_DATABASE=82580 Gigabit Fiber Network Connection (Ethernet Server Adapter I340-F4)
 
 pci:v00008086d00001528*
  ID_MODEL_FROM_DATABASE=Ethernet Controller 10-Gigabit X540-AT2
 
 pci:v00008086d00001528sv00001028sd00001F61*
- ID_MODEL_FROM_DATABASE=Ethernet 10G 4P X540/I350 rNDC
+ ID_MODEL_FROM_DATABASE=Ethernet Controller 10-Gigabit X540-AT2 (Ethernet 10G 4P X540/I350 rNDC)
 
 pci:v00008086d00001528sv0000103Csd0000192D*
- ID_MODEL_FROM_DATABASE=561FLR-T 2-port 10Gb Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=Ethernet Controller 10-Gigabit X540-AT2 (561FLR-T 2-port 10Gb Ethernet Adapter)
 
 pci:v00008086d00001528sv0000103Csd00002004*
- ID_MODEL_FROM_DATABASE=Ethernet 10Gb 2-port 561i Adapter
+ ID_MODEL_FROM_DATABASE=Ethernet Controller 10-Gigabit X540-AT2 (Ethernet 10Gb 2-port 561i Adapter)
 
 pci:v00008086d00001528sv0000103Csd0000211A*
- ID_MODEL_FROM_DATABASE=Ethernet 10Gb 2-port 561T Adapter
+ ID_MODEL_FROM_DATABASE=Ethernet Controller 10-Gigabit X540-AT2 (Ethernet 10Gb 2-port 561T Adapter)
 
 pci:v00008086d00001528sv0000108Esd00007B14*
- ID_MODEL_FROM_DATABASE=Sun Dual Port 10 GbE PCIe 2.0 ExpressModule, Base-T
+ ID_MODEL_FROM_DATABASE=Ethernet Controller 10-Gigabit X540-AT2 (Sun Dual Port 10 GbE PCIe 2.0 ExpressModule, Base-T)
 
 pci:v00008086d00001528sv0000108Esd00007B15*
- ID_MODEL_FROM_DATABASE=Sun Dual Port 10 GbE PCIe 2.0 Low Profile Adapter, Base-T
+ ID_MODEL_FROM_DATABASE=Ethernet Controller 10-Gigabit X540-AT2 (Sun Dual Port 10 GbE PCIe 2.0 Low Profile Adapter, Base-T)
 
 pci:v00008086d00001528sv00001137sd000000BF*
- ID_MODEL_FROM_DATABASE=Ethernet Converged Network Adapter X540-T2
+ ID_MODEL_FROM_DATABASE=Ethernet Controller 10-Gigabit X540-AT2 (Ethernet Converged Network Adapter X540-T2)
+
+pci:v00008086d00001528sv000017AAsd00001073*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller 10-Gigabit X540-AT2 (ThinkServer X540-T2 AnyFabric)
 
 pci:v00008086d00001528sv00008086sd00000001*
- ID_MODEL_FROM_DATABASE=Ethernet Converged Network Adapter X540-T2
+ ID_MODEL_FROM_DATABASE=Ethernet Controller 10-Gigabit X540-AT2 (Ethernet Converged Network Adapter X540-T2)
 
 pci:v00008086d00001528sv00008086sd00000002*
- ID_MODEL_FROM_DATABASE=Ethernet Converged Network Adapter X540-T1
+ ID_MODEL_FROM_DATABASE=Ethernet Controller 10-Gigabit X540-AT2 (Ethernet Converged Network Adapter X540-T1)
 
 pci:v00008086d00001528sv00008086sd0000001A*
- ID_MODEL_FROM_DATABASE=Ethernet Converged Network Adapter X540-T2
+ ID_MODEL_FROM_DATABASE=Ethernet Controller 10-Gigabit X540-AT2 (Ethernet Converged Network Adapter X540-T2)
 
 pci:v00008086d00001528sv00008086sd000000A2*
- ID_MODEL_FROM_DATABASE=Ethernet Converged Network Adapter X540-T1
+ ID_MODEL_FROM_DATABASE=Ethernet Controller 10-Gigabit X540-AT2 (Ethernet Converged Network Adapter X540-T1)
 
 pci:v00008086d00001528sv00008086sd00001F61*
- ID_MODEL_FROM_DATABASE=Ethernet 10G 4P X540/I350 rNDC
+ ID_MODEL_FROM_DATABASE=Ethernet Controller 10-Gigabit X540-AT2 (Ethernet 10G 4P X540/I350 rNDC)
 
 pci:v00008086d00001528sv00008086sd00005003*
- ID_MODEL_FROM_DATABASE=Ethernet 10G 2P X540-t Adapter
+ ID_MODEL_FROM_DATABASE=Ethernet Controller 10-Gigabit X540-AT2 (Ethernet 10G 2P X540-t Adapter)
 
 pci:v00008086d00001529*
  ID_MODEL_FROM_DATABASE=82599 10 Gigabit Dual Port Network Connection with FCoE
@@ -58053,16 +59496,19 @@ pci:v00008086d00001533*
  ID_MODEL_FROM_DATABASE=I210 Gigabit Network Connection
 
 pci:v00008086d00001533sv0000103Csd00000003*
- ID_MODEL_FROM_DATABASE=Ethernet Server Adapter I210-T1
+ ID_MODEL_FROM_DATABASE=I210 Gigabit Network Connection (Ethernet I210-T1 GbE NIC)
+
+pci:v00008086d00001533sv000010A9sd0000802C*
+ ID_MODEL_FROM_DATABASE=I210 Gigabit Network Connection (UV300 BaseIO single-port GbE)
+
+pci:v00008086d00001533sv000017AAsd00001100*
+ ID_MODEL_FROM_DATABASE=I210 Gigabit Network Connection (ThinkServer Ethernet Server Adapter)
 
 pci:v00008086d00001533sv00008086sd00000001*
- ID_MODEL_FROM_DATABASE=Ethernet Server Adapter I210-T1
+ ID_MODEL_FROM_DATABASE=I210 Gigabit Network Connection (Ethernet Server Adapter I210-T1)
 
 pci:v00008086d00001533sv00008086sd00000002*
- ID_MODEL_FROM_DATABASE=Ethernet Server Adapter I210-T1
-
-pci:v00008086d00001534*
- ID_MODEL_FROM_DATABASE=I210 Gigabit Network Connection
+ ID_MODEL_FROM_DATABASE=I210 Gigabit Network Connection (Ethernet Server Adapter I210-T1)
 
 pci:v00008086d00001536*
  ID_MODEL_FROM_DATABASE=I210 Gigabit Fiber Network Connection
@@ -58079,8 +59525,11 @@ pci:v00008086d00001539*
 pci:v00008086d0000153A*
  ID_MODEL_FROM_DATABASE=Ethernet Connection I217-LM
 
+pci:v00008086d0000153Asv0000103Csd00001909*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection I217-LM (ZBook 15)
+
 pci:v00008086d0000153Asv000017AAsd0000220E*
- ID_MODEL_FROM_DATABASE=ThinkPad T440p
+ ID_MODEL_FROM_DATABASE=Ethernet Connection I217-LM (ThinkPad T440p)
 
 pci:v00008086d0000153B*
  ID_MODEL_FROM_DATABASE=Ethernet Connection I217-V
@@ -58095,25 +59544,28 @@ pci:v00008086d0000154A*
  ID_MODEL_FROM_DATABASE=Ethernet Server Adapter X520-4
 
 pci:v00008086d0000154Asv00008086sd0000011A*
- ID_MODEL_FROM_DATABASE=Ethernet Converged Network Adapter X520-4
+ ID_MODEL_FROM_DATABASE=Ethernet Server Adapter X520-4 (Ethernet Converged Network Adapter X520-4)
 
 pci:v00008086d0000154Asv00008086sd0000011B*
- ID_MODEL_FROM_DATABASE=Ethernet Converged Network Adapter X520-4
+ ID_MODEL_FROM_DATABASE=Ethernet Server Adapter X520-4 (Ethernet Converged Network Adapter X520-4)
 
 pci:v00008086d0000154Asv00008086sd0000011C*
- ID_MODEL_FROM_DATABASE=Ethernet Converged Network Adapter X520-4
+ ID_MODEL_FROM_DATABASE=Ethernet Server Adapter X520-4 (Ethernet Converged Network Adapter X520-4)
+
+pci:v00008086d0000154C*
+ ID_MODEL_FROM_DATABASE=XL710/X710 Virtual Function
 
 pci:v00008086d0000154D*
  ID_MODEL_FROM_DATABASE=Ethernet 10G 2P X520 Adapter
 
 pci:v00008086d0000154Dsv00008086sd00007B11*
- ID_MODEL_FROM_DATABASE=10GbE 2P X520 Adapter
+ ID_MODEL_FROM_DATABASE=Ethernet 10G 2P X520 Adapter (10GbE 2P X520 Adapter)
 
 pci:v00008086d00001557*
  ID_MODEL_FROM_DATABASE=82599 10 Gigabit Network Connection
 
 pci:v00008086d00001557sv00008086sd00000001*
- ID_MODEL_FROM_DATABASE=Ethernet OCP Server Adapter X520-1
+ ID_MODEL_FROM_DATABASE=82599 10 Gigabit Network Connection (Ethernet OCP Server Adapter X520-1)
 
 pci:v00008086d00001558*
  ID_MODEL_FROM_DATABASE=Ethernet Converged Network Adapter X520-Q1
@@ -58130,30 +59582,114 @@ pci:v00008086d00001559*
 pci:v00008086d0000155A*
  ID_MODEL_FROM_DATABASE=Ethernet Connection I218-LM
 
+pci:v00008086d0000155Asv000017AAsd00002214*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection I218-LM (ThinkPad X240)
+
 pci:v00008086d0000155C*
  ID_MODEL_FROM_DATABASE=Ethernet Server Bypass Adapter
 
 pci:v00008086d0000155Csv00008086sd00000001*
- ID_MODEL_FROM_DATABASE=Ethernet Server Bypass Adapter X540-T2
+ ID_MODEL_FROM_DATABASE=Ethernet Server Bypass Adapter (X540-T2)
 
 pci:v00008086d0000155D*
  ID_MODEL_FROM_DATABASE=Ethernet Server Bypass Adapter
 
 pci:v00008086d0000155Dsv00008086sd00000001*
- ID_MODEL_FROM_DATABASE=Ethernet Server Bypass Adapter X520-SR2
+ ID_MODEL_FROM_DATABASE=Ethernet Server Bypass Adapter (X520-SR2)
 
 pci:v00008086d0000155Dsv00008086sd00000002*
- ID_MODEL_FROM_DATABASE=Ethernet Server Bypass Adapter X520-LR2
+ ID_MODEL_FROM_DATABASE=Ethernet Server Bypass Adapter (X520-LR2)
 
 pci:v00008086d00001560*
  ID_MODEL_FROM_DATABASE=Ethernet Controller X540
 
+pci:v00008086d0000156F*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection I219-LM
+
+pci:v00008086d00001570*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection I219-V
+
+pci:v00008086d00001571*
+ ID_MODEL_FROM_DATABASE=XL710/X710 Virtual Function
+
+pci:v00008086d00001572*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+
+
+pci:v00008086d00001572sv00001028sd00001F99*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (Ethernet 10G 4P X710/I350 rNDC)
+
+pci:v00008086d00001572sv00008086sd00000000*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (Ethernet Converged Network Adapter X710)
+
+pci:v00008086d00001572sv00008086sd00000001*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (Ethernet Converged Network Adapter X710-4)
+
+pci:v00008086d00001572sv00008086sd00000002*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (Ethernet Converged Network Adapter X710-4)
+
+pci:v00008086d00001572sv00008086sd00000004*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (Ethernet Converged Network Adapter X710-4)
+
+pci:v00008086d00001572sv00008086sd00000005*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (Ethernet 10G 4P X710 Adapter)
+
+pci:v00008086d00001572sv00008086sd00000006*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (Ethernet 10G 2P X710 Adapter)
+
+pci:v00008086d00001572sv00008086sd00000007*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (Ethernet Converged Network Adapter X710-2)
+
+pci:v00008086d00001572sv00008086sd00000008*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (Ethernet Converged Network Adapter X710-2)
+
 pci:v00008086d0000157B*
  ID_MODEL_FROM_DATABASE=I210 Gigabit Network Connection
 
 pci:v00008086d0000157C*
  ID_MODEL_FROM_DATABASE=I210 Gigabit Backplane Connection
 
+pci:v00008086d00001580*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller XL710 for 40GbE backplane
+
+pci:v00008086d00001581*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE backplane
+
+pci:v00008086d00001581sv00001028sd00001F98*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE backplane (Ethernet 10G 4P X710-k bNDC)
+
+pci:v00008086d00001583*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller XL710 for 40GbE QSFP+
+
+pci:v00008086d00001583sv00008086sd00000000*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller XL710 for 40GbE QSFP+ (Ethernet Converged Network Adapter XL710-Q2)
+
+pci:v00008086d00001583sv00008086sd00000001*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller XL710 for 40GbE QSFP+ (Ethernet Converged Network Adapter XL710-Q2)
+
+pci:v00008086d00001583sv00008086sd00000002*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller XL710 for 40GbE QSFP+ (Ethernet Converged Network Adapter XL710-Q2)
+
+pci:v00008086d00001583sv00008086sd00000003*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller XL710 for 40GbE QSFP+ (Ethernet I/O Module XL710-Q2)
+
+pci:v00008086d00001584*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller XL710 for 40GbE QSFP+
+
+pci:v00008086d00001584sv00008086sd00000000*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller XL710 for 40GbE QSFP+ (Ethernet Converged Network Adapter XL710-Q1)
+
+pci:v00008086d00001584sv00008086sd00000001*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller XL710 for 40GbE QSFP+ (Ethernet Converged Network Adapter XL710-Q1)
+
+pci:v00008086d00001584sv00008086sd00000002*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller XL710 for 40GbE QSFP+ (Ethernet Converged Network Adapter XL710-Q1)
+
+pci:v00008086d00001584sv00008086sd00000003*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller XL710 for 40GbE QSFP+ (Ethernet I/O Module XL710-Q1)
+
+pci:v00008086d00001585*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller XL710 for 10GbE QSFP+
+
 pci:v00008086d000015A0*
  ID_MODEL_FROM_DATABASE=Ethernet Connection (2) I218-LM
 
@@ -58166,86 +59702,203 @@ pci:v00008086d000015A2*
 pci:v00008086d000015A3*
  ID_MODEL_FROM_DATABASE=Ethernet Connection (3) I218-V
 
+pci:v00008086d000015B7*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection (2) I219-V
+
+pci:v00008086d000015B8*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection (2) I219-LM
+
+pci:v00008086d00001600*
+ ID_MODEL_FROM_DATABASE=Broadwell-U Host Bridge -OPI
+
+pci:v00008086d00001601*
+ ID_MODEL_FROM_DATABASE=Broadwell-U PCI Express x16 Controller
+
+pci:v00008086d00001602*
+ ID_MODEL_FROM_DATABASE=Broadwell-U Integrated Graphics
+
+pci:v00008086d00001603*
+ ID_MODEL_FROM_DATABASE=Broadwell-U Camarillo Device
+
+pci:v00008086d00001604*
+ ID_MODEL_FROM_DATABASE=Broadwell-U Host Bridge -OPI
+
+pci:v00008086d00001605*
+ ID_MODEL_FROM_DATABASE=Broadwell-U PCI Express x8 Controller
+
+pci:v00008086d00001606*
+ ID_MODEL_FROM_DATABASE=Broadwell-U Integrated Graphics
+
+pci:v00008086d00001607*
+ ID_MODEL_FROM_DATABASE=Broadwell-U CHAPS Device
+
+pci:v00008086d00001608*
+ ID_MODEL_FROM_DATABASE=Broadwell-U Host Bridge -OPI
+
+pci:v00008086d00001609*
+ ID_MODEL_FROM_DATABASE=Broadwell-U x4 PCIe
+
+pci:v00008086d0000160A*
+ ID_MODEL_FROM_DATABASE=Broadwell-U Integrated Graphics
+
+pci:v00008086d0000160B*
+ ID_MODEL_FROM_DATABASE=Broadwell-U Integrated Graphics
+
+pci:v00008086d0000160C*
+ ID_MODEL_FROM_DATABASE=Broadwell-U Audio Controller
+
+pci:v00008086d0000160D*
+ ID_MODEL_FROM_DATABASE=Broadwell-U Integrated Graphics
+
+pci:v00008086d0000160E*
+ ID_MODEL_FROM_DATABASE=Broadwell-U Integrated Graphics
+
+pci:v00008086d0000160F*
+ ID_MODEL_FROM_DATABASE=Broadwell-U SoftSKU
+
+pci:v00008086d00001610*
+ ID_MODEL_FROM_DATABASE=Broadwell-U Host Bridge - DMI
+
+pci:v00008086d00001612*
+ ID_MODEL_FROM_DATABASE=Broadwell-U Integrated Graphics
+
+pci:v00008086d00001614*
+ ID_MODEL_FROM_DATABASE=Broadwell-U Host Bridge - DMI
+
+pci:v00008086d00001616*
+ ID_MODEL_FROM_DATABASE=Broadwell-U Integrated Graphics
+
+pci:v00008086d00001618*
+ ID_MODEL_FROM_DATABASE=Broadwell-U Host Bridge - DMI
+
+pci:v00008086d0000161A*
+ ID_MODEL_FROM_DATABASE=Broadwell-U Integrated Graphics
+
+pci:v00008086d0000161B*
+ ID_MODEL_FROM_DATABASE=Broadwell-U Integrated Graphics
+
+pci:v00008086d0000161D*
+ ID_MODEL_FROM_DATABASE=Broadwell-U Integrated Graphics
+
+pci:v00008086d0000161E*
+ ID_MODEL_FROM_DATABASE=Broadwell-U Integrated Graphics
+
+pci:v00008086d00001622*
+ ID_MODEL_FROM_DATABASE=Broadwell-U Integrated Graphics
+
+pci:v00008086d00001626*
+ ID_MODEL_FROM_DATABASE=Broadwell-U Integrated Graphics
+
+pci:v00008086d0000162A*
+ ID_MODEL_FROM_DATABASE=Broadwell-U Integrated Graphics
+
+pci:v00008086d0000162B*
+ ID_MODEL_FROM_DATABASE=Broadwell-U Integrated Graphics
+
+pci:v00008086d0000162D*
+ ID_MODEL_FROM_DATABASE=Broadwell-U Integrated Graphics
+
+pci:v00008086d0000162E*
+ ID_MODEL_FROM_DATABASE=Broadwell-U Integrated Graphics
+
+pci:v00008086d00001632*
+ ID_MODEL_FROM_DATABASE=Broadwell-U Integrated Graphics
+
+pci:v00008086d00001636*
+ ID_MODEL_FROM_DATABASE=Broadwell-U Integrated Graphics
+
+pci:v00008086d0000163A*
+ ID_MODEL_FROM_DATABASE=Broadwell-U Integrated Graphics
+
+pci:v00008086d0000163B*
+ ID_MODEL_FROM_DATABASE=Broadwell-U Integrated Graphics
+
+pci:v00008086d0000163D*
+ ID_MODEL_FROM_DATABASE=Broadwell-U Integrated Graphics
+
+pci:v00008086d0000163E*
+ ID_MODEL_FROM_DATABASE=Broadwell-U Integrated Graphics
+
 pci:v00008086d00001960*
  ID_MODEL_FROM_DATABASE=80960RP (i960RP) Microprocessor
 
 pci:v00008086d00001960sv0000101Esd00000431*
- ID_MODEL_FROM_DATABASE=MegaRAID 431 RAID Controller
+ ID_MODEL_FROM_DATABASE=80960RP (i960RP) Microprocessor (MegaRAID 431 RAID Controller)
 
 pci:v00008086d00001960sv0000101Esd00000438*
- ID_MODEL_FROM_DATABASE=MegaRAID 438 Ultra2 LVD RAID Controller
+ ID_MODEL_FROM_DATABASE=80960RP (i960RP) Microprocessor (MegaRAID 438 Ultra2 LVD RAID Controller)
 
 pci:v00008086d00001960sv0000101Esd00000466*
- ID_MODEL_FROM_DATABASE=MegaRAID 466 Express Plus RAID Controller
+ ID_MODEL_FROM_DATABASE=80960RP (i960RP) Microprocessor (MegaRAID 466 Express Plus RAID Controller)
 
 pci:v00008086d00001960sv0000101Esd00000467*
- ID_MODEL_FROM_DATABASE=MegaRAID 467 Enterprise 1500 RAID Controller
+ ID_MODEL_FROM_DATABASE=80960RP (i960RP) Microprocessor (MegaRAID 467 Enterprise 1500 RAID Controller)
 
 pci:v00008086d00001960sv0000101Esd00000490*
- ID_MODEL_FROM_DATABASE=MegaRAID 490 Express 300 RAID Controller
+ ID_MODEL_FROM_DATABASE=80960RP (i960RP) Microprocessor (MegaRAID 490 Express 300 RAID Controller)
 
 pci:v00008086d00001960sv0000101Esd00000762*
- ID_MODEL_FROM_DATABASE=MegaRAID 762 Express RAID Controller
+ ID_MODEL_FROM_DATABASE=80960RP (i960RP) Microprocessor (MegaRAID 762 Express RAID Controller)
 
 pci:v00008086d00001960sv0000101Esd000009A0*
- ID_MODEL_FROM_DATABASE=PowerEdge Expandable RAID Controller 2/SC
+ ID_MODEL_FROM_DATABASE=80960RP (i960RP) Microprocessor (PowerEdge Expandable RAID Controller 2/SC)
 
 pci:v00008086d00001960sv00001028sd00000467*
- ID_MODEL_FROM_DATABASE=PowerEdge Expandable RAID Controller 2/DC
+ ID_MODEL_FROM_DATABASE=80960RP (i960RP) Microprocessor (PowerEdge Expandable RAID Controller 2/DC)
 
 pci:v00008086d00001960sv00001028sd00001111*
- ID_MODEL_FROM_DATABASE=PowerEdge Expandable RAID Controller 2/SC
+ ID_MODEL_FROM_DATABASE=80960RP (i960RP) Microprocessor (PowerEdge Expandable RAID Controller 2/SC)
 
 pci:v00008086d00001960sv0000103Csd000003A2*
- ID_MODEL_FROM_DATABASE=MegaRAID
+ ID_MODEL_FROM_DATABASE=80960RP (i960RP) Microprocessor (MegaRAID)
 
 pci:v00008086d00001960sv0000103Csd000010C6*
- ID_MODEL_FROM_DATABASE=MegaRAID 438, NetRAID-3Si
+ ID_MODEL_FROM_DATABASE=80960RP (i960RP) Microprocessor (MegaRAID 438, NetRAID-3Si)
 
 pci:v00008086d00001960sv0000103Csd000010C7*
- ID_MODEL_FROM_DATABASE=MegaRAID T5, Integrated NetRAID
+ ID_MODEL_FROM_DATABASE=80960RP (i960RP) Microprocessor (MegaRAID T5, Integrated NetRAID)
 
 pci:v00008086d00001960sv0000103Csd000010CC*
- ID_MODEL_FROM_DATABASE=MegaRAID, Integrated NetRAID
+ ID_MODEL_FROM_DATABASE=80960RP (i960RP) Microprocessor (MegaRAID, Integrated NetRAID)
 
 pci:v00008086d00001960sv0000103Csd000010CD*
- ID_MODEL_FROM_DATABASE=NetRAID-1Si
+ ID_MODEL_FROM_DATABASE=80960RP (i960RP) Microprocessor (NetRAID-1Si)
 
 pci:v00008086d00001960sv0000105Asd00000000*
- ID_MODEL_FROM_DATABASE=SuperTrak
+ ID_MODEL_FROM_DATABASE=80960RP (i960RP) Microprocessor (SuperTrak)
 
 pci:v00008086d00001960sv0000105Asd00002168*
- ID_MODEL_FROM_DATABASE=SuperTrak Pro
+ ID_MODEL_FROM_DATABASE=80960RP (i960RP) Microprocessor (SuperTrak Pro)
 
 pci:v00008086d00001960sv0000105Asd00005168*
- ID_MODEL_FROM_DATABASE=SuperTrak66/100
+ ID_MODEL_FROM_DATABASE=80960RP (i960RP) Microprocessor (SuperTrak66/100)
 
 pci:v00008086d00001960sv00001111sd00001111*
- ID_MODEL_FROM_DATABASE=MegaRAID 466, PowerEdge Expandable RAID Controller 2/SC
+ ID_MODEL_FROM_DATABASE=80960RP (i960RP) Microprocessor (MegaRAID 466, PowerEdge Expandable RAID Controller 2/SC)
 
 pci:v00008086d00001960sv00001111sd00001112*
- ID_MODEL_FROM_DATABASE=PowerEdge Expandable RAID Controller 2/SC
+ ID_MODEL_FROM_DATABASE=80960RP (i960RP) Microprocessor (PowerEdge Expandable RAID Controller 2/SC)
 
 pci:v00008086d00001960sv0000113Csd000003A2*
- ID_MODEL_FROM_DATABASE=MegaRAID
+ ID_MODEL_FROM_DATABASE=80960RP (i960RP) Microprocessor (MegaRAID)
 
 pci:v00008086d00001960sv0000E4BFsd00001010*
- ID_MODEL_FROM_DATABASE=CG1-RADIO
+ ID_MODEL_FROM_DATABASE=80960RP (i960RP) Microprocessor (CG1-RADIO)
 
 pci:v00008086d00001960sv0000E4BFsd00001020*
- ID_MODEL_FROM_DATABASE=CU2-QUARTET
+ ID_MODEL_FROM_DATABASE=80960RP (i960RP) Microprocessor (CU2-QUARTET)
 
 pci:v00008086d00001960sv0000E4BFsd00001040*
- ID_MODEL_FROM_DATABASE=CU1-CHORUS
+ ID_MODEL_FROM_DATABASE=80960RP (i960RP) Microprocessor (CU1-CHORUS)
 
 pci:v00008086d00001960sv0000E4BFsd00003100*
- ID_MODEL_FROM_DATABASE=CX1-BAND
+ ID_MODEL_FROM_DATABASE=80960RP (i960RP) Microprocessor (CX1-BAND)
 
 pci:v00008086d00001962*
  ID_MODEL_FROM_DATABASE=80960RM (i960RM) Microprocessor
 
 pci:v00008086d00001962sv0000105Asd00000000*
- ID_MODEL_FROM_DATABASE=SuperTrak SX6000 I2O CPU
+ ID_MODEL_FROM_DATABASE=80960RM (i960RM) Microprocessor (SuperTrak SX6000 I2O CPU)
 
 pci:v00008086d00001A21*
  ID_MODEL_FROM_DATABASE=82840 840 [Carmel] Chipset Host Bridge (Hub A)
@@ -58260,10 +59913,10 @@ pci:v00008086d00001A30*
  ID_MODEL_FROM_DATABASE=82845 845 [Brookdale] Chipset Host Bridge
 
 pci:v00008086d00001A30sv00001028sd0000010E*
- ID_MODEL_FROM_DATABASE=Optiplex GX240
+ ID_MODEL_FROM_DATABASE=82845 845 [Brookdale] Chipset Host Bridge (Optiplex GX240)
 
 pci:v00008086d00001A30sv000015D9sd00003280*
- ID_MODEL_FROM_DATABASE=Supermicro P4SBE Mainboard
+ ID_MODEL_FROM_DATABASE=82845 845 [Brookdale] Chipset Host Bridge (Supermicro P4SBE Mainboard)
 
 pci:v00008086d00001A31*
  ID_MODEL_FROM_DATABASE=82845 845 [Brookdale] Chipset AGP Bridge
@@ -58272,28 +59925,28 @@ pci:v00008086d00001A38*
  ID_MODEL_FROM_DATABASE=5000 Series Chipset DMA Engine
 
 pci:v00008086d00001A38sv000015D9sd00008680*
- ID_MODEL_FROM_DATABASE=X7DVL-E-O motherboard
+ ID_MODEL_FROM_DATABASE=5000 Series Chipset DMA Engine (X7DVL-E-O motherboard)
 
 pci:v00008086d00001A38sv00008086sd00003476*
- ID_MODEL_FROM_DATABASE=Intel S5000PSLSATA Server Board
+ ID_MODEL_FROM_DATABASE=5000 Series Chipset DMA Engine (Intel S5000PSLSATA Server Board)
 
 pci:v00008086d00001A48*
  ID_MODEL_FROM_DATABASE=82597EX 10GbE Ethernet Controller
 
 pci:v00008086d00001A48sv00008086sd0000A01F*
- ID_MODEL_FROM_DATABASE=PRO/10GbE SR Server Adapter
+ ID_MODEL_FROM_DATABASE=82597EX 10GbE Ethernet Controller (PRO/10GbE SR Server Adapter)
 
 pci:v00008086d00001A48sv00008086sd0000A11F*
- ID_MODEL_FROM_DATABASE=PRO/10GbE SR Server Adapter
+ ID_MODEL_FROM_DATABASE=82597EX 10GbE Ethernet Controller (PRO/10GbE SR Server Adapter)
 
 pci:v00008086d00001B48*
  ID_MODEL_FROM_DATABASE=82597EX 10GbE Ethernet Controller
 
 pci:v00008086d00001B48sv00008086sd0000A01F*
- ID_MODEL_FROM_DATABASE=PRO/10GbE LR Server Adapter
+ ID_MODEL_FROM_DATABASE=82597EX 10GbE Ethernet Controller (PRO/10GbE LR Server Adapter)
 
 pci:v00008086d00001B48sv00008086sd0000A11F*
- ID_MODEL_FROM_DATABASE=PRO/10GbE LR Server Adapter
+ ID_MODEL_FROM_DATABASE=82597EX 10GbE Ethernet Controller (PRO/10GbE LR Server Adapter)
 
 pci:v00008086d00001C00*
  ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 4 port SATA IDE Controller
@@ -58305,25 +59958,28 @@ pci:v00008086d00001C02*
  ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family SATA AHCI Controller
 
 pci:v00008086d00001C02sv00001028sd000004AA*
- ID_MODEL_FROM_DATABASE=XPS 8300
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family SATA AHCI Controller (XPS 8300)
 
 pci:v00008086d00001C02sv00001043sd0000844D*
- ID_MODEL_FROM_DATABASE=P8P67 Deluxe Motherboard
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family SATA AHCI Controller (P8 series motherboard)
+
+pci:v00008086d00001C02sv00008086sd00007270*
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family SATA AHCI Controller (Server Board S1200BTS)
 
 pci:v00008086d00001C03*
  ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 6 port SATA AHCI Controller
 
 pci:v00008086d00001C03sv00001028sd000004A3*
- ID_MODEL_FROM_DATABASE=Precision M4600
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 6 port SATA AHCI Controller (Precision M4600)
 
 pci:v00008086d00001C03sv00001028sd000004B2*
- ID_MODEL_FROM_DATABASE=Vostro 3350
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 6 port SATA AHCI Controller (Vostro 3350)
 
 pci:v00008086d00001C03sv00001028sd000004DA*
- ID_MODEL_FROM_DATABASE=Vostro 3750
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 6 port SATA AHCI Controller (Vostro 3750)
 
 pci:v00008086d00001C03sv00008086sd00007270*
- ID_MODEL_FROM_DATABASE=Apple MacBookPro8,2 [Core i7, 15", 2011]
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 6 port SATA AHCI Controller (Apple MacBookPro8,2 [Core i7, 15", 2011])
 
 pci:v00008086d00001C04*
  ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family SATA RAID Controller
@@ -58341,49 +59997,58 @@ pci:v00008086d00001C10*
  ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 1
 
 pci:v00008086d00001C10sv00001028sd000004AA*
- ID_MODEL_FROM_DATABASE=XPS 8300
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 1 (XPS 8300)
 
 pci:v00008086d00001C10sv00001028sd000004DA*
- ID_MODEL_FROM_DATABASE=Vostro 3750
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 1 (Vostro 3750)
+
+pci:v00008086d00001C10sv00001043sd0000844D*
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 1 (P8 series motherboard)
 
 pci:v00008086d00001C10sv00008086sd00007270*
- ID_MODEL_FROM_DATABASE=Apple MacBookPro8,2 [Core i7, 15", 2011]
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 1 (Server Board S1200BTS / Apple MacBook Pro 8,1/8,2)
 
 pci:v00008086d00001C12*
  ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 2
 
 pci:v00008086d00001C12sv00001028sd000004AA*
- ID_MODEL_FROM_DATABASE=XPS 8300
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 2 (XPS 8300)
 
 pci:v00008086d00001C12sv00008086sd00007270*
- ID_MODEL_FROM_DATABASE=Apple MacBookPro8,2 [Core i7, 15", 2011]
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 2 (Apple MacBookPro8,2 [Core i7, 15", 2011])
 
 pci:v00008086d00001C14*
  ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 3
 
 pci:v00008086d00001C14sv00001028sd000004DA*
- ID_MODEL_FROM_DATABASE=Vostro 3750
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 3 (Vostro 3750)
 
 pci:v00008086d00001C14sv00008086sd00007270*
- ID_MODEL_FROM_DATABASE=Apple MacBookPro8,2 [Core i7, 15", 2011]
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 3 (Apple MacBookPro8,2 [Core i7, 15", 2011])
 
 pci:v00008086d00001C16*
  ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 4
 
 pci:v00008086d00001C16sv00001028sd000004AA*
- ID_MODEL_FROM_DATABASE=XPS 8300
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 4 (XPS 8300)
 
 pci:v00008086d00001C18*
  ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 5
 
 pci:v00008086d00001C18sv00001028sd000004DA*
- ID_MODEL_FROM_DATABASE=Vostro 3750
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 5 (Vostro 3750)
+
+pci:v00008086d00001C18sv00008086sd00007270*
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 5 (Server Board S1200BTS)
 
 pci:v00008086d00001C1A*
  ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 6
 
 pci:v00008086d00001C1Asv00001028sd000004DA*
- ID_MODEL_FROM_DATABASE=Vostro 3750
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 6 (Vostro 3750)
+
+pci:v00008086d00001C1Asv00001043sd0000844D*
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 6 (P8 series motherboard)
 
 pci:v00008086d00001C1C*
  ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 7
@@ -58391,53 +60056,59 @@ pci:v00008086d00001C1C*
 pci:v00008086d00001C1E*
  ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 8
 
+pci:v00008086d00001C1Esv00001043sd0000844D*
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 8 (P8 series motherboard)
+
 pci:v00008086d00001C20*
  ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family High Definition Audio Controller
 
 pci:v00008086d00001C20sv00001028sd00000490*
- ID_MODEL_FROM_DATABASE=Alienware M17x R3
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family High Definition Audio Controller (Alienware M17x R3)
 
 pci:v00008086d00001C20sv00001028sd000004A3*
- ID_MODEL_FROM_DATABASE=Precision M4600
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family High Definition Audio Controller (Precision M4600)
 
 pci:v00008086d00001C20sv00001028sd000004AA*
- ID_MODEL_FROM_DATABASE=XPS 8300
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family High Definition Audio Controller (XPS 8300)
 
 pci:v00008086d00001C20sv00001028sd000004B2*
- ID_MODEL_FROM_DATABASE=Vostro 3350
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family High Definition Audio Controller (Vostro 3350)
 
 pci:v00008086d00001C20sv00001028sd000004DA*
- ID_MODEL_FROM_DATABASE=Vostro 3750
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family High Definition Audio Controller (Vostro 3750)
 
 pci:v00008086d00001C20sv00001043sd00008418*
- ID_MODEL_FROM_DATABASE=P8P67 Deluxe Motherboard
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family High Definition Audio Controller (P8P67 Deluxe Motherboard)
+
+pci:v00008086d00001C20sv00001043sd0000841B*
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family High Definition Audio Controller (P8H67 Series Motherboard)
 
 pci:v00008086d00001C20sv00008086sd00002008*
- ID_MODEL_FROM_DATABASE=DQ67SW board
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family High Definition Audio Controller (DQ67SW board)
 
 pci:v00008086d00001C20sv00008086sd00007270*
- ID_MODEL_FROM_DATABASE=Apple MacBookPro8,2 [Core i7, 15", 2011]
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family High Definition Audio Controller (Apple MacBookPro8,2 [Core i7, 15", 2011])
 
 pci:v00008086d00001C22*
  ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family SMBus Controller
 
 pci:v00008086d00001C22sv00001028sd000004A3*
- ID_MODEL_FROM_DATABASE=Precision M4600
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family SMBus Controller (Precision M4600)
 
 pci:v00008086d00001C22sv00001028sd000004AA*
- ID_MODEL_FROM_DATABASE=XPS 8300
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family SMBus Controller (XPS 8300)
 
 pci:v00008086d00001C22sv00001028sd000004B2*
- ID_MODEL_FROM_DATABASE=Vostro 3350
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family SMBus Controller (Vostro 3350)
 
 pci:v00008086d00001C22sv00001028sd000004DA*
- ID_MODEL_FROM_DATABASE=Vostro 3750
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family SMBus Controller (Vostro 3750)
 
 pci:v00008086d00001C22sv00001043sd0000844D*
- ID_MODEL_FROM_DATABASE=P8P67 Deluxe Motherboard
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family SMBus Controller (P8 series motherboard)
 
 pci:v00008086d00001C22sv00008086sd00007270*
- ID_MODEL_FROM_DATABASE=Apple MacBookPro8,2 [Core i7, 15", 2011]
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family SMBus Controller (Server Board S1200BTS / Apple MacBook Pro 8,1/8,2)
 
 pci:v00008086d00001C24*
  ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family Thermal Management Controller
@@ -58449,55 +60120,55 @@ pci:v00008086d00001C26*
  ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Enhanced Host Controller #1
 
 pci:v00008086d00001C26sv00001028sd000004A3*
- ID_MODEL_FROM_DATABASE=Precision M4600
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Enhanced Host Controller #1 (Precision M4600)
 
 pci:v00008086d00001C26sv00001028sd000004AA*
- ID_MODEL_FROM_DATABASE=XPS 8300
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Enhanced Host Controller #1 (XPS 8300)
 
 pci:v00008086d00001C26sv00001028sd000004B2*
- ID_MODEL_FROM_DATABASE=Vostro 3350
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Enhanced Host Controller #1 (Vostro 3350)
 
 pci:v00008086d00001C26sv00001028sd000004DA*
- ID_MODEL_FROM_DATABASE=Vostro 3750
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Enhanced Host Controller #1 (Vostro 3750)
 
 pci:v00008086d00001C26sv00001043sd0000844D*
- ID_MODEL_FROM_DATABASE=P8P67 Deluxe Motherboard
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Enhanced Host Controller #1 (P8 series motherboard)
 
 pci:v00008086d00001C26sv00008086sd00007270*
- ID_MODEL_FROM_DATABASE=Apple MacBookPro8,2 [Core i7, 15", 2011]
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Enhanced Host Controller #1 (Server Board S1200BTS / Apple MacBook Pro 8,1/8,2)
 
 pci:v00008086d00001C27*
  ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Universal Host Controller #1
 
 pci:v00008086d00001C27sv00008086sd00007270*
- ID_MODEL_FROM_DATABASE=Apple MacBookPro8,2 [Core i7, 15", 2011]
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Universal Host Controller #1 (Apple MacBookPro8,2 [Core i7, 15", 2011])
 
 pci:v00008086d00001C2C*
  ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Universal Host Controller #5
 
 pci:v00008086d00001C2Csv00008086sd00007270*
- ID_MODEL_FROM_DATABASE=Apple MacBookPro8,2 [Core i7, 15", 2011]
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Universal Host Controller #5 (Apple MacBookPro8,2 [Core i7, 15", 2011])
 
 pci:v00008086d00001C2D*
  ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Enhanced Host Controller #2
 
 pci:v00008086d00001C2Dsv00001028sd000004A3*
- ID_MODEL_FROM_DATABASE=Precision M4600
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Enhanced Host Controller #2 (Precision M4600)
 
 pci:v00008086d00001C2Dsv00001028sd000004AA*
- ID_MODEL_FROM_DATABASE=XPS 8300
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Enhanced Host Controller #2 (XPS 8300)
 
 pci:v00008086d00001C2Dsv00001028sd000004B2*
- ID_MODEL_FROM_DATABASE=Vostro 3350
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Enhanced Host Controller #2 (Vostro 3350)
 
 pci:v00008086d00001C2Dsv00001028sd000004DA*
- ID_MODEL_FROM_DATABASE=Vostro 3750
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Enhanced Host Controller #2 (Vostro 3750)
 
 pci:v00008086d00001C2Dsv00001043sd0000844D*
- ID_MODEL_FROM_DATABASE=P8P67 Deluxe Motherboard
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Enhanced Host Controller #2 (P8 series motherboard)
 
 pci:v00008086d00001C2Dsv00008086sd00007270*
- ID_MODEL_FROM_DATABASE=Apple MacBookPro8,2 [Core i7, 15", 2011]
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Enhanced Host Controller #2 (Server Board S1200BTS / Apple MacBook Pro 8,1/8,2)
 
 pci:v00008086d00001C33*
  ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family LAN Controller
@@ -58509,22 +60180,22 @@ pci:v00008086d00001C3A*
  ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family MEI Controller #1
 
 pci:v00008086d00001C3Asv00001028sd000004A3*
- ID_MODEL_FROM_DATABASE=Precision M4600
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family MEI Controller #1 (Precision M4600)
 
 pci:v00008086d00001C3Asv00001028sd000004AA*
- ID_MODEL_FROM_DATABASE=XPS 8300
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family MEI Controller #1 (XPS 8300)
 
 pci:v00008086d00001C3Asv00001028sd000004B2*
- ID_MODEL_FROM_DATABASE=Vostro 3350
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family MEI Controller #1 (Vostro 3350)
 
 pci:v00008086d00001C3Asv00001028sd000004DA*
- ID_MODEL_FROM_DATABASE=Vostro 3750
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family MEI Controller #1 (Vostro 3750)
 
 pci:v00008086d00001C3Asv00001043sd0000844D*
- ID_MODEL_FROM_DATABASE=P8P67 Deluxe Motherboard
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family MEI Controller #1 (P8 series motherboard)
 
 pci:v00008086d00001C3Asv00008086sd00007270*
- ID_MODEL_FROM_DATABASE=Apple MacBookPro8,2 [Core i7, 15", 2011]
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family MEI Controller #1 (Apple MacBookPro8,2 [Core i7, 15", 2011])
 
 pci:v00008086d00001C3B*
  ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family MEI Controller #2
@@ -58557,7 +60228,7 @@ pci:v00008086d00001C46*
  ID_MODEL_FROM_DATABASE=P67 Express Chipset Family LPC Controller
 
 pci:v00008086d00001C46sv00001043sd0000844D*
- ID_MODEL_FROM_DATABASE=P8P67 Deluxe Motherboard
+ ID_MODEL_FROM_DATABASE=P67 Express Chipset Family LPC Controller (P8P67 Deluxe Motherboard)
 
 pci:v00008086d00001C47*
  ID_MODEL_FROM_DATABASE=UM67 Express Chipset Family LPC Controller
@@ -58569,22 +60240,25 @@ pci:v00008086d00001C49*
  ID_MODEL_FROM_DATABASE=HM65 Express Chipset Family LPC Controller
 
 pci:v00008086d00001C49sv00008086sd00007270*
- ID_MODEL_FROM_DATABASE=Apple MacBookPro8,2 [Core i7, 15", 2011]
+ ID_MODEL_FROM_DATABASE=HM65 Express Chipset Family LPC Controller (Apple MacBookPro8,2 [Core i7, 15", 2011])
 
 pci:v00008086d00001C4A*
  ID_MODEL_FROM_DATABASE=H67 Express Chipset Family LPC Controller
 
 pci:v00008086d00001C4Asv00001028sd000004AA*
- ID_MODEL_FROM_DATABASE=XPS 8300
+ ID_MODEL_FROM_DATABASE=H67 Express Chipset Family LPC Controller (XPS 8300)
+
+pci:v00008086d00001C4Asv00001043sd0000844D*
+ ID_MODEL_FROM_DATABASE=H67 Express Chipset Family LPC Controller (P8H67 Series Motherboard)
 
 pci:v00008086d00001C4B*
  ID_MODEL_FROM_DATABASE=HM67 Express Chipset Family LPC Controller
 
 pci:v00008086d00001C4Bsv00001028sd000004B2*
- ID_MODEL_FROM_DATABASE=Vostro 3350
+ ID_MODEL_FROM_DATABASE=HM67 Express Chipset Family LPC Controller (Vostro 3350)
 
 pci:v00008086d00001C4Bsv00001028sd000004DA*
- ID_MODEL_FROM_DATABASE=Vostro 3750
+ ID_MODEL_FROM_DATABASE=HM67 Express Chipset Family LPC Controller (Vostro 3750)
 
 pci:v00008086d00001C4C*
  ID_MODEL_FROM_DATABASE=Q65 Express Chipset Family LPC Controller
@@ -58599,7 +60273,7 @@ pci:v00008086d00001C4F*
  ID_MODEL_FROM_DATABASE=QM67 Express Chipset Family LPC Controller
 
 pci:v00008086d00001C4Fsv00001028sd000004A3*
- ID_MODEL_FROM_DATABASE=Precision M4600
+ ID_MODEL_FROM_DATABASE=QM67 Express Chipset Family LPC Controller (Precision M4600)
 
 pci:v00008086d00001C50*
  ID_MODEL_FROM_DATABASE=B65 Express Chipset Family LPC Controller
@@ -58610,6 +60284,9 @@ pci:v00008086d00001C51*
 pci:v00008086d00001C52*
  ID_MODEL_FROM_DATABASE=C202 Chipset Family LPC Controller
 
+pci:v00008086d00001C52sv00008086sd00007270*
+ ID_MODEL_FROM_DATABASE=C202 Chipset Family LPC Controller (Server Board S1200BTS)
+
 pci:v00008086d00001C53*
  ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family LPC Controller
 
@@ -58622,6 +60299,9 @@ pci:v00008086d00001C55*
 pci:v00008086d00001C56*
  ID_MODEL_FROM_DATABASE=C206 Chipset Family LPC Controller
 
+pci:v00008086d00001C56sv00001043sd0000844D*
+ ID_MODEL_FROM_DATABASE=C206 Chipset Family LPC Controller (P8B WS Motherboard)
+
 pci:v00008086d00001C57*
  ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family LPC Controller
 
@@ -58851,19 +60531,19 @@ pci:v00008086d00001E02*
  ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family 6-port SATA Controller [AHCI mode]
 
 pci:v00008086d00001E02sv00001043sd000084CA*
- ID_MODEL_FROM_DATABASE=P8H77-I Motherboard
+ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family 6-port SATA Controller [AHCI mode] (P8 series motherboard)
 
 pci:v00008086d00001E02sv00001849sd00001E02*
- ID_MODEL_FROM_DATABASE=Motherboard
+ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family 6-port SATA Controller [AHCI mode] (Motherboard)
 
 pci:v00008086d00001E03*
  ID_MODEL_FROM_DATABASE=7 Series Chipset Family 6-port SATA Controller [AHCI mode]
 
 pci:v00008086d00001E03sv00001043sd00001477*
- ID_MODEL_FROM_DATABASE=N56VZ
+ ID_MODEL_FROM_DATABASE=7 Series Chipset Family 6-port SATA Controller [AHCI mode] (N56VZ)
 
 pci:v00008086d00001E03sv00001043sd00001517*
- ID_MODEL_FROM_DATABASE=Zenbook Prime UX31A
+ ID_MODEL_FROM_DATABASE=7 Series Chipset Family 6-port SATA Controller [AHCI mode] (Zenbook Prime UX31A)
 
 pci:v00008086d00001E04*
  ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family SATA Controller [RAID mode]
@@ -58890,25 +60570,25 @@ pci:v00008086d00001E10*
  ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 1
 
 pci:v00008086d00001E10sv00001043sd00001477*
- ID_MODEL_FROM_DATABASE=N56VZ
+ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 1 (N56VZ)
 
 pci:v00008086d00001E10sv00001043sd00001517*
- ID_MODEL_FROM_DATABASE=Zenbook Prime UX31A
+ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 1 (Zenbook Prime UX31A)
 
 pci:v00008086d00001E10sv00001043sd000084CA*
- ID_MODEL_FROM_DATABASE=P8H77-I Motherboard
+ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 1 (P8H77-I Motherboard)
 
 pci:v00008086d00001E10sv00001849sd00001E10*
- ID_MODEL_FROM_DATABASE=Motherboard
+ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 1 (Motherboard)
 
 pci:v00008086d00001E12*
  ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 2
 
 pci:v00008086d00001E12sv00001043sd00001477*
- ID_MODEL_FROM_DATABASE=N56VZ
+ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 2 (N56VZ)
 
 pci:v00008086d00001E12sv00001043sd00001517*
- ID_MODEL_FROM_DATABASE=Zenbook Prime UX31A
+ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 2 (Zenbook Prime UX31A)
 
 pci:v00008086d00001E14*
  ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 3
@@ -58917,25 +60597,25 @@ pci:v00008086d00001E16*
  ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 4
 
 pci:v00008086d00001E16sv00001043sd00001477*
- ID_MODEL_FROM_DATABASE=N56VZ
+ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 4 (N56VZ)
 
 pci:v00008086d00001E16sv00001849sd00001618*
- ID_MODEL_FROM_DATABASE=Z77 Extreme4 motherboard
+ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 4 (Z77 Extreme4 motherboard)
 
 pci:v00008086d00001E18*
  ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 5
 
 pci:v00008086d00001E18sv00001043sd000084CA*
- ID_MODEL_FROM_DATABASE=P8H77-I Motherboard
+ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 5 (P8H77-I Motherboard)
 
 pci:v00008086d00001E18sv00001849sd00001E18*
- ID_MODEL_FROM_DATABASE=Motherboard
+ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 5 (Motherboard)
 
 pci:v00008086d00001E1A*
  ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 6
 
 pci:v00008086d00001E1Asv00001849sd00001E1A*
- ID_MODEL_FROM_DATABASE=Motherboard
+ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 6 (Motherboard)
 
 pci:v00008086d00001E1C*
  ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 7
@@ -58944,43 +60624,46 @@ pci:v00008086d00001E1E*
  ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 8
 
 pci:v00008086d00001E1Esv00001849sd00001E1E*
- ID_MODEL_FROM_DATABASE=Motherboard
+ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family PCI Express Root Port 8 (Motherboard)
 
 pci:v00008086d00001E20*
  ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family High Definition Audio Controller
 
 pci:v00008086d00001E20sv00001043sd00001477*
- ID_MODEL_FROM_DATABASE=N56VZ
+ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family High Definition Audio Controller (N56VZ)
 
 pci:v00008086d00001E20sv00001043sd00001517*
- ID_MODEL_FROM_DATABASE=Zenbook Prime UX31A
+ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family High Definition Audio Controller (Zenbook Prime UX31A)
 
 pci:v00008086d00001E20sv00001043sd00008415*
- ID_MODEL_FROM_DATABASE=P8H77-I Motherboard
+ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family High Definition Audio Controller (P8H77-I Motherboard)
+
+pci:v00008086d00001E20sv00001043sd00008445*
+ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family High Definition Audio Controller (ASUS P8Z77-V LX Motherboard)
 
 pci:v00008086d00001E20sv00001849sd00001898*
- ID_MODEL_FROM_DATABASE=Z77 Extreme4 motherboard
+ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family High Definition Audio Controller (Z77 Extreme4 motherboard)
 
 pci:v00008086d00001E22*
  ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family SMBus Controller
 
 pci:v00008086d00001E22sv00001043sd00001477*
- ID_MODEL_FROM_DATABASE=N56VZ
+ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family SMBus Controller (N56VZ)
 
 pci:v00008086d00001E22sv00001043sd00001517*
- ID_MODEL_FROM_DATABASE=Zenbook Prime UX31A
+ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family SMBus Controller (Zenbook Prime UX31A)
 
 pci:v00008086d00001E22sv00001043sd000084CA*
- ID_MODEL_FROM_DATABASE=P8H77-I Motherboard
+ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family SMBus Controller (P8 series motherboard)
 
 pci:v00008086d00001E22sv00001849sd00001E22*
- ID_MODEL_FROM_DATABASE=Motherboard
+ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family SMBus Controller (Motherboard)
 
 pci:v00008086d00001E24*
  ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family Thermal Management Controller
 
 pci:v00008086d00001E24sv00001043sd00001517*
- ID_MODEL_FROM_DATABASE=Zenbook Prime UX31A
+ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family Thermal Management Controller (Zenbook Prime UX31A)
 
 pci:v00008086d00001E25*
  ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family DMI to PCI Bridge
@@ -58989,49 +60672,49 @@ pci:v00008086d00001E26*
  ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family USB Enhanced Host Controller #1
 
 pci:v00008086d00001E26sv00001043sd00001477*
- ID_MODEL_FROM_DATABASE=N56VZ
+ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family USB Enhanced Host Controller #1 (N56VZ)
 
 pci:v00008086d00001E26sv00001043sd00001517*
- ID_MODEL_FROM_DATABASE=Zenbook Prime UX31A
+ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family USB Enhanced Host Controller #1 (Zenbook Prime UX31A)
 
 pci:v00008086d00001E26sv00001043sd000084CA*
- ID_MODEL_FROM_DATABASE=P8H77-I Motherboard
+ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family USB Enhanced Host Controller #1 (P8 series motherboard)
 
 pci:v00008086d00001E26sv00001849sd00001E26*
- ID_MODEL_FROM_DATABASE=Motherboard
+ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family USB Enhanced Host Controller #1 (Motherboard)
 
 pci:v00008086d00001E2D*
  ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family USB Enhanced Host Controller #2
 
 pci:v00008086d00001E2Dsv00001043sd00001477*
- ID_MODEL_FROM_DATABASE=N56VZ
+ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family USB Enhanced Host Controller #2 (N56VZ)
 
 pci:v00008086d00001E2Dsv00001043sd00001517*
- ID_MODEL_FROM_DATABASE=Zenbook Prime UX31A
+ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family USB Enhanced Host Controller #2 (Zenbook Prime UX31A)
 
 pci:v00008086d00001E2Dsv00001043sd000084CA*
- ID_MODEL_FROM_DATABASE=P8H77-I Motherboard
+ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family USB Enhanced Host Controller #2 (P8 series motherboard)
 
 pci:v00008086d00001E2Dsv00001849sd00001E2D*
- ID_MODEL_FROM_DATABASE=Motherboard
+ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family USB Enhanced Host Controller #2 (Motherboard)
 
 pci:v00008086d00001E31*
  ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family USB xHCI Host Controller
 
 pci:v00008086d00001E31sv0000103Csd000017AB*
- ID_MODEL_FROM_DATABASE=ProBook 6570b
+ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family USB xHCI Host Controller (ProBook 6570b)
 
 pci:v00008086d00001E31sv00001043sd00001477*
- ID_MODEL_FROM_DATABASE=N56VZ
+ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family USB xHCI Host Controller (N56VZ)
 
 pci:v00008086d00001E31sv00001043sd00001517*
- ID_MODEL_FROM_DATABASE=Zenbook Prime UX31A
+ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family USB xHCI Host Controller (Zenbook Prime UX31A)
 
 pci:v00008086d00001E31sv00001043sd000084CA*
- ID_MODEL_FROM_DATABASE=P8H77-I Motherboard
+ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family USB xHCI Host Controller (P8 series motherboard)
 
 pci:v00008086d00001E31sv00001849sd00001E31*
- ID_MODEL_FROM_DATABASE=Motherboard
+ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family USB xHCI Host Controller (Motherboard)
 
 pci:v00008086d00001E33*
  ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family LAN Controller
@@ -59040,16 +60723,16 @@ pci:v00008086d00001E3A*
  ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family MEI Controller #1
 
 pci:v00008086d00001E3Asv00001043sd00001477*
- ID_MODEL_FROM_DATABASE=N56VZ
+ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family MEI Controller #1 (N56VZ)
 
 pci:v00008086d00001E3Asv00001043sd00001517*
- ID_MODEL_FROM_DATABASE=Zenbook Prime UX31A
+ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family MEI Controller #1 (Zenbook Prime UX31A)
 
 pci:v00008086d00001E3Asv00001043sd000084CA*
- ID_MODEL_FROM_DATABASE=P8H77-I Motherboard
+ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family MEI Controller #1 (P8 series motherboard)
 
 pci:v00008086d00001E3Asv00001849sd00001E3A*
- ID_MODEL_FROM_DATABASE=Motherboard
+ ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family MEI Controller #1 (Motherboard)
 
 pci:v00008086d00001E3B*
  ID_MODEL_FROM_DATABASE=7 Series/C210 Series Chipset Family MEI Controller #2
@@ -59072,8 +60755,11 @@ pci:v00008086d00001E43*
 pci:v00008086d00001E44*
  ID_MODEL_FROM_DATABASE=Z77 Express Chipset LPC Controller
 
+pci:v00008086d00001E44sv00001043sd000084CA*
+ ID_MODEL_FROM_DATABASE=Z77 Express Chipset LPC Controller (P8 series motherboard)
+
 pci:v00008086d00001E44sv00001849sd00001E44*
- ID_MODEL_FROM_DATABASE=Motherboard
+ ID_MODEL_FROM_DATABASE=Z77 Express Chipset LPC Controller (Motherboard)
 
 pci:v00008086d00001E45*
  ID_MODEL_FROM_DATABASE=7 Series Chipset Family LPC Controller
@@ -59094,7 +60780,7 @@ pci:v00008086d00001E4A*
  ID_MODEL_FROM_DATABASE=H77 Express Chipset LPC Controller
 
 pci:v00008086d00001E4Asv00001043sd000084CA*
- ID_MODEL_FROM_DATABASE=P8H77-I Motherboard
+ ID_MODEL_FROM_DATABASE=H77 Express Chipset LPC Controller (P8H77-I Motherboard)
 
 pci:v00008086d00001E4B*
  ID_MODEL_FROM_DATABASE=7 Series Chipset Family LPC Controller
@@ -59142,10 +60828,10 @@ pci:v00008086d00001E59*
  ID_MODEL_FROM_DATABASE=HM76 Express Chipset LPC Controller
 
 pci:v00008086d00001E59sv00001043sd00001477*
- ID_MODEL_FROM_DATABASE=N56VZ
+ ID_MODEL_FROM_DATABASE=HM76 Express Chipset LPC Controller (N56VZ)
 
 pci:v00008086d00001E59sv00001043sd00001517*
- ID_MODEL_FROM_DATABASE=Zenbook Prime UX31A
+ ID_MODEL_FROM_DATABASE=HM76 Express Chipset LPC Controller (Zenbook Prime UX31A)
 
 pci:v00008086d00001E5A*
  ID_MODEL_FROM_DATABASE=7 Series Chipset Family LPC Controller
@@ -59345,6 +61031,9 @@ pci:v00008086d0000225C*
 pci:v00008086d0000225D*
  ID_MODEL_FROM_DATABASE=Xeon Phi coprocessor 3120 series
 
+pci:v00008086d0000225E*
+ ID_MODEL_FROM_DATABASE=Xeon Phi coprocessor 31S1
+
 pci:v00008086d00002310*
  ID_MODEL_FROM_DATABASE=DH89xxCC LPC Controller
 
@@ -59475,25 +61164,28 @@ pci:v00008086d00002415*
  ID_MODEL_FROM_DATABASE=82801AA AC'97 Audio Controller
 
 pci:v00008086d00002415sv00001028sd00000095*
- ID_MODEL_FROM_DATABASE=Precision Workstation 220 Integrated Digital Audio
+ ID_MODEL_FROM_DATABASE=82801AA AC'97 Audio Controller (Precision Workstation 220 Integrated Digital Audio)
 
 pci:v00008086d00002415sv00001028sd000000B4*
- ID_MODEL_FROM_DATABASE=OptiPlex GX110
+ ID_MODEL_FROM_DATABASE=82801AA AC'97 Audio Controller (OptiPlex GX110)
 
 pci:v00008086d00002415sv0000110Asd00000051*
- ID_MODEL_FROM_DATABASE=Activy 2xx
+ ID_MODEL_FROM_DATABASE=82801AA AC'97 Audio Controller (Activy 2xx)
 
 pci:v00008086d00002415sv000011D4sd00000040*
- ID_MODEL_FROM_DATABASE=SoundMAX Integrated Digital Audio
+ ID_MODEL_FROM_DATABASE=82801AA AC'97 Audio Controller (SoundMAX Integrated Digital Audio)
 
 pci:v00008086d00002415sv000011D4sd00000048*
- ID_MODEL_FROM_DATABASE=SoundMAX Integrated Digital Audio
+ ID_MODEL_FROM_DATABASE=82801AA AC'97 Audio Controller (SoundMAX Integrated Digital Audio)
 
 pci:v00008086d00002415sv000011D4sd00005340*
- ID_MODEL_FROM_DATABASE=SoundMAX Integrated Digital Audio
+ ID_MODEL_FROM_DATABASE=82801AA AC'97 Audio Controller (SoundMAX Integrated Digital Audio)
 
 pci:v00008086d00002415sv00001734sd00001025*
- ID_MODEL_FROM_DATABASE=Activy 3xx
+ ID_MODEL_FROM_DATABASE=82801AA AC'97 Audio Controller (Activy 3xx)
+
+pci:v00008086d00002415sv00001AF4sd00001100*
+ ID_MODEL_FROM_DATABASE=82801AA AC'97 Audio Controller (QEMU Virtual Machine)
 
 pci:v00008086d00002416*
  ID_MODEL_FROM_DATABASE=82801AA AC'97 Modem Controller
@@ -59517,10 +61209,10 @@ pci:v00008086d00002425*
  ID_MODEL_FROM_DATABASE=82801AB AC'97 Audio Controller
 
 pci:v00008086d00002425sv000011D4sd00000040*
- ID_MODEL_FROM_DATABASE=SoundMAX Integrated Digital Audio
+ ID_MODEL_FROM_DATABASE=82801AB AC'97 Audio Controller (SoundMAX Integrated Digital Audio)
 
 pci:v00008086d00002425sv000011D4sd00000048*
- ID_MODEL_FROM_DATABASE=SoundMAX Integrated Digital Audio
+ ID_MODEL_FROM_DATABASE=82801AB AC'97 Audio Controller (SoundMAX Integrated Digital Audio)
 
 pci:v00008086d00002426*
  ID_MODEL_FROM_DATABASE=82801AB AC'97 Modem Controller
@@ -59532,349 +61224,364 @@ pci:v00008086d00002440*
  ID_MODEL_FROM_DATABASE=82801BA ISA Bridge (LPC)
 
 pci:v00008086d00002440sv00008086sd00005744*
- ID_MODEL_FROM_DATABASE=S845WD1-E
+ ID_MODEL_FROM_DATABASE=82801BA ISA Bridge (LPC) (S845WD1-E)
 
 pci:v00008086d00002442*
  ID_MODEL_FROM_DATABASE=82801BA/BAM USB Controller #1
 
 pci:v00008086d00002442sv00001014sd000001C6*
- ID_MODEL_FROM_DATABASE=Netvista A40/A40p
+ ID_MODEL_FROM_DATABASE=82801BA/BAM USB Controller #1 (Netvista A40/A40p)
 
 pci:v00008086d00002442sv00001025sd00001016*
- ID_MODEL_FROM_DATABASE=Travelmate 612 TX
+ ID_MODEL_FROM_DATABASE=82801BA/BAM USB Controller #1 (Travelmate 612 TX)
 
 pci:v00008086d00002442sv00001028sd000000C7*
- ID_MODEL_FROM_DATABASE=Dimension 8100
+ ID_MODEL_FROM_DATABASE=82801BA/BAM USB Controller #1 (Dimension 8100)
 
 pci:v00008086d00002442sv00001028sd000000D8*
- ID_MODEL_FROM_DATABASE=Precision 530
+ ID_MODEL_FROM_DATABASE=82801BA/BAM USB Controller #1 (Precision 530)
 
 pci:v00008086d00002442sv00001028sd0000010E*
- ID_MODEL_FROM_DATABASE=Optiplex GX240
+ ID_MODEL_FROM_DATABASE=82801BA/BAM USB Controller #1 (Optiplex GX240)
 
 pci:v00008086d00002442sv0000103Csd0000126F*
- ID_MODEL_FROM_DATABASE=e-pc 40
+ ID_MODEL_FROM_DATABASE=82801BA/BAM USB Controller #1 (e-pc 40)
 
 pci:v00008086d00002442sv00001043sd00008027*
- ID_MODEL_FROM_DATABASE=TUSL2-C Mainboard
+ ID_MODEL_FROM_DATABASE=82801BA/BAM USB Controller #1 (TUSL2-C Mainboard)
 
 pci:v00008086d00002442sv0000104Dsd000080DF*
- ID_MODEL_FROM_DATABASE=Vaio PCG-FX403
+ ID_MODEL_FROM_DATABASE=82801BA/BAM USB Controller #1 (Vaio PCG-FX403)
 
 pci:v00008086d00002442sv0000147Bsd00000507*
- ID_MODEL_FROM_DATABASE=TH7II-RAID
+ ID_MODEL_FROM_DATABASE=82801BA/BAM USB Controller #1 (TH7II-RAID)
 
 pci:v00008086d00002442sv00008086sd00004532*
- ID_MODEL_FROM_DATABASE=D815EEA2 mainboard
+ ID_MODEL_FROM_DATABASE=82801BA/BAM USB Controller #1 (D815EEA2 mainboard)
 
 pci:v00008086d00002442sv00008086sd00004557*
- ID_MODEL_FROM_DATABASE=D815EGEW Mainboard
+ ID_MODEL_FROM_DATABASE=82801BA/BAM USB Controller #1 (D815EGEW Mainboard)
 
 pci:v00008086d00002442sv00008086sd00005744*
- ID_MODEL_FROM_DATABASE=S845WD1-E mainboard
+ ID_MODEL_FROM_DATABASE=82801BA/BAM USB Controller #1 (S845WD1-E mainboard)
 
 pci:v00008086d00002443*
  ID_MODEL_FROM_DATABASE=82801BA/BAM SMBus Controller
 
 pci:v00008086d00002443sv00001014sd000001C6*
- ID_MODEL_FROM_DATABASE=Netvista A40/A40p
+ ID_MODEL_FROM_DATABASE=82801BA/BAM SMBus Controller (Netvista A40/A40p)
 
 pci:v00008086d00002443sv00001025sd00001016*
- ID_MODEL_FROM_DATABASE=Travelmate 612 TX
+ ID_MODEL_FROM_DATABASE=82801BA/BAM SMBus Controller (Travelmate 612 TX)
 
 pci:v00008086d00002443sv00001028sd000000C7*
- ID_MODEL_FROM_DATABASE=Dimension 8100
+ ID_MODEL_FROM_DATABASE=82801BA/BAM SMBus Controller (Dimension 8100)
 
 pci:v00008086d00002443sv00001028sd000000D8*
- ID_MODEL_FROM_DATABASE=Precision 530
+ ID_MODEL_FROM_DATABASE=82801BA/BAM SMBus Controller (Precision 530)
 
 pci:v00008086d00002443sv00001028sd0000010E*
- ID_MODEL_FROM_DATABASE=Optiplex GX240
+ ID_MODEL_FROM_DATABASE=82801BA/BAM SMBus Controller (Optiplex GX240)
 
 pci:v00008086d00002443sv0000103Csd0000126F*
- ID_MODEL_FROM_DATABASE=e-pc 40
+ ID_MODEL_FROM_DATABASE=82801BA/BAM SMBus Controller (e-pc 40)
 
 pci:v00008086d00002443sv00001043sd00008027*
- ID_MODEL_FROM_DATABASE=TUSL2-C Mainboard
+ ID_MODEL_FROM_DATABASE=82801BA/BAM SMBus Controller (TUSL2-C Mainboard)
 
 pci:v00008086d00002443sv0000104Dsd000080DF*
- ID_MODEL_FROM_DATABASE=Vaio PCG-FX403
+ ID_MODEL_FROM_DATABASE=82801BA/BAM SMBus Controller (Vaio PCG-FX403)
 
 pci:v00008086d00002443sv0000147Bsd00000507*
- ID_MODEL_FROM_DATABASE=TH7II-RAID
+ ID_MODEL_FROM_DATABASE=82801BA/BAM SMBus Controller (TH7II-RAID)
 
 pci:v00008086d00002443sv000015D9sd00003280*
- ID_MODEL_FROM_DATABASE=Supermicro P4SBE Mainboard
+ ID_MODEL_FROM_DATABASE=82801BA/BAM SMBus Controller (Supermicro P4SBE Mainboard)
 
 pci:v00008086d00002443sv00008086sd00004532*
- ID_MODEL_FROM_DATABASE=D815EEA2 mainboard
+ ID_MODEL_FROM_DATABASE=82801BA/BAM SMBus Controller (D815EEA2 mainboard)
 
 pci:v00008086d00002443sv00008086sd00004557*
- ID_MODEL_FROM_DATABASE=D815EGEW Mainboard
+ ID_MODEL_FROM_DATABASE=82801BA/BAM SMBus Controller (D815EGEW Mainboard)
 
 pci:v00008086d00002443sv00008086sd00005744*
- ID_MODEL_FROM_DATABASE=S845WD1-E mainboard
+ ID_MODEL_FROM_DATABASE=82801BA/BAM SMBus Controller (S845WD1-E mainboard)
 
 pci:v00008086d00002444*
  ID_MODEL_FROM_DATABASE=82801BA/BAM USB Controller #1
 
 pci:v00008086d00002444sv00001025sd00001016*
- ID_MODEL_FROM_DATABASE=Travelmate 612 TX
+ ID_MODEL_FROM_DATABASE=82801BA/BAM USB Controller #1 (Travelmate 612 TX)
 
 pci:v00008086d00002444sv00001028sd000000C7*
- ID_MODEL_FROM_DATABASE=Dimension 8100
+ ID_MODEL_FROM_DATABASE=82801BA/BAM USB Controller #1 (Dimension 8100)
 
 pci:v00008086d00002444sv00001028sd000000D8*
- ID_MODEL_FROM_DATABASE=Precision 530
+ ID_MODEL_FROM_DATABASE=82801BA/BAM USB Controller #1 (Precision 530)
 
 pci:v00008086d00002444sv00001028sd0000010E*
- ID_MODEL_FROM_DATABASE=Optiplex GX240
+ ID_MODEL_FROM_DATABASE=82801BA/BAM USB Controller #1 (Optiplex GX240)
 
 pci:v00008086d00002444sv0000103Csd0000126F*
- ID_MODEL_FROM_DATABASE=e-pc 40
+ ID_MODEL_FROM_DATABASE=82801BA/BAM USB Controller #1 (e-pc 40)
 
 pci:v00008086d00002444sv00001043sd00008027*
- ID_MODEL_FROM_DATABASE=TUSL2-C Mainboard
+ ID_MODEL_FROM_DATABASE=82801BA/BAM USB Controller #1 (TUSL2-C Mainboard)
 
 pci:v00008086d00002444sv0000104Dsd000080DF*
- ID_MODEL_FROM_DATABASE=Vaio PCG-FX403
+ ID_MODEL_FROM_DATABASE=82801BA/BAM USB Controller #1 (Vaio PCG-FX403)
 
 pci:v00008086d00002444sv0000147Bsd00000507*
- ID_MODEL_FROM_DATABASE=TH7II-RAID
+ ID_MODEL_FROM_DATABASE=82801BA/BAM USB Controller #1 (TH7II-RAID)
 
 pci:v00008086d00002444sv00008086sd00004532*
- ID_MODEL_FROM_DATABASE=D815EEA2 mainboard
+ ID_MODEL_FROM_DATABASE=82801BA/BAM USB Controller #1 (D815EEA2 mainboard)
 
 pci:v00008086d00002444sv00008086sd00005744*
- ID_MODEL_FROM_DATABASE=S845WD1-E mainboard
+ ID_MODEL_FROM_DATABASE=82801BA/BAM USB Controller #1 (S845WD1-E mainboard)
 
 pci:v00008086d00002445*
  ID_MODEL_FROM_DATABASE=82801BA/BAM AC'97 Audio Controller
 
 pci:v00008086d00002445sv00000E11sd0000000B*
- ID_MODEL_FROM_DATABASE=Compaq Deskpro EN Audio
+ ID_MODEL_FROM_DATABASE=82801BA/BAM AC'97 Audio Controller (Compaq Deskpro EN Audio)
 
 pci:v00008086d00002445sv00000E11sd00000088*
- ID_MODEL_FROM_DATABASE=Evo D500
+ ID_MODEL_FROM_DATABASE=82801BA/BAM AC'97 Audio Controller (Evo D500)
 
 pci:v00008086d00002445sv00001014sd000001C6*
- ID_MODEL_FROM_DATABASE=Netvista A40/A40p
+ ID_MODEL_FROM_DATABASE=82801BA/BAM AC'97 Audio Controller (Netvista A40/A40p)
 
 pci:v00008086d00002445sv00001025sd00001016*
- ID_MODEL_FROM_DATABASE=Travelmate 612 TX
+ ID_MODEL_FROM_DATABASE=82801BA/BAM AC'97 Audio Controller (Travelmate 612 TX)
 
 pci:v00008086d00002445sv00001028sd000000D8*
- ID_MODEL_FROM_DATABASE=Precision 530
+ ID_MODEL_FROM_DATABASE=82801BA/BAM AC'97 Audio Controller (Precision 530)
 
 pci:v00008086d00002445sv0000103Csd0000126F*
- ID_MODEL_FROM_DATABASE=e-pc 40
+ ID_MODEL_FROM_DATABASE=82801BA/BAM AC'97 Audio Controller (e-pc 40)
 
 pci:v00008086d00002445sv0000104Dsd000080DF*
- ID_MODEL_FROM_DATABASE=Vaio PCG-FX403
+ ID_MODEL_FROM_DATABASE=82801BA/BAM AC'97 Audio Controller (Vaio PCG-FX403)
 
 pci:v00008086d00002445sv00001462sd00003370*
- ID_MODEL_FROM_DATABASE=STAC9721 AC
+ ID_MODEL_FROM_DATABASE=82801BA/BAM AC'97 Audio Controller (STAC9721 AC)
 
 pci:v00008086d00002445sv0000147Bsd00000507*
- ID_MODEL_FROM_DATABASE=TH7II-RAID
+ ID_MODEL_FROM_DATABASE=82801BA/BAM AC'97 Audio Controller (TH7II-RAID)
 
 pci:v00008086d00002445sv00008086sd00004557*
- ID_MODEL_FROM_DATABASE=D815EGEW Mainboard
+ ID_MODEL_FROM_DATABASE=82801BA/BAM AC'97 Audio Controller (D815EGEW Mainboard)
 
 pci:v00008086d00002446*
  ID_MODEL_FROM_DATABASE=82801BA/BAM AC'97 Modem Controller
 
 pci:v00008086d00002446sv00001025sd00001016*
- ID_MODEL_FROM_DATABASE=Travelmate 612 TX
+ ID_MODEL_FROM_DATABASE=82801BA/BAM AC'97 Modem Controller (Travelmate 612 TX)
 
 pci:v00008086d00002446sv0000104Dsd000080DF*
- ID_MODEL_FROM_DATABASE=Vaio PCG-FX403
+ ID_MODEL_FROM_DATABASE=82801BA/BAM AC'97 Modem Controller (Vaio PCG-FX403)
 
 pci:v00008086d00002448*
  ID_MODEL_FROM_DATABASE=82801 Mobile PCI Bridge
 
 pci:v00008086d00002448sv00001028sd0000040B*
- ID_MODEL_FROM_DATABASE=Latitude E6510
+ ID_MODEL_FROM_DATABASE=82801 Mobile PCI Bridge (Latitude E6510)
 
 pci:v00008086d00002448sv0000103Csd00000934*
- ID_MODEL_FROM_DATABASE=HP Compaq nw8240 Mobile Workstation
+ ID_MODEL_FROM_DATABASE=82801 Mobile PCI Bridge (HP Compaq nw8240 Mobile Workstation)
 
 pci:v00008086d00002448sv0000103Csd0000099C*
- ID_MODEL_FROM_DATABASE=NX6110/NC6120
+ ID_MODEL_FROM_DATABASE=82801 Mobile PCI Bridge (NX6110/NC6120)
 
 pci:v00008086d00002448sv0000103Csd0000309F*
- ID_MODEL_FROM_DATABASE=Compaq nx9420 Notebook
+ ID_MODEL_FROM_DATABASE=82801 Mobile PCI Bridge (Compaq nx9420 Notebook)
 
 pci:v00008086d00002448sv0000103Csd000030A3*
- ID_MODEL_FROM_DATABASE=Compaq nw8440
+ ID_MODEL_FROM_DATABASE=82801 Mobile PCI Bridge (Compaq nw8440)
 
 pci:v00008086d00002448sv0000103Csd000030C1*
- ID_MODEL_FROM_DATABASE=Compaq 6910p
+ ID_MODEL_FROM_DATABASE=82801 Mobile PCI Bridge (Compaq 6910p)
 
 pci:v00008086d00002448sv0000104Dsd0000902D*
- ID_MODEL_FROM_DATABASE=VAIO VGN-NR120E
+ ID_MODEL_FROM_DATABASE=82801 Mobile PCI Bridge (VAIO VGN-NR120E)
 
 pci:v00008086d00002448sv0000105Bsd00000D7C*
- ID_MODEL_FROM_DATABASE=D270S/D250S Motherboard
+ ID_MODEL_FROM_DATABASE=82801 Mobile PCI Bridge (D270S/D250S Motherboard)
+
+pci:v00008086d00002448sv00001071sd00008209*
+ ID_MODEL_FROM_DATABASE=82801 Mobile PCI Bridge (Medion MIM 2240 Notebook PC [MD98100])
 
 pci:v00008086d00002448sv0000144Dsd0000C00C*
- ID_MODEL_FROM_DATABASE=P30 notebook
+ ID_MODEL_FROM_DATABASE=82801 Mobile PCI Bridge (P30 notebook)
+
+pci:v00008086d00002448sv0000144Dsd0000C06A*
+ ID_MODEL_FROM_DATABASE=82801 Mobile PCI Bridge (R730 Laptop)
 
 pci:v00008086d00002448sv0000144Dsd0000C072*
- ID_MODEL_FROM_DATABASE=Notebook N150P
+ ID_MODEL_FROM_DATABASE=82801 Mobile PCI Bridge (Notebook N150P)
 
 pci:v00008086d00002448sv00001458sd00005000*
- ID_MODEL_FROM_DATABASE=GA-D525TUD
+ ID_MODEL_FROM_DATABASE=82801 Mobile PCI Bridge (GA-D525TUD)
 
 pci:v00008086d00002448sv00001734sd00001055*
- ID_MODEL_FROM_DATABASE=Amilo M1420
+ ID_MODEL_FROM_DATABASE=82801 Mobile PCI Bridge (Amilo M1420)
 
 pci:v00008086d00002448sv000017AAsd000020AE*
- ID_MODEL_FROM_DATABASE=ThinkPad T61/R61
+ ID_MODEL_FROM_DATABASE=82801 Mobile PCI Bridge (ThinkPad T61/R61)
+
+pci:v00008086d00002448sv000017C0sd000010D2*
+ ID_MODEL_FROM_DATABASE=82801 Mobile PCI Bridge (Medion Akoya E7214 Notebook PC [MD98410])
+
+pci:v00008086d00002448sv000017C0sd00004083*
+ ID_MODEL_FROM_DATABASE=82801 Mobile PCI Bridge (Medion WIM 2210 Notebook PC [MD96850])
 
 pci:v00008086d00002448sv00008086sd0000544B*
- ID_MODEL_FROM_DATABASE=Desktop Board D425KT
+ ID_MODEL_FROM_DATABASE=82801 Mobile PCI Bridge (Desktop Board D425KT)
 
 pci:v00008086d00002448sv0000E4BFsd0000CC47*
- ID_MODEL_FROM_DATABASE=CCG-RUMBA
+ ID_MODEL_FROM_DATABASE=82801 Mobile PCI Bridge (CCG-RUMBA)
 
 pci:v00008086d00002449*
  ID_MODEL_FROM_DATABASE=82801BA/BAM/CA/CAM Ethernet Controller
 
 pci:v00008086d00002449sv00000E11sd00000012*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 VM
+ ID_MODEL_FROM_DATABASE=82801BA/BAM/CA/CAM Ethernet Controller (EtherExpress PRO/100 VM)
 
 pci:v00008086d00002449sv00000E11sd00000091*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 VE
+ ID_MODEL_FROM_DATABASE=82801BA/BAM/CA/CAM Ethernet Controller (EtherExpress PRO/100 VE)
 
 pci:v00008086d00002449sv00001014sd000001CE*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 VE
+ ID_MODEL_FROM_DATABASE=82801BA/BAM/CA/CAM Ethernet Controller (EtherExpress PRO/100 VE)
 
 pci:v00008086d00002449sv00001014sd000001DC*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 VE
+ ID_MODEL_FROM_DATABASE=82801BA/BAM/CA/CAM Ethernet Controller (EtherExpress PRO/100 VE)
 
 pci:v00008086d00002449sv00001014sd000001EB*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 VE
+ ID_MODEL_FROM_DATABASE=82801BA/BAM/CA/CAM Ethernet Controller (EtherExpress PRO/100 VE)
 
 pci:v00008086d00002449sv00001014sd000001EC*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 VE
+ ID_MODEL_FROM_DATABASE=82801BA/BAM/CA/CAM Ethernet Controller (EtherExpress PRO/100 VE)
 
 pci:v00008086d00002449sv00001014sd00000202*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 VE
+ ID_MODEL_FROM_DATABASE=82801BA/BAM/CA/CAM Ethernet Controller (EtherExpress PRO/100 VE)
 
 pci:v00008086d00002449sv00001014sd00000205*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 VE
+ ID_MODEL_FROM_DATABASE=82801BA/BAM/CA/CAM Ethernet Controller (EtherExpress PRO/100 VE)
 
 pci:v00008086d00002449sv00001014sd00000217*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 VE
+ ID_MODEL_FROM_DATABASE=82801BA/BAM/CA/CAM Ethernet Controller (EtherExpress PRO/100 VE)
 
 pci:v00008086d00002449sv00001014sd00000234*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 VE
+ ID_MODEL_FROM_DATABASE=82801BA/BAM/CA/CAM Ethernet Controller (EtherExpress PRO/100 VE)
 
 pci:v00008086d00002449sv00001014sd0000023D*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 VE
+ ID_MODEL_FROM_DATABASE=82801BA/BAM/CA/CAM Ethernet Controller (EtherExpress PRO/100 VE)
 
 pci:v00008086d00002449sv00001014sd00000244*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 VE
+ ID_MODEL_FROM_DATABASE=82801BA/BAM/CA/CAM Ethernet Controller (EtherExpress PRO/100 VE)
 
 pci:v00008086d00002449sv00001014sd00000245*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 VE
+ ID_MODEL_FROM_DATABASE=82801BA/BAM/CA/CAM Ethernet Controller (EtherExpress PRO/100 VE)
 
 pci:v00008086d00002449sv00001014sd00000265*
- ID_MODEL_FROM_DATABASE=PRO/100 VE Desktop Connection
+ ID_MODEL_FROM_DATABASE=82801BA/BAM/CA/CAM Ethernet Controller (PRO/100 VE Desktop Connection)
 
 pci:v00008086d00002449sv00001014sd00000267*
- ID_MODEL_FROM_DATABASE=PRO/100 VE Desktop Connection
+ ID_MODEL_FROM_DATABASE=82801BA/BAM/CA/CAM Ethernet Controller (PRO/100 VE Desktop Connection)
 
 pci:v00008086d00002449sv00001014sd0000026A*
- ID_MODEL_FROM_DATABASE=PRO/100 VE Desktop Connection
+ ID_MODEL_FROM_DATABASE=82801BA/BAM/CA/CAM Ethernet Controller (PRO/100 VE Desktop Connection)
 
 pci:v00008086d00002449sv0000109Fsd0000315D*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 VE
+ ID_MODEL_FROM_DATABASE=82801BA/BAM/CA/CAM Ethernet Controller (EtherExpress PRO/100 VE)
 
 pci:v00008086d00002449sv0000109Fsd00003181*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 VE
+ ID_MODEL_FROM_DATABASE=82801BA/BAM/CA/CAM Ethernet Controller (EtherExpress PRO/100 VE)
 
 pci:v00008086d00002449sv00001179sd0000FF01*
- ID_MODEL_FROM_DATABASE=PRO/100 VE Network Connection
+ ID_MODEL_FROM_DATABASE=82801BA/BAM/CA/CAM Ethernet Controller (PRO/100 VE Network Connection)
 
 pci:v00008086d00002449sv00001186sd00007801*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 VE
+ ID_MODEL_FROM_DATABASE=82801BA/BAM/CA/CAM Ethernet Controller (EtherExpress PRO/100 VE)
 
 pci:v00008086d00002449sv0000144Dsd00002602*
- ID_MODEL_FROM_DATABASE=HomePNA 1M CNR
+ ID_MODEL_FROM_DATABASE=82801BA/BAM/CA/CAM Ethernet Controller (HomePNA 1M CNR)
+
+pci:v00008086d00002449sv00001AF4sd00001100*
+ ID_MODEL_FROM_DATABASE=82801BA/BAM/CA/CAM Ethernet Controller (QEMU Virtual Machine)
 
 pci:v00008086d00002449sv00008086sd00003010*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 VE
+ ID_MODEL_FROM_DATABASE=82801BA/BAM/CA/CAM Ethernet Controller (EtherExpress PRO/100 VE)
 
 pci:v00008086d00002449sv00008086sd00003011*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 VM
+ ID_MODEL_FROM_DATABASE=82801BA/BAM/CA/CAM Ethernet Controller (EtherExpress PRO/100 VM)
 
 pci:v00008086d00002449sv00008086sd00003012*
- ID_MODEL_FROM_DATABASE=82562EH based Phoneline
+ ID_MODEL_FROM_DATABASE=82801BA/BAM/CA/CAM Ethernet Controller (82562EH based Phoneline)
 
 pci:v00008086d00002449sv00008086sd00003013*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 VE
+ ID_MODEL_FROM_DATABASE=82801BA/BAM/CA/CAM Ethernet Controller (EtherExpress PRO/100 VE)
 
 pci:v00008086d00002449sv00008086sd00003014*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 VM
+ ID_MODEL_FROM_DATABASE=82801BA/BAM/CA/CAM Ethernet Controller (EtherExpress PRO/100 VM)
 
 pci:v00008086d00002449sv00008086sd00003015*
- ID_MODEL_FROM_DATABASE=82562EH based Phoneline
+ ID_MODEL_FROM_DATABASE=82801BA/BAM/CA/CAM Ethernet Controller (82562EH based Phoneline)
 
 pci:v00008086d00002449sv00008086sd00003016*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 P Mobile Combo
+ ID_MODEL_FROM_DATABASE=82801BA/BAM/CA/CAM Ethernet Controller (EtherExpress PRO/100 P Mobile Combo)
 
 pci:v00008086d00002449sv00008086sd00003017*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 P Mobile
+ ID_MODEL_FROM_DATABASE=82801BA/BAM/CA/CAM Ethernet Controller (EtherExpress PRO/100 P Mobile)
 
 pci:v00008086d00002449sv00008086sd00003018*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100
+ ID_MODEL_FROM_DATABASE=82801BA/BAM/CA/CAM Ethernet Controller (EtherExpress PRO/100)
 
 pci:v00008086d0000244A*
  ID_MODEL_FROM_DATABASE=82801BAM IDE U100 Controller
 
 pci:v00008086d0000244Asv00001025sd00001016*
- ID_MODEL_FROM_DATABASE=Travelmate 612TX
+ ID_MODEL_FROM_DATABASE=82801BAM IDE U100 Controller (Travelmate 612TX)
 
 pci:v00008086d0000244Asv0000104Dsd000080DF*
- ID_MODEL_FROM_DATABASE=Vaio PCG-FX403
+ ID_MODEL_FROM_DATABASE=82801BAM IDE U100 Controller (Vaio PCG-FX403)
 
 pci:v00008086d0000244B*
  ID_MODEL_FROM_DATABASE=82801BA IDE U100 Controller
 
 pci:v00008086d0000244Bsv00001014sd000001C6*
- ID_MODEL_FROM_DATABASE=Netvista A40/A40p
+ ID_MODEL_FROM_DATABASE=82801BA IDE U100 Controller (Netvista A40/A40p)
 
 pci:v00008086d0000244Bsv00001028sd000000C7*
- ID_MODEL_FROM_DATABASE=Dimension 8100
+ ID_MODEL_FROM_DATABASE=82801BA IDE U100 Controller (Dimension 8100)
 
 pci:v00008086d0000244Bsv00001028sd000000D8*
- ID_MODEL_FROM_DATABASE=Precision 530
+ ID_MODEL_FROM_DATABASE=82801BA IDE U100 Controller (Precision 530)
 
 pci:v00008086d0000244Bsv00001028sd0000010E*
- ID_MODEL_FROM_DATABASE=Optiplex GX240
+ ID_MODEL_FROM_DATABASE=82801BA IDE U100 Controller (Optiplex GX240)
 
 pci:v00008086d0000244Bsv0000103Csd0000126F*
- ID_MODEL_FROM_DATABASE=e-pc 40
+ ID_MODEL_FROM_DATABASE=82801BA IDE U100 Controller (e-pc 40)
 
 pci:v00008086d0000244Bsv00001043sd00008027*
- ID_MODEL_FROM_DATABASE=TUSL2-C Mainboard
+ ID_MODEL_FROM_DATABASE=82801BA IDE U100 Controller (TUSL2-C Mainboard)
 
 pci:v00008086d0000244Bsv0000147Bsd00000507*
- ID_MODEL_FROM_DATABASE=TH7II-RAID
+ ID_MODEL_FROM_DATABASE=82801BA IDE U100 Controller (TH7II-RAID)
 
 pci:v00008086d0000244Bsv000015D9sd00003280*
- ID_MODEL_FROM_DATABASE=Supermicro P4SBE Mainboard
+ ID_MODEL_FROM_DATABASE=82801BA IDE U100 Controller (Supermicro P4SBE Mainboard)
 
 pci:v00008086d0000244Bsv00008086sd00004532*
- ID_MODEL_FROM_DATABASE=D815EEA2 mainboard
+ ID_MODEL_FROM_DATABASE=82801BA IDE U100 Controller (D815EEA2 mainboard)
 
 pci:v00008086d0000244Bsv00008086sd00004557*
- ID_MODEL_FROM_DATABASE=D815EGEW Mainboard
+ ID_MODEL_FROM_DATABASE=82801BA IDE U100 Controller (D815EGEW Mainboard)
 
 pci:v00008086d0000244Bsv00008086sd00005744*
- ID_MODEL_FROM_DATABASE=S845WD1-E mainboard
+ ID_MODEL_FROM_DATABASE=82801BA IDE U100 Controller (S845WD1-E mainboard)
 
 pci:v00008086d0000244C*
  ID_MODEL_FROM_DATABASE=82801BAM ISA Bridge (LPC)
@@ -59883,37 +61590,52 @@ pci:v00008086d0000244E*
  ID_MODEL_FROM_DATABASE=82801 PCI Bridge
 
 pci:v00008086d0000244Esv00001014sd00000267*
- ID_MODEL_FROM_DATABASE=NetVista A30p
+ ID_MODEL_FROM_DATABASE=82801 PCI Bridge (NetVista A30p)
 
 pci:v00008086d0000244Esv00001028sd0000020D*
- ID_MODEL_FROM_DATABASE=Inspiron 530
+ ID_MODEL_FROM_DATABASE=82801 PCI Bridge (Inspiron 530)
 
 pci:v00008086d0000244Esv00001028sd00000211*
- ID_MODEL_FROM_DATABASE=Optiplex 755
+ ID_MODEL_FROM_DATABASE=82801 PCI Bridge (Optiplex 755)
 
 pci:v00008086d0000244Esv00001028sd000002DA*
- ID_MODEL_FROM_DATABASE=OptiPlex 980
+ ID_MODEL_FROM_DATABASE=82801 PCI Bridge (OptiPlex 980)
 
 pci:v00008086d0000244Esv0000103Csd00002A3B*
- ID_MODEL_FROM_DATABASE=Pavilion A1512X
+ ID_MODEL_FROM_DATABASE=82801 PCI Bridge (Pavilion A1512X)
+
+pci:v00008086d0000244Esv0000103Csd00002A6F*
+ ID_MODEL_FROM_DATABASE=82801 PCI Bridge (Asus IPIBL-LB Motherboard)
 
 pci:v00008086d0000244Esv0000103Csd000031FE*
- ID_MODEL_FROM_DATABASE=ProLiant DL140 G3
+ ID_MODEL_FROM_DATABASE=82801 PCI Bridge (ProLiant DL140 G3)
 
 pci:v00008086d0000244Esv0000103Csd0000330B*
- ID_MODEL_FROM_DATABASE=ProLiant ML150 G6 Server
+ ID_MODEL_FROM_DATABASE=82801 PCI Bridge (ProLiant ML150 G6 Server)
 
 pci:v00008086d0000244Esv00001043sd00008277*
- ID_MODEL_FROM_DATABASE=P5K PRO Motherboard
+ ID_MODEL_FROM_DATABASE=82801 PCI Bridge (P5K PRO Motherboard)
+
+pci:v00008086d0000244Esv00001043sd0000844D*
+ ID_MODEL_FROM_DATABASE=82801 PCI Bridge (P8 series motherboard)
 
 pci:v00008086d0000244Esv00001458sd00005000*
- ID_MODEL_FROM_DATABASE=Motherboard
+ ID_MODEL_FROM_DATABASE=82801 PCI Bridge (Motherboard)
+
+pci:v00008086d0000244Esv00001462sd00007418*
+ ID_MODEL_FROM_DATABASE=82801 PCI Bridge (Wind PC MS-7418)
+
+pci:v00008086d0000244Esv000015D9sd0000060D*
+ ID_MODEL_FROM_DATABASE=82801 PCI Bridge (C7SIM-Q Motherboard)
 
 pci:v00008086d0000244Esv000015D9sd00009680*
- ID_MODEL_FROM_DATABASE=X7DBN Motherboard
+ ID_MODEL_FROM_DATABASE=82801 PCI Bridge (X7DBN Motherboard)
 
 pci:v00008086d0000244Esv00001775sd000011CC*
- ID_MODEL_FROM_DATABASE=CC11/CL11
+ ID_MODEL_FROM_DATABASE=82801 PCI Bridge (CC11/CL11)
+
+pci:v00008086d0000244Esv00008086sd00007270*
+ ID_MODEL_FROM_DATABASE=82801 PCI Bridge (Server Board S1200BTS)
 
 pci:v00008086d00002450*
  ID_MODEL_FROM_DATABASE=82801E ISA Bridge (LPC)
@@ -59943,160 +61665,160 @@ pci:v00008086d00002482*
  ID_MODEL_FROM_DATABASE=82801CA/CAM USB Controller #1
 
 pci:v00008086d00002482sv00000E11sd00000030*
- ID_MODEL_FROM_DATABASE=Evo N600c
+ ID_MODEL_FROM_DATABASE=82801CA/CAM USB Controller #1 (Evo N600c)
 
 pci:v00008086d00002482sv00001014sd00000220*
- ID_MODEL_FROM_DATABASE=ThinkPad A/T/X Series
+ ID_MODEL_FROM_DATABASE=82801CA/CAM USB Controller #1 (ThinkPad A/T/X Series)
 
 pci:v00008086d00002482sv0000104Dsd000080E7*
- ID_MODEL_FROM_DATABASE=VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
+ ID_MODEL_FROM_DATABASE=82801CA/CAM USB Controller #1 (VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP)
 
 pci:v00008086d00002482sv000015D9sd00003480*
- ID_MODEL_FROM_DATABASE=P4DP6
+ ID_MODEL_FROM_DATABASE=82801CA/CAM USB Controller #1 (P4DP6)
 
 pci:v00008086d00002482sv00008086sd00001958*
- ID_MODEL_FROM_DATABASE=vpr Matrix 170B4
+ ID_MODEL_FROM_DATABASE=82801CA/CAM USB Controller #1 (vpr Matrix 170B4)
 
 pci:v00008086d00002482sv00008086sd00003424*
- ID_MODEL_FROM_DATABASE=SE7501HG2 Mainboard
+ ID_MODEL_FROM_DATABASE=82801CA/CAM USB Controller #1 (SE7501HG2 Mainboard)
 
 pci:v00008086d00002482sv00008086sd00004541*
- ID_MODEL_FROM_DATABASE=Latitude C640
+ ID_MODEL_FROM_DATABASE=82801CA/CAM USB Controller #1 (Latitude C640)
 
 pci:v00008086d00002483*
  ID_MODEL_FROM_DATABASE=82801CA/CAM SMBus Controller
 
 pci:v00008086d00002483sv00001014sd00000220*
- ID_MODEL_FROM_DATABASE=ThinkPad A/T/X Series
+ ID_MODEL_FROM_DATABASE=82801CA/CAM SMBus Controller (ThinkPad A/T/X Series)
 
 pci:v00008086d00002483sv0000104Dsd000080E7*
- ID_MODEL_FROM_DATABASE=VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
+ ID_MODEL_FROM_DATABASE=82801CA/CAM SMBus Controller (VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP)
 
 pci:v00008086d00002483sv000015D9sd00003480*
- ID_MODEL_FROM_DATABASE=P4DP6
+ ID_MODEL_FROM_DATABASE=82801CA/CAM SMBus Controller (P4DP6)
 
 pci:v00008086d00002483sv00008086sd00001958*
- ID_MODEL_FROM_DATABASE=vpr Matrix 170B4
+ ID_MODEL_FROM_DATABASE=82801CA/CAM SMBus Controller (vpr Matrix 170B4)
 
 pci:v00008086d00002484*
  ID_MODEL_FROM_DATABASE=82801CA/CAM USB Controller #2
 
 pci:v00008086d00002484sv00000E11sd00000030*
- ID_MODEL_FROM_DATABASE=Evo N600c
+ ID_MODEL_FROM_DATABASE=82801CA/CAM USB Controller #2 (Evo N600c)
 
 pci:v00008086d00002484sv00001014sd00000220*
- ID_MODEL_FROM_DATABASE=ThinkPad A/T/X Series
+ ID_MODEL_FROM_DATABASE=82801CA/CAM USB Controller #2 (ThinkPad A/T/X Series)
 
 pci:v00008086d00002484sv0000104Dsd000080E7*
- ID_MODEL_FROM_DATABASE=VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
+ ID_MODEL_FROM_DATABASE=82801CA/CAM USB Controller #2 (VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP)
 
 pci:v00008086d00002484sv000015D9sd00003480*
- ID_MODEL_FROM_DATABASE=P4DP6
+ ID_MODEL_FROM_DATABASE=82801CA/CAM USB Controller #2 (P4DP6)
 
 pci:v00008086d00002484sv00008086sd00001958*
- ID_MODEL_FROM_DATABASE=vpr Matrix 170B4
+ ID_MODEL_FROM_DATABASE=82801CA/CAM USB Controller #2 (vpr Matrix 170B4)
 
 pci:v00008086d00002485*
  ID_MODEL_FROM_DATABASE=82801CA/CAM AC'97 Audio Controller
 
 pci:v00008086d00002485sv00001013sd00005959*
- ID_MODEL_FROM_DATABASE=Crystal WMD Audio Codec
+ ID_MODEL_FROM_DATABASE=82801CA/CAM AC'97 Audio Controller (Crystal WMD Audio Codec)
 
 pci:v00008086d00002485sv00001014sd00000222*
- ID_MODEL_FROM_DATABASE=ThinkPad A30/A30p/T23
+ ID_MODEL_FROM_DATABASE=82801CA/CAM AC'97 Audio Controller (ThinkPad A30/A30p/T23)
 
 pci:v00008086d00002485sv00001014sd00000508*
- ID_MODEL_FROM_DATABASE=ThinkPad T30
+ ID_MODEL_FROM_DATABASE=82801CA/CAM AC'97 Audio Controller (ThinkPad T30)
 
 pci:v00008086d00002485sv00001014sd0000051C*
- ID_MODEL_FROM_DATABASE=ThinkPad A/T/X Series
+ ID_MODEL_FROM_DATABASE=82801CA/CAM AC'97 Audio Controller (ThinkPad A/T/X Series)
 
 pci:v00008086d00002485sv00001043sd00001583*
- ID_MODEL_FROM_DATABASE=L3C (SPDIF)
+ ID_MODEL_FROM_DATABASE=82801CA/CAM AC'97 Audio Controller (L3C (SPDIF))
 
 pci:v00008086d00002485sv00001043sd00001623*
- ID_MODEL_FROM_DATABASE=L2B (no SPDIF)
+ ID_MODEL_FROM_DATABASE=82801CA/CAM AC'97 Audio Controller (L2B (no SPDIF))
 
 pci:v00008086d00002485sv00001043sd00001643*
- ID_MODEL_FROM_DATABASE=L3F
+ ID_MODEL_FROM_DATABASE=82801CA/CAM AC'97 Audio Controller (L3F)
 
 pci:v00008086d00002485sv0000104Dsd000080E7*
- ID_MODEL_FROM_DATABASE=VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
+ ID_MODEL_FROM_DATABASE=82801CA/CAM AC'97 Audio Controller (VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP)
 
 pci:v00008086d00002485sv0000144Dsd0000C006*
- ID_MODEL_FROM_DATABASE=vpr Matrix 170B4
+ ID_MODEL_FROM_DATABASE=82801CA/CAM AC'97 Audio Controller (vpr Matrix 170B4)
 
 pci:v00008086d00002486*
  ID_MODEL_FROM_DATABASE=82801CA/CAM AC'97 Modem Controller
 
 pci:v00008086d00002486sv00001014sd00000223*
- ID_MODEL_FROM_DATABASE=ThinkPad A/T/X Series
+ ID_MODEL_FROM_DATABASE=82801CA/CAM AC'97 Modem Controller (ThinkPad A/T/X Series)
 
 pci:v00008086d00002486sv00001014sd00000503*
- ID_MODEL_FROM_DATABASE=ThinkPad R31
+ ID_MODEL_FROM_DATABASE=82801CA/CAM AC'97 Modem Controller (ThinkPad R31)
 
 pci:v00008086d00002486sv00001014sd0000051A*
- ID_MODEL_FROM_DATABASE=ThinkPad A/T/X Series
+ ID_MODEL_FROM_DATABASE=82801CA/CAM AC'97 Modem Controller (ThinkPad A/T/X Series)
 
 pci:v00008086d00002486sv0000101Fsd00001025*
- ID_MODEL_FROM_DATABASE=620 Series
+ ID_MODEL_FROM_DATABASE=82801CA/CAM AC'97 Modem Controller (620 Series)
 
 pci:v00008086d00002486sv00001043sd00001496*
- ID_MODEL_FROM_DATABASE=PCtel HSP56 MR
+ ID_MODEL_FROM_DATABASE=82801CA/CAM AC'97 Modem Controller (PCtel HSP56 MR)
 
 pci:v00008086d00002486sv0000104Dsd000080E7*
- ID_MODEL_FROM_DATABASE=VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
+ ID_MODEL_FROM_DATABASE=82801CA/CAM AC'97 Modem Controller (VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP)
 
 pci:v00008086d00002486sv0000134Dsd00004C21*
- ID_MODEL_FROM_DATABASE=Dell Inspiron 2100 internal modem
+ ID_MODEL_FROM_DATABASE=82801CA/CAM AC'97 Modem Controller (Dell Inspiron 2100 internal modem)
 
 pci:v00008086d00002486sv0000144Dsd00002115*
- ID_MODEL_FROM_DATABASE=vpr Matrix 170B4 internal modem
+ ID_MODEL_FROM_DATABASE=82801CA/CAM AC'97 Modem Controller (vpr Matrix 170B4 internal modem)
 
 pci:v00008086d00002486sv000014F1sd00005421*
- ID_MODEL_FROM_DATABASE=MD56ORD V.92 MDC Modem
+ ID_MODEL_FROM_DATABASE=82801CA/CAM AC'97 Modem Controller (MD56ORD V.92 MDC Modem)
 
 pci:v00008086d00002487*
  ID_MODEL_FROM_DATABASE=82801CA/CAM USB Controller #3
 
 pci:v00008086d00002487sv00000E11sd00000030*
- ID_MODEL_FROM_DATABASE=Evo N600c
+ ID_MODEL_FROM_DATABASE=82801CA/CAM USB Controller #3 (Evo N600c)
 
 pci:v00008086d00002487sv00001014sd00000220*
- ID_MODEL_FROM_DATABASE=ThinkPad A/T/X Series
+ ID_MODEL_FROM_DATABASE=82801CA/CAM USB Controller #3 (ThinkPad A/T/X Series)
 
 pci:v00008086d00002487sv0000104Dsd000080E7*
- ID_MODEL_FROM_DATABASE=VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
+ ID_MODEL_FROM_DATABASE=82801CA/CAM USB Controller #3 (VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP)
 
 pci:v00008086d00002487sv000015D9sd00003480*
- ID_MODEL_FROM_DATABASE=P4DP6
+ ID_MODEL_FROM_DATABASE=82801CA/CAM USB Controller #3 (P4DP6)
 
 pci:v00008086d00002487sv00008086sd00001958*
- ID_MODEL_FROM_DATABASE=vpr Matrix 170B4
+ ID_MODEL_FROM_DATABASE=82801CA/CAM USB Controller #3 (vpr Matrix 170B4)
 
 pci:v00008086d0000248A*
  ID_MODEL_FROM_DATABASE=82801CAM IDE U100 Controller
 
 pci:v00008086d0000248Asv00000E11sd00000030*
- ID_MODEL_FROM_DATABASE=Evo N600c
+ ID_MODEL_FROM_DATABASE=82801CAM IDE U100 Controller (Evo N600c)
 
 pci:v00008086d0000248Asv00001014sd00000220*
- ID_MODEL_FROM_DATABASE=ThinkPad A/T/X Series
+ ID_MODEL_FROM_DATABASE=82801CAM IDE U100 Controller (ThinkPad A/T/X Series)
 
 pci:v00008086d0000248Asv0000104Dsd000080E7*
- ID_MODEL_FROM_DATABASE=VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
+ ID_MODEL_FROM_DATABASE=82801CAM IDE U100 Controller (VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP)
 
 pci:v00008086d0000248Asv00008086sd00001958*
- ID_MODEL_FROM_DATABASE=vpr Matrix 170B4
+ ID_MODEL_FROM_DATABASE=82801CAM IDE U100 Controller (vpr Matrix 170B4)
 
 pci:v00008086d0000248Asv00008086sd00004541*
- ID_MODEL_FROM_DATABASE=Latitude C640
+ ID_MODEL_FROM_DATABASE=82801CAM IDE U100 Controller (Latitude C640)
 
 pci:v00008086d0000248B*
  ID_MODEL_FROM_DATABASE=82801CA Ultra ATA Storage Controller
 
 pci:v00008086d0000248Bsv000015D9sd00003480*
- ID_MODEL_FROM_DATABASE=P4DP6
+ ID_MODEL_FROM_DATABASE=82801CA Ultra ATA Storage Controller (P4DP6)
 
 pci:v00008086d0000248C*
  ID_MODEL_FROM_DATABASE=82801CAM ISA Bridge (LPC)
@@ -60105,10 +61827,10 @@ pci:v00008086d000024C0*
  ID_MODEL_FROM_DATABASE=82801DB/DBL (ICH4/ICH4-L) LPC Interface Bridge
 
 pci:v00008086d000024C0sv00001014sd00000267*
- ID_MODEL_FROM_DATABASE=NetVista A30p
+ ID_MODEL_FROM_DATABASE=82801DB/DBL (ICH4/ICH4-L) LPC Interface Bridge (NetVista A30p)
 
 pci:v00008086d000024C0sv00001462sd00005800*
- ID_MODEL_FROM_DATABASE=845PE Max (MS-6580)
+ ID_MODEL_FROM_DATABASE=82801DB/DBL (ICH4/ICH4-L) LPC Interface Bridge (845PE Max (MS-6580))
 
 pci:v00008086d000024C1*
  ID_MODEL_FROM_DATABASE=82801DBL (ICH4-L) IDE Controller
@@ -60117,571 +61839,574 @@ pci:v00008086d000024C2*
  ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #1
 
 pci:v00008086d000024C2sv00001014sd00000267*
- ID_MODEL_FROM_DATABASE=NetVista A30p
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #1 (NetVista A30p)
 
 pci:v00008086d000024C2sv00001014sd0000052D*
- ID_MODEL_FROM_DATABASE=ThinkPad
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #1 (ThinkPad)
 
 pci:v00008086d000024C2sv00001025sd0000005A*
- ID_MODEL_FROM_DATABASE=TravelMate 290
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #1 (TravelMate 290)
 
 pci:v00008086d000024C2sv00001028sd00000126*
- ID_MODEL_FROM_DATABASE=Optiplex GX260
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #1 (Optiplex GX260)
 
 pci:v00008086d000024C2sv00001028sd00000163*
- ID_MODEL_FROM_DATABASE=Latitude D505
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #1 (Latitude D505)
 
 pci:v00008086d000024C2sv00001028sd0000018D*
- ID_MODEL_FROM_DATABASE=Inspiron 700m/710m
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #1 (Inspiron 700m/710m)
 
 pci:v00008086d000024C2sv00001028sd00000196*
- ID_MODEL_FROM_DATABASE=Inspiron 5160
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #1 (Inspiron 5160)
 
 pci:v00008086d000024C2sv0000103Csd0000088C*
- ID_MODEL_FROM_DATABASE=NC8000 laptop
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #1 (NC8000 laptop)
 
 pci:v00008086d000024C2sv0000103Csd00000890*
- ID_MODEL_FROM_DATABASE=NC6000 laptop
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #1 (NC6000 laptop)
 
 pci:v00008086d000024C2sv0000103Csd000008B0*
- ID_MODEL_FROM_DATABASE=tc1100 tablet
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #1 (tc1100 tablet)
 
 pci:v00008086d000024C2sv00001043sd00008089*
- ID_MODEL_FROM_DATABASE=P4B533
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #1 (P4B533)
 
 pci:v00008086d000024C2sv00001071sd00008160*
- ID_MODEL_FROM_DATABASE=MIM2000
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #1 (MIM2000)
 
 pci:v00008086d000024C2sv0000114Asd00000582*
- ID_MODEL_FROM_DATABASE=PC8 onboard USB 1.x
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #1 (PC8 onboard USB 1.x)
 
 pci:v00008086d000024C2sv0000144Dsd0000C005*
- ID_MODEL_FROM_DATABASE=X10 Laptop
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #1 (X10 Laptop)
 
 pci:v00008086d000024C2sv0000144Dsd0000C00C*
- ID_MODEL_FROM_DATABASE=P30/P35 notebook
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #1 (P30/P35 notebook)
 
 pci:v00008086d000024C2sv00001462sd00005800*
- ID_MODEL_FROM_DATABASE=845PE Max (MS-6580)
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #1 (845PE Max (MS-6580))
 
 pci:v00008086d000024C2sv00001509sd00002990*
- ID_MODEL_FROM_DATABASE=Averatec 5110H laptop
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #1 (Averatec 5110H laptop)
 
 pci:v00008086d000024C2sv00001734sd00001004*
- ID_MODEL_FROM_DATABASE=D1451 Mainboard (SCENIC N300, i845GV)
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #1 (D1451 Mainboard (SCENIC N300, i845GV))
 
 pci:v00008086d000024C2sv00001734sd00001055*
- ID_MODEL_FROM_DATABASE=Amilo M1420
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #1 (Amilo M1420)
 
 pci:v00008086d000024C2sv00004C53sd00001090*
- ID_MODEL_FROM_DATABASE=Cx9 / Vx9 mainboard
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #1 (Cx9 / Vx9 mainboard)
 
 pci:v00008086d000024C2sv00008086sd000024C2*
- ID_MODEL_FROM_DATABASE=Latitude X300
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #1 (Latitude X300)
 
 pci:v00008086d000024C2sv00008086sd00004541*
- ID_MODEL_FROM_DATABASE=Latitude D400/D500
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #1 (Latitude D400/D500)
 
 pci:v00008086d000024C2sv0000E4BFsd00000CC9*
- ID_MODEL_FROM_DATABASE=CC9-SAMBA
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #1 (CC9-SAMBA)
 
 pci:v00008086d000024C2sv0000E4BFsd00000CD2*
- ID_MODEL_FROM_DATABASE=CD2-BEBOP
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #1 (CD2-BEBOP)
 
 pci:v00008086d000024C3*
  ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) SMBus Controller
 
 pci:v00008086d000024C3sv00001014sd00000267*
- ID_MODEL_FROM_DATABASE=NetVista A30p
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) SMBus Controller (NetVista A30p)
 
 pci:v00008086d000024C3sv00001014sd0000052D*
- ID_MODEL_FROM_DATABASE=ThinkPad
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) SMBus Controller (ThinkPad)
 
 pci:v00008086d000024C3sv00001025sd0000005A*
- ID_MODEL_FROM_DATABASE=TravelMate 290
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) SMBus Controller (TravelMate 290)
 
 pci:v00008086d000024C3sv00001028sd00000126*
- ID_MODEL_FROM_DATABASE=Optiplex GX260
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) SMBus Controller (Optiplex GX260)
 
 pci:v00008086d000024C3sv00001028sd0000014F*
- ID_MODEL_FROM_DATABASE=Latitude X300
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) SMBus Controller (Latitude X300)
 
 pci:v00008086d000024C3sv00001028sd0000018D*
- ID_MODEL_FROM_DATABASE=Inspiron 700m/710m
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) SMBus Controller (Inspiron 700m/710m)
 
 pci:v00008086d000024C3sv0000103Csd0000088C*
- ID_MODEL_FROM_DATABASE=NC8000 laptop
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) SMBus Controller (NC8000 laptop)
 
 pci:v00008086d000024C3sv0000103Csd00000890*
- ID_MODEL_FROM_DATABASE=NC6000 laptop
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) SMBus Controller (NC6000 laptop)
 
 pci:v00008086d000024C3sv0000103Csd000008B0*
- ID_MODEL_FROM_DATABASE=tc1100 tablet
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) SMBus Controller (tc1100 tablet)
 
 pci:v00008086d000024C3sv00001071sd00008160*
- ID_MODEL_FROM_DATABASE=MIM2000
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) SMBus Controller (MIM2000)
 
 pci:v00008086d000024C3sv0000114Asd00000582*
- ID_MODEL_FROM_DATABASE=PC8 onboard SMbus
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) SMBus Controller (PC8 onboard SMbus)
 
 pci:v00008086d000024C3sv0000144Dsd0000C005*
- ID_MODEL_FROM_DATABASE=X10 Laptop
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) SMBus Controller (X10 Laptop)
 
 pci:v00008086d000024C3sv0000144Dsd0000C00C*
- ID_MODEL_FROM_DATABASE=P30/P35 notebook
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) SMBus Controller (P30/P35 notebook)
 
 pci:v00008086d000024C3sv00001458sd000024C2*
- ID_MODEL_FROM_DATABASE=GA-8PE667 Ultra
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) SMBus Controller (GA-8PE667 Ultra)
 
 pci:v00008086d000024C3sv00001462sd00005800*
- ID_MODEL_FROM_DATABASE=845PE Max (MS-6580)
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) SMBus Controller (845PE Max (MS-6580))
 
 pci:v00008086d000024C3sv00001734sd00001004*
- ID_MODEL_FROM_DATABASE=D1451 Mainboard (SCENIC N300, i845GV)
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) SMBus Controller (D1451 Mainboard (SCENIC N300, i845GV))
 
 pci:v00008086d000024C3sv00001734sd00001055*
- ID_MODEL_FROM_DATABASE=Amilo M1420
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) SMBus Controller (Amilo M1420)
 
 pci:v00008086d000024C3sv00004C53sd00001090*
- ID_MODEL_FROM_DATABASE=Cx9 / Vx9 mainboard
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) SMBus Controller (Cx9 / Vx9 mainboard)
 
 pci:v00008086d000024C3sv0000E4BFsd00000CC9*
- ID_MODEL_FROM_DATABASE=CC9-SAMBA
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) SMBus Controller (CC9-SAMBA)
 
 pci:v00008086d000024C3sv0000E4BFsd00000CD2*
- ID_MODEL_FROM_DATABASE=CD2-BEBOP
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) SMBus Controller (CD2-BEBOP)
 
 pci:v00008086d000024C4*
  ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #2
 
 pci:v00008086d000024C4sv00001014sd00000267*
- ID_MODEL_FROM_DATABASE=NetVista A30p
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #2 (NetVista A30p)
 
 pci:v00008086d000024C4sv00001014sd0000052D*
- ID_MODEL_FROM_DATABASE=ThinkPad
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #2 (ThinkPad)
 
 pci:v00008086d000024C4sv00001025sd0000005A*
- ID_MODEL_FROM_DATABASE=TravelMate 290
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #2 (TravelMate 290)
 
 pci:v00008086d000024C4sv00001028sd00000126*
- ID_MODEL_FROM_DATABASE=Optiplex GX260
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #2 (Optiplex GX260)
 
 pci:v00008086d000024C4sv00001028sd00000163*
- ID_MODEL_FROM_DATABASE=Latitude D505
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #2 (Latitude D505)
 
 pci:v00008086d000024C4sv00001028sd0000018D*
- ID_MODEL_FROM_DATABASE=Inspiron 700m/710m
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #2 (Inspiron 700m/710m)
 
 pci:v00008086d000024C4sv00001028sd00000196*
- ID_MODEL_FROM_DATABASE=Inspiron 5160
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #2 (Inspiron 5160)
 
 pci:v00008086d000024C4sv0000103Csd0000088C*
- ID_MODEL_FROM_DATABASE=NC8000 laptop
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #2 (NC8000 laptop)
 
 pci:v00008086d000024C4sv0000103Csd00000890*
- ID_MODEL_FROM_DATABASE=NC6000 laptop
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #2 (NC6000 laptop)
 
 pci:v00008086d000024C4sv0000103Csd000008B0*
- ID_MODEL_FROM_DATABASE=tc1100 tablet
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #2 (tc1100 tablet)
 
 pci:v00008086d000024C4sv00001043sd00008089*
- ID_MODEL_FROM_DATABASE=P4B533
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #2 (P4B533)
 
 pci:v00008086d000024C4sv00001071sd00008160*
- ID_MODEL_FROM_DATABASE=MIM2000
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #2 (MIM2000)
 
 pci:v00008086d000024C4sv0000144Dsd0000C00C*
- ID_MODEL_FROM_DATABASE=P30/P35 notebook
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #2 (P30/P35 notebook)
 
 pci:v00008086d000024C4sv00001462sd00005800*
- ID_MODEL_FROM_DATABASE=845PE Max (MS-6580)
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #2 (845PE Max (MS-6580))
 
 pci:v00008086d000024C4sv00001509sd00002990*
- ID_MODEL_FROM_DATABASE=Averatec 5110H
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #2 (Averatec 5110H)
 
 pci:v00008086d000024C4sv00001734sd00001004*
- ID_MODEL_FROM_DATABASE=D1451 Mainboard (SCENIC N300, i845GV)
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #2 (D1451 Mainboard (SCENIC N300, i845GV))
 
 pci:v00008086d000024C4sv00004C53sd00001090*
- ID_MODEL_FROM_DATABASE=Cx9 / Vx9 mainboard
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #2 (Cx9 / Vx9 mainboard)
 
 pci:v00008086d000024C4sv00008086sd000024C2*
- ID_MODEL_FROM_DATABASE=Latitude X300
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #2 (Latitude X300)
 
 pci:v00008086d000024C4sv00008086sd00004541*
- ID_MODEL_FROM_DATABASE=Latitude D400/D500
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #2 (Latitude D400/D500)
 
 pci:v00008086d000024C4sv0000E4BFsd00000CC9*
- ID_MODEL_FROM_DATABASE=CC9-SAMBA
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #2 (CC9-SAMBA)
 
 pci:v00008086d000024C4sv0000E4BFsd00000CD2*
- ID_MODEL_FROM_DATABASE=CD2-BEBOP
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #2 (CD2-BEBOP)
 
 pci:v00008086d000024C5*
  ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Audio Controller
 
 pci:v00008086d000024C5sv00000E11sd000000B8*
- ID_MODEL_FROM_DATABASE=Analog Devices Inc. codec [SoundMAX]
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Audio Controller (Analog Devices Inc. codec [SoundMAX])
 
 pci:v00008086d000024C5sv00001014sd00000267*
- ID_MODEL_FROM_DATABASE=NetVista A30p
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Audio Controller (NetVista A30p)
 
 pci:v00008086d000024C5sv00001014sd00000537*
- ID_MODEL_FROM_DATABASE=ThinkPad T41
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Audio Controller (ThinkPad T4x Series)
 
 pci:v00008086d000024C5sv00001014sd0000055F*
- ID_MODEL_FROM_DATABASE=Thinkpad R50e model 1634
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Audio Controller (Thinkpad R50e model 1634)
 
 pci:v00008086d000024C5sv00001025sd0000005A*
- ID_MODEL_FROM_DATABASE=TravelMate 290
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Audio Controller (TravelMate 290)
 
 pci:v00008086d000024C5sv00001028sd00000139*
- ID_MODEL_FROM_DATABASE=Latitude D400
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Audio Controller (Latitude D400)
 
 pci:v00008086d000024C5sv00001028sd0000014F*
- ID_MODEL_FROM_DATABASE=Latitude X300
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Audio Controller (Latitude X300)
 
 pci:v00008086d000024C5sv00001028sd00000152*
- ID_MODEL_FROM_DATABASE=Latitude D500
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Audio Controller (Latitude D500)
 
 pci:v00008086d000024C5sv00001028sd00000163*
- ID_MODEL_FROM_DATABASE=Latitude D505
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Audio Controller (Latitude D505)
 
 pci:v00008086d000024C5sv00001028sd0000018D*
- ID_MODEL_FROM_DATABASE=Inspiron 700m/710m [SigmaTel STAC9750,51]
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Audio Controller (Inspiron 700m/710m [SigmaTel STAC9750,51])
 
 pci:v00008086d000024C5sv00001028sd00000196*
- ID_MODEL_FROM_DATABASE=Inspiron 5160
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Audio Controller (Inspiron 5160)
 
 pci:v00008086d000024C5sv0000103Csd0000088C*
- ID_MODEL_FROM_DATABASE=NC8000 laptop
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Audio Controller (NC8000 laptop)
 
 pci:v00008086d000024C5sv0000103Csd00000890*
- ID_MODEL_FROM_DATABASE=NC6000 laptop
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Audio Controller (NC6000 laptop)
 
 pci:v00008086d000024C5sv0000103Csd000008B0*
- ID_MODEL_FROM_DATABASE=tc1100 tablet
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Audio Controller (tc1100 tablet)
 
 pci:v00008086d000024C5sv00001043sd00001713*
- ID_MODEL_FROM_DATABASE=M2400N/M6800N laptop
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Audio Controller (M2400N/M6800N laptop)
 
 pci:v00008086d000024C5sv00001043sd000080B0*
- ID_MODEL_FROM_DATABASE=P4B533
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Audio Controller (P4B533)
 
 pci:v00008086d000024C5sv00001071sd00008160*
- ID_MODEL_FROM_DATABASE=MIM2000
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Audio Controller (MIM2000)
 
 pci:v00008086d000024C5sv00001179sd00000201*
- ID_MODEL_FROM_DATABASE=Toshiba Tecra M1
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Audio Controller (Toshiba Tecra M1)
 
 pci:v00008086d000024C5sv0000144Dsd0000C005*
- ID_MODEL_FROM_DATABASE=X10 Laptop
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Audio Controller (X10 Laptop)
 
 pci:v00008086d000024C5sv0000144Dsd0000C00C*
- ID_MODEL_FROM_DATABASE=P30/P35 notebook
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Audio Controller (P30/P35 notebook)
 
 pci:v00008086d000024C5sv00001458sd0000A002*
- ID_MODEL_FROM_DATABASE=GA-8PE667 Ultra
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Audio Controller (GA-8PE667 Ultra)
 
 pci:v00008086d000024C5sv00001462sd00005800*
- ID_MODEL_FROM_DATABASE=845PE Max (MS-6580)
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Audio Controller (845PE Max (MS-6580))
 
 pci:v00008086d000024C5sv00001734sd00001005*
- ID_MODEL_FROM_DATABASE=D1451 (SCENIC N300, i845GV) Sigmatel STAC9750T
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Audio Controller (D1451 (SCENIC N300, i845GV) Sigmatel STAC9750T)
 
 pci:v00008086d000024C5sv00001734sd00001055*
- ID_MODEL_FROM_DATABASE=Amilo M1420
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Audio Controller (Amilo M1420)
 
 pci:v00008086d000024C5sv00008086sd000024C5*
- ID_MODEL_FROM_DATABASE=Dell Dimension 2400
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Audio Controller (Dell Dimension 2400)
 
 pci:v00008086d000024C6*
  ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Modem Controller
 
 pci:v00008086d000024C6sv00001014sd00000524*
- ID_MODEL_FROM_DATABASE=ThinkPad T41
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Modem Controller (ThinkPad T4x Series)
 
 pci:v00008086d000024C6sv00001014sd00000525*
- ID_MODEL_FROM_DATABASE=ThinkPad
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Modem Controller (ThinkPad)
 
 pci:v00008086d000024C6sv00001014sd00000559*
- ID_MODEL_FROM_DATABASE=ThinkPad R50e
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Modem Controller (ThinkPad R50e)
 
 pci:v00008086d000024C6sv00001025sd0000003C*
- ID_MODEL_FROM_DATABASE=Aspire 2001WLCi (Compal CL50 motherboard) implementation
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Modem Controller (Aspire 2001WLCi (Compal CL50 motherboard) implementation)
 
 pci:v00008086d000024C6sv00001025sd0000005A*
- ID_MODEL_FROM_DATABASE=TravelMate 290
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Modem Controller (TravelMate 290)
 
 pci:v00008086d000024C6sv00001028sd00000196*
- ID_MODEL_FROM_DATABASE=Inspiron 5160
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Modem Controller (Inspiron 5160)
 
 pci:v00008086d000024C6sv0000103Csd0000088C*
- ID_MODEL_FROM_DATABASE=NC8000 laptop
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Modem Controller (NC8000 laptop)
 
 pci:v00008086d000024C6sv0000103Csd00000890*
- ID_MODEL_FROM_DATABASE=NC6000 laptop
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Modem Controller (NC6000 laptop)
 
 pci:v00008086d000024C6sv0000103Csd000008B0*
- ID_MODEL_FROM_DATABASE=tc1100 tablet
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Modem Controller (tc1100 tablet)
 
 pci:v00008086d000024C6sv00001043sd00001716*
- ID_MODEL_FROM_DATABASE=M2400N laptop
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Modem Controller (M2400N laptop)
 
 pci:v00008086d000024C6sv00001043sd00001826*
- ID_MODEL_FROM_DATABASE=M6800N
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Modem Controller (M6800N)
 
 pci:v00008086d000024C6sv00001071sd00008160*
- ID_MODEL_FROM_DATABASE=MIM2000
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Modem Controller (MIM2000)
 
 pci:v00008086d000024C6sv0000134Dsd00004C21*
- ID_MODEL_FROM_DATABASE=Latitude D500
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Modem Controller (Latitude D500)
 
 pci:v00008086d000024C6sv0000144Dsd00002115*
- ID_MODEL_FROM_DATABASE=X10 Laptop
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Modem Controller (X10 Laptop)
 
 pci:v00008086d000024C6sv0000144Dsd0000C00C*
- ID_MODEL_FROM_DATABASE=P30/P35 notebook
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Modem Controller (P30/P35 notebook)
 
 pci:v00008086d000024C6sv000014F1sd00005422*
- ID_MODEL_FROM_DATABASE=D480 MDC V.9x Modem
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Modem Controller (D480 MDC V.9x Modem)
 
 pci:v00008086d000024C7*
  ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #3
 
 pci:v00008086d000024C7sv00001014sd00000267*
- ID_MODEL_FROM_DATABASE=NetVista A30p
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #3 (NetVista A30p)
 
 pci:v00008086d000024C7sv00001014sd0000052D*
- ID_MODEL_FROM_DATABASE=ThinkPad
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #3 (ThinkPad)
 
 pci:v00008086d000024C7sv00001025sd0000005A*
- ID_MODEL_FROM_DATABASE=TravelMate 290
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #3 (TravelMate 290)
 
 pci:v00008086d000024C7sv00001028sd00000126*
- ID_MODEL_FROM_DATABASE=Optiplex GX260
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #3 (Optiplex GX260)
 
 pci:v00008086d000024C7sv00001028sd00000163*
- ID_MODEL_FROM_DATABASE=Latitude D505
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #3 (Latitude D505)
 
 pci:v00008086d000024C7sv00001028sd0000018D*
- ID_MODEL_FROM_DATABASE=Inspiron 700m/710m
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #3 (Inspiron 700m/710m)
 
 pci:v00008086d000024C7sv00001028sd00000196*
- ID_MODEL_FROM_DATABASE=Inspiron 5160
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #3 (Inspiron 5160)
 
 pci:v00008086d000024C7sv0000103Csd0000088C*
- ID_MODEL_FROM_DATABASE=NC8000 laptop
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #3 (NC8000 laptop)
 
 pci:v00008086d000024C7sv0000103Csd00000890*
- ID_MODEL_FROM_DATABASE=NC6000 laptop
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #3 (NC6000 laptop)
 
 pci:v00008086d000024C7sv0000103Csd000008B0*
- ID_MODEL_FROM_DATABASE=tc1100 tablet
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #3 (tc1100 tablet)
 
 pci:v00008086d000024C7sv00001043sd00008089*
- ID_MODEL_FROM_DATABASE=P4B533
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #3 (P4B533)
 
 pci:v00008086d000024C7sv00001071sd00008160*
- ID_MODEL_FROM_DATABASE=MIM2000
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #3 (MIM2000)
 
 pci:v00008086d000024C7sv0000144Dsd0000C00C*
- ID_MODEL_FROM_DATABASE=P30/P35 notebook
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #3 (P30/P35 notebook)
 
 pci:v00008086d000024C7sv00001462sd00005800*
- ID_MODEL_FROM_DATABASE=845PE Max (MS-6580)
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #3 (845PE Max (MS-6580))
 
 pci:v00008086d000024C7sv00001509sd00002990*
- ID_MODEL_FROM_DATABASE=Averatec 5110H
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #3 (Averatec 5110H)
 
 pci:v00008086d000024C7sv00001734sd00001004*
- ID_MODEL_FROM_DATABASE=D1451 Mainboard (SCENIC N300, i845GV)
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #3 (D1451 Mainboard (SCENIC N300, i845GV))
 
 pci:v00008086d000024C7sv00004C53sd00001090*
- ID_MODEL_FROM_DATABASE=Cx9 / Vx9 mainboard
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #3 (Cx9 / Vx9 mainboard)
 
 pci:v00008086d000024C7sv00008086sd000024C2*
- ID_MODEL_FROM_DATABASE=Latitude X300
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #3 (Latitude X300)
 
 pci:v00008086d000024C7sv00008086sd00004541*
- ID_MODEL_FROM_DATABASE=Latitude D400/D500
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #3 (Latitude D400/D500)
 
 pci:v00008086d000024C7sv0000E4BFsd00000CC9*
- ID_MODEL_FROM_DATABASE=CC9-SAMBA
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #3 (CC9-SAMBA)
 
 pci:v00008086d000024C7sv0000E4BFsd00000CD2*
- ID_MODEL_FROM_DATABASE=CD2-BEBOP
+ ID_MODEL_FROM_DATABASE=82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #3 (CD2-BEBOP)
 
 pci:v00008086d000024CA*
  ID_MODEL_FROM_DATABASE=82801DBM (ICH4-M) IDE Controller
 
 pci:v00008086d000024CAsv00001014sd0000052D*
- ID_MODEL_FROM_DATABASE=ThinkPad
+ ID_MODEL_FROM_DATABASE=82801DBM (ICH4-M) IDE Controller (ThinkPad)
 
 pci:v00008086d000024CAsv00001025sd0000005A*
- ID_MODEL_FROM_DATABASE=TravelMate 290
+ ID_MODEL_FROM_DATABASE=82801DBM (ICH4-M) IDE Controller (TravelMate 290)
 
 pci:v00008086d000024CAsv00001028sd0000014F*
- ID_MODEL_FROM_DATABASE=Latitude X300
+ ID_MODEL_FROM_DATABASE=82801DBM (ICH4-M) IDE Controller (Latitude X300)
 
 pci:v00008086d000024CAsv00001028sd00000163*
- ID_MODEL_FROM_DATABASE=Latitude D505
+ ID_MODEL_FROM_DATABASE=82801DBM (ICH4-M) IDE Controller (Latitude D505)
 
 pci:v00008086d000024CAsv00001028sd0000018D*
- ID_MODEL_FROM_DATABASE=Inspiron 700m/710m
+ ID_MODEL_FROM_DATABASE=82801DBM (ICH4-M) IDE Controller (Inspiron 700m/710m)
 
 pci:v00008086d000024CAsv00001028sd00000196*
- ID_MODEL_FROM_DATABASE=Inspiron 5160
+ ID_MODEL_FROM_DATABASE=82801DBM (ICH4-M) IDE Controller (Inspiron 5160)
 
 pci:v00008086d000024CAsv0000103Csd0000088C*
- ID_MODEL_FROM_DATABASE=NC8000 laptop
+ ID_MODEL_FROM_DATABASE=82801DBM (ICH4-M) IDE Controller (NC8000 laptop)
 
 pci:v00008086d000024CAsv0000103Csd00000890*
- ID_MODEL_FROM_DATABASE=NC6000 laptop
+ ID_MODEL_FROM_DATABASE=82801DBM (ICH4-M) IDE Controller (NC6000 laptop)
 
 pci:v00008086d000024CAsv0000103Csd000008B0*
- ID_MODEL_FROM_DATABASE=tc1100 tablet
+ ID_MODEL_FROM_DATABASE=82801DBM (ICH4-M) IDE Controller (tc1100 tablet)
 
 pci:v00008086d000024CAsv00001071sd00008160*
- ID_MODEL_FROM_DATABASE=MIM2000
+ ID_MODEL_FROM_DATABASE=82801DBM (ICH4-M) IDE Controller (MIM2000)
 
 pci:v00008086d000024CAsv0000144Dsd0000C005*
- ID_MODEL_FROM_DATABASE=X10 Laptop
+ ID_MODEL_FROM_DATABASE=82801DBM (ICH4-M) IDE Controller (X10 Laptop)
 
 pci:v00008086d000024CAsv0000144Dsd0000C00C*
- ID_MODEL_FROM_DATABASE=P30/P35 notebook
+ ID_MODEL_FROM_DATABASE=82801DBM (ICH4-M) IDE Controller (P30/P35 notebook)
 
 pci:v00008086d000024CAsv00001734sd00001055*
- ID_MODEL_FROM_DATABASE=Amilo M1420
+ ID_MODEL_FROM_DATABASE=82801DBM (ICH4-M) IDE Controller (Amilo M1420)
 
 pci:v00008086d000024CAsv00008086sd00004541*
- ID_MODEL_FROM_DATABASE=Latitude D400/D500
+ ID_MODEL_FROM_DATABASE=82801DBM (ICH4-M) IDE Controller (Latitude D400/D500)
 
 pci:v00008086d000024CB*
  ID_MODEL_FROM_DATABASE=82801DB (ICH4) IDE Controller
 
 pci:v00008086d000024CBsv00001014sd00000267*
- ID_MODEL_FROM_DATABASE=NetVista A30p
+ ID_MODEL_FROM_DATABASE=82801DB (ICH4) IDE Controller (NetVista A30p)
 
 pci:v00008086d000024CBsv00001028sd00000126*
- ID_MODEL_FROM_DATABASE=Optiplex GX260
+ ID_MODEL_FROM_DATABASE=82801DB (ICH4) IDE Controller (Optiplex GX260)
 
 pci:v00008086d000024CBsv00001043sd00008089*
- ID_MODEL_FROM_DATABASE=P4B533
+ ID_MODEL_FROM_DATABASE=82801DB (ICH4) IDE Controller (P4B533)
 
 pci:v00008086d000024CBsv0000114Asd00000582*
- ID_MODEL_FROM_DATABASE=PC8 onboard IDE
+ ID_MODEL_FROM_DATABASE=82801DB (ICH4) IDE Controller (PC8 onboard IDE)
 
 pci:v00008086d000024CBsv00001458sd000024C2*
- ID_MODEL_FROM_DATABASE=GA-8PE667 Ultra
+ ID_MODEL_FROM_DATABASE=82801DB (ICH4) IDE Controller (GA-8PE667 Ultra)
 
 pci:v00008086d000024CBsv00001462sd00005800*
- ID_MODEL_FROM_DATABASE=845PE Max (MS-6580)
+ ID_MODEL_FROM_DATABASE=82801DB (ICH4) IDE Controller (845PE Max (MS-6580))
 
 pci:v00008086d000024CBsv00001734sd00001004*
- ID_MODEL_FROM_DATABASE=D1451 Mainboard (SCENIC N300, i845GV)
+ ID_MODEL_FROM_DATABASE=82801DB (ICH4) IDE Controller (D1451 Mainboard (SCENIC N300, i845GV))
 
 pci:v00008086d000024CBsv00004C53sd00001090*
- ID_MODEL_FROM_DATABASE=Cx9 / Vx9 mainboard
+ ID_MODEL_FROM_DATABASE=82801DB (ICH4) IDE Controller (Cx9 / Vx9 mainboard)
 
 pci:v00008086d000024CBsv0000E4BFsd00000CC9*
- ID_MODEL_FROM_DATABASE=CC9-SAMBA
+ ID_MODEL_FROM_DATABASE=82801DB (ICH4) IDE Controller (CC9-SAMBA)
 
 pci:v00008086d000024CBsv0000E4BFsd00000CD2*
- ID_MODEL_FROM_DATABASE=CD2-BEBOP
+ ID_MODEL_FROM_DATABASE=82801DB (ICH4) IDE Controller (CD2-BEBOP)
 
 pci:v00008086d000024CC*
  ID_MODEL_FROM_DATABASE=82801DBM (ICH4-M) LPC Interface Bridge
 
 pci:v00008086d000024CCsv0000144Dsd0000C00C*
- ID_MODEL_FROM_DATABASE=P30 notebook
+ ID_MODEL_FROM_DATABASE=82801DBM (ICH4-M) LPC Interface Bridge (P30 notebook)
 
 pci:v00008086d000024CCsv00001734sd00001055*
- ID_MODEL_FROM_DATABASE=Amilo M1420
+ ID_MODEL_FROM_DATABASE=82801DBM (ICH4-M) LPC Interface Bridge (Amilo M1420)
 
 pci:v00008086d000024CD*
  ID_MODEL_FROM_DATABASE=82801DB/DBM (ICH4/ICH4-M) USB2 EHCI Controller
 
 pci:v00008086d000024CDsv00001014sd00000267*
- ID_MODEL_FROM_DATABASE=NetVista A30p
+ ID_MODEL_FROM_DATABASE=82801DB/DBM (ICH4/ICH4-M) USB2 EHCI Controller (NetVista A30p)
 
 pci:v00008086d000024CDsv00001014sd0000052E*
- ID_MODEL_FROM_DATABASE=ThinkPad
+ ID_MODEL_FROM_DATABASE=82801DB/DBM (ICH4/ICH4-M) USB2 EHCI Controller (ThinkPad)
 
 pci:v00008086d000024CDsv00001025sd0000005A*
- ID_MODEL_FROM_DATABASE=TravelMate 290
+ ID_MODEL_FROM_DATABASE=82801DB/DBM (ICH4/ICH4-M) USB2 EHCI Controller (TravelMate 290)
 
 pci:v00008086d000024CDsv00001028sd0000011D*
- ID_MODEL_FROM_DATABASE=Latitude D600
+ ID_MODEL_FROM_DATABASE=82801DB/DBM (ICH4/ICH4-M) USB2 EHCI Controller (Latitude D600)
 
 pci:v00008086d000024CDsv00001028sd00000126*
- ID_MODEL_FROM_DATABASE=Optiplex GX260
+ ID_MODEL_FROM_DATABASE=82801DB/DBM (ICH4/ICH4-M) USB2 EHCI Controller (Optiplex GX260)
 
 pci:v00008086d000024CDsv00001028sd00000139*
- ID_MODEL_FROM_DATABASE=Latitude D400
+ ID_MODEL_FROM_DATABASE=82801DB/DBM (ICH4/ICH4-M) USB2 EHCI Controller (Latitude D400)
 
 pci:v00008086d000024CDsv00001028sd00000152*
- ID_MODEL_FROM_DATABASE=Latitude D500
+ ID_MODEL_FROM_DATABASE=82801DB/DBM (ICH4/ICH4-M) USB2 EHCI Controller (Latitude D500)
 
 pci:v00008086d000024CDsv00001028sd00000163*
- ID_MODEL_FROM_DATABASE=Latitude D505
+ ID_MODEL_FROM_DATABASE=82801DB/DBM (ICH4/ICH4-M) USB2 EHCI Controller (Latitude D505)
 
 pci:v00008086d000024CDsv00001028sd0000018D*
- ID_MODEL_FROM_DATABASE=Inspiron 700m/710m
+ ID_MODEL_FROM_DATABASE=82801DB/DBM (ICH4/ICH4-M) USB2 EHCI Controller (Inspiron 700m/710m)
 
 pci:v00008086d000024CDsv00001028sd00000196*
- ID_MODEL_FROM_DATABASE=Inspiron 5160
+ ID_MODEL_FROM_DATABASE=82801DB/DBM (ICH4/ICH4-M) USB2 EHCI Controller (Inspiron 5160)
 
 pci:v00008086d000024CDsv0000103Csd0000088C*
- ID_MODEL_FROM_DATABASE=NC8000 laptop
+ ID_MODEL_FROM_DATABASE=82801DB/DBM (ICH4/ICH4-M) USB2 EHCI Controller (NC8000 laptop)
 
 pci:v00008086d000024CDsv0000103Csd00000890*
- ID_MODEL_FROM_DATABASE=NC6000 laptop
+ ID_MODEL_FROM_DATABASE=82801DB/DBM (ICH4/ICH4-M) USB2 EHCI Controller (NC6000 laptop)
 
 pci:v00008086d000024CDsv0000103Csd000008B0*
- ID_MODEL_FROM_DATABASE=tc1100 tablet
+ ID_MODEL_FROM_DATABASE=82801DB/DBM (ICH4/ICH4-M) USB2 EHCI Controller (tc1100 tablet)
 
 pci:v00008086d000024CDsv00001043sd00008089*
- ID_MODEL_FROM_DATABASE=P4B533
+ ID_MODEL_FROM_DATABASE=82801DB/DBM (ICH4/ICH4-M) USB2 EHCI Controller (P4B533)
 
 pci:v00008086d000024CDsv00001071sd00008160*
- ID_MODEL_FROM_DATABASE=MIM2000
+ ID_MODEL_FROM_DATABASE=82801DB/DBM (ICH4/ICH4-M) USB2 EHCI Controller (MIM2000)
 
 pci:v00008086d000024CDsv0000114Asd00000582*
- ID_MODEL_FROM_DATABASE=PC8 onboard USB 2.0
+ ID_MODEL_FROM_DATABASE=82801DB/DBM (ICH4/ICH4-M) USB2 EHCI Controller (PC8 onboard USB 2.0)
 
 pci:v00008086d000024CDsv00001179sd0000FF00*
- ID_MODEL_FROM_DATABASE=Satellite 2430
+ ID_MODEL_FROM_DATABASE=82801DB/DBM (ICH4/ICH4-M) USB2 EHCI Controller (Satellite 2430)
 
 pci:v00008086d000024CDsv0000144Dsd0000C005*
- ID_MODEL_FROM_DATABASE=X10 Laptop
+ ID_MODEL_FROM_DATABASE=82801DB/DBM (ICH4/ICH4-M) USB2 EHCI Controller (X10 Laptop)
 
 pci:v00008086d000024CDsv0000144Dsd0000C00C*
- ID_MODEL_FROM_DATABASE=P30/P35 notebook
+ ID_MODEL_FROM_DATABASE=82801DB/DBM (ICH4/ICH4-M) USB2 EHCI Controller (P30/P35 notebook)
 
 pci:v00008086d000024CDsv00001462sd00003981*
- ID_MODEL_FROM_DATABASE=845PE Max (MS-6580)
+ ID_MODEL_FROM_DATABASE=82801DB/DBM (ICH4/ICH4-M) USB2 EHCI Controller (845PE Max (MS-6580))
 
 pci:v00008086d000024CDsv00001509sd00001968*
- ID_MODEL_FROM_DATABASE=Averatec 5110H
+ ID_MODEL_FROM_DATABASE=82801DB/DBM (ICH4/ICH4-M) USB2 EHCI Controller (Averatec 5110H)
 
 pci:v00008086d000024CDsv00001734sd00001004*
- ID_MODEL_FROM_DATABASE=D1451 Mainboard (SCENIC N300, i845GV)
+ ID_MODEL_FROM_DATABASE=82801DB/DBM (ICH4/ICH4-M) USB2 EHCI Controller (D1451 Mainboard (SCENIC N300, i845GV))
 
 pci:v00008086d000024CDsv00001734sd00001055*
- ID_MODEL_FROM_DATABASE=Amilo M1420
+ ID_MODEL_FROM_DATABASE=82801DB/DBM (ICH4/ICH4-M) USB2 EHCI Controller (Amilo M1420)
+
+pci:v00008086d000024CDsv00001AF4sd00001100*
+ ID_MODEL_FROM_DATABASE=82801DB/DBM (ICH4/ICH4-M) USB2 EHCI Controller (QEMU Virtual Machine)
 
 pci:v00008086d000024CDsv00004C53sd00001090*
- ID_MODEL_FROM_DATABASE=Cx9 / Vx9 mainboard
+ ID_MODEL_FROM_DATABASE=82801DB/DBM (ICH4/ICH4-M) USB2 EHCI Controller (Cx9 / Vx9 mainboard)
 
 pci:v00008086d000024CDsv00008086sd000024C2*
- ID_MODEL_FROM_DATABASE=Latitude X300
+ ID_MODEL_FROM_DATABASE=82801DB/DBM (ICH4/ICH4-M) USB2 EHCI Controller (Latitude X300)
 
 pci:v00008086d000024CDsv0000E4BFsd00000CC9*
- ID_MODEL_FROM_DATABASE=CC9-SAMBA
+ ID_MODEL_FROM_DATABASE=82801DB/DBM (ICH4/ICH4-M) USB2 EHCI Controller (CC9-SAMBA)
 
 pci:v00008086d000024CDsv0000E4BFsd00000CD2*
- ID_MODEL_FROM_DATABASE=CD2-BEBOP
+ ID_MODEL_FROM_DATABASE=82801DB/DBM (ICH4/ICH4-M) USB2 EHCI Controller (CD2-BEBOP)
 
 pci:v00008086d000024D0*
  ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) LPC Interface Bridge
@@ -60689,416 +62414,437 @@ pci:v00008086d000024D0*
 pci:v00008086d000024D1*
  ID_MODEL_FROM_DATABASE=82801EB (ICH5) SATA Controller
 
+pci:v00008086d000024D1sv00001028sd00000168*
+ ID_MODEL_FROM_DATABASE=82801EB (ICH5) SATA Controller (Precision Workstation 670 Mainboard)
+
 pci:v00008086d000024D1sv00001028sd00000169*
- ID_MODEL_FROM_DATABASE=Precision 470
+ ID_MODEL_FROM_DATABASE=82801EB (ICH5) SATA Controller (Precision 470)
 
 pci:v00008086d000024D1sv00001028sd0000019A*
- ID_MODEL_FROM_DATABASE=PowerEdge SC1425
+ ID_MODEL_FROM_DATABASE=82801EB (ICH5) SATA Controller (PowerEdge SC1425)
 
 pci:v00008086d000024D1sv0000103Csd000012BC*
- ID_MODEL_FROM_DATABASE=d530 CMT (DG746A)
+ ID_MODEL_FROM_DATABASE=82801EB (ICH5) SATA Controller (d530 CMT (DG746A))
 
 pci:v00008086d000024D1sv0000103Csd00003208*
- ID_MODEL_FROM_DATABASE=ProLiant DL140 G2
+ ID_MODEL_FROM_DATABASE=82801EB (ICH5) SATA Controller (ProLiant DL140 G2)
 
 pci:v00008086d000024D1sv00001043sd000080A6*
- ID_MODEL_FROM_DATABASE=P4P800 series motherboard
+ ID_MODEL_FROM_DATABASE=82801EB (ICH5) SATA Controller (P4P800 series motherboard)
 
 pci:v00008086d000024D1sv00001458sd000024D1*
- ID_MODEL_FROM_DATABASE=GA-8IPE1000 Pro2 motherboard (865PE)
+ ID_MODEL_FROM_DATABASE=82801EB (ICH5) SATA Controller (GA-8IPE1000 Pro2 motherboard (865PE))
 
 pci:v00008086d000024D1sv00001462sd00007280*
- ID_MODEL_FROM_DATABASE=865PE Neo2 (MS-6728)
+ ID_MODEL_FROM_DATABASE=82801EB (ICH5) SATA Controller (865PE Neo2 (MS-6728))
 
 pci:v00008086d000024D1sv00001462sd00007650*
- ID_MODEL_FROM_DATABASE=Hetis 865GV-E (MS-7065)
+ ID_MODEL_FROM_DATABASE=82801EB (ICH5) SATA Controller (Hetis 865GV-E (MS-7065))
 
 pci:v00008086d000024D1sv00001565sd00005200*
- ID_MODEL_FROM_DATABASE=P4TSV Motherboard (865G)
+ ID_MODEL_FROM_DATABASE=82801EB (ICH5) SATA Controller (P4TSV Motherboard (865G))
 
 pci:v00008086d000024D1sv000015D9sd00004580*
- ID_MODEL_FROM_DATABASE=P4SCE Mainboard
+ ID_MODEL_FROM_DATABASE=82801EB (ICH5) SATA Controller (P4SCE Mainboard)
 
 pci:v00008086d000024D1sv00008086sd00003427*
- ID_MODEL_FROM_DATABASE=S875WP1-E mainboard
+ ID_MODEL_FROM_DATABASE=82801EB (ICH5) SATA Controller (S875WP1-E mainboard)
 
 pci:v00008086d000024D1sv00008086sd00004246*
- ID_MODEL_FROM_DATABASE=Desktop Board D865GBF
+ ID_MODEL_FROM_DATABASE=82801EB (ICH5) SATA Controller (Desktop Board D865GBF)
 
 pci:v00008086d000024D1sv00008086sd00004C43*
- ID_MODEL_FROM_DATABASE=Desktop Board D865GLC
+ ID_MODEL_FROM_DATABASE=82801EB (ICH5) SATA Controller (Desktop Board D865GLC)
 
 pci:v00008086d000024D1sv00008086sd0000524C*
- ID_MODEL_FROM_DATABASE=D865PERL mainboard
+ ID_MODEL_FROM_DATABASE=82801EB (ICH5) SATA Controller (D865PERL mainboard)
 
 pci:v00008086d000024D2*
  ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #1
 
 pci:v00008086d000024D2sv00001014sd000002DD*
- ID_MODEL_FROM_DATABASE=eServer xSeries server mainboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #1 (eServer xSeries server mainboard)
 
 pci:v00008086d000024D2sv00001014sd000002ED*
- ID_MODEL_FROM_DATABASE=eServer xSeries server mainboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #1 (eServer xSeries server mainboard)
+
+pci:v00008086d000024D2sv00001028sd00000168*
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #1 (Precision Workstation 670 Mainboard)
 
 pci:v00008086d000024D2sv00001028sd00000169*
- ID_MODEL_FROM_DATABASE=Precision 470
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #1 (Precision 470)
 
 pci:v00008086d000024D2sv00001028sd0000016C*
- ID_MODEL_FROM_DATABASE=PowerEdge 1850 onboard UHCI
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #1 (PowerEdge 1850 onboard UHCI)
 
 pci:v00008086d000024D2sv00001028sd0000016D*
- ID_MODEL_FROM_DATABASE=PowerEdge 2850 onboard UHCI
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #1 (PowerEdge 2850 onboard UHCI)
 
 pci:v00008086d000024D2sv00001028sd00000170*
- ID_MODEL_FROM_DATABASE=PowerEdge 6850 onboard UHCI
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #1 (PowerEdge 6850 onboard UHCI)
 
 pci:v00008086d000024D2sv00001028sd00000183*
- ID_MODEL_FROM_DATABASE=PowerEdge 1800
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #1 (PowerEdge 1800)
 
 pci:v00008086d000024D2sv00001028sd0000019A*
- ID_MODEL_FROM_DATABASE=PowerEdge SC1425
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #1 (PowerEdge SC1425)
 
 pci:v00008086d000024D2sv0000103Csd0000006A*
- ID_MODEL_FROM_DATABASE=NX9500
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #1 (NX9500)
 
 pci:v00008086d000024D2sv0000103Csd000012BC*
- ID_MODEL_FROM_DATABASE=d530 CMT (DG746A)
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #1 (d530 CMT (DG746A))
 
 pci:v00008086d000024D2sv0000103Csd00003208*
- ID_MODEL_FROM_DATABASE=ProLiant DL140 G2
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #1 (ProLiant DL140 G2)
 
 pci:v00008086d000024D2sv00001043sd000080A6*
- ID_MODEL_FROM_DATABASE=P4P800/P5P800 series motherboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #1 (P4P800/P5P800 series motherboard)
 
 pci:v00008086d000024D2sv00001458sd000024D2*
- ID_MODEL_FROM_DATABASE=GA-8IPE1000/8KNXP motherboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #1 (GA-8IPE1000/8KNXP motherboard)
 
 pci:v00008086d000024D2sv00001462sd00007280*
- ID_MODEL_FROM_DATABASE=865PE Neo2 (MS-6728)
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #1 (865PE Neo2 (MS-6728))
 
 pci:v00008086d000024D2sv00001565sd00003101*
- ID_MODEL_FROM_DATABASE=P4TSV Motherboard (865G)
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #1 (P4TSV Motherboard (865G))
 
 pci:v00008086d000024D2sv000015D9sd00004580*
- ID_MODEL_FROM_DATABASE=P4SCE Mainboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #1 (P4SCE Mainboard)
 
 pci:v00008086d000024D2sv00001734sd0000101C*
- ID_MODEL_FROM_DATABASE=PRIMERGY RX/TX series onboard UHCI
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #1 (PRIMERGY RX/TX series onboard UHCI)
 
 pci:v00008086d000024D2sv00008086sd00003427*
- ID_MODEL_FROM_DATABASE=S875WP1-E mainboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #1 (S875WP1-E mainboard)
 
 pci:v00008086d000024D2sv00008086sd00004246*
- ID_MODEL_FROM_DATABASE=Desktop Board D865GBF
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #1 (Desktop Board D865GBF)
 
 pci:v00008086d000024D2sv00008086sd00004C43*
- ID_MODEL_FROM_DATABASE=Desktop Board D865GLC
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #1 (Desktop Board D865GLC)
 
 pci:v00008086d000024D2sv00008086sd0000524C*
- ID_MODEL_FROM_DATABASE=D865PERL mainboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #1 (D865PERL mainboard)
 
 pci:v00008086d000024D3*
  ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) SMBus Controller
 
 pci:v00008086d000024D3sv00001014sd000002DD*
- ID_MODEL_FROM_DATABASE=eServer xSeries server mainboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) SMBus Controller (eServer xSeries server mainboard)
 
 pci:v00008086d000024D3sv00001014sd000002ED*
- ID_MODEL_FROM_DATABASE=eServer xSeries server mainboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) SMBus Controller (eServer xSeries server mainboard)
 
 pci:v00008086d000024D3sv00001028sd00000156*
- ID_MODEL_FROM_DATABASE=Precision 360
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) SMBus Controller (Precision 360)
+
+pci:v00008086d000024D3sv00001028sd00000168*
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) SMBus Controller (Precision Workstation 670 Mainboard)
 
 pci:v00008086d000024D3sv00001028sd00000169*
- ID_MODEL_FROM_DATABASE=Precision 470
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) SMBus Controller (Precision 470)
 
 pci:v00008086d000024D3sv0000103Csd000012BC*
- ID_MODEL_FROM_DATABASE=d330 uT
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) SMBus Controller (d330 uT)
 
 pci:v00008086d000024D3sv0000103Csd00003208*
- ID_MODEL_FROM_DATABASE=ProLiant DL140 G2
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) SMBus Controller (ProLiant DL140 G2)
 
 pci:v00008086d000024D3sv00001043sd000080A6*
- ID_MODEL_FROM_DATABASE=P4P800/P5P800 series motherboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) SMBus Controller (P4P800/P5P800 series motherboard)
 
 pci:v00008086d000024D3sv00001458sd000024D2*
- ID_MODEL_FROM_DATABASE=GA-8IPE1000 Pro2 motherboard (865PE)
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) SMBus Controller (GA-8IPE1000 Pro2 motherboard (865PE))
 
 pci:v00008086d000024D3sv00001462sd00007280*
- ID_MODEL_FROM_DATABASE=865PE Neo2 (MS-6728)
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) SMBus Controller (865PE Neo2 (MS-6728))
 
 pci:v00008086d000024D3sv00001462sd00007650*
- ID_MODEL_FROM_DATABASE=Hetis 865GV-E (MS-7065)
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) SMBus Controller (Hetis 865GV-E (MS-7065))
 
 pci:v00008086d000024D3sv00001565sd00003101*
- ID_MODEL_FROM_DATABASE=P4TSV Motherboard (865G)
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) SMBus Controller (P4TSV Motherboard (865G))
 
 pci:v00008086d000024D3sv000015D9sd00004580*
- ID_MODEL_FROM_DATABASE=P4SCE Mainboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) SMBus Controller (P4SCE Mainboard)
 
 pci:v00008086d000024D3sv00001734sd0000101C*
- ID_MODEL_FROM_DATABASE=PRIMERGY RX/TX S2 series SMBus
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) SMBus Controller (PRIMERGY RX/TX S2 series SMBus)
 
 pci:v00008086d000024D3sv00008086sd00003427*
- ID_MODEL_FROM_DATABASE=S875WP1-E mainboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) SMBus Controller (S875WP1-E mainboard)
 
 pci:v00008086d000024D3sv00008086sd00004246*
- ID_MODEL_FROM_DATABASE=Desktop Board D865GBF
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) SMBus Controller (Desktop Board D865GBF)
 
 pci:v00008086d000024D3sv00008086sd00004C43*
- ID_MODEL_FROM_DATABASE=Desktop Board D865GLC
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) SMBus Controller (Desktop Board D865GLC)
 
 pci:v00008086d000024D3sv00008086sd0000524C*
- ID_MODEL_FROM_DATABASE=D865PERL mainboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) SMBus Controller (D865PERL mainboard)
 
 pci:v00008086d000024D4*
  ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #2
 
 pci:v00008086d000024D4sv00001014sd000002DD*
- ID_MODEL_FROM_DATABASE=eServer xSeries server mainboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #2 (eServer xSeries server mainboard)
 
 pci:v00008086d000024D4sv00001014sd000002ED*
- ID_MODEL_FROM_DATABASE=eServer xSeries server mainboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #2 (eServer xSeries server mainboard)
+
+pci:v00008086d000024D4sv00001028sd00000168*
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #2 (Precision Workstation 670 Mainboard)
 
 pci:v00008086d000024D4sv00001028sd00000169*
- ID_MODEL_FROM_DATABASE=Precision 470
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #2 (Precision 470)
 
 pci:v00008086d000024D4sv00001028sd0000016C*
- ID_MODEL_FROM_DATABASE=PowerEdge 1850 onboard UHCI
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #2 (PowerEdge 1850 onboard UHCI)
 
 pci:v00008086d000024D4sv00001028sd0000016D*
- ID_MODEL_FROM_DATABASE=PowerEdge 2850 onboard UHCI
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #2 (PowerEdge 2850 onboard UHCI)
 
 pci:v00008086d000024D4sv00001028sd00000170*
- ID_MODEL_FROM_DATABASE=PowerEdge 6850 onboard UHCI
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #2 (PowerEdge 6850 onboard UHCI)
 
 pci:v00008086d000024D4sv00001028sd00000183*
- ID_MODEL_FROM_DATABASE=PowerEdge 1800
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #2 (PowerEdge 1800)
 
 pci:v00008086d000024D4sv00001028sd0000019A*
- ID_MODEL_FROM_DATABASE=PowerEdge SC1425
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #2 (PowerEdge SC1425)
 
 pci:v00008086d000024D4sv0000103Csd0000006A*
- ID_MODEL_FROM_DATABASE=NX9500
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #2 (NX9500)
 
 pci:v00008086d000024D4sv0000103Csd000012BC*
- ID_MODEL_FROM_DATABASE=d530 CMT (DG746A)
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #2 (d530 CMT (DG746A))
 
 pci:v00008086d000024D4sv0000103Csd00003208*
- ID_MODEL_FROM_DATABASE=ProLiant DL140 G2
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #2 (ProLiant DL140 G2)
 
 pci:v00008086d000024D4sv00001043sd000080A6*
- ID_MODEL_FROM_DATABASE=P4P800/P5P800 series motherboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #2 (P4P800/P5P800 series motherboard)
 
 pci:v00008086d000024D4sv00001458sd000024D2*
- ID_MODEL_FROM_DATABASE=GA-8IPE1000 Pro2 motherboard (865PE)
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #2 (GA-8IPE1000 Pro2 motherboard (865PE))
 
 pci:v00008086d000024D4sv00001462sd00007280*
- ID_MODEL_FROM_DATABASE=865PE Neo2 (MS-6728)
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #2 (865PE Neo2 (MS-6728))
 
 pci:v00008086d000024D4sv00001462sd00007650*
- ID_MODEL_FROM_DATABASE=Hetis 865GV-E (MS-7065)
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #2 (Hetis 865GV-E (MS-7065))
 
 pci:v00008086d000024D4sv00001565sd00003101*
- ID_MODEL_FROM_DATABASE=P4TSV Motherboard (865G)
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #2 (P4TSV Motherboard (865G))
 
 pci:v00008086d000024D4sv000015D9sd00004580*
- ID_MODEL_FROM_DATABASE=P4SCE Mainboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #2 (P4SCE Mainboard)
 
 pci:v00008086d000024D4sv00001734sd0000101C*
- ID_MODEL_FROM_DATABASE=PRIMERGY RX/TX S2 series onboard UHCI
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #2 (PRIMERGY RX/TX S2 series onboard UHCI)
 
 pci:v00008086d000024D4sv00008086sd00003427*
- ID_MODEL_FROM_DATABASE=S875WP1-E mainboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #2 (S875WP1-E mainboard)
 
 pci:v00008086d000024D4sv00008086sd00004246*
- ID_MODEL_FROM_DATABASE=Desktop Board D865GBF
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #2 (Desktop Board D865GBF)
 
 pci:v00008086d000024D4sv00008086sd00004C43*
- ID_MODEL_FROM_DATABASE=Desktop Board D865GLC
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #2 (Desktop Board D865GLC)
 
 pci:v00008086d000024D4sv00008086sd0000524C*
- ID_MODEL_FROM_DATABASE=D865PERL mainboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #2 (D865PERL mainboard)
 
 pci:v00008086d000024D5*
  ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) AC'97 Audio Controller
 
 pci:v00008086d000024D5sv0000100Asd0000147B*
- ID_MODEL_FROM_DATABASE=Abit IS7-E motherboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) AC'97 Audio Controller (Abit IS7-E motherboard)
+
+pci:v00008086d000024D5sv00001028sd00000168*
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) AC'97 Audio Controller (Precision Workstation 670 Mainboard)
 
 pci:v00008086d000024D5sv00001028sd00000169*
- ID_MODEL_FROM_DATABASE=Precision 470
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) AC'97 Audio Controller (Precision 470)
 
 pci:v00008086d000024D5sv0000103Csd0000006A*
- ID_MODEL_FROM_DATABASE=NX9500
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) AC'97 Audio Controller (NX9500)
 
 pci:v00008086d000024D5sv0000103Csd000012BC*
- ID_MODEL_FROM_DATABASE=d330 uT
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) AC'97 Audio Controller (d330 uT)
 
 pci:v00008086d000024D5sv00001043sd000080F3*
- ID_MODEL_FROM_DATABASE=P4P800 series motherboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) AC'97 Audio Controller (P4P800 series motherboard)
 
 pci:v00008086d000024D5sv00001043sd0000810F*
- ID_MODEL_FROM_DATABASE=P5P800-MX Mainboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) AC'97 Audio Controller (P5P800-MX Mainboard)
 
 pci:v00008086d000024D5sv00001458sd0000A002*
- ID_MODEL_FROM_DATABASE=GA-8IPE1000/8KNXP motherboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) AC'97 Audio Controller (GA-8IPE1000/8KNXP motherboard)
 
 pci:v00008086d000024D5sv00001462sd00000080*
- ID_MODEL_FROM_DATABASE=865PE Neo2-V (MS-6788) Mainboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) AC'97 Audio Controller (865PE Neo2-V (MS-6788) Mainboard)
 
 pci:v00008086d000024D5sv00001462sd00007280*
- ID_MODEL_FROM_DATABASE=865PE Neo2 (MS-6728)
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) AC'97 Audio Controller (865PE Neo2 (MS-6728))
 
 pci:v00008086d000024D5sv00001462sd00007650*
- ID_MODEL_FROM_DATABASE=Hetis 865GV-E (MS-7065)
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) AC'97 Audio Controller (Hetis 865GV-E (MS-7065))
 
 pci:v00008086d000024D5sv00008086sd0000A000*
- ID_MODEL_FROM_DATABASE=D865PERL mainboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) AC'97 Audio Controller (D865PERL mainboard)
 
 pci:v00008086d000024D5sv00008086sd0000E000*
- ID_MODEL_FROM_DATABASE=D865PERL mainboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) AC'97 Audio Controller (D865PERL mainboard)
 
 pci:v00008086d000024D5sv00008086sd0000E001*
- ID_MODEL_FROM_DATABASE=Desktop Board D865GBF
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) AC'97 Audio Controller (Desktop Board D865GBF)
 
 pci:v00008086d000024D5sv00008086sd0000E002*
- ID_MODEL_FROM_DATABASE=SoundMax Intergrated Digital Audio
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) AC'97 Audio Controller (SoundMax Intergrated Digital Audio)
 
 pci:v00008086d000024D6*
  ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) AC'97 Modem Controller
 
 pci:v00008086d000024D6sv0000103Csd0000006A*
- ID_MODEL_FROM_DATABASE=NX9500
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) AC'97 Modem Controller (NX9500)
 
 pci:v00008086d000024D7*
  ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #3
 
 pci:v00008086d000024D7sv00001014sd000002ED*
- ID_MODEL_FROM_DATABASE=xSeries server mainboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #3 (xSeries server mainboard)
+
+pci:v00008086d000024D7sv00001028sd00000168*
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #3 (Precision Workstation 670 Mainboard)
 
 pci:v00008086d000024D7sv00001028sd00000169*
- ID_MODEL_FROM_DATABASE=Precision 470
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #3 (Precision 470)
 
 pci:v00008086d000024D7sv00001028sd0000016C*
- ID_MODEL_FROM_DATABASE=PowerEdge 1850 onboard UHCI
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #3 (PowerEdge 1850 onboard UHCI)
 
 pci:v00008086d000024D7sv00001028sd0000016D*
- ID_MODEL_FROM_DATABASE=PowerEdge 2850 onboard UHCI
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #3 (PowerEdge 2850 onboard UHCI)
 
 pci:v00008086d000024D7sv00001028sd00000170*
- ID_MODEL_FROM_DATABASE=PowerEdge 6850 onboard UHCI
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #3 (PowerEdge 6850 onboard UHCI)
 
 pci:v00008086d000024D7sv00001028sd00000183*
- ID_MODEL_FROM_DATABASE=PowerEdge 1800
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #3 (PowerEdge 1800)
 
 pci:v00008086d000024D7sv0000103Csd0000006A*
- ID_MODEL_FROM_DATABASE=NX9500
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #3 (NX9500)
 
 pci:v00008086d000024D7sv0000103Csd000012BC*
- ID_MODEL_FROM_DATABASE=d530 CMT (DG746A)
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #3 (d530 CMT (DG746A))
 
 pci:v00008086d000024D7sv00001043sd000080A6*
- ID_MODEL_FROM_DATABASE=P4P800/P5P800 series motherboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #3 (P4P800/P5P800 series motherboard)
 
 pci:v00008086d000024D7sv00001458sd000024D2*
- ID_MODEL_FROM_DATABASE=GA-8IPE1000 Pro2 motherboard (865PE)
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #3 (GA-8IPE1000 Pro2 motherboard (865PE))
 
 pci:v00008086d000024D7sv00001462sd00007280*
- ID_MODEL_FROM_DATABASE=865PE Neo2 (MS-6728)
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #3 (865PE Neo2 (MS-6728))
 
 pci:v00008086d000024D7sv00001462sd00007650*
- ID_MODEL_FROM_DATABASE=Hetis 865GV-E (MS-7065)
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #3 (Hetis 865GV-E (MS-7065))
 
 pci:v00008086d000024D7sv00001565sd00003101*
- ID_MODEL_FROM_DATABASE=P4TSV Motherboard (865G)
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #3 (P4TSV Motherboard (865G))
 
 pci:v00008086d000024D7sv000015D9sd00004580*
- ID_MODEL_FROM_DATABASE=P4SCE Mainboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #3 (P4SCE Mainboard)
 
 pci:v00008086d000024D7sv00001734sd0000101C*
- ID_MODEL_FROM_DATABASE=PRIMERGY RX/TX S2 series onboard UHCI
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #3 (PRIMERGY RX/TX S2 series onboard UHCI)
 
 pci:v00008086d000024D7sv00008086sd00003427*
- ID_MODEL_FROM_DATABASE=S875WP1-E mainboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #3 (S875WP1-E mainboard)
 
 pci:v00008086d000024D7sv00008086sd00004246*
- ID_MODEL_FROM_DATABASE=Desktop Board D865GBF
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #3 (Desktop Board D865GBF)
 
 pci:v00008086d000024D7sv00008086sd00004C43*
- ID_MODEL_FROM_DATABASE=Desktop Board D865GLC
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #3 (Desktop Board D865GLC)
 
 pci:v00008086d000024D7sv00008086sd0000524C*
- ID_MODEL_FROM_DATABASE=D865PERL mainboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #3 (D865PERL mainboard)
 
 pci:v00008086d000024DB*
  ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) IDE Controller
 
 pci:v00008086d000024DBsv00001014sd000002DD*
- ID_MODEL_FROM_DATABASE=eServer xSeries server mainboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) IDE Controller (eServer xSeries server mainboard)
 
 pci:v00008086d000024DBsv00001014sd000002ED*
- ID_MODEL_FROM_DATABASE=eServer xSeries server mainboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) IDE Controller (eServer xSeries server mainboard)
+
+pci:v00008086d000024DBsv00001028sd00000168*
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) IDE Controller (Precision Workstation 670 Mainboard)
 
 pci:v00008086d000024DBsv00001028sd00000169*
- ID_MODEL_FROM_DATABASE=Precision 470
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) IDE Controller (Precision 470)
 
 pci:v00008086d000024DBsv00001028sd0000016C*
- ID_MODEL_FROM_DATABASE=PowerEdge 1850 IDE Controller
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) IDE Controller (PowerEdge 1850 IDE Controller)
 
 pci:v00008086d000024DBsv00001028sd0000016D*
- ID_MODEL_FROM_DATABASE=PowerEdge 2850 IDE Controller
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) IDE Controller (PowerEdge 2850 IDE Controller)
 
 pci:v00008086d000024DBsv00001028sd00000170*
- ID_MODEL_FROM_DATABASE=PowerEdge 6850 IDE Controller
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) IDE Controller (PowerEdge 6850 IDE Controller)
 
 pci:v00008086d000024DBsv00001028sd0000019A*
- ID_MODEL_FROM_DATABASE=PowerEdge SC1425
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) IDE Controller (PowerEdge SC1425)
 
 pci:v00008086d000024DBsv0000103Csd0000006A*
- ID_MODEL_FROM_DATABASE=NX9500
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) IDE Controller (NX9500)
 
 pci:v00008086d000024DBsv0000103Csd000012BC*
- ID_MODEL_FROM_DATABASE=d530 CMT (DG746A)
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) IDE Controller (d530 CMT (DG746A))
 
 pci:v00008086d000024DBsv00001043sd000080A6*
- ID_MODEL_FROM_DATABASE=P4P800/P5P800 series motherboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) IDE Controller (P4P800/P5P800 series motherboard)
 
 pci:v00008086d000024DBsv00001458sd000024D2*
- ID_MODEL_FROM_DATABASE=GA-8IPE1000 Pro2 motherboard (865PE)
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) IDE Controller (GA-8IPE1000 Pro2 motherboard (865PE))
 
 pci:v00008086d000024DBsv00001462sd00007280*
- ID_MODEL_FROM_DATABASE=865PE Neo2 (MS-6728)
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) IDE Controller (865PE Neo2 (MS-6728))
 
 pci:v00008086d000024DBsv00001462sd00007580*
- ID_MODEL_FROM_DATABASE=MSI 875P
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) IDE Controller (MSI 875P)
 
 pci:v00008086d000024DBsv00001462sd00007650*
- ID_MODEL_FROM_DATABASE=Hetis 865GV-E (MS-7065)
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) IDE Controller (Hetis 865GV-E (MS-7065))
 
 pci:v00008086d000024DBsv00001565sd00003101*
- ID_MODEL_FROM_DATABASE=P4TSV Motherboard (865G)
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) IDE Controller (P4TSV Motherboard (865G))
 
 pci:v00008086d000024DBsv000015D9sd00004580*
- ID_MODEL_FROM_DATABASE=P4SCE Mainboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) IDE Controller (P4SCE Mainboard)
 
 pci:v00008086d000024DBsv00001734sd0000101C*
- ID_MODEL_FROM_DATABASE=PRIMERGY RX/TX S2 series onboard IDE
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) IDE Controller (PRIMERGY RX/TX S2 series onboard IDE)
 
 pci:v00008086d000024DBsv00008086sd000024DB*
- ID_MODEL_FROM_DATABASE=P4C800 Mainboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) IDE Controller (P4C800 Mainboard)
 
 pci:v00008086d000024DBsv00008086sd00003427*
- ID_MODEL_FROM_DATABASE=S875WP1-E mainboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) IDE Controller (S875WP1-E mainboard)
 
 pci:v00008086d000024DBsv00008086sd00004246*
- ID_MODEL_FROM_DATABASE=Desktop Board D865GBF
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) IDE Controller (Desktop Board D865GBF)
 
 pci:v00008086d000024DBsv00008086sd00004C43*
- ID_MODEL_FROM_DATABASE=Desktop Board D865GLC
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) IDE Controller (Desktop Board D865GLC)
 
 pci:v00008086d000024DBsv00008086sd0000524C*
- ID_MODEL_FROM_DATABASE=D865PERL mainboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) IDE Controller (D865PERL mainboard)
 
 pci:v00008086d000024DC*
  ID_MODEL_FROM_DATABASE=82801EB (ICH5) LPC Interface Bridge
@@ -61107,121 +62853,142 @@ pci:v00008086d000024DD*
  ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB2 EHCI Controller
 
 pci:v00008086d000024DDsv00001014sd000002DD*
- ID_MODEL_FROM_DATABASE=eServer xSeries server mainboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB2 EHCI Controller (eServer xSeries server mainboard)
 
 pci:v00008086d000024DDsv00001014sd000002ED*
- ID_MODEL_FROM_DATABASE=eServer xSeries server mainboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB2 EHCI Controller (eServer xSeries server mainboard)
+
+pci:v00008086d000024DDsv00001028sd00000168*
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB2 EHCI Controller (Precision Workstation 670 Mainboard)
 
 pci:v00008086d000024DDsv00001028sd00000169*
- ID_MODEL_FROM_DATABASE=Precision 470
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB2 EHCI Controller (Precision 470)
 
 pci:v00008086d000024DDsv00001028sd0000016C*
- ID_MODEL_FROM_DATABASE=PowerEdge 1850 onboard EHCI
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB2 EHCI Controller (PowerEdge 1850 onboard EHCI)
 
 pci:v00008086d000024DDsv00001028sd0000016D*
- ID_MODEL_FROM_DATABASE=PowerEdge 2850 onboard EHCI
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB2 EHCI Controller (PowerEdge 2850 onboard EHCI)
 
 pci:v00008086d000024DDsv00001028sd00000170*
- ID_MODEL_FROM_DATABASE=PowerEdge 6850 onboard EHCI
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB2 EHCI Controller (PowerEdge 6850 onboard EHCI)
 
 pci:v00008086d000024DDsv00001028sd00000183*
- ID_MODEL_FROM_DATABASE=PowerEdge 1800
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB2 EHCI Controller (PowerEdge 1800)
 
 pci:v00008086d000024DDsv00001028sd0000019A*
- ID_MODEL_FROM_DATABASE=PowerEdge SC1425
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB2 EHCI Controller (PowerEdge SC1425)
 
 pci:v00008086d000024DDsv0000103Csd0000006A*
- ID_MODEL_FROM_DATABASE=NX9500
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB2 EHCI Controller (NX9500)
 
 pci:v00008086d000024DDsv0000103Csd000012BC*
- ID_MODEL_FROM_DATABASE=d530 CMT (DG746A)
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB2 EHCI Controller (d530 CMT (DG746A))
 
 pci:v00008086d000024DDsv0000103Csd00003208*
- ID_MODEL_FROM_DATABASE=ProLiant DL140 G2
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB2 EHCI Controller (ProLiant DL140 G2)
 
 pci:v00008086d000024DDsv00001043sd000080A6*
- ID_MODEL_FROM_DATABASE=P4P800/P5P800 series motherboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB2 EHCI Controller (P4P800/P5P800 series motherboard)
 
 pci:v00008086d000024DDsv00001458sd00005006*
- ID_MODEL_FROM_DATABASE=GA-8IPE1000 Pro2 motherboard (865PE)
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB2 EHCI Controller (GA-8IPE1000 Pro2 motherboard (865PE))
 
 pci:v00008086d000024DDsv00001462sd00007280*
- ID_MODEL_FROM_DATABASE=865PE Neo2 (MS-6728)
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB2 EHCI Controller (865PE Neo2 (MS-6728))
 
 pci:v00008086d000024DDsv00001462sd00007650*
- ID_MODEL_FROM_DATABASE=Hetis 865GV-E (MS-7065)
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB2 EHCI Controller (Hetis 865GV-E (MS-7065))
 
 pci:v00008086d000024DDsv00008086sd00003427*
- ID_MODEL_FROM_DATABASE=S875WP1-E mainboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB2 EHCI Controller (S875WP1-E mainboard)
 
 pci:v00008086d000024DDsv00008086sd00004246*
- ID_MODEL_FROM_DATABASE=Desktop Board D865GBF
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB2 EHCI Controller (Desktop Board D865GBF)
 
 pci:v00008086d000024DDsv00008086sd00004C43*
- ID_MODEL_FROM_DATABASE=Desktop Board D865GLC
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB2 EHCI Controller (Desktop Board D865GLC)
 
 pci:v00008086d000024DDsv00008086sd0000524C*
- ID_MODEL_FROM_DATABASE=D865PERL mainboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB2 EHCI Controller (D865PERL mainboard)
 
 pci:v00008086d000024DE*
  ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #4
 
 pci:v00008086d000024DEsv00001014sd000002ED*
- ID_MODEL_FROM_DATABASE=xSeries server mainboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #4 (xSeries server mainboard)
+
+pci:v00008086d000024DEsv00001028sd00000168*
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #4 (Precision Workstation 670 Mainboard)
 
 pci:v00008086d000024DEsv00001028sd00000169*
- ID_MODEL_FROM_DATABASE=Precision 470
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #4 (Precision 470)
 
 pci:v00008086d000024DEsv00001043sd000080A6*
- ID_MODEL_FROM_DATABASE=P4P800/P5P800 series motherboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #4 (P4P800/P5P800 series motherboard)
 
 pci:v00008086d000024DEsv00001458sd000024D2*
- ID_MODEL_FROM_DATABASE=GA-8IPE1000 Pro2 motherboard (865PE)
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #4 (GA-8IPE1000 Pro2 motherboard (865PE))
 
 pci:v00008086d000024DEsv00001462sd00007280*
- ID_MODEL_FROM_DATABASE=865PE Neo2 (MS-6728)
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #4 (865PE Neo2 (MS-6728))
 
 pci:v00008086d000024DEsv00001462sd00007650*
- ID_MODEL_FROM_DATABASE=Hetis 865GV-E (MS-7065)
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #4 (Hetis 865GV-E (MS-7065))
 
 pci:v00008086d000024DEsv00001565sd00003101*
- ID_MODEL_FROM_DATABASE=P4TSV Motherboard (865G)
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #4 (P4TSV Motherboard (865G))
 
 pci:v00008086d000024DEsv000015D9sd00004580*
- ID_MODEL_FROM_DATABASE=P4SCE Mainboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #4 (P4SCE Mainboard)
 
 pci:v00008086d000024DEsv00001734sd0000101C*
- ID_MODEL_FROM_DATABASE=PRIMERGY RX/TX S2 series onboard UHCI
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #4 (PRIMERGY RX/TX S2 series onboard UHCI)
 
 pci:v00008086d000024DEsv00008086sd00003427*
- ID_MODEL_FROM_DATABASE=S875WP1-E mainboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #4 (S875WP1-E mainboard)
 
 pci:v00008086d000024DEsv00008086sd00004246*
- ID_MODEL_FROM_DATABASE=Desktop Board D865GBF
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #4 (Desktop Board D865GBF)
 
 pci:v00008086d000024DEsv00008086sd00004C43*
- ID_MODEL_FROM_DATABASE=Desktop Board D865GLC
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #4 (Desktop Board D865GLC)
 
 pci:v00008086d000024DEsv00008086sd0000524C*
- ID_MODEL_FROM_DATABASE=D865PERL mainboard
+ ID_MODEL_FROM_DATABASE=82801EB/ER (ICH5/ICH5R) USB UHCI Controller #4 (D865PERL mainboard)
 
 pci:v00008086d000024DF*
  ID_MODEL_FROM_DATABASE=82801ER (ICH5R) SATA Controller
 
+pci:v00008086d000024DFsv00001028sd00000168*
+ ID_MODEL_FROM_DATABASE=82801ER (ICH5R) SATA Controller (Precision Workstation 670 Mainboard)
+
+pci:v00008086d000024F3*
+ ID_MODEL_FROM_DATABASE=Wireless 8260
+
+pci:v00008086d000024F3sv00008086sd00000010*
+ ID_MODEL_FROM_DATABASE=Wireless 8260 (Dual Band Wireless-AC 8260)
+
+pci:v00008086d000024F4*
+ ID_MODEL_FROM_DATABASE=Wireless 8260
+
+pci:v00008086d000024F4sv00008086sd00000030*
+ ID_MODEL_FROM_DATABASE=Wireless 8260 (Dual Band Wireless-AC 8260)
+
 pci:v00008086d00002500*
  ID_MODEL_FROM_DATABASE=82820 820 (Camino) Chipset Host Bridge (MCH)
 
 pci:v00008086d00002500sv00001028sd00000095*
- ID_MODEL_FROM_DATABASE=Precision Workstation 220 Chipset
+ ID_MODEL_FROM_DATABASE=82820 820 (Camino) Chipset Host Bridge (MCH) (Precision Workstation 220 Chipset)
 
 pci:v00008086d00002500sv00001043sd0000801C*
- ID_MODEL_FROM_DATABASE=P3C-2000 system chipset
+ ID_MODEL_FROM_DATABASE=82820 820 (Camino) Chipset Host Bridge (MCH) (P3C-2000 system chipset)
 
 pci:v00008086d00002501*
  ID_MODEL_FROM_DATABASE=82820 820 (Camino) Chipset Host Bridge (MCH)
 
 pci:v00008086d00002501sv00001043sd0000801C*
- ID_MODEL_FROM_DATABASE=P3C-2000 system chipset
+ ID_MODEL_FROM_DATABASE=82820 820 (Camino) Chipset Host Bridge (MCH) (P3C-2000 system chipset)
 
 pci:v00008086d0000250B*
  ID_MODEL_FROM_DATABASE=82820 820 (Camino) Chipset Host Bridge
@@ -61239,16 +63006,16 @@ pci:v00008086d00002530*
  ID_MODEL_FROM_DATABASE=82850 850 (Tehama) Chipset Host Bridge (MCH)
 
 pci:v00008086d00002530sv00001028sd000000C7*
- ID_MODEL_FROM_DATABASE=Dimension 8100
+ ID_MODEL_FROM_DATABASE=82850 850 (Tehama) Chipset Host Bridge (MCH) (Dimension 8100)
 
 pci:v00008086d00002530sv0000147Bsd00000507*
- ID_MODEL_FROM_DATABASE=TH7II-RAID
+ ID_MODEL_FROM_DATABASE=82850 850 (Tehama) Chipset Host Bridge (MCH) (TH7II-RAID)
 
 pci:v00008086d00002531*
  ID_MODEL_FROM_DATABASE=82860 860 (Wombat) Chipset Host Bridge (MCH)
 
 pci:v00008086d00002531sv00001028sd000000D8*
- ID_MODEL_FROM_DATABASE=Precision 530
+ ID_MODEL_FROM_DATABASE=82860 860 (Wombat) Chipset Host Bridge (MCH) (Precision 530)
 
 pci:v00008086d00002532*
  ID_MODEL_FROM_DATABASE=82850 850 (Tehama) Chipset AGP Bridge
@@ -61263,19 +63030,19 @@ pci:v00008086d00002540*
  ID_MODEL_FROM_DATABASE=E7500 Memory Controller Hub
 
 pci:v00008086d00002540sv000015D9sd00003480*
- ID_MODEL_FROM_DATABASE=P4DP6
+ ID_MODEL_FROM_DATABASE=E7500 Memory Controller Hub (P4DP6)
 
 pci:v00008086d00002541*
  ID_MODEL_FROM_DATABASE=E7500/E7501 Host RASUM Controller
 
 pci:v00008086d00002541sv000015D9sd00003480*
- ID_MODEL_FROM_DATABASE=P4DP6
+ ID_MODEL_FROM_DATABASE=E7500/E7501 Host RASUM Controller (P4DP6)
 
 pci:v00008086d00002541sv00004C53sd00001090*
- ID_MODEL_FROM_DATABASE=Cx9 / Vx9 mainboard
+ ID_MODEL_FROM_DATABASE=E7500/E7501 Host RASUM Controller (Cx9 / Vx9 mainboard)
 
 pci:v00008086d00002541sv00008086sd00003424*
- ID_MODEL_FROM_DATABASE=SE7501HG2 Mainboard
+ ID_MODEL_FROM_DATABASE=E7500/E7501 Host RASUM Controller (SE7501HG2 Mainboard)
 
 pci:v00008086d00002543*
  ID_MODEL_FROM_DATABASE=E7500/E7501 Hub Interface B PCI-to-PCI Bridge
@@ -61284,7 +63051,7 @@ pci:v00008086d00002544*
  ID_MODEL_FROM_DATABASE=E7500/E7501 Hub Interface B RASUM Controller
 
 pci:v00008086d00002544sv00004C53sd00001090*
- ID_MODEL_FROM_DATABASE=Cx9 / Vx9 mainboard
+ ID_MODEL_FROM_DATABASE=E7500/E7501 Hub Interface B RASUM Controller (Cx9 / Vx9 mainboard)
 
 pci:v00008086d00002545*
  ID_MODEL_FROM_DATABASE=E7500/E7501 Hub Interface C PCI-to-PCI Bridge
@@ -61302,10 +63069,10 @@ pci:v00008086d0000254C*
  ID_MODEL_FROM_DATABASE=E7501 Memory Controller Hub
 
 pci:v00008086d0000254Csv00004C53sd00001090*
- ID_MODEL_FROM_DATABASE=Cx9 / Vx9 mainboard
+ ID_MODEL_FROM_DATABASE=E7501 Memory Controller Hub (Cx9 / Vx9 mainboard)
 
 pci:v00008086d0000254Csv00008086sd00003424*
- ID_MODEL_FROM_DATABASE=SE7501HG2 Mainboard
+ ID_MODEL_FROM_DATABASE=E7501 Memory Controller Hub (SE7501HG2 Mainboard)
 
 pci:v00008086d00002550*
  ID_MODEL_FROM_DATABASE=E7505 Memory Controller Hub
@@ -61329,13 +63096,13 @@ pci:v00008086d00002560*
  ID_MODEL_FROM_DATABASE=82845G/GL[Brookdale-G]/GE/PE DRAM Controller/Host-Hub Interface
 
 pci:v00008086d00002560sv00001028sd00000126*
- ID_MODEL_FROM_DATABASE=Optiplex GX260
+ ID_MODEL_FROM_DATABASE=82845G/GL[Brookdale-G]/GE/PE DRAM Controller/Host-Hub Interface (Optiplex GX260)
 
 pci:v00008086d00002560sv00001458sd00002560*
- ID_MODEL_FROM_DATABASE=GA-8PE667 Ultra
+ ID_MODEL_FROM_DATABASE=82845G/GL[Brookdale-G]/GE/PE DRAM Controller/Host-Hub Interface (GA-8PE667 Ultra)
 
 pci:v00008086d00002560sv00001462sd00005800*
- ID_MODEL_FROM_DATABASE=845PE Max (MS-6580)
+ ID_MODEL_FROM_DATABASE=82845G/GL[Brookdale-G]/GE/PE DRAM Controller/Host-Hub Interface (845PE Max (MS-6580))
 
 pci:v00008086d00002561*
  ID_MODEL_FROM_DATABASE=82845G/GL[Brookdale-G]/GE/PE Host-to-AGP Bridge
@@ -61344,31 +63111,31 @@ pci:v00008086d00002562*
  ID_MODEL_FROM_DATABASE=82845G/GL[Brookdale-G]/GE Chipset Integrated Graphics Device
 
 pci:v00008086d00002562sv00000E11sd000000B9*
- ID_MODEL_FROM_DATABASE=Evo D510 SFF
+ ID_MODEL_FROM_DATABASE=82845G/GL[Brookdale-G]/GE Chipset Integrated Graphics Device (Evo D510 SFF)
 
 pci:v00008086d00002562sv00001014sd00000267*
- ID_MODEL_FROM_DATABASE=NetVista A30p
+ ID_MODEL_FROM_DATABASE=82845G/GL[Brookdale-G]/GE Chipset Integrated Graphics Device (NetVista A30p)
 
 pci:v00008086d00002562sv00001734sd00001003*
- ID_MODEL_FROM_DATABASE=D1521 Mainboard (Fujitsu-Siemens)
+ ID_MODEL_FROM_DATABASE=82845G/GL[Brookdale-G]/GE Chipset Integrated Graphics Device (D1521 Mainboard (Fujitsu-Siemens))
 
 pci:v00008086d00002562sv00001734sd00001004*
- ID_MODEL_FROM_DATABASE=D1451 Mainboard (SCENIC N300, i845GV)
+ ID_MODEL_FROM_DATABASE=82845G/GL[Brookdale-G]/GE Chipset Integrated Graphics Device (D1451 Mainboard (SCENIC N300, i845GV))
 
 pci:v00008086d00002570*
  ID_MODEL_FROM_DATABASE=82865G/PE/P DRAM Controller/Host-Hub Interface
 
 pci:v00008086d00002570sv0000103Csd0000006A*
- ID_MODEL_FROM_DATABASE=NX9500
+ ID_MODEL_FROM_DATABASE=82865G/PE/P DRAM Controller/Host-Hub Interface (NX9500)
 
 pci:v00008086d00002570sv0000103Csd000012BC*
- ID_MODEL_FROM_DATABASE=d330 uT
+ ID_MODEL_FROM_DATABASE=82865G/PE/P DRAM Controller/Host-Hub Interface (d330 uT)
 
 pci:v00008086d00002570sv00001043sd000080F2*
- ID_MODEL_FROM_DATABASE=P4P800/P5P800 series motherboard
+ ID_MODEL_FROM_DATABASE=82865G/PE/P DRAM Controller/Host-Hub Interface (P4P800/P5P800 series motherboard)
 
 pci:v00008086d00002570sv00001458sd00002570*
- ID_MODEL_FROM_DATABASE=GA-8IPE1000 Pro2 motherboard (865PE)
+ ID_MODEL_FROM_DATABASE=82865G/PE/P DRAM Controller/Host-Hub Interface (GA-8IPE1000 Pro2 motherboard (865PE))
 
 pci:v00008086d00002571*
  ID_MODEL_FROM_DATABASE=82865G/PE/P AGP Bridge
@@ -61377,25 +63144,25 @@ pci:v00008086d00002572*
  ID_MODEL_FROM_DATABASE=82865G Integrated Graphics Controller
 
 pci:v00008086d00002572sv00001028sd0000019D*
- ID_MODEL_FROM_DATABASE=Dimension 3000
+ ID_MODEL_FROM_DATABASE=82865G Integrated Graphics Controller (Dimension 3000)
 
 pci:v00008086d00002572sv0000103Csd000012BC*
- ID_MODEL_FROM_DATABASE=D530 sff(dc578av)
+ ID_MODEL_FROM_DATABASE=82865G Integrated Graphics Controller (D530 sff(dc578av))
 
 pci:v00008086d00002572sv00001043sd000080A5*
- ID_MODEL_FROM_DATABASE=P5P800-MX Mainboard
+ ID_MODEL_FROM_DATABASE=82865G Integrated Graphics Controller (P5P800-MX Mainboard)
 
 pci:v00008086d00002572sv00001462sd00007650*
- ID_MODEL_FROM_DATABASE=Hetis 865GV-E (MS-7065)
+ ID_MODEL_FROM_DATABASE=82865G Integrated Graphics Controller (Hetis 865GV-E (MS-7065))
 
 pci:v00008086d00002572sv00001734sd0000101B*
- ID_MODEL_FROM_DATABASE=Fujitsu-Siemens Scenic E300 i865GV
+ ID_MODEL_FROM_DATABASE=82865G Integrated Graphics Controller (Fujitsu-Siemens Scenic E300 i865GV)
 
 pci:v00008086d00002572sv00008086sd00004246*
- ID_MODEL_FROM_DATABASE=Desktop Board D865GBF
+ ID_MODEL_FROM_DATABASE=82865G Integrated Graphics Controller (Desktop Board D865GBF)
 
 pci:v00008086d00002572sv00008086sd00004C43*
- ID_MODEL_FROM_DATABASE=Desktop Board D865GLC
+ ID_MODEL_FROM_DATABASE=82865G Integrated Graphics Controller (Desktop Board D865GLC)
 
 pci:v00008086d00002573*
  ID_MODEL_FROM_DATABASE=82865G/PE/P PCI to CSA Bridge
@@ -61407,13 +63174,13 @@ pci:v00008086d00002578*
  ID_MODEL_FROM_DATABASE=82875P/E7210 Memory Controller Hub
 
 pci:v00008086d00002578sv00001458sd00002578*
- ID_MODEL_FROM_DATABASE=GA-8KNXP motherboard (875P)
+ ID_MODEL_FROM_DATABASE=82875P/E7210 Memory Controller Hub (GA-8KNXP motherboard (875P))
 
 pci:v00008086d00002578sv00001462sd00007580*
- ID_MODEL_FROM_DATABASE=MS-6758 (875P Neo)
+ ID_MODEL_FROM_DATABASE=82875P/E7210 Memory Controller Hub (MS-6758 (875P Neo))
 
 pci:v00008086d00002578sv000015D9sd00004580*
- ID_MODEL_FROM_DATABASE=P4SCE Motherboard
+ ID_MODEL_FROM_DATABASE=82875P/E7210 Memory Controller Hub (P4SCE Motherboard)
 
 pci:v00008086d00002579*
  ID_MODEL_FROM_DATABASE=82875P Processor to AGP Controller
@@ -61428,13 +63195,13 @@ pci:v00008086d00002580*
  ID_MODEL_FROM_DATABASE=82915G/P/GV/GL/PL/910GL Memory Controller Hub
 
 pci:v00008086d00002580sv00001458sd00002580*
- ID_MODEL_FROM_DATABASE=GA-8I915ME-G Mainboard
+ ID_MODEL_FROM_DATABASE=82915G/P/GV/GL/PL/910GL Memory Controller Hub (GA-8I915ME-G Mainboard)
 
 pci:v00008086d00002580sv00001462sd00007028*
- ID_MODEL_FROM_DATABASE=915P/G Neo2
+ ID_MODEL_FROM_DATABASE=82915G/P/GV/GL/PL/910GL Memory Controller Hub (915P/G Neo2)
 
 pci:v00008086d00002580sv00001734sd0000105B*
- ID_MODEL_FROM_DATABASE=Scenic W620
+ ID_MODEL_FROM_DATABASE=82915G/P/GV/GL/PL/910GL Memory Controller Hub (Scenic W620)
 
 pci:v00008086d00002581*
  ID_MODEL_FROM_DATABASE=82915G/P/GV/GL/PL/910GL PCI Express Root Port
@@ -61443,28 +63210,28 @@ pci:v00008086d00002582*
  ID_MODEL_FROM_DATABASE=82915G/GV/910GL Integrated Graphics Controller
 
 pci:v00008086d00002582sv00001028sd00001079*
- ID_MODEL_FROM_DATABASE=Optiplex GX280
+ ID_MODEL_FROM_DATABASE=82915G/GV/910GL Integrated Graphics Controller (Optiplex GX280)
 
 pci:v00008086d00002582sv0000103Csd00003006*
- ID_MODEL_FROM_DATABASE=DC7100 SFF(DX878AV)
+ ID_MODEL_FROM_DATABASE=82915G/GV/910GL Integrated Graphics Controller (DC7100 SFF(DX878AV))
 
 pci:v00008086d00002582sv00001043sd00002582*
- ID_MODEL_FROM_DATABASE=P5GD1-VW Mainboard
+ ID_MODEL_FROM_DATABASE=82915G/GV/910GL Integrated Graphics Controller (P5GD1-VW Mainboard)
 
 pci:v00008086d00002582sv00001458sd00002582*
- ID_MODEL_FROM_DATABASE=GA-8I915ME-G Mainboard
+ ID_MODEL_FROM_DATABASE=82915G/GV/910GL Integrated Graphics Controller (GA-8I915ME-G Mainboard)
 
 pci:v00008086d00002582sv00001734sd0000105B*
- ID_MODEL_FROM_DATABASE=Scenic W620
+ ID_MODEL_FROM_DATABASE=82915G/GV/910GL Integrated Graphics Controller (Scenic W620)
 
 pci:v00008086d00002582sv00001849sd00002582*
- ID_MODEL_FROM_DATABASE=ASRock P4Dual-915GL
+ ID_MODEL_FROM_DATABASE=82915G/GV/910GL Integrated Graphics Controller (ASRock P4Dual-915GL)
 
 pci:v00008086d00002584*
  ID_MODEL_FROM_DATABASE=82925X/XE Memory Controller Hub
 
 pci:v00008086d00002584sv00001028sd00000177*
- ID_MODEL_FROM_DATABASE=Dimension 8400
+ ID_MODEL_FROM_DATABASE=82925X/XE Memory Controller Hub (Dimension 8400)
 
 pci:v00008086d00002585*
  ID_MODEL_FROM_DATABASE=82925X/XE PCI Express Root Port
@@ -61482,58 +63249,58 @@ pci:v00008086d00002590*
  ID_MODEL_FROM_DATABASE=Mobile 915GM/PM/GMS/910GML Express Processor to DRAM Controller
 
 pci:v00008086d00002590sv00001014sd00000575*
- ID_MODEL_FROM_DATABASE=ThinkPad Z60t
+ ID_MODEL_FROM_DATABASE=Mobile 915GM/PM/GMS/910GML Express Processor to DRAM Controller (ThinkPad Z60t)
 
 pci:v00008086d00002590sv00001028sd00000182*
- ID_MODEL_FROM_DATABASE=Dell Latitude C610
+ ID_MODEL_FROM_DATABASE=Mobile 915GM/PM/GMS/910GML Express Processor to DRAM Controller (Dell Latitude C610)
 
 pci:v00008086d00002590sv0000103Csd00000934*
- ID_MODEL_FROM_DATABASE=Compaq nw8240/nx8220
+ ID_MODEL_FROM_DATABASE=Mobile 915GM/PM/GMS/910GML Express Processor to DRAM Controller (Compaq nw8240/nx8220)
 
 pci:v00008086d00002590sv0000103Csd0000099C*
- ID_MODEL_FROM_DATABASE=NX6110/NC6120
+ ID_MODEL_FROM_DATABASE=Mobile 915GM/PM/GMS/910GML Express Processor to DRAM Controller (NX6110/NC6120)
 
 pci:v00008086d00002590sv0000104Dsd000081B7*
- ID_MODEL_FROM_DATABASE=Vaio VGN-S3XP
+ ID_MODEL_FROM_DATABASE=Mobile 915GM/PM/GMS/910GML Express Processor to DRAM Controller (Vaio VGN-S3XP)
 
 pci:v00008086d00002590sv0000A304sd000081B7*
- ID_MODEL_FROM_DATABASE=Vaio VGN-S3XP
+ ID_MODEL_FROM_DATABASE=Mobile 915GM/PM/GMS/910GML Express Processor to DRAM Controller (Vaio VGN-S3XP)
 
 pci:v00008086d00002590sv0000E4BFsd00000CCD*
- ID_MODEL_FROM_DATABASE=CCD-CALYPSO
+ ID_MODEL_FROM_DATABASE=Mobile 915GM/PM/GMS/910GML Express Processor to DRAM Controller (CCD-CALYPSO)
 
 pci:v00008086d00002590sv0000E4BFsd00000CD3*
- ID_MODEL_FROM_DATABASE=CD3-JIVE
+ ID_MODEL_FROM_DATABASE=Mobile 915GM/PM/GMS/910GML Express Processor to DRAM Controller (CD3-JIVE)
 
 pci:v00008086d00002590sv0000E4BFsd000058B1*
- ID_MODEL_FROM_DATABASE=XB1
+ ID_MODEL_FROM_DATABASE=Mobile 915GM/PM/GMS/910GML Express Processor to DRAM Controller (XB1)
 
 pci:v00008086d00002591*
  ID_MODEL_FROM_DATABASE=Mobile 915GM/PM Express PCI Express Root Port
 
 pci:v00008086d00002591sv0000103Csd00000934*
- ID_MODEL_FROM_DATABASE=HP Compaq nw8240 Mobile Workstation
+ ID_MODEL_FROM_DATABASE=Mobile 915GM/PM Express PCI Express Root Port (HP Compaq nw8240 Mobile Workstation)
 
 pci:v00008086d00002592*
  ID_MODEL_FROM_DATABASE=Mobile 915GM/GMS/910GML Express Graphics Controller
 
 pci:v00008086d00002592sv0000103Csd0000099C*
- ID_MODEL_FROM_DATABASE=NX6110/NC6120
+ ID_MODEL_FROM_DATABASE=Mobile 915GM/GMS/910GML Express Graphics Controller (NX6110/NC6120)
 
 pci:v00008086d00002592sv0000103Csd0000308A*
- ID_MODEL_FROM_DATABASE=NC6220
+ ID_MODEL_FROM_DATABASE=Mobile 915GM/GMS/910GML Express Graphics Controller (NC6220)
 
 pci:v00008086d00002592sv00001043sd00001881*
- ID_MODEL_FROM_DATABASE=GMA 900 915GM Integrated Graphics
+ ID_MODEL_FROM_DATABASE=Mobile 915GM/GMS/910GML Express Graphics Controller (GMA 900 915GM Integrated Graphics)
 
 pci:v00008086d00002592sv0000E4BFsd00000CCD*
- ID_MODEL_FROM_DATABASE=CCD-CALYPSO
+ ID_MODEL_FROM_DATABASE=Mobile 915GM/GMS/910GML Express Graphics Controller (CCD-CALYPSO)
 
 pci:v00008086d00002592sv0000E4BFsd00000CD3*
- ID_MODEL_FROM_DATABASE=CD3-JIVE
+ ID_MODEL_FROM_DATABASE=Mobile 915GM/GMS/910GML Express Graphics Controller (CD3-JIVE)
 
 pci:v00008086d00002592sv0000E4BFsd000058B1*
- ID_MODEL_FROM_DATABASE=XB1
+ ID_MODEL_FROM_DATABASE=Mobile 915GM/GMS/910GML Express Graphics Controller (XB1)
 
 pci:v00008086d000025A1*
  ID_MODEL_FROM_DATABASE=6300ESB LPC Interface Controller
@@ -61542,79 +63309,79 @@ pci:v00008086d000025A2*
  ID_MODEL_FROM_DATABASE=6300ESB PATA Storage Controller
 
 pci:v00008086d000025A2sv00001734sd00001073*
- ID_MODEL_FROM_DATABASE=Primergy Econel 200 D2020 mainboard
+ ID_MODEL_FROM_DATABASE=6300ESB PATA Storage Controller (Primergy Econel 200 D2020 mainboard)
 
 pci:v00008086d000025A2sv00001775sd000010D0*
- ID_MODEL_FROM_DATABASE=V5D Single Board Computer IDE
+ ID_MODEL_FROM_DATABASE=6300ESB PATA Storage Controller (V5D Single Board Computer IDE)
 
 pci:v00008086d000025A2sv00001775sd00001100*
- ID_MODEL_FROM_DATABASE=CR11/VR11 Single Board Computer
+ ID_MODEL_FROM_DATABASE=6300ESB PATA Storage Controller (CR11/VR11 Single Board Computer)
 
 pci:v00008086d000025A2sv00001775sd0000CE90*
- ID_MODEL_FROM_DATABASE=CE9
+ ID_MODEL_FROM_DATABASE=6300ESB PATA Storage Controller (CE9)
 
 pci:v00008086d000025A2sv00004C53sd000010B0*
- ID_MODEL_FROM_DATABASE=CL9 mainboard
+ ID_MODEL_FROM_DATABASE=6300ESB PATA Storage Controller (CL9 mainboard)
 
 pci:v00008086d000025A2sv00004C53sd000010E0*
- ID_MODEL_FROM_DATABASE=PSL09 PrPMC
+ ID_MODEL_FROM_DATABASE=6300ESB PATA Storage Controller (PSL09 PrPMC)
 
 pci:v00008086d000025A3*
  ID_MODEL_FROM_DATABASE=6300ESB SATA Storage Controller
 
 pci:v00008086d000025A3sv00001734sd00001073*
- ID_MODEL_FROM_DATABASE=Primergy Econel 200 D2020 mainboard
+ ID_MODEL_FROM_DATABASE=6300ESB SATA Storage Controller (Primergy Econel 200 D2020 mainboard)
 
 pci:v00008086d000025A3sv00001775sd00001100*
- ID_MODEL_FROM_DATABASE=CR11/VR11 Single Board Computer
+ ID_MODEL_FROM_DATABASE=6300ESB SATA Storage Controller (CR11/VR11 Single Board Computer)
 
 pci:v00008086d000025A3sv00001775sd0000CE90*
- ID_MODEL_FROM_DATABASE=CE9
+ ID_MODEL_FROM_DATABASE=6300ESB SATA Storage Controller (CE9)
 
 pci:v00008086d000025A3sv00004C53sd000010B0*
- ID_MODEL_FROM_DATABASE=CL9 mainboard
+ ID_MODEL_FROM_DATABASE=6300ESB SATA Storage Controller (CL9 mainboard)
 
 pci:v00008086d000025A3sv00004C53sd000010D0*
- ID_MODEL_FROM_DATABASE=Telum ASLP10 Processor AMC
+ ID_MODEL_FROM_DATABASE=6300ESB SATA Storage Controller (Telum ASLP10 Processor AMC)
 
 pci:v00008086d000025A3sv00004C53sd000010E0*
- ID_MODEL_FROM_DATABASE=PSL09 PrPMC
+ ID_MODEL_FROM_DATABASE=6300ESB SATA Storage Controller (PSL09 PrPMC)
 
 pci:v00008086d000025A4*
  ID_MODEL_FROM_DATABASE=6300ESB SMBus Controller
 
 pci:v00008086d000025A4sv00001734sd00001073*
- ID_MODEL_FROM_DATABASE=Primergy Econel 200 D2020 mainboard
+ ID_MODEL_FROM_DATABASE=6300ESB SMBus Controller (Primergy Econel 200 D2020 mainboard)
 
 pci:v00008086d000025A4sv00001775sd000010D0*
- ID_MODEL_FROM_DATABASE=V5D Single Board Computer
+ ID_MODEL_FROM_DATABASE=6300ESB SMBus Controller (V5D Single Board Computer)
 
 pci:v00008086d000025A4sv00001775sd00001100*
- ID_MODEL_FROM_DATABASE=CR11/VR11 Single Board Computer
+ ID_MODEL_FROM_DATABASE=6300ESB SMBus Controller (CR11/VR11 Single Board Computer)
 
 pci:v00008086d000025A4sv00001775sd0000CE90*
- ID_MODEL_FROM_DATABASE=CE9
+ ID_MODEL_FROM_DATABASE=6300ESB SMBus Controller (CE9)
 
 pci:v00008086d000025A4sv00004C53sd000010B0*
- ID_MODEL_FROM_DATABASE=CL9 mainboard
+ ID_MODEL_FROM_DATABASE=6300ESB SMBus Controller (CL9 mainboard)
 
 pci:v00008086d000025A4sv00004C53sd000010D0*
- ID_MODEL_FROM_DATABASE=Telum ASLP10 Processor AMC
+ ID_MODEL_FROM_DATABASE=6300ESB SMBus Controller (Telum ASLP10 Processor AMC)
 
 pci:v00008086d000025A4sv00004C53sd000010E0*
- ID_MODEL_FROM_DATABASE=PSL09 PrPMC
+ ID_MODEL_FROM_DATABASE=6300ESB SMBus Controller (PSL09 PrPMC)
 
 pci:v00008086d000025A6*
  ID_MODEL_FROM_DATABASE=6300ESB AC'97 Audio Controller
 
 pci:v00008086d000025A6sv00001775sd00001100*
- ID_MODEL_FROM_DATABASE=CR11/VR11 Single Board Computer
+ ID_MODEL_FROM_DATABASE=6300ESB AC'97 Audio Controller (CR11/VR11 Single Board Computer)
 
 pci:v00008086d000025A6sv00001775sd0000CE90*
- ID_MODEL_FROM_DATABASE=CE9
+ ID_MODEL_FROM_DATABASE=6300ESB AC'97 Audio Controller (CE9)
 
 pci:v00008086d000025A6sv00004C53sd000010B0*
- ID_MODEL_FROM_DATABASE=CL9 mainboard
+ ID_MODEL_FROM_DATABASE=6300ESB AC'97 Audio Controller (CL9 mainboard)
 
 pci:v00008086d000025A7*
  ID_MODEL_FROM_DATABASE=6300ESB AC'97 Modem Controller
@@ -61623,118 +63390,121 @@ pci:v00008086d000025A9*
  ID_MODEL_FROM_DATABASE=6300ESB USB Universal Host Controller
 
 pci:v00008086d000025A9sv00001734sd00001073*
- ID_MODEL_FROM_DATABASE=Primergy Econel 200 D2020 mainboard
+ ID_MODEL_FROM_DATABASE=6300ESB USB Universal Host Controller (Primergy Econel 200 D2020 mainboard)
 
 pci:v00008086d000025A9sv00001775sd000010D0*
- ID_MODEL_FROM_DATABASE=V5D Single Board Computer USB
+ ID_MODEL_FROM_DATABASE=6300ESB USB Universal Host Controller (V5D Single Board Computer USB)
 
 pci:v00008086d000025A9sv00001775sd00001100*
- ID_MODEL_FROM_DATABASE=CR11/VR11 Single Board Computer
+ ID_MODEL_FROM_DATABASE=6300ESB USB Universal Host Controller (CR11/VR11 Single Board Computer)
 
 pci:v00008086d000025A9sv00001775sd0000CE90*
- ID_MODEL_FROM_DATABASE=CE9
+ ID_MODEL_FROM_DATABASE=6300ESB USB Universal Host Controller (CE9)
 
 pci:v00008086d000025A9sv00004C53sd000010B0*
- ID_MODEL_FROM_DATABASE=CL9 mainboard
+ ID_MODEL_FROM_DATABASE=6300ESB USB Universal Host Controller (CL9 mainboard)
 
 pci:v00008086d000025A9sv00004C53sd000010D0*
- ID_MODEL_FROM_DATABASE=Telum ASLP10 Processor AMC
+ ID_MODEL_FROM_DATABASE=6300ESB USB Universal Host Controller (Telum ASLP10 Processor AMC)
 
 pci:v00008086d000025A9sv00004C53sd000010E0*
- ID_MODEL_FROM_DATABASE=PSL09 PrPMC
+ ID_MODEL_FROM_DATABASE=6300ESB USB Universal Host Controller (PSL09 PrPMC)
 
 pci:v00008086d000025AA*
  ID_MODEL_FROM_DATABASE=6300ESB USB Universal Host Controller
 
 pci:v00008086d000025AAsv00001734sd00001073*
- ID_MODEL_FROM_DATABASE=Primergy Econel 200 D2020 mainboard
+ ID_MODEL_FROM_DATABASE=6300ESB USB Universal Host Controller (Primergy Econel 200 D2020 mainboard)
 
 pci:v00008086d000025AAsv00001775sd00001100*
- ID_MODEL_FROM_DATABASE=CR11/VR11 Single Board Computer
+ ID_MODEL_FROM_DATABASE=6300ESB USB Universal Host Controller (CR11/VR11 Single Board Computer)
 
 pci:v00008086d000025AAsv00001775sd0000CE90*
- ID_MODEL_FROM_DATABASE=CE9
+ ID_MODEL_FROM_DATABASE=6300ESB USB Universal Host Controller (CE9)
 
 pci:v00008086d000025AAsv00004C53sd000010B0*
- ID_MODEL_FROM_DATABASE=CL9 mainboard
+ ID_MODEL_FROM_DATABASE=6300ESB USB Universal Host Controller (CL9 mainboard)
 
 pci:v00008086d000025AAsv00004C53sd000010D0*
- ID_MODEL_FROM_DATABASE=Telum ASLP10 Processor AMC
+ ID_MODEL_FROM_DATABASE=6300ESB USB Universal Host Controller (Telum ASLP10 Processor AMC)
 
 pci:v00008086d000025AAsv00004C53sd000010E0*
- ID_MODEL_FROM_DATABASE=PSL09 PrPMC
+ ID_MODEL_FROM_DATABASE=6300ESB USB Universal Host Controller (PSL09 PrPMC)
 
 pci:v00008086d000025AB*
  ID_MODEL_FROM_DATABASE=6300ESB Watchdog Timer
 
 pci:v00008086d000025ABsv00001734sd00001073*
- ID_MODEL_FROM_DATABASE=Primergy Econel 200 D2020 mainboard
+ ID_MODEL_FROM_DATABASE=6300ESB Watchdog Timer (Primergy Econel 200 D2020 mainboard)
 
 pci:v00008086d000025ABsv00001775sd000010D0*
- ID_MODEL_FROM_DATABASE=V5D Single Board Computer
+ ID_MODEL_FROM_DATABASE=6300ESB Watchdog Timer (V5D Single Board Computer)
 
 pci:v00008086d000025ABsv00001775sd00001100*
- ID_MODEL_FROM_DATABASE=CR11/VR11 Single Board Computer
+ ID_MODEL_FROM_DATABASE=6300ESB Watchdog Timer (CR11/VR11 Single Board Computer)
 
 pci:v00008086d000025ABsv00001775sd0000CE90*
- ID_MODEL_FROM_DATABASE=CE9
+ ID_MODEL_FROM_DATABASE=6300ESB Watchdog Timer (CE9)
+
+pci:v00008086d000025ABsv00001AF4sd00001100*
+ ID_MODEL_FROM_DATABASE=6300ESB Watchdog Timer (QEMU Virtual Machine)
 
 pci:v00008086d000025ABsv00004C53sd000010B0*
- ID_MODEL_FROM_DATABASE=CL9 mainboard
+ ID_MODEL_FROM_DATABASE=6300ESB Watchdog Timer (CL9 mainboard)
 
 pci:v00008086d000025ABsv00004C53sd000010D0*
- ID_MODEL_FROM_DATABASE=Telum ASLP10 Processor AMC
+ ID_MODEL_FROM_DATABASE=6300ESB Watchdog Timer (Telum ASLP10 Processor AMC)
 
 pci:v00008086d000025ABsv00004C53sd000010E0*
- ID_MODEL_FROM_DATABASE=PSL09 PrPMC
+ ID_MODEL_FROM_DATABASE=6300ESB Watchdog Timer (PSL09 PrPMC)
 
 pci:v00008086d000025AC*
  ID_MODEL_FROM_DATABASE=6300ESB I/O Advanced Programmable Interrupt Controller
 
 pci:v00008086d000025ACsv00001734sd00001073*
- ID_MODEL_FROM_DATABASE=Primergy Econel 200 D2020 mainboard
+ ID_MODEL_FROM_DATABASE=6300ESB I/O Advanced Programmable Interrupt Controller (Primergy Econel 200 D2020 mainboard)
 
 pci:v00008086d000025ACsv00001775sd000010D0*
- ID_MODEL_FROM_DATABASE=V5D Single Board Computer
+ ID_MODEL_FROM_DATABASE=6300ESB I/O Advanced Programmable Interrupt Controller (V5D Single Board Computer)
 
 pci:v00008086d000025ACsv00001775sd00001100*
- ID_MODEL_FROM_DATABASE=CR11/VR11 Single Board Computer
+ ID_MODEL_FROM_DATABASE=6300ESB I/O Advanced Programmable Interrupt Controller (CR11/VR11 Single Board Computer)
 
 pci:v00008086d000025ACsv00001775sd0000CE90*
- ID_MODEL_FROM_DATABASE=CE9
+ ID_MODEL_FROM_DATABASE=6300ESB I/O Advanced Programmable Interrupt Controller (CE9)
 
 pci:v00008086d000025ACsv00004C53sd000010B0*
- ID_MODEL_FROM_DATABASE=CL9 mainboard
+ ID_MODEL_FROM_DATABASE=6300ESB I/O Advanced Programmable Interrupt Controller (CL9 mainboard)
 
 pci:v00008086d000025ACsv00004C53sd000010D0*
- ID_MODEL_FROM_DATABASE=Telum ASLP10 Processor AMC
+ ID_MODEL_FROM_DATABASE=6300ESB I/O Advanced Programmable Interrupt Controller (Telum ASLP10 Processor AMC)
 
 pci:v00008086d000025ACsv00004C53sd000010E0*
- ID_MODEL_FROM_DATABASE=PSL09 PrPMC
+ ID_MODEL_FROM_DATABASE=6300ESB I/O Advanced Programmable Interrupt Controller (PSL09 PrPMC)
 
 pci:v00008086d000025AD*
  ID_MODEL_FROM_DATABASE=6300ESB USB2 Enhanced Host Controller
 
 pci:v00008086d000025ADsv00001734sd00001073*
- ID_MODEL_FROM_DATABASE=Primergy Econel 200 D2020 mainboard
+ ID_MODEL_FROM_DATABASE=6300ESB USB2 Enhanced Host Controller (Primergy Econel 200 D2020 mainboard)
 
 pci:v00008086d000025ADsv00001775sd000010D0*
- ID_MODEL_FROM_DATABASE=V5D Single Board Computer USB 2.0
+ ID_MODEL_FROM_DATABASE=6300ESB USB2 Enhanced Host Controller (V5D Single Board Computer USB 2.0)
 
 pci:v00008086d000025ADsv00001775sd00001100*
- ID_MODEL_FROM_DATABASE=CR11/VR11 Single Board Computer
+ ID_MODEL_FROM_DATABASE=6300ESB USB2 Enhanced Host Controller (CR11/VR11 Single Board Computer)
 
 pci:v00008086d000025ADsv00001775sd0000CE90*
- ID_MODEL_FROM_DATABASE=CE9
+ ID_MODEL_FROM_DATABASE=6300ESB USB2 Enhanced Host Controller (CE9)
 
 pci:v00008086d000025ADsv00004C53sd000010B0*
- ID_MODEL_FROM_DATABASE=CL9 mainboard
+ ID_MODEL_FROM_DATABASE=6300ESB USB2 Enhanced Host Controller (CL9 mainboard)
 
 pci:v00008086d000025ADsv00004C53sd000010D0*
- ID_MODEL_FROM_DATABASE=Telum ASLP10 Processor AMC
+ ID_MODEL_FROM_DATABASE=6300ESB USB2 Enhanced Host Controller (Telum ASLP10 Processor AMC)
 
 pci:v00008086d000025ADsv00004C53sd000010E0*
- ID_MODEL_FROM_DATABASE=PSL09 PrPMC
+ ID_MODEL_FROM_DATABASE=6300ESB USB2 Enhanced Host Controller (PSL09 PrPMC)
 
 pci:v00008086d000025AE*
  ID_MODEL_FROM_DATABASE=6300ESB 64-bit PCI-X Bridge
@@ -61743,13 +63513,13 @@ pci:v00008086d000025B0*
  ID_MODEL_FROM_DATABASE=6300ESB SATA RAID Controller
 
 pci:v00008086d000025B0sv00001775sd00001100*
- ID_MODEL_FROM_DATABASE=CR11/VR11 Single Board Computer
+ ID_MODEL_FROM_DATABASE=6300ESB SATA RAID Controller (CR11/VR11 Single Board Computer)
 
 pci:v00008086d000025B0sv00004C53sd000010D0*
- ID_MODEL_FROM_DATABASE=Telum ASLP10 Processor AMC
+ ID_MODEL_FROM_DATABASE=6300ESB SATA RAID Controller (Telum ASLP10 Processor AMC)
 
 pci:v00008086d000025B0sv00004C53sd000010E0*
- ID_MODEL_FROM_DATABASE=PSL09 PrPMC
+ ID_MODEL_FROM_DATABASE=6300ESB SATA RAID Controller (PSL09 PrPMC)
 
 pci:v00008086d000025C0*
  ID_MODEL_FROM_DATABASE=5000X Chipset Memory Controller Hub
@@ -61761,16 +63531,16 @@ pci:v00008086d000025D4*
  ID_MODEL_FROM_DATABASE=5000V Chipset Memory Controller Hub
 
 pci:v00008086d000025D4sv000015D9sd00008680*
- ID_MODEL_FROM_DATABASE=X7DVL-E-O motherboard
+ ID_MODEL_FROM_DATABASE=5000V Chipset Memory Controller Hub (X7DVL-E-O motherboard)
 
 pci:v00008086d000025D8*
  ID_MODEL_FROM_DATABASE=5000P Chipset Memory Controller Hub
 
 pci:v00008086d000025D8sv000015D9sd00009680*
- ID_MODEL_FROM_DATABASE=X7DBN Motherboard
+ ID_MODEL_FROM_DATABASE=5000P Chipset Memory Controller Hub (X7DBN Motherboard)
 
 pci:v00008086d000025D8sv00008086sd00003476*
- ID_MODEL_FROM_DATABASE=S5000PSLSATA Server Board
+ ID_MODEL_FROM_DATABASE=5000P Chipset Memory Controller Hub (S5000PSLSATA Server Board)
 
 pci:v00008086d000025E2*
  ID_MODEL_FROM_DATABASE=5000 Series Chipset PCI Express x4 Port 2
@@ -61794,79 +63564,79 @@ pci:v00008086d000025F0*
  ID_MODEL_FROM_DATABASE=5000 Series Chipset FSB Registers
 
 pci:v00008086d000025F0sv00001028sd000001BB*
- ID_MODEL_FROM_DATABASE=PowerEdge 1955 FSB Registers
+ ID_MODEL_FROM_DATABASE=5000 Series Chipset FSB Registers (PowerEdge 1955 FSB Registers)
 
 pci:v00008086d000025F0sv0000103Csd000031FD*
- ID_MODEL_FROM_DATABASE=ProLiant DL140 G3
+ ID_MODEL_FROM_DATABASE=5000 Series Chipset FSB Registers (ProLiant DL140 G3)
 
 pci:v00008086d000025F0sv000015D9sd00008680*
- ID_MODEL_FROM_DATABASE=X7DVL-E-O motherboard
+ ID_MODEL_FROM_DATABASE=5000 Series Chipset FSB Registers (X7DVL-E-O motherboard)
 
 pci:v00008086d000025F0sv000015D9sd00009680*
- ID_MODEL_FROM_DATABASE=X7DBN Motherboard
+ ID_MODEL_FROM_DATABASE=5000 Series Chipset FSB Registers (X7DBN Motherboard)
 
 pci:v00008086d000025F0sv00008086sd00003476*
- ID_MODEL_FROM_DATABASE=S5000PSLSATA Server Board
+ ID_MODEL_FROM_DATABASE=5000 Series Chipset FSB Registers (S5000PSLSATA Server Board)
 
 pci:v00008086d000025F1*
  ID_MODEL_FROM_DATABASE=5000 Series Chipset Reserved Registers
 
 pci:v00008086d000025F1sv0000103Csd000031FD*
- ID_MODEL_FROM_DATABASE=ProLiant DL140 G3
+ ID_MODEL_FROM_DATABASE=5000 Series Chipset Reserved Registers (ProLiant DL140 G3)
 
 pci:v00008086d000025F1sv000015D9sd00008680*
- ID_MODEL_FROM_DATABASE=X7DVL-E-O motherboard
+ ID_MODEL_FROM_DATABASE=5000 Series Chipset Reserved Registers (X7DVL-E-O motherboard)
 
 pci:v00008086d000025F1sv000015D9sd00009680*
- ID_MODEL_FROM_DATABASE=X7DBN Motherboard
+ ID_MODEL_FROM_DATABASE=5000 Series Chipset Reserved Registers (X7DBN Motherboard)
 
 pci:v00008086d000025F1sv00008086sd00003476*
- ID_MODEL_FROM_DATABASE=S5000PSLSATA Server Board
+ ID_MODEL_FROM_DATABASE=5000 Series Chipset Reserved Registers (S5000PSLSATA Server Board)
 
 pci:v00008086d000025F3*
  ID_MODEL_FROM_DATABASE=5000 Series Chipset Reserved Registers
 
 pci:v00008086d000025F3sv0000103Csd000031FD*
- ID_MODEL_FROM_DATABASE=ProLiant DL140 G3
+ ID_MODEL_FROM_DATABASE=5000 Series Chipset Reserved Registers (ProLiant DL140 G3)
 
 pci:v00008086d000025F3sv000015D9sd00008680*
- ID_MODEL_FROM_DATABASE=X7DVL-E-O motherboard
+ ID_MODEL_FROM_DATABASE=5000 Series Chipset Reserved Registers (X7DVL-E-O motherboard)
 
 pci:v00008086d000025F3sv000015D9sd00009680*
- ID_MODEL_FROM_DATABASE=X7DBN Motherboard
+ ID_MODEL_FROM_DATABASE=5000 Series Chipset Reserved Registers (X7DBN Motherboard)
 
 pci:v00008086d000025F3sv00008086sd00003476*
- ID_MODEL_FROM_DATABASE=S5000PSLSATA Server Board
+ ID_MODEL_FROM_DATABASE=5000 Series Chipset Reserved Registers (S5000PSLSATA Server Board)
 
 pci:v00008086d000025F5*
  ID_MODEL_FROM_DATABASE=5000 Series Chipset FBD Registers
 
 pci:v00008086d000025F5sv0000103Csd000031FD*
- ID_MODEL_FROM_DATABASE=ProLiant DL140 G3
+ ID_MODEL_FROM_DATABASE=5000 Series Chipset FBD Registers (ProLiant DL140 G3)
 
 pci:v00008086d000025F5sv000015D9sd00008680*
- ID_MODEL_FROM_DATABASE=X7DVL-E-O motherboard
+ ID_MODEL_FROM_DATABASE=5000 Series Chipset FBD Registers (X7DVL-E-O motherboard)
 
 pci:v00008086d000025F5sv000015D9sd00009680*
- ID_MODEL_FROM_DATABASE=X7DBN Motherboard
+ ID_MODEL_FROM_DATABASE=5000 Series Chipset FBD Registers (X7DBN Motherboard)
 
 pci:v00008086d000025F5sv00008086sd00003476*
- ID_MODEL_FROM_DATABASE=S5000PSLSATA Server Board
+ ID_MODEL_FROM_DATABASE=5000 Series Chipset FBD Registers (S5000PSLSATA Server Board)
 
 pci:v00008086d000025F6*
  ID_MODEL_FROM_DATABASE=5000 Series Chipset FBD Registers
 
 pci:v00008086d000025F6sv0000103Csd000031FD*
- ID_MODEL_FROM_DATABASE=ProLiant DL140 G3
+ ID_MODEL_FROM_DATABASE=5000 Series Chipset FBD Registers (ProLiant DL140 G3)
 
 pci:v00008086d000025F6sv000015D9sd00008680*
- ID_MODEL_FROM_DATABASE=X7DVL-E-O motherboard
+ ID_MODEL_FROM_DATABASE=5000 Series Chipset FBD Registers (X7DVL-E-O motherboard)
 
 pci:v00008086d000025F6sv000015D9sd00009680*
- ID_MODEL_FROM_DATABASE=X7DBN Motherboard
+ ID_MODEL_FROM_DATABASE=5000 Series Chipset FBD Registers (X7DBN Motherboard)
 
 pci:v00008086d000025F6sv00008086sd00003476*
- ID_MODEL_FROM_DATABASE=S5000PSLSATA Server Board
+ ID_MODEL_FROM_DATABASE=5000 Series Chipset FBD Registers (S5000PSLSATA Server Board)
 
 pci:v00008086d000025F7*
  ID_MODEL_FROM_DATABASE=5000 Series Chipset PCI Express x8 Port 2-3
@@ -61884,7 +63654,7 @@ pci:v00008086d00002600*
  ID_MODEL_FROM_DATABASE=E8500/E8501 Hub Interface 1.5
 
 pci:v00008086d00002600sv00001028sd00000170*
- ID_MODEL_FROM_DATABASE=PowerEdge 6850 Hub Interface
+ ID_MODEL_FROM_DATABASE=E8500/E8501 Hub Interface 1.5 (PowerEdge 6850 Hub Interface)
 
 pci:v00008086d00002601*
  ID_MODEL_FROM_DATABASE=E8500/E8501 PCI Express x4 Port D
@@ -61965,76 +63735,76 @@ pci:v00008086d00002620*
  ID_MODEL_FROM_DATABASE=E8500/E8501 eXternal Memory Bridge
 
 pci:v00008086d00002620sv00001028sd00000170*
- ID_MODEL_FROM_DATABASE=PowerEdge 6850 Memory Bridge
+ ID_MODEL_FROM_DATABASE=E8500/E8501 eXternal Memory Bridge (PowerEdge 6850 Memory Bridge)
 
 pci:v00008086d00002621*
  ID_MODEL_FROM_DATABASE=E8500/E8501 XMB Miscellaneous Registers
 
 pci:v00008086d00002621sv00001028sd00000170*
- ID_MODEL_FROM_DATABASE=PowerEdge 6850 XMB Registers
+ ID_MODEL_FROM_DATABASE=E8500/E8501 XMB Miscellaneous Registers (PowerEdge 6850 XMB Registers)
 
 pci:v00008086d00002622*
  ID_MODEL_FROM_DATABASE=E8500/E8501 XMB Memory Interleaving Registers
 
 pci:v00008086d00002622sv00001028sd00000170*
- ID_MODEL_FROM_DATABASE=PowerEdge 6850 Memory Interleaving Registers
+ ID_MODEL_FROM_DATABASE=E8500/E8501 XMB Memory Interleaving Registers (PowerEdge 6850 Memory Interleaving Registers)
 
 pci:v00008086d00002623*
  ID_MODEL_FROM_DATABASE=E8500/E8501 XMB DDR Initialization and Calibration
 
 pci:v00008086d00002623sv00001028sd00000170*
- ID_MODEL_FROM_DATABASE=PowerEdge 6850 DDR Initialization and Calibration
+ ID_MODEL_FROM_DATABASE=E8500/E8501 XMB DDR Initialization and Calibration (PowerEdge 6850 DDR Initialization and Calibration)
 
 pci:v00008086d00002624*
  ID_MODEL_FROM_DATABASE=E8500/E8501 XMB Reserved Registers
 
 pci:v00008086d00002624sv00001028sd00000170*
- ID_MODEL_FROM_DATABASE=PowerEdge 6850 Reserved Registers
+ ID_MODEL_FROM_DATABASE=E8500/E8501 XMB Reserved Registers (PowerEdge 6850 Reserved Registers)
 
 pci:v00008086d00002625*
  ID_MODEL_FROM_DATABASE=E8500/E8501 XMB Reserved Registers
 
 pci:v00008086d00002625sv00001028sd00000170*
- ID_MODEL_FROM_DATABASE=PowerEdge 6850 Reserved Registers
+ ID_MODEL_FROM_DATABASE=E8500/E8501 XMB Reserved Registers (PowerEdge 6850 Reserved Registers)
 
 pci:v00008086d00002626*
  ID_MODEL_FROM_DATABASE=E8500/E8501 XMB Reserved Registers
 
 pci:v00008086d00002626sv00001028sd00000170*
- ID_MODEL_FROM_DATABASE=PowerEdge 6850 Reserved Registers
+ ID_MODEL_FROM_DATABASE=E8500/E8501 XMB Reserved Registers (PowerEdge 6850 Reserved Registers)
 
 pci:v00008086d00002627*
  ID_MODEL_FROM_DATABASE=E8500/E8501 XMB Reserved Registers
 
 pci:v00008086d00002627sv00001028sd00000170*
- ID_MODEL_FROM_DATABASE=PowerEdge 6850 Reserved Registers
+ ID_MODEL_FROM_DATABASE=E8500/E8501 XMB Reserved Registers (PowerEdge 6850 Reserved Registers)
 
 pci:v00008086d00002640*
  ID_MODEL_FROM_DATABASE=82801FB/FR (ICH6/ICH6R) LPC Interface Bridge
 
 pci:v00008086d00002640sv00001462sd00007028*
- ID_MODEL_FROM_DATABASE=915P/G Neo2
+ ID_MODEL_FROM_DATABASE=82801FB/FR (ICH6/ICH6R) LPC Interface Bridge (915P/G Neo2)
 
 pci:v00008086d00002640sv00001734sd0000105C*
- ID_MODEL_FROM_DATABASE=Scenic W620
+ ID_MODEL_FROM_DATABASE=82801FB/FR (ICH6/ICH6R) LPC Interface Bridge (Scenic W620)
 
 pci:v00008086d00002640sv0000E4BFsd00000CCD*
- ID_MODEL_FROM_DATABASE=CCD-CALYPSO
+ ID_MODEL_FROM_DATABASE=82801FB/FR (ICH6/ICH6R) LPC Interface Bridge (CCD-CALYPSO)
 
 pci:v00008086d00002640sv0000E4BFsd00000CD3*
- ID_MODEL_FROM_DATABASE=CD3-JIVE
+ ID_MODEL_FROM_DATABASE=82801FB/FR (ICH6/ICH6R) LPC Interface Bridge (CD3-JIVE)
 
 pci:v00008086d00002640sv0000E4BFsd000058B1*
- ID_MODEL_FROM_DATABASE=XB1
+ ID_MODEL_FROM_DATABASE=82801FB/FR (ICH6/ICH6R) LPC Interface Bridge (XB1)
 
 pci:v00008086d00002641*
  ID_MODEL_FROM_DATABASE=82801FBM (ICH6M) LPC Interface Bridge
 
 pci:v00008086d00002641sv0000103Csd00000934*
- ID_MODEL_FROM_DATABASE=Compaq nw8240/nx8220
+ ID_MODEL_FROM_DATABASE=82801FBM (ICH6M) LPC Interface Bridge (Compaq nw8240/nx8220)
 
 pci:v00008086d00002641sv0000103Csd0000099C*
- ID_MODEL_FROM_DATABASE=NX6110/NC6120
+ ID_MODEL_FROM_DATABASE=82801FBM (ICH6M) LPC Interface Bridge (NX6110/NC6120)
 
 pci:v00008086d00002642*
  ID_MODEL_FROM_DATABASE=82801FW/FRW (ICH6W/ICH6RW) LPC Interface Bridge
@@ -62043,34 +63813,34 @@ pci:v00008086d00002651*
  ID_MODEL_FROM_DATABASE=82801FB/FW (ICH6/ICH6W) SATA Controller
 
 pci:v00008086d00002651sv00001028sd00000179*
- ID_MODEL_FROM_DATABASE=Optiplex GX280
+ ID_MODEL_FROM_DATABASE=82801FB/FW (ICH6/ICH6W) SATA Controller (Optiplex GX280)
 
 pci:v00008086d00002651sv00001043sd00002601*
- ID_MODEL_FROM_DATABASE=P5GD1-VW Mainboard
+ ID_MODEL_FROM_DATABASE=82801FB/FW (ICH6/ICH6W) SATA Controller (P5GD1-VW Mainboard)
 
 pci:v00008086d00002651sv00001734sd0000105C*
- ID_MODEL_FROM_DATABASE=Scenic W620
+ ID_MODEL_FROM_DATABASE=82801FB/FW (ICH6/ICH6W) SATA Controller (Scenic W620)
 
 pci:v00008086d00002651sv00008086sd00004147*
- ID_MODEL_FROM_DATABASE=D915GAG Motherboard
+ ID_MODEL_FROM_DATABASE=82801FB/FW (ICH6/ICH6W) SATA Controller (D915GAG Motherboard)
 
 pci:v00008086d00002651sv0000E4BFsd00000CCD*
- ID_MODEL_FROM_DATABASE=CCD-CALYPSO
+ ID_MODEL_FROM_DATABASE=82801FB/FW (ICH6/ICH6W) SATA Controller (CCD-CALYPSO)
 
 pci:v00008086d00002651sv0000E4BFsd00000CD3*
- ID_MODEL_FROM_DATABASE=CD3-JIVE
+ ID_MODEL_FROM_DATABASE=82801FB/FW (ICH6/ICH6W) SATA Controller (CD3-JIVE)
 
 pci:v00008086d00002651sv0000E4BFsd000058B1*
- ID_MODEL_FROM_DATABASE=XB1
+ ID_MODEL_FROM_DATABASE=82801FB/FW (ICH6/ICH6W) SATA Controller (XB1)
 
 pci:v00008086d00002652*
  ID_MODEL_FROM_DATABASE=82801FR/FRW (ICH6R/ICH6RW) SATA Controller
 
 pci:v00008086d00002652sv00001028sd00000177*
- ID_MODEL_FROM_DATABASE=Dimension 8400
+ ID_MODEL_FROM_DATABASE=82801FR/FRW (ICH6R/ICH6RW) SATA Controller (Dimension 8400)
 
 pci:v00008086d00002652sv00001462sd00007028*
- ID_MODEL_FROM_DATABASE=915P/G Neo2
+ ID_MODEL_FROM_DATABASE=82801FR/FRW (ICH6R/ICH6RW) SATA Controller (915P/G Neo2)
 
 pci:v00008086d00002653*
  ID_MODEL_FROM_DATABASE=82801FBM (ICH6M) SATA Controller
@@ -62079,286 +63849,289 @@ pci:v00008086d00002658*
  ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #1
 
 pci:v00008086d00002658sv00001028sd00000177*
- ID_MODEL_FROM_DATABASE=Dimension 8400
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #1 (Dimension 8400)
 
 pci:v00008086d00002658sv00001028sd00000179*
- ID_MODEL_FROM_DATABASE=Optiplex GX280
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #1 (Optiplex GX280)
 
 pci:v00008086d00002658sv0000103Csd00000934*
- ID_MODEL_FROM_DATABASE=Compaq nw8240/nx8220
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #1 (Compaq nw8240/nx8220)
 
 pci:v00008086d00002658sv0000103Csd0000099C*
- ID_MODEL_FROM_DATABASE=NX6110/NC6120
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #1 (NX6110/NC6120)
 
 pci:v00008086d00002658sv00001043sd000080A6*
- ID_MODEL_FROM_DATABASE=P5GD1-VW Mainboard
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #1 (P5GD1-VW Mainboard)
 
 pci:v00008086d00002658sv00001458sd00002558*
- ID_MODEL_FROM_DATABASE=GA-8I915ME-G Mainboard
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #1 (GA-8I915ME-G Mainboard)
 
 pci:v00008086d00002658sv00001462sd00007028*
- ID_MODEL_FROM_DATABASE=915P/G Neo2
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #1 (915P/G Neo2)
 
 pci:v00008086d00002658sv00001734sd0000105C*
- ID_MODEL_FROM_DATABASE=Scenic W620
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #1 (Scenic W620)
 
 pci:v00008086d00002658sv0000E4BFsd00000CCD*
- ID_MODEL_FROM_DATABASE=CCD-CALYPSO
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #1 (CCD-CALYPSO)
 
 pci:v00008086d00002658sv0000E4BFsd00000CD3*
- ID_MODEL_FROM_DATABASE=CD3-JIVE
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #1 (CD3-JIVE)
 
 pci:v00008086d00002658sv0000E4BFsd000058B1*
- ID_MODEL_FROM_DATABASE=XB1
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #1 (XB1)
 
 pci:v00008086d00002659*
  ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #2
 
 pci:v00008086d00002659sv00001028sd00000177*
- ID_MODEL_FROM_DATABASE=Dimension 8400
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #2 (Dimension 8400)
 
 pci:v00008086d00002659sv00001028sd00000179*
- ID_MODEL_FROM_DATABASE=Optiplex GX280
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #2 (Optiplex GX280)
 
 pci:v00008086d00002659sv0000103Csd00000934*
- ID_MODEL_FROM_DATABASE=Compaq nw8240/nx8220
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #2 (Compaq nw8240/nx8220)
 
 pci:v00008086d00002659sv0000103Csd0000099C*
- ID_MODEL_FROM_DATABASE=NX6110/NC6120
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #2 (NX6110/NC6120)
 
 pci:v00008086d00002659sv00001043sd000080A6*
- ID_MODEL_FROM_DATABASE=P5GD1-VW Mainboard
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #2 (P5GD1-VW Mainboard)
 
 pci:v00008086d00002659sv00001458sd00002659*
- ID_MODEL_FROM_DATABASE=GA-8I915ME-G Mainboard
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #2 (GA-8I915ME-G Mainboard)
 
 pci:v00008086d00002659sv00001462sd00007028*
- ID_MODEL_FROM_DATABASE=915P/G Neo2
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #2 (915P/G Neo2)
 
 pci:v00008086d00002659sv00001734sd0000105C*
- ID_MODEL_FROM_DATABASE=Scenic W620
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #2 (Scenic W620)
 
 pci:v00008086d00002659sv0000E4BFsd00000CCD*
- ID_MODEL_FROM_DATABASE=CCD-CALYPSO
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #2 (CCD-CALYPSO)
 
 pci:v00008086d00002659sv0000E4BFsd00000CD3*
- ID_MODEL_FROM_DATABASE=CD3-JIVE
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #2 (CD3-JIVE)
 
 pci:v00008086d00002659sv0000E4BFsd000058B1*
- ID_MODEL_FROM_DATABASE=XB1
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #2 (XB1)
 
 pci:v00008086d0000265A*
  ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #3
 
 pci:v00008086d0000265Asv00001028sd00000177*
- ID_MODEL_FROM_DATABASE=Dimension 8400
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #3 (Dimension 8400)
 
 pci:v00008086d0000265Asv00001028sd00000179*
- ID_MODEL_FROM_DATABASE=Optiplex GX280
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #3 (Optiplex GX280)
 
 pci:v00008086d0000265Asv0000103Csd00000934*
- ID_MODEL_FROM_DATABASE=Compaq nw8240/nx8220
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #3 (Compaq nw8240/nx8220)
 
 pci:v00008086d0000265Asv0000103Csd0000099C*
- ID_MODEL_FROM_DATABASE=NX6110/NC6120
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #3 (NX6110/NC6120)
 
 pci:v00008086d0000265Asv00001043sd000080A6*
- ID_MODEL_FROM_DATABASE=P5GD1-VW Mainboard
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #3 (P5GD1-VW Mainboard)
 
 pci:v00008086d0000265Asv00001458sd0000265A*
- ID_MODEL_FROM_DATABASE=GA-8I915ME-G Mainboard
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #3 (GA-8I915ME-G Mainboard)
 
 pci:v00008086d0000265Asv00001462sd00007028*
- ID_MODEL_FROM_DATABASE=915P/G Neo2
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #3 (915P/G Neo2)
 
 pci:v00008086d0000265Asv00001734sd0000105C*
- ID_MODEL_FROM_DATABASE=Scenic W620
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #3 (Scenic W620)
 
 pci:v00008086d0000265Asv0000E4BFsd00000CCD*
- ID_MODEL_FROM_DATABASE=CCD-CALYPSO
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #3 (CCD-CALYPSO)
 
 pci:v00008086d0000265Asv0000E4BFsd00000CD3*
- ID_MODEL_FROM_DATABASE=CD3-JIVE
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #3 (CD3-JIVE)
 
 pci:v00008086d0000265Asv0000E4BFsd000058B1*
- ID_MODEL_FROM_DATABASE=XB1
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #3 (XB1)
 
 pci:v00008086d0000265B*
  ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #4
 
 pci:v00008086d0000265Bsv00001028sd00000177*
- ID_MODEL_FROM_DATABASE=Dimension 8400
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #4 (Dimension 8400)
 
 pci:v00008086d0000265Bsv00001028sd00000179*
- ID_MODEL_FROM_DATABASE=Optiplex GX280
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #4 (Optiplex GX280)
 
 pci:v00008086d0000265Bsv0000103Csd0000099C*
- ID_MODEL_FROM_DATABASE=NX6110/NC6120
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #4 (NX6110/NC6120)
 
 pci:v00008086d0000265Bsv00001043sd000080A6*
- ID_MODEL_FROM_DATABASE=P5GD1-VW Mainboard
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #4 (P5GD1-VW Mainboard)
 
 pci:v00008086d0000265Bsv00001458sd0000265A*
- ID_MODEL_FROM_DATABASE=GA-8I915ME-G Mainboard
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #4 (GA-8I915ME-G Mainboard)
 
 pci:v00008086d0000265Bsv00001462sd00007028*
- ID_MODEL_FROM_DATABASE=915P/G Neo2
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #4 (915P/G Neo2)
 
 pci:v00008086d0000265Bsv00001734sd0000105C*
- ID_MODEL_FROM_DATABASE=Scenic W620
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #4 (Scenic W620)
 
 pci:v00008086d0000265Bsv0000E4BFsd00000CCD*
- ID_MODEL_FROM_DATABASE=CCD-CALYPSO
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #4 (CCD-CALYPSO)
 
 pci:v00008086d0000265Bsv0000E4BFsd00000CD3*
- ID_MODEL_FROM_DATABASE=CD3-JIVE
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #4 (CD3-JIVE)
 
 pci:v00008086d0000265Bsv0000E4BFsd000058B1*
- ID_MODEL_FROM_DATABASE=XB1
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #4 (XB1)
 
 pci:v00008086d0000265C*
  ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB2 EHCI Controller
 
 pci:v00008086d0000265Csv00001028sd00000177*
- ID_MODEL_FROM_DATABASE=Dimension 8400
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB2 EHCI Controller (Dimension 8400)
 
 pci:v00008086d0000265Csv00001028sd00000179*
- ID_MODEL_FROM_DATABASE=Optiplex GX280
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB2 EHCI Controller (Optiplex GX280)
 
 pci:v00008086d0000265Csv0000103Csd00000934*
- ID_MODEL_FROM_DATABASE=Compaq nw8240/nx8220
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB2 EHCI Controller (Compaq nw8240/nx8220)
 
 pci:v00008086d0000265Csv0000103Csd0000099C*
- ID_MODEL_FROM_DATABASE=NX6110/NC6120
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB2 EHCI Controller (NX6110/NC6120)
 
 pci:v00008086d0000265Csv00001043sd000080A6*
- ID_MODEL_FROM_DATABASE=P5GD1-VW Mainboard
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB2 EHCI Controller (P5GD1-VW Mainboard)
 
 pci:v00008086d0000265Csv00001458sd00005006*
- ID_MODEL_FROM_DATABASE=GA-8I915ME-G Mainboard
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB2 EHCI Controller (GA-8I915ME-G Mainboard)
 
 pci:v00008086d0000265Csv00001462sd00007028*
- ID_MODEL_FROM_DATABASE=915P/G Neo2
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB2 EHCI Controller (915P/G Neo2)
 
 pci:v00008086d0000265Csv00001734sd0000105C*
- ID_MODEL_FROM_DATABASE=Scenic W620
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB2 EHCI Controller (Scenic W620)
 
 pci:v00008086d0000265Csv00008086sd0000265C*
- ID_MODEL_FROM_DATABASE=Dimension 3100
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB2 EHCI Controller (Dimension 3100)
 
 pci:v00008086d0000265Csv0000E4BFsd00000CCD*
- ID_MODEL_FROM_DATABASE=CCD-CALYPSO
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB2 EHCI Controller (CCD-CALYPSO)
 
 pci:v00008086d0000265Csv0000E4BFsd00000CD3*
- ID_MODEL_FROM_DATABASE=CD3-JIVE
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB2 EHCI Controller (CD3-JIVE)
 
 pci:v00008086d0000265Csv0000E4BFsd000058B1*
- ID_MODEL_FROM_DATABASE=XB1
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) USB2 EHCI Controller (XB1)
 
 pci:v00008086d00002660*
  ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 1
 
 pci:v00008086d00002660sv0000103Csd00000934*
- ID_MODEL_FROM_DATABASE=HP Compaq nw8240 Mobile Workstation
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 1 (HP Compaq nw8240 Mobile Workstation)
 
 pci:v00008086d00002660sv0000103Csd0000099C*
- ID_MODEL_FROM_DATABASE=NX6110/NC6120
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 1 (NX6110/NC6120)
 
 pci:v00008086d00002660sv0000E4BFsd00000CCD*
- ID_MODEL_FROM_DATABASE=CCD-CALYPSO
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 1 (CCD-CALYPSO)
 
 pci:v00008086d00002660sv0000E4BFsd00000CD3*
- ID_MODEL_FROM_DATABASE=CD3-JIVE
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 1 (CD3-JIVE)
 
 pci:v00008086d00002660sv0000E4BFsd000058B1*
- ID_MODEL_FROM_DATABASE=XB1
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 1 (XB1)
 
 pci:v00008086d00002662*
  ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 2
 
 pci:v00008086d00002662sv0000103Csd00000934*
- ID_MODEL_FROM_DATABASE=HP Compaq nw8240 Mobile Workstation
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 2 (HP Compaq nw8240 Mobile Workstation)
 
 pci:v00008086d00002662sv0000E4BFsd00000CCD*
- ID_MODEL_FROM_DATABASE=CCD-CALYPSO
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 2 (CCD-CALYPSO)
 
 pci:v00008086d00002662sv0000E4BFsd00000CD3*
- ID_MODEL_FROM_DATABASE=CD3-JIVE
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 2 (CD3-JIVE)
 
 pci:v00008086d00002662sv0000E4BFsd000058B1*
- ID_MODEL_FROM_DATABASE=XB1
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 2 (XB1)
 
 pci:v00008086d00002664*
  ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 3
 
 pci:v00008086d00002664sv0000E4BFsd00000CCD*
- ID_MODEL_FROM_DATABASE=CCD-CALYPSO
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 3 (CCD-CALYPSO)
 
 pci:v00008086d00002664sv0000E4BFsd00000CD3*
- ID_MODEL_FROM_DATABASE=CD3-JIVE
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 3 (CD3-JIVE)
 
 pci:v00008086d00002664sv0000E4BFsd000058B1*
- ID_MODEL_FROM_DATABASE=XB1
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 3 (XB1)
 
 pci:v00008086d00002666*
  ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 4
 
 pci:v00008086d00002666sv0000E4BFsd00000CCD*
- ID_MODEL_FROM_DATABASE=CCD-CALYPSO
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 4 (CCD-CALYPSO)
 
 pci:v00008086d00002666sv0000E4BFsd00000CD3*
- ID_MODEL_FROM_DATABASE=CD3-JIVE
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 4 (CD3-JIVE)
 
 pci:v00008086d00002666sv0000E4BFsd000058B1*
- ID_MODEL_FROM_DATABASE=XB1
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 4 (XB1)
 
 pci:v00008086d00002668*
  ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) High Definition Audio Controller
 
 pci:v00008086d00002668sv00001014sd000005B7*
- ID_MODEL_FROM_DATABASE=ThinkPad Z60t
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) High Definition Audio Controller (ThinkPad Z60t)
 
 pci:v00008086d00002668sv0000103Csd00002A09*
- ID_MODEL_FROM_DATABASE=PufferM-UL8E
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) High Definition Audio Controller (PufferM-UL8E)
 
 pci:v00008086d00002668sv00001043sd00001173*
- ID_MODEL_FROM_DATABASE=Asus A6VC
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) High Definition Audio Controller (Asus A6VC)
 
 pci:v00008086d00002668sv00001043sd0000814E*
- ID_MODEL_FROM_DATABASE=P5GD1-VW Mainboard
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) High Definition Audio Controller (P5GD1-VW Mainboard)
 
 pci:v00008086d00002668sv00001462sd00007028*
- ID_MODEL_FROM_DATABASE=915P/G Neo2
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) High Definition Audio Controller (915P/G Neo2)
+
+pci:v00008086d00002668sv00001AF4sd00001100*
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) High Definition Audio Controller (QEMU Virtual Machine)
 
 pci:v00008086d0000266A*
  ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) SMBus Controller
 
 pci:v00008086d0000266Asv00001028sd00000177*
- ID_MODEL_FROM_DATABASE=Dimension 8400
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) SMBus Controller (Dimension 8400)
 
 pci:v00008086d0000266Asv00001028sd00000179*
- ID_MODEL_FROM_DATABASE=Optiplex GX280
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) SMBus Controller (Optiplex GX280)
 
 pci:v00008086d0000266Asv00001043sd000080A6*
- ID_MODEL_FROM_DATABASE=P5GD1-VW Mainboard
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) SMBus Controller (P5GD1-VW Mainboard)
 
 pci:v00008086d0000266Asv00001458sd0000266A*
- ID_MODEL_FROM_DATABASE=GA-8I915ME-G Mainboard
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) SMBus Controller (GA-8I915ME-G Mainboard)
 
 pci:v00008086d0000266Asv00001462sd00007028*
- ID_MODEL_FROM_DATABASE=915P/G Neo2
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) SMBus Controller (915P/G Neo2)
 
 pci:v00008086d0000266Asv00001734sd0000105C*
- ID_MODEL_FROM_DATABASE=Scenic W620
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) SMBus Controller (Scenic W620)
 
 pci:v00008086d0000266Asv0000E4BFsd00000CCD*
- ID_MODEL_FROM_DATABASE=CCD-CALYPSO
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) SMBus Controller (CCD-CALYPSO)
 
 pci:v00008086d0000266Asv0000E4BFsd00000CD3*
- ID_MODEL_FROM_DATABASE=CD3-JIVE
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) SMBus Controller (CD3-JIVE)
 
 pci:v00008086d0000266Asv0000E4BFsd000058B1*
- ID_MODEL_FROM_DATABASE=XB1
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) SMBus Controller (XB1)
 
 pci:v00008086d0000266C*
  ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) LAN Controller
@@ -62367,103 +64140,103 @@ pci:v00008086d0000266D*
  ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Modem Controller
 
 pci:v00008086d0000266Dsv00001025sd0000006A*
- ID_MODEL_FROM_DATABASE=Conexant AC'97 CoDec (in Acer TravelMate 2410 serie laptop)
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Modem Controller (Conexant AC'97 CoDec (in Acer TravelMate 2410 serie laptop))
 
 pci:v00008086d0000266Dsv0000103Csd00000934*
- ID_MODEL_FROM_DATABASE=Compaq nw8240/nx8220
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Modem Controller (Compaq nw8240/nx8220)
 
 pci:v00008086d0000266Dsv0000103Csd0000099C*
- ID_MODEL_FROM_DATABASE=NX6110/NC6120
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Modem Controller (NX6110/NC6120)
 
 pci:v00008086d0000266E*
  ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Audio Controller
 
 pci:v00008086d0000266Esv00001025sd0000006A*
- ID_MODEL_FROM_DATABASE=Realtek ALC 655 codec (in Acer TravelMate 2410 serie laptop)
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Audio Controller (Realtek ALC 655 codec (in Acer TravelMate 2410 serie laptop))
 
 pci:v00008086d0000266Esv00001028sd00000177*
- ID_MODEL_FROM_DATABASE=Dimension 8400
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Audio Controller (Dimension 8400)
 
 pci:v00008086d0000266Esv00001028sd00000179*
- ID_MODEL_FROM_DATABASE=Optiplex GX280
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Audio Controller (Optiplex GX280)
 
 pci:v00008086d0000266Esv00001028sd00000182*
- ID_MODEL_FROM_DATABASE=Latitude D610 Laptop
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Audio Controller (Latitude D610 Laptop)
 
 pci:v00008086d0000266Esv00001028sd00000187*
- ID_MODEL_FROM_DATABASE=Dell Precision M70 Laptop
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Audio Controller (Dell Precision M70 Laptop)
 
 pci:v00008086d0000266Esv00001028sd00000188*
- ID_MODEL_FROM_DATABASE=Inspiron 6000 laptop
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Audio Controller (Inspiron 6000 laptop)
 
 pci:v00008086d0000266Esv0000103Csd00000934*
- ID_MODEL_FROM_DATABASE=Compaq nw8240/nx8220
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Audio Controller (Compaq nw8240/nx8220)
 
 pci:v00008086d0000266Esv0000103Csd00000944*
- ID_MODEL_FROM_DATABASE=Compaq NC6220
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Audio Controller (Compaq NC6220)
 
 pci:v00008086d0000266Esv0000103Csd0000099C*
- ID_MODEL_FROM_DATABASE=NX6110/NC6120
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Audio Controller (NX6110/NC6120)
 
 pci:v00008086d0000266Esv0000103Csd00003006*
- ID_MODEL_FROM_DATABASE=DC7100 SFF(DX878AV)
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Audio Controller (DC7100 SFF(DX878AV))
 
 pci:v00008086d0000266Esv00001458sd0000A002*
- ID_MODEL_FROM_DATABASE=GA-8I915ME-G Mainboard
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Audio Controller (GA-8I915ME-G Mainboard)
 
 pci:v00008086d0000266Esv0000152Dsd00000745*
- ID_MODEL_FROM_DATABASE=Packard Bell A8550 Laptop
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Audio Controller (Packard Bell A8550 Laptop)
 
 pci:v00008086d0000266Esv00001734sd0000105A*
- ID_MODEL_FROM_DATABASE=Scenic W620
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Audio Controller (Scenic W620)
 
 pci:v00008086d0000266F*
  ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) IDE Controller
 
 pci:v00008086d0000266Fsv00001028sd00000177*
- ID_MODEL_FROM_DATABASE=Dimension 8400
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) IDE Controller (Dimension 8400)
 
 pci:v00008086d0000266Fsv0000103Csd00000934*
- ID_MODEL_FROM_DATABASE=Compaq nw8240/nx8220
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) IDE Controller (Compaq nw8240/nx8220)
 
 pci:v00008086d0000266Fsv0000103Csd0000099C*
- ID_MODEL_FROM_DATABASE=NX6110/NC6120
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) IDE Controller (NX6110/NC6120)
 
 pci:v00008086d0000266Fsv00001043sd000080A6*
- ID_MODEL_FROM_DATABASE=P5GD1-VW Mainboard
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) IDE Controller (P5GD1-VW Mainboard)
 
 pci:v00008086d0000266Fsv00001458sd0000266F*
- ID_MODEL_FROM_DATABASE=GA-8I915ME-G Mainboard
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) IDE Controller (GA-8I915ME-G Mainboard)
 
 pci:v00008086d0000266Fsv00001462sd00007028*
- ID_MODEL_FROM_DATABASE=915P/G Neo2
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) IDE Controller (915P/G Neo2)
 
 pci:v00008086d0000266Fsv00001734sd0000105C*
- ID_MODEL_FROM_DATABASE=Scenic W620
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) IDE Controller (Scenic W620)
 
 pci:v00008086d0000266Fsv0000E4BFsd00000CCD*
- ID_MODEL_FROM_DATABASE=CCD-CALYPSO
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) IDE Controller (CCD-CALYPSO)
 
 pci:v00008086d0000266Fsv0000E4BFsd00000CD3*
- ID_MODEL_FROM_DATABASE=CD3-JIVE
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) IDE Controller (CD3-JIVE)
 
 pci:v00008086d0000266Fsv0000E4BFsd000058B1*
- ID_MODEL_FROM_DATABASE=XB1
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) IDE Controller (XB1)
 
 pci:v00008086d00002670*
  ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset LPC Interface Controller
 
 pci:v00008086d00002670sv0000103Csd000031FE*
- ID_MODEL_FROM_DATABASE=ProLiant DL140 G3
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset LPC Interface Controller (ProLiant DL140 G3)
 
 pci:v00008086d00002670sv000015D9sd00008680*
- ID_MODEL_FROM_DATABASE=X7DVL-E-O motherboard
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset LPC Interface Controller (X7DVL-E-O motherboard)
 
 pci:v00008086d00002670sv000015D9sd00009680*
- ID_MODEL_FROM_DATABASE=X7DBN Motherboard
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset LPC Interface Controller (X7DBN Motherboard)
 
 pci:v00008086d00002670sv00008086sd00003476*
- ID_MODEL_FROM_DATABASE=Intel S5000PSLSATA Server Board
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset LPC Interface Controller (Intel S5000PSLSATA Server Board)
 
 pci:v00008086d00002680*
  ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset SATA IDE Controller
@@ -62472,22 +64245,22 @@ pci:v00008086d00002681*
  ID_MODEL_FROM_DATABASE=631xESB/632xESB SATA AHCI Controller
 
 pci:v00008086d00002681sv0000103Csd000031FE*
- ID_MODEL_FROM_DATABASE=ProLiant DL140 G3
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB SATA AHCI Controller (ProLiant DL140 G3)
 
 pci:v00008086d00002681sv000015D9sd00008680*
- ID_MODEL_FROM_DATABASE=X7DVL-E-O motherboard
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB SATA AHCI Controller (X7DVL-E-O motherboard)
 
 pci:v00008086d00002681sv000015D9sd00009680*
- ID_MODEL_FROM_DATABASE=X7DBN Motherboard
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB SATA AHCI Controller (X7DBN Motherboard)
 
 pci:v00008086d00002681sv00008086sd00003476*
- ID_MODEL_FROM_DATABASE=Intel S5000PSLSATA Server Board
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB SATA AHCI Controller (Intel S5000PSLSATA Server Board)
 
 pci:v00008086d00002682*
  ID_MODEL_FROM_DATABASE=631xESB/632xESB SATA RAID Controller
 
 pci:v00008086d00002682sv0000103Csd000031FE*
- ID_MODEL_FROM_DATABASE=Adaptec Serial ATA HostRAID
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB SATA RAID Controller (Adaptec Serial ATA HostRAID)
 
 pci:v00008086d00002683*
  ID_MODEL_FROM_DATABASE=631xESB/632xESB SATA RAID Controller
@@ -62496,109 +64269,109 @@ pci:v00008086d00002688*
  ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #1
 
 pci:v00008086d00002688sv00001028sd000001BB*
- ID_MODEL_FROM_DATABASE=PowerEdge 1955 onboard USB
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #1 (PowerEdge 1955 onboard USB)
 
 pci:v00008086d00002688sv00001028sd000001F0*
- ID_MODEL_FROM_DATABASE=PowerEdge R900 onboard USB
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #1 (PowerEdge R900 onboard USB)
 
 pci:v00008086d00002688sv0000103Csd000031FE*
- ID_MODEL_FROM_DATABASE=ProLiant DL140 G3
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #1 (ProLiant DL140 G3)
 
 pci:v00008086d00002688sv000015D9sd00008680*
- ID_MODEL_FROM_DATABASE=X7DVL-E-O motherboard
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #1 (X7DVL-E-O motherboard)
 
 pci:v00008086d00002688sv000015D9sd00009680*
- ID_MODEL_FROM_DATABASE=X7DBN Motherboard
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #1 (X7DBN Motherboard)
 
 pci:v00008086d00002688sv00008086sd00003476*
- ID_MODEL_FROM_DATABASE=Intel S5000PSLSATA Server Board
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #1 (Intel S5000PSLSATA Server Board)
 
 pci:v00008086d00002689*
  ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #2
 
 pci:v00008086d00002689sv00001028sd000001BB*
- ID_MODEL_FROM_DATABASE=PowerEdge 1955 onboard USB
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #2 (PowerEdge 1955 onboard USB)
 
 pci:v00008086d00002689sv00001028sd000001F0*
- ID_MODEL_FROM_DATABASE=PowerEdge R900 onboard USB
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #2 (PowerEdge R900 onboard USB)
 
 pci:v00008086d00002689sv0000103Csd000031FE*
- ID_MODEL_FROM_DATABASE=ProLiant DL140 G3
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #2 (ProLiant DL140 G3)
 
 pci:v00008086d00002689sv000015D9sd00008680*
- ID_MODEL_FROM_DATABASE=X7DVL-E-O motherboard
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #2 (X7DVL-E-O motherboard)
 
 pci:v00008086d00002689sv000015D9sd00009680*
- ID_MODEL_FROM_DATABASE=X7DBN Motherboard
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #2 (X7DBN Motherboard)
 
 pci:v00008086d00002689sv00008086sd00003476*
- ID_MODEL_FROM_DATABASE=Intel S5000PSLSATA Server Board
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #2 (Intel S5000PSLSATA Server Board)
 
 pci:v00008086d0000268A*
  ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #3
 
 pci:v00008086d0000268Asv00001028sd000001F0*
- ID_MODEL_FROM_DATABASE=PowerEdge R900 onboard USB
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #3 (PowerEdge R900 onboard USB)
 
 pci:v00008086d0000268Asv0000103Csd000031FE*
- ID_MODEL_FROM_DATABASE=ProLiant DL140 G3
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #3 (ProLiant DL140 G3)
 
 pci:v00008086d0000268Asv000015D9sd00008680*
- ID_MODEL_FROM_DATABASE=X7DVL-E-O motherboard
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #3 (X7DVL-E-O motherboard)
 
 pci:v00008086d0000268Asv000015D9sd00009680*
- ID_MODEL_FROM_DATABASE=X7DBN Motherboard
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #3 (X7DBN Motherboard)
 
 pci:v00008086d0000268Asv00008086sd00003476*
- ID_MODEL_FROM_DATABASE=Intel S5000PSLSATA Server Board
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #3 (Intel S5000PSLSATA Server Board)
 
 pci:v00008086d0000268B*
  ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #4
 
 pci:v00008086d0000268Bsv00001028sd000001F0*
- ID_MODEL_FROM_DATABASE=PowerEdge R900 onboard USB
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #4 (PowerEdge R900 onboard USB)
 
 pci:v00008086d0000268Bsv000015D9sd00008680*
- ID_MODEL_FROM_DATABASE=X7DVL-E-O motherboard
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #4 (X7DVL-E-O motherboard)
 
 pci:v00008086d0000268Bsv00008086sd00003476*
- ID_MODEL_FROM_DATABASE=Intel S5000PSLSATA Server Board
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset UHCI USB Controller #4 (Intel S5000PSLSATA Server Board)
 
 pci:v00008086d0000268C*
  ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset EHCI USB2 Controller
 
 pci:v00008086d0000268Csv00001028sd000001BB*
- ID_MODEL_FROM_DATABASE=PowerEdge 1955 onboard USB
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset EHCI USB2 Controller (PowerEdge 1955 onboard USB)
 
 pci:v00008086d0000268Csv00001028sd000001F0*
- ID_MODEL_FROM_DATABASE=PowerEdge R900 onboard USB
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset EHCI USB2 Controller (PowerEdge R900 onboard USB)
 
 pci:v00008086d0000268Csv0000103Csd000031FE*
- ID_MODEL_FROM_DATABASE=ProLiant DL140 G3
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset EHCI USB2 Controller (ProLiant DL140 G3)
 
 pci:v00008086d0000268Csv000015D9sd00008680*
- ID_MODEL_FROM_DATABASE=X7DVL-E-O motherboard
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset EHCI USB2 Controller (X7DVL-E-O motherboard)
 
 pci:v00008086d0000268Csv000015D9sd00009680*
- ID_MODEL_FROM_DATABASE=X7DBN Motherboard
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset EHCI USB2 Controller (X7DBN Motherboard)
 
 pci:v00008086d0000268Csv00008086sd00003476*
- ID_MODEL_FROM_DATABASE=Intel S5000PSLSATA Server Board
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset EHCI USB2 Controller (Intel S5000PSLSATA Server Board)
 
 pci:v00008086d00002690*
  ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset PCI Express Root Port 1
 
 pci:v00008086d00002690sv0000103Csd000031FE*
- ID_MODEL_FROM_DATABASE=ProLiant DL140 G3
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset PCI Express Root Port 1 (ProLiant DL140 G3)
 
 pci:v00008086d00002690sv000015D9sd00009680*
- ID_MODEL_FROM_DATABASE=X7DBN Motherboard
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset PCI Express Root Port 1 (X7DBN Motherboard)
 
 pci:v00008086d00002692*
  ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset PCI Express Root Port 2
 
 pci:v00008086d00002692sv0000103Csd000031FE*
- ID_MODEL_FROM_DATABASE=ProLiant DL140 G3
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset PCI Express Root Port 2 (ProLiant DL140 G3)
 
 pci:v00008086d00002694*
  ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset PCI Express Root Port 3
@@ -62619,46 +64392,49 @@ pci:v00008086d0000269B*
  ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset SMBus Controller
 
 pci:v00008086d0000269Bsv0000103Csd000031FE*
- ID_MODEL_FROM_DATABASE=ProLiant DL140 G3
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset SMBus Controller (ProLiant DL140 G3)
 
 pci:v00008086d0000269Bsv000015D9sd00008680*
- ID_MODEL_FROM_DATABASE=X7DVL-E-O motherboard
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset SMBus Controller (X7DVL-E-O motherboard)
 
 pci:v00008086d0000269Bsv000015D9sd00009680*
- ID_MODEL_FROM_DATABASE=X7DBN Motherboard
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset SMBus Controller (X7DBN Motherboard)
 
 pci:v00008086d0000269Bsv00008086sd00003476*
- ID_MODEL_FROM_DATABASE=Intel S5000PSLSATA Server Board
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB/3100 Chipset SMBus Controller (Intel S5000PSLSATA Server Board)
 
 pci:v00008086d0000269E*
  ID_MODEL_FROM_DATABASE=631xESB/632xESB IDE Controller
 
 pci:v00008086d0000269Esv0000103Csd000031FE*
- ID_MODEL_FROM_DATABASE=ProLiant DL140 G3
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB IDE Controller (ProLiant DL140 G3)
 
 pci:v00008086d0000269Esv000015D9sd00008680*
- ID_MODEL_FROM_DATABASE=X7DVL-E-O motherboard
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB IDE Controller (X7DVL-E-O motherboard)
 
 pci:v00008086d0000269Esv000015D9sd00009680*
- ID_MODEL_FROM_DATABASE=X7DBN Motherboard
+ ID_MODEL_FROM_DATABASE=631xESB/632xESB IDE Controller (X7DBN Motherboard)
 
 pci:v00008086d00002770*
  ID_MODEL_FROM_DATABASE=82945G/GZ/P/PL Memory Controller Hub
 
 pci:v00008086d00002770sv00001028sd000001AD*
- ID_MODEL_FROM_DATABASE=OptiPlex GX620
+ ID_MODEL_FROM_DATABASE=82945G/GZ/P/PL Memory Controller Hub (OptiPlex GX620)
 
 pci:v00008086d00002770sv0000103Csd00002A3B*
- ID_MODEL_FROM_DATABASE=Pavilion A1512X
+ ID_MODEL_FROM_DATABASE=82945G/GZ/P/PL Memory Controller Hub (Pavilion A1512X)
 
 pci:v00008086d00002770sv00001043sd0000817A*
- ID_MODEL_FROM_DATABASE=P5LD2-VM Mainboard
+ ID_MODEL_FROM_DATABASE=82945G/GZ/P/PL Memory Controller Hub (P5LD2-VM Mainboard)
 
 pci:v00008086d00002770sv0000107Bsd00005048*
- ID_MODEL_FROM_DATABASE=E4500
+ ID_MODEL_FROM_DATABASE=82945G/GZ/P/PL Memory Controller Hub (E4500)
+
+pci:v00008086d00002770sv00001462sd00007418*
+ ID_MODEL_FROM_DATABASE=82945G/GZ/P/PL Memory Controller Hub (Wind PC MS-7418)
 
 pci:v00008086d00002770sv00008086sd0000544E*
- ID_MODEL_FROM_DATABASE=DeskTop Board D945GTP
+ ID_MODEL_FROM_DATABASE=82945G/GZ/P/PL Memory Controller Hub (DeskTop Board D945GTP)
 
 pci:v00008086d00002771*
  ID_MODEL_FROM_DATABASE=82945G/GZ/P/PL PCI Express Root Port
@@ -62667,13 +64443,16 @@ pci:v00008086d00002772*
  ID_MODEL_FROM_DATABASE=82945G/GZ Integrated Graphics Controller
 
 pci:v00008086d00002772sv0000103Csd00002A3B*
- ID_MODEL_FROM_DATABASE=Pavilion A1512X
+ ID_MODEL_FROM_DATABASE=82945G/GZ Integrated Graphics Controller (Pavilion A1512X)
+
+pci:v00008086d00002772sv00001462sd00007418*
+ ID_MODEL_FROM_DATABASE=82945G/GZ Integrated Graphics Controller (Wind PC MS-7418)
 
 pci:v00008086d00002772sv00008086sd0000544E*
- ID_MODEL_FROM_DATABASE=DeskTop Board D945GTP
+ ID_MODEL_FROM_DATABASE=82945G/GZ Integrated Graphics Controller (DeskTop Board D945GTP)
 
 pci:v00008086d00002772sv00008086sd0000D605*
- ID_MODEL_FROM_DATABASE=Intel Desktop Board D945GCCR
+ ID_MODEL_FROM_DATABASE=82945G/GZ Integrated Graphics Controller (Intel Desktop Board D945GCCR)
 
 pci:v00008086d00002774*
  ID_MODEL_FROM_DATABASE=82955X Memory Controller Hub
@@ -62688,10 +64467,10 @@ pci:v00008086d00002778*
  ID_MODEL_FROM_DATABASE=E7230/3000/3010 Memory Controller Hub
 
 pci:v00008086d00002778sv00001028sd000001DF*
- ID_MODEL_FROM_DATABASE=PowerEdge SC440
+ ID_MODEL_FROM_DATABASE=E7230/3000/3010 Memory Controller Hub (PowerEdge SC440)
 
 pci:v00008086d00002778sv00001028sd000001E6*
- ID_MODEL_FROM_DATABASE=PowerEdge 860
+ ID_MODEL_FROM_DATABASE=E7230/3000/3010 Memory Controller Hub (PowerEdge 860)
 
 pci:v00008086d00002779*
  ID_MODEL_FROM_DATABASE=E7230/3000/3010 PCI Express Root Port
@@ -62703,7 +64482,7 @@ pci:v00008086d0000277C*
  ID_MODEL_FROM_DATABASE=82975X Memory Controller Hub
 
 pci:v00008086d0000277Csv00001043sd00008178*
- ID_MODEL_FROM_DATABASE=P5WDG2 WS Professional motherboard
+ ID_MODEL_FROM_DATABASE=82975X Memory Controller Hub (P5WDG2 WS Professional motherboard)
 
 pci:v00008086d0000277D*
  ID_MODEL_FROM_DATABASE=82975X PCI Express Root Port
@@ -62712,94 +64491,100 @@ pci:v00008086d00002782*
  ID_MODEL_FROM_DATABASE=82915G Integrated Graphics Controller
 
 pci:v00008086d00002782sv00001043sd00002582*
- ID_MODEL_FROM_DATABASE=P5GD1-VW Mainboard
+ ID_MODEL_FROM_DATABASE=82915G Integrated Graphics Controller (P5GD1-VW Mainboard)
 
 pci:v00008086d00002782sv00001734sd0000105B*
- ID_MODEL_FROM_DATABASE=Scenic W620
+ ID_MODEL_FROM_DATABASE=82915G Integrated Graphics Controller (Scenic W620)
 
 pci:v00008086d00002792*
  ID_MODEL_FROM_DATABASE=Mobile 915GM/GMS/910GML Express Graphics Controller
 
 pci:v00008086d00002792sv0000103Csd0000099C*
- ID_MODEL_FROM_DATABASE=NX6110/NC6120
+ ID_MODEL_FROM_DATABASE=Mobile 915GM/GMS/910GML Express Graphics Controller (NX6110/NC6120)
 
 pci:v00008086d00002792sv00001043sd00001881*
- ID_MODEL_FROM_DATABASE=GMA 900 915GM Integrated Graphics
+ ID_MODEL_FROM_DATABASE=Mobile 915GM/GMS/910GML Express Graphics Controller (GMA 900 915GM Integrated Graphics)
 
 pci:v00008086d00002792sv0000E4BFsd00000CCD*
- ID_MODEL_FROM_DATABASE=CCD-CALYPSO
+ ID_MODEL_FROM_DATABASE=Mobile 915GM/GMS/910GML Express Graphics Controller (CCD-CALYPSO)
 
 pci:v00008086d00002792sv0000E4BFsd00000CD3*
- ID_MODEL_FROM_DATABASE=CD3-JIVE
+ ID_MODEL_FROM_DATABASE=Mobile 915GM/GMS/910GML Express Graphics Controller (CD3-JIVE)
 
 pci:v00008086d00002792sv0000E4BFsd000058B1*
- ID_MODEL_FROM_DATABASE=XB1
+ ID_MODEL_FROM_DATABASE=Mobile 915GM/GMS/910GML Express Graphics Controller (XB1)
 
 pci:v00008086d000027A0*
  ID_MODEL_FROM_DATABASE=Mobile 945GM/PM/GMS, 943/940GML and 945GT Express Memory Controller Hub
 
 pci:v00008086d000027A0sv00001025sd0000006C*
- ID_MODEL_FROM_DATABASE=9814 WKMI
+ ID_MODEL_FROM_DATABASE=Mobile 945GM/PM/GMS, 943/940GML and 945GT Express Memory Controller Hub (9814 WKMI)
 
 pci:v00008086d000027A0sv00001028sd000001D7*
- ID_MODEL_FROM_DATABASE=XPS M1210
+ ID_MODEL_FROM_DATABASE=Mobile 945GM/PM/GMS, 943/940GML and 945GT Express Memory Controller Hub (XPS M1210)
 
 pci:v00008086d000027A0sv0000103Csd0000309F*
- ID_MODEL_FROM_DATABASE=Compaq nx9420 Notebook
+ ID_MODEL_FROM_DATABASE=Mobile 945GM/PM/GMS, 943/940GML and 945GT Express Memory Controller Hub (Compaq nx9420 Notebook)
 
 pci:v00008086d000027A0sv0000103Csd000030A1*
- ID_MODEL_FROM_DATABASE=NC2400
+ ID_MODEL_FROM_DATABASE=Mobile 945GM/PM/GMS, 943/940GML and 945GT Express Memory Controller Hub (NC2400)
 
 pci:v00008086d000027A0sv0000103Csd000030A3*
- ID_MODEL_FROM_DATABASE=Compaq nw8440
+ ID_MODEL_FROM_DATABASE=Mobile 945GM/PM/GMS, 943/940GML and 945GT Express Memory Controller Hub (Compaq nw8440)
 
 pci:v00008086d000027A0sv00001043sd00001237*
- ID_MODEL_FROM_DATABASE=A6J-Q008
+ ID_MODEL_FROM_DATABASE=Mobile 945GM/PM/GMS, 943/940GML and 945GT Express Memory Controller Hub (A6J-Q008)
+
+pci:v00008086d000027A0sv00001071sd00008209*
+ ID_MODEL_FROM_DATABASE=Mobile 945GM/PM/GMS, 943/940GML and 945GT Express Memory Controller Hub (Medion MIM 2240 Notebook PC [MD98100])
 
 pci:v00008086d000027A0sv000017AAsd00002015*
- ID_MODEL_FROM_DATABASE=ThinkPad T60
+ ID_MODEL_FROM_DATABASE=Mobile 945GM/PM/GMS, 943/940GML and 945GT Express Memory Controller Hub (ThinkPad T60)
 
 pci:v00008086d000027A0sv000017AAsd00002017*
- ID_MODEL_FROM_DATABASE=ThinkPad T60/R60 series
+ ID_MODEL_FROM_DATABASE=Mobile 945GM/PM/GMS, 943/940GML and 945GT Express Memory Controller Hub (ThinkPad R60/T60/X60 series)
 
 pci:v00008086d000027A1*
  ID_MODEL_FROM_DATABASE=Mobile 945GM/PM/GMS, 943/940GML and 945GT Express PCI Express Root Port
 
 pci:v00008086d000027A1sv0000103Csd0000309F*
- ID_MODEL_FROM_DATABASE=Compaq nx9420 Notebook
+ ID_MODEL_FROM_DATABASE=Mobile 945GM/PM/GMS, 943/940GML and 945GT Express PCI Express Root Port (Compaq nx9420 Notebook)
 
 pci:v00008086d000027A1sv0000103Csd000030A3*
- ID_MODEL_FROM_DATABASE=Compaq nw8440
+ ID_MODEL_FROM_DATABASE=Mobile 945GM/PM/GMS, 943/940GML and 945GT Express PCI Express Root Port (Compaq nw8440)
+
+pci:v00008086d000027A1sv00001071sd00008209*
+ ID_MODEL_FROM_DATABASE=Mobile 945GM/PM/GMS, 943/940GML and 945GT Express PCI Express Root Port (Medion MIM 2240 Notebook PC [MD98100])
 
 pci:v00008086d000027A2*
  ID_MODEL_FROM_DATABASE=Mobile 945GM/GMS, 943/940GML Express Integrated Graphics Controller
 
 pci:v00008086d000027A2sv0000103Csd000030A1*
- ID_MODEL_FROM_DATABASE=NC2400
+ ID_MODEL_FROM_DATABASE=Mobile 945GM/GMS, 943/940GML Express Integrated Graphics Controller (NC2400)
 
 pci:v00008086d000027A2sv000017AAsd0000201A*
- ID_MODEL_FROM_DATABASE=ThinkPad T60/R60 series
+ ID_MODEL_FROM_DATABASE=Mobile 945GM/GMS, 943/940GML Express Integrated Graphics Controller (ThinkPad R60/T60/X60 series)
 
 pci:v00008086d000027A2sv00009902sd00001584*
- ID_MODEL_FROM_DATABASE=CCE MPL-D10H120F
+ ID_MODEL_FROM_DATABASE=Mobile 945GM/GMS, 943/940GML Express Integrated Graphics Controller (CCE MPL-D10H120F)
 
 pci:v00008086d000027A6*
  ID_MODEL_FROM_DATABASE=Mobile 945GM/GMS/GME, 943/940GML Express Integrated Graphics Controller
 
 pci:v00008086d000027A6sv0000103Csd000030A1*
- ID_MODEL_FROM_DATABASE=NC2400
+ ID_MODEL_FROM_DATABASE=Mobile 945GM/GMS/GME, 943/940GML Express Integrated Graphics Controller (NC2400)
 
 pci:v00008086d000027A6sv00001775sd000011CC*
- ID_MODEL_FROM_DATABASE=CC11/CL11 integrated graphics (secondary)
+ ID_MODEL_FROM_DATABASE=Mobile 945GM/GMS/GME, 943/940GML Express Integrated Graphics Controller (CC11/CL11 integrated graphics (secondary))
 
 pci:v00008086d000027A6sv000017AAsd0000201A*
- ID_MODEL_FROM_DATABASE=ThinkPad T60/R60 series
+ ID_MODEL_FROM_DATABASE=Mobile 945GM/GMS/GME, 943/940GML Express Integrated Graphics Controller (ThinkPad R60/T60/X60 series)
 
 pci:v00008086d000027AC*
  ID_MODEL_FROM_DATABASE=Mobile 945GSE Express Memory Controller Hub
 
 pci:v00008086d000027ACsv00001775sd000011CC*
- ID_MODEL_FROM_DATABASE=CC11/CL11
+ ID_MODEL_FROM_DATABASE=Mobile 945GSE Express Memory Controller Hub (CC11/CL11)
 
 pci:v00008086d000027AD*
  ID_MODEL_FROM_DATABASE=Mobile 945GSE Express PCI Express Root Port
@@ -62808,172 +64593,184 @@ pci:v00008086d000027AE*
  ID_MODEL_FROM_DATABASE=Mobile 945GSE Express Integrated Graphics Controller
 
 pci:v00008086d000027AEsv00001775sd000011CC*
- ID_MODEL_FROM_DATABASE=CC11/CL11 integrated graphics (primary)
+ ID_MODEL_FROM_DATABASE=Mobile 945GSE Express Integrated Graphics Controller (CC11/CL11 integrated graphics (primary))
 
 pci:v00008086d000027B0*
  ID_MODEL_FROM_DATABASE=82801GH (ICH7DH) LPC Interface Bridge
 
 pci:v00008086d000027B0sv0000103Csd00002A3B*
- ID_MODEL_FROM_DATABASE=Pavilion A1512X
+ ID_MODEL_FROM_DATABASE=82801GH (ICH7DH) LPC Interface Bridge (Pavilion A1512X)
 
 pci:v00008086d000027B0sv00008086sd0000544E*
- ID_MODEL_FROM_DATABASE=DeskTop Board D945GTP
+ ID_MODEL_FROM_DATABASE=82801GH (ICH7DH) LPC Interface Bridge (DeskTop Board D945GTP)
 
 pci:v00008086d000027B8*
  ID_MODEL_FROM_DATABASE=82801GB/GR (ICH7 Family) LPC Interface Bridge
 
 pci:v00008086d000027B8sv00001028sd000001E6*
- ID_MODEL_FROM_DATABASE=PowerEdge 860
+ ID_MODEL_FROM_DATABASE=82801GB/GR (ICH7 Family) LPC Interface Bridge (PowerEdge 860)
 
 pci:v00008086d000027B8sv00001043sd00008179*
- ID_MODEL_FROM_DATABASE=P5KPL-VM Motherboard
+ ID_MODEL_FROM_DATABASE=82801GB/GR (ICH7 Family) LPC Interface Bridge (P5KPL-VM Motherboard)
 
 pci:v00008086d000027B8sv0000107Bsd00005048*
- ID_MODEL_FROM_DATABASE=E4500
+ ID_MODEL_FROM_DATABASE=82801GB/GR (ICH7 Family) LPC Interface Bridge (E4500)
+
+pci:v00008086d000027B8sv00001462sd00007418*
+ ID_MODEL_FROM_DATABASE=82801GB/GR (ICH7 Family) LPC Interface Bridge (Wind PC MS-7418)
 
 pci:v00008086d000027B8sv00001775sd000011CC*
- ID_MODEL_FROM_DATABASE=CC11/CL11
+ ID_MODEL_FROM_DATABASE=82801GB/GR (ICH7 Family) LPC Interface Bridge (CC11/CL11)
 
 pci:v00008086d000027B8sv00008086sd0000544E*
- ID_MODEL_FROM_DATABASE=DeskTop Board D945GTP
+ ID_MODEL_FROM_DATABASE=82801GB/GR (ICH7 Family) LPC Interface Bridge (DeskTop Board D945GTP)
 
 pci:v00008086d000027B9*
  ID_MODEL_FROM_DATABASE=82801GBM (ICH7-M) LPC Interface Bridge
 
 pci:v00008086d000027B9sv00001028sd000001D7*
- ID_MODEL_FROM_DATABASE=XPS M1210
+ ID_MODEL_FROM_DATABASE=82801GBM (ICH7-M) LPC Interface Bridge (XPS M1210)
 
 pci:v00008086d000027B9sv0000103Csd0000309F*
- ID_MODEL_FROM_DATABASE=Compaq nx9420 Notebook
+ ID_MODEL_FROM_DATABASE=82801GBM (ICH7-M) LPC Interface Bridge (Compaq nx9420 Notebook)
 
 pci:v00008086d000027B9sv0000103Csd000030A1*
- ID_MODEL_FROM_DATABASE=NC2400
+ ID_MODEL_FROM_DATABASE=82801GBM (ICH7-M) LPC Interface Bridge (NC2400)
 
 pci:v00008086d000027B9sv0000103Csd000030A3*
- ID_MODEL_FROM_DATABASE=Compaq nw8440
+ ID_MODEL_FROM_DATABASE=82801GBM (ICH7-M) LPC Interface Bridge (Compaq nw8440)
+
+pci:v00008086d000027B9sv00001071sd00008209*
+ ID_MODEL_FROM_DATABASE=82801GBM (ICH7-M) LPC Interface Bridge (Medion MIM 2240 Notebook PC [MD98100])
 
 pci:v00008086d000027B9sv000010F7sd00008338*
- ID_MODEL_FROM_DATABASE=Panasonic CF-Y5 laptop
+ ID_MODEL_FROM_DATABASE=82801GBM (ICH7-M) LPC Interface Bridge (Panasonic CF-Y5 laptop)
 
 pci:v00008086d000027B9sv000017AAsd00002009*
- ID_MODEL_FROM_DATABASE=ThinkPad T60/R60 series
+ ID_MODEL_FROM_DATABASE=82801GBM (ICH7-M) LPC Interface Bridge (ThinkPad R60/T60/X60 series)
 
 pci:v00008086d000027BC*
  ID_MODEL_FROM_DATABASE=NM10 Family LPC Controller
 
 pci:v00008086d000027BCsv0000105Bsd00000D7C*
- ID_MODEL_FROM_DATABASE=D270S/D250S Motherboard
+ ID_MODEL_FROM_DATABASE=NM10 Family LPC Controller (D270S/D250S Motherboard)
 
 pci:v00008086d000027BCsv0000144Dsd0000C072*
- ID_MODEL_FROM_DATABASE=Notebook N150P
+ ID_MODEL_FROM_DATABASE=NM10 Family LPC Controller (Notebook N150P)
 
 pci:v00008086d000027BCsv00001458sd00005001*
- ID_MODEL_FROM_DATABASE=GA-D525TUD
+ ID_MODEL_FROM_DATABASE=NM10 Family LPC Controller (GA-D525TUD)
 
 pci:v00008086d000027BCsv00008086sd00004F4D*
- ID_MODEL_FROM_DATABASE=DeskTop Board D510MO
+ ID_MODEL_FROM_DATABASE=NM10 Family LPC Controller (DeskTop Board D510MO)
 
 pci:v00008086d000027BCsv00008086sd0000544B*
- ID_MODEL_FROM_DATABASE=Desktop Board D425KT
+ ID_MODEL_FROM_DATABASE=NM10 Family LPC Controller (Desktop Board D425KT)
 
 pci:v00008086d000027BD*
  ID_MODEL_FROM_DATABASE=82801GHM (ICH7-M DH) LPC Interface Bridge
 
 pci:v00008086d000027BDsv00001025sd0000006C*
- ID_MODEL_FROM_DATABASE=9814 WKMI
+ ID_MODEL_FROM_DATABASE=82801GHM (ICH7-M DH) LPC Interface Bridge (9814 WKMI)
 
 pci:v00008086d000027C0*
  ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SATA Controller [IDE mode]
 
 pci:v00008086d000027C0sv00001028sd000001AD*
- ID_MODEL_FROM_DATABASE=OptiPlex GX620
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SATA Controller [IDE mode] (OptiPlex GX620)
 
 pci:v00008086d000027C0sv00001028sd000001DF*
- ID_MODEL_FROM_DATABASE=PowerEdge SC440
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SATA Controller [IDE mode] (PowerEdge SC440)
 
 pci:v00008086d000027C0sv00001028sd000001E6*
- ID_MODEL_FROM_DATABASE=PowerEdge 860
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SATA Controller [IDE mode] (PowerEdge 860)
 
 pci:v00008086d000027C0sv00001043sd00008179*
- ID_MODEL_FROM_DATABASE=P5KPL-VM Motherboard
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SATA Controller [IDE mode] (P5KPL-VM Motherboard)
 
 pci:v00008086d000027C0sv0000107Bsd00005048*
- ID_MODEL_FROM_DATABASE=E4500
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SATA Controller [IDE mode] (E4500)
 
 pci:v00008086d000027C0sv00001462sd00002310*
- ID_MODEL_FROM_DATABASE=MSI Hetis 945
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SATA Controller [IDE mode] (MSI Hetis 945)
 
 pci:v00008086d000027C0sv00001462sd00007236*
- ID_MODEL_FROM_DATABASE=945P Neo3-F Rev. 2.2 motherboard
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SATA Controller [IDE mode] (945P Neo3-F Rev. 2.2 motherboard)
+
+pci:v00008086d000027C0sv00001462sd00007418*
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SATA Controller [IDE mode] (Wind PC MS-7418)
 
 pci:v00008086d000027C0sv00001775sd000011CC*
- ID_MODEL_FROM_DATABASE=CC11/CL11
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SATA Controller [IDE mode] (CC11/CL11)
 
 pci:v00008086d000027C0sv00008086sd0000544B*
- ID_MODEL_FROM_DATABASE=Desktop Board D425KT
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SATA Controller [IDE mode] (Desktop Board D425KT)
 
 pci:v00008086d000027C0sv00008086sd0000544E*
- ID_MODEL_FROM_DATABASE=DeskTop Board D945GTP
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SATA Controller [IDE mode] (DeskTop Board D945GTP)
 
 pci:v00008086d000027C1*
  ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SATA Controller [AHCI mode]
 
 pci:v00008086d000027C1sv00001028sd000001DF*
- ID_MODEL_FROM_DATABASE=PowerEdge SC440
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SATA Controller [AHCI mode] (PowerEdge SC440)
 
 pci:v00008086d000027C1sv0000103Csd00002A3B*
- ID_MODEL_FROM_DATABASE=Pavilion A1512X
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SATA Controller [AHCI mode] (Pavilion A1512X)
 
 pci:v00008086d000027C1sv0000105Bsd00000D7C*
- ID_MODEL_FROM_DATABASE=D270S/D250S Motherboard
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SATA Controller [AHCI mode] (D270S/D250S Motherboard)
 
 pci:v00008086d000027C1sv0000144Dsd0000C072*
- ID_MODEL_FROM_DATABASE=Notebook N150P
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SATA Controller [AHCI mode] (Notebook N150P)
 
 pci:v00008086d000027C1sv00001458sd0000B005*
- ID_MODEL_FROM_DATABASE=GA-D525TUD
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SATA Controller [AHCI mode] (GA-D525TUD)
 
 pci:v00008086d000027C1sv00001775sd000011CC*
- ID_MODEL_FROM_DATABASE=CC11/CL11
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SATA Controller [AHCI mode] (CC11/CL11)
 
 pci:v00008086d000027C1sv00008086sd00004F4D*
- ID_MODEL_FROM_DATABASE=DeskTop Board D510MO
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SATA Controller [AHCI mode] (DeskTop Board D510MO)
 
 pci:v00008086d000027C1sv00008086sd00005842*
- ID_MODEL_FROM_DATABASE=DeskTop Board D975XBX
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SATA Controller [AHCI mode] (DeskTop Board D975XBX)
 
 pci:v00008086d000027C3*
  ID_MODEL_FROM_DATABASE=82801GR/GDH (ICH7R/ICH7DH) SATA Controller [RAID mode]
 
 pci:v00008086d000027C3sv00001775sd000011CC*
- ID_MODEL_FROM_DATABASE=CC11/CL11
+ ID_MODEL_FROM_DATABASE=82801GR/GDH (ICH7R/ICH7DH) SATA Controller [RAID mode] (CC11/CL11)
 
 pci:v00008086d000027C3sv00008086sd0000544E*
- ID_MODEL_FROM_DATABASE=DeskTop Board D945GTP
+ ID_MODEL_FROM_DATABASE=82801GR/GDH (ICH7R/ICH7DH) SATA Controller [RAID mode] (DeskTop Board D945GTP)
 
 pci:v00008086d000027C4*
  ID_MODEL_FROM_DATABASE=82801GBM/GHM (ICH7-M Family) SATA Controller [IDE mode]
 
 pci:v00008086d000027C4sv00001025sd0000006C*
- ID_MODEL_FROM_DATABASE=9814 WKMI
+ ID_MODEL_FROM_DATABASE=82801GBM/GHM (ICH7-M Family) SATA Controller [IDE mode] (9814 WKMI)
 
 pci:v00008086d000027C4sv00001028sd000001D7*
- ID_MODEL_FROM_DATABASE=XPS M1210
+ ID_MODEL_FROM_DATABASE=82801GBM/GHM (ICH7-M Family) SATA Controller [IDE mode] (XPS M1210)
+
+pci:v00008086d000027C4sv00001071sd00008209*
+ ID_MODEL_FROM_DATABASE=82801GBM/GHM (ICH7-M Family) SATA Controller [IDE mode] (Medion MIM 2240 Notebook PC [MD98100])
 
 pci:v00008086d000027C4sv000017AAsd0000200E*
- ID_MODEL_FROM_DATABASE=Thinkpad T60 model 2007
+ ID_MODEL_FROM_DATABASE=82801GBM/GHM (ICH7-M Family) SATA Controller [IDE mode] (ThinkPad T60)
 
 pci:v00008086d000027C5*
  ID_MODEL_FROM_DATABASE=82801GBM/GHM (ICH7-M Family) SATA Controller [AHCI mode]
 
 pci:v00008086d000027C5sv0000103Csd0000309F*
- ID_MODEL_FROM_DATABASE=Compaq nx9420 Notebook
+ ID_MODEL_FROM_DATABASE=82801GBM/GHM (ICH7-M Family) SATA Controller [AHCI mode] (Compaq nx9420 Notebook)
 
 pci:v00008086d000027C5sv0000103Csd000030A3*
- ID_MODEL_FROM_DATABASE=Compaq nw8440
+ ID_MODEL_FROM_DATABASE=82801GBM/GHM (ICH7-M Family) SATA Controller [AHCI mode] (Compaq nw8440)
 
 pci:v00008086d000027C5sv000017AAsd0000200D*
- ID_MODEL_FROM_DATABASE=ThinkPad T60/R60 series
+ ID_MODEL_FROM_DATABASE=82801GBM/GHM (ICH7-M Family) SATA Controller [AHCI mode] (ThinkPad R60/T60/X60 series)
 
 pci:v00008086d000027C6*
  ID_MODEL_FROM_DATABASE=82801GHM (ICH7-M DH) SATA Controller [RAID mode]
@@ -62982,520 +64779,586 @@ pci:v00008086d000027C8*
  ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #1
 
 pci:v00008086d000027C8sv00001025sd0000006C*
- ID_MODEL_FROM_DATABASE=9814 WKMI
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #1 (9814 WKMI)
 
 pci:v00008086d000027C8sv00001028sd000001AD*
- ID_MODEL_FROM_DATABASE=OptiPlex GX620
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #1 (OptiPlex GX620)
 
 pci:v00008086d000027C8sv00001028sd000001D7*
- ID_MODEL_FROM_DATABASE=XPS M1210
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #1 (XPS M1210)
 
 pci:v00008086d000027C8sv00001028sd000001DF*
- ID_MODEL_FROM_DATABASE=PowerEdge SC440
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #1 (PowerEdge SC440)
 
 pci:v00008086d000027C8sv00001028sd000001E6*
- ID_MODEL_FROM_DATABASE=PowerEdge 860
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #1 (PowerEdge 860)
 
 pci:v00008086d000027C8sv0000103Csd00002A3B*
- ID_MODEL_FROM_DATABASE=Pavilion A1512X
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #1 (Pavilion A1512X)
 
 pci:v00008086d000027C8sv0000103Csd0000309F*
- ID_MODEL_FROM_DATABASE=Compaq nx9420 Notebook
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #1 (Compaq nx9420 Notebook)
 
 pci:v00008086d000027C8sv0000103Csd000030A1*
- ID_MODEL_FROM_DATABASE=NC2400
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #1 (NC2400)
 
 pci:v00008086d000027C8sv0000103Csd000030A3*
- ID_MODEL_FROM_DATABASE=Compaq nw8440
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #1 (Compaq nw8440)
 
 pci:v00008086d000027C8sv00001043sd00001237*
- ID_MODEL_FROM_DATABASE=A6J-Q008
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #1 (A6J-Q008)
 
 pci:v00008086d000027C8sv00001043sd00008179*
- ID_MODEL_FROM_DATABASE=P5KPL-VM,P5LD2-VM Mainboard
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #1 (P5KPL-VM,P5LD2-VM Mainboard)
 
 pci:v00008086d000027C8sv0000105Bsd00000D7C*
- ID_MODEL_FROM_DATABASE=D270S/D250S Motherboard
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #1 (D270S/D250S Motherboard)
+
+pci:v00008086d000027C8sv00001071sd00008209*
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #1 (Medion MIM 2240 Notebook PC [MD98100])
 
 pci:v00008086d000027C8sv0000107Bsd00005048*
- ID_MODEL_FROM_DATABASE=E4500
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #1 (E4500)
 
 pci:v00008086d000027C8sv0000144Dsd0000C072*
- ID_MODEL_FROM_DATABASE=Notebook N150P
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #1 (Notebook N150P)
 
 pci:v00008086d000027C8sv00001458sd00005004*
- ID_MODEL_FROM_DATABASE=GA-D525TUD
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #1 (GA-D525TUD)
+
+pci:v00008086d000027C8sv00001462sd00007418*
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #1 (Wind PC MS-7418)
 
 pci:v00008086d000027C8sv00001775sd000011CC*
- ID_MODEL_FROM_DATABASE=CC11/CL11
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #1 (CC11/CL11)
 
 pci:v00008086d000027C8sv000017AAsd0000200A*
- ID_MODEL_FROM_DATABASE=ThinkPad T60/R60 series
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #1 (ThinkPad R60/T60/X60 series)
 
 pci:v00008086d000027C8sv00008086sd00004F4D*
- ID_MODEL_FROM_DATABASE=DeskTop Board D510MO
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #1 (DeskTop Board D510MO)
 
 pci:v00008086d000027C8sv00008086sd0000544B*
- ID_MODEL_FROM_DATABASE=Desktop Board D425KT
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #1 (Desktop Board D425KT)
 
 pci:v00008086d000027C8sv00008086sd0000544E*
- ID_MODEL_FROM_DATABASE=DeskTop Board D945GTP
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #1 (DeskTop Board D945GTP)
 
 pci:v00008086d000027C9*
  ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #2
 
 pci:v00008086d000027C9sv00001025sd0000006C*
- ID_MODEL_FROM_DATABASE=9814 WKMI
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #2 (9814 WKMI)
 
 pci:v00008086d000027C9sv00001028sd000001AD*
- ID_MODEL_FROM_DATABASE=OptiPlex GX620
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #2 (OptiPlex GX620)
 
 pci:v00008086d000027C9sv00001028sd000001D7*
- ID_MODEL_FROM_DATABASE=XPS M1210
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #2 (XPS M1210)
 
 pci:v00008086d000027C9sv00001028sd000001DF*
- ID_MODEL_FROM_DATABASE=PowerEdge SC440
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #2 (PowerEdge SC440)
 
 pci:v00008086d000027C9sv00001028sd000001E6*
- ID_MODEL_FROM_DATABASE=PowerEdge 860
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #2 (PowerEdge 860)
 
 pci:v00008086d000027C9sv0000103Csd00002A3B*
- ID_MODEL_FROM_DATABASE=Pavilion A1512X
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #2 (Pavilion A1512X)
 
 pci:v00008086d000027C9sv0000103Csd0000309F*
- ID_MODEL_FROM_DATABASE=Compaq nx9420 Notebook
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #2 (Compaq nx9420 Notebook)
 
 pci:v00008086d000027C9sv0000103Csd000030A1*
- ID_MODEL_FROM_DATABASE=NC2400
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #2 (NC2400)
 
 pci:v00008086d000027C9sv0000103Csd000030A3*
- ID_MODEL_FROM_DATABASE=Compaq nw8440
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #2 (Compaq nw8440)
 
 pci:v00008086d000027C9sv00001043sd00001237*
- ID_MODEL_FROM_DATABASE=A6J-Q008
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #2 (A6J-Q008)
 
 pci:v00008086d000027C9sv00001043sd00008179*
- ID_MODEL_FROM_DATABASE=P5KPL-VM,P5LD2-VM Mainboard
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #2 (P5KPL-VM,P5LD2-VM Mainboard)
 
 pci:v00008086d000027C9sv0000105Bsd00000D7C*
- ID_MODEL_FROM_DATABASE=D270S/D250S Motherboard
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #2 (D270S/D250S Motherboard)
+
+pci:v00008086d000027C9sv00001071sd00008209*
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #2 (Medion MIM 2240 Notebook PC [MD98100])
 
 pci:v00008086d000027C9sv0000107Bsd00005048*
- ID_MODEL_FROM_DATABASE=E4500
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #2 (E4500)
 
 pci:v00008086d000027C9sv0000144Dsd0000C072*
- ID_MODEL_FROM_DATABASE=Notebook N150P
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #2 (Notebook N150P)
 
 pci:v00008086d000027C9sv00001458sd00005004*
- ID_MODEL_FROM_DATABASE=GA-D525TUD
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #2 (GA-D525TUD)
+
+pci:v00008086d000027C9sv00001462sd00007418*
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #2 (Wind PC MS-7418)
 
 pci:v00008086d000027C9sv00001775sd000011CC*
- ID_MODEL_FROM_DATABASE=CC11/CL11
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #2 (CC11/CL11)
 
 pci:v00008086d000027C9sv000017AAsd0000200A*
- ID_MODEL_FROM_DATABASE=ThinkPad T60/R60 series
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #2 (ThinkPad R60/T60/X60 series)
 
 pci:v00008086d000027C9sv00008086sd00004F4D*
- ID_MODEL_FROM_DATABASE=DeskTop Board D510MO
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #2 (DeskTop Board D510MO)
 
 pci:v00008086d000027C9sv00008086sd0000544B*
- ID_MODEL_FROM_DATABASE=Desktop Board D425KT
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #2 (Desktop Board D425KT)
 
 pci:v00008086d000027C9sv00008086sd0000544E*
- ID_MODEL_FROM_DATABASE=DeskTop Board D945GTP
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #2 (DeskTop Board D945GTP)
 
 pci:v00008086d000027CA*
  ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #3
 
 pci:v00008086d000027CAsv00001025sd0000006C*
- ID_MODEL_FROM_DATABASE=9814 WKMI
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #3 (9814 WKMI)
 
 pci:v00008086d000027CAsv00001028sd000001AD*
- ID_MODEL_FROM_DATABASE=OptiPlex GX620
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #3 (OptiPlex GX620)
 
 pci:v00008086d000027CAsv00001028sd000001D7*
- ID_MODEL_FROM_DATABASE=XPS M1210
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #3 (XPS M1210)
 
 pci:v00008086d000027CAsv00001028sd000001DF*
- ID_MODEL_FROM_DATABASE=PowerEdge SC440
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #3 (PowerEdge SC440)
 
 pci:v00008086d000027CAsv00001028sd000001E6*
- ID_MODEL_FROM_DATABASE=PowerEdge 860
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #3 (PowerEdge 860)
 
 pci:v00008086d000027CAsv0000103Csd00002A3B*
- ID_MODEL_FROM_DATABASE=Pavilion A1512X
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #3 (Pavilion A1512X)
 
 pci:v00008086d000027CAsv0000103Csd0000309F*
- ID_MODEL_FROM_DATABASE=Compaq nx9420 Notebook
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #3 (Compaq nx9420 Notebook)
 
 pci:v00008086d000027CAsv0000103Csd000030A1*
- ID_MODEL_FROM_DATABASE=NC2400
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #3 (NC2400)
 
 pci:v00008086d000027CAsv0000103Csd000030A3*
- ID_MODEL_FROM_DATABASE=Compaq nw8440
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #3 (Compaq nw8440)
 
 pci:v00008086d000027CAsv00001043sd00001237*
- ID_MODEL_FROM_DATABASE=A6J-Q008
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #3 (A6J-Q008)
 
 pci:v00008086d000027CAsv00001043sd00008179*
- ID_MODEL_FROM_DATABASE=P5KPL-VM,P5LD2-VM Mainboard
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #3 (P5KPL-VM,P5LD2-VM Mainboard)
 
 pci:v00008086d000027CAsv0000105Bsd00000D7C*
- ID_MODEL_FROM_DATABASE=D270S/D250S Motherboard
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #3 (D270S/D250S Motherboard)
+
+pci:v00008086d000027CAsv00001071sd00008209*
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #3 (Medion MIM 2240 Notebook PC [MD98100])
 
 pci:v00008086d000027CAsv0000107Bsd00005048*
- ID_MODEL_FROM_DATABASE=E4500
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #3 (E4500)
 
 pci:v00008086d000027CAsv0000144Dsd0000C072*
- ID_MODEL_FROM_DATABASE=Notebook N150P
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #3 (Notebook N150P)
 
 pci:v00008086d000027CAsv00001458sd00005004*
- ID_MODEL_FROM_DATABASE=GA-D525TUD
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #3 (GA-D525TUD)
+
+pci:v00008086d000027CAsv00001462sd00007418*
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #3 (Wind PC MS-7418)
 
 pci:v00008086d000027CAsv00001775sd000011CC*
- ID_MODEL_FROM_DATABASE=CC11/CL11
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #3 (CC11/CL11)
 
 pci:v00008086d000027CAsv000017AAsd0000200A*
- ID_MODEL_FROM_DATABASE=ThinkPad T60/R60 series
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #3 (ThinkPad R60/T60/X60 series)
 
 pci:v00008086d000027CAsv00008086sd00004F4D*
- ID_MODEL_FROM_DATABASE=DeskTop Board D510MO
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #3 (DeskTop Board D510MO)
 
 pci:v00008086d000027CAsv00008086sd0000544E*
- ID_MODEL_FROM_DATABASE=DeskTop Board D945GTP
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #3 (DeskTop Board D945GTP)
 
 pci:v00008086d000027CB*
  ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #4
 
 pci:v00008086d000027CBsv00001025sd0000006C*
- ID_MODEL_FROM_DATABASE=9814 WKMI
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #4 (9814 WKMI)
 
 pci:v00008086d000027CBsv00001028sd000001AD*
- ID_MODEL_FROM_DATABASE=OptiPlex GX620
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #4 (OptiPlex GX620)
 
 pci:v00008086d000027CBsv00001028sd000001D7*
- ID_MODEL_FROM_DATABASE=XPS M1210
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #4 (XPS M1210)
 
 pci:v00008086d000027CBsv00001028sd000001DF*
- ID_MODEL_FROM_DATABASE=PowerEdge SC440
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #4 (PowerEdge SC440)
 
 pci:v00008086d000027CBsv0000103Csd00002A3B*
- ID_MODEL_FROM_DATABASE=Pavilion A1512X
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #4 (Pavilion A1512X)
 
 pci:v00008086d000027CBsv0000103Csd0000309F*
- ID_MODEL_FROM_DATABASE=Compaq nx9420 Notebook
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #4 (Compaq nx9420 Notebook)
 
 pci:v00008086d000027CBsv0000103Csd000030A1*
- ID_MODEL_FROM_DATABASE=NC2400
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #4 (NC2400)
 
 pci:v00008086d000027CBsv0000103Csd000030A3*
- ID_MODEL_FROM_DATABASE=Compaq nw8440
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #4 (Compaq nw8440)
 
 pci:v00008086d000027CBsv00001043sd00001237*
- ID_MODEL_FROM_DATABASE=A6J-Q008
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #4 (A6J-Q008)
 
 pci:v00008086d000027CBsv00001043sd00008179*
- ID_MODEL_FROM_DATABASE=P5KPL-VM,P5LD2-VM Mainboard
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #4 (P5KPL-VM,P5LD2-VM Mainboard)
 
 pci:v00008086d000027CBsv0000105Bsd00000D7C*
- ID_MODEL_FROM_DATABASE=D270S/D250S Motherboard
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #4 (D270S/D250S Motherboard)
+
+pci:v00008086d000027CBsv00001071sd00008209*
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #4 (Medion MIM 2240 Notebook PC [MD98100])
 
 pci:v00008086d000027CBsv0000107Bsd00005048*
- ID_MODEL_FROM_DATABASE=E4500
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #4 (E4500)
 
 pci:v00008086d000027CBsv0000144Dsd0000C072*
- ID_MODEL_FROM_DATABASE=Notebook N150P
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #4 (Notebook N150P)
 
 pci:v00008086d000027CBsv00001458sd00005004*
- ID_MODEL_FROM_DATABASE=GA-D525TUD
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #4 (GA-D525TUD)
+
+pci:v00008086d000027CBsv00001462sd00007418*
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #4 (Wind PC MS-7418)
 
 pci:v00008086d000027CBsv00001775sd000011CC*
- ID_MODEL_FROM_DATABASE=CC11/CL11
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #4 (CC11/CL11)
 
 pci:v00008086d000027CBsv000017AAsd0000200A*
- ID_MODEL_FROM_DATABASE=ThinkPad T60/R60 series
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #4 (ThinkPad R60/T60/X60 series)
 
 pci:v00008086d000027CBsv00008086sd00004F4D*
- ID_MODEL_FROM_DATABASE=DeskTop Board D510MO
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #4 (DeskTop Board D510MO)
 
 pci:v00008086d000027CBsv00008086sd0000544E*
- ID_MODEL_FROM_DATABASE=DeskTop Board D945GTP
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB UHCI Controller #4 (DeskTop Board D945GTP)
 
 pci:v00008086d000027CC*
  ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB2 EHCI Controller
 
 pci:v00008086d000027CCsv00001025sd0000006C*
- ID_MODEL_FROM_DATABASE=9814 WKMI
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB2 EHCI Controller (9814 WKMI)
 
 pci:v00008086d000027CCsv00001028sd000001AD*
- ID_MODEL_FROM_DATABASE=OptiPlex GX620
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB2 EHCI Controller (OptiPlex GX620)
 
 pci:v00008086d000027CCsv00001028sd000001D7*
- ID_MODEL_FROM_DATABASE=XPS M1210
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB2 EHCI Controller (XPS M1210)
 
 pci:v00008086d000027CCsv00001028sd000001DF*
- ID_MODEL_FROM_DATABASE=PowerEdge SC440
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB2 EHCI Controller (PowerEdge SC440)
 
 pci:v00008086d000027CCsv00001028sd000001E6*
- ID_MODEL_FROM_DATABASE=PowerEdge 860
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB2 EHCI Controller (PowerEdge 860)
 
 pci:v00008086d000027CCsv0000103Csd00002A3B*
- ID_MODEL_FROM_DATABASE=Pavilion A1512X
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB2 EHCI Controller (Pavilion A1512X)
 
 pci:v00008086d000027CCsv0000103Csd0000309F*
- ID_MODEL_FROM_DATABASE=Compaq nx9420 Notebook
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB2 EHCI Controller (Compaq nx9420 Notebook)
 
 pci:v00008086d000027CCsv0000103Csd000030A1*
- ID_MODEL_FROM_DATABASE=NC2400
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB2 EHCI Controller (NC2400)
 
 pci:v00008086d000027CCsv0000103Csd000030A3*
- ID_MODEL_FROM_DATABASE=Compaq nw8440
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB2 EHCI Controller (Compaq nw8440)
 
 pci:v00008086d000027CCsv00001043sd00001237*
- ID_MODEL_FROM_DATABASE=A6J-Q008
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB2 EHCI Controller (A6J-Q008)
 
 pci:v00008086d000027CCsv00001043sd00008179*
- ID_MODEL_FROM_DATABASE=P5KPL-VM,P5LD2-VM Mainboard
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB2 EHCI Controller (P5KPL-VM,P5LD2-VM Mainboard)
 
 pci:v00008086d000027CCsv0000105Bsd00000D7C*
- ID_MODEL_FROM_DATABASE=D270S/D250S Motherboard
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB2 EHCI Controller (D270S/D250S Motherboard)
+
+pci:v00008086d000027CCsv00001071sd00008209*
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB2 EHCI Controller (Medion MIM 2240 Notebook PC [MD98100])
 
 pci:v00008086d000027CCsv0000144Dsd0000C072*
- ID_MODEL_FROM_DATABASE=Notebook N150P
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB2 EHCI Controller (Notebook N150P)
 
 pci:v00008086d000027CCsv00001458sd00005006*
- ID_MODEL_FROM_DATABASE=GA-D525TUD
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB2 EHCI Controller (GA-D525TUD)
+
+pci:v00008086d000027CCsv00001462sd00007418*
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB2 EHCI Controller (Wind PC MS-7418)
 
 pci:v00008086d000027CCsv00001775sd000011CC*
- ID_MODEL_FROM_DATABASE=CC11/CL11
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB2 EHCI Controller (CC11/CL11)
 
 pci:v00008086d000027CCsv000017AAsd0000200B*
- ID_MODEL_FROM_DATABASE=ThinkPad T60/R60 series
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB2 EHCI Controller (ThinkPad R60/T60/X60 series)
 
 pci:v00008086d000027CCsv00008086sd00004F4D*
- ID_MODEL_FROM_DATABASE=DeskTop Board D510MO
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB2 EHCI Controller (DeskTop Board D510MO)
 
 pci:v00008086d000027CCsv00008086sd0000544B*
- ID_MODEL_FROM_DATABASE=Desktop Board D425KT
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB2 EHCI Controller (Desktop Board D425KT)
 
 pci:v00008086d000027CCsv00008086sd0000544E*
- ID_MODEL_FROM_DATABASE=DeskTop Board D945GTP
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family USB2 EHCI Controller (DeskTop Board D945GTP)
 
 pci:v00008086d000027D0*
  ID_MODEL_FROM_DATABASE=NM10/ICH7 Family PCI Express Port 1
 
 pci:v00008086d000027D0sv0000103Csd0000309F*
- ID_MODEL_FROM_DATABASE=Compaq nx9420 Notebook
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family PCI Express Port 1 (Compaq nx9420 Notebook)
 
 pci:v00008086d000027D0sv0000103Csd000030A3*
- ID_MODEL_FROM_DATABASE=Compaq nw8440
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family PCI Express Port 1 (Compaq nw8440)
+
+pci:v00008086d000027D0sv00001071sd00008209*
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family PCI Express Port 1 (Medion MIM 2240 Notebook PC [MD98100])
 
 pci:v00008086d000027D0sv0000144Dsd0000C072*
- ID_MODEL_FROM_DATABASE=Notebook N150P
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family PCI Express Port 1 (Notebook N150P)
 
 pci:v00008086d000027D0sv00001458sd00005001*
- ID_MODEL_FROM_DATABASE=GA-D525TUD
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family PCI Express Port 1 (GA-D525TUD)
+
+pci:v00008086d000027D0sv00001462sd00007418*
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family PCI Express Port 1 (Wind PC MS-7418)
 
 pci:v00008086d000027D0sv00001775sd000011CC*
- ID_MODEL_FROM_DATABASE=CC11/CL11
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family PCI Express Port 1 (CC11/CL11)
 
 pci:v00008086d000027D0sv00008086sd0000544B*
- ID_MODEL_FROM_DATABASE=Desktop Board D425KT
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family PCI Express Port 1 (Desktop Board D425KT)
 
 pci:v00008086d000027D2*
  ID_MODEL_FROM_DATABASE=NM10/ICH7 Family PCI Express Port 2
 
 pci:v00008086d000027D2sv0000103Csd0000309F*
- ID_MODEL_FROM_DATABASE=Compaq nx9420 Notebook
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family PCI Express Port 2 (Compaq nx9420 Notebook)
 
 pci:v00008086d000027D2sv0000103Csd000030A3*
- ID_MODEL_FROM_DATABASE=Compaq nw8440
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family PCI Express Port 2 (Compaq nw8440)
+
+pci:v00008086d000027D2sv00001071sd00008209*
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family PCI Express Port 2 (Medion MIM 2240 Notebook PC [MD98100])
 
 pci:v00008086d000027D2sv0000144Dsd0000C072*
- ID_MODEL_FROM_DATABASE=Notebook N150P
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family PCI Express Port 2 (Notebook N150P)
+
+pci:v00008086d000027D2sv00001462sd00007418*
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family PCI Express Port 2 (Wind PC MS-7418)
 
 pci:v00008086d000027D2sv00001775sd000011CC*
- ID_MODEL_FROM_DATABASE=CC11/CL11
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family PCI Express Port 2 (CC11/CL11)
 
 pci:v00008086d000027D2sv00008086sd0000544B*
- ID_MODEL_FROM_DATABASE=Desktop Board D425KT
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family PCI Express Port 2 (Desktop Board D425KT)
 
 pci:v00008086d000027D4*
  ID_MODEL_FROM_DATABASE=NM10/ICH7 Family PCI Express Port 3
 
+pci:v00008086d000027D4sv00001071sd00008209*
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family PCI Express Port 3 (Medion MIM 2240 Notebook PC [MD98100])
+
 pci:v00008086d000027D4sv0000144Dsd0000C072*
- ID_MODEL_FROM_DATABASE=Notebook N150P
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family PCI Express Port 3 (Notebook N150P)
+
+pci:v00008086d000027D4sv00001462sd00007418*
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family PCI Express Port 3 (Wind PC MS-7418)
 
 pci:v00008086d000027D4sv00001775sd000011CC*
- ID_MODEL_FROM_DATABASE=CC11/CL11
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family PCI Express Port 3 (CC11/CL11)
 
 pci:v00008086d000027D4sv00008086sd0000544B*
- ID_MODEL_FROM_DATABASE=Desktop Board D425KT
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family PCI Express Port 3 (Desktop Board D425KT)
 
 pci:v00008086d000027D6*
  ID_MODEL_FROM_DATABASE=NM10/ICH7 Family PCI Express Port 4
 
 pci:v00008086d000027D6sv0000103Csd000030A3*
- ID_MODEL_FROM_DATABASE=Compaq nw8440
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family PCI Express Port 4 (Compaq nw8440)
+
+pci:v00008086d000027D6sv00001071sd00008209*
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family PCI Express Port 4 (Medion MIM 2240 Notebook PC [MD98100])
 
 pci:v00008086d000027D6sv0000144Dsd0000C072*
- ID_MODEL_FROM_DATABASE=Notebook N150P
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family PCI Express Port 4 (Notebook N150P)
+
+pci:v00008086d000027D6sv00001462sd00007418*
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family PCI Express Port 4 (Wind PC MS-7418)
 
 pci:v00008086d000027D6sv00001775sd000011CC*
- ID_MODEL_FROM_DATABASE=CC11/CL11
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family PCI Express Port 4 (CC11/CL11)
 
 pci:v00008086d000027D6sv00008086sd0000544B*
- ID_MODEL_FROM_DATABASE=Desktop Board D425KT
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family PCI Express Port 4 (Desktop Board D425KT)
 
 pci:v00008086d000027D8*
  ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller
 
 pci:v00008086d000027D8sv00001025sd0000006C*
- ID_MODEL_FROM_DATABASE=9814 WKMI
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (9814 WKMI)
 
 pci:v00008086d000027D8sv00001028sd000001D7*
- ID_MODEL_FROM_DATABASE=XPS M1210
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (XPS M1210)
 
 pci:v00008086d000027D8sv0000103Csd00002A3B*
- ID_MODEL_FROM_DATABASE=Pavilion A1512X
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (Pavilion A1512X)
 
 pci:v00008086d000027D8sv0000103Csd0000309F*
- ID_MODEL_FROM_DATABASE=Compaq nx9420 Notebook
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (Compaq nx9420 Notebook)
 
 pci:v00008086d000027D8sv0000103Csd000030A1*
- ID_MODEL_FROM_DATABASE=NC2400
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (NC2400)
 
 pci:v00008086d000027D8sv0000103Csd000030A3*
- ID_MODEL_FROM_DATABASE=Compaq nw8440
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (Compaq nw8440)
 
 pci:v00008086d000027D8sv00001043sd00001123*
- ID_MODEL_FROM_DATABASE=A6J-Q008
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (A6J-Q008)
 
 pci:v00008086d000027D8sv00001043sd000013C4*
- ID_MODEL_FROM_DATABASE=Asus G2P
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (Asus G2P)
 
 pci:v00008086d000027D8sv00001043sd0000817F*
- ID_MODEL_FROM_DATABASE=P5LD2-VM Mainboard (Realtek ALC 882 codec)
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (P5LD2-VM Mainboard (Realtek ALC 882 codec))
 
 pci:v00008086d000027D8sv00001043sd00008290*
- ID_MODEL_FROM_DATABASE=P5KPL-VM Motherboard
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (P5KPL-VM Motherboard)
 
 pci:v00008086d000027D8sv00001043sd000082EA*
- ID_MODEL_FROM_DATABASE=P5KPL-CM Motherboard
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (P5KPL-CM Motherboard)
 
 pci:v00008086d000027D8sv0000105Bsd00000D7C*
- ID_MODEL_FROM_DATABASE=D270S/D250S Motherboard
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (D270S/D250S Motherboard)
+
+pci:v00008086d000027D8sv00001071sd00008207*
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (Medion MIM 2240 Notebook PC [MD98100])
 
 pci:v00008086d000027D8sv0000107Bsd00005048*
- ID_MODEL_FROM_DATABASE=E4500
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (E4500)
 
 pci:v00008086d000027D8sv000010F7sd00008338*
- ID_MODEL_FROM_DATABASE=Panasonic CF-Y5 laptop
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (Panasonic CF-Y5 laptop)
 
 pci:v00008086d000027D8sv00001179sd0000FF10*
- ID_MODEL_FROM_DATABASE=Toshiba Satellite A100-796 audio (Realtek ALC861)
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (Toshiba Satellite A100-796 audio (Realtek ALC861))
 
 pci:v00008086d000027D8sv00001179sd0000FF31*
- ID_MODEL_FROM_DATABASE=AC97 Data Fax SoftModem with SmartCP
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (AC97 Data Fax SoftModem with SmartCP)
 
 pci:v00008086d000027D8sv00001447sd00001043*
- ID_MODEL_FROM_DATABASE=Asus A8JP (Analog Devices AD1986A)
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (Asus A8JP (Analog Devices AD1986A))
 
 pci:v00008086d000027D8sv0000144Dsd0000C072*
- ID_MODEL_FROM_DATABASE=Notebook N150P
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (Notebook N150P)
 
 pci:v00008086d000027D8sv00001458sd0000A002*
- ID_MODEL_FROM_DATABASE=GA-D525TUD (Realtek ALC887)
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (GA-D525TUD (Realtek ALC887))
 
 pci:v00008086d000027D8sv00001458sd0000A102*
- ID_MODEL_FROM_DATABASE=GA-8I945PG-RH Mainboard
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (GA-8I945PG-RH Mainboard)
+
+pci:v00008086d000027D8sv00001462sd00007418*
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (Wind PC MS-7418)
 
 pci:v00008086d000027D8sv0000152Dsd00000753*
- ID_MODEL_FROM_DATABASE=Softmodem
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (Softmodem)
 
 pci:v00008086d000027D8sv00001734sd000010AD*
- ID_MODEL_FROM_DATABASE=Conexant softmodem SmartCP
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (Conexant softmodem SmartCP)
 
 pci:v00008086d000027D8sv000017AAsd00002010*
- ID_MODEL_FROM_DATABASE=ThinkPad T60/R60 series
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (ThinkPad R60/T60/X60 series)
 
 pci:v00008086d000027D8sv000017AAsd00003802*
- ID_MODEL_FROM_DATABASE=Lenovo 3000 C200 audio [Realtek ALC861VD]
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (Lenovo 3000 C200 audio [Realtek ALC861VD])
 
 pci:v00008086d000027D8sv00008086sd00001112*
- ID_MODEL_FROM_DATABASE=DeskTop Board D945GTP
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (DeskTop Board D945GTP)
 
 pci:v00008086d000027D8sv00008086sd000027D8*
- ID_MODEL_FROM_DATABASE=DeskTop Board D945GTP
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (DeskTop Board D945GTP)
 
 pci:v00008086d000027D8sv00008086sd0000D618*
- ID_MODEL_FROM_DATABASE=DeskTop Board D510MO
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (DeskTop Board D510MO)
 
 pci:v00008086d000027D8sv00008384sd00007680*
- ID_MODEL_FROM_DATABASE=STAC9221 HD Audio Codec
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (STAC9221 HD Audio Codec)
 
 pci:v00008086d000027DA*
  ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SMBus Controller
 
 pci:v00008086d000027DAsv00001025sd0000006C*
- ID_MODEL_FROM_DATABASE=9814 WKMI
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SMBus Controller (9814 WKMI)
 
 pci:v00008086d000027DAsv00001028sd000001AD*
- ID_MODEL_FROM_DATABASE=OptiPlex GX620
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SMBus Controller (OptiPlex GX620)
 
 pci:v00008086d000027DAsv00001028sd000001D7*
- ID_MODEL_FROM_DATABASE=XPS M1210
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SMBus Controller (XPS M1210)
 
 pci:v00008086d000027DAsv00001028sd000001DF*
- ID_MODEL_FROM_DATABASE=PowerEdge SC440
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SMBus Controller (PowerEdge SC440)
 
 pci:v00008086d000027DAsv00001028sd000001E6*
- ID_MODEL_FROM_DATABASE=PowerEdge 860
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SMBus Controller (PowerEdge 860)
 
 pci:v00008086d000027DAsv0000103Csd00002A3B*
- ID_MODEL_FROM_DATABASE=Pavilion A1512X
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SMBus Controller (Pavilion A1512X)
 
 pci:v00008086d000027DAsv00001043sd00008179*
- ID_MODEL_FROM_DATABASE=P5KPL-VM Motherboard
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SMBus Controller (P5KPL-VM Motherboard)
 
 pci:v00008086d000027DAsv0000105Bsd00000D7C*
- ID_MODEL_FROM_DATABASE=D270S/D250S Motherboard
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SMBus Controller (D270S/D250S Motherboard)
+
+pci:v00008086d000027DAsv00001071sd00008209*
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SMBus Controller (Medion MIM 2240 Notebook PC [MD98100])
 
 pci:v00008086d000027DAsv000010F7sd00008338*
- ID_MODEL_FROM_DATABASE=Panasonic CF-Y5 laptop
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SMBus Controller (Panasonic CF-Y5 laptop)
 
 pci:v00008086d000027DAsv0000144Dsd0000C072*
- ID_MODEL_FROM_DATABASE=Notebook N150P
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SMBus Controller (Notebook N150P)
 
 pci:v00008086d000027DAsv00001458sd00005001*
- ID_MODEL_FROM_DATABASE=GA-8I945PG-RH/GA-D525TUD Mainboard
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SMBus Controller (GA-8I945PG-RH/GA-D525TUD Mainboard)
+
+pci:v00008086d000027DAsv00001462sd00007418*
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SMBus Controller (Wind PC MS-7418)
 
 pci:v00008086d000027DAsv00001775sd000011CC*
- ID_MODEL_FROM_DATABASE=CC11/CL11
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SMBus Controller (CC11/CL11)
 
 pci:v00008086d000027DAsv000017AAsd0000200F*
- ID_MODEL_FROM_DATABASE=ThinkPad T60/R60 series
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SMBus Controller (ThinkPad R60/T60/X60 series)
 
 pci:v00008086d000027DAsv00008086sd00004F4D*
- ID_MODEL_FROM_DATABASE=DeskTop Board D510MO
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SMBus Controller (DeskTop Board D510MO)
 
 pci:v00008086d000027DAsv00008086sd0000544B*
- ID_MODEL_FROM_DATABASE=Desktop Board D425KT
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SMBus Controller (Desktop Board D425KT)
 
 pci:v00008086d000027DAsv00008086sd0000544E*
- ID_MODEL_FROM_DATABASE=DeskTop Board D945GTP
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SMBus Controller (DeskTop Board D945GTP)
 
 pci:v00008086d000027DAsv00008086sd00005842*
- ID_MODEL_FROM_DATABASE=DeskTop Board D975XBX
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family SMBus Controller (DeskTop Board D975XBX)
 
 pci:v00008086d000027DC*
  ID_MODEL_FROM_DATABASE=NM10/ICH7 Family LAN Controller
 
 pci:v00008086d000027DCsv0000103Csd00002A3B*
- ID_MODEL_FROM_DATABASE=Pavilion A1512X
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family LAN Controller (Pavilion A1512X)
 
 pci:v00008086d000027DCsv00008086sd0000308D*
- ID_MODEL_FROM_DATABASE=DeskTop Board D945GTP
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family LAN Controller (DeskTop Board D945GTP)
 
 pci:v00008086d000027DD*
  ID_MODEL_FROM_DATABASE=82801G (ICH7 Family) AC'97 Modem Controller
@@ -63504,85 +65367,88 @@ pci:v00008086d000027DE*
  ID_MODEL_FROM_DATABASE=82801G (ICH7 Family) AC'97 Audio Controller
 
 pci:v00008086d000027DEsv00001028sd000001AD*
- ID_MODEL_FROM_DATABASE=OptiPlex GX620
+ ID_MODEL_FROM_DATABASE=82801G (ICH7 Family) AC'97 Audio Controller (OptiPlex GX620)
 
 pci:v00008086d000027DEsv00001462sd00007267*
- ID_MODEL_FROM_DATABASE=Realtek ALC883 Audio Controller
+ ID_MODEL_FROM_DATABASE=82801G (ICH7 Family) AC'97 Audio Controller (Realtek ALC883 Audio Controller)
 
 pci:v00008086d000027DEsv00001775sd000011CC*
- ID_MODEL_FROM_DATABASE=CC11 integrated audio (AD1981BL codec)
+ ID_MODEL_FROM_DATABASE=82801G (ICH7 Family) AC'97 Audio Controller (CC11 integrated audio (AD1981BL codec))
 
 pci:v00008086d000027DF*
  ID_MODEL_FROM_DATABASE=82801G (ICH7 Family) IDE Controller
 
 pci:v00008086d000027DFsv00001028sd000001DF*
- ID_MODEL_FROM_DATABASE=PowerEdge SC440
+ ID_MODEL_FROM_DATABASE=82801G (ICH7 Family) IDE Controller (PowerEdge SC440)
 
 pci:v00008086d000027DFsv00001028sd000001E6*
- ID_MODEL_FROM_DATABASE=PowerEdge 860
+ ID_MODEL_FROM_DATABASE=82801G (ICH7 Family) IDE Controller (PowerEdge 860)
 
 pci:v00008086d000027DFsv0000103Csd00002A3B*
- ID_MODEL_FROM_DATABASE=Pavilion A1512X
+ ID_MODEL_FROM_DATABASE=82801G (ICH7 Family) IDE Controller (Pavilion A1512X)
 
 pci:v00008086d000027DFsv0000103Csd0000309F*
- ID_MODEL_FROM_DATABASE=Compaq nx9420 Notebook
+ ID_MODEL_FROM_DATABASE=82801G (ICH7 Family) IDE Controller (Compaq nx9420 Notebook)
 
 pci:v00008086d000027DFsv0000103Csd000030A1*
- ID_MODEL_FROM_DATABASE=NC2400
+ ID_MODEL_FROM_DATABASE=82801G (ICH7 Family) IDE Controller (NC2400)
 
 pci:v00008086d000027DFsv0000103Csd000030A3*
- ID_MODEL_FROM_DATABASE=Compaq nw8440
+ ID_MODEL_FROM_DATABASE=82801G (ICH7 Family) IDE Controller (Compaq nw8440)
 
 pci:v00008086d000027DFsv00001043sd00001237*
- ID_MODEL_FROM_DATABASE=A6J-Q008
+ ID_MODEL_FROM_DATABASE=82801G (ICH7 Family) IDE Controller (A6J-Q008)
 
 pci:v00008086d000027DFsv00001043sd00008179*
- ID_MODEL_FROM_DATABASE=P5KPL-VM Motherboard
+ ID_MODEL_FROM_DATABASE=82801G (ICH7 Family) IDE Controller (P5KPL-VM Motherboard)
 
 pci:v00008086d000027DFsv0000107Bsd00005048*
- ID_MODEL_FROM_DATABASE=E4500
+ ID_MODEL_FROM_DATABASE=82801G (ICH7 Family) IDE Controller (E4500)
 
 pci:v00008086d000027DFsv000010F7sd00008338*
- ID_MODEL_FROM_DATABASE=Panasonic CF-Y5 laptop
+ ID_MODEL_FROM_DATABASE=82801G (ICH7 Family) IDE Controller (Panasonic CF-Y5 laptop)
+
+pci:v00008086d000027DFsv00001462sd00007418*
+ ID_MODEL_FROM_DATABASE=82801G (ICH7 Family) IDE Controller (Wind PC MS-7418)
 
 pci:v00008086d000027DFsv00001775sd000011CC*
- ID_MODEL_FROM_DATABASE=CC11/CL11
+ ID_MODEL_FROM_DATABASE=82801G (ICH7 Family) IDE Controller (CC11/CL11)
 
 pci:v00008086d000027DFsv000017AAsd0000200C*
- ID_MODEL_FROM_DATABASE=ThinkPad T60/R60 series
+ ID_MODEL_FROM_DATABASE=82801G (ICH7 Family) IDE Controller (ThinkPad R60/T60/X60 series)
 
 pci:v00008086d000027DFsv00008086sd0000544E*
- ID_MODEL_FROM_DATABASE=DeskTop Board D945GTP
+ ID_MODEL_FROM_DATABASE=82801G (ICH7 Family) IDE Controller (DeskTop Board D945GTP)
 
 pci:v00008086d000027E0*
  ID_MODEL_FROM_DATABASE=82801GR/GH/GHM (ICH7 Family) PCI Express Port 5
 
 pci:v00008086d000027E0sv00001775sd000011CC*
- ID_MODEL_FROM_DATABASE=CC11/CL11
+ ID_MODEL_FROM_DATABASE=82801GR/GH/GHM (ICH7 Family) PCI Express Port 5 (CC11/CL11)
 
 pci:v00008086d000027E2*
  ID_MODEL_FROM_DATABASE=82801GR/GH/GHM (ICH7 Family) PCI Express Port 6
 
 pci:v00008086d000027E2sv00001775sd000011CC*
- ID_MODEL_FROM_DATABASE=CC11/CL11
+ ID_MODEL_FROM_DATABASE=82801GR/GH/GHM (ICH7 Family) PCI Express Port 6 (CC11/CL11)
 
 pci:v00008086d00002810*
  ID_MODEL_FROM_DATABASE=82801HB/HR (ICH8/R) LPC Interface Controller
 
 pci:v00008086d00002810sv00001043sd000081EC*
- ID_MODEL_FROM_DATABASE=P5B
+ ID_MODEL_FROM_DATABASE=82801HB/HR (ICH8/R) LPC Interface Controller (P5B)
 
 pci:v00008086d00002811*
  ID_MODEL_FROM_DATABASE=82801HEM (ICH8M-E) LPC Interface Controller
 
 pci:v00008086d00002811sv0000103Csd000030C1*
- ID_MODEL_FROM_DATABASE=Compaq 6910p
+ ID_MODEL_FROM_DATABASE=82801HEM (ICH8M-E) LPC Interface Controller (Compaq 6910p)
 
 pci:v00008086d00002811sv000017AAsd000020B6*
- ID_MODEL_FROM_DATABASE=ThinkPad T61/R61
+ ID_MODEL_FROM_DATABASE=82801HEM (ICH8M-E) LPC Interface Controller (ThinkPad T61/R61)
 
 pci:v00008086d00002811sv0000E4BFsd0000CC47*
- ID_MODEL_FROM_DATABASE=CCG-RUMBA
+ ID_MODEL_FROM_DATABASE=82801HEM (ICH8M-E) LPC Interface Controller (CCG-RUMBA)
 
 pci:v00008086d00002812*
  ID_MODEL_FROM_DATABASE=82801HH (ICH8DH) LPC Interface Controller
@@ -63594,34 +65460,37 @@ pci:v00008086d00002815*
  ID_MODEL_FROM_DATABASE=82801HM (ICH8M) LPC Interface Controller
 
 pci:v00008086d00002815sv00001025sd00000121*
- ID_MODEL_FROM_DATABASE=Aspire 5920G
+ ID_MODEL_FROM_DATABASE=82801HM (ICH8M) LPC Interface Controller (Aspire 5920G)
 
 pci:v00008086d00002815sv00001028sd000001F3*
- ID_MODEL_FROM_DATABASE=Inspiron 1420
+ ID_MODEL_FROM_DATABASE=82801HM (ICH8M) LPC Interface Controller (Inspiron 1420)
 
 pci:v00008086d00002815sv0000103Csd000030C0*
- ID_MODEL_FROM_DATABASE=Compaq 6710b
+ ID_MODEL_FROM_DATABASE=82801HM (ICH8M) LPC Interface Controller (Compaq 6710b)
 
 pci:v00008086d00002815sv0000103Csd000030CC*
- ID_MODEL_FROM_DATABASE=Pavilion dv6700
+ ID_MODEL_FROM_DATABASE=82801HM (ICH8M) LPC Interface Controller (Pavilion dv6700)
 
 pci:v00008086d00002815sv0000103Csd000030D9*
- ID_MODEL_FROM_DATABASE=Presario C700
+ ID_MODEL_FROM_DATABASE=82801HM (ICH8M) LPC Interface Controller (Presario C700)
 
 pci:v00008086d00002815sv0000104Dsd00009005*
- ID_MODEL_FROM_DATABASE=Vaio VGN-FZ260E
+ ID_MODEL_FROM_DATABASE=82801HM (ICH8M) LPC Interface Controller (Vaio VGN-FZ260E)
 
 pci:v00008086d00002815sv0000104Dsd0000902D*
- ID_MODEL_FROM_DATABASE=VAIO VGN-NR120E
+ ID_MODEL_FROM_DATABASE=82801HM (ICH8M) LPC Interface Controller (VAIO VGN-NR120E)
+
+pci:v00008086d00002815sv000017C0sd00004083*
+ ID_MODEL_FROM_DATABASE=82801HM (ICH8M) LPC Interface Controller (Medion WIM 2210 Notebook PC [MD96850])
 
 pci:v00008086d00002820*
  ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) 4 port SATA Controller [IDE mode]
 
 pci:v00008086d00002820sv00001028sd000001DA*
- ID_MODEL_FROM_DATABASE=OptiPlex 745
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) 4 port SATA Controller [IDE mode] (OptiPlex 745)
 
 pci:v00008086d00002820sv00001462sd00007235*
- ID_MODEL_FROM_DATABASE=P965 Neo MS-7235 mainboard
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) 4 port SATA Controller [IDE mode] (P965 Neo MS-7235 mainboard)
 
 pci:v00008086d00002821*
  ID_MODEL_FROM_DATABASE=82801HR/HO/HH (ICH8R/DO/DH) 6 port SATA Controller [AHCI mode]
@@ -63630,7 +65499,10 @@ pci:v00008086d00002822*
  ID_MODEL_FROM_DATABASE=82801 SATA Controller [RAID mode]
 
 pci:v00008086d00002822sv00001028sd0000020D*
- ID_MODEL_FROM_DATABASE=Inspiron 530
+ ID_MODEL_FROM_DATABASE=82801 SATA Controller [RAID mode] (Inspiron 530)
+
+pci:v00008086d00002822sv0000103Csd00002A6F*
+ ID_MODEL_FROM_DATABASE=82801 SATA Controller [RAID mode] (Asus IPIBL-LB Motherboard)
 
 pci:v00008086d00002823*
  ID_MODEL_FROM_DATABASE=Wellsburg sSATA RAID Controller
@@ -63639,16 +65511,16 @@ pci:v00008086d00002824*
  ID_MODEL_FROM_DATABASE=82801HB (ICH8) 4 port SATA Controller [AHCI mode]
 
 pci:v00008086d00002824sv00001043sd000081EC*
- ID_MODEL_FROM_DATABASE=P5B
+ ID_MODEL_FROM_DATABASE=82801HB (ICH8) 4 port SATA Controller [AHCI mode] (P5B)
 
 pci:v00008086d00002825*
  ID_MODEL_FROM_DATABASE=82801HR/HO/HH (ICH8R/DO/DH) 2 port SATA Controller [IDE mode]
 
 pci:v00008086d00002825sv00001028sd000001DA*
- ID_MODEL_FROM_DATABASE=OptiPlex 745
+ ID_MODEL_FROM_DATABASE=82801HR/HO/HH (ICH8R/DO/DH) 2 port SATA Controller [IDE mode] (OptiPlex 745)
 
 pci:v00008086d00002825sv00001462sd00007235*
- ID_MODEL_FROM_DATABASE=P965 Neo MS-7235 mainboard
+ ID_MODEL_FROM_DATABASE=82801HR/HO/HH (ICH8R/DO/DH) 2 port SATA Controller [IDE mode] (P965 Neo MS-7235 mainboard)
 
 pci:v00008086d00002826*
  ID_MODEL_FROM_DATABASE=C600/X79 series chipset SATA RAID Controller
@@ -63660,424 +65532,466 @@ pci:v00008086d00002828*
  ID_MODEL_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) SATA Controller [IDE mode]
 
 pci:v00008086d00002828sv00001028sd000001F3*
- ID_MODEL_FROM_DATABASE=Inspiron 1420
+ ID_MODEL_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) SATA Controller [IDE mode] (Inspiron 1420)
 
 pci:v00008086d00002828sv0000103Csd000030C0*
- ID_MODEL_FROM_DATABASE=Compaq 6710b
+ ID_MODEL_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) SATA Controller [IDE mode] (Compaq 6710b)
 
 pci:v00008086d00002828sv0000E4BFsd0000CC47*
- ID_MODEL_FROM_DATABASE=CCG-RUMBA
+ ID_MODEL_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) SATA Controller [IDE mode] (CCG-RUMBA)
 
 pci:v00008086d00002829*
  ID_MODEL_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) SATA Controller [AHCI mode]
 
 pci:v00008086d00002829sv00001025sd00000121*
- ID_MODEL_FROM_DATABASE=Aspire 5920G
+ ID_MODEL_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) SATA Controller [AHCI mode] (Aspire 5920G)
 
 pci:v00008086d00002829sv0000103Csd000030C0*
- ID_MODEL_FROM_DATABASE=Compaq 6710b
+ ID_MODEL_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) SATA Controller [AHCI mode] (Compaq 6710b)
 
 pci:v00008086d00002829sv0000103Csd000030C1*
- ID_MODEL_FROM_DATABASE=Compaq 6910p
+ ID_MODEL_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) SATA Controller [AHCI mode] (Compaq 6910p)
 
 pci:v00008086d00002829sv0000103Csd000030CC*
- ID_MODEL_FROM_DATABASE=Pavilion dv6700
+ ID_MODEL_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) SATA Controller [AHCI mode] (Pavilion dv6700)
 
 pci:v00008086d00002829sv0000103Csd000030D9*
- ID_MODEL_FROM_DATABASE=Presario C700
+ ID_MODEL_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) SATA Controller [AHCI mode] (Presario C700)
 
 pci:v00008086d00002829sv0000104Dsd00009005*
- ID_MODEL_FROM_DATABASE=Vaio VGN-FZ260E
+ ID_MODEL_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) SATA Controller [AHCI mode] (Vaio VGN-FZ260E)
 
 pci:v00008086d00002829sv0000104Dsd0000902D*
- ID_MODEL_FROM_DATABASE=VAIO VGN-NR120E
+ ID_MODEL_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) SATA Controller [AHCI mode] (VAIO VGN-NR120E)
 
 pci:v00008086d00002829sv000017AAsd000020A7*
- ID_MODEL_FROM_DATABASE=ThinkPad T61/R61
+ ID_MODEL_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) SATA Controller [AHCI mode] (ThinkPad T61/R61)
+
+pci:v00008086d00002829sv000017C0sd00004083*
+ ID_MODEL_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) SATA Controller [AHCI mode] (Medion WIM 2210 Notebook PC [MD96850])
 
 pci:v00008086d00002829sv0000E4BFsd0000CC47*
- ID_MODEL_FROM_DATABASE=CCG-RUMBA
+ ID_MODEL_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) SATA Controller [AHCI mode] (CCG-RUMBA)
 
 pci:v00008086d0000282A*
  ID_MODEL_FROM_DATABASE=82801 Mobile SATA Controller [RAID mode]
 
 pci:v00008086d0000282Asv00001028sd0000040B*
- ID_MODEL_FROM_DATABASE=Latitude E6510
+ ID_MODEL_FROM_DATABASE=82801 Mobile SATA Controller [RAID mode] (Latitude E6510)
 
 pci:v00008086d0000282Asv0000E4BFsd000050C1*
- ID_MODEL_FROM_DATABASE=PC1-GROOVE
+ ID_MODEL_FROM_DATABASE=82801 Mobile SATA Controller [RAID mode] (PC1-GROOVE)
 
 pci:v00008086d00002830*
  ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #1
 
 pci:v00008086d00002830sv00001025sd00000121*
- ID_MODEL_FROM_DATABASE=Acer Aspire 5920G
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #1 (Acer Aspire 5920G)
 
 pci:v00008086d00002830sv00001028sd000001DA*
- ID_MODEL_FROM_DATABASE=OptiPlex 745
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #1 (OptiPlex 745)
 
 pci:v00008086d00002830sv00001028sd000001F3*
- ID_MODEL_FROM_DATABASE=Inspiron 1420
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #1 (Inspiron 1420)
 
 pci:v00008086d00002830sv0000103Csd000030C0*
- ID_MODEL_FROM_DATABASE=Compaq 6710b
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #1 (Compaq 6710b)
 
 pci:v00008086d00002830sv0000103Csd000030C1*
- ID_MODEL_FROM_DATABASE=Compaq 6910p
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #1 (Compaq 6910p)
 
 pci:v00008086d00002830sv0000103Csd000030CC*
- ID_MODEL_FROM_DATABASE=Pavilion dv6700
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #1 (Pavilion dv6700)
 
 pci:v00008086d00002830sv0000103Csd000030D9*
- ID_MODEL_FROM_DATABASE=Presario C700
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #1 (Presario C700)
 
 pci:v00008086d00002830sv00001043sd000081EC*
- ID_MODEL_FROM_DATABASE=P5B
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #1 (P5B)
 
 pci:v00008086d00002830sv0000104Dsd00009005*
- ID_MODEL_FROM_DATABASE=Vaio VGN-FZ260E
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #1 (Vaio VGN-FZ260E)
 
 pci:v00008086d00002830sv0000104Dsd0000902D*
- ID_MODEL_FROM_DATABASE=VAIO VGN-NR120E
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #1 (VAIO VGN-NR120E)
 
 pci:v00008086d00002830sv00001462sd00007235*
- ID_MODEL_FROM_DATABASE=P965 Neo MS-7235 mainboard
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #1 (P965 Neo MS-7235 mainboard)
 
 pci:v00008086d00002830sv000017AAsd000020AA*
- ID_MODEL_FROM_DATABASE=ThinkPad T61/R61
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #1 (ThinkPad T61/R61)
+
+pci:v00008086d00002830sv000017C0sd00004083*
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #1 (Medion WIM 2210 Notebook PC [MD96850])
 
 pci:v00008086d00002830sv0000E4BFsd0000CC47*
- ID_MODEL_FROM_DATABASE=CCG-RUMBA
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #1 (CCG-RUMBA)
 
 pci:v00008086d00002831*
  ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #2
 
 pci:v00008086d00002831sv00001025sd00000121*
- ID_MODEL_FROM_DATABASE=Aspire 5920G
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #2 (Aspire 5920G)
 
 pci:v00008086d00002831sv00001028sd000001DA*
- ID_MODEL_FROM_DATABASE=OptiPlex 745
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #2 (OptiPlex 745)
 
 pci:v00008086d00002831sv00001028sd000001F3*
- ID_MODEL_FROM_DATABASE=Inspiron 1420
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #2 (Inspiron 1420)
 
 pci:v00008086d00002831sv0000103Csd000030C0*
- ID_MODEL_FROM_DATABASE=Compaq 6710b
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #2 (Compaq 6710b)
 
 pci:v00008086d00002831sv0000103Csd000030C1*
- ID_MODEL_FROM_DATABASE=Compaq 6910p
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #2 (Compaq 6910p)
 
 pci:v00008086d00002831sv0000103Csd000030CC*
- ID_MODEL_FROM_DATABASE=Pavilion dv6700
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #2 (Pavilion dv6700)
 
 pci:v00008086d00002831sv0000103Csd000030D9*
- ID_MODEL_FROM_DATABASE=Presario C700
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #2 (Presario C700)
 
 pci:v00008086d00002831sv00001043sd000081EC*
- ID_MODEL_FROM_DATABASE=P5B
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #2 (P5B)
 
 pci:v00008086d00002831sv0000104Dsd00009005*
- ID_MODEL_FROM_DATABASE=Vaio VGN-FZ260E
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #2 (Vaio VGN-FZ260E)
 
 pci:v00008086d00002831sv0000104Dsd0000902D*
- ID_MODEL_FROM_DATABASE=VAIO VGN-NR120E
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #2 (VAIO VGN-NR120E)
 
 pci:v00008086d00002831sv00001462sd00007235*
- ID_MODEL_FROM_DATABASE=P965 Neo MS-7235 mainboard
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #2 (P965 Neo MS-7235 mainboard)
 
 pci:v00008086d00002831sv000017AAsd000020AA*
- ID_MODEL_FROM_DATABASE=ThinkPad T61/R61
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #2 (ThinkPad T61/R61)
+
+pci:v00008086d00002831sv000017C0sd00004083*
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #2 (Medion WIM 2210 Notebook PC [MD96850])
 
 pci:v00008086d00002831sv0000E4BFsd0000CC47*
- ID_MODEL_FROM_DATABASE=CCG-RUMBA
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #2 (CCG-RUMBA)
 
 pci:v00008086d00002832*
  ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #3
 
 pci:v00008086d00002832sv00001025sd00000121*
- ID_MODEL_FROM_DATABASE=Aspire 5920G
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #3 (Aspire 5920G)
 
 pci:v00008086d00002832sv00001028sd000001DA*
- ID_MODEL_FROM_DATABASE=OptiPlex 745
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #3 (OptiPlex 745)
 
 pci:v00008086d00002832sv00001028sd000001F3*
- ID_MODEL_FROM_DATABASE=Inspiron 1420
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #3 (Inspiron 1420)
 
 pci:v00008086d00002832sv0000103Csd000030C0*
- ID_MODEL_FROM_DATABASE=Compaq 6710b
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #3 (Compaq 6710b)
 
 pci:v00008086d00002832sv0000103Csd000030C1*
- ID_MODEL_FROM_DATABASE=Compaq 6910p
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #3 (Compaq 6910p)
 
 pci:v00008086d00002832sv0000103Csd000030CC*
- ID_MODEL_FROM_DATABASE=Pavilion dv6700
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #3 (Pavilion dv6700)
 
 pci:v00008086d00002832sv0000103Csd000030D9*
- ID_MODEL_FROM_DATABASE=Presario C700
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #3 (Presario C700)
 
 pci:v00008086d00002832sv00001043sd000081EC*
- ID_MODEL_FROM_DATABASE=P5B
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #3 (P5B)
 
 pci:v00008086d00002832sv0000104Dsd00009005*
- ID_MODEL_FROM_DATABASE=Vaio VGN-FZ260E
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #3 (Vaio VGN-FZ260E)
 
 pci:v00008086d00002832sv0000104Dsd0000902D*
- ID_MODEL_FROM_DATABASE=VAIO VGN-NR120E
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #3 (VAIO VGN-NR120E)
 
 pci:v00008086d00002832sv000017AAsd000020AA*
- ID_MODEL_FROM_DATABASE=ThinkPad T61/R61
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #3 (ThinkPad T61/R61)
+
+pci:v00008086d00002832sv000017C0sd00004083*
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #3 (Medion WIM 2210 Notebook PC [MD96850])
 
 pci:v00008086d00002832sv0000E4BFsd0000CC47*
- ID_MODEL_FROM_DATABASE=CCG-RUMBA
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #3 (CCG-RUMBA)
 
 pci:v00008086d00002833*
  ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #4
 
 pci:v00008086d00002833sv00001043sd000081EC*
- ID_MODEL_FROM_DATABASE=P5B
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #4 (P5B)
 
 pci:v00008086d00002834*
  ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #4
 
 pci:v00008086d00002834sv00001025sd00000121*
- ID_MODEL_FROM_DATABASE=Aspire 5920G
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #4 (Aspire 5920G)
 
 pci:v00008086d00002834sv00001028sd000001DA*
- ID_MODEL_FROM_DATABASE=OptiPlex 745
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #4 (OptiPlex 745)
 
 pci:v00008086d00002834sv00001028sd000001F3*
- ID_MODEL_FROM_DATABASE=Inspiron 1420
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #4 (Inspiron 1420)
 
 pci:v00008086d00002834sv0000103Csd000030C0*
- ID_MODEL_FROM_DATABASE=Compaq 6710b
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #4 (Compaq 6710b)
 
 pci:v00008086d00002834sv0000103Csd000030C1*
- ID_MODEL_FROM_DATABASE=Compaq 6910p
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #4 (Compaq 6910p)
 
 pci:v00008086d00002834sv0000103Csd000030CC*
- ID_MODEL_FROM_DATABASE=Pavilion dv6700
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #4 (Pavilion dv6700)
 
 pci:v00008086d00002834sv00001043sd000081EC*
- ID_MODEL_FROM_DATABASE=P5B
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #4 (P5B)
 
 pci:v00008086d00002834sv0000104Dsd00009005*
- ID_MODEL_FROM_DATABASE=Vaio VGN-FZ260E
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #4 (Vaio VGN-FZ260E)
 
 pci:v00008086d00002834sv0000104Dsd0000902D*
- ID_MODEL_FROM_DATABASE=VAIO VGN-NR120E
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #4 (VAIO VGN-NR120E)
 
 pci:v00008086d00002834sv00001462sd00007235*
- ID_MODEL_FROM_DATABASE=P965 Neo MS-7235 mainboard
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #4 (P965 Neo MS-7235 mainboard)
 
 pci:v00008086d00002834sv000017AAsd000020AA*
- ID_MODEL_FROM_DATABASE=ThinkPad T61/R61
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #4 (ThinkPad T61/R61)
+
+pci:v00008086d00002834sv000017C0sd00004083*
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #4 (Medion WIM 2210 Notebook PC [MD96850])
 
 pci:v00008086d00002834sv0000E4BFsd0000CC47*
- ID_MODEL_FROM_DATABASE=CCG-RUMBA
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #4 (CCG-RUMBA)
 
 pci:v00008086d00002835*
  ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #5
 
 pci:v00008086d00002835sv00001025sd00000121*
- ID_MODEL_FROM_DATABASE=Acer Aspire 5920G
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #5 (Acer Aspire 5920G)
 
 pci:v00008086d00002835sv00001028sd000001DA*
- ID_MODEL_FROM_DATABASE=OptiPlex 745
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #5 (OptiPlex 745)
 
 pci:v00008086d00002835sv00001028sd000001F3*
- ID_MODEL_FROM_DATABASE=Inspiron 1420
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #5 (Inspiron 1420)
 
 pci:v00008086d00002835sv0000103Csd000030C0*
- ID_MODEL_FROM_DATABASE=Compaq 6710b
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #5 (Compaq 6710b)
 
 pci:v00008086d00002835sv0000103Csd000030C1*
- ID_MODEL_FROM_DATABASE=Compaq 6910p
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #5 (Compaq 6910p)
 
 pci:v00008086d00002835sv0000103Csd000030CC*
- ID_MODEL_FROM_DATABASE=Pavilion dv6700
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #5 (Pavilion dv6700)
 
 pci:v00008086d00002835sv00001043sd000081EC*
- ID_MODEL_FROM_DATABASE=P5B
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #5 (P5B)
 
 pci:v00008086d00002835sv0000104Dsd00009005*
- ID_MODEL_FROM_DATABASE=Vaio VGN-FZ260E
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #5 (Vaio VGN-FZ260E)
 
 pci:v00008086d00002835sv0000104Dsd0000902D*
- ID_MODEL_FROM_DATABASE=VAIO VGN-NR120E
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #5 (VAIO VGN-NR120E)
 
 pci:v00008086d00002835sv000017AAsd000020AA*
- ID_MODEL_FROM_DATABASE=Thinkpad T61/R61
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #5 (Thinkpad T61/R61)
+
+pci:v00008086d00002835sv000017C0sd00004083*
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #5 (Medion WIM 2210 Notebook PC [MD96850])
 
 pci:v00008086d00002835sv0000E4BFsd0000CC47*
- ID_MODEL_FROM_DATABASE=CCG-RUMBA
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #5 (CCG-RUMBA)
 
 pci:v00008086d00002836*
  ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #1
 
 pci:v00008086d00002836sv00001025sd00000121*
- ID_MODEL_FROM_DATABASE=Aspire 5920G
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #1 (Aspire 5920G)
 
 pci:v00008086d00002836sv00001028sd000001DA*
- ID_MODEL_FROM_DATABASE=OptiPlex 745
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #1 (OptiPlex 745)
 
 pci:v00008086d00002836sv00001028sd000001F3*
- ID_MODEL_FROM_DATABASE=Inspiron 1420
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #1 (Inspiron 1420)
 
 pci:v00008086d00002836sv0000103Csd000030C0*
- ID_MODEL_FROM_DATABASE=Compaq 6710b
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #1 (Compaq 6710b)
 
 pci:v00008086d00002836sv0000103Csd000030C1*
- ID_MODEL_FROM_DATABASE=Compaq 6910p
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #1 (Compaq 6910p)
 
 pci:v00008086d00002836sv0000103Csd000030CC*
- ID_MODEL_FROM_DATABASE=Pavilion dv6700
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #1 (Pavilion dv6700)
 
 pci:v00008086d00002836sv0000103Csd000030D9*
- ID_MODEL_FROM_DATABASE=Presario C700
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #1 (Presario C700)
 
 pci:v00008086d00002836sv00001043sd000081EC*
- ID_MODEL_FROM_DATABASE=P5B
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #1 (P5B)
 
 pci:v00008086d00002836sv0000104Dsd00009005*
- ID_MODEL_FROM_DATABASE=Vaio VGN-FZ260E
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #1 (Vaio VGN-FZ260E)
 
 pci:v00008086d00002836sv0000104Dsd0000902D*
- ID_MODEL_FROM_DATABASE=VAIO VGN-NR120E
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #1 (VAIO VGN-NR120E)
 
 pci:v00008086d00002836sv00001462sd00007235*
- ID_MODEL_FROM_DATABASE=P965 Neo MS-7235 mainboard
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #1 (P965 Neo MS-7235 mainboard)
 
 pci:v00008086d00002836sv000017AAsd000020AB*
- ID_MODEL_FROM_DATABASE=ThinkPad T61/R61
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #1 (ThinkPad T61/R61)
+
+pci:v00008086d00002836sv000017C0sd00004083*
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #1 (Medion WIM 2210 Notebook PC [MD96850])
 
 pci:v00008086d00002836sv0000E4BFsd0000CC47*
- ID_MODEL_FROM_DATABASE=CCG-RUMBA
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #1 (CCG-RUMBA)
 
 pci:v00008086d0000283A*
  ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #2
 
 pci:v00008086d0000283Asv00001025sd00000121*
- ID_MODEL_FROM_DATABASE=Acer Aspire 5920G
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #2 (Acer Aspire 5920G)
 
 pci:v00008086d0000283Asv00001028sd000001DA*
- ID_MODEL_FROM_DATABASE=OptiPlex 745
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #2 (OptiPlex 745)
 
 pci:v00008086d0000283Asv00001028sd000001F3*
- ID_MODEL_FROM_DATABASE=Inspiron 1420
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #2 (Inspiron 1420)
 
 pci:v00008086d0000283Asv0000103Csd000030C0*
- ID_MODEL_FROM_DATABASE=Compaq 6710b
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #2 (Compaq 6710b)
 
 pci:v00008086d0000283Asv0000103Csd000030C1*
- ID_MODEL_FROM_DATABASE=Compaq 6910p
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #2 (Compaq 6910p)
 
 pci:v00008086d0000283Asv0000103Csd000030CC*
- ID_MODEL_FROM_DATABASE=Pavilion dv6700
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #2 (Pavilion dv6700)
 
 pci:v00008086d0000283Asv00001043sd000081EC*
- ID_MODEL_FROM_DATABASE=P5B
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #2 (P5B)
 
 pci:v00008086d0000283Asv0000104Dsd00009005*
- ID_MODEL_FROM_DATABASE=Vaio VGN-FZ260E
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #2 (Vaio VGN-FZ260E)
 
 pci:v00008086d0000283Asv0000104Dsd0000902D*
- ID_MODEL_FROM_DATABASE=VAIO VGN-NR120E
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #2 (VAIO VGN-NR120E)
 
 pci:v00008086d0000283Asv000017AAsd000020AB*
- ID_MODEL_FROM_DATABASE=ThinkPad T61/R61
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #2 (ThinkPad T61/R61)
+
+pci:v00008086d0000283Asv000017C0sd00004083*
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #2 (Medion WIM 2210 Notebook PC [MD96850])
 
 pci:v00008086d0000283Asv0000E4BFsd0000CC47*
- ID_MODEL_FROM_DATABASE=CCG-RUMBA
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #2 (CCG-RUMBA)
 
 pci:v00008086d0000283E*
  ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) SMBus Controller
 
 pci:v00008086d0000283Esv00001025sd00000121*
- ID_MODEL_FROM_DATABASE=Aspire 5920G
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) SMBus Controller (Aspire 5920G)
 
 pci:v00008086d0000283Esv00001028sd000001DA*
- ID_MODEL_FROM_DATABASE=OptiPlex 745
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) SMBus Controller (OptiPlex 745)
 
 pci:v00008086d0000283Esv00001028sd000001F3*
- ID_MODEL_FROM_DATABASE=Inspiron 1420
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) SMBus Controller (Inspiron 1420)
 
 pci:v00008086d0000283Esv0000103Csd000030D9*
- ID_MODEL_FROM_DATABASE=Presario C700
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) SMBus Controller (Presario C700)
 
 pci:v00008086d0000283Esv00001043sd000081EC*
- ID_MODEL_FROM_DATABASE=P5B
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) SMBus Controller (P5B)
 
 pci:v00008086d0000283Esv0000104Dsd00009005*
- ID_MODEL_FROM_DATABASE=Vaio VGN-FZ260E
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) SMBus Controller (Vaio VGN-FZ260E)
 
 pci:v00008086d0000283Esv0000104Dsd00009008*
- ID_MODEL_FROM_DATABASE=Vaio VGN-SZ79SN_C
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) SMBus Controller (Vaio VGN-SZ79SN_C)
 
 pci:v00008086d0000283Esv0000104Dsd0000902D*
- ID_MODEL_FROM_DATABASE=VAIO VGN-NR120E
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) SMBus Controller (VAIO VGN-NR120E)
 
 pci:v00008086d0000283Esv00001462sd00007235*
- ID_MODEL_FROM_DATABASE=P965 Neo MS-7235 mainboard
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) SMBus Controller (P965 Neo MS-7235 mainboard)
 
 pci:v00008086d0000283Esv000017AAsd000020A9*
- ID_MODEL_FROM_DATABASE=ThinkPad T61/R61
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) SMBus Controller (ThinkPad T61/R61)
+
+pci:v00008086d0000283Esv000017C0sd00004083*
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) SMBus Controller (Medion WIM 2210 Notebook PC [MD96850])
 
 pci:v00008086d0000283Esv0000E4BFsd0000CC47*
- ID_MODEL_FROM_DATABASE=CCG-RUMBA
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) SMBus Controller (CCG-RUMBA)
 
 pci:v00008086d0000283F*
  ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 1
 
 pci:v00008086d0000283Fsv00001028sd000001DA*
- ID_MODEL_FROM_DATABASE=OptiPlex 745
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 1 (OptiPlex 745)
 
 pci:v00008086d0000283Fsv0000103Csd000030C1*
- ID_MODEL_FROM_DATABASE=Compaq 6910p
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 1 (Compaq 6910p)
 
 pci:v00008086d0000283Fsv0000104Dsd0000902D*
- ID_MODEL_FROM_DATABASE=VAIO VGN-NR120E
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 1 (VAIO VGN-NR120E)
 
 pci:v00008086d0000283Fsv000017AAsd000020AD*
- ID_MODEL_FROM_DATABASE=ThinkPad T61/R61
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 1 (ThinkPad T61/R61)
+
+pci:v00008086d0000283Fsv000017C0sd00004083*
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 1 (Medion WIM 2210 Notebook PC [MD96850])
 
 pci:v00008086d00002841*
  ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 2
 
 pci:v00008086d00002841sv0000103Csd000030C1*
- ID_MODEL_FROM_DATABASE=Compaq 6910p
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 2 (Compaq 6910p)
 
 pci:v00008086d00002841sv0000104Dsd0000902D*
- ID_MODEL_FROM_DATABASE=VAIO VGN-NR120E
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 2 (VAIO VGN-NR120E)
 
 pci:v00008086d00002841sv000017AAsd000020AD*
- ID_MODEL_FROM_DATABASE=ThinkPad T61/R61
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 2 (ThinkPad T61/R61)
+
+pci:v00008086d00002841sv000017C0sd00004083*
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 2 (Medion WIM 2210 Notebook PC [MD96850])
 
 pci:v00008086d00002843*
  ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 3
 
 pci:v00008086d00002843sv0000104Dsd0000902D*
- ID_MODEL_FROM_DATABASE=VAIO VGN-NR120E
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 3 (VAIO VGN-NR120E)
 
 pci:v00008086d00002843sv000017AAsd000020AD*
- ID_MODEL_FROM_DATABASE=ThinkPad T61/R61
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 3 (ThinkPad T61/R61)
+
+pci:v00008086d00002843sv000017C0sd00004083*
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 3 (Medion WIM 2210 Notebook PC [MD96850])
 
 pci:v00008086d00002845*
  ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 4
 
 pci:v00008086d00002845sv000017AAsd000020AD*
- ID_MODEL_FROM_DATABASE=ThinkPad T61/R61
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 4 (ThinkPad T61/R61)
+
+pci:v00008086d00002845sv000017C0sd00004083*
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 4 (Medion WIM 2210 Notebook PC [MD96850])
 
 pci:v00008086d00002847*
  ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 5
 
 pci:v00008086d00002847sv00001028sd000001DA*
- ID_MODEL_FROM_DATABASE=OptiPlex 745
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 5 (OptiPlex 745)
 
 pci:v00008086d00002847sv0000103Csd000030C1*
- ID_MODEL_FROM_DATABASE=Compaq 6910p
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 5 (Compaq 6910p)
 
 pci:v00008086d00002847sv000017AAsd000020AD*
- ID_MODEL_FROM_DATABASE=ThinkPad T61/R61
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 5 (ThinkPad T61/R61)
+
+pci:v00008086d00002847sv000017C0sd00004083*
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 5 (Medion WIM 2210 Notebook PC [MD96850])
 
 pci:v00008086d00002849*
  ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) PCI Express Port 6
@@ -64086,70 +66000,73 @@ pci:v00008086d0000284B*
  ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller
 
 pci:v00008086d0000284Bsv00001025sd0000011F*
- ID_MODEL_FROM_DATABASE=Realtek ALC268 audio codec
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (Realtek ALC268 audio codec)
 
 pci:v00008086d0000284Bsv00001025sd00000121*
- ID_MODEL_FROM_DATABASE=Aspire 5920G
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (Aspire 5920G)
 
 pci:v00008086d0000284Bsv00001025sd00000145*
- ID_MODEL_FROM_DATABASE=Realtek ALC889 (Aspire 8920G w. Dolby Theather)
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (Realtek ALC889 (Aspire 8920G w. Dolby Theather))
 
 pci:v00008086d0000284Bsv00001028sd000001DA*
- ID_MODEL_FROM_DATABASE=OptiPlex 745
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (OptiPlex 745)
 
 pci:v00008086d0000284Bsv00001028sd000001F3*
- ID_MODEL_FROM_DATABASE=Inspiron 1420
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (Inspiron 1420)
 
 pci:v00008086d0000284Bsv00001028sd000001F9*
- ID_MODEL_FROM_DATABASE=Dell Latitude D630
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (Dell Latitude D630)
 
 pci:v00008086d0000284Bsv00001028sd000001FF*
- ID_MODEL_FROM_DATABASE=Dell Precision M4300
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (Dell Precision M4300)
 
 pci:v00008086d0000284Bsv00001028sd00000256*
- ID_MODEL_FROM_DATABASE=Studio 1735
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (Studio 1735)
 
 pci:v00008086d0000284Bsv0000103Csd00002802*
- ID_MODEL_FROM_DATABASE=HP Compaq dc7700p
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (HP Compaq dc7700p)
 
 pci:v00008086d0000284Bsv0000103Csd000030C0*
- ID_MODEL_FROM_DATABASE=Compaq 6710b
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (Compaq 6710b)
 
 pci:v00008086d0000284Bsv0000103Csd000030C1*
- ID_MODEL_FROM_DATABASE=Compaq 6910p
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (Compaq 6910p)
 
 pci:v00008086d0000284Bsv0000103Csd000030CC*
- ID_MODEL_FROM_DATABASE=Pavilion dv6700
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (Pavilion dv6700)
 
 pci:v00008086d0000284Bsv00001043sd00001339*
- ID_MODEL_FROM_DATABASE=Asus M51S series
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (Asus M51S series)
 
 pci:v00008086d0000284Bsv00001043sd000081EC*
- ID_MODEL_FROM_DATABASE=P5B
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (P5B)
 
 pci:v00008086d0000284Bsv0000104Dsd00009005*
- ID_MODEL_FROM_DATABASE=Vaio VGN-FZ260E
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (Vaio VGN-FZ260E)
 
 pci:v00008086d0000284Bsv0000104Dsd00009008*
- ID_MODEL_FROM_DATABASE=Vaio VGN-SZ79SN_C
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (Vaio VGN-SZ79SN_C)
 
 pci:v00008086d0000284Bsv0000104Dsd00009016*
- ID_MODEL_FROM_DATABASE=Sony VAIO VGN-AR51M
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (Sony VAIO VGN-AR51M)
 
 pci:v00008086d0000284Bsv0000104Dsd0000902D*
- ID_MODEL_FROM_DATABASE=VAIO VGN-NR120E
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (VAIO VGN-NR120E)
 
 pci:v00008086d0000284Bsv000014F1sd00005051*
- ID_MODEL_FROM_DATABASE=Presario C700
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (Presario C700)
 
 pci:v00008086d0000284Bsv000017AAsd000020AC*
- ID_MODEL_FROM_DATABASE=ThinkPad T61/R61
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (ThinkPad T61/R61)
+
+pci:v00008086d0000284Bsv000017C0sd00004088*
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (Medion WIM 2210 Notebook PC [MD96850])
 
 pci:v00008086d0000284Bsv00008384sd00007616*
- ID_MODEL_FROM_DATABASE=Dell Vostro 1400
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (Dell Vostro 1400)
 
 pci:v00008086d0000284Bsv0000E4BFsd0000CC47*
- ID_MODEL_FROM_DATABASE=CCG-RUMBA
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (CCG-RUMBA)
 
 pci:v00008086d0000284F*
  ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) Thermal Reporting Device
@@ -64158,34 +66075,37 @@ pci:v00008086d00002850*
  ID_MODEL_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) IDE Controller
 
 pci:v00008086d00002850sv00001025sd00000121*
- ID_MODEL_FROM_DATABASE=Aspire 5920G
+ ID_MODEL_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) IDE Controller (Aspire 5920G)
 
 pci:v00008086d00002850sv00001028sd000001F3*
- ID_MODEL_FROM_DATABASE=Inspiron 1420
+ ID_MODEL_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) IDE Controller (Inspiron 1420)
 
 pci:v00008086d00002850sv0000103Csd000030C0*
- ID_MODEL_FROM_DATABASE=Compaq 6710b
+ ID_MODEL_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) IDE Controller (Compaq 6710b)
 
 pci:v00008086d00002850sv0000103Csd000030C1*
- ID_MODEL_FROM_DATABASE=Compaq 6910p
+ ID_MODEL_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) IDE Controller (Compaq 6910p)
 
 pci:v00008086d00002850sv0000103Csd000030CC*
- ID_MODEL_FROM_DATABASE=Pavilion dv6700
+ ID_MODEL_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) IDE Controller (Pavilion dv6700)
 
 pci:v00008086d00002850sv0000103Csd000030D9*
- ID_MODEL_FROM_DATABASE=Presario C700
+ ID_MODEL_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) IDE Controller (Presario C700)
 
 pci:v00008086d00002850sv0000104Dsd00009005*
- ID_MODEL_FROM_DATABASE=Vaio VGN-FZ260E
+ ID_MODEL_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) IDE Controller (Vaio VGN-FZ260E)
 
 pci:v00008086d00002850sv0000104Dsd0000902D*
- ID_MODEL_FROM_DATABASE=VAIO VGN-NR120E
+ ID_MODEL_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) IDE Controller (VAIO VGN-NR120E)
 
 pci:v00008086d00002850sv000017AAsd000020A6*
- ID_MODEL_FROM_DATABASE=ThinkPad T61/R61
+ ID_MODEL_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) IDE Controller (ThinkPad T61/R61)
+
+pci:v00008086d00002850sv000017C0sd00004083*
+ ID_MODEL_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) IDE Controller (Medion WIM 2210 Notebook PC [MD96850])
 
 pci:v00008086d00002850sv0000E4BFsd0000CC47*
- ID_MODEL_FROM_DATABASE=CCG-RUMBA
+ ID_MODEL_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) IDE Controller (CCG-RUMBA)
 
 pci:v00008086d00002912*
  ID_MODEL_FROM_DATABASE=82801IH (ICH9DH) LPC Interface Controller
@@ -64194,34 +66114,40 @@ pci:v00008086d00002914*
  ID_MODEL_FROM_DATABASE=82801IO (ICH9DO) LPC Interface Controller
 
 pci:v00008086d00002914sv00001028sd00000211*
- ID_MODEL_FROM_DATABASE=Optiplex 755
+ ID_MODEL_FROM_DATABASE=82801IO (ICH9DO) LPC Interface Controller (Optiplex 755)
 
 pci:v00008086d00002916*
  ID_MODEL_FROM_DATABASE=82801IR (ICH9R) LPC Interface Controller
 
 pci:v00008086d00002916sv00001028sd0000020D*
- ID_MODEL_FROM_DATABASE=Inspiron 530
+ ID_MODEL_FROM_DATABASE=82801IR (ICH9R) LPC Interface Controller (Inspiron 530)
+
+pci:v00008086d00002916sv0000103Csd00002A6F*
+ ID_MODEL_FROM_DATABASE=82801IR (ICH9R) LPC Interface Controller (Asus IPIBL-LB Motherboard)
 
 pci:v00008086d00002916sv00001043sd00008277*
- ID_MODEL_FROM_DATABASE=P5K PRO Motherboard
+ ID_MODEL_FROM_DATABASE=82801IR (ICH9R) LPC Interface Controller (P5K PRO Motherboard)
 
 pci:v00008086d00002916sv00008086sd00005044*
- ID_MODEL_FROM_DATABASE=Desktop Board DP35DP
+ ID_MODEL_FROM_DATABASE=82801IR (ICH9R) LPC Interface Controller (Desktop Board DP35DP)
 
 pci:v00008086d00002917*
  ID_MODEL_FROM_DATABASE=ICH9M-E LPC Interface Controller
 
 pci:v00008086d00002917sv0000E4BFsd0000CC4D*
- ID_MODEL_FROM_DATABASE=CCM-BOOGIE
+ ID_MODEL_FROM_DATABASE=ICH9M-E LPC Interface Controller (CCM-BOOGIE)
 
 pci:v00008086d00002918*
  ID_MODEL_FROM_DATABASE=82801IB (ICH9) LPC Interface Controller
 
 pci:v00008086d00002918sv00001028sd00000236*
- ID_MODEL_FROM_DATABASE=PowerEdge R610 82801IB (ICH9) LPC Interface Controller
+ ID_MODEL_FROM_DATABASE=82801IB (ICH9) LPC Interface Controller (PowerEdge R610 82801IB (ICH9) LPC Interface Controller)
 
 pci:v00008086d00002918sv00001462sd00007360*
- ID_MODEL_FROM_DATABASE=G33/P35 Neo
+ ID_MODEL_FROM_DATABASE=82801IB (ICH9) LPC Interface Controller (G33/P35 Neo)
+
+pci:v00008086d00002918sv00001AF4sd00001100*
+ ID_MODEL_FROM_DATABASE=82801IB (ICH9) LPC Interface Controller (QEMU Virtual Machine)
 
 pci:v00008086d00002919*
  ID_MODEL_FROM_DATABASE=ICH9M LPC Interface Controller
@@ -64230,43 +66156,46 @@ pci:v00008086d00002920*
  ID_MODEL_FROM_DATABASE=82801IR/IO/IH (ICH9R/DO/DH) 4 port SATA Controller [IDE mode]
 
 pci:v00008086d00002920sv00001028sd0000020D*
- ID_MODEL_FROM_DATABASE=Inspiron 530
+ ID_MODEL_FROM_DATABASE=82801IR/IO/IH (ICH9R/DO/DH) 4 port SATA Controller [IDE mode] (Inspiron 530)
 
 pci:v00008086d00002920sv00001028sd0000020F*
- ID_MODEL_FROM_DATABASE=PowerEdge R300 onboard SATA Controller
+ ID_MODEL_FROM_DATABASE=82801IR/IO/IH (ICH9R/DO/DH) 4 port SATA Controller [IDE mode] (PowerEdge R300 onboard SATA Controller)
 
 pci:v00008086d00002920sv00001028sd00000210*
- ID_MODEL_FROM_DATABASE=PowerEdge T300 onboard SATA Controller
+ ID_MODEL_FROM_DATABASE=82801IR/IO/IH (ICH9R/DO/DH) 4 port SATA Controller [IDE mode] (PowerEdge T300 onboard SATA Controller)
 
 pci:v00008086d00002920sv00001028sd00000211*
- ID_MODEL_FROM_DATABASE=Optiplex 755
+ ID_MODEL_FROM_DATABASE=82801IR/IO/IH (ICH9R/DO/DH) 4 port SATA Controller [IDE mode] (Optiplex 755)
 
 pci:v00008086d00002920sv00001028sd0000023C*
- ID_MODEL_FROM_DATABASE=PowerEdge R200 onboard SATA Controller
+ ID_MODEL_FROM_DATABASE=82801IR/IO/IH (ICH9R/DO/DH) 4 port SATA Controller [IDE mode] (PowerEdge R200 onboard SATA Controller)
 
 pci:v00008086d00002920sv00001043sd00008277*
- ID_MODEL_FROM_DATABASE=P5K PRO Motherboard
+ ID_MODEL_FROM_DATABASE=82801IR/IO/IH (ICH9R/DO/DH) 4 port SATA Controller [IDE mode] (P5K PRO Motherboard)
 
 pci:v00008086d00002921*
  ID_MODEL_FROM_DATABASE=82801IB (ICH9) 2 port SATA Controller [IDE mode]
 
 pci:v00008086d00002921sv00001028sd00000235*
- ID_MODEL_FROM_DATABASE=PowerEdge R710 SATA IDE Controller
+ ID_MODEL_FROM_DATABASE=82801IB (ICH9) 2 port SATA Controller [IDE mode] (PowerEdge R710 SATA IDE Controller)
 
 pci:v00008086d00002921sv00001028sd00000236*
- ID_MODEL_FROM_DATABASE=PowerEdge R610 SATA IDE Controller
+ ID_MODEL_FROM_DATABASE=82801IB (ICH9) 2 port SATA Controller [IDE mode] (PowerEdge R610 SATA IDE Controller)
 
 pci:v00008086d00002921sv00001028sd00000237*
- ID_MODEL_FROM_DATABASE=PowerEdge T610 SATA IDE Controller
+ ID_MODEL_FROM_DATABASE=82801IB (ICH9) 2 port SATA Controller [IDE mode] (PowerEdge T610 SATA IDE Controller)
 
 pci:v00008086d00002921sv00001462sd00007360*
- ID_MODEL_FROM_DATABASE=G33/P35 Neo
+ ID_MODEL_FROM_DATABASE=82801IB (ICH9) 2 port SATA Controller [IDE mode] (G33/P35 Neo)
 
 pci:v00008086d00002922*
  ID_MODEL_FROM_DATABASE=82801IR/IO/IH (ICH9R/DO/DH) 6 port SATA Controller [AHCI mode]
 
+pci:v00008086d00002922sv00001AF4sd00001100*
+ ID_MODEL_FROM_DATABASE=82801IR/IO/IH (ICH9R/DO/DH) 6 port SATA Controller [AHCI mode] (QEMU Virtual Machine)
+
 pci:v00008086d00002922sv00008086sd00005044*
- ID_MODEL_FROM_DATABASE=Desktop Board DP35DP
+ ID_MODEL_FROM_DATABASE=82801IR/IO/IH (ICH9R/DO/DH) 6 port SATA Controller [AHCI mode] (Desktop Board DP35DP)
 
 pci:v00008086d00002923*
  ID_MODEL_FROM_DATABASE=82801IB (ICH9) 4 port SATA Controller [AHCI mode]
@@ -64275,31 +66204,31 @@ pci:v00008086d00002925*
  ID_MODEL_FROM_DATABASE=82801IR/IO (ICH9R/DO) SATA Controller [RAID mode]
 
 pci:v00008086d00002925sv00001734sd000010E0*
- ID_MODEL_FROM_DATABASE=System Board D2542
+ ID_MODEL_FROM_DATABASE=82801IR/IO (ICH9R/DO) SATA Controller [RAID mode] (System Board D2542)
 
 pci:v00008086d00002925sv00008086sd00002925*
- ID_MODEL_FROM_DATABASE=System Board D2542
+ ID_MODEL_FROM_DATABASE=82801IR/IO (ICH9R/DO) SATA Controller [RAID mode] (System Board D2542)
 
 pci:v00008086d00002926*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) 2 port SATA Controller [IDE mode]
 
 pci:v00008086d00002926sv00001028sd0000020D*
- ID_MODEL_FROM_DATABASE=Inspiron 530
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) 2 port SATA Controller [IDE mode] (Inspiron 530)
 
 pci:v00008086d00002926sv00001028sd0000020F*
- ID_MODEL_FROM_DATABASE=PowerEdge R300 onboard SATA Controller
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) 2 port SATA Controller [IDE mode] (PowerEdge R300 onboard SATA Controller)
 
 pci:v00008086d00002926sv00001028sd00000210*
- ID_MODEL_FROM_DATABASE=PowerEdge T300 onboard SATA Controller
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) 2 port SATA Controller [IDE mode] (PowerEdge T300 onboard SATA Controller)
 
 pci:v00008086d00002926sv00001028sd00000211*
- ID_MODEL_FROM_DATABASE=Optiplex 755
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) 2 port SATA Controller [IDE mode] (Optiplex 755)
 
 pci:v00008086d00002926sv00001043sd00008277*
- ID_MODEL_FROM_DATABASE=P5K PRO Motherboard
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) 2 port SATA Controller [IDE mode] (P5K PRO Motherboard)
 
 pci:v00008086d00002926sv00001462sd00007360*
- ID_MODEL_FROM_DATABASE=G33/P35 Neo
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) 2 port SATA Controller [IDE mode] (G33/P35 Neo)
 
 pci:v00008086d00002928*
  ID_MODEL_FROM_DATABASE=82801IBM/IEM (ICH9M/ICH9M-E) 2 port SATA Controller [IDE mode]
@@ -64308,10 +66237,10 @@ pci:v00008086d00002929*
  ID_MODEL_FROM_DATABASE=82801IBM/IEM (ICH9M/ICH9M-E) 4 port SATA Controller [AHCI mode]
 
 pci:v00008086d00002929sv0000103Csd00003628*
- ID_MODEL_FROM_DATABASE=dv6-1190en
+ ID_MODEL_FROM_DATABASE=82801IBM/IEM (ICH9M/ICH9M-E) 4 port SATA Controller [AHCI mode] (dv6-1190en)
 
 pci:v00008086d00002929sv0000E4BFsd0000CC4D*
- ID_MODEL_FROM_DATABASE=CCM-BOOGIE
+ ID_MODEL_FROM_DATABASE=82801IBM/IEM (ICH9M/ICH9M-E) 4 port SATA Controller [AHCI mode] (CCM-BOOGIE)
 
 pci:v00008086d0000292C*
  ID_MODEL_FROM_DATABASE=82801IEM (ICH9M-E) SATA Controller [RAID mode]
@@ -64320,445 +66249,511 @@ pci:v00008086d0000292D*
  ID_MODEL_FROM_DATABASE=82801IBM/IEM (ICH9M/ICH9M-E) 2 port SATA Controller [IDE mode]
 
 pci:v00008086d0000292Dsv0000E4BFsd0000CC4D*
- ID_MODEL_FROM_DATABASE=CCM-BOOGIE
+ ID_MODEL_FROM_DATABASE=82801IBM/IEM (ICH9M/ICH9M-E) 2 port SATA Controller [IDE mode] (CCM-BOOGIE)
 
 pci:v00008086d00002930*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) SMBus Controller
 
 pci:v00008086d00002930sv00001028sd0000020D*
- ID_MODEL_FROM_DATABASE=Inspiron 530
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) SMBus Controller (Inspiron 530)
 
 pci:v00008086d00002930sv00001028sd00000211*
- ID_MODEL_FROM_DATABASE=Optiplex 755
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) SMBus Controller (Optiplex 755)
+
+pci:v00008086d00002930sv0000103Csd00002A6F*
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) SMBus Controller (Asus IPIBL-LB Motherboard)
 
 pci:v00008086d00002930sv0000103Csd00003628*
- ID_MODEL_FROM_DATABASE=dv6-1190en
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) SMBus Controller (dv6-1190en)
 
 pci:v00008086d00002930sv00001043sd00008277*
- ID_MODEL_FROM_DATABASE=P5K PRO Motherboard
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) SMBus Controller (P5K PRO Motherboard)
 
 pci:v00008086d00002930sv00001462sd00007360*
- ID_MODEL_FROM_DATABASE=G33/P35 Neo
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) SMBus Controller (G33/P35 Neo)
+
+pci:v00008086d00002930sv00001AF4sd00001100*
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) SMBus Controller (QEMU Virtual Machine)
 
 pci:v00008086d00002930sv00008086sd00005044*
- ID_MODEL_FROM_DATABASE=Desktop Board DP35DP
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) SMBus Controller (Desktop Board DP35DP)
 
 pci:v00008086d00002930sv0000E4BFsd0000CC4D*
- ID_MODEL_FROM_DATABASE=CCM-BOOGIE
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) SMBus Controller (CCM-BOOGIE)
 
 pci:v00008086d00002932*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) Thermal Subsystem
 
 pci:v00008086d00002932sv0000103Csd00003628*
- ID_MODEL_FROM_DATABASE=dv6-1190en
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) Thermal Subsystem (dv6-1190en)
 
 pci:v00008086d00002934*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #1
 
 pci:v00008086d00002934sv00001028sd0000020D*
- ID_MODEL_FROM_DATABASE=Inspiron 530
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #1 (Inspiron 530)
 
 pci:v00008086d00002934sv00001028sd0000020F*
- ID_MODEL_FROM_DATABASE=PowerEdge R300 onboard UHCI
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #1 (PowerEdge R300 onboard UHCI)
 
 pci:v00008086d00002934sv00001028sd00000210*
- ID_MODEL_FROM_DATABASE=PowerEdge T300 onboard UHCI
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #1 (PowerEdge T300 onboard UHCI)
 
 pci:v00008086d00002934sv00001028sd00000211*
- ID_MODEL_FROM_DATABASE=Optiplex 755
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #1 (Optiplex 755)
 
 pci:v00008086d00002934sv00001028sd00000235*
- ID_MODEL_FROM_DATABASE=PowerEdge R710 USB UHCI Controller
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #1 (PowerEdge R710 USB UHCI Controller)
 
 pci:v00008086d00002934sv00001028sd00000236*
- ID_MODEL_FROM_DATABASE=PowerEdge R610 USB UHCI Controller
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #1 (PowerEdge R610 USB UHCI Controller)
 
 pci:v00008086d00002934sv00001028sd00000237*
- ID_MODEL_FROM_DATABASE=PowerEdge T610 USB UHCI Controller
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #1 (PowerEdge T610 USB UHCI Controller)
 
 pci:v00008086d00002934sv00001028sd0000023C*
- ID_MODEL_FROM_DATABASE=PowerEdge R200 onboard UHCI
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #1 (PowerEdge R200 onboard UHCI)
 
 pci:v00008086d00002934sv00001028sd00000287*
- ID_MODEL_FROM_DATABASE=PowerEdge M610 onboard UHCI
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #1 (PowerEdge M610 onboard UHCI)
 
 pci:v00008086d00002934sv00001028sd0000029C*
- ID_MODEL_FROM_DATABASE=PowerEdge M710 USB UHCI Controller
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #1 (PowerEdge M710 USB UHCI Controller)
 
 pci:v00008086d00002934sv00001028sd00002011*
- ID_MODEL_FROM_DATABASE=Optiplex 755
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #1 (Optiplex 755)
+
+pci:v00008086d00002934sv0000103Csd00002A6F*
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #1 (Asus IPIBL-LB Motherboard)
 
 pci:v00008086d00002934sv00001043sd00008277*
- ID_MODEL_FROM_DATABASE=P5K PRO Motherboard
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #1 (P5K PRO Motherboard)
 
 pci:v00008086d00002934sv00001462sd00007360*
- ID_MODEL_FROM_DATABASE=G33/P35 Neo
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #1 (G33/P35 Neo)
+
+pci:v00008086d00002934sv00001AF4sd00001100*
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #1 (QEMU Virtual Machine)
 
 pci:v00008086d00002934sv00008086sd00005044*
- ID_MODEL_FROM_DATABASE=Desktop Board DP35DP
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #1 (Desktop Board DP35DP)
 
 pci:v00008086d00002934sv0000E4BFsd0000CC4D*
- ID_MODEL_FROM_DATABASE=CCM-BOOGIE
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #1 (CCM-BOOGIE)
 
 pci:v00008086d00002935*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #2
 
 pci:v00008086d00002935sv00001028sd0000020D*
- ID_MODEL_FROM_DATABASE=Inspiron 530
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #2 (Inspiron 530)
 
 pci:v00008086d00002935sv00001028sd0000020F*
- ID_MODEL_FROM_DATABASE=PowerEdge R300 onboard UHCI
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #2 (PowerEdge R300 onboard UHCI)
 
 pci:v00008086d00002935sv00001028sd00000210*
- ID_MODEL_FROM_DATABASE=PowerEdge T300 onboard UHCI
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #2 (PowerEdge T300 onboard UHCI)
 
 pci:v00008086d00002935sv00001028sd00000211*
- ID_MODEL_FROM_DATABASE=Optiplex 755
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #2 (Optiplex 755)
 
 pci:v00008086d00002935sv00001028sd00000235*
- ID_MODEL_FROM_DATABASE=PowerEdge R710 USB UHCI Controller
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #2 (PowerEdge R710 USB UHCI Controller)
 
 pci:v00008086d00002935sv00001028sd00000236*
- ID_MODEL_FROM_DATABASE=PowerEdge R610 USB UHCI Controller
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #2 (PowerEdge R610 USB UHCI Controller)
 
 pci:v00008086d00002935sv00001028sd00000237*
- ID_MODEL_FROM_DATABASE=PowerEdge T610 USB UHCI Controller
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #2 (PowerEdge T610 USB UHCI Controller)
 
 pci:v00008086d00002935sv00001028sd0000023C*
- ID_MODEL_FROM_DATABASE=PowerEdge R200 onboard UHCI
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #2 (PowerEdge R200 onboard UHCI)
 
 pci:v00008086d00002935sv00001028sd00000287*
- ID_MODEL_FROM_DATABASE=PowerEdge M610 onboard UHCI
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #2 (PowerEdge M610 onboard UHCI)
 
 pci:v00008086d00002935sv00001028sd0000029C*
- ID_MODEL_FROM_DATABASE=PowerEdge M710 USB UHCI Controller
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #2 (PowerEdge M710 USB UHCI Controller)
+
+pci:v00008086d00002935sv0000103Csd00002A6F*
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #2 (Asus IPIBL-LB Motherboard)
 
 pci:v00008086d00002935sv00001043sd00008277*
- ID_MODEL_FROM_DATABASE=P5K PRO Motherboard
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #2 (P5K PRO Motherboard)
 
 pci:v00008086d00002935sv00001462sd00007360*
- ID_MODEL_FROM_DATABASE=G33/P35 Neo
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #2 (G33/P35 Neo)
+
+pci:v00008086d00002935sv00001AF4sd00001100*
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #2 (QEMU Virtual Machine)
 
 pci:v00008086d00002935sv00008086sd00005044*
- ID_MODEL_FROM_DATABASE=Desktop Board DP35DP
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #2 (Desktop Board DP35DP)
 
 pci:v00008086d00002935sv0000E4BFsd0000CC4D*
- ID_MODEL_FROM_DATABASE=CCM-BOOGIE
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #2 (CCM-BOOGIE)
 
 pci:v00008086d00002936*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #3
 
 pci:v00008086d00002936sv00001028sd0000020D*
- ID_MODEL_FROM_DATABASE=Inspiron 530
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #3 (Inspiron 530)
 
 pci:v00008086d00002936sv00001028sd0000020F*
- ID_MODEL_FROM_DATABASE=PowerEdge R300 onboard UHCI
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #3 (PowerEdge R300 onboard UHCI)
 
 pci:v00008086d00002936sv00001028sd00000210*
- ID_MODEL_FROM_DATABASE=PowerEdge T300 onboard UHCI
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #3 (PowerEdge T300 onboard UHCI)
 
 pci:v00008086d00002936sv00001028sd00000211*
- ID_MODEL_FROM_DATABASE=Optiplex 755
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #3 (Optiplex 755)
 
 pci:v00008086d00002936sv00001028sd00000237*
- ID_MODEL_FROM_DATABASE=PowerEdge T610 USB UHCI Controller
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #3 (PowerEdge T610 USB UHCI Controller)
 
 pci:v00008086d00002936sv00001028sd0000023C*
- ID_MODEL_FROM_DATABASE=PowerEdge R200 onboard UHCI
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #3 (PowerEdge R200 onboard UHCI)
 
 pci:v00008086d00002936sv00001028sd00000287*
- ID_MODEL_FROM_DATABASE=PowerEdge M610 onboard UHCI
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #3 (PowerEdge M610 onboard UHCI)
 
 pci:v00008086d00002936sv00001028sd0000029C*
- ID_MODEL_FROM_DATABASE=PowerEdge M710 USB UHCI Controller
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #3 (PowerEdge M710 USB UHCI Controller)
+
+pci:v00008086d00002936sv0000103Csd00002A6F*
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #3 (Asus IPIBL-LB Motherboard)
 
 pci:v00008086d00002936sv00001043sd00008277*
- ID_MODEL_FROM_DATABASE=P5K PRO Motherboard
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #3 (P5K PRO Motherboard)
 
 pci:v00008086d00002936sv00001462sd00007360*
- ID_MODEL_FROM_DATABASE=G33/P35 Neo
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #3 (G33/P35 Neo)
+
+pci:v00008086d00002936sv00001AF4sd00001100*
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #3 (QEMU Virtual Machine)
 
 pci:v00008086d00002936sv00008086sd00005044*
- ID_MODEL_FROM_DATABASE=Desktop Board DP35DP
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #3 (Desktop Board DP35DP)
 
 pci:v00008086d00002936sv0000E4BFsd0000CC4D*
- ID_MODEL_FROM_DATABASE=CCM-BOOGIE
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #3 (CCM-BOOGIE)
 
 pci:v00008086d00002937*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #4
 
 pci:v00008086d00002937sv00001028sd0000020D*
- ID_MODEL_FROM_DATABASE=Inspiron 530
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #4 (Inspiron 530)
 
 pci:v00008086d00002937sv00001028sd00000211*
- ID_MODEL_FROM_DATABASE=Optiplex 755
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #4 (Optiplex 755)
 
 pci:v00008086d00002937sv00001028sd00000235*
- ID_MODEL_FROM_DATABASE=PowerEdge R710 USB UHCI Controller
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #4 (PowerEdge R710 USB UHCI Controller)
 
 pci:v00008086d00002937sv00001028sd00000236*
- ID_MODEL_FROM_DATABASE=PowerEdge R610 USB UHCI Controller
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #4 (PowerEdge R610 USB UHCI Controller)
 
 pci:v00008086d00002937sv00001028sd00000237*
- ID_MODEL_FROM_DATABASE=PowerEdge T610 USB UHCI Controller
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #4 (PowerEdge T610 USB UHCI Controller)
 
 pci:v00008086d00002937sv00001028sd00000287*
- ID_MODEL_FROM_DATABASE=PowerEdge M610 onboard UHCI
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #4 (PowerEdge M610 onboard UHCI)
 
 pci:v00008086d00002937sv00001028sd0000029C*
- ID_MODEL_FROM_DATABASE=PowerEdge M710 USB UHCI Controller
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #4 (PowerEdge M710 USB UHCI Controller)
 
 pci:v00008086d00002937sv00001028sd00002011*
- ID_MODEL_FROM_DATABASE=Optiplex 755
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #4 (Optiplex 755)
+
+pci:v00008086d00002937sv0000103Csd00002A6F*
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #4 (Asus IPIBL-LB Motherboard)
 
 pci:v00008086d00002937sv00001043sd00008277*
- ID_MODEL_FROM_DATABASE=P5K PRO Motherboard
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #4 (P5K PRO Motherboard)
 
 pci:v00008086d00002937sv00001462sd00007360*
- ID_MODEL_FROM_DATABASE=G33/P35 Neo
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #4 (G33/P35 Neo)
+
+pci:v00008086d00002937sv00001AF4sd00001100*
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #4 (QEMU Virtual Machine)
 
 pci:v00008086d00002937sv00008086sd00002937*
- ID_MODEL_FROM_DATABASE=Optiplex 755
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #4 (Optiplex 755)
 
 pci:v00008086d00002937sv00008086sd00002942*
- ID_MODEL_FROM_DATABASE=828011 (ICH9 Family ) USB UHCI Controller
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #4 (828011 (ICH9 Family ) USB UHCI Controller)
 
 pci:v00008086d00002937sv00008086sd00005044*
- ID_MODEL_FROM_DATABASE=Desktop Board DP35DP
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #4 (Desktop Board DP35DP)
 
 pci:v00008086d00002937sv0000E4BFsd0000CC4D*
- ID_MODEL_FROM_DATABASE=CCM-BOOGIE
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #4 (CCM-BOOGIE)
 
 pci:v00008086d00002938*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #5
 
 pci:v00008086d00002938sv00001028sd0000020D*
- ID_MODEL_FROM_DATABASE=Inspiron 530
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #5 (Inspiron 530)
 
 pci:v00008086d00002938sv00001028sd00000211*
- ID_MODEL_FROM_DATABASE=Optiplex 755
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #5 (Optiplex 755)
 
 pci:v00008086d00002938sv00001028sd00000235*
- ID_MODEL_FROM_DATABASE=PowerEdge R710 USB UHCI Controller
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #5 (PowerEdge R710 USB UHCI Controller)
 
 pci:v00008086d00002938sv00001028sd00000236*
- ID_MODEL_FROM_DATABASE=PowerEdge R610 USB UHCI Controller
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #5 (PowerEdge R610 USB UHCI Controller)
 
 pci:v00008086d00002938sv00001028sd00000237*
- ID_MODEL_FROM_DATABASE=PowerEdge T610 USB UHCI Controller
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #5 (PowerEdge T610 USB UHCI Controller)
 
 pci:v00008086d00002938sv00001028sd00000287*
- ID_MODEL_FROM_DATABASE=PowerEdge M610 onboard UHCI
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #5 (PowerEdge M610 onboard UHCI)
 
 pci:v00008086d00002938sv00001028sd0000029C*
- ID_MODEL_FROM_DATABASE=PowerEdge M710 USB UHCI Controller
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #5 (PowerEdge M710 USB UHCI Controller)
+
+pci:v00008086d00002938sv0000103Csd00002A6F*
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #5 (Asus IPIBL-LB Motherboard)
 
 pci:v00008086d00002938sv00001043sd00008277*
- ID_MODEL_FROM_DATABASE=P5K PRO Motherboard
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #5 (P5K PRO Motherboard)
 
 pci:v00008086d00002938sv00001462sd00007360*
- ID_MODEL_FROM_DATABASE=G33/P35 Neo
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #5 (G33/P35 Neo)
+
+pci:v00008086d00002938sv00001AF4sd00001100*
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #5 (QEMU Virtual Machine)
 
 pci:v00008086d00002938sv00008086sd00002938*
- ID_MODEL_FROM_DATABASE=Optiplex 755
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #5 (Optiplex 755)
 
 pci:v00008086d00002938sv00008086sd00005044*
- ID_MODEL_FROM_DATABASE=Desktop Board DP35DP
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #5 (Desktop Board DP35DP)
 
 pci:v00008086d00002938sv0000E4BFsd0000CC4D*
- ID_MODEL_FROM_DATABASE=CCM-BOOGIE
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #5 (CCM-BOOGIE)
 
 pci:v00008086d00002939*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #6
 
 pci:v00008086d00002939sv00001028sd0000020D*
- ID_MODEL_FROM_DATABASE=Inspiron 530
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #6 (Inspiron 530)
 
 pci:v00008086d00002939sv00001028sd00000210*
- ID_MODEL_FROM_DATABASE=PowerEdge T300 onboard UHCI
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #6 (PowerEdge T300 onboard UHCI)
 
 pci:v00008086d00002939sv00001028sd00000237*
- ID_MODEL_FROM_DATABASE=PowerEdge T610 USB UHCI Controller
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #6 (PowerEdge T610 USB UHCI Controller)
+
+pci:v00008086d00002939sv0000103Csd00002A6F*
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #6 (Asus IPIBL-LB Motherboard)
 
 pci:v00008086d00002939sv00001043sd00008277*
- ID_MODEL_FROM_DATABASE=P5K PRO Motherboard
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #6 (P5K PRO Motherboard)
 
 pci:v00008086d00002939sv00001462sd00007360*
- ID_MODEL_FROM_DATABASE=G33/P35 Neo
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #6 (G33/P35 Neo)
+
+pci:v00008086d00002939sv00001AF4sd00001100*
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #6 (QEMU Virtual Machine)
 
 pci:v00008086d00002939sv00008086sd00005044*
- ID_MODEL_FROM_DATABASE=Desktop Board DP35DP
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #6 (Desktop Board DP35DP)
 
 pci:v00008086d00002939sv0000E4BFsd0000CC4D*
- ID_MODEL_FROM_DATABASE=CCM-BOOGIE
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB UHCI Controller #6 (CCM-BOOGIE)
 
 pci:v00008086d0000293A*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #1
 
 pci:v00008086d0000293Asv00001028sd0000020D*
- ID_MODEL_FROM_DATABASE=Inspiron 530
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #1 (Inspiron 530)
 
 pci:v00008086d0000293Asv00001028sd0000020F*
- ID_MODEL_FROM_DATABASE=PowerEdge R300 onboard EHCI
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #1 (PowerEdge R300 onboard EHCI)
 
 pci:v00008086d0000293Asv00001028sd00000210*
- ID_MODEL_FROM_DATABASE=PowerEdge T300 onboard EHCI
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #1 (PowerEdge T300 onboard EHCI)
 
 pci:v00008086d0000293Asv00001028sd00000211*
- ID_MODEL_FROM_DATABASE=Optiplex 755
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #1 (Optiplex 755)
 
 pci:v00008086d0000293Asv00001028sd00000235*
- ID_MODEL_FROM_DATABASE=PowerEdge R710 USB EHCI Controller
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #1 (PowerEdge R710 USB EHCI Controller)
 
 pci:v00008086d0000293Asv00001028sd00000236*
- ID_MODEL_FROM_DATABASE=PowerEdge R610 USB EHCI Controller
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #1 (PowerEdge R610 USB EHCI Controller)
 
 pci:v00008086d0000293Asv00001028sd00000237*
- ID_MODEL_FROM_DATABASE=PowerEdge T610 USB EHCI Controller
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #1 (PowerEdge T610 USB EHCI Controller)
 
 pci:v00008086d0000293Asv00001028sd0000023C*
- ID_MODEL_FROM_DATABASE=PowerEdge R200 onboard EHCI
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #1 (PowerEdge R200 onboard EHCI)
 
 pci:v00008086d0000293Asv00001028sd00000287*
- ID_MODEL_FROM_DATABASE=PowerEdge M610 onboard EHCI
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #1 (PowerEdge M610 onboard EHCI)
 
 pci:v00008086d0000293Asv00001028sd0000029C*
- ID_MODEL_FROM_DATABASE=PowerEdge M710 USB EHCI Controller
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #1 (PowerEdge M710 USB EHCI Controller)
+
+pci:v00008086d0000293Asv0000103Csd00002A6F*
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #1 (Asus IPIBL-LB Motherboard)
 
 pci:v00008086d0000293Asv00001043sd00008277*
- ID_MODEL_FROM_DATABASE=P5K PRO Motherboard
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #1 (P5K PRO Motherboard)
 
 pci:v00008086d0000293Asv00001462sd00007360*
- ID_MODEL_FROM_DATABASE=G33/P35 Neo
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #1 (G33/P35 Neo)
+
+pci:v00008086d0000293Asv00001AF4sd00001100*
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #1 (QEMU Virtual Machine)
 
 pci:v00008086d0000293Asv00008086sd00005044*
- ID_MODEL_FROM_DATABASE=Desktop Board DP35DP
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #1 (Desktop Board DP35DP)
 
 pci:v00008086d0000293Asv0000E4BFsd0000CC4D*
- ID_MODEL_FROM_DATABASE=CCM-BOOGIE
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #1 (CCM-BOOGIE)
 
 pci:v00008086d0000293C*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #2
 
 pci:v00008086d0000293Csv00001028sd0000020D*
- ID_MODEL_FROM_DATABASE=Inspiron 530
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #2 (Inspiron 530)
 
 pci:v00008086d0000293Csv00001028sd00000211*
- ID_MODEL_FROM_DATABASE=Optiplex 755
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #2 (Optiplex 755)
 
 pci:v00008086d0000293Csv00001028sd00000235*
- ID_MODEL_FROM_DATABASE=PowerEdge R710 USB EHCI Controller
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #2 (PowerEdge R710 USB EHCI Controller)
 
 pci:v00008086d0000293Csv00001028sd00000236*
- ID_MODEL_FROM_DATABASE=PowerEdge R610 USB EHCI Controller
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #2 (PowerEdge R610 USB EHCI Controller)
 
 pci:v00008086d0000293Csv00001028sd00000237*
- ID_MODEL_FROM_DATABASE=PowerEdge T610 USB EHCI Controller
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #2 (PowerEdge T610 USB EHCI Controller)
 
 pci:v00008086d0000293Csv00001028sd00000287*
- ID_MODEL_FROM_DATABASE=PowerEdge M610 onboard EHCI
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #2 (PowerEdge M610 onboard EHCI)
 
 pci:v00008086d0000293Csv00001028sd0000029C*
- ID_MODEL_FROM_DATABASE=PowerEdge M710 USB EHCI Controller
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #2 (PowerEdge M710 USB EHCI Controller)
+
+pci:v00008086d0000293Csv0000103Csd00002A6F*
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #2 (Asus IPIBL-LB Motherboard)
 
 pci:v00008086d0000293Csv00001043sd00008277*
- ID_MODEL_FROM_DATABASE=P5K PRO Motherboard
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #2 (P5K PRO Motherboard)
 
 pci:v00008086d0000293Csv00001462sd00007360*
- ID_MODEL_FROM_DATABASE=G33/P35 Neo
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #2 (G33/P35 Neo)
+
+pci:v00008086d0000293Csv00001AF4sd00001100*
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #2 (QEMU Virtual Machine)
 
 pci:v00008086d0000293Csv00008086sd0000293C*
- ID_MODEL_FROM_DATABASE=Optiplex 755
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #2 (Optiplex 755)
 
 pci:v00008086d0000293Csv00008086sd00005044*
- ID_MODEL_FROM_DATABASE=Desktop Board DP35DP
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #2 (Desktop Board DP35DP)
 
 pci:v00008086d0000293Csv0000E4BFsd0000CC4D*
- ID_MODEL_FROM_DATABASE=CCM-BOOGIE
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) USB2 EHCI Controller #2 (CCM-BOOGIE)
 
 pci:v00008086d0000293E*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) HD Audio Controller
 
 pci:v00008086d0000293Esv00001028sd0000020D*
- ID_MODEL_FROM_DATABASE=Inspiron 530
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) HD Audio Controller (Inspiron 530)
 
 pci:v00008086d0000293Esv00001028sd00000211*
- ID_MODEL_FROM_DATABASE=Optiplex 755
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) HD Audio Controller (Optiplex 755)
+
+pci:v00008086d0000293Esv0000103Csd00002A6F*
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) HD Audio Controller (Asus IPIBL-LB Motherboard)
 
 pci:v00008086d0000293Esv0000103Csd00003628*
- ID_MODEL_FROM_DATABASE=dv6-1190en
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) HD Audio Controller (dv6-1190en)
 
 pci:v00008086d0000293Esv00001043sd0000829F*
- ID_MODEL_FROM_DATABASE=P5K PRO Motherboard
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) HD Audio Controller (P5K PRO Motherboard)
 
 pci:v00008086d0000293Esv00001462sd00007360*
- ID_MODEL_FROM_DATABASE=G33/P35 Neo
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) HD Audio Controller (G33/P35 Neo)
+
+pci:v00008086d0000293Esv00001AF4sd00001100*
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) HD Audio Controller (QEMU Virtual Machine)
 
 pci:v00008086d0000293Esv00008086sd0000293E*
- ID_MODEL_FROM_DATABASE=Optiplex 755
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) HD Audio Controller (Optiplex 755)
 
 pci:v00008086d0000293Esv00008086sd00002940*
- ID_MODEL_FROM_DATABASE=Optiplex 755
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) HD Audio Controller (Optiplex 755)
 
 pci:v00008086d0000293Esv0000E4BFsd0000CC4D*
- ID_MODEL_FROM_DATABASE=CCM-BOOGIE
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) HD Audio Controller (CCM-BOOGIE)
 
 pci:v00008086d00002940*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) PCI Express Port 1
 
 pci:v00008086d00002940sv00001028sd0000020D*
- ID_MODEL_FROM_DATABASE=Inspiron 530
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) PCI Express Port 1 (Inspiron 530)
 
 pci:v00008086d00002940sv00001028sd00000211*
- ID_MODEL_FROM_DATABASE=Optiplex 755
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) PCI Express Port 1 (Optiplex 755)
+
+pci:v00008086d00002940sv0000103Csd00002A6F*
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) PCI Express Port 1 (Asus IPIBL-LB Motherboard)
 
 pci:v00008086d00002940sv00001043sd00008277*
- ID_MODEL_FROM_DATABASE=P5K PRO Motherboard
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) PCI Express Port 1 (P5K PRO Motherboard)
 
 pci:v00008086d00002940sv00008086sd00002940*
- ID_MODEL_FROM_DATABASE=Optiplex 755
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) PCI Express Port 1 (Optiplex 755)
 
 pci:v00008086d00002942*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) PCI Express Port 2
 
 pci:v00008086d00002942sv00001028sd0000020D*
- ID_MODEL_FROM_DATABASE=Inspiron 530
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) PCI Express Port 2 (Inspiron 530)
 
 pci:v00008086d00002944*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) PCI Express Port 3
 
 pci:v00008086d00002944sv00001028sd0000020D*
- ID_MODEL_FROM_DATABASE=Inspiron 530
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) PCI Express Port 3 (Inspiron 530)
+
+pci:v00008086d00002944sv0000103Csd00002A6F*
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) PCI Express Port 3 (Asus IPIBL-LB Motherboard)
 
 pci:v00008086d00002946*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) PCI Express Port 4
 
 pci:v00008086d00002946sv00001028sd0000020D*
- ID_MODEL_FROM_DATABASE=Inspiron 530
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) PCI Express Port 4 (Inspiron 530)
 
 pci:v00008086d00002948*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) PCI Express Port 5
 
 pci:v00008086d00002948sv00001028sd0000020D*
- ID_MODEL_FROM_DATABASE=Inspiron 530
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) PCI Express Port 5 (Inspiron 530)
 
 pci:v00008086d00002948sv00001043sd00008277*
- ID_MODEL_FROM_DATABASE=P5K PRO Motherboard
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) PCI Express Port 5 (P5K PRO Motherboard)
 
 pci:v00008086d0000294A*
  ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) PCI Express Port 6
 
 pci:v00008086d0000294Asv00001028sd0000020D*
- ID_MODEL_FROM_DATABASE=Inspiron 530
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) PCI Express Port 6 (Inspiron 530)
 
 pci:v00008086d0000294Asv00001043sd00008277*
- ID_MODEL_FROM_DATABASE=P5K PRO Motherboard
+ ID_MODEL_FROM_DATABASE=82801I (ICH9 Family) PCI Express Port 6 (P5K PRO Motherboard)
 
 pci:v00008086d0000294C*
  ID_MODEL_FROM_DATABASE=82566DC-2 Gigabit Network Connection
 
 pci:v00008086d0000294Csv000017AAsd0000302E*
- ID_MODEL_FROM_DATABASE=82566DM-2 Gigabit Network Connection
+ ID_MODEL_FROM_DATABASE=82566DC-2 Gigabit Network Connection (82566DM-2 Gigabit Network Connection)
 
 pci:v00008086d00002970*
  ID_MODEL_FROM_DATABASE=82946GZ/PL/GL Memory Controller Hub
@@ -64803,7 +66798,7 @@ pci:v00008086d00002990*
  ID_MODEL_FROM_DATABASE=82Q963/Q965 Memory Controller Hub
 
 pci:v00008086d00002990sv00001028sd000001DA*
- ID_MODEL_FROM_DATABASE=OptiPlex 745
+ ID_MODEL_FROM_DATABASE=82Q963/Q965 Memory Controller Hub (OptiPlex 745)
 
 pci:v00008086d00002991*
  ID_MODEL_FROM_DATABASE=82Q963/Q965 PCI Express Root Port
@@ -64830,10 +66825,10 @@ pci:v00008086d000029A0*
  ID_MODEL_FROM_DATABASE=82P965/G965 Memory Controller Hub
 
 pci:v00008086d000029A0sv00001043sd000081EA*
- ID_MODEL_FROM_DATABASE=P5B
+ ID_MODEL_FROM_DATABASE=82P965/G965 Memory Controller Hub (P5B)
 
 pci:v00008086d000029A0sv00001462sd00007276*
- ID_MODEL_FROM_DATABASE=MS-7276 [G965MDH]
+ ID_MODEL_FROM_DATABASE=82P965/G965 Memory Controller Hub (MS-7276 [G965MDH])
 
 pci:v00008086d000029A1*
  ID_MODEL_FROM_DATABASE=82P965/G965 PCI Express Root Port
@@ -64842,7 +66837,7 @@ pci:v00008086d000029A2*
  ID_MODEL_FROM_DATABASE=82G965 Integrated Graphics Controller
 
 pci:v00008086d000029A2sv00001462sd00007276*
- ID_MODEL_FROM_DATABASE=MS-7276 [G965MDH]
+ ID_MODEL_FROM_DATABASE=82G965 Integrated Graphics Controller (MS-7276 [G965MDH])
 
 pci:v00008086d000029A3*
  ID_MODEL_FROM_DATABASE=82G965 Integrated Graphics Controller
@@ -64863,31 +66858,31 @@ pci:v00008086d000029B0*
  ID_MODEL_FROM_DATABASE=82Q35 Express DRAM Controller
 
 pci:v00008086d000029B0sv00001028sd00000211*
- ID_MODEL_FROM_DATABASE=OptiPlex 755
+ ID_MODEL_FROM_DATABASE=82Q35 Express DRAM Controller (OptiPlex 755)
 
 pci:v00008086d000029B1*
  ID_MODEL_FROM_DATABASE=82Q35 Express PCI Express Root Port
 
 pci:v00008086d000029B1sv00001028sd00000211*
- ID_MODEL_FROM_DATABASE=OptiPlex 755
+ ID_MODEL_FROM_DATABASE=82Q35 Express PCI Express Root Port (OptiPlex 755)
 
 pci:v00008086d000029B2*
  ID_MODEL_FROM_DATABASE=82Q35 Express Integrated Graphics Controller
 
 pci:v00008086d000029B2sv00001028sd00000211*
- ID_MODEL_FROM_DATABASE=OptiPlex 755
+ ID_MODEL_FROM_DATABASE=82Q35 Express Integrated Graphics Controller (OptiPlex 755)
 
 pci:v00008086d000029B3*
  ID_MODEL_FROM_DATABASE=82Q35 Express Integrated Graphics Controller
 
 pci:v00008086d000029B3sv00001028sd00000211*
- ID_MODEL_FROM_DATABASE=OptiPlex 755
+ ID_MODEL_FROM_DATABASE=82Q35 Express Integrated Graphics Controller (OptiPlex 755)
 
 pci:v00008086d000029B4*
  ID_MODEL_FROM_DATABASE=82Q35 Express MEI Controller
 
 pci:v00008086d000029B4sv00001028sd00000211*
- ID_MODEL_FROM_DATABASE=OptiPlex 755
+ ID_MODEL_FROM_DATABASE=82Q35 Express MEI Controller (OptiPlex 755)
 
 pci:v00008086d000029B5*
  ID_MODEL_FROM_DATABASE=82Q35 Express MEI Controller
@@ -64896,64 +66891,70 @@ pci:v00008086d000029B6*
  ID_MODEL_FROM_DATABASE=82Q35 Express PT IDER Controller
 
 pci:v00008086d000029B6sv00001028sd00000211*
- ID_MODEL_FROM_DATABASE=OptiPlex 755
+ ID_MODEL_FROM_DATABASE=82Q35 Express PT IDER Controller (OptiPlex 755)
 
 pci:v00008086d000029B7*
  ID_MODEL_FROM_DATABASE=82Q35 Express Serial KT Controller
 
 pci:v00008086d000029B7sv00001028sd00000211*
- ID_MODEL_FROM_DATABASE=OptiPlex 755
+ ID_MODEL_FROM_DATABASE=82Q35 Express Serial KT Controller (OptiPlex 755)
 
 pci:v00008086d000029C0*
  ID_MODEL_FROM_DATABASE=82G33/G31/P35/P31 Express DRAM Controller
 
 pci:v00008086d000029C0sv00001028sd0000020D*
- ID_MODEL_FROM_DATABASE=Inspiron 530
+ ID_MODEL_FROM_DATABASE=82G33/G31/P35/P31 Express DRAM Controller (Inspiron 530)
+
+pci:v00008086d000029C0sv0000103Csd00002A6F*
+ ID_MODEL_FROM_DATABASE=82G33/G31/P35/P31 Express DRAM Controller (Asus IPIBL-LB Motherboard)
 
 pci:v00008086d000029C0sv00001043sd00008276*
- ID_MODEL_FROM_DATABASE=P5K PRO Motherboard
+ ID_MODEL_FROM_DATABASE=82G33/G31/P35/P31 Express DRAM Controller (P5K PRO Motherboard)
 
 pci:v00008086d000029C0sv00001043sd000082B0*
- ID_MODEL_FROM_DATABASE=P5KPL-VM Motherboard
+ ID_MODEL_FROM_DATABASE=82G33/G31/P35/P31 Express DRAM Controller (P5KPL-VM Motherboard)
 
 pci:v00008086d000029C0sv00001462sd00007360*
- ID_MODEL_FROM_DATABASE=G33/P35 Neo
+ ID_MODEL_FROM_DATABASE=82G33/G31/P35/P31 Express DRAM Controller (G33/P35 Neo)
+
+pci:v00008086d000029C0sv00001AF4sd00001100*
+ ID_MODEL_FROM_DATABASE=82G33/G31/P35/P31 Express DRAM Controller (QEMU Virtual Machine)
 
 pci:v00008086d000029C0sv00008086sd00005044*
- ID_MODEL_FROM_DATABASE=Desktop Board DP35DP
+ ID_MODEL_FROM_DATABASE=82G33/G31/P35/P31 Express DRAM Controller (Desktop Board DP35DP)
 
 pci:v00008086d000029C1*
  ID_MODEL_FROM_DATABASE=82G33/G31/P35/P31 Express PCI Express Root Port
 
 pci:v00008086d000029C1sv00001028sd0000020D*
- ID_MODEL_FROM_DATABASE=Inspiron 530
+ ID_MODEL_FROM_DATABASE=82G33/G31/P35/P31 Express PCI Express Root Port (Inspiron 530)
 
 pci:v00008086d000029C1sv00001043sd00008276*
- ID_MODEL_FROM_DATABASE=P5K PRO Motherboard
+ ID_MODEL_FROM_DATABASE=82G33/G31/P35/P31 Express PCI Express Root Port (P5K PRO Motherboard)
 
 pci:v00008086d000029C2*
  ID_MODEL_FROM_DATABASE=82G33/G31 Express Integrated Graphics Controller
 
 pci:v00008086d000029C2sv00001028sd0000020D*
- ID_MODEL_FROM_DATABASE=Inspiron 530
+ ID_MODEL_FROM_DATABASE=82G33/G31 Express Integrated Graphics Controller (Inspiron 530)
 
 pci:v00008086d000029C2sv00001043sd000082B0*
- ID_MODEL_FROM_DATABASE=P5KPL-VM Motherboard
+ ID_MODEL_FROM_DATABASE=82G33/G31 Express Integrated Graphics Controller (P5KPL-VM Motherboard)
 
 pci:v00008086d000029C3*
  ID_MODEL_FROM_DATABASE=82G33/G31 Express Integrated Graphics Controller
 
 pci:v00008086d000029C3sv00001028sd0000020D*
- ID_MODEL_FROM_DATABASE=Inspiron 530
+ ID_MODEL_FROM_DATABASE=82G33/G31 Express Integrated Graphics Controller (Inspiron 530)
 
 pci:v00008086d000029C3sv00001043sd000082B0*
- ID_MODEL_FROM_DATABASE=P5KPL-VM Motherboard
+ ID_MODEL_FROM_DATABASE=82G33/G31 Express Integrated Graphics Controller (P5KPL-VM Motherboard)
 
 pci:v00008086d000029C4*
  ID_MODEL_FROM_DATABASE=82G33/G31/P35/P31 Express MEI Controller
 
 pci:v00008086d000029C4sv00008086sd00005044*
- ID_MODEL_FROM_DATABASE=Desktop Board DP35DP
+ ID_MODEL_FROM_DATABASE=82G33/G31/P35/P31 Express MEI Controller (Desktop Board DP35DP)
 
 pci:v00008086d000029C5*
  ID_MODEL_FROM_DATABASE=82G33/G31/P35/P31 Express MEI Controller
@@ -65037,37 +67038,40 @@ pci:v00008086d00002A00*
  ID_MODEL_FROM_DATABASE=Mobile PM965/GM965/GL960 Memory Controller Hub
 
 pci:v00008086d00002A00sv00001025sd00000121*
- ID_MODEL_FROM_DATABASE=Acer Aspire 5920G
+ ID_MODEL_FROM_DATABASE=Mobile PM965/GM965/GL960 Memory Controller Hub (Acer Aspire 5920G)
 
 pci:v00008086d00002A00sv00001028sd000001F3*
- ID_MODEL_FROM_DATABASE=Inspiron 1420
+ ID_MODEL_FROM_DATABASE=Mobile PM965/GM965/GL960 Memory Controller Hub (Inspiron 1420)
 
 pci:v00008086d00002A00sv0000103Csd000030C0*
- ID_MODEL_FROM_DATABASE=Compaq 6710b
+ ID_MODEL_FROM_DATABASE=Mobile PM965/GM965/GL960 Memory Controller Hub (Compaq 6710b)
 
 pci:v00008086d00002A00sv0000103Csd000030C1*
- ID_MODEL_FROM_DATABASE=Compaq 6910p
+ ID_MODEL_FROM_DATABASE=Mobile PM965/GM965/GL960 Memory Controller Hub (Compaq 6910p)
 
 pci:v00008086d00002A00sv0000103Csd000030CC*
- ID_MODEL_FROM_DATABASE=Pavilion dv6700
+ ID_MODEL_FROM_DATABASE=Mobile PM965/GM965/GL960 Memory Controller Hub (Pavilion dv6700)
 
 pci:v00008086d00002A00sv0000103Csd000030D9*
- ID_MODEL_FROM_DATABASE=Presario C700
+ ID_MODEL_FROM_DATABASE=Mobile PM965/GM965/GL960 Memory Controller Hub (Presario C700)
 
 pci:v00008086d00002A00sv0000104Dsd00009005*
- ID_MODEL_FROM_DATABASE=Vaio VGN-FZ260E
+ ID_MODEL_FROM_DATABASE=Mobile PM965/GM965/GL960 Memory Controller Hub (Vaio VGN-FZ260E)
 
 pci:v00008086d00002A00sv0000104Dsd0000902D*
- ID_MODEL_FROM_DATABASE=VAIO VGN-NR120E
+ ID_MODEL_FROM_DATABASE=Mobile PM965/GM965/GL960 Memory Controller Hub (VAIO VGN-NR120E)
 
 pci:v00008086d00002A00sv000017AAsd000020B1*
- ID_MODEL_FROM_DATABASE=ThinkPad T61
+ ID_MODEL_FROM_DATABASE=Mobile PM965/GM965/GL960 Memory Controller Hub (ThinkPad T61)
 
 pci:v00008086d00002A00sv000017AAsd000020B3*
- ID_MODEL_FROM_DATABASE=ThinkPad T61/R61
+ ID_MODEL_FROM_DATABASE=Mobile PM965/GM965/GL960 Memory Controller Hub (ThinkPad T61/R61)
+
+pci:v00008086d00002A00sv000017C0sd00004082*
+ ID_MODEL_FROM_DATABASE=Mobile PM965/GM965/GL960 Memory Controller Hub (Medion WIM 2210 Notebook PC [MD96850])
 
 pci:v00008086d00002A00sv0000E4BFsd0000CC47*
- ID_MODEL_FROM_DATABASE=CCG-RUMBA
+ ID_MODEL_FROM_DATABASE=Mobile PM965/GM965/GL960 Memory Controller Hub (CCG-RUMBA)
 
 pci:v00008086d00002A01*
  ID_MODEL_FROM_DATABASE=Mobile PM965/GM965/GL960 PCI Express Root Port
@@ -65076,52 +67080,58 @@ pci:v00008086d00002A02*
  ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (primary)
 
 pci:v00008086d00002A02sv00001028sd000001F3*
- ID_MODEL_FROM_DATABASE=Inspiron 1420
+ ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (primary) (Inspiron 1420)
 
 pci:v00008086d00002A02sv00001028sd000001F9*
- ID_MODEL_FROM_DATABASE=Latitude D630
+ ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (primary) (Latitude D630)
 
 pci:v00008086d00002A02sv0000103Csd000030C0*
- ID_MODEL_FROM_DATABASE=Compaq 6710b
+ ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (primary) (Compaq 6710b)
 
 pci:v00008086d00002A02sv0000103Csd000030D9*
- ID_MODEL_FROM_DATABASE=Presario C700
+ ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (primary) (Presario C700)
 
 pci:v00008086d00002A02sv0000104Dsd0000902D*
- ID_MODEL_FROM_DATABASE=VAIO VGN-NR120E
+ ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (primary) (VAIO VGN-NR120E)
 
 pci:v00008086d00002A02sv000017AAsd000020B5*
- ID_MODEL_FROM_DATABASE=ThinkPad T61/R61
+ ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (primary) (ThinkPad T61/R61)
+
+pci:v00008086d00002A02sv000017C0sd00004082*
+ ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (primary) (Medion WIM 2210 Notebook PC [MD96850])
 
 pci:v00008086d00002A02sv0000E4BFsd0000CC47*
- ID_MODEL_FROM_DATABASE=CCG-RUMBA
+ ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (primary) (CCG-RUMBA)
 
 pci:v00008086d00002A03*
  ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (secondary)
 
 pci:v00008086d00002A03sv00001028sd000001F3*
- ID_MODEL_FROM_DATABASE=Dell Inspiron 1420
+ ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (secondary) (Inspiron 1420)
 
 pci:v00008086d00002A03sv0000103Csd000030C0*
- ID_MODEL_FROM_DATABASE=Compaq 6710b
+ ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (secondary) (Compaq 6710b)
 
 pci:v00008086d00002A03sv0000103Csd000030D9*
- ID_MODEL_FROM_DATABASE=Presario C700
+ ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (secondary) (Presario C700)
 
 pci:v00008086d00002A03sv0000104Dsd0000902D*
- ID_MODEL_FROM_DATABASE=VAIO VGN-NR120E
+ ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (secondary) (VAIO VGN-NR120E)
 
 pci:v00008086d00002A03sv000017AAsd000020B5*
- ID_MODEL_FROM_DATABASE=ThinkPad T61/R61
+ ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (secondary) (ThinkPad T61/R61)
+
+pci:v00008086d00002A03sv000017C0sd00004082*
+ ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (secondary) (Medion WIM 2210 Notebook PC [MD96850])
 
 pci:v00008086d00002A03sv0000E4BFsd0000CC47*
- ID_MODEL_FROM_DATABASE=CCG-RUMBA
+ ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (secondary) (CCG-RUMBA)
 
 pci:v00008086d00002A04*
  ID_MODEL_FROM_DATABASE=Mobile PM965/GM965 MEI Controller
 
 pci:v00008086d00002A04sv0000103Csd000030C1*
- ID_MODEL_FROM_DATABASE=Compaq 6910p
+ ID_MODEL_FROM_DATABASE=Mobile PM965/GM965 MEI Controller (Compaq 6910p)
 
 pci:v00008086d00002A05*
  ID_MODEL_FROM_DATABASE=Mobile PM965/GM965 MEI Controller
@@ -65130,19 +67140,19 @@ pci:v00008086d00002A06*
  ID_MODEL_FROM_DATABASE=Mobile PM965/GM965 PT IDER Controller
 
 pci:v00008086d00002A06sv0000103Csd000030C1*
- ID_MODEL_FROM_DATABASE=Compaq 6910p
+ ID_MODEL_FROM_DATABASE=Mobile PM965/GM965 PT IDER Controller (Compaq 6910p)
 
 pci:v00008086d00002A07*
  ID_MODEL_FROM_DATABASE=Mobile PM965/GM965 KT Controller
 
 pci:v00008086d00002A07sv0000103Csd000030C1*
- ID_MODEL_FROM_DATABASE=Compaq 6910p
+ ID_MODEL_FROM_DATABASE=Mobile PM965/GM965 KT Controller (Compaq 6910p)
 
 pci:v00008086d00002A10*
  ID_MODEL_FROM_DATABASE=Mobile GME965/GLE960 Memory Controller Hub
 
 pci:v00008086d00002A10sv0000E4BFsd0000CC47*
- ID_MODEL_FROM_DATABASE=CCG-RUMBA
+ ID_MODEL_FROM_DATABASE=Mobile GME965/GLE960 Memory Controller Hub (CCG-RUMBA)
 
 pci:v00008086d00002A11*
  ID_MODEL_FROM_DATABASE=Mobile GME965/GLE960 PCI Express Root Port
@@ -65151,13 +67161,13 @@ pci:v00008086d00002A12*
  ID_MODEL_FROM_DATABASE=Mobile GME965/GLE960 Integrated Graphics Controller
 
 pci:v00008086d00002A12sv0000E4BFsd0000CC47*
- ID_MODEL_FROM_DATABASE=CCG-RUMBA
+ ID_MODEL_FROM_DATABASE=Mobile GME965/GLE960 Integrated Graphics Controller (CCG-RUMBA)
 
 pci:v00008086d00002A13*
  ID_MODEL_FROM_DATABASE=Mobile GME965/GLE960 Integrated Graphics Controller
 
 pci:v00008086d00002A13sv0000E4BFsd0000CC47*
- ID_MODEL_FROM_DATABASE=CCG-RUMBA
+ ID_MODEL_FROM_DATABASE=Mobile GME965/GLE960 Integrated Graphics Controller (CCG-RUMBA)
 
 pci:v00008086d00002A14*
  ID_MODEL_FROM_DATABASE=Mobile GME965/GLE960 MEI Controller
@@ -65175,25 +67185,25 @@ pci:v00008086d00002A40*
  ID_MODEL_FROM_DATABASE=Mobile 4 Series Chipset Memory Controller Hub
 
 pci:v00008086d00002A40sv0000E4BFsd0000CC4D*
- ID_MODEL_FROM_DATABASE=CCM-BOOGIE
+ ID_MODEL_FROM_DATABASE=Mobile 4 Series Chipset Memory Controller Hub (CCM-BOOGIE)
 
 pci:v00008086d00002A41*
  ID_MODEL_FROM_DATABASE=Mobile 4 Series Chipset PCI Express Graphics Port
 
 pci:v00008086d00002A41sv0000E4BFsd0000CC4D*
- ID_MODEL_FROM_DATABASE=CCM-BOOGIE
+ ID_MODEL_FROM_DATABASE=Mobile 4 Series Chipset PCI Express Graphics Port (CCM-BOOGIE)
 
 pci:v00008086d00002A42*
  ID_MODEL_FROM_DATABASE=Mobile 4 Series Chipset Integrated Graphics Controller
 
 pci:v00008086d00002A42sv0000E4BFsd0000CC4D*
- ID_MODEL_FROM_DATABASE=CCM-BOOGIE
+ ID_MODEL_FROM_DATABASE=Mobile 4 Series Chipset Integrated Graphics Controller (CCM-BOOGIE)
 
 pci:v00008086d00002A43*
  ID_MODEL_FROM_DATABASE=Mobile 4 Series Chipset Integrated Graphics Controller
 
 pci:v00008086d00002A43sv0000E4BFsd0000CC4D*
- ID_MODEL_FROM_DATABASE=CCM-BOOGIE
+ ID_MODEL_FROM_DATABASE=Mobile 4 Series Chipset Integrated Graphics Controller (CCM-BOOGIE)
 
 pci:v00008086d00002A44*
  ID_MODEL_FROM_DATABASE=Mobile 4 Series Chipset MEI Controller
@@ -65589,13 +67599,13 @@ pci:v00008086d00002D10*
  ID_MODEL_FROM_DATABASE=Core Processor QPI Link 0
 
 pci:v00008086d00002D11*
- ID_MODEL_FROM_DATABASE=Core Processor QPI Physical 0
+ ID_MODEL_FROM_DATABASE=1st Generation Core Processor QPI Physical 0
 
 pci:v00008086d00002D12*
- ID_MODEL_FROM_DATABASE=Core Processor Reserved
+ ID_MODEL_FROM_DATABASE=1st Generation Core Processor Reserved
 
 pci:v00008086d00002D13*
- ID_MODEL_FROM_DATABASE=Core Processor Reserved
+ ID_MODEL_FROM_DATABASE=1st Generation Core Processor Reserved
 
 pci:v00008086d00002D81*
  ID_MODEL_FROM_DATABASE=Xeon 5600 Series QuickPath Architecture System Address Decoder
@@ -65699,6 +67709,9 @@ pci:v00008086d00002E11*
 pci:v00008086d00002E12*
  ID_MODEL_FROM_DATABASE=4 Series Chipset Integrated Graphics Controller
 
+pci:v00008086d00002E12sv000017AAsd00003048*
+ ID_MODEL_FROM_DATABASE=4 Series Chipset Integrated Graphics Controller (ThinkCentre M6258)
+
 pci:v00008086d00002E13*
  ID_MODEL_FROM_DATABASE=4 Series Chipset Integrated Graphics Controller
 
@@ -65718,34 +67731,34 @@ pci:v00008086d00002E20*
  ID_MODEL_FROM_DATABASE=4 Series Chipset DRAM Controller
 
 pci:v00008086d00002E20sv00001028sd00000283*
- ID_MODEL_FROM_DATABASE=Dell Vostro 220
+ ID_MODEL_FROM_DATABASE=4 Series Chipset DRAM Controller (Dell Vostro 220)
 
 pci:v00008086d00002E20sv00001043sd000082D3*
- ID_MODEL_FROM_DATABASE=P5Q Deluxe Motherboard
+ ID_MODEL_FROM_DATABASE=4 Series Chipset DRAM Controller (P5Q Deluxe Motherboard)
 
 pci:v00008086d00002E20sv00001458sd00005000*
- ID_MODEL_FROM_DATABASE=GA-EP45-DS5/GA-EG45M-DS2H Motherboard
+ ID_MODEL_FROM_DATABASE=4 Series Chipset DRAM Controller (GA-EP45-DS5/GA-EG45M-DS2H Motherboard)
 
 pci:v00008086d00002E21*
  ID_MODEL_FROM_DATABASE=4 Series Chipset PCI Express Root Port
 
 pci:v00008086d00002E21sv00001043sd000082D3*
- ID_MODEL_FROM_DATABASE=P5Q Deluxe Motherboard
+ ID_MODEL_FROM_DATABASE=4 Series Chipset PCI Express Root Port (P5Q Deluxe Motherboard)
 
 pci:v00008086d00002E21sv00001458sd00005000*
- ID_MODEL_FROM_DATABASE=GA-EP45-DS5 Motherboard
+ ID_MODEL_FROM_DATABASE=4 Series Chipset PCI Express Root Port (GA-EP45-DS5 Motherboard)
 
 pci:v00008086d00002E22*
  ID_MODEL_FROM_DATABASE=4 Series Chipset Integrated Graphics Controller
 
 pci:v00008086d00002E22sv00001458sd0000D000*
- ID_MODEL_FROM_DATABASE=GA-EG45M-DS2H Mainboard
+ ID_MODEL_FROM_DATABASE=4 Series Chipset Integrated Graphics Controller (GA-EG45M-DS2H Mainboard)
 
 pci:v00008086d00002E23*
  ID_MODEL_FROM_DATABASE=4 Series Chipset Integrated Graphics Controller
 
 pci:v00008086d00002E23sv00001458sd0000D000*
- ID_MODEL_FROM_DATABASE=GA-EG45M-DS2H Mainboard
+ ID_MODEL_FROM_DATABASE=4 Series Chipset Integrated Graphics Controller (GA-EG45M-DS2H Mainboard)
 
 pci:v00008086d00002E24*
  ID_MODEL_FROM_DATABASE=4 Series Chipset HECI Controller
@@ -66050,6 +68063,9 @@ pci:v00008086d00002F37*
 pci:v00008086d00002F38*
  ID_MODEL_FROM_DATABASE=Haswell-E Home Agent 1
 
+pci:v00008086d00002F39*
+ ID_MODEL_FROM_DATABASE=Haswell-E I/O Performance Monitoring
+
 pci:v00008086d00002F3A*
  ID_MODEL_FROM_DATABASE=Haswell-E QPI Link 2
 
@@ -66381,16 +68397,16 @@ pci:v00008086d00003200*
  ID_MODEL_FROM_DATABASE=GD31244 PCI-X SATA HBA
 
 pci:v00008086d00003200sv00001775sd0000C200*
- ID_MODEL_FROM_DATABASE=C2K onboard SATA host bus adapter
+ ID_MODEL_FROM_DATABASE=GD31244 PCI-X SATA HBA (C2K onboard SATA host bus adapter)
 
 pci:v00008086d00003310*
  ID_MODEL_FROM_DATABASE=IOP348 I/O Processor
 
 pci:v00008086d00003310sv00001054sd00003030*
- ID_MODEL_FROM_DATABASE=HRA380 Hitachi RAID Adapter to PCIe
+ ID_MODEL_FROM_DATABASE=IOP348 I/O Processor (HRA380 Hitachi RAID Adapter to PCIe)
 
 pci:v00008086d00003310sv00001054sd00003034*
- ID_MODEL_FROM_DATABASE=HRA381 Hitachi RAID Adapter to PCIe
+ ID_MODEL_FROM_DATABASE=IOP348 I/O Processor (HRA381 Hitachi RAID Adapter to PCIe)
 
 pci:v00008086d00003313*
  ID_MODEL_FROM_DATABASE=IOP348 I/O Processor (SL8e) in IOC Mode SAS/SATA
@@ -66408,31 +68424,31 @@ pci:v00008086d00003340*
  ID_MODEL_FROM_DATABASE=82855PM Processor to I/O Controller
 
 pci:v00008086d00003340sv00001014sd00000529*
- ID_MODEL_FROM_DATABASE=Thinkpad T40 series
+ ID_MODEL_FROM_DATABASE=82855PM Processor to I/O Controller (Thinkpad T40 series)
 
 pci:v00008086d00003340sv00001025sd0000005A*
- ID_MODEL_FROM_DATABASE=TravelMate 290
+ ID_MODEL_FROM_DATABASE=82855PM Processor to I/O Controller (TravelMate 290)
 
 pci:v00008086d00003340sv0000103Csd0000088C*
- ID_MODEL_FROM_DATABASE=NC8000 laptop
+ ID_MODEL_FROM_DATABASE=82855PM Processor to I/O Controller (NC8000 laptop)
 
 pci:v00008086d00003340sv0000103Csd00000890*
- ID_MODEL_FROM_DATABASE=NC6000 laptop
+ ID_MODEL_FROM_DATABASE=82855PM Processor to I/O Controller (NC6000 laptop)
 
 pci:v00008086d00003340sv0000103Csd000008B0*
- ID_MODEL_FROM_DATABASE=tc1100 tablet
+ ID_MODEL_FROM_DATABASE=82855PM Processor to I/O Controller (tc1100 tablet)
 
 pci:v00008086d00003340sv0000144Dsd0000C005*
- ID_MODEL_FROM_DATABASE=X10 Laptop
+ ID_MODEL_FROM_DATABASE=82855PM Processor to I/O Controller (X10 Laptop)
 
 pci:v00008086d00003340sv0000144Dsd0000C00C*
- ID_MODEL_FROM_DATABASE=P30/P35 notebook
+ ID_MODEL_FROM_DATABASE=82855PM Processor to I/O Controller (P30/P35 notebook)
 
 pci:v00008086d00003341*
  ID_MODEL_FROM_DATABASE=82855PM Processor to AGP Controller
 
 pci:v00008086d00003341sv0000144Dsd0000C00C*
- ID_MODEL_FROM_DATABASE=P30 notebook
+ ID_MODEL_FROM_DATABASE=82855PM Processor to AGP Controller (P30 notebook)
 
 pci:v00008086d00003363*
  ID_MODEL_FROM_DATABASE=IOC340 I/O Controller in IOC Mode SAS/SATA
@@ -66459,19 +68475,19 @@ pci:v00008086d00003403*
  ID_MODEL_FROM_DATABASE=5500 I/O Hub to ESI Port
 
 pci:v00008086d00003403sv00001028sd00000236*
- ID_MODEL_FROM_DATABASE=PowerEdge R610 I/O Hub to ESI Port
+ ID_MODEL_FROM_DATABASE=5500 I/O Hub to ESI Port (PowerEdge R610 I/O Hub to ESI Port)
 
 pci:v00008086d00003403sv00001028sd00000287*
- ID_MODEL_FROM_DATABASE=PowerEdge M610 I/O Hub to ESI Port
+ ID_MODEL_FROM_DATABASE=5500 I/O Hub to ESI Port (PowerEdge M610 I/O Hub to ESI Port)
 
 pci:v00008086d00003403sv00001028sd0000028C*
- ID_MODEL_FROM_DATABASE=PowerEdge R410 I/O Hub to ESI Port
+ ID_MODEL_FROM_DATABASE=5500 I/O Hub to ESI Port (PowerEdge R410 I/O Hub to ESI Port)
 
 pci:v00008086d00003403sv00001028sd0000028D*
- ID_MODEL_FROM_DATABASE=PowerEdge T410 I/O Hub to ESI Port
+ ID_MODEL_FROM_DATABASE=5500 I/O Hub to ESI Port (PowerEdge T410 I/O Hub to ESI Port)
 
 pci:v00008086d00003403sv0000103Csd0000330B*
- ID_MODEL_FROM_DATABASE=ProLiant ML150 G6 Server
+ ID_MODEL_FROM_DATABASE=5500 I/O Hub to ESI Port (ProLiant ML150 G6 Server)
 
 pci:v00008086d00003404*
  ID_MODEL_FROM_DATABASE=5520/5500/X58 I/O Hub to ESI Port
@@ -66483,7 +68499,7 @@ pci:v00008086d00003406*
  ID_MODEL_FROM_DATABASE=5520 I/O Hub to ESI Port
 
 pci:v00008086d00003406sv0000103Csd0000330B*
- ID_MODEL_FROM_DATABASE=ProLiant G6 series
+ ID_MODEL_FROM_DATABASE=5520 I/O Hub to ESI Port (ProLiant G6 series)
 
 pci:v00008086d00003407*
  ID_MODEL_FROM_DATABASE=5520/5500/X58 I/O Hub to ESI Port
@@ -66492,7 +68508,7 @@ pci:v00008086d00003408*
  ID_MODEL_FROM_DATABASE=5520/5500/X58 I/O Hub PCI Express Root Port 1
 
 pci:v00008086d00003408sv0000103Csd0000330B*
- ID_MODEL_FROM_DATABASE=ProLiant G6 series
+ ID_MODEL_FROM_DATABASE=5520/5500/X58 I/O Hub PCI Express Root Port 1 (ProLiant G6 series)
 
 pci:v00008086d00003409*
  ID_MODEL_FROM_DATABASE=5520/5500/X58 I/O Hub PCI Express Root Port 2
@@ -66501,7 +68517,7 @@ pci:v00008086d0000340A*
  ID_MODEL_FROM_DATABASE=5520/5500/X58 I/O Hub PCI Express Root Port 3
 
 pci:v00008086d0000340Asv0000103Csd0000330B*
- ID_MODEL_FROM_DATABASE=ProLiant ML150 G6 Server
+ ID_MODEL_FROM_DATABASE=5520/5500/X58 I/O Hub PCI Express Root Port 3 (ProLiant ML150 G6 Server)
 
 pci:v00008086d0000340B*
  ID_MODEL_FROM_DATABASE=5520/X58 I/O Hub PCI Express Root Port 4
@@ -66516,7 +68532,7 @@ pci:v00008086d0000340E*
  ID_MODEL_FROM_DATABASE=5520/5500/X58 I/O Hub PCI Express Root Port 7
 
 pci:v00008086d0000340Esv0000103Csd0000330B*
- ID_MODEL_FROM_DATABASE=ProLiant ML150 G6 Server
+ ID_MODEL_FROM_DATABASE=5520/5500/X58 I/O Hub PCI Express Root Port 7 (ProLiant ML150 G6 Server)
 
 pci:v00008086d0000340F*
  ID_MODEL_FROM_DATABASE=5520/5500/X58 I/O Hub PCI Express Root Port 8
@@ -66543,13 +68559,13 @@ pci:v00008086d00003422*
  ID_MODEL_FROM_DATABASE=7500/5520/5500/X58 I/O Hub GPIO and Scratch Pad Registers
 
 pci:v00008086d00003422sv0000103Csd0000330B*
- ID_MODEL_FROM_DATABASE=ProLiant G6 series
+ ID_MODEL_FROM_DATABASE=7500/5520/5500/X58 I/O Hub GPIO and Scratch Pad Registers (ProLiant G6 series)
 
 pci:v00008086d00003423*
  ID_MODEL_FROM_DATABASE=7500/5520/5500/X58 I/O Hub Control Status and RAS Registers
 
 pci:v00008086d00003423sv0000103Csd0000330B*
- ID_MODEL_FROM_DATABASE=ProLiant G6 series
+ ID_MODEL_FROM_DATABASE=7500/5520/5500/X58 I/O Hub Control Status and RAS Registers (ProLiant G6 series)
 
 pci:v00008086d00003425*
  ID_MODEL_FROM_DATABASE=7500/5520/5500/X58 Physical and Link Layer Registers Port 0
@@ -66582,7 +68598,7 @@ pci:v00008086d0000342E*
  ID_MODEL_FROM_DATABASE=7500/5520/5500/X58 I/O Hub System Management Registers
 
 pci:v00008086d0000342Esv0000103Csd0000330B*
- ID_MODEL_FROM_DATABASE=ProLiant G6 series
+ ID_MODEL_FROM_DATABASE=7500/5520/5500/X58 I/O Hub System Management Registers (ProLiant G6 series)
 
 pci:v00008086d0000342F*
  ID_MODEL_FROM_DATABASE=7500/5520/5500/X58 Trusted Execution Technology Registers
@@ -66606,10 +68622,10 @@ pci:v00008086d00003500*
  ID_MODEL_FROM_DATABASE=6311ESB/6321ESB PCI Express Upstream Port
 
 pci:v00008086d00003500sv0000103Csd000031FE*
- ID_MODEL_FROM_DATABASE=ProLiant DL140 G3
+ ID_MODEL_FROM_DATABASE=6311ESB/6321ESB PCI Express Upstream Port (ProLiant DL140 G3)
 
 pci:v00008086d00003500sv000015D9sd00009680*
- ID_MODEL_FROM_DATABASE=X7DBN Motherboard
+ ID_MODEL_FROM_DATABASE=6311ESB/6321ESB PCI Express Upstream Port (X7DBN Motherboard)
 
 pci:v00008086d00003501*
  ID_MODEL_FROM_DATABASE=6310ESB PCI Express Upstream Port
@@ -66624,10 +68640,10 @@ pci:v00008086d0000350C*
  ID_MODEL_FROM_DATABASE=6311ESB/6321ESB PCI Express to PCI-X Bridge
 
 pci:v00008086d0000350Csv0000103Csd000031FE*
- ID_MODEL_FROM_DATABASE=ProLiant DL140 G3
+ ID_MODEL_FROM_DATABASE=6311ESB/6321ESB PCI Express to PCI-X Bridge (ProLiant DL140 G3)
 
 pci:v00008086d0000350Csv000015D9sd00009680*
- ID_MODEL_FROM_DATABASE=X7DBN Motherboard
+ ID_MODEL_FROM_DATABASE=6311ESB/6321ESB PCI Express to PCI-X Bridge (X7DBN Motherboard)
 
 pci:v00008086d0000350D*
  ID_MODEL_FROM_DATABASE=6310ESB PCI Express to PCI-X Bridge
@@ -66636,10 +68652,10 @@ pci:v00008086d00003510*
  ID_MODEL_FROM_DATABASE=6311ESB/6321ESB PCI Express Downstream Port E1
 
 pci:v00008086d00003510sv0000103Csd000031FE*
- ID_MODEL_FROM_DATABASE=ProLiant DL140 G3
+ ID_MODEL_FROM_DATABASE=6311ESB/6321ESB PCI Express Downstream Port E1 (ProLiant DL140 G3)
 
 pci:v00008086d00003510sv000015D9sd00009680*
- ID_MODEL_FROM_DATABASE=X7DBN Motherboard
+ ID_MODEL_FROM_DATABASE=6311ESB/6321ESB PCI Express Downstream Port E1 (X7DBN Motherboard)
 
 pci:v00008086d00003511*
  ID_MODEL_FROM_DATABASE=6310ESB PCI Express Downstream Port E1
@@ -66654,7 +68670,7 @@ pci:v00008086d00003518*
  ID_MODEL_FROM_DATABASE=6311ESB/6321ESB PCI Express Downstream Port E3
 
 pci:v00008086d00003518sv000015D9sd00009680*
- ID_MODEL_FROM_DATABASE=X7DBN Motherboard
+ ID_MODEL_FROM_DATABASE=6311ESB/6321ESB PCI Express Downstream Port E3 (X7DBN Motherboard)
 
 pci:v00008086d00003519*
  ID_MODEL_FROM_DATABASE=6310ESB PCI Express Downstream Port E3
@@ -66663,13 +68679,13 @@ pci:v00008086d00003575*
  ID_MODEL_FROM_DATABASE=82830M/MG/MP Host Bridge
 
 pci:v00008086d00003575sv00000E11sd00000030*
- ID_MODEL_FROM_DATABASE=Evo N600c
+ ID_MODEL_FROM_DATABASE=82830M/MG/MP Host Bridge (Evo N600c)
 
 pci:v00008086d00003575sv00001014sd0000021D*
- ID_MODEL_FROM_DATABASE=ThinkPad A/T/X Series
+ ID_MODEL_FROM_DATABASE=82830M/MG/MP Host Bridge (ThinkPad A/T/X Series)
 
 pci:v00008086d00003575sv0000104Dsd000080E7*
- ID_MODEL_FROM_DATABASE=VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP
+ ID_MODEL_FROM_DATABASE=82830M/MG/MP Host Bridge (VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP)
 
 pci:v00008086d00003576*
  ID_MODEL_FROM_DATABASE=82830M/MP AGP Bridge
@@ -66678,7 +68694,7 @@ pci:v00008086d00003577*
  ID_MODEL_FROM_DATABASE=82830M/MG Integrated Graphics Controller
 
 pci:v00008086d00003577sv00001014sd00000513*
- ID_MODEL_FROM_DATABASE=ThinkPad A/T/X Series
+ ID_MODEL_FROM_DATABASE=82830M/MG Integrated Graphics Controller (ThinkPad A/T/X Series)
 
 pci:v00008086d00003578*
  ID_MODEL_FROM_DATABASE=82830M/MG/MP Host Bridge
@@ -66687,181 +68703,181 @@ pci:v00008086d00003580*
  ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller
 
 pci:v00008086d00003580sv00001014sd0000055C*
- ID_MODEL_FROM_DATABASE=ThinkPad R50e
+ ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller (ThinkPad R50e)
 
 pci:v00008086d00003580sv00001028sd00000139*
- ID_MODEL_FROM_DATABASE=Latitude D400
+ ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller (Latitude D400)
 
 pci:v00008086d00003580sv00001028sd0000014F*
- ID_MODEL_FROM_DATABASE=Latitude X300
+ ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller (Latitude X300)
 
 pci:v00008086d00003580sv00001028sd00000152*
- ID_MODEL_FROM_DATABASE=Latitude D500
+ ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller (Latitude D500)
 
 pci:v00008086d00003580sv00001028sd00000163*
- ID_MODEL_FROM_DATABASE=Latitude D505
+ ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller (Latitude D505)
 
 pci:v00008086d00003580sv00001028sd0000018D*
- ID_MODEL_FROM_DATABASE=Inspiron 700m/710m
+ ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller (Inspiron 700m/710m)
 
 pci:v00008086d00003580sv00001028sd00000196*
- ID_MODEL_FROM_DATABASE=Inspiron 5160
+ ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller (Inspiron 5160)
 
 pci:v00008086d00003580sv0000114Asd00000582*
- ID_MODEL_FROM_DATABASE=PC8
+ ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller (PC8)
 
 pci:v00008086d00003580sv00001734sd00001055*
- ID_MODEL_FROM_DATABASE=Amilo M1420
+ ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller (Amilo M1420)
 
 pci:v00008086d00003580sv00001775sd000010D0*
- ID_MODEL_FROM_DATABASE=V5D Single Board Computer
+ ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller (V5D Single Board Computer)
 
 pci:v00008086d00003580sv00001775sd0000CE90*
- ID_MODEL_FROM_DATABASE=CE9
+ ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller (CE9)
 
 pci:v00008086d00003580sv00004C53sd000010B0*
- ID_MODEL_FROM_DATABASE=CL9 mainboard
+ ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller (CL9 mainboard)
 
 pci:v00008086d00003580sv00004C53sd000010E0*
- ID_MODEL_FROM_DATABASE=PSL09 PrPMC
+ ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller (PSL09 PrPMC)
 
 pci:v00008086d00003580sv0000E4BFsd00000CC9*
- ID_MODEL_FROM_DATABASE=CC9-SAMBA
+ ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller (CC9-SAMBA)
 
 pci:v00008086d00003580sv0000E4BFsd00000CD2*
- ID_MODEL_FROM_DATABASE=CD2-BEBOP
+ ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller (CD2-BEBOP)
 
 pci:v00008086d00003581*
  ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to AGP Controller
 
 pci:v00008086d00003581sv00001734sd00001055*
- ID_MODEL_FROM_DATABASE=Amilo M1420
+ ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to AGP Controller (Amilo M1420)
 
 pci:v00008086d00003582*
  ID_MODEL_FROM_DATABASE=82852/855GM Integrated Graphics Device
 
 pci:v00008086d00003582sv00001014sd00000562*
- ID_MODEL_FROM_DATABASE=ThinkPad R50e
+ ID_MODEL_FROM_DATABASE=82852/855GM Integrated Graphics Device (ThinkPad R50e)
 
 pci:v00008086d00003582sv00001028sd00000139*
- ID_MODEL_FROM_DATABASE=Latitude D400
+ ID_MODEL_FROM_DATABASE=82852/855GM Integrated Graphics Device (Latitude D400)
 
 pci:v00008086d00003582sv00001028sd0000014F*
- ID_MODEL_FROM_DATABASE=Latitude X300
+ ID_MODEL_FROM_DATABASE=82852/855GM Integrated Graphics Device (Latitude X300)
 
 pci:v00008086d00003582sv00001028sd00000152*
- ID_MODEL_FROM_DATABASE=Latitude D500
+ ID_MODEL_FROM_DATABASE=82852/855GM Integrated Graphics Device (Latitude D500)
 
 pci:v00008086d00003582sv00001028sd00000163*
- ID_MODEL_FROM_DATABASE=Latitude D505
+ ID_MODEL_FROM_DATABASE=82852/855GM Integrated Graphics Device (Latitude D505)
 
 pci:v00008086d00003582sv00001028sd0000018D*
- ID_MODEL_FROM_DATABASE=Inspiron 700m/710m
+ ID_MODEL_FROM_DATABASE=82852/855GM Integrated Graphics Device (Inspiron 700m/710m)
 
 pci:v00008086d00003582sv0000114Asd00000582*
- ID_MODEL_FROM_DATABASE=PC8 integrated graphics
+ ID_MODEL_FROM_DATABASE=82852/855GM Integrated Graphics Device (PC8 integrated graphics)
 
 pci:v00008086d00003582sv00001775sd000010D0*
- ID_MODEL_FROM_DATABASE=V5D Single Board Computer VGA
+ ID_MODEL_FROM_DATABASE=82852/855GM Integrated Graphics Device (V5D Single Board Computer VGA)
 
 pci:v00008086d00003582sv00001775sd0000CE90*
- ID_MODEL_FROM_DATABASE=CE9
+ ID_MODEL_FROM_DATABASE=82852/855GM Integrated Graphics Device (CE9)
 
 pci:v00008086d00003582sv00004C53sd000010B0*
- ID_MODEL_FROM_DATABASE=CL9 mainboard
+ ID_MODEL_FROM_DATABASE=82852/855GM Integrated Graphics Device (CL9 mainboard)
 
 pci:v00008086d00003582sv00004C53sd000010E0*
- ID_MODEL_FROM_DATABASE=PSL09 PrPMC
+ ID_MODEL_FROM_DATABASE=82852/855GM Integrated Graphics Device (PSL09 PrPMC)
 
 pci:v00008086d00003582sv0000E4BFsd00000CC9*
- ID_MODEL_FROM_DATABASE=CC9-SAMBA
+ ID_MODEL_FROM_DATABASE=82852/855GM Integrated Graphics Device (CC9-SAMBA)
 
 pci:v00008086d00003582sv0000E4BFsd00000CD2*
- ID_MODEL_FROM_DATABASE=CD2-BEBOP
+ ID_MODEL_FROM_DATABASE=82852/855GM Integrated Graphics Device (CD2-BEBOP)
 
 pci:v00008086d00003584*
  ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller
 
 pci:v00008086d00003584sv00001014sd0000055D*
- ID_MODEL_FROM_DATABASE=ThinkPad R50e
+ ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller (ThinkPad R50e)
 
 pci:v00008086d00003584sv00001028sd00000139*
- ID_MODEL_FROM_DATABASE=Latitude D400
+ ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller (Latitude D400)
 
 pci:v00008086d00003584sv00001028sd0000014F*
- ID_MODEL_FROM_DATABASE=Latitude X300
+ ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller (Latitude X300)
 
 pci:v00008086d00003584sv00001028sd00000152*
- ID_MODEL_FROM_DATABASE=Latitude D500
+ ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller (Latitude D500)
 
 pci:v00008086d00003584sv00001028sd00000163*
- ID_MODEL_FROM_DATABASE=Latitude D505
+ ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller (Latitude D505)
 
 pci:v00008086d00003584sv00001028sd0000018D*
- ID_MODEL_FROM_DATABASE=Inspiron 700m/710m
+ ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller (Inspiron 700m/710m)
 
 pci:v00008086d00003584sv00001028sd00000196*
- ID_MODEL_FROM_DATABASE=Inspiron 5160
+ ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller (Inspiron 5160)
 
 pci:v00008086d00003584sv0000114Asd00000582*
- ID_MODEL_FROM_DATABASE=PC8
+ ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller (PC8)
 
 pci:v00008086d00003584sv00001734sd00001055*
- ID_MODEL_FROM_DATABASE=Amilo M1420
+ ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller (Amilo M1420)
 
 pci:v00008086d00003584sv00001775sd000010D0*
- ID_MODEL_FROM_DATABASE=V5D Single Board Computer
+ ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller (V5D Single Board Computer)
 
 pci:v00008086d00003584sv00001775sd0000CE90*
- ID_MODEL_FROM_DATABASE=CE9
+ ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller (CE9)
 
 pci:v00008086d00003584sv00004C53sd000010B0*
- ID_MODEL_FROM_DATABASE=CL9 mainboard
+ ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller (CL9 mainboard)
 
 pci:v00008086d00003584sv00004C53sd000010E0*
- ID_MODEL_FROM_DATABASE=PSL09 PrPMC
+ ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller (PSL09 PrPMC)
 
 pci:v00008086d00003585*
  ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller
 
 pci:v00008086d00003585sv00001014sd0000055E*
- ID_MODEL_FROM_DATABASE=ThinkPad R50e
+ ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller (ThinkPad R50e)
 
 pci:v00008086d00003585sv00001028sd00000139*
- ID_MODEL_FROM_DATABASE=Latitude D400
+ ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller (Latitude D400)
 
 pci:v00008086d00003585sv00001028sd0000014F*
- ID_MODEL_FROM_DATABASE=Latitude X300
+ ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller (Latitude X300)
 
 pci:v00008086d00003585sv00001028sd00000152*
- ID_MODEL_FROM_DATABASE=Latitude D500
+ ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller (Latitude D500)
 
 pci:v00008086d00003585sv00001028sd00000163*
- ID_MODEL_FROM_DATABASE=Latitude D505
+ ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller (Latitude D505)
 
 pci:v00008086d00003585sv00001028sd0000018D*
- ID_MODEL_FROM_DATABASE=Inspiron 700m/710m
+ ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller (Inspiron 700m/710m)
 
 pci:v00008086d00003585sv00001028sd00000196*
- ID_MODEL_FROM_DATABASE=Inspiron 5160
+ ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller (Inspiron 5160)
 
 pci:v00008086d00003585sv0000114Asd00000582*
- ID_MODEL_FROM_DATABASE=PC8
+ ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller (PC8)
 
 pci:v00008086d00003585sv00001734sd00001055*
- ID_MODEL_FROM_DATABASE=Amilo M1420
+ ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller (Amilo M1420)
 
 pci:v00008086d00003585sv00001775sd000010D0*
- ID_MODEL_FROM_DATABASE=V5D Single Board Computer
+ ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller (V5D Single Board Computer)
 
 pci:v00008086d00003585sv00001775sd0000CE90*
- ID_MODEL_FROM_DATABASE=CE9
+ ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller (CE9)
 
 pci:v00008086d00003585sv00004C53sd000010B0*
- ID_MODEL_FROM_DATABASE=CL9 mainboard
+ ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller (CL9 mainboard)
 
 pci:v00008086d00003585sv00004C53sd000010E0*
- ID_MODEL_FROM_DATABASE=PSL09 PrPMC
+ ID_MODEL_FROM_DATABASE=82852/82855 GM/GME/PM/GMV Processor to I/O Controller (PSL09 PrPMC)
 
 pci:v00008086d0000358C*
  ID_MODEL_FROM_DATABASE=82854 GMCH
@@ -66873,67 +68889,70 @@ pci:v00008086d00003590*
  ID_MODEL_FROM_DATABASE=E7520 Memory Controller Hub
 
 pci:v00008086d00003590sv00001014sd000002DD*
- ID_MODEL_FROM_DATABASE=eServer xSeries server mainboard
+ ID_MODEL_FROM_DATABASE=E7520 Memory Controller Hub (eServer xSeries server mainboard)
 
 pci:v00008086d00003590sv00001028sd0000016C*
- ID_MODEL_FROM_DATABASE=PowerEdge 1850 Memory Controller Hub
+ ID_MODEL_FROM_DATABASE=E7520 Memory Controller Hub (PowerEdge 1850 Memory Controller Hub)
 
 pci:v00008086d00003590sv00001028sd0000016D*
- ID_MODEL_FROM_DATABASE=PowerEdge 2850 Memory Controller Hub
+ ID_MODEL_FROM_DATABASE=E7520 Memory Controller Hub (PowerEdge 2850 Memory Controller Hub)
 
 pci:v00008086d00003590sv00001028sd0000019A*
- ID_MODEL_FROM_DATABASE=PowerEdge SC1425
+ ID_MODEL_FROM_DATABASE=E7520 Memory Controller Hub (PowerEdge SC1425)
 
 pci:v00008086d00003590sv00001734sd0000103E*
- ID_MODEL_FROM_DATABASE=PRIMERGY RX/TX S2 series
+ ID_MODEL_FROM_DATABASE=E7520 Memory Controller Hub (PRIMERGY RX/TX S2 series)
 
 pci:v00008086d00003590sv00001775sd00001100*
- ID_MODEL_FROM_DATABASE=CR11/VR11 Single Board Computer
+ ID_MODEL_FROM_DATABASE=E7520 Memory Controller Hub (CR11/VR11 Single Board Computer)
 
 pci:v00008086d00003590sv00004C53sd000010D0*
- ID_MODEL_FROM_DATABASE=Telum ASLP10 Processor AMC
+ ID_MODEL_FROM_DATABASE=E7520 Memory Controller Hub (Telum ASLP10 Processor AMC)
 
 pci:v00008086d00003591*
  ID_MODEL_FROM_DATABASE=E7525/E7520 Error Reporting Registers
 
 pci:v00008086d00003591sv00001014sd000002DD*
- ID_MODEL_FROM_DATABASE=eServer xSeries server mainboard
+ ID_MODEL_FROM_DATABASE=E7525/E7520 Error Reporting Registers (eServer xSeries server mainboard)
+
+pci:v00008086d00003591sv00001028sd00000168*
+ ID_MODEL_FROM_DATABASE=E7525/E7520 Error Reporting Registers (Precision Workstation 670 Mainboard)
 
 pci:v00008086d00003591sv00001028sd00000169*
- ID_MODEL_FROM_DATABASE=Precision 470
+ ID_MODEL_FROM_DATABASE=E7525/E7520 Error Reporting Registers (Precision 470)
 
 pci:v00008086d00003591sv0000103Csd00003208*
- ID_MODEL_FROM_DATABASE=ProLiant DL140 G2
+ ID_MODEL_FROM_DATABASE=E7525/E7520 Error Reporting Registers (ProLiant DL140 G2)
 
 pci:v00008086d00003591sv00004C53sd000010D0*
- ID_MODEL_FROM_DATABASE=Telum ASLP10 Processor AMC
+ ID_MODEL_FROM_DATABASE=E7525/E7520 Error Reporting Registers (Telum ASLP10 Processor AMC)
 
 pci:v00008086d00003592*
  ID_MODEL_FROM_DATABASE=E7320 Memory Controller Hub
 
 pci:v00008086d00003592sv00001734sd00001073*
- ID_MODEL_FROM_DATABASE=Primergy Econel 200 D2020 mainboard
+ ID_MODEL_FROM_DATABASE=E7320 Memory Controller Hub (Primergy Econel 200 D2020 mainboard)
 
 pci:v00008086d00003593*
  ID_MODEL_FROM_DATABASE=E7320 Error Reporting Registers
 
 pci:v00008086d00003593sv00001734sd00001073*
- ID_MODEL_FROM_DATABASE=Primergy Econel 200 D2020 mainboard
+ ID_MODEL_FROM_DATABASE=E7320 Error Reporting Registers (Primergy Econel 200 D2020 mainboard)
 
 pci:v00008086d00003594*
  ID_MODEL_FROM_DATABASE=E7520 DMA Controller
 
 pci:v00008086d00003594sv00001775sd00001100*
- ID_MODEL_FROM_DATABASE=CR11/VR11 Single Board Computer
+ ID_MODEL_FROM_DATABASE=E7520 DMA Controller (CR11/VR11 Single Board Computer)
 
 pci:v00008086d00003594sv00004C53sd000010D0*
- ID_MODEL_FROM_DATABASE=Telum ASLP10 Processor AMC
+ ID_MODEL_FROM_DATABASE=E7520 DMA Controller (Telum ASLP10 Processor AMC)
 
 pci:v00008086d00003595*
  ID_MODEL_FROM_DATABASE=E7525/E7520/E7320 PCI Express Port A
 
 pci:v00008086d00003595sv00001775sd00001100*
- ID_MODEL_FROM_DATABASE=CR11/VR11 Single Board Computer
+ ID_MODEL_FROM_DATABASE=E7525/E7520/E7320 PCI Express Port A (CR11/VR11 Single Board Computer)
 
 pci:v00008086d00003596*
  ID_MODEL_FROM_DATABASE=E7525/E7520/E7320 PCI Express Port A1
@@ -66942,19 +68961,19 @@ pci:v00008086d00003597*
  ID_MODEL_FROM_DATABASE=E7525/E7520 PCI Express Port B
 
 pci:v00008086d00003597sv00001775sd00001100*
- ID_MODEL_FROM_DATABASE=CR11/VR11 Single Board Computer
+ ID_MODEL_FROM_DATABASE=E7525/E7520 PCI Express Port B (CR11/VR11 Single Board Computer)
 
 pci:v00008086d00003598*
  ID_MODEL_FROM_DATABASE=E7520 PCI Express Port B1
 
 pci:v00008086d00003598sv00001775sd00001100*
- ID_MODEL_FROM_DATABASE=CR11/VR11 Single Board Computer
+ ID_MODEL_FROM_DATABASE=E7520 PCI Express Port B1 (CR11/VR11 Single Board Computer)
 
 pci:v00008086d00003599*
  ID_MODEL_FROM_DATABASE=E7520 PCI Express Port C
 
 pci:v00008086d00003599sv00001775sd00001100*
- ID_MODEL_FROM_DATABASE=CR11/VR11 Single Board Computer
+ ID_MODEL_FROM_DATABASE=E7520 PCI Express Port C (CR11/VR11 Single Board Computer)
 
 pci:v00008086d0000359A*
  ID_MODEL_FROM_DATABASE=E7520 PCI Express Port C1
@@ -66963,13 +68982,16 @@ pci:v00008086d0000359B*
  ID_MODEL_FROM_DATABASE=E7525/E7520/E7320 Extended Configuration Registers
 
 pci:v00008086d0000359Bsv00001014sd000002DD*
- ID_MODEL_FROM_DATABASE=eServer xSeries server mainboard
+ ID_MODEL_FROM_DATABASE=E7525/E7520/E7320 Extended Configuration Registers (eServer xSeries server mainboard)
 
 pci:v00008086d0000359E*
  ID_MODEL_FROM_DATABASE=E7525 Memory Controller Hub
 
+pci:v00008086d0000359Esv00001028sd00000168*
+ ID_MODEL_FROM_DATABASE=E7525 Memory Controller Hub (Precision Workstation 670 Mainboard)
+
 pci:v00008086d0000359Esv00001028sd00000169*
- ID_MODEL_FROM_DATABASE=Precision 470
+ ID_MODEL_FROM_DATABASE=E7525 Memory Controller Hub (Precision 470)
 
 pci:v00008086d000035B0*
  ID_MODEL_FROM_DATABASE=3100 Chipset Memory I/O Controller Hub
@@ -67020,7 +69042,7 @@ pci:v00008086d0000360C*
  ID_MODEL_FROM_DATABASE=7300 Chipset FSB Registers
 
 pci:v00008086d0000360Csv00001028sd000001F0*
- ID_MODEL_FROM_DATABASE=PowerEdge R900 7300 Chipset FSB Registers
+ ID_MODEL_FROM_DATABASE=7300 Chipset FSB Registers (PowerEdge R900 7300 Chipset FSB Registers)
 
 pci:v00008086d0000360D*
  ID_MODEL_FROM_DATABASE=7300 Chipset Snoop Filter Registers
@@ -67182,19 +69204,19 @@ pci:v00008086d00003A16*
  ID_MODEL_FROM_DATABASE=82801JIR (ICH10R) LPC Interface Controller
 
 pci:v00008086d00003A16sv00001028sd0000028C*
- ID_MODEL_FROM_DATABASE=PowerEdge R410 LPC Interface Controller
+ ID_MODEL_FROM_DATABASE=82801JIR (ICH10R) LPC Interface Controller (PowerEdge R410 LPC Interface Controller)
 
 pci:v00008086d00003A16sv00001028sd0000028D*
- ID_MODEL_FROM_DATABASE=PowerEdge T410 LPC Interface Controller
+ ID_MODEL_FROM_DATABASE=82801JIR (ICH10R) LPC Interface Controller (PowerEdge T410 LPC Interface Controller)
 
 pci:v00008086d00003A16sv0000103Csd0000330B*
- ID_MODEL_FROM_DATABASE=ProLiant G6 series
+ ID_MODEL_FROM_DATABASE=82801JIR (ICH10R) LPC Interface Controller (ProLiant G6 series)
 
 pci:v00008086d00003A16sv00001043sd000082D4*
- ID_MODEL_FROM_DATABASE=P5Q Deluxe Motherboard
+ ID_MODEL_FROM_DATABASE=82801JIR (ICH10R) LPC Interface Controller (P5Q Deluxe Motherboard)
 
 pci:v00008086d00003A16sv00001458sd00005001*
- ID_MODEL_FROM_DATABASE=GA-EP45-DS5 Motherboard
+ ID_MODEL_FROM_DATABASE=82801JIR (ICH10R) LPC Interface Controller (GA-EP45-DS5 Motherboard)
 
 pci:v00008086d00003A18*
  ID_MODEL_FROM_DATABASE=82801JIB (ICH10) LPC Interface Controller
@@ -67206,52 +69228,52 @@ pci:v00008086d00003A20*
  ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) 4 port SATA IDE Controller #1
 
 pci:v00008086d00003A20sv00001028sd0000028C*
- ID_MODEL_FROM_DATABASE=PowerEdge R410 SATA IDE Controller
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) 4 port SATA IDE Controller #1 (PowerEdge R410 SATA IDE Controller)
 
 pci:v00008086d00003A20sv00001028sd0000028D*
- ID_MODEL_FROM_DATABASE=PowerEdge T410 SATA IDE Controller
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) 4 port SATA IDE Controller #1 (PowerEdge T410 SATA IDE Controller)
 
 pci:v00008086d00003A22*
  ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) SATA AHCI Controller
 
 pci:v00008086d00003A22sv0000103Csd0000330B*
- ID_MODEL_FROM_DATABASE=ProLiant G6 series
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) SATA AHCI Controller (ProLiant G6 series)
 
 pci:v00008086d00003A22sv00001043sd000082D4*
- ID_MODEL_FROM_DATABASE=P5Q Deluxe Motherboard
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) SATA AHCI Controller (P5Q Deluxe Motherboard)
 
 pci:v00008086d00003A22sv00001458sd0000B005*
- ID_MODEL_FROM_DATABASE=GA-EP45-DS5/GA-EG45M-DS2H Motherboard
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) SATA AHCI Controller (GA-EP45-DS5/GA-EG45M-DS2H Motherboard)
 
 pci:v00008086d00003A25*
  ID_MODEL_FROM_DATABASE=82801JIR (ICH10R) SATA RAID Controller
 
 pci:v00008086d00003A25sv00001028sd0000028C*
- ID_MODEL_FROM_DATABASE=PERC S100 Controller (PE R410)
+ ID_MODEL_FROM_DATABASE=82801JIR (ICH10R) SATA RAID Controller (PERC S100 Controller (PE R410))
 
 pci:v00008086d00003A25sv00001028sd0000028D*
- ID_MODEL_FROM_DATABASE=PERC S100 Controller (PE T410)
+ ID_MODEL_FROM_DATABASE=82801JIR (ICH10R) SATA RAID Controller (PERC S100 Controller (PE T410))
 
 pci:v00008086d00003A25sv00001028sd000002F1*
- ID_MODEL_FROM_DATABASE=PERC S100 Controller (PE R510)
+ ID_MODEL_FROM_DATABASE=82801JIR (ICH10R) SATA RAID Controller (PERC S100 Controller (PE R510))
 
 pci:v00008086d00003A26*
  ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) 2 port SATA IDE Controller #2
 
 pci:v00008086d00003A26sv00001028sd0000028C*
- ID_MODEL_FROM_DATABASE=PowerEdge R410 SATA IDE Controller
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) 2 port SATA IDE Controller #2 (PowerEdge R410 SATA IDE Controller)
 
 pci:v00008086d00003A26sv00001028sd0000028D*
- ID_MODEL_FROM_DATABASE=PowerEdge T410 SATA IDE Controller
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) 2 port SATA IDE Controller #2 (PowerEdge T410 SATA IDE Controller)
 
 pci:v00008086d00003A30*
  ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) SMBus Controller
 
 pci:v00008086d00003A30sv00001043sd000082D4*
- ID_MODEL_FROM_DATABASE=P5Q Deluxe Motherboard
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) SMBus Controller (P5Q Deluxe Motherboard)
 
 pci:v00008086d00003A30sv00001458sd00005001*
- ID_MODEL_FROM_DATABASE=GA-EP45-DS5/GA-EG45M-DS2H Motherboard
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) SMBus Controller (GA-EP45-DS5/GA-EG45M-DS2H Motherboard)
 
 pci:v00008086d00003A32*
  ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) Thermal Subsystem
@@ -67260,178 +69282,178 @@ pci:v00008086d00003A34*
  ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #1
 
 pci:v00008086d00003A34sv00001028sd0000028C*
- ID_MODEL_FROM_DATABASE=PowerEdge R410 USB UHCI Controller
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #1 (PowerEdge R410 USB UHCI Controller)
 
 pci:v00008086d00003A34sv00001028sd0000028D*
- ID_MODEL_FROM_DATABASE=PowerEdge T410 USB UHCI Controller
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #1 (PowerEdge T410 USB UHCI Controller)
 
 pci:v00008086d00003A34sv0000103Csd0000330B*
- ID_MODEL_FROM_DATABASE=ProLiant G6 series
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #1 (ProLiant G6 series)
 
 pci:v00008086d00003A34sv00001043sd000082D4*
- ID_MODEL_FROM_DATABASE=P5Q Deluxe Motherboard
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #1 (P5Q Deluxe Motherboard)
 
 pci:v00008086d00003A34sv00001458sd00005004*
- ID_MODEL_FROM_DATABASE=GA-EP45-DS5 Motherboard
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #1 (GA-EP45-DS5 Motherboard)
 
 pci:v00008086d00003A35*
  ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #2
 
 pci:v00008086d00003A35sv00001028sd0000028C*
- ID_MODEL_FROM_DATABASE=PowerEdge R410 USB UHCI Controller
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #2 (PowerEdge R410 USB UHCI Controller)
 
 pci:v00008086d00003A35sv00001028sd0000028D*
- ID_MODEL_FROM_DATABASE=PowerEdge T410 USB UHCI Controller
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #2 (PowerEdge T410 USB UHCI Controller)
 
 pci:v00008086d00003A35sv0000103Csd0000330B*
- ID_MODEL_FROM_DATABASE=ProLiant G6 series
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #2 (ProLiant G6 series)
 
 pci:v00008086d00003A35sv00001043sd000082D4*
- ID_MODEL_FROM_DATABASE=P5Q Deluxe Motherboard
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #2 (P5Q Deluxe Motherboard)
 
 pci:v00008086d00003A35sv00001458sd00005004*
- ID_MODEL_FROM_DATABASE=GA-EP45-DS5 Motherboard
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #2 (GA-EP45-DS5 Motherboard)
 
 pci:v00008086d00003A36*
  ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #3
 
 pci:v00008086d00003A36sv00001028sd0000028C*
- ID_MODEL_FROM_DATABASE=PowerEdge R410 USB UHCI Controller
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #3 (PowerEdge R410 USB UHCI Controller)
 
 pci:v00008086d00003A36sv00001028sd0000028D*
- ID_MODEL_FROM_DATABASE=PowerEdge T410 USB UHCI Controller
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #3 (PowerEdge T410 USB UHCI Controller)
 
 pci:v00008086d00003A36sv0000103Csd0000330B*
- ID_MODEL_FROM_DATABASE=ProLiant G6 series
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #3 (ProLiant G6 series)
 
 pci:v00008086d00003A36sv00001043sd000082D4*
- ID_MODEL_FROM_DATABASE=P5Q Deluxe Motherboard
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #3 (P5Q Deluxe Motherboard)
 
 pci:v00008086d00003A36sv00001458sd00005004*
- ID_MODEL_FROM_DATABASE=GA-EP45-DS5 Motherboard
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #3 (GA-EP45-DS5 Motherboard)
 
 pci:v00008086d00003A37*
  ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #4
 
 pci:v00008086d00003A37sv00001028sd0000028C*
- ID_MODEL_FROM_DATABASE=PowerEdge R410 USB UHCI Controller
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #4 (PowerEdge R410 USB UHCI Controller)
 
 pci:v00008086d00003A37sv00001028sd0000028D*
- ID_MODEL_FROM_DATABASE=PowerEdge T410 USB UHCI Controller
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #4 (PowerEdge T410 USB UHCI Controller)
 
 pci:v00008086d00003A37sv0000103Csd0000330B*
- ID_MODEL_FROM_DATABASE=ProLiant G6 series
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #4 (ProLiant G6 series)
 
 pci:v00008086d00003A37sv00001043sd000082D4*
- ID_MODEL_FROM_DATABASE=P5Q Deluxe Motherboard
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #4 (P5Q Deluxe Motherboard)
 
 pci:v00008086d00003A37sv00001458sd00005004*
- ID_MODEL_FROM_DATABASE=Motherboard
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #4 (Motherboard)
 
 pci:v00008086d00003A38*
  ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #5
 
 pci:v00008086d00003A38sv00001028sd0000028C*
- ID_MODEL_FROM_DATABASE=PowerEdge R410 USB UHCI Controller
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #5 (PowerEdge R410 USB UHCI Controller)
 
 pci:v00008086d00003A38sv00001028sd0000028D*
- ID_MODEL_FROM_DATABASE=PowerEdge T410 USB UHCI Controller
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #5 (PowerEdge T410 USB UHCI Controller)
 
 pci:v00008086d00003A38sv0000103Csd0000330B*
- ID_MODEL_FROM_DATABASE=ProLiant ML150 G6 Server
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #5 (ProLiant ML150 G6 Server)
 
 pci:v00008086d00003A38sv00001043sd000082D4*
- ID_MODEL_FROM_DATABASE=P5Q Deluxe Motherboard
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #5 (P5Q Deluxe Motherboard)
 
 pci:v00008086d00003A38sv00001458sd00005004*
- ID_MODEL_FROM_DATABASE=Motherboard
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #5 (Motherboard)
 
 pci:v00008086d00003A39*
  ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #6
 
 pci:v00008086d00003A39sv00001028sd0000028C*
- ID_MODEL_FROM_DATABASE=PowerEdge R410 USB UHCI Controller
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #6 (PowerEdge R410 USB UHCI Controller)
 
 pci:v00008086d00003A39sv00001028sd0000028D*
- ID_MODEL_FROM_DATABASE=PowerEdge T410 USB UHCI Controller
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #6 (PowerEdge T410 USB UHCI Controller)
 
 pci:v00008086d00003A39sv0000103Csd0000330B*
- ID_MODEL_FROM_DATABASE=ProLiant ML150 G6 Server
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #6 (ProLiant ML150 G6 Server)
 
 pci:v00008086d00003A39sv00001043sd000082D4*
- ID_MODEL_FROM_DATABASE=P5Q Deluxe Motherboard
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #6 (P5Q Deluxe Motherboard)
 
 pci:v00008086d00003A39sv00001458sd00005004*
- ID_MODEL_FROM_DATABASE=Motherboard
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB UHCI Controller #6 (Motherboard)
 
 pci:v00008086d00003A3A*
  ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB2 EHCI Controller #1
 
 pci:v00008086d00003A3Asv00001028sd0000028C*
- ID_MODEL_FROM_DATABASE=PowerEdge R410 USB EHCI Controller
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB2 EHCI Controller #1 (PowerEdge R410 USB EHCI Controller)
 
 pci:v00008086d00003A3Asv00001028sd0000028D*
- ID_MODEL_FROM_DATABASE=PowerEdge T410 USB EHCI Controller
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB2 EHCI Controller #1 (PowerEdge T410 USB EHCI Controller)
 
 pci:v00008086d00003A3Asv0000103Csd0000330B*
- ID_MODEL_FROM_DATABASE=ProLiant G6 series
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB2 EHCI Controller #1 (ProLiant G6 series)
 
 pci:v00008086d00003A3Asv00001043sd000082D4*
- ID_MODEL_FROM_DATABASE=P5Q Deluxe Motherboard
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB2 EHCI Controller #1 (P5Q Deluxe Motherboard)
 
 pci:v00008086d00003A3Asv00001458sd00005006*
- ID_MODEL_FROM_DATABASE=GA-EP45-DS5 Motherboard
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB2 EHCI Controller #1 (GA-EP45-DS5 Motherboard)
 
 pci:v00008086d00003A3C*
  ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB2 EHCI Controller #2
 
 pci:v00008086d00003A3Csv00001028sd0000028C*
- ID_MODEL_FROM_DATABASE=PowerEdge R410 USB EHCI Controller
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB2 EHCI Controller #2 (PowerEdge R410 USB EHCI Controller)
 
 pci:v00008086d00003A3Csv00001028sd0000028D*
- ID_MODEL_FROM_DATABASE=PowerEdge T410 USB EHCI Controller
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB2 EHCI Controller #2 (PowerEdge T410 USB EHCI Controller)
 
 pci:v00008086d00003A3Csv0000103Csd0000330B*
- ID_MODEL_FROM_DATABASE=ProLiant G6 series
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB2 EHCI Controller #2 (ProLiant G6 series)
 
 pci:v00008086d00003A3Csv00001043sd000082D4*
- ID_MODEL_FROM_DATABASE=P5Q Deluxe Motherboard
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB2 EHCI Controller #2 (P5Q Deluxe Motherboard)
 
 pci:v00008086d00003A3Csv00001458sd00005006*
- ID_MODEL_FROM_DATABASE=Motherboard
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) USB2 EHCI Controller #2 (Motherboard)
 
 pci:v00008086d00003A3E*
  ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) HD Audio Controller
 
 pci:v00008086d00003A3Esv00001043sd00008311*
- ID_MODEL_FROM_DATABASE=P5Q Deluxe Motherboard
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) HD Audio Controller (P5Q Deluxe Motherboard)
 
 pci:v00008086d00003A3Esv00001458sd0000A002*
- ID_MODEL_FROM_DATABASE=GA-EP45-UD3R Motherboard
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) HD Audio Controller (GA-EP45-UD3R Motherboard)
 
 pci:v00008086d00003A3Esv00001458sd0000A102*
- ID_MODEL_FROM_DATABASE=GA-EP45-DS5/GA-EG45M-DS2H Motherboard
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) HD Audio Controller (GA-EP45-DS5/GA-EG45M-DS2H Motherboard)
 
 pci:v00008086d00003A40*
  ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) PCI Express Root Port 1
 
 pci:v00008086d00003A40sv00001028sd0000028C*
- ID_MODEL_FROM_DATABASE=PowerEdge R410 PCI Express Port 1
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) PCI Express Root Port 1 (PowerEdge R410 PCI Express Port 1)
 
 pci:v00008086d00003A40sv00001028sd0000028D*
- ID_MODEL_FROM_DATABASE=PowerEdge T410 PCI Express Port 1
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) PCI Express Root Port 1 (PowerEdge T410 PCI Express Port 1)
 
 pci:v00008086d00003A40sv0000103Csd0000330B*
- ID_MODEL_FROM_DATABASE=ProLiant ML150 G6 Server
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) PCI Express Root Port 1 (ProLiant ML150 G6 Server)
 
 pci:v00008086d00003A40sv00001043sd000082D4*
- ID_MODEL_FROM_DATABASE=P5Q Deluxe Motherboard
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) PCI Express Root Port 1 (P5Q Deluxe Motherboard)
 
 pci:v00008086d00003A40sv00001043sd000082EA*
- ID_MODEL_FROM_DATABASE=P6T DeLuxe Motherboard
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) PCI Express Root Port 1 (P6T DeLuxe Motherboard)
 
 pci:v00008086d00003A40sv00001458sd00005001*
- ID_MODEL_FROM_DATABASE=GA-EP45-DS5/GA-EG45M-DS2H Motherboard
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) PCI Express Root Port 1 (GA-EP45-DS5/GA-EG45M-DS2H Motherboard)
 
 pci:v00008086d00003A42*
  ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) PCI Express Port 2
@@ -67440,43 +69462,43 @@ pci:v00008086d00003A44*
  ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) PCI Express Root Port 3
 
 pci:v00008086d00003A44sv00001043sd000082EA*
- ID_MODEL_FROM_DATABASE=P6T DeLuxe Motherboard
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) PCI Express Root Port 3 (P6T DeLuxe Motherboard)
 
 pci:v00008086d00003A46*
  ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) PCI Express Root Port 4
 
 pci:v00008086d00003A46sv00001043sd000082EA*
- ID_MODEL_FROM_DATABASE=P6T DeLuxe Motherboard
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) PCI Express Root Port 4 (P6T DeLuxe Motherboard)
 
 pci:v00008086d00003A46sv00001458sd00005001*
- ID_MODEL_FROM_DATABASE=GA-EP45-DS5 Motherboard
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) PCI Express Root Port 4 (GA-EP45-DS5 Motherboard)
 
 pci:v00008086d00003A48*
  ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) PCI Express Root Port 5
 
 pci:v00008086d00003A48sv0000103Csd0000330B*
- ID_MODEL_FROM_DATABASE=ProLiant ML150 G6 Server
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) PCI Express Root Port 5 (ProLiant ML150 G6 Server)
 
 pci:v00008086d00003A48sv00001043sd000082EA*
- ID_MODEL_FROM_DATABASE=P6T Deluxe Motherboard
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) PCI Express Root Port 5 (P6T Deluxe Motherboard)
 
 pci:v00008086d00003A48sv00001458sd00005001*
- ID_MODEL_FROM_DATABASE=GA-EP45-DS5 Motherboard
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) PCI Express Root Port 5 (GA-EP45-DS5 Motherboard)
 
 pci:v00008086d00003A4A*
  ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) PCI Express Root Port 6
 
 pci:v00008086d00003A4Asv0000103Csd0000330B*
- ID_MODEL_FROM_DATABASE=ProLiant ML150 G6 Server
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) PCI Express Root Port 6 (ProLiant ML150 G6 Server)
 
 pci:v00008086d00003A4Asv00001043sd000082D4*
- ID_MODEL_FROM_DATABASE=P5Q Deluxe Motherboard
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) PCI Express Root Port 6 (P5Q Deluxe Motherboard)
 
 pci:v00008086d00003A4Asv00001043sd000082EA*
- ID_MODEL_FROM_DATABASE=P6T DeLuxe Motherboard
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) PCI Express Root Port 6 (P6T DeLuxe Motherboard)
 
 pci:v00008086d00003A4Asv00001458sd00005001*
- ID_MODEL_FROM_DATABASE=GA-EP45-DS5/GA-EG45M-DS2H Motherboard
+ ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) PCI Express Root Port 6 (GA-EP45-DS5/GA-EG45M-DS2H Motherboard)
 
 pci:v00008086d00003A4C*
  ID_MODEL_FROM_DATABASE=82801JI (ICH10 Family) Gigabit Ethernet Controller
@@ -67566,10 +69588,10 @@ pci:v00008086d00003B07*
  ID_MODEL_FROM_DATABASE=Mobile 5 Series Chipset LPC Interface Controller
 
 pci:v00008086d00003B07sv00001028sd0000040B*
- ID_MODEL_FROM_DATABASE=Latitude E6510
+ ID_MODEL_FROM_DATABASE=Mobile 5 Series Chipset LPC Interface Controller (Latitude E6510)
 
 pci:v00008086d00003B07sv0000E4BFsd000050C1*
- ID_MODEL_FROM_DATABASE=PC1-GROOVE
+ ID_MODEL_FROM_DATABASE=Mobile 5 Series Chipset LPC Interface Controller (PC1-GROOVE)
 
 pci:v00008086d00003B08*
  ID_MODEL_FROM_DATABASE=5 Series Chipset LPC Interface Controller
@@ -67578,13 +69600,22 @@ pci:v00008086d00003B09*
  ID_MODEL_FROM_DATABASE=Mobile 5 Series Chipset LPC Interface Controller
 
 pci:v00008086d00003B09sv00001025sd00000347*
- ID_MODEL_FROM_DATABASE=Aspire 7740G
+ ID_MODEL_FROM_DATABASE=Mobile 5 Series Chipset LPC Interface Controller (Aspire 7740G)
+
+pci:v00008086d00003B09sv0000144Dsd0000C06A*
+ ID_MODEL_FROM_DATABASE=Mobile 5 Series Chipset LPC Interface Controller (R730 Laptop)
+
+pci:v00008086d00003B09sv000017C0sd000010D2*
+ ID_MODEL_FROM_DATABASE=Mobile 5 Series Chipset LPC Interface Controller (Medion Akoya E7214 Notebook PC [MD98410])
 
 pci:v00008086d00003B0A*
  ID_MODEL_FROM_DATABASE=5 Series Chipset LPC Interface Controller
 
 pci:v00008086d00003B0Asv00001028sd000002DA*
- ID_MODEL_FROM_DATABASE=OptiPlex 980
+ ID_MODEL_FROM_DATABASE=5 Series Chipset LPC Interface Controller (OptiPlex 980)
+
+pci:v00008086d00003B0Asv000015D9sd0000060D*
+ ID_MODEL_FROM_DATABASE=5 Series Chipset LPC Interface Controller (C7SIM-Q Motherboard)
 
 pci:v00008086d00003B0B*
  ID_MODEL_FROM_DATABASE=Mobile 5 Series Chipset LPC Interface Controller
@@ -67659,7 +69690,10 @@ pci:v00008086d00003B22*
  ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset 6 port SATA AHCI Controller
 
 pci:v00008086d00003B22sv00001028sd000002DA*
- ID_MODEL_FROM_DATABASE=OptiPlex 980
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset 6 port SATA AHCI Controller (OptiPlex 980)
+
+pci:v00008086d00003B22sv000015D9sd0000060D*
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset 6 port SATA AHCI Controller (C7SIM-Q Motherboard)
 
 pci:v00008086d00003B23*
  ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset 4 port SATA AHCI Controller
@@ -67667,17 +69701,32 @@ pci:v00008086d00003B23*
 pci:v00008086d00003B25*
  ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset SATA RAID Controller
 
+pci:v00008086d00003B25sv0000103Csd00003118*
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset SATA RAID Controller (HP Smart Array B110i SATA RAID Controller)
+
 pci:v00008086d00003B26*
  ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset 2 port SATA IDE Controller
 
 pci:v00008086d00003B28*
  ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset 4 port SATA IDE Controller
 
+pci:v00008086d00003B28sv0000144Dsd0000C06A*
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset 4 port SATA IDE Controller (R730 Laptop)
+
+pci:v00008086d00003B28sv000017C0sd000010D2*
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset 4 port SATA IDE Controller (Medion Akoya E7214 Notebook PC [MD98410])
+
 pci:v00008086d00003B29*
  ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset 4 port SATA AHCI Controller
 
 pci:v00008086d00003B29sv00001025sd00000347*
- ID_MODEL_FROM_DATABASE=Aspire 7740G
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset 4 port SATA AHCI Controller (Aspire 7740G)
+
+pci:v00008086d00003B29sv0000144Dsd0000C06A*
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset 4 port SATA AHCI Controller (R730 Laptop)
+
+pci:v00008086d00003B29sv000017C0sd000010D2*
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset 4 port SATA AHCI Controller (Medion Akoya E7214 Notebook PC [MD98410])
 
 pci:v00008086d00003B2C*
  ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset SATA RAID Controller
@@ -67685,59 +69734,89 @@ pci:v00008086d00003B2C*
 pci:v00008086d00003B2D*
  ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset 2 port SATA IDE Controller
 
+pci:v00008086d00003B2Dsv0000144Dsd0000C06A*
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset 2 port SATA IDE Controller (R730 Laptop)
+
+pci:v00008086d00003B2Dsv000017C0sd000010D2*
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset 2 port SATA IDE Controller (Medion Akoya E7214 Notebook PC [MD98410])
+
 pci:v00008086d00003B2Dsv0000E4BFsd000050C1*
- ID_MODEL_FROM_DATABASE=PC1-GROOVE
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset 2 port SATA IDE Controller (PC1-GROOVE)
 
 pci:v00008086d00003B2E*
  ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset 4 port SATA IDE Controller
 
 pci:v00008086d00003B2Esv0000E4BFsd000050C1*
- ID_MODEL_FROM_DATABASE=PC1-GROOVE
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset 4 port SATA IDE Controller (PC1-GROOVE)
 
 pci:v00008086d00003B2F*
  ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset 6 port SATA AHCI Controller
 
 pci:v00008086d00003B2Fsv00001028sd0000040B*
- ID_MODEL_FROM_DATABASE=Latitude E6510
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset 6 port SATA AHCI Controller (Latitude E6510)
 
 pci:v00008086d00003B2Fsv0000E4BFsd000050C1*
- ID_MODEL_FROM_DATABASE=PC1-GROOVE
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset 6 port SATA AHCI Controller (PC1-GROOVE)
 
 pci:v00008086d00003B30*
  ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset SMBus Controller
 
 pci:v00008086d00003B30sv00001025sd00000347*
- ID_MODEL_FROM_DATABASE=Aspire 7740G
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset SMBus Controller (Aspire 7740G)
 
 pci:v00008086d00003B30sv00001028sd000002DA*
- ID_MODEL_FROM_DATABASE=OptiPlex 980
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset SMBus Controller (OptiPlex 980)
 
 pci:v00008086d00003B30sv00001028sd0000040B*
- ID_MODEL_FROM_DATABASE=Latitude E6510
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset SMBus Controller (Latitude E6510)
+
+pci:v00008086d00003B30sv0000144Dsd0000C06A*
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset SMBus Controller (R730 Laptop)
+
+pci:v00008086d00003B30sv000015D9sd0000060D*
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset SMBus Controller (C7SIM-Q Motherboard)
+
+pci:v00008086d00003B30sv000017C0sd000010D2*
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset SMBus Controller (Medion Akoya E7214 Notebook PC [MD98410])
 
 pci:v00008086d00003B30sv0000E4BFsd000050C1*
- ID_MODEL_FROM_DATABASE=PC1-GROOVE
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset SMBus Controller (PC1-GROOVE)
 
 pci:v00008086d00003B32*
  ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset Thermal Subsystem
 
 pci:v00008086d00003B32sv00001025sd00000347*
- ID_MODEL_FROM_DATABASE=Aspire 7740G
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset Thermal Subsystem (Aspire 7740G)
+
+pci:v00008086d00003B32sv0000144Dsd0000C06A*
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset Thermal Subsystem (R730 Laptop)
+
+pci:v00008086d00003B32sv000017C0sd000010D2*
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset Thermal Subsystem (Medion Akoya E7214 Notebook PC [MD98410])
 
 pci:v00008086d00003B34*
  ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset USB2 Enhanced Host Controller
 
 pci:v00008086d00003B34sv00001025sd00000347*
- ID_MODEL_FROM_DATABASE=Aspire 7740G
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset USB2 Enhanced Host Controller (Aspire 7740G)
 
 pci:v00008086d00003B34sv00001028sd000002DA*
- ID_MODEL_FROM_DATABASE=OptiPlex 980
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset USB2 Enhanced Host Controller (OptiPlex 980)
 
 pci:v00008086d00003B34sv00001028sd0000040B*
- ID_MODEL_FROM_DATABASE=Latitude E6510
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset USB2 Enhanced Host Controller (Latitude E6510)
+
+pci:v00008086d00003B34sv0000144Dsd0000C06A*
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset USB2 Enhanced Host Controller (R730 Laptop)
+
+pci:v00008086d00003B34sv000015D9sd0000060D*
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset USB2 Enhanced Host Controller (C7SIM-Q Motherboard)
+
+pci:v00008086d00003B34sv000017C0sd000010D2*
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset USB2 Enhanced Host Controller (Medion Akoya E7214 Notebook PC [MD98410])
 
 pci:v00008086d00003B34sv0000E4BFsd000050C1*
- ID_MODEL_FROM_DATABASE=PC1-GROOVE
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset USB2 Enhanced Host Controller (PC1-GROOVE)
 
 pci:v00008086d00003B36*
  ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset USB Universal Host Controller
@@ -67761,16 +69840,25 @@ pci:v00008086d00003B3C*
  ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset USB2 Enhanced Host Controller
 
 pci:v00008086d00003B3Csv00001025sd00000347*
- ID_MODEL_FROM_DATABASE=Aspire 7740G
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset USB2 Enhanced Host Controller (Aspire 7740G)
 
 pci:v00008086d00003B3Csv00001028sd000002DA*
- ID_MODEL_FROM_DATABASE=OptiPlex 980
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset USB2 Enhanced Host Controller (OptiPlex 980)
 
 pci:v00008086d00003B3Csv00001028sd0000040B*
- ID_MODEL_FROM_DATABASE=Latitude E6510
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset USB2 Enhanced Host Controller (Latitude E6510)
+
+pci:v00008086d00003B3Csv0000144Dsd0000C06A*
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset USB2 Enhanced Host Controller (R730 Laptop)
+
+pci:v00008086d00003B3Csv000015D9sd0000060D*
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset USB2 Enhanced Host Controller (C7SIM-Q Motherboard)
+
+pci:v00008086d00003B3Csv000017C0sd000010D2*
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset USB2 Enhanced Host Controller (Medion Akoya E7214 Notebook PC [MD98410])
 
 pci:v00008086d00003B3Csv0000E4BFsd000050C1*
- ID_MODEL_FROM_DATABASE=PC1-GROOVE
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset USB2 Enhanced Host Controller (PC1-GROOVE)
 
 pci:v00008086d00003B3E*
  ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset USB Universal Host Controller
@@ -67788,34 +69876,61 @@ pci:v00008086d00003B42*
  ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset PCI Express Root Port 1
 
 pci:v00008086d00003B42sv00001028sd000002DA*
- ID_MODEL_FROM_DATABASE=OptiPlex 980
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset PCI Express Root Port 1 (OptiPlex 980)
 
 pci:v00008086d00003B42sv00001028sd0000040B*
- ID_MODEL_FROM_DATABASE=Latitude E6510
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset PCI Express Root Port 1 (Latitude E6510)
+
+pci:v00008086d00003B42sv0000144Dsd0000C06A*
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset PCI Express Root Port 1 (R730 Laptop)
+
+pci:v00008086d00003B42sv000015D9sd0000060D*
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset PCI Express Root Port 1 (C7SIM-Q Motherboard)
+
+pci:v00008086d00003B42sv000017C0sd000010D2*
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset PCI Express Root Port 1 (Medion Akoya E7214 Notebook PC [MD98410])
 
 pci:v00008086d00003B44*
  ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset PCI Express Root Port 2
 
 pci:v00008086d00003B44sv00001028sd0000040B*
- ID_MODEL_FROM_DATABASE=Latitude E6510
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset PCI Express Root Port 2 (Latitude E6510)
+
+pci:v00008086d00003B44sv000015D9sd0000060D*
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset PCI Express Root Port 2 (C7SIM-Q Motherboard)
+
+pci:v00008086d00003B44sv000017C0sd000010D2*
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset PCI Express Root Port 2 (Medion Akoya E7214 Notebook PC [MD98410])
 
 pci:v00008086d00003B46*
  ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset PCI Express Root Port 3
 
 pci:v00008086d00003B46sv00001028sd0000040B*
- ID_MODEL_FROM_DATABASE=Latitude E6510
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset PCI Express Root Port 3 (Latitude E6510)
+
+pci:v00008086d00003B46sv0000144Dsd0000C06A*
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset PCI Express Root Port 3 (R730 Laptop)
+
+pci:v00008086d00003B46sv000017C0sd000010D2*
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset PCI Express Root Port 3 (Medion Akoya E7214 Notebook PC [MD98410])
 
 pci:v00008086d00003B48*
  ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset PCI Express Root Port 4
 
 pci:v00008086d00003B48sv00001028sd0000040B*
- ID_MODEL_FROM_DATABASE=Latitude E6510
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset PCI Express Root Port 4 (Latitude E6510)
+
+pci:v00008086d00003B48sv0000144Dsd0000C06A*
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset PCI Express Root Port 4 (R730 Laptop)
 
 pci:v00008086d00003B4A*
  ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset PCI Express Root Port 5
 
 pci:v00008086d00003B4Asv00001028sd000002DA*
- ID_MODEL_FROM_DATABASE=OptiPlex 980
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset PCI Express Root Port 5 (OptiPlex 980)
+
+pci:v00008086d00003B4Asv000017C0sd000010D2*
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset PCI Express Root Port 5 (Medion Akoya E7214 Notebook PC [MD98410])
 
 pci:v00008086d00003B4C*
  ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset PCI Express Root Port 6
@@ -67833,16 +69948,25 @@ pci:v00008086d00003B56*
  ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset High Definition Audio
 
 pci:v00008086d00003B56sv00001025sd00000347*
- ID_MODEL_FROM_DATABASE=Aspire 7740G
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset High Definition Audio (Aspire 7740G)
 
 pci:v00008086d00003B56sv00001028sd000002DA*
- ID_MODEL_FROM_DATABASE=OptiPlex 980
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset High Definition Audio (OptiPlex 980)
 
 pci:v00008086d00003B56sv00001028sd0000040B*
- ID_MODEL_FROM_DATABASE=Latitude E6510
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset High Definition Audio (Latitude E6510)
+
+pci:v00008086d00003B56sv0000144Dsd0000C06A*
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset High Definition Audio (R730 Laptop)
+
+pci:v00008086d00003B56sv000015D9sd0000060D*
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset High Definition Audio (C7SIM-Q Motherboard)
+
+pci:v00008086d00003B56sv000017C0sd000010D2*
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset High Definition Audio (Medion Akoya E7214 Notebook PC [MD98410])
 
 pci:v00008086d00003B56sv0000E4BFsd000050C1*
- ID_MODEL_FROM_DATABASE=PC1-GROOVE
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset High Definition Audio (PC1-GROOVE)
 
 pci:v00008086d00003B57*
  ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset High Definition Audio
@@ -67851,10 +69975,16 @@ pci:v00008086d00003B64*
  ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset HECI Controller
 
 pci:v00008086d00003B64sv00001025sd00000347*
- ID_MODEL_FROM_DATABASE=Aspire 7740G
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset HECI Controller (Aspire 7740G)
+
+pci:v00008086d00003B64sv000015D9sd0000060D*
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset HECI Controller (C7SIM-Q Motherboard)
+
+pci:v00008086d00003B64sv000017C0sd000010D2*
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset HECI Controller (Medion Akoya E7214 Notebook PC [MD98410])
 
 pci:v00008086d00003B64sv0000E4BFsd000050C1*
- ID_MODEL_FROM_DATABASE=PC1-GROOVE
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset HECI Controller (PC1-GROOVE)
 
 pci:v00008086d00003B65*
  ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset HECI Controller
@@ -67866,7 +69996,7 @@ pci:v00008086d00003B67*
  ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset KT Controller
 
 pci:v00008086d00003B67sv0000E4BFsd000050C1*
- ID_MODEL_FROM_DATABASE=PC1-GROOVE
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset KT Controller (PC1-GROOVE)
 
 pci:v00008086d00003C00*
  ID_MODEL_FROM_DATABASE=Xeon E5/Core i7 DMI2
@@ -68196,25 +70326,25 @@ pci:v00008086d00004220*
  ID_MODEL_FROM_DATABASE=PRO/Wireless 2200BG [Calexico2] Network Connection
 
 pci:v00008086d00004220sv0000103Csd00000934*
- ID_MODEL_FROM_DATABASE=Compaq nw8240/nx8220
+ ID_MODEL_FROM_DATABASE=PRO/Wireless 2200BG [Calexico2] Network Connection (Compaq nw8240/nx8220)
 
 pci:v00008086d00004220sv0000103Csd000012F6*
- ID_MODEL_FROM_DATABASE=nc6120/nx8220/nw8240
+ ID_MODEL_FROM_DATABASE=PRO/Wireless 2200BG [Calexico2] Network Connection (nc6120/nx8220/nw8240)
 
 pci:v00008086d00004220sv00008086sd00002701*
- ID_MODEL_FROM_DATABASE=WM3B2300BG Mini-PCI Card
+ ID_MODEL_FROM_DATABASE=PRO/Wireless 2200BG [Calexico2] Network Connection (WM3B2300BG Mini-PCI Card)
 
 pci:v00008086d00004220sv00008086sd00002712*
- ID_MODEL_FROM_DATABASE=IBM ThinkPad R50e
+ ID_MODEL_FROM_DATABASE=PRO/Wireless 2200BG [Calexico2] Network Connection (IBM ThinkPad R50e)
 
 pci:v00008086d00004220sv00008086sd00002721*
- ID_MODEL_FROM_DATABASE=Dell B130 laptop integrated WLAN
+ ID_MODEL_FROM_DATABASE=PRO/Wireless 2200BG [Calexico2] Network Connection (Dell B130 laptop integrated WLAN)
 
 pci:v00008086d00004220sv00008086sd00002722*
- ID_MODEL_FROM_DATABASE=Dell Latitude D600
+ ID_MODEL_FROM_DATABASE=PRO/Wireless 2200BG [Calexico2] Network Connection (Dell Latitude D600)
 
 pci:v00008086d00004220sv00008086sd00002731*
- ID_MODEL_FROM_DATABASE=Samsung P35 integrated WLAN
+ ID_MODEL_FROM_DATABASE=PRO/Wireless 2200BG [Calexico2] Network Connection (Samsung P35 integrated WLAN)
 
 pci:v00008086d00004222*
  ID_MODEL_FROM_DATABASE=PRO/Wireless 3945ABG [Golan] Network Connection
@@ -68223,40 +70353,40 @@ pci:v00008086d00004222sv0000103Csd0000135C*
  ID_MODEL_FROM_DATABASE=PRO/Wireless 3945ABG [Golan] Network Connection
 
 pci:v00008086d00004222sv00008086sd00001000*
- ID_MODEL_FROM_DATABASE=PRO/Wireless 3945ABG Network Connection
+ ID_MODEL_FROM_DATABASE=PRO/Wireless 3945ABG [Golan] Network Connection (PRO/Wireless 3945ABG Network Connection)
 
 pci:v00008086d00004222sv00008086sd00001001*
- ID_MODEL_FROM_DATABASE=PRO/Wireless 3945ABG Network Connection
+ ID_MODEL_FROM_DATABASE=PRO/Wireless 3945ABG [Golan] Network Connection (WM3945ABG MOW2)
 
 pci:v00008086d00004222sv00008086sd00001005*
- ID_MODEL_FROM_DATABASE=PRO/Wireless 3945BG Network Connection
+ ID_MODEL_FROM_DATABASE=PRO/Wireless 3945ABG [Golan] Network Connection (PRO/Wireless 3945BG Network Connection)
 
 pci:v00008086d00004222sv00008086sd00001034*
- ID_MODEL_FROM_DATABASE=PRO/Wireless 3945BG Network Connection
+ ID_MODEL_FROM_DATABASE=PRO/Wireless 3945ABG [Golan] Network Connection (PRO/Wireless 3945BG Network Connection)
 
 pci:v00008086d00004222sv00008086sd00001044*
- ID_MODEL_FROM_DATABASE=PRO/Wireless 3945BG Network Connection
+ ID_MODEL_FROM_DATABASE=PRO/Wireless 3945ABG [Golan] Network Connection (PRO/Wireless 3945BG Network Connection)
 
 pci:v00008086d00004222sv00008086sd00001C00*
- ID_MODEL_FROM_DATABASE=PRO/Wireless 3945ABG Network Connection
+ ID_MODEL_FROM_DATABASE=PRO/Wireless 3945ABG [Golan] Network Connection (PRO/Wireless 3945ABG Network Connection)
 
 pci:v00008086d00004223*
  ID_MODEL_FROM_DATABASE=PRO/Wireless 2915ABG [Calexico2] Network Connection
 
 pci:v00008086d00004223sv00001000sd00008086*
- ID_MODEL_FROM_DATABASE=mPCI 3B Americas/Europe ZZA
+ ID_MODEL_FROM_DATABASE=PRO/Wireless 2915ABG [Calexico2] Network Connection (mPCI 3B Americas/Europe ZZA)
 
 pci:v00008086d00004223sv00001001sd00008086*
- ID_MODEL_FROM_DATABASE=mPCI 3B Europe ZZE
+ ID_MODEL_FROM_DATABASE=PRO/Wireless 2915ABG [Calexico2] Network Connection (mPCI 3B Europe ZZE)
 
 pci:v00008086d00004223sv00001002sd00008086*
- ID_MODEL_FROM_DATABASE=mPCI 3B Japan ZZJ
+ ID_MODEL_FROM_DATABASE=PRO/Wireless 2915ABG [Calexico2] Network Connection (mPCI 3B Japan ZZJ)
 
 pci:v00008086d00004223sv00001003sd00008086*
- ID_MODEL_FROM_DATABASE=mPCI 3B High-Band ZZH
+ ID_MODEL_FROM_DATABASE=PRO/Wireless 2915ABG [Calexico2] Network Connection (mPCI 3B High-Band ZZH)
 
 pci:v00008086d00004223sv00001351sd0000103C*
- ID_MODEL_FROM_DATABASE=Compaq NC6220
+ ID_MODEL_FROM_DATABASE=PRO/Wireless 2915ABG [Calexico2] Network Connection (Compaq NC6220)
 
 pci:v00008086d00004224*
  ID_MODEL_FROM_DATABASE=PRO/Wireless 2915ABG [Calexico2] Network Connection
@@ -68265,106 +70395,106 @@ pci:v00008086d00004227*
  ID_MODEL_FROM_DATABASE=PRO/Wireless 3945ABG [Golan] Network Connection
 
 pci:v00008086d00004227sv00008086sd00001011*
- ID_MODEL_FROM_DATABASE=ThinkPad T60/R60e/X60s
+ ID_MODEL_FROM_DATABASE=PRO/Wireless 3945ABG [Golan] Network Connection (ThinkPad T60/R60e/X60s)
 
 pci:v00008086d00004227sv00008086sd00001014*
- ID_MODEL_FROM_DATABASE=PRO/Wireless 3945BG Network Connection
+ ID_MODEL_FROM_DATABASE=PRO/Wireless 3945ABG [Golan] Network Connection (PRO/Wireless 3945BG Network Connection)
 
 pci:v00008086d00004229*
  ID_MODEL_FROM_DATABASE=PRO/Wireless 4965 AG or AGN [Kedron] Network Connection
 
 pci:v00008086d00004229sv00008086sd00001100*
- ID_MODEL_FROM_DATABASE=Vaio VGN-SZ79SN_C
+ ID_MODEL_FROM_DATABASE=PRO/Wireless 4965 AG or AGN [Kedron] Network Connection (Vaio VGN-SZ79SN_C)
 
 pci:v00008086d00004229sv00008086sd00001101*
- ID_MODEL_FROM_DATABASE=PRO/Wireless 4965 AG or AGN
+ ID_MODEL_FROM_DATABASE=PRO/Wireless 4965 AG or AGN [Kedron] Network Connection (PRO/Wireless 4965 AG or AGN)
 
 pci:v00008086d0000422B*
  ID_MODEL_FROM_DATABASE=Centrino Ultimate-N 6300
 
 pci:v00008086d0000422Bsv00008086sd00001101*
- ID_MODEL_FROM_DATABASE=Centrino Ultimate-N 6300 3x3 AGN
+ ID_MODEL_FROM_DATABASE=Centrino Ultimate-N 6300 (3x3 AGN)
 
 pci:v00008086d0000422Bsv00008086sd00001121*
- ID_MODEL_FROM_DATABASE=Centrino Ultimate-N 6300 3x3 AGN
+ ID_MODEL_FROM_DATABASE=Centrino Ultimate-N 6300 (3x3 AGN)
 
 pci:v00008086d0000422C*
  ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6200
 
 pci:v00008086d0000422Csv00008086sd00001301*
- ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6200 2x2 AGN
+ ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6200 (2x2 AGN)
 
 pci:v00008086d0000422Csv00008086sd00001306*
- ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6200 2x2 ABG
+ ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6200 (2x2 ABG)
 
 pci:v00008086d0000422Csv00008086sd00001307*
- ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6200 2x2 BG
+ ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6200 (2x2 BG)
 
 pci:v00008086d0000422Csv00008086sd00001321*
- ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6200 2x2 AGN
+ ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6200 (2x2 AGN)
 
 pci:v00008086d0000422Csv00008086sd00001326*
- ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6200 2x2 ABG
+ ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6200 (2x2 ABG)
 
 pci:v00008086d00004230*
  ID_MODEL_FROM_DATABASE=PRO/Wireless 4965 AG or AGN [Kedron] Network Connection
 
 pci:v00008086d00004230sv00008086sd00001110*
- ID_MODEL_FROM_DATABASE=Lenovo ThinkPad T51
+ ID_MODEL_FROM_DATABASE=PRO/Wireless 4965 AG or AGN [Kedron] Network Connection (Lenovo ThinkPad T51)
 
 pci:v00008086d00004230sv00008086sd00001111*
- ID_MODEL_FROM_DATABASE=Lenovo ThinkPad T61
+ ID_MODEL_FROM_DATABASE=PRO/Wireless 4965 AG or AGN [Kedron] Network Connection (Lenovo ThinkPad T61)
 
 pci:v00008086d00004232*
  ID_MODEL_FROM_DATABASE=WiFi Link 5100
 
 pci:v00008086d00004232sv00008086sd00001201*
- ID_MODEL_FROM_DATABASE=WiFi Link 5100 AGN
+ ID_MODEL_FROM_DATABASE=WiFi Link 5100 (AGN)
 
 pci:v00008086d00004232sv00008086sd00001204*
- ID_MODEL_FROM_DATABASE=WiFi Link 5100 AGN
+ ID_MODEL_FROM_DATABASE=WiFi Link 5100 (AGN)
 
 pci:v00008086d00004232sv00008086sd00001205*
- ID_MODEL_FROM_DATABASE=WiFi Link 5100 BGN
+ ID_MODEL_FROM_DATABASE=WiFi Link 5100 (BGN)
 
 pci:v00008086d00004232sv00008086sd00001206*
- ID_MODEL_FROM_DATABASE=WiFi Link 5100 ABG
+ ID_MODEL_FROM_DATABASE=WiFi Link 5100 (ABG)
 
 pci:v00008086d00004232sv00008086sd00001221*
- ID_MODEL_FROM_DATABASE=WiFi Link 5100 AGN
+ ID_MODEL_FROM_DATABASE=WiFi Link 5100 (AGN)
 
 pci:v00008086d00004232sv00008086sd00001224*
- ID_MODEL_FROM_DATABASE=WiFi Link 5100 AGN
+ ID_MODEL_FROM_DATABASE=WiFi Link 5100 (AGN)
 
 pci:v00008086d00004232sv00008086sd00001225*
- ID_MODEL_FROM_DATABASE=WiFi Link 5100 BGN
+ ID_MODEL_FROM_DATABASE=WiFi Link 5100 (BGN)
 
 pci:v00008086d00004232sv00008086sd00001226*
- ID_MODEL_FROM_DATABASE=WiFi Link 5100 ABG
+ ID_MODEL_FROM_DATABASE=WiFi Link 5100 (ABG)
 
 pci:v00008086d00004232sv00008086sd00001301*
- ID_MODEL_FROM_DATABASE=WiFi Link 5100 AGN
+ ID_MODEL_FROM_DATABASE=WiFi Link 5100 (AGN)
 
 pci:v00008086d00004232sv00008086sd00001304*
- ID_MODEL_FROM_DATABASE=WiFi Link 5100 AGN
+ ID_MODEL_FROM_DATABASE=WiFi Link 5100 (AGN)
 
 pci:v00008086d00004232sv00008086sd00001305*
- ID_MODEL_FROM_DATABASE=WiFi Link 5100 BGN
+ ID_MODEL_FROM_DATABASE=WiFi Link 5100 (BGN)
 
 pci:v00008086d00004232sv00008086sd00001306*
- ID_MODEL_FROM_DATABASE=WiFi Link 5100 ABG
+ ID_MODEL_FROM_DATABASE=WiFi Link 5100 (ABG)
 
 pci:v00008086d00004232sv00008086sd00001321*
- ID_MODEL_FROM_DATABASE=WiFi Link 5100 AGN
+ ID_MODEL_FROM_DATABASE=WiFi Link 5100 (AGN)
 
 pci:v00008086d00004232sv00008086sd00001324*
- ID_MODEL_FROM_DATABASE=WiFi Link 5100 AGN
+ ID_MODEL_FROM_DATABASE=WiFi Link 5100 (AGN)
 
 pci:v00008086d00004232sv00008086sd00001325*
- ID_MODEL_FROM_DATABASE=WiFi Link 5100 BGN
+ ID_MODEL_FROM_DATABASE=WiFi Link 5100 (BGN)
 
 pci:v00008086d00004232sv00008086sd00001326*
- ID_MODEL_FROM_DATABASE=WiFi Link 5100 ABG
+ ID_MODEL_FROM_DATABASE=WiFi Link 5100 (ABG)
 
 pci:v00008086d00004235*
  ID_MODEL_FROM_DATABASE=Ultimate N WiFi Link 5300
@@ -68376,43 +70506,43 @@ pci:v00008086d00004237*
  ID_MODEL_FROM_DATABASE=PRO/Wireless 5100 AGN [Shiloh] Network Connection
 
 pci:v00008086d00004237sv00008086sd00001211*
- ID_MODEL_FROM_DATABASE=WiFi Link 5100 AGN
+ ID_MODEL_FROM_DATABASE=PRO/Wireless 5100 AGN [Shiloh] Network Connection (WiFi Link 5100 AGN)
 
 pci:v00008086d00004237sv00008086sd00001214*
- ID_MODEL_FROM_DATABASE=WiFi Link 5100 AGN
+ ID_MODEL_FROM_DATABASE=PRO/Wireless 5100 AGN [Shiloh] Network Connection (WiFi Link 5100 AGN)
 
 pci:v00008086d00004237sv00008086sd00001215*
- ID_MODEL_FROM_DATABASE=WiFi Link 5100 BGN
+ ID_MODEL_FROM_DATABASE=PRO/Wireless 5100 AGN [Shiloh] Network Connection (WiFi Link 5100 BGN)
 
 pci:v00008086d00004237sv00008086sd00001216*
- ID_MODEL_FROM_DATABASE=WiFi Link 5100 ABG
+ ID_MODEL_FROM_DATABASE=PRO/Wireless 5100 AGN [Shiloh] Network Connection (WiFi Link 5100 ABG)
 
 pci:v00008086d00004237sv00008086sd00001311*
- ID_MODEL_FROM_DATABASE=WiFi Link 5100 AGN
+ ID_MODEL_FROM_DATABASE=PRO/Wireless 5100 AGN [Shiloh] Network Connection (WiFi Link 5100 AGN)
 
 pci:v00008086d00004237sv00008086sd00001314*
- ID_MODEL_FROM_DATABASE=WiFi Link 5100 AGN
+ ID_MODEL_FROM_DATABASE=PRO/Wireless 5100 AGN [Shiloh] Network Connection (WiFi Link 5100 AGN)
 
 pci:v00008086d00004237sv00008086sd00001315*
- ID_MODEL_FROM_DATABASE=WiFi Link 5100 BGN
+ ID_MODEL_FROM_DATABASE=PRO/Wireless 5100 AGN [Shiloh] Network Connection (WiFi Link 5100 BGN)
 
 pci:v00008086d00004237sv00008086sd00001316*
- ID_MODEL_FROM_DATABASE=WiFi Link 5100 ABG
+ ID_MODEL_FROM_DATABASE=PRO/Wireless 5100 AGN [Shiloh] Network Connection (WiFi Link 5100 ABG)
 
 pci:v00008086d00004238*
  ID_MODEL_FROM_DATABASE=Centrino Ultimate-N 6300
 
 pci:v00008086d00004238sv00008086sd00001111*
- ID_MODEL_FROM_DATABASE=Centrino Ultimate-N 6300 3x3 AGN
+ ID_MODEL_FROM_DATABASE=Centrino Ultimate-N 6300 (3x3 AGN)
 
 pci:v00008086d00004239*
  ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6200
 
 pci:v00008086d00004239sv00008086sd00001311*
- ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6200 2x2 AGN
+ ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6200 (2x2 AGN)
 
 pci:v00008086d00004239sv00008086sd00001316*
- ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6200 2x2 ABG
+ ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6200 (2x2 ABG)
 
 pci:v00008086d0000423A*
  ID_MODEL_FROM_DATABASE=PRO/Wireless 5350 AGN [Echo Peak] Network Connection
@@ -68424,37 +70554,37 @@ pci:v00008086d0000423C*
  ID_MODEL_FROM_DATABASE=WiMAX/WiFi Link 5150
 
 pci:v00008086d0000423Csv00008086sd00001201*
- ID_MODEL_FROM_DATABASE=WiMAX/WiFi Link 5150 AGN
+ ID_MODEL_FROM_DATABASE=WiMAX/WiFi Link 5150 (AGN)
 
 pci:v00008086d0000423Csv00008086sd00001206*
- ID_MODEL_FROM_DATABASE=WiMAX/WiFi Link 5150 ABG
+ ID_MODEL_FROM_DATABASE=WiMAX/WiFi Link 5150 (ABG)
 
 pci:v00008086d0000423Csv00008086sd00001221*
- ID_MODEL_FROM_DATABASE=WiMAX/WiFi Link 5150 AGN
+ ID_MODEL_FROM_DATABASE=WiMAX/WiFi Link 5150 (AGN)
 
 pci:v00008086d0000423Csv00008086sd00001301*
- ID_MODEL_FROM_DATABASE=WiMAX/WiFi Link 5150 AGN
+ ID_MODEL_FROM_DATABASE=WiMAX/WiFi Link 5150 (AGN)
 
 pci:v00008086d0000423Csv00008086sd00001306*
- ID_MODEL_FROM_DATABASE=WiMAX/WiFi Link 5150 ABG
+ ID_MODEL_FROM_DATABASE=WiMAX/WiFi Link 5150 (ABG)
 
 pci:v00008086d0000423Csv00008086sd00001321*
- ID_MODEL_FROM_DATABASE=WiMAX/WiFi Link 5150 AGN
+ ID_MODEL_FROM_DATABASE=WiMAX/WiFi Link 5150 (AGN)
 
 pci:v00008086d0000423D*
  ID_MODEL_FROM_DATABASE=WiMAX/WiFi Link 5150
 
 pci:v00008086d0000423Dsv00008086sd00001211*
- ID_MODEL_FROM_DATABASE=WiMAX/WiFi Link 5150 AGN
+ ID_MODEL_FROM_DATABASE=WiMAX/WiFi Link 5150 (AGN)
 
 pci:v00008086d0000423Dsv00008086sd00001216*
- ID_MODEL_FROM_DATABASE=WiMAX/WiFi Link 5150 ABG
+ ID_MODEL_FROM_DATABASE=WiMAX/WiFi Link 5150 (ABG)
 
 pci:v00008086d0000423Dsv00008086sd00001311*
- ID_MODEL_FROM_DATABASE=WiMAX/WiFi Link 5150 AGN
+ ID_MODEL_FROM_DATABASE=WiMAX/WiFi Link 5150 (AGN)
 
 pci:v00008086d0000423Dsv00008086sd00001316*
- ID_MODEL_FROM_DATABASE=WiMAX/WiFi Link 5150 ABG
+ ID_MODEL_FROM_DATABASE=WiMAX/WiFi Link 5150 (ABG)
 
 pci:v00008086d0000444E*
  ID_MODEL_FROM_DATABASE=Turbo Memory Controller
@@ -68601,17 +70731,23 @@ pci:v00008086d0000504C*
  ID_MODEL_FROM_DATABASE=EP80579 Integrated Processor with QuickAssist TDM
 
 pci:v00008086d00005200*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 Intelligent Server
+ ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 Intelligent Server PCI Bridge
 
 pci:v00008086d00005201*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 Intelligent Server
+ ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 Intelligent Server Fast Ethernet Controller
 
 pci:v00008086d00005201sv00008086sd00000001*
- ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 Server Ethernet Adapter
+ ID_MODEL_FROM_DATABASE=EtherExpress PRO/100 Intelligent Server Fast Ethernet Controller (EtherExpress PRO/100 Server Ethernet Adapter)
 
 pci:v00008086d0000530D*
  ID_MODEL_FROM_DATABASE=80310 (IOP) IO Processor
 
+pci:v00008086d00005845*
+ ID_MODEL_FROM_DATABASE=QEMU NVM Express Controller
+
+pci:v00008086d00005845sv00001AF4sd00001100*
+ ID_MODEL_FROM_DATABASE=QEMU NVM Express Controller (QEMU Virtual Machine)
+
 pci:v00008086d000065C0*
  ID_MODEL_FROM_DATABASE=5100 Chipset Memory Controller Hub
 
@@ -68637,16 +70773,16 @@ pci:v00008086d000065F0*
  ID_MODEL_FROM_DATABASE=5100 Chipset FSB Registers
 
 pci:v00008086d000065F0sv00001028sd0000020F*
- ID_MODEL_FROM_DATABASE=PowerEdge R300
+ ID_MODEL_FROM_DATABASE=5100 Chipset FSB Registers (PowerEdge R300)
 
 pci:v00008086d000065F0sv00001028sd00000210*
- ID_MODEL_FROM_DATABASE=PowerEdge T300
+ ID_MODEL_FROM_DATABASE=5100 Chipset FSB Registers (PowerEdge T300)
 
 pci:v00008086d000065F1*
  ID_MODEL_FROM_DATABASE=5100 Chipset Reserved Registers
 
 pci:v00008086d000065F1sv00001028sd00000210*
- ID_MODEL_FROM_DATABASE=PowerEdge T300
+ ID_MODEL_FROM_DATABASE=5100 Chipset Reserved Registers (PowerEdge T300)
 
 pci:v00008086d000065F3*
  ID_MODEL_FROM_DATABASE=5100 Chipset Reserved Registers
@@ -68672,23 +70808,506 @@ pci:v00008086d000065FA*
 pci:v00008086d000065FF*
  ID_MODEL_FROM_DATABASE=5100 Chipset DMA Engine
 
+pci:v00008086d00006F00*
+ ID_MODEL_FROM_DATABASE=Broadwell DMI2
+
+pci:v00008086d00006F01*
+ ID_MODEL_FROM_DATABASE=Broadwell PCI Express Root Port 0
+
+pci:v00008086d00006F02*
+ ID_MODEL_FROM_DATABASE=Broadwell PCI Express Root Port 1
+
+pci:v00008086d00006F03*
+ ID_MODEL_FROM_DATABASE=Broadwell PCI Express Root Port 1
+
+pci:v00008086d00006F04*
+ ID_MODEL_FROM_DATABASE=Broadwell PCI Express Root Port 2
+
+pci:v00008086d00006F05*
+ ID_MODEL_FROM_DATABASE=Broadwell PCI Express Root Port 2
+
+pci:v00008086d00006F06*
+ ID_MODEL_FROM_DATABASE=Broadwell PCI Express Root Port 2
+
+pci:v00008086d00006F07*
+ ID_MODEL_FROM_DATABASE=Broadwell PCI Express Root Port 2
+
+pci:v00008086d00006F08*
+ ID_MODEL_FROM_DATABASE=Broadwell PCI Express Root Port 3
+
+pci:v00008086d00006F09*
+ ID_MODEL_FROM_DATABASE=Broadwell PCI Express Root Port 3
+
+pci:v00008086d00006F0A*
+ ID_MODEL_FROM_DATABASE=Broadwell PCI Express Root Port 3
+
+pci:v00008086d00006F0B*
+ ID_MODEL_FROM_DATABASE=Broadwell PCI Express Root Port 3
+
+pci:v00008086d00006F10*
+ ID_MODEL_FROM_DATABASE=Broadwell IIO Debug
+
+pci:v00008086d00006F11*
+ ID_MODEL_FROM_DATABASE=Broadwell IIO Debug
+
+pci:v00008086d00006F12*
+ ID_MODEL_FROM_DATABASE=Broadwell IIO Debug
+
+pci:v00008086d00006F13*
+ ID_MODEL_FROM_DATABASE=Broadwell IIO Debug
+
+pci:v00008086d00006F14*
+ ID_MODEL_FROM_DATABASE=Broadwell IIO Debug
+
+pci:v00008086d00006F15*
+ ID_MODEL_FROM_DATABASE=Broadwell IIO Debug
+
+pci:v00008086d00006F16*
+ ID_MODEL_FROM_DATABASE=Broadwell IIO Debug
+
+pci:v00008086d00006F17*
+ ID_MODEL_FROM_DATABASE=Broadwell IIO Debug
+
+pci:v00008086d00006F18*
+ ID_MODEL_FROM_DATABASE=Broadwell IIO Debug
+
+pci:v00008086d00006F19*
+ ID_MODEL_FROM_DATABASE=Broadwell IIO Debug
+
+pci:v00008086d00006F1A*
+ ID_MODEL_FROM_DATABASE=Broadwell IIO Debug
+
+pci:v00008086d00006F1B*
+ ID_MODEL_FROM_DATABASE=Broadwell IIO Debug
+
+pci:v00008086d00006F1C*
+ ID_MODEL_FROM_DATABASE=Broadwell IIO Debug
+
+pci:v00008086d00006F1D*
+ ID_MODEL_FROM_DATABASE=Broadwell R2PCIe Agent
+
+pci:v00008086d00006F1E*
+ ID_MODEL_FROM_DATABASE=Broadwell Ubox
+
+pci:v00008086d00006F1F*
+ ID_MODEL_FROM_DATABASE=Broadwell Ubox
+
+pci:v00008086d00006F20*
+ ID_MODEL_FROM_DATABASE=Broadwell-DE Crystal Beach DMA Channel 0
+
+pci:v00008086d00006F21*
+ ID_MODEL_FROM_DATABASE=Broadwell-DE Crystal Beach DMA Channel 1
+
+pci:v00008086d00006F22*
+ ID_MODEL_FROM_DATABASE=Broadwell-DE Crystal Beach DMA Channel 2
+
+pci:v00008086d00006F23*
+ ID_MODEL_FROM_DATABASE=Broadwell-DE Crystal Beach DMA Channel 3
+
+pci:v00008086d00006F24*
+ ID_MODEL_FROM_DATABASE=Broadwell-DE Crystal Beach DMA Channel 4
+
+pci:v00008086d00006F25*
+ ID_MODEL_FROM_DATABASE=Broadwell-DE Crystal Beach DMA Channel 5
+
+pci:v00008086d00006F26*
+ ID_MODEL_FROM_DATABASE=Broadwell-DE Crystal Beach DMA Channel 6
+
+pci:v00008086d00006F27*
+ ID_MODEL_FROM_DATABASE=Broadwell-DE Crystal Beach DMA Channel 7
+
+pci:v00008086d00006F28*
+ ID_MODEL_FROM_DATABASE=Broadwell Adress Map/VTd_Misc/System Management
+
+pci:v00008086d00006F29*
+ ID_MODEL_FROM_DATABASE=Broadwell IIO Hot Plug
+
+pci:v00008086d00006F2A*
+ ID_MODEL_FROM_DATABASE=Broadwell IIO RAS/Control Status/Global Errors
+
+pci:v00008086d00006F2C*
+ ID_MODEL_FROM_DATABASE=Broadwell I/O APIC
+
+pci:v00008086d00006F30*
+ ID_MODEL_FROM_DATABASE=Broadwell Home Agent 0
+
+pci:v00008086d00006F32*
+ ID_MODEL_FROM_DATABASE=Broadwell QPI Link 0
+
+pci:v00008086d00006F33*
+ ID_MODEL_FROM_DATABASE=Broadwell QPI Link 1
+
+pci:v00008086d00006F34*
+ ID_MODEL_FROM_DATABASE=Broadwell R2PCIe Agent
+
+pci:v00008086d00006F36*
+ ID_MODEL_FROM_DATABASE=Broadwell R3 QPI Link 0/1
+
+pci:v00008086d00006F37*
+ ID_MODEL_FROM_DATABASE=Broadwell R3 QPI Link 0/1
+
+pci:v00008086d00006F38*
+ ID_MODEL_FROM_DATABASE=Broadwell Home Agent 1
+
+pci:v00008086d00006F39*
+ ID_MODEL_FROM_DATABASE=Broadwell IO Performance Monitoring
+
+pci:v00008086d00006F3A*
+ ID_MODEL_FROM_DATABASE=Broadwell QPI Link 2
+
+pci:v00008086d00006F3E*
+ ID_MODEL_FROM_DATABASE=Broadwell R3 QPI Link 2
+
+pci:v00008086d00006F3F*
+ ID_MODEL_FROM_DATABASE=Broadwell R3 QPI Link 2
+
+pci:v00008086d00006F40*
+ ID_MODEL_FROM_DATABASE=Broadwell QPI Link 2
+
+pci:v00008086d00006F41*
+ ID_MODEL_FROM_DATABASE=Broadwell R3 QPI Link 2
+
+pci:v00008086d00006F43*
+ ID_MODEL_FROM_DATABASE=Broadwell QPI Link 2
+
+pci:v00008086d00006F45*
+ ID_MODEL_FROM_DATABASE=Broadwell QPI Link 2 Debug
+
+pci:v00008086d00006F46*
+ ID_MODEL_FROM_DATABASE=Broadwell QPI Link 2 Debug
+
+pci:v00008086d00006F47*
+ ID_MODEL_FROM_DATABASE=Broadwell QPI Link 2 Debug
+
+pci:v00008086d00006F60*
+ ID_MODEL_FROM_DATABASE=Broadwell Home Agent 1
+
+pci:v00008086d00006F68*
+ ID_MODEL_FROM_DATABASE=Broadwell Target Address/Thermal/RAS
+
+pci:v00008086d00006F6A*
+ ID_MODEL_FROM_DATABASE=Broadwell Channel Target Address Decoder
+
+pci:v00008086d00006F6B*
+ ID_MODEL_FROM_DATABASE=Broadwell Channel Target Address Decoder
+
+pci:v00008086d00006F6C*
+ ID_MODEL_FROM_DATABASE=Broadwell Channel Target Address Decoder
+
+pci:v00008086d00006F6D*
+ ID_MODEL_FROM_DATABASE=Broadwell Channel Target Address Decoder
+
+pci:v00008086d00006F6E*
+ ID_MODEL_FROM_DATABASE=Broadwell DDRIO Channel 2/3 Broadcast
+
+pci:v00008086d00006F6F*
+ ID_MODEL_FROM_DATABASE=Broadwell DDRIO Global Broadcast
+
+pci:v00008086d00006F70*
+ ID_MODEL_FROM_DATABASE=Broadwell Home Agent 0 Debug
+
+pci:v00008086d00006F71*
+ ID_MODEL_FROM_DATABASE=Broadwell Memory Controller 0 - Target Address/Thermal/RAS
+
+pci:v00008086d00006F76*
+ ID_MODEL_FROM_DATABASE=Broadwell R3 QPI Link Debug
+
+pci:v00008086d00006F78*
+ ID_MODEL_FROM_DATABASE=Broadwell Home Agent 1 Debug
+
+pci:v00008086d00006F79*
+ ID_MODEL_FROM_DATABASE=Broadwell Target Address/Thermal/RAS
+
+pci:v00008086d00006F7D*
+ ID_MODEL_FROM_DATABASE=Broadwell Ubox
+
+pci:v00008086d00006F7E*
+ ID_MODEL_FROM_DATABASE=Broadwell R3 QPI Link Debug
+
+pci:v00008086d00006F80*
+ ID_MODEL_FROM_DATABASE=Broadwell QPI Link 0
+
+pci:v00008086d00006F81*
+ ID_MODEL_FROM_DATABASE=Broadwell R3 QPI Link 0/1
+
+pci:v00008086d00006F83*
+ ID_MODEL_FROM_DATABASE=Broadwell QPI Link 0
+
+pci:v00008086d00006F85*
+ ID_MODEL_FROM_DATABASE=Broadwell QPI Link 0 Debug
+
+pci:v00008086d00006F86*
+ ID_MODEL_FROM_DATABASE=Broadwell QPI Link 0 Debug
+
+pci:v00008086d00006F87*
+ ID_MODEL_FROM_DATABASE=Broadwell QPI Link 0 Debug
+
+pci:v00008086d00006F88*
+ ID_MODEL_FROM_DATABASE=Broadwell Power Control Unit
+
+pci:v00008086d00006F8A*
+ ID_MODEL_FROM_DATABASE=Broadwell Power Control Unit
+
+pci:v00008086d00006F90*
+ ID_MODEL_FROM_DATABASE=Broadwell QPI Link 1
+
+pci:v00008086d00006F93*
+ ID_MODEL_FROM_DATABASE=Broadwell QPI Link 1
+
+pci:v00008086d00006F95*
+ ID_MODEL_FROM_DATABASE=Broadwell QPI Link 1 Debug
+
+pci:v00008086d00006F96*
+ ID_MODEL_FROM_DATABASE=Broadwell QPI Link 1 Debug
+
+pci:v00008086d00006F98*
+ ID_MODEL_FROM_DATABASE=Broadwell Power Control Unit
+
+pci:v00008086d00006F99*
+ ID_MODEL_FROM_DATABASE=Broadwell Power Control Unit
+
+pci:v00008086d00006F9A*
+ ID_MODEL_FROM_DATABASE=Broadwell Power Control Unit
+
+pci:v00008086d00006F9C*
+ ID_MODEL_FROM_DATABASE=Broadwell Power Control Unit
+
+pci:v00008086d00006FA0*
+ ID_MODEL_FROM_DATABASE=Broadwell Home Agent 0
+
+pci:v00008086d00006FA8*
+ ID_MODEL_FROM_DATABASE=Broadwell Memory Controller 0 - Target Address/Thermal/RAS
+
+pci:v00008086d00006FAA*
+ ID_MODEL_FROM_DATABASE=Broadwell Memory Controller 0 - Channel Target Address Decoder
+
+pci:v00008086d00006FAB*
+ ID_MODEL_FROM_DATABASE=Broadwell Memory Controller 0 - Channel Target Address Decoder
+
+pci:v00008086d00006FAC*
+ ID_MODEL_FROM_DATABASE=Broadwell Memory Controller 0 - Channel Target Address Decoder
+
+pci:v00008086d00006FAD*
+ ID_MODEL_FROM_DATABASE=Broadwell Memory Controller 0 - Channel Target Address Decoder
+
+pci:v00008086d00006FAE*
+ ID_MODEL_FROM_DATABASE=Broadwell DDRIO Channel 0/1 Broadcast
+
+pci:v00008086d00006FAF*
+ ID_MODEL_FROM_DATABASE=Broadwell DDRIO Global Broadcast
+
+pci:v00008086d00006FB0*
+ ID_MODEL_FROM_DATABASE=Broadwell Memory Controller 0 - Channel 0 Thermal Control
+
+pci:v00008086d00006FB1*
+ ID_MODEL_FROM_DATABASE=Broadwell Memory Controller 0 - Channel 1 Thermal Control
+
+pci:v00008086d00006FB2*
+ ID_MODEL_FROM_DATABASE=Broadwell Memory Controller 0 - Channel 0 Error
+
+pci:v00008086d00006FB3*
+ ID_MODEL_FROM_DATABASE=Broadwell Memory Controller 0 - Channel 1 Error
+
+pci:v00008086d00006FB4*
+ ID_MODEL_FROM_DATABASE=Broadwell Memory Controller 0 - Channel 2 Thermal Control
+
+pci:v00008086d00006FB5*
+ ID_MODEL_FROM_DATABASE=Broadwell Memory Controller 0 - Channel 3 Thermal Control
+
+pci:v00008086d00006FB6*
+ ID_MODEL_FROM_DATABASE=Broadwell Memory Controller 0 - Channel 2 Error
+
+pci:v00008086d00006FB7*
+ ID_MODEL_FROM_DATABASE=Broadwell Memory Controller 0 - Channel 3 Error
+
+pci:v00008086d00006FB8*
+ ID_MODEL_FROM_DATABASE=Broadwell DDRIO Channel 2/3 Interface
+
+pci:v00008086d00006FB9*
+ ID_MODEL_FROM_DATABASE=Broadwell DDRIO Channel 2/3 Interface
+
+pci:v00008086d00006FBA*
+ ID_MODEL_FROM_DATABASE=Broadwell DDRIO Channel 2/3 Interface
+
+pci:v00008086d00006FBB*
+ ID_MODEL_FROM_DATABASE=Broadwell DDRIO Channel 2/3 Interface
+
+pci:v00008086d00006FBC*
+ ID_MODEL_FROM_DATABASE=Broadwell DDRIO Channel 0/1 Interface
+
+pci:v00008086d00006FBD*
+ ID_MODEL_FROM_DATABASE=Broadwell DDRIO Channel 0/1 Interface
+
+pci:v00008086d00006FBE*
+ ID_MODEL_FROM_DATABASE=Broadwell DDRIO Channel 0/1 Interface
+
+pci:v00008086d00006FBF*
+ ID_MODEL_FROM_DATABASE=Broadwell DDRIO Channel 0/1 Interface
+
+pci:v00008086d00006FC0*
+ ID_MODEL_FROM_DATABASE=Broadwell Power Control Unit
+
+pci:v00008086d00006FC1*
+ ID_MODEL_FROM_DATABASE=Broadwell Power Control Unit
+
+pci:v00008086d00006FC2*
+ ID_MODEL_FROM_DATABASE=Broadwell Power Control Unit
+
+pci:v00008086d00006FC3*
+ ID_MODEL_FROM_DATABASE=Broadwell Power Control Unit
+
+pci:v00008086d00006FC4*
+ ID_MODEL_FROM_DATABASE=Broadwell Power Control Unit
+
+pci:v00008086d00006FC5*
+ ID_MODEL_FROM_DATABASE=Broadwell Power Control Unit
+
+pci:v00008086d00006FC6*
+ ID_MODEL_FROM_DATABASE=Broadwell Power Control Unit
+
+pci:v00008086d00006FC7*
+ ID_MODEL_FROM_DATABASE=Broadwell Power Control Unit
+
+pci:v00008086d00006FC8*
+ ID_MODEL_FROM_DATABASE=Broadwell Power Control Unit
+
+pci:v00008086d00006FC9*
+ ID_MODEL_FROM_DATABASE=Broadwell Power Control Unit
+
+pci:v00008086d00006FCA*
+ ID_MODEL_FROM_DATABASE=Broadwell Power Control Unit
+
+pci:v00008086d00006FCB*
+ ID_MODEL_FROM_DATABASE=Broadwell Power Control Unit
+
+pci:v00008086d00006FCC*
+ ID_MODEL_FROM_DATABASE=Broadwell Power Control Unit
+
+pci:v00008086d00006FCD*
+ ID_MODEL_FROM_DATABASE=Broadwell Power Control Unit
+
+pci:v00008086d00006FCE*
+ ID_MODEL_FROM_DATABASE=Broadwell Power Control Unit
+
+pci:v00008086d00006FCF*
+ ID_MODEL_FROM_DATABASE=Broadwell Power Control Unit
+
+pci:v00008086d00006FD0*
+ ID_MODEL_FROM_DATABASE=Broadwell Memory Controller 1 - Channel 0 Thermal Control
+
+pci:v00008086d00006FD1*
+ ID_MODEL_FROM_DATABASE=Broadwell Memory Controller 1 - Channel 1 Thermal Control
+
+pci:v00008086d00006FD2*
+ ID_MODEL_FROM_DATABASE=Broadwell Memory Controller 1 - Channel 0 Error
+
+pci:v00008086d00006FD3*
+ ID_MODEL_FROM_DATABASE=Broadwell Memory Controller 1 - Channel 1 Error
+
+pci:v00008086d00006FD4*
+ ID_MODEL_FROM_DATABASE=Broadwell Memory Controller 1 - Channel 2 Thermal Control
+
+pci:v00008086d00006FD5*
+ ID_MODEL_FROM_DATABASE=Broadwell Memory Controller 1 - Channel 3 Thermal Control
+
+pci:v00008086d00006FD6*
+ ID_MODEL_FROM_DATABASE=Broadwell Memory Controller 1 - Channel 2 Error
+
+pci:v00008086d00006FD7*
+ ID_MODEL_FROM_DATABASE=Broadwell Memory Controller 1 - Channel 3 Error
+
+pci:v00008086d00006FE0*
+ ID_MODEL_FROM_DATABASE=Broadwell Caching Agent
+
+pci:v00008086d00006FE1*
+ ID_MODEL_FROM_DATABASE=Broadwell Caching Agent
+
+pci:v00008086d00006FE2*
+ ID_MODEL_FROM_DATABASE=Broadwell Caching Agent
+
+pci:v00008086d00006FE3*
+ ID_MODEL_FROM_DATABASE=Broadwell Caching Agent
+
+pci:v00008086d00006FE4*
+ ID_MODEL_FROM_DATABASE=Broadwell Caching Agent
+
+pci:v00008086d00006FE5*
+ ID_MODEL_FROM_DATABASE=Broadwell Caching Agent
+
+pci:v00008086d00006FE6*
+ ID_MODEL_FROM_DATABASE=Broadwell Caching Agent
+
+pci:v00008086d00006FE7*
+ ID_MODEL_FROM_DATABASE=Broadwell Caching Agent
+
+pci:v00008086d00006FE8*
+ ID_MODEL_FROM_DATABASE=Broadwell Caching Agent
+
+pci:v00008086d00006FE9*
+ ID_MODEL_FROM_DATABASE=Broadwell Caching Agent
+
+pci:v00008086d00006FEA*
+ ID_MODEL_FROM_DATABASE=Broadwell Caching Agent
+
+pci:v00008086d00006FEB*
+ ID_MODEL_FROM_DATABASE=Broadwell Caching Agent
+
+pci:v00008086d00006FEC*
+ ID_MODEL_FROM_DATABASE=Broadwell Caching Agent
+
+pci:v00008086d00006FED*
+ ID_MODEL_FROM_DATABASE=Broadwell Caching Agent
+
+pci:v00008086d00006FEE*
+ ID_MODEL_FROM_DATABASE=Broadwell Caching Agent
+
+pci:v00008086d00006FEF*
+ ID_MODEL_FROM_DATABASE=Broadwell Caching Agent
+
+pci:v00008086d00006FF0*
+ ID_MODEL_FROM_DATABASE=Broadwell Caching Agent
+
+pci:v00008086d00006FF1*
+ ID_MODEL_FROM_DATABASE=Broadwell Caching Agent
+
+pci:v00008086d00006FF8*
+ ID_MODEL_FROM_DATABASE=Broadwell Caching Agent
+
+pci:v00008086d00006FF9*
+ ID_MODEL_FROM_DATABASE=Broadwell Caching Agent
+
+pci:v00008086d00006FFA*
+ ID_MODEL_FROM_DATABASE=Broadwell Caching Agent
+
+pci:v00008086d00006FFB*
+ ID_MODEL_FROM_DATABASE=Broadwell Caching Agent
+
+pci:v00008086d00006FFC*
+ ID_MODEL_FROM_DATABASE=Broadwell Caching Agent
+
+pci:v00008086d00006FFD*
+ ID_MODEL_FROM_DATABASE=Broadwell Caching Agent
+
+pci:v00008086d00006FFE*
+ ID_MODEL_FROM_DATABASE=Broadwell Caching Agent
+
 pci:v00008086d00007000*
  ID_MODEL_FROM_DATABASE=82371SB PIIX3 ISA [Natoma/Triton II]
 
 pci:v00008086d00007000sv00001AF4sd00001100*
- ID_MODEL_FROM_DATABASE=Qemu virtual machine
+ ID_MODEL_FROM_DATABASE=82371SB PIIX3 ISA [Natoma/Triton II] (Qemu virtual machine)
 
 pci:v00008086d00007010*
  ID_MODEL_FROM_DATABASE=82371SB PIIX3 IDE [Natoma/Triton II]
 
 pci:v00008086d00007010sv00001AF4sd00001100*
- ID_MODEL_FROM_DATABASE=Qemu virtual machine
+ ID_MODEL_FROM_DATABASE=82371SB PIIX3 IDE [Natoma/Triton II] (Qemu virtual machine)
 
 pci:v00008086d00007020*
  ID_MODEL_FROM_DATABASE=82371SB PIIX3 USB [Natoma/Triton II]
 
 pci:v00008086d00007020sv00001AF4sd00001100*
- ID_MODEL_FROM_DATABASE=Qemu virtual machine
+ ID_MODEL_FROM_DATABASE=82371SB PIIX3 USB [Natoma/Triton II] (QEMU Virtual Machine)
 
 pci:v00008086d00007030*
  ID_MODEL_FROM_DATABASE=430VX - 82437VX TVX [Triton VX]
@@ -68706,49 +71325,52 @@ pci:v00008086d00007110*
  ID_MODEL_FROM_DATABASE=82371AB/EB/MB PIIX4 ISA
 
 pci:v00008086d00007110sv000015ADsd00001976*
- ID_MODEL_FROM_DATABASE=Virtual Machine Chipset
+ ID_MODEL_FROM_DATABASE=82371AB/EB/MB PIIX4 ISA (Virtual Machine Chipset)
 
 pci:v00008086d00007111*
  ID_MODEL_FROM_DATABASE=82371AB/EB/MB PIIX4 IDE
 
 pci:v00008086d00007111sv000015ADsd00001976*
- ID_MODEL_FROM_DATABASE=Virtual Machine Chipset
+ ID_MODEL_FROM_DATABASE=82371AB/EB/MB PIIX4 IDE (Virtual Machine Chipset)
 
 pci:v00008086d00007112*
  ID_MODEL_FROM_DATABASE=82371AB/EB/MB PIIX4 USB
 
 pci:v00008086d00007112sv000015ADsd00001976*
- ID_MODEL_FROM_DATABASE=Virtual Machine Chipset
+ ID_MODEL_FROM_DATABASE=82371AB/EB/MB PIIX4 USB (Virtual Machine Chipset)
+
+pci:v00008086d00007112sv00001AF4sd00001100*
+ ID_MODEL_FROM_DATABASE=82371AB/EB/MB PIIX4 USB (QEMU Virtual Machine)
 
 pci:v00008086d00007113*
  ID_MODEL_FROM_DATABASE=82371AB/EB/MB PIIX4 ACPI
 
 pci:v00008086d00007113sv000015ADsd00001976*
- ID_MODEL_FROM_DATABASE=Virtual Machine Chipset
+ ID_MODEL_FROM_DATABASE=82371AB/EB/MB PIIX4 ACPI (Virtual Machine Chipset)
 
 pci:v00008086d00007113sv00001AF4sd00001100*
- ID_MODEL_FROM_DATABASE=Qemu virtual machine
+ ID_MODEL_FROM_DATABASE=82371AB/EB/MB PIIX4 ACPI (Qemu virtual machine)
 
 pci:v00008086d00007120*
  ID_MODEL_FROM_DATABASE=82810 GMCH (Graphics Memory Controller Hub)
 
 pci:v00008086d00007120sv00004C53sd00001040*
- ID_MODEL_FROM_DATABASE=CL7 mainboard
+ ID_MODEL_FROM_DATABASE=82810 GMCH (Graphics Memory Controller Hub) (CL7 mainboard)
 
 pci:v00008086d00007120sv00004C53sd00001060*
- ID_MODEL_FROM_DATABASE=PC7 mainboard
+ ID_MODEL_FROM_DATABASE=82810 GMCH (Graphics Memory Controller Hub) (PC7 mainboard)
 
 pci:v00008086d00007121*
  ID_MODEL_FROM_DATABASE=82810 (CGC) Chipset Graphics Controller
 
 pci:v00008086d00007121sv00004C53sd00001040*
- ID_MODEL_FROM_DATABASE=CL7 mainboard
+ ID_MODEL_FROM_DATABASE=82810 (CGC) Chipset Graphics Controller (CL7 mainboard)
 
 pci:v00008086d00007121sv00004C53sd00001060*
- ID_MODEL_FROM_DATABASE=PC7 mainboard
+ ID_MODEL_FROM_DATABASE=82810 (CGC) Chipset Graphics Controller (PC7 mainboard)
 
 pci:v00008086d00007121sv00008086sd00004341*
- ID_MODEL_FROM_DATABASE=Cayman (CA810) Mainboard
+ ID_MODEL_FROM_DATABASE=82810 (CGC) Chipset Graphics Controller (Cayman (CA810) Mainboard)
 
 pci:v00008086d00007122*
  ID_MODEL_FROM_DATABASE=82810 DC-100 (GMCH) Graphics Memory Controller Hub
@@ -68760,13 +71382,13 @@ pci:v00008086d00007124*
  ID_MODEL_FROM_DATABASE=82810E DC-133 (GMCH) Graphics Memory Controller Hub
 
 pci:v00008086d00007124sv00001028sd000000B4*
- ID_MODEL_FROM_DATABASE=OptiPlex GX110
+ ID_MODEL_FROM_DATABASE=82810E DC-133 (GMCH) Graphics Memory Controller Hub (OptiPlex GX110)
 
 pci:v00008086d00007125*
  ID_MODEL_FROM_DATABASE=82810E DC-133 (CGC) Chipset Graphics Controller
 
 pci:v00008086d00007125sv00001028sd000000B4*
- ID_MODEL_FROM_DATABASE=OptiPlex GX110
+ ID_MODEL_FROM_DATABASE=82810E DC-133 (CGC) Chipset Graphics Controller (OptiPlex GX110)
 
 pci:v00008086d00007126*
  ID_MODEL_FROM_DATABASE=82810 DC-133 System and Graphics Controller
@@ -68787,73 +71409,73 @@ pci:v00008086d00007190*
  ID_MODEL_FROM_DATABASE=440BX/ZX/DX - 82443BX/ZX/DX Host bridge
 
 pci:v00008086d00007190sv00000E11sd00000500*
- ID_MODEL_FROM_DATABASE=Armada 1750 Laptop System Chipset
+ ID_MODEL_FROM_DATABASE=440BX/ZX/DX - 82443BX/ZX/DX Host bridge (Armada 1750 Laptop System Chipset)
 
 pci:v00008086d00007190sv00000E11sd0000B110*
- ID_MODEL_FROM_DATABASE=Armada M700/E500
+ ID_MODEL_FROM_DATABASE=440BX/ZX/DX - 82443BX/ZX/DX Host bridge (Armada M700/E500)
 
 pci:v00008086d00007190sv00001028sd0000008E*
- ID_MODEL_FROM_DATABASE=PowerEdge 1300 mainboard
+ ID_MODEL_FROM_DATABASE=440BX/ZX/DX - 82443BX/ZX/DX Host bridge (PowerEdge 1300 mainboard)
 
 pci:v00008086d00007190sv00001043sd0000803B*
- ID_MODEL_FROM_DATABASE=CUBX-L/E Mainboard
+ ID_MODEL_FROM_DATABASE=440BX/ZX/DX - 82443BX/ZX/DX Host bridge (CUBX-L/E Mainboard)
 
 pci:v00008086d00007190sv00001179sd00000001*
- ID_MODEL_FROM_DATABASE=Toshiba Tecra 8100 Laptop System Chipset
+ ID_MODEL_FROM_DATABASE=440BX/ZX/DX - 82443BX/ZX/DX Host bridge (Toshiba Tecra 8100 Laptop System Chipset)
 
 pci:v00008086d00007190sv000015ADsd00001976*
- ID_MODEL_FROM_DATABASE=Virtual Machine Chipset
+ ID_MODEL_FROM_DATABASE=440BX/ZX/DX - 82443BX/ZX/DX Host bridge (Virtual Machine Chipset)
 
 pci:v00008086d00007190sv00004C53sd00001050*
- ID_MODEL_FROM_DATABASE=CT7 mainboard
+ ID_MODEL_FROM_DATABASE=440BX/ZX/DX - 82443BX/ZX/DX Host bridge (CT7 mainboard)
 
 pci:v00008086d00007190sv00004C53sd00001051*
- ID_MODEL_FROM_DATABASE=CE7 mainboard
+ ID_MODEL_FROM_DATABASE=440BX/ZX/DX - 82443BX/ZX/DX Host bridge (CE7 mainboard)
 
 pci:v00008086d00007191*
  ID_MODEL_FROM_DATABASE=440BX/ZX/DX - 82443BX/ZX/DX AGP bridge
 
 pci:v00008086d00007191sv00001028sd0000008E*
- ID_MODEL_FROM_DATABASE=PowerEdge 1300 mainboard
+ ID_MODEL_FROM_DATABASE=440BX/ZX/DX - 82443BX/ZX/DX AGP bridge (PowerEdge 1300 mainboard)
 
 pci:v00008086d00007192*
  ID_MODEL_FROM_DATABASE=440BX/ZX/DX - 82443BX/ZX/DX Host bridge (AGP disabled)
 
 pci:v00008086d00007192sv00000E11sd00000460*
- ID_MODEL_FROM_DATABASE=Armada 1700 Laptop System Chipset
+ ID_MODEL_FROM_DATABASE=440BX/ZX/DX - 82443BX/ZX/DX Host bridge (AGP disabled) (Armada 1700 Laptop System Chipset)
 
 pci:v00008086d00007192sv00001179sd00000001*
- ID_MODEL_FROM_DATABASE=Satellite 4010
+ ID_MODEL_FROM_DATABASE=440BX/ZX/DX - 82443BX/ZX/DX Host bridge (AGP disabled) (Satellite 4010)
 
 pci:v00008086d00007192sv00004C53sd00001000*
- ID_MODEL_FROM_DATABASE=CC7/CR7/CP7/VC7/VP7/VR7 mainboard
+ ID_MODEL_FROM_DATABASE=440BX/ZX/DX - 82443BX/ZX/DX Host bridge (AGP disabled) (CC7/CR7/CP7/VC7/VP7/VR7 mainboard)
 
 pci:v00008086d00007192sv00008086sd00007190*
- ID_MODEL_FROM_DATABASE=Dell PowerEdge 350
+ ID_MODEL_FROM_DATABASE=440BX/ZX/DX - 82443BX/ZX/DX Host bridge (AGP disabled) (Dell PowerEdge 350)
 
 pci:v00008086d00007194*
  ID_MODEL_FROM_DATABASE=82440MX Host Bridge
 
 pci:v00008086d00007194sv00001033sd00000000*
- ID_MODEL_FROM_DATABASE=Versa Note Vxi
+ ID_MODEL_FROM_DATABASE=82440MX Host Bridge (Versa Note Vxi)
 
 pci:v00008086d00007194sv00004C53sd000010A0*
- ID_MODEL_FROM_DATABASE=CA3/CR3 mainboard
+ ID_MODEL_FROM_DATABASE=82440MX Host Bridge (CA3/CR3 mainboard)
 
 pci:v00008086d00007195*
  ID_MODEL_FROM_DATABASE=82440MX AC'97 Audio Controller
 
 pci:v00008086d00007195sv00001033sd000080CC*
- ID_MODEL_FROM_DATABASE=Versa Note VXi
+ ID_MODEL_FROM_DATABASE=82440MX AC'97 Audio Controller (Versa Note VXi)
 
 pci:v00008086d00007195sv000010CFsd00001099*
- ID_MODEL_FROM_DATABASE=QSound_SigmaTel Stac97 PCI Audio
+ ID_MODEL_FROM_DATABASE=82440MX AC'97 Audio Controller (QSound_SigmaTel Stac97 PCI Audio)
 
 pci:v00008086d00007195sv000011D4sd00000040*
- ID_MODEL_FROM_DATABASE=SoundMAX Integrated Digital Audio
+ ID_MODEL_FROM_DATABASE=82440MX AC'97 Audio Controller (SoundMAX Integrated Digital Audio)
 
 pci:v00008086d00007195sv000011D4sd00000048*
- ID_MODEL_FROM_DATABASE=SoundMAX Integrated Digital Audio
+ ID_MODEL_FROM_DATABASE=82440MX AC'97 Audio Controller (SoundMAX Integrated Digital Audio)
 
 pci:v00008086d00007196*
  ID_MODEL_FROM_DATABASE=82440MX AC'97 Modem Controller
@@ -68874,10 +71496,10 @@ pci:v00008086d000071A0*
  ID_MODEL_FROM_DATABASE=440GX - 82443GX Host bridge
 
 pci:v00008086d000071A0sv00004C53sd00001050*
- ID_MODEL_FROM_DATABASE=CT7 mainboard
+ ID_MODEL_FROM_DATABASE=440GX - 82443GX Host bridge (CT7 mainboard)
 
 pci:v00008086d000071A0sv00004C53sd00001051*
- ID_MODEL_FROM_DATABASE=CE7 mainboard
+ ID_MODEL_FROM_DATABASE=440GX - 82443GX Host bridge (CE7 mainboard)
 
 pci:v00008086d000071A1*
  ID_MODEL_FROM_DATABASE=440GX - 82443GX AGP bridge
@@ -68886,7 +71508,7 @@ pci:v00008086d000071A2*
  ID_MODEL_FROM_DATABASE=440GX - 82443GX Host bridge (AGP disabled)
 
 pci:v00008086d000071A2sv00004C53sd00001000*
- ID_MODEL_FROM_DATABASE=CC7/CR7/CP7/VC7/VP7/VR7 mainboard
+ ID_MODEL_FROM_DATABASE=440GX - 82443GX Host bridge (AGP disabled) (CC7/CR7/CP7/VC7/VP7/VR7 mainboard)
 
 pci:v00008086d00007600*
  ID_MODEL_FROM_DATABASE=82372FB PIIX5 ISA
@@ -68904,25 +71526,25 @@ pci:v00008086d00007800*
  ID_MODEL_FROM_DATABASE=82740 (i740) AGP Graphics Accelerator
 
 pci:v00008086d00007800sv0000003Dsd00000008*
- ID_MODEL_FROM_DATABASE=Starfighter AGP
+ ID_MODEL_FROM_DATABASE=82740 (i740) AGP Graphics Accelerator (Starfighter AGP)
 
 pci:v00008086d00007800sv0000003Dsd0000000B*
- ID_MODEL_FROM_DATABASE=Starfighter AGP
+ ID_MODEL_FROM_DATABASE=82740 (i740) AGP Graphics Accelerator (Starfighter AGP)
 
 pci:v00008086d00007800sv00001092sd00000100*
- ID_MODEL_FROM_DATABASE=Stealth II G460
+ ID_MODEL_FROM_DATABASE=82740 (i740) AGP Graphics Accelerator (Stealth II G460)
 
 pci:v00008086d00007800sv000010B4sd0000201A*
- ID_MODEL_FROM_DATABASE=Lightspeed 740
+ ID_MODEL_FROM_DATABASE=82740 (i740) AGP Graphics Accelerator (Lightspeed 740)
 
 pci:v00008086d00007800sv000010B4sd0000202F*
- ID_MODEL_FROM_DATABASE=Lightspeed 740
+ ID_MODEL_FROM_DATABASE=82740 (i740) AGP Graphics Accelerator (Lightspeed 740)
 
 pci:v00008086d00007800sv00008086sd00000000*
- ID_MODEL_FROM_DATABASE=Terminator 2x/i
+ ID_MODEL_FROM_DATABASE=82740 (i740) AGP Graphics Accelerator (Terminator 2x/i)
 
 pci:v00008086d00007800sv00008086sd00000100*
- ID_MODEL_FROM_DATABASE=Intel740 Graphics Accelerator
+ ID_MODEL_FROM_DATABASE=82740 (i740) AGP Graphics Accelerator (Intel740 Graphics Accelerator)
 
 pci:v00008086d00008002*
  ID_MODEL_FROM_DATABASE=Trusted Execution Technology Registers
@@ -69033,13 +71655,13 @@ pci:v00008086d00008500*
  ID_MODEL_FROM_DATABASE=IXP4XX Network Processor (IXP420/421/422/425/IXC1100)
 
 pci:v00008086d00008500sv00001993sd00000DED*
- ID_MODEL_FROM_DATABASE=mGuard-PCI AV#2
+ ID_MODEL_FROM_DATABASE=IXP4XX Network Processor (IXP420/421/422/425/IXC1100) (mGuard-PCI AV#2)
 
 pci:v00008086d00008500sv00001993sd00000DEE*
- ID_MODEL_FROM_DATABASE=mGuard-PCI AV#1
+ ID_MODEL_FROM_DATABASE=IXP4XX Network Processor (IXP420/421/422/425/IXC1100) (mGuard-PCI AV#1)
 
 pci:v00008086d00008500sv00001993sd00000DEF*
- ID_MODEL_FROM_DATABASE=mGuard-PCI AV#0
+ ID_MODEL_FROM_DATABASE=IXP4XX Network Processor (IXP420/421/422/425/IXC1100) (mGuard-PCI AV#0)
 
 pci:v00008086d00008800*
  ID_MODEL_FROM_DATABASE=Platform Controller Hub EG20T PCI Express Port
@@ -69131,8 +71753,11 @@ pci:v00008086d00008C02*
 pci:v00008086d00008C03*
  ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family 6-port SATA Controller 1 [AHCI mode]
 
+pci:v00008086d00008C03sv0000103Csd00001909*
+ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family 6-port SATA Controller 1 [AHCI mode] (ZBook 15)
+
 pci:v00008086d00008C03sv000017AAsd0000220E*
- ID_MODEL_FROM_DATABASE=ThinkPad T440p
+ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family 6-port SATA Controller 1 [AHCI mode] (ThinkPad T440p)
 
 pci:v00008086d00008C04*
  ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family SATA Controller 1 [RAID mode]
@@ -69162,7 +71787,7 @@ pci:v00008086d00008C10*
  ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family PCI Express Root Port #1
 
 pci:v00008086d00008C10sv000017AAsd0000220E*
- ID_MODEL_FROM_DATABASE=ThinkPad T440p
+ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family PCI Express Root Port #1 (ThinkPad T440p)
 
 pci:v00008086d00008C11*
  ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family PCI Express Root Port #1
@@ -69171,7 +71796,7 @@ pci:v00008086d00008C12*
  ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family PCI Express Root Port #2
 
 pci:v00008086d00008C12sv000017AAsd0000220E*
- ID_MODEL_FROM_DATABASE=ThinkPad T440p
+ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family PCI Express Root Port #2 (ThinkPad T440p)
 
 pci:v00008086d00008C13*
  ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family PCI Express Root Port #2
@@ -69215,8 +71840,11 @@ pci:v00008086d00008C1F*
 pci:v00008086d00008C20*
  ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset High Definition Audio Controller
 
+pci:v00008086d00008C20sv0000103Csd00001909*
+ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset High Definition Audio Controller (ZBook 15)
+
 pci:v00008086d00008C20sv000017AAsd0000220E*
- ID_MODEL_FROM_DATABASE=ThinkPad T440p
+ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset High Definition Audio Controller (ThinkPad T440p)
 
 pci:v00008086d00008C21*
  ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset High Definition Audio Controller
@@ -69224,8 +71852,11 @@ pci:v00008086d00008C21*
 pci:v00008086d00008C22*
  ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family SMBus Controller
 
+pci:v00008086d00008C22sv0000103Csd00001909*
+ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family SMBus Controller (ZBook 15)
+
 pci:v00008086d00008C22sv000017AAsd0000220E*
- ID_MODEL_FROM_DATABASE=ThinkPad T440p
+ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family SMBus Controller (ThinkPad T440p)
 
 pci:v00008086d00008C23*
  ID_MODEL_FROM_DATABASE=8 Series Chipset Family CHAP Counters
@@ -69236,20 +71867,29 @@ pci:v00008086d00008C24*
 pci:v00008086d00008C26*
  ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family USB EHCI #1
 
+pci:v00008086d00008C26sv0000103Csd00001909*
+ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family USB EHCI #1 (ZBook 15)
+
 pci:v00008086d00008C26sv000017AAsd0000220E*
- ID_MODEL_FROM_DATABASE=ThinkPad T440p
+ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family USB EHCI #1 (ThinkPad T440p)
 
 pci:v00008086d00008C2D*
  ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family USB EHCI #2
 
+pci:v00008086d00008C2Dsv0000103Csd00001909*
+ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family USB EHCI #2 (ZBook 15)
+
 pci:v00008086d00008C2Dsv000017AAsd0000220E*
- ID_MODEL_FROM_DATABASE=ThinkPad T440p
+ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family USB EHCI #2 (ThinkPad T440p)
 
 pci:v00008086d00008C31*
  ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family USB xHCI
 
+pci:v00008086d00008C31sv0000103Csd00001909*
+ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family USB xHCI (ZBook 15)
+
 pci:v00008086d00008C31sv000017AAsd0000220E*
- ID_MODEL_FROM_DATABASE=ThinkPad T440p
+ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family USB xHCI (ThinkPad T440p)
 
 pci:v00008086d00008C33*
  ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family LAN Controller
@@ -69260,8 +71900,11 @@ pci:v00008086d00008C34*
 pci:v00008086d00008C3A*
  ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family MEI Controller #1
 
+pci:v00008086d00008C3Asv0000103Csd00001909*
+ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family MEI Controller #1 (ZBook 15)
+
 pci:v00008086d00008C3Asv000017AAsd0000220E*
- ID_MODEL_FROM_DATABASE=ThinkPad T440p
+ ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family MEI Controller #1 (ThinkPad T440p)
 
 pci:v00008086d00008C3B*
  ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family MEI Controller #2
@@ -69320,8 +71963,11 @@ pci:v00008086d00008C4E*
 pci:v00008086d00008C4F*
  ID_MODEL_FROM_DATABASE=QM87 Express LPC Controller
 
+pci:v00008086d00008C4Fsv0000103Csd00001909*
+ ID_MODEL_FROM_DATABASE=QM87 Express LPC Controller (ZBook 15)
+
 pci:v00008086d00008C4Fsv000017AAsd0000220E*
- ID_MODEL_FROM_DATABASE=ThinkPad T440p
+ ID_MODEL_FROM_DATABASE=QM87 Express LPC Controller (ThinkPad T440p)
 
 pci:v00008086d00008C50*
  ID_MODEL_FROM_DATABASE=B85 Express LPC Controller
@@ -69371,6 +72017,114 @@ pci:v00008086d00008C5E*
 pci:v00008086d00008C5F*
  ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family LPC Controller
 
+pci:v00008086d00008C80*
+ ID_MODEL_FROM_DATABASE=9 Series Chipset Family SATA Controller [IDE Mode]
+
+pci:v00008086d00008C81*
+ ID_MODEL_FROM_DATABASE=9 Series Chipset Family SATA Controller [IDE Mode]
+
+pci:v00008086d00008C82*
+ ID_MODEL_FROM_DATABASE=9 Series Chipset Family SATA Controller [AHCI Mode]
+
+pci:v00008086d00008C83*
+ ID_MODEL_FROM_DATABASE=9 Series Chipset Family SATA Controller [AHCI Mode]
+
+pci:v00008086d00008C84*
+ ID_MODEL_FROM_DATABASE=9 Series Chipset Family SATA Controller [RAID Mode]
+
+pci:v00008086d00008C85*
+ ID_MODEL_FROM_DATABASE=9 Series Chipset Family SATA Controller [RAID Mode]
+
+pci:v00008086d00008C86*
+ ID_MODEL_FROM_DATABASE=9 Series Chipset Family SATA Controller [RAID Mode]
+
+pci:v00008086d00008C87*
+ ID_MODEL_FROM_DATABASE=9 Series Chipset Family SATA Controller [RAID Mode]
+
+pci:v00008086d00008C88*
+ ID_MODEL_FROM_DATABASE=9 Series Chipset Family SATA Controller [IDE Mode]
+
+pci:v00008086d00008C89*
+ ID_MODEL_FROM_DATABASE=9 Series Chipset Family SATA Controller [IDE Mode]
+
+pci:v00008086d00008C8E*
+ ID_MODEL_FROM_DATABASE=9 Series Chipset Family SATA Controller [RAID Mode]
+
+pci:v00008086d00008C8F*
+ ID_MODEL_FROM_DATABASE=9 Series Chipset Family SATA Controller [RAID Mode]
+
+pci:v00008086d00008C90*
+ ID_MODEL_FROM_DATABASE=9 Series Chipset Family PCI Express Root Port 1
+
+pci:v00008086d00008C92*
+ ID_MODEL_FROM_DATABASE=9 Series Chipset Family PCI Express Root Port 2
+
+pci:v00008086d00008C94*
+ ID_MODEL_FROM_DATABASE=9 Series Chipset Family PCI Express Root Port 3
+
+pci:v00008086d00008C96*
+ ID_MODEL_FROM_DATABASE=9 Series Chipset Family PCI Express Root Port 4
+
+pci:v00008086d00008C98*
+ ID_MODEL_FROM_DATABASE=9 Series Chipset Family PCI Express Root Port 5
+
+pci:v00008086d00008C9A*
+ ID_MODEL_FROM_DATABASE=9 Series Chipset Family PCI Express Root Port 6
+
+pci:v00008086d00008C9C*
+ ID_MODEL_FROM_DATABASE=9 Series Chipset Family PCI Express Root Port 7
+
+pci:v00008086d00008C9E*
+ ID_MODEL_FROM_DATABASE=9 Series Chipset Family PCI Express Root Port 8
+
+pci:v00008086d00008CA0*
+ ID_MODEL_FROM_DATABASE=9 Series Chipset Family HD Audio Controller
+
+pci:v00008086d00008CA2*
+ ID_MODEL_FROM_DATABASE=9 Series Chipset Family SMBus Controller
+
+pci:v00008086d00008CA4*
+ ID_MODEL_FROM_DATABASE=9 Series Chipset Family Thermal Controller
+
+pci:v00008086d00008CA6*
+ ID_MODEL_FROM_DATABASE=9 Series Chipset Family USB EHCI Controller #1
+
+pci:v00008086d00008CAD*
+ ID_MODEL_FROM_DATABASE=9 Series Chipset Family USB EHCI Controller #2
+
+pci:v00008086d00008CB1*
+ ID_MODEL_FROM_DATABASE=9 Series Chipset Family USB xHCI Controller
+
+pci:v00008086d00008CB3*
+ ID_MODEL_FROM_DATABASE=9 Series Chipset Family LAN Controller
+
+pci:v00008086d00008CBA*
+ ID_MODEL_FROM_DATABASE=9 Series Chipset Family ME Interface #1
+
+pci:v00008086d00008CBB*
+ ID_MODEL_FROM_DATABASE=9 Series Chipset Family ME Interface #2
+
+pci:v00008086d00008CBC*
+ ID_MODEL_FROM_DATABASE=9 Series Chipset Family IDE-R Controller
+
+pci:v00008086d00008CBD*
+ ID_MODEL_FROM_DATABASE=9 Series Chipset Family KT Controller
+
+pci:v00008086d00008CC1*
+ ID_MODEL_FROM_DATABASE=9 Series Chipset Family LPC Controller
+
+pci:v00008086d00008CC2*
+ ID_MODEL_FROM_DATABASE=9 Series Chipset Family LPC Controller
+
+pci:v00008086d00008CC3*
+ ID_MODEL_FROM_DATABASE=9 Series Chipset Family HM97 LPC Controller
+
+pci:v00008086d00008CC4*
+ ID_MODEL_FROM_DATABASE=9 Series Chipset Family Z97 LPC Controller
+
+pci:v00008086d00008CC6*
+ ID_MODEL_FROM_DATABASE=9 Series Chipset Family H97 Controller
+
 pci:v00008086d00008D00*
  ID_MODEL_FROM_DATABASE=Wellsburg 4-port SATA Controller [IDE mode]
 
@@ -69383,6 +72137,9 @@ pci:v00008086d00008D04*
 pci:v00008086d00008D06*
  ID_MODEL_FROM_DATABASE=Wellsburg SATA Controller [RAID mode]
 
+pci:v00008086d00008D06sv000017AAsd00001031*
+ ID_MODEL_FROM_DATABASE=Wellsburg SATA Controller [RAID mode] (ThinkServer RAID 110i)
+
 pci:v00008086d00008D08*
  ID_MODEL_FROM_DATABASE=Wellsburg 2-port SATA Controller [IDE mode]
 
@@ -69579,187 +72336,208 @@ pci:v00008086d000096A1*
  ID_MODEL_FROM_DATABASE=Integrated RAID
 
 pci:v00008086d00009C00*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP SATA Controller 1 [IDE mode]
+ ID_MODEL_FROM_DATABASE=8 Series SATA Controller 1 [IDE mode]
 
 pci:v00008086d00009C01*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP SATA Controller 1 [IDE mode]
+ ID_MODEL_FROM_DATABASE=8 Series SATA Controller 1 [IDE mode]
 
 pci:v00008086d00009C02*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP SATA Controller 1 [AHCI mode]
+ ID_MODEL_FROM_DATABASE=8 Series SATA Controller 1 [AHCI mode]
 
 pci:v00008086d00009C03*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP SATA Controller 1 [AHCI mode]
+ ID_MODEL_FROM_DATABASE=8 Series SATA Controller 1 [AHCI mode]
+
+pci:v00008086d00009C03sv000017AAsd00002214*
+ ID_MODEL_FROM_DATABASE=8 Series SATA Controller 1 [AHCI mode] (ThinkPad X240)
 
 pci:v00008086d00009C04*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP SATA Controller 1 [RAID mode]
+ ID_MODEL_FROM_DATABASE=8 Series SATA Controller 1 [RAID mode]
 
 pci:v00008086d00009C05*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP SATA Controller 1 [RAID mode]
+ ID_MODEL_FROM_DATABASE=8 Series SATA Controller 1 [RAID mode]
 
 pci:v00008086d00009C06*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP SATA Controller 1 [RAID mode]
+ ID_MODEL_FROM_DATABASE=8 Series SATA Controller 1 [RAID mode]
 
 pci:v00008086d00009C07*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP SATA Controller 1 [RAID mode]
+ ID_MODEL_FROM_DATABASE=8 Series SATA Controller 1 [RAID mode]
 
 pci:v00008086d00009C08*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP SATA Controller 2 [IDE mode]
+ ID_MODEL_FROM_DATABASE=8 Series SATA Controller 2 [IDE mode]
 
 pci:v00008086d00009C09*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP SATA Controller 2 [IDE mode]
+ ID_MODEL_FROM_DATABASE=8 Series SATA Controller 2 [IDE mode]
 
 pci:v00008086d00009C0A*
- ID_MODEL_FROM_DATABASE=LynxPoint-LP SATA Controller [Reserved]
+ ID_MODEL_FROM_DATABASE=8 Series SATA Controller [Reserved]
 
 pci:v00008086d00009C0B*
- ID_MODEL_FROM_DATABASE=LynxPoint-LP SATA Controller [Reserved]
+ ID_MODEL_FROM_DATABASE=8 Series SATA Controller [Reserved]
 
 pci:v00008086d00009C0C*
- ID_MODEL_FROM_DATABASE=LynxPoint-LP SATA Controller [Reserved]
+ ID_MODEL_FROM_DATABASE=8 Series SATA Controller [Reserved]
 
 pci:v00008086d00009C0D*
- ID_MODEL_FROM_DATABASE=LynxPoint-LP SATA Controller [Reserved]
+ ID_MODEL_FROM_DATABASE=8 Series SATA Controller [Reserved]
 
 pci:v00008086d00009C0E*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP SATA Controller 1 [RAID mode]
+ ID_MODEL_FROM_DATABASE=8 Series SATA Controller 1 [RAID mode]
 
 pci:v00008086d00009C0F*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP SATA Controller 1 [RAID mode]
+ ID_MODEL_FROM_DATABASE=8 Series SATA Controller 1 [RAID mode]
 
 pci:v00008086d00009C10*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP PCI Express Root Port 1
+ ID_MODEL_FROM_DATABASE=8 Series PCI Express Root Port 1
 
 pci:v00008086d00009C11*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP PCI Express Root Port 1
+ ID_MODEL_FROM_DATABASE=8 Series PCI Express Root Port 1
 
 pci:v00008086d00009C12*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP PCI Express Root Port 2
+ ID_MODEL_FROM_DATABASE=8 Series PCI Express Root Port 2
 
 pci:v00008086d00009C13*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP PCI Express Root Port 2
+ ID_MODEL_FROM_DATABASE=8 Series PCI Express Root Port 2
 
 pci:v00008086d00009C14*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP PCI Express Root Port 3
+ ID_MODEL_FROM_DATABASE=8 Series PCI Express Root Port 3
 
 pci:v00008086d00009C15*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP PCI Express Root Port 3
+ ID_MODEL_FROM_DATABASE=8 Series PCI Express Root Port 3
 
 pci:v00008086d00009C16*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP PCI Express Root Port 4
+ ID_MODEL_FROM_DATABASE=8 Series PCI Express Root Port 4
 
 pci:v00008086d00009C17*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP PCI Express Root Port 4
+ ID_MODEL_FROM_DATABASE=8 Series PCI Express Root Port 4
 
 pci:v00008086d00009C18*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP PCI Express Root Port 5
+ ID_MODEL_FROM_DATABASE=8 Series PCI Express Root Port 5
 
 pci:v00008086d00009C19*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP PCI Express Root Port 5
+ ID_MODEL_FROM_DATABASE=8 Series PCI Express Root Port 5
 
 pci:v00008086d00009C1A*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP PCI Express Root Port 6
+ ID_MODEL_FROM_DATABASE=8 Series PCI Express Root Port 6
 
 pci:v00008086d00009C1B*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP PCI Express Root Port 6
+ ID_MODEL_FROM_DATABASE=8 Series PCI Express Root Port 6
 
 pci:v00008086d00009C1C*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP PCI Express Root Port 7
+ ID_MODEL_FROM_DATABASE=8 Series PCI Express Root Port 7
 
 pci:v00008086d00009C1D*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP PCI Express Root Port 7
+ ID_MODEL_FROM_DATABASE=8 Series PCI Express Root Port 7
 
 pci:v00008086d00009C1E*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP PCI Express Root Port 8
+ ID_MODEL_FROM_DATABASE=8 Series PCI Express Root Port 8
 
 pci:v00008086d00009C1F*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP PCI Express Root Port 8
+ ID_MODEL_FROM_DATABASE=8 Series PCI Express Root Port 8
 
 pci:v00008086d00009C20*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP HD Audio Controller
+ ID_MODEL_FROM_DATABASE=8 Series HD Audio Controller
+
+pci:v00008086d00009C20sv000017AAsd00002214*
+ ID_MODEL_FROM_DATABASE=8 Series HD Audio Controller (ThinkPad X240)
 
 pci:v00008086d00009C21*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP HD Audio Controller
+ ID_MODEL_FROM_DATABASE=8 Series HD Audio Controller
 
 pci:v00008086d00009C22*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP SMBus Controller
+ ID_MODEL_FROM_DATABASE=8 Series SMBus Controller
+
+pci:v00008086d00009C22sv000017AAsd00002214*
+ ID_MODEL_FROM_DATABASE=8 Series SMBus Controller (ThinkPad X240)
 
 pci:v00008086d00009C23*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP CHAP Counters
+ ID_MODEL_FROM_DATABASE=8 Series CHAP Counters
 
 pci:v00008086d00009C24*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP Thermal
+ ID_MODEL_FROM_DATABASE=8 Series Thermal
 
 pci:v00008086d00009C26*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP USB EHCI #1
+ ID_MODEL_FROM_DATABASE=8 Series USB EHCI #1
+
+pci:v00008086d00009C26sv000017AAsd00002214*
+ ID_MODEL_FROM_DATABASE=8 Series USB EHCI #1 (ThinkPad X240)
 
 pci:v00008086d00009C2D*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP USB EHCI #2
+ ID_MODEL_FROM_DATABASE=8 Series USB EHCI #2
 
 pci:v00008086d00009C31*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP USB xHCI HC
+ ID_MODEL_FROM_DATABASE=8 Series USB xHCI HC
+
+pci:v00008086d00009C31sv000017AAsd00002214*
+ ID_MODEL_FROM_DATABASE=8 Series USB xHCI HC (ThinkPad X240)
 
 pci:v00008086d00009C35*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP SDIO Controller
+ ID_MODEL_FROM_DATABASE=8 Series SDIO Controller
 
 pci:v00008086d00009C36*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP Audio DSP Controller
+ ID_MODEL_FROM_DATABASE=8 Series Audio DSP Controller
 
 pci:v00008086d00009C3A*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP HECI #0
+ ID_MODEL_FROM_DATABASE=8 Series HECI #0
+
+pci:v00008086d00009C3Asv000017AAsd00002214*
+ ID_MODEL_FROM_DATABASE=8 Series HECI #0 (ThinkPad X240)
 
 pci:v00008086d00009C3B*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP HECI #1
+ ID_MODEL_FROM_DATABASE=8 Series HECI #1
 
 pci:v00008086d00009C3C*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP HECI IDER
+ ID_MODEL_FROM_DATABASE=8 Series HECI IDER
 
 pci:v00008086d00009C3D*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP HECI KT
+ ID_MODEL_FROM_DATABASE=8 Series HECI KT
 
 pci:v00008086d00009C40*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP LPC Controller
+ ID_MODEL_FROM_DATABASE=8 Series LPC Controller
 
 pci:v00008086d00009C41*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP LPC Controller
+ ID_MODEL_FROM_DATABASE=8 Series LPC Controller
 
 pci:v00008086d00009C42*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP LPC Controller
+ ID_MODEL_FROM_DATABASE=8 Series LPC Controller
 
 pci:v00008086d00009C43*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP LPC Controller
+ ID_MODEL_FROM_DATABASE=8 Series LPC Controller
+
+pci:v00008086d00009C43sv000017AAsd00002214*
+ ID_MODEL_FROM_DATABASE=8 Series LPC Controller (ThinkPad X240)
 
 pci:v00008086d00009C44*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP LPC Controller
+ ID_MODEL_FROM_DATABASE=8 Series LPC Controller
 
 pci:v00008086d00009C45*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP LPC Controller
+ ID_MODEL_FROM_DATABASE=8 Series LPC Controller
 
 pci:v00008086d00009C46*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP LPC Controller
+ ID_MODEL_FROM_DATABASE=8 Series LPC Controller
 
 pci:v00008086d00009C47*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP LPC Controller
+ ID_MODEL_FROM_DATABASE=8 Series LPC Controller
 
 pci:v00008086d00009C60*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP Low Power Sub-System DMA
+ ID_MODEL_FROM_DATABASE=8 Series Low Power Sub-System DMA
 
 pci:v00008086d00009C61*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP I2C Controller #0
+ ID_MODEL_FROM_DATABASE=8 Series I2C Controller #0
 
 pci:v00008086d00009C62*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP I2C Controller #1
+ ID_MODEL_FROM_DATABASE=8 Series I2C Controller #1
 
 pci:v00008086d00009C63*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP UART Controller #0
+ ID_MODEL_FROM_DATABASE=8 Series UART Controller #0
 
 pci:v00008086d00009C64*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP UART Controller #1
+ ID_MODEL_FROM_DATABASE=8 Series UART Controller #1
 
 pci:v00008086d00009C65*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP SPI Controller #0
+ ID_MODEL_FROM_DATABASE=8 Series SPI Controller #0
 
 pci:v00008086d00009C66*
- ID_MODEL_FROM_DATABASE=Lynx Point-LP SPI Controller #1
+ ID_MODEL_FROM_DATABASE=8 Series SPI Controller #1
 
 pci:v00008086d00009C83*
  ID_MODEL_FROM_DATABASE=Wildcat Point-LP SATA Controller [AHCI Mode]
@@ -69870,25 +72648,25 @@ pci:v00008086d0000A000*
  ID_MODEL_FROM_DATABASE=Atom Processor D4xx/D5xx/N4xx/N5xx DMI Bridge
 
 pci:v00008086d0000A000sv00001458sd00005000*
- ID_MODEL_FROM_DATABASE=GA-D525TUD
+ ID_MODEL_FROM_DATABASE=Atom Processor D4xx/D5xx/N4xx/N5xx DMI Bridge (GA-D525TUD)
 
 pci:v00008086d0000A000sv00008086sd00004F4D*
- ID_MODEL_FROM_DATABASE=DeskTop Board D510MO
+ ID_MODEL_FROM_DATABASE=Atom Processor D4xx/D5xx/N4xx/N5xx DMI Bridge (DeskTop Board D510MO)
 
 pci:v00008086d0000A000sv00008086sd0000544B*
- ID_MODEL_FROM_DATABASE=Desktop Board D425KT
+ ID_MODEL_FROM_DATABASE=Atom Processor D4xx/D5xx/N4xx/N5xx DMI Bridge (Desktop Board D425KT)
 
 pci:v00008086d0000A001*
  ID_MODEL_FROM_DATABASE=Atom Processor D4xx/D5xx/N4xx/N5xx Integrated Graphics Controller
 
 pci:v00008086d0000A001sv00001458sd0000D000*
- ID_MODEL_FROM_DATABASE=GA-D525TUD
+ ID_MODEL_FROM_DATABASE=Atom Processor D4xx/D5xx/N4xx/N5xx Integrated Graphics Controller (GA-D525TUD)
 
 pci:v00008086d0000A001sv00008086sd00004F4D*
- ID_MODEL_FROM_DATABASE=DeskTop Board D510MO
+ ID_MODEL_FROM_DATABASE=Atom Processor D4xx/D5xx/N4xx/N5xx Integrated Graphics Controller (DeskTop Board D510MO)
 
 pci:v00008086d0000A001sv00008086sd0000544B*
- ID_MODEL_FROM_DATABASE=Desktop Board D425KT
+ ID_MODEL_FROM_DATABASE=Atom Processor D4xx/D5xx/N4xx/N5xx Integrated Graphics Controller (Desktop Board D425KT)
 
 pci:v00008086d0000A002*
  ID_MODEL_FROM_DATABASE=Atom Processor D4xx/D5xx/N4xx/N5xx Integrated Graphics Controller
@@ -69900,19 +72678,19 @@ pci:v00008086d0000A010*
  ID_MODEL_FROM_DATABASE=Atom Processor D4xx/D5xx/N4xx/N5xx DMI Bridge
 
 pci:v00008086d0000A010sv0000144Dsd0000C072*
- ID_MODEL_FROM_DATABASE=Notebook N150P
+ ID_MODEL_FROM_DATABASE=Atom Processor D4xx/D5xx/N4xx/N5xx DMI Bridge (Notebook N150P)
 
 pci:v00008086d0000A011*
  ID_MODEL_FROM_DATABASE=Atom Processor D4xx/D5xx/N4xx/N5xx Integrated Graphics Controller
 
 pci:v00008086d0000A011sv0000144Dsd0000C072*
- ID_MODEL_FROM_DATABASE=Notebook N150P
+ ID_MODEL_FROM_DATABASE=Atom Processor D4xx/D5xx/N4xx/N5xx Integrated Graphics Controller (Notebook N150P)
 
 pci:v00008086d0000A012*
  ID_MODEL_FROM_DATABASE=Atom Processor D4xx/D5xx/N4xx/N5xx Integrated Graphics Controller
 
 pci:v00008086d0000A012sv0000144Dsd0000C072*
- ID_MODEL_FROM_DATABASE=Notebook N150P
+ ID_MODEL_FROM_DATABASE=Atom Processor D4xx/D5xx/N4xx/N5xx Integrated Graphics Controller (Notebook N150P)
 
 pci:v00008086d0000A013*
  ID_MODEL_FROM_DATABASE=Atom Processor D4xx/D5xx/N4xx/N5xx CHAPS counter
@@ -69933,22 +72711,22 @@ pci:v00008086d0000B555*
  ID_MODEL_FROM_DATABASE=21555 Non transparent PCI-to-PCI Bridge
 
 pci:v00008086d0000B555sv000012C7sd00005005*
- ID_MODEL_FROM_DATABASE=SS7HD PCI Adaptor Card
+ ID_MODEL_FROM_DATABASE=21555 Non transparent PCI-to-PCI Bridge (SS7HD PCI Adaptor Card)
 
 pci:v00008086d0000B555sv000012C7sd00005006*
- ID_MODEL_FROM_DATABASE=SS7HDC cPCI Adaptor Card
+ ID_MODEL_FROM_DATABASE=21555 Non transparent PCI-to-PCI Bridge (SS7HDC cPCI Adaptor Card)
 
 pci:v00008086d0000B555sv000012D9sd0000000A*
- ID_MODEL_FROM_DATABASE=PCI VoIP Gateway
+ ID_MODEL_FROM_DATABASE=21555 Non transparent PCI-to-PCI Bridge (PCI VoIP Gateway)
 
 pci:v00008086d0000B555sv00004C53sd00001050*
- ID_MODEL_FROM_DATABASE=CT7 mainboard
+ ID_MODEL_FROM_DATABASE=21555 Non transparent PCI-to-PCI Bridge (CT7 mainboard)
 
 pci:v00008086d0000B555sv00004C53sd00001051*
- ID_MODEL_FROM_DATABASE=CE7 mainboard
+ ID_MODEL_FROM_DATABASE=21555 Non transparent PCI-to-PCI Bridge (CE7 mainboard)
 
 pci:v00008086d0000B555sv0000E4BFsd00001000*
- ID_MODEL_FROM_DATABASE=CC8-1-BLUES
+ ID_MODEL_FROM_DATABASE=21555 Non transparent PCI-to-PCI Bridge (CC8-1-BLUES)
 
 pci:v00008086d0000D130*
  ID_MODEL_FROM_DATABASE=Core Processor DMI
@@ -69957,13 +72735,16 @@ pci:v00008086d0000D131*
  ID_MODEL_FROM_DATABASE=Core Processor DMI
 
 pci:v00008086d0000D131sv00001028sd000002DA*
- ID_MODEL_FROM_DATABASE=OptiPlex 980
+ ID_MODEL_FROM_DATABASE=Core Processor DMI (OptiPlex 980)
+
+pci:v00008086d0000D131sv000015D9sd0000060D*
+ ID_MODEL_FROM_DATABASE=Core Processor DMI (C7SIM-Q Motherboard)
 
 pci:v00008086d0000D132*
  ID_MODEL_FROM_DATABASE=Core Processor DMI
 
 pci:v00008086d0000D132sv00001028sd0000040B*
- ID_MODEL_FROM_DATABASE=Latitude E6510
+ ID_MODEL_FROM_DATABASE=Core Processor DMI (Latitude E6510)
 
 pci:v00008086d0000D133*
  ID_MODEL_FROM_DATABASE=Core Processor DMI
@@ -69984,10 +72765,13 @@ pci:v00008086d0000D138*
  ID_MODEL_FROM_DATABASE=Core Processor PCI Express Root Port 1
 
 pci:v00008086d0000D138sv00001028sd000002DA*
- ID_MODEL_FROM_DATABASE=OptiPlex 980
+ ID_MODEL_FROM_DATABASE=Core Processor PCI Express Root Port 1 (OptiPlex 980)
 
 pci:v00008086d0000D138sv00001028sd0000040B*
- ID_MODEL_FROM_DATABASE=Latitude E6510
+ ID_MODEL_FROM_DATABASE=Core Processor PCI Express Root Port 1 (Latitude E6510)
+
+pci:v00008086d0000D138sv000015D9sd0000060D*
+ ID_MODEL_FROM_DATABASE=Core Processor PCI Express Root Port 1 (C7SIM-Q Motherboard)
 
 pci:v00008086d0000D139*
  ID_MODEL_FROM_DATABASE=Core Processor PCI Express Root Port 2
@@ -70098,7 +72882,7 @@ pci:v00009004d00005078*
  ID_MODEL_FROM_DATABASE=AIC-7850
 
 pci:v00009004d00005078sv00009004sd00007850*
- ID_MODEL_FROM_DATABASE=AHA-2904/Integrated AIC-7850
+ ID_MODEL_FROM_DATABASE=AIC-7850 (AHA-2904/Integrated AIC-7850)
 
 pci:v00009004d00005175*
  ID_MODEL_FROM_DATABASE=AIC-755x
@@ -70134,10 +72918,10 @@ pci:v00009004d00005647*
  ID_MODEL_FROM_DATABASE=ANA-7711 TCP Offload Engine
 
 pci:v00009004d00005647sv00009004sd00007710*
- ID_MODEL_FROM_DATABASE=ANA-7711F TCP Offload Engine - Optical
+ ID_MODEL_FROM_DATABASE=ANA-7711 TCP Offload Engine (ANA-7711F TCP Offload Engine - Optical)
 
 pci:v00009004d00005647sv00009004sd00007711*
- ID_MODEL_FROM_DATABASE=ANA-7711LP TCP Offload Engine - Copper
+ ID_MODEL_FROM_DATABASE=ANA-7711 TCP Offload Engine (ANA-7711LP TCP Offload Engine - Copper)
 
 pci:v00009004d00005675*
  ID_MODEL_FROM_DATABASE=AIC-755x
@@ -70167,7 +72951,7 @@ pci:v00009004d00006075*
  ID_MODEL_FROM_DATABASE=AIC-1480 / APA-1480
 
 pci:v00009004d00006075sv00009004sd00007560*
- ID_MODEL_FROM_DATABASE=AIC-1480 / APA-1480 Cardbus
+ ID_MODEL_FROM_DATABASE=AIC-1480 / APA-1480 (Cardbus)
 
 pci:v00009004d00006078*
  ID_MODEL_FROM_DATABASE=AIC-7860
@@ -70176,7 +72960,7 @@ pci:v00009004d00006178*
  ID_MODEL_FROM_DATABASE=AIC-7861
 
 pci:v00009004d00006178sv00009004sd00007861*
- ID_MODEL_FROM_DATABASE=AHA-2940AU Single
+ ID_MODEL_FROM_DATABASE=AIC-7861 (AHA-2940AU Single)
 
 pci:v00009004d00006278*
  ID_MODEL_FROM_DATABASE=AIC-7860
@@ -70200,46 +72984,46 @@ pci:v00009004d00006915*
  ID_MODEL_FROM_DATABASE=ANA620xx/ANA69011A
 
 pci:v00009004d00006915sv00009004sd00000008*
- ID_MODEL_FROM_DATABASE=ANA69011A/TX 10/100
+ ID_MODEL_FROM_DATABASE=ANA620xx/ANA69011A (ANA69011A/TX 10/100)
 
 pci:v00009004d00006915sv00009004sd00000009*
- ID_MODEL_FROM_DATABASE=ANA69011A/TX 10/100
+ ID_MODEL_FROM_DATABASE=ANA620xx/ANA69011A (ANA69011A/TX 10/100)
 
 pci:v00009004d00006915sv00009004sd00000010*
- ID_MODEL_FROM_DATABASE=ANA62022 2-port 10/100
+ ID_MODEL_FROM_DATABASE=ANA620xx/ANA69011A (ANA62022 2-port 10/100)
 
 pci:v00009004d00006915sv00009004sd00000018*
- ID_MODEL_FROM_DATABASE=ANA62044 4-port 10/100
+ ID_MODEL_FROM_DATABASE=ANA620xx/ANA69011A (ANA62044 4-port 10/100)
 
 pci:v00009004d00006915sv00009004sd00000019*
- ID_MODEL_FROM_DATABASE=ANA62044 4-port 10/100
+ ID_MODEL_FROM_DATABASE=ANA620xx/ANA69011A (ANA62044 4-port 10/100)
 
 pci:v00009004d00006915sv00009004sd00000020*
- ID_MODEL_FROM_DATABASE=ANA62022 2-port 10/100
+ ID_MODEL_FROM_DATABASE=ANA620xx/ANA69011A (ANA62022 2-port 10/100)
 
 pci:v00009004d00006915sv00009004sd00000028*
- ID_MODEL_FROM_DATABASE=ANA69011A/TX 10/100
+ ID_MODEL_FROM_DATABASE=ANA620xx/ANA69011A (ANA69011A/TX 10/100)
 
 pci:v00009004d00006915sv00009004sd00008008*
- ID_MODEL_FROM_DATABASE=ANA69011A/TX 64 bit 10/100
+ ID_MODEL_FROM_DATABASE=ANA620xx/ANA69011A (ANA69011A/TX 64 bit 10/100)
 
 pci:v00009004d00006915sv00009004sd00008009*
- ID_MODEL_FROM_DATABASE=ANA69011A/TX 64 bit 10/100
+ ID_MODEL_FROM_DATABASE=ANA620xx/ANA69011A (ANA69011A/TX 64 bit 10/100)
 
 pci:v00009004d00006915sv00009004sd00008010*
- ID_MODEL_FROM_DATABASE=ANA62022 2-port 64 bit 10/100
+ ID_MODEL_FROM_DATABASE=ANA620xx/ANA69011A (ANA62022 2-port 64 bit 10/100)
 
 pci:v00009004d00006915sv00009004sd00008018*
- ID_MODEL_FROM_DATABASE=ANA62044 4-port 64 bit 10/100
+ ID_MODEL_FROM_DATABASE=ANA620xx/ANA69011A (ANA62044 4-port 64 bit 10/100)
 
 pci:v00009004d00006915sv00009004sd00008019*
- ID_MODEL_FROM_DATABASE=ANA62044 4-port 64 bit 10/100
+ ID_MODEL_FROM_DATABASE=ANA620xx/ANA69011A (ANA62044 4-port 64 bit 10/100)
 
 pci:v00009004d00006915sv00009004sd00008020*
- ID_MODEL_FROM_DATABASE=ANA62022 2-port 64 bit 10/100
+ ID_MODEL_FROM_DATABASE=ANA620xx/ANA69011A (ANA62022 2-port 64 bit 10/100)
 
 pci:v00009004d00006915sv00009004sd00008028*
- ID_MODEL_FROM_DATABASE=ANA69011A/TX 64 bit 10/100
+ ID_MODEL_FROM_DATABASE=ANA620xx/ANA69011A (ANA69011A/TX 64 bit 10/100)
 
 pci:v00009004d00007078*
  ID_MODEL_FROM_DATABASE=AHA-294x / AIC-7870
@@ -70278,7 +73062,7 @@ pci:v00009004d00007815*
  ID_MODEL_FROM_DATABASE=AIC-7815 RAID+Memory Controller IC
 
 pci:v00009004d00007815sv00009004sd00007815*
- ID_MODEL_FROM_DATABASE=ARO-1130U2 RAID Controller
+ ID_MODEL_FROM_DATABASE=AIC-7815 RAID+Memory Controller IC (ARO-1130U2 RAID Controller)
 
 pci:v00009004d00007815sv00009004sd00007840*
  ID_MODEL_FROM_DATABASE=AIC-7815 RAID+Memory Controller IC
@@ -70329,25 +73113,25 @@ pci:v00009004d00007895*
  ID_MODEL_FROM_DATABASE=AHA-2940U/UW / AHA-39xx / AIC-7895
 
 pci:v00009004d00007895sv00009004sd00007890*
- ID_MODEL_FROM_DATABASE=AHA-2940U/2940UW Dual AHA-394xAU/AUW/AUWD AIC-7895B
+ ID_MODEL_FROM_DATABASE=AHA-2940U/UW / AHA-39xx / AIC-7895 (AHA-2940U/2940UW Dual AHA-394xAU/AUW/AUWD AIC-7895B)
 
 pci:v00009004d00007895sv00009004sd00007891*
- ID_MODEL_FROM_DATABASE=AHA-2940U/2940UW Dual
+ ID_MODEL_FROM_DATABASE=AHA-2940U/UW / AHA-39xx / AIC-7895 (AHA-2940U/2940UW Dual)
 
 pci:v00009004d00007895sv00009004sd00007892*
- ID_MODEL_FROM_DATABASE=AHA-3940AU/AUW/AUWD/UWD
+ ID_MODEL_FROM_DATABASE=AHA-2940U/UW / AHA-39xx / AIC-7895 (AHA-3940AU/AUW/AUWD/UWD)
 
 pci:v00009004d00007895sv00009004sd00007894*
- ID_MODEL_FROM_DATABASE=AHA-3944AUWD
+ ID_MODEL_FROM_DATABASE=AHA-2940U/UW / AHA-39xx / AIC-7895 (AHA-3944AUWD)
 
 pci:v00009004d00007895sv00009004sd00007895*
- ID_MODEL_FROM_DATABASE=AHA-2940U/2940UW Dual AHA-394xAU/AUW/AUWD AIC-7895B
+ ID_MODEL_FROM_DATABASE=AHA-2940U/UW / AHA-39xx / AIC-7895 (AHA-2940U/2940UW Dual AHA-394xAU/AUW/AUWD AIC-7895B)
 
 pci:v00009004d00007895sv00009004sd00007896*
- ID_MODEL_FROM_DATABASE=AHA-2940U/2940UW Dual AHA-394xAU/AUW/AUWD AIC-7895B
+ ID_MODEL_FROM_DATABASE=AHA-2940U/UW / AHA-39xx / AIC-7895 (AHA-2940U/2940UW Dual AHA-394xAU/AUW/AUWD AIC-7895B)
 
 pci:v00009004d00007895sv00009004sd00007897*
- ID_MODEL_FROM_DATABASE=AHA-2940U/2940UW Dual AHA-394xAU/AUW/AUWD AIC-7895B
+ ID_MODEL_FROM_DATABASE=AHA-2940U/UW / AHA-39xx / AIC-7895 (AHA-2940U/2940UW Dual AHA-394xAU/AUW/AUWD AIC-7895B)
 
 pci:v00009004d00007896*
  ID_MODEL_FROM_DATABASE=AIC-789x
@@ -70359,13 +73143,13 @@ pci:v00009004d00008078*
  ID_MODEL_FROM_DATABASE=AIC-7880U
 
 pci:v00009004d00008078sv00009004sd00007880*
- ID_MODEL_FROM_DATABASE=AIC-7880P Ultra/Ultra Wide SCSI Chipset
+ ID_MODEL_FROM_DATABASE=AIC-7880U (AIC-7880P Ultra/Ultra Wide SCSI Chipset)
 
 pci:v00009004d00008178*
  ID_MODEL_FROM_DATABASE=AHA-2940U/UW/D / AIC-7881U
 
 pci:v00009004d00008178sv00009004sd00007881*
- ID_MODEL_FROM_DATABASE=AHA-2940UW SCSI Host Adapter
+ ID_MODEL_FROM_DATABASE=AHA-2940U/UW/D / AIC-7881U (AHA-2940UW SCSI Host Adapter)
 
 pci:v00009004d00008278*
  ID_MODEL_FROM_DATABASE=AHA-3940U/UW/UWD / AIC-7882U
@@ -70386,13 +73170,13 @@ pci:v00009004d00008778*
  ID_MODEL_FROM_DATABASE=AHA-2940UW Pro / AIC-788x
 
 pci:v00009004d00008778sv00009004sd00007887*
- ID_MODEL_FROM_DATABASE=2940UW Pro Ultra-Wide SCSI Controller
+ ID_MODEL_FROM_DATABASE=AHA-2940UW Pro / AIC-788x (2940UW Pro Ultra-Wide SCSI Controller)
 
 pci:v00009004d00008878*
  ID_MODEL_FROM_DATABASE=AHA-2930UW / AIC-7888
 
 pci:v00009004d00008878sv00009004sd00007888*
- ID_MODEL_FROM_DATABASE=AHA-2930UW SCSI Controller
+ ID_MODEL_FROM_DATABASE=AHA-2930UW / AIC-7888 (AHA-2930UW SCSI Controller)
 
 pci:v00009004d00008B78*
  ID_MODEL_FROM_DATABASE=ABA-1030
@@ -70407,19 +73191,19 @@ pci:v00009005d00000010*
  ID_MODEL_FROM_DATABASE=AHA-2940U2/U2W
 
 pci:v00009005d00000010sv00009005sd00002180*
- ID_MODEL_FROM_DATABASE=AHA-2940U2 SCSI Controller
+ ID_MODEL_FROM_DATABASE=AHA-2940U2/U2W (AHA-2940U2 SCSI Controller)
 
 pci:v00009005d00000010sv00009005sd00008100*
- ID_MODEL_FROM_DATABASE=AHA-2940U2B SCSI Controller
+ ID_MODEL_FROM_DATABASE=AHA-2940U2/U2W (AHA-2940U2B SCSI Controller)
 
 pci:v00009005d00000010sv00009005sd0000A100*
- ID_MODEL_FROM_DATABASE=AHA-2940U2B SCSI Controller
+ ID_MODEL_FROM_DATABASE=AHA-2940U2/U2W (AHA-2940U2B SCSI Controller)
 
 pci:v00009005d00000010sv00009005sd0000A180*
- ID_MODEL_FROM_DATABASE=AHA-2940U2W SCSI Controller
+ ID_MODEL_FROM_DATABASE=AHA-2940U2/U2W (AHA-2940U2W SCSI Controller)
 
 pci:v00009005d00000010sv00009005sd0000E100*
- ID_MODEL_FROM_DATABASE=AHA-2950U2B SCSI Controller
+ ID_MODEL_FROM_DATABASE=AHA-2940U2/U2W (AHA-2950U2B SCSI Controller)
 
 pci:v00009005d00000011*
  ID_MODEL_FROM_DATABASE=AHA-2930U2
@@ -70428,19 +73212,19 @@ pci:v00009005d00000013*
  ID_MODEL_FROM_DATABASE=78902
 
 pci:v00009005d00000013sv00009005sd00000003*
- ID_MODEL_FROM_DATABASE=AAA-131U2 Array1000 1 Channel RAID Controller
+ ID_MODEL_FROM_DATABASE=78902 (AAA-131U2 Array1000 1 Channel RAID Controller)
 
 pci:v00009005d00000013sv00009005sd0000000F*
- ID_MODEL_FROM_DATABASE=AIC7890_ARO
+ ID_MODEL_FROM_DATABASE=78902 (AIC7890_ARO)
 
 pci:v00009005d0000001F*
  ID_MODEL_FROM_DATABASE=AHA-2940U2/U2W / 7890/7891
 
 pci:v00009005d0000001Fsv00009005sd0000000F*
- ID_MODEL_FROM_DATABASE=2940U2W SCSI Controller
+ ID_MODEL_FROM_DATABASE=AHA-2940U2/U2W / 7890/7891 (2940U2W SCSI Controller)
 
 pci:v00009005d0000001Fsv00009005sd0000A180*
- ID_MODEL_FROM_DATABASE=2940U2W SCSI Controller
+ ID_MODEL_FROM_DATABASE=AHA-2940U2/U2W / 7890/7891 (2940U2W SCSI Controller)
 
 pci:v00009005d00000020*
  ID_MODEL_FROM_DATABASE=AIC-7890
@@ -70458,10 +73242,10 @@ pci:v00009005d00000050*
  ID_MODEL_FROM_DATABASE=AHA-3940U2x/395U2x
 
 pci:v00009005d00000050sv00009005sd0000F500*
- ID_MODEL_FROM_DATABASE=AHA-3950U2B
+ ID_MODEL_FROM_DATABASE=AHA-3940U2x/395U2x (AHA-3950U2B)
 
 pci:v00009005d00000050sv00009005sd0000FFFF*
- ID_MODEL_FROM_DATABASE=AHA-3950U2B
+ ID_MODEL_FROM_DATABASE=AHA-3940U2x/395U2x (AHA-3950U2B)
 
 pci:v00009005d00000051*
  ID_MODEL_FROM_DATABASE=AHA-3950U2D
@@ -70473,7 +73257,7 @@ pci:v00009005d00000053*
  ID_MODEL_FROM_DATABASE=AIC-7896 SCSI Controller
 
 pci:v00009005d00000053sv00009005sd0000FFFF*
- ID_MODEL_FROM_DATABASE=AIC-7896 SCSI Controller mainboard implementation
+ ID_MODEL_FROM_DATABASE=AIC-7896 SCSI Controller (mainboard implementation)
 
 pci:v00009005d0000005F*
  ID_MODEL_FROM_DATABASE=AIC-7896U2/7897U2
@@ -70482,25 +73266,25 @@ pci:v00009005d00000080*
  ID_MODEL_FROM_DATABASE=AIC-7892A U160/m
 
 pci:v00009005d00000080sv00000E11sd0000E2A0*
- ID_MODEL_FROM_DATABASE=Compaq 64-Bit/66MHz Wide Ultra3 SCSI Adapter
+ ID_MODEL_FROM_DATABASE=AIC-7892A U160/m (Compaq 64-Bit/66MHz Wide Ultra3 SCSI Adapter)
 
 pci:v00009005d00000080sv00009005sd00006220*
- ID_MODEL_FROM_DATABASE=AHA-29160C
+ ID_MODEL_FROM_DATABASE=AIC-7892A U160/m (AHA-29160C)
 
 pci:v00009005d00000080sv00009005sd000062A0*
- ID_MODEL_FROM_DATABASE=29160N Ultra160 SCSI Controller
+ ID_MODEL_FROM_DATABASE=AIC-7892A U160/m (29160N Ultra160 SCSI Controller)
 
 pci:v00009005d00000080sv00009005sd0000E220*
- ID_MODEL_FROM_DATABASE=29160LP Low Profile Ultra160 SCSI Controller
+ ID_MODEL_FROM_DATABASE=AIC-7892A U160/m (29160LP Low Profile Ultra160 SCSI Controller)
 
 pci:v00009005d00000080sv00009005sd0000E2A0*
- ID_MODEL_FROM_DATABASE=29160 Ultra160 SCSI Controller
+ ID_MODEL_FROM_DATABASE=AIC-7892A U160/m (29160 Ultra160 SCSI Controller)
 
 pci:v00009005d00000081*
  ID_MODEL_FROM_DATABASE=AIC-7892B U160/m
 
 pci:v00009005d00000081sv00009005sd000062A1*
- ID_MODEL_FROM_DATABASE=19160 Ultra160 SCSI Controller
+ ID_MODEL_FROM_DATABASE=AIC-7892B U160/m (19160 Ultra160 SCSI Controller)
 
 pci:v00009005d00000083*
  ID_MODEL_FROM_DATABASE=AIC-7892D U160/m
@@ -70509,10 +73293,10 @@ pci:v00009005d0000008F*
  ID_MODEL_FROM_DATABASE=AIC-7892P U160/m
 
 pci:v00009005d0000008Fsv00001179sd00000001*
- ID_MODEL_FROM_DATABASE=Magnia Z310
+ ID_MODEL_FROM_DATABASE=AIC-7892P U160/m (Magnia Z310)
 
 pci:v00009005d0000008Fsv000015D9sd00009005*
- ID_MODEL_FROM_DATABASE=Onboard SCSI Host Adapter
+ ID_MODEL_FROM_DATABASE=AIC-7892P U160/m (Onboard SCSI Host Adapter)
 
 pci:v00009005d00000092*
  ID_MODEL_FROM_DATABASE=AVC-2010 [VideoH!]
@@ -70524,10 +73308,10 @@ pci:v00009005d000000C0*
  ID_MODEL_FROM_DATABASE=AHA-3960D / AIC-7899A U160/m
 
 pci:v00009005d000000C0sv00000E11sd0000F620*
- ID_MODEL_FROM_DATABASE=Compaq 64-Bit/66MHz Dual Channel Wide Ultra3 SCSI Adapter
+ ID_MODEL_FROM_DATABASE=AHA-3960D / AIC-7899A U160/m (Compaq 64-Bit/66MHz Dual Channel Wide Ultra3 SCSI Adapter)
 
 pci:v00009005d000000C0sv00009005sd0000F620*
- ID_MODEL_FROM_DATABASE=AHA-3960D U160/m
+ ID_MODEL_FROM_DATABASE=AHA-3960D / AIC-7899A U160/m (AHA-3960D U160/m)
 
 pci:v00009005d000000C1*
  ID_MODEL_FROM_DATABASE=AIC-7899B U160/m
@@ -70539,28 +73323,28 @@ pci:v00009005d000000C5*
  ID_MODEL_FROM_DATABASE=RAID subsystem HBA
 
 pci:v00009005d000000C5sv00001028sd000000C5*
- ID_MODEL_FROM_DATABASE=PowerEdge 2400,2500,2550,4400
+ ID_MODEL_FROM_DATABASE=RAID subsystem HBA (PowerEdge 2400,2500,2550,4400)
 
 pci:v00009005d000000CF*
  ID_MODEL_FROM_DATABASE=AIC-7899P U160/m
 
 pci:v00009005d000000CFsv00001028sd000000CE*
- ID_MODEL_FROM_DATABASE=PowerEdge 1400
+ ID_MODEL_FROM_DATABASE=AIC-7899P U160/m (PowerEdge 1400)
 
 pci:v00009005d000000CFsv00001028sd000000D1*
- ID_MODEL_FROM_DATABASE=PowerEdge 2550
+ ID_MODEL_FROM_DATABASE=AIC-7899P U160/m (PowerEdge 2550)
 
 pci:v00009005d000000CFsv00001028sd000000D9*
- ID_MODEL_FROM_DATABASE=PowerEdge 2500
+ ID_MODEL_FROM_DATABASE=AIC-7899P U160/m (PowerEdge 2500)
 
 pci:v00009005d000000CFsv000010F1sd00002462*
- ID_MODEL_FROM_DATABASE=Thunder K7 S2462
+ ID_MODEL_FROM_DATABASE=AIC-7899P U160/m (Thunder K7 S2462)
 
 pci:v00009005d000000CFsv000015D9sd00009005*
- ID_MODEL_FROM_DATABASE=Onboard SCSI Host Adapter
+ ID_MODEL_FROM_DATABASE=AIC-7899P U160/m (Onboard SCSI Host Adapter)
 
 pci:v00009005d000000CFsv00008086sd00003411*
- ID_MODEL_FROM_DATABASE=SDS2 Mainboard
+ ID_MODEL_FROM_DATABASE=AIC-7899P U160/m (SDS2 Mainboard)
 
 pci:v00009005d00000241*
  ID_MODEL_FROM_DATABASE=Serial ATA II RAID 1420SA
@@ -70578,13 +73362,13 @@ pci:v00009005d00000250*
  ID_MODEL_FROM_DATABASE=ServeRAID Controller
 
 pci:v00009005d00000250sv00001014sd00000279*
- ID_MODEL_FROM_DATABASE=ServeRAID 6M
+ ID_MODEL_FROM_DATABASE=ServeRAID Controller (ServeRAID 6M)
 
 pci:v00009005d00000250sv00001014sd0000028C*
- ID_MODEL_FROM_DATABASE=ServeRAID 6i/6i+
+ ID_MODEL_FROM_DATABASE=ServeRAID Controller (ServeRAID 6i/6i+)
 
 pci:v00009005d00000250sv00001014sd0000028E*
- ID_MODEL_FROM_DATABASE=ServeRAID 7k
+ ID_MODEL_FROM_DATABASE=ServeRAID Controller (ServeRAID 7k)
 
 pci:v00009005d00000279*
  ID_MODEL_FROM_DATABASE=ServeRAID 6M
@@ -70593,415 +73377,415 @@ pci:v00009005d00000283*
  ID_MODEL_FROM_DATABASE=AAC-RAID
 
 pci:v00009005d00000283sv00009005sd00000283*
- ID_MODEL_FROM_DATABASE=Catapult
+ ID_MODEL_FROM_DATABASE=AAC-RAID (Catapult)
 
 pci:v00009005d00000284*
  ID_MODEL_FROM_DATABASE=AAC-RAID
 
 pci:v00009005d00000284sv00009005sd00000284*
- ID_MODEL_FROM_DATABASE=Tomcat
+ ID_MODEL_FROM_DATABASE=AAC-RAID (Tomcat)
 
 pci:v00009005d00000285*
  ID_MODEL_FROM_DATABASE=AAC-RAID
 
 pci:v00009005d00000285sv00000E11sd00000295*
- ID_MODEL_FROM_DATABASE=SATA 6Ch (Bearcat)
+ ID_MODEL_FROM_DATABASE=AAC-RAID (SATA 6Ch (Bearcat))
 
 pci:v00009005d00000285sv00001014sd000002F2*
- ID_MODEL_FROM_DATABASE=ServeRAID 8i
+ ID_MODEL_FROM_DATABASE=AAC-RAID (ServeRAID 8i)
 
 pci:v00009005d00000285sv00001028sd00000287*
- ID_MODEL_FROM_DATABASE=PowerEdge Expandable RAID Controller 320/DC
+ ID_MODEL_FROM_DATABASE=AAC-RAID (PowerEdge Expandable RAID Controller 320/DC)
 
 pci:v00009005d00000285sv00001028sd00000291*
- ID_MODEL_FROM_DATABASE=CERC SATA RAID 2 PCI SATA 6ch (DellCorsair)
+ ID_MODEL_FROM_DATABASE=AAC-RAID (CERC SATA RAID 2 PCI SATA 6ch (DellCorsair))
 
 pci:v00009005d00000285sv0000103Csd00003227*
- ID_MODEL_FROM_DATABASE=AAR-2610SA
+ ID_MODEL_FROM_DATABASE=AAC-RAID (AAR-2610SA)
 
 pci:v00009005d00000285sv0000108Esd00000286*
- ID_MODEL_FROM_DATABASE=Sun StorageTek SAS RAID HBA, Internal
+ ID_MODEL_FROM_DATABASE=AAC-RAID (Sun StorageTek SAS RAID HBA, Internal)
 
 pci:v00009005d00000285sv0000108Esd00000287*
- ID_MODEL_FROM_DATABASE=STK RAID EXT
+ ID_MODEL_FROM_DATABASE=AAC-RAID (STK RAID EXT)
 
 pci:v00009005d00000285sv0000108Esd00007AAC*
- ID_MODEL_FROM_DATABASE=STK RAID REM
+ ID_MODEL_FROM_DATABASE=AAC-RAID (STK RAID REM)
 
 pci:v00009005d00000285sv0000108Esd00007AAE*
- ID_MODEL_FROM_DATABASE=STK RAID EX
+ ID_MODEL_FROM_DATABASE=AAC-RAID (STK RAID EX)
 
 pci:v00009005d00000285sv000015D9sd000002B5*
- ID_MODEL_FROM_DATABASE=SMC AOC-USAS-S4i
+ ID_MODEL_FROM_DATABASE=AAC-RAID (SMC AOC-USAS-S4i)
 
 pci:v00009005d00000285sv000015D9sd000002B6*
- ID_MODEL_FROM_DATABASE=SMC AOC-USAS-S8i
+ ID_MODEL_FROM_DATABASE=AAC-RAID (SMC AOC-USAS-S8i)
 
 pci:v00009005d00000285sv000015D9sd000002C9*
- ID_MODEL_FROM_DATABASE=SMC AOC-USAS-S4iR
+ ID_MODEL_FROM_DATABASE=AAC-RAID (SMC AOC-USAS-S4iR)
 
 pci:v00009005d00000285sv000015D9sd000002CA*
- ID_MODEL_FROM_DATABASE=SMC AOC-USAS-S8iR
+ ID_MODEL_FROM_DATABASE=AAC-RAID (SMC AOC-USAS-S8iR)
 
 pci:v00009005d00000285sv000015D9sd000002D2*
- ID_MODEL_FROM_DATABASE=SMC AOC-USAS-S8i-LP
+ ID_MODEL_FROM_DATABASE=AAC-RAID (SMC AOC-USAS-S8i-LP)
 
 pci:v00009005d00000285sv000015D9sd000002D3*
- ID_MODEL_FROM_DATABASE=SMC AOC-USAS-S8iR-LP
+ ID_MODEL_FROM_DATABASE=AAC-RAID (SMC AOC-USAS-S8iR-LP)
 
 pci:v00009005d00000285sv000017AAsd00000286*
- ID_MODEL_FROM_DATABASE=Legend S220 (Legend Crusader)
+ ID_MODEL_FROM_DATABASE=AAC-RAID (Legend S220 (Legend Crusader))
 
 pci:v00009005d00000285sv000017AAsd00000287*
- ID_MODEL_FROM_DATABASE=Legend S230 (Legend Vulcan)
+ ID_MODEL_FROM_DATABASE=AAC-RAID (Legend S230 (Legend Vulcan))
 
 pci:v00009005d00000285sv00009005sd00000285*
- ID_MODEL_FROM_DATABASE=2200S (Vulcan)
+ ID_MODEL_FROM_DATABASE=AAC-RAID (2200S (Vulcan))
 
 pci:v00009005d00000285sv00009005sd00000286*
- ID_MODEL_FROM_DATABASE=2120S (Crusader)
+ ID_MODEL_FROM_DATABASE=AAC-RAID (2120S (Crusader))
 
 pci:v00009005d00000285sv00009005sd00000287*
- ID_MODEL_FROM_DATABASE=2200S (Vulcan-2m)
+ ID_MODEL_FROM_DATABASE=AAC-RAID (2200S (Vulcan-2m))
 
 pci:v00009005d00000285sv00009005sd00000288*
- ID_MODEL_FROM_DATABASE=3230S (Harrier)
+ ID_MODEL_FROM_DATABASE=AAC-RAID (3230S (Harrier))
 
 pci:v00009005d00000285sv00009005sd00000289*
- ID_MODEL_FROM_DATABASE=3240S (Tornado)
+ ID_MODEL_FROM_DATABASE=AAC-RAID (3240S (Tornado))
 
 pci:v00009005d00000285sv00009005sd0000028A*
- ID_MODEL_FROM_DATABASE=ASR-2020ZCR
+ ID_MODEL_FROM_DATABASE=AAC-RAID (ASR-2020ZCR)
 
 pci:v00009005d00000285sv00009005sd0000028B*
- ID_MODEL_FROM_DATABASE=ASR-2025ZCR (Terminator)
+ ID_MODEL_FROM_DATABASE=AAC-RAID (ASR-2025ZCR (Terminator))
 
 pci:v00009005d00000285sv00009005sd0000028E*
- ID_MODEL_FROM_DATABASE=ASR-2020SA (Skyhawk)
+ ID_MODEL_FROM_DATABASE=AAC-RAID (ASR-2020SA (Skyhawk))
 
 pci:v00009005d00000285sv00009005sd0000028F*
- ID_MODEL_FROM_DATABASE=ASR-2025SA
+ ID_MODEL_FROM_DATABASE=AAC-RAID (ASR-2025SA)
 
 pci:v00009005d00000285sv00009005sd00000290*
- ID_MODEL_FROM_DATABASE=AAR-2410SA PCI SATA 4ch (Jaguar II)
+ ID_MODEL_FROM_DATABASE=AAC-RAID (AAR-2410SA PCI SATA 4ch (Jaguar II))
 
 pci:v00009005d00000285sv00009005sd00000292*
- ID_MODEL_FROM_DATABASE=AAR-2810SA PCI SATA 8ch (Corsair-8)
+ ID_MODEL_FROM_DATABASE=AAC-RAID (AAR-2810SA PCI SATA 8ch (Corsair-8))
 
 pci:v00009005d00000285sv00009005sd00000293*
- ID_MODEL_FROM_DATABASE=AAR-21610SA PCI SATA 16ch (Corsair-16)
+ ID_MODEL_FROM_DATABASE=AAC-RAID (AAR-21610SA PCI SATA 16ch (Corsair-16))
 
 pci:v00009005d00000285sv00009005sd00000294*
- ID_MODEL_FROM_DATABASE=ESD SO-DIMM PCI-X SATA ZCR (Prowler)
+ ID_MODEL_FROM_DATABASE=AAC-RAID (ESD SO-DIMM PCI-X SATA ZCR (Prowler))
 
 pci:v00009005d00000285sv00009005sd00000296*
- ID_MODEL_FROM_DATABASE=ASR-2240S
+ ID_MODEL_FROM_DATABASE=AAC-RAID (ASR-2240S)
 
 pci:v00009005d00000285sv00009005sd00000297*
- ID_MODEL_FROM_DATABASE=ASR-4005SAS
+ ID_MODEL_FROM_DATABASE=AAC-RAID (ASR-4005SAS)
 
 pci:v00009005d00000285sv00009005sd00000298*
- ID_MODEL_FROM_DATABASE=ASR-4000
+ ID_MODEL_FROM_DATABASE=AAC-RAID (ASR-4000)
 
 pci:v00009005d00000285sv00009005sd00000299*
- ID_MODEL_FROM_DATABASE=ASR-4800SAS
+ ID_MODEL_FROM_DATABASE=AAC-RAID (ASR-4800SAS)
 
 pci:v00009005d00000285sv00009005sd0000029A*
- ID_MODEL_FROM_DATABASE=4805SAS
+ ID_MODEL_FROM_DATABASE=AAC-RAID (4805SAS)
 
 pci:v00009005d00000285sv00009005sd000002A4*
- ID_MODEL_FROM_DATABASE=ICP ICP9085LI
+ ID_MODEL_FROM_DATABASE=AAC-RAID (ICP ICP9085LI)
 
 pci:v00009005d00000285sv00009005sd000002A5*
- ID_MODEL_FROM_DATABASE=ICP ICP5085BR
+ ID_MODEL_FROM_DATABASE=AAC-RAID (ICP ICP5085BR)
 
 pci:v00009005d00000285sv00009005sd000002B5*
- ID_MODEL_FROM_DATABASE=ASR5800
+ ID_MODEL_FROM_DATABASE=AAC-RAID (ASR5800)
 
 pci:v00009005d00000285sv00009005sd000002B6*
- ID_MODEL_FROM_DATABASE=ASR5805
+ ID_MODEL_FROM_DATABASE=AAC-RAID (ASR5805)
 
 pci:v00009005d00000285sv00009005sd000002B7*
- ID_MODEL_FROM_DATABASE=ASR5808
+ ID_MODEL_FROM_DATABASE=AAC-RAID (ASR5808)
 
 pci:v00009005d00000285sv00009005sd000002B8*
- ID_MODEL_FROM_DATABASE=ICP5445SL
+ ID_MODEL_FROM_DATABASE=AAC-RAID (ICP5445SL)
 
 pci:v00009005d00000285sv00009005sd000002B9*
- ID_MODEL_FROM_DATABASE=ICP5085SL
+ ID_MODEL_FROM_DATABASE=AAC-RAID (ICP5085SL)
 
 pci:v00009005d00000285sv00009005sd000002BA*
- ID_MODEL_FROM_DATABASE=ICP5805SL
+ ID_MODEL_FROM_DATABASE=AAC-RAID (ICP5805SL)
 
 pci:v00009005d00000285sv00009005sd000002BB*
- ID_MODEL_FROM_DATABASE=3405
+ ID_MODEL_FROM_DATABASE=AAC-RAID (3405)
 
 pci:v00009005d00000285sv00009005sd000002BC*
- ID_MODEL_FROM_DATABASE=3805
+ ID_MODEL_FROM_DATABASE=AAC-RAID (3805)
 
 pci:v00009005d00000285sv00009005sd000002BD*
- ID_MODEL_FROM_DATABASE=31205
+ ID_MODEL_FROM_DATABASE=AAC-RAID (31205)
 
 pci:v00009005d00000285sv00009005sd000002BE*
- ID_MODEL_FROM_DATABASE=31605
+ ID_MODEL_FROM_DATABASE=AAC-RAID (31605)
 
 pci:v00009005d00000285sv00009005sd000002BF*
- ID_MODEL_FROM_DATABASE=ICP ICP5045BL
+ ID_MODEL_FROM_DATABASE=AAC-RAID (ICP ICP5045BL)
 
 pci:v00009005d00000285sv00009005sd000002C0*
- ID_MODEL_FROM_DATABASE=ICP ICP5085BL
+ ID_MODEL_FROM_DATABASE=AAC-RAID (ICP ICP5085BL)
 
 pci:v00009005d00000285sv00009005sd000002C1*
- ID_MODEL_FROM_DATABASE=ICP ICP5125BR
+ ID_MODEL_FROM_DATABASE=AAC-RAID (ICP ICP5125BR)
 
 pci:v00009005d00000285sv00009005sd000002C2*
- ID_MODEL_FROM_DATABASE=ICP ICP5165BR
+ ID_MODEL_FROM_DATABASE=AAC-RAID (ICP ICP5165BR)
 
 pci:v00009005d00000285sv00009005sd000002C3*
- ID_MODEL_FROM_DATABASE=51205
+ ID_MODEL_FROM_DATABASE=AAC-RAID (51205)
 
 pci:v00009005d00000285sv00009005sd000002C4*
- ID_MODEL_FROM_DATABASE=51605
+ ID_MODEL_FROM_DATABASE=AAC-RAID (51605)
 
 pci:v00009005d00000285sv00009005sd000002C5*
- ID_MODEL_FROM_DATABASE=ICP ICP5125SL
+ ID_MODEL_FROM_DATABASE=AAC-RAID (ICP ICP5125SL)
 
 pci:v00009005d00000285sv00009005sd000002C6*
- ID_MODEL_FROM_DATABASE=ICP ICP5165SL
+ ID_MODEL_FROM_DATABASE=AAC-RAID (ICP ICP5165SL)
 
 pci:v00009005d00000285sv00009005sd000002C7*
- ID_MODEL_FROM_DATABASE=3085
+ ID_MODEL_FROM_DATABASE=AAC-RAID (3085)
 
 pci:v00009005d00000285sv00009005sd000002C8*
- ID_MODEL_FROM_DATABASE=ICP5805BL
+ ID_MODEL_FROM_DATABASE=AAC-RAID (ICP5805BL)
 
 pci:v00009005d00000285sv00009005sd000002CE*
- ID_MODEL_FROM_DATABASE=51245
+ ID_MODEL_FROM_DATABASE=AAC-RAID (51245)
 
 pci:v00009005d00000285sv00009005sd000002CF*
- ID_MODEL_FROM_DATABASE=51645
+ ID_MODEL_FROM_DATABASE=AAC-RAID (51645)
 
 pci:v00009005d00000285sv00009005sd000002D0*
- ID_MODEL_FROM_DATABASE=52445
+ ID_MODEL_FROM_DATABASE=AAC-RAID (52445)
 
 pci:v00009005d00000285sv00009005sd000002D1*
- ID_MODEL_FROM_DATABASE=5405
+ ID_MODEL_FROM_DATABASE=AAC-RAID (5405)
 
 pci:v00009005d00000285sv00009005sd000002D4*
- ID_MODEL_FROM_DATABASE=ASR-2045
+ ID_MODEL_FROM_DATABASE=AAC-RAID (ASR-2045)
 
 pci:v00009005d00000285sv00009005sd000002D5*
- ID_MODEL_FROM_DATABASE=ASR-2405
+ ID_MODEL_FROM_DATABASE=AAC-RAID (ASR-2405)
 
 pci:v00009005d00000285sv00009005sd000002D6*
- ID_MODEL_FROM_DATABASE=ASR-2445
+ ID_MODEL_FROM_DATABASE=AAC-RAID (ASR-2445)
 
 pci:v00009005d00000285sv00009005sd000002D7*
- ID_MODEL_FROM_DATABASE=ASR-2805
+ ID_MODEL_FROM_DATABASE=AAC-RAID (ASR-2805)
 
 pci:v00009005d00000285sv00009005sd000002D8*
- ID_MODEL_FROM_DATABASE=5405G
+ ID_MODEL_FROM_DATABASE=AAC-RAID (5405G)
 
 pci:v00009005d00000285sv00009005sd000002D9*
- ID_MODEL_FROM_DATABASE=5445G
+ ID_MODEL_FROM_DATABASE=AAC-RAID (5445G)
 
 pci:v00009005d00000285sv00009005sd000002DA*
- ID_MODEL_FROM_DATABASE=5805G
+ ID_MODEL_FROM_DATABASE=AAC-RAID (5805G)
 
 pci:v00009005d00000285sv00009005sd000002DB*
- ID_MODEL_FROM_DATABASE=5085G
+ ID_MODEL_FROM_DATABASE=AAC-RAID (5085G)
 
 pci:v00009005d00000285sv00009005sd000002DC*
- ID_MODEL_FROM_DATABASE=51245G
+ ID_MODEL_FROM_DATABASE=AAC-RAID (51245G)
 
 pci:v00009005d00000285sv00009005sd000002DD*
- ID_MODEL_FROM_DATABASE=51645G
+ ID_MODEL_FROM_DATABASE=AAC-RAID (51645G)
 
 pci:v00009005d00000285sv00009005sd000002DE*
- ID_MODEL_FROM_DATABASE=52445G
+ ID_MODEL_FROM_DATABASE=AAC-RAID (52445G)
 
 pci:v00009005d00000285sv00009005sd000002DF*
- ID_MODEL_FROM_DATABASE=ASR-2045G
+ ID_MODEL_FROM_DATABASE=AAC-RAID (ASR-2045G)
 
 pci:v00009005d00000285sv00009005sd000002E0*
- ID_MODEL_FROM_DATABASE=ASR-2405G
+ ID_MODEL_FROM_DATABASE=AAC-RAID (ASR-2405G)
 
 pci:v00009005d00000285sv00009005sd000002E1*
- ID_MODEL_FROM_DATABASE=ASR-2445G
+ ID_MODEL_FROM_DATABASE=AAC-RAID (ASR-2445G)
 
 pci:v00009005d00000285sv00009005sd000002E2*
- ID_MODEL_FROM_DATABASE=ASR-2805G
+ ID_MODEL_FROM_DATABASE=AAC-RAID (ASR-2805G)
 
 pci:v00009005d00000286*
  ID_MODEL_FROM_DATABASE=AAC-RAID (Rocket)
 
 pci:v00009005d00000286sv00001014sd0000034D*
- ID_MODEL_FROM_DATABASE=8s
+ ID_MODEL_FROM_DATABASE=AAC-RAID (Rocket) (8s)
 
 pci:v00009005d00000286sv00001014sd00009540*
- ID_MODEL_FROM_DATABASE=ServeRAID 8k/8k-l4
+ ID_MODEL_FROM_DATABASE=AAC-RAID (Rocket) (ServeRAID 8k/8k-l4)
 
 pci:v00009005d00000286sv00001014sd00009580*
- ID_MODEL_FROM_DATABASE=ServeRAID 8k/8k-l8
+ ID_MODEL_FROM_DATABASE=AAC-RAID (Rocket) (ServeRAID 8k/8k-l8)
 
 pci:v00009005d00000286sv00009005sd0000028C*
- ID_MODEL_FROM_DATABASE=ASR-2230S + ASR-2230SLP PCI-X (Lancer)
+ ID_MODEL_FROM_DATABASE=AAC-RAID (Rocket) (ASR-2230S + ASR-2230SLP PCI-X (Lancer))
 
 pci:v00009005d00000286sv00009005sd0000028D*
- ID_MODEL_FROM_DATABASE=ASR-2130S
+ ID_MODEL_FROM_DATABASE=AAC-RAID (Rocket) (ASR-2130S)
 
 pci:v00009005d00000286sv00009005sd0000029B*
- ID_MODEL_FROM_DATABASE=ASR-2820SA
+ ID_MODEL_FROM_DATABASE=AAC-RAID (Rocket) (ASR-2820SA)
 
 pci:v00009005d00000286sv00009005sd0000029C*
- ID_MODEL_FROM_DATABASE=ASR-2620SA
+ ID_MODEL_FROM_DATABASE=AAC-RAID (Rocket) (ASR-2620SA)
 
 pci:v00009005d00000286sv00009005sd0000029D*
- ID_MODEL_FROM_DATABASE=ASR-2420SA
+ ID_MODEL_FROM_DATABASE=AAC-RAID (Rocket) (ASR-2420SA)
 
 pci:v00009005d00000286sv00009005sd0000029E*
- ID_MODEL_FROM_DATABASE=ICP ICP9024R0
+ ID_MODEL_FROM_DATABASE=AAC-RAID (Rocket) (ICP ICP9024R0)
 
 pci:v00009005d00000286sv00009005sd0000029F*
- ID_MODEL_FROM_DATABASE=ICP ICP9014R0
+ ID_MODEL_FROM_DATABASE=AAC-RAID (Rocket) (ICP ICP9014R0)
 
 pci:v00009005d00000286sv00009005sd000002A0*
- ID_MODEL_FROM_DATABASE=ICP ICP9047MA
+ ID_MODEL_FROM_DATABASE=AAC-RAID (Rocket) (ICP ICP9047MA)
 
 pci:v00009005d00000286sv00009005sd000002A1*
- ID_MODEL_FROM_DATABASE=ICP ICP9087MA
+ ID_MODEL_FROM_DATABASE=AAC-RAID (Rocket) (ICP ICP9087MA)
 
 pci:v00009005d00000286sv00009005sd000002A2*
- ID_MODEL_FROM_DATABASE=3800
+ ID_MODEL_FROM_DATABASE=AAC-RAID (Rocket) (3800)
 
 pci:v00009005d00000286sv00009005sd000002A3*
- ID_MODEL_FROM_DATABASE=ICP ICP5445AU
+ ID_MODEL_FROM_DATABASE=AAC-RAID (Rocket) (ICP ICP5445AU)
 
 pci:v00009005d00000286sv00009005sd000002A4*
- ID_MODEL_FROM_DATABASE=ICP ICP9085LI
+ ID_MODEL_FROM_DATABASE=AAC-RAID (Rocket) (ICP ICP9085LI)
 
 pci:v00009005d00000286sv00009005sd000002A5*
- ID_MODEL_FROM_DATABASE=ICP ICP5085BR
+ ID_MODEL_FROM_DATABASE=AAC-RAID (Rocket) (ICP ICP5085BR)
 
 pci:v00009005d00000286sv00009005sd000002A6*
- ID_MODEL_FROM_DATABASE=ICP9067MA
+ ID_MODEL_FROM_DATABASE=AAC-RAID (Rocket) (ICP9067MA)
 
 pci:v00009005d00000286sv00009005sd000002A7*
- ID_MODEL_FROM_DATABASE=3805
+ ID_MODEL_FROM_DATABASE=AAC-RAID (Rocket) (3805)
 
 pci:v00009005d00000286sv00009005sd000002A8*
- ID_MODEL_FROM_DATABASE=3400
+ ID_MODEL_FROM_DATABASE=AAC-RAID (Rocket) (3400)
 
 pci:v00009005d00000286sv00009005sd000002A9*
- ID_MODEL_FROM_DATABASE=ICP ICP5085AU
+ ID_MODEL_FROM_DATABASE=AAC-RAID (Rocket) (ICP ICP5085AU)
 
 pci:v00009005d00000286sv00009005sd000002AA*
- ID_MODEL_FROM_DATABASE=ICP ICP5045AU
+ ID_MODEL_FROM_DATABASE=AAC-RAID (Rocket) (ICP ICP5045AU)
 
 pci:v00009005d00000286sv00009005sd000002AC*
- ID_MODEL_FROM_DATABASE=1800
+ ID_MODEL_FROM_DATABASE=AAC-RAID (Rocket) (1800)
 
 pci:v00009005d00000286sv00009005sd000002B3*
- ID_MODEL_FROM_DATABASE=2400
+ ID_MODEL_FROM_DATABASE=AAC-RAID (Rocket) (2400)
 
 pci:v00009005d00000286sv00009005sd000002B4*
- ID_MODEL_FROM_DATABASE=ICP ICP5045AL
+ ID_MODEL_FROM_DATABASE=AAC-RAID (Rocket) (ICP ICP5045AL)
 
 pci:v00009005d00000286sv00009005sd00000800*
- ID_MODEL_FROM_DATABASE=Callisto
+ ID_MODEL_FROM_DATABASE=AAC-RAID (Rocket) (Callisto)
 
 pci:v00009005d0000028B*
  ID_MODEL_FROM_DATABASE=Series 6 - 6G SAS/PCIe 2
 
 pci:v00009005d0000028Bsv00009005sd00000200*
- ID_MODEL_FROM_DATABASE=Series 6 Entry Level - ASR-6405E - 4 internal 6G SAS ports
+ ID_MODEL_FROM_DATABASE=Series 6 - 6G SAS/PCIe 2 (Series 6 Entry Level - ASR-6405E - 4 internal 6G SAS ports)
 
 pci:v00009005d0000028Bsv00009005sd00000201*
- ID_MODEL_FROM_DATABASE=Series 6 Entry Level - ASR-6805E - 8 internal 6G SAS ports
+ ID_MODEL_FROM_DATABASE=Series 6 - 6G SAS/PCIe 2 (Series 6 Entry Level - ASR-6805E - 8 internal 6G SAS ports)
 
 pci:v00009005d0000028Bsv00009005sd00000300*
- ID_MODEL_FROM_DATABASE=Series 6 - ASR-6405 - 4 internal 6G SAS ports
+ ID_MODEL_FROM_DATABASE=Series 6 - 6G SAS/PCIe 2 (Series 6 - ASR-6405 - 4 internal 6G SAS ports)
 
 pci:v00009005d0000028Bsv00009005sd00000301*
- ID_MODEL_FROM_DATABASE=Series 6 - ASR-6805 - 8 internal 6G SAS ports
+ ID_MODEL_FROM_DATABASE=Series 6 - 6G SAS/PCIe 2 (Series 6 - ASR-6805 - 8 internal 6G SAS ports)
 
 pci:v00009005d0000028Bsv00009005sd00000302*
- ID_MODEL_FROM_DATABASE=Series 6 - ASR-6445 - 4 internal and 4 external 6G SAS ports
+ ID_MODEL_FROM_DATABASE=Series 6 - 6G SAS/PCIe 2 (Series 6 - ASR-6445 - 4 internal and 4 external 6G SAS ports)
 
 pci:v00009005d0000028Bsv00009005sd00000310*
- ID_MODEL_FROM_DATABASE=Series 6 Connectors on Top - ASR-6405T - 4 internal 6G SAS ports
+ ID_MODEL_FROM_DATABASE=Series 6 - 6G SAS/PCIe 2 (Series 6 Connectors on Top - ASR-6405T - 4 internal 6G SAS ports)
 
 pci:v00009005d0000028Bsv00009005sd00000311*
- ID_MODEL_FROM_DATABASE=Series 6 Connectors on Top - ASR-6805T - 8 internal 6G SAS
+ ID_MODEL_FROM_DATABASE=Series 6 - 6G SAS/PCIe 2 (Series 6 Connectors on Top - ASR-6805T - 8 internal 6G SAS)
 
 pci:v00009005d0000028Bsv00009005sd00000400*
- ID_MODEL_FROM_DATABASE=Series 6 - ASR-61205 - 12 internal 6G SAS ports
+ ID_MODEL_FROM_DATABASE=Series 6 - 6G SAS/PCIe 2 (Series 6 - ASR-61205 - 12 internal 6G SAS ports)
 
 pci:v00009005d0000028Bsv00009005sd00000401*
- ID_MODEL_FROM_DATABASE=Series 6 - ASR-61605 - 16 internal 6G SAS ports
+ ID_MODEL_FROM_DATABASE=Series 6 - 6G SAS/PCIe 2 (Series 6 - ASR-61605 - 16 internal 6G SAS ports)
 
 pci:v00009005d0000028Bsv00009005sd00000403*
- ID_MODEL_FROM_DATABASE=Series 6 - ASR-62405 - 24 internal 6G SAS ports
+ ID_MODEL_FROM_DATABASE=Series 6 - 6G SAS/PCIe 2 (Series 6 - ASR-62405 - 24 internal 6G SAS ports)
 
 pci:v00009005d0000028C*
  ID_MODEL_FROM_DATABASE=Series 7 6G SAS/PCIe 3
 
 pci:v00009005d0000028Csv00009005sd00000500*
- ID_MODEL_FROM_DATABASE=Series 7 - ASR-7805 - 8 internal 6G SAS Port/PCIe 3.0
+ ID_MODEL_FROM_DATABASE=Series 7 6G SAS/PCIe 3 (Series 7 - ASR-7805 - 8 internal 6G SAS Port/PCIe 3.0)
 
 pci:v00009005d0000028Csv00009005sd00000501*
- ID_MODEL_FROM_DATABASE=Series 7 - ASR-71605 - 16 internal 6G SAS Port/PCIe 3.0
+ ID_MODEL_FROM_DATABASE=Series 7 6G SAS/PCIe 3 (Series 7 - ASR-71605 - 16 internal 6G SAS Port/PCIe 3.0)
 
 pci:v00009005d0000028Csv00009005sd00000502*
- ID_MODEL_FROM_DATABASE=Series 7 - ASR-71685 - 16 internal 8 external 6G SAS Port/PCIe 3.0
+ ID_MODEL_FROM_DATABASE=Series 7 6G SAS/PCIe 3 (Series 7 - ASR-71685 - 16 internal 8 external 6G SAS Port/PCIe 3.0)
 
 pci:v00009005d0000028Csv00009005sd00000503*
- ID_MODEL_FROM_DATABASE=Series 7 - ASR-72405 - 24 internal 0 external 6G SAS Port/PCIe 3.0
+ ID_MODEL_FROM_DATABASE=Series 7 6G SAS/PCIe 3 (Series 7 - ASR-72405 - 24 internal 0 external 6G SAS Port/PCIe 3.0)
 
 pci:v00009005d0000028Csv00009005sd00000504*
- ID_MODEL_FROM_DATABASE=Series 7 - ASR-7885 - 8 internal 8 external 6G SAS Port/PCIe 3.0
+ ID_MODEL_FROM_DATABASE=Series 7 6G SAS/PCIe 3 (Series 7 - ASR-7885 - 8 internal 8 external 6G SAS Port/PCIe 3.0)
 
 pci:v00009005d0000028Csv00009005sd00000505*
- ID_MODEL_FROM_DATABASE=Series 7 Entry Level - ASR-71685E - 16 internal 8 external 6G SAS Port/PCIe 3.0
+ ID_MODEL_FROM_DATABASE=Series 7 6G SAS/PCIe 3 (Series 7 Entry Level - ASR-71685E - 16 internal 8 external 6G SAS Port/PCIe 3.0)
 
 pci:v00009005d0000028Csv00009005sd00000506*
- ID_MODEL_FROM_DATABASE=Series 7 Entry Level - ASR-72405E - 24 internal 0 external 6G SAS Port/PCIe 3.0
+ ID_MODEL_FROM_DATABASE=Series 7 6G SAS/PCIe 3 (Series 7 Entry Level - ASR-72405E - 24 internal 0 external 6G SAS Port/PCIe 3.0)
 
 pci:v00009005d0000028D*
  ID_MODEL_FROM_DATABASE=Series 8 12G SAS/PCIe 3
 
 pci:v00009005d0000028Dsv00009005sd00000550*
- ID_MODEL_FROM_DATABASE=Series 8 - ASR-82405 - 24 internal 0 external 12G SAS Port/PCIe 3.0
+ ID_MODEL_FROM_DATABASE=Series 8 12G SAS/PCIe 3 (Series 8 - ASR-82405 - 24 internal 0 external 12G SAS Port/PCIe 3.0)
 
 pci:v00009005d0000028Dsv00009005sd00000551*
- ID_MODEL_FROM_DATABASE=Series 8 - ASR-81605 - 16 internal 0 external 12G SAS Port/PCIe 3.0
+ ID_MODEL_FROM_DATABASE=Series 8 12G SAS/PCIe 3 (Series 8 - ASR-81605 - 16 internal 0 external 12G SAS Port/PCIe 3.0)
 
 pci:v00009005d0000028Dsv00009005sd00000552*
- ID_MODEL_FROM_DATABASE=Series 8 - ASR-8805 - 8 internal 0 external 12G SAS Port/PCIe 3.0
+ ID_MODEL_FROM_DATABASE=Series 8 12G SAS/PCIe 3 (Series 8 - ASR-8805 - 8 internal 0 external 12G SAS Port/PCIe 3.0)
 
 pci:v00009005d0000028Dsv00009005sd00000553*
- ID_MODEL_FROM_DATABASE=Series 8 - ASR-8085 - 0 internal 8 external 12G SAS Port/PCIe 3.0
+ ID_MODEL_FROM_DATABASE=Series 8 12G SAS/PCIe 3 (Series 8 - ASR-8085 - 0 internal 8 external 12G SAS Port/PCIe 3.0)
 
 pci:v00009005d0000028Dsv00009005sd00000554*
- ID_MODEL_FROM_DATABASE=Series 8 - ASR-8885 - 8 internal 8 external 12G SAS Port/PCIe 3.0
+ ID_MODEL_FROM_DATABASE=Series 8 12G SAS/PCIe 3 (Series 8 - ASR-8885 - 8 internal 8 external 12G SAS Port/PCIe 3.0)
 
 pci:v00009005d00000410*
  ID_MODEL_FROM_DATABASE=AIC-9410W SAS (Razor HBA RAID)
 
 pci:v00009005d00000410sv00009005sd00000410*
- ID_MODEL_FROM_DATABASE=ASC-48300(Spirit RAID)
+ ID_MODEL_FROM_DATABASE=AIC-9410W SAS (Razor HBA RAID) (ASC-48300(Spirit RAID))
 
 pci:v00009005d00000410sv00009005sd00000411*
- ID_MODEL_FROM_DATABASE=ASC-58300 (Oakmont RAID)
+ ID_MODEL_FROM_DATABASE=AIC-9410W SAS (Razor HBA RAID) (ASC-58300 (Oakmont RAID))
 
 pci:v00009005d00000412*
  ID_MODEL_FROM_DATABASE=AIC-9410W SAS (Razor HBA non-RAID)
 
 pci:v00009005d00000412sv00009005sd00000412*
- ID_MODEL_FROM_DATABASE=ASC-48300 (Spirit non-RAID)
+ ID_MODEL_FROM_DATABASE=AIC-9410W SAS (Razor HBA non-RAID) (ASC-48300 (Spirit non-RAID))
 
 pci:v00009005d00000412sv00009005sd00000413*
- ID_MODEL_FROM_DATABASE=ASC-58300 (Oakmont non-RAID)
+ ID_MODEL_FROM_DATABASE=AIC-9410W SAS (Razor HBA non-RAID) (ASC-58300 (Oakmont non-RAID))
 
 pci:v00009005d00000415*
  ID_MODEL_FROM_DATABASE=ASC-58300 SAS (Razor-External HBA RAID)
@@ -71025,13 +73809,13 @@ pci:v00009005d00000430*
  ID_MODEL_FROM_DATABASE=AIC-9405W SAS (Razor-Lite HBA RAID)
 
 pci:v00009005d00000430sv00009005sd00000430*
- ID_MODEL_FROM_DATABASE=ASC-44300 (Spirit-Lite RAID)
+ ID_MODEL_FROM_DATABASE=AIC-9405W SAS (Razor-Lite HBA RAID) (ASC-44300 (Spirit-Lite RAID))
 
 pci:v00009005d00000432*
  ID_MODEL_FROM_DATABASE=AIC-9405W SAS (Razor-Lite HBA non-RAID)
 
 pci:v00009005d00000432sv00009005sd00000432*
- ID_MODEL_FROM_DATABASE=ASC-44300 (Spirit-Lite non-RAID)
+ ID_MODEL_FROM_DATABASE=AIC-9405W SAS (Razor-Lite HBA non-RAID) (ASC-44300 (Spirit-Lite non-RAID))
 
 pci:v00009005d0000043E*
  ID_MODEL_FROM_DATABASE=AIC-9405W SAS (Razor-Lite ASIC non-RAID)
@@ -71046,22 +73830,22 @@ pci:v00009005d00000500*
  ID_MODEL_FROM_DATABASE=Obsidian chipset SCSI controller
 
 pci:v00009005d00000500sv00001014sd000002C1*
- ID_MODEL_FROM_DATABASE=PCI-X DDR 3Gb SAS Adapter (572A/572C)
+ ID_MODEL_FROM_DATABASE=Obsidian chipset SCSI controller (PCI-X DDR 3Gb SAS Adapter (572A/572C))
 
 pci:v00009005d00000500sv00001014sd000002C2*
- ID_MODEL_FROM_DATABASE=PCI-X DDR 3Gb SAS RAID Adapter (572B/572D)
+ ID_MODEL_FROM_DATABASE=Obsidian chipset SCSI controller (PCI-X DDR 3Gb SAS RAID Adapter (572B/572D))
 
 pci:v00009005d00000503*
  ID_MODEL_FROM_DATABASE=Scamp chipset SCSI controller
 
 pci:v00009005d00000503sv00001014sd000002BF*
- ID_MODEL_FROM_DATABASE=Quad Channel PCI-X DDR U320 SCSI RAID Adapter (571E)
+ ID_MODEL_FROM_DATABASE=Scamp chipset SCSI controller (Quad Channel PCI-X DDR U320 SCSI RAID Adapter (571E))
 
 pci:v00009005d00000503sv00001014sd000002C3*
- ID_MODEL_FROM_DATABASE=PCI-X DDR 3Gb SAS RAID Adapter (572F)
+ ID_MODEL_FROM_DATABASE=Scamp chipset SCSI controller (PCI-X DDR 3Gb SAS RAID Adapter (572F))
 
 pci:v00009005d00000503sv00001014sd000002D5*
- ID_MODEL_FROM_DATABASE=Quad Channel PCI-X DDR U320 SCSI RAID Adapter (571F)
+ ID_MODEL_FROM_DATABASE=Scamp chipset SCSI controller (Quad Channel PCI-X DDR U320 SCSI RAID Adapter (571F))
 
 pci:v00009005d00000910*
  ID_MODEL_FROM_DATABASE=AUA-3100B
@@ -71082,10 +73866,10 @@ pci:v00009005d00008011*
  ID_MODEL_FROM_DATABASE=ASC-39320D
 
 pci:v00009005d00008011sv00000E11sd000000AC*
- ID_MODEL_FROM_DATABASE=ASC-39320D U320
+ ID_MODEL_FROM_DATABASE=ASC-39320D (U320)
 
 pci:v00009005d00008011sv00009005sd00000041*
- ID_MODEL_FROM_DATABASE=ASC-39320D U320
+ ID_MODEL_FROM_DATABASE=ASC-39320D (U320)
 
 pci:v00009005d00008012*
  ID_MODEL_FROM_DATABASE=ASC-29320 U320
@@ -71106,10 +73890,10 @@ pci:v00009005d00008017*
  ID_MODEL_FROM_DATABASE=ASC-29320ALP U320
 
 pci:v00009005d00008017sv00009005sd00000044*
- ID_MODEL_FROM_DATABASE=ASC-29320ALP PCIx U320
+ ID_MODEL_FROM_DATABASE=ASC-29320ALP U320 (ASC-29320ALP PCIx U320)
 
 pci:v00009005d00008017sv00009005sd00000045*
- ID_MODEL_FROM_DATABASE=ASC-29320LPE PCIe U320
+ ID_MODEL_FROM_DATABASE=ASC-29320ALP U320 (ASC-29320LPE PCIe U320)
 
 pci:v00009005d0000801C*
  ID_MODEL_FROM_DATABASE=ASC-39320D U320
@@ -71118,7 +73902,7 @@ pci:v00009005d0000801D*
  ID_MODEL_FROM_DATABASE=AIC-7902B U320
 
 pci:v00009005d0000801Dsv00001014sd000002CC*
- ID_MODEL_FROM_DATABASE=ServeRAID 7e
+ ID_MODEL_FROM_DATABASE=AIC-7902B U320 (ServeRAID 7e)
 
 pci:v00009005d0000801E*
  ID_MODEL_FROM_DATABASE=AIC-7901A U320
@@ -71127,7 +73911,7 @@ pci:v00009005d0000801F*
  ID_MODEL_FROM_DATABASE=AIC-7902 U320
 
 pci:v00009005d0000801Fsv00001734sd00001011*
- ID_MODEL_FROM_DATABASE=PRIMERGY RX300 onboard SCSI
+ ID_MODEL_FROM_DATABASE=AIC-7902 U320 (PRIMERGY RX300 onboard SCSI)
 
 pci:v00009005d00008080*
  ID_MODEL_FROM_DATABASE=ASC-29320A U320 w/HostRAID
@@ -71144,6 +73928,9 @@ pci:v00009005d00008089*
 pci:v00009005d0000808F*
  ID_MODEL_FROM_DATABASE=AIC-7901 U320 w/HostRAID
 
+pci:v00009005d0000808Fsv00001028sd00000168*
+ ID_MODEL_FROM_DATABASE=AIC-7901 U320 w/HostRAID (Precision Workstation 670 Mainboard)
+
 pci:v00009005d00008090*
  ID_MODEL_FROM_DATABASE=ASC-39320 U320 w/HostRAID
 
@@ -71175,7 +73962,7 @@ pci:v00009005d0000809D*
  ID_MODEL_FROM_DATABASE=AIC-7902(B) U320 w/HostRAID
 
 pci:v00009005d0000809Dsv00001014sd000002CC*
- ID_MODEL_FROM_DATABASE=ServeRAID 7e
+ ID_MODEL_FROM_DATABASE=AIC-7902(B) U320 w/HostRAID (ServeRAID 7e)
 
 pci:v00009005d0000809E*
  ID_MODEL_FROM_DATABASE=AIC-7901A U320 w/HostRAID
@@ -71223,7 +74010,7 @@ pci:v00009710d00009815*
  ID_MODEL_FROM_DATABASE=PCI 9815 Multi-I/O Controller
 
 pci:v00009710d00009815sv00001000sd00000020*
- ID_MODEL_FROM_DATABASE=2P0S (2 port parallel adaptor)
+ ID_MODEL_FROM_DATABASE=PCI 9815 Multi-I/O Controller (2P0S (2 port parallel adaptor))
 
 pci:v00009710d00009820*
  ID_MODEL_FROM_DATABASE=PCI 9820 Multi-I/O Controller
@@ -71232,31 +74019,31 @@ pci:v00009710d00009835*
  ID_MODEL_FROM_DATABASE=PCI 9835 Multi-I/O Controller
 
 pci:v00009710d00009835sv00001000sd00000002*
- ID_MODEL_FROM_DATABASE=2S (16C550 UART)
+ ID_MODEL_FROM_DATABASE=PCI 9835 Multi-I/O Controller (2S (16C550 UART))
 
 pci:v00009710d00009835sv00001000sd00000012*
- ID_MODEL_FROM_DATABASE=1P2S
+ ID_MODEL_FROM_DATABASE=PCI 9835 Multi-I/O Controller (1P2S)
 
 pci:v00009710d00009845*
  ID_MODEL_FROM_DATABASE=PCI 9845 Multi-I/O Controller
 
 pci:v00009710d00009845sv00001000sd00000004*
- ID_MODEL_FROM_DATABASE=0P4S (4 port 16550A serial card)
+ ID_MODEL_FROM_DATABASE=PCI 9845 Multi-I/O Controller (0P4S (4 port 16550A serial card))
 
 pci:v00009710d00009845sv00001000sd00000006*
- ID_MODEL_FROM_DATABASE=0P6S (6 port 16550a serial card)
+ ID_MODEL_FROM_DATABASE=PCI 9845 Multi-I/O Controller (0P6S (6 port 16550a serial card))
 
 pci:v00009710d00009845sv00001000sd00000014*
- ID_MODEL_FROM_DATABASE=1P4S (1 Parallel / 4 16550A Serial Port Adapter)
+ ID_MODEL_FROM_DATABASE=PCI 9845 Multi-I/O Controller (1P4S (1 Parallel / 4 16550A Serial Port Adapter))
 
 pci:v00009710d00009855*
  ID_MODEL_FROM_DATABASE=PCI 9855 Multi-I/O Controller
 
 pci:v00009710d00009855sv00001000sd00000014*
- ID_MODEL_FROM_DATABASE=1P4S
+ ID_MODEL_FROM_DATABASE=PCI 9855 Multi-I/O Controller (1P4S)
 
 pci:v00009710d00009855sv00001000sd00000022*
- ID_MODEL_FROM_DATABASE=2P2S (2 Parallel / 2 16550A Serial Port Adapter)
+ ID_MODEL_FROM_DATABASE=PCI 9855 Multi-I/O Controller (2P2S (2 Parallel / 2 16550A Serial Port Adapter))
 
 pci:v00009710d00009865*
  ID_MODEL_FROM_DATABASE=PCI 9865 Multi-I/O Controller
@@ -71271,11 +74058,14 @@ pci:v00009710d00009912*
  ID_MODEL_FROM_DATABASE=PCIe 9912 Multi-I/O Controller
 
 pci:v00009710d00009922*
- ID_MODEL_FROM_DATABASE=PCIe 9922 Multi-I/O Controller
+ ID_MODEL_FROM_DATABASE=MCS9922 PCIe Multi-I/O Controller
 
 pci:v00009710d00009990*
  ID_MODEL_FROM_DATABASE=MCS9990 PCIe to 4‐Port USB 2.0 Host Controller
 
+pci:v00009850*
+ ID_VENDOR_FROM_DATABASE=3Com (wrong ID)
+
 pci:v00009902*
  ID_VENDOR_FROM_DATABASE=Stargen Inc.
 
@@ -71315,6 +74105,54 @@ pci:v0000A727d00000013*
 pci:v0000A727d00006803*
  ID_MODEL_FROM_DATABASE=3CRDAG675B Wireless 11a/b/g Adapter
 
+pci:v0000AA00*
+ ID_VENDOR_FROM_DATABASE=iTuner
+
+pci:v0000AA01*
+ ID_VENDOR_FROM_DATABASE=iTuner
+
+pci:v0000AA02*
+ ID_VENDOR_FROM_DATABASE=iTuner
+
+pci:v0000AA03*
+ ID_VENDOR_FROM_DATABASE=iTuner
+
+pci:v0000AA04*
+ ID_VENDOR_FROM_DATABASE=iTuner
+
+pci:v0000AA05*
+ ID_VENDOR_FROM_DATABASE=iTuner
+
+pci:v0000AA06*
+ ID_VENDOR_FROM_DATABASE=iTuner
+
+pci:v0000AA07*
+ ID_VENDOR_FROM_DATABASE=iTuner
+
+pci:v0000AA08*
+ ID_VENDOR_FROM_DATABASE=iTuner
+
+pci:v0000AA09*
+ ID_VENDOR_FROM_DATABASE=iTuner
+
+pci:v0000AA0A*
+ ID_VENDOR_FROM_DATABASE=iTuner
+
+pci:v0000AA0B*
+ ID_VENDOR_FROM_DATABASE=iTuner
+
+pci:v0000AA0C*
+ ID_VENDOR_FROM_DATABASE=iTuner
+
+pci:v0000AA0D*
+ ID_VENDOR_FROM_DATABASE=iTuner
+
+pci:v0000AA0E*
+ ID_VENDOR_FROM_DATABASE=iTuner
+
+pci:v0000AA0F*
+ ID_VENDOR_FROM_DATABASE=iTuner
+
 pci:v0000AA42*
  ID_VENDOR_FROM_DATABASE=Scitex Digital Video
 
@@ -71381,6 +74219,9 @@ pci:v0000BD11*
 pci:v0000BDBD*
  ID_VENDOR_FROM_DATABASE=Blackmagic Design
 
+pci:v0000BDBDd0000A106*
+ ID_MODEL_FROM_DATABASE=Multibridge Extreme
+
 pci:v0000BDBDd0000A117*
  ID_MODEL_FROM_DATABASE=Intensity Pro
 
@@ -71528,6 +74369,9 @@ pci:v0000D161d00001405*
 pci:v0000D161d00001420*
  ID_MODEL_FROM_DATABASE=Wildcard TE420 quad-span T1/E1/J1 card 3.3V (PCI-Express) (5th gen)
 
+pci:v0000D161d00001820*
+ ID_MODEL_FROM_DATABASE=Wildcard TE820 octal-span T1/E1/J1 card 3.3V (PCI-Express)
+
 pci:v0000D161d00002400*
  ID_MODEL_FROM_DATABASE=Wildcard TDM2400P 24-port analog card
 
@@ -71567,6 +74411,24 @@ pci:v0000D161d0000800A*
 pci:v0000D161d0000800B*
  ID_MODEL_FROM_DATABASE=Wildcard TE134 single-span T1/E1/J1 card
 
+pci:v0000D161d0000800C*
+ ID_MODEL_FROM_DATABASE=Wildcard A8A 8-port analog card
+
+pci:v0000D161d0000800D*
+ ID_MODEL_FROM_DATABASE=Wildcard A8B 8-port analog card (PCI-Express)
+
+pci:v0000D161d0000800E*
+ ID_MODEL_FROM_DATABASE=Wildcard TE235/TE435 quad-span T1/E1/J1 card (PCI-Express)
+
+pci:v0000D161d0000800F*
+ ID_MODEL_FROM_DATABASE=Wildcard A4A 4-port analog card
+
+pci:v0000D161d00008010*
+ ID_MODEL_FROM_DATABASE=Wildcard A4B 4-port analog card (PCI-Express)
+
+pci:v0000D161d00008013*
+ ID_MODEL_FROM_DATABASE=Wildcard TE236/TE436 quad-span T1/E1/J1 card
+
 pci:v0000D161d0000B410*
  ID_MODEL_FROM_DATABASE=Wildcard B410 quad-BRI card
 
@@ -71585,6 +74447,51 @@ pci:v0000D84D*
 pci:v0000DADA*
  ID_VENDOR_FROM_DATABASE=Datapath Limited
 
+pci:v0000DADAd00000133*
+ ID_MODEL_FROM_DATABASE=VisionRGB-X2
+
+pci:v0000DADAd00000139*
+ ID_MODEL_FROM_DATABASE=VisionRGB-E1
+
+pci:v0000DADAd00000144*
+ ID_MODEL_FROM_DATABASE=VisionSD8
+
+pci:v0000DADAd00000150*
+ ID_MODEL_FROM_DATABASE=VisionRGB-E2
+
+pci:v0000DADAd00000151*
+ ID_MODEL_FROM_DATABASE=VisionSD4+1
+
+pci:v0000DADAd00000159*
+ ID_MODEL_FROM_DATABASE=VisionAV
+
+pci:v0000DADAd00000161*
+ ID_MODEL_FROM_DATABASE=DGC161
+
+pci:v0000DADAd00000165*
+ ID_MODEL_FROM_DATABASE=DGC165
+
+pci:v0000DADAd00000167*
+ ID_MODEL_FROM_DATABASE=DGC167
+
+pci:v0000DADAd00000168*
+ ID_MODEL_FROM_DATABASE=DGC168
+
+pci:v0000DADAd00001139*
+ ID_MODEL_FROM_DATABASE=VisionRGB-E1S
+
+pci:v0000DADAd00001150*
+ ID_MODEL_FROM_DATABASE=VisionRGB-E2S
+
+pci:v0000DADAd00001151*
+ ID_MODEL_FROM_DATABASE=VisionSD4+1S
+
+pci:v0000DADAd00001153*
+ ID_MODEL_FROM_DATABASE=VisionDVI-DL
+
+pci:v0000DADAd00001154*
+ ID_MODEL_FROM_DATABASE=VisionSDI2
+
 pci:v0000DB10*
  ID_VENDOR_FROM_DATABASE=Diablo Technologies
 
@@ -71616,40 +74523,40 @@ pci:v0000DD01d00000003*
  ID_MODEL_FROM_DATABASE=Octopus DVB Adapter
 
 pci:v0000DD01d00000003sv0000DD01sd00000001*
- ID_MODEL_FROM_DATABASE=Octopus DVB adapter
+ ID_MODEL_FROM_DATABASE=Octopus DVB Adapter (Octopus DVB adapter)
 
 pci:v0000DD01d00000003sv0000DD01sd00000002*
- ID_MODEL_FROM_DATABASE=Octopus LE DVB adapter
+ ID_MODEL_FROM_DATABASE=Octopus DVB Adapter (Octopus LE DVB adapter)
 
 pci:v0000DD01d00000003sv0000DD01sd00000003*
- ID_MODEL_FROM_DATABASE=Octopus OEM
+ ID_MODEL_FROM_DATABASE=Octopus DVB Adapter (Octopus OEM)
 
 pci:v0000DD01d00000003sv0000DD01sd00000004*
- ID_MODEL_FROM_DATABASE=Octopus V3 DVB adapter
+ ID_MODEL_FROM_DATABASE=Octopus DVB Adapter (Octopus V3 DVB adapter)
 
 pci:v0000DD01d00000003sv0000DD01sd00000010*
- ID_MODEL_FROM_DATABASE=Octopus Mini
+ ID_MODEL_FROM_DATABASE=Octopus DVB Adapter (Octopus Mini)
 
 pci:v0000DD01d00000003sv0000DD01sd00000020*
- ID_MODEL_FROM_DATABASE=Cine S2 V6 DVB adapter
+ ID_MODEL_FROM_DATABASE=Octopus DVB Adapter (Cine S2 V6 DVB adapter)
 
 pci:v0000DD01d00000003sv0000DD01sd00000021*
- ID_MODEL_FROM_DATABASE=Cine S2 V6.5 DVB adapter
+ ID_MODEL_FROM_DATABASE=Octopus DVB Adapter (Cine S2 V6.5 DVB adapter)
 
 pci:v0000DD01d00000003sv0000DD01sd00000030*
- ID_MODEL_FROM_DATABASE=Cine CT V6.1 DVB adapter
+ ID_MODEL_FROM_DATABASE=Octopus DVB Adapter (Cine CT V6.1 DVB adapter)
 
 pci:v0000DD01d00000003sv0000DD01sd0000DB03*
- ID_MODEL_FROM_DATABASE=Mystique SaTiX-S2 V3 DVB adapter
+ ID_MODEL_FROM_DATABASE=Octopus DVB Adapter (Mystique SaTiX-S2 V3 DVB adapter)
 
 pci:v0000DD01d00000011*
  ID_MODEL_FROM_DATABASE=Octopus CI DVB Adapter
 
 pci:v0000DD01d00000011sv0000DD01sd00000040*
- ID_MODEL_FROM_DATABASE=Octopus CI
+ ID_MODEL_FROM_DATABASE=Octopus CI DVB Adapter (Octopus CI)
 
 pci:v0000DD01d00000011sv0000DD01sd00000041*
- ID_MODEL_FROM_DATABASE=Octopus CI Single
+ ID_MODEL_FROM_DATABASE=Octopus CI DVB Adapter (Octopus CI Single)
 
 pci:v0000DEAD*
  ID_VENDOR_FROM_DATABASE=Indigita Corporation
@@ -71682,22 +74589,22 @@ pci:v0000E159d00000001*
  ID_MODEL_FROM_DATABASE=Tiger3XX Modem/ISDN interface
 
 pci:v0000E159d00000001sv00000059sd00000001*
- ID_MODEL_FROM_DATABASE=128k ISDN-S/T Adapter
+ ID_MODEL_FROM_DATABASE=Tiger3XX Modem/ISDN interface (128k ISDN-S/T Adapter)
 
 pci:v0000E159d00000001sv00000059sd00000003*
- ID_MODEL_FROM_DATABASE=128k ISDN-U Adapter
+ ID_MODEL_FROM_DATABASE=Tiger3XX Modem/ISDN interface (128k ISDN-U Adapter)
 
 pci:v0000E159d00000001sv000000A7sd00000001*
- ID_MODEL_FROM_DATABASE=TELES.S0/PCI 2.x ISDN Adapter
+ ID_MODEL_FROM_DATABASE=Tiger3XX Modem/ISDN interface (TELES.S0/PCI 2.x ISDN Adapter)
 
 pci:v0000E159d00000001sv00008086sd00000003*
- ID_MODEL_FROM_DATABASE=Digium X100P/X101P analogue PSTN FXO interface
+ ID_MODEL_FROM_DATABASE=Tiger3XX Modem/ISDN interface (Digium X100P/X101P analogue PSTN FXO interface)
 
 pci:v0000E159d00000001sv0000B100sd00000003*
- ID_MODEL_FROM_DATABASE=OpenVox A400P 4-port analog card
+ ID_MODEL_FROM_DATABASE=Tiger3XX Modem/ISDN interface (OpenVox A400P 4-port analog card)
 
 pci:v0000E159d00000001sv0000B1D9sd00000003*
- ID_MODEL_FROM_DATABASE=AX400P 4-port analog card
+ ID_MODEL_FROM_DATABASE=Tiger3XX Modem/ISDN interface (AX400P 4-port analog card)
 
 pci:v0000E159d00000002*
  ID_MODEL_FROM_DATABASE=Tiger100APC ISDN chipset
@@ -71735,6 +74642,9 @@ pci:v0000E4BFd0000CC47*
 pci:v0000E4BFd0000CC4D*
  ID_MODEL_FROM_DATABASE=CCM-BOOGIE
 
+pci:v0000E4E4*
+ ID_VENDOR_FROM_DATABASE=Xorcom
+
 pci:v0000E55E*
  ID_VENDOR_FROM_DATABASE=Essence Technology, Inc.
 
index 3294d8a..418d39b 100644 (file)
@@ -311,6 +311,9 @@ usb:v*p*d*dcEFdsc02dp02*
 usb:v*p*d*dcEFdsc03dp01*
  ID_USB_PROTOCOL_FROM_DATABASE=Cable Based Association
 
+usb:v*p*d*dcEFdsc05*
+ ID_USB_SUBCLASS_FROM_DATABASE=USB3 Vision
+
 usb:v*p*d*dcFE*
  ID_USB_CLASS_FROM_DATABASE=Application Specific Interface
 
index 60dbcd2..d87313c 100644 (file)
@@ -20,6 +20,12 @@ usb:v0003*
 usb:v0004*
  ID_VENDOR_FROM_DATABASE=Nebraska Furniture Mart
 
+usb:v0011*
+ ID_VENDOR_FROM_DATABASE=Unknown
+
+usb:v0011p7788*
+ ID_MODEL_FROM_DATABASE=Flash mass storage drive
+
 usb:v0053*
  ID_VENDOR_FROM_DATABASE=Planex
 
@@ -30,7 +36,7 @@ usb:v0079*
  ID_VENDOR_FROM_DATABASE=DragonRise Inc.
 
 usb:v0079p0006*
- ID_MODEL_FROM_DATABASE=Generic USB Joystick
+ ID_MODEL_FROM_DATABASE=PC TWIN SHOCK Gamepad
 
 usb:v0079p0011*
  ID_MODEL_FROM_DATABASE=Gamepad
@@ -63,7 +69,7 @@ usb:v0204*
  ID_VENDOR_FROM_DATABASE=Chipsbank Microelectronics Co., Ltd
 
 usb:v0204p6025*
- ID_MODEL_FROM_DATABASE=CBM2080 Flash drive controller
+ ID_MODEL_FROM_DATABASE=CBM2080 / CBM2090 Flash drive controller
 
 usb:v0204p6026*
  ID_MODEL_FROM_DATABASE=CBM1180 Flash drive controller
@@ -263,18 +269,33 @@ usb:v03EBp2109*
 usb:v03EBp210D*
  ID_MODEL_FROM_DATABASE=XPLAIN evaluation kit (CDC ACM)
 
+usb:v03EBp2110*
+ ID_MODEL_FROM_DATABASE=AVR JTAGICE3 Debugger and Programmer
+
 usb:v03EBp2122*
  ID_MODEL_FROM_DATABASE=XMEGA-A1 Explained evaluation kit
 
+usb:v03EBp2141*
+ ID_MODEL_FROM_DATABASE=ICE debugger
+
 usb:v03EBp2310*
  ID_MODEL_FROM_DATABASE=EVK11xx evaluation board
 
 usb:v03EBp2FE4*
  ID_MODEL_FROM_DATABASE=ATxmega32A4U DFU bootloader
 
+usb:v03EBp2FE6*
+ ID_MODEL_FROM_DATABASE=Cactus V6 (DFU)
+
+usb:v03EBp2FEA*
+ ID_MODEL_FROM_DATABASE=Cactus RF60 (DFU)
+
 usb:v03EBp2FF0*
  ID_MODEL_FROM_DATABASE=atmega32u2 DFU bootloader
 
+usb:v03EBp2FF4*
+ ID_MODEL_FROM_DATABASE=atmega32u4 DFU bootloader
+
 usb:v03EBp2FFA*
  ID_MODEL_FROM_DATABASE=at90usb162 DFU bootloader
 
@@ -446,6 +467,9 @@ usb:v03F0p0121*
 usb:v03F0p0122*
  ID_MODEL_FROM_DATABASE=HID Internet Keyboard
 
+usb:v03F0p0139*
+ ID_MODEL_FROM_DATABASE=Barcode Scanner 4430
+
 usb:v03F0p0201*
  ID_MODEL_FROM_DATABASE=ScanJet 6200c
 
@@ -500,6 +524,9 @@ usb:v03F0p0317*
 usb:v03F0p0324*
  ID_MODEL_FROM_DATABASE=SK-2885 keyboard
 
+usb:v03F0p034A*
+ ID_MODEL_FROM_DATABASE=Elite Keyboard
+
 usb:v03F0p0401*
  ID_MODEL_FROM_DATABASE=ScanJet 5200c
 
@@ -743,6 +770,9 @@ usb:v03F0p1317*
 usb:v03F0p1327*
  ID_MODEL_FROM_DATABASE=iLO Virtual Hub
 
+usb:v03F0p134A*
+ ID_MODEL_FROM_DATABASE=Optical Mouse
+
 usb:v03F0p1405*
  ID_MODEL_FROM_DATABASE=ScanJet 3670
 
@@ -773,6 +803,9 @@ usb:v03F0p1517*
 usb:v03F0p1524*
  ID_MODEL_FROM_DATABASE=Smart Card Keyboard - KR
 
+usb:v03F0p1539*
+ ID_MODEL_FROM_DATABASE=Mini Magnetic Stripe Reader
+
 usb:v03F0p1602*
  ID_MODEL_FROM_DATABASE=PhotoSmart 330 series
 
@@ -884,6 +917,9 @@ usb:v03F0p1D02*
 usb:v03F0p1D17*
  ID_MODEL_FROM_DATABASE=LaserJet 1320
 
+usb:v03F0p1D24*
+ ID_MODEL_FROM_DATABASE=Barcode scanner
+
 usb:v03F0p1E02*
  ID_MODEL_FROM_DATABASE=PhotoSmart A320 Printer series
 
@@ -926,6 +962,9 @@ usb:v03F0p2012*
 usb:v03F0p201D*
  ID_MODEL_FROM_DATABASE=un2400 Gobi Wireless Modem (QDL mode)
 
+usb:v03F0p2039*
+ ID_MODEL_FROM_DATABASE=Cashdrawer
+
 usb:v03F0p2102*
  ID_MODEL_FROM_DATABASE=PhotoSmart 7345
 
@@ -999,7 +1038,10 @@ usb:v03F0p2505*
  ID_MODEL_FROM_DATABASE=ScanJet 3770
 
 usb:v03F0p2512*
- ID_MODEL_FROM_DATABASE=OfficeJet Pro L7300
+ ID_MODEL_FROM_DATABASE=OfficeJet Pro L7300 / Compaq LA2405 series monitor
+
+usb:v03F0p2514*
+ ID_MODEL_FROM_DATABASE=4-port hub
 
 usb:v03F0p2517*
  ID_MODEL_FROM_DATABASE=LaserJet 2410
@@ -1034,6 +1076,9 @@ usb:v03F0p2704*
 usb:v03F0p2717*
  ID_MODEL_FROM_DATABASE=Color LaserJet 2830
 
+usb:v03F0p2724*
+ ID_MODEL_FROM_DATABASE=Magnetic Stripe Reader IDRA-334133-HP
+
 usb:v03F0p2811*
  ID_MODEL_FROM_DATABASE=PSC-2100
 
@@ -1376,6 +1421,9 @@ usb:v03F0p5111*
 usb:v03F0p5211*
  ID_MODEL_FROM_DATABASE=PhotoSmart 3300 series
 
+usb:v03F0p5307*
+ ID_MODEL_FROM_DATABASE=v165w Stick
+
 usb:v03F0p5311*
  ID_MODEL_FROM_DATABASE=OfficeJet 6300
 
@@ -1409,6 +1457,9 @@ usb:v03F0p5817*
 usb:v03F0p5911*
  ID_MODEL_FROM_DATABASE=PhotoSmart C6180
 
+usb:v03F0p5912*
+ ID_MODEL_FROM_DATABASE=Officejet Pro 8600
+
 usb:v03F0p5A11*
  ID_MODEL_FROM_DATABASE=PhotoSmart C7100 series
 
@@ -1517,6 +1568,9 @@ usb:v03F0p6B02*
 usb:v03F0p6B11*
  ID_MODEL_FROM_DATABASE=Photosmart C4500 series
 
+usb:v03F0p6C11*
+ ID_MODEL_FROM_DATABASE=Photosmart C4480
+
 usb:v03F0p6C17*
  ID_MODEL_FROM_DATABASE=Color LaserJet 4610
 
@@ -1898,6 +1952,9 @@ usb:v03FC*
 usb:v03FD*
  ID_VENDOR_FROM_DATABASE=Xilinx, Inc.
 
+usb:v03FDp0008*
+ ID_MODEL_FROM_DATABASE=Platform Cable USB II
+
 usb:v03FE*
  ID_VENDOR_FROM_DATABASE=Farallon Comunications
 
@@ -1997,6 +2054,9 @@ usb:v0403p0232*
 usb:v0403p1060*
  ID_MODEL_FROM_DATABASE=JTAG adapter
 
+usb:v0403p1234*
+ ID_MODEL_FROM_DATABASE=IronLogic RFID Adapter [Z-2 USB]
+
 usb:v0403p6001*
  ID_MODEL_FROM_DATABASE=FT232 USB-Serial (UART) IC
 
@@ -2054,12 +2114,33 @@ usb:v0403p8A28*
 usb:v0403p8A98*
  ID_MODEL_FROM_DATABASE=TIAO Multi-Protocol Adapter
 
+usb:v0403p8B28*
+ ID_MODEL_FROM_DATABASE=Alpermann+Velte TCI70
+
+usb:v0403p8B29*
+ ID_MODEL_FROM_DATABASE=Alpermann+Velte TC60 CLS
+
+usb:v0403p8B2A*
+ ID_MODEL_FROM_DATABASE=Alpermann+Velte Rubidium Q1
+
+usb:v0403p8B2B*
+ ID_MODEL_FROM_DATABASE=Alpermann+Velte TCD
+
+usb:v0403p8B2C*
+ ID_MODEL_FROM_DATABASE=Alpermann+Velte TCC70
+
+usb:v0403p9132*
+ ID_MODEL_FROM_DATABASE=LCD and Temperature Interface
+
 usb:v0403p9133*
  ID_MODEL_FROM_DATABASE=CallerID
 
 usb:v0403p9135*
  ID_MODEL_FROM_DATABASE=Rotary Pub alarm
 
+usb:v0403p9136*
+ ID_MODEL_FROM_DATABASE=Pulsecounter
+
 usb:v0403p9E90*
  ID_MODEL_FROM_DATABASE=Marvell OpenRD Base/Client
 
@@ -2156,6 +2237,9 @@ usb:v0403pC8BD*
 usb:v0403pC8BE*
  ID_MODEL_FROM_DATABASE=Alpermann+Velte Rubidium D1
 
+usb:v0403pC8BF*
+ ID_MODEL_FROM_DATABASE=Alpermann+Velte TC60 RLV
+
 usb:v0403pCC48*
  ID_MODEL_FROM_DATABASE=Tactrix OpenPort 1.3 Mitsubishi
 
@@ -2258,6 +2342,15 @@ usb:v0403pEF10*
 usb:v0403pF070*
  ID_MODEL_FROM_DATABASE=Serial Converter 422/485 [Vardaan VEUSB422R3]
 
+usb:v0403pF0C8*
+ ID_MODEL_FROM_DATABASE=SPROG Decoder Programmer
+
+usb:v0403pF0C9*
+ ID_MODEL_FROM_DATABASE=SPROG-DCC CAN-USB
+
+usb:v0403pF0E9*
+ ID_MODEL_FROM_DATABASE=Tagsys L-P101
+
 usb:v0403pF1A0*
  ID_MODEL_FROM_DATABASE=Asix PRESTO Programmer
 
@@ -2561,6 +2654,9 @@ usb:v0409p02B4*
 usb:v0409p02B6*
  ID_MODEL_FROM_DATABASE=Aterm WL300NU-GS 802.11n Wireless Adapter
 
+usb:v0409p02BC*
+ ID_MODEL_FROM_DATABASE=Computer Monitor
+
 usb:v0409p0300*
  ID_MODEL_FROM_DATABASE=LifeTouch Note
 
@@ -2966,6 +3062,12 @@ usb:v040Ap4021*
 usb:v040Ap4022*
  ID_MODEL_FROM_DATABASE=1400 Digital Photo Printer
 
+usb:v040Ap402B*
+ ID_MODEL_FROM_DATABASE=Photo Printer 6850
+
+usb:v040Ap402E*
+ ID_MODEL_FROM_DATABASE=605 Photo Printer
+
 usb:v040Ap4034*
  ID_MODEL_FROM_DATABASE=805 Photo Printer
 
@@ -4331,6 +4433,9 @@ usb:v0424p2602*
 usb:v0424p2640*
  ID_MODEL_FROM_DATABASE=USB 2.0 Hub
 
+usb:v0424p2660*
+ ID_MODEL_FROM_DATABASE=Hub
+
 usb:v0424p4060*
  ID_MODEL_FROM_DATABASE=Ultra Fast Media Reader
 
@@ -4343,6 +4448,9 @@ usb:v0424p7500*
 usb:v0424p9512*
  ID_MODEL_FROM_DATABASE=SMC9512/9514 USB Hub
 
+usb:v0424p9514*
+ ID_MODEL_FROM_DATABASE=SMC9514 Hub
+
 usb:v0424pA700*
  ID_MODEL_FROM_DATABASE=2 Port Hub
 
@@ -4949,6 +5057,9 @@ usb:v043Ep7001*
 usb:v043Ep7013*
  ID_MODEL_FROM_DATABASE=MP3 Player
 
+usb:v043Ep70D7*
+ ID_MODEL_FROM_DATABASE=Mouse Scanner LSM-150 [LG Smart Scan Mouse]
+
 usb:v043Ep70F5*
  ID_MODEL_FROM_DATABASE=External HDD
 
@@ -5114,6 +5225,9 @@ usb:v044FpB203*
 usb:v044FpB300*
  ID_MODEL_FROM_DATABASE=Firestorm Dual Power
 
+usb:v044FpB303*
+ ID_MODEL_FROM_DATABASE=FireStorm Dual Analog 2
+
 usb:v044FpB304*
  ID_MODEL_FROM_DATABASE=Firestorm Dual Power
 
@@ -5177,6 +5291,9 @@ usb:v0451p2046*
 usb:v0451p2077*
  ID_MODEL_FROM_DATABASE=TUSB2077 Hub
 
+usb:v0451p2F90*
+ ID_MODEL_FROM_DATABASE=SM-USB-DIG
+
 usb:v0451p3410*
  ID_MODEL_FROM_DATABASE=TUSB3410 Microcontroller
 
@@ -5246,6 +5363,9 @@ usb:v0452p0050*
 usb:v0452p0051*
  ID_MODEL_FROM_DATABASE=Integrated Hub
 
+usb:v0452p0100*
+ ID_MODEL_FROM_DATABASE=Control Panel for Leica TCS SP5
+
 usb:v0453*
  ID_VENDOR_FROM_DATABASE=CMD Technology
 
@@ -5283,7 +5403,7 @@ usb:v0457p0162*
  ID_MODEL_FROM_DATABASE=SiS162 usb Wireless LAN Adapter
 
 usb:v0457p0163*
- ID_MODEL_FROM_DATABASE=802.11 Wireless LAN Adapter
+ ID_MODEL_FROM_DATABASE=SiS163U 802.11 Wireless LAN Adapter
 
 usb:v0457p0817*
  ID_MODEL_FROM_DATABASE=SiS-184-ASUS-4352.17 touch panel
@@ -5492,6 +5612,9 @@ usb:v0458p5003*
 usb:v0458p5004*
  ID_MODEL_FROM_DATABASE=G-pen Tablet
 
+usb:v0458p505E*
+ ID_MODEL_FROM_DATABASE=Genius iSlim 330
+
 usb:v0458p6001*
  ID_MODEL_FROM_DATABASE=GF3000F Ethernet Adapter
 
@@ -5558,6 +5681,24 @@ usb:v0458p705A*
 usb:v0458p705C*
  ID_MODEL_FROM_DATABASE=Genius iSlim 1300AF
 
+usb:v0458p7061*
+ ID_MODEL_FROM_DATABASE=Genius iLook 1321 V2
+
+usb:v0458p7066*
+ ID_MODEL_FROM_DATABASE=Acer Crystal Eye Webcam
+
+usb:v0458p7067*
+ ID_MODEL_FROM_DATABASE=Genius iSlim 1300AF V2
+
+usb:v0458p7068*
+ ID_MODEL_FROM_DATABASE=Genius eFace 1325R
+
+usb:v0458p706D*
+ ID_MODEL_FROM_DATABASE=Genius iSlim 2000AF V2
+
+usb:v0458p7076*
+ ID_MODEL_FROM_DATABASE=Genius FaceCam 312
+
 usb:v0458p7079*
  ID_MODEL_FROM_DATABASE=FaceCam 2025R
 
@@ -5567,6 +5708,12 @@ usb:v0458p707F*
 usb:v0458p7088*
  ID_MODEL_FROM_DATABASE=WideCam 1050
 
+usb:v0458p7089*
+ ID_MODEL_FROM_DATABASE=Genius FaceCam 320
+
+usb:v0458p708C*
+ ID_MODEL_FROM_DATABASE=Genius WideCam F100
+
 usb:v0459*
  ID_VENDOR_FROM_DATABASE=Adobe Systems, Inc.
 
@@ -5975,6 +6122,15 @@ usb:v045Ep02B0*
 usb:v045Ep02B6*
  ID_MODEL_FROM_DATABASE=Xbox 360 / Bluetooth Wireless Headset
 
+usb:v045Ep02BE*
+ ID_MODEL_FROM_DATABASE=Kinect for Windows NUI Audio
+
+usb:v045Ep02BF*
+ ID_MODEL_FROM_DATABASE=Kinect for Windows NUI Camera
+
+usb:v045Ep02C2*
+ ID_MODEL_FROM_DATABASE=Kinect for Windows NUI Motor
+
 usb:v045Ep0400*
  ID_MODEL_FROM_DATABASE=Windows Powered Pocket PC 2002
 
@@ -6437,6 +6593,9 @@ usb:v045Ep0772*
 usb:v045Ep0779*
  ID_MODEL_FROM_DATABASE=LifeCam HD-3000
 
+usb:v045Ep0780*
+ ID_MODEL_FROM_DATABASE=Comfort Curve Keyboard 3000
+
 usb:v045Ep0797*
  ID_MODEL_FROM_DATABASE=Optical Mouse 200
 
@@ -6818,9 +6977,15 @@ usb:v046Dp082D*
 usb:v046Dp0830*
  ID_MODEL_FROM_DATABASE=QuickClip
 
+usb:v046Dp0837*
+ ID_MODEL_FROM_DATABASE=BCC950 ConferenceCam
+
 usb:v046Dp0840*
  ID_MODEL_FROM_DATABASE=QuickCam Express
 
+usb:v046Dp0843*
+ ID_MODEL_FROM_DATABASE=Webcam C930e
+
 usb:v046Dp0850*
  ID_MODEL_FROM_DATABASE=QuickCam Web
 
@@ -7124,6 +7289,12 @@ usb:v046Dp0A1F*
 usb:v046Dp0A29*
  ID_MODEL_FROM_DATABASE=H600 [Wireless Headset]
 
+usb:v046Dp0A38*
+ ID_MODEL_FROM_DATABASE=Headset H340
+
+usb:v046Dp0A4D*
+ ID_MODEL_FROM_DATABASE=G430 Surround Sound Gaming Headset
+
 usb:v046Dp0B02*
  ID_MODEL_FROM_DATABASE=C-UV35 [Bluetooth Mini-Receiver] (HID proxy mode)
 
@@ -7313,6 +7484,9 @@ usb:v046DpC062*
 usb:v046DpC063*
  ID_MODEL_FROM_DATABASE=DELL Laser Mouse
 
+usb:v046DpC064*
+ ID_MODEL_FROM_DATABASE=M110 corded optical mouse (M-B0001)
+
 usb:v046DpC066*
  ID_MODEL_FROM_DATABASE=G9x Laser Mouse
 
@@ -7331,6 +7505,9 @@ usb:v046DpC06B*
 usb:v046DpC06C*
  ID_MODEL_FROM_DATABASE=Optical Mouse
 
+usb:v046DpC077*
+ ID_MODEL_FROM_DATABASE=M105 Optical Mouse
+
 usb:v046DpC101*
  ID_MODEL_FROM_DATABASE=UltraX Media Remote
 
@@ -7361,6 +7538,9 @@ usb:v046DpC125*
 usb:v046DpC126*
  ID_MODEL_FROM_DATABASE=Harmony Link
 
+usb:v046DpC12B*
+ ID_MODEL_FROM_DATABASE=Harmony Touch Remote
+
 usb:v046DpC201*
  ID_MODEL_FROM_DATABASE=WingMan Extreme Joystick with Throttle
 
@@ -7448,6 +7628,12 @@ usb:v046DpC226*
 usb:v046DpC227*
  ID_MODEL_FROM_DATABASE=G15 Refresh Keyboard
 
+usb:v046DpC228*
+ ID_MODEL_FROM_DATABASE=G19 Gaming Keyboard
+
+usb:v046DpC229*
+ ID_MODEL_FROM_DATABASE=G19 Gaming Keyboard Macro Interface
+
 usb:v046DpC22A*
  ID_MODEL_FROM_DATABASE=Gaming Keyboard G110
 
@@ -7466,6 +7652,18 @@ usb:v046DpC245*
 usb:v046DpC246*
  ID_MODEL_FROM_DATABASE=Gaming Mouse G300
 
+usb:v046DpC248*
+ ID_MODEL_FROM_DATABASE=G105 Gaming Keyboard
+
+usb:v046DpC24A*
+ ID_MODEL_FROM_DATABASE=G600 Gaming Mouse
+
+usb:v046DpC24D*
+ ID_MODEL_FROM_DATABASE=G710 Gaming Keyboard
+
+usb:v046DpC24E*
+ ID_MODEL_FROM_DATABASE=G500s Laser Gaming Mouse
+
 usb:v046DpC281*
  ID_MODEL_FROM_DATABASE=WingMan Force
 
@@ -7578,7 +7776,7 @@ usb:v046DpC31B*
  ID_MODEL_FROM_DATABASE=Compact Keyboard K300
 
 usb:v046DpC31C*
- ID_MODEL_FROM_DATABASE=Keyboard K120 for Business
+ ID_MODEL_FROM_DATABASE=Keyboard K120
 
 usb:v046DpC31D*
  ID_MODEL_FROM_DATABASE=Media Keyboard K200
@@ -7679,6 +7877,9 @@ usb:v046DpC529*
 usb:v046DpC52B*
  ID_MODEL_FROM_DATABASE=Unifying Receiver
 
+usb:v046DpC52D*
+ ID_MODEL_FROM_DATABASE=R700 Remote Presenter receiver
+
 usb:v046DpC52E*
  ID_MODEL_FROM_DATABASE=MK260 Wireless Combo Receiver
 
@@ -7688,6 +7889,21 @@ usb:v046DpC52F*
 usb:v046DpC532*
  ID_MODEL_FROM_DATABASE=Unifying Receiver
 
+usb:v046DpC534*
+ ID_MODEL_FROM_DATABASE=Unifying Receiver
+
+usb:v046DpC603*
+ ID_MODEL_FROM_DATABASE=3Dconnexion Spacemouse Plus XT
+
+usb:v046DpC605*
+ ID_MODEL_FROM_DATABASE=3Dconnexion CADman
+
+usb:v046DpC606*
+ ID_MODEL_FROM_DATABASE=3Dconnexion Spacemouse Classic
+
+usb:v046DpC621*
+ ID_MODEL_FROM_DATABASE=3Dconnexion Spaceball 5000
+
 usb:v046DpC623*
  ID_MODEL_FROM_DATABASE=3Dconnexion Space Traveller 3D Mouse
 
@@ -7700,9 +7916,18 @@ usb:v046DpC626*
 usb:v046DpC627*
  ID_MODEL_FROM_DATABASE=3Dconnexion Space Explorer 3D Mouse
 
+usb:v046DpC628*
+ ID_MODEL_FROM_DATABASE=3Dconnexion Space Navigator for Notebooks
+
 usb:v046DpC629*
  ID_MODEL_FROM_DATABASE=3Dconnexion SpacePilot Pro 3D Mouse
 
+usb:v046DpC62B*
+ ID_MODEL_FROM_DATABASE=3Dconnexion Space Mouse Pro
+
+usb:v046DpC640*
+ ID_MODEL_FROM_DATABASE=NuLOOQ navigator
+
 usb:v046DpC702*
  ID_MODEL_FROM_DATABASE=Cordless Presenter
 
@@ -8537,12 +8762,24 @@ usb:v0480p0011*
 usb:v0480p0014*
  ID_MODEL_FROM_DATABASE=InTouch Module
 
+usb:v0480p0100*
+ ID_MODEL_FROM_DATABASE=Stor.E Slim USB 3.0
+
 usb:v0480pA006*
  ID_MODEL_FROM_DATABASE=External Disk 1.5TB
 
 usb:v0480pA007*
  ID_MODEL_FROM_DATABASE=External Disk USB 3.0
 
+usb:v0480pA009*
+ ID_MODEL_FROM_DATABASE=Stor.E Basics
+
+usb:v0480pA00D*
+ ID_MODEL_FROM_DATABASE=STOR.E BASICS 500GB
+
+usb:v0480pB001*
+ ID_MODEL_FROM_DATABASE=Stor.E Partner
+
 usb:v0480pD010*
  ID_MODEL_FROM_DATABASE=External Disk 3TB
 
@@ -9968,6 +10205,9 @@ usb:v04A9p2225*
 usb:v04A9p2228*
  ID_MODEL_FROM_DATABASE=CanoScan 4400F
 
+usb:v04A9p2229*
+ ID_MODEL_FROM_DATABASE=CanoScan 8600F
+
 usb:v04A9p2602*
  ID_MODEL_FROM_DATABASE=MultiPASS C555
 
@@ -10745,6 +10985,9 @@ usb:v04A9p3196*
 usb:v04A9p319A*
  ID_MODEL_FROM_DATABASE=EOS 7D
 
+usb:v04A9p319B*
+ ID_MODEL_FROM_DATABASE=EOS 50D
+
 usb:v04A9p31AA*
  ID_MODEL_FROM_DATABASE=SELPHY CP770
 
@@ -10814,6 +11057,9 @@ usb:v04A9p31E5*
 usb:v04A9p31E6*
  ID_MODEL_FROM_DATABASE=PowerShot SD940 IS DIGITAL ELPH / Digital IXUS 120 IS / IXY DIGITAL 220 IS
 
+usb:v04A9p31E7*
+ ID_MODEL_FROM_DATABASE=SELPHY CP790
+
 usb:v04A9p31EA*
  ID_MODEL_FROM_DATABASE=EOS Rebel T2i / EOS 550D / EOS Kiss X4
 
@@ -10910,6 +11156,9 @@ usb:v04A9p3233*
 usb:v04A9p3234*
  ID_MODEL_FROM_DATABASE=PowerShot SX150 IS
 
+usb:v04A9p3235*
+ ID_MODEL_FROM_DATABASE=PowerShot ELPH 510 HS / IXUS 1100 HS
+
 usb:v04A9p3236*
  ID_MODEL_FROM_DATABASE=PowerShot S100
 
@@ -10979,12 +11228,24 @@ usb:v04A9p325B*
 usb:v04A9p325C*
  ID_MODEL_FROM_DATABASE=PowerShot SX500 IS
 
+usb:v04A9p325E*
+ ID_MODEL_FROM_DATABASE=PowerShot N
+
 usb:v04A9p325F*
  ID_MODEL_FROM_DATABASE=PowerShot SX280 HS
 
 usb:v04A9p3260*
  ID_MODEL_FROM_DATABASE=PowerShot SX270 HS
 
+usb:v04A9p3261*
+ ID_MODEL_FROM_DATABASE=PowerShot A3500 IS
+
+usb:v04A9p3262*
+ ID_MODEL_FROM_DATABASE=PowerShot A2600
+
+usb:v04A9p3263*
+ ID_MODEL_FROM_DATABASE=PowerShot SX275 HS
+
 usb:v04A9p3264*
  ID_MODEL_FROM_DATABASE=PowerShot A1400
 
@@ -11000,9 +11261,33 @@ usb:v04A9p3271*
 usb:v04A9p3276*
  ID_MODEL_FROM_DATABASE=PowerShot SX170 IS
 
+usb:v04A9p3277*
+ ID_MODEL_FROM_DATABASE=PowerShot SX510 HS
+
+usb:v04A9p3278*
+ ID_MODEL_FROM_DATABASE=PowerShot S200
+
 usb:v04A9p327D*
  ID_MODEL_FROM_DATABASE=Powershot ELPH 115 IS / IXUS 132
 
+usb:v04A9p327F*
+ ID_MODEL_FROM_DATABASE=EOS Rebel T5 / EOS 1200D / EOS Kiss X70
+
+usb:v04A9p3284*
+ ID_MODEL_FROM_DATABASE=PowerShot D30
+
+usb:v04A9p3286*
+ ID_MODEL_FROM_DATABASE=PowerShot SX600 HS
+
+usb:v04A9p3288*
+ ID_MODEL_FROM_DATABASE=Powershot ELPH 135 / IXUS 145
+
+usb:v04A9p3289*
+ ID_MODEL_FROM_DATABASE=PowerShot ELPH 340 HS / IXUS 265 HS
+
+usb:v04A9p328A*
+ ID_MODEL_FROM_DATABASE=PowerShot ELPH 150 IS / IXUS 155
+
 usb:v04AA*
  ID_VENDOR_FROM_DATABASE=DaeWoo Telecom, Ltd
 
@@ -11312,6 +11597,9 @@ usb:v04B3p4482*
 usb:v04B3p4485*
  ID_MODEL_FROM_DATABASE=Serial Converter
 
+usb:v04B3p4524*
+ ID_MODEL_FROM_DATABASE=40 Character Vacuum Fluorescent Display
+
 usb:v04B3p4525*
  ID_MODEL_FROM_DATABASE=Double sided CRT
 
@@ -11384,6 +11672,12 @@ usb:v04B4p2050*
 usb:v04B4p2830*
  ID_MODEL_FROM_DATABASE=Opera1 DVB-S (cold state)
 
+usb:v04B4p3813*
+ ID_MODEL_FROM_DATABASE=NANO BIOS Programmer
+
+usb:v04B4p4235*
+ ID_MODEL_FROM_DATABASE=Monitor 02 Driver
+
 usb:v04B4p4381*
  ID_MODEL_FROM_DATABASE=SCAPS USC-1 Scanner Controller
 
@@ -12320,6 +12614,9 @@ usb:v04C5p10AE*
 usb:v04C5p10AF*
  ID_MODEL_FROM_DATABASE=fi-4220C2
 
+usb:v04C5p10C7*
+ ID_MODEL_FROM_DATABASE=fi-60f scanner
+
 usb:v04C5p10E0*
  ID_MODEL_FROM_DATABASE=fi-5120c Scanner
 
@@ -12335,6 +12632,9 @@ usb:v04C5p10FE*
 usb:v04C5p1150*
  ID_MODEL_FROM_DATABASE=fi-6230
 
+usb:v04C5p201D*
+ ID_MODEL_FROM_DATABASE=SATA 3.0 6Gbit/s Adaptor [GROOVY]
+
 usb:v04C6*
  ID_VENDOR_FROM_DATABASE=Toshiba America Electronic Components
 
@@ -12374,6 +12674,9 @@ usb:v04C8p072D*
 usb:v04CA*
  ID_VENDOR_FROM_DATABASE=Lite-On Technology Corp.
 
+usb:v04CAp004F*
+ ID_MODEL_FROM_DATABASE=SK-9020 keyboard
+
 usb:v04CAp1766*
  ID_MODEL_FROM_DATABASE=HID Monitor Controls
 
@@ -12800,6 +13103,9 @@ usb:v04D8p0036*
 usb:v04D8p00E0*
  ID_MODEL_FROM_DATABASE=PIC32 Starter Board
 
+usb:v04D8p04CD*
+ ID_MODEL_FROM_DATABASE=28Cxxx EEPROM Programmer
+
 usb:v04D8p0A04*
  ID_MODEL_FROM_DATABASE=AGP LIN Serial Analyzer
 
@@ -12824,9 +13130,15 @@ usb:v04D8p900A*
 usb:v04D8pC001*
  ID_MODEL_FROM_DATABASE=PicoLCD 20x4
 
+usb:v04D8pF4B5*
+ ID_MODEL_FROM_DATABASE=SmartScope
+
 usb:v04D8pF8DA*
  ID_MODEL_FROM_DATABASE=Hughski Ltd. ColorHug
 
+usb:v04D8pF91C*
+ ID_MODEL_FROM_DATABASE=SPROG IIv3
+
 usb:v04D8pFAFF*
  ID_MODEL_FROM_DATABASE=Dangerous Prototypes BusPirate v4 Bootloader mode
 
@@ -12842,6 +13154,9 @@ usb:v04D8pFBBA*
 usb:v04D8pFBBB*
  ID_MODEL_FROM_DATABASE=DiscFerret Magnetic Disc Analyser (active mode)
 
+usb:v04D8pFC1E*
+ ID_MODEL_FROM_DATABASE=Bachrus Speedometer Interface
+
 usb:v04D8pFC92*
  ID_MODEL_FROM_DATABASE=Open Bench Logic Sniffer
 
@@ -12888,7 +13203,7 @@ usb:v04D9p2519*
  ID_MODEL_FROM_DATABASE=Shenzhen LogoTech 2.4GHz receiver
 
 usb:v04D9p2832*
- ID_MODEL_FROM_DATABASE=1channel Telephone line recorder
+ ID_MODEL_FROM_DATABASE=HT82A832R Audio MCU
 
 usb:v04D9p2834*
  ID_MODEL_FROM_DATABASE=HT82A834R Audio MCU
@@ -12977,6 +13292,9 @@ usb:v04DAp2374*
 usb:v04DAp2451*
  ID_MODEL_FROM_DATABASE=HDC-SD9
 
+usb:v04DAp245B*
+ ID_MODEL_FROM_DATABASE=HC-X920K (3MOS Full HD video camcorder)
+
 usb:v04DAp2497*
  ID_MODEL_FROM_DATABASE=HDC-TM700
 
@@ -13346,6 +13664,9 @@ usb:v04E6p5292*
 usb:v04E6p5410*
  ID_MODEL_FROM_DATABASE=SCR35xx Smart Card Reader
 
+usb:v04E6p5591*
+ ID_MODEL_FROM_DATABASE=SCL3711-NFC&RW
+
 usb:v04E6pE000*
  ID_MODEL_FROM_DATABASE=SCRx31 Reader
 
@@ -13439,6 +13760,9 @@ usb:v04E8p1006*
 usb:v04E8p130C*
  ID_MODEL_FROM_DATABASE=NX100
 
+usb:v04E8p1F05*
+ ID_MODEL_FROM_DATABASE=S2 Portable [JMicron] (500GB)
+
 usb:v04E8p1F06*
  ID_MODEL_FROM_DATABASE=HX-MU064DA portable harddisk
 
@@ -13574,6 +13898,9 @@ usb:v04E8p3310*
 usb:v04E8p3315*
  ID_MODEL_FROM_DATABASE=ML-2540 Series Laser Printer
 
+usb:v04E8p331E*
+ ID_MODEL_FROM_DATABASE=M262x/M282x Xpress Series Laser Printer
+
 usb:v04E8p3409*
  ID_MODEL_FROM_DATABASE=SCX-4216F Scanner
 
@@ -13622,6 +13949,9 @@ usb:v04E8p3420*
 usb:v04E8p3426*
  ID_MODEL_FROM_DATABASE=SCX-4500 Laser Printer
 
+usb:v04E8p342D*
+ ID_MODEL_FROM_DATABASE=SCX-4x28 Series
+
 usb:v04E8p344F*
  ID_MODEL_FROM_DATABASE=SCX-3400 Series
 
@@ -13838,6 +14168,9 @@ usb:v04E8p5F05*
 usb:v04E8p6032*
  ID_MODEL_FROM_DATABASE=G2 Portable hard drive
 
+usb:v04E8p6033*
+ ID_MODEL_FROM_DATABASE=G2 Portable device
+
 usb:v04E8p6034*
  ID_MODEL_FROM_DATABASE=G2 Portable hard drive
 
@@ -13847,6 +14180,9 @@ usb:v04E8p60B3*
 usb:v04E8p60C4*
  ID_MODEL_FROM_DATABASE=M2 Portable Hard Drive USB 3.0
 
+usb:v04E8p6124*
+ ID_MODEL_FROM_DATABASE=D3 Station External Hard Drive
+
 usb:v04E8p61B6*
  ID_MODEL_FROM_DATABASE=M3 Portable Hard Drive 1TB
 
@@ -13962,7 +14298,7 @@ usb:v04E8p685B*
  ID_MODEL_FROM_DATABASE=GT-I9100 Phone [Galaxy S II] (mass storage mode)
 
 usb:v04E8p685C*
- ID_MODEL_FROM_DATABASE=GT-I9250 Phone [Galaxy Nexus]
+ ID_MODEL_FROM_DATABASE=GT-I9250 Phone [Galaxy Nexus] (Mass storage mode)
 
 usb:v04E8p685D*
  ID_MODEL_FROM_DATABASE=GT-I9100 Phone [Galaxy S II] (Download mode)
@@ -13971,7 +14307,10 @@ usb:v04E8p685E*
  ID_MODEL_FROM_DATABASE=GT-I9100 / GT-C3350 Phones (USB Debugging mode)
 
 usb:v04E8p6860*
- ID_MODEL_FROM_DATABASE=GT-I9100 Phone [Galaxy S II], GT-I9300 Phone [Galaxy S III], GT-P7500 [Galaxy Tab 10.1]
+ ID_MODEL_FROM_DATABASE=GT-I9100 Phone [Galaxy S II], GT-I9300 Phone [Galaxy S III], GT-P7500 [Galaxy Tab 10.1] , GT-I9500 [Galaxy S 4]
+
+usb:v04E8p6863*
+ ID_MODEL_FROM_DATABASE=GT-I9500 [Galaxy S4] / GT-I9250 [Galaxy Nexus] (network tethering)
 
 usb:v04E8p6865*
  ID_MODEL_FROM_DATABASE=GT-I9300 Phone [Galaxy S III] (PTP mode)
@@ -13979,6 +14318,9 @@ usb:v04E8p6865*
 usb:v04E8p6866*
  ID_MODEL_FROM_DATABASE=GT-I9300 Phone [Galaxy S III] (debugging mode)
 
+usb:v04E8p6868*
+ ID_MODEL_FROM_DATABASE=Escape Composite driver for Android Phones: Modem+Diagnostic+ADB
+
 usb:v04E8p6875*
  ID_MODEL_FROM_DATABASE=GT-B3710 Standalone LTE device (Commercial)
 
@@ -14129,6 +14471,9 @@ usb:v04F2p0403*
 usb:v04F2p0418*
  ID_MODEL_FROM_DATABASE=KU-0418 Tactical Pad
 
+usb:v04F2p0618*
+ ID_MODEL_FROM_DATABASE=RG-0618U Wireless HID Receiver & KG-0609 Wireless Keyboard with Touchpad
+
 usb:v04F2p0760*
  ID_MODEL_FROM_DATABASE=Acer KU-0760 Keyboard
 
@@ -14138,6 +14483,9 @@ usb:v04F2p0841*
 usb:v04F2p0860*
  ID_MODEL_FROM_DATABASE=2.4G Multimedia Wireless Kit
 
+usb:v04F2p1121*
+ ID_MODEL_FROM_DATABASE=Periboard 717 Mini Wireless Keyboard
+
 usb:v04F2pA001*
  ID_MODEL_FROM_DATABASE=E-Video DC-100 Camera
 
@@ -14243,6 +14591,12 @@ usb:v04F2pB057*
 usb:v04F2pB059*
  ID_MODEL_FROM_DATABASE=CKF7037 HP webcam
 
+usb:v04F2pB064*
+ ID_MODEL_FROM_DATABASE=CNA7137 Integrated Webcam
+
+usb:v04F2pB070*
+ ID_MODEL_FROM_DATABASE=Camera
+
 usb:v04F2pB071*
  ID_MODEL_FROM_DATABASE=2.0M UVC Webcam / CNF7129
 
@@ -14312,6 +14666,9 @@ usb:v04F2pB2B0*
 usb:v04F2pB2B9*
  ID_MODEL_FROM_DATABASE=Lenovo Integrated Camera UVC
 
+usb:v04F2pB2DA*
+ ID_MODEL_FROM_DATABASE=thinkpad t430s camera
+
 usb:v04F2pB2EA*
  ID_MODEL_FROM_DATABASE=Integrated Camera [ThinkPad]
 
@@ -14321,6 +14678,9 @@ usb:v04F2pB330*
 usb:v04F2pB354*
  ID_MODEL_FROM_DATABASE=UVC 1.00 device HD UVC WebCam
 
+usb:v04F2pB394*
+ ID_MODEL_FROM_DATABASE=Integrated Camera
+
 usb:v04F3*
  ID_VENDOR_FROM_DATABASE=Elan Microelectronics Corp.
 
@@ -14939,12 +15299,18 @@ usb:v04F9p01EB*
 usb:v04F9p01F4*
  ID_MODEL_FROM_DATABASE=MFC-5890CN
 
+usb:v04F9p0217*
+ ID_MODEL_FROM_DATABASE=MFC-8480DN
+
 usb:v04F9p0223*
  ID_MODEL_FROM_DATABASE=DCP-365CN
 
 usb:v04F9p0248*
  ID_MODEL_FROM_DATABASE=DCP-7055 scanner/printer
 
+usb:v04F9p02B3*
+ ID_MODEL_FROM_DATABASE=MFC J4510DW
+
 usb:v04F9p1000*
  ID_MODEL_FROM_DATABASE=Printer
 
@@ -15012,7 +15378,7 @@ usb:v04FCp0171*
  ID_MODEL_FROM_DATABASE=SPCA1527A/SPCA1528 SD card camera (Mass Storage mode)
 
 usb:v04FCp0201*
- ID_MODEL_FROM_DATABASE=RS232C Adapter
+ ID_MODEL_FROM_DATABASE=SPCP825 RS232C Adapter
 
 usb:v04FCp0232*
  ID_MODEL_FROM_DATABASE=Fingerprint
@@ -15059,9 +15425,15 @@ usb:v04FCp5331*
 usb:v04FCp5360*
  ID_MODEL_FROM_DATABASE=Sunplus Generic Digital Camera
 
+usb:v04FCp5563*
+ ID_MODEL_FROM_DATABASE=Digital Media Player MP3/WMA [The Sharper Image]
+
 usb:v04FCp5720*
  ID_MODEL_FROM_DATABASE=Card Reader Driver
 
+usb:v04FCp6333*
+ ID_MODEL_FROM_DATABASE=Siri A9 UVC chipset
+
 usb:v04FCp7333*
  ID_MODEL_FROM_DATABASE=Finet Technology Palmpix DC-85
 
@@ -15140,6 +15512,18 @@ usb:v0502p3325*
 usb:v0502p3341*
  ID_MODEL_FROM_DATABASE=Iconia tablet A500
 
+usb:v0502p33C3*
+ ID_MODEL_FROM_DATABASE=Liquid Gallant Duo E350
+
+usb:v0502p33C4*
+ ID_MODEL_FROM_DATABASE=Liquid Gallant Duo E350 (debug mode)
+
+usb:v0502p33C7*
+ ID_MODEL_FROM_DATABASE=Liquid Gallant Duo E350 (USB tethering)
+
+usb:v0502p33C8*
+ ID_MODEL_FROM_DATABASE=Liquid Gallant Duo E350 (debug mode, USB tethering)
+
 usb:v0502pD001*
  ID_MODEL_FROM_DATABASE=Divio NW801/DVC-V6+ Digital Camera
 
@@ -15249,7 +15633,7 @@ usb:v050Dp0013*
  ID_MODEL_FROM_DATABASE=F8T013 Bluetooth Adapter
 
 usb:v050Dp0017*
- ID_MODEL_FROM_DATABASE=B8T017 Bluetooth+EDR 2.1
+ ID_MODEL_FROM_DATABASE=B8T017 Bluetooth+EDR 2.1 / F4U017 USB 2.0 7-port Hub
 
 usb:v050Dp003A*
  ID_MODEL_FROM_DATABASE=Universal Media Reader
@@ -15347,6 +15731,9 @@ usb:v050Dp0416*
 usb:v050Dp0551*
  ID_MODEL_FROM_DATABASE=F6C550-AVR UPS
 
+usb:v050Dp065A*
+ ID_MODEL_FROM_DATABASE=F8T065BF Mini Bluetooth 4.0 Adapter
+
 usb:v050Dp0706*
  ID_MODEL_FROM_DATABASE=2-N-1 7-Port Hub (Lower half)
 
@@ -15383,6 +15770,9 @@ usb:v050Dp1106*
 usb:v050Dp1109*
  ID_MODEL_FROM_DATABASE=F9L1109v1 802.11a/b/g/n/ac Wireless Adapter [Realtek RTL8812AU]
 
+usb:v050Dp110A*
+ ID_MODEL_FROM_DATABASE=F9L1101v2 802.11abgn Wireless Adapter [Realtek RTL8192DU]
+
 usb:v050Dp11F2*
  ID_MODEL_FROM_DATABASE=ISY Wireless Micro Adapter IWL 2000 [RTL8188CUS]
 
@@ -15398,6 +15788,9 @@ usb:v050Dp2103*
 usb:v050Dp21F1*
  ID_MODEL_FROM_DATABASE=N300 WLAN N Adapter [ISY]
 
+usb:v050Dp21F2*
+ ID_MODEL_FROM_DATABASE=RTL8192CU 802.11n WLAN Adapter [ISY IWL 4000]
+
 usb:v050Dp258A*
  ID_MODEL_FROM_DATABASE=F5U258 Host to Host cable
 
@@ -15420,7 +15813,7 @@ usb:v050Dp6051*
  ID_MODEL_FROM_DATABASE=F5D6051 802.11b Wireless Network Adapter [ZyDAS ZD1201]
 
 usb:v050Dp615A*
- ID_MODEL_FROM_DATABASE=F7D4101 / F9L1101 802.11abgn Wireless Adapter [Broadcom BCM4323]
+ ID_MODEL_FROM_DATABASE=F7D4101 / F9L1101v1 802.11abgn Wireless Adapter [Broadcom BCM4323]
 
 usb:v050Dp7050*
  ID_MODEL_FROM_DATABASE=F5D7050 Wireless G Adapter v1000/v2000 [Intersil ISL3887]
@@ -15629,6 +16022,9 @@ usb:v0525p1200*
 usb:v0525p1265*
  ID_MODEL_FROM_DATABASE=File-backed Storage Gadget
 
+usb:v0525p3424*
+ ID_MODEL_FROM_DATABASE=Lumidigm Venus fingerprint sensor
+
 usb:v0525pA0F0*
  ID_MODEL_FROM_DATABASE=Cambridge Electronic Devices Power1401 mk 2
 
@@ -16052,6 +16448,9 @@ usb:v0547p2810*
 usb:v0547p4D90*
  ID_MODEL_FROM_DATABASE=AmScope MD1900 camera
 
+usb:v0547p7000*
+ ID_MODEL_FROM_DATABASE=PowerSpec MCE460 Front Panel LED Display
+
 usb:v0547p7777*
  ID_MODEL_FROM_DATABASE=Bluetooth Device
 
@@ -16556,6 +16955,9 @@ usb:v054Cp035B*
 usb:v054Cp035C*
  ID_MODEL_FROM_DATABASE=NWZ-A726/A728/A729
 
+usb:v054Cp035F*
+ ID_MODEL_FROM_DATABASE=UP-DR200 Photo Printer
+
 usb:v054Cp0382*
  ID_MODEL_FROM_DATABASE=Memory Stick PRO-HG Duo Adaptor (MSAC-UAH1)
 
@@ -16595,9 +16997,18 @@ usb:v054Cp0485*
 usb:v054Cp04CB*
  ID_MODEL_FROM_DATABASE=WALKMAN NWZ-E354
 
+usb:v054Cp0541*
+ ID_MODEL_FROM_DATABASE=DSC-HX100V [Cybershot Digital Still Camera]
+
+usb:v054Cp0689*
+ ID_MODEL_FROM_DATABASE=Walkman NWZ-B173F
+
 usb:v054Cp06BB*
  ID_MODEL_FROM_DATABASE=WALKMAN NWZ-F805
 
+usb:v054Cp088C*
+ ID_MODEL_FROM_DATABASE=Portable Headphone Amplifier
+
 usb:v054Cp1000*
  ID_MODEL_FROM_DATABASE=Wireless Buzz! Receiver
 
@@ -16622,6 +17033,12 @@ usb:v0550p0004*
 usb:v0550p0005*
  ID_MODEL_FROM_DATABASE=InkJet Color Printer
 
+usb:v0550p000B*
+ ID_MODEL_FROM_DATABASE=Workcentre 24
+
+usb:v0550p014E*
+ ID_MODEL_FROM_DATABASE=CM215b Printer
+
 usb:v0551*
  ID_VENDOR_FROM_DATABASE=CompuTrend Systems, Inc.
 
@@ -17207,6 +17624,9 @@ usb:v056Ap0069*
 usb:v056Ap0081*
  ID_MODEL_FROM_DATABASE=Graphire Wireless 6x8
 
+usb:v056Ap0084*
+ ID_MODEL_FROM_DATABASE=Wireless adapter for Bamboo tablets
+
 usb:v056Ap0090*
  ID_MODEL_FROM_DATABASE=TPC90
 
@@ -17273,6 +17693,9 @@ usb:v056Ap00D1*
 usb:v056Ap00D3*
  ID_MODEL_FROM_DATABASE=Bamboo Fun (CTH-661)
 
+usb:v056Ap00D4*
+ ID_MODEL_FROM_DATABASE=Bamboo Pen (CTL-460)
+
 usb:v056Ap00D6*
  ID_MODEL_FROM_DATABASE=Bamboo Pen & Touch (CTH-460)
 
@@ -17291,6 +17714,12 @@ usb:v056Ap00F6*
 usb:v056Ap00F8*
  ID_MODEL_FROM_DATABASE=Cintiq 24HD touch (DTH-2400) tablet
 
+usb:v056Ap0307*
+ ID_MODEL_FROM_DATABASE=Cintiq Companion Hybrid 13HD (DTH-A1300) tablet
+
+usb:v056Ap0309*
+ ID_MODEL_FROM_DATABASE=Cintiq Companion Hybrid 13HD (DTH-A1300) touchscreen
+
 usb:v056Ap0400*
  ID_MODEL_FROM_DATABASE=PenPartner 4x5
 
@@ -18620,6 +19049,9 @@ usb:v0586p341E*
 usb:v0586p341F*
  ID_MODEL_FROM_DATABASE=NWD2205 802.11n Wireless N Adapter [Realtek RTL8192CU]
 
+usb:v0586p3425*
+ ID_MODEL_FROM_DATABASE=NWD6505 802.11a/b/g/n/ac Wireless Adapter [MediaTek MT7610U]
+
 usb:v0586p343E*
  ID_MODEL_FROM_DATABASE=N220 802.11bgn Wireless Adapter
 
@@ -18638,9 +19070,15 @@ usb:v058A*
 usb:v058B*
  ID_VENDOR_FROM_DATABASE=Infineon Technologies
 
+usb:v058Bp0015*
+ ID_MODEL_FROM_DATABASE=Flash Loader utility
+
 usb:v058Bp001C*
  ID_MODEL_FROM_DATABASE=Flash Drive
 
+usb:v058Bp0041*
+ ID_MODEL_FROM_DATABASE=Flash Loader utility
+
 usb:v058C*
  ID_VENDOR_FROM_DATABASE=In Focus Systems
 
@@ -18756,7 +19194,7 @@ usb:v058Fp6366*
  ID_MODEL_FROM_DATABASE=Multi Flash Reader
 
 usb:v058Fp6377*
- ID_MODEL_FROM_DATABASE=Multimedia Card Reader
+ ID_MODEL_FROM_DATABASE=AU6375 4-LUN card reader
 
 usb:v058Fp6386*
  ID_MODEL_FROM_DATABASE=Memory Card
@@ -18827,12 +19265,18 @@ usb:v058Fp9510*
 usb:v058Fp9520*
  ID_MODEL_FROM_DATABASE=EMV Certified Smart Card Reader
 
+usb:v058Fp9540*
+ ID_MODEL_FROM_DATABASE=AU9540 Smartcard Reader
+
 usb:v058Fp9720*
  ID_MODEL_FROM_DATABASE=USB-Serial Adapter
 
 usb:v058FpA014*
  ID_MODEL_FROM_DATABASE=Asus Integrated Webcam
 
+usb:v058FpB002*
+ ID_MODEL_FROM_DATABASE=Acer Integrated Webcam
+
 usb:v0590*
  ID_VENDOR_FROM_DATABASE=Omron Corp.
 
@@ -18884,6 +19328,9 @@ usb:v0596p0002*
 usb:v0596p0500*
  ID_MODEL_FROM_DATABASE=PCT Multitouch HID Controller
 
+usb:v0596p0543*
+ ID_MODEL_FROM_DATABASE=DELL XPS touchscreen
+
 usb:v0597*
  ID_VENDOR_FROM_DATABASE=Trisignal Communications
 
@@ -18956,6 +19403,9 @@ usb:v059Bp0061*
 usb:v059Bp006D*
  ID_MODEL_FROM_DATABASE=HipZip MP3 Player
 
+usb:v059Bp0070*
+ ID_MODEL_FROM_DATABASE=eGo Portable Hard Drive
+
 usb:v059Bp007C*
  ID_MODEL_FROM_DATABASE=Ultra Max USB/1394
 
@@ -19064,9 +19514,15 @@ usb:v059Fp0323*
 usb:v059Fp0421*
  ID_MODEL_FROM_DATABASE=Big Disk G465
 
+usb:v059Fp0525*
+ ID_MODEL_FROM_DATABASE=BigDisk Extreme 500
+
 usb:v059Fp0641*
  ID_MODEL_FROM_DATABASE=Mobile Hard Drive
 
+usb:v059Fp0829*
+ ID_MODEL_FROM_DATABASE=BigDisk Extreme+
+
 usb:v059Fp100C*
  ID_MODEL_FROM_DATABASE=Rugged Triple Interface Mobile Hard Drive
 
@@ -19091,6 +19547,9 @@ usb:v059Fp1049*
 usb:v059Fp1052*
  ID_MODEL_FROM_DATABASE=P'9220 Mobile Drive
 
+usb:v059Fp1064*
+ ID_MODEL_FROM_DATABASE=Rugged 16 and 32 GB
+
 usb:v059FpA601*
  ID_MODEL_FROM_DATABASE=HardDrive
 
@@ -19365,7 +19824,7 @@ usb:v05ACp0225*
  ID_MODEL_FROM_DATABASE=Internal Keyboard/Trackpad (JIS)
 
 usb:v05ACp0229*
- ID_MODEL_FROM_DATABASE=Internal Keyboard/Trackpad (MacBook Pro) (ANSI)
+ ID_MODEL_FROM_DATABASE=Internal Keyboard/Trackpad (ANSI)
 
 usb:v05ACp022A*
  ID_MODEL_FROM_DATABASE=Internal Keyboard/Trackpad (MacBook Pro) (ISO)
@@ -19446,7 +19905,7 @@ usb:v05ACp0302*
  ID_MODEL_FROM_DATABASE=Optical Mouse [Fujitsu]
 
 usb:v05ACp0304*
- ID_MODEL_FROM_DATABASE=Optical USB Mouse [Mitsumi]
+ ID_MODEL_FROM_DATABASE=Mighty Mouse [Mitsumi, M1152]
 
 usb:v05ACp0306*
  ID_MODEL_FROM_DATABASE=Optical USB Mouse [Fujitsu]
@@ -19478,6 +19937,9 @@ usb:v05ACp1003*
 usb:v05ACp1006*
  ID_MODEL_FROM_DATABASE=Hub in Aluminum Keyboard
 
+usb:v05ACp1008*
+ ID_MODEL_FROM_DATABASE=Mini DisplayPort to Dual-Link DVI Adapter
+
 usb:v05ACp1101*
  ID_MODEL_FROM_DATABASE=Speakers
 
@@ -19571,6 +20033,9 @@ usb:v05ACp1265*
 usb:v05ACp1266*
  ID_MODEL_FROM_DATABASE=iPod Nano 6.Gen
 
+usb:v05ACp1267*
+ ID_MODEL_FROM_DATABASE=iPod Nano 7.Gen
+
 usb:v05ACp1281*
  ID_MODEL_FROM_DATABASE=Apple Mobile Device [Recovery Mode]
 
@@ -19601,6 +20066,9 @@ usb:v05ACp1299*
 usb:v05ACp129A*
  ID_MODEL_FROM_DATABASE=iPad
 
+usb:v05ACp129C*
+ ID_MODEL_FROM_DATABASE=iPhone 4(CDMA)
+
 usb:v05ACp129E*
  ID_MODEL_FROM_DATABASE=iPod Touch 4.Gen
 
@@ -19613,15 +20081,30 @@ usb:v05ACp12A0*
 usb:v05ACp12A2*
  ID_MODEL_FROM_DATABASE=iPad 2 (3G; 64GB)
 
+usb:v05ACp12A3*
+ ID_MODEL_FROM_DATABASE=iPad 2 (CDMA)
+
+usb:v05ACp12A4*
+ ID_MODEL_FROM_DATABASE=iPad 3 (wifi)
+
+usb:v05ACp12A5*
+ ID_MODEL_FROM_DATABASE=iPad 3 (CDMA)
+
 usb:v05ACp12A6*
  ID_MODEL_FROM_DATABASE=iPad 3 (3G, 16 GB)
 
+usb:v05ACp12A8*
+ ID_MODEL_FROM_DATABASE=iPhone5/5C/5S
+
 usb:v05ACp12A9*
  ID_MODEL_FROM_DATABASE=iPad 2
 
 usb:v05ACp12AA*
  ID_MODEL_FROM_DATABASE=iPod Touch 5.Gen [A1421]
 
+usb:v05ACp12AB*
+ ID_MODEL_FROM_DATABASE=iPad 4 (WiFi, 32GB)
+
 usb:v05ACp1300*
  ID_MODEL_FROM_DATABASE=iPod Shuffle
 
@@ -19643,6 +20126,15 @@ usb:v05ACp1402*
 usb:v05ACp1500*
  ID_MODEL_FROM_DATABASE=SuperDrive [A1379]
 
+usb:v05ACp8005*
+ ID_MODEL_FROM_DATABASE=OHCI Root Hub Simulation
+
+usb:v05ACp8006*
+ ID_MODEL_FROM_DATABASE=EHCI Root Hub Simulation
+
+usb:v05ACp8007*
+ ID_MODEL_FROM_DATABASE=XHCI Root Hub USB 2.0 Simulation
+
 usb:v05ACp8202*
  ID_MODEL_FROM_DATABASE=HCF V.90 Data/Fax Modem
 
@@ -19739,6 +20231,9 @@ usb:v05ACp8510*
 usb:v05ACp911C*
  ID_MODEL_FROM_DATABASE=Hub in A1082 [Cinema HD Display 23"]
 
+usb:v05ACp9127*
+ ID_MODEL_FROM_DATABASE=Hub in Thunderbolt Display
+
 usb:v05ACp912F*
  ID_MODEL_FROM_DATABASE=Hub in 30" Cinema Display
 
@@ -19943,6 +20438,9 @@ usb:v05C6p9202*
 usb:v05C6p9203*
  ID_MODEL_FROM_DATABASE=Gobi Wireless Modem
 
+usb:v05C6p9205*
+ ID_MODEL_FROM_DATABASE=Gobi 2000
+
 usb:v05C6p9211*
  ID_MODEL_FROM_DATABASE=Acer Gobi Wireless Modem (QDL mode)
 
@@ -20024,9 +20522,18 @@ usb:v05C8p021A*
 usb:v05C8p0318*
  ID_MODEL_FROM_DATABASE=Webcam
 
+usb:v05C8p0361*
+ ID_MODEL_FROM_DATABASE=SunplusIT INC. HP Truevision HD Webcam
+
+usb:v05C8p036E*
+ ID_MODEL_FROM_DATABASE=Webcam
+
 usb:v05C8p0403*
  ID_MODEL_FROM_DATABASE=Webcam
 
+usb:v05C8p041B*
+ ID_MODEL_FROM_DATABASE=HP 2.0MP High Definition Webcam
+
 usb:v05C9*
  ID_VENDOR_FROM_DATABASE=Semtech Corp.
 
@@ -20762,6 +21269,9 @@ usb:v05DCp4D12*
 usb:v05DCp4D30*
  ID_MODEL_FROM_DATABASE=MP3 Player
 
+usb:v05DCpA209*
+ ID_MODEL_FROM_DATABASE=JumpDrive S70
+
 usb:v05DCpA300*
  ID_MODEL_FROM_DATABASE=JumpDrive2
 
@@ -20822,6 +21332,9 @@ usb:v05DCpA701*
 usb:v05DCpA731*
  ID_MODEL_FROM_DATABASE=JumpDrive FireFly
 
+usb:v05DCpA768*
+ ID_MODEL_FROM_DATABASE=JumpDrive Retrax
+
 usb:v05DCpA790*
  ID_MODEL_FROM_DATABASE=JumpDrive 2GB
 
@@ -20831,6 +21344,9 @@ usb:v05DCpA811*
 usb:v05DCpA813*
  ID_MODEL_FROM_DATABASE=16gB flash thumb drive
 
+usb:v05DCpA815*
+ ID_MODEL_FROM_DATABASE=JumpDrive V10
+
 usb:v05DCpB002*
  ID_MODEL_FROM_DATABASE=USB CF Reader
 
@@ -20840,6 +21356,9 @@ usb:v05DCpB018*
 usb:v05DCpB047*
  ID_MODEL_FROM_DATABASE=SDHC Reader [RW047-7000]
 
+usb:v05DCpBA02*
+ ID_MODEL_FROM_DATABASE=Workflow CFR1
+
 usb:v05DCpC753*
  ID_MODEL_FROM_DATABASE=JumpDrive TwistTurn
 
@@ -20985,7 +21504,7 @@ usb:v05E3p0607*
  ID_MODEL_FROM_DATABASE=Logitech G110 Hub
 
 usb:v05E3p0608*
- ID_MODEL_FROM_DATABASE=USB-2.0 4-Port HUB
+ ID_MODEL_FROM_DATABASE=Hub
 
 usb:v05E3p0610*
  ID_MODEL_FROM_DATABASE=4-port hub
@@ -21059,6 +21578,9 @@ usb:v05E3p0718*
 usb:v05E3p0719*
  ID_MODEL_FROM_DATABASE=SATA adapter
 
+usb:v05E3p0722*
+ ID_MODEL_FROM_DATABASE=SD/MMC card reader
+
 usb:v05E3p0723*
  ID_MODEL_FROM_DATABASE=GL827L SD/MMC/MS Flash Card Reader
 
@@ -21071,9 +21593,18 @@ usb:v05E3p0727*
 usb:v05E3p0731*
  ID_MODEL_FROM_DATABASE=GL3310 SATA 3Gb/s Bridge Controller
 
+usb:v05E3p0732*
+ ID_MODEL_FROM_DATABASE=All-in-One Cardreader
+
 usb:v05E3p0736*
  ID_MODEL_FROM_DATABASE=microSD Reader/Writer
 
+usb:v05E3p0741*
+ ID_MODEL_FROM_DATABASE=microSD Card Reader
+
+usb:v05E3p0743*
+ ID_MODEL_FROM_DATABASE=SDXC and microSDXC CardReader
+
 usb:v05E3p0760*
  ID_MODEL_FROM_DATABASE=USB 2.0 Card Reader/Writer
 
@@ -21197,6 +21728,9 @@ usb:v05F3p0081*
 usb:v05F3p00FF*
  ID_MODEL_FROM_DATABASE=VEC Footpedal
 
+usb:v05F3p0203*
+ ID_MODEL_FROM_DATABASE=Y-mouse Keyboard & Mouse Adapter
+
 usb:v05F3p020B*
  ID_MODEL_FROM_DATABASE=PS2 Adapter
 
@@ -21236,6 +21770,9 @@ usb:v05F9p2601*
 usb:v05F9p2602*
  ID_MODEL_FROM_DATABASE=Datalogic Magellan 1100i Barcode Scanner
 
+usb:v05F9p4204*
+ ID_MODEL_FROM_DATABASE=Datalogic Gryphon GFS4470 Fixed Scanner
+
 usb:v05F9p5204*
  ID_MODEL_FROM_DATABASE=Datalogic Gryphon GFS4170 (config mode)
 
@@ -21311,6 +21848,9 @@ usb:v05FEp0014*
 usb:v05FEp1010*
  ID_MODEL_FROM_DATABASE=Optical Wireless
 
+usb:v05FEp2001*
+ ID_MODEL_FROM_DATABASE=Microsoft Wireless Receiver 700
+
 usb:v05FF*
  ID_VENDOR_FROM_DATABASE=LeCroy Corp.
 
@@ -21335,6 +21875,9 @@ usb:v0603*
 usb:v0603p00F1*
  ID_MODEL_FROM_DATABASE=Keyboard
 
+usb:v0603p00F2*
+ ID_MODEL_FROM_DATABASE=Keyboard (Labtec Ultra Flat Keyboard)
+
 usb:v0603p6871*
  ID_MODEL_FROM_DATABASE=Mouse
 
@@ -21392,6 +21935,9 @@ usb:v060Bp2231*
 usb:v060Bp2270*
  ID_MODEL_FROM_DATABASE=Gigabyte K8100 Aivia Gaming Keyboard
 
+usb:v060Bp5253*
+ ID_MODEL_FROM_DATABASE=Thermaltake MEKA G-Unit Gaming Keyboard
+
 usb:v060Bp5811*
  ID_MODEL_FROM_DATABASE=ACK-571U Wireless Keyboard
 
@@ -21812,6 +22358,9 @@ usb:v064EpA110*
 usb:v064EpA114*
  ID_MODEL_FROM_DATABASE=Lemote Webcam
 
+usb:v064EpA116*
+ ID_MODEL_FROM_DATABASE=UVC 1.3MPixel WebCam
+
 usb:v064EpA136*
  ID_MODEL_FROM_DATABASE=Asus Integrated Webcam [CN031B]
 
@@ -22781,6 +23330,9 @@ usb:v068Ep00D3*
 usb:v068Ep00E2*
  ID_MODEL_FROM_DATABASE=HFX OEM Joystick
 
+usb:v068Ep00F0*
+ ID_MODEL_FROM_DATABASE=Multi-Function Panel
+
 usb:v068Ep00F1*
  ID_MODEL_FROM_DATABASE=Pro Throttle
 
@@ -22794,7 +23346,7 @@ usb:v068Ep00F4*
  ID_MODEL_FROM_DATABASE=Combatstick
 
 usb:v068Ep00FA*
- ID_MODEL_FROM_DATABASE=Flight Sim Pedals
+ ID_MODEL_FROM_DATABASE=Ch Throttle Quadrant
 
 usb:v068Ep00FF*
  ID_MODEL_FROM_DATABASE=Flight Sim Yoke
@@ -22856,6 +23408,9 @@ usb:v0698p9999*
 usb:v0699*
  ID_VENDOR_FROM_DATABASE=Tektronix, Inc.
 
+usb:v0699p0347*
+ ID_MODEL_FROM_DATABASE=AFG 3022B
+
 usb:v069A*
  ID_VENDOR_FROM_DATABASE=Askey Computer Corp.
 
@@ -23387,6 +23942,9 @@ usb:v06C2*
 usb:v06C2p0030*
  ID_MODEL_FROM_DATABASE=PhidgetRFID
 
+usb:v06C2p0031*
+ ID_MODEL_FROM_DATABASE=RFID reader
+
 usb:v06C2p0038*
  ID_MODEL_FROM_DATABASE=4-Motor PhidgetServo v3.0
 
@@ -23690,6 +24248,12 @@ usb:v06D3p0394*
 usb:v06D3p03A1*
  ID_MODEL_FROM_DATABASE=CP9550D/DW Port
 
+usb:v06D3p3B30*
+ ID_MODEL_FROM_DATABASE=CP-D70DW / CP-D707DW
+
+usb:v06D3p3B31*
+ ID_MODEL_FROM_DATABASE=CP-K60DW-S
+
 usb:v06D4*
  ID_VENDOR_FROM_DATABASE=Cisco Systems
 
@@ -24476,6 +25040,9 @@ usb:v072Fp1000*
 usb:v072Fp1001*
  ID_MODEL_FROM_DATABASE=PLDT Drive
 
+usb:v072Fp2200*
+ ID_MODEL_FROM_DATABASE=ACR122U
+
 usb:v072Fp8002*
  ID_MODEL_FROM_DATABASE=AET63 BioTRUSTKey
 
@@ -24947,6 +25514,12 @@ usb:v0765*
 usb:v0765p5001*
  ID_MODEL_FROM_DATABASE=Huey PRO Colorimeter
 
+usb:v0765p5020*
+ ID_MODEL_FROM_DATABASE=i1 Display Pro
+
+usb:v0765p6003*
+ ID_MODEL_FROM_DATABASE=ColorMunki Smile
+
 usb:v0765pD094*
  ID_MODEL_FROM_DATABASE=X-Rite DTP94 [Quato Silver Haze Pro]
 
@@ -25226,12 +25799,24 @@ usb:v0781p5530*
 usb:v0781p5567*
  ID_MODEL_FROM_DATABASE=Cruzer Blade
 
+usb:v0781p556C*
+ ID_MODEL_FROM_DATABASE=Ultra
+
+usb:v0781p556D*
+ ID_MODEL_FROM_DATABASE=Memory Vault
+
 usb:v0781p5571*
  ID_MODEL_FROM_DATABASE=Cruzer Fit
 
+usb:v0781p5576*
+ ID_MODEL_FROM_DATABASE=Cruzer Facet
+
 usb:v0781p5580*
  ID_MODEL_FROM_DATABASE=SDCZ80 Flash Drive
 
+usb:v0781p5581*
+ ID_MODEL_FROM_DATABASE=Ultra
+
 usb:v0781p5E10*
  ID_MODEL_FROM_DATABASE=Encrypted
 
@@ -25352,6 +25937,9 @@ usb:v0781p74D0*
 usb:v0781p74D1*
  ID_MODEL_FROM_DATABASE=Sansa Clip+ (msc)
 
+usb:v0781p74E5*
+ ID_MODEL_FROM_DATABASE=Sansa Clip Zip
+
 usb:v0781p8181*
  ID_MODEL_FROM_DATABASE=Pen Flash
 
@@ -25731,6 +26319,9 @@ usb:v07AAp001A*
  ID_MODEL_FROM_DATABASE=ULUSB-11 Key
 
 usb:v07AAp001C*
+ ID_MODEL_FROM_DATABASE=CG-WLUSB2GT 802.11g Wireless Adapter [Intersil ISL3880]
+
+usb:v07AAp0020*
  ID_MODEL_FROM_DATABASE=CG-WLUSB2GTST 802.11g Wireless Adapter [Intersil ISL3887]
 
 usb:v07AAp002E*
@@ -26015,6 +26606,9 @@ usb:v07B4p0114*
 usb:v07B4p0118*
  ID_MODEL_FROM_DATABASE=Mju Mini Digital/Mju Digital 500 Camera / Stylus 850 SW
 
+usb:v07B4p0125*
+ ID_MODEL_FROM_DATABASE=Tough TG-1 Camera
+
 usb:v07B4p0184*
  ID_MODEL_FROM_DATABASE=P-S100 port
 
@@ -26342,6 +26936,9 @@ usb:v07C4pA400*
 usb:v07C4pA600*
  ID_MODEL_FROM_DATABASE=Card Reader
 
+usb:v07C4pA604*
+ ID_MODEL_FROM_DATABASE=12-in-1 Card Reader
+
 usb:v07C4pAD01*
  ID_MODEL_FROM_DATABASE=Mass Storage Device
 
@@ -26375,6 +26972,9 @@ usb:v07C4pC010*
 usb:v07C5*
  ID_VENDOR_FROM_DATABASE=APG Cash Drawer
 
+usb:v07C5p0500*
+ ID_MODEL_FROM_DATABASE=Cash Drawer
+
 usb:v07C6*
  ID_VENDOR_FROM_DATABASE=ShareWave, Inc.
 
@@ -26444,6 +27044,9 @@ usb:v07CApA827*
 usb:v07CApA867*
  ID_MODEL_FROM_DATABASE=AVerTV DVB-T (A867)
 
+usb:v07CApB300*
+ ID_MODEL_FROM_DATABASE=A300 DVB-T TV receiver
+
 usb:v07CApB800*
  ID_MODEL_FROM_DATABASE=MR800 FM Radio
 
@@ -27041,6 +27644,9 @@ usb:v0803*
 usb:v0803p1300*
  ID_MODEL_FROM_DATABASE=V92 Faxmodem
 
+usb:v0803p3095*
+ ID_MODEL_FROM_DATABASE=V.92 56K Mini External Modem Model 3095
+
 usb:v0803p4310*
  ID_MODEL_FROM_DATABASE=4410a Wireless-G Adapter [Intersil ISL3887]
 
@@ -27443,6 +28049,9 @@ usb:v083Ap4507*
 usb:v083Ap4521*
  ID_MODEL_FROM_DATABASE=Siemens S30863-S1016-R107-2 802.11g Wireless Adapter [Intersil ISL3887]
 
+usb:v083Ap4531*
+ ID_MODEL_FROM_DATABASE=T-Com Sinus 154 data II [Intersil ISL3887]
+
 usb:v083Ap5046*
  ID_MODEL_FROM_DATABASE=SpeedStream 10/100 Ethernet [pegasus]
 
@@ -27614,6 +28223,9 @@ usb:v0846p9018*
 usb:v0846p9020*
  ID_MODEL_FROM_DATABASE=WNA3100(v1) Wireless-N 300 [Broadcom BCM43231]
 
+usb:v0846p9021*
+ ID_MODEL_FROM_DATABASE=WNA3100M(v1) Wireless-N 300 [Realtek RTL8192CU]
+
 usb:v0846p9030*
  ID_MODEL_FROM_DATABASE=WNA1100 Wireless-N 150 [Atheros AR9271]
 
@@ -27623,9 +28235,21 @@ usb:v0846p9040*
 usb:v0846p9041*
  ID_MODEL_FROM_DATABASE=WNA1000M 802.11bgn [Realtek RTL8188CUS]
 
+usb:v0846p9042*
+ ID_MODEL_FROM_DATABASE=On Networks N150MA 802.11bgn [Realtek RTL8188CUS]
+
+usb:v0846p9050*
+ ID_MODEL_FROM_DATABASE=A6200 802.11a/b/g/n/ac Wireless Adapter [Broadcom BCM43526]
+
+usb:v0846p9052*
+ ID_MODEL_FROM_DATABASE=A6100 AC600 DB Wireless Adapter [Realtek RTL8811AU]
+
 usb:v0846pA001*
  ID_MODEL_FROM_DATABASE=PA101 10 Mbps HPNA Home Phoneline RJ-1
 
+usb:v0846pF001*
+ ID_MODEL_FROM_DATABASE=On Networks N300MA 802.11bgn [Realtek RTL8192CU]
+
 usb:v084D*
  ID_VENDOR_FROM_DATABASE=Minton Optic Industry Co., Inc.
 
@@ -27776,8 +28400,17 @@ usb:v085Ap8027*
 usb:v085C*
  ID_VENDOR_FROM_DATABASE=ColorVision, Inc.
 
+usb:v085Cp0100*
+ ID_MODEL_FROM_DATABASE=Spyder 1
+
 usb:v085Cp0200*
- ID_MODEL_FROM_DATABASE=Monitor Spyder
+ ID_MODEL_FROM_DATABASE=Spyder 2
+
+usb:v085Cp0300*
+ ID_MODEL_FROM_DATABASE=Spyder 3
+
+usb:v085Cp0400*
+ ID_MODEL_FROM_DATABASE=Spyder 4
 
 usb:v0862*
  ID_VENDOR_FROM_DATABASE=Teletrol Systems, Inc.
@@ -28028,6 +28661,12 @@ usb:v0892*
 usb:v0892p0101*
  ID_MODEL_FROM_DATABASE=Smartdio Reader/Writer
 
+usb:v0894*
+ ID_VENDOR_FROM_DATABASE=TSI Incorporated
+
+usb:v0894p0010*
+ ID_MODEL_FROM_DATABASE=Remote NDIS Network Device
+
 usb:v0897*
  ID_VENDOR_FROM_DATABASE=Lauterbach
 
@@ -28082,6 +28721,18 @@ usb:v08A9p0015*
 usb:v08AE*
  ID_VENDOR_FROM_DATABASE=Macally (Mace Group, Inc.)
 
+usb:v08B0*
+ ID_VENDOR_FROM_DATABASE=Metrohm
+
+usb:v08B0p0006*
+ ID_MODEL_FROM_DATABASE=814 Sample Processor
+
+usb:v08B0p0015*
+ ID_MODEL_FROM_DATABASE=857 Titrando
+
+usb:v08B0p001A*
+ ID_MODEL_FROM_DATABASE=852 Titrando
+
 usb:v08B4*
  ID_VENDOR_FROM_DATABASE=Sorenson Vision, Inc.
 
@@ -28427,6 +29078,9 @@ usb:v08E3p0301*
 usb:v08E4*
  ID_VENDOR_FROM_DATABASE=Pioneer Corp.
 
+usb:v08E4p0185*
+ ID_MODEL_FROM_DATABASE=DDJ-WeGO2
+
 usb:v08E5*
  ID_VENDOR_FROM_DATABASE=Litronic
 
@@ -28935,10 +29589,16 @@ usb:v0906*
  ID_VENDOR_FROM_DATABASE=Faraday Technology Corp.
 
 usb:v0908*
- ID_VENDOR_FROM_DATABASE=ShenZhen SANZHAI Technology Co.,Ltd
+ ID_VENDOR_FROM_DATABASE=Siemens AG
+
+usb:v0908p01F4*
+ ID_MODEL_FROM_DATABASE=SIMATIC NET CP 5711
+
+usb:v0908p01FE*
+ ID_MODEL_FROM_DATABASE=SIMATIC NET PC Adapter A2
 
 usb:v0908p2701*
- ID_MODEL_FROM_DATABASE=Spy Pen VGA
+ ID_MODEL_FROM_DATABASE=ShenZhen SANZHAI Technology Co.,Ltd Spy Pen VGA
 
 usb:v0909*
  ID_VENDOR_FROM_DATABASE=Audio-Technica Corp.
@@ -29186,12 +29846,18 @@ usb:v091Ep23CC*
 usb:v091Ep2459*
  ID_MODEL_FROM_DATABASE=GPSmap 62/78 series
 
+usb:v091Ep2491*
+ ID_MODEL_FROM_DATABASE=Edge 800
+
 usb:v091Ep2519*
  ID_MODEL_FROM_DATABASE=eTrex 30
 
 usb:v091Ep2535*
  ID_MODEL_FROM_DATABASE=Edge 800
 
+usb:v091Ep253C*
+ ID_MODEL_FROM_DATABASE=GPSmap 62sc
+
 usb:v091Ep255B*
  ID_MODEL_FROM_DATABASE=Nuvi 2505LM
 
@@ -29216,12 +29882,18 @@ usb:v0922p0007*
 usb:v0922p0009*
  ID_MODEL_FROM_DATABASE=LabelWriter 310
 
+usb:v0922p0019*
+ ID_MODEL_FROM_DATABASE=LabelWriter 400
+
 usb:v0922p001A*
  ID_MODEL_FROM_DATABASE=LabelWriter 400 Turbo
 
 usb:v0922p0020*
  ID_MODEL_FROM_DATABASE=LabelWriter 450
 
+usb:v0922p1001*
+ ID_MODEL_FROM_DATABASE=LabelManager PnP
+
 usb:v0923*
  ID_VENDOR_FROM_DATABASE=IC Media Corp.
 
@@ -29264,6 +29936,9 @@ usb:v0925*
 usb:v0925p0005*
  ID_MODEL_FROM_DATABASE=Gamtec.,Ltd SmartJoy PLUS Adapter
 
+usb:v0925p03E8*
+ ID_MODEL_FROM_DATABASE=Wii Classic Controller Adapter
+
 usb:v0925p3881*
  ID_MODEL_FROM_DATABASE=Saleae Logic
 
@@ -29318,6 +29993,9 @@ usb:v0930p000C*
 usb:v0930p0010*
  ID_MODEL_FROM_DATABASE=Gigabeat S (mtp)
 
+usb:v0930p0200*
+ ID_MODEL_FROM_DATABASE=Integrated Bluetooth (Taiyo Yuden)
+
 usb:v0930p0301*
  ID_MODEL_FROM_DATABASE=PCX1100U Cable Modem (WDM)
 
@@ -29384,6 +30062,9 @@ usb:v0930p070B*
 usb:v0930p0A07*
  ID_MODEL_FROM_DATABASE=WLM-10U1 802.11abgn Wireless Adapter [Ralink RT3572]
 
+usb:v0930p0A13*
+ ID_MODEL_FROM_DATABASE=AX88179 Gigabit Ethernet [Toshiba]
+
 usb:v0930p0B05*
  ID_MODEL_FROM_DATABASE=PX1220E-1G25 External hard drive
 
@@ -29592,7 +30273,7 @@ usb:v0939*
  ID_VENDOR_FROM_DATABASE=Lumberg, Inc.
 
 usb:v0939p0B15*
- ID_MODEL_FROM_DATABASE=Toshiba Stor.E Alu 2 1TB (PX1710E-1HJ0)
+ ID_MODEL_FROM_DATABASE=Toshiba Stor.E Alu 2
 
 usb:v093A*
  ID_VENDOR_FROM_DATABASE=Pixart Imaging, Inc.
@@ -29654,6 +30335,9 @@ usb:v093Ap260F*
 usb:v093Ap2621*
  ID_MODEL_FROM_DATABASE=PAC731x Trust Webcam
 
+usb:v093Ap2622*
+ ID_MODEL_FROM_DATABASE=Webcam Genius
+
 usb:v093Ap2624*
  ID_MODEL_FROM_DATABASE=Webcam
 
@@ -29852,6 +30536,9 @@ usb:v0951p1653*
 usb:v0951p1656*
  ID_MODEL_FROM_DATABASE=DataTraveler Ultimate G2
 
+usb:v0951p1665*
+ ID_MODEL_FROM_DATABASE=Digital DataTraveler SE9 64GB
+
 usb:v0951p1689*
  ID_MODEL_FROM_DATABASE=DataTraveler SE9
 
@@ -29894,12 +30581,18 @@ usb:v0957p0200*
 usb:v0957p0202*
  ID_MODEL_FROM_DATABASE=E-Video DC-350 Camera
 
+usb:v0957p0407*
+ ID_MODEL_FROM_DATABASE=33220A Waveform Generator
+
 usb:v0957p0518*
  ID_MODEL_FROM_DATABASE=82357B GPIB Interface
 
 usb:v0957p0A07*
  ID_MODEL_FROM_DATABASE=34411A Multimeter
 
+usb:v0957p1507*
+ ID_MODEL_FROM_DATABASE=33210A Waveform Generator
+
 usb:v0957p1745*
  ID_MODEL_FROM_DATABASE=Test and Measurement Device (IVI)
 
@@ -29934,7 +30627,7 @@ usb:v095Dp0001*
  ID_MODEL_FROM_DATABASE=Polycom ViaVideo
 
 usb:v0967*
- ID_VENDOR_FROM_DATABASE=Acer (??)
+ ID_VENDOR_FROM_DATABASE=Acer NeWeb Corp.
 
 usb:v0967p0204*
  ID_MODEL_FROM_DATABASE=WarpLink 802.11b Adapter
@@ -29957,6 +30650,12 @@ usb:v096Ep0807*
 usb:v0971*
  ID_VENDOR_FROM_DATABASE=Gretag-Macbeth AG
 
+usb:v0971p2000*
+ ID_MODEL_FROM_DATABASE=i1 Pro
+
+usb:v0971p2001*
+ ID_MODEL_FROM_DATABASE=i1 Monitor
+
 usb:v0971p2003*
  ID_MODEL_FROM_DATABASE=Eye-One display
 
@@ -29964,7 +30663,7 @@ usb:v0971p2005*
  ID_MODEL_FROM_DATABASE=Huey
 
 usb:v0971p2007*
- ID_MODEL_FROM_DATABASE=ColorMunki
+ ID_MODEL_FROM_DATABASE=ColorMunki Photo
 
 usb:v0973*
  ID_VENDOR_FROM_DATABASE=Schlumberger
@@ -30083,6 +30782,9 @@ usb:v099Ap0638*
 usb:v099Ap610C*
  ID_MODEL_FROM_DATABASE=EL-610 Super Mini Electron luminescent Keyboard
 
+usb:v099Ap713A*
+ ID_MODEL_FROM_DATABASE=WK-713 Multimedia Keyboard
+
 usb:v099Ap7160*
  ID_MODEL_FROM_DATABASE=Hyper Slim Keyboard
 
@@ -30276,7 +30978,10 @@ usb:v09D3*
  ID_VENDOR_FROM_DATABASE=Com One
 
 usb:v09D3p0001*
- ID_MODEL_FROM_DATABASE=ISDN TA
+ ID_MODEL_FROM_DATABASE=ISDN TA / Light Rider 128K
+
+usb:v09D3p000B*
+ ID_MODEL_FROM_DATABASE=Bluetooth Adapter class 1 [BlueLight]
 
 usb:v09D7*
  ID_VENDOR_FROM_DATABASE=Novatel Wireless
@@ -30288,13 +30993,13 @@ usb:v09D9*
  ID_VENDOR_FROM_DATABASE=KRF Tech, Ltd
 
 usb:v09DA*
- ID_VENDOR_FROM_DATABASE=A4 Tech Co., Ltd
+ ID_VENDOR_FROM_DATABASE=A4Tech Co., Ltd.
 
 usb:v09DAp0006*
  ID_MODEL_FROM_DATABASE=Optical Mouse WOP-35 / Trust 450L Optical Mouse
 
 usb:v09DAp000A*
- ID_MODEL_FROM_DATABASE=Optical Mouse Opto 510D
+ ID_MODEL_FROM_DATABASE=Optical Mouse Opto 510D / OP-620D
 
 usb:v09DAp000E*
  ID_MODEL_FROM_DATABASE=X-F710F Optical Mouse 3xFire Gaming Mouse
@@ -30497,6 +31202,12 @@ usb:v0A07p00DA*
 usb:v0A0B*
  ID_VENDOR_FROM_DATABASE=Cybex Computer Products Co.
 
+usb:v0A0D*
+ ID_VENDOR_FROM_DATABASE=Servergy, Inc
+
+usb:v0A0Dp2514*
+ ID_MODEL_FROM_DATABASE=CTS-1000 Internal Hub
+
 usb:v0A11*
  ID_VENDOR_FROM_DATABASE=Xentec, Inc.
 
@@ -30788,6 +31499,9 @@ usb:v0A48p5024*
 usb:v0A48p5025*
  ID_MODEL_FROM_DATABASE=Mass Storage Device
 
+usb:v0A4A*
+ ID_VENDOR_FROM_DATABASE=Ploytec GmbH
+
 usb:v0A4B*
  ID_VENDOR_FROM_DATABASE=Fujitsu Media Devices, Ltd
 
@@ -31118,6 +31832,9 @@ usb:v0A5CpBD11*
 usb:v0A5CpBD13*
  ID_MODEL_FROM_DATABASE=BCM4323 802.11abgn Wireless Adapter
 
+usb:v0A5CpBD16*
+ ID_MODEL_FROM_DATABASE=BCM4319 802.11bgn Wireless Adapter
+
 usb:v0A5CpBD17*
  ID_MODEL_FROM_DATABASE=BCM43236 802.11abgn Wireless Adapter
 
@@ -31574,6 +32291,9 @@ usb:v0AB1*
 usb:v0AB1p0002*
  ID_MODEL_FROM_DATABASE=OBID RFID-Reader
 
+usb:v0AB1p0004*
+ ID_MODEL_FROM_DATABASE=OBID classic-pro
+
 usb:v0ABA*
  ID_VENDOR_FROM_DATABASE=Ellisys
 
@@ -31676,6 +32396,9 @@ usb:v0AC8pC33F*
 usb:v0AC8pC429*
  ID_MODEL_FROM_DATABASE=Lenovo ThinkCentre Web Camera
 
+usb:v0AC8pC42D*
+ ID_MODEL_FROM_DATABASE=Lenovo IdeaCentre Web Camera
+
 usb:v0AC9*
  ID_VENDOR_FROM_DATABASE=Micro Solutions, Inc.
 
@@ -31724,6 +32447,9 @@ usb:v0ACDp0630*
 usb:v0ACDp0810*
  ID_MODEL_FROM_DATABASE=SecurePIN (IDPA-506100Y) PIN Pad
 
+usb:v0ACDp2030*
+ ID_MODEL_FROM_DATABASE=ValueMag Magnetic Stripe Reader
+
 usb:v0ACE*
  ID_VENDOR_FROM_DATABASE=ZyDAS
 
@@ -31925,6 +32651,12 @@ usb:v0AF9p0010*
 usb:v0AF9p0011*
  ID_MODEL_FROM_DATABASE=Micro Innovations IC50C Webcam
 
+usb:v0AFA*
+ ID_VENDOR_FROM_DATABASE=DMC Co., Ltd.
+
+usb:v0AFAp07D2*
+ ID_MODEL_FROM_DATABASE=Controller Board for Projected Capacitive Touch Screen DUS3000
+
 usb:v0AFC*
  ID_VENDOR_FROM_DATABASE=Zaptronix Ltd
 
@@ -31943,6 +32675,9 @@ usb:v0B00*
 usb:v0B05*
  ID_VENDOR_FROM_DATABASE=ASUSTek Computer, Inc.
 
+usb:v0B05p0001*
+ ID_MODEL_FROM_DATABASE=MeMO Pad HD 7 (CD-ROM mode)
+
 usb:v0B05p1101*
  ID_MODEL_FROM_DATABASE=Mass Storage (UISDMC4S)
 
@@ -31956,7 +32691,7 @@ usb:v0B05p1708*
  ID_MODEL_FROM_DATABASE=Mass Storage Device
 
 usb:v0B05p170B*
- ID_MODEL_FROM_DATABASE=Mass Storage Device
+ ID_MODEL_FROM_DATABASE=Multi card reader
 
 usb:v0B05p170C*
  ID_MODEL_FROM_DATABASE=WL-159g 802.11bg
@@ -32048,6 +32783,9 @@ usb:v0B05p1784*
 usb:v0B05p1786*
  ID_MODEL_FROM_DATABASE=USB-N10 802.11n Network Adapter [Realtek RTL8188SU]
 
+usb:v0B05p1788*
+ ID_MODEL_FROM_DATABASE=BT-270 Bluetooth Adapter
+
 usb:v0B05p1791*
  ID_MODEL_FROM_DATABASE=WL-167G v3 802.11n Adapter [Realtek RTL8188SU]
 
@@ -32060,12 +32798,21 @@ usb:v0B05p179E*
 usb:v0B05p179F*
  ID_MODEL_FROM_DATABASE=Eee Note EA800 (tablet mode)
 
+usb:v0B05p17A0*
+ ID_MODEL_FROM_DATABASE=Xonar U3 sound card
+
 usb:v0B05p17A1*
  ID_MODEL_FROM_DATABASE=Eee Note EA800 (mass storage mode)
 
 usb:v0B05p17AB*
  ID_MODEL_FROM_DATABASE=USB-N13 802.11n Network Adapter (rev. B1) [Realtek RTL8192CU]
 
+usb:v0B05p17C7*
+ ID_MODEL_FROM_DATABASE=WL-330NUL
+
+usb:v0B05p17C9*
+ ID_MODEL_FROM_DATABASE=USB-AC53 802.11a/b/g/n/ac Wireless Adapter [Broadcom BCM43526]
+
 usb:v0B05p4C80*
  ID_MODEL_FROM_DATABASE=Transformer Pad TF300TG
 
@@ -32084,6 +32831,15 @@ usb:v0B05p4D01*
 usb:v0B05p4DAF*
  ID_MODEL_FROM_DATABASE=Transformer Pad Infinity TF700 (Fastboot)
 
+usb:v0B05p5410*
+ ID_MODEL_FROM_DATABASE=MeMO Pad HD 7 (MTP mode)
+
+usb:v0B05p5412*
+ ID_MODEL_FROM_DATABASE=MeMO Pad HD 7 (PTP mode)
+
+usb:v0B05p550F*
+ ID_MODEL_FROM_DATABASE=ASUS fonepad 7
+
 usb:v0B05p6101*
  ID_MODEL_FROM_DATABASE=Cable Modem
 
@@ -32126,12 +32882,21 @@ usb:v0B0Dp0000*
 usb:v0B0E*
  ID_VENDOR_FROM_DATABASE=GN Netcom
 
+usb:v0B0Ep034C*
+ ID_MODEL_FROM_DATABASE=Jabra UC Voice 750 MS
+
 usb:v0B0Ep0420*
  ID_MODEL_FROM_DATABASE=Jabra SPEAK 510
 
+usb:v0B0Ep094D*
+ ID_MODEL_FROM_DATABASE=GN Netcom / Jabra REVO Wireless
+
 usb:v0B0Ep1022*
  ID_MODEL_FROM_DATABASE=Jabra PRO 9450, Type 9400BS (DECT Headset)
 
+usb:v0B0Ep2007*
+ ID_MODEL_FROM_DATABASE=GN 2000 Stereo Corded Headset
+
 usb:v0B0Ep620C*
  ID_MODEL_FROM_DATABASE=Jabra BT620s
 
@@ -32192,6 +32957,9 @@ usb:v0B33*
 usb:v0B33p0020*
  ID_MODEL_FROM_DATABASE=ShuttleXpress
 
+usb:v0B33p0700*
+ ID_MODEL_FROM_DATABASE=RollerMouse Pro
+
 usb:v0B37*
  ID_VENDOR_FROM_DATABASE=Hitachi ULSI Systems Co., Ltd
 
@@ -32357,6 +33125,12 @@ usb:v0B48p300D*
 usb:v0B48p300E*
  ID_MODEL_FROM_DATABASE=TT-connect C-2400
 
+usb:v0B48p3012*
+ ID_MODEL_FROM_DATABASE=TT-connect CT2-4650 CI
+
+usb:v0B48p3014*
+ ID_MODEL_FROM_DATABASE=TT-TVStick CT2-4400
+
 usb:v0B49*
  ID_VENDOR_FROM_DATABASE=ASCII Corp.
 
@@ -32588,6 +33362,9 @@ usb:v0B95p1720*
 usb:v0B95p1780*
  ID_MODEL_FROM_DATABASE=AX88178
 
+usb:v0B95p1790*
+ ID_MODEL_FROM_DATABASE=AX88179 Gigabit Ethernet
+
 usb:v0B95p7720*
  ID_MODEL_FROM_DATABASE=AX88772
 
@@ -32687,6 +33464,9 @@ usb:v0BAFp011B*
 usb:v0BAFp0121*
  ID_MODEL_FROM_DATABASE=USR5423 802.11bg Wireless Adapter [ZyDAS ZD1211B]
 
+usb:v0BAFp0303*
+ ID_MODEL_FROM_DATABASE=USR5637 56K Faxmodem
+
 usb:v0BAFp6112*
  ID_MODEL_FROM_DATABASE=FaxModem Model 5633
 
@@ -33233,6 +34013,9 @@ usb:v0BB4p0C01*
 usb:v0BB4p0C02*
  ID_MODEL_FROM_DATABASE=Dream / ADP1 / G1 / Magic / Tattoo (Debug)
 
+usb:v0BB4p0C03*
+ ID_MODEL_FROM_DATABASE=Android Phone [Fairphone First Edition (FP1)]
+
 usb:v0BB4p0C13*
  ID_MODEL_FROM_DATABASE=Diamond
 
@@ -33272,6 +34055,12 @@ usb:v0BB4p0CA2*
 usb:v0BB4p0CA5*
  ID_MODEL_FROM_DATABASE=Android Phone [Evo Shift 4G]
 
+usb:v0BB4p0CAE*
+ ID_MODEL_FROM_DATABASE=T-Mobile MyTouch 4G Slide [Doubleshot]
+
+usb:v0BB4p0DEA*
+ ID_MODEL_FROM_DATABASE=M7_UL [HTC One]
+
 usb:v0BB4p0FF8*
  ID_MODEL_FROM_DATABASE=Desire HD (Tethering Mode)
 
@@ -33344,18 +34133,36 @@ usb:v0BC2p2320*
 usb:v0BC2p3008*
  ID_MODEL_FROM_DATABASE=FreeAgent Desk 1TB
 
+usb:v0BC2p3101*
+ ID_MODEL_FROM_DATABASE=FreeAgent XTreme 640GB
+
+usb:v0BC2p3312*
+ ID_MODEL_FROM_DATABASE=SRD00F2 Expansion Desktop Drive (STBV)
+
 usb:v0BC2p3320*
  ID_MODEL_FROM_DATABASE=SRD00F2 [Expansion Desktop Drive]
 
 usb:v0BC2p3332*
  ID_MODEL_FROM_DATABASE=Expansion
 
+usb:v0BC2p5020*
+ ID_MODEL_FROM_DATABASE=FreeAgent GoFlex
+
 usb:v0BC2p5021*
  ID_MODEL_FROM_DATABASE=FreeAgent GoFlex USB 2.0
 
+usb:v0BC2p5030*
+ ID_MODEL_FROM_DATABASE=FreeAgent GoFlex Upgrade Cable STAE104
+
 usb:v0BC2p5031*
  ID_MODEL_FROM_DATABASE=FreeAgent GoFlex USB 3.0
 
+usb:v0BC2p5070*
+ ID_MODEL_FROM_DATABASE=FreeAgent GoFlex Desk
+
+usb:v0BC2p5071*
+ ID_MODEL_FROM_DATABASE=FreeAgent GoFlex Desk
+
 usb:v0BC2p50A1*
  ID_MODEL_FROM_DATABASE=FreeAgent GoFlex Desk
 
@@ -33377,6 +34184,12 @@ usb:v0BC2pA0A1*
 usb:v0BC2pA0A4*
  ID_MODEL_FROM_DATABASE=Backup Plus Desktop Drive
 
+usb:v0BC2pAB00*
+ ID_MODEL_FROM_DATABASE=Slim Portable Drive
+
+usb:v0BC2pAB20*
+ ID_MODEL_FROM_DATABASE=Backup Plus Portable Drive
+
 usb:v0BC3*
  ID_VENDOR_FROM_DATABASE=IPWireless, Inc.
 
@@ -33545,12 +34358,21 @@ usb:v0BDAp0176*
 usb:v0BDAp0178*
  ID_MODEL_FROM_DATABASE=Mass Storage Device
 
+usb:v0BDAp0179*
+ ID_MODEL_FROM_DATABASE=RTL8188ETV Wireless LAN 802.11n Network Adapter
+
 usb:v0BDAp0184*
  ID_MODEL_FROM_DATABASE=RTS5182 Card Reader
 
 usb:v0BDAp0186*
  ID_MODEL_FROM_DATABASE=Card Reader
 
+usb:v0BDAp0301*
+ ID_MODEL_FROM_DATABASE=multicard reader
+
+usb:v0BDAp1724*
+ ID_MODEL_FROM_DATABASE=RTL8723AU 802.11n WLAN Adapter
+
 usb:v0BDAp2831*
  ID_MODEL_FROM_DATABASE=RTL2831U DVB-T
 
@@ -33560,6 +34382,9 @@ usb:v0BDAp2832*
 usb:v0BDAp2838*
  ID_MODEL_FROM_DATABASE=RTL2838 DVB-T
 
+usb:v0BDAp5730*
+ ID_MODEL_FROM_DATABASE=HP 2.0MP High Definition Webcam
+
 usb:v0BDAp8150*
  ID_MODEL_FROM_DATABASE=RTL8150 Fast Ethernet Adapter
 
@@ -33608,6 +34433,9 @@ usb:v0BDAp8198*
 usb:v0BDAp8199*
  ID_MODEL_FROM_DATABASE=RTL8187SU 802.11g WLAN Adapter
 
+usb:v0BDAp8812*
+ ID_MODEL_FROM_DATABASE=RTL8812AU 802.11a/b/g/n/ac WLAN Adapter
+
 usb:v0BDB*
  ID_VENDOR_FROM_DATABASE=Ericsson Business Mobile Networks BV
 
@@ -33939,7 +34767,7 @@ usb:v0C24p0019*
  ID_MODEL_FROM_DATABASE=Bluetooth Device
 
 usb:v0C24p0021*
- ID_MODEL_FROM_DATABASE=Bluetooth Device
+ ID_MODEL_FROM_DATABASE=Bluetooth Device (V2.1+EDR)
 
 usb:v0C24p0C24*
  ID_MODEL_FROM_DATABASE=Bluetooth Device(SAMPLE)
@@ -34043,6 +34871,9 @@ usb:v0C45*
 usb:v0C45p0011*
  ID_MODEL_FROM_DATABASE=EBUDDY
 
+usb:v0C45p0520*
+ ID_MODEL_FROM_DATABASE=MaxTrack Wireless Mouse
+
 usb:v0C45p1018*
  ID_MODEL_FROM_DATABASE=Compact Flash storage memory card reader
 
@@ -34397,9 +35228,15 @@ usb:v0C45p62C0*
 usb:v0C45p62E0*
  ID_MODEL_FROM_DATABASE=MSI Starcam Racer
 
+usb:v0C45p6300*
+ ID_MODEL_FROM_DATABASE=PC Microscope camera
+
 usb:v0C45p6310*
  ID_MODEL_FROM_DATABASE=Sonix USB 2.0 Camera
 
+usb:v0C45p6340*
+ ID_MODEL_FROM_DATABASE=Camera
+
 usb:v0C45p6341*
  ID_MODEL_FROM_DATABASE=Defender G-Lens 2577 HD720p Camera
 
@@ -34427,6 +35264,12 @@ usb:v0C45p6419*
 usb:v0C45p641D*
  ID_MODEL_FROM_DATABASE=1.3 MPixel Integrated Webcam
 
+usb:v0C45p643F*
+ ID_MODEL_FROM_DATABASE=Dell Integrated HD Webcam
+
+usb:v0C45p644D*
+ ID_MODEL_FROM_DATABASE=1.3 MPixel Integrated Webcam
+
 usb:v0C45p6480*
  ID_MODEL_FROM_DATABASE=Sonix 1.3 MP Laptop Integrated Webcam
 
@@ -34436,6 +35279,9 @@ usb:v0C45p648B*
 usb:v0C45p64BD*
  ID_MODEL_FROM_DATABASE=Sony Visual Communication Camera
 
+usb:v0C45p7401*
+ ID_MODEL_FROM_DATABASE=TEMPer Temperature Sensor
+
 usb:v0C45p7402*
  ID_MODEL_FROM_DATABASE=TEMPerHUM Temperature & Humidity Sensor
 
@@ -35229,11 +36075,53 @@ usb:v0CE5p0003*
  ID_MODEL_FROM_DATABASE=Matrix
 
 usb:v0CE9*
- ID_VENDOR_FROM_DATABASE=pico Technology
+ ID_VENDOR_FROM_DATABASE=Pico Technology
 
 usb:v0CE9p1001*
  ID_MODEL_FROM_DATABASE=PicoScope3000 series PC Oscilloscope
 
+usb:v0CE9p1007*
+ ID_MODEL_FROM_DATABASE=PicoScope 2000 series PC Oscilloscope
+
+usb:v0CE9p1008*
+ ID_MODEL_FROM_DATABASE=PicoScope 5000 series PC Oscilloscope
+
+usb:v0CE9p1009*
+ ID_MODEL_FROM_DATABASE=PicoScope 4000 series PC Oscilloscope
+
+usb:v0CE9p100E*
+ ID_MODEL_FROM_DATABASE=PicoScope 6000 series PC Oscilloscope
+
+usb:v0CE9p1012*
+ ID_MODEL_FROM_DATABASE=PicoScope 3000A series PC Oscilloscope
+
+usb:v0CE9p1016*
+ ID_MODEL_FROM_DATABASE=PicoScope 2000A series PC Oscilloscope
+
+usb:v0CE9p1018*
+ ID_MODEL_FROM_DATABASE=PicoScope 4000A series PC Oscilloscope
+
+usb:v0CE9p1200*
+ ID_MODEL_FROM_DATABASE=PicoScope 2000 series PC Oscilloscope
+
+usb:v0CE9p1201*
+ ID_MODEL_FROM_DATABASE=PicoScope 3000 series PC Oscilloscope
+
+usb:v0CE9p1202*
+ ID_MODEL_FROM_DATABASE=PicoScope 4000 series PC Oscilloscope
+
+usb:v0CE9p1203*
+ ID_MODEL_FROM_DATABASE=PicoScope 5000 series PC Oscilloscope
+
+usb:v0CE9p1204*
+ ID_MODEL_FROM_DATABASE=PicoScope 6000 series PC Oscilloscope
+
+usb:v0CE9p1211*
+ ID_MODEL_FROM_DATABASE=PicoScope 3000 series PC Oscilloscope
+
+usb:v0CE9p1212*
+ ID_MODEL_FROM_DATABASE=PicoScope 4000 series PC Oscilloscope
+
 usb:v0CF1*
  ID_VENDOR_FROM_DATABASE=e-Conn Electronic Co., Ltd
 
@@ -35291,6 +36179,9 @@ usb:v0CF3p3000*
 usb:v0CF3p3002*
  ID_MODEL_FROM_DATABASE=AR3011 Bluetooth
 
+usb:v0CF3p3004*
+ ID_MODEL_FROM_DATABASE=AR3012 Bluetooth 4.0
+
 usb:v0CF3p3005*
  ID_MODEL_FROM_DATABASE=AR3011 Bluetooth
 
@@ -35465,6 +36356,15 @@ usb:v0D35*
 usb:v0D3A*
  ID_VENDOR_FROM_DATABASE=Posiflex Technologies, Inc.
 
+usb:v0D3Ap0206*
+ ID_MODEL_FROM_DATABASE=Series 3xxx Cash Drawer
+
+usb:v0D3Ap0207*
+ ID_MODEL_FROM_DATABASE=Series 3xxx Cash Drawer
+
+usb:v0D3Ap0500*
+ ID_MODEL_FROM_DATABASE=Magnetic Stripe Reader
+
 usb:v0D3C*
  ID_VENDOR_FROM_DATABASE=Sri Cable Technology, Ltd
 
@@ -35474,6 +36374,9 @@ usb:v0D3D*
 usb:v0D3Dp0001*
  ID_MODEL_FROM_DATABASE=HID Keyboard
 
+usb:v0D3Dp0040*
+ ID_MODEL_FROM_DATABASE=PS/2 Adapter
+
 usb:v0D3E*
  ID_VENDOR_FROM_DATABASE=Fitcom, inc.
 
@@ -35552,6 +36455,9 @@ usb:v0D49p7010*
 usb:v0D49p7100*
  ID_MODEL_FROM_DATABASE=OneTouch II 300GB External Hard Disk
 
+usb:v0D49p7310*
+ ID_MODEL_FROM_DATABASE=OneTouch 4
+
 usb:v0D49p7410*
  ID_MODEL_FROM_DATABASE=Mobile Hard Disk Drive (1TB)
 
@@ -35759,6 +36665,9 @@ usb:v0D78*
 usb:v0D7A*
  ID_VENDOR_FROM_DATABASE=MARX Datentechnik GmbH
 
+usb:v0D7Ap0001*
+ ID_MODEL_FROM_DATABASE=CrypToken
+
 usb:v0D7B*
  ID_VENDOR_FROM_DATABASE=Wellco Technology Co., Ltd
 
@@ -36194,6 +37103,9 @@ usb:v0DB0p1020*
 usb:v0DB0p1967*
  ID_MODEL_FROM_DATABASE=Bluetooth Dongle
 
+usb:v0DB0p3713*
+ ID_MODEL_FROM_DATABASE=Primo 73
+
 usb:v0DB0p3801*
  ID_MODEL_FROM_DATABASE=Motorola Bluetooth 2.1+EDR Device
 
@@ -36305,6 +37217,15 @@ usb:v0DB7*
 usb:v0DB7p0002*
  ID_MODEL_FROM_DATABASE=Goldpfeil P-LAN
 
+usb:v0DBA*
+ ID_VENDOR_FROM_DATABASE=Digidesign
+
+usb:v0DBAp1000*
+ ID_MODEL_FROM_DATABASE=Mbox 1 [Mbox]
+
+usb:v0DBAp3000*
+ ID_MODEL_FROM_DATABASE=Mbox 2
+
 usb:v0DBC*
  ID_VENDOR_FROM_DATABASE=A&D Medical
 
@@ -36677,6 +37598,9 @@ usb:v0DF6p0060*
 usb:v0DF6p0062*
  ID_MODEL_FROM_DATABASE=WLA-5000 802.11abgn [Ralink RT3572]
 
+usb:v0DF6p0072*
+ ID_MODEL_FROM_DATABASE=AX88179 Gigabit Ethernet [Sitecom]
+
 usb:v0DF6p061C*
  ID_MODEL_FROM_DATABASE=LN-028 Network USB 2.0 Adapter
 
@@ -37100,6 +38024,12 @@ usb:v0E6A*
 usb:v0E6Ap0101*
  ID_MODEL_FROM_DATABASE=MA100 [USB-UART Bridge IC]
 
+usb:v0E6Ap030B*
+ ID_MODEL_FROM_DATABASE=Truly Ergonomic Computer Keyboard (Device Firmware Update mode)
+
+usb:v0E6Ap030C*
+ ID_MODEL_FROM_DATABASE=Truly Ergonomic Computer Keyboard
+
 usb:v0E6Ap6001*
  ID_MODEL_FROM_DATABASE=GEMBIRD Flexible keyboard KB-109F-B-DE
 
@@ -37154,6 +38084,9 @@ usb:v0E79p14AD*
 usb:v0E79p150E*
  ID_MODEL_FROM_DATABASE=80 G9
 
+usb:v0E79p3001*
+ ID_MODEL_FROM_DATABASE=40 Titanium
+
 usb:v0E7B*
  ID_VENDOR_FROM_DATABASE=On-Tech Industry Co., Ltd
 
@@ -37193,9 +38126,15 @@ usb:v0E8Dp1806*
 usb:v0E8Dp1836*
  ID_MODEL_FROM_DATABASE=Samsung SE-S084 Super WriteMaster Slim External DVD writer
 
+usb:v0E8Dp2000*
+ ID_MODEL_FROM_DATABASE=MT65xx Preloader
+
 usb:v0E8Dp3329*
  ID_MODEL_FROM_DATABASE=Qstarz BT-Q1000XT
 
+usb:v0E8Dp763E*
+ ID_MODEL_FROM_DATABASE=MT7630e Bluetooth Adapter
+
 usb:v0E8F*
  ID_VENDOR_FROM_DATABASE=GreenAsia Inc.
 
@@ -37203,7 +38142,7 @@ usb:v0E8Fp0003*
  ID_MODEL_FROM_DATABASE=MaxFire Blaze2
 
 usb:v0E8Fp0012*
- ID_MODEL_FROM_DATABASE=USB Wireless 2.4GHz Gamepad
+ ID_MODEL_FROM_DATABASE=Joystick/Gamepad
 
 usb:v0E8Fp0016*
  ID_MODEL_FROM_DATABASE=4 port USB 1.1 hub UH-174
@@ -37337,9 +38276,18 @@ usb:v0EB7*
 usb:v0EB8*
  ID_VENDOR_FROM_DATABASE=Mettler Toledo
 
+usb:v0EB8p2200*
+ ID_MODEL_FROM_DATABASE=Ariva Scale
+
 usb:v0EB8pF000*
  ID_MODEL_FROM_DATABASE=PS60 Scale
 
+usb:v0EBB*
+ ID_VENDOR_FROM_DATABASE=Thermo Fisher Scientific
+
+usb:v0EBBp0002*
+ ID_MODEL_FROM_DATABASE=FT-IR Spectrometer
+
 usb:v0EBE*
  ID_VENDOR_FROM_DATABASE=VWeb Corp.
 
@@ -37460,6 +38408,12 @@ usb:v0EEFp0001*
 usb:v0EEFp0002*
  ID_MODEL_FROM_DATABASE=Touchscreen Controller(Professional)
 
+usb:v0EEFp7200*
+ ID_MODEL_FROM_DATABASE=Touchscreen Controller
+
+usb:v0EEFpA802*
+ ID_MODEL_FROM_DATABASE=eGalaxTouch EXC7920
+
 usb:v0EF0*
  ID_VENDOR_FROM_DATABASE=Hitachi Cable, Ltd
 
@@ -37571,6 +38525,12 @@ usb:v0F12*
 usb:v0F13*
  ID_VENDOR_FROM_DATABASE=Acetek Technology Co., Ltd
 
+usb:v0F14*
+ ID_VENDOR_FROM_DATABASE=Ingenico
+
+usb:v0F14p0012*
+ ID_MODEL_FROM_DATABASE=Vital'Act 3S
+
 usb:v0F18*
  ID_VENDOR_FROM_DATABASE=Finger Lakes Instrumentation
 
@@ -37655,6 +38615,12 @@ usb:v0F37*
 usb:v0F38*
  ID_VENDOR_FROM_DATABASE=Nien-Yi Industrial Corp.
 
+usb:v0F39*
+ ID_VENDOR_FROM_DATABASE=TG3 Electronics
+
+usb:v0F39p0876*
+ ID_MODEL_FROM_DATABASE=Keyboard [87 Francium Pro]
+
 usb:v0F3D*
  ID_VENDOR_FROM_DATABASE=Airprime, Incorporated
 
@@ -37742,6 +38708,9 @@ usb:v0F63*
 usb:v0F63p0010*
  ID_MODEL_FROM_DATABASE=Leapster Explorer
 
+usb:v0F63p0022*
+ ID_MODEL_FROM_DATABASE=Leap Reader
+
 usb:v0F63p0500*
  ID_MODEL_FROM_DATABASE=Fly Fusion
 
@@ -37829,6 +38798,9 @@ usb:v0F6Ep0404*
 usb:v0F73*
  ID_VENDOR_FROM_DATABASE=DFI
 
+usb:v0F78*
+ ID_VENDOR_FROM_DATABASE=Guntermann & Drunck GmbH
+
 usb:v0F7C*
  ID_VENDOR_FROM_DATABASE=DQ Technology, Inc.
 
@@ -37965,7 +38937,7 @@ usb:v0FCAp8001*
  ID_MODEL_FROM_DATABASE=Blackberry Handheld
 
 usb:v0FCAp8004*
- ID_MODEL_FROM_DATABASE=Blackberry Handheld
+ ID_MODEL_FROM_DATABASE=Blackberry
 
 usb:v0FCAp8007*
  ID_MODEL_FROM_DATABASE=Blackberry Handheld
@@ -38048,6 +39020,12 @@ usb:v0FCEp3138*
 usb:v0FCEp3149*
  ID_MODEL_FROM_DATABASE=Xperia X8
 
+usb:v0FCEp514F*
+ ID_MODEL_FROM_DATABASE=Xperia arc S [Adb-Enable Mode]
+
+usb:v0FCEp5169*
+ ID_MODEL_FROM_DATABASE=Xperia S [Adb-Enable Mode]
+
 usb:v0FCEp5177*
  ID_MODEL_FROM_DATABASE=Xperia Ion [Debug Mode]
 
@@ -38210,6 +39188,9 @@ usb:v0FCEpE166*
 usb:v0FCEpE167*
  ID_MODEL_FROM_DATABASE=XPERIA mini
 
+usb:v0FCEpF0FA*
+ ID_MODEL_FROM_DATABASE=Liveview micro display MN800 in DFU mode
+
 usb:v0FCF*
  ID_VENDOR_FROM_DATABASE=Dynastream Innovations, Inc.
 
@@ -38217,13 +39198,16 @@ usb:v0FCFp1003*
  ID_MODEL_FROM_DATABASE=ANT Development Board
 
 usb:v0FCFp1004*
- ID_MODEL_FROM_DATABASE=ANT2USB
+ ID_MODEL_FROM_DATABASE=ANTUSB Stick
 
 usb:v0FCFp1006*
  ID_MODEL_FROM_DATABASE=ANT Development Board
 
 usb:v0FCFp1008*
- ID_MODEL_FROM_DATABASE=Mini stick Suunto
+ ID_MODEL_FROM_DATABASE=ANTUSB2 Stick
+
+usb:v0FCFp1009*
+ ID_MODEL_FROM_DATABASE=ANTUSB-m Stick
 
 usb:v0FD0*
  ID_VENDOR_FROM_DATABASE=Tulip Computers B.V.
@@ -38279,6 +39263,12 @@ usb:v0FDAp0100*
 usb:v0FDC*
  ID_VENDOR_FROM_DATABASE=Micro Plus
 
+usb:v0FDE*
+ ID_VENDOR_FROM_DATABASE=Oregon Scientific
+
+usb:v0FDEpCA01*
+ ID_MODEL_FROM_DATABASE=WMRS200 weather station
+
 usb:v0FE0*
  ID_VENDOR_FROM_DATABASE=Osterhout Design Group
 
@@ -38360,12 +39350,21 @@ usb:v0FFC*
 usb:v0FFCp0021*
  ID_MODEL_FROM_DATABASE=Nord Stage 2
 
+usb:v0FFD*
+ ID_VENDOR_FROM_DATABASE=EarlySense
+
+usb:v0FFDpFF00*
+ ID_MODEL_FROM_DATABASE=OEM
+
 usb:v0FFF*
  ID_VENDOR_FROM_DATABASE=Aopen, Inc.
 
 usb:v1000*
  ID_VENDOR_FROM_DATABASE=Speed Tech Corp.
 
+usb:v1000p153B*
+ ID_MODEL_FROM_DATABASE=TerraTec Electronic GmbH
+
 usb:v1001*
  ID_VENDOR_FROM_DATABASE=Ritronics Components (S) Pte., Ltd
 
@@ -38399,6 +39398,9 @@ usb:v1004p618E*
 usb:v1004p618F*
  ID_MODEL_FROM_DATABASE=Ally/Optimus One
 
+usb:v1004p61C5*
+ ID_MODEL_FROM_DATABASE=P880 / Charge only
+
 usb:v1004p61C6*
  ID_MODEL_FROM_DATABASE=Vortex (msc)
 
@@ -38409,7 +39411,7 @@ usb:v1004p61F1*
  ID_MODEL_FROM_DATABASE=Optimus Android Phone [LG Software mode]
 
 usb:v1004p61F9*
- ID_MODEL_FROM_DATABASE=V909 G-Slate
+ ID_MODEL_FROM_DATABASE=Optimus (Various Models) MTP Mode
 
 usb:v1004p61FC*
  ID_MODEL_FROM_DATABASE=Optimus 3
@@ -38423,9 +39425,15 @@ usb:v1004p6300*
 usb:v1004p631C*
  ID_MODEL_FROM_DATABASE=Optimus Android Phone [MTP mode]
 
+usb:v1004p631D*
+ ID_MODEL_FROM_DATABASE=Optimus Android Phone (Camera/PTP Mode)
+
 usb:v1004p631E*
  ID_MODEL_FROM_DATABASE=Optimus Android Phone [Camera/PTP mode]
 
+usb:v1004p631F*
+ ID_MODEL_FROM_DATABASE=Optimus Android Phone (Charge Mode)
+
 usb:v1004p6356*
  ID_MODEL_FROM_DATABASE=Optimus Android Phone [Virtual CD mode]
 
@@ -38435,6 +39443,9 @@ usb:v1004p6800*
 usb:v1004p7000*
  ID_MODEL_FROM_DATABASE=LG LDP-7024D(LD)USB
 
+usb:v1004p91C8*
+ ID_MODEL_FROM_DATABASE=P880 / USB tethering
+
 usb:v1004pA400*
  ID_MODEL_FROM_DATABASE=Renoir (KC910)
 
@@ -38637,13 +39648,13 @@ usb:v1033p0068*
  ID_MODEL_FROM_DATABASE=3,5'' HDD case MD-231
 
 usb:v1038*
- ID_VENDOR_FROM_DATABASE=Ideazon, Inc.
+ ID_VENDOR_FROM_DATABASE=SteelSeries ApS
 
 usb:v1038p0100*
- ID_MODEL_FROM_DATABASE=Zboard
+ ID_MODEL_FROM_DATABASE=Ideazon Zboard
 
 usb:v1038p1361*
- ID_MODEL_FROM_DATABASE=Sensei
+ ID_MODEL_FROM_DATABASE=Ideazon Sensei
 
 usb:v1039*
  ID_VENDOR_FROM_DATABASE=devolo AG
@@ -38654,6 +39665,12 @@ usb:v1039p0824*
 usb:v1039p2140*
  ID_MODEL_FROM_DATABASE=dsl+ 1100 duo
 
+usb:v103A*
+ ID_VENDOR_FROM_DATABASE=PSA
+
+usb:v103ApF000*
+ ID_MODEL_FROM_DATABASE=Actia Evo XS
+
 usb:v103D*
  ID_VENDOR_FROM_DATABASE=Stanton
 
@@ -38798,6 +39815,9 @@ usb:v1050p0110*
 usb:v1050p0111*
  ID_MODEL_FROM_DATABASE=Yubikey NEO OTP+CCID
 
+usb:v1050p0200*
+ ID_MODEL_FROM_DATABASE=U2F Gnubby
+
 usb:v1050p0211*
  ID_MODEL_FROM_DATABASE=Gnubby
 
@@ -38841,49 +39861,79 @@ usb:v1058p0704*
  ID_MODEL_FROM_DATABASE=Passport External HDD
 
 usb:v1058p070A*
- ID_MODEL_FROM_DATABASE=My Passport Essential SE
+ ID_MODEL_FROM_DATABASE=My Passport Essential (WDBAAA), My Passport for Mac (WDBAAB), My Passport Essential SE (WDBABM), My Passport SE for Mac (WDBABW)
+
+usb:v1058p070B*
+ ID_MODEL_FROM_DATABASE=My Passport Elite (WDBAAC)
+
+usb:v1058p070C*
+ ID_MODEL_FROM_DATABASE=My Passport Studio (WDBAAE)
 
 usb:v1058p071A*
- ID_MODEL_FROM_DATABASE=My Passport
+ ID_MODEL_FROM_DATABASE=My Passport Essential (WDBAAA)
+
+usb:v1058p071D*
+ ID_MODEL_FROM_DATABASE=My Passport Studio (WDBALG)
 
 usb:v1058p0730*
- ID_MODEL_FROM_DATABASE=My Passport
+ ID_MODEL_FROM_DATABASE=My Passport Essential (WDBACY)
 
 usb:v1058p0740*
- ID_MODEL_FROM_DATABASE=My Passport
+ ID_MODEL_FROM_DATABASE=My Passport Essential (WDBACY)
+
+usb:v1058p0741*
+ ID_MODEL_FROM_DATABASE=My Passport Ultra
 
 usb:v1058p0742*
  ID_MODEL_FROM_DATABASE=My Passport Essential SE
 
 usb:v1058p0748*
- ID_MODEL_FROM_DATABASE=My Passport 1TB USB 3.0
+ ID_MODEL_FROM_DATABASE=My Passport (WDBKXH)
+
+usb:v1058p0810*
+ ID_MODEL_FROM_DATABASE=My Passport Ultra (WDBZFP)
 
 usb:v1058p0900*
  ID_MODEL_FROM_DATABASE=MyBook Essential External HDD
 
 usb:v1058p0901*
- ID_MODEL_FROM_DATABASE=MyBook External HDD
+ ID_MODEL_FROM_DATABASE=My Book Essential Edition (Green Ring) (WDG1U)
+
+usb:v1058p0902*
+ ID_MODEL_FROM_DATABASE=My Book Pro Edition (WDG1T)
 
 usb:v1058p0903*
  ID_MODEL_FROM_DATABASE=My Book Premium Edition
 
 usb:v1058p0910*
- ID_MODEL_FROM_DATABASE=MyBook Essential External HDD
+ ID_MODEL_FROM_DATABASE=My Book Essential Edition (Green Ring) (WDG1U)
 
 usb:v1058p1001*
- ID_MODEL_FROM_DATABASE=External Hard Disk [Elements]
+ ID_MODEL_FROM_DATABASE=Elements Desktop (WDE1U)
 
 usb:v1058p1003*
  ID_MODEL_FROM_DATABASE=Elements 1000 GB
 
 usb:v1058p1010*
- ID_MODEL_FROM_DATABASE=Elements External HDD
+ ID_MODEL_FROM_DATABASE=Elements Portable (WDBAAR)
 
 usb:v1058p1021*
- ID_MODEL_FROM_DATABASE=Elements 2TB
+ ID_MODEL_FROM_DATABASE=Elements Desktop (WDBAAU)
 
 usb:v1058p1023*
- ID_MODEL_FROM_DATABASE=Elements SE
+ ID_MODEL_FROM_DATABASE=Elements SE Portable (WDBABV)
+
+usb:v1058p1048*
+ ID_MODEL_FROM_DATABASE=Elements Portable (WDBU6Y)
+
+usb:v1058p10A2*
+ ID_MODEL_FROM_DATABASE=Elements SE Portable (WDBPCK)
+
+usb:v1058p10A8*
+ ID_MODEL_FROM_DATABASE=Elements Portable (WDBUZG)
+
+usb:v1058p1100*
+ ID_MODEL_FROM_DATABASE=My Book Essential Edition 2.0 (WDH1U)
 
 usb:v1058p1103*
  ID_MODEL_FROM_DATABASE=My Book Studio
@@ -38894,11 +39944,23 @@ usb:v1058p1104*
 usb:v1058p1105*
  ID_MODEL_FROM_DATABASE=My Book Studio II
 
+usb:v1058p1110*
+ ID_MODEL_FROM_DATABASE=My Book Essential (WDBAAF), My Book for Mac (WDBAAG)
+
+usb:v1058p1111*
+ ID_MODEL_FROM_DATABASE=My Book Elite (WDBAAH)
+
+usb:v1058p1112*
+ ID_MODEL_FROM_DATABASE=My Book Studio (WDBAAJ), My Book Studio LX (WDBACH)
+
 usb:v1058p1123*
- ID_MODEL_FROM_DATABASE=My Book 3.0
+ ID_MODEL_FROM_DATABASE=My Book 3.0 (WDBABP)
+
+usb:v1058p1130*
+ ID_MODEL_FROM_DATABASE=My Book Essential (WDBACW)
 
 usb:v1058p1140*
- ID_MODEL_FROM_DATABASE=My Book Essential USB3.0
+ ID_MODEL_FROM_DATABASE=My Book Essential (WDBACW)
 
 usb:v1059*
  ID_VENDOR_FROM_DATABASE=Giesecke & Devrient GmbH
@@ -39167,6 +40229,9 @@ usb:v106Fp0009*
 usb:v106Fp000A*
  ID_MODEL_FROM_DATABASE=CR10x Coin Recycler
 
+usb:v106Fp000C*
+ ID_MODEL_FROM_DATABASE=Xchange
+
 usb:v1076*
  ID_VENDOR_FROM_DATABASE=GCT Semiconductor, Inc.
 
@@ -39230,6 +40295,12 @@ usb:v1099*
 usb:v109A*
  ID_VENDOR_FROM_DATABASE=DATASOFT Systems GmbH
 
+usb:v109B*
+ ID_VENDOR_FROM_DATABASE=Hisense
+
+usb:v109Bp9118*
+ ID_MODEL_FROM_DATABASE=Medion P4013 Mobile
+
 usb:v109F*
  ID_VENDOR_FROM_DATABASE=eSOL Co., Ltd
 
@@ -39353,6 +40424,15 @@ usb:v10BF*
 usb:v10BFp0001*
  ID_MODEL_FROM_DATABASE=SmartHome PowerLinc
 
+usb:v10C3*
+ ID_VENDOR_FROM_DATABASE=Universal Laser Systems, Inc.
+
+usb:v10C3p00A4*
+ ID_MODEL_FROM_DATABASE=ULS PLS Series Laser Engraver Firmware Loader
+
+usb:v10C3p00A5*
+ ID_MODEL_FROM_DATABASE=ULS Print Support
+
 usb:v10C4*
  ID_VENDOR_FROM_DATABASE=Cygnal Integrated Products, Inc.
 
@@ -39404,6 +40484,12 @@ usb:v10C4p8461*
 usb:v10C4p8477*
  ID_MODEL_FROM_DATABASE=Balluff RFID Reader
 
+usb:v10C4p8496*
+ ID_MODEL_FROM_DATABASE=SiLabs Cypress FW downloader
+
+usb:v10C4p8497*
+ ID_MODEL_FROM_DATABASE=SiLabs Cypress EVB
+
 usb:v10C4p8605*
  ID_MODEL_FROM_DATABASE=dilitronics ESoLUX solar lighting controller
 
@@ -39422,6 +40508,9 @@ usb:v10C4p8863*
 usb:v10C4p8897*
  ID_MODEL_FROM_DATABASE=C8051F38x HDMI Splitter [UHBX]
 
+usb:v10C4p8918*
+ ID_MODEL_FROM_DATABASE=C8051F38x HDMI Audio Extractor [VSA-HA-DP]
+
 usb:v10C4pEA60*
  ID_MODEL_FROM_DATABASE=CP210x UART Bridge / myAVR mySmartUSB light
 
@@ -39803,6 +40892,9 @@ usb:v1141*
 usb:v1142*
  ID_VENDOR_FROM_DATABASE=CyberScan Technologies, Inc.
 
+usb:v1142p0709*
+ ID_MODEL_FROM_DATABASE=Cyberview High Speed Scanner
+
 usb:v1145*
  ID_VENDOR_FROM_DATABASE=Japan Radio Company
 
@@ -39833,6 +40925,9 @@ usb:v114D*
 usb:v114F*
  ID_VENDOR_FROM_DATABASE=Wavecom
 
+usb:v114Fp1234*
+ ID_MODEL_FROM_DATABASE=Fastrack Xtend FXT001 Modem
+
 usb:v115B*
  ID_VENDOR_FROM_DATABASE=Salix Technology Co., Ltd.
 
@@ -40023,7 +41118,7 @@ usb:v1199p683A*
  ID_MODEL_FROM_DATABASE=MC8785 Device
 
 usb:v1199p683C*
- ID_MODEL_FROM_DATABASE=MC8790 Device
+ ID_MODEL_FROM_DATABASE=Mobile Broadband 3G/UMTS (MC8790 Device)
 
 usb:v1199p6850*
  ID_MODEL_FROM_DATABASE=AirCard 880 Device
@@ -40091,6 +41186,12 @@ usb:v1199p9009*
 usb:v1199p900A*
  ID_MODEL_FROM_DATABASE=Gobi 2000 Wireless Modem
 
+usb:v1199p9055*
+ ID_MODEL_FROM_DATABASE=Gobi 9x15 Multimode 3G/4G LTE Modem (NAT mode)
+
+usb:v1199p9057*
+ ID_MODEL_FROM_DATABASE=Gobi 9x15 Multimode 3G/4G LTE Modem (IP passthrough mode)
+
 usb:v119A*
  ID_VENDOR_FROM_DATABASE=ZHAN QI Technology Co., Ltd
 
@@ -40133,12 +41234,30 @@ usb:v11ACp6565*
 usb:v11B0*
  ID_VENDOR_FROM_DATABASE=ATECH FLASH TECHNOLOGY
 
+usb:v11B0p6208*
+ ID_MODEL_FROM_DATABASE=PRO-28U
+
+usb:v11BE*
+ ID_VENDOR_FROM_DATABASE=R&D International NV
+
+usb:v11BEpF0A0*
+ ID_MODEL_FROM_DATABASE=Martin Maxxyz DMX
+
 usb:v11C5*
  ID_VENDOR_FROM_DATABASE=Inmax
 
 usb:v11C5p0521*
  ID_MODEL_FROM_DATABASE=IMT-0521 Smartcard Reader
 
+usb:v11CA*
+ ID_VENDOR_FROM_DATABASE=VeriFone Inc
+
+usb:v11CAp0207*
+ ID_MODEL_FROM_DATABASE=PIN Pad VX 810
+
+usb:v11CAp0220*
+ ID_MODEL_FROM_DATABASE=PIN Pad VX 805
+
 usb:v11DB*
  ID_VENDOR_FROM_DATABASE=Topfield Co., Ltd.
 
@@ -40169,6 +41288,9 @@ usb:v11F5p0005*
 usb:v11F5p0008*
  ID_MODEL_FROM_DATABASE=UMTS/HSDPA Data Card
 
+usb:v11F5p0101*
+ ID_MODEL_FROM_DATABASE=RCU Connect
+
 usb:v11F6*
  ID_VENDOR_FROM_DATABASE=Prolific
 
@@ -40179,7 +41301,7 @@ usb:v11F7*
  ID_VENDOR_FROM_DATABASE=Alcatel (?)
 
 usb:v11F7p02DF*
- ID_MODEL_FROM_DATABASE=TD10 Mobile phone USB cable
+ ID_MODEL_FROM_DATABASE=Serial cable (v2) for TD-10 Mobile Phone
 
 usb:v1203*
  ID_VENDOR_FROM_DATABASE=TSC Auto ID Technology Co., Ltd
@@ -40247,6 +41369,9 @@ usb:v1228p0012*
 usb:v1228p0015*
  ID_MODEL_FROM_DATABASE=TPaq21/MPaq21 Datalogger
 
+usb:v1228p584C*
+ ID_MODEL_FROM_DATABASE=XL2 Logger
+
 usb:v1230*
  ID_VENDOR_FROM_DATABASE=Chipidea-Microelectronica, S.A.
 
@@ -40269,23 +41394,113 @@ usb:v1234pED02*
  ID_MODEL_FROM_DATABASE=Emotiv EPOC Developer Headset Wireless Dongle
 
 usb:v1235*
- ID_VENDOR_FROM_DATABASE=Novation EMS
+ ID_VENDOR_FROM_DATABASE=Focusrite-Novation
 
 usb:v1235p0001*
- ID_MODEL_FROM_DATABASE=ReMOTE Audio/XStation
+ ID_MODEL_FROM_DATABASE=ReMOTE Audio/XStation First Edition
 
 usb:v1235p0002*
  ID_MODEL_FROM_DATABASE=Speedio
 
 usb:v1235p0003*
- ID_MODEL_FROM_DATABASE=ReMOTE ZeRO SL
+ ID_MODEL_FROM_DATABASE=RemoteSL + ZeroSL
+
+usb:v1235p0004*
+ ID_MODEL_FROM_DATABASE=ReMOTE LE
+
+usb:v1235p0005*
+ ID_MODEL_FROM_DATABASE=XIOSynth [First Edition]
+
+usb:v1235p0006*
+ ID_MODEL_FROM_DATABASE=XStation
+
+usb:v1235p0007*
+ ID_MODEL_FROM_DATABASE=XIOSynth
+
+usb:v1235p0008*
+ ID_MODEL_FROM_DATABASE=ReMOTE SL Compact
+
+usb:v1235p0009*
+ ID_MODEL_FROM_DATABASE=nIO
+
+usb:v1235p000A*
+ ID_MODEL_FROM_DATABASE=Nocturn
+
+usb:v1235p000B*
+ ID_MODEL_FROM_DATABASE=ReMOTE SL MkII
+
+usb:v1235p000C*
+ ID_MODEL_FROM_DATABASE=ZeRO MkII
+
+usb:v1235p000E*
+ ID_MODEL_FROM_DATABASE=Launchpad
+
+usb:v1235p0010*
+ ID_MODEL_FROM_DATABASE=Saffire 6
+
+usb:v1235p0011*
+ ID_MODEL_FROM_DATABASE=Ultranova
+
+usb:v1235p0012*
+ ID_MODEL_FROM_DATABASE=Nocturn Keyboard
+
+usb:v1235p0013*
+ ID_MODEL_FROM_DATABASE=VRM Box
+
+usb:v1235p0014*
+ ID_MODEL_FROM_DATABASE=VRM Box Audio Class (2-out)
+
+usb:v1235p0015*
+ ID_MODEL_FROM_DATABASE=Dicer
+
+usb:v1235p0016*
+ ID_MODEL_FROM_DATABASE=Ultranova
+
+usb:v1235p0018*
+ ID_MODEL_FROM_DATABASE=Twitch
+
+usb:v1235p0019*
+ ID_MODEL_FROM_DATABASE=Impulse 25
+
+usb:v1235p001A*
+ ID_MODEL_FROM_DATABASE=Impulse 49
+
+usb:v1235p001B*
+ ID_MODEL_FROM_DATABASE=Impulse 61
 
 usb:v1235p4661*
  ID_MODEL_FROM_DATABASE=ReMOTE25
 
+usb:v1235p8000*
+ ID_MODEL_FROM_DATABASE=Scarlett 18i6
+
+usb:v1235p8002*
+ ID_MODEL_FROM_DATABASE=Scarlett 8i6
+
 usb:v1235p8006*
  ID_MODEL_FROM_DATABASE=Focusrite Scarlett 2i2
 
+usb:v1235p8008*
+ ID_MODEL_FROM_DATABASE=Saffire 6
+
+usb:v1235p800A*
+ ID_MODEL_FROM_DATABASE=Scarlett 2i4
+
+usb:v1235p800C*
+ ID_MODEL_FROM_DATABASE=Scarlett 18i20
+
+usb:v1235p800E*
+ ID_MODEL_FROM_DATABASE=iTrack Solo
+
+usb:v1235p8010*
+ ID_MODEL_FROM_DATABASE=Forte
+
+usb:v1235p8012*
+ ID_MODEL_FROM_DATABASE=Scarlett 6i6
+
+usb:v1235p8014*
+ ID_MODEL_FROM_DATABASE=Scarlett 18i8
+
 usb:v1241*
  ID_VENDOR_FROM_DATABASE=Belkin
 
@@ -40305,7 +41520,7 @@ usb:v1241p1166*
  ID_MODEL_FROM_DATABASE=MI-2150 Trust Mouse
 
 usb:v1241p1177*
- ID_MODEL_FROM_DATABASE=F8E842-DL Mouse
+ ID_MODEL_FROM_DATABASE=Mouse [HT82M21A]
 
 usb:v1241p1503*
  ID_MODEL_FROM_DATABASE=Keyboard
@@ -40358,6 +41573,9 @@ usb:v125Fp312A*
 usb:v125Fp312B*
  ID_MODEL_FROM_DATABASE=Superior S102 Pro
 
+usb:v125FpA22A*
+ ID_MODEL_FROM_DATABASE=DashDrive Elite HE720 500GB
+
 usb:v125FpA91A*
  ID_MODEL_FROM_DATABASE=Portable HDD CH91
 
@@ -40373,6 +41591,9 @@ usb:v125FpC93A*
 usb:v125FpC96A*
  ID_MODEL_FROM_DATABASE=C906 Flash Drive
 
+usb:v125FpCB10*
+ ID_MODEL_FROM_DATABASE=Dash Drive UV100
+
 usb:v1260*
  ID_VENDOR_FROM_DATABASE=Standard Microsystems Corp.
 
@@ -40532,6 +41753,9 @@ usb:v1283p0150*
 usb:v1286*
  ID_VENDOR_FROM_DATABASE=Marvell Semiconductor, Inc.
 
+usb:v1286p00BC*
+ ID_MODEL_FROM_DATABASE=Marvell JTAG Probe
+
 usb:v1286p1FAB*
  ID_MODEL_FROM_DATABASE=88W8338 [Libertas] 802.11g
 
@@ -40628,6 +41852,12 @@ usb:v12C4p0006*
 usb:v12C4p0008*
  ID_MODEL_FROM_DATABASE=Teleprompter Foot Control (v1)
 
+usb:v12CF*
+ ID_VENDOR_FROM_DATABASE=DEXIN
+
+usb:v12CFp0170*
+ ID_MODEL_FROM_DATABASE=Tt eSPORTS BLACK Gaming mouse
+
 usb:v12D1*
  ID_VENDOR_FROM_DATABASE=Huawei Technologies Co., Ltd.
 
@@ -40697,9 +41927,15 @@ usb:v12D1p14CF*
 usb:v12D1p14D1*
  ID_MODEL_FROM_DATABASE=K3770 3G Modem (Mass Storage Mode)
 
+usb:v12D1p14DB*
+ ID_MODEL_FROM_DATABASE=E353/E3131
+
 usb:v12D1p14F1*
  ID_MODEL_FROM_DATABASE=Gobi 3000 HSPA+ Modem
 
+usb:v12D1p14FE*
+ ID_MODEL_FROM_DATABASE=Modem (Mass Storage Mode)
+
 usb:v12D1p1501*
  ID_MODEL_FROM_DATABASE=Pulse
 
@@ -40721,6 +41957,12 @@ usb:v12D1p1521*
 usb:v12D1p155A*
  ID_MODEL_FROM_DATABASE=R205 Mobile WiFi (CD-ROM mode)
 
+usb:v12D1p1575*
+ ID_MODEL_FROM_DATABASE=K5150 LTE modem
+
+usb:v12D1p15CA*
+ ID_MODEL_FROM_DATABASE=E3131 3G/UMTS/HSPA+ Modem (Mass Storage Mode)
+
 usb:v12D1p1805*
  ID_MODEL_FROM_DATABASE=AT&T Go Phone U2800A phone
 
@@ -40736,6 +41978,12 @@ usb:v12D1p1C20*
 usb:v12D1p1D50*
  ID_MODEL_FROM_DATABASE=ET302s TD-SCDMA/TD-HSDPA Mobile Broadband
 
+usb:v12D1p1F01*
+ ID_MODEL_FROM_DATABASE=E353/E3131 (Mass storage mode)
+
+usb:v12D1p1F16*
+ ID_MODEL_FROM_DATABASE=K5150 LTE modem (Mass Storage Mode)
+
 usb:v12D1p380B*
  ID_MODEL_FROM_DATABASE=WiMAX USB modem(s)
 
@@ -40754,6 +42002,12 @@ usb:v12D6p0888*
 usb:v12D7*
  ID_VENDOR_FROM_DATABASE=BETTER WIRE FACTORY CO., LTD.
 
+usb:v12D8*
+ ID_VENDOR_FROM_DATABASE=Araneus Information Systems Oy
+
+usb:v12D8p0001*
+ ID_MODEL_FROM_DATABASE=Alea I True Random Number Generator
+
 usb:v12E6*
  ID_VENDOR_FROM_DATABASE=Waldorf Music GmbH
 
@@ -40797,7 +42051,7 @@ usb:v1307p0163*
  ID_MODEL_FROM_DATABASE=256MB/512MB/1GB Flash Drive
 
 usb:v1307p0165*
- ID_MODEL_FROM_DATABASE=2GB/4GB Flash Drive
+ ID_MODEL_FROM_DATABASE=2GB/4GB/8GB Flash Drive
 
 usb:v1307p0190*
  ID_MODEL_FROM_DATABASE=Ut190 8 GB Flash Drive with MicroSD reader
@@ -40838,6 +42092,51 @@ usb:v1312*
 usb:v1313*
  ID_VENDOR_FROM_DATABASE=ThorLabs
 
+usb:v1313p0010*
+ ID_MODEL_FROM_DATABASE=LC1 Linear Camera (Jungo)
+
+usb:v1313p0011*
+ ID_MODEL_FROM_DATABASE=SP1 Spectrometer (Jungo)
+
+usb:v1313p0012*
+ ID_MODEL_FROM_DATABASE=SP2 Spectrometer (Jungo)
+
+usb:v1313p0110*
+ ID_MODEL_FROM_DATABASE=LC1 Linear Camera (VISA)
+
+usb:v1313p0111*
+ ID_MODEL_FROM_DATABASE=SP1 Spectrometer (VISA)
+
+usb:v1313p0112*
+ ID_MODEL_FROM_DATABASE=SP2 Spectrometer (VISA)
+
+usb:v1313p8001*
+ ID_MODEL_FROM_DATABASE=TXP-Series Slot (TXP5001, TXP5004)
+
+usb:v1313p8012*
+ ID_MODEL_FROM_DATABASE=BC106 Camera Beam Profiler
+
+usb:v1313p8013*
+ ID_MODEL_FROM_DATABASE=WFS10 Wavefront Sensor
+
+usb:v1313p8017*
+ ID_MODEL_FROM_DATABASE=BC206 Camera Beam Profiler
+
+usb:v1313p8019*
+ ID_MODEL_FROM_DATABASE=BP2 Multi Slit Beam Profiler
+
+usb:v1313p8020*
+ ID_MODEL_FROM_DATABASE=PM300 Optical Power Meter
+
+usb:v1313p8021*
+ ID_MODEL_FROM_DATABASE=PM300E Optical Power and Energy Meter
+
+usb:v1313p8022*
+ ID_MODEL_FROM_DATABASE=PM320E Optical Power and Energy Meter
+
+usb:v1313p8030*
+ ID_MODEL_FROM_DATABASE=ER100 Extinction Ratio Meter
+
 usb:v1313p8070*
  ID_MODEL_FROM_DATABASE=PM100D
 
@@ -40946,6 +42245,12 @@ usb:v132Bp2045*
 usb:v132Bp2049*
  ID_MODEL_FROM_DATABASE=Magicolor 2490MF
 
+usb:v133E*
+ ID_VENDOR_FROM_DATABASE=Kemper Digital GmbH
+
+usb:v133Ep0815*
+ ID_MODEL_FROM_DATABASE=Virus TI Desktop
+
 usb:v1342*
  ID_VENDOR_FROM_DATABASE=Mobility
 
@@ -40967,6 +42272,18 @@ usb:v1342p0204*
 usb:v1342p0304*
  ID_MODEL_FROM_DATABASE=EasiDock Ethernet
 
+usb:v1343*
+ ID_VENDOR_FROM_DATABASE=Citizen Systems
+
+usb:v1343p0003*
+ ID_MODEL_FROM_DATABASE=CX / DNP DS40
+
+usb:v1343p0004*
+ ID_MODEL_FROM_DATABASE=CX-W / DNP DS80
+
+usb:v1343p0005*
+ ID_MODEL_FROM_DATABASE=CY / DNP DSRX
+
 usb:v1345*
  ID_VENDOR_FROM_DATABASE=Sino Lite Technology Corp.
 
@@ -40994,6 +42311,12 @@ usb:v1347p0403*
 usb:v1347p0404*
  ID_MODEL_FROM_DATABASE=G2/G3/G4 CCD-F KAF CCD
 
+usb:v1347p0405*
+ ID_MODEL_FROM_DATABASE=Gx CCD-I CCD
+
+usb:v1347p0406*
+ ID_MODEL_FROM_DATABASE=Gx CCD-F CCD
+
 usb:v1347p0410*
  ID_MODEL_FROM_DATABASE=G1-0400 CCD
 
@@ -41033,6 +42356,9 @@ usb:v134E*
 usb:v1357*
  ID_VENDOR_FROM_DATABASE=P&E Microcomputer Systems
 
+usb:v1357p0089*
+ ID_MODEL_FROM_DATABASE=OpenSDA - CDC Serial Port
+
 usb:v1357p0503*
  ID_MODEL_FROM_DATABASE=USB-ML-12 HCS08/HCS12 Multilink
 
@@ -41043,7 +42369,7 @@ usb:v1366*
  ID_VENDOR_FROM_DATABASE=SEGGER
 
 usb:v1366p0101*
- ID_MODEL_FROM_DATABASE=J-Link ARM
+ ID_MODEL_FROM_DATABASE=J-Link PLUS
 
 usb:v136B*
  ID_VENDOR_FROM_DATABASE=STEC
@@ -41141,6 +42467,12 @@ usb:v138Ap003C*
 usb:v138Ap003D*
  ID_MODEL_FROM_DATABASE=VFS491
 
+usb:v138Ap003F*
+ ID_MODEL_FROM_DATABASE=VFS495 Fingerprint Reader
+
+usb:v138Ap0050*
+ ID_MODEL_FROM_DATABASE=Swipe Fingerprint Sensor
+
 usb:v138E*
  ID_VENDOR_FROM_DATABASE=Jungo LTD
 
@@ -41153,6 +42485,9 @@ usb:v1390*
 usb:v1390p0001*
  ID_MODEL_FROM_DATABASE=GO 520 T/GO 630/ONE XL (v9)
 
+usb:v1390p5454*
+ ID_MODEL_FROM_DATABASE=Blue & Me 2
+
 usb:v1391*
  ID_VENDOR_FROM_DATABASE=IdealTEK, Inc.
 
@@ -41255,6 +42590,15 @@ usb:v13B1p0039*
 usb:v13B1p003A*
  ID_MODEL_FROM_DATABASE=AE2500 802.11abgn Wireless Adapter [Broadcom BCM43236]
 
+usb:v13B1p003B*
+ ID_MODEL_FROM_DATABASE=AE3000 802.11abgn (3x3) Wireless Adapter [Ralink RT3573]
+
+usb:v13B1p003E*
+ ID_MODEL_FROM_DATABASE=AE6000 802.11a/b/g/n/ac Wireless Adapter [MediaTek MT7610U]
+
+usb:v13B1p003F*
+ ID_MODEL_FROM_DATABASE=WUSB6300 802.11a/b/g/n/ac Wireless Adapter [Realtek RTL8812AU]
+
 usb:v13B1p13B1*
  ID_MODEL_FROM_DATABASE=WUSB200: Wireless-G Business Network Adapter with Rangebooster
 
@@ -41271,7 +42615,7 @@ usb:v13BA*
  ID_VENDOR_FROM_DATABASE=PCPlay
 
 usb:v13BAp0001*
- ID_MODEL_FROM_DATABASE=König Electronic CMP-KEYPAD12 Numeric Keypad
+ ID_MODEL_FROM_DATABASE=Konig Electronic CMP-KEYPAD12 Numeric Keypad
 
 usb:v13BAp0017*
  ID_MODEL_FROM_DATABASE=PS/2 Keyboard+Mouse Adapter
@@ -41438,6 +42782,12 @@ usb:v13D3p3315*
 usb:v13D3p3375*
  ID_MODEL_FROM_DATABASE=Atheros AR3012 Bluetooth 4.0 Adapter
 
+usb:v13D3p3392*
+ ID_MODEL_FROM_DATABASE=Azurewave 43228+20702
+
+usb:v13D3p3394*
+ ID_MODEL_FROM_DATABASE=Bluetooth
+
 usb:v13D3p5070*
  ID_MODEL_FROM_DATABASE=Webcam
 
@@ -41450,9 +42800,15 @@ usb:v13D3p5115*
 usb:v13D3p5116*
  ID_MODEL_FROM_DATABASE=Integrated Webcam
 
+usb:v13D3p5122*
+ ID_MODEL_FROM_DATABASE=2M Integrated Webcam
+
 usb:v13D3p5126*
  ID_MODEL_FROM_DATABASE=PC Cam
 
+usb:v13D3p5130*
+ ID_MODEL_FROM_DATABASE=Integrated Webcam
+
 usb:v13D3p5702*
  ID_MODEL_FROM_DATABASE=UVC VGA Webcam
 
@@ -41516,6 +42872,9 @@ usb:v13FDp0840*
 usb:v13FDp0841*
  ID_MODEL_FROM_DATABASE=Samsung SE-T084M DVD-RW
 
+usb:v13FDp1040*
+ ID_MODEL_FROM_DATABASE=INIC-1511L PATA Bridge
+
 usb:v13FDp1340*
  ID_MODEL_FROM_DATABASE=Hi-Speed USB to SATA Bridge
 
@@ -41525,9 +42884,15 @@ usb:v13FDp160F*
 usb:v13FDp1640*
  ID_MODEL_FROM_DATABASE=INIC-1610L SATA Bridge
 
+usb:v13FDp1669*
+ ID_MODEL_FROM_DATABASE=INIC-1609PN
+
 usb:v13FDp1840*
  ID_MODEL_FROM_DATABASE=INIC-1608 SATA bridge
 
+usb:v13FDp1E40*
+ ID_MODEL_FROM_DATABASE=INIC-1610P SATA bridge
+
 usb:v13FE*
  ID_VENDOR_FROM_DATABASE=Kingston Technology Company Inc.
 
@@ -41547,10 +42912,10 @@ usb:v13FEp1E50*
  ID_MODEL_FROM_DATABASE=U3 Smart Drive
 
 usb:v13FEp1F00*
- ID_MODEL_FROM_DATABASE=DataTraveler 2.0 4GB Flash Drive / Patriot Xporter 32GB (PEF32GUSB) Flash Drive
+ ID_MODEL_FROM_DATABASE=Kingston DataTraveler / Patriot Xporter
 
 usb:v13FEp1F23*
- ID_MODEL_FROM_DATABASE=2Gb
+ ID_MODEL_FROM_DATABASE=PS2232 flash drive controller
 
 usb:v13FEp2240*
  ID_MODEL_FROM_DATABASE=microSD card reader
@@ -41561,12 +42926,18 @@ usb:v13FEp3100*
 usb:v13FEp3123*
  ID_MODEL_FROM_DATABASE=Verbatim STORE N GO 4GB
 
+usb:v13FEp3600*
+ ID_MODEL_FROM_DATABASE=flash drive (4GB, EMTEC)
+
 usb:v13FEp3800*
  ID_MODEL_FROM_DATABASE=Rage XT Flash Drive
 
 usb:v13FEp3E00*
  ID_MODEL_FROM_DATABASE=Flash Drive
 
+usb:v13FEp5000*
+ ID_MODEL_FROM_DATABASE=USB flash drive (32 GB SHARKOON Accelerate)
+
 usb:v13FEp5100*
  ID_MODEL_FROM_DATABASE=Flash Drive
 
@@ -41666,6 +43037,12 @@ usb:v1415p2000*
 usb:v1419*
  ID_VENDOR_FROM_DATABASE=ABILITY ENTERPRISE CO., LTD.
 
+usb:v1421*
+ ID_VENDOR_FROM_DATABASE=Sensor Technology
+
+usb:v1421p0605*
+ ID_MODEL_FROM_DATABASE=Sentech Camera
+
 usb:v1429*
  ID_VENDOR_FROM_DATABASE=Vega Technologies Industrial (Austria) Co.
 
@@ -41768,6 +43145,18 @@ usb:v1457p5118*
 usb:v1457p5119*
  ID_MODEL_FROM_DATABASE=OpenMoko Neo1973 u-boot cdc_acm serial port
 
+usb:v1457p511A*
+ ID_MODEL_FROM_DATABASE=HXD8 u-boot usbtty CDC ACM Mode
+
+usb:v1457p511B*
+ ID_MODEL_FROM_DATABASE=SMDK2440 u-boot usbtty CDC ACM mode
+
+usb:v1457p511C*
+ ID_MODEL_FROM_DATABASE=SMDK2443 u-boot usbtty CDC ACM mode
+
+usb:v1457p511D*
+ ID_MODEL_FROM_DATABASE=QT2410 u-boot usbtty CDC ACM mode
+
 usb:v1457p5120*
  ID_MODEL_FROM_DATABASE=OpenMoko Neo1973 u-boot usbtty generic serial
 
@@ -41927,6 +43316,9 @@ usb:v148E*
 usb:v148F*
  ID_VENDOR_FROM_DATABASE=Ralink Technology, Corp.
 
+usb:v148Fp1000*
+ ID_MODEL_FROM_DATABASE=Motorola BC4 Bluetooth 3.0+HS Adapter
+
 usb:v148Fp1706*
  ID_MODEL_FROM_DATABASE=RT2500USB Wireless Adapter
 
@@ -41975,6 +43367,9 @@ usb:v148Fp5372*
 usb:v148Fp5572*
  ID_MODEL_FROM_DATABASE=RT5572 Wireless Adapter
 
+usb:v148Fp7601*
+ ID_MODEL_FROM_DATABASE=MT7601U Wireless Adapter
+
 usb:v148Fp9020*
  ID_MODEL_FROM_DATABASE=RT2500USB Wireless Adapter
 
@@ -41990,6 +43385,18 @@ usb:v1491p0020*
 usb:v1493*
  ID_VENDOR_FROM_DATABASE=Suunto
 
+usb:v1493p0010*
+ ID_MODEL_FROM_DATABASE=Bluebird [Ambit]
+
+usb:v1493p0019*
+ ID_MODEL_FROM_DATABASE=Duck [Ambit2]
+
+usb:v1493p001A*
+ ID_MODEL_FROM_DATABASE=Colibri [Ambit2 S]
+
+usb:v1493p001D*
+ ID_MODEL_FROM_DATABASE=Greentit [Ambit2 R]
+
 usb:v1497*
  ID_VENDOR_FROM_DATABASE=Panstrong Company Ltd.
 
@@ -42110,6 +43517,9 @@ usb:v14CD*
 usb:v14CDp121C*
  ID_MODEL_FROM_DATABASE=microSD card reader
 
+usb:v14CDp121F*
+ ID_MODEL_FROM_DATABASE=microSD CardReader SY-T18
+
 usb:v14CDp123A*
  ID_MODEL_FROM_DATABASE=SD/MMC/RS-MMC Card Reader
 
@@ -42123,7 +43533,7 @@ usb:v14CDp6116*
  ID_MODEL_FROM_DATABASE=M6116 SATA Bridge
 
 usb:v14CDp6600*
- ID_MODEL_FROM_DATABASE=USB 2.0 IDE DEVICE
+ ID_MODEL_FROM_DATABASE=M110E PATA bridge
 
 usb:v14CDp6700*
  ID_MODEL_FROM_DATABASE=Card Reader
@@ -42158,6 +43568,9 @@ usb:v14E1*
 usb:v14E1p5000*
  ID_MODEL_FROM_DATABASE=PenMount 5000 Touch Controller
 
+usb:v14E4*
+ ID_VENDOR_FROM_DATABASE=Broadcom Corp.
+
 usb:v14E5*
  ID_VENDOR_FROM_DATABASE=SAIN Information & Communications Co., Ltd.
 
@@ -42206,6 +43619,15 @@ usb:v1501*
 usb:v1509*
  ID_VENDOR_FROM_DATABASE=First International Computer, Inc.
 
+usb:v1509p0A01*
+ ID_MODEL_FROM_DATABASE=LI-3100 Area Meter
+
+usb:v1509p0A02*
+ ID_MODEL_FROM_DATABASE=LI-7000 CO2/H2O Gas Analyzer
+
+usb:v1509p0A03*
+ ID_MODEL_FROM_DATABASE=C-DiGit Blot Scanner
+
 usb:v1509p9242*
  ID_MODEL_FROM_DATABASE=eHome Infrared Transceiver
 
@@ -42245,6 +43667,12 @@ usb:v1518p0001*
 usb:v1518p0002*
  ID_MODEL_FROM_DATABASE=HDReye (before firmware loads)
 
+usb:v1519*
+ ID_VENDOR_FROM_DATABASE=Comneon
+
+usb:v1519p0020*
+ ID_MODEL_FROM_DATABASE=HSIC Device
+
 usb:v1520*
  ID_VENDOR_FROM_DATABASE=Bitwire Corp.
 
@@ -42272,6 +43700,15 @@ usb:v1529p3100*
 usb:v152A*
  ID_VENDOR_FROM_DATABASE=Thesycon Systemsoftware & Consulting GmbH
 
+usb:v152Ap8400*
+ ID_MODEL_FROM_DATABASE=INI DVS128
+
+usb:v152Ap840D*
+ ID_MODEL_FROM_DATABASE=INI DAViS
+
+usb:v152Ap841A*
+ ID_MODEL_FROM_DATABASE=INI DAViS FX3
+
 usb:v152D*
  ID_VENDOR_FROM_DATABASE=JMicron Technology Corp. / JMicron USA Technology Corp.
 
@@ -42329,6 +43766,9 @@ usb:v1532p0007*
 usb:v1532p0013*
  ID_MODEL_FROM_DATABASE=Orochi mouse
 
+usb:v1532p0015*
+ ID_MODEL_FROM_DATABASE=Naga Mouse
+
 usb:v1532p0016*
  ID_MODEL_FROM_DATABASE=DeathAdder Mouse
 
@@ -42356,9 +43796,21 @@ usb:v1532p0102*
 usb:v1532p0109*
  ID_MODEL_FROM_DATABASE=Lycosa Keyboard
 
+usb:v1532p0113*
+ ID_MODEL_FROM_DATABASE=RZ07-0074 Gaming Keypad [Orbweaver]
+
 usb:v1532p0300*
  ID_MODEL_FROM_DATABASE=RZ06-0063 Motion Sensing Controllers [Hydra]
 
+usb:v153B*
+ ID_VENDOR_FROM_DATABASE=TerraTec Electronic GmbH
+
+usb:v153Bp1181*
+ ID_MODEL_FROM_DATABASE=Cinergy S2 PCIe Dual Port 1
+
+usb:v153Bp1182*
+ ID_MODEL_FROM_DATABASE=Cinergy S2 PCIe Dual Port 2
+
 usb:v1546*
  ID_VENDOR_FROM_DATABASE=U-Blox AG
 
@@ -42380,12 +43832,18 @@ usb:v154B*
 usb:v154Bp0010*
  ID_MODEL_FROM_DATABASE=USB 2.0 Flash Drive
 
+usb:v154Bp0048*
+ ID_MODEL_FROM_DATABASE=Flash Drive
+
 usb:v154Bp004D*
  ID_MODEL_FROM_DATABASE=8 GB Flash Drive
 
 usb:v154Bp0057*
  ID_MODEL_FROM_DATABASE=32GB Micro Slide Attache Flash Drive
 
+usb:v154Bp007A*
+ ID_MODEL_FROM_DATABASE=8GB Classic Attache Flash Drive
+
 usb:v154Bp6545*
  ID_MODEL_FROM_DATABASE=FD Device
 
@@ -42522,7 +43980,10 @@ usb:v15A2p0052*
  ID_MODEL_FROM_DATABASE=i.MX50 SystemOnChip in RecoveryMode
 
 usb:v15A2p0054*
- ID_MODEL_FROM_DATABASE=i.MX6Q SystemOnChip in RecoveryMode
+ ID_MODEL_FROM_DATABASE=i.MX 6Dual/6Quad SystemOnChip in RecoveryMode
+
+usb:v15A2p0061*
+ ID_MODEL_FROM_DATABASE=i.MX 6Solo/6DualLite SystemOnChip in RecoveryMode
 
 usb:v15A4*
  ID_VENDOR_FROM_DATABASE=Afatech Technologies, Inc.
@@ -42632,6 +44093,9 @@ usb:v15C2p0036*
 usb:v15C2p0038*
  ID_MODEL_FROM_DATABASE=GD01 MX LCD Display/IR Receiver
 
+usb:v15C2p0042*
+ ID_MODEL_FROM_DATABASE=Antec Veris Multimedia Station E-Z IR Receiver
+
 usb:v15C2pFFDA*
  ID_MODEL_FROM_DATABASE=iMON PAD Remote Controller
 
@@ -42716,6 +44180,9 @@ usb:v15D9p0A4C*
 usb:v15D9p0A4D*
  ID_MODEL_FROM_DATABASE=Optical Mouse
 
+usb:v15D9p0A4F*
+ ID_MODEL_FROM_DATABASE=Optical Mouse
+
 usb:v15DC*
  ID_VENDOR_FROM_DATABASE=Hynix Semiconductor Inc.
 
@@ -43499,6 +44966,15 @@ usb:v1690p0740*
 usb:v1690p0901*
  ID_MODEL_FROM_DATABASE=Voyager 205 ADSL Router
 
+usb:v1690p2000*
+ ID_MODEL_FROM_DATABASE=naturaSign Pad Standard
+
+usb:v1690p2001*
+ ID_MODEL_FROM_DATABASE=naturaSign Pad Standard
+
+usb:v1690pFE12*
+ ID_MODEL_FROM_DATABASE=Bootloader
+
 usb:v1696*
  ID_VENDOR_FROM_DATABASE=Hitachi Video and Information System, Inc.
 
@@ -43661,6 +45137,9 @@ usb:v16C0p06B4*
 usb:v16C0p06B5*
  ID_MODEL_FROM_DATABASE=USB2LPT with 3 interfaces (native, HID, printer)
 
+usb:v16C0p0762*
+ ID_MODEL_FROM_DATABASE=Osmocom SIMtrace
+
 usb:v16C0p076B*
  ID_MODEL_FROM_DATABASE=OpenPCD 13.56MHz RFID Reader
 
@@ -43751,6 +45230,15 @@ usb:v16D0p075D*
 usb:v16D0p080A*
  ID_MODEL_FROM_DATABASE=S2E1 Interface
 
+usb:v16D0p0870*
+ ID_MODEL_FROM_DATABASE=Kaufmann Automotive GmbH, RKS+CAN Interface
+
+usb:v16D1*
+ ID_VENDOR_FROM_DATABASE=Suprema Inc.
+
+usb:v16D1p0401*
+ ID_MODEL_FROM_DATABASE=SUP-SFR400(A) BioMini Fingerprint Reader
+
 usb:v16D3*
  ID_VENDOR_FROM_DATABASE=Frontline Test Equipment, Inc.
 
@@ -43766,6 +45254,9 @@ usb:v16D5p6501*
 usb:v16D5p6502*
  ID_MODEL_FROM_DATABASE=CDMA/UMTS/GPRS modem
 
+usb:v16D5p6603*
+ ID_MODEL_FROM_DATABASE=ADU-890WH modem
+
 usb:v16D6*
  ID_VENDOR_FROM_DATABASE=JABLOCOM s.r.o.
 
@@ -43862,6 +45353,18 @@ usb:v170Bp0011*
 usb:v170D*
  ID_VENDOR_FROM_DATABASE=Avnera
 
+usb:v1711*
+ ID_VENDOR_FROM_DATABASE=Leica Microsystems
+
+usb:v1711p3020*
+ ID_MODEL_FROM_DATABASE=IC80 HD Camera
+
+usb:v1724*
+ ID_VENDOR_FROM_DATABASE=Meyer Instruments (MIS)
+
+usb:v1724p0115*
+ ID_MODEL_FROM_DATABASE=PAXcam5
+
 usb:v1725*
  ID_VENDOR_FROM_DATABASE=Vitesse Semiconductor
 
@@ -43949,9 +45452,21 @@ usb:v1737p0078*
 usb:v1737p0079*
  ID_MODEL_FROM_DATABASE=WUSB600N v2 Dual-Band Wireless-N Network Adapter [Ralink RT3572]
 
+usb:v173D*
+ ID_VENDOR_FROM_DATABASE=QSENN
+
+usb:v173Dp0002*
+ ID_MODEL_FROM_DATABASE=GP-K7000 keyboard
+
 usb:v1740*
  ID_VENDOR_FROM_DATABASE=Senao
 
+usb:v1740p0100*
+ ID_MODEL_FROM_DATABASE=EUB1200AC AC1200 DB Wireless Adapter [Realtek RTL8812AU]
+
+usb:v1740p0600*
+ ID_MODEL_FROM_DATABASE=EUB600v1 802.11abgn Wireless Adapter [Ralink RT3572]
+
 usb:v1740p0605*
  ID_MODEL_FROM_DATABASE=LevelOne WUA-0605 N_Max Wireless USB Adapter
 
@@ -43991,14 +45506,23 @@ usb:v1740p9801*
 usb:v1743*
  ID_VENDOR_FROM_DATABASE=General Atomics
 
+usb:v1748*
+ ID_VENDOR_FROM_DATABASE=MQP Electronics
+
+usb:v1748p0101*
+ ID_MODEL_FROM_DATABASE=Packet-Master USB12
+
 usb:v174C*
  ID_VENDOR_FROM_DATABASE=ASMedia Technology Inc.
 
 usb:v174Cp5106*
  ID_MODEL_FROM_DATABASE=Transcend StoreJet 25M3
 
+usb:v174Cp5136*
+ ID_MODEL_FROM_DATABASE=ASM1053 SATA 6Gb/s bridge
+
 usb:v174Cp55AA*
- ID_MODEL_FROM_DATABASE=ASMedia 2105 SATA bridge
+ ID_MODEL_FROM_DATABASE=ASM1051 SATA 3Gb/s bridge
 
 usb:v174F*
  ID_VENDOR_FROM_DATABASE=Syntek
@@ -44126,6 +45650,9 @@ usb:v1781p0C31*
 usb:v1781p0C9F*
  ID_MODEL_FROM_DATABASE=USBtiny
 
+usb:v1781p1EEF*
+ ID_MODEL_FROM_DATABASE=OpenAPC SecuKey
+
 usb:v1782*
  ID_VENDOR_FROM_DATABASE=Spreadtrum Communications Inc.
 
@@ -44195,6 +45722,9 @@ usb:v17A0p0100*
 usb:v17A0p0101*
  ID_MODEL_FROM_DATABASE=UB1 boundary microphone
 
+usb:v17A0p0120*
+ ID_MODEL_FROM_DATABASE=Meteorite condenser microphone
+
 usb:v17A0p0200*
  ID_MODEL_FROM_DATABASE=StudioDock monitors (internal hub)
 
@@ -44210,6 +45740,9 @@ usb:v17A0p0301*
 usb:v17A0p0302*
  ID_MODEL_FROM_DATABASE=GoMic compact condenser microphone
 
+usb:v17A0p0303*
+ ID_MODEL_FROM_DATABASE=C01U Pro condenser microphone
+
 usb:v17A0p0304*
  ID_MODEL_FROM_DATABASE=Q2U handheld mic with XLR
 
@@ -44360,6 +45893,9 @@ usb:v17E9p037C*
 usb:v17E9p037D*
  ID_MODEL_FROM_DATABASE=Plugable USB2-HDMI-165
 
+usb:v17E9p410A*
+ ID_MODEL_FROM_DATABASE=HDMI Adapter
+
 usb:v17E9p430A*
  ID_MODEL_FROM_DATABASE=HP Port Replicator (Composite Device)
 
@@ -44372,6 +45908,9 @@ usb:v17EB*
 usb:v17EF*
  ID_VENDOR_FROM_DATABASE=Lenovo
 
+usb:v17EFp1000*
+ ID_MODEL_FROM_DATABASE=Hub
+
 usb:v17EFp1003*
  ID_MODEL_FROM_DATABASE=Integrated Smart Card Reader
 
@@ -44384,6 +45923,9 @@ usb:v17EFp1008*
 usb:v17EFp100A*
  ID_MODEL_FROM_DATABASE=ThinkPad Mini Dock Plus Series 3
 
+usb:v17EFp304B*
+ ID_MODEL_FROM_DATABASE=AX88179 Gigabit Ethernet [ThinkPad OneLink GigaLAN]
+
 usb:v17EFp3815*
  ID_MODEL_FROM_DATABASE=ChipsBnk 2GB USB Stick
 
@@ -44444,6 +45986,12 @@ usb:v17EFp6009*
 usb:v17EFp6014*
  ID_MODEL_FROM_DATABASE=Mini Wireless Keyboard N5901
 
+usb:v17EFp6025*
+ ID_MODEL_FROM_DATABASE=ThinkPad Travel Mouse
+
+usb:v17EFp7203*
+ ID_MODEL_FROM_DATABASE=Ethernet adapter [U2L 100P-Y1]
+
 usb:v17EFp7423*
  ID_MODEL_FROM_DATABASE=IdeaPad A1 Tablet
 
@@ -46464,7 +48012,7 @@ usb:v1C7B*
  ID_VENDOR_FROM_DATABASE=LUXSHARE PRECISION INDUSTRY (SHENZHEN) CO., LTD.
 
 usb:v1C83*
- ID_VENDOR_FROM_DATABASE=Schomäcker GmbH
+ ID_VENDOR_FROM_DATABASE=Schomaecker GmbH
 
 usb:v1C83p0001*
  ID_MODEL_FROM_DATABASE=RS150 V2
@@ -47573,6 +49121,12 @@ usb:v2047*
 usb:v2047p0200*
  ID_MODEL_FROM_DATABASE=MSP430 USB HID Bootstrap Loader
 
+usb:v2047p0855*
+ ID_MODEL_FROM_DATABASE=Invensense Embedded MotionApp HID Sensor
+
+usb:v2047p0964*
+ ID_MODEL_FROM_DATABASE=Inventio Software MSP430
+
 usb:v2080*
  ID_VENDOR_FROM_DATABASE=Barnes & Noble
 
@@ -47762,6 +49316,12 @@ usb:v2237*
 usb:v2237p4161*
  ID_MODEL_FROM_DATABASE=eReader White
 
+usb:v228D*
+ ID_VENDOR_FROM_DATABASE=8D Technologies inc.
+
+usb:v228Dp0001*
+ ID_MODEL_FROM_DATABASE=Terminal Bike Key Reader
+
 usb:v22A6*
  ID_VENDOR_FROM_DATABASE=Pie Digital, Inc.
 
@@ -48245,12 +49805,39 @@ usb:v2478*
 usb:v2478p2008*
  ID_MODEL_FROM_DATABASE=U209-000-R Serial Port
 
+usb:v249C*
+ ID_VENDOR_FROM_DATABASE=M2Tech s.r.l.
+
 usb:v2632*
  ID_VENDOR_FROM_DATABASE=TwinMOS
 
 usb:v2632p3209*
  ID_MODEL_FROM_DATABASE=7-in-1 Card Reader
 
+usb:v2639*
+ ID_VENDOR_FROM_DATABASE=Xsens
+
+usb:v2639p0001*
+ ID_MODEL_FROM_DATABASE=MTi-10 IMU
+
+usb:v2639p0002*
+ ID_MODEL_FROM_DATABASE=MTi-20 VRU
+
+usb:v2639p0003*
+ ID_MODEL_FROM_DATABASE=MTi-30 AHRS
+
+usb:v2639p0011*
+ ID_MODEL_FROM_DATABASE=MTi-100 IMU
+
+usb:v2639p0012*
+ ID_MODEL_FROM_DATABASE=MTi-200 VRU
+
+usb:v2639p0013*
+ ID_MODEL_FROM_DATABASE=MTi-300 AHRS
+
+usb:v2639p0017*
+ ID_MODEL_FROM_DATABASE=MTi-G-700 GPS INS
+
 usb:v2650*
  ID_VENDOR_FROM_DATABASE=Electronics For Imaging, Inc. [hex]
 
@@ -48299,6 +49886,12 @@ usb:v2659p1212*
 usb:v2659p1213*
  ID_MODEL_FROM_DATABASE=MediaTV Pro III MiniPCIe (US)
 
+usb:v2676*
+ ID_VENDOR_FROM_DATABASE=Basler AG
+
+usb:v2676pBA02*
+ ID_MODEL_FROM_DATABASE=ace
+
 usb:v2730*
  ID_VENDOR_FROM_DATABASE=Citizen
 
index edfa842..ef0ebc5 100644 (file)
 #    driver, <vendor> is the firmware-provided string exported
 #    by the kernel DMI modalias.
 #
-#  Scan codes are specified as:
-#    KEYBOARD_KEY_<hex scan code>=<key code identifier>
-#  The scan code should be expressed in hex lowercase and in
-#  full bytes, a multiple of 2 digits. The key codes are retrieved
-#  and normalized from the kernel input API header.
+# Scan codes are specified as:
+#   KEYBOARD_KEY_<hex scan code>=<key code identifier>
+# The scan code should be expressed in hex lowercase. The key codes
+# are retrieved and normalized from the kernel input API header.
 #
-#  A '!' as the first charcter of the key identifier string
-#  will add the scan code to the AT keyboard's list of scan codes
-#  where the driver will synthesize a release event and not expect
-#  it to be generated by the hardware.
+# An '!' as the first character of the key identifier string
+# will add the scan code to the AT keyboard's list of scan codes
+# where the driver will synthesize a release event and not expect
+# it to be generated by the hardware.
 #
 # To debug key presses and access scan code mapping data of
 # an input device use the commonly available tool: evtest(1).
+#
+# To update this file, create a new file
+#   /etc/udev/hwdb.d/70-keyboad.hwdb
+# and add your rules there. To load the new rules execute (as root):
+#   udevadm hwdb --update
+#   udevadm trigger /dev/input/eventXX
+# where /dev/input/eventXX is the keyboard in question. If in
+# doubt, simply use /dev/input/event* to reload all input rules.
+#
+# If your changes are generally applicable, open a bug report on
+#   http://bugs.freedesktop.org/enter_bug.cgi?product=systemd
+# and include your new rules, a description of the device, and the
+# output of
+#   udevadm info /dev/input/eventXX
+# (or /dev/input/event*).
 
 ##########################################
 # Acer
@@ -138,6 +152,7 @@ keyboard:dmi:bvn*:bvr*:bd*:svnASUS:pn*
  KEYBOARD_KEY_ef=mute
 
 keyboard:name:Asus WMI hotkeys:dmi:bvn*:bvr*:bd*:svnASUS*:pn*:pvr*
+keyboard:name:Eee PC WMI hotkeys:dmi:bvn*:bvr*:bd*:svnASUS*:pn*:pvr*
  KEYBOARD_KEY_6b=f21                                    # Touchpad Toggle
 
 ###########################################################
@@ -228,6 +243,10 @@ keyboard:dmi:bvn*:bvr*:bd*:svnDell*:pnPrecision*:pvr*
 keyboard:dmi:bvn*:bvr*:bd*:svnDell*:pnXPS*:pvr*
  KEYBOARD_KEY_8c=!unknown
 
+# Dell Latitude microphone mute
+keyboard:name:Dell WMI hotkeys:dmi:bvn*:bvr*:bd*:svnDell*:pnLatitude*
+ KEYBOARD_KEY_150=f20                                   # Mic mute toggle, should be micmute
+
 ###########################################################
 # Everex
 ###########################################################
@@ -363,7 +382,7 @@ keyboard:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHP*Pavilion*dv7*Notebook*PC:pvr
  KEYBOARD_KEY_b7=print
  KEYBOARD_KEY_c2=media                                  # FIXME: quick play
  KEYBOARD_KEY_c6=break
- KEYBOARD_KEY_94=0
+ KEYBOARD_KEY_94=reserved
 
 # Elitebook
 keyboard:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*Compaq*:pvr*
@@ -500,7 +519,7 @@ keyboard:name:ThinkPad Extra Buttons:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*
  KEYBOARD_KEY_15=volumedown
  KEYBOARD_KEY_16=mute
  KEYBOARD_KEY_17=prog1
- KEYBOARD_KEY_1a=f20
+ KEYBOARD_KEY_1a=f20                                    # Microphone mute button; should be micmute
 
 # ThinkPad Keyboard with TrackPoint
 keyboard:usb:v17EFp6009*
@@ -568,7 +587,7 @@ keyboard:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*IdeaPad*Y550*:pvr*
 
 keyboard:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*IdeaPad*U300s*:pvr*
  KEYBOARD_KEY_f1=f21
- KEYBOARD_KEY_ce=f20
+ KEYBOARD_KEY_ce=f20                                    # micmute
 
 keyboard:dmi:bvn*:bvr*:svnLENOVO*:pn*IdeaPad*Z370*:pvr*
  KEYBOARD_KEY_a0=!mute
@@ -579,6 +598,18 @@ keyboard:dmi:bvn*:bvr*:svnLENOVO*:pn*IdeaPad*Z370*:pvr*
 keyboard:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*Lenovo*V480*:pvr*
  KEYBOARD_KEY_f1=f21
 
+# enhanced USB keyboard
+keyboard:usb:v04B3p301B*
+ KEYBOARD_KEY_90001=prog1 # ThinkVantage
+ KEYBOARD_KEY_90002=screenlock
+ KEYBOARD_KEY_90003=file
+ KEYBOARD_KEY_90004=wordprocessor
+ KEYBOARD_KEY_90005=spreadsheet
+ KEYBOARD_KEY_90006=calc
+ KEYBOARD_KEY_90007=mail
+ KEYBOARD_KEY_90008=www
+
+
 ###########################################################
 # Logitech
 ###########################################################
@@ -792,7 +823,7 @@ keyboard:dmi:bvn*:bvr*:bd*:svnOLPC:pnXO:*
  KEYBOARD_KEY_f3=f17
  KEYBOARD_KEY_f2=f18
  KEYBOARD_KEY_f1=f19
- KEYBOARD_KEY_f0=f20
+ KEYBOARD_KEY_f0=f20                                    # micmute
  KEYBOARD_KEY_ef=f21
  KEYBOARD_KEY_ee=chat
  KEYBOARD_KEY_e4=chat
@@ -853,6 +884,14 @@ keyboard:dmi:bvn*:bvr*:bd*:svnOQO*Inc.*:pnOQO*Model*2*:pvr*
  KEYBOARD_KEY_f3=volumeup
 
 ###########################################################
+# Plantronics
+###########################################################
+
+# Plantronics .Audio 626 DSP
+keyboard:usb:v047FpC006*
+ KEYBOARD_KEY_b002f=f20                                # Microphone mute button; should be micmute
+
+###########################################################
 # Quanta
 ###########################################################
 
@@ -897,9 +936,10 @@ keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*550P*:pvr*
  KEYBOARD_KEY_a8=!                                      # Fn Lock - Function lock on
  KEYBOARD_KEY_a9=!                                      # Fn Lock - Function lock off
 
+# Series 7 / 9
 keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*700Z*:pvr*
 keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*700G*:pvr*
-keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*900X[34][CDG]*:pvr*
+keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*900X[34][CDEFG]*:pvr*
 keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*940X3G*:pvr*
  KEYBOARD_KEY_ce=!prog1                                 # Fn+F1 launch settings
  KEYBOARD_KEY_a0=!mute                                  # Fn+F6 mute
@@ -909,7 +949,6 @@ keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*940X3G*:pvr*
  KEYBOARD_KEY_96=!kbdillumup                            # Fn+F10 keyboard backlight up
  KEYBOARD_KEY_b3=!prog3                                 # Fn+F11 fan/cooling mode changer
 
-# Series 9
 keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*900X[34][AB]*:pvr*
  KEYBOARD_KEY_ce=!                                      # Fn+F8 keyboard backlight up
  KEYBOARD_KEY_8d=!                                      # Fn+F7 keyboard backlight down
@@ -924,6 +963,14 @@ keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*90X3A*:pvr*
  KEYBOARD_KEY_96=!kbdillumup                            # Fn+F8 keyboard backlight up
  KEYBOARD_KEY_d5=!wlan                                  # Fn+F12 Wi-Fi toggle
 
+# Series 7 Ultra
+keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*7[34]0U3E*:pvr*
+ KEYBOARD_KEY_ce=!prog1                                 # Fn+F1 launch settings
+ KEYBOARD_KEY_97=!kbdillumdown                          # Fn+F9 keyboard backlight down
+ KEYBOARD_KEY_96=!kbdillumup                            # Fn+F10 keyboard backlight up
+ KEYBOARD_KEY_b3=!prog3                                 # Fn+F11 fan/cooling mode changer
+ KEYBOARD_KEY_d5=!wlan                                  # Fn+F12 wlan/airplane switch
+
 # SQ1US
 keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pnSQ1US:pvr*
  KEYBOARD_KEY_d4=menu
index b72c415..86d414a 100755 (executable)
@@ -107,6 +107,7 @@ sub usb_classes {
 sub pci_vendor {
         my $vendor;
         my $device;
+        my $device_text;
 
         open(IN, "<", "pci.ids");
         open(OUT, ">", "20-pci-vendor-model.hwdb");
@@ -130,10 +131,10 @@ sub pci_vendor {
                 $line =~ m/^\t([0-9a-f]{4})\s*(.+)$/;
                 if (defined $1) {
                         $device = uc $1;
-                        my $text = $2;
+                        $device_text = $2;
                         print(OUT "\n");
                         print(OUT "pci:v0000" . $vendor . "d0000" . $device . "*\n");
-                        print(OUT " ID_MODEL_FROM_DATABASE=" . $text . "\n");
+                        print(OUT " ID_MODEL_FROM_DATABASE=" . $device_text . "\n");
                         next;
                 }
 
@@ -141,10 +142,12 @@ sub pci_vendor {
                 if (defined $1) {
                         my $sub_vendor = uc $1;
                         my $sub_device = uc $2;
-                        my $text = $3;
+                        my $sub_text = $3;
+                        $sub_text =~ s/^\Q$device_text\E\s*//;
+                        $sub_text =~ s/(.+)/\ ($1)/;
                         print(OUT "\n");
                         print(OUT "pci:v0000" . $vendor . "d0000" . $device . "sv0000" . $sub_vendor . "sd0000" . $sub_device . "*\n");
-                        print(OUT " ID_MODEL_FROM_DATABASE=" . $text . "\n");
+                        print(OUT " ID_MODEL_FROM_DATABASE=" . $device_text . $sub_text . "\n");
                 }
         }
 
diff --git a/m4/acx_libwrap.m4 b/m4/acx_libwrap.m4
deleted file mode 100644 (file)
index ccf8afc..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-AC_DEFUN([ACX_LIBWRAP], [
-LIBWRAP_LIBS=
-saved_LIBS="$LIBS"
-LIBS="$LIBS -lwrap"
-AC_MSG_CHECKING([for tcpwrap library and headers])
-AC_LINK_IFELSE(
-[AC_LANG_PROGRAM(
-[#include <tcpd.h>
-#include <syslog.h>
-int allow_severity = LOG_INFO;
-int deny_severity = LOG_WARNING;],
-[struct request_info *req;
-return hosts_access (req);])],
-[AC_DEFINE(HAVE_LIBWRAP, [], [Have tcpwrap?])
-LIBWRAP_LIBS="-lwrap"
-AC_MSG_RESULT(yes)],
-[AC_MSG_RESULT(no)])
-LIBS="$saved_LIBS"
-])
index aa53ef2..7bd5ad8 100644 (file)
@@ -42,7 +42,7 @@ AC_DEFUN([CC_CHECK_FLAG_APPEND], [
                  AS_TR_SH([cc_cv_$2_$3]),
           [eval "AS_TR_SH([cc_save_$2])='${$2}'"
            eval "AS_TR_SH([$2])='-Werror $3'"
-           AC_LINK_IFELSE([AC_LANG_SOURCE([int a = 0; int main(void) { return a; } ])],
+           AC_LINK_IFELSE([AC_LANG_SOURCE([int main(void) { return 0; } ])],
                           [eval "AS_TR_SH([cc_cv_$2_$3])='yes'"],
                           [eval "AS_TR_SH([cc_cv_$2_$3])='no'"])
            eval "AS_TR_SH([$2])='$cc_save_$2'"])
index 6f8668b..2270166 100644 (file)
                         <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>systemd-binfmt.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>systemd-delta</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>wine</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                        <citerefentry project='die-net'><refentrytitle>wine</refentrytitle><manvolnum>8</manvolnum></citerefentry>
                 </para>
         </refsect1>
 
index 5f19847..5254022 100644 (file)
@@ -64,7 +64,7 @@
                 <para>Firmware information is available only on EFI
                 systems.</para>
 
-                <para>Currently, only the <citerefentry><refentrytitle>gummiboot</refentrytitle><manvolnum>8</manvolnum></citerefentry> boot
+                <para>Currently, only the <citerefentry project='gummiboot'><refentrytitle>gummiboot</refentrytitle><manvolnum>8</manvolnum></citerefentry> boot
                 manager implements the required boot loader interface
                 to provide complete boot manager information.</para>
         </refsect1>
index 65c2cee..ac6e9f7 100644 (file)
@@ -59,7 +59,7 @@
                 Linux case, this kernel (optionally) extracts and
                 executes an initial RAM disk image (initrd), such as
                 generated by
-                <citerefentry><refentrytitle>dracut</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                <citerefentry project='die-net'><refentrytitle>dracut</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
                 which looks for the root file system (possibly using
                 <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 for this). After the root file system is found and
@@ -80,7 +80,7 @@
 
                 <para>Additional information about the system boot
                 process may be found in
-                <citerefentry><refentrytitle>boot</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
+                <citerefentry project='man-pages'><refentrytitle>boot</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
         </refsect1>
 
         <refsect1>
@@ -308,10 +308,10 @@ systemd-reboot.service   systemd-poweroff.service   systemd-halt.service   syste
                 <title>See Also</title>
                 <para>
                         <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>boot</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+                        <citerefentry project='man-pages'><refentrytitle>boot</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>systemd.special</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>systemd.target</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>dracut</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                        <citerefentry project='die-net'><refentrytitle>dracut</refentrytitle><manvolnum>8</manvolnum></citerefentry>
                 </para>
         </refsect1>
 
diff --git a/man/coredump.conf.xml b/man/coredump.conf.xml
new file mode 100644 (file)
index 0000000..0c9160e
--- /dev/null
@@ -0,0 +1,145 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2014 Zbigniew Jędrzejewski-Szmek
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="coredump.conf" conditional="ENABLE_COREDUMP">
+  <refentryinfo>
+    <title>coredump.conf</title>
+    <productname>systemd</productname>
+
+    <authorgroup>
+      <author>
+        <contrib>Developer</contrib>
+        <firstname>Lennart</firstname>
+        <surname>Poettering</surname>
+        <email>lennart@poettering.net</email>
+      </author>
+    </authorgroup>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>coredump.conf</refentrytitle>
+    <manvolnum>5</manvolnum>
+  </refmeta>
+
+  <refnamediv>
+    <refname>coredump.conf</refname>
+    <refpurpose>Coredump storage configuration file</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <para><filename>/etc/systemd/coredump.conf</filename></para>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>This file configures the behaviour of <command>systemd-coredump</command>,
+    a handler for core dumps invoked by the kernel.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>Options</title>
+
+    <para>All options are configured in the
+    <literal>[Coredump]</literal> section:</para>
+
+    <variablelist>
+
+      <varlistentry>
+        <term><varname>Storage=</varname></term>
+
+        <listitem><para>Controls where to store cores. One of
+        <literal>none</literal>, <literal>external</literal>,
+        <literal>journal</literal>, and <literal>both</literal>. When
+        <literal>none</literal>, the coredumps will be logged but not
+        stored permanently. When <literal>external</literal> (the
+        default), cores will be stored in <filename>/var/lib/systemd/coredump</filename>.
+        When <literal>journal</literal>, cores will be stored in
+        the journal and rotated following normal journal
+        rotation patterns. When <literal>both</literal>, cores
+        will be stored in both locations.</para>
+
+        <para>When cores are stored in the journal, they might be
+        compressed following journal compression settings, see
+        <citerefentry><refentrytitle>journald.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+        When cores are stored externally, they will be compressed
+        by default, see below.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>Compress=</varname></term>
+
+        <listitem><para>Controls the type of compression for external
+        storage. Takes a boolean argument, defaults to
+        <literal>yes</literal>.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>ProcessSizeMax=</varname></term>
+
+        <listitem><para>The maximum size in bytes of a core
+        which will be processed. Coredumps exceeding this size
+        will be logged, but the backtrace will not be generated
+        and the core will not be stored.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>ExternalSizeMax=</varname></term>
+        <term><varname>JournalSizeMax=</varname></term>
+
+        <listitem><para>The maximum (uncompressed) size in bytes of a
+        core to be saved.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>MaxUse=</varname></term>
+        <term><varname>KeepFree=</varname></term>
+
+        <listitem><para>Enforce limits on the disk space taken up by
+        externally stored coredumps. <option>MaxUse=</option> makes
+        sure that old coredumps are removed as soon as the total disk
+        space taken up by coredumps grows beyond this limit (defaults
+        to 10% of the total disk size). <option>KeepFree=</option>
+        controls how much disk space to keep free at least (defaults
+        to 15% of the total disk size). Note that the disk space used
+        by coredumps might temporarily exceed these limits while
+        coredumps are processed. Note that old coredumps are also
+        removed based on time via
+        <citerefentry><refentrytitle>systemd-tmpfiles</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para></listitem>
+      </varlistentry>
+    </variablelist>
+
+  </refsect1>
+
+  <refsect1>
+    <title>See Also</title>
+    <para>
+      <citerefentry><refentrytitle>systemd-journald.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>coredumpctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>systemd-tmpfiles</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+    </para>
+  </refsect1>
+
+</refentry>
similarity index 79%
rename from man/systemd-coredumpctl.xml
rename to man/coredumpctl.xml
index 092ec56..a7b8793 100644 (file)
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 -->
 
-<refentry id="systemd-coredumpctl" conditional='ENABLE_COREDUMP'
+<refentry id="coredumpctl" conditional='ENABLE_COREDUMP'
           xmlns:xi="http://www.w3.org/2001/XInclude">
 
         <refentryinfo>
-                <title>systemd-coredumpctl</title>
+                <title>coredumpctl</title>
                 <productname>systemd</productname>
 
                 <authorgroup>
         </refentryinfo>
 
         <refmeta>
-                <refentrytitle>systemd-coredumpctl</refentrytitle>
+                <refentrytitle>coredumpctl</refentrytitle>
                 <manvolnum>1</manvolnum>
         </refmeta>
 
         <refnamediv>
-                <refname>systemd-coredumpctl</refname>
+                <refname>coredumpctl</refname>
                 <refpurpose>Retrieve coredumps from the journal</refpurpose>
         </refnamediv>
 
         <refsynopsisdiv>
                 <cmdsynopsis>
-                        <command>systemd-coredumpctl</command>
+                        <command>coredumpctl</command>
                         <arg choice="opt" rep="repeat">OPTIONS</arg>
                         <arg choice="req">COMMAND</arg>
                         <arg choice="opt" rep="repeat">PID|COMM|EXE|MATCH</arg>
@@ -60,7 +60,7 @@
         <refsect1>
                 <title>Description</title>
 
-                <para><command>systemd-coredumpctl</command> may be used to
+                <para><command>coredumpctl</command> may be used to
                 retrieve coredumps from
                 <citerefentry><refentrytitle>systemd-journald</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
         </refsect1>
 
                 <variablelist>
                         <varlistentry>
+                                <term><option>--no-legend</option></term>
+
+                                <listitem><para>Do not print the column headers.
+                                </para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>-1</option></term>
+
+                                <listitem><para>Show information of a
+                                single coredump only, instead of
+                                listing all known coredumps.
+                                </para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
                                 <term><option>-F</option></term>
                                 <term><option>--field=</option></term>
 
                                 <option>FILE</option>.</para></listitem>
                         </varlistentry>
 
-                        <varlistentry>
-                                <term><option>--no-legend</option></term>
-
-                                <listitem><para>Do not print the column headers.
-                                </para></listitem>
-                        </varlistentry>
-
                         <xi:include href="standard-options.xml" xpointer="help" />
                         <xi:include href="standard-options.xml" xpointer="version" />
                         <xi:include href="standard-options.xml" xpointer="no-pager" />
+
                 </variablelist>
 
                 <para>The following commands are understood:</para>
                         <varlistentry>
                                 <term><command>list</command></term>
 
-                                <listitem><para>List coredumps captured in the journal
-                                matching specified characteristics.</para></listitem>
+                                <listitem><para>List coredumps
+                                captured in the journal matching
+                                specified characteristics. If no
+                                command is specified, this is the
+                                implied default.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>info</command></term>
+
+                                <listitem><para>Show detailed
+                                information about coredumps captured
+                                in the journal.</para></listitem>
                         </varlistentry>
 
                         <varlistentry>
                                 </para></listitem>
                         </varlistentry>
 
-
                         <varlistentry>
                                 <term><command>gdb</command></term>
 
         <refsect1>
                 <title>Matching</title>
 
-                <para>Match can be:</para>
+                <para>A match can be:</para>
 
                 <variablelist>
                         <varlistentry>
 
                                 <listitem><para>General journalctl predicates
                                 (see <citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>).
-                                Must contain an equals sign.
+                                Must contain an equal sign.
                                 </para></listitem>
                         </varlistentry>
                 </variablelist>
         <refsect1>
                 <title>See Also</title>
                 <para>
+                        <citerefentry><refentrytitle>systemd-coredump</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>coredump.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>systemd-journald.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>gdb</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                        <citerefentry project='man-pages'><refentrytitle>gdb</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 </para>
         </refsect1>
 
index 668e51d..42caf34 100644 (file)
                 comma-delimited list of options.  The following
                 options are recognized:</para>
 
-                <variablelist class='crypttab-options'>
+                <variablelist class='fstab-options'>
 
                         <varlistentry>
-                                <term><varname>discard</varname></term>
+                                <term><option>discard</option></term>
 
                                 <listitem><para>Allow discard requests to be
                                 passed through the encrypted block device. This
                         </varlistentry>
 
                         <varlistentry>
-                                <term><varname>cipher=</varname></term>
+                                <term><option>cipher=</option></term>
 
                                 <listitem><para>Specifies the cipher to use. See
                                 <citerefentry><refentrytitle>cryptsetup</refentrytitle><manvolnum>8</manvolnum></citerefentry>
                         </varlistentry>
 
                         <varlistentry>
-                                <term><varname>hash=</varname></term>
+                                <term><option>hash=</option></term>
 
                                 <listitem><para>Specifies the hash to use for
                                 password hashing. See
                         </varlistentry>
 
                         <varlistentry>
-                                <term><varname>keyfile-offset=</varname></term>
+                                <term><option>keyfile-offset=</option></term>
 
                                 <listitem><para>Specifies the number of bytes to
                                 skip at the start of the key file. See
                         </varlistentry>
 
                         <varlistentry>
-                                <term><varname>keyfile-size=</varname></term>
+                                <term><option>keyfile-size=</option></term>
 
                                 <listitem><para>Specifies the maximum number
                                 of bytes to read from the key file. See
                         </varlistentry>
 
                         <varlistentry>
-                                <term><varname>key-slot=</varname></term>
+                                <term><option>key-slot=</option></term>
 
                                 <listitem><para>Specifies the key slot to
                                 compare the passphrase or key against.
                                 If the key slot does not match the given
                                 passphrase or key, but another would, the
                                 setup of the device will fail regardless.
-                                This option implies <varname>luks</varname>. See
+                                This option implies <option>luks</option>. See
                                 <citerefentry><refentrytitle>cryptsetup</refentrytitle><manvolnum>8</manvolnum></citerefentry>
                                 for possible values. The default is to try
                                 all key slots in sequential order.</para></listitem>
                         </varlistentry>
 
                         <varlistentry>
-                                <term><varname>luks</varname></term>
+                                <term><option>luks</option></term>
 
                                 <listitem><para>Force LUKS mode. When this mode
                                 is used, the following options are ignored since
                                 they are provided by the LUKS header on the
-                                device: <varname>cipher=</varname>,
-                                <varname>hash=</varname>,
-                                <varname>size=</varname>.</para></listitem>
+                                device: <option>cipher=</option>,
+                                <option>hash=</option>,
+                                <option>size=</option>.</para></listitem>
                         </varlistentry>
 
                         <varlistentry>
-                                <term><varname>noauto</varname></term>
+                                <term><option>noauto</option></term>
 
                                 <listitem><para>This device will not be
                                 automatically unlocked on boot.</para></listitem>
                         </varlistentry>
 
                         <varlistentry>
-                                <term><varname>nofail</varname></term>
+                                <term><option>nofail</option></term>
 
                                 <listitem><para>The system will not wait for the
                                 device to show up and be unlocked at boot, and
                         </varlistentry>
 
                         <varlistentry>
-                                <term><varname>plain</varname></term>
+                                <term><option>plain</option></term>
 
                                 <listitem><para>Force plain encryption mode.</para></listitem>
                         </varlistentry>
 
                         <varlistentry>
-                                <term><varname>read-only</varname></term><term><varname>readonly</varname></term>
+                                <term><option>read-only</option></term><term><option>readonly</option></term>
 
                                 <listitem><para>Set up the encrypted block
                                 device in read-only mode.</para></listitem>
                         </varlistentry>
 
                         <varlistentry>
-                                <term><varname>size=</varname></term>
+                                <term><option>size=</option></term>
 
                                 <listitem><para>Specifies the key size
                                 in bits. See
                         </varlistentry>
 
                         <varlistentry>
-                                <term><varname>swap</varname></term>
+                                <term><option>swap</option></term>
 
                                 <listitem><para>The encrypted block device will
                                 be used as a swap device, and will be formatted
                                 accordingly after setting up the encrypted
                                 block device, with
-                                <citerefentry><refentrytitle>mkswap</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
-                                This option implies <varname>plain</varname>.</para>
+                                <citerefentry project='man-pages'><refentrytitle>mkswap</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
+                                This option implies <option>plain</option>.</para>
 
-                                <para>WARNING: Using the <varname>swap</varname>
+                                <para>WARNING: Using the <option>swap</option>
                                 option will destroy the contents of the named
                                 partition during every boot, so make sure the
                                 underlying block device is specified correctly.</para></listitem>
                         </varlistentry>
 
                         <varlistentry>
-                                <term><varname>tcrypt</varname></term>
+                                <term><option>tcrypt</option></term>
 
                                 <listitem><para>Use TrueCrypt encryption mode.
                                 When this mode is used, the following options are
                                 ignored since they are provided by the TrueCrypt
                                 header on the device or do not apply:
-                                <varname>cipher=</varname>,
-                                <varname>hash=</varname>,
-                                <varname>keyfile-offset=</varname>,
-                                <varname>keyfile-size=</varname>,
-                                <varname>size=</varname>.</para>
+                                <option>cipher=</option>,
+                                <option>hash=</option>,
+                                <option>keyfile-offset=</option>,
+                                <option>keyfile-size=</option>,
+                                <option>size=</option>.</para>
 
                                 <para>When this mode is used, the passphrase is
                                 read from the key file given in the third field.
                                 passphrase and key files to derive a password
                                 for the volume. Therefore, the passphrase and
                                 all key files need to be provided. Use
-                                <varname>tcrypt-keyfile=</varname> to provide
+                                <option>tcrypt-keyfile=</option> to provide
                                 the absolute path to all key files. When using
                                 an empty passphrase in combination with one or
                                 more key files, use <literal>/dev/null</literal>
                         </varlistentry>
 
                         <varlistentry>
-                                <term><varname>tcrypt-hidden</varname></term>
+                                <term><option>tcrypt-hidden</option></term>
 
                                 <listitem><para>Use the hidden TrueCrypt volume.
-                                This option implies <varname>tcrypt</varname>.</para>
+                                This option implies <option>tcrypt</option>.</para>
 
                                 <para>This will map the hidden volume that is
                                 inside of the volume provided in the second
                         </varlistentry>
 
                         <varlistentry>
-                                <term><varname>tcrypt-keyfile=</varname></term>
+                                <term><option>tcrypt-keyfile=</option></term>
 
                                 <listitem><para>Specifies the absolute path to a
                                 key file to use for a TrueCrypt volume. This
-                                implies <varname>tcrypt</varname> and can be
+                                implies <option>tcrypt</option> and can be
                                 used more than once to provide several key
                                 files.</para>
 
-                                <para>See the entry for <varname>tcrypt</varname>
+                                <para>See the entry for <option>tcrypt</option>
                                 on the behavior of the passphrase and key files
                                 when using TrueCrypt encryption mode.</para></listitem>
                         </varlistentry>
 
                         <varlistentry>
-                                <term><varname>tcrypt-system</varname></term>
+                                <term><option>tcrypt-system</option></term>
 
                                 <listitem><para>Use TrueCrypt in system
                                 encryption mode. This option implies
-                                <varname>tcrypt</varname>.</para></listitem>
+                                <option>tcrypt</option>.</para></listitem>
                         </varlistentry>
 
                         <varlistentry>
-                                <term><varname>timeout=</varname></term>
+                                <term><option>timeout=</option></term>
 
                                 <listitem><para>Specifies the timeout for
                                 querying for a password. If no unit is
                         </varlistentry>
 
                         <varlistentry>
-                                <term><varname>tmp</varname></term>
+                                <term><option>x-systemd.device-timeout=</option></term>
+
+                                <listitem><para>Specifies how long
+                                systemd should wait for a device to
+                                show up before giving up on the
+                                entry. The argument is a time in
+                                seconds or explicitly specifified
+                                units of <literal>s</literal>,
+                                <literal>min</literal>,
+                                <literal>h</literal>,
+                                <literal>ms</literal>.
+                                </para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>tmp</option></term>
 
                                 <listitem><para>The encrypted block device will
                                 be prepared for using it as <filename>/tmp</filename>;
                                 it will be formatted using
-                                <citerefentry><refentrytitle>mke2fs</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
-                                This option implies <varname>plain</varname>.</para>
+                                <citerefentry project='man-pages'><refentrytitle>mke2fs</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
+                                This option implies <option>plain</option>.</para>
 
-                                <para>WARNING: Using the <varname>tmp</varname>
+                                <para>WARNING: Using the <option>tmp</option>
                                 option will destroy the contents of the named
                                 partition during every boot, so make sure the
                                 underlying block device is specified correctly.</para></listitem>
                         </varlistentry>
 
                         <varlistentry>
-                                <term><varname>tries=</varname></term>
+                                <term><option>tries=</option></term>
 
                                 <listitem><para>Specifies the maximum number of
                                 times the user is queried for a password.
                         </varlistentry>
 
                         <varlistentry>
-                                <term><varname>verify</varname></term>
+                                <term><option>verify</option></term>
 
                                 <listitem><para> If the encryption password is
                                 read from console, it has to be entered twice to
                         <programlisting>luks       UUID=2505567a-9e27-4efe-a4d5-15ad146c258b
 swap       /dev/sda7       /dev/urandom             swap
 truecrypt  /dev/sda2       /etc/container_password  tcrypt
-hidden     /mnt/tc_hidden  /null                    tcrypt-hidden,tcrypt-keyfile=/etc/keyfile</programlisting>
+hidden     /mnt/tc_hidden  /dev/null                tcrypt-hidden,tcrypt-keyfile=/etc/keyfile</programlisting>
                 </example>
         </refsect1>
 
@@ -380,8 +395,8 @@ hidden     /mnt/tc_hidden  /null                    tcrypt-hidden,tcrypt-keyfile
                         <citerefentry><refentrytitle>systemd-cryptsetup@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>systemd-cryptsetup-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>cryptsetup</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>mkswap</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>mke2fs</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                        <citerefentry project='man-pages'><refentrytitle>mkswap</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry project='man-pages'><refentrytitle>mke2fs</refentrytitle><manvolnum>8</manvolnum></citerefentry>
                 </para>
         </refsect1>
 
index 060af2e..8bcc5f9 100644 (file)
@@ -24,7 +24,7 @@
 <xsl:import href="http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl"/>
 
 <!-- translate man page references to links to html pages -->
-<xsl:template match="citerefentry">
+<xsl:template match="citerefentry[not(@project)]">
   <a>
     <xsl:attribute name="href">
       <xsl:value-of select="refentrytitle"/><xsl:text>.html</xsl:text>
   </a>
 </xsl:template>
 
+<xsl:template match="citerefentry[@project='man-pages'] | citerefentry[manvolnum='2'] | citerefentry[manvolnum='4']">
+  <a>
+    <xsl:attribute name="href">
+      <xsl:text>http://man7.org/linux/man-pages/man</xsl:text>
+      <xsl:value-of select="manvolnum"/>
+      <xsl:text>/</xsl:text>
+      <xsl:value-of select="refentrytitle"/>
+      <xsl:text>.</xsl:text>
+      <xsl:value-of select="manvolnum"/>
+      <xsl:text>.html</xsl:text>
+    </xsl:attribute>
+    <xsl:call-template name="inline.charseq"/>
+  </a>
+</xsl:template>
+
+<xsl:template match="citerefentry[@project='die-net']">
+  <a>
+    <xsl:attribute name="href">
+      <xsl:text>http://linux.die.net/man/</xsl:text>
+      <xsl:value-of select="manvolnum"/>
+      <xsl:text>/</xsl:text>
+      <xsl:value-of select="refentrytitle"/>
+    </xsl:attribute>
+    <xsl:call-template name="inline.charseq"/>
+  </a>
+</xsl:template>
+
+<xsl:template match="citerefentry[@project='archlinux']">
+  <a>
+    <xsl:attribute name="href">
+      <xsl:text>https://www.archlinux.org/</xsl:text>
+      <xsl:value-of select="refentrytitle"/>
+      <xsl:text>/</xsl:text>
+      <xsl:value-of select="refentrytitle"/>
+      <xsl:text>.</xsl:text>
+      <xsl:value-of select="manvolnum"/>
+      <xsl:text>.html</xsl:text>
+    </xsl:attribute>
+    <xsl:call-template name="inline.charseq"/>
+  </a>
+</xsl:template>
+
+<xsl:template match="citerefentry[@project='gummiboot']">
+  <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
 <xsl:template match="refsect1/title|refsect1/info/title">
   <!-- the ID is output in the block.object call for refsect1 -->
   <h2>
index 88dd082..a23a047 100644 (file)
@@ -74,8 +74,8 @@
 
                         <orderedlist>
                                 <listitem><para>Close all open file
-                                descriptors except stdin, stdout,
-                                stderr (i.e. the first three file
+                                descriptors except standard input, output,
+                                and error (i.e. the first three file
                                 descriptors 0, 1, 2). This ensures
                                 that no accidentally passed file
                                 descriptor stays around in the daemon
                                 write the daemon PID (as returned by
                                 <function>getpid()</function>) to a
                                 PID file, for example
-                                <filename>/var/run/foobar.pid</filename>
+                                <filename>/run/foobar.pid</filename>
                                 (for a hypothetical daemon "foobar")
                                 to ensure that the daemon cannot be
                                 started more than once. This must be
                                 it is verified at the same time that
                                 the PID previously stored in the PID
                                 file no longer exists or belongs to a
-                                foreign process. Commonly, some kind of
-                                file locking is employed to implement
-                                this logic.</para></listitem>
+                                foreign process.</para></listitem>
 
                                 <listitem><para>In the daemon process,
                                 drop privileges, if possible and
                                 detect service errors and problems. It
                                 is recommended to follow the exit code
                                 scheme as defined in the <ulink
-                                url="http://refspecs.freestandards.org/LSB_3.1.1/LSB-Core-generic/LSB-Core-generic/iniscrptact.html">LSB
+                                url="http://refspecs.linuxbase.org/LSB_3.1.1/LSB-Core-generic/LSB-Core-generic/iniscrptact.html">LSB
                                 recommendations for SysV init
                                 scripts</ulink>.</para></listitem>
 
                                 interface.</para></listitem>
 
                                 <listitem><para>Instead of using the
-                                <function>syslog()</function> call to log directly to the
-                                system syslog service, a new-style daemon may
-                                choose to simply log to standard error via
-                                <function>fprintf()</function>, which is then forwarded to
-                                syslog by the init system. If log
-                                priorities are necessary, these can be
-                                encoded by prefixing individual log
-                                lines with strings like "&lt;4&gt;"
-                                (for log priority 4 "WARNING" in the
-                                syslog priority scheme), following a
-                                similar style as the Linux kernel's
-                                <function>printk()</function> priority system. In fact,
-                                using this style of logging also
-                                enables the init system to optionally
-                                direct all application logging to the
-                                kernel log buffer (kmsg), as
-                                accessible via
-                                <citerefentry><refentrytitle>dmesg</refentrytitle><manvolnum>1</manvolnum></citerefentry>. This
-                                kind of logging may be enabled by
-                                setting
-                                <varname>StandardError=syslog</varname>
-                                in the service unit file. For details,
-                                see
+                                <function>syslog()</function> call to
+                                log directly to the system syslog
+                                service, a new-style daemon may choose
+                                to simply log to standard error via
+                                <function>fprintf()</function>, which
+                                is then forwarded to syslog by the
+                                init system. If log priorities are
+                                necessary, these can be encoded by
+                                prefixing individual log lines with
+                                strings like "&lt;4&gt;" (for log
+                                priority 4 "WARNING" in the syslog
+                                priority scheme), following a similar
+                                style as the Linux kernel's
+                                <function>printk()</function> priority
+                                system. For details, see
                                 <citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                                 and
                                 <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para></listitem>
 
                         <para>These recommendations are similar but
                         not identical to the <ulink
-                        url="http://developer.apple.com/mac/library/documentation/MacOSX/Conceptual/BPSystemStartup/Articles/LaunchOnDemandDaemons.html#//apple_ref/doc/uid/TP40001762-104738">Apple
+                        url="https://developer.apple.com/library/mac/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html">Apple
                         MacOS X Daemon Requirements</ulink>.</para>
                 </refsect2>
 
                         exclusively on boot (and manually by the
                         administrator) via SysV init scripts, as
                         detailed in the <ulink
-                        url="http://refspecs.freestandards.org/LSB_3.1.1/LSB-Core-generic/LSB-Core-generic/iniscrptact.html">LSB
+                        url="http://refspecs.linuxbase.org/LSB_3.1.1/LSB-Core-generic/LSB-Core-generic/iniscrptact.html">LSB
                         Linux Standard Base Core
                         Specification</ulink>. This method of
                         activation is supported ubiquitously on Linux
                         boot.</para>
 
                         <para>Packages using
-                        <citerefentry><refentrytitle>autoconf</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                        <citerefentry project='die-net'><refentrytitle>autoconf</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                         are recommended to use a configure script
                         excerpt like the following to determine the
                         unit installation path during source
@@ -793,7 +783,7 @@ AM_CONDITIONAL([HAVE_SYSTEMD], [test "x$with_systemdsystemunitdir" != "xno"])</p
                         work, it is recommended to add the following
                         to the top-level <filename>Makefile.am</filename>
                         file in
-                        <citerefentry><refentrytitle>automake</refentrytitle><manvolnum>1</manvolnum></citerefentry>-based
+                        <citerefentry project='die-net'><refentrytitle>automake</refentrytitle><manvolnum>1</manvolnum></citerefentry>-based
                         projects:</para>
 
                         <programlisting>DISTCHECK_CONFIGURE_FLAGS = \
@@ -808,7 +798,7 @@ systemdsystemunit_DATA = \
 endif</programlisting>
 
                         <para>In the
-                        <citerefentry><refentrytitle>rpm</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                        <citerefentry project='die-net'><refentrytitle>rpm</refentrytitle><manvolnum>8</manvolnum></citerefentry>
                         <filename>.spec</filename> file, use snippets
                         like the following to enable/disable the
                         service during
@@ -943,6 +933,14 @@ fi</programlisting>
         </refsect1>
 
         <refsect1>
+                <title>Placing Daemon Data</title>
+
+                <para>It is recommended to follow the general
+                guidelines for placing package files, as discussed in
+                <citerefentry><refentrytitle>file-hierarchy</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
+        </refsect1>
+
+        <refsect1>
                 <title>See Also</title>
                 <para>
                         <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
@@ -950,7 +948,8 @@ fi</programlisting>
                         <citerefentry><refentrytitle>sd_listen_fds</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>daemon</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                        <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>file-hierarchy</refentrytitle><manvolnum>7</manvolnum></citerefentry>
                 </para>
         </refsect1>
 
diff --git a/man/file-hierarchy.xml b/man/file-hierarchy.xml
new file mode 100644 (file)
index 0000000..523846b
--- /dev/null
@@ -0,0 +1,978 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="file-hierarchy">
+
+        <refentryinfo>
+                <title>file-hierarchy</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>file-hierarchy</refentrytitle>
+                <manvolnum>7</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>file-hierarchy</refname>
+                <refpurpose>File system hierarchy overview</refpurpose>
+        </refnamediv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para>Operating systems using the
+                <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                system and service manager are organized based on a
+                file system hierarchy inspired by UNIX, more
+                specifically the hierarchy described in the <ulink
+                url="http://refspecs.linuxfoundation.org/FHS_2.3/fhs-2.3.html">File
+                System Hierarchy</ulink> specification and
+                <citerefentry project='man-pages'><refentrytitle>hier</refentrytitle><manvolnum>7</manvolnum></citerefentry>. This
+                manual page describes a more minimal, modernized
+                subset of these specifications that defines more
+                strictly the suggestions and restrictions systemd
+                makes on the file system hierarchy.</para>
+
+                <para>Many of the paths described here are queriable
+                with the
+                <citerefentry><refentrytitle>systemd-path</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                tool.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>General Structure</title>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><filename>/</filename></term>
+                                <listitem><para>The file system
+                                root. Usually writable, but this is
+                                not required. Possibly a temporary
+                                file system (<literal>tmpfs</literal>). Not shared with
+                                other hosts (unless read-only).
+                                </para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><filename>/boot</filename></term>
+                                <listitem><para>The boot partition
+                                used for bringing up the system. On
+                                EFI systems this is possibly the EFI
+                                System Partition, also see
+                                <citerefentry><refentrytitle>systemd-efi-boot-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>. This
+                                directory is usually strictly local
+                                to the host, and should be considered
+                                read-only, except when a new kernel or
+                                boot loader is installed. This
+                                directory only exists on systems that
+                                run on physical or emulated hardware
+                                that requires boot
+                                loaders.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><filename>/etc</filename></term>
+                                <listitem><para>System-specific
+                                configuration. This directory may or
+                                may not be read-only. Frequently, this
+                                directory is pre-populated with
+                                vendor-supplied configuration files,
+                                but applications should not make
+                                assumptions about this directory
+                                being fully populated or populated at
+                                all, and should fall back to defaults
+                                if configuration is missing.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><filename>/home</filename></term>
+                                <listitem><para>The location for
+                                normal user's home
+                                directories. Possibly shared with
+                                other systems, and never
+                                read-only. This directory should only
+                                be used for normal users, never for
+                                system users. This directory and
+                                possibly the directories contained
+                                within it might only become available
+                                or writable in late boot or even only
+                                after user authentication. This directory
+                                might be placed on limited-functionality
+                                network file systems, hence
+                                applications should not assume the
+                                full set of file API is available on
+                                this directory. Applications should
+                                generally not reference this directory
+                                directly, but via the per-user
+                                <varname>$HOME</varname> environment
+                                variable, or via the home directory
+                                field of the user
+                                database.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><filename>/root</filename></term>
+                                <listitem><para>The home directory of
+                                the root user. The root user's home
+                                directory is located outside of
+                                <filename>/home</filename> in order to
+                                make sure the root user may log in
+                                even without <filename>/home</filename>
+                                being available and
+                                mounted.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><filename>/srv</filename></term>
+                                <listitem><para>The place to store
+                                general server payload, managed by the
+                                administrator. No restrictions are
+                                made how this directory is organized
+                                internally. Generally writable, and
+                                possibly shared among systems. This
+                                directory might become available or
+                                writable only very late during
+                                boot.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><filename>/tmp</filename></term>
+                                <listitem><para>The place for small
+                                temporary files. This directory is
+                                usually mounted as
+                                a <literal>tmpfs</literal> instance, and
+                                should hence not be used for larger
+                                files. (Use
+                                <filename>/var/tmp</filename> for
+                                larger files.) Since the directory is
+                                accessible to other users of the
+                                system it is essential that this
+                                directory is only written to with the
+                                <citerefentry project='man-pages'><refentrytitle>mkstemp</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                                <citerefentry project='man-pages'><refentrytitle>mkdtemp</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                                and related calls. This directory is
+                                usually flushed at boot-up. Also,
+                                files that are not accessed within a
+                                certain time are usually automatically
+                                deleted. If applications find the
+                                environment variable
+                                <varname>$TMPDIR</varname> set they
+                                should prefer using the directory
+                                specified in it over directly
+                                referencing
+                                <filename>/tmp</filename> (see <citerefentry project='man-pages'><refentrytitle>environ</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                                and
+                                <ulink url="http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03">IEEE Std 1003.1</ulink> for details).</para></listitem>
+                        </varlistentry>
+
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>Runtime Data</title>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><filename>/run</filename></term>
+                                <listitem><para>A
+                                <literal>tmpfs</literal> file system
+                                for system packages to place runtime
+                                data in. This directory is flushed on
+                                boot, and generally writable for
+                                privileged programs
+                                only. Always writable.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><filename>/run/log</filename></term>
+                                <listitem><para>Runtime system
+                                logs. System components may place
+                                private logs in this directory. Always
+                                writable, even when
+                                <filename>/var/log</filename> might
+                                not be accessible
+                                yet.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><filename>/run/user</filename></term>
+                                <listitem><para>Contains per-user
+                                runtime directories, each usually
+                                individually mounted
+                                <literal>tmpfs</literal>
+                                instances. Always writable, flushed at
+                                each reboot and when the user logs
+                                out. User code should not reference
+                                this directory directly, but via the
+                                <varname>$XDG_RUNTIME_DIR</varname>
+                                environment variable, as documented in
+                                the <ulink
+                                url="http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html">XDG
+                                Base Directory
+                                Specification</ulink>.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>Vendor-supplied Operating System Resources</title>
+
+                <variablelist>
+
+                        <varlistentry>
+                                <term><filename>/usr</filename></term>
+                                <listitem><para>Vendor-supplied
+                                operating system resources. Usually
+                                read-only, but this is not
+                                required. Possibly shared between
+                                multiple hosts. This directory should
+                                not be modified by the administrator,
+                                except when installing or removing
+                                vendor-supplied
+                                packages.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><filename>/usr/bin</filename></term>
+                                <listitem><para>Binaries and
+                                executables for user commands, that
+                                shall appear in the
+                                <varname>$PATH</varname> search
+                                path. It is recommended not to place
+                                binaries in this directory that are
+                                not useful for invocation from a shell
+                                (such as daemon binaries); these
+                                should be placed in a subdirectory of
+                                <filename>/usr/lib</filename>
+                                instead.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><filename>/usr/include</filename></term>
+                                <listitem><para>C and C++ API header
+                                files of system
+                                libraries.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><filename>/usr/lib</filename></term>
+                                <listitem><para>Static, private vendor
+                                data that is compatible with all
+                                architectures (though not necessarily
+                                architecture-independent). Note that
+                                this includes internal executables or
+                                other binaries that are not regularly
+                                invoked from a shell. Such binaries
+                                may be for any architecture supported
+                                by the system. Do not place public
+                                libraries in this directory, use
+                                <varname>$libdir</varname> (see
+                                below), instead.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><filename>/usr/lib/<replaceable>arch-id</replaceable></filename></term>
+                                <listitem><para>Location for placing
+                                dynamic libraries, also called <varname>$libdir</varname>.
+                                The architecture identifier to use is defined on <ulink
+                                url="https://wiki.debian.org/Multiarch/Tuples">Multiarch Architecture Specifiers (Tuples)</ulink>
+                                list. Legacy locations of <varname>$libdir</varname> are
+                                <filename>/usr/lib</filename>,
+                                <filename>/usr/lib64</filename>.
+                                This directory should not
+                                be used for package-specific data,
+                                unless this data is
+                                architecture-dependent, too. To query
+                                <varname>$libdir</varname> for the
+                                primary architecture of the system,
+                                invoke:
+                                <programlisting># pkg-config --variable=libdir systemd</programlisting> or
+                                <programlisting># systemd-path system-library-arch</programlisting>
+                                </para></listitem>
+
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><filename>/usr/share</filename></term>
+                                <listitem><para>Resources shared
+                                between multiple packages, such as
+                                documentation, man pages, time zone
+                                information, fonts and other
+                                resources. Usually, the precise
+                                location and format of files stored
+                                below this directory is subject to
+                                specifications that ensure
+                                interoperability.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><filename>/usr/share/doc</filename></term>
+                                <listitem><para>Documentation for the
+                                operating system or system
+                                packages.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><filename>/usr/share/factory/etc</filename></term>
+                                <listitem><para>Repository for
+                                vendor-supplied default configuration
+                                files. This directory should be
+                                populated with pristine vendor versions
+                                of all configuration files that may be
+                                placed in
+                                <filename>/etc</filename>. This is
+                                useful to compare the local
+                                configuration of a system with vendor
+                                defaults and to populate the local
+                                configuration with
+                                defaults.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><filename>/usr/share/factory/var</filename></term>
+
+                                <listitem><para>Similar to
+                                <filename>/usr/share/factory/etc</filename>
+                                but for vendor versions of files in
+                                the variable, persistent data
+                                directory
+                                <filename>/var</filename>.</para></listitem>
+
+                        </varlistentry>
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>Persistent Variable System Data</title>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><filename>/var</filename></term>
+                                <listitem><para>Persistent, variable
+                                system data. Must be writable. This
+                                directory might be pre-populated with
+                                vendor-supplied data, but applications
+                                should be able to reconstruct
+                                necessary files and directories in
+                                this subhierarchy should they be
+                                missing, as the system might start up
+                                without this directory being
+                                populated. Persistency is recommended,
+                                but optional, to support ephemeral
+                                systems. This directory might become
+                                available or writable only very late
+                                during boot. Components that are
+                                required to operate during early boot
+                                hence shall not unconditionally rely
+                                on this directory.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><filename>/var/cache</filename></term>
+                                <listitem><para>Persistent system
+                                cache data. System components may
+                                place non-essential data in this
+                                directory. Flushing this directory
+                                should have no effect on operation of
+                                programs, except for increased
+                                runtimes necessary to rebuild these
+                                caches.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><filename>/var/lib</filename></term>
+                                <listitem><para>Persistent system
+                                data. System components may
+                                place private data in this
+                                directory.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><filename>/var/log</filename></term>
+                                <listitem><para>Persistent system
+                                logs. System components may place
+                                private logs in this directory, though
+                                it is recommended to do most logging
+                                via the
+                                <citerefentry project='man-pages'><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                                and
+                                <citerefentry><refentrytitle>sd_journal_print</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                                calls.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><filename>/var/spool</filename></term>
+                                <listitem><para>Persistent system
+                                spool data, such as printer or mail
+                                queues.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><filename>/var/tmp</filename></term>
+                                <listitem><para>The place for larger
+                                and persistent temporary files. In
+                                contrast to <filename>/tmp</filename>
+                                this directory is usually mounted from
+                                a persistent physical file system and
+                                can thus accept larger files. (Use
+                                <filename>/tmp</filename> for smaller
+                                files.) This directory is generally
+                                not flushed at boot-up, but time-based
+                                cleanup of files that have not been
+                                accessed for a certain time is
+                                applied. The same security
+                                restrictions as with
+                                <filename>/tmp</filename> apply, and
+                                hence only
+                                <citerefentry project='man-pages'><refentrytitle>mkstemp</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                                <citerefentry project='man-pages'><refentrytitle>mkdtemp</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                                or similar calls should be used to
+                                make use of this directory. If
+                                applications find the environment
+                                variable <varname>$TMPDIR</varname>
+                                set they should prefer using the
+                                directory specified in it over
+                                directly referencing
+                                <filename>/var/tmp</filename> (see <citerefentry project='man-pages'><refentrytitle>environ</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                                for details).
+                                </para></listitem>
+                        </varlistentry>
+
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>Virtual Kernel and API File Systems</title>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><filename>/dev</filename></term>
+                                <listitem><para>The root directory for
+                                device nodes. Usually this directory
+                                is mounted as a
+                                <literal>devtmpfs</literal> instance,
+                                but might be of a different type in
+                                sandboxed/containerized setups. This
+                                directory is managed jointly by the
+                                kernel and
+                                <citerefentry><refentrytitle>systemd-udevd</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                                and should not be written to by other
+                                components. A number of special
+                                purpose virtual file systems might be
+                                mounted below this
+                                directory.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><filename>/dev/shm</filename></term>
+                                <listitem><para>Place for POSIX shared
+                                memory segments, as created via
+                                <citerefentry><refentrytitle>shm_open</refentrytitle><manvolnum>3</manvolnum></citerefentry>. This
+                                directory is flushed on boot, and is a
+                                <literal>tmpfs</literal> file
+                                system. Since all users have write
+                                access to this directory, special care
+                                should be taken to avoid name clashes
+                                and vulnerabilities. For normal users,
+                                shared memory segments in this
+                                directory are usually deleted when the
+                                user logs out. Usually it is a better
+                                idea to use memory mapped files in
+                                <filename>/run</filename> (for system
+                                programs) or
+                                <varname>$XDG_RUNTIME_DIR</varname>
+                                (for user programs) instead of POSIX
+                                shared memory segments, since those
+                                directories are not world-writable and
+                                hence not vulnerable to
+                                security-sensitive name
+                                clashes.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><filename>/proc</filename></term>
+                                <listitem><para>A virtual kernel file
+                                system exposing the process list and
+                                other functionality. This file system
+                                is mostly an API to interface with the
+                                kernel and not a place where normal
+                                files may be stored. For details, see
+                                <citerefentry project='man-pages'><refentrytitle>proc</refentrytitle><manvolnum>5</manvolnum></citerefentry>. A
+                                number of special purpose virtual file
+                                systems might be mounted below this
+                                directory.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><filename>/proc/sys</filename></term>
+                                <listitem><para>A hierarchy below
+                                <filename>/proc</filename> that
+                                exposes a number of kernel
+                                tunables. The primary way to configure
+                                the settings in this API file tree is
+                                via
+                                <citerefentry><refentrytitle>sysctl.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                                files. In sandboxed/containerized
+                                setups this directory is generally
+                                mounted read-only.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><filename>/sys</filename></term>
+                                <listitem><para>A virtual kernel file
+                                system exposing discovered devices and
+                                other functionality. This file system
+                                is mostly an API to interface with the
+                                kernel and not a place where normal
+                                files may be stored. In
+                                sandboxed/containerized setups this
+                                directory is generally mounted
+                                read-only. A number of special purpose
+                                virtual file systems might be mounted
+                                below this
+                                directory.</para></listitem>
+                        </varlistentry>
+
+
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>Compatibility Symlinks</title>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><filename>/bin</filename></term>
+                                <term><filename>/sbin</filename></term>
+                                <term><filename>/usr/sbin</filename></term>
+
+                                <listitem><para>These compatibility
+                                symlinks point to
+                                <filename>/usr/bin</filename>,
+                                ensuring that scripts and binaries
+                                referencing these legacy paths
+                                correctly find their binaries.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><filename>/lib</filename></term>
+
+                                <listitem><para>This compatibility
+                                symlink points to
+                                <filename>/usr/lib</filename>,
+                                ensuring that programs referencing
+                                this legacy path correctly find
+                                their resources.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><filename>/lib64</filename></term>
+
+                                <listitem><para>On some architecture
+                                ABIs this compatibility symlink points
+                                to <varname>$libdir</varname>,
+                                ensuring that binaries referencing
+                                this legacy path correctly find their
+                                dynamic loader. This symlink only
+                                exists on architectures whose ABI
+                                places the dynamic loader in this
+                                path.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><filename>/var/run</filename></term>
+
+                                <listitem><para>This compatibility
+                                symlink points to
+                                <filename>/run</filename>, ensuring
+                                that programs referencing this legacy
+                                path correctly find their runtime
+                                data.</para></listitem>
+                        </varlistentry>
+
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>Home Directory</title>
+
+                <para>User applications may want to place files and
+                directories in the user's home directory. They should
+                follow the following basic structure. Note that some
+                of these directories are also standardized (though
+                more weakly) by the <ulink
+                url="http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html">XDG
+                Base Directory Specification</ulink>. Additional
+                locations for high-level user resources are defined by
+                <ulink
+                url="http://www.freedesktop.org/wiki/Software/xdg-user-dirs/">xdg-user-dirs</ulink>.</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><filename>~/.cache</filename></term>
+
+                                <listitem><para>Persistent user cache
+                                data. User programs may place
+                                non-essential data in this
+                                directory. Flushing this directory
+                                should have no effect on operation of
+                                programs, except for increased
+                                runtimes necessary to rebuild these
+                                caches. If an application finds
+                                <varname>$XDG_CACHE_HOME</varname> set
+                                is should use the directory specified
+                                in it instead of this
+                                directory.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><filename>~/.config</filename></term>
+
+                                <listitem><para>Application
+                                configuration and state. When a new
+                                user is created this directory will be
+                                empty or not exist at
+                                all. Applications should fall back to
+                                defaults should their configuration or
+                                state in this directory be missing. If
+                                an application finds
+                                <varname>$XDG_CONFIG_HOME</varname> set
+                                is should use the directory specified
+                                in it instead of this
+                                directory.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><filename>~/.local/bin</filename></term>
+
+                                <listitem><para>Executables that shall
+                                appear in the user's
+                                <varname>$PATH</varname> search
+                                path. It is recommended not to place
+                                executables in this directory that are
+                                not useful for invocation from a
+                                shell; these should be placed in a
+                                subdirectory of
+                                <filename>~/.local/lib</filename>
+                                instead. Care should be taken when
+                                placing architecture-dependent
+                                binaries in this place which might be
+                                problematic if the home directory is
+                                shared between multiple hosts with
+                                different
+                                architectures.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><filename>~/.local/lib</filename></term>
+
+                                <listitem><para>Static, private vendor
+                                data that is compatible with all
+                                architectures.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><filename>~/.local/lib/<replaceable>arch-id</replaceable></filename></term>
+
+                                <listitem><para>Location for placing
+                                public dynamic libraries. The architecture
+                                identifier to use, is defined on <ulink
+                                url="https://wiki.debian.org/Multiarch/Tuples">Multiarch Architecture Specifiers (Tuples)</ulink>
+                                list.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><filename>~/.local/share</filename></term>
+
+                                <listitem><para>Resources shared
+                                between multiple packages, such as
+                                fonts or artwork. Usually, the precise
+                                location and format of files stored
+                                below this directory is subject to
+                                specifications that ensure
+                                interoperability. If
+                                an application finds
+                                <varname>$XDG_DATA_HOME</varname> set
+                                is should use the directory specified
+                                in it instead of this
+                                directory.</para></listitem>
+                        </varlistentry>
+
+                </variablelist>
+        </refsect1>
+
+
+        <refsect1>
+                <title>Unprivileged Write Access</title>
+
+                <para>Unprivileged processes generally lack
+                write access to most of the hierarchy.</para>
+
+                <para>The exceptions for normal users are
+                <filename>/tmp</filename>,
+                <filename>/var/tmp</filename>,
+                <filename>/dev/shm</filename>, as well as the home
+                directory <varname>$HOME</varname> (usually found
+                below <filename>/home</filename>) and the runtime
+                directory <varname>$XDG_RUNTIME_DIR</varname> (found
+                below <filename>/run/user</filename>) of the
+                user, which are all writable.</para>
+
+                <para>For unprivileged system processes only
+                <filename>/tmp</filename>,
+                <filename>/var/tmp</filename> and
+                <filename>/dev/shm</filename> are writable. If an
+                unprivileged system process needs a private, writable
+                directory in <filename>/var</filename> or
+                <filename>/run</filename>, it is recommended to either
+                create it before dropping privileges in the daemon
+                code, to create it via
+                <citerefentry><refentrytitle>tmpfiles.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                fragments during boot, or via the
+                <varname>RuntimeDirectory=</varname> directive of
+                service units (see
+                <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                for details).</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Node Types</title>
+
+                <para>Unix file systems support different types of file
+                nodes, including regular files, directories, symlinks,
+                character and block device nodes, sockets and FIFOs.</para>
+
+                <para>It is strongly recommended that
+                <filename>/dev</filename> is the only location below
+                which device nodes shall be placed. Similar,
+                <filename>/run</filename> shall be the only location
+                to place sockets and FIFOs. Regular files,
+                directories and symlinks may be used in all
+                directories.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>System Packages</title>
+
+                <para>Developers of system packages should follow
+                strict rules when placing their own files in the file
+                system. The following table lists recommended
+                locations for specific types of files supplied by the
+                vendor.</para>
+
+                <table>
+                  <title>System Package Vendor Files Locations</title>
+                  <tgroup cols='2' align='left' colsep='1' rowsep='1'>
+                    <colspec colname="directory" />
+                    <colspec colname="purpose" />
+                    <thead>
+                      <row>
+                        <entry>Directory</entry>
+                        <entry>Purpose</entry>
+                      </row>
+                    </thead>
+                    <tbody>
+                      <row>
+                        <entry><filename>/usr/bin</filename></entry>
+                        <entry>Package executables that shall appear in the <varname>$PATH</varname> executable search path, compiled for any of the supported architectures compatible with the operating system. It is not recommended to place internal binaries or binaries that are not commonly invoked from the shell in this directory, such as daemon binaries. As this directory is shared with most other packages of the system special care should be taken to pick unique names for files placed here, that are unlikely to clash with other package's files.</entry>
+                      </row>
+                      <row>
+                        <entry><filename>/usr/lib/<replaceable>arch-id</replaceable></filename></entry>
+                        <entry>Public shared libraries of the package. As above, be careful with using too generic names, and pick unique names for your libraries to place here to avoid name clashes.</entry>
+                      </row>
+                      <row>
+                        <entry><filename>/usr/lib/<replaceable>package</replaceable></filename></entry>
+                        <entry>Private, static vendor resources of the package, including private binaries and libraries, or any other kind of read-only vendor data.</entry>
+                      </row>
+                      <row>
+                        <entry><filename>/usr/lib/<replaceable>arch-id</replaceable>/<replaceable>package</replaceable></filename></entry>
+                        <entry>Private other vendor resources of the package that are architecture-specific and cannot be shared between architectures. Note that this generally does not include private executables since binaries of a specific architecture may be freely invoked from any other supported system architecture.</entry>
+                      </row>
+                      <row>
+                        <entry><filename>/usr/include/<replaceable>package</replaceable></filename></entry>
+                        <entry>Public C/C++ APIs of public shared libraries of the package.</entry>
+                      </row>
+                    </tbody>
+                  </tgroup>
+                </table>
+
+                <para>Additional static vendor files may be installed
+                in the <filename>/usr/share</filename> hierarchy, to
+                the locations defined by the various relevant
+                specifications.</para>
+
+                <para>During runtime and for local configuration and
+                state additional directories are defined:</para>
+
+                <table>
+                  <title>System Package Variable Files Locations</title>
+                  <tgroup cols='2' align='left' colsep='1' rowsep='1'>
+                    <colspec colname="directory" />
+                    <colspec colname="purpose" />
+                    <thead>
+                      <row>
+                        <entry>Directory</entry>
+                        <entry>Purpose</entry>
+                      </row>
+                    </thead>
+                    <tbody>
+                      <row>
+                        <entry><filename>/etc/<replaceable>package</replaceable></filename></entry>
+                        <entry>System-specific configuration for the package. It is recommended to default to safe fallbacks if this configuration is missing, if this is possible. Alternatively, a <citerefentry><refentrytitle>tmpfiles.d</refentrytitle><manvolnum>5</manvolnum></citerefentry> fragment may be used to copy or symlink the necessary files and directories from <filename>/usr/share/factory</filename> during boot, via the <literal>L</literal> or <literal>C</literal> directives.</entry>
+                      </row>
+                      <row>
+                        <entry><filename>/run/<replaceable>package</replaceable></filename></entry>
+                        <entry>Runtime data for the package. Packages must be able to create the necessary subdirectories in this tree on their own, since the directory is flushed automatically on boot. Alternatively, a <citerefentry><refentrytitle>tmpfiles.d</refentrytitle><manvolnum>5</manvolnum></citerefentry> fragment may be used to create the necessary directories during boot. Alternatively, the <varname>RuntimeDirectory=</varname> directive of service units may be used (see <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry> for details.)</entry>
+                      </row>
+                      <row>
+                        <entry><filename>/run/log/<replaceable>package</replaceable></filename></entry>
+                        <entry>Runtime log data for the package. As above, the package needs to make sure to create this directory if necessary, as it will be flushed on every boot.</entry>
+                      </row>
+                      <row>
+                        <entry><filename>/var/cache/<replaceable>package</replaceable></filename></entry>
+                        <entry>Persistent cache data of the package. If this directory is flushed the application should work correctly on next invocation, though possibly slowed down due to the need to rebuild any local cache files. The application must be capable of recreating this directory should it be missing and necessary.</entry>
+                      </row>
+                      <row>
+                        <entry><filename>/var/lib/<replaceable>package</replaceable></filename></entry>
+                        <entry>Persistent private data of the package. This is the primary place to put persistent data that does not fall into the other categories listed. Packages should be able to create the necessary subdirectories in this tree on their own, since the directory might be missing on boot. Alternatively, a <citerefentry><refentrytitle>tmpfiles.d</refentrytitle><manvolnum>5</manvolnum></citerefentry> fragment may be used to create the necessary directories during boot.</entry>
+                      </row>
+                      <row>
+                        <entry><filename>/var/log/<replaceable>package</replaceable></filename></entry>
+                        <entry>Persistent log data of the package. As above, the package should make sure to create this directory if necessary, as it might be missing.</entry>
+                      </row>
+                      <row>
+                        <entry><filename>/var/spool/<replaceable>package</replaceable></filename></entry>
+                        <entry>Persistent spool/queue data of the package. As above, the package should make sure to create this directory if necessary, as it might be missing.</entry>
+                      </row>
+                    </tbody>
+                  </tgroup>
+                </table>
+        </refsect1>
+
+        <refsect1>
+                <title>User Packages</title>
+
+                <para>Programs running in user context should follow
+                strict rules when placing their own files in the
+                user's home directory. The following table lists
+                recommended locations in the home directory for
+                specific types of files supplied by the vendor if the
+                application is installed in the home directory. (Note
+                however, that user applications installed system-wide
+                should follow the rules outlined above regarding
+                placing vendor files.)</para>
+
+                <table>
+                  <title>User Package Vendor File Locations</title>
+                  <tgroup cols='2' align='left' colsep='1' rowsep='1'>
+                    <colspec colname="directory" />
+                    <colspec colname="purpose" />
+                    <thead>
+                      <row>
+                        <entry>Directory</entry>
+                        <entry>Purpose</entry>
+                      </row>
+                    </thead>
+                    <tbody>
+                      <row>
+                        <entry><filename>~/.local/bin</filename></entry>
+                        <entry>Package executables that shall appear in the <varname>$PATH</varname> executable search path. It is not recommended to place internal executables or executables that are not commonly invoked from the shell in this directory, such as daemon executables. As this directory is shared with most other packages of the user special care should be taken to pick unique names for files placed here, that are unlikely to clash with other package's files.</entry>
+                      </row>
+                      <row>
+                        <entry><filename>~/.local/lib/<replaceable>arch-id</replaceable></filename></entry>
+                        <entry>Public shared libraries of the package. As above, be careful with using too generic names, and pick unique names for your libraries to place here to avoid name clashes.</entry>
+                      </row>
+                      <row>
+                        <entry><filename>~/.local/lib/<replaceable>package</replaceable></filename></entry>
+                        <entry>Private, static vendor resources of the package, compatible wih any architecture, or any other kind of read-only vendor data.</entry>
+                      </row>
+                      <row>
+                        <entry><filename>~/.local/lib/<replaceable>arch-id</replaceable>/<replaceable>package</replaceable></filename></entry>
+                        <entry>Private other vendor resources of the package that are architecture-specific and cannot be shared between architectures.</entry>
+                      </row>
+                    </tbody>
+                  </tgroup>
+                </table>
+
+                <para>Additional static vendor files may be installed
+                in the <filename>~/.local/share</filename> hierarchy,
+                to the locations defined by the various relevant
+                specifications.</para>
+
+                <para>During runtime and for local configuration and
+                state additional directories are defined:</para>
+
+                <table>
+                  <title>User Package Variable File Locations</title>
+                  <tgroup cols='2' align='left' colsep='1' rowsep='1'>
+                    <colspec colname="directory" />
+                    <colspec colname="purpose" />
+                    <thead>
+                      <row>
+                        <entry>Directory</entry>
+                        <entry>Purpose</entry>
+                      </row>
+                    </thead>
+                    <tbody>
+                      <row>
+                        <entry><filename>~/.config/<replaceable>package</replaceable></filename></entry>
+                        <entry>User-specific configuration and state for the package. It is required to default to safe fallbacks if this configuration is missing.</entry>
+                      </row>
+                      <row>
+                        <entry><filename><varname>$XDG_RUNTIME_DIR</varname>/<replaceable>package</replaceable></filename></entry>
+                        <entry>User runtime data for the package.</entry>
+                      </row>
+                      <row>
+                        <entry><filename>~/.cache/<replaceable>package</replaceable></filename></entry>
+                        <entry>Persistent cache data of the package. If this directory is flushed the application should work correctly on next invocation, though possibly slowed down due to the need to rebuild any local cache files. The application must be capable of recreating this directory should it be missing and necessary.</entry>
+                      </row>
+                    </tbody>
+                  </tgroup>
+                </table>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry project='man-pages'><refentrytitle>hier</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-path</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-efi-boot-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sysctl.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>tmpfiles.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
index d3b686e..e9ed655 100644 (file)
                         <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>shutdown</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>wall</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                        <citerefentry project='man-pages'><refentrytitle>wall</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 </para>
         </refsect1>
 
index a8648c5..2f949de 100644 (file)
 
                 <para>You may use
                 <citerefentry><refentrytitle>hostnamectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
-                to change the value of this file from the command
-                line.</para>
+                to change the value of this file during runtime from
+                the command line. Use
+                <citerefentry><refentrytitle>systemd-firstboot</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                to initialize it on mounted (but not booted) system
+                images.</para>
         </refsect1>
 
         <refsect1>
@@ -95,7 +98,8 @@
                           <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
                           <citerefentry><refentrytitle>machine-info</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
                           <citerefentry><refentrytitle>hostnamectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
-                          <citerefentry><refentrytitle>systemd-hostnamed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                          <citerefentry><refentrytitle>systemd-hostnamed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd-firstboot</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                   </para>
         </refsect1>
 
index 6746a70..128d92f 100644 (file)
                 (e.g. "Lennart's Laptop"), the static hostname which
                 is used to initialize the kernel hostname at boot
                 (e.g. "lennarts-laptop"), and the transient hostname
-                which might be assigned temporarily due to network
-                configuration and might revert back to the static
-                hostname if network connectivity is lost and is only
-                temporarily written to the kernel hostname
-                (e.g. "dhcp-47-11").</para>
+                which is a default received from network configuration.
+                If a static hostname is set, and is valid (something other
+                than localhost), then the transient hostname is not used.</para>
 
                 <para>Note that the pretty hostname has little
                 restrictions on the characters used, while the static
                 for more information. The pretty hostname, chassis
                 type, and icon name are stored in
                 <filename>/etc/machine-info</filename>, see
-                <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
+                <citerefentry><refentrytitle>machine-info</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
+
+                <para>Use
+                <citerefentry><refentrytitle>systemd-firstboot</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                to initialize the system host name for mounted (but
+                not booted) system images.</para>
         </refsect1>
 
         <refsect1>
                         </varlistentry>
 
                         <varlistentry>
-                                <term><option>-P</option></term>
-                                <term><option>--privileged</option></term>
-
-                                <listitem><para>Acquire privileges via PolicyKit
-                                before executing the operation.</para></listitem>
-                        </varlistentry>
-
-                        <varlistentry>
                                 <term><option>--static</option></term>
                                 <term><option>--transient</option></term>
                                 <term><option>--pretty</option></term>
                         </varlistentry>
 
                         <varlistentry>
-                                <term><command>set-hostname [NAME]</command></term>
+                                <term><command>set-hostname <replaceable>NAME</replaceable></command></term>
 
                                 <listitem><para>Set the system
-                                hostname. By default, this will alter
-                                the pretty, the static, and the
-                                transient hostname alike; however, if
-                                one or more of
+                                hostname to
+                                <replaceable>NAME</replaceable>. By
+                                default, this will alter the pretty,
+                                the static, and the transient hostname
+                                alike; however, if one or more of
                                 <option>--static</option>,
                                 <option>--transient</option>,
                                 <option>--pretty</option> are used,
                                 the hostname string is not done if
                                 only the transient and/or static host
                                 names are set, and the pretty host
-                                name is left untouched. Pass the empty
-                                string <literal></literal> as the
-                                hostname to reset the selected
-                                hostnames to their default (usually
+                                name is left untouched.</para>
+
+                                <para>Pass the empty string
+                                <literal></literal> as the hostname to
+                                reset the selected hostnames to their
+                                default (usually
                                 <literal>localhost</literal>).</para></listitem>
                         </varlistentry>
 
                         <varlistentry>
-                                <term><command>set-icon-name [NAME]</command></term>
+                                <term><command>set-icon-name <replaceable>NAME</replaceable></command></term>
 
                                 <listitem><para>Set the system icon
-                                name. The icon name is used by some
-                                graphical applications to visualize
-                                this host. The icon name should follow
-                                the <ulink
+                                name to
+                                <replaceable>NAME</replaceable>. The
+                                icon name is used by some graphical
+                                applications to visualize this host.
+                                The icon name should follow the <ulink
                                 url="http://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html">Icon
-                                Naming Specification</ulink>. Pass an
-                                empty string to this operation to
-                                reset the icon name to the default
-                                value, which is determined from chassis
-                                type (see below) and possibly other
+                                Naming Specification</ulink>.</para>
+
+                                <para>Pass an empty string to reset
+                                the icon name to the default value,
+                                which is determined from chassis type
+                                (see below) and possibly other
                                 parameters.</para></listitem>
                         </varlistentry>
 
                         <varlistentry>
-                                <term><command>set-chassis [TYPE]</command></term>
+                                <term><command>set-chassis <replaceable>TYPE</replaceable></command></term>
 
-                                <listitem><para>Set the chassis
-                                type. The chassis type is used by some
+                                <listitem><para>Set the chassis type
+                                to <replaceable>TYPE</replaceable>.
+                                The chassis type is used by some
                                 graphical applications to visualize
-                                the host or alter user
-                                interaction. Currently, the following
-                                chassis types are defined:
+                                the host or alter user interaction.
+                                Currently, the following chassis types
+                                are defined:
                                 <literal>desktop</literal>,
                                 <literal>laptop</literal>,
                                 <literal>server</literal>,
                                 <literal>tablet</literal>,
-                                <literal>handset</literal>, as well as
+                                <literal>handset</literal>,
+                                <literal>watch</literal>, as well as
                                 the special chassis types
                                 <literal>vm</literal> and
                                 <literal>container</literal> for
                                 virtualized systems that lack an
-                                immediate physical chassis. Pass an
-                                empty string to this operation to
-                                reset the chassis type to the default
-                                value which is determined from the
-                                firmware and possibly other
-                                parameters.</para></listitem>
+                                immediate physical chassis.</para>
+
+                                <para>Pass an empty string to reset
+                                the chassis type to the default value
+                                which is determined from the firmware
+                                and possibly other parameters.</para>
+                                </listitem>
                         </varlistentry>
 
+                        <varlistentry>
+                                <term><command>set-deployment <replaceable>ENVIRONMENT</replaceable></command></term>
+
+                                <listitem><para>Set the deployment
+                                environment
+                                description. <replaceable>ENVIRONMENT</replaceable>
+                                must be a single word without any
+                                control characters. One of the
+                                following is suggested:
+                                <literal>development</literal>,
+                                <literal>integration</literal>,
+                                <literal>staging</literal>,
+                                <literal>production</literal>.
+                                </para>
+
+                                <para>Pass an empty string to reset to
+                                the default empty value.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>set-location <replaceable>LOCATION</replaceable></command></term>
+
+                                <listitem><para>Set the location
+                                string for the system, if it is
+                                known. <replaceable>LOCATION</replaceable>
+                                should be a human-friendly, free-form
+                                string describing the physical
+                                location of the system, if it is known
+                                and applicable. This may be as generic
+                                as <literal>Berlin, Germany</literal>
+                                or as specific as <literal>Left Rack,
+                                2nd Shelf</literal>.</para>
+
+                                <para>Pass an empty string to reset to
+                                the default empty value.</para>
+                                </listitem>
+                        </varlistentry>
                 </variablelist>
         </refsect1>
 
                         <citerefentry><refentrytitle>hostname</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>machine-info</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>systemd-hostnamed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                        <citerefentry><refentrytitle>systemd-hostnamed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-firstboot</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 </para>
         </refsect1>
 
index 78fc6f6..e10918a 100644 (file)
                 field, then they are automatically matched as
                 alternatives, i.e. the resulting output will show
                 entries matching any of the specified matches for the
-                same field. Finally, if the character
-                <literal>+</literal> appears as a separate word on the
-                command line, all matches before and after are combined
-                in a disjunction (i.e. logical OR).</para>
+                same field. Finally, the character
+                <literal>+</literal> may appears as a separate word
+                between other terms on the command line. This causes
+                all matches before and after to be combined in a
+                disjunction (i.e. logical OR).</para>
 
                 <para>As shortcuts for a few types of field/value
                 matches, file paths may be specified. If a file path
                 <literal>_KERNEL_DEVICE=</literal> match for the
                 device.</para>
 
+                <para>Additional constraints may be added using options
+                <option>--boot</option>, <option>--unit=</option>,
+                etc, to further limit what entries will be shown
+                (logical AND).</para>
+
                 <para>Output is interleaved from all accessible
                 journal files, whether they are rotated or currently
                 being written, and regardless of whether they belong to the
                 system itself or are accessible user journals.</para>
 
+                <para>The set of journal files which will be used
+                can be modified using the <option>--user</option>,
+                <option>--system</option>, <option>--directory</option>,
+                and <option>--file</option> options, see below.</para>
+
                 <para>All users are granted access to their private
                 per-user journals. However, by default, only root and
                 users who are members of the <literal>systemd-journal</literal>
                 <option>--no-pager</option> option and the "Environment"
                 section below.</para>
 
-                <para>When outputing to a tty, lines are colored
+                <para>When outputting to a tty, lines are colored
                 according to priority: lines of level ERROR and higher
                 are colored red; lines of level NOTICE and higher are
                 highlighted; other lines are displayed normally.
                                 with some other numeric value on the
                                 command line. Note that this option is
                                 only supported for the
-                                <citerefentry><refentrytitle>less</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                                <citerefentry project='man-pages'><refentrytitle>less</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                                 pager.</para></listitem>
                         </varlistentry>
 
 
                                 <listitem><para>Show messages for the
                                 specified systemd unit
-                                <replaceable>UNIT</replaceable>, or
-                                for any of the units matched by
+                                <replaceable>UNIT</replaceable> (such
+                                as a service unit), or for any of the
+                                units matched by
                                 <replaceable>PATTERN</replaceable>.
                                 If a pattern is specified, a list of
                                 unit names found in the journal is
                                 the form FROM..TO. The log levels are
                                 the usual syslog log levels as
                                 documented in
-                                <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                                <citerefentry project='man-pages'><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
                                 i.e. <literal>emerg</literal> (0),
                                 <literal>alert</literal> (1),
                                 <literal>crit</literal> (2),
 
                 <programlisting>journalctl -k -b -1</programlisting>
 
+                <para>Show a live log display from a system service <filename>apache.service</filename>:</para>
+
+                <programlisting>journalctl -f -u apache</programlisting>
+
         </refsect1>
 
         <refsect1>
                         <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>systemd-journald.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>coredumpctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>systemd.journal-fields</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>journald.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
                 </para>
index a814ec1..5538b96 100644 (file)
 
                                 <listitem><para>Controls whether to
                                 split up journal files per user. One
-                                of <literal>login</literal>,
-                                <literal>uid</literal> and
-                                <literal>none</literal>. If
-                                <literal>login</literal>, each logged-in
-                                user will get his own journal
-                                files, but systemd user IDs will log
-                                into the system journal. If
-                                <literal>uid</literal>, any user ID
-                                will get his own journal files
-                                regardless of whether it belongs to a
-                                system service or refers to a real
-                                logged in user. If
+                                of <literal>uid</literal>,
+                                <literal>login</literal> and
+                                <literal>none</literal>.  If
+                                <literal>uid</literal>, all users will
+                                get each their own journal files
+                                regardless of whether they possess a
+                                login session or not, however system
+                                users will log into the system
+                                journal. If <literal>login</literal>,
+                                actually logged-in users will get each
+                                their own journal files, but users
+                                without login session and system users
+                                will log into the system journal. If
                                 <literal>none</literal>, journal files
                                 are not split up by user and all
-                                messages are instead stored in the single
-                                system journal. Note that splitting
-                                up journal files by user is only
-                                available for journals stored
+                                messages are instead stored in the
+                                single system journal. Note that
+                                splitting up journal files by user is
+                                only available for journals stored
                                 persistently. If journals are stored
-                                on volatile storage (see above), only a
-                                single journal file for all user IDs
+                                on volatile storage (see above), only
+                                single journal file for all user IDs
                                 is kept. Defaults to
-                                <literal>login</literal>.</para></listitem>
+                                <literal>uid</literal>.</para></listitem>
                         </varlistentry>
 
                         <varlistentry>
                                 limiting is applied per-service, so
                                 that two services which log do not
                                 interfere with each other's
-                                limits. Defaults to 200 messages in
-                                10s. The time specification for
+                                limits. Defaults to 1000 messages in
+                                30s. The time specification for
                                 <varname>RateLimitInterval=</varname>
                                 may be specified in the following
                                 units: <literal>s</literal>,
                                 <term><varname>ForwardToSyslog=</varname></term>
                                 <term><varname>ForwardToKMsg=</varname></term>
                                 <term><varname>ForwardToConsole=</varname></term>
+                                <term><varname>ForwardToWall=</varname></term>
 
                                 <listitem><para>Control whether log
                                 messages received by the journal
                                 daemon shall be forwarded to a
                                 traditional syslog daemon, to the
-                                kernel log buffer (kmsg), or to the
-                                system console. These options take
-                                boolean arguments. If forwarding to
-                                syslog is enabled but no syslog daemon
-                                is running, the respective option has
-                                no effect. By default, only forwarding
-                                to syslog is enabled. These settings
-                                may be overridden at boot time with
-                                the kernel command line options
+                                kernel log buffer (kmsg), to the
+                                system console, or sent as wall
+                                messages to all logged-in users. These
+                                options take boolean arguments. If
+                                forwarding to syslog is enabled but no
+                                syslog daemon is running, the
+                                respective option has no effect. By
+                                default, only forwarding wall is
+                                enabled. These settings may be
+                                overridden at boot time with the
+                                kernel command line options
                                 <literal>systemd.journald.forward_to_syslog=</literal>,
-                                <literal>systemd.journald.forward_to_kmsg=</literal>
+                                <literal>systemd.journald.forward_to_kmsg=</literal>,
+                                <literal>systemd.journald.forward_to_console=</literal>
                                 and
-                                <literal>systemd.journald.forward_to_console=</literal>.
+                                <literal>systemd.journald.forward_to_wall=</literal>.
                                 When forwarding to the console, the
-                                TTY to log to can be changed
-                                with <varname>TTYPath=</varname>,
-                                described below.</para></listitem>
+                                TTY to log to can be changed with
+                                <varname>TTYPath=</varname>, described
+                                below.</para></listitem>
                         </varlistentry>
 
                         <varlistentry>
                                 <term><varname>MaxLevelSyslog=</varname></term>
                                 <term><varname>MaxLevelKMsg=</varname></term>
                                 <term><varname>MaxLevelConsole=</varname></term>
+                                <term><varname>MaxLevelWall=</varname></term>
 
                                 <listitem><para>Controls the maximum
                                 log level of messages that are stored
-                                on disk, forwarded to syslog, kmsg or
-                                the console (if that is enabled, see
-                                above). As argument, takes one of
+                                on disk, forwarded to syslog, kmsg,
+                                the console or wall (if that is
+                                enabled, see above). As argument,
+                                takes one of
                                 <literal>emerg</literal>,
                                 <literal>alert</literal>,
                                 <literal>crit</literal>,
                                 written to disk and forwarded to
                                 syslog. Defaults to
                                 <literal>notice</literal> for
-                                <varname>MaxLevelKMsg=</varname> and
+                                <varname>MaxLevelKMsg=</varname>,
                                 <literal>info</literal> for
-                                <varname>MaxLevelConsole=</varname>.</para></listitem>
+                                <varname>MaxLevelConsole=</varname> and
+                                <literal>emerg</literal> for
+                                <varname>MaxLevelWall=</varname>.</para></listitem>
                         </varlistentry>
 
                         <varlistentry>
index afcff7c..36428aa 100644 (file)
                 kernel, please see <ulink
                 url="https://www.kernel.org/doc/Documentation/kernel-parameters.txt"><filename>kernel-parameters.txt</filename></ulink>
                 and
-                <citerefentry><refentrytitle>bootparam</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
+                <citerefentry project='man-pages'><refentrytitle>bootparam</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
 
                 <para>For command line parameters understood by the
                 initial RAM disk, please see
-                <citerefentry><refentrytitle>dracut.cmdline</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+                <citerefentry project='die-net'><refentrytitle>dracut.cmdline</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
                 or the documentation of the specific initrd
                 implementation of your installation.</para>
         </refsect1>
                         </varlistentry>
 
                         <varlistentry>
+                                <term><varname>systemd.mask=</varname></term>
+                                <term><varname>systemd.wants=</varname></term>
+                                <term><varname>systemd.debug-shell</varname></term>
+                                <listitem>
+                                        <para>Additional parameters
+                                        understood by
+                                        <citerefentry><refentrytitle>systemd-debug-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                                        to mask or start specific
+                                        units at boot, or invoke a
+                                        debug shell on tty9.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
                                 <term><varname>systemd.restore_state=</varname></term>
                                 <listitem>
                                         <para>This parameter is understood by
 
                         <varlistentry>
                                 <term><varname>fsck.mode=</varname></term>
+                                <term><varname>fsck.repair=</varname></term>
 
                                 <listitem>
-                                        <para>Parameter understood by
+                                        <para>Parameters understood by
                                         the file system checker
                                         services. For details, see
                                         <citerefentry><refentrytitle>systemd-fsck@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
                                 <term><varname>systemd.journald.forward_to_syslog=</varname></term>
                                 <term><varname>systemd.journald.forward_to_kmsg=</varname></term>
                                 <term><varname>systemd.journald.forward_to_console=</varname></term>
+                                <term><varname>systemd.journald.forward_to_wall=</varname></term>
 
                                 <listitem>
                                         <para>Parameters understood by
                                         <para>May be used to disable
                                         the Plymouth boot splash. For
                                         details, see
-                                        <citerefentry><refentrytitle>plymouth</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+                                        <citerefentry project='die-net'><refentrytitle>plymouth</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
                                 </listitem>
                         </varlistentry>
 
                         </varlistentry>
 
                         <varlistentry>
+                                <term><varname>root=</varname></term>
+                                <term><varname>rootfstype=</varname></term>
+                                <term><varname>rootfsflags=</varname></term>
+                                <term><varname>ro</varname></term>
+                                <term><varname>rw</varname></term>
+
+                                <listitem>
+                                        <para>Configures the root file
+                                        system and its file system
+                                        type and mount options, as
+                                        well as whether it shall be
+                                        mounted read-only or
+                                        read-writable initially. For
+                                        details, see
+                                        <citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>systemd.gpt_auto=</varname></term>
+                                <term><varname>rd.systemd.gpt_auto=</varname></term>
+
+                                <listitem>
+                                        <para>Configures whether GPT
+                                        based partition auto-discovery
+                                        shall be attempted. For
+                                        details, see
+                                        <citerefentry><refentrytitle>systemd-gpt-auto-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
                                 <term><varname>modules-load=</varname></term>
                                 <term><varname>rd.modules-load=</varname></term>
 
                   <title>See Also</title>
                   <para>
                           <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
-                          <citerefentry><refentrytitle>bootparam</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
-                          <citerefentry><refentrytitle>dracut.cmdline</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+                          <citerefentry project='man-pages'><refentrytitle>bootparam</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+                          <citerefentry project='die-net'><refentrytitle>dracut.cmdline</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd-debug-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
                           <citerefentry><refentrytitle>systemd-fsck@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
                           <citerefentry><refentrytitle>systemd-quotacheck.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
                           <citerefentry><refentrytitle>systemd-journald.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
                           <citerefentry><refentrytitle>systemd-vconsole-setup.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
                           <citerefentry><refentrytitle>systemd-udevd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
-                          <citerefentry><refentrytitle>plymouth</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                          <citerefentry project='die-net'><refentrytitle>plymouth</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
                           <citerefentry><refentrytitle>systemd-cryptsetup-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
                           <citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
-                          <citerefentry><refentrytitle>systemd-modules-load.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
-                          <citerefentry><refentrytitle>systemd-backlight@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                          <citerefentry><refentrytitle>systemd-gpt-auto-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd-modules-load.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd-backlight@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
                           <citerefentry><refentrytitle>systemd-rfkill@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
                   </para>
         </refsect1>
index 3612b7d..178ad1d 100644 (file)
@@ -95,14 +95,20 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
 
           <para>The kernel-install plugin <filename>50-depmod.install</filename> runs depmod for the <replaceable>KERNEL-VERSION</replaceable>.</para>
 
-          <para>The kernel-install plugin <filename>90-loaderentry.install</filename> copies
+          <para>The kernel-install plugin
+          <filename>90-loaderentry.install</filename> copies
           <replaceable>KERNEL-IMAGE</replaceable> to
           <filename>/boot/<replaceable>MACHINE-ID</replaceable>/<replaceable>KERNEL-VERSION</replaceable>/linux</filename>.
-          It also creates a boot loader entry according to the boot loader specification in
+          It also creates a boot loader entry according to the boot
+          loader specification in
           <filename>/boot/loader/entries/<replaceable>MACHINE-ID</replaceable>-<replaceable>KERNEL-VERSION</replaceable>.conf</filename>.
-          The title of the entry is the <replaceable>PRETTY_NAME</replaceable> parameter specified in <filename>/etc/os-release</filename>,
-          or "Linux <replaceable>KERNEL-VERSION</replaceable>", if unset.
-          If the file <filename>initrd</filename> is found next to the
+          The title of the entry is the
+          <replaceable>PRETTY_NAME</replaceable> parameter specified
+          in <filename>/etc/os-release</filename> or
+          <filename>/usr/lib/os-release</filename> (if the former is
+          missing), or "Linux
+          <replaceable>KERNEL-VERSION</replaceable>", if unset.  If
+          the file <filename>initrd</filename> is found next to the
           <filename>linux</filename> file, the initrd will be added to
           the configuration.</para>
         </listitem>
@@ -165,6 +171,7 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
       <varlistentry>
         <term>
           <filename>/etc/os-release</filename>
+          <filename>/usr/lib/os-release</filename>
         </term>
           <listitem>
             <para>The content of the file specifies the operating system title <replaceable>PRETTY_NAME</replaceable>.</para>
index 56a72e1..272da64 100644 (file)
@@ -7,6 +7,6 @@
 
   <para id='pkgconfig-text'>These APIs are implemented as a shared
   library, which can be compiled and linked to with the
-  <constant>libsystemd</constant> <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+  <constant>libsystemd</constant> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
   file.</para>
 </refsect1>
index e970921..67bcc18 100644 (file)
                 configuration files might be checked for locale
                 configuration as well, however only as
                 fallback.</para>
+
+                <para><citerefentry><refentrytitle>localectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                may be used to alter the settings in this file during
+                runtime from the command line. Use
+                <citerefentry><refentrytitle>systemd-firstboot</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                to initialize them on mounted (but not booted) system
+                images.</para>
         </refsect1>
 
         <refsect1>
@@ -142,7 +149,9 @@ LC_MESSAGES=en_US.UTF-8</programlisting>
                   <para>
                           <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                           <citerefentry><refentrytitle>locale</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
-                          <citerefentry><refentrytitle>systemd-localed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                          <citerefentry><refentrytitle>localectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd-localed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd-firstboot</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                   </para>
         </refsect1>
 
index c2e79a2..38e73c7 100644 (file)
                 UI before the user logs in, such as the display
                 manager, as well as the default for users after
                 login.</para>
+
+                <para>Use
+                <citerefentry><refentrytitle>systemd-firstboot</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                to initialize the system locale for mounted (but not
+                booted) system images.</para>
         </refsect1>
 
         <refsect1>
                         </varlistentry>
 
                         <varlistentry>
-                                <term><option>-P</option></term>
-                                <term><option>--privileged</option></term>
-
-                                <listitem><para>Acquire privileges via PolicyKit
-                                before executing the operation.</para></listitem>
-                        </varlistentry>
-
-                        <varlistentry>
                                 <term><option>--no-convert</option></term>
 
                                 <listitem><para>If
                           The XKB Configuration Guide
                         </ulink>,
                         <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>systemd-localed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                        <citerefentry><refentrytitle>systemd-localed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-firstboot</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 </para>
         </refsect1>
 
index dbf2379..1cbdf68 100644 (file)
@@ -71,7 +71,7 @@
                 <literal>Europe/Berlin</literal> or
                 <literal>Etc/UTC</literal>.  The resulting link should
                 lead to the corresponding binary
-                <citerefentry><refentrytitle>tzfile</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                <citerefentry project='man-pages'><refentrytitle>tzfile</refentrytitle><manvolnum>5</manvolnum></citerefentry>
                 timezone data for the configured timezone.</para>
 
                 <para>Because the timezone identifier is extracted from
 
                 <para>The timezone may be overridden for individual
                 programs by using the TZ environment variable. See
-                <citerefentry><refentrytitle>environ</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
+                <citerefentry project='man-pages'><refentrytitle>environ</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
 
                 <para>You may use
                 <citerefentry><refentrytitle>timedatectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 to change the settings of this file from the command
-                line.</para>
+                line during runtime. Use
+                <citerefentry><refentrytitle>systemd-firstboot</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                to initialize the time zone on mounted (but not
+                booted) system images.</para>
         </refsect1>
 
         <refsect1>
                   <title>See Also</title>
                   <para>
                           <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
-                          <citerefentry><refentrytitle>tzset</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                          <citerefentry project='man-pages'><refentrytitle>tzset</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
                           <citerefentry><refentrytitle>localtime</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
                           <citerefentry><refentrytitle>timedatectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
-                          <citerefentry><refentrytitle>systemd-timedated.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                          <citerefentry><refentrytitle>systemd-timedated.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd-firstboot</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                   </para>
         </refsect1>
 
index 54cc379..f037da2 100644 (file)
                                 template unit
                                 <filename>autovt@.service</filename>
                                 for the respective VT TTY name,
-                                e.g. <filename>autovt@tty4.service</filename>. By
+                                for example, <filename>autovt@tty4.service</filename>. By
                                 default,
                                 <filename>autovt@.service</filename>
                                 is linked to
-                                <filename>getty@.service</filename>,
-                                i.e. login prompts are started
+                                <filename>getty@.service</filename>.
+                                In other words, login prompts are started
                                 dynamically as the user switches to
                                 unused virtual terminals. Hence, this
                                 parameter controls how many login
                                 <literal>gettys</literal> are
                                 available on the VTs. If a VT is
                                 already used by some other subsystem
-                                (for example a graphical login), this
+                                (for example, a graphical login), this
                                 kind of activation will not be
                                 attempted. Note that the VT configured
                                 in <varname>ReserveVT=</varname> is
                                 always subject to this kind of
                                 activation, even if it is not one of
-                                VTs configured with the
+                                the VTs configured with the
                                 <varname>NAutoVTs=</varname>
                                 directive. Defaults to 6. When set to
                                 0, automatic spawning of
                                 <term><varname>ReserveVT=</varname></term>
 
                                 <listitem><para>Takes a positive
-                                integer. Configures the number of one
+                                integer. Identifies one
                                 virtual terminal that shall
                                 unconditionally be reserved for
                                 <filename>autovt@.service</filename>
                                 selected with this option will be
                                 marked busy unconditionally, so that no
                                 other subsystem will allocate it. This
-                                functionality is useful to ensure that
+                                functionality is useful to ensure that,
                                 regardless of how many VTs are allocated
                                 by other subsystems, one login
                                 <literal>getty</literal> is always
                                 <listitem><para>Takes a boolean
                                 argument. Configures whether the
                                 processes of a user should be killed
-                                when she or he completely logs out (i.e. after
-                                her/his last session ended). Defaults to
+                                when the user completely logs out (i.e. after
+                                the user's last session ended). Defaults to
                                 <literal>no</literal>.</para>
 
                                 <para>Note that setting
                                 <literal>kexec</literal>,
                                 <literal>suspend</literal>,
                                 <literal>hibernate</literal>,
-                                <literal>hybrid-sleep</literal>,
+                                <literal>hybrid-sleep</literal>, and
                                 <literal>lock</literal>. Defaults to
                                 <literal>ignore</literal>.</para>
 
                                 being active before the inhibitor is
                                 ignored and the operation executes
                                 anyway. Defaults to
-                                5s.</para></listitem>
+                                5.</para></listitem>
                         </varlistentry>
 
                         <varlistentry>
                                 <literal>kexec</literal>,
                                 <literal>suspend</literal>,
                                 <literal>hibernate</literal>,
-                                <literal>hybrid-sleep</literal> and
+                                <literal>hybrid-sleep</literal>, and
                                 <literal>lock</literal>. If
                                 <literal>ignore</literal>, logind will
                                 never handle these keys. If
                                 <literal>lock</literal>, all running
-                                sessions will be screen-locked; otherwise,
-                                the specified action
-                                will be taken in the respective
-                                event. Only input devices with the
+                                sessions will be screen-locked;
+                                otherwise, the specified action will
+                                be taken in the respective event. Only
+                                input devices with the
                                 <literal>power-switch</literal> udev
                                 tag will be watched for key/lid switch
                                 events. <varname>HandlePowerKey=</varname>
                                 default to <literal>suspend</literal>.
                                 <varname>HandleHibernateKey=</varname>
                                 defaults to
-                                <literal>hibernate</literal>.</para></listitem>
+                                <literal>hibernate</literal>. Note
+                                that the lid switch is ignored if the
+                                system is inserted in a docking
+                                station, or if more than one display
+                                is connected.</para></listitem>
                         </varlistentry>
 
                         <varlistentry>
                                 </para></listitem>
                         </varlistentry>
 
+                        <varlistentry>
+                                <term><varname>RuntimeDirectorySize=</varname></term>
+
+                                <listitem><para>Sets the size limit on
+                                the
+                                <varname>$XDG_RUNTIME_DIR</varname>
+                                runtime directory for each user who
+                                logs in. Takes a size in bytes,
+                                optionally suffixed with the usual K, G,
+                                M, and T suffixes, to the base 1024
+                                (IEC). Alternatively, a numerical
+                                percentage suffixed by <literal>%</literal>
+                                may be specified, which sets the size
+                                limit relative to the amount of
+                                physical RAM. Defaults to 10%. Note
+                                that this size is a safety limit
+                                only. As each runtime directory is a
+                                tmpfs file system, it will only consume
+                                as much memory as is needed.
+                                </para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>RemoveIPC=</varname></term>
+
+                                <listitem><para>Controls whether
+                                System V and POSIX IPC objects
+                                belonging to the user shall be removed
+                                when the user fully logs out. Takes a
+                                boolean argument. If enabled, the user
+                                may not consume IPC resources after
+                                the last of his sessions
+                                terminated. This covers System V
+                                semaphores, shared memory and message
+                                queues, as well as POSIX shared memory
+                                and message queues. Note that IPC
+                                objects of the root user are excluded
+                                from the effect of this
+                                setting. Defaults to
+                                <literal>yes</literal>.</para></listitem>
+                        </varlistentry>
+
                 </variablelist>
         </refsect1>
 
index 4b4759e..725370d 100644 (file)
                 <para>The
                 <citerefentry><refentrytitle>systemd-machine-id-setup</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 tool may be used by installer tools to initialize the
-                machine ID at install time.</para>
+                machine ID at install time. Use
+                <citerefentry><refentrytitle>systemd-firstboot</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                to initialize it on mounted (but not booted) system
+                images.</para>
         </refsect1>
 
         <refsect1>
@@ -138,7 +141,8 @@ id[8] = (id[8] &amp; 0x3F) | 0x80;</programlisting>
                           <citerefentry><refentrytitle>machine-info</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
                           <citerefentry><refentrytitle>os-release</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
                           <citerefentry><refentrytitle>sd-id128</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
-                          <citerefentry><refentrytitle>sd_id128_get_machine</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                          <citerefentry><refentrytitle>sd_id128_get_machine</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>systemd-firstboot</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                   </para>
         </refsect1>
 
index 7448e68..c654daa 100644 (file)
                                 <literal>laptop</literal>,
                                 <literal>server</literal>,
                                 <literal>tablet</literal>,
-                                <literal>handset</literal>, as well as
+                               <literal>handset</literal>,
+                               <literal>watch</literal>, as well as
                                 the special chassis types
                                 <literal>vm</literal> and
                                 <literal>container</literal> for
                                 available.</para></listitem>
                         </varlistentry>
 
-                </variablelist>
+                        <varlistentry>
+                                <term><varname>DEPLOYMENT=</varname></term>
+
+                                <listitem><para>Describes the system
+                                deployment environment. One of the
+                                following is suggested:
+                                <literal>development</literal>,
+                                <literal>integration</literal>,
+                                <literal>staging</literal>,
+                                <literal>production</literal>.
+                                </para></listitem>
+                        </varlistentry>
 
+                        <varlistentry>
+                                <term><varname>LOCATION=</varname></term>
+
+                                <listitem><para>Describes the system
+                                location if applicable and
+                                known. Takes a human-friendly,
+                                free-form string. This may be as
+                                generic as <literal>Berlin,
+                                Germany</literal> or as specific as
+                                <literal>Left Rack, 2nd
+                                Shelf</literal>.</para></listitem>
+                        </varlistentry>
+                </variablelist>
         </refsect1>
 
         <refsect1>
 
                 <programlisting>PRETTY_HOSTNAME="Lennart's Tablet"
 ICON_NAME=computer-tablet
-CHASSIS=tablet</programlisting>
+CHASSIS=tablet
+DEPLOYMENT=production</programlisting>
         </refsect1>
 
         <refsect1>
index 89dca9c..2f2e257 100644 (file)
                         </varlistentry>
 
                         <varlistentry>
-                                <term><command>terminate</command> <replaceable>ID</replaceable>...</term>
+                                <term><command>login</command> <replaceable>ID</replaceable></term>
 
-                                <listitem><para>Terminates a virtual
-                                machine or container. This kills all
-                                processes of the virtual machine or
-                                container and deallocates all
-                                resources attached to that
-                                instance.</para></listitem>
+                                <listitem><para>Open a terminal login
+                                session to a container. This will
+                                create a TTY connection to a specific
+                                container and asks for the execution of a
+                                getty on it. Note that this is only
+                                supported for containers running
+                                <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                                as init system.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>reboot</command> <replaceable>ID</replaceable>...</term>
+
+                                <listitem><para>Reboot one or more
+                                containers. This will trigger a reboot
+                                by sending SIGINT to the container's
+                                init process, which is roughly
+                                equivalent to pressing Ctrl+Alt+Del on
+                                a non-containerized system, and is
+                                compatible with containers running any
+                                init system.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>poweroff</command> <replaceable>ID</replaceable>...</term>
+
+                                <listitem><para>Power off one or more
+                                containers. This will trigger a reboot
+                                by sending SIGRTMIN+4 to the
+                                container's init process, which causes
+                                systemd-compatible init systems to
+                                shut down cleanly. This operation does
+                                not work on containers that do not run
+                                a
+                                <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>-compatible
+                                init system, such as
+                                sysvinit.</para></listitem>
                         </varlistentry>
 
                         <varlistentry>
                         </varlistentry>
 
                         <varlistentry>
-                                <term><command>reboot</command> <replaceable>ID</replaceable>...</term>
+                                <term><command>terminate</command> <replaceable>ID</replaceable>...</term>
 
-                                <listitem><para>Reboot one or more
-                                containers. This will trigger a reboot
-                                by sending SIGINT to the container's
-                                init process, which is roughly
-                                equivalent to pressing Ctrl+Alt+Del on
-                                a non-containerized
-                                system.</para></listitem>
+                                <listitem><para>Terminates a virtual
+                                machine or container. This kills all
+                                processes of the virtual machine or
+                                container and deallocates all
+                                resources attached to that
+                                instance.</para></listitem>
                         </varlistentry>
 
-                        <varlistentry>
-                                <term><command>login</command> <replaceable>ID</replaceable></term>
-
-                                <listitem><para>Open a terminal login
-                                session to a container. This will
-                                create a TTY connection to a specific
-                                container and asks for the execution of a
-                                getty on it. Note that this is only
-                                supported for containers running
-                                <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>
-                                as init system.</para></listitem>
-                        </varlistentry>
                 </variablelist>
 
         </refsect1>
index cca3a99..ba9297e 100644 (file)
@@ -123,10 +123,10 @@ netgroup:       nis</programlisting>
                         <citerefentry><refentrytitle>systemd-logind.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>logind.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>loginctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>pam_loginuid</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                        <citerefentry project='man-pages'><refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry project='man-pages'><refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry project='man-pages'><refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry project='die-net'><refentrytitle>pam_loginuid</refentrytitle><manvolnum>8</manvolnum></citerefentry>
                 </para>
         </refsect1>
 
index c1dd62f..4e02f80 100644 (file)
 
         <refsynopsisdiv>
                 <para><filename>/etc/os-release</filename></para>
+                <para><filename>/usr/lib/os-release</filename></para>
         </refsynopsisdiv>
 
         <refsect1>
                 <title>Description</title>
 
-                <para>The <filename>/etc/os-release</filename> file
-                contains operating system identification data.</para>
+                <para>The <filename>/etc/os-release</filename> and
+                <filename>/usr/lib/os-release</filename> files contain
+                operating system identification data.</para>
 
                 <para>The basic file format of
                 <filename>os-release</filename> is a newline-separated
                 strings. Lines beginning with "#" shall be ignored as
                 comments.</para>
 
-                <para><filename>/etc/os-release</filename> contains
-                data that is defined by the operating system vendor
-                and should not be changed by the administrator.</para>
+                <para>The file <filename>/etc/os-release</filename>
+                takes precedence over
+                <filename>/usr/lib/os-release</filename>. Applications
+                should check for the former, and exclusively use its
+                data if it exists, and only fall back to
+                <filename>/usr/lib/os-release</filename> if it is
+                missing. Applications should not read data from both
+                files at the same
+                time. <filename>/usr/lib/os-release</filename> is the
+                recommended place to store OS release information as
+                part of vendor trees. Frequently,
+                <filename>/etc/os-release</filename> is simply a
+                symlink to <filename>/usr/lib/os-release</filename>,
+                to provide compatibility with applications only
+                looking at <filename>/etc</filename>.</para>
+
+                <para><filename>os-release</filename> contains data
+                that is defined by the operating system vendor and
+                should generally not be changed by the
+                administrator.</para>
 
                 <para>As this file only encodes names and identifiers
                 it should not be localized.</para>
 
-                <para>The file <filename>/etc/os-release</filename> might
-                be a symlink to another file, but it is important that
+                <para>The <filename>/etc/os-release</filename> and
+                <filename>/usr/lib/os-release</filename> files might
+                be symlinks to other files, but it is important that
                 the file is available from earliest boot on, and hence
                 must be located on the root file system.</para>
 
                 <para>For a longer rationale for
-                <filename>/etc/os-release</filename> please refer to
+                <filename>os-release</filename> please refer to
                 the <ulink
                 url="http://0pointer.de/blog/projects/os-release">Announcement of <filename>/etc/os-release</filename></ulink>.</para>
         </refsect1>
                 <title>Options</title>
 
                 <para>The following OS identifications parameters may be set using
-                <filename>/etc/os-release</filename>:</para>
+                <filename>os-release</filename>:</para>
 
                 <variablelist>
 
index 3022cdb..52dfe9d 100644 (file)
                                 variable takes precedence. One of
                                 <literal>unspecified</literal>,
                                 <literal>tty</literal>,
-                                <literal>x11</literal> or
-                                <literal>wayland</literal>. See
+                                <literal>x11</literal>,
+                                <literal>wayland</literal> or
+                                <literal>mir</literal>. See
                                 <citerefentry><refentrytitle>sd_session_get_type</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                                 for details about the session type.</para></listitem>
                         </varlistentry>
                         <varlistentry>
                                 <term><varname>$XDG_SESSION_DESKTOP</varname></term>
 
-                                <listitem><para>The session
-                                deskop. This may be used to indicate
-                                the session desktop used, where this
-                                applies. This should be a short,
-                                lowercase string identifying the
-                                desktop environment used if this
+                                <listitem><para>A single, short
+                                identifier string for the desktop
+                                environment. This may be used to
+                                indicate the session desktop used,
+                                where this applies and if this
                                 information is available. For example:
-                                <literal>gnome</literal>, or
-                                <literal>kde</literal>.</para></listitem>
+                                <literal>GNOME</literal>, or
+                                <literal>KDE</literal>. It is
+                                recommended to use the same
+                                identifiers and capitalization as for
+                                <varname>$XDG_CURRENT_DESKTOP</varname>,
+                                as defined by the <ulink
+                                url="http://standards.freedesktop.org/desktop-entry-spec/latest/">Desktop
+                                Entry
+                                Specification</ulink>.</para></listitem>
                         </varlistentry>
 
                         <varlistentry>
@@ -305,10 +312,10 @@ session    required     pam_systemd.so</programlisting>
                         <citerefentry><refentrytitle>systemd-logind.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>logind.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>loginctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>pam_loginuid</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry project='man-pages'><refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry project='man-pages'><refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry project='man-pages'><refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry project='man-pages'><refentrytitle>pam_loginuid</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>systemd.scope</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>systemd.slice</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
diff --git a/man/resolved.conf.xml b/man/resolved.conf.xml
new file mode 100644 (file)
index 0000000..c582368
--- /dev/null
@@ -0,0 +1,142 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2014 Tom Gundersen
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="resolved.conf" conditional='ENABLE_RESOLVED'>
+        <refentryinfo>
+                <title>resolved.conf</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Tom</firstname>
+                                <surname>Gundersen</surname>
+                                <email>teg@jklm.no</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>resolved.conf</refentrytitle>
+                <manvolnum>5</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>resolved.conf</refname>
+                <refpurpose>Network Name Resolution configuration file</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>/etc/systemd/resolved.conf</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para>When starting, systemd-resolved will read the
+                configuration file <filename>resolved.conf</filename>.
+                This configuration file controls local DNS and LLMNR
+                name resolving.</para>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <variablelist class='network-directives'>
+
+                        <varlistentry>
+                                <term><varname>DNS=</varname></term>
+                                <listitem><para>A space separated list
+                                of IPv4 and IPv6 addresses to be used
+                                as system DNS servers. DNS requests
+                                are sent to one of the listed DNS
+                                servers in parallel to any
+                                per-interface DNS servers acquired
+                                from
+                                <citerefentry><refentrytitle>systemd-networkd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>. For
+                                compatibility reasons, if set to the
+                                empty list the DNS servers listed in
+                                <filename>/etc/resolv.conf</filename>
+                                are used, if any are
+                                configured there. This setting
+                                defaults to the empty
+                                list.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>FallbackDNS=</varname></term>
+                                <listitem><para>A space separated list
+                                of IPv4 and IPv6 addresses to be used
+                                as the fallback DNS servers. Any
+                                per-interface DNS servers obtained
+                                from
+                                <citerefentry><refentrytitle>systemd-networkd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                                take precedence over this setting, as
+                                do any servers set via
+                                <varname>DNS=</varname> above or
+                                <filename>/etc/resolv.conf</filename>. This
+                                setting is hence only used if no other
+                                DNS server information is known. If
+                                this option is not given, a
+                                compiled-in list of DNS servers is
+                                used instead.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>LLMNR=</varname></term>
+                                <listitem><para>Takes a boolean
+                                argument or
+                                <literal>resolve</literal>. Controls
+                                Link-Local Multicast Name Resolution support (<ulink
+                                url="https://tools.ietf.org/html/rfc4795">RFC
+                                4794</ulink>) on the local host. If
+                                true enables full LLMNR responder and
+                                resolver support. If false disable
+                                both. If set to
+                                <literal>resolve</literal> only
+                                resolving support is enabled, but
+                                responding is disabled. Note that
+                                <citerefentry><refentrytitle>systemd-networkd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                                also maintains per-interface LLMNR
+                                settings. LLMNR will be enabled on an
+                                interface only if the per-interface
+                                and the global setting is
+                                on.</para></listitem>
+                        </varlistentry>
+
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                  <title>See Also</title>
+                  <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-resolved.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-networkd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>resolv.conf</refentrytitle><manvolnum>4</manvolnum></citerefentry>
+                  </para>
+        </refsect1>
+
+</refentry>
index 2b4f3a5..d78a115 100644 (file)
                 <para>These prefixes are intended to be used in
                 conjunction with stderr-based logging as implemented
                 by systemd. If a systemd service definition file is
-                configured with <varname>StandardError=syslog</varname>
-                or <varname>StandardError=kmsg</varname>, these
-                prefixes can be used to encode a log level in lines
+                configured with
+                <varname>StandardError=journal</varname>,
+                <varname>StandardError=syslog</varname> or
+                <varname>StandardError=kmsg</varname>, these prefixes
+                can be used to encode a log level in lines
                 printed. This is similar to the kernel
                 <function>printk()</function>-style logging. See
                 <citerefentry><refentrytitle>klogctl</refentrytitle><manvolnum>2</manvolnum></citerefentry>
                 for more information.</para>
 
                 <para>The log levels are identical to
-                <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>'s
+                <citerefentry project='man-pages'><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>'s
                 log level system. To use these prefixes simply prefix
                 every line with one of these strings. A line that is
                 not prefixed will be logged at the default log level
                         <citerefentry><refentrytitle>daemon</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>fprintf</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry project='man-pages'><refentrytitle>fprintf</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>sd-readahead</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                        <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 </para>
         </refsect1>
 
index 5a4146a..d9ebb9c 100644 (file)
                 <para><function>SD_ID128_FORMAT_STR</function> and
                 <function>SD_ID128_FORMAT_VAL()</function> may be used
                 to format a 128-bit ID in a
-                <citerefentry><refentrytitle>printf</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                <citerefentry project='man-pages'><refentrytitle>printf</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                 format string, as shown in the following
                 example:</para>
 
                         <citerefentry><refentrytitle>sd_id128_to_string</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>sd_id128_randomize</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>sd_id128_get_machine</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>printf</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry project='man-pages'><refentrytitle>printf</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>sd-journal</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>
                 </para>
         </refsect1>
index 7a05aee..edf7c32 100644 (file)
@@ -79,7 +79,8 @@
                 <citerefentry><refentrytitle>sd_journal_add_match</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
                 <citerefentry><refentrytitle>sd_journal_seek_head</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
                 <citerefentry><refentrytitle>sd_journal_get_cursor</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
-                <citerefentry><refentrytitle>sd_journal_cutoff_realtime_usec</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                <citerefentry><refentrytitle>sd_journal_get_cutoff_realtime_usec</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                <citerefentry><refentrytitle>sd_journal_get_cutoff_monotonic_usec</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
                 <citerefentry><refentrytitle>sd_journal_get_usage</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
                 <citerefentry><refentrytitle>sd_journal_get_catalog</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                 and
                         <citerefentry><refentrytitle>sd_journal_add_match</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>sd_journal_seek_head</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>sd_journal_get_cursor</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>sd_journal_cutoff_realtime_usec</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_get_cutoff_realtime_usec</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sd_journal_get_cutoff_monotonic_usec</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>sd_journal_get_usage</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>sd_journal_get_fd</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>sd_journal_query_unique</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>sd_journal_get_catalog</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>sd-id128</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                        <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 </para>
         </refsect1>
 
index e68f4fd..d8d4504 100644 (file)
@@ -98,7 +98,7 @@
                 <para>If the functions return string arrays, these are
                 generally <constant>NULL</constant> terminated and need to be freed by the
                 caller with the libc
-                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                <citerefentry project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                 call after use, including the strings referenced
                 therein. Similarly, individual strings returned need to
                 be freed, as well.</para>
                         <citerefentry><refentrytitle>sd_login_monitor_new</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>sd-readahead</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                        <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 </para>
         </refsect1>
 
index f84fbae..5a84857 100644 (file)
@@ -314,7 +314,7 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
     capabilities mask. A positive return value means that is was
     set, zero means that it was not set, and a negative return
     value signifies an error. See
-    <citerefentry><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+    <citerefentry project='man-pages'><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry>
     and <varname>Capabilities=</varname> and
     <varname>CapabilityBoundingSet=</varname> settings in
     <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
@@ -431,7 +431,7 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
     <para><function>sd_bus_open_user()</function> and other functions
     described here are available as a shared library, which can be
     compiled and linked to with the
-    <constant>libsystemd</constant> <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+    <constant>libsystemd</constant> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
     file.</para>
   </refsect1>
 
@@ -441,11 +441,11 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
     <para>
       <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
       <citerefentry><refentrytitle>sd-bus</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
-      <citerefentry><refentrytitle>credentials</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
       <citerefentry><refentrytitle>fork</refentrytitle><manvolnum>2</manvolnum></citerefentry>,
       <citerefentry><refentrytitle>execve</refentrytitle><manvolnum>2</manvolnum></citerefentry>,
-      <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
-      <citerefentry><refentrytitle>proc</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+      <citerefentry project='man-pages'><refentrytitle>credentials</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+      <citerefentry project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry project='man-pages'><refentrytitle>proc</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
       <citerefentry><refentrytitle>systemd.journald-fields</refentrytitle><manvolnum>7</manvolnum></citerefentry>
     </para>
   </refsect1>
index 64b92e2..406769b 100644 (file)
@@ -233,7 +233,7 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
     <para><function>sd_bus_creds_new_from_pid()</function> is
     available as a shared library, which can be compiled and linked to
     with the
-    <constant>libsystemd</constant> <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+    <constant>libsystemd</constant> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
     file.</para>
   </refsect1>
 
index 68f1d7b..3317ead 100644 (file)
@@ -232,8 +232,8 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
     <title>Description</title>
 
     <para>The <structname>sd_bus_error</structname> structure carries
-    information for a <filename>sd-bus</filename> error.
-    Functions described below can be used to set and query fields in
+    information for a <filename>sd-bus</filename> error. The
+    functions described below can be used to set and query fields in
     this structure. The <structfield>name</structfield> field contains a
     short identifier of an error. It should follow the rules for error
     names described in the D-Bus specification, subsection <ulink
@@ -246,7 +246,7 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
     <para><function>sd_bus_error_set</function> will return an
     errno-like negative value returned based on parameter
     <parameter>name</parameter> (see
-    <citerefentry><refentrytitle>errno</refentrytitle><manvolnum>3</manvolnum></citerefentry>).
+    <citerefentry project='man-pages'><refentrytitle>errno</refentrytitle><manvolnum>3</manvolnum></citerefentry>).
     Various well-known D-Bus errors are converted to specific values,
     and the remaining ones to <constant>-ENXIO</constant>. Well-known
     D-Bus error names are available as constants
@@ -270,7 +270,7 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
 
     <para><function>sd_bus_error_setf</function> is similar to
     <function>sd_bus_error_set</function>, but takes a
-    <citerefentry><refentrytitle>printf</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+    <citerefentry project='man-pages'><refentrytitle>printf</refentrytitle><manvolnum>3</manvolnum></citerefentry>
     format string and corresponding arguments to generate
     <structname>message</structname>.</para>
 
@@ -291,7 +291,7 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
     <para><function>sd_bus_error_set_errnof</function> is similar to
     <function>sd_bus_error_set_errno</function>, but in addition to
     <parameter>name</parameter>, takes a
-    <citerefentry><refentrytitle>printf</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+    <citerefentry project='man-pages'><refentrytitle>printf</refentrytitle><manvolnum>3</manvolnum></citerefentry>
     format and corresponding arguments.
     <structfield>name</structfield> will be generated from
     <parameter>format</parameter> and the arguments.</para>
@@ -322,7 +322,7 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
     <para><function>sd_bus_error_free</function> will destroy resources
     held by <parameter>e</parameter>. The parameter itself will not
     be deallocated, and must be
-    <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>d
+    <citerefentry project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>d
     by the caller if necessary.</para>
   </refsect1>
 
@@ -397,7 +397,7 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
     <para><function>sd_bus_set_error()</function> and other functions
     described here are available as a shared library, which can be
     compiled and linked to with the
-    <constant>libsystemd</constant> <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+    <constant>libsystemd</constant> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
     file.</para>
   </refsect1>
 
@@ -407,7 +407,7 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
     <para>
       <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
       <citerefentry><refentrytitle>sd-bus</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
-      <citerefentry><refentrytitle>errno</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry project='man-pages'><refentrytitle>errno</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
       <citerefentry><refentrytitle>strerror</refentrytitle><manvolnum>3</manvolnum></citerefentry>
     </para>
   </refsect1>
diff --git a/man/sd_bus_label_escape.xml b/man/sd_bus_label_escape.xml
deleted file mode 100644 (file)
index 0b5564f..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-<?xml version='1.0'?> <!--*-nxml-*-->
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
-"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
-
-<!--
-This file is part of systemd.
-
-Copyright 2014 Zbigniew Jędrzejewski-Szmek
-
-systemd is free software; you can redistribute it and/or modify it
-under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation; either version 2.1 of the License, or
-(at your option) any later version.
-
-systemd is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with systemd; If not, see <http://www.gnu.org/licenses/>.
--->
-
-<refentry id="sd_bus_label_escape" conditional="ENABLE_KDBUS">
-
-  <refentryinfo>
-    <title>sd_bus_label_escape</title>
-    <productname>systemd</productname>
-
-    <authorgroup>
-      <author>
-        <contrib>A monkey with a typewriter</contrib>
-        <firstname>Zbigniew</firstname>
-        <surname>Jędrzejewski-Szmek</surname>
-        <email>zbyszek@in.waw.pl</email>
-      </author>
-    </authorgroup>
-  </refentryinfo>
-
-  <refmeta>
-    <refentrytitle>sd_bus_label_escape</refentrytitle>
-    <manvolnum>3</manvolnum>
-  </refmeta>
-
-  <refnamediv>
-    <refname>sd_bus_label_escape</refname>
-    <refname>sd_bus_label_unescape</refname>
-
-    <refpurpose>Escape D-Bus object path special characters</refpurpose>
-  </refnamediv>
-
-  <refsynopsisdiv>
-    <funcsynopsis>
-      <funcsynopsisinfo>#include &lt;systemd/sd-bus.h&gt;</funcsynopsisinfo>
-
-      <funcprototype>
-        <funcdef>char *<function>sd_bus_label_escape</function></funcdef>
-        <paramdef>const char *<parameter>s</parameter></paramdef>
-      </funcprototype>
-
-      <funcprototype>
-        <funcdef>char *<function>sd_bus_label_unescape</function></funcdef>
-        <paramdef>const char *<parameter>f</parameter></paramdef>
-      </funcprototype>
-    </funcsynopsis>
-  </refsynopsisdiv>
-
-  <refsect1>
-    <title>Description</title>
-
-    <para><function>sd_bus_label_escape()</function> takes a
-    <constant>NUL</constant>-terminated string as a argument. It will
-    replace all characters which are invalid in a D-Bus object path by
-    <literal>_</literal> and a hexadecimal number. As a special case,
-    the empty string will be replaced by a lone <literal>_</literal>.
-    <function>sd_bus_label_unescape()</function> can be used to
-    reverse this process.</para>
-  </refsect1>
-
-  <refsect1>
-    <title>Return Value</title>
-
-    <para>On success, a new <constant>NUL</constant>-terminated string
-    will be returned. It must be
-    <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>d
-    by the caller. If a memory allocation failure occurs,
-    <constant>NULL</constant> will be returned.
-    </para>
-  </refsect1>
-
-  <refsect1>
-    <title>Notes</title>
-
-    <para><function>sd_bus_label_escape()</function> and
-    <function>sd_bus_label_unescape()</function> are available as a
-    shared library, which can be compiled and linked to with the
-    <constant>libsystemd</constant> <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
-    file.</para>
-  </refsect1>
-
-  <refsect1>
-    <title>See Also</title>
-
-    <para>
-      <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
-      <citerefentry><refentrytitle>sd-bus</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
-      <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
-    </para>
-  </refsect1>
-
-</refentry>
diff --git a/man/sd_bus_message_append.xml b/man/sd_bus_message_append.xml
new file mode 100644 (file)
index 0000000..961ab53
--- /dev/null
@@ -0,0 +1,254 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+This file is part of systemd.
+
+Copyright 2014 Zbigniew Jędrzejewski-Szmek
+
+systemd is free software; you can redistribute it and/or modify it
+under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+systemd is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd_bus_message_append" conditional="ENABLE_KDBUS"
+          xmlns:xi="http://www.w3.org/2001/XInclude">
+
+  <refentryinfo>
+    <title>sd_bus_message_append</title>
+    <productname>systemd</productname>
+
+    <authorgroup>
+      <author>
+        <contrib>A monkey with a typewriter</contrib>
+        <firstname>Zbigniew</firstname>
+        <surname>Jędrzejewski-Szmek</surname>
+        <email>zbyszek@in.waw.pl</email>
+      </author>
+    </authorgroup>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>sd_bus_message_append</refentrytitle>
+    <manvolnum>3</manvolnum>
+  </refmeta>
+
+  <refnamediv>
+    <refname>sd_bus_message_append</refname>
+
+    <refpurpose>Attach parts of message based on a format string</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcsynopsisinfo>#include &lt;systemd/sd-bus.h&gt;</funcsynopsisinfo>
+
+      <funcprototype>
+        <funcdef>int sd_bus_message_append</funcdef>
+        <paramdef>sd_bus_message *<parameter>m</parameter></paramdef>
+        <paramdef>const char *<parameter>types</parameter></paramdef>
+        <paramdef>...</paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>The <function>sd_bus_message_append</function> function appends
+    a sequence of items to message <parameter>m</parameter>. The
+    format string <parameter>types</parameter> describes the types of
+    arguments that follow.</para>
+
+    <para>The format string is composed of the elements shown in the
+    table below. It contains zero or more single "complete types".
+    Each complete type may be one of the basic types or a fully
+    described container type. A container type may be a structure, a
+    variant type code, an array with its element type, or a dictionary
+    with its entry type. The format string is
+    <constant>NUL</constant>-terminated.</para>
+
+    <para>In case of a basic type, one argument of the corresponding
+    type is expected.</para>
+
+    <para>A structure is denoted by a sequence of complete types
+    between <literal>(</literal> and <literal>)</literal>. This
+    sequence cannot be empty — it must contain at least one type.
+    Arguments corresponding to this nested sequence follow the same
+    rules as if they were not nested.</para>
+
+    <para>A variant is denoted by <literal>v</literal>. Correspoding
+    arguments must include a format string denoting a complete type,
+    and following that, arguments corresponding to the specified type.
+    </para>
+
+    <para>An array is denoted by <literal>a</literal> followed by a
+    complete type. Corresponding arguments must include the size of
+    the array, and then repeated this number of times, arguments
+    corresponding to the nested type.</para>
+
+    <para>A dictionary is an array of dictionary entries, denoted by
+    <literal>a</literal> followed by a pair of complete types between
+    <literal>{</literal> and <literal>}</literal>. The first of those
+    types must be a basic type. Corresponding arguments must include
+    the size of the dictionary, and then repeated this number of
+    times, arguments corresponding to each of the two nested
+    types.</para>
+
+    <table>
+      <title>Item format specifiers</title>
+
+      <tgroup cols='4'>
+        <xi:include href="sd_bus_message_append_basic.xml" xpointer="xpointer(//table[@id='format-specifiers'])//colspec" />
+        <xi:include href="sd_bus_message_append_basic.xml" xpointer="xpointer(//table[@id='format-specifiers']//thead)" />
+
+        <tbody>
+          <xi:include href="sd_bus_message_append_basic.xml" xpointer="xpointer(//table[@id='format-specifiers']//tbody/*)" />
+
+          <row>
+            <entry><literal>a</literal></entry>
+            <entry><constant>SD_BUS_TYPE_ARRAY</constant></entry>
+            <entry>array</entry>
+            <entry>determined by array type and size</entry>
+          </row>
+
+          <row>
+            <entry><literal>v</literal></entry>
+            <entry><constant>SD_BUS_TYPE_VARIANT</constant></entry>
+            <entry>variant</entry>
+            <entry>determined by the type argument</entry>
+          </row>
+
+          <row>
+            <entry><literal>(</literal></entry>
+            <entry><constant>SD_BUS_TYPE_STRUCT_BEGIN</constant></entry>
+            <entry>array start</entry>
+            <entry morerows="1">determined by the nested types</entry>
+          </row>
+          <row>
+            <entry><literal>)</literal></entry>
+            <entry><constant>SD_BUS_TYPE_STRUCT_END</constant></entry>
+            <entry>array end</entry>
+          </row>
+
+          <row>
+            <entry><literal>{</literal></entry>
+            <entry><constant>SD_BUS_TYPE_DICT_ENTRY_BEGIN</constant></entry>
+            <entry>dictionary entry start</entry>
+            <entry morerows="1">determined by the nested types</entry>
+          </row>
+          <row>
+            <entry><literal>}</literal></entry>
+            <entry><constant>SD_BUS_TYPE_DICT_ENTRY_END</constant></entry>
+            <entry>dictionary entry end</entry>
+          </row>
+       </tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    <title>Types string grammar</title>
+
+    <programlisting>types ::= complete_type*
+complete_type ::= basic_type | variant | structure | array | dictionary
+basic_type ::= "y" | "n" | "q" | "u" | "i" | "x" | "t" | "d" |
+               "b" | "h" |
+               "s" | "o" | "g"
+variant ::= "v"
+structure ::= "(" complete_type+ ")"
+array ::= "a" complete_type
+dictionary ::= "a" "{" basic_type complete_type "}"
+</programlisting>
+  </refsect1>
+
+  <refsect1>
+    <title>Examples</title>
+
+    <para>Append a single basic type (the string <literal>a string</literal>):
+    </para>
+
+    <programlisting>sd_bus_message *m;
+...
+sd_bus_message_append(m, "s", "a string");</programlisting>
+
+    <para>Append all types of integers:</para>
+
+    <programlisting>uint8_t y = 1;
+int16_t n = 2;
+uint16_t q = 3;
+int32_t i = 4;
+uint32_t u = 5;
+int32_t x = 6;
+uint32_t t = 7;
+double d = 8.0;
+sd_bus_message_append(m, "ynqiuxtd", y, n, q, i, u, x, t, d);</programlisting>
+
+     <para>Append a structure composed of string and a D-Bus path:</para>
+
+     <programlisting>sd_bus_message_append(m, "(so)", "a string", "/a/path");
+</programlisting>
+
+     <para>Append an array of UNIX file descriptors:</para>
+
+     <programlisting>sd_bus_message_append(m, "ah", 3, STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO);
+</programlisting>
+
+     <para>Append a variant, with the real type "g" (signature),
+     and value "sdbusisgood":</para>
+
+     <programlisting>sd_bus_message_append(m, "v", "g", "sdbusisgood");</programlisting>
+
+     <para>Append a dictionary containing the mapping {1=>"a", 2=>"b", 3=>""}:
+     </para>
+
+     <programlisting>sd_bus_message_append(m, "a{is}", 3, 1, "a", 2, "b", 3, NULL);
+     </programlisting>
+  </refsect1>
+
+  <refsect1>
+    <title>Return Value</title>
+
+    <para>On success, this call returns 0 or a positive
+    integer. On failure, this call returns a negative
+    errno-style error code.</para>
+  </refsect1>
+
+  <xi:include href="sd_bus_message_append_basic.xml" xpointer="errors" />
+
+  <refsect1>
+    <title>Notes</title>
+
+    <para><function>sd_bus_open_user()</function> and other functions
+    described here are available as a shared library, which can be
+    compiled and linked to with the
+    <constant>libsystemd-bus</constant> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+    file.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>See Also</title>
+
+    <para>
+      <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd-bus</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd_bus_new</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd_bus_ref</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd_bus_unref</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>ssh</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>systemd-machined.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>machinectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+    </para>
+  </refsect1>
+
+</refentry>
diff --git a/man/sd_bus_message_append_array.xml b/man/sd_bus_message_append_array.xml
new file mode 100644 (file)
index 0000000..e0f6767
--- /dev/null
@@ -0,0 +1,190 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+This file is part of systemd.
+
+Copyright 2014 Zbigniew Jędrzejewski-Szmek
+
+systemd is free software; you can redistribute it and/or modify it
+under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+systemd is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd_bus_message_append_array" conditional="ENABLE_KDBUS"
+          xmlns:xi="http://www.w3.org/2001/XInclude">
+
+  <refentryinfo>
+    <title>sd_bus_message_append_array</title>
+    <productname>systemd</productname>
+
+    <authorgroup>
+      <author>
+        <contrib>A monkey with a typewriter</contrib>
+        <firstname>Zbigniew</firstname>
+        <surname>Jędrzejewski-Szmek</surname>
+        <email>zbyszek@in.waw.pl</email>
+      </author>
+    </authorgroup>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>sd_bus_message_append_array</refentrytitle>
+    <manvolnum>3</manvolnum>
+  </refmeta>
+
+  <refnamediv>
+    <refname>sd_bus_message_append_array</refname>
+    <refname>sd_bus_message_append_array_memfd</refname>
+    <refname>sd_bus_message_append_array_iovec</refname>
+    <refname>sd_bus_message_append_array_space</refname>
+
+    <refpurpose>Attach an array of items to a message</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcsynopsisinfo>#include &lt;systemd/sd-bus.h&gt;</funcsynopsisinfo>
+
+      <funcprototype>
+        <funcdef>int sd_bus_message_append_array</funcdef>
+        <paramdef>sd_bus_message *<parameter>m</parameter></paramdef>
+        <paramdef>char <parameter>type</parameter></paramdef>
+        <paramdef>char void *<parameter>ptr</parameter></paramdef>
+        <paramdef>size_t <parameter>size</parameter></paramdef>
+      </funcprototype>
+
+      <funcprototype>
+        <funcdef>int sd_bus_message_append_array_memfd</funcdef>
+        <paramdef>sd_bus_message *<parameter>m</parameter></paramdef>
+        <paramdef>char <parameter>type</parameter></paramdef>
+        <paramdef>sd_memfd *<parameter>memfd</parameter></paramdef>
+      </funcprototype>
+
+      <funcprototype>
+        <funcdef>int sd_bus_message_append_array_iovec</funcdef>
+        <paramdef>sd_bus_message *<parameter>m</parameter></paramdef>
+        <paramdef>char <parameter>type</parameter></paramdef>
+        <paramdef>const struct iovec *<parameter>iov</parameter></paramdef>
+        <paramdef>unsigned <parameter>n</parameter></paramdef>
+      </funcprototype>
+
+      <funcprototype>
+        <funcdef>int sd_bus_message_append_array_space</funcdef>
+        <paramdef>char <parameter>type</parameter></paramdef>
+        <paramdef>size_t <parameter>size</parameter></paramdef>
+        <paramdef>char void **<parameter>ptr</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>The <function>sd_bus_message_append_array</function> functionc
+    appends items to message <parameter>m</parameter> as the single
+    array. A container will be opened, items appended, and the
+    container closed. Parameter <parameter>type</parameter> determines
+    how pointer <parameter>p</parameter> is interpreted.
+    <parameter>type</parameter> must be one of the "trivial" types
+    <literal>y</literal>, <literal>n</literal>, <literal>q</literal>,
+    <literal>i</literal>, <literal>u</literal>, <literal>x</literal>,
+    <literal>t</literal>, <literal>d</literal> (but not
+    <literal>b</literal>), as defined by the
+    <ulink url="http://dbus.freedesktop.org/doc/dbus-specification.html#basic-types">Basic Types</ulink>
+    section of the D-Bus specification, and listed in
+    <citerefentry><refentrytitle>sd_bus_message_append_basic</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
+    Pointer <parameter>p</parameter> must point to an array of size
+    <parameter>size</parameter> bytes containing items of the
+    respective type. Size <parameter>size</parameter> must be a
+    multiple of the size of the type <parameter>type</parameter>. As a
+    special case, <parameter>p</parameter> may be
+    <constant>NULL</constant>, if <parameter>size</parameter> is 0.
+    </para>
+
+    <para>The memory pointed at by <parameter>p</parameter> is copied
+    into the memory area containing the message and may be changed
+    after this call.</para>
+
+    <para>The
+    <function>sd_bus_message_append_array_memfd</function> function appends
+    items to message <parameter>m</parameter>, similarly to
+    <function>sd_bus_message_append_array</function>. Contents of the
+    memory file descriptor <parameter>memfd</parameter> are used as
+    the contents of the array. Their size must be a multiple of the
+    size of the type <parameter>type</parameter>.</para>
+
+    <para>The descriptor specified with <parameter>memfd</parameter>
+    will be sealed and cannot be modified after this call.</para>
+
+    <para>The
+    <function>sd_bus_message_append_array_iovec</function> function appends
+    items to message <parameter>m</parameter>, similarly to
+    <function>sd_bus_message_append_array</function>. Contents of the
+    iovec <parameter>iov</parameter> are used as the contents of the
+    array. The total size of <parameter>iov</parameter> payload (the
+    sum of <structfield>iov_len</structfield> fields) must be a multiple
+    of the size of the type <parameter>type</parameter>.</para>
+
+    <para>The <parameter>iov</parameter> argument must point to
+    <parameter>n</parameter> <structname>struct iovec</structname>
+    structures. Each structure may have the
+    <structname>iov_base</structname> field set, in which case the
+    memory pointed to will be copied into the message, or unset, in
+    which case a block of zeros of length
+    <structname>iov_len</structname> bytes will be inserted. The
+    memory pointed at by <parameter>iov</parameter> may be changed
+    after this call.</para>
+
+    <para>The
+    <function>sd_bus_message_append_array_space</function> function appends
+    space for an array of items to message <parameter>m</parameter>.
+    It behaves the same as
+    <function>sd_bus_message_append_array</function>, but instead
+    of copying items to the message, it returns a pointer to the
+    destination area to the caller in pointer <parameter>p</parameter>.
+    </para>
+  </refsect1>
+
+  <refsect1>
+    <title>Return Value</title>
+
+    <para>On success, these calls return 0 or a positive integer. On
+    failure, they returns a negative errno-style error code.</para>
+  </refsect1>
+
+  <xi:include href="sd_bus_message_append_basic.xml" xpointer="errors" />
+
+  <refsect1>
+    <title>Notes</title>
+
+    <para><function>sd_bus_append_array()</function> and other
+    functions described here are available as a shared library, which
+    can be compiled and linked to with the
+    <constant>libsystemd</constant> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+    file.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>See Also</title>
+
+    <para>
+      <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd-bus</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd_bus_message_append</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd_bus_message_append_basic</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <ulink url="http://dbus.freedesktop.org/doc/dbus-specification.html">The D-Bus specification</ulink>
+    </para>
+  </refsect1>
+
+</refentry>
diff --git a/man/sd_bus_message_append_basic.xml b/man/sd_bus_message_append_basic.xml
new file mode 100644 (file)
index 0000000..da92020
--- /dev/null
@@ -0,0 +1,278 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+This file is part of systemd.
+
+Copyright 2014 Zbigniew Jędrzejewski-Szmek
+
+systemd is free software; you can redistribute it and/or modify it
+under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+systemd is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd_bus_message_append_basic" conditional="ENABLE_KDBUS">
+
+  <refentryinfo>
+    <title>sd_bus_message_append_basic</title>
+    <productname>systemd</productname>
+
+    <authorgroup>
+      <author>
+        <contrib>A monkey with a typewriter</contrib>
+        <firstname>Zbigniew</firstname>
+        <surname>Jędrzejewski-Szmek</surname>
+        <email>zbyszek@in.waw.pl</email>
+      </author>
+    </authorgroup>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>sd_bus_message_append_basic</refentrytitle>
+    <manvolnum>3</manvolnum>
+  </refmeta>
+
+  <refnamediv>
+    <refname>sd_bus_message_append_basic</refname>
+
+    <refpurpose>Attach a single part to a message</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcsynopsisinfo>#include &lt;systemd/sd-bus.h&gt;</funcsynopsisinfo>
+
+      <funcprototype>
+        <funcdef>int sd_bus_message_append_basic</funcdef>
+        <paramdef>sd_bus_message *<parameter>m</parameter></paramdef>
+        <paramdef>char <parameter>type</parameter></paramdef>
+        <paramdef>char void *<parameter>p</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para><function>sd_bus_message_append_basic</function> appends a
+    single item to the message <parameter>m</parameter>. Parameter
+    <parameter>type</parameter> determines how pointer
+    <parameter>p</parameter> is interpreted.
+    <parameter>type</parameter> must be one of the basic types
+    as defined by the
+
+    <ulink url="http://dbus.freedesktop.org/doc/dbus-specification.html#basic-types">Basic Types</ulink>
+    section of the D-Bus specification, and listed in the table below.
+    </para>
+
+    <table id='format-specifiers'>
+      <title>Item format specifiers</title>
+
+      <tgroup cols='4'>
+        <colspec colname='specifier' />
+        <colspec colname='constant' />
+        <colspec colname='description' />
+        <colspec colname='size' />
+        <thead>
+          <row>
+            <entry>Specifier</entry>
+            <entry>Constant</entry>
+            <entry>Description</entry>
+            <entry>Size</entry>
+          </row>
+        </thead>
+        <tbody>
+          <row>
+            <entry><literal>y</literal></entry>
+            <entry><constant>SD_BUS_TYPE_BYTE</constant></entry>
+            <entry>unsigned interger</entry>
+            <entry>1 byte</entry>
+          </row>
+
+          <row>
+            <entry><literal>b</literal></entry>
+            <entry><constant>SD_BUS_TYPE_BOOLEAN</constant></entry>
+            <entry>boolean</entry>
+            <entry>4 bytes</entry>
+          </row>
+
+          <row>
+            <entry><literal>n</literal></entry>
+            <entry><constant>SD_BUS_TYPE_INT16</constant></entry>
+            <entry>signed integer</entry>
+            <entry>2 bytes</entry>
+          </row>
+
+          <row>
+            <entry><literal>q</literal></entry>
+            <entry><constant>SD_BUS_TYPE_UINT16</constant></entry>
+            <entry>unsigned integer</entry>
+            <entry>2 bytes</entry>
+          </row>
+
+          <row>
+            <entry><literal>i</literal></entry>
+            <entry><constant>SD_BUS_TYPE_INT32</constant></entry>
+            <entry>signed integer</entry>
+            <entry>4 bytes</entry>
+          </row>
+
+          <row>
+            <entry><literal>u</literal></entry>
+            <entry><constant>SD_BUS_TYPE_UINT32</constant></entry>
+            <entry>unsigned integer</entry>
+            <entry>4 bytes</entry>
+          </row>
+
+          <row>
+            <entry><literal>x</literal></entry>
+            <entry><constant>SD_BUS_TYPE_INT64</constant></entry>
+            <entry>signed integer</entry>
+            <entry>8 bytes</entry>
+          </row>
+
+          <row>
+            <entry><literal>t</literal></entry>
+            <entry><constant>SD_BUS_TYPE_UINT64</constant></entry>
+            <entry>unsigned integer</entry>
+            <entry>8 bytes</entry>
+          </row>
+
+          <row>
+            <entry><literal>d</literal></entry>
+            <entry><constant>SD_BUS_TYPE_DOUBLE</constant></entry>
+            <entry>floating-point</entry>
+            <entry>8 bytes</entry>
+          </row>
+
+          <row>
+            <entry><literal>s</literal></entry>
+            <entry><constant>SD_BUS_TYPE_STRING</constant></entry>
+            <entry>Unicode string</entry>
+            <entry>variable</entry>
+          </row>
+
+          <row>
+            <entry><literal>o</literal></entry>
+            <entry><constant>SD_BUS_TYPE_OBJECT_PATH</constant></entry>
+            <entry>object path</entry>
+            <entry>variable</entry>
+          </row>
+
+          <row>
+            <entry><literal>g</literal></entry>
+            <entry><constant>SD_BUS_TYPE_SIGNATURE</constant></entry>
+            <entry>signature</entry>
+            <entry>variable</entry>
+          </row>
+
+          <row>
+            <entry><literal>h</literal></entry>
+            <entry><constant>SD_BUS_TYPE_UNIX_FD</constant></entry>
+            <entry>UNIX file descriptor</entry>
+            <entry>4 bytes</entry>
+          </row>
+       </tbody>
+      </tgroup>
+    </table>
+
+    <para>The value of the parameter is copied into the memory area
+    containing the message and may be changed after this call. If
+    <parameter>type</parameter> is <literal>h</literal> (UNIX file
+    descriptor), it is always "consumed" by this call, and either
+    successfully appended to the message or closed.</para>
+
+    <para>For types <literal>s</literal>, <literal>o</literal>, and
+    <literal>g</literal>, the parameter <parameter>p</parameter> is
+    interpreted as a pointer to a <constant>NUL</constant>-terminated
+    character sequence. As a special case, a <constant>NULL</constant>
+    pointer is interpreted as an empty string. The string should be
+    valid Unicode string encoded as UTF-8. In case of the two latter
+    types, the additional requirements for a D-Bus object path or
+    type signature should be satisfied. Those requirements should be
+    verified by the recepient of the message.
+    </para>
+  </refsect1>
+
+  <refsect1>
+    <title>Return Value</title>
+
+    <para>On success, this call returns 0 or a positive integer. On
+    failure, it returns a negative errno-style error code.</para>
+  </refsect1>
+
+  <refsect1 id='errors'>
+    <title>Errors</title>
+
+    <para>Returned errors may indicate the following problems:</para>
+
+    <variablelist>
+
+      <varlistentry>
+        <term><varname>-EINVAL</varname></term>
+
+        <listitem><para>Specified parameter is invalid.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>-EPERM</varname></term>
+
+        <listitem><para>Message has been sealed.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>-ESTALE</varname></term>
+
+        <listitem><para>Message is in invalid state.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>-ENXIO</varname></term>
+
+        <listitem><para>Message cannot be appended to.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>-ENOMEM</varname></term>
+
+        <listitem><para>Memory allocation failed.</para></listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Notes</title>
+
+    <para>The <function>sd_bus_append_basic()</function> function
+    described here is available as a shared library, which can be
+    compiled and linked to with the
+    <constant>libsystemd</constant> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+    file.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>See Also</title>
+
+    <para>
+      <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd-bus</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd_bus_message_append</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <ulink url="http://dbus.freedesktop.org/doc/dbus-specification.html">The D-Bus specification</ulink>
+    </para>
+  </refsect1>
+
+</refentry>
diff --git a/man/sd_bus_message_append_string_memfd.xml b/man/sd_bus_message_append_string_memfd.xml
new file mode 100644 (file)
index 0000000..fd857cc
--- /dev/null
@@ -0,0 +1,153 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+This file is part of systemd.
+
+Copyright 2014 Zbigniew Jędrzejewski-Szmek
+
+systemd is free software; you can redistribute it and/or modify it
+under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+systemd is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd_bus_message_append_string_memfd" conditional="ENABLE_KDBUS"
+          xmlns:xi="http://www.w3.org/2001/XInclude">
+
+  <refentryinfo>
+    <title>sd_bus_message_append_string_memfd</title>
+    <productname>systemd</productname>
+
+    <authorgroup>
+      <author>
+        <contrib>A monkey with a typewriter</contrib>
+        <firstname>Zbigniew</firstname>
+        <surname>Jędrzejewski-Szmek</surname>
+        <email>zbyszek@in.waw.pl</email>
+      </author>
+    </authorgroup>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>sd_bus_message_append_string_memfd</refentrytitle>
+    <manvolnum>3</manvolnum>
+  </refmeta>
+
+  <refnamediv>
+    <refname>sd_bus_message_append_string_memfd</refname>
+    <refname>sd_bus_message_append_string_iovec</refname>
+    <refname>sd_bus_message_append_string_space</refname>
+
+    <refpurpose>Attach a string to a message</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcsynopsisinfo>#include &lt;systemd/sd-bus.h&gt;</funcsynopsisinfo>
+
+      <funcprototype>
+        <funcdef>int sd_bus_message_append_string_memfd</funcdef>
+        <paramdef>sd_bus_message *<parameter>m</parameter></paramdef>
+        <paramdef>sd_memfd *<parameter>memfd</parameter></paramdef>
+      </funcprototype>
+
+      <funcprototype>
+        <funcdef>int sd_bus_message_append_string_iovec</funcdef>
+        <paramdef>sd_bus_message *<parameter>m</parameter></paramdef>
+        <paramdef>const struct iovec *<parameter>iov</parameter></paramdef>
+        <paramdef>unsigned <parameter>n</parameter></paramdef>
+      </funcprototype>
+
+      <funcprototype>
+        <funcdef>int sd_bus_message_append_string_space</funcdef>
+        <paramdef>sd_bus_message *<parameter>m</parameter></paramdef>
+        <paramdef>size_t <parameter>size</parameter></paramdef>
+        <paramdef>char **<parameter>s</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>The functions
+    <function>sd_bus_message_append_string_memfd</function> and
+    <function>sd_bus_message_append_string_iovec</function> can be
+    used to append a single string (item of type <literal>s</literal>)
+    to message <parameter>m</parameter>.</para>
+
+    <para>In case of
+    <function>sd_bus_message_append_string_memfd</function>, the
+    contents of <parameter>memfd</parameter> are the string. They must
+    satisfy the same constraints as described for the
+    <literal>s</literal> type in
+    <citerefentry><refentrytitle>sd_bus_message_append_basic</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
+
+    <para>In case of
+    <function>sd_bus_message_append_string_iovec</function>, the
+    payload of <parameter>iov</parameter> is the string. It must
+    satisfy the same constraints as described for the
+    <literal>s</literal> type in
+    <citerefentry><refentrytitle>sd_bus_message_append_basic</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
+
+    <para>The <parameter>iov</parameter> argument must point to
+    <parameter>n</parameter> <structname>struct iovec</structname>
+    structures. Each structure may have the
+    <structname>iov_base</structname> field set, in which case the
+    memory pointed to will be copied into the message, or unset, in
+    which case a block of spaces (ASCII 32) of length
+    <structname>iov_len</structname> will be inserted. The
+    memory pointed at by <parameter>iov</parameter> may be changed
+    after this call.</para>
+
+    <para>The
+    <function>sd_bus_message_append_string_space</function> function appends
+    space for a string to message <parameter>m</parameter>. It behaves
+    similar to <function>sd_bus_message_append_basic</function> with
+    type <literal>s</literal>, but instead of copying a string into
+    the message, it returns a pointer to the destination area to
+    the caller in pointer <parameter>p</parameter>. Space for the string
+    of length <parameter>size</parameter> plus the terminating
+    <constant>NUL</constant> is allocated.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>Return Value</title>
+
+    <para>On success, those calls return 0 or a positive integer. On
+    failure, they returns a negative errno-style error code.</para>
+  </refsect1>
+
+  <xi:include href="sd_bus_message_append_basic.xml" xpointer="errors" />
+
+  <refsect1>
+    <title>Notes</title>
+
+    <para>The functions described here are available as a shared library,
+    which can be compiled and linked to with the
+    <constant>libsystemd</constant> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+    file.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>See Also</title>
+
+    <para>
+      <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd-bus</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd_bus_message_append_basic</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <ulink url="http://dbus.freedesktop.org/doc/dbus-specification.html">The D-Bus specification</ulink>
+    </para>
+  </refsect1>
+
+</refentry>
diff --git a/man/sd_bus_message_append_strv.xml b/man/sd_bus_message_append_strv.xml
new file mode 100644 (file)
index 0000000..898a7c4
--- /dev/null
@@ -0,0 +1,116 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+This file is part of systemd.
+
+Copyright 2014 Zbigniew Jędrzejewski-Szmek
+
+systemd is free software; you can redistribute it and/or modify it
+under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+systemd is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd_bus_message_append_strv" conditional="ENABLE_KDBUS"
+          xmlns:xi="http://www.w3.org/2001/XInclude">
+
+  <refentryinfo>
+    <title>sd_bus_message_append_strv</title>
+    <productname>systemd</productname>
+
+    <authorgroup>
+      <author>
+        <contrib>A monkey with a typewriter</contrib>
+        <firstname>Zbigniew</firstname>
+        <surname>Jędrzejewski-Szmek</surname>
+        <email>zbyszek@in.waw.pl</email>
+      </author>
+    </authorgroup>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>sd_bus_message_append_strv</refentrytitle>
+    <manvolnum>3</manvolnum>
+  </refmeta>
+
+  <refnamediv>
+    <refname>sd_bus_message_append_strv</refname>
+
+    <refpurpose>Attach an array of strings to a message</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcsynopsisinfo>#include &lt;systemd/sd-bus.h&gt;</funcsynopsisinfo>
+
+      <funcprototype>
+        <funcdef>int sd_bus_message_append_strv</funcdef>
+        <paramdef>sd_bus_message *<parameter>m</parameter></paramdef>
+        <paramdef>char **<parameter>l</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>The <function>sd_bus_message_append</function> function can be
+    used to append an array of strings to message
+    <parameter>m</parameter>. The parameter <parameter>l</parameter>
+    shall point to a <constant>NULL</constant>-terminated array of pointers
+    to <constant>NUL</constant>-terminated strings. Each string must
+    satisfy the same constraints as described for the
+    <literal>s</literal> type in
+    <citerefentry><refentrytitle>sd_bus_message_append_basic</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
+    </para>
+
+    <para>The memory pointed at by <parameter>p</parameter> and the
+    contents of the strings themselves are copied into the memory area
+    containing the message and may be changed after this call. Note
+    that the signature of <parameter>l</parameter> parameter is to be
+    treated as <type>const char *const *</type>, and the contents
+    will not be modified.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>Return Value</title>
+
+    <para>On success, this call returns 0 or a positive integer. On
+    failure, a negative errno-style error code is returned.</para>
+  </refsect1>
+
+  <xi:include href="sd_bus_message_append_basic.xml" xpointer="errors" />
+
+  <refsect1>
+    <title>Notes</title>
+
+    <para>The <function>sd_bus_append_append_strv()</function> function
+    described here is available as a shared library, which can be
+    compiled and linked to with the
+    <constant>libsystemd</constant> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+    file.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>See Also</title>
+
+    <para>
+      <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd-bus</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd_bus_message_append</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd_bus_message_append_array</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <ulink url="http://dbus.freedesktop.org/doc/dbus-specification.html">The D-Bus specification</ulink>
+    </para>
+  </refsect1>
+
+</refentry>
index 5e25263..641ecec 100644 (file)
 
                         <funcprototype>
                                 <funcdef>int <function>sd_bus_message_get_cookie</function></funcdef>
-                                <paramdef>sd_bus_message<parameter>message</parameter></paramdef>
-                                <paramdef>uint64_t<parameter>cookie</parameter></paramdef>
+                                <paramdef>sd_bus_message *<parameter>message</parameter></paramdef>
+                                <paramdef>uint64_t *<parameter>cookie</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_bus_message_get_reply_cookie</function></funcdef>
-                                <paramdef>sd_bus_message<parameter>message</parameter></paramdef>
-                                <paramdef>uint64_t<parameter>cookie</parameter></paramdef>
+                                <paramdef>sd_bus_message *<parameter>message</parameter></paramdef>
+                                <paramdef>uint64_t *<parameter>cookie</parameter></paramdef>
                         </funcprototype>
                 </funcsynopsis>
         </refsynopsisdiv>
                 and <function>sd_bus_message_get_reply_cookie()</function>
                 interfaces are available as a shared library, which can
                 be compiled and linked to with the
-                <constant>libsystemd</constant> <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                <constant>libsystemd</constant> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 file.</para>
         </refsect1>
 
index 683931c..311ba55 100644 (file)
 
                 <para><function>sd_bus_message_get_seqnum()</function>
                 returns the kernel-assigned sequence number of the
-                message. The kernel assigns a global monotonically increasing
-                sequence number to all messages sent on the local
-                system. This sequence number is useful for determining
+                message. The kernel assigns a global, monotonically
+                increasing sequence number to all messages transmitted
+                on the local system, at the time the message was
+                sent. This sequence number is useful for determining
                 message send order, even across different busses of
                 the local system. The sequence number combined with
                 the boot ID of the system (as returned by
                 is a suitable globally unique identifier for bus
                 messages.</para>
 
+                <para>Note that the sending order and receiving order
+                of messages might differ, in particular for broadcast
+                messages. This means that the sequence number and the
+                timestamps of messages a client reads are not
+                necessarily monotonically increasing.</para>
+
                 <para>These timestamps and the sequence number are
                 attached to each message by the kernel and cannot be
                 manipulated by the sender.</para>
                 and <function>sd_bus_message_get_seqnum()</function>
                 interfaces are available as a shared library, which
                 can be compiled and linked to with the
-                <constant>libsystemd</constant> <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                <constant>libsystemd</constant> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 file.</para>
         </refsect1>
 
diff --git a/man/sd_bus_negotiate_fds.xml b/man/sd_bus_negotiate_fds.xml
new file mode 100644 (file)
index 0000000..c91318c
--- /dev/null
@@ -0,0 +1,176 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+This file is part of systemd.
+
+Copyright 2014 Lennart Poettering
+
+systemd is free software; you can redistribute it and/or modify it
+under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+systemd is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd_bus_negotiate_fds" conditional="ENABLE_KDBUS">
+
+  <refentryinfo>
+    <title>sd_bus_negotiate_fds</title>
+    <productname>systemd</productname>
+
+    <authorgroup>
+      <author>
+        <contrib>Developer</contrib>
+        <firstname>Lennart</firstname>
+        <surname>Poettering</surname>
+        <email>lennart@poettering.net</email>
+      </author>
+    </authorgroup>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>sd_bus_negotiate_fds</refentrytitle>
+    <manvolnum>3</manvolnum>
+  </refmeta>
+
+  <refnamediv>
+    <refname>sd_bus_negotiate_fds</refname>
+    <refname>sd_bus_negotiate_timestamps</refname>
+    <refname>sd_bus_negotiate_creds</refname>
+
+    <refpurpose>Control feature negotiation on bus connections</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcsynopsisinfo>#include &lt;systemd/sd-bus.h&gt;</funcsynopsisinfo>
+
+      <funcprototype>
+        <funcdef>int <function>sd_bus_negotiate_fds</function></funcdef>
+        <paramdef>sd_bus *<parameter>bus</parameter></paramdef>
+        <paramdef>int <parameter>b</parameter></paramdef>
+      </funcprototype>
+
+      <funcprototype>
+        <funcdef>int <function>sd_bus_negotiate_timestamp</function></funcdef>
+        <paramdef>sd_bus *<parameter>bus</parameter></paramdef>
+        <paramdef>int <parameter>b</parameter></paramdef>
+      </funcprototype>
+
+      <funcprototype>
+        <funcdef>int <function>sd_bus_negotiate_creds</function></funcdef>
+        <paramdef>sd_bus *<parameter>bus</parameter></paramdef>
+        <paramdef>int <parameter>b</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para><function>sd_bus_negotiate_fds()</function> controls whether
+    file descriptor passing shall be negotiated for the specified bus
+    connection. It takes a bus object and a boolean, which, when true,
+    enables file descriptor passing, and, when false, disables it. Note
+    that not all transports and servers support file descriptor
+    passing. To find out whether file descriptor passing is available
+    after negotiation, use
+    <citerefentry><refentrytitle>sd_bus_can_send</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+    and pass <constant>SD_BUS_TYPE_UNIX_FD</constant>. Note that file
+    descriptor passing is always enabled for both sending and
+    receiving or for neither, but never only in one direction. By
+    default, file descriptor passing is negotiated for all
+    connections.</para>
+
+    <para>Note that when bus activation is used, it is highly
+    recommended to set the <option>AcceptFileDescriptors=</option>
+    setting in the <filename>.busname</filename> unit file to the same
+    setting as negotiated by the program ultimately activated. By
+    default, file descriptor passing is enabled for both.</para>
+
+    <para><function>sd_bus_negotiate_timestamps()</function> controls
+    whether implicit sender timestamps shall be attached automatically
+    to all incoming messages. Takes a bus object and a boolean, which,
+    when true, enables timestamping, and, when false, disables it. If
+    this is disabled,
+    <citerefentry><refentrytitle>sd_bus_message_get_monotonic_usec</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+    <citerefentry><refentrytitle>sd_bus_message_get_realtime_usec</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+    <citerefentry><refentrytitle>sd_bus_message_get_seqno</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+    fail with <constant>-ENODATA</constant> on incoming messages. Note
+    that not all transports support timestamping of messages. On local
+    transports, the timestamping is applied by the kernel and cannot be
+    manipulated by userspace.</para>
+
+    <para><function>sd_bus_negotiate_creds()</function> controls
+    whether implicit sender credentials shall be attached
+    automatically to all incoming messages. Takes a bus object and a
+    bit mask value, which controls which credential parameters are
+    attached. If this is not used,
+    <citerefentry><refentrytitle>sd_bus_message_get_creds</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+    fails with <constant>-ENODATA</constant> on incoming
+    messages. Note that not all transports support attaching sender
+    credentials to messages, or do not support all types of sender
+    credential parameters. On local transports, the sender credentials
+    are attached by the kernel and cannot be manipulated by
+    userspace. By default, no sender credentials are attached.</para>
+
+    <para>These functions may be called only before the connection has
+    been started with
+    <citerefentry><refentrytitle>sd_bus_start</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>Return Value</title>
+
+    <para>On success, these functions returns 0 or a
+    positive integer. On failure, they return a negative errno-style
+    error code.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>Errors</title>
+
+    <para>Returned errors may indicate the following problems:</para>
+
+    <variablelist>
+      <varlistentry>
+        <term><varname>-EPERM</varname></term>
+
+        <listitem><para>The bus connection has already been started.</para></listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Notes</title>
+
+    <para><function>sd_bus_negotiate_fs()</function> and the other
+    functions described here are available as a shared library, which
+    can be compiled and linked to with the
+    <constant>libsystemd</constant> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+    file.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>See Also</title>
+
+    <para>
+      <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd-bus</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd_bus_start</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd_bus_message_can_send</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd_bus_message_get_monotonic_usec</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd_bus_message_get_creds</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+    </para>
+  </refsect1>
+
+</refentry>
index b36d66c..1f8d787 100644 (file)
@@ -125,7 +125,7 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
     <para><function>sd_bus_new()</function> and other functions
     described here are available as a shared library, which can be
     compiled and linked to with the
-    <constant>libsystemd</constant> <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+    <constant>libsystemd</constant> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
     file.</para>
   </refsect1>
 
index 7fa1be6..6cb4a31 100644 (file)
@@ -96,13 +96,13 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
     <title>Description</title>
 
     <para><function>sd_bus_open_user()</function> creates a new bus
-    object and opens a connection to the the user bus.
+    object and opens a connection to the user bus.
     <function>sd_bus_open_system()</function> does the same, but
     connects to the system bus.</para>
 
     <para>If the <varname>$DBUS_SESSION_BUS_ADDRESS</varname> environment
     variable is set
-    (c.f. <citerefentry><refentrytitle>environ</refentrytitle><manvolnum>7</manvolnum></citerefentry>),
+    (cf. <citerefentry project='man-pages'><refentrytitle>environ</refentrytitle><manvolnum>7</manvolnum></citerefentry>),
     it will be used as the address of the user bus. This variable can
     contain multiple addresses separated by <literal>;</literal>. If
     this variable is not set, a suitable default for the default user
@@ -195,7 +195,7 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
     <para><function>sd_bus_open_user()</function> and other functions
     described here are available as a shared library, which can be
     compiled and linked to with the
-    <constant>libsystemd</constant> <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+    <constant>libsystemd</constant> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
     file.</para>
   </refsect1>
 
diff --git a/man/sd_bus_path_encode.xml b/man/sd_bus_path_encode.xml
new file mode 100644 (file)
index 0000000..c96b0ac
--- /dev/null
@@ -0,0 +1,150 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+This file is part of systemd.
+
+Copyright 2014 Zbigniew Jędrzejewski-Szmek
+
+systemd is free software; you can redistribute it and/or modify it
+under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+systemd is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd_bus_path_encode" conditional="ENABLE_KDBUS">
+
+  <refentryinfo>
+    <title>sd_bus_path_encode</title>
+    <productname>systemd</productname>
+
+    <authorgroup>
+      <author>
+        <contrib>A monkey with a typewriter</contrib>
+        <firstname>Zbigniew</firstname>
+        <surname>Jędrzejewski-Szmek</surname>
+        <email>zbyszek@in.waw.pl</email>
+      </author>
+    </authorgroup>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>sd_bus_path_encode</refentrytitle>
+    <manvolnum>3</manvolnum>
+  </refmeta>
+
+  <refnamediv>
+    <refname>sd_bus_path_encode</refname>
+    <refname>sd_bus_path_decode</refname>
+
+    <refpurpose>Convert an external identifier into an object path and back</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcsynopsisinfo>#include &lt;systemd/sd-bus.h&gt;</funcsynopsisinfo>
+
+      <funcprototype>
+        <funcdef>int <function>sd_bus_path_encode</function></funcdef>
+        <paramdef>const char *<parameter>prefix</parameter></paramdef>
+        <paramdef>const char *<parameter>external_id</parameter></paramdef>
+        <paramdef>char **<parameter>ret_path</parameter></paramdef>
+      </funcprototype>
+
+      <funcprototype>
+        <funcdef>int <function>sd_bus_path_decode</function></funcdef>
+        <paramdef>const char *<parameter>prefix</parameter></paramdef>
+        <paramdef>const char *<parameter>path</parameter></paramdef>
+        <paramdef>char **<parameter>ret_external_id</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para><function>sd_bus_path_encode()</function> and
+    <function>sd_bus_path_decode()</function> convert external
+    identifier strings into object paths and back. These functions are
+    useful to map application-specific string identifiers of any kind
+    into bus object paths in a simple, reversible and safe way.</para>
+
+    <para><function>sd_bus_path_encode()</function> takes a bus path
+    prefix and an external identifier string as arguments, plus a
+    place to store the returned bus path string. The bus path prefix
+    must be a valid bus path, starting with a slash
+    <literal>/</literal>, and not ending in one. The external
+    identifier string may be in any format, may be the empty string,
+    and has no restrictions on the charset — however, it must
+    always be <constant>NUL</constant>-terminated. The returned string
+    will be the concatenation of the bus path prefix plus an escaped
+    version of the external identifier string. This operation may be
+    reversed with <function>sd_bus_decode()</function>. It is
+    recommended to only use external identifiers that generally
+    require little escaping to be turned into valid bus path
+    identifiers (for example, by sticking to a 7-bit ASCII character
+    set), in order to ensure the resulting bus path is still short and
+    easily processed.</para>
+
+    <para><function>sd_bus_path_decode()</function> reverses the
+    operation of <function>sd_bus_path_encode()</function> and thus
+    regenerates an external identifier string from a bus path. It
+    takes a bus path and a prefix string, plus a place to store the
+    returned external identifier string. If the bus path does not
+    start with the specified prefix, 0 is returned and the returned
+    string is set to <constant>NULL</constant>. Otherwise, the
+    string following the prefix is unescaped and returned in the
+    external identifier string.</para>
+
+    <para>The escaping used will replace all characters which are
+    invalid in a bus object path by <literal>_</literal>, followed by a
+    hexadecimal value. As a special case, the empty string will be
+    replaced by a lone <literal>_</literal>.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>Return Value</title>
+
+    <para>On success, <function>sd_bus_path_encode()</function>
+    returns positive or 0, and a valid bus path in the return
+    argument. On success, <function>sd_bus_path_decode()</function>
+    returns a positive value if the prefixed matched, or 0 if it
+    did not. If the prefix matched, the external identifier is returned
+    in the return parameter. If it did not match, NULL is returned in
+    the return parameter. On failure, a negative errno-style error
+    number is returned by either function. The returned strings must
+    be
+    <citerefentry project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>'d
+    by the caller.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>Notes</title>
+
+    <para><function>sd_bus_path_encode()</function> and
+    <function>sd_bus_path_decode()</function> are available as a
+    shared library, which can be compiled and linked to with the
+    <constant>libsystemd</constant> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+    file.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>See Also</title>
+
+    <para>
+      <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd-bus</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+    </para>
+  </refsect1>
+
+</refentry>
index 9003f9f..c23bbb3 100644 (file)
 
                         <funcprototype>
                                 <funcdef>int <function>sd_bus_request_name</function></funcdef>
-                                <paramdef>sd_bus<parameter>bus</parameter></paramdef>
+                                <paramdef>sd_bus *<parameter>bus</parameter></paramdef>
                                 <paramdef>const char *<parameter>name</parameter></paramdef>
                                 <paramdef>uint64_t <parameter>flags</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_bus_release_name</function></funcdef>
-                                <paramdef>sd_bus<parameter>bus</parameter></paramdef>
+                                <paramdef>sd_bus *<parameter>bus</parameter></paramdef>
                                 <paramdef>const char *<parameter>name</parameter></paramdef>
                         </funcprototype>
                 </funcsynopsis>
                 and <function>sd_bus_release_name()</function>
                 interfaces are available as a shared library, which can
                 be compiled and linked to with the
-                <constant>libsystemd</constant> <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                <constant>libsystemd</constant> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 file.</para>
         </refsect1>
 
diff --git a/man/sd_event_add_time.xml b/man/sd_event_add_time.xml
new file mode 100644 (file)
index 0000000..a3304f7
--- /dev/null
@@ -0,0 +1,245 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+This file is part of systemd.
+
+Copyright 2014 Lennart Poettering
+
+systemd is free software; you can redistribute it and/or modify it
+under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+systemd is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd_event_add_time" conditional="ENABLE_KDBUS">
+
+  <refentryinfo>
+    <title>sd_event_add_time</title>
+    <productname>systemd</productname>
+
+    <authorgroup>
+      <author>
+        <contrib>Developer</contrib>
+        <firstname>Lennart</firstname>
+        <surname>Poettering</surname>
+        <email>lennart@poettering.net</email>
+      </author>
+    </authorgroup>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>sd_event_add_time</refentrytitle>
+    <manvolnum>3</manvolnum>
+  </refmeta>
+
+  <refnamediv>
+    <refname>sd_event_add_time</refname>
+    <refname>sd_event_source_get_time</refname>
+    <refname>sd_event_source_set_time</refname>
+    <refname>sd_event_source_get_time_accuracy</refname>
+    <refname>sd_event_source_set_time_accuracy</refname>
+    <refname>sd_event_source_get_time_clock</refname>
+
+    <refpurpose>Add a timer event source to an event loop</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcsynopsisinfo>#include &lt;systemd/sd-bus.h&gt;</funcsynopsisinfo>
+
+      <funcprototype>
+        <funcdef>int <function>sd_event_add_time</function></funcdef>
+        <paramdef>sd_event *<parameter>event</parameter></paramdef>
+        <paramdef>sd_event_source **<parameter>source</parameter></paramdef>
+        <paramdef>clockid_t <parameter>clock</parameter></paramdef>
+        <paramdef>uint64_t <parameter>usec</parameter></paramdef>
+        <paramdef>uint64_t <parameter>accuracy</parameter></paramdef>
+        <paramdef>sd_event_time_handler_t <parameter>handler</parameter></paramdef>
+        <paramdef>void *<parameter>userdata</parameter></paramdef>
+      </funcprototype>
+
+      <funcprototype>
+        <funcdef>int <function>sd_event_source_get_time</function></funcdef>
+        <paramdef>sd_event_source *<parameter>source</parameter></paramdef>
+        <paramdef>usec_t *<parameter>usec</parameter></paramdef>
+      </funcprototype>
+
+      <funcprototype>
+        <funcdef>int <function>sd_event_source_set_time</function></funcdef>
+        <paramdef>sd_event_source *<parameter>source</parameter></paramdef>
+        <paramdef>usec_t <parameter>usec</parameter></paramdef>
+      </funcprototype>
+
+      <funcprototype>
+        <funcdef>int <function>sd_event_source_get_time_accuracy</function></funcdef>
+        <paramdef>sd_event_source *<parameter>source</parameter></paramdef>
+        <paramdef>usec_t *<parameter>usec</parameter></paramdef>
+      </funcprototype>
+
+      <funcprototype>
+        <funcdef>int <function>sd_event_source_set_time_accuracy</function></funcdef>
+        <paramdef>sd_event_source *<parameter>source</parameter></paramdef>
+        <paramdef>usec_t <parameter>usec</parameter></paramdef>
+      </funcprototype>
+
+      <funcprototype>
+        <funcdef>int <function>sd_event_source_get_time_clock</function></funcdef>
+        <paramdef>sd_event_source *<parameter>source</parameter></paramdef>
+        <paramdef>clockid_t *<parameter>clock</parameter></paramdef>
+      </funcprototype>
+
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para><function>sd_event_add_time()</function> adds a new timer
+    event source to an event loop object. The event loop is specified
+    in <parameter>event</parameter>, the event source is returned in
+    the <parameter>source</parameter> parameter. The
+    <parameter>clock</parameter> parameter takes a clock identifier,
+    one of <constant>CLOCK_REALTIME</constant>,
+    <constant>CLOCK_MONOTONIC</constant> and
+    <constant>CLOCK_BOOTTIME_ALARM</constant>. See
+    <citerefentry><refentrytitle>timerfd_create</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+    for details regarding the various types of clocks. The
+    <parameter>usec</parameter> parameter takes a time value in
+    microseconds, relative to the clock's epoch specifying when the
+    timer shall elapse the earliest. The
+    <parameter>accuracy</parameter> parameter takes an additional
+    accuracy value in microseconds specifying a time the timer event
+    may be delayed. Specify 0 for selecting the default accuracy
+    (250ms). Specify 1 for most accurate timers. Consider specifying
+    60000000 or larger (1h) for long-running events that may be
+    delayed substantially. Picking higher accuracy values allows the
+    system to coalesce timer events more aggressively, thus improving
+    power efficiency. The <parameter>handler</parameter> shall
+    reference a function to call when the timer elapses. The handler
+    function will be passed the <parameter>userdata</parameter>
+    pointer, which may be chosen freely by the caller. The handler is
+    also passed the configured time it was triggered, however it might
+    actually have been called at a slightly later time, subject to the
+    specified accuracy value, the kernel timer slack (see
+    <citerefentry><refentrytitle>prctl</refentrytitle><manvolnum>2</manvolnum></citerefentry>)
+    and additional scheduling latencies. By default, the timer will
+    elapse once (SD_EVENT_ONESHOT), but this may be changed with
+    <citerefentry><refentrytitle>sd_event_source_set_enabled</refentrytitle><manvolnum>3</manvolnum></citerefentry>. If
+    the handler function returns a negative error code, it will be
+    disabled after the invocation, even if SD_EVENT_ON mode is set.
+    </para>
+
+    <para><function>sd_event_source_get_time()</function> retrieves
+    the configured time value of a timer event source created
+    previously with <function>sd_event_add_time()</function>. It takes
+    the event source object and a pointer to a variable to store the
+    time in microseconds in.</para>
+
+    <para><function>sd_event_source_set_time()</function> changes the
+    configured time value of a timer event source created previously
+    with <function>sd_event_add_time()</function>. It takes the event
+    source object and a time relative to the selected clock's
+    epoch, in microseconds.</para>
+
+    <para><function>sd_event_source_get_time_accuracy()</function>
+    retrieves the configured accuracy value of a timer event source
+    created previously with <function>sd_event_add_time()</function>. It
+    takes the event source object and a pointer to a variable to store
+    the accuracy in microseconds in.</para>
+
+    <para><function>sd_event_source_set_time_accuracy()</function>
+    changes the configured accuracy of a timer event source created
+    previously with <function>sd_event_add_time()</function>. It takes
+    the event source object and an accuracy, in microseconds.</para>
+
+    <para><function>sd_event_source_get_time_clock()</function>
+    retrieves the configured clock of a timer event source created
+    previously with <function>sd_event_add_time()</function>. It takes
+    the event source object and a pointer to a variable to store the
+    clock identifier in.</para>
+
+  </refsect1>
+
+  <refsect1>
+    <title>Return Value</title>
+
+    <para>On success, these functions return 0 or a positive
+    integer. On failure, they return a negative errno-style error
+    code. </para>
+  </refsect1>
+
+  <refsect1>
+    <title>Errors</title>
+
+    <para>Returned errors may indicate the following problems:</para>
+
+    <variablelist>
+      <varlistentry>
+        <term><varname>-ENOMEM</varname></term>
+
+        <listitem><para>Not enough memory to allocate object.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>-EINVAL</varname></term>
+
+        <listitem><para>An invalid argument has been passed.</para></listitem>
+
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>-ESTALE</varname></term>
+
+        <listitem><para>The event loop is already terminated.</para></listitem>
+
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>-ECHILD</varname></term>
+
+        <listitem><para>The event loop has been created in a different process.</para></listitem>
+
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>-ENOTSUP</varname></term>
+
+        <listitem><para>The selected clock is not supported by the event loop implementation.</para></listitem>
+
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Notes</title>
+
+    <para><function>sd_event_add_time()</function> and the other functions
+    described here are available as a shared library, which can be
+    compiled and linked to with the
+    <constant>libsystemd</constant> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+    file.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>See Also</title>
+
+    <para>
+      <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd-event</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd_event_new</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>clock_gettime</refentrytitle><manvolnum>2</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd_event_source_set_enabled</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+    </para>
+  </refsect1>
+
+</refentry>
diff --git a/man/sd_event_new.xml b/man/sd_event_new.xml
new file mode 100644 (file)
index 0000000..bd495b6
--- /dev/null
@@ -0,0 +1,181 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+This file is part of systemd.
+
+Copyright 2014 Lennart Poettering
+
+systemd is free software; you can redistribute it and/or modify it
+under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+systemd is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="sd_event_new" conditional="ENABLE_KDBUS">
+
+  <refentryinfo>
+    <title>sd_event_new</title>
+    <productname>systemd</productname>
+
+    <authorgroup>
+      <author>
+        <contrib>Developer</contrib>
+        <firstname>Lennart</firstname>
+        <surname>Poettering</surname>
+        <email>lennart@poettering.net</email>
+      </author>
+    </authorgroup>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>sd_event_new</refentrytitle>
+    <manvolnum>3</manvolnum>
+  </refmeta>
+
+  <refnamediv>
+    <refname>sd_event_new</refname>
+    <refname>sd_event_default</refname>
+    <refname>sd_event_ref</refname>
+    <refname>sd_event_unref</refname>
+
+    <refpurpose>Acquire and release an event loop object</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcsynopsisinfo>#include &lt;systemd/sd-bus.h&gt;</funcsynopsisinfo>
+
+      <funcprototype>
+        <funcdef>int <function>sd_event_new</function></funcdef>
+        <paramdef>sd_bus **<parameter>event</parameter></paramdef>
+      </funcprototype>
+
+      <funcprototype>
+        <funcdef>int <function>sd_event_default</function></funcdef>
+        <paramdef>sd_bus **<parameter>event</parameter></paramdef>
+      </funcprototype>
+
+      <funcprototype>
+        <funcdef>sd_bus *<function>sd_event_ref</function></funcdef>
+        <paramdef>sd_bus *<parameter>event</parameter></paramdef>
+      </funcprototype>
+
+      <funcprototype>
+        <funcdef>sd_bus *<function>sd_event_unref</function></funcdef>
+        <paramdef>sd_bus *<parameter>event</parameter></paramdef>
+      </funcprototype>
+
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para><function>sd_event_new()</function> allocates a new event
+    loop object. The event loop object is returned in the
+    <parameter>event</parameter> parameter. After use, drop
+    the returned reference with
+    <function>sd_event_unref()</function>. When the last reference is
+    dropped, the event loop is freed.</para>
+
+    <para><function>sd_event_default()</function> acquires a reference
+    to the default event loop object of the calling thread, possibly
+    allocating a new object if no default event loop object has been
+    allocated yet for the thread. After use, drop the returned
+    reference with <function>sd_event_unref()</function>. When the
+    last reference is dropped, the event loop is freed. If this
+    function is called while the object returned from a previous call
+    from the same thread is still referenced, the same object is
+    returned again, but the reference is increased by one. It is
+    recommended to use this call instead of
+    <function>sd_event_new()</function> in order to share event loop
+    objects between various components that are dispatched in the same
+    thread. All threads either have exactly zero or one default event loop
+    associated, but never more.</para>
+
+    <para><function>sd_event_ref()</function> increases the reference
+    counter of the specified event loop object by one.</para>
+
+    <para><function>sd_event_unref()</function> decreases the
+    reference counter of the specified event loop object by one. If
+    the counter hits zero, the event loop object is freed. Note that it
+    is freed regardless of whether it is the default event loop object for a
+    thread or not. This means that allocating an event loop with
+    <function>sd_event_default()</function>, then releasing it, and
+    then acquiring a new one with
+    <function>sd_event_default()</function> will result in two
+    distinct objects. Note that, in order to free an event loop object,
+    all remaining event sources of the event loop also need to be
+    freed as they each keep a reference to it.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>Return Value</title>
+
+    <para>On success, <function>sd_event_new()</function> and
+    <function>sd_event_default()</function> return 0 or a positive
+    integer. On failure, they return a negative errno-style error
+    code. <function>sd_event_ref()</function> always returns a pointer
+    to the event loop object passed
+    in. <function>sd_event_unref()</function> always returns
+    NULL.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>Errors</title>
+
+    <para>Returned errors may indicate the following problems:</para>
+
+    <variablelist>
+      <varlistentry>
+        <term><varname>-ENOMEM</varname></term>
+
+        <listitem><para>Not enough memory to allocate object</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>-EMFILE</varname></term>
+
+        <listitem><para>The maximum number of event loops has been allocated.</para></listitem>
+
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Notes</title>
+
+    <para><function>sd_event_new()</function> and the other functions
+    described here are available as a shared library, which can be
+    compiled and linked to with the
+    <constant>libsystemd</constant> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+    file.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>See Also</title>
+
+    <para>
+      <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd-event</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd_event_add_io</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd_event_add_time</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd_event_add_signal</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd_event_add_child</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd_event_add_defer</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd_event_add_post</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd_event_add_exit</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+    </para>
+  </refsect1>
+
+</refentry>
index 0fc8243..76527c3 100644 (file)
 
                         <funcprototype>
                                 <funcdef>int <function>sd_get_seats</function></funcdef>
-                                <paramdef>char*** <parameter>seats</parameter></paramdef>
+                                <paramdef>char ***<parameter>seats</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_get_sessions</function></funcdef>
-                                <paramdef>char*** <parameter>sessions</parameter></paramdef>
+                                <paramdef>char ***<parameter>sessions</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_get_uids</function></funcdef>
-                                <paramdef>uid_t** <parameter>users</parameter></paramdef>
+                                <paramdef>uid_t **<parameter>users</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_get_machine_names</function></funcdef>
-                                <paramdef>char*** <parameter>machines</parameter></paramdef>
+                                <paramdef>char ***<parameter>machines</parameter></paramdef>
                         </funcprototype>
 
                 </funcsynopsis>
@@ -85,7 +85,7 @@
                 seats. Returns a <constant>NULL</constant> terminated array of seat
                 identifiers. The returned array and all strings it
                 references need to be freed with the libc
-                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                <citerefentry project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                 call after use. Note that instead of an empty array
                 <constant>NULL</constant> may be returned and should be considered
                 equivalent to an empty array.</para>
                 <function>sd_get_machine_names()</function> interfaces
                 are available as a shared library, which can be compiled
                 and linked to with the
-                <constant>libsystemd</constant> <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                <constant>libsystemd</constant> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 file.</para>
         </refsect1>
 
index cce3979..b3bf529 100644 (file)
 
                         <funcprototype>
                                 <funcdef>int <function>sd_id128_get_machine</function></funcdef>
-                                <paramdef>sd_id128_t<parameter>ret</parameter></paramdef>
+                                <paramdef>sd_id128_t *<parameter>ret</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_id128_get_boot</function></funcdef>
-                                <paramdef>sd_id128_t<parameter>ret</parameter></paramdef>
+                                <paramdef>sd_id128_t *<parameter>ret</parameter></paramdef>
                         </funcprototype>
 
                 </funcsynopsis>
@@ -83,7 +83,7 @@
                 file exposed by the kernel. It is randomly generated
                 early at boot and is unique for every running kernel
                 instance. See
-                <citerefentry><refentrytitle>random</refentrytitle><manvolnum>4</manvolnum></citerefentry>
+                <citerefentry project='man-pages'><refentrytitle>random</refentrytitle><manvolnum>4</manvolnum></citerefentry>
                 for more information. This function also internally
                 caches the returned ID to make this call a cheap
                 operation.</para>
                 and <function>sd_id128_get_boot()</function>
                 interfaces are available as a shared library, which can
                 be compiled and linked to with the
-                <literal>libsystemd</literal> <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                <literal>libsystemd</literal> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 file.</para>
         </refsect1>
 
index 7e8c646..8c01ce8 100644 (file)
@@ -53,7 +53,7 @@
 
                         <funcprototype>
                                 <funcdef>int <function>sd_id128_randomize</function></funcdef>
-                                <paramdef>sd_id128_t<parameter>ret</parameter></paramdef>
+                                <paramdef>sd_id128_t *<parameter>ret</parameter></paramdef>
                         </funcprototype>
 
                 </funcsynopsis>
@@ -97,7 +97,7 @@
                 <para>The <function>sd_id128_randomize()</function> interface
                 is available as a shared library, which can be compiled
                 and linked to with the
-                <literal>libsystemd</literal> <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                <literal>libsystemd</literal> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 file.</para>
         </refsect1>
 
index 72a67dc..62badda 100644 (file)
                         <funcsynopsisinfo>#include &lt;systemd/sd-id128.h&gt;</funcsynopsisinfo>
 
                         <funcprototype>
-                                <funcdef>char<function>sd_id128_to_string</function></funcdef>
+                                <funcdef>char *<function>sd_id128_to_string</function></funcdef>
                                 <paramdef>sd_id128_t <parameter>id</parameter>, char <parameter>s</parameter>[33]</paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_id128_from_string</function></funcdef>
-                                <paramdef>const char* <parameter>s</parameter>, sd_id128_t* <parameter>ret</parameter></paramdef>
+                                <paramdef>const char *<parameter>s</parameter>, sd_id128_t *<parameter>ret</parameter></paramdef>
                         </funcprototype>
 
                 </funcsynopsis>
@@ -94,7 +94,7 @@
 
                 <para>When formatting a 128-bit ID into a string, it is
                 often easier to use a format string for
-                <citerefentry><refentrytitle>printf</refentrytitle><manvolnum>3</manvolnum></citerefentry>. This
+                <citerefentry project='man-pages'><refentrytitle>printf</refentrytitle><manvolnum>3</manvolnum></citerefentry>. This
                 is easily done using the
                 <function>SD_ID128_FORMAT_STR</function> and
                 <function>SD_ID128_FORMAT_VAL()</function> macros. For
                 <para>The <function>sd_id128_to_string()</function>
                 and <function>sd_id128_from_string()</function> interfaces are
                 available as a shared library, which can be compiled and
-                linked to with the <literal>libsystemd</literal> <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                linked to with the <literal>libsystemd</literal> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 file.</para>
         </refsect1>
 
                 <para>
                         <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>sd-id128</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>printf</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                        <citerefentry project='man-pages'><refentrytitle>printf</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                 </para>
         </refsect1>
 
index bb851d1..17ecca8 100644 (file)
@@ -85,7 +85,7 @@
                                 <paramdef>int <parameter>fd</parameter></paramdef>
                                 <paramdef>int <parameter>type</parameter></paramdef>
                                 <paramdef>int <parameter>listening</parameter></paramdef>
-                                <paramdef>const char<parameter>path</parameter></paramdef>
+                                <paramdef>const char *<parameter>path</parameter></paramdef>
                                 <paramdef>size_t <parameter>length</parameter></paramdef>
                         </funcprototype>
 
index d776b14..21a5ab1 100644 (file)
 
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_add_match</function></funcdef>
-                                <paramdef>sd_journal<parameter>j</parameter></paramdef>
-                                <paramdef>const void<parameter>data</parameter></paramdef>
+                                <paramdef>sd_journal *<parameter>j</parameter></paramdef>
+                                <paramdef>const void *<parameter>data</parameter></paramdef>
                                 <paramdef>size_t <parameter>size</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_add_disjunction</function></funcdef>
-                                <paramdef>sd_journal<parameter>j</parameter></paramdef>
+                                <paramdef>sd_journal *<parameter>j</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_add_conjunction</function></funcdef>
-                                <paramdef>sd_journal<parameter>j</parameter></paramdef>
+                                <paramdef>sd_journal *<parameter>j</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>void <function>sd_journal_flush_matches</function></funcdef>
-                                <paramdef>sd_journal<parameter>j</parameter></paramdef>
+                                <paramdef>sd_journal *<parameter>j</parameter></paramdef>
                         </funcprototype>
                 </funcsynopsis>
         </refsynopsisdiv>
                 <function>sd_journal_flush_matches()</function>
                 interfaces are available as a shared library, which can
                 be compiled and linked to with the
-                <constant>libsystemd</constant> <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                <constant>libsystemd</constant> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 file.</para>
         </refsect1>
 
index 2495648..485bbba 100644 (file)
 
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_get_catalog</function></funcdef>
-                                <paramdef>sd_journal<parameter>j</parameter></paramdef>
-                                <paramdef>char** <parameter>ret</parameter></paramdef>
+                                <paramdef>sd_journal *<parameter>j</parameter></paramdef>
+                                <paramdef>char **<parameter>ret</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_get_catalog_for_message_id</function></funcdef>
                                 <paramdef>sd_id128_t <parameter>id</parameter></paramdef>
-                                <paramdef>char** <parameter>ret</parameter></paramdef>
+                                <paramdef>char **<parameter>ret</parameter></paramdef>
                         </funcprototype>
 
 
 
                 <para>On successful return, <parameter>ret</parameter>
                 points to a new string, which must be freed with
-                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
+                <citerefentry project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
                 </para>
         </refsect1>
 
                 <function>sd_journal_get_catalog_for_message_id()</function>
                 interfaces are available as a shared library, which can
                 be compiled and linked to with the
-                <constant>libsystemd</constant> <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                <constant>libsystemd</constant> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 file.</para>
         </refsect1>
 
index 4410d6e..3f5483b 100644 (file)
 
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_get_cursor</function></funcdef>
-                                <paramdef>sd_journal<parameter>j</parameter></paramdef>
-                                <paramdef>char ** <parameter>cursor</parameter></paramdef>
+                                <paramdef>sd_journal *<parameter>j</parameter></paramdef>
+                                <paramdef>char **<parameter>cursor</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_test_cursor</function></funcdef>
-                                <paramdef>sd_journal<parameter>j</parameter></paramdef>
-                                <paramdef>const char * <parameter>cursor</parameter></paramdef>
+                                <paramdef>sd_journal *<parameter>j</parameter></paramdef>
+                                <paramdef>const char *<parameter>cursor</parameter></paramdef>
                         </funcprototype>
 
                 </funcsynopsis>
@@ -89,7 +89,7 @@
                 string is allocated via libc
                 <citerefentry><refentrytitle>malloc</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                 and should be freed after use with
-                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
+                <citerefentry project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
 
                 <para>Note that
                 <function>sd_journal_get_cursor()</function> will not
                 and <function>sd_journal_test_cursor()</function>
                 interfaces are available as a shared library, which can
                 be compiled and linked to with the
-                <constant>libsystemd</constant> <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                <constant>libsystemd</constant> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 file.</para>
         </refsect1>
 
index d32ab01..673cff4 100644 (file)
 
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_get_cutoff_realtime_usec</function></funcdef>
-                                <paramdef>sd_journal<parameter>j</parameter></paramdef>
-                                <paramdef>uint64_t<parameter>from</parameter></paramdef>
-                                <paramdef>uint64_t<parameter>to</parameter></paramdef>
+                                <paramdef>sd_journal *<parameter>j</parameter></paramdef>
+                                <paramdef>uint64_t *<parameter>from</parameter></paramdef>
+                                <paramdef>uint64_t *<parameter>to</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_get_cutoff_monotonic_usec</function></funcdef>
-                                <paramdef>sd_journal<parameter>j</parameter></paramdef>
+                                <paramdef>sd_journal *<parameter>j</parameter></paramdef>
                                 <paramdef>sd_id128_t <parameter>boot_id</parameter></paramdef>
-                                <paramdef>uint64_t<parameter>from</parameter></paramdef>
-                                <paramdef>uint64_t<parameter>to</parameter></paramdef>
+                                <paramdef>uint64_t *<parameter>from</parameter></paramdef>
+                                <paramdef>uint64_t *<parameter>to</parameter></paramdef>
                         </funcprototype>
 
                 </funcsynopsis>
                 <title>Description</title>
 
                 <para><function>sd_journal_get_cutoff_realtime_usec()</function>
-                gets the realtime (wallclock) timestamps of the first
-                and last entries accessible in the journal.  It takes
-                three arguments: the journal context object and two
-                pointers to 64-bit unsigned integers to store the
-                timestamps in. The timestamps are in microseconds
-                since the epoch,
+                retrieves the realtime (wallclock) timestamps of the
+                first and last entries accessible in the journal.  It
+                takes three arguments: the journal context object
+                <parameter>j</parameter> and two pointers
+                <parameter>from</parameter> and
+                <parameter>to</parameter> pointing at 64-bit unsigned
+                integers to store the timestamps in. The timestamps
+                are in microseconds since the epoch,
                 i.e. <constant>CLOCK_REALTIME</constant>. Either one
                 of the two timestamp arguments may be passed as
                 <constant>NULL</constant> in case the timestamp is not
                 needed, but not both.</para>
 
                 <para><function>sd_journal_get_cutoff_monotonic_usec()</function>
-                gets the monotonic timestamps of the first and last
-                entries accessible in the journal. It takes three
-                arguments: the journal context object, a 128-bit
-                identifier for the boot, and two pointers to 64-bit
-                unsigned integers to store the timestamps. The
-                timestamps are in microseconds since boot-up of the
-                specific boot,
+                retrieves the monotonic timestamps of the first and
+                last entries accessible in the journal. It takes three
+                arguments: the journal context object
+                <parameter>j</parameter>, a 128-bit identifier for the
+                boot <parameter>boot_id</parameter>, and two pointers
+                to 64-bit unsigned integers to store the timestamps,
+                <parameter>from</parameter> and
+                <parameter>to</parameter>. The timestamps are in
+                microseconds since boot-up of the specific boot,
                 i.e. <constant>CLOCK_MONOTONIC</constant>. Since the
                 monotonic clock begins new with every reboot it only
                 defines a well-defined point in time when used
                 <function>sd_journal_get_cutoff_monotonic_usec()</function>
                 return 1 on success, 0 if not suitable entries are in
                 the journal or a negative errno-style error code.</para>
+
+                <para>Locations pointed to by parameters
+                <parameter>from</parameter> and
+                <parameter>to</parameter> will be set only if the
+                return value is positive, and obviously, the
+                parameters are non-null.</para>
         </refsect1>
 
         <refsect1>
                 <function>sd_journal_get_cutoff_monotonic_usec()</function>
                 interfaces are available as a shared library, which can
                 be compiled and linked to with the
-                <constant>libsystemd</constant> <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                <constant>libsystemd</constant> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 file.</para>
         </refsect1>
 
index c01db4e..19fbcd3 100644 (file)
 
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_get_data</function></funcdef>
-                                <paramdef>sd_journal<parameter>j</parameter></paramdef>
-                                <paramdef>const char<parameter>field</parameter></paramdef>
-                                <paramdef>const void** <parameter>data</parameter></paramdef>
-                                <paramdef>size_t<parameter>length</parameter></paramdef>
+                                <paramdef>sd_journal *<parameter>j</parameter></paramdef>
+                                <paramdef>const char *<parameter>field</parameter></paramdef>
+                                <paramdef>const void **<parameter>data</parameter></paramdef>
+                                <paramdef>size_t *<parameter>length</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_enumerate_data</function></funcdef>
-                                <paramdef>sd_journal<parameter>j</parameter></paramdef>
-                                <paramdef>const void** <parameter>data</parameter></paramdef>
-                                <paramdef>size_t<parameter>length</parameter></paramdef>
+                                <paramdef>sd_journal *<parameter>j</parameter></paramdef>
+                                <paramdef>const void **<parameter>data</parameter></paramdef>
+                                <paramdef>size_t *<parameter>length</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>void <function>sd_journal_restart_data</function></funcdef>
-                                <paramdef>sd_journal<parameter>j</parameter></paramdef>
+                                <paramdef>sd_journal *<parameter>j</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef><function>SD_JOURNAL_FOREACH_DATA</function></funcdef>
-                                <paramdef>sd_journal<parameter>j</parameter></paramdef>
-                                <paramdef>const void<parameter>data</parameter></paramdef>
+                                <paramdef>sd_journal *<parameter>j</parameter></paramdef>
+                                <paramdef>const void *<parameter>data</parameter></paramdef>
                                 <paramdef>size_t <parameter>length</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_set_data_threshold</function></funcdef>
-                                <paramdef>sd_journal<parameter>j</parameter></paramdef>
+                                <paramdef>sd_journal *<parameter>j</parameter></paramdef>
                                 <paramdef>size_t <parameter>sz</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_get_data_threshold</function></funcdef>
-                                <paramdef>sd_journal<parameter>j</parameter></paramdef>
-                                <paramdef>size_t<parameter>sz</parameter></paramdef>
+                                <paramdef>sd_journal *<parameter>j</parameter></paramdef>
+                                <paramdef>size_t *<parameter>sz</parameter></paramdef>
                         </funcprototype>
                 </funcsynopsis>
         </refsynopsisdiv>
                 <function>sd_journal_get_data_threshold()</function>
                 interfaces are available as a shared library, which can
                 be compiled and linked to with the
-                <constant>libsystemd</constant> <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                <constant>libsystemd</constant> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 file.</para>
         </refsect1>
 
                 <programlisting>...
 int print_fields(sd_journal *j) {
         const void *data;
-        size_t l;
+        size_t length;
         SD_JOURNAL_FOREACH_DATA(j, data, length)
                 printf("%.*s\n", (int) length, data);
 }
index 16aeea2..3aa79ce 100644 (file)
 
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_get_fd</function></funcdef>
-                                <paramdef>sd_journal<parameter>j</parameter></paramdef>
+                                <paramdef>sd_journal *<parameter>j</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_get_events</function></funcdef>
-                                <paramdef>sd_journal<parameter>j</parameter></paramdef>
+                                <paramdef>sd_journal *<parameter>j</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_get_timeout</function></funcdef>
-                                <paramdef>sd_journal<parameter>j</parameter></paramdef>
-                                <paramdef>uint64_t<parameter>timeout_usec</parameter></paramdef>
+                                <paramdef>sd_journal *<parameter>j</parameter></paramdef>
+                                <paramdef>uint64_t *<parameter>timeout_usec</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_process</function></funcdef>
-                                <paramdef>sd_journal<parameter>j</parameter></paramdef>
+                                <paramdef>sd_journal *<parameter>j</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_wait</function></funcdef>
-                                <paramdef>sd_journal<parameter>j</parameter></paramdef>
+                                <paramdef>sd_journal *<parameter>j</parameter></paramdef>
                                 <paramdef>uint64_t <parameter>timeout_usec</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_reliable_fd</function></funcdef>
-                                <paramdef>sd_journal<parameter>j</parameter></paramdef>
+                                <paramdef>sd_journal *<parameter>j</parameter></paramdef>
                         </funcprototype>
 
                 </funcsynopsis>
@@ -255,7 +255,7 @@ else {
                 <function>sd_journal_wait()</function> interfaces are
                 available as a shared library, which can be compiled and
                 linked to with the
-                <constant>libsystemd</constant> <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                <constant>libsystemd</constant> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 file.</para>
         </refsect1>
 
index a9e6f07..18fbdca 100644 (file)
 
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_get_realtime_usec</function></funcdef>
-                                <paramdef>sd_journal<parameter>j</parameter></paramdef>
-                                <paramdef>uint64_t<parameter>usec</parameter></paramdef>
+                                <paramdef>sd_journal *<parameter>j</parameter></paramdef>
+                                <paramdef>uint64_t *<parameter>usec</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_get_monotonic_usec</function></funcdef>
-                                <paramdef>sd_journal<parameter>j</parameter></paramdef>
-                                <paramdef>uint64_t<parameter>usec</parameter></paramdef>
-                                <paramdef>sd_id128_t<parameter>boot_id</parameter></paramdef>
+                                <paramdef>sd_journal *<parameter>j</parameter></paramdef>
+                                <paramdef>uint64_t *<parameter>usec</parameter></paramdef>
+                                <paramdef>sd_id128_t *<parameter>boot_id</parameter></paramdef>
                         </funcprototype>
 
                 </funcsynopsis>
                 <function>sd_journal_get_monotonic_usec()</function>
                 interfaces are available as a shared library, which can
                 be compiled and linked to with the
-                <constant>libsystemd</constant> <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                <constant>libsystemd</constant> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 file.</para>
         </refsect1>
 
index e677b5f..cd996bd 100644 (file)
@@ -53,8 +53,8 @@
 
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_get_usage</function></funcdef>
-                                <paramdef>sd_journal<parameter>j</parameter></paramdef>
-                                <paramdef>uint64_t<parameter>bytes</parameter></paramdef>
+                                <paramdef>sd_journal *<parameter>j</parameter></paramdef>
+                                <paramdef>uint64_t *<parameter>bytes</parameter></paramdef>
                         </funcprototype>
 
                 </funcsynopsis>
@@ -86,7 +86,7 @@
                 <para>The <function>sd_journal_get_usage()</function>
                 interface is available as a shared library, which can be
                 compiled and linked to with the
-                <constant>libsystemd</constant> <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                <constant>libsystemd</constant> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 file.</para>
         </refsect1>
 
index d3a7183..4df6b4e 100644 (file)
 
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_next</function></funcdef>
-                                <paramdef>sd_journal<parameter>j</parameter></paramdef>
+                                <paramdef>sd_journal *<parameter>j</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_previous</function></funcdef>
-                                <paramdef>sd_journal<parameter>j</parameter></paramdef>
+                                <paramdef>sd_journal *<parameter>j</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_next_skip</function></funcdef>
-                                <paramdef>sd_journal<parameter>j</parameter></paramdef>
+                                <paramdef>sd_journal *<parameter>j</parameter></paramdef>
                                 <paramdef>uint64_t <parameter>skip</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_previous_skip</function></funcdef>
-                                <paramdef>sd_journal<parameter>j</parameter></paramdef>
+                                <paramdef>sd_journal *<parameter>j</parameter></paramdef>
                                 <paramdef>uint64_t <parameter>skip</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef><function>SD_JOURNAL_FOREACH</function></funcdef>
-                                <paramdef>sd_journal<parameter>j</parameter></paramdef>
+                                <paramdef>sd_journal *<parameter>j</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef><function>SD_JOURNAL_FOREACH_BACKWARDS</function></funcdef>
-                                <paramdef>sd_journal<parameter>j</parameter></paramdef>
+                                <paramdef>sd_journal *<parameter>j</parameter></paramdef>
                         </funcprototype>
                 </funcsynopsis>
         </refsynopsisdiv>
                 <function>sd_journal_previous_skip()</function> interfaces are
                 available as a shared library, which can be compiled and
                 linked to with the
-                <constant>libsystemd</constant> <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                <constant>libsystemd</constant> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 file.</para>
         </refsect1>
 
@@ -183,7 +183,7 @@ int main(int argc, char *argv[]) {
                 const char *d;
                 size_t l;
 
-                r = sd_journal_get_data(j, "MESSAGE", &amp;d, &amp;l);
+                r = sd_journal_get_data(j, "MESSAGE", (const void **)&amp;d, &amp;l);
                 if (r &lt; 0) {
                         fprintf(stderr, "Failed to read message field: %s\n", strerror(-r));
                         continue;
index 3fc0d0c..2d1dbc3 100644 (file)
 
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_open</function></funcdef>
-                                <paramdef>sd_journal** <parameter>ret</parameter></paramdef>
+                                <paramdef>sd_journal **<parameter>ret</parameter></paramdef>
                                 <paramdef>int <parameter>flags</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_open_directory</function></funcdef>
-                                <paramdef>sd_journal** <parameter>ret</parameter></paramdef>
-                                <paramdef>const char<parameter>path</parameter></paramdef>
+                                <paramdef>sd_journal **<parameter>ret</parameter></paramdef>
+                                <paramdef>const char *<parameter>path</parameter></paramdef>
                                 <paramdef>int <parameter>flags</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_open_files</function></funcdef>
-                                <paramdef>sd_journal** <parameter>ret</parameter></paramdef>
-                                <paramdef>const char** <parameter>paths</parameter></paramdef>
+                                <paramdef>sd_journal **<parameter>ret</parameter></paramdef>
+                                <paramdef>const char **<parameter>paths</parameter></paramdef>
                                 <paramdef>int <parameter>flags</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_open_container</function></funcdef>
-                                <paramdef>sd_journal** <parameter>ret</parameter></paramdef>
-                                <paramdef>const char<parameter>machine</parameter></paramdef>
+                                <paramdef>sd_journal **<parameter>ret</parameter></paramdef>
+                                <paramdef>const char *<parameter>machine</parameter></paramdef>
                                 <paramdef>int <parameter>flags</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>void <function>sd_journal_close</function></funcdef>
-                                <paramdef>sd_journal<parameter>j</parameter></paramdef>
+                                <paramdef>sd_journal *<parameter>j</parameter></paramdef>
                         </funcprototype>
                 </funcsynopsis>
         </refsynopsisdiv>
                 <function>sd_journal_close()</function> interfaces are
                 available as a shared library, which can be compiled and
                 linked to with the
-                <constant>libsystemd</constant> <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                <constant>libsystemd</constant> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 file.</para>
         </refsect1>
 
index c6f204b..055094c 100644 (file)
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_print</function></funcdef>
                                 <paramdef>int <parameter>priority</parameter></paramdef>
-                                <paramdef>const char<parameter>format</parameter></paramdef>
+                                <paramdef>const char *<parameter>format</parameter></paramdef>
                                 <paramdef>...</paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_printv</function></funcdef>
                                 <paramdef>int <parameter>priority</parameter></paramdef>
-                                <paramdef>const char<parameter>format</parameter></paramdef>
+                                <paramdef>const char *<parameter>format</parameter></paramdef>
                                 <paramdef>va_list <parameter>ap</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_send</function></funcdef>
-                                <paramdef>const char<parameter>format</parameter></paramdef>
+                                <paramdef>const char *<parameter>format</parameter></paramdef>
                                 <paramdef>...</paramdef>
                         </funcprototype>
 
@@ -84,7 +84,7 @@
 
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_perror</function></funcdef>
-                                <paramdef>const char<parameter>message</parameter></paramdef>
+                                <paramdef>const char *<parameter>message</parameter></paramdef>
                         </funcprototype>
 
                 </funcsynopsis>
@@ -98,9 +98,9 @@
                 system journal. The first argument is a priority
                 value. This is followed by a format string and its
                 parameters, similar to
-                <citerefentry><refentrytitle>printf</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                <citerefentry project='man-pages'><refentrytitle>printf</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                 or
-                <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>. The
+                <citerefentry project='man-pages'><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>. The
                 priority value is one of
                 <constant>LOG_EMERG</constant>,
                 <constant>LOG_ALERT</constant>,
                 <constant>LOG_INFO</constant>,
                 <constant>LOG_DEBUG</constant>, as defined in
                 <filename>syslog.h</filename>, see
-                <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                <citerefentry project='man-pages'><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                 for details. It is recommended to use this call to
                 submit log messages in the application locale or system
                 locale and in UTF-8 format, but no such restrictions
                 the passed string, suffixed with ": " and a human
                 readable representation of the current error code
                 stored in
-                <citerefentry><refentrytitle>errno</refentrytitle><manvolnum>3</manvolnum></citerefentry>. If
+                <citerefentry project='man-pages'><refentrytitle>errno</refentrytitle><manvolnum>3</manvolnum></citerefentry>. If
                 the message string is passed as <constant>NULL</constant> or empty string,
                 only the error string representation will be written,
                 prefixed with nothing. An additional journal field
@@ -193,7 +193,7 @@ sd_journal_send("MESSAGE=Hello World, this is PID %lu!", (unsigned long) getpid(
                 SD_JOURNAL_SUPPRESS_LOCATION before including
                 <filename>sd-journal.h</filename>.</para>
 
-                <para><citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                <para><citerefentry project='man-pages'><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                 and <function>sd_journal_print()</function> may
                 largely be used interchangeably
                 functionality-wise. However, note that log messages
@@ -216,8 +216,13 @@ sd_journal_send("MESSAGE=Hello World, this is PID %lu!", (unsigned long) getpid(
 
                 <para>The four calls return 0 on success or a negative
                 errno-style error code. The
-                <citerefentry><refentrytitle>errno</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                <citerefentry project='man-pages'><refentrytitle>errno</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                 variable itself is not altered.</para>
+
+                <para>If
+                <citerefentry><refentrytitle>systemd-journald</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                is not running (the socket is not present), those
+                functions do nothing, and also return 0.</para>
         </refsect1>
 
         <refsect1>
@@ -242,7 +247,7 @@ sd_journal_send("MESSAGE=Hello World, this is PID %lu!", (unsigned long) getpid(
                 <function>sd_journal_sendv()</function> interfaces
                 are available as a shared library, which can be compiled
                 and linked to with the
-                <constant>libsystemd</constant> <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                <constant>libsystemd</constant> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 file.</para>
         </refsect1>
 
@@ -253,9 +258,9 @@ sd_journal_send("MESSAGE=Hello World, this is PID %lu!", (unsigned long) getpid(
                         <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>sd-journal</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>sd_journal_stream_fd</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry project='man-pages'><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>perror</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>errno</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry project='man-pages'><refentrytitle>errno</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>systemd.journal-fields</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>signal</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>socket</refentrytitle><manvolnum>7</manvolnum></citerefentry>
index 6f489bb..8f0e6b8 100644 (file)
 
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_query_unique</function></funcdef>
-                                <paramdef>sd_journal<parameter>j</parameter></paramdef>
-                                <paramdef>const char<parameter>field</parameter></paramdef>
+                                <paramdef>sd_journal *<parameter>j</parameter></paramdef>
+                                <paramdef>const char *<parameter>field</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_enumerate_unique</function></funcdef>
-                                <paramdef>sd_journal<parameter>j</parameter></paramdef>
-                                <paramdef>const void** <parameter>data</parameter></paramdef>
-                                <paramdef>size_t<parameter>length</parameter></paramdef>
+                                <paramdef>sd_journal *<parameter>j</parameter></paramdef>
+                                <paramdef>const void **<parameter>data</parameter></paramdef>
+                                <paramdef>size_t *<parameter>length</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>void <function>sd_journal_restart_unique</function></funcdef>
-                                <paramdef>sd_journal<parameter>j</parameter></paramdef>
+                                <paramdef>sd_journal *<parameter>j</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef><function>SD_JOURNAL_FOREACH_UNIQUE</function></funcdef>
-                                <paramdef>sd_journal<parameter>j</parameter></paramdef>
-                                <paramdef>const void<parameter>data</parameter></paramdef>
+                                <paramdef>sd_journal *<parameter>j</parameter></paramdef>
+                                <paramdef>const void *<parameter>data</parameter></paramdef>
                                 <paramdef>size_t <parameter>length</parameter></paramdef>
                         </funcprototype>
 
                 <function>sd_journal_restart_unique()</function>
                 interfaces are available as a shared library, which can
                 be compiled and linked to with the
-                <constant>libsystemd</constant> <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                <constant>libsystemd</constant> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 file.</para>
         </refsect1>
 
index 9ee14e4..2ef37e5 100644 (file)
 
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_seek_head</function></funcdef>
-                                <paramdef>sd_journal<parameter>j</parameter></paramdef>
+                                <paramdef>sd_journal *<parameter>j</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_seek_tail</function></funcdef>
-                                <paramdef>sd_journal<parameter>j</parameter></paramdef>
+                                <paramdef>sd_journal *<parameter>j</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_seek_monotonic_usec</function></funcdef>
-                                <paramdef>sd_journal<parameter>j</parameter></paramdef>
+                                <paramdef>sd_journal *<parameter>j</parameter></paramdef>
                                 <paramdef>sd_id128_t <parameter>boot_id</parameter></paramdef>
                                 <paramdef>uint64_t <parameter>usec</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_seek_realtime_usec</function></funcdef>
-                                <paramdef>sd_journal<parameter>j</parameter></paramdef>
+                                <paramdef>sd_journal *<parameter>j</parameter></paramdef>
                                 <paramdef>uint64_t <parameter>usec</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_seek_cursor</function></funcdef>
-                                <paramdef>sd_journal<parameter>j</parameter></paramdef>
-                                <paramdef>const char * <parameter>cursor</parameter></paramdef>
+                                <paramdef>sd_journal *<parameter>j</parameter></paramdef>
+                                <paramdef>const char *<parameter>cursor</parameter></paramdef>
                         </funcprototype>
                 </funcsynopsis>
         </refsynopsisdiv>
                 and <function>sd_journal_seek_cursor()</function>
                 interfaces are available as a shared library, which can
                 be compiled and linked to with the
-                <constant>libsystemd</constant> <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                <constant>libsystemd</constant> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 file.</para>
         </refsect1>
 
index e7bd661..c9ce7cd 100644 (file)
@@ -53,7 +53,7 @@
 
                         <funcprototype>
                                 <funcdef>int <function>sd_journal_stream_fd</function></funcdef>
-                                <paramdef>const char<parameter>identifier</parameter></paramdef>
+                                <paramdef>const char *<parameter>identifier</parameter></paramdef>
                                 <paramdef>int <parameter>priority</parameter></paramdef>
                                 <paramdef>int <parameter>level_prefix</parameter></paramdef>
                         </funcprototype>
@@ -88,7 +88,7 @@
                 <constant>LOG_INFO</constant>,
                 <constant>LOG_DEBUG</constant>, as defined in
                 <filename>syslog.h</filename>, see
-                <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                <citerefentry project='man-pages'><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                 for details. The third argument is a boolean: if true
                 kernel-style log priority level prefixes (such as
                 <constant>SD_WARNING</constant>) are interpreted, see
                 <para>The <function>sd_journal_stream_fd()</function>
                 interface is available as a shared library, which can
                 be compiled and linked to with the
-                <constant>libsystemd</constant> <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                <constant>libsystemd</constant> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 file.</para>
         </refsect1>
 
                 <title>Examples</title>
 
                 <para>Creating a log stream suitable for
-                <citerefentry><refentrytitle>fprintf</refentrytitle><manvolnum>3</manvolnum></citerefentry>:</para>
+                <citerefentry project='man-pages'><refentrytitle>fprintf</refentrytitle><manvolnum>3</manvolnum></citerefentry>:</para>
 
                 <programlisting>#include &lt;syslog.h&gt;
 #include &lt;stdio.h&gt;
@@ -161,8 +161,8 @@ int main(int argc, char *argv[]) {
                         <citerefentry><refentrytitle>sd-journal</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>sd_journal_print</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>fprintf</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry project='man-pages'><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry project='man-pages'><refentrytitle>fprintf</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>systemd.journal-fields</refentrytitle><manvolnum>7</manvolnum></citerefentry>
                 </para>
         </refsect1>
index aca7087..ba66238 100644 (file)
 
                         <funcprototype>
                                 <funcdef>int <function>sd_login_monitor_new</function></funcdef>
-                                <paramdef>const char<parameter>category</parameter></paramdef>
-                                <paramdef>sd_login_monitor** <parameter>ret</parameter></paramdef>
+                                <paramdef>const char *<parameter>category</parameter></paramdef>
+                                <paramdef>sd_login_monitor **<parameter>ret</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
-                                <funcdef>sd_login_monitor<function>sd_login_monitor_unref</function></funcdef>
-                                <paramdef>sd_login_monitor<parameter>m</parameter></paramdef>
+                                <funcdef>sd_login_monitor *<function>sd_login_monitor_unref</function></funcdef>
+                                <paramdef>sd_login_monitor *<parameter>m</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_login_monitor_flush</function></funcdef>
-                                <paramdef>sd_login_monitor<parameter>m</parameter></paramdef>
+                                <paramdef>sd_login_monitor *<parameter>m</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_login_monitor_get_fd</function></funcdef>
-                                <paramdef>sd_login_monitor<parameter>m</parameter></paramdef>
+                                <paramdef>sd_login_monitor *<parameter>m</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_login_monitor_get_events</function></funcdef>
-                                <paramdef>sd_login_monitor<parameter>m</parameter></paramdef>
+                                <paramdef>sd_login_monitor *<parameter>m</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_login_monitor_get_timeout</function></funcdef>
-                                <paramdef>sd_login_monitor<parameter>m</parameter></paramdef>
-                                <paramdef>uint64_t<parameter>timeout_usec</parameter></paramdef>
+                                <paramdef>sd_login_monitor *<parameter>m</parameter></paramdef>
+                                <paramdef>uint64_t *<parameter>timeout_usec</parameter></paramdef>
                         </funcprototype>
 
                 </funcsynopsis>
@@ -226,7 +226,7 @@ else {
                 <function>sd_login_monitor_get_timeout()</function>
                 interfaces are available as a shared library, which can
                 be compiled and linked to with the
-                <constant>libsystemd</constant> <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                <constant>libsystemd</constant> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 file.</para>
         </refsect1>
 
index 1e762f4..4b79603 100644 (file)
                 <refname>sd_pid_get_owner_uid</refname>
                 <refname>sd_pid_get_machine_name</refname>
                 <refname>sd_pid_get_slice</refname>
+                <refname>sd_peer_get_session</refname>
+                <refname>sd_peer_get_unit</refname>
+                <refname>sd_peer_get_user_unit</refname>
+                <refname>sd_peer_get_owner_uid</refname>
+                <refname>sd_peer_get_machine_name</refname>
+                <refname>sd_peer_get_slice</refname>
                 <refpurpose>Determine session, service, owner of a
                 session, container/VM or slice of a specific
-                PID</refpurpose>
+                PID or socket peer</refpurpose>
         </refnamediv>
 
         <refsynopsisdiv>
                         <funcprototype>
                                 <funcdef>int <function>sd_pid_get_session</function></funcdef>
                                 <paramdef>pid_t <parameter>pid</parameter></paramdef>
-                                <paramdef>char** <parameter>session</parameter></paramdef>
+                                <paramdef>char **<parameter>session</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_pid_get_unit</function></funcdef>
                                 <paramdef>pid_t <parameter>pid</parameter></paramdef>
-                                <paramdef>char** <parameter>unit</parameter></paramdef>
+                                <paramdef>char **<parameter>unit</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_pid_get_user_unit</function></funcdef>
                                 <paramdef>pid_t <parameter>pid</parameter></paramdef>
-                                <paramdef>char** <parameter>unit</parameter></paramdef>
+                                <paramdef>char **<parameter>unit</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_pid_get_owner_uid</function></funcdef>
                                 <paramdef>pid_t <parameter>pid</parameter></paramdef>
-                                <paramdef>uid_t<parameter>uid</parameter></paramdef>
+                                <paramdef>uid_t *<parameter>uid</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_pid_get_machine_name</function></funcdef>
                                 <paramdef>pid_t <parameter>pid</parameter></paramdef>
-                                <paramdef>char** <parameter>name</parameter></paramdef>
+                                <paramdef>char **<parameter>name</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_pid_get_slice</function></funcdef>
                                 <paramdef>pid_t <parameter>pid</parameter></paramdef>
-                                <paramdef>char** <parameter>slice</parameter></paramdef>
+                                <paramdef>char **<parameter>slice</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_peer_get_session</function></funcdef>
+                                <paramdef>int <parameter>fd</parameter></paramdef>
+                                <paramdef>char **<parameter>session</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_peer_get_unit</function></funcdef>
+                                <paramdef>int <parameter>fd</parameter></paramdef>
+                                <paramdef>char **<parameter>unit</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_peer_get_user_unit</function></funcdef>
+                                <paramdef>int <parameter>fd</parameter></paramdef>
+                                <paramdef>char **<parameter>unit</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_peer_get_owner_uid</function></funcdef>
+                                <paramdef>int <parameter>fd</parameter></paramdef>
+                                <paramdef>uid_t *<parameter>uid</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_peer_get_machine_name</function></funcdef>
+                                <paramdef>int <parameter>fd</parameter></paramdef>
+                                <paramdef>char **<parameter>name</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_peer_get_slice</function></funcdef>
+                                <paramdef>int <parameter>fd</parameter></paramdef>
+                                <paramdef>char **<parameter>slice</parameter></paramdef>
                         </funcprototype>
                 </funcsynopsis>
         </refsynopsisdiv>
                 threads). For processes not being part of a login
                 session this function will fail. The returned string
                 needs to be freed with the libc
-                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                <citerefentry project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                 call after use.</para>
 
                 <para><function>sd_pid_get_unit()</function> may be
                 use <function>sd_pid_get_user_unit()</function> for
                 that.) The returned string needs to be freed with the
                 libc
-                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                <citerefentry project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                 call after use.</para>
 
                 <para><function>sd_pid_get_user_unit()</function> may
                 container is a member of. The machine name is a short
                 string, suitable for usage in file system paths. The
                 returned string needs to be freed with the libc
-                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                <citerefentry project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                 call after use.</para>
 
                 <para><function>sd_pid_get_slice()</function> may be
                 <citerefentry><refentrytitle>systemd.slice</refentrytitle><manvolnum>5</manvolnum></citerefentry>
                 for details about slices. The returned string needs to
                 be freed with the libc
-                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                <citerefentry project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                 call after use.</para>
 
                 <para>If the <varname>pid</varname> parameter of any
                 of these functions is passed as 0, the operation is
                 executed for the calling process.</para>
+
+                <para>The <function>sd_peer_get_session()</function>,
+                <function>sd_peer_get_unit()</function>,
+                <function>sd_peer_get_user_unit()</function>,
+                <function>sd_peer_get_owner_uid()</function>,
+                <function>sd_peer_get_machine_name()</function> and
+                <function>sd_peer_get_slice()</function> calls operate
+                similar to their PID counterparts, but operate on a
+                connected AF_UNIX socket and retrieve information
+                about the connected peer process.</para>
         </refsect1>
 
         <refsect1>
                 <function>sd_pid_get_unit()</function>,
                 <function>sd_pid_get_user_unit()</function>,
                 <function>sd_pid_get_owner_uid()</function>,
-                <function>sd_pid_get_machine_name()</function> and
-                <function>sd_pid_get_slice()</function> interfaces are
-                available as a shared library, which can be compiled and
-                linked to with the
-                <constant>libsystemd</constant> <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                <function>sd_pid_get_machine_name()</function>,
+                <function>sd_pid_get_slice()</function>,
+                <function>sd_peer_get_session()</function>,
+                <function>sd_peer_get_unit()</function>,
+                <function>sd_peer_get_user_unit()</function>,
+                <function>sd_peer_get_owner_uid()</function>,
+                <function>sd_peer_get_machine_name()</function> and
+                <function>sd_peer_get_slice()</function> interfaces are
+                available as a shared library, which can be compiled
+                and linked to with the
+                <constant>libsystemd</constant> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 file.</para>
 
                 <para>Note that the login session identifier as
index f2550dd..20c7b99 100644 (file)
 
                         <funcprototype>
                                 <funcdef>int <function>sd_seat_get_active</function></funcdef>
-                                <paramdef>const char<parameter>seat</parameter></paramdef>
-                                <paramdef>char** <parameter>session</parameter></paramdef>
-                                <paramdef>uid_t<parameter>uid</parameter></paramdef>
+                                <paramdef>const char *<parameter>seat</parameter></paramdef>
+                                <paramdef>char **<parameter>session</parameter></paramdef>
+                                <paramdef>uid_t *<parameter>uid</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_seat_get_sessions</function></funcdef>
-                                <paramdef>const char<parameter>seat</parameter></paramdef>
-                                <paramdef>char*** <parameter>sessions</parameter></paramdef>
-                                <paramdef>uid_t** <parameter>uid</parameter></paramdef>
-                                <paramdef>unsigned int<parameter>n_uids</parameter></paramdef>
+                                <paramdef>const char *<parameter>seat</parameter></paramdef>
+                                <paramdef>char ***<parameter>sessions</parameter></paramdef>
+                                <paramdef>uid_t **<parameter>uid</parameter></paramdef>
+                                <paramdef>unsigned int *<parameter>n_uids</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_seat_can_multi_session</function></funcdef>
-                                <paramdef>const char<parameter>seat</parameter></paramdef>
+                                <paramdef>const char *<parameter>seat</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_seat_can_tty</function></funcdef>
-                                <paramdef>const char<parameter>seat</parameter></paramdef>
+                                <paramdef>const char *<parameter>seat</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_seat_can_graphical</function></funcdef>
-                                <paramdef>const char<parameter>seat</parameter></paramdef>
+                                <paramdef>const char *<parameter>seat</parameter></paramdef>
                         </funcprototype>
                 </funcsynopsis>
         </refsynopsisdiv>
@@ -99,7 +99,7 @@
                 <constant>NULL</constant>, in case only one of the
                 parameters shall be queried. The returned string needs
                 to be freed with the libc
-                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                <citerefentry project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                 call after use.</para>
 
                 <para><function>sd_seat_get_sessions()</function> may
                 <constant>NULL</constant> in case these values need not to be
                 determined. The arrays and the strings referenced by
                 them need to be freed with the libc
-                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                <citerefentry project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                 call after use. Note that instead of an empty array
                 <constant>NULL</constant> may be returned and should be considered
                 equivalent to an empty array.</para>
                 <function>sd_seat_can_grapical()</function> interfaces
                 are available as a shared library, which can be compiled
                 and linked to with the
-                <constant>libsystemd</constant> <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                <constant>libsystemd</constant> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 file.</para>
         </refsect1>
 
index ddb2bee..5006be4 100644 (file)
 
                         <funcprototype>
                                 <funcdef>int <function>sd_session_is_active</function></funcdef>
-                                <paramdef>const char<parameter>session</parameter></paramdef>
+                                <paramdef>const char *<parameter>session</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_session_is_remote</function></funcdef>
-                                <paramdef>const char<parameter>session</parameter></paramdef>
+                                <paramdef>const char *<parameter>session</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_session_get_state</function></funcdef>
-                                <paramdef>const char<parameter>session</parameter></paramdef>
-                                <paramdef>char** <parameter>state</parameter></paramdef>
+                                <paramdef>const char *<parameter>session</parameter></paramdef>
+                                <paramdef>char **<parameter>state</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_session_get_uid</function></funcdef>
-                                <paramdef>const char<parameter>session</parameter></paramdef>
-                                <paramdef>uid_t<parameter>uid</parameter></paramdef>
+                                <paramdef>const char *<parameter>session</parameter></paramdef>
+                                <paramdef>uid_t *<parameter>uid</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_session_get_seat</function></funcdef>
-                                <paramdef>const char<parameter>session</parameter></paramdef>
-                                <paramdef>char** <parameter>seat</parameter></paramdef>
+                                <paramdef>const char *<parameter>session</parameter></paramdef>
+                                <paramdef>char **<parameter>seat</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_session_get_service</function></funcdef>
-                                <paramdef>const char<parameter>session</parameter></paramdef>
-                                <paramdef>char** <parameter>service</parameter></paramdef>
+                                <paramdef>const char *<parameter>session</parameter></paramdef>
+                                <paramdef>char **<parameter>service</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_session_get_type</function></funcdef>
-                                <paramdef>const char<parameter>session</parameter></paramdef>
-                                <paramdef>char** <parameter>type</parameter></paramdef>
+                                <paramdef>const char *<parameter>session</parameter></paramdef>
+                                <paramdef>char **<parameter>type</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_session_get_class</function></funcdef>
-                                <paramdef>const char<parameter>session</parameter></paramdef>
-                                <paramdef>char** <parameter>class</parameter></paramdef>
+                                <paramdef>const char *<parameter>session</parameter></paramdef>
+                                <paramdef>char **<parameter>class</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_session_get_display</function></funcdef>
-                                <paramdef>const char<parameter>session</parameter></paramdef>
-                                <paramdef>char** <parameter>display</parameter></paramdef>
+                                <paramdef>const char *<parameter>session</parameter></paramdef>
+                                <paramdef>char **<parameter>display</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_session_get_remote_host</function></funcdef>
-                                <paramdef>const char<parameter>session</parameter></paramdef>
-                                <paramdef>char** <parameter>remote_host</parameter></paramdef>
+                                <paramdef>const char *<parameter>session</parameter></paramdef>
+                                <paramdef>char **<parameter>remote_host</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_session_get_remote_user</function></funcdef>
-                                <paramdef>const char<parameter>session</parameter></paramdef>
-                                <paramdef>char** <parameter>remote_user</parameter></paramdef>
+                                <paramdef>const char *<parameter>session</parameter></paramdef>
+                                <paramdef>char **<parameter>remote_user</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_session_get_tty</function></funcdef>
-                                <paramdef>const char<parameter>session</parameter></paramdef>
-                                <paramdef>char** <parameter>tty</parameter></paramdef>
+                                <paramdef>const char *<parameter>session</parameter></paramdef>
+                                <paramdef>char **<parameter>tty</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_session_get_vt</function></funcdef>
-                                <paramdef>const char<parameter>session</parameter></paramdef>
-                                <paramdef>unsigned int<parameter>vt</parameter></paramdef>
+                                <paramdef>const char *<parameter>session</parameter></paramdef>
+                                <paramdef>unsigned int *<parameter>vt</parameter></paramdef>
                         </funcprototype>
                 </funcsynopsis>
         </refsynopsisdiv>
                 returned. This function is a more generic version of
                 <function>sd_session_is_active()</function>. The returned
                 string needs to be freed with the libc
-                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                <citerefentry project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                 call after use.</para>
 
                 <para><function>sd_session_get_uid()</function> may be
                 identifier belongs to. Note that not all sessions are
                 attached to a seat, this call will fail for them. The
                 returned string needs to be freed with the libc
-                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                <citerefentry project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                 call after use.</para>
 
                 <para><function>sd_session_get_service()</function>
                 session identified by the specified session
                 identifier. The returned string needs to be freed with
                 the libc
-                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                <citerefentry project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                 call after use.</para>
 
                 <para><function>sd_session_get_type()</function> may
                 be used to determine the type of the session
                 identified by the specified session identifier. The
                 returned string is one of <literal>x11</literal>,
-                <literal>wayland</literal>, <literal>tty</literal> or
-                <literal>unspecified</literal> and needs to be freed
-                with the libc
-                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                <literal>wayland</literal>, <literal>tty</literal>,
+                <literal>mir</literal> or <literal>unspecified</literal> and
+                needs to be freed with the libc
+                <citerefentry project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                 call after use.</para>
 
                 <para><function>sd_session_get_class()</function> may
                 <literal>lock-screen</literal>, or
                 <literal>background</literal> and needs to be freed
                 with the libc
-                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                <citerefentry project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                 call after use.</para>
 
                 <para><function>sd_session_get_display()</function>
                 session identified by the specified session
                 identifier. The returned string needs to be
                 freed with the libc
-                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                <citerefentry project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                 call after use.</para>
 
                 <para><function>sd_session_get_remote_host()</function>
                 session identified by the specified session
                 identifier. The returned string needs to be
                 freed with the libc
-                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                <citerefentry project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                 call after use.</para>
 
                 <para><function>sd_session_get_remote_user()</function>
                 session identified by the specified session
                 identifier. The returned string needs to be
                 freed with the libc
-                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                <citerefentry project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                 call after use. Note that this value is rarely known
                 to the system, and even then should not be relied on.</para>
 
                 session identified by the specified session
                 identifier. The returned string needs to be
                 freed with the libc
-                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                <citerefentry project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                 call after use.</para>
 
                 <para><function>sd_session_get_vt()</function>
                 <function>sd_session_get_tty()</function>
                 interfaces are available as a shared library, which can
                 be compiled and linked to with the
-                <constant>libsystemd</constant> <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                <constant>libsystemd</constant> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 file.</para>
         </refsect1>
 
index f2899ee..e1b345c 100644 (file)
@@ -47,6 +47,7 @@
                 <refname>sd_uid_is_on_seat</refname>
                 <refname>sd_uid_get_sessions</refname>
                 <refname>sd_uid_get_seats</refname>
+                <refname>sd_uid_get_display</refname>
                 <refpurpose>Determine login state of a specific Unix user ID</refpurpose>
         </refnamediv>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_uid_get_state</function></funcdef>
                                 <paramdef>uid_t <parameter>uid</parameter></paramdef>
-                                <paramdef>char** <parameter>state</parameter></paramdef>
+                                <paramdef>char **<parameter>state</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_uid_is_on_seat</function></funcdef>
                                 <paramdef>uid_t <parameter>uid</parameter></paramdef>
                                 <paramdef>int <parameter>require_active</parameter></paramdef>
-                                <paramdef>const char<parameter>seat</parameter></paramdef>
+                                <paramdef>const char *<parameter>seat</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_uid_get_sessions</function></funcdef>
                                 <paramdef>uid_t <parameter>uid</parameter></paramdef>
                                 <paramdef>int <parameter>require_active</parameter></paramdef>
-                                <paramdef>char*** <parameter>sessions</parameter></paramdef>
+                                <paramdef>char ***<parameter>sessions</parameter></paramdef>
                         </funcprototype>
 
                         <funcprototype>
                                 <funcdef>int <function>sd_uid_get_seats</function></funcdef>
                                 <paramdef>uid_t <parameter>uid</parameter></paramdef>
                                 <paramdef>int <parameter>require_active</parameter></paramdef>
-                                <paramdef>char*** <parameter>seats</parameter></paramdef>
+                                <paramdef>char ***<parameter>seats</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
+                                <funcdef>int <function>sd_uid_get_display</function></funcdef>
+                                <paramdef>uid_t <parameter>uid</parameter></paramdef>
+                                <paramdef>char **<parameter>session</parameter></paramdef>
                         </funcprototype>
                 </funcsynopsis>
         </refsynopsisdiv>
                 in regards to additional state strings being
                 returned. The returned string needs to be freed with
                 the libc
-                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                <citerefentry project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                 call after use.</para>
 
                 <para><function>sd_uid_is_on_seat()</function> may be
                 <constant>NULL</constant> terminated string array of session identifiers in
                 <parameter>sessions</parameter> which needs to be
                 freed by the caller with the libc
-                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                <citerefentry project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                 call after use, including all the strings
                 referenced. If the string array parameter is passed as
                 <constant>NULL</constant>, the array will not be filled in, but the return
                 with no attached seat and hence the number of entries
                 in the returned array may differ from the one returned
                 by <function>sd_uid_get_sessions()</function>.</para>
+
+                <para><function>sd_uid_get_display()</function>
+                returns the name of the "primary" session of a user.
+                If the user has graphical sessions, it will be the
+                oldest graphical session. Otherwise, it will be the
+                oldest open session.</para>
         </refsect1>
 
         <refsect1>
                 positive integer; if it fails,
                 0. <function>sd_uid_get_sessions()</function> and
                 <function>sd_uid_get_seats()</function> return the
-                number of entries in the returned arrays. On failure,
+                number of entries in the returned arrays.
+                <function>sd_uid_get_display()</function> returns
+                a non-negative code on success. On failure,
                 these calls return a negative errno-style error
                 code.</para>
         </refsect1>
         <refsect1>
                 <title>Notes</title>
 
-                <para>The <function>sd_uid_get_state()</function>,
+                <para>Functions described here are available as a
+                shared library, and can be compiled and linked to
+                using the
+                <constant>libsystemd</constant> <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                entry.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>History</title>
+
+                <function>sd_uid_get_state()</function>,
                 <function>sd_uid_is_on_seat()</function>,
-                <function>sd_uid_get_sessions()</function>, and
-                <function>sd_uid_get_seats()</function> interfaces are
-                available as a shared library, which can be compiled and
-                linked to with the <constant>libsystemd</constant> <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
-                file.</para>
+                <function>sd_uid_get_sessions()</function>,
+                and <function>sd_uid_get_seats()</function> functions
+                were added in systemd-31.
+
+                <para><function>sd_uid_get_display()</function> was
+                added in systemd-213.</para>
         </refsect1>
 
         <refsect1>
index 88d1e5b..4164027 100644 (file)
@@ -55,7 +55,7 @@
                         <funcprototype>
                                 <funcdef>int <function>sd_watchdog_enabled</function></funcdef>
                                 <paramdef>int <parameter>unset_environment</parameter></paramdef>
-                                <paramdef>const uint64_t *<parameter>usec</parameter></paramdef>
+                                <paramdef>uint64_t *<parameter>usec</parameter></paramdef>
                         </funcprototype>
                 </funcsynopsis>
         </refsynopsisdiv>
index 7372585..6a4c184 100644 (file)
                         <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>halt</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>wall</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                        <citerefentry project='man-pages'><refentrytitle>wall</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 </para>
         </refsect1>
 
index 00a857b..dd73f92 100644 (file)
                 <para>The configuration files contain a list of
                 variable assignments, separated by newlines. Empty
                 lines and lines whose first non-whitespace character
-                is # or ; are ignored.</para>
-
-                <para>Note that both / and . are accepted as label
-                separators within sysctl variable
-                names. <literal>kernel.domainname=foo</literal> and
-                <literal>kernel/domainname=foo</literal> hence are
-                entirely equivalent.</para>
+                is <literal>#</literal> or <literal>;</literal> are
+                ignored.</para>
 
                 <para>Each configuration file shall be named in the
                 style of <filename><replaceable>program</replaceable>.conf</filename>.
                 number and a dash, to simplify the ordering of the
                 files.</para>
 
+                <para>Note that either <literal>/</literal> or
+                <literal>.</literal> may be used as separators within
+                sysctl variable names. If the first separator is a
+                slash, remaining slashes and dots are left intact. If
+                the first separator is a dot, dots and slashes are
+                interchanged. <literal>kernel.domainname=foo</literal>
+                and <literal>kernel/domainname=foo</literal> are
+                equivalent and will cause <literal>foo</literal> to
+                be written to
+                <filename>/proc/sys/kernel/domainname</filename>.
+                Either
+                <literal>net.ipv4.conf.enp3s0/200.forwarding</literal>
+                or
+                <literal>net/ipv4/conf/enp3s0.200/forwarding</literal>
+                may be used to refer to
+                <filename>/proc/sys/net/ipv4/conf/enp3s0.200/forwarding</filename>.
+                </para>
+
                 <para>If the administrator wants to disable a
                 configuration file supplied by the vendor, the
                 recommended way is to place a symlink to
                 early on boot. The network interface-specific options
                 will also be applied individually for each network
                 interface as it shows up in the system. (More
-                specifically, that is
+                specifically,
                 <filename>net.ipv4.conf.*</filename>,
                 <filename>net.ipv6.conf.*</filename>,
-                <filename>net.ipv4.neigh.*</filename> and <filename>net.ipv6.neigh.*</filename>)</para>
+                <filename>net.ipv4.neigh.*</filename> and <filename>net.ipv6.neigh.*</filename>).</para>
+
+                <para>Many sysctl parameters only become available
+                when certain kernel modules are loaded. Modules are
+                usually loaded on demand, e.g. when certain hardware
+                is plugged in or network brought up. This means that
+                <citerefentry><refentrytitle>systemd-sysctl.service</refentrytitle><manvolnum>8</manvolnum></citerefentry> which runs
+                during early boot will not configure such parameters
+                if they become available after it has run. To
+                set such parameters, it is recommended to add
+                an <citerefentry><refentrytitle>udev</refentrytitle><manvolnum>7</manvolnum></citerefentry> rule to set those parameters when they become
+                available. Alternatively, a slightly simpler and
+                less efficient option is to add the module to
+                <citerefentry><refentrytitle>modules-load.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>, causing it to be loaded statically
+                before sysctl settings are applied (see
+                example below).</para>
         </refsect1>
 
         <refsect1>
-                <title>Example</title>
+                <title>Examples</title>
+                <example>
+                        <title>Set kernel YP domain name</title>
+                        <para><filename>/etc/sysctl.d/domain-name.conf</filename>:
+                        </para>
+
+                        <programlisting>kernel.domainname=example.com</programlisting>
+                </example>
+
                 <example>
-                        <title>/etc/sysctl.d/domain-name.conf example:</title>
+                        <title>Disable packet filter on bridged packets (method one)</title>
+                        <para><filename>/etc/udev/rules.d/99-bridge.conf</filename>:
+                        </para>
+
+                        <programlisting>ACTION=="add", SUBSYSTEM=="module", KERNEL=="bridge", RUN+="/usr/lib/systemd/systemd-sysctl --prefix=/proc/sys/net/bridge"
+</programlisting>
+
+                        <para><filename>/etc/sysctl.d/bridge.conf</filename>:
+                        </para>
+
+                        <programlisting>net.bridge.bridge-nf-call-ip6tables = 0
+net.bridge.bridge-nf-call-iptables = 0
+net.bridge.bridge-nf-call-arptables = 0
+</programlisting>
+                </example>
+
+                <example>
+                        <title>Disable packet filter on bridged packets (method two)</title>
+                        <para><filename>/etc/modules-load.d/bridge.conf</filename>:
+                        </para>
+
+                        <programlisting>bridge</programlisting>
+
+                        <para><filename>/etc/sysctl.d/bridge.conf</filename>:
+                        </para>
 
-                        <programlisting># Set kernel YP domain name
-kernel.domainname=example.com</programlisting>
+                        <programlisting>net.bridge.bridge-nf-call-ip6tables = 0
+net.bridge.bridge-nf-call-iptables = 0
+net.bridge.bridge-nf-call-arptables = 0
+</programlisting>
                 </example>
         </refsect1>
 
@@ -133,6 +195,7 @@ kernel.domainname=example.com</programlisting>
                         <citerefentry><refentrytitle>systemd-delta</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>sysctl</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>sysctl.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                        <citerefentry><refentrytitle>modprobe</refentrytitle><manvolnum>8</manvolnum></citerefentry>
                 </para>
         </refsect1>
 
index 355cd11..2818bcb 100644 (file)
@@ -132,6 +132,18 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
       </varlistentry>
 
       <varlistentry>
+        <term><option>-r</option></term>
+        <term><option>--recursive</option></term>
+
+        <listitem>
+          <para>When listing units, also show units of local
+          containers. Units of local containers will be prefixed with
+          the container name, separated by a single colon character
+          (<literal>:</literal>).</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
         <term><option>--reverse</option></term>
 
         <listitem>
@@ -145,12 +157,27 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
 
       <varlistentry>
         <term><option>--after</option></term>
+
+        <listitem>
+          <para>With <command>list-dependencies</command>, show the
+          units that are ordered before the specified unit. In other
+          words, list the units that are in the <varname>After=</varname>
+          directive of the specified unit, have the specified unit in
+          their <varname>Before=</varname> directive, or are otherwise
+          implicit dependencies of the specified unit.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
         <term><option>--before</option></term>
 
         <listitem>
-          <para>Show which units are started after or before
-          with <command>list-dependencies</command>, respectively.
-          </para>
+          <para>With <command>list-dependencies</command>, show the
+          units that are ordered after the specified unit. In other
+          words, list the units that are in the <varname>Before=</varname>
+          directive of the specified unit, have the specified unit in
+          their <varname>After=</varname> directive, or otherwise depend
+          on the specified unit.</para>
         </listitem>
       </varlistentry>
 
@@ -203,8 +230,10 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
         <para>If <literal>replace-irreversibly</literal> is specified,
         operate like <literal>replace</literal>, but also mark the new
         jobs as irreversible. This prevents future conflicting
-        transactions from replacing these jobs. The jobs can still be
-        cancelled using the <command>cancel</command> command.</para>
+        transactions from replacing these jobs (or even being enqueued
+        while the irreversible jobs are still pending). Irreversible
+        jobs can still be cancelled using the <command>cancel</command>
+        command.</para>
 
         <para><literal>isolate</literal> is only valid for start
         operations and causes all other units to be stopped when the
@@ -259,6 +288,8 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
           <command>snapshot</command>,
           <command>is-active</command>,
           <command>is-failed</command>,
+          <command>is-enabled</command>,
+          <command>is-system-running</command>,
           <command>enable</command> and
         <command>disable</command>.</para>
         </listitem>
@@ -344,11 +375,36 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
 
         <listitem>
           <para>When used with <command>kill</command>, choose which
-          processes to kill. Must be one of <option>main</option>,
-          <option>control</option> or <option>all</option> to select
-          whether to kill only the main process of the unit, the
-          control process or all processes of the unit. If omitted,
-          defaults to <option>all</option>.</para>
+          processes to send a signal to. Must be one of
+          <option>main</option>, <option>control</option> or
+          <option>all</option> to select whether to kill only the main
+          process, the control process or all processes of the
+          unit. The main process of the unit is the one that defines
+          the life-time of it. A control process of a unit is one that
+          is invoked by the manager to induce state changes of it. For
+          example, all processes started due to the
+          <varname>ExecStartPre=</varname>,
+          <varname>ExecStop=</varname> or
+          <varname>ExecReload=</varname> settings of service units are
+          control processes. Note that there is only one control
+          process per unit at a time, as only one state change is
+          executed at a time. For services of type
+          <varname>Type=forking</varname>, the initial process started
+          by the manager for <varname>ExecStart=</varname> is a
+          control process, while the process ultimately forked off by
+          that one is then considered the main process of the unit (if
+          it can be determined). This is different for service units
+          of other types, where the process forked off by the manager
+          for <varname>ExecStart=</varname> is always the main process
+          itself. A service unit consists of zero or one main process,
+          zero or one control process plus any number of additional
+          processes. Not all unit types manage processes of these
+          types however. For example, for mount units, control processes
+          are defined (which are the invocations of
+          <filename>/usr/bin/mount</filename> and
+          <filename>/usr/bin/umount</filename>), but no main process
+          is defined. If omitted, defaults to
+          <option>all</option>.</para>
         </listitem>
 
       </varlistentry>
@@ -383,7 +439,7 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
           safe option to request an immediate reboot. If
           <option>--force</option> is specified twice for these
           operations, they will be executed immediately without
-          terminating any processes or umounting any file
+          terminating any processes or unmounting any file
           systems. Warning: specifying <option>--force</option> twice
           with any of these operations might result in data
           loss.</para>
@@ -423,6 +479,20 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
       </varlistentry>
 
       <varlistentry>
+        <term><option>--preset-mode=</option></term>
+
+        <listitem>
+          <para>Takes one of <literal>full</literal> (the default),
+          <literal>enable-only</literal>,
+          <literal>disable-only</literal>. When used with the
+          <command>preset</command> or <command>preset-all</command>
+          commands, controls whether units shall be disabled and
+          enabled according to the preset rules, or only enabled, or
+          only disabled.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
         <term><option>-n</option></term>
         <term><option>--lines=</option></term>
 
@@ -567,8 +637,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
             file.</para>
 
             <para>This command should not be confused with the
-            <command>daemon-reload</command> or <command>load</command>
-            commands.</para>
+            <command>daemon-reload</command> command.</para>
           </listitem>
 
         </varlistentry>
@@ -637,9 +706,8 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
           <listitem>
             <para>Send a signal to one or more processes of the
             unit. Use <option>--kill-who=</option> to select which
-            process to kill. Use <option>--kill-mode=</option> to select
-            the kill mode and <option>--signal=</option> to select the
-            signal to send.</para>
+            process to kill. Use <option>--signal=</option> to select
+            the signal to send.</para>
           </listitem>
         </varlistentry>
         <varlistentry>
@@ -672,10 +740,11 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
           <listitem>
             <para>Show terse runtime status information about one or
             more units, followed by most recent log data from the
-            journal. If no units are specified, show all units (subject
-            to limitations specified with <option>-t</option>). If a PID
-            is passed, show information about the unit the process
-            belongs to.</para>
+            journal. If no units are specified, show system status. If
+            combined with <option>--all</option>, also show the status of
+            all units (subject to limitations specified with
+            <option>-t</option>). If a PID is passed, show information
+            about the unit the process belongs to.</para>
 
             <para>This function is intended to generate human-readable
             output. If you are looking for computer-parsable output,
@@ -971,17 +1040,36 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
             command line, to the defaults configured in the preset
             policy files. This has the same effect as
             <command>disable</command> or <command>enable</command>,
-            depending how the unit is listed in the preset files. For
-            more information on the preset policy format, see
+            depending how the unit is listed in the preset files.</para>
+
+            <para>Use <option>--preset-mode=</option> to control
+            whether units shall be enabled and disabled, or only
+            enabled, or only disabled.</para>
+
+            <para>For more information on the preset policy format,
+            see
             <citerefentry><refentrytitle>systemd.preset</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
             For more information on the concept of presets, please
-            consult the
-            <ulink url="http://freedesktop.org/wiki/Software/systemd/Preset">Preset</ulink>
+            consult the <ulink
+            url="http://freedesktop.org/wiki/Software/systemd/Preset">Preset</ulink>
             document.</para>
           </listitem>
         </varlistentry>
 
         <varlistentry>
+          <term><command>preset-all</command></term>
+
+          <listitem>
+            <para>Resets all installed unit files to the defaults
+            configured in the preset policy file (see above).</para>
+
+            <para>Use <option>--preset-mode=</option> to control
+            whether units shall be enabled and disabled, or only
+            enabled, or only disabled.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
           <term><command>mask <replaceable>NAME</replaceable>...</command></term>
 
           <listitem>
@@ -993,7 +1081,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
             activation of the unit, including manual activation. Use
             this option with care. This honors the
             <option>--runtime</option> option to only mask temporarily
-            until the next reoobt of the system.</para>
+            until the next reboot of the system.</para>
           </listitem>
         </varlistentry>
 
@@ -1042,6 +1130,24 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
     </refsect2>
 
     <refsect2>
+      <title>Machine Commands</title>
+
+      <variablelist>
+        <varlistentry>
+          <term><command>list-machines <optional><replaceable>PATTERN</replaceable>...</optional></command></term>
+
+          <listitem>
+            <para>List the host and all running local containers with
+            their state. If one or more
+            <replaceable>PATTERN</replaceable>s are specified, only
+            containers matching one of them are shown.
+            </para>
+          </listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+
+    <refsect2>
       <title>Job Commands</title>
 
       <variablelist>
@@ -1167,10 +1273,9 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
             <para>Reload systemd manager configuration. This will reload
             all unit files and recreate the entire dependency
             tree. While the daemon is being reloaded, all sockets systemd
-            listens on on behalf of user configuration will stay
+            listens on behalf of user configuration will stay
             accessible.</para> <para>This command should not be confused
-            with the <command>load</command> or
-            <command>reload</command> commands.</para>
+            with the <command>reload</command> command.</para>
           </listitem>
         </varlistentry>
         <varlistentry>
@@ -1195,6 +1300,20 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
 
       <variablelist>
         <varlistentry>
+          <term><command>is-system-running</command></term>
+
+          <listitem>
+            <para>Checks whether the system is running. This returns
+            success when the system is fully up and running, meaning
+            not in startup, shutdown or maintenance mode. Failure is
+            returned otherwise. In addition, the current state is
+            printed in a short string to standard output. Use
+            <option>--quiet</option> to suppress output of this state
+            string.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
           <term><command>default</command></term>
 
           <listitem>
@@ -1202,6 +1321,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
             <command>isolate default.target</command>.</para>
           </listitem>
         </varlistentry>
+
         <varlistentry>
           <term><command>rescue</command></term>
 
@@ -1355,7 +1475,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
     <refsect2>
       <title>Parameter Syntax</title>
 
-      <para>Unit ommands listed above take either a single unit name
+      <para>Unit commands listed above take either a single unit name
       (designated as <replaceable>NAME</replaceable>), or multiple
       unit specifications (designated as
       <replaceable>PATTERN</replaceable>...). In the first case, the
@@ -1427,7 +1547,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
       <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
       <citerefentry><refentrytitle>systemd.resource-management</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
       <citerefentry><refentrytitle>systemd.special</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
-      <citerefentry><refentrytitle>wall</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+      <citerefentry project='man-pages'><refentrytitle>wall</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
       <citerefentry><refentrytitle>systemd.preset</refentrytitle><manvolnum>5</manvolnum></citerefentry>
       <citerefentry><refentrytitle>glob</refentrytitle><manvolnum>7</manvolnum></citerefentry>
     </para>
index c7a2598..073e807 100644 (file)
                         <arg choice="plain">set-log-level</arg>
                         <arg choice="opt"><replaceable>LEVEL</replaceable></arg>
                 </cmdsynopsis>
+                <cmdsynopsis>
+                        <command>systemd-analyze</command>
+                        <arg choice="opt" rep="repeat">OPTIONS</arg>
+                        <arg choice="plain">verify</arg>
+                        <arg choice="opt" rep="repeat"><replaceable>FILES</replaceable></arg>
+                </cmdsynopsis>
         </refsynopsisdiv>
 
         <refsect1>
                 <para><command>systemd-analyze</command> may be used
                 to determine system boot-up performance statistics and
                 retrieve other state and tracing information from the
-                system and service manager.</para>
+                system and service manager, and to verify the
+                correctness of unit files.</para>
 
                 <para><command>systemd-analyze time</command>
                 prints the time spent in the kernel before
                 described in
                 <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>).</para>
 
+                <para><command>systemd-analyze verify</command> will
+                load unit files and print warnings if any errors are
+                detected. Files specified on the command line will be
+                loaded, but also any other units referenced by
+                them. This command works by prepending the directories
+                for all command line arguments at the beginning of the
+                unit load path, which means that all units files found
+                in those directories will be used in preference to the
+                unit files found in the standard locations, even if
+                not listed explicitly.</para>
+
                 <para>If no command is passed, <command>systemd-analyze
                 time</command> is implied.</para>
 
                         <varlistentry>
                                 <term><option>--user</option></term>
 
-                                <listitem><para>Shows performance data
-                                of user sessions instead of the system
-                                manager.</para></listitem>
+                                <listitem><para>Operates on the user
+                                systemd instance.</para></listitem>
                         </varlistentry>
 
                         <varlistentry>
                                 <term><option>--system</option></term>
 
-                                <listitem><para>Shows performance data
-                                of the system manager. This is the
-                                implied default.</para></listitem>
+                                <listitem><para>Operates on the system
+                                systemd instance. This is the implied
+                                default.</para></listitem>
                         </varlistentry>
 
                         <varlistentry>
                                 e.g. "50ms".</para></listitem>
                         </varlistentry>
 
+                        <varlistentry>
+                                <term><option>--no-man</option></term>
+
+                                <listitem><para>Do not invoke man to verify the existence
+                                of man pages listen in <varname>Documentation=</varname>.
+                                </para></listitem>
+                        </varlistentry>
+
                         <xi:include href="user-system-options.xml" xpointer="host" />
                         <xi:include href="user-system-options.xml" xpointer="machine" />
 
         </refsect1>
 
         <refsect1>
-                <title>Examples</title>
+                <title>Examples for <command>dot</command></title>
 
-                <para>This plots all dependencies of any unit whose
-                name starts with <literal>avahi-daemon.</literal>:</para>
+                <example>
+                        <title>Plots all dependencies of any unit whose
+                        name starts with <literal>avahi-daemon</literal></title>
 
-                <programlisting>$ systemd-analyze dot 'avahi-daemon.*' | dot -Tsvg > avahi.svg
-$ eog avahi.svg</programlisting>
+                        <programlisting>$ systemd-analyze dot 'avahi-daemon.*' | dot -Tsvg > avahi.svg
+                        $ eog avahi.svg</programlisting>
+                </example>
 
-                <para>This plots the dependencies between all known target units:</para>
+                <example>
+                        <title>Plots the dependencies between all known target units</title>
 
-                <programlisting>systemd-analyze dot --to-pattern='*.target' --from-pattern='*.target' | dot -Tsvg > targets.svg
+                        <programlisting>systemd-analyze dot --to-pattern='*.target' --from-pattern='*.target' | dot -Tsvg > targets.svg
 $ eog targets.svg</programlisting>
+                </example>
+        </refsect1>
 
-
+        <refsect1>
+                <title>Examples for <command>verify</command></title>
+
+                <para>The following errors are currently detected:</para>
+                <itemizedlist>
+                        <listitem><para>unknown sections and
+                        directives, </para></listitem>
+
+                        <listitem><para>missing dependencies which are
+                        required to start the given unit,
+                        </para></listitem>
+
+                        <listitem><para>man pages listed in
+                        <varname>Documentation=</varname> which are
+                        not found in the system,</para></listitem>
+
+                        <listitem><para>commands listed in
+                        <varname>ExecStart=</varname> and similar
+                        which are not found in the system or not
+                        executable.</para></listitem>
+                </itemizedlist>
+
+                <example>
+                        <title>Misspelt directives</title>
+
+                        <programlisting>$ cat ./user.slice
+[Unit]
+WhatIsThis=11
+Documentation=man:nosuchfile(1)
+Requires=different.service
+
+[Service]
+Desription=x
+
+$ systemd-verify ./user.slice
+[./user.slice:9] Unknown lvalue 'WhatIsThis' in section 'Unit'
+[./user.slice:13] Unknown section 'Service'. Ignoring.
+Error: org.freedesktop.systemd1.LoadFailed:
+         Unit different.service failed to load:
+         No such file or directory.
+Failed to create user.slice/start: Invalid argument
+user.slice: man nosuchfile(1) command failed with code 16
+                        </programlisting>
+                </example>
+
+                <example>
+                        <title>Missing service units</title>
+
+                        <programlisting>$ tail ./a.socket ./b.socket
+==> ./a.socket &lt;==
+[Socket]
+ListenStream=100
+
+==> ./b.socket &lt;==
+[Socket]
+ListenStream=100
+Accept=yes
+
+$ systemd-verify ./a.socket ./b.socket
+Service a.service not loaded, a.socket cannot be started.
+Service b@0.service not loaded, b.socket cannot be started.
+                        </programlisting>
+                </example>
         </refsect1>
 
         <xi:include href="less-variables.xml" />
index 6c87feb..536dad9 100644 (file)
@@ -68,7 +68,7 @@
                 boot. <filename>systemd-ask-password-wall.service</filename>
                 is a system service that informs all logged in users
                 for system passwords via
-                <citerefentry><refentrytitle>wall</refentrytitle><manvolnum>1</manvolnum></citerefentry>. It
+                <citerefentry project='man-pages'><refentrytitle>wall</refentrytitle><manvolnum>1</manvolnum></citerefentry>. It
                 is intended to be used after boot to ensure that users
                 are properly notified.</para>
 
@@ -89,7 +89,7 @@
                 <para>
                         <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>systemd-tty-ask-password-agent</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>wall</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                        <citerefentry project='man-pages'><refentrytitle>wall</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 </para>
         </refsect1>
 
index 805827e..ce0ac3d 100644 (file)
@@ -78,7 +78,7 @@
                 asking the user for passwords using Plymouth; a
                 boot-time password agent querying the user directly on
                 the console; an agent requesting password input via a
-                <citerefentry><refentrytitle>wall</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                <citerefentry project='man-pages'><refentrytitle>wall</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 message; an agent suitable for running in a GNOME
                 session; a command line agent which can be started
                 temporarily to process queued password requests; a TTY
                 <para>
                         <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>plymouth</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>wall</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                        <citerefentry project='die-net'><refentrytitle>plymouth</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry project='man-pages'><refentrytitle>wall</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 </para>
         </refsect1>
 
index 748e417..cb96048 100644 (file)
@@ -69,7 +69,7 @@
                 <para>
                         <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>binfmt.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>wine</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                        <citerefentry project='die-net'><refentrytitle>wine</refentrytitle><manvolnum>8</manvolnum></citerefentry>
                 </para>
         </refsect1>
 
index 6659b90..150ca48 100644 (file)
@@ -78,8 +78,8 @@
                         in which order, and where possible problems
                         exist in the startup sequence of the system.
                         It is essentially a more detailed version of
-                        the <command>systemd-analyze</command>
-                        <command>plot</command> function.
+                        the <command>systemd-analyze plot</command>
+                        function.
                 </para>
                 <para>
                         Of course, bootchart can also be used at any
                                 not graph the time elapsed since boot
                                 and before systemd-bootchart was
                                 started, as it may result in extremely
-                                large graphs.  </para></listitem>
+                                large graphs. The time elapsed since boot
+                                might also include any time that the system
+                                was suspended.</para></listitem>
                         </varlistentry>
                 </variablelist>
         </refsect1>
                 <para>These options can also be set in the
                 <filename>/etc/systemd/bootchart.conf</filename>
                 file. See
-                <citerefentry><refentrytitle>bootchart.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+                <citerefentry project='man-pages'><refentrytitle>bootchart.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
                 </para>
 
                 <variablelist>
         <refsect1>
                 <title>See Also</title>
                 <para>
-                        <citerefentry><refentrytitle>bootchart.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                        <citerefentry project='man-pages'><refentrytitle>bootchart.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
                 </para>
         </refsect1>
 
index 75a3c8b..3a5930d 100644 (file)
@@ -59,7 +59,7 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
     <para><filename>systemd-bus-proxyd.socket</filename> will launch
     <filename>systemd-bus-proxyd@.service</filename> for connections
     to the classic D-Bus socket in
-    <filename>/run/dbus/system_bus_socket</filename>.</para>
+    <filename>/var/run/dbus/system_bus_socket</filename>.</para>
 
     <para><filename>systemd-bus-proxyd@.service</filename> is launched
     for an existing D-Bus connection and will use
index 4098a76..e5a867b 100644 (file)
                                 to the same named levels). These
                                 priority values are the same as
                                 defined by
-                                <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>. Defaults
+                                <citerefentry project='man-pages'><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>. Defaults
                                 to <literal>info</literal>. Note that
                                 this simply controls the default,
                                 individual lines may be logged with
index 230957b..d8dbe68 100644 (file)
                         <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>systemd-cgtop</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>ps</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                        <citerefentry project='man-pages'><refentrytitle>ps</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 </para>
         </refsect1>
 
index 73f8e74..8ee552a 100644 (file)
@@ -63,7 +63,7 @@
                 hierarchy, ordered by their CPU, memory, or disk I/O load. The
                 display is refreshed in regular intervals (by default
                 every 1s), similar in style to
-                <citerefentry><refentrytitle>top</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
+                <citerefentry project='man-pages'><refentrytitle>top</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
                 If <command>systemd-cgtop</command> is not connected
                 to a tty, only one iteration is performed and no
                 columns headers are printed. This mode is suitable for
                         <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>systemd-cgls</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>top</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                        <citerefentry project='man-pages'><refentrytitle>top</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 </para>
         </refsect1>
 
diff --git a/man/systemd-coredump.xml b/man/systemd-coredump.xml
new file mode 100644 (file)
index 0000000..b83b278
--- /dev/null
@@ -0,0 +1,105 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2014 Zbigniew Jędrzejewski-Szmek
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd-coredump" conditional='ENABLE_COREDUMP'
+          xmlns:xi="http://www.w3.org/2001/XInclude">
+
+  <refentryinfo>
+    <title>systemd-coredump</title>
+    <productname>systemd</productname>
+
+    <authorgroup>
+      <author>
+        <contrib>Developer</contrib>
+        <firstname>Lennart</firstname>
+        <surname>Poettering</surname>
+        <email>lennart@poettering.net</email>
+      </author>
+    </authorgroup>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>systemd-coredump</refentrytitle>
+    <manvolnum>8</manvolnum>
+  </refmeta>
+
+  <refnamediv>
+    <refname>systemd-coredump</refname>
+    <refpurpose>Log and store core dumps</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <para><filename>/usr/lib/systemd/systemd-coredump</filename></para>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para><command>systemd-coredump</command> can be used as a helper
+    binary by the kernel when a user space program receives a fatal
+    signal and dumps core. For it to be used in this capacity, it must
+    be specified by the
+    <varname>kernel.core_pattern</varname> <citerefentry project='man-pages'><refentrytitle>sysctl</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+    setting. Systemd installs
+    <filename>/usr/lib/sysctl.d/50-coredump.conf</filename> which
+    configures <varname>kernel.core_pattern</varname> to invoke
+    <command>systemd-coredump</command>. This file may be masked or
+    overriden to use a different setting following normal
+    <citerefentry><refentrytitle>sysctl.d</refentrytitle><manvolnum>5</manvolnum></citerefentry> rules.</para>
+
+    <para>The behaviour of a specific program upon reception of a
+    signal is governed by a few factors which are described in detail
+    in <citerefentry project='man-pages'><refentrytitle>core</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+    In particular, the coredump will only be processed when the
+    related resource limits are high enough. For programs started by
+    <command>systemd</command> those may be set using
+    <varname>LimitCore=</varname> (see
+    <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>).
+    </para>
+
+    <para><command>systemd-coredump</command> will log the coredump
+    including a backtrace if possible, and store the core (contents of
+    process' memory contents) in an external file on disk in
+    <filename>/var/lib/systemd/coredump</filename>, or directly in
+    the journal. This behaviour may be modified using
+    <citerefentry><refentrytitle>coredump.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
+
+    <para>Apart from the
+    <citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+    log viewer,
+    <citerefentry><refentrytitle>coredumpctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+    may be used to list and extract coredumps.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>See Also</title>
+    <para>
+      <citerefentry><refentrytitle>coredump.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>coredumpctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>systemd-journald.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+      <citerefentry project='man-pages'><refentrytitle>core</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sysctl.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>systemd-sysctl.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
+    </para>
+  </refsect1>
+</refentry>
diff --git a/man/systemd-debug-generator.xml b/man/systemd-debug-generator.xml
new file mode 100644 (file)
index 0000000..ce4750e
--- /dev/null
@@ -0,0 +1,98 @@
+<?xml version="1.0"?>
+<!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<!--
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+<refentry id="systemd-debug-generator">
+
+        <refentryinfo>
+                <title>systemd-debug-generator</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-debug-generator</refentrytitle>
+                <manvolnum>8</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-debug-generator</refname>
+                <refpurpose>Generator for enabling a runtime debug shell and masking specific units at boot</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>/usr/lib/systemd/system-generators/systemd-debug-generator</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><filename>systemd-debug-generator</filename> is
+                a generator that reads the kernel command line and
+                understands three options:</para>
+
+                <para>If the <option>systemd.mask=</option> option is
+                specified and followed by a unit name, this unit is
+                masked for the runtime, similar to the effect of
+                <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
+                <command>mask</command> command. This is useful to
+                boot with certain units removed from the initial boot
+                transaction for debugging system startup. May be
+                specified more than once.</para>
+
+                <para>If the <option>systemd.wants=</option> option is
+                specified and followed by a unit name, a start job for
+                this unit is added to the initial transaction. This is
+                useful to start one ore more additional units at
+                boot. May be specified more than once.</para>
+
+                <para>If the <option>systemd.debug-shell</option>
+                option is specified, the debug shell service
+                <literal>debug-shell.service</literal> is pulled into
+                the boot transaction. It will spawn a debug shell on
+                tty9 during early system startup. Note that the shell
+                may also be turned on persistently by enabling it with
+                <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
+                <command>enable</command> command.</para>
+
+                <para><filename>systemd-debug-generator</filename>
+                implements the <ulink
+                url="http://www.freedesktop.org/wiki/Software/systemd/Generators">generator
+                specification</ulink>.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>kernel-command-line</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd-escape.xml b/man/systemd-escape.xml
new file mode 100644 (file)
index 0000000..b2a4a9c
--- /dev/null
@@ -0,0 +1,193 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd-escape"
+          xmlns:xi="http://www.w3.org/2001/XInclude">
+
+        <refentryinfo>
+                <title>systemd-escape</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-escape</refentrytitle>
+                <manvolnum>1</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-escape</refname>
+                <refpurpose>Escape strings for usage in system unit names</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <cmdsynopsis>
+                        <command>systemd-escape <arg choice="opt" rep="repeat">OPTIONS</arg> <arg choice="opt" rep="repeat">STRING</arg></command>
+                </cmdsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><command>systemd-escape</command> may be used to
+                escape strings for inclusion in systemd unit
+                names. The command may be used to escape and to undo
+                escaping of strings.</para>
+
+                <para>The command takes any number of strings on the
+                command line, and will process them individually, one
+                after the other. It will output them separated by
+                spaces to stdout.</para>
+
+                <para>By default this command will escape the strings
+                passed, unless <option>--unescape</option> is passed
+                which results in the inverse operation being
+                applied. If <option>--mangle</option> a special mode
+                of escaping is applied instead, which assumes a string
+                to be already escaped but will escape everything that
+                appears obviously non-escaped.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>The following options are understood:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><option>--suffix=</option></term>
+
+                                <listitem><para>Appends the specified
+                                unit type suffix to the escaped
+                                string. Takes one of the unit types
+                                supported by systemd, such as
+                                <literal>.service</literal> or
+                                <literal>.mount</literal>. May not be
+                                used in conjunction with
+                                <option>--template=</option>,
+                                <option>--unescape</option> or
+                                <option>--mangle</option>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--template=</option></term>
+
+                                <listitem><para>Inserts the escaped
+                                strings in a unit name template. Takes
+                                a unit name template such as
+                                <filename>foobar@.service</filename>
+                                May not be used in conjunction with
+                                <option>--suffix=</option>,
+                                <option>--unescape</option> or
+                                <option>--mangle</option>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--path</option></term>
+                                <term><option>-p</option></term>
+
+                                <listitem><para>When escaping or
+                                unescaping a string, assume it refers
+                                to a file system path. This enables
+                                special processing of the initial
+                                <literal>/</literal> of the
+                                path.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--unescape</option></term>
+
+                                <listitem><para>Instead of escaping
+                                the specified strings, undo the
+                                escaping, reversing the operation. May
+                                not be used in conjunction with
+                                <option>--suffix=</option>,
+                                <option>--template=</option> or
+                                <option>--mangle</option>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--mangle</option></term>
+
+                                <listitem><para>Like
+                                <option>--escape</option>, but only
+                                escape characters that are obviously
+                                not escaped yet, and possibly
+                                automatically append an appropriate
+                                unit type suffix to the string. May
+                                not be used in conjunction with
+                                <option>--suffix=</option>,
+                                <option>--template=</option> or
+                                <option>--unescape</option>.</para></listitem>
+                        </varlistentry>
+
+                        <xi:include href="standard-options.xml" xpointer="help" />
+                        <xi:include href="standard-options.xml" xpointer="version" />
+                </variablelist>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Examples</title>
+
+                <para>Escape a single string:</para>
+                <programlisting>$ systemd-escape 'Hallöchen, Meister'
+Hall\xc3\xb6chen\x2c\x20Meister</programlisting>
+
+                <para>To undo escaping on a single string:</para>
+                <programlisting>$ systemd-escape -u 'Hall\xc3\xb6chen\x2c\x20Meister'
+Hallöchen, Meister</programlisting>
+
+                <para>To generate the mount unit for a path:</para>
+                <programlisting>$ systemd-escape -p --suffix=mount "/tmp//waldi/foobar/"
+tmp-waldi-foobar.mount</programlisting>
+
+                <para>To generate instance names of three strings</para>
+                <programlisting>$ systemd-escape --template=systemd-nspawn@.service 'My Container 1' 'containerb' 'container/III'
+systemd-nspawn@My\x20Container\x201.service systemd-nspawn@containerb.service systemd-nspawn@container-III.service</programlisting>
+        </refsect1>
+
+        <refsect1>
+                <title>Exit status</title>
+
+                <para>On success, 0 is returned, a non-zero failure
+                code otherwise.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd-firstboot.xml b/man/systemd-firstboot.xml
new file mode 100644 (file)
index 0000000..5da0a75
--- /dev/null
@@ -0,0 +1,286 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd-firstboot"
+          xmlns:xi="http://www.w3.org/2001/XInclude">
+
+        <refentryinfo>
+                <title>systemd-firstboot</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-firstboot</refentrytitle>
+                <manvolnum>1</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-firstboot</refname>
+                <refname>systemd-firstboot.service</refname>
+                <refpurpose>Initialize basic system settings on or before the first boot-up of a system</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <cmdsynopsis>
+                        <command>systemd-firstboot</command>
+                        <arg choice="opt" rep="repeat">OPTIONS</arg>
+                </cmdsynopsis>
+
+                <para><filename>systemd-firstboot.service</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><command>systemd-firstboot</command> initializes
+                the most basic system settings interactively on the
+                first boot, or optionally non-interactively when a
+                system image is created. The following settings may be
+                set up:</para>
+
+                <itemizedlist>
+                        <listitem><para>The system locale, more
+                        specifically the two locale variables
+                        <varname>LANG=</varname> and
+                        <varname>LC_MESSAGES</varname></para></listitem>
+
+                        <listitem><para>The system time zone</para></listitem>
+
+                        <listitem><para>The system host name</para></listitem>
+
+                        <listitem><para>The machine ID of the system</para></listitem>
+
+                        <listitem><para>The root user's password</para></listitem>
+                </itemizedlist>
+
+                <para>Each of the fields may either be queried
+                interactively from the users, set non-interactively on
+                the tool's command line, or be copied from a host
+                system that is used to set up the system image.</para>
+
+                <para>If a setting is already initialized it will not
+                be overwritten and the user will not be prompted for
+                the setting.</para>
+
+                <para>Note that this tool operates directly on the
+                file system and does not involve any running system
+                services, unlike
+                <citerefentry><refentrytitle>localectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                <citerefentry><refentrytitle>timedatectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                or
+                <citerefentry><refentrytitle>hostnamectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>. This
+                allows <command>systemd-firstboot</command> to operate
+                on mounted but not booted disk images and in early
+                boot. It is not recommended to use
+                <command>systemd-firsboot</command> on the running
+                system while it is up.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>The following options are understood:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><option>--root=<replaceable>root</replaceable></option></term>
+                                <listitem><para>Takes a directory path
+                                as an argument. All paths will be
+                                prefixed with the given alternate
+                                <replaceable>root</replaceable> path,
+                                including config search paths. This is
+                                useful to operate on a system image
+                                mounted to the specified directory
+                                instead of the host system itself.
+                                </para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--locale=<replaceable>LOCALE</replaceable></option></term>
+                                <term><option>--locale-messages=<replaceable>LOCALE</replaceable></option></term>
+
+                                <listitem><para>Sets the system
+                                locale, more specifically the
+                                <varname>LANG=</varname> and
+                                <varname>LC_MESSAGES</varname>
+                                settings. The argument should be a
+                                valid locale identifier, such as
+                                <literal>de_DE.UTF-8</literal>. This
+                                controls the
+                                <citerefentry><refentrytitle>locale.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                                configuration file.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--timezone=<replaceable>TIMEZONE</replaceable></option></term>
+
+                                <listitem><para>Sets the system time
+                                zone. The argument should be a valid
+                                time zone identifier, such as
+                                <literal>Europe/Berlin</literal>. This
+                                controls the
+                                <citerefentry><refentrytitle>localtime</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                                symlink.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--hostname=<replaceable>HOSTNAME</replaceable></option></term>
+
+                                <listitem><para>Sets the system
+                                hostname. The argument should be a
+                                host name, compatible with DNS. This
+                                controls the
+                                <citerefentry><refentrytitle>hostname</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                                configuration file.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--machine-id=<replaceable>ID</replaceable></option></term>
+
+                                <listitem><para>Sets the system's machine ID. This
+                                controls the
+                                <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                                file.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--root-password=<replaceable>PASSWORD</replaceable></option></term>
+                                <term><option>--root-password-file=<replaceable>PATH</replaceable></option></term>
+
+                                <listitem><para>Sets the password of
+                                the system's root user. This creates a
+                                <citerefentry><refentrytitle>shadow</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                                file. This setting exists in two
+                                forms:
+                                <option>--root-password=</option>
+                                accepts the password to set directly
+                                on the command line,
+                                <option>--root-password-file=</option>
+                                reads it from a file. Note that
+                                it is not recommended specifying
+                                passwords on the command line as other
+                                users might be able to see them
+                                simply by invoking
+                                <citerefentry><refentrytitle>ps</refentrytitle><manvolnum>1</manvolnum></citerefentry>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--prompt-locale</option></term>
+                                <term><option>--prompt-timezone</option></term>
+                                <term><option>--prompt-hostname</option></term>
+                                <term><option>--prompt-root-password</option></term>
+
+                                <para>Prompt the user interactively
+                                for a specific basic setting. Note
+                                that any explicit configuration
+                                settings specified on the command line
+                                take precedence, and the user is not
+                                prompted for it.</para>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--prompt</option></term>
+
+                                <para>Query the user for locale,
+                                timezone, hostname and root
+                                password. This is equivalent to
+                                specifying
+                                <option>--prompt-locale</option>,
+                                <option>--prompt-timezone</option>,
+                                <option>--prompt-hostname</option>,
+                                <option>--prompt-root-password</option>
+                                in combination.</para>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--copy-locale</option></term>
+                                <term><option>--copy-timezone</option></term>
+                                <term><option>--copy-root-password</option></term>
+
+                                <para>Copy a specific basic setting
+                                from the host. This only works in
+                                combination with
+                                <option>--root=</option> (see
+                                above).</para>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--copy</option></term>
+
+                                <para>Copy locale, time zone and root
+                                password from the host. This is
+                                equivalent to specifying
+                                <option>--copy-locale</option>,
+                                <option>--copy-timezone</option>,
+                                <option>--copy-root-password</option>
+                                in combination.</para>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>--setup-machine-id</option></term>
+
+                                <para>Initialize the system's machine
+                                ID to a random ID. This only works in
+                                combination with
+                                <option>--root=</option>.</para>
+                        </varlistentry>
+
+                        <xi:include href="standard-options.xml" xpointer="help" />
+                        <xi:include href="standard-options.xml" xpointer="version" />
+                </variablelist>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Exit status</title>
+
+                <para>On success, 0 is returned, a non-zero failure
+                code otherwise.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>locale.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>localtime</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>hostname</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>shadow</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-machine-id-setup</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>localectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>timedatectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>hostnamectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
index c653dc5..ee66f37 100644 (file)
         <refsect1>
                 <title>Description</title>
 
-                <para><filename>systemd-fsck@.service</filename> is a
-                service responsible for file system checks. It is
-                instantiated for each device that requires a file
-                system
-                check. <filename>systemd-fsck-root.service</filename> is
-                responsible for file system checks on the root
-                file system. The root file system check is performed
-                before the other file systems. Either service is enabled
-                at boot if passno in <filename>/etc/fstab</filename> for
-                the file system is set to a value greater than zero.</para>
-
-                <para><filename>systemd-fsck</filename> will
-                forward file system checking progress to the
-                console. If a file system check fails, emergency mode
-                is activated, by isolating to
+                <para><filename>systemd-fsck@.service</filename> and
+                <filename>systemd-fsck-root.service</filename> are
+                services responsible for file system checks. They are
+                instantiated for each device that is configured for
+                file system checking.
+                <filename>systemd-fsck-root.service</filename> is
+                responsible for file system checks on the root file
+                system, but in only if the root filesystem wasn't
+                checked in the initramfs.
+                <filename>systemd-fsck@.service</filename> is used for
+                all other file systems and for the root file system in
+                the initramfs.</para>
+
+                <para>Those services are started at boot if
+                <option>passno</option> in
+                <filename>/etc/fstab</filename> for the file system is
+                set to a value greater than zero. The file system
+                check for root is performed before the other file
+                systems. Other file systems may be checked in
+                parallel, except when they are one the same rotating
+                disk.</para>
+
+                <para><filename>systemd-fsck</filename> does not know
+                any details about specific filesystems, and simply
+                executes file system checkers specific to each
+                filesystem type (<filename>/sbin/fsck.*</filename>).
+                This helper will decide if the filesystem should
+                actually be checked based on the time since last
+                check, number of mounts, unclean unmount, etc.</para>
+
+                <para><filename>systemd-fsck</filename> will forward
+                file system checking progress to the console. If a
+                file system check fails for a service without
+                <option>nofail</option>, emergency mode is activated,
+                by isolating to
                 <filename>emergency.target</filename>.</para>
         </refsect1>
 
                                 skips any file system
                                 checks.</para></listitem>
                         </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>fsck.repair=</varname></term>
+
+                                <listitem><para>One of
+                                <literal>preen</literal>,
+                                <literal>yes</literal>,
+                                <literal>no</literal>. Controls the
+                                mode of operation. The default is <literal>
+                                preen</literal>, and will automatically repair
+                                problems that can be safely fixed. <literal>yes
+                                </literal> will answer yes to all questions by
+                                fsck and <literal>no</literal> will answer no to
+                                all questions.
+                                </para></listitem>
+                        </varlistentry>
                 </variablelist>
         </refsect1>
 
                 <para>
                         <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>fsck</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>systemd-quotacheck.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                        <citerefentry><refentrytitle>systemd-quotacheck.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>fsck.btrfs</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>fsck.cramfs</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>fsck.ext4</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>fsck.fat</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>fsck.hfsplus</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>fsck.minix</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>fsck.ntfs</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>fsck.xfs</refentrytitle><manvolnum>8</manvolnum></citerefentry>
                 </para>
         </refsect1>
 
index 2f3d124..f6a6689 100644 (file)
@@ -94,7 +94,7 @@
                 <title>See Also</title>
                 <para>
                         <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>agetty</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                        <citerefentry project='man-pages'><refentrytitle>agetty</refentrytitle><manvolnum>8</manvolnum></citerefentry>
                 </para>
         </refsect1>
 
index 95c0c35..68fe270 100644 (file)
@@ -43,7 +43,8 @@
         <refnamediv>
                 <refname>systemd-gpt-auto-generator</refname>
                 <refpurpose>Generator for automatically discovering
-                and mounting <filename>/home</filename> as well as
+                and mounting root, <filename>/home</filename> and
+                <filename>/srv</filename> partitions, as well as
                 discovering and enabling swap partitions, based on GPT
                 partition type GUIDs.</refpurpose>
         </refnamediv>
                 <title>Description</title>
 
                 <para><filename>systemd-gpt-auto-generator</filename>
-                is a generator that automatically discovers
-                <filename>/home</filename> and swap partitions and
-                creates mount and swap units for them, based on the
-                the partition type GUIDs of GUID partition tables
-                (GPT). Note that this generator will execute no
-                operation on non-GPT systems, on systems where the
-                units are explicitly configured (for example, listed
-                in
-                <citerefentry><refentrytitle>fstab</refentrytitle><manvolnum>5</manvolnum></citerefentry>)
-                or where the mount point is non-empty.</para>
-
-                <para>This generator will only look for partitions on
-                the same physical disk the root file system is stored
-                on. This generator has no effect on systems where the
-                root file system is distributed on multiple disks, for
-                example via btrfs RAID.</para>
-
-                <para>This generator is useful for centralizing file
-                system configuration in the partition table and making
-                manual configuration in
-                <filename>/etc/fstab</filename> or suchlike
+                is a unit generator that automatically discovers root,
+                <filename>/home</filename>, <filename>/srv</filename>
+                and swap partitions and creates mount and swap units
+                for them, based on the partition type GUIDs of
+                GUID partition tables (GPT). It implements the <ulink
+                url="http://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/">Discoverable
+                Partitions Specification</ulink>. Note that this
+                generator has no effect on non-GPT systems, on systems
+                where the units are explicitly configured (for
+                example, listed in
+                <citerefentry><refentrytitle>fstab</refentrytitle><manvolnum>5</manvolnum></citerefentry>),
+                or where the mount points are non-empty.</para>
+
+                <para>This generator will only look for root
+                partitions on the same physical disk the EFI System
+                Partition (ESP) is located on. It will only look for
+                the other partitions on the same physical disk the
+                root file system is located on. These partitions will
+                not be searched on systems where the root file system is
+                distributed on multiple disks, for example via btrfs
+                RAID.</para>
+
+                <para><filename>systemd-gpt-auto-generator</filename>
+                is useful for centralizing file system configuration
+                in the partition table and making manual configuration
+                in <filename>/etc/fstab</filename> or suchlike
                 unnecessary.</para>
 
-                <para>This generator looks for swap partitions using
-                GPT type 0657fd6d-a4ab-43c4-84e50933c84b4f4f. It looks
-                for <filename>/home</filename> partitions using GPT
-                type 933ac7e1-2eb4-4f13-b8440e14e2aef915.</para>
+                <para>This generator looks for the partitions based on
+                their partition type GUID. The following partition
+                type GUIDs are identified:</para>
+
+                <table>
+                        <title>Partition Type GUIDs</title>
+                        <tgroup cols='3' align='left' colsep='1' rowsep='1'>
+                                <colspec colname="guid" />
+                                <colspec colname="name" />
+                                <colspec colname="explanation" />
+                                <thead>
+                                        <row>
+                                                <entry>Partition Type GUID</entry>
+                                                <entry>Name</entry>
+                                                <entry>Explanation</entry>
+                                        </row>
+                                </thead>
+                                <tbody>
+                                        <row>
+                                                <entry>44479540-f297-41b2-9af7-d131d5f0458a</entry>
+                                                <entry><filename>Root Partition (x86)</filename></entry>
+                                                <entry>On 32-bit x86 systems, the first x86 root partition on the disk the EFI ESP is located on is mounted to the root directory <filename>/</filename>.</entry>
+                                        </row>
+                                        <row>
+                                                <entry>4f68bce3-e8cd-4db1-96e7-fbcaf984b709</entry>
+                                                <entry><filename>Root Partition (x86-64)</filename></entry>
+                                                <entry>On 64-bit x86 systems, the first x86-64 root partition on the disk the EFI ESP is located on is mounted to the root directory <filename>/</filename>.</entry>
+                                        </row>
+                                        <row>
+                                                <entry>69dad710-2ce4-4e3c-b16c-21a1d49abed3</entry>
+                                                <entry><filename>Root Partition (32-bit ARM)</filename></entry>
+                                                <entry>On 32-bit ARM systems, the first ARM root partition on the disk the EFI ESP is located on is mounted to the root directory <filename>/</filename>.</entry>
+                                        </row>
+                                        <row>
+                                                <entry>b921b045-1df0-41c3-af44-4c6f280d3fae</entry>
+                                                <entry><filename>Root Partition (64-bit ARM)</filename></entry>
+                                                <entry>On 64-bit ARM systems, the first ARM root partition on the disk the EFI ESP is located on is mounted to the root directory <filename>/</filename>.</entry>
+                                        </row>
+                                        <row>
+                                                <entry>933ac7e1-2eb4-4f13-b844-0e14e2aef915</entry>
+                                                <entry>Home Partition</entry>
+                                                <entry>The first home partition on the disk the root partition is located on is mounted to <filename>/home</filename>.</entry>
+                                        </row>
+                                        <row>
+                                                <entry>3b8f8425-20e0-4f3b-907f-1a25a76f98e8</entry>
+                                                <entry>Server Data Partition</entry>
+                                                <entry>The first server data partition on the disk the root partition is located on is mounted to <filename>/srv</filename>.</entry>
+                                        </row>
+                                        <row>
+                                                <entry>0657fd6d-a4ab-43c4-84e5-0933c84b4f4f</entry>
+                                                <entry>Swap</entry>
+                                                <entry>All swap partitions located on the disk the root partition is located on are enabled.</entry>
+                                        </row>
+                                </tbody>
+                        </tgroup>
+                </table>
+
+                <para>The <filename>/home</filename> and
+                <filename>/srv</filename> partitions may be encrypted
+                in LUKS format. In this case a device mapper device is
+                set up under the names
+                <filename>/dev/mapper/home</filename> and
+                <filename>/dev/mapper/srv</filename>. Note that this
+                might create conflicts if the same partition is listed
+                in <filename>/etc/crypttab</filename> with a different
+                device mapper device name.</para>
+
+                <para>Also note that
+                <citerefentry><refentrytitle>systemd-efi-boot-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                will mount the EFI System Partition (ESP) to
+                <filename>/boot</filename> if not otherwise mounted.</para>
+
+                <para>When using this generator in conjunction with
+                btrfs file systems, make sure to set the correct
+                default subvolumes on them, using <command>btrfs
+                subvolume set-default</command>.</para>
 
                 <para><filename>systemd-gpt-auto-generator</filename>
                 implements the <ulink
-                url="http://www.freedesktop.org/wiki/Software/systemd/Generators">generator
-                specification</ulink>.</para>
+                url="http://www.freedesktop.org/wiki/Software/systemd/Generators">Generator
+                Specification</ulink>.</para>
         </refsect1>
 
         <refsect1>
                         <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>systemd.mount</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>systemd.swap</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>systemd-efi-boot-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>fstab</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                        <citerefentry><refentrytitle>systemd-cryptsetup@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>cryptsetup</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>fstab</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>btrfs</refentrytitle><manvolnum>8</manvolnum></citerefentry>
                 </para>
         </refsect1>
 
index 555c541..c694744 100644 (file)
 
                 <para>This burns the ISO image
                 <filename>foobar.iso</filename> on a CD using
-                <citerefentry><refentrytitle>wodim</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                <citerefentry project='man-pages'><refentrytitle>wodim</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                 and inhibits system sleeping, shutdown and idle while
                 doing so.</para>
         </refsect1>
diff --git a/man/systemd-journal-remote.xml b/man/systemd-journal-remote.xml
new file mode 100644 (file)
index 0000000..08c0283
--- /dev/null
@@ -0,0 +1,315 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+This file is part of systemd.
+
+Copyright 2012 Zbigniew Jędrzejewski-Szmek
+
+systemd is free software; you can redistribute it and/or modify it
+under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+systemd is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd-journal-remote" conditional='HAVE_MICROHTTPD'
+          xmlns:xi="http://www.w3.org/2001/XInclude">
+
+  <refentryinfo>
+    <title>systemd-journal-remote</title>
+    <productname>systemd</productname>
+
+    <authorgroup>
+      <author>
+        <contrib>Developer</contrib>
+        <firstname>Zbigniew</firstname>
+        <surname>Jędrzejewski-Szmek</surname>
+        <email>zbyszek@in.waw.pl</email>
+      </author>
+    </authorgroup>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>systemd-journal-remote</refentrytitle>
+    <manvolnum>8</manvolnum>
+  </refmeta>
+
+  <refnamediv>
+    <refname>systemd-journal-remote</refname>
+    <refpurpose>Receive journal messages over the network</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <cmdsynopsis>
+      <command>systemd-journal-remote</command>
+      <arg choice="opt" rep="repeat">OPTIONS</arg>
+      <arg choice="opt" rep="norepeat">-o/--output=<replaceable>DIR</replaceable>|<replaceable>FILE</replaceable></arg>
+      <arg choice="opt" rep="repeat">SOURCES</arg>
+    </cmdsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>
+      <filename>systemd-journal-remote</filename> is a command to
+      receive serialized journal events and store them to the journal.
+      Input streams are in the
+      <ulink url="http://www.freedesktop.org/wiki/Software/systemd/export">
+        Journal Export Format
+      </ulink>,
+      i.e. like the output from
+      <command>journalctl --output=export</command>. For transport over
+      the network, this serialized stream is usually carried over an
+      HTTPS connection.
+    </para>
+  </refsect1>
+
+  <refsect1>
+    <title>Sources</title>
+
+    <para>
+      Sources can be either "active"
+      (<command>systemd-journal-remote</command> requests and pulls
+      the data), or "passive"
+      (<command>systemd-journal-remote</command> waits for a
+      connection and then receives events pushed by the other side).
+    </para>
+
+    <para>
+      <command>systemd-journal-remote</command> can read more than one
+      event stream at a time. They will be interleaved in the output
+      file. In case of "active" connections, each "source" is one
+      stream, and in case of "passive" connections, each connection can
+      result in a separate stream. Sockets can be configured in
+      "accept" mode (i.e. only one connection), or "listen" mode (i.e.
+      multiple connections, each resulting in a stream).
+    </para>
+
+    <para>
+      When there are no more connections, and no more can be created
+      (there are no listening sockets), then
+      <command>systemd-journal-remote</command> will exit.
+    </para>
+
+    <para>Active sources can be specified in the following
+    ways:</para>
+
+    <variablelist>
+      <varlistentry>
+        <listitem><para>When <option>-</option> is given as a
+        positional argument, events will be read from standard input.
+        Other positional arguments will be treated as filenames
+        to open and read from.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>--url=<replaceable>ADDRESS</replaceable></option></term>
+
+        <listitem><para>With the
+        <option>--url=<replaceable>ADDRESS</replaceable></option> option,
+        events will be retrieved using HTTP from
+        <replaceable>ADDRESS</replaceable>. This URL should refer to the
+        root of a remote
+        <citerefentry><refentrytitle>systemd-journal-gatewayd</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+        instance (e.g. <ulink>http://some.host:19531/</ulink> or
+        <ulink>https://some.host:19531/</ulink>).</para></listitem>
+      </varlistentry>
+    </variablelist>
+
+    <para>Passive sources can be specified in the following
+    ways:</para>
+
+    <variablelist>
+      <varlistentry>
+        <term><option>--listen-raw=<replaceable>ADDRESS</replaceable></option></term>
+
+        <listitem><para><replaceable>ADDRESS</replaceable> must be an
+        address suitable for <option>ListenStream=</option> (cf.
+        <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>).
+        <command>systemd-journal-remote</command> will listen on this
+        socket for connections. Each connection is expected to be a
+        stream of journal events.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>--listen-http=<replaceable>ADDRESS</replaceable></option></term>
+        <term><option>--listen-https=<replaceable>ADDRESS</replaceable></option></term>
+
+        <listitem><para><replaceable>ADDRESS</replaceable> must be
+        either a negative integer, in which case it will be
+        interpreted as the (negated) file descriptor number, or an
+        address suitable for <option>ListenStream=</option> (c.f.
+        <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>).
+        In the first case, matching file descriptor must be inherited
+        through
+        <varname>$LISTEN_FDS</varname>/<varname>$LISTEN_PID</varname>.
+        In the second case, an HTTP or HTTPS server will be spawned on
+        this port, respectively for <option>--listen-http</option> and
+        <option>--listen-https</option>. Currenntly, only POST requests
+        to <filename>/upload</filename> with <literal>Content-Type:
+        application/vnd.fdo.journal</literal> are supported.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>$LISTEN_FDS</varname></term>
+
+        <listitem><para><command>systemd-journal-remote</command>
+        supports the
+        <varname>$LISTEN_FDS</varname>/<varname>$LISTEN_PID</varname>
+        protocol. Open sockets inherited through socket activation
+        behave like those opened with <option>--listen-raw=</option>
+        described above, unless they are specified as an argument in
+        <option>--listen-http=-<replaceable>n</replaceable></option>
+        or
+        <option>--listen-https=-<replaceable>n</replaceable></option>
+        above. In the latter case, an HTTP or HTTPS server will be
+        spawned using this descriptor and connections must be made
+        over the HTTP protocol.</para>
+        </listitem>
+      </varlistentry>
+
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Sinks</title>
+
+    <para>The location of the output journal can be specified
+    with <option>-o</option> or <option>--output=</option>. For "active"
+    sources, this option is required.
+    </para>
+
+    <variablelist>
+      <varlistentry>
+        <term><option>--output=<replaceable>FILE</replaceable></option></term>
+
+        <listitem><para>Will write to this journal file. The filename
+        must end with <filename>.journal</filename>. The file will be
+        created if it does not exist. If necessary (journal file full,
+        or corrupted), the file will be renamed following normal
+        journald rules and a new journal file will be created in its
+        stead.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>--output=<replaceable>DIR</replaceable></option></term>
+
+        <listitem><para>Will create journal files underneath directory
+        <replaceable>DIR</replaceable>. The directory must exist. If
+        necessary (journal files over size, or corrupted), journal
+        files will be rotated following normal journald rules. Names
+        of files underneath <replaceable>DIR</replaceable> will be
+        generated using the rules described below.</para></listitem>
+      </varlistentry>
+    </variablelist>
+
+    <para>If <option>--output=</option> is not used, the output
+    directory <filename>/var/log/journal/remote/</filename> will be
+    used.  In case the output file is not specified, journal files
+    will be created underneath the selected directory. Files will be
+    called
+    <filename>remote-<replaceable>hostname</replaceable>.journal</filename>,
+    where the <replaceable>hostname</replaceable> part is the
+    escaped hostname of the source endpoint of the connection, or the
+    numerical address if the hostname cannot be determined.</para>
+
+    <para>In case of "active" sources, the output file name must
+    always be given explicitly.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>Options</title>
+
+    <para>The following options are understood:</para>
+
+    <variablelist>
+      <varlistentry>
+        <term><option>--split-mode</option></term>
+
+        <listitem><para>One of <constant>none</constant> or
+        <constant>host</constant>. For the first, only one output
+        journal file is used. For the latter, a separate output file
+        is used, based on the hostname of the other endpoint of a
+        connection.</para>
+
+        <para>In case of "active" sources, the output file name must
+        always be given explicitly and only <constant>none</constant>
+        is allowed.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>--compress</option></term>
+        <term><option>--no-compress</option></term>
+
+        <listitem><para>Compress or not, respectively, the data in the
+        journal using XZ.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>--seal</option></term>
+        <term><option>--no-seal</option></term>
+
+        <listitem><para>Periodically sign or not, respectively, the
+        data in the journal using Forward Secure Sealing.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>--getter=<replaceable>PROG --option1 --option2</replaceable></option></term>
+
+        <listitem><para>Program to invoke to retrieve data. The journal
+        event stream must be generated on standard output.</para>
+
+        <para>Examples:</para>
+
+        <programlisting>--getter='curl "-HAccept: application/vnd.fdo.journal" https://some.host:19531/'</programlisting>
+
+        <programlisting>--getter='wget --header="Accept: application/vnd.fdo.journal" -O- https://some.host:19531/'</programlisting>
+        </listitem>
+      </varlistentry>
+
+      <xi:include href="standard-options.xml" xpointer="help" />
+      <xi:include href="standard-options.xml" xpointer="version" />
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Examples</title>
+    <para>Copy local journal events to a different journal directory:
+    <programlisting>
+journalctl -o export | systemd-journal-remote -o /tmp/dir -
+    </programlisting>
+    </para>
+
+    <para>Retrieve events from a remote
+    <citerefentry><refentrytitle>systemd-journal-gatewayd</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+    instance and store them in
+    <filename>/var/log/journal/some.host/remote-some~host.journal</filename>:
+    <programlisting>
+systemd-journal-remote --url http://some.host:19531/
+    </programlisting>
+    </para>
+  </refsect1>
+
+  <refsect1>
+    <title>See Also</title>
+    <para>
+      <citerefentry><refentrytitle>systemd-journal-upload</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>systemd-journald.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>systemd-journal-gatewayd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+    </para>
+  </refsect1>
+</refentry>
diff --git a/man/systemd-journal-upload.xml b/man/systemd-journal-upload.xml
new file mode 100644 (file)
index 0000000..ca251c6
--- /dev/null
@@ -0,0 +1,193 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+This file is part of systemd.
+
+Copyright 2014 Zbigniew Jędrzejewski-Szmek
+
+systemd is free software; you can redistribute it and/or modify it
+under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+systemd is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd-journal-upload" conditional='HAVE_MICROHTTPD'
+          xmlns:xi="http://www.w3.org/2001/XInclude">
+
+  <refentryinfo>
+    <title>systemd-journal-upload</title>
+    <productname>systemd</productname>
+
+    <authorgroup>
+      <author>
+        <contrib>Developer</contrib>
+        <firstname>Zbigniew</firstname>
+        <surname>Jędrzejewski-Szmek</surname>
+        <email>zbyszek@in.waw.pl</email>
+      </author>
+    </authorgroup>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>systemd-journal-upload</refentrytitle>
+    <manvolnum>8</manvolnum>
+  </refmeta>
+
+  <refnamediv>
+    <refname>systemd-journal-upload</refname>
+    <refpurpose>Send journal messages over the network</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <cmdsynopsis>
+      <command>systemd-journal-upload</command>
+      <arg choice="opt" rep="repeat">OPTIONS</arg>
+      <arg choice="opt" rep="norepeat">-u/--url=<replaceable>URL</replaceable></arg>
+      <arg choice="opt" rep="repeat">SOURCES</arg>
+    </cmdsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>
+      <command>systemd-journal-upload</command> will upload journal
+      entries to the URL specified with <option>--url</option>. Unless
+      limited by one of the options specified below, all journal
+      entries accessible to the user the program is running as will be
+      uploaded, and then the program will wait and send new entries
+      as they become available.
+    </para>
+  </refsect1>
+
+  <refsect1>
+    <title>Options</title>
+
+    <variablelist>
+      <varlistentry>
+        <term><option>-u</option></term>
+        <term><option>--url=<optional>https://</optional><replaceable>URL</replaceable></option></term>
+        <term><option>--url=<optional>http://</optional><replaceable>URL</replaceable></option></term>
+
+        <listitem><para>Upload to the specified
+        address. <replaceable>URL</replaceable> may specify either
+        just the hostname or both the protocol and
+        hostname. <constant>https</constant> is the default.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>--system</option></term>
+        <term><option>--user</option></term>
+
+        <listitem><para>Limit uploaded entries to entries from system
+        services and the kernel, or to entries from services of
+        current user. This has the same meaning as
+        <option>--system</option> and <option>--user</option> options
+        for
+        <citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>. If
+        neither is specified, all accessible entries are uploaded.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>-m</option></term>
+        <term><option>--merge</option></term>
+
+        <listitem><para>Upload entries interleaved from all available
+        journals, including other machines. This has the same meaning
+        as <option>--merge</option> option for
+        <citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>-D</option></term>
+        <term><option>--directory=<replaceable>DIR</replaceable></option></term>
+
+        <listitem><para>Takes a directory path as argument. Upload
+        entries from the specified journal directory
+        <replaceable>DIR</replaceable> instead of the default runtime
+        and system journal paths. This has the same meaning as
+        <option>--directory</option> option for
+        <citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>--file=<replaceable>GLOB</replaceable></option></term>
+
+        <listitem><para>Takes a file glob as an argument. Upload
+        entries from the specified journal files matching
+        <replaceable>GLOB</replaceable> instead of the default runtime
+        and system journal paths. May be specified multiple times, in
+        which case files will be suitably interleaved. This has the same meaning as
+        <option>--file</option> option for
+        <citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>--cursor=</option></term>
+
+        <listitem><para>Upload entries from the location in the
+        journal specified by the passed cursor. This has the same
+        meaning as <option>--cursor</option> option for
+        <citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>--after-cursor=</option></term>
+
+        <listitem><para>Upload entries from the location in the
+        journal <emphasis>after</emphasis> the location specified by
+        the this cursor.  This has the same meaning as
+        <option>--after-cursor</option> option for
+        <citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
+        </para></listitem>
+      </varlistentry>
+
+
+      <varlistentry>
+        <term><option>--save-state</option><optional>=<replaceable>PATH</replaceable></optional></term>
+
+        <listitem><para>Upload entries from the location in the
+        journal <emphasis>after</emphasis> the location specified by
+        the cursor saved in file at <replaceable>PATH</replaceable>
+        (<filename>/var/lib/systemd/journal-upload/state</filename> by default).
+        After an entry is successfully uploaded, update this file
+        with the cursor of that entry.
+        </para></listitem>
+      </varlistentry>
+
+      <xi:include href="standard-options.xml" xpointer="help" />
+      <xi:include href="standard-options.xml" xpointer="version" />
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Exit status</title>
+
+    <para>On success, 0 is returned; otherwise, a non-zero
+    failure code is returned.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>See Also</title>
+    <para>
+      <citerefentry><refentrytitle>systemd-journal-remote</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>systemd-journald.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>systemd-journal-gatewayd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+    </para>
+  </refsect1>
+</refentry>
index 4d2cb40..1f1a7f1 100644 (file)
@@ -45,6 +45,7 @@
         <refnamediv>
                 <refname>systemd-journald.service</refname>
                 <refname>systemd-journald.socket</refname>
+                <refname>systemd-journald-dev-log.socket</refname>
                 <refname>systemd-journald</refname>
                 <refpurpose>Journal service</refpurpose>
         </refnamediv>
@@ -52,6 +53,7 @@
         <refsynopsisdiv>
                 <para><filename>systemd-journald.service</filename></para>
                 <para><filename>systemd-journald.socket</filename></para>
+                <para><filename>systemd-journald-dev-log.socket</filename></para>
                 <para><filename>/usr/lib/systemd/systemd-journald</filename></para>
         </refsynopsisdiv>
 
@@ -63,7 +65,7 @@
                 It creates and maintains structured, indexed journals
                 based on logging information that is received from the
                 kernel, from user processes via the libc
-                <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                <citerefentry project='man-pages'><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                 call, from standard input and standard error of system
                 services or via its native API. It will implicitly
                 collect numerous metadata fields for each log
                                 <term><varname>systemd.journald.forward_to_syslog=</varname></term>
                                 <term><varname>systemd.journald.forward_to_kmsg=</varname></term>
                                 <term><varname>systemd.journald.forward_to_console=</varname></term>
+                                <term><varname>systemd.journald.forward_to_wall=</varname></term>
 
                                 <listitem><para>Enables/disables
                                 forwarding of collected log messages
-                                to syslog, the kernel log buffer or
-                                the system console.
+                                to syslog, the kernel log buffer, the
+                                system console or wall.
                                 </para>
 
                                 <para>See
                         <citerefentry><refentrytitle>journald.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>systemd.journal-fields</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>sd-journal</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-coredump</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>setfacl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                         <command>pydoc systemd.journal</command>.
                 </para>
index 5c34b34..28352e3 100644 (file)
                 UUID passed is sufficiently unique and is different
                 for every booted instanced of the VM.</para>
 
-                <para>Similarly, if run inside a Linux container
+                <para>Similar, if run inside a Linux container
                 environment and a UUID is set for the container this
                 is used to initialize the machine ID. For details see
                 the documentation of the <ulink
                 url="http://www.freedesktop.org/wiki/Software/systemd/ContainerInterface">Container
                 Interface</ulink>.</para>
 
+                <para>Use
+                <citerefentry><refentrytitle>systemd-firstboot</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                to initialize the machine ID on mounted (but not
+                booted) system images.</para>
+
         </refsect1>
 
         <refsect1>
                 <para>The following options are understood:</para>
 
                 <variablelist>
+                        <varlistentry>
+                                <term><option>--root=<replaceable>root</replaceable></option></term>
+                                <listitem><para>Takes a directory path
+                                as an argument. All paths will be
+                                prefixed with the given alternate
+                                <replaceable>root</replaceable> path,
+                                including config search paths.
+                                </para></listitem>
+                        </varlistentry>
                         <xi:include href="standard-options.xml" xpointer="help" />
                         <xi:include href="standard-options.xml" xpointer="version" />
                 </variablelist>
                 <para>
                         <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>dbus-uuidgen</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                        <citerefentry><refentrytitle>dbus-uuidgen</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-firstboot</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 </para>
         </refsect1>
 
diff --git a/man/systemd-networkd-wait-online.service.xml b/man/systemd-networkd-wait-online.service.xml
new file mode 100644 (file)
index 0000000..3083588
--- /dev/null
@@ -0,0 +1,96 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2014 Tom Gundersen
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd-networkd-wait-online.service" conditional='ENABLE_NETWORKD'>
+
+        <refentryinfo>
+                <title>systemd-networkd.service</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Tom</firstname>
+                                <surname>Gundersen</surname>
+                                <email>teg@jklm.no</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-networkd-wait-online.service</refentrytitle>
+                <manvolnum>8</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-networkd-wait-online.service</refname>
+                <refname>systemd-networkd-wait-online</refname>
+                <refpurpose>Wait for network to come online</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>systemd-networkd-wait-online.service</filename></para>
+                <para><filename>/usr/lib/systemd/systemd-networkd-wait-online</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><command>systemd-networkd-wait-online</command> is a
+                one-shot system service that waits for the network to be configured.
+                By default, it will wait for all links it is aware of and which are managed by
+                <citerefentry><refentrytitle>systemd-networkd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                to be fully configured or failed, and for at least one link to gain a
+                carrier.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>The following options are understood:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><option>-i</option></term>
+                                <term><option>--interface=</option></term>
+
+                                <listitem><para>Network interface to wait for
+                                before deciding if the system is online. This is
+                                useful when a system has several interfaces which
+                                will be configured, but a particular one is necessary
+                                to access some network resources. This option may be
+                                used more than once to wait for multiple network
+                                interfaces.</para></listitem>
+                        </varlistentry>
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-networkd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
index 2517efc..0570798 100644 (file)
 
                 <para>To configure low-level link settings independently of
                 networks, see
-                <citerefentry><refentrytitle>udev</refentrytitle><manvolnum>7</manvolnum></citerefentry>
-                .</para>
+                <citerefentry><refentrytitle>systemd.link</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
 
                 <para>Network configurations applied before networkd is started
                 are not removed, and static configuration applied by networkd
-                is not removed when networkd exits. This ensures restarting
-                networkd does not cut the network connection, and, in particular,
+                is not removed when networkd exits. Dynamic configuration applied by
+                networkd may also optionally be left in place on shutdown. This ensures
+                restarting networkd does not cut the network connection, and, in particular,
                 that it is safe to transition between the initrd and the real root,
                 and back.</para>
         </refsect1>
                 system network directory <filename>/usr/lib/systemd/network</filename>,
                 the volatile runtime network directory
                 <filename>/run/systemd/network</filename> and the local administration
-                network directory <filename>/etc/systemd/network</filename>.
-                All configuration files are collectively sorted and processed in lexical order,
-                regardless of the directories in which they live. However, files with
-                identical filenames replace each other. Files in
-                <filename>/etc</filename> have the highest priority, files in
-                <filename>/run</filename> take precedence over files with the same
-                name in <filename>/usr/lib</filename>. This can be used to override a
-                system-supplied configuration file with a local file if needed; a symlink in
-                <filename>/etc</filename> with the same name as a configuration file in
-                <filename>/usr/lib</filename>, pointing to <filename>/dev/null</filename>,
-                disables the configuration file entirely.</para>
+                network directory <filename>/etc/systemd/network</filename>.</para>
 
-                <refsect2><title>Virtual Network Devices</title>
-                        <para>Virtual Network Device files must have the extension
-                        <filename>.netdev</filename>; other extensions are ignored. Virtual
-                        network devices are created as soon as networkd is started.</para>
-
-                        <para>A virtual network device is only created if the
-                        <literal>[Match]</literal> section matches the current
-                        environment, or if the section is empty. The following keys are accepted:</para>
-
-                        <variablelist class='network-directives'>
-                                <varlistentry>
-                                        <term><varname>Host=</varname></term>
-                                        <listitem>
-                                                <para>Matches against the hostname or machine ID of the
-                                                host. See <literal>ConditionHost=</literal> in
-                                                <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
-                                                for details.
-                                                </para>
-                                        </listitem>
-                                </varlistentry>
-                                <varlistentry>
-                                        <term><varname>Virtualization=</varname></term>
-                                        <listitem>
-                                                <para>Checks whether the system is executed in a virtualized
-                                                environment and optionally test whether it is a specific
-                                                implementation. See <literal>ConditionVirtualization=</literal> in
-                                                <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
-                                                for details.
-                                                </para>
-                                        </listitem>
-                                </varlistentry>
-                                <varlistentry>
-                                        <term><varname>KernelCommandLine=</varname></term>
-                                        <listitem>
-                                                <para>Checks whether a specific kernel command line option is
-                                                set (or if prefixed with the exclamation mark unset). See
-                                                <literal>ConditionKernelCommandLine=</literal> in
-                                                <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
-                                                for details.
-                                                </para>
-                                        </listitem>
-                                </varlistentry>
-                                <varlistentry>
-                                        <term><varname>Architecture=</varname></term>
-                                        <listitem>
-                                                <para>Checks whether the system is running on a specific
-                                                architecture. See <literal>ConditionArchitecture=</literal> in
-                                                <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
-                                                for details.
-                                                </para>
-                                        </listitem>
-                                </varlistentry>
-                        </variablelist>
-
-                        <para>The <literal>[NetDev]</literal> section accepts the following
-                        keys:</para>
-
-                        <variablelist class='network-directives'>
-                                <varlistentry>
-                                        <term><varname>Name=</varname></term>
-                                        <listitem>
-                                                <para>The interface name used when creating the
-                                                netdev. This option is compulsory.</para>
-                                        </listitem>
-                                </varlistentry>
-                                <varlistentry>
-                                        <term><varname>Kind=</varname></term>
-                                        <listitem>
-                                                <para>The netdev kind. Currently, <literal>bridge</literal>,
-                                                <literal>bond</literal> and <literal>vlan</literal>
-                                                are supported. This option is compulsory.</para>
-                                        </listitem>
-                                </varlistentry>
-                        </variablelist>
-
-                        <para>The <literal>[VLAN]</literal> section only applies for netdevs of kind <literal>vlan</literal>,
-                        and accepts the following key:</para>
-
-                        <variablelist class='network-directives'>
-                                <varlistentry>
-                                        <term><varname>Id=</varname></term>
-                                        <listitem>
-                                                <para>The VLAN ID to use. An integer in the range 0–4094.
-                                                This option is compulsory.</para>
-                                        </listitem>
-                                </varlistentry>
-                        </variablelist>
-
-                </refsect2>
-
-                <refsect2><title>Networks</title>
-                        <para>Network files must have the extension <filename>.network</filename>;
-                        other extensions are ignored. Networks are applied to links whenever the links
-                        appear.</para>
-
-                        <para>The network file contains a <literal>[Match]</literal> section,
-                        which determines if a given network file may be applied to a given device;
-                        and a <literal>[Network]</literal> section specifying how the device should
-                        be configured. The first (in lexical order) of the network files that
-                        matches a given device is applied.</para>
-
-                        <para>A network file is said to match a device if each of the entries in the
-                        <literal>[Match]</literal> section matches, or if the section is empty.
-                        The following keys are accepted:</para>
-
-                        <variablelist class='network-directives'>
-                                <varlistentry>
-                                        <term><varname>MACAddress=</varname></term>
-                                        <listitem>
-                                                <para>The hardware address.</para>
-                                        </listitem>
-                                </varlistentry>
-                                <varlistentry>
-                                        <term><varname>Path=</varname></term>
-                                        <listitem>
-                                                <para>The persistent path, as exposed by the udev
-                                                property <literal>ID_PATH</literal>. May contain shell
-                                                style globs.</para>
-                                        </listitem>
-                                </varlistentry>
-                                <varlistentry>
-                                        <term><varname>Driver=</varname></term>
-                                        <listitem>
-                                                <para>The driver currently bound to the device, as
-                                                exposed by the udev property <literal>DRIVER</literal>
-                                                of its parent device, or if that is not set the driver
-                                                as exposed by <literal>ethtool -i</literal> of the
-                                                device itself.</para>
-                                        </listitem>
-                                </varlistentry>
-                                <varlistentry>
-                                        <term><varname>Type=</varname></term>
-                                        <listitem>
-                                                <para>The device type, as exposed by the udev property
-                                                <literal>DEVTYPE</literal>.</para>
-                                        </listitem>
-                                </varlistentry>
-                                <varlistentry>
-                                        <term><varname>Name=</varname></term>
-                                        <listitem>
-                                                <para>The device name, as exposed by the udev property
-                                                <literal>INTERFACE</literal>. May contain shell style
-                                                globs.</para>
-                                        </listitem>
-                                </varlistentry>
-                                <varlistentry>
-                                        <term><varname>Host=</varname></term>
-                                        <listitem>
-                                                <para>Matches against the hostname or machine ID of the
-                                                host. See <literal>ConditionHost=</literal> in
-                                                <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
-                                                for details.
-                                                </para>
-                                        </listitem>
-                                </varlistentry>
-                                <varlistentry>
-                                        <term><varname>Virtualization=</varname></term>
-                                        <listitem>
-                                                <para>Checks whether the system is executed in a virtualized
-                                                environment and optionally test whether it is a specific
-                                                implementation. See <literal>ConditionVirtualization=</literal> in
-                                                <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
-                                                for details.
-                                                </para>
-                                        </listitem>
-                                </varlistentry>
-                                <varlistentry>
-                                        <term><varname>KernelCommandLine=</varname></term>
-                                        <listitem>
-                                                <para>Checks whether a specific kernel command line option is
-                                                set (or if prefixed with the exclamation mark unset). See
-                                                <literal>ConditionKernelCommandLine=</literal> in
-                                                <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
-                                                for details.
-                                                </para>
-                                        </listitem>
-                                </varlistentry>
-                                <varlistentry>
-                                        <term><varname>Architecture=</varname></term>
-                                        <listitem>
-                                                <para>Checks whether the system is running on a specific
-                                                architecture. See <literal>ConditionArchitecture=</literal> in
-                                                <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
-                                                for details.
-                                                </para>
-                                        </listitem>
-                                </varlistentry>
-                        </variablelist>
-
-                        <para>The <literal>[Network]</literal> section accepts the following keys:</para>
-
-                        <variablelist class='network-directives'>
-                                <varlistentry>
-                                        <term><varname>Description=</varname></term>
-                                        <listitem>
-                                                <para>A description of the device. This is only used for
-                                                presentation purposes.</para>
-                                        </listitem>
-                                </varlistentry>
-                                <varlistentry>
-                                        <term><varname>DHCP=</varname></term>
-                                        <listitem>
-                                                <para>A boolean. When true, enables basic DHCPv4 support.</para>
-                                        </listitem>
-                                </varlistentry>
-                                <varlistentry>
-                                        <term><varname>Address=</varname></term>
-                                        <listitem>
-                                                <para>A static IPv4 or IPv6 address and its prefix length,
-                                                separated by a <literal>/</literal> character. The format of the address must
-                                                be as described in
-                                                <citerefentry><refentrytitle>inet_pton</refentrytitle><manvolnum>3</manvolnum></citerefentry>
-                                                . This is a short-hand for an [Address] section only containing an Address key (see below).</para>
-                                        </listitem>
-                                </varlistentry>
-                                <varlistentry>
-                                        <term><varname>Gateway=</varname></term>
-                                        <listitem>
-                                                <para>The gateway address, which must be in the format described in
-                                                <citerefentry><refentrytitle>inet_pton</refentrytitle><manvolnum>3</manvolnum></citerefentry>
-                                                . This is a short-hand for a [Route] section only containing a Gateway key.</para>
-                                        </listitem>
-                                </varlistentry>
-                                <varlistentry>
-                                        <term><varname>DNS=</varname></term>
-                                        <listitem>
-                                                <para>A DNS server address, which must be in the format described in
-                                                <citerefentry><refentrytitle>inet_pton</refentrytitle><manvolnum>3</manvolnum></citerefentry>
-                                                .</para>
-                                        </listitem>
-                                </varlistentry>
-                                <varlistentry>
-                                        <term><varname>Bridge=</varname></term>
-                                        <listitem>
-                                                <para>The name of the bridge to add the link to.</para>
-                                        </listitem>
-                                </varlistentry>
-                                <varlistentry>
-                                        <term><varname>Bond=</varname></term>
-                                        <listitem>
-                                                <para>The name of the bond to add the link to.</para>
-                                        </listitem>
-                                </varlistentry>
-                                <varlistentry>
-                                        <term><varname>VLAN=</varname></term>
-                                        <listitem>
-                                                <para>The name of a VLAN to create on the link. This option
-                                                may be specified more than once.</para>
-                                        </listitem>
-                                </varlistentry>
-                        </variablelist>
-
-                        <para>The <literal>[Address]</literal> section accepts the following keys:</para>
-
-                        <variablelist class='network-directives'>
-                                <varlistentry>
-                                        <term><varname>Address=</varname></term>
-                                        <listitem>
-                                                <para>As in the <literal>[Network]</literal> section. This key is mandatory.</para>
-                                        </listitem>
-                                </varlistentry>
-                                <varlistentry>
-                                        <term><varname>Broadcast=</varname></term>
-                                        <listitem>
-                                                <para>The broadcast address, which must be in the format described in
-                                                <citerefentry><refentrytitle>inet_pton</refentrytitle><manvolnum>3</manvolnum></citerefentry>
-                                                . This key only applies to IPv4 addresses. If it is not given, it is
-                                                derived from the <literal>Address</literal> key.</para>
-                                        </listitem>
-                                </varlistentry>
-                                <varlistentry>
-                                        <term><varname>Label=</varname></term>
-                                        <listitem>
-                                                <para>An address label.</para>
-                                        </listitem>
-                                </varlistentry>
-                        </variablelist>
-
-                        <para>The <literal>[Route]</literal> section accepts the following keys:</para>
-
-                        <variablelist class='network-directives'>
-                                <varlistentry>
-                                        <term><varname>Gateway=</varname></term>
-                                        <listitem>
-                                                <para>As in the <literal>[Network]</literal> section. This key is mandatory.</para>
-                                        </listitem>
-                                </varlistentry>
-                                <varlistentry>
-                                        <term><varname>Destination=</varname></term>
-                                        <listitem>
-                                                <para>The destination prefix of the route. Possibly followed by a slash and the
-                                                prefixlength, if ommitted a full-length host route is assumed.</para>
-                                        </listitem>
-                                </varlistentry>
-                        </variablelist>
-
-                        <para>The <literal>[DHCPv4]</literal> section accepts the following keys:</para>
-
-                        <variablelist class='network-directives'>
-                                <varlistentry>
-                                        <term><varname>UseDNS=</varname></term>
-                                        <listitem>
-                                                <para>When true (the default), the DNS servers received from the DHCP server will
-                                                be used and take precedence over any statically configured ones.</para>
-                                        </listitem>
-                                </varlistentry>
-                                <varlistentry>
-                                        <term><varname>UseMTU=</varname></term>
-                                        <listitem>
-                                                <para>When true, the interface maximum transmission unit from the DHCP server will
-                                                be used on the current link. Defaults to false.</para>
-                                        </listitem>
-                                </varlistentry>
-                                <varlistentry>
-                                        <term><varname>UseHostname=</varname></term>
-                                        <listitem>
-                                                <para>When true (the default), the hostname received from the DHCP server
-                                                will be used as the transient hostname.</para>
-                                        </listitem>
-                                </varlistentry>
-                                <varlistentry>
-                                        <term><varname>CriticalConnection=</varname></term>
-                                        <listitem>
-                                                <para>When true, the connection will never be torn down even if the DHCP lease
-                                                expires. This is contrary to the DHCP specification, but may be the best choice
-                                                if, say, the root filesystem relies on this connection. Defaults to false.</para>
-                                        </listitem>
-                                </varlistentry>
-                       </variablelist>
-
-                </refsect2>
+                <para>Networks are configured in <filename>.network</filename> files, see
+                <citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                and virtual network devices are configured in <filename>.netdev</filename> files, see
+                <citerefentry><refentrytitle>systemd.netdev</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+                </para>
         </refsect1>
 
         <refsect1>
                 <title>See Also</title>
                 <para>
                         <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>udev</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                        <citerefentry><refentrytitle>systemd.link</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.netdev</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-network-wait-online.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
                 </para>
         </refsect1>
 
index 0a661c9..aea5055 100644 (file)
@@ -70,7 +70,7 @@
                 <para><command>systemd-nspawn</command> may be used to
                 run a command or OS in a light-weight namespace
                 container. In many ways it is similar to
-                <citerefentry><refentrytitle>chroot</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                <citerefentry project='man-pages'><refentrytitle>chroot</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                 but more powerful since it fully virtualizes the file
                 system hierarchy, as well as the process tree, the
                 various IPC subsystems and the host and domain
                 involved with boot and systems management.</para>
 
                 <para>In contrast to
-                <citerefentry><refentrytitle>chroot</refentrytitle><manvolnum>1</manvolnum></citerefentry> <command>systemd-nspawn</command>
+                <citerefentry project='man-pages'><refentrytitle>chroot</refentrytitle><manvolnum>1</manvolnum></citerefentry> <command>systemd-nspawn</command>
                 may be used to boot full Linux-based operating systems
                 in a container.</para>
 
                 <para>Use a tool like
-                <citerefentry><refentrytitle>yum</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
-                <citerefentry><refentrytitle>debootstrap</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                <citerefentry project='die-net'><refentrytitle>yum</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                <citerefentry project='die-net'><refentrytitle>debootstrap</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
                 or
-                <citerefentry><refentrytitle>pacman</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                <citerefentry project='arch'><refentrytitle>pacman</refentrytitle><manvolnum>8</manvolnum></citerefentry>
                 to set up an OS directory tree suitable as file system
                 hierarchy for <command>systemd-nspawn</command>
                 containers.</para>
 
                 <para>As a safety check
                 <command>systemd-nspawn</command> will verify the
-                existence of <filename>/etc/os-release</filename> in
-                the container tree before starting the container (see
+                existence of <filename>/usr/lib/os-release</filename>
+                or <filename>/etc/os-release</filename> in the
+                container tree before starting the container (see
                 <citerefentry><refentrytitle>os-release</refentrytitle><manvolnum>5</manvolnum></citerefentry>). It
                 might be necessary to add this file to the container
                 tree manually if the OS of the container is too old to
                                 <term><option>--directory=</option></term>
 
                                 <listitem><para>Directory to use as
-                                file system root for the namespace
-                                container. If omitted, the current
-                                directory will be
-                                used.</para></listitem>
+                                file system root for the container. If
+                                neither <option>--directory=</option>
+                                nor <option>--image=</option> are
+                                specified, the current directory will
+                                be used. May not be specified together with
+                                <option>--image=</option>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><option>-i</option></term>
+                                <term><option>--image=</option></term>
+
+                                <listitem><para>Disk image to mount
+                                the root directory for the container
+                                from. Takes a path to a regular file
+                                or to a block device node. The file or
+                                block device must contain a GUID
+                                Partition Table with a root partition
+                                which is mounted as the root directory
+                                of the container. Optionally, it may
+                                contain a home and/or a server data
+                                partition which are mounted to the
+                                appropriate places in the
+                                container. All these partitions must
+                                be identified by the partition types
+                                defined by the <ulink
+                                url="http://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/">Discoverable
+                                Partitions Specification</ulink>. Any
+                                other partitions, such as foreign
+                                partitions, swap partitions or EFI
+                                system partitions are not mounted. May
+                                not be specified together with
+                                <option>--directory=</option>.</para></listitem>
                         </varlistentry>
 
                         <varlistentry>
                                 <term><option>-u</option></term>
                                 <term><option>--user=</option></term>
 
-                                <listitem><para>Run the command
-                                under specified user, create home
-                                directory and cd into it. As rest
-                                of systemd-nspawn, this is not
-                                the security feature and limits
-                                against accidental changes only.
-                                </para></listitem>
+                                <listitem><para>After transitioning
+                                into the container, change to the
+                                specified user-defined in the
+                                container's user database. Like all
+                                other systemd-nspawn features, this is
+                                not a security feature and provides
+                                protection against accidental
+                                destructive operations
+                                only.</para></listitem>
                         </varlistentry>
 
                         <varlistentry>
 
                                 <listitem><para>Assign the specified
                                 network interface to the
-                                container. This will move the
+                                container. This will remove the
                                 specified interface from the calling
                                 namespace and place it in the
                                 container. When the container
                         </varlistentry>
 
                         <varlistentry>
+                                <term><option>--network-macvlan=</option></term>
+
+                                <listitem><para>Create a
+                                <literal>macvlan</literal> interface
+                                of the specified Ethernet network
+                                interface and add it to the
+                                container. A
+                                <literal>macvlan</literal> interface
+                                is a virtual interface that adds a
+                                second MAC address to an existing
+                                physical Ethernet link. The interface
+                                in the container will be named after
+                                the interface on the host, prefixed
+                                with <literal>mv-</literal>. Note that
+                                <option>--network-macvlan=</option>
+                                implies
+                                <option>--private-network</option>. This
+                                option may be used more than once to
+                                add multiple network interfaces to the
+                                container.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
                                 <term><option>--network-veth</option></term>
 
                                 <listitem><para>Create a virtual
-                                Ethernet link between host and
-                                container. The host side of the
+                                Ethernet link
+                                (<literal>veth</literal>) between host
+                                and container. The host side of the
                                 Ethernet link will be available as a
                                 network interface named after the
                                 container's name (as specified with
                                 <option>--machine=</option>), prefixed
                                 with <literal>ve-</literal>. The
-                                container side of the the Ethernet
+                                container side of the Ethernet
                                 link will be named
                                 <literal>host0</literal>. Note that
                                 <option>--network-veth</option>
                                 <option>--network-bridge=</option>
                                 implies
                                 <option>--network-veth</option>. If
-                                this option is used the host side of
+                                this option is used, the host side of
                                 the Ethernet link will use the
                                 <literal>vb-</literal> prefix instead
                                 of <literal>ve-</literal>.</para></listitem>
                                 additional capabilities to grant the
                                 container. Takes a comma-separated
                                 list of capability names, see
-                                <citerefentry><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                                <citerefentry project='man-pages'><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry>
                                 for more information. Note that the
                                 following capabilities will be granted
                                 in any way: CAP_CHOWN,
                         </varlistentry>
 
                         <varlistentry>
+                                <term><option>--tmpfs=</option></term>
+
+                                <listitem><para>Mount a tmpfs file
+                                system into the container. Takes a
+                                single absolute path argument that
+                                specifies where to mount the tmpfs
+                                instance to (in which case the
+                                directory access mode will be chosen
+                                as 0755, owned by root/root), or
+                                optionally a colon-separated pair of
+                                path and mount option string, that is
+                                used for mounting (in which case the
+                                kernel default for access mode and
+                                owner will be chosen, unless otherwise
+                                specified). This option is
+                                particularly useful for mounting
+                                directories such as
+                                <filename>/var</filename> as tmpfs, to
+                                allow state-less systems, in
+                                particular when combined with
+                                <option>--read-only</option>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
                                 <term><option>--setenv=</option></term>
 
                                 <listitem><para>Specifies an
                                 accessible via
                                 <citerefentry><refentrytitle>machinectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                                 and shown by tools such as
-                                <citerefentry><refentrytitle>ps</refentrytitle><manvolnum>1</manvolnum></citerefentry>. If
+                                <citerefentry project='man-pages'><refentrytitle>ps</refentrytitle><manvolnum>1</manvolnum></citerefentry>. If
                                 the container does not run an init
                                 system, it is recommended to set this
                                 option to <literal>no</literal>. Note
                                 <literal>x86</literal> and
                                 <literal>x86-64</literal> are
                                 supported. This is useful when running
-                                a 32bit container on a 64bit
-                                host. If this setting is not used
+                                a 32-bit container on a 64-bit
+                                host. If this setting is not used,
                                 the personality reported in the
                                 container is the same as the one
                                 reported on the
                                 of the container OS itself.</para></listitem>
                         </varlistentry>
 
+                        <varlistentry>
+                                <term><option>--volatile</option><replaceable>=MODE</replaceable></term>
+
+                                <listitem><para>Boots the container in
+                                volatile (ephemeral) mode. When no
+                                mode parameter is passed or when mode
+                                is specified as <literal>yes</literal>
+                                full volatile mode is enabled. This
+                                means the root directory is mounted as
+                                mostly unpopulated
+                                <literal>tmpfs</literal> instance, and
+                                <filename>/usr</filename> from the OS
+                                tree is mounted into it, read-only
+                                (the system thus starts up with
+                                read-only OS resources, but pristine
+                                state and configuration, any changes
+                                to the either are lost on
+                                shutdown). When the mode parameter is
+                                specified as <literal>state</literal>
+                                the OS tree is mounted read-only, but
+                                <filename>/var</filename> is mounted
+                                as <literal>tmpfs</literal> instance
+                                into it (the system thus starts up
+                                with read-only OS resources and
+                                configuration, but prestine state, any
+                                changes to the latter are lost on
+                                shutdown). When the mode parameter is
+                                specified as <literal>no</literal>
+                                (the default) the whole OS tree is made
+                                available writable.</para>
+
+                                <para>Note that setting this to
+                                <literal>yes</literal> or
+                                <literal>state</literal> will only
+                                work correctly with operating systems
+                                in the container that can boot up with
+                                only <filename>/usr</filename>
+                                mounted, and are able to populate
+                                <filename>/var</filename>
+                                automatically, as
+                                needed.</para></listitem>
+                        </varlistentry>
+
                         <xi:include href="standard-options.xml" xpointer="help" />
                         <xi:include href="standard-options.xml" xpointer="version" />
                 </variablelist>
                 <title>See Also</title>
                 <para>
                         <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>chroot</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>yum</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>debootstrap</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>pacman</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry project='man-pages'><refentrytitle>chroot</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry project='die-net'><refentrytitle>yum</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry project='die-net'><refentrytitle>debootstrap</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry project='arch'><refentrytitle>pacman</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>systemd.slice</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>machinectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 </para>
diff --git a/man/systemd-path.xml b/man/systemd-path.xml
new file mode 100644 (file)
index 0000000..fc01d5e
--- /dev/null
@@ -0,0 +1,111 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd-path"
+          xmlns:xi="http://www.w3.org/2001/XInclude">
+
+        <refentryinfo>
+                <title>systemd-path</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-path</refentrytitle>
+                <manvolnum>1</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-path</refname>
+                <refpurpose>List and query system and user paths</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <cmdsynopsis>
+                        <command>systemd-path <arg choice="opt" rep="repeat">OPTIONS</arg> <arg choice="opt" rep="repeat">NAME</arg></command>
+                </cmdsynopsis>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><command>systemd-path</command> may be used to
+                query system and user paths. The tool makes many of
+                the paths described in
+                <citerefentry><refentrytitle>file-hierarchy</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                queriable.</para>
+
+                <para>When invoked without arguments a list of known
+                paths and their current values is shown. When at least
+                one argument is passed the path with this is name is
+                queried and its value shown. The variables whose name
+                begins with <literal>search-</literal> don't refer to
+                individual paths, but instead a to a list of
+                colon-separated search paths, in their order of
+                precedence.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>The following options are understood:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><option>--suffix=</option></term>
+
+                                <listitem><para>The printed paths are
+                                suffixed by the specified
+                                string.</para></listitem>
+                        </varlistentry>
+
+                        <xi:include href="standard-options.xml" xpointer="help" />
+                        <xi:include href="standard-options.xml" xpointer="version" />
+                </variablelist>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Exit status</title>
+
+                <para>On success, 0 is returned, a non-zero failure
+                code otherwise.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>file-hierarchy</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
index 67b41f5..669fe78 100644 (file)
 
                 <variablelist>
                         <varlistentry>
-                                <term><option>--max-files=</option></term>
+                                <term><option>--files-max=</option></term>
 
                                 <listitem><para>Maximum number of
                                 files to read ahead. Only valid
diff --git a/man/systemd-resolved.service.xml b/man/systemd-resolved.service.xml
new file mode 100644 (file)
index 0000000..c44b10c
--- /dev/null
@@ -0,0 +1,91 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2014 Tom Gundersen
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd-resolved.service" conditional='ENABLE_RESOLVED'>
+
+        <refentryinfo>
+                <title>systemd-resolved.service</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Tom</firstname>
+                                <surname>Gundersen</surname>
+                                <email>teg@jklm.no</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-resolved.service</refentrytitle>
+                <manvolnum>8</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-resolved.service</refname>
+                <refname>systemd-resolved</refname>
+                <refpurpose>Network Name Resolution manager</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>systemd-resolved.service</filename></para>
+                <para><filename>/usr/lib/systemd/systemd-resolved</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><command>systemd-resolved</command> is a system
+                service that manages network name resolution. It
+                implements a caching DNS stub resolver and an LLMNR
+                resolver and responder. It also generates
+                <filename>/run/systemd/resolve/resolv.conf</filename>
+                for compatibility which may be symlinked from
+                <filename>/etc/resolv.conf</filename>.</para>
+
+                <para>The DNS servers contacted are determined from
+                the global settings in
+                <citerefentry><refentrytitle>resolved.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                the per-link static settings in
+                <filename>.network</filename> files, and the per-link
+                dynamic settings received over DHCP. See
+                <citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                for more details.</para>
+
+                <para>Note that <filename>/run/systemd/resolve/resolv.conf</filename>
+                should not be used directly, but only through a symlink from
+                <filename>/etc/resolv.conf</filename>.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>resolved.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-networkd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
index 064195a..0c9d13d 100644 (file)
@@ -107,11 +107,23 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
       </varlistentry>
 
       <varlistentry>
+        <term><option>--property=</option></term>
+        <term><option>-p</option></term>
+
+        <listitem><para>Sets a unit property for the scope or service
+        unit that is created. This takes an assignment in the same
+        format as
+        <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
+        <command>set-property</command> command.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
         <term><option>--description=</option></term>
 
-        <listitem><para>Provide description for the unit. If not
-        specified, the command itself will be used as a description.
-        See <varname>Description=</varname> in
+        <listitem><para>Provide a description for the service or scope
+        unit. If not specified, the command itself will be used as a
+        description. See <varname>Description=</varname> in
         <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
         </para></listitem>
       </varlistentry>
@@ -128,10 +140,10 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
       <varlistentry>
         <term><option>--remain-after-exit</option></term>
 
-        <listitem><para>After the service's process has terminated, keep
-        the service around until it is explicitly stopped. This is
-        useful to collect runtime information about the service after
-        it finished running. Also see
+        <listitem><para>After the service or scope process has
+        terminated, keep the service around until it is explicitly
+        stopped. This is useful to collect runtime information about
+        the service after it finished running. Also see
         <varname>RemainAfterExit=</varname> in
         <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
         </para>
@@ -141,15 +153,58 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
       <varlistentry>
         <term><option>--send-sighup</option></term>
 
-        <listitem><para>When terminating the scope unit, send a SIGHUP
-        immediately after SIGTERM. This is useful to indicate to
-        shells and shell-like processes that the connection has been
-        severed. Also see <varname>SendSIGHUP=</varname> in
+        <listitem><para>When terminating the scope or service unit,
+        send a SIGHUP immediately after SIGTERM. This is useful to
+        indicate to shells and shell-like processes that the
+        connection has been severed. Also see
+        <varname>SendSIGHUP=</varname> in
         <citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
         </para>
         </listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><option>--service-type=</option></term>
+
+        <listitem><para>Sets the service type. Also see
+        <varname>Type=</varname> in
+        <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>. This
+        option has no effect in conjunction with
+        <option>--scope</option>. Defaults to
+        <constant>simple</constant>.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>--uid=</option></term>
+        <term><option>--gid=</option></term>
+
+        <listitem><para>Runs the service process under the UNIX user
+        and group. Also see <varname>User=</varname> and
+        <varname>Group=</varname> in
+        <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>--nice=</option></term>
+
+        <listitem><para>Runs the service process with the specified
+        nice level. Also see <varname>Nice=</varname> in
+        <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>--setenv=</option></term>
+
+        <listitem><para>Runs the service process with the specified
+        environment variables set. Also see
+        <varname>Environment=</varname> in
+        <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
+        </listitem>
+      </varlistentry>
+
       <xi:include href="user-system-options.xml" xpointer="user" />
       <xi:include href="user-system-options.xml" xpointer="system" />
       <xi:include href="user-system-options.xml" xpointer="host" />
@@ -173,7 +228,7 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
   </refsect1>
 
   <refsect1>
-    <title>Example</title>
+    <title>Examples</title>
 
     <para>The following command will log the environment variables
     provided by systemd to services:</para>
@@ -186,6 +241,15 @@ Sep 08 07:37:21 bupkis systemd[1]: Started /usr/bin/env.
 Sep 08 07:37:21 bupkis env[19948]: PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
 Sep 08 07:37:21 bupkis env[19948]: LANG=en_US.UTF-8
 Sep 08 07:37:21 bupkis env[19948]: BOOT_IMAGE=/vmlinuz-3.11.0-0.rc5.git6.2.fc20.x86_64</programlisting>
+
+    <para>The following command invokes the
+    <citerefentry project='man-pages'><refentrytitle>updatedb</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+    tool, but lowers the block IO weight for it to 10. See
+    <citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+    for more information on the <varname>BlockIOWeight=</varname>
+    property.</para>
+
+    <programlisting># systemd-run -p BlockIOWeight=10 updatedb</programlisting>
   </refsect1>
 
   <refsect1>
@@ -197,6 +261,8 @@ Sep 08 07:37:21 bupkis env[19948]: BOOT_IMAGE=/vmlinuz-3.11.0-0.rc5.git6.2.fc20.
       <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
       <citerefentry><refentrytitle>systemd.scope</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
       <citerefentry><refentrytitle>systemd.slice</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
       <citerefentry><refentrytitle>machinectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
     </para>
   </refsect1>
index a917f4d..d0ea6d8 100644 (file)
@@ -128,7 +128,7 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
         <citerefentry><refentrytitle>systemd-hibernate.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>, or
         <citerefentry><refentrytitle>systemd-hybrid-sleep.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
         More than one value can be specified by separating
-        multiple values with commas. They will be tried
+        multiple values with whitespace. They will be tried
         in turn, until one is written without error. If
         neither succeeds, the operation will be aborted.
         </para></listitem>
@@ -146,7 +146,7 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
         <citerefentry><refentrytitle>systemd-hibernate.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>, or
         <citerefentry><refentrytitle>systemd-hybrid-sleep.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
         More than one value can be specified by separating
-        multiple values with commas. They will be tried
+        multiple values with whitespace. They will be tried
         in turn, until one is written without error. If
         neither succeeds, the operation will be aborted.
         </para></listitem>
index 690f961..9a3ae1b 100644 (file)
@@ -56,7 +56,7 @@
                 <para><filename>systemd-suspend.service</filename></para>
                 <para><filename>systemd-hibernate.service</filename></para>
                 <para><filename>systemd-hybrid-sleep.service</filename></para>
-                <para><filename>/usr/lib/systemd/systemd-sleep</filename></para>
+                <para><filename>/usr/lib/systemd/system-sleep</filename></para>
         </refsynopsisdiv>
 
         <refsect1>
index f3a89ad..6105c51 100644 (file)
                                 capabilities to include in the
                                 capability bounding set for PID 1 and
                                 its children. See
-                                <citerefentry><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                                <citerefentry project='man-pages'><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry>
                                 for details. Takes a whitespace-separated
                                 list of capability names as read by
                                 <citerefentry><refentrytitle>cap_from_name</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
                                 <term><varname>TimerSlackNSec=</varname></term>
 
                                 <listitem><para>Sets the timer slack
-                                in nanoseconds for PID 1 which is then
-                                inherited to all executed processes,
+                                in nanoseconds for PID 1, which is
+                                inherited by all executed processes,
                                 unless overridden individually, for
                                 example with the
                                 <varname>TimerSlackNSec=</varname>
                                 see
                                 <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>). The
                                 timer slack controls the accuracy of
-                                wake-ups triggered by timers. See
+                                wake-ups triggered by system
+                                timers. See
                                 <citerefentry><refentrytitle>prctl</refentrytitle><manvolnum>2</manvolnum></citerefentry>
                                 for more information. Note that in
                                 contrast to most other time span
                         </varlistentry>
 
                         <varlistentry>
+                                <term><varname>DefaultTimerAccuracySec=</varname></term>
+
+                                <listitem><para>Sets the default
+                                accuracy of timer units. This controls
+                                the global default for the
+                                <varname>AccuracySec=</varname>
+                                setting of timer units, see
+                                <citerefentry><refentrytitle>systemd.timer</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                                for
+                                details. <varname>AccuracySec=</varname>
+                                set in individual units override the
+                                global default for the specific
+                                unit. Defaults to 1min. Note that the
+                                accuracy of timer units is also
+                                affected by the configured timer slack
+                                for PID 1, see
+                                <varname>TimerSlackNSec=</varname>
+                                above.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
                                 <term><varname>DefaultTimeoutStartSec=</varname></term>
                                 <term><varname>DefaultTimeoutStopSec=</varname></term>
                                 <term><varname>DefaultRestartSec=</varname></term>
                                 <varname>TimeoutStartSec=</varname>,
                                 <varname>TimeoutStopSec=</varname> and
                                 <varname>RestartSec=</varname> (for
-                                service units, see
+                                services, see
                                 <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
                                 for details on the per-unit
                                 settings). For non-service units,
                                 <varname>TimeoutSec=</varname> value.
                                 </para></listitem>
                         </varlistentry>
+
                         <varlistentry>
                                 <term><varname>DefaultStartLimitInterval=</varname></term>
                                 <term><varname>DefaultStartLimitBurst=</varname></term>
 
-                                <listitem><para>Configure the default start rate
-                                limiting, as configured per-service by
-                                <varname>StartLimitInterval=</varname> and
+                                <listitem><para>Configure the default
+                                unit start rate limiting, as
+                                configured per-service by
+                                <varname>StartLimitInterval=</varname>
+                                and
                                 <varname>StartLimitBurst=</varname>. See
                                 <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
                                 for details on the per-service
-                                settings).
-                                </para></listitem>
+                                settings.</para></listitem>
                         </varlistentry>
 
                         <varlistentry>
                                 executed processes. Takes a
                                 space-separated list of variable
                                 assignments. See
-                                <citerefentry><refentrytitle>environ</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                                <citerefentry project='man-pages'><refentrytitle>environ</refentrytitle><manvolnum>7</manvolnum></citerefentry>
                                 for details about environment
                                 variables.</para>
 
                         </varlistentry>
 
                         <varlistentry>
+                                <term><varname>DefaultCPUAccounting=</varname></term>
+                                <term><varname>DefaultBlockIOAccounting=</varname></term>
+                                <term><varname>DefaultMemoryAccounting=</varname></term>
+
+                                <listitem><para>Configure the default
+                                resource accounting settings, as
+                                configured per-unit by
+                                <varname>CPUAccounting=</varname>,
+                                <varname>BlockIOAccounting=</varname>
+                                and
+                                <varname>MemoryAccounting=</varname>. See
+                                <citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                                for details on the per-unit
+                                settings.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
                                 <term><varname>DefaultLimitCPU=</varname></term>
                                 <term><varname>DefaultLimitFSIZE=</varname></term>
                                 <term><varname>DefaultLimitDATA=</varname></term>
                           <citerefentry><refentrytitle>systemd.directives</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
                           <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
                           <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
-                          <citerefentry><refentrytitle>environ</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
-                          <citerefentry><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                          <citerefentry project='man-pages'><refentrytitle>environ</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+                          <citerefentry project='man-pages'><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry>
                   </para>
         </refsect1>
 
diff --git a/man/systemd-sysusers.xml b/man/systemd-sysusers.xml
new file mode 100644 (file)
index 0000000..6871060
--- /dev/null
@@ -0,0 +1,120 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd-sysusers"
+          xmlns:xi="http://www.w3.org/2001/XInclude">
+
+        <refentryinfo>
+                <title>systemd-sysusers</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-sysusers</refentrytitle>
+                <manvolnum>8</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-sysusers</refname>
+                <refname>systemd-sysusers.service</refname>
+                <refpurpose>Allocate system users and groups</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <cmdsynopsis>
+                        <command>systemd-sysusers</command>
+                        <arg choice="opt" rep="repeat">OPTIONS</arg>
+                        <arg choice="opt" rep="repeat"><replaceable>CONFIGFILE</replaceable></arg>
+                </cmdsynopsis>
+
+                <para><filename>systemd-sysusers.service</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><command>systemd-sysusers</command> creates
+                system users and groups, based on the file format and
+                location specified in
+                <citerefentry><refentrytitle>sysusers.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+                </para>
+
+                <para>If invoked with no arguments, it applies all
+                directives from all files found. If one or more
+                filenames are passed on the command line, only the
+                directives in these files are applied. If only the
+                basename of a file is specified, all directories as
+                specified in
+                <citerefentry><refentrytitle>sysusers.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                are searched for a matching file. If the string
+                <filename>-</filename> is specified as filenames
+                entries from the standard input of the process are
+                read.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <para>The following options are understood:</para>
+
+                <variablelist>
+                        <varlistentry>
+                                <term><option>--root=<replaceable>root</replaceable></option></term>
+                                <listitem><para>Takes a directory path
+                                as an argument. All paths will be
+                                prefixed with the given alternate <replaceable>root</replaceable>
+                                path, including config search paths.
+                                </para></listitem>
+                        </varlistentry>
+
+                        <xi:include href="standard-options.xml" xpointer="help" />
+                        <xi:include href="standard-options.xml" xpointer="version" />
+                </variablelist>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Exit status</title>
+
+                <para>On success, 0 is returned, a non-zero failure
+                code otherwise.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>sysusers.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
index 4f17bcc..143d340 100644 (file)
@@ -81,7 +81,7 @@
                         <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>timedatectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>localtime</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>hwclock</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                        <citerefentry project='man-pages'><refentrytitle>hwclock</refentrytitle><manvolnum>8</manvolnum></citerefentry>
                 </para>
         </refsect1>
 
diff --git a/man/systemd-timesyncd.service.xml b/man/systemd-timesyncd.service.xml
new file mode 100644 (file)
index 0000000..47e243c
--- /dev/null
@@ -0,0 +1,92 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2014 Kay Sievers
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd-timesyncd.service" conditional='ENABLE_TIMESYNCD'>
+
+        <refentryinfo>
+                <title>systemd-timesyncd.service</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Kay</firstname>
+                                <surname>Sievers</surname>
+                                <email>kay@vrfy.org</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-timesyncd.service</refentrytitle>
+                <manvolnum>8</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-timesyncd.service</refname>
+                <refname>systemd-timesyncd</refname>
+                <refpurpose>Network Time Synchronization</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>systemd-timesyncd.service</filename></para>
+                <para><filename>/usr/lib/systemd/systemd-timesyncd</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><filename>systemd-timesyncd</filename> is a
+                system service that may be used to synchronize the
+                local system clock with a remote Network Time Protocol
+                server. It also saves the local time to disk every
+                time the clock has been synchronized and uses this to
+                possibly advance the system realtime clock on
+                subsequent reboots to ensure it
+                monotonically advances even if the system lacks a
+                battery-buffered RTC chip.</para>
+
+                <para>The NTP servers contacted are determined from
+                the global settings in
+                <citerefentry><refentrytitle>timesyncd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                the per-link static settings in
+                <filename>.network</filename> files, and the per-link
+                dynamic settings received over DHCP. See
+                <citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                for more details.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>timesyncd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-networkd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>timedatectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>localtime</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry project='man-pages'><refentrytitle>hwclock</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
index 0b62640..fad2cbb 100644 (file)
                                 </para></listitem>
                         </varlistentry>
                         <varlistentry>
-                                <term><option>--prefix=PATH</option></term>
+                                <term><option>--prefix=<replaceable>path</replaceable></option></term>
                                 <listitem><para>Only apply rules that
                                 apply to paths with the specified
                                 prefix. This option can be specified
                                 multiple times.</para></listitem>
                         </varlistentry>
                         <varlistentry>
-                                <term><option>--exclude-prefix=PATH</option></term>
+                                <term><option>--exclude-prefix=<replaceable>path</replaceable></option></term>
                                 <listitem><para>Ignore rules that
                                 apply to paths with the specified
                                 prefix. This option can be specified
                                 multiple times.</para></listitem>
                         </varlistentry>
+                        <varlistentry>
+                                <term><option>--root=<replaceable>root</replaceable></option></term>
+                                <listitem><para>Takes a directory path
+                                as an argument. All paths will be
+                                prefixed with the given alternate <replaceable>root</replaceable>
+                                path, including config search paths.
+                                </para></listitem>
+                        </varlistentry>
 
                         <xi:include href="standard-options.xml" xpointer="help" />
                         <xi:include href="standard-options.xml" xpointer="version" />
index e0df87d..53bd3aa 100644 (file)
 
                                 <listitem><para>Forward password
                                 requests to
-                                <citerefentry><refentrytitle>wall</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                                <citerefentry project='man-pages'><refentrytitle>wall</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                                 instead of querying the user on the
                                 calling TTY.</para></listitem>
                         </varlistentry>
                                 <term><option>--plymouth</option></term>
 
                                 <listitem><para>Ask question with
-                                <citerefentry><refentrytitle>plymouth</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                                <citerefentry project='die-net'><refentrytitle>plymouth</refentrytitle><manvolnum>8</manvolnum></citerefentry>
                                 instead of querying the user on the
                                 calling TTY.</para></listitem>
                         </varlistentry>
                         <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>systemd-ask-password-console.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>wall</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>plymouth</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                        <citerefentry project='man-pages'><refentrytitle>wall</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry project='die-net'><refentrytitle>plymouth</refentrytitle><manvolnum>8</manvolnum></citerefentry>
                 </para>
         </refsect1>
 
index f44b7a0..049a440 100644 (file)
@@ -22,7 +22,6 @@
   <refmeta>
     <refentrytitle>systemd-udevd.service</refentrytitle>
     <manvolnum>8</manvolnum>
-    <refmiscinfo class="version"></refmiscinfo>
   </refmeta>
 
   <refnamediv>
@@ -44,6 +43,7 @@
       <arg><option>--debug</option></arg>
       <arg><option>--children-max=</option></arg>
       <arg><option>--exec-delay=</option></arg>
+      <arg><option>--event-timeout=</option></arg>
       <arg><option>--resolve-names=early|late|never</option></arg>
       <arg><option>--version</option></arg>
       <arg><option>--help</option></arg>
 
   <refsect1><title>Description</title>
     <para><command>systemd-udevd</command> listens to kernel uevents.
-      For every event, systemd-udevd executes matching instructions
-      specified in udev rules. See <citerefentry>
-      <refentrytitle>udev</refentrytitle><manvolnum>7</manvolnum>
-      </citerefentry>.</para>
-    <para>The behavior of the running daemon can be changed with
-    <command>udevadm control</command>.</para>
+    For every event, systemd-udevd executes matching instructions
+    specified in udev rules. See <citerefentry>
+    <refentrytitle>udev</refentrytitle><manvolnum>7</manvolnum>
+    </citerefentry>.</para>
+
+    <para>The behavior of the running daemon can be changed
+    dynamically with <command>udevadm control</command>, or
+    configured using
+    <citerefentry><refentrytitle>udev.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+    </para>
   </refsect1>
 
   <refsect1><title>Options</title>
       </varlistentry>
 
       <varlistentry>
+        <term><option>--event-timeout=</option></term>
+        <listitem>
+          <para>Set the number of seconds to wait for events to finish. After
+          this time the event will be terminated. The default is 30 seconds.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
         <term><option>--resolve-names=</option></term>
         <listitem>
           <para>Specify when systemd-udevd should resolve names of users and groups.
         </listitem>
       </varlistentry>
       <varlistentry>
+        <term><varname>udev.event-timeout=</varname></term>
+        <term><varname>rd.udev.event-timeout=</varname></term>
+        <listitem>
+          <para>Wait for events to finish up to the given number
+          of seconds. This option might be useful if events are
+          terminated due to kernel drivers taking too long to initialize.</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
         <term><varname>net.ifnames=</varname></term>
         <listitem>
           <para>Network interfaces are renamed to give them predictable names
          in kernel-command-line.xml -->
  </refsect1>
 
- <refsect1><title>Configuration file</title>
-   <para>udev expects its main configuration file at <filename>/etc/udev/udev.conf</filename>.
-   It consists of a set of variables allowing the user to override default udev values. All
-   empty lines or lines beginning with '#' are ignored. The following variables can be
-   set:</para>
-   <variablelist>
-     <varlistentry>
-       <term><varname>udev_log</varname></term>
-       <listitem>
-         <para>The logging priority. Valid values are the numerical syslog priorities
-         or their textual representations: <option>err</option>, <option>info</option>
-         and <option>debug</option>.</para>
-       </listitem>
-     </varlistentry>
-   </variablelist>
- </refsect1>
-
   <refsect1>
     <title>See Also</title>
-    <para><citerefentry>
-        <refentrytitle>udev</refentrytitle><manvolnum>7</manvolnum>
-      </citerefentry>, <citerefentry>
-        <refentrytitle>udevadm</refentrytitle><manvolnum>8</manvolnum>
-    </citerefentry></para>
+    <para>
+      <citerefentry><refentrytitle>udev.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>udev</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>udevadm</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+    </para>
   </refsect1>
 </refentry>
diff --git a/man/systemd-update-done.service.xml b/man/systemd-update-done.service.xml
new file mode 100644 (file)
index 0000000..c3b402b
--- /dev/null
@@ -0,0 +1,101 @@
+<?xml version="1.0"?>
+<!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<!--
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+<refentry id="systemd-update-done.service">
+
+        <refentryinfo>
+                <title>systemd-update-done.service</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd-update-done.service</refentrytitle>
+                <manvolnum>8</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd-update-done.service</refname>
+                <refname>systemd-update-done</refname>
+                <refpurpose>Mark <filename>/etc</filename> and <filename>/var</filename> fully updated</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>systemd-update-done.service</filename></para>
+                <para><filename>/usr/lib/systemd/systemd-update-done</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><filename>systemd-update-done.service</filename>
+                is a service that is invoked as part of the first boot
+                after the vendor operating system resources in
+                <filename>/usr</filename> have been updated. This is
+                useful to implement offline updates of
+                <filename>/usr</filename> which might requires updates
+                to <filename>/etc</filename> or
+                <filename>/var</filename> on the following boot.</para>
+
+                <para><filename>systemd-update-done.service</filename>
+                updates the file modification time (mtime) of the
+                stamp files <filename>/etc/.updated</filename> and
+                <filename>/var/.updated</filename> to the modification
+                time of the <filename>/usr</filename> directory,
+                unless the stamp files are already newer.</para>
+
+                <para>Services that shall run after offline upgrades
+                of <filename>/usr</filename> should order themselves
+                before
+                <filename>systemd-update-done.service</filename>, and
+                use the <varname>ConditionNeedsUpdate=</varname> (see
+                <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>)
+                condition to make sure to run when
+                <filename>/etc</filename> or <filename>/var</filename>
+                are older than <filename>/usr</filename> according to
+                the modification times of the files described
+                above. This requires that updates to
+                <filename>/usr</filename> are always followed by an
+                update of the modification time of
+                <filename>/usr</filename>, for example by invoking
+                <citerefentry project='man-pages'><refentrytitle>touch</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                on it.</para>
+
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry project='man-pages'><refentrytitle>touch</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
index 846fc95..7d9e32e 100644 (file)
                 is a service that writes SysV runlevel changes to utmp
                 and wtmp, as well as the audit logs, as they
                 occur. <filename>systemd-update-utmp.service</filename>
-                does the same for system reboots and shut-down requests.</para>
+                does the same for system reboots and shutdown requests.</para>
         </refsect1>
 
         <refsect1>
                 <title>See Also</title>
                 <para>
                         <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>utmp</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                        <citerefentry project='man-pages'><refentrytitle>utmp</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>auditd</refentrytitle><manvolnum>8</manvolnum></citerefentry>
                 </para>
         </refsect1>
index fc93e2d..767cbc7 100644 (file)
@@ -70,7 +70,7 @@
                 <para>
                         <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>systemd-logind.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>pam_nologin</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                        <citerefentry project='man-pages'><refentrytitle>pam_nologin</refentrytitle><manvolnum>8</manvolnum></citerefentry>
                 </para>
         </refsect1>
 
index 1983993..d6ad6f4 100644 (file)
                                 directory path. Sets the root
                                 directory for executed processes, with
                                 the
-                                <citerefentry><refentrytitle>chroot</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+                                <citerefentry project='man-pages'><refentrytitle>chroot</refentrytitle><manvolnum>2</manvolnum></citerefentry>
                                 system call. If this is used, it must
                                 be ensured that the process and all
                                 its auxiliary files are available in
 
                                 <para>
                                 See
-                                <citerefentry><refentrytitle>environ</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                                <citerefentry project='man-pages'><refentrytitle>environ</refentrytitle><manvolnum>7</manvolnum></citerefentry>
                                 for details about environment variables.</para></listitem>
                         </varlistentry>
                         <varlistentry>
 
                                 <para>The files listed with this
                                 directive will be read shortly before
-                                the process is executed. Settings from
-                                these files override settings made
-                                with
+                                the process is executed (more
+                                specifically, after all
+                                processes from a previous unit state
+                                terminated. This means you can
+                                generate these files in one unit
+                                state, and read it with this option in
+                                the next). Settings from these files
+                                override settings made with
                                 <varname>Environment=</varname>. If
                                 the same variable is set twice from
                                 these files, the files will be read in
                                 <option>tty</option>,
                                 <option>tty-force</option>,
                                 <option>tty-fail</option> or
-                                <option>socket</option>. If
-                                <option>null</option> is selected,
-                                standard input will be connected to
+                                <option>socket</option>.</para>
+
+                                <para>If <option>null</option> is
+                                selected, standard input will be
+                                connected to
                                 <filename>/dev/null</filename>,
                                 i.e. all read attempts by the process
-                                will result in immediate EOF. If
-                                <option>tty</option> is selected,
-                                standard input is connected to a TTY
-                                (as configured by
+                                will result in immediate EOF.</para>
+
+                                <para>If <option>tty</option> is
+                                selected, standard input is connected
+                                to a TTY (as configured by
                                 <varname>TTYPath=</varname>, see
                                 below) and the executed process
                                 becomes the controlling process of the
                                 terminal. If the terminal is already
-                                being controlled by another process, the
-                                executed process waits until the current
-                                controlling process releases the
-                                terminal.
-                                <option>tty-force</option>
-                                is similar to <option>tty</option>,
-                                but the executed process is forcefully
-                                and immediately made the controlling
+                                being controlled by another process,
+                                the executed process waits until the
+                                current controlling process releases
+                                the terminal.</para>
+
+                                <para><option>tty-force</option> is similar
+                                to <option>tty</option>, but the
+                                executed process is forcefully and
+                                immediately made the controlling
                                 process of the terminal, potentially
                                 removing previous controlling
                                 processes from the
-                                terminal. <option>tty-fail</option> is
+                                terminal.</para>
+
+                                <para><option>tty-fail</option> is
                                 similar to <option>tty</option> but if
                                 the terminal already has a controlling
                                 process start-up of the executed
-                                process fails.  The
-                                <option>socket</option> option is only
-                                valid in socket-activated services,
-                                and only when the socket configuration
-                                file (see
+                                process fails.</para>
+
+                                <para>The <option>socket</option>
+                                option is only valid in
+                                socket-activated services, and only
+                                when the socket configuration file
+                                (see
                                 <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>
                                 for details) specifies a single socket
                                 only. If this option is set, standard
                                 with daemons designed for use with the
                                 traditional
                                 <citerefentry><refentrytitle>inetd</refentrytitle><manvolnum>8</manvolnum></citerefentry>
-                                daemon. This setting defaults to
+                                daemon.</para>
+
+                                <para>This setting defaults to
                                 <option>null</option>.</para></listitem>
                         </varlistentry>
                         <varlistentry>
                                 of <option>inherit</option>,
                                 <option>null</option>,
                                 <option>tty</option>,
+                                <option>journal</option>,
                                 <option>syslog</option>,
                                 <option>kmsg</option>,
-                                <option>journal</option>,
+                                <option>journal+console</option>,
                                 <option>syslog+console</option>,
-                                <option>kmsg+console</option>,
-                                <option>journal+console</option> or
-                                <option>socket</option>. If set to
-                                <option>inherit</option>, the file
-                                descriptor of standard input is
-                                duplicated for standard output. If set
-                                to <option>null</option>, standard
-                                output will be connected to
+                                <option>kmsg+console</option> or
+                                <option>socket</option>.</para>
+
+                                <para><option>inherit</option>
+                                duplicates the file descriptor of
+                                standard input for standard
+                                output.</para>
+
+                                <para><option>null</option> connects
+                                standard output to
                                 <filename>/dev/null</filename>,
                                 i.e. everything written to it will be
-                                lost. If set to <option>tty</option>,
-                                standard output will be connected to a
-                                tty (as configured via
+                                lost.</para>
+
+                                <para><option>tty</option> connects
+                                standard output to a tty (as
+                                configured via
                                 <varname>TTYPath=</varname>, see
                                 below). If the TTY is used for output
                                 only, the executed process will not
                                 become the controlling process of the
                                 terminal, and will not fail or wait
                                 for other processes to release the
-                                terminal. <option>syslog</option>
-                                connects standard output to the
-                                <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>
-                                system syslog
-                                service. <option>kmsg</option>
-                                connects it with the kernel log buffer
-                                which is accessible via
-                                <citerefentry><refentrytitle>dmesg</refentrytitle><manvolnum>1</manvolnum></citerefentry>. <option>journal</option>
-                                connects it with the journal which is
-                                accessible via
-                                <citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
-                                (Note that everything that is written
-                                to syslog or kmsg is implicitly stored
-                                in the journal as well, those options
-                                are hence supersets of this
-                                one). <option>syslog+console</option>,
-                                <option>journal+console</option> and
-                                <option>kmsg+console</option> work
-                                similarly but copy the output to the
-                                system console as
-                                well. <option>socket</option> connects
-                                standard output to a socket from
-                                socket activation, semantics are
-                                similar to the respective option of
-                                <varname>StandardInput=</varname>.
-                                This setting defaults to the value set
-                                with
+                                terminal.</para>
+
+                                <para><option>journal</option>
+                                connects standard output with the
+                                journal which is accessible via
+                                <citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
+                                Note that everything that is written
+                                to syslog or kmsg (see below) is
+                                implicitly stored in the journal as
+                                well, the specific two options listed
+                                below are hence supersets of this
+                                one.</para>
+
+                                <para><option>syslog</option> connects
+                                standard output to the <citerefentry
+                                project='man-pages'><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                                system syslog service, in addition to
+                                the journal. Note that the journal
+                                daemon is usually configured to
+                                forward everything it receives to
+                                syslog anyway, in which case this
+                                option is no different from
+                                <option>journal</option>.</para>
+
+                                <para><option>kmsg</option> connects
+                                standard output with the kernel log
+                                buffer which is accessible via
+                                <citerefentry
+                                project='man-pages'><refentrytitle>dmesg</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                                in addition to the journal. The
+                                journal daemon might be configured to
+                                send all logs to kmsg anyway, in which
+                                case this option is no different from
+                                <option>journal</option>.</para>
+
+                                <para><option>journal+console</option>,
+                                <option>syslog+console</option> and
+                                <option>kmsg+console</option> work in
+                                a similar way as the three options
+                                above but copy the output to the
+                                system console as well.</para>
+
+                                <para><option>socket</option> connects
+                                standard output to a socket acquired
+                                via socket activation. The semantics
+                                are similar to the same option of
+                                <varname>StandardInput=</varname>.</para>
+
+                                <para>This setting defaults to the
+                                value set with
                                 <option>DefaultStandardOutput=</option>
                                 in
                                 <citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
                                 <option>local5</option>,
                                 <option>local6</option> or
                                 <option>local7</option>. See
-                                <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                                <citerefentry project='man-pages'><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                                 for details. This option is only
                                 useful when
                                 <varname>StandardOutput=</varname> or
                                 <option>notice</option>,
                                 <option>info</option>,
                                 <option>debug</option>. See
-                                <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                                <citerefentry project='man-pages'><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                                 for details. This option is only
                                 useful when
                                 <varname>StandardOutput=</varname> or
                                 <varname>User=</varname> setting. If
                                 not set, no PAM session will be opened
                                 for the executed processes. See
-                                <citerefentry><refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                                <citerefentry project='man-pages'><refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum></citerefentry>
                                 for details.</para></listitem>
                         </varlistentry>
 
                         <varlistentry>
-                                <term><varname>TCPWrapName=</varname></term>
-                                <listitem><para>If this is a
-                                socket-activated service, this sets the
-                                tcpwrap service name to check the
-                                permission for the current connection
-                                with. This is only useful in
-                                conjunction with socket-activated
-                                services, and stream sockets (TCP) in
-                                particular. It has no effect on other
-                                socket types (e.g. datagram/UDP) and
-                                on processes unrelated to socket-based
-                                activation. If the tcpwrap
-                                verification fails, daemon start-up
-                                will fail and the connection is
-                                terminated. See
-                                <citerefentry><refentrytitle>tcpd</refentrytitle><manvolnum>8</manvolnum></citerefentry>
-                                for details. Note that this option may
-                                be used to do access control checks
-                                only. Shell commands and commands
-                                described in
-                                <citerefentry><refentrytitle>hosts_options</refentrytitle><manvolnum>5</manvolnum></citerefentry>
-                                are not supported.</para></listitem>
-                        </varlistentry>
-
-                        <varlistentry>
                                 <term><varname>CapabilityBoundingSet=</varname></term>
 
                                 <listitem><para>Controls which
                                 capabilities to include in the
                                 capability bounding set for the
                                 executed process. See
-                                <citerefentry><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                                <citerefentry project='man-pages'><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry>
                                 for details. Takes a whitespace-separated
                                 list of capability names as read by
                                 <citerefentry><refentrytitle>cap_from_name</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
                                 <term><varname>SecureBits=</varname></term>
                                 <listitem><para>Controls the secure
                                 bits set for the executed process. See
-                                <citerefentry><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                                <citerefentry project='man-pages'><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry>
                                 for details. Takes a list of strings:
                                 <option>keep-caps</option>,
                                 <option>keep-caps-locked</option>,
                         <varlistentry>
                                 <term><varname>Capabilities=</varname></term>
                                 <listitem><para>Controls the
-                                <citerefentry><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                                <citerefentry project='man-pages'><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry>
                                 set for the executed process. Take a
                                 capability string describing the
                                 effective, permitted and inherited
                                 capability sets as documented in
                                 <citerefentry><refentrytitle>cap_from_text</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
                                 Note that these capability sets are
-                                usually influenced by the capabilities
+                                usually influenced (and filtered) by the capabilities
                                 attached to the executed file. Due to
                                 that
                                 <varname>CapabilityBoundingSet=</varname>
                                 <term><varname>ReadOnlyDirectories=</varname></term>
                                 <term><varname>InaccessibleDirectories=</varname></term>
 
-                                <listitem><para>Sets up a new
-                                file system namespace for executed
+                                <listitem><para>Sets up a new file
+                                system namespace for executed
                                 processes. These options may be used
                                 to limit access a process might have
                                 to the main file system
                                 processes inside the namespace. Note
                                 that restricting access with these
                                 options does not extend to submounts
-                                of a directory. You must list
-                                submounts separately in these settings
-                                to ensure the same limited
-                                access. These options may be specified
+                                of a directory that are created later
+                                on. These options may be specified
                                 more than once in which case all
                                 directories listed will have limited
                                 access from within the namespace. If
                                 the empty string is assigned to this
-                                option, the specific list is reset, and
-                                all prior assignments have no
+                                option, the specific list is reset,
+                                and all prior assignments have no
                                 effect.</para>
                                 <para>Paths in
                                 <varname>ReadOnlyDirectories=</varname>
                                 may be prefixed with
                                 <literal>-</literal>, in which case
                                 they will be ignored when they do not
-                                exist.</para></listitem>
+                                exist. Note that using this
+                                setting will disconnect propagation of
+                                mounts from the service to the host
+                                (propagation in the opposite direction
+                                continues to work). This means that
+                                this setting may not be used for
+                                services which shall be able to
+                                install mount points in the main mount
+                                namespace.</para></listitem>
                         </varlistentry>
 
                         <varlistentry>
                                 processes via
                                 <filename>/tmp</filename> or
                                 <filename>/var/tmp</filename>
-                                impossible. All temporary data created
-                                by service will be removed after
-                                the service is stopped. Defaults to
-                                false. Note that it is possible to run
-                                two or more units within the same
-                                private <filename>/tmp</filename> and
+                                impossible. If this is enabled, all
+                                temporary files created by a service
+                                in these directories will be removed
+                                after the service is stopped. Defaults
+                                to false. It is possible to run two or
+                                more units within the same private
+                                <filename>/tmp</filename> and
                                 <filename>/var/tmp</filename>
                                 namespace by using the
                                 <varname>JoinsNamespaceOf=</varname>
                                 directive, see
                                 <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
-                                for details.</para></listitem>
+                                for details. Note that using this
+                                setting will disconnect propagation of
+                                mounts from the service to the host
+                                (propagation in the opposite direction
+                                continues to work). This means that
+                                this setting may not be used for
+                                services which shall be able to install
+                                mount points in the main mount
+                                namespace.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>PrivateDevices=</varname></term>
+
+                                <listitem><para>Takes a boolean
+                                argument. If true, sets up a new /dev
+                                namespace for the executed processes
+                                and only adds API pseudo devices such
+                                as <filename>/dev/null</filename>,
+                                <filename>/dev/zero</filename> or
+                                <filename>/dev/random</filename> (as
+                                well as the pseudo TTY subsystem) to
+                                it, but no physical devices such as
+                                <filename>/dev/sda</filename>. This is
+                                useful to securely turn off physical
+                                device access by the executed
+                                process. Defaults to false. Enabling
+                                this option will also remove
+                                <constant>CAP_MKNOD</constant> from
+                                the capability bounding set for the
+                                unit (see above), and set
+                                <varname>DevicePolicy=closed</varname>
+                                (see
+                                <citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                                for details). Note that using this
+                                setting will disconnect propagation of
+                                mounts from the service to the host
+                                (propagation in the opposite direction
+                                continues to work). This means that
+                                this setting may not be used for
+                                services which shall be able to
+                                install mount points in the main mount
+                                namespace.</para></listitem>
                         </varlistentry>
 
                         <varlistentry>
                                 available to the executed process.
                                 This is useful to securely turn off
                                 network access by the executed
-                                process. Defaults to false. Note that
-                                it is possible to run two or more
-                                units within the same private network
+                                process. Defaults to false. It is
+                                possible to run two or more units
+                                within the same private network
                                 namespace by using the
                                 <varname>JoinsNamespaceOf=</varname>
                                 directive, see
                                 <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
-                                for details.</para></listitem>
+                                for details. Note that this option
+                                will disconnect all socket families
+                                from the host, this includes
+                                AF_NETLINK and AF_UNIX. The latter has
+                                the effect that AF_UNIX sockets in the
+                                abstract socket namespace will become
+                                unavailable to the processes (however,
+                                those located in the file system will
+                                continue to be
+                                accessible).</para></listitem>
                         </varlistentry>
 
                         <varlistentry>
-                                <term><varname>PrivateDevices=</varname></term>
+                                <term><varname>ProtectSystem=</varname></term>
 
                                 <listitem><para>Takes a boolean
-                                argument. If true, sets up a new /dev
-                                namespace for the executed processes
-                                and only adds API pseudo devices such
-                                as <filename>/dev/null</filename>,
-                                <filename>/dev/zero</filename> or
-                                <filename>/dev/random</filename> to
-                                it, but no physical devices such as
-                                <filename>/dev/sda</filename>. This is
-                                useful to securely turn off physical
-                                device access by the executed
-                                process. Defaults to
-                                false.</para></listitem>
+                                argument or
+                                <literal>full</literal>. If true,
+                                mounts the <filename>/usr</filename>
+                                directory read-only for processes
+                                invoked by this unit. If set to
+                                <literal>full</literal>, the
+                                <filename>/etc</filename> directory is mounted
+                                read-only, too. This setting ensures
+                                that any modification of the vendor
+                                supplied operating system (and
+                                optionally its configuration) is
+                                prohibited for the service. It is
+                                recommended to enable this setting for
+                                all long-running services, unless they
+                                are involved with system updates or
+                                need to modify the operating system in
+                                other ways. Note however that
+                                processes retaining the CAP_SYS_ADMIN
+                                capability can undo the effect of this
+                                setting. This setting is hence
+                                particularly useful for daemons which
+                                have this capability removed, for
+                                example with
+                                <varname>CapabilityBoundingSet=</varname>. Defaults
+                                to off.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>ProtectHome=</varname></term>
+
+                                <listitem><para>Takes a boolean
+                                argument or
+                                <literal>read-only</literal>. If true,
+                                the directories
+                                <filename>/home</filename> and
+                                <filename>/run/user</filename> are
+                                made inaccessible and empty for
+                                processes invoked by this unit. If set
+                                to <literal>read-only</literal>, the
+                                two directories are made read-only
+                                instead. It is recommended to enable
+                                this setting for all long-running
+                                services (in particular network-facing
+                                ones), to ensure they cannot get access
+                                to private user data, unless the
+                                services actually require access to
+                                the user's private data. Note however
+                                that processes retaining the
+                                CAP_SYS_ADMIN capability can undo the
+                                effect of this setting. This setting
+                                is hence particularly useful for
+                                daemons which have this capability
+                                removed, for example with
+                                <varname>CapabilityBoundingSet=</varname>. Defaults
+                                to off.</para></listitem>
                         </varlistentry>
 
                         <varlistentry>
                                 <option>shared</option>,
                                 <option>slave</option> or
                                 <option>private</option>, which
-                                control whether the file system
-                                namespace set up for this unit's
-                                processes will receive or propagate
-                                new mounts. See
+                                control whether mounts in the file
+                                system namespace set up for this
+                                unit's processes will receive or
+                                propagate mounts or unmounts. See
                                 <citerefentry><refentrytitle>mount</refentrytitle><manvolnum>2</manvolnum></citerefentry>
-                                for details. Default to
-                                <option>shared</option>.</para></listitem>
+                                for details. Defaults to
+                                <option>shared</option>. Use
+                                <option>shared</option> to ensure that
+                                mounts and unmounts are propagated
+                                from the host to the container and
+                                vice versa. Use <option>slave</option>
+                                to run processes so that none of their
+                                mounts and unmounts will propagate to
+                                the host. Use <option>private</option>
+                                to also ensure that no mounts and
+                                unmounts from the host will propagate
+                                into the unit processes'
+                                namespace. Note that
+                                <option>slave</option> means that file
+                                systems mounted on the host might stay
+                                mounted continously in the unit's
+                                namespace, and thus keep the device
+                                busy. Note that the file system
+                                namespace related options
+                                (<varname>PrivateTmp=</varname>,
+                                <varname>PrivateDevices=</varname>,
+                                <varname>ProtectSystem=</varname>,
+                                <varname>ProtectHome=</varname>,
+                                <varname>ReadOnlyDirectories=</varname>,
+                                <varname>InaccessibleDirectories=</varname>
+                                and
+                                <varname>ReadWriteDirectories=</varname>)
+                                require that mount and unmount
+                                propagation from the unit's file
+                                system namespace is disabled, and
+                                hence downgrade
+                                <option>shared</option> to
+                                <option>slave</option>.
+                                </para></listitem>
                         </varlistentry>
 
                         <varlistentry>
                         <varlistentry>
                                 <term><varname>AppArmorProfile=</varname></term>
 
-                                <listitem><para>Take a profile name as argument.
+                                <listitem><para>Takes a profile name as argument.
                                 The process executed by the unit will switch to
                                 this profile when started. Profiles must already
                                 be loaded in the kernel, or the unit will fail.
                         </varlistentry>
 
                         <varlistentry>
+                                <term><varname>SmackProcessLabel=</varname></term>
+
+                                <listitem><para>Takes a
+                                <option>SMACK64</option> security
+                                label as argument. The process
+                                executed by the unit will be started
+                                under this label and SMACK will decide
+                                whether the processes is allowed to
+                                run or not based on it. The process
+                                will continue to run under the label
+                                specified here unless the executable
+                                has its own
+                                <option>SMACK64EXEC</option> label, in
+                                which case the process will transition
+                                to run under that label. When not
+                                specified, the label that systemd is
+                                running under is used. This directive
+                                is ignored if SMACK is
+                                disabled.</para>
+
+                                <para>The value may be prefixed by
+                                <literal>-</literal>, in which case
+                                all errors will be ignored. An empty
+                                value may be specified to unset
+                                previous assignments.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
                                 <term><varname>IgnoreSIGPIPE=</varname></term>
 
                                 <listitem><para>Takes a boolean
                         <varlistentry>
                                 <term><varname>SystemCallFilter=</varname></term>
 
-                                <listitem><para>Takes a space-separated
-                                list of system call
+                                <listitem><para>Takes a
+                                space-separated list of system call
                                 names. If this setting is used, all
                                 system calls executed by the unit
                                 processes except for the listed ones
                                 the effect is inverted: only the
                                 listed system calls will result in
                                 immediate process termination
-                                (blacklisting). If this option is used,
+                                (blacklisting). If running in user
+                                mode and this option is used,
                                 <varname>NoNewPrivileges=yes</varname>
-                                is implied. This feature makes use of
-                                the Secure Computing Mode 2 interfaces
-                                of the kernel ('seccomp filtering')
-                                and is useful for enforcing a minimal
+                                is implied. This feature makes use of the
+                                Secure Computing Mode 2 interfaces of
+                                the kernel ('seccomp filtering') and
+                                is useful for enforcing a minimal
                                 sandboxing environment. Note that the
                                 <function>execve</function>,
                                 <function>rt_sigreturn</function>,
                                 <constant>x86</constant>,
                                 <constant>x86-64</constant>,
                                 <constant>x32</constant>,
-                                <constant>arm</constant> as well as the
-                                special identifier
-                                <constant>native</constant>. Only system
-                                calls of the specified architectures
-                                will be permitted to processes of this
-                                unit. This is an effective way to
-                                disable compatibility with non-native
-                                architectures for processes, for
-                                example to prohibit execution of
-                                32-bit x86 binaries on 64-bit x86-64
-                                systems. The special
+                                <constant>arm</constant> as well as
+                                the special identifier
+                                <constant>native</constant>. Only
+                                system calls of the specified
+                                architectures will be permitted to
+                                processes of this unit. This is an
+                                effective way to disable compatibility
+                                with non-native architectures for
+                                processes, for example to prohibit
+                                execution of 32-bit x86 binaries on
+                                64-bit x86-64 systems. The special
                                 <constant>native</constant> identifier
                                 implicitly maps to the native
                                 architecture of the system (or more
                                 strictly: to the architecture the
-                                system manager is compiled for). Note
-                                that setting this option to a
-                                non-empty list implies that
-                                <constant>native</constant> is included
-                                too. By default, this option is set to
-                                the empty list, i.e. no architecture
-                                system call filtering is
+                                system manager is compiled for). If
+                                running in user mode and this option
+                                is used,
+                                <varname>NoNewPrivileges=yes</varname>
+                                is implied. Note that setting this
+                                option to a non-empty list implies
+                                that <constant>native</constant> is
+                                included too. By default, this option
+                                is set to the empty list, i.e. no
+                                architecture system call filtering is
                                 applied.</para></listitem>
                         </varlistentry>
 
                         <varlistentry>
+                                <term><varname>RestrictAddressFamilies=</varname></term>
+
+                                <listitem><para>Restricts the set of
+                                socket address families accessible to
+                                the processes of this unit. Takes a
+                                space-separated list of address family
+                                names to whitelist, such as
+                                <constant>AF_UNIX</constant>,
+                                <constant>AF_INET</constant> or
+                                <constant>AF_INET6</constant>. When
+                                prefixed with <constant>~</constant>
+                                the listed address families will be
+                                applied as blacklist, otherwise as
+                                whitelist. Note that this restricts
+                                access to the
+                                <citerefentry><refentrytitle>socket</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+                                system call only. Sockets passed into
+                                the process by other means (for
+                                example, by using socket activation
+                                with socket units, see
+                                <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>)
+                                are unaffected. Also, sockets created
+                                with <function>socketpair()</function>
+                                (which creates connected AF_UNIX
+                                sockets only) are unaffected. Note
+                                that this option has no effect on
+                                32-bit x86 and is ignored (but works
+                                correctly on x86-64). If running in user
+                                mode and this option is used,
+                                <varname>NoNewPrivileges=yes</varname>
+                                is implied. By default, no
+                                restriction applies, all address
+                                families are accessible to
+                                processes. If assigned the empty
+                                string, any previous list changes are
+                                undone.</para>
+
+                                <para>Use this option to limit
+                                exposure of processes to remote
+                                systems, in particular via exotic
+                                network protocols. Note that in most
+                                cases, the local
+                                <constant>AF_UNIX</constant> address
+                                family should be included in the
+                                configured whitelist as it is
+                                frequently used for local
+                                communication, including for
+                                <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+                                logging.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
                                 <term><varname>Personality=</varname></term>
 
                                 <listitem><para>Controls which
                                 processes. Takes one of
                                 <constant>x86</constant> and
                                 <constant>x86-64</constant>. This is
-                                useful when running 32bit services on
-                                a 64bit host system. If not specified
+                                useful when running 32-bit services on
+                                a 64-bit host system. If not specified,
                                 the personality is left unmodified and
                                 thus reflects the personality of the
                                 host system's
                                 kernel.</para></listitem>
                         </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>RuntimeDirectory=</varname></term>
+                                <term><varname>RuntimeDirectoryMode=</varname></term>
+
+                                <listitem><para>Takes a list of
+                                directory names. If set, one or more
+                                directories by the specified names
+                                will be created below
+                                <filename>/run</filename> (for system
+                                services) or below
+                                <varname>$XDG_RUNTIME_DIR</varname>
+                                (for user services) when the unit is
+                                started, and removed when the unit is
+                                stopped. The directories will have the
+                                access mode specified in
+                                <varname>RuntimeDirectoryMode=</varname>,
+                                and will be owned by the user and
+                                group specified in
+                                <varname>User=</varname> and
+                                <varname>Group=</varname>. Use this to
+                                manage one or more runtime directories
+                                of the unit and bind their lifetime to
+                                the daemon runtime. The specified
+                                directory names must be relative, and
+                                may not include a
+                                <literal>/</literal>, i.e. must refer
+                                to simple directories to create or
+                                remove. This is particularly useful
+                                for unprivileged daemons that cannot
+                                create runtime directories in
+                                <filename>/run</filename> due to lack
+                                of privileges, and to make sure the
+                                runtime directory is cleaned up
+                                automatically after use. For runtime
+                                directories that require more complex
+                                or different configuration or lifetime
+                                guarantees, please consider using
+                                <citerefentry><refentrytitle>tmpfiles.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para></listitem>
+                        </varlistentry>
+
                 </variablelist>
         </refsect1>
 
                                 or
                                 <varname>StandardError=tty</varname>).
                                 See
-                                <citerefentry><refentrytitle>termcap</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+                                <citerefentry project='man-pages'><refentrytitle>termcap</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
                                 </para></listitem>
                         </varlistentry>
                 </variablelist>
                 <varname>systemd.setenv=</varname> (see
                 <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>). Additional
                 variables may also be set through PAM,
-                c.f. <citerefentry><refentrytitle>pam_env</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+                cf. <citerefentry project='man-pages'><refentrytitle>pam_env</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
         </refsect1>
 
         <refsect1>
                           <citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
                           <citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
                           <citerefentry><refentrytitle>systemd.directives</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
-                          <citerefentry><refentrytitle>exec</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                          <citerefentry><refentrytitle>tmpfiles.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry project='man-pages'><refentrytitle>exec</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                   </para>
         </refsect1>
 
index d77e6eb..154b95a 100644 (file)
                                         number causing this entry, if
                                         any. Contains the numeric
                                         value of
-                                        <citerefentry><refentrytitle>errno</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                                        <citerefentry project='man-pages'><refentrytitle>errno</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                                         formatted as a decimal
                                         string.</para>
                                 </listitem>
                                         (formatted as decimal string),
                                         the identifier string
                                         (i.e. "tag"), and the client
-                                        PID.</para>
+                                        PID. (Note that the tag is
+                                        usually derived from glibc's
+                                        <varname>program_invocation_short_name</varname>
+                                        variable, see <citerefentry><refentrytitle>program_invocation_short_name</refentrytitle><manvolnum>3</manvolnum></citerefentry>.)</para>
                                 </listitem>
 
                         </varlistentry>
                         <varlistentry>
                                 <term><varname>_CAP_EFFECTIVE=</varname></term>
                                 <listitem>
-                                        <para>The effective <citerefentry><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry> of
+                                        <para>The effective <citerefentry project='man-pages'><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry> of
                                         the process the journal entry
                                         originates from.</para>
                                 </listitem>
                                         messages containing coredumps from
                                         system and session units.
                                         See
-                                        <citerefentry><refentrytitle>systemd-coredumpctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
+                                        <citerefentry><refentrytitle>coredumpctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
                                         </para>
                                 </listitem>
                         </varlistentry>
                                         microseconds, formatted as a decimal
                                         string. To be useful as an
                                         address for the entry, this
-                                        should be combined with with the
+                                        should be combined with the
                                         boot ID in <literal>_BOOT_ID=</literal>.
                                         </para>
                                 </listitem>
                           <citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                           <citerefentry><refentrytitle>journald.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
                           <citerefentry><refentrytitle>sd-journal</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
-                          <citerefentry><refentrytitle>systemd-coredumpctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                          <citerefentry><refentrytitle>coredumpctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                           <citerefentry><refentrytitle>systemd.directives</refentrytitle><manvolnum>7</manvolnum></citerefentry>
                   </para>
         </refsect1>
diff --git a/man/systemd.link.xml b/man/systemd.link.xml
new file mode 100644 (file)
index 0000000..6075b39
--- /dev/null
@@ -0,0 +1,402 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2014 Tom Gundersen
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd.link">
+        <refentryinfo>
+                <title>systemd.link</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Tom</firstname>
+                                <surname>Gundersen</surname>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd.link</refentrytitle>
+                <manvolnum>5</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd.link</refname>
+                <refpurpose>Network device configuration</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename><replaceable>link</replaceable>.link</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para>Network link configuration is performed by the <command>net_setup_link</command>
+                udev builtin.</para>
+
+                <para>The link files are read from the files located in the
+                system network directory <filename>/usr/lib/systemd/network</filename>,
+                the volatile runtime network directory <filename>/run/systemd/network</filename>,
+                and the local administration network directory <filename>/etc/systemd/network</filename>.
+                Link files must have the extension <filename>.link</filename>; other extensions are ignored.
+                All link files are collectively sorted and processed in lexical order,
+                regardless of the directories in which they live. However, files with
+                identical filenames replace each other. Files in <filename>/etc</filename>
+                have the highest priority, files in <filename>/run</filename> take precedence
+                over files with the same name in <filename>/usr/lib</filename>. This can be
+                used to override a system-supplied link file with a local file if needed;
+                a symlink in <filename>/etc</filename> with the same name as a link file in
+                <filename>/usr/lib</filename>, pointing to <filename>/dev/null</filename>,
+                disables the link file entirely.</para>
+
+                <para>The link file contains a <literal>[Match]</literal> section, which
+                determines if a given link file may be applied to a given device; and a
+                <literal>[Link]</literal> section specifying how the device should be
+                configured. The first (in lexical order) of the link files that matches
+                a given device is applied.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>[Match] Section Options</title>
+
+                <para>A link file is said to match a device if each of the entries in the
+                <literal>[Match]</literal> section matches, or if the section is empty.
+                The following keys are accepted:</para>
+
+                <variablelist class='network-directives'>
+                        <varlistentry>
+                                <term><varname>MACAddress=</varname></term>
+                                <listitem>
+                                        <para>The hardware address.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><varname>Path=</varname></term>
+                                <listitem>
+                                <para>The persistent path, as exposed by the
+                                udev property <literal>ID_PATH</literal>. May
+                                contain shell style globs.</para>
+                        </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><varname>Driver=</varname></term>
+                                <listitem>
+                                        <para>The driver currently bound to the device,
+                                        as exposed by the udev property <literal>DRIVER</literal>
+                                        of its parent device, or if that is not set, the
+                                        driver as exposed by <literal>ethtool -i</literal>
+                                        of the device itself.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><varname>Type=</varname></term>
+                                <listitem>
+                                        <para>The device type, as exposed by the udev
+                                        property <literal>DEVTYPE</literal>.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><varname>Host=</varname></term>
+                                <listitem>
+                                        <para>Matches against the hostname or machine
+                                        ID of the host. See <literal>ConditionHost=</literal> in
+                                        <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                                        for details.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><varname>Virtualization=</varname></term>
+                                <listitem>
+                                        <para>Checks whether the system is executed in
+                                        a virtualized environment and optionally test
+                                        whether it is a specific implementation. See
+                                        <literal>ConditionVirtualization=</literal> in
+                                        <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                                        for details.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><varname>KernelCommandLine=</varname></term>
+                                <listitem>
+                                        <para>Checks whether a specific kernel command
+                                        line option is set (or if prefixed with the
+                                        exclamation mark unset). See
+                                        <literal>ConditionKernelCommandLine=</literal> in
+                                        <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                                        for details.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><varname>Architecture=</varname></term>
+                                <listitem>
+                                        <para>Checks whether the system is running on a
+                                        specific architecture. See
+                                        <literal>ConditionArchitecture=</literal> in
+                                        <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                                        for details.</para>
+                                </listitem>
+                        </varlistentry>
+                </variablelist>
+
+        </refsect1>
+
+        <refsect1>
+                <title>[Link] Section Options</title>
+
+                <para>The <literal>[Link]</literal> section accepts the following
+                keys:</para>
+
+                <variablelist class='network-directives'>
+                        <varlistentry>
+                                <term><varname>Description=</varname></term>
+                                <listitem>
+                                        <para>A description of the device.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><varname>Alias=</varname></term>
+                                <listitem>
+                                        <para>The <literal>ifalias</literal> is set to
+                                        this value.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><varname>MACAddressPolicy=</varname></term>
+                                <listitem>
+                                        <para>The policy by which the MAC address
+                                        should be set. The available policies are:
+                                        </para>
+
+                                        <variablelist>
+                                                <varlistentry>
+                                                        <term><literal>persistent</literal></term>
+                                                        <listitem>
+                                                                <para>If the hardware has a persistent
+                                                                MAC address, as most hardware should,
+                                                                and if it is used by the kernel, nothing
+                                                                is done. Otherwise, a new MAC address
+                                                                is generated which is guaranteed to be
+                                                                the same on every boot for the given
+                                                                machine and the given device, but which
+                                                                is otherwise random.</para>
+                                                        </listitem>
+                                                </varlistentry>
+                                                <varlistentry>
+                                                        <term><literal>random</literal></term>
+                                                        <listitem>
+                                                                <para>If the kernel is using a random MAC
+                                                                address, nothing is done. Otherwise, a new
+                                                                address is randomly generated each time the
+                                                                device appears, typically at boot.</para>
+                                                        </listitem>
+                                                </varlistentry>
+                                        </variablelist>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><varname>MACAddress=</varname></term>
+                                <listitem>
+                                        <para>The MAC address to use, if no
+                                        <literal>MACAddressPolicy=</literal>
+                                        is specified.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><varname>NamePolicy=</varname></term>
+                                <listitem>
+                                        <para>An ordered, space-separated list of
+                                        policies by which the interface name should
+                                        be set. <literal>NamePolicy</literal> may be
+                                        disabled by specifying
+                                        <literal>net.ifnames=0</literal> on the kernel
+                                        commandline. Each of the policies may fail, and
+                                        the first successful one is used. The name is
+                                        not set directly, but is exported to udev as
+                                        the property <literal>ID_NET_NAME</literal>,
+                                        which is, by default, used by a udev rule to set
+                                        <literal>NAME</literal>. If the name has already
+                                        been set by userspace, no renaming is performed.
+                                        The available policies are:</para>
+
+                                        <variablelist>
+                                                <varlistentry>
+                                                        <term><literal>kernel</literal></term>
+                                                        <listitem>
+                                                                <para>If the kernel claims that the name it
+                                                                has set for a device is predictable, then
+                                                                no renaming is performed.
+                                                                </para>
+                                                        </listitem>
+                                                </varlistentry>
+                                                <varlistentry>
+                                                        <term><literal>database</literal></term>
+                                                        <listitem>
+                                                                <para>The name is set based on entries in
+                                                                the udev's Hardware Database with the key
+                                                                <literal>ID_NET_NAME_FROM_DATABASE</literal>.
+                                                                </para>
+                                                        </listitem>
+                                                </varlistentry>
+                                                <varlistentry>
+                                                        <term><literal>onboard</literal></term>
+                                                        <listitem>
+                                                                <para>The name is set based on information given by
+                                                                the firmware for on-board devices, as exported by
+                                                                the udev property <literal>ID_NET_NAME_ONBOARD</literal>.
+                                                                </para>
+                                                        </listitem>
+                                                </varlistentry>
+                                                <varlistentry>
+                                                        <term><literal>slot</literal></term>
+                                                        <listitem>
+                                                                <para>The name is set based on information given by
+                                                                the firmware for hot-plug devices, as exported by
+                                                                the udev property <literal>ID_NET_NAME_SLOT</literal>.
+                                                                </para>
+                                                        </listitem>
+                                                </varlistentry>
+                                                <varlistentry>
+                                                        <term><literal>path</literal></term>
+                                                        <listitem>
+                                                                <para>The name is set based on the device's physical
+                                                                location, as exported by the udev property
+                                                                <literal>ID_NET_NAME_PATH</literal>.</para>
+                                                        </listitem>
+                                                </varlistentry>
+                                                <varlistentry>
+                                                        <term><literal>mac</literal></term>
+                                                        <listitem>
+                                                                <para>The name is set based on the device's
+                                                                persistent MAC address, as exported by the udev
+                                                                property <literal>ID_NET_NAME_MAC</literal>.</para>
+                                                        </listitem>
+                                                </varlistentry>
+                                        </variablelist>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><varname>Name=</varname></term>
+                                <listitem>
+                                        <para>The interface name to use in case all the
+                                        policies specified in
+                                        <varname>NamePolicy=</varname> fail, or in case
+                                        <varname>NamePolicy=</varname> is missing or
+                                        disabled.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><varname>MTUBytes=</varname></term>
+                                <listitem>
+                                        <para>The maximum transmission unit in bytes to
+                                        set for the device. The usual suffixes K, M, G,
+                                        are supported and are understood to the base of
+                                        1024.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><varname>BitsPerSecond=</varname></term>
+                                <listitem>
+                                        <para>The speed to set for the device, the
+                                        value is rounded down to the nearest Mbps.
+                                        The usual suffixes K, M, G, are supported and
+                                        are understood to the base of 1000.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><varname>Duplex=</varname></term>
+                                <listitem>
+                                        <para>The duplex mode to set for the device.
+                                        The accepted values are <literal>half</literal>
+                                        and <literal>full</literal>.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><varname>WakeOnLan=</varname></term>
+                                <listitem>
+                                        <para>The Wake-on-LAN policy to set for the
+                                        device. The supported values are:</para>
+
+                                        <variablelist>
+                                                <varlistentry>
+                                                        <term><literal>phy</literal></term>
+                                                        <listitem>
+                                                                <para>Wake on PHY activity.</para>
+                                                        </listitem>
+                                                </varlistentry>
+                                                <varlistentry>
+                                                        <term><literal>magic</literal></term>
+                                                        <listitem>
+                                                                <para>Wake on receipt of a magic packet.
+                                                                </para>
+                                                        </listitem>
+                                                </varlistentry>
+                                                <varlistentry>
+                                                        <term><literal>off</literal></term>
+                                                        <listitem>
+                                                                <para>Never wake.</para>
+                                                        </listitem>
+                                                </varlistentry>
+                                        </variablelist>
+                                </listitem>
+                        </varlistentry>
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>Example</title>
+                <example>
+                        <title>/etc/systemd/network/wireless.link</title>
+
+                        <programlisting>[Match]
+MACAddress=12:34:56:78:9a:bc
+Driver=brcmsmac
+Path=pci-0000:02:00.0-*
+Type=wlan
+Virtualization=no
+Host=my-laptop
+Architecture=x86-64
+
+[Link]
+Name=wireless0
+MTUBytes=1450
+BitsPerSecond=10M
+WakeOnLan=magic
+MACAddress=cb:a9:87:65:43:21</programlisting>
+                </example>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry>
+                                <refentrytitle>systemd-udevd.service</refentrytitle><manvolnum>8</manvolnum>
+                        </citerefentry>,
+                        <citerefentry>
+                                <refentrytitle>udevadm</refentrytitle><manvolnum>8</manvolnum>
+                        </citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
index 657cf11..f116aa5 100644 (file)
                 monitored by systemd and appear like any other mount
                 unit in systemd.
                 See <filename>/proc/self/mountinfo</filename> description
-                in <citerefentry><refentrytitle>proc</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+                in <citerefentry project='man-pages'><refentrytitle>proc</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
                 </para>
 
                 <para>Some file systems have special semantics as API
                 which influence how dependencies are created for mount
                 points from <filename>/etc/fstab</filename>. systemd
                 will create a dependency of type
-                <option>Wants</option> from either
-                <filename>local-fs.target</filename> or
+                <option>Wants</option> or <option>Requires</option>
+                (see option <option>nofail</option> below), from
+                either <filename>local-fs.target</filename> or
                 <filename>remote-fs.target</filename>, depending
-                whether the file system is local or remote. If
-                <option>x-systemd.automount</option> is set, an
-                automount unit will be created for the file
-                system. See
-                <citerefentry><refentrytitle>systemd.automount</refentrytitle><manvolnum>5</manvolnum></citerefentry>
-                for details. If
-                <option>x-systemd.device-timeout=</option> is
-                specified, it may be used to configure how long systemd
-                should wait for a device to show up before giving up
-                on an entry from
-                <filename>/etc/fstab</filename>. Specify a time in
-                seconds or explicitly specify a unit as
-                <literal>s</literal>, <literal>min</literal>,
-                <literal>h</literal>, <literal>ms</literal>.</para>
-
-                <para>If <option>nofail</option> is given, this mount
-                will be only wanted, not required, by the
-                <filename>local-fs.target</filename>. This means that
-                the boot will continue even if this mount point is not
-                mounted successfully. Option <option>fail</option> has
-                the opposite meaning and is the default.</para>
-
-                <para>If <option>noauto</option> is given, this mount
-                will not be added as a dependency for
-                <filename>local-fs.target</filename>. This means that
-                it will not be mounted automatically during boot,
-                unless it is pulled in by some other unit. Option
-                <option>auto</option> has the opposite meaning and is
-                the default.</para>
+                whether the file system is local or remote.</para>
+
+                <variablelist class='fstab-options'>
+
+                  <varlistentry>
+                    <term><option>x-systemd.automount</option></term>
+
+                    <listitem><para>An automount unit will be created
+                    for the file system. See
+                    <citerefentry><refentrytitle>systemd.automount</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                    for details.</para></listitem>
+                  </varlistentry>
+
+                  <varlistentry>
+                    <term><option>x-systemd.device-timeout=</option></term>
+
+                    <listitem><para>Configure how long systemd should
+                    wait for a device to show up before giving up on
+                    an entry from
+                    <filename>/etc/fstab</filename>. Specify a time in
+                    seconds or explicitly append a unit as
+                    <literal>s</literal>, <literal>min</literal>,
+                    <literal>h</literal>,
+                    <literal>ms</literal>.</para>
+
+                    <para>Note that this option can only be used in
+                    <filename>/etc/fstab</filename>, and will be
+                    ignored when part of <varname>Options=</varname>
+                    setting in a unit file.</para>
+                    </listitem>
+                  </varlistentry>
+
+                  <varlistentry>
+                    <term><option>nofail</option></term>
+                    <term><option>fail</option></term>
+
+                    <listitem><para>With <option>nofail</option> this
+                    mount will be only wanted, not required, by the
+                    <filename>local-fs.target</filename>. This means
+                    that the boot will continue even if this mount
+                    point is not mounted successfully. Option
+                    <option>fail</option> has the opposite meaning and
+                    is the default.</para>
+                    </listitem>
+                  </varlistentry>
+
+                  <varlistentry>
+                    <term><option>noauto</option></term>
+                    <term><option>auto</option></term>
+
+                    <listitem><para>With <option>noauto</option>, this
+                    mount will not be added as a dependency for
+                    <filename>local-fs.target</filename>. This means
+                    that it will not be mounted automatically during
+                    boot, unless it is pulled in by some other
+                    unit. Option <option>auto</option> has the
+                    opposite meaning and is the default.</para>
+                    </listitem>
+                  </varlistentry>
+
+                  <varlistentry>
+                    <term><option>x-initrd.mount</option></term>
+
+                    <listitem><para>An additional filesystem to be
+                    mounted in the initramfs. See
+                    <filename>initrd-fs.target</filename> description
+                    in
+                    <citerefentry><refentrytitle>systemd.special</refentrytitle><manvolnum>7</manvolnum></citerefentry>.
+                    </para></listitem>
+                  </varlistentry>
+                </variablelist>
 
                 <para>If a mount point is configured in both
                 <filename>/etc/fstab</filename> and a unit file that
                         </varlistentry>
 
                         <varlistentry>
+                                <term><varname>SloppyOptions=</varname></term>
+
+                                <listitem><para>Takes a boolean
+                                argument. If true, parsing of the
+                                options specified in
+                                <varname>Options=</varname> is
+                                relaxed, and unknown mount options are
+                                tolerated. This corresponds with
+                                <citerefentry><refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum></citerefentry>'s
+                                <parameter>-s</parameter>
+                                switch. Defaults to
+                                off.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
                                 <term><varname>DirectoryMode=</varname></term>
                                 <listitem><para>Directories of mount
                                 points (and any parent directories)
                           <citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
                           <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
                           <citerefentry><refentrytitle>systemd.device</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
-                          <citerefentry><refentrytitle>proc</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                          <citerefentry project='man-pages'><refentrytitle>proc</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
                           <citerefentry><refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
                           <citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
                           <citerefentry><refentrytitle>systemd.directives</refentrytitle><manvolnum>7</manvolnum></citerefentry>
diff --git a/man/systemd.netdev.xml b/man/systemd.netdev.xml
new file mode 100644 (file)
index 0000000..275ee52
--- /dev/null
@@ -0,0 +1,595 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2013 Tom Gundersen
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd.netdev" conditional='ENABLE_NETWORKD'>
+
+        <refentryinfo>
+                <title>systemd.network</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Tom</firstname>
+                                <surname>Gundersen</surname>
+                                <email>teg@jklm.no</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd.netdev</refentrytitle>
+                <manvolnum>5</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd.netdev</refname>
+                <refpurpose>Virtual Network Device configuration</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename><replaceable>netdev</replaceable>.netdev</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para>Network setup is performed by
+                <citerefentry><refentrytitle>systemd-networkd</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
+                </para>
+
+                <para>Virtual Network Device files must have the extension
+                <filename>.netdev</filename>; other extensions are ignored. Virtual
+                network devices are created as soon as networkd is started. If a netdev
+                with the specified name already exists, networkd will use that as-is
+                rather than create its own. Note that the settings of the pre-existing
+                netdev will not be changed by networkd.</para>
+
+                <para>The <filename>.netdev</filename> files are read from the files located in the
+                system network directory <filename>/usr/lib/systemd/network</filename>,
+                the volatile runtime network directory
+                <filename>/run/systemd/network</filename> and the local administration
+                network directory <filename>/etc/systemd/network</filename>.
+                All configuration files are collectively sorted and processed in lexical order,
+                regardless of the directories in which they live. However, files with
+                identical filenames replace each other. Files in
+                <filename>/etc</filename> have the highest priority, files in
+                <filename>/run</filename> take precedence over files with the same
+                name in <filename>/usr/lib</filename>. This can be used to override a
+                system-supplied configuration file with a local file if needed; a symlink in
+                <filename>/etc</filename> with the same name as a configuration file in
+                <filename>/usr/lib</filename>, pointing to <filename>/dev/null</filename>,
+                disables the configuration file entirely.</para>
+
+        </refsect1>
+
+        <refsect1>
+                <title>[Match] Section Options</title>
+
+                <para>A virtual network device is only created if the
+                <literal>[Match]</literal> section matches the current
+                environment, or if the section is empty. The following keys are accepted:</para>
+
+                        <variablelist class='network-directives'>
+                                <varlistentry>
+                                        <term><varname>Host=</varname></term>
+                                        <listitem>
+                                                <para>Matches against the hostname or machine ID of the
+                                                host. See <literal>ConditionHost=</literal> in
+                                                <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                                                for details.
+                                                </para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>Virtualization=</varname></term>
+                                        <listitem>
+                                                <para>Checks whether the system is executed in a virtualized
+                                                environment and optionally test whether it is a specific
+                                                implementation. See <literal>ConditionVirtualization=</literal> in
+                                                <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                                                for details.
+                                                </para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>KernelCommandLine=</varname></term>
+                                        <listitem>
+                                                <para>Checks whether a specific kernel command line option is
+                                                set (or if prefixed with the exclamation mark unset). See
+                                                <literal>ConditionKernelCommandLine=</literal> in
+                                                <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                                                for details.
+                                                </para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>Architecture=</varname></term>
+                                        <listitem>
+                                                <para>Checks whether the system is running on a specific
+                                                architecture. See <literal>ConditionArchitecture=</literal> in
+                                                <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                                                for details.
+                                                </para>
+                                        </listitem>
+                                </varlistentry>
+                        </variablelist>
+
+        </refsect1>
+
+        <refsect1>
+                <title>[NetDev] Section Options</title>
+
+                        <para>The <literal>[NetDev]</literal> section accepts the following
+                        keys:</para>
+
+                        <variablelist class='network-directives'>
+                                <varlistentry>
+                                        <term><varname>Description=</varname></term>
+                                        <listitem>
+                                                <para>A free-form description of the netdev.
+                                                </para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>Name=</varname></term>
+                                        <listitem>
+                                                <para>The interface name used when creating the
+                                                netdev. This option is compulsory.</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>Kind=</varname></term>
+                                        <listitem>
+                                                <para>The netdev kind. Currently, <literal>bridge</literal>,
+                                                <literal>bond</literal>, <literal>vlan</literal>,
+                                                <literal>macvlan</literal>, <literal>vxlan</literal>,
+                                                <literal>ipip</literal>, <literal>gre</literal>,
+                                                <literal>sit</literal>, <literal>vti</literal>,
+                                                <literal>veth</literal>, <literal>tun</literal>,
+                                                <literal>tap</literal> and <literal>dummy</literal>
+                                                are supported. This option is compulsory.</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>MTUBytes=</varname></term>
+                                        <listitem>
+                                                <para>The maximum transmission unit in bytes to
+                                                set for the device. The usual suffixes K, M, G,
+                                                are supported and are understood to the base of
+                                                1024. This key is not currently suported for
+                                                <literal>tun</literal> or <literal>tap</literal> devices.
+                                                </para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>MACAddress=</varname></term>
+                                        <listitem>
+                                                <para>The MAC address to use for the device.
+                                                If none is given, one is generated based on
+                                                the interface name and the
+                                                <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+                                                This key is not currently suported for <literal>tun</literal> or <literal>tap</literal> devices.
+                                                </para>
+                                        </listitem>
+                                </varlistentry>
+                        </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>[VLAN] Section Options</title>
+
+                        <para>The <literal>[VLAN]</literal> section only applies for netdevs of kind <literal>vlan</literal>,
+                        and accepts the following key:</para>
+
+                        <variablelist class='network-directives'>
+                                <varlistentry>
+                                        <term><varname>Id=</varname></term>
+                                        <listitem>
+                                                <para>The VLAN ID to use. An integer in the range 0–4094.
+                                                This option is compulsory.</para>
+                                        </listitem>
+                                </varlistentry>
+                        </variablelist>
+
+        </refsect1>
+
+        <refsect1>
+                <title>[MACVLAN] Section Options</title>
+
+                        <para>The <literal>[MACVLAN]</literal> section only applies for netdevs of kind
+                        <literal>macvlan</literal>, and accepts the following key:</para>
+
+                        <variablelist class='network-directives'>
+                                <varlistentry>
+                                        <term><varname>Mode=</varname></term>
+                                        <listitem>
+                                                <para>The MACVLAN mode to use. The supported options are
+                                                <literal>private</literal>, <literal>vepa</literal>,
+                                                <literal>bridge</literal> and <literal>passthru</literal>.
+                                                </para>
+                                        </listitem>
+                                </varlistentry>
+                        </variablelist>
+
+        </refsect1>
+        <refsect1>
+                <title>[VXLAN] Section Options</title>
+                        <para>The <literal>[VXLAN]</literal> section only applies for netdevs of kind
+                        <literal>vxlan</literal>, and accepts the following key:</para>
+
+                        <variablelist class='network-directives'>
+                                <varlistentry>
+                                        <term><varname>Id=</varname></term>
+                                        <listitem>
+                                                <para>The VXLAN ID to use.</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>Group=</varname></term>
+                                        <listitem>
+                                                <para>An assigned multicast group IP address.</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>TOS=</varname></term>
+                                        <listitem>
+                                                <para>The Type Of Service byte value for a vxlan interface.</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>TTL=</varname></term>
+                                        <listitem>
+                                                <para>A fixed Time To Live N on Virtual eXtensible Local Area Network packets.
+                                                N is a number in the range 1-255. 0 is a special value meaning that packets
+                                                inherit the TTL value.</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>MacLearning=</varname></term>
+                                        <listitem>
+                                                <para>A boolean. When true, enables dynamic MAC learning
+                                                to discover remote MAC addresses.</para>
+                                        </listitem>
+                                </varlistentry>
+                        </variablelist>
+        </refsect1>
+        <refsect1>
+                <title>[Tunnel] Section Options</title>
+
+                        <para>The <literal>[Tunnel]</literal> section only applies for netdevs of kind
+                        <literal>ipip</literal>, <literal>sit</literal>, <literal>gre</literal> and
+                        <literal>vti</literal> and accepts the following keys:</para>
+
+                        <variablelist class='network-directives'>
+                                <varlistentry>
+                                        <term><varname>Local=</varname></term>
+                                        <listitem>
+                                                <para>A static local address for tunneled packets.
+                                                It must be an address on another interface of this host.</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>Remote=</varname></term>
+                                        <listitem>
+                                                <para>The remote endpoint of the tunnel.</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>TOS=</varname></term>
+                                        <listitem>
+                                                <para>The Type Of Service byte value for a tunnel interface.
+                                                For details about the TOS see the
+                                                <ulink url="http://tools.ietf.org/html/rfc1349">
+                                                Type of Service in the Internet Protocol Suite
+                                                </ulink> document.
+                                                </para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>TTL=</varname></term>
+                                        <listitem>
+                                                <para>A fixed Time To Live N on tunneled packets.
+                                                N is a number in the range 1-255. 0 is a special value meaning that packets
+                                                inherit the TTL value. The default value for IPv4 tunnels is: inherit.
+                                                The default value for IPv6 tunnels is: 64.</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>DiscoverPathMTU=</varname></term>
+                                        <listitem>
+                                                <para>A boolean. When true, enables Path MTU Discovery on the tunnel.</para>
+                                        </listitem>
+                                </varlistentry>
+                        </variablelist>
+        </refsect1>
+        <refsect1>
+                <title>[Peer] Section Options</title>
+
+                        <para>The <literal>[Peer]</literal> section only applies for netdevs of kind <literal>veth</literal>
+                        and accepts the following key:</para>
+
+                        <variablelist class='network-directives'>
+                                <varlistentry>
+                                        <term><varname>Name=</varname></term>
+                                        <listitem>
+                                                <para>The interface name used when creating the netdev.
+                                                This option is compulsory.</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>MACAddress=</varname></term>
+                                        <listitem>
+                                                <para>The peer MACAddress, if not set it is generated in the same
+                                                way as the MAC address of the main interface.</para>
+                                        </listitem>
+                                </varlistentry>
+                        </variablelist>
+        </refsect1>
+        <refsect1>
+                <title>[Tun] Section Options</title>
+
+                        <para>The <literal>[Tun]</literal> section only applies for netdevs of kind
+                        <literal>tun</literal>, and accepts the following keys:</para>
+
+                        <variablelist class='network-directives'>
+                                <varlistentry>
+                                        <term><varname>OneQueue=</varname></term>
+                                        <listitem><para>Takes a boolean argument. Configures whether
+                                        all packets are queued at the device (enabled), or a fixed number
+                                        of packets are queued at the device and the rest at the
+                                        <literal>qdisc</literal>. Defaults to <literal>no</literal>.</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>MultiQueue=</varname></term>
+                                        <listitem><para>Takes a boolean argument. Configures whether to
+                                        use multiple file descriptors (queues) to parallelize packets
+                                        sending and receiving. Defaults to <literal>no</literal>.</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>PacketInfo=</varname></term>
+                                        <listitem><para>Takes a boolean argument. Configures whether packets
+                                        should be prepened with four extra bytes (two flag bytes and two
+                                        protocol bytes). If disabled it indicates that the packets will be
+                                        pure IP packets. Defaults to <literal>no</literal>.</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>User=</varname></term>
+                                        <listitem><para>User to grant access to the <filename>/dev/net/tun</filename>
+                                        device.</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>Group=</varname></term>
+                                        <listitem><para>Group to grant access to the <filename>/dev/net/tun</filename>
+                                        device.</para>
+                                        </listitem>
+                                </varlistentry>
+
+                        </variablelist>
+
+        </refsect1>
+
+        <refsect1>
+                <title>[Tap] Section Options</title>
+
+                        <para>The <literal>[Tap]</literal> section only applies for netdevs of kind
+                        <literal>tap</literal>, and accepts the same keys as the
+                        <literal>[Tun]</literal> section.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>[Bond] Section Options</title>
+
+                        <para>The <literal>[Bond]</literal> section accepts the following
+                        key:</para>
+
+                        <variablelist class='network-directives'>
+                                <varlistentry>
+                                        <term><varname>Mode=</varname></term>
+                                        <listitem>
+                                          <para>Specifies one of the bonding policies. The default is
+                                          <literal>balance-rr</literal> (round robin). Possible values are
+                                                <literal>balance-rr</literal>,
+                                                <literal>active-backup</literal>,
+                                                <literal>balance-xor</literal>,
+                                                <literal>broadcast</literal>,
+                                                <literal>802.3ad</literal>,
+                                                <literal>balance-tlb</literal>, and
+                                                <literal>balance-alb</literal>.
+                                          </para>
+                                        </listitem>
+                                </varlistentry>
+
+                                <varlistentry>
+                                  <term><varname>TransmitHashPolicy=</varname></term>
+                                  <listitem>
+                                    <para>Selects the transmit hash policy to use for slave selection in
+                                    balance-xor, 802.3ad, and tlb modes. Possible values are
+                                    <literal>layer2</literal>,
+                                    <literal>layer3+4</literal>,
+                                    <literal>layer2+3</literal>,
+                                    <literal>encap2+3</literal>,
+                                    <literal>802.3ad</literal>, and
+                                    <literal>encap3+4</literal>.
+                                    </para>
+                                  </listitem>
+                                </varlistentry>
+
+                                <varlistentry>
+                                  <term><varname>LACPTransmitRate=</varname></term>
+                                  <listitem>
+                                    <para>Specifies the rate with which link partner
+                                    transmits Link Aggregation Control Protocol Data Unit packets
+                                    in 802.3ad mode. Possible values are
+                                    <literal>slow</literal>, which requests partner to transmit LACPDUs every 30 seconds, and
+                                    <literal>fast</literal>, which requests partner to transmit LACPDUs every second.
+                                    The default value is <literal>slow</literal>.</para>
+                                  </listitem>
+                                </varlistentry>
+
+                                <varlistentry>
+                                  <term><varname>MIIMonitorSec=</varname></term>
+                                  <listitem>
+                                    <para>Specifies the frequency that Media Independent Interface link
+                                    monitoring will occur. A value of zero disables MII link monitoring.
+                                    This values is rounded down to the nearest millisecond. The default
+                                    value is 0.</para>
+                                  </listitem>
+                                </varlistentry>
+
+                                <varlistentry>
+                                  <term><varname>UpDelaySec=</varname></term>
+                                  <listitem>
+                                    <para>Specifies the delay before a link is enabled after a link up
+                                    status has been detected. This value is rounded down to a multiple of
+                                    MIIMonitorSec. The default value is 0.</para>
+                                  </listitem>
+                                </varlistentry>
+
+                                <varlistentry>
+                                  <term><varname>DownDelaySec=</varname></term>
+                                  <listitem>
+                                    <para>Specifies the delay before a link is disabled after a link down
+                                    status has been detected. This value is rounded down to a multiple of
+                                    MIIMonitorSec. The default value is 0.</para>
+                                  </listitem>
+                                </varlistentry>
+
+                        </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>Example</title>
+                <example>
+                        <title>/etc/systemd/network/bridge.netdev</title>
+
+                        <programlisting>[NetDev]
+Name=bridge0
+Kind=bridge</programlisting>
+                </example>
+
+                <example>
+                        <title>/etc/systemd/network/vlan1.netdev</title>
+
+                        <programlisting>[Match]
+Virtualization=no
+
+[NetDev]
+Name=vlan1
+Kind=vlan
+
+[VLAN]
+Id=1</programlisting>
+                </example>
+                <example>
+                        <title>/etc/systemd/network/ipip.netdev</title>
+                        <programlisting>[NetDev]
+Name=ipip-tun
+Kind=ipip
+MTUBytes=1480
+
+[Tunnel]
+Local=192.168.223.238
+Remote=192.169.224.239
+TTL=64</programlisting>
+                </example>
+                <example>
+                  <title>/etc/systemd/network/tap.netdev</title>
+                  <programlisting>[NetDev]
+Name=tap-test
+Kind=tap
+
+[Tap]
+MultiQueue=true
+PacketInfo=true</programlisting> </example>
+
+                <example>
+                        <title>/etc/systemd/network/sit.netdev</title>
+                        <programlisting>[NetDev]
+Name=sit-tun
+Kind=sit
+MTUBytes=1480
+
+[Tunnel]
+Local=10.65.223.238
+Remote=10.65.223.239</programlisting>
+                </example>
+
+                <example>
+                        <title>/etc/systemd/network/gre.netdev</title>
+                        <programlisting>[NetDev]
+Name=gre-tun
+Kind=gre
+MTUBytes=1480
+
+[Tunnel]
+Local=10.65.223.238
+Remote=10.65.223.239</programlisting>
+                </example>
+
+                <example>
+                        <title>/etc/systemd/network/vti.netdev</title>
+
+                        <programlisting>[NetDev]
+Name=vti-tun
+Kind=vti
+MTUBytes=1480
+
+[Tunnel]
+Local=10.65.223.238
+Remote=10.65.223.239</programlisting>
+                </example>
+
+                <example>
+                        <title>/etc/systemd/network/veth.netdev</title>
+                        <programlisting>[NetDev]
+Name=veth-test
+Kind=veth
+
+[Peer]
+Name=veth-peer</programlisting>
+                </example>
+
+                <example>
+                        <title>/etc/systemd/network/dummy.netdev</title>
+                        <programlisting>[NetDev]
+Name=dummy-test
+Kind=dummy
+MACAddress=12:34:56:78:9a:bc</programlisting>
+                </example>
+
+        </refsect1>
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-networkd</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
diff --git a/man/systemd.network.xml b/man/systemd.network.xml
new file mode 100644 (file)
index 0000000..641e02a
--- /dev/null
@@ -0,0 +1,595 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2013 Tom Gundersen
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd.network" conditional='ENABLE_NETWORKD'>
+
+        <refentryinfo>
+                <title>systemd.network</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Tom</firstname>
+                                <surname>Gundersen</surname>
+                                <email>teg@jklm.no</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>systemd.network</refentrytitle>
+                <manvolnum>5</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>systemd.network</refname>
+                <refpurpose>Network configuration</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename><replaceable>network</replaceable>.network</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+               <para>Network setup is performed by
+               <citerefentry><refentrytitle>systemd-networkd</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
+               </para>
+
+                <para>Network files must have the extension <filename>.network</filename>;
+                other extensions are ignored. Networks are applied to links whenever the links
+                appear.</para>
+
+                <para>The <filename>.network</filename> files are read from the files located in the
+                system network directory <filename>/usr/lib/systemd/network</filename>,
+                the volatile runtime network directory
+                <filename>/run/systemd/network</filename> and the local administration
+                network directory <filename>/etc/systemd/network</filename>.
+                All configuration files are collectively sorted and processed in lexical order,
+                regardless of the directories in which they live. However, files with
+                identical filenames replace each other. Files in
+                <filename>/etc</filename> have the highest priority, files in
+                <filename>/run</filename> take precedence over files with the same
+                name in <filename>/usr/lib</filename>. This can be used to override a
+                system-supplied configuration file with a local file if needed; a symlink in
+                <filename>/etc</filename> with the same name as a configuration file in
+                <filename>/usr/lib</filename>, pointing to <filename>/dev/null</filename>,
+                disables the configuration file entirely.</para>
+
+        </refsect1>
+
+        <refsect1>
+                <title>[Match] Section Options</title>
+
+                        <para>The network file contains a <literal>[Match]</literal> section,
+                        which determines if a given network file may be applied to a given device;
+                        and a <literal>[Network]</literal> section specifying how the device should
+                        be configured. The first (in lexical order) of the network files that
+                        matches a given device is applied.</para>
+
+                        <para>A network file is said to match a device if each of the entries in the
+                        <literal>[Match]</literal> section matches, or if the section is empty.
+                        The following keys are accepted:</para>
+
+                        <variablelist class='network-directives'>
+                                <varlistentry>
+                                        <term><varname>MACAddress=</varname></term>
+                                        <listitem>
+                                                <para>The hardware address.</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>Path=</varname></term>
+                                        <listitem>
+                                                <para>The persistent path, as exposed by the udev
+                                                property <literal>ID_PATH</literal>. May contain shell
+                                                style globs.</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>Driver=</varname></term>
+                                        <listitem>
+                                                <para>The driver currently bound to the device, as
+                                                exposed by the udev property <literal>DRIVER</literal>
+                                                of its parent device, or if that is not set the driver
+                                                as exposed by <literal>ethtool -i</literal> of the
+                                                device itself.</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>Type=</varname></term>
+                                        <listitem>
+                                                <para>The device type, as exposed by the udev property
+                                                <literal>DEVTYPE</literal>.</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>Name=</varname></term>
+                                        <listitem>
+                                                <para>The device name, as exposed by the udev property
+                                                <literal>INTERFACE</literal>. May contain shell style
+                                                globs.</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>Host=</varname></term>
+                                        <listitem>
+                                                <para>Matches against the hostname or machine ID of the
+                                                host. See <literal>ConditionHost=</literal> in
+                                                <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                                                for details.
+                                                </para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>Virtualization=</varname></term>
+                                        <listitem>
+                                                <para>Checks whether the system is executed in a virtualized
+                                                environment and optionally test whether it is a specific
+                                                implementation. See <literal>ConditionVirtualization=</literal> in
+                                                <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                                                for details.
+                                                </para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>KernelCommandLine=</varname></term>
+                                        <listitem>
+                                                <para>Checks whether a specific kernel command line option is
+                                                set (or if prefixed with the exclamation mark unset). See
+                                                <literal>ConditionKernelCommandLine=</literal> in
+                                                <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                                                for details.
+                                                </para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>Architecture=</varname></term>
+                                        <listitem>
+                                                <para>Checks whether the system is running on a specific
+                                                architecture. See <literal>ConditionArchitecture=</literal> in
+                                                <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                                                for details.
+                                                </para>
+                                        </listitem>
+                                </varlistentry>
+                        </variablelist>
+
+        </refsect1>
+
+        <refsect1>
+                <title>[Network] Section Options</title>
+
+                        <para>The <literal>[Network]</literal> section accepts the following keys:</para>
+
+                        <variablelist class='network-directives'>
+                                <varlistentry>
+                                        <term><varname>Description=</varname></term>
+                                        <listitem>
+                                                <para>A description of the device. This is only used for
+                                                presentation purposes.</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>DHCP=</varname></term>
+                                        <listitem>
+                                                <para>Enables DHCPv4 and/or DHCPv6 support. Accepts
+                                                <literal>both</literal>, <literal>none</literal>,
+                                                <literal>v4</literal> or <literal>v6</literal>.</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>DHCPServer=</varname></term>
+                                        <listitem>
+                                                <para>A boolean. Enables a basic DHCPv4 server on the
+                                                device. Mostly useful for handing out leases to container
+                                                instances.</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>IPv4LL=</varname></term>
+                                        <listitem>
+                                                <para>A boolean. When true, enables IPv4 link-local support.
+                                                </para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>IPv4LLRoute=</varname></term>
+                                        <listitem>
+                                                <para>A boolean. When true, sets up the route needed for
+                                                non-IPv4LL hosts to communicate with IPv4LL-only hosts. Defaults
+                                                to false.
+                                                </para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>LLMNR=</varname></term>
+                                        <listitem>
+                                                <para>A boolean or <literal>resolve</literal>. When true, enables
+                                                Link-Local Multicast Name Resolution on the link, when set to
+                                                <literal>resolve</literal> only resolution is enabled, but not
+                                                announcement. Defaults to true.</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>Address=</varname></term>
+                                        <listitem>
+                                                <para>A static IPv4 or IPv6 address and its prefix length,
+                                                separated by a <literal>/</literal> character. Specify this
+                                                key more than once to configure several addresses.
+                                                The format of the address must be as described in
+                                                <citerefentry><refentrytitle>inet_pton</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
+                                                This is a short-hand for an [Address] section only containing
+                                                an Address key (see below). This option may be specified
+                                                more than once.
+                                                </para>
+
+                                                <para>If the specified
+                                                address is 0.0.0.0
+                                                (for IPv4) or [::]
+                                                (for IPv6), a new
+                                                address range of the
+                                                requested size is
+                                                automatically
+                                                allocated from a
+                                                system-wide pool of
+                                                unused ranges. The
+                                                allocated range is
+                                                checked against all
+                                                current network
+                                                interfaces and all
+                                                known network
+                                                configuration files to
+                                                avoid address range
+                                                conflicts. The default
+                                                system-wide pool
+                                                consists of
+                                                192.168.0.0/16,
+                                                172.16.0.0/12 and
+                                                10.0.0.0/8 for IPv4,
+                                                and fc00::/7 for
+                                                IPv6. This
+                                                functionality is
+                                                useful to manage a
+                                                large number of
+                                                dynamically created
+                                                network interfaces
+                                                with the same network
+                                                configuration and
+                                                automatic address
+                                                range
+                                                assignment.</para>
+
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>Gateway=</varname></term>
+                                        <listitem>
+                                                <para>The gateway address, which must be in the format described in
+                                                <citerefentry><refentrytitle>inet_pton</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
+                                                This is a short-hand for a [Route] section only containing a Gateway
+                                                key. This option may be specified more than once.</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>DNS=</varname></term>
+                                        <listitem>
+                                                <para>A DNS server address, which must be in the format described in
+                                                <citerefentry><refentrytitle>inet_pton</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
+                                                This option may be specified more than once.</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>Domains=</varname></term>
+                                        <listitem>
+                                                <para>The domains used for DNS resolution over this link.</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>NTP=</varname></term>
+                                        <listitem>
+                                                <para>An NTP server address. This option may be specified more than once.</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>Bridge=</varname></term>
+                                        <listitem>
+                                                <para>The name of the bridge to add the link to.</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>Bond=</varname></term>
+                                        <listitem>
+                                                <para>The name of the bond to add the link to.</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>VLAN=</varname></term>
+                                        <listitem>
+                                                <para>The name of a VLAN to create on the link. This option
+                                                may be specified more than once.</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>MACVLAN=</varname></term>
+                                        <listitem>
+                                                <para>The name of a MACVLAN to create on the link. This option
+                                                may be specified more than once.</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>VXLAN=</varname></term>
+                                        <listitem>
+                                                <para>The name of a VXLAN to create on the link. This option
+                                                may be specified more than once.</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>Tunnel=</varname></term>
+                                        <listitem>
+                                                <para>The name of a Tunnel to create on the link. This option
+                                                may be specified more than once.</para>
+                                        </listitem>
+                                </varlistentry>
+                        </variablelist>
+
+        </refsect1>
+
+        <refsect1>
+                <title>[Address] Section Options</title>
+
+                        <para>An <literal>[Address]</literal> section accepts the following keys.
+                        Specify several <literal>[Address]</literal> sections to configure several
+                        addresses.</para>
+
+                        <variablelist class='network-directives'>
+                                <varlistentry>
+                                        <term><varname>Address=</varname></term>
+                                        <listitem>
+                                                <para>As in the <literal>[Network]</literal> section. This key is mandatory.</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>Peer=</varname></term>
+                                        <listitem>
+                                                <para>The peer address in a point-to-point connection. Accepts the same format as
+                                                the <literal>Address</literal> key.</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>Broadcast=</varname></term>
+                                        <listitem>
+                                                <para>The broadcast address, which must be in the format described in
+                                                <citerefentry><refentrytitle>inet_pton</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
+                                                This key only applies to IPv4 addresses. If it is not given, it is
+                                                derived from the <literal>Address</literal> key.</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>Label=</varname></term>
+                                        <listitem>
+                                                <para>An address label.</para>
+                                        </listitem>
+                                </varlistentry>
+                        </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>[Route] Section Options</title>
+                        <para>The <literal>[Route]</literal> section accepts the following keys. Specify
+                        several <literal>[Route]</literal> sections to configure several routes.</para>
+
+                        <variablelist class='network-directives'>
+                                <varlistentry>
+                                        <term><varname>Gateway=</varname></term>
+                                        <listitem>
+                                                <para>As in the <literal>[Network]</literal> section. This key is mandatory.</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>Destination=</varname></term>
+                                        <listitem>
+                                                <para>The destination prefix of the route. Possibly followed by a slash and the
+                                                prefixlength. If omitted, a full-length host route is assumed.</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>Metric=</varname></term>
+                                        <listitem>
+                                                <para>The metric of the route. An unsigned integer</para>
+                                        </listitem>
+                                </varlistentry>
+                        </variablelist>
+        </refsect1>
+
+        <refsect1>
+                <title>[DHCP] Section Options</title>
+                        <para>The <literal>[DHCP]</literal> section accepts the following keys:</para>
+
+                        <variablelist class='network-directives'>
+                                <varlistentry>
+                                        <term><varname>UseDNS=</varname></term>
+                                        <listitem>
+                                                <para>When true (the default), the DNS servers received from the DHCP server will
+                                                be used and take precedence over any statically configured ones.</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>UseMTU=</varname></term>
+                                        <listitem>
+                                                <para>When true, the interface maximum transmission unit from the DHCP server will
+                                                be used on the current link. Defaults to false.</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>SendHostname=</varname></term>
+                                        <listitem>
+                                                <para>When true (the default), the machine's hostname will be sent to the DHCP
+                                                server</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>UseHostname=</varname></term>
+                                        <listitem>
+                                                <para>When true (the default), the hostname received from the DHCP server
+                                                will be used as the transient hostname.</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>UseDomains=</varname></term>
+                                        <listitem>
+                                                <para>When true (not the default), the domain name received from the DHCP server
+                                                will be used for DNS resolution over this link.</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>UseRoutes=</varname></term>
+                                        <listitem>
+                                                <para>When true (the default), the static routes will be requested from the DHCP server
+                                                and added to the routing table with metric of 1024.</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>CriticalConnection=</varname></term>
+                                        <listitem>
+                                                <para>When true, the connection will never be torn down even if the DHCP lease
+                                                expires. This is contrary to the DHCP specification, but may be the best choice
+                                                if, say, the root filesystem relies on this connection. Defaults to false.</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>VendorClassIdentifier=</varname></term>
+                                        <listitem>
+                                                <para>The vendor class identifier used to identify vendor type and configuration.</para>
+                                        </listitem>
+                                </varlistentry>
+                                <varlistentry>
+                                        <term><varname>RequestBroadcast=</varname></term>
+                                        <listitem>
+                                                <para>Request the server to use broadcast messages before the IP address has been
+                                                configured. This is necessary for devices that cannot receive RAW packets, or that
+                                                cannot receive packets at all before an IP address has been configured. On the other
+                                                hand, this must not be enabled on networks where broadcasts are filtered out.</para>
+                                        </listitem>
+                                </varlistentry>
+                       </variablelist>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Example</title>
+                <example>
+                        <title>/etc/systemd/network/50-static.network</title>
+
+                        <programlisting>[Match]
+Name=enp2s0
+
+[Network]
+Address=192.168.0.15/24
+Gateway=192.168.0.1</programlisting>
+                </example>
+
+                <example>
+                        <title>/etc/systemd/network/80-dhcp.network</title>
+
+                        <programlisting>[Match]
+Name=en*
+
+[Network]
+DHCP=both</programlisting>
+                </example>
+
+                <example>
+                        <title>/etc/systemd/network/bridge-static.network</title>
+
+                        <programlisting>[Match]
+Name=bridge0
+
+[Network]
+Address=192.168.0.15/24
+Gateway=192.168.0.1
+DNS=192.168.0.1</programlisting>
+                </example>
+
+                <example>
+                        <title>/etc/systemd/network/bridge-slave-interface.network</title>
+
+                        <programlisting>[Match]
+Name=enp2s0
+
+[Network]
+Bridge=bridge0</programlisting>
+                </example>
+                <example>
+                        <title>/etc/systemd/network/ipip.network</title>
+
+                        <programlisting>[Match]
+Name=em1
+
+[Network]
+Tunnel=ipip-tun</programlisting>
+                </example>
+
+                <example>
+                        <title>/etc/systemd/network/sit.network</title>
+
+                        <programlisting>[Match]
+Name=em1
+
+[Network]
+Tunnel=sit-tun</programlisting>
+                </example>
+
+                <example>
+                        <title>/etc/systemd/network/gre.network</title>
+
+                        <programlisting>[Match]
+Name=em1
+
+[Network]
+Tunnel=gre-tun</programlisting>
+                </example>
+
+                <example>
+                        <title>/etc/systemd/network/vti.network</title>
+
+                        <programlisting>[Match]
+Name=em1
+
+[Network]
+Tunnel=vti-tun</programlisting>
+                </example>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-networkd</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.netdev</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
index e923b6d..e91c260 100644 (file)
@@ -105,22 +105,60 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
           <para>Turn on CPU usage accounting for this unit. Takes a
           boolean argument. Note that turning on CPU accounting for
           one unit might also implicitly turn it on for all units
-          contained in the same slice and for all its parent slices and
-          the units contained therein.</para>
+          contained in the same slice and for all its parent slices
+          and the units contained therein. The system default for this
+          setting maybe controlled with
+          <varname>DefaultCPUAccounting=</varname> in
+          <citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
         </listitem>
       </varlistentry>
 
       <varlistentry>
         <term><varname>CPUShares=<replaceable>weight</replaceable></varname></term>
+        <term><varname>StartupCPUShares=<replaceable>weight</replaceable></varname></term>
 
         <listitem>
-          <para>Assign the specified overall CPU time share weight to
-          the processes executed. Takes an integer value. This
-          controls the <literal>cpu.shares</literal> control group
+          <para>Assign the specified CPU time share weight to the
+          processes executed. Those options take an integer value and
+          control the <literal>cpu.shares</literal> control group
           attribute, which defaults to 1024. For details about this
           control group attribute, see <ulink
+          url="https://www.kernel.org/doc/Documentation/scheduler/sched-design-CFS.txt">sched-design-CFS.txt</ulink>.
+          The available CPU time is split up among all units within
+          one slice relative to their CPU time share weight.</para>
+
+          <para>While <varname>StartupCPUShares=</varname> only
+          applies to the startup phase of the system,
+          <varname>CPUShares=</varname> applies to normal runtime of
+          the system, and if the former is not set also to the startup
+          phase. Using <varname>StartupCPUShares=</varname> allows
+          priorizing specific services at boot-up differently than
+          during normal runtime.</para>
+
+          <para>Those options imply
+          <literal>CPUAccounting=true</literal>.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>CPUQuota=</varname></term>
+
+        <listitem>
+          <para>Assign the specified CPU time quota to the processes
+          executed. Takes a percentage value, suffixed with "%". The
+          percentage specifies how much CPU time the unit shall get at
+          maximum, relative to the total CPU time available on one
+          CPU. Use values &gt; 100% for alloting CPU time on more than
+          one CPU. This controls the
+          <literal>cpu.cfs_quota_us</literal> control group
+          attribute. For details about this control group attribute,
+          see <ulink
           url="https://www.kernel.org/doc/Documentation/scheduler/sched-design-CFS.txt">sched-design-CFS.txt</ulink>.</para>
 
+          <para>Example: <varname>CPUShares=20%</varname> ensures that
+          the executed processes will never get more than 20% CPU time
+          on one CPU.</para>
+
           <para>Implies <literal>CPUAccounting=true</literal>.</para>
         </listitem>
       </varlistentry>
@@ -132,8 +170,10 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
           <para>Turn on process and kernel memory accounting for this
           unit. Takes a boolean argument. Note that turning on memory
           accounting for one unit might also implicitly turn it on for
-          all units contained in the same slice and for all its parent
-          slices and the units contained therein.</para>
+          all its parent slices. The system default for this setting
+          maybe controlled with
+          <varname>DefaultMemoryAccounting=</varname> in
+          <citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
         </listitem>
       </varlistentry>
 
@@ -164,26 +204,34 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
           <para>Turn on Block IO accounting for this unit. Takes a
           boolean argument. Note that turning on block IO accounting
           for one unit might also implicitly turn it on for all units
-          contained in the same slice and all for its parent slices and
-          the units contained therein.</para>
+          contained in the same slice and all for its parent slices
+          and the units contained therein. The system default for this
+          setting maybe controlled with
+          <varname>DefaultBlockIOAccounting=</varname> in
+          <citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
         </listitem>
       </varlistentry>
 
       <varlistentry>
         <term><varname>BlockIOWeight=<replaceable>weight</replaceable></varname></term>
-
-        <listitem><para>Set the default
-        overall block IO weight for the
-        executed processes. Takes a single
-        weight value (between 10 and 1000) to
-        set the default block IO weight. This
-        controls the
-        <literal>blkio.weight</literal>
-        control group attribute, which
-        defaults to 1000. For details about
-        this control group attribute, see
-        <ulink
-            url="https://www.kernel.org/doc/Documentation/cgroups/blkio-controller.txt">blkio-controller.txt</ulink>.</para>
+        <term><varname>StartupBlockIOWeight=<replaceable>weight</replaceable></varname></term>
+
+        <listitem><para>Set the default overall block IO weight for
+        the executed processes. Takes a single weight value (between
+        10 and 1000) to set the default block IO weight. This controls
+        the <literal>blkio.weight</literal> control group attribute,
+        which defaults to 1000. For details about this control group
+        attribute, see <ulink
+        url="https://www.kernel.org/doc/Documentation/cgroups/blkio-controller.txt">blkio-controller.txt</ulink>.
+        The available IO bandwidth is split up among all units within
+        one slice relative to their block IO weight.</para>
+
+        <para>While <varname>StartupBlockIOWeight=</varname> only
+        applies to the startup phase of the system,
+        <varname>BlockIOWeight=</varname> applies to the later runtime
+        of the system, and if the former is not set also to the
+        startup phase. This allows priorizing specific services at
+        boot-up differently than during runtime.</para>
 
         <para>Implies
         <literal>BlockIOAccounting=true</literal>.</para>
@@ -267,12 +315,16 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
           followed by a device group name, as listed in
           <filename>/proc/devices</filename>. The latter is useful to
           whitelist all current and future devices belonging to a
-          specific device group at once. Examples:
-          <filename>/dev/sda5</filename> is a path to a device node,
-          referring to an ATA or SCSI block
+          specific device group at once. The device group is matched
+          according to file name globbing rules, you may hence use the
+          <literal>*</literal> and <literal>?</literal>
+          wildcards. Examples: <filename>/dev/sda5</filename> is a
+          path to a device node, referring to an ATA or SCSI block
           device. <literal>char-pts</literal> and
           <literal>char-alsa</literal> are specifiers for all pseudo
-          TTYs and all ALSA sound devices, respectively.</para>
+          TTYs and all ALSA sound devices,
+          respectively. <literal>char-cpu/*</literal> is a specifier
+          matching all CPU related device groups.</para>
         </listitem>
       </varlistentry>
 
index 5b3afb8..5c4bd65 100644 (file)
@@ -519,6 +519,20 @@ ExecStart=/bin/echo $ONE $TWO ${TWO}</programlisting>
                                 following:</para>
 
                                 <programlisting>/bin/kill -HUP $MAINPID</programlisting>
+
+                                <para>Note however that reloading a
+                                daemon by sending a signal (as with
+                                the example line above) is usually not
+                                a good choice, because this is an
+                                asynchronous operation and hence not
+                                suitable to order reloads of multiple
+                                services against each other. It is
+                                strongly recommended to set
+                                <varname>ExecReload=</varname> to a
+                                command that not only triggers a
+                                configuration reload of the daemon,
+                                but also synchronously waits for it to
+                                complete.</para>
                                 </listitem>
                         </varlistentry>
 
@@ -591,11 +605,12 @@ ExecStart=/bin/echo $ONE $TWO ${TWO}</programlisting>
                                 time span value such as "5min
                                 20s". Pass <literal>0</literal> to
                                 disable the timeout logic. Defaults to
-                                <varname>TimeoutStartSec=</varname> from
+                                <varname>DefaultTimeoutStartSec=</varname> from
                                 the manager configuration file, except
                                 when <varname>Type=oneshot</varname> is
                                 used, in which case the timeout
-                                is disabled by default.
+                                is disabled by default
+                                (see <citerefentry><refentrytitle>systemd-systemd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>).
                                 </para></listitem>
                         </varlistentry>
 
@@ -614,8 +629,9 @@ ExecStart=/bin/echo $ONE $TWO ${TWO}</programlisting>
                                 time span value such as "5min
                                 20s". Pass <literal>0</literal> to disable
                                 the timeout logic. Defaults to
-                                <varname>TimeoutStartSec=</varname> from the
-                                manager configuration file.
+                                <varname>DefaultTimeoutStopSec=</varname> from the
+                                manager configuration file
+                                (see <citerefentry><refentrytitle>systemd-systemd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>).
                                 </para></listitem>
                         </varlistentry>
 
@@ -689,51 +705,151 @@ ExecStart=/bin/echo $ONE $TWO ${TWO}</programlisting>
                                 <option>no</option>,
                                 <option>on-success</option>,
                                 <option>on-failure</option>,
+                                <option>on-abnormal</option>,
                                 <option>on-watchdog</option>,
                                 <option>on-abort</option>, or
                                 <option>always</option>. If set to
                                 <option>no</option> (the default), the
-                                service will not be restarted. If set to
-                                <option>on-success</option>, it will be
-                                restarted only when the service process
-                                exits cleanly.
-                                In this context, a clean exit means
-                                an exit code of 0, or one of the signals
+                                service will not be restarted. If set
+                                to <option>on-success</option>, it
+                                will be restarted only when the
+                                service process exits cleanly.  In
+                                this context, a clean exit means an
+                                exit code of 0, or one of the signals
                                 <constant>SIGHUP</constant>,
                                 <constant>SIGINT</constant>,
-                                <constant>SIGTERM</constant>,
-                                or <constant>SIGPIPE</constant>, and
-                                additionally, exit statuses and signals
-                                specified in <varname>SuccessExitStatus=</varname>.
+                                <constant>SIGTERM</constant> or
+                                <constant>SIGPIPE</constant>, and
+                                additionally, exit statuses and
+                                signals specified in
+                                <varname>SuccessExitStatus=</varname>.
                                 If set to <option>on-failure</option>,
                                 the service will be restarted when the
-                                process exits with a non-zero exit code,
-                                is terminated by a signal (including on
-                                core dump), when an operation (such as
-                                service reload) times out, and when the
-                                configured watchdog timeout is triggered.
-                                If set to
-                                <option>on-abort</option>, the service
-                                will be restarted only if the service
-                                process exits due to an uncaught
-                                signal not specified as a clean exit
-                                status.
-                                If set to
-                                <option>on-watchdog</option>, the service
-                                will be restarted only if the watchdog
-                                timeout for the service expires.
-                                If set to
+                                process exits with a non-zero exit
+                                code, is terminated by a signal
+                                (including on core dump, but excluding
+                                the aforementiond four signals), when
+                                an operation (such as service reload)
+                                times out, and when the configured
+                                watchdog timeout is triggered.  If set
+                                to <option>on-abnormal</option>, the
+                                service will be restarted when the
+                                process is terminated by a signal
+                                (including on core dump, excluding the
+                                aforementioned four signals), when an
+                                operation times out, or when the
+                                watchdog timeout is triggered. If set
+                                to <option>on-abort</option>, the
+                                service will be restarted only if the
+                                service process exits due to an
+                                uncaught signal not specified as a
+                                clean exit status.  If set to
+                                <option>on-watchdog</option>, the
+                                service will be restarted only if the
+                                watchdog timeout for the service
+                                expires.  If set to
                                 <option>always</option>, the service
-                                will be restarted regardless of whether
-                                it exited cleanly or not, got
+                                will be restarted regardless of
+                                whether it exited cleanly or not, got
                                 terminated abnormally by a signal, or
                                 hit a timeout.</para>
 
-                                <para>In addition to the above settings,
-                                the service will not be restarted if the
-                                exit code or signal is specified in
+                                <table>
+                                        <title>Exit causes and the effect of the <varname>Restart=</varname> settings on them</title>
+
+                                        <tgroup cols='2'>
+                                                <colspec colname='path' />
+                                                <colspec colname='expl' />
+                                                <thead>
+                                                        <row>
+                                                                <entry>Restart settings/Exit causes</entry>
+                                                                <entry><option>no</option></entry>
+                                                                <entry><option>always</option></entry>
+                                                                <entry><option>on-success</option></entry>
+                                                                <entry><option>on-failure</option></entry>
+                                                                <entry><option>on-abnormal</option></entry>
+                                                                <entry><option>on-abort</option></entry>
+                                                                <entry><option>on-watchdog</option></entry>
+                                                        </row>
+                                                </thead>
+                                                <tbody>
+                                                        <row>
+                                                                <entry>Clean exit code or signal</entry>
+                                                                <entry/>
+                                                                <entry>X</entry>
+                                                                <entry>X</entry>
+                                                                <entry/>
+                                                                <entry/>
+                                                                <entry/>
+                                                                <entry/>
+                                                        </row>
+                                                        <row>
+                                                                <entry>Unclean exit code</entry>
+                                                                <entry/>
+                                                                <entry>X</entry>
+                                                                <entry/>
+                                                                <entry>X</entry>
+                                                                <entry/>
+                                                                <entry/>
+                                                                <entry/>
+                                                        </row>
+                                                        <row>
+                                                                <entry>Unclean signal</entry>
+                                                                <entry/>
+                                                                <entry>X</entry>
+                                                                <entry/>
+                                                                <entry>X</entry>
+                                                                <entry>X</entry>
+                                                                <entry>X</entry>
+                                                                <entry/>
+                                                        </row>
+                                                        <row>
+                                                                <entry>Timeout</entry>
+                                                                <entry/>
+                                                                <entry>X</entry>
+                                                                <entry/>
+                                                                <entry>X</entry>
+                                                                <entry>X</entry>
+                                                                <entry/>
+                                                                <entry/>
+                                                        </row>
+                                                        <row>
+                                                                <entry>Watchdog</entry>
+                                                                <entry/>
+                                                                <entry>X</entry>
+                                                                <entry/>
+                                                                <entry>X</entry>
+                                                                <entry>X</entry>
+                                                                <entry/>
+                                                                <entry>X</entry>
+                                                        </row>
+                                                </tbody>
+                                        </tgroup>
+                                </table>
+
+                                <para>As exceptions to the setting
+                                above the service will not be
+                                restarted if the exit code or signal
+                                is specified in
                                 <varname>RestartPreventExitStatus=</varname>
-                                (see below).</para></listitem>
+                                (see below). Also, the services will
+                                always be restarted if the exit code
+                                or signal is specified in
+                                <varname>RestartForceExitStatus=</varname>
+                                (see below).</para>
+
+                                <para>Setting this to
+                                <option>on-failure</option> is the
+                                recommended choice for long-running
+                                services, in order to increase
+                                reliability by attempting automatic
+                                recovery from errors. For services
+                                that shall be able to terminate on
+                                their own choice (and avoid
+                                immediate restarting),
+                                <option>on-abnormal</option> is an
+                                alternative choice.</para>
+                                </listitem>
                         </varlistentry>
 
                         <varlistentry>
@@ -748,7 +864,7 @@ ExecStart=/bin/echo $ONE $TWO ${TWO}</programlisting>
                                 definitions can either be numeric exit
                                 codes or termination signal names,
                                 separated by spaces. For example:
-                                <programlisting>SuccessExitStatus=1 2 8 <constant>SIGKILL</constant></programlisting>
+                                <programlisting>SuccessExitStatus=1 2 8 SIGKILL</programlisting>
                                 ensures that exit codes 1, 2, 8 and
                                 the termination signal
                                 <constant>SIGKILL</constant> are
@@ -788,9 +904,8 @@ ExecStart=/bin/echo $ONE $TWO ${TWO}</programlisting>
                                 spaces. Defaults to the empty list, so
                                 that, by default, no exit status is
                                 excluded from the configured restart
-                                logic. Example:
-                                <literal>RestartPreventExitStatus=1 6
-                                SIGABRT</literal>, ensures that exit
+                                logic. For example:
+                                <programlisting>RestartPreventExitStatus=1 6 SIGABRT</programlisting> ensures that exit
                                 codes 1 and 6 and the termination
                                 signal <constant>SIGABRT</constant> will
                                 not result in automatic service
@@ -805,6 +920,18 @@ ExecStart=/bin/echo $ONE $TWO ${TWO}</programlisting>
                         </varlistentry>
 
                         <varlistentry>
+                                <term><varname>RestartForceExitStatus=</varname></term>
+                                <listitem><para>Takes a list of exit
+                                status definitions that when returned
+                                by the main service process will force
+                                automatic service restarts, regardless
+                                of the restart setting configured with
+                                <varname>Restart=</varname>. The
+                                argument format is similar to
+                                <varname>RestartPreventExitStatus=</varname>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
                                 <term><varname>PermissionsStartOnly=</varname></term>
                                 <listitem><para>Takes a boolean
                                 argument. If true, the permission-related
@@ -1017,6 +1144,30 @@ ExecStart=/bin/echo $ONE $TWO ${TWO}</programlisting>
                                 <option>none</option>.</para></listitem>
                         </varlistentry>
 
+                        <varlistentry>
+                                <term><varname>RebootArgument=</varname></term>
+                                <listitem><para>Configure the optional
+                                argument for the
+                                <citerefentry><refentrytitle>reboot</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+                                system call if
+                                <varname>StartLimitAction=</varname>
+                                is a reboot action. This works just
+                                like the optional argument to
+                                <command>systemctl reboot</command>
+                                command.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>FailureAction=</varname></term>
+                                <listitem><para>Configure the action
+                                to take when the service enters a failed
+                                state. Takes the same values as
+                                <varname>StartLimitAction=</varname>
+                                and executes the same actions.
+                                Defaults to <option>none</option>.
+                                </para></listitem>
+                        </varlistentry>
+
                 </variablelist>
 
                 <para>Check
index 4d27ddf..f82e6c3 100644 (file)
@@ -56,13 +56,13 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
 
     <para>A unit configuration file whose name ends in
     <literal>.slice</literal> encodes information about a slice which
-    is a concept for hierarchially managing resources of a group of
+    is a concept for hierarchically managing resources of a group of
     processes. This management is performed by creating a node in the
     Linux Control Group (cgroup) tree. Units that manage processes
-    (primarilly scope and service units) may be assigned to a specific
-    slice. For each slice, certain resource limits may the be set that
+    (primarily scope and service units) may be assigned to a specific
+    slice. For each slice, certain resource limits may be set that
     apply to all processes of all units contained in that
-    slice. Slices are organized hierarchially in a tree. The name of
+    slice. Slices are organized hierarchically in a tree. The name of
     the slice encodes the location in the tree. The name consists of a
     dash-separated series of names, which describes the path to the
     slice from the root slice. The root slice is named,
index d645de4..238029a 100644 (file)
                                 replaced with a
                                 <constant>NUL</constant> character
                                 before binding. For details, see
-                                <citerefentry><refentrytitle>unix</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
+                                <citerefentry project='man-pages'><refentrytitle>unix</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
 
                                 <para>If the address string is a
                                 single number, it is read as port
                         </varlistentry>
 
                         <varlistentry>
-                                <term><varname>DirectoryMode=</varname></term>
-                                <listitem><para>If listening on a file
-                                system socket or FIFO, the parent
-                                directories are automatically created
-                                if needed. This option specifies the
-                                file system access mode used when
-                                creating these directories. Takes an
-                                access mode in octal
-                                notation. Defaults to
-                                0755.</para></listitem>
+                                <term><varname>SocketUser=</varname></term>
+                                <term><varname>SocketGroup=</varname></term>
+
+                                <listitem><para>Takes a UNIX
+                                user/group name. When specified,
+                                all AF_UNIX sockets and FIFO nodes in
+                                the file system are owned by the
+                                specified user and group. If unset
+                                (the default), the nodes are owned by
+                                the root user/group (if run in system
+                                context) or the invoking user/group
+                                (if run in user context). If only a
+                                user is specified but no group, then
+                                the group is derived from the user's
+                                default group.</para></listitem>
                         </varlistentry>
 
                         <varlistentry>
                         </varlistentry>
 
                         <varlistentry>
+                                <term><varname>DirectoryMode=</varname></term>
+                                <listitem><para>If listening on a file
+                                system socket or FIFO, the parent
+                                directories are automatically created
+                                if needed. This option specifies the
+                                file system access mode used when
+                                creating these directories. Takes an
+                                access mode in octal
+                                notation. Defaults to
+                                0755.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
                                 <term><varname>Accept=</varname></term>
                                 <listitem><para>Takes a boolean
                                 argument. If true, a service instance
                         </varlistentry>
 
                         <varlistentry>
+                                <term><varname>KeepAliveTimeSec=</varname></term>
+                                <listitem><para>Takes time (in seconds) as argument . The connection needs to remain
+                                idle before TCP starts sending keepalive probes. This controls the TCP_KEEPIDLE
+                                socket option (see
+                                <citerefentry><refentrytitle>socket</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                                and the <ulink
+                                url="http://www.tldp.org/HOWTO/html_single/TCP-Keepalive-HOWTO/">TCP
+                                Keepalive HOWTO</ulink> for details.)
+                                Defaults value is 7200 seconds (2 hours).</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>KeepAliveIntervalSec=</varname></term>
+                                <listitem><para>Takes time (in seconds) as argument between individual keepalive probes,
+                                if the socket option SO_KEEPALIVE has  been set on this socket seconds as argument.
+                                This controls the TCP_KEEPINTVL socket option (see
+                                <citerefentry><refentrytitle>socket</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                                and the <ulink
+                                url="http://www.tldp.org/HOWTO/html_single/TCP-Keepalive-HOWTO/">TCP
+                                Keepalive HOWTO</ulink> for details.)
+                                Defaults value is 75 seconds.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>KeepAliveProbes=</varname></term>
+                                <listitem><para>Takes interger as argument. It's the number of unacknowledged probes to
+                                send before considering the connection dead and notifying the application layer.
+                                This controls the TCP_KEEPCNT socket option (see
+                                <citerefentry><refentrytitle>socket</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                                and the <ulink
+                                url="http://www.tldp.org/HOWTO/html_single/TCP-Keepalive-HOWTO/">TCP
+                                Keepalive HOWTO</ulink> for details.)
+                                Defaults value is 9.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>NoDelay=</varname></term>
+                                <listitem><para>Takes a boolean
+                                argument. TCP Nagle's algorithm works by combining a number of
+                                small outgoing messages, and sending them all at once.
+                                This controls the TCP_NODELAY socket option (see
+                                <citerefentry><refentrytitle>tcp</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                                Defaults to
+                                <option>false</option>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
                                 <term><varname>Priority=</varname></term>
                                 <listitem><para>Takes an integer
                                 argument controlling the priority for
                         </varlistentry>
 
                         <varlistentry>
+                                <term><varname>DeferAcceptSec=</varname></term>
+
+                                <listitem><para>Takes time (in
+                                seconds) as argument. If set, the
+                                listening process will be awakened
+                                only when data arrives on the socket,
+                                and not immediately when connection is
+                                established. When this option is set,
+                                the
+                                <constant>TCP_DEFER_ACCEPT</constant>
+                                socket option will be used (see
+                                <citerefentry><refentrytitle>tcp</refentrytitle><manvolnum>7</manvolnum></citerefentry>),
+                                and the kernel will ignore initial ACK
+                                packets without any data. The argument
+                                specifies the approximate amount of
+                                time the kernel should wait for
+                                incoming data before falling back to
+                                the normal behaviour of honouring
+                                empty ACK packets. This option is
+                                beneficial for protocols where the
+                                client sends the data first (e.g.
+                                HTTP, in contrast to SMTP), because
+                                the server process will not be woken
+                                up unnecessarily before it can take
+                                any action.
+                                </para>
+
+                                <para>If the client also uses the
+                                <constant>TCP_DEFER_ACCEPT</constant>
+                                option, the latency of the initial
+                                connection may be reduced, because the
+                                kernel will send data in the final
+                                packet establishing the connection
+                                (the third packet in the "three-way
+                                handshake").</para>
+
+                                <para>Disabled by default.</para>
+                                </listitem>
+                        </varlistentry>
+
+                        <varlistentry>
                                 <term><varname>ReceiveBuffer=</varname></term>
                                 <term><varname>SendBuffer=</varname></term>
                                 <listitem><para>Takes an integer
 
                         <varlistentry>
                                 <term><varname>PipeSize=</varname></term>
-                                <listitem><para>Takes an size in
+                                <listitem><para>Takes a size in
                                 bytes. Controls the pipe buffer size
                                 of FIFOs configured in this socket
                                 unit. See
                                 finish. If a command does not exit
                                 within the configured time, the socket
                                 will be considered failed and be shut
-                                down again. All commands still running,
+                                down again. All commands still running
                                 will be terminated forcibly via
                                 <constant>SIGTERM</constant>, and after another delay of
                                 this time with <constant>SIGKILL</constant>. (See
                                 <option>KillMode=</option> in <citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>.)
                                 Takes a unit-less value in seconds, or
                                 a time span value such as "5min
-                                20s". Pass 0 to disable the timeout
-                                logic. Defaults to <varname>TimeoutStartSec=</varname> from the
-                                manager configuration file.</para></listitem>
+                                20s". Pass <literal>0</literal> to disable the timeout
+                                logic. Defaults to <varname>DefaultTimeoutStartSec=</varname> from the
+                                manager configuration file
+                                (see <citerefentry><refentrytitle>systemd-systemd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>).
+                                </para></listitem>
                         </varlistentry>
 
                         <varlistentry>
                                 option.</para></listitem>
                         </varlistentry>
 
+                        <varlistentry>
+                                <term><varname>RemoveOnStop=</varname></term>
+                                <listitem><para>Takes a boolean
+                                argument. If enabled, any file nodes
+                                created by this socket unit are
+                                removed when it is stopped. This
+                                applies to AF_UNIX sockets in the file
+                                system, POSIX message queues, FIFOs,
+                                as well as any symlinks to
+                                them configured with
+                                <varname>Symlinks=</varname>. Normally,
+                                it should not be necessary to use this
+                                option, and is not recommended as
+                                services might continue to run after
+                                the socket unit has been terminated
+                                and it should still be possible to
+                                communicate with them via their file
+                                system node. Defaults to
+                                off.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>Symlinks=</varname></term>
+                                <listitem><para>Takes a list of file
+                                system paths. The specified paths will
+                                be created as symlinks to the AF_UNIX
+                                socket path or FIFO path of this
+                                socket unit.  If this setting is used,
+                                only one AF_UNIX socket in the file
+                                system or one FIFO may be configured
+                                for the socket unit. Use this option
+                                to manage one or more symlinked alias
+                                names for a socket, binding their
+                                lifecycle together. Defaults to the
+                                empty list.</para></listitem>
+                        </varlistentry>
+
                 </variablelist>
 
                 <para>Check
index 8ccccc2..863d7f3 100644 (file)
@@ -52,6 +52,7 @@
                 <filename>bluetooth.target</filename>,
                 <filename>ctrl-alt-del.target</filename>,
                 <filename>cryptsetup.target</filename>,
+                <filename>cryptsetup-pre.target</filename>,
                 <filename>dbus.service</filename>,
                 <filename>dbus.socket</filename>,
                 <filename>default.target</filename>,
@@ -72,6 +73,7 @@
                 <filename>multi-user.target</filename>,
                 <filename>network.target</filename>,
                 <filename>network-online.target</filename>,
+                <filename>network-pre.target</filename>,
                 <filename>nss-lookup.target</filename>,
                 <filename>nss-user-lookup.target</filename>,
                 <filename>paths.target</filename>,
                                         <filename>sysroot-usr.mount</filename>
                                         and all mount points found in
                                         <filename>/etc/fstab</filename>
-                                        that have the
-                                        <option>auto</option> and
+                                        that have
                                         <option>x-initrd.mount</option>
-                                        mount options set.
-                                        </para>
+                                        and not have <option>noauto</option>
+                                        mount options set.</para>
                                 </listitem>
                         </varlistentry>
                         <varlistentry>
 
                 <variablelist>
                         <varlistentry>
+                                <term><filename>cryptsetup-pre.target</filename></term>
+                                <listitem>
+                                        <para>This passive target unit
+                                        may be pulled in by services
+                                        that want to run before any
+                                        encrypted block device is set
+                                        up. All encrypted block
+                                        devices are set up after this
+                                        target has been reached. Since
+                                        the shutdown order is
+                                        implicitly the reverse
+                                        start-up order between units,
+                                        this target is particularly
+                                        useful to ensure that a
+                                        service is shut down only
+                                        after all encrypted block
+                                        devices are fully
+                                        stopped.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
                                 <term><filename>local-fs-pre.target</filename></term>
                                 <listitem>
                                         <para>This target unit is
                                         will be stopped before the
                                         network -- to whatever level
                                         it might be set up then -- is
-                                        shut down. Also see <ulink
+                                        shut down. It is hence useful
+                                        when writing service files
+                                        that require network access on
+                                        shutdown, which should order
+                                        themselves after this target,
+                                        but not pull it in. Also see
+                                        <ulink
                                         url="http://www.freedesktop.org/wiki/Software/systemd/NetworkTarget">Running
                                         Services After the Network is
                                         up</ulink> for more
                                         an LSB header referring to the
                                         <literal>$network</literal>
                                         facility.</para>
-
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term><filename>network-pre.target</filename></term>
+                                <listitem>
+                                        <para>This passive target unit
+                                        may be pulled in by services
+                                        that want to run before any
+                                        network is set up, for example
+                                        for the purpose of setting up a
+                                        firewall. All network
+                                        management software orders
+                                        itself after this target, but
+                                        does not pull it in.</para>
                                 </listitem>
                         </varlistentry>
                         <varlistentry>
                                         user/group name lookups for
                                         which
                                         <filename>nss-user-lookup.target</filename>
-                                        should be used. systemd
+                                        should be used. All services
+                                        for which the availability of
+                                        full host/network name
+                                        resolution is essential should
+                                        be ordered after this target,
+                                        but not pull it in. systemd
                                         automatically adds
                                         dependencies of type
                                         <varname>After=</varname> for
                                         host/network name lookups for
                                         which
                                         <filename>nss-lookup.target</filename>
-                                        should be used. </para>
+                                        should be used. All services
+                                        for which the availability of
+                                        the full user/group database is
+                                        essential should be ordered
+                                        after this target, but not
+                                        pull it in. Note that system
+                                        users are always resolvable,
+                                        and hence do not require any
+                                        special ordering against this
+                                        target.</para>
                                 </listitem>
                         </varlistentry>
                         <varlistentry>
                                         should use
                                         <filename>network-online.target</filename>
                                         (see above).</para>
-
-                                        <para>Again, this target unit
-                                        is <emphasis>not</emphasis>
-                                        suitable for pulling in other
-                                        units, it is only useful for
-                                        ordering.</para>
                                 </listitem>
                         </varlistentry>
                         <varlistentry>
                                 <term><filename>rpcbind.target</filename></term>
                                 <listitem>
-                                        <para>systemd automatically
-                                        adds dependencies of type
+                                        <para>The portmapper/rpcbind
+                                        pulls in this target and
+                                        orders itself before it, to
+                                        indicate its
+                                        availability. systemd
+                                        automatically adds
+                                        dependencies of type
                                         <varname>After=</varname> for
                                         this target unit to all SysV
                                         init script service units with
                         <varlistentry>
                                 <term><filename>time-sync.target</filename></term>
                                 <listitem>
-                                        <para>systemd automatically
-                                        adds dependencies of type
+                                        <para>Services responsible for
+                                        synchronizing the system clock
+                                        from a remote source (such as
+                                        NTP client implementations)
+                                        should pull in this target and
+                                        order themselves before
+                                        it. All services where correct
+                                        time is essential should be
+                                        ordered after this unit, but
+                                        not pull it in. systemd
+                                        automatically adds
+                                        dependencies of type
                                         <varname>After=</varname> for
                                         this target unit to all SysV
                                         init script service units with
                                         an LSB header referring to the
                                         <literal>$time</literal>
-                                        facility.</para>
+                                        facility. </para>
                                 </listitem>
                         </varlistentry>
                 </variablelist>
                         <varlistentry>
                                 <term><filename>machine.slice</filename></term>
                                 <listitem>
-                                        <para>By defalt, all virtual
+                                        <para>By default, all virtual
                                         machines and containers
                                         registered with
                                         <command>systemd-machined</command>
                           <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
                           <citerefentry><refentrytitle>systemd.target</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
                           <citerefentry><refentrytitle>systemd.slice</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
-                          <citerefentry><refentrytitle>bootup</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+                          <citerefentry project='man-pages'><refentrytitle>bootup</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
                           <citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>
                   </para>
         </refsect1>
index 492309e..61901d2 100644 (file)
                                 <citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>.)
                                 Takes a unit-less value in seconds, or
                                 a time span value such as "5min
-                                20s". Pass 0 to disable the timeout
-                                logic. Defaults to <varname>TimeoutStartSec=</varname> from the
-                                manager configuration file.</para></listitem>
+                                20s". Pass <literal>0</literal> to disable the timeout
+                                logic. Defaults to <varname>DefaultTimeoutStartSec=</varname> from the
+                                manager configuration file
+                                (see <citerefentry><refentrytitle>systemd-systemd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>).
+                                </para></listitem>
                         </varlistentry>
                 </variablelist>
 
index a837f23..02431a5 100644 (file)
                 <para>When parsing, systemd will also accept relative
                 time specifications. A time span (see above) that is
                 prefixed with <literal>+</literal> is evaluated to the
-                current time plus the specified
-                time span. Correspondingly, a time span that is prefixed
+                current time plus the specified time
+                span. Correspondingly, a time span that is prefixed
                 with <literal>-</literal> is evaluated to the current
                 time minus the specified time span. Instead of
-                prefixing the time span with <literal>-</literal>, it
-                may also be suffixed with a space and the word
+                prefixing the time span with <literal>+</literal> or
+                <literal>-</literal>, it may also be suffixed with a
+                space and the word <literal>left</literal> or
                 <literal>ago</literal>.</para>
 
+                <para>Finally, a timespan prefixed with
+                <literal>@</literal> is evaluated relative to the UNIX
+                time epoch 1st Jan, 1970, 00:00.</para>
+
                 <para>Examples for valid timestamps and their
                 normalized form (assuming the current time was
                 2012-11-23 18:15:22):</para>
                tomorrow → Fri 2012-11-24 00:00:00
                +3h30min → Fri 2012-11-23 21:45:22
                     -5s → Fri 2012-11-23 18:15:17
-              11min ago → Fri 2012-11-23 18:04:22</programlisting>
+              11min ago → Fri 2012-11-23 18:04:22
+            @1395716396 → Tue 2014-03-25 03:59:56</programlisting>
 
                 <para>Note that timestamps printed by systemd will not
                 be parsed correctly by systemd, as the timezone
 
                 <para>The special expressions
                 <literal>hourly</literal>, <literal>daily</literal>,
-                <literal>monthly</literal> and <literal>weekly</literal>
-                may be used as calendar events which refer to
-                <literal>*-*-* *:00:00</literal>, <literal>*-*-*
-                00:00:00</literal>, <literal>*-*-01 00:00:00</literal> and
-                <literal>Mon *-*-* 00:00:00</literal>,
-                respectively.</para>
+                <literal>monthly</literal>, <literal>weekly</literal>,
+                and <literal>yearly</literal> or
+                <literal>annually</literal> may be used as calendar
+                events which refer to
+                <literal>*-*-* *:00:00</literal>,
+                <literal>*-*-* 00:00:00</literal>,
+                <literal>*-*-01 00:00:00</literal>,
+                <literal>Mon *-*-* 00:00:00</literal>, and
+                <literal>*-01-01 00:00:00</literal> respectively.
+                </para>
 
                 <para>Examples for valid timestamps and their
                 normalized form:</para>
@@ -271,6 +281,8 @@ Wed-Sat,Tue 12-10-15 1:2:3 → Tue-Sat 2012-10-15 01:02:03
                      daily → *-*-* 00:00:00
                    monthly → *-*-01 00:00:00
                     weekly → Mon *-*-* 00:00:00
+                    yearly → *-01-01 00:00:00
+                  annually → *-01-01 00:00:00
                      *:2/3 → *-*-* *:02/3:00</programlisting>
 
                   <para>Calendar events are used by timer units, see
index 98d4f7b..9fcf5cc 100644 (file)
                 <varname>Unit=</varname> (see below).</para>
 
                 <para>Unless <varname>DefaultDependencies=</varname>
-                is set to <option>false</option>, timer units will
+                is set to <option>false</option>, all timer units will
                 implicitly have dependencies of type
                 <varname>Conflicts=</varname> and
                 <varname>Before=</varname> on
-                <filename>shutdown.target</filename>. These ensure
-                that timer units are stopped cleanly prior to system
-                shutdown. Only timer units involved with early boot or
-                late system shutdown should disable this
-                option.</para>
+                <filename>shutdown.target</filename> to ensure that
+                they are stopped cleanly prior to system shutdown.
+                Timer units with at least one
+                <varname>OnCalendar=</varname> directive will have an
+                additional <varname>After=</varname> dependency on
+                <filename>timer-sync.target</filename> to avoid
+                being started before the system clock has been
+                correctly set. Only timer units involved with early
+                boot or late system shutdown should disable the
+                <varname>DefaultDependencies=</varname> option.</para>
         </refsect1>
 
         <refsect1>
                                 are named identically, except for the
                                 suffix.</para></listitem>
                         </varlistentry>
+
+
+                        <varlistentry>
+                                <term><varname>Persistent=</varname></term>
+
+                                <listitem><para>Takes a boolean
+                                argument. If true, the time when the
+                                service unit was last triggered is
+                                stored on disk. When the timer is
+                                activated, the service unit is
+                                triggered immediately if it would have
+                                been triggered at least once during
+                                the time when the timer was inactive.
+                                This is useful to catch up on missed
+                                runs of the service when the machine
+                                was off. Note that this setting only
+                                has an effect on timers configured
+                                with <varname>OnCalendar=</varname>.
+                                </para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>WakeSystem=</varname></term>
+
+                                <listitem><para>Takes a boolean
+                                argument. If true, an elapsing timer
+                                will cause the system to resume from
+                                suspend, should it be suspended and if
+                                the system supports this. Note that
+                                this option will only make sure the
+                                system resumes on the appropriate
+                                times, it will not take care of
+                                suspending it again after any work
+                                that is to be done is
+                                finished. Defaults to
+                                <varname>false</varname>.</para></listitem>
+                        </varlistentry>
                 </variablelist>
         </refsect1>
 
index 07a73fd..c8d9300 100644 (file)
 <filename>...</filename>
                 </literallayout></para>
 
-                <para><literallayout><filename>$HOME/.config/systemd/user/*</filename>
+                <para><literallayout><filename>$XDG_CONFIG_HOME/systemd/user/*</filename>
+<filename>$HOME/.config/systemd/user/*</filename>
 <filename>/etc/systemd/user/*</filename>
 <filename>/run/systemd/user/*</filename>
+<filename>$XDG_DATA_HOME/systemd/user/*</filename>
+<filename>$HOME/.local/share/systemd/user/*</filename>
 <filename>/usr/lib/systemd/user/*</filename>
 <filename>...</filename>
                 </literallayout></para>
                 <para>Unit files may contain additional options on top
                 of those listed here. If systemd encounters an unknown
                 option, it will write a warning log message but
-                continue loading the unit. If an option is prefixed
-                with <option>X-</option>, it is ignored completely by
-                systemd. Applications may use this to include
-                additional information in the unit files.</para>
+                continue loading the unit. If an option or section name
+                is prefixed with <option>X-</option>, it is ignored
+                completely by systemd. Options within an ignored
+                section do not need the prefix. Applications may use
+                this to include additional information in the unit
+                files.</para>
 
                 <para>Boolean arguments used in unit files can be
                 written in various formats. For positive settings the
                 settings to a unit, without having to modify their
                 unit files. Make sure that the file that is included
                 has the appropriate section headers before any
-                directive.</para>
+                directive. Note that for instanced units this logic
+                will first look for the instance
+                <literal>.d/</literal> subdirectory and read its
+                <literal>.conf</literal> files, followed by the
+                template <literal>.d/</literal> subdirectory and reads
+                its <literal>.conf</literal> files.</para>
 
                 <para>Note that while systemd offers a flexible
                 dependency system between units it is recommended to
                 (<option>--user</option>) and the variable
                 <varname>$SYSTEMD_UNIT_PATH</varname> is set, this
                 contents of this variable overrides the unit load
-                path.
-                </para>
+                path. If <varname>$SYSTEMD_UNIT_PATH</varname> ends
+                with an empty component (<literal>:</literal>), the
+                usual unit load path will be appended to the contents
+                of the variable.</para>
 
                 <table>
                   <title>
                     </thead>
                     <tbody>
                       <row>
+                        <entry><filename>$XDG_CONFIG_HOME/systemd/user</filename></entry>
+                        <entry>User configuration (only used when $XDG_CONFIG_HOME is set)</entry>
+                      </row>
+                      <row>
                         <entry><filename>$HOME/.config/systemd/user</filename></entry>
-                        <entry>User configuration</entry>
+                        <entry>User configuration (only used when $XDG_CONFIG_HOME is not set)</entry>
                       </row>
                       <row>
                         <entry><filename>/etc/systemd/user</filename></entry>
                         <entry>Runtime units</entry>
                       </row>
                       <row>
+                        <entry><filename>$XDG_DATA_HOME/systemd/user</filename></entry>
+                        <entry>Units of packages that have been installed in the home directory (only used when $XDG_DATA_HOME is set)</entry>
+                      </row>
+                      <row>
+                        <entry><filename>$HOME/.local/share/systemd/user</filename></entry>
+                        <entry>Units of packages that have been installed in the home directory (only used when $XDG_DATA_HOME is not set)</entry>
+                      </row>
+                      <row>
                         <entry><filename>/usr/lib/systemd/user</filename></entry>
-                        <entry>Units of installed packages</entry>
+                        <entry>Units of packages that have been installed system-wide</entry>
                       </row>
                     </tbody>
                   </tgroup>
                                 <literal>man:</literal>. For more
                                 information about the syntax of these
                                 URIs, see
-                                <citerefentry><refentrytitle>uri</refentrytitle><manvolnum>7</manvolnum></citerefentry>. The
+                                <citerefentry project='man-pages'><refentrytitle>uri</refentrytitle><manvolnum>7</manvolnum></citerefentry>. The
                                 URIs should be listed in order of
                                 relevance, starting with the most
                                 relevant. It is a good idea to first
                         <varlistentry>
                                 <term><varname>RequiresMountsFor=</varname></term>
 
-                                <listitem><para>Takes a space-separated
-                                list of absolute paths. Automatically
-                                adds dependencies of type
-                                <varname>Requires=</varname> and
-                                <varname>After=</varname> for all
+                                <listitem><para>Takes a
+                                space-separated list of absolute
+                                paths. Automatically adds dependencies
+                                of type <varname>Requires=</varname>
+                                and <varname>After=</varname> for all
                                 mount units required to access the
-                                specified path.</para></listitem>
+                                specified path.</para>
+
+                                <para>Mount points marked with
+                                <option>noauto</option> are not
+                                mounted automatically and will be
+                                ignored for the purposes of this
+                                option. If such a mount should be a
+                                requirement for this unit,
+                                direct dependencies on the mount
+                                units may be added
+                                (<varname>Requires=</varname> and
+                                <varname>After=</varname> or
+                                some other combination).
+                                </para></listitem>
                         </varlistentry>
 
                         <varlistentry>
                                 <term><varname>ConditionSecurity=</varname></term>
                                 <term><varname>ConditionCapability=</varname></term>
                                 <term><varname>ConditionACPower=</varname></term>
+                                <term><varname>ConditionNeedsUpdate=</varname></term>
+                                <term><varname>ConditionFirstBoot=</varname></term>
                                 <term><varname>ConditionPathExists=</varname></term>
                                 <term><varname>ConditionPathExistsGlob=</varname></term>
                                 <term><varname>ConditionPathIsDirectory=</varname></term>
                                 <varname>x86</varname>,
                                 <varname>x86-64</varname>,
                                 <varname>ppc</varname>,
+                                <varname>ppc-le</varname>,
                                 <varname>ppc64</varname>,
+                                <varname>ppc64-le</varname>,
                                 <varname>ia64</varname>,
                                 <varname>parisc</varname>,
                                 <varname>parisc64</varname>,
                                 <varname>sparc</varname>,
                                 <varname>sparc64</varname>,
                                 <varname>mips</varname>,
+                                <varname>mips-le</varname>,
                                 <varname>mips64</varname>,
+                                <varname>mips64-le</varname>,
                                 <varname>alpha</varname>,
                                 <varname>arm</varname>,
                                 <varname>arm-be</varname>,
                                 <varname>arm64-be</varname>,
                                 <varname>sh</varname>,
                                 <varname>sh64</varname>,
-                                <varname>m86k</varname> to test
+                                <varname>m86k</varname>,
+                                <varname>tilegx</varname>,
+                                <varname>cris</varname> to test
                                 against a specific architecture. The
                                 architecture is determined from the
                                 information returned by
                                 virtualization solution, or one of
                                 <varname>qemu</varname>,
                                 <varname>kvm</varname>,
+                                <varname>zvm</varname>,
                                 <varname>vmware</varname>,
                                 <varname>microsoft</varname>,
                                 <varname>oracle</varname>,
                                 <varname>xen</varname>,
                                 <varname>bochs</varname>,
-                                <varname>chroot</varname>,
                                 <varname>uml</varname>,
                                 <varname>openvz</varname>,
                                 <varname>lxc</varname>,
                                 case the kernel command line is
                                 searched for the word appearing as is,
                                 or as left hand side of an
-                                assignment. In the latter case the
+                                assignment. In the latter case, the
                                 exact assignment is looked for with
                                 right and left hand side
                                 matching.</para>
                                 (i.e. this does not check whether
                                 capability is actually available in
                                 the permitted or effective sets, see
-                                <citerefentry><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                                <citerefentry project='man-pages'><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry>
                                 for details). Pass a capability name
                                 such as <literal>CAP_MKNOD</literal>,
                                 possibly prefixed with an exclamation
                                 all AC connectors are disconnected
                                 from a power source.</para>
 
+                                <para><varname>ConditionNeedsUpdate=</varname>
+                                takes one of <filename>/var</filename>
+                                or <filename>/etc</filename> as
+                                argument, possibly prefixed with a
+                                <literal>!</literal> (for inverting
+                                the condition). This condition may be
+                                used to conditionalize units on
+                                whether the specified directory
+                                requires an update because
+                                <filename>/usr</filename>'s
+                                modification time is newer than the
+                                stamp file
+                                <filename>.updated</filename> in the
+                                specified directory. This is useful to
+                                implement offline updates of the
+                                vendor operating system resources in
+                                <filename>/usr</filename> that require
+                                updating of <filename>/etc</filename>
+                                or <filename>/var</filename> on the
+                                next following boot. Units making use
+                                of this condition should order
+                                themselves before
+                                <citerefentry><refentrytitle>systemd-update-done.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                                to make sure they run before the stamp
+                                files's modification time gets reset
+                                indicating a completed update.</para>
+
+                                <para><varname>ConditionFirstBoot=</varname>
+                                takes a boolean argument. This
+                                condition may be used to
+                                conditionalize units on whether the
+                                system is booting up with an
+                                unpopulated <filename>/etc</filename>
+                                directory. This may be used to
+                                populate <filename>/etc</filename> on
+                                the first boot after factory reset, or
+                                when a new system instances boots up
+                                for the first time.</para>
+
                                 <para>With
                                 <varname>ConditionPathExists=</varname>
                                 a file existence condition is
                                 useful for implementation of generator
                                 tools that convert configuration from
                                 an external configuration file format
-                                into native unit files. Thus
+                                into native unit files. This
                                 functionality should not be used in
                                 normal units.</para></listitem>
                         </varlistentry>
                                 of unit names may be
                                 given.</para></listitem>
                         </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>DefaultInstance=</varname></term>
+
+                                <listitem><para>In template unit files,
+                                this specifies for which instance the
+                                unit shall be enabled if the template
+                                is enabled without any explicitly set
+                                instance. This option has no effect in
+                                non-template unit files. The specified
+                                string must be usable as instance
+                                identifier.</para></listitem>
+                        </varlistentry>
                 </variablelist>
 
                 <para>The following specifiers are interpreted in the
                         <citerefentry><refentrytitle>systemd.scope</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>systemd.slice</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-verify</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry project='man-pages'><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>systemd.directives</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>uname</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 </para>
index 331e6c2..0d01757 100644 (file)
                                 target. Argument must be one of
                                 <option>console</option>,
                                 <option>journal</option>,
-                                <option>syslog</option>,
                                 <option>kmsg</option>,
                                 <option>journal-or-kmsg</option>,
-                                <option>syslog-or-kmsg</option>,
                                 <option>null</option>.</para></listitem>
                         </varlistentry>
                         <varlistentry>
 
                                 <listitem><para>Set log level. As
                                 argument this accepts a numerical log
-                                level or the well-known <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                                level or the well-known <citerefentry project='man-pages'><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                                 symbolic names (lowercase):
                                 <option>emerg</option>,
                                 <option>alert</option>,
                 file system hierarchy (beneath
                 <filename>/sys/fs/cgroup/systemd/</filename>), or in tools
                 such as
-                <citerefentry><refentrytitle>ps</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                <citerefentry project='man-pages'><refentrytitle>ps</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 (<command>ps xawf -eo pid,user,cgroup,args</command>
                 is particularly useful to list all processes and the
                 systemd units they belong to.).</para>
                                 <term><constant>SIGRTMIN+26</constant></term>
                                 <term><constant>SIGRTMIN+27</constant></term>
                                 <term><constant>SIGRTMIN+28</constant></term>
-                                <term><constant>SIGRTMIN+29</constant></term>
 
                                 <listitem><para>Sets the log level to
-                                <literal>journal-or-kmsg</literal>
-                                (or <literal>console</literal> on
+                                <literal>journal-or-kmsg</literal> (or
+                                <literal>console</literal> on
                                 <constant>SIGRTMIN+27</constant>,
                                 <literal>kmsg</literal> on
-                                <constant>SIGRTMIN+28</constant>,
-                                or <literal>syslog-or-kmsg</literal>
-                                on <constant>SIGRTMIN+29</constant>), as
+                                <constant>SIGRTMIN+28</constant>), as
                                 controlled via
                                 <varname>systemd.log_target=journal-or-kmsg</varname>
-                                (or <varname>systemd.log_target=console</varname>
-                                on <constant>SIGRTMIN+27</constant>,
+                                (or
+                                <varname>systemd.log_target=console</varname>
+                                on <constant>SIGRTMIN+27</constant> or
                                 <varname>systemd.log_target=kmsg</varname>
-                                on <constant>SIGRTMIN+28</constant>,
-                                or
-                                <varname>systemd.log_target=syslog-or-kmsg</varname>
-                                on <constant>SIGRTMIN+29</constant>) on
-                                the kernel command
+                                on <constant>SIGRTMIN+28</constant>)
+                                on the kernel command
                                 line.</para></listitem>
                         </varlistentry>
                 </variablelist>
                         <citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>systemd.special</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>kernel-command-line</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>bootup</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+                        <citerefentry project='man-pages'><refentrytitle>bootup</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>systemd.directives</refentrytitle><manvolnum>7</manvolnum></citerefentry>
                 </para>
         </refsect1>
diff --git a/man/sysusers.d.xml b/man/sysusers.d.xml
new file mode 100644 (file)
index 0000000..18c71db
--- /dev/null
@@ -0,0 +1,279 @@
+<?xml version="1.0"?>
+<!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<!--
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+<refentry id="sysusers.d">
+
+        <refentryinfo>
+                <title>sysusers.d</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>sysusers.d</refentrytitle>
+                <manvolnum>5</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>sysusers.d</refname>
+                <refpurpose>Declarative allocation of system users and groups</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>/usr/lib/sysusers.d/*.conf</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para><command>systemd-sysusers</command> uses the
+                files from <filename>sysusers.d</filename> directory
+                to create system users and groups at package
+                installation or boot time. This tool may be used to
+                allocate system users and groups only, it is not
+                useful for creating non-system users and groups, as it
+                accesses <filename>/etc/passwd</filename> and
+                <filename>/etc/group</filename> directly, bypassing
+                any more complex user databases, for example any
+                database involving NIS or LDAP.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Configuration Format</title>
+
+                <para>Each configuration file shall be named in the
+                style of
+                <filename><replaceable>package</replaceable>.conf</filename>
+                or
+                <filename><replaceable>package</replaceable>-<replaceable>part</replaceable>.conf</filename>.
+                The second variant should be used when it is desirable
+                to make it easy to override just this part of
+                configuration.</para>
+
+                <para>The file format is one line per user or group
+                containing name, ID, GECOS field description and home directory:</para>
+
+                <programlisting># Type Name ID GECOS
+u httpd 440 "HTTP User"
+u authd /usr/bin/authd "Authorization user"
+g input - -
+m authd input
+u root 0 "Superuser" /root</programlisting>
+
+                <refsect2>
+                        <title>Type</title>
+
+                        <para>The type consists of a single
+                        letter. The following line types are
+                        understood:</para>
+
+                        <variablelist>
+                                <varlistentry>
+                                        <term><varname>u</varname></term>
+                                        <listitem><para>Create a
+                                        system user and group of the
+                                        specified name should they not
+                                        exist yet. The user's primary
+                                        group will be set to the group
+                                        bearing the same name. The
+                                        user's shell will be set to
+                                        <filename>/sbin/nologin</filename>,
+                                        the home directory to the
+                                        specified home directory, or
+                                        <filename>/</filename> if none
+                                        is given. The account will be
+                                        created disabled, so that
+                                        logins are not
+                                        allowed.</para></listitem>
+                                </varlistentry>
+
+                                <varlistentry>
+                                        <term><varname>g</varname></term>
+                                        <listitem><para>Create a
+                                        system group of the specified
+                                        name should it not exist
+                                        yet. Note that
+                                        <varname>u</varname>
+                                        implicitly create a matching
+                                        group. The group will be
+                                        created with no password
+                                        set.</para></listitem>
+                                </varlistentry>
+
+                                <varlistentry>
+                                        <term><varname>m</varname></term>
+                                        <listitem><para>Add a user to
+                                        a group. If the user or group
+                                        are not existing yet, they
+                                        will be implicitly
+                                        created.</para></listitem>
+                                </varlistentry>
+
+                                <varlistentry>
+                                        <term><varname>r</varname></term>
+                                        <listitem><para>Add a range of
+                                        numeric UIDs/GIDs to the pool
+                                        to allocate new UIDs and GIDs
+                                        from. If no line of this type
+                                        is specified the range of
+                                        UIDs/GIDs is set to some
+                                        compiled-in default. Note that
+                                        both UIDs and GIDs are
+                                        allocated from the same pool,
+                                        in order to ensure that users
+                                        and groups of the same name
+                                        are likely to carry the same
+                                        numeric UID and
+                                        GID.</para></listitem>
+                                </varlistentry>
+
+                        </variablelist>
+                </refsect2>
+
+                <refsect2>
+                        <title>Name</title>
+
+                        <para>The name field specifies the user or
+                        group name. It should be shorter than 31
+                        characters and avoid any non-ASCII characters,
+                        and not begin with a numeric character. It is
+                        strongly recommended to pick user and group
+                        names that are unlikely to clash with normal
+                        users created by the administrator. A good
+                        scheme to guarantee this is by prefixing all
+                        system and group names with the underscore,
+                        and avoiding too generic names.</para>
+
+                        <para>For <varname>m</varname> lines this
+                        field should contain the user name to add to a
+                        group.</para>
+
+                        <para>For lines of type <varname>r</varname>
+                        this field should be set to
+                        <literal>-</literal>.</para>
+                </refsect2>
+
+                <refsect2>
+                        <title>ID</title>
+
+                        <para>For <varname>u</varname> and
+                        <varname>g</varname> the numeric 32bit UID or
+                        GID of the user/group. Do not use IDs 65535 or
+                        4294967295, as they have special placeholder
+                        meanings. Specify <literal>-</literal> for
+                        automatic UID/GID allocation for the user or
+                        group. Alternatively, specify an absolute path
+                        in the file system. In this case the UID/GID
+                        is read from the path's owner/group. This is
+                        useful to create users whose UID/GID match the
+                        owners of pre-existing files (such as SUID or
+                        SGID binaries).</para>
+
+                        <para>For <varname>m</varname> lines this
+                        field should contain the group name to add to
+                        a user to.</para>
+
+                        <para>For lines of type <varname>r</varname>
+                        this field should be set to a UID/GID range in
+                        the format <literal>FROM-TO</literal> where
+                        both values are formatted as decimal ASCII
+                        numbers. Alternatively, a single UID/GID may
+                        be specified formatted as decimal ASCII
+                        numbers.</para>
+                </refsect2>
+
+                <refsect2>
+                        <title>GECOS</title>
+
+                        <para>A short, descriptive string for users to
+                        be created, enclosed in quotation marks. Note
+                        that this field may not contain colons.</para>
+
+                        <para>Only applies to lines of type
+                        <varname>u</varname> and should otherwise be
+                        left unset, or be set to
+                        <literal>-</literal>.</para>
+                </refsect2>
+
+                <refsect2>
+                        <title>Home Directory</title>
+
+                        <para>The home directory for a new system
+                        user. If omitted defaults to the root
+                        directory. It is recommended to not
+                        unnecessarily specify home directories for
+                        system users, unless software strictly
+                        requires one to be set.</para>
+
+                        <para>Only applies to lines of type
+                        <varname>u</varname> and should otherwise be
+                        left unset, or be set to
+                        <literal>-</literal>.</para>
+                </refsect2>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Overriding vendor configuration</title>
+
+                <para>Note that <command>systemd-sysusers</command>
+                will do nothing if the specified users or groups
+                already exist, so normally there no reason to override
+                <filename>sysusers.d</filename> vendor configuration,
+                except to block certain users or groups from being
+                created.</para>
+
+                <para>Files in <filename>/etc/sysusers.d</filename>
+                override files with the same name in
+                <filename>/usr/lib/sysusers.d</filename> and
+                <filename>/run/sysusers.d</filename>. Files in
+                <filename>/run/sysusers.d</filename> override files
+                with the same name in
+                <filename>/usr/lib/sysusers.d</filename>. The scheme is the same as for
+                <citerefentry><refentrytitle>tmpfiles.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                except for the directory name.</para>
+
+                <para>If the administrator wants to disable a
+                configuration file supplied by the vendor, the
+                recommended way is to place a symlink to
+                <filename>/dev/null</filename> in
+                <filename>/etc/sysusers.d/</filename> bearing the
+                same filename.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>See Also</title>
+                <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-sysusers</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>tmpfiles.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                </para>
+        </refsect1>
+
+</refentry>
index 1949c95..33ea118 100644 (file)
                 <para>
                         <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>wall</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                        <citerefentry project='man-pages'><refentrytitle>wall</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 </para>
         </refsect1>
 
index ee75d42..f3edb8d 100644 (file)
                 <para><command>timedatectl</command> may be used to
                 query and change the system clock and its
                 settings.</para>
+
+                <para>Use
+                <citerefentry><refentrytitle>systemd-firstboot</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                to initialize the system time zone for mounted (but not
+                booted) system images.</para>
         </refsect1>
 
         <refsect1>
                                 change the 3rd line of
                                 <filename>/etc/adjtime</filename>, as
                                 documented in
-                                <citerefentry><refentrytitle>hwclock</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para></listitem>
+                                <citerefentry project='man-pages'><refentrytitle>hwclock</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para></listitem>
                         </varlistentry>
 
                         <varlistentry>
@@ -236,11 +241,12 @@ chronyd.service - NTP client/server
                 <title>See Also</title>
                 <para>
                         <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>hwclock</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>date</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry project='man-pages'><refentrytitle>hwclock</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry project='man-pages'><refentrytitle>date</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>localtime</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>systemd-timedated.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                        <citerefentry><refentrytitle>systemd-timedated.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-firstboot</refentrytitle><manvolnum>1</manvolnum></citerefentry>
                 </para>
         </refsect1>
 
diff --git a/man/timesyncd.conf.xml b/man/timesyncd.conf.xml
new file mode 100644 (file)
index 0000000..aeb7182
--- /dev/null
@@ -0,0 +1,115 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="timesyncd.conf" conditional='ENABLE_TIMESYNCD'>
+        <refentryinfo>
+                <title>timesyncd.conf</title>
+                <productname>systemd</productname>
+
+                <authorgroup>
+                        <author>
+                                <contrib>Developer</contrib>
+                                <firstname>Lennart</firstname>
+                                <surname>Poettering</surname>
+                                <email>lennart@poettering.net</email>
+                        </author>
+                </authorgroup>
+        </refentryinfo>
+
+        <refmeta>
+                <refentrytitle>timesyncd.conf</refentrytitle>
+                <manvolnum>5</manvolnum>
+        </refmeta>
+
+        <refnamediv>
+                <refname>timesyncd.conf</refname>
+                <refpurpose>Network Time Synchronization configuration file</refpurpose>
+        </refnamediv>
+
+        <refsynopsisdiv>
+                <para><filename>/etc/systemd/timesyncd.conf</filename></para>
+        </refsynopsisdiv>
+
+        <refsect1>
+                <title>Description</title>
+
+                <para>When starting, systemd-timesyncd will read the
+                configuration file
+                <filename>timesyncd.conf</filename>.  This
+                configuration file controls NTP network time
+                synchronization.</para>
+
+        </refsect1>
+
+        <refsect1>
+                <title>Options</title>
+
+                <variablelist class='network-directives'>
+
+                        <varlistentry>
+                                <term><varname>NTP=</varname></term>
+                                <listitem><para>A space separated list
+                                of NTP servers host names or IP
+                                addresses. During runtime this list is
+                                combined with any per-interface NTP
+                                servers acquired from
+                                <citerefentry><refentrytitle>systemd-networkd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>. systemd-timesyncd
+                                will contact all configured system or
+                                per-interface servers in turn until
+                                one is found that responds. This
+                                setting defaults to the empty
+                                list.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>FallbackNTP=</varname></term>
+                                <listitem><para>A space separated list
+                                of NTP server host names or IP
+                                addresses to be used as the fallback
+                                NTP servers. Any per-interface NTP
+                                servers obtained from
+                                <citerefentry><refentrytitle>systemd-networkd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                                take precedence over this setting, as
+                                do any servers set via
+                                <varname>NTP=</varname> above. This
+                                setting is hence only used if no other
+                                NTP server information is known. If
+                                this option is not given, a
+                                compiled-in list of NTP servers is
+                                used instead.</para></listitem>
+                        </varlistentry>
+
+                </variablelist>
+        </refsect1>
+
+        <refsect1>
+                  <title>See Also</title>
+                  <para>
+                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-timesyncd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd-networkd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+                  </para>
+        </refsect1>
+
+</refentry>
index 812129f..df81d76 100644 (file)
                 temporary files and directories which usually reside
                 in directories such as <filename>/run</filename>
                 or <filename>/tmp</filename>.</para>
+
+                <para>Volatile and temporary files and directories are
+                those located in <filename>/run</filename> (and its
+                alias <filename>/var/run</filename>),
+                <filename>/tmp</filename>,
+                <filename>/var/tmp</filename>, the API file systems
+                such as <filename>/sys</filename> or
+                <filename>/proc</filename>, as well as some other
+                directories below <filename>/var</filename>.</para>
+
+                <para>System daemons frequently require private
+                runtime directories below <filename>/run</filename> to
+                place communication sockets and similar in. For these,
+                consider declaring them in their unit files using
+                <varname>RuntimeDirectory=</varname>
+                (see <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry> for details),
+                if this is feasible.</para>
         </refsect1>
 
         <refsect1>
                 of the directories they reside in. If multiple files
                 specify the same path, the entry in the file with the
                 lexicographically earliest name will be applied, all
-                all other conflicting entries logged as errors.</para>
+                all other conflicting entries will be logged as
+                errors. When two lines are prefix and suffix of each
+                other, then the prefix is always processed first, the
+                suffix later. Otherwise, the files/directories are
+                processed in the order they are listed.</para>
 
                 <para>If the administrator wants to disable a
                 configuration file supplied by the vendor, the
@@ -148,33 +169,80 @@ L    /tmp/foobar -    -    -    -   /dev/null</programlisting>
 
                                 <varlistentry>
                                         <term><varname>p</varname></term>
-                                        <listitem><para>Create a named pipe (FIFO) if it does not exist yet.</para></listitem>
+                                        <term><varname>p+</varname></term>
+                                        <listitem><para>Create a named
+                                        pipe (FIFO) if it does not
+                                        exist yet. If suffixed with
+                                        <varname>+</varname> and a
+                                        file already exists where the
+                                        pipe is to be created, it will
+                                        be removed and be replaced by
+                                        the pipe.</para></listitem>
                                 </varlistentry>
 
                                 <varlistentry>
                                         <term><varname>L</varname></term>
-                                        <listitem><para>Create a symlink if it does not exist yet.</para></listitem>
+                                        <term><varname>L+</varname></term>
+                                        <listitem><para>Create a
+                                        symlink if it does not exist
+                                        yet. If suffixed with
+                                        <varname>+</varname> and a
+                                        file already exists where the
+                                        symlink is to be created, it
+                                        will be removed and be
+                                        replaced by the
+                                        symlink. If the argument is omitted,
+                                        symlinks to files with the same name
+                                        residing in the directory
+                                        <filename>/usr/share/factory/</filename>
+                                        are created.</para></listitem>
                                 </varlistentry>
 
                                 <varlistentry>
                                         <term><varname>c</varname></term>
-                                        <listitem><para>Create a character device node if it does not exist yet.</para></listitem>
+                                        <term><varname>c+</varname></term>
+                                        <listitem><para>Create a
+                                        character device node if it
+                                        does not exist yet. If
+                                        suffixed with
+                                        <varname>+</varname> and a
+                                        file already exists where the
+                                        device node is to be created,
+                                        it will be removed and be
+                                        replaced by the device
+                                        node.</para></listitem>
                                 </varlistentry>
 
                                 <varlistentry>
                                         <term><varname>b</varname></term>
-                                        <listitem><para>Create a block device node if it does not exist yet.</para></listitem>
+                                        <term><varname>b+</varname></term>
+                                        <listitem><para>Create a block
+                                        device node if it does not
+                                        exist yet. If suffixed with
+                                        <varname>+</varname> and a
+                                        file already exists where the
+                                        device node is to be created,
+                                        it will be removed and be
+                                        replaced by the device
+                                        node.</para></listitem>
                                 </varlistentry>
 
                                 <varlistentry>
-                                        <term><varname>m</varname></term>
-                                        <listitem><para>If the
-                                        specified file path exists,
-                                        adjust its access mode, group
-                                        and user to the specified
-                                        values and reset the SELinux
-                                        security context. If it does not exist, do
-                                        nothing.</para></listitem>
+                                        <term><varname>C</varname></term>
+                                        <listitem><para>Recursively
+                                        copy a file or directory, if
+                                        the destination files or
+                                        directories do not exist
+                                        yet. Note that this command
+                                        will not descend into
+                                        subdirectories if the
+                                        destination directory already
+                                        exists. Instead, the entire
+                                        copy operation is
+                                        skipped. If the argument is omitted,
+                                        files from the source directory
+                                        <filename>/usr/share/factory/</filename>
+                                        with the same name are copied.</para></listitem>
                                 </varlistentry>
 
                                 <varlistentry>
@@ -240,29 +308,50 @@ L    /tmp/foobar -    -    -    -   /dev/null</programlisting>
 
                                 <varlistentry>
                                         <term><varname>z</varname></term>
-                                        <listitem><para>Restore
-                                        SELinux security context
-                                        and set ownership and access
-                                        mode of a file or directory if
-                                        it exists.  Lines of this type
-                                        accept shell-style globs in
-                                        place of normal path names.
+                                        <listitem><para>Adjust the
+                                        access mode, group and user,
+                                        and restore the SELinux security
+                                        context of a file or directory,
+                                        if it exists. Lines of this
+                                        type accept shell-style globs
+                                        in place of normal path names.
                                         </para></listitem>
                                 </varlistentry>
 
                                 <varlistentry>
                                         <term><varname>Z</varname></term>
                                         <listitem><para>Recursively
-                                        restore SELinux security
-                                        context and set
-                                        ownership and access mode of a
-                                        path and all its
-                                        subdirectories (if it is a
-                                        directory). Lines of this type
-                                        accept shell-style globs in
-                                        place of normal path
+                                        set the access mode, group and
+                                        user, and restore the SELinux
+                                        security context of a file or
+                                        directory if it exists, as
+                                        well as of its subdirectories
+                                        and the files contained
+                                        therein (if applicable). Lines
+                                        of this type accept
+                                        shell-style globs in place of
+                                        normal path
                                         names.</para></listitem>
                                 </varlistentry>
+
+                                <varlistentry>
+                                        <term><varname>t</varname></term>
+                                        <listitem><para>Set extended
+                                        attributes on item. It may be
+                                        used in conjunction with other
+                                        types (only <varname>d</varname>,
+                                        <varname>D</varname>, <varname>f</varname>,
+                                        <varname>F</varname>, <varname>L</varname>,
+                                        <varname>p</varname>, <varname>c</varname>,
+                                        <varname>b</varname>, makes sense).
+                                        If used as a standalone line, then
+                                        <command>systemd-tmpfiles</command>
+                                        will try to set extended
+                                        attributes on specified path.
+                                        This can be especially used to set
+                                        SMACK labels.
+                                        </para></listitem>
+                                </varlistentry>
                         </variablelist>
 
                         <para>If the exclamation mark is used, this
@@ -350,7 +439,23 @@ r! /tmp/.X[0-9]*-lock</programlisting>
                         will not be modified. This parameter is
                         ignored for <varname>x</varname>,
                         <varname>r</varname>, <varname>R</varname>,
-                        <varname>L</varname> lines.</para>
+                        <varname>L</varname>, <varname>t</varname> lines.</para>
+
+                        <para>Optionally, if prefixed with
+                        <literal>~</literal>, the access mode is masked
+                        based on the already set access bits for
+                        existing file or directories: if the existing
+                        file has all executable bits unset, all
+                        executable bits are removed from the new
+                        access mode, too. Similarly, if all read bits
+                        are removed from the old access mode, they will
+                        be removed from the new access mode too, and
+                        if all write bits are removed, they will be
+                        removed from the new access mode too. In
+                        addition, the sticky/SUID/SGID bit is removed unless
+                        applied to a directory. This
+                        functionality is particularly useful in
+                        conjunction with <varname>Z</varname>.</para>
                 </refsect2>
 
                 <refsect2>
@@ -366,8 +471,8 @@ r! /tmp/.X[0-9]*-lock</programlisting>
                         ownership will not be modified. These
                         parameters are ignored for
                         <varname>x</varname>, <varname>r</varname>,
-                        <varname>R</varname>, <varname>L</varname>
-                        lines.</para>
+                        <varname>R</varname>, <varname>L</varname>,
+                        <varname>t</varname> lines.</para>
                 </refsect2>
 
                 <refsect2>
@@ -429,8 +534,10 @@ r! /tmp/.X[0-9]*-lock</programlisting>
                         <varname>f</varname>, <varname>F</varname>,
                         and <varname>w</varname> may be used to
                         specify a short string that is written to the
-                        file, suffixed by a newline. Ignored for all
-                        other lines.</para>
+                        file, suffixed by a newline. For
+                        <varname>C</varname>, specifies the source file
+                        or directory. For <varname>t</varname> determines
+                        extended attributes to be set. Ignored for all other lines.</para>
                 </refsect2>
 
         </refsect1>
@@ -441,8 +548,9 @@ r! /tmp/.X[0-9]*-lock</programlisting>
                         <title>/etc/tmpfiles.d/screen.conf example</title>
                         <para><command>screen</command> needs two directories created at boot with specific modes and ownership.</para>
 
-                        <programlisting>d /var/run/screens  1777 root root 10d
-d /var/run/uscreens 0755 root root 10d12h</programlisting>
+                        <programlisting>d /run/screens  1777 root root 10d
+d /run/uscreens 0755 root root 10d12h
+t /run/screen - - - - user.name="John Smith" security.SMACK64=screen</programlisting>
                 </example>
                 <example>
                         <title>/etc/tmpfiles.d/abrt.conf example</title>
@@ -458,7 +566,8 @@ x /var/tmp/abrt/*</programlisting>
                 <para>
                         <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>systemd-tmpfiles</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
-                        <citerefentry><refentrytitle>systemd-delta</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                        <citerefentry><refentrytitle>systemd-delta</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>
                 </para>
         </refsect1>
 
diff --git a/man/udev.conf.xml b/man/udev.conf.xml
new file mode 100644 (file)
index 0000000..de84b91
--- /dev/null
@@ -0,0 +1,88 @@
+<?xml version='1.0'?>
+<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+  "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  This file is part of systemd.
+
+  Copyright 2014 Zbigniew Jędrzejewski-Szmek
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="udev.conf"
+          xmlns:xi="http://www.w3.org/2001/XInclude">
+
+  <refentryinfo>
+    <title>udev.conf</title>
+    <productname>systemd</productname>
+    <authorgroup>
+      <author>
+        <contrib>Developer</contrib>
+        <firstname>Kay</firstname>
+        <surname>Sievers</surname>
+        <email>kay@vrfy.org</email>
+      </author>
+    </authorgroup>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>udev.conf</refentrytitle>
+    <manvolnum>5</manvolnum>
+  </refmeta>
+
+  <refnamediv>
+    <refname>udev.conf</refname>
+    <refpurpose>Configuration for device event managing daemon</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <para><filename>/etc/udev/udev.conf</filename></para>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>
+      <citerefentry><refentrytitle>systemd-udevd</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+      expects its main configuration file at
+      <filename>/etc/udev/udev.conf</filename>. It consists of a set
+      of variables allowing the user to override default udev
+      values. All empty lines or lines beginning with '#' are
+      ignored. The following variables can be set:</para>
+
+      <variablelist>
+        <varlistentry>
+          <term><varname>udev_log</varname></term>
+
+          <listitem>
+            <para>The logging priority. Valid values are the numerical
+            syslog priorities or their textual representations:
+            <option>err</option>, <option>info</option> and
+            <option>debug</option>.</para>
+          </listitem>
+        </varlistentry>
+      </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>See Also</title>
+    <para>
+      <citerefentry><refentrytitle>systemd-udevd</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>udev</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>udevadm</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+    </para>
+  </refsect1>
+</refentry>
index 95b37fd..db72937 100644 (file)
         <varlistentry>
           <term><varname>NAME</varname></term>
           <listitem>
-            <para>The name to use for a network interface. The name of a device node
-            cannot be changed by udev, only additional symlinks can be created.</para>
+            <para>The name to use for a network interface. See
+            <citerefentry><refentrytitle>systemd.link</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+            for a higher-level mechanism for setting the interface name.
+            The name of a device node cannot be changed by udev, only additional
+            symlinks can be created.</para>
           </listitem>
         </varlistentry>
 
                 </listitem>
               </varlistentry>
               <varlistentry>
-                <term><option>event_timeout=</option></term>
-                <listitem>
-                  <para>Number of seconds an event waits for operations to finish before
-                  giving up and terminating itself.</para>
-                </listitem>
-              </varlistentry>
-              <varlistentry>
                 <term><option>string_escape=<replaceable>none|replace</replaceable></option></term>
                 <listitem>
                   <para>Usually control and other possibly unsafe characters are replaced
       During runtime only the binary database is used.</para>
   </refsect1>
 
-  <refsect1><title>Network Link Configuration</title>
-      <para>Network link configuration is performed by the <literal>net_setup_link</literal>
-      udev builtin.</para>
-
-      <para>The link files are read from the files located in the
-      system network directory <filename>/usr/lib/systemd/network</filename>,
-      the volatile runtime network directory <filename>/run/systemd/network</filename>
-      and the local administration network directory <filename>/etc/systemd/network</filename>.
-      Link files must have the extension <filename>.link</filename>; other extensions are ignored.
-      All link files are collectively sorted and processed in lexical order,
-      regardless of the directories in which they live. However, files with
-      identical filenames replace each other. Files in <filename>/etc</filename>
-      have the highest priority, files in <filename>/run</filename> take precedence
-      over files with the same name in <filename>/usr/lib</filename>. This can be
-      used to override a system-supplied link file with a local file if needed;
-      a symlink in <filename>/etc</filename> with the same name as a link file in
-      <filename>/usr/lib</filename>, pointing to <filename>/dev/null</filename>,
-      disables the link file entirely.</para>
-
-      <para>The link file contains a <literal>[Match]</literal> section, which
-      determines if a given link file may be applied to a given device; and a
-      <literal>[Link]</literal> section specifying how the device should be
-      configured. The first (in lexical order) of the link files that matches
-      a given device is applied.</para>
-
-      <para>A link file is said to match a device if each of the entries in the
-      <literal>[Match]</literal> section matches, or if the section is empty.
-      The following keys are accepted:</para>
-
-      <variablelist class='network-directives'>
-        <varlistentry>
-          <term><varname>MACAddress=</varname></term>
-          <listitem>
-            <para>The hardware address.
-            </para>
-          </listitem>
-        </varlistentry>
-        <varlistentry>
-          <term><varname>Path=</varname></term>
-          <listitem>
-            <para>The persistent path, as exposed by the udev property <literal>ID_PATH</literal>.
-            May contain shell style globs.</para>
-          </listitem>
-        </varlistentry>
-        <varlistentry>
-          <term><varname>Driver=</varname></term>
-          <listitem>
-            <para>The driver currently bound to the device, as exposed by the
-            udev property <literal>DRIVER</literal> of its parent device, or if
-            that is not set the driver as exposed by <literal>ethtool -i</literal>
-            of the device itself.</para>
-          </listitem>
-        </varlistentry>
-        <varlistentry>
-          <term><varname>Type=</varname></term>
-          <listitem>
-            <para>The device type, as exposed by the udev property <literal>DEVTYPE</literal>.</para>
-          </listitem>
-        </varlistentry>
-        <varlistentry>
-          <term><varname>Host=</varname></term>
-          <listitem>
-            <para>Matches against the hostname or machine ID of the
-            host. See <literal>ConditionHost=</literal> in
-            <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
-            for details.</para>
-          </listitem>
-        </varlistentry>
-        <varlistentry>
-          <term><varname>Virtualization=</varname></term>
-          <listitem>
-            <para>Checks whether the system is executed in a virtualized
-            environment and optionally test whether it is a specific
-            implementation. See <literal>ConditionVirtualization=</literal> in
-            <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
-            for details.</para>
-          </listitem>
-        </varlistentry>
-        <varlistentry>
-          <term><varname>KernelCommandLine=</varname></term>
-          <listitem>
-            <para>Checks whether a specific kernel command line option is
-            set (or if prefixed with the exclamation mark unset). See
-            <literal>ConditionKernelCommandLine=</literal> in
-            <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
-            for details.</para>
-          </listitem>
-        </varlistentry>
-        <varlistentry>
-          <term><varname>Architecture=</varname></term>
-          <listitem>
-            <para>Checks whether the system is running on a specific
-            architecture. See <literal>ConditionArchitecture=</literal> in
-            <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
-            for details.</para>
-          </listitem>
-        </varlistentry>
-      </variablelist>
-
-      <para>The <literal>[Link]</literal> section accepts the following keys:</para>
-
-      <variablelist class='network-directives'>
-        <varlistentry>
-          <term><varname>Description=</varname></term>
-          <listitem>
-            <para>A description of the device.</para>
-          </listitem>
-        </varlistentry>
-        <varlistentry>
-          <term><varname>Alias=</varname></term>
-          <listitem>
-            <para>The <literal>ifalias</literal> is set to this value.</para>
-          </listitem>
-        </varlistentry>
-        <varlistentry>
-          <term><varname>MACAddressPolicy=</varname></term>
-          <listitem>
-            <para>The policy by which the MAC address should be set. The
-              available policies are:
-            </para>
-            <variablelist>
-              <varlistentry>
-                <term><literal>persistent</literal></term>
-                <listitem>
-                  <para>If the hardware has a persistent MAC address, as most
-                    hardware should, and this is used by the kernel, nothing is
-                    done. Otherwise, a new MAC address is generated which is
-                    guaranteed to be the same on every boot for the given
-                    machine and the given device, but which is otherwise random.
-                  </para>
-                </listitem>
-              </varlistentry>
-              <varlistentry>
-                <term><literal>random</literal></term>
-                <listitem>
-                  <para>If the kernel is using a random MAC address, nothing is
-                    done. Otherwise, a new address is randomly generated each
-                    time the device appears, typically at boot.
-                  </para>
-                </listitem>
-              </varlistentry>
-            </variablelist>
-          </listitem>
-        </varlistentry>
-        <varlistentry>
-          <term><varname>MACAddress=</varname></term>
-          <listitem>
-            <para>The MAC address to use, if no <literal>MACAddressPolicy=</literal>
-              is specified.
-            </para>
-          </listitem>
-        </varlistentry>
-        <varlistentry>
-          <term><varname>NamePolicy=</varname></term>
-          <listitem>
-            <para>An ordered, space-separated list of policies by which the
-              interface name should be set. <literal>NamePolicy</literal> may
-              be disabled by specifying <literal>net.ifnames=0</literal> on the
-              kernel commandline. Each of the policies may fail, and the first
-              successful one is used. The name is not set directly, but
-              is exported to udev as the property <literal>ID_NET_NAME</literal>,
-              which is, by default, used by a udev rule to set
-              <literal>NAME</literal>. The available policies are:
-            </para>
-            <variablelist>
-              <varlistentry>
-                <term><literal>database</literal></term>
-                <listitem>
-                  <para>The name is set based on entries in the Hardware
-                    Database with the key
-                    <literal>ID_NET_NAME_FROM_DATABASE</literal>.
-                  </para>
-                </listitem>
-              </varlistentry>
-              <varlistentry>
-                <term><literal>onboard</literal></term>
-                <listitem>
-                  <para>The name is set based on information given by the
-                    firmware for on-board devices, as exported by the udev
-                    property <literal>ID_NET_NAME_ONBOARD</literal>.
-                  </para>
-                </listitem>
-              </varlistentry>
-              <varlistentry>
-                <term><literal>slot</literal></term>
-                <listitem>
-                  <para>The name is set based on information given by the
-                    firmware for hot-plug devices, as exported by the udev
-                    property <literal>ID_NET_NAME_SLOT</literal>.
-                  </para>
-                </listitem>
-              </varlistentry>
-              <varlistentry>
-                <term><literal>path</literal></term>
-                <listitem>
-                  <para>The name is set based on the device's physical location,
-                    as exported by the udev property
-                    <literal>ID_NET_NAME_PATH</literal>.
-                  </para>
-                </listitem>
-              </varlistentry>
-              <varlistentry>
-                <term><literal>mac</literal></term>
-                <listitem>
-                  <para>The name is set based on the device's persistent MAC
-                    address, as exported by the udev property
-                    <literal>ID_NET_NAME_MAC</literal>.
-                  </para>
-                </listitem>
-              </varlistentry>
-            </variablelist>
-          </listitem>
-        </varlistentry>
-        <varlistentry>
-          <term><varname>Name=</varname></term>
-          <listitem>
-            <para>The interface name to use in case all the policies specified
-              in <varname>NamePolicy=</varname> fail, or in case
-              <varname>NamePolicy=</varname> is missing or disabled.
-            </para>
-          </listitem>
-        </varlistentry>
-        <varlistentry>
-          <term><varname>MTUBytes=</varname></term>
-          <listitem>
-            <para>The maximum transmission unit in bytes to set for
-            the device. The usual suffixes K, M, G, are supported and
-            are understood to the base of 1024.</para>
-          </listitem>
-        </varlistentry>
-        <varlistentry>
-          <term><varname>BitsPerSecond=</varname></term>
-          <listitem>
-            <para>The speed to set for the device, the value is
-            rounded down to the nearest Mbps. The usual suffixes K, M,
-            G, are supported and are understood to the base of
-            1000.</para>
-          </listitem>
-        </varlistentry>
-        <varlistentry>
-          <term><varname>Duplex=</varname></term>
-          <listitem>
-            <para>The duplex mode to set for the device. The accepted values
-              are <literal>half</literal> and <literal>full</literal>.
-            </para>
-          </listitem>
-        </varlistentry>
-        <varlistentry>
-          <term><varname>WakeOnLan=</varname></term>
-          <listitem>
-            <para>The Wake-on-LAN policy to set for the device. The supported
-              values are:
-            </para>
-            <variablelist>
-              <varlistentry>
-                <term><literal>phy</literal></term>
-                <listitem>
-                  <para>Wake on PHY activity.</para>
-                </listitem>
-              </varlistentry>
-              <varlistentry>
-                <term><literal>magic</literal></term>
-                <listitem>
-                  <para>Wake on receipt of a magic packet.</para>
-                </listitem>
-              </varlistentry>
-              <varlistentry>
-                <term><literal>off</literal></term>
-                <listitem>
-                  <para>Never wake.</para>
-                </listitem>
-              </varlistentry>
-            </variablelist>
-          </listitem>
-        </varlistentry>
-      </variablelist>
-  </refsect1>
-
   <refsect1>
     <title>See Also</title>
     <para>
       </citerefentry>,
       <citerefentry>
         <refentrytitle>udevadm</refentrytitle><manvolnum>8</manvolnum>
+      </citerefentry>,
+      <citerefentry>
+        <refentrytitle>systemd.link</refentrytitle><manvolnum>5</manvolnum>
       </citerefentry>
     </para>
   </refsect1>
index a3f8d54..749144d 100644 (file)
@@ -20,7 +20,6 @@
   <refmeta>
     <refentrytitle>udevadm</refentrytitle>
     <manvolnum>8</manvolnum>
-    <refmiscinfo class="version"></refmiscinfo>
   </refmeta>
 
   <refnamediv>
           </listitem>
         </varlistentry>
         <varlistentry>
-          <term><option>-s</option></term>
-          <term><option>--seq-start=<replaceable>SEQNUM</replaceable></option></term>
-          <listitem>
-            <para>Wait only for events after the given sequence
-            number.</para>
-          </listitem>
-        </varlistentry>
-        <varlistentry>
-          <term><option>-e</option></term>
-          <term><option>--seq-end=<replaceable>SEQNUM</replaceable></option></term>
-          <listitem>
-            <para>Wait only for events before the given sequence number.</para>
-          </listitem>
-        </varlistentry>
-        <varlistentry>
           <term><option>-E</option></term>
           <term><option>--exit-if-exists=<replaceable>FILE</replaceable></option></term>
           <listitem>
           </listitem>
         </varlistentry>
         <varlistentry>
-          <term><option>-q</option></term>
-          <term><option>--quiet</option></term>
-          <listitem>
-            <para>Do not print any output, like the remaining queue entries when reaching the timeout.</para>
-          </listitem>
-        </varlistentry>
-        <varlistentry>
           <term><option>-h</option></term>
           <term><option>--help</option></term>
           <listitem>
     <title>See Also</title>
     <para><citerefentry>
         <refentrytitle>udev</refentrytitle><manvolnum>7</manvolnum>
-    </citerefentry>
+    </citerefentry>,
     <citerefentry>
         <refentrytitle>systemd-udevd.service</refentrytitle><manvolnum>8</manvolnum>
     </citerefentry></para>
index cca5c79..8616c54 100644 (file)
     <term><option>--host=</option></term>
 
     <listitem id='host-text'>
-      <para>Execute the operation remotely. Specify a hostname, or
+      <para>Execute the operation remotely. Specify a hostname, or a
       username and hostname separated by <literal>@</literal>, to
-      connect to. This will use SSH to talk to the remote machine
-      manager instance.</para>
+      connect to. The hostname may optionally be suffixed by a
+      container name, separated by <literal>:</literal>, which
+      connects directly to a specific container on the specified
+      host. This will use SSH to talk to the remote machine manager
+      instance. Container names may be enumerated with
+      <command>machinectl -H
+      <replaceable>HOST</replaceable></command>.</para>
     </listitem>
   </varlistentry>
 
index d49fba0..6863ca9 100644 (file)
@@ -1,6 +1,14 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
 [Match]
 Virtualization=container
 Name=host0
 
 [Network]
-DHCP=yes
+DHCP=both
+IPv4LL=yes
similarity index 75%
rename from units/org.freedesktop.DBus.busname
rename to network/80-container-ve.network
index 68c649d..cb04c7c 100644 (file)
@@ -5,8 +5,11 @@
 #  the Free Software Foundation; either version 2.1 of the License, or
 #  (at your option) any later version.
 
-[Unit]
-Description=Bus Driver Service Bus Name
+[Match]
+Name=ve-*
+Driver=veth
 
-[BusName]
-Service=systemd-bus-driverd.service
+[Network]
+Address=0.0.0.0/28
+IPv4LL=yes
+DHCPServer=yes
index 53215f6..79538f9 100644 (file)
@@ -1,3 +1,3 @@
 [Link]
-NamePolicy=database onboard slot path
+NamePolicy=kernel database onboard slot path
 MACAddressPolicy=persistent
diff --git a/network/Makefile b/network/Makefile
new file mode 120000 (symlink)
index 0000000..bd10475
--- /dev/null
@@ -0,0 +1 @@
+../src/Makefile
\ No newline at end of file
index ede5999..df48b48 100644 (file)
@@ -7,5 +7,39 @@
     <filesystem path="/sbin/*" label="_" exec_label="none" />
     <filesystem path="/usr/bin/*" label="_" exec_label="none" />
     <filesystem path="/usr/sbin/*" label="_" exec_label="none" />
+    <filesystem path="/usr/lib/systemd/systemd-journald" exec_label="^" />
+    <filesystem path="/usr/lib/systemd/systemd" exec_label="none" />
+    <filesystem path="/usr/lib/systemd/systemd-ac-power" exec_label="none" />
+    <filesystem path="/usr/lib/systemd/systemd-activate" exec_label="none" />
+    <filesystem path="/usr/lib/systemd/systemd-bootchart" exec_label="none" />
+    <filesystem path="/usr/lib/systemd/systemd-bus-proxyd" exec_label="none" />
+    <filesystem path="/usr/lib/systemd/systemd-fsck" exec_label="none" />
+    <filesystem path="/usr/lib/systemd/systemd-initctl" exec_label="none" />
+    <filesystem path="/usr/lib/systemd/systemd-logind" exec_label="none" />
+    <filesystem path="/usr/lib/systemd/systemd-modules-load" exec_label="none" />
+    <filesystem path="/usr/lib/systemd/systemd-multi-seat-x" exec_label="none" />
+    <filesystem path="/usr/lib/systemd/systemd-readahead" exec_label="none" />
+    <filesystem path="/usr/lib/systemd/systemd-remount-fs" exec_label="none" />
+    <filesystem path="/usr/lib/systemd/systemd-reply-password" exec_label="none" />
+    <filesystem path="/usr/lib/systemd/systemd-shutdown" exec_label="none" />
+    <filesystem path="/usr/lib/systemd/systemd-shutdownd" exec_label="none" />
+    <filesystem path="/usr/lib/systemd/systemd-sleep" exec_label="none" />
+    <filesystem path="/usr/lib/systemd/systemd-socket-proxyd" exec_label="none" />
+    <filesystem path="/usr/lib/systemd/systemd-sysctl" exec_label="none" />
+    <filesystem path="/usr/lib/systemd/systemd-udevd" exec_label="none" />
+    <filesystem path="/usr/lib/systemd/systemd-update-done" exec_label="none" />
+    <filesystem path="/usr/lib/systemd/systemd-update-utmp" exec_label="none" />
+    <filesystem path="/usr/lib/systemd/systemd-user-sessions" exec_label="none" />
+    <filesystem path="/usr/lib/systemd/system-generators/systemd-debug-generator" exec_label="none" />
+    <filesystem path="/usr/lib/systemd/system-generators/systemd-fstab-generator" exec_label="none" />
+    <filesystem path="/usr/lib/systemd/system-generators/systemd-getty-generator" exec_label="none" />
+    <filesystem path="/usr/lib/systemd/systemd-cgroups-agent" label="_" exec_label="systemd" />
+    <filesystem path="/usr/lib/udev/accelerometer" exec_label="none" />
+    <filesystem path="/usr/lib/udev/ata_id" exec_label="none" />
+    <filesystem path="/usr/lib/udev/cdrom_id" exec_label="none" />
+    <filesystem path="/usr/lib/udev/collect" exec_label="none" />
+    <filesystem path="/usr/lib/udev/mtd_probe" exec_label="none" />
+    <filesystem path="/usr/lib/udev/scsi_id" exec_label="none" />
+    <filesystem path="/usr/lib/udev/v4l_id" exec_label="none" />
   </assign>
 </manifest>
index 7622e03..bda8005 100644 (file)
@@ -5,21 +5,37 @@
 # directory.
 %global __requires_exclude pkg-config
 
+%bcond_with unified_directory
+%bcond_with kdbus
+
+%define enable() %{expand:%%{?with_%{1}:--enable-%{1}}%%{!?with_%{1}:--disable-%{1}}}
+# In order to reduce the root privilege daemon,
+# '/run' directory has a group access permission for run_tmp group (gid:1902).
+%define RUN_TMP_GID 1902
+%define WITH_RUN_GID %{RUN_TMP_GID}
+
 %define WITH_BASH_COMPLETION 0
+%define WITH_ZSH_COMPLETION 0
 %define WITH_BLACKLIGHT 0
 %define WITH_COREDUMP 0
-%define WITH_PAM 0
 %define WITH_RANDOMSEED 0
 
-%define WITH_LOGIND 0
+%define WITH_LOGIND 1
+%define WITH_PAM 1
+%define WITH_FIRSTBOOT 0
 %define WITH_TIMEDATED 0
 
+%define WITH_NETWORKD 0
+%define WITH_RESOLVED 0
+%define WITH_TIMESYNCD 0
+%define WITH_RFKILL 0
+
 %define WITH_COMPAT_LIBS 1
 
 Name:           systemd
 Url:            http://www.freedesktop.org/wiki/Software/systemd
-Version:        210
-Release:        1
+Version:        216
+Release:        1%{?release_flags}
 License:        LGPL-2.1+ and MIT and GPL-2.0+
 Summary:        A System and Service Manager
 Source0:        http://www.freedesktop.org/software/systemd/%{name}-%{version}.tar.xz
@@ -36,6 +52,7 @@ Source1001:     systemd.manifest
 BuildRequires:  glib2-devel
 BuildRequires:  kmod-devel >= 15
 BuildRequires:  hwdata
+BuildRequires:  kernel-headers
 
 BuildRequires:  libacl-devel
 BuildRequires:  pkgconfig
@@ -62,6 +79,9 @@ BuildRequires:  libtool
 BuildRequires:  smack-devel
 Requires:       dbus
 Requires:       %{name}-libs = %{version}-%{release}
+%if %{WITH_PAM}
+Requires:       pam
+%endif
 
 Provides:       /bin/systemctl
 Provides:       /sbin/shutdown
@@ -89,7 +109,7 @@ work as a drop-in replacement for sysvinit.
 
 %package libs
 Summary:        systemd libraries
-License:        GPL-2.0+
+License:        LGPLv2+ and MIT
 Provides:       libudev
 Obsoletes:      systemd < 185-4
 Conflicts:      systemd < 185-4
@@ -99,7 +119,7 @@ Libraries for systemd and udev, as well as the systemd PAM module.
 
 %package devel
 Summary:        Development headers for systemd
-License:        GPL-2.0+
+License:        LGPLv2+ and MIT
 Requires:       %{name} = %{version}-%{release}
 Provides:       pkgconfig(libudev)
 Provides:       libudev-devel = %{version}
@@ -110,7 +130,7 @@ Development headers and auxiliary files for developing applications for systemd.
 
 %package -n libgudev1
 Summary:        Libraries for adding libudev support to applications that use glib
-License:        GPL-2.0+
+License:        LGPLv2+
 Requires:       %{name} = %{version}-%{release}
 
 %description -n libgudev1
@@ -120,7 +140,7 @@ functionality from applications that use glib.
 %package -n libgudev1-devel
 Summary:        Header files for adding libudev support to applications that use glib
 Requires:       libgudev1 = %{version}-%{release}
-License:        GPL-2.0+
+License:        LGPLv2+
 
 %description -n libgudev1-devel
 This package contains the header and pkg-config files for developing
@@ -129,7 +149,7 @@ glib-based applications using libudev functionality.
 %package journal-gateway
 Summary:        Gateway for serving journal events over the network using HTTP
 Requires:       %{name} = %{version}-%{release}
-License:        LGPL-2.1+
+License:        LGPLv2+
 Requires(pre):    /usr/bin/getent
 Requires(post):   systemd
 Requires(preun):  systemd
@@ -144,36 +164,21 @@ systemd-journal-gatewayd serves journal events over the network using HTTP.
 %build
 cp %{SOURCE1001} .
 
-export CFLAGS+=" -g -O0 -DCONFIG_TIZEN -DCONFIG_TIZEN_WIP"
+export CFLAGS=" -g -O0 -fPIE -ftrapv"
+export LDFLAGS=" -pie"
 autoreconf -fiv
 %configure \
-    --disable-static \
-    --with-sysvinit-path= \
-    --with-sysvrcnd-path= \
-    --disable-gtk-doc-html \
-    --disable-selinux \
-    --disable-ima \
-    --disable-tcpwrap \
-    --enable-split-usr \
-    --disable-nls \
-    --disable-manpages \
-    --disable-efi \
-%if %{WITH_PAM}
-    --with-pamlibdir="/%{_libdir}/security" \
-%else
+    %{enable kdbus} \
+%if ! %{WITH_PAM}
     --disable-pam \
 %endif
     --with-firmware-path="/%{_libdir}/firmware" \
+%if ! %{WITH_BASH_COMPLETION}
+    --with-bashcompletiondir="" \
+%endif
+%if ! %{WITH_ZSH_COMPLETION}
     --with-zshcompletiondir="" \
-    --disable-hostnamed \
-    --disable-machined \
-    --disable-binfmt \
-    --disable-vconsole \
-    --disable-quotacheck \
-    --disable-localed \
-    --disable-polkit \
-    --disable-myhostname \
-    --without-python \
+%endif
 %if "%{?tizen_profile_name}" == "wearable"
     --disable-xz \
 %endif
@@ -195,6 +200,50 @@ autoreconf -fiv
 %if %{WITH_COMPAT_LIBS}
     --enable-compat-libs \
 %endif
+%if ! %{WITH_NETWORKD}
+    --disable-networkd \
+%endif
+%if ! %{WITH_RESOLVED}
+    --disable-resolved \
+%endif
+%if ! %{WITH_TIMESYNCD}
+    --disable-timesyncd \
+%endif
+%if ! %{WITH_RFKILL}
+    --disable-rfkill \
+%endif
+%if %{WITH_RUN_GID}
+    --with-run-gid=%{WITH_RUN_GID} \
+%endif
+%if ! %{WITH_FIRSTBOOT}
+    --disable-firstboot \
+%endif
+%if "%{?tizen_profile_name}" == "mobile" || "%{?tizen_profile_name}" == "wearable"
+    --with-smack-run-label="systemd" \
+    --with-smack-default-process-label="systemd::no-label" \
+    --with-process-label \
+%endif
+    --enable-tizen \
+    --enable-tizen-wip \
+    --disable-static \
+    --with-sysvinit-path= \
+    --with-sysvrcnd-path= \
+    --disable-gtk-doc-html \
+    --disable-selinux \
+    --disable-ima \
+    --enable-split-usr \
+    --disable-nls \
+    --disable-manpages \
+    --disable-efi \
+    --disable-hostnamed \
+    --disable-machined \
+    --disable-binfmt \
+    --disable-vconsole \
+    --disable-quotacheck \
+    --disable-localed \
+    --disable-polkit \
+    --disable-myhostname \
+    --without-python
 
 make %{?_smp_mflags}
 
@@ -210,21 +259,34 @@ find %{buildroot} \( -name '*.a' -o -name '*.la' \) -delete
 mkdir -p %{buildroot}/%{_sbindir}
 mkdir -p %{buildroot}/sbin
 ln -sf ../bin/udevadm %{buildroot}%{_sbindir}/udevadm
+# TODO: Below code should be removed after we go unified directory structure.
+%if !%{with unified_directory}
+mkdir -p %{buildroot}%{_prefix}/lib/firmware/updates
+%endif
 
 # Create SysV compatibility symlinks. systemctl/systemd are smart
 # enough to detect in which way they are called.
 ln -s ../lib/systemd/systemd %{buildroot}%{_sbindir}/init
+# TODO: Below code should be removed after we go unified directory structure.
+%if %{with unified_directory}
 ln -s /usr/lib/systemd/systemd %{buildroot}/sbin/init
+%endif
 ln -s ../lib/systemd/systemd %{buildroot}%{_bindir}/systemd
 ln -s ../bin/systemctl %{buildroot}%{_sbindir}/reboot
+# TODO: Below code should be removed after we go unified directory structure.
+%if %{with unified_directory}
 ln -s /usr/bin/systemctl %{buildroot}/sbin/reboot
+%endif
 ln -s ../bin/systemctl %{buildroot}%{_sbindir}/halt
 ln -s ../bin/systemctl %{buildroot}%{_sbindir}/poweroff
 ln -s ../bin/systemctl %{buildroot}%{_sbindir}/shutdown
 ln -s ../bin/systemctl %{buildroot}%{_sbindir}/telinit
 ln -s ../bin/systemctl %{buildroot}%{_sbindir}/runlevel
 ln -s /usr/lib/systemd/systemd-udevd %{buildroot}/%{_sbindir}/udevd
+# TODO: Below code should be removed after we go unified directory structure.
+%if %{with unified_directory}
 ln -s /lib/firmware %{buildroot}%{_libdir}/firmware
+%endif
 
 # We create all wants links manually at installation time to make sure
 # they are not owned and hence overriden by rpm after the user deleted
@@ -243,7 +305,6 @@ mkdir -p %{buildroot}%{_prefix}/lib/systemd/user-generators
 # Create new-style configuration files so that we can ghost-own them
 touch %{buildroot}%{_sysconfdir}/hostname
 touch %{buildroot}%{_sysconfdir}/locale.conf
-touch %{buildroot}%{_sysconfdir}/machine-id
 touch %{buildroot}%{_sysconfdir}/machine-info
 touch %{buildroot}%{_sysconfdir}/localtime
 mkdir -p %{buildroot}%{_sysconfdir}/X11/xorg.conf.d
@@ -285,27 +346,6 @@ rm -f %{buildroot}%{_libdir}/udev/rules.d/80-net-name-slot.rules
 rm -f %{buildroot}%{_libdir}/udev/rules.d/95-keyboard-force-release.rules
 rm -f %{buildroot}%{_libdir}/udev/rules.d/95-keymap.rules
 
-%if ! %{WITH_BASH_COMPLETION}
-# Hmm, bash completion also removed :(
-rm -f %{buildroot}%{_datadir}/bash-completion/completions/busctl
-rm -f %{buildroot}%{_datadir}/bash-completion/completions/journalctl
-rm -f %{buildroot}%{_datadir}/bash-completion/completions/kernel-install
-%if %{WITH_LOGIND}
-rm -f %{buildroot}%{_datadir}/bash-completion/completions/loginctl
-%endif
-%if %{WITH_TIMEDATED}
-rm -f %{buildroot}%{_datadir}/bash-completion/completions/timedatectl
-%endif
-rm -f %{buildroot}%{_datadir}/bash-completion/completions/systemctl
-%if %{WITH_COREDUMP}
-rm -f %{buildroot}%{_datadir}/bash-completion/completions/systemd-coredumpctl
-%endif
-rm -f %{buildroot}%{_datadir}/bash-completion/completions/systemd-delta
-rm -f %{buildroot}%{_datadir}/bash-completion/completions/systemd-run
-rm -f %{buildroot}%{_datadir}/bash-completion/completions/udevadm
-rm -f %{buildroot}%{_datadir}/bash-completion/completions/systemd-analyze
-%endif
-
 # This will be done by tizen specific init script.
 rm -f %{buildroot}%{_libdir}/systemd/system/local-fs.target.wants/systemd-fsck-root.service
 
@@ -330,6 +370,15 @@ chmod +x %{SOURCE1}
 %{SOURCE1} %{SOURCE13} %{buildroot}%{_sysconfdir}/systemd/journald.conf
 %{SOURCE1} %{SOURCE14} %{buildroot}%{_sysconfdir}/systemd/bootchart.conf
 
+# We do not need some of systemd native unit files. Even if those are
+# not used, it can make slower unit loading time.
+for unit in \
+       tmp.mount \
+       local-fs.target.wants/tmp.mount;
+do
+       rm -f %{buildroot}%{_libdir}/systemd/system/$unit
+done
+
 # All of licenses should be manifested in /usr/share/license.
 mkdir -p %{buildroot}%{_datadir}/license
 cat LICENSE.LGPL2.1 > %{buildroot}%{_datadir}/license/systemd
@@ -348,7 +397,6 @@ getent group systemd-journal >/dev/null 2>&1 || groupadd -r -g 190 systemd-journ
 systemctl stop systemd-udevd-control.socket systemd-udevd-kernel.socket systemd-udevd.service >/dev/null 2>&1 || :
 
 %post
-systemd-machine-id-setup >/dev/null 2>&1 || :
 %if %{WITH_RANDOMSEED}
 /usr/lib/systemd/systemd-random-seed save >/dev/null 2>&1 || :
 %endif
@@ -369,6 +417,7 @@ ln -s /dev/null /etc/systemd/system/systemd-remount-fs.service
 ln -s /dev/null /etc/systemd/system/systemd-journal-flush.service
 ln -s /dev/null /etc/systemd/system/systemd-update-utmp.service
 ln -s /dev/null /etc/systemd/system/kmod-static-nodes.service
+ln -s /dev/null /etc/systemd/system/systemd-fsck-root.service
 
 # Tizen is not supporting /usr/lib/macros.d yet.
 # To avoid this, the macro will be copied to origin macro dir.
@@ -391,6 +440,10 @@ fi
 %post -n libgudev1 -p /sbin/ldconfig
 %postun -n libgudev1 -p /sbin/ldconfig
 
+%posttrans
+# Make sure /etc/mtab is pointing /proc/self/mounts
+ln -sf ../proc/self/mounts /etc/mtab
+
 %files
 %defattr(-,root,root,-)
 %{_datadir}/license/systemd
@@ -412,8 +465,14 @@ fi
 %dir %{_prefix}/lib/tmpfiles.d
 %dir %{_prefix}/lib/sysctl.d
 %dir %{_prefix}/lib/modules-load.d
+# TODO: Below code should be removed after we go unified directory structure.
+%if %{with unified_directory}
 %{_prefix}/lib/firmware
 %dir %{_datadir}/systemd
+%else
+%dir %{_prefix}/lib/firmware
+%endif
+%dir %{_datadir}/systemd
 %dir %{_datadir}/pkgconfig
 %dir %{_localstatedir}/log/journal
 %dir %{_localstatedir}/lib/systemd
@@ -445,7 +504,6 @@ fi
 %ghost %config(noreplace) %{_sysconfdir}/hostname
 %ghost %config(noreplace) %{_sysconfdir}/localtime
 %ghost %config(noreplace) %{_sysconfdir}/locale.conf
-%ghost %config(noreplace) %{_sysconfdir}/machine-id
 %ghost %config(noreplace) %{_sysconfdir}/machine-info
 %ghost %config(noreplace) %{_sysconfdir}/X11/xorg.conf.d/00-keyboard.conf
 %ghost %{_localstatedir}/lib/systemd/catalog/database
@@ -478,31 +536,54 @@ fi
 %if %{WITH_COREDUMP}
 %{_bindir}/systemd-coredumpctl
 %endif
+%{_bindir}/systemd-escape
+%if %{WITH_FIRSTBOOT}
+%{_bindir}/systemd-firstboot
+%endif
+%{_bindir}/systemd-path
+%{_bindir}/systemd-sysusers
 %{_bindir}/udevadm
 %{_prefix}/lib/systemd/systemd
 %{_prefix}/lib/systemd/system
 %{_prefix}/lib/systemd/user
 %{_prefix}/lib/systemd/systemd-*
 %{_prefix}/lib/udev
-%{_prefix}/lib/systemd/system-generators/systemd-getty-generator
+%{_prefix}/lib/systemd/system-generators/systemd-debug-generator
 %{_prefix}/lib/systemd/system-generators/systemd-fstab-generator
+%{_prefix}/lib/systemd/system-generators/systemd-getty-generator
+%if %{with kdbus}
+%exclude %{_prefix}/lib/systemd/system-generators/systemd-dbus1-generator
+%exclude %{_prefix}/lib/systemd/user-generators/systemd-dbus1-generator
+%endif
 %exclude %{_prefix}/lib/systemd/system-generators/systemd-system-update-generator
 %exclude %{_prefix}/lib/systemd/system-generators/systemd-gpt-auto-generator
 %{_prefix}/lib/tmpfiles.d/systemd.conf
 %{_prefix}/lib/tmpfiles.d/systemd-nologin.conf
-%{_prefix}/lib/tmpfiles.d/x11.conf
+%{_prefix}/lib/tmpfiles.d/systemd-remote.conf
+%{_prefix}/lib/tmpfiles.d/etc.conf
 %{_prefix}/lib/tmpfiles.d/tmp.conf
+%{_prefix}/lib/tmpfiles.d/var.conf
+%{_prefix}/lib/tmpfiles.d/x11.conf
 %{_prefix}/lib/sysctl.d/50-default.conf
 %{_prefix}/lib/systemd/catalog/systemd.catalog
 %{_prefix}/lib/systemd/catalog/systemd.fr.catalog
 %{_prefix}/lib/systemd/catalog/systemd.it.catalog
 %{_prefix}/lib/systemd/catalog/systemd.ru.catalog
 %{_prefix}/lib/systemd/network/80-container-host0.network
+%{_prefix}/lib/systemd/network/80-container-ve.network
 %{_prefix}/lib/systemd/network/99-default.link
+%{_prefix}/lib/systemd/system-preset/90-systemd.preset
+%{_prefix}/lib/sysusers.d/basic.conf
+%{_prefix}/lib/sysusers.d/systemd-remote.conf
+%{_prefix}/lib/sysusers.d/systemd.conf
+%exclude %{_prefix}/lib/systemd/system/systemd-bootchart.service
 %{_sbindir}/init
-/sbin/init
 %{_sbindir}/reboot
+# TODO: Below code should be removed after we go unified directory structure.
+%if %{with unified_directory}
+/sbin/init
 /sbin/reboot
+%endif
 %{_sbindir}/halt
 %{_sbindir}/poweroff
 %{_sbindir}/shutdown
@@ -524,24 +605,32 @@ fi
 %{_datadir}/pkgconfig/systemd.pc
 %{_datadir}/pkgconfig/udev.pc
 %if %{WITH_BASH_COMPLETION}
-%{_datadir}/bash-completion/completions/buxctl
+%{_datadir}/bash-completion/completions/busctl
 %{_datadir}/bash-completion/completions/journalctl
 %{_datadir}/bash-completion/completions/kernel-install
 %if %{WITH_LOGIND}
 %{_datadir}/bash-completion/completions/loginctl
 %endif
-%if %{WITH_TIMEDATED}
-%{_datadir}/bash-completion/completions/timedatectl
-%endif
 %{_datadir}/bash-completion/completions/systemctl
+%{_datadir}/bash-completion/completions/systemd-analyze
+%{_datadir}/bash-completion/completions/systemd-cat
+%{_datadir}/bash-completion/completions/systemd-cgls
+%{_datadir}/bash-completion/completions/systemd-cgtop
 %if %{WITH_COREDUMP}
 %{_datadir}/bash-completion/completions/systemd-coredumpctl
 %endif
 %{_datadir}/bash-completion/completions/systemd-delta
+%{_datadir}/bash-completion/completions/systemd-detect-virt
+%{_datadir}/bash-completion/completions/systemd-nspawn
 %{_datadir}/bash-completion/completions/systemd-run
+%if %{WITH_TIMEDATED}
+%{_datadir}/bash-completion/completions/timedatectl
+%endif
 %{_datadir}/bash-completion/completions/udevadm
-%{_datadir}/bash-completion/completions/systemd-analyze
 %endif
+%exclude %{_datadir}/factory/etc/nsswitch.conf
+%{_datadir}/factory/etc/pam.d/other
+%{_datadir}/factory/etc/pam.d/system-auth
 %manifest systemd.manifest
 
 %files libs
@@ -573,13 +662,22 @@ fi
 %{_libdir}/libudev.so
 %{_includedir}/systemd/_sd-common.h
 %{_includedir}/systemd/sd-daemon.h
-##%if %{WITH_LOGIND}
 %{_includedir}/systemd/sd-login.h
-##%endif
 %{_includedir}/systemd/sd-journal.h
 %{_includedir}/systemd/sd-id128.h
 %{_includedir}/systemd/sd-messages.h
 %{_includedir}/libudev.h
+%if %{with kdbus}
+%{_includedir}/systemd/sd-bus-protocol.h
+%{_includedir}/systemd/sd-bus-vtable.h
+%{_includedir}/systemd/sd-bus.h
+%{_includedir}/systemd/sd-event.h
+%{_includedir}/systemd/sd-memfd.h
+%{_includedir}/systemd/sd-path.h
+%{_includedir}/systemd/sd-resolve.h
+%{_includedir}/systemd/sd-rtnl.h
+%{_includedir}/systemd/sd-utf8.h
+%endif
 %{_libdir}/pkgconfig/libsystemd.pc
 %if %{WITH_COMPAT_LIBS}
 %{_libdir}/pkgconfig/libsystemd-daemon.pc
index f844c1e..1b836c0 100644 (file)
@@ -15,10 +15,10 @@ Storage=persistent
 #SyncIntervalSec=5m
 #RateLimitInterval=30s
 #RateLimitBurst=1000
-SystemMaxUse=8M
+SystemMaxUse=4M
 #SystemKeepFree=
 #SystemMaxFileSize=
-RuntimeMaxUse=8M
+RuntimeMaxUse=4M
 #RuntimeKeepFree=
 #RuntimeMaxFileSize=
 #MaxRetentionSec=
index 0301751..f214ece 100644 (file)
@@ -1,4 +1,7 @@
+de
+el
 fr
+it
 pl
 ru
-it
+uk
diff --git a/po/de.po b/po/de.po
new file mode 100644 (file)
index 0000000..a41e33d
--- /dev/null
+++ b/po/de.po
@@ -0,0 +1,418 @@
+# German translation for systemd.
+# Copyright (C) 2014 systemd's COPYRIGHT HOLDER
+# This file is distributed under the same license as the systemd package.
+# Christian Kirbach <Christian.Kirbach@gmail.com>, 2014.
+# Benjamin Steinwender <b@stbe.at>, 2014.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: systemd master\n"
+"Report-Msgid-Bugs-To: https://bugs.freedesktop.org/enter_bug.cgi?"
+"product=systemd&keywords=I18N+L10N&component=general\n"
+"POT-Creation-Date: 2014-06-02 10:25+0000\n"
+"PO-Revision-Date: 2014-06-02 22:43+0100\n"
+"Last-Translator: Benjamin Steinwender <b@stbe.at>\n"
+"Language-Team: German <gnome-de@gnome.org>\n"
+"Language: de\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Poedit 1.6.5\n"
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:1
+msgid "Set host name"
+msgstr "Rechnername festlegen"
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:2
+msgid "Authentication is required to set the local host name."
+msgstr "Legitimierung ist zum Festlegen des lokalen Rechnernamens notwendig"
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:3
+msgid "Set static host name"
+msgstr "Statischen Rechnernamen festlegen"
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:4
+msgid ""
+"Authentication is required to set the statically configured local host name, "
+"as well as the pretty host name."
+msgstr ""
+"Authentifizierung ist erforderlich, um den statisch geänderten, lokalen "
+"Rechnernamen, sowie den beschönigten Rechnernamen festzulegen."
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:5
+msgid "Set machine information"
+msgstr "Maschinen-Information festlegen"
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:6
+msgid "Authentication is required to set local machine information."
+msgstr ""
+"Legitimierung ist zum Festlegen der lokalen Maschinen-Information "
+"erforderlich."
+
+#: ../src/locale/org.freedesktop.locale1.policy.in.h:1
+msgid "Set system locale"
+msgstr "Die lokale Sprachumgebung festlegen"
+
+#: ../src/locale/org.freedesktop.locale1.policy.in.h:2
+msgid "Authentication is required to set the system locale."
+msgstr ""
+"Legitimierung ist zum Festlegen der systemweiten Spracheinstellungen "
+"erforderlich."
+
+#: ../src/locale/org.freedesktop.locale1.policy.in.h:3
+msgid "Set system keyboard settings"
+msgstr "Tastatureinstellungen des Systems festlegen"
+
+#: ../src/locale/org.freedesktop.locale1.policy.in.h:4
+msgid "Authentication is required to set the system keyboard settings."
+msgstr ""
+"Legitimierung ist zum Festlegen der Tastatureinstellungen des Systems "
+"erforderlich."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:1
+msgid "Allow applications to inhibit system shutdown"
+msgstr "Anwendungen dürfen das Herunterfahren des Systems unterbinden"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:2
+msgid ""
+"Authentication is required to allow an application to inhibit system "
+"shutdown."
+msgstr ""
+"Legitimierung ist notwendig, um Anwendungen das Herunterfahren des Systems "
+"zu erlauben."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:3
+msgid "Allow applications to delay system shutdown"
+msgstr "Anwendungen dürfen das Herunterfahren des Systems verzögern"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:4
+msgid ""
+"Authentication is required to allow an application to delay system shutdown."
+msgstr ""
+"Legitimierung ist notwendig, um Anwendungen das Verzögern des Herunterfahren "
+"des Systems zu erlauben."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:5
+msgid "Allow applications to inhibit system sleep"
+msgstr "Anwendungen dürfen den Bereitschaftsmodus unterbinden"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:6
+msgid ""
+"Authentication is required to allow an application to inhibit system sleep."
+msgstr ""
+"Legitimierung ist erforderlich, um Anwendungen das Unterbinden des "
+"Bereitschaftsmodus zu erlauben."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:7
+msgid "Allow applications to delay system sleep"
+msgstr "Anwendungen dürfen den Bereitschaftsmodus verzögern"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:8
+msgid ""
+"Authentication is required to allow an application to delay system sleep."
+msgstr ""
+"Legitimierung ist erforderlich, um Anwendungen das Verzögern des "
+"Bereitschaftsmodus zu erlauben."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:9
+msgid "Allow applications to inhibit automatic system suspend"
+msgstr "Anwendungen dürfen den automatischen Bereitschaftsmodus unterbinden"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:10
+msgid ""
+"Authentication is required to allow an application to inhibit automatic "
+"system suspend."
+msgstr ""
+"Legitimierung ist notwendig, um Anwendungen das Unterbinden des "
+"automatischen Bereitschaftsmodus zu erlauben."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:11
+msgid "Allow applications to inhibit system handling of the power key"
+msgstr ""
+"Anwendungen dürfen das Auswerten des Ein-/Ausschaltknopfs des Systems "
+"unterbinden"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:12
+msgid ""
+"Authentication is required to allow an application to inhibit system "
+"handling of the power key."
+msgstr ""
+"Legitmierung ist erforderlich, um Anwendungen das Unterbinden der Auswertung "
+"der Ein-/Ausschaltknopfs des Systems zu erlauben."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:13
+msgid "Allow applications to inhibit system handling of the suspend key"
+msgstr ""
+"Anwendungen dürfen das Auswerten des Bereitschaftsknopfs des Systems "
+"unterbinden"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:14
+msgid ""
+"Authentication is required to allow an application to inhibit system "
+"handling of the suspend key."
+msgstr ""
+"Legitimierung ist erforderlich, um Anwendungen das Unterbinden der "
+"Auswertung des Bereitschaftsknopfes des Systems zu erlauben."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:15
+msgid "Allow applications to inhibit system handling of the hibernate key"
+msgstr ""
+"Anwendungen dürfen das Auswerten des Knopfs für den Ruhezustand unterbinden"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:16
+msgid ""
+"Authentication is required to allow an application to inhibit system "
+"handling of the hibernate key."
+msgstr ""
+"Legitimierung ist erforderlich, um Anwendungen das Unterbinden der "
+"Auswertung des Knopfs für den Ruhezustand zu erlauben."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:17
+msgid "Allow applications to inhibit system handling of the lid switch"
+msgstr ""
+"Anwendungen dürfen das Auswerten des Notebookdeckelschalters unterbinden"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:18
+msgid ""
+"Authentication is required to allow an application to inhibit system "
+"handling of the lid switch."
+msgstr ""
+"Legitimierung ist erforderlich, um Anwendungen das Unterbinden der "
+"Auswertung des Notebookdeckelschalters des Systems zu erlauben."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:19
+msgid "Allow non-logged-in users to run programs"
+msgstr "Nicht angemeldete Benutzer dürfen Programme ausführen"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:20
+msgid ""
+"Authentication is required to allow a non-logged-in user to run programs."
+msgstr ""
+"Legitimierung ist erforderlich, damit nicht angemeldete Benutzer Programme "
+"ausführen dürfen."
+
+# www.freedesktop.org/wiki/Software/systemd/multiseat/
+#: ../src/login/org.freedesktop.login1.policy.in.h:21
+msgid "Allow attaching devices to seats"
+msgstr "Das Anschließen von Geräten an Arbeitsstationen erlauben"
+
+# www.freedesktop.org/wiki/Software/systemd/multiseat/
+#: ../src/login/org.freedesktop.login1.policy.in.h:22
+msgid "Authentication is required for attaching a device to a seat."
+msgstr ""
+"Legitimierung ist zum Anschließen eines Geräts an eine Arbeitsstation "
+"notwendig."
+
+# www.freedesktop.org/wiki/Software/systemd/multiseat/
+#: ../src/login/org.freedesktop.login1.policy.in.h:23
+msgid "Flush device to seat attachments"
+msgstr "Zurücksetzen der an eine Arbeitsstation angeschlossenen Geräte"
+
+# www.freedesktop.org/wiki/Software/systemd/multiseat/
+#: ../src/login/org.freedesktop.login1.policy.in.h:24
+msgid ""
+"Authentication is required for resetting how devices are attached to seats."
+msgstr ""
+"Legitimierung ist zum Zurücksetzen notwendig, wie Geräte an eine "
+"Arbeitsstation angeschlossen werden."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:25
+msgid "Power off the system"
+msgstr "Das System ausschalten"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:26
+msgid "Authentication is required for powering off the system."
+msgstr "Legitimierung ist zum Ausschalten des Systems notwendig."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:27
+msgid "Power off the system while other users are logged in"
+msgstr "Das System herunter fahren, während andere Benutzer angemeldet sind"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:28
+msgid ""
+"Authentication is required for powering off the system while other users are "
+"logged in."
+msgstr ""
+"Legitimierung ist zum Herunterfahren des Systems notwendig, während andere "
+"Benutzer angemeldet sind."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:29
+msgid "Power off the system while an application asked to inhibit it"
+msgstr ""
+"Das System ausschalten, während eine Anwendung anfordert es zu unterbinden"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:30
+msgid ""
+"Authentication is required for powering off the system while an application "
+"asked to inhibit it."
+msgstr ""
+"Legitimierung ist zum Ausschalten des Systems notwendig, während eine "
+"Anwendung anfordert es zu unterbinden."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:31
+msgid "Reboot the system"
+msgstr "Das System neu starten"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:32
+msgid "Authentication is required for rebooting the system."
+msgstr "Legitimierung ist zum Neustart des Systems notwendig."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:33
+msgid "Reboot the system while other users are logged in"
+msgstr "Das Systems neu starten, während andere Benutzer angemeldet sind"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:34
+msgid ""
+"Authentication is required for rebooting the system while other users are "
+"logged in."
+msgstr ""
+"Legitimierung ist zum Neustart des Systems notwendig, während andere "
+"Benutzer angemeldet sind."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:35
+msgid "Reboot the system while an application asked to inhibit it"
+msgstr ""
+"Das System neu starten, während eine Anwendung anfordert es zu unterbinden"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:36
+msgid ""
+"Authentication is required for rebooting the system while an application "
+"asked to inhibit it."
+msgstr ""
+"Legitimierung ist zum Neustart des Systems notwendig, während eine Anwendung "
+"anforderte es zu unterbinden."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:37
+msgid "Suspend the system"
+msgstr "Das System in Bereitschaft versetzen"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:38
+msgid "Authentication is required for suspending the system."
+msgstr "Legitimierung ist zum Versetzen des Systems in Bereitschaft notwendig."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:39
+msgid "Suspend the system while other users are logged in"
+msgstr ""
+"Das System in Bereitschaft versetzen, während andere Benutzer angemeldet "
+"sind."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:40
+msgid ""
+"Authentication is required for suspending the system while other users are "
+"logged in."
+msgstr ""
+"Legitimierung ist zum Versetzen des Systems in Bereitschaft notwendig, "
+"während andere Benutzer angemeldet sind."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:41
+msgid "Suspend the system while an application asked to inhibit it"
+msgstr ""
+"Das System in Bereitschaft versetzen, während eine Anwendung anfordert dies "
+"zu unterbinden"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:42
+msgid ""
+"Authentication is required for suspending the system while an application "
+"asked to inhibit it."
+msgstr ""
+"Legitimierung ist zum Versetzen des Systems in Bereitschaft notwendig, "
+"während eine Anwendung anfordert dies zu unterbinden."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:43
+msgid "Hibernate the system"
+msgstr "Den Ruhezustand des Systems aktivieren"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:44
+msgid "Authentication is required for hibernating the system."
+msgstr ""
+"Legitimierung ist zum Aktivieren des Ruhezustands des Systems notwendig."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:45
+msgid "Hibernate the system while other users are logged in"
+msgstr ""
+"Den Ruhezustand des Systems aktivieren, während andere Benutzer angemeldet "
+"sind"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:46
+msgid ""
+"Authentication is required for hibernating the system while other users are "
+"logged in."
+msgstr ""
+"Legitimierung ist zum Aktivieren des Ruhezustands des Systems notwendig, "
+"während andere Benutzer angemeldet sind."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:47
+msgid "Hibernate the system while an application asked to inhibit it"
+msgstr ""
+"Das System in den Ruhezustand versetzen, während eine Anwendung wünscht dies "
+"zu verhindern"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:48
+msgid ""
+"Authentication is required for hibernating the system while an application "
+"asked to inhibit it."
+msgstr ""
+"Legitimierung ist zum Versetzen des System in den Ruhezustand notwendig, "
+"während eine Anwendung wünscht dies zu verhindern."
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:1
+msgid "Set system time"
+msgstr "Die Systemzeit festlegen"
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:2
+msgid "Authentication is required to set the system time."
+msgstr "Legitimierung ist zum Festlegen der Systemzeit notwendig."
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:3
+msgid "Set system timezone"
+msgstr "Die Systemzeitzone festlegen"
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:4
+msgid "Authentication is required to set the system timezone."
+msgstr "Legitimierung ist zum Festlegen der Systemzeitzone notwendig."
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:5
+msgid "Set RTC to local timezone or UTC"
+msgstr "Echtzeituhr auf lokale Zeitzone oder UTC setzen"
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:6
+msgid ""
+"Authentication is required to control whether the RTC stores the local or "
+"UTC time."
+msgstr ""
+"Legitimierung ist notwendig zum Festlegen, ob die Echtzeituhr auf lokale "
+"Zeitzone oder UTC eingestellt ist."
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:7
+msgid "Turn network time synchronization on or off"
+msgstr "Netzwerkzeitabgeich ein- oder ausschalten"
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:8
+msgid ""
+"Authentication is required to control whether network time synchronization "
+"shall be enabled."
+msgstr ""
+"Legitimierung ist zum Festlegen, ob Netzwerkzeitabgeich eingeschaltet sein "
+"soll, erforderlich."
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:1
+msgid "Send passphrase back to system"
+msgstr "Passphrase zurück an das System senden"
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:2
+msgid ""
+"Authentication is required to send the entered passphrase back to the system."
+msgstr ""
+"Legitimierung ist zum Senden des eingegebenen Kennworts zurück an das System "
+"notwendig."
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:3
+msgid "Privileged system and service manager access"
+msgstr "Privilegierter Zugriff auf die System- und Dienstverwaltung"
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:4
+msgid "Authentication is required to access the system and service manager."
+msgstr ""
+"Legitimierung ist notwendig für den Zugriff auf die System- und "
+"Dienstverwaltung."
diff --git a/po/el.po b/po/el.po
new file mode 100644 (file)
index 0000000..1570565
--- /dev/null
+++ b/po/el.po
@@ -0,0 +1,404 @@
+# Greek translation for systemd.
+# Copyright (C) 2014 systemd's COPYRIGHT HOLDER
+# This file is distributed under the same license as the systemd package.
+# Dimitris Spingos <dmtrs32@gmail.com>, 2014.
+# Dimitris Spingos (Δημήτρης Σπίγγος) <dmtrs32@gmail.com>, 2014.
+msgid ""
+msgstr ""
+"Project-Id-Version: systemd master\n"
+"Report-Msgid-Bugs-To: https://bugs.freedesktop.org/enter_bug.cgi?product=sys"
+"temd&keywords=I18N+L10N&component=general\n"
+"POT-Creation-Date: 2014-04-25 15:51+0000\n"
+"PO-Revision-Date: 2014-04-29 09:17+0300\n"
+"Last-Translator: Dimitris Spingos (Δημήτρης Σπίγγος) <dmtrs32@gmail.com>\n"
+"Language-Team: team@lists.gnome.gr\n"
+"Language: el\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Virtaal 0.7.0\n"
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:1
+msgid "Set host name"
+msgstr "Ορισμός ονόματος οικοδεσπότη"
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:2
+msgid "Authentication is required to set the local host name."
+msgstr "Απαιτείται πιστοποίηση για να ορίσετε τοπικά όνομα οικοδεσπότη."
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:3
+msgid "Set static host name"
+msgstr "Ορισμός στατικού ονόματος οικοδεσπότη"
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:4
+msgid ""
+"Authentication is required to set the statically configured local host name, "
+"as well as the pretty host name."
+msgstr ""
+"Απαιτείται πιστοποίηση για να ορίσετε το στατικά ρυθμισμένο όνομα τοπικού "
+"οικοδεσπότη, καθώς και το pretty όνομα οικοδεσπότη."
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:5
+msgid "Set machine information"
+msgstr "Ορισμός πληροφοριών μηχανής"
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:6
+msgid "Authentication is required to set local machine information."
+msgstr "Απαιτείται πιστοποίηση για να ορίσετε πληροφορίες τοπικής μηχανής."
+
+#: ../src/locale/org.freedesktop.locale1.policy.in.h:1
+msgid "Set system locale"
+msgstr "Ορισμός τοπικών ρυθμίσεων συστήματος"
+
+#: ../src/locale/org.freedesktop.locale1.policy.in.h:2
+msgid "Authentication is required to set the system locale."
+msgstr ""
+"Απαιτείται πιστοποίηση για να ορίσετε τις τοπικές ρυθμίσεις του συστήματος."
+
+#: ../src/locale/org.freedesktop.locale1.policy.in.h:3
+msgid "Set system keyboard settings"
+msgstr "Ορισμός ρυθμίσεων πληκτρολογίου συστήματος"
+
+#: ../src/locale/org.freedesktop.locale1.policy.in.h:4
+msgid "Authentication is required to set the system keyboard settings."
+msgstr ""
+"Απαιτείται πιστοποίηση για να ορίσετε τις ρυθμίσεις πληκτρολογίου του "
+"συστήματος."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:1
+msgid "Allow applications to inhibit system shutdown"
+msgstr ""
+"Να επιτρέπεται στις εφαρμογές να αποτρέπουν τον τερματισμό του συστήματος"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:2
+msgid ""
+"Authentication is required to allow an application to inhibit system "
+"shutdown."
+msgstr ""
+"Απαιτείται πιστοποίηση για να επιτρέπεται σε μια εφαρμογή να αποτρέψει τον "
+"τερματισμό του συστήματος."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:3
+msgid "Allow applications to delay system shutdown"
+msgstr ""
+"Να επιτρέπεται στις εφαρμογές να καθυστερούν τον τερματισμό του συστήματος"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:4
+msgid ""
+"Authentication is required to allow an application to delay system shutdown."
+msgstr ""
+"Απαιτείται πιστοποίηση για να επιτρέπεται σε μια εφαρμογή να καθυστερήσει "
+"τον τερματισμό του συστήματος."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:5
+msgid "Allow applications to inhibit system sleep"
+msgstr "Να επιτρέπεται στις εφαρμογές να αποτρέπουν την ύπνωση του συστήματος"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:6
+msgid ""
+"Authentication is required to allow an application to inhibit system sleep."
+msgstr ""
+"Απαιτείται πιστοποίηση για να επιτρέπεται σε μια εφαρμογή να αποτρέψει την "
+"ύπνωση του συστήματος."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:7
+msgid "Allow applications to delay system sleep"
+msgstr "Να επιτρέπεται στις εφαρμογές να καθυστερούν την ύπνωση του συστήματος"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:8
+msgid ""
+"Authentication is required to allow an application to delay system sleep."
+msgstr ""
+"Απαιτείται πιστοποίηση για να επιτρέπεται σε μια εφαρμογή να καθυστερήσει "
+"την ύπνωση του συστήματος."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:9
+msgid "Allow applications to inhibit automatic system suspend"
+msgstr ""
+"Να επιτρέπεται στις εφαρμογές να αποτρέπουν την αυτόματη αναστολή του "
+"συστήματος"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:10
+msgid ""
+"Authentication is required to allow an application to inhibit automatic "
+"system suspend."
+msgstr ""
+"Απαιτείται πιστοποίηση για να επιτρέπεται σε μια εφαρμογή να αποτρέψει την "
+"αυτόματη αναστολή του συστήματος."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:11
+msgid "Allow applications to inhibit system handling of the power key"
+msgstr ""
+"Να επιτρέπεται στις εφαρμογές να αποτρέπουν τη διαχείριση του πλήκτρου "
+"ενεργοποίησης του συστήματος"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:12
+msgid ""
+"Authentication is required to allow an application to inhibit system "
+"handling of the power key."
+msgstr ""
+"Απαιτείται πιστοποίηση για να επιτρέπεται σε μια εφαρμογή να αποτρέψει την "
+"διαχείριση του πλήκτρου ενεργοποίησης του συστήματος."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:13
+msgid "Allow applications to inhibit system handling of the suspend key"
+msgstr ""
+"Να επιτρέπεται στις εφαρμογές να αποτρέπουν τη διαχείριση του πλήκτρου "
+"αναστολής του συστήματος."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:14
+msgid ""
+"Authentication is required to allow an application to inhibit system "
+"handling of the suspend key."
+msgstr ""
+"Απαιτείται πιστοποίηση για να επιτρέπεται σε μια εφαρμογή να αποτρέψει την "
+"διαχείριση του πλήκτρου αναστολής του συστήματος."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:15
+msgid "Allow applications to inhibit system handling of the hibernate key"
+msgstr ""
+"Να επιτρέπεται στις εφαρμογές να αποτρέπουν τη διαχείριση του πλήκτρου "
+"αδρανοποίησης του συστήματος"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:16
+msgid ""
+"Authentication is required to allow an application to inhibit system "
+"handling of the hibernate key."
+msgstr ""
+"Απαιτείται πιστοποίηση για να επιτρέπεται σε μια εφαρμογή να αποτρέψει την "
+"διαχείριση του πλήκτρου αδρανοποίησης του συστήματος."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:17
+msgid "Allow applications to inhibit system handling of the lid switch"
+msgstr ""
+"Να επιτρέπεται στις εφαρμογές να αποτρέπουν τη διαχείριση του διακόπτη "
+"καλύμματος του συστήματος"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:18
+msgid ""
+"Authentication is required to allow an application to inhibit system "
+"handling of the lid switch."
+msgstr ""
+"Απαιτείται πιστοποίηση για να επιτρέπεται σε μια εφαρμογή να αποτρέψει την "
+"διαχείριση του διακόπτη καλύμματος του συστήματος."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:19
+msgid "Allow non-logged-in users to run programs"
+msgstr "Να επιτρέπεται σε μη συνδεμένους χρήστες να εκτελούν προγράμματα"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:20
+msgid ""
+"Authentication is required to allow a non-logged-in user to run programs."
+msgstr ""
+"Απαιτείται πιστοποίηση για να επιτρέπεται σε μη συνδεμένους χρήστες να "
+"εκτελούν προγράμματα."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:21
+msgid "Allow attaching devices to seats"
+msgstr "Να επιτρέπεται η προσάρτηση συσκευών στους σταθμούς εργασίας"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:22
+msgid "Authentication is required for attaching a device to a seat."
+msgstr ""
+"Απαιτείται πιστοποίηση για προσάρτηση μιας συσκευής σε έναν σταθμό εργασίας."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:23
+msgid "Flush device to seat attachments"
+msgstr "Αφαίρεση συσκευής από προσαρτήσεις σταθμού εργασίας"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:24
+msgid ""
+"Authentication is required for resetting how devices are attached to seats."
+msgstr ""
+"Απαιτείται πιστοποίηση για επαναφορά του τρόπου που οι συσκευές προσαρτώνται "
+"στους σταθμούς εργασίας."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:25
+msgid "Power off the system"
+msgstr "Σβήσιμο του συστήματος"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:26
+msgid "Authentication is required for powering off the system."
+msgstr "Απαιτείται πιστοποίηση για την σβήσιμο του συστήματος."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:27
+msgid "Power off the system while other users are logged in"
+msgstr "Σβήσιμο του συστήματος ενώ άλλοι χρήστες είναι συνδεμένοι"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:28
+msgid ""
+"Authentication is required for powering off the system while other users are "
+"logged in."
+msgstr ""
+"Απαιτείται πιστοποίηση για σβήσιμο του συστήματος ενώ άλλοι χρήστες είναι "
+"συνδεμένοι."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:29
+msgid "Power off the system while an application asked to inhibit it"
+msgstr "Απενεργοποίηση του συστήματος ενώ μια εφαρμογή ζήτησε να αποτραπεί."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:30
+msgid ""
+"Authentication is required for powering off the system while an application "
+"asked to inhibit it."
+msgstr ""
+"Απαιτείται πιστοποίηση για απενεργοποίηση του συστήματος ενώ μια εφαρμογή "
+"ζήτησε να αποτραπεί."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:31
+msgid "Reboot the system"
+msgstr "Επανεκκίνηση του συστήματος"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:32
+msgid "Authentication is required for rebooting the system."
+msgstr "Απαιτείται πιστοποίηση για επανεκκίνηση του συστήματος."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:33
+msgid "Reboot the system while other users are logged in"
+msgstr "Επανεκκίνηση του συστήματος ενώ άλλοι χρήστες είναι συνδεμένοι"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:34
+msgid ""
+"Authentication is required for rebooting the system while other users are "
+"logged in."
+msgstr ""
+"Απαιτείται πιστοποίηση για επανεκκίνηση του συστήματος ενώ άλλοι χρήστες "
+"είναι συνδεμένοι."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:35
+msgid "Reboot the system while an application asked to inhibit it"
+msgstr "Επανεκκίνηση του συστήματος ενώ μια εφαρμογή ζήτησε να αποτραπεί"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:36
+msgid ""
+"Authentication is required for rebooting the system while an application "
+"asked to inhibit it."
+msgstr ""
+"Απαιτείται πιστοποίηση για επανεκκίνηση του συστήματος ενώ μια εφαρμογή "
+"ζήτησε να αποτραπεί."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:37
+msgid "Suspend the system"
+msgstr "Αναστολή του συστήματος"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:38
+msgid "Authentication is required for suspending the system."
+msgstr "Απαιτείται πιστοποίηση για την αναστολή του συστήματος."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:39
+msgid "Suspend the system while other users are logged in"
+msgstr "Αναστολή του συστήματος ενώ άλλοι χρήστες είναι συνδεμένοι"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:40
+msgid ""
+"Authentication is required for suspending the system while other users are "
+"logged in."
+msgstr ""
+"Απαιτείται πιστοποίηση για αναστολή του συστήματος ενώ άλλοι χρήστες είναι "
+"συνδεμένοι."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:41
+msgid "Suspend the system while an application asked to inhibit it"
+msgstr "Αναστολή του συστήματος ενώ μια εφαρμογή ζήτησε να αποτραπεί"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:42
+msgid ""
+"Authentication is required for suspending the system while an application "
+"asked to inhibit it."
+msgstr ""
+"Απαιτείται πιστοποίηση για αναστολή του συστήματος ενώ μια εφαρμογή ζήτησε "
+"να αποτραπεί."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:43
+msgid "Hibernate the system"
+msgstr "Αδρανοποίηση του συτήματος"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:44
+msgid "Authentication is required for hibernating the system."
+msgstr "Απαιτείται πιστοποίηση για αδρανοποίηση του συστήματος."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:45
+msgid "Hibernate the system while other users are logged in"
+msgstr "Αδρανοποίηση του συστήματος ενώ άλλοι χρήστες είναι συνδεμένοι"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:46
+msgid ""
+"Authentication is required for hibernating the system while other users are "
+"logged in."
+msgstr ""
+"Απαιτείται πιστοποίηση για αδρανοποίηση του συστήματος ενώ άλλοι χρήστες "
+"είναι συνδεμένοι."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:47
+msgid "Hibernate the system while an application asked to inhibit it"
+msgstr "Αδρανοποίηση του συστήματος ενώ μια εφαρμογή ζήτησε να αποτραπεί"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:48
+msgid ""
+"Authentication is required for hibernating the system while an application "
+"asked to inhibit it."
+msgstr ""
+"Απαιτείται πιστοποίηση για αδρανοποίηση του συστήματος ενώ μια εφαρμογή "
+"ζήτησε να αποτραπεί."
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:1
+msgid "Set system time"
+msgstr "Ορισμός ώρας συστήματος"
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:2
+msgid "Authentication is required to set the system time."
+msgstr "Απαιτείται πιστοποίηση για να ορίσετε την ώρα του συστήματος."
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:3
+msgid "Set system timezone"
+msgstr "Ορισμός ζώνης ώρας συστήματος"
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:4
+msgid "Authentication is required to set the system timezone."
+msgstr "Απαιτείται πιστοποίηση για να ορίσετε την ώρα ζώνης του συστήματος."
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:5
+msgid "Set RTC to local timezone or UTC"
+msgstr "Ορισμός RTC στην τοπική ζώνη ώρας ή UTC"
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:6
+msgid ""
+"Authentication is required to control whether the RTC stores the local or "
+"UTC time."
+msgstr ""
+"Απαιτείται πιστοποίηση για να ελέγξετε αν το RTC αποθηκεύει την τοπική ή την "
+"ώρα UTC."
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:7
+msgid "Turn network time synchronization on or off"
+msgstr "Ενεργοποίηση/Απενεργοποίηση συγχρονισμού ώρας δικτύου"
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:8
+msgid ""
+"Authentication is required to control whether network time synchronization "
+"shall be enabled."
+msgstr ""
+"Απαιτείται πιστοποίηση για να ελέγξετε αν ο συγχρονισμός ώρας δικτύου θα "
+"ενεργοποιηθεί."
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:1
+msgid "Send passphrase back to system"
+msgstr "Αποστολή του συνθηματικού πίσω στο σύστημα"
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:2
+msgid ""
+"Authentication is required to send the entered passphrase back to the system."
+msgstr ""
+"Απαιτείται πιστοποίηση για αποστολή του εισερχόμενου συνθηματικού πίσω στο "
+"σύστημα."
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:3
+msgid "Privileged system and service manager access"
+msgstr "Προνομιούχος πρόσβαση διαχειριστή συστήματος και υπηρεσίας"
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:4
+msgid "Authentication is required to access the system and service manager."
+msgstr ""
+"Απαιτείται πιστοποίηση για να προσπελάσετε τον διαχειριστή συστήματος και "
+"υπηρεσιών."
diff --git a/po/uk.po b/po/uk.po
new file mode 100644 (file)
index 0000000..7a5212a
--- /dev/null
+++ b/po/uk.po
@@ -0,0 +1,377 @@
+# Ukrainian translation for systemd.
+# Copyright (C) 2014 systemd's COPYRIGHT HOLDER
+# This file is distributed under the same license as the systemd package.
+# Eugene Melnik <jeka7js@gmail.com>, 2014.
+# Daniel Korostil <ted.korostiled@gmail.com>, 2014.
+msgid ""
+msgstr ""
+"Project-Id-Version: systemd master\n"
+"Report-Msgid-Bugs-To: https://bugs.freedesktop.org/enter_bug.cgi?product=sys"
+"temd&keywords=I18N+L10N&component=general\n"
+"POT-Creation-Date: 2014-06-06 22:16+0000\n"
+"PO-Revision-Date: 2014-07-16 19:13+0300\n"
+"Last-Translator: Daniel Korostil <ted.korostiled@gmail.com>\n"
+"Language-Team: linux.org.ua\n"
+"Language: uk\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%"
+"10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+"X-Generator: Virtaal 0.7.1\n"
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:1
+msgid "Set host name"
+msgstr "Встановити назву вузла"
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:2
+msgid "Authentication is required to set the local host name."
+msgstr "Засвідчення потрібне, щоб встановити назву локального вузла."
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:3
+msgid "Set static host name"
+msgstr "Встановити статичну назву вузла"
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:4
+msgid ""
+"Authentication is required to set the statically configured local host name, "
+"as well as the pretty host name."
+msgstr ""
+"Засвідчення потрібне, щоб вказати статично налаштовану назву локального "
+"вузла, так само й форматовану."
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:5
+msgid "Set machine information"
+msgstr "Встановити інформацію про машину"
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:6
+msgid "Authentication is required to set local machine information."
+msgstr "Засвідчення потрібно, щоб вказати локальну інформацію про машини."
+
+#: ../src/locale/org.freedesktop.locale1.policy.in.h:1
+msgid "Set system locale"
+msgstr "Вказати системну локаль"
+
+#: ../src/locale/org.freedesktop.locale1.policy.in.h:2
+msgid "Authentication is required to set the system locale."
+msgstr "Засвідчення потрібно, щоб встановити системну локаль."
+
+#: ../src/locale/org.freedesktop.locale1.policy.in.h:3
+msgid "Set system keyboard settings"
+msgstr "Вказати налаштування системної клавіатури"
+
+#: ../src/locale/org.freedesktop.locale1.policy.in.h:4
+msgid "Authentication is required to set the system keyboard settings."
+msgstr "Засвідчення потрібно, щоб вказати налаштування системної клавіатури."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:1
+msgid "Allow applications to inhibit system shutdown"
+msgstr "Дозволити програмам перешкоджати вимкненню системи"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:2
+msgid ""
+"Authentication is required to allow an application to inhibit system "
+"shutdown."
+msgstr ""
+"Засвідчення потрібно, щоб дозволити програмам перешкоджати вимкненню системи."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:3
+msgid "Allow applications to delay system shutdown"
+msgstr "Дозволити програмам затримувати вимкнення системи"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:4
+msgid ""
+"Authentication is required to allow an application to delay system shutdown."
+msgstr ""
+"Засвідчення потрібно, щоб дозволити програмам затримувати вимкнення системи."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:5
+msgid "Allow applications to inhibit system sleep"
+msgstr "Дозволити програмам перешкоджати засинанню системи"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:6
+msgid ""
+"Authentication is required to allow an application to inhibit system sleep."
+msgstr ""
+"Засвідчення потрібно, щоб дозволити програмам перешкоджати засинанню системи."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:7
+msgid "Allow applications to delay system sleep"
+msgstr "Дозволити програмами затримувати засинання системи"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:8
+msgid ""
+"Authentication is required to allow an application to delay system sleep."
+msgstr ""
+"Засвідчення потрібно, щоб дозволити програмам затримувати засинання системи."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:9
+msgid "Allow applications to inhibit automatic system suspend"
+msgstr "Дозволити програмам перешкоджати автоматичному призупиненню системи"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:10
+msgid ""
+"Authentication is required to allow an application to inhibit automatic "
+"system suspend."
+msgstr ""
+"Засвідчення потрібно, щоб дозволити програмам перешкоджати автоматичному "
+"призупиненню системи."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:11
+msgid "Allow applications to inhibit system handling of the power key"
+msgstr "Дозволити програмам перешкоджати обробленню системою клавіші живлення"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:12
+msgid ""
+"Authentication is required to allow an application to inhibit system "
+"handling of the power key."
+msgstr ""
+"Засвідчення потрібно, щоб дозволити програмам перешкоджати обробленню "
+"системою клавіші живлення."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:13
+msgid "Allow applications to inhibit system handling of the suspend key"
+msgstr ""
+"Дозволити програмам перешкоджати обробленню системою клавіші призупинення"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:14
+msgid ""
+"Authentication is required to allow an application to inhibit system "
+"handling of the suspend key."
+msgstr ""
+"Засвідчення потрібно, щоб дозволити програмам перешкоджати обробленню "
+"системою клавіші призупинення."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:15
+msgid "Allow applications to inhibit system handling of the hibernate key"
+msgstr "Дозволити програмам перешкоджати обробленню системою клавіші присипання"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:16
+msgid ""
+"Authentication is required to allow an application to inhibit system "
+"handling of the hibernate key."
+msgstr ""
+"Засвідчення потрібно, щоб дозволити програмам перешкоджати обробленню "
+"системою клавіші присипання."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:17
+msgid "Allow applications to inhibit system handling of the lid switch"
+msgstr ""
+"Дозволити програмам перешкоджати обробленню системою клавіші перемикання "
+"кришки"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:18
+msgid ""
+"Authentication is required to allow an application to inhibit system "
+"handling of the lid switch."
+msgstr ""
+"Засвідчення потрібно, щоб дозволити програмам перешкоджати обробленню "
+"системою клавіші перемикання кришки."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:19
+msgid "Allow non-logged-in users to run programs"
+msgstr "Дозволити незареєстрованим користувачам запускати програми"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:20
+msgid ""
+"Authentication is required to allow a non-logged-in user to run programs."
+msgstr ""
+"Засвідчення потрібно, щоб дозволити незареєстрованим користувачам запускати "
+"програми."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:21
+msgid "Allow attaching devices to seats"
+msgstr "Дозволити під'єднання пристроїв до місць"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:22
+msgid "Authentication is required for attaching a device to a seat."
+msgstr "Засвідчення потрібно, щоб під'єднувати пристрої до місць."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:23
+msgid "Flush device to seat attachments"
+msgstr "Очисний пристрій для під'єднань до місця"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:24
+msgid ""
+"Authentication is required for resetting how devices are attached to seats."
+msgstr "Засвідчення потрібно, щоб перезапустити спосіб під'єднання до місць."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:25
+msgid "Power off the system"
+msgstr "Вимкнути систему"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:26
+msgid "Authentication is required for powering off the system."
+msgstr "Засвідчення потрібно, щоб вимкнути систему."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:27
+msgid "Power off the system while other users are logged in"
+msgstr "Вимикнути систему, коли інші користувачі ще в ній"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:28
+msgid ""
+"Authentication is required for powering off the system while other users are "
+"logged in."
+msgstr ""
+"Засвідчення потрібно, щоб вимкнути систему, коли інші користувачі в ній."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:29
+msgid "Power off the system while an application asked to inhibit it"
+msgstr "Вимкнути систему, коли програми намагаються першкодити цьому"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:30
+msgid ""
+"Authentication is required for powering off the system while an application "
+"asked to inhibit it."
+msgstr ""
+"Засвідчення потрібно, щоб вимкнути систему, коли програми намагаються "
+"першкодити цьому."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:31
+msgid "Reboot the system"
+msgstr "Перезавантажити систему"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:32
+msgid "Authentication is required for rebooting the system."
+msgstr "Для перезавантаження системи необхідна ідентифікація."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:33
+msgid "Reboot the system while other users are logged in"
+msgstr "Перезавантажити, якщо інщі користувачі в системі"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:34
+msgid ""
+"Authentication is required for rebooting the system while other users are "
+"logged in."
+msgstr ""
+"Засвідчення потрібно, щоб перезапустити систему, коли інші користувачі в "
+"ній."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:35
+msgid "Reboot the system while an application asked to inhibit it"
+msgstr "Перезапустити систему, коли програми намагаються першкодити цьому"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:36
+msgid ""
+"Authentication is required for rebooting the system while an application "
+"asked to inhibit it."
+msgstr ""
+"Засвідчення потрібно, щоб перезапустити систему, коли програми намагаються "
+"першкодити цьому."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:37
+msgid "Suspend the system"
+msgstr "Призупинити систему"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:38
+msgid "Authentication is required for suspending the system."
+msgstr "Засвідчення потрібно, щоб призупинити систему."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:39
+msgid "Suspend the system while other users are logged in"
+msgstr "Призупинити систему, коли інші користувачі в ній"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:40
+msgid ""
+"Authentication is required for suspending the system while other users are "
+"logged in."
+msgstr ""
+"Засвідчення потрібно, щоб призупинити систему, коли інші користувачі в ній."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:41
+msgid "Suspend the system while an application asked to inhibit it"
+msgstr "Призупинити систему, коли програми намагаються першкодити цьому"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:42
+msgid ""
+"Authentication is required for suspending the system while an application "
+"asked to inhibit it."
+msgstr ""
+"Засвідчення потрібно, щоб призупнити систему, коли програми намагаються "
+"першкодити цьому."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:43
+msgid "Hibernate the system"
+msgstr "Приспати систему"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:44
+msgid "Authentication is required for hibernating the system."
+msgstr "Засвідчення потрібно, щоб приспати систему."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:45
+msgid "Hibernate the system while other users are logged in"
+msgstr "Приспати систему, коли інші користувачі в ній"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:46
+msgid ""
+"Authentication is required for hibernating the system while other users are "
+"logged in."
+msgstr ""
+"Засвідчення потрібно, щоб присипання систему, коли інші користувачі в ній."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:47
+msgid "Hibernate the system while an application asked to inhibit it"
+msgstr "Приспати систему, коли програми намагаються першкодити цьому"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:48
+msgid ""
+"Authentication is required for hibernating the system while an application "
+"asked to inhibit it."
+msgstr ""
+"Засвідчення потрібно, щоб приспати систему, коли програми намагаються "
+"першкодити цьому."
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:1
+msgid "Set system time"
+msgstr "Вказати системний час"
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:2
+msgid "Authentication is required to set the system time."
+msgstr "Засвідчення потрібно, щоб вказати системний час."
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:3
+msgid "Set system timezone"
+msgstr "Вказати системний часовий пояс"
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:4
+msgid "Authentication is required to set the system timezone."
+msgstr "Засвідчення потрібно, щоб вказати системний часовий пояс."
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:5
+msgid "Set RTC to local timezone or UTC"
+msgstr "Вкажіть RTC для локального часового поясу або UTC"
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:6
+msgid ""
+"Authentication is required to control whether the RTC stores the local or "
+"UTC time."
+msgstr "Засвідчення потрібно, щоб контролювати, чи RTC зберігає час, чи UTC."
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:7
+msgid "Turn network time synchronization on or off"
+msgstr "Увімкнути або вимкнути синхронізування через мережу"
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:8
+msgid ""
+"Authentication is required to control whether network time synchronization "
+"shall be enabled."
+msgstr ""
+"Засвідчення потрібно, щоб контролювати, чи синхронізування часу через мережу "
+"запущено."
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:1
+msgid "Send passphrase back to system"
+msgstr "Надіслати пароль назад у систему"
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:2
+msgid ""
+"Authentication is required to send the entered passphrase back to the system."
+msgstr "Засвідчення потрібно, щоб надіслати введений пароль назад у систему."
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:3
+msgid "Privileged system and service manager access"
+msgstr "Привілейований доступ до менеджера системи і служб"
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:4
+msgid "Authentication is required to access the system and service manager."
+msgstr "Засвідчення потрібно, щоб доступитись до менеджера системи і служб."
index 3fd6e8a..4c300da 100644 (file)
@@ -2,18 +2,15 @@
 #
 # Enable autosuspend for qemu emulated usb hid devices
 
-# Note that there are buggy qemu versions which advertise remote
-# wakeup support but don't actually implement it correctly.  This
-# is the reason why we need a match for the serial number here.
-# The serial number "42" is used to tag the implementations where
+# Note that there are buggy qemu versions (0.13 & older) which
+# advertise remote wakeup support but don't actually implement
+# it correctly.  This is the reason why we need a match for the
+# serial number here.  Old, broken versions have serial "1".
+# It has been changed to "42" after fixing the bug to indicate
 # remote wakeup is working.
-ACTION=="add", SUBSYSTEM=="usb", ATTR{product}=="QEMU USB Mouse", ATTR{serial}=="42", TEST=="power/control", ATTR{power/control}="auto"
-ACTION=="add", SUBSYSTEM=="usb", ATTR{product}=="QEMU USB Tablet", ATTR{serial}=="42", TEST=="power/control", ATTR{power/control}="auto"
-ACTION=="add", SUBSYSTEM=="usb", ATTR{product}=="QEMU USB Keyboard", ATTR{serial}=="42", TEST=="power/control", ATTR{power/control}="auto"
-
-# Catch-all for Avocent HID devices. Keyed off interface in order to only
-# trigger on HID class devices.
-ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="0624", ATTR{bInterfaceClass}=="03", TEST=="../power/control", ATTR{../power/control}="auto"
+ACTION=="add", SUBSYSTEM=="usb", ATTR{product}=="QEMU USB Mouse", ATTR{serial}!="1", TEST=="power/control", ATTR{power/control}="auto"
+ACTION=="add", SUBSYSTEM=="usb", ATTR{product}=="QEMU USB Tablet", ATTR{serial}!="1", TEST=="power/control", ATTR{power/control}="auto"
+ACTION=="add", SUBSYSTEM=="usb", ATTR{product}=="QEMU USB Keyboard", ATTR{serial}!="1", TEST=="power/control", ATTR{power/control}="auto"
 
 # Dell DRAC 4
 ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="413c", ATTR{idProduct}=="2500", TEST=="power/control", ATTR{power/control}="auto"
index 679dfdf..2bf9c1e 100644 (file)
@@ -15,11 +15,15 @@ ACTION!="add", GOTO="default_permissions_end"
 SUBSYSTEM=="tty", KERNEL=="ptmx", GROUP="tty", MODE="0666"
 SUBSYSTEM=="tty", KERNEL=="tty", GROUP="tty", MODE="0666"
 SUBSYSTEM=="tty", KERNEL=="tty[0-9]*", GROUP="tty", MODE="0620"
+SUBSYSTEM=="tty", KERNEL=="sclp_line[0-9]*", GROUP="tty", MODE="0620"
+SUBSYSTEM=="tty", KERNEL=="ttysclp[0-9]*", GROUP="tty", MODE="0620"
+SUBSYSTEM=="tty", KERNEL=="3270/tty[0-9]*", GROUP="tty", MODE="0620"
 SUBSYSTEM=="vc", KERNEL=="vcs*|vcsa*", GROUP="tty"
 KERNEL=="tty[A-Z]*[0-9]|pppox[0-9]*|ircomm[0-9]*|noz[0-9]*|rfcomm[0-9]*", GROUP="dialout"
 
 SUBSYSTEM=="mem", KERNEL=="mem|kmem|port", GROUP="kmem", MODE="0640"
 
+SUBSYSTEM=="input", GROUP="input"
 SUBSYSTEM=="input", KERNEL=="js[0-9]*", MODE="0664"
 
 SUBSYSTEM=="video4linux", GROUP="video"
@@ -46,7 +50,6 @@ KERNEL=="irlpt[0-9]*", GROUP="lp"
 SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ENV{ID_USB_INTERFACES}=="*:0701??:*", GROUP="lp"
 
 SUBSYSTEM=="block", GROUP="disk"
-SUBSYSTEM=="block", KERNEL=="fd[0-9]", GROUP="floppy"
 SUBSYSTEM=="block", KERNEL=="sr[0-9]*", GROUP="cdrom"
 SUBSYSTEM=="scsi_generic", SUBSYSTEMS=="scsi", ATTRS{type}=="4|5", GROUP="cdrom"
 KERNEL=="sch[0-9]*", GROUP="cdrom"
@@ -56,6 +59,8 @@ KERNEL=="pktcdvd", GROUP="cdrom"
 SUBSYSTEM=="scsi_generic|scsi_tape", SUBSYSTEMS=="scsi", ATTRS{type}=="1|8", GROUP="tape"
 SUBSYSTEM=="scsi_generic", SUBSYSTEMS=="scsi", ATTRS{type}=="0", GROUP="disk"
 KERNEL=="qft[0-9]*|nqft[0-9]*|zqft[0-9]*|nzqft[0-9]*|rawqft[0-9]*|nrawqft[0-9]*", GROUP="disk"
+KERNEL=="loop-control", GROUP="disk", OPTIONS+="static_node=loop-control"
+KERNEL=="btrfs-control", GROUP="disk"
 KERNEL=="rawctl", GROUP="disk"
 SUBSYSTEM=="raw", KERNEL=="raw[0-9]*", GROUP="disk"
 SUBSYSTEM=="aoe", GROUP="disk", MODE="0220"
index 4e0f366..22f71e7 100644 (file)
@@ -1,6 +1,6 @@
 # do not edit this file, it will be overwritten on update
 
-ACTION!="add", GOTO="keyboard_end"
+ACTION=="remove", GOTO="keyboard_end"
 KERNEL!="event*", GOTO="keyboard_end"
 ENV{ID_INPUT_KEY}=="", GOTO="keyboard_end"
 
index 4f7163d..475b151 100644 (file)
@@ -84,4 +84,7 @@ ENV{DEVTYPE}=="partition", ENV{ID_WWN_WITH_EXTENSION}=="?*", SYMLINK+="disk/by-i
 ENV{ID_PART_ENTRY_SCHEME}=="gpt", ENV{ID_PART_ENTRY_UUID}=="?*", SYMLINK+="disk/by-partuuid/$env{ID_PART_ENTRY_UUID}"
 ENV{ID_PART_ENTRY_SCHEME}=="gpt", ENV{ID_PART_ENTRY_NAME}=="?*", SYMLINK+="disk/by-partlabel/$env{ID_PART_ENTRY_NAME}"
 
+# add symlink to GPT root disk
+ENV{ID_PART_ENTRY_SCHEME}=="gpt", ENV{ID_PART_GPT_AUTO_ROOT}=="1", SYMLINK+="gpt-auto-root"
+
 LABEL="persistent_storage_end"
index 021359a..aa435c4 100644 (file)
@@ -7,7 +7,7 @@
 
 ACTION=="remove", GOTO="systemd_end"
 
-SUBSYSTEM=="tty", KERNEL=="tty[a-zA-Z]*|hvc*|xvc*|hvsi*|ttysclp*|sclp_line*", TAG+="systemd"
+SUBSYSTEM=="tty", KERNEL=="tty[a-zA-Z]*|hvc*|xvc*|hvsi*|ttysclp*|sclp_line*|3270/tty[0-9]*", TAG+="systemd"
 
 KERNEL=="vport*", TAG+="systemd"
 
@@ -22,6 +22,9 @@ SUBSYSTEM=="block", KERNEL!="ram*", ENV{DM_UUID}=="CRYPT-*", ENV{ID_PART_TABLE_T
 SUBSYSTEM=="block", ENV{DEVTYPE}=="disk", KERNEL=="md*", TEST!="md/array_state", ENV{SYSTEMD_READY}="0"
 SUBSYSTEM=="block", ENV{DEVTYPE}=="disk", KERNEL=="md*", ATTR{md/array_state}=="|clear|inactive", ENV{SYSTEMD_READY}="0"
 
+# Ignore loop devices that don't have any file attached
+SUBSYSTEM=="block", KERNEL=="loop[0-9]*", ENV{DEVTYPE}=="disk", TEST!="loop/backing_file", ENV{SYSTEMD_READY}="0"
+
 # Ignore nbd devices in the "add" event, with "change" the nbd is ready
 ACTION=="add", SUBSYSTEM=="block", KERNEL=="nbd*", ENV{SYSTEMD_READY}="0"
 
@@ -40,7 +43,7 @@ SUBSYSTEM=="net", KERNEL!="lo", TAG+="systemd", ENV{SYSTEMD_ALIAS}+="/sys/subsys
 SUBSYSTEM=="bluetooth", TAG+="systemd", ENV{SYSTEMD_ALIAS}+="/sys/subsystem/bluetooth/devices/%k"
 
 SUBSYSTEM=="bluetooth", TAG+="systemd", ENV{SYSTEMD_WANTS}+="bluetooth.target"
-ENV{ID_SMARTCARD_READER}=="*?", TAG+="systemd", ENV{SYSTEMD_WANTS}+="smartcard.target"
+ENV{ID_SMARTCARD_READER}=="?*", TAG+="systemd", ENV{SYSTEMD_WANTS}+="smartcard.target"
 SUBSYSTEM=="sound", KERNEL=="card*", TAG+="systemd", ENV{SYSTEMD_WANTS}+="sound.target"
 
 SUBSYSTEM=="printer", TAG+="systemd", ENV{SYSTEMD_WANTS}+="printer.target"
diff --git a/shell-completion/Makefile b/shell-completion/Makefile
new file mode 120000 (symlink)
index 0000000..bd10475
--- /dev/null
@@ -0,0 +1 @@
+../src/Makefile
\ No newline at end of file
diff --git a/shell-completion/bash/.gitignore b/shell-completion/bash/.gitignore
new file mode 100644 (file)
index 0000000..016e09d
--- /dev/null
@@ -0,0 +1 @@
+/systemctl
index 06d5d93..49520e4 100644 (file)
@@ -31,12 +31,13 @@ __get_machines() {
 }
 
 __get_endpoints() {
+        local mode=$1
         local a b
-        busctl list --no-legend --no-pager | { while read a b; do echo " $a"; done; };
+        busctl $mode list --no-legend --no-pager | { while read a b; do echo " $a"; done; };
 }
 
 _busctl() {
-        local i verb comps
+        local i verb comps mode
         local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
         local -A OPTS=(
                [STANDALONE]='-h --help --version --no-pager --no-legend --system --user
@@ -44,6 +45,12 @@ _busctl() {
                       [ARG]='-H --host -M --machine --address --match'
         )
 
+        if __contains_word "--user" ${COMP_WORDS[*]}; then
+            mode=--user
+        else
+            mode=--system
+        fi
+
         if __contains_word "$prev" ${OPTS[ARG]}; then
                 case $prev in
                         --host|-H)
@@ -79,7 +86,7 @@ _busctl() {
         elif __contains_word "$verb" ${VERBS[STANDALONE]}; then
                 comps=''
         elif __contains_word "$verb" ${VERBS[ENDPOINT]}; then
-                comps=$( __get_endpoints )
+                comps=$( __get_endpoints $mode)
         fi
 
         COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
similarity index 90%
rename from shell-completion/bash/systemd-coredumpctl
rename to shell-completion/bash/coredumpctl
index 805e848..e23152d 100644 (file)
@@ -1,4 +1,4 @@
-# systemd-coredumpctl(1) completion                       -*- shell-script -*-
+# coredumpctl(1) completion                       -*- shell-script -*-
 #
 # This file is part of systemd.
 #
@@ -57,11 +57,11 @@ _coredumpctl() {
                 COMPREPLY=( $(compgen -W '${__journal_fields[*]}' -S= -- "$cur") )
                return 0
         elif [[ $cur = *=* ]]; then
-                mapfile -t field_vals < <(systemd-coredumpctl -F "${prev%=}" 2>/dev/null)
+                mapfile -t field_vals < <(coredumpctl -F "${prev%=}" 2>/dev/null)
                 COMPREPLY=( $(compgen -W '${field_vals[*]}' -- "${cur#=}") )
                 return 0
         elif [[ $prev = '=' ]]; then
-                mapfile -t field_vals < <(systemd-coredumpctl -F "${COMP_WORDS[COMP_CWORD-2]}" 2>/dev/null)
+                mapfile -t field_vals < <(coredumpctl -F "${COMP_WORDS[COMP_CWORD-2]}" 2>/dev/null)
                 comps=${field_vals[*]}
         else
                 for ((i=0; i <= COMP_CWORD; i++)); do
@@ -82,4 +82,4 @@ _coredumpctl() {
         return 0
 }
 
-complete -F _coredumpctl systemd-coredumpctl
+complete -F _coredumpctl coredumpctl
index 9c75da9..a5e3460 100644 (file)
@@ -38,7 +38,8 @@ _hostnamectl() {
         local -A VERBS=(
                 [STANDALONE]='status'
                      [ICONS]='set-icon-name'
-                      [NAME]='set-hostname'
+                      [NAME]='set-hostname set-deployment'
+                   [CHASSIS]='set-chassis'
         )
 
         for ((i=0; i < COMP_CWORD; i++)); do
@@ -50,6 +51,8 @@ _hostnamectl() {
 
         if [[ -z $verb ]]; then
                 comps=${VERBS[*]}
+        elif __contains_word "$verb" ${VERBS[CHASSIS]}; then
+                comps='desktop laptop server tablet handset watch vm container'
         elif __contains_word "$verb" ${VERBS[STANDALONE]} ${VERBS[ICONS]} ${VERBS[NAME]}; then
                 comps=''
         fi
index e4b2f4a..14dcd22 100644 (file)
@@ -35,6 +35,8 @@ __journal_fields=(MESSAGE{,_ID} PRIORITY CODE_{FILE,LINE,FUNC}
                   _UDEV_{SYSNAME,DEVNODE,DEVLINK}
                   __CURSOR __{REALTIME,MONOTONIC}_TIMESTAMP)
 
+__syslog_priorities=(emerg alert crit err warning notice info debug)
+
 _journalctl() {
         local field_vals= cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
         local -A OPTS=(
@@ -44,8 +46,8 @@ _journalctl() {
                               --no-tail -q --quiet --setup-keys --this-boot --verify
                               --version --list-catalog --update-catalog --list-boots'
                        [ARG]='-b --boot --this-boot -D --directory --file -F --field
-                              -o --output -u --unit --user-unit'
-                [ARGUNKNOWN]='-c --cursor --interval -n --lines -p --priority --since --until
+                              -o --output -u --unit --user-unit -p --priority'
+                [ARGUNKNOWN]='-c --cursor --interval -n --lines --since --until
                               --verify-key'
         )
 
@@ -68,6 +70,9 @@ _journalctl() {
                         --field|-F)
                                 comps=${__journal_fields[*]}
                         ;;
+                        --priority|-p)
+                                comps=${__syslog_priorities[*]}
+                        ;;
                         --unit|-u)
                                 comps=$(journalctl -F '_SYSTEMD_UNIT' 2>/dev/null)
                         ;;
similarity index 88%
rename from shell-completion/bash/systemctl
rename to shell-completion/bash/systemctl.in
index dc7ef66..64b15df 100644 (file)
@@ -24,8 +24,8 @@ __systemctl() {
 
 __systemd_properties() {
         local mode=$1
-        { __systemctl -a $mode show;
-         systemd --dump-configuration-items; } |
+        { __systemctl $mode show --all;
+         @rootlibexecdir@/systemd --dump-configuration-items; } |
         while IFS='=' read -r key value; do
             [[ $value ]] && echo "$key"
         done
@@ -51,12 +51,14 @@ __filter_units_by_property () {
         done
 }
 
-__get_all_units      () { __systemctl $1 list-units --all \
+__get_all_units      () { { __systemctl $1 list-unit-files; __systemctl $1 list-units --all; } \
         | { while read -r a b; do echo " $a"; done; }; }
 __get_active_units   () { __systemctl $1 list-units       \
         | { while read -r a b; do echo " $a"; done; }; }
-__get_startable_units () { __systemctl $1 list-units --all -t service,timer,socket,mount,automount,path,snapshot,swap \
-        | { while read -r a b c d; do [[ $c == "inactive" || $c == "failed " ]] && echo " $a"; done; }; }
+__get_startable_units () { {
+        __systemctl $1 list-units --all -t service,timer,socket,mount,automount,path,snapshot,swap
+        __systemctl $1 list-unit-files -t service,timer,socket,mount,automount,path,snapshot,swap; } \
+        | { while read -r a b c d; do [[ $c == "inactive" || $c == "failed" ]] && echo " $a"; done; }; }
 __get_failed_units   () { __systemctl $1 list-units       \
         | { while read -r a b c d; do [[ $c == "failed"   ]] && echo " $a"; done; }; }
 __get_enabled_units  () { __systemctl $1 list-unit-files  \
@@ -73,8 +75,8 @@ _systemctl () {
         local -A OPTS=(
                [STANDALONE]='--all -a --reverse --after --before --defaults --fail --ignore-dependencies --failed --force -f --full -l --global
                              --help -h --no-ask-password --no-block --no-legend --no-pager --no-reload --no-wall
-                             --quiet -q --privileged -P --system --user --version --runtime'
-                      [ARG]='--host -H --kill-mode --kill-who --property -p --signal -s --type -t --state --root'
+                             --quiet -q --privileged -P --system --user --version --runtime --recursive -r'
+                      [ARG]='--host -H --kill-who --property -p --signal -s --type -t --state --root'
         )
 
         if __contains_word "--user" ${COMP_WORDS[*]}; then
@@ -89,7 +91,7 @@ _systemctl () {
                                 comps=$(compgen -A signal)
                         ;;
                         --type|-t)
-                                comps='automount device mount path service snapshot socket swap target timer'
+                                comps='automount busname device mount path service snapshot socket swap target timer'
                         ;;
                         --state)
                                 comps='loaded not-found stub
@@ -99,9 +101,6 @@ _systemctl () {
                         --kill-who)
                                 comps='all control main'
                         ;;
-                        --kill-mode)
-                                comps='control-group process'
-                        ;;
                         --root)
                                 comps=$(compgen -A directory -- "$cur" )
                                 compopt -o filenames
@@ -159,20 +158,25 @@ _systemctl () {
 
         elif __contains_word "$verb" ${VERBS[ALL_UNITS]}; then
                 comps=$( __get_all_units $mode )
+                compopt -o filenames
 
         elif __contains_word "$verb" ${VERBS[ENABLED_UNITS]}; then
                 comps=$( __get_enabled_units $mode )
+                compopt -o filenames
 
         elif __contains_word "$verb" ${VERBS[DISABLED_UNITS]}; then
                 comps=$( __get_disabled_units $mode )
+                compopt -o filenames
 
         elif __contains_word "$verb" ${VERBS[REENABLABLE_UNITS]}; then
                 comps=$( __get_disabled_units $mode;
                          __get_enabled_units $mode )
+                compopt -o filenames
 
         elif __contains_word "$verb" ${VERBS[STARTABLE_UNITS]}; then
                 comps=$( __filter_units_by_property $mode CanStart yes \
                       $( __get_startable_units $mode))
+                compopt -o filenames
 
         elif __contains_word "$verb" ${VERBS[RESTARTABLE_UNITS]}; then
                 comps=$( __filter_units_by_property $mode CanStart yes \
@@ -180,24 +184,30 @@ _systemctl () {
                         | while read -r line; do \
                                 [[ "$line" =~ \.(device|snapshot|socket|timer)$ ]] || echo " $line"; \
                         done ))
+                compopt -o filenames
 
         elif __contains_word "$verb" ${VERBS[STOPPABLE_UNITS]}; then
                 comps=$( __filter_units_by_property $mode CanStop yes \
                       $( __get_active_units $mode ) )
+                compopt -o filenames
 
         elif __contains_word "$verb" ${VERBS[RELOADABLE_UNITS]}; then
                 comps=$( __filter_units_by_property $mode CanReload yes \
                       $( __get_active_units $mode ) )
+                compopt -o filenames
 
         elif __contains_word "$verb" ${VERBS[ISOLATABLE_UNITS]}; then
                 comps=$( __filter_units_by_property $mode AllowIsolate yes \
                       $( __get_all_units $mode ) )
+                compopt -o filenames
 
         elif __contains_word "$verb" ${VERBS[FAILED_UNITS]}; then
                 comps=$( __get_failed_units $mode )
+                compopt -o filenames
 
         elif __contains_word "$verb" ${VERBS[MASKED_UNITS]}; then
                 comps=$( __get_masked_units $mode )
+                compopt -o filenames
 
         elif __contains_word "$verb" ${VERBS[STANDALONE]} ${VERBS[NAME]}; then
                 comps=''
@@ -222,7 +232,7 @@ _systemctl () {
                         | { while read -r a b; do echo " $a"; done; } )
         fi
 
-        COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+        COMPREPLY=( $(compgen -o filenames -W '$comps' -- "$cur") )
         return 0
 }
 
index 6afcd96..77d1b54 100644 (file)
@@ -25,16 +25,26 @@ __contains_word () {
         done
 }
 
+__get_machines() {
+        local a b
+        machinectl list --no-legend --no-pager | { while read a b; do echo " $a"; done; };
+}
+
 _systemd_analyze() {
         local i verb comps
         local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
-        local OPTS='--help --version --system --user --from-pattern --to-pattern --order --require'
+
+        local -A OPTS=(
+               [STANDALONE]='--help --version --system --user --from-pattern --to-pattern --order --require --no-pager'
+                      [ARG]='-H --host -M --machine'
+        )
 
         local -A VERBS=(
                 [STANDALONE]='time blame plot dump'
                 [CRITICAL_CHAIN]='critical-chain'
                 [DOT]='dot'
                 [LOG_LEVEL]='set-log-level'
+                [VERIFY]='verify'
         )
 
         _init_completion || return
@@ -47,6 +57,19 @@ _systemd_analyze() {
                 fi
         done
 
+        if __contains_word "$prev" ${OPTS[ARG]}; then
+                case $prev in
+                        --host|-H)
+                                comps=$(compgen -A hostname)
+                        ;;
+                        --machine|-M)
+                                comps=$( __get_machines )
+                        ;;
+                esac
+                COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+                return 0
+        fi
+
         if [[ -z $verb  && $cur = -* ]]; then
                 COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
                 return 0
@@ -77,6 +100,14 @@ _systemd_analyze() {
                         comps='debug info notice warning err crit alert emerg'
                 fi
 
+        elif __contains_word "$verb" ${VERBS[VERIFY]}; then
+                if [[ $cur = -* ]]; then
+                        comps='--help --version --system --user --no-man'
+                else
+                        comps=$( compgen -A file -- "$cur" )
+                        compopt -o filenames
+                fi
+
         fi
 
         COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
diff --git a/shell-completion/bash/systemd-cat b/shell-completion/bash/systemd-cat
new file mode 100644 (file)
index 0000000..8d84042
--- /dev/null
@@ -0,0 +1,57 @@
+# systemd-cat(1) completion                  -*- shell-script -*-
+#
+# This file is part of systemd.
+#
+# Copyright 2014 Thomas H.P. Andersen
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
+__contains_word() {
+        local w word=$1; shift
+        for w in "$@"; do
+                [[ $w = "$word" ]] && return
+        done
+}
+
+_systemd_cat() {
+        local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
+        local i verb comps
+
+        local -A OPTS=(
+               [STANDALONE]='-h --help --version'
+                      [ARG]='-t --identifier -p --priority --level-prefix'
+        )
+
+        _init_completion || return
+
+        if __contains_word "$prev" ${OPTS[ARG]}; then
+                case $prev in
+                        --identifier|-t)
+                                comps=''
+                        ;;
+                        --priority|-p)
+                                comps='emerg alert crit err warning notice info debug'
+                        ;;
+                        --level-prefix)
+                                comps='yes no'
+                        ;;
+                esac
+                COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+                return 0
+        fi
+
+        COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+}
+
+complete -F _systemd_cat systemd-cat
diff --git a/shell-completion/bash/systemd-cgls b/shell-completion/bash/systemd-cgls
new file mode 100644 (file)
index 0000000..0570438
--- /dev/null
@@ -0,0 +1,56 @@
+# systemd-cgls(1) completion                  -*- shell-script -*-
+#
+# This file is part of systemd.
+#
+# Copyright 2014 Thomas H.P. Andersen
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
+__contains_word() {
+        local w word=$1; shift
+        for w in "$@"; do
+                [[ $w = "$word" ]] && return
+        done
+}
+
+__get_machines() {
+        local a b
+        machinectl list --no-legend --no-pager | { while read a b; do echo " $a"; done; };
+}
+
+_systemd_cgls() {
+        local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
+        local i verb comps
+
+        local -A OPTS=(
+               [STANDALONE]='-h --help --version --all -l --full -k --no-pager'
+                      [ARG]='-M --machine'
+        )
+
+        _init_completion || return
+
+        if __contains_word "$prev" ${OPTS[ARG]}; then
+                case $prev in
+                        --machine|-M)
+                                comps=$( __get_machines )
+                        ;;
+                esac
+                COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+                return 0
+        fi
+
+        COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+}
+
+complete -F _systemd_cgls systemd-cgls
diff --git a/shell-completion/bash/systemd-cgtop b/shell-completion/bash/systemd-cgtop
new file mode 100644 (file)
index 0000000..d7ea42d
--- /dev/null
@@ -0,0 +1,40 @@
+# systemd-cgtop(1) completion                  -*- shell-script -*-
+#
+# This file is part of systemd.
+#
+# Copyright 2014 Thomas H.P. Andersen
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
+__contains_word() {
+        local w word=$1; shift
+        for w in "$@"; do
+                [[ $w = "$word" ]] && return
+        done
+}
+
+_systemd_cgtop() {
+        local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
+        local comps
+
+        local -A OPTS=(
+               [STANDALONE]='-h --help --version -p -t -c -m -i -b --batch -n --iterations -d --delay'
+        )
+
+        _init_completion || return
+
+        COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+}
+
+complete -F _systemd_cgtop systemd-cgtop
diff --git a/shell-completion/bash/systemd-detect-virt b/shell-completion/bash/systemd-detect-virt
new file mode 100644 (file)
index 0000000..df06c29
--- /dev/null
@@ -0,0 +1,40 @@
+# systemd-detect-virt(1) completion             -*- shell-script -*-
+#
+# This file is part of systemd.
+#
+# Copyright 2014 Thomas H.P. Andersen
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
+__contains_word() {
+        local w word=$1; shift
+        for w in "$@"; do
+                [[ $w = "$word" ]] && return
+        done
+}
+
+_systemd_detect_virt() {
+        local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
+        local i verb comps
+
+        local -A OPTS=(
+               [STANDALONE]='-h --help --version -c --container -v --vm -q --quiet'
+        )
+
+        _init_completion || return
+
+        COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+}
+
+complete -F _systemd_detect_virt systemd-detect-virt
diff --git a/shell-completion/bash/systemd-nspawn b/shell-completion/bash/systemd-nspawn
new file mode 100644 (file)
index 0000000..f911d1b
--- /dev/null
@@ -0,0 +1,115 @@
+# systemd-nspawn(1) completion                  -*- shell-script -*-
+#
+# This file is part of systemd.
+#
+# Copyright 2014 Thomas H.P. Andersen
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
+__contains_word() {
+        local w word=$1; shift
+        for w in "$@"; do
+                [[ $w = "$word" ]] && return
+        done
+}
+
+__get_users() {
+        local a b
+        loginctl list-users --no-legend --no-pager | { while read a b; do echo " $b"; done; };
+}
+
+__get_slices() {
+        local a b
+        systemctl list-units -t slice --no-legend --no-pager | { while read a b; do echo " $a"; done; };
+}
+
+_systemd_nspawn() {
+        local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
+        local i verb comps
+
+        local -A OPTS=(
+               [STANDALONE]='-h --help --version --private-network -b --boot --read-only -q --quiet --share-system --keep-unit --network-veth -j'
+                      [ARG]='-D --directory -u --user --uuid --capability --drop-capability --link-journal --bind --bind-ro -M --machine
+                             -S --slice --setenv -Z --selinux-context -L --selinux-apifs-context --register --network-interface --network-bridge
+                             --personality -i --image'
+        )
+
+        _init_completion || return
+
+        if __contains_word "$prev" ${OPTS[ARG]}; then
+                case $prev in
+                        --directory|-D)
+                                comps=$(compgen -A directory -- "$cur" )
+                        ;;
+                        --user|-u)
+                                comps=$( __get_users )
+                        ;;
+                        --uuid)
+                                comps=''
+                        ;;
+                        --capability)
+                                comps='CAP_BLOCK_SUSPEND CAP_IPC_LOCK CAP_MAC_ADMIN CAP_MAC_OVERRIDE CAP_SYS_MODULE CAP_SYS_PACCT CAP_SYS_RAWIO
+                                       CAP_SYS_TIME CAP_SYSLOG CAP_WAKE_ALARM CAP_NET_ADMIN'
+                        ;;
+                        --drop-capability)
+                                comps='CAP_AUDIT_CONTROL CAP_AUDIT_WRITE CAP_CHOWN CAP_DAC_OVERRIDE CAP_DAC_READ_SEARCH CAP_FOWNER CAP_FSETID
+                                       CAP_IPC_OWNER CAP_KILL CAP_LEASE CAP_LINUX_IMMUTABLE CAP_MKNOD CAP_NET_ADMIN CAP_NET_BIND_SERVICE
+                                       CAP_NET_BROADCAST CAP_NET_RAW CAP_SETFCAP CAP_SETGID CAP_SETPCAP CAP_SETUID CAP_SYS_ADMIN CAP_SYS_BOOT
+                                       CAP_SYS_CHROOT CAP_SYS_NICE CAP_SYS_PTRACE CAP_SYS_RESOURCE CAP_SYS_TTY_CONFIG'
+                        ;;
+                        --link-journal)
+                                comps='no auto guest host'
+                        ;;
+                        --bind|--bind-ro)
+                                comps=''
+                        ;;
+                        --machine|-M)
+                                comps=''
+                        ;;
+                        --slice|-S)
+                                comps=$( __get_slices )
+                        ;;
+                        --setenv)
+                                comps=''
+                        ;;
+                        --selinux-context|-Z)
+                                comps=''
+                        ;;
+                        --selinux-apifs-context|-L)
+                                comps=''
+                        ;;
+                        --register)
+                                comps='yes no'
+                        ;;
+                        --network-interface)
+                                comps=''
+                        ;;
+                        --network-bridge)
+                                comps=''
+                        ;;
+                        --personality)
+                                comps='x86 x86-64'
+                        ;;
+                        --image|-i)
+                                comps=$( compgen -A file -- "$cur" )
+                        ;;
+                esac
+                COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+                return 0
+        fi
+
+        COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
+}
+
+complete -F _systemd_nspawn systemd-nspawn
index ab55274..712655c 100644 (file)
@@ -25,9 +25,16 @@ __systemctl() {
 __get_slice_units () { __systemctl $1 list-units --all -t slice \
         | { while read -r a b c d; do echo " $a"; done; }; }
 
+__get_machines() {
+        local a b
+        machinectl list --no-legend --no-pager | { while read a b; do echo " $a"; done; };
+}
+
 _systemd_run() {
     local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
-    local OPTS='-h --help --version --user --scope --unit --description --slice -r --remain-after-exit --send-sighup'
+    local OPTS='-h --help --version --user --system --scope --unit --description --slice
+                -r --remain-after-exit --send-sighup -H --host -M --machine --service-type
+                --uid --gid --nice --setenv -p --property'
 
     local mode=--system
     local i
@@ -40,7 +47,7 @@ _systemd_run() {
 
         [[ ${COMP_WORDS[i]} == "--user" ]] && mode=--user
 
-        [[ $i -lt $COMP_CWORD && ${COMP_WORDS[i]} == @(--unit|--description|--slice) ]] && ((i++))
+        [[ $i -lt $COMP_CWORD && ${COMP_WORDS[i]} == @(--unit|--description|--slice|--service-type|-H|--host|-M|--machine|-p|--property) ]] && ((i++))
     done
 
     case "$prev" in
@@ -54,6 +61,37 @@ _systemd_run() {
             COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
             return 0
             ;;
+        --service-type)
+            local comps='simple forking oneshot dbus notify idle'
+
+            COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+            return 0
+            ;;
+        -p|--property)
+            local comps='CPUAccounting= MemoryAccounting= BlockIOAccounting= SendSIGHUP=
+                         SendSIGKILL= MemoryLimit= CPUShares= BlockIOWeight= User= Group=
+                         DevicePolicy= KillMode= DeviceAllow= BlockIOReadBandwidth=
+                         BlockIOWriteBandwidth= BlockIODeviceWeight= Nice= Environment=
+                         KillSignal= LimitCPU= LimitFSIZE= LimitDATA= LimitSTACK=
+                         LimitCORE= LimitRSS= LimitNOFILE= LimitAS= LimitNPROC=
+                         LimitMEMLOCK= LimitLOCKS= LimitSIGPENDING= LimitMSGQUEUE=
+                         LimitNICE= LimitRTPRIO= LimitRTTIME='
+
+            COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+            return 0
+            ;;
+        -H|--host)
+            local comps=$(compgen -A hostname)
+
+            COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+            return 0
+            ;;
+        -M|--machine)
+            local comps=$( __get_machines )
+
+            COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
+            return 0
+            ;;
     esac
 
     COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
diff --git a/shell-completion/zsh/.gitignore b/shell-completion/zsh/.gitignore
new file mode 100644 (file)
index 0000000..75f13ad
--- /dev/null
@@ -0,0 +1 @@
+/_systemctl
index 7c01564..fb18413 100644 (file)
@@ -43,12 +43,15 @@ _arguments \
     {-h,--help}'[Prints a short help text and exits.]' \
     '--version[Prints a short version string and exits.]' \
     '--no-pager[Do not pipe output into a pager]' \
+    '--no-legend[Do not show the headers and footers]' \
     '--system[Connect to system manager]' \
     '--user[Connect to user service manager]' \
     {-H+,--host=}'[Operate on remote host]:userathost:_sd_hosts_or_user_at_host' \
     {-M+,--machine=}'[Operate on local container]:machines:_sd_machines' \
     '--address=[Connect to the bus specified by address]:address' \
-    '--no-unique[Only show well-known names]' \
-    '--no-machine[Do not show machine IDs]' \
+    '--show-machine[Show machine ID column in list]' \
+    '--unique[Only show unique names]' \
+    '--acquired[Only show acquired names]' \
+    '--activatable[Only show activatable names]' \
     '--match=[Only show matching messages]:match' \
     '*::busctl command:_busctl_command'
similarity index 54%
rename from shell-completion/zsh/_systemd-coredumpctl
rename to shell-completion/zsh/_coredumpctl
index 94b1e92..d13bc70 100644 (file)
@@ -1,21 +1,21 @@
-#compdef systemd-coredumpctl
+#compdef coredumpctl
 
-_systemd-coredumpctl_command(){
-    local -a _systemd_coredumpctl_cmds
-    _systemd_coredumpctl_cmds=(
+_coredumpctl_command(){
+    local -a _coredumpctl_cmds
+    _coredumpctl_cmds=(
             'list:List available coredumps'
             'dump:Print coredump to stdout'
             'gdb:Start gdb on a coredump'
     )
     if (( CURRENT == 1 )); then
-        _describe -t commands 'systemd-coredumpctl command' _systemd_coredumpctl_cmds
+        _describe -t commands 'coredumpctl command' _coredumpctl_cmds
     else
         local curcontext="$curcontext"
         local -a _dumps
-        cmd="${${_systemd_coredumpctl_cmds[(r)$words[1]:*]%%:*}}"
+        cmd="${${_coredumpctl_cmds[(r)$words[1]:*]%%:*}}"
         if (( $#cmd  )); then
-            # user can set zstyle ':completion:*:*:systemd-coredumpctl:*' sort no for coredumps to be ordered by date, otherwise they get ordered by pid
-            _dumps=( "${(foa)$(systemd-coredumpctl list | awk 'BEGIN{OFS=":"} /^\s/ {sub(/[[ \t]+/, ""); print $5,$0}' 2>/dev/null)}" )
+            # user can set zstyle ':completion:*:*:coredumpctl:*' sort no for coredumps to be ordered by date, otherwise they get ordered by pid
+            _dumps=( "${(foa)$(coredumpctl list | awk 'BEGIN{OFS=":"} /^\s/ {sub(/[[ \t]+/, ""); print $5,$0}' 2>/dev/null)}" )
             if [[ -n "$_dumps" ]]; then
                 _describe -t pids 'coredumps' _dumps
             else
@@ -33,4 +33,4 @@ _arguments \
     '--no-pager[Do not pipe output into a pager]' \
     {-h,--help}'[Show this help]' \
     '--version[Show package version]' \
-    '*::systemd-coredumpctl commands:_systemd-coredumpctl_command'
+    '*::coredumpctl commands:_coredumpctl_command'
index 45b9597..e02f6de 100644 (file)
@@ -1,11 +1,46 @@
 #compdef hostnamectl
 
+_hostnamectl_set-hostname() {
+    if (( CURRENT <= 3 )); then
+        _message "new hostname"
+    else
+        _message "no more options"
+    fi
+}
+
+_hostnamectl_set-icon-name() {
+    if (( CURRENT <= 3 )); then
+        _message "new icon name"
+    else
+        _message "no more options"
+    fi
+}
+
+_hostnamectl_set-chassis() {
+    if (( CURRENT <= 3 )); then
+        _chassis=( desktop laptop server tablet handset watch vm container )
+        _describe chassis _chassis
+    else
+        _message "no more options"
+    fi
+}
+
+_hostnamectl_set-deployment() {
+    if (( CURRENT <= 3 )); then
+        _message "new environment"
+    else
+        _message "no more options"
+    fi
+}
+
 _hostnamectl_command() {
     local -a _hostnamectl_cmds
     _hostnamectl_cmds=(
         "status:Show current hostname settings"
         "set-hostname:Set system hostname"
         "set-icon-name:Set icon name for host"
+        "set-chassis:Set chassis type for host"
+        "set-deployment:Set deployment environment"
     )
     if (( CURRENT == 1 )); then
         _describe -t commands 'hostnamectl commands' _hostnamectl_cmds || compadd "$@"
@@ -13,8 +48,11 @@ _hostnamectl_command() {
         local curcontext="$curcontext"
         cmd="${${_hostnamectl_cmds[(r)$words[1]:*]%%:*}}"
         if (( $#cmd )); then
-            [[ $cmd == status ]] && msg="no options" || msg="options for $cmd"
-            _message "$msg"
+            if [[ $cmd == status ]]; then
+                _message "no options"
+            else
+                _hostnamectl_$cmd
+            fi
         else
             _message "unknown hostnamectl command: $words[1]"
         fi
index c04f4f3..d8af4d1 100644 (file)
@@ -22,8 +22,8 @@ _localectl_set-locale() {
 
 _localectl_set-keymap() {
     local -a _keymaps
-    _keymaps=( ${(f)"$(_call_program locales "$service" list-keymaps)"} )
     if (( CURRENT <= 3 )); then
+        _keymaps=( ${(f)"$(_call_program locales "$service" list-keymaps)"} )
         _describe keymaps _keymaps
     else
         _message "no more options"
@@ -64,6 +64,10 @@ _localectl_command() {
         'set-keymap:Set virtual console keyboard mapping'
         'list-keymaps:Show known virtual console keyboard mappings'
         'set-x11-keymap:Set X11 keyboard mapping'
+        'list-x11-keymap-models:Show known X11 keyboard mapping models'
+        'list-x11-keymap-layouts:Show known X11 keyboard mapping layouts'
+        'list-x11-keymap-variants:Show known X11 keyboard mapping variants'
+        'list-x11-keymap-options:Show known X11 keyboard mapping options'
     )
     if (( CURRENT == 1 )); then
         _describe -t commands 'localectl command' _localectl_cmds
@@ -73,7 +77,7 @@ _localectl_command() {
         if (( $+functions[_localectl_$cmd] )); then
             _localectl_$cmd
         else
-            _message "no more options"
+            _message "unknown localectl command: $words[1]"
         fi
     fi
 }
@@ -85,4 +89,5 @@ _arguments \
     '--no-pager[Do not pipe output into a pager]' \
     '--no-ask-password[Do not prompt for password]' \
     {-H+,--host=}'[Operate on remote host]:userathost:_sd_hosts_or_user_at_host' \
+    {-M+,--machine=}'[Operate on local container]:machine' \
     '*::localectl commands:_localectl_command'
index 740629d..0de66e1 100644 (file)
@@ -56,6 +56,8 @@ done
     "activate:Activate a session"
     "lock-session:Screen lock one or more sessions"
     "unlock-session:Screen unlock one or more sessions"
+    "lock-sessions:Screen lock all current sessions"
+    "unlock-sessions:Screen unlock all current sessions"
     "terminate-session:Terminate one or more sessions"
     "kill-session:Send signal to processes of a session"
     "list-users:List users"
@@ -99,8 +101,11 @@ _arguments -s \
     {-a,--all}'[Show all properties, including empty ones]' \
     '--kill-who=[Who to send signal to]:killwho:(main control all)' \
     {-s+,--signal=}'[Which signal to send]:signal:_signals' \
-    '--no-ask-password[Do not ask for system passwords]' \
     {-H+,--host=}'[Operate on remote host]:userathost:_sd_hosts_or_user_at_host' \
+    {-M+,--machine=}'[Operate on local container]:machine' \
     {-P,--privileged}'[Acquire privileges before execution]' \
+    {-l,--full}'[Do not ellipsize output]' \
     '--no-pager[Do not pipe output into a pager]' \
+    '--no-legend[Do not show the headers and footers]' \
+    '--no-ask-password[Do not ask for system passwords]' \
     '*::loginctl command:_loginctl_command'
index 15c149f..c666b7e 100644 (file)
@@ -7,6 +7,9 @@
     "list:List currently running VMs/containers"
     "status:Show VM/container status"
     "show:Show properties of one or more VMs/containers"
+    "login:Get a login prompt on a VM/container"
+    "poweroff:Power off one or more VMs/containers"
+    "reboot:Reboot one or more VMs/containers"
     "terminate:Terminate one or more VMs/containers"
     "kill:Send signal to process or a VM/container"
   )
index 1d64d13..a0039ee 100644 (file)
@@ -1,6 +1,6 @@
 #autoload
 __get_machines () {
-        machinectl --full --no-pager list | {while read -r a b; do echo $a; done;};
+        machinectl --full --no-legend --no-pager list |  {while read -r a b; do echo $a; done;};
 }
 
 local -a _machines
diff --git a/shell-completion/zsh/_sd_unit_files b/shell-completion/zsh/_sd_unit_files
new file mode 100644 (file)
index 0000000..4778a04
--- /dev/null
@@ -0,0 +1,9 @@
+#autoload
+
+_sd_unit_files() {
+    local files expl
+    files=( '*:files:->files' )
+
+    _description files expl 'unit file'
+    _files "$expl[@]" -g '*.(automount|busname|device|mount|path|service|snapshot|socket|swap|target|timer)'
+}
similarity index 88%
rename from shell-completion/zsh/_systemctl
rename to shell-completion/zsh/_systemctl.in
index b6cf664..e681ec6 100644 (file)
@@ -100,7 +100,7 @@ _systemctl_all_units()
   if ( [[ ${+_sys_all_units} -eq 0 ]] || _cache_invalid SYS_ALL_UNITS ) &&
     ! _retrieve_cache SYS_ALL_UNITS;
   then
-    _sys_all_units=( $(__systemctl list-units --all | { while read a b; do echo " $a"; done; }) )
+    _sys_all_units=( $(__systemctl list-units --all | { while read -r a b; do echo -E - " $a"; done; }) )
     _store_cache SYS_ALL_UNITS _sys_all_units
   fi
 }
@@ -113,7 +113,7 @@ _systemctl_really_all_units()
   if ( [[ ${+_sys_really_all_units} -eq 0 ]] || _cache_invalid SYS_REALLY_ALL_UNITS ) &&
     ! _retrieve_cache SYS_REALLY_ALL_UNITS;
   then
-    all_unit_files=( $(__systemctl list-unit-files | { while read a b; do echo " $a"; done; }) )
+    all_unit_files=( $(__systemctl list-unit-files | { while read -r a b; do echo -E - " $a"; done; }) )
     _systemctl_all_units
     really_all_units=($_sys_all_units $all_unit_files)
     _sys_really_all_units=(${(u)really_all_units})
@@ -138,12 +138,12 @@ _filter_units_by_property() {
   done
 }
 
-_systemctl_active_units()  {_sys_active_units=(  $(__systemctl list-units          | { while read a b; do echo " $a"; done; }) )}
-_systemctl_inactive_units(){_sys_inactive_units=($(__systemctl list-units --all    | { while read a b c d; do [[ $c == "inactive" || $c == "failed" ]] && echo " $a"; done; }) )}
-_systemctl_failed_units()  {_sys_failed_units=(  $(__systemctl list-units --failed | { while read a b; do echo " $a"; done; }) )}
-_systemctl_enabled_units() {_sys_enabled_units=( $(__systemctl list-unit-files     | { while read a b; do [[ $b == "enabled" ]] && echo " $a"; done; }) )}
-_systemctl_disabled_units(){_sys_disabled_units=($(__systemctl list-unit-files     | { while read a b; do [[ $b == "disabled" ]] && echo " $a"; done; }) )}
-_systemctl_masked_units()  {_sys_masked_units=(  $(__systemctl list-unit-files     | { while read a b; do [[ $b == "masked" ]] && echo " $a"; done; }) )}
+_systemctl_active_units()  {_sys_active_units=(  $(__systemctl list-units          | { while read -r a b; do echo -E - " $a"; done; }) )}
+_systemctl_inactive_units(){_sys_inactive_units=($(__systemctl list-units --all    | { while read -r a b c d; do [[ $c == "inactive" || $c == "failed" ]] && echo -E - " $a"; done; }) )}
+_systemctl_failed_units()  {_sys_failed_units=(  $(__systemctl list-units --failed | { while read -r a b; do echo -E - " $a"; done; }) )}
+_systemctl_enabled_units() {_sys_enabled_units=( $(__systemctl list-unit-files     | { while read -r a b; do [[ $b == "enabled" ]] && echo -E - " $a"; done; }) )}
+_systemctl_disabled_units(){_sys_disabled_units=($(__systemctl list-unit-files     | { while read -r a b; do [[ $b == "disabled" ]] && echo -E - " $a"; done; }) )}
+_systemctl_masked_units()  {_sys_masked_units=(  $(__systemctl list-unit-files     | { while read -r a b; do [[ $b == "masked" ]] && echo -E - " $a"; done; }) )}
 
 # Completion functions for ALL_UNITS
 for fun in is-active is-failed is-enabled status show cat mask preset help list-dependencies ; do
@@ -219,8 +219,8 @@ for fun in restart reload-or-restart ; do
   {
     _systemctl_all_units
     compadd "$@" - $( _filter_units_by_property CanStart yes \
-      ${_sys_all_units[*]} | while read line; do \
-      [[ "$line" =~ \.device$ ]] || echo " $line"; \
+      ${_sys_all_units[*]} | while read -r line; do \
+      [[ "$line" =~ \.device$ ]] || echo -E - " $line"; \
       done )
   }
 done
@@ -261,7 +261,9 @@ for fun in set-environment unset-environment ; do
   }
 done
 
-(( $+functions[_systemctl_link] )) || _systemctl_link() { _files }
+(( $+functions[_systemctl_link] )) || _systemctl_link() {
+   _sd_unit_files
+}
 
 # no systemctl completion for:
 #    [STANDALONE]='daemon-reexec daemon-reload default
@@ -297,16 +299,29 @@ _unit_states() {
 
 _unit_types() {
     local -a _types
-    _types=(automount device mount path service snapshot socket swap target timer)
+    _types=(automount busname device mount path service snapshot socket swap target timer)
     _values -s , "${_types[@]}"
 }
 
+_unit_properties() {
+  if ( [[ ${+_sys_all_properties} -eq 0 ]] || _cache_invalid SYS_ALL_PROPERTIES ) &&
+    ! _retrieve_cache SYS_ALL_PROPERTIES;
+  then
+    _sys_all_properties=( $( {__systemctl show --all;
+       @rootlibexecdir@/systemd --dump-configuration-items; } | {
+       while IFS='=' read -r a b; do [ -n "$b" ] && echo "$a"; done
+    }) )
+    _store_cache SYS_ALL_PROPRTIES _sys_all_properties
+  fi
+  _values -s , "${_sys_all_properties[@]}"
+}
+
 _arguments -s \
     {-h,--help}'[Show help]' \
     '--version[Show package version]' \
     {-t+,--type=}'[List only units of a particular type]:unit type:_unit_types' \
     '--state=[Display units in the specifyied state]:unit state:_unit_states' \
-    \*{-p+,--property=}'[Show only properties by specific name]:unit property' \
+    {-p+,--property=}'[Show only properties by specific name]:unit property:_unit_properties' \
     {-a,--all}'[Show all units/properties, including dead/empty ones]' \
     '--reverse[Show reverse dependencies]' \
     '--after[Show units ordered after]' \
index 2eda5fe..c101ad0 100644 (file)
@@ -6,6 +6,10 @@ _systemd_analyze_set-log-level() {
     _describe -t level 'logging level' _levels || compadd "$@"
 }
 
+_systemd_analyze_verify() {
+    _sd_unit_files
+}
+
 _systemd_analyze_command(){
     local -a _systemd_analyze_cmds
     # Descriptions taken from systemd-analyze --help.
@@ -17,6 +21,7 @@ _systemd_analyze_command(){
         'dot:Dump dependency graph (in dot(1) format)'
         'dump:Dump server status'
         'set-log-level:Set systemd log threshold'
+        'verify:Check unit files for correctness'
     )
 
     if (( CURRENT == 1 )); then
@@ -38,7 +43,12 @@ _systemd_analyze_command(){
 
 _arguments \
     {-h,--help}'[Show help text.]' \
-    '--user[Shows performance data of user sessions instead of the system manager.]' \
+    '--system[Operate on system systemd instance.]' \
+    '--user[Operate on user systemd instance.]' \
+    '--no-pager[Do not user pager.]' \
+    '--no-man[Do not check man pages.]' \
     '--order[When generating graph for dot, show only order]' \
     '--require[When generating graph for dot, show only requirement]' \
+    {-H+,--host=}'[Operate on remote host]:userathost:_sd_hosts_or_user_at_host' \
+    {-M+,--machine=}'[Operate on local container]:machine' \
     '*::systemd-analyze commands:_systemd_analyze_command'
index a8c2411..ceedb2c 100644 (file)
@@ -13,12 +13,32 @@ _nspawn-caps(){
 _arguments \
     {-h,--help}'[Show this help]' \
     {--directory=,-D+}'[Directory to use as file system root for the namespace container. If omitted the current directory will be used.]:directories:_directories' \
-    {--boot,-b+}'[Automatically search for an init binary and invoke it instead of a shell or a user supplied program.]' \
+    {--image=,-i+}'[Disk image to mount the root directory for the container from.]' \
+    {--boot=,-b+}'[Automatically search for an init binary and invoke it instead of a shell or a user supplied program.]' \
     {--user=,-u+}'[Run the command under specified user, create home directory and cd into it.]' \
+    {--machine=,-M+}'[Sets the machine name for this container.]' \
     '--uuid=[Set the specified uuid for the container.]' \
-    {--controllers=,-C+}'[Makes the container appear in other hierarchies than the name=systemd:/ one. Takes a comma-separated list of controllers.]' \
+    '--slice=[Make the container part of the specified slice, instead of the default machine.slice.]' \
     '--private-network[Turn off networking in the container. This makes all network interfaces unavailable in the container, with the exception of the loopback device.]' \
-    '--read-only[Mount the root file system read only for the container.]' \
+    '--private-network[Disconnect networking of the container from the host.]' \
+    '--network-interface=[Assign the specified network interface to the container.]' \
+    '--network-macvlan=[Create a "macvlan" interface of the specified Ethernet network interface and add it to the container.]' \
+    '--network-veth[Create a virtual Ethernet link (veth) between host and container.]' \
+    '--network-bridge=[Adds the host side of the Ethernet link created with --network-veth to the specified bridge.]' \
+    {--selinux-context=,-Z+}'[Sets the SELinux security context to be used to label processes in the container.]' \
+    {--selinux-apifs-context=,-L+}'[Sets the SELinux security context to be used to label files in the virtual API file systems in the container.]' \
     '--capability=[List one or more additional capabilities to grant the container.]:capabilities:_nspawn-caps' \
+    '--drop-capability=[Specify one or more additional capabilities to drop for the container]' \
     "--link-journal=[Control whether the container's journal shall be made visible to the host system.]:options:(no, host, guest, auto)" \
-    '-j[Equivalent to --link-journal=guest.]'
+    '-j[Equivalent to --link-journal=guest.]' \
+    '--read-only[Mount the root file system read only for the container.]' \
+    '--bind=[Bind mount a file or directory from the host into the container.]' \
+    '--bind-ro=[Bind mount a file or directory from the host into the container (read-only).]' \
+    '--setenv=[Specifies an environment variable assignment to pass to the init process in the container, in the format "NAME=VALUE".]' \
+    '--share-system[Allows the container to share certain system facilities with the host.]' \
+    '--register=[Controls whether the container is registered with systemd-machined(8).]' \
+    '--keep-unit[Instead of creating a transient scope unit to run the container in, simply register the service or scope unit systemd-nspawn has been invoked in with systemd-machined(8).]' \
+    '--personality=[Control the architecture ("personality") reported by uname(2) in the container.]' \
+    {--quiet,-q}'[Turns off any status output by the tool itself.]' \
+    {--help,-h}'[Print a short help text and exit.]' \
+    '--version[Print a short version string and exit.]'
index 23c484c..8942773 100644 (file)
@@ -27,7 +27,7 @@
 #include <sys/wait.h>
 #include <getopt.h>
 
-#include <systemd/sd-daemon.h>
+#include "systemd/sd-daemon.h"
 
 #include "socket-util.h"
 #include "build.h"
@@ -59,25 +59,6 @@ static int add_epoll(int epoll_fd, int fd) {
         return 0;
 }
 
-static int make_socket_fd(const char* address, int flags) {
-        SocketAddress a;
-        int fd, r;
-
-        r = socket_address_parse(&a, address);
-        if (r < 0) {
-                log_error("Failed to parse socket: %s", strerror(-r));
-                return r;
-        }
-
-        fd = socket_address_listen(&a, flags, SOMAXCONN, SOCKET_ADDRESS_DEFAULT, NULL, false, false, 0755, 0644, NULL);
-        if (fd < 0) {
-                log_error("Failed to listen: %s", strerror(-r));
-                return fd;
-        }
-
-        return fd;
-}
-
 static int open_sockets(int *epoll_fd, bool accept) {
         char **address;
         int n, fd, r;
@@ -119,7 +100,7 @@ static int open_sockets(int *epoll_fd, bool accept) {
 
         STRV_FOREACH(address, arg_listen) {
 
-                fd = make_socket_fd(*address, SOCK_STREAM | (arg_accept*SOCK_CLOEXEC));
+                fd = make_socket_fd(LOG_DEBUG, *address, SOCK_STREAM | (arg_accept*SOCK_CLOEXEC));
                 if (fd < 0) {
                         log_open();
                         log_error("Failed to open '%s': %s", *address, strerror(-fd));
@@ -298,7 +279,7 @@ static int install_chld_handler(void) {
         return r;
 }
 
-static int help(void) {
+static void help(void) {
         printf("%s [OPTIONS...]\n\n"
                "Listen on sockets and launch child on connection.\n\n"
                "Options:\n"
@@ -309,10 +290,7 @@ static int help(void) {
                "  --version                Print version string and exit\n"
                "\n"
                "Note: file descriptors from sd_listen_fds() will be passed through.\n"
-               , program_invocation_short_name
-               );
-
-        return 0;
+               , program_invocation_short_name);
 }
 
 static int parse_argv(int argc, char *argv[]) {
@@ -338,7 +316,8 @@ static int parse_argv(int argc, char *argv[]) {
         while ((c = getopt_long(argc, argv, "+hl:aE:", options, NULL)) >= 0)
                 switch(c) {
                 case 'h':
-                        return help();
+                        help();
+                        return 0;
 
                 case ARG_VERSION:
                         puts(PACKAGE_STRING);
@@ -373,7 +352,7 @@ static int parse_argv(int argc, char *argv[]) {
                 }
 
         if (optind == argc) {
-                log_error("Usage: %s [OPTION...] PROGRAM [OPTION...]",
+                log_error("%s: command to execute is missing.",
                           program_invocation_short_name);
                 return -EINVAL;
         }
diff --git a/src/analyze/analyze-verify.c b/src/analyze/analyze-verify.c
new file mode 100644 (file)
index 0000000..5b16b6c
--- /dev/null
@@ -0,0 +1,280 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Zbigniew Jędrzejewski-Szmek
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdlib.h>
+#include <getopt.h>
+
+#include "manager.h"
+#include "bus-util.h"
+#include "log.h"
+#include "strv.h"
+#include "build.h"
+#include "pager.h"
+#include "analyze-verify.h"
+
+static int generate_path(char **var, char **filenames) {
+        char **filename;
+
+        _cleanup_strv_free_ char **ans = NULL;
+        int r;
+
+        STRV_FOREACH(filename, filenames) {
+                char *t;
+
+                t = dirname_malloc(*filename);
+                if (!t)
+                        return -ENOMEM;
+
+                r = strv_consume(&ans, t);
+                if (r < 0)
+                        return r;
+        }
+
+        assert_se(strv_uniq(ans));
+
+        r = strv_extend(&ans, "");
+        if (r < 0)
+                return r;
+
+        *var = strv_join(ans, ":");
+        if (!*var)
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int verify_socket(Unit *u) {
+        int r;
+
+        assert(u);
+
+        if (u->type != UNIT_SOCKET)
+                return 0;
+
+        /* Cannot run this without the service being around */
+
+        /* This makes sure instance is created if necessary. */
+        r = socket_instantiate_service(SOCKET(u));
+        if (r < 0) {
+                log_error_unit(u->id, "Socket %s cannot be started, failed to create instance.",
+                               u->id);
+                return r;
+        }
+
+        /* This checks both type of sockets */
+        if (UNIT_ISSET(SOCKET(u)->service)) {
+                Service *service;
+
+                service = SERVICE(UNIT_DEREF(SOCKET(u)->service));
+                log_debug_unit(u->id, "%s uses %s", u->id, UNIT(service)->id);
+
+                if (UNIT(service)->load_state != UNIT_LOADED) {
+                        log_error_unit(u->id, "Service %s not loaded, %s cannot be started.",
+                                       UNIT(service)->id, u->id);
+                        return -ENOENT;
+                }
+        }
+
+        return 0;
+}
+
+static int verify_executable(Unit *u, ExecCommand *exec) {
+        if (exec == NULL)
+                return 0;
+
+        if (access(exec->path, X_OK) < 0) {
+                log_error_unit(u->id, "%s: command %s is not executable: %m",
+                               u->id, exec->path);
+                return -errno;
+        }
+
+        return 0;
+}
+
+static int verify_executables(Unit *u) {
+        ExecCommand *exec;
+        int r = 0, k;
+        unsigned i;
+
+        assert(u);
+
+        exec =  u->type == UNIT_SOCKET ? SOCKET(u)->control_command :
+                u->type == UNIT_MOUNT ? MOUNT(u)->control_command :
+                u->type == UNIT_SWAP ? SWAP(u)->control_command : NULL;
+        k = verify_executable(u, exec);
+        if (k < 0 && r == 0)
+                r = k;
+
+        if (u->type == UNIT_SERVICE)
+                for (i = 0; i < ELEMENTSOF(SERVICE(u)->exec_command); i++) {
+                        k = verify_executable(u, SERVICE(u)->exec_command[i]);
+                        if (k < 0 && r == 0)
+                                r = k;
+                }
+
+        if (u->type == UNIT_SOCKET)
+                for (i = 0; i < ELEMENTSOF(SOCKET(u)->exec_command); i++) {
+                        k = verify_executable(u, SOCKET(u)->exec_command[i]);
+                        if (k < 0 && r == 0)
+                                r = k;
+                }
+
+        return r;
+}
+
+static int verify_documentation(Unit *u, bool check_man) {
+        char **p;
+        int r = 0, k;
+
+        STRV_FOREACH(p, u->documentation) {
+                log_debug_unit(u->id, "%s: found documentation item %s.", u->id, *p);
+                if (check_man && startswith(*p, "man:")) {
+                        k = show_man_page(*p + 4, true);
+                        if (k != 0) {
+                                if (k < 0)
+                                        log_error_unit(u->id, "%s: can't show %s: %s",
+                                                       u->id, *p, strerror(-r));
+                                else {
+                                        log_error_unit(u->id, "%s: man %s command failed with code %d",
+                                                       u->id, *p + 4, k);
+                                        k = -ENOEXEC;
+                                }
+                                if (r == 0)
+                                        r = k;
+                        }
+                }
+        }
+
+        /* Check remote URLs? */
+
+        return r;
+}
+
+static int verify_unit(Unit *u, bool check_man) {
+        _cleanup_bus_error_free_ sd_bus_error err = SD_BUS_ERROR_NULL;
+        Job *j;
+        int r, k;
+
+        assert(u);
+
+        if (log_get_max_level() >= LOG_DEBUG)
+                unit_dump(u, stdout, "\t");
+
+        log_debug_unit(u->id, "Creating %s/start job", u->id);
+        r = manager_add_job(u->manager, JOB_START, u, JOB_REPLACE, false, &err, &j);
+        if (sd_bus_error_is_set(&err))
+                log_error_unit(u->id, "Error: %s: %s",
+                               err.name, err.message);
+        if (r < 0)
+                log_error_unit(u->id, "Failed to create %s/start: %s",
+                               u->id, strerror(-r));
+
+        k = verify_socket(u);
+        if (k < 0 && r == 0)
+                r = k;
+
+        k = verify_executables(u);
+        if (k < 0 && r == 0)
+                r = k;
+
+        k = verify_documentation(u, check_man);
+        if (k < 0 && r == 0)
+                r = k;
+
+        return r;
+}
+
+int verify_units(char **filenames, SystemdRunningAs running_as, bool check_man) {
+        _cleanup_bus_error_free_ sd_bus_error err = SD_BUS_ERROR_NULL;
+        Manager *m = NULL;
+        FILE *serial = NULL;
+        FDSet *fdset = NULL;
+
+        _cleanup_free_ char *var = NULL;
+
+        char **filename;
+        int r = 0, k;
+
+        Unit *units[strv_length(filenames)];
+        int i, count = 0;
+
+        if (strv_isempty(filenames))
+                return 0;
+
+        /* set the path */
+        r = generate_path(&var, filenames);
+        if (r < 0) {
+                log_error("Failed to generate unit load path: %s", strerror(-r));
+                return r;
+        }
+
+        assert_se(set_unit_path(var) >= 0);
+
+        r = manager_new(running_as, true, &m);
+        if (r < 0) {
+                log_error("Failed to initalize manager: %s", strerror(-r));
+                return r;
+        }
+
+        log_debug("Starting manager...");
+
+        r = manager_startup(m, serial, fdset);
+        if (r < 0) {
+                log_error("Failed to start manager: %s", strerror(-r));
+                goto finish;
+        }
+
+        manager_clear_jobs(m);
+
+        log_debug("Loading remaining units from the command line...");
+
+        STRV_FOREACH(filename, filenames) {
+                char fname[UNIT_NAME_MAX + 2 + 1] = "./";
+
+                log_debug("Handling %s...", *filename);
+
+                /* manager_load_unit does not like pure basenames, so prepend
+                 * the local directory, but only for valid names. manager_load_unit
+                 * will print the error for other ones. */
+                if (!strchr(*filename, '/') && strlen(*filename) <= UNIT_NAME_MAX) {
+                        strncat(fname + 2, *filename, UNIT_NAME_MAX);
+                        k = manager_load_unit(m, NULL, fname, &err, &units[count]);
+                } else
+                        k = manager_load_unit(m, NULL, *filename, &err, &units[count]);
+                if (k < 0) {
+                        log_error("Failed to load %s: %s", *filename, strerror(-k));
+                        if (r == 0)
+                                r = k;
+                } else
+                        count ++;
+        }
+
+        for (i = 0; i < count; i++) {
+                k = verify_unit(units[i], check_man);
+                if (k < 0 && r == 0)
+                        r = k;
+        }
+
+finish:
+        manager_free(m);
+
+        return r;
+}
diff --git a/src/analyze/analyze-verify.h b/src/analyze/analyze-verify.h
new file mode 100644 (file)
index 0000000..5c86d98
--- /dev/null
@@ -0,0 +1,26 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Zbigniew Jędrzejewski-Szmek
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdbool.h>
+
+#include "path-lookup.h"
+
+int verify_units(char **filenames, SystemdRunningAs running_as, bool check_man);
index 3d2d08f..d860a02 100644 (file)
 #include "special.h"
 #include "hashmap.h"
 #include "pager.h"
+#include "analyze-verify.h"
 
 #define SCALE_X (0.1 / 1000.0)   /* pixels per us */
-#define SCALE_Y 20.0
+#define SCALE_Y (20.0)
 
 #define compare(a, b) (((a) > (b))? 1 : (((b) > (a))? -1 : 0))
 
@@ -74,6 +75,7 @@ static bool arg_no_pager = false;
 static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
 static char *arg_host = NULL;
 static bool arg_user = false;
+static bool arg_man = true;
 
 struct boot_times {
         usec_t firmware_time;
@@ -100,6 +102,16 @@ struct unit_times {
         usec_t time;
 };
 
+struct host_info {
+        char *hostname;
+        char *kernel_name;
+        char *kernel_release;
+        char *kernel_version;
+        char *os_pretty_name;
+        char *virtualization;
+        char *architecture;
+};
+
 static void pager_open_if_enabled(void) {
 
         if (arg_no_pager)
@@ -170,21 +182,6 @@ static int compare_unit_start(const void *a, const void *b) {
                        ((struct unit_times *)b)->activating);
 }
 
-static int get_os_name(char **_n) {
-        char *n = NULL;
-        int r;
-
-        r = parse_env_file("/etc/os-release", NEWLINE, "PRETTY_NAME", &n, NULL);
-        if (r < 0)
-                return r;
-
-        if (!n)
-                return -ENOENT;
-
-        *_n = n;
-        return 0;
-}
-
 static void free_unit_times(struct unit_times *t, unsigned n) {
         struct unit_times *p;
 
@@ -372,6 +369,63 @@ finish:
         return 0;
 }
 
+static void free_host_info(struct host_info *hi) {
+        free(hi->hostname);
+        free(hi->kernel_name);
+        free(hi->kernel_release);
+        free(hi->kernel_version);
+        free(hi->os_pretty_name);
+        free(hi->virtualization);
+        free(hi->architecture);
+        free(hi);
+}
+
+static int acquire_host_info(sd_bus *bus, struct host_info **hi) {
+        int r;
+        struct host_info *host;
+
+        static const struct bus_properties_map hostname_map[] = {
+                { "Hostname", "s", NULL, offsetof(struct host_info, hostname) },
+                { "KernelName", "s", NULL, offsetof(struct host_info, kernel_name) },
+                { "KernelRelease", "s", NULL, offsetof(struct host_info, kernel_release) },
+                { "KernelVersion", "s", NULL, offsetof(struct host_info, kernel_version) },
+                { "OperatingSystemPrettyName", "s", NULL, offsetof(struct host_info, os_pretty_name) },
+                {}
+        };
+
+        static const struct bus_properties_map manager_map[] = {
+                { "Virtualization", "s", NULL, offsetof(struct host_info, virtualization) },
+                { "Architecture",   "s", NULL, offsetof(struct host_info, architecture) },
+                {}
+        };
+
+        host = new0(struct host_info, 1);
+        if (!host)
+                return log_oom();
+
+        r = bus_map_all_properties(bus,
+                                   "org.freedesktop.hostname1",
+                                   "/org/freedesktop/hostname1",
+                                   hostname_map,
+                                   host);
+        if (r < 0)
+                goto fail;
+
+        r = bus_map_all_properties(bus,
+                                   "org.freedesktop.systemd1",
+                                   "/org/freedesktop/systemd1",
+                                   manager_map,
+                                   host);
+        if (r < 0)
+                goto fail;
+
+        *hi = host;
+        return 0;
+fail:
+        free_host_info(host);
+        return r;
+}
+
 static int pretty_boot_time(sd_bus *bus, char **_buf) {
         char ts[FORMAT_TIMESPAN_MAX];
         struct boot_times *t;
@@ -437,10 +491,10 @@ static void svg_graph_box(double height, double begin, double end) {
 static int analyze_plot(sd_bus *bus) {
         struct unit_times *times;
         struct boot_times *boot;
-        struct utsname name;
+        struct host_info *host = NULL;
         int n, m = 1, y=0;
         double width;
-        _cleanup_free_ char *pretty_times = NULL, *osname = NULL;
+        _cleanup_free_ char *pretty_times = NULL;
         struct unit_times *u;
 
         n = acquire_boot_times(bus, &boot);
@@ -451,12 +505,13 @@ static int analyze_plot(sd_bus *bus) {
         if (n < 0)
                 return n;
 
-        get_os_name(&osname);
-        assert_se(uname(&name) >= 0);
+        n = acquire_host_info(bus, &host);
+        if (n < 0)
+                return n;
 
         n = acquire_time_data(bus, &times);
         if (n <= 0)
-                return n;
+                goto out;
 
         qsort(times, n, sizeof(struct unit_times), compare_unit_start);
 
@@ -551,9 +606,14 @@ static int analyze_plot(sd_bus *bus) {
 
         svg("<rect class=\"background\" width=\"100%%\" height=\"100%%\" />\n");
         svg("<text x=\"20\" y=\"50\">%s</text>", pretty_times);
-        svg("<text x=\"20\" y=\"30\">%s %s (%s %s) %s</text>",
-            isempty(osname) ? "Linux" : osname,
-            name.nodename, name.release, name.version, name.machine);
+        svg("<text x=\"20\" y=\"30\">%s %s (%s %s %s) %s %s</text>",
+            isempty(host->os_pretty_name) ? "Linux" : host->os_pretty_name,
+            isempty(host->hostname) ? "" : host->hostname,
+            isempty(host->kernel_name) ? "" : host->kernel_name,
+            isempty(host->kernel_release) ? "" : host->kernel_release,
+            isempty(host->kernel_version) ? "" : host->kernel_version,
+            isempty(host->architecture) ? "" : host->architecture,
+            isempty(host->virtualization) ? "" : host->virtualization);
 
         svg("<g transform=\"translate(%.3f,100)\">\n", 20.0 + (SCALE_X * boot->firmware_time));
         svg_graph_box(m, -(double) boot->firmware_time, boot->finish_time);
@@ -636,7 +696,10 @@ static int analyze_plot(sd_bus *bus) {
 
         free_unit_times(times, (unsigned) n);
 
-        return 0;
+        n = 0;
+out:
+        free_host_info(host);
+        return n;
 }
 
 static int list_dependencies_print(const char *name, unsigned int level, unsigned int branches,
@@ -645,7 +708,7 @@ static int list_dependencies_print(const char *name, unsigned int level, unsigne
         char ts[FORMAT_TIMESPAN_MAX], ts2[FORMAT_TIMESPAN_MAX];
 
         for (i = level; i != 0; i--)
-                printf("%s", draw_special_char(branches & (1 << (i-1)) ? DRAW_TREE_VERT : DRAW_TREE_SPACE));
+                printf("%s", draw_special_char(branches & (1 << (i-1)) ? DRAW_TREE_VERTICAL : DRAW_TREE_SPACE));
 
         printf("%s", draw_special_char(last ? DRAW_TREE_RIGHT : DRAW_TREE_BRANCH));
 
@@ -1117,17 +1180,17 @@ static int set_log_level(sd_bus *bus, char **args) {
         return 0;
 }
 
-static int help(void) {
+static void help(void) {
 
         pager_open_if_enabled();
 
         printf("%s [OPTIONS...] {COMMAND} ...\n\n"
-               "Process systemd profiling information.\n\n"
+               "Profile systemd, show unit dependencies, check unit files.\n\n"
                "  -h --help               Show this help\n"
                "     --version            Show package version\n"
                "     --no-pager           Do not pipe output into a pager\n"
-               "     --system             Connect to system manager\n"
-               "     --user               Connect to user manager\n"
+               "     --system             Operate on system systemd instance\n"
+               "     --user               Operate on user systemd instance\n"
                "  -H --host=[USER@]HOST   Operate on remote host\n"
                "  -M --machine=CONTAINER  Operate on local container\n"
                "     --order              When generating a dependency graph, show only order\n"
@@ -1138,7 +1201,8 @@ static int help(void) {
                "     --fuzz=TIMESPAN      When printing the tree of the critical chain, print also\n"
                "                          services, which finished TIMESPAN earlier, than the\n"
                "                          latest in the branch. The unit of TIMESPAN is seconds\n"
-               "                          unless specified with a different unit, i.e. 50ms\n\n"
+               "                          unless specified with a different unit, i.e. 50ms\n"
+               "     --man[=BOOL]         Do [not] check for existence of man pages\n\n"
                "Commands:\n"
                "  time                    Print time spent in the kernel before reaching userspace\n"
                "  blame                   Print list of running units ordered by time to init\n"
@@ -1146,14 +1210,13 @@ static int help(void) {
                "  plot                    Output SVG graphic showing service initialization\n"
                "  dot                     Output dependency graph in dot(1) format\n"
                "  set-log-level LEVEL     Set logging threshold for systemd\n"
-               "  dump                    Output state serialization of service manager\n",
-               program_invocation_short_name);
+               "  dump                    Output state serialization of service manager\n"
+               "  verify FILE...          Check unit files for correctness\n"
+               , program_invocation_short_name);
 
         /* When updating this list, including descriptions, apply
-         * changes to shell-completion/bash/systemd and
-         * shell-completion/systemd-zsh-completion.zsh too. */
-
-        return 0;
+         * changes to shell-completion/bash/systemd-analyze and
+         * shell-completion/zsh/_systemd-analyze too. */
 }
 
 static int parse_argv(int argc, char *argv[]) {
@@ -1166,7 +1229,8 @@ static int parse_argv(int argc, char *argv[]) {
                 ARG_DOT_FROM_PATTERN,
                 ARG_DOT_TO_PATTERN,
                 ARG_FUZZ,
-                ARG_NO_PAGER
+                ARG_NO_PAGER,
+                ARG_MAN,
         };
 
         static const struct option options[] = {
@@ -1180,6 +1244,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "to-pattern",   required_argument, NULL, ARG_DOT_TO_PATTERN   },
                 { "fuzz",         required_argument, NULL, ARG_FUZZ             },
                 { "no-pager",     no_argument,       NULL, ARG_NO_PAGER         },
+                { "man",          optional_argument, NULL, ARG_MAN              },
                 { "host",         required_argument, NULL, 'H'                  },
                 { "machine",      required_argument, NULL, 'M'                  },
                 {}
@@ -1190,12 +1255,12 @@ static int parse_argv(int argc, char *argv[]) {
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "hH:M:", options, NULL)) >= 0) {
-
+        while ((c = getopt_long(argc, argv, "hH:M:", options, NULL)) >= 0)
                 switch (c) {
 
                 case 'h':
-                        return help();
+                        help();
+                        return 0;
 
                 case ARG_VERSION:
                         puts(PACKAGE_STRING);
@@ -1250,19 +1315,31 @@ static int parse_argv(int argc, char *argv[]) {
                         arg_host = optarg;
                         break;
 
+                case ARG_MAN:
+                        if (optarg) {
+                                r = parse_boolean(optarg);
+                                if (r < 0) {
+                                        log_error("Failed to parse --man= argument.");
+                                        return -EINVAL;
+                                }
+
+                                arg_man = !!r;
+                        } else
+                                arg_man = true;
+
+                        break;
+
                 case '?':
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached("Unhandled option code.");
                 }
-        }
 
-        return 1;
+        return 1; /* work to do */
 }
 
 int main(int argc, char *argv[]) {
-        _cleanup_bus_unref_ sd_bus *bus = NULL;
         int r;
 
         setlocale(LC_ALL, "");
@@ -1274,28 +1351,36 @@ int main(int argc, char *argv[]) {
         if (r <= 0)
                 goto finish;
 
-        r = bus_open_transport(arg_transport, arg_host, arg_user, &bus);
-        if (r < 0) {
-                log_error("Failed to create bus connection: %s", strerror(-r));
-                goto finish;
-        }
+        if (streq_ptr(argv[optind], "verify"))
+                r = verify_units(argv+optind+1,
+                                 arg_user ? SYSTEMD_USER : SYSTEMD_SYSTEM,
+                                 arg_man);
+        else {
+                _cleanup_bus_close_unref_ sd_bus *bus = NULL;
+
+                r = bus_open_transport_systemd(arg_transport, arg_host, arg_user, &bus);
+                if (r < 0) {
+                        log_error("Failed to create bus connection: %s", strerror(-r));
+                        goto finish;
+                }
 
-        if (!argv[optind] || streq(argv[optind], "time"))
-                r = analyze_time(bus);
-        else if (streq(argv[optind], "blame"))
-                r = analyze_blame(bus);
-        else if (streq(argv[optind], "critical-chain"))
-                r = analyze_critical_chain(bus, argv+optind+1);
-        else if (streq(argv[optind], "plot"))
-                r = analyze_plot(bus);
-        else if (streq(argv[optind], "dot"))
-                r = dot(bus, argv+optind+1);
-        else if (streq(argv[optind], "dump"))
-                r = dump(bus, argv+optind+1);
-        else if (streq(argv[optind], "set-log-level"))
-                r = set_log_level(bus, argv+optind+1);
-        else
-                log_error("Unknown operation '%s'.", argv[optind]);
+                if (!argv[optind] || streq(argv[optind], "time"))
+                        r = analyze_time(bus);
+                else if (streq(argv[optind], "blame"))
+                        r = analyze_blame(bus);
+                else if (streq(argv[optind], "critical-chain"))
+                        r = analyze_critical_chain(bus, argv+optind+1);
+                else if (streq(argv[optind], "plot"))
+                        r = analyze_plot(bus);
+                else if (streq(argv[optind], "dot"))
+                        r = dot(bus, argv+optind+1);
+                else if (streq(argv[optind], "dump"))
+                        r = dump(bus, argv+optind+1);
+                else if (streq(argv[optind], "set-log-level"))
+                        r = set_log_level(bus, argv+optind+1);
+                else
+                        log_error("Unknown operation '%s'.", argv[optind]);
+        }
 
 finish:
         pager_close();
index ea0c623..5c37cff 100644 (file)
 #include "def.h"
 
 static const char *arg_icon = NULL;
+static const char *arg_id = NULL;
 static const char *arg_message = NULL;
 static bool arg_use_tty = true;
 static usec_t arg_timeout = DEFAULT_TIMEOUT_USEC;
 static bool arg_accept_cached = false;
 static bool arg_multiple = false;
 
-static int help(void) {
-
+static void help(void) {
         printf("%s [OPTIONS...] MESSAGE\n\n"
                "Query the user for a system passphrase, via the TTY or an UI agent.\n\n"
                "  -h --help          Show this help\n"
@@ -58,10 +58,9 @@ static int help(void) {
                "     --timeout=SEC   Timeout in sec\n"
                "     --no-tty        Ask question via agent even on TTY\n"
                "     --accept-cached Accept cached passwords\n"
-               "     --multiple      List multiple passwords if available\n",
-               program_invocation_short_name);
-
-        return 0;
+               "     --multiple      List multiple passwords if available\n"
+               "     --id=ID         Query identifier (e.g. cryptsetup:/dev/sda5)\n"
+               , program_invocation_short_name);
 }
 
 static int parse_argv(int argc, char *argv[]) {
@@ -71,7 +70,8 @@ static int parse_argv(int argc, char *argv[]) {
                 ARG_TIMEOUT,
                 ARG_NO_TTY,
                 ARG_ACCEPT_CACHED,
-                ARG_MULTIPLE
+                ARG_MULTIPLE,
+                ARG_ID
         };
 
         static const struct option options[] = {
@@ -81,6 +81,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "no-tty",        no_argument,       NULL, ARG_NO_TTY        },
                 { "accept-cached", no_argument,       NULL, ARG_ACCEPT_CACHED },
                 { "multiple",      no_argument,       NULL, ARG_MULTIPLE      },
+                { "id",            required_argument, NULL, ARG_ID            },
                 {}
         };
 
@@ -89,12 +90,13 @@ static int parse_argv(int argc, char *argv[]) {
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) {
+        while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
 
                 switch (c) {
 
                 case 'h':
-                        return help();
+                        help();
+                        return 0;
 
                 case ARG_ICON:
                         arg_icon = optarg;
@@ -119,16 +121,19 @@ static int parse_argv(int argc, char *argv[]) {
                         arg_multiple = true;
                         break;
 
+                case ARG_ID:
+                        arg_id = optarg;
+                        break;
+
                 case '?':
                         return -EINVAL;
 
                 default:
                         assert_not_reached("Unhandled option");
                 }
-        }
 
-        if (optind != argc-1) {
-                help();
+        if (optind != argc - 1) {
+                log_error("%s: required argument missing.", program_invocation_short_name);
                 return -EINVAL;
         }
 
@@ -143,7 +148,8 @@ int main(int argc, char *argv[]) {
         log_parse_environment();
         log_open();
 
-        if ((r = parse_argv(argc, argv)) <= 0)
+        r = parse_argv(argc, argv);
+        if (r <= 0)
                 goto finish;
 
         if (arg_timeout > 0)
@@ -162,7 +168,7 @@ int main(int argc, char *argv[]) {
         } else {
                 char **l;
 
-                if ((r = ask_password_agent(arg_message, arg_icon, timeout, arg_accept_cached, &l)) >= 0) {
+                if ((r = ask_password_agent(arg_message, arg_icon, arg_id, timeout, arg_accept_cached, &l)) >= 0) {
                         char **p;
 
                         STRV_FOREACH(p, l) {
index 86f10cc..4d94ebf 100644 (file)
@@ -24,6 +24,7 @@
 #include "fileio.h"
 #include "libudev.h"
 #include "udev-util.h"
+#include "def.h"
 
 static struct udev_device *find_pci_or_platform_parent(struct udev_device *device) {
         struct udev_device *parent;
@@ -50,7 +51,7 @@ static struct udev_device *find_pci_or_platform_parent(struct udev_device *devic
                 if (!c)
                         return NULL;
 
-                c += strspn(c, "0123456789");
+                c += strspn(c, DIGITS);
                 if (*c == '-') {
                         /* A connector DRM device, let's ignore all but LVDS and eDP! */
 
@@ -67,7 +68,8 @@ static struct udev_device *find_pci_or_platform_parent(struct udev_device *devic
                         unsigned long class = 0;
 
                         if (safe_atolu(value, &class) < 0) {
-                                log_warning("Cannot parse PCI class %s of device %s:%s.", value, subsystem, sysname);
+                                log_warning("Cannot parse PCI class %s of device %s:%s.",
+                                            value, subsystem, sysname);
                                 return NULL;
                         }
 
@@ -175,7 +177,9 @@ static bool validate_device(struct udev *udev, struct udev_device *device) {
                 if (same_device(parent, other_parent)) {
                         /* Both have the same PCI parent, that means
                          * we are out. */
-                        log_debug("Skipping backlight device %s, since backlight device %s is on same PCI device and, takes precedence.", udev_device_get_sysname(device), udev_device_get_sysname(other));
+                        log_debug("Skipping backlight device %s, since device %s is on same PCI device and takes precedence.",
+                                  udev_device_get_sysname(device),
+                                  udev_device_get_sysname(other));
                         return false;
                 }
 
@@ -184,7 +188,9 @@ static bool validate_device(struct udev *udev, struct udev_device *device) {
                         /* The other is connected to the platform bus
                          * and we are a PCI device, that also means we
                          * are out. */
-                        log_debug("Skipping backlight device %s, since backlight device %s is a platform device and takes precedence.", udev_device_get_sysname(device), udev_device_get_sysname(other));
+                        log_debug("Skipping backlight device %s, since device %s is a platform device and takes precedence.",
+                                  udev_device_get_sysname(device),
+                                  udev_device_get_sysname(other));
                         return false;
                 }
         }
@@ -192,11 +198,78 @@ static bool validate_device(struct udev *udev, struct udev_device *device) {
         return true;
 }
 
+static unsigned get_max_brightness(struct udev_device *device) {
+        int r;
+        const char *max_brightness_str;
+        unsigned max_brightness;
+
+        max_brightness_str = udev_device_get_sysattr_value(device, "max_brightness");
+        if (!max_brightness_str) {
+                log_warning("Failed to read 'max_brightness' attribute.");
+                return 0;
+        }
+
+        r = safe_atou(max_brightness_str, &max_brightness);
+        if (r < 0) {
+                log_warning("Failed to parse 'max_brightness' \"%s\": %s", max_brightness_str, strerror(-r));
+                return 0;
+        }
+
+        if (max_brightness <= 0) {
+                log_warning("Maximum brightness is 0, ignoring device.");
+                return 0;
+        }
+
+        return max_brightness;
+}
+
+/* Some systems turn the backlight all the way off at the lowest levels.
+ * clamp_brightness clamps the saved brightness to at least 1 or 5% of
+ * max_brightness in case of 'backlight' subsystem. This avoids preserving
+ * an unreadably dim screen, which would otherwise force the user to
+ * disable state restoration. */
+static void clamp_brightness(struct udev_device *device, char **value, unsigned max_brightness) {
+        int r;
+        unsigned brightness, new_brightness, min_brightness;
+        const char *subsystem;
+
+        r = safe_atou(*value, &brightness);
+        if (r < 0) {
+                log_warning("Failed to parse brightness \"%s\": %s", *value, strerror(-r));
+                return;
+        }
+
+        subsystem = udev_device_get_subsystem(device);
+        if (streq_ptr(subsystem, "backlight"))
+                min_brightness = MAX(1U, max_brightness/20);
+        else
+                min_brightness = 0;
+
+        new_brightness = CLAMP(brightness, min_brightness, max_brightness);
+        if (new_brightness != brightness) {
+                char *old_value = *value;
+
+                r = asprintf(value, "%u", new_brightness);
+                if (r < 0) {
+                        log_oom();
+                        return;
+                }
+
+                log_info("Saved brightness %s %s to %s.", old_value,
+                         new_brightness > brightness ?
+                         "too low; increasing" : "too high; decreasing",
+                         *value);
+
+                free(old_value);
+        }
+}
+
 int main(int argc, char *argv[]) {
         _cleanup_udev_unref_ struct udev *udev = NULL;
         _cleanup_udev_device_unref_ struct udev_device *device = NULL;
         _cleanup_free_ char *saved = NULL, *ss = NULL, *escaped_ss = NULL, *escaped_sysname = NULL, *escaped_path_id = NULL;
         const char *sysname, *path_id;
+        unsigned max_brightness;
         int r;
 
         if (argc != 3) {
@@ -212,7 +285,8 @@ int main(int argc, char *argv[]) {
 
         r = mkdir_p("/var/lib/systemd/backlight", 0755);
         if (r < 0) {
-                log_error("Failed to create backlight directory: %s", strerror(-r));
+                log_error("Failed to create backlight directory /var/lib/systemd/backlight: %s",
+                          strerror(-r));
                 return EXIT_FAILURE;
         }
 
@@ -224,7 +298,7 @@ int main(int argc, char *argv[]) {
 
         sysname = strchr(argv[2], ':');
         if (!sysname) {
-                log_error("Requires pair of subsystem and sysname for specifying backlight device.");
+                log_error("Requires a subsystem and sysname pair specifying a backlight device.");
                 return EXIT_FAILURE;
         }
 
@@ -252,6 +326,14 @@ int main(int argc, char *argv[]) {
                 return EXIT_FAILURE;
         }
 
+        /* If max_brightness is 0, then there is no actual backlight
+         * device. This happens on desktops with Asus mainboards
+         * that load the eeepc-wmi module.
+         */
+        max_brightness = get_max_brightness(device);
+        if (max_brightness == 0)
+                return EXIT_SUCCESS;
+
         escaped_ss = cescape(ss);
         if (!escaped_ss) {
                 log_oom();
@@ -306,9 +388,12 @@ int main(int argc, char *argv[]) {
                         return EXIT_FAILURE;
                 }
 
+                clamp_brightness(device, &value, max_brightness);
+
                 r = udev_device_set_sysattr_value(device, "brightness", value);
                 if (r < 0) {
-                        log_error("Failed to write system attribute: %s", strerror(-r));
+                        log_error("Failed to write system 'brightness' attribute: %s",
+                                  strerror(-r));
                         return EXIT_FAILURE;
                 }
 
@@ -322,7 +407,7 @@ int main(int argc, char *argv[]) {
 
                 value = udev_device_get_sysattr_value(device, "brightness");
                 if (!value) {
-                        log_error("Failed to read system attribute: %s", strerror(-r));
+                        log_error("Failed to read system 'brightness' attribute");
                         return EXIT_FAILURE;
                 }
 
index a1877c4..c1c1522 100644 (file)
@@ -86,7 +86,7 @@ static int apply_file(const char *path, bool ignore_enoent) {
 
         assert(path);
 
-        r = search_and_fopen_nulstr(path, "re", conf_file_dirs, &f);
+        r = search_and_fopen_nulstr(path, "re", NULL, conf_file_dirs, &f);
         if (r < 0) {
                 if (ignore_enoent && r == -ENOENT)
                         return 0;
@@ -122,15 +122,12 @@ static int apply_file(const char *path, bool ignore_enoent) {
         return r;
 }
 
-static int help(void) {
-
+static void help(void) {
         printf("%s [OPTIONS...] [CONFIGURATION FILE...]\n\n"
                "Registers binary formats.\n\n"
                "  -h --help             Show this help\n"
-               "     --version          Show package version\n",
-               program_invocation_short_name);
-
-        return 0;
+               "     --version          Show package version\n"
+               , program_invocation_short_name);
 }
 
 static int parse_argv(int argc, char *argv[]) {
@@ -150,12 +147,13 @@ static int parse_argv(int argc, char *argv[]) {
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) {
+        while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
 
                 switch (c) {
 
                 case 'h':
-                        return help();
+                        help();
+                        return 0;
 
                 case ARG_VERSION:
                         puts(PACKAGE_STRING);
@@ -168,7 +166,6 @@ static int parse_argv(int argc, char *argv[]) {
                 default:
                         assert_not_reached("Unhandled option");
                 }
-        }
 
         return 1;
 }
index 359e273..51b51c4 100644 (file)
 #include "util.h"
 #include "utf8.h"
 
-static int help(void) {
-
+static void help(void) {
         printf("%s [OPTIONS...] COMMAND ...\n\n"
                "Query or change firmware and boot manager settings.\n\n"
                "  -h --help              Show this help\n"
                "     --version           Show package version\n"
                "Commands:\n"
-               "  status                 Show current boot settings\n",
-               program_invocation_short_name);
-
-        return 0;
+               "  status                 Show current boot settings\n"
+               , program_invocation_short_name);
 }
 
 static int parse_argv(int argc, char *argv[]) {
@@ -51,8 +48,8 @@ static int parse_argv(int argc, char *argv[]) {
         };
 
         static const struct option options[] = {
-                { "help",                no_argument,       NULL, 'h'                     },
-                { "version",             no_argument,       NULL, ARG_VERSION             },
+                { "help",        no_argument, NULL, 'h'          },
+                { "version",     no_argument, NULL, ARG_VERSION  },
                 {}
         };
 
@@ -61,12 +58,13 @@ static int parse_argv(int argc, char *argv[]) {
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "+h", options, NULL)) >= 0) {
+        while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
 
                 switch (c) {
 
                 case 'h':
-                        return help();
+                        help();
+                        return 0;
 
                 case ARG_VERSION:
                         puts(PACKAGE_STRING);
@@ -79,7 +77,6 @@ static int parse_argv(int argc, char *argv[]) {
                 default:
                         assert_not_reached("Unhandled option");
                 }
-        }
 
         return 1;
 }
@@ -268,21 +265,17 @@ static int bootctl_main(int argc, char *argv[]) {
 }
 
 int main(int argc, char *argv[]) {
-        int r, retval = EXIT_FAILURE;
+        int r;
 
         log_parse_environment();
         log_open();
 
         r = parse_argv(argc, argv);
-        if (r < 0)
-                goto finish;
-        else if (r == 0) {
-                retval = EXIT_SUCCESS;
+        if (r <= 0)
                 goto finish;
-        }
 
         r = bootctl_main(argc, argv);
-        retval = r < 0 ? EXIT_FAILURE : r;
-finish:
-        return retval;
+
+ finish:
+        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
 }
index 77f3d19..8ef5ad1 100644 (file)
@@ -48,7 +48,7 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <stdbool.h>
-#include <systemd/sd-journal.h>
+#include "systemd/sd-journal.h"
 
 #include "util.h"
 #include "fileio.h"
@@ -124,17 +124,11 @@ static void parse_conf(void) {
                 { "Bootchart", "ControlGroup",     config_parse_bool,   0, &arg_show_cgroup },
                 { NULL, NULL, NULL, 0, NULL }
         };
-        _cleanup_fclose_ FILE *f;
-        int r;
 
-        f = fopen(BOOTCHART_CONF, "re");
-        if (!f)
-                return;
-
-        r = config_parse(NULL, BOOTCHART_CONF, f,
-                         NULL, config_item_table_lookup, (void*) items, true, false, NULL);
-        if (r < 0)
-                log_warning("Failed to parse configuration file: %s", strerror(-r));
+        config_parse(NULL, BOOTCHART_CONF, NULL,
+                     NULL,
+                     config_item_table_lookup, items,
+                     true, false, true, NULL);
 
         if (init != NULL)
                 strscpy(arg_init_path, sizeof(arg_init_path), init);
@@ -169,29 +163,31 @@ static void help(void) {
                 DEFAULT_INIT);
 }
 
-static int parse_args(int argc, char *argv[]) {
-        static struct option options[] = {
-                {"rel",       no_argument,        NULL,  'r'},
-                {"freq",      required_argument,  NULL,  'f'},
-                {"samples",   required_argument,  NULL,  'n'},
-                {"pss",       no_argument,        NULL,  'p'},
-                {"output",    required_argument,  NULL,  'o'},
-                {"init",      required_argument,  NULL,  'i'},
-                {"no-filter", no_argument,        NULL,  'F'},
-                {"cmdline",   no_argument,        NULL,  'C'},
-                {"control-group", no_argument,    NULL,  'c'},
-                {"help",      no_argument,        NULL,  'h'},
-                {"scale-x",   required_argument,  NULL,  'x'},
-                {"scale-y",   required_argument,  NULL,  'y'},
-                {"entropy",   no_argument,        NULL,  'e'},
-                {NULL, 0, NULL, 0}
+static int parse_argv(int argc, char *argv[]) {
+        static const struct option options[] = {
+                {"rel",           no_argument,        NULL,  'r'},
+                {"freq",          required_argument,  NULL,  'f'},
+                {"samples",       required_argument,  NULL,  'n'},
+                {"pss",           no_argument,        NULL,  'p'},
+                {"output",        required_argument,  NULL,  'o'},
+                {"init",          required_argument,  NULL,  'i'},
+                {"no-filter",     no_argument,        NULL,  'F'},
+                {"cmdline",       no_argument,        NULL,  'C'},
+                {"control-group", no_argument,        NULL,  'c'},
+                {"help",          no_argument,        NULL,  'h'},
+                {"scale-x",       required_argument,  NULL,  'x'},
+                {"scale-y",       required_argument,  NULL,  'y'},
+                {"entropy",       no_argument,        NULL,  'e'},
+                {}
         };
-        int c;
+        int c, r;
 
-        while ((c = getopt_long(argc, argv, "erpf:n:o:i:FCchx:y:", options, NULL)) >= 0) {
-                int r;
+        if (getpid() == 1)
+                opterr = 0;
 
+        while ((c = getopt_long(argc, argv, "erpf:n:o:i:FCchx:y:", options, NULL)) >= 0)
                 switch (c) {
+
                 case 'r':
                         arg_relative = true;
                         break;
@@ -244,19 +240,22 @@ static int parse_args(int argc, char *argv[]) {
                         break;
                 case 'h':
                         help();
-                        exit (EXIT_SUCCESS);
-                        break;
+                        return 0;
+                case '?':
+                        if (getpid() != 1)
+                                return -EINVAL;
+                        else
+                                return 0;
                 default:
-                        break;
+                        assert_not_reached("Unhandled option code.");
                 }
-        }
 
-        if (arg_hz <= 0.0) {
-                fprintf(stderr, "Error: Frequency needs to be > 0\n");
+        if (arg_hz <= 0) {
+                log_error("Frequency needs to be > 0");
                 return -EINVAL;
         }
 
-        return 0;
+        return 1;
 }
 
 static void do_journal_append(char *file) {
@@ -317,12 +316,13 @@ int main(int argc, char *argv[]) {
         time_t t = 0;
         int r;
         struct rlimit rlim;
+        bool has_procfs = false;
 
         parse_conf();
 
-        r = parse_args(argc, argv);
-        if (r < 0)
-                return EXIT_FAILURE;
+        r = parse_argv(argc, argv);
+        if (r <= 0)
+                return r == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
 
         /*
          * If the kernel executed us through init=/usr/lib/systemd/systemd-bootchart, then
@@ -356,6 +356,16 @@ int main(int argc, char *argv[]) {
 
         log_uptime();
 
+        if (graph_start < 0.0) {
+                fprintf(stderr,
+                        "Failed to setup graph start time.\n\nThe system uptime "
+                        "probably includes time that the system was suspended. "
+                        "Use --rel to bypass this issue.\n");
+                exit (EXIT_FAILURE);
+        }
+
+        has_procfs = access("/proc/vmstat", F_OK) == 0;
+
         LIST_HEAD_INIT(head);
 
         /* main program loop */
@@ -370,8 +380,8 @@ int main(int argc, char *argv[]) {
 
                 sampledata = new0(struct list_sample_data, 1);
                 if (sampledata == NULL) {
-                        log_error("Failed to allocate memory for a node: %m");
-                        return -1;
+                        log_oom();
+                        return EXIT_FAILURE;
                 }
 
                 sampledata->sampletime = gettime_ns();
@@ -387,16 +397,16 @@ int main(int argc, char *argv[]) {
                 if (sysfd < 0)
                         sysfd = open("/sys", O_RDONLY|O_CLOEXEC);
 
-                if (!build)
-                        parse_env_file("/etc/os-release", NEWLINE,
-                                       "PRETTY_NAME", &build,
-                                       NULL);
+                if (!build) {
+                        if (parse_env_file("/etc/os-release", NEWLINE, "PRETTY_NAME", &build, NULL) == -ENOENT)
+                                parse_env_file("/usr/lib/os-release", NEWLINE, "PRETTY_NAME", &build, NULL);
+                }
 
-                /* wait for /proc to become available, discarding samples */
-                if (graph_start <= 0.0)
-                        log_uptime();
-                else
+                if (has_procfs)
                         log_sample(samples, &sampledata);
+                else
+                        /* wait for /proc to become available, discarding samples */
+                        has_procfs = access("/proc/vmstat", F_OK) == 0;
 
                 sample_stop = gettime_ns();
 
index e071983..2d2ea42 100644 (file)
@@ -34,6 +34,7 @@
 #include <time.h>
 
 #include "util.h"
+#include "time-util.h"
 #include "strxcpyx.h"
 #include "store.h"
 #include "bootchart.h"
@@ -54,30 +55,25 @@ double gettime_ns(void) {
 
         clock_gettime(CLOCK_MONOTONIC, &n);
 
-        return (n.tv_sec + (n.tv_nsec / 1000000000.0));
+        return (n.tv_sec + (n.tv_nsec / (double) NSEC_PER_SEC));
 }
 
-void log_uptime(void) {
-        _cleanup_fclose_ FILE *f = NULL;
-        char str[32];
-        double uptime;
-
-        f = fopen("/proc/uptime", "re");
-
-        if (!f)
-                return;
-        if (!fscanf(f, "%s %*s", str))
-                return;
-
-        uptime = strtod(str, NULL);
+static double gettime_up(void) {
+        struct timespec n;
 
-        log_start = gettime_ns();
+        clock_gettime(CLOCK_BOOTTIME, &n);
+        return (n.tv_sec + (n.tv_nsec / (double) NSEC_PER_SEC));
+}
 
-        /* start graph at kernel boot time */
+void log_uptime(void) {
         if (arg_relative)
-                graph_start = log_start;
-        else
+                graph_start = log_start = gettime_ns();
+        else {
+                double uptime = gettime_up();
+
+                log_start = gettime_ns();
                 graph_start = log_start - uptime;
+        }
 }
 
 static char *bufgetline(char *buf) {
index a53f98a..135883f 100644 (file)
@@ -80,6 +80,8 @@ static void svg_header(void) {
         double h;
         struct list_sample_data *sampledata_last;
 
+        assert(head);
+
         sampledata = head;
         LIST_FIND_TAIL(link, sampledata, head);
         sampledata_last = head;
@@ -123,6 +125,7 @@ static void svg_header(void) {
         svg("<defs>\n  <style type=\"text/css\">\n    <![CDATA[\n");
 
         svg("      rect       { stroke-width: 1; }\n");
+        svg("      rect.bg    { fill: rgb(255,255,255); }\n");
         svg("      rect.cpu   { fill: rgb(64,64,240); stroke-width: 0; fill-opacity: 0.7; }\n");
         svg("      rect.wait  { fill: rgb(240,240,0); stroke-width: 0; fill-opacity: 0.7; }\n");
         svg("      rect.bi    { fill: rgb(240,128,128); stroke-width: 0; fill-opacity: 0.7; }\n");
@@ -878,21 +881,21 @@ static struct ps_struct *get_next_ps(struct ps_struct *ps) {
         return NULL;
 }
 
-static int ps_filter(struct ps_struct *ps) {
+static bool ps_filter(struct ps_struct *ps) {
         if (!arg_filter)
-                return 0;
+                return false;
 
         /* can't draw data when there is only 1 sample (need start + stop) */
         if (ps->first == ps->last)
-                return -1;
+                return true;
 
         /* don't filter kthreadd */
         if (ps->pid == 2)
-                return 0;
+                return false;
 
         /* drop stuff that doesn't use any real CPU time */
         if (ps->total <= 0.001)
-                return -1;
+                return true;
 
         return 0;
 }
@@ -1270,6 +1273,7 @@ void svg_do(const char *build) {
 
         /* after this, we can draw the header with proper sizing */
         svg_header();
+        svg("<rect class=\"bg\" width=\"100%%\" height=\"100%%\" />\n\n");
 
         svg("<g transform=\"translate(10,400)\">\n");
         svg_io_bi_bar();
diff --git a/src/bus-driverd/bus-driverd.c b/src/bus-driverd/bus-driverd.c
deleted file mode 100644 (file)
index 5405960..0000000
+++ /dev/null
@@ -1,957 +0,0 @@
-/***
-  This file is part of systemd.
-
-  Copyright 2013 Daniel Mack
-
-  systemd is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation; either version 2.1 of the License, or
-  (at your option) any later version.
-
-  systemd is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdlib.h>
-#include <stdbool.h>
-#include <unistd.h>
-#include <getopt.h>
-#include <locale.h>
-#include <string.h>
-#include <poll.h>
-#include <netdb.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <sys/timex.h>
-#include <sys/utsname.h>
-
-#include "kdbus.h"
-#include "sd-bus.h"
-#include "bus-internal.h"
-#include "sd-daemon.h"
-#include "sd-event.h"
-#include "event-util.h"
-#include "bus-util.h"
-#include "bus-error.h"
-#include "bus-message.h"
-#include "bus-kernel.h"
-#include "socket-util.h"
-#include "util.h"
-#include "build.h"
-#include "strv.h"
-#include "sd-id128.h"
-#include "async.h"
-#include "hashmap.h"
-#include "def.h"
-#include "unit-name.h"
-#include "bus-control.h"
-#include "cgroup-util.h"
-
-#define CLIENTS_MAX 1024
-#define MATCHES_MAX 1024
-
-typedef struct Match Match;
-typedef struct Client Client;
-typedef struct Context Context;
-
-struct Match {
-        Client *client;
-        char *match;
-        uint64_t cookie;
-        LIST_FIELDS(Match, matches);
-};
-
-struct Client {
-        Context *context;
-        uint64_t id;
-        uint64_t next_cookie;
-        Hashmap *matches;
-        unsigned n_matches;
-        char *watch;
-};
-
-struct Context {
-        sd_bus *bus;
-        sd_event *event;
-        Hashmap *clients;
-};
-
-static void match_free(Match *m) {
-
-        if (!m)
-                return;
-
-        if (m->client) {
-                Match *first;
-
-                first = hashmap_get(m->client->matches, m->match);
-                LIST_REMOVE(matches, first, m);
-                if (first)
-                        assert_se(hashmap_replace(m->client->matches, first->match, first) >= 0);
-                else
-                        hashmap_remove(m->client->matches, m->match);
-
-                m->client->n_matches--;
-        }
-
-        free(m->match);
-        free(m);
-}
-
-static int match_new(Client *c, struct bus_match_component *components, unsigned n_components, Match **_m) {
-        Match *m, *first;
-        int r;
-
-        assert(c);
-        assert(_m);
-
-        r = hashmap_ensure_allocated(&c->matches, string_hash_func, string_compare_func);
-        if (r < 0)
-                return r;
-
-        m = new0(Match, 1);
-        if (!m)
-                return -ENOMEM;
-
-        m->match = bus_match_to_string(components, n_components);
-        if (!m->match) {
-                r = -ENOMEM;
-                goto fail;
-        }
-
-        m->cookie = ++c->next_cookie;
-
-        first = hashmap_get(c->matches, m->match);
-        LIST_PREPEND(matches, first, m);
-        r = hashmap_replace(c->matches, m->match, first);
-        if (r < 0) {
-                LIST_REMOVE(matches, first, m);
-                goto fail;
-        }
-
-        m->client = c;
-        c->n_matches++;
-
-        *_m = m;
-        m = NULL;
-
-        return 0;
-
-fail:
-        match_free(m);
-        return r;
-}
-
-static int on_name_owner_changed(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error);
-
-static void client_free(Client *c) {
-        Match *m;
-
-        if (!c)
-                return;
-
-        if (c->context) {
-                if (c->watch)
-                        sd_bus_remove_match(c->context->bus, c->watch, on_name_owner_changed, c);
-
-                assert_se(hashmap_remove(c->context->clients, &c->id) == c);
-        }
-
-        while ((m = hashmap_first(c->matches)))
-                match_free(m);
-
-        hashmap_free(c->matches);
-        free(c->watch);
-
-        free(c);
-}
-
-static int on_name_owner_changed(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
-        Client *c = userdata;
-
-        assert(bus);
-        assert(m);
-
-        client_free(c);
-        return 0;
-}
-
-static int client_acquire(Context *context, uint64_t id, Client **_c) {
-        char *watch = NULL;
-        Client *c;
-        int r;
-
-        assert(context);
-        assert(_c);
-
-        c = hashmap_get(context->clients, &id);
-        if (c) {
-                *_c = c;
-                return 0;
-        }
-
-        if (hashmap_size(context->clients) >= CLIENTS_MAX)
-                return -ENOBUFS;
-
-        r = hashmap_ensure_allocated(&context->clients, uint64_hash_func, uint64_compare_func);
-        if (r < 0)
-                return r;
-
-        c = new0(Client, 1);
-        if (!c)
-                return -ENOMEM;
-
-        c->id = id;
-
-        r = hashmap_put(context->clients, &c->id, c);
-        if (r < 0)
-                goto fail;
-
-        c->context = context;
-
-        if (asprintf(&watch,
-                     "type='signal',"
-                     "sender='org.freedesktop.DBus',"
-                     "path='/org/freedesktop/DBus',"
-                     "interface='org.freedesktop.DBus',"
-                     "member='NameOwnerChanged',"
-                     "arg0=':1.%llu'", (unsigned long long) id) < 0) {
-                r = -ENOMEM;
-                goto fail;
-        }
-
-        r = sd_bus_add_match(context->bus, watch, on_name_owner_changed, c);
-        if (r < 0) {
-                free(watch);
-                goto fail;
-        }
-
-        c->watch = watch;
-
-        *_c = c;
-        return 0;
-
-fail:
-        client_free(c);
-        return r;
-}
-
-static int driver_add_match(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
-
-        struct bus_match_component *components = NULL;
-        Context *context = userdata;
-        unsigned n_components = 0;
-        Match *m = NULL;
-        Client *c = NULL;
-        char *arg0;
-        uint64_t id;
-        int r;
-
-        assert(bus);
-        assert(message);
-        assert(context);
-
-        r = sd_bus_message_read(message, "s", &arg0);
-        if (r < 0)
-                return r;
-
-        r = bus_kernel_parse_unique_name(message->sender, &id);
-        if (r < 0)
-                return r;
-
-        r = client_acquire(context, id, &c);
-        if (r == -ENOBUFS)
-                return sd_bus_error_setf(error, SD_BUS_ERROR_LIMITS_EXCEEDED, "Reached limit of %u clients", CLIENTS_MAX);
-        if (r < 0)
-                return r;
-
-        if (c->n_matches >= MATCHES_MAX) {
-                r = sd_bus_error_setf(error, SD_BUS_ERROR_LIMITS_EXCEEDED, "Reached limit of %u matches per client", MATCHES_MAX);
-                goto fail;
-        }
-
-        r = bus_match_parse(arg0, &components, &n_components);
-        if (r < 0) {
-                r = sd_bus_error_setf(error, SD_BUS_ERROR_MATCH_RULE_INVALID, "Match rule \"%s\" is not valid", arg0);
-                goto fail;
-        }
-
-        r = match_new(c, components, n_components, &m);
-        if (r < 0)
-                goto fail;
-
-        r = bus_add_match_internal_kernel(bus, id, components, n_components, m->cookie);
-        if (r < 0)
-                goto fail;
-
-        bus_match_parse_free(components, n_components);
-
-        return sd_bus_reply_method_return(message, NULL);
-
-fail:
-        bus_match_parse_free(components, n_components);
-
-        match_free(m);
-
-        if (c->n_matches <= 0)
-                client_free(c);
-
-        return r;
-}
-
-static int driver_remove_match(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
-
-        struct bus_match_component *components = NULL;
-        _cleanup_free_ char *normalized = NULL;
-        Context *context = userdata;
-        unsigned n_components = 0;
-        Client *c = NULL;
-        Match *m = NULL;
-        char *arg0;
-        uint64_t id;
-        int r;
-
-        assert(bus);
-        assert(message);
-        assert(context);
-
-        r = sd_bus_message_read(message, "s", &arg0);
-        if (r < 0)
-                return r;
-
-        r = bus_kernel_parse_unique_name(message->sender, &id);
-        if (r < 0)
-                return r;
-
-        c = hashmap_get(context->clients, &id);
-        if (!c)
-                return sd_bus_error_setf(error, SD_BUS_ERROR_MATCH_RULE_NOT_FOUND, "You have not registered any matches.");
-
-        r = bus_match_parse(arg0, &components, &n_components);
-        if (r < 0) {
-                r = sd_bus_error_setf(error, SD_BUS_ERROR_MATCH_RULE_INVALID, "Match rule \"%s\" is not valid", arg0);
-                goto finish;
-        }
-
-        normalized = bus_match_to_string(components, n_components);
-        if (!normalized) {
-                r = -ENOMEM;
-                goto finish;
-        }
-
-        m = hashmap_get(c->matches, normalized);
-        if (!m) {
-                r = sd_bus_error_setf(error, SD_BUS_ERROR_MATCH_RULE_NOT_FOUND, "Match rule \"%s\" not found.", normalized);
-                goto finish;
-        }
-
-        bus_remove_match_internal_kernel(bus, id, m->cookie);
-        match_free(m);
-
-        r = sd_bus_reply_method_return(message, NULL);
-
-finish:
-        bus_match_parse_free(components, n_components);
-
-        if (c->n_matches <= 0)
-                client_free(c);
-
-        return r;
-}
-
-static int get_creds_by_name(sd_bus *bus, const char *name, uint64_t mask, sd_bus_creds **_creds, sd_bus_error *error) {
-        _cleanup_bus_creds_unref_ sd_bus_creds *c = NULL;
-        int r;
-
-        assert(bus);
-        assert(name);
-        assert(_creds);
-
-        assert_return(service_name_is_valid(name), -EINVAL);
-
-        r = sd_bus_get_owner(bus, name, mask, &c);
-        if (r == -ENOENT || r == -ENXIO)
-                return sd_bus_error_setf(error, SD_BUS_ERROR_NAME_HAS_NO_OWNER, "Name %s is currently not owned by anyone.", name);
-        if (r < 0)
-                return r;
-
-        if ((c->mask & mask) != mask)
-                return -ENOTSUP;
-
-        *_creds = c;
-        c = NULL;
-
-        return 0;
-}
-
-
-static int get_creds_by_message(sd_bus *bus, sd_bus_message *m, uint64_t mask, sd_bus_creds **_creds, sd_bus_error *error) {
-        const char *name;
-        int r;
-
-        assert(bus);
-        assert(m);
-        assert(_creds);
-
-        r = sd_bus_message_read(m, "s", &name);
-        if (r < 0)
-                return r;
-
-        return get_creds_by_name(bus, name, mask, _creds, error);
-}
-
-static int driver_get_security_context(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
-        _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
-        _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
-        int r;
-
-        r = get_creds_by_message(bus, m, SD_BUS_CREDS_SELINUX_CONTEXT, &creds, error);
-        if (r < 0)
-                return r;
-
-        r = sd_bus_message_new_method_return(m, &reply);
-        if (r < 0)
-                return r;
-
-        r = sd_bus_message_append_array(reply, 'y', creds->label, strlen(creds->label));
-        if (r < 0)
-                return r;
-
-        return sd_bus_send(bus, reply, NULL);
-}
-
-static int driver_get_pid(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
-        _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
-        int r;
-
-        r = get_creds_by_message(bus, m, SD_BUS_CREDS_PID, &creds, error);
-        if (r < 0)
-                return r;
-
-        return sd_bus_reply_method_return(m, "u", (uint32_t) creds->pid);
-}
-
-static int driver_get_user(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
-        _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
-        int r;
-
-        r = get_creds_by_message(bus, m, SD_BUS_CREDS_UID, &creds, error);
-        if (r < 0)
-                return r;
-
-        return sd_bus_reply_method_return(m, "u", (uint32_t) creds->uid);
-}
-
-static int driver_get_name_owner(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
-        _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
-        const char *name;
-        int r;
-
-        r = sd_bus_message_read(m, "s", &name);
-        if (r < 0)
-                return r;
-
-        /* Here's a special exception for compatibility with dbus1:
-         * the bus name of the driver is owned by itself, not by a
-         * unique ID. */
-        if (streq(name, "org.freedesktop.DBus"))
-                return sd_bus_reply_method_return(m, "s", "org.freedesktop.DBus");
-
-        r = get_creds_by_name(bus, name, SD_BUS_CREDS_UNIQUE_NAME, &creds, error);
-        if (r < 0)
-                return r;
-
-        return sd_bus_reply_method_return(m, "s", creds->unique_name);
-}
-
-static int driver_get_id(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
-        sd_id128_t server_id;
-        char buf[SD_ID128_STRING_MAX];
-        int r;
-
-        r = sd_bus_get_server_id(bus, &server_id);
-        if (r < 0)
-                return r;
-
-        return sd_bus_reply_method_return(m, "s", sd_id128_to_string(server_id, buf));
-}
-
-static int driver_hello(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
-        return sd_bus_reply_method_return(m, "s", m->sender);
-}
-
-static int return_strv(sd_bus *bus, sd_bus_message *m, char **l) {
-        _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
-        int r;
-
-        r = sd_bus_message_new_method_return(m, &reply);
-        if (r < 0)
-                return r;
-
-        r = sd_bus_message_append_strv(reply, l);
-        if (r < 0)
-                return r;
-
-        return sd_bus_send(bus, reply, NULL);
-}
-
-static int driver_list_names(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
-        _cleanup_strv_free_ char **names = NULL;
-        int r;
-
-        r = sd_bus_list_names(bus, &names, NULL);
-        if (r < 0)
-                return r;
-
-        /* Let's sort the names list to make it stable */
-        strv_sort(names);
-
-        return return_strv(bus, m, names);
-}
-
-static int driver_list_activatable_names(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
-        _cleanup_strv_free_ char **names = NULL;
-        int r;
-
-        r = sd_bus_list_names(bus, NULL, &names);
-        if (r < 0)
-                return r;
-
-        /* Let's sort the names list to make it stable */
-        strv_sort(names);
-
-        return return_strv(bus, m, names);
-}
-
-static int driver_list_queued_owners(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
-        struct kdbus_cmd_name_list cmd = {};
-        struct kdbus_name_list *name_list;
-        struct kdbus_cmd_name *name;
-        _cleanup_strv_free_ char **owners = NULL;
-        char *arg0;
-        int r;
-
-        r = sd_bus_message_read(m, "s", &arg0);
-        if (r < 0)
-                return r;
-
-        assert_return(service_name_is_valid(arg0), -EINVAL);
-
-        cmd.flags = KDBUS_NAME_LIST_QUEUED;
-
-        r = ioctl(bus->input_fd, KDBUS_CMD_NAME_LIST, &cmd);
-        if (r < 0)
-                return -errno;
-
-        name_list = (struct kdbus_name_list *) ((uint8_t *) bus->kdbus_buffer + cmd.offset);
-
-        KDBUS_ITEM_FOREACH(name, name_list, names) {
-                char *n;
-
-                if (name->size <= sizeof(*name))
-                        continue;
-
-                if (!streq(name->name, arg0))
-                        continue;
-
-                if (asprintf(&n, ":1.%llu", (unsigned long long) name->owner_id) < 0)
-                        return -ENOMEM;
-
-                r = strv_push(&owners, n);
-                if (r < 0) {
-                        free(n);
-                        return -ENOMEM;
-                }
-        }
-
-        r = ioctl(bus->input_fd, KDBUS_CMD_FREE, &cmd.offset);
-        if (r < 0)
-                return -errno;
-
-        return return_strv(bus, m, owners);
-}
-
-static int driver_name_has_owner(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
-        const char *name;
-        int r;
-
-        r = sd_bus_message_read(m, "s", &name);
-        if (r < 0)
-                return r;
-
-        assert_return(service_name_is_valid(name), -EINVAL);
-
-        r = sd_bus_get_owner(bus, name, 0, NULL);
-        if (r < 0 && r != -ENOENT && r != -ENXIO)
-                return r;
-
-        return sd_bus_reply_method_return(m, "b", r >= 0);
-}
-
-static int driver_request_name(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
-        struct kdbus_cmd_name *n;
-        uint32_t flags;
-        size_t size, l;
-        uint64_t id;
-        const char *name;
-        int r;
-
-        r = sd_bus_message_read(m, "su", &name, &flags);
-        if (r < 0)
-                return r;
-
-        assert_return(service_name_is_valid(name), -EINVAL);
-        assert_return((flags & ~(BUS_NAME_ALLOW_REPLACEMENT|BUS_NAME_REPLACE_EXISTING|BUS_NAME_DO_NOT_QUEUE)) == 0, -EINVAL);
-
-        l = strlen(name);
-        size = offsetof(struct kdbus_cmd_name, name) + l + 1;
-        n = alloca0(size);
-        n->size = size;
-        memcpy(n->name, name, l+1);
-        kdbus_translate_request_name_flags(flags, (uint64_t *) &n->flags);
-
-        /* This function is open-coded because we request the name 'on behalf'
-         * of the requesting connection */
-        r = bus_kernel_parse_unique_name(m->sender, &id);
-        if (r < 0)
-                return r;
-
-        n->owner_id = id;
-
-        r = ioctl(bus->input_fd, KDBUS_CMD_NAME_ACQUIRE, n);
-        if (r < 0) {
-                if (errno == EEXIST)
-                        return sd_bus_reply_method_return(m, "u", BUS_NAME_EXISTS);
-                if (errno == EALREADY)
-                        return sd_bus_reply_method_return(m, "u", BUS_NAME_ALREADY_OWNER);
-
-                return -errno;
-        }
-
-        if (n->flags & KDBUS_NAME_IN_QUEUE)
-                return sd_bus_reply_method_return(m, "u", BUS_NAME_IN_QUEUE);
-
-        return sd_bus_reply_method_return(m, "u", BUS_NAME_PRIMARY_OWNER);
-}
-
-static int driver_release_name(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
-        struct kdbus_cmd_name *n;
-        const char *name;
-        size_t l, size;
-        uint64_t id;
-        int r;
-
-        r = sd_bus_message_read(m, "s", &name);
-        if (r < 0)
-                return r;
-
-        assert_return(service_name_is_valid(name), -EINVAL);
-
-        l = strlen(name);
-        size = offsetof(struct kdbus_cmd_name, name) + l + 1;
-        n = alloca0(size);
-        n->size = size;
-        memcpy(n->name, name, l+1);
-
-        /* This function is open-coded because we request the name 'on behalf'
-         * of the requesting connection */
-        r = bus_kernel_parse_unique_name(m->sender, &id);
-        if (r < 0)
-                return r;
-
-        n->owner_id = id;
-
-        r = ioctl(bus->input_fd, KDBUS_CMD_NAME_RELEASE, n);
-        if (r < 0) {
-                if (errno == ESRCH)
-                        return sd_bus_reply_method_return(m, "u", BUS_NAME_NON_EXISTENT);
-                if (errno == EADDRINUSE)
-                        return sd_bus_reply_method_return(m, "u", BUS_NAME_NOT_OWNER);
-                return -errno;
-        }
-
-        return sd_bus_reply_method_return(m, "u", BUS_NAME_RELEASED);
-}
-
-static int driver_start_service_by_name(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
-        _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
-        _cleanup_strv_free_ char **t = NULL;
-        _cleanup_free_ char *path = NULL;
-        uint32_t flags;
-        char *name, *u;
-        int r;
-
-        r = sd_bus_message_read(m, "su", &name, &flags);
-        if (r < 0)
-                return r;
-
-        assert_return(service_name_is_valid(name), -EINVAL);
-        assert_return(flags == 0, -ENOTSUP);
-
-        r = sd_bus_get_owner(bus, name, 0, NULL);
-        if (r >= 0)
-                return sd_bus_reply_method_return(m, "u", BUS_START_REPLY_ALREADY_RUNNING);
-        if (r != -ENOENT)
-                return r;
-
-        u = strappenda(name, ".busname");
-
-        path = unit_dbus_path_from_name(u);
-        if (!path)
-                return -ENOMEM;
-
-        r = sd_bus_get_property_strv(
-                        bus,
-                        "org.freedesktop.systemd1",
-                        path,
-                        "org.freedesktop.systemd1.Unit",
-                        "Triggers",
-                        error,
-                        &t);
-        if (r < 0)
-                return r;
-
-        if (!t || !t[0] || t[1])
-                return sd_bus_error_setf(error, SD_BUS_ERROR_SERVICE_UNKNOWN, "Bus name %s not found.", name);
-
-        r = sd_bus_call_method(
-                        bus,
-                        "org.freedesktop.systemd1",
-                        "/org/freedesktop/systemd1",
-                        "org.freedesktop.systemd1.Manager",
-                        "StartUnit",
-                        error,
-                        &reply,
-                        "ss",
-                        t[0],
-                        "replace");
-        if (r < 0)
-                return r;
-
-        return sd_bus_reply_method_return(m, "u", BUS_START_REPLY_SUCCESS);
-}
-
-static int driver_update_environment(sd_bus*bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
-        _cleanup_bus_message_unref_ sd_bus_message *msg = NULL;
-        _cleanup_strv_free_ char **args = NULL;
-        int r;
-
-        r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "{ss}");
-        if (r < 0)
-                return r;
-
-       while ((r = sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY, "ss")) > 0) {
-                _cleanup_free_ char *s = NULL;
-                const char *key;
-                const char *value;
-
-                r = sd_bus_message_read(m, "ss", &key, &value);
-                if (r < 0)
-                        return r;
-
-                s = strjoin(key, "=", value, NULL);
-                if (!s)
-                        return ENOMEM;
-
-                r  = strv_extend(&args, s);
-                if (r < 0)
-                        return r;
-
-                r = sd_bus_message_exit_container(m);
-                if (r < 0)
-                        return r;
-        }
-
-        r = sd_bus_message_exit_container(m);
-        if (r < 0)
-                return r;
-
-        if (!args)
-                return -EINVAL;
-
-        r = sd_bus_message_new_method_call(
-                        bus,
-                        &msg,
-                        "org.freedesktop.systemd1",
-                        "/org/freedesktop/systemd1",
-                        "org.freedesktop.systemd1.Manager",
-                        "SetEnvironment");
-        if (r < 0)
-                return r;
-
-        r = sd_bus_message_append_strv(msg, args);
-        if (r < 0)
-                return r;
-
-        r = sd_bus_call(bus, msg, 0, NULL, NULL);
-        if (r < 0)
-                return r;
-
-        return sd_bus_reply_method_return(m, NULL);
-}
-
-static int driver_unsupported(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
-        return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "%s() is not supported", sd_bus_message_get_member(m));
-}
-
-static const sd_bus_vtable driver_vtable[] = {
-        SD_BUS_VTABLE_START(0),
-        SD_BUS_METHOD("AddMatch", "s", NULL, driver_add_match, SD_BUS_VTABLE_UNPRIVILEGED),
-        SD_BUS_METHOD("GetConnectionSELinuxSecurityContext", "s", "ay", driver_get_security_context, SD_BUS_VTABLE_UNPRIVILEGED),
-        SD_BUS_METHOD("GetConnectionUnixProcessID", "s", "u", driver_get_pid, SD_BUS_VTABLE_UNPRIVILEGED),
-        SD_BUS_METHOD("GetConnectionUnixUser", "s", "u", driver_get_user, SD_BUS_VTABLE_UNPRIVILEGED),
-        SD_BUS_METHOD("GetId", NULL, "s", driver_get_id, SD_BUS_VTABLE_UNPRIVILEGED),
-        SD_BUS_METHOD("GetNameOwner", "s", "s", driver_get_name_owner, SD_BUS_VTABLE_UNPRIVILEGED),
-        SD_BUS_METHOD("Hello", NULL, "s", driver_hello, SD_BUS_VTABLE_UNPRIVILEGED),
-        SD_BUS_METHOD("ListActivatableNames", NULL, "as", driver_list_activatable_names, SD_BUS_VTABLE_UNPRIVILEGED),
-        SD_BUS_METHOD("ListNames", NULL, "as", driver_list_names, SD_BUS_VTABLE_UNPRIVILEGED),
-        SD_BUS_METHOD("ListQueuedOwners", "s", "as", driver_list_queued_owners, SD_BUS_VTABLE_UNPRIVILEGED),
-        SD_BUS_METHOD("NameHasOwner", "s", "b", driver_name_has_owner, SD_BUS_VTABLE_UNPRIVILEGED),
-        SD_BUS_METHOD("ReleaseName", "s", "u", driver_release_name, SD_BUS_VTABLE_UNPRIVILEGED),
-        SD_BUS_METHOD("ReloadConfig", NULL, NULL, driver_unsupported, SD_BUS_VTABLE_DEPRECATED),
-        SD_BUS_METHOD("RemoveMatch", "s", NULL, driver_remove_match, SD_BUS_VTABLE_UNPRIVILEGED),
-        SD_BUS_METHOD("RequestName", "su", "u", driver_request_name, SD_BUS_VTABLE_UNPRIVILEGED),
-        SD_BUS_METHOD("StartServiceByName", "su", "u", driver_start_service_by_name, SD_BUS_VTABLE_UNPRIVILEGED),
-        SD_BUS_METHOD("UpdateActivationEnvironment", "a{ss}", NULL, driver_update_environment, 0),
-        SD_BUS_SIGNAL("NameAcquired", "s", SD_BUS_VTABLE_DEPRECATED),
-        SD_BUS_SIGNAL("NameLost", "s", SD_BUS_VTABLE_DEPRECATED),
-        SD_BUS_SIGNAL("NameOwnerChanged", "sss", 0),
-        SD_BUS_VTABLE_END
-};
-
-static int find_object(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                void *userdata,
-                void **ret_found,
-                sd_bus_error *ret_error) {
-
-        /* We support the driver interface on exactly two different
-         * paths: the root and the entry point object. This is a bit
-         * different from the original dbus-daemon which supported it
-         * on any path. */
-
-        if (streq_ptr(path, "/"))
-                return 1;
-
-        if (streq_ptr(path, "/org/freedesktop/DBus"))
-                return 1;
-
-        return 0;
-}
-
-static int node_enumerator(
-                sd_bus *bus,
-                const char *path,
-                void *userdata,
-                char ***ret_nodes,
-                sd_bus_error *ret_error) {
-
-        char **l;
-
-        l = strv_new("/", "/org/freedesktop/DBus", NULL);
-        if (!l)
-                return -ENOMEM;
-
-        *ret_nodes = l;
-        return 0;
-}
-
-static int connect_bus(Context *c) {
-        int r;
-
-        assert(c);
-
-        r = sd_bus_default(&c->bus);
-        if (r < 0) {
-                log_error("Failed to create bus: %s", strerror(-r));
-                return r;
-        }
-
-        if (!c->bus->is_kernel) {
-                log_error("Not running on kdbus");
-                return -EPERM;
-        }
-
-        r = sd_bus_add_fallback_vtable(c->bus, "/", "org.freedesktop.DBus", driver_vtable, find_object, c);
-        if (r < 0) {
-                log_error("Failed to add manager object vtable: %s", strerror(-r));
-                return r;
-        }
-
-        r = sd_bus_add_node_enumerator(c->bus, "/", node_enumerator, c);
-        if (r < 0) {
-                log_error("Failed to add node enumerator: %s", strerror(-r));
-                return r;
-        }
-
-        r = sd_bus_request_name(c->bus, "org.freedesktop.DBus", 0);
-        if (r < 0) {
-                log_error("Unable to request name: %s", strerror(-r));
-                return r;
-        }
-
-        r = sd_bus_attach_event(c->bus, c->event, 0);
-        if (r < 0) {
-                log_error("Error while adding bus to event loop: %s", strerror(-r));
-                return r;
-        }
-
-        return 0;
-}
-
-static bool check_idle(void *userdata) {
-        Context *c = userdata;
-        assert(c);
-
-        return hashmap_isempty(c->clients);
-}
-
-int main(int argc, char *argv[]) {
-        Context context = {};
-        Client *c;
-        int r;
-
-        log_set_target(LOG_TARGET_AUTO);
-        log_parse_environment();
-        log_open();
-
-        if (argc != 1) {
-                log_error("This program takes no arguments.");
-                r = -EINVAL;
-                goto finish;
-        }
-
-        r = sd_event_default(&context.event);
-        if (r < 0) {
-                log_error("Failed to allocate event loop: %s", strerror(-r));
-                goto finish;
-        }
-
-        sd_event_set_watchdog(context.event, true);
-
-        r = connect_bus(&context);
-        if (r < 0)
-                goto finish;
-
-        r = bus_event_loop_with_idle(context.event, context.bus, "org.freedesktop.DBus", DEFAULT_EXIT_USEC, check_idle, &context);
-        if (r < 0) {
-                log_error("Failed to run event loop: %s", strerror(-r));
-                goto finish;
-        }
-
-finish:
-        while ((c = hashmap_first(context.clients)))
-                client_free(c);
-
-        sd_bus_unref(context.bus);
-        sd_event_unref(context.event);
-
-        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
-}
diff --git a/src/bus-proxyd/bus-policy.c b/src/bus-proxyd/bus-policy.c
new file mode 100644 (file)
index 0000000..06c16a7
--- /dev/null
@@ -0,0 +1,729 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2013 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "xml.h"
+#include "fileio.h"
+#include "strv.h"
+#include "conf-files.h"
+#include "bus-internal.h"
+#include "bus-policy.h"
+
+static void policy_item_free(PolicyItem *i) {
+        assert(i);
+
+        free(i->interface);
+        free(i->member);
+        free(i->error);
+        free(i->name);
+        free(i->path);
+        free(i);
+}
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(PolicyItem*, policy_item_free);
+
+static int file_load(Policy *p, const char *path) {
+
+        _cleanup_free_ char *c = NULL, *policy_user = NULL, *policy_group = NULL;
+        _cleanup_(policy_item_freep) PolicyItem *i = NULL;
+        void *xml_state = NULL;
+        unsigned n_other = 0;
+        const char *q;
+        int r;
+
+        enum {
+                STATE_OUTSIDE,
+                STATE_BUSCONFIG,
+                STATE_POLICY,
+                STATE_POLICY_CONTEXT,
+                STATE_POLICY_USER,
+                STATE_POLICY_GROUP,
+                STATE_POLICY_OTHER_ATTRIBUTE,
+                STATE_ALLOW_DENY,
+                STATE_ALLOW_DENY_INTERFACE,
+                STATE_ALLOW_DENY_MEMBER,
+                STATE_ALLOW_DENY_ERROR,
+                STATE_ALLOW_DENY_PATH,
+                STATE_ALLOW_DENY_MESSAGE_TYPE,
+                STATE_ALLOW_DENY_NAME,
+                STATE_ALLOW_DENY_OTHER_ATTRIBUTE,
+                STATE_OTHER,
+        } state = STATE_OUTSIDE;
+
+        enum {
+                POLICY_CATEGORY_NONE,
+                POLICY_CATEGORY_DEFAULT,
+                POLICY_CATEGORY_MANDATORY,
+                POLICY_CATEGORY_USER,
+                POLICY_CATEGORY_GROUP
+        } policy_category = POLICY_CATEGORY_NONE;
+
+        unsigned line = 0;
+
+        assert(p);
+
+        r = read_full_file(path, &c, NULL);
+        if (r < 0) {
+                if (r == -ENOENT)
+                        return 0;
+                if (r == -EISDIR)
+                        return r;
+
+                log_error("Failed to load %s: %s", path, strerror(-r));
+                return r;
+        }
+
+        q = c;
+        for (;;) {
+                _cleanup_free_ char *name = NULL;
+                int t;
+
+                t = xml_tokenize(&q, &name, &xml_state, &line);
+                if (t < 0) {
+                        log_error("XML parse failure in %s: %s", path, strerror(-t));
+                        return t;
+                }
+
+                switch (state) {
+
+                case STATE_OUTSIDE:
+
+                        if (t == XML_TAG_OPEN) {
+                                if (streq(name, "busconfig"))
+                                        state = STATE_BUSCONFIG;
+                                else {
+                                        log_error("Unexpected tag %s at %s:%u.", name, path, line);
+                                        return -EINVAL;
+                                }
+
+                        } else if (t == XML_END)
+                                return 0;
+                        else if (t != XML_TEXT || !in_charset(name, WHITESPACE)) {
+                                log_error("Unexpected token (1) at %s:%u.", path, line);
+                                return -EINVAL;
+                        }
+
+                        break;
+
+                case STATE_BUSCONFIG:
+
+                        if (t == XML_TAG_OPEN) {
+                                if (streq(name, "policy")) {
+                                        state = STATE_POLICY;
+                                        policy_category = POLICY_CATEGORY_NONE;
+                                        free(policy_user);
+                                        free(policy_group);
+                                        policy_user = policy_group = NULL;
+                                } else {
+                                        state = STATE_OTHER;
+                                        n_other = 0;
+                                }
+                        } else if (t == XML_TAG_CLOSE_EMPTY ||
+                                   (t == XML_TAG_CLOSE && streq(name, "busconfig")))
+                                state = STATE_OUTSIDE;
+                        else if (t != XML_TEXT || !in_charset(name, WHITESPACE)) {
+                                log_error("Unexpected token (2) at %s:%u.", path, line);
+                                return -EINVAL;
+                        }
+
+                        break;
+
+                case STATE_POLICY:
+
+                        if (t == XML_ATTRIBUTE_NAME) {
+                                if (streq(name, "context"))
+                                        state = STATE_POLICY_CONTEXT;
+                                else if (streq(name, "user"))
+                                        state = STATE_POLICY_USER;
+                                else if (streq(name, "group"))
+                                        state = STATE_POLICY_GROUP;
+                                else {
+                                        if (streq(name, "at_console"))
+                                                log_debug("Attribute %s of <policy> tag unsupported at %s:%u, ignoring.", name, path, line);
+                                        else
+                                                log_warning("Attribute %s of <policy> tag unknown at %s:%u, ignoring.", name, path, line);
+                                        state = STATE_POLICY_OTHER_ATTRIBUTE;
+                                }
+                        } else if (t == XML_TAG_CLOSE_EMPTY ||
+                                   (t == XML_TAG_CLOSE && streq(name, "policy")))
+                                state = STATE_BUSCONFIG;
+                        else if (t == XML_TAG_OPEN) {
+                                PolicyItemType it;
+
+                                if (streq(name, "allow"))
+                                        it = POLICY_ITEM_ALLOW;
+                                else if (streq(name, "deny"))
+                                        it = POLICY_ITEM_DENY;
+                                else {
+                                        log_warning("Unknown tag %s in <policy> %s:%u.", name, path, line);
+                                        return -EINVAL;
+                                }
+
+                                assert(!i);
+                                i = new0(PolicyItem, 1);
+                                if (!i)
+                                        return log_oom();
+
+                                i->type = it;
+                                state = STATE_ALLOW_DENY;
+
+                        } else if (t != XML_TEXT || !in_charset(name, WHITESPACE)) {
+                                log_error("Unexpected token (3) at %s:%u.", path, line);
+                                return -EINVAL;
+                        }
+
+                        break;
+
+                case STATE_POLICY_CONTEXT:
+
+                        if (t == XML_ATTRIBUTE_VALUE) {
+                                if (streq(name, "default")) {
+                                        policy_category = POLICY_CATEGORY_DEFAULT;
+                                        state = STATE_POLICY;
+                                } else if (streq(name, "mandatory")) {
+                                        policy_category = POLICY_CATEGORY_MANDATORY;
+                                        state = STATE_POLICY;
+                                } else {
+                                        log_error("context= parameter %s unknown for <policy> at %s:%u.", name, path, line);
+                                        return -EINVAL;
+                                }
+                        } else {
+                                log_error("Unexpected token (4) at %s:%u.", path, line);
+                                return -EINVAL;
+                        }
+
+                        break;
+
+                case STATE_POLICY_USER:
+
+                        if (t == XML_ATTRIBUTE_VALUE) {
+                                free(policy_user);
+                                policy_user = name;
+                                name = NULL;
+                                policy_category = POLICY_CATEGORY_USER;
+                                state = STATE_POLICY;
+                        } else {
+                                log_error("Unexpected token (5) in %s:%u.", path, line);
+                                return -EINVAL;
+                        }
+
+                        break;
+
+                case STATE_POLICY_GROUP:
+
+                        if (t == XML_ATTRIBUTE_VALUE) {
+                                free(policy_group);
+                                policy_group = name;
+                                name = NULL;
+                                policy_category = POLICY_CATEGORY_GROUP;
+                                state = STATE_POLICY;
+                        } else {
+                                log_error("Unexpected token (6) at %s:%u.", path, line);
+                                return -EINVAL;
+                        }
+
+                        break;
+
+                case STATE_POLICY_OTHER_ATTRIBUTE:
+
+                        if (t == XML_ATTRIBUTE_VALUE)
+                                state = STATE_POLICY;
+                        else {
+                                log_error("Unexpected token (7) in %s:%u.", path, line);
+                                return -EINVAL;
+                        }
+
+                        break;
+
+                case STATE_ALLOW_DENY:
+
+                        assert(i);
+
+                        if (t == XML_ATTRIBUTE_NAME) {
+                                PolicyItemClass ic;
+
+                                if (startswith(name, "send_"))
+                                        ic = POLICY_ITEM_SEND;
+                                else if (startswith(name, "receive_"))
+                                        ic = POLICY_ITEM_RECV;
+                                else if (streq(name, "own"))
+                                        ic = POLICY_ITEM_OWN;
+                                else if (streq(name, "own_prefix"))
+                                        ic = POLICY_ITEM_OWN_PREFIX;
+                                else if (streq(name, "user"))
+                                        ic = POLICY_ITEM_USER;
+                                else if (streq(name, "group"))
+                                        ic = POLICY_ITEM_GROUP;
+                                else if (streq(name, "eavesdrop")) {
+                                        log_debug("Unsupported attribute %s= at %s:%u, ignoring.", name, path, line);
+                                        i->class = POLICY_ITEM_IGNORE;
+                                        state = STATE_ALLOW_DENY_OTHER_ATTRIBUTE;
+                                        break;
+                                } else {
+                                        log_error("Unknown attribute %s= at %s:%u, ignoring.", name, path, line);
+                                        state = STATE_ALLOW_DENY_OTHER_ATTRIBUTE;
+                                        break;
+                                }
+
+                                if (i->class != _POLICY_ITEM_CLASS_UNSET && ic != i->class) {
+                                        log_error("send_ and receive_ fields mixed on same tag at %s:%u.", path, line);
+                                        return -EINVAL;
+                                }
+
+                                i->class = ic;
+
+                                if (ic == POLICY_ITEM_SEND || ic == POLICY_ITEM_RECV) {
+                                        const char *u;
+
+                                        u = strchr(name, '_');
+                                        assert(u);
+
+                                        u++;
+
+                                        if (streq(u, "interface"))
+                                                state = STATE_ALLOW_DENY_INTERFACE;
+                                        else if (streq(u, "member"))
+                                                state = STATE_ALLOW_DENY_MEMBER;
+                                        else if (streq(u, "error"))
+                                                state = STATE_ALLOW_DENY_ERROR;
+                                        else if (streq(u, "path"))
+                                                state = STATE_ALLOW_DENY_PATH;
+                                        else if (streq(u, "type"))
+                                                state = STATE_ALLOW_DENY_MESSAGE_TYPE;
+                                        else if ((streq(u, "destination") && ic == POLICY_ITEM_SEND) ||
+                                                 (streq(u, "sender") && ic == POLICY_ITEM_RECV))
+                                                state = STATE_ALLOW_DENY_NAME;
+                                        else {
+                                                if (streq(u, "requested_reply"))
+                                                        log_debug("Unsupported attribute %s= at %s:%u, ignoring.", name, path, line);
+                                                else
+                                                        log_error("Unknown attribute %s= at %s:%u, ignoring.", name, path, line);
+                                                state = STATE_ALLOW_DENY_OTHER_ATTRIBUTE;
+                                                break;
+                                        }
+                                } else
+                                        state = STATE_ALLOW_DENY_NAME;
+
+                        } else if (t == XML_TAG_CLOSE_EMPTY ||
+                                   (t == XML_TAG_CLOSE && streq(name, i->type == POLICY_ITEM_ALLOW ? "allow" : "deny"))) {
+
+                                if (i->class == _POLICY_ITEM_CLASS_UNSET) {
+                                        log_error("Policy not set at %s:%u.", path, line);
+                                        return -EINVAL;
+                                }
+
+                                if (policy_category == POLICY_CATEGORY_DEFAULT)
+                                        LIST_PREPEND(items, p->default_items, i);
+                                else if (policy_category == POLICY_CATEGORY_MANDATORY)
+                                        LIST_PREPEND(items, p->default_items, i);
+                                else if (policy_category == POLICY_CATEGORY_USER) {
+                                        const char *u = policy_user;
+
+                                        assert_cc(sizeof(uid_t) == sizeof(uint32_t));
+
+                                        r = hashmap_ensure_allocated(&p->user_items, trivial_hash_func, trivial_compare_func);
+                                        if (r < 0)
+                                                return log_oom();
+
+                                        if (!u) {
+                                                log_error("User policy without name");
+                                                return -EINVAL;
+                                        }
+
+                                        r = get_user_creds(&u, &i->uid, NULL, NULL, NULL);
+                                        if (r < 0) {
+                                                log_error("Failed to resolve user %s, ignoring policy: %s", u, strerror(-r));
+                                                free(i);
+                                        } else {
+                                                PolicyItem *first;
+
+                                                first = hashmap_get(p->user_items, UINT32_TO_PTR(i->uid));
+                                                LIST_PREPEND(items, first, i);
+
+                                                r = hashmap_replace(p->user_items, UINT32_TO_PTR(i->uid), first);
+                                                if (r < 0) {
+                                                        LIST_REMOVE(items, first, i);
+                                                        return log_oom();
+                                                }
+                                        }
+
+                                } else if (policy_category == POLICY_CATEGORY_GROUP) {
+                                        const char *g = policy_group;
+
+                                        assert_cc(sizeof(gid_t) == sizeof(uint32_t));
+
+                                        r = hashmap_ensure_allocated(&p->group_items, trivial_hash_func, trivial_compare_func);
+                                        if (r < 0)
+                                                return log_oom();
+
+                                        if (!g) {
+                                                log_error("Group policy without name");
+                                                return -EINVAL;
+                                        }
+
+                                        r = get_group_creds(&g, &i->gid);
+                                        if (r < 0) {
+                                                log_error("Failed to resolve group %s, ignoring policy: %s", g, strerror(-r));
+                                                free(i);
+                                        } else {
+                                                PolicyItem *first;
+
+                                                first = hashmap_get(p->group_items, UINT32_TO_PTR(i->gid));
+                                                LIST_PREPEND(items, first, i);
+
+                                                r = hashmap_replace(p->group_items, UINT32_TO_PTR(i->gid), first);
+                                                if (r < 0) {
+                                                        LIST_REMOVE(items, first, i);
+                                                        return log_oom();
+                                                }
+                                        }
+                                }
+
+                                state = STATE_POLICY;
+                                i = NULL;
+
+                        } else if (t != XML_TEXT || !in_charset(name, WHITESPACE)) {
+                                log_error("Unexpected token (8) at %s:%u.", path, line);
+                                return -EINVAL;
+                        }
+
+                        break;
+
+                case STATE_ALLOW_DENY_INTERFACE:
+
+                        if (t == XML_ATTRIBUTE_VALUE) {
+                                assert(i);
+                                if (i->interface) {
+                                        log_error("Duplicate interface at %s:%u.", path, line);
+                                        return -EINVAL;
+                                }
+
+                                i->interface = name;
+                                name = NULL;
+                                state = STATE_ALLOW_DENY;
+                        } else {
+                                log_error("Unexpected token (9) at %s:%u.", path, line);
+                                return -EINVAL;
+                        }
+
+                        break;
+
+                case STATE_ALLOW_DENY_MEMBER:
+
+                        if (t == XML_ATTRIBUTE_VALUE) {
+                                assert(i);
+                                if (i->member) {
+                                        log_error("Duplicate member in %s:%u.", path, line);
+                                        return -EINVAL;
+                                }
+
+                                i->member = name;
+                                name = NULL;
+                                state = STATE_ALLOW_DENY;
+                        } else {
+                                log_error("Unexpected token (10) in %s:%u.", path, line);
+                                return -EINVAL;
+                        }
+
+                        break;
+
+                case STATE_ALLOW_DENY_ERROR:
+
+                        if (t == XML_ATTRIBUTE_VALUE) {
+                                assert(i);
+                                if (i->error) {
+                                        log_error("Duplicate error in %s:%u.", path, line);
+                                        return -EINVAL;
+                                }
+
+                                i->error = name;
+                                name = NULL;
+                                state = STATE_ALLOW_DENY;
+                        } else {
+                                log_error("Unexpected token (11) in %s:%u.", path, line);
+                                return -EINVAL;
+                        }
+
+                        break;
+
+                case STATE_ALLOW_DENY_PATH:
+
+                        if (t == XML_ATTRIBUTE_VALUE) {
+                                assert(i);
+                                if (i->path) {
+                                        log_error("Duplicate path in %s:%u.", path, line);
+                                        return -EINVAL;
+                                }
+
+                                i->path = name;
+                                name = NULL;
+                                state = STATE_ALLOW_DENY;
+                        } else {
+                                log_error("Unexpected token (12) in %s:%u.", path, line);
+                                return -EINVAL;
+                        }
+
+                        break;
+
+                case STATE_ALLOW_DENY_MESSAGE_TYPE:
+
+                        if (t == XML_ATTRIBUTE_VALUE) {
+                                assert(i);
+
+                                if (i->message_type != 0) {
+                                        log_error("Duplicate message type in %s:%u.", path, line);
+                                        return -EINVAL;
+                                }
+
+                                r = bus_message_type_from_string(name, &i->message_type);
+                                if (r < 0) {
+                                        log_error("Invalid message type in %s:%u.", path, line);
+                                        return -EINVAL;
+                                }
+
+                                state = STATE_ALLOW_DENY;
+                        } else {
+                                log_error("Unexpected token (13) in %s:%u.", path, line);
+                                return -EINVAL;
+                        }
+
+                        break;
+
+                case STATE_ALLOW_DENY_NAME:
+
+                        if (t == XML_ATTRIBUTE_VALUE) {
+                                assert(i);
+                                if (i->name) {
+                                        log_error("Duplicate name in %s:%u.", path, line);
+                                        return -EINVAL;
+                                }
+
+                                i->name = name;
+                                name = NULL;
+                                state = STATE_ALLOW_DENY;
+                        } else {
+                                log_error("Unexpected token (14) in %s:%u.", path, line);
+                                return -EINVAL;
+                        }
+
+                        break;
+
+                case STATE_ALLOW_DENY_OTHER_ATTRIBUTE:
+
+                        if (t == XML_ATTRIBUTE_VALUE)
+                                state = STATE_ALLOW_DENY;
+                        else {
+                                log_error("Unexpected token (15) in %s:%u.", path, line);
+                                return -EINVAL;
+                        }
+
+                        break;
+
+                case STATE_OTHER:
+
+                        if (t == XML_TAG_OPEN)
+                                n_other++;
+                        else if (t == XML_TAG_CLOSE || t == XML_TAG_CLOSE_EMPTY) {
+
+                                if (n_other == 0)
+                                        state = STATE_BUSCONFIG;
+                                else
+                                        n_other--;
+                        }
+
+                        break;
+                }
+        }
+}
+
+int policy_load(Policy *p, char **files) {
+        char **i;
+        int r;
+
+        assert(p);
+
+        STRV_FOREACH(i, files) {
+
+                r = file_load(p, *i);
+                if (r == -EISDIR) {
+                        _cleanup_strv_free_ char **l = NULL;
+                        char **j;
+
+                        r = conf_files_list(&l, ".conf", NULL, *i, NULL);
+                        if (r < 0) {
+                                log_error("Failed to get configuration file list: %s", strerror(-r));
+                                return r;
+                        }
+
+                        STRV_FOREACH(j, l)
+                                file_load(p, *j);
+                }
+
+                /* We ignore all errors but EISDIR, and just proceed. */
+        }
+
+        return 0;
+}
+
+void policy_free(Policy *p) {
+        PolicyItem *i, *first;
+
+        if (!p)
+                return;
+
+        while ((i = p->default_items)) {
+                LIST_REMOVE(items, p->default_items, i);
+                policy_item_free(i);
+        }
+
+        while ((i = p->mandatory_items)) {
+                LIST_REMOVE(items, p->mandatory_items, i);
+                policy_item_free(i);
+        }
+
+        while ((first = hashmap_steal_first(p->user_items))) {
+
+                while ((i = first)) {
+                        LIST_REMOVE(items, first, i);
+                        policy_item_free(i);
+                }
+        }
+
+        while ((first = hashmap_steal_first(p->group_items))) {
+
+                while ((i = first)) {
+                        LIST_REMOVE(items, first, i);
+                        policy_item_free(i);
+                }
+        }
+
+        hashmap_free(p->user_items);
+        hashmap_free(p->group_items);
+
+        p->user_items = p->group_items = NULL;
+}
+
+static void dump_items(PolicyItem *i, const char *prefix) {
+
+        if (!i)
+                return;
+
+        if (!prefix)
+                prefix = "";
+
+        printf("%sType: %s\n"
+               "%sClass: %s\n",
+               prefix, policy_item_type_to_string(i->type),
+               prefix, policy_item_class_to_string(i->class));
+
+        if (i->interface)
+                printf("%sInterface: %s\n",
+                       prefix, i->interface);
+
+        if (i->member)
+                printf("%sMember: %s\n",
+                       prefix, i->member);
+
+        if (i->error)
+                printf("%sError: %s\n",
+                       prefix, i->error);
+
+        if (i->path)
+                printf("%sPath: %s\n",
+                       prefix, i->path);
+
+        if (i->name)
+                printf("%sName: %s\n",
+                       prefix, i->name);
+
+        if (i->message_type != 0)
+                printf("%sMessage Type: %s\n",
+                       prefix, bus_message_type_to_string(i->message_type));
+
+        if (i->uid_valid) {
+                _cleanup_free_ char *user;
+
+                user = uid_to_name(i->uid);
+
+                printf("%sUser: %s\n",
+                       prefix, strna(user));
+        }
+
+        if (i->gid_valid) {
+                _cleanup_free_ char *group;
+
+                group = gid_to_name(i->gid);
+
+                printf("%sGroup: %s\n",
+                       prefix, strna(group));
+        }
+
+        if (i->items_next) {
+                printf("%s%s\n", prefix, draw_special_char(DRAW_DASH));
+                dump_items(i->items_next, prefix);
+        }
+}
+
+static void dump_hashmap_items(Hashmap *h) {
+        PolicyItem *i;
+        Iterator j;
+        void *k;
+
+        HASHMAP_FOREACH_KEY(i, k, h, j) {
+                printf("\t%s Item for %u:\n", draw_special_char(DRAW_ARROW), PTR_TO_UINT(k));
+                dump_items(i, "\t\t");
+        }
+}
+
+noreturn void policy_dump(Policy *p) {
+
+        printf("%s Default Items:\n", draw_special_char(DRAW_ARROW));
+        dump_items(p->default_items, "\t");
+
+        printf("%s Group Items:\n", draw_special_char(DRAW_ARROW));
+        dump_hashmap_items(p->group_items);
+
+        printf("%s User Items:\n", draw_special_char(DRAW_ARROW));
+        dump_hashmap_items(p->user_items);
+
+        printf("%s Mandatory Items:\n", draw_special_char(DRAW_ARROW));
+        dump_items(p->mandatory_items, "\t");
+
+        exit(0);
+}
+
+static const char* const policy_item_type_table[_POLICY_ITEM_TYPE_MAX] = {
+        [_POLICY_ITEM_TYPE_UNSET] = "unset",
+        [POLICY_ITEM_ALLOW] = "allow",
+        [POLICY_ITEM_DENY] = "deny",
+};
+DEFINE_STRING_TABLE_LOOKUP(policy_item_type, PolicyItemType);
+
+static const char* const policy_item_class_table[_POLICY_ITEM_CLASS_MAX] = {
+        [_POLICY_ITEM_CLASS_UNSET] = "unset",
+        [POLICY_ITEM_SEND] = "send",
+        [POLICY_ITEM_RECV] = "recv",
+        [POLICY_ITEM_OWN] = "own",
+        [POLICY_ITEM_OWN_PREFIX] = "own-prefix",
+        [POLICY_ITEM_USER] = "user",
+        [POLICY_ITEM_GROUP] = "group",
+        [POLICY_ITEM_IGNORE] = "ignore",
+};
+DEFINE_STRING_TABLE_LOOKUP(policy_item_class, PolicyItemClass);
diff --git a/src/bus-proxyd/bus-policy.h b/src/bus-proxyd/bus-policy.h
new file mode 100644 (file)
index 0000000..a6ff5c3
--- /dev/null
@@ -0,0 +1,85 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2013 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <inttypes.h>
+
+#include "list.h"
+#include "hashmap.h"
+
+typedef enum PolicyItemType {
+        _POLICY_ITEM_TYPE_UNSET = 0,
+        POLICY_ITEM_ALLOW,
+        POLICY_ITEM_DENY,
+        _POLICY_ITEM_TYPE_MAX,
+        _POLICY_ITEM_TYPE_INVALID = -1,
+} PolicyItemType;
+
+typedef enum PolicyItemClass {
+        _POLICY_ITEM_CLASS_UNSET = 0,
+        POLICY_ITEM_SEND,
+        POLICY_ITEM_RECV,
+        POLICY_ITEM_OWN,
+        POLICY_ITEM_OWN_PREFIX,
+        POLICY_ITEM_USER,
+        POLICY_ITEM_GROUP,
+        POLICY_ITEM_IGNORE,
+        _POLICY_ITEM_CLASS_MAX,
+        _POLICY_ITEM_CLASS_INVALID = -1,
+} PolicyItemClass;
+
+typedef struct PolicyItem PolicyItem;
+
+struct PolicyItem {
+        PolicyItemType type;
+        PolicyItemClass class;
+        char *interface;
+        char *member;
+        char *error;
+        char *path;
+        char *name;
+        uint8_t message_type;
+        uid_t uid;
+        gid_t gid;
+
+        bool uid_valid, gid_valid;
+
+        LIST_FIELDS(PolicyItem, items);
+};
+
+typedef struct Policy {
+        LIST_HEAD(PolicyItem, default_items);
+        LIST_HEAD(PolicyItem, mandatory_items);
+        Hashmap *user_items;
+        Hashmap *group_items;
+} Policy;
+
+int policy_load(Policy *p, char **files);
+void policy_free(Policy *p);
+
+void policy_dump(Policy *p);
+
+const char* policy_item_type_to_string(PolicyItemType t) _const_;
+PolicyItemType policy_item_type_from_string(const char *s) _pure_;
+
+const char* policy_item_class_to_string(PolicyItemClass t) _const_;
+PolicyItemClass policy_item_class_from_string(const char *s) _pure_;
index b9e4d9d..d8d989b 100644 (file)
@@ -4,6 +4,8 @@
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
+  Copyright 2013 Daniel Mack
+  Copyright 2014 Kay Sievers
 
   systemd is free software; you can redistribute it and/or modify it
   under the terms of the GNU Lesser General Public License as published by
 #include "bus-internal.h"
 #include "bus-message.h"
 #include "bus-util.h"
+#include "bus-internal.h"
 #include "build.h"
 #include "strv.h"
 #include "def.h"
+#include "capability.h"
+#include "bus-policy.h"
 
-static const char *arg_address = DEFAULT_SYSTEM_BUS_PATH;
+static char *arg_address = NULL;
 static char *arg_command_line_buffer = NULL;
+static bool arg_drop_privileges = false;
+static char **arg_configuration = NULL;
 
 static int help(void) {
 
         printf("%s [OPTIONS...]\n\n"
                "Connect STDIO or a socket to a given bus address.\n\n"
-               "  -h --help              Show this help\n"
-               "     --version           Show package version\n"
-               "     --address=ADDRESS   Connect to the bus specified by ADDRESS\n"
-               "                         (default: " DEFAULT_SYSTEM_BUS_PATH ")\n",
+               "  -h --help               Show this help\n"
+               "     --version            Show package version\n"
+               "     --drop-privileges    Drop privileges\n"
+               "     --configuration=PATH Configuration file or directory\n"
+               "     --machine=MACHINE    Connect to specified machine\n"
+               "     --address=ADDRESS    Connect to the bus specified by ADDRESS\n"
+               "                          (default: " DEFAULT_SYSTEM_BUS_PATH ")\n",
                program_invocation_short_name);
 
         return 0;
@@ -63,21 +73,27 @@ static int parse_argv(int argc, char *argv[]) {
         enum {
                 ARG_VERSION = 0x100,
                 ARG_ADDRESS,
+                ARG_DROP_PRIVILEGES,
+                ARG_CONFIGURATION,
+                ARG_MACHINE,
         };
 
         static const struct option options[] = {
-                { "help",       no_argument,       NULL, 'h'            },
-                { "version",    no_argument,       NULL, ARG_VERSION    },
-                { "address",    required_argument, NULL, ARG_ADDRESS    },
-                { NULL,         0,                 NULL, 0              }
+                { "help",            no_argument,       NULL, 'h'                 },
+                { "version",         no_argument,       NULL, ARG_VERSION         },
+                { "address",         required_argument, NULL, ARG_ADDRESS         },
+                { "drop-privileges", no_argument,       NULL, ARG_DROP_PRIVILEGES },
+                { "configuration",   required_argument, NULL, ARG_CONFIGURATION   },
+                { "machine",         required_argument, NULL, ARG_MACHINE         },
+                {},
         };
 
-        int c;
+        int c, r;
 
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) {
+        while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
 
                 switch (c) {
 
@@ -90,9 +106,49 @@ static int parse_argv(int argc, char *argv[]) {
                         puts(SYSTEMD_FEATURES);
                         return 0;
 
-                case ARG_ADDRESS:
-                        arg_address = optarg;
+                case ARG_ADDRESS: {
+                        char *a;
+
+                        a = strdup(optarg);
+                        if (!a)
+                                return log_oom();
+
+                        free(arg_address);
+                        arg_address = a;
+                        break;
+                }
+
+                case ARG_DROP_PRIVILEGES:
+                        arg_drop_privileges = true;
+                        break;
+
+                case ARG_CONFIGURATION:
+                        r = strv_extend(&arg_configuration, optarg);
+                        if (r < 0)
+                                return log_oom();
+                        break;
+
+                case ARG_MACHINE: {
+                        _cleanup_free_ char *e = NULL;
+                        char *a;
+
+                        e = bus_address_escape(optarg);
+                        if (!e)
+                                return log_oom();
+
+#ifdef ENABLE_KDBUS
+                        a = strjoin("x-container-kernel:machine=", e, ";x-container-unix:machine=", e, NULL);
+#else
+                        a = strjoin("x-container-unix:machine=", e, NULL);
+#endif
+                        if (!a)
+                                return log_oom();
+
+                        free(arg_address);
+                        arg_address = a;
+
                         break;
+                }
 
                 case '?':
                         return -EINVAL;
@@ -100,18 +156,22 @@ static int parse_argv(int argc, char *argv[]) {
                 default:
                         assert_not_reached("Unhandled option");
                 }
-        }
 
         /* If the first command line argument is only "x" characters
          * we'll write who we are talking to into it, so that "ps" is
          * explanatory */
         arg_command_line_buffer = argv[optind];
-        if (argc > optind + 1 ||
-            (arg_command_line_buffer && arg_command_line_buffer[strspn(arg_command_line_buffer, "x")] != 0)) {
+        if (argc > optind + 1 || (arg_command_line_buffer && !in_charset(arg_command_line_buffer, "x"))) {
                 log_error("Too many arguments");
                 return -EINVAL;
         }
 
+        if (!arg_address) {
+                arg_address = strdup(DEFAULT_SYSTEM_BUS_PATH);
+                if (!arg_address)
+                        return log_oom();
+        }
+
         return 1;
 }
 
@@ -258,6 +318,9 @@ static int process_policy(sd_bus *a, sd_bus *b, sd_bus_message *m) {
         assert(b);
         assert(m);
 
+        if (!a->is_kernel)
+                return 0;
+
         if (!sd_bus_message_is_method_call(m, "org.freedesktop.DBus.Properties", "GetAll"))
                 return 0;
 
@@ -289,6 +352,606 @@ static int process_policy(sd_bus *a, sd_bus *b, sd_bus_message *m) {
         return 1;
 }
 
+static int synthetic_driver_send(sd_bus *b, sd_bus_message *m) {
+        int r;
+
+        assert(b);
+        assert(m);
+
+        r = bus_message_append_sender(m, "org.freedesktop.DBus");
+        if (r < 0)
+                return r;
+
+        r = bus_seal_synthetic_message(b, m);
+        if (r < 0)
+                return r;
+
+        return sd_bus_send(b, m, NULL);
+}
+
+static int synthetic_reply_method_error(sd_bus_message *call, const sd_bus_error *e) {
+        _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
+        int r;
+
+        if (call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
+                return 0;
+
+        r = sd_bus_message_new_method_error(call, &m, e);
+        if (r < 0)
+                return r;
+
+        return synthetic_driver_send(call->bus, m);
+}
+
+static int synthetic_reply_method_errno(sd_bus_message *call, int error, const sd_bus_error *p) {
+
+        _cleanup_bus_error_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
+
+        if (call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
+                return 0;
+
+        if (sd_bus_error_is_set(p))
+                return synthetic_reply_method_error(call, p);
+
+        sd_bus_error_set_errno(&berror, error);
+
+        return synthetic_reply_method_error(call, &berror);
+}
+
+static int synthetic_reply_method_return(sd_bus_message *call, const char *types, ...) {
+        _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
+        int r;
+
+        if (call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
+                return 0;
+
+        r = sd_bus_message_new_method_return(call, &m);
+        if (r < 0)
+                return r;
+
+        if (!isempty(types)) {
+                va_list ap;
+
+                va_start(ap, types);
+                r = bus_message_append_ap(m, types, ap);
+                va_end(ap);
+                if (r < 0)
+                        return r;
+        }
+
+        return synthetic_driver_send(call->bus, m);
+}
+
+static int synthetic_reply_return_strv(sd_bus_message *call, char **l) {
+        _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
+        int r;
+
+        r = sd_bus_message_new_method_return(call, &m);
+        if (r < 0)
+                return synthetic_reply_method_errno(call, r, NULL);
+
+        r = sd_bus_message_append_strv(m, l);
+        if (r < 0)
+                return synthetic_reply_method_errno(call, r, NULL);
+
+        return synthetic_driver_send(call->bus, m);
+}
+
+static int get_creds_by_name(sd_bus *bus, const char *name, uint64_t mask, sd_bus_creds **_creds, sd_bus_error *error) {
+        _cleanup_bus_creds_unref_ sd_bus_creds *c = NULL;
+        int r;
+
+        assert(bus);
+        assert(name);
+        assert(_creds);
+
+        assert_return(service_name_is_valid(name), -EINVAL);
+
+        r = sd_bus_get_owner(bus, name, mask, &c);
+        if (r == -ESRCH || r == -ENXIO)
+                return sd_bus_error_setf(error, SD_BUS_ERROR_NAME_HAS_NO_OWNER, "Name %s is currently not owned by anyone.", name);
+        if (r < 0)
+                return r;
+
+        if ((c->mask & mask) != mask)
+                return -ENOTSUP;
+
+        *_creds = c;
+        c = NULL;
+
+        return 0;
+}
+
+static int get_creds_by_message(sd_bus *bus, sd_bus_message *m, uint64_t mask, sd_bus_creds **_creds, sd_bus_error *error) {
+        const char *name;
+        int r;
+
+        assert(bus);
+        assert(m);
+        assert(_creds);
+
+        r = sd_bus_message_read(m, "s", &name);
+        if (r < 0)
+                return r;
+
+        return get_creds_by_name(bus, name, mask, _creds, error);
+}
+
+static int peer_is_privileged(sd_bus *bus, sd_bus_message *m) {
+        _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
+        uid_t uid;
+        int r;
+
+        r = get_creds_by_message(bus, m, SD_BUS_CREDS_UID, &creds, NULL);
+        if (r < 0)
+                return r;
+
+        r = sd_bus_creds_get_uid(creds, &uid);
+        if (r < 0)
+                return r;
+
+        r = sd_bus_creds_has_effective_cap(creds, CAP_SYS_ADMIN);
+        if (r > 0)
+                return true;
+
+        if (uid == getuid())
+                return true;
+
+        return false;
+}
+
+static int process_driver(sd_bus *a, sd_bus *b, sd_bus_message *m) {
+        int r;
+
+        assert(a);
+        assert(b);
+        assert(m);
+
+        if (!a->is_kernel)
+                return 0;
+
+        if (!streq_ptr(sd_bus_message_get_destination(m), "org.freedesktop.DBus"))
+                return 0;
+
+        if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus.Introspectable", "Introspect")) {
+                if (0 && !isempty(sd_bus_message_get_signature(m, true))) {
+                        _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+
+                        r = sd_bus_error_setf(&error, SD_BUS_ERROR_INVALID_ARGS, "Expected no parameters");
+
+                        return synthetic_reply_method_errno(m, r, &error);
+                }
+
+                return synthetic_reply_method_return(m, "s",
+                        "<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\" "
+                          "\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n"
+                        "<node>\n"
+                        " <interface name=\"org.freedesktop.DBus.Introspectable\">\n"
+                        "  <method name=\"Introspect\">\n"
+                        "   <arg name=\"data\" type=\"s\" direction=\"out\"/>\n"
+                        "  </method>\n"
+                        " </interface>\n"
+                        " <interface name=\"org.freedesktop.DBus\">\n"
+                        "  <method name=\"AddMatch\">\n"
+                        "   <arg type=\"s\" direction=\"in\"/>\n"
+                        "  </method>\n"
+                        "  <method name=\"RemoveMatch\">\n"
+                        "   <arg type=\"s\" direction=\"in\"/>\n"
+                        "  </method>\n"
+                        "  <method name=\"GetConnectionSELinuxSecurityContext\">\n"
+                        "   <arg type=\"s\" direction=\"in\"/>\n"
+                        "   <arg type=\"ay\" direction=\"out\"/>\n"
+                        "  </method>\n"
+                        "  <method name=\"GetConnectionUnixProcessID\">\n"
+                        "   <arg type=\"s\" direction=\"in\"/>\n"
+                        "   <arg type=\"u\" direction=\"out\"/>\n"
+                        "  </method>\n"
+                        "  <method name=\"GetConnectionUnixUser\">\n"
+                        "   <arg type=\"s\" direction=\"in\"/>\n"
+                        "   <arg type=\"u\" direction=\"out\"/>\n"
+                        "  </method>\n"
+                        "  <method name=\"GetId\">\n"
+                        "   <arg type=\"s\" direction=\"out\"/>\n"
+                        "  </method>\n"
+                        "  <method name=\"GetNameOwner\">\n"
+                        "   <arg type=\"s\" direction=\"in\"/>\n"
+                        "   <arg type=\"s\" direction=\"out\"/>\n"
+                        "  </method>\n"
+                        "  <method name=\"Hello\">\n"
+                        "   <arg type=\"s\" direction=\"out\"/>\n"
+                        "  </method>\n"
+                        "  <method name=\"ListActivatableNames\">\n"
+                        "   <arg type=\"as\" direction=\"out\"/>\n"
+                        "  </method>\n"
+                        "  <method name=\"ListNames\">\n"
+                        "   <arg type=\"as\" direction=\"out\"/>\n"
+                        "  </method>\n"
+                        "  <method name=\"ListQueuedOwners\">\n"
+                        "   <arg type=\"s\" direction=\"in\"/>\n"
+                        "   <arg type=\"as\" direction=\"out\"/>\n"
+                        "  </method>\n"
+                        "  <method name=\"NameHasOwner\">\n"
+                        "   <arg type=\"s\" direction=\"in\"/>\n"
+                        "   <arg type=\"b\" direction=\"out\"/>\n"
+                        "  </method>\n"
+                        "  <method name=\"ReleaseName\">\n"
+                        "   <arg type=\"s\" direction=\"in\"/>\n"
+                        "   <arg type=\"u\" direction=\"out\"/>\n"
+                        "  </method>\n"
+                        "  <method name=\"ReloadConfig\">\n"
+                        "  </method>\n"
+                        "  <method name=\"RequestName\">\n"
+                        "   <arg type=\"s\" direction=\"in\"/>\n"
+                        "   <arg type=\"u\" direction=\"in\"/>\n"
+                        "   <arg type=\"u\" direction=\"out\"/>\n"
+                        "  </method>\n"
+                        "  <method name=\"StartServiceByName\">\n"
+                        "   <arg type=\"s\" direction=\"in\"/>\n"
+                        "   <arg type=\"u\" direction=\"in\"/>\n"
+                        "   <arg type=\"u\" direction=\"out\"/>\n"
+                        "  </method>\n"
+                        "  <method name=\"UpdateActivationEnvironment\">\n"
+                        "   <arg type=\"a{ss}\" direction=\"in\"/>\n"
+                        "  </method>\n"
+                        "  <signal name=\"NameAcquired\">\n"
+                        "   <arg type=\"s\"/>\n"
+                        "  </signal>\n"
+                        "  <signal name=\"NameLost\">\n"
+                        "   <arg type=\"s\"/>\n"
+                        "  </signal>\n"
+                        "  <signal name=\"NameOwnerChanged\">\n"
+                        "   <arg type=\"s\"/>\n"
+                        "   <arg type=\"s\"/>\n"
+                        "   <arg type=\"s\"/>\n"
+                        "  </signal>\n"
+                        " </interface>\n"
+                        "</node>\n");
+
+        } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "AddMatch")) {
+                const char *match;
+
+                r = sd_bus_message_read(m, "s", &match);
+                if (r < 0)
+                        return synthetic_reply_method_errno(m, r, NULL);
+
+                r = sd_bus_add_match(a, NULL, match, NULL, NULL);
+                if (r < 0)
+                        return synthetic_reply_method_errno(m, r, NULL);
+
+                return synthetic_reply_method_return(m, NULL);
+
+        } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "RemoveMatch")) {
+                const char *match;
+
+                r = sd_bus_message_read(m, "s", &match);
+                if (r < 0)
+                        return synthetic_reply_method_errno(m, r, NULL);
+
+                r = bus_remove_match_by_string(a, match, NULL, NULL);
+                if (r == 0)
+                        return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_MATCH_RULE_NOT_FOUND, "Match rule not found"));
+                if (r < 0)
+                        return synthetic_reply_method_errno(m, r, NULL);
+
+                return synthetic_reply_method_return(m, NULL);
+
+        } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "GetConnectionSELinuxSecurityContext")) {
+                _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
+
+                r = get_creds_by_message(a, m, SD_BUS_CREDS_SELINUX_CONTEXT, &creds, NULL);
+                if (r < 0)
+                        return synthetic_reply_method_errno(m, r, NULL);
+
+                return synthetic_reply_method_return(m, "y", creds->label, strlen(creds->label));
+
+        } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "GetConnectionUnixProcessID")) {
+                _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
+
+                r = get_creds_by_message(a, m, SD_BUS_CREDS_PID, &creds, NULL);
+                if (r < 0)
+                        return synthetic_reply_method_errno(m, r, NULL);
+
+                return synthetic_reply_method_return(m, "u", (uint32_t) creds->pid);
+
+        } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "GetConnectionUnixUser")) {
+                _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
+
+                r = get_creds_by_message(a, m, SD_BUS_CREDS_UID, &creds, NULL);
+                if (r < 0)
+                        return synthetic_reply_method_errno(m, r, NULL);
+
+                return synthetic_reply_method_return(m, "u", (uint32_t) creds->uid);
+
+        } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "GetId")) {
+                sd_id128_t server_id;
+                char buf[SD_ID128_STRING_MAX];
+
+                r = sd_bus_get_server_id(a, &server_id);
+                if (r < 0)
+                        return synthetic_reply_method_errno(m, r, NULL);
+
+                return synthetic_reply_method_return(m, "s", sd_id128_to_string(server_id, buf));
+
+        } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "GetNameOwner")) {
+                const char *name;
+                _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
+                _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+
+                r = sd_bus_message_read(m, "s", &name);
+                if (r < 0)
+                        return synthetic_reply_method_errno(m, r, NULL);
+
+                if (streq(name, "org.freedesktop.DBus"))
+                        return synthetic_reply_method_return(m, "s", "org.freedesktop.DBus");
+
+                r = get_creds_by_name(a, name, SD_BUS_CREDS_UNIQUE_NAME, &creds, &error);
+                if (r < 0)
+                        return synthetic_reply_method_errno(m, r, &error);
+
+                return synthetic_reply_method_return(m, "s", creds->unique_name);
+
+        /* "Hello" is handled in process_hello() */
+
+        } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "ListActivatableNames")) {
+                _cleanup_strv_free_ char **names = NULL;
+
+                r = sd_bus_list_names(a, NULL, &names);
+                if (r < 0)
+                        return synthetic_reply_method_errno(m, r, NULL);
+
+                /* Let's sort the names list to make it stable */
+                strv_sort(names);
+
+                return synthetic_reply_return_strv(m, names);
+
+        } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "ListNames")) {
+                _cleanup_strv_free_ char **names = NULL;
+
+                r = sd_bus_list_names(a, &names, NULL);
+                if (r < 0)
+                        return synthetic_reply_method_errno(m, r, NULL);
+
+                r = strv_extend(&names, "org.freedesktop.DBus");
+                if (r < 0)
+                        return synthetic_reply_method_errno(m, r, NULL);
+
+                /* Let's sort the names list to make it stable */
+                strv_sort(names);
+
+                return synthetic_reply_return_strv(m, names);
+
+        } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "ListQueuedOwners")) {
+                struct kdbus_cmd_name_list cmd = {};
+                struct kdbus_name_list *name_list;
+                struct kdbus_cmd_name *name;
+                _cleanup_strv_free_ char **owners = NULL;
+                char *arg0;
+                int err = 0;
+
+                r = sd_bus_message_read(m, "s", &arg0);
+                if (r < 0)
+                        return synthetic_reply_method_errno(m, r, NULL);
+
+                if (!service_name_is_valid(arg0))
+                        return synthetic_reply_method_errno(m, -EINVAL, NULL);
+
+                cmd.flags = KDBUS_NAME_LIST_QUEUED;
+                r = ioctl(a->input_fd, KDBUS_CMD_NAME_LIST, &cmd);
+                if (r < 0)
+                        return synthetic_reply_method_errno(m, -errno, NULL);
+
+                name_list = (struct kdbus_name_list *) ((uint8_t *) a->kdbus_buffer + cmd.offset);
+
+                KDBUS_ITEM_FOREACH(name, name_list, names) {
+                        char *n;
+
+                        if (name->size <= sizeof(*name))
+                                continue;
+
+                        if (!streq(name->name, arg0))
+                                continue;
+
+                        if (asprintf(&n, ":1.%llu", (unsigned long long) name->owner_id) < 0) {
+                                err  = -ENOMEM;
+                                break;
+                        }
+
+                        r = strv_consume(&owners, n);
+                        if (r < 0) {
+                                err = r;
+                                break;
+                        }
+                }
+
+                r = ioctl(a->input_fd, KDBUS_CMD_FREE, &cmd.offset);
+                if (r < 0)
+                        return synthetic_reply_method_errno(m, r, NULL);
+
+                if (err < 0)
+                        return synthetic_reply_method_errno(m, err, NULL);
+
+                return synthetic_reply_return_strv(m, owners);
+
+        } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "NameHasOwner")) {
+                const char *name;
+
+                r = sd_bus_message_read(m, "s", &name);
+                if (r < 0)
+                        return synthetic_reply_method_errno(m, r, NULL);
+
+                if (!service_name_is_valid(name))
+                        return synthetic_reply_method_errno(m, -EINVAL, NULL);
+
+                if (streq(name, "org.freedesktop.DBus"))
+                        return synthetic_reply_method_return(m, "b", true);
+
+                r = sd_bus_get_owner(a, name, 0, NULL);
+                if (r < 0 && r != -ESRCH && r != -ENXIO)
+                        return synthetic_reply_method_errno(m, r, NULL);
+
+                return synthetic_reply_method_return(m, "b", r >= 0);
+
+        } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "ReleaseName")) {
+                const char *name;
+
+                r = sd_bus_message_read(m, "s", &name);
+                if (r < 0)
+                        return synthetic_reply_method_errno(m, r, NULL);
+
+                if (!service_name_is_valid(name))
+                        return synthetic_reply_method_errno(m, -EINVAL, NULL);
+
+                r = sd_bus_release_name(a, name);
+                if (r < 0) {
+                        if (r == -ESRCH)
+                                return synthetic_reply_method_return(m, "u", BUS_NAME_NON_EXISTENT);
+                        if (r == -EADDRINUSE)
+                                return synthetic_reply_method_return(m, "u", BUS_NAME_NOT_OWNER);
+
+                        return synthetic_reply_method_errno(m, r, NULL);
+                }
+
+                return synthetic_reply_method_return(m, "u", BUS_NAME_RELEASED);
+
+        } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "ReloadConfig")) {
+                _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+
+                r = sd_bus_error_setf(&error, SD_BUS_ERROR_NOT_SUPPORTED, "%s() is not supported", sd_bus_message_get_member(m));
+
+                return synthetic_reply_method_errno(m, r, &error);
+
+        } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "RequestName")) {
+                const char *name;
+                uint32_t flags;
+
+                r = sd_bus_message_read(m, "su", &name, &flags);
+                if (r < 0)
+                        return synthetic_reply_method_errno(m, r, NULL);
+
+                if (!service_name_is_valid(name))
+                        return synthetic_reply_method_errno(m, -EINVAL, NULL);
+                if ((flags & ~(BUS_NAME_ALLOW_REPLACEMENT|BUS_NAME_REPLACE_EXISTING|BUS_NAME_DO_NOT_QUEUE)) != 0)
+                        return synthetic_reply_method_errno(m, -EINVAL, NULL);
+
+                r = sd_bus_request_name(a, name, flags);
+                if (r < 0) {
+                        if (r == -EEXIST)
+                                return synthetic_reply_method_return(m, "u", BUS_NAME_EXISTS);
+                        if (r == -EALREADY)
+                                return synthetic_reply_method_return(m, "u", BUS_NAME_ALREADY_OWNER);
+                        return synthetic_reply_method_errno(m, r, NULL);
+                }
+
+                if (r == 0)
+                        return synthetic_reply_method_return(m, "u", BUS_NAME_IN_QUEUE);
+
+                return synthetic_reply_method_return(m, "u", BUS_NAME_PRIMARY_OWNER);
+
+        } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "StartServiceByName")) {
+                _cleanup_bus_message_unref_ sd_bus_message *msg = NULL;
+                const char *name;
+                uint32_t flags;
+
+                r = sd_bus_message_read(m, "su", &name, &flags);
+                if (r < 0)
+                        return synthetic_reply_method_errno(m, r, NULL);
+
+                if (!service_name_is_valid(name))
+                        return synthetic_reply_method_errno(m, -EINVAL, NULL);
+                if (flags != 0)
+                        return synthetic_reply_method_errno(m, -EINVAL, NULL);
+
+                r = sd_bus_get_owner(a, name, 0, NULL);
+                if (r >= 0 || streq(name, "org.freedesktop.DBus"))
+                        return synthetic_reply_method_return(m, "u", BUS_START_REPLY_ALREADY_RUNNING);
+                if (r != -ESRCH)
+                        return synthetic_reply_method_errno(m, r, NULL);
+
+                r = sd_bus_message_new_method_call(
+                                a,
+                                &msg,
+                                name,
+                                "/",
+                                "org.freedesktop.DBus.Peer",
+                                "Ping");
+                if (r < 0)
+                        return synthetic_reply_method_errno(m, r, NULL);
+
+                r = sd_bus_send(a, msg, NULL);
+                if (r < 0)
+                        return synthetic_reply_method_errno(m, r, NULL);
+
+                return synthetic_reply_method_return(m, "u", BUS_START_REPLY_SUCCESS);
+
+        } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "UpdateActivationEnvironment")) {
+                _cleanup_bus_message_unref_ sd_bus_message *msg = NULL;
+                _cleanup_strv_free_ char **args = NULL;
+
+                if (!peer_is_privileged(a, m))
+                        return synthetic_reply_method_errno(m, -EPERM, NULL);
+
+                r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "{ss}");
+                if (r < 0)
+                        return synthetic_reply_method_errno(m, r, NULL);
+
+                while ((r = sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY, "ss")) > 0) {
+                        _cleanup_free_ char *s = NULL;
+                        const char *key;
+                        const char *value;
+
+                        r = sd_bus_message_read(m, "ss", &key, &value);
+                        if (r < 0)
+                                return synthetic_reply_method_errno(m, r, NULL);
+
+                        s = strjoin(key, "=", value, NULL);
+                        if (!s)
+                                return synthetic_reply_method_errno(m, -ENOMEM, NULL);
+
+                        r  = strv_extend(&args, s);
+                        if (r < 0)
+                                return synthetic_reply_method_errno(m, r, NULL);
+
+                        r = sd_bus_message_exit_container(m);
+                        if (r < 0)
+                                return synthetic_reply_method_errno(m, r, NULL);
+                }
+
+                r = sd_bus_message_exit_container(m);
+                if (r < 0)
+                        return synthetic_reply_method_errno(m, r, NULL);
+
+                if (!args)
+                        return synthetic_reply_method_errno(m, -EINVAL, NULL);
+
+                r = sd_bus_message_new_method_call(
+                                a,
+                                &msg,
+                                "org.freedesktop.systemd1",
+                                "/org/freedesktop/systemd1",
+                                "org.freedesktop.systemd1.Manager",
+                                "SetEnvironment");
+                if (r < 0)
+                        return synthetic_reply_method_errno(m, r, NULL);
+
+                r = sd_bus_message_append_strv(msg, args);
+                if (r < 0)
+                        return synthetic_reply_method_errno(m, r, NULL);
+
+                r = sd_bus_call(a, msg, 0, NULL, NULL);
+                if (r < 0)
+                        return synthetic_reply_method_errno(m, r, NULL);
+
+               return synthetic_reply_method_return(m, NULL);
+
+        } else {
+                _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+
+                r = sd_bus_error_setf(&error, SD_BUS_ERROR_UNKNOWN_METHOD, "Unknown method '%s'.", m->member);
+
+                return synthetic_reply_method_errno(m, r, &error);
+        }
+}
+
 static int process_hello(sd_bus *a, sd_bus *b, sd_bus_message *m, bool *got_hello) {
         _cleanup_bus_message_unref_ sd_bus_message *n = NULL;
         bool is_hello;
@@ -427,13 +1090,14 @@ static int patch_sender(sd_bus *a, sd_bus_message *m) {
 
 int main(int argc, char *argv[]) {
 
-        _cleanup_bus_unref_ sd_bus *a = NULL, *b = NULL;
+        _cleanup_bus_close_unref_ sd_bus *a = NULL, *b = NULL;
         sd_id128_t server_id;
         int r, in_fd, out_fd;
         bool got_hello = false;
         bool is_unix;
         struct ucred ucred = {};
         _cleanup_free_ char *peersec = NULL;
+        Policy policy = {};
 
         log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
         log_parse_environment();
@@ -443,6 +1107,14 @@ int main(int argc, char *argv[]) {
         if (r <= 0)
                 goto finish;
 
+        r = policy_load(&policy, arg_configuration);
+        if (r < 0) {
+                log_error("Failed to load policy: %s", strerror(-r));
+                goto finish;
+        }
+
+        /* policy_dump(&policy); */
+
         r = sd_listen_fds(0);
         if (r == 0) {
                 in_fd = STDIN_FILENO;
@@ -464,6 +1136,22 @@ int main(int argc, char *argv[]) {
                 getpeersec(in_fd, &peersec);
         }
 
+        if (arg_drop_privileges) {
+                const char *user = "systemd-bus-proxy";
+                uid_t uid;
+                gid_t gid;
+
+                r = get_user_creds(&user, &uid, &gid, NULL, NULL);
+                if (r < 0) {
+                        log_error("Cannot resolve user name %s: %s", user, strerror(-r));
+                        goto finish;
+                }
+
+                r = drop_privileges(uid, gid, 1ULL << CAP_IPC_OWNER);
+                if (r < 0)
+                        goto finish;
+        }
+
         r = sd_bus_new(&a);
         if (r < 0) {
                 log_error("Failed to allocate bus: %s", strerror(-r));
@@ -580,7 +1268,7 @@ int main(int argc, char *argv[]) {
                         goto finish;
                 }
 
-                r = sd_bus_add_match(a, match, NULL, NULL);
+                r = sd_bus_add_match(a, NULL, match, NULL, NULL);
                 if (r < 0) {
                         log_error("Failed to add match for NameLost: %s", strerror(-r));
                         goto finish;
@@ -601,7 +1289,7 @@ int main(int argc, char *argv[]) {
                         goto finish;
                 }
 
-                r = sd_bus_add_match(a, match, NULL, NULL);
+                r = sd_bus_add_match(a, NULL, match, NULL, NULL);
                 if (r < 0) {
                         log_error("Failed to add match for NameAcquired: %s", strerror(-r));
                         goto finish;
@@ -696,17 +1384,28 @@ int main(int argc, char *argv[]) {
                                         goto finish;
                                 }
 
-                                k = sd_bus_send(a, m, NULL);
+                                k = process_driver(a, b, m);
                                 if (k < 0) {
-                                        if (r == -ECONNRESET)
-                                                r = 0;
-                                        else {
-                                                r = k;
-                                                log_error("Failed to send message: %s", strerror(-r));
-                                        }
-
+                                        r = k;
+                                        log_error("Failed to process driver calls: %s", strerror(-r));
                                         goto finish;
                                 }
+
+                                if (k > 0)
+                                        r = k;
+                                else {
+                                        k = sd_bus_send(a, m, NULL);
+                                        if (k < 0) {
+                                                if (k == -ECONNRESET)
+                                                        r = 0;
+                                                else {
+                                                        r = k;
+                                                        log_error("Failed to send message: %s", strerror(-r));
+                                                }
+
+                                                goto finish;
+                                        }
+                                }
                         }
                 }
 
@@ -774,11 +1473,10 @@ int main(int argc, char *argv[]) {
                 }
         }
 
-        r = 0;
-
 finish:
-        sd_bus_flush(a);
-        sd_bus_flush(b);
+        policy_free(&policy);
+        strv_free(arg_configuration);
+        free(arg_address);
 
         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
 }
index b8e275d..7070503 100644 (file)
 #include "build.h"
 #include "output-mode.h"
 #include "fileio.h"
+#include "sd-bus.h"
+#include "bus-util.h"
+#include "bus-error.h"
+#include "unit-name.h"
 
 static bool arg_no_pager = false;
 static bool arg_kernel_threads = false;
@@ -42,8 +46,7 @@ static bool arg_all = false;
 static int arg_full = -1;
 static char* arg_machine = NULL;
 
-static int help(void) {
-
+static void help(void) {
         printf("%s [OPTIONS...] [CGROUP...]\n\n"
                "Recursively show control group contents.\n\n"
                "  -h --help           Show this help\n"
@@ -52,10 +55,8 @@ static int help(void) {
                "  -a --all            Show all groups, including empty\n"
                "  -l --full           Do not ellipsize output\n"
                "  -k                  Include kernel threads in output\n"
-               "  -M --machine        Show container\n",
-               program_invocation_short_name);
-
-        return 0;
+               "  -M --machine        Show container\n"
+               , program_invocation_short_name);
 }
 
 static int parse_argv(int argc, char *argv[]) {
@@ -80,12 +81,13 @@ static int parse_argv(int argc, char *argv[]) {
         assert(argc >= 1);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "hkalM:", options, NULL)) >= 0) {
+        while ((c = getopt_long(argc, argv, "hkalM:", options, NULL)) >= 0)
 
                 switch (c) {
 
                 case 'h':
-                        return help();
+                        help();
+                        return 0;
 
                 case ARG_VERSION:
                         puts(PACKAGE_STRING);
@@ -118,7 +120,6 @@ static int parse_argv(int argc, char *argv[]) {
                 default:
                         assert_not_reached("Unhandled option");
                 }
-        }
 
         return 1;
 }
@@ -126,7 +127,8 @@ static int parse_argv(int argc, char *argv[]) {
 int main(int argc, char *argv[]) {
         int r = 0, retval = EXIT_FAILURE;
         int output_flags;
-        char _cleanup_free_ *root = NULL;
+        _cleanup_free_ char *root = NULL;
+        _cleanup_bus_close_unref_ sd_bus *bus = NULL;
 
         log_parse_environment();
         log_open();
@@ -151,6 +153,12 @@ int main(int argc, char *argv[]) {
                 arg_all * OUTPUT_SHOW_ALL |
                 (arg_full > 0) * OUTPUT_FULL_WIDTH;
 
+        r = bus_open_transport(BUS_TRANSPORT_LOCAL, NULL, false, &bus);
+        if (r < 0) {
+                log_error("Failed to create bus connection: %s", strerror(-r));
+                goto finish;
+        }
+
         if (optind < argc) {
                 int i;
 
@@ -189,8 +197,52 @@ int main(int argc, char *argv[]) {
                 } else {
                         if (arg_machine) {
                                 char *m;
+                                const char *cgroup;
+                                _cleanup_free_ char *scope = NULL;
+                                _cleanup_free_ char *path = NULL;
+                                _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
+                                _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+
                                 m = strappenda("/run/systemd/machines/", arg_machine);
-                                r = parse_env_file(m, NEWLINE, "CGROUP", &root, NULL);
+                                r = parse_env_file(m, NEWLINE, "SCOPE", &scope, NULL);
+                                if (r < 0) {
+                                        log_error("Failed to get machine path: %s", strerror(-r));
+                                        goto finish;
+                                }
+
+                                path = unit_dbus_path_from_name(scope);
+                                if (!path) {
+                                        log_oom();
+                                        goto finish;
+                                }
+
+                                r = sd_bus_get_property(
+                                                bus,
+                                                "org.freedesktop.systemd1",
+                                                path,
+                                                "org.freedesktop.systemd1.Scope",
+                                                "ControlGroup",
+                                                &error,
+                                                &reply,
+                                                "s");
+
+                                if (r < 0) {
+                                        log_error("Failed to query ControlGroup: %s", bus_error_message(&error, -r));
+                                        goto finish;
+                                }
+
+                                r = sd_bus_message_read(reply, "s", &cgroup);
+                                if (r < 0) {
+                                        bus_log_parse_error(r);
+                                        goto finish;
+                                }
+
+                                root = strdup(cgroup);
+                                if (!root) {
+                                        log_oom();
+                                        goto finish;
+                                }
+
                         } else
                                 r = cg_get_root_path(&root);
                         if (r < 0) {
index d1d843b..e581fbc 100644 (file)
@@ -26,7 +26,7 @@
 #include "bus-util.h"
 
 int main(int argc, char *argv[]) {
-        _cleanup_bus_unref_ sd_bus *bus = NULL;
+        _cleanup_bus_close_unref_ sd_bus *bus = NULL;
         int r;
 
         if (argc != 2) {
@@ -62,7 +62,5 @@ int main(int argc, char *argv[]) {
                 return EXIT_FAILURE;
         }
 
-        sd_bus_flush(bus);
-
         return EXIT_SUCCESS;
 }
index fd0023b..509fe4c 100644 (file)
@@ -548,8 +548,7 @@ static int display(Hashmap *a) {
         return 0;
 }
 
-static int help(void) {
-
+static void help(void) {
         printf("%s [OPTIONS...]\n\n"
                "Show top control groups by their resource usage.\n\n"
                "  -h --help           Show this help\n"
@@ -563,10 +562,8 @@ static int help(void) {
                "  -d --delay=DELAY    Delay between updates\n"
                "  -n --iterations=N   Run for N iterations before exiting\n"
                "  -b --batch          Run in batch mode, accepting no input\n"
-               "     --depth=DEPTH    Maximum traversal depth (default: %u)\n",
-               program_invocation_short_name, arg_depth);
-
-        return 0;
+               "     --depth=DEPTH    Maximum traversal depth (default: %u)\n"
+               , program_invocation_short_name, arg_depth);
 }
 
 static int parse_argv(int argc, char *argv[]) {
@@ -594,12 +591,13 @@ static int parse_argv(int argc, char *argv[]) {
         assert(argc >= 1);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "hptcmin:bd:", options, NULL)) >= 0) {
+        while ((c = getopt_long(argc, argv, "hptcmin:bd:", options, NULL)) >= 0)
 
                 switch (c) {
 
                 case 'h':
-                        return help();
+                        help();
+                        return 0;
 
                 case ARG_VERSION:
                         puts(PACKAGE_STRING);
@@ -674,7 +672,6 @@ static int parse_argv(int argc, char *argv[]) {
                 default:
                         assert_not_reached("Unhandled option");
                 }
-        }
 
         if (optind < argc) {
                 log_error("Too many arguments.");
index 5955bd8..4326d17 100644 (file)
@@ -55,7 +55,7 @@ int get_audit_fd(void) {
 void close_audit_fd(void) {
 
         if (initialized && audit_fd >= 0)
-                close_nointr_nofail(audit_fd);
+                safe_close(audit_fd);
 
         initialized = true;
         audit_fd = -ECONNRESET;
index 889b20e..73a8ce1 100644 (file)
@@ -90,9 +90,7 @@ static void unmount_autofs(Automount *a) {
         automount_send_ready(a, -EHOSTDOWN);
 
         a->pipe_event_source = sd_event_source_unref(a->pipe_event_source);
-
-        close_nointr_nofail(a->pipe_fd);
-        a->pipe_fd = -1;
+        a->pipe_fd = safe_close(a->pipe_fd);
 
         /* If we reload/reexecute things we keep the mount point
          * around */
@@ -146,7 +144,7 @@ static int automount_add_default_dependencies(Automount *a) {
 
 static int automount_verify(Automount *a) {
         bool b;
-        char *e;
+        _cleanup_free_ char *e = NULL;
         assert(a);
 
         if (UNIT(a)->load_state != UNIT_LOADED)
@@ -162,7 +160,6 @@ static int automount_verify(Automount *a) {
                 return -ENOMEM;
 
         b = unit_has_name(UNIT(a), e);
-        free(e);
 
         if (!b) {
                 log_error_unit(UNIT(a)->id, "%s's Where setting doesn't match unit name. Refusing.", UNIT(a)->id);
@@ -310,8 +307,7 @@ static int open_dev_autofs(Manager *m) {
 
         init_autofs_dev_ioctl(&param);
         if (ioctl(m->dev_autofs_fd, AUTOFS_DEV_IOCTL_VERSION, &param) < 0) {
-                close_nointr_nofail(m->dev_autofs_fd);
-                m->dev_autofs_fd = -1;
+                m->dev_autofs_fd = safe_close(m->dev_autofs_fd);
                 return -errno;
         }
 
@@ -411,8 +407,9 @@ static int autofs_send_ready(int dev_autofs_fd, int ioctl_fd, uint32_t token, in
 }
 
 int automount_send_ready(Automount *a, int status) {
-        int ioctl_fd, r;
+        _cleanup_close_ int ioctl_fd = -1;
         unsigned token;
+        int r;
 
         assert(a);
         assert(status <= 0);
@@ -421,10 +418,8 @@ int automount_send_ready(Automount *a, int status) {
                 return 0;
 
         ioctl_fd = open_ioctl_fd(UNIT(a)->manager->dev_autofs_fd, a->where, a->dev_id);
-        if (ioctl_fd < 0) {
-                r = ioctl_fd;
-                goto fail;
-        }
+        if (ioctl_fd < 0)
+                return ioctl_fd;
 
         if (status)
                 log_debug_unit(UNIT(a)->id, "Sending failure: %s", strerror(-status));
@@ -450,18 +445,15 @@ int automount_send_ready(Automount *a, int status) {
                         r = k;
         }
 
-fail:
-        if (ioctl_fd >= 0)
-                close_nointr_nofail(ioctl_fd);
-
         return r;
 }
 
 static void automount_enter_waiting(Automount *a) {
+        _cleanup_close_ int ioctl_fd = -1;
         int p[2] = { -1, -1 };
         char name[32], options[128];
         bool mounted = false;
-        int r, ioctl_fd = -1, dev_autofs_fd;
+        int r, dev_autofs_fd;
         struct stat st;
 
         assert(a);
@@ -500,8 +492,7 @@ static void automount_enter_waiting(Automount *a) {
 
         mounted = true;
 
-        close_nointr_nofail(p[1]);
-        p[1] = -1;
+        p[1] = safe_close(p[1]);
 
         if (stat(a->where, &st) < 0) {
                 r = -errno;
@@ -528,9 +519,6 @@ static void automount_enter_waiting(Automount *a) {
          * the direct mount will not receive events from the
          * kernel. */
 
-        close_nointr_nofail(ioctl_fd);
-        ioctl_fd = -1;
-
         r = sd_event_add_io(UNIT(a)->manager->event, &a->pipe_event_source, p[0], EPOLLIN, automount_dispatch_io, a);
         if (r < 0)
                 goto fail;
@@ -543,10 +531,7 @@ static void automount_enter_waiting(Automount *a) {
         return;
 
 fail:
-        assert_se(close_pipe(p) == 0);
-
-        if (ioctl_fd >= 0)
-                close_nointr_nofail(ioctl_fd);
+        safe_close_pair(p);
 
         if (mounted)
                 repeat_unmount(a->where);
@@ -713,9 +698,7 @@ static int automount_deserialize_item(Unit *u, const char *key, const char *valu
                 if (safe_atoi(value, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
                         log_debug_unit(u->id, "Failed to parse pipe-fd value %s", value);
                 else {
-                        if (a->pipe_fd >= 0)
-                                close_nointr_nofail(a->pipe_fd);
-
+                        safe_close(a->pipe_fd);
                         a->pipe_fd = fdset_remove(fds, fd);
                 }
         } else
@@ -809,8 +792,7 @@ fail:
 static void automount_shutdown(Manager *m) {
         assert(m);
 
-        if (m->dev_autofs_fd >= 0)
-                close_nointr_nofail(m->dev_autofs_fd);
+        m->dev_autofs_fd = safe_close(m->dev_autofs_fd);
 }
 
 static void automount_reset_failed(Unit *u) {
index 3d7cd3e..d380382 100644 (file)
 #define _PAM_FEATURE_ "-PAM"
 #endif
 
-#ifdef HAVE_LIBWRAP
-#define _LIBWRAP_FEATURE_ "+LIBWRAP"
-#else
-#define _LIBWRAP_FEATURE_ "-LIBWRAP"
-#endif
-
 #ifdef HAVE_AUDIT
 #define _AUDIT_FEATURE_ "+AUDIT"
 #else
 #define _IMA_FEATURE_ "-IMA"
 #endif
 
+#ifdef HAVE_SMACK
+#define _SMACK_FEATURE_ "+SMACK"
+#else
+#define _SMACK_FEATURE_ "-SMACK"
+#endif
+
 #ifdef HAVE_SYSV_COMPAT
 #define _SYSVINIT_FEATURE_ "+SYSVINIT"
 #else
 #define _GCRYPT_FEATURE_ "-GCRYPT"
 #endif
 
+#ifdef HAVE_GNUTLS
+#define _GNUTLS_FEATURE_ "+GNUTLS"
+#else
+#define _GNUTLS_FEATURE_ "-GNUTLS"
+#endif
+
 #ifdef HAVE_ACL
 #define _ACL_FEATURE_ "+ACL"
 #else
 #define _XZ_FEATURE_ "-XZ"
 #endif
 
+#ifdef HAVE_LZ4
+#define _LZ4_FEATURE_ "+LZ4"
+#else
+#define _LZ4_FEATURE_ "-LZ4"
+#endif
+
 #ifdef HAVE_SECCOMP
 #define _SECCOMP_FEATURE_ "+SECCOMP"
 #else
 #define _SECCOMP_FEATURE_ "-SECCOMP"
 #endif
 
-#define SYSTEMD_FEATURES _PAM_FEATURE_ " " _LIBWRAP_FEATURE_ " " _AUDIT_FEATURE_ " " _SELINUX_FEATURE_ " " _IMA_FEATURE_ " " _SYSVINIT_FEATURE_ " " _LIBCRYPTSETUP_FEATURE_ " " _GCRYPT_FEATURE_ " " _ACL_FEATURE_ " " _XZ_FEATURE_ " " _SECCOMP_FEATURE_ " " _APPARMOR_FEATURE_
+#ifdef HAVE_BLKID
+#define _BLKID_FEATURE_ "+BLKID"
+#else
+#define _BLKID_FEATURE_ "-BLKID"
+#endif
+
+#ifdef HAVE_ELFUTILS
+#define _ELFUTILS_FEATURE_ "+ELFUTILS"
+#else
+#define _ELFUTILS_FEATURE_ "-ELFUTILS"
+#endif
+
+#ifdef HAVE_KMOD
+#define _KMOD_FEATURE_ "+KMOD"
+#else
+#define _KMOD_FEATURE_ "-KMOD"
+#endif
+
+#ifdef HAVE_KMOD
+#define _KMOD_FEATURE_ "+KMOD"
+#else
+#define _KMOD_FEATURE_ "-KMOD"
+#endif
+
+#ifdef HAVE_LIBIDN
+#define _IDN_FEATURE_ "+IDN"
+#else
+#define _IDN_FEATURE_ "-IDN"
+#endif
+
+#define SYSTEMD_FEATURES                                                \
+        _PAM_FEATURE_ " "                                               \
+        _AUDIT_FEATURE_ " "                                             \
+        _SELINUX_FEATURE_ " "                                           \
+        _IMA_FEATURE_ " "                                               \
+        _APPARMOR_FEATURE_ " "                                          \
+        _SMACK_FEATURE_ " "                                             \
+        _SYSVINIT_FEATURE_ " "                                          \
+        _LIBCRYPTSETUP_FEATURE_ " "                                     \
+        _GCRYPT_FEATURE_ " "                                            \
+        _GNUTLS_FEATURE_ " "                                            \
+        _ACL_FEATURE_ " "                                               \
+        _XZ_FEATURE_ " "                                                \
+        _LZ4_FEATURE_ " "                                               \
+        _SECCOMP_FEATURE_ " "                                           \
+        _BLKID_FEATURE_ " "                                             \
+        _ELFUTILS_FEATURE_ " "                                          \
+        _KMOD_FEATURE_ " "                                              \
+        _IDN_FEATURE_ " "
index 4c34538..39ea6a0 100644 (file)
 
 static const UnitActiveState state_translation_table[_BUSNAME_STATE_MAX] = {
         [BUSNAME_DEAD] = UNIT_INACTIVE,
+        [BUSNAME_MAKING] = UNIT_ACTIVATING,
+        [BUSNAME_REGISTERED] = UNIT_ACTIVE,
         [BUSNAME_LISTENING] = UNIT_ACTIVE,
         [BUSNAME_RUNNING] = UNIT_ACTIVE,
+        [BUSNAME_SIGTERM] = UNIT_DEACTIVATING,
+        [BUSNAME_SIGKILL] = UNIT_DEACTIVATING,
         [BUSNAME_FAILED] = UNIT_FAILED
 };
 
 static int busname_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata);
+static int busname_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata);
 
 static void busname_init(Unit *u) {
         BusName *n = BUSNAME(u);
@@ -43,24 +48,83 @@ static void busname_init(Unit *u) {
         assert(u->load_state == UNIT_STUB);
 
         n->starter_fd = -1;
+        n->accept_fd = true;
+        n->activating = true;
+
+        n->timeout_usec = u->manager->default_timeout_start_usec;
+}
+
+static void busname_unwatch_control_pid(BusName *n) {
+        assert(n);
+
+        if (n->control_pid <= 0)
+                return;
+
+        unit_unwatch_pid(UNIT(n), n->control_pid);
+        n->control_pid = 0;
+}
+
+static void busname_free_policy(BusName *n) {
+        BusNamePolicy *p;
+
+        assert(n);
+
+        while ((p = n->policy)) {
+                LIST_REMOVE(policy, n->policy, p);
+
+                free(p->name);
+                free(p);
+        }
+}
+
+static void busname_close_fd(BusName *n) {
+        assert(n);
+
+        n->starter_event_source = sd_event_source_unref(n->starter_event_source);
+        n->starter_fd = safe_close(n->starter_fd);
 }
 
 static void busname_done(Unit *u) {
         BusName *n = BUSNAME(u);
 
-        assert(u);
+        assert(n);
 
         free(n->name);
         n->name = NULL;
 
+        busname_free_policy(n);
+        busname_unwatch_control_pid(n);
+        busname_close_fd(n);
+
         unit_ref_unset(&n->service);
 
-        n->event_source = sd_event_source_unref(n->event_source);
+        n->timer_event_source = sd_event_source_unref(n->timer_event_source);
+}
+
+static int busname_arm_timer(BusName *n) {
+        int r;
 
-        if (n->starter_fd >= 0) {
-                close_nointr_nofail(n->starter_fd);
-                n->starter_fd = -1;
+        assert(n);
+
+        if (n->timeout_usec <= 0) {
+                n->timer_event_source = sd_event_source_unref(n->timer_event_source);
+                return 0;
         }
+
+        if (n->timer_event_source) {
+                r = sd_event_source_set_time(n->timer_event_source, now(CLOCK_MONOTONIC) + n->timeout_usec);
+                if (r < 0)
+                        return r;
+
+                return sd_event_source_set_enabled(n->timer_event_source, SD_EVENT_ONESHOT);
+        }
+
+        return sd_event_add_time(
+                        UNIT(n)->manager->event,
+                        &n->timer_event_source,
+                        CLOCK_MONOTONIC,
+                        now(CLOCK_MONOTONIC) + n->timeout_usec, 0,
+                        busname_dispatch_timer, n);
 }
 
 static int busname_add_default_default_dependencies(BusName *n) {
@@ -99,20 +163,22 @@ static int busname_add_extras(BusName *n) {
                         return r;
         }
 
-        if (!UNIT_DEREF(n->service)) {
-                Unit *x;
+        if (n->activating) {
+                if (!UNIT_DEREF(n->service)) {
+                        Unit *x;
+
+                        r = unit_load_related_unit(u, ".service", &x);
+                        if (r < 0)
+                                return r;
 
-                r = unit_load_related_unit(u, ".service", &x);
+                        unit_ref_set(&n->service, x);
+                }
+
+                r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, UNIT_DEREF(n->service), true);
                 if (r < 0)
                         return r;
-
-                unit_ref_set(&n->service, x);
         }
 
-        r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, UNIT_DEREF(n->service), true);
-        if (r < 0)
-                return r;
-
         if (u->default_dependencies) {
                 r = busname_add_default_default_dependencies(n);
                 if (r < 0)
@@ -122,8 +188,6 @@ static int busname_add_extras(BusName *n) {
         return 0;
 }
 
-
-
 static int busname_verify(BusName *n) {
         char *e;
 
@@ -176,10 +240,19 @@ static void busname_dump(Unit *u, FILE *f, const char *prefix) {
         fprintf(f,
                 "%sBus Name State: %s\n"
                 "%sResult: %s\n"
-                "%sName: %s\n",
+                "%sName: %s\n"
+                "%sActivating: %s\n"
+                "%sAccept FD: %s\n",
                 prefix, busname_state_to_string(n->state),
                 prefix, busname_result_to_string(n->result),
-                prefix, n->name);
+                prefix, n->name,
+                prefix, yes_no(n->activating),
+                prefix, yes_no(n->accept_fd));
+
+        if (n->control_pid > 0)
+                fprintf(f,
+                        "%sControl PID: "PID_FMT"\n",
+                        prefix, n->control_pid);
 }
 
 static void busname_unwatch_fd(BusName *n) {
@@ -187,23 +260,12 @@ static void busname_unwatch_fd(BusName *n) {
 
         assert(n);
 
-        if (n->event_source) {
-                r = sd_event_source_set_enabled(n->event_source, SD_EVENT_OFF);
-                if (r < 0)
-                        log_debug_unit(UNIT(n)->id, "Failed to disable event source.");
-        }
-}
-
-static void busname_close_fd(BusName *n) {
-        assert(n);
-
-        busname_unwatch_fd(n);
-
-        if (n->starter_fd <= 0)
+        if (!n->starter_event_source)
                 return;
 
-        close_nointr_nofail(n->starter_fd);
-        n->starter_fd = -1;
+        r = sd_event_source_set_enabled(n->starter_event_source, SD_EVENT_OFF);
+        if (r < 0)
+                log_debug_unit(UNIT(n)->id, "Failed to disable event source.");
 }
 
 static int busname_watch_fd(BusName *n) {
@@ -214,10 +276,10 @@ static int busname_watch_fd(BusName *n) {
         if (n->starter_fd < 0)
                 return 0;
 
-        if (n->event_source)
-                r = sd_event_source_set_enabled(n->event_source, SD_EVENT_ON);
+        if (n->starter_event_source)
+                r = sd_event_source_set_enabled(n->starter_event_source, SD_EVENT_ON);
         else
-                r = sd_event_add_io(UNIT(n)->manager->event, &n->event_source, n->starter_fd, EPOLLIN, busname_dispatch_io, n);
+                r = sd_event_add_io(UNIT(n)->manager->event, &n->starter_event_source, n->starter_fd, EPOLLIN, busname_dispatch_io, n);
         if (r < 0) {
                 log_warning_unit(UNIT(n)->id, "Failed to watch starter fd: %s", strerror(-r));
                 busname_unwatch_fd(n);
@@ -228,14 +290,19 @@ static int busname_watch_fd(BusName *n) {
 }
 
 static int busname_open_fd(BusName *n) {
+        _cleanup_free_ char *path = NULL;
+        const char *mode;
+
         assert(n);
 
         if (n->starter_fd >= 0)
                 return 0;
 
-        n->starter_fd = bus_kernel_create_starter(UNIT(n)->manager->running_as == SYSTEMD_SYSTEM ? "system" : "user", n->name);
+        mode = UNIT(n)->manager->running_as == SYSTEMD_SYSTEM ? "system" : "user";
+        n->starter_fd = bus_kernel_open_bus_fd(mode, &path);
         if (n->starter_fd < 0) {
-                log_warning_unit(UNIT(n)->id, "Failed to create starter fd: %s", strerror(-n->starter_fd));
+                log_warning_unit(UNIT(n)->id, "Failed to open %s: %s",
+                                 path ?: "kdbus", strerror(-n->starter_fd));
                 return n->starter_fd;
         }
 
@@ -249,10 +316,15 @@ static void busname_set_state(BusName *n, BusNameState state) {
         old_state = n->state;
         n->state = state;
 
+        if (!IN_SET(state, BUSNAME_MAKING, BUSNAME_SIGTERM, BUSNAME_SIGKILL)) {
+                n->timer_event_source = sd_event_source_unref(n->timer_event_source);
+                busname_unwatch_control_pid(n);
+        }
+
         if (state != BUSNAME_LISTENING)
                 busname_unwatch_fd(n);
 
-        if (!IN_SET(state, BUSNAME_LISTENING, BUSNAME_RUNNING))
+        if (!IN_SET(state, BUSNAME_LISTENING, BUSNAME_MAKING, BUSNAME_REGISTERED, BUSNAME_RUNNING))
                 busname_close_fd(n);
 
         if (state != old_state)
@@ -272,7 +344,21 @@ static int busname_coldplug(Unit *u) {
         if (n->deserialized_state == n->state)
                 return 0;
 
-        if (IN_SET(n->deserialized_state, BUSNAME_LISTENING, BUSNAME_RUNNING)) {
+        if (IN_SET(n->deserialized_state, BUSNAME_MAKING, BUSNAME_SIGTERM, BUSNAME_SIGKILL)) {
+
+                if (n->control_pid <= 0)
+                        return -EBADMSG;
+
+                r = unit_watch_pid(UNIT(n), n->control_pid);
+                if (r < 0)
+                        return r;
+
+                r = busname_arm_timer(n);
+                if (r < 0)
+                        return r;
+        }
+
+        if (IN_SET(n->deserialized_state, BUSNAME_MAKING, BUSNAME_LISTENING, BUSNAME_REGISTERED, BUSNAME_RUNNING)) {
                 r = busname_open_fd(n);
                 if (r < 0)
                         return r;
@@ -288,6 +374,56 @@ static int busname_coldplug(Unit *u) {
         return 0;
 }
 
+static int busname_make_starter(BusName *n, pid_t *_pid) {
+        pid_t pid;
+        int r;
+
+        r = busname_arm_timer(n);
+        if (r < 0)
+                goto fail;
+
+        /* We have to resolve the user/group names out-of-process,
+         * hence let's fork here. It's messy, but well, what can we
+         * do? */
+
+        pid = fork();
+        if (pid < 0)
+                return -errno;
+
+        if (pid == 0) {
+                int ret;
+
+                default_signals(SIGNALS_CRASH_HANDLER, SIGNALS_IGNORE, -1);
+                ignore_signals(SIGPIPE, -1);
+                log_forget_fds();
+
+                r = bus_kernel_make_starter(n->starter_fd, n->name, n->activating, n->accept_fd, n->policy, n->policy_world);
+                if (r < 0) {
+                        ret = EXIT_MAKE_STARTER;
+                        goto fail_child;
+                }
+
+                _exit(0);
+
+        fail_child:
+                log_open();
+                log_error("Failed to create starter connection at step %s: %s", exit_status_to_string(ret, EXIT_STATUS_SYSTEMD), strerror(-r));
+
+                _exit(ret);
+        }
+
+        r = unit_watch_pid(UNIT(n), pid);
+        if (r < 0)
+                goto fail;
+
+        *_pid = pid;
+        return 0;
+
+fail:
+        n->timer_event_source = sd_event_source_unref(n->timer_event_source);
+        return r;
+}
+
 static void busname_enter_dead(BusName *n, BusNameResult f) {
         assert(n);
 
@@ -297,24 +433,104 @@ static void busname_enter_dead(BusName *n, BusNameResult f) {
         busname_set_state(n, n->result != BUSNAME_SUCCESS ? BUSNAME_FAILED : BUSNAME_DEAD);
 }
 
-static void busname_enter_listening(BusName *n) {
+static void busname_enter_signal(BusName *n, BusNameState state, BusNameResult f) {
+        KillContext kill_context = {};
         int r;
 
         assert(n);
 
-        r = busname_open_fd(n);
+        if (f != BUSNAME_SUCCESS)
+                n->result = f;
+
+        kill_context_init(&kill_context);
+
+        r = unit_kill_context(UNIT(n),
+                              &kill_context,
+                              state != BUSNAME_SIGTERM,
+                              -1,
+                              n->control_pid,
+                              false);
         if (r < 0) {
-                log_warning_unit(UNIT(n)->id, "%s failed to listen on bus names: %s", UNIT(n)->id, strerror(-r));
+                log_warning_unit(UNIT(n)->id, "%s failed to kill control process: %s", UNIT(n)->id, strerror(-r));
                 goto fail;
         }
 
-        r = busname_watch_fd(n);
-        if (r < 0) {
-                log_warning_unit(UNIT(n)->id, "%s failed to watch names: %s", UNIT(n)->id, strerror(-r));
+        if (r > 0) {
+                r = busname_arm_timer(n);
+                if (r < 0) {
+                        log_warning_unit(UNIT(n)->id, "%s failed to arm timer: %s", UNIT(n)->id, strerror(-r));
+                        goto fail;
+                }
+
+                busname_set_state(n, state);
+        } else if (state == BUSNAME_SIGTERM)
+                busname_enter_signal(n, BUSNAME_SIGKILL, BUSNAME_SUCCESS);
+        else
+                busname_enter_dead(n, BUSNAME_SUCCESS);
+
+        return;
+
+fail:
+        busname_enter_dead(n, BUSNAME_FAILURE_RESOURCES);
+}
+
+static void busname_enter_listening(BusName *n) {
+        int r;
+
+        assert(n);
+
+        if (n->activating) {
+                r = busname_watch_fd(n);
+                if (r < 0) {
+                        log_warning_unit(UNIT(n)->id, "%s failed to watch names: %s", UNIT(n)->id, strerror(-r));
+                        goto fail;
+                }
+
+                busname_set_state(n, BUSNAME_LISTENING);
+        } else
+                busname_set_state(n, BUSNAME_REGISTERED);
+
+        return;
+
+fail:
+        busname_enter_signal(n, BUSNAME_SIGTERM, BUSNAME_FAILURE_RESOURCES);
+}
+
+static void busname_enter_making(BusName *n) {
+        int r;
+
+        assert(n);
+
+        r = busname_open_fd(n);
+        if (r < 0)
                 goto fail;
+
+        if (n->policy) {
+                /* If there is a policy, we need to resolve user/group
+                 * names, which we can't do from PID1, hence let's
+                 * fork. */
+                busname_unwatch_control_pid(n);
+
+                r = busname_make_starter(n, &n->control_pid);
+                if (r < 0) {
+                        log_warning_unit(UNIT(n)->id, "%s failed to fork 'making' task: %s", UNIT(n)->id, strerror(-r));
+                        goto fail;
+                }
+
+                busname_set_state(n, BUSNAME_MAKING);
+        } else {
+                /* If there is no policy, we can do everything
+                 * directly from PID 1, hence do so. */
+
+                r = bus_kernel_make_starter(n->starter_fd, n->name, n->activating, n->accept_fd, NULL, n->policy_world);
+                if (r < 0) {
+                        log_warning_unit(UNIT(n)->id, "%s failed to make starter: %s", UNIT(n)->id, strerror(-r));
+                        goto fail;
+                }
+
+                busname_enter_listening(n);
         }
 
-        busname_set_state(n, BUSNAME_LISTENING);
         return;
 
 fail:
@@ -330,6 +546,9 @@ static void busname_enter_running(BusName *n) {
 
         assert(n);
 
+        if (!n->activating)
+                return;
+
         /* We don't take conenctions anymore if we are supposed to
          * shut down anyway */
 
@@ -370,7 +589,16 @@ static int busname_start(Unit *u) {
 
         assert(n);
 
-        if (UNIT_ISSET(n->service)) {
+        /* We cannot fulfill this request right now, try again later
+         * please! */
+        if (IN_SET(n->state, BUSNAME_SIGTERM, BUSNAME_SIGKILL))
+                return -EAGAIN;
+
+        /* Already on it! */
+        if (n->state == BUSNAME_MAKING)
+                return 0;
+
+        if (n->activating && UNIT_ISSET(n->service)) {
                 Service *service;
 
                 service = SERVICE(UNIT_DEREF(n->service));
@@ -384,7 +612,7 @@ static int busname_start(Unit *u) {
         assert(IN_SET(n->state, BUSNAME_DEAD, BUSNAME_FAILED));
 
         n->result = BUSNAME_SUCCESS;
-        busname_enter_listening(n);
+        busname_enter_making(n);
 
         return 0;
 }
@@ -393,7 +621,20 @@ static int busname_stop(Unit *u) {
         BusName *n = BUSNAME(u);
 
         assert(n);
-        assert(n->state == BUSNAME_LISTENING || n->state == BUSNAME_RUNNING);
+
+        /* Already on it */
+        if (IN_SET(n->state, BUSNAME_SIGTERM, BUSNAME_SIGKILL))
+                return 0;
+
+        /* If there's already something running, we go directly into
+         * kill mode. */
+
+        if (n->state == BUSNAME_MAKING) {
+                busname_enter_signal(n, BUSNAME_SIGTERM, BUSNAME_SUCCESS);
+                return -EAGAIN;
+        }
+
+        assert(IN_SET(n->state, BUSNAME_REGISTERED, BUSNAME_LISTENING, BUSNAME_RUNNING));
 
         busname_enter_dead(n, BUSNAME_SUCCESS);
         return 0;
@@ -409,6 +650,9 @@ static int busname_serialize(Unit *u, FILE *f, FDSet *fds) {
         unit_serialize_item(u, f, "state", busname_state_to_string(n->state));
         unit_serialize_item(u, f, "result", busname_result_to_string(n->result));
 
+        if (n->control_pid > 0)
+                unit_serialize_item_format(u, f, "control-pid", PID_FMT, n->control_pid);
+
         if (n->starter_fd >= 0) {
                 int copy;
 
@@ -447,14 +691,20 @@ static int busname_deserialize_item(Unit *u, const char *key, const char *value,
                 else if (f != BUSNAME_SUCCESS)
                         n->result = f;
 
+        } else if (streq(key, "control-pid")) {
+                pid_t pid;
+
+                if (parse_pid(value, &pid) < 0)
+                        log_debug_unit(u->id, "Failed to parse control-pid value %s", value);
+                else
+                        n->control_pid = pid;
         } else if (streq(key, "starter-fd")) {
                 int fd;
 
                 if (safe_atoi(value, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
                         log_debug_unit(u->id, "Failed to parse starter fd value %s", value);
                 else {
-                        if (n->starter_fd >= 0)
-                                close_nointr_nofail(n->starter_fd);
+                        safe_close(n->starter_fd);
                         n->starter_fd = fdset_remove(fds, fd);
                 }
         } else
@@ -500,6 +750,88 @@ fail:
         return 0;
 }
 
+static void busname_sigchld_event(Unit *u, pid_t pid, int code, int status) {
+        BusName *n = BUSNAME(u);
+        BusNameResult f;
+
+        assert(n);
+        assert(pid >= 0);
+
+        if (pid != n->control_pid)
+                return;
+
+        n->control_pid = 0;
+
+        if (is_clean_exit(code, status, NULL))
+                f = BUSNAME_SUCCESS;
+        else if (code == CLD_EXITED)
+                f = BUSNAME_FAILURE_EXIT_CODE;
+        else if (code == CLD_KILLED)
+                f = BUSNAME_FAILURE_SIGNAL;
+        else if (code == CLD_DUMPED)
+                f = BUSNAME_FAILURE_CORE_DUMP;
+        else
+                assert_not_reached("Unknown sigchld code");
+
+        log_full_unit(f == BUSNAME_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
+                      u->id, "%s control process exited, code=%s status=%i",
+                      u->id, sigchld_code_to_string(code), status);
+
+        if (f != BUSNAME_SUCCESS)
+                n->result = f;
+
+        switch (n->state) {
+
+        case BUSNAME_MAKING:
+                if (f == BUSNAME_SUCCESS)
+                        busname_enter_listening(n);
+                else
+                        busname_enter_signal(n, BUSNAME_SIGTERM, f);
+                break;
+
+        case BUSNAME_SIGTERM:
+        case BUSNAME_SIGKILL:
+                busname_enter_dead(n, f);
+                break;
+
+        default:
+                assert_not_reached("Uh, control process died at wrong time.");
+        }
+
+        /* Notify clients about changed exit status */
+        unit_add_to_dbus_queue(u);
+}
+
+static int busname_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
+        BusName *n = BUSNAME(userdata);
+
+        assert(n);
+        assert(n->timer_event_source == source);
+
+        switch (n->state) {
+
+        case BUSNAME_MAKING:
+                log_warning_unit(UNIT(n)->id, "%s making timed out. Terminating.", UNIT(n)->id);
+                busname_enter_signal(n, BUSNAME_SIGTERM, BUSNAME_FAILURE_TIMEOUT);
+                break;
+
+        case BUSNAME_SIGTERM:
+                log_warning_unit(UNIT(n)->id, "%s stopping timed out. Killing.", UNIT(n)->id);
+                busname_enter_signal(n, BUSNAME_SIGKILL, BUSNAME_FAILURE_TIMEOUT);
+                break;
+
+        case BUSNAME_SIGKILL:
+                log_warning_unit(UNIT(n)->id, "%s still around after SIGKILL. Ignoring.", UNIT(n)->id);
+                busname_enter_dead(n, BUSNAME_FAILURE_TIMEOUT);
+                break;
+
+        default:
+                assert_not_reached("Timeout at wrong time.");
+        }
+
+        return 0;
+}
+
 static void busname_reset_failed(Unit *u) {
         BusName *n = BUSNAME(u);
 
@@ -536,11 +868,33 @@ static void busname_trigger_notify(Unit *u, Unit *other) {
                 busname_enter_listening(n);
 }
 
+static int busname_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) {
+        return unit_kill_common(u, who, signo, -1, BUSNAME(u)->control_pid, error);
+}
+
+static int busname_get_timeout(Unit *u, uint64_t *timeout) {
+        BusName *n = BUSNAME(u);
+        int r;
+
+        if (!n->timer_event_source)
+                return 0;
+
+        r = sd_event_source_get_time(n->timer_event_source, timeout);
+        if (r < 0)
+                return r;
+
+        return 1;
+}
+
 static const char* const busname_state_table[_BUSNAME_STATE_MAX] = {
         [BUSNAME_DEAD] = "dead",
+        [BUSNAME_MAKING] = "making",
+        [BUSNAME_REGISTERED] = "registered",
         [BUSNAME_LISTENING] = "listening",
         [BUSNAME_RUNNING] = "running",
-        [BUSNAME_FAILED] = "failed"
+        [BUSNAME_SIGTERM] = "sigterm",
+        [BUSNAME_SIGKILL] = "sigkill",
+        [BUSNAME_FAILED] = "failed",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(busname_state, BusNameState);
@@ -548,10 +902,23 @@ DEFINE_STRING_TABLE_LOOKUP(busname_state, BusNameState);
 static const char* const busname_result_table[_BUSNAME_RESULT_MAX] = {
         [BUSNAME_SUCCESS] = "success",
         [BUSNAME_FAILURE_RESOURCES] = "resources",
+        [BUSNAME_FAILURE_TIMEOUT] = "timeout",
+        [BUSNAME_FAILURE_EXIT_CODE] = "exit-code",
+        [BUSNAME_FAILURE_SIGNAL] = "signal",
+        [BUSNAME_FAILURE_CORE_DUMP] = "core-dump",
+        [BUSNAME_FAILURE_SERVICE_FAILED_PERMANENT] = "service-failed-permanent",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(busname_result, BusNameResult);
 
+static const char* const busname_policy_access_table[_BUSNAME_POLICY_ACCESS_MAX] = {
+        [BUSNAME_POLICY_ACCESS_SEE] = "see",
+        [BUSNAME_POLICY_ACCESS_TALK] = "talk",
+        [BUSNAME_POLICY_ACCESS_OWN] = "own",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(busname_policy_access, BusNamePolicyAccess);
+
 const UnitVTable busname_vtable = {
         .object_size = sizeof(BusName),
 
@@ -572,12 +939,18 @@ const UnitVTable busname_vtable = {
         .start = busname_start,
         .stop = busname_stop,
 
+        .kill = busname_kill,
+
+        .get_timeout = busname_get_timeout,
+
         .serialize = busname_serialize,
         .deserialize_item = busname_deserialize_item,
 
         .active_state = busname_active_state,
         .sub_state_to_string = busname_sub_state_to_string,
 
+        .sigchld_event = busname_sigchld_event,
+
         .trigger_notify = busname_trigger_notify,
 
         .reset_failed = busname_reset_failed,
index 6debd48..65d57f7 100644 (file)
 ***/
 
 typedef struct BusName BusName;
+typedef struct BusNamePolicy BusNamePolicy;
 
 #include "unit.h"
 
 typedef enum BusNameState {
         BUSNAME_DEAD,
+        BUSNAME_MAKING,
+        BUSNAME_REGISTERED,
         BUSNAME_LISTENING,
         BUSNAME_RUNNING,
+        BUSNAME_SIGTERM,
+        BUSNAME_SIGKILL,
         BUSNAME_FAILED,
         _BUSNAME_STATE_MAX,
         _BUSNAME_STATE_INVALID = -1
@@ -37,23 +42,62 @@ typedef enum BusNameState {
 typedef enum BusNameResult {
         BUSNAME_SUCCESS,
         BUSNAME_FAILURE_RESOURCES,
+        BUSNAME_FAILURE_TIMEOUT,
+        BUSNAME_FAILURE_EXIT_CODE,
+        BUSNAME_FAILURE_SIGNAL,
+        BUSNAME_FAILURE_CORE_DUMP,
         BUSNAME_FAILURE_SERVICE_FAILED_PERMANENT,
         _BUSNAME_RESULT_MAX,
         _BUSNAME_RESULT_INVALID = -1
 } BusNameResult;
 
+typedef enum BusNamePolicyType {
+        BUSNAME_POLICY_TYPE_USER,
+        BUSNAME_POLICY_TYPE_GROUP,
+        _BUSNAME_POLICY_TYPE_MAX,
+        _BUSNAME_POLICY_TYPE_INVALID = -1
+} BusNamePolicyType;
+
+typedef enum BusNamePolicyAccess {
+        BUSNAME_POLICY_ACCESS_SEE,
+        BUSNAME_POLICY_ACCESS_TALK,
+        BUSNAME_POLICY_ACCESS_OWN,
+        _BUSNAME_POLICY_ACCESS_MAX,
+        _BUSNAME_POLICY_ACCESS_INVALID = -1
+} BusNamePolicyAccess;
+
+struct BusNamePolicy {
+        BusNamePolicyType type;
+        BusNamePolicyAccess access;
+
+        char *name;
+
+        LIST_FIELDS(BusNamePolicy, policy);
+};
+
 struct BusName {
         Unit meta;
 
         char *name;
         int starter_fd;
 
+        bool activating;
+        bool accept_fd;
+
         UnitRef service;
 
         BusNameState state, deserialized_state;
         BusNameResult result;
 
-        sd_event_source *event_source;
+        usec_t timeout_usec;
+
+        sd_event_source *starter_event_source;
+        sd_event_source *timer_event_source;
+
+        pid_t control_pid;
+
+        LIST_HEAD(BusNamePolicy, policy);
+        BusNamePolicyAccess policy_world;
 };
 
 extern const UnitVTable busname_vtable;
@@ -63,3 +107,6 @@ BusNameState busname_state_from_string(const char *s) _pure_;
 
 const char* busname_result_to_string(BusNameResult i) _const_;
 BusNameResult busname_result_from_string(const char *s) _pure_;
+
+const char* busname_policy_access_to_string(BusNamePolicyAccess i) _const_;
+BusNamePolicyAccess busname_policy_access_from_string(const char *s) _pure_;
index 1327486..9248cb5 100644 (file)
 ***/
 
 #include <fcntl.h>
+#include <fnmatch.h>
 
 #include "path-util.h"
 #include "special.h"
 #include "cgroup-util.h"
 #include "cgroup.h"
 
+#define CGROUP_CPU_QUOTA_PERIOD_USEC ((usec_t) 100 * USEC_PER_MSEC)
+
 void cgroup_context_init(CGroupContext *c) {
         assert(c);
 
         /* Initialize everything to the kernel defaults, assuming the
          * structure is preinitialized to 0 */
 
-        c->cpu_shares = 1024;
+        c->cpu_shares = (unsigned long) -1;
+        c->startup_cpu_shares = (unsigned long) -1;
         c->memory_limit = (uint64_t) -1;
-        c->blockio_weight = 1000;
+        c->blockio_weight = (unsigned long) -1;
+        c->startup_blockio_weight = (unsigned long) -1;
+
+        c->cpu_quota_per_sec_usec = USEC_INFINITY;
 }
 
 void cgroup_context_free_device_allow(CGroupContext *c, CGroupDeviceAllow *a) {
@@ -81,6 +88,7 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) {
         CGroupBlockIODeviceBandwidth *b;
         CGroupBlockIODeviceWeight *w;
         CGroupDeviceAllow *a;
+        char u[FORMAT_TIMESPAN_MAX];
 
         assert(c);
         assert(f);
@@ -92,14 +100,20 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) {
                 "%sBlockIOAccounting=%s\n"
                 "%sMemoryAccounting=%s\n"
                 "%sCPUShares=%lu\n"
+                "%sStartupCPUShares=%lu\n"
+                "%sCPUQuotaPerSecSec=%s\n"
                 "%sBlockIOWeight=%lu\n"
+                "%sStartupBlockIOWeight=%lu\n"
                 "%sMemoryLimit=%" PRIu64 "\n"
                 "%sDevicePolicy=%s\n",
                 prefix, yes_no(c->cpu_accounting),
                 prefix, yes_no(c->blockio_accounting),
                 prefix, yes_no(c->memory_accounting),
                 prefix, c->cpu_shares,
+                prefix, c->startup_cpu_shares,
+                prefix, strna(format_timespan(u, sizeof(u), c->cpu_quota_per_sec_usec, 1)),
                 prefix, c->blockio_weight,
+                prefix, c->startup_blockio_weight,
                 prefix, c->memory_limit,
                 prefix, cgroup_device_policy_to_string(c->device_policy));
 
@@ -186,7 +200,7 @@ static int whitelist_device(const char *path, const char *node, const char *acc)
 
         r = cg_set_attribute("devices", path, "devices.allow", buf);
         if (r < 0)
-                log_warning("Failed to set devices.allow on %s: %s", path, strerror(-r));
+                log_full(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, "Failed to set devices.allow on %s: %s", path, strerror(-r));
 
         return r;
 }
@@ -246,7 +260,8 @@ static int whitelist_major(const char *path, const char *name, char type, const
 
                 w++;
                 w += strspn(w, WHITESPACE);
-                if (!streq(w, name))
+
+                if (fnmatch(name, w, 0) != 0)
                         continue;
 
                 sprintf(buf,
@@ -257,7 +272,7 @@ static int whitelist_major(const char *path, const char *name, char type, const
 
                 r = cg_set_attribute("devices", path, "devices.allow", buf);
                 if (r < 0)
-                        log_warning("Failed to set devices.allow on %s: %s", path, strerror(-r));
+                        log_full(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, "Failed to set devices.allow on %s: %s", path, strerror(-r));
         }
 
         return 0;
@@ -267,7 +282,7 @@ fail:
         return -errno;
 }
 
-void cgroup_context_apply(CGroupContext *c, CGroupControllerMask mask, const char *path) {
+void cgroup_context_apply(CGroupContext *c, CGroupControllerMask mask, const char *path, ManagerState state) {
         bool is_root;
         int r;
 
@@ -282,12 +297,27 @@ void cgroup_context_apply(CGroupContext *c, CGroupControllerMask mask, const cha
         is_root = isempty(path) || path_equal(path, "/");
 
         if ((mask & CGROUP_CPU) && !is_root) {
-                char buf[DECIMAL_STR_MAX(unsigned long) + 1];
+                char buf[MAX(DECIMAL_STR_MAX(unsigned long), DECIMAL_STR_MAX(usec_t)) + 1];
 
-                sprintf(buf, "%lu\n", c->cpu_shares);
+                sprintf(buf, "%lu\n",
+                        state == MANAGER_STARTING && c->startup_cpu_shares != (unsigned long) -1 ? c->startup_cpu_shares :
+                        c->cpu_shares != (unsigned long) -1 ? c->cpu_shares : 1024);
                 r = cg_set_attribute("cpu", path, "cpu.shares", buf);
                 if (r < 0)
-                        log_warning("Failed to set cpu.shares on %s: %s", path, strerror(-r));
+                        log_full(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, "Failed to set cpu.shares on %s: %s", path, strerror(-r));
+
+                sprintf(buf, USEC_FMT "\n", CGROUP_CPU_QUOTA_PERIOD_USEC);
+                r = cg_set_attribute("cpu", path, "cpu.cfs_period_us", buf);
+                if (r < 0)
+                        log_full(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, "Failed to set cpu.cfs_period_us on %s: %s", path, strerror(-r));
+
+                if (c->cpu_quota_per_sec_usec != USEC_INFINITY) {
+                        sprintf(buf, USEC_FMT "\n", c->cpu_quota_per_sec_usec * CGROUP_CPU_QUOTA_PERIOD_USEC / USEC_PER_SEC);
+                        r = cg_set_attribute("cpu", path, "cpu.cfs_quota_us", buf);
+                } else
+                        r = cg_set_attribute("cpu", path, "cpu.cfs_quota_us", "-1");
+                if (r < 0)
+                        log_full(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, "Failed to set cpu.cfs_quota_us on %s: %s", path, strerror(-r));
         }
 
         if (mask & CGROUP_BLKIO) {
@@ -298,10 +328,11 @@ void cgroup_context_apply(CGroupContext *c, CGroupControllerMask mask, const cha
                 CGroupBlockIODeviceBandwidth *b;
 
                 if (!is_root) {
-                        sprintf(buf, "%lu\n", c->blockio_weight);
+                        sprintf(buf, "%lu\n", state == MANAGER_STARTING && c->startup_blockio_weight != (unsigned long) -1 ? c->startup_blockio_weight :
+                                c->blockio_weight != (unsigned long) -1 ? c->blockio_weight : 1000);
                         r = cg_set_attribute("blkio", path, "blkio.weight", buf);
                         if (r < 0)
-                                log_warning("Failed to set blkio.weight on %s: %s", path, strerror(-r));
+                                log_full(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, "Failed to set blkio.weight on %s: %s", path, strerror(-r));
 
                         /* FIXME: no way to reset this list */
                         LIST_FOREACH(device_weights, w, c->blockio_device_weights) {
@@ -314,7 +345,7 @@ void cgroup_context_apply(CGroupContext *c, CGroupControllerMask mask, const cha
                                 sprintf(buf, "%u:%u %lu", major(dev), minor(dev), w->weight);
                                 r = cg_set_attribute("blkio", path, "blkio.weight_device", buf);
                                 if (r < 0)
-                                        log_error("Failed to set blkio.weight_device on %s: %s", path, strerror(-r));
+                                        log_full(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, "Failed to set blkio.weight_device on %s: %s", path, strerror(-r));
                         }
                 }
 
@@ -332,7 +363,7 @@ void cgroup_context_apply(CGroupContext *c, CGroupControllerMask mask, const cha
                         sprintf(buf, "%u:%u %" PRIu64 "\n", major(dev), minor(dev), b->bandwidth);
                         r = cg_set_attribute("blkio", path, a, buf);
                         if (r < 0)
-                                log_error("Failed to set %s on %s: %s", a, path, strerror(-r));
+                                log_full(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, "Failed to set %s on %s: %s", a, path, strerror(-r));
                 }
         }
 
@@ -346,7 +377,7 @@ void cgroup_context_apply(CGroupContext *c, CGroupControllerMask mask, const cha
                         r = cg_set_attribute("memory", path, "memory.limit_in_bytes", "-1");
 
                 if (r < 0)
-                        log_error("Failed to set memory.limit_in_bytes on %s: %s", path, strerror(-r));
+                        log_full(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, "Failed to set memory.limit_in_bytes on %s: %s", path, strerror(-r));
         }
 
         if ((mask & CGROUP_DEVICE) && !is_root) {
@@ -357,21 +388,27 @@ void cgroup_context_apply(CGroupContext *c, CGroupControllerMask mask, const cha
                 else
                         r = cg_set_attribute("devices", path, "devices.allow", "a");
                 if (r < 0)
-                        log_warning("Failed to reset devices.list on %s: %s", path, strerror(-r));
+                        log_full(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, "Failed to reset devices.list on %s: %s", path, strerror(-r));
 
                 if (c->device_policy == CGROUP_CLOSED ||
                     (c->device_policy == CGROUP_AUTO && c->device_allow)) {
                         static const char auto_devices[] =
-                                "/dev/null\0" "rw\0"
-                                "/dev/zero\0" "rw\0"
-                                "/dev/full\0" "rw\0"
-                                "/dev/random\0" "rw\0"
-                                "/dev/urandom\0" "rw\0";
+                                "/dev/null\0" "rwm\0"
+                                "/dev/zero\0" "rwm\0"
+                                "/dev/full\0" "rwm\0"
+                                "/dev/random\0" "rwm\0"
+                                "/dev/urandom\0" "rwm\0"
+                                "/dev/tty\0" "rwm\0"
+                                "/dev/pts/ptmx\0" "rw\0"; /* /dev/pts/ptmx may not be duplicated, but accessed */
 
                         const char *x, *y;
 
                         NULSTR_FOREACH_PAIR(x, y, auto_devices)
                                 whitelist_device(path, x, y);
+
+                        whitelist_major(path, "pts", 'c', "rw");
+                        whitelist_major(path, "kdbus", 'c', "rw");
+                        whitelist_major(path, "kdbus/*", 'c', "rw");
                 }
 
                 LIST_FOREACH(device_allow, a, c->device_allow) {
@@ -407,11 +444,15 @@ CGroupControllerMask cgroup_context_get_mask(CGroupContext *c) {
 
         /* Figure out which controllers we need */
 
-        if (c->cpu_accounting || c->cpu_shares != 1024)
+        if (c->cpu_accounting ||
+            c->cpu_shares != (unsigned long) -1 ||
+            c->startup_cpu_shares != (unsigned long) -1 ||
+            c->cpu_quota_per_sec_usec != USEC_INFINITY)
                 mask |= CGROUP_CPUACCT | CGROUP_CPU;
 
         if (c->blockio_accounting ||
-            c->blockio_weight != 1000 ||
+            c->blockio_weight != (unsigned long) -1 ||
+            c->startup_blockio_weight != (unsigned long) -1 ||
             c->blockio_device_weights ||
             c->blockio_device_bandwidths)
                 mask |= CGROUP_BLKIO;
@@ -467,18 +508,12 @@ CGroupControllerMask unit_get_members_mask(Unit *u) {
 }
 
 CGroupControllerMask unit_get_siblings_mask(Unit *u) {
-        CGroupControllerMask m;
-
         assert(u);
 
         if (UNIT_ISSET(u->slice))
-                m = unit_get_members_mask(UNIT_DEREF(u->slice));
-        else
-                m = unit_get_cgroup_mask(u) | unit_get_members_mask(u);
+                return unit_get_members_mask(UNIT_DEREF(u->slice));
 
-        /* Sibling propagation is only relevant for weight-based
-         * controllers, so let's mask out everything else */
-        return m & (CGROUP_CPU|CGROUP_BLKIO|CGROUP_CPUACCT);
+        return unit_get_cgroup_mask(u) | unit_get_members_mask(u);
 }
 
 CGroupControllerMask unit_get_target_mask(Unit *u) {
@@ -608,7 +643,7 @@ static bool unit_has_mask_realized(Unit *u, CGroupControllerMask mask) {
  * If not, create paths, move processes over, and set attributes.
  *
  * Returns 0 on success and < 0 on failure. */
-static int unit_realize_cgroup_now(Unit *u) {
+static int unit_realize_cgroup_now(Unit *u, ManagerState state) {
         CGroupControllerMask mask;
         int r;
 
@@ -626,7 +661,7 @@ static int unit_realize_cgroup_now(Unit *u) {
 
         /* First, realize parents */
         if (UNIT_ISSET(u->slice)) {
-                r = unit_realize_cgroup_now(UNIT_DEREF(u->slice));
+                r = unit_realize_cgroup_now(UNIT_DEREF(u->slice), state);
                 if (r < 0)
                         return r;
         }
@@ -637,7 +672,7 @@ static int unit_realize_cgroup_now(Unit *u) {
                 return r;
 
         /* Finally, apply the necessary attributes. */
-        cgroup_context_apply(unit_get_cgroup_context(u), mask, u->cgroup_path);
+        cgroup_context_apply(unit_get_cgroup_context(u), mask, u->cgroup_path, state);
 
         return 0;
 }
@@ -652,14 +687,17 @@ static void unit_add_to_cgroup_queue(Unit *u) {
 }
 
 unsigned manager_dispatch_cgroup_queue(Manager *m) {
-        Unit *i;
+        ManagerState state;
         unsigned n = 0;
+        Unit *i;
         int r;
 
+        state = manager_state(m);
+
         while ((i = m->cgroup_queue)) {
                 assert(i->in_cgroup_queue);
 
-                r = unit_realize_cgroup_now(i);
+                r = unit_realize_cgroup_now(i, state);
                 if (r < 0)
                         log_warning("Failed to realize cgroups for queued unit %s: %s", i->id, strerror(-r));
 
@@ -731,7 +769,7 @@ int unit_realize_cgroup(Unit *u) {
         unit_queue_siblings(u);
 
         /* And realize this one now (and apply the values) */
-        return unit_realize_cgroup_now(u);
+        return unit_realize_cgroup_now(u, manager_state(u->manager));
 }
 
 void unit_destroy_cgroup(Unit *u) {
@@ -794,17 +832,10 @@ pid_t unit_search_main_pid(Unit *u) {
 
 int manager_setup_cgroup(Manager *m) {
         _cleanup_free_ char *path = NULL;
-        char *e;
         int r;
 
         assert(m);
 
-        /* 0. Be nice to Ingo Molnar #628004 */
-        if (path_is_mount_point("/sys/fs/cgroup/systemd", false) <= 0) {
-                log_warning("No control group support available, not creating root group.");
-                return 0;
-        }
-
         /* 1. Determine hierarchy */
         free(m->cgroup_root);
         m->cgroup_root = NULL;
@@ -819,6 +850,8 @@ int manager_setup_cgroup(Manager *m) {
          * off. This is to support live upgrades from older systemd
          * versions where PID 1 was moved there. */
         if (m->running_as == SYSTEMD_SYSTEM) {
+                char *e;
+
                 e = endswith(m->cgroup_root, "/" SPECIAL_SYSTEM_SLICE);
                 if (!e)
                         e = endswith(m->cgroup_root, "/system");
@@ -840,41 +873,42 @@ int manager_setup_cgroup(Manager *m) {
         }
 
         log_debug("Using cgroup controller " SYSTEMD_CGROUP_CONTROLLER ". File system hierarchy is at %s.", path);
+        if (!m->test_run) {
 
-        /* 3. Install agent */
-        if (m->running_as == SYSTEMD_SYSTEM) {
-                r = cg_install_release_agent(SYSTEMD_CGROUP_CONTROLLER, SYSTEMD_CGROUP_AGENT_PATH);
-                if (r < 0)
-                        log_warning("Failed to install release agent, ignoring: %s", strerror(-r));
-                else if (r > 0)
-                        log_debug("Installed release agent.");
-                else
-                        log_debug("Release agent already installed.");
-        }
+                /* 3. Install agent */
+                if (m->running_as == SYSTEMD_SYSTEM) {
+                        r = cg_install_release_agent(SYSTEMD_CGROUP_CONTROLLER, SYSTEMD_CGROUP_AGENT_PATH);
+                        if (r < 0)
+                                log_warning("Failed to install release agent, ignoring: %s", strerror(-r));
+                        else if (r > 0)
+                                log_debug("Installed release agent.");
+                        else
+                                log_debug("Release agent already installed.");
+                }
 
-        /* 4. Make sure we are in the root cgroup */
-        r = cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_root, 0);
-        if (r < 0) {
-                log_error("Failed to create root cgroup hierarchy: %s", strerror(-r));
-                return r;
-        }
+                /* 4. Make sure we are in the root cgroup */
+                r = cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_root, 0);
+                if (r < 0) {
+                        log_error("Failed to create root cgroup hierarchy: %s", strerror(-r));
+                        return r;
+                }
 
-        /* 5. And pin it, so that it cannot be unmounted */
-        if (m->pin_cgroupfs_fd >= 0)
-                close_nointr_nofail(m->pin_cgroupfs_fd);
+                /* 5. And pin it, so that it cannot be unmounted */
+                safe_close(m->pin_cgroupfs_fd);
 
-        m->pin_cgroupfs_fd = open(path, O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOCTTY|O_NONBLOCK);
-        if (r < 0) {
-                log_error("Failed to open pin file: %m");
-                return -errno;
+                m->pin_cgroupfs_fd = open(path, O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOCTTY|O_NONBLOCK);
+                if (m->pin_cgroupfs_fd < 0) {
+                        log_error("Failed to open pin file: %m");
+                        return -errno;
+                }
+
+                /* 6.  Always enable hierarchial support if it exists... */
+                cg_set_attribute("memory", "/", "memory.use_hierarchy", "1");
         }
 
-        /* 6. Figure out which controllers are supported */
+        /* 7. Figure out which controllers are supported */
         m->cgroup_supported = cg_mask_supported();
 
-        /* 7.  Always enable hierarchial support if it exists... */
-        cg_set_attribute("memory", "/", "memory.use_hierarchy", "1");
-
         return 0;
 }
 
@@ -886,10 +920,7 @@ void manager_shutdown_cgroup(Manager *m, bool delete) {
         if (delete && m->cgroup_root)
                 cg_trim(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_root, false);
 
-        if (m->pin_cgroupfs_fd >= 0) {
-                close_nointr_nofail(m->pin_cgroupfs_fd);
-                m->pin_cgroupfs_fd = -1;
-        }
+        m->pin_cgroupfs_fd = safe_close(m->pin_cgroupfs_fd);
 
         free(m->cgroup_root);
         m->cgroup_root = NULL;
index be717ad..d299872 100644 (file)
@@ -71,8 +71,11 @@ struct CGroupContext {
         bool memory_accounting;
 
         unsigned long cpu_shares;
+        unsigned long startup_cpu_shares;
+        usec_t cpu_quota_per_sec_usec;
 
         unsigned long blockio_weight;
+        unsigned long startup_blockio_weight;
         LIST_HEAD(CGroupBlockIODeviceWeight, blockio_device_weights);
         LIST_HEAD(CGroupBlockIODeviceBandwidth, blockio_device_bandwidths);
 
@@ -89,7 +92,7 @@ struct CGroupContext {
 void cgroup_context_init(CGroupContext *c);
 void cgroup_context_done(CGroupContext *c);
 void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix);
-void cgroup_context_apply(CGroupContext *c, CGroupControllerMask mask, const char *path);
+void cgroup_context_apply(CGroupContext *c, CGroupControllerMask mask, const char *path, ManagerState state);
 
 CGroupControllerMask cgroup_context_get_mask(CGroupContext *c);
 
index 1448fa1..353e0c9 100644 (file)
@@ -27,7 +27,7 @@
 #include <sys/statvfs.h>
 #include <fnmatch.h>
 
-#include <systemd/sd-id128.h>
+#include "sd-id128.h"
 #include "util.h"
 #include "condition.h"
 #include "virt.h"
@@ -52,14 +52,15 @@ static bool condition_test_security(Condition *c) {
                 return use_ima() == !c->negate;
         if (streq(c->parameter, "smack"))
                 return use_smack() == !c->negate;
+
         return c->negate;
 }
 
 static bool condition_test_capability(Condition *c) {
+        _cleanup_fclose_ FILE *f = NULL;
         cap_value_t value;
-        FILE *f;
         char line[LINE_MAX];
-        unsigned long long capabilities = (unsigned long long) -1;
+        unsigned long long capabilities = -1;
 
         assert(c);
         assert(c->parameter);
@@ -86,11 +87,53 @@ static bool condition_test_capability(Condition *c) {
                 }
         }
 
-        fclose(f);
-
         return !!(capabilities & (1ULL << value)) == !c->negate;
 }
 
+static bool condition_test_needs_update(Condition *c) {
+        const char *p;
+        struct stat usr, other;
+
+        assert(c);
+        assert(c->parameter);
+        assert(c->type == CONDITION_NEEDS_UPDATE);
+
+        /* If the file system is read-only we shouldn't suggest an update */
+        if (path_is_read_only_fs(c->parameter) > 0)
+                return c->negate;
+
+        /* Any other failure means we should allow the condition to be true,
+         * so that we rather invoke too many update tools then too
+         * few. */
+
+        if (!path_is_absolute(c->parameter))
+                return !c->negate;
+
+        p = strappenda(c->parameter, "/.updated");
+        if (lstat(p, &other) < 0)
+                return !c->negate;
+
+        if (lstat("/usr/", &usr) < 0)
+                return !c->negate;
+
+        return (usr.st_mtim.tv_sec > other.st_mtim.tv_sec ||
+                (usr.st_mtim.tv_sec == other.st_mtim.tv_sec && usr.st_mtim.tv_nsec > other.st_mtim.tv_nsec)) == !c->negate;
+}
+
+static bool condition_test_first_boot(Condition *c) {
+        int r;
+
+        assert(c);
+        assert(c->parameter);
+        assert(c->type == CONDITION_FIRST_BOOT);
+
+        r = parse_boolean(c->parameter);
+        if (r < 0)
+                return c->negate;
+
+        return ((access("/run/systemd/first-boot", F_OK) >= 0) == !!r) == !c->negate;
+}
+
 static bool condition_test(Condition *c) {
         assert(c);
 
@@ -170,6 +213,12 @@ static bool condition_test(Condition *c) {
         case CONDITION_ARCHITECTURE:
                 return condition_test_architecture(c);
 
+        case CONDITION_NEEDS_UPDATE:
+                return condition_test_needs_update(c);
+
+        case CONDITION_FIRST_BOOT:
+                return condition_test_first_boot(c);
+
         case CONDITION_NULL:
                 return !c->negate;
 
index 854491b..28f1924 100644 (file)
@@ -30,6 +30,10 @@ static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, busname_result, BusName
 const sd_bus_vtable bus_busname_vtable[] = {
         SD_BUS_VTABLE_START(0),
         SD_BUS_PROPERTY("Name", "s", NULL, offsetof(BusName, name), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("TimeoutUSec", "t", bus_property_get_usec, offsetof(BusName, timeout_usec), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("ControlPID", "u", bus_property_get_pid, offsetof(BusName, control_pid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(BusName, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
+        SD_BUS_PROPERTY("Activating", "b", bus_property_get_bool, offsetof(BusName, activating), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("AcceptFileDescriptors", "b", bus_property_get_bool, offsetof(BusName, accept_fd), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_VTABLE_END
 };
index 775825b..eb7c2b9 100644 (file)
@@ -133,12 +133,51 @@ static int property_get_device_allow(
         return sd_bus_message_close_container(reply);
 }
 
+static int property_get_cpu_quota_per_sec_usec(
+                sd_bus *bus,
+                const char *path,
+                const char *interface,
+                const char *property,
+                sd_bus_message *reply,
+                void *userdata,
+                sd_bus_error *error) {
+
+        CGroupContext *c = userdata;
+
+        assert(bus);
+        assert(reply);
+        assert(c);
+
+        return sd_bus_message_append(reply, "t", c->cpu_quota_per_sec_usec);
+}
+
+static int property_get_ulong_as_u64(
+                sd_bus *bus,
+                const char *path,
+                const char *interface,
+                const char *property,
+                sd_bus_message *reply,
+                void *userdata,
+                sd_bus_error *error) {
+
+        unsigned long *ul = userdata;
+
+        assert(bus);
+        assert(reply);
+        assert(ul);
+
+        return sd_bus_message_append(reply, "t", *ul == (unsigned long) -1 ? (uint64_t) -1 : (uint64_t) *ul);
+}
+
 const sd_bus_vtable bus_cgroup_vtable[] = {
         SD_BUS_VTABLE_START(0),
         SD_BUS_PROPERTY("CPUAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, cpu_accounting), 0),
-        SD_BUS_PROPERTY("CPUShares", "t", bus_property_get_ulong, offsetof(CGroupContext, cpu_shares), 0),
+        SD_BUS_PROPERTY("CPUShares", "t", property_get_ulong_as_u64, offsetof(CGroupContext, cpu_shares), 0),
+        SD_BUS_PROPERTY("StartupCPUShares", "t", property_get_ulong_as_u64, offsetof(CGroupContext, startup_cpu_shares), 0),
+        SD_BUS_PROPERTY("CPUQuotaPerSecUSec", "t", property_get_cpu_quota_per_sec_usec, 0, 0),
         SD_BUS_PROPERTY("BlockIOAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, blockio_accounting), 0),
-        SD_BUS_PROPERTY("BlockIOWeight", "t", bus_property_get_ulong, offsetof(CGroupContext, blockio_weight), 0),
+        SD_BUS_PROPERTY("BlockIOWeight", "t", property_get_ulong_as_u64, offsetof(CGroupContext, blockio_weight), 0),
+        SD_BUS_PROPERTY("StartupBlockIOWeight", "t", property_get_ulong_as_u64, offsetof(CGroupContext, startup_blockio_weight), 0),
         SD_BUS_PROPERTY("BlockIODeviceWeight", "a(st)", property_get_blockio_device_weight, 0, 0),
         SD_BUS_PROPERTY("BlockIOReadBandwidth", "a(st)", property_get_blockio_device_bandwidths, 0, 0),
         SD_BUS_PROPERTY("BlockIOWriteBandwidth", "a(st)", property_get_blockio_device_bandwidths, 0, 0),
@@ -173,6 +212,7 @@ int bus_cgroup_set_property(
 
                 if (mode != UNIT_CHECK) {
                         c->cpu_accounting = b;
+                        u->cgroup_realized_mask &= ~CGROUP_CPUACCT;
                         unit_write_drop_in_private(u, mode, name, b ? "CPUAccounting=yes" : "CPUAccounting=no");
                 }
 
@@ -186,17 +226,64 @@ int bus_cgroup_set_property(
                 if (r < 0)
                         return r;
 
-                ul = (unsigned long) u64;
-                if (ul <= 0 || (uint64_t) ul != u64)
-                        return sd_bus_error_set_errnof(error, EINVAL, "CPUShares value out of range");
+                if (u64 == (uint64_t) -1)
+                        ul = (unsigned long) -1;
+                else {
+                        ul = (unsigned long) u64;
+                        if (ul <= 0 || (uint64_t) ul != u64)
+                                return sd_bus_error_set_errnof(error, EINVAL, "CPUShares value out of range");
+                }
 
                 if (mode != UNIT_CHECK) {
                         c->cpu_shares = ul;
+                        u->cgroup_realized_mask &= ~CGROUP_CPU;
                         unit_write_drop_in_private_format(u, mode, name, "CPUShares=%lu", ul);
                 }
 
                 return 1;
 
+        } else if (streq(name, "StartupCPUShares")) {
+                uint64_t u64;
+                unsigned long ul;
+
+                r = sd_bus_message_read(message, "t", &u64);
+                if (r < 0)
+                        return r;
+
+                if (u64 == (uint64_t) -1)
+                        ul = (unsigned long) -1;
+                else {
+                        ul = (unsigned long) u64;
+                        if (ul <= 0 || (uint64_t) ul != u64)
+                                return sd_bus_error_set_errnof(error, EINVAL, "StartupCPUShares value out of range");
+                }
+
+                if (mode != UNIT_CHECK) {
+                        c->startup_cpu_shares = ul;
+                        u->cgroup_realized_mask &= ~CGROUP_CPU;
+                        unit_write_drop_in_private_format(u, mode, name, "StartupCPUShares=%lu", ul);
+                }
+
+                return 1;
+
+        } else if (streq(name, "CPUQuotaPerSecUSec")) {
+                uint64_t u64;
+
+                r = sd_bus_message_read(message, "t", &u64);
+                if (r < 0)
+                        return r;
+
+                if (u64 <= 0)
+                        return sd_bus_error_set_errnof(error, EINVAL, "CPUQuotaPerSecUSec value out of range");
+
+                if (mode != UNIT_CHECK) {
+                        c->cpu_quota_per_sec_usec = u64;
+                        u->cgroup_realized_mask &= ~CGROUP_CPU;
+                        unit_write_drop_in_private_format(u, mode, "CPUQuota", "CPUQuota=%0.f%%", (double) (c->cpu_quota_per_sec_usec / 10000));
+                }
+
+                return 1;
+
         } else if (streq(name, "BlockIOAccounting")) {
                 int b;
 
@@ -206,6 +293,7 @@ int bus_cgroup_set_property(
 
                 if (mode != UNIT_CHECK) {
                         c->blockio_accounting = b;
+                        u->cgroup_realized_mask &= ~CGROUP_BLKIO;
                         unit_write_drop_in_private(u, mode, name, b ? "BlockIOAccounting=yes" : "BlockIOAccounting=no");
                 }
 
@@ -219,17 +307,46 @@ int bus_cgroup_set_property(
                 if (r < 0)
                         return r;
 
-                ul = (unsigned long) u64;
-                if (ul < 10 || ul > 1000)
-                        return sd_bus_error_set_errnof(error, EINVAL, "BlockIOWeight value out of range");
+                if (u64 == (uint64_t) -1)
+                        ul = (unsigned long) -1;
+                else  {
+                        ul = (unsigned long) u64;
+                        if (ul < 10 || ul > 1000)
+                                return sd_bus_error_set_errnof(error, EINVAL, "BlockIOWeight value out of range");
+                }
 
                 if (mode != UNIT_CHECK) {
                         c->blockio_weight = ul;
+                        u->cgroup_realized_mask &= ~CGROUP_BLKIO;
                         unit_write_drop_in_private_format(u, mode, name, "BlockIOWeight=%lu", ul);
                 }
 
                 return 1;
 
+        } else if (streq(name, "StartupBlockIOWeight")) {
+                uint64_t u64;
+                unsigned long ul;
+
+                r = sd_bus_message_read(message, "t", &u64);
+                if (r < 0)
+                        return r;
+
+                if (u64 == (uint64_t) -1)
+                        ul = (unsigned long) -1;
+                else  {
+                        ul = (unsigned long) u64;
+                        if (ul < 10 || ul > 1000)
+                                return sd_bus_error_set_errnof(error, EINVAL, "StartupBlockIOWeight value out of range");
+                }
+
+                if (mode != UNIT_CHECK) {
+                        c->startup_blockio_weight = ul;
+                        u->cgroup_realized_mask &= ~CGROUP_BLKIO;
+                        unit_write_drop_in_private_format(u, mode, name, "StartupBlockIOWeight=%lu", ul);
+                }
+
+                return 1;
+
         } else if (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth")) {
                 const char *path;
                 bool read = true;
@@ -294,6 +411,8 @@ int bus_cgroup_set_property(
                                                 cgroup_context_free_blockio_device_bandwidth(c, a);
                         }
 
+                        u->cgroup_realized_mask &= ~CGROUP_BLKIO;
+
                         f = open_memstream(&buf, &size);
                         if (!f)
                                 return -ENOMEM;
@@ -375,6 +494,8 @@ int bus_cgroup_set_property(
                                         cgroup_context_free_blockio_device_weight(c, c->blockio_device_weights);
                         }
 
+                        u->cgroup_realized_mask &= ~CGROUP_BLKIO;
+
                         f = open_memstream(&buf, &size);
                         if (!f)
                                 return -ENOMEM;
@@ -398,6 +519,7 @@ int bus_cgroup_set_property(
 
                 if (mode != UNIT_CHECK) {
                         c->memory_accounting = b;
+                        u->cgroup_realized_mask &= ~CGROUP_MEMORY;
                         unit_write_drop_in_private(u, mode, name, b ? "MemoryAccounting=yes" : "MemoryAccounting=no");
                 }
 
@@ -412,6 +534,7 @@ int bus_cgroup_set_property(
 
                 if (mode != UNIT_CHECK) {
                         c->memory_limit = limit;
+                        u->cgroup_realized_mask &= ~CGROUP_MEMORY;
                         unit_write_drop_in_private_format(u, mode, name, "%s=%" PRIu64, name, limit);
                 }
 
@@ -433,6 +556,7 @@ int bus_cgroup_set_property(
                         char *buf;
 
                         c->device_policy = p;
+                        u->cgroup_realized_mask &= ~CGROUP_DEVICE;
 
                         buf = strappenda("DevicePolicy=", policy);
                         unit_write_drop_in_private(u, mode, name, buf);
@@ -511,6 +635,8 @@ int bus_cgroup_set_property(
                                         cgroup_context_free_device_allow(c, c->device_allow);
                         }
 
+                        u->cgroup_realized_mask &= ~CGROUP_DEVICE;
+
                         f = open_memstream(&buf, &size);
                         if (!f)
                                 return -ENOMEM;
diff --git a/src/core/dbus-client-track.c b/src/core/dbus-client-track.c
deleted file mode 100644 (file)
index 07dfea4..0000000
+++ /dev/null
@@ -1,251 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
-  This file is part of systemd.
-
-  Copyright 2013 Lennart Poettering
-
-  systemd is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation; either version 2.1 of the License, or
-  (at your option) any later version.
-
-  systemd is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "bus-util.h"
-#include "dbus-client-track.h"
-
-static unsigned long tracked_client_hash(const void *a, const uint8_t hash_key[HASH_KEY_SIZE]) {
-        const BusTrackedClient *x = a;
-
-        return string_hash_func(x->name, hash_key) ^ trivial_hash_func(x->bus, hash_key);
-}
-
-static int tracked_client_compare(const void *a, const void *b) {
-        const BusTrackedClient *x = a, *y = b;
-        int r;
-
-        r = strcmp(x->name, y->name);
-        if (r != 0)
-                return r;
-
-        if (x->bus < y->bus)
-                return -1;
-        if (x->bus > y->bus)
-                return 1;
-
-        return 0;
-}
-
-static int on_name_owner_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
-        BusTrackedClient *c = userdata;
-        const char *name, *old, *new;
-        int r;
-
-        assert(bus);
-        assert(message);
-
-        r = sd_bus_message_read(message, "sss", &name, &old, &new);
-        if (r < 0) {
-                bus_log_parse_error(r);
-                return r;
-        }
-
-        bus_client_untrack(c->set, bus, name);
-        return 0;
-}
-
-static char *build_match(const char *name) {
-
-        return strjoin("type='signal',"
-                       "sender='org.freedesktop.DBus',"
-                       "path='/org/freedesktop/DBus',"
-                       "interface='org.freedesktop.DBus',"
-                       "member='NameOwnerChanged',"
-                       "arg0='", name, "'", NULL);
-}
-
-int bus_client_track(Set **s, sd_bus *bus, const char *name) {
-        BusTrackedClient *c, *found;
-        size_t l;
-        int r;
-
-        assert(s);
-        assert(bus);
-
-        r = set_ensure_allocated(s, tracked_client_hash, tracked_client_compare);
-        if (r < 0)
-                return r;
-
-        name = strempty(name);
-
-        l = strlen(name);
-
-        c = alloca(offsetof(BusTrackedClient, name) + l + 1);
-        c->set = *s;
-        c->bus = bus;
-        strcpy(c->name, name);
-
-        found = set_get(*s, c);
-        if (found)
-                return 0;
-
-        c = memdup(c, offsetof(BusTrackedClient, name) + l + 1);
-        if (!c)
-                return -ENOMEM;
-
-        r = set_put(*s, c);
-        if (r < 0) {
-                free(c);
-                return r;
-        }
-
-        if (!isempty(name)) {
-                _cleanup_free_ char *match = NULL;
-
-                match = build_match(name);
-                if (!match) {
-                        set_remove(*s, c);
-                        free(c);
-                        return -ENOMEM;
-                }
-
-                r = sd_bus_add_match(bus, match, on_name_owner_changed, c);
-                if (r < 0) {
-                        set_remove(*s, c);
-                        free(c);
-                        return r;
-                }
-        }
-
-        sd_bus_ref(c->bus);
-        return 1;
-}
-
-static void bus_client_free_one(Set *s, BusTrackedClient *c) {
-        assert(s);
-        assert(c);
-
-        if (!isempty(c->name)) {
-                _cleanup_free_ char *match = NULL;
-
-                match = build_match(c->name);
-                if (match)
-                        sd_bus_remove_match(c->bus, match, on_name_owner_changed, c);
-        }
-
-        sd_bus_unref(c->bus);
-        set_remove(s, c);
-        free(c);
-}
-
-int bus_client_untrack(Set *s, sd_bus *bus, const char *name) {
-        BusTrackedClient *c, *found;
-        size_t l;
-
-        assert(bus);
-        assert(s);
-        assert(name);
-
-        name = strempty(name);
-
-        l = strlen(name);
-
-        c = alloca(offsetof(BusTrackedClient, name) + l + 1);
-        c->bus = bus;
-        strcpy(c->name, name);
-
-        found = set_get(s, c);
-        if (!found)
-                return 0;
-
-        bus_client_free_one(s, found);
-        return 1;
-}
-
-void bus_client_track_free(Set *s) {
-        BusTrackedClient *c;
-
-        while ((c = set_first(s)))
-                bus_client_free_one(s, c);
-
-        set_free(s);
-}
-
-int bus_client_untrack_bus(Set *s, sd_bus *bus) {
-        BusTrackedClient *c;
-        Iterator i;
-        int r = 0;
-
-        SET_FOREACH(c, s, i)
-                if (c->bus == bus) {
-                        bus_client_free_one(s, c);
-                        r++;
-                }
-
-        return r;
-}
-
-void bus_client_track_serialize(Manager *m, FILE *f, Set *s) {
-        BusTrackedClient *c;
-        Iterator i;
-
-        assert(m);
-        assert(f);
-
-        SET_FOREACH(c, s, i) {
-                if (c->bus == m->api_bus)
-                        fprintf(f, "subscribed=%s\n", isempty(c->name) ? "*" : c->name);
-                else
-                        fprintf(f, "subscribed=%p %s\n", c->bus, isempty(c->name) ? "*" : c->name);
-        }
-}
-
-int bus_client_track_deserialize_item(Manager *m, Set **s, const char *line) {
-        const char *e, *q, *name;
-        sd_bus *bus;
-        void *p;
-        int r;
-
-        e = startswith(line, "subscribed=");
-        if (!e)
-                return 0;
-
-        q = strpbrk(e, WHITESPACE);
-        if (!q) {
-                if (m->api_bus) {
-                        bus = m->api_bus;
-                        name = e;
-                        goto finish;
-                }
-
-                return 1;
-        }
-
-        if (sscanf(e, "%p", &p) != 1) {
-                log_debug("Failed to parse subscription pointer.");
-                return -EINVAL;
-        }
-
-        bus = set_get(m->private_buses, p);
-        if (!bus)
-                return 1;
-
-        name = q + strspn(q, WHITESPACE);
-
-finish:
-        r = bus_client_track(s, bus, streq(name, "*") ? NULL : name);
-        if (r < 0) {
-                log_debug("Failed to deserialize client subscription: %s", strerror(-r));
-                return r;
-        }
-
-        return 1;
-}
index 935c62b..bbcd610 100644 (file)
@@ -34,6 +34,8 @@
 #include "dbus-execute.h"
 #include "capability.h"
 #include "env-util.h"
+#include "af-list.h"
+#include "namespace.h"
 
 #ifdef HAVE_SECCOMP
 #include "seccomp-util.h"
@@ -43,6 +45,9 @@ BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_exec_output, exec_output, ExecOutp
 
 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_input, exec_input, ExecInput);
 
+static BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_protect_home, protect_home, ProtectHome);
+static BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_protect_system, protect_system, ProtectSystem);
+
 static int property_get_environment_files(
                 sd_bus *bus,
                 const char *path,
@@ -86,6 +91,7 @@ static int property_get_rlimit(
 
         struct rlimit *rl;
         uint64_t u;
+        rlim_t x;
 
         assert(bus);
         assert(reply);
@@ -93,7 +99,7 @@ static int property_get_rlimit(
 
         rl = *(struct rlimit**) userdata;
         if (rl)
-                u = (uint64_t) rl->rlim_max;
+                x = rl->rlim_max;
         else {
                 struct rlimit buf = {};
                 int z;
@@ -102,10 +108,14 @@ static int property_get_rlimit(
                 assert(z >= 0);
 
                 getrlimit(z, &buf);
-
-                u = (uint64_t) buf.rlim_max;
+                x = buf.rlim_max;
         }
 
+        /* rlim_t might have different sizes, let's map
+         * RLIMIT_INFINITY to (uint64_t) -1, so that it is the same on
+         * all archs */
+        u = x == RLIM_INFINITY ? (uint64_t) -1 : (uint64_t) x;
+
         return sd_bus_message_append(reply, "t", u);
 }
 
@@ -290,7 +300,7 @@ static int property_get_timer_slack_nsec(
         assert(reply);
         assert(c);
 
-        if (c->timer_slack_nsec != (nsec_t) -1)
+        if (c->timer_slack_nsec != NSEC_INFINITY)
                 u = (uint64_t) c->timer_slack_nsec;
         else
                 u = (uint64_t) prctl(PR_GET_TIMERSLACK);
@@ -384,11 +394,9 @@ static int property_get_syscall_filter(
                 if (!name)
                         continue;
 
-                r = strv_push(&l, name);
-                if (r < 0) {
-                        free(name);
-                        return -ENOMEM;
-                }
+                r = strv_consume(&l, name);
+                if (r < 0)
+                        return r;
         }
 #endif
 
@@ -500,6 +508,24 @@ static int property_get_apparmor_profile(
         return sd_bus_message_append(reply, "(bs)", c->apparmor_profile_ignore, c->apparmor_profile);
 }
 
+static int property_get_smack_process_label(
+                sd_bus *bus,
+                const char *path,
+                const char *interface,
+                const char *property,
+                sd_bus_message *reply,
+                void *userdata,
+                sd_bus_error *error) {
+
+        ExecContext *c = userdata;
+
+        assert(bus);
+        assert(reply);
+        assert(c);
+
+        return sd_bus_message_append(reply, "(bs)", c->smack_process_label_ignore, c->smack_process_label);
+}
+
 static int property_get_personality(
                 sd_bus *bus,
                 const char *path,
@@ -518,6 +544,54 @@ static int property_get_personality(
         return sd_bus_message_append(reply, "s", personality_to_string(c->personality));
 }
 
+static int property_get_address_families(
+                sd_bus *bus,
+                const char *path,
+                const char *interface,
+                const char *property,
+                sd_bus_message *reply,
+                void *userdata,
+                sd_bus_error *error) {
+
+        ExecContext *c = userdata;
+        _cleanup_strv_free_ char **l = NULL;
+        Iterator i;
+        void *af;
+        int r;
+
+        assert(bus);
+        assert(reply);
+        assert(c);
+
+        r = sd_bus_message_open_container(reply, 'r', "bas");
+        if (r < 0)
+                return r;
+
+        r = sd_bus_message_append(reply, "b", c->address_families_whitelist);
+        if (r < 0)
+                return r;
+
+        SET_FOREACH(af, c->address_families, i) {
+                const char *name;
+
+                name = af_to_name(PTR_TO_INT(af));
+                if (!name)
+                        continue;
+
+                r = strv_extend(&l, name);
+                if (r < 0)
+                        return -ENOMEM;
+        }
+
+        strv_sort(l);
+
+        r = sd_bus_message_append_strv(reply, l);
+        if (r < 0)
+                return r;
+
+        return sd_bus_message_close_container(reply);
+}
+
 const sd_bus_vtable bus_exec_vtable[] = {
         SD_BUS_VTABLE_START(0),
         SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(ExecContext, environment), SD_BUS_VTABLE_PROPERTY_CONST),
@@ -566,7 +640,6 @@ const sd_bus_vtable bus_exec_vtable[] = {
         SD_BUS_PROPERTY("User", "s", NULL, offsetof(ExecContext, user), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("Group", "s", NULL, offsetof(ExecContext, group), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("SupplementaryGroups", "as", NULL, offsetof(ExecContext, supplementary_groups), SD_BUS_VTABLE_PROPERTY_CONST),
-        SD_BUS_PROPERTY("TCPWrapName", "s", NULL, offsetof(ExecContext, tcpwrap_name), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("PAMName", "s", NULL, offsetof(ExecContext, pam_name), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("ReadWriteDirectories", "as", NULL, offsetof(ExecContext, read_write_dirs), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("ReadOnlyDirectories", "as", NULL, offsetof(ExecContext, read_only_dirs), SD_BUS_VTABLE_PROPERTY_CONST),
@@ -575,16 +648,22 @@ const sd_bus_vtable bus_exec_vtable[] = {
         SD_BUS_PROPERTY("PrivateTmp", "b", bus_property_get_bool, offsetof(ExecContext, private_tmp), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("PrivateNetwork", "b", bus_property_get_bool, offsetof(ExecContext, private_network), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("PrivateDevices", "b", bus_property_get_bool, offsetof(ExecContext, private_devices), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("ProtectHome", "s", bus_property_get_protect_home, offsetof(ExecContext, protect_home), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("ProtectSystem", "s", bus_property_get_protect_system, offsetof(ExecContext, protect_system), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("SameProcessGroup", "b", bus_property_get_bool, offsetof(ExecContext, same_pgrp), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("UtmpIdentifier", "s", NULL, offsetof(ExecContext, utmp_id), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("SELinuxContext", "(bs)", property_get_selinux_context, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("AppArmorProfile", "(bs)", property_get_apparmor_profile, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("SmackProcessLabel", "(bs)", property_get_smack_process_label, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("IgnoreSIGPIPE", "b", bus_property_get_bool, offsetof(ExecContext, ignore_sigpipe), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("NoNewPrivileges", "b", bus_property_get_bool, offsetof(ExecContext, no_new_privileges), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("SystemCallFilter", "(bas)", property_get_syscall_filter, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("SystemCallArchitectures", "as", property_get_syscall_archs, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("SystemCallErrorNumber", "i", property_get_syscall_errno, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("Personality", "s", property_get_personality, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("RestrictAddressFamilies", "(bas)", property_get_address_families, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("RuntimeDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, runtime_directory_mode), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("RuntimeDirectory", "as", NULL, offsetof(ExecContext, runtime_directory), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_VTABLE_END
 };
 
@@ -788,7 +867,7 @@ int bus_exec_context_set_transient_property(
                         strv_free(c->environment);
                         c->environment = e;
 
-                        joined = strv_join(c->environment, " ");
+                        joined = strv_join_quoted(c->environment);
                         if (!joined)
                                 return -ENOMEM;
 
@@ -796,6 +875,44 @@ int bus_exec_context_set_transient_property(
                 }
 
                 return 1;
+
+        } else if (rlimit_from_string(name) >= 0) {
+                uint64_t rl;
+                rlim_t x;
+
+                r = sd_bus_message_read(message, "t", &rl);
+                if (r < 0)
+                        return r;
+
+                if (rl == (uint64_t) -1)
+                        x = RLIM_INFINITY;
+                else {
+                        x = (rlim_t) rl;
+
+                        if ((uint64_t) x != rl)
+                                return -ERANGE;
+                }
+
+                if (mode != UNIT_CHECK) {
+                        int z;
+
+                        z = rlimit_from_string(name);
+
+                        if (!c->rlimit[z]) {
+                                c->rlimit[z] = new(struct rlimit, 1);
+                                if (!c->rlimit[z])
+                                        return -ENOMEM;
+                        }
+
+                        c->rlimit[z]->rlim_cur = c->rlimit[z]->rlim_max = x;
+
+                        if (x == RLIM_INFINITY)
+                                unit_write_drop_in_private_format(u, mode, name, "%s=infinity\n", name);
+                        else
+                                unit_write_drop_in_private_format(u, mode, name, "%s=%" PRIu64 "\n", name, rl);
+                }
+
+                return 1;
         }
 
         return 0;
index a8eae47..3f7a28a 100644 (file)
 #include "selinux-access.h"
 #include "job.h"
 #include "dbus-job.h"
-#include "dbus-client-track.h"
+#include "dbus.h"
 
 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_type, job_type, JobType);
 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_state, job_state, JobState);
 
+static int verify_sys_admin_or_owner_sync(sd_bus_message *message, Job *j, sd_bus_error *error) {
+        int r;
+
+        if (sd_bus_track_contains(j->clients, sd_bus_message_get_sender(message)))
+                return 0; /* One of the job owners is calling us */
+
+        r = sd_bus_query_sender_privilege(message, CAP_SYS_ADMIN);
+        if (r < 0)
+                return r;
+        if (r == 0)
+                return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Access denied to perform action");
+
+        /* Root has called us */
+        return 0;
+}
+
 static int property_get_unit(
                 sd_bus *bus,
                 const char *path,
@@ -52,7 +68,7 @@ static int property_get_unit(
         return sd_bus_message_append(reply, "(so)", j->unit->id, p);
 }
 
-static int method_cancel(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
+int bus_job_method_cancel(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
         Job *j = userdata;
         int r;
 
@@ -60,7 +76,11 @@ static int method_cancel(sd_bus *bus, sd_bus_message *message, void *userdata, s
         assert(message);
         assert(j);
 
-        r = selinux_unit_access_check(j->unit, bus, message, "stop", error);
+        r = verify_sys_admin_or_owner_sync(message, j, error);
+        if (r < 0)
+                return r;
+
+        r = selinux_unit_access_check(j->unit, message, "stop", error);
         if (r < 0)
                 return r;
 
@@ -71,7 +91,7 @@ static int method_cancel(sd_bus *bus, sd_bus_message *message, void *userdata, s
 
 const sd_bus_vtable bus_job_vtable[] = {
         SD_BUS_VTABLE_START(0),
-        SD_BUS_METHOD("Cancel", NULL, NULL, method_cancel, 0),
+        SD_BUS_METHOD("Cancel", NULL, NULL, bus_job_method_cancel, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_PROPERTY("Id", "u", NULL, offsetof(Job, id), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("Unit", "(so)", property_get_unit, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("JobType", "s", property_get_type, offsetof(Job, type), SD_BUS_VTABLE_PROPERTY_CONST),
@@ -79,53 +99,10 @@ const sd_bus_vtable bus_job_vtable[] = {
         SD_BUS_VTABLE_END
 };
 
-static int foreach_client(Job *j, int (*send_message)(sd_bus *bus, const char *name, Job *j)) {
-        BusTrackedClient *one_destination = NULL;
-        Iterator i;
-        sd_bus *b;
-        unsigned n, m;
-        int r, ret;
-
-        assert(j);
-        assert(send_message);
-
-        n = set_size(j->manager->subscribed);
-        m = set_size(j->subscribed);
-
-        if (n <= 0 && m <= 0)
-                return 0;
-
-        if (n == 1 && m == 0)
-                one_destination = set_first(j->manager->subscribed);
-        else if (n == 0 && m == 1)
-                one_destination = set_first(j->subscribed);
-        else
-                one_destination = NULL;
-
-        if (one_destination)
-                return send_message(one_destination->bus, isempty(one_destination->name) ? NULL : one_destination->name, j);
-
-        ret = 0;
-
-        /* Send to everybody */
-        SET_FOREACH(b, j->manager->private_buses, i) {
-                r = send_message(b, NULL, j);
-                if (r < 0)
-                        ret = r;
-        }
-
-        if (j->manager->api_bus) {
-                r = send_message(j->manager->api_bus, NULL, j);
-                if (r < 0)
-                        ret = r;
-        }
-
-        return ret;
-}
-
-static int send_new_signal(sd_bus *bus, const char *destination, Job *j) {
+static int send_new_signal(sd_bus *bus, void *userdata) {
         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
         _cleanup_free_ char *p = NULL;
+        Job *j = userdata;
         int r;
 
         assert(bus);
@@ -148,11 +125,12 @@ static int send_new_signal(sd_bus *bus, const char *destination, Job *j) {
         if (r < 0)
                 return r;
 
-        return sd_bus_send_to(bus, m, destination, NULL);
+        return sd_bus_send(bus, m, NULL);
 }
 
-static int send_changed_signal(sd_bus *bus, const char *destination, Job *j) {
+static int send_changed_signal(sd_bus *bus, void *userdata) {
         _cleanup_free_ char *p = NULL;
+        Job *j = userdata;
 
         assert(bus);
         assert(j);
@@ -174,16 +152,17 @@ void bus_job_send_change_signal(Job *j) {
                 j->in_dbus_queue = false;
         }
 
-        r = foreach_client(j, j->sent_dbus_new_signal ? send_changed_signal : send_new_signal);
+        r = bus_foreach_bus(j->manager, j->clients, j->sent_dbus_new_signal ? send_changed_signal : send_new_signal, j);
         if (r < 0)
                 log_debug("Failed to send job change signal for %u: %s", j->id, strerror(-r));
 
         j->sent_dbus_new_signal = true;
 }
 
-static int send_removed_signal(sd_bus *bus, const char *destination, Job *j) {
+static int send_removed_signal(sd_bus *bus, void *userdata) {
         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
         _cleanup_free_ char *p = NULL;
+        Job *j = userdata;
         int r;
 
         assert(bus);
@@ -193,7 +172,6 @@ static int send_removed_signal(sd_bus *bus, const char *destination, Job *j) {
         if (!p)
                 return -ENOMEM;
 
-
         r = sd_bus_message_new_signal(
                         bus,
                         &m,
@@ -207,7 +185,7 @@ static int send_removed_signal(sd_bus *bus, const char *destination, Job *j) {
         if (r < 0)
                 return r;
 
-        return sd_bus_send_to(bus, m, destination, NULL);
+        return sd_bus_send(bus, m, NULL);
 }
 
 void bus_job_send_removed_signal(Job *j) {
@@ -218,7 +196,7 @@ void bus_job_send_removed_signal(Job *j) {
         if (!j->sent_dbus_new_signal)
                 bus_job_send_change_signal(j);
 
-        r = foreach_client(j, send_removed_signal);
+        r = bus_foreach_bus(j->manager, j->clients, send_removed_signal, j);
         if (r < 0)
                 log_debug("Failed to send job remove signal for %u: %s", j->id, strerror(-r));
 }
index d1d0f6d..6c2fc07 100644 (file)
@@ -26,5 +26,7 @@
 
 extern const sd_bus_vtable bus_job_vtable[];
 
+int bus_job_method_cancel(sd_bus *bus, sd_bus_message *message, void *job, sd_bus_error *error);
+
 void bus_job_send_change_signal(Job *j);
 void bus_job_send_removed_signal(Job *j);
index 86816f6..008cf6b 100644 (file)
 #include "install.h"
 #include "selinux-access.h"
 #include "watchdog.h"
-#include "hwclock.h"
+#include "clock-util.h"
 #include "path-util.h"
 #include "virt.h"
+#include "architecture.h"
 #include "env-util.h"
 #include "dbus.h"
+#include "dbus-job.h"
 #include "dbus-manager.h"
 #include "dbus-unit.h"
 #include "dbus-snapshot.h"
-#include "dbus-client-track.h"
 #include "dbus-execute.h"
 #include "bus-errors.h"
 
@@ -89,6 +90,21 @@ static int property_get_virtualization(
         return sd_bus_message_append(reply, "s", id);
 }
 
+static int property_get_architecture(
+                sd_bus *bus,
+                const char *path,
+                const char *interface,
+                const char *property,
+                sd_bus_message *reply,
+                void *userdata,
+                sd_bus_error *error) {
+
+        assert(bus);
+        assert(reply);
+
+        return sd_bus_message_append(reply, "s", architecture_to_string(uname_architecture()));
+}
+
 static int property_get_tainted(
                 sd_bus *bus,
                 const char *path,
@@ -115,7 +131,7 @@ static int property_get_tainted(
         if (access("/proc/cgroups", F_OK) < 0)
                 e = stpcpy(e, "cgroups-missing:");
 
-        if (hwclock_is_localtime() > 0)
+        if (clock_is_localtime() > 0)
                 e = stpcpy(e, "local-hwclock:");
 
         /* remove the last ':' */
@@ -224,6 +240,24 @@ static int property_get_n_names(
         return sd_bus_message_append(reply, "u", (uint32_t) hashmap_size(m->units));
 }
 
+static int property_get_n_failed_units(
+                sd_bus *bus,
+                const char *path,
+                const char *interface,
+                const char *property,
+                sd_bus_message *reply,
+                void *userdata,
+                sd_bus_error *error) {
+
+        Manager *m = userdata;
+
+        assert(bus);
+        assert(reply);
+        assert(m);
+
+        return sd_bus_message_append(reply, "u", (uint32_t) set_size(m->failed_units));
+}
+
 static int property_get_n_jobs(
                 sd_bus *bus,
                 const char *path,
@@ -266,6 +300,24 @@ static int property_get_progress(
         return sd_bus_message_append(reply, "d", d);
 }
 
+static int property_get_system_state(
+                sd_bus *bus,
+                const char *path,
+                const char *interface,
+                const char *property,
+                sd_bus_message *reply,
+                void *userdata,
+                sd_bus_error *error) {
+
+        Manager *m = userdata;
+
+        assert(bus);
+        assert(reply);
+        assert(m);
+
+        return sd_bus_message_append(reply, "s", manager_state_to_string(manager_state(m)));
+}
+
 static int property_set_runtime_watchdog(
                 sd_bus *bus,
                 const char *path,
@@ -301,6 +353,8 @@ static int method_get_unit(sd_bus *bus, sd_bus_message *message, void *userdata,
         assert(message);
         assert(m);
 
+        /* Anyone can call this method */
+
         r = sd_bus_message_read(message, "s", &name);
         if (r < 0)
                 return r;
@@ -309,7 +363,7 @@ static int method_get_unit(sd_bus *bus, sd_bus_message *message, void *userdata,
         if (!u)
                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not loaded.", name);
 
-        r = selinux_unit_access_check(u, bus, message, "status", error);
+        r = selinux_unit_access_check(u, message, "status", error);
         if (r < 0)
                 return r;
 
@@ -333,6 +387,8 @@ static int method_get_unit_by_pid(sd_bus *bus, sd_bus_message *message, void *us
 
         assert_cc(sizeof(pid_t) == sizeof(uint32_t));
 
+        /* Anyone can call this method */
+
         r = sd_bus_message_read(message, "u", &pid);
         if (r < 0)
                 return r;
@@ -353,7 +409,7 @@ static int method_get_unit_by_pid(sd_bus *bus, sd_bus_message *message, void *us
         if (!u)
                 return sd_bus_error_setf(error, BUS_ERROR_NO_UNIT_FOR_PID, "PID %u does not belong to any loaded unit.", pid);
 
-        r = selinux_unit_access_check(u, bus, message, "status", error);
+        r = selinux_unit_access_check(u, message, "status", error);
         if (r < 0)
                 return r;
 
@@ -375,6 +431,8 @@ static int method_load_unit(sd_bus *bus, sd_bus_message *message, void *userdata
         assert(message);
         assert(m);
 
+        /* Anyone can call this method */
+
         r = sd_bus_message_read(message, "s", &name);
         if (r < 0)
                 return r;
@@ -383,7 +441,7 @@ static int method_load_unit(sd_bus *bus, sd_bus_message *message, void *userdata
         if (r < 0)
                 return r;
 
-        r = selinux_unit_access_check(u, bus, message, "status", error);
+        r = selinux_unit_access_check(u, message, "status", error);
         if (r < 0)
                 return r;
 
@@ -403,6 +461,12 @@ static int method_start_unit_generic(sd_bus *bus, sd_bus_message *message, Manag
         assert(message);
         assert(m);
 
+        r = bus_verify_manage_unit_async(m, message, error);
+        if (r < 0)
+                return r;
+        if (r == 0)
+                return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
+
         r = sd_bus_message_read(message, "s", &name);
         if (r < 0)
                 return r;
@@ -452,6 +516,12 @@ static int method_start_unit_replace(sd_bus *bus, sd_bus_message *message, void
         assert(message);
         assert(m);
 
+        r = bus_verify_manage_unit_async(m, message, error);
+        if (r < 0)
+                return r;
+        if (r == 0)
+                return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
+
         r = sd_bus_message_read(message, "s", &old_name);
         if (r < 0)
                 return r;
@@ -473,6 +543,13 @@ static int method_kill_unit(sd_bus *bus, sd_bus_message *message, void *userdata
         assert(message);
         assert(m);
 
+        /* Like bus_verify_manage_unit_async(), but uses CAP_SYS_KILL */
+        r = bus_verify_manage_unit_async_for_kill(m, message, error);
+        if (r < 0)
+                return r;
+        if (r == 0)
+                return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
+
         r = sd_bus_message_read(message, "s", &name);
         if (r < 0)
                 return r;
@@ -494,6 +571,12 @@ static int method_reset_failed_unit(sd_bus *bus, sd_bus_message *message, void *
         assert(message);
         assert(m);
 
+        r = bus_verify_manage_unit_async(m, message, error);
+        if (r < 0)
+                return r;
+        if (r == 0)
+                return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
+
         r = sd_bus_message_read(message, "s", &name);
         if (r < 0)
                 return r;
@@ -515,6 +598,12 @@ static int method_set_unit_properties(sd_bus *bus, sd_bus_message *message, void
         assert(message);
         assert(m);
 
+        r = bus_verify_manage_unit_async(m, message, error);
+        if (r < 0)
+                return r;
+        if (r == 0)
+                return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
+
         r = sd_bus_message_read(message, "s", &name);
         if (r < 0)
                 return r;
@@ -538,6 +627,12 @@ static int method_start_transient_unit(sd_bus *bus, sd_bus_message *message, voi
         assert(message);
         assert(m);
 
+        r = bus_verify_manage_unit_async(m, message, error);
+        if (r < 0)
+                return r;
+        if (r == 0)
+                return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
+
         r = sd_bus_message_read(message, "ss", &name, &smode);
         if (r < 0)
                 return r;
@@ -553,7 +648,7 @@ static int method_start_transient_unit(sd_bus *bus, sd_bus_message *message, voi
         if (mode < 0)
                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Job mode %s is invalid.", smode);
 
-        r = selinux_access_check(bus, message, "start", error);
+        r = selinux_access_check(message, "start", error);
         if (r < 0)
                 return r;
 
@@ -597,6 +692,8 @@ static int method_get_job(sd_bus *bus, sd_bus_message *message, void *userdata,
         assert(message);
         assert(m);
 
+        /* Anyone can call this method */
+
         r = sd_bus_message_read(message, "u", &id);
         if (r < 0)
                 return r;
@@ -605,7 +702,7 @@ static int method_get_job(sd_bus *bus, sd_bus_message *message, void *userdata,
         if (!j)
                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
 
-        r = selinux_unit_access_check(j->unit, bus, message, "status", error);
+        r = selinux_unit_access_check(j->unit, message, "status", error);
         if (r < 0)
                 return r;
 
@@ -634,13 +731,7 @@ static int method_cancel_job(sd_bus *bus, sd_bus_message *message, void *userdat
         if (!j)
                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
 
-        r = selinux_unit_access_check(j->unit, bus, message, "stop", error);
-        if (r < 0)
-                return r;
-
-        job_finish_and_invalidate(j, JOB_CANCELED, true);
-
-        return sd_bus_reply_method_return(message, NULL);
+        return bus_job_method_cancel(bus, message, j, error);
 }
 
 static int method_clear_jobs(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
@@ -651,7 +742,7 @@ static int method_clear_jobs(sd_bus *bus, sd_bus_message *message, void *userdat
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "reboot", error);
+        r = selinux_access_check(message, "reboot", error);
         if (r < 0)
                 return r;
 
@@ -668,7 +759,7 @@ static int method_reset_failed(sd_bus *bus, sd_bus_message *message, void *userd
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "reload", error);
+        r = selinux_access_check(message, "reload", error);
         if (r < 0)
                 return r;
 
@@ -677,7 +768,7 @@ static int method_reset_failed(sd_bus *bus, sd_bus_message *message, void *userd
         return sd_bus_reply_method_return(message, NULL);
 }
 
-static int method_list_units(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
+static int list_units_filtered(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error, char **states) {
         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
         Manager *m = userdata;
         const char *k;
@@ -689,7 +780,9 @@ static int method_list_units(sd_bus *bus, sd_bus_message *message, void *userdat
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "status", error);
+        /* Anyone can call this method */
+
+        r = selinux_access_check(message, "status", error);
         if (r < 0)
                 return r;
 
@@ -710,6 +803,12 @@ static int method_list_units(sd_bus *bus, sd_bus_message *message, void *userdat
 
                 following = unit_following(u);
 
+                if (!strv_isempty(states) &&
+                    !strv_contains(states, unit_load_state_to_string(u->load_state)) &&
+                    !strv_contains(states, unit_active_state_to_string(unit_active_state(u))) &&
+                    !strv_contains(states, unit_sub_state_to_string(u)))
+                        continue;
+
                 unit_path = unit_dbus_path(u);
                 if (!unit_path)
                         return -ENOMEM;
@@ -743,6 +842,21 @@ static int method_list_units(sd_bus *bus, sd_bus_message *message, void *userdat
         return sd_bus_send(bus, reply, NULL);
 }
 
+static int method_list_units(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
+        return list_units_filtered(bus, message, userdata, error, NULL);
+}
+
+static int method_list_units_filtered(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
+        _cleanup_strv_free_ char **states = NULL;
+        int r;
+
+        r = sd_bus_message_read_strv(message, &states);
+        if (r < 0)
+                return r;
+
+        return list_units_filtered(bus, message, userdata, error, states);
+}
+
 static int method_list_jobs(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
         Manager *m = userdata;
@@ -754,7 +868,9 @@ static int method_list_jobs(sd_bus *bus, sd_bus_message *message, void *userdata
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "status", error);
+        /* Anyone can call this method */
+
+        r = selinux_access_check(message, "status", error);
         if (r < 0)
                 return r;
 
@@ -804,15 +920,29 @@ static int method_subscribe(sd_bus *bus, sd_bus_message *message, void *userdata
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "status", error);
-        if (r < 0)
-                return r;
+        /* Anyone can call this method */
 
-        r = bus_client_track(&m->subscribed, bus, sd_bus_message_get_sender(message));
+        r = selinux_access_check(message, "status", error);
         if (r < 0)
                 return r;
-        if (r == 0)
-                return sd_bus_error_setf(error, BUS_ERROR_ALREADY_SUBSCRIBED, "Client is already subscribed.");
+
+        if (bus == m->api_bus) {
+
+                /* Note that direct bus connection subscribe by
+                 * default, we only track peers on the API bus here */
+
+                if (!m->subscribed) {
+                        r = sd_bus_track_new(bus, &m->subscribed, NULL, NULL);
+                        if (r < 0)
+                                return r;
+                }
+
+                r = sd_bus_track_add_sender(m->subscribed, message);
+                if (r < 0)
+                        return r;
+                if (r == 0)
+                        return sd_bus_error_setf(error, BUS_ERROR_ALREADY_SUBSCRIBED, "Client is already subscribed.");
+        }
 
         return sd_bus_reply_method_return(message, NULL);
 }
@@ -825,15 +955,19 @@ static int method_unsubscribe(sd_bus *bus, sd_bus_message *message, void *userda
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "status", error);
-        if (r < 0)
-                return r;
+        /* Anyone can call this method */
 
-        r = bus_client_untrack(m->subscribed, bus, sd_bus_message_get_sender(message));
+        r = selinux_access_check(message, "status", error);
         if (r < 0)
                 return r;
-        if (r == 0)
-                return sd_bus_error_setf(error, BUS_ERROR_NOT_SUBSCRIBED, "Client is not subscribed.");
+
+        if (bus == m->api_bus) {
+                r = sd_bus_track_remove_sender(m->subscribed, message);
+                if (r < 0)
+                        return r;
+                if (r == 0)
+                        return sd_bus_error_setf(error, BUS_ERROR_NOT_SUBSCRIBED, "Client is not subscribed.");
+        }
 
         return sd_bus_reply_method_return(message, NULL);
 }
@@ -849,7 +983,9 @@ static int method_dump(sd_bus *bus, sd_bus_message *message, void *userdata, sd_
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "status", error);
+        /* Anyone can call this method */
+
+        r = selinux_access_check(message, "status", error);
         if (r < 0)
                 return r;
 
@@ -880,7 +1016,7 @@ static int method_create_snapshot(sd_bus *bus, sd_bus_message *message, void *us
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "start", error);
+        r = selinux_access_check(message, "start", error);
         if (r < 0)
                 return r;
 
@@ -912,7 +1048,7 @@ static int method_remove_snapshot(sd_bus *bus, sd_bus_message *message, void *us
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "stop", error);
+        r = selinux_access_check(message, "stop", error);
         if (r < 0)
                 return r;
 
@@ -938,7 +1074,13 @@ static int method_reload(sd_bus *bus, sd_bus_message *message, void *userdata, s
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "reload", error);
+        r = bus_verify_reload_daemon_async(m, message, error);
+        if (r < 0)
+                return r;
+        if (r == 0)
+                return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
+
+        r = selinux_access_check(message, "reload", error);
         if (r < 0)
                 return r;
 
@@ -966,7 +1108,13 @@ static int method_reexecute(sd_bus *bus, sd_bus_message *message, void *userdata
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "reload", error);
+        r = bus_verify_reload_daemon_async(m, message, error);
+        if (r < 0)
+                return r;
+        if (r == 0)
+                return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
+
+        r = selinux_access_check(message, "reload", error);
         if (r < 0)
                 return r;
 
@@ -985,7 +1133,7 @@ static int method_exit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "halt", error);
+        r = selinux_access_check(message, "halt", error);
         if (r < 0)
                 return r;
 
@@ -1005,7 +1153,7 @@ static int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, s
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "reboot", error);
+        r = selinux_access_check(message, "reboot", error);
         if (r < 0)
                 return r;
 
@@ -1026,7 +1174,7 @@ static int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata,
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "halt", error);
+        r = selinux_access_check(message, "halt", error);
         if (r < 0)
                 return r;
 
@@ -1046,7 +1194,7 @@ static int method_halt(sd_bus *bus, sd_bus_message *message, void *userdata, sd_
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "halt", error);
+        r = selinux_access_check(message, "halt", error);
         if (r < 0)
                 return r;
 
@@ -1066,7 +1214,7 @@ static int method_kexec(sd_bus *bus, sd_bus_message *message, void *userdata, sd
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "reboot", error);
+        r = selinux_access_check(message, "reboot", error);
         if (r < 0)
                 return r;
 
@@ -1088,7 +1236,7 @@ static int method_switch_root(sd_bus *bus, sd_bus_message *message, void *userda
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "reboot", error);
+        r = selinux_access_check(message, "reboot", error);
         if (r < 0)
                 return r;
 
@@ -1105,7 +1253,7 @@ static int method_switch_root(sd_bus *bus, sd_bus_message *message, void *userda
         /* Safety check */
         if (isempty(init)) {
                 if (! path_is_os_tree(root))
-                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified switch root path %s does not seem to be an OS tree. /etc/os-release is missing.", root);
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified switch root path %s does not seem to be an OS tree. os-release file is missing.", root);
         } else {
                 _cleanup_free_ char *p = NULL;
 
@@ -1152,7 +1300,7 @@ static int method_set_environment(sd_bus *bus, sd_bus_message *message, void *us
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "reload", error);
+        r = selinux_access_check(message, "reload", error);
         if (r < 0)
                 return r;
 
@@ -1178,7 +1326,7 @@ static int method_unset_environment(sd_bus *bus, sd_bus_message *message, void *
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "reload", error);
+        r = selinux_access_check(message, "reload", error);
         if (r < 0)
                 return r;
 
@@ -1205,7 +1353,7 @@ static int method_unset_and_set_environment(sd_bus *bus, sd_bus_message *message
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "reload", error);
+        r = selinux_access_check(message, "reload", error);
         if (r < 0)
                 return r;
 
@@ -1241,7 +1389,9 @@ static int method_list_unit_files(sd_bus *bus, sd_bus_message *message, void *us
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "status", error);
+        /* Anyone can call this method */
+
+        r = selinux_access_check(message, "status", error);
         if (r < 0)
                 return r;
 
@@ -1292,7 +1442,9 @@ static int method_get_unit_file_state(sd_bus *bus, sd_bus_message *message, void
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "status", error);
+        /* Anyone can call this method */
+
+        r = selinux_access_check(message, "status", error);
         if (r < 0)
                 return r;
 
@@ -1319,7 +1471,9 @@ static int method_get_default_target(sd_bus *bus, sd_bus_message *message, void
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "status", error);
+        /* Anyone can call this method */
+
+        r = selinux_access_check(message, "status", error);
         if (r < 0)
                 return r;
 
@@ -1332,7 +1486,7 @@ static int method_get_default_target(sd_bus *bus, sd_bus_message *message, void
         return sd_bus_reply_method_return(message, "s", default_target);
 }
 
-static int send_unit_files_changed(sd_bus *bus, const char *destination, void *userdata) {
+static int send_unit_files_changed(sd_bus *bus, void *userdata) {
         _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
         int r;
 
@@ -1342,7 +1496,7 @@ static int send_unit_files_changed(sd_bus *bus, const char *destination, void *u
         if (r < 0)
                 return r;
 
-        return sd_bus_send_to(bus, message, destination, NULL);
+        return sd_bus_send(bus, message, NULL);
 }
 
 static int reply_unit_file_changes_and_free(
@@ -1357,8 +1511,11 @@ static int reply_unit_file_changes_and_free(
         unsigned i;
         int r;
 
-        if (n_changes > 0)
-                bus_manager_foreach_client(m, send_unit_files_changed, NULL);
+        if (n_changes > 0) {
+                r = bus_foreach_bus(m, NULL, send_unit_files_changed, NULL);
+                if (r < 0)
+                        log_debug("Failed to send UnitFilesChanged signal: %s", strerror(-r));
+        }
 
         r = sd_bus_message_new_method_return(message, &reply);
         if (r < 0)
@@ -1398,8 +1555,8 @@ fail:
 static int method_enable_unit_files_generic(
                 sd_bus *bus,
                 sd_bus_message *message,
-                Manager *m, const
-                char *verb,
+                Manager *m,
+                const char *verb,
                 int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes),
                 bool carries_install_info,
                 sd_bus_error *error) {
@@ -1417,27 +1574,33 @@ static int method_enable_unit_files_generic(
         assert(message);
         assert(m);
 
+        r = bus_verify_manage_unit_files_async(m, message, error);
+        if (r < 0)
+                return r;
+        if (r == 0)
+                return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
+
         r = sd_bus_message_read_strv(message, &l);
         if (r < 0)
                 return r;
 
+        r = sd_bus_message_read(message, "bb", &runtime, &force);
+        if (r < 0)
+                return r;
+
 #ifdef HAVE_SELINUX
         STRV_FOREACH(i, l) {
                 Unit *u;
 
                 u = manager_get_unit(m, *i);
                 if (u) {
-                        r = selinux_unit_access_check(u, bus, message, verb, error);
+                        r = selinux_unit_access_check(u, message, verb, error);
                         if (r < 0)
                                 return r;
                 }
         }
 #endif
 
-        r = sd_bus_message_read(message, "bb", &runtime, &force);
-        if (r < 0)
-                return r;
-
         scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
 
         r = call(scope, runtime, NULL, l, force, &changes, &n_changes);
@@ -1459,14 +1622,80 @@ static int method_link_unit_files(sd_bus *bus, sd_bus_message *message, void *us
         return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_link, false, error);
 }
 
+static int unit_file_preset_without_mode(UnitFileScope scope, bool runtime, const char *root_dir, char **files, bool force, UnitFileChange **changes, unsigned *n_changes) {
+        return unit_file_preset(scope, runtime, root_dir, files, UNIT_FILE_PRESET_FULL, force, changes, n_changes);
+}
+
 static int method_preset_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
-        return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_preset, true, error);
+        return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_preset_without_mode, true, error);
 }
 
 static int method_mask_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
         return method_enable_unit_files_generic(bus, message, userdata, "disable", unit_file_mask, false, error);
 }
 
+static int method_preset_unit_files_with_mode(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
+
+        _cleanup_strv_free_ char **l = NULL;
+#ifdef HAVE_SELINUX
+        char **i;
+#endif
+        UnitFileChange *changes = NULL;
+        unsigned n_changes = 0;
+        Manager *m = userdata;
+        UnitFilePresetMode mm;
+        UnitFileScope scope;
+        int runtime, force, r;
+        const char *mode;
+
+        assert(bus);
+        assert(message);
+        assert(m);
+
+        r = bus_verify_manage_unit_files_async(m, message, error);
+        if (r < 0)
+                return r;
+        if (r == 0)
+                return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
+
+        r = sd_bus_message_read_strv(message, &l);
+        if (r < 0)
+                return r;
+
+        r = sd_bus_message_read(message, "sbb", &mode, &runtime, &force);
+        if (r < 0)
+                return r;
+
+        if (isempty(mode))
+                mm = UNIT_FILE_PRESET_FULL;
+        else {
+                mm = unit_file_preset_mode_from_string(mode);
+                if (mm < 0)
+                        return -EINVAL;
+        }
+
+#ifdef HAVE_SELINUX
+        STRV_FOREACH(i, l) {
+                Unit *u;
+
+                u = manager_get_unit(m, *i);
+                if (u) {
+                        r = selinux_unit_access_check(u, message, "enable", error);
+                        if (r < 0)
+                                return r;
+                }
+        }
+#endif
+
+        scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
+
+        r = unit_file_preset(scope, runtime, NULL, l, mm, force, &changes, &n_changes);
+        if (r < 0)
+                return r;
+
+        return reply_unit_file_changes_and_free(m, bus, message, r, changes, n_changes);
+}
+
 static int method_disable_unit_files_generic(
                 sd_bus *bus,
                 sd_bus_message *message,
@@ -1485,7 +1714,13 @@ static int method_disable_unit_files_generic(
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, verb, error);
+        r = bus_verify_manage_unit_files_async(m, message, error);
+        if (r < 0)
+                return r;
+        if (r == 0)
+                return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
+
+        r = selinux_access_check(message, verb, error);
         if (r < 0)
                 return r;
 
@@ -1526,7 +1761,13 @@ static int method_set_default_target(sd_bus *bus, sd_bus_message *message, void
         assert(message);
         assert(m);
 
-        r = selinux_access_check(bus, message, "enable", error);
+        r = bus_verify_manage_unit_files_async(m, message, error);
+        if (r < 0)
+                return r;
+        if (r == 0)
+                return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
+
+        r = selinux_access_check(message, "enable", error);
         if (r < 0)
                 return r;
 
@@ -1543,12 +1784,57 @@ static int method_set_default_target(sd_bus *bus, sd_bus_message *message, void
         return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
 }
 
+static int method_preset_all_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
+        UnitFileChange *changes = NULL;
+        unsigned n_changes = 0;
+        Manager *m = userdata;
+        UnitFilePresetMode mm;
+        UnitFileScope scope;
+        const char *mode;
+        int force, runtime, r;
+
+        assert(bus);
+        assert(message);
+        assert(m);
+
+        r = bus_verify_manage_unit_files_async(m, message, error);
+        if (r < 0)
+                return r;
+        if (r == 0)
+                return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
+
+        r = selinux_access_check(message, "enable", error);
+        if (r < 0)
+                return r;
+
+        r = sd_bus_message_read(message, "sbb", &mode, &runtime, &force);
+        if (r < 0)
+                return r;
+
+        if (isempty(mode))
+                mm = UNIT_FILE_PRESET_FULL;
+        else {
+                mm = unit_file_preset_mode_from_string(mode);
+                if (mm < 0)
+                        return -EINVAL;
+        }
+
+        scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
+
+        r = unit_file_preset_all(scope, runtime, NULL, mm, force, &changes, &n_changes);
+        if (r < 0)
+                return r;
+
+        return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
+}
+
 const sd_bus_vtable bus_manager_vtable[] = {
         SD_BUS_VTABLE_START(0),
 
         SD_BUS_PROPERTY("Version", "s", property_get_version, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("Features", "s", property_get_features, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("Virtualization", "s", property_get_virtualization, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("Architecture", "s", property_get_architecture, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("Tainted", "s", property_get_tainted, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         BUS_PROPERTY_DUAL_TIMESTAMP("FirmwareTimestamp", offsetof(Manager, firmware_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
         BUS_PROPERTY_DUAL_TIMESTAMP("LoaderTimestamp", offsetof(Manager, loader_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
@@ -1565,6 +1851,7 @@ const sd_bus_vtable bus_manager_vtable[] = {
         SD_BUS_WRITABLE_PROPERTY("LogLevel", "s", property_get_log_level, property_set_log_level, 0, 0),
         SD_BUS_WRITABLE_PROPERTY("LogTarget", "s", property_get_log_target, property_set_log_target, 0, 0),
         SD_BUS_PROPERTY("NNames", "u", property_get_n_names, 0, 0),
+        SD_BUS_PROPERTY("NFailedUnits", "u", property_get_n_failed_units, 0, 0),
         SD_BUS_PROPERTY("NJobs", "u", property_get_n_jobs, 0, 0),
         SD_BUS_PROPERTY("NInstalledJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_installed_jobs), 0),
         SD_BUS_PROPERTY("NFailedJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_failed_jobs), 0),
@@ -1578,35 +1865,37 @@ const sd_bus_vtable bus_manager_vtable[] = {
         SD_BUS_WRITABLE_PROPERTY("RuntimeWatchdogUSec", "t", bus_property_get_usec, property_set_runtime_watchdog, offsetof(Manager, runtime_watchdog), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_WRITABLE_PROPERTY("ShutdownWatchdogUSec", "t", bus_property_get_usec, bus_property_set_usec, offsetof(Manager, shutdown_watchdog), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("ControlGroup", "s", NULL, offsetof(Manager, cgroup_root), 0),
+        SD_BUS_PROPERTY("SystemState", "s", property_get_system_state, 0, 0),
 
         SD_BUS_METHOD("GetUnit", "s", "o", method_get_unit, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("GetUnitByPID", "u", "o", method_get_unit_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("LoadUnit", "s", "o", method_load_unit, SD_BUS_VTABLE_UNPRIVILEGED),
-        SD_BUS_METHOD("StartUnit", "ss", "o", method_start_unit, 0),
-        SD_BUS_METHOD("StartUnitReplace", "sss", "o", method_start_unit_replace, 0),
-        SD_BUS_METHOD("StopUnit", "ss", "o", method_stop_unit, 0),
-        SD_BUS_METHOD("ReloadUnit", "ss", "o", method_reload_unit, 0),
-        SD_BUS_METHOD("RestartUnit", "ss", "o", method_restart_unit, 0),
-        SD_BUS_METHOD("TryRestartUnit", "ss", "o", method_try_restart_unit, 0),
-        SD_BUS_METHOD("ReloadOrRestartUnit", "ss", "o", method_reload_or_restart_unit, 0),
-        SD_BUS_METHOD("ReloadOrTryRestartUnit", "ss", "o", method_reload_or_try_restart_unit, 0),
-        SD_BUS_METHOD("KillUnit", "ssi", NULL, method_kill_unit, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
-        SD_BUS_METHOD("ResetFailedUnit", "s", NULL, method_reset_failed_unit, 0),
-        SD_BUS_METHOD("SetUnitProperties", "sba(sv)", NULL, method_set_unit_properties, 0),
-        SD_BUS_METHOD("StartTransientUnit", "ssa(sv)a(sa(sv))", "o", method_start_transient_unit, 0),
+        SD_BUS_METHOD("StartUnit", "ss", "o", method_start_unit, SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("StartUnitReplace", "sss", "o", method_start_unit_replace, SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("StopUnit", "ss", "o", method_stop_unit, SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("ReloadUnit", "ss", "o", method_reload_unit, SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("RestartUnit", "ss", "o", method_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("TryRestartUnit", "ss", "o", method_try_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("ReloadOrRestartUnit", "ss", "o", method_reload_or_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("ReloadOrTryRestartUnit", "ss", "o", method_reload_or_try_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("KillUnit", "ssi", NULL, method_kill_unit, SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("ResetFailedUnit", "s", NULL, method_reset_failed_unit, SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("SetUnitProperties", "sba(sv)", NULL, method_set_unit_properties, SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("StartTransientUnit", "ssa(sv)a(sa(sv))", "o", method_start_transient_unit, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("GetJob", "u", "o", method_get_job, SD_BUS_VTABLE_UNPRIVILEGED),
-        SD_BUS_METHOD("CancelJob", "u", NULL, method_cancel_job, 0),
+        SD_BUS_METHOD("CancelJob", "u", NULL, method_cancel_job, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("ClearJobs", NULL, NULL, method_clear_jobs, 0),
         SD_BUS_METHOD("ResetFailed", NULL, NULL, method_reset_failed, 0),
         SD_BUS_METHOD("ListUnits", NULL, "a(ssssssouso)", method_list_units, SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("ListUnitsFiltered", "as", "a(ssssssouso)", method_list_units_filtered, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("ListJobs", NULL, "a(usssoo)", method_list_jobs, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("Subscribe", NULL, NULL, method_subscribe, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("Unsubscribe", NULL, NULL, method_unsubscribe, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("Dump", NULL, "s", method_dump, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("CreateSnapshot", "sb", "o", method_create_snapshot, 0),
         SD_BUS_METHOD("RemoveSnapshot", "s", NULL, method_remove_snapshot, 0),
-        SD_BUS_METHOD("Reload", NULL, NULL, method_reload, 0),
-        SD_BUS_METHOD("Reexecute", NULL, NULL, method_reexecute, 0),
+        SD_BUS_METHOD("Reload", NULL, NULL, method_reload, SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("Reexecute", NULL, NULL, method_reexecute, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("Exit", NULL, NULL, method_exit, 0),
         SD_BUS_METHOD("Reboot", NULL, NULL, method_reboot, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
         SD_BUS_METHOD("PowerOff", NULL, NULL, method_poweroff, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
@@ -1618,15 +1907,17 @@ const sd_bus_vtable bus_manager_vtable[] = {
         SD_BUS_METHOD("UnsetAndSetEnvironment", "asas", NULL, method_unset_and_set_environment, 0),
         SD_BUS_METHOD("ListUnitFiles", NULL, "a(ss)", method_list_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("GetUnitFileState", "s", "s", method_get_unit_file_state, SD_BUS_VTABLE_UNPRIVILEGED),
-        SD_BUS_METHOD("EnableUnitFiles", "asbb", "ba(sss)", method_enable_unit_files, 0),
-        SD_BUS_METHOD("DisableUnitFiles", "asb", "a(sss)", method_disable_unit_files, 0),
-        SD_BUS_METHOD("ReenableUnitFiles", "asbb", "ba(sss)", method_reenable_unit_files, 0),
-        SD_BUS_METHOD("LinkUnitFiles", "asbb", "a(sss)", method_link_unit_files, 0),
-        SD_BUS_METHOD("PresetUnitFiles", "asbb", "ba(sss)", method_preset_unit_files, 0),
-        SD_BUS_METHOD("MaskUnitFiles", "asbb", "a(sss)", method_mask_unit_files, 0),
-        SD_BUS_METHOD("UnmaskUnitFiles", "asb", "a(sss)", method_unmask_unit_files, 0),
-        SD_BUS_METHOD("SetDefaultTarget", "sb", "a(sss)", method_set_default_target, 0),
+        SD_BUS_METHOD("EnableUnitFiles", "asbb", "ba(sss)", method_enable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("DisableUnitFiles", "asb", "a(sss)", method_disable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("ReenableUnitFiles", "asbb", "ba(sss)", method_reenable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("LinkUnitFiles", "asbb", "a(sss)", method_link_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("PresetUnitFiles", "asbb", "ba(sss)", method_preset_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("PresetUnitFilesWithMode", "assbb", "ba(sss)", method_preset_unit_files_with_mode, SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("MaskUnitFiles", "asbb", "a(sss)", method_mask_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("UnmaskUnitFiles", "asb", "a(sss)", method_unmask_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("SetDefaultTarget", "sb", "a(sss)", method_set_default_target, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("GetDefaultTarget", NULL, "s", method_get_default_target, SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("PresetAllUnitFiles", "sbb", "a(sss)", method_preset_all_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
 
         SD_BUS_SIGNAL("UnitNew", "so", 0),
         SD_BUS_SIGNAL("UnitRemoved", "so", 0),
@@ -1639,41 +1930,7 @@ const sd_bus_vtable bus_manager_vtable[] = {
         SD_BUS_VTABLE_END
 };
 
-int bus_manager_foreach_client(Manager *m, int (*send_message)(sd_bus *bus, const char *destination, void *userdata), void *userdata) {
-        Iterator i;
-        sd_bus *b;
-        unsigned n;
-        int r, ret;
-
-        n = set_size(m->subscribed);
-        if (n <= 0)
-                return 0;
-        if (n == 1) {
-                BusTrackedClient *d;
-
-                assert_se(d = set_first(m->subscribed));
-                return send_message(d->bus, isempty(d->name) ? NULL : d->name, userdata);
-        }
-
-        ret = 0;
-
-        /* Send to everybody */
-        SET_FOREACH(b, m->private_buses, i) {
-                r = send_message(b, NULL, userdata);
-                if (r < 0)
-                        ret = r;
-        }
-
-        if (m->api_bus) {
-                r = send_message(m->api_bus, NULL, userdata);
-                if (r < 0)
-                        ret = r;
-        }
-
-        return ret;
-}
-
-static int send_finished(sd_bus *bus, const char *destination, void *userdata) {
+static int send_finished(sd_bus *bus, void *userdata) {
         _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
         usec_t *times = userdata;
         int r;
@@ -1689,7 +1946,7 @@ static int send_finished(sd_bus *bus, const char *destination, void *userdata) {
         if (r < 0)
                 return r;
 
-        return sd_bus_send_to(bus, message, destination, NULL);
+        return sd_bus_send(bus, message, NULL);
 }
 
 void bus_manager_send_finished(
@@ -1705,13 +1962,23 @@ void bus_manager_send_finished(
 
         assert(m);
 
-        r = bus_manager_foreach_client(m, send_finished,
-                                   (usec_t[6]) { firmware_usec, loader_usec, kernel_usec, initrd_usec, userspace_usec, total_usec });
+        r = bus_foreach_bus(
+                        m,
+                        NULL,
+                        send_finished,
+                        (usec_t[6]) {
+                                firmware_usec,
+                                loader_usec,
+                                kernel_usec,
+                                initrd_usec,
+                                userspace_usec,
+                                total_usec
+                        });
         if (r < 0)
                 log_debug("Failed to send finished signal: %s", strerror(-r));
 }
 
-static int send_reloading(sd_bus *bus, const char *destination, void *userdata) {
+static int send_reloading(sd_bus *bus, void *userdata) {
         _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
         int r;
 
@@ -1725,7 +1992,7 @@ static int send_reloading(sd_bus *bus, const char *destination, void *userdata)
         if (r < 0)
                 return r;
 
-        return sd_bus_send_to(bus, message, destination, NULL);
+        return sd_bus_send(bus, message, NULL);
 }
 
 void bus_manager_send_reloading(Manager *m, bool active) {
@@ -1733,7 +2000,7 @@ void bus_manager_send_reloading(Manager *m, bool active) {
 
         assert(m);
 
-        r = bus_manager_foreach_client(m, send_reloading, INT_TO_PTR(active));
+        r = bus_foreach_bus(m, NULL, send_reloading, INT_TO_PTR(active));
         if (r < 0)
                 log_debug("Failed to send reloading signal: %s", strerror(-r));
 
index 0ef99fa..e1903fa 100644 (file)
@@ -26,7 +26,5 @@
 
 extern const sd_bus_vtable bus_manager_vtable[];
 
-int bus_manager_foreach_client(Manager *m, int (*send_message)(sd_bus *bus, const char *destination, void *userdata), void *userdata);
-
 void bus_manager_send_finished(Manager *m, usec_t firmware_usec, usec_t loader_usec, usec_t kernel_usec, usec_t initrd_usec, usec_t userspace_usec, usec_t total_usec);
 void bus_manager_send_reloading(Manager *m, bool active);
index e64d3ea..53fe4ed 100644 (file)
@@ -117,6 +117,7 @@ const sd_bus_vtable bus_mount_vtable[] = {
         SD_BUS_PROPERTY("TimeoutUSec", "t", bus_property_get_usec, offsetof(Mount, timeout_usec), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("ControlPID", "u", bus_property_get_pid, offsetof(Mount, control_pid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         SD_BUS_PROPERTY("DirectoryMode", "u", bus_property_get_mode, offsetof(Mount, directory_mode), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("SloppyOptions", "b", bus_property_get_bool, offsetof(Mount, sloppy_options), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Mount, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         BUS_EXEC_COMMAND_VTABLE("ExecMount", offsetof(Mount, exec_command[MOUNT_EXEC_MOUNT]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
         BUS_EXEC_COMMAND_VTABLE("ExecUnmount", offsetof(Mount, exec_command[MOUNT_EXEC_UNMOUNT]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
@@ -124,6 +125,47 @@ const sd_bus_vtable bus_mount_vtable[] = {
         SD_BUS_VTABLE_END
 };
 
+static int bus_mount_set_transient_property(
+                Mount *m,
+                const char *name,
+                sd_bus_message *message,
+                UnitSetPropertiesMode mode,
+                sd_bus_error *error) {
+
+        const char *new_property;
+        char **property;
+        char *p;
+        int r;
+
+        assert(m);
+        assert(name);
+        assert(message);
+
+        if (streq(name, "What"))
+                property = &m->parameters_fragment.what;
+        else if (streq(name, "Options"))
+                property = &m->parameters_fragment.options;
+        else if (streq(name, "Type"))
+                property = &m->parameters_fragment.fstype;
+        else
+                return 0;
+
+        r = sd_bus_message_read(message, "s", &new_property);
+        if (r < 0)
+                return r;
+
+        if (mode != UNIT_CHECK) {
+                p = strdup(new_property);
+                if (!p)
+                        return -ENOMEM;
+
+                free(*property);
+                *property = p;
+        }
+
+        return 1;
+}
+
 int bus_mount_set_property(
                 Unit *u,
                 const char *name,
@@ -132,12 +174,33 @@ int bus_mount_set_property(
                 sd_bus_error *error) {
 
         Mount *m = MOUNT(u);
+        int r;
 
         assert(m);
         assert(name);
         assert(message);
 
-        return bus_cgroup_set_property(u, &m->cgroup_context, name, message, mode, error);
+        r = bus_cgroup_set_property(u, &m->cgroup_context, name, message, mode, error);
+        if (r != 0)
+                return r;
+
+        if (u->transient && u->load_state == UNIT_STUB) {
+                /* This is a transient unit, let's load a little more */
+
+                r = bus_mount_set_transient_property(m, name, message, mode, error);
+                if (r != 0)
+                        return r;
+
+                r = bus_exec_context_set_transient_property(u, &m->exec_context, name, message, mode, error);
+                if (r != 0)
+                        return r;
+
+                r = bus_kill_context_set_transient_property(u, &m->kill_context, name, message, mode, error);
+                if (r != 0)
+                        return r;
+        }
+
+        return 0;
 }
 
 int bus_mount_commit_properties(Unit *u) {
index b9e3be4..a762223 100644 (file)
@@ -25,6 +25,7 @@
 #include "dbus-cgroup.h"
 #include "dbus-kill.h"
 #include "dbus-scope.h"
+#include "dbus.h"
 #include "bus-util.h"
 #include "bus-internal.h"
 #include "bus-errors.h"
@@ -37,6 +38,12 @@ static int bus_scope_abandon(sd_bus *bus, sd_bus_message *message, void *userdat
         assert(message);
         assert(s);
 
+        r = bus_verify_manage_unit_async(UNIT(s)->manager, message, error);
+        if (r < 0)
+                return r;
+        if (r == 0)
+                return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
+
         r = scope_abandon(s);
         if (sd_bus_error_is_set(error))
                 return r;
@@ -138,7 +145,7 @@ static int bus_scope_set_transient_property(
                         if (r < 0)
                                 return r;
 
-                        unit_write_drop_in_format(UNIT(s), mode, name, "[Scope]\nTimeoutStopSec=%lluus\n", (unsigned long long) s->timeout_stop_usec);
+                        unit_write_drop_in_format(UNIT(s), mode, name, "[Scope]\nTimeoutStopSec="USEC_FMT"us\n", s->timeout_stop_usec);
                 } else {
                         r = sd_bus_message_skip(message, "t");
                         if (r < 0)
index 0451790..5a881e8 100644 (file)
@@ -34,7 +34,7 @@ static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_type, service_type, ServiceType
 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, service_result, ServiceResult);
 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_restart, service_restart, ServiceRestart);
 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_notify_access, notify_access, NotifyAccess);
-static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_start_limit_action, start_limit_action, StartLimitAction);
+static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_failure_action, failure_action, FailureAction);
 
 const sd_bus_vtable bus_service_vtable[] = {
         SD_BUS_VTABLE_START(0),
@@ -49,7 +49,9 @@ const sd_bus_vtable bus_service_vtable[] = {
         BUS_PROPERTY_DUAL_TIMESTAMP("WatchdogTimestamp", offsetof(Service, watchdog_timestamp), 0),
         SD_BUS_PROPERTY("StartLimitInterval", "t", bus_property_get_usec, offsetof(Service, start_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("StartLimitBurst", "u", bus_property_get_unsigned, offsetof(Service, start_limit.burst), SD_BUS_VTABLE_PROPERTY_CONST),
-        SD_BUS_PROPERTY("StartLimitAction", "s", property_get_start_limit_action, offsetof(Service, start_limit_action), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("StartLimitAction", "s", property_get_failure_action, offsetof(Service, start_limit_action), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("RebootArgument", "s", NULL, offsetof(Service, reboot_arg), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("FailureAction", "s", property_get_failure_action, offsetof(Service, failure_action), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("PermissionsStartOnly", "b", bus_property_get_bool, offsetof(Service, permissions_start_only), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("RootDirectoryStartOnly", "b", bus_property_get_bool, offsetof(Service, root_directory_start_only), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("RemainAfterExit", "b", bus_property_get_bool, offsetof(Service, remain_after_exit), SD_BUS_VTABLE_PROPERTY_CONST),
@@ -58,6 +60,7 @@ const sd_bus_vtable bus_service_vtable[] = {
         SD_BUS_PROPERTY("ControlPID", "u", bus_property_get_pid, offsetof(Service, control_pid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         SD_BUS_PROPERTY("BusName", "s", NULL, offsetof(Service, bus_name), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("StatusText", "s", NULL, offsetof(Service, status_text), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
+        SD_BUS_PROPERTY("StatusErrno", "i", NULL, offsetof(Service, status_errno), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Service, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         BUS_EXEC_STATUS_VTABLE("ExecMain", offsetof(Service, main_exec_status), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         BUS_EXEC_COMMAND_LIST_VTABLE("ExecStartPre", offsetof(Service, exec_command[SERVICE_EXEC_START_PRE]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
index 053e35c..2a5ef44 100644 (file)
@@ -33,7 +33,7 @@ int bus_snapshot_method_remove(sd_bus *bus, sd_bus_message *message, void *userd
         assert(message);
         assert(s);
 
-        r = selinux_unit_access_check(UNIT(s), bus, message, "stop", error);
+        r = selinux_unit_access_check(UNIT(s), message, "stop", error);
         if (r < 0)
                 return r;
 
index 67a5627..50b1674 100644 (file)
@@ -91,10 +91,17 @@ const sd_bus_vtable bus_socket_vtable[] = {
         SD_BUS_PROPERTY("Backlog", "u", bus_property_get_unsigned, offsetof(Socket, backlog), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("TimeoutUSec", "t", bus_property_get_usec, offsetof(Socket, timeout_usec), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("BindToDevice", "s", NULL, offsetof(Socket, bind_to_device), SD_BUS_VTABLE_PROPERTY_CONST),
-        SD_BUS_PROPERTY("DirectoryMode", "u", bus_property_get_mode, offsetof(Socket, directory_mode), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("SocketUser", "s", NULL, offsetof(Socket, user), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("SocketGroup", "s", NULL, offsetof(Socket, group), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("SocketMode", "u", bus_property_get_mode, offsetof(Socket, socket_mode), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("DirectoryMode", "u", bus_property_get_mode, offsetof(Socket, directory_mode), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("Accept", "b", bus_property_get_bool, offsetof(Socket, accept), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("KeepAlive", "b", bus_property_get_bool, offsetof(Socket, keep_alive), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("KeepAliveTimeUSec", "t", bus_property_get_usec, offsetof(Socket, keep_alive_time), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("KeepAliveIntervalUSec", "t", bus_property_get_usec, offsetof(Socket, keep_alive_interval), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("KeepAliveProbes", "u", bus_property_get_unsigned, offsetof(Socket, keep_alive_cnt), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("DeferAcceptUSec" , "t", bus_property_get_usec, offsetof(Socket, defer_accept), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("NoDelay", "b", bus_property_get_bool, offsetof(Socket, no_delay), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("Priority", "i", bus_property_get_int, offsetof(Socket, priority), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("ReceiveBuffer", "t", bus_property_get_size, offsetof(Socket, receive_buffer), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("SendBuffer", "t", bus_property_get_size, offsetof(Socket, send_buffer), SD_BUS_VTABLE_PROPERTY_CONST),
@@ -106,7 +113,9 @@ const sd_bus_vtable bus_socket_vtable[] = {
         SD_BUS_PROPERTY("Broadcast", "b", bus_property_get_bool, offsetof(Socket, broadcast), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("PassCredentials", "b", bus_property_get_bool, offsetof(Socket, pass_cred), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("PassSecurity", "b", bus_property_get_bool, offsetof(Socket, pass_sec), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("RemoveOnStop", "b", bus_property_get_bool, offsetof(Socket, remove_on_stop), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("Listen", "a(ss)", property_get_listen, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("Symlinks", "as", NULL, offsetof(Socket, symlinks), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("Mark", "i", bus_property_get_int, offsetof(Socket, mark), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("MaxConnections", "u", bus_property_get_unsigned, offsetof(Socket, max_connections), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("MessageQueueMaxMessages", "x", bus_property_get_long, offsetof(Socket, mq_maxmsg), SD_BUS_VTABLE_PROPERTY_CONST),
index 9d54b94..f1f8c54 100644 (file)
@@ -135,14 +135,51 @@ static int property_get_unit(
         return sd_bus_message_append(reply, "s", trigger ? trigger->id : "");
 }
 
+static int property_get_next_elapse_monotonic(
+                sd_bus *bus,
+                const char *path,
+                const char *interface,
+                const char *property,
+                sd_bus_message *reply,
+                void *userdata,
+                sd_bus_error *error) {
+
+        Timer *t = userdata;
+        usec_t x;
+
+        assert(bus);
+        assert(reply);
+        assert(t);
+
+        if (t->next_elapse_monotonic_or_boottime <= 0)
+                x = 0;
+        else if (t->wake_system) {
+                usec_t a, b;
+
+                a = now(CLOCK_MONOTONIC);
+                b = now(CLOCK_BOOTTIME);
+
+                if (t->next_elapse_monotonic_or_boottime + a > b)
+                        x = t->next_elapse_monotonic_or_boottime + a - b;
+                else
+                        x = 0;
+        } else
+                x = t->next_elapse_monotonic_or_boottime;
+
+        return sd_bus_message_append(reply, "t", x);
+}
+
 const sd_bus_vtable bus_timer_vtable[] = {
         SD_BUS_VTABLE_START(0),
         SD_BUS_PROPERTY("Unit", "s", property_get_unit, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("TimersMonotonic", "a(stt)", property_get_monotonic_timers, 0, SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
         SD_BUS_PROPERTY("TimersCalendar", "a(sst)", property_get_calendar_timers, 0, SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
         SD_BUS_PROPERTY("NextElapseUSecRealtime", "t", bus_property_get_usec, offsetof(Timer, next_elapse_realtime), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
-        SD_BUS_PROPERTY("NextElapseUSecMonotonic", "t", bus_property_get_usec, offsetof(Timer, next_elapse_monotonic), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
+        SD_BUS_PROPERTY("NextElapseUSecMonotonic", "t", property_get_next_elapse_monotonic, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
+        BUS_PROPERTY_DUAL_TIMESTAMP("LastTriggerUSec", offsetof(Timer, last_trigger), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Timer, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         SD_BUS_PROPERTY("AccuracyUSec", "t", bus_property_get_usec, offsetof(Timer, accuracy_usec), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("Persistent", "b", bus_property_get_bool, offsetof(Timer, persistent), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("WakeSystem", "b", bus_property_get_bool, offsetof(Timer, wake_system), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_VTABLE_END
 };
index 24d8a59..8fe83ae 100644 (file)
 #include "strv.h"
 #include "path-util.h"
 #include "fileio.h"
-#include "dbus-unit.h"
-#include "dbus-manager.h"
 #include "bus-errors.h"
-#include "dbus-client-track.h"
+#include "dbus.h"
+#include "dbus-manager.h"
+#include "dbus-unit.h"
 
 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_load_state, unit_load_state, UnitLoadState);
 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_job_mode, job_mode, JobMode);
@@ -421,6 +421,12 @@ int bus_unit_method_kill(sd_bus *bus, sd_bus_message *message, void *userdata, s
         assert(message);
         assert(u);
 
+        r = bus_verify_manage_unit_async_for_kill(u->manager, message, error);
+        if (r < 0)
+                return r;
+        if (r == 0)
+                return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
+
         r = sd_bus_message_read(message, "si", &swho, &signo);
         if (r < 0)
                 return r;
@@ -436,7 +442,7 @@ int bus_unit_method_kill(sd_bus *bus, sd_bus_message *message, void *userdata, s
         if (signo <= 0 || signo >= _NSIG)
                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Signal number out of range.");
 
-        r = selinux_unit_access_check(u, bus, message, "stop", error);
+        r = selinux_unit_access_check(u, message, "stop", error);
         if (r < 0)
                 return r;
 
@@ -455,7 +461,13 @@ int bus_unit_method_reset_failed(sd_bus *bus, sd_bus_message *message, void *use
         assert(message);
         assert(u);
 
-        r = selinux_unit_access_check(u, bus, message, "reload", error);
+        r = bus_verify_manage_unit_async(u->manager, message, error);
+        if (r < 0)
+                return r;
+        if (r == 0)
+                return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
+
+        r = selinux_unit_access_check(u, message, "reload", error);
         if (r < 0)
                 return r;
 
@@ -472,11 +484,17 @@ int bus_unit_method_set_properties(sd_bus *bus, sd_bus_message *message, void *u
         assert(message);
         assert(u);
 
+        r = bus_verify_manage_unit_async(u->manager, message, error);
+        if (r < 0)
+                return r;
+        if (r == 0)
+                return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
+
         r = sd_bus_message_read(message, "b", &runtime);
         if (r < 0)
                 return r;
 
-        r = selinux_unit_access_check(u, bus, message, "start", error);
+        r = selinux_unit_access_check(u, message, "start", error);
         if (r < 0)
                 return r;
 
@@ -589,7 +607,7 @@ const sd_bus_vtable bus_unit_cgroup_vtable[] = {
         SD_BUS_VTABLE_END
 };
 
-static int send_new_signal(sd_bus *bus, const char *destination, void *userdata) {
+static int send_new_signal(sd_bus *bus, void *userdata) {
         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
         _cleanup_free_ char *p = NULL;
         Unit *u = userdata;
@@ -615,10 +633,10 @@ static int send_new_signal(sd_bus *bus, const char *destination, void *userdata)
         if (r < 0)
                 return r;
 
-        return sd_bus_send_to(bus, m, destination, NULL);
+        return sd_bus_send(bus, m, NULL);
 }
 
-static int send_changed_signal(sd_bus *bus, const char *destination, void *userdata) {
+static int send_changed_signal(sd_bus *bus, void *userdata) {
         _cleanup_free_ char *p = NULL;
         Unit *u = userdata;
         int r;
@@ -638,21 +656,13 @@ static int send_changed_signal(sd_bus *bus, const char *destination, void *userd
                         bus, p,
                         UNIT_VTABLE(u)->bus_interface,
                         NULL);
-        if (r < 0) {
-                log_warning("Failed to send out specific PropertiesChanged signal for %s: %s", u->id, strerror(-r));
+        if (r < 0)
                 return r;
-        }
 
-        r = sd_bus_emit_properties_changed_strv(
+        return sd_bus_emit_properties_changed_strv(
                         bus, p,
                         "org.freedesktop.systemd1.Unit",
                         NULL);
-        if (r < 0) {
-                log_warning("Failed to send out generic PropertiesChanged signal for %s: %s", u->id, strerror(-r));
-                return r;
-        }
-
-        return 0;
 }
 
 void bus_unit_send_change_signal(Unit *u) {
@@ -667,14 +677,14 @@ void bus_unit_send_change_signal(Unit *u) {
         if (!u->id)
                 return;
 
-        r = bus_manager_foreach_client(u->manager, u->sent_dbus_new_signal ? send_changed_signal : send_new_signal, u);
+        r = bus_foreach_bus(u->manager, NULL, u->sent_dbus_new_signal ? send_changed_signal : send_new_signal, u);
         if (r < 0)
                 log_debug("Failed to send unit change signal for %s: %s", u->id, strerror(-r));
 
         u->sent_dbus_new_signal = true;
 }
 
-static int send_removed_signal(sd_bus *bus, const char *destination, void *userdata) {
+static int send_removed_signal(sd_bus *bus, void *userdata) {
         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
         _cleanup_free_ char *p = NULL;
         Unit *u = userdata;
@@ -700,7 +710,7 @@ static int send_removed_signal(sd_bus *bus, const char *destination, void *userd
         if (r < 0)
                 return r;
 
-        return sd_bus_send_to(bus, m, destination, NULL);
+        return sd_bus_send(bus, m, NULL);
 }
 
 void bus_unit_send_removed_signal(Unit *u) {
@@ -713,7 +723,7 @@ void bus_unit_send_removed_signal(Unit *u) {
         if (!u->id)
                 return;
 
-        r = bus_manager_foreach_client(u->manager, send_removed_signal, u);
+        r = bus_foreach_bus(u->manager, NULL, send_removed_signal, u);
         if (r < 0)
                 log_debug("Failed to send unit remove signal for %s: %s", u->id, strerror(-r));
 }
@@ -745,7 +755,7 @@ int bus_unit_queue_job(
         }
 
         r = selinux_unit_access_check(
-                        u, bus, message,
+                        u, message,
                         (type == JOB_START || type == JOB_RESTART || type == JOB_TRY_RESTART) ? "start" :
                         type == JOB_STOP ? "stop" : "reload", error);
         if (r < 0)
@@ -765,9 +775,17 @@ int bus_unit_queue_job(
         if (r < 0)
                 return r;
 
-        r = bus_client_track(&j->subscribed, bus, sd_bus_message_get_sender(message));
-        if (r < 0)
-                return r;
+        if (bus == u->manager->api_bus) {
+                if (!j->clients) {
+                        r = sd_bus_track_new(bus, &j->clients, NULL, NULL);
+                        if (r < 0)
+                                return r;
+                }
+
+                r = sd_bus_track_add_sender(j->clients, message);
+                if (r < 0)
+                        return r;
+        }
 
         path = job_dbus_path(j);
         if (!path)
index 1059415..834a14c 100644 (file)
@@ -41,7 +41,6 @@
 #include "bus-error.h"
 #include "bus-errors.h"
 #include "strxcpyx.h"
-#include "dbus-client-track.h"
 #include "bus-internal.h"
 #include "selinux-access.h"
 
@@ -162,8 +161,10 @@ static int signal_activation_request(sd_bus *bus, sd_bus_message *message, void
                 return 0;
         }
 
-        if (manager_unit_inactive_or_pending(m, SPECIAL_DBUS_SERVICE) ||
-            manager_unit_inactive_or_pending(m, SPECIAL_DBUS_SOCKET)) {
+        /* In Tizen 2.4 with kdbus enabled this check not only makes no sense, it will break activation because dbus.socket is always inactive. */
+        if (m->kdbus_fd < 0 &&
+            (manager_unit_inactive_or_pending(m, SPECIAL_DBUS_SERVICE) ||
+            manager_unit_inactive_or_pending(m, SPECIAL_DBUS_SOCKET))) {
                 r = sd_bus_error_setf(&error, BUS_ERROR_SHUTTING_DOWN, "Refusing activation, D-Bus is shutting down.");
                 goto failed;
         }
@@ -240,7 +241,7 @@ static int selinux_filter(sd_bus *bus, sd_bus_message *message, void *userdata,
 
         if (object_path_startswith("/org/freedesktop/systemd1", path)) {
 
-                r = selinux_access_check(bus, message, verb, error);
+                r = selinux_access_check(message, verb, error);
                 if (r < 0)
                         return r;
 
@@ -271,7 +272,7 @@ static int selinux_filter(sd_bus *bus, sd_bus_message *message, void *userdata,
         if (!u)
                 return 0;
 
-        r = selinux_unit_access_check(u, bus, message, verb, error);
+        r = selinux_unit_access_check(u, message, verb, error);
         if (r < 0)
                 return r;
 
@@ -311,7 +312,7 @@ static int find_unit(Manager *m, sd_bus *bus, const char *path, Unit **unit, sd_
                 sd_bus_message *message;
                 pid_t pid;
 
-                message = sd_bus_get_current(bus);
+                message = sd_bus_get_current_message(bus);
                 if (!message)
                         return 0;
 
@@ -537,58 +538,58 @@ static int bus_setup_api_vtables(Manager *m, sd_bus *bus) {
         assert(bus);
 
 #ifdef HAVE_SELINUX
-        r = sd_bus_add_filter(bus, selinux_filter, m);
+        r = sd_bus_add_filter(bus, NULL, selinux_filter, m);
         if (r < 0) {
                 log_error("Failed to add SELinux access filter: %s", strerror(-r));
                 return r;
         }
 #endif
 
-        r = sd_bus_add_object_vtable(bus, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", bus_manager_vtable, m);
+        r = sd_bus_add_object_vtable(bus, NULL, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", bus_manager_vtable, m);
         if (r < 0) {
                 log_error("Failed to register Manager vtable: %s", strerror(-r));
                 return r;
         }
 
-        r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/job", "org.freedesktop.systemd1.Job", bus_job_vtable, bus_job_find, m);
+        r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/job", "org.freedesktop.systemd1.Job", bus_job_vtable, bus_job_find, m);
         if (r < 0) {
                 log_error("Failed to register Job vtable: %s", strerror(-r));
                 return r;
         }
 
-        r = sd_bus_add_node_enumerator(bus, "/org/freedesktop/systemd1/job", bus_job_enumerate, m);
+        r = sd_bus_add_node_enumerator(bus, NULL, "/org/freedesktop/systemd1/job", bus_job_enumerate, m);
         if (r < 0) {
                 log_error("Failed to add job enumerator: %s", strerror(-r));
                 return r;
         }
 
-        r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", "org.freedesktop.systemd1.Unit", bus_unit_vtable, bus_unit_find, m);
+        r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", "org.freedesktop.systemd1.Unit", bus_unit_vtable, bus_unit_find, m);
         if (r < 0) {
                 log_error("Failed to register Unit vtable: %s", strerror(-r));
                 return r;
         }
 
-        r = sd_bus_add_node_enumerator(bus, "/org/freedesktop/systemd1/unit", bus_unit_enumerate, m);
+        r = sd_bus_add_node_enumerator(bus, NULL, "/org/freedesktop/systemd1/unit", bus_unit_enumerate, m);
         if (r < 0) {
                 log_error("Failed to add job enumerator: %s", strerror(-r));
                 return r;
         }
 
         for (t = 0; t < _UNIT_TYPE_MAX; t++) {
-                r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, unit_vtable[t]->bus_vtable, bus_unit_interface_find, m);
+                r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, unit_vtable[t]->bus_vtable, bus_unit_interface_find, m);
                 if (r < 0)  {
                         log_error("Failed to register type specific vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
                         return r;
                 }
 
                 if (unit_vtable[t]->cgroup_context_offset > 0) {
-                        r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_unit_cgroup_vtable, bus_unit_cgroup_find, m);
+                        r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_unit_cgroup_vtable, bus_unit_cgroup_find, m);
                         if (r < 0) {
                                 log_error("Failed to register control group unit vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
                                 return r;
                         }
 
-                        r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_cgroup_vtable, bus_cgroup_context_find, m);
+                        r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_cgroup_vtable, bus_cgroup_context_find, m);
                         if (r < 0) {
                                 log_error("Failed to register control group vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
                                 return r;
@@ -596,7 +597,7 @@ static int bus_setup_api_vtables(Manager *m, sd_bus *bus) {
                 }
 
                 if (unit_vtable[t]->exec_context_offset > 0) {
-                        r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_exec_vtable, bus_exec_context_find, m);
+                        r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_exec_vtable, bus_exec_context_find, m);
                         if (r < 0) {
                                 log_error("Failed to register execute vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
                                 return r;
@@ -604,7 +605,7 @@ static int bus_setup_api_vtables(Manager *m, sd_bus *bus) {
                 }
 
                 if (unit_vtable[t]->kill_context_offset > 0) {
-                        r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_kill_vtable, bus_kill_context_find, m);
+                        r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_kill_vtable, bus_kill_context_find, m);
                         if (r < 0) {
                                 log_error("Failed to register kill vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
                                 return r;
@@ -623,6 +624,7 @@ static int bus_setup_disconnected_match(Manager *m, sd_bus *bus) {
 
         r = sd_bus_add_match(
                         bus,
+                        NULL,
                         "sender='org.freedesktop.DBus.Local',"
                         "type='signal',"
                         "path='/org/freedesktop/DBus/Local',"
@@ -711,6 +713,7 @@ static int bus_on_connection(sd_event_source *s, int fd, uint32_t revents, void
 
                 r = sd_bus_add_match(
                                 bus,
+                                NULL,
                                 "type='signal',"
                                 "interface='org.freedesktop.systemd1.Agent',"
                                 "member='Released',"
@@ -781,6 +784,7 @@ static int bus_setup_api(Manager *m, sd_bus *bus) {
 
         r = sd_bus_add_match(
                         bus,
+                        NULL,
                         "type='signal',"
                         "sender='org.freedesktop.DBus',"
                         "path='/org/freedesktop/DBus',"
@@ -792,6 +796,7 @@ static int bus_setup_api(Manager *m, sd_bus *bus) {
 
         r = sd_bus_add_match(
                         bus,
+                        NULL,
                         "type='signal',"
                         "sender='org.freedesktop.DBus',"
                         "path='/org/freedesktop/DBus',"
@@ -875,6 +880,7 @@ static int bus_setup_system(Manager *m, sd_bus *bus) {
          * the system bus */
         r = sd_bus_add_match(
                         bus,
+                        NULL,
                         "type='signal',"
                         "interface='org.freedesktop.systemd1.Agent',"
                         "member='Released',"
@@ -919,7 +925,7 @@ static int bus_init_system(Manager *m) {
 
         r = bus_setup_system(m, bus);
         if (r < 0) {
-                log_error("Fauiled to set up system bus: %s", strerror(-r));
+                log_error("Failed to set up system bus: %s", strerror(-r));
                 return 0;
         }
 
@@ -954,7 +960,7 @@ static int bus_init_private(Manager *m) {
                         return 0;
 
                 strcpy(sa.un.sun_path, "/run/systemd/private");
-                salen = offsetof(union sockaddr_union, un.sun_path) + sizeof("/run/systemd/private") - 1;
+                salen = offsetof(union sockaddr_union, un.sun_path) + strlen("/run/systemd/private");
         } else {
                 size_t left = sizeof(sa.un.sun_path);
                 char *p = sa.un.sun_path;
@@ -1040,9 +1046,12 @@ static void destroy_bus(Manager *m, sd_bus **bus) {
                 return;
 
         /* Get rid of tracked clients on this bus */
-        bus_client_untrack_bus(m->subscribed, *bus);
+        if (m->subscribed && sd_bus_track_get_bus(m->subscribed) == *bus)
+                m->subscribed = sd_bus_track_unref(m->subscribed);
+
         HASHMAP_FOREACH(j, m->jobs, i)
-                bus_client_untrack_bus(j->subscribed, *bus);
+                if (j->clients && sd_bus_track_get_bus(j->clients) == *bus)
+                        j->clients = sd_bus_track_unref(j->clients);
 
         /* Get rid of queued message on this bus */
         if (m->queued_message_bus == *bus) {
@@ -1075,15 +1084,18 @@ void bus_done(Manager *m) {
                 destroy_bus(m, &b);
 
         set_free(m->private_buses);
-        set_free(m->subscribed);
+        m->private_buses = NULL;
+
+        m->subscribed = sd_bus_track_unref(m->subscribed);
+        strv_free(m->deserialized_subscribed);
+        m->deserialized_subscribed = NULL;
 
         if (m->private_listen_event_source)
                 m->private_listen_event_source = sd_event_source_unref(m->private_listen_event_source);
 
-        if (m->private_listen_fd >= 0) {
-                close_nointr_nofail(m->private_listen_fd);
-                m->private_listen_fd = -1;
-        }
+        m->private_listen_fd = safe_close(m->private_listen_fd);
+
+        bus_verify_polkit_async_registry_free(m->polkit_registry);
 }
 
 int bus_fdset_add_all(Manager *m, FDSet *fds) {
@@ -1126,16 +1138,101 @@ int bus_fdset_add_all(Manager *m, FDSet *fds) {
         return 0;
 }
 
-void bus_serialize(Manager *m, FILE *f) {
-        assert(m);
+int bus_foreach_bus(
+                Manager *m,
+                sd_bus_track *subscribed2,
+                int (*send_message)(sd_bus *bus, void *userdata),
+                void *userdata) {
+
+        Iterator i;
+        sd_bus *b;
+        int r, ret = 0;
+
+        /* Send to all direct busses, unconditionally */
+        SET_FOREACH(b, m->private_buses, i) {
+                r = send_message(b, userdata);
+                if (r < 0)
+                        ret = r;
+        }
+
+        /* Send to API bus, but only if somebody is subscribed */
+        if (sd_bus_track_count(m->subscribed) > 0 ||
+            sd_bus_track_count(subscribed2) > 0) {
+                r = send_message(m->api_bus, userdata);
+                if (r < 0)
+                        ret = r;
+        }
+
+        return ret;
+}
+
+void bus_track_serialize(sd_bus_track *t, FILE *f) {
+        const char *n;
+
         assert(f);
 
-        bus_client_track_serialize(m, f, m->subscribed);
+        for (n = sd_bus_track_first(t); n; n = sd_bus_track_next(t))
+                fprintf(f, "subscribed=%s\n", n);
 }
 
-int bus_deserialize_item(Manager *m, const char *line) {
-        assert(m);
+int bus_track_deserialize_item(char ***l, const char *line) {
+        const char *e;
+
+        assert(l);
         assert(line);
 
-        return bus_client_track_deserialize_item(m, &m->subscribed, line);
+        e = startswith(line, "subscribed=");
+        if (!e)
+                return 0;
+
+        return strv_extend(l, e);
+}
+
+int bus_track_coldplug(Manager *m, sd_bus_track **t, char ***l) {
+        int r = 0;
+
+        assert(m);
+        assert(t);
+        assert(l);
+
+        if (!strv_isempty(*l) && m->api_bus) {
+                char **i;
+
+                if (!*t) {
+                        r = sd_bus_track_new(m->api_bus, t, NULL, NULL);
+                        if (r < 0)
+                                return r;
+                }
+
+                r = 0;
+                STRV_FOREACH(i, *l) {
+                        int k;
+
+                        k = sd_bus_track_add_name(*t, *i);
+                        if (k < 0)
+                                r = k;
+                }
+        }
+
+        strv_free(*l);
+        *l = NULL;
+
+        return r;
+}
+
+int bus_verify_manage_unit_async(Manager *m, sd_bus_message *call, sd_bus_error *error) {
+        return bus_verify_polkit_async(call, CAP_SYS_ADMIN, "org.freedesktop.systemd1.manage-units", false, &m->polkit_registry, error);
+}
+
+/* Same as bus_verify_manage_unit_async(), but checks for CAP_KILL instead of CAP_SYS_ADMIN */
+int bus_verify_manage_unit_async_for_kill(Manager *m, sd_bus_message *call, sd_bus_error *error) {
+        return bus_verify_polkit_async(call, CAP_KILL, "org.freedesktop.systemd1.manage-units", false, &m->polkit_registry, error);
+}
+
+int bus_verify_manage_unit_files_async(Manager *m, sd_bus_message *call, sd_bus_error *error) {
+        return bus_verify_polkit_async(call, CAP_SYS_ADMIN, "org.freedesktop.systemd1.manage-unit-files", false, &m->polkit_registry, error);
+}
+
+int bus_verify_reload_daemon_async(Manager *m, sd_bus_message *call, sd_bus_error *error) {
+        return bus_verify_polkit_async(call, CAP_SYS_ADMIN, "org.freedesktop.systemd1.reload-daemon", false, &m->polkit_registry, error);
 }
index a3bef47..d04f532 100644 (file)
@@ -30,5 +30,13 @@ void bus_done(Manager *m);
 
 int bus_fdset_add_all(Manager *m, FDSet *fds);
 
-void bus_serialize(Manager *m, FILE *f);
-int bus_deserialize_item(Manager *m, const char *line);
+void bus_track_serialize(sd_bus_track *t, FILE *f);
+int bus_track_deserialize_item(char ***l, const char *line);
+int bus_track_coldplug(Manager *m, sd_bus_track **t, char ***l);
+
+int bus_foreach_bus(Manager *m, sd_bus_track *subscribed2, int (*send_message)(sd_bus *bus, void *userdata), void *userdata);
+
+int bus_verify_manage_unit_async(Manager *m, sd_bus_message *call, sd_bus_error *error);
+int bus_verify_manage_unit_async_for_kill(Manager *m, sd_bus_message *call, sd_bus_error *error);
+int bus_verify_manage_unit_files_async(Manager *m, sd_bus_message *call, sd_bus_error *error);
+int bus_verify_reload_daemon_async(Manager *m, sd_bus_message *call, sd_bus_error *error);
index d17b2df..0f28a16 100644 (file)
@@ -183,13 +183,87 @@ static int device_find_escape_name(Manager *m, const char *dn, Unit **_u) {
         return 0;
 }
 
+static int device_make_description(Unit *u, struct udev_device *dev, const char *path) {
+        const char *model;
+
+        assert(u);
+        assert(dev);
+        assert(path);
+
+        model = udev_device_get_property_value(dev, "ID_MODEL_FROM_DATABASE");
+        if (!model)
+                model = udev_device_get_property_value(dev, "ID_MODEL");
+
+        if (model) {
+                const char *label;
+
+                /* Try to concatenate the device model string with a label, if there is one */
+                label = udev_device_get_property_value(dev, "ID_FS_LABEL");
+                if (!label)
+                        label = udev_device_get_property_value(dev, "ID_PART_ENTRY_NAME");
+                if (!label)
+                        label = udev_device_get_property_value(dev, "ID_PART_ENTRY_NUMBER");
+
+                if (label) {
+                        _cleanup_free_ char *j;
+
+                        j = strjoin(model, " ", label, NULL);
+                        if (j)
+                                return unit_set_description(u, j);
+                }
+
+                return unit_set_description(u, model);
+        }
+
+        return unit_set_description(u, path);
+}
+
+static int device_add_udev_wants(Unit *u, struct udev_device *dev) {
+        const char *wants;
+        const char *word, *state;
+        size_t l;
+        int r;
+        const char *property;
+
+        assert(u);
+        assert(dev);
+
+        property = u->manager->running_as == SYSTEMD_USER ? "SYSTEMD_USER_WANTS" : "SYSTEMD_WANTS";
+        wants = udev_device_get_property_value(dev, property);
+        if (!wants)
+                return 0;
+
+        FOREACH_WORD_QUOTED(word, l, wants, state) {
+                _cleanup_free_ char *n = NULL;
+                char e[l+1];
+
+                memcpy(e, word, l);
+                e[l] = 0;
+
+                n = unit_name_mangle(e, MANGLE_NOGLOB);
+                if (!n)
+                        return -ENOMEM;
+
+                r = unit_add_dependency_by_name(u, UNIT_WANTS, n, NULL, true);
+                if (r < 0)
+                        return r;
+        }
+        if (!isempty(state))
+                log_warning_unit(u->id, "Property %s on %s has trailing garbage, ignoring.",
+                                 property, strna(udev_device_get_syspath(dev)));
+
+        return 0;
+}
+
 static int device_update_unit(Manager *m, struct udev_device *dev, const char *path, bool main) {
-        const char *sysfs, *model;
+        const char *sysfs;
         Unit *u = NULL;
-        int r;
         bool delete;
+        int r;
 
         assert(m);
+        assert(dev);
+        assert(path);
 
         sysfs = udev_device_get_syspath(dev);
         if (!sysfs)
@@ -242,43 +316,15 @@ static int device_update_unit(Manager *m, struct udev_device *dev, const char *p
                         goto fail;
         }
 
-        if ((model = udev_device_get_property_value(dev, "ID_MODEL_FROM_DATABASE")) ||
-            (model = udev_device_get_property_value(dev, "ID_MODEL")))
-                r = unit_set_description(u, model);
-        else
-                r = unit_set_description(u, path);
-        if (r < 0)
-                goto fail;
+        device_make_description(u, dev, path);
 
         if (main) {
-                const char *wants;
-
                 /* The additional systemd udev properties we only
                  * interpret for the main object */
 
-                wants = udev_device_get_property_value(dev, m->running_as == SYSTEMD_USER ? "SYSTEMD_USER_WANTS" : "SYSTEMD_WANTS");
-                if (wants) {
-                        char *state, *w;
-                        size_t l;
-
-                        FOREACH_WORD_QUOTED(w, l, wants, state) {
-                                _cleanup_free_ char *n = NULL;
-                                char e[l+1];
-
-                                memcpy(e, w, l);
-                                e[l] = 0;
-
-                                n = unit_name_mangle(e, MANGLE_NOGLOB);
-                                if (!n) {
-                                        r = -ENOMEM;
-                                        goto fail;
-                                }
-
-                                r = unit_add_dependency_by_name(u, UNIT_WANTS, n, NULL, true);
-                                if (r < 0)
-                                        goto fail;
-                        }
-                }
+                r = device_add_udev_wants(u, dev);
+                if (r < 0)
+                        goto fail;
         }
 
         /* Note that this won't dispatch the load queue, the caller
@@ -349,13 +395,13 @@ static int device_process_new_device(Manager *m, struct udev_device *dev) {
          * aliases */
         alias = udev_device_get_property_value(dev, "SYSTEMD_ALIAS");
         if (alias) {
-                char *state, *w;
+                const char *word, *state;
                 size_t l;
 
-                FOREACH_WORD_QUOTED(w, l, alias, state) {
+                FOREACH_WORD_QUOTED(word, l, alias, state) {
                         char e[l+1];
 
-                        memcpy(e, w, l);
+                        memcpy(e, word, l);
                         e[l] = 0;
 
                         if (path_is_absolute(e))
@@ -363,6 +409,8 @@ static int device_process_new_device(Manager *m, struct udev_device *dev) {
                         else
                                 log_warning("SYSTEMD_ALIAS for %s is not an absolute path, ignoring: %s", sysfs, e);
                 }
+                if (!isempty(state))
+                        log_warning("SYSTEMD_ALIAS for %s has trailing garbage, ignoring.", sysfs);
         }
 
         return 0;
index a328fc2..d002b1e 100644 (file)
@@ -69,7 +69,6 @@
 #include "ioprio.h"
 #include "securebits.h"
 #include "namespace.h"
-#include "tcpwrap.h"
 #include "exit-status.h"
 #include "missing.h"
 #include "utmp-wtmp.h"
 #include "async.h"
 #include "selinux-util.h"
 #include "errno-list.h"
+#include "af-list.h"
+#include "mkdir.h"
 #include "apparmor-util.h"
+#include "smack-util.h"
 
 #ifdef HAVE_SECCOMP
 #include "seccomp-util.h"
@@ -121,7 +123,7 @@ static int shift_fds(int fds[], unsigned n_fds) {
                         if ((nfd = fcntl(fds[i], F_DUPFD, i+3)) < 0)
                                 return -errno;
 
-                        close_nointr_nofail(fds[i]);
+                        safe_close(fds[i]);
                         fds[i] = nfd;
 
                         /* Hmm, the fd we wanted isn't free? Then
@@ -207,7 +209,7 @@ static int open_null_as(int flags, int nfd) {
 
         if (fd != nfd) {
                 r = dup2(fd, nfd) < 0 ? -errno : nfd;
-                close_nointr_nofail(fd);
+                safe_close(fd);
         } else
                 r = nfd;
 
@@ -232,12 +234,12 @@ static int connect_logger_as(const ExecContext *context, ExecOutput output, cons
 
         r = connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path));
         if (r < 0) {
-                close_nointr_nofail(fd);
+                safe_close(fd);
                 return -errno;
         }
 
         if (shutdown(fd, SHUT_RD) < 0) {
-                close_nointr_nofail(fd);
+                safe_close(fd);
                 return -errno;
         }
 
@@ -261,7 +263,7 @@ static int connect_logger_as(const ExecContext *context, ExecOutput output, cons
 
         if (fd != nfd) {
                 r = dup2(fd, nfd) < 0 ? -errno : nfd;
-                close_nointr_nofail(fd);
+                safe_close(fd);
         } else
                 r = nfd;
 
@@ -278,7 +280,7 @@ static int open_terminal_as(const char *path, mode_t mode, int nfd) {
 
         if (fd != nfd) {
                 r = dup2(fd, nfd) < 0 ? -errno : nfd;
-                close_nointr_nofail(fd);
+                safe_close(fd);
         } else
                 r = nfd;
 
@@ -332,13 +334,13 @@ static int setup_input(const ExecContext *context, int socket_fd, bool apply_tty
                                       i == EXEC_INPUT_TTY_FAIL,
                                       i == EXEC_INPUT_TTY_FORCE,
                                       false,
-                                      (usec_t) -1);
+                                      USEC_INFINITY);
                 if (fd < 0)
                         return fd;
 
                 if (fd != STDIN_FILENO) {
                         r = dup2(fd, STDIN_FILENO) < 0 ? -errno : STDIN_FILENO;
-                        close_nointr_nofail(fd);
+                        safe_close(fd);
                 } else
                         r = STDIN_FILENO;
 
@@ -502,7 +504,7 @@ static int setup_confirm_stdio(int *_saved_stdin,
         }
 
         if (fd >= 2)
-                close_nointr_nofail(fd);
+                safe_close(fd);
 
         *_saved_stdin = saved_stdin;
         *_saved_stdout = saved_stdout;
@@ -510,20 +512,15 @@ static int setup_confirm_stdio(int *_saved_stdin,
         return 0;
 
 fail:
-        if (saved_stdout >= 0)
-                close_nointr_nofail(saved_stdout);
-
-        if (saved_stdin >= 0)
-                close_nointr_nofail(saved_stdin);
-
-        if (fd >= 0)
-                close_nointr_nofail(fd);
+        safe_close(saved_stdout);
+        safe_close(saved_stdin);
+        safe_close(fd);
 
         return r;
 }
 
 _printf_(1, 2) static int write_confirm_message(const char *format, ...) {
-        int fd;
+        _cleanup_close_ int fd = -1;
         va_list ap;
 
         assert(format);
@@ -536,8 +533,6 @@ _printf_(1, 2) static int write_confirm_message(const char *format, ...) {
         vdprintf(fd, format, ap);
         va_end(ap);
 
-        close_nointr_nofail(fd);
-
         return 0;
 }
 
@@ -559,18 +554,15 @@ static int restore_confirm_stdio(int *saved_stdin,
                 if (dup2(*saved_stdout, STDOUT_FILENO) < 0)
                         r = -errno;
 
-        if (*saved_stdin >= 0)
-                close_nointr_nofail(*saved_stdin);
-
-        if (*saved_stdout >= 0)
-                close_nointr_nofail(*saved_stdout);
+        safe_close(*saved_stdin);
+        safe_close(*saved_stdout);
 
         return r;
 }
 
 static int ask_for_confirmation(char *response, char **argv) {
         int saved_stdout = -1, saved_stdin = -1, r;
-        char *line;
+        _cleanup_free_ char *line = NULL;
 
         r = setup_confirm_stdio(&saved_stdin, &saved_stdout);
         if (r < 0)
@@ -580,8 +572,7 @@ static int ask_for_confirmation(char *response, char **argv) {
         if (!line)
                 return -ENOMEM;
 
-        r = ask(response, "yns", "Execute %s? [Yes, No, Skip] ", line);
-        free(line);
+        r = ask_char(response, "yns", "Execute %s? [Yes, No, Skip] ", line);
 
         restore_confirm_stdio(&saved_stdin, &saved_stdout);
 
@@ -969,43 +960,163 @@ static int apply_seccomp(ExecContext *c) {
                         r = seccomp_arch_add(seccomp, PTR_TO_UINT32(id) - 1);
                         if (r == -EEXIST)
                                 continue;
-                        if (r < 0) {
-                                seccomp_release(seccomp);
-                                return r;
-                        }
+                        if (r < 0)
+                                goto finish;
                 }
-        } else {
 
+        } else {
                 r = seccomp_add_secondary_archs(seccomp);
-                if (r < 0) {
-                        seccomp_release(seccomp);
-                        return r;
-                }
+                if (r < 0)
+                        goto finish;
         }
 
         action = c->syscall_whitelist ? SCMP_ACT_ALLOW : negative_action;
         SET_FOREACH(id, c->syscall_filter, i) {
                 r = seccomp_rule_add(seccomp, action, PTR_TO_INT(id) - 1, 0);
-                if (r < 0) {
-                        seccomp_release(seccomp);
-                        return r;
-                }
+                if (r < 0)
+                        goto finish;
         }
 
+        r = seccomp_attr_set(seccomp, SCMP_FLTATR_CTL_NNP, 0);
+        if (r < 0)
+                goto finish;
+
         r = seccomp_load(seccomp);
+
+finish:
         seccomp_release(seccomp);
+        return r;
+}
+
+static int apply_address_families(ExecContext *c) {
+        scmp_filter_ctx *seccomp;
+        Iterator i;
+        int r;
+
+        assert(c);
+
+        seccomp = seccomp_init(SCMP_ACT_ALLOW);
+        if (!seccomp)
+                return -ENOMEM;
 
+        r = seccomp_add_secondary_archs(seccomp);
+        if (r < 0)
+                goto finish;
+
+        if (c->address_families_whitelist) {
+                int af, first = 0, last = 0;
+                void *afp;
+
+                /* If this is a whitelist, we first block the address
+                 * families that are out of range and then everything
+                 * that is not in the set. First, we find the lowest
+                 * and highest address family in the set. */
+
+                SET_FOREACH(afp, c->address_families, i) {
+                        af = PTR_TO_INT(afp);
+
+                        if (af <= 0 || af >= af_max())
+                                continue;
+
+                        if (first == 0 || af < first)
+                                first = af;
+
+                        if (last == 0 || af > last)
+                                last = af;
+                }
+
+                assert((first == 0) == (last == 0));
+
+                if (first == 0) {
+
+                        /* No entries in the valid range, block everything */
+                        r = seccomp_rule_add(
+                                        seccomp,
+                                        SCMP_ACT_ERRNO(EPROTONOSUPPORT),
+                                        SCMP_SYS(socket),
+                                        0);
+                        if (r < 0)
+                                goto finish;
+
+                } else {
+
+                        /* Block everything below the first entry */
+                        r = seccomp_rule_add(
+                                        seccomp,
+                                        SCMP_ACT_ERRNO(EPROTONOSUPPORT),
+                                        SCMP_SYS(socket),
+                                        1,
+                                        SCMP_A0(SCMP_CMP_LT, first));
+                        if (r < 0)
+                                goto finish;
+
+                        /* Block everything above the last entry */
+                        r = seccomp_rule_add(
+                                        seccomp,
+                                        SCMP_ACT_ERRNO(EPROTONOSUPPORT),
+                                        SCMP_SYS(socket),
+                                        1,
+                                        SCMP_A0(SCMP_CMP_GT, last));
+                        if (r < 0)
+                                goto finish;
+
+                        /* Block everything between the first and last
+                         * entry */
+                        for (af = 1; af < af_max(); af++) {
+
+                                if (set_contains(c->address_families, INT_TO_PTR(af)))
+                                        continue;
+
+                                r = seccomp_rule_add(
+                                                seccomp,
+                                                SCMP_ACT_ERRNO(EPROTONOSUPPORT),
+                                                SCMP_SYS(socket),
+                                                1,
+                                                SCMP_A0(SCMP_CMP_EQ, af));
+                                if (r < 0)
+                                        goto finish;
+                        }
+                }
+
+        } else {
+                void *af;
+
+                /* If this is a blacklist, then generate one rule for
+                 * each address family that are then combined in OR
+                 * checks. */
+
+                SET_FOREACH(af, c->address_families, i) {
+
+                        r = seccomp_rule_add(
+                                        seccomp,
+                                        SCMP_ACT_ERRNO(EPROTONOSUPPORT),
+                                        SCMP_SYS(socket),
+                                        1,
+                                        SCMP_A0(SCMP_CMP_EQ, PTR_TO_INT(af)));
+                        if (r < 0)
+                                goto finish;
+                }
+        }
+
+        r = seccomp_attr_set(seccomp, SCMP_FLTATR_CTL_NNP, 0);
+        if (r < 0)
+                goto finish;
+
+        r = seccomp_load(seccomp);
+
+finish:
+        seccomp_release(seccomp);
         return r;
 }
+
 #endif
 
 static void do_idle_pipe_dance(int idle_pipe[4]) {
         assert(idle_pipe);
 
-        if (idle_pipe[1] >= 0)
-                close_nointr_nofail(idle_pipe[1]);
-        if (idle_pipe[2] >= 0)
-                close_nointr_nofail(idle_pipe[2]);
+
+        safe_close(idle_pipe[1]);
+        safe_close(idle_pipe[2]);
 
         if (idle_pipe[0] >= 0) {
                 int r;
@@ -1020,12 +1131,11 @@ static void do_idle_pipe_dance(int idle_pipe[4]) {
                         fd_wait_for_event(idle_pipe[0], POLLHUP, IDLE_TIMEOUT2_USEC);
                 }
 
-                close_nointr_nofail(idle_pipe[0]);
+                safe_close(idle_pipe[0]);
 
         }
 
-        if (idle_pipe[3] >= 0)
-                close_nointr_nofail(idle_pipe[3]);
+        safe_close(idle_pipe[3]);
 }
 
 static int build_environment(
@@ -1063,7 +1173,7 @@ static int build_environment(
                         return -ENOMEM;
                 our_env[n_env++] = x;
 
-                if (asprintf(&x, "WATCHDOG_USEC=%llu", (unsigned long long) watchdog_usec) < 0)
+                if (asprintf(&x, "WATCHDOG_USEC="USEC_FMT, watchdog_usec) < 0)
                         return -ENOMEM;
                 our_env[n_env++] = x;
         }
@@ -1125,6 +1235,7 @@ int exec_spawn(ExecCommand *command,
                bool confirm_spawn,
                CGroupControllerMask cgroup_supported,
                const char *cgroup_path,
+               const char *runtime_prefix,
                const char *unit_id,
                usec_t watchdog_usec,
                int idle_pipe[4],
@@ -1250,23 +1361,6 @@ int exec_spawn(ExecCommand *command,
                                 goto fail_child;
                         }
 
-                if (context->tcpwrap_name) {
-                        if (socket_fd >= 0)
-                                if (!socket_tcpwrap(socket_fd, context->tcpwrap_name)) {
-                                        err = -EACCES;
-                                        r = EXIT_TCPWRAP;
-                                        goto fail_child;
-                                }
-
-                        for (i = 0; i < (int) n_fds; i++) {
-                                if (!socket_tcpwrap(fds[i], context->tcpwrap_name)) {
-                                        err = -EACCES;
-                                        r = EXIT_TCPWRAP;
-                                        goto fail_child;
-                                }
-                        }
-                }
-
                 exec_context_tty_reset(context);
 
                 if (confirm_spawn) {
@@ -1371,7 +1465,7 @@ int exec_spawn(ExecCommand *command,
                                 goto fail_child;
                         }
 
-                if (context->timer_slack_nsec != (nsec_t) -1)
+                if (context->timer_slack_nsec != NSEC_INFINITY)
                         if (prctl(PR_SET_TIMERSLACK, context->timer_slack_nsec) < 0) {
                                 err = -errno;
                                 r = EXIT_TIMERSLACK;
@@ -1422,6 +1516,27 @@ int exec_spawn(ExecCommand *command,
                 }
 #endif
 
+                if (!strv_isempty(context->runtime_directory) && runtime_prefix) {
+                        char **rt;
+
+                        STRV_FOREACH(rt, context->runtime_directory) {
+                                _cleanup_free_ char *p;
+
+                                p = strjoin(runtime_prefix, "/", *rt, NULL);
+                                if (!p) {
+                                        r = EXIT_RUNTIME_DIRECTORY;
+                                        err = -ENOMEM;
+                                        goto fail_child;
+                                }
+
+                                err = mkdir_safe(p, context->runtime_directory_mode, uid, gid);
+                                if (err < 0) {
+                                        r = EXIT_RUNTIME_DIRECTORY;
+                                        goto fail_child;
+                                }
+                        }
+                }
+
                 if (apply_permissions) {
                         err = enforce_groups(context, username, gid);
                         if (err < 0) {
@@ -1454,7 +1569,9 @@ int exec_spawn(ExecCommand *command,
                     !strv_isempty(context->inaccessible_dirs) ||
                     context->mount_flags != 0 ||
                     (context->private_tmp && runtime && (runtime->tmp_dir || runtime->var_tmp_dir)) ||
-                    context->private_devices) {
+                    context->private_devices ||
+                    context->protect_system != PROTECT_SYSTEM_NO ||
+                    context->protect_home != PROTECT_HOME_NO) {
 
                         char *tmp = NULL, *var = NULL;
 
@@ -1478,8 +1595,9 @@ int exec_spawn(ExecCommand *command,
                                         tmp,
                                         var,
                                         context->private_devices,
+                                        context->protect_home,
+                                        context->protect_system,
                                         context->mount_flags);
-
                         if (err < 0) {
                                 r = EXIT_NAMESPACE;
                                 goto fail_child;
@@ -1531,7 +1649,7 @@ int exec_spawn(ExecCommand *command,
 
                 if (apply_permissions) {
 
-                        for (i = 0; i < RLIMIT_NLIMITS; i++) {
+                        for (i = 0; i < _RLIMIT_MAX; i++) {
                                 if (!context->rlimit[i])
                                         continue;
 
@@ -1550,6 +1668,25 @@ int exec_spawn(ExecCommand *command,
                                 }
                         }
 
+#ifdef HAVE_SMACK
+                        if (context->smack_process_label) {
+                                err = smack_label_apply_pid(0, context->smack_process_label);
+                                if (err < 0) {
+                                        r = EXIT_SMACK_PROCESS_LABEL;
+                                        goto fail_child;
+                                }
+                        }
+#ifdef SMACK_DEFAULT_PROCESS_LABEL
+                        else {
+                                err = smack_label_apply_pid(0, SMACK_DEFAULT_PROCESS_LABEL);
+                                if (err < 0) {
+                                        r = EXIT_SMACK_PROCESS_LABEL;
+                                        goto fail_child;
+                                }
+                        }
+#endif
+#endif
+
                         if (context->user) {
                                 err = enforce_user(context, uid);
                                 if (err < 0) {
@@ -1584,7 +1721,18 @@ int exec_spawn(ExecCommand *command,
                                 }
 
 #ifdef HAVE_SECCOMP
-                        if (context->syscall_filter || context->syscall_archs) {
+                        if (context->address_families_whitelist ||
+                            !set_isempty(context->address_families)) {
+                                err = apply_address_families(context);
+                                if (err < 0) {
+                                        r = EXIT_ADDRESS_FAMILIES;
+                                        goto fail_child;
+                                }
+                        }
+
+                        if (context->syscall_whitelist ||
+                            !set_isempty(context->syscall_filter) ||
+                            !set_isempty(context->syscall_archs)) {
                                 err = apply_seccomp(context);
                                 if (err < 0) {
                                         r = EXIT_SECCOMP;
@@ -1705,8 +1853,9 @@ void exec_context_init(ExecContext *c) {
         c->syslog_priority = LOG_DAEMON|LOG_INFO;
         c->syslog_level_prefix = true;
         c->ignore_sigpipe = true;
-        c->timer_slack_nsec = (nsec_t) -1;
+        c->timer_slack_nsec = NSEC_INFINITY;
         c->personality = 0xffffffffUL;
+        c->runtime_directory_mode = 0755;
 }
 
 void exec_context_done(ExecContext *c) {
@@ -1733,9 +1882,6 @@ void exec_context_done(ExecContext *c) {
         free(c->tty_path);
         c->tty_path = NULL;
 
-        free(c->tcpwrap_name);
-        c->tcpwrap_name = NULL;
-
         free(c->syslog_identifier);
         c->syslog_identifier = NULL;
 
@@ -1777,13 +1923,41 @@ void exec_context_done(ExecContext *c) {
         free(c->apparmor_profile);
         c->apparmor_profile = NULL;
 
-#ifdef HAVE_SECCOMP
         set_free(c->syscall_filter);
         c->syscall_filter = NULL;
 
         set_free(c->syscall_archs);
         c->syscall_archs = NULL;
-#endif
+
+        set_free(c->address_families);
+        c->address_families = NULL;
+
+        strv_free(c->runtime_directory);
+        c->runtime_directory = NULL;
+}
+
+int exec_context_destroy_runtime_directory(ExecContext *c, const char *runtime_prefix) {
+        char **i;
+
+        assert(c);
+
+        if (!runtime_prefix)
+                return 0;
+
+        STRV_FOREACH(i, c->runtime_directory) {
+                _cleanup_free_ char *p;
+
+                p = strjoin(runtime_prefix, "/", *i, NULL);
+                if (!p)
+                        return -ENOMEM;
+
+                /* We execute this synchronously, since we need to be
+                 * sure this is gone when we start the service
+                 * next. */
+                rm_rf_dangerous(p, false, true, false);
+        }
+
+        return 0;
 }
 
 void exec_command_done(ExecCommand *c) {
@@ -1869,7 +2043,7 @@ int exec_context_load_environment(const ExecContext *c, char ***l) {
                         return -EINVAL;
                 }
                 for (n = 0; n < count; n++) {
-                        k = load_env_file(pglob.gl_pathv[n], NULL, &p);
+                        k = load_env_file(NULL, pglob.gl_pathv[n], NULL, &p);
                         if (k < 0) {
                                 if (ignore)
                                         continue;
@@ -1903,8 +2077,8 @@ int exec_context_load_environment(const ExecContext *c, char ***l) {
 }
 
 static bool tty_may_match_dev_console(const char *tty) {
-        char *active = NULL, *console;
-        bool b;
+        _cleanup_free_ char *active = NULL;
+       char *console;
 
         if (startswith(tty, "/dev/"))
                 tty += 5;
@@ -1919,10 +2093,7 @@ static bool tty_may_match_dev_console(const char *tty) {
                 return true;
 
         /* "tty0" means the active VC, so it may be the same sometimes */
-        b = streq(console, tty) || (streq(console, "tty0") && tty_is_vc(tty));
-        free(active);
-
-        return b;
+        return streq(console, tty) || (streq(console, "tty0") && tty_is_vc(tty));
 }
 
 bool exec_context_may_touch_console(ExecContext *ec) {
@@ -1959,6 +2130,8 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
                 "%sPrivateTmp: %s\n"
                 "%sPrivateNetwork: %s\n"
                 "%sPrivateDevices: %s\n"
+                "%sProtectHome: %s\n"
+                "%sProtectSystem: %s\n"
                 "%sIgnoreSIGPIPE: %s\n",
                 prefix, c->umask,
                 prefix, c->working_directory ? c->working_directory : "/",
@@ -1967,6 +2140,8 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
                 prefix, yes_no(c->private_tmp),
                 prefix, yes_no(c->private_network),
                 prefix, yes_no(c->private_devices),
+                prefix, protect_home_to_string(c->protect_home),
+                prefix, protect_system_to_string(c->protect_system),
                 prefix, yes_no(c->ignore_sigpipe));
 
         STRV_FOREACH(e, c->environment)
@@ -1975,11 +2150,6 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
         STRV_FOREACH(e, c->environment_files)
                 fprintf(f, "%sEnvironmentFile: %s\n", prefix, *e);
 
-        if (c->tcpwrap_name)
-                fprintf(f,
-                        "%sTCPWrapName: %s\n",
-                        prefix, c->tcpwrap_name);
-
         if (c->nice_set)
                 fprintf(f,
                         "%sNice: %i\n",
@@ -1992,7 +2162,8 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
 
         for (i = 0; i < RLIM_NLIMITS; i++)
                 if (c->rlimit[i])
-                        fprintf(f, "%s%s: %llu\n", prefix, rlimit_to_string(i), (unsigned long long) c->rlimit[i]->rlim_max);
+                        fprintf(f, "%s%s: "RLIM_FMT"\n",
+                                prefix, rlimit_to_string(i), c->rlimit[i]->rlim_max);
 
         if (c->ioprio_set) {
                 _cleanup_free_ char *class_str = NULL;
@@ -2026,7 +2197,7 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
                 fputs("\n", f);
         }
 
-        if (c->timer_slack_nsec != (nsec_t) -1)
+        if (c->timer_slack_nsec != NSEC_INFINITY)
                 fprintf(f, "%sTimerSlackNSec: "NSEC_FMT "\n", prefix, c->timer_slack_nsec);
 
         fprintf(f,
@@ -2312,10 +2483,10 @@ char *exec_command_line(char **argv) {
 }
 
 void exec_command_dump(ExecCommand *c, FILE *f, const char *prefix) {
-        char *p2;
+        _cleanup_free_ char *p2 = NULL;
         const char *prefix2;
 
-        char *cmd;
+        _cleanup_free_ char *cmd = NULL;
 
         assert(c);
         assert(f);
@@ -2331,11 +2502,7 @@ void exec_command_dump(ExecCommand *c, FILE *f, const char *prefix) {
                 "%sCommand Line: %s\n",
                 prefix, cmd ? cmd : strerror(ENOMEM));
 
-        free(cmd);
-
         exec_status_dump(&c->exec_status, f, prefix2);
-
-        free(p2);
 }
 
 void exec_command_dump_list(ExecCommand *c, FILE *f, const char *prefix) {
@@ -2456,7 +2623,7 @@ ExecRuntime *exec_runtime_unref(ExecRuntime *r) {
         if (r->n_ref <= 0) {
                 free(r->tmp_dir);
                 free(r->var_tmp_dir);
-                close_pipe(r->netns_storage_socket);
+                safe_close_pair(r->netns_storage_socket);
                 free(r);
         }
 
@@ -2545,9 +2712,7 @@ int exec_runtime_deserialize_item(ExecRuntime **rt, Unit *u, const char *key, co
                 if (safe_atoi(value, &fd) < 0 || !fdset_contains(fds, fd))
                         log_debug_unit(u->id, "Failed to parse netns socket value %s", value);
                 else {
-                        if ((*rt)->netns_storage_socket[0] >= 0)
-                                close_nointr_nofail((*rt)->netns_storage_socket[0]);
-
+                        safe_close((*rt)->netns_storage_socket[0]);
                         (*rt)->netns_storage_socket[0] = fdset_remove(fds, fd);
                 }
         } else if (streq(key, "netns-socket-1")) {
@@ -2560,9 +2725,7 @@ int exec_runtime_deserialize_item(ExecRuntime **rt, Unit *u, const char *key, co
                 if (safe_atoi(value, &fd) < 0 || !fdset_contains(fds, fd))
                         log_debug_unit(u->id, "Failed to parse netns socket value %s", value);
                 else {
-                        if ((*rt)->netns_storage_socket[1] >= 0)
-                                close_nointr_nofail((*rt)->netns_storage_socket[1]);
-
+                        safe_close((*rt)->netns_storage_socket[1]);
                         (*rt)->netns_storage_socket[1] = fdset_remove(fds, fd);
                 }
         } else
@@ -2579,6 +2742,8 @@ static void *remove_tmpdir_thread(void *p) {
 }
 
 void exec_runtime_destroy(ExecRuntime *rt) {
+        int r;
+
         if (!rt)
                 return;
 
@@ -2588,17 +2753,29 @@ void exec_runtime_destroy(ExecRuntime *rt) {
 
         if (rt->tmp_dir) {
                 log_debug("Spawning thread to nuke %s", rt->tmp_dir);
-                asynchronous_job(remove_tmpdir_thread, rt->tmp_dir);
+
+                r = asynchronous_job(remove_tmpdir_thread, rt->tmp_dir);
+                if (r < 0) {
+                        log_warning("Failed to nuke %s: %s", rt->tmp_dir, strerror(-r));
+                        free(rt->tmp_dir);
+                }
+
                 rt->tmp_dir = NULL;
         }
 
         if (rt->var_tmp_dir) {
                 log_debug("Spawning thread to nuke %s", rt->var_tmp_dir);
-                asynchronous_job(remove_tmpdir_thread, rt->var_tmp_dir);
+
+                r = asynchronous_job(remove_tmpdir_thread, rt->var_tmp_dir);
+                if (r < 0) {
+                        log_warning("Failed to nuke %s: %s", rt->var_tmp_dir, strerror(-r));
+                        free(rt->var_tmp_dir);
+                }
+
                 rt->var_tmp_dir = NULL;
         }
 
-        close_pipe(rt->netns_storage_socket);
+        safe_close_pair(rt->netns_storage_socket);
 }
 
 static const char* const exec_input_table[_EXEC_INPUT_MAX] = {
index 2bfe227..34dcfea 100644 (file)
@@ -33,15 +33,13 @@ typedef struct ExecRuntime ExecRuntime;
 #include <stdbool.h>
 #include <stdio.h>
 #include <sched.h>
-#ifdef HAVE_SECCOMP
-#include <seccomp.h>
-
-#include "set.h"
-#endif
 
 #include "list.h"
 #include "util.h"
+#include "set.h"
 #include "fdset.h"
+#include "missing.h"
+#include "namespace.h"
 
 typedef enum ExecInput {
         EXEC_INPUT_NULL,
@@ -97,7 +95,7 @@ struct ExecContext {
         char **environment;
         char **environment_files;
 
-        struct rlimit *rlimit[RLIMIT_NLIMITS];
+        struct rlimit *rlimit[_RLIMIT_MAX];
         char *working_directory, *root_directory;
 
         mode_t umask;
@@ -116,8 +114,6 @@ struct ExecContext {
 
         nsec_t timer_slack_nsec;
 
-        char *tcpwrap_name;
-
         char *tty_path;
 
         bool tty_reset;
@@ -144,6 +140,9 @@ struct ExecContext {
         bool apparmor_profile_ignore;
         char *apparmor_profile;
 
+        bool smack_process_label_ignore;
+        char *smack_process_label;
+
         char **read_write_dirs, **read_only_dirs, **inaccessible_dirs;
         unsigned long mount_flags;
 
@@ -161,6 +160,8 @@ struct ExecContext {
         bool private_tmp;
         bool private_network;
         bool private_devices;
+        ProtectSystem protect_system;
+        ProtectHome protect_home;
 
         bool no_new_privileges;
 
@@ -178,10 +179,17 @@ struct ExecContext {
         int syscall_errno;
         bool syscall_whitelist:1;
 
+        Set *address_families;
+        bool address_families_whitelist:1;
+
+        char **runtime_directory;
+        mode_t runtime_directory_mode;
+
         bool oom_score_adjust_set:1;
         bool nice_set:1;
         bool ioprio_set:1;
         bool cpu_sched_set:1;
+        bool no_new_privileges_set:1;
 };
 
 #include "cgroup.h"
@@ -197,6 +205,7 @@ int exec_spawn(ExecCommand *command,
                bool confirm_spawn,
                CGroupControllerMask cgroup_mask,
                const char *cgroup_path,
+               const char *runtime_prefix,
                const char *unit_id,
                usec_t watchdog_usec,
                int pipe_fd[2],
@@ -220,6 +229,8 @@ void exec_context_init(ExecContext *c);
 void exec_context_done(ExecContext *c);
 void exec_context_dump(ExecContext *c, FILE* f, const char *prefix);
 
+int exec_context_destroy_runtime_directory(ExecContext *c, const char *runtime_root);
+
 int exec_context_load_environment(const ExecContext *c, char ***l);
 
 bool exec_context_may_touch_console(ExecContext *c);
index 7f8ec23..7bffd8d 100644 (file)
 int ima_setup(void) {
 
 #ifdef HAVE_IMA
-       struct stat st;
-       ssize_t policy_size = 0, written = 0;
-       char *policy;
-       int policyfd = -1, imafd = -1;
-       int result = 0;
-
-       if (stat(IMA_POLICY_PATH, &st) < 0)
-               return 0;
-
-       policy_size = st.st_size;
-       if (stat(IMA_SECFS_DIR, &st) < 0) {
-               log_debug("IMA support is disabled in the kernel, ignoring.");
-               return 0;
-       }
-
-       if (stat(IMA_SECFS_POLICY, &st) < 0) {
-               log_error("Another IMA custom policy has already been loaded, "
-                         "ignoring.");
-               return 0;
-       }
-
-       policyfd = open(IMA_POLICY_PATH, O_RDONLY|O_CLOEXEC);
-       if (policyfd < 0) {
-               log_error("Failed to open the IMA custom policy file %s (%m), "
-                         "ignoring.", IMA_POLICY_PATH);
-               return 0;
-       }
-
-       imafd = open(IMA_SECFS_POLICY, O_WRONLY|O_CLOEXEC);
-       if (imafd < 0) {
-               log_error("Failed to open the IMA kernel interface %s (%m), "
-                         "ignoring.", IMA_SECFS_POLICY);
-               goto out;
-       }
-
-       policy = mmap(NULL, policy_size, PROT_READ, MAP_PRIVATE, policyfd, 0);
-       if (policy == MAP_FAILED) {
-               log_error("mmap() failed (%m), freezing");
-               result = -errno;
-               goto out;
-       }
-
-       written = loop_write(imafd, policy, (size_t)policy_size, false);
-       if (written != policy_size) {
-               log_error("Failed to load the IMA custom policy file %s (%m), "
-                         "ignoring.", IMA_POLICY_PATH);
-               goto out_mmap;
-       }
-
-       log_info("Successfully loaded the IMA custom policy %s.",
-                IMA_POLICY_PATH);
+        struct stat st;
+        ssize_t policy_size = 0, written = 0;
+        char *policy;
+        _cleanup_close_ int policyfd = -1, imafd = -1;
+        int result = 0;
+
+        if (stat(IMA_POLICY_PATH, &st) < 0)
+                return 0;
+
+        policy_size = st.st_size;
+        if (stat(IMA_SECFS_DIR, &st) < 0) {
+                log_debug("IMA support is disabled in the kernel, ignoring.");
+                return 0;
+        }
+
+        if (stat(IMA_SECFS_POLICY, &st) < 0) {
+                log_error("Another IMA custom policy has already been loaded, "
+                          "ignoring.");
+                return 0;
+        }
+
+        policyfd = open(IMA_POLICY_PATH, O_RDONLY|O_CLOEXEC);
+        if (policyfd < 0) {
+                log_error("Failed to open the IMA custom policy file %s (%m), "
+                          "ignoring.", IMA_POLICY_PATH);
+                return 0;
+        }
+
+        imafd = open(IMA_SECFS_POLICY, O_WRONLY|O_CLOEXEC);
+        if (imafd < 0) {
+                log_error("Failed to open the IMA kernel interface %s (%m), "
+                          "ignoring.", IMA_SECFS_POLICY);
+                goto out;
+        }
+
+        policy = mmap(NULL, policy_size, PROT_READ, MAP_PRIVATE, policyfd, 0);
+        if (policy == MAP_FAILED) {
+                log_error("mmap() failed (%m), freezing");
+                result = -errno;
+                goto out;
+        }
+
+        written = loop_write(imafd, policy, (size_t)policy_size, false);
+        if (written != policy_size) {
+                log_error("Failed to load the IMA custom policy file %s (%m), "
+                          "ignoring.", IMA_POLICY_PATH);
+                goto out_mmap;
+        }
+
+        log_info("Successfully loaded the IMA custom policy %s.",
+                 IMA_POLICY_PATH);
 out_mmap:
-       munmap(policy, policy_size);
+        munmap(policy, policy_size);
 out:
-       if (policyfd >= 0)
-                close_nointr_nofail(policyfd);
-       if (imafd >= 0)
-                close_nointr_nofail(imafd);
-       if (result)
-                return result;
+        if (result)
+                 return result;
 #endif /* HAVE_IMA */
 
-       return 0;
+        return 0;
 }
index 0cd4397..5e4987f 100644 (file)
@@ -37,7 +37,7 @@
 #include "special.h"
 #include "async.h"
 #include "virt.h"
-#include "dbus-client-track.h"
+#include "dbus.h"
 
 Job* job_new_raw(Unit *unit) {
         Job *j;
@@ -90,7 +90,8 @@ void job_free(Job *j) {
 
         sd_event_source_unref(j->timer_event_source);
 
-        bus_client_track_free(j->subscribed);
+        sd_bus_track_unref(j->clients);
+        strv_free(j->deserialized_clients);
 
         free(j);
 }
@@ -872,7 +873,12 @@ int job_start_timer(Job *j) {
         if (j->unit->job_timeout <= 0)
                 return 0;
 
-        r = sd_event_add_monotonic(j->manager->event, &j->timer_event_source, j->begin_usec + j->unit->job_timeout, 0, job_dispatch_timer, j);
+        r = sd_event_add_time(
+                        j->manager->event,
+                        &j->timer_event_source,
+                        CLOCK_MONOTONIC,
+                        j->begin_usec + j->unit->job_timeout, 0,
+                        job_dispatch_timer, j);
         if (r < 0)
                 return r;
 
@@ -931,7 +937,7 @@ int job_serialize(Job *j, FILE *f, FDSet *fds) {
         if (j->begin_usec > 0)
                 fprintf(f, "job-begin="USEC_FMT"\n", j->begin_usec);
 
-        bus_client_track_serialize(j->manager, f, j->subscribed);
+        bus_track_serialize(j->clients, f);
 
         /* End marker */
         fputc('\n', f);
@@ -1035,13 +1041,10 @@ int job_deserialize(Job *j, FILE *f, FDSet *fds) {
                         else
                                 j->begin_usec = ull;
 
-                } else {
-                        char t[strlen(l) + 1 + strlen(v) + 1];
+                } else if (streq(l, "subscribed")) {
 
-                        strcpy(stpcpy(stpcpy(t, l), "="), v);
-
-                        if (bus_client_track_deserialize_item(j->manager, &j->subscribed, t) == 0)
-                                log_debug("Unknown deserialization key '%s'", l);
+                        if (strv_extend(&j->deserialized_clients, v) < 0)
+                                return log_oom();
                 }
         }
 }
@@ -1051,13 +1054,27 @@ int job_coldplug(Job *j) {
 
         assert(j);
 
+        /* After deserialization is complete and the bus connection
+         * set up again, let's start watching our subscribers again */
+        r = bus_track_coldplug(j->manager, &j->clients, &j->deserialized_clients);
+        if (r < 0)
+                return r;
+
+        if (j->state == JOB_WAITING)
+                job_add_to_run_queue(j);
+
         if (j->begin_usec == 0 || j->unit->job_timeout == 0)
                 return 0;
 
         if (j->timer_event_source)
                 j->timer_event_source = sd_event_source_unref(j->timer_event_source);
 
-        r = sd_event_add_monotonic(j->manager->event, &j->timer_event_source, j->begin_usec + j->unit->job_timeout, 0, job_dispatch_timer, j);
+        r = sd_event_add_time(
+                        j->manager->event,
+                        &j->timer_event_source,
+                        CLOCK_MONOTONIC,
+                        j->begin_usec + j->unit->job_timeout, 0,
+                        job_dispatch_timer, j);
         if (r < 0)
                 log_debug("Failed to restart timeout for job: %s", strerror(-r));
 
@@ -1146,9 +1163,9 @@ static const char* const job_mode_table[_JOB_MODE_MAX] = {
         [JOB_REPLACE] = "replace",
         [JOB_REPLACE_IRREVERSIBLY] = "replace-irreversibly",
         [JOB_ISOLATE] = "isolate",
+        [JOB_FLUSH] = "flush",
         [JOB_IGNORE_DEPENDENCIES] = "ignore-dependencies",
         [JOB_IGNORE_REQUIREMENTS] = "ignore-requirements",
-        [JOB_FLUSH] = "flush",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(job_mode, JobMode);
index 8cc3a02..1e7c61b 100644 (file)
@@ -145,8 +145,15 @@ struct Job {
         sd_event_source *timer_event_source;
         usec_t begin_usec;
 
-        /* There can be more than one client, because of job merging. */
-        Set *subscribed;
+        /*
+         * This tracks where to send signals, and also which clients
+         * are allowed to call DBus methods on the job (other than
+         * root).
+         *
+         * There can be more than one client, because of job merging.
+         */
+        sd_bus_track *clients;
+        char **deserialized_clients;
 
         JobResult result;
 
index 57ed41c..291e1f9 100644 (file)
@@ -168,7 +168,7 @@ static int killall(int sig, Set *pids, bool send_sighup) {
                         continue;
 
                 if (sig == SIGKILL) {
-                        _cleanup_free_ char *s;
+                        _cleanup_free_ char *s = NULL;
 
                         get_process_comm(pid, &s);
                         log_notice("Sending SIGKILL to PID "PID_FMT" (%s).", pid, strna(s));
@@ -202,7 +202,7 @@ static int killall(int sig, Set *pids, bool send_sighup) {
 
 void broadcast_signal(int sig, bool wait_for_exit, bool send_sighup) {
         sigset_t mask, oldmask;
-        Set *pids = NULL;
+        _cleanup_set_free_ Set *pids = NULL;
 
         if (wait_for_exit)
                 pids = set_new(trivial_hash_func, trivial_compare_func);
@@ -223,6 +223,4 @@ void broadcast_signal(int sig, bool wait_for_exit, bool send_sighup) {
                 wait_for_children(pids, &mask);
 
         assert_se(sigprocmask(SIG_SETMASK, &oldmask, NULL) == 0);
-
-        set_free(pids);
 }
index 0791ae8..2f3f608 100644 (file)
@@ -27,7 +27,7 @@
 
 #include "macro.h"
 #include "execute.h"
-
+#include "capability.h"
 #include "kmod-setup.h"
 
 static void systemd_kmod_log(
@@ -54,6 +54,7 @@ static bool cmdline_check_kdbus(void) {
 }
 
 int kmod_setup(void) {
+
         static const struct {
                 const char *module;
                 const char *path;
@@ -76,6 +77,9 @@ int kmod_setup(void) {
         unsigned int i;
         int r;
 
+        if (have_effective_cap(CAP_SYS_MODULE) == 0)
+                return 0;
+
         for (i = 0; i < ELEMENTSOF(kmod_table); i++) {
                 struct kmod_module *mod;
 
index 546e560..ffc68b4 100644 (file)
@@ -58,6 +58,7 @@ static int iterate_dir(
                 if (errno == ENOENT)
                         return 0;
 
+                log_error("Failed to open directory %s: %m", path);
                 return -errno;
         }
 
@@ -101,7 +102,6 @@ static int process_dir(
                 char ***strv) {
 
         _cleanup_free_ char *path = NULL;
-        int r;
 
         assert(u);
         assert(unit_path);
@@ -112,11 +112,8 @@ static int process_dir(
         if (!path)
                 return log_oom();
 
-        if (!u->manager->unit_path_cache || set_get(u->manager->unit_path_cache, path)) {
-                r = iterate_dir(u, path, dependency, strv);
-                if (r < 0)
-                        return r;
-        }
+        if (!u->manager->unit_path_cache || set_get(u->manager->unit_path_cache, path))
+                iterate_dir(u, path, dependency, strv);
 
         if (u->instance) {
                 _cleanup_free_ char *template = NULL, *p = NULL;
@@ -130,11 +127,8 @@ static int process_dir(
                 if (!p)
                         return log_oom();
 
-                if (!u->manager->unit_path_cache || set_get(u->manager->unit_path_cache, p)) {
-                        r = iterate_dir(u, p, dependency, strv);
-                        if (r < 0)
-                                return r;
-                }
+                if (!u->manager->unit_path_cache || set_get(u->manager->unit_path_cache, p))
+                        iterate_dir(u, p, dependency, strv);
         }
 
         return 0;
@@ -152,12 +146,8 @@ char **unit_find_dropin_paths(Unit *u) {
         SET_FOREACH(t, u->names, i) {
                 char **p;
 
-                STRV_FOREACH(p, u->manager->lookup_paths.unit_path) {
-                        /* This loads the drop-in config snippets */
-                        r = process_dir(u, *p, t, ".d", _UNIT_DEPENDENCY_INVALID, &strv);
-                        if (r < 0)
-                                return NULL;
-                }
+                STRV_FOREACH(p, u->manager->lookup_paths.unit_path)
+                        process_dir(u, *p, t, ".d", _UNIT_DEPENDENCY_INVALID, &strv);
         }
 
         if (strv_isempty(strv))
@@ -176,7 +166,6 @@ char **unit_find_dropin_paths(Unit *u) {
 int unit_load_dropin(Unit *u) {
         Iterator i;
         char *t, **f;
-        int r;
 
         assert(u);
 
@@ -186,26 +175,20 @@ int unit_load_dropin(Unit *u) {
                 char **p;
 
                 STRV_FOREACH(p, u->manager->lookup_paths.unit_path) {
-                        r = process_dir(u, *p, t, ".wants", UNIT_WANTS, NULL);
-                        if (r < 0)
-                                return r;
-
-                        r = process_dir(u, *p, t, ".requires", UNIT_REQUIRES, NULL);
-                        if (r < 0)
-                                return r;
+                        process_dir(u, *p, t, ".wants", UNIT_WANTS, NULL);
+                        process_dir(u, *p, t, ".requires", UNIT_REQUIRES, NULL);
                 }
         }
 
         u->dropin_paths = unit_find_dropin_paths(u);
-        if (! u->dropin_paths)
+        if (!u->dropin_paths)
                 return 0;
 
         STRV_FOREACH(f, u->dropin_paths) {
-                r = config_parse(u->id, *f, NULL,
-                                 UNIT_VTABLE(u)->sections, config_item_perf_lookup,
-                                 (void*) load_fragment_gperf_lookup, false, false, u);
-                if (r < 0)
-                        return r;
+                config_parse(u->id, *f, NULL,
+                             UNIT_VTABLE(u)->sections,
+                             config_item_perf_lookup, load_fragment_gperf_lookup,
+                             false, false, false, u);
         }
 
         u->dropin_mtime = now(CLOCK_REALTIME);
index 26146b1..0b12b74 100644 (file)
@@ -41,21 +41,23 @@ $1.TTYReset,                     config_parse_bool,                  0,
 $1.TTYVHangup,                   config_parse_bool,                  0,                             offsetof($1, exec_context.tty_vhangup)
 $1.TTYVTDisallocate,             config_parse_bool,                  0,                             offsetof($1, exec_context.tty_vt_disallocate)
 $1.SyslogIdentifier,             config_parse_unit_string_printf,    0,                             offsetof($1, exec_context.syslog_identifier)
-$1.SyslogFacility,               config_parse_facility,              0,                             offsetof($1, exec_context.syslog_priority)
-$1.SyslogLevel,                  config_parse_level,                 0,                             offsetof($1, exec_context.syslog_priority)
+$1.SyslogFacility,               config_parse_log_facility,          0,                             offsetof($1, exec_context.syslog_priority)
+$1.SyslogLevel,                  config_parse_log_level,             0,                             offsetof($1, exec_context.syslog_priority)
 $1.SyslogLevelPrefix,            config_parse_bool,                  0,                             offsetof($1, exec_context.syslog_level_prefix)
 $1.Capabilities,                 config_parse_exec_capabilities,     0,                             offsetof($1, exec_context)
 $1.SecureBits,                   config_parse_exec_secure_bits,      0,                             offsetof($1, exec_context)
 $1.CapabilityBoundingSet,        config_parse_bounding_set,          0,                             offsetof($1, exec_context.capability_bounding_set_drop)
 $1.TimerSlackNSec,               config_parse_nsec,                  0,                             offsetof($1, exec_context.timer_slack_nsec)
-$1.NoNewPrivileges,              config_parse_bool,                  0,                             offsetof($1, exec_context.no_new_privileges)
+$1.NoNewPrivileges,              config_parse_no_new_privileges,     0,                             offsetof($1, exec_context)
 m4_ifdef(`HAVE_SECCOMP',
 `$1.SystemCallFilter,            config_parse_syscall_filter,        0,                             offsetof($1, exec_context)
 $1.SystemCallArchitectures,      config_parse_syscall_archs,         0,                             offsetof($1, exec_context.syscall_archs)
-$1.SystemCallErrorNumber,        config_parse_syscall_errno,         0,                             offsetof($1, exec_context)',
+$1.SystemCallErrorNumber,        config_parse_syscall_errno,         0,                             offsetof($1, exec_context)
+$1.RestrictAddressFamilies,      config_parse_address_families,      0,                             offsetof($1, exec_context)',
 `$1.SystemCallFilter,            config_parse_warn_compat,           0,                             0
 $1.SystemCallArchitectures,      config_parse_warn_compat,           0,                             0
-$1.SystemCallErrorNumber,        config_parse_warn_compat,           0,                             0')
+$1.SystemCallErrorNumber,        config_parse_warn_compat,           0,                             0
+$1.RestrictAddressFamilies,      config_parse_warn_compat,           0,                             0')
 $1.LimitCPU,                     config_parse_limit,                 RLIMIT_CPU,                    offsetof($1, exec_context.rlimit)
 $1.LimitFSIZE,                   config_parse_limit,                 RLIMIT_FSIZE,                  offsetof($1, exec_context.rlimit)
 $1.LimitDATA,                    config_parse_limit,                 RLIMIT_DATA,                   offsetof($1, exec_context.rlimit)
@@ -72,17 +74,18 @@ $1.LimitMSGQUEUE,                config_parse_limit,                 RLIMIT_MSGQ
 $1.LimitNICE,                    config_parse_limit,                 RLIMIT_NICE,                   offsetof($1, exec_context.rlimit)
 $1.LimitRTPRIO,                  config_parse_limit,                 RLIMIT_RTPRIO,                 offsetof($1, exec_context.rlimit)
 $1.LimitRTTIME,                  config_parse_limit,                 RLIMIT_RTTIME,                 offsetof($1, exec_context.rlimit)
-$1.ReadWriteDirectories,         config_parse_path_strv,             0,                             offsetof($1, exec_context.read_write_dirs)
-$1.ReadOnlyDirectories,          config_parse_path_strv,             0,                             offsetof($1, exec_context.read_only_dirs)
-$1.InaccessibleDirectories,      config_parse_path_strv,             0,                             offsetof($1, exec_context.inaccessible_dirs)
+$1.ReadWriteDirectories,         config_parse_namespace_path_strv,   0,                             offsetof($1, exec_context.read_write_dirs)
+$1.ReadOnlyDirectories,          config_parse_namespace_path_strv,   0,                             offsetof($1, exec_context.read_only_dirs)
+$1.InaccessibleDirectories,      config_parse_namespace_path_strv,   0,                             offsetof($1, exec_context.inaccessible_dirs)
 $1.PrivateTmp,                   config_parse_bool,                  0,                             offsetof($1, exec_context.private_tmp)
 $1.PrivateNetwork,               config_parse_bool,                  0,                             offsetof($1, exec_context.private_network)
 $1.PrivateDevices,               config_parse_bool,                  0,                             offsetof($1, exec_context.private_devices)
+$1.ProtectSystem,                config_parse_protect_system,        0,                             offsetof($1, exec_context)
+$1.ProtectHome,                  config_parse_protect_home,          0,                             offsetof($1, exec_context)
 $1.MountFlags,                   config_parse_exec_mount_flags,      0,                             offsetof($1, exec_context)
 $1.Personality,                  config_parse_personality,           0,                             offsetof($1, exec_context.personality)
-m4_ifdef(`HAVE_LIBWRAP',
-`$1.TCPWrapName,                 config_parse_unit_string_printf,    0,                             offsetof($1, exec_context.tcpwrap_name)',
-`$1.TCPWrapName,                 config_parse_warn_compat,           0,                             0')
+$1.RuntimeDirectoryMode,         config_parse_mode,                  0,                             offsetof($1, exec_context.runtime_directory_mode)
+$1.RuntimeDirectory,             config_parse_runtime_directory,     0,                             offsetof($1, exec_context.runtime_directory)
 m4_ifdef(`HAVE_PAM',
 `$1.PAMName,                     config_parse_unit_string_printf,    0,                             offsetof($1, exec_context.pam_name)',
 `$1.PAMName,                     config_parse_warn_compat,           0,                             0')
@@ -92,8 +95,11 @@ m4_ifdef(`HAVE_SELINUX',
 `$1.SELinuxContext,              config_parse_exec_selinux_context,  0,                             offsetof($1, exec_context)',
 `$1.SELinuxContext,              config_parse_warn_compat,           0,                             0')
 m4_ifdef(`HAVE_APPARMOR',
-`$1.AppArmorProfile,              config_parse_exec_apparmor_profile,0,                             offsetof($1, exec_context)',
-`$1.AppArmorProfile,              config_parse_warn_compat,          0,                             0')'
+`$1.AppArmorProfile,             config_parse_exec_apparmor_profile, 0,                             offsetof($1, exec_context)',
+`$1.AppArmorProfile,             config_parse_warn_compat,           0,                             0')
+m4_ifdef(`HAVE_SMACK',
+`$1.SmackProcessLabel,           config_parse_exec_smack_process_label, 0,                          offsetof($1, exec_context)',
+`$1.SmackProcessLabel,           config_parse_warn_compat,           0,                             0')'
 )m4_dnl
 m4_define(`KILL_CONTEXT_CONFIG_ITEMS',
 `$1.SendSIGKILL,                 config_parse_bool,                  0,                             offsetof($1, kill_context.send_sigkill)
@@ -104,13 +110,16 @@ $1.KillSignal,                   config_parse_kill_signal,           0,
 m4_define(`CGROUP_CONTEXT_CONFIG_ITEMS',
 `$1.Slice,                       config_parse_unit_slice,            0,                             0
 $1.CPUAccounting,                config_parse_bool,                  0,                             offsetof($1, cgroup_context.cpu_accounting)
-$1.CPUShares,                    config_parse_cpu_shares,            0,                             offsetof($1, cgroup_context)
+$1.CPUShares,                    config_parse_cpu_shares,            0,                             offsetof($1, cgroup_context.cpu_shares)
+$1.StartupCPUShares,             config_parse_cpu_shares,            0,                             offsetof($1, cgroup_context.startup_cpu_shares)
+$1.CPUQuota,                     config_parse_cpu_quota,             0,                             offsetof($1, cgroup_context)
 $1.MemoryAccounting,             config_parse_bool,                  0,                             offsetof($1, cgroup_context.memory_accounting)
 $1.MemoryLimit,                  config_parse_memory_limit,          0,                             offsetof($1, cgroup_context)
 $1.DeviceAllow,                  config_parse_device_allow,          0,                             offsetof($1, cgroup_context)
 $1.DevicePolicy,                 config_parse_device_policy,         0,                             offsetof($1, cgroup_context.device_policy)
 $1.BlockIOAccounting,            config_parse_bool,                  0,                             offsetof($1, cgroup_context.blockio_accounting)
-$1.BlockIOWeight,                config_parse_blockio_weight,        0,                             offsetof($1, cgroup_context)
+$1.BlockIOWeight,                config_parse_blockio_weight,        0,                             offsetof($1, cgroup_context.blockio_weight)
+$1.StartupBlockIOWeight,         config_parse_blockio_weight,        0,                             offsetof($1, cgroup_context.startup_blockio_weight)
 $1.BlockIODeviceWeight,          config_parse_blockio_device_weight, 0,                             offsetof($1, cgroup_context)
 $1.BlockIOReadBandwidth,         config_parse_blockio_bandwidth,     0,                             offsetof($1, cgroup_context)
 $1.BlockIOWriteBandwidth,        config_parse_blockio_bandwidth,     0,                             offsetof($1, cgroup_context)'
@@ -155,6 +164,8 @@ Unit.ConditionPathIsReadWrite,   config_parse_unit_condition_path,   CONDITION_P
 Unit.ConditionDirectoryNotEmpty, config_parse_unit_condition_path,   CONDITION_DIRECTORY_NOT_EMPTY, 0
 Unit.ConditionFileNotEmpty,      config_parse_unit_condition_path,   CONDITION_FILE_NOT_EMPTY,      0
 Unit.ConditionFileIsExecutable,  config_parse_unit_condition_path,   CONDITION_FILE_IS_EXECUTABLE,  0
+Unit.ConditionNeedsUpdate,       config_parse_unit_condition_path,   CONDITION_NEEDS_UPDATE,        0
+Unit.ConditionFirstBoot,         config_parse_unit_condition_string, CONDITION_FIRST_BOOT,          0
 Unit.ConditionKernelCommandLine, config_parse_unit_condition_string, CONDITION_KERNEL_COMMAND_LINE, 0
 Unit.ConditionArchitecture,      config_parse_unit_condition_string, CONDITION_ARCHITECTURE,        0
 Unit.ConditionVirtualization,    config_parse_unit_condition_string, CONDITION_VIRTUALIZATION,      0
@@ -178,14 +189,17 @@ Service.TimeoutStopSec,          config_parse_service_timeout,       0,
 Service.WatchdogSec,             config_parse_sec,                   0,                             offsetof(Service, watchdog_usec)
 Service.StartLimitInterval,      config_parse_sec,                   0,                             offsetof(Service, start_limit.interval)
 Service.StartLimitBurst,         config_parse_unsigned,              0,                             offsetof(Service, start_limit.burst)
-Service.StartLimitAction,        config_parse_start_limit_action,    0,                             offsetof(Service, start_limit_action)
+Service.StartLimitAction,        config_parse_failure_action,        0,                             offsetof(Service, start_limit_action)
+Service.RebootArgument,          config_parse_string,                0,                             offsetof(Service, reboot_arg)
+Service.FailureAction,           config_parse_failure_action,        0,                             offsetof(Service, failure_action)
 Service.Type,                    config_parse_service_type,          0,                             offsetof(Service, type)
 Service.Restart,                 config_parse_service_restart,       0,                             offsetof(Service, restart)
 Service.PermissionsStartOnly,    config_parse_bool,                  0,                             offsetof(Service, permissions_start_only)
 Service.RootDirectoryStartOnly,  config_parse_bool,                  0,                             offsetof(Service, root_directory_start_only)
 Service.RemainAfterExit,         config_parse_bool,                  0,                             offsetof(Service, remain_after_exit)
 Service.GuessMainPID,            config_parse_bool,                  0,                             offsetof(Service, guess_main_pid)
-Service.RestartPreventExitStatus, config_parse_set_status,           0,                             offsetof(Service, restart_ignore_status)
+Service.RestartPreventExitStatus, config_parse_set_status,           0,                             offsetof(Service, restart_prevent_status)
+Service.RestartForceExitStatus,  config_parse_set_status,            0,                             offsetof(Service, restart_force_status)
 Service.SuccessExitStatus,       config_parse_set_status,            0,                             offsetof(Service, success_status)
 m4_ifdef(`HAVE_SYSV_COMPAT',
 `Service.SysVStartPriority,      config_parse_sysv_priority,         0,                             offsetof(Service, sysv_start_priority)',
@@ -213,11 +227,18 @@ Socket.ExecStartPost,            config_parse_exec,                  SOCKET_EXEC
 Socket.ExecStopPre,              config_parse_exec,                  SOCKET_EXEC_STOP_PRE,          offsetof(Socket, exec_command)
 Socket.ExecStopPost,             config_parse_exec,                  SOCKET_EXEC_STOP_POST,         offsetof(Socket, exec_command)
 Socket.TimeoutSec,               config_parse_sec,                   0,                             offsetof(Socket, timeout_usec)
-Socket.DirectoryMode,            config_parse_mode,                  0,                             offsetof(Socket, directory_mode)
+Socket.SocketUser,               config_parse_unit_string_printf,    0,                             offsetof(Socket, user)
+Socket.SocketGroup,              config_parse_unit_string_printf,    0,                             offsetof(Socket, group)
 Socket.SocketMode,               config_parse_mode,                  0,                             offsetof(Socket, socket_mode)
+Socket.DirectoryMode,            config_parse_mode,                  0,                             offsetof(Socket, directory_mode)
 Socket.Accept,                   config_parse_bool,                  0,                             offsetof(Socket, accept)
 Socket.MaxConnections,           config_parse_unsigned,              0,                             offsetof(Socket, max_connections)
 Socket.KeepAlive,                config_parse_bool,                  0,                             offsetof(Socket, keep_alive)
+Socket.KeepAliveTimeSec,         config_parse_sec,                   0,                             offsetof(Socket, keep_alive_time)
+Socket.KeepAliveIntervalSec,     config_parse_sec,                   0,                             offsetof(Socket, keep_alive_interval)
+Socket.KeepAliveProbes,          config_parse_unsigned,              0,                             offsetof(Socket, keep_alive_cnt)
+Socket.DeferAcceptSec,           config_parse_sec,                   0,                             offsetof(Socket, defer_accept)
+Socket.NoDelay,                  config_parse_bool,                  0,                             offsetof(Socket, no_delay)
 Socket.Priority,                 config_parse_int,                   0,                             offsetof(Socket, priority)
 Socket.ReceiveBuffer,            config_parse_iec_size,              0,                             offsetof(Socket, receive_buffer)
 Socket.SendBuffer,               config_parse_iec_size,              0,                             offsetof(Socket, send_buffer)
@@ -234,6 +255,8 @@ Socket.TCPCongestion,            config_parse_string,                0,
 Socket.ReusePort,                config_parse_bool,                  0,                             offsetof(Socket, reuse_port)
 Socket.MessageQueueMaxMessages,  config_parse_long,                  0,                             offsetof(Socket, mq_maxmsg)
 Socket.MessageQueueMessageSize,  config_parse_long,                  0,                             offsetof(Socket, mq_msgsize)
+Socket.RemoveOnStop,             config_parse_bool,                  0,                             offsetof(Socket, remove_on_stop)
+Socket.Symlinks,                 config_parse_unit_path_strv_printf, 0,                             offsetof(Socket, symlinks)
 Socket.Service,                  config_parse_socket_service,        0,                             0
 m4_ifdef(`HAVE_SMACK',
 `Socket.SmackLabel,              config_parse_string,                0,                             offsetof(Socket, smack)
@@ -247,7 +270,13 @@ CGROUP_CONTEXT_CONFIG_ITEMS(Socket)m4_dnl
 KILL_CONTEXT_CONFIG_ITEMS(Socket)m4_dnl
 m4_dnl
 BusName.Name,                    config_parse_string,                0,                             offsetof(BusName, name)
+BusName.Activating,              config_parse_bool,                  0,                             offsetof(BusName, activating)
 BusName.Service,                 config_parse_busname_service,       0,                             0
+BusName.AllowUser,               config_parse_bus_policy,            0,                             0
+BusName.AllowGroup,              config_parse_bus_policy,            0,                             0
+BusName.AllowWorld,              config_parse_bus_policy_world,      0,                             offsetof(BusName, policy_world)
+BusName.SELinuxContext,          config_parse_exec_selinux_context,  0,                             0
+BusName.AcceptFileDescriptors,   config_parse_bool,                  0,                             offsetof(BusName, accept_fd)
 m4_dnl
 Mount.What,                      config_parse_string,                0,                             offsetof(Mount, parameters_fragment.what)
 Mount.Where,                     config_parse_path,                  0,                             offsetof(Mount, where)
@@ -255,6 +284,7 @@ Mount.Options,                   config_parse_string,                0,
 Mount.Type,                      config_parse_string,                0,                             offsetof(Mount, parameters_fragment.fstype)
 Mount.TimeoutSec,                config_parse_sec,                   0,                             offsetof(Mount, timeout_usec)
 Mount.DirectoryMode,             config_parse_mode,                  0,                             offsetof(Mount, directory_mode)
+Mount.SloppyOptions,             config_parse_bool,                  0,                             offsetof(Mount, sloppy_options)
 EXEC_CONTEXT_CONFIG_ITEMS(Mount)m4_dnl
 CGROUP_CONTEXT_CONFIG_ITEMS(Mount)m4_dnl
 KILL_CONTEXT_CONFIG_ITEMS(Mount)m4_dnl
@@ -275,6 +305,8 @@ Timer.OnBootSec,                 config_parse_timer,                 0,
 Timer.OnStartupSec,              config_parse_timer,                 0,                             0
 Timer.OnUnitActiveSec,           config_parse_timer,                 0,                             0
 Timer.OnUnitInactiveSec,         config_parse_timer,                 0,                             0
+Timer.Persistent,                config_parse_bool,                  0,                             offsetof(Timer, persistent)
+Timer.WakeSystem,                config_parse_bool,                  0,                             offsetof(Timer, wake_system)
 Timer.AccuracySec,               config_parse_sec,                   0,                             offsetof(Timer, accuracy_usec)
 Timer.Unit,                      config_parse_trigger_unit,          0,                             0
 m4_dnl
@@ -297,3 +329,4 @@ Install.Alias,                   NULL,                               0,
 Install.WantedBy,                NULL,                               0,                             0
 Install.RequiredBy,              NULL,                               0,                             0
 Install.Also,                    NULL,                               0,                             0
+Install.DefaultInstance,         NULL,                               0,                             0
index 82aed1e..51e2df0 100644 (file)
@@ -33,6 +33,8 @@
 #include <sys/stat.h>
 #include <sys/time.h>
 #include <sys/resource.h>
+#include <sys/types.h>
+#include <grp.h>
 
 #ifdef HAVE_SECCOMP
 #include <seccomp.h>
 #include "bus-util.h"
 #include "bus-error.h"
 #include "errno-list.h"
+#include "af-list.h"
 
 #ifdef HAVE_SECCOMP
 #include "seccomp-util.h"
 #endif
 
-#if !defined(HAVE_SYSV_COMPAT) || !defined(HAVE_SECCOMP) || !defined(HAVE_LIBWRAP) || !defined(HAVE_PAM) || !defined(HAVE_SELINUX) || !defined(HAVE_SMACK) || !defined(HAVE_APPARMOR)
+#if !defined(HAVE_SYSV_COMPAT) || !defined(HAVE_SECCOMP) || !defined(HAVE_PAM) || !defined(HAVE_SELINUX) || !defined(HAVE_SMACK) || !defined(HAVE_APPARMOR)
 int config_parse_warn_compat(
                 const char *unit,
                 const char *filename,
@@ -81,7 +84,7 @@ int config_parse_warn_compat(
 }
 #endif
 
-int config_parse_unit_deps(const charunit,
+int config_parse_unit_deps(const char *unit,
                            const char *filename,
                            unsigned line,
                            const char *section,
@@ -94,19 +97,18 @@ int config_parse_unit_deps(const char* unit,
 
         UnitDependency d = ltype;
         Unit *u = userdata;
-        char *w;
+        const char *word, *state;
         size_t l;
-        char *state;
 
         assert(filename);
         assert(lvalue);
         assert(rvalue);
 
-        FOREACH_WORD_QUOTED(w, l, rvalue, state) {
+        FOREACH_WORD_QUOTED(word, l, rvalue, state) {
                 _cleanup_free_ char *t = NULL, *k = NULL;
                 int r;
 
-                t = strndup(w, l);
+                t = strndup(word, l);
                 if (!t)
                         return log_oom();
 
@@ -122,6 +124,8 @@ int config_parse_unit_deps(const char* unit,
                         log_syntax(unit, LOG_ERR, filename, line, -r,
                                    "Failed to add dependency on %s, ignoring: %s", k, strerror(-r));
         }
+        if (!isempty(state))
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Invalid syntax, ignoring.");
 
         return 0;
 }
@@ -195,8 +199,8 @@ int config_parse_unit_path_printf(const char *unit,
                                   void *data,
                                   void *userdata) {
 
-        Unit *u = userdata;
         _cleanup_free_ char *k = NULL;
+        Unit *u = userdata;
         int r;
 
         assert(filename);
@@ -205,12 +209,72 @@ int config_parse_unit_path_printf(const char *unit,
         assert(u);
 
         r = unit_full_printf(u, rvalue, &k);
-        if (r < 0)
-                log_syntax(unit, LOG_ERR, filename, line, -r,
-                           "Failed to resolve unit specifiers on %s, ignoring: %s", rvalue, strerror(-r));
+        if (r < 0) {
+                log_syntax(unit, LOG_ERR, filename, line, -r, "Failed to resolve unit specifiers on %s, ignoring: %s", rvalue, strerror(-r));
+                return 0;
+        }
 
-        return config_parse_path(unit, filename, line, section, section_line, lvalue, ltype,
-                                 k ? k : rvalue, data, userdata);
+        return config_parse_path(unit, filename, line, section, section_line, lvalue, ltype, k, data, userdata);
+}
+
+int config_parse_unit_path_strv_printf(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        char ***x = data;
+        const char *word, *state;
+        Unit *u = userdata;
+        size_t l;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(u);
+
+        FOREACH_WORD_QUOTED(word, l, rvalue, state) {
+                _cleanup_free_ char *k = NULL;
+                char t[l+1];
+
+                memcpy(t, word, l);
+                t[l] = 0;
+
+                r = unit_full_printf(u, t, &k);
+                if (r < 0) {
+                        log_syntax(unit, LOG_ERR, filename, line, -r, "Failed to resolve unit specifiers on %s, ignoring: %s", t, strerror(-r));
+                        return 0;
+                }
+
+                if (!utf8_is_valid(k)) {
+                        log_invalid_utf8(unit, LOG_ERR, filename, line, EINVAL, rvalue);
+                        return 0;
+                }
+
+                if (!path_is_absolute(k)) {
+                        log_syntax(unit, LOG_ERR, filename, line, -r, "Symlink path %s is not absolute, ignoring: %s", k, strerror(-r));
+                        return 0;
+                }
+
+                path_kill_slashes(k);
+
+                r = strv_push(x, k);
+                if (r < 0)
+                        return log_oom();
+
+                k = NULL;
+        }
+        if (!isempty(state))
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Invalid syntax, ignoring.");
+
+        return 0;
 }
 
 int config_parse_socket_listen(const char *unit,
@@ -474,9 +538,8 @@ int config_parse_exec(const char *unit,
          * overriding of argv[0]. */
         for (;;) {
                 int i;
-                char *w;
+                const char *word, *state;
                 size_t l;
-                char *state;
                 bool honour_argv0 = false, ignore = false;
 
                 path = NULL;
@@ -507,37 +570,41 @@ int config_parse_exec(const char *unit,
                 }
 
                 k = 0;
-                FOREACH_WORD_QUOTED(w, l, rvalue, state) {
-                        if (strneq(w, ";", MAX(l, 1U)))
-                                break;
+                FOREACH_WORD_QUOTED(word, l, rvalue, state) {
+                        if (strneq(word, ";", MAX(l, 1U)))
+                                goto found;
 
                         k++;
                 }
+                if (!isempty(state)) {
+                        log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                                   "Trailing garbage, ignoring.");
+                        return 0;
+                }
 
+        found:
                 n = new(char*, k + !honour_argv0);
                 if (!n)
                         return log_oom();
 
                 k = 0;
-                FOREACH_WORD_QUOTED(w, l, rvalue, state) {
-                        if (strneq(w, ";", MAX(l, 1U)))
+                FOREACH_WORD_QUOTED(word, l, rvalue, state) {
+                        if (strneq(word, ";", MAX(l, 1U)))
                                 break;
-                        else if (strneq(w, "\\;", MAX(l, 1U)))
-                                w ++;
+                        else if (strneq(word, "\\;", MAX(l, 1U)))
+                                word ++;
 
-                        if (honour_argv0 && w == rvalue) {
+                        if (honour_argv0 && word == rvalue) {
                                 assert(!path);
 
-                                path = strndup(w, l);
+                                path = strndup(word, l);
                                 if (!path) {
                                         r = log_oom();
                                         goto fail;
                                 }
 
                                 if (!utf8_is_valid(path)) {
-                                        log_syntax(unit, LOG_ERR, filename, line, EINVAL,
-                                                   "Path is not UTF-8 clean, ignoring assignment: %s",
-                                                   rvalue);
+                                        log_invalid_utf8(unit, LOG_ERR, filename, line, EINVAL, rvalue);
                                         r = 0;
                                         goto fail;
                                 }
@@ -545,16 +612,14 @@ int config_parse_exec(const char *unit,
                         } else {
                                 char *c;
 
-                                c = n[k++] = cunescape_length(w, l);
+                                c = n[k++] = cunescape_length(word, l);
                                 if (!c) {
                                         r = log_oom();
                                         goto fail;
                                 }
 
                                 if (!utf8_is_valid(c)) {
-                                        log_syntax(unit, LOG_ERR, filename, line, EINVAL,
-                                                   "Path is not UTF-8 clean, ignoring assignment: %s",
-                                                   rvalue);
+                                        log_invalid_utf8(unit, LOG_ERR, filename, line, EINVAL, rvalue);
                                         r = 0;
                                         goto fail;
                                 }
@@ -799,9 +864,8 @@ int config_parse_exec_cpu_affinity(const char *unit,
                                    void *userdata) {
 
         ExecContext *c = data;
-        char *w;
+        const char *word, *state;
         size_t l;
-        char *state;
 
         assert(filename);
         assert(lvalue);
@@ -816,12 +880,12 @@ int config_parse_exec_cpu_affinity(const char *unit,
                 return 0;
         }
 
-        FOREACH_WORD_QUOTED(w, l, rvalue, state) {
+        FOREACH_WORD_QUOTED(word, l, rvalue, state) {
                 _cleanup_free_ char *t = NULL;
                 int r;
                 unsigned cpu;
 
-                t = strndup(w, l);
+                t = strndup(word, l);
                 if (!t)
                         return log_oom();
 
@@ -841,6 +905,9 @@ int config_parse_exec_cpu_affinity(const char *unit,
 
                 CPU_SET_S(cpu, CPU_ALLOC_SIZE(c->cpuset_ncpus), c->cpuset);
         }
+        if (!isempty(state))
+                log_syntax(unit, LOG_WARNING, filename, line, EINVAL,
+                           "Trailing garbage, ignoring.");
 
         return 0;
 }
@@ -890,9 +957,8 @@ int config_parse_exec_secure_bits(const char *unit,
                                   void *userdata) {
 
         ExecContext *c = data;
-        char *w;
         size_t l;
-        char *state;
+        const char *word, *state;
 
         assert(filename);
         assert(lvalue);
@@ -905,18 +971,18 @@ int config_parse_exec_secure_bits(const char *unit,
                 return 0;
         }
 
-        FOREACH_WORD_QUOTED(w, l, rvalue, state) {
-                if (first_word(w, "keep-caps"))
+        FOREACH_WORD_QUOTED(word, l, rvalue, state) {
+                if (first_word(word, "keep-caps"))
                         c->secure_bits |= 1<<SECURE_KEEP_CAPS;
-                else if (first_word(w, "keep-caps-locked"))
+                else if (first_word(word, "keep-caps-locked"))
                         c->secure_bits |= 1<<SECURE_KEEP_CAPS_LOCKED;
-                else if (first_word(w, "no-setuid-fixup"))
+                else if (first_word(word, "no-setuid-fixup"))
                         c->secure_bits |= 1<<SECURE_NO_SETUID_FIXUP;
-                else if (first_word(w, "no-setuid-fixup-locked"))
+                else if (first_word(word, "no-setuid-fixup-locked"))
                         c->secure_bits |= 1<<SECURE_NO_SETUID_FIXUP_LOCKED;
-                else if (first_word(w, "noroot"))
+                else if (first_word(word, "noroot"))
                         c->secure_bits |= 1<<SECURE_NOROOT;
-                else if (first_word(w, "noroot-locked"))
+                else if (first_word(word, "noroot-locked"))
                         c->secure_bits |= 1<<SECURE_NOROOT_LOCKED;
                 else {
                         log_syntax(unit, LOG_ERR, filename, line, EINVAL,
@@ -924,6 +990,9 @@ int config_parse_exec_secure_bits(const char *unit,
                         return 0;
                 }
         }
+        if (!isempty(state))
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                           "Invalid syntax, garbage at the end, ignoring.");
 
         return 0;
 }
@@ -940,9 +1009,8 @@ int config_parse_bounding_set(const char *unit,
                               void *userdata) {
 
         uint64_t *capability_bounding_set_drop = data;
-        char *w;
+        const char *word, *state;
         size_t l;
-        char *state;
         bool invert = false;
         uint64_t sum = 0;
 
@@ -961,12 +1029,12 @@ int config_parse_bounding_set(const char *unit,
          * non-inverted everywhere to have a fully normalized
          * interface. */
 
-        FOREACH_WORD_QUOTED(w, l, rvalue, state) {
+        FOREACH_WORD_QUOTED(word, l, rvalue, state) {
                 _cleanup_free_ char *t = NULL;
                 int r;
                 cap_value_t cap;
 
-                t = strndup(w, l);
+                t = strndup(word, l);
                 if (!t)
                         return log_oom();
 
@@ -979,6 +1047,9 @@ int config_parse_bounding_set(const char *unit,
 
                 sum |= ((uint64_t) 1ULL) << (uint64_t) cap;
         }
+        if (!isempty(state))
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                           "Trailing garbage, ignoring.");
 
         if (invert)
                 *capability_bounding_set_drop |= sum;
@@ -1108,9 +1179,8 @@ int config_parse_exec_mount_flags(const char *unit,
                                   void *userdata) {
 
         ExecContext *c = data;
-        char *w;
+        const char *word, *state;
         size_t l;
-        char *state;
         unsigned long flags = 0;
 
         assert(filename);
@@ -1118,26 +1188,28 @@ int config_parse_exec_mount_flags(const char *unit,
         assert(rvalue);
         assert(data);
 
-        FOREACH_WORD_SEPARATOR(w, l, rvalue, ", ", state) {
+        FOREACH_WORD_SEPARATOR(word, l, rvalue, ", ", state) {
                 _cleanup_free_ char *t;
 
-                t = strndup(w, l);
+                t = strndup(word, l);
                 if (!t)
                         return log_oom();
 
                 if (streq(t, "shared"))
-                        flags |= MS_SHARED;
+                        flags = MS_SHARED;
                 else if (streq(t, "slave"))
-                        flags |= MS_SLAVE;
-                else if (streq(w, "private"))
-                        flags |= MS_PRIVATE;
+                        flags = MS_SLAVE;
+                else if (streq(word, "private"))
+                        flags = MS_PRIVATE;
                 else {
                         log_syntax(unit, LOG_ERR, filename, line, EINVAL,
-                                   "Failed to parse mount flag %s, ignoring: %s",
-                                   t, rvalue);
+                                   "Failed to parse mount flag %s, ignoring: %s", t, rvalue);
                         return 0;
                 }
         }
+        if (!isempty(state))
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                           "Trailing garbage, ignoring.");
 
         c->mount_flags = flags;
         return 0;
@@ -1181,7 +1253,8 @@ int config_parse_exec_selinux_context(
 
         r = unit_name_printf(u, rvalue, &k);
         if (r < 0) {
-                log_syntax(unit, LOG_ERR, filename, line, -r, "Failed to resolve specifiers, ignoring: %s", strerror(-r));
+                log_syntax(unit, LOG_ERR, filename, line, -r,
+                           "Failed to resolve specifiers, ignoring: %s", strerror(-r));
                 return 0;
         }
 
@@ -1230,7 +1303,8 @@ int config_parse_exec_apparmor_profile(
 
         r = unit_name_printf(u, rvalue, &k);
         if (r < 0) {
-                log_syntax(unit, LOG_ERR, filename, line, -r, "Failed to resolve specifiers, ignoring: %s", strerror(-r));
+                log_syntax(unit, LOG_ERR, filename, line, -r,
+                           "Failed to resolve specifiers, ignoring: %s", strerror(-r));
                 return 0;
         }
 
@@ -1241,6 +1315,56 @@ int config_parse_exec_apparmor_profile(
         return 0;
 }
 
+int config_parse_exec_smack_process_label(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        ExecContext *c = data;
+        Unit *u = userdata;
+        bool ignore;
+        char *k;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        if (isempty(rvalue)) {
+                free(c->smack_process_label);
+                c->smack_process_label = NULL;
+                c->smack_process_label_ignore = false;
+                return 0;
+        }
+
+        if (rvalue[0] == '-') {
+                ignore = true;
+                rvalue++;
+        } else
+                ignore = false;
+
+        r = unit_name_printf(u, rvalue, &k);
+        if (r < 0) {
+                log_syntax(unit, LOG_ERR, filename, line, -r,
+                           "Failed to resolve specifiers, ignoring: %s", strerror(-r));
+                return 0;
+        }
+
+        free(c->smack_process_label);
+        c->smack_process_label = k;
+        c->smack_process_label_ignore = ignore;
+
+        return 0;
+}
+
 int config_parse_timer(const char *unit,
                        const char *filename,
                        unsigned line,
@@ -1257,7 +1381,6 @@ int config_parse_timer(const char *unit,
         TimerValue *v;
         TimerBase b;
         CalendarSpec *c = NULL;
-        clockid_t id;
 
         assert(filename);
         assert(lvalue);
@@ -1284,8 +1407,6 @@ int config_parse_timer(const char *unit,
                                    rvalue);
                         return 0;
                 }
-
-                id = CLOCK_REALTIME;
         } else {
                 if (parse_sec(rvalue, &u) < 0) {
                         log_syntax(unit, LOG_ERR, filename, line, EINVAL,
@@ -1293,8 +1414,6 @@ int config_parse_timer(const char *unit,
                                    rvalue);
                         return 0;
                 }
-
-                id = CLOCK_MONOTONIC;
         }
 
         v = new0(TimerValue, 1);
@@ -1302,7 +1421,6 @@ int config_parse_timer(const char *unit,
                 return log_oom();
 
         v->base = b;
-        v->clock_id = id;
         v->value = u;
         v->calendar_spec = c;
 
@@ -1458,18 +1576,21 @@ int config_parse_socket_service(const char *unit,
 
         r = unit_name_printf(UNIT(s), rvalue, &p);
         if (r < 0) {
-                log_syntax(unit, LOG_ERR, filename, line, -r, "Failed to resolve specifiers, ignoring: %s", rvalue);
+                log_syntax(unit, LOG_ERR, filename, line, -r,
+                           "Failed to resolve specifiers, ignoring: %s", rvalue);
                 return 0;
         }
 
         if (!endswith(p, ".service")) {
-                log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Unit must be of type service, ignoring: %s", rvalue);
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                           "Unit must be of type service, ignoring: %s", rvalue);
                 return 0;
         }
 
         r = manager_load_unit(UNIT(s)->manager, p, NULL, &error, &x);
         if (r < 0) {
-                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to load unit %s, ignoring: %s", rvalue, bus_error_message(&error, r));
+                log_syntax(unit, LOG_ERR, filename, line, -r,
+                           "Failed to load unit %s, ignoring: %s", rvalue, bus_error_message(&error, r));
                 return 0;
         }
 
@@ -1491,7 +1612,7 @@ int config_parse_service_sockets(const char *unit,
 
         Service *s = data;
         int r;
-        char *state, *w;
+        const char *word, *state;
         size_t l;
 
         assert(filename);
@@ -1499,10 +1620,10 @@ int config_parse_service_sockets(const char *unit,
         assert(rvalue);
         assert(data);
 
-        FOREACH_WORD_QUOTED(w, l, rvalue, state) {
+        FOREACH_WORD_QUOTED(word, l, rvalue, state) {
                 _cleanup_free_ char *t = NULL, *k = NULL;
 
-                t = strndup(w, l);
+                t = strndup(word, l);
                 if (!t)
                         return log_oom();
 
@@ -1527,6 +1648,9 @@ int config_parse_service_sockets(const char *unit,
                 if (r < 0)
                         return r;
         }
+        if (!isempty(state))
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                           "Trailing garbage, ignoring.");
 
         return 0;
 }
@@ -1589,18 +1713,21 @@ int config_parse_busname_service(
 
         r = unit_name_printf(UNIT(n), rvalue, &p);
         if (r < 0) {
-                log_syntax(unit, LOG_ERR, filename, line, -r, "Failed to resolve specifiers, ignoring: %s", rvalue);
+                log_syntax(unit, LOG_ERR, filename, line, -r,
+                           "Failed to resolve specifiers, ignoring: %s", rvalue);
                 return 0;
         }
 
         if (!endswith(p, ".service")) {
-                log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Unit must be of type service, ignoring: %s", rvalue);
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                           "Unit must be of type service, ignoring: %s", rvalue);
                 return 0;
         }
 
         r = manager_load_unit(UNIT(n)->manager, p, NULL, &error, &x);
         if (r < 0) {
-                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to load unit %s, ignoring: %s", rvalue, bus_error_message(&error, r));
+                log_syntax(unit, LOG_ERR, filename, line, -r,
+                           "Failed to load unit %s, ignoring: %s", rvalue, bus_error_message(&error, r));
                 return 0;
         }
 
@@ -1609,6 +1736,72 @@ int config_parse_busname_service(
         return 0;
 }
 
+DEFINE_CONFIG_PARSE_ENUM(config_parse_bus_policy_world, busname_policy_access, BusNamePolicyAccess, "Failed to parse bus name policy access");
+
+int config_parse_bus_policy(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        _cleanup_free_ BusNamePolicy *p = NULL;
+        _cleanup_free_ char *id_str = NULL;
+        BusName *busname = data;
+        char *access_str;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        p = new0(BusNamePolicy, 1);
+        if (!p)
+                return log_oom();
+
+        if (streq(lvalue, "AllowUser"))
+                p->type = BUSNAME_POLICY_TYPE_USER;
+        else if (streq(lvalue, "AllowGroup"))
+                p->type = BUSNAME_POLICY_TYPE_GROUP;
+        else
+                assert_not_reached("Unknown lvalue");
+
+        id_str = strdup(rvalue);
+        if (!id_str)
+                return log_oom();
+
+        access_str = strpbrk(id_str, WHITESPACE);
+        if (!access_str) {
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                           "Invalid busname policy value '%s'", rvalue);
+                return 0;
+        }
+
+        *access_str = '\0';
+        access_str++;
+        access_str += strspn(access_str, WHITESPACE);
+
+        p->access = busname_policy_access_from_string(access_str);
+        if (p->access < 0) {
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                           "Invalid busname policy access type '%s'", access_str);
+                return 0;
+        }
+
+        p->name = id_str;
+        id_str = NULL;
+
+        LIST_PREPEND(policy, busname->policy, p);
+        p = NULL;
+
+        return 0;
+}
+
 int config_parse_unit_env_file(const char *unit,
                                const char *filename,
                                unsigned line,
@@ -1640,7 +1833,7 @@ int config_parse_unit_env_file(const char *unit,
 
         r = unit_full_printf(u, rvalue, &n);
         if (r < 0)
-                log_syntax(unit, LOG_ERR, filename, line, r,
+                log_syntax(unit, LOG_ERR, filename, line, -r,
                            "Failed to resolve specifiers, ignoring: %s", rvalue);
 
         s = n ?: rvalue;
@@ -1669,7 +1862,8 @@ int config_parse_environ(const char *unit,
                          void *userdata) {
 
         Unit *u = userdata;
-        char*** env = data, *w, *state;
+        char*** env = data;
+        const char *word, *state;
         size_t l;
         _cleanup_free_ char *k = NULL;
         int r;
@@ -1698,11 +1892,11 @@ int config_parse_environ(const char *unit,
         if (!k)
                 return log_oom();
 
-        FOREACH_WORD_QUOTED(w, l, k, state) {
+        FOREACH_WORD_QUOTED(word, l, k, state) {
                 _cleanup_free_ char *n;
                 char **x;
 
-                n = cunescape_length(w, l);
+                n = cunescape_length(word, l);
                 if (!n)
                         return log_oom();
 
@@ -1719,6 +1913,9 @@ int config_parse_environ(const char *unit,
                 strv_free(*env);
                 *env = x;
         }
+        if (!isempty(state))
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                           "Trailing garbage, ignoring.");
 
         return 0;
 }
@@ -1926,7 +2123,7 @@ int config_parse_unit_condition_null(const char *unit,
 }
 
 DEFINE_CONFIG_PARSE_ENUM(config_parse_notify_access, notify_access, NotifyAccess, "Failed to parse notify access specifier");
-DEFINE_CONFIG_PARSE_ENUM(config_parse_start_limit_action, start_limit_action, StartLimitAction, "Failed to parse start limit action specifier");
+DEFINE_CONFIG_PARSE_ENUM(config_parse_failure_action, failure_action, FailureAction, "Failed to parse failure action specifier");
 
 int config_parse_unit_requires_mounts_for(
                 const char *unit,
@@ -1941,36 +2138,37 @@ int config_parse_unit_requires_mounts_for(
                 void *userdata) {
 
         Unit *u = userdata;
-        char *state;
+        const char *word, *state;
         size_t l;
-        char *w;
 
         assert(filename);
         assert(lvalue);
         assert(rvalue);
         assert(data);
 
-        FOREACH_WORD_QUOTED(w, l, rvalue, state) {
+        FOREACH_WORD_QUOTED(word, l, rvalue, state) {
                 int r;
                 _cleanup_free_ char *n;
 
-                n = strndup(w, l);
+                n = strndup(word, l);
                 if (!n)
                         return log_oom();
 
                 if (!utf8_is_valid(n)) {
-                        log_syntax(unit, LOG_ERR, filename, line, EINVAL,
-                                   "Path is not UTF-8 clean, ignoring assignment: %s", rvalue);
+                        log_invalid_utf8(unit, LOG_ERR, filename, line, EINVAL, rvalue);
                         continue;
                 }
 
                 r = unit_require_mounts_for(u, n);
                 if (r < 0) {
-                        log_syntax(unit, LOG_ERR, filename, line, r,
+                        log_syntax(unit, LOG_ERR, filename, line, -r,
                                    "Failed to add required mount for, ignoring: %s", rvalue);
                         continue;
                 }
         }
+        if (!isempty(state))
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                           "Trailing garbage, ignoring.");
 
         return 0;
 }
@@ -2046,7 +2244,7 @@ int config_parse_syscall_filter(
         ExecContext *c = data;
         Unit *u = userdata;
         bool invert = false;
-        char *w, *state;
+        const char *word, *state;
         size_t l;
         int r;
 
@@ -2099,17 +2297,18 @@ int config_parse_syscall_filter(
                 }
         }
 
-        FOREACH_WORD_QUOTED(w, l, rvalue, state) {
+        FOREACH_WORD_QUOTED(word, l, rvalue, state) {
                 _cleanup_free_ char *t = NULL;
                 int id;
 
-                t = strndup(w, l);
+                t = strndup(word, l);
                 if (!t)
                         return log_oom();
 
                 id = seccomp_syscall_resolve_name(t);
                 if (id < 0)  {
-                        log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Failed to parse system call, ignoring: %s", t);
+                        log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                                   "Failed to parse system call, ignoring: %s", t);
                         continue;
                 }
 
@@ -2125,8 +2324,14 @@ int config_parse_syscall_filter(
                 } else
                         set_remove(c->syscall_filter, INT_TO_PTR(id + 1));
         }
+        if (!isempty(state))
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                           "Trailing garbage, ignoring.");
 
-        c->no_new_privileges = true;
+        /* Turn on NNP, but only if it wasn't configured explicitly
+         * before, and only if we are in user mode. */
+        if (!c->no_new_privileges_set && u->manager->running_as == SYSTEMD_USER)
+                c->no_new_privileges = true;
 
         return 0;
 }
@@ -2144,7 +2349,7 @@ int config_parse_syscall_archs(
                 void *userdata) {
 
         Set **archs = data;
-        char *w, *state;
+        const char *word, *state;
         size_t l;
         int r;
 
@@ -2158,17 +2363,18 @@ int config_parse_syscall_archs(
         if (r < 0)
                 return log_oom();
 
-        FOREACH_WORD_QUOTED(w, l, rvalue, state) {
+        FOREACH_WORD_QUOTED(word, l, rvalue, state) {
                 _cleanup_free_ char *t = NULL;
                 uint32_t a;
 
-                t = strndup(w, l);
+                t = strndup(word, l);
                 if (!t)
                         return log_oom();
 
                 r = seccomp_arch_from_string(t, &a);
                 if (r < 0) {
-                        log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Failed to parse system call architecture, ignoring: %s", t);
+                        log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                                   "Failed to parse system call architecture, ignoring: %s", t);
                         continue;
                 }
 
@@ -2178,6 +2384,9 @@ int config_parse_syscall_archs(
                 if (r < 0)
                         return log_oom();
         }
+        if (!isempty(state))
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                           "Trailing garbage, ignoring.");
 
         return 0;
 }
@@ -2209,13 +2418,93 @@ int config_parse_syscall_errno(
 
         e = errno_from_name(rvalue);
         if (e < 0) {
-                log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Failed to parse error number, ignoring: %s", rvalue);
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                           "Failed to parse error number, ignoring: %s", rvalue);
                 return 0;
         }
 
         c->syscall_errno = e;
         return 0;
 }
+
+int config_parse_address_families(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        ExecContext *c = data;
+        Unit *u = userdata;
+        bool invert = false;
+        const char *word, *state;
+        size_t l;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(u);
+
+        if (isempty(rvalue)) {
+                /* Empty assignment resets the list */
+                set_free(c->address_families);
+                c->address_families = NULL;
+                c->address_families_whitelist = false;
+                return 0;
+        }
+
+        if (rvalue[0] == '~') {
+                invert = true;
+                rvalue++;
+        }
+
+        if (!c->address_families) {
+                c->address_families = set_new(trivial_hash_func, trivial_compare_func);
+                if (!c->address_families)
+                        return log_oom();
+
+                c->address_families_whitelist = !invert;
+        }
+
+        FOREACH_WORD_QUOTED(word, l, rvalue, state) {
+                _cleanup_free_ char *t = NULL;
+                int af;
+
+                t = strndup(word, l);
+                if (!t)
+                        return log_oom();
+
+                af = af_from_name(t);
+                if (af <= 0)  {
+                        log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                                   "Failed to parse address family, ignoring: %s", t);
+                        continue;
+                }
+
+                /* If we previously wanted to forbid an address family and now
+                 * we want to allow it, then remove it from the list
+                 */
+                if (!invert == c->address_families_whitelist)  {
+                        r = set_put(c->address_families, INT_TO_PTR(af));
+                        if (r == -EEXIST)
+                                continue;
+                        if (r < 0)
+                                return log_oom();
+                } else
+                        set_remove(c->address_families, INT_TO_PTR(af));
+        }
+        if (!isempty(state))
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                           "Trailing garbage, ignoring.");
+
+        return 0;
+}
 #endif
 
 int config_parse_unit_slice(
@@ -2280,8 +2569,7 @@ int config_parse_cpu_shares(
                 void *data,
                 void *userdata) {
 
-        CGroupContext *c = data;
-        unsigned long lu;
+        unsigned long *shares = data, lu;
         int r;
 
         assert(filename);
@@ -2289,7 +2577,7 @@ int config_parse_cpu_shares(
         assert(rvalue);
 
         if (isempty(rvalue)) {
-                c->cpu_shares = 1024;
+                *shares = (unsigned long) -1;
                 return 0;
         }
 
@@ -2300,7 +2588,49 @@ int config_parse_cpu_shares(
                 return 0;
         }
 
-        c->cpu_shares = lu;
+        *shares = lu;
+        return 0;
+}
+
+int config_parse_cpu_quota(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        CGroupContext *c = data;
+        double percent;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+
+        if (isempty(rvalue)) {
+                c->cpu_quota_per_sec_usec = USEC_INFINITY;
+                return 0;
+        }
+
+        if (!endswith(rvalue, "%")) {
+
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                           "CPU quota '%s' not ending in '%%'. Ignoring.", rvalue);
+                return 0;
+        }
+
+        if (sscanf(rvalue, "%lf%%", &percent) != 1 || percent <= 0) {
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                           "CPU quota '%s' invalid. Ignoring.", rvalue);
+                return 0;
+        }
+
+        c->cpu_quota_per_sec_usec = (usec_t) (percent * USEC_PER_SEC / 100);
+
         return 0;
 }
 
@@ -2329,7 +2659,8 @@ int config_parse_memory_limit(
 
         r = parse_size(rvalue, 1024, &bytes);
         if (r < 0) {
-                log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Memory limit '%s' invalid. Ignoring.", rvalue);
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                           "Memory limit '%s' invalid. Ignoring.", rvalue);
                 return 0;
         }
 
@@ -2370,7 +2701,8 @@ int config_parse_device_allow(
         if (!startswith(path, "/dev/") &&
             !startswith(path, "block-") &&
             !startswith(path, "char-")) {
-                log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Invalid device node path '%s'. Ignoring.", path);
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                           "Invalid device node path '%s'. Ignoring.", path);
                 return 0;
         }
 
@@ -2379,7 +2711,8 @@ int config_parse_device_allow(
                 m = "rwm";
 
         if (!in_charset(m, "rwm")) {
-                log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Invalid device rights '%s'. Ignoring.", m);
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                           "Invalid device rights '%s'. Ignoring.", m);
                 return 0;
         }
 
@@ -2409,8 +2742,7 @@ int config_parse_blockio_weight(
                 void *data,
                 void *userdata) {
 
-        CGroupContext *c = data;
-        unsigned long lu;
+        unsigned long *weight = data, lu;
         int r;
 
         assert(filename);
@@ -2418,7 +2750,7 @@ int config_parse_blockio_weight(
         assert(rvalue);
 
         if (isempty(rvalue)) {
-                c->blockio_weight = 1000;
+                *weight = (unsigned long) -1;
                 return 0;
         }
 
@@ -2429,8 +2761,7 @@ int config_parse_blockio_weight(
                 return 0;
         }
 
-        c->blockio_weight = lu;
-
+        *weight = lu;
         return 0;
 }
 
@@ -2491,7 +2822,6 @@ int config_parse_blockio_device_weight(
                 return 0;
         }
 
-
         w = new0(CGroupBlockIODeviceWeight, 1);
         if (!w)
                 return log_oom();
@@ -2564,7 +2894,8 @@ int config_parse_blockio_bandwidth(
 
         r = parse_size(bandwidth, 1000, &bytes);
         if (r < 0 || bytes <= 0) {
-                log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Block IO Bandwidth '%s' invalid. Ignoring.", rvalue);
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                           "Block IO Bandwidth '%s' invalid. Ignoring.", rvalue);
                 return 0;
         }
 
@@ -2605,7 +2936,8 @@ int config_parse_job_mode_isolate(
 
         r = parse_boolean(rvalue);
         if (r < 0) {
-                log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Failed to parse boolean, ignoring: %s", rvalue);
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                           "Failed to parse boolean, ignoring: %s", rvalue);
                 return 0;
         }
 
@@ -2643,6 +2975,317 @@ int config_parse_personality(
         return 0;
 }
 
+int config_parse_runtime_directory(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        char***rt = data;
+        const char *word, *state;
+        size_t l;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        if (isempty(rvalue)) {
+                /* Empty assignment resets the list */
+                strv_free(*rt);
+                *rt = NULL;
+                return 0;
+        }
+
+        FOREACH_WORD_QUOTED(word, l, rvalue, state) {
+                _cleanup_free_ char *n;
+
+                n = strndup(word, l);
+                if (!n)
+                        return log_oom();
+
+                if (!filename_is_safe(n)) {
+                        log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                                   "Runtime directory is not valid, ignoring assignment: %s", rvalue);
+                        continue;
+                }
+
+                r = strv_push(rt, n);
+                if (r < 0)
+                        return log_oom();
+
+                n = NULL;
+        }
+        if (!isempty(state))
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                           "Trailing garbage, ignoring.");
+
+        return 0;
+}
+
+int config_parse_set_status(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        size_t l;
+        const char *word, *state;
+        int r;
+        ExitStatusSet *status_set = data;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        /* Empty assignment resets the list */
+        if (isempty(rvalue)) {
+                exit_status_set_free(status_set);
+                return 0;
+        }
+
+        FOREACH_WORD(word, l, rvalue, state) {
+                _cleanup_free_ char *temp;
+                int val;
+
+                temp = strndup(word, l);
+                if (!temp)
+                        return log_oom();
+
+                r = safe_atoi(temp, &val);
+                if (r < 0) {
+                        val = signal_from_string_try_harder(temp);
+
+                        if (val <= 0) {
+                                log_syntax(unit, LOG_ERR, filename, line, -val,
+                                           "Failed to parse value, ignoring: %s", word);
+                                return 0;
+                        }
+                } else {
+                        if (val < 0 || val > 255) {
+                                log_syntax(unit, LOG_ERR, filename, line, ERANGE,
+                                           "Value %d is outside range 0-255, ignoring", val);
+                                continue;
+                        }
+                }
+
+                r = set_ensure_allocated(&status_set->status, NULL, NULL);
+                if (r < 0)
+                        return log_oom();
+
+                r = set_put(status_set->status, INT_TO_PTR(val));
+                if (r < 0) {
+                        log_syntax(unit, LOG_ERR, filename, line, -r,
+                                   "Unable to store: %s", word);
+                        return r;
+                }
+        }
+        if (!isempty(state))
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                           "Trailing garbage, ignoring.");
+
+        return 0;
+}
+
+int config_parse_namespace_path_strv(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        char*** sv = data;
+        const char *word, *state;
+        size_t l;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        if (isempty(rvalue)) {
+                /* Empty assignment resets the list */
+                strv_free(*sv);
+                *sv = NULL;
+                return 0;
+        }
+
+        FOREACH_WORD_QUOTED(word, l, rvalue, state) {
+                _cleanup_free_ char *n;
+                int offset;
+
+                n = strndup(word, l);
+                if (!n)
+                        return log_oom();
+
+                if (!utf8_is_valid(n)) {
+                        log_invalid_utf8(unit, LOG_ERR, filename, line, EINVAL, rvalue);
+                        continue;
+                }
+
+                offset = n[0] == '-';
+                if (!path_is_absolute(n + offset)) {
+                        log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                                   "Not an absolute path, ignoring: %s", rvalue);
+                        continue;
+                }
+
+                path_kill_slashes(n);
+
+                r = strv_push(sv, n);
+                if (r < 0)
+                        return log_oom();
+
+                n = NULL;
+        }
+        if (!isempty(state))
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                           "Trailing garbage, ignoring.");
+
+        return 0;
+}
+
+int config_parse_no_new_privileges(
+                const char* unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        ExecContext *c = data;
+        int k;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        k = parse_boolean(rvalue);
+        if (k < 0) {
+                log_syntax(unit, LOG_ERR, filename, line, -k,
+                           "Failed to parse boolean value, ignoring: %s", rvalue);
+                return 0;
+        }
+
+        c->no_new_privileges = !!k;
+        c->no_new_privileges_set = true;
+
+        return 0;
+}
+
+int config_parse_protect_home(
+                const char* unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        ExecContext *c = data;
+        int k;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        /* Our enum shall be a superset of booleans, hence first try
+         * to parse as as boolean, and then as enum */
+
+        k = parse_boolean(rvalue);
+        if (k > 0)
+                c->protect_home = PROTECT_HOME_YES;
+        else if (k == 0)
+                c->protect_home = PROTECT_HOME_NO;
+        else {
+                ProtectHome h;
+
+                h = protect_home_from_string(rvalue);
+                if (h < 0){
+                        log_syntax(unit, LOG_ERR, filename, line, -h,
+                                   "Failed to parse protect home value, ignoring: %s", rvalue);
+                        return 0;
+                }
+
+                c->protect_home = h;
+        }
+
+        return 0;
+}
+
+int config_parse_protect_system(
+                const char* unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        ExecContext *c = data;
+        int k;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        /* Our enum shall be a superset of booleans, hence first try
+         * to parse as as boolean, and then as enum */
+
+        k = parse_boolean(rvalue);
+        if (k > 0)
+                c->protect_system = PROTECT_SYSTEM_YES;
+        else if (k == 0)
+                c->protect_system = PROTECT_SYSTEM_NO;
+        else {
+                ProtectSystem s;
+
+                s = protect_system_from_string(rvalue);
+                if (s < 0){
+                        log_syntax(unit, LOG_ERR, filename, line, -s,
+                                   "Failed to parse protect system value, ignoring: %s", rvalue);
+                        return 0;
+                }
+
+                c->protect_system = s;
+        }
+
+        return 0;
+}
+
 #define FOLLOW_MAX 8
 
 static int open_follow(char **filename, FILE **_f, Set *names, char **_final) {
@@ -2706,7 +3349,7 @@ static int open_follow(char **filename, FILE **_f, Set *names, char **_final) {
         f = fdopen(fd, "re");
         if (!f) {
                 r = -errno;
-                close_nointr_nofail(fd);
+                safe_close(fd);
                 return r;
         }
 
@@ -2847,9 +3490,10 @@ static int load_from_path(Unit *u, const char *path) {
                 u->load_state = UNIT_LOADED;
 
                 /* Now, parse the file contents */
-                r = config_parse(u->id, filename, f, UNIT_VTABLE(u)->sections,
-                                 config_item_perf_lookup,
-                                 (void*) load_fragment_gperf_lookup, false, true, u);
+                r = config_parse(u->id, filename, f,
+                                 UNIT_VTABLE(u)->sections,
+                                 config_item_perf_lookup, load_fragment_gperf_lookup,
+                                 false, true, false, u);
                 if (r < 0)
                         return r;
         }
@@ -2957,7 +3601,7 @@ void unit_dump_config_items(FILE *f) {
                 const ConfigParserCallback callback;
                 const char *rvalue;
         } table[] = {
-#if !defined(HAVE_SYSV_COMPAT) || !defined(HAVE_SECCOMP) || !defined(HAVE_LIBWRAP) || !defined(HAVE_PAM) || !defined(HAVE_SELINUX) || !defined(HAVE_SMACK) || !defined(HAVE_APPARMOR)
+#if !defined(HAVE_SYSV_COMPAT) || !defined(HAVE_SECCOMP) || !defined(HAVE_PAM) || !defined(HAVE_SELINUX) || !defined(HAVE_SMACK) || !defined(HAVE_APPARMOR)
                 { config_parse_warn_compat,           "NOTSUPPORTED" },
 #endif
                 { config_parse_int,                   "INTEGER" },
@@ -2981,8 +3625,8 @@ void unit_dump_config_items(FILE *f) {
                 { config_parse_unit_env_file,         "FILE" },
                 { config_parse_output,                "OUTPUT" },
                 { config_parse_input,                 "INPUT" },
-                { config_parse_facility,              "FACILITY" },
-                { config_parse_level,                 "LEVEL" },
+                { config_parse_log_facility,          "FACILITY" },
+                { config_parse_log_level,             "LEVEL" },
                 { config_parse_exec_capabilities,     "CAPABILITIES" },
                 { config_parse_exec_secure_bits,      "SECUREBITS" },
                 { config_parse_bounding_set,          "BOUNDINGSET" },
@@ -3001,7 +3645,7 @@ void unit_dump_config_items(FILE *f) {
                 { config_parse_socket_bindtodevice,   "NETWORKINTERFACE" },
                 { config_parse_sec,                   "SECONDS" },
                 { config_parse_nsec,                  "NANOSECONDS" },
-                { config_parse_path_strv,             "PATH [...]" },
+                { config_parse_namespace_path_strv,   "PATH [...]" },
                 { config_parse_unit_requires_mounts_for, "PATH [...]" },
                 { config_parse_exec_mount_flags,      "MOUNTFLAG [...]" },
                 { config_parse_unit_string_printf,    "STRING" },
@@ -3016,7 +3660,7 @@ void unit_dump_config_items(FILE *f) {
                 { config_parse_unit_slice,            "SLICE" },
                 { config_parse_documentation,         "URL" },
                 { config_parse_service_timeout,       "SECONDS" },
-                { config_parse_start_limit_action,    "ACTION" },
+                { config_parse_failure_action,        "ACTION" },
                 { config_parse_set_status,            "STATUS" },
                 { config_parse_service_sockets,       "SOCKETS" },
                 { config_parse_environ,               "ENVIRON" },
@@ -3024,6 +3668,7 @@ void unit_dump_config_items(FILE *f) {
                 { config_parse_syscall_filter,        "SYSCALLS" },
                 { config_parse_syscall_archs,         "ARCHS" },
                 { config_parse_syscall_errno,         "ERRNO" },
+                { config_parse_address_families,      "FAMILIES" },
 #endif
                 { config_parse_cpu_shares,            "SHARES" },
                 { config_parse_memory_limit,          "LIMIT" },
@@ -3039,6 +3684,7 @@ void unit_dump_config_items(FILE *f) {
 #endif
                 { config_parse_job_mode,              "MODE" },
                 { config_parse_job_mode_isolate,      "BOOLEAN" },
+                { config_parse_personality,           "PERSONALITY" },
         };
 
         const char *prev = NULL;
index 4a5ec35..4620f42 100644 (file)
@@ -34,6 +34,7 @@ int config_parse_unit_deps(const char *unit, const char *filename, unsigned line
 int config_parse_unit_string_printf(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_unit_strv_printf(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_unit_path_printf(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_unit_path_strv_printf(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_documentation(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_socket_listen(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_socket_bind(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
@@ -64,6 +65,8 @@ int config_parse_path_spec(const char *unit, const char *filename, unsigned line
 int config_parse_socket_service(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_service_sockets(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_busname_service(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_bus_policy(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_bus_policy_world(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_unit_env_file(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_ip_tos(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_unit_condition_path(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
@@ -71,7 +74,7 @@ int config_parse_unit_condition_string(const char *unit, const char *filename, u
 int config_parse_unit_condition_null(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_kill_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_notify_access(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_start_limit_action(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_failure_action(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_unit_requires_mounts_for(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_syscall_filter(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_syscall_archs(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
@@ -90,6 +93,15 @@ int config_parse_job_mode_isolate(const char *unit, const char *filename, unsign
 int config_parse_exec_selinux_context(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_personality(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_exec_apparmor_profile(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_exec_smack_process_label(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_address_families(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_runtime_directory(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_set_status(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_namespace_path_strv(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_no_new_privileges(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_cpu_quota(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_protect_home(const char* unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_protect_system(const char* unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 
 /* gperf prototypes */
 const struct ConfigPerfItem* load_fragment_gperf_lookup(const char *key, unsigned length);
index 276deb9..7a41035 100644 (file)
@@ -133,8 +133,7 @@ int locale_setup(char ***environment) {
                         goto finish;
                 }
 
-                if (strv_push(&add, s) < 0) {
-                        free(s);
+                if (strv_consume(&add, s) < 0) {
                         r = -ENOMEM;
                         goto finish;
                 }
index d0156f2..6ac1fff 100644 (file)
@@ -19,7 +19,6 @@
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
-#include <errno.h>
 #include <sys/socket.h>
 #include <net/if.h>
 #include <asm/types.h>
 #include "sd-rtnl.h"
 #include "rtnl-util.h"
 
-static int pipe_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
-        int *counter = userdata;
-        int r;
-
-        (*counter) --;
-
-        r = sd_rtnl_message_get_errno(m);
-
-        return r == -EEXIST ? 0 : r;
-}
-
-static int add_addresses(sd_rtnl *rtnl, int if_loopback, struct in_addr *ipv4_address, int *counter) {
-        _cleanup_rtnl_message_unref_ sd_rtnl_message *ipv4 = NULL, *ipv6 = NULL;
-        int r;
-
-        r = sd_rtnl_message_new_addr(rtnl, &ipv4, RTM_NEWADDR, if_loopback, AF_INET);
-        if (r < 0)
-                return r;
-
-        r = sd_rtnl_message_addr_set_prefixlen(ipv4, 8);
-        if (r < 0)
-                return r;
-
-        r = sd_rtnl_message_addr_set_flags(ipv4, IFA_F_PERMANENT);
-        if (r < 0)
-                return r;
+/* this is hardcoded in the kernel, so don't look it up */
+#define LOOPBACK_IFINDEX 1
 
-        r = sd_rtnl_message_addr_set_scope(ipv4, RT_SCOPE_HOST);
-        if (r < 0)
-                return r;
-
-        r = sd_rtnl_message_append_in_addr(ipv4, IFA_LOCAL, ipv4_address);
-        if (r < 0)
-                return r;
-
-        r = sd_rtnl_call_async(rtnl, ipv4, &pipe_handler, counter, 0, NULL);
-        if (r < 0)
-                return r;
-
-        (*counter) ++;
-
-        if (!socket_ipv6_is_supported())
-                return 0;
-
-        r = sd_rtnl_message_new_addr(rtnl, &ipv6, RTM_NEWADDR, if_loopback, AF_INET6);
-        if (r < 0)
-                return r;
-
-        r = sd_rtnl_message_addr_set_prefixlen(ipv6, 128);
-        if (r < 0)
-                return r;
-
-        r = sd_rtnl_message_addr_set_flags(ipv6, IFA_F_PERMANENT);
-        if (r < 0)
-                return r;
-
-        r = sd_rtnl_message_addr_set_scope(ipv6, RT_SCOPE_HOST);
-        if (r < 0)
-                return r;
-
-        r = sd_rtnl_message_append_in6_addr(ipv6, IFA_LOCAL, &in6addr_loopback);
-        if (r < 0)
-                return r;
-
-        r = sd_rtnl_call_async(rtnl, ipv6, &pipe_handler, counter, 0, NULL);
-        if (r < 0)
-                return r;
-
-        (*counter) ++;
-
-        return 0;
-}
-
-static int start_interface(sd_rtnl *rtnl, int if_loopback, struct in_addr *ipv4_address, int *counter) {
+static int start_loopback(sd_rtnl *rtnl) {
         _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
         int r;
 
-        r = sd_rtnl_message_new_link(rtnl, &req, RTM_SETLINK, if_loopback);
+        r = sd_rtnl_message_new_link(rtnl, &req, RTM_SETLINK, LOOPBACK_IFINDEX);
         if (r < 0)
                 return r;
 
@@ -120,12 +49,10 @@ static int start_interface(sd_rtnl *rtnl, int if_loopback, struct in_addr *ipv4_
         if (r < 0)
                 return r;
 
-        r = sd_rtnl_call_async(rtnl, req, &pipe_handler, counter, 0, NULL);
+        r = sd_rtnl_call(rtnl, req, 0, NULL);
         if (r < 0)
                 return r;
 
-        (*counter) ++;
-
         return 0;
 }
 
@@ -157,49 +84,25 @@ static int check_loopback(void) {
 
 int loopback_setup(void) {
         _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
-        int r, if_loopback, counter = 0;
-        bool eperm = false;
-        struct in_addr ipv4_address;
-
-        errno = 0;
-        if_loopback = (int) if_nametoindex("lo");
-        if (if_loopback <= 0)
-                return errno ? -errno : -ENODEV;
-
-        ipv4_address.s_addr = htonl(INADDR_LOOPBACK);
+        int r;
 
         r = sd_rtnl_open(&rtnl, 0);
         if (r < 0)
                 return r;
 
-        r = add_addresses(rtnl, if_loopback, &ipv4_address, &counter);
-        if (r < 0)
-                return r;
-
-        r = start_interface(rtnl, if_loopback, &ipv4_address, &counter);
-        if (r < 0)
-                return r;
-
-        while (counter > 0) {
-                r = sd_rtnl_wait(rtnl, 0);
-                if (r < 0)
-                        return r;
-
-                r = sd_rtnl_process(rtnl, 0);
-                if (r < 0) {
-                        if (r == -EPERM)
-                                eperm = true;
-                        else {
-                                log_warning("Failed to configure loopback device: %s", strerror(-r));
-                                return r;
-                        }
+        r = start_loopback(rtnl);
+        if (r == -EPERM) {
+                if (check_loopback() < 0) {
+                        log_warning("Failed to configure loopback device: %s",
+                                    strerror(EPERM));
+                        return -EPERM;
                 }
+        } else if (r < 0) {
+                log_warning("Failed to configure loopback device: %s",
+                            strerror(-r));
+                return r;
         }
 
-        if (eperm && check_loopback() < 0) {
-                log_warning("Failed to configure loopback device: %s", strerror(EPERM));
-                return -EPERM;
-        }
 
         return 0;
 }
index 1b55da7..712f60c 100644 (file)
@@ -27,7 +27,7 @@
 #include <fcntl.h>
 #include <sys/mount.h>
 
-#include <systemd/sd-id128.h>
+#include "systemd/sd-id128.h"
 
 #include "machine-id-setup.h"
 #include "macro.h"
@@ -36,8 +36,9 @@
 #include "log.h"
 #include "virt.h"
 #include "fileio.h"
+#include "path-util.h"
 
-static int shorten_uuid(char destination[36], const char *source) {
+static int shorten_uuid(char destination[34], const char source[36]) {
         unsigned i, j;
 
         for (i = 0, j = 0; i < 36 && j < 32; i++) {
@@ -59,21 +60,25 @@ static int shorten_uuid(char destination[36], const char *source) {
         return -EINVAL;
 }
 
-static int generate(char id[34]) {
+static int generate(char id[34], const char *root) {
         int fd, r;
         unsigned char *p;
         sd_id128_t buf;
         char *q;
         ssize_t k;
         const char *vm_id;
+        _cleanup_free_ char *dbus_machine_id = NULL;
 
         assert(id);
 
+        if (asprintf(&dbus_machine_id, "%s/var/lib/dbus/machine-id", root) < 0)
+                return log_oom();
+
         /* First, try reading the D-Bus machine id, unless it is a symlink */
-        fd = open("/var/lib/dbus/machine-id", O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
+        fd = open(dbus_machine_id, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
         if (fd >= 0) {
                 k = loop_read(fd, id, 33, false);
-                close_nointr_nofail(fd);
+                safe_close(fd);
 
                 if (k == 33 && id[32] == '\n') {
 
@@ -88,32 +93,9 @@ static int generate(char id[34]) {
                 }
         }
 
-        /* If that didn't work, see if we are running in qemu/kvm and a
-         * machine ID was passed in via -uuid on the qemu/kvm command
-         * line */
-
-        r = detect_vm(&vm_id);
-        if (r > 0 && streq(vm_id, "kvm")) {
-                char uuid[37];
-
-                fd = open("/sys/class/dmi/id/product_uuid", O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
-                if (fd >= 0) {
-                        k = loop_read(fd, uuid, 36, false);
-                        close_nointr_nofail(fd);
-
-                        if (k >= 36) {
-                                r = shorten_uuid(id, uuid);
-                                if (r >= 0) {
-                                        log_info("Initializing machine ID from KVM UUID.");
-                                        return 0;
-                                }
-                        }
-                }
-        }
-
-        /* If that didn't work either, see if we are running in a
-         * container, and a machine ID was passed in via
-         * $container_uuid the way libvirt/LXC does it */
+        /* If that didn't work, see if we are running in a container,
+         * and a machine ID was passed in via $container_uuid the way
+         * libvirt/LXC does it */
         r = detect_container(NULL);
         if (r > 0) {
                 _cleanup_free_ char *e = NULL;
@@ -128,6 +110,30 @@ static int generate(char id[34]) {
                                 }
                         }
                 }
+
+        } else {
+                /* If we are not running in a container, see if we are
+                 * running in qemu/kvm and a machine ID was passed in
+                 * via -uuid on the qemu/kvm command line */
+
+                r = detect_vm(&vm_id);
+                if (r > 0 && streq(vm_id, "kvm")) {
+                        char uuid[37];
+
+                        fd = open("/sys/class/dmi/id/product_uuid", O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
+                        if (fd >= 0) {
+                                k = loop_read(fd, uuid, 36, false);
+                                safe_close(fd);
+
+                                if (k >= 36) {
+                                        r = shorten_uuid(id, uuid);
+                                        if (r >= 0) {
+                                                log_info("Initializing machine ID from KVM UUID.");
+                                                return 0;
+                                        }
+                                }
+                        }
+                }
         }
 
         /* If that didn't work, generate a random machine id */
@@ -150,12 +156,24 @@ static int generate(char id[34]) {
         return 0;
 }
 
-int machine_id_setup(void) {
+int machine_id_setup(const char *root) {
+        const char *etc_machine_id, *run_machine_id;
         _cleanup_close_ int fd = -1;
-        int r;
         bool writable = false;
         struct stat st;
         char id[34]; /* 32 + \n + \0 */
+        int r;
+
+        if (isempty(root))  {
+                etc_machine_id = "/etc/machine-id";
+                run_machine_id = "/run/machine-id";
+        } else {
+                etc_machine_id = strappenda(root, "/etc/machine-id");
+                path_kill_slashes((char*) etc_machine_id);
+
+                run_machine_id = strappenda(root, "/run/machine-id");
+                path_kill_slashes((char*) run_machine_id);
+        }
 
         RUN_WITH_UMASK(0000) {
                 /* We create this 0444, to indicate that this isn't really
@@ -163,13 +181,14 @@ int machine_id_setup(void) {
                  * will be owned by root it doesn't matter much, but maybe
                  * people look. */
 
-                fd = open("/etc/machine-id", O_RDWR|O_CREAT|O_CLOEXEC|O_NOCTTY, 0444);
+                mkdir_parents(etc_machine_id, 0755);
+                fd = open(etc_machine_id, O_RDWR|O_CREAT|O_CLOEXEC|O_NOCTTY, 0444);
                 if (fd >= 0)
                         writable = true;
                 else {
-                        fd = open("/etc/machine-id", O_RDONLY|O_CLOEXEC|O_NOCTTY);
+                        fd = open(etc_machine_id, O_RDONLY|O_CLOEXEC|O_NOCTTY);
                         if (fd < 0) {
-                                log_error("Cannot open /etc/machine-id: %m");
+                                log_error("Cannot open %s: %m", etc_machine_id);
                                 return -errno;
                         }
 
@@ -193,7 +212,7 @@ int machine_id_setup(void) {
         /* Hmm, so, the id currently stored is not useful, then let's
          * generate one */
 
-        r = generate(id);
+        r = generate(id, root);
         if (r < 0)
                 return r;
 
@@ -204,34 +223,33 @@ int machine_id_setup(void) {
                         return 0;
         }
 
-        close_nointr_nofail(fd);
-        fd = -1;
+        fd = safe_close(fd);
 
         /* Hmm, we couldn't write it? So let's write it to
          * /run/machine-id as a replacement */
 
         RUN_WITH_UMASK(0022) {
-                r = write_string_file("/run/machine-id", id);
+                r = write_string_file(run_machine_id, id);
         }
         if (r < 0) {
-                log_error("Cannot write /run/machine-id: %s", strerror(-r));
-                unlink("/run/machine-id");
+                log_error("Cannot write %s: %s", run_machine_id, strerror(-r));
+                unlink(run_machine_id);
                 return r;
         }
 
         /* And now, let's mount it over */
-        r = mount("/run/machine-id", "/etc/machine-id", NULL, MS_BIND, NULL);
+        r = mount(run_machine_id, etc_machine_id, NULL, MS_BIND, NULL);
         if (r < 0) {
-                log_error("Failed to mount /etc/machine-id: %m");
-                unlink_noerrno("/run/machine-id");
+                log_error("Failed to mount %s: %m", etc_machine_id);
+                unlink_noerrno(run_machine_id);
                 return -errno;
         }
 
-        log_info("Installed transient /etc/machine-id file.");
+        log_info("Installed transient %s file.", etc_machine_id);
 
         /* Mark the mount read-only */
-        if (mount(NULL, "/etc/machine-id", NULL, MS_BIND|MS_RDONLY|MS_REMOUNT, NULL) < 0)
-                log_warning("Failed to make transient /etc/machine-id read-only: %m");
+        if (mount(NULL, etc_machine_id, NULL, MS_BIND|MS_RDONLY|MS_REMOUNT, NULL) < 0)
+                log_warning("Failed to make transient %s read-only: %m", etc_machine_id);
 
         return 0;
 }
index b9e6b4d..b0583ee 100644 (file)
@@ -21,4 +21,4 @@
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
-int machine_id_setup(void);
+int machine_id_setup(const char *root);
index 89b4825..333f222 100644 (file)
@@ -26,7 +26,9 @@
 %_udevrulesdir @udevrulesdir@
 %_journalcatalogdir @catalogdir@
 %_tmpfilesdir @tmpfilesdir@
+%_sysusersdir @sysusersdir@
 %_sysctldir @sysctldir@
+%_binfmtdir @binfmtdir@
 
 %systemd_requires \
 Requires(post): systemd \
@@ -37,42 +39,58 @@ Requires(postun): systemd \
 %systemd_post() \
 if [ $1 -eq 1 ] ; then \
         # Initial installation \
-        @rootbindir@/systemctl preset %{?*} >/dev/null 2>&1 || : \
+        systemctl preset %{?*} >/dev/null 2>&1 || : \
 fi \
 %{nil}
 
 %systemd_preun() \
 if [ $1 -eq 0 ] ; then \
         # Package removal, not upgrade \
-        @rootbindir@/systemctl --no-reload disable %{?*} > /dev/null 2>&1 || : \
-        @rootbindir@/systemctl stop %{?*} > /dev/null 2>&1 || : \
+        systemctl --no-reload disable %{?*} > /dev/null 2>&1 || : \
+        systemctl stop %{?*} > /dev/null 2>&1 || : \
 fi \
 %{nil}
 
 %systemd_postun() \
-@rootbindir@/systemctl daemon-reload >/dev/null 2>&1 || : \
+systemctl daemon-reload >/dev/null 2>&1 || : \
 %{nil}
 
 %systemd_postun_with_restart() \
-@rootbindir@/systemctl daemon-reload >/dev/null 2>&1 || : \
+systemctl daemon-reload >/dev/null 2>&1 || : \
 if [ $1 -ge 1 ] ; then \
         # Package upgrade, not uninstall \
-        @rootbindir@/systemctl try-restart %{?*} >/dev/null 2>&1 || : \
+        systemctl try-restart %{?*} >/dev/null 2>&1 || : \
 fi \
 %{nil}
 
 %udev_hwdb_update() \
-@rootbindir@/udevadm hwdb --update >/dev/null 2>&1 || : \
+udevadm hwdb --update >/dev/null 2>&1 || : \
 %{nil}
 
 %udev_rules_update() \
-@rootbindir@/udevadm control --reload >/dev/null 2>&1 || : \
+udevadm control --reload >/dev/null 2>&1 || : \
 %{nil}
 
 %journal_catalog_update() \
-@rootbindir@/journalctl --update-catalog >/dev/null 2>&1 || : \
+journalctl --update-catalog >/dev/null 2>&1 || : \
 %{nil}
 
 %tmpfiles_create() \
-@rootbindir@/systemd-tmpfiles --create %{?*} >/dev/null 2>&1 || : \
+systemd-tmpfiles --create %{?*} >/dev/null 2>&1 || : \
+%{nil}
+
+%sysusers_create() \
+systemd-sysusers %{?*} >/dev/null 2>&1 || : \
+%{nil}
+
+%sysusers_create_inline() \
+echo %{?*} | systemd-sysusers - >/dev/null 2>&1 || : \
+%{nil}
+
+%sysctl_apply() \
+@rootlibexecdir@/systemd-sysctl %{?*} >/dev/null 2>&1 || : \
+%{nil}
+
+%binfmt_apply() \
+@rootlibexecdir@/systemd-binfmt %{?*} >/dev/null 2>&1 || : \
 %{nil}
index f468481..eab1f63 100644 (file)
@@ -35,6 +35,9 @@
 #ifdef HAVE_VALGRIND_VALGRIND_H
 #include <valgrind/valgrind.h>
 #endif
+#ifdef HAVE_SECCOMP
+#include <seccomp.h>
+#endif
 
 #include "sd-daemon.h"
 #include "sd-messages.h"
@@ -47,6 +50,7 @@
 #include "conf-parser.h"
 #include "missing.h"
 #include "label.h"
+#include "pager.h"
 #include "build.h"
 #include "strv.h"
 #include "def.h"
@@ -58,7 +62,7 @@
 #include "capability.h"
 #include "killall.h"
 #include "env-util.h"
-#include "hwclock.h"
+#include "clock-util.h"
 #include "fileio.h"
 #include "dbus-manager.h"
 #include "bus-error.h"
@@ -91,6 +95,7 @@ static int arg_crash_chvt = -1;
 static bool arg_confirm_spawn = false;
 static ShowStatus arg_show_status = _SHOW_STATUS_UNSET;
 static bool arg_switched_root = false;
+static int arg_no_pager = -1;
 static char ***arg_join_controllers = NULL;
 static ExecOutput arg_default_std_output = EXEC_OUTPUT_JOURNAL;
 static ExecOutput arg_default_std_error = EXEC_OUTPUT_INHERIT;
@@ -105,14 +110,26 @@ static char **arg_default_environment = NULL;
 #ifdef CONFIG_TIZEN
 static char **arg_default_extra_dependencies = NULL;
 #endif
-static struct rlimit *arg_default_rlimit[RLIMIT_NLIMITS] = {};
+static struct rlimit *arg_default_rlimit[_RLIMIT_MAX] = {};
 static uint64_t arg_capability_bounding_set_drop = 0;
-static nsec_t arg_timer_slack_nsec = (nsec_t) -1;
+static nsec_t arg_timer_slack_nsec = NSEC_INFINITY;
+static usec_t arg_default_timer_accuracy_usec = 1 * USEC_PER_MINUTE;
 static Set* arg_syscall_archs = NULL;
 static FILE* arg_serialization = NULL;
+static bool arg_default_cpu_accounting = false;
+static bool arg_default_blockio_accounting = false;
+static bool arg_default_memory_accounting = false;
 
 static void nop_handler(int sig) {}
 
+static void pager_open_if_enabled(void) {
+
+        if (arg_no_pager <= 0)
+                return;
+
+        pager_open(false);
+}
+
 noreturn static void crash(int sig) {
 
         if (getpid() != 1)
@@ -214,31 +231,25 @@ static void install_crash_handler(void) {
         sigaction_many(&sa, SIGNALS_CRASH_HANDLER, -1);
 }
 
-static int console_setup(bool do_reset) {
-        int tty_fd, r;
-
-        /* If we are init, we connect stdin/stdout/stderr to /dev/null
-         * and make sure we don't have a controlling tty. */
-
-        release_terminal();
-
-        if (!do_reset)
-                return 0;
+static int console_setup(void) {
+        _cleanup_close_ int tty_fd = -1;
+        int r;
 
         tty_fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
         if (tty_fd < 0) {
                 log_error("Failed to open /dev/console: %s", strerror(-tty_fd));
-                return -tty_fd;
+                return tty_fd;
         }
 
-        /* We don't want to force text mode.
-         * plymouth may be showing pictures already from initrd. */
+        /* We don't want to force text mode.  plymouth may be showing
+         * pictures already from initrd. */
         r = reset_terminal_fd(tty_fd, false);
-        if (r < 0)
+        if (r < 0) {
                 log_error("Failed to reset /dev/console: %s", strerror(-r));
+                return r;
+        }
 
-        close_nointr_nofail(tty_fd);
-        return r;
+        return 0;
 }
 
 static int set_default_unit(const char *u) {
@@ -256,7 +267,7 @@ static int set_default_unit(const char *u) {
         return 0;
 }
 
-static int parse_proc_cmdline_word(const char *word) {
+static int parse_proc_cmdline_item(const char *key, const char *value) {
 
         static const char * const rlmap[] = {
                 "emergency", SPECIAL_EMERGENCY_TARGET,
@@ -271,162 +282,107 @@ static int parse_proc_cmdline_word(const char *word) {
                 "4",         SPECIAL_RUNLEVEL4_TARGET,
                 "5",         SPECIAL_RUNLEVEL5_TARGET,
         };
+        int r;
 
-        assert(word);
+        assert(key);
 
-        if (startswith(word, "systemd.unit=")) {
+        if (streq(key, "systemd.unit") && value) {
 
                 if (!in_initrd())
-                        return set_default_unit(word + 13);
+                        return set_default_unit(value);
 
-        } else if (startswith(word, "rd.systemd.unit=")) {
+        } else if (streq(key, "rd.systemd.unit") && value) {
 
                 if (in_initrd())
-                        return set_default_unit(word + 16);
-
-        } else if (startswith(word, "systemd.log_target=")) {
-
-                if (log_set_target_from_string(word + 19) < 0)
-                        log_warning("Failed to parse log target %s. Ignoring.", word + 19);
-
-        } else if (startswith(word, "systemd.log_level=")) {
-
-                if (log_set_max_level_from_string(word + 18) < 0)
-                        log_warning("Failed to parse log level %s. Ignoring.", word + 18);
-
-        } else if (startswith(word, "systemd.log_color=")) {
+                        return set_default_unit(value);
 
-                if (log_show_color_from_string(word + 18) < 0)
-                        log_warning("Failed to parse log color setting %s. Ignoring.", word + 18);
+        } else if (streq(key, "systemd.dump_core") && value) {
 
-        } else if (startswith(word, "systemd.log_location=")) {
-
-                if (log_show_location_from_string(word + 21) < 0)
-                        log_warning("Failed to parse log location setting %s. Ignoring.", word + 21);
-
-        } else if (startswith(word, "systemd.dump_core=")) {
-                int r;
-
-                r = parse_boolean(word + 18);
+                r = parse_boolean(value);
                 if (r < 0)
-                        log_warning("Failed to parse dump core switch %s. Ignoring.", word + 18);
+                        log_warning("Failed to parse dump core switch %s. Ignoring.", value);
                 else
                         arg_dump_core = r;
 
-        } else if (startswith(word, "systemd.crash_shell=")) {
-                int r;
+        } else if (streq(key, "systemd.crash_shell") && value) {
 
-                r = parse_boolean(word + 20);
+                r = parse_boolean(value);
                 if (r < 0)
-                        log_warning("Failed to parse crash shell switch %s. Ignoring.", word + 20);
+                        log_warning("Failed to parse crash shell switch %s. Ignoring.", value);
                 else
                         arg_crash_shell = r;
 
-        } else if (startswith(word, "systemd.confirm_spawn=")) {
-                int r;
+        } else if (streq(key, "systemd.crash_chvt") && value) {
 
-                r = parse_boolean(word + 22);
-                if (r < 0)
-                        log_warning("Failed to parse confirm spawn switch %s. Ignoring.", word + 22);
+                if (safe_atoi(value, &r) < 0)
+                        log_warning("Failed to parse crash chvt switch %s. Ignoring.", value);
                 else
-                        arg_confirm_spawn = r;
+                        arg_crash_chvt = r;
 
-        } else if (startswith(word, "systemd.crash_chvt=")) {
-                int k;
+        } else if (streq(key, "systemd.confirm_spawn") && value) {
 
-                if (safe_atoi(word + 19, &k) < 0)
-                        log_warning("Failed to parse crash chvt switch %s. Ignoring.", word + 19);
+                r = parse_boolean(value);
+                if (r < 0)
+                        log_warning("Failed to parse confirm spawn switch %s. Ignoring.", value);
                 else
-                        arg_crash_chvt = k;
+                        arg_confirm_spawn = r;
 
-        } else if (startswith(word, "systemd.show_status=")) {
-                int r;
+        } else if (streq(key, "systemd.show_status") && value) {
 
-                r = parse_show_status(word + 20, &arg_show_status);
+                r = parse_show_status(value, &arg_show_status);
                 if (r < 0)
-                        log_warning("Failed to parse show status switch %s. Ignoring.", word + 20);
-        } else if (startswith(word, "systemd.default_standard_output=")) {
-                int r;
+                        log_warning("Failed to parse show status switch %s. Ignoring.", value);
 
-                r = exec_output_from_string(word + 32);
+        } else if (streq(key, "systemd.default_standard_output") && value) {
+
+                r = exec_output_from_string(value);
                 if (r < 0)
-                        log_warning("Failed to parse default standard output switch %s. Ignoring.", word + 32);
+                        log_warning("Failed to parse default standard output switch %s. Ignoring.", value);
                 else
                         arg_default_std_output = r;
-        } else if (startswith(word, "systemd.default_standard_error=")) {
-                int r;
 
-                r = exec_output_from_string(word + 31);
+        } else if (streq(key, "systemd.default_standard_error") && value) {
+
+                r = exec_output_from_string(value);
                 if (r < 0)
-                        log_warning("Failed to parse default standard error switch %s. Ignoring.", word + 31);
+                        log_warning("Failed to parse default standard error switch %s. Ignoring.", value);
                 else
                         arg_default_std_error = r;
-        } else if (startswith(word, "systemd.setenv=")) {
-                const char *cenv = word + 15;
 
-                if (env_assignment_is_valid(cenv)) {
+        } else if (streq(key, "systemd.setenv") && value) {
+
+                if (env_assignment_is_valid(value)) {
                         char **env;
 
-                        env = strv_env_set(arg_default_environment, cenv);
+                        env = strv_env_set(arg_default_environment, value);
                         if (env)
                                 arg_default_environment = env;
                         else
-                                log_warning("Setting environment variable '%s' failed, ignoring: %s",
-                                            cenv, strerror(ENOMEM));
+                                log_warning("Setting environment variable '%s' failed, ignoring: %s", value, strerror(ENOMEM));
                 } else
-                        log_warning("Environment variable name '%s' is not valid. Ignoring.", cenv);
-
-        } else if (startswith(word, "systemd.") ||
-                   (in_initrd() && startswith(word, "rd.systemd."))) {
-
-                const char *c;
-
-                /* Ignore systemd.journald.xyz and friends */
-                c = word;
-                if (startswith(c, "rd."))
-                        c += 3;
-                if (startswith(c, "systemd."))
-                        c += 8;
-                if (c[strcspn(c, ".=")] != '.')  {
-
-                        log_warning("Unknown kernel switch %s. Ignoring.", word);
-
-                        log_info("Supported kernel switches:\n"
-                                 "systemd.unit=UNIT                        Default unit to start\n"
-                                 "rd.systemd.unit=UNIT                     Default unit to start when run in initrd\n"
-                                 "systemd.dump_core=0|1                    Dump core on crash\n"
-                                 "systemd.crash_shell=0|1                  Run shell on crash\n"
-                                 "systemd.crash_chvt=N                     Change to VT #N on crash\n"
-                                 "systemd.confirm_spawn=0|1                Confirm every process spawn\n"
-                                 "systemd.show_status=0|1|auto             Show status updates on the console during bootup\n"
-                                 "systemd.log_target=console|kmsg|journal|journal-or-kmsg|syslog|syslog-or-kmsg|null\n"
-                                 "                                         Log target\n"
-                                 "systemd.log_level=LEVEL                  Log level\n"
-                                 "systemd.log_color=0|1                    Highlight important log messages\n"
-                                 "systemd.log_location=0|1                 Include code location in log messages\n"
-                                 "systemd.default_standard_output=null|tty|syslog|syslog+console|kmsg|kmsg+console|journal|journal+console\n"
-                                 "                                         Set default log output for services\n"
-                                 "systemd.default_standard_error=null|tty|syslog|syslog+console|kmsg|kmsg+console|journal|journal+console\n"
-                                 "                                         Set default log error output for services\n"
-                                 "systemd.setenv=ASSIGNMENT                Set an environment variable for all spawned processes\n");
-                }
+                        log_warning("Environment variable name '%s' is not valid. Ignoring.", value);
+
+        } else if (streq(key, "quiet") && !value) {
+
+                log_set_max_level(LOG_NOTICE);
 
-        } else if (streq(word, "quiet")) {
                 if (arg_show_status == _SHOW_STATUS_UNSET)
                         arg_show_status = SHOW_STATUS_AUTO;
-        } else if (streq(word, "debug")) {
-                /* Log to kmsg, the journal socket will fill up before the
-                 * journal is started and tools running during that time
-                 * will block with every log message for for 60 seconds,
-                 * before they give up. */
-                log_set_max_level(LOG_DEBUG);
-                log_set_target(detect_container(NULL) > 0 ? LOG_TARGET_CONSOLE : LOG_TARGET_KMSG);
-        } else if (!in_initrd()) {
+
+        } else if (streq(key, "debug") && !value) {
+
+                /* Note that log_parse_environment() handles 'debug'
+                 * too, and sets the log level to LOG_DEBUG. */
+
+                if (detect_container(NULL) > 0)
+                        log_set_target(LOG_TARGET_CONSOLE);
+
+        } else if (!in_initrd() && !value) {
                 unsigned i;
 
                 /* SysV compatibility */
                 for (i = 0; i < ELEMENTSOF(rlmap); i += 2)
-                        if (streq(word, rlmap[i]))
+                        if (streq(key, rlmap[i]))
                                 return set_default_unit(rlmap[i+1]);
         }
 
@@ -465,20 +421,20 @@ DEFINE_SETTER(config_parse_target, log_set_target_from_string, "target")
 DEFINE_SETTER(config_parse_color, log_show_color_from_string, "color" )
 DEFINE_SETTER(config_parse_location, log_show_location_from_string, "location")
 
-static int config_parse_cpu_affinity2(const char *unit,
-                                      const char *filename,
-                                      unsigned line,
-                                      const char *section,
-                                      unsigned section_line,
-                                      const char *lvalue,
-                                      int ltype,
-                                      const char *rvalue,
-                                      void *data,
-                                      void *userdata) {
-
-        char *w;
+static int config_parse_cpu_affinity2(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        const char *word, *state;
         size_t l;
-        char *state;
         cpu_set_t *c = NULL;
         unsigned ncpus = 0;
 
@@ -486,12 +442,12 @@ static int config_parse_cpu_affinity2(const char *unit,
         assert(lvalue);
         assert(rvalue);
 
-        FOREACH_WORD_QUOTED(w, l, rvalue, state) {
+        FOREACH_WORD_QUOTED(word, l, rvalue, state) {
                 char *t;
                 int r;
                 unsigned cpu;
 
-                if (!(t = strndup(w, l)))
+                if (!(t = strndup(word, l)))
                         return log_oom();
 
                 r = safe_atou(t, &cpu);
@@ -510,6 +466,9 @@ static int config_parse_cpu_affinity2(const char *unit,
 
                 CPU_SET_S(cpu, CPU_ALLOC_SIZE(ncpus), c);
         }
+        if (!isempty(state))
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                           "Trailing garbage, ignoring.");
 
         if (c) {
                 if (sched_setaffinity(0, CPU_ALLOC_SIZE(ncpus), c) < 0)
@@ -521,6 +480,36 @@ static int config_parse_cpu_affinity2(const char *unit,
         return 0;
 }
 
+static int config_parse_show_status(
+                const char* unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        int k;
+        ShowStatus *b = data;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        k = parse_show_status(rvalue, b);
+        if (k < 0) {
+                log_syntax(unit, LOG_ERR, filename, line, -k,
+                           "Failed to parse show status setting, ignoring: %s", rvalue);
+                return 0;
+        }
+
+        return 0;
+}
+
 static void strv_free_free(char ***l) {
         char ***i;
 
@@ -550,7 +539,7 @@ static int config_parse_join_controllers(const char *unit,
                                          void *userdata) {
 
         unsigned n = 0;
-        char *state, *w;
+        const char *word, *state;
         size_t length;
 
         assert(filename);
@@ -559,10 +548,10 @@ static int config_parse_join_controllers(const char *unit,
 
         free_join_controllers();
 
-        FOREACH_WORD_QUOTED(w, length, rvalue, state) {
+        FOREACH_WORD_QUOTED(word, length, rvalue, state) {
                 char *s, **l;
 
-                s = strndup(w, length);
+                s = strndup(word, length);
                 if (!s)
                         return log_oom();
 
@@ -628,6 +617,9 @@ static int config_parse_join_controllers(const char *unit,
                         arg_join_controllers = t;
                 }
         }
+        if (!isempty(state))
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                           "Trailing garbage, ignoring.");
 
         return 0;
 }
@@ -652,6 +644,7 @@ static int parse_config_file(void) {
                 { "Manager", "SystemCallArchitectures",   config_parse_syscall_archs,    0, &arg_syscall_archs                     },
 #endif
                 { "Manager", "TimerSlackNSec",            config_parse_nsec,             0, &arg_timer_slack_nsec                  },
+                { "Manager", "DefaultTimerAccuracySec",   config_parse_sec,              0, &arg_default_timer_accuracy_usec       },
                 { "Manager", "DefaultStandardOutput",     config_parse_output,           0, &arg_default_std_output                },
                 { "Manager", "DefaultStandardError",      config_parse_output,           0, &arg_default_std_error                 },
                 { "Manager", "DefaultTimeoutStartSec",    config_parse_sec,              0, &arg_default_timeout_start_usec        },
@@ -679,26 +672,19 @@ static int parse_config_file(void) {
                 { "Manager", "DefaultLimitNICE",          config_parse_limit,            0, &arg_default_rlimit[RLIMIT_NICE]       },
                 { "Manager", "DefaultLimitRTPRIO",        config_parse_limit,            0, &arg_default_rlimit[RLIMIT_RTPRIO]     },
                 { "Manager", "DefaultLimitRTTIME",        config_parse_limit,            0, &arg_default_rlimit[RLIMIT_RTTIME]     },
+                { "Manager", "DefaultCPUAccounting",      config_parse_bool,             0, &arg_default_cpu_accounting            },
+                { "Manager", "DefaultBlockIOAccounting",  config_parse_bool,             0, &arg_default_blockio_accounting        },
+                { "Manager", "DefaultMemoryAccounting",   config_parse_bool,             0, &arg_default_memory_accounting         },
                 {}
         };
 
-        _cleanup_fclose_ FILE *f;
         const char *fn;
-        int r;
 
         fn = arg_running_as == SYSTEMD_SYSTEM ? PKGSYSCONFDIR "/system.conf" : PKGSYSCONFDIR "/user.conf";
-        f = fopen(fn, "re");
-        if (!f) {
-                if (errno == ENOENT)
-                        return 0;
-
-                log_warning("Failed to open configuration file '%s': %m", fn);
-                return 0;
-        }
-
-        r = config_parse(NULL, fn, f, "Manager\0", config_item_table_lookup, (void*) items, false, false, NULL);
-        if (r < 0)
-                log_warning("Failed to parse configuration file: %s", strerror(-r));
+        config_parse(NULL, fn, NULL,
+                     "Manager\0",
+                     config_item_table_lookup, items,
+                     false, false, true, NULL);
 
         return 0;
 }
@@ -714,6 +700,7 @@ static int parse_argv(int argc, char *argv[]) {
                 ARG_SYSTEM,
                 ARG_USER,
                 ARG_TEST,
+                ARG_NO_PAGER,
                 ARG_VERSION,
                 ARG_DUMP_CONFIGURATION_ITEMS,
                 ARG_DUMP_CORE,
@@ -735,6 +722,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "system",                   no_argument,       NULL, ARG_SYSTEM                   },
                 { "user",                     no_argument,       NULL, ARG_USER                     },
                 { "test",                     no_argument,       NULL, ARG_TEST                     },
+                { "no-pager",                 no_argument,       NULL, ARG_NO_PAGER                 },
                 { "help",                     no_argument,       NULL, 'h'                          },
                 { "version",                  no_argument,       NULL, ARG_VERSION                  },
                 { "dump-configuration-items", no_argument,       NULL, ARG_DUMP_CONFIGURATION_ITEMS },
@@ -842,6 +830,12 @@ static int parse_argv(int argc, char *argv[]) {
 
                 case ARG_TEST:
                         arg_action = ACTION_TEST;
+                        if (arg_no_pager < 0)
+                                arg_no_pager = true;
+                        break;
+
+                case ARG_NO_PAGER:
+                        arg_no_pager = true;
                         break;
 
                 case ARG_VERSION:
@@ -922,6 +916,8 @@ static int parse_argv(int argc, char *argv[]) {
 
                 case 'h':
                         arg_action = ACTION_HELP;
+                        if (arg_no_pager < 0)
+                                arg_no_pager = true;
                         break;
 
                 case 'D':
@@ -937,13 +933,13 @@ static int parse_argv(int argc, char *argv[]) {
                          * parse_proc_cmdline_word() or ignore. */
 
                 case '?':
-                default:
-                        if (getpid() != 1) {
-                                log_error("Unknown option code %c", c);
+                        if (getpid() != 1)
                                 return -EINVAL;
-                        }
+                        else
+                                return 0;
 
-                        break;
+                default:
+                        assert_not_reached("Unhandled option code.");
                 }
 
         if (optind < argc && getpid() != 1) {
@@ -954,26 +950,6 @@ static int parse_argv(int argc, char *argv[]) {
                 return -EINVAL;
         }
 
-        if (detect_container(NULL) > 0) {
-                char **a;
-
-                /* All /proc/cmdline arguments the kernel didn't
-                 * understand it passed to us. We're not really
-                 * interested in that usually since /proc/cmdline is
-                 * more interesting and complete. With one exception:
-                 * if we are run in a container /proc/cmdline is not
-                 * relevant for the container, hence we rely on argv[]
-                 * instead. */
-
-                for (a = argv; a < argv + argc; a++) {
-                        r = parse_proc_cmdline_word(*a);
-                        if (r < 0) {
-                                log_error("Failed on cmdline argument %s: %s", *a, strerror(-r));
-                                return r;
-                        }
-                }
-        }
-
         return 0;
 }
 
@@ -983,6 +959,7 @@ static int help(void) {
                "Starts up and maintains the system or user services.\n\n"
                "  -h --help                      Show this help\n"
                "     --test                      Determine startup sequence, dump it and exit\n"
+               "     --no-pager                  Do not pipe output into a pager\n"
                "     --dump-configuration-items  Dump understood unit configuration items\n"
                "     --unit=UNIT                 Set default unit\n"
                "     --system                    Run a system instance, even if PID != 1\n"
@@ -991,7 +968,7 @@ static int help(void) {
                "     --crash-shell[=0|1]         Run shell on crash\n"
                "     --confirm-spawn[=0|1]       Ask for confirmation when spawning processes\n"
                "     --show-status[=0|1]         Show status updates on the console during bootup\n"
-               "     --log-target=TARGET         Set log target (console, journal, syslog, kmsg, journal-or-kmsg, syslog-or-kmsg, null)\n"
+               "     --log-target=TARGET         Set log target (console, journal, kmsg, journal-or-kmsg, null)\n"
                "     --log-level=LEVEL           Set log level (debug, info, notice, warning, err, crit, alert, emerg)\n"
                "     --log-color[=0|1]           Highlight important log messages\n"
                "     --log-location[=0|1]        Include code location in log messages\n"
@@ -1109,19 +1086,25 @@ static int bump_rlimit_nofile(struct rlimit *saved_rlimit) {
 }
 
 static void test_mtab(void) {
-        char *p;
 
-        /* Check that /etc/mtab is a symlink */
+        static const char ok[] =
+                "/proc/self/mounts\0"
+                "/proc/mounts\0"
+                "../proc/self/mounts\0"
+                "../proc/mounts\0";
 
-        if (readlink_malloc("/etc/mtab", &p) >= 0) {
-                bool b;
+        _cleanup_free_ char *p = NULL;
+        int r;
 
-                b = streq(p, "/proc/self/mounts") || streq(p, "/proc/mounts");
-                free(p);
+        /* Check that /etc/mtab is a symlink to the right place or
+         * non-existing. But certainly not a file, or a symlink to
+         * some weird place... */
 
-                if (b)
-                        return;
-        }
+        r = readlink_malloc("/etc/mtab", &p);
+        if (r == -ENOENT)
+                return;
+        if (r >= 0 && nulstr_contains(ok, p))
+                return;
 
         log_warning("/etc/mtab is not a symlink or not pointing to /proc/self/mounts. "
                     "This is not supported anymore. "
@@ -1140,21 +1123,6 @@ static void test_usr(void) {
                     "Consult http://freedesktop.org/wiki/Software/systemd/separate-usr-is-broken for more information.");
 }
 
-static void test_cgroups(void) {
-
-        if (access("/proc/cgroups", F_OK) >= 0)
-                return;
-
-        log_warning("CONFIG_CGROUPS was not set when your kernel was compiled. "
-                    "Systems without control groups are not supported. "
-                    "We will now sleep for 10s, and then continue boot-up. "
-                    "Expect breakage and please do not file bugs. "
-                    "Instead fix your kernel and enable CONFIG_CGROUPS. "
-                    "Consult http://0pointer.de/blog/projects/cgroups-vs-cgroups.html for more information.");
-
-        sleep(10);
-}
-
 static int initialize_join_controllers(void) {
         /* By default, mount "cpu" + "cpuacct" together, and "net_cls"
          * + "net_prio". We'd like to add "cpuset" to the mix, but
@@ -1224,9 +1192,15 @@ static int status_welcome(void) {
                            "PRETTY_NAME", &pretty_name,
                            "ANSI_COLOR", &ansi_color,
                            NULL);
+        if (r == -ENOENT) {
+                r = parse_env_file("/usr/lib/os-release", NEWLINE,
+                                   "PRETTY_NAME", &pretty_name,
+                                   "ANSI_COLOR", &ansi_color,
+                                   NULL);
+        }
 
         if (r < 0 && r != -ENOENT)
-                log_warning("Failed to read /etc/os-release: %s", strerror(-r));
+                log_warning("Failed to read os-release file: %s", strerror(-r));
 
         return status_printf(NULL, false, false,
                              "\nWelcome to \x1B[%sm%s\x1B[0m!\n",
@@ -1234,6 +1208,16 @@ static int status_welcome(void) {
                              isempty(pretty_name) ? "Linux" : pretty_name);
 }
 
+static int write_container_id(void) {
+        const char *c;
+
+        c = getenv("container");
+        if (isempty(c))
+                return 0;
+
+        return write_string_file("/run/systemd/container", c);
+}
+
 int main(int argc, char *argv[]) {
         Manager *m = NULL;
         int r, retval = EXIT_FAILURE;
@@ -1253,6 +1237,7 @@ int main(int argc, char *argv[]) {
         bool loaded_policy = false;
         bool arm_reboot_watchdog = false;
         bool queue_default_job = false;
+        bool empty_etc = false;
         char *switch_root_dir = NULL, *switch_root_init = NULL;
         static struct rlimit saved_rlimit_nofile = { 0, 0 };
 
@@ -1293,6 +1278,7 @@ int main(int argc, char *argv[]) {
         saved_argc = argc;
 
         log_show_color(isatty(STDERR_FILENO) > 0);
+        log_set_upgrade_syslog_to_journal(true);
 
         /* Disable the umask logic */
         if (getpid() == 1)
@@ -1311,24 +1297,29 @@ int main(int argc, char *argv[]) {
 
                 if (!skip_setup) {
                         mount_setup_early();
+#ifdef CONFIG_TIZEN_WIP
+                        if (access("/opt/.initrd-done", F_OK) < 0 &&
+                            access("/usr/bin/tizen-boot.sh", X_OK) == 0) {
+                                /* If systemd is running as PID 1 and
+                                 * booted without initrd, we need
+                                 * extra pre-mounts to use passwd and
+                                 * group. */
+                                log_info("No initrd. invoke tizen-boot.sh");
+                                int sys_ret = system("/usr/bin/tizen-boot.sh");
+                                if (WIFSIGNALED(sys_ret) &&
+                                    (WTERMSIG(sys_ret) == SIGINT || WTERMSIG(sys_ret) == SIGQUIT)) {
+                                        log_error("Failed to execute tizen-boot");
+                                        goto finish;
+                                }
+                        }
+#endif
                         dual_timestamp_get(&security_start_timestamp);
                         if (selinux_setup(&loaded_policy) < 0)
                                 goto finish;
                         if (ima_setup() < 0)
                                 goto finish;
-#ifndef CONFIG_TIZEN_WIP
-                        /* FIXME */
-                        /* smack_setup is temporary blocked. Now Tizen
-                         * is using newest feature of smack. Invalid
-                         * argument will occur in fflush by dual
-                         * permission field. Until smack_setup cover
-                         * the new feature it will be blocked. When
-                         * the smack_setup can cover the dual
-                         * permission field then smack.service should
-                         * be removed. */
                         if (smack_setup(&loaded_policy) < 0)
                                 goto finish;
-#endif
                         dual_timestamp_get(&security_finish_timestamp);
                 }
 
@@ -1336,30 +1327,37 @@ int main(int argc, char *argv[]) {
                         goto finish;
 
                 if (!skip_setup) {
-                        if (hwclock_is_localtime() > 0) {
+                        if (clock_is_localtime() > 0) {
                                 int min;
 
-                                /* The first-time call to settimeofday() does a time warp in the kernel */
-                                r = hwclock_set_timezone(&min);
+                                /*
+                                 * The very first call of settimeofday() also does a time warp in the kernel.
+                                 *
+                                 * In the rtc-in-local time mode, we set the kernel's timezone, and rely on
+                                 * external tools to take care of maintaining the RTC and do all adjustments.
+                                 * This matches the behavior of Windows, which leaves the RTC alone if the
+                                 * registry tells that the RTC runs in UTC.
+                                 */
+                                r = clock_set_timezone(&min);
                                 if (r < 0)
                                         log_error("Failed to apply local time delta, ignoring: %s", strerror(-r));
                                 else
                                         log_info("RTC configured in localtime, applying delta of %i minutes to system time.", min);
                         } else if (!in_initrd()) {
                                 /*
-                                 * Do dummy first-time call to seal the kernel's time warp magic
+                                 * Do a dummy very first call to seal the kernel's time warp magic.
                                  *
                                  * Do not call this this from inside the initrd. The initrd might not
                                  * carry /etc/adjtime with LOCAL, but the real system could be set up
                                  * that way. In such case, we need to delay the time-warp or the sealing
                                  * until we reach the real system.
+                                 *
+                                 * Do no set the kernel's timezone. The concept of local time cannot
+                                 * be supported reliably, the time will jump or be incorrect at every daylight
+                                 * saving time change. All kernel local time concepts will be treated
+                                 * as UTC that way.
                                  */
-                                hwclock_reset_timezone();
-
-                                /* Tell the kernel our timezone */
-                                r = hwclock_set_timezone(NULL);
-                                if (r < 0)
-                                        log_error("Failed to set the kernel's timezone, ignoring: %s", strerror(-r));
+                                clock_reset_timewarp();
                         }
                 }
 
@@ -1426,9 +1424,11 @@ int main(int argc, char *argv[]) {
                 goto finish;
 
         if (arg_running_as == SYSTEMD_SYSTEM)
-                if (parse_proc_cmdline(parse_proc_cmdline_word) < 0)
+                if (parse_proc_cmdline(parse_proc_cmdline_item) < 0)
                         goto finish;
 
+        /* Note that this also parses bits from the kernel command
+         * line, including "debug". */
         log_parse_environment();
 
         if (parse_argv(argc, argv) < 0)
@@ -1454,6 +1454,11 @@ int main(int argc, char *argv[]) {
                 goto finish;
         }
 
+        if (arg_action == ACTION_TEST)
+                skip_setup = true;
+
+        pager_open_if_enabled();
+
         if (arg_action == ACTION_HELP) {
                 retval = help();
                 goto finish;
@@ -1500,8 +1505,16 @@ int main(int argc, char *argv[]) {
 
         /* Reset the console, but only if this is really init and we
          * are freshly booted */
-        if (arg_running_as == SYSTEMD_SYSTEM && arg_action == ACTION_RUN)
-                console_setup(getpid() == 1 && !skip_setup);
+        if (arg_running_as == SYSTEMD_SYSTEM && arg_action == ACTION_RUN) {
+
+                /* If we are init, we connect stdin/stdout/stderr to
+                 * /dev/null and make sure we don't have a controlling
+                 * tty. */
+                release_terminal();
+
+                if (getpid() == 1 && !skip_setup)
+                        console_setup();
+        }
 
         /* Open the logging devices, if possible and necessary */
         log_open();
@@ -1522,21 +1535,37 @@ int main(int argc, char *argv[]) {
         if (arg_running_as == SYSTEMD_SYSTEM) {
                 const char *virtualization = NULL;
 
-                log_info(PACKAGE_STRING " running in system mode. (" SYSTEMD_FEATURES ")");
+                log_info(PACKAGE_STRING " running in %ssystem mode. (" SYSTEMD_FEATURES ")",
+                         arg_action == ACTION_TEST ? "test " : "" );
 
                 detect_virtualization(&virtualization);
                 if (virtualization)
                         log_info("Detected virtualization '%s'.", virtualization);
 
+                write_container_id();
+
                 log_info("Detected architecture '%s'.", architecture_to_string(uname_architecture()));
 
                 if (in_initrd())
                         log_info("Running in initial RAM disk.");
 
+                /* Let's check whether /etc is already populated. We
+                 * don't actually really check for that, but use
+                 * /etc/machine-id as flag file. This allows container
+                 * managers and installers to provision a couple of
+                 * files already. If the container manager wants to
+                 * provision the machine ID itself it should pass
+                 * $container_uuid to PID 1.*/
+
+                empty_etc = access("/etc/machine-id", F_OK) < 0;
+                if (empty_etc)
+                        log_info("Running with unpopulated /etc.");
         } else {
-                _cleanup_free_ char *t = uid_to_name(getuid());
-                log_debug(PACKAGE_STRING " running in user mode for user "PID_FMT"/%s. (" SYSTEMD_FEATURES ")",
-                          getuid(), t);
+                _cleanup_free_ char *t;
+
+                t = uid_to_name(getuid());
+                log_debug(PACKAGE_STRING " running in %suser mode for user "UID_FMT"/%s. (" SYSTEMD_FEATURES ")",
+                          arg_action == ACTION_TEST ? " test" : "", getuid(), t);
         }
 
         if (arg_running_as == SYSTEMD_SYSTEM && !skip_setup) {
@@ -1544,22 +1573,20 @@ int main(int argc, char *argv[]) {
                         status_welcome();
 
 #ifdef HAVE_KMOD
-                if (detect_container(NULL) <= 0)
-                        kmod_setup();
+                kmod_setup();
 #endif
                 hostname_setup();
-                machine_id_setup();
+                machine_id_setup(NULL);
                 loopback_setup();
 
                 test_mtab();
                 test_usr();
-                test_cgroups();
         }
 
         if (arg_running_as == SYSTEMD_SYSTEM && arg_runtime_watchdog > 0)
                 watchdog_set_timeout(&arg_runtime_watchdog);
 
-        if (arg_timer_slack_nsec != (nsec_t) -1)
+        if (arg_timer_slack_nsec != NSEC_INFINITY)
                 if (prctl(PR_SET_TIMERSLACK, arg_timer_slack_nsec) < 0)
                         log_error("Failed to adjust timer slack: %m");
 
@@ -1591,16 +1618,26 @@ int main(int argc, char *argv[]) {
                 }
         }
 
-        if (arg_running_as == SYSTEMD_SYSTEM)
+        if (arg_running_as == SYSTEMD_SYSTEM) {
                 bump_rlimit_nofile(&saved_rlimit_nofile);
 
-        r = manager_new(arg_running_as, &m);
+                if (empty_etc) {
+                        r = unit_file_preset_all(UNIT_FILE_SYSTEM, false, NULL, UNIT_FILE_PRESET_FULL, false, NULL, 0);
+                        if (r < 0)
+                                log_warning("Failed to populate /etc with preset unit settings, ignoring: %s", strerror(-r));
+                        else
+                                log_info("Populated /etc with preset unit settings.");
+                }
+        }
+
+        r = manager_new(arg_running_as, arg_action == ACTION_TEST, &m);
         if (r < 0) {
                 log_error("Failed to allocate manager object: %s", strerror(-r));
                 goto finish;
         }
 
         m->confirm_spawn = arg_confirm_spawn;
+        m->default_timer_accuracy_usec = arg_default_timer_accuracy_usec;
         m->default_std_output = arg_default_std_output;
         m->default_std_error = arg_default_std_error;
         m->default_restart_usec = arg_default_restart_usec;
@@ -1608,6 +1645,9 @@ int main(int argc, char *argv[]) {
         m->default_timeout_stop_usec = arg_default_timeout_stop_usec;
         m->default_start_limit_interval = arg_default_start_limit_interval;
         m->default_start_limit_burst = arg_default_start_limit_burst;
+        m->default_cpu_accounting = arg_default_cpu_accounting;
+        m->default_blockio_accounting = arg_default_blockio_accounting;
+        m->default_memory_accounting = arg_default_memory_accounting;
         m->runtime_watchdog = arg_runtime_watchdog;
         m->shutdown_watchdog = arg_shutdown_watchdog;
         m->userspace_timestamp = userspace_timestamp;
@@ -1619,10 +1659,10 @@ int main(int argc, char *argv[]) {
         manager_set_default_rlimits(m, arg_default_rlimit);
         manager_environment_add(m, NULL, arg_default_environment);
 #ifdef CONFIG_TIZEN
-        if (arg_running_as == SYSTEMD_SYSTEM && arg_default_extra_dependencies)
-                manager_set_default_extra_dependencies(m, arg_default_extra_dependencies);
+        manager_set_default_extra_dependencies(m, arg_default_extra_dependencies);
 #endif
         manager_set_show_status(m, arg_show_status);
+        manager_set_first_boot(m, empty_etc);
 
         /* Remember whether we should queue the default job */
         queue_default_job = !arg_serialization || arg_switched_root;
@@ -1778,6 +1818,8 @@ int main(int argc, char *argv[]) {
         }
 
 finish:
+        pager_close();
+
         if (m) {
                 manager_free(m);
                 m = NULL;
@@ -1804,6 +1846,7 @@ finish:
         if (reexecute) {
                 const char **args;
                 unsigned i, args_size;
+                sigset_t ss;
 
                 /* Close and disarm the watchdog, so that the new
                  * instance can reinitialize it, but doesn't get
@@ -1887,6 +1930,13 @@ finish:
                 args[i++] = NULL;
                 assert(i <= args_size);
 
+                /* reenable any blocked signals, especially important
+                 * if we switch from initial ramdisk to init=... */
+                reset_all_signal_handlers();
+
+                assert_se(sigemptyset(&ss) == 0);
+                assert_se(sigprocmask(SIG_SETMASK, &ss, NULL) == 0);
+
                 if (switch_root_init) {
                         args[0] = switch_root_init;
                         execv(args[0], (char* const*) args);
@@ -1961,7 +2011,7 @@ finish:
                 if (log_get_show_location())
                         command_line[pos++] = "--log-location";
 
-                assert(pos + 1 < ELEMENTSOF(command_line));
+                assert(pos < ELEMENTSOF(command_line));
 
                 if (arm_reboot_watchdog && arg_shutdown_watchdog > 0) {
                         char *e;
index 13cc645..02e835d 100644 (file)
@@ -84,9 +84,6 @@
 #define JOBS_IN_PROGRESS_PERIOD_USEC (USEC_PER_SEC / 3)
 #define JOBS_IN_PROGRESS_PERIOD_DIVISOR 3
 
-/* Where clients shall send notification messages to */
-#define NOTIFY_SOCKET "@/org/freedesktop/systemd1/notify"
-
 #define TIME_T_MAX (time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1)
 
 static int manager_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
@@ -105,7 +102,12 @@ static int manager_watch_jobs_in_progress(Manager *m) {
                 return 0;
 
         next = now(CLOCK_MONOTONIC) + JOBS_IN_PROGRESS_WAIT_USEC;
-        return sd_event_add_monotonic(m->event, &m->jobs_in_progress_event_source, next, 0, manager_dispatch_jobs_in_progress, m);
+        return sd_event_add_time(
+                        m->event,
+                        &m->jobs_in_progress_event_source,
+                        CLOCK_MONOTONIC,
+                        next, 0,
+                        manager_dispatch_jobs_in_progress, m);
 }
 
 #define CYLON_BUFFER_EXTRA (2*(sizeof(ANSI_RED_ON)-1) + sizeof(ANSI_HIGHLIGHT_RED_ON)-1 + 2*(sizeof(ANSI_HIGHLIGHT_OFF)-1))
@@ -140,6 +142,8 @@ static void draw_cylon(char buffer[], size_t buflen, unsigned width, unsigned po
 }
 
 void manager_flip_auto_status(Manager *m, bool enable) {
+        assert(m);
+
         if (enable) {
                 if (m->show_status == SHOW_STATUS_AUTO)
                         manager_set_show_status(m, SHOW_STATUS_TEMPORARY);
@@ -221,8 +225,8 @@ static int manager_watch_idle_pipe(Manager *m) {
 static void manager_close_idle_pipe(Manager *m) {
         assert(m);
 
-        close_pipe(m->idle_pipe);
-        close_pipe(m->idle_pipe + 2);
+        safe_close_pair(m->idle_pipe);
+        safe_close_pair(m->idle_pipe + 2);
 }
 
 static int manager_setup_time_change(Manager *m) {
@@ -237,6 +241,9 @@ static int manager_setup_time_change(Manager *m) {
         assert(m);
         assert_cc(sizeof(time_t) == sizeof(TIME_T_MAX));
 
+        if (m->test_run)
+                return 0;
+
         /* Uses TFD_TIMER_CANCEL_ON_SET to get notifications whenever
          * CLOCK_REALTIME makes a jump relative to CLOCK_MONOTONIC */
 
@@ -248,8 +255,7 @@ static int manager_setup_time_change(Manager *m) {
 
         if (timerfd_settime(m->time_change_fd, TFD_TIMER_ABSTIME|TFD_TIMER_CANCEL_ON_SET, &its, NULL) < 0) {
                 log_debug("Failed to set up TFD_TIMER_CANCEL_ON_SET, ignoring: %m");
-                close_nointr_nofail(m->time_change_fd);
-                m->time_change_fd = -1;
+                m->time_change_fd = safe_close(m->time_change_fd);
                 return 0;
         }
 
@@ -299,6 +305,9 @@ static int manager_setup_signals(Manager *m) {
 
         assert(m);
 
+        if (m->test_run)
+                return 0;
+
         /* We are not interested in SIGSTOP and friends. */
         assert_se(sigaction(SIGCHLD, &sa, NULL) == 0);
 
@@ -332,7 +341,7 @@ static int manager_setup_signals(Manager *m) {
                         SIGRTMIN+26, /* systemd: set log target to journal-or-kmsg */
                         SIGRTMIN+27, /* systemd: set log target to console */
                         SIGRTMIN+28, /* systemd: set log target to kmsg */
-                        SIGRTMIN+29, /* systemd: set log target to syslog-or-kmsg */
+                        SIGRTMIN+29, /* systemd: set log target to syslog-or-kmsg (obsolete)*/
                         -1);
         assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
 
@@ -406,7 +415,7 @@ static int manager_default_environment(Manager *m) {
         return 0;
 }
 
-int manager_new(SystemdRunningAs running_as, Manager **_m) {
+int manager_new(SystemdRunningAs running_as, bool test_run, Manager **_m) {
         Manager *m;
         int r;
 
@@ -419,18 +428,21 @@ int manager_new(SystemdRunningAs running_as, Manager **_m) {
                 return -ENOMEM;
 
 #ifdef ENABLE_EFI
-        if (detect_container(NULL) <= 0)
+        if (running_as == SYSTEMD_SYSTEM && detect_container(NULL) <= 0)
                 boot_timestamps(&m->userspace_timestamp, &m->firmware_timestamp, &m->loader_timestamp);
 #endif
 
         m->running_as = running_as;
         m->exit_code = _MANAGER_EXIT_CODE_INVALID;
+        m->default_timer_accuracy_usec = USEC_PER_MINUTE;
 
         m->idle_pipe[0] = m->idle_pipe[1] = m->idle_pipe[2] = m->idle_pipe[3] = -1;
 
         m->pin_cgroupfs_fd = m->notify_fd = m->signal_fd = m->time_change_fd = m->dev_autofs_fd = m->private_listen_fd = m->kdbus_fd = -1;
         m->current_job_id = 1; /* start as id #1, so that we can leave #0 around as "null-like" value */
 
+        m->test_run = test_run;
+
         r = manager_default_environment(m);
         if (r < 0)
                 goto fail;
@@ -451,6 +463,14 @@ int manager_new(SystemdRunningAs running_as, Manager **_m) {
         if (r < 0)
                 goto fail;
 
+        r = set_ensure_allocated(&m->startup_units, trivial_hash_func, trivial_compare_func);
+        if (r < 0)
+                goto fail;
+
+        r = set_ensure_allocated(&m->failed_units, trivial_hash_func, trivial_compare_func);
+        if (r < 0)
+                goto fail;
+
         r = sd_event_default(&m->event);
         if (r < 0)
                 goto fail;
@@ -460,8 +480,8 @@ int manager_new(SystemdRunningAs running_as, Manager **_m) {
                 goto fail;
 
 #ifdef CONFIG_TIZEN
-        m->dep_ignore_list = set_new(string_hash_func, string_compare_func);
-        if (!m->dep_ignore_list)
+        r = hashmap_ensure_allocated(&m->dep_ignore_list, string_hash_func, string_compare_func);
+        if (r < 0)
                 goto fail;
 #endif
 
@@ -506,16 +526,20 @@ fail:
 }
 
 static int manager_setup_notify(Manager *m) {
-        union {
-                struct sockaddr sa;
-                struct sockaddr_un un;
-        } sa = {
-                .sa.sa_family = AF_UNIX,
-        };
-        int one = 1, r;
+        int r;
+
+        if (m->test_run)
+                return 0;
 
         if (m->notify_fd < 0) {
                 _cleanup_close_ int fd = -1;
+                union {
+                        struct sockaddr sa;
+                        struct sockaddr_un un;
+                } sa = {
+                        .sa.sa_family = AF_UNIX,
+                };
+                int one = 1;
 
                 /* First free all secondary fields */
                 free(m->notify_socket);
@@ -528,29 +552,49 @@ static int manager_setup_notify(Manager *m) {
                         return -errno;
                 }
 
-                if (getpid() != 1 || detect_container(NULL) > 0)
-                        snprintf(sa.un.sun_path, sizeof(sa.un.sun_path), NOTIFY_SOCKET "/%" PRIx64, random_u64());
-                else
-                        strncpy(sa.un.sun_path, NOTIFY_SOCKET, sizeof(sa.un.sun_path));
-                sa.un.sun_path[0] = 0;
+                if (m->running_as == SYSTEMD_SYSTEM)
+                        m->notify_socket = strdup("/run/systemd/notify");
+                else {
+                        const char *e;
+
+                        e = getenv("XDG_RUNTIME_DIR");
+                        if (!e) {
+                                log_error("XDG_RUNTIME_DIR is not set: %m");
+                                return -EINVAL;
+                        }
+
+                        m->notify_socket = strappend(e, "/systemd/notify");
+                }
+                if (!m->notify_socket)
+                        return log_oom();
 
-                r = bind(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1));
+                strncpy(sa.un.sun_path, m->notify_socket, sizeof(sa.un.sun_path)-1);
+                r = bind(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path));
                 if (r < 0) {
-                        log_error("bind() failed: %m");
+                        log_error("bind(@%s) failed: %m", sa.un.sun_path+1);
                         return -errno;
                 }
 
+#if RUN_GID != 0
+                if (m->running_as == SYSTEMD_SYSTEM) {
+                        if (smack_label_ip_in_fd(fd, "*") < 0) {
+                                log_error("smack_label_ip_in_fd() failed: %m");
+                                return -errno;
+                        }
+
+                        if (smack_label_ip_out_fd(fd, "@") < 0) {
+                                log_error("smack_label_ip_out_fd() failed: %m");
+                                return -errno;
+                        }
+                }
+#endif
+
                 r = setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one));
                 if (r < 0) {
                         log_error("SO_PASSCRED failed: %m");
                         return -errno;
                 }
 
-                sa.un.sun_path[0] = '@';
-                m->notify_socket = strdup(sa.un.sun_path);
-                if (!m->notify_socket)
-                        return log_oom();
-
                 m->notify_fd = fd;
                 fd = -1;
 
@@ -579,12 +623,10 @@ static int manager_setup_notify(Manager *m) {
 static int manager_setup_kdbus(Manager *m) {
 #ifdef ENABLE_KDBUS
         _cleanup_free_ char *p = NULL;
-#endif
 
-#ifdef ENABLE_KDBUS
         assert(m);
 
-        if (m->kdbus_fd >= 0)
+        if (m->test_run || m->kdbus_fd >= 0)
                 return 0;
 
         m->kdbus_fd = bus_kernel_create_bus(m->running_as == SYSTEMD_SYSTEM ? "system" : "user", m->running_as == SYSTEMD_SYSTEM, &p);
@@ -611,6 +653,9 @@ static int manager_connect_bus(Manager *m, bool reexecuting) {
 
         assert(m);
 
+        if (m->test_run)
+                return 0;
+
         try_bus_connect =
                 m->kdbus_fd >= 0 ||
                 reexecuting ||
@@ -784,9 +829,12 @@ void manager_free(Manager *m) {
         hashmap_free(m->watch_pids2);
         hashmap_free(m->watch_bus);
 #ifdef CONFIG_TIZEN
-        set_free_free(m->dep_ignore_list);
+        hashmap_free(m->dep_ignore_list);
 #endif
 
+        set_free(m->startup_units);
+        set_free(m->failed_units);
+
         sd_event_source_unref(m->signal_event_source);
         sd_event_source_unref(m->notify_event_source);
         sd_event_source_unref(m->time_change_event_source);
@@ -794,14 +842,10 @@ void manager_free(Manager *m) {
         sd_event_source_unref(m->idle_pipe_event_source);
         sd_event_source_unref(m->run_queue_event_source);
 
-        if (m->signal_fd >= 0)
-                close_nointr_nofail(m->signal_fd);
-        if (m->notify_fd >= 0)
-                close_nointr_nofail(m->notify_fd);
-        if (m->time_change_fd >= 0)
-                close_nointr_nofail(m->time_change_fd);
-        if (m->kdbus_fd >= 0)
-                close_nointr_nofail(m->kdbus_fd);
+        safe_close(m->signal_fd);
+        safe_close(m->notify_fd);
+        safe_close(m->time_change_fd);
+        safe_close(m->kdbus_fd);
 
         manager_close_idle_pipe(m);
 
@@ -819,7 +863,7 @@ void manager_free(Manager *m) {
         free(m->switch_root);
         free(m->switch_root_init);
 
-        for (i = 0; i < RLIMIT_NLIMITS; i++)
+        for (i = 0; i < _RLIMIT_MAX; i++)
                 free(m->rlimit[i]);
 
         assert(hashmap_isempty(m->units_requiring_mounts_for));
@@ -848,7 +892,7 @@ int manager_enumerate(Manager *m) {
 }
 
 static int manager_coldplug(Manager *m) {
-        int r = 0, q;
+        int r = 0;
         Iterator i;
         Unit *u;
         char *k;
@@ -857,12 +901,14 @@ static int manager_coldplug(Manager *m) {
 
         /* Then, let's set up their initial state. */
         HASHMAP_FOREACH_KEY(u, k, m->units, i) {
+                int q;
 
                 /* ignore aliases */
                 if (u->id != k)
                         continue;
 
-                if ((q = unit_coldplug(u)) < 0)
+                q = unit_coldplug(u);
+                if (q < 0)
                         r = q;
         }
 
@@ -961,6 +1007,7 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
 
         r = lookup_paths_init(
                         &m->lookup_paths, m->running_as, true,
+                        NULL,
                         m->generator_unit_path,
                         m->generator_unit_path_early,
                         m->generator_unit_path_late);
@@ -981,11 +1028,8 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
         dual_timestamp_get(&m->units_load_finish_timestamp);
 
         /* Second, deserialize if there is something to deserialize */
-        if (serialization) {
-                q = manager_deserialize(m, serialization, fds);
-                if (q < 0)
-                        r = q;
-        }
+        if (serialization)
+                r = manager_deserialize(m, serialization, fds);
 
         /* Any fds left? Find some unit which wants them. This is
          * useful to allow container managers to pass some file
@@ -993,22 +1037,25 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
          * socket-based activation of entire containers. */
         if (fdset_size(fds) > 0) {
                 q = manager_distribute_fds(m, fds);
-                if (q < 0)
+                if (q < 0 && r == 0)
                         r = q;
         }
 
         /* We might have deserialized the notify fd, but if we didn't
          * then let's create the bus now */
-        manager_setup_notify(m);
+        q = manager_setup_notify(m);
+        if (q < 0 && r == 0)
+                r = q;
 
         /* We might have deserialized the kdbus control fd, but if we
          * didn't, then let's create the bus now. */
         manager_setup_kdbus(m);
         manager_connect_bus(m, !!serialization);
+        bus_track_coldplug(m, &m->subscribed, &m->deserialized_subscribed);
 
         /* Third, fire things up! */
         q = manager_coldplug(m);
-        if (q < 0)
+        if (q < 0 && r == 0)
                 r = q;
 
         if (serialization) {
@@ -1627,6 +1674,11 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t
                                 break;
                         }
 
+                        if (fflush(f)) {
+                                log_warning("Failed to flush status stream");
+                                break;
+                        }
+
                         log_dump(LOG_INFO, dump);
                         break;
                 }
@@ -1702,6 +1754,7 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t
                                 break;
 
                         case 26:
+                        case 29: /* compatibility: used to be mapped to LOG_TARGET_SYSLOG_OR_KMSG */
                                 log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
                                 log_notice("Setting log target to journal-or-kmsg.");
                                 break;
@@ -1716,11 +1769,6 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t
                                 log_notice("Setting log target to kmsg.");
                                 break;
 
-                        case 29:
-                                log_set_target(LOG_TARGET_SYSLOG_OR_KMSG);
-                                log_notice("Setting log target to syslog-or-kmsg.");
-                                break;
-
                         default:
                                 log_warning("Got unhandled signal <%s>.", signal_to_string(sfsi.ssi_signo));
                         }
@@ -1749,9 +1797,7 @@ static int manager_dispatch_time_change_fd(sd_event_source *source, int fd, uint
 
         /* Restart the watch */
         m->time_change_event_source = sd_event_source_unref(m->time_change_event_source);
-
-        close_nointr_nofail(m->time_change_fd);
-        m->time_change_fd = -1;
+        m->time_change_fd = safe_close(m->time_change_fd);
 
         manager_setup_time_change(m);
 
@@ -1800,7 +1846,7 @@ int manager_loop(Manager *m) {
         RATELIMIT_DEFINE(rl, 1*USEC_PER_SEC, 50000);
 
         assert(m);
-        m->exit_code = MANAGER_RUNNING;
+        m->exit_code = MANAGER_OK;
 
         /* Release the path cache */
         set_free_free(m->unit_path_cache);
@@ -1814,7 +1860,7 @@ int manager_loop(Manager *m) {
         if (r < 0)
                 return r;
 
-        while (m->exit_code == MANAGER_RUNNING) {
+        while (m->exit_code == MANAGER_OK) {
                 usec_t wait_usec;
 
                 if (m->runtime_watchdog > 0 && m->running_as == SYSTEMD_SYSTEM)
@@ -1848,7 +1894,7 @@ int manager_loop(Manager *m) {
                         if (wait_usec <= 0)
                                 wait_usec = 1;
                 } else
-                        wait_usec = (usec_t) -1;
+                        wait_usec = USEC_INFINITY;
 
                 r = sd_event_run(m->event, wait_usec);
                 if (r < 0) {
@@ -1950,10 +1996,7 @@ void manager_send_unit_audit(Manager *m, Unit *u, int type, bool success) {
 }
 
 void manager_send_unit_plymouth(Manager *m, Unit *u) {
-        union sockaddr_union sa = {
-                .un.sun_family = AF_UNIX,
-                .un.sun_path = "\0/org/freedesktop/plymouthd",
-        };
+        union sockaddr_union sa = PLYMOUTH_SOCKET;
 
         int n = 0;
         _cleanup_free_ char *message = NULL;
@@ -2035,7 +2078,7 @@ int manager_open_serialization(Manager *m, FILE **_f) {
 
         f = fdopen(fd, "w+");
         if (!f) {
-                close_nointr_nofail(fd);
+                safe_close(fd);
                 return -errno;
         }
 
@@ -2111,7 +2154,7 @@ int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool switching_root) {
                 fprintf(f, "kdbus-fd=%i\n", copy);
         }
 
-        bus_serialize(m, f);
+        bus_track_serialize(m->subscribed, f);
 
         fputc('\n', f);
 
@@ -2119,9 +2162,6 @@ int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool switching_root) {
                 if (u->id != t)
                         continue;
 
-                if (!unit_can_serialize(u))
-                        continue;
-
                 /* Start marker */
                 fputs(u->id, f);
                 fputc('\n', f);
@@ -2256,11 +2296,8 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
                         if (safe_atoi(l + 10, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
                                 log_debug("Failed to parse notify fd: %s", l + 10);
                         else {
-                                if (m->notify_fd >= 0) {
-                                        m->notify_event_source = sd_event_source_unref(m->notify_event_source);
-                                        close_nointr_nofail(m->notify_fd);
-                                }
-
+                                m->notify_event_source = sd_event_source_unref(m->notify_event_source);
+                                safe_close(m->notify_fd);
                                 m->notify_fd = fdset_remove(fds, fd);
                         }
 
@@ -2282,13 +2319,11 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
                         if (safe_atoi(l + 9, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
                                 log_debug("Failed to parse kdbus fd: %s", l + 9);
                         else {
-                                if (m->kdbus_fd >= 0)
-                                        close_nointr_nofail(m->kdbus_fd);
-
+                                safe_close(m->kdbus_fd);
                                 m->kdbus_fd = fdset_remove(fds, fd);
                         }
 
-                } else if (bus_deserialize_item(m, l) == 0)
+                } else if (bus_track_deserialize_item(&m->deserialized_subscribed, l) == 0)
                         log_debug("Unknown serialization item '%s'", l);
         }
 
@@ -2368,6 +2403,7 @@ int manager_reload(Manager *m) {
 
         q = lookup_paths_init(
                         &m->lookup_paths, m->running_as, true,
+                        NULL,
                         m->generator_unit_path,
                         m->generator_unit_path_early,
                         m->generator_unit_path_late);
@@ -2407,23 +2443,6 @@ int manager_reload(Manager *m) {
         return r;
 }
 
-static bool manager_is_booting_or_shutting_down(Manager *m) {
-        Unit *u;
-
-        assert(m);
-
-        /* Is the initial job still around? */
-        if (manager_get_job(m, m->default_unit_job_id))
-                return true;
-
-        /* Is there a job for the shutdown target? */
-        u = manager_get_unit(m, SPECIAL_SHUTDOWN_TARGET);
-        if (u)
-                return !!u->job;
-
-        return false;
-}
-
 bool manager_is_reloading_or_reexecuting(Manager *m) {
         assert(m);
 
@@ -2457,6 +2476,8 @@ bool manager_unit_inactive_or_pending(Manager *m, const char *name) {
 void manager_check_finished(Manager *m) {
         char userspace[FORMAT_TIMESPAN_MAX], initrd[FORMAT_TIMESPAN_MAX], kernel[FORMAT_TIMESPAN_MAX], sum[FORMAT_TIMESPAN_MAX];
         usec_t firmware_usec, loader_usec, kernel_usec, initrd_usec, userspace_usec, total_usec;
+        Unit *u = NULL;
+        Iterator i;
 
         assert(m);
 
@@ -2464,10 +2485,12 @@ void manager_check_finished(Manager *m) {
                 m->jobs_in_progress_event_source = sd_event_source_unref(m->jobs_in_progress_event_source);
 
         if (hashmap_size(m->jobs) > 0) {
+
                 if (m->jobs_in_progress_event_source) {
-                        uint64_t next = now(CLOCK_MONOTONIC) + JOBS_IN_PROGRESS_WAIT_USEC;
-                        sd_event_source_set_time(m->jobs_in_progress_event_source, next);
+                        sd_event_source_set_time(m->jobs_in_progress_event_source,
+                                                 now(CLOCK_MONOTONIC) + JOBS_IN_PROGRESS_WAIT_USEC);
                 }
+
                 return;
         }
 
@@ -2480,6 +2503,9 @@ void manager_check_finished(Manager *m) {
         /* Turn off confirm spawn now */
         m->confirm_spawn = false;
 
+        /* This is no longer the first boot */
+        manager_set_first_boot(m, false);
+
         if (dual_timestamp_is_set(&m->finish_timestamp))
                 return;
 
@@ -2542,6 +2568,10 @@ void manager_check_finished(Manager *m) {
                                    NULL);
         }
 
+        SET_FOREACH(u, m->startup_units, i)
+                if (u->cgroup_path)
+                        cgroup_context_apply(unit_get_cgroup_context(u), unit_get_cgroup_mask(u), u->cgroup_path, manager_state(m));
+
         bus_manager_send_finished(m, firmware_usec, loader_usec, kernel_usec, initrd_usec, userspace_usec, total_usec);
 
         sd_notifyf(false,
@@ -2633,6 +2663,9 @@ void manager_run_generators(Manager *m) {
 
         assert(m);
 
+        if (m->test_run)
+                return;
+
         generator_path = m->running_as == SYSTEMD_SYSTEM ? SYSTEM_GENERATOR_PATH : USER_GENERATOR_PATH;
         d = opendir(generator_path);
         if (!d) {
@@ -2663,7 +2696,7 @@ void manager_run_generators(Manager *m) {
         argv[4] = NULL;
 
         RUN_WITH_UMASK(0022)
-                execute_directory(generator_path, d, (char**) argv);
+                execute_directory(generator_path, d, DEFAULT_TIMEOUT_USEC, (char**) argv);
 
 finish:
         trim_generator_dir(m, &m->generator_unit_path);
@@ -2730,6 +2763,50 @@ int manager_environment_add(Manager *m, char **minus, char **plus) {
 }
 
 #ifdef CONFIG_TIZEN
+static int manager_write_file_default_extra_dependencies(Manager *m) {
+        _cleanup_fclose_ FILE *dep = NULL, *ignore = NULL;
+        Iterator i;
+        char **s = NULL, *k = NULL;
+        int r = 0;
+
+        assert(m);
+
+        if (strv_isempty(m->dependencies))
+                return 0;
+
+        errno = 0;
+
+        /* write to file default dependency units */
+        r =  mkdir_p("/run/systemd/default-extra-dependencies", 0755);
+        if (r < 0)
+                return r;
+
+        dep = fopen("/run/systemd/default-extra-dependencies/dependencies", "we");
+        if (!dep)
+                return -errno;
+
+        STRV_FOREACH(s, m->dependencies)
+                fprintf(dep, "%s\n", *s);
+
+        fflush(dep);
+        if (ferror(dep))
+                return errno ? -errno : -EIO;
+
+        /* write to file ignore units */
+        ignore = fopen("/run/systemd/default-extra-dependencies/ignore-units", "we");
+        if (!ignore)
+                return -errno;
+
+        HASHMAP_FOREACH(k, m->dep_ignore_list, i)
+                fprintf(ignore, "%s\n", k);
+
+        fflush(ignore);
+        if (ferror(ignore))
+                return errno ? -errno : -EIO;
+
+        return 0;
+}
+
 int manager_set_default_extra_dependencies(Manager *m, char **dependencies) {
         _cleanup_free_ char *buf = NULL;
         _cleanup_closedir_ DIR *dir = NULL;
@@ -2740,16 +2817,26 @@ int manager_set_default_extra_dependencies(Manager *m, char **dependencies) {
 
         assert(m);
 
+        if (m->running_as != SYSTEMD_SYSTEM)
+                return 0;
+
+        if (strv_isempty(dependencies))
+                return 0;
+
         if (strv_extend_strv(&m->dependencies, dependencies) < 0) {
                 strv_free(m->dependencies);
                 return log_oom();
         }
 
         STRV_FOREACH(d, m->dependencies) {
-                name = strdup(*d);
-                r = set_put(m->dep_ignore_list, name);
-                if (r < 0)
-                        return r;
+                r = hashmap_put(m->dep_ignore_list, *d, *d);
+                if (r < 0) {
+                        if (r == -EEXIST) {
+                                goto dir;
+                        } else {
+                                return r;
+                        }
+                }
         }
 
         r = read_full_file(PKGSYSCONFDIR "/default-extra-dependencies/ignore-units",
@@ -2758,17 +2845,15 @@ int manager_set_default_extra_dependencies(Manager *m, char **dependencies) {
                 goto dir;
 
         FOREACH_WORD_SEPARATOR(word, len, buf, NEWLINE, state) {
-                _cleanup_free_ char *copy;
-
-                copy = strndup(word, len);
-                if (!copy)
+                name = NULL;
+                name = strndup(word, len);
+                if (!name)
                         return -ENOMEM;
 
                 if (len <= 0)
                         continue;
 
-                name = strdup(copy);
-                r = set_put(m->dep_ignore_list, name);
+                r = hashmap_put(m->dep_ignore_list, name, name);
                 if (r < 0)
                         return r;
         }
@@ -2800,13 +2885,22 @@ dir:
                         continue;
                 }
 
+                name = NULL;
                 name = strdup(basename(dst));
-                r = set_put(m->dep_ignore_list, name);
-                if (r < 0)
-                        return r;
+                if (!name)
+                        return -ENOMEM;
+
+                r = hashmap_put(m->dep_ignore_list, name, name);
+                if (r < 0) {
+                        if (r == -EEXIST) {
+                                continue;
+                        } else {
+                                return r;
+                        }
+                }
         }
 
-        return 0;
+        return manager_write_file_default_extra_dependencies(m);
 }
 #endif
 
@@ -2815,7 +2909,7 @@ int manager_set_default_rlimits(Manager *m, struct rlimit **default_rlimit) {
 
         assert(m);
 
-        for (i = 0; i < RLIMIT_NLIMITS; i++) {
+        for (i = 0; i < _RLIMIT_MAX; i++) {
                 if (!default_rlimit[i])
                         continue;
 
@@ -2876,6 +2970,9 @@ static bool manager_get_show_status(Manager *m) {
         if (m->no_console_output)
                 return false;
 
+        if (!IN_SET(manager_state(m), MANAGER_STARTING, MANAGER_STOPPING))
+                return false;
+
         if (m->show_status > 0)
                 return true;
 
@@ -2885,6 +2982,20 @@ static bool manager_get_show_status(Manager *m) {
         return plymouth_running();
 }
 
+void manager_set_first_boot(Manager *m, bool b) {
+        assert(m);
+
+        if (m->running_as != SYSTEMD_SYSTEM)
+                return;
+
+        m->first_boot = b;
+
+        if (m->first_boot)
+                touch("/run/systemd/first-boot");
+        else
+                unlink("/run/systemd/first-boot");
+}
+
 void manager_status_printf(Manager *m, bool ephemeral, const char *status, const char *format, ...) {
         va_list ap;
 
@@ -2896,9 +3007,6 @@ void manager_status_printf(Manager *m, bool ephemeral, const char *status, const
         if (ephemeral && m->n_on_console > 0)
                 return;
 
-        if (!manager_is_booting_or_shutting_down(m))
-                return;
-
         va_start(ap, format);
         status_vprintf(status, true, ephemeral, format, ap);
         va_end(ap);
@@ -2938,3 +3046,53 @@ Set *manager_get_units_requiring_mounts_for(Manager *m, const char *path) {
 
         return hashmap_get(m->units_requiring_mounts_for, streq(p, "/") ? "" : p);
 }
+
+const char *manager_get_runtime_prefix(Manager *m) {
+        assert(m);
+
+        return m->running_as == SYSTEMD_SYSTEM ?
+               "/run" :
+               getenv("XDG_RUNTIME_DIR");
+}
+
+ManagerState manager_state(Manager *m) {
+        Unit *u;
+
+        assert(m);
+
+        /* Did we ever finish booting? If not then we are still starting up */
+        if (!dual_timestamp_is_set(&m->finish_timestamp))
+                return MANAGER_STARTING;
+
+        /* Is the special shutdown target queued? If so, we are in shutdown state */
+        u = manager_get_unit(m, SPECIAL_SHUTDOWN_TARGET);
+        if (u && u->job && IN_SET(u->job->type, JOB_START, JOB_RESTART, JOB_TRY_RESTART, JOB_RELOAD_OR_START))
+                return MANAGER_STOPPING;
+
+        /* Are the rescue or emergency targets active or queued? If so we are in maintenance state */
+        u = manager_get_unit(m, SPECIAL_RESCUE_TARGET);
+        if (u && (UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)) ||
+                  (u->job && IN_SET(u->job->type, JOB_START, JOB_RESTART, JOB_TRY_RESTART, JOB_RELOAD_OR_START))))
+                return MANAGER_MAINTENANCE;
+
+        u = manager_get_unit(m, SPECIAL_EMERGENCY_TARGET);
+        if (u && (UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)) ||
+                  (u->job && IN_SET(u->job->type, JOB_START, JOB_RESTART, JOB_TRY_RESTART, JOB_RELOAD_OR_START))))
+                return MANAGER_MAINTENANCE;
+
+        /* Are there any failed units? If so, we are in degraded mode */
+        if (set_size(m->failed_units) > 0)
+                return MANAGER_DEGRADED;
+
+        return MANAGER_RUNNING;
+}
+
+static const char *const manager_state_table[_MANAGER_STATE_MAX] = {
+        [MANAGER_STARTING] = "starting",
+        [MANAGER_RUNNING] = "running",
+        [MANAGER_DEGRADED] = "degraded",
+        [MANAGER_MAINTENANCE] = "maintenance",
+        [MANAGER_STOPPING] = "stopping",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(manager_state, ManagerState);
index 15b43d6..46b5f7d 100644 (file)
 
 typedef struct Manager Manager;
 
-typedef enum ManagerExitCode {
+typedef enum ManagerState {
+        MANAGER_STARTING,
         MANAGER_RUNNING,
+        MANAGER_DEGRADED,
+        MANAGER_MAINTENANCE,
+        MANAGER_STOPPING,
+        _MANAGER_STATE_MAX,
+        _MANAGER_STATE_INVALID = -1
+} ManagerState;
+
+typedef enum ManagerExitCode {
+        MANAGER_OK,
         MANAGER_EXIT,
         MANAGER_RELOAD,
         MANAGER_REEXECUTE,
@@ -58,6 +68,7 @@ typedef enum ManagerExitCode {
 #include "execute.h"
 #include "unit-name.h"
 #include "exit-status.h"
+#include "show-status.h"
 
 struct Manager {
         /* Note that the set of units we know of is allowed to be
@@ -105,6 +116,12 @@ struct Manager {
         Hashmap *watch_pids1;  /* pid => Unit object n:1 */
         Hashmap *watch_pids2;  /* pid => Unit object n:1 */
 
+        /* A set contains all units which cgroup should be refreshed after startup */
+        Set *startup_units;
+
+        /* A set which contains all currently failed units */
+        Set *failed_units;
+
         sd_event_source *run_queue_event_source;
 
         char *notify_socket;
@@ -127,7 +144,7 @@ struct Manager {
         char **environment;
 #ifdef CONFIG_TIZEN
         char **dependencies;
-        Set *dep_ignore_list;
+        Hashmap *dep_ignore_list;
 #endif
 
         usec_t runtime_watchdog;
@@ -171,7 +188,13 @@ struct Manager {
         Set *private_buses;
         int private_listen_fd;
         sd_event_source *private_listen_event_source;
-        Set *subscribed;
+
+        /* Contains all the clients that are subscribed to signals via
+        the API bus. Note that private bus connections are always
+        considered subscribes, since they last for very short only,
+        and it is much simpler that way. */
+        sd_bus_track *subscribed;
+        char **deserialized_subscribed;
 
         sd_bus_message *queued_message; /* This is used during reloading:
                                       * before the reload we queue the
@@ -209,6 +232,9 @@ struct Manager {
         bool dispatching_dbus_queue:1;
 
         bool taint_usr:1;
+        bool first_boot:1;
+
+        bool test_run:1;
 
         ShowStatus show_status;
         bool confirm_spawn;
@@ -216,13 +242,18 @@ struct Manager {
 
         ExecOutput default_std_output, default_std_error;
 
-        usec_t default_restart_usec, default_timeout_start_usec,
-                default_timeout_stop_usec;
+        usec_t default_restart_usec, default_timeout_start_usec, default_timeout_stop_usec;
 
         usec_t default_start_limit_interval;
         unsigned default_start_limit_burst;
 
-        struct rlimit *rlimit[RLIMIT_NLIMITS];
+        bool default_cpu_accounting;
+        bool default_memory_accounting;
+        bool default_blockio_accounting;
+
+        usec_t default_timer_accuracy_usec;
+
+        struct rlimit *rlimit[_RLIMIT_MAX];
 
         /* non-zero if we are reloading or reexecuting, */
         int n_reloading;
@@ -249,9 +280,12 @@ struct Manager {
 
         /* Reference to the kdbus bus control fd */
         int kdbus_fd;
+
+        /* Used for processing polkit authorization responses */
+        Hashmap *polkit_registry;
 };
 
-int manager_new(SystemdRunningAs running_as, Manager **m);
+int manager_new(SystemdRunningAs running_as, bool test_run, Manager **m);
 void manager_free(Manager *m);
 
 int manager_enumerate(Manager *m);
@@ -312,7 +346,16 @@ void manager_undo_generators(Manager *m);
 void manager_recheck_journal(Manager *m);
 
 void manager_set_show_status(Manager *m, ShowStatus mode);
+void manager_set_first_boot(Manager *m, bool b);
+
 void manager_status_printf(Manager *m, bool ephemeral, const char *status, const char *format, ...) _printf_(4,5);
 void manager_flip_auto_status(Manager *m, bool enable);
 
 Set *manager_get_units_requiring_mounts_for(Manager *m, const char *path);
+
+const char *manager_get_runtime_prefix(Manager *m);
+
+ManagerState manager_state(Manager *m);
+
+const char *manager_state_to_string(ManagerState m) _const_;
+ManagerState manager_state_from_string(const char *s) _pure_;
index 6265730..c468cd4 100644 (file)
@@ -63,8 +63,13 @@ typedef struct MountPoint {
 
 /* The first three entries we might need before SELinux is up. The
  * fourth (securityfs) is needed by IMA to load a custom policy. The
- * other ones we can delay until SELinux and IMA are loaded. */
+ * other ones we can delay until SELinux and IMA are loaded. When
+ * SMACK is enabled we need smackfs, too, so it's a fifth one. */
+#ifdef HAVE_SMACK
 #define N_EARLY_MOUNT 5
+#else
+#define N_EARLY_MOUNT 4
+#endif
 
 static const MountPoint mount_table[] = {
         { "sysfs",      "/sys",                      "sysfs",      NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV,
@@ -86,19 +91,17 @@ static const MountPoint mount_table[] = {
         { "devpts",     "/dev/pts",                  "devpts",     "mode=620,gid=" STRINGIFY(TTY_GID), MS_NOSUID|MS_NOEXEC,
           NULL,       MNT_IN_CONTAINER },
 #ifdef HAVE_SMACK
-        { "tmpfs",      "/run",                      "tmpfs",      "mode=755,smackfsroot=*", MS_NOSUID|MS_NODEV|MS_STRICTATIME,
+        { "tmpfs",      "/run",                      "tmpfs",      "mode=775,smackfsroot=*,gid=" STRINGIFY(RUN_GID), MS_NOSUID|MS_NODEV|MS_STRICTATIME,
           use_smack,  MNT_FATAL },
 #endif
-        { "tmpfs",      "/run",                      "tmpfs",      "mode=755", MS_NOSUID|MS_NODEV|MS_STRICTATIME,
+        { "tmpfs",      "/run",                      "tmpfs",      "mode=775,gid=" STRINGIFY(RUN_GID), MS_NOSUID|MS_NODEV|MS_STRICTATIME,
           NULL,       MNT_FATAL|MNT_IN_CONTAINER },
         { "tmpfs",      "/sys/fs/cgroup",            "tmpfs",      "mode=755", MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_STRICTATIME,
-          NULL,       MNT_IN_CONTAINER },
-#ifdef HAVE_XATTR
+          NULL,       MNT_FATAL|MNT_IN_CONTAINER },
         { "cgroup",     "/sys/fs/cgroup/systemd",    "cgroup",     "none,name=systemd,xattr", MS_NOSUID|MS_NOEXEC|MS_NODEV,
           NULL,       MNT_IN_CONTAINER },
-#endif
         { "cgroup",     "/sys/fs/cgroup/systemd",    "cgroup",     "none,name=systemd", MS_NOSUID|MS_NOEXEC|MS_NODEV,
-          NULL,       MNT_IN_CONTAINER },
+          NULL,       MNT_FATAL|MNT_IN_CONTAINER },
         { "pstore",     "/sys/fs/pstore",            "pstore",     NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV,
           NULL,       MNT_NONE },
 #ifdef ENABLE_EFI
@@ -188,7 +191,7 @@ static int mount_one(const MountPoint *p, bool relabel) {
                   p->type,
                   p->flags,
                   p->options) < 0) {
-                log_full((p->mode & MNT_FATAL) ? LOG_ERR : LOG_DEBUG, "Failed to mount %s: %m", p->where);
+                log_full((p->mode & MNT_FATAL) ? LOG_ERR : LOG_DEBUG, "Failed to mount %s at %s: %m", p->type, p->where);
                 return (p->mode & MNT_FATAL) ? -errno : 0;
         }
 
@@ -219,10 +222,10 @@ int mount_setup_early(void) {
 }
 
 int mount_cgroup_controllers(char ***join_controllers) {
-        int r;
-        char buf[LINE_MAX];
         _cleanup_set_free_free_ Set *controllers = NULL;
         _cleanup_fclose_ FILE *f;
+        char buf[LINE_MAX];
+        int r;
 
         /* Mount all available cgroup controllers that are built into the kernel. */
 
@@ -265,6 +268,7 @@ int mount_cgroup_controllers(char ***join_controllers) {
         }
 
         for (;;) {
+                _cleanup_free_ char *options = NULL, *controller = NULL, *where = NULL;
                 MountPoint p = {
                         .what = "cgroup",
                         .type = "cgroup",
@@ -272,7 +276,6 @@ int mount_cgroup_controllers(char ***join_controllers) {
                         .mode = MNT_IN_CONTAINER,
                 };
                 char ***k = NULL;
-                _cleanup_free_ char *options = NULL, *controller;
 
                 controller = set_steal_first(controllers);
                 if (!controller)
@@ -289,7 +292,7 @@ int mount_cgroup_controllers(char ***join_controllers) {
                         for (i = *k, j = *k; *i; i++) {
 
                                 if (!streq(*i, controller)) {
-                                        char _cleanup_free_ *t;
+                                        _cleanup_free_ char *t;
 
                                         t = set_remove(controllers, *i);
                                         if (!t) {
@@ -311,7 +314,11 @@ int mount_cgroup_controllers(char ***join_controllers) {
                         controller = NULL;
                 }
 
-                p.where = strappenda("/sys/fs/cgroup/", options);
+                where = strappend("/sys/fs/cgroup/", options);
+                if (!where)
+                        return log_oom();
+
+                p.where = where;
                 p.options = options;
 
                 r = mount_one(&p, true);
@@ -322,7 +329,11 @@ int mount_cgroup_controllers(char ***join_controllers) {
                         char **i;
 
                         for (i = *k; *i; i++) {
-                                char *t = strappenda("/sys/fs/cgroup/", *i);
+                                _cleanup_free_ char *t = NULL;
+
+                                t = strappend("/sys/fs/cgroup/", *i);
+                                if (!t)
+                                        return log_oom();
 
                                 r = symlink(options, t);
                                 if (r < 0 && errno != EEXIST) {
@@ -333,6 +344,12 @@ int mount_cgroup_controllers(char ***join_controllers) {
                 }
         }
 
+#ifndef CONFIG_TIZEN_WIP
+        /* Now that we mounted everything, let's make the tmpfs the
+         * cgroup file systems are mounted into read-only. */
+        mount("tmpfs", "/sys/fs/cgroup", "tmpfs", MS_REMOUNT|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_STRICTATIME|MS_RDONLY, "mode=755");
+#endif
+
         return 0;
 }
 
index a0cea1e..ec90b0a 100644 (file)
@@ -62,20 +62,6 @@ static const UnitActiveState state_translation_table[_MOUNT_STATE_MAX] = {
 static int mount_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata);
 static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata);
 
-static char* mount_test_option(const char *haystack, const char *needle) {
-        struct mntent me = { .mnt_opts = (char*) haystack };
-
-        assert(needle);
-
-        /* Like glibc's hasmntopt(), but works on a string, not a
-         * struct mntent */
-
-        if (!haystack)
-                return NULL;
-
-        return hasmntopt(&me, needle);
-}
-
 static bool mount_is_network(MountParameters *p) {
         assert(p);
 
@@ -137,10 +123,6 @@ static void mount_init(Unit *u) {
         m->timeout_usec = u->manager->default_timeout_start_usec;
         m->directory_mode = 0755;
 
-        exec_context_init(&m->exec_context);
-        kill_context_init(&m->kill_context);
-        cgroup_context_init(&m->cgroup_context);
-
         if (unit_has_name(u, "-.mount")) {
                 /* Don't allow start/stop for root directory */
                 u->refuse_manual_start = true;
@@ -181,7 +163,12 @@ static int mount_arm_timer(Mount *m) {
                 return sd_event_source_set_enabled(m->timer_event_source, SD_EVENT_ONESHOT);
         }
 
-        return sd_event_add_monotonic(UNIT(m)->manager->event, &m->timer_event_source, now(CLOCK_MONOTONIC) + m->timeout_usec, 0, mount_dispatch_timer, m);
+        return sd_event_add_time(
+                        UNIT(m)->manager->event,
+                        &m->timer_event_source,
+                        CLOCK_MONOTONIC,
+                        now(CLOCK_MONOTONIC) + m->timeout_usec, 0,
+                        mount_dispatch_timer, m);
 }
 
 static void mount_unwatch_control_pid(Mount *m) {
@@ -215,8 +202,6 @@ static void mount_done(Unit *u) {
         mount_parameters_done(&m->parameters_proc_self_mountinfo);
         mount_parameters_done(&m->parameters_fragment);
 
-        cgroup_context_done(&m->cgroup_context);
-        exec_context_done(&m->exec_context);
         m->exec_runtime = exec_runtime_unref(m->exec_runtime);
         exec_command_done_array(m->exec_command, _MOUNT_EXEC_COMMAND_MAX);
         m->control_command = NULL;
@@ -395,7 +380,8 @@ static int mount_add_default_dependencies(Mount *m) {
         if (!p)
                 return 0;
 
-        if (path_equal(m->where, "/"))
+        if (path_equal(m->where, "/") ||
+            path_equal(m->where, "/usr"))
                 return 0;
 
         if (mount_is_network(p)) {
@@ -433,57 +419,6 @@ static int mount_add_default_dependencies(Mount *m) {
         return 0;
 }
 
-static int mount_fix_timeouts(Mount *m) {
-        MountParameters *p;
-        const char *timeout = NULL;
-        Unit *other;
-        Iterator i;
-        usec_t u;
-        char *t;
-        int r;
-
-        assert(m);
-
-        p = get_mount_parameters_fragment(m);
-        if (!p)
-                return 0;
-
-        /* Allow configuration how long we wait for a device that
-         * backs a mount point to show up. This is useful to support
-         * endless device timeouts for devices that show up only after
-         * user input, like crypto devices. */
-
-        if ((timeout = mount_test_option(p->options, "comment=systemd.device-timeout")))
-                timeout += 31;
-        else if ((timeout = mount_test_option(p->options, "x-systemd.device-timeout")))
-                timeout += 25;
-        else
-                return 0;
-
-        t = strndup(timeout, strcspn(timeout, ",;" WHITESPACE));
-        if (!t)
-                return -ENOMEM;
-
-        r = parse_sec(t, &u);
-        free(t);
-
-        if (r < 0) {
-                log_warning_unit(UNIT(m)->id,
-                                 "Failed to parse timeout for %s, ignoring: %s",
-                                 m->where, timeout);
-                return r;
-        }
-
-        SET_FOREACH(other, UNIT(m)->dependencies[UNIT_AFTER], i) {
-                if (other->type != UNIT_DEVICE)
-                        continue;
-
-                other->job_timeout = u;
-        }
-
-        return 0;
-}
-
 static int mount_verify(Mount *m) {
         _cleanup_free_ char *e = NULL;
         bool b;
@@ -541,10 +476,6 @@ static int mount_add_extras(Mount *m) {
 
         path_kill_slashes(m->where);
 
-        r = unit_add_exec_dependencies(u, &m->exec_context);
-        if (r < 0)
-                return r;
-
         if (!u->description) {
                 r = unit_set_description(u, m->where);
                 if (r < 0)
@@ -563,24 +494,24 @@ static int mount_add_extras(Mount *m) {
         if (r < 0)
                 return r;
 
-        if (u->default_dependencies) {
-                r = mount_add_default_dependencies(m);
-                if (r < 0)
-                        return r;
-        }
-
-        r = unit_add_default_slice(u);
+        r = unit_patch_contexts(u);
         if (r < 0)
                 return r;
 
-        r = mount_fix_timeouts(m);
+        r = unit_add_exec_dependencies(u, &m->exec_context);
         if (r < 0)
                 return r;
 
-        r = unit_exec_context_defaults(u, &m->exec_context);
+        r = unit_add_default_slice(u, &m->cgroup_context);
         if (r < 0)
                 return r;
 
+        if (u->default_dependencies) {
+                r = mount_add_default_dependencies(m);
+                if (r < 0)
+                        return r;
+        }
+
         return 0;
 }
 
@@ -786,6 +717,7 @@ static int mount_spawn(Mount *m, ExecCommand *c, pid_t *_pid) {
                        UNIT(m)->manager->confirm_spawn,
                        UNIT(m)->manager->cgroup_supported,
                        UNIT(m)->cgroup_path,
+                       manager_get_runtime_prefix(UNIT(m)->manager),
                        UNIT(m)->id,
                        0,
                        NULL,
@@ -818,6 +750,8 @@ static void mount_enter_dead(Mount *m, MountResult f) {
         exec_runtime_destroy(m->exec_runtime);
         m->exec_runtime = exec_runtime_unref(m->exec_runtime);
 
+        exec_context_destroy_runtime_directory(&m->exec_context, manager_get_runtime_prefix(UNIT(m)->manager));
+
         mount_set_state(m, m->result != MOUNT_SUCCESS ? MOUNT_FAILED : MOUNT_DEAD);
 }
 
@@ -893,6 +827,23 @@ void warn_if_dir_nonempty(const char *unit, const char* where) {
                    NULL);
 }
 
+static int fail_if_symlink(const char *unit, const char* where) {
+        assert(where);
+
+        if (is_symlink(where) > 0) {
+                log_struct_unit(LOG_WARNING,
+                                unit,
+                                "MESSAGE=%s: Mount on symlink %s not allowed.",
+                                unit, where,
+                                "WHERE=%s", where,
+                                MESSAGE_ID(SD_MESSAGE_OVERMOUNTING),
+                                NULL);
+
+                return -ELOOP;
+        }
+        return 0;
+}
+
 static void mount_enter_unmounting(Mount *m) {
         int r;
 
@@ -904,6 +855,7 @@ static void mount_enter_unmounting(Mount *m) {
         if ((r = exec_command_set(
                              m->control_command,
                              "/bin/umount",
+                             "-n",
                              m->where,
                              NULL)) < 0)
                 goto fail;
@@ -942,10 +894,15 @@ static void mount_enter_mounting(Mount *m) {
         if (p && mount_is_bind(p))
                 mkdir_p_label(p->what, m->directory_mode);
 
+        r = fail_if_symlink(m->meta.id, m->where);
+        if (r < 0)
+                goto fail;
+
         if (m->from_fragment)
                 r = exec_command_set(
                                 m->control_command,
                                 "/bin/mount",
+                                m->sloppy_options ? "-ns" : "-n",
                                 m->parameters_fragment.what,
                                 m->where,
                                 "-t", m->parameters_fragment.fstype ? m->parameters_fragment.fstype : "auto",
@@ -993,6 +950,7 @@ static void mount_enter_remounting(Mount *m) {
                 r = exec_command_set(
                                 m->control_command,
                                 "/bin/mount",
+                                m->sloppy_options ? "-ns" : "-n",
                                 m->parameters_fragment.what,
                                 m->where,
                                 "-t", m->parameters_fragment.fstype ? m->parameters_fragment.fstype : "auto",
@@ -1388,7 +1346,7 @@ static int mount_add_one(
         _cleanup_free_ char *e = NULL, *w = NULL, *o = NULL, *f = NULL;
         bool load_extras = false;
         MountParameters *p;
-        bool delete;
+        bool delete, changed = false;
         Unit *u;
         int r;
 
@@ -1456,6 +1414,7 @@ static int mount_add_one(
                 }
 
                 unit_add_to_load_queue(u);
+                changed = true;
         } else {
                 delete = false;
 
@@ -1474,21 +1433,29 @@ static int mount_add_one(
                         /* Load in the extras later on, after we
                          * finished initialization of the unit */
                         load_extras = true;
+                        changed = true;
                 }
         }
 
-        if (!(w = strdup(what)) ||
-            !(o = strdup(options)) ||
-            !(f = strdup(fstype))) {
+        w = strdup(what);
+        o = strdup(options);
+        f = strdup(fstype);
+        if (!w || !o || !f) {
                 r = -ENOMEM;
                 goto fail;
         }
 
         p = &MOUNT(u)->parameters_proc_self_mountinfo;
+
+        changed = changed ||
+                !streq_ptr(p->options, options) ||
+                !streq_ptr(p->what, what) ||
+                !streq_ptr(p->fstype, fstype);
+
         if (set_flags) {
                 MOUNT(u)->is_mounted = true;
                 MOUNT(u)->just_mounted = !MOUNT(u)->from_proc_self_mountinfo;
-                MOUNT(u)->just_changed = !streq_ptr(p->options, o);
+                MOUNT(u)->just_changed = changed;
         }
 
         MOUNT(u)->from_proc_self_mountinfo = true;
@@ -1511,7 +1478,8 @@ static int mount_add_one(
                         goto fail;
         }
 
-        unit_add_to_dbus_queue(u);
+        if (changed)
+                unit_add_to_dbus_queue(u);
 
         return 0;
 
@@ -1667,20 +1635,20 @@ static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents,
                 Mount *mount = MOUNT(u);
 
                 if (!mount->is_mounted) {
-                        /* This has just been unmounted. */
 
                         mount->from_proc_self_mountinfo = false;
 
                         switch (mount->state) {
 
                         case MOUNT_MOUNTED:
+                                /* This has just been unmounted by
+                                 * somebody else, follow the state
+                                 * change. */
                                 mount_enter_dead(mount, MOUNT_SUCCESS);
                                 break;
 
                         default:
-                                mount_set_state(mount, mount->state);
                                 break;
-
                         }
 
                 } else if (mount->just_mounted || mount->just_changed) {
@@ -1691,6 +1659,9 @@ static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents,
 
                         case MOUNT_DEAD:
                         case MOUNT_FAILED:
+                                /* This has just been mounted by
+                                 * somebody else, follow the state
+                                 * change. */
                                 mount_enter_mounted(mount, MOUNT_SUCCESS);
                                 break;
 
@@ -1818,6 +1789,8 @@ const UnitVTable mount_vtable = {
 
         .get_timeout = mount_get_timeout,
 
+        .can_transient = true,
+
         .enumerate = mount_enumerate,
         .shutdown = mount_shutdown,
 
index a53423c..2dcb663 100644 (file)
@@ -88,6 +88,8 @@ struct Mount {
         bool just_mounted:1;
         bool just_changed:1;
 
+        bool sloppy_options;
+
         MountResult result;
         MountResult reload_result;
 
index c034bfd..fe95377 100644 (file)
@@ -42,6 +42,7 @@
 #include "mkdir.h"
 #include "dev-setup.h"
 #include "def.h"
+#include "label.h"
 
 typedef enum MountMode {
         /* This is ordered by priority! */
@@ -68,8 +69,9 @@ static int append_mounts(BindMount **p, char **strv, MountMode mode) {
         STRV_FOREACH(i, strv) {
 
                 (*p)->ignore = false;
+                (*p)->done = false;
 
-                if ((mode == INACCESSIBLE || mode == READONLY) && (*i)[0] == '-') {
+                if ((mode == INACCESSIBLE || mode == READONLY || mode == READWRITE) && (*i)[0] == '-') {
                         (*p)->ignore = true;
                         (*i)++;
                 }
@@ -122,8 +124,7 @@ static void drop_duplicates(BindMount *m, unsigned *n) {
                 if (previous && path_equal(f->path, previous->path))
                         continue;
 
-                t->path = f->path;
-                t->mode = f->mode;
+                *t = *f;
 
                 previous = t;
 
@@ -142,9 +143,8 @@ static int mount_dev(BindMount *m) {
                 "/dev/urandom\0"
                 "/dev/tty\0";
 
-        struct stat devnodes_stat[6] = {};
-        const char *d;
-        unsigned n = 0;
+        char temporary_mount[] = "/tmp/namespace-dev-XXXXXX";
+        const char *d, *dev = NULL, *devpts = NULL, *devshm = NULL, *devkdbus = NULL, *devhugepages = NULL, *devmqueue = NULL, *devlog = NULL, *devptmx = NULL;
         _cleanup_umask_ mode_t u;
         int r;
 
@@ -152,56 +152,124 @@ static int mount_dev(BindMount *m) {
 
         u = umask(0000);
 
-        /* First: record device mode_t and dev_t */
-        NULSTR_FOREACH(d, devnodes) {
-                r = stat(d, &devnodes_stat[n]);
-                if (r < 0) {
-                        if (errno != ENOENT)
-                                return -errno;
-                } else {
-                        if (!S_ISBLK(devnodes_stat[n].st_mode) &&
-                            !S_ISCHR(devnodes_stat[n].st_mode))
-                                return -EINVAL;
-                }
+        if (!mkdtemp(temporary_mount))
+                return -errno;
 
-                n++;
+        dev = strappenda(temporary_mount, "/dev");
+        mkdir(dev, 0755);
+        if (mount("tmpfs", dev, "tmpfs", MS_NOSUID|MS_STRICTATIME, "mode=755") < 0) {
+                r = -errno;
+                goto fail;
         }
 
-        assert(n == ELEMENTSOF(devnodes_stat));
+        devpts = strappenda(temporary_mount, "/dev/pts");
+        mkdir(devpts, 0755);
+        if (mount("/dev/pts", devpts, NULL, MS_BIND, NULL) < 0) {
+                r = -errno;
+                goto fail;
+        }
 
-        r = mount("tmpfs", "/dev", "tmpfs", MS_NOSUID|MS_STRICTATIME, "mode=755");
-        if (r < 0)
-                return m->ignore ? 0 : -errno;
+        devptmx = strappenda(temporary_mount, "/dev/ptmx");
+        symlink("pts/ptmx", devptmx);
 
+        devshm = strappenda(temporary_mount, "/dev/shm");
+        mkdir(devshm, 01777);
+        r = mount("/dev/shm", devshm, NULL, MS_BIND, NULL);
+        if (r < 0) {
+                r = -errno;
+                goto fail;
+        }
 
-        mkdir_p("/dev/pts", 0755);
+        devmqueue = strappenda(temporary_mount, "/dev/mqueue");
+        mkdir(devmqueue, 0755);
+        mount("/dev/mqueue", devmqueue, NULL, MS_BIND, NULL);
 
-        r = mount("devpts", "/dev/pts", "devpts", MS_NOSUID|MS_NOEXEC, "newinstance,ptmxmode=0666,mode=620,gid=" STRINGIFY(TTY_GID));
-        if (r < 0)
-                return m->ignore ? 0 : -errno;
+        devkdbus = strappenda(temporary_mount, "/dev/kdbus");
+        mkdir(devkdbus, 0755);
+        mount("/dev/kdbus", devkdbus, NULL, MS_BIND, NULL);
 
-        mkdir_p("/dev/shm", 0755);
+        devhugepages = strappenda(temporary_mount, "/dev/hugepages");
+        mkdir(devhugepages, 0755);
+        mount("/dev/hugepages", devhugepages, NULL, MS_BIND, NULL);
 
-        r = mount("tmpfs", "/dev/shm", "tmpfs", MS_NOSUID|MS_NODEV|MS_STRICTATIME, "mode=1777");
-        if (r < 0)
-                return m->ignore ? 0 : -errno;
+        devlog = strappenda(temporary_mount, "/dev/log");
+        symlink("/run/systemd/journal/dev-log", devlog);
 
-        /* Second: actually create it */
-        n = 0;
         NULSTR_FOREACH(d, devnodes) {
-                if (devnodes_stat[n].st_rdev == 0)
+                _cleanup_free_ char *dn = NULL;
+                struct stat st;
+
+                r = stat(d, &st);
+                if (r < 0) {
+
+                        if (errno == ENOENT)
+                                continue;
+
+                        r = -errno;
+                        goto fail;
+                }
+
+                if (!S_ISBLK(st.st_mode) &&
+                    !S_ISCHR(st.st_mode)) {
+                        r = -EINVAL;
+                        goto fail;
+                }
+
+                if (st.st_rdev == 0)
                         continue;
 
-                r = mknod(d, devnodes_stat[n].st_mode, devnodes_stat[n].st_rdev);
-                if (r < 0)
-                        return m->ignore ? 0 : -errno;
+                dn = strappend(temporary_mount, d);
+                if (!dn) {
+                        r = -ENOMEM;
+                        goto fail;
+                }
+
+                label_context_set(d, st.st_mode);
+                r = mknod(dn, st.st_mode, st.st_rdev);
+                label_context_clear();
+
+                if (r < 0) {
+                        r = -errno;
+                        goto fail;
+                }
+        }
 
-                n++;
+        dev_setup(temporary_mount);
+
+        if (mount(dev, "/dev/", NULL, MS_MOVE, NULL) < 0) {
+                r = -errno;
+                goto fail;
         }
 
-        dev_setup(NULL);
+        rmdir(dev);
+        rmdir(temporary_mount);
 
         return 0;
+
+fail:
+        if (devpts)
+                umount(devpts);
+
+        if (devshm)
+                umount(devshm);
+
+        if (devkdbus)
+                umount(devkdbus);
+
+        if (devhugepages)
+                umount(devhugepages);
+
+        if (devmqueue)
+                umount(devmqueue);
+
+        if (dev) {
+                umount(dev);
+                rmdir(dev);
+        }
+
+        rmdir(temporary_mount);
+
+        return r;
 }
 
 static int apply_mount(
@@ -216,17 +284,21 @@ static int apply_mount(
 
         switch (m->mode) {
 
-        case PRIVATE_DEV:
-                return mount_dev(m);
-
         case INACCESSIBLE:
+
+                /* First, get rid of everything that is below if there
+                 * is anything... Then, overmount it with an
+                 * inaccessible directory. */
+                umount_recursive(m->path, 0);
+
                 what = "/run/systemd/inaccessible";
                 break;
 
         case READONLY:
         case READWRITE:
-                what = m->path;
-                break;
+                /* Nothing to mount here, we just later toggle the
+                 * MS_RDONLY bit for the mount point */
+                return 0;
 
         case PRIVATE_TMP:
                 what = tmp_dir;
@@ -236,6 +308,9 @@ static int apply_mount(
                 what = var_tmp_dir;
                 break;
 
+        case PRIVATE_DEV:
+                return mount_dev(m);
+
         default:
                 assert_not_reached("Unknown mode");
         }
@@ -246,7 +321,7 @@ static int apply_mount(
         if (r >= 0)
                 log_debug("Successfully mounted %s to %s", what, m->path);
         else if (m->ignore && errno == ENOENT)
-                r = 0;
+                return 0;
 
         return r;
 }
@@ -256,14 +331,17 @@ static int make_read_only(BindMount *m) {
 
         assert(m);
 
-        if (m->mode != INACCESSIBLE && m->mode != READONLY)
-                return 0;
+        if (IN_SET(m->mode, INACCESSIBLE, READONLY))
+                r = bind_remount_recursive(m->path, true);
+        else if (IN_SET(m->mode, READWRITE, PRIVATE_TMP, PRIVATE_VAR_TMP, PRIVATE_DEV))
+                r = bind_remount_recursive(m->path, false);
+        else
+                r = 0;
 
-        r = mount(NULL, m->path, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY|MS_REC, NULL);
-        if (r < 0 && !(m->ignore && errno == ENOENT))
-                return -errno;
+        if (m->ignore && r == -ENOENT)
+                return 0;
 
-        return 0;
+        return r;
 }
 
 int setup_namespace(
@@ -273,6 +351,8 @@ int setup_namespace(
                 char* tmp_dir,
                 char* var_tmp_dir,
                 bool private_dev,
+                ProtectHome protect_home,
+                ProtectSystem protect_system,
                 unsigned mount_flags) {
 
         BindMount *m, *mounts = NULL;
@@ -289,10 +369,13 @@ int setup_namespace(
                 strv_length(read_write_dirs) +
                 strv_length(read_only_dirs) +
                 strv_length(inaccessible_dirs) +
-                private_dev;
+                private_dev +
+                (protect_home != PROTECT_HOME_NO ? 3 : 0) +
+                (protect_system != PROTECT_SYSTEM_NO ? 2 : 0) +
+                (protect_system == PROTECT_SYSTEM_FULL ? 1 : 0);
 
         if (n > 0) {
-                m = mounts = (BindMount *) alloca(n * sizeof(BindMount));
+                m = mounts = (BindMount *) alloca0(n * sizeof(BindMount));
                 r = append_mounts(&m, read_write_dirs, READWRITE);
                 if (r < 0)
                         return r;
@@ -323,30 +406,46 @@ int setup_namespace(
                         m++;
                 }
 
+                if (protect_home != PROTECT_HOME_NO) {
+                        r = append_mounts(&m, STRV_MAKE("-/home", "-/run/user", "-/root"), protect_home == PROTECT_HOME_READ_ONLY ? READONLY : INACCESSIBLE);
+                        if (r < 0)
+                                return r;
+                }
+
+                if (protect_system != PROTECT_SYSTEM_NO) {
+                        r = append_mounts(&m, protect_system == PROTECT_SYSTEM_FULL ? STRV_MAKE("/usr", "-/boot", "/etc") : STRV_MAKE("/usr", "-/boot"), READONLY);
+                        if (r < 0)
+                                return r;
+                }
+
                 assert(mounts + n == m);
 
                 qsort(mounts, n, sizeof(BindMount), mount_path_compare);
                 drop_duplicates(mounts, &n);
         }
 
-        /* Remount / as SLAVE so that nothing now mounted in the namespace
-           shows up in the parent */
-        if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL) < 0)
-                return -errno;
+        if (n > 0) {
+                /* Remount / as SLAVE so that nothing now mounted in the namespace
+                   shows up in the parent */
+                if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL) < 0)
+                        return -errno;
 
-        for (m = mounts; m < mounts + n; ++m) {
-                r = apply_mount(m, tmp_dir, var_tmp_dir);
-                if (r < 0)
-                        goto fail;
-        }
+                for (m = mounts; m < mounts + n; ++m) {
+                        r = apply_mount(m, tmp_dir, var_tmp_dir);
+                        if (r < 0)
+                                goto fail;
+                }
 
-        for (m = mounts; m < mounts + n; ++m) {
-                r = make_read_only(m);
-                if (r < 0)
-                        goto fail;
+                for (m = mounts; m < mounts + n; ++m) {
+                        r = make_read_only(m);
+                        if (r < 0)
+                                goto fail;
+                }
         }
 
-        /* Remount / as the desired mode */
+        /* Remount / as the desired mode. Not that this will not
+         * reestablish propagation from our side to the host, since
+         * what's disconnected is disconnected. */
         if (mount(NULL, "/", NULL, mount_flags | MS_REC, NULL) < 0) {
                 r = -errno;
                 goto fail;
@@ -355,9 +454,11 @@ int setup_namespace(
         return 0;
 
 fail:
-        for (m = mounts; m < mounts + n; ++m)
-                if (m->done)
-                        umount2(m->path, MNT_DETACH);
+        if (n > 0) {
+                for (m = mounts; m < mounts + n; ++m)
+                        if (m->done)
+                                umount2(m->path, MNT_DETACH);
+        }
 
         return r;
 }
@@ -517,3 +618,19 @@ fail:
 
         return r;
 }
+
+static const char *const protect_home_table[_PROTECT_HOME_MAX] = {
+        [PROTECT_HOME_NO] = "no",
+        [PROTECT_HOME_YES] = "yes",
+        [PROTECT_HOME_READ_ONLY] = "read-only",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(protect_home, ProtectHome);
+
+static const char *const protect_system_table[_PROTECT_SYSTEM_MAX] = {
+        [PROTECT_SYSTEM_NO] = "no",
+        [PROTECT_SYSTEM_YES] = "yes",
+        [PROTECT_SYSTEM_FULL] = "full",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(protect_system, ProtectSystem);
index fb1fc6e..9343fe3 100644 (file)
 
 #include <stdbool.h>
 
+#include "macro.h"
+
+typedef enum ProtectHome {
+        PROTECT_HOME_NO,
+        PROTECT_HOME_YES,
+        PROTECT_HOME_READ_ONLY,
+        _PROTECT_HOME_MAX,
+        _PROTECT_HOME_INVALID = -1
+} ProtectHome;
+
+typedef enum ProtectSystem {
+        PROTECT_SYSTEM_NO,
+        PROTECT_SYSTEM_YES,
+        PROTECT_SYSTEM_FULL,
+        _PROTECT_SYSTEM_MAX,
+        _PROTECT_SYSTEM_INVALID = -1
+} ProtectSystem;
+
 int setup_namespace(char **read_write_dirs,
                     char **read_only_dirs,
                     char **inaccessible_dirs,
                     char *tmp_dir,
                     char *var_tmp_dir,
                     bool private_dev,
+                    ProtectHome protect_home,
+                    ProtectSystem protect_system,
                     unsigned mount_flags);
 
 int setup_tmp_dirs(const char *id,
@@ -36,3 +56,9 @@ int setup_tmp_dirs(const char *id,
                   char **var_tmp_dir);
 
 int setup_netns(int netns_storage_socket[2]);
+
+const char* protect_home_to_string(ProtectHome p) _const_;
+ProtectHome protect_home_from_string(const char *s) _pure_;
+
+const char* protect_system_to_string(ProtectSystem p) _const_;
+ProtectSystem protect_system_from_string(const char *s) _pure_;
index a375dce..3e13825 100644 (file)
@@ -28,6 +28,8 @@
         <policy context="default">
                 <deny send_destination="org.freedesktop.systemd1"/>
 
+                <!-- Completely open to anyone -->
+
                 <allow send_destination="org.freedesktop.systemd1"
                        send_interface="org.freedesktop.DBus.Introspectable"/>
 
 
                 <allow send_destination="org.freedesktop.systemd1"
                        send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="ListUnitsFiltered"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
                        send_member="ListUnitFiles"/>
 
                 <allow send_destination="org.freedesktop.systemd1"
                        send_interface="org.freedesktop.systemd1.Manager"
                        send_member="GetDefaultTarget"/>
 
+                <!-- Managed via polkit or other criteria -->
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="StartUnit"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="StartUnitReplace"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="StopUnit"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="ReloadUnit"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="RestartUnit"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="TryRestartUnit"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="ReloadOrRestartUnit"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="ReloadOrTryRestartUnit"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="KillUnit"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="ResetFailedUnit"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="SetUnitProperties"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="StartTransientUnit"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="CancelJob"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="Reload"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="Reexecute"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="EnableUnitFiles"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="DisableUnitFiles"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="ReenableUnitFiles"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="LinkUnitFiles"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="PresetUnitFiles"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="PresetUnitFilesWithMode"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="MaskUnitFiles"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="UnmaskUnitFiles"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="SetDefaultTarget"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="PresetAllUnitFiles"/>
+
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Job"
+                       send_member="Cancel"/>
+
                 <allow receive_sender="org.freedesktop.systemd1"/>
         </policy>
 
index 51bdafa..387677d 100644 (file)
                 <annotate key="org.freedesktop.policykit.exec.path">@bindir@/systemd-stdio-bridge</annotate>
         </action>
 
+        <action id="org.freedesktop.systemd1.manage-units">
+                <_description>Manage system services or units</_description>
+                <_message>Authentication is required to manage system services or units.</_message>
+                <defaults>
+                        <allow_any>auth_admin</allow_any>
+                        <allow_inactive>auth_admin</allow_inactive>
+                        <allow_active>auth_admin_keep</allow_active>
+                </defaults>
+        </action>
+
+        <action id="org.freedesktop.systemd1.manage-unit-files">
+                <_description>Manage system service or unit files</_description>
+                <_message>Authentication is required to manage system service or unit files.</_message>
+                <defaults>
+                        <allow_any>auth_admin</allow_any>
+                        <allow_inactive>auth_admin</allow_inactive>
+                        <allow_active>auth_admin_keep</allow_active>
+                </defaults>
+        </action>
+
+        <action id="org.freedesktop.systemd1.reload-daemon">
+                <_description>Reload the systemd state</_description>
+                <_message>Authentication is required to reload the systemd state.</_message>
+                <defaults>
+                        <allow_any>auth_admin</allow_any>
+                        <allow_inactive>auth_admin</allow_inactive>
+                        <allow_active>auth_admin_keep</allow_active>
+                </defaults>
+        </action>
+
 </policyconfig>
index 1d6c6cc..f54c77f 100644 (file)
@@ -99,7 +99,8 @@ int path_spec_watch(PathSpec *s, sd_event_io_handler_t handler) {
                                 break;
                         }
 
-                        log_warning("Failed to add watch on %s: %m", s->path);
+                        log_warning("Failed to add watch on %s: %s", s->path,
+                                    errno == ENOSPC ? "too many watches" : strerror(-r));
                         r = -errno;
                         if (cut)
                                 *cut = tmp;
@@ -152,11 +153,7 @@ void path_spec_unwatch(PathSpec *s) {
         assert(s);
 
         s->event_source = sd_event_source_unref(s->event_source);
-
-        if (s->inotify_fd >= 0) {
-                close_nointr_nofail(s->inotify_fd);
-                s->inotify_fd = -1;
-        }
+        s->inotify_fd = safe_close(s->inotify_fd);
 }
 
 int path_spec_fd_event(PathSpec *s, uint32_t revents) {
@@ -761,16 +758,16 @@ DEFINE_STRING_TABLE_LOOKUP(path_state, PathState);
 static const char* const path_type_table[_PATH_TYPE_MAX] = {
         [PATH_EXISTS] = "PathExists",
         [PATH_EXISTS_GLOB] = "PathExistsGlob",
+        [PATH_DIRECTORY_NOT_EMPTY] = "DirectoryNotEmpty",
         [PATH_CHANGED] = "PathChanged",
         [PATH_MODIFIED] = "PathModified",
-        [PATH_DIRECTORY_NOT_EMPTY] = "DirectoryNotEmpty"
 };
 
 DEFINE_STRING_TABLE_LOOKUP(path_type, PathType);
 
 static const char* const path_result_table[_PATH_RESULT_MAX] = {
         [PATH_SUCCESS] = "success",
-        [PATH_FAILURE_RESOURCES] = "resources"
+        [PATH_FAILURE_RESOURCES] = "resources",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(path_result, PathResult);
index 16758fe..e8f9e8d 100644 (file)
@@ -51,9 +51,6 @@ static void scope_init(Unit *u) {
 
         s->timeout_stop_usec = u->manager->default_timeout_stop_usec;
 
-        cgroup_context_init(&s->cgroup_context);
-        kill_context_init(&s->kill_context);
-
         UNIT(s)->ignore_on_isolate = true;
         UNIT(s)->ignore_on_snapshot = true;
 }
@@ -63,8 +60,6 @@ static void scope_done(Unit *u) {
 
         assert(u);
 
-        cgroup_context_done(&s->cgroup_context);
-
         free(s->controller);
 
         s->timer_event_source = sd_event_source_unref(s->timer_event_source);
@@ -88,7 +83,12 @@ static int scope_arm_timer(Scope *s) {
                 return sd_event_source_set_enabled(s->timer_event_source, SD_EVENT_ONESHOT);
         }
 
-        return sd_event_add_monotonic(UNIT(s)->manager->event, &s->timer_event_source, now(CLOCK_MONOTONIC) + s->timeout_stop_usec, 0, scope_dispatch_timer, s);
+        return sd_event_add_time(
+                        UNIT(s)->manager->event,
+                        &s->timer_event_source,
+                        CLOCK_MONOTONIC,
+                        now(CLOCK_MONOTONIC) + s->timeout_stop_usec, 0,
+                        scope_dispatch_timer, s);
 }
 
 static void scope_set_state(Scope *s, ScopeState state) {
@@ -156,7 +156,11 @@ static int scope_load(Unit *u) {
         if (r < 0)
                 return r;
 
-        r = unit_add_default_slice(u);
+        r = unit_patch_contexts(u);
+        if (r < 0)
+                return r;
+
+        r = unit_add_default_slice(u, &s->cgroup_context);
         if (r < 0)
                 return r;
 
index 21c7a8c..cdbfb83 100644 (file)
@@ -169,7 +169,6 @@ void selinux_access_free(void) {
    still be generated if the access would be denied in enforcing mode.
 */
 int selinux_generic_access_check(
-                sd_bus *bus,
                 sd_bus_message *message,
                 const char *path,
                 const char *permission,
@@ -183,7 +182,6 @@ int selinux_generic_access_check(
         char **cmdline = NULL;
         int r = 0;
 
-        assert(bus);
         assert(message);
         assert(permission);
         assert(error);
@@ -255,7 +253,6 @@ finish:
 #else
 
 int selinux_generic_access_check(
-                sd_bus *bus,
                 sd_bus_message *message,
                 const char *path,
                 const char *permission,
index 9e89064..27d9e14 100644 (file)
 
 void selinux_access_free(void);
 
-int selinux_generic_access_check(sd_bus *bus, sd_bus_message *message, const char *path, const char *permission, sd_bus_error *error);
+int selinux_generic_access_check(sd_bus_message *message, const char *path, const char *permission, sd_bus_error *error);
 
 #ifdef HAVE_SELINUX
 
-#define selinux_access_check(bus, message, permission, error) \
-        selinux_generic_access_check(bus, message, NULL, permission, error)
-#define selinux_unit_access_check(unit, bus, message, permission, error) \
-        ({ Unit *_unit = (unit); selinux_generic_access_check(bus, message, _unit->fragment_path ?: _unit->fragment_path, permission, error); })
+#define selinux_access_check(message, permission, error) \
+        selinux_generic_access_check((message), NULL, (permission), (error))
+
+#define selinux_unit_access_check(unit, message, permission, error) \
+        ({                                                              \
+                Unit *_unit = (unit);                                   \
+                selinux_generic_access_check((message), _unit->fragment_path ?: _unit->fragment_path, (permission), (error)); \
+        })
 
 #else
 
-#define selinux_access_check(bus, message, permission, error) 0
-#define selinux_unit_access_check(unit, bus, message, permission, error) 0
+#define selinux_access_check(message, permission, error) 0
+#define selinux_unit_access_check(unit, message, permission, error) 0
 
 #endif
index 9a5d6b2..b419a27 100644 (file)
@@ -46,82 +46,82 @@ static int null_log(int type, const char *fmt, ...) {
 int selinux_setup(bool *loaded_policy) {
 
 #ifdef HAVE_SELINUX
-       int enforce = 0;
-       usec_t before_load, after_load;
-       security_context_t con;
-       int r;
-       union selinux_callback cb;
-
-       assert(loaded_policy);
-
-       /* Turn off all of SELinux' own logging, we want to do that */
-       cb.func_log = null_log;
-       selinux_set_callback(SELINUX_CB_LOG, cb);
-
-       /* Don't load policy in the initrd if we don't appear to have
-        * it.  For the real root, we check below if we've already
-        * loaded policy, and return gracefully.
-        */
-       if (in_initrd() && access(selinux_path(), F_OK) < 0)
-               return 0;
-
-       /* Already initialized by somebody else? */
-       r = getcon_raw(&con);
-       if (r == 0) {
-               bool initialized;
-
-               initialized = !streq(con, "kernel");
-               freecon(con);
-
-               if (initialized)
-                       return 0;
-       }
-
-       /* Make sure we have no fds open while loading the policy and
-        * transitioning */
-       log_close();
-
-       /* Now load the policy */
-       before_load = now(CLOCK_MONOTONIC);
-       r = selinux_init_load_policy(&enforce);
-       if (r == 0) {
-               char timespan[FORMAT_TIMESPAN_MAX];
-               char *label;
-
-               retest_selinux();
-
-               /* Transition to the new context */
-               r = label_get_create_label_from_exe(SYSTEMD_BINARY_PATH, &label);
-               if (r < 0 || label == NULL) {
-                       log_open();
-                       log_error("Failed to compute init label, ignoring.");
-               } else {
-                       r = setcon(label);
-
-                       log_open();
-                       if (r < 0)
-                               log_error("Failed to transition into init label '%s', ignoring.", label);
-
-                       label_free(label);
-               }
-
-               after_load = now(CLOCK_MONOTONIC);
-
-               log_info("Successfully loaded SELinux policy in %s.",
-                        format_timespan(timespan, sizeof(timespan), after_load - before_load, 0));
-
-               *loaded_policy = true;
-
-       } else {
-               log_open();
-
-               if (enforce > 0) {
-                       log_error("Failed to load SELinux policy. Freezing.");
-                       return -EIO;
-               } else
-                       log_debug("Unable to load SELinux policy. Ignoring.");
-       }
+        int enforce = 0;
+        usec_t before_load, after_load;
+        security_context_t con;
+        int r;
+        union selinux_callback cb;
+        bool initialized = false;
+
+        assert(loaded_policy);
+
+        /* Turn off all of SELinux' own logging, we want to do that */
+        cb.func_log = null_log;
+        selinux_set_callback(SELINUX_CB_LOG, cb);
+
+        /* Don't load policy in the initrd if we don't appear to have
+         * it.  For the real root, we check below if we've already
+         * loaded policy, and return gracefully.
+         */
+        if (in_initrd() && access(selinux_path(), F_OK) < 0)
+                return 0;
+
+        /* Already initialized by somebody else? */
+        r = getcon_raw(&con);
+        if (r == 0) {
+                initialized = !streq(con, "kernel");
+                freecon(con);
+        }
+
+        /* Make sure we have no fds open while loading the policy and
+         * transitioning */
+        log_close();
+
+        /* Now load the policy */
+        before_load = now(CLOCK_MONOTONIC);
+        r = selinux_init_load_policy(&enforce);
+        if (r == 0) {
+                char timespan[FORMAT_TIMESPAN_MAX];
+                char *label;
+
+                retest_selinux();
+
+                /* Transition to the new context */
+                r = label_get_create_label_from_exe(SYSTEMD_BINARY_PATH, &label);
+                if (r < 0 || label == NULL) {
+                        log_open();
+                        log_error("Failed to compute init label, ignoring.");
+                } else {
+                        r = setcon(label);
+
+                        log_open();
+                        if (r < 0)
+                                log_error("Failed to transition into init label '%s', ignoring.", label);
+
+                        label_free(label);
+                }
+
+                after_load = now(CLOCK_MONOTONIC);
+
+                log_info("Successfully loaded SELinux policy in %s.",
+                         format_timespan(timespan, sizeof(timespan), after_load - before_load, 0));
+
+                *loaded_policy = true;
+
+        } else {
+                log_open();
+
+                if (enforce > 0) {
+                        if (!initialized) {
+                                log_error("Failed to load SELinux policy. Freezing.");
+                                return -EIO;
+                        }
+
+                        log_warning("Failed to load new SELinux policy. Continuing with old policy.");
+                } else
+                        log_debug("Unable to load SELinux policy. Ignoring.");
+        }
 #endif
 
-       return 0;
+        return 0;
 }
index 242f3f9..9aaed5b 100644 (file)
 #include <dirent.h>
 #include <unistd.h>
 #include <sys/reboot.h>
+#include <linux/reboot.h>
+#include <sys/syscall.h>
 
+#include "async.h"
 #include "manager.h"
 #include "unit.h"
 #include "service.h"
 #include "bus-error.h"
 #include "bus-util.h"
 
-#ifdef HAVE_SYSV_COMPAT
-
-#define DEFAULT_SYSV_TIMEOUT_USEC (5*USEC_PER_MINUTE)
-
-typedef enum RunlevelType {
-        RUNLEVEL_UP,
-        RUNLEVEL_DOWN
-} RunlevelType;
-
-static const struct {
-        const char *path;
-        const char *target;
-        const RunlevelType type;
-} rcnd_table[] = {
-        /* Standard SysV runlevels for start-up */
-        { "rc1.d",  SPECIAL_RESCUE_TARGET,    RUNLEVEL_UP },
-        { "rc2.d",  SPECIAL_RUNLEVEL2_TARGET, RUNLEVEL_UP },
-        { "rc3.d",  SPECIAL_RUNLEVEL3_TARGET, RUNLEVEL_UP },
-        { "rc4.d",  SPECIAL_RUNLEVEL4_TARGET, RUNLEVEL_UP },
-        { "rc5.d",  SPECIAL_RUNLEVEL5_TARGET, RUNLEVEL_UP },
-
-        /* Standard SysV runlevels for shutdown */
-        { "rc0.d",  SPECIAL_POWEROFF_TARGET,  RUNLEVEL_DOWN },
-        { "rc6.d",  SPECIAL_REBOOT_TARGET,    RUNLEVEL_DOWN }
-
-        /* Note that the order here matters, as we read the
-           directories in this order, and we want to make sure that
-           sysv_start_priority is known when we first load the
-           unit. And that value we only know from S links. Hence
-           UP must be read before DOWN */
-};
-
-#define RUNLEVELS_UP "12345"
-#endif
-
 static const UnitActiveState state_translation_table[_SERVICE_STATE_MAX] = {
         [SERVICE_DEAD] = UNIT_INACTIVE,
         [SERVICE_START_PRE] = UNIT_ACTIVATING,
@@ -135,21 +103,10 @@ static void service_init(Unit *u) {
         s->timeout_stop_usec = u->manager->default_timeout_stop_usec;
         s->restart_usec = u->manager->default_restart_usec;
         s->type = _SERVICE_TYPE_INVALID;
-
-#ifdef HAVE_SYSV_COMPAT
-        s->sysv_start_priority = -1;
-        s->sysv_start_priority_from_rcnd = -1;
-#endif
         s->socket_fd = -1;
         s->guess_main_pid = true;
 
-        exec_context_init(&s->exec_context);
-        kill_context_init(&s->kill_context);
-        cgroup_context_init(&s->cgroup_context);
-
-        RATELIMIT_INIT(s->start_limit,
-                       u->manager->default_start_limit_interval,
-                       u->manager->default_start_limit_burst);
+        RATELIMIT_INIT(s->start_limit, u->manager->default_start_limit_interval, u->manager->default_start_limit_burst);
 
         s->control_command_id = _SERVICE_EXEC_COMMAND_INVALID;
 }
@@ -226,8 +183,7 @@ static void service_close_socket_fd(Service *s) {
         if (s->socket_fd < 0)
                 return;
 
-        close_nointr_nofail(s->socket_fd);
-        s->socket_fd = -1;
+        s->socket_fd = asynchronous_close(s->socket_fd);
 }
 
 static void service_connection_unref(Service *s) {
@@ -264,7 +220,12 @@ static void service_start_watchdog(Service *s) {
 
                 r = sd_event_source_set_enabled(s->watchdog_event_source, SD_EVENT_ONESHOT);
         } else {
-                r = sd_event_add_monotonic(UNIT(s)->manager->event, &s->watchdog_event_source, s->watchdog_timestamp.monotonic + s->watchdog_usec, 0, service_dispatch_watchdog, s);
+                r = sd_event_add_time(
+                                UNIT(s)->manager->event,
+                                &s->watchdog_event_source,
+                                CLOCK_MONOTONIC,
+                                s->watchdog_timestamp.monotonic + s->watchdog_usec, 0,
+                                service_dispatch_watchdog, s);
                 if (r < 0) {
                         log_warning_unit(UNIT(s)->id, "%s failed to add watchdog timer: %s", UNIT(s)->id, strerror(-r));
                         return;
@@ -294,30 +255,20 @@ static void service_done(Unit *u) {
         free(s->pid_file);
         s->pid_file = NULL;
 
-#ifdef HAVE_SYSV_COMPAT
-        free(s->sysv_runlevels);
-        s->sysv_runlevels = NULL;
-#endif
-
         free(s->status_text);
         s->status_text = NULL;
 
-        cgroup_context_done(&s->cgroup_context);
-        exec_context_done(&s->exec_context);
+        free(s->reboot_arg);
+        s->reboot_arg = NULL;
+
         s->exec_runtime = exec_runtime_unref(s->exec_runtime);
         exec_command_free_array(s->exec_command, _SERVICE_EXEC_COMMAND_MAX);
         s->control_command = NULL;
         s->main_command = NULL;
 
-        set_free(s->restart_ignore_status.code);
-        s->restart_ignore_status.code = NULL;
-        set_free(s->restart_ignore_status.signal);
-        s->restart_ignore_status.signal = NULL;
-
-        set_free(s->success_status.code);
-        s->success_status.code = NULL;
-        set_free(s->success_status.signal);
-        s->success_status.signal = NULL;
+        exit_status_set_free(&s->restart_prevent_status);
+        exit_status_set_free(&s->restart_force_status);
+        exit_status_set_free(&s->success_status);
 
         /* This will leak a process, but at least no memory or any of
          * our resources */
@@ -354,737 +305,14 @@ static int service_arm_timer(Service *s, usec_t usec) {
                 return sd_event_source_set_enabled(s->timer_event_source, SD_EVENT_ONESHOT);
         }
 
-        return sd_event_add_monotonic(UNIT(s)->manager->event, &s->timer_event_source, now(CLOCK_MONOTONIC) + usec, 0, service_dispatch_timer, s);
-}
-
-#ifdef HAVE_SYSV_COMPAT
-static char *sysv_translate_name(const char *name) {
-        char *r;
-
-        r = new(char, strlen(name) + sizeof(".service"));
-        if (!r)
-                return NULL;
-
-        if (endswith(name, ".sh"))
-                /* Drop .sh suffix */
-                strcpy(stpcpy(r, name) - 3, ".service");
-        else
-                /* Normal init script name */
-                strcpy(stpcpy(r, name), ".service");
-
-        return r;
-}
-
-static int sysv_translate_facility(const char *name, const char *filename, char **_r) {
-
-        /* We silently ignore the $ prefix here. According to the LSB
-         * spec it simply indicates whether something is a
-         * standardized name or a distribution-specific one. Since we
-         * just follow what already exists and do not introduce new
-         * uses or names we don't care who introduced a new name. */
-
-        static const char * const table[] = {
-                /* LSB defined facilities */
-                "local_fs",             NULL,
-                "network",              SPECIAL_NETWORK_TARGET,
-                "named",                SPECIAL_NSS_LOOKUP_TARGET,
-                "portmap",              SPECIAL_RPCBIND_TARGET,
-                "remote_fs",            SPECIAL_REMOTE_FS_TARGET,
-                "syslog",               NULL,
-                "time",                 SPECIAL_TIME_SYNC_TARGET,
-        };
-
-        unsigned i;
-        char *r;
-        const char *n;
-
-        assert(name);
-        assert(_r);
-
-        n = *name == '$' ? name + 1 : name;
-
-        for (i = 0; i < ELEMENTSOF(table); i += 2) {
-
-                if (!streq(table[i], n))
-                        continue;
-
-                if (!table[i+1])
-                        return 0;
-
-                r = strdup(table[i+1]);
-                if (!r)
-                        return log_oom();
-
-                goto finish;
-        }
-
-        /* If we don't know this name, fallback heuristics to figure
-         * out whether something is a target or a service alias. */
-
-        if (*name == '$') {
-                if (!unit_prefix_is_valid(n))
-                        return -EINVAL;
-
-                /* Facilities starting with $ are most likely targets */
-                r = unit_name_build(n, NULL, ".target");
-        } else if (filename && streq(name, filename))
-                /* Names equaling the file name of the services are redundant */
-                return 0;
-        else
-                /* Everything else we assume to be normal service names */
-                r = sysv_translate_name(n);
-
-        if (!r)
-                return -ENOMEM;
-
-finish:
-        *_r = r;
-
-        return 1;
-}
-
-static int sysv_fix_order(Service *s) {
-        Unit *other;
-        int r;
-
-        assert(s);
-
-        if (s->sysv_start_priority < 0)
-                return 0;
-
-        /* For each pair of services where at least one lacks a LSB
-         * header, we use the start priority value to order things. */
-
-        LIST_FOREACH(units_by_type, other, UNIT(s)->manager->units_by_type[UNIT_SERVICE]) {
-                Service *t;
-                UnitDependency d;
-                bool special_s, special_t;
-
-                t = SERVICE(other);
-
-                if (s == t)
-                        continue;
-
-                if (UNIT(t)->load_state != UNIT_LOADED)
-                        continue;
-
-                if (t->sysv_start_priority < 0)
-                        continue;
-
-                /* If both units have modern headers we don't care
-                 * about the priorities */
-                if ((UNIT(s)->fragment_path || s->sysv_has_lsb) &&
-                    (UNIT(t)->fragment_path || t->sysv_has_lsb))
-                        continue;
-
-                special_s = s->sysv_runlevels && !chars_intersect(RUNLEVELS_UP, s->sysv_runlevels);
-                special_t = t->sysv_runlevels && !chars_intersect(RUNLEVELS_UP, t->sysv_runlevels);
-
-                if (special_t && !special_s)
-                        d = UNIT_AFTER;
-                else if (special_s && !special_t)
-                        d = UNIT_BEFORE;
-                else if (t->sysv_start_priority < s->sysv_start_priority)
-                        d = UNIT_AFTER;
-                else if (t->sysv_start_priority > s->sysv_start_priority)
-                        d = UNIT_BEFORE;
-                else
-                        continue;
-
-                /* FIXME: Maybe we should compare the name here lexicographically? */
-
-                if ((r = unit_add_dependency(UNIT(s), d, UNIT(t), true)) < 0)
-                        return r;
-        }
-
-        return 0;
-}
-
-static ExecCommand *exec_command_new(const char *path, const char *arg1) {
-        ExecCommand *c;
-
-        if (!(c = new0(ExecCommand, 1)))
-                return NULL;
-
-        if (!(c->path = strdup(path))) {
-                free(c);
-                return NULL;
-        }
-
-        if (!(c->argv = strv_new(path, arg1, NULL))) {
-                free(c->path);
-                free(c);
-                return NULL;
-        }
-
-        return c;
-}
-
-static int sysv_exec_commands(Service *s, const bool supports_reload) {
-        ExecCommand *c;
-
-        assert(s);
-        assert(s->is_sysv);
-        assert(UNIT(s)->source_path);
-
-        c = exec_command_new(UNIT(s)->source_path, "start");
-        if (!c)
-                return -ENOMEM;
-        exec_command_append_list(s->exec_command+SERVICE_EXEC_START, c);
-
-        c = exec_command_new(UNIT(s)->source_path, "stop");
-        if (!c)
-                return -ENOMEM;
-        exec_command_append_list(s->exec_command+SERVICE_EXEC_STOP, c);
-
-        if (supports_reload) {
-                c = exec_command_new(UNIT(s)->source_path, "reload");
-                if (!c)
-                        return -ENOMEM;
-                exec_command_append_list(s->exec_command+SERVICE_EXEC_RELOAD, c);
-        }
-
-        return 0;
+        return sd_event_add_time(
+                        UNIT(s)->manager->event,
+                        &s->timer_event_source,
+                        CLOCK_MONOTONIC,
+                        now(CLOCK_MONOTONIC) + usec, 0,
+                        service_dispatch_timer, s);
 }
 
-static bool usage_contains_reload(const char *line) {
-        return (strcasestr(line, "{reload|") ||
-                strcasestr(line, "{reload}") ||
-                strcasestr(line, "{reload\"") ||
-                strcasestr(line, "|reload|") ||
-                strcasestr(line, "|reload}") ||
-                strcasestr(line, "|reload\""));
-}
-
-static int service_load_sysv_path(Service *s, const char *path) {
-        FILE *f;
-        Unit *u;
-        unsigned line = 0;
-        int r;
-        enum {
-                NORMAL,
-                DESCRIPTION,
-                LSB,
-                LSB_DESCRIPTION,
-                USAGE_CONTINUATION
-        } state = NORMAL;
-        char *short_description = NULL, *long_description = NULL, *chkconfig_description = NULL, *description;
-        struct stat st;
-        bool supports_reload = false;
-
-        assert(s);
-        assert(path);
-
-        u = UNIT(s);
-
-        f = fopen(path, "re");
-        if (!f) {
-                r = errno == ENOENT ? 0 : -errno;
-                goto finish;
-        }
-
-        if (fstat(fileno(f), &st) < 0) {
-                r = -errno;
-                goto finish;
-        }
-
-        free(u->source_path);
-        u->source_path = strdup(path);
-        if (!u->source_path) {
-                r = -ENOMEM;
-                goto finish;
-        }
-        u->source_mtime = timespec_load(&st.st_mtim);
-
-        if (null_or_empty(&st)) {
-                u->load_state = UNIT_MASKED;
-                r = 0;
-                goto finish;
-        }
-
-        s->is_sysv = true;
-
-        while (!feof(f)) {
-                char l[LINE_MAX], *t;
-
-                if (!fgets(l, sizeof(l), f)) {
-                        if (feof(f))
-                                break;
-
-                        r = -errno;
-                        log_error_unit(u->id,
-                                       "Failed to read configuration file '%s': %s",
-                                       path, strerror(-r));
-                        goto finish;
-                }
-
-                line++;
-
-                t = strstrip(l);
-                if (*t != '#') {
-                        /* Try to figure out whether this init script supports
-                         * the reload operation. This heuristic looks for
-                         * "Usage" lines which include the reload option. */
-                        if ( state == USAGE_CONTINUATION ||
-                            (state == NORMAL && strcasestr(t, "usage"))) {
-                                if (usage_contains_reload(t)) {
-                                        supports_reload = true;
-                                        state = NORMAL;
-                                } else if (t[strlen(t)-1] == '\\')
-                                        state = USAGE_CONTINUATION;
-                                else
-                                        state = NORMAL;
-                        }
-
-                        continue;
-                }
-
-                if (state == NORMAL && streq(t, "### BEGIN INIT INFO")) {
-                        state = LSB;
-                        s->sysv_has_lsb = true;
-                        continue;
-                }
-
-                if ((state == LSB_DESCRIPTION || state == LSB) && streq(t, "### END INIT INFO")) {
-                        state = NORMAL;
-                        continue;
-                }
-
-                t++;
-                t += strspn(t, WHITESPACE);
-
-                if (state == NORMAL) {
-
-                        /* Try to parse Red Hat style chkconfig headers */
-
-                        if (startswith_no_case(t, "chkconfig:")) {
-                                int start_priority;
-                                char runlevels[16], *k;
-
-                                state = NORMAL;
-
-                                if (sscanf(t+10, "%15s %i %*i",
-                                           runlevels,
-                                           &start_priority) != 2) {
-
-                                        log_warning_unit(u->id,
-                                                         "[%s:%u] Failed to parse chkconfig line. Ignoring.",
-                                                         path, line);
-                                        continue;
-                                }
-
-                                /* A start priority gathered from the
-                                 * symlink farms is preferred over the
-                                 * data from the LSB header. */
-                                if (start_priority < 0 || start_priority > 99)
-                                        log_warning_unit(u->id,
-                                                         "[%s:%u] Start priority out of range. Ignoring.",
-                                                         path, line);
-                                else
-                                        s->sysv_start_priority = start_priority;
-
-                                char_array_0(runlevels);
-                                k = delete_chars(runlevels, WHITESPACE "-");
-
-                                if (k[0]) {
-                                        char *d;
-
-                                        if (!(d = strdup(k))) {
-                                                r = -ENOMEM;
-                                                goto finish;
-                                        }
-
-                                        free(s->sysv_runlevels);
-                                        s->sysv_runlevels = d;
-                                }
-
-                        } else if (startswith_no_case(t, "description:")) {
-
-                                size_t k = strlen(t);
-                                char *d;
-                                const char *j;
-
-                                if (t[k-1] == '\\') {
-                                        state = DESCRIPTION;
-                                        t[k-1] = 0;
-                                }
-
-                                if ((j = strstrip(t+12)) && *j) {
-                                        if (!(d = strdup(j))) {
-                                                r = -ENOMEM;
-                                                goto finish;
-                                        }
-                                } else
-                                        d = NULL;
-
-                                free(chkconfig_description);
-                                chkconfig_description = d;
-
-                        } else if (startswith_no_case(t, "pidfile:")) {
-
-                                char *fn;
-
-                                state = NORMAL;
-
-                                fn = strstrip(t+8);
-                                if (!path_is_absolute(fn)) {
-                                        log_warning_unit(u->id,
-                                                         "[%s:%u] PID file not absolute. Ignoring.",
-                                                         path, line);
-                                        continue;
-                                }
-
-                                if (!(fn = strdup(fn))) {
-                                        r = -ENOMEM;
-                                        goto finish;
-                                }
-
-                                free(s->pid_file);
-                                s->pid_file = fn;
-                        }
-
-                } else if (state == DESCRIPTION) {
-
-                        /* Try to parse Red Hat style description
-                         * continuation */
-
-                        size_t k = strlen(t);
-                        char *j;
-
-                        if (t[k-1] == '\\')
-                                t[k-1] = 0;
-                        else
-                                state = NORMAL;
-
-                        if ((j = strstrip(t)) && *j) {
-                                char *d = NULL;
-
-                                if (chkconfig_description)
-                                        d = strjoin(chkconfig_description, " ", j, NULL);
-                                else
-                                        d = strdup(j);
-
-                                if (!d) {
-                                        r = -ENOMEM;
-                                        goto finish;
-                                }
-
-                                free(chkconfig_description);
-                                chkconfig_description = d;
-                        }
-
-                } else if (state == LSB || state == LSB_DESCRIPTION) {
-
-                        if (startswith_no_case(t, "Provides:")) {
-                                char *i, *w;
-                                size_t z;
-
-                                state = LSB;
-
-                                FOREACH_WORD_QUOTED(w, z, t+9, i) {
-                                        char *n, *m;
-
-                                        if (!(n = strndup(w, z))) {
-                                                r = -ENOMEM;
-                                                goto finish;
-                                        }
-
-                                        r = sysv_translate_facility(n, basename(path), &m);
-                                        free(n);
-
-                                        if (r < 0)
-                                                goto finish;
-
-                                        if (r == 0)
-                                                continue;
-
-                                        if (unit_name_to_type(m) == UNIT_SERVICE)
-                                                r = unit_merge_by_name(u, m);
-                                        else
-                                                /* NB: SysV targets
-                                                 * which are provided
-                                                 * by a service are
-                                                 * pulled in by the
-                                                 * services, as an
-                                                 * indication that the
-                                                 * generic service is
-                                                 * now available. This
-                                                 * is strictly
-                                                 * one-way. The
-                                                 * targets do NOT pull
-                                                 * in the SysV
-                                                 * services! */
-                                                r = unit_add_two_dependencies_by_name(u, UNIT_BEFORE, UNIT_WANTS, m, NULL, true);
-
-                                        if (r < 0)
-                                                log_error_unit(u->id,
-                                                               "[%s:%u] Failed to add LSB Provides name %s, ignoring: %s",
-                                                               path, line, m, strerror(-r));
-
-                                        free(m);
-                                }
-
-                        } else if (startswith_no_case(t, "Required-Start:") ||
-                                   startswith_no_case(t, "Should-Start:") ||
-                                   startswith_no_case(t, "X-Start-Before:") ||
-                                   startswith_no_case(t, "X-Start-After:")) {
-                                char *i, *w;
-                                size_t z;
-
-                                state = LSB;
-
-                                FOREACH_WORD_QUOTED(w, z, strchr(t, ':')+1, i) {
-                                        char *n, *m;
-
-                                        if (!(n = strndup(w, z))) {
-                                                r = -ENOMEM;
-                                                goto finish;
-                                        }
-
-                                        r = sysv_translate_facility(n, basename(path), &m);
-                                        if (r < 0) {
-                                                log_error_unit(u->id,
-                                                               "[%s:%u] Failed to translate LSB dependency %s, ignoring: %s",
-                                                               path, line, n, strerror(-r));
-                                                free(n);
-                                                continue;
-                                        }
-
-                                        free(n);
-
-                                        if (r == 0)
-                                                continue;
-
-                                        r = unit_add_dependency_by_name(u, startswith_no_case(t, "X-Start-Before:") ? UNIT_BEFORE : UNIT_AFTER, m, NULL, true);
-
-                                        if (r < 0)
-                                                log_error_unit(u->id, "[%s:%u] Failed to add dependency on %s, ignoring: %s",
-                                                               path, line, m, strerror(-r));
-
-                                        free(m);
-                                }
-                        } else if (startswith_no_case(t, "Default-Start:")) {
-                                char *k, *d;
-
-                                state = LSB;
-
-                                k = delete_chars(t+14, WHITESPACE "-");
-
-                                if (k[0] != 0) {
-                                        if (!(d = strdup(k))) {
-                                                r = -ENOMEM;
-                                                goto finish;
-                                        }
-
-                                        free(s->sysv_runlevels);
-                                        s->sysv_runlevels = d;
-                                }
-
-                        } else if (startswith_no_case(t, "Description:")) {
-                                char *d, *j;
-
-                                state = LSB_DESCRIPTION;
-
-                                if ((j = strstrip(t+12)) && *j) {
-                                        if (!(d = strdup(j))) {
-                                                r = -ENOMEM;
-                                                goto finish;
-                                        }
-                                } else
-                                        d = NULL;
-
-                                free(long_description);
-                                long_description = d;
-
-                        } else if (startswith_no_case(t, "Short-Description:")) {
-                                char *d, *j;
-
-                                state = LSB;
-
-                                if ((j = strstrip(t+18)) && *j) {
-                                        if (!(d = strdup(j))) {
-                                                r = -ENOMEM;
-                                                goto finish;
-                                        }
-                                } else
-                                        d = NULL;
-
-                                free(short_description);
-                                short_description = d;
-
-                        } else if (state == LSB_DESCRIPTION) {
-
-                                if (startswith(l, "#\t") || startswith(l, "#  ")) {
-                                        char *j;
-
-                                        if ((j = strstrip(t)) && *j) {
-                                                char *d = NULL;
-
-                                                if (long_description)
-                                                        d = strjoin(long_description, " ", t, NULL);
-                                                else
-                                                        d = strdup(j);
-
-                                                if (!d) {
-                                                        r = -ENOMEM;
-                                                        goto finish;
-                                                }
-
-                                                free(long_description);
-                                                long_description = d;
-                                        }
-
-                                } else
-                                        state = LSB;
-                        }
-                }
-        }
-
-        if ((r = sysv_exec_commands(s, supports_reload)) < 0)
-                goto finish;
-
-        if (s->sysv_runlevels && !chars_intersect(RUNLEVELS_UP, s->sysv_runlevels)) {
-                /* If there a runlevels configured for this service
-                 * but none of the standard ones, then we assume this
-                 * is some special kind of service (which might be
-                 * needed for early boot) and don't create any links
-                 * to it. */
-
-                UNIT(s)->default_dependencies = false;
-
-                /* Don't timeout special services during boot (like fsck) */
-                s->timeout_start_usec = 0;
-                s->timeout_stop_usec = 0;
-        } else {
-                s->timeout_start_usec = DEFAULT_SYSV_TIMEOUT_USEC;
-                s->timeout_stop_usec = DEFAULT_SYSV_TIMEOUT_USEC;
-        }
-
-        /* Special setting for all SysV services */
-        s->type = SERVICE_FORKING;
-        s->remain_after_exit = !s->pid_file;
-        s->guess_main_pid = false;
-        s->restart = SERVICE_RESTART_NO;
-        s->exec_context.ignore_sigpipe = false;
-        s->kill_context.kill_mode = KILL_PROCESS;
-
-        /* We use the long description only if
-         * no short description is set. */
-
-        if (short_description)
-                description = short_description;
-        else if (chkconfig_description)
-                description = chkconfig_description;
-        else if (long_description)
-                description = long_description;
-        else
-                description = NULL;
-
-        if (description) {
-                char *d;
-
-                if (!(d = strappend(s->sysv_has_lsb ? "LSB: " : "SYSV: ", description))) {
-                        r = -ENOMEM;
-                        goto finish;
-                }
-
-                u->description = d;
-        }
-
-        /* The priority that has been set in /etc/rcN.d/ hierarchies
-         * takes precedence over what is stored as default in the LSB
-         * header */
-        if (s->sysv_start_priority_from_rcnd >= 0)
-                s->sysv_start_priority = s->sysv_start_priority_from_rcnd;
-
-        u->load_state = UNIT_LOADED;
-        r = 0;
-
-finish:
-
-        if (f)
-                fclose(f);
-
-        free(short_description);
-        free(long_description);
-        free(chkconfig_description);
-
-        return r;
-}
-
-static int service_load_sysv_name(Service *s, const char *name) {
-        char **p;
-
-        assert(s);
-        assert(name);
-
-        /* For SysV services we strip the *.sh suffixes. */
-        if (endswith(name, ".sh.service"))
-                return -ENOENT;
-
-        STRV_FOREACH(p, UNIT(s)->manager->lookup_paths.sysvinit_path) {
-                char *path;
-                int r;
-
-                path = strjoin(*p, "/", name, NULL);
-                if (!path)
-                        return -ENOMEM;
-
-                assert(endswith(path, ".service"));
-                path[strlen(path)-8] = 0;
-
-                r = service_load_sysv_path(s, path);
-
-                if (r >= 0 && UNIT(s)->load_state == UNIT_STUB) {
-                        /* Try *.sh source'able init scripts */
-                        strcat(path, ".sh");
-                        r = service_load_sysv_path(s, path);
-                }
-                free(path);
-
-                if (r < 0)
-                        return r;
-
-                if (UNIT(s)->load_state != UNIT_STUB)
-                        break;
-        }
-
-        return 0;
-}
-
-static int service_load_sysv(Service *s) {
-        const char *t;
-        Iterator i;
-        int r;
-
-        assert(s);
-
-        /* Load service data from SysV init scripts, preferably with
-         * LSB headers ... */
-
-        if (strv_isempty(UNIT(s)->manager->lookup_paths.sysvinit_path))
-                return 0;
-
-        if ((t = UNIT(s)->id))
-                if ((r = service_load_sysv_name(s, t)) < 0)
-                        return r;
-
-        if (UNIT(s)->load_state == UNIT_STUB)
-                SET_FOREACH(t, UNIT(s)->names, i) {
-                        if (t == UNIT(s)->id)
-                                continue;
-
-                        if ((r = service_load_sysv_name(s, t)) < 0)
-                                return r;
-
-                        if (UNIT(s)->load_state != UNIT_STUB)
-                                break;
-                }
-
-        return 0;
-}
-#endif
-
 static int service_verify(Service *s) {
         assert(s);
 
@@ -1103,7 +331,12 @@ static int service_verify(Service *s) {
         }
 
         if (s->type == SERVICE_ONESHOT && s->restart != SERVICE_RESTART_NO) {
-                log_error_unit(UNIT(s)->id, "%s has Restart setting other than no, which isn't allowed for Type=oneshot services. Refusing.", UNIT(s)->id);
+                log_error_unit(UNIT(s)->id, "%s has Restart= setting other than no, which isn't allowed for Type=oneshot services. Refusing.", UNIT(s)->id);
+                return -EINVAL;
+        }
+
+        if (s->type == SERVICE_ONESHOT && !exit_status_set_is_empty(&s->restart_force_status)) {
+                log_error_unit(UNIT(s)->id, "%s has RestartForceStatus= set, which isn't allowed for Type=oneshot services. Refusing.", UNIT(s)->id);
                 return -EINVAL;
         }
 
@@ -1142,7 +375,7 @@ static int service_add_default_extra_dependencies(Service *s) {
         if (!t)
                 return -ENOMEM;
 
-        ignore = set_contains(UNIT(s)->manager->dep_ignore_list, t);
+        ignore = hashmap_contains(UNIT(s)->manager->dep_ignore_list, t);
         free(t);
         if (ignore)
                 return 0;
@@ -1152,6 +385,7 @@ static int service_add_default_extra_dependencies(Service *s) {
                 if (r < 0)
                         return r;
         }
+
         return 0;
 }
 #endif
@@ -1211,15 +445,6 @@ static int service_load(Unit *u) {
         if (r < 0)
                 return r;
 
-#ifdef HAVE_SYSV_COMPAT
-        /* Load a classic init script as a fallback, if we couldn't find anything */
-        if (u->load_state == UNIT_STUB) {
-                r = service_load_sysv(s);
-                if (r < 0)
-                        return r;
-        }
-#endif
-
         /* Still nothing found? Then let's give up */
         if (u->load_state == UNIT_STUB)
                 return -ENOENT;
@@ -1242,25 +467,17 @@ static int service_load(Unit *u) {
 
                 service_fix_output(s);
 
-                r = unit_add_exec_dependencies(u, &s->exec_context);
+                r = unit_patch_contexts(u);
                 if (r < 0)
                         return r;
 
-                r = unit_add_default_slice(u);
+                r = unit_add_exec_dependencies(u, &s->exec_context);
                 if (r < 0)
                         return r;
 
-#ifdef HAVE_SYSV_COMPAT
-                r = sysv_fix_order(s);
+                r = unit_add_default_slice(u, &s->cgroup_context);
                 if (r < 0)
                         return r;
-#endif
-
-                if (s->bus_name) {
-                        r = unit_watch_bus_name(u, s->bus_name);
-                        if (r < 0)
-                                return r;
-                }
 
                 if (s->type == SERVICE_NOTIFY && s->notify_access == NOTIFY_NONE)
                         s->notify_access = NOTIFY_MAIN;
@@ -1268,15 +485,18 @@ static int service_load(Unit *u) {
                 if (s->watchdog_usec > 0 && s->notify_access == NOTIFY_NONE)
                         s->notify_access = NOTIFY_MAIN;
 
-                if (UNIT(s)->default_dependencies) {
-                        r = service_add_default_dependencies(s);
+                if (s->bus_name) {
+                        r = unit_watch_bus_name(u, s->bus_name);
                         if (r < 0)
                                 return r;
                 }
 
-                r = unit_exec_context_defaults(u, &s->exec_context);
-                if (r < 0)
-                        return r;
+                if (u->default_dependencies) {
+                        r = service_add_default_dependencies(s);
+                        if (r < 0)
+
+                                return r;
+                }
         }
 
         return service_verify(s);
@@ -1357,21 +577,10 @@ static void service_dump(Unit *u, FILE *f, const char *prefix) {
         }
 
 #ifdef HAVE_SYSV_COMPAT
-        if (s->is_sysv)
-                fprintf(f,
-                        "%sSysV Init Script has LSB Header: %s\n"
-                        "%sSysVEnabled: %s\n",
-                        prefix, yes_no(s->sysv_has_lsb),
-                        prefix, yes_no(s->sysv_enabled));
-
         if (s->sysv_start_priority >= 0)
                 fprintf(f,
                         "%sSysVStartPriority: %i\n",
                         prefix, s->sysv_start_priority);
-
-        if (s->sysv_runlevels)
-                fprintf(f, "%sSysVRunLevels: %s\n",
-                        prefix, s->sysv_runlevels);
 #endif
 
         if (s->status_text)
@@ -1475,9 +684,7 @@ static int service_search_main_pid(Service *s) {
                 log_warning_unit(UNIT(s)->id,
                                  "Failed to watch PID "PID_FMT" from service %s",
                                  pid, UNIT(s)->id);
-                return r;
-
-        return 0;
+        return r;
 }
 
 static void service_set_state(Service *s, ServiceState state) {
@@ -1811,6 +1018,7 @@ static int service_spawn(
                        UNIT(s)->manager->confirm_spawn,
                        UNIT(s)->manager->cgroup_supported,
                        path,
+                       manager_get_runtime_prefix(UNIT(s)->manager),
                        UNIT(s)->id,
                        s->watchdog_usec,
                        s->type == SERVICE_IDLE ? UNIT(s)->manager->idle_pipe : NULL,
@@ -1881,6 +1089,8 @@ static int cgroup_good(Service *s) {
         return !r;
 }
 
+static int service_execute_action(Service *s, FailureAction action, const char *reason, bool log_action_none);
+
 static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart) {
         int r;
         assert(s);
@@ -1890,18 +1100,21 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart)
 
         service_set_state(s, s->result != SERVICE_SUCCESS ? SERVICE_FAILED : SERVICE_DEAD);
 
+        if (s->result != SERVICE_SUCCESS)
+                service_execute_action(s, s->failure_action, "failed", false);
+
         if (allow_restart &&
             !s->forbid_restart &&
             (s->restart == SERVICE_RESTART_ALWAYS ||
              (s->restart == SERVICE_RESTART_ON_SUCCESS && s->result == SERVICE_SUCCESS) ||
              (s->restart == SERVICE_RESTART_ON_FAILURE && s->result != SERVICE_SUCCESS) ||
+             (s->restart == SERVICE_RESTART_ON_ABNORMAL && !IN_SET(s->result, SERVICE_SUCCESS, SERVICE_FAILURE_EXIT_CODE)) ||
              (s->restart == SERVICE_RESTART_ON_WATCHDOG && s->result == SERVICE_FAILURE_WATCHDOG) ||
-             (s->restart == SERVICE_RESTART_ON_ABORT && (s->result == SERVICE_FAILURE_SIGNAL ||
-                                                         s->result == SERVICE_FAILURE_CORE_DUMP))) &&
-            (s->result != SERVICE_FAILURE_EXIT_CODE ||
-             !set_contains(s->restart_ignore_status.code, INT_TO_PTR(s->main_exec_status.status))) &&
-            (s->result != SERVICE_FAILURE_SIGNAL ||
-             !set_contains(s->restart_ignore_status.signal, INT_TO_PTR(s->main_exec_status.status)))) {
+             (s->restart == SERVICE_RESTART_ON_ABORT && IN_SET(s->result, SERVICE_FAILURE_SIGNAL, SERVICE_FAILURE_CORE_DUMP)) ||
+             (s->main_exec_status.code == CLD_EXITED && set_contains(s->restart_force_status.status, INT_TO_PTR(s->main_exec_status.status))) ||
+             (IN_SET(s->main_exec_status.code, CLD_KILLED, CLD_DUMPED) && set_contains(s->restart_force_status.signal, INT_TO_PTR(s->main_exec_status.status)))) &&
+            (s->main_exec_status.code != CLD_EXITED || !set_contains(s->restart_prevent_status.status, INT_TO_PTR(s->main_exec_status.status))) &&
+            (!IN_SET(s->main_exec_status.code, CLD_KILLED, CLD_DUMPED) || !set_contains(s->restart_prevent_status.signal, INT_TO_PTR(s->main_exec_status.status)))) {
 
                 r = service_arm_timer(s, s->restart_usec);
                 if (r < 0)
@@ -1912,10 +1125,13 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart)
 
         s->forbid_restart = false;
 
-        /* we want fresh tmpdirs in case service is started again immediately */
+        /* We want fresh tmpdirs in case service is started again immediately */
         exec_runtime_destroy(s->exec_runtime);
         s->exec_runtime = exec_runtime_unref(s->exec_runtime);
 
+        /* Also, remove the runtime directory in */
+        exec_context_destroy_runtime_directory(&s->exec_context, manager_get_runtime_prefix(UNIT(s)->manager));
+
         /* Try to delete the pid file. At this point it will be
          * out-of-date, and some software might be confused by it, so
          * let's remove it. */
@@ -2244,8 +1460,7 @@ static void service_enter_start_pre(Service *s) {
         return;
 
 fail:
-        log_warning_unit(UNIT(s)->id,
-                         "%s failed to run 'start-pre' task: %s", UNIT(s)->id, strerror(-r));
+        log_warning_unit(UNIT(s)->id, "%s failed to run 'start-pre' task: %s", UNIT(s)->id, strerror(-r));
         service_enter_dead(s, SERVICE_FAILURE_RESOURCES, true);
 }
 
@@ -2257,8 +1472,7 @@ static void service_enter_restart(Service *s) {
 
         if (UNIT(s)->job && UNIT(s)->job->type == JOB_STOP) {
                 /* Don't restart things if we are going down anyway */
-                log_info_unit(UNIT(s)->id,
-                              "Stop job pending for unit, delaying automatic restart.");
+                log_info_unit(UNIT(s)->id, "Stop job pending for unit, delaying automatic restart.");
 
                 r = service_arm_timer(s, s->restart_usec);
                 if (r < 0)
@@ -2279,8 +1493,7 @@ static void service_enter_restart(Service *s) {
          * it will be canceled as part of the service_stop() call that
          * is executed as part of JOB_RESTART. */
 
-        log_debug_unit(UNIT(s)->id,
-                       "%s scheduled restart job.", UNIT(s)->id);
+        log_debug_unit(UNIT(s)->id, "%s scheduled restart job.", UNIT(s)->id);
         return;
 
 fail:
@@ -2409,26 +1622,27 @@ fail:
         service_enter_stop(s, SERVICE_FAILURE_RESOURCES);
 }
 
-static int service_start_limit_test(Service *s) {
+static int service_execute_action(Service *s, FailureAction action, const char *reason, bool log_action_none) {
         assert(s);
 
-        if (ratelimit_test(&s->start_limit))
-                return 0;
+        if (action == SERVICE_FAILURE_ACTION_REBOOT ||
+            action == SERVICE_FAILURE_ACTION_REBOOT_FORCE)
+                update_reboot_param_file(s->reboot_arg);
 
-        switch (s->start_limit_action) {
+        switch (action) {
 
-        case SERVICE_START_LIMIT_NONE:
-                log_warning_unit(UNIT(s)->id,
-                                 "%s start request repeated too quickly, refusing to start.",
-                                 UNIT(s)->id);
+        case SERVICE_FAILURE_ACTION_NONE:
+                if (log_action_none)
+                        log_warning_unit(UNIT(s)->id,
+                                         "%s %s, refusing to start.", UNIT(s)->id, reason);
                 break;
 
-        case SERVICE_START_LIMIT_REBOOT: {
+        case SERVICE_FAILURE_ACTION_REBOOT: {
                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
                 int r;
 
                 log_warning_unit(UNIT(s)->id,
-                                 "%s start request repeated too quickly, rebooting.", UNIT(s)->id);
+                                 "%s %s, rebooting.", UNIT(s)->id, reason);
 
                 r = manager_add_job_by_name(UNIT(s)->manager, JOB_START,
                                             SPECIAL_REBOOT_TARGET, JOB_REPLACE,
@@ -2440,28 +1654,44 @@ static int service_start_limit_test(Service *s) {
                 break;
         }
 
-        case SERVICE_START_LIMIT_REBOOT_FORCE:
+        case SERVICE_FAILURE_ACTION_REBOOT_FORCE:
                 log_warning_unit(UNIT(s)->id,
-                                 "%s start request repeated too quickly, forcibly rebooting.", UNIT(s)->id);
+                                 "%s %s, forcibly rebooting.", UNIT(s)->id, reason);
                 UNIT(s)->manager->exit_code = MANAGER_REBOOT;
                 break;
 
-        case SERVICE_START_LIMIT_REBOOT_IMMEDIATE:
+        case SERVICE_FAILURE_ACTION_REBOOT_IMMEDIATE:
                 log_warning_unit(UNIT(s)->id,
-                                 "%s start request repeated too quickly, rebooting immediately.", UNIT(s)->id);
+                                 "%s %s, rebooting immediately.", UNIT(s)->id, reason);
                 sync();
+                if (s->reboot_arg) {
+                        log_info("Rebooting with argument '%s'.", s->reboot_arg);
+                        syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
+                                LINUX_REBOOT_CMD_RESTART2, s->reboot_arg);
+                }
+
+                log_info("Rebooting.");
                 reboot(RB_AUTOBOOT);
                 break;
 
         default:
                 log_error_unit(UNIT(s)->id,
-                               "start limit action=%i", s->start_limit_action);
-                assert_not_reached("Unknown StartLimitAction.");
+                               "failure action=%i", action);
+                assert_not_reached("Unknown FailureAction.");
         }
 
         return -ECANCELED;
 }
 
+static int service_start_limit_test(Service *s) {
+        assert(s);
+
+        if (ratelimit_test(&s->start_limit))
+                return 0;
+
+        return service_execute_action(s, s->start_limit_action, "start request repeated too quickly", true);
+}
+
 static int service_start(Unit *u) {
         Service *s = SERVICE(u);
         int r;
@@ -2509,6 +1739,10 @@ static int service_start(Unit *u) {
         s->main_pid_alien = false;
         s->forbid_restart = false;
 
+        free(s->status_text);
+        s->status_text = NULL;
+        s->status_errno = 0;
+
         service_enter_start_pre(s);
         return 0;
 }
@@ -2721,8 +1955,7 @@ static int service_deserialize_item(Unit *u, const char *key, const char *value,
                         log_debug_unit(u->id, "Failed to parse socket-fd value %s", value);
                 else {
 
-                        if (s->socket_fd >= 0)
-                                close_nointr_nofail(s->socket_fd);
+                        asynchronous_close(s->socket_fd);
                         s->socket_fd = fdset_remove(fds, fd);
                 }
         } else if (streq(key, "main-exec-status-pid")) {
@@ -2794,11 +2027,6 @@ static bool service_check_gc(Unit *u) {
             control_pid_good(s) > 0)
                 return true;
 
-#ifdef HAVE_SYSV_COMPAT
-        if (s->is_sysv)
-                return true;
-#endif
-
         return false;
 }
 
@@ -3363,11 +2591,15 @@ static int service_dispatch_timer(sd_event_source *source, usec_t usec, void *us
 
 static int service_dispatch_watchdog(sd_event_source *source, usec_t usec, void *userdata) {
         Service *s = SERVICE(userdata);
+        char t[FORMAT_TIMESPAN_MAX];
 
         assert(s);
         assert(source == s->watchdog_event_source);
 
-        log_error_unit(UNIT(s)->id, "%s watchdog timeout!", UNIT(s)->id);
+        log_error_unit(UNIT(s)->id,
+                       "%s watchdog timeout (limit %s)!",
+                       UNIT(s)->id,
+                       format_timespan(t, sizeof(t), s->watchdog_usec, 1));
         service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_WATCHDOG);
 
         return 0;
@@ -3391,7 +2623,6 @@ static void service_notify_message(Unit *u, pid_t pid, char **tags) {
         }
 
         if (s->notify_access == NOTIFY_MAIN && pid != s->main_pid) {
-
                 if (s->main_pid != 0)
                         log_warning_unit(u->id, "%s: Got notification message from PID "PID_FMT", but reception only permitted for main PID "PID_FMT, u->id, pid, s->main_pid);
                 else
@@ -3400,14 +2631,10 @@ static void service_notify_message(Unit *u, pid_t pid, char **tags) {
         }
 
         /* Interpret MAINPID= */
-        if ((e = strv_find_prefix(tags, "MAINPID=")) &&
-            (s->state == SERVICE_START ||
-             s->state == SERVICE_START_POST ||
-             s->state == SERVICE_RUNNING ||
-             s->state == SERVICE_RELOAD)) {
-
+        e = strv_find_prefix(tags, "MAINPID=");
+        if (e && IN_SET(s->state, SERVICE_START, SERVICE_START_POST, SERVICE_RUNNING, SERVICE_RELOAD)) {
                 if (parse_pid(e + 8, &pid) < 0)
-                        log_warning_unit(u->id, "Failed to parse notification message %s", e);
+                        log_warning_unit(u->id, "Failed to parse MAINPID= field in notification message: %s", e);
                 else {
                         log_debug_unit(u->id, "%s: got %s", u->id, e);
                         service_set_main_pid(s, pid);
@@ -3453,7 +2680,24 @@ static void service_notify_message(Unit *u, pid_t pid, char **tags) {
                         free(t);
         }
 
-        /* Interpet WATCHDOG= */
+        /* Interpret ERRNO= */
+        e = strv_find_prefix(tags, "ERRNO=");
+        if (e) {
+                int status_errno;
+
+                if (safe_atoi(e + 6, &status_errno) < 0 || status_errno < 0)
+                        log_warning_unit(u->id, "Failed to parse ERRNO= field in notification message: %s", e);
+                else {
+                        log_debug_unit(u->id, "%s: got %s", u->id, e);
+
+                        if (s->status_errno != status_errno) {
+                                s->status_errno = status_errno;
+                                notify_dbus = true;
+                        }
+                }
+        }
+
+        /* Interpret WATCHDOG= */
         if (strv_find(tags, "WATCHDOG=1")) {
                 log_debug_unit(u->id, "%s: got WATCHDOG=1", u->id);
                 service_reset_watchdog(s);
@@ -3478,176 +2722,6 @@ static int service_get_timeout(Unit *u, uint64_t *timeout) {
         return 1;
 }
 
-#ifdef HAVE_SYSV_COMPAT
-
-static int service_enumerate(Manager *m) {
-        char **p;
-        unsigned i;
-        _cleanup_closedir_ DIR *d = NULL;
-        _cleanup_free_ char *path = NULL, *fpath = NULL, *name = NULL;
-        Set *runlevel_services[ELEMENTSOF(rcnd_table)] = {};
-        _cleanup_set_free_ Set *shutdown_services = NULL;
-        Unit *service;
-        Iterator j;
-        int r;
-
-        assert(m);
-
-        if (m->running_as != SYSTEMD_SYSTEM)
-                return 0;
-
-        STRV_FOREACH(p, m->lookup_paths.sysvrcnd_path)
-                for (i = 0; i < ELEMENTSOF(rcnd_table); i ++) {
-                        struct dirent *de;
-
-                        free(path);
-                        path = strjoin(*p, "/", rcnd_table[i].path, NULL);
-                        if (!path) {
-                                r = -ENOMEM;
-                                goto finish;
-                        }
-
-                        if (d)
-                                closedir(d);
-
-                        d = opendir(path);
-                        if (!d) {
-                                if (errno != ENOENT)
-                                        log_warning("opendir(%s) failed: %m", path);
-
-                                continue;
-                        }
-
-                        while ((de = readdir(d))) {
-                                int a, b;
-
-                                if (ignore_file(de->d_name))
-                                        continue;
-
-                                if (de->d_name[0] != 'S' && de->d_name[0] != 'K')
-                                        continue;
-
-                                if (strlen(de->d_name) < 4)
-                                        continue;
-
-                                a = undecchar(de->d_name[1]);
-                                b = undecchar(de->d_name[2]);
-
-                                if (a < 0 || b < 0)
-                                        continue;
-
-                                free(fpath);
-                                fpath = strjoin(path, "/", de->d_name, NULL);
-                                if (!fpath) {
-                                        r = -ENOMEM;
-                                        goto finish;
-                                }
-
-                                if (access(fpath, X_OK) < 0) {
-
-                                        if (errno != ENOENT)
-                                                log_warning("access() failed on %s: %m", fpath);
-
-                                        continue;
-                                }
-
-                                free(name);
-                                name = sysv_translate_name(de->d_name + 3);
-                                if (!name) {
-                                        r = log_oom();
-                                        goto finish;
-                                }
-
-                                r = manager_load_unit_prepare(m, name, NULL, NULL, &service);
-                                if (r < 0) {
-                                        log_warning("Failed to prepare unit %s: %s", name, strerror(-r));
-                                        continue;
-                                }
-
-                                if (de->d_name[0] == 'S')  {
-
-                                        if (rcnd_table[i].type == RUNLEVEL_UP) {
-                                                SERVICE(service)->sysv_start_priority_from_rcnd =
-                                                        MAX(a*10 + b, SERVICE(service)->sysv_start_priority_from_rcnd);
-
-                                                SERVICE(service)->sysv_enabled = true;
-                                        }
-
-                                        r = set_ensure_allocated(&runlevel_services[i],
-                                                                 trivial_hash_func, trivial_compare_func);
-                                        if (r < 0)
-                                                goto finish;
-
-                                        r = set_put(runlevel_services[i], service);
-                                        if (r < 0)
-                                                goto finish;
-
-                                } else if (de->d_name[0] == 'K' &&
-                                           (rcnd_table[i].type == RUNLEVEL_DOWN)) {
-
-                                        r = set_ensure_allocated(&shutdown_services,
-                                                                 trivial_hash_func, trivial_compare_func);
-                                        if (r < 0)
-                                                goto finish;
-
-                                        r = set_put(shutdown_services, service);
-                                        if (r < 0)
-                                                goto finish;
-                                }
-                        }
-                }
-
-        /* Now we loaded all stubs and are aware of the lowest
-        start-up priority for all services, not let's actually load
-        the services, this will also tell us which services are
-        actually native now */
-        manager_dispatch_load_queue(m);
-
-        /* If this is a native service, rely on native ways to pull in
-         * a service, don't pull it in via sysv rcN.d links. */
-        for (i = 0; i < ELEMENTSOF(rcnd_table); i ++)
-                SET_FOREACH(service, runlevel_services[i], j) {
-                        service = unit_follow_merge(service);
-
-                        if (service->fragment_path)
-                                continue;
-
-                        r = unit_add_two_dependencies_by_name_inverse(
-                                service, UNIT_AFTER, UNIT_WANTS,
-                                rcnd_table[i].target, NULL, true);
-                        if (r < 0)
-                                goto finish;
-                }
-
-        /* We honour K links only for halt/reboot. For the normal
-         * runlevels we assume the stop jobs will be implicitly added
-         * by the core logic. Also, we don't really distinguish here
-         * between the runlevels 0 and 6 and just add them to the
-         * special shutdown target. */
-        SET_FOREACH(service, shutdown_services, j) {
-                service = unit_follow_merge(service);
-
-                if (service->fragment_path)
-                        continue;
-
-                r = unit_add_two_dependencies_by_name(
-                        service, UNIT_BEFORE, UNIT_CONFLICTS,
-                        SPECIAL_SHUTDOWN_TARGET, NULL, true);
-                if (r < 0)
-                        goto finish;
-        }
-
-        r = 0;
-
-finish:
-
-        for (i = 0; i < ELEMENTSOF(rcnd_table); i++)
-                set_free(runlevel_services[i]);
-
-        return r;
-}
-#endif
-
 static void service_bus_name_owner_change(
                 Unit *u,
                 const char *name,
@@ -3799,9 +2873,10 @@ static const char* const service_restart_table[_SERVICE_RESTART_MAX] = {
         [SERVICE_RESTART_NO] = "no",
         [SERVICE_RESTART_ON_SUCCESS] = "on-success",
         [SERVICE_RESTART_ON_FAILURE] = "on-failure",
+        [SERVICE_RESTART_ON_ABNORMAL] = "on-abnormal",
         [SERVICE_RESTART_ON_WATCHDOG] = "on-watchdog",
         [SERVICE_RESTART_ON_ABORT] = "on-abort",
-        [SERVICE_RESTART_ALWAYS] = "always"
+        [SERVICE_RESTART_ALWAYS] = "always",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(service_restart, ServiceRestart);
@@ -3849,13 +2924,13 @@ static const char* const service_result_table[_SERVICE_RESULT_MAX] = {
 
 DEFINE_STRING_TABLE_LOOKUP(service_result, ServiceResult);
 
-static const char* const start_limit_action_table[_SERVICE_START_LIMIT_MAX] = {
-        [SERVICE_START_LIMIT_NONE] = "none",
-        [SERVICE_START_LIMIT_REBOOT] = "reboot",
-        [SERVICE_START_LIMIT_REBOOT_FORCE] = "reboot-force",
-        [SERVICE_START_LIMIT_REBOOT_IMMEDIATE] = "reboot-immediate"
+static const char* const failure_action_table[_SERVICE_FAILURE_ACTION_MAX] = {
+        [SERVICE_FAILURE_ACTION_NONE] = "none",
+        [SERVICE_FAILURE_ACTION_REBOOT] = "reboot",
+        [SERVICE_FAILURE_ACTION_REBOOT_FORCE] = "reboot-force",
+        [SERVICE_FAILURE_ACTION_REBOOT_IMMEDIATE] = "reboot-immediate"
 };
-DEFINE_STRING_TABLE_LOOKUP(start_limit_action, StartLimitAction);
+DEFINE_STRING_TABLE_LOOKUP(failure_action, FailureAction);
 
 const UnitVTable service_vtable = {
         .object_size = sizeof(Service),
@@ -3910,11 +2985,6 @@ const UnitVTable service_vtable = {
         .bus_commit_properties = bus_service_commit_properties,
 
         .get_timeout = service_get_timeout,
-
-#ifdef HAVE_SYSV_COMPAT
-        .enumerate = service_enumerate,
-#endif
-
         .can_transient = true,
 
         .status_message_formats = {
index 1992926..686cf4b 100644 (file)
@@ -53,6 +53,7 @@ typedef enum ServiceRestart {
         SERVICE_RESTART_NO,
         SERVICE_RESTART_ON_SUCCESS,
         SERVICE_RESTART_ON_FAILURE,
+        SERVICE_RESTART_ON_ABNORMAL,
         SERVICE_RESTART_ON_WATCHDOG,
         SERVICE_RESTART_ON_ABORT,
         SERVICE_RESTART_ALWAYS,
@@ -103,21 +104,22 @@ typedef enum ServiceResult {
         _SERVICE_RESULT_INVALID = -1
 } ServiceResult;
 
-typedef enum StartLimitAction {
-        SERVICE_START_LIMIT_NONE,
-        SERVICE_START_LIMIT_REBOOT,
-        SERVICE_START_LIMIT_REBOOT_FORCE,
-        SERVICE_START_LIMIT_REBOOT_IMMEDIATE,
-        _SERVICE_START_LIMIT_MAX,
-        _SERVICE_START_LIMIT_INVALID = -1
-} StartLimitAction;
+typedef enum FailureAction {
+        SERVICE_FAILURE_ACTION_NONE,
+        SERVICE_FAILURE_ACTION_REBOOT,
+        SERVICE_FAILURE_ACTION_REBOOT_FORCE,
+        SERVICE_FAILURE_ACTION_REBOOT_IMMEDIATE,
+        _SERVICE_FAILURE_ACTION_MAX,
+        _SERVICE_FAILURE_ACTION_INVALID = -1
+} FailureAction;
 
 struct Service {
         Unit meta;
 
         ServiceType type;
         ServiceRestart restart;
-        ExitStatusSet restart_ignore_status;
+        ExitStatusSet restart_prevent_status;
+        ExitStatusSet restart_force_status;
         ExitStatusSet success_status;
 
         /* If set we'll read the main daemon PID from this file */
@@ -174,21 +176,19 @@ struct Service {
         bool forbid_restart:1;
         bool start_timeout_defined:1;
 #ifdef HAVE_SYSV_COMPAT
-        bool is_sysv:1;
-        bool sysv_has_lsb:1;
-        bool sysv_enabled:1;
-        int sysv_start_priority_from_rcnd;
         int sysv_start_priority;
-
-        char *sysv_runlevels;
 #endif
 
         char *bus_name;
 
         char *status_text;
+        int status_errno;
+
+        FailureAction failure_action;
 
         RateLimit start_limit;
-        StartLimitAction start_limit_action;
+        FailureAction start_limit_action;
+        char *reboot_arg;
 
         UnitRef accept_socket;
 
@@ -222,5 +222,5 @@ NotifyAccess notify_access_from_string(const char *s) _pure_;
 const char* service_result_to_string(ServiceResult i) _const_;
 ServiceResult service_result_from_string(const char *s) _pure_;
 
-const char* start_limit_action_to_string(StartLimitAction i) _const_;
-StartLimitAction start_limit_action_from_string(const char *s) _pure_;
+const char* failure_action_to_string(FailureAction i) _const_;
+FailureAction failure_action_from_string(const char *s) _pure_;
diff --git a/src/core/show-status.c b/src/core/show-status.c
new file mode 100644 (file)
index 0000000..02b1be7
--- /dev/null
@@ -0,0 +1,42 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "show-status.h"
+#include "util.h"
+
+int parse_show_status(const char *v, ShowStatus *ret) {
+        int r;
+
+        assert(v);
+        assert(ret);
+
+        if (streq(v, "auto")) {
+                *ret = SHOW_STATUS_AUTO;
+                return 0;
+        }
+
+        r = parse_boolean(v);
+        if (r < 0)
+                return r;
+
+        *ret = r ? SHOW_STATUS_YES : SHOW_STATUS_NO;
+        return 0;
+}
diff --git a/src/core/show-status.h b/src/core/show-status.h
new file mode 100644 (file)
index 0000000..a2b2153
--- /dev/null
@@ -0,0 +1,34 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+/* Manager status */
+
+typedef enum ShowStatus {
+        _SHOW_STATUS_UNSET = -2,
+        SHOW_STATUS_AUTO = -1,
+        SHOW_STATUS_NO = 0,
+        SHOW_STATUS_YES = 1,
+        SHOW_STATUS_TEMPORARY = 2,
+} ShowStatus;
+
+int parse_show_status(const char *v, ShowStatus *ret);
index c751030..1abc140 100644 (file)
@@ -74,9 +74,7 @@ static int parse_argv(int argc, char *argv[]) {
         assert(argc >= 1);
         assert(argv);
 
-        opterr = 0;
-
-        while ((c = getopt_long(argc, argv, ":", options, NULL)) >= 0)
+        while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
                 switch (c) {
 
                 case ARG_LOG_LEVEL:
@@ -115,11 +113,6 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
 
                 case '?':
-                        log_error("Unknown option %s.", argv[optind-1]);
-                        return -EINVAL;
-
-                case ':':
-                        log_error("Missing argument to %s.", argv[optind-1]);
                         return -EINVAL;
 
                 default:
@@ -220,7 +213,7 @@ static int pivot_to_new_root(void) {
 }
 
 int main(int argc, char *argv[]) {
-        bool need_umount = true, need_swapoff = true, need_loop_detach = true, need_dm_detach = true;
+        bool need_umount, need_swapoff, need_loop_detach, need_dm_detach;
         bool in_container, use_watchdog = false;
         _cleanup_free_ char *cgroup = NULL;
         char *arguments[3];
@@ -246,8 +239,6 @@ int main(int argc, char *argv[]) {
                 goto error;
         }
 
-        in_container = detect_container(NULL) > 0;
-
         if (streq(arg_verb, "reboot"))
                 cmd = RB_AUTOBOOT;
         else if (streq(arg_verb, "poweroff"))
@@ -275,11 +266,12 @@ int main(int argc, char *argv[]) {
         log_info("Sending SIGKILL to remaining processes...");
         broadcast_signal(SIGKILL, true, false);
 
-        if (in_container) {
-                need_swapoff = false;
-                need_dm_detach = false;
-                need_loop_detach = false;
-        }
+        in_container = detect_container(NULL) > 0;
+
+        need_umount = true;
+        need_swapoff = !in_container;
+        need_loop_detach = !in_container;
+        need_dm_detach = !in_container;
 
         /* Unmount all mountpoints, swaps, and loopback devices */
         for (retries = 0; retries < FINALIZE_ATTEMPTS; retries++) {
@@ -347,28 +339,36 @@ int main(int argc, char *argv[]) {
                         if (retries > 0)
                                 log_info("All filesystems, swaps, loop devices, DM devices detached.");
                         /* Yay, done */
-                        break;
+                        goto initrd_jump;
                 }
 
                 /* If in this iteration we didn't manage to
                  * unmount/deactivate anything, we simply give up */
                 if (!changed) {
-                        log_error("Cannot finalize remaining file systems and devices, giving up.");
-                        break;
+                        log_info("Cannot finalize remaining%s%s%s%s continuing.",
+                                 need_umount ? " file systems," : "",
+                                 need_swapoff ? " swap devices," : "",
+                                 need_loop_detach ? " loop devices," : "",
+                                 need_dm_detach ? " DM devices," : "");
+                        goto initrd_jump;
                 }
 
-                log_debug("Couldn't finalize remaining file systems and devices after %u retries, trying again.", retries+1);
+                log_debug("After %u retries, couldn't finalize remaining %s%s%s%s trying again.",
+                          retries + 1,
+                          need_umount ? " file systems," : "",
+                          need_swapoff ? " swap devices," : "",
+                          need_loop_detach ? " loop devices," : "",
+                          need_dm_detach ? " DM devices," : "");
         }
 
-        if (retries >= FINALIZE_ATTEMPTS)
-                log_error("Too many iterations, giving up.");
-        else
-                log_info("Storage is finalized.");
+        log_error("Too many iterations, giving up.");
+
+ initrd_jump:
 
         arguments[0] = NULL;
         arguments[1] = arg_verb;
         arguments[2] = NULL;
-        execute_directory(SYSTEM_SHUTDOWN_PATH, NULL, arguments);
+        execute_directory(SYSTEM_SHUTDOWN_PATH, NULL, DEFAULT_TIMEOUT_USEC, arguments);
 
         if (!in_container && !in_initrd() &&
             access("/run/initramfs/shutdown", X_OK) == 0) {
@@ -384,6 +384,13 @@ int main(int argc, char *argv[]) {
                 }
         }
 
+        if (need_umount || need_swapoff || need_loop_detach || need_dm_detach)
+                log_error("Failed to finalize %s%s%s%s ignoring",
+                          need_umount ? " file systems," : "",
+                          need_swapoff ? " swap devices," : "",
+                          need_loop_detach ? " loop devices," : "",
+                          need_dm_detach ? " DM devices," : "");
+
         /* The kernel will automaticall flush ATA disks and suchlike
          * on reboot(), but the file systems need to be synce'd
          * explicitly in advance. So let's do this here, but not
index 1e42df2..057feef 100644 (file)
@@ -36,23 +36,6 @@ static const UnitActiveState state_translation_table[_SLICE_STATE_MAX] = {
         [SLICE_ACTIVE] = UNIT_ACTIVE
 };
 
-static void slice_init(Unit *u) {
-        Slice *s = SLICE(u);
-
-        assert(u);
-        assert(u->load_state == UNIT_STUB);
-
-        cgroup_context_init(&s->cgroup_context);
-}
-
-static void slice_done(Unit *u) {
-        Slice *s = SLICE(u);
-
-        assert(u);
-
-        cgroup_context_done(&s->cgroup_context);
-}
-
 static void slice_set_state(Slice *t, SliceState state) {
         SliceState old_state;
         assert(t);
@@ -152,6 +135,10 @@ static int slice_load(Unit *u) {
         /* This is a new unit? Then let's add in some extras */
         if (u->load_state == UNIT_LOADED) {
 
+                r = unit_patch_contexts(u);
+                if (r < 0)
+                        return r;
+
                 r = slice_add_parent_slice(s);
                 if (r < 0)
                         return r;
@@ -286,9 +273,7 @@ const UnitVTable slice_vtable = {
         .no_alias = true,
         .no_instances = true,
 
-        .init = slice_init,
         .load = slice_load,
-        .done = slice_done,
 
         .coldplug = slice_coldplug,
 
index a68605c..952b47c 100644 (file)
 #include "log.h"
 #include "label.h"
 
-#define SMACK_CONFIG "/etc/smack/accesses.d/"
-#define CIPSO_CONFIG "/etc/smack/cipso.d/"
-
 #ifdef HAVE_SMACK
 
-static int write_rules(const char* dstpath, const char* srcdir) {
-        _cleanup_fclose_ FILE *dst = NULL;
+static int write_access2_rules(const char* srcdir) {
+        _cleanup_close_ int load2_fd = -1, change_fd = -1;
         _cleanup_closedir_ DIR *dir = NULL;
         struct dirent *entry;
         char buf[NAME_MAX];
         int dfd = -1;
         int r = 0;
 
-        dst = fopen(dstpath, "we");
-        if (!dst)  {
+        load2_fd = open("/sys/fs/smackfs/load2", O_RDWR|O_CLOEXEC|O_NONBLOCK|O_NOCTTY);
+        if (load2_fd < 0)  {
+                if (errno != ENOENT)
+                        log_warning("Failed to open '%s': %m", "/sys/fs/smackfs/load2");
+                return -errno; /* negative error */
+        }
+
+        change_fd = open("/sys/fs/smackfs/change-rule", O_RDWR|O_CLOEXEC|O_NONBLOCK|O_NOCTTY);
+        if (change_fd < 0)  {
                 if (errno != ENOENT)
-                        log_warning("Failed to open %s: %m", dstpath);
+                        log_warning("Failed to open '%s': %m", "/sys/fs/smackfs/change-rule");
                 return -errno; /* negative error */
         }
 
-        /* write rules to dst from every file in the directory */
+        /* write rules to load2 or change-rule from every file in the directory */
         dir = opendir(srcdir);
         if (!dir) {
                 if (errno != ENOENT)
-                        log_warning("Failed to opendir %s: %m", srcdir);
+                        log_warning("Failed to opendir '%s': %m", srcdir);
                 return errno; /* positive on purpose */
         }
 
@@ -75,11 +79,14 @@ static int write_rules(const char* dstpath, const char* srcdir) {
                 int fd;
                 _cleanup_fclose_ FILE *policy = NULL;
 
+                if (!dirent_is_file(entry))
+                        continue;
+
                 fd = openat(dfd, entry->d_name, O_RDONLY|O_CLOEXEC);
                 if (fd < 0) {
                         if (r == 0)
                                 r = -errno;
-                        log_warning("Failed to open %s: %m", entry->d_name);
+                        log_warning("Failed to open '%s': %m", entry->d_name);
                         continue;
                 }
 
@@ -87,31 +94,109 @@ static int write_rules(const char* dstpath, const char* srcdir) {
                 if (!policy) {
                         if (r == 0)
                                 r = -errno;
-                        close_nointr_nofail(fd);
-                        log_error("Failed to open %s: %m", entry->d_name);
+                        safe_close(fd);
+                        log_error("Failed to open '%s': %m", entry->d_name);
                         continue;
                 }
 
                 /* load2 write rules in the kernel require a line buffered stream */
                 FOREACH_LINE(buf, policy,
-                             log_error("Failed to read line from %s: %m",
+                             log_error("Failed to read line from '%s': %m",
                                        entry->d_name)) {
-                        if (!fputs(buf, dst)) {
+
+                        _cleanup_free_ char *sbj = NULL, *obj = NULL, *acc1 = NULL, *acc2 = NULL;
+
+                        if (isempty(truncate_nl(buf)))
+                                continue;
+
+                        /* if 3 args -> load rule   : subject object access1 */
+                        /* if 4 args -> change rule : subject object access1 access2 */
+                        if (sscanf(buf, "%ms %ms %ms %ms", &sbj, &obj, &acc1, &acc2) < 3) {
+                                log_error("Failed to parse rule '%s' in '%s'", buf, entry->d_name);
+                                continue;
+                        }
+
+                        if (write(isempty(acc2) ? load2_fd : change_fd, buf, strlen(buf)) < 0) {
                                 if (r == 0)
-                                        r = -EINVAL;
-                                log_error("Failed to write line to %s", dstpath);
-                                break;
+                                        r = -errno;
+                                log_error("Failed to write '%s' to '%s' in '%s'",
+                                          buf, isempty(acc2) ? "/sys/fs/smackfs/load2" : "/sys/fs/smackfs/change-rule", entry->d_name);
                         }
-                        if (fflush(dst)) {
+                }
+        }
+
+        return r;
+}
+
+static int write_cipso2_rules(const char* srcdir) {
+        _cleanup_close_ int cipso2_fd = -1;
+        _cleanup_closedir_ DIR *dir = NULL;
+        struct dirent *entry;
+        char buf[NAME_MAX];
+        int dfd = -1;
+        int r = 0;
+
+        cipso2_fd = open("/sys/fs/smackfs/cipso2", O_RDWR|O_CLOEXEC|O_NONBLOCK|O_NOCTTY);
+        if (cipso2_fd < 0)  {
+                if (errno != ENOENT)
+                        log_warning("Failed to open '%s': %m", "/sys/fs/smackfs/cipso2");
+                return -errno; /* negative error */
+        }
+
+        /* write rules to cipso2 from every file in the directory */
+        dir = opendir(srcdir);
+        if (!dir) {
+                if (errno != ENOENT)
+                        log_warning("Failed to opendir '%s': %m", srcdir);
+                return errno; /* positive on purpose */
+        }
+
+        dfd = dirfd(dir);
+        assert(dfd >= 0);
+
+        FOREACH_DIRENT(entry, dir, return 0) {
+                int fd;
+                _cleanup_fclose_ FILE *policy = NULL;
+
+                if (!dirent_is_file(entry))
+                        continue;
+
+                fd = openat(dfd, entry->d_name, O_RDONLY|O_CLOEXEC);
+                if (fd < 0) {
+                        if (r == 0)
+                                r = -errno;
+                        log_warning("Failed to open '%s': %m", entry->d_name);
+                        continue;
+                }
+
+                policy = fdopen(fd, "re");
+                if (!policy) {
+                        if (r == 0)
+                                r = -errno;
+                        safe_close(fd);
+                        log_error("Failed to open '%s': %m", entry->d_name);
+                        continue;
+                }
+
+                /* cipso2 write rules in the kernel require a line buffered stream */
+                FOREACH_LINE(buf, policy,
+                             log_error("Failed to read line from '%s': %m",
+                                       entry->d_name)) {
+
+                        if (isempty(truncate_nl(buf)))
+                                continue;
+
+                        if (write(cipso2_fd, buf, strlen(buf)) < 0) {
                                 if (r == 0)
                                         r = -errno;
-                                log_error("Failed to flush writes to %s: %m", dstpath);
+                                log_error("Failed to write '%s' to '/sys/fs/smackfs/cipso2' in '%s'",
+                                          buf, entry->d_name);
                                 break;
                         }
                 }
         }
 
-       return r;
+        return r;
 }
 
 #endif
@@ -124,13 +209,13 @@ int smack_setup(bool *loaded_policy) {
 
         assert(loaded_policy);
 
-        r = write_rules("/sys/fs/smackfs/load2", SMACK_CONFIG);
+        r = write_access2_rules("/etc/smack/accesses.d/");
         switch(r) {
         case -ENOENT:
                 log_debug("Smack is not enabled in the kernel.");
                 return 0;
         case ENOENT:
-                log_debug("Smack access rules directory " SMACK_CONFIG " not found");
+                log_debug("Smack access rules directory '/etc/smack/accesses.d/' not found");
                 return 0;
         case 0:
                 log_info("Successfully loaded Smack policies.");
@@ -148,17 +233,17 @@ int smack_setup(bool *loaded_policy) {
                             SMACK_RUN_LABEL, strerror(-r));
 #endif
 
-        r = write_rules("/sys/fs/smackfs/cipso2", CIPSO_CONFIG);
+        r = write_cipso2_rules("/etc/smack/cipso.d/");
         switch(r) {
         case -ENOENT:
                 log_debug("Smack/CIPSO is not enabled in the kernel.");
                 return 0;
         case ENOENT:
-                log_debug("Smack/CIPSO access rules directory " CIPSO_CONFIG " not found");
+                log_debug("Smack/CIPSO access rules directory '/etc/smack/cipso.d/' not found");
                 return 0;
         case 0:
                 log_info("Successfully loaded Smack/CIPSO policies.");
-                return 0;
+                break;
         default:
                 log_warning("Failed to load Smack/CIPSO access rules: %s, ignoring.",
                             strerror(abs(r)));
index d914af2..5eed615 100644 (file)
@@ -51,10 +51,11 @@ static void snapshot_set_state(Snapshot *s, SnapshotState state) {
         s->state = state;
 
         if (state != old_state)
-                log_debug("%s changed %s -> %s",
-                          UNIT(s)->id,
-                          snapshot_state_to_string(old_state),
-                          snapshot_state_to_string(state));
+                log_debug_unit(UNIT(s)->id,
+                               "%s changed %s -> %s",
+                               UNIT(s)->id,
+                               snapshot_state_to_string(old_state),
+                               snapshot_state_to_string(state));
 
         unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], true);
 }
@@ -154,7 +155,7 @@ static int snapshot_deserialize_item(Unit *u, const char *key, const char *value
 
                 state = snapshot_state_from_string(value);
                 if (state < 0)
-                        log_debug("Failed to parse state value %s", value);
+                        log_debug_unit(u->id, "Failed to parse state value %s", value);
                 else
                         s->deserialized_state = state;
 
@@ -162,7 +163,7 @@ static int snapshot_deserialize_item(Unit *u, const char *key, const char *value
 
                 r = parse_boolean(value);
                 if (r < 0)
-                        log_debug("Failed to parse cleanup value %s", value);
+                        log_debug_unit(u->id, "Failed to parse cleanup value %s", value);
                 else
                         s->cleanup = r;
 
@@ -172,7 +173,7 @@ static int snapshot_deserialize_item(Unit *u, const char *key, const char *value
                 if (r < 0)
                         return r;
         } else
-                log_debug("Unknown serialization key '%s'", key);
+                log_debug_unit(u->id, "Unknown serialization key '%s'", key);
 
         return 0;
 }
@@ -257,6 +258,8 @@ int snapshot_create(Manager *m, const char *name, bool cleanup, sd_bus_error *e,
         SNAPSHOT(u)->cleanup = cleanup;
         *_s = SNAPSHOT(u);
 
+        log_info_unit(u->id, "Created snapshot %s.", u->id);
+
         return 0;
 
 fail:
@@ -269,6 +272,8 @@ fail:
 void snapshot_remove(Snapshot *s) {
         assert(s);
 
+        log_info_unit(UNIT(s)->id, "Removing snapshot %s.", UNIT(s)->id);
+
         unit_add_to_cleanup_queue(UNIT(s));
 }
 
index 0ccda2f..1189f45 100644 (file)
@@ -29,9 +29,7 @@
 #include <arpa/inet.h>
 #include <netinet/tcp.h>
 #include <mqueue.h>
-#ifdef HAVE_XATTR
-#include <attr/xattr.h>
-#endif
+#include <sys/xattr.h>
 
 #include "sd-event.h"
 #include "log.h"
@@ -57,6 +55,7 @@
 static const UnitActiveState state_translation_table[_SOCKET_STATE_MAX] = {
         [SOCKET_DEAD] = UNIT_INACTIVE,
         [SOCKET_START_PRE] = UNIT_ACTIVATING,
+        [SOCKET_START_CHOWN] = UNIT_ACTIVATING,
         [SOCKET_START_POST] = UNIT_ACTIVATING,
         [SOCKET_LISTENING] = UNIT_ACTIVE,
         [SOCKET_RUNNING] = UNIT_ACTIVE,
@@ -90,11 +89,8 @@ static void socket_init(Unit *u) {
         s->ip_ttl = -1;
         s->mark = -1;
 
-        exec_context_init(&s->exec_context);
         s->exec_context.std_output = u->manager->default_std_output;
         s->exec_context.std_error = u->manager->default_std_error;
-        kill_context_init(&s->kill_context);
-        cgroup_context_init(&s->cgroup_context);
 
         s->control_command_id = _SOCKET_EXEC_COMMAND_INVALID;
 }
@@ -119,9 +115,7 @@ void socket_free_ports(Socket *s) {
 
                 sd_event_source_unref(p->event_source);
 
-                if (p->fd >= 0)
-                        close_nointr_nofail(p->fd);
-
+                safe_close(p->fd);
                 free(p->path);
                 free(p);
         }
@@ -134,8 +128,6 @@ static void socket_done(Unit *u) {
 
         socket_free_ports(s);
 
-        cgroup_context_done(&s->cgroup_context);
-        exec_context_done(&s->exec_context);
         s->exec_runtime = exec_runtime_unref(s->exec_runtime);
         exec_command_free_array(s->exec_command, _SOCKET_EXEC_COMMAND_MAX);
         s->control_command = NULL;
@@ -154,6 +146,11 @@ static void socket_done(Unit *u) {
         free(s->smack_ip_in);
         free(s->smack_ip_out);
 
+        strv_free(s->symlinks);
+
+        free(s->user);
+        free(s->group);
+
         s->timer_event_source = sd_event_source_unref(s->timer_event_source);
 }
 
@@ -175,12 +172,16 @@ static int socket_arm_timer(Socket *s) {
                 return sd_event_source_set_enabled(s->timer_event_source, SD_EVENT_ONESHOT);
         }
 
-        return sd_event_add_monotonic(UNIT(s)->manager->event, &s->timer_event_source, now(CLOCK_MONOTONIC) + s->timeout_usec, 0, socket_dispatch_timer, s);
+        return sd_event_add_time(
+                        UNIT(s)->manager->event,
+                        &s->timer_event_source,
+                        CLOCK_MONOTONIC,
+                        now(CLOCK_MONOTONIC) + s->timeout_usec, 0,
+                        socket_dispatch_timer, s);
 }
 
-static int socket_instantiate_service(Socket *s) {
-        _cleanup_free_ char *prefix = NULL;
-        _cleanup_free_ char *name = NULL;
+int socket_instantiate_service(Socket *s) {
+        _cleanup_free_ char *prefix = NULL, *name = NULL;
         int r;
         Unit *u;
 
@@ -191,31 +192,20 @@ static int socket_instantiate_service(Socket *s) {
          * here. For Accept=no this is mostly a NOP since the service
          * is figured out at load time anyway. */
 
-        if (UNIT_DEREF(s->service))
+        if (UNIT_DEREF(s->service) || !s->accept)
                 return 0;
 
-        assert(s->accept);
-
-        if (!(prefix = unit_name_to_prefix(UNIT(s)->id)))
+        prefix = unit_name_to_prefix(UNIT(s)->id);
+        if (!prefix)
                 return -ENOMEM;
 
-        r = asprintf(&name, "%s@%u.service", prefix, s->n_accepted);
-
-        if (r < 0)
+        if (asprintf(&name, "%s@%u.service", prefix, s->n_accepted) < 0)
                 return -ENOMEM;
 
         r = manager_load_unit(UNIT(s)->manager, name, NULL, NULL, &u);
-
         if (r < 0)
                 return r;
 
-#ifdef HAVE_SYSV_COMPAT
-        if (SERVICE(u)->is_sysv) {
-                log_error("Using SysV services for socket activation is not supported. Refusing.");
-                return -ENOENT;
-        }
-#endif
-
         u->no_gc = true;
         unit_ref_set(&s->service, u);
 
@@ -338,7 +328,7 @@ static int socket_add_extras(Socket *s) {
         if (r < 0)
                 return r;
 
-        r = unit_exec_context_defaults(u, &s->exec_context);
+        r = unit_patch_contexts(u);
         if (r < 0)
                 return r;
 
@@ -347,7 +337,7 @@ static int socket_add_extras(Socket *s) {
                 if (r < 0)
                         return r;
 
-                r = unit_add_default_slice(u);
+                r = unit_add_default_slice(u, &s->cgroup_context);
                 if (r < 0)
                         return r;
         }
@@ -361,6 +351,39 @@ static int socket_add_extras(Socket *s) {
         return 0;
 }
 
+static const char *socket_find_symlink_target(Socket *s) {
+        const char *found = NULL;
+        SocketPort *p;
+
+        LIST_FOREACH(port, p, s->ports) {
+                const char *f = NULL;
+
+                switch (p->type) {
+
+                case SOCKET_FIFO:
+                        f = p->path;
+                        break;
+
+                case SOCKET_SOCKET:
+                        if (p->address.sockaddr.un.sun_path[0] != 0)
+                                f = p->address.sockaddr.un.sun_path;
+                        break;
+
+                default:
+                        break;
+                }
+
+                if (f) {
+                        if (found)
+                                return NULL;
+
+                        found = f;
+                }
+        }
+
+        return found;
+}
+
 static int socket_verify(Socket *s) {
         assert(s);
 
@@ -393,6 +416,11 @@ static int socket_verify(Socket *s) {
                 return -EINVAL;
         }
 
+        if (!strv_isempty(s->symlinks) && !socket_find_symlink_target(s)) {
+                log_error_unit(UNIT(s)->id, "%s has symlinks set but none or more than one node in the file system. Refusing.", UNIT(s)->id);
+                return -EINVAL;
+        }
+
         return 0;
 }
 
@@ -434,6 +462,7 @@ _const_ static const char* listen_lookup(int family, int type) {
 }
 
 static void socket_dump(Unit *u, FILE *f, const char *prefix) {
+        char time_string[FORMAT_TIMESPAN_MAX];
         SocketExecCommand c;
         Socket *s = SOCKET(u);
         SocketPort *p;
@@ -452,12 +481,14 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) {
                 "%sSocketMode: %04o\n"
                 "%sDirectoryMode: %04o\n"
                 "%sKeepAlive: %s\n"
+                "%sNoDelay: %s\n"
                 "%sFreeBind: %s\n"
                 "%sTransparent: %s\n"
                 "%sBroadcast: %s\n"
                 "%sPassCredentials: %s\n"
                 "%sPassSecurity: %s\n"
-                "%sTCPCongestion: %s\n",
+                "%sTCPCongestion: %s\n"
+                "%sRemoveOnStop: %s\n",
                 prefix, socket_state_to_string(s->state),
                 prefix, socket_result_to_string(s->result),
                 prefix, socket_address_bind_ipv6_only_to_string(s->bind_ipv6_only),
@@ -465,17 +496,19 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) {
                 prefix, s->socket_mode,
                 prefix, s->directory_mode,
                 prefix, yes_no(s->keep_alive),
+                prefix, yes_no(s->no_delay),
                 prefix, yes_no(s->free_bind),
                 prefix, yes_no(s->transparent),
                 prefix, yes_no(s->broadcast),
                 prefix, yes_no(s->pass_cred),
                 prefix, yes_no(s->pass_sec),
-                prefix, strna(s->tcp_congestion));
+                prefix, strna(s->tcp_congestion),
+                prefix, yes_no(s->remove_on_stop));
 
         if (s->control_pid > 0)
                 fprintf(f,
-                        "%sControl PID: %lu\n",
-                        prefix, (unsigned long) s->control_pid);
+                        "%sControl PID: "PID_FMT"\n",
+                        prefix, s->control_pid);
 
         if (s->bind_to_device)
                 fprintf(f,
@@ -556,6 +589,33 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) {
                         "%sSmackLabelIPOut: %s\n",
                         prefix, s->smack_ip_out);
 
+        if (!isempty(s->user) || !isempty(s->group))
+                fprintf(f,
+                        "%sOwnerUser: %s\n"
+                        "%sOwnerGroup: %s\n",
+                        prefix, strna(s->user),
+                        prefix, strna(s->group));
+
+        if (s->keep_alive_time > 0)
+                fprintf(f,
+                        "%sKeepAliveTimeSec: %s\n",
+                        prefix, format_timespan(time_string, FORMAT_TIMESPAN_MAX, s->keep_alive_time, USEC_PER_SEC));
+
+        if (s->keep_alive_interval)
+                fprintf(f,
+                        "%sKeepAliveIntervalSec: %s\n",
+                        prefix, format_timespan(time_string, FORMAT_TIMESPAN_MAX, s->keep_alive_interval, USEC_PER_SEC));
+
+        if (s->keep_alive_cnt)
+                fprintf(f,
+                        "%sKeepAliveProbes: %u\n",
+                        prefix, s->keep_alive_cnt);
+
+        if (s->defer_accept)
+                fprintf(f,
+                        "%sDeferAcceptSec: %s\n",
+                        prefix, format_timespan(time_string, FORMAT_TIMESPAN_MAX, s->defer_accept, USEC_PER_SEC));
+
         LIST_FOREACH(port, p, s->ports) {
 
                 if (p->type == SOCKET_SOCKET) {
@@ -595,13 +655,7 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) {
 static int instance_from_socket(int fd, unsigned nr, char **instance) {
         socklen_t l;
         char *r;
-        union {
-                struct sockaddr sa;
-                struct sockaddr_un un;
-                struct sockaddr_in in;
-                struct sockaddr_in6 in6;
-                struct sockaddr_storage storage;
-        } local, remote;
+        union sockaddr_union local, remote;
 
         assert(fd >= 0);
         assert(instance);
@@ -673,16 +727,22 @@ static int instance_from_socket(int fd, unsigned nr, char **instance) {
                 int k;
 
                 k = getpeercred(fd, &ucred);
-                if (k < 0)
+                if (k >= 0) {
+                        if (asprintf(&r,
+                                     "%u-"PID_FMT"-"UID_FMT,
+                                     nr, ucred.pid, ucred.uid) < 0)
+                                return -ENOMEM;
+                } else if (k == -ENODATA) {
+                        /* This handles the case where somebody is
+                         * connecting from another pid/uid namespace
+                         * (e.g. from outside of our container). */
+                        if (asprintf(&r,
+                                     "%u-unknown",
+                                     nr) < 0)
+                                return -ENOMEM;
+                } else
                         return k;
 
-                if (asprintf(&r,
-                             "%u-%lu-%lu",
-                             nr,
-                             (unsigned long) ucred.pid,
-                             (unsigned long) ucred.uid) < 0)
-                        return -ENOMEM;
-
                 break;
         }
 
@@ -696,6 +756,7 @@ static int instance_from_socket(int fd, unsigned nr, char **instance) {
 
 static void socket_close_fds(Socket *s) {
         SocketPort *p;
+        char **i;
 
         assert(s);
 
@@ -706,18 +767,40 @@ static void socket_close_fds(Socket *s) {
                 if (p->fd < 0)
                         continue;
 
-                close_nointr_nofail(p->fd);
+                p->fd = safe_close(p->fd);
 
-                /* One little note: we should never delete any sockets
-                 * in the file system here! After all some other
-                 * process we spawned might still have a reference of
-                 * this fd and wants to continue to use it. Therefore
-                 * we delete sockets in the file system before we
-                 * create a new one, not after we stopped using
-                 * one! */
+                /* One little note: we should normally not delete any
+                 * sockets in the file system here! After all some
+                 * other process we spawned might still have a
+                 * reference of this fd and wants to continue to use
+                 * it. Therefore we delete sockets in the file system
+                 * before we create a new one, not after we stopped
+                 * using one! */
 
-                p->fd = -1;
+                if (s->remove_on_stop) {
+                        switch (p->type) {
+
+                        case SOCKET_FIFO:
+                                unlink(p->path);
+                                break;
+
+                        case SOCKET_MQUEUE:
+                                mq_unlink(p->path);
+                                break;
+
+                        case SOCKET_SOCKET:
+                                socket_address_unlink(&p->address);
+                                break;
+
+                        default:
+                                break;
+                        }
+                }
         }
+
+        if (s->remove_on_stop)
+                STRV_FOREACH(i, s->symlinks)
+                        unlink(*i);
 }
 
 static void socket_apply_socket_options(Socket *s, int fd) {
@@ -730,6 +813,36 @@ static void socket_apply_socket_options(Socket *s, int fd) {
                         log_warning_unit(UNIT(s)->id, "SO_KEEPALIVE failed: %m");
         }
 
+        if (s->keep_alive_time) {
+                int value = s->keep_alive_time / USEC_PER_SEC;
+                if (setsockopt(fd, SOL_TCP, TCP_KEEPIDLE, &value, sizeof(value)) < 0)
+                        log_warning_unit(UNIT(s)->id, "TCP_KEEPIDLE failed: %m");
+        }
+
+        if (s->keep_alive_interval) {
+                int value =  s->keep_alive_interval / USEC_PER_SEC;
+                if (setsockopt(fd, SOL_TCP, TCP_KEEPINTVL, &value, sizeof(value)) < 0)
+                        log_warning_unit(UNIT(s)->id, "TCP_KEEPINTVL failed: %m");
+        }
+
+        if (s->keep_alive_cnt) {
+                int value = s->keep_alive_cnt;
+                if (setsockopt(fd, SOL_SOCKET, TCP_KEEPCNT, &value, sizeof(value)) < 0)
+                        log_warning_unit(UNIT(s)->id, "TCP_KEEPCNT failed: %m");
+        }
+
+        if (s->defer_accept) {
+                int value = s->defer_accept / USEC_PER_SEC;
+                if (setsockopt(fd, SOL_TCP, TCP_DEFER_ACCEPT, &value, sizeof(value)) < 0)
+                        log_warning_unit(UNIT(s)->id, "TCP_DEFER_ACCEPT failed: %m");
+        }
+
+        if (s->no_delay) {
+                int b = s->no_delay;
+                if (setsockopt(fd, SOL_TCP, TCP_NODELAY, &b, sizeof(b)) < 0)
+                        log_warning_unit(UNIT(s)->id, "TCP_NODELAY failed: %m");
+        }
+
         if (s->broadcast) {
                 int one = 1;
                 if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &one, sizeof(one)) < 0)
@@ -886,9 +999,7 @@ static int fifo_address_create(
 
 fail:
         label_context_clear();
-
-        if (fd >= 0)
-                close_nointr_nofail(fd);
+        safe_close(fd);
 
         return r;
 }
@@ -903,7 +1014,8 @@ static int special_address_create(
         assert(path);
         assert(_fd);
 
-        if ((fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW)) < 0) {
+        fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW);
+        if (fd < 0) {
                 r = -errno;
                 goto fail;
         }
@@ -923,8 +1035,7 @@ static int special_address_create(
         return 0;
 
 fail:
-        if (fd >= 0)
-                close_nointr_nofail(fd);
+        safe_close(fd);
 
         return r;
 }
@@ -957,7 +1068,6 @@ static int mq_address_create(
 
         /* Include the original umask in our mask */
         umask(~mq_mode | old_mask);
-
         fd = mq_open(path, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_CREAT, mq_mode, attr);
         umask(old_mask);
 
@@ -983,12 +1093,26 @@ static int mq_address_create(
         return 0;
 
 fail:
-        if (fd >= 0)
-                close_nointr_nofail(fd);
-
+        safe_close(fd);
         return r;
 }
 
+static int socket_symlink(Socket *s) {
+        const char *p;
+        char **i;
+
+        assert(s);
+
+        p = socket_find_symlink_target(s);
+        if (!p)
+                return 0;
+
+        STRV_FOREACH(i, s->symlinks)
+                symlink(p, *i);
+
+        return 0;
+}
+
 static int socket_open_fds(Socket *s) {
         SocketPort *p;
         int r;
@@ -1006,17 +1130,15 @@ static int socket_open_fds(Socket *s) {
 
                         if (!know_label) {
 
-                                if ((r = socket_instantiate_service(s)) < 0)
+                                r = socket_instantiate_service(s);
+                                if (r < 0)
                                         return r;
 
                                 if (UNIT_ISSET(s->service) &&
                                     SERVICE(UNIT_DEREF(s->service))->exec_command[SERVICE_EXEC_START]) {
                                         r = label_get_create_label_from_exe(SERVICE(UNIT_DEREF(s->service))->exec_command[SERVICE_EXEC_START]->path, &label);
-
-                                        if (r < 0) {
-                                                if (r != -EPERM)
-                                                        return r;
-                                        }
+                                        if (r < 0 && r != -EPERM)
+                                                return r;
                                 }
 
                                 know_label = true;
@@ -1038,6 +1160,7 @@ static int socket_open_fds(Socket *s) {
 
                         p->fd = r;
                         socket_apply_socket_options(s, p->fd);
+                        socket_symlink(s);
 
                 } else  if (p->type == SOCKET_SPECIAL) {
 
@@ -1058,6 +1181,8 @@ static int socket_open_fds(Socket *s) {
                                 goto rollback;
 
                         socket_apply_fifo_options(s, p->fd);
+                        socket_symlink(s);
+
                 } else if (p->type == SOCKET_MQUEUE) {
 
                         r = mq_address_create(
@@ -1091,11 +1216,12 @@ static void socket_unwatch_fds(Socket *s) {
                 if (p->fd < 0)
                         continue;
 
-                if (p->event_source) {
-                        r = sd_event_source_set_enabled(p->event_source, SD_EVENT_OFF);
-                        if (r < 0)
-                                log_debug_unit(UNIT(s)->id, "Failed to disable event source.");
-                }
+                if (!p->event_source)
+                        continue;
+
+                r = sd_event_source_set_enabled(p->event_source, SD_EVENT_OFF);
+                if (r < 0)
+                        log_debug_unit(UNIT(s)->id, "Failed to disable event source.");
         }
 }
 
@@ -1134,14 +1260,16 @@ static void socket_set_state(Socket *s, SocketState state) {
         old_state = s->state;
         s->state = state;
 
-        if (state != SOCKET_START_PRE &&
-            state != SOCKET_START_POST &&
-            state != SOCKET_STOP_PRE &&
-            state != SOCKET_STOP_PRE_SIGTERM &&
-            state != SOCKET_STOP_PRE_SIGKILL &&
-            state != SOCKET_STOP_POST &&
-            state != SOCKET_FINAL_SIGTERM &&
-            state != SOCKET_FINAL_SIGKILL) {
+        if (!IN_SET(state,
+                    SOCKET_START_PRE,
+                    SOCKET_START_CHOWN,
+                    SOCKET_START_POST,
+                    SOCKET_STOP_PRE,
+                    SOCKET_STOP_PRE_SIGTERM,
+                    SOCKET_STOP_PRE_SIGKILL,
+                    SOCKET_STOP_POST,
+                    SOCKET_FINAL_SIGTERM,
+                    SOCKET_FINAL_SIGKILL)) {
 
                 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
                 socket_unwatch_control_pid(s);
@@ -1152,12 +1280,14 @@ static void socket_set_state(Socket *s, SocketState state) {
         if (state != SOCKET_LISTENING)
                 socket_unwatch_fds(s);
 
-        if (state != SOCKET_START_POST &&
-            state != SOCKET_LISTENING &&
-            state != SOCKET_RUNNING &&
-            state != SOCKET_STOP_PRE &&
-            state != SOCKET_STOP_PRE_SIGTERM &&
-            state != SOCKET_STOP_PRE_SIGKILL)
+        if (!IN_SET(state,
+                    SOCKET_START_CHOWN,
+                    SOCKET_START_POST,
+                    SOCKET_LISTENING,
+                    SOCKET_RUNNING,
+                    SOCKET_STOP_PRE,
+                    SOCKET_STOP_PRE_SIGTERM,
+                    SOCKET_STOP_PRE_SIGKILL))
                 socket_close_fds(s);
 
         if (state != old_state)
@@ -1177,14 +1307,16 @@ static int socket_coldplug(Unit *u) {
         if (s->deserialized_state == s->state)
                 return 0;
 
-        if (s->deserialized_state == SOCKET_START_PRE ||
-            s->deserialized_state == SOCKET_START_POST ||
-            s->deserialized_state == SOCKET_STOP_PRE ||
-            s->deserialized_state == SOCKET_STOP_PRE_SIGTERM ||
-            s->deserialized_state == SOCKET_STOP_PRE_SIGKILL ||
-            s->deserialized_state == SOCKET_STOP_POST ||
-            s->deserialized_state == SOCKET_FINAL_SIGTERM ||
-            s->deserialized_state == SOCKET_FINAL_SIGKILL) {
+        if (IN_SET(s->deserialized_state,
+                   SOCKET_START_PRE,
+                   SOCKET_START_CHOWN,
+                   SOCKET_START_POST,
+                   SOCKET_STOP_PRE,
+                   SOCKET_STOP_PRE_SIGTERM,
+                   SOCKET_STOP_PRE_SIGKILL,
+                   SOCKET_STOP_POST,
+                   SOCKET_FINAL_SIGTERM,
+                   SOCKET_FINAL_SIGKILL)) {
 
                 if (s->control_pid <= 0)
                         return -EBADMSG;
@@ -1198,12 +1330,14 @@ static int socket_coldplug(Unit *u) {
                         return r;
         }
 
-        if (s->deserialized_state == SOCKET_START_POST ||
-            s->deserialized_state == SOCKET_LISTENING ||
-            s->deserialized_state == SOCKET_RUNNING ||
-            s->deserialized_state == SOCKET_STOP_PRE ||
-            s->deserialized_state == SOCKET_STOP_PRE_SIGTERM ||
-            s->deserialized_state == SOCKET_STOP_PRE_SIGKILL) {
+        if (IN_SET(s->deserialized_state,
+                   SOCKET_START_CHOWN,
+                   SOCKET_START_POST,
+                   SOCKET_LISTENING,
+                   SOCKET_RUNNING,
+                   SOCKET_STOP_PRE,
+                   SOCKET_STOP_PRE_SIGTERM,
+                   SOCKET_STOP_PRE_SIGKILL)) {
                 r = socket_open_fds(s);
                 if (r < 0)
                         return r;
@@ -1220,9 +1354,9 @@ static int socket_coldplug(Unit *u) {
 }
 
 static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) {
+        _cleanup_free_ char **argv = NULL;
         pid_t pid;
         int r;
-        char **argv;
 
         assert(s);
         assert(c);
@@ -1253,13 +1387,12 @@ static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) {
                        UNIT(s)->manager->confirm_spawn,
                        UNIT(s)->manager->cgroup_supported,
                        UNIT(s)->cgroup_path,
+                       manager_get_runtime_prefix(UNIT(s)->manager),
                        UNIT(s)->id,
                        0,
                        NULL,
                        s->exec_runtime,
                        &pid);
-
-        strv_free(argv);
         if (r < 0)
                 goto fail;
 
@@ -1269,12 +1402,94 @@ static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) {
                 goto fail;
 
         *_pid = pid;
-
         return 0;
 
 fail:
         s->timer_event_source = sd_event_source_unref(s->timer_event_source);
+        return r;
+}
+
+static int socket_chown(Socket *s, pid_t *_pid) {
+        pid_t pid;
+        int r;
+
+        r = socket_arm_timer(s);
+        if (r < 0)
+                goto fail;
+
+        /* We have to resolve the user names out-of-process, hence
+         * let's fork here. It's messy, but well, what can we do? */
+
+        pid = fork();
+        if (pid < 0)
+                return -errno;
+
+        if (pid == 0) {
+                SocketPort *p;
+                uid_t uid = (uid_t) -1;
+                gid_t gid = (gid_t) -1;
+                int ret;
+
+                default_signals(SIGNALS_CRASH_HANDLER, SIGNALS_IGNORE, -1);
+                ignore_signals(SIGPIPE, -1);
+                log_forget_fds();
+
+                if (!isempty(s->user)) {
+                        const char *user = s->user;
+
+                        r = get_user_creds(&user, &uid, &gid, NULL, NULL);
+                        if (r < 0) {
+                                ret = EXIT_USER;
+                                goto fail_child;
+                        }
+                }
+
+                if (!isempty(s->group)) {
+                        const char *group = s->group;
 
+                        r = get_group_creds(&group, &gid);
+                        if (r < 0) {
+                                ret = EXIT_GROUP;
+                                goto fail_child;
+                        }
+                }
+
+                LIST_FOREACH(port, p, s->ports) {
+                        const char *path = NULL;
+
+                        if (p->type == SOCKET_SOCKET)
+                                path = socket_address_get_path(&p->address);
+                        else if (p->type == SOCKET_FIFO)
+                                path = p->path;
+
+                        if (!path)
+                                continue;
+
+                        if (chown(path, uid, gid) < 0) {
+                                r = -errno;
+                                ret = EXIT_CHOWN;
+                                goto fail_child;
+                        }
+                }
+
+                _exit(0);
+
+        fail_child:
+                log_open();
+                log_error("Failed to chown socket at step %s: %s", exit_status_to_string(ret, EXIT_STATUS_SYSTEMD), strerror(-r));
+
+                _exit(ret);
+        }
+
+        r = unit_watch_pid(UNIT(s), pid);
+        if (r < 0)
+                goto fail;
+
+        *_pid = pid;
+        return 0;
+
+fail:
+        s->timer_event_source = sd_event_source_unref(s->timer_event_source);
         return r;
 }
 
@@ -1287,6 +1502,8 @@ static void socket_enter_dead(Socket *s, SocketResult f) {
         exec_runtime_destroy(s->exec_runtime);
         s->exec_runtime = exec_runtime_unref(s->exec_runtime);
 
+        exec_context_destroy_runtime_directory(&s->exec_context, manager_get_runtime_prefix(UNIT(s)->manager));
+
         socket_set_state(s, s->result != SOCKET_SUCCESS ? SOCKET_FAILED : SOCKET_DEAD);
 }
 
@@ -1300,11 +1517,12 @@ static void socket_enter_stop_post(Socket *s, SocketResult f) {
                 s->result = f;
 
         socket_unwatch_control_pid(s);
-
         s->control_command_id = SOCKET_EXEC_STOP_POST;
+        s->control_command = s->exec_command[SOCKET_EXEC_STOP_POST];
 
-        if ((s->control_command = s->exec_command[SOCKET_EXEC_STOP_POST])) {
-                if ((r = socket_spawn(s, s->control_command, &s->control_pid)) < 0)
+        if (s->control_command) {
+                r = socket_spawn(s, s->control_command, &s->control_pid);
+                if (r < 0)
                         goto fail;
 
                 socket_set_state(s, SOCKET_STOP_POST);
@@ -1372,11 +1590,12 @@ static void socket_enter_stop_pre(Socket *s, SocketResult f) {
                 s->result = f;
 
         socket_unwatch_control_pid(s);
-
         s->control_command_id = SOCKET_EXEC_STOP_PRE;
+        s->control_command = s->exec_command[SOCKET_EXEC_STOP_PRE];
 
-        if ((s->control_command = s->exec_command[SOCKET_EXEC_STOP_PRE])) {
-                if ((r = socket_spawn(s, s->control_command, &s->control_pid)) < 0)
+        if (s->control_command) {
+                r = socket_spawn(s, s->control_command, &s->control_pid);
+                if (r < 0)
                         goto fail;
 
                 socket_set_state(s, SOCKET_STOP_PRE);
@@ -1411,26 +1630,53 @@ static void socket_enter_start_post(Socket *s) {
         int r;
         assert(s);
 
+        socket_unwatch_control_pid(s);
+        s->control_command_id = SOCKET_EXEC_START_POST;
+        s->control_command = s->exec_command[SOCKET_EXEC_START_POST];
+
+        if (s->control_command) {
+                r = socket_spawn(s, s->control_command, &s->control_pid);
+                if (r < 0) {
+                        log_warning_unit(UNIT(s)->id, "%s failed to run 'start-post' task: %s", UNIT(s)->id, strerror(-r));
+                        goto fail;
+                }
+
+                socket_set_state(s, SOCKET_START_POST);
+        } else
+                socket_enter_listening(s);
+
+        return;
+
+fail:
+        socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
+}
+
+static void socket_enter_start_chown(Socket *s) {
+        int r;
+
+        assert(s);
+
         r = socket_open_fds(s);
         if (r < 0) {
                 log_warning_unit(UNIT(s)->id, "%s failed to listen on sockets: %s", UNIT(s)->id, strerror(-r));
                 goto fail;
         }
 
-        socket_unwatch_control_pid(s);
+        if (!isempty(s->user) || !isempty(s->group)) {
 
-        s->control_command_id = SOCKET_EXEC_START_POST;
+                socket_unwatch_control_pid(s);
+                s->control_command_id = SOCKET_EXEC_START_CHOWN;
+                s->control_command = NULL;
 
-        if ((s->control_command = s->exec_command[SOCKET_EXEC_START_POST])) {
-                r = socket_spawn(s, s->control_command, &s->control_pid);
+                r = socket_chown(s, &s->control_pid);
                 if (r < 0) {
-                        log_warning_unit(UNIT(s)->id, "%s failed to run 'start-post' task: %s", UNIT(s)->id, strerror(-r));
+                        log_warning_unit(UNIT(s)->id, "%s failed to fork 'start-chown' task: %s", UNIT(s)->id, strerror(-r));
                         goto fail;
                 }
 
-                socket_set_state(s, SOCKET_START_POST);
+                socket_set_state(s, SOCKET_START_CHOWN);
         } else
-                socket_enter_listening(s);
+                socket_enter_start_post(s);
 
         return;
 
@@ -1443,22 +1689,23 @@ static void socket_enter_start_pre(Socket *s) {
         assert(s);
 
         socket_unwatch_control_pid(s);
-
         s->control_command_id = SOCKET_EXEC_START_PRE;
+        s->control_command = s->exec_command[SOCKET_EXEC_START_PRE];
 
-        if ((s->control_command = s->exec_command[SOCKET_EXEC_START_PRE])) {
+        if (s->control_command) {
                 r = socket_spawn(s, s->control_command, &s->control_pid);
-                if (r < 0)
+                if (r < 0) {
+                        log_warning_unit(UNIT(s)->id, "%s failed to run 'start-pre' task: %s", UNIT(s)->id, strerror(-r));
                         goto fail;
+                }
 
                 socket_set_state(s, SOCKET_START_PRE);
         } else
-                socket_enter_start_post(s);
+                socket_enter_start_chown(s);
 
         return;
 
 fail:
-        log_warning_unit(UNIT(s)->id, "%s failed to run 'start-pre' task: %s", UNIT(s)->id, strerror(-r));
         socket_enter_dead(s, SOCKET_FAILURE_RESOURCES);
 }
 
@@ -1475,7 +1722,7 @@ static void socket_enter_running(Socket *s, int cfd) {
                 log_debug_unit(UNIT(s)->id, "Suppressing connection request on %s since unit stop is scheduled.", UNIT(s)->id);
 
                 if (cfd >= 0)
-                        close_nointr_nofail(cfd);
+                        safe_close(cfd);
                 else  {
                         /* Flush all sockets by closing and reopening them */
                         socket_close_fds(s);
@@ -1511,6 +1758,12 @@ static void socket_enter_running(Socket *s, int cfd) {
                         }
 
                 if (!pending) {
+                        if (!UNIT_ISSET(s->service)) {
+                                log_error_unit(UNIT(s)->id, "%s: service to activate vanished, refusing activation.", UNIT(s)->id);
+                                r = -ENOENT;
+                                goto fail;
+                        }
+
                         r = manager_add_job(UNIT(s)->manager, JOB_START, UNIT_DEREF(s->service), JOB_REPLACE, true, &error, NULL);
                         if (r < 0)
                                 goto fail;
@@ -1523,7 +1776,7 @@ static void socket_enter_running(Socket *s, int cfd) {
 
                 if (s->n_connections >= s->max_connections) {
                         log_warning_unit(UNIT(s)->id, "%s: Too many incoming connections (%u)", UNIT(s)->id, s->n_connections);
-                        close_nointr_nofail(cfd);
+                        safe_close(cfd);
                         return;
                 }
 
@@ -1538,7 +1791,7 @@ static void socket_enter_running(Socket *s, int cfd) {
 
                         /* ENOTCONN is legitimate if TCP RST was received.
                          * This connection is over, but the socket unit lives on. */
-                        close_nointr_nofail(cfd);
+                        safe_close(cfd);
                         return;
                 }
 
@@ -1589,9 +1842,7 @@ fail:
                          bus_error_message(&error, r));
 
         socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
-
-        if (cfd >= 0)
-                close_nointr_nofail(cfd);
+        safe_close(cfd);
 }
 
 static void socket_run_next(Socket *s) {
@@ -1629,16 +1880,20 @@ static int socket_start(Unit *u) {
 
         /* We cannot fulfill this request right now, try again later
          * please! */
-        if (s->state == SOCKET_STOP_PRE ||
-            s->state == SOCKET_STOP_PRE_SIGKILL ||
-            s->state == SOCKET_STOP_PRE_SIGTERM ||
-            s->state == SOCKET_STOP_POST ||
-            s->state == SOCKET_FINAL_SIGTERM ||
-            s->state == SOCKET_FINAL_SIGKILL)
+        if (IN_SET(s->state,
+                   SOCKET_STOP_PRE,
+                   SOCKET_STOP_PRE_SIGKILL,
+                   SOCKET_STOP_PRE_SIGTERM,
+                   SOCKET_STOP_POST,
+                   SOCKET_FINAL_SIGTERM,
+                   SOCKET_FINAL_SIGKILL))
                 return -EAGAIN;
 
-        if (s->state == SOCKET_START_PRE ||
-            s->state == SOCKET_START_POST)
+        /* Already on it! */
+        if (IN_SET(s->state,
+                   SOCKET_START_PRE,
+                   SOCKET_START_CHOWN,
+                   SOCKET_START_POST))
                 return 0;
 
         /* Cannot run this without the service being around */
@@ -1660,14 +1915,6 @@ static int socket_start(Unit *u) {
                         log_error_unit(u->id, "Socket service %s already active, refusing.", UNIT(service)->id);
                         return -EBUSY;
                 }
-
-#ifdef HAVE_SYSV_COMPAT
-                if (service->is_sysv) {
-                        log_error_unit(u->id,
-                                       "Using SysV services for socket activation is not supported. Refusing.");
-                        return -ENOENT;
-                }
-#endif
         }
 
         assert(s->state == SOCKET_DEAD || s->state == SOCKET_FAILED);
@@ -1684,18 +1931,21 @@ static int socket_stop(Unit *u) {
         assert(s);
 
         /* Already on it */
-        if (s->state == SOCKET_STOP_PRE ||
-            s->state == SOCKET_STOP_PRE_SIGTERM ||
-            s->state == SOCKET_STOP_PRE_SIGKILL ||
-            s->state == SOCKET_STOP_POST ||
-            s->state == SOCKET_FINAL_SIGTERM ||
-            s->state == SOCKET_FINAL_SIGKILL)
+        if (IN_SET(s->state,
+                   SOCKET_STOP_PRE,
+                   SOCKET_STOP_PRE_SIGTERM,
+                   SOCKET_STOP_PRE_SIGKILL,
+                   SOCKET_STOP_POST,
+                   SOCKET_FINAL_SIGTERM,
+                   SOCKET_FINAL_SIGKILL))
                 return 0;
 
         /* If there's already something running we go directly into
          * kill mode. */
-        if (s->state == SOCKET_START_PRE ||
-            s->state == SOCKET_START_POST) {
+        if (IN_SET(s->state,
+                   SOCKET_START_PRE,
+                   SOCKET_START_CHOWN,
+                   SOCKET_START_POST)) {
                 socket_enter_signal(s, SOCKET_STOP_PRE_SIGTERM, SOCKET_SUCCESS);
                 return -EAGAIN;
         }
@@ -1720,7 +1970,7 @@ static int socket_serialize(Unit *u, FILE *f, FDSet *fds) {
         unit_serialize_item_format(u, f, "n-accepted", "%u", s->n_accepted);
 
         if (s->control_pid > 0)
-                unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) s->control_pid);
+                unit_serialize_item_format(u, f, "control-pid", PID_FMT, s->control_pid);
 
         if (s->control_command_id >= 0)
                 unit_serialize_item(u, f, "control-command", socket_exec_command_to_string(s->control_command_id));
@@ -1822,8 +2072,7 @@ static int socket_deserialize_item(Unit *u, const char *key, const char *value,
                                         break;
 
                         if (p) {
-                                if (p->fd >= 0)
-                                        close_nointr_nofail(p->fd);
+                                safe_close(p->fd);
                                 p->fd = fdset_remove(fds, fd);
                         }
                 }
@@ -1842,8 +2091,7 @@ static int socket_deserialize_item(Unit *u, const char *key, const char *value,
                                         break;
 
                         if (p) {
-                                if (p->fd >= 0)
-                                        close_nointr_nofail(p->fd);
+                                safe_close(p->fd);
                                 p->fd = fdset_remove(fds, fd);
                         }
                 }
@@ -1862,8 +2110,7 @@ static int socket_deserialize_item(Unit *u, const char *key, const char *value,
                                         break;
 
                         if (p) {
-                                if (p->fd >= 0)
-                                        close_nointr_nofail(p->fd);
+                                safe_close(p->fd);
                                 p->fd = fdset_remove(fds, fd);
                         }
                 }
@@ -1881,8 +2128,7 @@ static int socket_deserialize_item(Unit *u, const char *key, const char *value,
                                         break;
 
                         if (p) {
-                                if (p->fd >= 0)
-                                        close_nointr_nofail(p->fd);
+                                safe_close(p->fd);
                                 p->fd = fdset_remove(fds, fd);
                         }
                 }
@@ -1900,8 +2146,7 @@ static int socket_deserialize_item(Unit *u, const char *key, const char *value,
                                         break;
 
                         if (p) {
-                                if (p->fd >= 0)
-                                        close_nointr_nofail(p->fd);
+                                safe_close(p->fd);
                                 p->fd = fdset_remove(fds, fd);
                         }
                 }
@@ -2076,7 +2321,7 @@ static void socket_sigchld_event(Unit *u, pid_t pid, int code, int status) {
         else if (code == CLD_DUMPED)
                 f = SOCKET_FAILURE_CORE_DUMP;
         else
-                assert_not_reached("Unknown code");
+                assert_not_reached("Unknown sigchld code");
 
         if (s->control_command) {
                 exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
@@ -2116,11 +2361,18 @@ static void socket_sigchld_event(Unit *u, pid_t pid, int code, int status) {
 
                 case SOCKET_START_PRE:
                         if (f == SOCKET_SUCCESS)
-                                socket_enter_start_post(s);
+                                socket_enter_start_chown(s);
                         else
                                 socket_enter_signal(s, SOCKET_FINAL_SIGTERM, f);
                         break;
 
+                case SOCKET_START_CHOWN:
+                        if (f == SOCKET_SUCCESS)
+                                socket_enter_start_post(s);
+                        else
+                                socket_enter_stop_pre(s, f);
+                        break;
+
                 case SOCKET_START_POST:
                         if (f == SOCKET_SUCCESS)
                                 socket_enter_listening(s);
@@ -2158,65 +2410,53 @@ static int socket_dispatch_timer(sd_event_source *source, usec_t usec, void *use
         switch (s->state) {
 
         case SOCKET_START_PRE:
-                log_warning_unit(UNIT(s)->id,
-                                 "%s starting timed out. Terminating.", UNIT(s)->id);
+                log_warning_unit(UNIT(s)->id, "%s starting timed out. Terminating.", UNIT(s)->id);
                 socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_FAILURE_TIMEOUT);
                 break;
 
+        case SOCKET_START_CHOWN:
         case SOCKET_START_POST:
-                log_warning_unit(UNIT(s)->id,
-                                 "%s starting timed out. Stopping.", UNIT(s)->id);
+                log_warning_unit(UNIT(s)->id, "%s starting timed out. Stopping.", UNIT(s)->id);
                 socket_enter_stop_pre(s, SOCKET_FAILURE_TIMEOUT);
                 break;
 
         case SOCKET_STOP_PRE:
-                log_warning_unit(UNIT(s)->id,
-                                 "%s stopping timed out. Terminating.", UNIT(s)->id);
+                log_warning_unit(UNIT(s)->id, "%s stopping timed out. Terminating.", UNIT(s)->id);
                 socket_enter_signal(s, SOCKET_STOP_PRE_SIGTERM, SOCKET_FAILURE_TIMEOUT);
                 break;
 
         case SOCKET_STOP_PRE_SIGTERM:
                 if (s->kill_context.send_sigkill) {
-                        log_warning_unit(UNIT(s)->id,
-                                         "%s stopping timed out. Killing.", UNIT(s)->id);
+                        log_warning_unit(UNIT(s)->id, "%s stopping timed out. Killing.", UNIT(s)->id);
                         socket_enter_signal(s, SOCKET_STOP_PRE_SIGKILL, SOCKET_FAILURE_TIMEOUT);
                 } else {
-                        log_warning_unit(UNIT(s)->id,
-                                         "%s stopping timed out. Skipping SIGKILL. Ignoring.",
-                                         UNIT(s)->id);
+                        log_warning_unit(UNIT(s)->id, "%s stopping timed out. Skipping SIGKILL. Ignoring.", UNIT(s)->id);
                         socket_enter_stop_post(s, SOCKET_FAILURE_TIMEOUT);
                 }
                 break;
 
         case SOCKET_STOP_PRE_SIGKILL:
-                log_warning_unit(UNIT(s)->id,
-                                 "%s still around after SIGKILL. Ignoring.", UNIT(s)->id);
+                log_warning_unit(UNIT(s)->id, "%s still around after SIGKILL. Ignoring.", UNIT(s)->id);
                 socket_enter_stop_post(s, SOCKET_FAILURE_TIMEOUT);
                 break;
 
         case SOCKET_STOP_POST:
-                log_warning_unit(UNIT(s)->id,
-                                 "%s stopping timed out (2). Terminating.", UNIT(s)->id);
+                log_warning_unit(UNIT(s)->id, "%s stopping timed out (2). Terminating.", UNIT(s)->id);
                 socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_FAILURE_TIMEOUT);
                 break;
 
         case SOCKET_FINAL_SIGTERM:
                 if (s->kill_context.send_sigkill) {
-                        log_warning_unit(UNIT(s)->id,
-                                         "%s stopping timed out (2). Killing.", UNIT(s)->id);
+                        log_warning_unit(UNIT(s)->id, "%s stopping timed out (2). Killing.", UNIT(s)->id);
                         socket_enter_signal(s, SOCKET_FINAL_SIGKILL, SOCKET_FAILURE_TIMEOUT);
                 } else {
-                        log_warning_unit(UNIT(s)->id,
-                                         "%s stopping timed out (2). Skipping SIGKILL. Ignoring.",
-                                         UNIT(s)->id);
+                        log_warning_unit(UNIT(s)->id, "%s stopping timed out (2). Skipping SIGKILL. Ignoring.", UNIT(s)->id);
                         socket_enter_dead(s, SOCKET_FAILURE_TIMEOUT);
                 }
                 break;
 
         case SOCKET_FINAL_SIGKILL:
-                log_warning_unit(UNIT(s)->id,
-                                 "%s still around after SIGKILL (2). Entering failed mode.",
-                                 UNIT(s)->id);
+                log_warning_unit(UNIT(s)->id, "%s still around after SIGKILL (2). Entering failed mode.", UNIT(s)->id);
                 socket_enter_dead(s, SOCKET_FAILURE_TIMEOUT);
                 break;
 
@@ -2365,6 +2605,7 @@ static int socket_get_timeout(Unit *u, uint64_t *timeout) {
 static const char* const socket_state_table[_SOCKET_STATE_MAX] = {
         [SOCKET_DEAD] = "dead",
         [SOCKET_START_PRE] = "start-pre",
+        [SOCKET_START_CHOWN] = "start-chown",
         [SOCKET_START_POST] = "start-post",
         [SOCKET_LISTENING] = "listening",
         [SOCKET_RUNNING] = "running",
@@ -2381,6 +2622,7 @@ DEFINE_STRING_TABLE_LOOKUP(socket_state, SocketState);
 
 static const char* const socket_exec_command_table[_SOCKET_EXEC_COMMAND_MAX] = {
         [SOCKET_EXEC_START_PRE] = "StartPre",
+        [SOCKET_EXEC_START_CHOWN] = "StartChown",
         [SOCKET_EXEC_START_POST] = "StartPost",
         [SOCKET_EXEC_STOP_PRE] = "StopPre",
         [SOCKET_EXEC_STOP_POST] = "StopPost"
index 076a183..eede705 100644 (file)
@@ -32,6 +32,7 @@ typedef struct Socket Socket;
 typedef enum SocketState {
         SOCKET_DEAD,
         SOCKET_START_PRE,
+        SOCKET_START_CHOWN,
         SOCKET_START_POST,
         SOCKET_LISTENING,
         SOCKET_RUNNING,
@@ -48,6 +49,7 @@ typedef enum SocketState {
 
 typedef enum SocketExecCommand {
         SOCKET_EXEC_START_PRE,
+        SOCKET_EXEC_START_CHOWN,
         SOCKET_EXEC_START_POST,
         SOCKET_EXEC_STOP_PRE,
         SOCKET_EXEC_STOP_POST,
@@ -99,7 +101,11 @@ struct Socket {
         unsigned max_connections;
 
         unsigned backlog;
+        unsigned keep_alive_cnt;
         usec_t timeout_usec;
+        usec_t keep_alive_time;
+        usec_t keep_alive_interval;
+        usec_t defer_accept;
 
         ExecCommand* exec_command[_SOCKET_EXEC_COMMAND_MAX];
         ExecContext exec_context;
@@ -125,10 +131,14 @@ struct Socket {
 
         SocketResult result;
 
+        char **symlinks;
+
         bool accept;
+        bool remove_on_stop;
 
         /* Socket options */
         bool keep_alive;
+        bool no_delay;
         bool free_bind;
         bool transparent;
         bool broadcast;
@@ -154,6 +164,8 @@ struct Socket {
         char *smack;
         char *smack_ip_in;
         char *smack_ip_out;
+
+        char *user, *group;
 };
 
 /* Called from the service code when collecting fds */
@@ -176,3 +188,5 @@ const char* socket_result_to_string(SocketResult i) _const_;
 SocketResult socket_result_from_string(const char *s) _pure_;
 
 const char* socket_port_type_to_string(SocketPort *p) _pure_;
+
+int socket_instantiate_service(Socket *s);
index 24c4611..9f353af 100644 (file)
@@ -118,11 +118,8 @@ static void swap_init(Unit *u) {
 
         s->timeout_usec = u->manager->default_timeout_start_usec;
 
-        exec_context_init(&s->exec_context);
         s->exec_context.std_output = u->manager->default_std_output;
         s->exec_context.std_error = u->manager->default_std_error;
-        kill_context_init(&s->kill_context);
-        cgroup_context_init(&s->cgroup_context);
 
         s->parameters_proc_swaps.priority = s->parameters_fragment.priority = -1;
 
@@ -155,8 +152,6 @@ static void swap_done(Unit *u) {
         free(s->parameters_fragment.what);
         s->parameters_fragment.what = NULL;
 
-        cgroup_context_done(&s->cgroup_context);
-        exec_context_done(&s->exec_context);
         s->exec_runtime = exec_runtime_unref(s->exec_runtime);
         exec_command_done_array(s->exec_command, _SWAP_EXEC_COMMAND_MAX);
         s->control_command = NULL;
@@ -184,7 +179,12 @@ static int swap_arm_timer(Swap *s) {
                 return sd_event_source_set_enabled(s->timer_event_source, SD_EVENT_ONESHOT);
         }
 
-        return sd_event_add_monotonic(UNIT(s)->manager->event, &s->timer_event_source, now(CLOCK_MONOTONIC) + s->timeout_usec, 0, swap_dispatch_timer, s);
+        return sd_event_add_time(
+                        UNIT(s)->manager->event,
+                        &s->timer_event_source,
+                        CLOCK_MONOTONIC,
+                        now(CLOCK_MONOTONIC) + s->timeout_usec, 0,
+                        swap_dispatch_timer, s);
 }
 
 static int swap_add_device_links(Swap *s) {
@@ -303,9 +303,6 @@ static int swap_load(Unit *u) {
                 return r;
 
         if (u->load_state == UNIT_LOADED) {
-                r = unit_add_exec_dependencies(u, &s->exec_context);
-                if (r < 0)
-                        return r;
 
                 if (UNIT(s)->fragment_path)
                         s->from_fragment = true;
@@ -342,7 +339,15 @@ static int swap_load(Unit *u) {
                 if (r < 0)
                         return r;
 
-                r = unit_add_default_slice(u);
+                r = unit_patch_contexts(u);
+                if (r < 0)
+                        return r;
+
+                r = unit_add_exec_dependencies(u, &s->exec_context);
+                if (r < 0)
+                        return r;
+
+                r = unit_add_default_slice(u, &s->cgroup_context);
                 if (r < 0)
                         return r;
 
@@ -351,10 +356,6 @@ static int swap_load(Unit *u) {
                         if (r < 0)
                                 return r;
                 }
-
-                r = unit_exec_context_defaults(u, &s->exec_context);
-                if (r < 0)
-                        return r;
         }
 
         return swap_verify(s);
@@ -608,8 +609,8 @@ static void swap_dump(Unit *u, FILE *f, const char *prefix) {
 
         if (s->control_pid > 0)
                 fprintf(f,
-                        "%sControl PID: %lu\n",
-                        prefix, (unsigned long) s->control_pid);
+                        "%sControl PID: "PID_FMT"\n",
+                        prefix, s->control_pid);
 
         exec_context_dump(&s->exec_context, f, prefix);
         kill_context_dump(&s->kill_context, f, prefix);
@@ -644,6 +645,7 @@ static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) {
                        UNIT(s)->manager->confirm_spawn,
                        UNIT(s)->manager->cgroup_supported,
                        UNIT(s)->cgroup_path,
+                       manager_get_runtime_prefix(UNIT(s)->manager),
                        UNIT(s)->id,
                        0,
                        NULL,
@@ -676,6 +678,8 @@ static void swap_enter_dead(Swap *s, SwapResult f) {
         exec_runtime_destroy(s->exec_runtime);
         s->exec_runtime = exec_runtime_unref(s->exec_runtime);
 
+        exec_context_destroy_runtime_directory(&s->exec_context, manager_get_runtime_prefix(UNIT(s)->manager));
+
         swap_set_state(s, s->result != SWAP_SUCCESS ? SWAP_FAILED : SWAP_DEAD);
 }
 
@@ -874,7 +878,7 @@ static int swap_serialize(Unit *u, FILE *f, FDSet *fds) {
         unit_serialize_item(u, f, "result", swap_result_to_string(s->result));
 
         if (s->control_pid > 0)
-                unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) s->control_pid);
+                unit_serialize_item_format(u, f, "control-pid", PID_FMT, s->control_pid);
 
         if (s->control_command_id >= 0)
                 unit_serialize_item(u, f, "control-command", swap_exec_command_to_string(s->control_command_id));
index ce0e41d..0ea61db 100644 (file)
@@ -30,6 +30,8 @@
 #include "util.h"
 #include "path-util.h"
 #include "switch-root.h"
+#include "mkdir.h"
+#include "base-filesystem.h"
 #include "missing.h"
 
 int switch_root(const char *new_root) {
@@ -41,11 +43,11 @@ int switch_root(const char *new_root) {
                 "/sys\0"
                 "/run\0";
 
-        int r, old_root_fd = -1;
+        _cleanup_close_ int old_root_fd = -1;
         struct stat new_root_stat;
         bool old_root_remove;
-        const char *i;
-        _cleanup_free_ char *temporary_old_root = NULL;
+        const char *i, *temporary_old_root;
+        int r;
 
         if (path_equal(new_root, "/"))
                 return 0;
@@ -56,16 +58,14 @@ int switch_root(const char *new_root) {
          * directory we choose for this, but it should be more likely
          * than not that /mnt exists and is suitable as mount point
          * and is on the same fs as the old root dir */
-        temporary_old_root = strappend(new_root, "/mnt");
-        if (!temporary_old_root)
-                return -ENOMEM;
+        temporary_old_root = strappenda(new_root, "/mnt");
+        mkdir_p(temporary_old_root, 0755);
 
         old_root_remove = in_initrd();
 
         if (stat(new_root, &new_root_stat) < 0) {
-                r = -errno;
                 log_error("Failed to stat directory %s: %m", new_root);
-                goto fail;
+                return -errno;
         }
 
         /* Work-around for a kernel bug: for some reason the kernel
@@ -84,6 +84,8 @@ int switch_root(const char *new_root) {
                 snprintf(new_mount, sizeof(new_mount), "%s%s", new_root, i);
                 char_array_0(new_mount);
 
+                mkdir_p(new_mount, 0755);
+
                 if ((stat(new_mount, &sb) < 0) ||
                     sb.st_dev != new_root_stat.st_dev) {
 
@@ -103,10 +105,15 @@ int switch_root(const char *new_root) {
                 }
         }
 
+        r = base_filesystem_create(new_root);
+        if (r < 0) {
+                log_error("Failed to create the base filesystem: %s", strerror(-r));
+                return r;
+        }
+
         if (chdir(new_root) < 0) {
-                r = -errno;
                 log_error("Failed to change directory to %s: %m", new_root);
-                goto fail;
+                return -errno;
         }
 
         if (old_root_remove) {
@@ -122,28 +129,24 @@ int switch_root(const char *new_root) {
 
                 /* Immediately get rid of the old root. Since we are
                  * running off it we need to do this lazily. */
-                if (umount2(temporary_old_root, MNT_DETACH) < 0) {
-                        r = -errno;
-                        log_error("Failed to umount old root dir %s: %m", temporary_old_root);
-                        goto fail;
+                if (umount2("/mnt", MNT_DETACH) < 0) {
+                        log_error("Failed to umount old root dir /mnt: %m");
+                        return -errno;
                 }
 
         } else if (mount(new_root, "/", NULL, MS_MOVE, NULL) < 0) {
-                r = -errno;
                 log_error("Failed to mount moving %s to /: %m", new_root);
-                goto fail;
+                return -errno;
         }
 
         if (chroot(".") < 0) {
-                r = -errno;
                 log_error("Failed to change root: %m");
-                goto fail;
+                return -errno;
         }
 
         if (chdir("/") < 0) {
-                r = -errno;
                 log_error("Failed to change directory: %m");
-                goto fail;
+                return -errno;
         }
 
         if (old_root_fd >= 0) {
@@ -157,11 +160,5 @@ int switch_root(const char *new_root) {
                 }
         }
 
-        r = 0;
-
-fail:
-        if (old_root_fd >= 0)
-                close_nointr_nofail(old_root_fd);
-
-        return r;
+        return 0;
 }
index 158919d..fc9c168 100644 (file)
@@ -23,6 +23,7 @@
 #CapabilityBoundingSet=
 #SystemCallArchitectures=
 #TimerSlackNSec=
+#DefaultTimerAccuracySec=1min
 #DefaultStandardOutput=journal
 #DefaultStandardError=inherit
 #DefaultTimeoutStartSec=90s
@@ -32,6 +33,9 @@
 #DefaultStartLimitBurst=5
 #DefaultEnvironment=
 #DefaultExtraDependencies=
+#DefaultCPUAccounting=no
+#DefaultBlockIOAccounting=no
+#DefaultMemoryAccounting=no
 #DefaultLimitCPU=
 #DefaultLimitFSIZE=
 #DefaultLimitDATA=
index de0f649..d5b86bf 100644 (file)
@@ -6,7 +6,7 @@
 #  (at your option) any later version.
 
 prefix=@prefix@
-exec_prefix=@exec_prefix@
+libdir=@libdir@
 systemdutildir=@rootlibexecdir@
 systemdsystemunitdir=@systemunitdir@
 systemdsystempresetdir=@systempresetdir@
@@ -18,7 +18,16 @@ systemdsystemunitpath=${systemdsystemconfdir}:/etc/systemd/system:/run/systemd/s
 systemduserunitpath=${systemduserconfdir}:/etc/systemd/user:/run/systemd/user:/usr/local/lib/systemd/user:/usr/local/share/systemd/user:${systemduserunitdir}:/usr/lib/systemd/user:/usr/share/systemd/user
 systemdsystemgeneratordir=@systemgeneratordir@
 systemdusergeneratordir=@usergeneratordir@
+systemdsleepdir=@systemsleepdir@
+systemdshutdowndir=@systemshutdowndir@
+tmpfilesdir=@tmpfilesdir@
+sysusersdir=@sysusersdir@
+sysctldir=@sysctldir@
+binfmtdir=@binfmtdir@
+modulesloaddir=@modulesloaddir@
 catalogdir=@catalogdir@
+systemuidmax=@systemuidmax@
+systemgidmax=@systemgidmax@
 
 Name: systemd
 Description: systemd System and Service Manager
diff --git a/src/core/tcpwrap.c b/src/core/tcpwrap.c
deleted file mode 100644 (file)
index 6c630fa..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
-  This file is part of systemd.
-
-  Copyright 2010 Lennart Poettering
-
-  systemd is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation; either version 2.1 of the License, or
-  (at your option) any later version.
-
-  systemd is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <arpa/inet.h>
-#include <netinet/in.h>
-
-#ifdef HAVE_LIBWRAP
-#include <tcpd.h>
-#endif
-
-#include "tcpwrap.h"
-#include "log.h"
-
-bool socket_tcpwrap(int fd, const char *name) {
-#ifdef HAVE_LIBWRAP
-        struct request_info req;
-        union {
-                struct sockaddr sa;
-                struct sockaddr_in in;
-                struct sockaddr_in6 in6;
-                struct sockaddr_un un;
-                struct sockaddr_storage storage;
-        } sa_union;
-        socklen_t l = sizeof(sa_union);
-
-        if (getsockname(fd, &sa_union.sa, &l) < 0)
-                return true;
-
-        if (sa_union.sa.sa_family != AF_INET &&
-            sa_union.sa.sa_family != AF_INET6)
-                return true;
-
-        request_init(&req,
-                     RQ_DAEMON, name,
-                     RQ_FILE, fd,
-                     NULL);
-
-        fromhost(&req);
-
-        if (!hosts_access(&req)) {
-                log_warning("Connection refused by tcpwrap.");
-                return false;
-        }
-
-        log_debug("Connection accepted by tcpwrap.");
-#endif
-        return true;
-}
index 1c3ab29..dc0f289 100644 (file)
@@ -28,6 +28,7 @@
 #include "special.h"
 #include "bus-util.h"
 #include "bus-error.h"
+#include "mkdir.h"
 
 static const UnitActiveState state_translation_table[_TIMER_STATE_MAX] = {
         [TIMER_DEAD] = UNIT_INACTIVE,
@@ -45,9 +46,9 @@ static void timer_init(Unit *u) {
         assert(u);
         assert(u->load_state == UNIT_STUB);
 
-        t->next_elapse_monotonic = (usec_t) -1;
-        t->next_elapse_realtime = (usec_t) -1;
-        t->accuracy_usec = USEC_PER_MINUTE;
+        t->next_elapse_monotonic_or_boottime = USEC_INFINITY;
+        t->next_elapse_realtime = USEC_INFINITY;
+        t->accuracy_usec = u->manager->default_timer_accuracy_usec;
 }
 
 void timer_free_values(Timer *t) {
@@ -74,6 +75,8 @@ static void timer_done(Unit *u) {
 
         t->monotonic_event_source = sd_event_source_unref(t->monotonic_event_source);
         t->realtime_event_source = sd_event_source_unref(t->realtime_event_source);
+
+        free(t->stamp_path);
 }
 
 static int timer_verify(Timer *t) {
@@ -83,8 +86,7 @@ static int timer_verify(Timer *t) {
                 return 0;
 
         if (!t->values) {
-                log_error_unit(UNIT(t)->id,
-                               "%s lacks value setting. Refusing.", UNIT(t)->id);
+                log_error_unit(UNIT(t)->id, "%s lacks value setting. Refusing.", UNIT(t)->id);
                 return -EINVAL;
         }
 
@@ -93,6 +95,7 @@ static int timer_verify(Timer *t) {
 
 static int timer_add_default_dependencies(Timer *t) {
         int r;
+        TimerValue *v;
 
         assert(t);
 
@@ -104,11 +107,61 @@ static int timer_add_default_dependencies(Timer *t) {
                 r = unit_add_two_dependencies_by_name(UNIT(t), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true);
                 if (r < 0)
                         return r;
+
+                LIST_FOREACH(value, v, t->values) {
+                        if (v->base == TIMER_CALENDAR) {
+                                r = unit_add_dependency_by_name(UNIT(t), UNIT_AFTER, SPECIAL_TIME_SYNC_TARGET, NULL, true);
+                                if (r < 0)
+                                        return r;
+                                break;
+                        }
+                }
         }
 
         return unit_add_two_dependencies_by_name(UNIT(t), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true);
 }
 
+static int timer_setup_persistent(Timer *t) {
+        int r;
+
+        assert(t);
+
+        if (!t->persistent)
+                return 0;
+
+        if (UNIT(t)->manager->running_as == SYSTEMD_SYSTEM) {
+
+                r = unit_require_mounts_for(UNIT(t), "/var/lib/systemd/timers");
+                if (r < 0)
+                        return r;
+
+                t->stamp_path = strappend("/var/lib/systemd/timers/stamp-", UNIT(t)->id);
+        } else {
+                const char *e;
+
+                e = getenv("XDG_DATA_HOME");
+                if (e)
+                        t->stamp_path = strjoin(e, "/systemd/timers/stamp-", UNIT(t)->id, NULL);
+                else {
+
+                        _cleanup_free_ char *h = NULL;
+
+                        r = get_home_dir(&h);
+                        if (r < 0) {
+                                log_error("Failed to determine home directory: %s", strerror(-r));
+                                return r;
+                        }
+
+                        t->stamp_path = strjoin(h, "/.local/share/systemd/timers/stamp-", UNIT(t)->id, NULL);
+                }
+        }
+
+        if (!t->stamp_path)
+                return log_oom();
+
+        return 0;
+}
+
 static int timer_load(Unit *u) {
         Timer *t = TIMER(u);
         int r;
@@ -134,7 +187,11 @@ static int timer_load(Unit *u) {
                                 return r;
                 }
 
-                if (UNIT(t)->default_dependencies) {
+                r = timer_setup_persistent(t);
+                if (r < 0)
+                        return r;
+
+                if (u->default_dependencies) {
                         r = timer_add_default_dependencies(t);
                         if (r < 0)
                                 return r;
@@ -156,10 +213,14 @@ static void timer_dump(Unit *u, FILE *f, const char *prefix) {
                 "%sTimer State: %s\n"
                 "%sResult: %s\n"
                 "%sUnit: %s\n"
+                "%sPersistent: %s\n"
+                "%sWakeSystem: %s\n"
                 "%sAccuracy: %s\n",
                 prefix, timer_state_to_string(t->state),
                 prefix, timer_result_to_string(t->result),
                 prefix, trigger ? trigger->id : "n/a",
+                prefix, yes_no(t->persistent),
+                prefix, yes_no(t->wake_system),
                 prefix, format_timespan(buf, sizeof(buf), t->accuracy_usec, 1));
 
         LIST_FOREACH(value, v, t->values) {
@@ -235,16 +296,34 @@ static void timer_enter_dead(Timer *t, TimerResult f) {
         timer_set_state(t, t->result != TIMER_SUCCESS ? TIMER_FAILED : TIMER_DEAD);
 }
 
+static usec_t monotonic_to_boottime(usec_t t) {
+        usec_t a, b;
+
+        if (t <= 0)
+                return 0;
+
+        a = now(CLOCK_BOOTTIME);
+        b = now(CLOCK_MONOTONIC);
+
+        if (t + a > b)
+                return t + a - b;
+        else
+                return 0;
+}
 
 static void timer_enter_waiting(Timer *t, bool initial) {
-        TimerValue *v;
-        usec_t base = 0;
-        dual_timestamp ts;
         bool found_monotonic = false, found_realtime = false;
+        usec_t ts_realtime, ts_monotonic;
+        usec_t base = 0;
+        TimerValue *v;
         int r;
 
-        dual_timestamp_get(&ts);
-        t->next_elapse_monotonic = t->next_elapse_realtime = 0;
+        /* If we shall wake the system we use the boottime clock
+         * rather than the monotonic clock. */
+
+        ts_realtime = now(CLOCK_REALTIME);
+        ts_monotonic = now(t->wake_system ? CLOCK_BOOTTIME : CLOCK_MONOTONIC);
+        t->next_elapse_monotonic_or_boottime = t->next_elapse_realtime = 0;
 
         LIST_FOREACH(value, v, t->values) {
 
@@ -252,8 +331,16 @@ static void timer_enter_waiting(Timer *t, bool initial) {
                         continue;
 
                 if (v->base == TIMER_CALENDAR) {
+                        usec_t b;
+
+                        /* If we know the last time this was
+                         * triggered, schedule the job based relative
+                         * to that. If we don't just start from
+                         * now. */
 
-                        r = calendar_spec_next_usec(v->calendar_spec, ts.realtime, &v->next_elapse);
+                        b = t->last_trigger.realtime > 0 ? t->last_trigger.realtime : ts_realtime;
+
+                        r = calendar_spec_next_usec(v->calendar_spec, b, &v->next_elapse);
                         if (r < 0)
                                 continue;
 
@@ -271,7 +358,7 @@ static void timer_enter_waiting(Timer *t, bool initial) {
                                 if (state_translation_table[t->state] == UNIT_ACTIVE)
                                         base = UNIT(t)->inactive_exit_timestamp.monotonic;
                                 else
-                                        base = ts.monotonic;
+                                        base = ts_monotonic;
                                 break;
 
                         case TIMER_BOOT:
@@ -288,7 +375,7 @@ static void timer_enter_waiting(Timer *t, bool initial) {
                                 base = UNIT_TRIGGER(UNIT(t))->inactive_exit_timestamp.monotonic;
 
                                 if (base <= 0)
-                                        base = t->last_trigger_monotonic;
+                                        base = t->last_trigger.monotonic;
 
                                 if (base <= 0)
                                         continue;
@@ -300,7 +387,7 @@ static void timer_enter_waiting(Timer *t, bool initial) {
                                 base = UNIT_TRIGGER(UNIT(t))->inactive_enter_timestamp.monotonic;
 
                                 if (base <= 0)
-                                        base = t->last_trigger_monotonic;
+                                        base = t->last_trigger.monotonic;
 
                                 if (base <= 0)
                                         continue;
@@ -311,20 +398,21 @@ static void timer_enter_waiting(Timer *t, bool initial) {
                                 assert_not_reached("Unknown timer base");
                         }
 
+                        if (t->wake_system)
+                                base = monotonic_to_boottime(base);
+
                         v->next_elapse = base + v->value;
 
-                        if (!initial &&
-                            v->next_elapse < ts.monotonic &&
-                            (v->base == TIMER_ACTIVE || v->base == TIMER_BOOT || v->base == TIMER_STARTUP)) {
+                        if (!initial && v->next_elapse < ts_monotonic && IN_SET(v->base, TIMER_ACTIVE, TIMER_BOOT, TIMER_STARTUP)) {
                                 /* This is a one time trigger, disable it now */
                                 v->disabled = true;
                                 continue;
                         }
 
                         if (!found_monotonic)
-                                t->next_elapse_monotonic = v->next_elapse;
+                                t->next_elapse_monotonic_or_boottime = v->next_elapse;
                         else
-                                t->next_elapse_monotonic = MIN(t->next_elapse_monotonic, v->next_elapse);
+                                t->next_elapse_monotonic_or_boottime = MIN(t->next_elapse_monotonic_or_boottime, v->next_elapse);
 
                         found_monotonic = true;
                 }
@@ -338,36 +426,37 @@ static void timer_enter_waiting(Timer *t, bool initial) {
 
         if (found_monotonic) {
                 char buf[FORMAT_TIMESPAN_MAX];
-                log_debug_unit(UNIT(t)->id,
-                               "%s: Monotonic timer elapses in %s.",
+
+                log_debug_unit(UNIT(t)->id, "%s: Monotonic timer elapses in %s.",
                                UNIT(t)->id,
-                               format_timespan(buf, sizeof(buf), t->next_elapse_monotonic > ts.monotonic ? t->next_elapse_monotonic - ts.monotonic : 0, 0));
+                               format_timespan(buf, sizeof(buf), t->next_elapse_monotonic_or_boottime > ts_monotonic ? t->next_elapse_monotonic_or_boottime - ts_monotonic : 0, 0));
 
                 if (t->monotonic_event_source) {
-                        r = sd_event_source_set_time(t->monotonic_event_source, t->next_elapse_monotonic);
+                        r = sd_event_source_set_time(t->monotonic_event_source, t->next_elapse_monotonic_or_boottime);
                         if (r < 0)
                                 goto fail;
 
                         r = sd_event_source_set_enabled(t->monotonic_event_source, SD_EVENT_ONESHOT);
                 } else
-                        r = sd_event_add_monotonic(UNIT(t)->manager->event, &t->monotonic_event_source, t->next_elapse_monotonic, t->accuracy_usec, timer_dispatch, t);
-
+                        r = sd_event_add_time(
+                                        UNIT(t)->manager->event,
+                                        &t->monotonic_event_source,
+                                        t->wake_system ? CLOCK_BOOTTIME_ALARM : CLOCK_MONOTONIC,
+                                        t->next_elapse_monotonic_or_boottime, t->accuracy_usec,
+                                        timer_dispatch, t);
                 if (r < 0)
                         goto fail;
 
         } else if (t->monotonic_event_source) {
-                r = sd_event_source_set_enabled(t->monotonic_event_source, SD_EVENT_OFF);
 
+                r = sd_event_source_set_enabled(t->monotonic_event_source, SD_EVENT_OFF);
                 if (r < 0)
                         goto fail;
         }
 
         if (found_realtime) {
                 char buf[FORMAT_TIMESTAMP_MAX];
-                log_debug_unit(UNIT(t)->id,
-                               "%s: Realtime timer elapses at %s.",
-                               UNIT(t)->id,
-                               format_timestamp(buf, sizeof(buf), t->next_elapse_realtime));
+                log_debug_unit(UNIT(t)->id, "%s: Realtime timer elapses at %s.", UNIT(t)->id, format_timestamp(buf, sizeof(buf), t->next_elapse_realtime));
 
                 if (t->realtime_event_source) {
                         r = sd_event_source_set_time(t->realtime_event_source, t->next_elapse_realtime);
@@ -376,14 +465,18 @@ static void timer_enter_waiting(Timer *t, bool initial) {
 
                         r = sd_event_source_set_enabled(t->realtime_event_source, SD_EVENT_ONESHOT);
                 } else
-                        r = sd_event_add_realtime(UNIT(t)->manager->event, &t->realtime_event_source, t->next_elapse_realtime, t->accuracy_usec, timer_dispatch, t);
-
+                        r = sd_event_add_time(
+                                        UNIT(t)->manager->event,
+                                        &t->realtime_event_source,
+                                        t->wake_system ? CLOCK_REALTIME_ALARM : CLOCK_REALTIME,
+                                        t->next_elapse_realtime, t->accuracy_usec,
+                                        timer_dispatch, t);
                 if (r < 0)
                         goto fail;
 
         } else if (t->realtime_event_source) {
-                r = sd_event_source_set_enabled(t->realtime_event_source, SD_EVENT_OFF);
 
+                r = sd_event_source_set_enabled(t->realtime_event_source, SD_EVENT_OFF);
                 if (r < 0)
                         goto fail;
         }
@@ -392,9 +485,7 @@ static void timer_enter_waiting(Timer *t, bool initial) {
         return;
 
 fail:
-        log_warning_unit(UNIT(t)->id,
-                         "%s failed to enter waiting state: %s",
-                         UNIT(t)->id, strerror(-r));
+        log_warning_unit(UNIT(t)->id, "%s failed to enter waiting state: %s", UNIT(t)->id, strerror(-r));
         timer_enter_dead(t, TIMER_FAILURE_RESOURCES);
 }
 
@@ -413,7 +504,10 @@ static void timer_enter_running(Timer *t) {
         if (r < 0)
                 goto fail;
 
-        t->last_trigger_monotonic = now(CLOCK_MONOTONIC);
+        dual_timestamp_get(&t->last_trigger);
+
+        if (t->stamp_path)
+                touch_file(t->stamp_path, true, t->last_trigger.realtime, (uid_t) -1, (gid_t) -1, 0);
 
         timer_set_state(t, TIMER_RUNNING);
         return;
@@ -434,6 +528,20 @@ static int timer_start(Unit *u) {
         if (UNIT_TRIGGER(u)->load_state != UNIT_LOADED)
                 return -ENOENT;
 
+        t->last_trigger = DUAL_TIMESTAMP_NULL;
+
+        if (t->stamp_path) {
+                struct stat st;
+
+                if (stat(t->stamp_path, &st) >= 0)
+                        t->last_trigger.realtime = timespec_load(&st.st_atim);
+                else if (errno == ENOENT)
+                        /* The timer has never run before,
+                         * make sure a stamp file exists.
+                         */
+                        touch_file(t->stamp_path, true, (usec_t) -1, (uid_t) -1, (gid_t) -1, 0);
+        }
+
         t->result = TIMER_SUCCESS;
         timer_enter_waiting(t, true);
         return 0;
@@ -459,11 +567,18 @@ static int timer_serialize(Unit *u, FILE *f, FDSet *fds) {
         unit_serialize_item(u, f, "state", timer_state_to_string(t->state));
         unit_serialize_item(u, f, "result", timer_result_to_string(t->result));
 
+        if (t->last_trigger.realtime > 0)
+                unit_serialize_item_format(u, f, "last-trigger-realtime", "%" PRIu64, t->last_trigger.realtime);
+
+        if (t->last_trigger.monotonic > 0)
+                unit_serialize_item_format(u, f, "last-trigger-monotonic", "%" PRIu64, t->last_trigger.monotonic);
+
         return 0;
 }
 
 static int timer_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
         Timer *t = TIMER(u);
+        int r;
 
         assert(u);
         assert(key);
@@ -486,6 +601,17 @@ static int timer_deserialize_item(Unit *u, const char *key, const char *value, F
                         log_debug_unit(u->id, "Failed to parse result value %s", value);
                 else if (f != TIMER_SUCCESS)
                         t->result = f;
+        } else if (streq(key, "last-trigger-realtime")) {
+
+                r = safe_atou64(value, &t->last_trigger.realtime);
+                if (r < 0)
+                        log_debug_unit(u->id, "Failed to parse last-trigger-realtime value %s", value);
+
+        } else if (streq(key, "last-trigger-monotonic")) {
+
+                r = safe_atou64(value, &t->last_trigger.monotonic);
+                if (r < 0)
+                        log_debug_unit(u->id, "Failed to parse last-trigger-monotonic value %s", value);
 
         } else
                 log_debug_unit(u->id, "Unknown serialization key '%s'", key);
@@ -546,9 +672,7 @@ static void timer_trigger_notify(Unit *u, Unit *other) {
         case TIMER_RUNNING:
 
                 if (UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other))) {
-                        log_debug_unit(UNIT(t)->id,
-                                       "%s got notified about unit deactivation.",
-                                       UNIT(t)->id);
+                        log_debug_unit(UNIT(t)->id, "%s got notified about unit deactivation.", UNIT(t)->id);
                         timer_enter_waiting(t, false);
                 }
                 break;
@@ -581,8 +705,7 @@ static void timer_time_change(Unit *u) {
         if (t->state != TIMER_WAITING)
                 return;
 
-        log_debug_unit(u->id,
-                       "%s: time change, recalculating next elapse.", u->id);
+        log_debug_unit(u->id, "%s: time change, recalculating next elapse.", u->id);
         timer_enter_waiting(t, false);
 }
 
index 3e7efa4..de412a0 100644 (file)
@@ -50,7 +50,6 @@ typedef enum TimerBase {
 typedef struct TimerValue {
         TimerBase base;
         bool disabled;
-        clockid_t clock_id;
 
         usec_t value; /* only for monotonic events */
         CalendarSpec *calendar_spec; /* only for calendar events */
@@ -72,8 +71,9 @@ struct Timer {
         usec_t accuracy_usec;
 
         LIST_HEAD(TimerValue, values);
-        usec_t next_elapse_monotonic;
         usec_t next_elapse_realtime;
+        usec_t next_elapse_monotonic_or_boottime;
+        dual_timestamp last_trigger;
 
         TimerState state, deserialized_state;
 
@@ -82,7 +82,10 @@ struct Timer {
 
         TimerResult result;
 
-        usec_t last_trigger_monotonic;
+        bool persistent;
+        bool wake_system;
+
+        char *stamp_path;
 };
 
 void timer_free_values(Timer *t);
index d00f427..1f4c9ce 100644 (file)
@@ -264,9 +264,12 @@ static int transaction_merge_jobs(Transaction *tr, sd_bus_error *e) {
                                 return -EAGAIN;
 
                         /* We couldn't merge anything. Failure */
-                        sd_bus_error_setf(
-                                        e, BUS_ERROR_TRANSACTION_JOBS_CONFLICTING, "Transaction contains conflicting jobs '%s' and '%s' for %s. Probably contradicting requirement dependencies configured.",
-                                        job_type_to_string(t), job_type_to_string(k->type), k->unit->id);
+                        sd_bus_error_setf(e, BUS_ERROR_TRANSACTION_JOBS_CONFLICTING,
+                                          "Transaction contains conflicting jobs '%s' and '%s' for %s. "
+                                          "Probably contradicting requirement dependencies configured.",
+                                          job_type_to_string(t),
+                                          job_type_to_string(k->type),
+                                          k->unit->id);
                         return r;
                 }
         }
@@ -378,7 +381,7 @@ static int transaction_verify_order_one(Transaction *tr, Job *j, Job *from, unsi
                                       "Found dependency on %s/%s",
                                       k->unit->id, job_type_to_string(k->type));
 
-                        if (!delete &&
+                        if (!delete && hashmap_get(tr->jobs, k->unit) &&
                             !unit_matters_to_anchor(k->unit, k)) {
                                 /* Ok, we can drop this one, so let's
                                  * do so. */
@@ -512,7 +515,8 @@ static int transaction_is_destructive(Transaction *tr, JobMode mode, sd_bus_erro
                 if (j->unit->job && (mode == JOB_FAIL || j->unit->job->irreversible) &&
                     !job_type_is_superset(j->type, j->unit->job->type)) {
 
-                        sd_bus_error_setf(e, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE, "Transaction is destructive.");
+                        sd_bus_error_setf(e, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE,
+                                          "Transaction is destructive.");
                         return -EEXIST;
                 }
         }
@@ -860,35 +864,44 @@ int transaction_add_job_and_dependencies(
             unit->load_state != UNIT_ERROR &&
             unit->load_state != UNIT_NOT_FOUND &&
             unit->load_state != UNIT_MASKED) {
-                sd_bus_error_setf(e, BUS_ERROR_LOAD_FAILED, "Unit %s is not loaded properly.", unit->id);
+                sd_bus_error_setf(e, BUS_ERROR_LOAD_FAILED,
+                                  "Unit %s is not loaded properly.", unit->id);
                 return -EINVAL;
         }
 
         if (type != JOB_STOP && unit->load_state == UNIT_ERROR) {
-                sd_bus_error_setf(e, BUS_ERROR_LOAD_FAILED,
-                               "Unit %s failed to load: %s. "
-                               "See system logs and 'systemctl status %s' for details.",
-                               unit->id,
-                               strerror(-unit->load_error),
-                               unit->id);
+                if (unit->load_error == -ENOENT || unit->manager->test_run)
+                        sd_bus_error_setf(e, BUS_ERROR_LOAD_FAILED,
+                                          "Unit %s failed to load: %s.",
+                                          unit->id,
+                                          strerror(-unit->load_error));
+                else
+                        sd_bus_error_setf(e, BUS_ERROR_LOAD_FAILED,
+                                          "Unit %s failed to load: %s. "
+                                          "See system logs and 'systemctl status %s' for details.",
+                                          unit->id,
+                                          strerror(-unit->load_error),
+                                          unit->id);
                 return -EINVAL;
         }
 
         if (type != JOB_STOP && unit->load_state == UNIT_NOT_FOUND) {
                 sd_bus_error_setf(e, BUS_ERROR_LOAD_FAILED,
-                               "Unit %s failed to load: %s.",
-                               unit->id,
-                               strerror(-unit->load_error));
+                                  "Unit %s failed to load: %s.",
+                                  unit->id, strerror(-unit->load_error));
                 return -EINVAL;
         }
 
         if (type != JOB_STOP && unit->load_state == UNIT_MASKED) {
-                sd_bus_error_setf(e, BUS_ERROR_UNIT_MASKED, "Unit %s is masked.", unit->id);
+                sd_bus_error_setf(e, BUS_ERROR_UNIT_MASKED,
+                                  "Unit %s is masked.", unit->id);
                 return -EADDRNOTAVAIL;
         }
 
         if (!unit_job_is_applicable(unit, type)) {
-                sd_bus_error_setf(e, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE, "Job type %s is not applicable for unit %s.", job_type_to_string(type), unit->id);
+                sd_bus_error_setf(e, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE,
+                                  "Job type %s is not applicable for unit %s.",
+                                  job_type_to_string(type), unit->id);
                 return -EBADR;
         }
 
index 2d166c1..cffa453 100644 (file)
@@ -61,52 +61,46 @@ static void mount_points_list_free(MountPoint **head) {
 }
 
 static int mount_points_list_get(MountPoint **head) {
-        FILE *proc_self_mountinfo;
-        char *path, *p;
+        _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
         unsigned int i;
-        int r;
 
         assert(head);
 
-        if (!(proc_self_mountinfo = fopen("/proc/self/mountinfo", "re")))
+        proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
+        if (!proc_self_mountinfo)
                 return -errno;
 
         for (i = 1;; i++) {
-                int k;
+                _cleanup_free_ char *path = NULL;
+                char *p = NULL;
                 MountPoint *m;
+                int k;
 
-                path = p = NULL;
-
-                if ((k = fscanf(proc_self_mountinfo,
-                                "%*s "       /* (1) mount id */
-                                "%*s "       /* (2) parent id */
-                                "%*s "       /* (3) major:minor */
-                                "%*s "       /* (4) root */
-                                "%ms "       /* (5) mount point */
-                                "%*s"        /* (6) mount options */
-                                "%*[^-]"     /* (7) optional fields */
-                                "- "         /* (8) separator */
-                                "%*s "       /* (9) file system type */
-                                "%*s"        /* (10) mount source */
-                                "%*s"        /* (11) mount options 2 */
-                                "%*[^\n]",   /* some rubbish at the end */
-                                &path)) != 1) {
+                k = fscanf(proc_self_mountinfo,
+                           "%*s "       /* (1) mount id */
+                           "%*s "       /* (2) parent id */
+                           "%*s "       /* (3) major:minor */
+                           "%*s "       /* (4) root */
+                           "%ms "       /* (5) mount point */
+                           "%*s"        /* (6) mount options */
+                           "%*[^-]"     /* (7) optional fields */
+                           "- "         /* (8) separator */
+                           "%*s "       /* (9) file system type */
+                           "%*s"        /* (10) mount source */
+                           "%*s"        /* (11) mount options 2 */
+                           "%*[^\n]",   /* some rubbish at the end */
+                           &path);
+                if (k != 1) {
                         if (k == EOF)
                                 break;
 
                         log_warning("Failed to parse /proc/self/mountinfo:%u.", i);
-
-                        free(path);
                         continue;
                 }
 
                 p = cunescape(path);
-                free(path);
-
-                if (!p) {
-                        r = -ENOMEM;
-                        goto finish;
-                }
+                if (!p)
+                        return -ENOMEM;
 
                 /* Ignore mount points we can't unmount because they
                  * are API or because we are keeping them open (like
@@ -118,28 +112,22 @@ static int mount_points_list_get(MountPoint **head) {
                         continue;
                 }
 
-                if (!(m = new0(MountPoint, 1))) {
+                m = new0(MountPoint, 1);
+                if (!m) {
                         free(p);
-                        r = -ENOMEM;
-                        goto finish;
+                        return -ENOMEM;
                 }
 
                 m->path = p;
                 LIST_PREPEND(mount_point, *head, m);
         }
 
-        r = 0;
-
-finish:
-        fclose(proc_self_mountinfo);
-
-        return r;
+        return 0;
 }
 
 static int swap_list_get(MountPoint **head) {
-        FILE *proc_swaps;
+        _cleanup_fclose_ FILE *proc_swaps = NULL;
         unsigned int i;
-        int r;
 
         assert(head);
 
@@ -179,26 +167,19 @@ static int swap_list_get(MountPoint **head) {
                 free(dev);
 
                 if (!d) {
-                        r = -ENOMEM;
-                        goto finish;
+                        return -ENOMEM;
                 }
 
                 if (!(swap = new0(MountPoint, 1))) {
                         free(d);
-                        r = -ENOMEM;
-                        goto finish;
+                        return -ENOMEM;
                 }
 
                 swap->path = d;
                 LIST_PREPEND(mount_point, *head, swap);
         }
 
-        r = 0;
-
-finish:
-        fclose(proc_swaps);
-
-        return r;
+        return 0;
 }
 
 static int loopback_list_get(MountPoint **head) {
@@ -329,14 +310,14 @@ static int dm_list_get(MountPoint **head) {
 }
 
 static int delete_loopback(const char *device) {
-        int fd, r;
+        _cleanup_close_ int fd = -1;
+        int r;
 
-        if ((fd = open(device, O_RDONLY|O_CLOEXEC)) < 0)
+        fd = open(device, O_RDONLY|O_CLOEXEC);
+        if (fd < 0)
                 return errno == ENOENT ? 0 : -errno;
 
         r = ioctl(fd, LOOP_CLR_FD, 0);
-        close_nointr_nofail(fd);
-
         if (r >= 0)
                 return 1;
 
index 4e18afa..62599d0 100644 (file)
@@ -182,7 +182,7 @@ static int specifier_user_name(char specifier, void *data, void *userdata, char
         char *printed = NULL;
         Unit *u = userdata;
         ExecContext *c;
-        int r;
+        int r = 0;
 
         assert(u);
 
@@ -208,7 +208,7 @@ static int specifier_user_name(char specifier, void *data, void *userdata, char
                                 if (r < 0)
                                         return -ENODATA;
 
-                                asprintf(&printed, "%lu", (unsigned long) uid);
+                                r = asprintf(&printed, UID_FMT, uid);
                         }
                 }
 
@@ -231,10 +231,10 @@ static int specifier_user_name(char specifier, void *data, void *userdata, char
                 if (specifier == 'u')
                         printed = strdup(username);
                 else
-                        asprintf(&printed, "%lu", (unsigned long) uid);
+                        r = asprintf(&printed, UID_FMT, uid);
         }
 
-        if (!printed)
+        if (r < 0 || !printed)
                 return -ENOMEM;
 
         *ret = printed;
@@ -369,7 +369,7 @@ int unit_full_printf(Unit *u, const char *format, char **ret) {
         /* This is similar to unit_name_printf() but also supports
          * unescaping. Also, adds a couple of additional codes:
          *
-         * %f the the instance if set, otherwise the id
+         * %f the instance if set, otherwise the id
          * %c cgroup path of unit
          * %r where units in this slice are placed in the cgroup tree
          * %R the root of this systemd's instance tree
index 1bbcb39..08e74b4 100644 (file)
@@ -51,6 +51,7 @@
 #include "dbus.h"
 #include "execute.h"
 #include "virt.h"
+#include "dropin.h"
 
 const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX] = {
         [UNIT_SERVICE] = &service_vtable,
@@ -68,6 +69,8 @@ const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX] = {
         [UNIT_SCOPE] = &scope_vtable
 };
 
+static int maybe_warn_about_dependency(const char *id, const char *other, UnitDependency dependency);
+
 Unit *unit_new(Manager *m, size_t size) {
         Unit *u;
 
@@ -101,104 +104,122 @@ bool unit_has_name(Unit *u, const char *name) {
         return !!set_get(u->names, (char*) name);
 }
 
+static void unit_init(Unit *u) {
+        CGroupContext *cc;
+        ExecContext *ec;
+        KillContext *kc;
+
+        assert(u);
+        assert(u->manager);
+        assert(u->type >= 0);
+
+        cc = unit_get_cgroup_context(u);
+        if (cc) {
+                cgroup_context_init(cc);
+
+                /* Copy in the manager defaults into the cgroup
+                 * context, _before_ the rest of the settings have
+                 * been initialized */
+
+                cc->cpu_accounting = u->manager->default_cpu_accounting;
+                cc->blockio_accounting = u->manager->default_blockio_accounting;
+                cc->memory_accounting = u->manager->default_memory_accounting;
+        }
+
+        ec = unit_get_exec_context(u);
+        if (ec)
+                exec_context_init(ec);
+
+        kc = unit_get_kill_context(u);
+        if (kc)
+                kill_context_init(kc);
+
+        if (UNIT_VTABLE(u)->init)
+                UNIT_VTABLE(u)->init(u);
+}
+
 int unit_add_name(Unit *u, const char *text) {
+        _cleanup_free_ char *s = NULL, *i = NULL;
         UnitType t;
-        char *s, *i = NULL;
         int r;
 
         assert(u);
         assert(text);
 
         if (unit_name_is_template(text)) {
+
                 if (!u->instance)
                         return -EINVAL;
 
                 s = unit_name_replace_instance(text, u->instance);
         } else
                 s = strdup(text);
-
         if (!s)
                 return -ENOMEM;
 
-        if (!unit_name_is_valid(s, TEMPLATE_INVALID)) {
-                r = -EINVAL;
-                goto fail;
-        }
+        if (!unit_name_is_valid(s, TEMPLATE_INVALID))
+                return -EINVAL;
 
         assert_se((t = unit_name_to_type(s)) >= 0);
 
-        if (u->type != _UNIT_TYPE_INVALID && t != u->type) {
-                r = -EINVAL;
-                goto fail;
-        }
+        if (u->type != _UNIT_TYPE_INVALID && t != u->type)
+                return -EINVAL;
 
         r = unit_name_to_instance(s, &i);
         if (r < 0)
-                goto fail;
+                return r;
 
-        if (i && unit_vtable[t]->no_instances) {
-                r = -EINVAL;
-                goto fail;
-        }
+        if (i && unit_vtable[t]->no_instances)
+                return -EINVAL;
 
         /* Ensure that this unit is either instanced or not instanced,
          * but not both. */
-        if (u->type != _UNIT_TYPE_INVALID && !u->instance != !i) {
-                r = -EINVAL;
-                goto fail;
-        }
+        if (u->type != _UNIT_TYPE_INVALID && !u->instance != !i)
+                return -EINVAL;
 
         if (unit_vtable[t]->no_alias &&
             !set_isempty(u->names) &&
-            !set_get(u->names, s)) {
-                r = -EEXIST;
-                goto fail;
-        }
+            !set_get(u->names, s))
+                return -EEXIST;
 
-        if (hashmap_size(u->manager->units) >= MANAGER_MAX_NAMES) {
-                r = -E2BIG;
-                goto fail;
-        }
+        if (hashmap_size(u->manager->units) >= MANAGER_MAX_NAMES)
+                return -E2BIG;
 
         r = set_put(u->names, s);
         if (r < 0) {
                 if (r == -EEXIST)
-                        r = 0;
-                goto fail;
+                        return 0;
+
+                return r;
         }
 
         r = hashmap_put(u->manager->units, s, u);
         if (r < 0) {
                 set_remove(u->names, s);
-                goto fail;
+                return r;
         }
 
         if (u->type == _UNIT_TYPE_INVALID) {
-
                 u->type = t;
                 u->id = s;
                 u->instance = i;
 
                 LIST_PREPEND(units_by_type, u->manager->units_by_type[t], u);
 
-                if (UNIT_VTABLE(u)->init)
-                        UNIT_VTABLE(u)->init(u);
-        } else
-                free(i);
+                unit_init(u);
 
-        unit_add_to_dbus_queue(u);
-        return 0;
+                i = NULL;
+        }
 
-fail:
-        free(s);
-        free(i);
+        s = NULL;
 
-        return r;
+        unit_add_to_dbus_queue(u);
+        return 0;
 }
 
 int unit_choose_id(Unit *u, const char *name) {
-        char *s, *i;
         _cleanup_free_ char *t = NULL;
+        char *s, *i;
         int r;
 
         assert(u);
@@ -218,7 +239,6 @@ int unit_choose_id(Unit *u, const char *name) {
 
         /* Selects one of the names of this unit as the id */
         s = set_get(u->names, (char*) name);
-
         if (!s)
                 return -ENOENT;
 
@@ -328,7 +348,8 @@ void unit_add_to_dbus_queue(Unit *u) {
                 return;
 
         /* Shortcut things if nobody cares */
-        if (set_isempty(u->manager->subscribed)) {
+        if (sd_bus_track_count(u->manager->subscribed) <= 0 &&
+            set_isempty(u->manager->private_buses)) {
                 u->sent_dbus_new_signal = true;
                 return;
         }
@@ -409,6 +430,27 @@ static void unit_free_requires_mounts_for(Unit *u) {
         u->requires_mounts_for = NULL;
 }
 
+static void unit_done(Unit *u) {
+        ExecContext *ec;
+        CGroupContext *cc;
+
+        assert(u);
+
+        if (u->type < 0)
+                return;
+
+        if (UNIT_VTABLE(u)->done)
+                UNIT_VTABLE(u)->done(u);
+
+        ec = unit_get_exec_context(u);
+        if (ec)
+                exec_context_done(ec);
+
+        cc = unit_get_cgroup_context(u);
+        if (cc)
+                cgroup_context_done(cc);
+}
+
 void unit_free(Unit *u) {
         UnitDependency d;
         Iterator i;
@@ -421,9 +463,7 @@ void unit_free(Unit *u) {
 
         bus_unit_send_removed_signal(u);
 
-        if (u->load_state != UNIT_STUB)
-                if (UNIT_VTABLE(u)->done)
-                        UNIT_VTABLE(u)->done(u);
+        unit_done(u);
 
         unit_free_requires_mounts_for(u);
 
@@ -470,6 +510,9 @@ void unit_free(Unit *u) {
                 free(u->cgroup_path);
         }
 
+        set_remove(u->manager->failed_units, u);
+        set_remove(u->manager->startup_units, u);
+
         free(u->description);
         strv_free(u->documentation);
         free(u->fragment_path);
@@ -542,7 +585,7 @@ static void merge_names(Unit *u, Unit *other) {
                 assert_se(hashmap_replace(u->manager->units, t, u) == 0);
 }
 
-static void merge_dependencies(Unit *u, Unit *other, UnitDependency d) {
+static void merge_dependencies(Unit *u, Unit *other, const char *other_id, UnitDependency d) {
         Iterator i;
         Unit *back;
         int r;
@@ -556,14 +599,25 @@ static void merge_dependencies(Unit *u, Unit *other, UnitDependency d) {
                 UnitDependency k;
 
                 for (k = 0; k < _UNIT_DEPENDENCY_MAX; k++) {
-                        r = set_remove_and_put(back->dependencies[k], other, u);
-                        if (r == -EEXIST)
-                                set_remove(back->dependencies[k], other);
-                        else
-                                assert(r >= 0 || r == -ENOENT);
+                        /* Do not add dependencies between u and itself */
+                        if (back == u) {
+                                if (set_remove(back->dependencies[k], other))
+                                        maybe_warn_about_dependency(u->id, other_id, k);
+                        } else {
+                                r = set_remove_and_put(back->dependencies[k], other, u);
+                                if (r == -EEXIST)
+                                        set_remove(back->dependencies[k], other);
+                                else
+                                        assert(r >= 0 || r == -ENOENT);
+                        }
                 }
         }
 
+        /* Also do not move dependencies on u to itself */
+        back = set_remove(other->dependencies[d], u);
+        if (back)
+                maybe_warn_about_dependency(u->id, other_id, d);
+
         complete_move(&u->dependencies[d], &other->dependencies[d]);
 
         set_free(other->dependencies[d]);
@@ -572,6 +626,7 @@ static void merge_dependencies(Unit *u, Unit *other, UnitDependency d) {
 
 int unit_merge(Unit *u, Unit *other) {
         UnitDependency d;
+        const char *other_id = NULL;
 
         assert(u);
         assert(other);
@@ -602,6 +657,9 @@ int unit_merge(Unit *u, Unit *other) {
         if (!UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other)))
                 return -EEXIST;
 
+        if (other->id)
+                other_id = strdupa(other->id);
+
         /* Merge names */
         merge_names(u, other);
 
@@ -611,7 +669,7 @@ int unit_merge(Unit *u, Unit *other) {
 
         /* Merge dependencies */
         for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++)
-                merge_dependencies(u, other, d);
+                merge_dependencies(u, other, other_id, d);
 
         other->load_state = UNIT_MERGED;
         other->merged_into = u;
@@ -683,6 +741,19 @@ int unit_add_exec_dependencies(Unit *u, ExecContext *c) {
                         return r;
         }
 
+        if (u->manager->running_as != SYSTEMD_SYSTEM)
+                return 0;
+
+        if (c->private_tmp) {
+                r = unit_require_mounts_for(u, "/tmp");
+                if (r < 0)
+                        return r;
+
+                r = unit_require_mounts_for(u, "/var/tmp");
+                if (r < 0)
+                        return r;
+        }
+
         if (c->std_output != EXEC_OUTPUT_KMSG &&
             c->std_output != EXEC_OUTPUT_SYSLOG &&
             c->std_output != EXEC_OUTPUT_JOURNAL &&
@@ -700,11 +771,9 @@ int unit_add_exec_dependencies(Unit *u, ExecContext *c) {
         /* If syslog or kernel logging is requested, make sure our own
          * logging daemon is run first. */
 
-        if (u->manager->running_as == SYSTEMD_SYSTEM) {
-                r = unit_add_dependency_by_name(u, UNIT_AFTER, SPECIAL_JOURNALD_SOCKET, NULL, true);
-                if (r < 0)
-                        return r;
-        }
+        r = unit_add_dependency_by_name(u, UNIT_AFTER, SPECIAL_JOURNALD_SOCKET, NULL, true);
+        if (r < 0)
+                return r;
 
         return 0;
 }
@@ -979,6 +1048,9 @@ static int unit_add_slice_dependencies(Unit *u) {
         if (UNIT_ISSET(u->slice))
                 return unit_add_two_dependencies(u, UNIT_AFTER, UNIT_WANTS, UNIT_DEREF(u->slice), true);
 
+        if (streq(u->id, SPECIAL_ROOT_SLICE))
+                return 0;
+
         return unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_WANTS, SPECIAL_ROOT_SLICE, NULL, true);
 }
 
@@ -1020,6 +1092,25 @@ static int unit_add_mount_dependencies(Unit *u) {
         return 0;
 }
 
+static int unit_add_startup_units(Unit *u) {
+        CGroupContext *c;
+        int r = 0;
+
+        c = unit_get_cgroup_context(u);
+        if (!c)
+                return 0;
+
+        if (c->startup_cpu_shares == (unsigned long) -1 &&
+            c->startup_blockio_weight == (unsigned long) -1)
+                return 0;
+
+        r = set_put(u->manager->startup_units, u);
+        if (r == -EEXIST)
+                return 0;
+
+        return r;
+}
+
 int unit_load(Unit *u) {
         int r;
 
@@ -1061,6 +1152,10 @@ int unit_load(Unit *u) {
                 if (r < 0)
                         goto fail;
 
+                r = unit_add_startup_units(u);
+                if (r < 0)
+                        goto fail;
+
                 if (u->on_failure_job_mode == JOB_ISOLATE && set_size(u->dependencies[UNIT_ON_FAILURE]) > 1) {
                         log_error_unit(u->id, "More than one OnFailure= dependencies specified for %s but OnFailureJobMode=isolate set. Refusing.", u->id);
                         r = -EINVAL;
@@ -1376,12 +1471,44 @@ static void unit_check_unneeded(Unit *u) {
                 if (unit_active_or_pending(other))
                         return;
 
-        log_info_unit(u->id, "Service %s is not needed anymore. Stopping.", u->id);
+        log_info_unit(u->id, "Unit %s is not needed anymore. Stopping.", u->id);
 
         /* Ok, nobody needs us anymore. Sniff. Then let's commit suicide */
         manager_add_job(u->manager, JOB_STOP, u, JOB_FAIL, true, NULL, NULL);
 }
 
+static void unit_check_binds_to(Unit *u) {
+        bool stop = false;
+        Unit *other;
+        Iterator i;
+
+        assert(u);
+
+        if (u->job)
+                return;
+
+        if (unit_active_state(u) != UNIT_ACTIVE)
+                return;
+
+        SET_FOREACH(other, u->dependencies[UNIT_BINDS_TO], i) {
+                if (other->job)
+                        continue;
+
+                if (!UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other)))
+                        continue;
+
+                stop = true;
+        }
+
+        if (!stop)
+                return;
+
+        log_info_unit(u->id, "Unit %s is bound to inactive service. Stopping, too.", u->id);
+
+        /* A unit we need to run is gone. Sniff. Let's stop this. */
+        manager_add_job(u->manager, JOB_STOP, u, JOB_FAIL, true, NULL, NULL);
+}
+
 static void retroactively_start_dependencies(Unit *u) {
         Iterator i;
         Unit *other;
@@ -1500,12 +1627,13 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su
 
         /* Note that this is called for all low-level state changes,
          * even if they might map to the same high-level
-         * UnitActiveState! That means that ns == os is OK an expected
+         * UnitActiveState! That means that ns == os is an expected
          * behavior here. For example: if a mount point is remounted
          * this function will be called too! */
 
         m = u->manager;
 
+        /* Update timestamps for state changes */
         if (m->n_reloading <= 0) {
                 dual_timestamp ts;
 
@@ -1522,11 +1650,18 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su
                         u->active_exit_timestamp = ts;
         }
 
+        /* Keep track of failed units */
+        if (ns == UNIT_FAILED)
+                set_put(u->manager->failed_units, u);
+        else
+                set_remove(u->manager->failed_units, u);
+
+        /* Make sure the cgroup is always removed when we become inactive */
         if (UNIT_IS_INACTIVE_OR_FAILED(ns))
                 unit_destroy_cgroup(u);
 
         /* Note that this doesn't apply to RemainAfterExit services exiting
-         * sucessfully, since there's no change of state in that case. Which is
+         * successfully, since there's no change of state in that case. Which is
          * why it is handled in service_set_state() */
         if (UNIT_IS_INACTIVE_OR_FAILED(os) != UNIT_IS_INACTIVE_OR_FAILED(ns)) {
                 ExecContext *ec;
@@ -1640,7 +1775,7 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su
         if (UNIT_IS_ACTIVE_OR_RELOADING(ns)) {
 
                 if (unit_has_name(u, SPECIAL_DBUS_SERVICE))
-                        /* The bus just might have become available,
+                        /* The bus might have just become available,
                          * hence try to connect to it, if we aren't
                          * yet connected. */
                         bus_init(m, true);
@@ -1685,11 +1820,19 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su
         manager_recheck_journal(m);
         unit_trigger_notify(u);
 
-        /* Maybe we finished startup and are now ready for being
-         * stopped because unneeded? */
-        if (u->manager->n_reloading <= 0)
+        if (u->manager->n_reloading <= 0) {
+                /* Maybe we finished startup and are now ready for
+                 * being stopped because unneeded? */
                 unit_check_unneeded(u);
 
+                /* Maybe we finished startup, but something we needed
+                 * has vanished? Let's die then. (This happens when
+                 * something BindsTo= to a Type=oneshot unit, as these
+                 * units go directly from starting to inactive,
+                 * without ever entering started.) */
+                unit_check_binds_to(u);
+        }
+
         unit_add_to_dbus_queue(u);
         unit_add_to_gc_queue(u);
 }
@@ -1703,11 +1846,11 @@ int unit_watch_pid(Unit *u, pid_t pid) {
         /* Watch a specific PID. We only support one or two units
          * watching each PID for now, not more. */
 
-        r = hashmap_ensure_allocated(&u->manager->watch_pids1, trivial_hash_func, trivial_compare_func);
+        r = set_ensure_allocated(&u->pids, trivial_hash_func, trivial_compare_func);
         if (r < 0)
                 return r;
 
-        r = set_ensure_allocated(&u->pids, trivial_hash_func, trivial_compare_func);
+        r = hashmap_ensure_allocated(&u->manager->watch_pids1, trivial_hash_func, trivial_compare_func);
         if (r < 0)
                 return r;
 
@@ -1736,7 +1879,17 @@ void unit_unwatch_pid(Unit *u, pid_t pid) {
         set_remove(u->pids, LONG_TO_PTR(pid));
 }
 
-static int watch_pids_in_path(Unit *u, const char *path) {
+void unit_unwatch_all_pids(Unit *u) {
+        assert(u);
+
+        while (!set_isempty(u->pids))
+                unit_unwatch_pid(u, PTR_TO_LONG(set_first(u->pids)));
+
+        set_free(u->pids);
+        u->pids = NULL;
+}
+
+static int unit_watch_pids_in_path(Unit *u, const char *path) {
         _cleanup_closedir_ DIR *d = NULL;
         _cleanup_fclose_ FILE *f = NULL;
         int ret = 0, r;
@@ -1774,7 +1927,7 @@ static int watch_pids_in_path(Unit *u, const char *path) {
                         if (!p)
                                 return -ENOMEM;
 
-                        r = watch_pids_in_path(u, p);
+                        r = unit_watch_pids_in_path(u, p);
                         if (r < 0 && ret >= 0)
                                 ret = r;
                 }
@@ -1787,31 +1940,15 @@ static int watch_pids_in_path(Unit *u, const char *path) {
         return ret;
 }
 
-
 int unit_watch_all_pids(Unit *u) {
         assert(u);
 
-        if (!u->cgroup_path)
-                return -ENOENT;
-
         /* Adds all PIDs from our cgroup to the set of PIDs we watch */
 
-        return watch_pids_in_path(u, u->cgroup_path);
-}
-
-void unit_unwatch_all_pids(Unit *u) {
-        Iterator i;
-        void *e;
-
-        assert(u);
-
-        SET_FOREACH(e, u->pids, i) {
-                hashmap_remove_value(u->manager->watch_pids1, e, u);
-                hashmap_remove_value(u->manager->watch_pids2, e, u);
-        }
+        if (!u->cgroup_path)
+                return -ENOENT;
 
-        set_free(u->pids);
-        u->pids = NULL;
+        return unit_watch_pids_in_path(u, u->cgroup_path);
 }
 
 void unit_tidy_watch_pids(Unit *u, pid_t except1, pid_t except2) {
@@ -1829,7 +1966,7 @@ void unit_tidy_watch_pids(Unit *u, pid_t except1, pid_t except2) {
                         continue;
 
                 if (!pid_is_unwaited(pid))
-                        set_remove(u->pids, e);
+                        unit_unwatch_pid(u, pid);
         }
 }
 
@@ -1860,6 +1997,53 @@ bool unit_job_is_applicable(Unit *u, JobType j) {
         }
 }
 
+static int maybe_warn_about_dependency(const char *id, const char *other, UnitDependency dependency) {
+        assert(id);
+
+        switch (dependency) {
+        case UNIT_REQUIRES:
+        case UNIT_REQUIRES_OVERRIDABLE:
+        case UNIT_WANTS:
+        case UNIT_REQUISITE:
+        case UNIT_REQUISITE_OVERRIDABLE:
+        case UNIT_BINDS_TO:
+        case UNIT_PART_OF:
+        case UNIT_REQUIRED_BY:
+        case UNIT_REQUIRED_BY_OVERRIDABLE:
+        case UNIT_WANTED_BY:
+        case UNIT_BOUND_BY:
+        case UNIT_CONSISTS_OF:
+        case UNIT_REFERENCES:
+        case UNIT_REFERENCED_BY:
+        case UNIT_PROPAGATES_RELOAD_TO:
+        case UNIT_RELOAD_PROPAGATED_FROM:
+        case UNIT_JOINS_NAMESPACE_OF:
+                return 0;
+
+        case UNIT_CONFLICTS:
+        case UNIT_CONFLICTED_BY:
+        case UNIT_BEFORE:
+        case UNIT_AFTER:
+        case UNIT_ON_FAILURE:
+        case UNIT_TRIGGERS:
+        case UNIT_TRIGGERED_BY:
+                if (streq_ptr(id, other))
+                        log_warning_unit(id, "Dependency %s=%s dropped from unit %s",
+                                         unit_dependency_to_string(dependency), id, other);
+                else
+                        log_warning_unit(id, "Dependency %s=%s dropped from unit %s merged into %s",
+                                         unit_dependency_to_string(dependency), id,
+                                         strna(other), id);
+                return -EINVAL;
+
+        case _UNIT_DEPENDENCY_MAX:
+        case _UNIT_DEPENDENCY_INVALID:
+                break;
+        }
+
+        assert_not_reached("Invalid dependency type");
+}
+
 int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_reference) {
 
         static const UnitDependency inverse_table[_UNIT_DEPENDENCY_MAX] = {
@@ -1889,6 +2073,7 @@ int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_referen
                 [UNIT_JOINS_NAMESPACE_OF] = UNIT_JOINS_NAMESPACE_OF,
         };
         int r, q = 0, v = 0, w = 0;
+        Unit *orig_u = u, *orig_other = other;
 
         assert(u);
         assert(d >= 0 && d < _UNIT_DEPENDENCY_MAX);
@@ -1899,8 +2084,10 @@ int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_referen
 
         /* We won't allow dependencies on ourselves. We will not
          * consider them an error however. */
-        if (u == other)
+        if (u == other) {
+                maybe_warn_about_dependency(orig_u->id, orig_other->id, d);
                 return 0;
+        }
 
         r = set_ensure_allocated(&u->dependencies[d], trivial_hash_func, trivial_compare_func);
         if (r < 0)
@@ -1967,10 +2154,12 @@ int unit_add_two_dependencies(Unit *u, UnitDependency d, UnitDependency e, Unit
 
         assert(u);
 
-        if ((r = unit_add_dependency(u, d, other, add_reference)) < 0)
+        r = unit_add_dependency(u, d, other, add_reference);
+        if (r < 0)
                 return r;
 
-        if ((r = unit_add_dependency(u, e, other, add_reference)) < 0)
+        r = unit_add_dependency(u, e, other, add_reference);
+        if (r < 0)
                 return r;
 
         return 0;
@@ -2030,22 +2219,22 @@ int unit_add_dependency_by_name(Unit *u, UnitDependency d, const char *name, con
 }
 
 int unit_add_two_dependencies_by_name(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference) {
+        _cleanup_free_ char *s = NULL;
         Unit *other;
         int r;
-        _cleanup_free_ char *s = NULL;
 
         assert(u);
         assert(name || path);
 
-        if (!(name = resolve_template(u, name, path, &s)))
+        name = resolve_template(u, name, path, &s);
+        if (!name)
                 return -ENOMEM;
 
-        if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0)
+        r = manager_load_unit(u->manager, name, path, NULL, &other);
+        if (r < 0)
                 return r;
 
-        r = unit_add_two_dependencies(u, d, e, other, add_reference);
-
-        return r;
+        return unit_add_two_dependencies(u, d, e, other, add_reference);
 }
 
 int unit_add_dependency_by_name_inverse(Unit *u, UnitDependency d, const char *name, const char *path, bool add_reference) {
@@ -2056,15 +2245,15 @@ int unit_add_dependency_by_name_inverse(Unit *u, UnitDependency d, const char *n
         assert(u);
         assert(name || path);
 
-        if (!(name = resolve_template(u, name, path, &s)))
+        name = resolve_template(u, name, path, &s);
+        if (!name)
                 return -ENOMEM;
 
-        if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0)
+        r = manager_load_unit(u->manager, name, path, NULL, &other);
+        if (r < 0)
                 return r;
 
-        r = unit_add_dependency(other, d, u, add_reference);
-
-        return r;
+        return unit_add_dependency(other, d, u, add_reference);
 }
 
 int unit_add_two_dependencies_by_name_inverse(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference) {
@@ -2075,24 +2264,24 @@ int unit_add_two_dependencies_by_name_inverse(Unit *u, UnitDependency d, UnitDep
         assert(u);
         assert(name || path);
 
-        if (!(name = resolve_template(u, name, path, &s)))
+        name = resolve_template(u, name, path, &s);
+        if (!name)
                 return -ENOMEM;
 
-        if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0)
+        r = manager_load_unit(u->manager, name, path, NULL, &other);
+        if (r < 0)
                 return r;
 
-        if ((r = unit_add_two_dependencies(other, d, e, u, add_reference)) < 0)
+        r = unit_add_two_dependencies(other, d, e, u, add_reference);
+        if (r < 0)
                 return r;
 
         return r;
 }
 
 int set_unit_path(const char *p) {
-        _cleanup_free_ char *c = NULL;
-
         /* This is mostly for debug purposes */
-        c = path_make_absolute_cwd(p);
-        if (setenv("SYSTEMD_UNIT_PATH", c, 0) < 0)
+        if (setenv("SYSTEMD_UNIT_PATH", p, 0) < 0)
                 return -errno;
 
         return 0;
@@ -2132,20 +2321,18 @@ char *unit_default_cgroup_path(Unit *u) {
                 return strjoin(u->manager->cgroup_root, "/", escaped, NULL);
 }
 
-int unit_add_default_slice(Unit *u) {
+int unit_add_default_slice(Unit *u, CGroupContext *c) {
         _cleanup_free_ char *b = NULL;
         const char *slice_name;
         Unit *slice;
         int r;
 
         assert(u);
+        assert(c);
 
         if (UNIT_ISSET(u->slice))
                 return 0;
 
-        if (!unit_get_cgroup_context(u))
-                return 0;
-
         if (u->instance) {
                 _cleanup_free_ char *prefix = NULL, *escaped = NULL;
 
@@ -2237,25 +2424,25 @@ bool unit_can_serialize(Unit *u) {
 }
 
 int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) {
-        ExecRuntime *rt;
         int r;
 
         assert(u);
         assert(f);
         assert(fds);
 
-        if (!unit_can_serialize(u))
-                return 0;
+        if (unit_can_serialize(u)) {
+                ExecRuntime *rt;
 
-        r = UNIT_VTABLE(u)->serialize(u, f, fds);
-        if (r < 0)
-                return r;
-
-        rt = unit_get_exec_runtime(u);
-        if (rt) {
-                r = exec_runtime_serialize(rt, u, f, fds);
+                r = UNIT_VTABLE(u)->serialize(u, f, fds);
                 if (r < 0)
                         return r;
+
+                rt = unit_get_exec_runtime(u);
+                if (rt) {
+                        r = exec_runtime_serialize(rt, u, f, fds);
+                        if (r < 0)
+                                return r;
+                }
         }
 
         dual_timestamp_serialize(f, "inactive-exit-timestamp", &u->inactive_exit_timestamp);
@@ -2317,17 +2504,14 @@ void unit_serialize_item(Unit *u, FILE *f, const char *key, const char *value) {
 }
 
 int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
-        size_t offset;
         ExecRuntime **rt = NULL;
+        size_t offset;
         int r;
 
         assert(u);
         assert(f);
         assert(fds);
 
-        if (!unit_can_serialize(u))
-                return 0;
-
         offset = UNIT_VTABLE(u)->exec_runtime_offset;
         if (offset > 0)
                 rt = (ExecRuntime**) ((uint8_t*) u + offset);
@@ -2437,24 +2621,34 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
                         if (!s)
                                 return -ENOMEM;
 
-                        free(u->cgroup_path);
-                        u->cgroup_path = s;
+                        if (u->cgroup_path) {
+                                void *p;
+
+                                p = hashmap_remove(u->manager->cgroup_unit, u->cgroup_path);
+                                log_info("Removing cgroup_path %s from hashmap (%p)",
+                                         u->cgroup_path, p);
+                                free(u->cgroup_path);
+                        }
 
+                        u->cgroup_path = s;
                         assert(hashmap_put(u->manager->cgroup_unit, s, u) == 1);
+
                         continue;
                 }
 
-                if (rt) {
-                        r = exec_runtime_deserialize_item(rt, u, l, v, fds);
+                if (unit_can_serialize(u)) {
+                        if (rt) {
+                                r = exec_runtime_deserialize_item(rt, u, l, v, fds);
+                                if (r < 0)
+                                        return r;
+                                if (r > 0)
+                                        continue;
+                        }
+
+                        r = UNIT_VTABLE(u)->deserialize_item(u, l, v, fds);
                         if (r < 0)
                                 return r;
-                        if (r > 0)
-                                continue;
                 }
-
-                r = UNIT_VTABLE(u)->deserialize_item(u, l, v, fds);
-                if (r < 0)
-                        return r;
         }
 }
 
@@ -2777,27 +2971,55 @@ void unit_ref_unset(UnitRef *ref) {
         ref->unit = NULL;
 }
 
-int unit_exec_context_defaults(Unit *u, ExecContext *c) {
+int unit_patch_contexts(Unit *u) {
+        CGroupContext *cc;
+        ExecContext *ec;
         unsigned i;
         int r;
 
         assert(u);
-        assert(c);
 
-        /* This only copies in the ones that need memory */
-        for (i = 0; i < RLIMIT_NLIMITS; i++)
-                if (u->manager->rlimit[i] && !c->rlimit[i]) {
-                        c->rlimit[i] = newdup(struct rlimit, u->manager->rlimit[i], 1);
-                        if (!c->rlimit[i])
-                                return -ENOMEM;
+        /* Patch in the manager defaults into the exec and cgroup
+         * contexts, _after_ the rest of the settings have been
+         * initialized */
+
+        ec = unit_get_exec_context(u);
+        if (ec) {
+                /* This only copies in the ones that need memory */
+                for (i = 0; i < _RLIMIT_MAX; i++)
+                        if (u->manager->rlimit[i] && !ec->rlimit[i]) {
+                                ec->rlimit[i] = newdup(struct rlimit, u->manager->rlimit[i], 1);
+                                if (!ec->rlimit[i])
+                                        return -ENOMEM;
+                        }
+
+                if (u->manager->running_as == SYSTEMD_USER &&
+                    !ec->working_directory) {
+
+                        r = get_home_dir(&ec->working_directory);
+                        if (r < 0)
+                                return r;
                 }
 
-        if (u->manager->running_as == SYSTEMD_USER &&
-            !c->working_directory) {
+                if (u->manager->running_as == SYSTEMD_USER &&
+                    (ec->syscall_whitelist ||
+                     !set_isempty(ec->syscall_filter) ||
+                     !set_isempty(ec->syscall_archs) ||
+                     ec->address_families_whitelist ||
+                     !set_isempty(ec->address_families)))
+                        ec->no_new_privileges = true;
 
-                r = get_home_dir(&c->working_directory);
-                if (r < 0)
-                        return r;
+                if (ec->private_devices)
+                        ec->capability_bounding_set_drop |= (uint64_t) 1ULL << (uint64_t) CAP_MKNOD;
+        }
+
+        cc = unit_get_cgroup_context(u);
+        if (cc) {
+
+                if (ec &&
+                    ec->private_devices &&
+                    cc->device_policy == CGROUP_AUTO)
+                        cc->device_policy = CGROUP_CLOSED;
         }
 
         return 0;
@@ -2807,6 +3029,9 @@ ExecContext *unit_get_exec_context(Unit *u) {
         size_t offset;
         assert(u);
 
+        if (u->type < 0)
+                return NULL;
+
         offset = UNIT_VTABLE(u)->exec_context_offset;
         if (offset <= 0)
                 return NULL;
@@ -2818,6 +3043,9 @@ KillContext *unit_get_kill_context(Unit *u) {
         size_t offset;
         assert(u);
 
+        if (u->type < 0)
+                return NULL;
+
         offset = UNIT_VTABLE(u)->kill_context_offset;
         if (offset <= 0)
                 return NULL;
@@ -2828,6 +3056,9 @@ KillContext *unit_get_kill_context(Unit *u) {
 CGroupContext *unit_get_cgroup_context(Unit *u) {
         size_t offset;
 
+        if (u->type < 0)
+                return NULL;
+
         offset = UNIT_VTABLE(u)->cgroup_context_offset;
         if (offset <= 0)
                 return NULL;
@@ -2838,6 +3069,9 @@ CGroupContext *unit_get_cgroup_context(Unit *u) {
 ExecRuntime *unit_get_exec_runtime(Unit *u) {
         size_t offset;
 
+        if (u->type < 0)
+                return NULL;
+
         offset = UNIT_VTABLE(u)->exec_runtime_offset;
         if (offset <= 0)
                 return NULL;
@@ -2845,68 +3079,55 @@ ExecRuntime *unit_get_exec_runtime(Unit *u) {
         return *(ExecRuntime**) ((uint8_t*) u + offset);
 }
 
-static int drop_in_file(Unit *u, UnitSetPropertiesMode mode, const char *name, char **_p, char **_q) {
-        _cleanup_free_ char *b = NULL;
-        char *p, *q;
-        int r;
-
-        assert(u);
-        assert(name);
-        assert(_p);
-        assert(_q);
-
-        b = xescape(name, "/.");
-        if (!b)
-                return -ENOMEM;
-
-        if (!filename_is_safe(b))
-                return -EINVAL;
-
+static int unit_drop_in_dir(Unit *u, UnitSetPropertiesMode mode, bool transient, char **dir) {
         if (u->manager->running_as == SYSTEMD_USER) {
-                _cleanup_free_ char *c = NULL;
+                int r;
 
-                r = user_config_home(&c);
-                if (r < 0)
-                        return r;
+                r = user_config_home(dir);
                 if (r == 0)
                         return -ENOENT;
+                return r;
+        }
 
-                p = strjoin(c, "/", u->id, ".d", NULL);
-        } else if (mode == UNIT_PERSISTENT && !u->transient)
-                p = strjoin("/etc/systemd/system/", u->id, ".d", NULL);
+        if (mode == UNIT_PERSISTENT && !transient)
+                *dir = strdup("/etc/systemd/system");
         else
-                p = strjoin("/run/systemd/system/", u->id, ".d", NULL);
-        if (!p)
+                *dir = strdup("/run/systemd/system");
+        if (!*dir)
                 return -ENOMEM;
 
-        q = strjoin(p, "/90-", b, ".conf", NULL);
-        if (!q) {
-                free(p);
-                return -ENOMEM;
-        }
-
-        *_p = p;
-        *_q = q;
         return 0;
 }
 
+static int unit_drop_in_file(Unit *u,
+                             UnitSetPropertiesMode mode, const char *name, char **p, char **q) {
+        _cleanup_free_ char *dir = NULL;
+        int r;
+
+        assert(u);
+
+        r = unit_drop_in_dir(u, mode, u->transient, &dir);
+        if (r < 0)
+                return r;
+
+        return drop_in_file(dir, u->id, 50, name, p, q);
+}
+
 int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data) {
-        _cleanup_free_ char *p = NULL, *q = NULL;
+
+        _cleanup_free_ char *dir = NULL;
         int r;
 
         assert(u);
-        assert(name);
-        assert(data);
 
         if (!IN_SET(mode, UNIT_PERSISTENT, UNIT_RUNTIME))
                 return 0;
 
-        r = drop_in_file(u, mode, name, &p, &q);
+        r = unit_drop_in_dir(u, mode, u->transient, &dir);
         if (r < 0)
                 return r;
 
-        mkdir_p(p, 0755);
-        return write_string_file_atomic_label(q, data);
+        return write_drop_in(dir, u->id, 50, name, data);
 }
 
 int unit_write_drop_in_format(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *format, ...) {
@@ -2982,7 +3203,7 @@ int unit_remove_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name) {
         if (!IN_SET(mode, UNIT_PERSISTENT, UNIT_RUNTIME))
                 return 0;
 
-        r = drop_in_file(u, mode, name, &p, &q);
+        r = unit_drop_in_file(u, mode, name, &p, &q);
         if (r < 0)
                 return r;
 
@@ -3155,11 +3376,9 @@ int unit_require_mounts_for(Unit *u, const char *path) {
                 return 0;
         }
 
-        r = strv_push(&u->requires_mounts_for, p);
-        if (r < 0) {
-                free(p);
+        r = strv_consume(&u->requires_mounts_for, p);
+        if (r < 0)
                 return r;
-        }
 
         PATH_FOREACH_PREFIX_MORE(prefix, p) {
                 Set *x;
@@ -3260,9 +3479,9 @@ static const char* const unit_dependency_table[_UNIT_DEPENDENCY_MAX] = {
         [UNIT_TRIGGERED_BY] = "TriggeredBy",
         [UNIT_PROPAGATES_RELOAD_TO] = "PropagatesReloadTo",
         [UNIT_RELOAD_PROPAGATED_FROM] = "ReloadPropagatedFrom",
+        [UNIT_JOINS_NAMESPACE_OF] = "JoinsNamespaceOf",
         [UNIT_REFERENCES] = "References",
         [UNIT_REFERENCED_BY] = "ReferencedBy",
-        [UNIT_JOINS_NAMESPACE_OF] = "JoinsNamespaceOf",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(unit_dependency, UnitDependency);
index 808929e..3e61067 100644 (file)
@@ -519,7 +519,7 @@ int unit_load_fragment_and_dropin(Unit *u);
 int unit_load_fragment_and_dropin_optional(Unit *u);
 int unit_load(Unit *unit);
 
-int unit_add_default_slice(Unit *u);
+int unit_add_default_slice(Unit *u, CGroupContext *c);
 
 const char *unit_description(Unit *u) _pure_;
 
@@ -602,11 +602,12 @@ void unit_ref_unset(UnitRef *ref);
 #define UNIT_DEREF(ref) ((ref).unit)
 #define UNIT_ISSET(ref) (!!(ref).unit)
 
-int unit_exec_context_defaults(Unit *u, ExecContext *c);
+int unit_patch_contexts(Unit *u);
 
 ExecContext *unit_get_exec_context(Unit *u) _pure_;
 KillContext *unit_get_kill_context(Unit *u) _pure_;
 CGroupContext *unit_get_cgroup_context(Unit *u) _pure_;
+
 ExecRuntime *unit_get_exec_runtime(Unit *u) _pure_;
 
 int unit_setup_exec_runtime(Unit *u);
index f19ac75..8c7ecde 100644 (file)
@@ -14,6 +14,7 @@
 #LogLocation=no
 #SystemCallArchitectures=
 #TimerSlackNSec=
+#DefaultTimerAccuracySec=1min
 #DefaultStandardOutput=inherit
 #DefaultStandardError=inherit
 #DefaultTimeoutStartSec=90s
index 38c746b..3233e15 100644 (file)
 #include "mkdir.h"
 #include "strv.h"
 #include "fileio.h"
+#include "path-util.h"
+#include "dropin.h"
+#include "generator.h"
 
 static const char *arg_dest = "/tmp";
 static bool arg_enabled = true;
 static bool arg_read_crypttab = true;
-
-static char **arg_disks;
-static char **arg_options;
-static char *arg_keyfile;
-
+static char **arg_disks = NULL;
+static char **arg_options = NULL;
+static char *arg_keyfile = NULL;
 
 static bool has_option(const char *haystack, const char *needle) {
         const char *f = haystack;
@@ -74,9 +75,12 @@ static int create_disk(
                 const char *password,
                 const char *options) {
 
-        _cleanup_free_ char *p = NULL, *n = NULL, *d = NULL, *u = NULL, *from = NULL, *to = NULL, *e = NULL;
+        _cleanup_free_ char *p = NULL, *n = NULL, *d = NULL, *u = NULL, *to = NULL, *e = NULL,
+                *filtered = NULL;
         _cleanup_fclose_ FILE *f = NULL;
         bool noauto, nofail, tmp, swap;
+        char *from;
+        int r;
 
         assert(name);
         assert(device);
@@ -91,7 +95,11 @@ static int create_disk(
                 return -EINVAL;
         }
 
-        n = unit_name_from_path_instance("systemd-cryptsetup", name, ".service");
+        e = unit_name_escape(name);
+        if (!e)
+                return log_oom();
+
+        n = unit_name_build("systemd-cryptsetup", e, ".service");
         if (!n)
                 return log_oom();
 
@@ -117,13 +125,13 @@ static int create_disk(
                 "# Automatically generated by systemd-cryptsetup-generator\n\n"
                 "[Unit]\n"
                 "Description=Cryptography Setup for %I\n"
-                "Documentation=man:systemd-cryptsetup@.service(8) man:crypttab(5)\n"
+                "Documentation=man:crypttab(5) man:systemd-cryptsetup-generator(8) man:systemd-cryptsetup@.service(8)\n"
                 "SourcePath=/etc/crypttab\n"
-                "Conflicts=umount.target\n"
                 "DefaultDependencies=no\n"
+                "Conflicts=umount.target\n"
                 "BindsTo=dev-mapper-%i.device\n"
                 "IgnoreOnIsolate=true\n"
-                "After=systemd-readahead-collect.service systemd-readahead-replay.service\n",
+                "After=systemd-readahead-collect.service systemd-readahead-replay.service cryptsetup-pre.target\n",
                 f);
 
         if (!nofail)
@@ -131,24 +139,28 @@ static int create_disk(
                         "Before=cryptsetup.target\n");
 
         if (password) {
-                if (streq(password, "/dev/urandom") ||
-                    streq(password, "/dev/random") ||
-                    streq(password, "/dev/hw_random"))
+                if (STR_IN_SET(password, "/dev/urandom", "/dev/random", "/dev/hw_random"))
                         fputs("After=systemd-random-seed.service\n", f);
-
                 else if (!streq(password, "-") && !streq(password, "none")) {
-                        _cleanup_free_ char *uu = fstab_node_to_udev_node(password);
-                        if (uu == NULL)
+                        _cleanup_free_ char *uu;
+
+                        uu = fstab_node_to_udev_node(password);
+                        if (!uu)
                                 return log_oom();
 
-                        if (is_device_path(uu)) {
-                                _cleanup_free_ char *dd = unit_name_from_path(uu, ".device");
-                                if (dd == NULL)
-                                        return log_oom();
+                        if (!path_equal(uu, "/dev/null")) {
+
+                                if (is_device_path(uu)) {
+                                        _cleanup_free_ char *dd;
 
-                                fprintf(f, "After=%1$s\nRequires=%1$s\n", dd);
-                        } else
-                                fprintf(f, "RequiresMountsFor=%s\n", password);
+                                        dd = unit_name_from_path(uu, ".device");
+                                        if (!dd)
+                                                return log_oom();
+
+                                        fprintf(f, "After=%1$s\nRequires=%1$s\n", dd);
+                                } else
+                                        fprintf(f, "RequiresMountsFor=%s\n", password);
+                        }
                 }
         }
 
@@ -163,6 +175,10 @@ static int create_disk(
                         "RequiresMountsFor=%s\n",
                         u);
 
+        r = generator_write_timeouts(arg_dest, device, name, options, &filtered);
+        if (r < 0)
+                return r;
+
         fprintf(f,
                 "\n[Service]\n"
                 "Type=oneshot\n"
@@ -170,7 +186,7 @@ static int create_disk(
                 "TimeoutSec=0\n" /* the binary handles timeouts anyway */
                 "ExecStart=" SYSTEMD_CRYPTSETUP_PATH " attach '%s' '%s' '%s' '%s'\n"
                 "ExecStop=" SYSTEMD_CRYPTSETUP_PATH " detach '%s'\n",
-                name, u, strempty(password), strempty(options),
+                name, u, strempty(password), strempty(filtered),
                 name);
 
         if (tmp)
@@ -184,14 +200,12 @@ static int create_disk(
                         name);
 
         fflush(f);
-
         if (ferror(f)) {
                 log_error("Failed to write file %s: %m", p);
                 return -errno;
         }
 
-        if (asprintf(&from, "../%s", n) < 0)
-                return log_oom();
+        from = strappenda("../", n);
 
         if (!noauto) {
 
@@ -220,10 +234,6 @@ static int create_disk(
                 }
         }
 
-        e = unit_name_escape(name);
-        if (!e)
-                return log_oom();
-
         free(to);
         to = strjoin(arg_dest, "/dev-mapper-", e, ".device.requires/", n, NULL);
         if (!to)
@@ -236,103 +246,54 @@ static int create_disk(
         }
 
         if (!noauto && !nofail) {
-                int r;
-                free(p);
-                p = strjoin(arg_dest, "/dev-mapper-", e, ".device.d/50-job-timeout-sec-0.conf", NULL);
-                if (!p)
-                        return log_oom();
-
-                mkdir_parents_label(p, 0755);
-
-                r = write_string_file(p,
-                                "# Automatically generated by systemd-cryptsetup-generator\n\n"
-                                "[Unit]\n"
-                                "JobTimeoutSec=0\n"); /* the binary handles timeouts anyway */
-                if (r)
+                r = write_drop_in(arg_dest, name, 90, "device-timeout",
+                                  "# Automatically generated by systemd-cryptsetup-generator \n\n"
+                                  "[Unit]\nJobTimeoutSec=0");
+                if (r < 0) {
+                        log_error("Failed to write device drop-in: %s", strerror(-r));
                         return r;
+                }
         }
 
         return 0;
 }
 
-static int parse_proc_cmdline_word(const char *word) {
+static int parse_proc_cmdline_item(const char *key, const char *value) {
         int r;
 
-        if (startswith(word, "luks=")) {
-                r = parse_boolean(word + 5);
+        if (STR_IN_SET(key, "luks", "rd.luks") && value) {
+
+                r = parse_boolean(value);
                 if (r < 0)
-                        log_warning("Failed to parse luks switch %s. Ignoring.", word + 5);
+                        log_warning("Failed to parse luks switch %s. Ignoring.", value);
                 else
                         arg_enabled = r;
 
-        } else if (startswith(word, "rd.luks=")) {
-
-                if (in_initrd()) {
-                        r = parse_boolean(word + 8);
-                        if (r < 0)
-                                log_warning("Failed to parse luks switch %s. Ignoring.", word + 8);
-                        else
-                                arg_enabled = r;
-                }
+        } else if (STR_IN_SET(key, "luks.crypttab", "rd.luks.crypttab") && value) {
 
-        } else if (startswith(word, "luks.crypttab=")) {
-                r = parse_boolean(word + 14);
+                r = parse_boolean(value);
                 if (r < 0)
-                        log_warning("Failed to parse luks crypttab switch %s. Ignoring.", word + 14);
+                        log_warning("Failed to parse luks crypttab switch %s. Ignoring.", value);
                 else
                         arg_read_crypttab = r;
 
-        } else if (startswith(word, "rd.luks.crypttab=")) {
+        } else if (STR_IN_SET(key, "luks.uuid", "rd.luks.uuid") && value) {
 
-                if (in_initrd()) {
-                        r = parse_boolean(word + 17);
-                        if (r < 0)
-                                log_warning("Failed to parse luks crypttab switch %s. Ignoring.", word + 17);
-                        else
-                                arg_read_crypttab = r;
-                }
-
-        } else if (startswith(word, "luks.uuid=")) {
-                if (strv_extend(&arg_disks, word + 10) < 0)
+                if (strv_extend(&arg_disks, value) < 0)
                         return log_oom();
 
-        } else if (startswith(word, "rd.luks.uuid=")) {
-
-                if (in_initrd()) {
-                        if (strv_extend(&arg_disks, word + 13) < 0)
-                                return log_oom();
-                }
+        } else if (STR_IN_SET(key, "luks.options", "rd.luks.options") && value) {
 
-        } else if (startswith(word, "luks.options=")) {
-                if (strv_extend(&arg_options, word + 13) < 0)
+                if (strv_extend(&arg_options, value) < 0)
                         return log_oom();
 
-        } else if (startswith(word, "rd.luks.options=")) {
+        } else if (STR_IN_SET(key, "luks.key", "rd.luks.key") && value) {
 
-                if (in_initrd()) {
-                        if (strv_extend(&arg_options, word + 16) < 0)
-                                return log_oom();
-                }
-
-        } else if (startswith(word, "luks.key=")) {
                 free(arg_keyfile);
-                arg_keyfile = strdup(word + 9);
+                arg_keyfile = strdup(value);
                 if (!arg_keyfile)
                         return log_oom();
 
-        } else if (startswith(word, "rd.luks.key=")) {
-
-                if (in_initrd()) {
-                        free(arg_keyfile);
-                        arg_keyfile = strdup(word + 12);
-                        if (!arg_keyfile)
-                                return log_oom();
-                }
-
-        } else if (startswith(word, "luks.") ||
-                   (in_initrd() && startswith(word, "rd.luks."))) {
-
-                log_warning("Unknown kernel switch %s. Ignoring.", word);
         }
 
         return 0;
@@ -359,7 +320,7 @@ int main(int argc, char *argv[]) {
 
         umask(0022);
 
-        if (parse_proc_cmdline(parse_proc_cmdline_word) < 0)
+        if (parse_proc_cmdline(parse_proc_cmdline_item) < 0)
                 goto cleanup;
 
         if (!arg_enabled) {
@@ -509,13 +470,9 @@ next:
                                 k = sscanf(s, "%m[0-9a-fA-F-]=%ms", &proc_uuid, &proc_options);
                                 if (k == 2) {
                                         if (streq(proc_uuid, device + 5)) {
-                                                if (options)
-                                                        free(options);
-                                                options = strdup(proc_options);
-                                                if (!options) {
-                                                        log_oom();
-                                                        goto cleanup;
-                                                }
+                                                free(options);
+                                                options = proc_options;
+                                                proc_options = NULL;
                                         }
                                 } else if (!options) {
                                         /*
index 033c0cd..94570eb 100644 (file)
 #include "libudev.h"
 #include "udev-util.h"
 
-static const char *opt_type = NULL; /* CRYPT_LUKS1, CRYPT_TCRYPT or CRYPT_PLAIN */
-static char *opt_cipher = NULL;
-static unsigned opt_key_size = 0;
-static int opt_key_slot = CRYPT_ANY_SLOT;
-static unsigned opt_keyfile_size = 0;
-static unsigned opt_keyfile_offset = 0;
-static char *opt_hash = NULL;
-static unsigned opt_tries = 3;
-static bool opt_readonly = false;
-static bool opt_verify = false;
-static bool opt_discards = false;
-static bool opt_tcrypt_hidden = false;
-static bool opt_tcrypt_system = false;
-static char **opt_tcrypt_keyfiles = NULL;
-static usec_t opt_timeout = 0;
+static const char *arg_type = NULL; /* CRYPT_LUKS1, CRYPT_TCRYPT or CRYPT_PLAIN */
+static char *arg_cipher = NULL;
+static unsigned arg_key_size = 0;
+static int arg_key_slot = CRYPT_ANY_SLOT;
+static unsigned arg_keyfile_size = 0;
+static unsigned arg_keyfile_offset = 0;
+static char *arg_hash = NULL;
+static unsigned arg_tries = 3;
+static bool arg_readonly = false;
+static bool arg_verify = false;
+static bool arg_discards = false;
+static bool arg_tcrypt_hidden = false;
+static bool arg_tcrypt_system = false;
+static char **arg_tcrypt_keyfiles = NULL;
+static usec_t arg_timeout = 0;
 
 /* Options Debian's crypttab knows we don't:
 
@@ -78,43 +78,50 @@ static int parse_one_option(const char *option) {
                 if (!t)
                         return log_oom();
 
-                free(opt_cipher);
-                opt_cipher = t;
+                free(arg_cipher);
+                arg_cipher = t;
 
         } else if (startswith(option, "size=")) {
 
-                if (safe_atou(option+5, &opt_key_size) < 0) {
+                if (safe_atou(option+5, &arg_key_size) < 0) {
                         log_error("size= parse failure, ignoring.");
                         return 0;
                 }
 
+                if (arg_key_size % 8) {
+                        log_error("size= not a multiple of 8, ignoring.");
+                        return 0;
+                }
+
+                arg_key_size /= 8;
+
         } else if (startswith(option, "key-slot=")) {
 
-                opt_type = CRYPT_LUKS1;
-                if (safe_atoi(option+9, &opt_key_slot) < 0) {
+                arg_type = CRYPT_LUKS1;
+                if (safe_atoi(option+9, &arg_key_slot) < 0) {
                         log_error("key-slot= parse failure, ignoring.");
                         return 0;
                 }
 
         } else if (startswith(option, "tcrypt-keyfile=")) {
 
-                opt_type = CRYPT_TCRYPT;
+                arg_type = CRYPT_TCRYPT;
                 if (path_is_absolute(option+15)) {
-                        if (strv_extend(&opt_tcrypt_keyfiles, option + 15) < 0)
+                        if (strv_extend(&arg_tcrypt_keyfiles, option + 15) < 0)
                                 return log_oom();
                 } else
                         log_error("Key file path '%s' is not absolute. Ignoring.", option+15);
 
         } else if (startswith(option, "keyfile-size=")) {
 
-                if (safe_atou(option+13, &opt_keyfile_size) < 0) {
+                if (safe_atou(option+13, &arg_keyfile_size) < 0) {
                         log_error("keyfile-size= parse failure, ignoring.");
                         return 0;
                 }
 
         } else if (startswith(option, "keyfile-offset=")) {
 
-                if (safe_atou(option+15, &opt_keyfile_offset) < 0) {
+                if (safe_atou(option+15, &arg_keyfile_offset) < 0) {
                         log_error("keyfile-offset= parse failure, ignoring.");
                         return 0;
                 }
@@ -126,39 +133,37 @@ static int parse_one_option(const char *option) {
                 if (!t)
                         return log_oom();
 
-                free(opt_hash);
-                opt_hash = t;
+                free(arg_hash);
+                arg_hash = t;
 
         } else if (startswith(option, "tries=")) {
 
-                if (safe_atou(option+6, &opt_tries) < 0) {
+                if (safe_atou(option+6, &arg_tries) < 0) {
                         log_error("tries= parse failure, ignoring.");
                         return 0;
                 }
 
-        } else if (streq(option, "readonly") || streq(option, "read-only"))
-                opt_readonly = true;
+        } else if (STR_IN_SET(option, "readonly", "read-only"))
+                arg_readonly = true;
         else if (streq(option, "verify"))
-                opt_verify = true;
-        else if (streq(option, "allow-discards") || streq(option, "discard"))
-                opt_discards = true;
+                arg_verify = true;
+        else if (STR_IN_SET(option, "allow-discards", "discard"))
+                arg_discards = true;
         else if (streq(option, "luks"))
-                opt_type = CRYPT_LUKS1;
+                arg_type = CRYPT_LUKS1;
         else if (streq(option, "tcrypt"))
-                opt_type = CRYPT_TCRYPT;
+                arg_type = CRYPT_TCRYPT;
         else if (streq(option, "tcrypt-hidden")) {
-                opt_type = CRYPT_TCRYPT;
-                opt_tcrypt_hidden = true;
+                arg_type = CRYPT_TCRYPT;
+                arg_tcrypt_hidden = true;
         } else if (streq(option, "tcrypt-system")) {
-                opt_type = CRYPT_TCRYPT;
-                opt_tcrypt_system = true;
-        } else if (streq(option, "plain") ||
-                 streq(option, "swap") ||
-                 streq(option, "tmp"))
-                opt_type = CRYPT_PLAIN;
+                arg_type = CRYPT_TCRYPT;
+                arg_tcrypt_system = true;
+        } else if (STR_IN_SET(option, "plain", "swap", "tmp"))
+                arg_type = CRYPT_PLAIN;
         else if (startswith(option, "timeout=")) {
 
-                if (parse_sec(option+8, &opt_timeout) < 0) {
+                if (parse_sec(option+8, &arg_timeout) < 0) {
                         log_error("timeout= parse failure, ignoring.");
                         return 0;
                 }
@@ -170,16 +175,16 @@ static int parse_one_option(const char *option) {
 }
 
 static int parse_options(const char *options) {
-        char *state, *w;
+        const char *word, *state;
         size_t l;
         int r;
 
         assert(options);
 
-        FOREACH_WORD_SEPARATOR(w, l, options, ",", state) {
+        FOREACH_WORD_SEPARATOR(word, l, options, ",", state) {
                 _cleanup_free_ char *o;
 
-                o = strndup(w, l);
+                o = strndup(word, l);
                 if (!o)
                         return -ENOMEM;
                 r = parse_one_option(o);
@@ -196,12 +201,11 @@ static void log_glue(int level, const char *msg, void *usrptr) {
 
 static char* disk_description(const char *path) {
 
-        static const char name_fields[] = {
+        static const char name_fields[] =
                 "ID_PART_ENTRY_NAME\0"
                 "DM_NAME\0"
                 "ID_MODEL_FROM_DATABASE\0"
-                "ID_MODEL\0"
-        };
+                "ID_MODEL\0";
 
         _cleanup_udev_unref_ struct udev *udev = NULL;
         _cleanup_udev_device_unref_ struct udev_device *device = NULL;
@@ -260,6 +264,8 @@ static int get_password(const char *name, usec_t until, bool accept_cached, char
         int r;
         char **p;
         _cleanup_free_ char *text = NULL;
+        _cleanup_free_ char *escaped_name = NULL;
+        char *id;
 
         assert(name);
         assert(passwords);
@@ -267,13 +273,19 @@ static int get_password(const char *name, usec_t until, bool accept_cached, char
         if (asprintf(&text, "Please enter passphrase for disk %s!", name) < 0)
                 return log_oom();
 
-        r = ask_password_auto(text, "drive-harddisk", until, accept_cached, passwords);
+        escaped_name = cescape(name);
+        if (!escaped_name)
+                return log_oom();
+
+        id = strappenda("cryptsetup:", escaped_name);
+
+        r = ask_password_auto(text, "drive-harddisk", id, until, accept_cached, passwords);
         if (r < 0) {
                 log_error("Failed to query password: %s", strerror(-r));
                 return r;
         }
 
-        if (opt_verify) {
+        if (arg_verify) {
                 _cleanup_strv_free_ char **passwords2 = NULL;
 
                 assert(strv_length(*passwords) == 1);
@@ -281,7 +293,9 @@ static int get_password(const char *name, usec_t until, bool accept_cached, char
                 if (asprintf(&text, "Please enter passphrase for disk %s! (verification)", name) < 0)
                         return log_oom();
 
-                r = ask_password_auto(text, "drive-harddisk", until, false, &passwords2);
+                id = strappenda("cryptsetup-verification:", escaped_name);
+
+                r = ask_password_auto(text, "drive-harddisk", id, until, false, &passwords2);
                 if (r < 0) {
                         log_error("Failed to query verification password: %s", strerror(-r));
                         return r;
@@ -300,14 +314,14 @@ static int get_password(const char *name, usec_t until, bool accept_cached, char
         STRV_FOREACH(p, *passwords) {
                 char *c;
 
-                if (strlen(*p)+1 >= opt_key_size)
+                if (strlen(*p)+1 >= arg_key_size)
                         continue;
 
                 /* Pad password if necessary */
-                if (!(c = new(char, opt_key_size)))
+                if (!(c = new(char, arg_key_size)))
                         return log_oom();
 
-                strncpy(c, *p, opt_key_size);
+                strncpy(c, *p, arg_key_size);
                 free(*p);
                 *p = c;
         }
@@ -324,18 +338,18 @@ static int attach_tcrypt(struct crypt_device *cd,
         _cleanup_free_ char *passphrase = NULL;
         struct crypt_params_tcrypt params = {
                 .flags = CRYPT_TCRYPT_LEGACY_MODES,
-                .keyfiles = (const char **)opt_tcrypt_keyfiles,
-                .keyfiles_count = strv_length(opt_tcrypt_keyfiles)
+                .keyfiles = (const char **)arg_tcrypt_keyfiles,
+                .keyfiles_count = strv_length(arg_tcrypt_keyfiles)
         };
 
         assert(cd);
         assert(name);
-        assert(key_file || passwords);
+        assert(key_file || (passwords && passwords[0]));
 
-        if (opt_tcrypt_hidden)
+        if (arg_tcrypt_hidden)
                 params.flags |= CRYPT_TCRYPT_HIDDEN_HEADER;
 
-        if (opt_tcrypt_system)
+        if (arg_tcrypt_system)
                 params.flags |= CRYPT_TCRYPT_SYSTEM_HEADER;
 
         if (key_file) {
@@ -359,7 +373,7 @@ static int attach_tcrypt(struct crypt_device *cd,
                 return r;
         }
 
-        return crypt_activate_by_volume_key(cd, name, NULL, 0, flags);;
+        return crypt_activate_by_volume_key(cd, name, NULL, 0, flags);
 }
 
 static int attach_luks_or_plain(struct crypt_device *cd,
@@ -374,31 +388,31 @@ static int attach_luks_or_plain(struct crypt_device *cd,
         assert(name);
         assert(key_file || passwords);
 
-        if (!opt_type || streq(opt_type, CRYPT_LUKS1))
+        if (!arg_type || streq(arg_type, CRYPT_LUKS1))
                 r = crypt_load(cd, CRYPT_LUKS1, NULL);
 
-        if ((!opt_type && r < 0) || streq_ptr(opt_type, CRYPT_PLAIN)) {
+        if ((!arg_type && r < 0) || streq_ptr(arg_type, CRYPT_PLAIN)) {
                 struct crypt_params_plain params = {};
                 const char *cipher, *cipher_mode;
                 _cleanup_free_ char *truncated_cipher = NULL;
 
-                if (opt_hash) {
+                if (arg_hash) {
                         /* plain isn't a real hash type. it just means "use no hash" */
-                        if (!streq(opt_hash, "plain"))
-                                params.hash = opt_hash;
+                        if (!streq(arg_hash, "plain"))
+                                params.hash = arg_hash;
                 } else
                         params.hash = "ripemd160";
 
-                if (opt_cipher) {
+                if (arg_cipher) {
                         size_t l;
 
-                        l = strcspn(opt_cipher, "-");
-                        truncated_cipher = strndup(opt_cipher, l);
+                        l = strcspn(arg_cipher, "-");
+                        truncated_cipher = strndup(arg_cipher, l);
                         if (!truncated_cipher)
                                 return log_oom();
 
                         cipher = truncated_cipher;
-                        cipher_mode = opt_cipher[l] ? opt_cipher+l+1 : "plain";
+                        cipher_mode = arg_cipher[l] ? arg_cipher+l+1 : "plain";
                 } else {
                         cipher = "aes";
                         cipher_mode = "cbc-essiv:sha256";
@@ -407,7 +421,7 @@ static int attach_luks_or_plain(struct crypt_device *cd,
                 /* for CRYPT_PLAIN limit reads
                  * from keyfile to key length, and
                  * ignore keyfile-size */
-                opt_keyfile_size = opt_key_size / 8;
+                arg_keyfile_size = arg_key_size;
 
                 /* In contrast to what the name
                  * crypt_setup() might suggest this
@@ -416,7 +430,7 @@ static int attach_luks_or_plain(struct crypt_device *cd,
                  * parameters when used for plain
                  * mode. */
                 r = crypt_format(cd, CRYPT_PLAIN, cipher, cipher_mode,
-                                 NULL, NULL, opt_keyfile_size, &params);
+                                 NULL, NULL, arg_keyfile_size, &params);
 
                 /* hash == NULL implies the user passed "plain" */
                 pass_volume_key = (params.hash == NULL);
@@ -434,9 +448,9 @@ static int attach_luks_or_plain(struct crypt_device *cd,
                  crypt_get_device_name(cd));
 
         if (key_file) {
-                r = crypt_activate_by_keyfile_offset(cd, name, opt_key_slot,
-                                                     key_file, opt_keyfile_size,
-                                                     opt_keyfile_offset, flags);
+                r = crypt_activate_by_keyfile_offset(cd, name, arg_key_slot,
+                                                     key_file, arg_keyfile_size,
+                                                     arg_keyfile_offset, flags);
                 if (r < 0) {
                         log_error("Failed to activate with key file '%s': %s", key_file, strerror(-r));
                         return -EAGAIN;
@@ -446,9 +460,9 @@ static int attach_luks_or_plain(struct crypt_device *cd,
 
                 STRV_FOREACH(p, passwords) {
                         if (pass_volume_key)
-                                r = crypt_activate_by_volume_key(cd, name, *p, opt_key_size, flags);
+                                r = crypt_activate_by_volume_key(cd, name, *p, arg_key_size, flags);
                         else
-                                r = crypt_activate_by_passphrase(cd, name, opt_key_slot, *p, strlen(*p), flags);
+                                r = crypt_activate_by_passphrase(cd, name, arg_key_slot, *p, strlen(*p), flags);
 
                         if (r >= 0)
                                 break;
@@ -535,13 +549,18 @@ int main(int argc, char *argv[]) {
                         description = NULL;
                 }
 
+                k = 0;
                 if (mount_point && description)
-                        asprintf(&name_buffer, "%s (%s) on %s", description, argv[2], mount_point);
+                        k = asprintf(&name_buffer, "%s (%s) on %s", description, argv[2], mount_point);
                 else if (mount_point)
-                        asprintf(&name_buffer, "%s on %s", argv[2], mount_point);
+                        k = asprintf(&name_buffer, "%s on %s", argv[2], mount_point);
                 else if (description)
-                        asprintf(&name_buffer, "%s (%s)", description, argv[2]);
+                        k = asprintf(&name_buffer, "%s (%s)", description, argv[2]);
 
+                if (k < 0) {
+                        log_oom();
+                        goto finish;
+                }
                 name = name_buffer ? name_buffer : argv[2];
 
                 k = crypt_init(&cd, argv[3]);
@@ -559,18 +578,18 @@ int main(int argc, char *argv[]) {
                         goto finish;
                 }
 
-                if (opt_readonly)
+                if (arg_readonly)
                         flags |= CRYPT_ACTIVATE_READONLY;
 
-                if (opt_discards)
+                if (arg_discards)
                         flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
 
-                if (opt_timeout > 0)
-                        until = now(CLOCK_MONOTONIC) + opt_timeout;
+                if (arg_timeout > 0)
+                        until = now(CLOCK_MONOTONIC) + arg_timeout;
                 else
                         until = 0;
 
-                opt_key_size = (opt_key_size > 0 ? opt_key_size : 256);
+                arg_key_size = (arg_key_size > 0 ? arg_key_size : (256 / 8));
 
                 if (key_file) {
                         struct stat st;
@@ -581,18 +600,18 @@ int main(int argc, char *argv[]) {
                                 log_warning("Key file %s is world-readable. This is not a good idea!", key_file);
                 }
 
-                for (tries = 0; opt_tries == 0 || tries < opt_tries; tries++) {
+                for (tries = 0; arg_tries == 0 || tries < arg_tries; tries++) {
                         _cleanup_strv_free_ char **passwords = NULL;
 
                         if (!key_file) {
-                                k = get_password(name, until, tries == 0 && !opt_verify, &passwords);
+                                k = get_password(name, until, tries == 0 && !arg_verify, &passwords);
                                 if (k == -EAGAIN)
                                         continue;
                                 else if (k < 0)
                                         goto finish;
                         }
 
-                        if (streq_ptr(opt_type, CRYPT_TCRYPT))
+                        if (streq_ptr(arg_type, CRYPT_TCRYPT))
                                 k = attach_tcrypt(cd, argv[2], key_file, passwords, flags);
                         else
                                 k = attach_luks_or_plain(cd, argv[2], key_file, passwords, flags);
@@ -609,7 +628,7 @@ int main(int argc, char *argv[]) {
                         log_warning("Invalid passphrase.");
                 }
 
-                if (opt_tries != 0 && tries >= opt_tries) {
+                if (arg_tries != 0 && tries >= arg_tries) {
                         log_error("Too many attempts; giving up.");
                         r = EXIT_FAILURE;
                         goto finish;
@@ -644,9 +663,9 @@ finish:
         if (cd)
                 crypt_free(cd);
 
-        free(opt_cipher);
-        free(opt_hash);
-        strv_free(opt_tcrypt_keyfiles);
+        free(arg_cipher);
+        free(arg_hash);
+        strv_free(arg_tcrypt_keyfiles);
 
         return r;
 }
index b1c94c2..e1ffc55 100644 (file)
@@ -66,7 +66,8 @@ static int create_dbus_files(
                         "# Automatically generated by systemd-dbus1-generator\n\n"
                         "[Unit]\n"
                         "SourcePath=%s\n"
-                        "Description=DBUS1: %s\n\n"
+                        "Description=DBUS1: %s\n"
+                        "Documentation=man:systemd-dbus1-generator(8)\n\n"
                         "[Service]\n"
                         "ExecStart=%s\n"
                         "Type=dbus\n"
@@ -95,7 +96,7 @@ static int create_dbus_files(
                                 }
 
                                 fprintf(f, "Environment=DBUS_STARTER_ADDRESS="KERNEL_USER_BUS_FMT ";" UNIX_USER_BUS_FMT "\n",
-                                        (unsigned long) getuid(), run);
+                                        getuid(), run);
                         }
                 }
 
@@ -122,10 +123,12 @@ static int create_dbus_files(
                 "# Automatically generated by systemd-dbus1-generator\n\n"
                 "[Unit]\n"
                 "SourcePath=%s\n"
-                "Description=DBUS1: %s\n\n"
+                "Description=DBUS1: %s\n"
+                "Documentation=man:systemd-dbus1-generator(8)\n\n"
                 "[BusName]\n"
                 "Name=%s\n"
-                "Service=%s\n",
+                "Service=%s\n"
+                "AllowWorld=talk\n",
                 path,
                 name,
                 name,
@@ -153,34 +156,24 @@ static int create_dbus_files(
 static int add_dbus(const char *path, const char *fname, const char *type) {
         _cleanup_free_ char *name = NULL, *exec = NULL, *user = NULL, *service = NULL;
 
-        ConfigTableItem table[] = {
+        const ConfigTableItem table[] = {
                 { "D-BUS Service", "Name", config_parse_string, 0, &name },
                 { "D-BUS Service", "Exec", config_parse_string, 0, &exec },
                 { "D-BUS Service", "User", config_parse_string, 0, &user },
                 { "D-BUS Service", "SystemdService", config_parse_string, 0, &service },
         };
 
-        _cleanup_fclose_ FILE *f = NULL;
-        _cleanup_free_ char *p = NULL;
+        char *p;
         int r;
 
         assert(path);
         assert(fname);
 
-        p = strjoin(path, "/", fname, NULL);
-        if (!p)
-                return log_oom();
-
-        f = fopen(p, "re");
-        if (!f) {
-                if (errno == -ENOENT)
-                        return 0;
-
-                log_error("Failed to read %s: %m", p);
-                return -errno;
-        }
-
-        r = config_parse(NULL, p, f, "D-BUS Service\0", config_item_table_lookup, table, true, false, NULL);
+        p = strappenda(path, "/", fname);
+        r = config_parse(NULL, p, NULL,
+                         "D-BUS Service\0",
+                         config_item_table_lookup, table,
+                         true, false, true, NULL);
         if (r < 0)
                 return r;
 
diff --git a/src/debug-generator/Makefile b/src/debug-generator/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/debug-generator/debug-generator.c b/src/debug-generator/debug-generator.c
new file mode 100644 (file)
index 0000000..fd7c29d
--- /dev/null
@@ -0,0 +1,173 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "util.h"
+#include "strv.h"
+#include "unit-name.h"
+#include "mkdir.h"
+
+static const char *arg_dest = "/tmp";
+static char **arg_mask = NULL;
+static char **arg_wants = NULL;
+static bool arg_debug_shell = false;
+
+static int parse_proc_cmdline_item(const char *key, const char *value) {
+        int r;
+
+        assert(key);
+
+        if (streq(key, "systemd.mask")) {
+
+                if (!value)
+                        log_error("Missing argument for systemd.mask= kernel command line parameter.");
+                else {
+                        char *n;
+
+                        n = unit_name_mangle(value, MANGLE_NOGLOB);
+                        if (!n)
+                                return log_oom();
+
+                        r = strv_consume(&arg_mask, n);
+                        if (r < 0)
+                                return log_oom();
+                }
+
+        } else if (streq(key, "systemd.wants")) {
+
+                if (!value)
+                        log_error("Missing argument for systemd.want= kernel command line parameter.");
+                else {
+                        char *n;
+
+                        n = unit_name_mangle(value, MANGLE_NOGLOB);
+                        if (!n)
+                                return log_oom();
+
+                        r = strv_consume(&arg_wants, n);
+                        if (r < 0)
+                                return log_oom();
+                }
+
+        } else if (streq(key, "systemd.debug-shell")) {
+
+                if (value) {
+                        r = parse_boolean(value);
+                        if (r < 0)
+                                log_error("Failed to parse systemd.debug-shell= argument '%s', ignoring.", value);
+                        else
+                                arg_debug_shell = r;
+                } else
+                        arg_debug_shell = true;
+        }
+
+        return 0;
+}
+
+static int generate_mask_symlinks(void) {
+        char **u;
+        int r = 0;
+
+        if (strv_isempty(arg_mask))
+                return 0;
+
+        STRV_FOREACH(u, arg_mask) {
+                _cleanup_free_ char *p = NULL;
+
+                p = strjoin(arg_dest, "/", *u, NULL);
+                if (!p)
+                        return log_oom();
+
+                if (symlink("/dev/null", p) < 0) {
+                        log_error("Failed to create mask symlink %s: %m", p);
+                        r = -errno;
+                }
+        }
+
+        return r;
+}
+
+static int generate_wants_symlinks(void) {
+        char **u;
+        int r = 0;
+
+        if (strv_isempty(arg_wants))
+                return 0;
+
+        STRV_FOREACH(u, arg_wants) {
+                _cleanup_free_ char *p = NULL, *f = NULL;
+
+                p = strjoin(arg_dest, "/default.target.wants/", *u, NULL);
+                if (!p)
+                        return log_oom();
+
+                f = strappend(SYSTEM_DATA_UNIT_PATH "/", *u);
+                if (!f)
+                        return log_oom();
+
+                mkdir_parents_label(p, 0755);
+
+                if (symlink(f, p) < 0) {
+                        log_error("Failed to create wants symlink %s: %m", p);
+                        r = -errno;
+                }
+        }
+
+        return r;
+}
+
+int main(int argc, char *argv[]) {
+        int r, q;
+
+        if (argc > 1 && argc != 4) {
+                log_error("This program takes three or no arguments.");
+                return EXIT_FAILURE;
+        }
+
+        if (argc > 1)
+                arg_dest = argv[2];
+
+        log_set_target(LOG_TARGET_SAFE);
+        log_parse_environment();
+        log_open();
+
+        umask(0022);
+
+        if (parse_proc_cmdline(parse_proc_cmdline_item) < 0)
+                return EXIT_FAILURE;
+
+        if (arg_debug_shell) {
+                r = strv_extend(&arg_wants, "debug-shell.service");
+                if (r < 0) {
+                        r = log_oom();
+                        goto finish;
+                }
+        }
+
+        r = generate_mask_symlinks();
+
+        q = generate_wants_symlinks();
+        if (q < 0)
+                r = q;
+
+finish:
+        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+
+}
index 369f8f8..cd8bd35 100644 (file)
@@ -103,8 +103,9 @@ static int notify_override_masked(const char *top, const char *bottom) {
         if (!(arg_flags & SHOW_MASKED))
                 return 0;
 
-        printf("%s%s%s     %s → %s\n",
-               ansi_highlight_red(), "[MASKED]", ansi_highlight_off(), top, bottom);
+        printf("%s%s%s     %s %s %s\n",
+               ansi_highlight_red(), "[MASKED]", ansi_highlight_off(),
+               top, draw_special_char(DRAW_ARROW), bottom);
         return 1;
 }
 
@@ -112,8 +113,9 @@ static int notify_override_equivalent(const char *top, const char *bottom) {
         if (!(arg_flags & SHOW_EQUIVALENT))
                 return 0;
 
-        printf("%s%s%s %s → %s\n",
-               ansi_highlight_green(), "[EQUIVALENT]", ansi_highlight_off(), top, bottom);
+        printf("%s%s%s %s %s %s\n",
+               ansi_highlight_green(), "[EQUIVALENT]", ansi_highlight_off(),
+               top, draw_special_char(DRAW_ARROW), bottom);
         return 1;
 }
 
@@ -121,8 +123,9 @@ static int notify_override_redirected(const char *top, const char *bottom) {
         if (!(arg_flags & SHOW_REDIRECTED))
                 return 0;
 
-        printf("%s%s%s   %s → %s\n",
-               ansi_highlight(), "[REDIRECTED]", ansi_highlight_off(), top, bottom);
+        printf("%s%s%s   %s %s %s\n",
+               ansi_highlight(), "[REDIRECTED]", ansi_highlight_off(),
+               top, draw_special_char(DRAW_ARROW), bottom);
         return 1;
 }
 
@@ -130,8 +133,9 @@ static int notify_override_overridden(const char *top, const char *bottom) {
         if (!(arg_flags & SHOW_OVERRIDDEN))
                 return 0;
 
-        printf("%s%s%s %s → %s\n",
-               ansi_highlight(), "[OVERRIDDEN]", ansi_highlight_off(), top, bottom);
+        printf("%s%s%s %s %s %s\n",
+               ansi_highlight(), "[OVERRIDDEN]", ansi_highlight_off(),
+               top, draw_special_char(DRAW_ARROW), bottom);
         return 1;
 }
 
@@ -139,8 +143,9 @@ static int notify_override_extended(const char *top, const char *bottom) {
         if (!(arg_flags & SHOW_EXTENDED))
                return 0;
 
-        printf("%s%s%s   %s → %s\n",
-               ansi_highlight(), "[EXTENDED]", ansi_highlight_off(), top, bottom);
+        printf("%s%s%s   %s %s %s\n",
+               ansi_highlight(), "[EXTENDED]", ansi_highlight_off(),
+               top, draw_special_char(DRAW_ARROW), bottom);
         return 1;
 }
 
@@ -241,7 +246,7 @@ static int enumerate_dir_d(Hashmap *top, Hashmap *bottom, Hashmap *drops, const
                         return -ENOMEM;
                 d = p + strlen(toppath) + 1;
 
-                log_debug("Adding at top: %s → %s", d, p);
+                log_debug("Adding at top: %s %s %s", d, draw_special_char(DRAW_ARROW), p);
                 k = hashmap_put(top, d, p);
                 if (k >= 0) {
                         p = strdup(p);
@@ -253,7 +258,7 @@ static int enumerate_dir_d(Hashmap *top, Hashmap *bottom, Hashmap *drops, const
                         return k;
                 }
 
-                log_debug("Adding at bottom: %s → %s", d, p);
+                log_debug("Adding at bottom: %s %s %s", d, draw_special_char(DRAW_ARROW), p);
                 free(hashmap_remove(bottom, d));
                 k = hashmap_put(bottom, d, p);
                 if (k < 0) {
@@ -276,7 +281,8 @@ static int enumerate_dir_d(Hashmap *top, Hashmap *bottom, Hashmap *drops, const
                 if (!p)
                         return -ENOMEM;
 
-                log_debug("Adding to drops: %s → %s → %s", unit, basename(p), p);
+                log_debug("Adding to drops: %s %s %s %s %s",
+                          unit, draw_special_char(DRAW_ARROW), basename(p), draw_special_char(DRAW_ARROW), p);
                 k = hashmap_put(h, basename(p), p);
                 if (k < 0) {
                         free(p);
@@ -328,7 +334,7 @@ static int enumerate_dir(Hashmap *top, Hashmap *bottom, Hashmap *drops, const ch
                 if (!p)
                         return -ENOMEM;
 
-                log_debug("Adding at top: %s → %s", basename(p), p);
+                log_debug("Adding at top: %s %s %s", basename(p), draw_special_char(DRAW_ARROW), p);
                 k = hashmap_put(top, basename(p), p);
                 if (k >= 0) {
                         p = strdup(p);
@@ -339,7 +345,7 @@ static int enumerate_dir(Hashmap *top, Hashmap *bottom, Hashmap *drops, const ch
                         return k;
                 }
 
-                log_debug("Adding at bottom: %s → %s", basename(p), p);
+                log_debug("Adding at bottom: %s %s %s", basename(p), draw_special_char(DRAW_ARROW), p);
                 free(hashmap_remove(bottom, basename(p)));
                 k = hashmap_put(bottom, basename(p), p);
                 if (k < 0) {
@@ -467,38 +473,35 @@ static int process_suffix_chop(const char *arg) {
         return -EINVAL;
 }
 
-static int help(void) {
-
+static void help(void) {
         printf("%s [OPTIONS...] [SUFFIX...]\n\n"
                "Find overridden configuration files.\n\n"
                "  -h --help           Show this help\n"
                "     --version        Show package version\n"
                "     --no-pager       Do not pipe output into a pager\n"
                "     --diff[=1|0]     Show a diff when overridden files differ\n"
-               "  -t --type=LIST...   Only display a selected set of override types\n",
-               program_invocation_short_name);
-
-        return 0;
+               "  -t --type=LIST...   Only display a selected set of override types\n"
+               , program_invocation_short_name);
 }
 
 static int parse_flags(const char *flag_str, int flags) {
-        char *w, *state;
+        const char *word, *state;
         size_t l;
 
-        FOREACH_WORD(w, l, flag_str, state) {
-                if (strneq("masked", w, l))
+        FOREACH_WORD(word, l, flag_str, state) {
+                if (strneq("masked", word, l))
                         flags |= SHOW_MASKED;
-                else if (strneq ("equivalent", w, l))
+                else if (strneq ("equivalent", word, l))
                         flags |= SHOW_EQUIVALENT;
-                else if (strneq("redirected", w, l))
+                else if (strneq("redirected", word, l))
                         flags |= SHOW_REDIRECTED;
-                else if (strneq("overridden", w, l))
+                else if (strneq("overridden", word, l))
                         flags |= SHOW_OVERRIDDEN;
-                else if (strneq("unchanged", w, l))
+                else if (strneq("unchanged", word, l))
                         flags |= SHOW_UNCHANGED;
-                else if (strneq("extended", w, l))
+                else if (strneq("extended", word, l))
                         flags |= SHOW_EXTENDED;
-                else if (strneq("default", w, l))
+                else if (strneq("default", word, l))
                         flags |= SHOW_DEFAULTS;
                 else
                         return -EINVAL;
@@ -528,7 +531,7 @@ static int parse_argv(int argc, char *argv[]) {
         assert(argc >= 1);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "ht:", options, NULL)) >= 0) {
+        while ((c = getopt_long(argc, argv, "ht:", options, NULL)) >= 0)
 
                 switch (c) {
 
@@ -579,7 +582,6 @@ static int parse_argv(int argc, char *argv[]) {
                 default:
                         assert_not_reached("Unhandled option");
                 }
-        }
 
         return 1;
 }
index 8cf8dcf..ff5bee5 100644 (file)
@@ -36,18 +36,15 @@ static enum {
         ONLY_CONTAINER
 } arg_mode = ANY_VIRTUALIZATION;
 
-static int help(void) {
-
+static void help(void) {
         printf("%s [OPTIONS...]\n\n"
                "Detect execution in a virtualized environment.\n\n"
                "  -h --help             Show this help\n"
                "     --version          Show package version\n"
                "  -c --container        Only detect whether we are run in a container\n"
                "  -v --vm               Only detect whether we are run in a VM\n"
-               "  -q --quiet            Don't output anything, just set return value\n",
-               program_invocation_short_name);
-
-        return 0;
+               "  -q --quiet            Don't output anything, just set return value\n"
+               , program_invocation_short_name);
 }
 
 static int parse_argv(int argc, char *argv[]) {
@@ -70,12 +67,13 @@ static int parse_argv(int argc, char *argv[]) {
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "hqcv", options, NULL)) >= 0) {
+        while ((c = getopt_long(argc, argv, "hqcv", options, NULL)) >= 0)
 
                 switch (c) {
 
                 case 'h':
-                        return help();
+                        help();
+                        return 0;
 
                 case ARG_VERSION:
                         puts(PACKAGE_STRING);
@@ -100,10 +98,10 @@ static int parse_argv(int argc, char *argv[]) {
                 default:
                         assert_not_reached("Unhandled option");
                 }
-        }
 
         if (optind < argc) {
-                help();
+                log_error("%s takes no arguments.",
+                          program_invocation_short_name);
                 return -EINVAL;
         }
 
index 606d35b..d4d7780 100644 (file)
 #include "util.h"
 #include "mkdir.h"
 #include "unit-name.h"
+#include "virt.h"
+#include "generator.h"
+#include "special.h"
 
 static const char *arg_dest = "/tmp";
 
 int main(int argc, char *argv[]) {
+        _cleanup_free_ char *what = NULL;
+        _cleanup_fclose_ FILE *f = NULL;
         int r = EXIT_SUCCESS;
         sd_id128_t id;
-        _cleanup_free_ char *what = NULL, *fsck = NULL;
         char *name;
-        _cleanup_fclose_ FILE *f = NULL, *f2 = NULL;
 
         if (argc > 1 && argc != 4) {
                 log_error("This program takes three or no arguments.");
@@ -51,16 +54,32 @@ int main(int argc, char *argv[]) {
 
         umask(0022);
 
-        if (!is_efi_boot())
+        if (in_initrd()) {
+                log_debug("In initrd, exiting.");
                 return EXIT_SUCCESS;
+        }
+
+        if (detect_container(NULL) > 0) {
+                log_debug("In a container, exiting.");
+                return EXIT_SUCCESS;
+        }
+
+        if (!is_efi_boot()) {
+                log_debug("Not an EFI boot, exiting.");
+                return EXIT_SUCCESS;
+        }
 
-        if (dir_is_empty("/boot") <= 0)
+        if (path_is_mount_point("/boot", true) <= 0 &&
+            dir_is_empty("/boot") <= 0) {
+                log_debug("/boot already populated, exiting.");
                 return EXIT_SUCCESS;
+        }
 
         r = efi_loader_get_device_part_uuid(&id);
-        if (r == -ENOENT)
+        if (r == -ENOENT) {
+                log_debug("EFI loader partition unknown, exiting.");
                 return EXIT_SUCCESS;
-        if (r < 0) {
+        } else if (r < 0) {
                 log_error("Failed to read ESP partition UUID: %s", strerror(-r));
                 return EXIT_FAILURE;
         }
@@ -80,28 +99,35 @@ int main(int argc, char *argv[]) {
                 return EXIT_FAILURE;
         }
 
-        fsck = unit_name_from_path_instance("systemd-fsck", what, ".service");
-        if (!fsck) {
-                log_oom();
-                return EXIT_FAILURE;
-        }
-
         fprintf(f,
                 "# Automatially generated by systemd-efi-boot-generator\n\n"
                 "[Unit]\n"
                 "Description=EFI System Partition\n"
-                "Requires=%s\n"
-                "After=%s\n"
+                "Documentation=man:systemd-efi-boot-generator(8)\n");
+
+        r = generator_write_fsck_deps(f, arg_dest, what, "/boot", "vfat");
+        if (r < 0)
+                return EXIT_FAILURE;
+
+        fprintf(f,
                 "\n"
                 "[Mount]\n"
-                "Where=/boot\n"
                 "What=%s\n"
+                "Where=/boot\n"
+                "Type=vfat\n"
                 "Options=umask=0077,noauto\n",
-                fsck, fsck, what);
+                what);
+
+        fflush(f);
+        if (ferror(f)) {
+                log_error("Failed to write mount unit file: %m");
+                return EXIT_FAILURE;
+        }
 
         name = strappenda(arg_dest, "/boot.automount");
-        f2 = fopen(name, "wxe");
-        if (!f2) {
+        fclose(f);
+        f = fopen(name, "wxe");
+        if (!f) {
                 log_error("Failed to create automount unit file %s: %m", name);
                 return EXIT_FAILURE;
         }
@@ -110,9 +136,15 @@ int main(int argc, char *argv[]) {
               "[Unit]\n"
               "Description=EFI System Partition Automount\n\n"
               "[Automount]\n"
-              "Where=/boot\n", f2);
+              "Where=/boot\n", f);
+
+        fflush(f);
+        if (ferror(f)) {
+                log_error("Failed to write automount unit file: %m");
+                return EXIT_FAILURE;
+        }
 
-        name = strappenda(arg_dest, "/local-fs.target.wants/boot.automount");
+        name = strappenda(arg_dest, "/" SPECIAL_LOCAL_FS_TARGET ".wants/boot.automount");
         mkdir_parents(name, 0755);
 
         if (symlink("../boot.automount", name) < 0) {
diff --git a/src/escape/Makefile b/src/escape/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/escape/escape.c b/src/escape/escape.c
new file mode 100644 (file)
index 0000000..f2a0721
--- /dev/null
@@ -0,0 +1,236 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Michael Biebl
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <getopt.h>
+
+#include "log.h"
+#include "unit-name.h"
+#include "build.h"
+#include "strv.h"
+
+static enum {
+        ACTION_ESCAPE,
+        ACTION_UNESCAPE,
+        ACTION_MANGLE
+} arg_action = ACTION_ESCAPE;
+static const char *arg_suffix = NULL;
+static const char *arg_template = NULL;
+static bool arg_path = false;
+
+static void help(void) {
+        printf("%s [OPTIONS...] [NAME...]\n\n"
+               "Show system and user paths.\n\n"
+               "  -h --help               Show this help\n"
+               "     --version            Show package version\n"
+               "     --suffix=SUFFIX      Unit suffix to append to escaped strings\n"
+               "     --template=TEMPLATE  Insert strings as instance into template\n"
+               "  -u --unescape           Unescape strings\n"
+               "  -m --mangle             Mangle strings\n"
+               "  -p --path               When escaping/unescaping assume the string is a path\n"
+               , program_invocation_short_name);
+}
+
+static int parse_argv(int argc, char *argv[]) {
+
+        enum {
+                ARG_VERSION = 0x100,
+                ARG_SUFFIX,
+                ARG_TEMPLATE
+        };
+
+        static const struct option options[] = {
+                { "help",      no_argument,       NULL, 'h'           },
+                { "version",   no_argument,       NULL, ARG_VERSION   },
+                { "suffix",    required_argument, NULL, ARG_SUFFIX    },
+                { "template",  required_argument, NULL, ARG_TEMPLATE  },
+                { "unescape",  no_argument,       NULL, 'u'           },
+                { "mangle",    no_argument,       NULL, 'm'           },
+                { "path",      no_argument,       NULL, 'p'           },
+                {}
+        };
+
+        int c;
+
+        assert(argc >= 0);
+        assert(argv);
+
+        while ((c = getopt_long(argc, argv, "hump", options, NULL)) >= 0)
+
+                switch (c) {
+
+                case 'h':
+                        help();
+                        return 0;
+
+                case ARG_VERSION:
+                        puts(PACKAGE_STRING);
+                        puts(SYSTEMD_FEATURES);
+                        return 0;
+
+                case ARG_SUFFIX:
+
+                        if (unit_type_from_string(optarg) < 0) {
+                                log_error("Invalid unit suffix type %s.", optarg);
+                                return -EINVAL;
+                        }
+
+                        arg_suffix = optarg;
+                        break;
+
+                case ARG_TEMPLATE:
+
+                        if (!unit_name_is_valid(optarg, true) || !unit_name_is_template(optarg)) {
+                                log_error("Template name %s is not valid.", optarg);
+                                return -EINVAL;
+                        }
+
+                        arg_template = optarg;
+                        break;
+
+                case 'u':
+                        arg_action = ACTION_UNESCAPE;
+                        break;
+
+                case 'm':
+                        arg_action = ACTION_MANGLE;
+                        break;
+
+                case 'p':
+                        arg_path = true;
+                        break;
+
+                case '?':
+                        return -EINVAL;
+
+                default:
+                        assert_not_reached("Unhandled option");
+                }
+
+        if (optind >= argc) {
+                log_error("Not enough arguments.");
+                return -EINVAL;
+        }
+
+        if (arg_template && arg_suffix) {
+                log_error("--suffix= and --template= may not be combined.");
+                return -EINVAL;
+        }
+
+        if ((arg_template || arg_suffix) && arg_action != ACTION_ESCAPE) {
+                log_error("--suffix= and --template= are not compatible with --unescape or --mangle.");
+                return -EINVAL;
+        }
+
+        if (arg_path && !IN_SET(arg_action, ACTION_ESCAPE, ACTION_UNESCAPE)) {
+                log_error("--path may not be combined with --mangle.");
+                return -EINVAL;
+        }
+
+        return 1;
+}
+
+int main(int argc, char *argv[]) {
+        char **i;
+        int r;
+
+        log_parse_environment();
+        log_open();
+
+        r = parse_argv(argc, argv);
+        if (r <= 0)
+                goto finish;
+
+        STRV_FOREACH(i, argv + optind) {
+                _cleanup_free_ char *e = NULL;
+
+                switch (arg_action) {
+
+                case ACTION_ESCAPE:
+                        if (arg_path)
+                                e = unit_name_path_escape(*i);
+                        else
+                                e = unit_name_escape(*i);
+
+                        if (!e) {
+                                r = log_oom();
+                                goto finish;
+                        }
+
+                        if (arg_template) {
+                                char *x;
+
+                                x = unit_name_replace_instance(arg_template, e);
+                                if (!x) {
+                                        r = log_oom();
+                                        goto finish;
+                                }
+
+                                free(e);
+                                e = x;
+                        } else if (arg_suffix) {
+                                char *x;
+
+                                x = strjoin(e, ".", arg_suffix, NULL);
+                                if (!x) {
+                                        r = log_oom();
+                                        goto finish;
+                                }
+
+                                free(e);
+                                e = x;
+                        }
+
+                        break;
+
+                case ACTION_UNESCAPE:
+                        if (arg_path)
+                                e = unit_name_path_unescape(*i);
+                        else
+                                e = unit_name_unescape(*i);
+
+                        if (!e) {
+                                r = log_oom();
+                                goto finish;
+                        }
+                        break;
+
+                case ACTION_MANGLE:
+                        e = unit_name_mangle(*i, MANGLE_NOGLOB);
+                        if (!e) {
+                                r = log_oom();
+                                goto finish;
+                        }
+                        break;
+                }
+
+                if (i != argv+optind)
+                        fputc(' ', stdout);
+
+                fputs(e, stdout);
+        }
+
+        fputc('\n', stdout);
+
+finish:
+        return r <= 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/src/firstboot/Makefile b/src/firstboot/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/firstboot/firstboot.c b/src/firstboot/firstboot.c
new file mode 100644 (file)
index 0000000..fd73adb
--- /dev/null
@@ -0,0 +1,935 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <shadow.h>
+
+#include "strv.h"
+#include "fileio.h"
+#include "copy.h"
+#include "build.h"
+#include "mkdir.h"
+#include "time-util.h"
+#include "path-util.h"
+#include "locale-util.h"
+#include "ask-password-api.h"
+
+static char *arg_root = NULL;
+static char *arg_locale = NULL;  /* $LANG */
+static char *arg_locale_messages = NULL; /* $LC_MESSAGES */
+static char *arg_timezone = NULL;
+static char *arg_hostname = NULL;
+static sd_id128_t arg_machine_id = {};
+static char *arg_root_password = NULL;
+static bool arg_prompt_locale = false;
+static bool arg_prompt_timezone = false;
+static bool arg_prompt_hostname = false;
+static bool arg_prompt_root_password = false;
+static bool arg_copy_locale = false;
+static bool arg_copy_timezone = false;
+static bool arg_copy_root_password = false;
+
+#define prefix_roota(p) (arg_root ? (const char*) strappenda(arg_root, p) : (const char*) p)
+
+static void clear_string(char *x) {
+
+        if (!x)
+                return;
+
+        /* A delicious drop of snake-oil! */
+        memset(x, 'x', strlen(x));
+}
+
+static bool press_any_key(void) {
+        char k = 0;
+        bool need_nl = true;
+
+        printf("-- Press any key to proceed --");
+        fflush(stdout);
+
+        read_one_char(stdin, &k, USEC_INFINITY, &need_nl);
+
+        if (need_nl)
+                putchar('\n');
+
+        return k != 'q';
+}
+
+static void print_welcome(void) {
+        _cleanup_free_ char *pretty_name = NULL;
+        const char *os_release = NULL;
+        static bool done = false;
+        int r;
+
+        if (done)
+                return;
+
+        os_release = prefix_roota("/etc/os-release");
+        r = parse_env_file(os_release, NEWLINE,
+                           "PRETTY_NAME", &pretty_name,
+                           NULL);
+        if (r == -ENOENT) {
+
+                os_release = prefix_roota("/usr/lib/os-release");
+                r = parse_env_file(os_release, NEWLINE,
+                                   "PRETTY_NAME", &pretty_name,
+                                   NULL);
+        }
+
+        if (r < 0 && r != -ENOENT)
+                log_warning("Failed to read os-release file: %s", strerror(-r));
+
+        printf("\nWelcome to your new installation of %s!\nPlease configure a few basic system settings:\n\n",
+               isempty(pretty_name) ? "Linux" : pretty_name);
+
+        press_any_key();
+
+        done = true;
+}
+
+static int show_menu(char **x, unsigned n_columns, unsigned width, unsigned percentage) {
+        unsigned n, per_column, i, j;
+        unsigned break_lines, break_modulo;
+
+        assert(n_columns > 0);
+
+        n = strv_length(x);
+        per_column = (n + n_columns - 1) / n_columns;
+
+        break_lines = lines();
+        if (break_lines > 2)
+                break_lines--;
+
+        /* The first page gets two extra lines, since we want to show
+         * a title */
+        break_modulo = break_lines;
+        if (break_modulo > 3)
+                break_modulo -= 3;
+
+        for (i = 0; i < per_column; i++) {
+
+                for (j = 0; j < n_columns; j ++) {
+                        _cleanup_free_ char *e = NULL;
+
+                        if (j * per_column + i >= n)
+                                break;
+
+                        e = ellipsize(x[j * per_column + i], width, percentage);
+                        if (!e)
+                                return log_oom();
+
+                        printf("%4u) %-*s", j * per_column + i + 1, width, e);
+                }
+
+                putchar('\n');
+
+                /* on the first screen we reserve 2 extra lines for the title */
+                if (i % break_lines == break_modulo) {
+                        if (!press_any_key())
+                                return 0;
+                }
+        }
+
+        return 0;
+}
+
+static int prompt_loop(const char *text, char **l, bool (*is_valid)(const char *name), char **ret) {
+        int r;
+
+        assert(text);
+        assert(is_valid);
+        assert(ret);
+
+        for (;;) {
+                _cleanup_free_ char *p = NULL;
+                unsigned u;
+
+                r = ask_string(&p, "%s %s (empty to skip): ", draw_special_char(DRAW_TRIANGULAR_BULLET), text);
+                if (r < 0) {
+                        log_error("Failed to query user: %s", strerror(-r));
+                        return r;
+                }
+
+                if (isempty(p)) {
+                        log_warning("No data entered, skipping.");
+                        return 0;
+                }
+
+                r = safe_atou(p, &u);
+                if (r >= 0) {
+                        char *c;
+
+                        if (u <= 0 || u > strv_length(l)) {
+                                log_error("Specified entry number out of range.");
+                                continue;
+                        }
+
+                        log_info("Selected '%s'.", l[u-1]);
+
+                        c = strdup(l[u-1]);
+                        if (!c)
+                                return log_oom();
+
+                        free(*ret);
+                        *ret = c;
+                        return 0;
+                }
+
+                if (!is_valid(p)) {
+                        log_error("Entered data invalid.");
+                        continue;
+                }
+
+                free(*ret);
+                *ret = p;
+                p = 0;
+                return 0;
+        }
+}
+
+static int prompt_locale(void) {
+        _cleanup_strv_free_ char **locales = NULL;
+        int r;
+
+        if (arg_locale || arg_locale_messages)
+                return 0;
+
+        if (!arg_prompt_locale)
+                return 0;
+
+        r = get_locales(&locales);
+        if (r < 0) {
+                log_error("Cannot query locales list: %s", strerror(-r));
+                return r;
+        }
+
+        print_welcome();
+
+        printf("\nAvailable Locales:\n\n");
+        r = show_menu(locales, 3, 22, 60);
+        if (r < 0)
+                return r;
+
+        putchar('\n');
+
+        r = prompt_loop("Please enter system locale name or number", locales, locale_is_valid, &arg_locale);
+        if (r < 0)
+                return r;
+
+        if (isempty(arg_locale))
+                return 0;
+
+        r = prompt_loop("Please enter system message locale name or number", locales, locale_is_valid, &arg_locale_messages);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+static int process_locale(void) {
+        const char *etc_localeconf;
+        char* locales[3];
+        unsigned i = 0;
+        int r;
+
+        etc_localeconf = prefix_roota("/etc/locale.conf");
+        if (faccessat(AT_FDCWD, etc_localeconf, F_OK, AT_SYMLINK_NOFOLLOW) >= 0)
+                return 0;
+
+        if (arg_copy_locale && arg_root) {
+
+                mkdir_parents(etc_localeconf, 0755);
+                r = copy_file("/etc/locale.conf", etc_localeconf, 0, 0644);
+                if (r != -ENOENT) {
+                        if (r < 0) {
+                                log_error("Failed to copy %s: %s", etc_localeconf, strerror(-r));
+                                return r;
+                        }
+
+                        log_info("%s copied.", etc_localeconf);
+                        return 0;
+                }
+        }
+
+        r = prompt_locale();
+        if (r < 0)
+                return r;
+
+        if (!isempty(arg_locale))
+                locales[i++] = strappenda("LANG=", arg_locale);
+        if (!isempty(arg_locale_messages) && !streq(arg_locale_messages, arg_locale))
+                locales[i++] = strappenda("LC_MESSAGES=", arg_locale_messages);
+
+        if (i == 0)
+                return 0;
+
+        locales[i] = NULL;
+
+        mkdir_parents(etc_localeconf, 0755);
+        r = write_env_file(etc_localeconf, locales);
+        if (r < 0) {
+                log_error("Failed to write %s: %s", etc_localeconf, strerror(-r));
+                return r;
+        }
+
+        log_info("%s written.", etc_localeconf);
+        return 0;
+}
+
+static int prompt_timezone(void) {
+        _cleanup_strv_free_ char **zones = NULL;
+        int r;
+
+        if (arg_timezone)
+                return 0;
+
+        if (!arg_prompt_timezone)
+                return 0;
+
+        r = get_timezones(&zones);
+        if (r < 0) {
+                log_error("Cannot query timezone list: %s", strerror(-r));
+                return r;
+        }
+
+        print_welcome();
+
+        printf("\nAvailable Time Zones:\n\n");
+        r = show_menu(zones, 3, 22, 30);
+        if (r < 0)
+                return r;
+
+        putchar('\n');
+
+        r = prompt_loop("Please enter timezone name or number", zones, timezone_is_valid, &arg_timezone);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+static int process_timezone(void) {
+        const char *etc_localtime, *e;
+        int r;
+
+        etc_localtime = prefix_roota("/etc/localtime");
+        if (faccessat(AT_FDCWD, etc_localtime, F_OK, AT_SYMLINK_NOFOLLOW) >= 0)
+                return 0;
+
+        if (arg_copy_timezone && arg_root) {
+                _cleanup_free_ char *p = NULL;
+
+                r = readlink_malloc("/etc/localtime", &p);
+                if (r != -ENOENT) {
+                        if (r < 0) {
+                                log_error("Failed to read host timezone: %s", strerror(-r));
+                                return r;
+                        }
+
+                        mkdir_parents(etc_localtime, 0755);
+                        if (symlink(p, etc_localtime) < 0) {
+                                log_error("Failed to create %s symlink: %m", etc_localtime);
+                                return -errno;
+                        }
+
+                        log_info("%s copied.", etc_localtime);
+                        return 0;
+                }
+        }
+
+        r = prompt_timezone();
+        if (r < 0)
+                return r;
+
+        if (isempty(arg_timezone))
+                return 0;
+
+        e = strappenda("../usr/share/zoneinfo/", arg_timezone);
+
+        mkdir_parents(etc_localtime, 0755);
+        if (symlink(e, etc_localtime) < 0) {
+                log_error("Failed to create %s symlink: %m", etc_localtime);
+                return -errno;
+        }
+
+        log_info("%s written", etc_localtime);
+        return 0;
+}
+
+static int prompt_hostname(void) {
+        int r;
+
+        if (arg_hostname)
+                return 0;
+
+        if (!arg_prompt_hostname)
+                return 0;
+
+        print_welcome();
+        putchar('\n');
+
+        for (;;) {
+                _cleanup_free_ char *h = NULL;
+
+                r = ask_string(&h, "%s Please enter hostname for new system (empty to skip): ", draw_special_char(DRAW_TRIANGULAR_BULLET));
+                if (r < 0) {
+                        log_error("Failed to query hostname: %s", strerror(-r));
+                        return r;
+                }
+
+                if (isempty(h)) {
+                        log_warning("No hostname entered, skipping.");
+                        break;
+                }
+
+                if (!hostname_is_valid(h)) {
+                        log_error("Specified hostname invalid.");
+                        continue;
+                }
+
+                arg_hostname = h;
+                h = NULL;
+                break;
+        }
+
+        return 0;
+}
+
+static int process_hostname(void) {
+        const char *etc_hostname;
+        int r;
+
+        etc_hostname = prefix_roota("/etc/hostname");
+        if (faccessat(AT_FDCWD, etc_hostname, F_OK, AT_SYMLINK_NOFOLLOW) >= 0)
+                return 0;
+
+        r = prompt_hostname();
+        if (r < 0)
+                return r;
+
+        if (isempty(arg_hostname))
+                return 0;
+
+        mkdir_parents(etc_hostname, 0755);
+        r = write_string_file(etc_hostname, arg_hostname);
+        if (r < 0) {
+                log_error("Failed to write %s: %s", etc_hostname, strerror(-r));
+                return r;
+        }
+
+        log_info("%s written.", etc_hostname);
+        return 0;
+}
+
+static int process_machine_id(void) {
+        const char *etc_machine_id;
+        char id[SD_ID128_STRING_MAX];
+        int r;
+
+        etc_machine_id = prefix_roota("/etc/machine-id");
+        if (faccessat(AT_FDCWD, etc_machine_id, F_OK, AT_SYMLINK_NOFOLLOW) >= 0)
+                return 0;
+
+        if (!arg_root)
+                return 0;
+
+        if (sd_id128_equal(arg_machine_id, SD_ID128_NULL))
+                return 0;
+
+        mkdir_parents(etc_machine_id, 0755);
+        r = write_string_file(etc_machine_id, sd_id128_to_string(arg_machine_id, id));
+        if (r < 0) {
+                log_error("Failed to write machine id: %s", strerror(-r));
+                return r;
+        }
+
+        log_info("%s written.", etc_machine_id);
+        return 0;
+}
+
+static int prompt_root_password(void) {
+        const char *msg1, *msg2, *etc_shadow;
+        int r;
+
+        if (arg_root_password)
+                return 0;
+
+        if (!arg_prompt_root_password)
+                return 0;
+
+        etc_shadow = prefix_roota("/etc/shadow");
+        if (faccessat(AT_FDCWD, etc_shadow, F_OK, AT_SYMLINK_NOFOLLOW) >= 0)
+                return 0;
+
+        print_welcome();
+        putchar('\n');
+
+        msg1 = strappenda(draw_special_char(DRAW_TRIANGULAR_BULLET), " Please enter a new root password (empty to skip): ");
+        msg2 = strappenda(draw_special_char(DRAW_TRIANGULAR_BULLET), " Please enter new root password again: ");
+
+        for (;;) {
+                _cleanup_free_ char *a = NULL, *b = NULL;
+
+                r = ask_password_tty(msg1, 0, NULL, &a);
+                if (r < 0) {
+                        log_error("Failed to query root password: %s", strerror(-r));
+                        return r;
+                }
+
+                if (isempty(a)) {
+                        log_warning("No password entered, skipping.");
+                        break;
+                }
+
+                r = ask_password_tty(msg2, 0, NULL, &b);
+                if (r < 0) {
+                        log_error("Failed to query root password: %s", strerror(-r));
+                        clear_string(a);
+                        return r;
+                }
+
+                if (!streq(a, b)) {
+                        log_error("Entered passwords did not match, please try again.");
+                        clear_string(a);
+                        clear_string(b);
+                        continue;
+                }
+
+                clear_string(b);
+                arg_root_password = a;
+                a = NULL;
+                break;
+        }
+
+        return 0;
+}
+
+static int write_root_shadow(const char *path, const struct spwd *p) {
+        _cleanup_fclose_ FILE *f = NULL;
+        assert(path);
+        assert(p);
+
+        RUN_WITH_UMASK(0777)
+                f = fopen(path, "wex");
+        if (!f)
+                return -errno;
+
+        errno = 0;
+        if (putspent(p, f) != 0)
+                return errno ? -errno : -EIO;
+
+        return fflush_and_check(f);
+}
+
+static int process_root_password(void) {
+
+        static const char table[] =
+                "abcdefghijklmnopqrstuvwxyz"
+                "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                "0123456789"
+                "./";
+
+        struct spwd item = {
+                .sp_namp = (char*) "root",
+                .sp_min = 0,
+                .sp_max = 99999,
+                .sp_warn = 7,
+                .sp_inact = -1,
+                .sp_expire = -1,
+                .sp_flag = (unsigned long) -1, /* this appears to be what everybody does ... */
+        };
+
+        _cleanup_close_ int lock = -1;
+        char salt[3+16+1+1];
+        uint8_t raw[16];
+        unsigned i;
+        char *j;
+
+        const char *etc_shadow;
+        int r;
+
+        etc_shadow = prefix_roota("/etc/shadow");
+        if (faccessat(AT_FDCWD, etc_shadow, F_OK, AT_SYMLINK_NOFOLLOW) >= 0)
+                return 0;
+
+        mkdir_parents(etc_shadow, 0755);
+
+        lock = take_password_lock(arg_root);
+        if (lock < 0)
+                return lock;
+
+        if (arg_copy_root_password && arg_root) {
+                struct spwd *p;
+
+                errno = 0;
+                p = getspnam("root");
+                if (p || errno != ENOENT) {
+                        if (!p) {
+                                if (!errno)
+                                        errno = EIO;
+
+                                log_error("Failed to find shadow entry for root: %m");
+                                return -errno;
+                        }
+
+                        r = write_root_shadow(etc_shadow, p);
+                        if (r < 0) {
+                                log_error("Failed to write %s: %s", etc_shadow, strerror(-r));
+                                return r;
+                        }
+
+                        log_info("%s copied.", etc_shadow);
+                        return 0;
+                }
+        }
+
+        r = prompt_root_password();
+        if (r < 0)
+                return r;
+
+        if (!arg_root_password)
+                return 0;
+
+        r = dev_urandom(raw, 16);
+        if (r < 0) {
+                log_error("Failed to get salt: %s", strerror(-r));
+                return r;
+        }
+
+        /* We only bother with SHA512 hashed passwords, the rest is legacy, and we don't do legacy. */
+        assert_cc(sizeof(table) == 64 + 1);
+        j = stpcpy(salt, "$6$");
+        for (i = 0; i < 16; i++)
+                j[i] = table[raw[i] & 63];
+        j[i++] = '$';
+        j[i] = 0;
+
+        errno = 0;
+        item.sp_pwdp = crypt(arg_root_password, salt);
+        if (!item.sp_pwdp) {
+                if (!errno)
+                        errno = -EINVAL;
+
+                log_error("Failed to encrypt password: %m");
+                return -errno;
+        }
+
+        item.sp_lstchg = (long) (now(CLOCK_REALTIME) / USEC_PER_DAY);
+
+        r = write_root_shadow(etc_shadow, &item);
+        if (r < 0) {
+                log_error("Failed to write %s: %s", etc_shadow, strerror(-r));
+                return r;
+        }
+
+        log_info("%s written.", etc_shadow);
+        return 0;
+}
+
+static void help(void) {
+        printf("%s [OPTIONS...]\n\n"
+               "Configures basic settings of the system.\n\n"
+               "  -h --help                    Show this help\n"
+               "     --version                 Show package version\n"
+               "     --root=PATH               Operate on an alternate filesystem root\n"
+               "     --locale=LOCALE           Set primary locale (LANG=)\n"
+               "     --locale-messages=LOCALE  Set message locale (LC_MESSAGES=)\n"
+               "     --timezone=TIMEZONE       Set timezone\n"
+               "     --hostname=NAME           Set host name\n"
+               "     --machine-ID=ID           Set machine ID\n"
+               "     --root-password=PASSWORD  Set root password\n"
+               "     --root-password-file=FILE Set root password from file\n"
+               "     --prompt-locale           Prompt the user for locale settings\n"
+               "     --prompt-timezone         Prompt the user for timezone\n"
+               "     --prompt-hostname         Prompt the user for hostname\n"
+               "     --prompt-root-password    Prompt the user for root password\n"
+               "     --prompt                  Prompt for locale, timezone, hostname, root password\n"
+               "     --copy-locale             Copy locale from host\n"
+               "     --copy-timezone           Copy timezone from host\n"
+               "     --copy-root-password      Copy root password from host\n"
+               "     --copy                    Copy locale, timezone, root password\n"
+               "     --setup-machine-id        Generate a new random machine ID\n"
+               , program_invocation_short_name);
+}
+
+static int parse_argv(int argc, char *argv[]) {
+
+        enum {
+                ARG_VERSION = 0x100,
+                ARG_ROOT,
+                ARG_LOCALE,
+                ARG_LOCALE_MESSAGES,
+                ARG_TIMEZONE,
+                ARG_HOSTNAME,
+                ARG_MACHINE_ID,
+                ARG_ROOT_PASSWORD,
+                ARG_ROOT_PASSWORD_FILE,
+                ARG_PROMPT,
+                ARG_PROMPT_LOCALE,
+                ARG_PROMPT_TIMEZONE,
+                ARG_PROMPT_HOSTNAME,
+                ARG_PROMPT_ROOT_PASSWORD,
+                ARG_COPY,
+                ARG_COPY_LOCALE,
+                ARG_COPY_TIMEZONE,
+                ARG_COPY_ROOT_PASSWORD,
+                ARG_SETUP_MACHINE_ID,
+        };
+
+        static const struct option options[] = {
+                { "help",                 no_argument,       NULL, 'h'                      },
+                { "version",              no_argument,       NULL, ARG_VERSION              },
+                { "root",                 required_argument, NULL, ARG_ROOT                 },
+                { "locale",               required_argument, NULL, ARG_LOCALE               },
+                { "locale-messages",      required_argument, NULL, ARG_LOCALE_MESSAGES      },
+                { "timezone",             required_argument, NULL, ARG_TIMEZONE             },
+                { "hostname",             required_argument, NULL, ARG_HOSTNAME             },
+                { "machine-id",           required_argument, NULL, ARG_MACHINE_ID           },
+                { "root-password",        required_argument, NULL, ARG_ROOT_PASSWORD        },
+                { "root-password-file",   required_argument, NULL, ARG_ROOT_PASSWORD_FILE   },
+                { "prompt",               no_argument,       NULL, ARG_PROMPT               },
+                { "prompt-locale",        no_argument,       NULL, ARG_PROMPT_LOCALE        },
+                { "prompt-timezone",      no_argument,       NULL, ARG_PROMPT_TIMEZONE      },
+                { "prompt-hostname",      no_argument,       NULL, ARG_PROMPT_HOSTNAME      },
+                { "prompt-root-password", no_argument,       NULL, ARG_PROMPT_ROOT_PASSWORD },
+                { "copy",                 no_argument,       NULL, ARG_COPY                 },
+                { "copy-locale",          no_argument,       NULL, ARG_COPY_LOCALE          },
+                { "copy-timezone",        no_argument,       NULL, ARG_COPY_TIMEZONE        },
+                { "copy-root-password",   no_argument,       NULL, ARG_COPY_ROOT_PASSWORD   },
+                { "setup-machine-id",     no_argument,       NULL, ARG_SETUP_MACHINE_ID     },
+                {}
+        };
+
+        int r, c;
+
+        assert(argc >= 0);
+        assert(argv);
+
+        while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
+
+                switch (c) {
+
+                case 'h':
+                        help();
+                        return 0;
+
+                case ARG_VERSION:
+                        puts(PACKAGE_STRING);
+                        puts(SYSTEMD_FEATURES);
+                        return 0;
+
+                case ARG_ROOT:
+                        free(arg_root);
+                        arg_root = path_make_absolute_cwd(optarg);
+                        if (!arg_root)
+                                return log_oom();
+
+                        path_kill_slashes(arg_root);
+
+                        if (path_equal(arg_root, "/")) {
+                                free(arg_root);
+                                arg_root = NULL;
+                        }
+
+                        break;
+
+                case ARG_LOCALE:
+                        if (!locale_is_valid(optarg)) {
+                                log_error("Locale %s is not valid.", optarg);
+                                return -EINVAL;
+                        }
+
+                        free(arg_locale);
+                        arg_locale = strdup(optarg);
+                        if (!arg_locale)
+                                return log_oom();
+
+                        break;
+
+                case ARG_LOCALE_MESSAGES:
+                        if (!locale_is_valid(optarg)) {
+                                log_error("Locale %s is not valid.", optarg);
+                                return -EINVAL;
+                        }
+
+                        free(arg_locale_messages);
+                        arg_locale_messages = strdup(optarg);
+                        if (!arg_locale_messages)
+                                return log_oom();
+
+                        break;
+
+                case ARG_TIMEZONE:
+                        if (!timezone_is_valid(optarg)) {
+                                log_error("Timezone %s is not valid.", optarg);
+                                return -EINVAL;
+                        }
+
+                        free(arg_timezone);
+                        arg_timezone = strdup(optarg);
+                        if (!arg_timezone)
+                                return log_oom();
+
+                        break;
+
+                case ARG_ROOT_PASSWORD:
+                        free(arg_root_password);
+                        arg_root_password = strdup(optarg);
+                        if (!arg_root_password)
+                                return log_oom();
+
+                        break;
+
+                case ARG_ROOT_PASSWORD_FILE:
+                        free(arg_root_password);
+                        arg_root_password  = NULL;
+
+                        r = read_one_line_file(optarg, &arg_root_password);
+                        if (r < 0) {
+                                log_error("Failed to read %s: %s", optarg, strerror(-r));
+                                return r;
+                        }
+
+                        break;
+
+                case ARG_HOSTNAME:
+                        if (!hostname_is_valid(optarg)) {
+                                log_error("Host name %s is not valid.", optarg);
+                                return -EINVAL;
+                        }
+
+                        free(arg_hostname);
+                        arg_hostname = strdup(optarg);
+                        if (!arg_hostname)
+                                return log_oom();
+
+                        break;
+
+                case ARG_MACHINE_ID:
+                        if (sd_id128_from_string(optarg, &arg_machine_id) < 0) {
+                                log_error("Failed to parse machine id %s.", optarg);
+                                return -EINVAL;
+                        }
+
+                        break;
+
+                case ARG_PROMPT:
+                        arg_prompt_locale = arg_prompt_timezone = arg_prompt_hostname = arg_prompt_root_password = true;
+                        break;
+
+                case ARG_PROMPT_LOCALE:
+                        arg_prompt_locale = true;
+                        break;
+
+                case ARG_PROMPT_TIMEZONE:
+                        arg_prompt_timezone = true;
+                        break;
+
+                case ARG_PROMPT_HOSTNAME:
+                        arg_prompt_hostname = true;
+                        break;
+
+                case ARG_PROMPT_ROOT_PASSWORD:
+                        arg_prompt_root_password = true;
+                        break;
+
+                case ARG_COPY:
+                        arg_copy_locale = arg_copy_timezone = arg_copy_root_password = true;
+
+                case ARG_COPY_LOCALE:
+                        arg_copy_locale = true;
+                        break;
+
+                case ARG_COPY_TIMEZONE:
+                        arg_copy_timezone = true;
+                        break;
+
+                case ARG_COPY_ROOT_PASSWORD:
+                        arg_copy_root_password = true;
+                        break;
+
+                case ARG_SETUP_MACHINE_ID:
+
+                        r = sd_id128_randomize(&arg_machine_id);
+                        if (r < 0) {
+                                log_error("Failed to generate randomized machine ID: %s", strerror(-r));
+                                return r;
+                        }
+
+                        break;
+
+                case '?':
+                        return -EINVAL;
+
+                default:
+                        assert_not_reached("Unhandled option");
+                }
+
+        return 1;
+}
+
+int main(int argc, char *argv[]) {
+        int r;
+
+        r = parse_argv(argc, argv);
+        if (r <= 0)
+                goto finish;
+
+        log_set_target(LOG_TARGET_AUTO);
+        log_parse_environment();
+        log_open();
+
+        umask(0022);
+
+        r = process_locale();
+        if (r < 0)
+                goto finish;
+
+        r = process_timezone();
+        if (r < 0)
+                goto finish;
+
+        r = process_hostname();
+        if (r < 0)
+                goto finish;
+
+        r = process_machine_id();
+        if (r < 0)
+                goto finish;
+
+        r = process_root_password();
+        if (r < 0)
+                goto finish;
+
+finish:
+        free(arg_root);
+        free(arg_locale);
+        free(arg_locale_messages);
+        free(arg_timezone);
+        free(arg_hostname);
+        clear_string(arg_root_password);
+        free(arg_root_password);
+
+        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
index 4a5f6b1..dfe97bc 100644 (file)
@@ -4,6 +4,7 @@
   This file is part of systemd.
 
   Copyright 2010 Lennart Poettering
+  Copyright 2014 Holger Hans Peter Freyther
 
   systemd is free software; you can redistribute it and/or modify it
   under the terms of the GNU Lesser General Public License as published by
 #include "bus-errors.h"
 #include "fileio.h"
 #include "udev-util.h"
+#include "path-util.h"
 
 static bool arg_skip = false;
 static bool arg_force = false;
 static bool arg_show_progress = false;
+static const char *arg_repair = "-a";
 
 static void start_target(const char *target) {
         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
-        _cleanup_bus_unref_ sd_bus *bus = NULL;
+        _cleanup_bus_close_unref_ sd_bus *bus = NULL;
         int r;
 
         assert(target);
@@ -72,21 +75,38 @@ static void start_target(const char *target) {
                 log_error("Failed to start unit: %s", bus_error_message(&error, -r));
 }
 
-static int parse_proc_cmdline_word(const char *w) {
-        if (streq(w, "fsck.mode=auto"))
-                arg_force = arg_skip = false;
-        else if (streq(w, "fsck.mode=force"))
-                arg_force = true;
-        else if (streq(w, "fsck.mode=skip"))
-                arg_skip = true;
-        else if (startswith(w, "fsck"))
-                log_warning("Invalid fsck parameter. Ignoring.");
+static int parse_proc_cmdline_item(const char *key, const char *value) {
+
+        if (streq(key, "fsck.mode") && value) {
+
+                if (streq(value, "auto"))
+                        arg_force = arg_skip = false;
+                else if (streq(value, "force"))
+                        arg_force = true;
+                else if (streq(value, "skip"))
+                        arg_skip = true;
+                else
+                        log_warning("Invalid fsck.mode= parameter '%s'. Ignoring.", value);
+
+        } else if (streq(key, "fsck.repair") && value) {
+
+                if (streq(value, "preen"))
+                        arg_repair = "-a";
+                else if (streq(value, "yes"))
+                        arg_repair = "-y";
+                else if (streq(value, "no"))
+                        arg_repair = "-n";
+                else
+                        log_warning("Invalid fsck.repair= parameter '%s'. Ignoring.", value);
+        }
+
 #ifdef HAVE_SYSV_COMPAT
-        else if (streq(w, "fastboot")) {
-                log_error("Please pass 'fsck.mode=skip' rather than 'fastboot' on the kernel command line.");
+        else if (streq(key, "fastboot") && !value) {
+                log_warning("Please pass 'fsck.mode=skip' rather than 'fastboot' on the kernel command line.");
                 arg_skip = true;
-        } else if (streq(w, "forcefsck")) {
-                log_error("Please pass 'fsck.mode=force' rather than 'forcefsck' on the kernel command line.");
+
+        } else if (streq(key, "forcefsck") && !value) {
+                log_warning("Please pass 'fsck.mode=force' rather than 'forcefsck' on the kernel command line.");
                 arg_force = true;
         }
 #endif
@@ -95,6 +115,7 @@ static int parse_proc_cmdline_word(const char *w) {
 }
 
 static void test_files(void) {
+
 #ifdef HAVE_SYSV_COMPAT
         if (access("/fastboot", F_OK) >= 0) {
                 log_error("Please pass 'fsck.mode=skip' on the kernel command line rather than creating /fastboot on the root file system.");
@@ -137,7 +158,7 @@ static int process_progress(int fd) {
 
         f = fdopen(fd, "r");
         if (!f) {
-                close_nointr_nofail(fd);
+                safe_close(fd);
                 return -errno;
         }
 
@@ -215,7 +236,7 @@ int main(int argc, char *argv[]) {
 
         umask(0022);
 
-        parse_proc_cmdline(parse_proc_cmdline_word);
+        parse_proc_cmdline(parse_proc_cmdline_item);
         test_files();
 
         if (!arg_force && arg_skip)
@@ -280,15 +301,12 @@ int main(int argc, char *argv[]) {
 
         type = udev_device_get_property_value(udev_device, "ID_FS_TYPE");
         if (type) {
-                const char *checker = strappenda("/sbin/fsck.", type);
-                r = access(checker, X_OK);
-                if (r < 0) {
-                        if (errno == ENOENT) {
-                                log_info("%s doesn't exist, not checking file system.", checker);
-                                return EXIT_SUCCESS;
-                        } else
-                                log_warning("%s cannot be used: %m", checker);
-                }
+                r = fsck_exists(type);
+                if (r == -ENOENT) {
+                        log_info("fsck.%s doesn't exist, not checking file system on %s", type, device);
+                        return EXIT_SUCCESS;
+                } else if (r < 0)
+                        log_warning("fsck.%s cannot be used for %s: %s", type, device, strerror(-r));
         }
 
         if (arg_show_progress)
@@ -298,9 +316,20 @@ int main(int argc, char *argv[]) {
                 }
 
         cmdline[i++] = "/sbin/fsck";
-        cmdline[i++] = "-a";
+        cmdline[i++] =  arg_repair;
         cmdline[i++] = "-T";
-        cmdline[i++] = "-l";
+
+        /*
+         * Disable locking which conflict with udev's event
+         * ownershipi, until util-linux moves the flock
+         * synchronization file which prevents multiple fsck running
+         * on the same rotationg media, from the disk device
+         * node to a privately owned regular file.
+         *
+         * https://bugs.freedesktop.org/show_bug.cgi?id=79576#c5
+         *
+         * cmdline[i++] = "-l";
+         */
 
         if (!root_directory)
                 cmdline[i++] = "-M";
@@ -324,15 +353,12 @@ int main(int argc, char *argv[]) {
         } else if (pid == 0) {
                 /* Child */
                 if (progress_pipe[0] >= 0)
-                        close_nointr_nofail(progress_pipe[0]);
+                        safe_close(progress_pipe[0]);
                 execv(cmdline[0], (char**) cmdline);
                 _exit(8); /* Operational error */
         }
 
-        if (progress_pipe[1] >= 0) {
-                close_nointr_nofail(progress_pipe[1]);
-                progress_pipe[1] = -1;
-        }
+        progress_pipe[1] = safe_close(progress_pipe[1]);
 
         if (progress_pipe[0] >= 0) {
                 process_progress(progress_pipe[0]);
@@ -372,7 +398,7 @@ int main(int argc, char *argv[]) {
                 touch("/run/systemd/quotacheck");
 
 finish:
-        close_pipe(progress_pipe);
+        safe_close_pair(progress_pipe);
 
         return r;
 }
index a8824df..1725f29 100644 (file)
 #include "special.h"
 #include "mkdir.h"
 #include "fileio.h"
+#include "generator.h"
+#include "strv.h"
+#include "virt.h"
 
 static const char *arg_dest = "/tmp";
-static bool arg_enabled = true;
+static bool arg_fstab_enabled = true;
+static char *arg_root_what = NULL;
+static char *arg_root_fstype = NULL;
+static char *arg_root_options = NULL;
+static int arg_root_rw = -1;
+
 
 #ifdef CONFIG_TIZEN_WIP
 #define COMMENT_HASFS  "comment=havefs-"
@@ -120,6 +128,11 @@ static int add_swap(const char *what, struct mntent *me) {
         assert(what);
         assert(me);
 
+        if (detect_container(NULL) > 0) {
+                log_info("Running in a container, ignoring fstab swap entry for %s.", what);
+                return 0;
+        }
+
         r = mount_find_pri(me, &pri);
         if (r < 0) {
                 log_error("Failed to parse priority");
@@ -148,7 +161,8 @@ static int add_swap(const char *what, struct mntent *me) {
         fprintf(f,
                 "# Automatically generated by systemd-fstab-generator\n\n"
                 "[Unit]\n"
-                "SourcePath=/etc/fstab\n\n"
+                "SourcePath=/etc/fstab\n"
+                "Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n\n"
                 "[Swap]\n"
                 "What=%s\n",
                 what);
@@ -164,6 +178,11 @@ static int add_swap(const char *what, struct mntent *me) {
                 return -errno;
         }
 
+        /* use what as where, to have a nicer error message */
+        r = generator_write_timeouts(arg_dest, what, what, me->mnt_opts, NULL);
+        if (r < 0)
+                return r;
+
         if (!noauto) {
                 lnk = strjoin(arg_dest, "/" SPECIAL_SWAP_TARGET ".wants/", name, NULL);
                 if (!lnk)
@@ -195,61 +214,10 @@ static bool mount_in_initrd(struct mntent *me) {
                 streq(me->mnt_dir, "/usr");
 }
 
-static int add_fsck(FILE *f, const char *what, const char *where, const char *type, int passno) {
-        assert(f);
-
-        if (passno == 0)
-                return 0;
-
-        if (!is_device_path(what)) {
-                log_warning("Checking was requested for \"%s\", but it is not a device.", what);
-                return 0;
-        }
-
-        if (type && !streq(type, "auto")) {
-                int r;
-                const char *checker;
-
-                checker = strappenda("/sbin/fsck.", type);
-                r = access(checker, X_OK);
-                if (r < 0) {
-                        log_warning("Checking was requested for %s, but %s cannot be used: %m", what, checker);
-
-                        /* treat missing check as essentially OK */
-                        return errno == ENOENT ? 0 : -errno;
-                }
-        }
-
-        if (streq(where, "/")) {
-                char *lnk;
-
-                lnk = strappenda(arg_dest, "/" SPECIAL_LOCAL_FS_TARGET ".wants/systemd-fsck-root.service");
-                mkdir_parents_label(lnk, 0755);
-                if (symlink(SYSTEM_DATA_UNIT_PATH "/systemd-fsck-root.service", lnk) < 0) {
-                        log_error("Failed to create symlink %s: %m", lnk);
-                        return -errno;
-                }
-        } else {
-                _cleanup_free_ char *fsck = NULL;
-
-                fsck = unit_name_from_path_instance("systemd-fsck", what, ".service");
-                if (!fsck)
-                        return log_oom();
-
-                fprintf(f,
-                        "RequiresOverridable=%s\n"
-                        "After=%s\n",
-                        fsck,
-                        fsck);
-        }
-
-        return 0;
-}
-
 static int add_mount(
                 const char *what,
                 const char *where,
-                const char *type,
+                const char *fstype,
                 const char *opts,
                 int passno,
                 bool noauto,
@@ -257,19 +225,20 @@ static int add_mount(
                 bool automount,
                 const char *post,
                 const char *source) {
+
         _cleanup_free_ char
                 *name = NULL, *unit = NULL, *lnk = NULL,
-                *automount_name = NULL, *automount_unit = NULL;
+                *automount_name = NULL, *automount_unit = NULL,
+                *filtered = NULL;
         _cleanup_fclose_ FILE *f = NULL;
         int r;
 
         assert(what);
         assert(where);
-        assert(type);
         assert(opts);
         assert(source);
 
-        if (streq(type, "autofs"))
+        if (streq_ptr(fstype, "autofs"))
                 return 0;
 
         if (!is_path(where)) {
@@ -281,6 +250,13 @@ static int add_mount(
             mount_point_ignore(where))
                 return 0;
 
+        if (path_equal(where, "/")) {
+                /* The root disk is not an option */
+                automount = false;
+                noauto = false;
+                nofail = false;
+        }
+
         name = unit_name_from_path(where, ".mount");
         if (!name)
                 return log_oom();
@@ -299,35 +275,38 @@ static int add_mount(
         }
 
         fprintf(f,
-              "# Automatically generated by systemd-fstab-generator\n\n"
-              "[Unit]\n"
-              "SourcePath=%s\n",
-              source);
+                "# Automatically generated by systemd-fstab-generator\n\n"
+                "[Unit]\n"
+                "SourcePath=%s\n"
+                "Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n",
+                source);
 
         if (post && !noauto && !nofail && !automount)
-                fprintf(f,
-                        "Before=%s\n",
-                        post);
+                fprintf(f, "Before=%s\n", post);
 
-        r = add_fsck(f, what, where, type, passno);
-        if (r < 0)
-                return r;
+        if (passno != 0) {
+                r = generator_write_fsck_deps(f, arg_dest, what, where, fstype);
+                if (r < 0)
+                        return r;
+        }
 
         fprintf(f,
                 "\n"
                 "[Mount]\n"
                 "What=%s\n"
-                "Where=%s\n"
-                "Type=%s\n",
+                "Where=%s\n",
                 what,
-                where,
-                type);
+                where);
 
-        if (!isempty(opts) &&
-            !streq(opts, "defaults"))
-                fprintf(f,
-                        "Options=%s\n",
-                        opts);
+        if (!isempty(fstype) && !streq(fstype, "auto"))
+                fprintf(f, "Type=%s\n", fstype);
+
+        r = generator_write_timeouts(arg_dest, what, where, opts, &filtered);
+        if (r < 0)
+                return r;
+
+        if (!isempty(filtered) && !streq(filtered, "defaults"))
+                fprintf(f, "Options=%s\n", filtered);
 
         fflush(f);
         if (ferror(f)) {
@@ -335,21 +314,19 @@ static int add_mount(
                 return -errno;
         }
 
-        if (!noauto) {
-                if (post) {
-                        lnk = strjoin(arg_dest, "/", post, nofail || automount ? ".wants/" : ".requires/", name, NULL);
-                        if (!lnk)
-                                return log_oom();
-
-                        mkdir_parents_label(lnk, 0755);
-                        if (symlink(unit, lnk) < 0) {
-                                log_error("Failed to create symlink %s: %m", lnk);
-                                return -errno;
-                        }
+        if (!noauto && post) {
+                lnk = strjoin(arg_dest, "/", post, nofail || automount ? ".wants/" : ".requires/", name, NULL);
+                if (!lnk)
+                        return log_oom();
+
+                mkdir_parents_label(lnk, 0755);
+                if (symlink(unit, lnk) < 0) {
+                        log_error("Failed to create symlink %s: %m", lnk);
+                        return -errno;
                 }
         }
 
-        if (automount && !path_equal(where, "/")) {
+        if (automount) {
                 automount_name = unit_name_from_path(where, ".automount");
                 if (!automount_name)
                         return log_oom();
@@ -368,12 +345,13 @@ static int add_mount(
                 fprintf(f,
                         "# Automatically generated by systemd-fstab-generator\n\n"
                         "[Unit]\n"
-                        "SourcePath=%s\n",
+                        "SourcePath=%s\n"
+                        "Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n",
                         source);
 
                 if (post)
                         fprintf(f,
-                                "Before= %s\n",
+                                "Before=%s\n",
                                 post);
 
                 fprintf(f,
@@ -402,19 +380,19 @@ static int add_mount(
         return 0;
 }
 
-static int parse_fstab(const char *prefix, bool initrd) {
-        char *fstab_path;
-        _cleanup_endmntent_ FILE *f;
-        int r = 0;
+static int parse_fstab(bool initrd) {
+        _cleanup_endmntent_ FILE *f = NULL;
+        const char *fstab_path;
         struct mntent *me;
+        int r = 0;
 
-        fstab_path = strappenda(strempty(prefix), "/etc/fstab");
-        f = setmntent(fstab_path, "r");
+        fstab_path = initrd ? "/sysroot/etc/fstab" : "/etc/fstab";
+        f = setmntent(fstab_path, "re");
         if (!f) {
                 if (errno == ENOENT)
                         return 0;
 
-                log_error("Failed to open %s/etc/fstab: %m", strempty(prefix));
+                log_error("Failed to open %s: %m", fstab_path);
                 return -errno;
         }
 
@@ -426,8 +404,16 @@ static int parse_fstab(const char *prefix, bool initrd) {
                         continue;
 
                 what = fstab_node_to_udev_node(me->mnt_fsname);
-                where = strjoin(strempty(prefix), me->mnt_dir, NULL);
-                if (!what || !where)
+                if (!what)
+                        return log_oom();
+
+                if (detect_container(NULL) > 0 && is_device_path(what)) {
+                        log_info("Running in a container, ignoring fstab device entry for %s.", what);
+                        continue;
+                }
+
+                where = initrd ? strappend("/sysroot/", me->mnt_dir) : strdup(me->mnt_dir);
+                if (!where)
                         return log_oom();
 
                 if (is_path(where))
@@ -483,25 +469,29 @@ static int parse_fstab(const char *prefix, bool initrd) {
                                 opts = strdup("");
 #endif
 
-                        if (initrd) {
+                        if (initrd)
                                 post = SPECIAL_INITRD_FS_TARGET;
-                        } else if (mount_in_initrd(me)) {
+                        else if (mount_in_initrd(me))
                                 post = SPECIAL_INITRD_ROOT_FS_TARGET;
-                        } else if (mount_is_network(me)) {
+                        else if (mount_is_network(me))
                                 post = SPECIAL_REMOTE_FS_TARGET;
-                        } else {
+                        else
                                 post = SPECIAL_LOCAL_FS_TARGET;
-                        }
 
+                        k = add_mount(what,
+                                      where,
+                                      me->mnt_type,
 #ifdef CONFIG_TIZEN_WIP
-                        k = add_mount(what, where, me->mnt_type, opts,
-                                      me->mnt_passno, noauto, nofail, automount,
-                                      post, fstab_path);
+                                      opts,
 #else
-                        k = add_mount(what, where, me->mnt_type, me->mnt_opts,
-                                      me->mnt_passno, noauto, nofail, automount,
-                                      post, fstab_path);
+                                      me->mnt_opts,
 #endif
+                                      me->mnt_passno,
+                                      noauto,
+                                      nofail,
+                                      automount,
+                                      post,
+                                      fstab_path);
                 }
 
                 if (k < 0)
@@ -511,118 +501,94 @@ static int parse_fstab(const char *prefix, bool initrd) {
         return r;
 }
 
-static int parse_new_root_from_proc_cmdline(void) {
-        _cleanup_free_ char *what = NULL, *type = NULL, *opts = NULL, *line = NULL;
-        bool noauto, nofail;
-        char *w, *state;
-        size_t l;
-        int r;
-
-        r = proc_cmdline(&line);
-        if (r < 0)
-                log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
-        if (r <= 0)
-                return 0;
-
-        opts = strdup("ro");
-        type = strdup("auto");
-        if (!opts || !type)
-                return log_oom();
-
-        /* root= and roofstype= may occur more than once, the last instance should take precedence.
-         * In the case of multiple rootflags= the arguments should be concatenated */
-        FOREACH_WORD_QUOTED(w, l, line, state) {
-                _cleanup_free_ char *word;
-
-                word = strndup(w, l);
-                if (!word)
-                        return log_oom();
-
-                else if (startswith(word, "root=")) {
-                        free(what);
-                        what = fstab_node_to_udev_node(word+5);
-                        if (!what)
-                                return log_oom();
-
-                } else if (startswith(word, "rootfstype=")) {
-                        free(type);
-                        type = strdup(word + 11);
-                        if (!type)
-                                return log_oom();
-
-                } else if (startswith(word, "rootflags=")) {
-                        char *o;
-
-                        o = strjoin(opts, ",", word + 10, NULL);
-                        if (!o)
-                                return log_oom();
-
-                        free(opts);
-                        opts = o;
-
-                } else if (streq(word, "ro") || streq(word, "rw")) {
-                        char *o;
-
-                        o = strjoin(opts, ",", word, NULL);
-                        if (!o)
-                                return log_oom();
-
-                        free(opts);
-                        opts = o;
-                }
-        }
-
-        noauto = !!strstr(opts, "noauto");
-        nofail = !!strstr(opts, "nofail");
+static int add_root_mount(void) {
+        _cleanup_free_ char *what = NULL;
+        const char *opts;
 
-        if (!what) {
+        if (isempty(arg_root_what)) {
                 log_debug("Could not find a root= entry on the kernel commandline.");
                 return 0;
         }
 
-        if (what[0] != '/') {
-                log_debug("Skipping entry what=%s where=/sysroot type=%s", what, type);
+        what = fstab_node_to_udev_node(arg_root_what);
+        if (!path_is_absolute(what)) {
+                log_debug("Skipping entry what=%s where=/sysroot type=%s", what, strna(arg_root_fstype));
                 return 0;
         }
 
-        log_debug("Found entry what=%s where=/sysroot type=%s", what, type);
-        r = add_mount(what, "/sysroot", type, opts, 1, noauto, nofail, false,
-                      SPECIAL_INITRD_ROOT_FS_TARGET, "/proc/cmdline");
-
-        return (r < 0) ? r : 0;
+        if (!arg_root_options)
+                opts = arg_root_rw > 0 ? "rw" : "ro";
+        else if (arg_root_rw >= 0 ||
+                 (!mount_test_option(arg_root_options, "ro") &&
+                  !mount_test_option(arg_root_options, "rw")))
+                opts = strappenda(arg_root_options, ",", arg_root_rw > 0 ? "rw" : "ro");
+        else
+                opts = arg_root_options;
+
+        log_debug("Found entry what=%s where=/sysroot type=%s", what, strna(arg_root_fstype));
+        return add_mount(what,
+                         "/sysroot",
+                         arg_root_fstype,
+                         opts,
+                         1,
+                         false,
+                         false,
+                         false,
+                         SPECIAL_INITRD_ROOT_FS_TARGET,
+                         "/proc/cmdline");
 }
 
-static int parse_proc_cmdline_word(const char *word) {
+static int parse_proc_cmdline_item(const char *key, const char *value) {
         int r;
 
-        if (startswith(word, "fstab=")) {
-                r = parse_boolean(word + 6);
+        /* root= and roofstype= may occur more than once, the last
+         * instance should take precedence.  In the case of multiple
+         * rootflags= the arguments should be concatenated */
+
+        if (STR_IN_SET(key, "fstab", "rd.fstab") && value) {
+
+                r = parse_boolean(value);
                 if (r < 0)
-                        log_warning("Failed to parse fstab switch %s. Ignoring.", word + 6);
+                        log_warning("Failed to parse fstab switch %s. Ignoring.", value);
                 else
-                        arg_enabled = r;
+                        arg_fstab_enabled = r;
 
-        } else if (startswith(word, "rd.fstab=")) {
+        } else if (streq(key, "root") && value) {
 
-                if (in_initrd()) {
-                        r = parse_boolean(word + 9);
-                        if (r < 0)
-                                log_warning("Failed to parse fstab switch %s. Ignoring.", word + 9);
-                        else
-                                arg_enabled = r;
-                }
+                free(arg_root_what);
+                arg_root_what = strdup(value);
+                if (!arg_root_what)
+                        return log_oom();
 
-        } else if (startswith(word, "fstab.") ||
-                   (in_initrd() && startswith(word, "rd.fstab."))) {
+        } else if (streq(key, "rootfstype") && value) {
 
-                log_warning("Unknown kernel switch %s. Ignoring.", word);
-        }
+                free(arg_root_fstype);
+                arg_root_fstype = strdup(value);
+                if (!arg_root_fstype)
+                        return log_oom();
+
+        } else if (streq(key, "rootflags") && value) {
+                char *o;
+
+                o = arg_root_options ?
+                        strjoin(arg_root_options, ",", value, NULL) :
+                        strdup(value);
+                if (!o)
+                        return log_oom();
+
+                free(arg_root_options);
+                arg_root_options = o;
+
+        } else if (streq(key, "rw") && !value)
+                arg_root_rw = true;
+        else if (streq(key, "ro") && !value)
+                arg_root_rw = false;
 
         return 0;
 }
 
 int main(int argc, char *argv[]) {
-        int r = 0, k, l = 0;
+        int r = 0;
 
         if (argc > 1 && argc != 4) {
                 log_error("This program takes three or no arguments.");
@@ -638,19 +604,35 @@ int main(int argc, char *argv[]) {
 
         umask(0022);
 
-        if (parse_proc_cmdline(parse_proc_cmdline_word) < 0)
+        if (parse_proc_cmdline(parse_proc_cmdline_item) < 0)
                 return EXIT_FAILURE;
 
+        /* Always honour root= in the kernel command line if we are in an initrd */
         if (in_initrd())
-                r = parse_new_root_from_proc_cmdline();
+                r = add_root_mount();
 
-        if (!arg_enabled)
-                return (r < 0) ? EXIT_FAILURE : EXIT_SUCCESS;
+        /* Honour /etc/fstab only when that's enabled */
+        if (arg_fstab_enabled) {
+                int k;
 
-        k = parse_fstab(NULL, false);
+                log_debug("Parsing /etc/fstab");
 
-        if (in_initrd())
-                l = parse_fstab("/sysroot", true);
+                /* Parse the local /etc/fstab, possibly from the initrd */
+                k = parse_fstab(false);
+                if (k < 0)
+                        r = k;
+
+                /* If running in the initrd also parse the /etc/fstab from the host */
+                if (in_initrd()) {
+                        log_debug("Parsing /sysroot/etc/fstab");
+
+                        k = parse_fstab(true);
+                        if (k < 0)
+                                r = k;
+                }
+        }
+
+        free(arg_root_what);
 
-        return (r < 0) || (k < 0) || (l < 0) ? EXIT_FAILURE : EXIT_SUCCESS;
+        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
 }
index 08b3b1e..06ca9b9 100644 (file)
 static const char *arg_dest = "/tmp";
 
 static int add_symlink(const char *fservice, const char *tservice) {
-        _cleanup_free_ char *from = NULL, *to = NULL;
+        char *from, *to;
         int r;
 
         assert(fservice);
         assert(tservice);
 
-        from = strappend(SYSTEM_DATA_UNIT_PATH "/", fservice);
-        if (!from)
-                return log_oom();
-
-        to = strjoin(arg_dest,"/getty.target.wants/", tservice, NULL);
-        if (!to)
-                return log_oom();
+        from = strappenda(SYSTEM_DATA_UNIT_PATH "/", fservice);
+        to = strappenda(arg_dest, "/getty.target.wants/", tservice);
 
         mkdir_parents_label(to, 0755);
 
@@ -72,7 +67,7 @@ static int add_serial_getty(const char *tty) {
 
         log_debug("Automatically adding serial getty for /dev/%s.", tty);
 
-        n = unit_name_replace_instance("serial-getty@.service", tty);
+        n = unit_name_from_path_instance("serial-getty", tty, ".service");
         if (!n)
                 return log_oom();
 
@@ -86,7 +81,7 @@ static int add_container_getty(const char *tty) {
 
         log_debug("Automatically adding container getty for /dev/pts/%s.", tty);
 
-        n = unit_name_replace_instance("container-getty@.service", tty);
+        n = unit_name_from_path_instance("container-getty", tty, ".service");
         if (!n)
                 return log_oom();
 
@@ -124,7 +119,8 @@ int main(int argc, char *argv[]) {
                 "xvc0\0"
                 "hvsi0\0"
                 "sclp_line0\0"
-                "ttysclp0\0";
+                "ttysclp0\0"
+                "3270!tty1\0";
 
         _cleanup_free_ char *active = NULL;
         const char *j;
@@ -158,14 +154,14 @@ int main(int argc, char *argv[]) {
 
                 r = getenv_for_pid(1, "container_ttys", &container_ttys);
                 if (r > 0) {
-                        char *w, *state;
+                        const char *word, *state;
                         size_t l;
 
-                        FOREACH_WORD(w, l, container_ttys, state) {
+                        FOREACH_WORD(word, l, container_ttys, state) {
                                 const char *t;
                                 char tty[l + 1];
 
-                                memcpy(tty, w, l);
+                                memcpy(tty, word, l);
                                 tty[l] = 0;
 
                                 /* First strip off /dev/ if it is specified */
@@ -188,15 +184,15 @@ int main(int argc, char *argv[]) {
         }
 
         if (read_one_line_file("/sys/class/tty/console/active", &active) >= 0) {
-                char *w, *state;
+                const char *word, *state;
                 size_t l;
 
                 /* Automatically add in a serial getty on all active
                  * kernel consoles */
-                FOREACH_WORD(w, l, active, state) {
+                FOREACH_WORD(word, l, active, state) {
                         _cleanup_free_ char *tty = NULL;
 
-                        tty = strndup(w, l);
+                        tty = strndup(word, l);
                         if (!tty) {
                                 log_oom();
                                 return EXIT_FAILURE;
@@ -220,14 +216,9 @@ int main(int argc, char *argv[]) {
         /* Automatically add in a serial getty on the first
          * virtualizer console */
         NULSTR_FOREACH(j, virtualization_consoles) {
-                _cleanup_free_ char *p = NULL;
-
-                p = strappend("/sys/class/tty/", j);
-                if (!p) {
-                        log_oom();
-                        return EXIT_FAILURE;
-                }
+                char *p;
 
+                p = strappenda("/sys/class/tty/", j);
                 if (access(p, F_OK) < 0)
                         continue;
 
index 05934da..7dcbbfe 100644 (file)
 #include <linux/btrfs.h>
 #endif
 
+#include "sd-id128.h"
+#include "libudev.h"
 #include "path-util.h"
 #include "util.h"
 #include "mkdir.h"
 #include "missing.h"
-#include "sd-id128.h"
-#include "libudev.h"
 #include "udev-util.h"
 #include "special.h"
 #include "unit-name.h"
 #include "virt.h"
-
-/* TODO:
- *
- * - Properly handle cryptsetup partitions
- * - Define new partition type for encrypted swap
- * - Make /home automount rather than mount
- *
- */
-
-#define GPT_SWAP SD_ID128_MAKE(06,57,fd,6d,a4,ab,43,c4,84,e5,09,33,c8,4b,4f,4f)
-#define GPT_HOME SD_ID128_MAKE(93,3a,c7,e1,2e,b4,4f,13,b8,44,0e,14,e2,ae,f9,15)
+#include "generator.h"
+#include "gpt.h"
+#include "fileio.h"
+#include "efivars.h"
+#include "blkid-util.h"
 
 static const char *arg_dest = "/tmp";
+static bool arg_enabled = true;
+static bool arg_root_enabled = true;
+static bool arg_root_rw = false;
 
-DEFINE_TRIVIAL_CLEANUP_FUNC(blkid_probe, blkid_free_probe);
-#define _cleanup_blkid_freep_probe_ _cleanup_(blkid_free_probep)
-
-static int verify_gpt_partition(const char *node, sd_id128_t *type, unsigned *nr, char **fstype) {
-        _cleanup_blkid_freep_probe_ blkid_probe b = NULL;
-        const char *v;
-        int r;
-
-        errno = 0;
-        b = blkid_new_probe_from_filename(node);
-        if (!b)
-                return errno != 0 ? -errno : -ENOMEM;
-
-        blkid_probe_enable_superblocks(b, 1);
-        blkid_probe_set_superblocks_flags(b, BLKID_SUBLKS_TYPE);
-        blkid_probe_enable_partitions(b, 1);
-        blkid_probe_set_partitions_flags(b, BLKID_PARTS_ENTRY_DETAILS);
-
-        errno = 0;
-        r = blkid_do_safeprobe(b);
-        if (r == -2 || r == 1) /* no result or uncertain */
-                return -EBADSLT;
-        else if (r != 0)
-                return errno ? -errno : -EIO;
-
-        errno = 0;
-        r = blkid_probe_lookup_value(b, "PART_ENTRY_SCHEME", &v, NULL);
-        if (r != 0)
-                /* return 0 if we're not on GPT */
-                return errno ? -errno : 0;
-
-        if (strcmp(v, "gpt") != 0)
-                return 0;
-
-        if (type) {
-                errno = 0;
-                r = blkid_probe_lookup_value(b, "PART_ENTRY_TYPE", &v, NULL);
-                if (r != 0)
-                        return errno ? -errno : -EIO;
-
-                r = sd_id128_from_string(v, type);
-                if (r < 0)
-                        return r;
-        }
-
-        if (nr) {
-                errno = 0;
-                r = blkid_probe_lookup_value(b, "PART_ENTRY_NUMBER", &v, NULL);
-                if (r != 0)
-                        return errno ? -errno : -EIO;
-
-                r = safe_atou(v, nr);
-                if (r < 0)
-                        return r;
-        }
-
-
-        if (fstype) {
-                errno = 0;
-                r = blkid_probe_lookup_value(b, "TYPE", &v, NULL);
-                if (r != 0)
-                        *fstype = NULL;
-                else {
-                        char *fst;
-
-                        fst = strdup(v);
-                        if (!fst)
-                                return -ENOMEM;
-
-                        *fstype = fst;
-                }
-        }
-
-        return 1;
-}
-
-static int add_swap(const char *path, const char *fstype) {
+static int add_swap(const char *path) {
         _cleanup_free_ char *name = NULL, *unit = NULL, *lnk = NULL;
         _cleanup_fclose_ FILE *f = NULL;
 
-        log_debug("Adding swap: %s %s", path, fstype);
+        assert(path);
+
+        log_debug("Adding swap: %s", path);
 
         name = unit_name_from_path(path, ".swap");
         if (!name)
@@ -153,9 +76,8 @@ static int add_swap(const char *path, const char *fstype) {
         fprintf(f,
                 "# Automatically generated by systemd-gpt-auto-generator\n\n"
                 "[Unit]\n"
-                "DefaultDependencies=no\n"
-                "Conflicts=" SPECIAL_UMOUNT_TARGET "\n"
-                "Before=" SPECIAL_UMOUNT_TARGET " " SPECIAL_SWAP_TARGET "\n\n"
+                "Description=Swap Partition\n"
+                "Documentation=man:systemd-gpt-auto-generator(8)\n\n"
                 "[Swap]\n"
                 "What=%s\n",
                 path);
@@ -179,81 +101,382 @@ static int add_swap(const char *path, const char *fstype) {
         return 0;
 }
 
-static int add_home(const char *path, const char *fstype) {
-        _cleanup_free_ char *unit = NULL, *lnk = NULL, *fsck = NULL;
+static int add_cryptsetup(const char *id, const char *what, bool rw, char **device) {
+        _cleanup_free_ char *e = NULL, *n = NULL, *p = NULL, *d = NULL, *to = NULL;
         _cleanup_fclose_ FILE *f = NULL;
+        char *from, *ret;
+        int r;
 
-        if (dir_is_empty("/home") <= 0)
-                return 0;
+        assert(id);
+        assert(what);
+        assert(device);
 
-        log_debug("Adding home: %s %s", path, fstype);
+        d = unit_name_from_path(what, ".device");
+        if (!d)
+                return log_oom();
 
-        unit = strappend(arg_dest, "/home.mount");
-        if (!unit)
+        e = unit_name_escape(id);
+        if (!e)
                 return log_oom();
 
-        f = fopen(unit, "wxe");
+        n = unit_name_build("systemd-cryptsetup", e, ".service");
+        if (!n)
+                return log_oom();
+
+        p = strjoin(arg_dest, "/", n, NULL);
+        if (!n)
+                return log_oom();
+
+        f = fopen(p, "wxe");
         if (!f) {
-                log_error("Failed to create unit file %s: %m", unit);
+                log_error("Failed to create unit file %s: %m", p);
+                return -errno;
+        }
+
+        fprintf(f,
+                "# Automatically generated by systemd-gpt-auto-generator\n\n"
+                "[Unit]\n"
+                "Description=Cryptography Setup for %%I\n"
+                "Documentation=man:systemd-gpt-auto-generator(8) man:systemd-cryptsetup@.service(8)\n"
+                "DefaultDependencies=no\n"
+                "Conflicts=umount.target\n"
+                "BindsTo=dev-mapper-%%i.device %s\n"
+                "Before=umount.target cryptsetup.target\n"
+                "After=%s\n"
+                "IgnoreOnIsolate=true\n"
+                "After=systemd-readahead-collect.service systemd-readahead-replay.service\n\n"
+                "[Service]\n"
+                "Type=oneshot\n"
+                "RemainAfterExit=yes\n"
+                "TimeoutSec=0\n" /* the binary handles timeouts anyway */
+                "ExecStart=" SYSTEMD_CRYPTSETUP_PATH " attach '%s' '%s' '' '%s'\n"
+                "ExecStop=" SYSTEMD_CRYPTSETUP_PATH " detach '%s'\n",
+                d, d,
+                id, what, rw ? "" : "read-only",
+                id);
+
+        fflush(f);
+        if (ferror(f)) {
+                log_error("Failed to write file %s: %m", p);
+                return -errno;
+        }
+
+        from = strappenda("../", n);
+
+        to = strjoin(arg_dest, "/", d, ".wants/", n, NULL);
+        if (!to)
+                return log_oom();
+
+        mkdir_parents_label(to, 0755);
+        if (symlink(from, to) < 0) {
+                log_error("Failed to create symlink %s: %m", to);
                 return -errno;
         }
 
-        fsck = unit_name_from_path_instance("systemd-fsck", path, ".service");
-        if (!fsck)
+        free(to);
+        to = strjoin(arg_dest, "/cryptsetup.target.requires/", n, NULL);
+        if (!to)
                 return log_oom();
 
+        mkdir_parents_label(to, 0755);
+        if (symlink(from, to) < 0) {
+                log_error("Failed to create symlink %s: %m", to);
+                return -errno;
+        }
+
+        free(to);
+        to = strjoin(arg_dest, "/dev-mapper-", e, ".device.requires/", n, NULL);
+        if (!to)
+                return log_oom();
+
+        mkdir_parents_label(to, 0755);
+        if (symlink(from, to) < 0) {
+                log_error("Failed to create symlink %s: %m", to);
+                return -errno;
+        }
+
+        free(p);
+        p = strjoin(arg_dest, "/dev-mapper-", e, ".device.d/50-job-timeout-sec-0.conf", NULL);
+        if (!p)
+                return log_oom();
+
+        mkdir_parents_label(p, 0755);
+        r = write_string_file(p,
+                        "# Automatically generated by systemd-gpt-auto-generator\n\n"
+                        "[Unit]\n"
+                        "JobTimeoutSec=0\n"); /* the binary handles timeouts anyway */
+        if (r < 0) {
+                log_error("Failed to write device drop-in: %s", strerror(-r));
+                return r;
+        }
+
+        ret = strappend("/dev/mapper/", id);
+        if (!ret)
+                return log_oom();
+
+        *device = ret;
+        return 0;
+}
+
+static int add_mount(
+                const char *id,
+                const char *what,
+                const char *where,
+                const char *fstype,
+                bool rw,
+                const char *description,
+                const char *post) {
+
+        _cleanup_free_ char *unit = NULL, *lnk = NULL, *crypto_what = NULL, *p = NULL;
+        _cleanup_fclose_ FILE *f = NULL;
+        int r;
+
+        assert(id);
+        assert(what);
+        assert(where);
+        assert(description);
+
+        log_debug("Adding %s: %s %s", where, what, strna(fstype));
+
+        if (streq_ptr(fstype, "crypto_LUKS")) {
+
+                r = add_cryptsetup(id, what, rw, &crypto_what);
+                if (r < 0)
+                        return r;
+
+                what = crypto_what;
+                fstype = NULL;
+        }
+
+        unit = unit_name_from_path(where, ".mount");
+        if (!unit)
+                return log_oom();
+
+        p = strjoin(arg_dest, "/", unit, NULL);
+        if (!p)
+                return log_oom();
+
+        f = fopen(p, "wxe");
+        if (!f) {
+                log_error("Failed to create unit file %s: %m", unit);
+                return -errno;
+        }
+
         fprintf(f,
                 "# Automatically generated by systemd-gpt-auto-generator\n\n"
                 "[Unit]\n"
-                "DefaultDependencies=no\n"
-                "Requires=%s\n"
-                "After=" SPECIAL_LOCAL_FS_PRE_TARGET " %s\n"
-                "Conflicts=" SPECIAL_UMOUNT_TARGET "\n"
-                "Before=" SPECIAL_UMOUNT_TARGET " " SPECIAL_LOCAL_FS_TARGET "\n\n"
+                "Description=%s\n"
+                "Documentation=man:systemd-gpt-auto-generator(8)\n",
+                description);
+
+        if (post)
+                fprintf(f, "Before=%s\n", post);
+
+        r = generator_write_fsck_deps(f, arg_dest, what, where, fstype);
+        if (r < 0)
+                return r;
+
+        fprintf(f,
+                "\n"
                 "[Mount]\n"
                 "What=%s\n"
-                "Where=/home\n"
-                "Type=%s\n",
-                fsck, fsck, path, fstype);
+                "Where=%s\n",
+                what, where);
+
+        if (fstype)
+                fprintf(f, "Type=%s\n", fstype);
+
+        fprintf(f, "Options=%s\n", rw ? "rw" : "ro");
 
         fflush(f);
         if (ferror(f)) {
-                log_error("Failed to write unit file %s: %m", unit);
+                log_error("Failed to write unit file %s: %m", p);
                 return -errno;
         }
 
-        lnk = strjoin(arg_dest, "/" SPECIAL_LOCAL_FS_TARGET ".requires/home.mount", NULL);
-        if (!lnk)
-                return log_oom();
+        if (post) {
+                lnk = strjoin(arg_dest, "/", post, ".requires/", unit, NULL);
+                if (!lnk)
+                        return log_oom();
 
-        mkdir_parents_label(lnk, 0755);
-        if (symlink(unit, lnk) < 0) {
-                log_error("Failed to create symlink %s: %m", lnk);
-                return -errno;
+                mkdir_parents_label(lnk, 0755);
+                if (symlink(p, lnk) < 0) {
+                        log_error("Failed to create symlink %s: %m", lnk);
+                        return -errno;
+                }
         }
 
         return 0;
 }
 
-static int enumerate_partitions(struct udev *udev, dev_t dev) {
-        struct udev_device *parent = NULL;
+static int probe_and_add_mount(
+                const char *id,
+                const char *what,
+                const char *where,
+                bool rw,
+                const char *description,
+                const char *post) {
+
+        _cleanup_blkid_free_probe_ blkid_probe b = NULL;
+        const char *fstype;
+        int r;
+
+        assert(id);
+        assert(what);
+        assert(where);
+        assert(description);
+
+        if (path_is_mount_point(where, true) <= 0 &&
+            dir_is_empty(where) <= 0) {
+                log_debug("%s already populated, ignoring.", where);
+                return 0;
+        }
+
+        /* Let's check the partition type here, so that we know
+         * whether to do LUKS magic. */
+
+        errno = 0;
+        b = blkid_new_probe_from_filename(what);
+        if (!b) {
+                if (errno == 0)
+                        return log_oom();
+                log_error("Failed to allocate prober: %m");
+                return -errno;
+        }
+
+        blkid_probe_enable_superblocks(b, 1);
+        blkid_probe_set_superblocks_flags(b, BLKID_SUBLKS_TYPE);
+
+        errno = 0;
+        r = blkid_do_safeprobe(b);
+        if (r == -2 || r == 1) /* no result or uncertain */
+                return 0;
+        else if (r != 0) {
+                if (errno == 0)
+                        errno = EIO;
+                log_error("Failed to probe %s: %m", what);
+                return -errno;
+        }
+
+        blkid_probe_lookup_value(b, "TYPE", &fstype, NULL);
+
+        return add_mount(
+                        id,
+                        what,
+                        where,
+                        fstype,
+                        rw,
+                        description,
+                        post);
+}
+
+static int enumerate_partitions(dev_t devnum) {
+
         _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
         _cleanup_udev_device_unref_ struct udev_device *d = NULL;
+        _cleanup_blkid_free_probe_ blkid_probe b = NULL;
+        _cleanup_udev_unref_ struct udev *udev = NULL;
+        _cleanup_free_ char *home = NULL, *srv = NULL;
         struct udev_list_entry *first, *item;
-        unsigned home_nr = (unsigned) -1;
-        _cleanup_free_ char *home = NULL, *home_fstype = NULL;
-        int r;
+        struct udev_device *parent = NULL;
+        const char *node, *pttype, *devtype;
+        int home_nr = -1, srv_nr = -1;
+        bool home_rw = true, srv_rw = true;
+        blkid_partlist pl;
+        int r, k;
+        dev_t pn;
 
-        e = udev_enumerate_new(udev);
-        if (!e)
+        udev = udev_new();
+        if (!udev)
                 return log_oom();
 
-        d = udev_device_new_from_devnum(udev, 'b', dev);
+        d = udev_device_new_from_devnum(udev, 'b', devnum);
         if (!d)
                 return log_oom();
 
         parent = udev_device_get_parent(d);
-        if (!parent)
+        if (!parent) {
+                log_debug("Not a partitioned device, ignoring.");
+                return 0;
+        }
+
+        /* Does it have a devtype? */
+        devtype = udev_device_get_devtype(parent);
+        if (!devtype) {
+                log_debug("Parent doesn't have a device type, ignoring.");
+                return 0;
+        }
+
+        /* Is this a disk or a partition? We only care for disks... */
+        if (!streq(devtype, "disk")) {
+                log_debug("Parent isn't a raw disk, ignoring.");
+                return 0;
+        }
+
+        /* Does it have a device node? */
+        node = udev_device_get_devnode(parent);
+        if (!node) {
+                log_debug("Parent device does not have device node, ignoring.");
+                return 0;
+        }
+
+        log_debug("Root device %s.", node);
+
+        pn = udev_device_get_devnum(parent);
+        if (major(pn) == 0)
+                return 0;
+
+        errno = 0;
+        b = blkid_new_probe_from_filename(node);
+        if (!b) {
+                if (errno == 0)
+                        return log_oom();
+
+                log_error("Failed allocate prober: %m");
+                return -errno;
+        }
+
+        blkid_probe_enable_partitions(b, 1);
+        blkid_probe_set_partitions_flags(b, BLKID_PARTS_ENTRY_DETAILS);
+
+        errno = 0;
+        r = blkid_do_safeprobe(b);
+        if (r == -2 || r == 1) /* no result or uncertain */
+                return 0;
+        else if (r != 0) {
+                if (errno == 0)
+                        errno = EIO;
+                log_error("Failed to probe %s: %m", node);
+                return -errno;
+        }
+
+        errno = 0;
+        r = blkid_probe_lookup_value(b, "PTTYPE", &pttype, NULL);
+        if (r != 0) {
+                if (errno == 0)
+                        errno = EIO;
+                log_error("Failed to determine partition table type of %s: %m", node);
+                return -errno;
+        }
+
+        /* We only do this all for GPT... */
+        if (!streq_ptr(pttype, "gpt")) {
+                log_debug("Not a GPT partition table, ignoring.");
+                return 0;
+        }
+
+        errno = 0;
+        pl = blkid_probe_get_partitions(b);
+        if (!pl) {
+                if (errno == 0)
+                        return log_oom();
+
+                log_error("Failed to list partitions of %s: %m", node);
+                return -errno;
+        }
+
+        e = udev_enumerate_new(udev);
+        if (!e)
                 return log_oom();
 
         r = udev_enumerate_add_match_parent(e, parent);
@@ -266,65 +489,112 @@ static int enumerate_partitions(struct udev *udev, dev_t dev) {
 
         r = udev_enumerate_scan_devices(e);
         if (r < 0) {
-                log_error("Failed to enumerate partitions on /dev/block/%u:%u: %s",
-                          major(dev), minor(dev), strerror(-r));
+                log_error("Failed to enumerate partitions on %s: %s", node, strerror(-r));
                 return r;
         }
 
         first = udev_enumerate_get_list_entry(e);
         udev_list_entry_foreach(item, first) {
-                _cleanup_free_ char *fstype = NULL;
-                const char *node = NULL;
                 _cleanup_udev_device_unref_ struct udev_device *q;
+                const char *stype, *subnode;
                 sd_id128_t type_id;
-                unsigned nr;
+                blkid_partition pp;
+                dev_t qn;
+                int nr;
+                unsigned long long flags;
 
                 q = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item));
                 if (!q)
-                        return log_oom();
+                        continue;
 
-                if (udev_device_get_devnum(q) == udev_device_get_devnum(d))
+                qn = udev_device_get_devnum(q);
+                if (major(qn) == 0)
                         continue;
 
-                if (udev_device_get_devnum(q) == udev_device_get_devnum(parent))
+                if (qn == devnum)
                         continue;
 
-                node = udev_device_get_devnode(q);
-                if (!node)
-                        return log_oom();
+                if (qn == pn)
+                        continue;
 
-                r = verify_gpt_partition(node, &type_id, &nr, &fstype);
-                if (r < 0) {
-                        /* skip child devices which are not detected properly */
-                        if (r == -EBADSLT)
-                                continue;
-                        log_error("Failed to verify GPT partition %s: %s",
-                                  node, strerror(-r));
-                        return r;
-                }
-                if (r == 0)
+                subnode = udev_device_get_devnode(q);
+                if (!subnode)
+                        continue;
+
+                pp = blkid_partlist_devno_to_partition(pl, qn);
+                if (!pp)
                         continue;
 
-                if (sd_id128_equal(type_id, GPT_SWAP))
-                        add_swap(node, fstype);
-                else if (sd_id128_equal(type_id, GPT_HOME)) {
-                        if (!home || nr < home_nr) {
-                                free(home);
-                                home = strdup(node);
-                                if (!home)
-                                        return log_oom();
+                flags = blkid_partition_get_flags(pp);
 
-                                home_nr = nr;
+                /* Ignore partitions that are not marked for automatic
+                 * mounting on discovery */
+                if (flags & GPT_FLAG_NO_AUTO)
+                        continue;
 
-                                free(home_fstype);
-                                home_fstype = fstype;
-                                fstype = NULL;
+                nr = blkid_partition_get_partno(pp);
+                if (nr < 0)
+                        continue;
+
+                stype = blkid_partition_get_type_string(pp);
+                if (!stype)
+                        continue;
+
+                if (sd_id128_from_string(stype, &type_id) < 0)
+                        continue;
+
+                if (sd_id128_equal(type_id, GPT_SWAP)) {
+
+                        if (flags & GPT_FLAG_READ_ONLY) {
+                                log_debug("%s marked as read-only swap partition, which is bogus, ignoring.", subnode);
+                                continue;
                         }
+
+                        k = add_swap(subnode);
+                        if (k < 0)
+                                r = k;
+
+                } else if (sd_id128_equal(type_id, GPT_HOME)) {
+
+                        /* We only care for the first /home partition */
+                        if (home && nr >= home_nr)
+                                continue;
+
+                        home_nr = nr;
+                        home_rw = !(flags & GPT_FLAG_READ_ONLY),
+
+                        free(home);
+                        home = strdup(subnode);
+                        if (!home)
+                                return log_oom();
+
+                } else if (sd_id128_equal(type_id, GPT_SRV)) {
+
+                        /* We only care for the first /srv partition */
+                        if (srv && nr >= srv_nr)
+                                continue;
+
+                        srv_nr = nr;
+                        srv_rw = !(flags & GPT_FLAG_READ_ONLY),
+
+                        free(srv);
+                        srv = strdup(node);
+                        if (!srv)
+                                return log_oom();
                 }
         }
 
-        if (home && home_fstype)
-                add_home(home, home_fstype);
+        if (home) {
+                k = probe_and_add_mount("home", home, "/home", home_rw, "Home Partition", SPECIAL_LOCAL_FS_TARGET);
+                if (k < 0)
+                        r = k;
+        }
+
+        if (srv) {
+                k = probe_and_add_mount("srv", srv, "/srv", srv_rw, "Server Data Partition", SPECIAL_LOCAL_FS_TARGET);
+                if (k < 0)
+                        r = k;
+        }
 
         return r;
 }
@@ -384,7 +654,7 @@ static int get_block_device(const char *path, dev_t *dev) {
         assert(path);
         assert(dev);
 
-        if (lstat("/", &st))
+        if (lstat(path, &st))
                 return -errno;
 
         if (major(st.st_dev) != 0) {
@@ -392,7 +662,7 @@ static int get_block_device(const char *path, dev_t *dev) {
                 return 1;
         }
 
-        if (statfs("/", &sfs) < 0)
+        if (statfs(path, &sfs) < 0)
                 return -errno;
 
         if (F_TYPE_EQUAL(sfs.f_type, BTRFS_SUPER_MAGIC))
@@ -401,37 +671,92 @@ static int get_block_device(const char *path, dev_t *dev) {
         return 0;
 }
 
-static int devno_to_devnode(struct udev *udev, dev_t devno, char **ret) {
-        _cleanup_udev_device_unref_ struct udev_device *d;
-        const char *t;
-        char *n;
+static int parse_proc_cmdline_item(const char *key, const char *value) {
+        int r;
 
-        d = udev_device_new_from_devnum(udev, 'b', devno);
-        if (!d)
-                return log_oom();
+        assert(key);
 
-        t = udev_device_get_devnode(d);
-        if (!t)
-                return -ENODEV;
+        if (STR_IN_SET(key, "systemd.gpt_auto", "rd.systemd.gpt_auto") && value) {
 
-        n = strdup(t);
-        if (!n)
-                return -ENOMEM;
+                r = parse_boolean(value);
+                if (r < 0)
+                        log_warning("Failed to parse gpt-auto switch %s. Ignoring.", value);
+
+                arg_enabled = r;
+
+        } else if (streq(key, "root") && value) {
+
+                /* Disable root disk logic if there's a root= value
+                 * specified (unless it happens to be "gpt-auto") */
+
+                arg_root_enabled = streq(value, "gpt-auto");
+
+        } else if (streq(key, "rw") && !value)
+                arg_root_rw = true;
+        else if (streq(key, "ro") && !value)
+                arg_root_rw = false;
 
-        *ret = n;
         return 0;
 }
 
-int main(int argc, char *argv[]) {
-        _cleanup_free_ char *node = NULL;
-        _cleanup_udev_unref_ struct udev *udev = NULL;
+static int add_root_mount(void) {
+
+#ifdef ENABLE_EFI
+        int r;
+
+        if (!is_efi_boot()) {
+                log_debug("Not a EFI boot, not creating root mount.");
+                return 0;
+        }
+
+        r = efi_loader_get_device_part_uuid(NULL);
+        if (r == -ENOENT) {
+                log_debug("EFI loader partition unknown, exiting.");
+                return 0;
+        } else if (r < 0) {
+                log_error("Failed to read ESP partition UUID: %s", strerror(-r));
+                return r;
+        }
+
+        /* OK, we have an ESP partition, this is fantastic, so let's
+         * wait for a root device to show up. A udev rule will create
+         * the link for us under the right name. */
+
+        return add_mount(
+                        "root",
+                        "/dev/gpt-auto-root",
+                        in_initrd() ? "/sysroot" : "/",
+                        NULL,
+                        arg_root_rw,
+                        "Root Partition",
+                        in_initrd() ? SPECIAL_INITRD_ROOT_FS_TARGET : SPECIAL_LOCAL_FS_TARGET);
+#else
+        return 0;
+#endif
+}
+
+static int add_mounts(void) {
         dev_t devno;
+        int r;
+
+        r = get_block_device("/", &devno);
+        if (r < 0) {
+                log_error("Failed to determine block device of root file system: %s", strerror(-r));
+                return r;
+        } else if (r == 0) {
+                log_debug("Root file system not on a (single) block device.");
+                return 0;
+        }
+
+        return enumerate_partitions(devno);
+}
+
+int main(int argc, char *argv[]) {
         int r = 0;
 
         if (argc > 1 && argc != 4) {
                 log_error("This program takes three or no arguments.");
-                r = -EINVAL;
-                goto finish;
+                return EXIT_FAILURE;
         }
 
         if (argc > 1)
@@ -443,50 +768,29 @@ int main(int argc, char *argv[]) {
 
         umask(0022);
 
-        if (in_initrd()) {
-                log_debug("In initrd, exiting.");
-                goto finish;
-        }
-
         if (detect_container(NULL) > 0) {
                 log_debug("In a container, exiting.");
-                goto finish;
+                return EXIT_SUCCESS;
         }
 
-        r = get_block_device("/", &devno);
-        if (r < 0) {
-                log_error("Failed to determine block device of root file system: %s", strerror(-r));
-                goto finish;
-        }
-        if (r == 0) {
-                log_debug("Root file system not on a (single) block device.");
-                goto finish;
-        }
+        if (parse_proc_cmdline(parse_proc_cmdline_item) < 0)
+                return EXIT_FAILURE;
 
-        udev = udev_new();
-        if (!udev) {
-                r = log_oom();
-                goto finish;
+        if (!arg_enabled) {
+                log_debug("Disabled, exiting.");
+                return EXIT_SUCCESS;
         }
 
-        r = devno_to_devnode(udev, devno, &node);
-        if (r < 0) {
-                log_error("Failed to determine block device node from major/minor: %s", strerror(-r));
-                goto finish;
-        }
+        if (arg_root_enabled)
+                r = add_root_mount();
 
-        log_debug("Root device %s.", node);
+        if (!in_initrd()) {
+                int k;
 
-        r = verify_gpt_partition(node, NULL, NULL, NULL);
-        if (r < 0) {
-                log_error("Failed to verify GPT partition %s: %s", node, strerror(-r));
-                goto finish;
+                k = add_mounts();
+                if (k < 0)
+                        r = k;
         }
-        if (r == 0)
-                goto finish;
-
-        r = enumerate_partitions(udev, devno);
 
-finish:
         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
 }
index a151b50..1eec758 100644 (file)
@@ -338,7 +338,10 @@ g_udev_client_new (const gchar * const *subsystems)
  *
  * Gets all devices belonging to @subsystem.
  *
- * Returns: (element-type GUdevDevice) (transfer full): A list of #GUdevDevice objects. The caller should free the result by using g_object_unref() on each element in the list and then g_list_free() on the list.
+ * Returns: (nullable) (element-type GUdevDevice) (transfer full): A
+ * list of #GUdevDevice objects. The caller should free the result by
+ * using g_object_unref() on each element in the list and then
+ * g_list_free() on the list.
  */
 GList *
 g_udev_client_query_by_subsystem (GUdevClient  *client,
@@ -391,7 +394,8 @@ g_udev_client_query_by_subsystem (GUdevClient  *client,
  *
  * Looks up a device for a type and device number.
  *
- * Returns: (transfer full): A #GUdevDevice object or %NULL if the device was not found. Free with g_object_unref().
+ * Returns: (nullable) (transfer full): A #GUdevDevice object or %NULL
+ * if the device was not found. Free with g_object_unref().
  */
 GUdevDevice *
 g_udev_client_query_by_device_number (GUdevClient      *client,
@@ -423,7 +427,8 @@ g_udev_client_query_by_device_number (GUdevClient      *client,
  *
  * Looks up a device for a device file.
  *
- * Returns: (transfer full): A #GUdevDevice object or %NULL if the device was not found. Free with g_object_unref().
+ * Returns: (nullable) (transfer full): A #GUdevDevice object or %NULL
+ * if the device was not found. Free with g_object_unref().
  */
 GUdevDevice *
 g_udev_client_query_by_device_file (GUdevClient  *client,
@@ -459,7 +464,8 @@ g_udev_client_query_by_device_file (GUdevClient  *client,
  *
  * Looks up a device for a sysfs path.
  *
- * Returns: (transfer full): A #GUdevDevice object or %NULL if the device was not found. Free with g_object_unref().
+ * Returns: (nullable) (transfer full): A #GUdevDevice object or %NULL
+ * if the device was not found. Free with g_object_unref().
  */
 GUdevDevice *
 g_udev_client_query_by_sysfs_path (GUdevClient  *client,
@@ -491,7 +497,8 @@ g_udev_client_query_by_sysfs_path (GUdevClient  *client,
  *
  * Looks up a device for a subsystem and name.
  *
- * Returns: (transfer full): A #GUdevDevice object or %NULL if the device was not found. Free with g_object_unref().
+ * Returns: (nullable) (transfer full): A #GUdevDevice object or %NULL
+ * if the device was not found. Free with g_object_unref().
  */
 GUdevDevice *
 g_udev_client_query_by_subsystem_and_name (GUdevClient  *client,
index 2c768b7..7106719 100644 (file)
@@ -228,7 +228,8 @@ g_udev_device_get_sysfs_path (GUdevDevice *device)
  *
  * Gets the name of the driver used for @device.
  *
- * Returns: The name of the driver for @device or %NULL if unknown.
+ * Returns: (nullable): The name of the driver for @device or %NULL if
+ * unknown.
  */
 const gchar *
 g_udev_device_get_driver (GUdevDevice *device)
@@ -325,8 +326,8 @@ g_udev_device_get_device_number (GUdevDevice *device)
  *
  * Gets the device file for @device.
  *
- * Returns: The device file for @device or %NULL if no device file
- * exists.
+ * Returns: (nullable): The device file for @device or %NULL if no
+ * device file exists.
  */
 const gchar *
 g_udev_device_get_device_file (GUdevDevice *device)
@@ -375,7 +376,8 @@ g_udev_device_get_device_file_symlinks (GUdevDevice *device)
  *
  * Gets the immediate parent of @device, if any.
  *
- * Returns: (transfer full): A #GUdevDevice or %NULL if @device has no parent. Free with g_object_unref().
+ * Returns: (nullable) (transfer full): A #GUdevDevice or %NULL if
+ * @device has no parent. Free with g_object_unref().
  */
 GUdevDevice *
 g_udev_device_get_parent (GUdevDevice  *device)
@@ -406,7 +408,9 @@ g_udev_device_get_parent (GUdevDevice  *device)
  * Walks up the chain of parents of @device and returns the first
  * device encountered where @subsystem and @devtype matches, if any.
  *
- * Returns: (transfer full): A #GUdevDevice or %NULL if @device has no parent with @subsystem and @devtype. Free with g_object_unref().
+ * Returns: (nullable) (transfer full): A #GUdevDevice or %NULL if
+ * @device has no parent with @subsystem and @devtype. Free with
+ * g_object_unref().
  */
 GUdevDevice *
 g_udev_device_get_parent_with_subsystem (GUdevDevice  *device,
@@ -492,7 +496,8 @@ g_udev_device_has_property (GUdevDevice  *device,
  *
  * Look up the value for @key on @device.
  *
- * Returns: The value for @key or %NULL if @key doesn't exist on @device. Do not free this string, it is owned by @device.
+ * Returns: (nullable): The value for @key or %NULL if @key doesn't
+ * exist on @device. Do not free this string, it is owned by @device.
  */
 const gchar *
 g_udev_device_get_property (GUdevDevice  *device,
@@ -664,7 +669,10 @@ split_at_whitespace (const gchar *s)
  * horizontal tab ('\t'), and vertical tab ('\v') are considered; the
  * locale is not taken into account).
  *
- * Returns: (transfer none) (array zero-terminated=1) (element-type utf8): The value of @key on @device split into tokens or %NULL if @key doesn't exist. This array is owned by @device and should not be freed by the caller.
+ * Returns: (nullable) (transfer none) (array zero-terminated=1) (element-type utf8):
+ * The value of @key on @device split into tokens or %NULL if @key
+ * doesn't exist. This array is owned by @device and should not be
+ * freed by the caller.
  */
 const gchar* const *
 g_udev_device_get_property_as_strv (GUdevDevice  *device,
@@ -758,8 +766,9 @@ g_udev_device_has_sysfs_attr (GUdevDevice  *device,
  *
  * Look up the sysfs attribute with @name on @device.
  *
- * Returns: The value of the sysfs attribute or %NULL if there is no
- * such attribute. Do not free this string, it is owned by @device.
+ * Returns: (nullable): The value of the sysfs attribute or %NULL if
+ * there is no such attribute. Do not free this string, it is owned by
+ * @device.
  */
 const gchar *
 g_udev_device_get_sysfs_attr (GUdevDevice  *device,
@@ -907,7 +916,10 @@ g_udev_device_get_sysfs_attr_as_boolean (GUdevDevice  *device,
  * tab ('\t'), and vertical tab ('\v') are considered; the locale is
  * not taken into account).
  *
- * Returns: (transfer none) (array zero-terminated=1) (element-type utf8): The value of the sysfs attribute split into tokens or %NULL if there is no such attribute. This array is owned by @device and should not be freed by the caller.
+ * Returns: (nullable) (transfer none) (array zero-terminated=1) (element-type utf8):
+ * The value of the sysfs attribute split into tokens or %NULL if
+ * there is no such attribute. This array is owned by @device and
+ * should not be freed by the caller.
  */
 const gchar * const *
 g_udev_device_get_sysfs_attr_as_strv (GUdevDevice  *device,
diff --git a/src/gudev/libgudev-1.0.sym b/src/gudev/libgudev-1.0.sym
new file mode 100644 (file)
index 0000000..0600486
--- /dev/null
@@ -0,0 +1,68 @@
+/***
+  This file is part of systemd.
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+***/
+
+{
+global:
+        g_udev_client_get_type;
+        g_udev_client_new;
+        g_udev_client_query_by_device_file;
+        g_udev_client_query_by_device_number;
+        g_udev_client_query_by_subsystem;
+        g_udev_client_query_by_subsystem_and_name;
+        g_udev_client_query_by_sysfs_path;
+        g_udev_device_get_action;
+        g_udev_device_get_device_file;
+        g_udev_device_get_device_file_symlinks;
+        g_udev_device_get_device_number;
+        g_udev_device_get_device_type;
+        g_udev_device_get_devtype;
+        g_udev_device_get_driver;
+        g_udev_device_get_is_initialized;
+        g_udev_device_get_name;
+        g_udev_device_get_number;
+        g_udev_device_get_parent;
+        g_udev_device_get_parent_with_subsystem;
+        g_udev_device_get_property;
+        g_udev_device_get_property_as_boolean;
+        g_udev_device_get_property_as_double;
+        g_udev_device_get_property_as_int;
+        g_udev_device_get_property_as_strv;
+        g_udev_device_get_property_as_uint64;
+        g_udev_device_get_property_keys;
+        g_udev_device_get_seqnum;
+        g_udev_device_get_subsystem;
+        g_udev_device_get_sysfs_attr;
+        g_udev_device_get_sysfs_attr_as_boolean;
+        g_udev_device_get_sysfs_attr_as_double;
+        g_udev_device_get_sysfs_attr_as_int;
+        g_udev_device_get_sysfs_attr_as_strv;
+        g_udev_device_get_sysfs_attr_as_uint64;
+        g_udev_device_get_sysfs_attr_keys;
+        g_udev_device_get_sysfs_path;
+        g_udev_device_get_tags;
+        g_udev_device_get_type;
+        g_udev_device_get_usec_since_initialized;
+        g_udev_device_has_property;
+        g_udev_device_has_sysfs_attr;
+        g_udev_device_type_get_type;
+        g_udev_enumerator_add_match_is_initialized;
+        g_udev_enumerator_add_match_name;
+        g_udev_enumerator_add_match_property;
+        g_udev_enumerator_add_match_subsystem;
+        g_udev_enumerator_add_match_sysfs_attr;
+        g_udev_enumerator_add_match_tag;
+        g_udev_enumerator_add_nomatch_subsystem;
+        g_udev_enumerator_add_nomatch_sysfs_attr;
+        g_udev_enumerator_add_sysfs_path;
+        g_udev_enumerator_execute;
+        g_udev_enumerator_get_type;
+        g_udev_enumerator_new;
+local:
+        *;
+};
index e455249..e487369 100644 (file)
@@ -35,7 +35,7 @@
 #include "util.h"
 #include "spawn-polkit-agent.h"
 #include "build.h"
-#include "hwclock.h"
+#include "clock-util.h"
 #include "strv.h"
 #include "sd-id128.h"
 #include "virt.h"
@@ -67,34 +67,45 @@ typedef struct StatusInfo {
         char *pretty_hostname;
         char *icon_name;
         char *chassis;
+        char *deployment;
+        char *location;
+        char *kernel_name;
+        char *kernel_release;
+        char *os_pretty_name;
+        char *os_cpe_name;
+        char *virtualization;
+        char *architecture;
 } StatusInfo;
 
 static void print_status_info(StatusInfo *i) {
         sd_id128_t mid = {}, bid = {};
         int r;
-        const char *id = NULL;
-        _cleanup_free_ char *pretty_name = NULL, *cpe_name = NULL;
-        struct utsname u;
 
         assert(i);
 
-        printf("   Static hostname: %s\n",
-               strna(i->static_hostname));
+        printf("   Static hostname: %s\n", strna(i->static_hostname));
 
         if (!isempty(i->pretty_hostname) &&
             !streq_ptr(i->pretty_hostname, i->static_hostname))
-                printf("   Pretty hostname: %s\n",
-                       strna(i->pretty_hostname));
+                printf("   Pretty hostname: %s\n", i->pretty_hostname);
 
         if (!isempty(i->hostname) &&
             !streq_ptr(i->hostname, i->static_hostname))
-                printf("Transient hostname: %s\n",
-                       strna(i->hostname));
+                printf("Transient hostname: %s\n", i->hostname);
 
-        printf("         Icon name: %s\n"
-               "           Chassis: %s\n",
-               strna(i->icon_name),
-               strna(i->chassis));
+        if (!isempty(i->icon_name))
+                printf("         Icon name: %s\n",
+                       strna(i->icon_name));
+
+        if (!isempty(i->chassis))
+                printf("           Chassis: %s\n",
+                       strna(i->chassis));
+
+        if (!isempty(i->deployment))
+                printf("        Deployment: %s\n", i->deployment);
+
+        if (!isempty(i->location))
+                printf("          Location: %s\n", i->location);
 
         r = sd_id128_get_machine(&mid);
         if (r >= 0)
@@ -104,27 +115,20 @@ static void print_status_info(StatusInfo *i) {
         if (r >= 0)
                 printf("           Boot ID: " SD_ID128_FORMAT_STR "\n", SD_ID128_FORMAT_VAL(bid));
 
-        if (detect_virtualization(&id) > 0)
-                printf("    Virtualization: %s\n", id);
+        if (!isempty(i->virtualization))
+                printf("    Virtualization: %s\n", i->virtualization);
 
-        r = parse_env_file("/etc/os-release", NEWLINE,
-                           "PRETTY_NAME", &pretty_name,
-                           "CPE_NAME", &cpe_name,
-                           NULL);
-        if (r < 0)
-                log_warning("Failed to read /etc/os-release: %s", strerror(-r));
+        if (!isempty(i->os_pretty_name))
+                printf("  Operating System: %s\n", i->os_pretty_name);
 
-        if (!isempty(pretty_name))
-                printf("  Operating System: %s\n", pretty_name);
+        if (!isempty(i->os_cpe_name))
+                printf("       CPE OS Name: %s\n", i->os_cpe_name);
 
-        if (!isempty(cpe_name))
-                printf("       CPE OS Name: %s\n", cpe_name);
+        if (!isempty(i->kernel_name) && !isempty(i->kernel_release))
+                printf("            Kernel: %s %s\n", i->kernel_name, i->kernel_release);
 
-        assert_se(uname(&u) >= 0);
-        printf("            Kernel: %s %s\n"
-               "      Architecture: %s\n",
-               u.sysname, u.release,
-               architecture_to_string(uname_architecture()));
+        if (!isempty(i->architecture))
+                printf("      Architecture: %s\n", i->architecture);
 
 }
 
@@ -157,24 +161,44 @@ static int show_one_name(sd_bus *bus, const char* attr) {
 
 static int show_all_names(sd_bus *bus) {
         StatusInfo info = {};
-        static const struct bus_properties_map map[]  = {
-                { "Hostname",       "s", NULL, offsetof(StatusInfo, hostname) },
-                { "StaticHostname", "s", NULL, offsetof(StatusInfo, static_hostname) },
-                { "PrettyHostname", "s", NULL, offsetof(StatusInfo, pretty_hostname) },
-                { "IconName",       "s", NULL, offsetof(StatusInfo, icon_name) },
-                { "Chassis",        "s", NULL, offsetof(StatusInfo, chassis) },
+
+        static const struct bus_properties_map hostname_map[]  = {
+                { "Hostname",                  "s", NULL, offsetof(StatusInfo, hostname)        },
+                { "StaticHostname",            "s", NULL, offsetof(StatusInfo, static_hostname) },
+                { "PrettyHostname",            "s", NULL, offsetof(StatusInfo, pretty_hostname) },
+                { "IconName",                  "s", NULL, offsetof(StatusInfo, icon_name)       },
+                { "Chassis",                   "s", NULL, offsetof(StatusInfo, chassis)         },
+                { "Deployment",                "s", NULL, offsetof(StatusInfo, deployment)      },
+                { "Location",                  "s", NULL, offsetof(StatusInfo, location)        },
+                { "KernelName",                "s", NULL, offsetof(StatusInfo, kernel_name)     },
+                { "KernelRelease",             "s", NULL, offsetof(StatusInfo, kernel_release)  },
+                { "OperatingSystemPrettyName", "s", NULL, offsetof(StatusInfo, os_pretty_name)  },
+                { "OperatingSystemCPEName",    "s", NULL, offsetof(StatusInfo, os_cpe_name)     },
+                {}
+        };
+
+        static const struct bus_properties_map manager_map[] = {
+                { "Virtualization",            "s", NULL, offsetof(StatusInfo, virtualization)  },
+                { "Architecture",              "s", NULL, offsetof(StatusInfo, architecture)    },
                 {}
         };
+
         int r;
 
         r = bus_map_all_properties(bus,
                                    "org.freedesktop.hostname1",
                                    "/org/freedesktop/hostname1",
-                                   map,
+                                   hostname_map,
                                    &info);
         if (r < 0)
                 goto fail;
 
+        bus_map_all_properties(bus,
+                               "org.freedesktop.systemd1",
+                               "/org/freedesktop/systemd1",
+                               manager_map,
+                               &info);
+
         print_status_info(&info);
 
 fail:
@@ -183,7 +207,16 @@ fail:
         free(info.pretty_hostname);
         free(info.icon_name);
         free(info.chassis);
-        return 0;
+        free(info.deployment);
+        free(info.location);
+        free(info.kernel_name);
+        free(info.kernel_release);
+        free(info.os_pretty_name);
+        free(info.os_cpe_name);
+        free(info.virtualization);
+        free(info.architecture);
+
+        return r;
 }
 
 static int show_status(sd_bus *bus, char **args, unsigned n) {
@@ -291,8 +324,21 @@ static int set_chassis(sd_bus *bus, char **args, unsigned n) {
         return set_simple_string(bus, "SetChassis", args[1]);
 }
 
-static int help(void) {
+static int set_deployment(sd_bus *bus, char **args, unsigned n) {
+        assert(args);
+        assert(n == 2);
+
+        return set_simple_string(bus, "SetDeployment", args[1]);
+}
 
+static int set_location(sd_bus *bus, char **args, unsigned n) {
+        assert(args);
+        assert(n == 2);
+
+        return set_simple_string(bus, "SetLocation", args[1]);
+}
+
+static void help(void) {
         printf("%s [OPTIONS...] COMMAND ...\n\n"
                "Query or change system hostname.\n\n"
                "  -h --help              Show this help\n"
@@ -307,10 +353,10 @@ static int help(void) {
                "  status                 Show current hostname settings\n"
                "  set-hostname NAME      Set system hostname\n"
                "  set-icon-name NAME     Set icon name for host\n"
-               "  set-chassis NAME       Set chassis type for host\n",
-               program_invocation_short_name);
-
-        return 0;
+               "  set-chassis NAME       Set chassis type for host\n"
+               "  set-deployment NAME    Set deployment environment for host\n"
+               "  set-location NAME      Set location for host\n"
+               , program_invocation_short_name);
 }
 
 static int parse_argv(int argc, char *argv[]) {
@@ -340,12 +386,13 @@ static int parse_argv(int argc, char *argv[]) {
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "hH:M:", options, NULL)) >= 0) {
+        while ((c = getopt_long(argc, argv, "hH:M:", options, NULL)) >= 0)
 
                 switch (c) {
 
                 case 'h':
-                        return help();
+                        help();
+                        return 0;
 
                 case ARG_VERSION:
                         puts(PACKAGE_STRING);
@@ -384,7 +431,6 @@ static int parse_argv(int argc, char *argv[]) {
                 default:
                         assert_not_reached("Unhandled option");
                 }
-        }
 
         return 1;
 }
@@ -401,10 +447,12 @@ static int hostnamectl_main(sd_bus *bus, int argc, char *argv[]) {
                 const int argc;
                 int (* const dispatch)(sd_bus *bus, char **args, unsigned n);
         } verbs[] = {
-                { "status",        LESS,  1, show_status   },
-                { "set-hostname",  EQUAL, 2, set_hostname  },
-                { "set-icon-name", EQUAL, 2, set_icon_name },
-                { "set-chassis",   EQUAL, 2, set_chassis   },
+                { "status",           LESS,  1, show_status    },
+                { "set-hostname",     EQUAL, 2, set_hostname   },
+                { "set-icon-name",    EQUAL, 2, set_icon_name  },
+                { "set-chassis",      EQUAL, 2, set_chassis    },
+                { "set-deployment",   EQUAL, 2, set_deployment },
+                { "set-location",     EQUAL, 2, set_location   },
         };
 
         int left;
@@ -468,7 +516,7 @@ static int hostnamectl_main(sd_bus *bus, int argc, char *argv[]) {
 }
 
 int main(int argc, char *argv[]) {
-        _cleanup_bus_unref_ sd_bus *bus = NULL;
+        _cleanup_bus_close_unref_ sd_bus *bus = NULL;
         int r;
 
         setlocale(LC_ALL, "");
index 6aa08ca..d31fef7 100644 (file)
@@ -22,7 +22,8 @@
 #include <errno.h>
 #include <string.h>
 #include <unistd.h>
-#include <dlfcn.h>
+#include <sys/utsname.h>
+#include <sys/capability.h>
 
 #include "util.h"
 #include "strv.h"
 #include "bus-util.h"
 #include "event-util.h"
 
+#define VALID_DEPLOYMENT_CHARS (DIGITS LETTERS "-.:")
+
 enum {
         PROP_HOSTNAME,
         PROP_STATIC_HOSTNAME,
         PROP_PRETTY_HOSTNAME,
         PROP_ICON_NAME,
         PROP_CHASSIS,
+        PROP_DEPLOYMENT,
+        PROP_LOCATION,
+        PROP_KERNEL_NAME,
+        PROP_KERNEL_RELEASE,
+        PROP_KERNEL_VERSION,
+        PROP_OS_PRETTY_NAME,
+        PROP_OS_CPE_NAME,
         _PROP_MAX
 };
 
@@ -59,20 +69,29 @@ static void context_reset(Context *c) {
         }
 }
 
-static void context_free(Context *c, sd_bus *bus) {
+static void context_free(Context *c) {
         assert(c);
 
         context_reset(c);
-        bus_verify_polkit_async_registry_free(bus, c->polkit_registry);
+        bus_verify_polkit_async_registry_free(c->polkit_registry);
 }
 
 static int context_read_data(Context *c) {
         int r;
+        struct utsname u;
 
         assert(c);
 
         context_reset(c);
 
+        assert_se(uname(&u) >= 0);
+        c->data[PROP_KERNEL_NAME] = strdup(u.sysname);
+        c->data[PROP_KERNEL_RELEASE] = strdup(u.release);
+        c->data[PROP_KERNEL_VERSION] = strdup(u.version);
+        if (!c->data[PROP_KERNEL_NAME] || !c->data[PROP_KERNEL_RELEASE] ||
+            !c->data[PROP_KERNEL_VERSION])
+                return -ENOMEM;
+
         c->data[PROP_HOSTNAME] = gethostname_malloc();
         if (!c->data[PROP_HOSTNAME])
                 return -ENOMEM;
@@ -85,27 +104,30 @@ static int context_read_data(Context *c) {
                            "PRETTY_HOSTNAME", &c->data[PROP_PRETTY_HOSTNAME],
                            "ICON_NAME", &c->data[PROP_ICON_NAME],
                            "CHASSIS", &c->data[PROP_CHASSIS],
+                           "DEPLOYMENT", &c->data[PROP_DEPLOYMENT],
+                           "LOCATION", &c->data[PROP_LOCATION],
                            NULL);
         if (r < 0 && r != -ENOENT)
                 return r;
 
-        return 0;
-}
-
-static bool check_nss(void) {
-        void *dl;
-
-        dl = dlopen("libnss_myhostname.so.2", RTLD_LAZY);
-        if (dl) {
-                dlclose(dl);
-                return true;
+        r = parse_env_file("/etc/os-release", NEWLINE,
+                           "PRETTY_NAME", &c->data[PROP_OS_PRETTY_NAME],
+                           "CPE_NAME", &c->data[PROP_OS_CPE_NAME],
+                           NULL);
+        if (r == -ENOENT) {
+                r = parse_env_file("/usr/lib/os-release", NEWLINE,
+                                   "PRETTY_NAME", &c->data[PROP_OS_PRETTY_NAME],
+                                   "CPE_NAME", &c->data[PROP_OS_CPE_NAME],
+                                   NULL);
         }
 
-        return false;
+        if (r < 0 && r != -ENOENT)
+                return r;
+
+        return 0;
 }
 
 static bool valid_chassis(const char *chassis) {
-
         assert(chassis);
 
         return nulstr_contains(
@@ -115,10 +137,17 @@ static bool valid_chassis(const char *chassis) {
                         "laptop\0"
                         "server\0"
                         "tablet\0"
-                        "handset\0",
+                        "handset\0"
+                        "watch\0",
                         chassis);
 }
 
+static bool valid_deployment(const char *deployment) {
+        assert(deployment);
+
+        return in_charset(deployment, VALID_DEPLOYMENT_CHARS);
+}
+
 static const char* fallback_chassis(void) {
         int r;
         char *type;
@@ -228,16 +257,36 @@ static char* context_fallback_icon_name(Context *c) {
         return strdup("computer");
 }
 
-static int context_write_data_hostname(Context *c) {
+
+static bool hostname_is_useful(const char *hn) {
+        return !isempty(hn) && !is_localhost(hn);
+}
+
+static int context_update_kernel_hostname(Context *c) {
+        const char *static_hn;
         const char *hn;
 
         assert(c);
 
-        if (isempty(c->data[PROP_HOSTNAME]))
-                hn = "localhost";
-        else
+        static_hn = c->data[PROP_STATIC_HOSTNAME];
+
+        /* /etc/hostname with something other than "localhost"
+         * has the highest preference ... */
+        if (hostname_is_useful(static_hn))
+                hn = static_hn;
+
+        /* ... the transient host name, (ie: DHCP) comes next ...*/
+        else if (!isempty(c->data[PROP_HOSTNAME]))
                 hn = c->data[PROP_HOSTNAME];
 
+        /* ... fallback to static "localhost.*" ignored above ... */
+        else if (!isempty(static_hn))
+                hn = static_hn;
+
+        /* ... and the ultimate fallback */
+        else
+                hn = "localhost";
+
         if (sethostname(hn, strlen(hn)) < 0)
                 return -errno;
 
@@ -258,12 +307,14 @@ static int context_write_data_static_hostname(Context *c) {
         return write_string_file_atomic_label("/etc/hostname", c->data[PROP_STATIC_HOSTNAME]);
 }
 
-static int context_write_data_other(Context *c) {
+static int context_write_data_machine_info(Context *c) {
 
         static const char * const name[_PROP_MAX] = {
                 [PROP_PRETTY_HOSTNAME] = "PRETTY_HOSTNAME",
                 [PROP_ICON_NAME] = "ICON_NAME",
-                [PROP_CHASSIS] = "CHASSIS"
+                [PROP_CHASSIS] = "CHASSIS",
+                [PROP_DEPLOYMENT] = "DEPLOYMENT",
+                [PROP_LOCATION] = "LOCATION",
         };
 
         _cleanup_strv_free_ char **l = NULL;
@@ -271,12 +322,13 @@ static int context_write_data_other(Context *c) {
 
         assert(c);
 
-        r = load_env_file("/etc/machine-info", NULL, &l);
+        r = load_env_file(NULL, "/etc/machine-info", NULL, &l);
         if (r < 0 && r != -ENOENT)
                 return r;
 
-        for (p = 2; p < _PROP_MAX; p++) {
-                char *t, **u;
+        for (p = PROP_PRETTY_HOSTNAME; p <= PROP_LOCATION; p++) {
+                _cleanup_free_ char *t = NULL;
+                char **u;
 
                 assert(name[p]);
 
@@ -285,12 +337,11 @@ static int context_write_data_other(Context *c) {
                         continue;
                 }
 
-                if (asprintf(&t, "%s=%s", name[p], strempty(c->data[p])) < 0)
+                t = strjoin(name[p], "=", c->data[p], NULL);
+                if (!t)
                         return -ENOMEM;
 
                 u = strv_env_set(l, t);
-                free(t);
-
                 if (!u)
                         return -ENOMEM;
 
@@ -299,7 +350,6 @@ static int context_write_data_other(Context *c) {
         }
 
         if (strv_isempty(l)) {
-
                 if (unlink("/etc/machine-info") < 0)
                         return errno == ENOENT ? 0 : -errno;
 
@@ -376,7 +426,7 @@ static int method_set_hostname(sd_bus *bus, sd_bus_message *m, void *userdata, s
         if (streq_ptr(name, c->data[PROP_HOSTNAME]))
                 return sd_bus_reply_method_return(m, NULL);
 
-        r = bus_verify_polkit_async(bus, &c->polkit_registry, m, "org.freedesktop.hostname1.set-hostname", interactive, error, method_set_hostname, c);
+        r = bus_verify_polkit_async(m, CAP_SYS_ADMIN, "org.freedesktop.hostname1.set-hostname", interactive, &c->polkit_registry, error);
         if (r < 0)
                 return r;
         if (r == 0)
@@ -389,7 +439,7 @@ static int method_set_hostname(sd_bus *bus, sd_bus_message *m, void *userdata, s
         free(c->data[PROP_HOSTNAME]);
         c->data[PROP_HOSTNAME] = h;
 
-        r = context_write_data_hostname(c);
+        r = context_update_kernel_hostname(c);
         if (r < 0) {
                 log_error("Failed to set host name: %s", strerror(-r));
                 return sd_bus_error_set_errnof(error, r, "Failed to set hostname: %s", strerror(-r));
@@ -418,7 +468,7 @@ static int method_set_static_hostname(sd_bus *bus, sd_bus_message *m, void *user
         if (streq_ptr(name, c->data[PROP_STATIC_HOSTNAME]))
                 return sd_bus_reply_method_return(m, NULL);
 
-        r = bus_verify_polkit_async(bus, &c->polkit_registry, m, "org.freedesktop.hostname1.set-static-hostname", interactive, error, method_set_static_hostname, c);
+        r = bus_verify_polkit_async(m, CAP_SYS_ADMIN, "org.freedesktop.hostname1.set-static-hostname", interactive, &c->polkit_registry, error);
         if (r < 0)
                 return r;
         if (r == 0)
@@ -441,6 +491,12 @@ static int method_set_static_hostname(sd_bus *bus, sd_bus_message *m, void *user
                 c->data[PROP_STATIC_HOSTNAME] = h;
         }
 
+        r = context_update_kernel_hostname(c);
+        if (r < 0) {
+                log_error("Failed to set host name: %s", strerror(-r));
+                return sd_bus_error_set_errnof(error, r, "Failed to set hostname: %s", strerror(-r));
+        }
+
         r = context_write_data_static_hostname(c);
         if (r < 0) {
                 log_error("Failed to write static host name: %s", strerror(-r));
@@ -477,9 +533,10 @@ static int set_machine_info(Context *c, sd_bus *bus, sd_bus_message *m, int prop
          * same time as the static one, use the same policy action for
          * both... */
 
-        r = bus_verify_polkit_async(bus, &c->polkit_registry, m, prop == PROP_PRETTY_HOSTNAME ?
-                          "org.freedesktop.hostname1.set-static-hostname" :
-                          "org.freedesktop.hostname1.set-machine-info", interactive, error, cb, c);
+        r = bus_verify_polkit_async(m, CAP_SYS_ADMIN,
+                                    prop == PROP_PRETTY_HOSTNAME ?
+                                    "org.freedesktop.hostname1.set-static-hostname" :
+                                    "org.freedesktop.hostname1.set-machine-info", interactive, &c->polkit_registry, error);
         if (r < 0)
                 return r;
         if (r == 0)
@@ -496,11 +553,14 @@ static int set_machine_info(Context *c, sd_bus *bus, sd_bus_message *m, int prop
 
                 if (prop == PROP_ICON_NAME && !filename_is_safe(name))
                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid icon name '%s'", name);
-                if (prop == PROP_PRETTY_HOSTNAME &&
-                    (string_has_cc(name) || chars_intersect(name, "\t")))
+                if (prop == PROP_PRETTY_HOSTNAME && string_has_cc(name, NULL))
                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid pretty host name '%s'", name);
                 if (prop == PROP_CHASSIS && !valid_chassis(name))
                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid chassis '%s'", name);
+                if (prop == PROP_DEPLOYMENT && !valid_deployment(name))
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid deployment '%s'", name);
+                if (prop == PROP_LOCATION && string_has_cc(name, NULL))
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid location '%s'", name);
 
                 h = strdup(name);
                 if (!h)
@@ -510,7 +570,7 @@ static int set_machine_info(Context *c, sd_bus *bus, sd_bus_message *m, int prop
                 c->data[prop] = h;
         }
 
-        r = context_write_data_other(c);
+        r = context_write_data_machine_info(c);
         if (r < 0) {
                 log_error("Failed to write machine info: %s", strerror(-r));
                 return sd_bus_error_set_errnof(error, r, "Failed to write machine info: %s", strerror(-r));
@@ -518,11 +578,15 @@ static int set_machine_info(Context *c, sd_bus *bus, sd_bus_message *m, int prop
 
         log_info("Changed %s to '%s'",
                  prop == PROP_PRETTY_HOSTNAME ? "pretty host name" :
+                 prop == PROP_DEPLOYMENT ? "deployment" :
+                 prop == PROP_LOCATION ? "location" :
                  prop == PROP_CHASSIS ? "chassis" : "icon name", strna(c->data[prop]));
 
         sd_bus_emit_properties_changed(bus, "/org/freedesktop/hostname1", "org.freedesktop.hostname1",
                                        prop == PROP_PRETTY_HOSTNAME ? "PrettyHostname" :
-                                       prop == PROP_CHASSIS ? "Chassis" : "IconName", NULL);
+                                       prop == PROP_DEPLOYMENT ? "Deployment" :
+                                       prop == PROP_LOCATION ? "Location" :
+                                       prop == PROP_CHASSIS ? "Chassis" : "IconName" , NULL);
 
         return sd_bus_reply_method_return(m, NULL);
 }
@@ -539,6 +603,14 @@ static int method_set_chassis(sd_bus *bus, sd_bus_message *m, void *userdata, sd
         return set_machine_info(userdata, bus, m, PROP_CHASSIS, method_set_chassis, error);
 }
 
+static int method_set_deployment(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
+        return set_machine_info(userdata, bus, m, PROP_DEPLOYMENT, method_set_deployment, error);
+}
+
+static int method_set_location(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
+        return set_machine_info(userdata, bus, m, PROP_LOCATION, method_set_location, error);
+}
+
 static const sd_bus_vtable hostname_vtable[] = {
         SD_BUS_VTABLE_START(0),
         SD_BUS_PROPERTY("Hostname", "s", NULL, offsetof(Context, data) + sizeof(char*) * PROP_HOSTNAME, 0),
@@ -546,16 +618,25 @@ static const sd_bus_vtable hostname_vtable[] = {
         SD_BUS_PROPERTY("PrettyHostname", "s", NULL, offsetof(Context, data) + sizeof(char*) * PROP_PRETTY_HOSTNAME, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         SD_BUS_PROPERTY("IconName", "s", property_get_icon_name, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         SD_BUS_PROPERTY("Chassis", "s", property_get_chassis, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
+        SD_BUS_PROPERTY("Deployment", "s", NULL, offsetof(Context, data) + sizeof(char*) * PROP_DEPLOYMENT, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
+        SD_BUS_PROPERTY("Location", "s", NULL, offsetof(Context, data) + sizeof(char*) * PROP_LOCATION, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
+        SD_BUS_PROPERTY("KernelName", "s", NULL, offsetof(Context, data) + sizeof(char*) * PROP_KERNEL_NAME, SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("KernelRelease", "s", NULL, offsetof(Context, data) + sizeof(char*) * PROP_KERNEL_RELEASE, SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("KernelVersion", "s", NULL, offsetof(Context, data) + sizeof(char*) * PROP_KERNEL_VERSION, SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("OperatingSystemPrettyName", "s", NULL, offsetof(Context, data) + sizeof(char*) * PROP_OS_PRETTY_NAME, SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("OperatingSystemCPEName", "s", NULL, offsetof(Context, data) + sizeof(char*) * PROP_OS_CPE_NAME, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_METHOD("SetHostname", "sb", NULL, method_set_hostname, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("SetStaticHostname", "sb", NULL, method_set_static_hostname, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("SetPrettyHostname", "sb", NULL, method_set_pretty_hostname, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("SetIconName", "sb", NULL, method_set_icon_name, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("SetChassis", "sb", NULL, method_set_chassis, SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("SetDeployment", "sb", NULL, method_set_deployment, SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("SetLocation", "sb", NULL, method_set_location, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_VTABLE_END,
 };
 
 static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) {
-        _cleanup_bus_unref_ sd_bus *bus = NULL;
+        _cleanup_bus_close_unref_ sd_bus *bus = NULL;
         int r;
 
         assert(c);
@@ -568,7 +649,7 @@ static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) {
                 return r;
         }
 
-        r = sd_bus_add_object_vtable(bus, "/org/freedesktop/hostname1", "org.freedesktop.hostname1", hostname_vtable, c);
+        r = sd_bus_add_object_vtable(bus, NULL, "/org/freedesktop/hostname1", "org.freedesktop.hostname1", hostname_vtable, c);
         if (r < 0) {
                 log_error("Failed to register object: %s", strerror(-r));
                 return r;
@@ -594,9 +675,8 @@ static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) {
 
 int main(int argc, char *argv[]) {
         Context context = {};
-
         _cleanup_event_unref_ sd_event *event = NULL;
-        _cleanup_bus_unref_ sd_bus *bus = NULL;
+        _cleanup_bus_close_unref_ sd_bus *bus = NULL;
         int r;
 
         log_set_target(LOG_TARGET_AUTO);
@@ -612,9 +692,6 @@ int main(int argc, char *argv[]) {
                 goto finish;
         }
 
-        if (!check_nss())
-                log_warning("Warning: nss-myhostname is not installed. Changing the local hostname might make it unresolveable. Please install nss-myhostname!");
-
         if (argc != 1) {
                 log_error("This program takes no arguments.");
                 r = -EINVAL;
@@ -646,7 +723,7 @@ int main(int argc, char *argv[]) {
         }
 
 finish:
-        context_free(&context, bus);
+        context_free(&context);
 
         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
 }
index 468df35..0954e58 100644 (file)
@@ -218,7 +218,7 @@ static int fifo_process(Fifo *f) {
                         return 0;
 
                 log_warning("Failed to read from fifo: %m");
-                return -1;
+                return -errno;
         }
 
         f->bytes_read += l;
@@ -245,7 +245,7 @@ static void fifo_free(Fifo *f) {
                 if (f->server)
                         epoll_ctl(f->server->epoll_fd, EPOLL_CTL_DEL, f->fd, NULL);
 
-                close_nointr_nofail(f->fd);
+                safe_close(f->fd);
         }
 
         free(f);
@@ -257,8 +257,7 @@ static void server_done(Server *s) {
         while (s->fifos)
                 fifo_free(s->fifos);
 
-        if (s->epoll_fd >= 0)
-                close_nointr_nofail(s->epoll_fd);
+        safe_close(s->epoll_fd);
 
         if (s->bus) {
                 sd_bus_flush(s->bus);
@@ -384,7 +383,8 @@ int main(int argc, char *argv[]) {
 
         umask(0022);
 
-        if ((n = sd_listen_fds(true)) < 0) {
+        n = sd_listen_fds(true);
+        if (n < 0) {
                 log_error("Failed to read listening file descriptors from environment: %s", strerror(-r));
                 return EXIT_FAILURE;
         }
@@ -397,7 +397,7 @@ int main(int argc, char *argv[]) {
         if (server_init(&server, (unsigned) n) < 0)
                 return EXIT_FAILURE;
 
-        log_debug("systemd-initctl running as pid %lu", (unsigned long) getpid());
+        log_debug("systemd-initctl running as pid "PID_FMT, getpid());
 
         sd_notify(false,
                   "READY=1\n"
@@ -427,7 +427,7 @@ int main(int argc, char *argv[]) {
 
         r = EXIT_SUCCESS;
 
-        log_debug("systemd-initctl stopped as pid %lu", (unsigned long) getpid());
+        log_debug("systemd-initctl stopped as pid "PID_FMT, getpid());
 
 fail:
         sd_notify(false,
diff --git a/src/journal-remote/.gitignore b/src/journal-remote/.gitignore
new file mode 100644 (file)
index 0000000..06847b6
--- /dev/null
@@ -0,0 +1,2 @@
+/journal-remote.conf
+/journal-upload.conf
diff --git a/src/journal-remote/Makefile b/src/journal-remote/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
similarity index 87%
rename from src/journal/journal-gatewayd.c
rename to src/journal-remote/journal-gatewayd.c
index 7e97a35..db81fe3 100644 (file)
 
 #include <microhttpd.h>
 
+#ifdef HAVE_GNUTLS
+#include <gnutls/gnutls.h>
+#endif
+
 #include "log.h"
 #include "util.h"
 #include "sd-journal.h"
 #include "build.h"
 #include "fileio.h"
 
+static char *key_pem = NULL;
+static char *cert_pem = NULL;
+static char *trust_pem = NULL;
+
 typedef struct RequestMeta {
         sd_journal *journal;
 
@@ -70,6 +78,7 @@ static const char* const mime_types[_OUTPUT_MODE_MAX] = {
 static RequestMeta *request_meta(void **connection_cls) {
         RequestMeta *m;
 
+        assert(connection_cls);
         if (*connection_cls)
                 return *connection_cls;
 
@@ -111,60 +120,6 @@ static int open_journal(RequestMeta *m) {
         return sd_journal_open(&m->journal, SD_JOURNAL_LOCAL_ONLY|SD_JOURNAL_SYSTEM);
 }
 
-static int respond_oom_internal(struct MHD_Connection *connection) {
-        struct MHD_Response *response;
-        const char m[] = "Out of memory.\n";
-        int ret;
-
-        assert(connection);
-
-        response = MHD_create_response_from_buffer(sizeof(m)-1, (char*) m, MHD_RESPMEM_PERSISTENT);
-        if (!response)
-                return MHD_NO;
-
-        MHD_add_response_header(response, "Content-Type", "text/plain");
-        ret = MHD_queue_response(connection, MHD_HTTP_SERVICE_UNAVAILABLE, response);
-        MHD_destroy_response(response);
-
-        return ret;
-}
-
-#define respond_oom(connection) log_oom(), respond_oom_internal(connection)
-
-_printf_(3,4)
-static int respond_error(
-                struct MHD_Connection *connection,
-                unsigned code,
-                const char *format, ...) {
-
-        struct MHD_Response *response;
-        char *m;
-        int r;
-        va_list ap;
-
-        assert(connection);
-        assert(format);
-
-        va_start(ap, format);
-        r = vasprintf(&m, format, ap);
-        va_end(ap);
-
-        if (r < 0)
-                return respond_oom(connection);
-
-        response = MHD_create_response_from_buffer(strlen(m), m, MHD_RESPMEM_MUST_FREE);
-        if (!response) {
-                free(m);
-                return respond_oom(connection);
-        }
-
-        MHD_add_response_header(response, "Content-Type", "text/plain");
-        r = MHD_queue_response(connection, code, response);
-        MHD_destroy_response(response);
-
-        return r;
-}
-
 static ssize_t request_reader_entries(
                 void *cls,
                 uint64_t pos,
@@ -495,20 +450,20 @@ static int request_handler_entries(
 
         r = open_journal(m);
         if (r < 0)
-                return respond_error(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to open journal: %s\n", strerror(-r));
+                return mhd_respondf(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to open journal: %s\n", strerror(-r));
 
         if (request_parse_accept(m, connection) < 0)
-                return respond_error(connection, MHD_HTTP_BAD_REQUEST, "Failed to parse Accept header.\n");
+                return mhd_respond(connection, MHD_HTTP_BAD_REQUEST, "Failed to parse Accept header.\n");
 
         if (request_parse_range(m, connection) < 0)
-                return respond_error(connection, MHD_HTTP_BAD_REQUEST, "Failed to parse Range header.\n");
+                return mhd_respond(connection, MHD_HTTP_BAD_REQUEST, "Failed to parse Range header.\n");
 
         if (request_parse_arguments(m, connection) < 0)
-                return respond_error(connection, MHD_HTTP_BAD_REQUEST, "Failed to parse URL arguments.\n");
+                return mhd_respond(connection, MHD_HTTP_BAD_REQUEST, "Failed to parse URL arguments.\n");
 
         if (m->discrete) {
                 if (!m->cursor)
-                        return respond_error(connection, MHD_HTTP_BAD_REQUEST, "Discrete seeks require a cursor specification.\n");
+                        return mhd_respond(connection, MHD_HTTP_BAD_REQUEST, "Discrete seeks require a cursor specification.\n");
 
                 m->n_entries = 1;
                 m->n_entries_set = true;
@@ -521,7 +476,7 @@ static int request_handler_entries(
         else if (m->n_skip < 0)
                 r = sd_journal_seek_tail(m->journal);
         if (r < 0)
-                return respond_error(connection, MHD_HTTP_BAD_REQUEST, "Failed to seek in journal.\n");
+                return mhd_respond(connection, MHD_HTTP_BAD_REQUEST, "Failed to seek in journal.\n");
 
         response = MHD_create_response_from_callback(MHD_SIZE_UNKNOWN, 4*1024, request_reader_entries, m, NULL);
         if (!response)
@@ -657,14 +612,14 @@ static int request_handler_fields(
 
         r = open_journal(m);
         if (r < 0)
-                return respond_error(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to open journal: %s\n", strerror(-r));
+                return mhd_respondf(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to open journal: %s\n", strerror(-r));
 
         if (request_parse_accept(m, connection) < 0)
-                return respond_error(connection, MHD_HTTP_BAD_REQUEST, "Failed to parse Accept header.\n");
+                return mhd_respond(connection, MHD_HTTP_BAD_REQUEST, "Failed to parse Accept header.\n");
 
         r = sd_journal_query_unique(m->journal, field);
         if (r < 0)
-                return respond_error(connection, MHD_HTTP_BAD_REQUEST, "Failed to query unique fields.\n");
+                return mhd_respond(connection, MHD_HTTP_BAD_REQUEST, "Failed to query unique fields.\n");
 
         response = MHD_create_response_from_callback(MHD_SIZE_UNKNOWN, 4*1024, request_reader_fields, m, NULL);
         if (!response)
@@ -723,10 +678,10 @@ static int request_handler_file(
 
         fd = open(path, O_RDONLY|O_CLOEXEC);
         if (fd < 0)
-                return respond_error(connection, MHD_HTTP_NOT_FOUND, "Failed to open file %s: %m\n", path);
+                return mhd_respondf(connection, MHD_HTTP_NOT_FOUND, "Failed to open file %s: %m\n", path);
 
         if (fstat(fd, &st) < 0)
-                return respond_error(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to stat file: %m\n");
+                return mhd_respondf(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to stat file: %m\n");
 
         response = MHD_create_response_from_fd_at_offset(st.st_size, fd, 0);
         if (!response)
@@ -790,15 +745,15 @@ static int request_handler_machine(
 
         r = open_journal(m);
         if (r < 0)
-                return respond_error(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to open journal: %s\n", strerror(-r));
+                return mhd_respondf(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to open journal: %s\n", strerror(-r));
 
         r = sd_id128_get_machine(&mid);
         if (r < 0)
-                return respond_error(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to determine machine ID: %s\n", strerror(-r));
+                return mhd_respondf(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to determine machine ID: %s\n", strerror(-r));
 
         r = sd_id128_get_boot(&bid);
         if (r < 0)
-                return respond_error(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to determine boot ID: %s\n", strerror(-r));
+                return mhd_respondf(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to determine boot ID: %s\n", strerror(-r));
 
         hostname = gethostname_malloc();
         if (!hostname)
@@ -806,13 +761,14 @@ static int request_handler_machine(
 
         r = sd_journal_get_usage(m->journal, &usage);
         if (r < 0)
-                return respond_error(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to determine disk usage: %s\n", strerror(-r));
+                return mhd_respondf(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to determine disk usage: %s\n", strerror(-r));
 
         r = sd_journal_get_cutoff_realtime_usec(m->journal, &cutoff_from, &cutoff_to);
         if (r < 0)
-                return respond_error(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to determine disk usage: %s\n", strerror(-r));
+                return mhd_respondf(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to determine disk usage: %s\n", strerror(-r));
 
-        parse_env_file("/etc/os-release", NEWLINE, "PRETTY_NAME", &os_name, NULL);
+        if (parse_env_file("/etc/os-release", NEWLINE, "PRETTY_NAME", &os_name, NULL) == -ENOENT)
+                parse_env_file("/usr/lib/os-release", NEWLINE, "PRETTY_NAME", &os_name, NULL);
 
         get_virtualization(&v);
 
@@ -859,6 +815,7 @@ static int request_handler(
                 const char *upload_data,
                 size_t *upload_data_size,
                 void **connection_cls) {
+        int r, code;
 
         assert(connection);
         assert(connection_cls);
@@ -866,8 +823,8 @@ static int request_handler(
         assert(method);
 
         if (!streq(method, "GET"))
-                return respond_error(connection, MHD_HTTP_METHOD_NOT_ACCEPTABLE,
-                                     "Unsupported method.\n");
+                return mhd_respond(connection, MHD_HTTP_METHOD_NOT_ACCEPTABLE,
+                                   "Unsupported method.\n");
 
 
         if (!*connection_cls) {
@@ -876,6 +833,12 @@ static int request_handler(
                 return MHD_YES;
         }
 
+        if (trust_pem) {
+                r = check_permissions(connection, &code, NULL);
+                if (r < 0)
+                        return code;
+        }
+
         if (streq(url, "/"))
                 return request_handler_redirect(connection, "/browse");
 
@@ -891,30 +854,26 @@ static int request_handler(
         if (streq(url, "/machine"))
                 return request_handler_machine(connection, *connection_cls);
 
-        return respond_error(connection, MHD_HTTP_NOT_FOUND, "Not found.\n");
+        return mhd_respond(connection, MHD_HTTP_NOT_FOUND, "Not found.\n");
 }
 
-static int help(void) {
-
+static void help(void) {
         printf("%s [OPTIONS...] ...\n\n"
                "HTTP server for journal events.\n\n"
                "  -h --help           Show this help\n"
                "     --version        Show package version\n"
-               "     --cert=CERT.PEM  Specify server certificate in PEM format\n"
-               "     --key=KEY.PEM    Specify server key in PEM format\n",
+               "     --cert=CERT.PEM  Server certificate in PEM format\n"
+               "     --key=KEY.PEM    Server key in PEM format\n"
+               "     --trust=CERT.PEM Certificat authority certificate in PEM format\n",
                program_invocation_short_name);
-
-        return 0;
 }
 
-static char *key_pem = NULL;
-static char *cert_pem = NULL;
-
 static int parse_argv(int argc, char *argv[]) {
         enum {
                 ARG_VERSION = 0x100,
                 ARG_KEY,
                 ARG_CERT,
+                ARG_TRUST,
         };
 
         int r, c;
@@ -924,6 +883,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "version", no_argument,       NULL, ARG_VERSION },
                 { "key",     required_argument, NULL, ARG_KEY     },
                 { "cert",    required_argument, NULL, ARG_CERT    },
+                { "trust",   required_argument, NULL, ARG_TRUST   },
                 {}
         };
 
@@ -935,7 +895,8 @@ static int parse_argv(int argc, char *argv[]) {
                 switch(c) {
 
                 case 'h':
-                        return help();
+                        help();
+                        return 0;
 
                 case ARG_VERSION:
                         puts(PACKAGE_STRING);
@@ -968,6 +929,23 @@ static int parse_argv(int argc, char *argv[]) {
                         assert(cert_pem);
                         break;
 
+                case ARG_TRUST:
+#ifdef HAVE_GNUTLS
+                        if (trust_pem) {
+                                log_error("CA certificate file specified twice");
+                                return -EINVAL;
+                        }
+                        r = read_full_file(optarg, &trust_pem, NULL);
+                        if (r < 0) {
+                                log_error("Failed to read CA certificate file: %s", strerror(-r));
+                                return r;
+                        }
+                        assert(trust_pem);
+                        break;
+#else
+                        log_error("Option --trust is not available.");
+#endif
+
                 case '?':
                         return -EINVAL;
 
@@ -985,6 +963,11 @@ static int parse_argv(int argc, char *argv[]) {
                 return -EINVAL;
         }
 
+        if (trust_pem && !key_pem) {
+                log_error("CA certificate can only be used with certificate file");
+                return -EINVAL;
+        }
+
         return 1;
 }
 
@@ -1002,6 +985,11 @@ int main(int argc, char *argv[]) {
         if (r == 0)
                 return EXIT_SUCCESS;
 
+#ifdef HAVE_GNUTLS
+        gnutls_global_set_log_function(log_func_gnutls);
+        log_reset_gnutls_level();
+#endif
+
         n = sd_listen_fds(1);
         if (n < 0) {
                 log_error("Failed to determine passed sockets: %s", strerror(-n));
@@ -1018,6 +1006,7 @@ int main(int argc, char *argv[]) {
                         { MHD_OPTION_END, 0, NULL },
                         { MHD_OPTION_END, 0, NULL },
                         { MHD_OPTION_END, 0, NULL },
+                        { MHD_OPTION_END, 0, NULL },
                         { MHD_OPTION_END, 0, NULL }};
                 int opts_pos = 2;
                 int flags = MHD_USE_THREAD_PER_CONNECTION|MHD_USE_POLL|MHD_USE_DEBUG;
@@ -1033,6 +1022,11 @@ int main(int argc, char *argv[]) {
                                 {MHD_OPTION_HTTPS_MEM_CERT, 0, cert_pem};
                         flags |= MHD_USE_SSL;
                 }
+                if (trust_pem) {
+                        assert(flags & MHD_USE_SSL);
+                        opts[opts_pos++] = (struct MHD_OptionItem)
+                                {MHD_OPTION_HTTPS_MEM_TRUST, 0, trust_pem};
+                }
 
                 d = MHD_start_daemon(flags, 19531,
                                      NULL, NULL,
diff --git a/src/journal-remote/journal-remote-parse.c b/src/journal-remote/journal-remote-parse.c
new file mode 100644 (file)
index 0000000..dfb87d4
--- /dev/null
@@ -0,0 +1,493 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Zbigniew Jędrzejewski-Szmek
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "journal-remote-parse.h"
+#include "journald-native.h"
+
+#define LINE_CHUNK 8*1024u
+
+void source_free(RemoteSource *source) {
+        if (!source)
+                return;
+
+        if (source->fd >= 0 && !source->passive_fd) {
+                log_debug("Closing fd:%d (%s)", source->fd, source->name);
+                safe_close(source->fd);
+        }
+
+        free(source->name);
+        free(source->buf);
+        iovw_free_contents(&source->iovw);
+
+        log_debug("Writer ref count %u", source->writer->n_ref);
+        writer_unref(source->writer);
+
+        sd_event_source_unref(source->event);
+
+        free(source);
+}
+
+/**
+ * Initialize zero-filled source with given values. On success, takes
+ * ownerhship of fd and writer, otherwise does not touch them.
+ */
+RemoteSource* source_new(int fd, bool passive_fd, char *name, Writer *writer) {
+
+        RemoteSource *source;
+
+        log_debug("Creating source for %sfd:%d (%s)",
+                  passive_fd ? "passive " : "", fd, name);
+
+        assert(fd >= 0);
+
+        source = new0(RemoteSource, 1);
+        if (!source)
+                return NULL;
+
+        source->fd = fd;
+        source->passive_fd = passive_fd;
+        source->name = name;
+        source->writer = writer;
+
+        return source;
+}
+
+static char* realloc_buffer(RemoteSource *source, size_t size) {
+        char *b, *old = source->buf;
+
+        b = GREEDY_REALLOC(source->buf, source->size, size);
+        if (!b)
+                return NULL;
+
+        iovw_rebase(&source->iovw, old, source->buf);
+
+        return b;
+}
+
+static int get_line(RemoteSource *source, char **line, size_t *size) {
+        ssize_t n;
+        char *c = NULL;
+
+        assert(source);
+        assert(source->state == STATE_LINE);
+        assert(source->offset <= source->filled);
+        assert(source->filled <= source->size);
+        assert(source->buf == NULL || source->size > 0);
+        assert(source->fd >= 0);
+
+        while (true) {
+                if (source->buf) {
+                        size_t start = MAX(source->scanned, source->offset);
+
+                        c = memchr(source->buf + start, '\n',
+                                   source->filled - start);
+                        if (c != NULL)
+                                break;
+                }
+
+                source->scanned = source->filled;
+                if (source->scanned >= DATA_SIZE_MAX) {
+                        log_error("Entry is bigger than %u bytes.", DATA_SIZE_MAX);
+                        return -E2BIG;
+                }
+
+                if (source->passive_fd)
+                        /* we have to wait for some data to come to us */
+                        return -EWOULDBLOCK;
+
+                if (source->size - source->filled < LINE_CHUNK &&
+                    !realloc_buffer(source,
+                                    MIN(source->filled + LINE_CHUNK, ENTRY_SIZE_MAX)))
+                                return log_oom();
+
+                assert(source->size - source->filled >= LINE_CHUNK ||
+                       source->size == ENTRY_SIZE_MAX);
+
+                n = read(source->fd, source->buf + source->filled,
+                         source->size - source->filled);
+                if (n < 0) {
+                        if (errno != EAGAIN && errno != EWOULDBLOCK)
+                                log_error("read(%d, ..., %zd): %m", source->fd,
+                                          source->size - source->filled);
+                        return -errno;
+                } else if (n == 0)
+                        return 0;
+
+                source->filled += n;
+        }
+
+        *line = source->buf + source->offset;
+        *size = c + 1 - source->buf - source->offset;
+        source->offset += *size;
+
+        return 1;
+}
+
+int push_data(RemoteSource *source, const char *data, size_t size) {
+        assert(source);
+        assert(source->state != STATE_EOF);
+
+        if (!realloc_buffer(source, source->filled + size)) {
+                log_error("Failed to store received data of size %zu "
+                          "(in addition to existing %zu bytes with %zu filled): %s",
+                          size, source->size, source->filled, strerror(ENOMEM));
+                return -ENOMEM;
+        }
+
+        memcpy(source->buf + source->filled, data, size);
+        source->filled += size;
+
+        return 0;
+}
+
+static int fill_fixed_size(RemoteSource *source, void **data, size_t size) {
+
+        assert(source);
+        assert(source->state == STATE_DATA_START ||
+               source->state == STATE_DATA ||
+               source->state == STATE_DATA_FINISH);
+        assert(size <= DATA_SIZE_MAX);
+        assert(source->offset <= source->filled);
+        assert(source->filled <= source->size);
+        assert(source->buf != NULL || source->size == 0);
+        assert(source->buf == NULL || source->size > 0);
+        assert(source->fd >= 0);
+        assert(data);
+
+        while (source->filled - source->offset < size) {
+                int n;
+
+                if (source->passive_fd)
+                        /* we have to wait for some data to come to us */
+                        return -EWOULDBLOCK;
+
+                if (!realloc_buffer(source, source->offset + size))
+                        return log_oom();
+
+                n = read(source->fd, source->buf + source->filled,
+                         source->size - source->filled);
+                if (n < 0) {
+                        if (errno != EAGAIN && errno != EWOULDBLOCK)
+                                log_error("read(%d, ..., %zd): %m", source->fd,
+                                          source->size - source->filled);
+                        return -errno;
+                } else if (n == 0)
+                        return 0;
+
+                source->filled += n;
+        }
+
+        *data = source->buf + source->offset;
+        source->offset += size;
+
+        return 1;
+}
+
+static int get_data_size(RemoteSource *source) {
+        int r;
+        void *data;
+
+        assert(source);
+        assert(source->state == STATE_DATA_START);
+        assert(source->data_size == 0);
+
+        r = fill_fixed_size(source, &data, sizeof(uint64_t));
+        if (r <= 0)
+                return r;
+
+        source->data_size = le64toh( *(uint64_t *) data );
+        if (source->data_size > DATA_SIZE_MAX) {
+                log_error("Stream declares field with size %zu > DATA_SIZE_MAX = %u",
+                          source->data_size, DATA_SIZE_MAX);
+                return -EINVAL;
+        }
+        if (source->data_size == 0)
+                log_warning("Binary field with zero length");
+
+        return 1;
+}
+
+static int get_data_data(RemoteSource *source, void **data) {
+        int r;
+
+        assert(source);
+        assert(data);
+        assert(source->state == STATE_DATA);
+
+        r = fill_fixed_size(source, data, source->data_size);
+        if (r <= 0)
+                return r;
+
+        return 1;
+}
+
+static int get_data_newline(RemoteSource *source) {
+        int r;
+        char *data;
+
+        assert(source);
+        assert(source->state == STATE_DATA_FINISH);
+
+        r = fill_fixed_size(source, (void**) &data, 1);
+        if (r <= 0)
+                return r;
+
+        assert(data);
+        if (*data != '\n') {
+                log_error("expected newline, got '%c'", *data);
+                return -EINVAL;
+        }
+
+        return 1;
+}
+
+static int process_dunder(RemoteSource *source, char *line, size_t n) {
+        const char *timestamp;
+        int r;
+
+        assert(line);
+        assert(n > 0);
+        assert(line[n-1] == '\n');
+
+        /* XXX: is it worth to support timestamps in extended format?
+         * We don't produce them, but who knows... */
+
+        timestamp = startswith(line, "__CURSOR=");
+        if (timestamp)
+                /* ignore __CURSOR */
+                return 1;
+
+        timestamp = startswith(line, "__REALTIME_TIMESTAMP=");
+        if (timestamp) {
+                long long unsigned x;
+                line[n-1] = '\0';
+                r = safe_atollu(timestamp, &x);
+                if (r < 0)
+                        log_warning("Failed to parse __REALTIME_TIMESTAMP: '%s'", timestamp);
+                else
+                        source->ts.realtime = x;
+                return r < 0 ? r : 1;
+        }
+
+        timestamp = startswith(line, "__MONOTONIC_TIMESTAMP=");
+        if (timestamp) {
+                long long unsigned x;
+                line[n-1] = '\0';
+                r = safe_atollu(timestamp, &x);
+                if (r < 0)
+                        log_warning("Failed to parse __MONOTONIC_TIMESTAMP: '%s'", timestamp);
+                else
+                        source->ts.monotonic = x;
+                return r < 0 ? r : 1;
+        }
+
+        timestamp = startswith(line, "__");
+        if (timestamp) {
+                log_notice("Unknown dunder line %s", line);
+                return 1;
+        }
+
+        /* no dunder */
+        return 0;
+}
+
+int process_data(RemoteSource *source) {
+        int r;
+
+        switch(source->state) {
+        case STATE_LINE: {
+                char *line, *sep;
+                size_t n;
+
+                assert(source->data_size == 0);
+
+                r = get_line(source, &line, &n);
+                if (r < 0)
+                        return r;
+                if (r == 0) {
+                        source->state = STATE_EOF;
+                        return r;
+                }
+                assert(n > 0);
+                assert(line[n-1] == '\n');
+
+                if (n == 1) {
+                        log_debug("Received empty line, event is ready");
+                        return 1;
+                }
+
+                r = process_dunder(source, line, n);
+                if (r != 0)
+                        return r < 0 ? r : 0;
+
+                /* MESSAGE=xxx\n
+                   or
+                   COREDUMP\n
+                   LLLLLLLL0011223344...\n
+                */
+                sep = memchr(line, '=', n);
+                if (sep)
+                        /* chomp newline */
+                        n--;
+                else
+                        /* replace \n with = */
+                        line[n-1] = '=';
+                log_debug("Received: %.*s", (int) n, line);
+
+                r = iovw_put(&source->iovw, line, n);
+                if (r < 0) {
+                        log_error("Failed to put line in iovect");
+                        return r;
+                }
+
+                if (!sep)
+                        source->state = STATE_DATA_START;
+                return 0; /* continue */
+        }
+
+        case STATE_DATA_START:
+                assert(source->data_size == 0);
+
+                r = get_data_size(source);
+                log_debug("get_data_size() -> %d", r);
+                if (r < 0)
+                        return r;
+                if (r == 0) {
+                        source->state = STATE_EOF;
+                        return 0;
+                }
+
+                source->state = source->data_size > 0 ?
+                        STATE_DATA : STATE_DATA_FINISH;
+
+                return 0; /* continue */
+
+        case STATE_DATA: {
+                void *data;
+
+                assert(source->data_size > 0);
+
+                r = get_data_data(source, &data);
+                log_debug("get_data_data() -> %d", r);
+                if (r < 0)
+                        return r;
+                if (r == 0) {
+                        source->state = STATE_EOF;
+                        return 0;
+                }
+
+                assert(data);
+
+                r = iovw_put(&source->iovw, data, source->data_size);
+                if (r < 0) {
+                        log_error("failed to put binary buffer in iovect");
+                        return r;
+                }
+
+                source->state = STATE_DATA_FINISH;
+
+                return 0; /* continue */
+        }
+
+        case STATE_DATA_FINISH:
+                r = get_data_newline(source);
+                log_debug("get_data_newline() -> %d", r);
+                if (r < 0)
+                        return r;
+                if (r == 0) {
+                        source->state = STATE_EOF;
+                        return 0;
+                }
+
+                source->data_size = 0;
+                source->state = STATE_LINE;
+
+                return 0; /* continue */
+        default:
+                assert_not_reached("wtf?");
+        }
+}
+
+int process_source(RemoteSource *source, bool compress, bool seal) {
+        size_t remain, target;
+        int r;
+
+        assert(source);
+        assert(source->writer);
+
+        r = process_data(source);
+        if (r <= 0)
+                return r;
+
+        /* We have a full event */
+        log_debug("Received a full event from source@%p fd:%d (%s)",
+                  source, source->fd, source->name);
+
+        if (!source->iovw.count) {
+                log_warning("Entry with no payload, skipping");
+                goto freeing;
+        }
+
+        assert(source->iovw.iovec);
+        assert(source->iovw.count);
+
+        r = writer_write(source->writer, &source->iovw, &source->ts, compress, seal);
+        if (r < 0)
+                log_error("Failed to write entry of %zu bytes: %s",
+                          iovw_size(&source->iovw), strerror(-r));
+        else
+                r = 1;
+
+ freeing:
+        iovw_free_contents(&source->iovw);
+
+        /* possibly reset buffer position */
+        remain = source->filled - source->offset;
+
+        if (remain == 0) /* no brainer */
+                source->offset = source->scanned = source->filled = 0;
+        else if (source->offset > source->size - source->filled &&
+                 source->offset > remain) {
+                memcpy(source->buf, source->buf + source->offset, remain);
+                source->offset = source->scanned = 0;
+                source->filled = remain;
+        }
+
+        target = source->size;
+        while (target > 16 * LINE_CHUNK && remain < target / 2)
+                target /= 2;
+        if (target < source->size) {
+                char *tmp;
+
+                tmp = realloc(source->buf, target);
+                if (tmp)
+                        log_warning("Failed to reallocate buffer to (smaller) size %zu",
+                                    target);
+                else {
+                        log_debug("Reallocated buffer from %zu to %zu bytes",
+                                  source->size, target);
+                        source->buf = tmp;
+                        source->size = target;
+                }
+        }
+
+        return r;
+}
diff --git a/src/journal-remote/journal-remote-parse.h b/src/journal-remote/journal-remote-parse.h
new file mode 100644 (file)
index 0000000..8499f4e
--- /dev/null
@@ -0,0 +1,68 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Zbigniew Jędrzejewski-Szmek
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#pragma once
+
+#include "sd-event.h"
+#include "journal-remote-write.h"
+
+typedef enum {
+        STATE_LINE = 0,    /* waiting to read, or reading line */
+        STATE_DATA_START,  /* reading binary data header */
+        STATE_DATA,        /* reading binary data */
+        STATE_DATA_FINISH, /* expecting newline */
+        STATE_EOF,         /* done */
+} source_state;
+
+typedef struct RemoteSource {
+        char *name;
+        int fd;
+        bool passive_fd;
+
+        char *buf;
+        size_t size;       /* total size of the buffer */
+        size_t offset;     /* offset to the beginning of live data in the buffer */
+        size_t scanned;    /* number of bytes since the beginning of data without a newline */
+        size_t filled;     /* total number of bytes in the buffer */
+        size_t data_size;  /* size of the binary data chunk being processed */
+
+        struct iovec_wrapper iovw;
+
+        source_state state;
+        dual_timestamp ts;
+
+        Writer *writer;
+
+        sd_event_source *event;
+} RemoteSource;
+
+RemoteSource* source_new(int fd, bool passive_fd, char *name, Writer *writer);
+
+static inline size_t source_non_empty(RemoteSource *source) {
+        assert(source);
+
+        return source->filled;
+}
+
+void source_free(RemoteSource *source);
+int process_data(RemoteSource *source);
+int push_data(RemoteSource *source, const char *data, size_t size);
+int process_source(RemoteSource *source, bool compress, bool seal);
diff --git a/src/journal-remote/journal-remote-write.c b/src/journal-remote/journal-remote-write.c
new file mode 100644 (file)
index 0000000..8ede950
--- /dev/null
@@ -0,0 +1,168 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Zbigniew Jędrzejewski-Szmek
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "journal-remote.h"
+
+int iovw_put(struct iovec_wrapper *iovw, void* data, size_t len) {
+        if (!GREEDY_REALLOC(iovw->iovec, iovw->size_bytes, iovw->count + 1))
+                return log_oom();
+
+        iovw->iovec[iovw->count++] = (struct iovec) {data, len};
+        return 0;
+}
+
+void iovw_free_contents(struct iovec_wrapper *iovw) {
+        free(iovw->iovec);
+        iovw->iovec = NULL;
+        iovw->size_bytes = iovw->count = 0;
+}
+
+size_t iovw_size(struct iovec_wrapper *iovw) {
+        size_t n = 0, i;
+
+        for (i = 0; i < iovw->count; i++)
+                n += iovw->iovec[i].iov_len;
+
+        return n;
+}
+
+void iovw_rebase(struct iovec_wrapper *iovw, char *old, char *new) {
+        size_t i;
+
+        for (i = 0; i < iovw->count; i++)
+                iovw->iovec[i].iov_base = (char*) iovw->iovec[i].iov_base - old + new;
+}
+
+/**********************************************************************
+ **********************************************************************
+ **********************************************************************/
+
+static int do_rotate(JournalFile **f, bool compress, bool seal) {
+        int r = journal_file_rotate(f, compress, seal);
+        if (r < 0) {
+                if (*f)
+                        log_error("Failed to rotate %s: %s", (*f)->path,
+                                  strerror(-r));
+                else
+                        log_error("Failed to create rotated journal: %s",
+                                  strerror(-r));
+        }
+
+        return r;
+}
+
+Writer* writer_new(RemoteServer *server) {
+        Writer *w;
+
+        w = new0(Writer, 1);
+        if (!w)
+                return NULL;
+
+        memset(&w->metrics, 0xFF, sizeof(w->metrics));
+
+        w->mmap = mmap_cache_new();
+        if (!w->mmap) {
+                free(w);
+                return NULL;
+        }
+
+        w->n_ref = 1;
+        w->server = server;
+
+        return w;
+}
+
+Writer* writer_free(Writer *w) {
+        if (!w)
+                return NULL;
+
+        if (w->journal) {
+                log_debug("Closing journal file %s.", w->journal->path);
+                journal_file_close(w->journal);
+        }
+
+        if (w->server) {
+                w->server->event_count += w->seqnum;
+                if (w->hashmap_key)
+                        hashmap_remove(w->server->writers, w->hashmap_key);
+        }
+
+        free(w->hashmap_key);
+
+        if (w->mmap)
+                mmap_cache_unref(w->mmap);
+
+        free(w);
+
+        return NULL;
+}
+
+Writer* writer_unref(Writer *w) {
+        if (w && (-- w->n_ref <= 0))
+                writer_free(w);
+
+        return NULL;
+}
+
+Writer* writer_ref(Writer *w) {
+        if (w)
+                assert_se(++ w->n_ref >= 2);
+
+        return w;
+}
+
+
+int writer_write(Writer *s,
+                 struct iovec_wrapper *iovw,
+                 dual_timestamp *ts,
+                 bool compress,
+                 bool seal) {
+        int r;
+
+        assert(s);
+        assert(iovw);
+        assert(iovw->count > 0);
+
+        if (journal_file_rotate_suggested(s->journal, 0)) {
+                log_info("%s: Journal header limits reached or header out-of-date, rotating",
+                         s->journal->path);
+                r = do_rotate(&s->journal, compress, seal);
+                if (r < 0)
+                        return r;
+        }
+
+        r = journal_file_append_entry(s->journal, ts, iovw->iovec, iovw->count,
+                                      &s->seqnum, NULL, NULL);
+        if (r >= 0)
+                return 1;
+
+        log_debug("%s: Write failed, rotating: %s", s->journal->path, strerror(-r));
+        r = do_rotate(&s->journal, compress, seal);
+        if (r < 0)
+                return r;
+        else
+                log_info("%s: Successfully rotated journal", s->journal->path);
+
+        log_debug("Retrying write.");
+        r = journal_file_append_entry(s->journal, ts, iovw->iovec, iovw->count,
+                                      &s->seqnum, NULL, NULL);
+        return r < 0 ? r : 1;
+}
diff --git a/src/journal-remote/journal-remote-write.h b/src/journal-remote/journal-remote-write.h
new file mode 100644 (file)
index 0000000..aa381c6
--- /dev/null
@@ -0,0 +1,74 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Zbigniew Jędrzejewski-Szmek
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#pragma once
+
+#include <stdlib.h>
+
+#include "journal-file.h"
+
+typedef struct RemoteServer RemoteServer;
+
+struct iovec_wrapper {
+        struct iovec *iovec;
+        size_t size_bytes;
+        size_t count;
+};
+
+int iovw_put(struct iovec_wrapper *iovw, void* data, size_t len);
+void iovw_free_contents(struct iovec_wrapper *iovw);
+size_t iovw_size(struct iovec_wrapper *iovw);
+void iovw_rebase(struct iovec_wrapper *iovw, char *old, char *new);
+
+typedef struct Writer {
+        JournalFile *journal;
+        JournalMetrics metrics;
+
+        MMapCache *mmap;
+        RemoteServer *server;
+        char *hashmap_key;
+
+        uint64_t seqnum;
+
+        int n_ref;
+} Writer;
+
+Writer* writer_new(RemoteServer* server);
+Writer* writer_free(Writer *w);
+
+Writer* writer_ref(Writer *w);
+Writer* writer_unref(Writer *w);
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(Writer*, writer_unref);
+#define _cleanup_writer_unref_ _cleanup_(writer_unrefp)
+
+int writer_write(Writer *s,
+                 struct iovec_wrapper *iovw,
+                 dual_timestamp *ts,
+                 bool compress,
+                 bool seal);
+
+typedef enum JournalWriteSplitMode {
+        JOURNAL_WRITE_SPLIT_NONE,
+        JOURNAL_WRITE_SPLIT_HOST,
+        _JOURNAL_WRITE_SPLIT_MAX,
+        _JOURNAL_WRITE_SPLIT_INVALID = -1
+} JournalWriteSplitMode;
diff --git a/src/journal-remote/journal-remote.c b/src/journal-remote/journal-remote.c
new file mode 100644 (file)
index 0000000..aa659d1
--- /dev/null
@@ -0,0 +1,1544 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Zbigniew Jędrzejewski-Szmek
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/prctl.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <getopt.h>
+
+#include "sd-daemon.h"
+#include "journal-file.h"
+#include "journald-native.h"
+#include "socket-util.h"
+#include "mkdir.h"
+#include "build.h"
+#include "macro.h"
+#include "strv.h"
+#include "fileio.h"
+#include "conf-parser.h"
+#include "siphash24.h"
+
+#ifdef HAVE_GNUTLS
+#include <gnutls/gnutls.h>
+#endif
+
+#include "journal-remote.h"
+#include "journal-remote-write.h"
+
+#define REMOTE_JOURNAL_PATH "/var/log/journal/remote"
+
+#define PRIV_KEY_FILE CERTIFICATE_ROOT "/private/journal-remote.pem"
+#define CERT_FILE     CERTIFICATE_ROOT "/certs/journal-remote.pem"
+#define TRUST_FILE    CERTIFICATE_ROOT "/ca/trusted.pem"
+
+static char* arg_url = NULL;
+static char* arg_getter = NULL;
+static char* arg_listen_raw = NULL;
+static char* arg_listen_http = NULL;
+static char* arg_listen_https = NULL;
+static char** arg_files = NULL;
+static int arg_compress = true;
+static int arg_seal = false;
+static int http_socket = -1, https_socket = -1;
+static char** arg_gnutls_log = NULL;
+
+static JournalWriteSplitMode arg_split_mode = JOURNAL_WRITE_SPLIT_HOST;
+static char* arg_output = NULL;
+
+static char *arg_key = NULL;
+static char *arg_cert = NULL;
+static char *arg_trust = NULL;
+static bool arg_trust_all = false;
+
+/**********************************************************************
+ **********************************************************************
+ **********************************************************************/
+
+static int spawn_child(const char* child, char** argv) {
+        int fd[2];
+        pid_t parent_pid, child_pid;
+        int r;
+
+        if (pipe(fd) < 0) {
+                log_error("Failed to create pager pipe: %m");
+                return -errno;
+        }
+
+        parent_pid = getpid();
+
+        child_pid = fork();
+        if (child_pid < 0) {
+                r = -errno;
+                log_error("Failed to fork: %m");
+                safe_close_pair(fd);
+                return r;
+        }
+
+        /* In the child */
+        if (child_pid == 0) {
+                r = dup2(fd[1], STDOUT_FILENO);
+                if (r < 0) {
+                        log_error("Failed to dup pipe to stdout: %m");
+                        _exit(EXIT_FAILURE);
+                }
+
+                safe_close_pair(fd);
+
+                /* Make sure the child goes away when the parent dies */
+                if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
+                        _exit(EXIT_FAILURE);
+
+                /* Check whether our parent died before we were able
+                 * to set the death signal */
+                if (getppid() != parent_pid)
+                        _exit(EXIT_SUCCESS);
+
+                execvp(child, argv);
+                log_error("Failed to exec child %s: %m", child);
+                _exit(EXIT_FAILURE);
+        }
+
+        r = close(fd[1]);
+        if (r < 0)
+                log_warning("Failed to close write end of pipe: %m");
+
+        return fd[0];
+}
+
+static int spawn_curl(const char* url) {
+        char **argv = STRV_MAKE("curl",
+                                "-HAccept: application/vnd.fdo.journal",
+                                "--silent",
+                                "--show-error",
+                                url);
+        int r;
+
+        r = spawn_child("curl", argv);
+        if (r < 0)
+                log_error("Failed to spawn curl: %m");
+        return r;
+}
+
+static int spawn_getter(const char *getter, const char *url) {
+        int r;
+        _cleanup_strv_free_ char **words = NULL;
+
+        assert(getter);
+        r = strv_split_quoted(&words, getter);
+        if (r < 0) {
+                log_error("Failed to split getter option: %s", strerror(-r));
+                return r;
+        }
+
+        r = strv_extend(&words, url);
+        if (r < 0) {
+                log_error("Failed to create command line: %s", strerror(-r));
+                return r;
+        }
+
+        r = spawn_child(words[0], words);
+        if (r < 0)
+                log_error("Failed to spawn getter %s: %m", getter);
+
+        return r;
+}
+
+#define filename_escape(s) xescape((s), "/ ")
+
+static int open_output(Writer *w, const char* host) {
+        _cleanup_free_ char *_output = NULL;
+        const char *output;
+        int r;
+
+        switch (arg_split_mode) {
+        case JOURNAL_WRITE_SPLIT_NONE:
+                output = arg_output ?: REMOTE_JOURNAL_PATH "/remote.journal";
+                break;
+
+        case JOURNAL_WRITE_SPLIT_HOST: {
+                _cleanup_free_ char *name;
+
+                assert(host);
+
+                name = filename_escape(host);
+                if (!name)
+                        return log_oom();
+
+                r = asprintf(&_output, "%s/remote-%s.journal",
+                             arg_output ?: REMOTE_JOURNAL_PATH,
+                             name);
+                if (r < 0)
+                        return log_oom();
+
+                output = _output;
+                break;
+        }
+
+        default:
+                assert_not_reached("what?");
+        }
+
+        r = journal_file_open_reliably(output,
+                                       O_RDWR|O_CREAT, 0640,
+                                       arg_compress, arg_seal,
+                                       &w->metrics,
+                                       w->mmap,
+                                       NULL, &w->journal);
+        if (r < 0)
+                log_error("Failed to open output journal %s: %s",
+                          output, strerror(-r));
+        else
+                log_info("Opened output file %s", w->journal->path);
+        return r;
+}
+
+/**********************************************************************
+ **********************************************************************
+ **********************************************************************/
+
+static int init_writer_hashmap(RemoteServer *s) {
+        static const struct {
+                hash_func_t hash_func;
+                compare_func_t compare_func;
+        } functions[] = {
+                [JOURNAL_WRITE_SPLIT_NONE] = {trivial_hash_func,
+                                              trivial_compare_func},
+                [JOURNAL_WRITE_SPLIT_HOST] = {string_hash_func,
+                                              string_compare_func},
+        };
+
+        assert(arg_split_mode >= 0 && arg_split_mode < (int) ELEMENTSOF(functions));
+
+        s->writers = hashmap_new(functions[arg_split_mode].hash_func,
+                                 functions[arg_split_mode].compare_func);
+        if (!s->writers)
+                return log_oom();
+
+        return 0;
+}
+
+static int get_writer(RemoteServer *s, const char *host,
+                      Writer **writer) {
+        const void *key;
+        _cleanup_writer_unref_ Writer *w = NULL;
+        int r;
+
+        switch(arg_split_mode) {
+        case JOURNAL_WRITE_SPLIT_NONE:
+                key = "one and only";
+                break;
+
+        case JOURNAL_WRITE_SPLIT_HOST:
+                assert(host);
+                key = host;
+                break;
+
+        default:
+                assert_not_reached("what split mode?");
+        }
+
+        w = hashmap_get(s->writers, key);
+        if (w)
+                writer_ref(w);
+        else {
+                w = writer_new(s);
+                if (!w)
+                        return log_oom();
+
+                if (arg_split_mode == JOURNAL_WRITE_SPLIT_HOST) {
+                        w->hashmap_key = strdup(key);
+                        if (!w->hashmap_key)
+                                return log_oom();
+                }
+
+                r = open_output(w, host);
+                if (r < 0)
+                        return r;
+
+                r = hashmap_put(s->writers, w->hashmap_key ?: key, w);
+                if (r < 0)
+                        return r;
+        }
+
+        *writer = w;
+        w = NULL;
+        return 0;
+}
+
+/**********************************************************************
+ **********************************************************************
+ **********************************************************************/
+
+/* This should go away as soon as µhttpd allows state to be passed around. */
+static RemoteServer *server;
+
+static int dispatch_raw_source_event(sd_event_source *event,
+                                     int fd,
+                                     uint32_t revents,
+                                     void *userdata);
+static int dispatch_raw_connection_event(sd_event_source *event,
+                                         int fd,
+                                         uint32_t revents,
+                                         void *userdata);
+static int dispatch_http_event(sd_event_source *event,
+                               int fd,
+                               uint32_t revents,
+                               void *userdata);
+
+static int get_source_for_fd(RemoteServer *s,
+                             int fd, char *name, RemoteSource **source) {
+        Writer *writer;
+        int r;
+
+        assert(fd >= 0);
+        assert(source);
+
+        if (!GREEDY_REALLOC0(s->sources, s->sources_size, fd + 1))
+                return log_oom();
+
+        r = get_writer(s, name, &writer);
+        if (r < 0) {
+                log_warning("Failed to get writer for source %s: %s",
+                            name, strerror(-r));
+                return r;
+        }
+
+        if (s->sources[fd] == NULL) {
+                s->sources[fd] = source_new(fd, false, name, writer);
+                if (!s->sources[fd]) {
+                        writer_unref(writer);
+                        return log_oom();
+                }
+
+                s->active++;
+        }
+
+        *source = s->sources[fd];
+        return 0;
+}
+
+static int remove_source(RemoteServer *s, int fd) {
+        RemoteSource *source;
+
+        assert(s);
+        assert(fd >= 0 && fd < (ssize_t) s->sources_size);
+
+        source = s->sources[fd];
+        if (source) {
+                /* this closes fd too */
+                source_free(source);
+                s->sources[fd] = NULL;
+                s->active--;
+        }
+
+        return 0;
+}
+
+static int add_source(RemoteServer *s, int fd, char* name, bool own_name) {
+
+        RemoteSource *source;
+        int r;
+
+        assert(s);
+        assert(fd >= 0);
+        assert(name);
+
+        if (!own_name) {
+                name = strdup(name);
+                if (!name)
+                        return log_oom();
+        }
+
+        r = get_source_for_fd(s, fd, name, &source);
+        if (r < 0) {
+                log_error("Failed to create source for fd:%d (%s): %s",
+                          fd, name, strerror(-r));
+                return r;
+        }
+
+        r = sd_event_add_io(s->events, &source->event,
+                            fd, EPOLLIN|EPOLLRDHUP|EPOLLPRI,
+                            dispatch_raw_source_event, s);
+        if (r < 0) {
+                log_error("Failed to register event source for fd:%d: %s",
+                          fd, strerror(-r));
+                goto error;
+        }
+
+        return 1; /* work to do */
+
+ error:
+        remove_source(s, fd);
+        return r;
+}
+
+static int add_raw_socket(RemoteServer *s, int fd) {
+        int r;
+
+        r = sd_event_add_io(s->events, &s->listen_event,
+                            fd, EPOLLIN,
+                            dispatch_raw_connection_event, s);
+        if (r < 0) {
+                close(fd);
+                return r;
+        }
+
+        s->active ++;
+        return 0;
+}
+
+static int setup_raw_socket(RemoteServer *s, const char *address) {
+        int fd;
+
+        fd = make_socket_fd(LOG_INFO, address, SOCK_STREAM | SOCK_CLOEXEC);
+        if (fd < 0)
+                return fd;
+
+        return add_raw_socket(s, fd);
+}
+
+/**********************************************************************
+ **********************************************************************
+ **********************************************************************/
+
+static RemoteSource *request_meta(void **connection_cls, int fd, char *hostname) {
+        RemoteSource *source;
+        Writer *writer;
+        int r;
+
+        assert(connection_cls);
+        if (*connection_cls)
+                return *connection_cls;
+
+        r = get_writer(server, hostname, &writer);
+        if (r < 0) {
+                log_warning("Failed to get writer for source %s: %s",
+                            hostname, strerror(-r));
+                return NULL;
+        }
+
+        source = source_new(fd, true, hostname, writer);
+        if (!source) {
+                log_oom();
+                writer_unref(writer);
+                return NULL;
+        }
+
+        log_debug("Added RemoteSource as connection metadata %p", source);
+
+        *connection_cls = source;
+        return source;
+}
+
+static void request_meta_free(void *cls,
+                              struct MHD_Connection *connection,
+                              void **connection_cls,
+                              enum MHD_RequestTerminationCode toe) {
+        RemoteSource *s;
+
+        assert(connection_cls);
+        s = *connection_cls;
+
+        log_debug("Cleaning up connection metadata %p", s);
+        source_free(s);
+        *connection_cls = NULL;
+}
+
+static int process_http_upload(
+                struct MHD_Connection *connection,
+                const char *upload_data,
+                size_t *upload_data_size,
+                RemoteSource *source) {
+
+        bool finished = false;
+        size_t remaining;
+        int r;
+
+        assert(source);
+
+        log_debug("request_handler_upload: connection %p, %zu bytes",
+                  connection, *upload_data_size);
+
+        if (*upload_data_size) {
+                log_debug("Received %zu bytes", *upload_data_size);
+
+                r = push_data(source, upload_data, *upload_data_size);
+                if (r < 0)
+                        return mhd_respond_oom(connection);
+
+                *upload_data_size = 0;
+        } else
+                finished = true;
+
+        while (true) {
+                r = process_source(source, arg_compress, arg_seal);
+                if (r == -EAGAIN || r == -EWOULDBLOCK)
+                        break;
+                else if (r < 0) {
+                        log_warning("Failed to process data for connection %p", connection);
+                        if (r == -E2BIG)
+                                return mhd_respondf(connection,
+                                                    MHD_HTTP_REQUEST_ENTITY_TOO_LARGE,
+                                                    "Entry is too large, maximum is %u bytes.\n",
+                                                    DATA_SIZE_MAX);
+                        else
+                                return mhd_respondf(connection,
+                                                    MHD_HTTP_UNPROCESSABLE_ENTITY,
+                                                    "Processing failed: %s.", strerror(-r));
+                }
+        }
+
+        if (!finished)
+                return MHD_YES;
+
+        /* The upload is finished */
+
+        remaining = source_non_empty(source);
+        if (remaining > 0) {
+                log_warning("Premature EOFbyte. %zu bytes lost.", remaining);
+                return mhd_respondf(connection, MHD_HTTP_EXPECTATION_FAILED,
+                                    "Premature EOF. %zu bytes of trailing data not processed.",
+                                    remaining);
+        }
+
+        return mhd_respond(connection, MHD_HTTP_ACCEPTED, "OK.\n");
+};
+
+static int request_handler(
+                void *cls,
+                struct MHD_Connection *connection,
+                const char *url,
+                const char *method,
+                const char *version,
+                const char *upload_data,
+                size_t *upload_data_size,
+                void **connection_cls) {
+
+        const char *header;
+        int r, code, fd;
+        _cleanup_free_ char *hostname = NULL;
+
+        assert(connection);
+        assert(connection_cls);
+        assert(url);
+        assert(method);
+
+        log_debug("Handling a connection %s %s %s", method, url, version);
+
+        if (*connection_cls)
+                return process_http_upload(connection,
+                                           upload_data, upload_data_size,
+                                           *connection_cls);
+
+        if (!streq(method, "POST"))
+                return mhd_respond(connection, MHD_HTTP_METHOD_NOT_ACCEPTABLE,
+                                   "Unsupported method.\n");
+
+        if (!streq(url, "/upload"))
+                return mhd_respond(connection, MHD_HTTP_NOT_FOUND,
+                                   "Not found.\n");
+
+        header = MHD_lookup_connection_value(connection,
+                                             MHD_HEADER_KIND, "Content-Type");
+        if (!header || !streq(header, "application/vnd.fdo.journal"))
+                return mhd_respond(connection, MHD_HTTP_UNSUPPORTED_MEDIA_TYPE,
+                                   "Content-Type: application/vnd.fdo.journal"
+                                   " is required.\n");
+
+        {
+                const union MHD_ConnectionInfo *ci;
+
+                ci = MHD_get_connection_info(connection,
+                                             MHD_CONNECTION_INFO_CONNECTION_FD);
+                if (!ci) {
+                        log_error("MHD_get_connection_info failed: cannot get remote fd");
+                        return mhd_respond(connection, MHD_HTTP_INTERNAL_SERVER_ERROR,
+                                           "Cannot check remote address");
+                        return code;
+                }
+
+                fd = ci->connect_fd;
+                assert(fd >= 0);
+        }
+
+        if (server->check_trust) {
+                r = check_permissions(connection, &code, &hostname);
+                if (r < 0)
+                        return code;
+        } else {
+                r = getnameinfo_pretty(fd, &hostname);
+                if (r < 0) {
+                        return mhd_respond(connection, MHD_HTTP_INTERNAL_SERVER_ERROR,
+                                           "Cannot check remote hostname");
+                }
+        }
+
+        assert(hostname);
+
+        if (!request_meta(connection_cls, fd, hostname))
+                return respond_oom(connection);
+        hostname = NULL;
+        return MHD_YES;
+}
+
+static int setup_microhttpd_server(RemoteServer *s,
+                                   int fd,
+                                   const char *key,
+                                   const char *cert,
+                                   const char *trust) {
+        struct MHD_OptionItem opts[] = {
+                { MHD_OPTION_NOTIFY_COMPLETED, (intptr_t) request_meta_free},
+                { MHD_OPTION_EXTERNAL_LOGGER, (intptr_t) microhttpd_logger},
+                { MHD_OPTION_LISTEN_SOCKET, fd},
+                { MHD_OPTION_END},
+                { MHD_OPTION_END},
+                { MHD_OPTION_END},
+                { MHD_OPTION_END}};
+        int opts_pos = 3;
+        int flags =
+                MHD_USE_DEBUG |
+                MHD_USE_PEDANTIC_CHECKS |
+                MHD_USE_EPOLL_LINUX_ONLY |
+                MHD_USE_DUAL_STACK;
+
+        const union MHD_DaemonInfo *info;
+        int r, epoll_fd;
+        MHDDaemonWrapper *d;
+
+        assert(fd >= 0);
+
+        r = fd_nonblock(fd, true);
+        if (r < 0) {
+                log_error("Failed to make fd:%d nonblocking: %s", fd, strerror(-r));
+                return r;
+        }
+
+        if (key) {
+                assert(cert);
+
+                opts[opts_pos++] = (struct MHD_OptionItem)
+                        {MHD_OPTION_HTTPS_MEM_KEY, 0, (char*) key};
+                opts[opts_pos++] = (struct MHD_OptionItem)
+                        {MHD_OPTION_HTTPS_MEM_CERT, 0, (char*) cert};
+
+                flags |= MHD_USE_SSL;
+
+                if (trust)
+                        opts[opts_pos++] = (struct MHD_OptionItem)
+                                {MHD_OPTION_HTTPS_MEM_TRUST, 0, (char*) trust};
+        }
+
+        d = new(MHDDaemonWrapper, 1);
+        if (!d)
+                return log_oom();
+
+        d->fd = (uint64_t) fd;
+
+        d->daemon = MHD_start_daemon(flags, 0,
+                                     NULL, NULL,
+                                     request_handler, NULL,
+                                     MHD_OPTION_ARRAY, opts,
+                                     MHD_OPTION_END);
+        if (!d->daemon) {
+                log_error("Failed to start µhttp daemon");
+                r = -EINVAL;
+                goto error;
+        }
+
+        log_debug("Started MHD %s daemon on fd:%d (wrapper @ %p)",
+                  key ? "HTTPS" : "HTTP", fd, d);
+
+
+        info = MHD_get_daemon_info(d->daemon, MHD_DAEMON_INFO_EPOLL_FD_LINUX_ONLY);
+        if (!info) {
+                log_error("µhttp returned NULL daemon info");
+                r = -ENOTSUP;
+                goto error;
+        }
+
+        epoll_fd = info->listen_fd;
+        if (epoll_fd < 0) {
+                log_error("µhttp epoll fd is invalid");
+                r = -EUCLEAN;
+                goto error;
+        }
+
+        r = sd_event_add_io(s->events, &d->event,
+                            epoll_fd, EPOLLIN,
+                            dispatch_http_event, d);
+        if (r < 0) {
+                log_error("Failed to add event callback: %s", strerror(-r));
+                goto error;
+        }
+
+        r = hashmap_ensure_allocated(&s->daemons, uint64_hash_func, uint64_compare_func);
+        if (r < 0) {
+                log_oom();
+                goto error;
+        }
+
+        r = hashmap_put(s->daemons, &d->fd, d);
+        if (r < 0) {
+                log_error("Failed to add daemon to hashmap: %s", strerror(-r));
+                goto error;
+        }
+
+        s->active ++;
+        return 0;
+
+error:
+        MHD_stop_daemon(d->daemon);
+        free(d->daemon);
+        free(d);
+        return r;
+}
+
+static int setup_microhttpd_socket(RemoteServer *s,
+                                   const char *address,
+                                   const char *key,
+                                   const char *cert,
+                                   const char *trust) {
+        int fd;
+
+        fd = make_socket_fd(LOG_INFO, address, SOCK_STREAM | SOCK_CLOEXEC);
+        if (fd < 0)
+                return fd;
+
+        return setup_microhttpd_server(s, fd, key, cert, trust);
+}
+
+static int dispatch_http_event(sd_event_source *event,
+                               int fd,
+                               uint32_t revents,
+                               void *userdata) {
+        MHDDaemonWrapper *d = userdata;
+        int r;
+
+        assert(d);
+
+        r = MHD_run(d->daemon);
+        if (r == MHD_NO) {
+                log_error("MHD_run failed!");
+                // XXX: unregister daemon
+                return -EINVAL;
+        }
+
+        return 1; /* work to do */
+}
+
+/**********************************************************************
+ **********************************************************************
+ **********************************************************************/
+
+static int dispatch_sigterm(sd_event_source *event,
+                            const struct signalfd_siginfo *si,
+                            void *userdata) {
+        RemoteServer *s = userdata;
+
+        assert(s);
+
+        log_received_signal(LOG_INFO, si);
+
+        sd_event_exit(s->events, 0);
+        return 0;
+}
+
+static int setup_signals(RemoteServer *s) {
+        sigset_t mask;
+        int r;
+
+        assert(s);
+
+        assert_se(sigemptyset(&mask) == 0);
+        sigset_add_many(&mask, SIGINT, SIGTERM, -1);
+        assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
+
+        r = sd_event_add_signal(s->events, &s->sigterm_event, SIGTERM, dispatch_sigterm, s);
+        if (r < 0)
+                return r;
+
+        r = sd_event_add_signal(s->events, &s->sigint_event, SIGINT, dispatch_sigterm, s);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+static int fd_fd(const char *spec) {
+        int fd, r;
+
+        r = safe_atoi(spec, &fd);
+        if (r < 0)
+                return r;
+        if (fd < 0)
+                return -EINVAL;
+
+        return fd;
+}
+
+static int remoteserver_init(RemoteServer *s,
+                             const char* key,
+                             const char* cert,
+                             const char* trust) {
+        int r, n, fd;
+        char **file;
+
+        assert(s);
+
+        if ((arg_listen_raw || arg_listen_http) && trust) {
+                log_error("Option --trust makes all non-HTTPS connections untrusted.");
+                return -EINVAL;
+        }
+
+        sd_event_default(&s->events);
+
+        setup_signals(s);
+
+        assert(server == NULL);
+        server = s;
+
+        n = sd_listen_fds(true);
+        if (n < 0) {
+                log_error("Failed to read listening file descriptors from environment: %s",
+                          strerror(-n));
+                return n;
+        } else
+                log_info("Received %d descriptors", n);
+
+        if (MAX(http_socket, https_socket) >= SD_LISTEN_FDS_START + n) {
+                log_error("Received fewer sockets than expected");
+                return -EBADFD;
+        }
+
+        for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd++) {
+                if (sd_is_socket(fd, AF_UNSPEC, 0, false)) {
+                        log_info("Received a listening socket (fd:%d)", fd);
+
+                        if (fd == http_socket)
+                                r = setup_microhttpd_server(s, fd, NULL, NULL, NULL);
+                        else if (fd == https_socket)
+                                r = setup_microhttpd_server(s, fd, key, cert, trust);
+                        else
+                                r = add_raw_socket(s, fd);
+                } else if (sd_is_socket(fd, AF_UNSPEC, 0, true)) {
+                        char *hostname;
+
+                        r = getnameinfo_pretty(fd, &hostname);
+                        if (r < 0) {
+                                log_error("Failed to retrieve remote name: %s", strerror(-r));
+                                return r;
+                        }
+
+                        log_info("Received a connection socket (fd:%d) from %s", fd, hostname);
+
+                        r = add_source(s, fd, hostname, true);
+                        if (r < 0)
+                                free(hostname);
+                } else {
+                        log_error("Unknown socket passed on fd:%d", fd);
+
+                        return -EINVAL;
+                }
+
+                if(r < 0) {
+                        log_error("Failed to register socket (fd:%d): %s",
+                                  fd, strerror(-r));
+                        return r;
+                }
+        }
+
+        if (arg_url) {
+                const char *url, *hostname;
+
+                url = strappenda(arg_url, "/entries");
+
+                if (arg_getter) {
+                        log_info("Spawning getter %s...", url);
+                        fd = spawn_getter(arg_getter, url);
+                } else {
+                        log_info("Spawning curl %s...", url);
+                        fd = spawn_curl(url);
+                }
+                if (fd < 0)
+                        return fd;
+
+                hostname =
+                        startswith(arg_url, "https://") ?:
+                        startswith(arg_url, "http://") ?:
+                        arg_url;
+
+                r = add_source(s, fd, (char*) hostname, false);
+                if (r < 0)
+                        return r;
+        }
+
+        if (arg_listen_raw) {
+                log_info("Listening on a socket...");
+                r = setup_raw_socket(s, arg_listen_raw);
+                if (r < 0)
+                        return r;
+        }
+
+        if (arg_listen_http) {
+                r = setup_microhttpd_socket(s, arg_listen_http, NULL, NULL, NULL);
+                if (r < 0)
+                        return r;
+        }
+
+        if (arg_listen_https) {
+                r = setup_microhttpd_socket(s, arg_listen_https, key, cert, trust);
+                if (r < 0)
+                        return r;
+        }
+
+        STRV_FOREACH(file, arg_files) {
+                const char *output_name;
+
+                if (streq(*file, "-")) {
+                        log_info("Using standard input as source.");
+
+                        fd = STDIN_FILENO;
+                        output_name = "stdin";
+                } else {
+                        log_info("Reading file %s...", *file);
+
+                        fd = open(*file, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NONBLOCK);
+                        if (fd < 0) {
+                                log_error("Failed to open %s: %m", *file);
+                                return -errno;
+                        }
+                        output_name = *file;
+                }
+
+                r = add_source(s, fd, (char*) output_name, false);
+                if (r < 0)
+                        return r;
+        }
+
+        if (s->active == 0) {
+                log_error("Zarro sources specified");
+                return -EINVAL;
+        }
+
+        r = init_writer_hashmap(s);
+        if (r < 0)
+                return r;
+
+        if (arg_split_mode == JOURNAL_WRITE_SPLIT_NONE) {
+                /* In this case we know what the writer will be
+                   called, so we can create it and verify that we can
+                   create output as expected. */
+                r = get_writer(s, NULL, &s->_single_writer);
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
+static void server_destroy(RemoteServer *s) {
+        size_t i;
+        MHDDaemonWrapper *d;
+
+        while ((d = hashmap_steal_first(s->daemons))) {
+                MHD_stop_daemon(d->daemon);
+                sd_event_source_unref(d->event);
+                free(d);
+        }
+
+        hashmap_free(s->daemons);
+
+        assert(s->sources_size == 0 || s->sources);
+        for (i = 0; i < s->sources_size; i++)
+                remove_source(s, i);
+        free(s->sources);
+
+        writer_unref(s->_single_writer);
+        hashmap_free(s->writers);
+
+        sd_event_source_unref(s->sigterm_event);
+        sd_event_source_unref(s->sigint_event);
+        sd_event_source_unref(s->listen_event);
+        sd_event_unref(s->events);
+
+        /* fds that we're listening on remain open... */
+}
+
+/**********************************************************************
+ **********************************************************************
+ **********************************************************************/
+
+static int dispatch_raw_source_event(sd_event_source *event,
+                                     int fd,
+                                     uint32_t revents,
+                                     void *userdata) {
+
+        RemoteServer *s = userdata;
+        RemoteSource *source;
+        int r;
+
+        assert(fd >= 0 && fd < (ssize_t) s->sources_size);
+        source = s->sources[fd];
+        assert(source->fd == fd);
+
+        r = process_source(source, arg_compress, arg_seal);
+        if (source->state == STATE_EOF) {
+                size_t remaining;
+
+                log_info("EOF reached with source fd:%d (%s)",
+                         source->fd, source->name);
+
+                remaining = source_non_empty(source);
+                if (remaining > 0)
+                        log_warning("Premature EOF. %zu bytes lost.", remaining);
+                remove_source(s, source->fd);
+                log_info("%zd active sources remaining", s->active);
+                return 0;
+        } else if (r == -E2BIG) {
+                log_error("Entry too big, skipped");
+                return 1;
+        } else if (r == -EAGAIN) {
+                return 0;
+        } else if (r < 0) {
+                log_info("Closing connection: %s", strerror(-r));
+                remove_source(server, fd);
+                return 0;
+        } else
+                return 1;
+}
+
+static int accept_connection(const char* type, int fd,
+                             SocketAddress *addr, char **hostname) {
+        int fd2, r;
+
+        log_debug("Accepting new %s connection on fd:%d", type, fd);
+        fd2 = accept4(fd, &addr->sockaddr.sa, &addr->size, SOCK_NONBLOCK|SOCK_CLOEXEC);
+        if (fd2 < 0) {
+                log_error("accept() on fd:%d failed: %m", fd);
+                return -errno;
+        }
+
+        switch(socket_address_family(addr)) {
+        case AF_INET:
+        case AF_INET6: {
+                _cleanup_free_ char *a = NULL;
+                char *b;
+
+                r = socket_address_print(addr, &a);
+                if (r < 0) {
+                        log_error("socket_address_print(): %s", strerror(-r));
+                        close(fd2);
+                        return r;
+                }
+
+                r = socknameinfo_pretty(&addr->sockaddr, addr->size, &b);
+                if (r < 0) {
+                        close(fd2);
+                        return r;
+                }
+
+                log_info("Accepted %s %s connection from %s",
+                         type,
+                         socket_address_family(addr) == AF_INET ? "IP" : "IPv6",
+                         a);
+
+                *hostname = b;
+
+                return fd2;
+        };
+        default:
+                log_error("Rejected %s connection with unsupported family %d",
+                          type, socket_address_family(addr));
+                close(fd2);
+
+                return -EINVAL;
+        }
+}
+
+static int dispatch_raw_connection_event(sd_event_source *event,
+                                         int fd,
+                                         uint32_t revents,
+                                         void *userdata) {
+        RemoteServer *s = userdata;
+        int fd2, r;
+        SocketAddress addr = {
+                .size = sizeof(union sockaddr_union),
+                .type = SOCK_STREAM,
+        };
+        char *hostname;
+
+        fd2 = accept_connection("raw", fd, &addr, &hostname);
+        if (fd2 < 0)
+                return fd2;
+
+        r = add_source(s, fd2, hostname, true);
+        if (r < 0)
+                free(hostname);
+        return r;
+}
+
+/**********************************************************************
+ **********************************************************************
+ **********************************************************************/
+
+static const char* const journal_write_split_mode_table[_JOURNAL_WRITE_SPLIT_MAX] = {
+        [JOURNAL_WRITE_SPLIT_NONE] = "none",
+        [JOURNAL_WRITE_SPLIT_HOST] = "host",
+};
+
+DEFINE_PRIVATE_STRING_TABLE_LOOKUP(journal_write_split_mode, JournalWriteSplitMode);
+static DEFINE_CONFIG_PARSE_ENUM(config_parse_write_split_mode,
+                                journal_write_split_mode,
+                                JournalWriteSplitMode,
+                                "Failed to parse split mode setting");
+
+static int parse_config(void) {
+        const ConfigTableItem items[] = {
+                { "Remote",  "SplitMode",              config_parse_write_split_mode, 0, &arg_split_mode },
+                { "Remote",  "ServerKeyFile",          config_parse_path,             0, &arg_key        },
+                { "Remote",  "ServerCertificateFile",  config_parse_path,             0, &arg_cert       },
+                { "Remote",  "TrustedCertificateFile", config_parse_path,             0, &arg_trust      },
+                {}};
+
+        return config_parse(NULL, PKGSYSCONFDIR "/journal-remote.conf", NULL,
+                            "Remote\0",
+                            config_item_table_lookup, items,
+                            false, false, true, NULL);
+}
+
+static void help(void) {
+        printf("%s [OPTIONS...] {FILE|-}...\n\n"
+               "Write external journal events to journal file(s).\n\n"
+               "  -h --help               Show this help\n"
+               "     --version            Show package version\n"
+               "     --url=URL            Read events from systemd-journal-gatewayd at URL\n"
+               "     --getter=COMMAND     Read events from the output of COMMAND\n"
+               "     --listen-raw=ADDR    Listen for connections at ADDR\n"
+               "     --listen-http=ADDR   Listen for HTTP connections at ADDR\n"
+               "     --listen-https=ADDR  Listen for HTTPS connections at ADDR\n"
+               "  -o --output=FILE|DIR Write output to FILE or DIR/external-*.journal\n"
+               "     --compress[=BOOL]    Use XZ-compression in the output journal (default: yes)\n"
+               "     --seal[=BOOL]        Use Event sealing in the output journal (default: no)\n"
+               "     --key=FILENAME       Specify key in PEM format (default:\n"
+               "                          \"" PRIV_KEY_FILE "\")\n"
+               "     --cert=FILENAME      Specify certificate in PEM format (default:\n"
+               "                          \"" CERT_FILE "\")\n"
+               "     --trust=FILENAME|all Specify CA certificate or disable checking (default:\n"
+               "                          \"" TRUST_FILE "\")\n"
+               "     --gnutls-log=CATEGORY...\n"
+               "                          Specify a list of gnutls logging categories\n"
+               "\n"
+               "Note: file descriptors from sd_listen_fds() will be consumed, too.\n"
+               , program_invocation_short_name);
+}
+
+static int parse_argv(int argc, char *argv[]) {
+        enum {
+                ARG_VERSION = 0x100,
+                ARG_URL,
+                ARG_LISTEN_RAW,
+                ARG_LISTEN_HTTP,
+                ARG_LISTEN_HTTPS,
+                ARG_GETTER,
+                ARG_SPLIT_MODE,
+                ARG_COMPRESS,
+                ARG_SEAL,
+                ARG_KEY,
+                ARG_CERT,
+                ARG_TRUST,
+                ARG_GNUTLS_LOG,
+        };
+
+        static const struct option options[] = {
+                { "help",         no_argument,       NULL, 'h'              },
+                { "version",      no_argument,       NULL, ARG_VERSION      },
+                { "url",          required_argument, NULL, ARG_URL          },
+                { "getter",       required_argument, NULL, ARG_GETTER       },
+                { "listen-raw",   required_argument, NULL, ARG_LISTEN_RAW   },
+                { "listen-http",  required_argument, NULL, ARG_LISTEN_HTTP  },
+                { "listen-https", required_argument, NULL, ARG_LISTEN_HTTPS },
+                { "output",       required_argument, NULL, 'o'              },
+                { "split-mode",   required_argument, NULL, ARG_SPLIT_MODE   },
+                { "compress",     optional_argument, NULL, ARG_COMPRESS     },
+                { "seal",         optional_argument, NULL, ARG_SEAL         },
+                { "key",          required_argument, NULL, ARG_KEY          },
+                { "cert",         required_argument, NULL, ARG_CERT         },
+                { "trust",        required_argument, NULL, ARG_TRUST        },
+                { "gnutls-log",   required_argument, NULL, ARG_GNUTLS_LOG   },
+                {}
+        };
+
+        int c, r;
+        bool type_a, type_b;
+
+        assert(argc >= 0);
+        assert(argv);
+
+        while ((c = getopt_long(argc, argv, "ho:", options, NULL)) >= 0)
+                switch(c) {
+                case 'h':
+                        help();
+                        return 0 /* done */;
+
+                case ARG_VERSION:
+                        puts(PACKAGE_STRING);
+                        puts(SYSTEMD_FEATURES);
+                        return 0 /* done */;
+
+                case ARG_URL:
+                        if (arg_url) {
+                                log_error("cannot currently set more than one --url");
+                                return -EINVAL;
+                        }
+
+                        arg_url = optarg;
+                        break;
+
+                case ARG_GETTER:
+                        if (arg_getter) {
+                                log_error("cannot currently use --getter more than once");
+                                return -EINVAL;
+                        }
+
+                        arg_getter = optarg;
+                        break;
+
+                case ARG_LISTEN_RAW:
+                        if (arg_listen_raw) {
+                                log_error("cannot currently use --listen-raw more than once");
+                                return -EINVAL;
+                        }
+
+                        arg_listen_raw = optarg;
+                        break;
+
+                case ARG_LISTEN_HTTP:
+                        if (arg_listen_http || http_socket >= 0) {
+                                log_error("cannot currently use --listen-http more than once");
+                                return -EINVAL;
+                        }
+
+                        r = fd_fd(optarg);
+                        if (r >= 0)
+                                http_socket = r;
+                        else
+                                arg_listen_http = optarg;
+                        break;
+
+                case ARG_LISTEN_HTTPS:
+                        if (arg_listen_https || https_socket >= 0) {
+                                log_error("cannot currently use --listen-https more than once");
+                                return -EINVAL;
+                        }
+
+                        r = fd_fd(optarg);
+                        if (r >= 0)
+                                https_socket = r;
+                        else
+                                arg_listen_https = optarg;
+
+                        break;
+
+                case ARG_KEY:
+                        if (arg_key) {
+                                log_error("Key file specified twice");
+                                return -EINVAL;
+                        }
+
+                        arg_key = strdup(optarg);
+                        if (!arg_key)
+                                return log_oom();
+
+                        break;
+
+                case ARG_CERT:
+                        if (arg_cert) {
+                                log_error("Certificate file specified twice");
+                                return -EINVAL;
+                        }
+
+                        arg_cert = strdup(optarg);
+                        if (!arg_cert)
+                                return log_oom();
+
+                        break;
+
+                case ARG_TRUST:
+                        if (arg_trust || arg_trust_all) {
+                                log_error("Confusing trusted CA configuration");
+                                return -EINVAL;
+                        }
+
+                        if (streq(optarg, "all"))
+                                arg_trust_all = true;
+                        else {
+#ifdef HAVE_GNUTLS
+                                arg_trust = strdup(optarg);
+                                if (!arg_trust)
+                                        return log_oom();
+#else
+                                log_error("Option --trust is not available.");
+                                return -EINVAL;
+#endif
+                        }
+
+                        break;
+
+                case 'o':
+                        if (arg_output) {
+                                log_error("cannot use --output/-o more than once");
+                                return -EINVAL;
+                        }
+
+                        arg_output = optarg;
+                        break;
+
+                case ARG_SPLIT_MODE:
+                        arg_split_mode = journal_write_split_mode_from_string(optarg);
+                        if (arg_split_mode == _JOURNAL_WRITE_SPLIT_INVALID) {
+                                log_error("Invalid split mode: %s", optarg);
+                                return -EINVAL;
+                        }
+                        break;
+
+                case ARG_COMPRESS:
+                        if (optarg) {
+                                r = parse_boolean(optarg);
+                                if (r < 0) {
+                                        log_error("Failed to parse --compress= parameter.");
+                                        return -EINVAL;
+                                }
+
+                                arg_compress = !!r;
+                        } else
+                                arg_compress = true;
+
+                        break;
+
+                case ARG_SEAL:
+                        if (optarg) {
+                                r = parse_boolean(optarg);
+                                if (r < 0) {
+                                        log_error("Failed to parse --seal= parameter.");
+                                        return -EINVAL;
+                                }
+
+                                arg_seal = !!r;
+                        } else
+                                arg_seal = true;
+
+                        break;
+
+                case ARG_GNUTLS_LOG: {
+#ifdef HAVE_GNUTLS
+                        const char *word, *state;
+                        size_t size;
+
+                        FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
+                                char *cat;
+
+                                cat = strndup(word, size);
+                                if (!cat)
+                                        return log_oom();
+
+                                if (strv_consume(&arg_gnutls_log, cat) < 0)
+                                        return log_oom();
+                        }
+                        break;
+#else
+                        log_error("Option --gnutls-log is not available.");
+                        return -EINVAL;
+#endif
+                }
+
+                case '?':
+                        return -EINVAL;
+
+                default:
+                        assert_not_reached("Unknown option code.");
+                }
+
+        if (optind < argc)
+                arg_files = argv + optind;
+
+        type_a = arg_getter || !strv_isempty(arg_files);
+        type_b = arg_url
+                || arg_listen_raw
+                || arg_listen_http || arg_listen_https
+                || sd_listen_fds(false) > 0;
+        if (type_a && type_b) {
+                log_error("Cannot use file input or --getter with "
+                          "--arg-listen-... or socket activation.");
+                return -EINVAL;
+        }
+        if (type_a) {
+                if (!arg_output) {
+                        log_error("Option --output must be specified with file input or --getter.");
+                        return -EINVAL;
+                }
+
+                arg_split_mode = JOURNAL_WRITE_SPLIT_NONE;
+        }
+
+        if (arg_split_mode == JOURNAL_WRITE_SPLIT_NONE
+            && arg_output && is_dir(arg_output, true) > 0) {
+                log_error("For SplitMode=none, output must be a file.");
+                return -EINVAL;
+        }
+
+        if (arg_split_mode == JOURNAL_WRITE_SPLIT_HOST
+            && arg_output && is_dir(arg_output, true) <= 0) {
+                log_error("For SplitMode=host, output must be a directory.");
+                return -EINVAL;
+        }
+
+        log_debug("Full config: SplitMode=%s Key=%s Cert=%s Trust=%s",
+                  journal_write_split_mode_to_string(arg_split_mode),
+                  strna(arg_key),
+                  strna(arg_cert),
+                  strna(arg_trust));
+
+        return 1 /* work to do */;
+}
+
+static int load_certificates(char **key, char **cert, char **trust) {
+        int r;
+
+        r = read_full_file(arg_key ?: PRIV_KEY_FILE, key, NULL);
+        if (r < 0) {
+                log_error("Failed to read key from file '%s': %s",
+                          arg_key ?: PRIV_KEY_FILE, strerror(-r));
+                return r;
+        }
+
+        r = read_full_file(arg_cert ?: CERT_FILE, cert, NULL);
+        if (r < 0) {
+                log_error("Failed to read certificate from file '%s': %s",
+                          arg_cert ?: CERT_FILE, strerror(-r));
+                return r;
+        }
+
+        if (arg_trust_all)
+                log_info("Certificate checking disabled.");
+        else {
+                r = read_full_file(arg_trust ?: TRUST_FILE, trust, NULL);
+                if (r < 0) {
+                        log_error("Failed to read CA certificate file '%s': %s",
+                                  arg_trust ?: TRUST_FILE, strerror(-r));
+                        return r;
+                }
+        }
+
+        return 0;
+}
+
+static int setup_gnutls_logger(char **categories) {
+        if (!arg_listen_http && !arg_listen_https)
+                return 0;
+
+#ifdef HAVE_GNUTLS
+        {
+                char **cat;
+                int r;
+
+                gnutls_global_set_log_function(log_func_gnutls);
+
+                if (categories)
+                        STRV_FOREACH(cat, categories) {
+                                r = log_enable_gnutls_category(*cat);
+                                if (r < 0)
+                                        return r;
+                        }
+                else
+                        log_reset_gnutls_level();
+        }
+#endif
+
+        return 0;
+}
+
+int main(int argc, char **argv) {
+        RemoteServer s = {};
+        int r;
+        _cleanup_free_ char *key = NULL, *cert = NULL, *trust = NULL;
+
+        log_show_color(true);
+        log_parse_environment();
+
+        r = parse_config();
+        if (r < 0)
+                return EXIT_FAILURE;
+
+        r = parse_argv(argc, argv);
+        if (r <= 0)
+                return r == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
+
+        r = setup_gnutls_logger(arg_gnutls_log);
+        if (r < 0)
+                return EXIT_FAILURE;
+
+        if (arg_listen_https || https_socket >= 0)
+                if (load_certificates(&key, &cert, &trust) < 0)
+                        return EXIT_FAILURE;
+
+        if (remoteserver_init(&s, key, cert, trust) < 0)
+                return EXIT_FAILURE;
+
+        sd_event_set_watchdog(s.events, true);
+
+        log_debug("%s running as pid "PID_FMT,
+                  program_invocation_short_name, getpid());
+        sd_notify(false,
+                  "READY=1\n"
+                  "STATUS=Processing requests...");
+
+        while (s.active) {
+                r = sd_event_get_state(s.events);
+                if (r < 0)
+                        break;
+                if (r == SD_EVENT_FINISHED)
+                        break;
+
+                r = sd_event_run(s.events, -1);
+                if (r < 0) {
+                        log_error("Failed to run event loop: %s", strerror(-r));
+                        break;
+                }
+        }
+
+        server_destroy(&s);
+        log_info("Finishing after writing %" PRIu64 " entries", s.event_count);
+
+        sd_notify(false, "STATUS=Shutting down...");
+
+        free(arg_key);
+        free(arg_cert);
+        free(arg_trust);
+
+        return r >= 0 ? EXIT_SUCCESS : EXIT_FAILURE;
+}
diff --git a/src/journal-remote/journal-remote.conf.in b/src/journal-remote/journal-remote.conf.in
new file mode 100644 (file)
index 0000000..3e32f34
--- /dev/null
@@ -0,0 +1,5 @@
+[Remote]
+# SplitMode=host
+# ServerKeyFile=@CERTIFICATEROOT@/private/journal-remote.pem
+# ServerCertificateFile=@CERTIFICATEROOT@/certs/journal-remote.pem
+# TrustedCertificateFile=@CERTIFICATEROOT@/ca/trusted.pem
diff --git a/src/journal-remote/journal-remote.h b/src/journal-remote/journal-remote.h
new file mode 100644 (file)
index 0000000..1cf22f6
--- /dev/null
@@ -0,0 +1,56 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Zbigniew Jędrzejewski-Szmek
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#pragma once
+
+#include <inttypes.h>
+
+#include "sd-event.h"
+#include "hashmap.h"
+#include "microhttpd-util.h"
+
+#include "journal-remote-parse.h"
+#include "journal-remote-write.h"
+
+typedef struct MHDDaemonWrapper MHDDaemonWrapper;
+
+struct MHDDaemonWrapper {
+        uint64_t fd;
+        struct MHD_Daemon *daemon;
+
+        sd_event_source *event;
+};
+
+struct RemoteServer {
+        RemoteSource **sources;
+        size_t sources_size;
+        size_t active;
+
+        sd_event *events;
+        sd_event_source *sigterm_event, *sigint_event, *listen_event;
+
+        Hashmap *writers;
+        Writer *_single_writer;
+        uint64_t event_count;
+
+        bool check_trust;
+        Hashmap *daemons;
+};
diff --git a/src/journal-remote/journal-upload-journal.c b/src/journal-remote/journal-upload-journal.c
new file mode 100644 (file)
index 0000000..1cd52db
--- /dev/null
@@ -0,0 +1,402 @@
+#include <stdbool.h>
+
+#include <curl/curl.h>
+
+#include "util.h"
+#include "log.h"
+#include "utf8.h"
+#include "journal-upload.h"
+
+/**
+ * Write up to size bytes to buf. Return negative on error, and number of
+ * bytes written otherwise. The last case is a kind of an error too.
+ */
+static ssize_t write_entry(char *buf, size_t size, Uploader *u) {
+        int r;
+        size_t pos = 0;
+
+        assert(size <= SSIZE_MAX);
+
+        while (true) {
+
+                switch(u->entry_state) {
+                case ENTRY_CURSOR: {
+                        free(u->current_cursor);
+                        u->current_cursor = NULL;
+
+                        r = sd_journal_get_cursor(u->journal, &u->current_cursor);
+                        if (r < 0) {
+                                log_error("Failed to get cursor: %s", strerror(-r));
+                                return r;
+                        }
+
+                        r = snprintf(buf + pos, size - pos,
+                                     "__CURSOR=%s\n", u->current_cursor);
+                        if (pos + r > size)
+                                /* not enough space */
+                                return pos;
+
+                        u->entry_state ++;
+
+                        if (pos + r == size) {
+                                /* exactly one character short, but we don't need it */
+                                buf[size - 1] = '\n';
+                                return size;
+                        }
+
+                        pos += r;
+                }       /* fall through */
+
+                case ENTRY_REALTIME: {
+                        usec_t realtime;
+
+                        r = sd_journal_get_realtime_usec(u->journal, &realtime);
+                        if (r < 0) {
+                                log_error("Failed to get realtime timestamp: %s", strerror(-r));
+                                return r;
+                        }
+
+                        r = snprintf(buf + pos, size - pos,
+                                     "__REALTIME_TIMESTAMP="USEC_FMT"\n", realtime);
+                        if (r + pos > size)
+                                /* not enough space */
+                                return pos;
+
+                        u->entry_state ++;
+
+                        if (r + pos == size) {
+                                /* exactly one character short, but we don't need it */
+                                buf[size - 1] = '\n';
+                                return size;
+                        }
+
+                        pos += r;
+                }       /* fall through */
+
+                case ENTRY_MONOTONIC: {
+                        usec_t monotonic;
+                        sd_id128_t boot_id;
+
+                        r = sd_journal_get_monotonic_usec(u->journal, &monotonic, &boot_id);
+                        if (r < 0) {
+                                log_error("Failed to get monotonic timestamp: %s", strerror(-r));
+                                return r;
+                        }
+
+                        r = snprintf(buf + pos, size - pos,
+                                     "__MONOTONIC_TIMESTAMP="USEC_FMT"\n", monotonic);
+                        if (r + pos > size)
+                                /* not enough space */
+                                return pos;
+
+                        u->entry_state ++;
+
+                        if (r + pos == size) {
+                                /* exactly one character short, but we don't need it */
+                                buf[size - 1] = '\n';
+                                return size;
+                        }
+
+                        pos += r;
+                }       /* fall through */
+
+                case ENTRY_BOOT_ID: {
+                        sd_id128_t boot_id;
+                        char sid[33];
+
+                        r = sd_journal_get_monotonic_usec(u->journal, NULL, &boot_id);
+                        if (r < 0) {
+                                log_error("Failed to get monotonic timestamp: %s", strerror(-r));
+                                return r;
+                        }
+
+                        r = snprintf(buf + pos, size - pos,
+                                     "_BOOT_ID=%s\n", sd_id128_to_string(boot_id, sid));
+                        if (r + pos> size)
+                                /* not enough space */
+                                return pos;
+
+                        u->entry_state ++;
+
+                        if (r + pos == size) {
+                                /* exactly one character short, but we don't need it */
+                                buf[size - 1] = '\n';
+                                return size;
+                        }
+
+                        pos += r;
+                }       /* fall through */
+
+                case ENTRY_NEW_FIELD: {
+                        u->field_pos = 0;
+
+                        r = sd_journal_enumerate_data(u->journal,
+                                                      &u->field_data,
+                                                      &u->field_length);
+                        if (r < 0) {
+                                log_error("Failed to move to next field in entry: %s",
+                                          strerror(-r));
+                                return r;
+                        } else if (r == 0) {
+                                u->entry_state = ENTRY_OUTRO;
+                                continue;
+                        }
+
+                        if (!utf8_is_printable_newline(u->field_data,
+                                                       u->field_length, false)) {
+                                u->entry_state = ENTRY_BINARY_FIELD_START;
+                                continue;
+                        }
+
+                        u->entry_state ++;
+                }       /* fall through */
+
+                case ENTRY_TEXT_FIELD:
+                case ENTRY_BINARY_FIELD: {
+                        bool done;
+                        size_t tocopy;
+
+                        done = size - pos > u->field_length - u->field_pos;
+                        if (done)
+                                tocopy = u->field_length - u->field_pos;
+                        else
+                                tocopy = size - pos;
+
+                        memcpy(buf + pos,
+                               (char*) u->field_data + u->field_pos,
+                               tocopy);
+
+                        if (done) {
+                                buf[pos + tocopy] = '\n';
+                                pos += tocopy + 1;
+                                u->entry_state = ENTRY_NEW_FIELD;
+                                continue;
+                        } else {
+                                u->field_pos += tocopy;
+                                return size;
+                        }
+                }
+
+                case ENTRY_BINARY_FIELD_START: {
+                        const char *c;
+                        size_t len;
+
+                        c = memchr(u->field_data, '=', u->field_length);
+                        if (!c || c == u->field_data) {
+                                log_error("Invalid field.");
+                                return -EINVAL;
+                        }
+
+                        len = c - (const char*)u->field_data;
+
+                        /* need space for label + '\n' */
+                        if (size - pos < len + 1)
+                                return pos;
+
+                        memcpy(buf + pos, u->field_data, len);
+                        buf[pos + len] = '\n';
+                        pos += len + 1;
+
+                        u->field_pos = len + 1;
+                        u->entry_state ++;
+                }       /* fall through */
+
+                case ENTRY_BINARY_FIELD_SIZE: {
+                        uint64_t le64;
+
+                        /* need space for uint64_t */
+                        if (size - pos < 8)
+                                return pos;
+
+                        le64 = htole64(u->field_length - u->field_pos);
+                        memcpy(buf + pos, &le64, 8);
+                        pos += 8;
+
+                        u->entry_state ++;
+                        continue;
+                }
+
+                case ENTRY_OUTRO:
+                        /* need space for '\n' */
+                        if (size - pos < 1)
+                                return pos;
+
+                        buf[pos++] = '\n';
+                        u->entry_state ++;
+                        u->entries_sent ++;
+
+                        return pos;
+
+                default:
+                        assert_not_reached("WTF?");
+                }
+        }
+        assert_not_reached("WTF?");
+}
+
+static size_t journal_input_callback(void *buf, size_t size, size_t nmemb, void *userp) {
+        Uploader *u = userp;
+        int r;
+        sd_journal *j;
+        size_t filled = 0;
+        ssize_t w;
+
+        assert(u);
+        assert(nmemb <= SSIZE_MAX / size);
+
+        j = u->journal;
+
+        while (j && filled < size * nmemb) {
+                if (u->entry_state == ENTRY_DONE) {
+                        r = sd_journal_next(j);
+                        if (r < 0) {
+                                log_error("Failed to move to next entry in journal: %s",
+                                          strerror(-r));
+                                return CURL_READFUNC_ABORT;
+                        } else if (r == 0) {
+                                if (u->input_event)
+                                        log_debug("No more entries, waiting for journal.");
+                                else {
+                                        log_info("No more entries, closing journal.");
+                                        close_journal_input(u);
+                                }
+
+                                u->uploading = false;
+
+                                break;
+                        }
+
+                        u->entry_state = ENTRY_CURSOR;
+                }
+
+                w = write_entry((char*)buf + filled, size * nmemb - filled, u);
+                if (w < 0)
+                        return CURL_READFUNC_ABORT;
+                filled += w;
+
+                if (filled == 0) {
+                        log_error("Buffer space is too small to write entry.");
+                        return CURL_READFUNC_ABORT;
+                } else if (u->entry_state != ENTRY_DONE)
+                        /* This means that all available space was used up */
+                        break;
+
+                log_debug("Entry %zu (%s) has been uploaded.",
+                          u->entries_sent, u->current_cursor);
+        }
+
+        return filled;
+}
+
+void close_journal_input(Uploader *u) {
+        assert(u);
+
+        if (u->journal) {
+                log_debug("Closing journal input.");
+
+                sd_journal_close(u->journal);
+                u->journal = NULL;
+        }
+        u->timeout = 0;
+}
+
+static int process_journal_input(Uploader *u, int skip) {
+        int r;
+
+        r = sd_journal_next_skip(u->journal, skip);
+        if (r < 0) {
+                log_error("Failed to skip to next entry: %s", strerror(-r));
+                return r;
+        } else if (r < skip)
+                return 0;
+
+        /* have data */
+        u->entry_state = ENTRY_CURSOR;
+        return start_upload(u, journal_input_callback, u);
+}
+
+int check_journal_input(Uploader *u) {
+        if (u->input_event) {
+                int r;
+
+                r = sd_journal_process(u->journal);
+                if (r < 0) {
+                        log_error("Failed to process journal: %s", strerror(-r));
+                        close_journal_input(u);
+                        return r;
+                }
+
+                if (r == SD_JOURNAL_NOP)
+                        return 0;
+        }
+
+        return process_journal_input(u, 1);
+}
+
+static int dispatch_journal_input(sd_event_source *event,
+                                  int fd,
+                                  uint32_t revents,
+                                  void *userp) {
+        Uploader *u = userp;
+
+        assert(u);
+
+        if (u->uploading) {
+                log_warning("dispatch_journal_input called when uploading, ignoring.");
+                return 0;
+        }
+
+        log_debug("Detected journal input, checking for new data.");
+        return check_journal_input(u);
+}
+
+int open_journal_for_upload(Uploader *u,
+                            sd_journal *j,
+                            const char *cursor,
+                            bool after_cursor,
+                            bool follow) {
+        int fd, r, events;
+
+        u->journal = j;
+
+        sd_journal_set_data_threshold(j, 0);
+
+        if (follow) {
+                fd = sd_journal_get_fd(j);
+                if (fd < 0) {
+                        log_error("sd_journal_get_fd failed: %s", strerror(-fd));
+                        return fd;
+                }
+
+                events = sd_journal_get_events(j);
+
+                r = sd_journal_reliable_fd(j);
+                assert(r >= 0);
+                if (r > 0)
+                        u->timeout = -1;
+                else
+                        u->timeout = JOURNAL_UPLOAD_POLL_TIMEOUT;
+
+                r = sd_event_add_io(u->events, &u->input_event,
+                                    fd, events, dispatch_journal_input, u);
+                if (r < 0) {
+                        log_error("Failed to register input event: %s", strerror(-r));
+                        return r;
+                }
+
+                log_debug("Listening for journal events on fd:%d, timeout %d",
+                          fd, u->timeout == (uint64_t) -1 ? -1 : (int) u->timeout);
+        } else
+                log_debug("Not listening for journal events.");
+
+        if (cursor) {
+                r = sd_journal_seek_cursor(j, cursor);
+                if (r < 0) {
+                        log_error("Failed to seek to cursor %s: %s",
+                                  cursor, strerror(-r));
+                        return r;
+                }
+        }
+
+        return process_journal_input(u, 1 + !!after_cursor);
+}
diff --git a/src/journal-remote/journal-upload.c b/src/journal-remote/journal-upload.c
new file mode 100644 (file)
index 0000000..7a7aee8
--- /dev/null
@@ -0,0 +1,826 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Zbigniew Jędrzejewski-Szmek
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdio.h>
+#include <curl/curl.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <getopt.h>
+
+#include "sd-daemon.h"
+
+#include "log.h"
+#include "util.h"
+#include "build.h"
+#include "fileio.h"
+#include "conf-parser.h"
+#include "journal-upload.h"
+
+#define PRIV_KEY_FILE CERTIFICATE_ROOT "/private/journal-upload.pem"
+#define CERT_FILE     CERTIFICATE_ROOT "/certs/journal-upload.pem"
+#define TRUST_FILE    CERTIFICATE_ROOT "/ca/trusted.pem"
+
+static const char* arg_url;
+
+static void close_fd_input(Uploader *u);
+
+static const char *arg_key = NULL;
+static const char *arg_cert = NULL;
+static const char *arg_trust = NULL;
+
+static const char *arg_directory = NULL;
+static char **arg_file = NULL;
+static const char *arg_cursor = NULL;
+static bool arg_after_cursor = false;
+static int arg_journal_type = 0;
+static const char *arg_machine = NULL;
+static bool arg_merge = false;
+static int arg_follow = -1;
+static const char *arg_save_state = NULL;
+
+#define SERVER_ANSWER_KEEP 2048
+
+#define STATE_FILE "/var/lib/systemd/journal-upload/state"
+
+#define easy_setopt(curl, opt, value, level, cmd)                       \
+        {                                                               \
+                code = curl_easy_setopt(curl, opt, value);              \
+                if (code) {                                             \
+                        log_full(level,                                 \
+                                 "curl_easy_setopt " #opt " failed: %s", \
+                                  curl_easy_strerror(code));            \
+                        cmd;                                            \
+                }                                                       \
+        }
+
+static size_t output_callback(char *buf,
+                              size_t size,
+                              size_t nmemb,
+                              void *userp) {
+        Uploader *u = userp;
+
+        assert(u);
+
+        log_debug("The server answers (%zu bytes): %.*s",
+                  size*nmemb, (int)(size*nmemb), buf);
+
+        if (nmemb && !u->answer) {
+                u->answer = strndup(buf, size*nmemb);
+                if (!u->answer)
+                        log_warning("Failed to store server answer (%zu bytes): %s",
+                                    size*nmemb, strerror(ENOMEM));
+        }
+
+        return size * nmemb;
+}
+
+static int update_cursor_state(Uploader *u) {
+        _cleanup_free_ char *temp_path = NULL;
+        _cleanup_fclose_ FILE *f = NULL;
+        int r;
+
+        if (!u->state_file || !u->last_cursor)
+                return 0;
+
+        r = fopen_temporary(u->state_file, &f, &temp_path);
+        if (r < 0)
+                goto finish;
+
+        fprintf(f,
+                "# This is private data. Do not parse.\n"
+                "LAST_CURSOR=%s\n",
+                u->last_cursor);
+
+        fflush(f);
+
+        if (ferror(f) || rename(temp_path, u->state_file) < 0) {
+                r = -errno;
+                unlink(u->state_file);
+                unlink(temp_path);
+        }
+
+finish:
+        if (r < 0)
+                log_error("Failed to save state %s: %s", u->state_file, strerror(-r));
+
+        return r;
+}
+
+static int load_cursor_state(Uploader *u) {
+        int r;
+
+        if (!u->state_file)
+                return 0;
+
+        r = parse_env_file(u->state_file, NEWLINE,
+                           "LAST_CURSOR",  &u->last_cursor,
+                           NULL);
+
+        if (r < 0 && r != -ENOENT) {
+                log_error("Failed to read state file %s: %s",
+                          u->state_file, strerror(-r));
+                return r;
+        }
+
+        return 0;
+}
+
+
+
+int start_upload(Uploader *u,
+                 size_t (*input_callback)(void *ptr,
+                                          size_t size,
+                                          size_t nmemb,
+                                          void *userdata),
+                 void *data) {
+        CURLcode code;
+
+        assert(u);
+        assert(input_callback);
+
+        if (!u->header) {
+                struct curl_slist *h;
+
+                h = curl_slist_append(NULL, "Content-Type: application/vnd.fdo.journal");
+                if (!h)
+                        return log_oom();
+
+                h = curl_slist_append(h, "Transfer-Encoding: chunked");
+                if (!h) {
+                        curl_slist_free_all(h);
+                        return log_oom();
+                }
+
+                h = curl_slist_append(h, "Accept: text/plain");
+                if (!h) {
+                        curl_slist_free_all(h);
+                        return log_oom();
+                }
+
+                u->header = h;
+        }
+
+        if (!u->easy) {
+                CURL *curl;
+
+                curl = curl_easy_init();
+                if (!curl) {
+                        log_error("Call to curl_easy_init failed.");
+                        return -ENOSR;
+                }
+
+                /* tell it to POST to the URL */
+                easy_setopt(curl, CURLOPT_POST, 1L,
+                            LOG_ERR, return -EXFULL);
+
+                easy_setopt(curl, CURLOPT_ERRORBUFFER, &u->error,
+                            LOG_ERR, return -EXFULL);
+
+                /* set where to write to */
+                easy_setopt(curl, CURLOPT_WRITEFUNCTION, output_callback,
+                            LOG_ERR, return -EXFULL);
+
+                easy_setopt(curl, CURLOPT_WRITEDATA, data,
+                            LOG_ERR, return -EXFULL);
+
+                /* set where to read from */
+                easy_setopt(curl, CURLOPT_READFUNCTION, input_callback,
+                            LOG_ERR, return -EXFULL);
+
+                easy_setopt(curl, CURLOPT_READDATA, data,
+                            LOG_ERR, return -EXFULL);
+
+                /* use our special own mime type and chunked transfer */
+                easy_setopt(curl, CURLOPT_HTTPHEADER, u->header,
+                            LOG_ERR, return -EXFULL);
+
+                /* enable verbose for easier tracing */
+                easy_setopt(curl, CURLOPT_VERBOSE, 1L, LOG_WARNING, );
+
+                easy_setopt(curl, CURLOPT_USERAGENT,
+                            "systemd-journal-upload " PACKAGE_STRING,
+                            LOG_WARNING, );
+
+                if (arg_key || startswith(u->url, "https://")) {
+                        assert(arg_cert);
+
+                        easy_setopt(curl, CURLOPT_SSLKEY, arg_key ?: PRIV_KEY_FILE,
+                                    LOG_ERR, return -EXFULL);
+                        easy_setopt(curl, CURLOPT_SSLCERT, arg_cert ?: CERT_FILE,
+                                    LOG_ERR, return -EXFULL);
+                }
+
+                if (arg_trust || startswith(u->url, "https://"))
+                        easy_setopt(curl, CURLOPT_CAINFO, arg_trust ?: TRUST_FILE,
+                                    LOG_ERR, return -EXFULL);
+
+                if (arg_key || arg_trust)
+                        easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1,
+                                    LOG_WARNING, );
+
+                u->easy = curl;
+        } else {
+                /* truncate the potential old error message */
+                u->error[0] = '\0';
+
+                free(u->answer);
+                u->answer = 0;
+        }
+
+        /* upload to this place */
+        code = curl_easy_setopt(u->easy, CURLOPT_URL, u->url);
+        if (code) {
+                log_error("curl_easy_setopt CURLOPT_URL failed: %s",
+                          curl_easy_strerror(code));
+                return -EXFULL;
+        }
+
+        u->uploading = true;
+
+        return 0;
+}
+
+static size_t fd_input_callback(void *buf, size_t size, size_t nmemb, void *userp) {
+        Uploader *u = userp;
+
+        ssize_t r;
+
+        assert(u);
+        assert(nmemb <= SSIZE_MAX / size);
+
+        if (u->input < 0)
+                return 0;
+
+        r = read(u->input, buf, size * nmemb);
+        log_debug("%s: allowed %zu, read %zu", __func__, size*nmemb, r);
+
+        if (r > 0)
+                return r;
+
+        u->uploading = false;
+        if (r == 0) {
+                log_debug("Reached EOF");
+                close_fd_input(u);
+                return 0;
+        } else {
+                log_error("Aborting transfer after read error on input: %m.");
+                return CURL_READFUNC_ABORT;
+        }
+}
+
+static void close_fd_input(Uploader *u) {
+        assert(u);
+
+        if (u->input >= 0)
+                close_nointr(u->input);
+        u->input = -1;
+        u->timeout = 0;
+}
+
+static int dispatch_fd_input(sd_event_source *event,
+                             int fd,
+                             uint32_t revents,
+                             void *userp) {
+        Uploader *u = userp;
+
+        assert(u);
+        assert(fd >= 0);
+
+        if (revents & EPOLLHUP) {
+                log_debug("Received HUP");
+                close_fd_input(u);
+                return 0;
+        }
+
+        if (!(revents & EPOLLIN)) {
+                log_warning("Unexpected poll event %"PRIu32".", revents);
+                return -EINVAL;
+        }
+
+        if (u->uploading) {
+                log_warning("dispatch_fd_input called when uploading, ignoring.");
+                return 0;
+        }
+
+        return start_upload(u, fd_input_callback, u);
+}
+
+static int open_file_for_upload(Uploader *u, const char *filename) {
+        int fd, r;
+
+        if (streq(filename, "-"))
+                fd = STDIN_FILENO;
+        else {
+                fd = open(filename, O_RDONLY|O_CLOEXEC|O_NOCTTY);
+                if (fd < 0) {
+                        log_error("Failed to open %s: %m", filename);
+                        return -errno;
+                }
+        }
+
+        u->input = fd;
+
+        if (arg_follow) {
+                r = sd_event_add_io(u->events, &u->input_event,
+                                    fd, EPOLLIN, dispatch_fd_input, u);
+                if (r < 0) {
+                        if (r != -EPERM || arg_follow > 0) {
+                                log_error("Failed to register input event: %s", strerror(-r));
+                                return r;
+                        }
+
+                        /* Normal files should just be consumed without polling. */
+                        r = start_upload(u, fd_input_callback, u);
+                }
+        }
+
+        return r;
+}
+
+static int dispatch_sigterm(sd_event_source *event,
+                            const struct signalfd_siginfo *si,
+                            void *userdata) {
+        Uploader *u = userdata;
+
+        assert(u);
+
+        log_received_signal(LOG_INFO, si);
+
+        close_fd_input(u);
+        close_journal_input(u);
+
+        sd_event_exit(u->events, 0);
+        return 0;
+}
+
+static int setup_signals(Uploader *u) {
+        sigset_t mask;
+        int r;
+
+        assert(u);
+
+        assert_se(sigemptyset(&mask) == 0);
+        sigset_add_many(&mask, SIGINT, SIGTERM, -1);
+        assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
+
+        r = sd_event_add_signal(u->events, &u->sigterm_event, SIGTERM, dispatch_sigterm, u);
+        if (r < 0)
+                return r;
+
+        r = sd_event_add_signal(u->events, &u->sigint_event, SIGINT, dispatch_sigterm, u);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+static int setup_uploader(Uploader *u, const char *url, const char *state_file) {
+        int r;
+
+        assert(u);
+        assert(url);
+
+        memzero(u, sizeof(Uploader));
+        u->input = -1;
+
+        if (!startswith(url, "http://") && !startswith(url, "https://"))
+                url = strappenda("https://", url);
+
+        u->url = strappend(url, "/upload");
+        if (!u->url)
+                return log_oom();
+
+        u->state_file = state_file;
+
+        r = sd_event_default(&u->events);
+        if (r < 0) {
+                log_error("sd_event_default failed: %s", strerror(-r));
+                return r;
+        }
+
+        r = setup_signals(u);
+        if (r < 0) {
+                log_error("Failed to set up signals: %s", strerror(-r));
+                return r;
+        }
+
+        return load_cursor_state(u);
+}
+
+static void destroy_uploader(Uploader *u) {
+        assert(u);
+
+        curl_easy_cleanup(u->easy);
+        curl_slist_free_all(u->header);
+        free(u->answer);
+
+        free(u->last_cursor);
+        free(u->current_cursor);
+
+        free(u->url);
+
+        u->input_event = sd_event_source_unref(u->input_event);
+
+        close_fd_input(u);
+        close_journal_input(u);
+
+        sd_event_source_unref(u->sigterm_event);
+        sd_event_source_unref(u->sigint_event);
+        sd_event_unref(u->events);
+}
+
+static int perform_upload(Uploader *u) {
+        CURLcode code;
+        long status;
+
+        assert(u);
+
+        code = curl_easy_perform(u->easy);
+        if (code) {
+                log_error("Upload to %s failed: %.*s",
+                          u->url,
+                          u->error[0] ? (int) sizeof(u->error) : INT_MAX,
+                          u->error[0] ? u->error : curl_easy_strerror(code));
+                return -EIO;
+        }
+
+        code = curl_easy_getinfo(u->easy, CURLINFO_RESPONSE_CODE, &status);
+        if (code) {
+                log_error("Failed to retrieve response code: %s",
+                          curl_easy_strerror(code));
+                return -EUCLEAN;
+        }
+
+        if (status >= 300) {
+                log_error("Upload to %s failed with code %lu: %s",
+                          u->url, status, strna(u->answer));
+                return -EIO;
+        } else if (status < 200) {
+                log_error("Upload to %s finished with unexpected code %lu: %s",
+                          u->url, status, strna(u->answer));
+                return -EIO;
+        } else
+                log_debug("Upload finished successfully with code %lu: %s",
+                          status, strna(u->answer));
+
+        free(u->last_cursor);
+        u->last_cursor = u->current_cursor;
+        u->current_cursor = NULL;
+
+        return update_cursor_state(u);
+}
+
+static int parse_config(void) {
+        const ConfigTableItem items[] = {
+                { "Upload",  "URL",                    config_parse_string, 0, &arg_url    },
+                { "Upload",  "ServerKeyFile",          config_parse_path,   0, &arg_key    },
+                { "Upload",  "ServerCertificateFile",  config_parse_path,   0, &arg_cert   },
+                { "Upload",  "TrustedCertificateFile", config_parse_path,   0, &arg_trust  },
+                {}};
+
+        return config_parse(NULL, PKGSYSCONFDIR "/journal-upload.conf", NULL,
+                            "Upload\0",
+                            config_item_table_lookup, items,
+                            false, false, true, NULL);
+}
+
+static void help(void) {
+        printf("%s -u URL {FILE|-}...\n\n"
+               "Upload journal events to a remote server.\n\n"
+               "  -h --help                 Show this help\n"
+               "     --version              Show package version\n"
+               "  -u --url=URL              Upload to this address\n"
+               "     --key=FILENAME         Specify key in PEM format\n"
+               "     --cert=FILENAME        Specify certificate in PEM format\n"
+               "     --trust=FILENAME       Specify CA certificate in PEM format\n"
+               "     --system               Use the system journal\n"
+               "     --user                 Use the user journal for the current user\n"
+               "  -m --merge                Use  all available journals\n"
+               "  -M --machine=CONTAINER    Operate on local container\n"
+               "  -D --directory=PATH       Use journal files from directory\n"
+               "     --file=PATH            Use this journal file\n"
+               "     --cursor=CURSOR        Start at the specified cursor\n"
+               "     --after-cursor=CURSOR  Start after the specified cursor\n"
+               "     --follow[=BOOL]        Do [not] wait for input\n"
+               "     --save-state[=FILE]    Save uploaded cursors (default \n"
+               "                            " STATE_FILE ")\n"
+               "  -h --help                 Show this help and exit\n"
+               "     --version              Print version string and exit\n"
+               , program_invocation_short_name);
+}
+
+static int parse_argv(int argc, char *argv[]) {
+        enum {
+                ARG_VERSION = 0x100,
+                ARG_KEY,
+                ARG_CERT,
+                ARG_TRUST,
+                ARG_USER,
+                ARG_SYSTEM,
+                ARG_FILE,
+                ARG_CURSOR,
+                ARG_AFTER_CURSOR,
+                ARG_FOLLOW,
+                ARG_SAVE_STATE,
+        };
+
+        static const struct option options[] = {
+                { "help",         no_argument,       NULL, 'h'                },
+                { "version",      no_argument,       NULL, ARG_VERSION        },
+                { "url",          required_argument, NULL, 'u'                },
+                { "key",          required_argument, NULL, ARG_KEY            },
+                { "cert",         required_argument, NULL, ARG_CERT           },
+                { "trust",        required_argument, NULL, ARG_TRUST          },
+                { "system",       no_argument,       NULL, ARG_SYSTEM         },
+                { "user",         no_argument,       NULL, ARG_USER           },
+                { "merge",        no_argument,       NULL, 'm'                },
+                { "machine",      required_argument, NULL, 'M'                },
+                { "directory",    required_argument, NULL, 'D'                },
+                { "file",         required_argument, NULL, ARG_FILE           },
+                { "cursor",       required_argument, NULL, ARG_CURSOR         },
+                { "after-cursor", required_argument, NULL, ARG_AFTER_CURSOR   },
+                { "follow",       optional_argument, NULL, ARG_FOLLOW         },
+                { "save-state",   optional_argument, NULL, ARG_SAVE_STATE     },
+                {}
+        };
+
+        int c, r;
+
+        assert(argc >= 0);
+        assert(argv);
+
+        opterr = 0;
+
+        while ((c = getopt_long(argc, argv, "hu:mM:D:", options, NULL)) >= 0)
+                switch(c) {
+                case 'h':
+                        help();
+                        return 0 /* done */;
+
+                case ARG_VERSION:
+                        puts(PACKAGE_STRING);
+                        puts(SYSTEMD_FEATURES);
+                        return 0 /* done */;
+
+                case 'u':
+                        if (arg_url) {
+                                log_error("cannot use more than one --url");
+                                return -EINVAL;
+                        }
+
+                        arg_url = optarg;
+                        break;
+
+                case ARG_KEY:
+                        if (arg_key) {
+                                log_error("cannot use more than one --key");
+                                return -EINVAL;
+                        }
+
+                        arg_key = optarg;
+                        break;
+
+                case ARG_CERT:
+                        if (arg_cert) {
+                                log_error("cannot use more than one --cert");
+                                return -EINVAL;
+                        }
+
+                        arg_cert = optarg;
+                        break;
+
+                case ARG_TRUST:
+                        if (arg_trust) {
+                                log_error("cannot use more than one --trust");
+                                return -EINVAL;
+                        }
+
+                        arg_trust = optarg;
+                        break;
+
+                case ARG_SYSTEM:
+                        arg_journal_type |= SD_JOURNAL_SYSTEM;
+                        break;
+
+                case ARG_USER:
+                        arg_journal_type |= SD_JOURNAL_CURRENT_USER;
+                        break;
+
+                case 'm':
+                        arg_merge = true;
+                        break;
+
+                case 'M':
+                        if (arg_machine) {
+                                log_error("cannot use more than one --machine/-M");
+                                return -EINVAL;
+                        }
+
+                        arg_machine = optarg;
+                        break;
+
+                case 'D':
+                        if (arg_directory) {
+                                log_error("cannot use more than one --directory/-D");
+                                return -EINVAL;
+                        }
+
+                        arg_directory = optarg;
+                        break;
+
+                case ARG_FILE:
+                        r = glob_extend(&arg_file, optarg);
+                        if (r < 0) {
+                                log_error("Failed to add paths: %s", strerror(-r));
+                                return r;
+                        };
+                        break;
+
+                case ARG_CURSOR:
+                        if (arg_cursor) {
+                                log_error("cannot use more than one --cursor/--after-cursor");
+                                return -EINVAL;
+                        }
+
+                        arg_cursor = optarg;
+                        break;
+
+                case ARG_AFTER_CURSOR:
+                        if (arg_cursor) {
+                                log_error("cannot use more than one --cursor/--after-cursor");
+                                return -EINVAL;
+                        }
+
+                        arg_cursor = optarg;
+                        arg_after_cursor = true;
+                        break;
+
+                case ARG_FOLLOW:
+                        if (optarg) {
+                                r = parse_boolean(optarg);
+                                if (r < 0) {
+                                        log_error("Failed to parse --follow= parameter.");
+                                        return -EINVAL;
+                                }
+
+                                arg_follow = !!r;
+                        } else
+                                arg_follow = true;
+
+                        break;
+
+                case ARG_SAVE_STATE:
+                        arg_save_state = optarg ?: STATE_FILE;
+                        break;
+
+                case '?':
+                        log_error("Unknown option %s.", argv[optind-1]);
+                        return -EINVAL;
+
+                case ':':
+                        log_error("Missing argument to %s.", argv[optind-1]);
+                        return -EINVAL;
+
+                default:
+                        assert_not_reached("Unhandled option code.");
+                }
+
+        if (!arg_url) {
+                log_error("Required --url/-u option missing.");
+                return -EINVAL;
+        }
+
+        if (!!arg_key != !!arg_cert) {
+                log_error("Options --key and --cert must be used together.");
+                return -EINVAL;
+        }
+
+        if (optind < argc && (arg_directory || arg_file || arg_machine || arg_journal_type)) {
+                log_error("Input arguments make no sense with journal input.");
+                return -EINVAL;
+        }
+
+        return 1;
+}
+
+static int open_journal(sd_journal **j) {
+        int r;
+
+        if (arg_directory)
+                r = sd_journal_open_directory(j, arg_directory, arg_journal_type);
+        else if (arg_file)
+                r = sd_journal_open_files(j, (const char**) arg_file, 0);
+        else if (arg_machine)
+                r = sd_journal_open_container(j, arg_machine, 0);
+        else
+                r = sd_journal_open(j, !arg_merge*SD_JOURNAL_LOCAL_ONLY + arg_journal_type);
+        if (r < 0)
+                log_error("Failed to open %s: %s",
+                          arg_directory ? arg_directory : arg_file ? "files" : "journal",
+                          strerror(-r));
+        return r;
+}
+
+int main(int argc, char **argv) {
+        Uploader u;
+        int r;
+        bool use_journal;
+
+        log_show_color(true);
+        log_parse_environment();
+
+        r = parse_config();
+        if (r < 0)
+                goto finish;
+
+        r = parse_argv(argc, argv);
+        if (r <= 0)
+                goto finish;
+
+        r = setup_uploader(&u, arg_url, arg_save_state);
+        if (r < 0)
+                goto cleanup;
+
+        sd_event_set_watchdog(u.events, true);
+
+        log_debug("%s running as pid "PID_FMT,
+                  program_invocation_short_name, getpid());
+
+        use_journal = optind >= argc;
+        if (use_journal) {
+                sd_journal *j;
+                r = open_journal(&j);
+                if (r < 0)
+                        goto finish;
+                r = open_journal_for_upload(&u, j,
+                                            arg_cursor ?: u.last_cursor,
+                                            arg_cursor ? arg_after_cursor : true,
+                                            !!arg_follow);
+                if (r < 0)
+                        goto finish;
+        }
+
+        sd_notify(false,
+                  "READY=1\n"
+                  "STATUS=Processing input...");
+
+        while (true) {
+                if (use_journal) {
+                        if (!u.journal)
+                                break;
+
+                        r = check_journal_input(&u);
+                } else if (u.input < 0 && !use_journal) {
+                        if (optind >= argc)
+                                break;
+
+                        log_debug("Using %s as input.", argv[optind]);
+                        r = open_file_for_upload(&u, argv[optind++]);
+                }
+                if (r < 0)
+                        goto cleanup;
+
+                r = sd_event_get_state(u.events);
+                if (r < 0)
+                        break;
+                if (r == SD_EVENT_FINISHED)
+                        break;
+
+                if (u.uploading) {
+                        r = perform_upload(&u);
+                        if (r < 0)
+                                break;
+                }
+
+                r = sd_event_run(u.events, u.timeout);
+                if (r < 0) {
+                        log_error("Failed to run event loop: %s", strerror(-r));
+                        break;
+                }
+        }
+
+cleanup:
+        sd_notify(false, "STATUS=Shutting down...");
+        destroy_uploader(&u);
+
+finish:
+        return r == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
+}
diff --git a/src/journal-remote/journal-upload.conf.in b/src/journal-remote/journal-upload.conf.in
new file mode 100644 (file)
index 0000000..c567068
--- /dev/null
@@ -0,0 +1,5 @@
+[Upload]
+# URL=
+# ServerKeyFile=@CERTIFICATEROOT@/private/journal-upload.pem
+# ServerCertificateFile=@CERTIFICATEROOT@/certs/journal-upload.pem
+# TrustedCertificateFile=@CERTIFICATEROOT@/ca/trusted.pem
diff --git a/src/journal-remote/journal-upload.h b/src/journal-remote/journal-upload.h
new file mode 100644 (file)
index 0000000..3b46fa8
--- /dev/null
@@ -0,0 +1,68 @@
+#pragma once
+
+#include <inttypes.h>
+
+#include "sd-journal.h"
+#include "sd-event.h"
+
+typedef enum {
+        ENTRY_CURSOR = 0,           /* Nothing actually written yet. */
+        ENTRY_REALTIME,
+        ENTRY_MONOTONIC,
+        ENTRY_BOOT_ID,
+        ENTRY_NEW_FIELD,            /* In between fields. */
+        ENTRY_TEXT_FIELD,           /* In the middle of a text field. */
+        ENTRY_BINARY_FIELD_START,   /* Writing the name of a binary field. */
+        ENTRY_BINARY_FIELD_SIZE,    /* Writing the size of a binary field. */
+        ENTRY_BINARY_FIELD,         /* In the middle of a binary field. */
+        ENTRY_OUTRO,                /* Writing '\n' */
+        ENTRY_DONE,                 /* Need to move to a new field. */
+} entry_state;
+
+typedef struct Uploader {
+        sd_event *events;
+        sd_event_source *sigint_event, *sigterm_event;
+
+        char *url;
+        CURL *easy;
+        bool uploading;
+        char error[CURL_ERROR_SIZE];
+        struct curl_slist *header;
+        char *answer;
+
+        sd_event_source *input_event;
+        uint64_t timeout;
+
+        /* fd stuff */
+        int input;
+
+        /* journal stuff */
+        sd_journal* journal;
+
+        entry_state entry_state;
+        const void *field_data;
+        size_t field_pos, field_length;
+
+        /* general metrics */
+        const char *state_file;
+
+        size_t entries_sent;
+        char *last_cursor, *current_cursor;
+} Uploader;
+
+#define JOURNAL_UPLOAD_POLL_TIMEOUT (10 * USEC_PER_SEC)
+
+int start_upload(Uploader *u,
+                 size_t (*input_callback)(void *ptr,
+                                          size_t size,
+                                          size_t nmemb,
+                                          void *userdata),
+                 void *data);
+
+int open_journal_for_upload(Uploader *u,
+                            sd_journal *j,
+                            const char *cursor,
+                            bool after_cursor,
+                            bool follow);
+void close_journal_input(Uploader *u);
+int check_journal_input(Uploader *u);
diff --git a/src/journal-remote/log-generator.py b/src/journal-remote/log-generator.py
new file mode 100755 (executable)
index 0000000..9a8fb07
--- /dev/null
@@ -0,0 +1,68 @@
+#!/usr/bin/python
+from __future__ import print_function
+import sys
+import argparse
+
+PARSER = argparse.ArgumentParser()
+PARSER.add_argument('n', type=int)
+PARSER.add_argument('--dots', action='store_true')
+OPTIONS = PARSER.parse_args()
+
+template = """\
+__CURSOR=s=6863c726210b4560b7048889d8ada5c5;i=3e931;b=f446871715504074bf7049ef0718fa93;m={m:x};t=4fd05c
+__REALTIME_TIMESTAMP={realtime_ts}
+__MONOTONIC_TIMESTAMP={monotonic_ts}
+_BOOT_ID=f446871715504074bf7049ef0718fa93
+_TRANSPORT=syslog
+PRIORITY={priority}
+SYSLOG_FACILITY={facility}
+SYSLOG_IDENTIFIER=/USR/SBIN/CRON
+MESSAGE={message}
+_UID=0
+_GID=0
+_MACHINE_ID=69121ca41d12c1b69a7960174c27b618
+_HOSTNAME=hostname
+SYSLOG_PID=25721
+_PID=25721
+_SOURCE_REALTIME_TIMESTAMP={source_realtime_ts}
+DATA={data}
+"""
+
+m  = 0x198603b12d7
+realtime_ts = 1404101101501873
+monotonic_ts = 1753961140951
+source_realtime_ts = 1404101101483516
+priority = 3
+facility = 6
+
+src = open('/dev/urandom', 'rb')
+
+bytes = 0
+
+for i in range(OPTIONS.n):
+    message = repr(src.read(2000))
+    data = repr(src.read(4000))
+
+    entry = template.format(m=m,
+                            realtime_ts=realtime_ts,
+                            monotonic_ts=monotonic_ts,
+                            source_realtime_ts=source_realtime_ts,
+                            priority=priority,
+                            facility=facility,
+                            message=message,
+                            data=data)
+    m += 1
+    realtime_ts += 1
+    monotonic_ts += 1
+    source_realtime_ts += 1
+
+    bytes += len(entry)
+
+    print(entry)
+
+    if OPTIONS.dots:
+        print('.', file=sys.stderr, end='', flush=True)
+
+if OPTIONS.dots:
+        print(file=sys.stderr)
+print('Wrote {} bytes'.format(bytes), file=sys.stderr)
diff --git a/src/journal-remote/microhttpd-util.c b/src/journal-remote/microhttpd-util.c
new file mode 100644 (file)
index 0000000..55c45f4
--- /dev/null
@@ -0,0 +1,303 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Lennart Poettering
+  Copyright 2012 Zbigniew Jędrzejewski-Szmek
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "microhttpd-util.h"
+#include "log.h"
+#include "macro.h"
+#include "util.h"
+#include "strv.h"
+
+#ifdef HAVE_GNUTLS
+#include <gnutls/gnutls.h>
+#include <gnutls/x509.h>
+#endif
+
+void microhttpd_logger(void *arg, const char *fmt, va_list ap) {
+        char *f;
+
+        f = strappenda("microhttpd: ", fmt);
+
+        DISABLE_WARNING_FORMAT_NONLITERAL;
+        log_metav(LOG_INFO, NULL, 0, NULL, f, ap);
+        REENABLE_WARNING;
+}
+
+
+static int mhd_respond_internal(struct MHD_Connection *connection,
+                                enum MHD_RequestTerminationCode code,
+                                char *buffer,
+                                size_t size,
+                                enum MHD_ResponseMemoryMode mode) {
+        struct MHD_Response *response;
+        int r;
+
+        assert(connection);
+
+        response = MHD_create_response_from_buffer(size, buffer, mode);
+        if (!response)
+                return MHD_NO;
+
+        log_debug("Queing response %u: %s", code, buffer);
+        MHD_add_response_header(response, "Content-Type", "text/plain");
+        r = MHD_queue_response(connection, code, response);
+        MHD_destroy_response(response);
+
+        return r;
+}
+
+int mhd_respond(struct MHD_Connection *connection,
+                enum MHD_RequestTerminationCode code,
+                const char *message) {
+
+        return mhd_respond_internal(connection, code,
+                                    (char*) message, strlen(message),
+                                    MHD_RESPMEM_PERSISTENT);
+}
+
+int mhd_respond_oom(struct MHD_Connection *connection) {
+        return mhd_respond(connection, MHD_HTTP_SERVICE_UNAVAILABLE,  "Out of memory.\n");
+}
+
+int mhd_respondf(struct MHD_Connection *connection,
+                 enum MHD_RequestTerminationCode code,
+                 const char *format, ...) {
+
+        char *m;
+        int r;
+        va_list ap;
+
+        assert(connection);
+        assert(format);
+
+        va_start(ap, format);
+        r = vasprintf(&m, format, ap);
+        va_end(ap);
+
+        if (r < 0)
+                return respond_oom(connection);
+
+        return mhd_respond_internal(connection, code, m, r, MHD_RESPMEM_MUST_FREE);
+}
+
+#ifdef HAVE_GNUTLS
+
+static struct {
+        const char *const names[4];
+        int level;
+        bool enabled;
+} gnutls_log_map[] = {
+        { {"0"},                  LOG_DEBUG },
+        { {"1", "audit"},         LOG_WARNING, true}, /* gnutls session audit */
+        { {"2", "assert"},        LOG_DEBUG },        /* gnutls assert log */
+        { {"3", "hsk", "ext"},    LOG_DEBUG },        /* gnutls handshake log */
+        { {"4", "rec"},           LOG_DEBUG },        /* gnutls record log */
+        { {"5", "dtls"},          LOG_DEBUG },        /* gnutls DTLS log */
+        { {"6", "buf"},           LOG_DEBUG },
+        { {"7", "write", "read"}, LOG_DEBUG },
+        { {"8"},                  LOG_DEBUG },
+        { {"9", "enc", "int"},    LOG_DEBUG },
+};
+
+void log_func_gnutls(int level, const char *message) {
+        assert_se(message);
+
+        if (0 <= level && level < (int) ELEMENTSOF(gnutls_log_map)) {
+                if (gnutls_log_map[level].enabled)
+                        log_meta(gnutls_log_map[level].level, NULL, 0, NULL,
+                                 "gnutls %d/%s: %s", level, gnutls_log_map[level].names[1], message);
+        } else {
+                log_debug("Received GNUTLS message with unknown level %d.", level);
+                log_meta(LOG_DEBUG, NULL, 0, NULL, "gnutls: %s", message);
+        }
+}
+
+int log_enable_gnutls_category(const char *cat) {
+        unsigned i;
+
+        if (streq(cat, "all")) {
+                for (i = 0; i < ELEMENTSOF(gnutls_log_map); i++)
+                        gnutls_log_map[i].enabled = true;
+                log_reset_gnutls_level();
+                return 0;
+        } else
+                for (i = 0; i < ELEMENTSOF(gnutls_log_map); i++)
+                        if (strv_contains((char**)gnutls_log_map[i].names, cat)) {
+                                gnutls_log_map[i].enabled = true;
+                                log_reset_gnutls_level();
+                                return 0;
+                        }
+        log_error("No such log category: %s", cat);
+        return -EINVAL;
+}
+
+void log_reset_gnutls_level(void) {
+        int i;
+
+        for (i = ELEMENTSOF(gnutls_log_map) - 1; i >= 0; i--)
+                if (gnutls_log_map[i].enabled) {
+                        log_debug("Setting gnutls log level to %d", i);
+                        gnutls_global_set_log_level(i);
+                        break;
+                }
+}
+
+static int verify_cert_authorized(gnutls_session_t session) {
+        unsigned status;
+        gnutls_certificate_type_t type;
+        gnutls_datum_t out;
+        int r;
+
+        r = gnutls_certificate_verify_peers2(session, &status);
+        if (r < 0) {
+                log_error("gnutls_certificate_verify_peers2 failed: %s", strerror(-r));
+                return r;
+        }
+
+        type = gnutls_certificate_type_get(session);
+        r = gnutls_certificate_verification_status_print(status, type, &out, 0);
+        if (r < 0) {
+                log_error("gnutls_certificate_verification_status_print failed: %s", strerror(-r));
+                return r;
+        }
+
+        log_info("Certificate status: %s", out.data);
+
+        return status == 0 ? 0 : -EPERM;
+}
+
+static int get_client_cert(gnutls_session_t session, gnutls_x509_crt_t *client_cert) {
+        const gnutls_datum_t *pcert;
+        unsigned listsize;
+        gnutls_x509_crt_t cert;
+        int r;
+
+        assert(session);
+        assert(client_cert);
+
+        pcert = gnutls_certificate_get_peers(session, &listsize);
+        if (!pcert || !listsize) {
+                log_error("Failed to retrieve certificate chain");
+                return -EINVAL;
+        }
+
+        r = gnutls_x509_crt_init(&cert);
+        if (r < 0) {
+                log_error("Failed to initialize client certificate");
+                return r;
+        }
+
+        /* Note that by passing values between 0 and listsize here, you
+           can get access to the CA's certs */
+        r = gnutls_x509_crt_import(cert, &pcert[0], GNUTLS_X509_FMT_DER);
+        if (r < 0) {
+                log_error("Failed to import client certificate");
+                gnutls_x509_crt_deinit(cert);
+                return r;
+        }
+
+        *client_cert = cert;
+        return 0;
+}
+
+static int get_auth_dn(gnutls_x509_crt_t client_cert, char **buf) {
+        size_t len = 0;
+        int r;
+
+        assert(buf);
+        assert(*buf == NULL);
+
+        r = gnutls_x509_crt_get_dn(client_cert, NULL, &len);
+        if (r != GNUTLS_E_SHORT_MEMORY_BUFFER) {
+                log_error("gnutls_x509_crt_get_dn failed");
+                return r;
+        }
+
+        *buf = malloc(len);
+        if (!*buf)
+                return log_oom();
+
+        gnutls_x509_crt_get_dn(client_cert, *buf, &len);
+        return 0;
+}
+
+int check_permissions(struct MHD_Connection *connection, int *code, char **hostname) {
+        const union MHD_ConnectionInfo *ci;
+        gnutls_session_t session;
+        gnutls_x509_crt_t client_cert;
+        _cleanup_free_ char *buf = NULL;
+        int r;
+
+        assert(connection);
+        assert(code);
+
+        *code = 0;
+
+        ci = MHD_get_connection_info(connection,
+                                     MHD_CONNECTION_INFO_GNUTLS_SESSION);
+        if (!ci) {
+                log_error("MHD_get_connection_info failed: session is unencrypted");
+                *code = mhd_respond(connection, MHD_HTTP_FORBIDDEN,
+                                    "Encrypted connection is required");
+                return -EPERM;
+        }
+        session = ci->tls_session;
+        assert(session);
+
+        r = get_client_cert(session, &client_cert);
+        if (r < 0) {
+                *code = mhd_respond(connection, MHD_HTTP_UNAUTHORIZED,
+                                    "Authorization through certificate is required");
+                return -EPERM;
+        }
+
+        r = get_auth_dn(client_cert, &buf);
+        if (r < 0) {
+                *code = mhd_respond(connection, MHD_HTTP_UNAUTHORIZED,
+                                    "Failed to determine distinguished name from certificate");
+                return -EPERM;
+        }
+
+        log_info("Connection from %s", buf);
+
+        if (hostname) {
+                *hostname = buf;
+                buf = NULL;
+        }
+
+        r = verify_cert_authorized(session);
+        if (r < 0) {
+                log_warning("Client is not authorized");
+                *code = mhd_respond(connection, MHD_HTTP_UNAUTHORIZED,
+                                    "Client certificate not signed by recognized authority");
+        }
+        return r;
+}
+
+#else
+int check_permissions(struct MHD_Connection *connection, int *code, char **hostname) {
+        return -EPERM;
+}
+#endif
diff --git a/src/journal-remote/microhttpd-util.h b/src/journal-remote/microhttpd-util.h
new file mode 100644 (file)
index 0000000..c43d7f7
--- /dev/null
@@ -0,0 +1,55 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Zbigniew Jędrzejewski-Szmek
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#pragma once
+
+#include <stdarg.h>
+#include <microhttpd.h>
+
+#include "macro.h"
+
+void microhttpd_logger(void *arg, const char *fmt, va_list ap) _printf_(2, 0);
+
+/* respond_oom() must be usable with return, hence this form. */
+#define respond_oom(connection) log_oom(), mhd_respond_oom(connection)
+
+int mhd_respondf(struct MHD_Connection *connection,
+                 unsigned code,
+                 const char *format, ...) _printf_(3,4);
+
+int mhd_respond(struct MHD_Connection *connection,
+                unsigned code,
+                const char *message);
+
+int mhd_respond_oom(struct MHD_Connection *connection);
+
+int check_permissions(struct MHD_Connection *connection, int *code, char **hostname);
+
+#ifdef HAVE_GNUTLS
+void log_func_gnutls(int level, const char *message);
+int log_enable_gnutls_category(const char *cat);
+void log_reset_gnutls_level(void);
+
+/* This is additionally filtered by our internal log level, so it
+ * should be set fairly high to capture all potentially interesting
+ * events without overwhelming detail.
+ */
+#endif
index 02b7564..627c062 100644 (file)
@@ -27,7 +27,7 @@
 #include <errno.h>
 #include <fcntl.h>
 
-#include <systemd/sd-journal.h>
+#include "systemd/sd-journal.h"
 
 #include "util.h"
 #include "build.h"
@@ -36,18 +36,15 @@ static char *arg_identifier = NULL;
 static int arg_priority = LOG_INFO;
 static bool arg_level_prefix = true;
 
-static int help(void) {
-
+static void help(void) {
         printf("%s [OPTIONS...] {COMMAND} ...\n\n"
                "Execute process with stdout/stderr connected to the journal.\n\n"
                "  -h --help               Show this help\n"
                "     --version            Show package version\n"
                "  -t --identifier=STRING  Set syslog identifier\n"
                "  -p --priority=PRIORITY  Set priority value (0..7)\n"
-               "     --level-prefix=BOOL  Control whether level prefix shall be parsed\n",
-               program_invocation_short_name);
-
-        return 0;
+               "     --level-prefix=BOOL  Control whether level prefix shall be parsed\n"
+               , program_invocation_short_name);
 }
 
 static int parse_argv(int argc, char *argv[]) {
@@ -71,12 +68,13 @@ static int parse_argv(int argc, char *argv[]) {
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "+ht:p:", options, NULL)) >= 0) {
+        while ((c = getopt_long(argc, argv, "+ht:p:", options, NULL)) >= 0)
 
                 switch (c) {
 
                 case 'h':
-                        return help();
+                        help();
+                        return 0;
 
                 case ARG_VERSION:
                         puts(PACKAGE_STRING);
@@ -120,7 +118,6 @@ static int parse_argv(int argc, char *argv[]) {
                 default:
                         assert_not_reached("Unhandled option");
                 }
-        }
 
         return 1;
 }
@@ -152,7 +149,7 @@ int main(int argc, char *argv[]) {
         }
 
         if (fd >= 3)
-                close_nointr_nofail(fd);
+                safe_close(fd);
 
         fd = -1;
 
@@ -170,11 +167,8 @@ int main(int argc, char *argv[]) {
         log_error("Failed to execute process: %s", strerror(-r));
 
 finish:
-        if (fd >= 0)
-                close_nointr_nofail(fd);
-
-        if (saved_stderr >= 0)
-                close_nointr_nofail(saved_stderr);
+        safe_close(fd);
+        safe_close(saved_stderr);
 
         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
 }
index 2823232..f03357d 100644 (file)
@@ -103,7 +103,7 @@ static int finish_item(
                 const char *payload) {
 
         ssize_t offset;
-        CatalogItem *i;
+        _cleanup_free_ CatalogItem *i = NULL;
         int r;
 
         assert(h);
@@ -126,13 +126,14 @@ static int finish_item(
         i->offset = htole64((uint64_t) offset);
 
         r = hashmap_put(h, i, i);
-        if (r == EEXIST) {
+        if (r == -EEXIST) {
                 log_warning("Duplicate entry for " SD_ID128_FORMAT_STR ".%s, ignoring.",
                             SD_ID128_FORMAT_VAL(id), language ? language : "C");
-                free(i);
                 return 0;
-        }
+        } else if (r < 0)
+                return r;
 
+        i = NULL;
         return 0;
 }
 
@@ -158,6 +159,37 @@ int catalog_file_lang(const char* filename, char **lang) {
         return 1;
 }
 
+static int catalog_entry_lang(const char* filename, int line,
+                              const char* t, const char* deflang, char **lang) {
+        size_t c;
+
+        c = strlen(t);
+        if (c == 0) {
+                log_error("[%s:%u] Language too short.", filename, line);
+                return -EINVAL;
+        }
+        if (c > 31) {
+                log_error("[%s:%u] language too long.", filename, line);
+                return -EINVAL;
+        }
+
+        if (deflang) {
+                if (streq(t, deflang)) {
+                        log_warning("[%s:%u] language specified unnecessarily",
+                                    filename, line);
+                        return 0;
+                } else
+                        log_warning("[%s:%u] language differs from default for file",
+                                    filename, line);
+        }
+
+        *lang = strdup(t);
+        if (!*lang)
+                        return -ENOMEM;
+
+        return 0;
+}
+
 int catalog_import_file(Hashmap *h, struct strbuf *sb, const char *path) {
         _cleanup_fclose_ FILE *f = NULL;
         _cleanup_free_ char *payload = NULL;
@@ -237,25 +269,9 @@ int catalog_import_file(Hashmap *h, struct strbuf *sb, const char *path) {
                                 if (with_language) {
                                         t = strstrip(line + 2 + 1 + 32 + 1);
 
-                                        c = strlen(t);
-                                        if (c <= 0) {
-                                                log_error("[%s:%u] Language too short.", path, n);
-                                                return -EINVAL;
-                                        }
-                                        if (c > 31) {
-                                                log_error("[%s:%u] language too long.", path, n);
-                                                return -EINVAL;
-                                        }
-
-                                        if (deflang) {
-                                                log_warning("[%s:%u] language %s", path, n,
-                                                            streq(t, deflang) ?
-                                                            "specified unnecessarily" :
-                                                            "differs from default for file");
-                                                lang = strdup(t);
-                                                if (!lang)
-                                                        return -ENOMEM;
-                                        }
+                                        r = catalog_entry_lang(path, n, t, deflang, &lang);
+                                        if (r < 0)
+                                                return r;
                                 }
 
                                 got_id = true;
@@ -383,8 +399,8 @@ error:
 int catalog_update(const char* database, const char* root, const char* const* dirs) {
         _cleanup_strv_free_ char **files = NULL;
         char **f;
-        Hashmap *h;
         struct strbuf *sb = NULL;
+        _cleanup_hashmap_free_free_ Hashmap *h = NULL;
         _cleanup_free_ CatalogItem *items = NULL;
         CatalogItem *i;
         Iterator j;
@@ -406,13 +422,17 @@ int catalog_update(const char* database, const char* root, const char* const* di
         }
 
         STRV_FOREACH(f, files) {
-                log_debug("reading file '%s'", *f);
-                catalog_import_file(h, sb, *f);
+                log_debug("Reading file '%s'", *f);
+                r = catalog_import_file(h, sb, *f);
+                if (r < 0) {
+                        log_error("Failed to import file '%s': %s.",
+                                  *f, strerror(-r));
+                        goto finish;
+                }
         }
 
         if (hashmap_size(h) <= 0) {
                 log_info("No items in catalog.");
-                r = 0;
                 goto finish;
         } else
                 log_debug("Found %u items in catalog.", hashmap_size(h));
@@ -443,11 +463,7 @@ int catalog_update(const char* database, const char* root, const char* const* di
                 log_debug("%s: wrote %u items, with %zu bytes of strings, %ld total size.",
                           database, n, sb->len, r);
 
-        r = 0;
-
 finish:
-        if (h)
-                hashmap_free_free(h);
         if (sb)
                 strbuf_cleanup(sb);
 
@@ -469,18 +485,18 @@ static int open_mmap(const char *database, int *_fd, struct stat *_st, void **_p
                 return -errno;
 
         if (fstat(fd, &st) < 0) {
-                close_nointr_nofail(fd);
+                safe_close(fd);
                 return -errno;
         }
 
         if (st.st_size < (off_t) sizeof(CatalogHeader)) {
-                close_nointr_nofail(fd);
+                safe_close(fd);
                 return -EINVAL;
         }
 
         p = mmap(NULL, PAGE_ALIGN(st.st_size), PROT_READ, MAP_SHARED, fd, 0);
         if (p == MAP_FAILED) {
-                close_nointr_nofail(fd);
+                safe_close(fd);
                 return -errno;
         }
 
@@ -491,7 +507,7 @@ static int open_mmap(const char *database, int *_fd, struct stat *_st, void **_p
             h->incompatible_flags != 0 ||
             le64toh(h->n_items) <= 0 ||
             st.st_size < (off_t) (le64toh(h->header_size) + le64toh(h->catalog_item_size) * le64toh(h->n_items))) {
-                close_nointr_nofail(fd);
+                safe_close(fd);
                 munmap(p, st.st_size);
                 return -EBADMSG;
         }
index a4427be..52a4c10 100644 (file)
 #include <assert.h>
 #include <stdlib.h>
 #include <string.h>
-#include <lzma.h>
+#include <unistd.h>
 
-#include "macro.h"
-#include "compress.h"
+#ifdef HAVE_XZ
+#  include <lzma.h>
+#endif
 
-bool compress_blob(const void *src, uint64_t src_size, void *dst, uint64_t *dst_size) {
-        lzma_stream s = LZMA_STREAM_INIT;
+#ifdef HAVE_LZ4
+#  include <lz4.h>
+#endif
+
+#include "compress.h"
+#include "macro.h"
+#include "util.h"
+#include "sparse-endian.h"
+#include "journal-def.h"
+
+#define ALIGN_8(l) ALIGN_TO(l, sizeof(size_t))
+
+static const char* const object_compressed_table[_OBJECT_COMPRESSED_MAX] = {
+        [OBJECT_COMPRESSED_XZ] = "XZ",
+        [OBJECT_COMPRESSED_LZ4] = "LZ4",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(object_compressed, int);
+
+int compress_blob_xz(const void *src, uint64_t src_size, void *dst, size_t *dst_size) {
+#ifdef HAVE_XZ
+        static const lzma_options_lzma opt = {
+                1u << 20u, NULL, 0, LZMA_LC_DEFAULT, LZMA_LP_DEFAULT,
+                LZMA_PB_DEFAULT, LZMA_MODE_FAST, 128, LZMA_MF_HC3, 4};
+        static const lzma_filter filters[2] = {
+                {LZMA_FILTER_LZMA2, (lzma_options_lzma*) &opt},
+                {LZMA_VLI_UNKNOWN, NULL}
+        };
         lzma_ret ret;
-        bool b = false;
+        size_t out_pos = 0;
 
         assert(src);
         assert(src_size > 0);
         assert(dst);
         assert(dst_size);
 
-        /* Returns false if we couldn't compress the data or the
+        /* Returns < 0 if we couldn't compress the data or the
          * compressed result is longer than the original */
 
-        ret = lzma_easy_encoder(&s, LZMA_PRESET_DEFAULT, LZMA_CHECK_NONE);
+        if (src_size < 80)
+                return -ENOBUFS;
+
+        ret = lzma_stream_buffer_encode((lzma_filter*) filters, LZMA_CHECK_NONE, NULL,
+                                        src, src_size, dst, &out_pos, src_size - 1);
         if (ret != LZMA_OK)
-                return false;
+                return -ENOBUFS;
 
-        s.next_in = src;
-        s.avail_in = src_size;
-        s.next_out = dst;
-        s.avail_out = src_size;
+        *dst_size = out_pos;
+        return 0;
+#else
+        return -EPROTONOSUPPORT;
+#endif
+}
+
+int compress_blob_lz4(const void *src, uint64_t src_size, void *dst, size_t *dst_size) {
+#ifdef HAVE_LZ4
+        int r;
+
+        assert(src);
+        assert(src_size > 0);
+        assert(dst);
+        assert(dst_size);
 
-        /* Does it fit? */
-        if (lzma_code(&s, LZMA_FINISH) != LZMA_STREAM_END)
-                goto fail;
+        /* Returns < 0 if we couldn't compress the data or the
+         * compressed result is longer than the original */
 
-        /* Is it actually shorter? */
-        if (s.avail_out == 0)
-                goto fail;
+        if (src_size < 9)
+                return -ENOBUFS;
 
-        *dst_size = src_size - s.avail_out;
-        b = true;
+        r = LZ4_compress_limitedOutput(src, dst + 8, src_size, src_size - 8 - 1);
+        if (r <= 0)
+                return -ENOBUFS;
 
-fail:
-        lzma_end(&s);
+        *(le64_t*) dst = htole64(src_size);
+        *dst_size = r + 8;
 
-        return b;
+        return 0;
+#else
+        return -EPROTONOSUPPORT;
+#endif
 }
 
-bool uncompress_blob(const void *src, uint64_t src_size,
-                     void **dst, uint64_t *dst_alloc_size, uint64_t* dst_size, uint64_t dst_max) {
 
-        lzma_stream s = LZMA_STREAM_INIT;
+int decompress_blob_xz(const void *src, uint64_t src_size,
+                       void **dst, size_t *dst_alloc_size, size_t* dst_size, size_t dst_max) {
+
+#ifdef HAVE_XZ
+        _cleanup_(lzma_end) lzma_stream s = LZMA_STREAM_INIT;
         lzma_ret ret;
-        uint64_t space;
-        bool b = false;
+        size_t space;
 
         assert(src);
         assert(src_size > 0);
@@ -83,72 +128,113 @@ bool uncompress_blob(const void *src, uint64_t src_size,
 
         ret = lzma_stream_decoder(&s, UINT64_MAX, 0);
         if (ret != LZMA_OK)
-                return false;
-
-        if (*dst_alloc_size <= src_size) {
-                void *p;
-
-                p = realloc(*dst, src_size*2);
-                if (!p)
-                        return false;
+                return -ENOMEM;
 
-                *dst = p;
-                *dst_alloc_size = src_size*2;
-        }
+        space = MIN(src_size * 2, dst_max ?: (size_t) -1);
+        if (!greedy_realloc(dst, dst_alloc_size, space, 1))
+                return -ENOMEM;
 
         s.next_in = src;
         s.avail_in = src_size;
 
         s.next_out = *dst;
-        space = dst_max > 0 ? MIN(*dst_alloc_size, dst_max) : *dst_alloc_size;
         s.avail_out = space;
 
         for (;;) {
-                void *p;
+                size_t used;
 
                 ret = lzma_code(&s, LZMA_FINISH);
 
                 if (ret == LZMA_STREAM_END)
                         break;
-
-                if (ret != LZMA_OK)
-                        goto fail;
+                else if (ret != LZMA_OK)
+                        return -ENOMEM;
 
                 if (dst_max > 0 && (space - s.avail_out) >= dst_max)
                         break;
+                else if (dst_max > 0 && space == dst_max)
+                        return -ENOBUFS;
 
-                p = realloc(*dst, space*2);
-                if (!p)
-                        goto fail;
-
-                s.next_out = (uint8_t*) p + ((uint8_t*) s.next_out - (uint8_t*) *dst);
-                s.avail_out += space;
-
-                space *= 2;
+                used = space - s.avail_out;
+                space = MIN(2 * space, dst_max ?: (size_t) -1);
+                if (!greedy_realloc(dst, dst_alloc_size, space, 1))
+                        return -ENOMEM;
 
-                *dst = p;
-                *dst_alloc_size = space;
+                s.avail_out = space - used;
+                s.next_out = *dst + used;
         }
 
         *dst_size = space - s.avail_out;
-        b = true;
+        return 0;
+#else
+        return -EPROTONOSUPPORT;
+#endif
+}
+
+int decompress_blob_lz4(const void *src, uint64_t src_size,
+                        void **dst, size_t *dst_alloc_size, size_t* dst_size, size_t dst_max) {
+
+#ifdef HAVE_LZ4
+        char* out;
+        int r, size; /* LZ4 uses int for size */
+
+        assert(src);
+        assert(src_size > 0);
+        assert(dst);
+        assert(dst_alloc_size);
+        assert(dst_size);
+        assert(*dst_alloc_size == 0 || *dst);
 
-fail:
-        lzma_end(&s);
+        if (src_size <= 8)
+                return -EBADMSG;
+
+        size = le64toh( *(le64_t*)src );
+        if (size < 0 || (le64_t) size != *(le64_t*)src)
+                return -EFBIG;
+        if ((size_t) size > *dst_alloc_size) {
+                out = realloc(*dst, size);
+                if (!out)
+                        return -ENOMEM;
+                *dst = out;
+                *dst_alloc_size = size;
+        } else
+                out = *dst;
+
+        r = LZ4_decompress_safe(src + 8, out, src_size - 8, size);
+        if (r < 0 || r != size)
+                return -EBADMSG;
+
+        *dst_size = size;
+        return 0;
+#else
+        return -EPROTONOSUPPORT;
+#endif
+}
 
-        return b;
+int decompress_blob(int compression,
+                    const void *src, uint64_t src_size,
+                    void **dst, size_t *dst_alloc_size, size_t* dst_size, size_t dst_max) {
+        if (compression == OBJECT_COMPRESSED_XZ)
+                return decompress_blob_xz(src, src_size,
+                                          dst, dst_alloc_size, dst_size, dst_max);
+        else if (compression == OBJECT_COMPRESSED_LZ4)
+                return decompress_blob_lz4(src, src_size,
+                                           dst, dst_alloc_size, dst_size, dst_max);
+        else
+                return -EBADMSG;
 }
 
-bool uncompress_startswith(const void *src, uint64_t src_size,
-                           void **buffer, uint64_t *buffer_size,
-                           const void *prefix, uint64_t prefix_len,
-                           uint8_t extra) {
 
-        lzma_stream s = LZMA_STREAM_INIT;
+int decompress_startswith_xz(const void *src, uint64_t src_size,
+                             void **buffer, size_t *buffer_size,
+                             const void *prefix, size_t prefix_len,
+                             uint8_t extra) {
+
+#ifdef HAVE_XZ
+        _cleanup_(lzma_end) lzma_stream s = LZMA_STREAM_INIT;
         lzma_ret ret;
-        bool b = false;
 
-        /* Checks whether the uncompressed blob starts with the
+        /* Checks whether the decompressed blob starts with the
          * mentioned prefix. The byte extra needs to follow the
          * prefix */
 
@@ -161,18 +247,10 @@ bool uncompress_startswith(const void *src, uint64_t src_size,
 
         ret = lzma_stream_decoder(&s, UINT64_MAX, 0);
         if (ret != LZMA_OK)
-                return false;
-
-        if (*buffer_size <= prefix_len) {
-                void *p;
+                return -EBADMSG;
 
-                p = realloc(*buffer, prefix_len*2);
-                if (!p)
-                        return false;
-
-                *buffer = p;
-                *buffer_size = prefix_len*2;
-        }
+        if (!(greedy_realloc(buffer, buffer_size, ALIGN_8(prefix_len + 1), 1)))
+                return -ENOMEM;
 
         s.next_in = src;
         s.avail_in = src_size;
@@ -181,36 +259,417 @@ bool uncompress_startswith(const void *src, uint64_t src_size,
         s.avail_out = *buffer_size;
 
         for (;;) {
-                void *p;
-
                 ret = lzma_code(&s, LZMA_FINISH);
 
                 if (ret != LZMA_STREAM_END && ret != LZMA_OK)
-                        goto fail;
+                        return -EBADMSG;
 
-                if ((*buffer_size - s.avail_out > prefix_len) &&
-                    memcmp(*buffer, prefix, prefix_len) == 0 &&
-                    ((const uint8_t*) *buffer)[prefix_len] == extra)
-                        break;
+                if (*buffer_size - s.avail_out >= prefix_len + 1)
+                        return memcmp(*buffer, prefix, prefix_len) == 0 &&
+                                ((const uint8_t*) *buffer)[prefix_len] == extra;
 
                 if (ret == LZMA_STREAM_END)
-                        goto fail;
+                        return 0;
 
-                p = realloc(*buffer, *buffer_size*2);
-                if (!p)
-                        goto fail;
-
-                s.next_out = (uint8_t*) p + ((uint8_t*) s.next_out - (uint8_t*) *buffer);
                 s.avail_out += *buffer_size;
 
-                *buffer = p;
-                *buffer_size *= 2;
+                if (!(greedy_realloc(buffer, buffer_size, *buffer_size * 2, 1)))
+                        return -ENOMEM;
+
+                s.next_out = *buffer + *buffer_size - s.avail_out;
         }
 
-        b = true;
+#else
+        return -EPROTONOSUPPORT;
+#endif
+}
+
+int decompress_startswith_lz4(const void *src, uint64_t src_size,
+                              void **buffer, size_t *buffer_size,
+                              const void *prefix, size_t prefix_len,
+                              uint8_t extra) {
+#ifdef HAVE_LZ4
+        /* Checks whether the decompressed blob starts with the
+         * mentioned prefix. The byte extra needs to follow the
+         * prefix */
+
+        int r;
+
+        assert(src);
+        assert(src_size > 0);
+        assert(buffer);
+        assert(buffer_size);
+        assert(prefix);
+        assert(*buffer_size == 0 || *buffer);
+
+        if (src_size <= 8)
+                return -EBADMSG;
+
+        if (!(greedy_realloc(buffer, buffer_size, ALIGN_8(prefix_len + 1), 1)))
+                return -ENOMEM;
+
+        r = LZ4_decompress_safe_partial(src + 8, *buffer, src_size - 8,
+                                        prefix_len + 1, *buffer_size);
+
+        if (r < 0)
+                return -EBADMSG;
+        if ((unsigned) r >= prefix_len + 1)
+                return memcmp(*buffer, prefix, prefix_len) == 0 &&
+                        ((const uint8_t*) *buffer)[prefix_len] == extra;
+        else
+                return 0;
+
+#else
+        return -EPROTONOSUPPORT;
+#endif
+}
+
+int decompress_startswith(int compression,
+                          const void *src, uint64_t src_size,
+                          void **buffer, size_t *buffer_size,
+                          const void *prefix, size_t prefix_len,
+                          uint8_t extra) {
+        if (compression == OBJECT_COMPRESSED_XZ)
+                return decompress_startswith_xz(src, src_size,
+                                                buffer, buffer_size,
+                                                prefix, prefix_len,
+                                                extra);
+        else if (compression == OBJECT_COMPRESSED_LZ4)
+                return decompress_startswith_lz4(src, src_size,
+                                                 buffer, buffer_size,
+                                                 prefix, prefix_len,
+                                                 extra);
+        else
+                return -EBADMSG;
+}
+
+int compress_stream_xz(int fdf, int fdt, off_t max_bytes) {
+#ifdef HAVE_XZ
+        _cleanup_(lzma_end) lzma_stream s = LZMA_STREAM_INIT;
+        lzma_ret ret;
+
+        uint8_t buf[BUFSIZ], out[BUFSIZ];
+        lzma_action action = LZMA_RUN;
+
+        assert(fdf >= 0);
+        assert(fdt >= 0);
+
+        ret = lzma_easy_encoder(&s, LZMA_PRESET_DEFAULT, LZMA_CHECK_CRC64);
+        if (ret != LZMA_OK) {
+                log_error("Failed to initialize XZ encoder: code %d", ret);
+                return -EINVAL;
+        }
+
+        for (;;) {
+                if (s.avail_in == 0 && action == LZMA_RUN) {
+                        size_t m = sizeof(buf);
+                        ssize_t n;
+
+                        if (max_bytes != -1 && m > (size_t) max_bytes)
+                                m = max_bytes;
+
+                        n = read(fdf, buf, m);
+                        if (n < 0)
+                                return -errno;
+                        if (n == 0)
+                                action = LZMA_FINISH;
+                        else {
+                                s.next_in = buf;
+                                s.avail_in = n;
+
+                                if (max_bytes != -1) {
+                                        assert(max_bytes >= n);
+                                        max_bytes -= n;
+                                }
+                        }
+                }
+
+                if (s.avail_out == 0) {
+                        s.next_out = out;
+                        s.avail_out = sizeof(out);
+                }
+
+                ret = lzma_code(&s, action);
+                if (ret != LZMA_OK && ret != LZMA_STREAM_END) {
+                        log_error("Compression failed: code %d", ret);
+                        return -EBADMSG;
+                }
+
+                if (s.avail_out == 0 || ret == LZMA_STREAM_END) {
+                        ssize_t n, k;
+
+                        n = sizeof(out) - s.avail_out;
+
+                        errno = 0;
+                        k = loop_write(fdt, out, n, false);
+                        if (k < 0)
+                                return k;
+                        if (k != n)
+                                return errno ? -errno : -EIO;
+
+                        if (ret == LZMA_STREAM_END) {
+                                log_debug("XZ compression finished (%"PRIu64" -> %"PRIu64" bytes, %.1f%%)",
+                                          s.total_in, s.total_out,
+                                          (double) s.total_out / s.total_in * 100);
+
+                                return 0;
+                        }
+                }
+        }
+#else
+        return -EPROTONOSUPPORT;
+#endif
+}
+
+#define LZ4_BUFSIZE (512*1024)
+
+int compress_stream_lz4(int fdf, int fdt, off_t max_bytes) {
+
+#ifdef HAVE_LZ4
+
+        _cleanup_free_ char *buf1 = NULL, *buf2 = NULL, *out = NULL;
+        char *buf;
+        LZ4_stream_t lz4_data = {};
+        le32_t header;
+        size_t total_in = 0, total_out = sizeof(header);
+        ssize_t n;
+
+        assert(fdf >= 0);
+        assert(fdt >= 0);
+
+        buf1 = malloc(LZ4_BUFSIZE);
+        buf2 = malloc(LZ4_BUFSIZE);
+        out = malloc(LZ4_COMPRESSBOUND(LZ4_BUFSIZE));
+        if (!buf1 || !buf2 || !out)
+                return log_oom();
+
+        buf = buf1;
+        for (;;) {
+                size_t m;
+                int r;
+
+                m = LZ4_BUFSIZE;
+                if (max_bytes != -1 && m > (size_t) max_bytes - total_in)
+                        m = max_bytes - total_in;
+
+                n = read(fdf, buf, m);
+                if (n < 0)
+                        return -errno;
+                if (n == 0)
+                        break;
+
+                total_in += n;
+
+                r = LZ4_compress_limitedOutput_continue(&lz4_data, buf, out, n, n);
+                if (r == 0) {
+                        log_debug("Compressed size exceeds original, aborting compression.");
+                        return -ENOBUFS;
+                }
+
+                header = htole32(r);
+                errno = 0;
+
+                n = write(fdt, &header, sizeof(header));
+                if (n < 0)
+                        return -errno;
+                if (n != sizeof(header))
+                        return errno ? -errno : -EIO;
+
+                n = loop_write(fdt, out, r, false);
+                if (n < 0)
+                        return n;
+                if (n != r)
+                        return errno ? -errno : -EIO;
+
+                total_out += sizeof(header) + r;
+
+                buf = buf == buf1 ? buf2 : buf1;
+        }
+
+        header = htole32(0);
+        n = write(fdt, &header, sizeof(header));
+        if (n < 0)
+                return -errno;
+        if (n != sizeof(header))
+                return errno ? -errno : -EIO;
+
+        log_debug("LZ4 compression finished (%zu -> %zu bytes, %.1f%%)",
+                  total_in, total_out,
+                  (double) total_out / total_in * 100);
+
+        return 0;
+#else
+        return -EPROTONOSUPPORT;
+#endif
+}
+
+int decompress_stream_xz(int fdf, int fdt, off_t max_bytes) {
+
+#ifdef HAVE_XZ
+        _cleanup_(lzma_end) lzma_stream s = LZMA_STREAM_INIT;
+        lzma_ret ret;
+
+        uint8_t buf[BUFSIZ], out[BUFSIZ];
+        lzma_action action = LZMA_RUN;
+
+        assert(fdf >= 0);
+        assert(fdt >= 0);
+
+        ret = lzma_stream_decoder(&s, UINT64_MAX, 0);
+        if (ret != LZMA_OK) {
+                log_error("Failed to initialize XZ decoder: code %d", ret);
+                return -ENOMEM;
+        }
+
+        for (;;) {
+                if (s.avail_in == 0 && action == LZMA_RUN) {
+                        ssize_t n;
+
+                        n = read(fdf, buf, sizeof(buf));
+                        if (n < 0)
+                                return -errno;
+                        if (n == 0)
+                                action = LZMA_FINISH;
+                        else {
+                                s.next_in = buf;
+                                s.avail_in = n;
+                        }
+                }
+
+                if (s.avail_out == 0) {
+                        s.next_out = out;
+                        s.avail_out = sizeof(out);
+                }
+
+                ret = lzma_code(&s, action);
+                if (ret != LZMA_OK && ret != LZMA_STREAM_END) {
+                        log_error("Decompression failed: code %d", ret);
+                        return -EBADMSG;
+                }
+
+                if (s.avail_out == 0 || ret == LZMA_STREAM_END) {
+                        ssize_t n, k;
+
+                        n = sizeof(out) - s.avail_out;
+
+                        if (max_bytes != -1) {
+                                if (max_bytes < n)
+                                        return -EFBIG;
+
+                                max_bytes -= n;
+                        }
+
+                        errno = 0;
+                        k = loop_write(fdt, out, n, false);
+                        if (k < 0)
+                                return k;
+                        if (k != n)
+                                return errno ? -errno : -EIO;
+
+                        if (ret == LZMA_STREAM_END) {
+                                log_debug("XZ decompression finished (%"PRIu64" -> %"PRIu64" bytes, %.1f%%)",
+                                          s.total_in, s.total_out,
+                                          (double) s.total_out / s.total_in * 100);
+
+                                return 0;
+                        }
+                }
+        }
+#else
+        log_error("Cannot decompress file. Compiled without XZ support.");
+        return -EPROTONOSUPPORT;
+#endif
+}
+
+int decompress_stream_lz4(int fdf, int fdt, off_t max_bytes) {
+
+#ifdef HAVE_LZ4
+        _cleanup_free_ char *buf = NULL, *out = NULL;
+        size_t buf_size = 0;
+        LZ4_streamDecode_t lz4_data = {};
+        le32_t header;
+        size_t total_in = sizeof(header), total_out = 0;
+
+        assert(fdf >= 0);
+        assert(fdt >= 0);
+
+        out = malloc(4*LZ4_BUFSIZE);
+        if (!out)
+                return log_oom();
+
+        for (;;) {
+                ssize_t n, m;
+                int r;
+
+                n = read(fdf, &header, sizeof(header));
+                if (n < 0)
+                        return -errno;
+                if (n != sizeof(header))
+                        return errno ? -errno : -EIO;
+
+                m = le32toh(header);
+                if (m == 0)
+                        break;
+
+                /* We refuse to use a bigger decompression buffer than
+                 * the one used for compression by 4 times. This means
+                 * that compression buffer size can be enlarged 4
+                 * times. This can be changed, but old binaries might
+                 * not accept buffers compressed by newer binaries then.
+                 */
+                if (m > LZ4_COMPRESSBOUND(LZ4_BUFSIZE * 4)) {
+                        log_error("Compressed stream block too big: %zd bytes", m);
+                        return -EBADMSG;
+                }
+
+                total_in += sizeof(header) + m;
+
+                if (!GREEDY_REALLOC(buf, buf_size, m))
+                        return log_oom();
+
+                errno = 0;
+                n = loop_read(fdf, buf, m, false);
+                if (n < 0)
+                        return n;
+                if (n != m)
+                        return errno ? -errno : -EIO;
+
+                r = LZ4_decompress_safe_continue(&lz4_data, buf, out, m, 4*LZ4_BUFSIZE);
+                if (r <= 0)
+                        log_error("LZ4 decompression failed.");
+
+                total_out += r;
+
+                if (max_bytes != -1 && total_out > (size_t) max_bytes) {
+                        log_debug("Decompressed stream longer than %zd bytes", max_bytes);
+                        return -EFBIG;
+                }
+
+                errno = 0;
+                n = loop_write(fdt, out, r, false);
+                if (n < 0)
+                        return n;
+                if (n != r)
+                        return errno ? -errno : -EIO;
+        }
+
+        log_debug("LZ4 decompression finished (%zu -> %zu bytes, %.1f%%)",
+                  total_in, total_out,
+                  (double) total_out / total_in * 100);
+
+        return 0;
+#else
+        log_error("Cannot decompress file. Compiled without LZ4 support.");
+        return -EPROTONOSUPPORT;
+#endif
+}
 
-fail:
-        lzma_end(&s);
+int decompress_stream(const char *filename, int fdf, int fdt, off_t max_bytes) {
 
-        return b;
+        if (endswith(filename, ".lz4"))
+                return decompress_stream_lz4(fdf, fdt, max_bytes);
+        else if (endswith(filename, ".xz"))
+                return decompress_stream_xz(fdf, fdt, max_bytes);
+        else
+                return -EPROTONOSUPPORT;
 }
index 2b87e73..136dda6 100644 (file)
 
 #include <inttypes.h>
 #include <stdbool.h>
+#include <unistd.h>
 
-bool compress_blob(const void *src, uint64_t src_size, void *dst, uint64_t *dst_size);
+#include "journal-def.h"
 
-bool uncompress_blob(const void *src, uint64_t src_size,
-                     void **dst, uint64_t *dst_alloc_size, uint64_t* dst_size, uint64_t dst_max);
+const char* object_compressed_to_string(int compression);
+int object_compressed_from_string(const char *compression);
 
-bool uncompress_startswith(const void *src, uint64_t src_size,
-                           void **buffer, uint64_t *buffer_size,
-                           const void *prefix, uint64_t prefix_len,
-                           uint8_t extra);
+int compress_blob_xz(const void *src, uint64_t src_size, void *dst, size_t *dst_size);
+int compress_blob_lz4(const void *src, uint64_t src_size, void *dst, size_t *dst_size);
+
+static inline int compress_blob(const void *src, uint64_t src_size, void *dst, size_t *dst_size) {
+        int r;
+#ifdef HAVE_LZ4
+        r = compress_blob_lz4(src, src_size, dst, dst_size);
+        if (r == 0)
+                return OBJECT_COMPRESSED_LZ4;
+#else
+        r = compress_blob_xz(src, src_size, dst, dst_size);
+        if (r == 0)
+                return OBJECT_COMPRESSED_XZ;
+#endif
+        return r;
+}
+
+int decompress_blob_xz(const void *src, uint64_t src_size,
+                       void **dst, size_t *dst_alloc_size, size_t* dst_size, size_t dst_max);
+int decompress_blob_lz4(const void *src, uint64_t src_size,
+                        void **dst, size_t *dst_alloc_size, size_t* dst_size, size_t dst_max);
+int decompress_blob(int compression,
+                    const void *src, uint64_t src_size,
+                    void **dst, size_t *dst_alloc_size, size_t* dst_size, size_t dst_max);
+
+int decompress_startswith_xz(const void *src, uint64_t src_size,
+                             void **buffer, size_t *buffer_size,
+                             const void *prefix, size_t prefix_len,
+                             uint8_t extra);
+int decompress_startswith_lz4(const void *src, uint64_t src_size,
+                              void **buffer, size_t *buffer_size,
+                              const void *prefix, size_t prefix_len,
+                              uint8_t extra);
+int decompress_startswith(int compression,
+                          const void *src, uint64_t src_size,
+                          void **buffer, size_t *buffer_size,
+                          const void *prefix, size_t prefix_len,
+                          uint8_t extra);
+
+int compress_stream_xz(int fdf, int fdt, off_t max_bytes);
+int compress_stream_lz4(int fdf, int fdt, off_t max_bytes);
+
+int decompress_stream_xz(int fdf, int fdt, off_t max_size);
+int decompress_stream_lz4(int fdf, int fdt, off_t max_size);
+
+#ifdef HAVE_LZ4
+#  define compress_stream compress_stream_lz4
+#  define COMPRESSED_EXT ".lz4"
+#else
+#  define compress_stream compress_stream_xz
+#  define COMPRESSED_EXT ".xz"
+#endif
+
+int decompress_stream(const char *filename, int fdf, int fdt, off_t max_bytes);
diff --git a/src/journal/coredump-vacuum.c b/src/journal/coredump-vacuum.c
new file mode 100644 (file)
index 0000000..125bb3a
--- /dev/null
@@ -0,0 +1,272 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/statvfs.h>
+
+#include "util.h"
+#include "time-util.h"
+#include "hashmap.h"
+#include "macro.h"
+
+#include "coredump-vacuum.h"
+
+#define DEFAULT_MAX_USE_LOWER (off_t) (1ULL*1024ULL*1024ULL)           /* 1 MiB */
+#define DEFAULT_MAX_USE_UPPER (off_t) (4ULL*1024ULL*1024ULL*1024ULL)   /* 4 GiB */
+#define DEFAULT_KEEP_FREE_UPPER (off_t) (4ULL*1024ULL*1024ULL*1024ULL) /* 4 GiB */
+#define DEFAULT_KEEP_FREE (off_t) (1024ULL*1024ULL)                    /* 1 MB */
+
+struct vacuum_candidate {
+        unsigned n_files;
+        char *oldest_file;
+        usec_t oldest_mtime;
+};
+
+static void vacuum_candidate_free(struct vacuum_candidate *c) {
+        if (!c)
+                return;
+
+        free(c->oldest_file);
+        free(c);
+}
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(struct vacuum_candidate*, vacuum_candidate_free);
+
+static void vacuum_candidate_hasmap_free(Hashmap *h) {
+        struct vacuum_candidate *c;
+
+        while ((c = hashmap_steal_first(h)))
+                vacuum_candidate_free(c);
+
+        hashmap_free(h);
+}
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, vacuum_candidate_hasmap_free);
+
+static int uid_from_file_name(const char *filename, uid_t *uid) {
+        const char *p, *e, *u;
+
+        p = startswith(filename, "core.");
+        if (!p)
+                return -EINVAL;
+
+        /* Skip the comm field */
+        p = strchr(p, '.');
+        if (!p)
+                return -EINVAL;
+        p++;
+
+        /* Find end up UID */
+        e = strchr(p, '.');
+        if (!e)
+                return -EINVAL;
+
+        u = strndupa(p, e-p);
+        return parse_uid(u, uid);
+}
+
+static bool vacuum_necessary(int fd, off_t sum, off_t keep_free, off_t max_use) {
+        off_t fs_size = 0, fs_free = (off_t) -1;
+        struct statvfs sv;
+
+        assert(fd >= 0);
+
+        if (fstatvfs(fd, &sv) >= 0) {
+                fs_size = sv.f_frsize * sv.f_blocks;
+                fs_free = sv.f_frsize * sv.f_bfree;
+        }
+
+        if (max_use == (off_t) -1) {
+
+                if (fs_size > 0) {
+                        max_use = PAGE_ALIGN(fs_size / 10); /* 10% */
+
+                        if (max_use > DEFAULT_MAX_USE_UPPER)
+                                max_use = DEFAULT_MAX_USE_UPPER;
+
+                        if (max_use < DEFAULT_MAX_USE_LOWER)
+                                max_use = DEFAULT_MAX_USE_LOWER;
+                }
+                else
+                        max_use = DEFAULT_MAX_USE_LOWER;
+        } else
+                max_use = PAGE_ALIGN(max_use);
+
+        if (max_use > 0 && sum > max_use)
+                return true;
+
+        if (keep_free == (off_t) -1) {
+
+                if (fs_size > 0) {
+                        keep_free = PAGE_ALIGN((fs_size * 3) / 20); /* 15% */
+
+                        if (keep_free > DEFAULT_KEEP_FREE_UPPER)
+                                keep_free = DEFAULT_KEEP_FREE_UPPER;
+                } else
+                        keep_free = DEFAULT_KEEP_FREE;
+        } else
+                keep_free = PAGE_ALIGN(keep_free);
+
+        if (keep_free > 0 && fs_free < keep_free)
+                return true;
+
+        return false;
+}
+
+int coredump_vacuum(int exclude_fd, off_t keep_free, off_t max_use) {
+        _cleanup_closedir_ DIR *d = NULL;
+        struct stat exclude_st;
+        int r;
+
+        if (keep_free <= 0 && max_use <= 0)
+                return 0;
+
+        if (exclude_fd >= 0) {
+                if (fstat(exclude_fd, &exclude_st) < 0) {
+                        log_error("Failed to fstat(): %m");
+                        return -errno;
+                }
+        }
+
+        /* This algorithm will keep deleting the oldest file of the
+         * user with the most coredumps until we are back in the size
+         * limits. Note that vacuuming for journal files is different,
+         * because we rely on rate-limiting of the messages there,
+         * to avoid being flooded. */
+
+        d = opendir("/var/lib/systemd/coredump");
+        if (!d) {
+                if (errno == ENOENT)
+                        return 0;
+
+                log_error("Can't open coredump directory: %m");
+                return -errno;
+        }
+
+        for (;;) {
+                _cleanup_(vacuum_candidate_hasmap_freep) Hashmap *h = NULL;
+                struct vacuum_candidate *worst = NULL;
+                struct dirent *de;
+                off_t sum = 0;
+
+                rewinddir(d);
+
+                FOREACH_DIRENT(de, d, goto fail) {
+                        struct vacuum_candidate *c;
+                        struct stat st;
+                        uid_t uid;
+                        usec_t t;
+
+                        r = uid_from_file_name(de->d_name, &uid);
+                        if (r < 0)
+                                continue;
+
+                        if (fstatat(dirfd(d), de->d_name, &st, AT_NO_AUTOMOUNT|AT_SYMLINK_NOFOLLOW) < 0) {
+                                if (errno == ENOENT)
+                                        continue;
+
+                                log_warning("Failed to stat /var/lib/systemd/coredump/%s", de->d_name);
+                                continue;
+                        }
+
+                        if (!S_ISREG(st.st_mode))
+                                continue;
+
+                        if (exclude_fd >= 0 &&
+                            exclude_st.st_dev == st.st_dev &&
+                            exclude_st.st_ino == st.st_ino)
+                                continue;
+
+                        r = hashmap_ensure_allocated(&h, NULL, NULL);
+                        if (r < 0)
+                                return log_oom();
+
+                        t = timespec_load(&st.st_mtim);
+
+                        c = hashmap_get(h, UINT32_TO_PTR(uid));
+                        if (c) {
+
+                                if (t < c->oldest_mtime) {
+                                        char *n;
+
+                                        n = strdup(de->d_name);
+                                        if (!n)
+                                                return log_oom();
+
+                                        free(c->oldest_file);
+                                        c->oldest_file = n;
+                                        c->oldest_mtime = t;
+                                }
+
+                        } else {
+                                _cleanup_(vacuum_candidate_freep) struct vacuum_candidate *n = NULL;
+
+                                n = new0(struct vacuum_candidate, 1);
+                                if (!n)
+                                        return log_oom();
+
+                                n->oldest_file = strdup(de->d_name);
+                                if (!n->oldest_file)
+                                        return log_oom();
+
+                                n->oldest_mtime = t;
+
+                                r = hashmap_put(h, UINT32_TO_PTR(uid), n);
+                                if (r < 0)
+                                        return log_oom();
+
+                                c = n;
+                                n = NULL;
+                        }
+
+                        c->n_files++;
+
+                        if (!worst ||
+                            worst->n_files < c->n_files ||
+                            (worst->n_files == c->n_files && c->oldest_mtime < worst->oldest_mtime))
+                                worst = c;
+
+                        sum += st.st_blocks * 512;
+                }
+
+                if (!worst)
+                        break;
+
+                r = vacuum_necessary(dirfd(d), sum, keep_free, max_use);
+                if (r <= 0)
+                        return r;
+
+                if (unlinkat(dirfd(d), worst->oldest_file, 0) < 0) {
+
+                        if (errno == ENOENT)
+                                continue;
+
+                        log_error("Failed to remove file %s: %m", worst->oldest_file);
+                        return -errno;
+                } else
+                        log_info("Removed old coredump %s.", worst->oldest_file);
+        }
+
+        return 0;
+
+fail:
+        log_error("Failed to read directory: %m");
+        return -errno;
+}
similarity index 82%
rename from src/journal/microhttpd-util.h
rename to src/journal/coredump-vacuum.h
index 74d1668..7ad4399 100644 (file)
@@ -1,9 +1,11 @@
 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
 
+#pragma once
+
 /***
   This file is part of systemd.
 
-  Copyright 2012 Zbigniew Jędrzejewski-Szmek
+  Copyright 2014 Lennart Poettering
 
   systemd is free software; you can redistribute it and/or modify it
   under the terms of the GNU Lesser General Public License as published by
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
-#pragma once
-
-#include <stdarg.h>
-
-#include "macro.h"
+#include <sys/types.h>
 
-void microhttpd_logger(void *arg, const char *fmt, va_list ap) _printf_(2, 0);
+int coredump_vacuum(int exclude_fd, off_t keep_free, off_t max_use);
index 733373b..79f51d1 100644 (file)
 #include <unistd.h>
 #include <stdio.h>
 #include <sys/prctl.h>
+#include <sys/types.h>
+#include <sys/xattr.h>
 
-#include <systemd/sd-journal.h>
-
-#ifdef HAVE_LOGIND
-#include <systemd/sd-login.h>
+#ifdef HAVE_ELFUTILS
+#  include <dwarf.h>
+#  include <elfutils/libdwfl.h>
 #endif
 
+#include "systemd/sd-journal.h"
+#include "systemd/sd-login.h"
+
 #include "log.h"
 #include "util.h"
+#include "strv.h"
 #include "macro.h"
 #include "mkdir.h"
 #include "special.h"
 #include "cgroup-util.h"
+#include "journald-native.h"
+#include "conf-parser.h"
+#include "copy.h"
+#include "stacktrace.h"
+#include "path-util.h"
+#include "compress.h"
+#include "coredump-vacuum.h"
+
+#ifdef HAVE_ACL
+#  include <sys/acl.h>
+#  include "acl-util.h"
+#endif
+
+/* The maximum size up to which we process coredumps */
+#define PROCESS_SIZE_MAX ((off_t) (2LLU*1024LLU*1024LLU*1024LLU))
+
+/* The maximum size up to which we leave the coredump around on
+ * disk */
+#define EXTERNAL_SIZE_MAX PROCESS_SIZE_MAX
+
+/* The maximum size up to which we store the coredump in the
+ * journal */
+#define JOURNAL_SIZE_MAX ((size_t) (767LU*1024LU*1024LU))
 
-/* Few programs have less than 3MiB resident */
-#define COREDUMP_MIN_START (3*1024*1024)
 /* Make sure to not make this larger than the maximum journal entry
- * size. See ENTRY_SIZE_MAX in journald-native.c. */
-#define COREDUMP_MAX (767*1024*1024)
+ * size. See DATA_SIZE_MAX in journald-native.c. */
+assert_cc(JOURNAL_SIZE_MAX <= DATA_SIZE_MAX);
 
 enum {
-        ARG_PID = 1,
-        ARG_UID,
-        ARG_GID,
-        ARG_SIGNAL,
-        ARG_TIMESTAMP,
-        ARG_COMM,
-        _ARG_MAX
+        INFO_PID,
+        INFO_UID,
+        INFO_GID,
+        INFO_SIGNAL,
+        INFO_TIMESTAMP,
+        INFO_COMM,
+        INFO_EXE,
+        _INFO_LEN
 };
 
-static int divert_coredump(void) {
-        _cleanup_fclose_ FILE *f = NULL;
+typedef enum CoredumpStorage {
+        COREDUMP_STORAGE_NONE,
+        COREDUMP_STORAGE_EXTERNAL,
+        COREDUMP_STORAGE_JOURNAL,
+        COREDUMP_STORAGE_BOTH,
+        _COREDUMP_STORAGE_MAX,
+        _COREDUMP_STORAGE_INVALID = -1
+} CoredumpStorage;
+
+static const char* const coredump_storage_table[_COREDUMP_STORAGE_MAX] = {
+        [COREDUMP_STORAGE_NONE] = "none",
+        [COREDUMP_STORAGE_EXTERNAL] = "external",
+        [COREDUMP_STORAGE_JOURNAL] = "journal",
+        [COREDUMP_STORAGE_BOTH] = "both",
+};
+
+DEFINE_PRIVATE_STRING_TABLE_LOOKUP(coredump_storage, CoredumpStorage);
+static DEFINE_CONFIG_PARSE_ENUM(config_parse_coredump_storage, coredump_storage, CoredumpStorage, "Failed to parse storage setting");
+
+static CoredumpStorage arg_storage = COREDUMP_STORAGE_EXTERNAL;
+static bool arg_compress = true;
+static off_t arg_process_size_max = PROCESS_SIZE_MAX;
+static off_t arg_external_size_max = EXTERNAL_SIZE_MAX;
+static size_t arg_journal_size_max = JOURNAL_SIZE_MAX;
+static off_t arg_keep_free = (off_t) -1;
+static off_t arg_max_use = (off_t) -1;
+
+static int parse_config(void) {
+        static const ConfigTableItem items[] = {
+                { "Coredump", "Storage",          config_parse_coredump_storage,  0, &arg_storage           },
+                { "Coredump", "Compress",         config_parse_bool,              0, &arg_compress          },
+                { "Coredump", "ProcessSizeMax",   config_parse_iec_off,           0, &arg_process_size_max  },
+                { "Coredump", "ExternalSizeMax",  config_parse_iec_off,           0, &arg_external_size_max },
+                { "Coredump", "JournalSizeMax",   config_parse_iec_size,          0, &arg_journal_size_max  },
+                { "Coredump", "KeepFree",         config_parse_iec_off,           0, &arg_keep_free         },
+                { "Coredump", "MaxUse",           config_parse_iec_off,           0, &arg_max_use           },
+                {}
+        };
+
+        return config_parse(NULL, "/etc/systemd/coredump.conf", NULL,
+                            "Coredump\0",
+                            config_item_table_lookup, items,
+                            false, false, true, NULL);
+}
+
+static int fix_acl(int fd, uid_t uid) {
+
+#ifdef HAVE_ACL
+        _cleanup_(acl_freep) acl_t acl = NULL;
+        acl_entry_t entry;
+        acl_permset_t permset;
+
+        assert(fd >= 0);
 
-        log_info("Detected coredump of the journal daemon itself, diverting coredump to /var/lib/systemd/coredump/.");
+        if (uid <= SYSTEM_UID_MAX)
+                return 0;
+
+        /* Make sure normal users can read (but not write or delete)
+         * their own coredumps */
+
+        acl = acl_get_fd(fd);
+        if (!acl) {
+                log_error("Failed to get ACL: %m");
+                return -errno;
+        }
+
+        if (acl_create_entry(&acl, &entry) < 0 ||
+            acl_set_tag_type(entry, ACL_USER) < 0 ||
+            acl_set_qualifier(entry, &uid) < 0) {
+                log_error("Failed to patch ACL: %m");
+                return -errno;
+        }
+
+        if (acl_get_permset(entry, &permset) < 0 ||
+            acl_add_perm(permset, ACL_READ) < 0 ||
+            calc_acl_mask_if_needed(&acl) < 0) {
+                log_warning("Failed to patch ACL: %m");
+                return -errno;
+        }
+
+        if (acl_set_fd(fd, acl) < 0) {
+                log_error("Failed to apply ACL: %m");
+                return -errno;
+        }
+#endif
+
+        return 0;
+}
+
+static int fix_xattr(int fd, const char *info[_INFO_LEN]) {
+
+        static const char * const xattrs[_INFO_LEN] = {
+                [INFO_PID] = "user.coredump.pid",
+                [INFO_UID] = "user.coredump.uid",
+                [INFO_GID] = "user.coredump.gid",
+                [INFO_SIGNAL] = "user.coredump.signal",
+                [INFO_TIMESTAMP] = "user.coredump.timestamp",
+                [INFO_COMM] = "user.coredump.comm",
+                [INFO_EXE] = "user.coredump.exe",
+        };
+
+        int r = 0;
+        unsigned i;
+
+        assert(fd >= 0);
+
+        /* Attach some metadata to coredumps via extended
+         * attributes. Just because we can. */
+
+        for (i = 0; i < _INFO_LEN; i++) {
+                int k;
+
+                if (isempty(info[i]) || !xattrs[i])
+                        continue;
+
+                k = fsetxattr(fd, xattrs[i], info[i], strlen(info[i]), XATTR_CREATE);
+                if (k < 0 && r == 0)
+                        r = -errno;
+        }
+
+        return r;
+}
+
+#define filename_escape(s) xescape((s), "./ ")
+
+static int fix_permissions(
+                int fd,
+                const char *filename,
+                const char *target,
+                const char *info[_INFO_LEN],
+                uid_t uid) {
+
+        assert(fd >= 0);
+        assert(filename);
+        assert(target);
+        assert(info);
+
+        /* Ignore errors on these */
+        fchmod(fd, 0640);
+        fix_acl(fd, uid);
+        fix_xattr(fd, info);
+
+        if (fsync(fd) < 0) {
+                log_error("Failed to sync coredump %s: %m", filename);
+                return -errno;
+        }
+
+        if (rename(filename, target) < 0) {
+                log_error("Failed to rename coredump %s -> %s: %m", filename, target);
+                return -errno;
+        }
+
+        return 0;
+}
+
+static int maybe_remove_external_coredump(const char *filename, off_t size) {
+
+        /* Returns 1 if might remove, 0 if will not remove, < 0 on error. */
+
+        if (IN_SET(arg_storage, COREDUMP_STORAGE_EXTERNAL, COREDUMP_STORAGE_BOTH) &&
+            size <= arg_external_size_max)
+                return 0;
+
+        if (!filename)
+                return 1;
+
+        if (unlink(filename) < 0 && errno != ENOENT) {
+                log_error("Failed to unlink %s: %m", filename);
+                return -errno;
+        }
+
+        return 1;
+}
+
+static int make_filename(const char *info[_INFO_LEN], char **ret) {
+        _cleanup_free_ char *c = NULL, *u = NULL, *p = NULL, *t = NULL;
+        sd_id128_t boot;
+        int r;
+
+        assert(info);
+
+        c = filename_escape(info[INFO_COMM]);
+        if (!c)
+                return -ENOMEM;
+
+        u = filename_escape(info[INFO_UID]);
+        if (!u)
+                return -ENOMEM;
+
+        r = sd_id128_get_boot(&boot);
+        if (r < 0)
+                return r;
+
+        p = filename_escape(info[INFO_PID]);
+        if (!p)
+                return -ENOMEM;
+
+        t = filename_escape(info[INFO_TIMESTAMP]);
+        if (!t)
+                return -ENOMEM;
+
+        if (asprintf(ret,
+                     "/var/lib/systemd/coredump/core.%s.%s." SD_ID128_FORMAT_STR ".%s.%s000000",
+                     c,
+                     u,
+                     SD_ID128_FORMAT_VAL(boot),
+                     p,
+                     t) < 0)
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int save_external_coredump(
+                const char *info[_INFO_LEN],
+                uid_t uid,
+                char **ret_filename,
+                int *ret_fd,
+                off_t *ret_size) {
+
+        _cleanup_free_ char *fn = NULL, *tmp = NULL;
+        _cleanup_close_ int fd = -1;
+        struct stat st;
+        int r;
+
+        assert(info);
+        assert(ret_filename);
+        assert(ret_fd);
+        assert(ret_size);
+
+        r = make_filename(info, &fn);
+        if (r < 0) {
+                log_error("Failed to determine coredump file name: %s", strerror(-r));
+                return r;
+        }
+
+        tmp = tempfn_random(fn);
+        if (!tmp)
+                return log_oom();
 
         mkdir_p_label("/var/lib/systemd/coredump", 0755);
 
-        f = fopen("/var/lib/systemd/coredump/core.systemd-journald", "we");
-        if (!f) {
-                log_error("Failed to create coredump file: %m");
+        fd = open(tmp, O_CREAT|O_EXCL|O_RDWR|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0640);
+        if (fd < 0) {
+                log_error("Failed to create coredump file %s: %m", tmp);
                 return -errno;
         }
 
-        for (;;) {
-                uint8_t buffer[4096];
-                size_t l, q;
+        r = copy_bytes(STDIN_FILENO, fd, arg_process_size_max);
+        if (r == -E2BIG) {
+                log_error("Coredump of %s (%s) is larger than configured processing limit, refusing.", info[INFO_PID], info[INFO_COMM]);
+                goto fail;
+        } else if (IN_SET(r, -EDQUOT, -ENOSPC)) {
+                log_error("Not enough disk space for coredump of %s (%s), refusing.", info[INFO_PID], info[INFO_COMM]);
+                goto fail;
+        } else if (r < 0) {
+                log_error("Failed to dump coredump to file: %s", strerror(-r));
+                goto fail;
+        }
 
-                l = fread(buffer, 1, sizeof(buffer), stdin);
-                if (l <= 0) {
-                        if (ferror(f)) {
-                                log_error("Failed to read coredump: %m");
-                                return -errno;
-                        }
+        if (fstat(fd, &st) < 0) {
+                log_error("Failed to fstat coredump %s: %m", tmp);
+                goto fail;
+        }
+
+        if (lseek(fd, 0, SEEK_SET) == (off_t) -1) {
+                log_error("Failed to seek on %s: %m", tmp);
+                goto fail;
+        }
 
-                        break;
+#if defined(HAVE_XZ) || defined(HAVE_LZ4)
+        /* If we will remove the coredump anyway, do not compress. */
+        if (maybe_remove_external_coredump(NULL, st.st_size) == 0
+            && arg_compress) {
+
+                _cleanup_free_ char *fn_compressed = NULL, *tmp_compressed = NULL;
+                _cleanup_close_ int fd_compressed = -1;
+
+                fn_compressed = strappend(fn, COMPRESSED_EXT);
+                if (!fn_compressed) {
+                        log_oom();
+                        goto uncompressed;
                 }
 
-                q = fwrite(buffer, 1, l, f);
-                if (q != l) {
-                        log_error("Failed to write coredump: %m");
-                        return -errno;
+                tmp_compressed = tempfn_random(fn_compressed);
+                if (!tmp_compressed) {
+                        log_oom();
+                        goto uncompressed;
                 }
+
+                fd_compressed = open(tmp_compressed, O_CREAT|O_EXCL|O_RDWR|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0640);
+                if (fd_compressed < 0) {
+                        log_error("Failed to create file %s: %m", tmp_compressed);
+                        goto uncompressed;
+                }
+
+                r = compress_stream(fd, fd_compressed, -1);
+                if (r < 0) {
+                        log_error("Failed to compress %s: %s", tmp_compressed, strerror(-r));
+                        goto fail_compressed;
+                }
+
+                r = fix_permissions(fd_compressed, tmp_compressed, fn_compressed, info, uid);
+                if (r < 0)
+                        goto fail_compressed;
+
+                /* OK, this worked, we can get rid of the uncompressed version now */
+                unlink_noerrno(tmp);
+
+                *ret_filename = fn_compressed;    /* compressed */
+                *ret_fd = fd;                     /* uncompressed */
+                *ret_size = st.st_size;           /* uncompressed */
+
+                fn_compressed = NULL;
+                fd = -1;
+
+                return 0;
+
+        fail_compressed:
+                unlink_noerrno(tmp_compressed);
         }
 
-        fflush(f);
+uncompressed:
+#endif
+        r = fix_permissions(fd, tmp, fn, info, uid);
+        if (r < 0)
+                goto fail;
+
+        *ret_filename = fn;
+        *ret_fd = fd;
+        *ret_size = st.st_size;
+
+        fn = NULL;
+        fd = -1;
+
+        return 0;
+
+fail:
+        unlink_noerrno(tmp);
+        return r;
+}
+
+static int allocate_journal_field(int fd, size_t size, char **ret, size_t *ret_size) {
+        _cleanup_free_ char *field = NULL;
+        ssize_t n;
+
+        assert(fd >= 0);
+        assert(ret);
+        assert(ret_size);
 
-        if (ferror(f)) {
-                log_error("Failed to write coredump: %m");
+        if (lseek(fd, 0, SEEK_SET) == (off_t) -1) {
+                log_warning("Failed to seek: %m");
                 return -errno;
         }
 
+        field = malloc(9 + size);
+        if (!field) {
+                log_warning("Failed to allocate memory for coredump, coredump will not be stored.");
+                return -ENOMEM;
+        }
+
+        memcpy(field, "COREDUMP=", 9);
+
+        n = read(fd, field + 9, size);
+        if (n < 0) {
+                log_error("Failed to read core data: %s", strerror(-n));
+                return (int) n;
+        }
+        if ((size_t) n < size) {
+                log_error("Core data too short.");
+                return -EIO;
+        }
+
+        *ret = field;
+        *ret_size = size + 9;
+
+        field = NULL;
+
         return 0;
 }
 
 int main(int argc, char* argv[]) {
-        int r, j = 0;
-        char *t;
-        ssize_t n;
-        pid_t pid;
-        uid_t uid;
-        gid_t gid;
-        struct iovec iovec[14];
-        size_t coredump_bufsize, coredump_size;
+
         _cleanup_free_ char *core_pid = NULL, *core_uid = NULL, *core_gid = NULL, *core_signal = NULL,
                 *core_timestamp = NULL, *core_comm = NULL, *core_exe = NULL, *core_unit = NULL,
-                *core_session = NULL, *core_message = NULL, *core_cmdline = NULL, *coredump_data = NULL;
+                *core_session = NULL, *core_message = NULL, *core_cmdline = NULL, *coredump_data = NULL,
+                *core_slice = NULL, *core_cgroup = NULL, *core_owner_uid = NULL,
+                *exe = NULL, *comm = NULL, *filename = NULL;
+        const char *info[_INFO_LEN];
+
+        _cleanup_close_ int coredump_fd = -1;
 
+        struct iovec iovec[18];
+        off_t coredump_size;
+        int r, j = 0;
+        uid_t uid, owner_uid;
+        gid_t gid;
+        pid_t pid;
+        char *t;
+
+        /* Make sure we never enter a loop */
         prctl(PR_SET_DUMPABLE, 0);
 
-        if (argc != _ARG_MAX) {
-                log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
-                log_open();
+        /* First, log to a safe place, since we don't know what
+         * crashed and it might be journald which we'd rather not log
+         * to then. */
+        log_set_target(LOG_TARGET_KMSG);
+        log_open();
 
-                log_error("Invalid number of arguments passed from kernel.");
+        if (argc < INFO_COMM + 1) {
+                log_error("Not enough arguments passed from kernel (%d, expected %d).",
+                          argc - 1, INFO_COMM + 1 - 1);
                 r = -EINVAL;
                 goto finish;
         }
 
-        r = parse_pid(argv[ARG_PID], &pid);
+        /* Ignore all parse errors */
+        parse_config();
+
+        log_debug("Selected storage '%s'.", coredump_storage_to_string(arg_storage));
+        log_debug("Selected compression %s.", yes_no(arg_compress));
+
+        r = parse_uid(argv[INFO_UID + 1], &uid);
         if (r < 0) {
-                log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
-                log_open();
+                log_error("Failed to parse UID.");
+                goto finish;
+        }
 
+        r = parse_pid(argv[INFO_PID + 1], &pid);
+        if (r < 0) {
                 log_error("Failed to parse PID.");
                 goto finish;
         }
 
+        r = parse_gid(argv[INFO_GID + 1], &gid);
+        if (r < 0) {
+                log_error("Failed to parse GID.");
+                goto finish;
+        }
+
+        if (get_process_comm(pid, &comm) < 0) {
+                log_warning("Failed to get COMM, falling back to the commandline.");
+                comm = strv_join(argv + INFO_COMM + 1, " ");
+        }
+
+        if (get_process_exe(pid, &exe) < 0)
+                log_warning("Failed to get EXE.");
+
+        info[INFO_PID] = argv[INFO_PID + 1];
+        info[INFO_UID] = argv[INFO_UID + 1];
+        info[INFO_GID] = argv[INFO_GID + 1];
+        info[INFO_SIGNAL] = argv[INFO_SIGNAL + 1];
+        info[INFO_TIMESTAMP] = argv[INFO_TIMESTAMP + 1];
+        info[INFO_COMM] = comm;
+        info[INFO_EXE] = exe;
+
         if (cg_pid_get_unit(pid, &t) >= 0) {
 
                 if (streq(t, SPECIAL_JOURNALD_SERVICE)) {
-                        /* Make sure we don't make use of the journal,
-                         * if it's the journal which is crashing */
-                        log_set_target(LOG_TARGET_KMSG);
-                        log_open();
 
-                        r = divert_coredump();
+                        /* If we are journald, we cut things short,
+                         * don't write to the journal, but still
+                         * create a coredump. */
+
+                        if (arg_storage != COREDUMP_STORAGE_NONE)
+                                arg_storage = COREDUMP_STORAGE_EXTERNAL;
+
+                        r = save_external_coredump(info, uid, &filename, &coredump_fd, &coredump_size);
+                        if (r < 0)
+                                goto finish;
+
+                        r = maybe_remove_external_coredump(filename, coredump_size);
+                        if (r < 0)
+                                goto finish;
+
+                        log_info("Detected coredump of the journal daemon itself, diverted to %s.", filename);
                         goto finish;
                 }
 
@@ -149,44 +566,27 @@ int main(int argc, char* argv[]) {
         if (core_unit)
                 IOVEC_SET_STRING(iovec[j++], core_unit);
 
-        /* OK, now we know it's not the journal, hence make use of
-         * it */
+        /* OK, now we know it's not the journal, hence we can make use
+         * of it now. */
         log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
         log_open();
 
-        r = parse_uid(argv[ARG_UID], &uid);
-        if (r < 0) {
-                log_error("Failed to parse UID.");
-                goto finish;
-        }
-
-        r = parse_gid(argv[ARG_GID], &gid);
-        if (r < 0) {
-                log_error("Failed to parse GID.");
-                goto finish;
-        }
-
-        core_pid = strappend("COREDUMP_PID=", argv[ARG_PID]);
+        core_pid = strappend("COREDUMP_PID=", info[INFO_PID]);
         if (core_pid)
                 IOVEC_SET_STRING(iovec[j++], core_pid);
 
-        core_uid = strappend("COREDUMP_UID=", argv[ARG_UID]);
+        core_uid = strappend("COREDUMP_UID=", info[INFO_UID]);
         if (core_uid)
                 IOVEC_SET_STRING(iovec[j++], core_uid);
 
-        core_gid = strappend("COREDUMP_GID=", argv[ARG_GID]);
+        core_gid = strappend("COREDUMP_GID=", info[INFO_GID]);
         if (core_gid)
                 IOVEC_SET_STRING(iovec[j++], core_gid);
 
-        core_signal = strappend("COREDUMP_SIGNAL=", argv[ARG_SIGNAL]);
+        core_signal = strappend("COREDUMP_SIGNAL=", info[INFO_SIGNAL]);
         if (core_signal)
                 IOVEC_SET_STRING(iovec[j++], core_signal);
 
-        core_comm = strappend("COREDUMP_COMM=", argv[ARG_COMM]);
-        if (core_comm)
-                IOVEC_SET_STRING(iovec[j++], core_comm);
-
-#ifdef HAVE_LOGIND
         if (sd_pid_get_session(pid, &t) >= 0) {
                 core_session = strappend("COREDUMP_SESSION=", t);
                 free(t);
@@ -195,12 +595,29 @@ int main(int argc, char* argv[]) {
                         IOVEC_SET_STRING(iovec[j++], core_session);
         }
 
-#endif
+        if (sd_pid_get_owner_uid(pid, &owner_uid) >= 0) {
+                r = asprintf(&core_owner_uid,
+                             "COREDUMP_OWNER_UID=" UID_FMT, owner_uid);
+                if (r > 0)
+                        IOVEC_SET_STRING(iovec[j++], core_owner_uid);
+        }
 
-        if (get_process_exe(pid, &t) >= 0) {
-                core_exe = strappend("COREDUMP_EXE=", t);
+        if (sd_pid_get_slice(pid, &t) >= 0) {
+                core_slice = strappend("COREDUMP_SLICE=", t);
                 free(t);
 
+                if (core_slice)
+                        IOVEC_SET_STRING(iovec[j++], core_slice);
+        }
+
+        if (comm) {
+                core_comm = strappend("COREDUMP_COMM=", comm);
+                if (core_comm)
+                        IOVEC_SET_STRING(iovec[j++], core_comm);
+        }
+
+        if (exe) {
+                core_exe = strappend("COREDUMP_EXE=", exe);
                 if (core_exe)
                         IOVEC_SET_STRING(iovec[j++], core_exe);
         }
@@ -213,23 +630,52 @@ int main(int argc, char* argv[]) {
                         IOVEC_SET_STRING(iovec[j++], core_cmdline);
         }
 
-        core_timestamp = strjoin("COREDUMP_TIMESTAMP=", argv[ARG_TIMESTAMP], "000000", NULL);
+        if (cg_pid_get_path_shifted(pid, NULL, &t) >= 0) {
+                core_cgroup = strappend("COREDUMP_CGROUP=", t);
+                free(t);
+
+                if (core_cgroup)
+                        IOVEC_SET_STRING(iovec[j++], core_cgroup);
+        }
+
+        core_timestamp = strjoin("COREDUMP_TIMESTAMP=", info[INFO_TIMESTAMP], "000000", NULL);
         if (core_timestamp)
                 IOVEC_SET_STRING(iovec[j++], core_timestamp);
 
         IOVEC_SET_STRING(iovec[j++], "MESSAGE_ID=fc2e22bc6ee647b6b90729ab34a250b1");
         IOVEC_SET_STRING(iovec[j++], "PRIORITY=2");
 
-        core_message = strjoin("MESSAGE=Process ", argv[ARG_PID], " (", argv[ARG_COMM], ") dumped core.", NULL);
-        if (core_message)
-                IOVEC_SET_STRING(iovec[j++], core_message);
+        /* Vacuum before we write anything again */
+        coredump_vacuum(-1, arg_keep_free, arg_max_use);
+
+        /* Always stream the coredump to disk, if that's possible */
+        r = save_external_coredump(info, uid, &filename, &coredump_fd, &coredump_size);
+        if (r < 0)
+                /* skip whole core dumping part */
+                goto log;
+
+        /* If we don't want to keep the coredump on disk, remove it
+         * now, as later on we will lack the privileges for
+         * it. However, we keep the fd to it, so that we can still
+         * process it and log it. */
+        r = maybe_remove_external_coredump(filename, coredump_size);
+        if (r < 0)
+                goto finish;
+        if (r == 0) {
+                const char *coredump_filename;
+
+                coredump_filename = strappenda("COREDUMP_FILENAME=", filename);
+                IOVEC_SET_STRING(iovec[j++], coredump_filename);
+        }
+
+        /* Vacuum again, but exclude the coredump we just created */
+        coredump_vacuum(coredump_fd, arg_keep_free, arg_max_use);
 
         /* Now, let's drop privileges to become the user who owns the
          * segfaulted process and allocate the coredump memory under
          * his uid. This also ensures that the credentials journald
          * will see are the ones of the coredumping user, thus making
          * sure the user himself gets access to the core dump. */
-
         if (setresgid(gid, gid, gid) < 0 ||
             setresuid(uid, uid, uid) < 0) {
                 log_error("Failed to drop privileges: %m");
@@ -237,44 +683,42 @@ int main(int argc, char* argv[]) {
                 goto finish;
         }
 
-        coredump_bufsize = COREDUMP_MIN_START;
-        coredump_data = malloc(coredump_bufsize);
-        if (!coredump_data) {
-                log_warning("Failed to allocate memory for core, core will not be stored.");
-                goto finalize;
+#ifdef HAVE_ELFUTILS
+        /* Try to get a strack trace if we can */
+        if (coredump_size <= arg_process_size_max) {
+                _cleanup_free_ char *stacktrace = NULL;
+
+                r = coredump_make_stack_trace(coredump_fd, exe, &stacktrace);
+                if (r >= 0)
+                        core_message = strjoin("MESSAGE=Process ", info[INFO_PID], " (", comm, ") of user ", info[INFO_UID], " dumped core.\n\n", stacktrace, NULL);
+                else if (r == -EINVAL)
+                        log_warning("Failed to generate stack trace: %s", dwfl_errmsg(dwfl_errno()));
+                else
+                        log_warning("Failed to generate stack trace: %s", strerror(-r));
         }
 
-        memcpy(coredump_data, "COREDUMP=", 9);
-        coredump_size = 9;
-
-        for (;;) {
-                n = loop_read(STDIN_FILENO, coredump_data + coredump_size,
-                              coredump_bufsize - coredump_size, false);
-                if (n < 0) {
-                        log_error("Failed to read core data: %s", strerror(-n));
-                        r = (int) n;
-                        goto finish;
-                } else if (n == 0)
-                        break;
+        if (!core_message)
+#endif
+log:
+        core_message = strjoin("MESSAGE=Process ", info[INFO_PID], " (", comm, ") of user ", info[INFO_UID], " dumped core.", NULL);
+        if (core_message)
+                IOVEC_SET_STRING(iovec[j++], core_message);
 
-                coredump_size += n;
+        /* Optionally store the entire coredump in the journal */
+        if (IN_SET(arg_storage, COREDUMP_STORAGE_JOURNAL, COREDUMP_STORAGE_BOTH) &&
+            coredump_size <= (off_t) arg_journal_size_max) {
+                size_t sz;
 
-                if (coredump_size > COREDUMP_MAX) {
-                        log_error("Core too large, core will not be stored.");
-                        goto finalize;
-                }
+                /* Store the coredump itself in the journal */
 
-                if (!GREEDY_REALLOC(coredump_data, coredump_bufsize, coredump_size + 1)) {
-                        log_warning("Failed to allocate memory for core, core will not be stored.");
-                        goto finalize;
+                r = allocate_journal_field(coredump_fd, (size_t) coredump_size, &coredump_data, &sz);
+                if (r >= 0) {
+                        iovec[j].iov_base = coredump_data;
+                        iovec[j].iov_len = sz;
+                        j++;
                 }
         }
 
-        iovec[j].iov_base = coredump_data;
-        iovec[j].iov_len = coredump_size;
-        j++;
-
-finalize:
         r = sd_journal_sendv(iovec, j);
         if (r < 0)
                 log_error("Failed to log coredump: %s", strerror(-r));
diff --git a/src/journal/coredump.conf b/src/journal/coredump.conf
new file mode 100644 (file)
index 0000000..0cc328f
--- /dev/null
@@ -0,0 +1,17 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+#
+# See coredump.conf(5) for details
+
+[Coredump]
+#Storage=external
+#Compress=yes
+#ProcessSizeMax=2G
+#ExternalSizeMax=2G
+#JournalSizeMax=767M
+#MaxUse=
+#KeepFree=
index 3bceb48..f5cf85a 100644 (file)
@@ -26,7 +26,7 @@
 #include <fcntl.h>
 #include <unistd.h>
 
-#include <systemd/sd-journal.h>
+#include "systemd/sd-journal.h"
 
 #include "build.h"
 #include "set.h"
 #include "pager.h"
 #include "macro.h"
 #include "journal-internal.h"
+#include "copy.h"
+#include "compress.h"
 
 static enum {
         ACTION_NONE,
+        ACTION_INFO,
         ACTION_LIST,
         ACTION_DUMP,
         ACTION_GDB,
 } arg_action = ACTION_LIST;
-
-static FILE* output = NULL;
-static char* field = NULL;
-
+static const char* arg_field = NULL;
 static int arg_no_pager = false;
 static int arg_no_legend = false;
+static int arg_one = false;
+
+static FILE* output = NULL;
 
 static Set *new_matches(void) {
         Set *set;
@@ -78,27 +81,6 @@ static Set *new_matches(void) {
         return set;
 }
 
-static int help(void) {
-        printf("%s [OPTIONS...] [MATCHES...]\n\n"
-               "List or retrieve coredumps from the journal.\n\n"
-               "Flags:\n"
-               "  -o --output=FILE  Write output to FILE\n"
-               "     --no-pager     Do not pipe output into a pager\n"
-               "     --no-legend    Do not print the column headers.\n\n"
-
-               "Commands:\n"
-               "  -h --help         Show this help\n"
-               "  --version         Print version string\n"
-               "  -F --field=FIELD  List all values a certain field takes\n"
-               "  gdb               Start gdb for the first matching coredump\n"
-               "  list              List available coredumps\n"
-               "  dump PID          Print coredump to stdout\n"
-               "  dump PATH         Print coredump to stdout\n"
-               , program_invocation_short_name);
-
-        return 0;
-}
-
 static int add_match(Set *set, const char *match) {
         int r = -ENOMEM;
         unsigned pid;
@@ -126,11 +108,10 @@ static int add_match(Set *set, const char *match) {
                 goto fail;
 
         log_debug("Adding pattern: %s", pattern);
-        r = set_put(set, pattern);
+        r = set_consume(set, pattern);
         if (r < 0) {
                 log_error("Failed to add pattern '%s': %s",
                           pattern, strerror(-r));
-                free(pattern);
                 goto fail;
         }
 
@@ -140,6 +121,26 @@ fail:
         return r;
 }
 
+static void help(void) {
+        printf("%s [OPTIONS...]\n\n"
+               "List or retrieve coredumps from the journal.\n\n"
+               "Flags:\n"
+               "  -h --help          Show this help\n"
+               "     --version       Print version string\n"
+               "     --no-pager      Do not pipe output into a pager\n"
+               "     --no-legend     Do not print the column headers.\n"
+               "  -1                 Show information about most recent entry only\n"
+               "  -F --field=FIELD   List all values a certain field takes\n"
+               "  -o --output=FILE   Write output to FILE\n\n"
+
+               "Commands:\n"
+               "  list [MATCHES...]  List available coredumps (default)\n"
+               "  info [MATCHES...]  Show detailed information about one or more coredumps\n"
+               "  dump [MATCHES...]  Print first matching coredump to stdout\n"
+               "  gdb [MATCHES...]   Start gdb for the first matching coredump\n"
+               , program_invocation_short_name);
+}
+
 static int parse_argv(int argc, char *argv[], Set *matches) {
         enum {
                 ARG_VERSION = 0x100,
@@ -162,12 +163,13 @@ static int parse_argv(int argc, char *argv[], Set *matches) {
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "ho:F:", options, NULL)) >= 0)
+        while ((c = getopt_long(argc, argv, "ho:F:1", options, NULL)) >= 0)
                 switch(c) {
 
                 case 'h':
                         arg_action = ACTION_NONE;
-                        return help();
+                        help();
+                        return 0;
 
                 case ARG_VERSION:
                         arg_action = ACTION_NONE;
@@ -198,12 +200,15 @@ static int parse_argv(int argc, char *argv[], Set *matches) {
                         break;
 
                 case 'F':
-                        if (field) {
+                        if (arg_field) {
                                 log_error("cannot use --field/-F more than once");
                                 return -EINVAL;
                         }
+                        arg_field = optarg;
+                        break;
 
-                        field = optarg;
+                case '1':
+                        arg_one = true;
                         break;
 
                 case '?':
@@ -221,13 +226,15 @@ static int parse_argv(int argc, char *argv[], Set *matches) {
                         arg_action = ACTION_DUMP;
                 else if (streq(cmd, "gdb"))
                         arg_action = ACTION_GDB;
+                else if (streq(cmd, "info"))
+                        arg_action = ACTION_INFO;
                 else {
                         log_error("Unknown action '%s'", cmd);
                         return -EINVAL;
                 }
         }
 
-        if (field && arg_action != ACTION_LIST) {
+        if (arg_field && arg_action != ACTION_LIST) {
                 log_error("Option --field/-F only makes sense with list");
                 return -EINVAL;
         }
@@ -245,9 +252,10 @@ static int parse_argv(int argc, char *argv[], Set *matches) {
 static int retrieve(const void *data,
                     size_t len,
                     const char *name,
-                    const char **var) {
+                    char **var) {
 
         size_t ident;
+        char *v;
 
         ident = strlen(name) + 1; /* name + "=" */
 
@@ -260,50 +268,60 @@ static int retrieve(const void *data,
         if (((const char*) data)[ident - 1] != '=')
                 return 0;
 
-        *var = strndup((const char*)data + ident, len - ident);
-        if (!*var)
+        v = strndup((const char*)data + ident, len - ident);
+        if (!v)
                 return log_oom();
 
+        free(*var);
+        *var = v;
+
         return 0;
 }
 
 static void print_field(FILE* file, sd_journal *j) {
-        _cleanup_free_ const char *value = NULL;
+        _cleanup_free_ char *value = NULL;
         const void *d;
         size_t l;
 
-        assert(field);
+        assert(file);
+        assert(j);
+
+        assert(arg_field);
 
         SD_JOURNAL_FOREACH_DATA(j, d, l)
-                retrieve(d, l, field, &value);
+                retrieve(d, l, arg_field, &value);
+
         if (value)
                 fprintf(file, "%s\n", value);
 }
 
-static int print_entry(FILE* file, sd_journal *j, int had_legend) {
-        _cleanup_free_ const char
+static int print_list(FILE* file, sd_journal *j, int had_legend) {
+        _cleanup_free_ char
                 *pid = NULL, *uid = NULL, *gid = NULL,
-                *sgnl = NULL, *exe = NULL;
+                *sgnl = NULL, *exe = NULL, *comm = NULL, *cmdline = NULL,
+                *filename = NULL;
         const void *d;
         size_t l;
         usec_t t;
         char buf[FORMAT_TIMESTAMP_MAX];
         int r;
+        bool present;
+
+        assert(file);
+        assert(j);
 
         SD_JOURNAL_FOREACH_DATA(j, d, l) {
                 retrieve(d, l, "COREDUMP_PID", &pid);
-                retrieve(d, l, "COREDUMP_PID", &pid);
                 retrieve(d, l, "COREDUMP_UID", &uid);
                 retrieve(d, l, "COREDUMP_GID", &gid);
                 retrieve(d, l, "COREDUMP_SIGNAL", &sgnl);
                 retrieve(d, l, "COREDUMP_EXE", &exe);
-                if (!exe)
-                        retrieve(d, l, "COREDUMP_COMM", &exe);
-                if (!exe)
-                        retrieve(d, l, "COREDUMP_CMDLINE", &exe);
+                retrieve(d, l, "COREDUMP_COMM", &comm);
+                retrieve(d, l, "COREDUMP_CMDLINE", &cmdline);
+                retrieve(d, l, "COREDUMP_FILENAME", &filename);
         }
 
-        if (!pid && !uid && !gid && !sgnl && !exe) {
+        if (!pid && !uid && !gid && !sgnl && !exe && !comm && !cmdline && !filename) {
                 log_warning("Empty coredump log entry");
                 return -EINVAL;
         }
@@ -315,47 +333,184 @@ static int print_entry(FILE* file, sd_journal *j, int had_legend) {
         }
 
         format_timestamp(buf, sizeof(buf), t);
+        present = filename && access(filename, F_OK) == 0;
 
         if (!had_legend && !arg_no_legend)
-                fprintf(file, "%-*s %*s %*s %*s %*s %s\n",
-                        FORMAT_TIMESTAMP_MAX-1, "TIME",
+                fprintf(file, "%-*s %*s %*s %*s %*s %*s %s\n",
+                        FORMAT_TIMESTAMP_WIDTH, "TIME",
                         6, "PID",
                         5, "UID",
                         5, "GID",
                         3, "SIG",
+                        1, "PRESENT",
                            "EXE");
 
-        fprintf(file, "%*s %*s %*s %*s %*s %s\n",
-                FORMAT_TIMESTAMP_MAX-1, buf,
-                6, pid,
-                5, uid,
-                5, gid,
-                3, sgnl,
-                exe);
+        fprintf(file, "%-*s %*s %*s %*s %*s %*s %s\n",
+                FORMAT_TIMESTAMP_WIDTH, buf,
+                6, strna(pid),
+                5, strna(uid),
+                5, strna(gid),
+                3, strna(sgnl),
+                1, present ? "*" : "",
+                strna(exe ?: (comm ?: cmdline)));
 
         return 0;
 }
 
-static int dump_list(sd_journal *j) {
-        int found = 0;
+static int print_info(FILE *file, sd_journal *j, bool need_space) {
+        _cleanup_free_ char
+                *pid = NULL, *uid = NULL, *gid = NULL,
+                *sgnl = NULL, *exe = NULL, *comm = NULL, *cmdline = NULL,
+                *unit = NULL, *user_unit = NULL, *session = NULL,
+                *boot_id = NULL, *machine_id = NULL, *hostname = NULL,
+                *slice = NULL, *cgroup = NULL, *owner_uid = NULL,
+                *message = NULL, *timestamp = NULL, *filename = NULL;
+        const void *d;
+        size_t l;
+        int r;
 
+        assert(file);
         assert(j);
 
-        /* The coredumps are likely to compressed, and for just
-         * listing them we don't need to decompress them, so let's
-         * pick a fairly low data threshold here */
-        sd_journal_set_data_threshold(j, 4096);
+        SD_JOURNAL_FOREACH_DATA(j, d, l) {
+                retrieve(d, l, "COREDUMP_PID", &pid);
+                retrieve(d, l, "COREDUMP_UID", &uid);
+                retrieve(d, l, "COREDUMP_GID", &gid);
+                retrieve(d, l, "COREDUMP_SIGNAL", &sgnl);
+                retrieve(d, l, "COREDUMP_EXE", &exe);
+                retrieve(d, l, "COREDUMP_COMM", &comm);
+                retrieve(d, l, "COREDUMP_CMDLINE", &cmdline);
+                retrieve(d, l, "COREDUMP_UNIT", &unit);
+                retrieve(d, l, "COREDUMP_USER_UNIT", &user_unit);
+                retrieve(d, l, "COREDUMP_SESSION", &session);
+                retrieve(d, l, "COREDUMP_OWNER_UID", &owner_uid);
+                retrieve(d, l, "COREDUMP_SLICE", &slice);
+                retrieve(d, l, "COREDUMP_CGROUP", &cgroup);
+                retrieve(d, l, "COREDUMP_TIMESTAMP", &timestamp);
+                retrieve(d, l, "COREDUMP_FILENAME", &filename);
+                retrieve(d, l, "_BOOT_ID", &boot_id);
+                retrieve(d, l, "_MACHINE_ID", &machine_id);
+                retrieve(d, l, "_HOSTNAME", &hostname);
+                retrieve(d, l, "MESSAGE", &message);
+        }
+
+        if (need_space)
+                fputs("\n", file);
+
+        if (comm)
+                fprintf(file,
+                        "           PID: %s%s%s (%s)\n",
+                        ansi_highlight(), strna(pid), ansi_highlight_off(), comm);
+        else
+                fprintf(file,
+                        "           PID: %s%s%s\n",
+                        ansi_highlight(), strna(pid), ansi_highlight_off());
+
+        if (uid) {
+                uid_t n;
+
+                if (parse_uid(uid, &n) >= 0) {
+                        _cleanup_free_ char *u = NULL;
+
+                        u = uid_to_name(n);
+                        fprintf(file,
+                                "           UID: %s (%s)\n",
+                                uid, u);
+                } else {
+                        fprintf(file,
+                                "           UID: %s\n",
+                                uid);
+                }
+        }
+
+        if (gid) {
+                gid_t n;
 
-        SD_JOURNAL_FOREACH(j) {
-                if (field)
-                        print_field(stdout, j);
+                if (parse_gid(gid, &n) >= 0) {
+                        _cleanup_free_ char *g = NULL;
+
+                        g = gid_to_name(n);
+                        fprintf(file,
+                                "           GID: %s (%s)\n",
+                                gid, g);
+                } else {
+                        fprintf(file,
+                                "           GID: %s\n",
+                                gid);
+                }
+        }
+
+        if (sgnl) {
+                int sig;
+
+                if (safe_atoi(sgnl, &sig) >= 0)
+                        fprintf(file, "        Signal: %s (%s)\n", sgnl, signal_to_string(sig));
                 else
-                        print_entry(stdout, j, found++);
+                        fprintf(file, "        Signal: %s\n", sgnl);
+        }
+
+        if (timestamp) {
+                usec_t u;
+
+                r = safe_atou64(timestamp, &u);
+                if (r >= 0) {
+                        char absolute[FORMAT_TIMESTAMP_MAX], relative[FORMAT_TIMESPAN_MAX];
+
+                        fprintf(file,
+                                "     Timestamp: %s (%s)\n",
+                                format_timestamp(absolute, sizeof(absolute), u),
+                                format_timestamp_relative(relative, sizeof(relative), u));
+
+                } else
+                        fprintf(file, "     Timestamp: %s\n", timestamp);
+        }
+
+        if (cmdline)
+                fprintf(file, "  Command Line: %s\n", cmdline);
+        if (exe)
+                fprintf(file, "    Executable: %s%s%s\n", ansi_highlight(), exe, ansi_highlight_off());
+        if (cgroup)
+                fprintf(file, " Control Group: %s\n", cgroup);
+        if (unit)
+                fprintf(file, "          Unit: %s\n", unit);
+        if (user_unit)
+                fprintf(file, "     User Unit: %s\n", unit);
+        if (slice)
+                fprintf(file, "         Slice: %s\n", slice);
+        if (session)
+                fprintf(file, "       Session: %s\n", session);
+        if (owner_uid) {
+                uid_t n;
+
+                if (parse_uid(owner_uid, &n) >= 0) {
+                        _cleanup_free_ char *u = NULL;
+
+                        u = uid_to_name(n);
+                        fprintf(file,
+                                "     Owner UID: %s (%s)\n",
+                                owner_uid, u);
+                } else {
+                        fprintf(file,
+                                "     Owner UID: %s\n",
+                                owner_uid);
+                }
         }
+        if (boot_id)
+                fprintf(file, "       Boot ID: %s\n", boot_id);
+        if (machine_id)
+                fprintf(file, "    Machine ID: %s\n", machine_id);
+        if (hostname)
+                fprintf(file, "      Hostname: %s\n", hostname);
 
-        if (!field && !found) {
-                log_notice("No coredumps found");
-                return -ESRCH;
+        if (filename && access(filename, F_OK) == 0)
+                fprintf(file, "      Coredump: %s\n", filename);
+
+        if (message) {
+                _cleanup_free_ char *m = NULL;
+
+                m = strreplace(message, "\n", "\n                ");
+
+                fprintf(file, "       Message: %s\n", strstrip(m ?: message));
         }
 
         return 0;
@@ -372,49 +527,189 @@ static int focus(sd_journal *j) {
                 return r;
         }
         if (r == 0) {
-                log_error("No match found");
+                log_error("No match found.");
                 return -ESRCH;
         }
         return r;
 }
 
-static int dump_core(sd_journal* j) {
-        const void *data;
-        size_t len, ret;
+static void print_entry(sd_journal *j, unsigned n_found) {
+        assert(j);
+
+        if (arg_action == ACTION_INFO)
+                print_info(stdout, j, n_found);
+        else if (arg_field)
+                print_field(stdout, j);
+        else
+                print_list(stdout, j, n_found);
+}
+
+static int dump_list(sd_journal *j) {
+        unsigned n_found = 0;
         int r;
 
         assert(j);
 
-        /* We want full data, nothing truncated. */
-        sd_journal_set_data_threshold(j, 0);
+        /* The coredumps are likely to compressed, and for just
+         * listing them we don't need to decompress them, so let's
+         * pick a fairly low data threshold here */
+        sd_journal_set_data_threshold(j, 4096);
+
+        if (arg_one) {
+                r = focus(j);
+                if (r < 0)
+                        return r;
+
+                print_entry(j, 0);
+        } else {
+                SD_JOURNAL_FOREACH(j)
+                        print_entry(j, n_found++);
+
+                if (!arg_field && n_found <= 0) {
+                        log_notice("No coredumps found.");
+                        return -ESRCH;
+                }
+        }
+
+        return 0;
+}
+
+static int save_core(sd_journal *j, int fd, char **path, bool *unlink_temp) {
+        const char *data;
+        _cleanup_free_ char *filename = NULL;
+        size_t len;
+        int r;
+
+        assert((fd >= 0) != !!path);
+        assert(!!path == !!unlink_temp);
+
+        /* Prefer uncompressed file to journal (probably cached) to
+         * compressed file (probably uncached). */
+        r = sd_journal_get_data(j, "COREDUMP_FILENAME", (const void**) &data, &len);
+        if (r < 0 && r != -ENOENT)
+                log_warning("Failed to retrieve COREDUMP_FILENAME: %s", strerror(-r));
+        else if (r == 0)
+                retrieve(data, len, "COREDUMP_FILENAME", &filename);
+
+        if (filename && access(filename, R_OK) < 0) {
+                log_full(errno == ENOENT ? LOG_DEBUG : LOG_WARNING,
+                         "File %s is not readable: %m", filename);
+                free(filename);
+                filename = NULL;
+        }
+
+        if (filename && !endswith(filename, ".xz") && !endswith(filename, ".lz4")) {
+                if (path) {
+                        *path = filename;
+                        filename = NULL;
+                }
+
+                return 0;
+        } else {
+                _cleanup_close_ int fdt = -1;
+                char *temp = NULL;
+
+                if (fd < 0) {
+                        temp = strdup("/var/tmp/coredump-XXXXXX");
+                        if (!temp)
+                                return log_oom();
+
+                        fdt = mkostemp_safe(temp, O_WRONLY|O_CLOEXEC);
+                        if (fdt < 0) {
+                                log_error("Failed to create temporary file: %m");
+                                return -errno;
+                        }
+                        log_debug("Created temporary file %s", temp);
+
+                        fd = fdt;
+                }
+
+                r = sd_journal_get_data(j, "COREDUMP", (const void**) &data, &len);
+                if (r == 0) {
+                        ssize_t sz;
+
+                        assert(len >= 9);
+                        data += 9;
+                        len -= 9;
+
+                        sz = write(fdt, data, len);
+                        if (sz < 0) {
+                                log_error("Failed to write temporary file: %m");
+                                r = -errno;
+                                goto error;
+                        }
+                        if (sz != (ssize_t) len) {
+                                log_error("Short write to temporary file.");
+                                r = -EIO;
+                                goto error;
+                        }
+                } else if (filename) {
+#if defined(HAVE_XZ) || defined(HAVE_LZ4)
+                        _cleanup_close_ int fdf;
+
+                        fdf = open(filename, O_RDONLY | O_CLOEXEC);
+                        if (fdf < 0) {
+                                log_error("Failed to open %s: %m", filename);
+                                r = -errno;
+                                goto error;
+                        }
+
+                        r = decompress_stream(filename, fdf, fd, -1);
+                        if (r < 0) {
+                                log_error("Failed to decompress %s: %s", filename, strerror(-r));
+                                goto error;
+                        }
+#else
+                        log_error("Cannot decompress file. Compiled without compression support.");
+                        r = -ENOTSUP;
+                        goto error;
+#endif
+                } else {
+                        if (r == -ENOENT)
+                                log_error("Cannot retrieve coredump from journal nor disk.");
+                        else
+                                log_error("Failed to retrieve COREDUMP field: %s", strerror(-r));
+                        goto error;
+                }
+
+                if (temp) {
+                        *path = temp;
+                        *unlink_temp = true;
+                }
+
+                return 0;
+
+error:
+                if (temp) {
+                        unlink(temp);
+                        log_debug("Removed temporary file %s", temp);
+                }
+                return r;
+        }
+}
+
+static int dump_core(sd_journal* j) {
+        int r;
+
+        assert(j);
 
         r = focus(j);
         if (r < 0)
                 return r;
 
-        print_entry(output ? stdout : stderr, j, false);
+        print_info(output ? stdout : stderr, j, false);
 
         if (on_tty() && !output) {
-                log_error("Refusing to dump core to tty");
+                log_error("Refusing to dump core to tty.");
                 return -ENOTTY;
         }
 
-        r = sd_journal_get_data(j, "COREDUMP", (const void**) &data, &len);
+        r = save_core(j, output ? fileno(output) : STDOUT_FILENO, NULL, NULL);
         if (r < 0) {
-                log_error("Failed to retrieve COREDUMP field: %s", strerror(-r));
+                log_error("Coredump retrieval failed: %s", strerror(-r));
                 return r;
         }
 
-        assert(len >= 9);
-        data = (const uint8_t*) data + 9;
-        len -= 9;
-
-        ret = fwrite(data, len, 1, output ? output : stdout);
-        if (ret != 1) {
-                log_error("dumping coredump: %m (%zu)", ret);
-                return -errno;
-        }
-
         r = sd_journal_previous(j);
         if (r >= 0)
                 log_warning("More than one entry matches, ignoring rest.");
@@ -423,25 +718,22 @@ static int dump_core(sd_journal* j) {
 }
 
 static int run_gdb(sd_journal *j) {
-        char path[] = "/var/tmp/coredump-XXXXXX";
-        const void *data;
+        _cleanup_free_ char *exe = NULL, *path = NULL;
+        bool unlink_path = false;
+        const char *data;
+        siginfo_t st;
         size_t len;
-        ssize_t sz;
         pid_t pid;
-        _cleanup_free_ char *exe = NULL;
         int r;
-        _cleanup_close_ int fd = -1;
-        siginfo_t st;
 
         assert(j);
 
-        sd_journal_set_data_threshold(j, 0);
-
         r = focus(j);
         if (r < 0)
                 return r;
 
-        print_entry(stdout, j, false);
+        print_info(stdout, j, false);
+        fputs("\n", stdout);
 
         r = sd_journal_get_data(j, "COREDUMP_EXE", (const void**) &data, &len);
         if (r < 0) {
@@ -449,9 +741,9 @@ static int run_gdb(sd_journal *j) {
                 return r;
         }
 
-        assert(len >= 13);
-        data = (const uint8_t*) data + 13;
-        len -= 13;
+        assert(len > strlen("COREDUMP_EXE="));
+        data += strlen("COREDUMP_EXE=");
+        len -= strlen("COREDUMP_EXE=");
 
         exe = strndup(data, len);
         if (!exe)
@@ -462,37 +754,17 @@ static int run_gdb(sd_journal *j) {
                 return -ENOENT;
         }
 
-        r = sd_journal_get_data(j, "COREDUMP", (const void**) &data, &len);
-        if (r < 0) {
-                log_error("Failed to retrieve COREDUMP field: %s", strerror(-r));
-                return r;
-        }
-
-        assert(len >= 9);
-        data = (const uint8_t*) data + 9;
-        len -= 9;
-
-        fd = mkostemp_safe(path, O_WRONLY|O_CLOEXEC);
-        if (fd < 0) {
-                log_error("Failed to create temporary file: %m");
-                return -errno;
+        if (!path_is_absolute(exe)) {
+                log_error("Binary is not an absolute path.");
+                return -ENOENT;
         }
 
-        sz = write(fd, data, len);
-        if (sz < 0) {
-                log_error("Failed to write temporary file: %m");
-                r = -errno;
-                goto finish;
-        }
-        if (sz != (ssize_t) len) {
-                log_error("Short write to temporary file.");
-                r = -EIO;
-                goto finish;
+        r = save_core(j, -1, &path, &unlink_path);
+        if (r < 0) {
+                log_error("Failed to retrieve core: %s", strerror(-r));
+                return r;
         }
 
-        close_nointr_nofail(fd);
-        fd = -1;
-
         pid = fork();
         if (pid < 0) {
                 log_error("Failed to fork(): %m");
@@ -501,6 +773,7 @@ static int run_gdb(sd_journal *j) {
         }
         if (pid == 0) {
                 execlp("gdb", "gdb", exe, path, NULL);
+
                 log_error("Failed to invoke gdb: %m");
                 _exit(1);
         }
@@ -514,7 +787,11 @@ static int run_gdb(sd_journal *j) {
         r = st.si_code == CLD_EXITED ? st.si_status : 255;
 
 finish:
-        unlink(path);
+        if (unlink_path) {
+                log_debug("Removed temporary file %s", path);
+                unlink(path);
+        }
+
         return r;
 }
 
@@ -548,6 +825,9 @@ int main(int argc, char *argv[]) {
                 goto end;
         }
 
+        /* We want full data, nothing truncated. */
+        sd_journal_set_data_threshold(j, 0);
+
         SET_FOREACH(match, matches, it) {
                 r = sd_journal_add_match(j, match, strlen(match));
                 if (r != 0) {
@@ -567,6 +847,7 @@ int main(int argc, char *argv[]) {
         switch(arg_action) {
 
         case ACTION_LIST:
+        case ACTION_INFO:
                 if (!arg_no_pager)
                         pager_open(false);
 
index f416b79..5ab1982 100644 (file)
@@ -418,10 +418,9 @@ finish:
         if (m)
                 munmap(m, PAGE_ALIGN(sizeof(FSSHeader)));
 
-        if (fd >= 0)
-                close_nointr_nofail(fd);
-
+        safe_close(fd);
         free(p);
+
         return r;
 }
 
index 7e407a4..e55fa19 100644 (file)
@@ -23,7 +23,7 @@
 
 #include "sparse-endian.h"
 
-#include <systemd/sd-id128.h>
+#include "systemd/sd-id128.h"
 
 #include "macro.h"
 
@@ -66,9 +66,13 @@ enum {
 
 /* Object flags */
 enum {
-        OBJECT_COMPRESSED = 1
+        OBJECT_COMPRESSED_XZ = 1 << 0,
+        OBJECT_COMPRESSED_LZ4 = 1 << 1,
+        _OBJECT_COMPRESSED_MAX
 };
 
+#define OBJECT_COMPRESSION_MASK (OBJECT_COMPRESSED_XZ | OBJECT_COMPRESSED_LZ4)
+
 struct ObjectHeader {
         uint8_t type;
         uint8_t flags;
@@ -155,13 +159,33 @@ enum {
 
 /* Header flags */
 enum {
-        HEADER_INCOMPATIBLE_COMPRESSED = 1
+        HEADER_INCOMPATIBLE_COMPRESSED_XZ = 1 << 0,
+        HEADER_INCOMPATIBLE_COMPRESSED_LZ4 = 1 << 1,
 };
 
+#define HEADER_INCOMPATIBLE_ANY (HEADER_INCOMPATIBLE_COMPRESSED_XZ|HEADER_INCOMPATIBLE_COMPRESSED_LZ4)
+
+#if defined(HAVE_XZ) && defined(HAVE_LZ4)
+#  define HEADER_INCOMPATIBLE_SUPPORTED HEADER_INCOMPATIBLE_ANY
+#elif defined(HAVE_XZ)
+#  define HEADER_INCOMPATIBLE_SUPPORTED HEADER_INCOMPATIBLE_COMPRESSED_XZ
+#elif defined(HAVE_LZ4)
+#  define HEADER_INCOMPATIBLE_SUPPORTED HEADER_INCOMPATIBLE_COMPRESSED_LZ4
+#else
+#  define HEADER_INCOMPATIBLE_SUPPORTED 0
+#endif
+
 enum {
         HEADER_COMPATIBLE_SEALED = 1
 };
 
+#define HEADER_COMPATIBLE_ANY HEADER_COMPATIBLE_SEALED
+#ifdef HAVE_GCRYPT
+#  define HEADER_COMPATIBLE_SUPPORTED HEADER_COMPATIBLE_SEALED
+#else
+#  define HEADER_COMPATIBLE_SUPPORTED 0
+#endif
+
 #define HEADER_SIGNATURE ((char[]) { 'L', 'P', 'K', 'S', 'H', 'H', 'R', 'H' })
 
 struct Header {
index a2cc697..26bb917 100644 (file)
 #include <sys/statvfs.h>
 #include <fcntl.h>
 #include <stddef.h>
-
-#ifdef HAVE_XATTR
-#include <attr/xattr.h>
-#endif
+#include <sys/xattr.h>
 
 #include "journal-def.h"
 #include "journal-file.h"
@@ -141,9 +138,7 @@ void journal_file_close(JournalFile *f) {
         if (f->header)
                 munmap(f->header, PAGE_ALIGN(sizeof(Header)));
 
-        if (f->fd >= 0)
-                close_nointr_nofail(f->fd);
-
+        safe_close(f->fd);
         free(f->path);
 
         if (f->mmap)
@@ -151,7 +146,7 @@ void journal_file_close(JournalFile *f) {
 
         hashmap_free_free(f->chain_cache);
 
-#ifdef HAVE_XZ
+#if defined(HAVE_XZ) || defined(HAVE_LZ4)
         free(f->compress_buffer);
 #endif
 
@@ -171,21 +166,21 @@ void journal_file_close(JournalFile *f) {
 }
 
 static int journal_file_init_header(JournalFile *f, JournalFile *template) {
-        Header h;
+        Header h = {};
         ssize_t k;
         int r;
 
         assert(f);
 
-        zero(h);
         memcpy(h.signature, HEADER_SIGNATURE, 8);
         h.header_size = htole64(ALIGN64(sizeof(h)));
 
-        h.incompatible_flags =
-                htole32(f->compress ? HEADER_INCOMPATIBLE_COMPRESSED : 0);
+        h.incompatible_flags |= htole32(
+                f->compress_xz * HEADER_INCOMPATIBLE_COMPRESSED_XZ |
+                f->compress_lz4 * HEADER_INCOMPATIBLE_COMPRESSED_LZ4);
 
-        h.compatible_flags =
-                htole32(f->seal ? HEADER_COMPATIBLE_SEALED : 0);
+        h.compatible_flags = htole32(
+                f->seal * HEADER_COMPATIBLE_SEALED);
 
         r = sd_id128_randomize(&h.file_id);
         if (r < 0)
@@ -235,6 +230,8 @@ static int journal_file_refresh_header(JournalFile *f) {
 }
 
 static int journal_file_verify_header(JournalFile *f) {
+        uint32_t flags;
+
         assert(f);
 
         if (memcmp(f->header->signature, HEADER_SIGNATURE, 8))
@@ -242,24 +239,30 @@ static int journal_file_verify_header(JournalFile *f) {
 
         /* In both read and write mode we refuse to open files with
          * incompatible flags we don't know */
-#ifdef HAVE_XZ
-        if ((le32toh(f->header->incompatible_flags) & ~HEADER_INCOMPATIBLE_COMPRESSED) != 0)
-                return -EPROTONOSUPPORT;
-#else
-        if (f->header->incompatible_flags != 0)
+        flags = le32toh(f->header->incompatible_flags);
+        if (flags & ~HEADER_INCOMPATIBLE_SUPPORTED) {
+                if (flags & ~HEADER_INCOMPATIBLE_ANY)
+                        log_debug("Journal file %s has unknown incompatible flags %"PRIx32,
+                                  f->path, flags & ~HEADER_INCOMPATIBLE_ANY);
+                flags = (flags & HEADER_INCOMPATIBLE_ANY) & ~HEADER_INCOMPATIBLE_SUPPORTED;
+                if (flags)
+                        log_debug("Journal file %s uses incompatible flags %"PRIx32
+                                  " disabled at compilation time.", f->path, flags);
                 return -EPROTONOSUPPORT;
-#endif
+        }
 
         /* When open for writing we refuse to open files with
          * compatible flags, too */
-        if (f->writable) {
-#ifdef HAVE_GCRYPT
-                if ((le32toh(f->header->compatible_flags) & ~HEADER_COMPATIBLE_SEALED) != 0)
-                        return -EPROTONOSUPPORT;
-#else
-                if (f->header->compatible_flags != 0)
-                        return -EPROTONOSUPPORT;
-#endif
+        flags = le32toh(f->header->compatible_flags);
+        if (f->writable && (flags & ~HEADER_COMPATIBLE_SUPPORTED)) {
+                if (flags & ~HEADER_COMPATIBLE_ANY)
+                        log_debug("Journal file %s has unknown compatible flags %"PRIx32,
+                                  f->path, flags & ~HEADER_COMPATIBLE_ANY);
+                flags = (flags & HEADER_COMPATIBLE_ANY) & ~HEADER_COMPATIBLE_SUPPORTED;
+                if (flags)
+                        log_debug("Journal file %s uses compatible flags %"PRIx32
+                                  " disabled at compilation time.", f->path, flags);
+                return -EPROTONOSUPPORT;
         }
 
         if (f->header->state >= _STATE_MAX)
@@ -284,12 +287,6 @@ static int journal_file_verify_header(JournalFile *f) {
             !VALID64(le64toh(f->header->entry_array_offset)))
                 return -ENODATA;
 
-        if (le64toh(f->header->data_hash_table_offset) < le64toh(f->header->header_size) ||
-            le64toh(f->header->field_hash_table_offset) < le64toh(f->header->header_size) ||
-            le64toh(f->header->tail_object_offset) < le64toh(f->header->header_size) ||
-            le64toh(f->header->entry_array_offset) < le64toh(f->header->header_size))
-                return -ENODATA;
-
         if (f->writable) {
                 uint8_t state;
                 sd_id128_t machine_id;
@@ -315,7 +312,8 @@ static int journal_file_verify_header(JournalFile *f) {
                 }
         }
 
-        f->compress = JOURNAL_HEADER_COMPRESSED(f->header);
+        f->compress_xz = JOURNAL_HEADER_COMPRESSED_XZ(f->header);
+        f->compress_lz4 = JOURNAL_HEADER_COMPRESSED_LZ4(f->header);
 
         f->seal = JOURNAL_HEADER_SEALED(f->header);
 
@@ -822,9 +820,10 @@ int journal_file_find_data_object_with_hash(
                 if (le64toh(o->data.hash) != hash)
                         goto next;
 
-                if (o->object.flags & OBJECT_COMPRESSED) {
-#ifdef HAVE_XZ
-                        uint64_t l, rsize;
+                if (o->object.flags & OBJECT_COMPRESSION_MASK) {
+#if defined(HAVE_XZ) || defined(HAVE_LZ4)
+                        uint64_t l;
+                        size_t rsize;
 
                         l = le64toh(o->object.size);
                         if (l <= offsetof(Object, data.payload))
@@ -832,8 +831,10 @@ int journal_file_find_data_object_with_hash(
 
                         l -= offsetof(Object, data.payload);
 
-                        if (!uncompress_blob(o->data.payload, l, &f->compress_buffer, &f->compress_buffer_size, &rsize, 0))
-                                return -EBADMSG;
+                        r = decompress_blob(o->object.flags & OBJECT_COMPRESSION_MASK,
+                                            o->data.payload, l, &f->compress_buffer, &f->compress_buffer_size, &rsize, 0);
+                        if (r < 0)
+                                return r;
 
                         if (rsize == size &&
                             memcmp(f->compress_buffer, data, size) == 0) {
@@ -849,7 +850,6 @@ int journal_file_find_data_object_with_hash(
 #else
                         return -EPROTONOSUPPORT;
 #endif
-
                 } else if (le64toh(o->object.size) == osize &&
                            memcmp(o->data.payload, data, size) == 0) {
 
@@ -956,8 +956,7 @@ static int journal_file_append_data(
         uint64_t hash, p;
         uint64_t osize;
         Object *o;
-        int r;
-        bool compressed = false;
+        int r, compression = 0;
         const void *eq;
 
         assert(f);
@@ -986,23 +985,24 @@ static int journal_file_append_data(
 
         o->data.hash = htole64(hash);
 
-#ifdef HAVE_XZ
-        if (f->compress &&
+#if defined(HAVE_XZ) || defined(HAVE_LZ4)
+        if (f->compress_xz &&
             size >= COMPRESSION_SIZE_THRESHOLD) {
-                uint64_t rsize;
+                size_t rsize;
 
-                compressed = compress_blob(data, size, o->data.payload, &rsize);
+                compression = compress_blob(data, size, o->data.payload, &rsize);
 
-                if (compressed) {
+                if (compression) {
                         o->object.size = htole64(offsetof(Object, data.payload) + rsize);
-                        o->object.flags |= OBJECT_COMPRESSED;
+                        o->object.flags |= compression;
 
-                        log_debug("Compressed data object %"PRIu64" -> %"PRIu64, size, rsize);
+                        log_debug("Compressed data object %"PRIu64" -> %zu using %s",
+                                  size, rsize, object_compressed_to_string(compression));
                 }
         }
 #endif
 
-        if (!compressed && size > 0)
+        if (!compression && size > 0)
                 memcpy(o->data.payload, data, size);
 
         r = journal_file_link_data(f, o, p, hash);
@@ -1367,7 +1367,7 @@ int journal_file_append_entry(JournalFile *f, const dual_timestamp *ts, const st
 }
 
 typedef struct ChainCacheItem {
-        uint64_t first; /* the array at the begin of the chain */
+        uint64_t first; /* the array at the beginning of the chain */
         uint64_t array; /* the cached array */
         uint64_t begin; /* the first item in the cached array */
         uint64_t total; /* the total number of items in all arrays before this one in the chain */
@@ -1953,7 +1953,7 @@ int journal_file_next_entry(
                 direction_t direction,
                 Object **ret, uint64_t *offset) {
 
-        uint64_t i, n;
+        uint64_t i, n, ofs;
         int r;
 
         assert(f);
@@ -1994,10 +1994,24 @@ int journal_file_next_entry(
         }
 
         /* And jump to it */
-        return generic_array_get(f,
-                                 le64toh(f->header->entry_array_offset),
-                                 i,
-                                 ret, offset);
+        r = generic_array_get(f,
+                              le64toh(f->header->entry_array_offset),
+                              i,
+                              ret, &ofs);
+        if (r <= 0)
+                return r;
+
+        if (p > 0 &&
+            (direction == DIRECTION_DOWN ? ofs <= p : ofs >= p)) {
+                log_debug("%s: entry array corrupted at entry %"PRIu64,
+                          f->path, i);
+                return -EBADMSG;
+        }
+
+        if (offset)
+                *offset = ofs;
+
+        return 1;
 }
 
 int journal_file_skip_entry(
@@ -2218,8 +2232,6 @@ int journal_file_move_to_entry_by_monotonic_for_data(
 
                 z = q;
         }
-
-        return 0;
 }
 
 int journal_file_move_to_entry_by_seqnum_for_data(
@@ -2333,8 +2345,9 @@ void journal_file_dump(JournalFile *f) {
                         break;
                 }
 
-                if (o->object.flags & OBJECT_COMPRESSED)
-                        printf("Flags: COMPRESSED\n");
+                if (o->object.flags & OBJECT_COMPRESSION_MASK)
+                        printf("Flags: %s\n",
+                               object_compressed_to_string(o->object.flags & OBJECT_COMPRESSION_MASK));
 
                 if (p == le64toh(f->header->tail_object_offset))
                         p = 0;
@@ -2371,7 +2384,7 @@ void journal_file_print_header(JournalFile *f) {
                "Sequential Number ID: %s\n"
                "State: %s\n"
                "Compatible Flags:%s%s\n"
-               "Incompatible Flags:%s%s\n"
+               "Incompatible Flags:%s%s%s\n"
                "Header size: %"PRIu64"\n"
                "Arena size: %"PRIu64"\n"
                "Data Hash Table Size: %"PRIu64"\n"
@@ -2393,9 +2406,10 @@ void journal_file_print_header(JournalFile *f) {
                f->header->state == STATE_ONLINE ? "ONLINE" :
                f->header->state == STATE_ARCHIVED ? "ARCHIVED" : "UNKNOWN",
                JOURNAL_HEADER_SEALED(f->header) ? " SEALED" : "",
-               (le32toh(f->header->compatible_flags) & ~HEADER_COMPATIBLE_SEALED) ? " ???" : "",
-               JOURNAL_HEADER_COMPRESSED(f->header) ? " COMPRESSED" : "",
-               (le32toh(f->header->incompatible_flags) & ~HEADER_INCOMPATIBLE_COMPRESSED) ? " ???" : "",
+               (le32toh(f->header->compatible_flags) & ~HEADER_COMPATIBLE_ANY) ? " ???" : "",
+               JOURNAL_HEADER_COMPRESSED_XZ(f->header) ? " COMPRESSED-XZ" : "",
+               JOURNAL_HEADER_COMPRESSED_LZ4(f->header) ? " COMPRESSED-LZ4" : "",
+               (le32toh(f->header->incompatible_flags) & ~HEADER_INCOMPATIBLE_ANY) ? " ???" : "",
                le64toh(f->header->header_size),
                le64toh(f->header->arena_size),
                le64toh(f->header->data_hash_table_size) / sizeof(HashItem),
@@ -2468,8 +2482,10 @@ int journal_file_open(
         f->flags = flags;
         f->prot = prot_from_flags(flags);
         f->writable = (flags & O_ACCMODE) != O_RDONLY;
-#ifdef HAVE_XZ
-        f->compress = compress;
+#if defined(HAVE_LZ4)
+        f->compress_lz4 = compress;
+#elif defined(HAVE_XZ)
+        f->compress_xz = compress;
 #endif
 #ifdef HAVE_GCRYPT
         f->seal = seal;
@@ -2509,7 +2525,6 @@ int journal_file_open(
         }
 
         if (f->last_stat.st_size == 0 && f->writable) {
-#ifdef HAVE_XATTR
                 uint64_t crtime;
 
                 /* Let's attach the creation time to the journal file,
@@ -2524,7 +2539,6 @@ int journal_file_open(
 
                 crtime = htole64((uint64_t) now(CLOCK_REALTIME));
                 fsetxattr(f->fd, "user.crtime_usec", &crtime, sizeof(crtime), XATTR_CREATE);
-#endif
 
 #ifdef HAVE_GCRYPT
                 /* Try to load the FSPRG state, and if we can't, then
@@ -2763,12 +2777,14 @@ int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint6
                 if ((uint64_t) t != l)
                         return -E2BIG;
 
-                if (o->object.flags & OBJECT_COMPRESSED) {
-#ifdef HAVE_XZ
-                        uint64_t rsize;
+                if (o->object.flags & OBJECT_COMPRESSION_MASK) {
+#if defined(HAVE_XZ) || defined(HAVE_LZ4)
+                        size_t rsize;
 
-                        if (!uncompress_blob(o->data.payload, l, &from->compress_buffer, &from->compress_buffer_size, &rsize, 0))
-                                return -EBADMSG;
+                        r = decompress_blob(o->object.flags & OBJECT_COMPRESSION_MASK,
+                                            o->data.payload, l, &from->compress_buffer, &from->compress_buffer_size, &rsize, 0);
+                        if (r < 0)
+                                return r;
 
                         data = from->compress_buffer;
                         l = rsize;
index 50dbe29..3d41682 100644 (file)
@@ -27,7 +27,7 @@
 #include <gcrypt.h>
 #endif
 
-#include <systemd/sd-id128.h>
+#include "systemd/sd-id128.h"
 
 #include "sparse-endian.h"
 #include "journal-def.h"
@@ -56,7 +56,8 @@ typedef struct JournalFile {
         int flags;
         int prot;
         bool writable:1;
-        bool compress:1;
+        bool compress_xz:1;
+        bool compress_lz4:1;
         bool seal:1;
 
         bool tail_entry_monotonic_valid:1;
@@ -79,7 +80,7 @@ typedef struct JournalFile {
 
 #ifdef HAVE_XZ
         void *compress_buffer;
-        uint64_t compress_buffer_size;
+        size_t compress_buffer_size;
 #endif
 
 #ifdef HAVE_GCRYPT
@@ -153,8 +154,11 @@ static inline bool VALID_EPOCH(uint64_t u) {
 #define JOURNAL_HEADER_SEALED(h) \
         (!!(le32toh((h)->compatible_flags) & HEADER_COMPATIBLE_SEALED))
 
-#define JOURNAL_HEADER_COMPRESSED(h) \
-        (!!(le32toh((h)->incompatible_flags) & HEADER_INCOMPATIBLE_COMPRESSED))
+#define JOURNAL_HEADER_COMPRESSED_XZ(h) \
+        (!!(le32toh((h)->incompatible_flags) & HEADER_INCOMPATIBLE_COMPRESSED_XZ))
+
+#define JOURNAL_HEADER_COMPRESSED_LZ4(h) \
+        (!!(le32toh((h)->incompatible_flags) & HEADER_INCOMPATIBLE_COMPRESSED_LZ4))
 
 int journal_file_move_to_object(JournalFile *f, int type, uint64_t offset, Object **ret);
 
index 2c401e3..2f1f7fc 100644 (file)
@@ -25,7 +25,7 @@
 #include <inttypes.h>
 #include <stdbool.h>
 
-#include <systemd/sd-id128.h>
+#include "systemd/sd-id128.h"
 
 #include "journal-def.h"
 #include "list.h"
index da6244c..c527e65 100644 (file)
@@ -25,6 +25,6 @@
 #include <sys/types.h>
 #include <stdio.h>
 
-#include <systemd/sd-id128.h>
+#include "systemd/sd-id128.h"
 
 int print_qr_code(FILE *f, const void *seed, size_t seed_size, uint64_t start, uint64_t interval, const char *hn, sd_id128_t machine);
index ca9199f..bb1ef66 100644 (file)
@@ -66,7 +66,7 @@ retry:
         fd_inc_sndbuf(fd, SNDBUF_SIZE);
 
         if (!__sync_bool_compare_and_swap(&fd_plus_one, 0, fd+1)) {
-                close_nointr_nofail(fd);
+                safe_close(fd);
                 goto retry;
         }
 
@@ -198,7 +198,8 @@ finish:
 
 _public_ int sd_journal_sendv(const struct iovec *iov, int n) {
         PROTECT_ERRNO;
-        int fd, buffer_fd;
+        int fd;
+        _cleanup_close_ int buffer_fd = -1;
         struct iovec *w;
         uint64_t *l;
         int i, j = 0;
@@ -315,10 +316,8 @@ _public_ int sd_journal_sendv(const struct iovec *iov, int n) {
                 return buffer_fd;
 
         n = writev(buffer_fd, w, j);
-        if (n < 0) {
-                close_nointr_nofail(buffer_fd);
+        if (n < 0)
                 return -errno;
-        }
 
         mh.msg_iov = NULL;
         mh.msg_iovlen = 0;
@@ -336,8 +335,6 @@ _public_ int sd_journal_sendv(const struct iovec *iov, int n) {
         mh.msg_controllen = cmsg->cmsg_len;
 
         k = sendmsg(fd, &mh, MSG_NOSIGNAL);
-        close_nointr_nofail(buffer_fd);
-
         if (k < 0)
                 return -errno;
 
@@ -398,10 +395,10 @@ _public_ int sd_journal_stream_fd(const char *identifier, int priority, int leve
                 .un.sun_family = AF_UNIX,
                 .un.sun_path = "/run/systemd/journal/stdout",
         };
-        int fd;
+        _cleanup_close_ int fd = -1;
         char *header;
         size_t l;
-        ssize_t r;
+        int r;
 
         assert_return(priority >= 0, -EINVAL);
         assert_return(priority <= 7, -EINVAL);
@@ -411,15 +408,11 @@ _public_ int sd_journal_stream_fd(const char *identifier, int priority, int leve
                 return -errno;
 
         r = connect(fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
-        if (r < 0) {
-                close_nointr_nofail(fd);
+        if (r < 0)
                 return -errno;
-        }
 
-        if (shutdown(fd, SHUT_RD) < 0) {
-                close_nointr_nofail(fd);
+        if (shutdown(fd, SHUT_RD) < 0)
                 return -errno;
-        }
 
         fd_inc_sndbuf(fd, SNDBUF_SIZE);
 
@@ -443,18 +436,16 @@ _public_ int sd_journal_stream_fd(const char *identifier, int priority, int leve
         header[l++] = '0';
         header[l++] = '\n';
 
-        r = loop_write(fd, header, l, false);
-        if (r < 0) {
-                close_nointr_nofail(fd);
-                return (int) r;
-        }
+        r = (int) loop_write(fd, header, l, false);
+        if (r < 0)
+                return r;
 
-        if ((size_t) r != l) {
-                close_nointr_nofail(fd);
+        if ((size_t) r != l)
                 return -errno;
-        }
 
-        return fd;
+        r = fd;
+        fd = -1;
+        return r;
 }
 
 _public_ int sd_journal_print_with_location(int priority, const char *file, const char *line, const char *func, const char *format, ...) {
index ebe5e42..7699482 100644 (file)
 #include <sys/stat.h>
 #include <sys/statvfs.h>
 #include <unistd.h>
-
-#ifdef HAVE_XATTR
-#include <attr/xattr.h>
-#endif
+#include <sys/xattr.h>
 
 #include "journal-def.h"
 #include "journal-file.h"
@@ -79,11 +76,8 @@ static void patch_realtime(
                 unsigned long long *realtime) {
 
         usec_t x;
-
-#ifdef HAVE_XATTR
         uint64_t crtime;
         _cleanup_free_ const char *path = NULL;
-#endif
 
         /* The timestamp was determined by the file name, but let's
          * see if the file might actually be older than the file name
@@ -95,18 +89,17 @@ static void patch_realtime(
         assert(realtime);
 
         x = timespec_load(&st->st_ctim);
-        if (x > 0 && x != (usec_t) -1 && x < *realtime)
+        if (x > 0 && x != USEC_INFINITY && x < *realtime)
                 *realtime = x;
 
         x = timespec_load(&st->st_atim);
-        if (x > 0 && x != (usec_t) -1 && x < *realtime)
+        if (x > 0 && x != USEC_INFINITY && x < *realtime)
                 *realtime = x;
 
         x = timespec_load(&st->st_mtim);
-        if (x > 0 && x != (usec_t) -1 && x < *realtime)
+        if (x > 0 && x != USEC_INFINITY && x < *realtime)
                 *realtime = x;
 
-#ifdef HAVE_XATTR
         /* Let's read the original creation time, if possible. Ideally
          * we'd just query the creation time the FS might provide, but
          * unfortunately there's currently no sane API to query
@@ -125,7 +118,6 @@ static void patch_realtime(
                 if (crtime > 0 && crtime != (uint64_t) -1 && crtime < *realtime)
                         *realtime = crtime;
         }
-#endif
 }
 
 static int journal_file_empty(int dir_fd, const char *name) {
@@ -300,13 +292,6 @@ int journal_directory_vacuum(
         qsort_safe(list, n_list, sizeof(struct vacuum_info), vacuum_compare);
 
         for (i = 0; i < n_list; i++) {
-                struct statvfs ss;
-
-                if (fstatvfs(dirfd(d), &ss) < 0) {
-                        r = -errno;
-                        goto finish;
-                }
-
                 if ((max_retention_usec <= 0 || list[i].realtime >= retention_limit) &&
                     (max_use <= 0 || sum <= max_use))
                         break;
index 9434cc9..6c8ca8c 100644 (file)
 #include "compress.h"
 #include "fsprg.h"
 
+static void draw_progress(uint64_t p, usec_t *last_usec) {
+        unsigned n, i, j, k;
+        usec_t z, x;
+
+        if (!on_tty())
+                return;
+
+        z = now(CLOCK_MONOTONIC);
+        x = *last_usec;
+
+        if (x != 0 && x + 40 * USEC_PER_MSEC > z)
+                return;
+
+        *last_usec = z;
+
+        n = (3 * columns()) / 4;
+        j = (n * (unsigned) p) / 65535ULL;
+        k = n - j;
+
+        fputs("\r\x1B[?25l" ANSI_HIGHLIGHT_GREEN_ON, stdout);
+
+        for (i = 0; i < j; i++)
+                fputs("\xe2\x96\x88", stdout);
+
+        fputs(ANSI_HIGHLIGHT_OFF, stdout);
+
+        for (i = 0; i < k; i++)
+                fputs("\xe2\x96\x91", stdout);
+
+        printf(" %3"PRIu64"%%", 100U * p / 65535U);
+
+        fputs("\r\x1B[?25h", stdout);
+        fflush(stdout);
+}
+
+static void flush_progress(void) {
+        unsigned n, i;
+
+        if (!on_tty())
+                return;
+
+        n = (3 * columns()) / 4;
+
+        putchar('\r');
+
+        for (i = 0; i < n + 5; i++)
+                putchar(' ');
+
+        putchar('\r');
+        fflush(stdout);
+}
+
+#define debug(_offset, _fmt, ...) do{                                   \
+                flush_progress();                                       \
+                log_debug(OFSfmt": " _fmt, _offset, ##__VA_ARGS__);     \
+        } while(0)
+
+#define warning(_offset, _fmt, ...) do{                                 \
+                flush_progress();                                       \
+                log_warning(OFSfmt": " _fmt, _offset, ##__VA_ARGS__);   \
+        } while(0)
+
+#define error(_offset, _fmt, ...) do{                                   \
+                flush_progress();                                       \
+                log_error(OFSfmt": " _fmt, (uint64_t)_offset, ##__VA_ARGS__); \
+        } while(0)
+
 static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o) {
         uint64_t i;
 
@@ -45,7 +112,7 @@ static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o
          * possible field values. It does not follow any references to
          * other objects. */
 
-        if ((o->object.flags & OBJECT_COMPRESSED) &&
+        if ((o->object.flags & OBJECT_COMPRESSED_XZ) &&
             o->object.type != OBJECT_DATA)
                 return -EBADMSG;
 
@@ -53,48 +120,46 @@ static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o
 
         case OBJECT_DATA: {
                 uint64_t h1, h2;
+                int compression, r;
 
                 if (le64toh(o->data.entry_offset) == 0)
-                        log_warning(OFSfmt": unused data (entry_offset==0)", offset);
+                        warning(offset, "unused data (entry_offset==0)");
 
                 if ((le64toh(o->data.entry_offset) == 0) ^ (le64toh(o->data.n_entries) == 0)) {
-                        log_error(OFSfmt": bad n_entries: %"PRIu64, offset, o->data.n_entries);
+                        error(offset, "bad n_entries: %"PRIu64, o->data.n_entries);
                         return -EBADMSG;
                 }
 
                 if (le64toh(o->object.size) - offsetof(DataObject, payload) <= 0) {
-                        log_error(OFSfmt": bad object size (<= %zu): %"PRIu64,
-                                  offset,
-                                  offsetof(DataObject, payload),
-                                  le64toh(o->object.size));
+                        error(offset, "bad object size (<= %zu): %"PRIu64,
+                              offsetof(DataObject, payload),
+                              le64toh(o->object.size));
                         return -EBADMSG;
                 }
 
                 h1 = le64toh(o->data.hash);
 
-                if (o->object.flags & OBJECT_COMPRESSED) {
-#ifdef HAVE_XZ
-                        void *b = NULL;
-                        uint64_t alloc = 0, b_size;
-
-                        if (!uncompress_blob(o->data.payload,
-                                             le64toh(o->object.size) - offsetof(Object, data.payload),
-                                             &b, &alloc, &b_size, 0)) {
-                                log_error(OFSfmt": uncompression failed", offset);
-                                return -EBADMSG;
+                compression = o->object.flags & OBJECT_COMPRESSION_MASK;
+                if (compression) {
+                        _cleanup_free_ void *b = NULL;
+                        size_t alloc = 0, b_size;
+
+                        r = decompress_blob(compression,
+                                            o->data.payload,
+                                            le64toh(o->object.size) - offsetof(Object, data.payload),
+                                            &b, &alloc, &b_size, 0);
+                        if (r < 0) {
+                                error(offset, "%s decompression failed: %s",
+                                      object_compressed_to_string(compression), strerror(-r));
+                                return r;
                         }
 
                         h2 = hash64(b, b_size);
-                        free(b);
-#else
-                        log_error("Compression is not supported");
-                        return -EPROTONOSUPPORT;
-#endif
                 } else
                         h2 = hash64(o->data.payload, le64toh(o->object.size) - offsetof(Object, data.payload));
 
                 if (h1 != h2) {
-                        log_error(OFSfmt": invalid hash (%08"PRIx64" vs. %08"PRIx64, offset, h1, h2);
+                        error(offset, "invalid hash (%08"PRIx64" vs. %08"PRIx64, h1, h2);
                         return -EBADMSG;
                 }
 
@@ -102,12 +167,11 @@ static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o
                     !VALID64(o->data.next_field_offset) ||
                     !VALID64(o->data.entry_offset) ||
                     !VALID64(o->data.entry_array_offset)) {
-                        log_error(OFSfmt": invalid offset (next_hash_offset="OFSfmt", next_field_offset="OFSfmt", entry_offset="OFSfmt", entry_array_offset="OFSfmt,
-                                  offset,
-                                  o->data.next_hash_offset,
-                                  o->data.next_field_offset,
-                                  o->data.entry_offset,
-                                  o->data.entry_array_offset);
+                        error(offset, "invalid offset (next_hash_offset="OFSfmt", next_field_offset="OFSfmt", entry_offset="OFSfmt", entry_array_offset="OFSfmt,
+                              o->data.next_hash_offset,
+                              o->data.next_field_offset,
+                              o->data.entry_offset,
+                              o->data.entry_array_offset);
                         return -EBADMSG;
                 }
 
@@ -116,67 +180,67 @@ static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o
 
         case OBJECT_FIELD:
                 if (le64toh(o->object.size) - offsetof(FieldObject, payload) <= 0) {
-                        log_error(OFSfmt": bad field size (<= %zu): %"PRIu64,
-                                  offset,
-                                  offsetof(FieldObject, payload),
-                                  le64toh(o->object.size));
+                        error(offset,
+                              "bad field size (<= %zu): %"PRIu64,
+                              offsetof(FieldObject, payload),
+                              le64toh(o->object.size));
                         return -EBADMSG;
                 }
 
                 if (!VALID64(o->field.next_hash_offset) ||
                     !VALID64(o->field.head_data_offset)) {
-                        log_error(OFSfmt": invalid offset (next_hash_offset="OFSfmt", head_data_offset="OFSfmt,
-                                  offset,
-                                  o->field.next_hash_offset,
-                                  o->field.head_data_offset);
+                        error(offset,
+                              "invalid offset (next_hash_offset="OFSfmt", head_data_offset="OFSfmt,
+                              o->field.next_hash_offset,
+                              o->field.head_data_offset);
                         return -EBADMSG;
                 }
                 break;
 
         case OBJECT_ENTRY:
                 if ((le64toh(o->object.size) - offsetof(EntryObject, items)) % sizeof(EntryItem) != 0) {
-                        log_error(OFSfmt": bad entry size (<= %zu): %"PRIu64,
-                                  offset,
-                                  offsetof(EntryObject, items),
-                                  le64toh(o->object.size));
+                        error(offset,
+                              "bad entry size (<= %zu): %"PRIu64,
+                              offsetof(EntryObject, items),
+                              le64toh(o->object.size));
                         return -EBADMSG;
                 }
 
                 if ((le64toh(o->object.size) - offsetof(EntryObject, items)) / sizeof(EntryItem) <= 0) {
-                        log_error(OFSfmt": invalid number items in entry: %"PRIu64,
-                                  offset,
-                                  (le64toh(o->object.size) - offsetof(EntryObject, items)) / sizeof(EntryItem));
+                        error(offset,
+                              "invalid number items in entry: %"PRIu64,
+                              (le64toh(o->object.size) - offsetof(EntryObject, items)) / sizeof(EntryItem));
                         return -EBADMSG;
                 }
 
                 if (le64toh(o->entry.seqnum) <= 0) {
-                        log_error(OFSfmt": invalid entry seqnum: %"PRIx64,
-                                  offset,
-                                  le64toh(o->entry.seqnum));
+                        error(offset,
+                              "invalid entry seqnum: %"PRIx64,
+                              le64toh(o->entry.seqnum));
                         return -EBADMSG;
                 }
 
                 if (!VALID_REALTIME(le64toh(o->entry.realtime))) {
-                        log_error(OFSfmt": invalid entry realtime timestamp: %"PRIu64,
-                                  offset,
-                                  le64toh(o->entry.realtime));
+                        error(offset,
+                              "invalid entry realtime timestamp: %"PRIu64,
+                              le64toh(o->entry.realtime));
                         return -EBADMSG;
                 }
 
                 if (!VALID_MONOTONIC(le64toh(o->entry.monotonic))) {
-                        log_error(OFSfmt": invalid entry monotonic timestamp: %"PRIu64,
-                                  offset,
-                                  le64toh(o->entry.monotonic));
+                        error(offset,
+                              "invalid entry monotonic timestamp: %"PRIu64,
+                              le64toh(o->entry.monotonic));
                         return -EBADMSG;
                 }
 
                 for (i = 0; i < journal_file_entry_n_items(o); i++) {
                         if (o->entry.items[i].object_offset == 0 ||
                             !VALID64(o->entry.items[i].object_offset)) {
-                                log_error(OFSfmt": invalid entry item (%"PRIu64"/%"PRIu64" offset: "OFSfmt,
-                                          offset,
-                                          i, journal_file_entry_n_items(o),
-                                          o->entry.items[i].object_offset);
+                                error(offset,
+                                      "invalid entry item (%"PRIu64"/%"PRIu64" offset: "OFSfmt,
+                                      i, journal_file_entry_n_items(o),
+                                      o->entry.items[i].object_offset);
                                 return -EBADMSG;
                         }
                 }
@@ -187,41 +251,41 @@ static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o
         case OBJECT_FIELD_HASH_TABLE:
                 if ((le64toh(o->object.size) - offsetof(HashTableObject, items)) % sizeof(HashItem) != 0 ||
                     (le64toh(o->object.size) - offsetof(HashTableObject, items)) / sizeof(HashItem) <= 0) {
-                        log_error(OFSfmt": invalid %s hash table size: %"PRIu64,
-                                  offset,
-                                  o->object.type == OBJECT_DATA_HASH_TABLE ? "data" : "field",
-                                  le64toh(o->object.size));
+                        error(offset,
+                              "invalid %s hash table size: %"PRIu64,
+                              o->object.type == OBJECT_DATA_HASH_TABLE ? "data" : "field",
+                              le64toh(o->object.size));
                         return -EBADMSG;
                 }
 
                 for (i = 0; i < journal_file_hash_table_n_items(o); i++) {
                         if (o->hash_table.items[i].head_hash_offset != 0 &&
                             !VALID64(le64toh(o->hash_table.items[i].head_hash_offset))) {
-                                log_error(OFSfmt": invalid %s hash table item (%"PRIu64"/%"PRIu64") head_hash_offset: "OFSfmt,
-                                          offset,
-                                          o->object.type == OBJECT_DATA_HASH_TABLE ? "data" : "field",
-                                          i, journal_file_hash_table_n_items(o),
-                                          le64toh(o->hash_table.items[i].head_hash_offset));
+                                error(offset,
+                                      "invalid %s hash table item (%"PRIu64"/%"PRIu64") head_hash_offset: "OFSfmt,
+                                      o->object.type == OBJECT_DATA_HASH_TABLE ? "data" : "field",
+                                      i, journal_file_hash_table_n_items(o),
+                                      le64toh(o->hash_table.items[i].head_hash_offset));
                                 return -EBADMSG;
                         }
                         if (o->hash_table.items[i].tail_hash_offset != 0 &&
                             !VALID64(le64toh(o->hash_table.items[i].tail_hash_offset))) {
-                                log_error(OFSfmt": invalid %s hash table item (%"PRIu64"/%"PRIu64") tail_hash_offset: "OFSfmt,
-                                          offset,
-                                          o->object.type == OBJECT_DATA_HASH_TABLE ? "data" : "field",
-                                          i, journal_file_hash_table_n_items(o),
-                                          le64toh(o->hash_table.items[i].tail_hash_offset));
+                                error(offset,
+                                      "invalid %s hash table item (%"PRIu64"/%"PRIu64") tail_hash_offset: "OFSfmt,
+                                      o->object.type == OBJECT_DATA_HASH_TABLE ? "data" : "field",
+                                      i, journal_file_hash_table_n_items(o),
+                                      le64toh(o->hash_table.items[i].tail_hash_offset));
                                 return -EBADMSG;
                         }
 
                         if ((o->hash_table.items[i].head_hash_offset != 0) !=
                             (o->hash_table.items[i].tail_hash_offset != 0)) {
-                                log_error(OFSfmt": invalid %s hash table item (%"PRIu64"/%"PRIu64"): head_hash_offset="OFSfmt" tail_hash_offset="OFSfmt,
-                                          offset,
-                                          o->object.type == OBJECT_DATA_HASH_TABLE ? "data" : "field",
-                                          i, journal_file_hash_table_n_items(o),
-                                          le64toh(o->hash_table.items[i].head_hash_offset),
-                                          le64toh(o->hash_table.items[i].tail_hash_offset));
+                                error(offset,
+                                      "invalid %s hash table item (%"PRIu64"/%"PRIu64"): head_hash_offset="OFSfmt" tail_hash_offset="OFSfmt,
+                                      o->object.type == OBJECT_DATA_HASH_TABLE ? "data" : "field",
+                                      i, journal_file_hash_table_n_items(o),
+                                      le64toh(o->hash_table.items[i].head_hash_offset),
+                                      le64toh(o->hash_table.items[i].tail_hash_offset));
                                 return -EBADMSG;
                         }
                 }
@@ -231,26 +295,26 @@ static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o
         case OBJECT_ENTRY_ARRAY:
                 if ((le64toh(o->object.size) - offsetof(EntryArrayObject, items)) % sizeof(le64_t) != 0 ||
                     (le64toh(o->object.size) - offsetof(EntryArrayObject, items)) / sizeof(le64_t) <= 0) {
-                        log_error(OFSfmt": invalid object entry array size: %"PRIu64,
-                                  offset,
-                                  le64toh(o->object.size));
+                        error(offset,
+                              "invalid object entry array size: %"PRIu64,
+                              le64toh(o->object.size));
                         return -EBADMSG;
                 }
 
                 if (!VALID64(o->entry_array.next_entry_array_offset)) {
-                        log_error(OFSfmt": invalid object entry array next_entry_array_offset: "OFSfmt,
-                                  offset,
-                                  o->entry_array.next_entry_array_offset);
+                        error(offset,
+                              "invalid object entry array next_entry_array_offset: "OFSfmt,
+                              o->entry_array.next_entry_array_offset);
                         return -EBADMSG;
                 }
 
                 for (i = 0; i < journal_file_entry_array_n_items(o); i++)
                         if (le64toh(o->entry_array.items[i]) != 0 &&
                             !VALID64(le64toh(o->entry_array.items[i]))) {
-                                log_error(OFSfmt": invalid object entry array item (%"PRIu64"/%"PRIu64"): "OFSfmt,
-                                          offset,
-                                          i, journal_file_entry_array_n_items(o),
-                                          le64toh(o->entry_array.items[i]));
+                                error(offset,
+                                      "invalid object entry array item (%"PRIu64"/%"PRIu64"): "OFSfmt,
+                                      i, journal_file_entry_array_n_items(o),
+                                      le64toh(o->entry_array.items[i]));
                                 return -EBADMSG;
                         }
 
@@ -258,16 +322,16 @@ static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o
 
         case OBJECT_TAG:
                 if (le64toh(o->object.size) != sizeof(TagObject)) {
-                        log_error(OFSfmt": invalid object tag size: %"PRIu64,
-                                  offset,
-                                  le64toh(o->object.size));
+                        error(offset,
+                              "invalid object tag size: %"PRIu64,
+                              le64toh(o->object.size));
                         return -EBADMSG;
                 }
 
                 if (!VALID_EPOCH(o->tag.epoch)) {
-                        log_error(OFSfmt": invalid object tag epoch: %"PRIu64,
-                                  offset,
-                                  o->tag.epoch);
+                        error(offset,
+                              "invalid object tag epoch: %"PRIu64,
+                              o->tag.epoch);
                         return -EBADMSG;
                 }
 
@@ -277,58 +341,6 @@ static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o
         return 0;
 }
 
-static void draw_progress(uint64_t p, usec_t *last_usec) {
-        unsigned n, i, j, k;
-        usec_t z, x;
-
-        if (!on_tty())
-                return;
-
-        z = now(CLOCK_MONOTONIC);
-        x = *last_usec;
-
-        if (x != 0 && x + 40 * USEC_PER_MSEC > z)
-                return;
-
-        *last_usec = z;
-
-        n = (3 * columns()) / 4;
-        j = (n * (unsigned) p) / 65535ULL;
-        k = n - j;
-
-        fputs("\r\x1B[?25l" ANSI_HIGHLIGHT_GREEN_ON, stdout);
-
-        for (i = 0; i < j; i++)
-                fputs("\xe2\x96\x88", stdout);
-
-        fputs(ANSI_HIGHLIGHT_OFF, stdout);
-
-        for (i = 0; i < k; i++)
-                fputs("\xe2\x96\x91", stdout);
-
-        printf(" %3"PRIu64"%%", 100U * p / 65535U);
-
-        fputs("\r\x1B[?25h", stdout);
-        fflush(stdout);
-}
-
-static void flush_progress(void) {
-        unsigned n, i;
-
-        if (!on_tty())
-                return;
-
-        n = (3 * columns()) / 4;
-
-        putchar('\r');
-
-        for (i = 0; i < n + 5; i++)
-                putchar(' ');
-
-        putchar('\r');
-        fflush(stdout);
-}
-
 static int write_uint64(int fd, uint64_t p) {
         ssize_t k;
 
@@ -391,7 +403,8 @@ static int entry_points_to_data(
         assert(entry_fd >= 0);
 
         if (!contains_uint64(f->mmap, entry_fd, n_entries, entry_p)) {
-                log_error("Data object references invalid entry at %"PRIu64, data_p);
+                error(data_p,
+                      "data object references invalid entry at "OFSfmt, entry_p);
                 return -EBADMSG;
         }
 
@@ -407,7 +420,8 @@ static int entry_points_to_data(
                 }
 
         if (!found) {
-                log_error("Data object not referenced by linked entry at %"PRIu64, data_p);
+                error(entry_p,
+                      "data object at "OFSfmt" not referenced by linked entry", data_p);
                 return -EBADMSG;
         }
 
@@ -450,7 +464,7 @@ static int entry_points_to_data(
                                         x = z;
                         }
 
-                        log_error("Entry object doesn't exist in main entry array at %"PRIu64, entry_p);
+                        error(entry_p, "entry object doesn't exist in main entry array");
                         return -EBADMSG;
                 }
 
@@ -480,8 +494,9 @@ static int verify_data(
 
         /* Entry array means at least two objects */
         if (a && n < 2) {
-                log_error("Entry array present (entry_array_offset=%"PRIu64", but n_entries=%"PRIu64,
-                          a, n);
+                error(p,
+                      "entry array present (entry_array_offset="OFSfmt", but n_entries=%"PRIu64")",
+                      a, n);
                 return -EBADMSG;
         }
 
@@ -501,12 +516,12 @@ static int verify_data(
                 uint64_t next, m, j;
 
                 if (a == 0) {
-                        log_error("Array chain too short at %"PRIu64, p);
+                        error(p, "array chain too short");
                         return -EBADMSG;
                 }
 
                 if (!contains_uint64(f->mmap, entry_array_fd, n_entry_arrays, a)) {
-                        log_error("Invalid array at %"PRIu64, p);
+                        error(p, "invalid array offset "OFSfmt, a);
                         return -EBADMSG;
                 }
 
@@ -516,7 +531,8 @@ static int verify_data(
 
                 next = le64toh(o->entry_array.next_entry_array_offset);
                 if (next != 0 && next <= a) {
-                        log_error("Array chain has cycle at %"PRIu64, p);
+                        error(p, "array chain has cycle (jumps back from "OFSfmt" to "OFSfmt")",
+                              a, next);
                         return -EBADMSG;
                 }
 
@@ -525,7 +541,7 @@ static int verify_data(
 
                         q = le64toh(o->entry_array.items[j]);
                         if (q <= last) {
-                                log_error("Data object's entry array not sorted at %"PRIu64, p);
+                                error(p, "data object's entry array not sorted");
                                 return -EBADMSG;
                         }
                         last = q;
@@ -576,8 +592,8 @@ static int verify_hash_table(
                         uint64_t next;
 
                         if (!contains_uint64(f->mmap, data_fd, n_data, p)) {
-                                log_error("Invalid data object at hash entry %"PRIu64" of %"PRIu64,
-                                          i, n);
+                                error(p, "invalid data object at hash entry %"PRIu64" of %"PRIu64,
+                                      i, n);
                                 return -EBADMSG;
                         }
 
@@ -587,14 +603,14 @@ static int verify_hash_table(
 
                         next = le64toh(o->data.next_hash_offset);
                         if (next != 0 && next <= p) {
-                                log_error("Hash chain has a cycle in hash entry %"PRIu64" of %"PRIu64,
-                                          i, n);
+                                error(p, "hash chain has a cycle in hash entry %"PRIu64" of %"PRIu64,
+                                      i, n);
                                 return -EBADMSG;
                         }
 
                         if (le64toh(o->data.hash) % n != i) {
-                                log_error("Hash value mismatch in hash entry %"PRIu64" of %"PRIu64,
-                                          i, n);
+                                error(p, "hash value mismatch in hash entry %"PRIu64" of %"PRIu64,
+                                      i, n);
                                 return -EBADMSG;
                         }
 
@@ -607,7 +623,7 @@ static int verify_hash_table(
                 }
 
                 if (last != le64toh(f->data_hash_table[i].tail_hash_offset)) {
-                        log_error("Tail hash pointer mismatch in hash table");
+                        error(p, "tail hash pointer mismatch in hash table");
                         return -EBADMSG;
                 }
         }
@@ -661,7 +677,7 @@ static int verify_entry(
                 h = le64toh(o->entry.items[i].hash);
 
                 if (!contains_uint64(f->mmap, data_fd, n_data, q)) {
-                        log_error("Invalid data object at entry %"PRIu64, p);
+                        error(p, "invalid data object of entry");
                                 return -EBADMSG;
                         }
 
@@ -670,7 +686,7 @@ static int verify_entry(
                         return r;
 
                 if (le64toh(u->data.hash) != h) {
-                        log_error("Hash mismatch for data object at entry %"PRIu64, p);
+                        error(p, "hash mismatch for data object of entry");
                         return -EBADMSG;
                 }
 
@@ -678,7 +694,7 @@ static int verify_entry(
                 if (r < 0)
                         return r;
                 if (r == 0) {
-                        log_error("Data object missing from hash at entry %"PRIu64, p);
+                        error(p, "data object missing from hash table");
                         return -EBADMSG;
                 }
         }
@@ -713,12 +729,12 @@ static int verify_entry_array(
                         draw_progress(0x8000 + (0x3FFF * i / n), last_usec);
 
                 if (a == 0) {
-                        log_error("Array chain too short at %"PRIu64" of %"PRIu64, i, n);
+                        error(a, "array chain too short at %"PRIu64" of %"PRIu64, i, n);
                         return -EBADMSG;
                 }
 
                 if (!contains_uint64(f->mmap, entry_array_fd, n_entry_arrays, a)) {
-                        log_error("Invalid array at %"PRIu64" of %"PRIu64, i, n);
+                        error(a, "invalid array %"PRIu64" of %"PRIu64, i, n);
                         return -EBADMSG;
                 }
 
@@ -728,7 +744,9 @@ static int verify_entry_array(
 
                 next = le64toh(o->entry_array.next_entry_array_offset);
                 if (next != 0 && next <= a) {
-                        log_error("Array chain has cycle at %"PRIu64" of %"PRIu64, i, n);
+                        error(a,
+                              "array chain has cycle at %"PRIu64" of %"PRIu64" (jumps back from to "OFSfmt")",
+                              i, n, next);
                         return -EBADMSG;
                 }
 
@@ -738,15 +756,15 @@ static int verify_entry_array(
 
                         p = le64toh(o->entry_array.items[j]);
                         if (p <= last) {
-                                log_error("Entry array not sorted at %"PRIu64" of %"PRIu64,
-                                          i, n);
+                                error(a, "entry array not sorted at %"PRIu64" of %"PRIu64,
+                                      i, n);
                                 return -EBADMSG;
                         }
                         last = p;
 
                         if (!contains_uint64(f->mmap, entry_fd, n_entries, p)) {
-                                log_error("Invalid array entry at %"PRIu64" of %"PRIu64,
-                                          i, n);
+                                error(a, "invalid array entry at %"PRIu64" of %"PRIu64,
+                                      i, n);
                                 return -EBADMSG;
                         }
 
@@ -826,12 +844,7 @@ int journal_file_verify(
                 goto fail;
         }
 
-#ifdef HAVE_GCRYPT
-        if ((le32toh(f->header->compatible_flags) & ~HEADER_COMPATIBLE_SEALED) != 0)
-#else
-        if (f->header->compatible_flags != 0)
-#endif
-        {
+        if (le32toh(f->header->compatible_flags) & ~HEADER_COMPATIBLE_SUPPORTED) {
                 log_error("Cannot verify file with unknown extensions.");
                 r = -ENOTSUP;
                 goto fail;
@@ -839,7 +852,7 @@ int journal_file_verify(
 
         for (i = 0; i < sizeof(f->header->reserved); i++)
                 if (f->header->reserved[i] != 0) {
-                        log_error("Reserved field in non-zero.");
+                        error(offsetof(Header, reserved[i]), "reserved field is non-zero");
                         r = -EBADMSG;
                         goto fail;
                 }
@@ -854,12 +867,12 @@ int journal_file_verify(
 
                 r = journal_file_move_to_object(f, -1, p, &o);
                 if (r < 0) {
-                        log_error("Invalid object at "OFSfmt, p);
+                        error(p, "invalid object");
                         goto fail;
                 }
 
                 if (p > le64toh(f->header->tail_object_offset)) {
-                        log_error("Invalid tail object pointer");
+                        error(offsetof(Header, tail_object_offset), "invalid tail object pointer");
                         r = -EBADMSG;
                         goto fail;
                 }
@@ -871,12 +884,25 @@ int journal_file_verify(
 
                 r = journal_file_object_verify(f, p, o);
                 if (r < 0) {
-                        log_error("Invalid object contents at "OFSfmt": %s", p, strerror(-r));
+                        error(p, "invalid object contents: %s", strerror(-r));
+                        goto fail;
+                }
+
+                if ((o->object.flags & OBJECT_COMPRESSED_XZ) &&
+                    (o->object.flags & OBJECT_COMPRESSED_LZ4)) {
+                        error(p, "objected with double compression");
+                        r = -EINVAL;
+                        goto fail;
+                }
+
+                if ((o->object.flags & OBJECT_COMPRESSED_XZ) && !JOURNAL_HEADER_COMPRESSED_XZ(f->header)) {
+                        error(p, "XZ compressed object in file without XZ compression");
+                        r = -EBADMSG;
                         goto fail;
                 }
 
-                if ((o->object.flags & OBJECT_COMPRESSED) && !JOURNAL_HEADER_COMPRESSED(f->header)) {
-                        log_error("Compressed object in file without compression at "OFSfmt, p);
+                if ((o->object.flags & OBJECT_COMPRESSED_LZ4) && !JOURNAL_HEADER_COMPRESSED_LZ4(f->header)) {
+                        error(p, "LZ4 compressed object in file without LZ4 compression");
                         r = -EBADMSG;
                         goto fail;
                 }
@@ -897,7 +923,7 @@ int journal_file_verify(
 
                 case OBJECT_ENTRY:
                         if (JOURNAL_HEADER_SEALED(f->header) && n_tags <= 0) {
-                                log_error("First entry before first tag at "OFSfmt, p);
+                                error(p, "first entry before first tag");
                                 r = -EBADMSG;
                                 goto fail;
                         }
@@ -907,21 +933,21 @@ int journal_file_verify(
                                 goto fail;
 
                         if (le64toh(o->entry.realtime) < last_tag_realtime) {
-                                log_error("Older entry after newer tag at "OFSfmt, p);
+                                error(p, "older entry after newer tag");
                                 r = -EBADMSG;
                                 goto fail;
                         }
 
                         if (!entry_seqnum_set &&
                             le64toh(o->entry.seqnum) != le64toh(f->header->head_entry_seqnum)) {
-                                log_error("Head entry sequence number incorrect at "OFSfmt, p);
+                                error(p, "head entry sequence number incorrect");
                                 r = -EBADMSG;
                                 goto fail;
                         }
 
                         if (entry_seqnum_set &&
                             entry_seqnum >= le64toh(o->entry.seqnum)) {
-                                log_error("Entry sequence number out of synchronization at "OFSfmt, p);
+                                error(p, "entry sequence number out of synchronization");
                                 r = -EBADMSG;
                                 goto fail;
                         }
@@ -932,7 +958,7 @@ int journal_file_verify(
                         if (entry_monotonic_set &&
                             sd_id128_equal(entry_boot_id, o->entry.boot_id) &&
                             entry_monotonic > le64toh(o->entry.monotonic)) {
-                                log_error("Entry timestamp out of synchronization at "OFSfmt, p);
+                                error(p, "entry timestamp out of synchronization");
                                 r = -EBADMSG;
                                 goto fail;
                         }
@@ -943,7 +969,7 @@ int journal_file_verify(
 
                         if (!entry_realtime_set &&
                             le64toh(o->entry.realtime) != le64toh(f->header->head_entry_realtime)) {
-                                log_error("Head entry realtime timestamp incorrect");
+                                error(p, "head entry realtime timestamp incorrect");
                                 r = -EBADMSG;
                                 goto fail;
                         }
@@ -956,14 +982,14 @@ int journal_file_verify(
 
                 case OBJECT_DATA_HASH_TABLE:
                         if (n_data_hash_tables > 1) {
-                                log_error("More than one data hash table at "OFSfmt, p);
+                                error(p, "more than one data hash table");
                                 r = -EBADMSG;
                                 goto fail;
                         }
 
                         if (le64toh(f->header->data_hash_table_offset) != p + offsetof(HashTableObject, items) ||
                             le64toh(f->header->data_hash_table_size) != le64toh(o->object.size) - offsetof(HashTableObject, items)) {
-                                log_error("Header fields for data hash table invalid");
+                                error(p, "header fields for data hash table invalid");
                                 r = -EBADMSG;
                                 goto fail;
                         }
@@ -973,14 +999,14 @@ int journal_file_verify(
 
                 case OBJECT_FIELD_HASH_TABLE:
                         if (n_field_hash_tables > 1) {
-                                log_error("More than one field hash table at "OFSfmt, p);
+                                error(p, "more than one field hash table");
                                 r = -EBADMSG;
                                 goto fail;
                         }
 
                         if (le64toh(f->header->field_hash_table_offset) != p + offsetof(HashTableObject, items) ||
                             le64toh(f->header->field_hash_table_size) != le64toh(o->object.size) - offsetof(HashTableObject, items)) {
-                                log_error("Header fields for field hash table invalid");
+                                error(p, "header fields for field hash table invalid");
                                 r = -EBADMSG;
                                 goto fail;
                         }
@@ -995,7 +1021,7 @@ int journal_file_verify(
 
                         if (p == le64toh(f->header->entry_array_offset)) {
                                 if (found_main_entry_array) {
-                                        log_error("More than one main entry array at "OFSfmt, p);
+                                        error(p, "more than one main entry array");
                                         r = -EBADMSG;
                                         goto fail;
                                 }
@@ -1008,19 +1034,19 @@ int journal_file_verify(
 
                 case OBJECT_TAG:
                         if (!JOURNAL_HEADER_SEALED(f->header)) {
-                                log_error("Tag object in file without sealing at "OFSfmt, p);
+                                error(p, "tag object in file without sealing");
                                 r = -EBADMSG;
                                 goto fail;
                         }
 
                         if (le64toh(o->tag.seqnum) != n_tags + 1) {
-                                log_error("Tag sequence number out of synchronization at "OFSfmt, p);
+                                error(p, "tag sequence number out of synchronization");
                                 r = -EBADMSG;
                                 goto fail;
                         }
 
                         if (le64toh(o->tag.epoch) < last_epoch) {
-                                log_error("Epoch sequence out of synchronization at "OFSfmt, p);
+                                error(p, "epoch sequence out of synchronization");
                                 r = -EBADMSG;
                                 goto fail;
                         }
@@ -1029,11 +1055,11 @@ int journal_file_verify(
                         if (f->seal) {
                                 uint64_t q, rt;
 
-                                log_debug("Checking tag %"PRIu64"...", le64toh(o->tag.seqnum));
+                                debug(p, "checking tag %"PRIu64"...", le64toh(o->tag.seqnum));
 
                                 rt = f->fss_start_usec + o->tag.epoch * f->fss_interval_usec;
                                 if (entry_realtime_set && entry_realtime >= rt + f->fss_interval_usec) {
-                                        log_error("Tag/entry realtime timestamp out of synchronization at "OFSfmt, p);
+                                        error(p, "tag/entry realtime timestamp out of synchronization");
                                         r = -EBADMSG;
                                         goto fail;
                                 }
@@ -1076,7 +1102,7 @@ int journal_file_verify(
                                         goto fail;
 
                                 if (memcmp(o->tag.tag, gcry_md_read(f->hmac, 0), TAG_LENGTH) != 0) {
-                                        log_error("Tag failed verification at "OFSfmt, p);
+                                        error(p, "tag failed verification");
                                         r = -EBADMSG;
                                         goto fail;
                                 }
@@ -1105,72 +1131,72 @@ int journal_file_verify(
         }
 
         if (!found_last) {
-                log_error("Tail object pointer dead");
+                error(le64toh(f->header->tail_object_offset), "tail object pointer dead");
                 r = -EBADMSG;
                 goto fail;
         }
 
         if (n_objects != le64toh(f->header->n_objects)) {
-                log_error("Object number mismatch");
+                error(offsetof(Header, n_objects), "object number mismatch");
                 r = -EBADMSG;
                 goto fail;
         }
 
         if (n_entries != le64toh(f->header->n_entries)) {
-                log_error("Entry number mismatch");
+                error(offsetof(Header, n_entries), "entry number mismatch");
                 r = -EBADMSG;
                 goto fail;
         }
 
         if (JOURNAL_HEADER_CONTAINS(f->header, n_data) &&
             n_data != le64toh(f->header->n_data)) {
-                log_error("Data number mismatch");
+                error(offsetof(Header, n_data), "data number mismatch");
                 r = -EBADMSG;
                 goto fail;
         }
 
         if (JOURNAL_HEADER_CONTAINS(f->header, n_fields) &&
             n_fields != le64toh(f->header->n_fields)) {
-                log_error("Field number mismatch");
+                error(offsetof(Header, n_fields), "field number mismatch");
                 r = -EBADMSG;
                 goto fail;
         }
 
         if (JOURNAL_HEADER_CONTAINS(f->header, n_tags) &&
             n_tags != le64toh(f->header->n_tags)) {
-                log_error("Tag number mismatch");
+                error(offsetof(Header, n_tags), "tag number mismatch");
                 r = -EBADMSG;
                 goto fail;
         }
 
         if (JOURNAL_HEADER_CONTAINS(f->header, n_entry_arrays) &&
             n_entry_arrays != le64toh(f->header->n_entry_arrays)) {
-                log_error("Entry array number mismatch");
+                error(offsetof(Header, n_entry_arrays), "entry array number mismatch");
                 r = -EBADMSG;
                 goto fail;
         }
 
         if (n_data_hash_tables != 1) {
-                log_error("Missing data hash table");
+                error(0, "missing data hash table");
                 r = -EBADMSG;
                 goto fail;
         }
 
         if (n_field_hash_tables != 1) {
-                log_error("Missing field hash table");
+                error(0, "missing field hash table");
                 r = -EBADMSG;
                 goto fail;
         }
 
         if (!found_main_entry_array) {
-                log_error("Missing entry array");
+                error(0, "missing entry array");
                 r = -EBADMSG;
                 goto fail;
         }
 
         if (entry_seqnum_set &&
             entry_seqnum != le64toh(f->header->tail_entry_seqnum)) {
-                log_error("Invalid tail seqnum");
+                error(offsetof(Header, tail_entry_seqnum), "invalid tail seqnum");
                 r = -EBADMSG;
                 goto fail;
         }
@@ -1178,13 +1204,13 @@ int journal_file_verify(
         if (entry_monotonic_set &&
             (!sd_id128_equal(entry_boot_id, f->header->boot_id) ||
              entry_monotonic != le64toh(f->header->tail_entry_monotonic))) {
-                log_error("Invalid tail monotonic timestamp");
+                error(0, "invalid tail monotonic timestamp");
                 r = -EBADMSG;
                 goto fail;
         }
 
         if (entry_realtime_set && entry_realtime != le64toh(f->header->tail_entry_realtime)) {
-                log_error("Invalid tail realtime timestamp");
+                error(0, "invalid tail realtime timestamp");
                 r = -EBADMSG;
                 goto fail;
         }
@@ -1222,9 +1248,9 @@ int journal_file_verify(
         mmap_cache_close_fd(f->mmap, entry_fd);
         mmap_cache_close_fd(f->mmap, entry_array_fd);
 
-        close_nointr_nofail(data_fd);
-        close_nointr_nofail(entry_fd);
-        close_nointr_nofail(entry_array_fd);
+        safe_close(data_fd);
+        safe_close(entry_fd);
+        safe_close(entry_array_fd);
 
         if (first_contained)
                 *first_contained = le64toh(f->header->head_entry_realtime);
@@ -1247,17 +1273,17 @@ fail:
 
         if (data_fd >= 0) {
                 mmap_cache_close_fd(f->mmap, data_fd);
-                close_nointr_nofail(data_fd);
+                safe_close(data_fd);
         }
 
         if (entry_fd >= 0) {
                 mmap_cache_close_fd(f->mmap, entry_fd);
-                close_nointr_nofail(entry_fd);
+                safe_close(entry_fd);
         }
 
         if (entry_array_fd >= 0) {
                 mmap_cache_close_fd(f->mmap, entry_array_fd);
-                close_nointr_nofail(entry_array_fd);
+                safe_close(entry_array_fd);
         }
 
         return r;
index a328ba1..5c4a71d 100644 (file)
@@ -40,7 +40,7 @@
 #include "acl-util.h"
 #endif
 
-#include <systemd/sd-journal.h>
+#include "systemd/sd-journal.h"
 
 #include "log.h"
 #include "logs-show.h"
@@ -160,15 +160,15 @@ static int parse_boot_descriptor(const char *x, sd_id128_t *boot_id, int *offset
         return 0;
 }
 
-static int help(void) {
+static void help(void) {
 
         pager_open_if_enabled();
 
         printf("%s [OPTIONS...] [MATCHES...]\n\n"
                "Query the journal.\n\n"
                "Flags:\n"
-               "     --system              Show only the system journal\n"
-               "     --user                Show only the user journal for the current user\n"
+               "     --system              Show the system journal\n"
+               "     --user                Show the user journal for the current user\n"
                "  -M --machine=CONTAINER   Operate on local container\n"
                "     --since=DATE          Start showing entries on or newer than the specified date\n"
                "     --until=DATE          Stop showing entries on or older than the specified date\n"
@@ -218,8 +218,6 @@ static int help(void) {
                "     --verify              Verify journal file consistency\n"
 #endif
                , program_invocation_short_name);
-
-        return 0;
 }
 
 static int parse_argv(int argc, char *argv[]) {
@@ -306,12 +304,13 @@ static int parse_argv(int argc, char *argv[]) {
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "hefo:aln::qmb::kD:p:c:u:F:xrM:", options, NULL)) >= 0) {
+        while ((c = getopt_long(argc, argv, "hefo:aln::qmb::kD:p:c:u:F:xrM:", options, NULL)) >= 0)
 
                 switch (c) {
 
                 case 'h':
-                        return help();
+                        help();
+                        return 0;
 
                 case ARG_VERSION:
                         puts(PACKAGE_STRING);
@@ -633,7 +632,6 @@ static int parse_argv(int argc, char *argv[]) {
                 default:
                         assert_not_reached("Unhandled option");
                 }
-        }
 
         if (arg_follow && !arg_no_tail && arg_lines < 0)
                 arg_lines = 10;
@@ -658,6 +656,11 @@ static int parse_argv(int argc, char *argv[]) {
                 return -EINVAL;
         }
 
+        if (arg_action != ACTION_SHOW && optind < argc) {
+                log_error("Extraneous arguments starting with '%s'", argv[optind]);
+                return -EINVAL;
+        }
+
         return 1;
 }
 
@@ -694,15 +697,20 @@ static int generate_new_id128(void) {
 
 static int add_matches(sd_journal *j, char **args) {
         char **i;
+        bool have_term = false;
 
         assert(j);
 
         STRV_FOREACH(i, args) {
                 int r;
 
-                if (streq(*i, "+"))
+                if (streq(*i, "+")) {
+                        if (!have_term)
+                                break;
                         r = sd_journal_add_disjunction(j);
-                else if (path_is_absolute(*i)) {
+                        have_term = false;
+
+                } else if (path_is_absolute(*i)) {
                         _cleanup_free_ char *p, *t = NULL, *t2 = NULL;
                         const char *path;
                         _cleanup_free_ char *interpreter = NULL;
@@ -736,11 +744,17 @@ static int add_matches(sd_journal *j, char **args) {
                                         }
                                 } else
                                         t = strappend("_EXE=", path);
-                        } else if (S_ISCHR(st.st_mode))
-                                asprintf(&t, "_KERNEL_DEVICE=c%u:%u", major(st.st_rdev), minor(st.st_rdev));
-                        else if (S_ISBLK(st.st_mode))
-                                asprintf(&t, "_KERNEL_DEVICE=b%u:%u", major(st.st_rdev), minor(st.st_rdev));
-                        else {
+                        } else if (S_ISCHR(st.st_mode)) {
+                                if (asprintf(&t, "_KERNEL_DEVICE=c%u:%u",
+                                             major(st.st_rdev),
+                                             minor(st.st_rdev)) < 0)
+                                        return -ENOMEM;
+                        } else if (S_ISBLK(st.st_mode)) {
+                                if (asprintf(&t, "_KERNEL_DEVICE=b%u:%u",
+                                             major(st.st_rdev),
+                                             minor(st.st_rdev)) < 0)
+                                        return -ENOMEM;
+                        } else {
                                 log_error("File is neither a device node, nor regular file, nor executable: %s", *i);
                                 return -EINVAL;
                         }
@@ -751,8 +765,12 @@ static int add_matches(sd_journal *j, char **args) {
                         r = sd_journal_add_match(j, t, 0);
                         if (t2)
                                 r = sd_journal_add_match(j, t2, 0);
-                } else
+                        have_term = true;
+
+                } else {
                         r = sd_journal_add_match(j, *i, 0);
+                        have_term = true;
+                }
 
                 if (r < 0) {
                         log_error("Failed to add match '%s': %s", *i, strerror(-r));
@@ -760,6 +778,11 @@ static int add_matches(sd_journal *j, char **args) {
                 }
         }
 
+        if (!strv_isempty(args) && !have_term) {
+                log_error("\"+\" can only be used between terms");
+                return -EINVAL;
+        }
+
         return 0;
 }
 
@@ -1285,7 +1308,7 @@ static int setup_keys(void) {
         n = now(CLOCK_REALTIME);
         n /= arg_interval;
 
-        close_nointr_nofail(fd);
+        safe_close(fd);
         fd = mkostemp_safe(k, O_WRONLY|O_CLOEXEC);
         if (fd < 0) {
                 log_error("Failed to open %s: %m", k);
@@ -1384,8 +1407,7 @@ static int setup_keys(void) {
         r = 0;
 
 finish:
-        if (fd >= 0)
-                close_nointr_nofail(fd);
+        safe_close(fd);
 
         if (k) {
                 unlink(k);
@@ -1590,16 +1612,12 @@ int main(int argc, char *argv[]) {
             arg_action == ACTION_LIST_CATALOG ||
             arg_action == ACTION_DUMP_CATALOG) {
 
-                const char* database = CATALOG_DATABASE;
-                _cleanup_free_ char *copy = NULL;
-                if (arg_root) {
-                        copy = strjoin(arg_root, "/", CATALOG_DATABASE, NULL);
-                        if (!copy) {
-                                r = log_oom();
-                                goto finish;
-                        }
-                        path_kill_slashes(copy);
-                        database = copy;
+                _cleanup_free_ char *database;
+
+                database = path_join(arg_root, CATALOG_DATABASE, NULL);
+                if (!database) {
+                        r = log_oom();
+                        goto finish;
                 }
 
                 if (arg_action == ACTION_UPDATE_CATALOG) {
@@ -1748,7 +1766,7 @@ int main(int argc, char *argv[]) {
         }
 
         if (arg_cursor || arg_after_cursor) {
-                r = sd_journal_seek_cursor(j, arg_cursor ? arg_cursor : arg_after_cursor);
+                r = sd_journal_seek_cursor(j, arg_cursor ?: arg_after_cursor);
                 if (r < 0) {
                         log_error("Failed to seek to cursor: %s", strerror(-r));
                         return EXIT_FAILURE;
@@ -1933,5 +1951,7 @@ int main(int argc, char *argv[]) {
 finish:
         pager_close();
 
+        strv_free(arg_file);
+
         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
 }
index 35da52a..6ec2528 100644 (file)
@@ -67,9 +67,9 @@ void server_forward_console(
         /* First: timestamp */
         if (prefix_timestamp()) {
                 assert_se(clock_gettime(CLOCK_MONOTONIC, &ts) == 0);
-                snprintf(tbuf, sizeof(tbuf), "[%5llu.%06llu] ",
-                         (unsigned long long) ts.tv_sec,
-                         (unsigned long long) ts.tv_nsec / 1000);
+                snprintf(tbuf, sizeof(tbuf), "[%5"PRI_TIME".%06ld] ",
+                         ts.tv_sec,
+                         ts.tv_nsec / 1000);
                 IOVEC_SET_STRING(iovec[n++], tbuf);
         }
 
@@ -80,7 +80,7 @@ void server_forward_console(
                         identifier = ident_buf;
                 }
 
-                snprintf(header_pid, sizeof(header_pid), "[%lu]: ", (unsigned long) ucred->pid);
+                snprintf(header_pid, sizeof(header_pid), "["PID_FMT"]: ", ucred->pid);
                 char_array_0(header_pid);
 
                 if (identifier)
@@ -107,5 +107,5 @@ void server_forward_console(
         if (writev(fd, iovec, n) < 0)
                 log_debug("Failed to write to %s for logging: %m", tty);
 
-        close_nointr_nofail(fd);
+        safe_close(fd);
 }
index 84efee3..74554c1 100644 (file)
@@ -15,26 +15,28 @@ struct ConfigPerfItem;
 %struct-type
 %includes
 %%
-Journal.Storage,            config_parse_storage,   0, offsetof(Server, storage)
-Journal.Compress,           config_parse_bool,      0, offsetof(Server, compress)
-Journal.Seal,               config_parse_bool,      0, offsetof(Server, seal)
-Journal.SyncIntervalSec,    config_parse_sec,       0, offsetof(Server, sync_interval_usec)
-Journal.RateLimitInterval,  config_parse_sec,       0, offsetof(Server, rate_limit_interval)
-Journal.RateLimitBurst,     config_parse_unsigned,  0, offsetof(Server, rate_limit_burst)
-Journal.SystemMaxUse,       config_parse_iec_off,   0, offsetof(Server, system_metrics.max_use)
-Journal.SystemMaxFileSize,  config_parse_iec_off,   0, offsetof(Server, system_metrics.max_size)
-Journal.SystemKeepFree,     config_parse_iec_off,   0, offsetof(Server, system_metrics.keep_free)
-Journal.RuntimeMaxUse,      config_parse_iec_off,   0, offsetof(Server, runtime_metrics.max_use)
-Journal.RuntimeMaxFileSize, config_parse_iec_off,   0, offsetof(Server, runtime_metrics.max_size)
-Journal.RuntimeKeepFree,    config_parse_iec_off,   0, offsetof(Server, runtime_metrics.keep_free)
-Journal.MaxRetentionSec,    config_parse_sec,       0, offsetof(Server, max_retention_usec)
-Journal.MaxFileSec,         config_parse_sec,       0, offsetof(Server, max_file_usec)
-Journal.ForwardToSyslog,    config_parse_bool,      0, offsetof(Server, forward_to_syslog)
-Journal.ForwardToKMsg,      config_parse_bool,      0, offsetof(Server, forward_to_kmsg)
-Journal.ForwardToConsole,   config_parse_bool,      0, offsetof(Server, forward_to_console)
-Journal.TTYPath,            config_parse_path,      0, offsetof(Server, tty_path)
-Journal.MaxLevelStore,      config_parse_level,     0, offsetof(Server, max_level_store)
-Journal.MaxLevelSyslog,     config_parse_level,     0, offsetof(Server, max_level_syslog)
-Journal.MaxLevelKMsg,       config_parse_level,     0, offsetof(Server, max_level_kmsg)
-Journal.MaxLevelConsole,    config_parse_level,     0, offsetof(Server, max_level_console)
-Journal.SplitMode,          config_parse_split_mode,0, offsetof(Server, split_mode)
+Journal.Storage,            config_parse_storage,    0, offsetof(Server, storage)
+Journal.Compress,           config_parse_bool,       0, offsetof(Server, compress)
+Journal.Seal,               config_parse_bool,       0, offsetof(Server, seal)
+Journal.SyncIntervalSec,    config_parse_sec,        0, offsetof(Server, sync_interval_usec)
+Journal.RateLimitInterval,  config_parse_sec,        0, offsetof(Server, rate_limit_interval)
+Journal.RateLimitBurst,     config_parse_unsigned,   0, offsetof(Server, rate_limit_burst)
+Journal.SystemMaxUse,       config_parse_iec_off,    0, offsetof(Server, system_metrics.max_use)
+Journal.SystemMaxFileSize,  config_parse_iec_off,    0, offsetof(Server, system_metrics.max_size)
+Journal.SystemKeepFree,     config_parse_iec_off,    0, offsetof(Server, system_metrics.keep_free)
+Journal.RuntimeMaxUse,      config_parse_iec_off,    0, offsetof(Server, runtime_metrics.max_use)
+Journal.RuntimeMaxFileSize, config_parse_iec_off,    0, offsetof(Server, runtime_metrics.max_size)
+Journal.RuntimeKeepFree,    config_parse_iec_off,    0, offsetof(Server, runtime_metrics.keep_free)
+Journal.MaxRetentionSec,    config_parse_sec,        0, offsetof(Server, max_retention_usec)
+Journal.MaxFileSec,         config_parse_sec,        0, offsetof(Server, max_file_usec)
+Journal.ForwardToSyslog,    config_parse_bool,       0, offsetof(Server, forward_to_syslog)
+Journal.ForwardToKMsg,      config_parse_bool,       0, offsetof(Server, forward_to_kmsg)
+Journal.ForwardToConsole,   config_parse_bool,       0, offsetof(Server, forward_to_console)
+Journal.ForwardToWall,      config_parse_bool,       0, offsetof(Server, forward_to_wall)
+Journal.TTYPath,            config_parse_path,       0, offsetof(Server, tty_path)
+Journal.MaxLevelStore,      config_parse_log_level,  0, offsetof(Server, max_level_store)
+Journal.MaxLevelSyslog,     config_parse_log_level,  0, offsetof(Server, max_level_syslog)
+Journal.MaxLevelKMsg,       config_parse_log_level,  0, offsetof(Server, max_level_kmsg)
+Journal.MaxLevelConsole,    config_parse_log_level,  0, offsetof(Server, max_level_console)
+Journal.MaxLevelWall,       config_parse_log_level,  0, offsetof(Server, max_level_wall)
+Journal.SplitMode,          config_parse_split_mode, 0, offsetof(Server, split_mode)
index 05b128f..fb8ea08 100644 (file)
@@ -25,7 +25,7 @@
 #include <sys/mman.h>
 #include <sys/socket.h>
 
-#include <systemd/sd-messages.h>
+#include "systemd/sd-messages.h"
 #include <libudev.h>
 
 #include "journald-server.h"
@@ -71,7 +71,7 @@ void server_forward_kmsg(
                         identifier = ident_buf;
                 }
 
-                snprintf(header_pid, sizeof(header_pid), "[%lu]: ", (unsigned long) ucred->pid);
+                snprintf(header_pid, sizeof(header_pid), "["PID_FMT"]: ", ucred->pid);
                 char_array_0(header_pid);
 
                 if (identifier)
@@ -152,7 +152,7 @@ static void dev_kmsg_record(Server *s, char *p, size_t l) {
                 /* Did we lose any? */
                 if (serial > *s->kernel_seqnum)
                         server_driver_message(s, SD_MESSAGE_JOURNAL_MISSED, "Missed %"PRIu64" kernel messages",
-                                              serial - *s->kernel_seqnum - 1);
+                                              serial - *s->kernel_seqnum);
 
                 /* Make sure we never read this one again. Note that
                  * we always store the next message serial we expect
@@ -274,6 +274,9 @@ static void dev_kmsg_record(Server *s, char *p, size_t l) {
         if (asprintf(&syslog_priority, "PRIORITY=%i", priority & LOG_PRIMASK) >= 0)
                 IOVEC_SET_STRING(iovec[n++], syslog_priority);
 
+        if (asprintf(&syslog_facility, "SYSLOG_FACILITY=%i", LOG_FAC(priority)) >= 0)
+                IOVEC_SET_STRING(iovec[n++], syslog_facility);
+
         if ((priority & LOG_FACMASK) == LOG_KERN)
                 IOVEC_SET_STRING(iovec[n++], "SYSLOG_IDENTIFIER=kernel");
         else {
@@ -295,9 +298,6 @@ static void dev_kmsg_record(Server *s, char *p, size_t l) {
                         if (syslog_pid)
                                 IOVEC_SET_STRING(iovec[n++], syslog_pid);
                 }
-
-                if (asprintf(&syslog_facility, "SYSLOG_FACILITY=%i", LOG_FAC(priority)) >= 0)
-                        IOVEC_SET_STRING(iovec[n++], syslog_facility);
         }
 
         message = cunescape_length_with_prefix(p, pl, "MESSAGE=");
@@ -428,19 +428,14 @@ int server_open_dev_kmsg(Server *s) {
         return 0;
 
 fail:
-        if (s->dev_kmsg_event_source)
-                s->dev_kmsg_event_source = sd_event_source_unref(s->dev_kmsg_event_source);
-
-        if (s->dev_kmsg_fd >= 0) {
-                close_nointr_nofail(s->dev_kmsg_fd);
-                s->dev_kmsg_fd = -1;
-        }
+        s->dev_kmsg_event_source = sd_event_source_unref(s->dev_kmsg_event_source);
+        s->dev_kmsg_fd = safe_close(s->dev_kmsg_fd);
 
         return r;
 }
 
 int server_open_kernel_seqnum(Server *s) {
-        int fd;
+        _cleanup_close_ int fd;
         uint64_t *p;
 
         assert(s);
@@ -457,18 +452,15 @@ int server_open_kernel_seqnum(Server *s) {
 
         if (posix_fallocate(fd, 0, sizeof(uint64_t)) < 0) {
                 log_error("Failed to allocate sequential number file, ignoring: %m");
-                close_nointr_nofail(fd);
                 return 0;
         }
 
         p = mmap(NULL, sizeof(uint64_t), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
         if (p == MAP_FAILED) {
                 log_error("Failed to map sequential number file, ignoring: %m");
-                close_nointr_nofail(fd);
                 return 0;
         }
 
-        close_nointr_nofail(fd);
         s->kernel_seqnum = p;
 
         return 0;
index 359d962..ac2d0ba 100644 (file)
 #include "journald-kmsg.h"
 #include "journald-console.h"
 #include "journald-syslog.h"
+#include "journald-wall.h"
 
-/* Make sure not to make this smaller than the maximum coredump
- * size. See COREDUMP_MAX in coredump.c */
-#define ENTRY_SIZE_MAX (1024*1024*768)
-#define DATA_SIZE_MAX (1024*1024*768)
-
-static bool valid_user_field(const char *p, size_t l) {
+bool valid_user_field(const char *p, size_t l, bool allow_protected) {
         const char *a;
 
         /* We kinda enforce POSIX syntax recommendations for
@@ -55,7 +51,7 @@ static bool valid_user_field(const char *p, size_t l) {
                 return false;
 
         /* Variables starting with an underscore are protected */
-        if (p[0] == '_')
+        if (!allow_protected && p[0] == '_')
                 return false;
 
         /* Don't allow digits as first character */
@@ -64,9 +60,9 @@ static bool valid_user_field(const char *p, size_t l) {
 
         /* Only allow A-Z0-9 and '_' */
         for (a = p; a < p + l; a++)
-                if (!((*a >= 'A' && *a <= 'Z') ||
-                      (*a >= '0' && *a <= '9') ||
-                      *a == '_'))
+                if ((*a < 'A' || *a > 'Z') &&
+                    (*a < '0' || *a > '9') &&
+                    *a != '_')
                         return false;
 
         return true;
@@ -86,7 +82,7 @@ void server_process_native_message(
         struct iovec *iovec = NULL;
         unsigned n = 0, j, tn = (unsigned) -1;
         const char *p;
-        size_t remaining, m = 0;
+        size_t remaining, m = 0, entry_size = 0;
         int priority = LOG_INFO;
         char *identifier = NULL, *message = NULL;
         pid_t object_pid = 0;
@@ -110,9 +106,16 @@ void server_process_native_message(
 
                 if (e == p) {
                         /* Entry separator */
+
+                        if (entry_size + n + 1 > ENTRY_SIZE_MAX) { /* data + separators + trailer */
+                                log_debug("Entry is too big with %u properties and %zu bytes, ignoring.", n, entry_size);
+                                continue;
+                        }
+
                         server_dispatch_message(s, iovec, n, m, ucred, tv, label, label_len, NULL, priority, object_pid);
                         n = 0;
                         priority = LOG_INFO;
+                        entry_size = 0;
 
                         p++;
                         remaining--;
@@ -130,15 +133,14 @@ void server_process_native_message(
                 /* A property follows */
 
                 /* n received properties, +1 for _TRANSPORT */
-                if (!GREEDY_REALLOC(iovec, m, n + 1 + N_IOVEC_META_FIELDS +
-                                              !!object_pid * N_IOVEC_OBJECT_FIELDS)) {
+                if (!GREEDY_REALLOC(iovec, m, n + 1 + N_IOVEC_META_FIELDS + !!object_pid * N_IOVEC_OBJECT_FIELDS)) {
                         log_oom();
                         break;
                 }
 
                 q = memchr(p, '=', e - p);
                 if (q) {
-                        if (valid_user_field(p, q - p)) {
+                        if (valid_user_field(p, q - p, false)) {
                                 size_t l;
 
                                 l = e - p;
@@ -149,6 +151,7 @@ void server_process_native_message(
                                  * field */
                                 iovec[n].iov_base = (char*) p;
                                 iovec[n].iov_len = l;
+                                entry_size += iovec[n].iov_len;
                                 n++;
 
                                 /* We need to determine the priority
@@ -218,7 +221,7 @@ void server_process_native_message(
                         l = le64toh(l_le);
 
                         if (l > DATA_SIZE_MAX) {
-                                log_debug("Received binary data block too large, ignoring.");
+                                log_debug("Received binary data block of %"PRIu64" bytes is too large, ignoring.", l);
                                 break;
                         }
 
@@ -238,9 +241,10 @@ void server_process_native_message(
                         k[e - p] = '=';
                         memcpy(k + (e - p) + 1, e + 1 + sizeof(uint64_t), l);
 
-                        if (valid_user_field(p, e - p)) {
+                        if (valid_user_field(p, e - p, false)) {
                                 iovec[n].iov_base = k;
                                 iovec[n].iov_len = (e - p) + 1 + l;
+                                entry_size += iovec[n].iov_len;
                                 n++;
                         } else
                                 free(k);
@@ -255,6 +259,13 @@ void server_process_native_message(
 
         tn = n++;
         IOVEC_SET_STRING(iovec[tn], "_TRANSPORT=journal");
+        entry_size += strlen("_TRANSPORT=journal");
+
+        if (entry_size + n + 1 > ENTRY_SIZE_MAX) { /* data + separators + trailer */
+                log_debug("Entry is too big with %u properties and %zu bytes, ignoring.",
+                          n, entry_size);
+                goto finish;
+        }
 
         if (message) {
                 if (s->forward_to_syslog)
@@ -265,6 +276,9 @@ void server_process_native_message(
 
                 if (s->forward_to_console)
                         server_forward_console(s, priority, identifier, message, ucred);
+
+                if (s->forward_to_wall)
+                        server_forward_wall(s, priority, identifier, message, ucred);
         }
 
         server_dispatch_message(s, iovec, n, m, ucred, tv, label, label_len, NULL, priority, object_pid);
@@ -367,12 +381,15 @@ void server_process_native_file(
 }
 
 int server_open_native_socket(Server*s) {
-        union sockaddr_union sa;
         int one, r;
 
         assert(s);
 
         if (s->native_fd < 0) {
+                union sockaddr_union sa = {
+                        .un.sun_family = AF_UNIX,
+                        .un.sun_path = "/run/systemd/journal/socket",
+                };
 
                 s->native_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
                 if (s->native_fd < 0) {
@@ -380,15 +397,11 @@ int server_open_native_socket(Server*s) {
                         return -errno;
                 }
 
-                zero(sa);
-                sa.un.sun_family = AF_UNIX;
-                strncpy(sa.un.sun_path, "/run/systemd/journal/socket", sizeof(sa.un.sun_path));
-
                 unlink(sa.un.sun_path);
 
                 r = bind(s->native_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
                 if (r < 0) {
-                        log_error("bind() failed: %m");
+                        log_error("bind(%s) failed: %m", sa.un.sun_path);
                         return -errno;
                 }
 
index 16c09f5..e82a5b8 100644 (file)
 
 #include "journald-server.h"
 
+/* Make sure not to make this smaller than the maximum coredump
+ * size. See COREDUMP_MAX in coredump.c */
+#define ENTRY_SIZE_MAX (1024*1024*770u)
+#define DATA_SIZE_MAX (1024*1024*768u)
+
+bool valid_user_field(const char *p, size_t l, bool allow_protected);
+
 void server_process_native_message(Server *s, const void *buffer, size_t buffer_size, struct ucred *ucred, struct timeval *tv, const char *label, size_t label_len);
 
 void server_process_native_file(Server *s, int fd, struct ucred *ucred, struct timeval *tv, const char *label, size_t label_len);
index 96ef66d..c3fb44a 100644 (file)
 #define DEFAULT_SYNC_INTERVAL_USEC (5*USEC_PER_MINUTE)
 #define DEFAULT_RATE_LIMIT_INTERVAL (30*USEC_PER_SEC)
 #define DEFAULT_RATE_LIMIT_BURST 1000
+#define DEFAULT_MAX_FILE_USEC USEC_PER_MONTH
 
 #define RECHECK_AVAILABLE_SPACE_USEC (30*USEC_PER_SEC)
 
-static const char* const storage_table[] = {
+static const char* const storage_table[_STORAGE_MAX] = {
         [STORAGE_AUTO] = "auto",
         [STORAGE_VOLATILE] = "volatile",
         [STORAGE_PERSISTENT] = "persistent",
@@ -80,10 +81,10 @@ static const char* const storage_table[] = {
 DEFINE_STRING_TABLE_LOOKUP(storage, Storage);
 DEFINE_CONFIG_PARSE_ENUM(config_parse_storage, storage, Storage, "Failed to parse storage setting");
 
-static const char* const split_mode_table[] = {
-        [SPLIT_NONE] = "none",
+static const char* const split_mode_table[_SPLIT_MAX] = {
+        [SPLIT_LOGIN] = "login",
         [SPLIT_UID] = "uid",
-        [SPLIT_LOGIN] = "login"
+        [SPLIT_NONE] = "none",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(split_mode, SplitMode);
@@ -205,7 +206,7 @@ void server_fix_perms(Server *s, JournalFile *f, uid_t uid) {
                 log_warning("Failed to fix access mode on %s, ignoring: %s", f->path, strerror(-r));
 
 #ifdef HAVE_ACL
-        if (uid <= 0)
+        if (uid <= SYSTEM_UID_MAX)
                 return;
 
         acl = acl_get_fd(f->fd);
@@ -258,7 +259,7 @@ static JournalFile* find_journal(Server *s, uid_t uid) {
         if (s->runtime_journal)
                 return s->runtime_journal;
 
-        if (uid <= 0)
+        if (uid <= SYSTEM_UID_MAX)
                 return s->system_journal;
 
         r = sd_id128_get_machine(&machine);
@@ -269,8 +270,8 @@ static JournalFile* find_journal(Server *s, uid_t uid) {
         if (f)
                 return f;
 
-        if (asprintf(&p, "/var/log/journal/" SD_ID128_FORMAT_STR "/user-%lu.journal",
-                     SD_ID128_FORMAT_VAL(machine), (unsigned long) uid) < 0)
+        if (asprintf(&p, "/var/log/journal/" SD_ID128_FORMAT_STR "/user-"UID_FMT".journal",
+                     SD_ID128_FORMAT_VAL(machine), uid) < 0)
                 return s->system_journal;
 
         while (hashmap_size(s->user_journals) >= USER_JOURNALS_MAX) {
@@ -295,6 +296,27 @@ static JournalFile* find_journal(Server *s, uid_t uid) {
         return f;
 }
 
+static int do_rotate(Server *s, JournalFile **f, const char* name,
+                     bool seal, uint32_t uid) {
+        int r;
+        assert(s);
+
+        if (!*f)
+                return -EINVAL;
+
+        r = journal_file_rotate(f, s->compress, seal);
+        if (r < 0)
+                if (*f)
+                        log_error("Failed to rotate %s: %s",
+                                  (*f)->path, strerror(-r));
+                else
+                        log_error("Failed to create new %s journal: %s",
+                                  name, strerror(-r));
+        else
+                server_fix_perms(s, *f, uid);
+        return r;
+}
+
 void server_rotate(Server *s) {
         JournalFile *f;
         void *k;
@@ -303,42 +325,16 @@ void server_rotate(Server *s) {
 
         log_debug("Rotating...");
 
-        if (s->runtime_journal) {
-                r = journal_file_rotate(&s->runtime_journal, s->compress, false);
-                if (r < 0)
-                        if (s->runtime_journal)
-                                log_error("Failed to rotate %s: %s", s->runtime_journal->path, strerror(-r));
-                        else
-                                log_error("Failed to create new runtime journal: %s", strerror(-r));
-                else
-                        server_fix_perms(s, s->runtime_journal, 0);
-        }
-
-        if (s->system_journal) {
-                r = journal_file_rotate(&s->system_journal, s->compress, s->seal);
-                if (r < 0)
-                        if (s->system_journal)
-                                log_error("Failed to rotate %s: %s", s->system_journal->path, strerror(-r));
-                        else
-                                log_error("Failed to create new system journal: %s", strerror(-r));
-
-                else
-                        server_fix_perms(s, s->system_journal, 0);
-        }
+        do_rotate(s, &s->runtime_journal, "runtime", false, 0);
+        do_rotate(s, &s->system_journal, "system", s->seal, 0);
 
         HASHMAP_FOREACH_KEY(f, k, s->user_journals, i) {
-                r = journal_file_rotate(&f, s->compress, s->seal);
-                if (r < 0)
-                        if (f)
-                                log_error("Failed to rotate %s: %s", f->path, strerror(-r));
-                        else {
-                                log_error("Failed to create user journal: %s", strerror(-r));
-                                hashmap_remove(s->user_journals, k);
-                        }
-                else {
+                r = do_rotate(s, &f, "user", s->seal, PTR_TO_UINT32(k));
+                if (r >= 0)
                         hashmap_replace(s->user_journals, k, f);
-                        server_fix_perms(s, f, PTR_TO_UINT32(k));
-                }
+                else if (!f)
+                        /* Old file has been closed and deallocated */
+                        hashmap_remove(s->user_journals, k);
         }
 }
 
@@ -369,6 +365,20 @@ void server_sync(Server *s) {
         s->sync_scheduled = false;
 }
 
+static void do_vacuum(Server *s, char *ids, JournalFile *f, const char* path,
+                      JournalMetrics *metrics) {
+        char *p;
+        int r;
+
+        if (!f)
+                return;
+
+        p = strappenda(path, ids);
+        r = journal_directory_vacuum(p, metrics->max_use, s->max_retention_usec, &s->oldest_file_usec);
+        if (r < 0 && r != -ENOENT)
+                log_error("Failed to vacuum %s: %s", p, strerror(-r));
+}
+
 void server_vacuum(Server *s) {
         char ids[33];
         sd_id128_t machine;
@@ -383,24 +393,10 @@ void server_vacuum(Server *s) {
                 log_error("Failed to get machine ID: %s", strerror(-r));
                 return;
         }
-
         sd_id128_to_string(machine, ids);
 
-        if (s->system_journal) {
-                char *p = strappenda("/var/log/journal/", ids);
-
-                r = journal_directory_vacuum(p, s->system_metrics.max_use, s->max_retention_usec, &s->oldest_file_usec);
-                if (r < 0 && r != -ENOENT)
-                        log_error("Failed to vacuum %s: %s", p, strerror(-r));
-        }
-
-        if (s->runtime_journal) {
-                char *p = strappenda("/run/log/journal/", ids);
-
-                r = journal_directory_vacuum(p, s->runtime_metrics.max_use, s->max_retention_usec, &s->oldest_file_usec);
-                if (r < 0 && r != -ENOENT)
-                        log_error("Failed to vacuum %s: %s", p, strerror(-r));
-        }
+        do_vacuum(s, ids, s->system_journal, "/var/log/journal/", &s->system_metrics);
+        do_vacuum(s, ids, s->runtime_journal, "/run/log/journal/", &s->runtime_metrics);
 
         s->cached_available_space_timestamp = 0;
 }
@@ -581,13 +577,13 @@ static void dispatch_message_real(
         if (ucred) {
                 realuid = ucred->uid;
 
-                sprintf(pid, "_PID=%lu", (unsigned long) ucred->pid);
+                sprintf(pid, "_PID="PID_FMT, ucred->pid);
                 IOVEC_SET_STRING(iovec[n++], pid);
 
-                sprintf(uid, "_UID=%lu", (unsigned long) ucred->uid);
+                sprintf(uid, "_UID="UID_FMT, ucred->uid);
                 IOVEC_SET_STRING(iovec[n++], uid);
 
-                sprintf(gid, "_GID=%lu", (unsigned long) ucred->gid);
+                sprintf(gid, "_GID="GID_FMT, ucred->gid);
                 IOVEC_SET_STRING(iovec[n++], gid);
 
                 r = get_process_comm(ucred->pid, &t);
@@ -621,13 +617,13 @@ static void dispatch_message_real(
 #ifdef HAVE_AUDIT
                 r = audit_session_from_pid(ucred->pid, &audit);
                 if (r >= 0) {
-                        sprintf(audit_session, "_AUDIT_SESSION=%lu", (unsigned long) audit);
+                        sprintf(audit_session, "_AUDIT_SESSION=%"PRIu32, audit);
                         IOVEC_SET_STRING(iovec[n++], audit_session);
                 }
 
                 r = audit_loginuid_from_pid(ucred->pid, &loginuid);
                 if (r >= 0) {
-                        sprintf(audit_loginuid, "_AUDIT_LOGINUID=%lu", (unsigned long) loginuid);
+                        sprintf(audit_loginuid, "_AUDIT_LOGINUID="UID_FMT, loginuid);
                         IOVEC_SET_STRING(iovec[n++], audit_loginuid);
                 }
 #endif
@@ -649,7 +645,7 @@ static void dispatch_message_real(
                         if (cg_path_get_owner_uid(c, &owner) >= 0) {
                                 owner_valid = true;
 
-                                sprintf(owner_uid, "_SYSTEMD_OWNER_UID=%lu", (unsigned long) owner);
+                                sprintf(owner_uid, "_SYSTEMD_OWNER_UID="UID_FMT, owner);
                                 IOVEC_SET_STRING(iovec[n++], owner_uid);
                         }
 
@@ -686,7 +682,7 @@ static void dispatch_message_real(
 #ifdef HAVE_SELINUX
                 if (use_selinux()) {
                         if (label) {
-                                x = alloca(sizeof("_SELINUX_CONTEXT=") + label_len);
+                                x = alloca(strlen("_SELINUX_CONTEXT=") + label_len + 1);
 
                                 *((char*) mempcpy(stpcpy(x, "_SELINUX_CONTEXT="), label, label_len)) = 0;
                                 IOVEC_SET_STRING(iovec[n++], x);
@@ -708,13 +704,13 @@ static void dispatch_message_real(
         if (object_pid) {
                 r = get_process_uid(object_pid, &object_uid);
                 if (r >= 0) {
-                        sprintf(o_uid, "OBJECT_UID=%lu", (unsigned long) object_uid);
+                        sprintf(o_uid, "OBJECT_UID="UID_FMT, object_uid);
                         IOVEC_SET_STRING(iovec[n++], o_uid);
                 }
 
                 r = get_process_gid(object_pid, &object_gid);
                 if (r >= 0) {
-                        sprintf(o_gid, "OBJECT_GID=%lu", (unsigned long) object_gid);
+                        sprintf(o_gid, "OBJECT_GID="GID_FMT, object_gid);
                         IOVEC_SET_STRING(iovec[n++], o_gid);
                 }
 
@@ -742,13 +738,13 @@ static void dispatch_message_real(
 #ifdef HAVE_AUDIT
                 r = audit_session_from_pid(object_pid, &audit);
                 if (r >= 0) {
-                        sprintf(o_audit_session, "OBJECT_AUDIT_SESSION=%lu", (unsigned long) audit);
+                        sprintf(o_audit_session, "OBJECT_AUDIT_SESSION=%"PRIu32, audit);
                         IOVEC_SET_STRING(iovec[n++], o_audit_session);
                 }
 
                 r = audit_loginuid_from_pid(object_pid, &loginuid);
                 if (r >= 0) {
-                        sprintf(o_audit_loginuid, "OBJECT_AUDIT_LOGINUID=%lu", (unsigned long) loginuid);
+                        sprintf(o_audit_loginuid, "OBJECT_AUDIT_LOGINUID="UID_FMT, loginuid);
                         IOVEC_SET_STRING(iovec[n++], o_audit_loginuid);
                 }
 #endif
@@ -766,7 +762,7 @@ static void dispatch_message_real(
                         }
 
                         if (cg_path_get_owner_uid(c, &owner) >= 0) {
-                                sprintf(o_owner_uid, "OBJECT_SYSTEMD_OWNER_UID=%lu", (unsigned long) owner);
+                                sprintf(o_owner_uid, "OBJECT_SYSTEMD_OWNER_UID="UID_FMT, owner);
                                 IOVEC_SET_STRING(iovec[n++], o_owner_uid);
                         }
 
@@ -810,12 +806,11 @@ static void dispatch_message_real(
                 /* Split up strictly by any UID */
                 journal_uid = realuid;
         else if (s->split_mode == SPLIT_LOGIN && realuid > 0 && owner_valid && owner > 0)
-                /* Split up by login UIDs, this avoids creation of
-                 * individual journals for system UIDs.  We do this
-                 * only if the realuid is not root, in order not to
-                 * accidentally leak privileged information to the
-                 * user that is logged by a privileged process that is
-                 * part of an unprivileged session.*/
+                /* Split up by login UIDs.  We do this only if the
+                 * realuid is not root, in order not to accidentally
+                 * leak privileged information to the user that is
+                 * logged by a privileged process that is part of an
+                 * unprivileged session.*/
                 journal_uid = owner;
         else
                 journal_uid = 0;
@@ -995,7 +990,10 @@ static int system_journal_open(Server *s) {
                         /* OK, we really need the runtime journal, so create
                          * it if necessary. */
 
-                        (void) mkdir_parents(fn, 0755);
+                        (void) mkdir("/run/log", 0755);
+                        (void) mkdir("/run/log/journal", 0755);
+                        (void) mkdir_parents(fn, 0750);
+
                         r = journal_file_open_reliably(fn, O_RDWR|O_CREAT, 0640, s->compress, false, &s->runtime_metrics, s->mmap, NULL, &s->runtime_journal);
                         free(fn);
 
@@ -1131,15 +1129,13 @@ int process_datagram(sd_event_source *es, int fd, uint32_t revents, void *userda
                 union {
                         struct cmsghdr cmsghdr;
 
-                        /* We use NAME_MAX space for the
-                         * SELinux label here. The kernel
-                         * currently enforces no limit, but
-                         * according to suggestions from the
-                         * SELinux people this will change and
-                         * it will probably be identical to
-                         * NAME_MAX. For now we use that, but
-                         * this should be updated one day when
-                         * the final limit is known.*/
+                        /* We use NAME_MAX space for the SELinux label
+                         * here. The kernel currently enforces no
+                         * limit, but according to suggestions from
+                         * the SELinux people this will change and it
+                         * will probably be identical to NAME_MAX. For
+                         * now we use that, but this should be updated
+                         * one day when the final limit is known.*/
                         uint8_t buf[CMSG_SPACE(sizeof(struct ucred)) +
                                     CMSG_SPACE(sizeof(struct timeval)) +
                                     CMSG_SPACE(sizeof(int)) + /* fd */
@@ -1216,8 +1212,6 @@ int process_datagram(sd_event_source *es, int fd, uint32_t revents, void *userda
 
                 close_many(fds, n_fds);
         }
-
-        return 0;
 }
 
 static int dispatch_sigusr1(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) {
@@ -1229,6 +1223,9 @@ static int dispatch_sigusr1(sd_event_source *es, const struct signalfd_siginfo *
 
         touch("/run/systemd/journal/flushed");
         server_flush_to_var(s);
+#ifdef CONFIG_TIZEN
+        server_vacuum(s);
+#endif
         server_sync(s);
 
         return 0;
@@ -1288,7 +1285,7 @@ static int setup_signals(Server *s) {
 
 static int server_parse_proc_cmdline(Server *s) {
         _cleanup_free_ char *line = NULL;
-        char *w, *state;
+        const char *w, *state;
         size_t l;
         int r;
 
@@ -1323,35 +1320,27 @@ static int server_parse_proc_cmdline(Server *s) {
                                 log_warning("Failed to parse forward to console switch %s. Ignoring.", word + 36);
                         else
                                 s->forward_to_console = r;
+                } else if (startswith(word, "systemd.journald.forward_to_wall=")) {
+                        r = parse_boolean(word + 33);
+                        if (r < 0)
+                                log_warning("Failed to parse forward to wall switch %s. Ignoring.", word + 33);
+                        else
+                                s->forward_to_wall = r;
                 } else if (startswith(word, "systemd.journald"))
                         log_warning("Invalid systemd.journald parameter. Ignoring.");
         }
+        /* do not warn about state here, since probably systemd already did */
 
         return 0;
 }
 
 static int server_parse_config_file(Server *s) {
-        static const char fn[] = "/etc/systemd/journald.conf";
-        _cleanup_fclose_ FILE *f = NULL;
-        int r;
-
         assert(s);
 
-        f = fopen(fn, "re");
-        if (!f) {
-                if (errno == ENOENT)
-                        return 0;
-
-                log_warning("Failed to open configuration file %s: %m", fn);
-                return -errno;
-        }
-
-        r = config_parse(NULL, fn, f, "Journal\0", config_item_perf_lookup,
-                         (void*) journald_gperf_lookup, false, false, s);
-        if (r < 0)
-                log_warning("Failed to parse configuration file: %s", strerror(-r));
-
-        return r;
+        return config_parse(NULL, "/etc/systemd/journald.conf", NULL,
+                            "Journal\0",
+                            config_item_perf_lookup, journald_gperf_lookup,
+                            false, false, true, s);
 }
 
 static int server_dispatch_sync(sd_event_source *es, usec_t t, void *userdata) {
@@ -1380,14 +1369,19 @@ int server_schedule_sync(Server *s, int priority) {
         if (s->sync_interval_usec > 0) {
                 usec_t when;
 
-                r = sd_event_get_now_monotonic(s->event, &when);
+                r = sd_event_now(s->event, CLOCK_MONOTONIC, &when);
                 if (r < 0)
                         return r;
 
                 when += s->sync_interval_usec;
 
                 if (!s->sync_event_source) {
-                        r = sd_event_add_monotonic(s->event, &s->sync_event_source, when, 0, server_dispatch_sync, s);
+                        r = sd_event_add_time(
+                                        s->event,
+                                        &s->sync_event_source,
+                                        CLOCK_MONOTONIC,
+                                        when, 0,
+                                        server_dispatch_sync, s);
                         if (r < 0)
                                 return r;
 
@@ -1435,8 +1429,7 @@ static int server_open_hostname(Server *s) {
                 if (r == -EPERM) {
                         log_warning("Failed to register hostname fd in event loop: %s. Ignoring.",
                                         strerror(-r));
-                        close_nointr_nofail(s->hostname_fd);
-                        s->hostname_fd = -1;
+                        s->hostname_fd = safe_close(s->hostname_fd);
                         return 0;
                 }
 
@@ -1469,12 +1462,15 @@ int server_init(Server *s) {
         s->rate_limit_interval = DEFAULT_RATE_LIMIT_INTERVAL;
         s->rate_limit_burst = DEFAULT_RATE_LIMIT_BURST;
 
-        s->forward_to_syslog = true;
+        s->forward_to_wall = true;
+
+        s->max_file_usec = DEFAULT_MAX_FILE_USEC;
 
         s->max_level_store = LOG_DEBUG;
         s->max_level_syslog = LOG_DEBUG;
         s->max_level_kmsg = LOG_NOTICE;
         s->max_level_console = LOG_INFO;
+        s->max_level_wall = LOG_EMERG;
 
         memset(&s->system_metrics, 0xFF, sizeof(s->system_metrics));
         memset(&s->runtime_metrics, 0xFF, sizeof(s->runtime_metrics));
@@ -1532,7 +1528,8 @@ int server_init(Server *s) {
 
                         s->stdout_fd = fd;
 
-                } else if (sd_is_socket_unix(fd, SOCK_DGRAM, -1, "/dev/log", 0) > 0) {
+                } else if (sd_is_socket_unix(fd, SOCK_DGRAM, -1, "/dev/log", 0) > 0 ||
+                           sd_is_socket_unix(fd, SOCK_DGRAM, -1, "/run/systemd/journal/dev-log", 0) > 0) {
 
                         if (s->syslog_fd >= 0) {
                                 log_error("Too many /dev/log sockets passed.");
@@ -1559,9 +1556,11 @@ int server_init(Server *s) {
         if (r < 0)
                 return r;
 
+#ifndef CONFIG_TIZEN_WIP
         r = server_open_dev_kmsg(s);
         if (r < 0)
                 return r;
+#endif
 
         r = server_open_kernel_seqnum(s);
         if (r < 0)
@@ -1644,20 +1643,11 @@ void server_done(Server *s) {
         sd_event_source_unref(s->hostname_event_source);
         sd_event_unref(s->event);
 
-        if (s->syslog_fd >= 0)
-                close_nointr_nofail(s->syslog_fd);
-
-        if (s->native_fd >= 0)
-                close_nointr_nofail(s->native_fd);
-
-        if (s->stdout_fd >= 0)
-                close_nointr_nofail(s->stdout_fd);
-
-        if (s->dev_kmsg_fd >= 0)
-                close_nointr_nofail(s->dev_kmsg_fd);
-
-        if (s->hostname_fd >= 0)
-                close_nointr_nofail(s->hostname_fd);
+        safe_close(s->syslog_fd);
+        safe_close(s->native_fd);
+        safe_close(s->stdout_fd);
+        safe_close(s->dev_kmsg_fd);
+        safe_close(s->hostname_fd);
 
         if (s->rate_limit)
                 journal_rate_limit_free(s->rate_limit);
index 2a81061..42a2235 100644 (file)
@@ -45,8 +45,8 @@ typedef enum Storage {
 } Storage;
 
 typedef enum SplitMode {
-        SPLIT_LOGIN,
         SPLIT_UID,
+        SPLIT_LOGIN,
         SPLIT_NONE,
         _SPLIT_MAX,
         _SPLIT_INVALID = -1
@@ -97,6 +97,7 @@ typedef struct Server {
         bool forward_to_kmsg;
         bool forward_to_syslog;
         bool forward_to_console;
+        bool forward_to_wall;
 
         unsigned n_forward_syslog_missed;
         usec_t last_warn_forward_syslog_missed;
@@ -119,6 +120,7 @@ typedef struct Server {
         int max_level_syslog;
         int max_level_kmsg;
         int max_level_console;
+        int max_level_wall;
 
         Storage storage;
         SplitMode split_mode;
index 36fc755..8a983d8 100644 (file)
@@ -35,6 +35,7 @@
 #include "journald-syslog.h"
 #include "journald-kmsg.h"
 #include "journald-console.h"
+#include "journald-wall.h"
 
 #define STDOUT_STREAMS_MAX 4096
 
@@ -106,6 +107,9 @@ static int stdout_stream_log(StdoutStream *s, const char *p) {
         if (s->forward_to_console || s->server->forward_to_console)
                 server_forward_console(s->server, priority, s->identifier, p, &s->ucred);
 
+        if (s->server->forward_to_wall)
+                server_forward_wall(s->server, priority, s->identifier, p, &s->ucred);
+
         IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=stdout");
 
         syslog_priority[strlen("PRIORITY=")] = '0' + LOG_PRI(priority);
@@ -337,8 +341,7 @@ void stdout_stream_free(StdoutStream *s) {
                 s->event_source = sd_event_source_unref(s->event_source);
         }
 
-        if (s->fd >= 0)
-                close_nointr_nofail(s->fd);
+        safe_close(s->fd);
 
 #ifdef HAVE_SELINUX
         if (s->security_context)
@@ -373,13 +376,13 @@ static int stdout_stream_new(sd_event_source *es, int listen_fd, uint32_t revent
 
         if (s->n_stdout_streams >= STDOUT_STREAMS_MAX) {
                 log_warning("Too many stdout streams, refusing connection.");
-                close_nointr_nofail(fd);
+                safe_close(fd);
                 return 0;
         }
 
         stream = new0(StdoutStream, 1);
         if (!stream) {
-                close_nointr_nofail(fd);
+                safe_close(fd);
                 return log_oom();
         }
 
@@ -447,14 +450,14 @@ int server_open_stdout_socket(Server *s) {
 
                 r = bind(s->stdout_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
                 if (r < 0) {
-                        log_error("bind() failed: %m");
+                        log_error("bind(%s) failed: %m", sa.un.sun_path);
                         return -errno;
                 }
 
                 chmod(sa.un.sun_path, 0666);
 
                 if (listen(s->stdout_fd, SOMAXCONN) < 0) {
-                        log_error("listen() failed: %m");
+                        log_error("listen(%s) failed: %m", sa.un.sun_path);
                         return -errno;
                 }
         } else
index 241f7ed..656dc72 100644 (file)
 #include "journald-syslog.h"
 #include "journald-kmsg.h"
 #include "journald-console.h"
+#include "journald-wall.h"
 
 /* Warn once every 30s if we missed syslog message */
 #define WARN_FORWARD_SYSLOG_MISSED_USEC (30 * USEC_PER_SEC)
 
 static void forward_syslog_iovec(Server *s, const struct iovec *iovec, unsigned n_iovec, struct ucred *ucred, struct timeval *tv) {
 
-        union sockaddr_union sa = {
+        static const union sockaddr_union sa = {
                 .un.sun_family = AF_UNIX,
                 .un.sun_path = "/run/systemd/journal/syslog",
         };
         struct msghdr msghdr = {
                 .msg_iov = (struct iovec *) iovec,
                 .msg_iovlen = n_iovec,
-                .msg_name = &sa,
+                .msg_name = (struct sockaddr*) &sa.sa,
                 .msg_namelen = offsetof(union sockaddr_union, un.sun_path)
-                               + sizeof("/run/systemd/journal/syslog") - 1,
+                               + strlen("/run/systemd/journal/syslog"),
         };
         struct cmsghdr *cmsg;
         union {
@@ -158,7 +159,7 @@ void server_forward_syslog(Server *s, int priority, const char *identifier, cons
                         identifier = ident_buf;
                 }
 
-                snprintf(header_pid, sizeof(header_pid), "[%lu]: ", (unsigned long) ucred->pid);
+                snprintf(header_pid, sizeof(header_pid), "["PID_FMT"]: ", ucred->pid);
                 char_array_0(header_pid);
 
                 if (identifier)
@@ -380,6 +381,9 @@ void server_process_syslog_message(
         if (s->forward_to_console)
                 server_forward_console(s, priority, identifier, buf, ucred);
 
+        if (s->forward_to_wall)
+                server_forward_wall(s, priority, identifier, buf, ucred);
+
         IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=syslog");
 
         if (asprintf(&syslog_priority, "PRIORITY=%i", priority & LOG_PRIMASK) >= 0)
@@ -422,9 +426,9 @@ int server_open_syslog_socket(Server *s) {
         assert(s);
 
         if (s->syslog_fd < 0) {
-                union sockaddr_union sa = {
+                static const union sockaddr_union sa = {
                         .un.sun_family = AF_UNIX,
-                        .un.sun_path = "/dev/log",
+                        .un.sun_path = "/run/systemd/journal/dev-log",
                 };
 
                 s->syslog_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
@@ -437,7 +441,7 @@ int server_open_syslog_socket(Server *s) {
 
                 r = bind(s->syslog_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
                 if (r < 0) {
-                        log_error("bind() failed: %m");
+                        log_error("bind(%s) failed: %m", sa.un.sun_path);
                         return -errno;
                 }
 
diff --git a/src/journal/journald-wall.c b/src/journal/journald-wall.c
new file mode 100644 (file)
index 0000000..fcbd918
--- /dev/null
@@ -0,0 +1,69 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Sebastian Thorarensen
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "utmp-wtmp.h"
+#include "journald-server.h"
+#include "journald-wall.h"
+
+void server_forward_wall(
+                Server *s,
+                int priority,
+                const char *identifier,
+                const char *message,
+                struct ucred *ucred) {
+
+        _cleanup_free_ char *ident_buf = NULL, *l_buf = NULL;
+        const char *l;
+        int r;
+
+        assert(s);
+        assert(message);
+
+        if (LOG_PRI(priority) > s->max_level_wall)
+                return;
+
+        if (ucred) {
+                if (!identifier) {
+                        get_process_comm(ucred->pid, &ident_buf);
+                        identifier = ident_buf;
+                }
+
+                if (asprintf(&l_buf, "%s["PID_FMT"]: %s", strempty(identifier), ucred->pid, message) < 0) {
+                        log_oom();
+                        return;
+                }
+
+                l = l_buf;
+
+        } else if (identifier) {
+
+                l = l_buf = strjoin(identifier, ": ", message, NULL);
+                if (!l_buf) {
+                        log_oom();
+                        return;
+                }
+        } else
+                l = message;
+
+        r = utmp_wall(l, "systemd-journald", NULL);
+        if (r < 0)
+                log_debug("Failed to send wall message: %s", strerror(-r));
+}
diff --git a/src/journal/journald-wall.h b/src/journal/journald-wall.h
new file mode 100644 (file)
index 0000000..93c3cec
--- /dev/null
@@ -0,0 +1,26 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Sebastian Thorarensen
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "journald-server.h"
+
+void server_forward_wall(Server *s, int priority, const char *identifier, const char *message, struct ucred *ucred);
index 37896d0..b1a0e25 100644 (file)
@@ -24,9 +24,9 @@
 #include <errno.h>
 #include <unistd.h>
 
-#include <systemd/sd-journal.h>
-#include <systemd/sd-messages.h>
-#include <systemd/sd-daemon.h>
+#include "systemd/sd-journal.h"
+#include "systemd/sd-messages.h"
+#include "systemd/sd-daemon.h"
 
 #include "journal-authenticate.h"
 #include "journald-server.h"
@@ -37,11 +37,6 @@ int main(int argc, char *argv[]) {
         Server server;
         int r;
 
-        /* if (getppid() != 1) { */
-        /*         log_error("This program should be invoked by init only."); */
-        /*         return EXIT_FAILURE; */
-        /* } */
-
         if (argc > 1) {
                 log_error("This program does not take arguments.");
                 return EXIT_FAILURE;
@@ -62,7 +57,7 @@ int main(int argc, char *argv[]) {
         server_flush_to_var(&server);
         server_flush_dev_kmsg(&server);
 
-        log_debug("systemd-journald running as pid %lu", (unsigned long) getpid());
+        log_debug("systemd-journald running as pid "PID_FMT, getpid());
         server_driver_message(&server, SD_MESSAGE_JOURNAL_START, "Journal started");
 
         sd_notify(false,
@@ -70,7 +65,7 @@ int main(int argc, char *argv[]) {
                   "STATUS=Processing requests...");
 
         for (;;) {
-                usec_t t = (usec_t) -1, n;
+                usec_t t = USEC_INFINITY, n;
 
                 r = sd_event_get_state(server.event);
                 if (r < 0)
@@ -110,7 +105,6 @@ int main(int argc, char *argv[]) {
                 r = sd_event_run(server.event, t);
                 if (r < 0) {
                         log_error("Failed to run event loop: %s", strerror(-r));
-                        r = -errno;
                         goto finish;
                 }
 
@@ -118,7 +112,7 @@ int main(int argc, char *argv[]) {
                 server_maybe_warn_forward_syslog_missed(&server);
         }
 
-        log_debug("systemd-journald stopped as pid %lu", (unsigned long) getpid());
+        log_debug("systemd-journald stopped as pid "PID_FMT, getpid());
         server_driver_message(&server, SD_MESSAGE_JOURNAL_STOP, "Journal stopped");
 
 finish:
index 54f6833..2073f1b 100644 (file)
@@ -11,7 +11,7 @@
 #Storage=auto
 #Compress=yes
 #Seal=yes
-#SplitMode=login
+#SplitMode=uid
 #SyncIntervalSec=5m
 #RateLimitInterval=30s
 #RateLimitBurst=1000
 #RuntimeMaxFileSize=
 #MaxRetentionSec=
 #MaxFileSec=1month
-#ForwardToSyslog=yes
+#ForwardToSyslog=no
 #ForwardToKMsg=no
 #ForwardToConsole=no
+#ForwardToWall=yes
 #TTYPath=/dev/console
 #MaxLevelStore=debug
 #MaxLevelSyslog=debug
 #MaxLevelKMsg=notice
 #MaxLevelConsole=info
+#MaxLevelWall=emerg
index 3740a9a..b9ec902 100644 (file)
@@ -51,6 +51,8 @@
 
 #define DEFAULT_DATA_THRESHOLD (64*1024)
 
+static void remove_file_real(sd_journal *j, JournalFile *f);
+
 static bool journal_pid_changed(sd_journal *j) {
         assert(j);
 
@@ -885,6 +887,7 @@ static int real_journal_next(sd_journal *j, direction_t direction) {
                 r = next_beyond_location(j, f, direction, &o, &p);
                 if (r < 0) {
                         log_debug("Can't iterate through %s, ignoring: %s", f->path, strerror(-r));
+                        remove_file_real(j, f);
                         continue;
                 } else if (r == 0)
                         continue;
@@ -994,7 +997,7 @@ _public_ int sd_journal_get_cursor(sd_journal *j, char **cursor) {
 }
 
 _public_ int sd_journal_seek_cursor(sd_journal *j, const char *cursor) {
-        char *w, *state;
+        const char *word, *state;
         size_t l;
         unsigned long long seqnum, monotonic, realtime, xor_hash;
         bool
@@ -1010,18 +1013,18 @@ _public_ int sd_journal_seek_cursor(sd_journal *j, const char *cursor) {
         assert_return(!journal_pid_changed(j), -ECHILD);
         assert_return(!isempty(cursor), -EINVAL);
 
-        FOREACH_WORD_SEPARATOR(w, l, cursor, ";", state) {
+        FOREACH_WORD_SEPARATOR(word, l, cursor, ";", state) {
                 char *item;
                 int k = 0;
 
-                if (l < 2 || w[1] != '=')
+                if (l < 2 || word[1] != '=')
                         return -EINVAL;
 
-                item = strndup(w, l);
+                item = strndup(word, l);
                 if (!item)
                         return -ENOMEM;
 
-                switch (w[0]) {
+                switch (word[0]) {
 
                 case 's':
                         seqnum_id_set = true;
@@ -1100,7 +1103,7 @@ _public_ int sd_journal_seek_cursor(sd_journal *j, const char *cursor) {
 
 _public_ int sd_journal_test_cursor(sd_journal *j, const char *cursor) {
         int r;
-        char *w, *state;
+        const char *word, *state;
         size_t l;
         Object *o;
 
@@ -1115,20 +1118,20 @@ _public_ int sd_journal_test_cursor(sd_journal *j, const char *cursor) {
         if (r < 0)
                 return r;
 
-        FOREACH_WORD_SEPARATOR(w, l, cursor, ";", state) {
+        FOREACH_WORD_SEPARATOR(word, l, cursor, ";", state) {
                 _cleanup_free_ char *item = NULL;
                 sd_id128_t id;
                 unsigned long long ll;
                 int k = 0;
 
-                if (l < 2 || w[1] != '=')
+                if (l < 2 || word[1] != '=')
                         return -EINVAL;
 
-                item = strndup(w, l);
+                item = strndup(word, l);
                 if (!item)
                         return -ENOMEM;
 
-                switch (w[0]) {
+                switch (word[0]) {
 
                 case 's':
                         k = sd_id128_from_string(item+2, &id);
@@ -1270,7 +1273,7 @@ static bool file_type_wanted(int flags, const char *filename) {
         if (flags & SD_JOURNAL_CURRENT_USER) {
                 char prefix[5 + DECIMAL_STR_MAX(uid_t) + 1];
 
-                assert_se(snprintf(prefix, sizeof(prefix), "user-%lu", (unsigned long) getuid())
+                assert_se(snprintf(prefix, sizeof(prefix), "user-"UID_FMT, getuid())
                           < (int) sizeof(prefix));
 
                 if (file_has_type_prefix(prefix, filename))
@@ -1339,7 +1342,7 @@ static int add_file(sd_journal *j, const char *prefix, const char *filename) {
 }
 
 static int remove_file(sd_journal *j, const char *prefix, const char *filename) {
-        char *path;
+        _cleanup_free_ char *path;
         JournalFile *f;
 
         assert(j);
@@ -1351,10 +1354,17 @@ static int remove_file(sd_journal *j, const char *prefix, const char *filename)
                 return -ENOMEM;
 
         f = hashmap_get(j->files, path);
-        free(path);
         if (!f)
                 return 0;
 
+        remove_file_real(j, f);
+        return 0;
+}
+
+static void remove_file_real(sd_journal *j, JournalFile *f) {
+        assert(j);
+        assert(f);
+
         hashmap_remove(j->files, f->path);
 
         log_debug("File %s removed.", f->path);
@@ -1372,8 +1382,6 @@ static int remove_file(sd_journal *j, const char *prefix, const char *filename)
         journal_file_close(f);
 
         j->current_invalidate_counter ++;
-
-        return 0;
 }
 
 static int add_directory(sd_journal *j, const char *prefix, const char *dirname) {
@@ -1447,8 +1455,7 @@ static int add_directory(sd_journal *j, const char *prefix, const char *dirname)
                 de = readdir(d);
                 if (!de && errno != 0) {
                         r = -errno;
-                        log_debug("Failed to read directory %s: %s",
-                                  m->path, strerror(errno));
+                        log_debug("Failed to read directory %s: %m", m->path);
                         return r;
                 }
                 if (!de)
@@ -1538,8 +1545,7 @@ static int add_root_directory(sd_journal *j, const char *p) {
                 de = readdir(d);
                 if (!de && errno != 0) {
                         r = -errno;
-                        log_debug("Failed to read directory %s: %s",
-                                  m->path, strerror(errno));
+                        log_debug("Failed to read directory %s: %m", m->path);
                         return r;
                 }
                 if (!de)
@@ -1842,8 +1848,7 @@ _public_ void sd_journal_close(sd_journal *j) {
         hashmap_free(j->directories_by_path);
         hashmap_free(j->directories_by_wd);
 
-        if (j->inotify_fd >= 0)
-                close_nointr_nofail(j->inotify_fd);
+        safe_close(j->inotify_fd);
 
         if (j->mmap) {
                 log_debug("mmap cache statistics: %u hit, %u miss", mmap_cache_get_hit(j->mmap), mmap_cache_get_missed(j->mmap));
@@ -1978,6 +1983,7 @@ _public_ int sd_journal_get_data(sd_journal *j, const char *field, const void **
                 uint64_t p, l;
                 le64_t le_hash;
                 size_t t;
+                int compression;
 
                 p = le64toh(o->entry.items[i].object_offset);
                 le_hash = o->entry.items[i].hash;
@@ -1990,19 +1996,22 @@ _public_ int sd_journal_get_data(sd_journal *j, const char *field, const void **
 
                 l = le64toh(o->object.size) - offsetof(Object, data.payload);
 
-                if (o->object.flags & OBJECT_COMPRESSED) {
-
-#ifdef HAVE_XZ
-                        if (uncompress_startswith(o->data.payload, l,
+                compression = o->object.flags & OBJECT_COMPRESSION_MASK;
+                if (compression) {
+#if defined(HAVE_XZ) || defined(HAVE_LZ4)
+                        if (decompress_startswith(compression,
+                                                  o->data.payload, l,
                                                   &f->compress_buffer, &f->compress_buffer_size,
                                                   field, field_length, '=')) {
 
-                                uint64_t rsize;
+                                size_t rsize;
 
-                                if (!uncompress_blob(o->data.payload, l,
-                                                     &f->compress_buffer, &f->compress_buffer_size, &rsize,
-                                                     j->data_threshold))
-                                        return -EBADMSG;
+                                r = decompress_blob(compression,
+                                                    o->data.payload, l,
+                                                    &f->compress_buffer, &f->compress_buffer_size, &rsize,
+                                                    j->data_threshold);
+                                if (r < 0)
+                                        return r;
 
                                 *data = f->compress_buffer;
                                 *size = (size_t) rsize;
@@ -2012,7 +2021,6 @@ _public_ int sd_journal_get_data(sd_journal *j, const char *field, const void **
 #else
                         return -EPROTONOSUPPORT;
 #endif
-
                 } else if (l >= field_length+1 &&
                            memcmp(o->data.payload, field, field_length) == 0 &&
                            o->data.payload[field_length] == '=') {
@@ -2039,6 +2047,7 @@ _public_ int sd_journal_get_data(sd_journal *j, const char *field, const void **
 static int return_data(sd_journal *j, JournalFile *f, Object *o, const void **data, size_t *size) {
         size_t t;
         uint64_t l;
+        int compression;
 
         l = le64toh(o->object.size) - offsetof(Object, data.payload);
         t = (size_t) l;
@@ -2047,12 +2056,17 @@ static int return_data(sd_journal *j, JournalFile *f, Object *o, const void **da
         if ((uint64_t) t != l)
                 return -E2BIG;
 
-        if (o->object.flags & OBJECT_COMPRESSED) {
-#ifdef HAVE_XZ
-                uint64_t rsize;
+        compression = o->object.flags & OBJECT_COMPRESSION_MASK;
+        if (compression) {
+#if defined(HAVE_XZ) || defined(HAVE_LZ4)
+                size_t rsize;
+                int r;
 
-                if (!uncompress_blob(o->data.payload, l, &f->compress_buffer, &f->compress_buffer_size, &rsize, j->data_threshold))
-                        return -EBADMSG;
+                r = decompress_blob(compression,
+                                    o->data.payload, l, &f->compress_buffer,
+                                    &f->compress_buffer_size, &rsize, j->data_threshold);
+                if (r < 0)
+                        return r;
 
                 *data = f->compress_buffer;
                 *size = (size_t) rsize;
@@ -2293,8 +2307,6 @@ _public_ int sd_journal_process(sd_journal *j) {
                         l -= step;
                 }
         }
-
-        return determine_change(j);
 }
 
 _public_ int sd_journal_wait(sd_journal *j, uint64_t timeout_usec) {
@@ -2387,7 +2399,7 @@ _public_ int sd_journal_get_cutoff_realtime_usec(sd_journal *j, uint64_t *from,
 _public_ int sd_journal_get_cutoff_monotonic_usec(sd_journal *j, sd_id128_t boot_id, uint64_t *from, uint64_t *to) {
         Iterator i;
         JournalFile *f;
-        bool first = true;
+        bool found = false;
         int r;
 
         assert_return(j, -EINVAL);
@@ -2406,21 +2418,21 @@ _public_ int sd_journal_get_cutoff_monotonic_usec(sd_journal *j, sd_id128_t boot
                 if (r == 0)
                         continue;
 
-                if (first) {
+                if (found) {
                         if (from)
-                                *from = fr;
+                                *from = MIN(fr, *from);
                         if (to)
-                                *to = t;
-                        first = false;
+                                *to = MAX(t, *to);
                 } else {
                         if (from)
-                                *from = MIN(fr, *from);
+                                *from = fr;
                         if (to)
-                                *to = MAX(t, *to);
+                                *to = t;
+                        found = true;
                 }
         }
 
-        return first ? 0 : 1;
+        return found;
 }
 
 void journal_print_header(sd_journal *j) {
diff --git a/src/journal/stacktrace.c b/src/journal/stacktrace.c
new file mode 100644 (file)
index 0000000..6b9d272
--- /dev/null
@@ -0,0 +1,200 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <dwarf.h>
+#include <elfutils/libdwfl.h>
+
+#include "util.h"
+#include "macro.h"
+#include "stacktrace.h"
+
+#define FRAMES_MAX 64
+#define THREADS_MAX 64
+
+struct stack_context {
+        FILE *f;
+        Dwfl *dwfl;
+        Elf *elf;
+        unsigned n_thread;
+        unsigned n_frame;
+};
+
+static int frame_callback(Dwfl_Frame *frame, void *userdata) {
+        struct stack_context *c = userdata;
+        Dwarf_Addr pc, pc_adjusted, bias = 0;
+        _cleanup_free_ Dwarf_Die *scopes = NULL;
+        const char *fname = NULL, *symbol = NULL;
+        Dwfl_Module *module;
+        bool is_activation;
+
+        assert(frame);
+        assert(c);
+
+        if (c->n_frame >= FRAMES_MAX)
+                return DWARF_CB_ABORT;
+
+        if (!dwfl_frame_pc(frame, &pc, &is_activation))
+                return DWARF_CB_ABORT;
+
+        pc_adjusted = pc - (is_activation ? 0 : 1);
+
+        module = dwfl_addrmodule(c->dwfl, pc_adjusted);
+        if (module) {
+                Dwarf_Die *s, *cudie;
+                int n;
+
+                cudie = dwfl_module_addrdie(module, pc_adjusted, &bias);
+                if (cudie) {
+                        n = dwarf_getscopes(cudie, pc_adjusted - bias, &scopes);
+                        for (s = scopes; s < scopes + n; s++) {
+                                if (IN_SET(dwarf_tag(s), DW_TAG_subprogram, DW_TAG_inlined_subroutine, DW_TAG_entry_point)) {
+                                        Dwarf_Attribute *a, space;
+
+                                        a = dwarf_attr_integrate(s, DW_AT_MIPS_linkage_name, &space);
+                                        if (!a)
+                                                a = dwarf_attr_integrate(s, DW_AT_linkage_name, &space);
+                                        if (a)
+                                                symbol = dwarf_formstring(a);
+                                        if (!symbol)
+                                                symbol = dwarf_diename(s);
+
+                                        if (symbol)
+                                                break;
+                                }
+                        }
+                }
+
+                if (!symbol)
+                        symbol = dwfl_module_addrname(module, pc_adjusted);
+
+                fname = dwfl_module_info(module, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+        }
+
+        fprintf(c->f, "#%-2u 0x%016" PRIx64 " %s (%s)\n", c->n_frame, (uint64_t) pc, strna(symbol), strna(fname));
+        c->n_frame ++;
+
+        return DWARF_CB_OK;
+}
+
+static int thread_callback(Dwfl_Thread *thread, void *userdata) {
+        struct stack_context *c = userdata;
+        pid_t tid;
+
+        assert(thread);
+        assert(c);
+
+        if (c->n_thread >= THREADS_MAX)
+                return DWARF_CB_ABORT;
+
+        if (c->n_thread != 0)
+                fputc('\n', c->f);
+
+        c->n_frame = 0;
+
+        tid = dwfl_thread_tid(thread);
+        fprintf(c->f, "Stack trace of thread " PID_FMT ":\n", tid);
+
+        if (dwfl_thread_getframes(thread, frame_callback, c) < 0)
+                return DWARF_CB_ABORT;
+
+        c->n_thread ++;
+
+        return DWARF_CB_OK;
+}
+
+int coredump_make_stack_trace(int fd, const char *executable, char **ret) {
+
+        static const Dwfl_Callbacks callbacks = {
+                .find_elf = dwfl_build_id_find_elf,
+                .find_debuginfo = dwfl_standard_find_debuginfo,
+        };
+
+        struct stack_context c = {};
+        char *buf = NULL;
+        size_t sz = 0;
+        int r;
+
+        assert(fd >= 0);
+        assert(ret);
+
+        if (lseek(fd, 0, SEEK_SET) == (off_t) -1)
+                return -errno;
+
+        c.f = open_memstream(&buf, &sz);
+        if (!c.f)
+                return -ENOMEM;
+
+        elf_version(EV_CURRENT);
+
+        c.elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
+        if (!c.elf) {
+                r = -EINVAL;
+                goto finish;
+        }
+
+        c.dwfl = dwfl_begin(&callbacks);
+        if (!c.dwfl) {
+                r = -EINVAL;
+                goto finish;
+        }
+
+        if (dwfl_core_file_report(c.dwfl, c.elf, executable) < 0) {
+                r = -EINVAL;
+                goto finish;
+        }
+
+        if (dwfl_report_end(c.dwfl, NULL, NULL) != 0) {
+                r = -EINVAL;
+                goto finish;
+        }
+
+        if (dwfl_core_file_attach(c.dwfl, c.elf) < 0) {
+                r = -EINVAL;
+                goto finish;
+        }
+
+        if (dwfl_getthreads(c.dwfl, thread_callback, &c) < 0) {
+                r = -EINVAL;
+                goto finish;
+        }
+
+        fclose(c.f);
+        c.f = NULL;
+
+        *ret = buf;
+        buf = NULL;
+
+        r = 0;
+
+finish:
+        if (c.dwfl)
+                dwfl_end(c.dwfl);
+
+        if (c.elf)
+                elf_end(c.elf);
+
+        if (c.f)
+                fclose(c.f);
+
+        free(buf);
+
+        return r;
+}
diff --git a/src/journal/stacktrace.h b/src/journal/stacktrace.h
new file mode 100644 (file)
index 0000000..189e5c4
--- /dev/null
@@ -0,0 +1,24 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+int coredump_make_stack_trace(int fd, const char *executable, char **ret);
index b087a8b..967ab67 100644 (file)
@@ -157,7 +157,8 @@ int main(int argc, char *argv[]) {
 
         setlocale(LC_ALL, "de_DE.UTF-8");
 
-        log_set_max_level(LOG_DEBUG);
+        log_parse_environment();
+        log_open();
 
         test_catalog_file_lang();
 
diff --git a/src/journal/test-compress-benchmark.c b/src/journal/test-compress-benchmark.c
new file mode 100644 (file)
index 0000000..8975e29
--- /dev/null
@@ -0,0 +1,113 @@
+/***
+  This file is part of systemd
+
+  Copyright 2014 Zbigniew Jędrzejewski-Szmek
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "compress.h"
+#include "util.h"
+#include "macro.h"
+
+typedef int (compress_t)(const void *src, uint64_t src_size, void *dst, size_t *dst_size);
+typedef int (decompress_t)(const void *src, uint64_t src_size,
+                           void **dst, size_t *dst_alloc_size, size_t* dst_size, size_t dst_max);
+
+#define MAX_SIZE (1024*1024LU)
+
+static char* make_buf(size_t count) {
+        char *buf;
+        size_t i;
+
+        buf = malloc(count);
+        assert(buf);
+
+        for (i = 0; i < count; i++)
+                buf[i] = 'a' + i % ('z' - 'a' + 1);
+
+        return buf;
+}
+
+static void test_compress_decompress(const char* label,
+                                     compress_t compress, decompress_t decompress) {
+        usec_t n, n2 = 0;
+        float dt;
+
+        _cleanup_free_ char *text, *buf;
+        _cleanup_free_ void *buf2 = NULL;
+        size_t buf2_allocated = 0;
+        size_t skipped = 0, compressed = 0, total = 0;
+
+        text = make_buf(MAX_SIZE);
+        buf = calloc(MAX_SIZE + 1, 1);
+        assert(text && buf);
+
+        n = now(CLOCK_MONOTONIC);
+
+        for (size_t i = 1; i <= MAX_SIZE; i += (i < 2048 ? 1 : 217)) {
+                size_t j = 0, k = 0;
+                int r;
+
+                r = compress(text, i, buf, &j);
+                /* assume compresion must be succesful except for small inputs */
+                assert(r == 0 || (i < 2048 && r == -ENOBUFS));
+                /* check for overwrites */
+                assert(buf[i] == 0);
+                if (r != 0) {
+                        skipped += i;
+                        continue;
+                }
+
+                assert(j > 0);
+                if (j >= i)
+                        log_error("%s \"compressed\" %zu -> %zu", label, i, j);
+
+                r = decompress(buf, j, &buf2, &buf2_allocated, &k, 0);
+                assert(r == 0);
+                assert(buf2_allocated >= k);
+                assert(k == i);
+
+                assert(memcmp(text, buf2, i) == 0);
+
+                total += i;
+                compressed += j;
+
+                n2 = now(CLOCK_MONOTONIC);
+                if (n2 - n > 60 * USEC_PER_SEC)
+                        break;
+        }
+
+        dt = (n2-n) / 1e6;
+
+        log_info("%s: compressed & decompressed %zu bytes in %.2fs (%.2fMiB/s), "
+                 "mean compresion %.2f%%, skipped %zu bytes",
+                 label, total, dt,
+                 total / 1024. / 1024 / dt,
+                 100 - compressed * 100. / total,
+                 skipped);
+}
+
+int main(int argc, char *argv[]) {
+
+        log_set_max_level(LOG_DEBUG);
+
+#ifdef HAVE_XZ
+        test_compress_decompress("XZ", compress_blob_xz, decompress_blob_xz);
+#endif
+#ifdef HAVE_LZ4
+        test_compress_decompress("LZ4", compress_blob_lz4, decompress_blob_lz4);
+#endif
+        return 0;
+}
diff --git a/src/journal/test-compress.c b/src/journal/test-compress.c
new file mode 100644 (file)
index 0000000..f5f5f8d
--- /dev/null
@@ -0,0 +1,207 @@
+/***
+  This file is part of systemd
+
+  Copyright 2014 Ronny Chevalier
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "compress.h"
+#include "util.h"
+#include "macro.h"
+
+#ifdef HAVE_XZ
+# define XZ_OK 0
+#else
+# define XZ_OK -EPROTONOSUPPORT
+#endif
+
+#ifdef HAVE_LZ4
+# define LZ4_OK 0
+#else
+# define LZ4_OK -EPROTONOSUPPORT
+#endif
+
+typedef int (compress_blob_t)(const void *src, uint64_t src_size,
+                              void *dst, size_t *dst_size);
+typedef int (decompress_blob_t)(const void *src, uint64_t src_size,
+                                void **dst, size_t *dst_alloc_size,
+                                size_t* dst_size, size_t dst_max);
+typedef int (decompress_sw_t)(const void *src, uint64_t src_size,
+                              void **buffer, size_t *buffer_size,
+                              const void *prefix, size_t prefix_len,
+                              uint8_t extra);
+
+typedef int (compress_stream_t)(int fdf, int fdt, off_t max_bytes);
+typedef int (decompress_stream_t)(int fdf, int fdt, off_t max_size);
+
+static void test_compress_decompress(int compression,
+                                     compress_blob_t compress,
+                                     decompress_blob_t decompress) {
+        char text[] = "foofoofoofoo AAAA aaaaaaaaa ghost busters barbarbar FFF"
+                      "foofoofoofoo AAAA aaaaaaaaa ghost busters barbarbar FFF";
+        char compressed[512];
+        size_t csize = 512;
+        size_t usize = 0;
+        _cleanup_free_ char *decompressed = NULL;
+        int r;
+
+        log_info("/* testing %s blob compression/decompression */",
+                 object_compressed_to_string(compression));
+
+        r = compress(text, sizeof(text), compressed, &csize);
+        assert(r == 0);
+        r = decompress(compressed, csize,
+                       (void **) &decompressed, &usize, &csize, 0);
+        assert(r == 0);
+        assert_se(decompressed);
+        assert_se(streq(decompressed, text));
+
+        r = decompress("garbage", 7,
+                       (void **) &decompressed, &usize, &csize, 0);
+        assert(r < 0);
+
+        /* make sure to have the minimal lz4 compressed size */
+        r = decompress("00000000\1g", 9,
+                       (void **) &decompressed, &usize, &csize, 0);
+        assert(r < 0);
+
+        r = decompress("\100000000g", 9,
+                       (void **) &decompressed, &usize, &csize, 0);
+        assert(r < 0);
+
+        memzero(decompressed, usize);
+}
+
+static void test_decompress_startswith(int compression,
+                                       compress_blob_t compress,
+                                       decompress_sw_t decompress_sw) {
+
+        char text[] = "foofoofoofoo AAAA aaaaaaaaa ghost busters barbarbar FFF"
+                      "foofoofoofoo AAAA aaaaaaaaa ghost busters barbarbar FFF";
+        char compressed[512];
+        size_t csize = 512;
+        size_t usize = 0;
+        _cleanup_free_ char *decompressed = NULL;
+
+        log_info("/* testing decompress_startswith with %s */",
+                 object_compressed_to_string(compression));
+
+        assert_se(compress(text, sizeof(text), compressed, &csize) == 0);
+        assert_se(decompress_sw(compressed,
+                                csize,
+                                (void **) &decompressed,
+                                &usize,
+                                "foofoofoofoo", 12, ' ') > 0);
+        assert_se(decompress_sw(compressed,
+                                csize,
+                                (void **) &decompressed,
+                                &usize,
+                                "foofoofoofoo", 12, 'w') == 0);
+        assert_se(decompress_sw(compressed,
+                                csize,
+                                (void **) &decompressed,
+                                &usize,
+                                "barbarbar", 9, ' ') == 0);
+        assert_se(decompress_sw(compressed,
+                                csize,
+                                (void **) &decompressed,
+                                &usize,
+                                "foofoofoofoo", 12, ' ') > 0);
+}
+
+static void test_compress_stream(int compression,
+                                 const char* cat,
+                                 compress_stream_t compress,
+                                 decompress_stream_t decompress,
+                                 const char *srcfile) {
+
+        _cleanup_close_ int src = -1, dst = -1, dst2 = -1;
+        char pattern[] = "/tmp/systemd-test.xz.XXXXXX",
+             pattern2[] = "/tmp/systemd-test.xz.XXXXXX";
+        int r;
+        _cleanup_free_ char *cmd = NULL, *cmd2;
+        struct stat st = {};
+
+        log_debug("/* testing %s compression */",
+                  object_compressed_to_string(compression));
+
+        log_debug("/* create source from %s */", srcfile);
+
+        assert_se((src = open(srcfile, O_RDONLY|O_CLOEXEC)) >= 0);
+
+        log_debug("/* test compression */");
+
+        assert_se((dst = mkostemp_safe(pattern, O_RDWR|O_CLOEXEC)) >= 0);
+
+        assert(compress(src, dst, -1) == 0);
+
+        if (cat) {
+                assert_se(asprintf(&cmd, "%s %s | diff %s -", cat, pattern, srcfile) > 0);
+                assert(system(cmd) == 0);
+        }
+
+        log_debug("/* test decompression */");
+
+        assert_se((dst2 = mkostemp_safe(pattern2, O_RDWR|O_CLOEXEC)) >= 0);
+
+        assert_se(stat(srcfile, &st) == 0);
+
+        assert_se(lseek(dst, 0, SEEK_SET) == 0);
+        r = decompress(dst, dst2, st.st_size);
+        assert(r == 0);
+
+        assert_se(asprintf(&cmd2, "diff %s %s", srcfile, pattern2) > 0);
+        assert_se(system(cmd2) == 0);
+
+        log_debug("/* test faulty decompression */");
+
+        assert_se(lseek(dst, 1, SEEK_SET) == 1);
+        r = decompress(dst, dst2, st.st_size);
+        assert(r == -EBADMSG);
+
+        assert_se(lseek(dst, 0, SEEK_SET) == 0);
+        assert_se(lseek(dst2, 0, SEEK_SET) == 0);
+        r = decompress(dst, dst2, st.st_size - 1);
+        assert(r == -EFBIG);
+
+        assert_se(unlink(pattern) == 0);
+        assert_se(unlink(pattern2) == 0);
+}
+
+int main(int argc, char *argv[]) {
+
+        log_set_max_level(LOG_DEBUG);
+
+#ifdef HAVE_XZ
+        test_compress_decompress(OBJECT_COMPRESSED_XZ, compress_blob_xz, decompress_blob_xz);
+        test_decompress_startswith(OBJECT_COMPRESSED_XZ, compress_blob_xz, decompress_startswith_xz);
+        test_compress_stream(OBJECT_COMPRESSED_XZ, "xzcat",
+                             compress_stream_xz, decompress_stream_xz, argv[0]);
+#else
+        log_info("/* XZ test skipped */");
+#endif
+#ifdef HAVE_LZ4
+        test_compress_decompress(OBJECT_COMPRESSED_LZ4, compress_blob_lz4, decompress_blob_lz4);
+        test_decompress_startswith(OBJECT_COMPRESSED_LZ4, compress_blob_lz4, decompress_startswith_lz4);
+
+        /* Produced stream is not compatible with lz4 binary, skip lz4cat check. */
+        test_compress_stream(OBJECT_COMPRESSED_LZ4, NULL,
+                             compress_stream_lz4, decompress_stream_lz4, argv[0]);
+#else
+        log_info("/* LZ4 test skipped */");
+#endif
+
+        return 0;
+}
diff --git a/src/journal/test-coredump-vacuum.c b/src/journal/test-coredump-vacuum.c
new file mode 100644 (file)
index 0000000..a4dd001
--- /dev/null
@@ -0,0 +1,32 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2012 Zbigniew Jędrzejewski-Szmek
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdlib.h>
+
+#include "coredump-vacuum.h"
+
+int main(int argc, char *argv[]) {
+
+        if (coredump_vacuum(-1, (off_t) -1, 70 * 1024) < 0)
+                return EXIT_FAILURE;
+
+        return EXIT_SUCCESS;
+}
index e61e87a..0ca24e0 100644 (file)
 
 int main(int argc, char *argv[]) {
 
-        char fn[sizeof("/var/tmp/test-journal-flush-")-1 + DECIMAL_STR_MAX(pid_t) + sizeof(".journal")];
+        char dn[] = "/var/tmp/test-journal-flush.XXXXXX", *fn;
         JournalFile *new_journal = NULL;
         sd_journal *j = NULL;
         unsigned n = 0;
         int r;
 
-        sprintf(fn, "/var/tmp/test-journal-flush-%lu.journal", (unsigned long) getpid());
+        assert_se(mkdtemp(dn));
+        fn = strappend(dn, "/test.journal");
 
         r = journal_file_open(fn, O_CREAT|O_RDWR, 0644, false, false, NULL, NULL, NULL, &new_journal);
         assert_se(r >= 0);
@@ -67,5 +68,7 @@ int main(int argc, char *argv[]) {
 
         journal_file_close(new_journal);
 
+        assert_se(rmdir(dn) == 0);
+
         return 0;
 }
index 58f260d..ada2f6c 100644 (file)
@@ -19,7 +19,7 @@
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
-#include <systemd/sd-journal.h>
+#include "systemd/sd-journal.h"
 
 #include "log.h"
 #include "util.h"
index 5c96044..6c5995e 100644 (file)
@@ -23,7 +23,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 
-#include <systemd/sd-journal.h>
+#include "systemd/sd-journal.h"
 
 #include "journal-file.h"
 #include "journal-internal.h"
index 37bffc1..a318705 100644 (file)
@@ -21,7 +21,7 @@
 
 #include <stdio.h>
 
-#include <systemd/sd-journal.h>
+#include "systemd/sd-journal.h"
 
 #include "journal-internal.h"
 #include "util.h"
index 3e986ed..81ca47e 100644 (file)
@@ -19,7 +19,7 @@
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
-#include <systemd/sd-journal.h>
+#include "systemd/sd-journal.h"
 #include <stdlib.h>
 #include <unistd.h>
 
@@ -72,7 +72,7 @@ int main(int argc, char *argv[]) {
                         "N_CPUS=%li", sysconf(_SC_NPROCESSORS_ONLN),
                         NULL);
 
-        sleep(10);
+        sleep(1);
 
         return 0;
 }
index 8e1d08d..8ccd813 100644 (file)
@@ -22,7 +22,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 
-#include <systemd/sd-journal.h>
+#include "systemd/sd-journal.h"
 
 #include "journal-file.h"
 #include "journal-internal.h"
index 0540074..3b181c6 100644 (file)
@@ -48,7 +48,7 @@ static void bit_toggle(const char *fn, uint64_t p) {
         r = pwrite(fd, &b, 1, p/8);
         assert(r == 1);
 
-        close_nointr_nofail(fd);
+        safe_close(fd);
 }
 
 static int raw_verify(const char *fn, const char *verification_key) {
index 85b4cf7..6025d04 100644 (file)
@@ -22,7 +22,7 @@
 #include <fcntl.h>
 #include <unistd.h>
 
-#include <systemd/sd-journal.h>
+#include "systemd/sd-journal.h"
 
 #include "log.h"
 #include "journal-file.h"
index 7d03bfe..b7bb260 100644 (file)
@@ -72,9 +72,9 @@ int main(int argc, char *argv[]) {
 
         mmap_cache_unref(m);
 
-        close_nointr_nofail(x);
-        close_nointr_nofail(y);
-        close_nointr_nofail(z);
+        safe_close(x);
+        safe_close(y);
+        safe_close(z);
 
         return 0;
 }
index a6a8abc..6f032b5 100644 (file)
@@ -32,6 +32,8 @@ fi
 
 if [[ -f /etc/os-release ]]; then
     . /etc/os-release
+elif [[ -f /usr/lib/os-release ]]; then
+    . /usr/lib/os-release
 fi
 
 if ! [[ $PRETTY_NAME ]]; then
@@ -45,11 +47,10 @@ if [[ -f /etc/kernel/cmdline ]]; then
 fi
 
 if ! [[ ${BOOT_OPTIONS[*]} ]]; then
-    readarray -t line < /proc/cmdline
-    for i in ${line[*]}; do
-        if [[ "${i#initrd=*}" == "$i" ]]; then
-            BOOT_OPTIONS[${#BOOT_OPTIONS[@]}]="$i"
-        fi
+    read -ar line < /proc/cmdline
+    for i in "${line[@]}"; do
+        [[ "${i#initrd=*}" != "$i" ]] && continue
+        BOOT_OPTIONS[${#BOOT_OPTIONS[@]}]="$i"
     done
 fi
 
diff --git a/src/kernel-install/Makefile b/src/kernel-install/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/libsystemd-dhcp/dhcp-lease.c b/src/libsystemd-dhcp/dhcp-lease.c
deleted file mode 100644 (file)
index c1f76aa..0000000
+++ /dev/null
@@ -1,244 +0,0 @@
-/***
-  This file is part of systemd.
-
-  Copyright (C) 2013 Intel Corporation. All rights reserved.
-  Copyright (C) 2014 Tom Gundersen
-
-  systemd is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation; either version 2.1 of the License, or
-  (at your option) any later version.
-
-  systemd is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <stdio.h>
-#include <net/ethernet.h>
-#include <sys/param.h>
-
-#include "util.h"
-#include "list.h"
-
-#include "dhcp-protocol.h"
-#include "dhcp-internal.h"
-#include "dhcp-lease.h"
-#include "sd-dhcp-client.h"
-
-int sd_dhcp_lease_get_address(sd_dhcp_lease *lease, struct in_addr *addr) {
-        assert_return(lease, -EINVAL);
-        assert_return(addr, -EINVAL);
-
-        addr->s_addr = lease->address;
-
-        return 0;
-}
-
-int sd_dhcp_lease_get_mtu(sd_dhcp_lease *lease, uint16_t *mtu) {
-        assert_return(lease, -EINVAL);
-        assert_return(mtu, -EINVAL);
-
-        if (lease->mtu)
-                *mtu = lease->mtu;
-        else
-                return -ENOENT;
-
-        return 0;
-}
-
-int sd_dhcp_lease_get_dns(sd_dhcp_lease *lease, struct in_addr **addr, size_t *addr_size) {
-        assert_return(lease, -EINVAL);
-        assert_return(addr, -EINVAL);
-        assert_return(addr_size, -EINVAL);
-
-        if (lease->dns_size) {
-                *addr_size = lease->dns_size;
-                *addr = lease->dns;
-        } else
-                return -ENOENT;
-
-        return 0;
-}
-
-int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname) {
-        assert_return(lease, -EINVAL);
-        assert_return(domainname, -EINVAL);
-
-        if (lease->domainname)
-                *domainname = lease->domainname;
-        else
-                return -ENOENT;
-
-        return 0;
-}
-
-int sd_dhcp_lease_get_hostname(sd_dhcp_lease *lease, const char **hostname) {
-        assert_return(lease, -EINVAL);
-        assert_return(hostname, -EINVAL);
-
-        if (lease->hostname)
-                *hostname = lease->hostname;
-        else
-                return -ENOENT;
-
-        return 0;
-}
-
-int sd_dhcp_lease_get_router(sd_dhcp_lease *lease, struct in_addr *addr) {
-        assert_return(lease, -EINVAL);
-        assert_return(addr, -EINVAL);
-
-        addr->s_addr = lease->router;
-
-        return 0;
-}
-
-int sd_dhcp_lease_get_netmask(sd_dhcp_lease *lease, struct in_addr *addr) {
-        assert_return(lease, -EINVAL);
-        assert_return(addr, -EINVAL);
-
-        addr->s_addr = lease->subnet_mask;
-
-        return 0;
-}
-
-sd_dhcp_lease *sd_dhcp_lease_ref(sd_dhcp_lease *lease) {
-        if (lease)
-                assert_se(REFCNT_INC(lease->n_ref) >= 2);
-
-        return lease;
-}
-
-sd_dhcp_lease *sd_dhcp_lease_unref(sd_dhcp_lease *lease) {
-        if (lease && REFCNT_DEC(lease->n_ref) <= 0) {
-                free(lease->hostname);
-                free(lease->domainname);
-                free(lease->dns);
-                free(lease);
-        }
-
-        return NULL;
-}
-
-int dhcp_lease_parse_options(uint8_t code, uint8_t len, const uint8_t *option,
-                              void *user_data) {
-        sd_dhcp_lease *lease = user_data;
-        be32_t val;
-
-        switch(code) {
-
-        case DHCP_OPTION_IP_ADDRESS_LEASE_TIME:
-                if (len == 4) {
-                        memcpy(&val, option, 4);
-                        lease->lifetime = be32toh(val);
-                }
-
-                break;
-
-        case DHCP_OPTION_SERVER_IDENTIFIER:
-                if (len >= 4)
-                        memcpy(&lease->server_address, option, 4);
-
-                break;
-
-        case DHCP_OPTION_SUBNET_MASK:
-                if (len >= 4)
-                        memcpy(&lease->subnet_mask, option, 4);
-
-                break;
-
-        case DHCP_OPTION_ROUTER:
-                if (len >= 4)
-                        memcpy(&lease->router, option, 4);
-
-                break;
-
-        case DHCP_OPTION_DOMAIN_NAME_SERVER:
-                if (len && !(len % 4)) {
-                        unsigned i;
-
-                        lease->dns_size = len / 4;
-
-                        free(lease->dns);
-                        lease->dns = new0(struct in_addr, lease->dns_size);
-                        if (!lease->dns)
-                                return -ENOMEM;
-
-                        for (i = 0; i < lease->dns_size; i++) {
-                                memcpy(&lease->dns[i].s_addr, option + 4 * i, 4);
-                        }
-                }
-
-                break;
-
-        case DHCP_OPTION_INTERFACE_MTU:
-                if (len >= 2) {
-                        be16_t mtu;
-
-                        memcpy(&mtu, option, 2);
-                        lease->mtu = be16toh(mtu);
-
-                        if (lease->mtu < 68)
-                                lease->mtu = 0;
-                }
-
-                break;
-
-        case DHCP_OPTION_DOMAIN_NAME:
-                if (len >= 1) {
-                        free(lease->domainname);
-                        lease->domainname = strndup((const char *)option, len);
-                }
-
-                break;
-
-        case DHCP_OPTION_HOST_NAME:
-                if (len >= 1) {
-                        free(lease->hostname);
-                        lease->hostname = strndup((const char *)option, len);
-                }
-
-                break;
-
-        case DHCP_OPTION_RENEWAL_T1_TIME:
-                if (len == 4) {
-                        memcpy(&val, option, 4);
-                        lease->t1 = be32toh(val);
-                }
-
-                break;
-
-        case DHCP_OPTION_REBINDING_T2_TIME:
-                if (len == 4) {
-                        memcpy(&val, option, 4);
-                        lease->t2 = be32toh(val);
-                }
-
-                break;
-        }
-
-        return 0;
-}
-
-int dhcp_lease_new(sd_dhcp_lease **ret) {
-        _cleanup_dhcp_lease_unref_ sd_dhcp_lease *lease = NULL;
-
-        lease = new0(sd_dhcp_lease, 1);
-        if (!lease)
-                return -ENOMEM;
-
-        lease->n_ref = REFCNT_INIT;
-
-        *ret = lease;
-        lease = NULL;
-
-        return 0;
-}
diff --git a/src/libsystemd-dhcp/dhcp-network.c b/src/libsystemd-dhcp/dhcp-network.c
deleted file mode 100644 (file)
index 934e8bf..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/***
-  This file is part of systemd.
-
-  Copyright (C) 2013 Intel Corporation. All rights reserved.
-
-  systemd is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation; either version 2.1 of the License, or
-  (at your option) any later version.
-
-  systemd is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <string.h>
-#include <linux/if_packet.h>
-#include <net/ethernet.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#include "socket-util.h"
-
-#include "dhcp-internal.h"
-
-int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link)
-{
-        int s, one = 1;
-
-        assert(index > 0);
-        assert(link);
-
-        s = socket(AF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
-                   htons(ETH_P_IP));
-        if (s < 0)
-                return -errno;
-
-        link->ll.sll_family = AF_PACKET;
-        link->ll.sll_protocol = htons(ETH_P_IP);
-        link->ll.sll_ifindex =  index;
-        link->ll.sll_halen = ETH_ALEN;
-        memset(link->ll.sll_addr, 0xff, ETH_ALEN);
-
-        if (setsockopt (s, SOL_PACKET, PACKET_AUXDATA, &one, sizeof(one)) < 0)
-                return -errno;
-
-        if (bind(s, &link->sa, sizeof(link->ll)) < 0) {
-                close_nointr_nofail(s);
-                return -errno;
-        }
-
-        return s;
-}
-
-int dhcp_network_bind_udp_socket(int index, be32_t address, uint16_t port)
-{
-        int s;
-        union sockaddr_union src = {
-                .in.sin_family = AF_INET,
-                .in.sin_port = htobe16(port),
-                .in.sin_addr.s_addr = address,
-        };
-
-        s = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
-        if (s < 0)
-                return -errno;
-
-        if (bind(s, &src.sa, sizeof(src.in)) < 0) {
-                close_nointr_nofail(s);
-                return -errno;
-        }
-
-        return s;
-}
-
-int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link,
-                                 const void *packet, size_t len)
-{
-        assert(link);
-        assert(packet);
-        assert(len);
-
-        if (sendto(s, packet, len, 0, &link->sa, sizeof(link->ll)) < 0)
-                return -errno;
-
-        return 0;
-}
-
-int dhcp_network_send_udp_socket(int s, be32_t address, uint16_t port,
-                                 const void *packet, size_t len)
-{
-        union sockaddr_union dest = {
-                .in.sin_family = AF_INET,
-                .in.sin_port = htobe16(port),
-                .in.sin_addr.s_addr = address,
-        };
-
-        if (sendto(s, packet, len, 0, &dest.sa, sizeof(dest.in)) < 0)
-                return -errno;
-
-        return 0;
-}
diff --git a/src/libsystemd-dhcp/dhcp-option.c b/src/libsystemd-dhcp/dhcp-option.c
deleted file mode 100644 (file)
index 4d45b3b..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
-  This file is part of systemd.
-
-  Copyright (C) 2013 Intel Corporation. All rights reserved.
-
-  systemd is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation; either version 2.1 of the License, or
-  (at your option) any later version.
-
-  systemd is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdint.h>
-#include <string.h>
-#include <errno.h>
-#include <stdio.h>
-
-#include "dhcp-internal.h"
-
-int dhcp_option_append(uint8_t **buf, size_t *buflen, uint8_t code,
-                       size_t optlen, const void *optval)
-{
-        if (!buf || !buflen)
-                return -EINVAL;
-
-        switch (code) {
-
-        case DHCP_OPTION_PAD:
-        case DHCP_OPTION_END:
-                if (*buflen < 1)
-                        return -ENOBUFS;
-
-                (*buf)[0] = code;
-                *buf += 1;
-                *buflen -= 1;
-                break;
-
-        default:
-                if (*buflen < optlen + 2)
-                        return -ENOBUFS;
-
-                if (!optval)
-                        return -EINVAL;
-
-                (*buf)[0] = code;
-                (*buf)[1] = optlen;
-                memcpy(&(*buf)[2], optval, optlen);
-
-                *buf += optlen + 2;
-                *buflen -= (optlen + 2);
-
-                break;
-        }
-
-        return 0;
-}
-
-static int parse_options(const uint8_t *buf, size_t buflen, uint8_t *overload,
-                         uint8_t *message_type, dhcp_option_cb_t cb,
-                         void *user_data)
-{
-        const uint8_t *code = buf;
-        const uint8_t *len;
-
-        while (buflen > 0) {
-                switch (*code) {
-                case DHCP_OPTION_PAD:
-                        buflen -= 1;
-                        code++;
-                        break;
-
-                case DHCP_OPTION_END:
-                        return 0;
-
-                case DHCP_OPTION_MESSAGE_TYPE:
-                        if (buflen < 3)
-                                return -ENOBUFS;
-                        buflen -= 3;
-
-                        len = code + 1;
-                        if (*len != 1)
-                                return -EINVAL;
-
-                        if (message_type)
-                                *message_type = *(len + 1);
-
-                        code += 3;
-
-                        break;
-
-                case DHCP_OPTION_OVERLOAD:
-                        if (buflen < 3)
-                                return -ENOBUFS;
-                        buflen -= 3;
-
-                        len = code + 1;
-                        if (*len != 1)
-                                return -EINVAL;
-
-                        if (overload)
-                                *overload = *(len + 1);
-
-                        code += 3;
-
-                        break;
-
-                default:
-                        if (buflen < 3)
-                                return -ENOBUFS;
-
-                        len = code + 1;
-
-                        if (buflen < (size_t)*len + 2)
-                                return -EINVAL;
-                        buflen -= *len + 2;
-
-                        if (cb)
-                                cb(*code, *len, len + 1, user_data);
-
-                        code += *len + 2;
-
-                        break;
-                }
-        }
-
-        if (buflen)
-                return -EINVAL;
-
-        return 0;
-}
-
-int dhcp_option_parse(DHCPMessage *message, size_t len,
-                      dhcp_option_cb_t cb, void *user_data)
-{
-        uint8_t overload = 0;
-        uint8_t message_type = 0;
-        uint8_t *opt = (uint8_t *)(message + 1);
-        int res;
-
-        if (!message)
-                return -EINVAL;
-
-        if (len < sizeof(DHCPMessage) + 4)
-                return -EINVAL;
-
-        len -= sizeof(DHCPMessage) + 4;
-
-        if (opt[0] != 0x63 && opt[1] != 0x82 && opt[2] != 0x53 &&
-                        opt[3] != 0x63)
-                return -EINVAL;
-
-        res = parse_options(&opt[4], len, &overload, &message_type,
-                        cb, user_data);
-        if (res < 0)
-                return res;
-
-        if (overload & DHCP_OVERLOAD_FILE) {
-                res = parse_options(message->file, sizeof(message->file),
-                                NULL, &message_type, cb, user_data);
-                if (res < 0)
-                        return res;
-        }
-
-        if (overload & DHCP_OVERLOAD_SNAME) {
-                res = parse_options(message->sname, sizeof(message->sname),
-                                NULL, &message_type, cb, user_data);
-                if (res < 0)
-                        return res;
-        }
-
-        if (message_type)
-                return message_type;
-
-        return -ENOMSG;
-}
diff --git a/src/libsystemd-dhcp/dhcp-packet.c b/src/libsystemd-dhcp/dhcp-packet.c
deleted file mode 100644 (file)
index 8388e56..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-/***
-  This file is part of systemd.
-
-  Copyright (C) 2013 Intel Corporation. All rights reserved.
-  Copyright (C) 2014 Tom Gundersen
-
-  systemd is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation; either version 2.1 of the License, or
-  (at your option) any later version.
-
-  systemd is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <stdio.h>
-#include <net/ethernet.h>
-#include <net/if_arp.h>
-#include <sys/param.h>
-
-#include "util.h"
-#include "list.h"
-
-#include "dhcp-protocol.h"
-#include "dhcp-lease.h"
-#include "dhcp-internal.h"
-#include "sd-dhcp-client.h"
-
-#define DHCP_CLIENT_MIN_OPTIONS_SIZE            312
-
-int dhcp_message_init(DHCPMessage *message, uint8_t op, uint32_t xid,
-                      uint8_t type, uint8_t **opt, size_t *optlen) {
-        int err;
-
-        assert(op == BOOTREQUEST || op == BOOTREPLY);
-
-        *opt = (uint8_t *)(message + 1);
-
-        if (*optlen < 4)
-                return -ENOBUFS;
-        *optlen -= 4;
-
-        message->op = op;
-        message->htype = ARPHRD_ETHER;
-        message->hlen = ETHER_ADDR_LEN;
-        message->xid = htobe32(xid);
-
-        (*opt)[0] = 0x63;
-        (*opt)[1] = 0x82;
-        (*opt)[2] = 0x53;
-        (*opt)[3] = 0x63;
-
-        *opt += 4;
-
-        err = dhcp_option_append(opt, optlen, DHCP_OPTION_MESSAGE_TYPE, 1,
-                                 &type);
-        if (err < 0)
-                return err;
-
-        return 0;
-}
-
-static uint16_t dhcp_checksum(void *buf, int len) {
-        uint32_t sum;
-        uint16_t *check;
-        int i;
-        uint8_t *odd;
-
-        sum = 0;
-        check = buf;
-
-        for (i = 0; i < len / 2 ; i++)
-                sum += check[i];
-
-        if (len & 0x01) {
-                odd = buf;
-                sum += odd[len - 1];
-        }
-
-        while (sum >> 16)
-                sum = (sum & 0xffff) + (sum >> 16);
-
-        return ~sum;
-}
-
-void dhcp_packet_append_ip_headers(DHCPPacket *packet, uint16_t len) {
-        packet->ip.version = IPVERSION;
-        packet->ip.ihl = DHCP_IP_SIZE / 4;
-        packet->ip.tot_len = htobe16(len);
-
-        packet->ip.protocol = IPPROTO_UDP;
-        packet->ip.saddr = INADDR_ANY;
-        packet->ip.daddr = INADDR_BROADCAST;
-
-        packet->udp.source = htobe16(DHCP_PORT_CLIENT);
-        packet->udp.dest = htobe16(DHCP_PORT_SERVER);
-
-        packet->udp.len = htobe16(len - DHCP_IP_SIZE);
-
-        packet->ip.check = packet->udp.len;
-        packet->udp.check = dhcp_checksum(&packet->ip.ttl, len - 8);
-
-        packet->ip.ttl = IPDEFTTL;
-        packet->ip.check = 0;
-        packet->ip.check = dhcp_checksum(&packet->ip, DHCP_IP_SIZE);
-}
-
-int dhcp_packet_verify_headers(DHCPPacket *packet, size_t len, bool checksum) {
-        size_t hdrlen;
-
-        assert(packet);
-
-        /* IP */
-
-        if (len < DHCP_IP_SIZE) {
-                log_dhcp_client(client, "ignoring packet: packet (%zu bytes) "
-                                " smaller than IP header (%u bytes)", len,
-                                DHCP_IP_SIZE);
-                return -EINVAL;
-        }
-
-        if (packet->ip.ihl < 5) {
-                log_dhcp_client(client, "ignoring packet: IPv4 IHL (%u words) invalid",
-                                packet->ip.ihl);
-                return -EINVAL;
-        }
-
-        hdrlen = packet->ip.ihl * 4;
-        if (hdrlen < 20) {
-                log_dhcp_client(client, "ignoring packet: IPv4 IHL (%zu bytes) "
-                                "smaller than minimum (20 bytes)", hdrlen);
-                return -EINVAL;
-        }
-
-        if (len < hdrlen) {
-                log_dhcp_client(client, "ignoring packet: packet (%zu bytes) "
-                                "smaller than expected (%zu) by IP header", len,
-                                hdrlen);
-                return -EINVAL;
-        }
-
-        if (dhcp_checksum(&packet->ip, hdrlen)) {
-                log_dhcp_client(client, "ignoring packet: invalid IP checksum");
-                return -EINVAL;
-        }
-
-        /* UDP */
-
-        if (len < DHCP_IP_UDP_SIZE) {
-                log_dhcp_client(client, "ignoring packet: packet (%zu bytes) "
-                                " smaller than IP+UDP header (%u bytes)", len,
-                                DHCP_IP_UDP_SIZE);
-                return -EINVAL;
-        }
-
-        if (len < hdrlen + be16toh(packet->udp.len)) {
-                log_dhcp_client(client, "ignoring packet: packet (%zu bytes) "
-                                "smaller than expected (%zu) by UDP header", len,
-                                hdrlen + be16toh(packet->udp.len));
-                return -EINVAL;
-        }
-
-        if (checksum && packet->udp.check) {
-                packet->ip.check = packet->udp.len;
-                packet->ip.ttl = 0;
-
-                if (dhcp_checksum(&packet->ip.ttl,
-                                  be16toh(packet->udp.len) + 12)) {
-                        log_dhcp_client(client, "ignoring packet: invalid UDP checksum");
-                        return -EINVAL;
-                }
-        }
-
-        if (be16toh(packet->udp.dest) != DHCP_PORT_CLIENT) {
-                log_dhcp_client(client, "ignoring packet: to port %u, which "
-                                "is not the DHCP client port (%u)",
-                                be16toh(packet->udp.dest), DHCP_PORT_CLIENT);
-                return -EINVAL;
-        }
-
-        return 0;
-}
diff --git a/src/libsystemd-dhcp/sd-dhcp-client.c b/src/libsystemd-dhcp/sd-dhcp-client.c
deleted file mode 100644 (file)
index 0c82260..0000000
+++ /dev/null
@@ -1,1051 +0,0 @@
-/***
-  This file is part of systemd.
-
-  Copyright (C) 2013 Intel Corporation. All rights reserved.
-
-  systemd is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation; either version 2.1 of the License, or
-  (at your option) any later version.
-
-  systemd is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <stdio.h>
-#include <net/ethernet.h>
-#include <sys/param.h>
-#include <sys/ioctl.h>
-
-#include "util.h"
-#include "list.h"
-
-#include "dhcp-protocol.h"
-#include "dhcp-lease.h"
-#include "dhcp-internal.h"
-#include "sd-dhcp-client.h"
-
-struct sd_dhcp_client {
-        DHCPState state;
-        sd_event *event;
-        int event_priority;
-        sd_event_source *timeout_resend;
-        int index;
-        int fd;
-        union sockaddr_union link;
-        sd_event_source *receive_message;
-        uint8_t *req_opts;
-        size_t req_opts_allocated;
-        size_t req_opts_size;
-        be32_t last_addr;
-        struct ether_addr mac_addr;
-        uint32_t xid;
-        usec_t start_time;
-        uint16_t secs;
-        unsigned int attempt;
-        usec_t request_sent;
-        sd_event_source *timeout_t1;
-        sd_event_source *timeout_t2;
-        sd_event_source *timeout_expire;
-        sd_dhcp_client_cb_t cb;
-        void *userdata;
-        sd_dhcp_lease *lease;
-};
-
-static const uint8_t default_req_opts[] = {
-        DHCP_OPTION_SUBNET_MASK,
-        DHCP_OPTION_ROUTER,
-        DHCP_OPTION_HOST_NAME,
-        DHCP_OPTION_DOMAIN_NAME,
-        DHCP_OPTION_DOMAIN_NAME_SERVER,
-        DHCP_OPTION_NTP_SERVER,
-};
-
-static int client_receive_message_raw(sd_event_source *s, int fd,
-                                      uint32_t revents, void *userdata);
-static int client_receive_message_udp(sd_event_source *s, int fd,
-                                      uint32_t revents, void *userdata);
-
-int sd_dhcp_client_set_callback(sd_dhcp_client *client, sd_dhcp_client_cb_t cb,
-                                void *userdata) {
-        assert_return(client, -EINVAL);
-
-        client->cb = cb;
-        client->userdata = userdata;
-
-        return 0;
-}
-
-int sd_dhcp_client_set_request_option(sd_dhcp_client *client, uint8_t option) {
-        size_t i;
-
-        assert_return(client, -EINVAL);
-        assert_return (client->state == DHCP_STATE_INIT, -EBUSY);
-
-        switch(option) {
-        case DHCP_OPTION_PAD:
-        case DHCP_OPTION_OVERLOAD:
-        case DHCP_OPTION_MESSAGE_TYPE:
-        case DHCP_OPTION_PARAMETER_REQUEST_LIST:
-        case DHCP_OPTION_END:
-                return -EINVAL;
-
-        default:
-                break;
-        }
-
-        for (i = 0; i < client->req_opts_size; i++)
-                if (client->req_opts[i] == option)
-                        return -EEXIST;
-
-        if (!GREEDY_REALLOC(client->req_opts, client->req_opts_allocated,
-                            client->req_opts_size + 1))
-                return -ENOMEM;
-
-        client->req_opts[client->req_opts_size++] = option;
-
-        return 0;
-}
-
-int sd_dhcp_client_set_request_address(sd_dhcp_client *client,
-                                       const struct in_addr *last_addr) {
-        assert_return(client, -EINVAL);
-        assert_return(client->state == DHCP_STATE_INIT, -EBUSY);
-
-        if (last_addr)
-                client->last_addr = last_addr->s_addr;
-        else
-                client->last_addr = INADDR_ANY;
-
-        return 0;
-}
-
-int sd_dhcp_client_set_index(sd_dhcp_client *client, int interface_index) {
-        assert_return(client, -EINVAL);
-        assert_return(client->state == DHCP_STATE_INIT, -EBUSY);
-        assert_return(interface_index >= -1, -EINVAL);
-
-        client->index = interface_index;
-
-        return 0;
-}
-
-int sd_dhcp_client_set_mac(sd_dhcp_client *client,
-                           const struct ether_addr *addr) {
-        assert_return(client, -EINVAL);
-        assert_return(client->state == DHCP_STATE_INIT, -EBUSY);
-
-        memcpy(&client->mac_addr, addr, ETH_ALEN);
-
-        return 0;
-}
-
-int sd_dhcp_client_get_lease(sd_dhcp_client *client, sd_dhcp_lease **ret) {
-        assert_return(client, -EINVAL);
-        assert_return(ret, -EINVAL);
-
-        if (client->state != DHCP_STATE_BOUND &&
-            client->state != DHCP_STATE_RENEWING &&
-            client->state != DHCP_STATE_REBINDING)
-                return -EADDRNOTAVAIL;
-
-        *ret = sd_dhcp_lease_ref(client->lease);
-
-        return 0;
-}
-
-static int client_notify(sd_dhcp_client *client, int event) {
-        if (client->cb)
-                client->cb(client, event, client->userdata);
-
-        return 0;
-}
-
-static int client_stop(sd_dhcp_client *client, int error) {
-        assert_return(client, -EINVAL);
-
-        client->receive_message =
-                sd_event_source_unref(client->receive_message);
-
-        if (client->fd >= 0)
-                close(client->fd);
-        client->fd = -1;
-
-        client->timeout_resend = sd_event_source_unref(client->timeout_resend);
-
-        client->timeout_t1 = sd_event_source_unref(client->timeout_t1);
-        client->timeout_t2 = sd_event_source_unref(client->timeout_t2);
-        client->timeout_expire = sd_event_source_unref(client->timeout_expire);
-
-        client->attempt = 1;
-
-        client_notify(client, error);
-
-        client->start_time = 0;
-        client->secs = 0;
-        client->state = DHCP_STATE_INIT;
-
-        if (client->lease)
-                client->lease = sd_dhcp_lease_unref(client->lease);
-
-        log_dhcp_client(client, "STOPPED");
-
-        return 0;
-}
-
-static int client_message_init(sd_dhcp_client *client, DHCPMessage *message,
-                               uint8_t type, uint16_t secs, uint8_t **opt,
-                               size_t *optlen) {
-        int r;
-
-        assert(secs);
-
-        r = dhcp_message_init(message, BOOTREQUEST, client->xid, type, opt,
-                              optlen);
-        if (r < 0)
-                return r;
-
-        /* Although 'secs' field is a SHOULD in RFC 2131, certain DHCP servers
-           refuse to issue an DHCP lease if 'secs' is set to zero */
-        message->secs = htobe16(secs);
-
-        memcpy(&message->chaddr, &client->mac_addr, ETH_ALEN);
-
-        if (client->state == DHCP_STATE_RENEWING ||
-            client->state == DHCP_STATE_REBINDING)
-                message->ciaddr = client->lease->address;
-
-        /* Some DHCP servers will refuse to issue an DHCP lease if the Client
-           Identifier option is not set */
-        r = dhcp_option_append(opt, optlen, DHCP_OPTION_CLIENT_IDENTIFIER,
-                               ETH_ALEN, &client->mac_addr);
-        if (r < 0)
-                return r;
-
-        if (type == DHCP_DISCOVER || type == DHCP_REQUEST) {
-                be16_t max_size;
-
-                r = dhcp_option_append(opt, optlen,
-                                       DHCP_OPTION_PARAMETER_REQUEST_LIST,
-                                       client->req_opts_size,
-                                       client->req_opts);
-                if (r < 0)
-                        return r;
-
-                /* Some DHCP servers will send bigger DHCP packets than the
-                   defined default size unless the Maximum Messge Size option
-                   is explicitely set */
-                max_size = htobe16(DHCP_IP_UDP_SIZE + DHCP_MESSAGE_SIZE +
-                                   DHCP_MIN_OPTIONS_SIZE);
-                r = dhcp_option_append(opt, optlen,
-                                       DHCP_OPTION_MAXIMUM_MESSAGE_SIZE,
-                                       2, &max_size);
-                if (r < 0)
-                        return r;
-        }
-
-        return 0;
-}
-
-static int client_send_discover(sd_dhcp_client *client, uint16_t secs) {
-        int err = 0;
-        _cleanup_free_ DHCPPacket *discover;
-        size_t optlen, len;
-        uint8_t *opt;
-
-        optlen = DHCP_MIN_OPTIONS_SIZE;
-        len = sizeof(DHCPPacket) + optlen;
-
-        discover = malloc0(len);
-
-        if (!discover)
-                return -ENOMEM;
-
-        err = client_message_init(client, &discover->dhcp, DHCP_DISCOVER,
-                                  secs, &opt, &optlen);
-        if (err < 0)
-                return err;
-
-        if (client->last_addr != INADDR_ANY) {
-                err = dhcp_option_append(&opt, &optlen,
-                                         DHCP_OPTION_REQUESTED_IP_ADDRESS,
-                                         4, &client->last_addr);
-                if (err < 0)
-                        return err;
-        }
-
-        err = dhcp_option_append(&opt, &optlen, DHCP_OPTION_END, 0, NULL);
-        if (err < 0)
-                return err;
-
-        dhcp_packet_append_ip_headers(discover, len);
-
-        err = dhcp_network_send_raw_socket(client->fd, &client->link,
-                                           discover, len);
-
-        log_dhcp_client(client, "DISCOVER");
-
-        return err;
-}
-
-static int client_send_request(sd_dhcp_client *client, uint16_t secs) {
-        _cleanup_free_ DHCPPacket *request;
-        size_t optlen, len;
-        int err;
-        uint8_t *opt;
-
-        optlen = DHCP_MIN_OPTIONS_SIZE;
-        len = sizeof(DHCPPacket) + optlen;
-
-        request = malloc0(len);
-        if (!request)
-                return -ENOMEM;
-
-        err = client_message_init(client, &request->dhcp, DHCP_REQUEST, secs,
-                                  &opt, &optlen);
-        if (err < 0)
-                return err;
-
-        if (client->state == DHCP_STATE_REQUESTING) {
-                err = dhcp_option_append(&opt, &optlen,
-                                         DHCP_OPTION_REQUESTED_IP_ADDRESS,
-                                         4, &client->lease->address);
-                if (err < 0)
-                        return err;
-
-                err = dhcp_option_append(&opt, &optlen,
-                                         DHCP_OPTION_SERVER_IDENTIFIER,
-                                         4, &client->lease->server_address);
-                if (err < 0)
-                        return err;
-        }
-
-        err = dhcp_option_append(&opt, &optlen, DHCP_OPTION_END, 0, NULL);
-        if (err < 0)
-                return err;
-
-        if (client->state == DHCP_STATE_RENEWING) {
-                err = dhcp_network_send_udp_socket(client->fd,
-                                                   client->lease->server_address,
-                                                   DHCP_PORT_SERVER,
-                                                   &request->dhcp,
-                                                   len - DHCP_IP_UDP_SIZE);
-        } else {
-                dhcp_packet_append_ip_headers(request, len);
-
-                err = dhcp_network_send_raw_socket(client->fd, &client->link,
-                                                   request, len);
-        }
-
-        log_dhcp_client(client, "REQUEST");
-
-        return err;
-}
-
-static uint16_t client_update_secs(sd_dhcp_client *client, usec_t time_now)
-{
-        client->secs = ((time_now - client->start_time) / USEC_PER_SEC) ? : 1;
-
-        return client->secs;
-}
-
-static int client_timeout_resend(sd_event_source *s, uint64_t usec,
-                                 void *userdata) {
-        sd_dhcp_client *client = userdata;
-        usec_t next_timeout = 0;
-        uint32_t time_left;
-        int r = 0;
-
-        assert(s);
-        assert(client);
-        assert(client->event);
-
-        switch (client->state) {
-        case DHCP_STATE_RENEWING:
-
-                time_left = (client->lease->t2 - client->lease->t1) / 2;
-                if (time_left < 60)
-                        time_left = 60;
-
-                next_timeout = usec + time_left * USEC_PER_SEC;
-
-                break;
-
-        case DHCP_STATE_REBINDING:
-
-                time_left = (client->lease->lifetime - client->lease->t2) / 2;
-                if (time_left < 60)
-                        time_left = 60;
-
-                next_timeout = usec + time_left * USEC_PER_SEC;
-                break;
-
-        case DHCP_STATE_INIT:
-        case DHCP_STATE_INIT_REBOOT:
-        case DHCP_STATE_REBOOTING:
-        case DHCP_STATE_SELECTING:
-        case DHCP_STATE_REQUESTING:
-        case DHCP_STATE_BOUND:
-
-                if (client->attempt < 64)
-                        client->attempt *= 2;
-
-                next_timeout = usec + (client->attempt - 1) * USEC_PER_SEC;
-
-                break;
-        }
-
-        next_timeout += (random_u32() & 0x1fffff);
-
-        client->timeout_resend = sd_event_source_unref(client->timeout_resend);
-
-        r = sd_event_add_monotonic(client->event,
-                                     &client->timeout_resend,
-                                     next_timeout,
-                                     10 * USEC_PER_MSEC,
-                                     client_timeout_resend, client);
-        if (r < 0)
-                goto error;
-
-        r = sd_event_source_set_priority(client->timeout_resend,
-                                         client->event_priority);
-        if (r < 0)
-                goto error;
-
-        switch (client->state) {
-        case DHCP_STATE_INIT:
-
-                client_update_secs(client, usec);
-
-                r = client_send_discover(client, client->secs);
-                if (r >= 0) {
-                        client->state = DHCP_STATE_SELECTING;
-                        client->attempt = 1;
-                } else {
-                        if (client->attempt >= 64)
-                                goto error;
-                }
-
-                break;
-
-        case DHCP_STATE_SELECTING:
-                client_update_secs(client, usec);
-
-                r = client_send_discover(client, client->secs);
-                if (r < 0 && client->attempt >= 64)
-                        goto error;
-
-                break;
-
-        case DHCP_STATE_REQUESTING:
-        case DHCP_STATE_RENEWING:
-        case DHCP_STATE_REBINDING:
-                r = client_send_request(client, client->secs);
-                if (r < 0 && client->attempt >= 64)
-                         goto error;
-
-                client->request_sent = usec;
-
-                break;
-
-        case DHCP_STATE_INIT_REBOOT:
-        case DHCP_STATE_REBOOTING:
-        case DHCP_STATE_BOUND:
-
-                break;
-        }
-
-        return 0;
-
-error:
-        client_stop(client, r);
-
-        /* Errors were dealt with when stopping the client, don't spill
-           errors into the event loop handler */
-        return 0;
-}
-
-static int client_initialize_events(sd_dhcp_client *client,
-                                    sd_event_io_handler_t io_callback,
-                                    usec_t usec) {
-        int r;
-
-        assert(client);
-        assert(client->event);
-
-        r = sd_event_add_io(client->event, &client->receive_message,
-                            client->fd, EPOLLIN, io_callback,
-                            client);
-        if (r < 0)
-                goto error;
-
-        r = sd_event_source_set_priority(client->receive_message,
-                                         client->event_priority);
-        if (r < 0)
-                goto error;
-
-        client->timeout_resend = sd_event_source_unref(client->timeout_resend);
-
-        r = sd_event_add_monotonic(client->event,
-                                   &client->timeout_resend,
-                                   usec, 0,
-                                   client_timeout_resend, client);
-        if (r < 0)
-                goto error;
-
-        r = sd_event_source_set_priority(client->timeout_resend,
-                                         client->event_priority);
-
-error:
-        if (r < 0)
-                client_stop(client, r);
-
-        return 0;
-
-}
-
-static int client_timeout_expire(sd_event_source *s, uint64_t usec,
-                                 void *userdata) {
-        sd_dhcp_client *client = userdata;
-
-        log_dhcp_client(client, "EXPIRED");
-
-        client_stop(client, DHCP_EVENT_EXPIRED);
-
-        return 0;
-}
-
-static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata) {
-        sd_dhcp_client *client = userdata;
-        int r;
-
-        if (client->fd >= 0) {
-                client->receive_message =
-                        sd_event_source_unref(client->receive_message);
-                close(client->fd);
-                client->fd = -1;
-        }
-
-        client->state = DHCP_STATE_REBINDING;
-        client->attempt = 1;
-
-        r = dhcp_network_bind_raw_socket(client->index, &client->link);
-        if (r < 0) {
-                client_stop(client, r);
-                return 0;
-        }
-
-        client->fd = r;
-
-        log_dhcp_client(client, "TIMEOUT T2");
-
-        return client_initialize_events(client, client_receive_message_raw,
-                                        usec);
-}
-
-static int client_timeout_t1(sd_event_source *s, uint64_t usec,
-                             void *userdata) {
-        sd_dhcp_client *client = userdata;
-        int r;
-
-        client->state = DHCP_STATE_RENEWING;
-        client->attempt = 1;
-
-        r = dhcp_network_bind_udp_socket(client->index,
-                                         client->lease->address,
-                                         DHCP_PORT_CLIENT);
-        if (r < 0) {
-                client_stop(client, r);
-                return 0;
-        }
-
-        client->fd = r;
-
-        log_dhcp_client(client, "TIMEOUT T1");
-
-        return client_initialize_events(client, client_receive_message_udp, usec);
-}
-
-static int client_handle_offer(sd_dhcp_client *client, DHCPMessage *offer,
-                               size_t len) {
-        _cleanup_dhcp_lease_unref_ sd_dhcp_lease *lease = NULL;
-        int r;
-
-        r = dhcp_lease_new(&lease);
-        if (r < 0)
-                return r;
-
-        r = dhcp_option_parse(offer, len, dhcp_lease_parse_options, lease);
-        if (r != DHCP_OFFER)
-                return -ENOMSG;
-
-        lease->address = offer->yiaddr;
-
-        if (lease->address == INADDR_ANY ||
-            lease->server_address == INADDR_ANY ||
-            lease->subnet_mask == INADDR_ANY ||
-            lease->lifetime == 0)
-                return -ENOMSG;
-
-        client->lease = lease;
-        lease = NULL;
-
-        log_dhcp_client(client, "OFFER");
-
-        return 0;
-}
-
-static int client_handle_ack(sd_dhcp_client *client, DHCPMessage *ack,
-                             size_t len) {
-        _cleanup_dhcp_lease_unref_ sd_dhcp_lease *lease = NULL;
-        int r;
-
-        r = dhcp_lease_new(&lease);
-        if (r < 0)
-                return r;
-
-        r = dhcp_option_parse(ack, len, dhcp_lease_parse_options, lease);
-        if (r == DHCP_NAK) {
-                log_dhcp_client(client, "NAK");
-                return DHCP_EVENT_NO_LEASE;
-        }
-
-        if (r != DHCP_ACK)
-                return -ENOMSG;
-
-        lease->address = ack->yiaddr;
-
-        if (lease->address == INADDR_ANY ||
-            lease->server_address == INADDR_ANY ||
-            lease->subnet_mask == INADDR_ANY || lease->lifetime == 0)
-                return -ENOMSG;
-
-        r = DHCP_EVENT_IP_ACQUIRE;
-        if (client->lease) {
-                if (client->lease->address != lease->address ||
-                    client->lease->subnet_mask != lease->subnet_mask ||
-                    client->lease->router != lease->router) {
-                        r = DHCP_EVENT_IP_CHANGE;
-                }
-
-                client->lease = sd_dhcp_lease_unref(client->lease);
-        }
-
-        client->lease = lease;
-        lease = NULL;
-
-        log_dhcp_client(client, "ACK");
-
-        return r;
-}
-
-static uint64_t client_compute_timeout(uint64_t request_sent,
-                                       uint32_t lifetime) {
-        return request_sent + (lifetime - 3) * USEC_PER_SEC +
-                + (random_u32() & 0x1fffff);
-}
-
-static int client_set_lease_timeouts(sd_dhcp_client *client, uint64_t usec) {
-        uint64_t next_timeout;
-        int r;
-
-        assert(client);
-        assert(client->event);
-
-        if (client->lease->lifetime < 10)
-                return -EINVAL;
-
-        client->timeout_t1 = sd_event_source_unref(client->timeout_t1);
-        client->timeout_t2 = sd_event_source_unref(client->timeout_t2);
-        client->timeout_expire = sd_event_source_unref(client->timeout_expire);
-
-        if (!client->lease->t1)
-                client->lease->t1 = client->lease->lifetime / 2;
-
-        next_timeout = client_compute_timeout(client->request_sent,
-                                              client->lease->t1);
-        if (next_timeout < usec)
-                return -EINVAL;
-
-        r = sd_event_add_monotonic(client->event,
-                                     &client->timeout_t1,
-                                     next_timeout,
-                                     10 * USEC_PER_MSEC,
-                                     client_timeout_t1, client);
-        if (r < 0)
-                return r;
-
-        r = sd_event_source_set_priority(client->timeout_t1,
-                                         client->event_priority);
-        if (r < 0)
-                return r;
-
-        if (!client->lease->t2)
-                client->lease->t2 = client->lease->lifetime * 7 / 8;
-
-        if (client->lease->t2 < client->lease->t1)
-                return -EINVAL;
-
-        if (client->lease->lifetime < client->lease->t2)
-                return -EINVAL;
-
-        next_timeout = client_compute_timeout(client->request_sent,
-                                              client->lease->t2);
-        if (next_timeout < usec)
-                return -EINVAL;
-
-        r = sd_event_add_monotonic(client->event,
-                                     &client->timeout_t2,
-                                     next_timeout,
-                                     10 * USEC_PER_MSEC,
-                                     client_timeout_t2, client);
-        if (r < 0)
-                return r;
-
-        r = sd_event_source_set_priority(client->timeout_t2,
-                                         client->event_priority);
-        if (r < 0)
-                return r;
-
-        next_timeout = client_compute_timeout(client->request_sent,
-                                              client->lease->lifetime);
-        if (next_timeout < usec)
-                return -EINVAL;
-
-        r = sd_event_add_monotonic(client->event,
-                                     &client->timeout_expire, next_timeout,
-                                     10 * USEC_PER_MSEC,
-                                     client_timeout_expire, client);
-        if (r < 0)
-                return r;
-
-        r = sd_event_source_set_priority(client->timeout_expire,
-                                         client->event_priority);
-        if (r < 0)
-                return r;
-
-        return 0;
-}
-
-static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message,
-                                 int len, usec_t time_now) {
-        int r = 0, notify_event = 0;
-
-        assert(client);
-        assert(client->event);
-        assert(message);
-
-        if (len < DHCP_MESSAGE_SIZE) {
-                log_dhcp_client(client, "message too small (%d bytes): "
-                                "ignoring", len);
-                return 0;
-        }
-
-        if (message->op != BOOTREPLY) {
-                log_dhcp_client(client, "not a BOOTREPLY message: ignoring");
-                return 0;
-        }
-
-        if (be32toh(message->xid) != client->xid) {
-                log_dhcp_client(client, "received xid (%u) does not match "
-                                "expected (%u): ignoring",
-                                be32toh(message->xid), client->xid);
-                return 0;
-        }
-
-        if (memcmp(&message->chaddr[0], &client->mac_addr.ether_addr_octet,
-                   ETHER_ADDR_LEN)) {
-                log_dhcp_client(client, "received chaddr does not match "
-                                "expected: ignoring");
-                return 0;
-        }
-
-        switch (client->state) {
-        case DHCP_STATE_SELECTING:
-
-                r = client_handle_offer(client, message, len);
-                if (r >= 0) {
-
-                        client->timeout_resend =
-                                sd_event_source_unref(client->timeout_resend);
-
-                        client->state = DHCP_STATE_REQUESTING;
-                        client->attempt = 1;
-
-                        r = sd_event_add_monotonic(client->event,
-                                                   &client->timeout_resend,
-                                                   time_now, 0,
-                                                   client_timeout_resend,
-                                                   client);
-                        if (r < 0)
-                                goto error;
-
-                        r = sd_event_source_set_priority(client->timeout_resend,
-                                                         client->event_priority);
-                        if (r < 0)
-                                goto error;
-                }
-
-                break;
-
-        case DHCP_STATE_REQUESTING:
-        case DHCP_STATE_RENEWING:
-        case DHCP_STATE_REBINDING:
-
-                r = client_handle_ack(client, message, len);
-
-                if (r == DHCP_EVENT_NO_LEASE)
-                        goto error;
-
-                if (r >= 0) {
-                        client->timeout_resend =
-                                sd_event_source_unref(client->timeout_resend);
-
-                        if (client->state == DHCP_STATE_REQUESTING)
-                                notify_event = DHCP_EVENT_IP_ACQUIRE;
-                        else if (r != DHCP_EVENT_IP_ACQUIRE)
-                                notify_event = r;
-
-                        client->state = DHCP_STATE_BOUND;
-                        client->attempt = 1;
-
-                        client->last_addr = client->lease->address;
-
-                        r = client_set_lease_timeouts(client, time_now);
-                        if (r < 0)
-                                goto error;
-
-                        if (notify_event)
-                                client_notify(client, notify_event);
-
-                        client->receive_message =
-                                sd_event_source_unref(client->receive_message);
-                        close(client->fd);
-                        client->fd = -1;
-                }
-
-                r = 0;
-
-                break;
-
-        case DHCP_STATE_INIT:
-        case DHCP_STATE_INIT_REBOOT:
-        case DHCP_STATE_REBOOTING:
-        case DHCP_STATE_BOUND:
-
-                break;
-        }
-
-error:
-        if (r < 0 || r == DHCP_EVENT_NO_LEASE)
-                return client_stop(client, r);
-
-        return 0;
-}
-
-static int client_receive_message_udp(sd_event_source *s, int fd,
-                                      uint32_t revents, void *userdata) {
-        sd_dhcp_client *client = userdata;
-        _cleanup_free_ DHCPMessage *message = NULL;
-        int buflen = 0, len, r;
-        usec_t time_now;
-
-        assert(s);
-        assert(client);
-        assert(client->event);
-
-        r = ioctl(fd, FIONREAD, &buflen);
-        if (r < 0 || buflen <= 0)
-                buflen = sizeof(DHCPMessage) + DHCP_MIN_OPTIONS_SIZE;
-
-        message = malloc0(buflen);
-        if (!message)
-                return -ENOMEM;
-
-        len = read(fd, message, buflen);
-        if (len < 0)
-                return 0;
-
-        r = sd_event_get_now_monotonic(client->event, &time_now);
-        if (r < 0)
-                return client_stop(client, r);
-
-        return client_handle_message(client, message, len,
-                                     time_now);
-}
-
-static int client_receive_message_raw(sd_event_source *s, int fd,
-                                      uint32_t revents, void *userdata) {
-        sd_dhcp_client *client = userdata;
-        _cleanup_free_ DHCPPacket *packet = NULL;
-        usec_t time_now;
-        uint8_t cmsgbuf[CMSG_LEN(sizeof(struct tpacket_auxdata))];
-        struct iovec iov = {};
-        struct msghdr msg = {
-                .msg_iov = &iov,
-                .msg_iovlen = 1,
-                .msg_control = cmsgbuf,
-                .msg_controllen = sizeof(cmsgbuf),
-        };
-        struct cmsghdr *cmsg;
-        bool checksum = true;
-        int buflen = 0, len, r;
-
-        assert(s);
-        assert(client);
-        assert(client->event);
-
-        r = ioctl(fd, FIONREAD, &buflen);
-        if (r < 0 || buflen <= 0)
-                buflen = sizeof(DHCPPacket) + DHCP_MIN_OPTIONS_SIZE;
-
-        packet = malloc0(buflen);
-        if (!packet)
-                return -ENOMEM;
-
-        iov.iov_base = packet;
-        iov.iov_len = buflen;
-
-        len = recvmsg(fd, &msg, 0);
-        if (len < 0) {
-                log_dhcp_client(client, "could not receive message from raw "
-                                "socket: %s", strerror(errno));
-                return 0;
-        }
-
-        for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
-                if (cmsg->cmsg_level == SOL_PACKET && cmsg->cmsg_type == PACKET_AUXDATA) {
-                        struct tpacket_auxdata *aux = (void *)CMSG_DATA(cmsg);
-
-                        checksum = !(aux->tp_status & TP_STATUS_CSUMNOTREADY);
-                        break;
-                }
-        }
-
-        r = dhcp_packet_verify_headers(packet, len, checksum);
-        if (r < 0)
-                return 0;
-
-        len -= DHCP_IP_UDP_SIZE;
-
-        r = sd_event_get_now_monotonic(client->event, &time_now);
-        if (r < 0)
-                return client_stop(client, r);
-
-        return client_handle_message(client, &packet->dhcp, len, time_now);
-}
-
-int sd_dhcp_client_start(sd_dhcp_client *client) {
-        int r;
-
-        assert_return(client, -EINVAL);
-        assert_return(client->event, -EINVAL);
-        assert_return(client->index > 0, -EINVAL);
-        assert_return(client->state == DHCP_STATE_INIT ||
-                      client->state == DHCP_STATE_INIT_REBOOT, -EBUSY);
-
-        client->xid = random_u32();
-
-        r = dhcp_network_bind_raw_socket(client->index, &client->link);
-
-        if (r < 0) {
-                client_stop(client, r);
-                return r;
-        }
-
-        client->fd = r;
-        client->start_time = now(CLOCK_MONOTONIC);
-        client->secs = 0;
-
-        log_dhcp_client(client, "STARTED");
-
-        return client_initialize_events(client, client_receive_message_raw,
-                                        client->start_time);
-}
-
-int sd_dhcp_client_stop(sd_dhcp_client *client) {
-        return client_stop(client, DHCP_EVENT_STOP);
-}
-
-int sd_dhcp_client_attach_event(sd_dhcp_client *client, sd_event *event,
-                                int priority) {
-        int r;
-
-        assert_return(client, -EINVAL);
-        assert_return(!client->event, -EBUSY);
-
-        if (event)
-                client->event = sd_event_ref(event);
-        else {
-                r = sd_event_default(&client->event);
-                if (r < 0)
-                        return 0;
-        }
-
-        client->event_priority = priority;
-
-        return 0;
-}
-
-int sd_dhcp_client_detach_event(sd_dhcp_client *client) {
-        assert_return(client, -EINVAL);
-
-        client->event = sd_event_unref(client->event);
-
-        return 0;
-}
-
-sd_event *sd_dhcp_client_get_event(sd_dhcp_client *client) {
-        if (!client)
-                return NULL;
-
-        return client->event;
-}
-
-void sd_dhcp_client_free(sd_dhcp_client *client) {
-        if (!client)
-                return;
-
-        sd_dhcp_client_stop(client);
-        sd_dhcp_client_detach_event(client);
-
-        free(client->req_opts);
-        free(client);
-}
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(sd_dhcp_client*, sd_dhcp_client_free);
-#define _cleanup_dhcp_client_free_ _cleanup_(sd_dhcp_client_freep)
-
-int sd_dhcp_client_new(sd_dhcp_client **ret) {
-        _cleanup_dhcp_client_free_ sd_dhcp_client *client = NULL;
-
-        assert_return(ret, -EINVAL);
-
-        client = new0(sd_dhcp_client, 1);
-        if (!client)
-                return -ENOMEM;
-
-        client->state = DHCP_STATE_INIT;
-        client->index = -1;
-        client->fd = -1;
-        client->attempt = 1;
-
-        client->req_opts_size = ELEMENTSOF(default_req_opts);
-
-        client->req_opts = memdup(default_req_opts, client->req_opts_size);
-        if (!client->req_opts)
-                return -ENOMEM;
-
-        *ret = client;
-        client = NULL;
-
-        return 0;
-}
diff --git a/src/libsystemd-network/Makefile b/src/libsystemd-network/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
similarity index 59%
rename from src/libsystemd-dhcp/dhcp-internal.h
rename to src/libsystemd-network/dhcp-internal.h
index ce83b81..1069c8a 100644 (file)
 
 #include <stdint.h>
 #include <linux/if_packet.h>
+#include <net/ethernet.h>
 
 #include "socket-util.h"
 
+#include "sd-dhcp-client.h"
 #include "dhcp-protocol.h"
 
-int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link);
-int dhcp_network_bind_udp_socket(int index, be32_t address, uint16_t port);
+int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link, uint32_t xid, struct ether_addr mac_addr);
+int dhcp_network_bind_udp_socket(be32_t address, uint16_t port);
 int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link,
                                  const void *packet, size_t len);
 int dhcp_network_send_udp_socket(int s, be32_t address, uint16_t port,
                                  const void *packet, size_t len);
 
-int dhcp_option_append(uint8_t **buf, size_t *buflen, uint8_t code,
-                       size_t optlen, const void *optval);
+int dhcp_option_append(DHCPMessage *message, size_t size, size_t *offset, uint8_t overload,
+                       uint8_t code, size_t optlen, const void *optval);
 
 typedef int (*dhcp_option_cb_t)(uint8_t code, uint8_t len,
                                 const uint8_t *option, void *user_data);
@@ -46,10 +48,23 @@ int dhcp_option_parse(DHCPMessage *message, size_t len,
                       dhcp_option_cb_t cb, void *user_data);
 
 int dhcp_message_init(DHCPMessage *message, uint8_t op, uint32_t xid, uint8_t type,
-                      uint8_t **opt, size_t *optlen);
+                      size_t optlen, size_t *optoffset);
 
-void dhcp_packet_append_ip_headers(DHCPPacket *packet, uint16_t len);
+uint16_t dhcp_packet_checksum(uint8_t *buf, size_t len);
+
+void dhcp_packet_append_ip_headers(DHCPPacket *packet, be32_t source_addr,
+                                   uint16_t source, be32_t destination_addr,
+                                   uint16_t destination, uint16_t len);
 
 int dhcp_packet_verify_headers(DHCPPacket *packet, size_t len, bool checksum);
 
-#define log_dhcp_client(client, fmt, ...) log_meta(LOG_DEBUG, __FILE__, __LINE__, __func__, "DHCP CLIENT: " fmt, ##__VA_ARGS__)
+DEFINE_TRIVIAL_CLEANUP_FUNC(sd_dhcp_client*, sd_dhcp_client_unref);
+#define _cleanup_dhcp_client_unref_ _cleanup_(sd_dhcp_client_unrefp)
+
+/* If we are invoking callbacks of a dhcp-client, ensure unreffing the
+ * client from the callback doesn't destroy the object we are working
+ * on */
+#define DHCP_CLIENT_DONT_DESTROY(client) \
+        _cleanup_dhcp_client_unref_ _unused_ sd_dhcp_client *_dont_destroy_##client = sd_dhcp_client_ref(client)
+
+#define log_dhcp_client(client, fmt, ...) log_meta(LOG_DEBUG, __FILE__, __LINE__, __func__, "DHCP CLIENT (0x%x): " fmt, client->xid, ##__VA_ARGS__)
similarity index 65%
rename from src/libsystemd-dhcp/dhcp-lease.h
rename to src/libsystemd-network/dhcp-lease-internal.h
index 87323dc..d4675f3 100644 (file)
 #include <stdint.h>
 #include <linux/if_packet.h>
 
-#include "socket-util.h"
 #include "refcnt.h"
+#include "util.h"
 
 #include "dhcp-protocol.h"
 
 #include "sd-dhcp-client.h"
 
+struct sd_dhcp_route {
+        struct in_addr dst_addr;
+        struct in_addr gw_addr;
+        uint8_t dst_prefixlen;
+};
+
 struct sd_dhcp_lease {
         RefCount n_ref;
 
+        int32_t time_offset;
         uint32_t t1;
         uint32_t t2;
         uint32_t lifetime;
+        uint32_t mtu_aging_timeout;
         be32_t address;
         be32_t server_address;
         be32_t subnet_mask;
         be32_t router;
+        be32_t next_server;
+        be32_t broadcast;
         struct in_addr *dns;
         size_t dns_size;
+        struct in_addr *ntp;
+        size_t ntp_size;
+        struct in_addr *policy_filter;
+        size_t policy_filter_size;
+        struct sd_dhcp_route *static_route;
+        size_t static_route_size;
+        size_t static_route_allocated;
+        uint16_t boot_file_size;
+        uint16_t mdr;
         uint16_t mtu;
+        uint8_t ttl;
+        bool ip_forward;
+        bool ip_forward_non_local;
         char *domainname;
         char *hostname;
+        char *root_path;
 };
 
 int dhcp_lease_new(sd_dhcp_lease **ret);
 int dhcp_lease_parse_options(uint8_t code, uint8_t len, const uint8_t *option,
                               void *user_data);
 
+int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file);
+int dhcp_lease_load(const char *lease_file, sd_dhcp_lease **ret);
+
+int dhcp_lease_set_default_subnet_mask(sd_dhcp_lease *lease);
+
 DEFINE_TRIVIAL_CLEANUP_FUNC(sd_dhcp_lease*, sd_dhcp_lease_unref);
 #define _cleanup_dhcp_lease_unref_ _cleanup_(sd_dhcp_lease_unrefp)
diff --git a/src/libsystemd-network/dhcp-network.c b/src/libsystemd-network/dhcp-network.c
new file mode 100644 (file)
index 0000000..1ced5cf
--- /dev/null
@@ -0,0 +1,201 @@
+/***
+  This file is part of systemd.
+
+  Copyright (C) 2013 Intel Corporation. All rights reserved.
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <string.h>
+#include <linux/if_packet.h>
+#include <net/ethernet.h>
+#include <net/if_arp.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <linux/filter.h>
+
+#include "socket-util.h"
+
+#include "dhcp-internal.h"
+
+int dhcp_network_bind_raw_socket(int ifindex, union sockaddr_union *link,
+                                 uint32_t xid, struct ether_addr mac_addr) {
+
+        struct sock_filter filter[] = {
+                BPF_STMT(BPF_LD + BPF_W + BPF_LEN, 0),                                 /* A <- packet length */
+                BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, sizeof(DHCPPacket), 1, 0),         /* packet >= DHCPPacket ? */
+                BPF_STMT(BPF_RET + BPF_K, 0),                                          /* ignore */
+                BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(DHCPPacket, ip.protocol)), /* A <- IP protocol */
+                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 1, 0),                /* IP protocol == UDP ? */
+                BPF_STMT(BPF_RET + BPF_K, 0),                                          /* ignore */
+                BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(DHCPPacket, ip.frag_off)), /* A <- Flags */
+                BPF_STMT(BPF_ALU + BPF_AND + BPF_K, 0x20),                             /* A <- A & 0x20 (More Fragments bit) */
+                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 1, 0),                          /* A == 0 ? */
+                BPF_STMT(BPF_RET + BPF_K, 0),                                          /* ignore */
+                BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(DHCPPacket, ip.frag_off)), /* A <- Flags + Fragment offset */
+                BPF_STMT(BPF_ALU + BPF_AND + BPF_K, 0x1fff),                           /* A <- A & 0x1fff (Fragment offset) */
+                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 1, 0),                          /* A == 0 ? */
+                BPF_STMT(BPF_RET + BPF_K, 0),                                          /* ignore */
+                BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(DHCPPacket, udp.dest)),    /* A <- UDP destination port */
+                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, DHCP_PORT_CLIENT, 1, 0),           /* UDP destination port == DHCP client port ? */
+                BPF_STMT(BPF_RET + BPF_K, 0),                                          /* ignore */
+                BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(DHCPPacket, dhcp.op)),     /* A <- DHCP op */
+                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, BOOTREPLY, 1, 0),                  /* op == BOOTREPLY ? */
+                BPF_STMT(BPF_RET + BPF_K, 0),                                          /* ignore */
+                BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(DHCPPacket, dhcp.htype)),  /* A <- DHCP header type */
+                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ARPHRD_ETHER, 1, 0),               /* header type == ARPHRD_ETHER ? */
+                BPF_STMT(BPF_RET + BPF_K, 0),                                          /* ignore */
+                BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(DHCPPacket, dhcp.hlen)),   /* A <- mac address length */
+                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETHER_ADDR_LEN, 1, 0),             /* address length == ETHER_ADDR_LEN ? */
+                BPF_STMT(BPF_RET + BPF_K, 0),                                          /* ignore */
+                BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(DHCPPacket, dhcp.xid)),    /* A <- client identifier */
+                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, xid, 1, 0),                        /* client identifier == xid ? */
+                BPF_STMT(BPF_RET + BPF_K, 0),                                          /* ignore */
+                BPF_STMT(BPF_LD + BPF_IMM, htobe32(*((unsigned int *) &mac_addr))),                    /* A <- 4 bytes of client's MAC */
+                BPF_STMT(BPF_MISC + BPF_TAX, 0),                                                       /* X <- A */
+                BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(DHCPPacket, dhcp.chaddr)),                 /* A <- 4 bytes of MAC from dhcp.chaddr */
+                BPF_STMT(BPF_ALU + BPF_XOR + BPF_X, 0),                                                /* A xor X */
+                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 1, 0),                                          /* A == 0 ? */
+                BPF_STMT(BPF_RET + BPF_K, 0),                                                          /* ignore */
+                BPF_STMT(BPF_LD + BPF_IMM, htobe16(*((unsigned short *) (((char *) &mac_addr) + 4)))), /* A <- remainder of client's MAC */
+                BPF_STMT(BPF_MISC + BPF_TAX, 0),                                                       /* X <- A */
+                BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(DHCPPacket, dhcp.chaddr) + 4),             /* A <- remainder of MAC from dhcp.chaddr */
+                BPF_STMT(BPF_ALU + BPF_XOR + BPF_X, 0),                                                /* A xor X */
+                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 1, 0),                                          /* A == 0 ? */
+                BPF_STMT(BPF_RET + BPF_K, 0),                                                          /* ignore */
+                BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(DHCPPacket, dhcp.magic)),  /* A <- DHCP magic cookie */
+                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, DHCP_MAGIC_COOKIE, 1, 0),          /* cookie == DHCP magic cookie ? */
+                BPF_STMT(BPF_RET + BPF_K, 0),                                          /* ignore */
+                BPF_STMT(BPF_RET + BPF_K, 65535),                                      /* return all */
+        };
+        struct sock_fprog fprog = {
+                .len = ELEMENTSOF(filter),
+                .filter = filter
+        };
+        _cleanup_close_ int s = -1;
+        int r, on = 1;
+
+        assert(ifindex > 0);
+        assert(link);
+
+        s = socket(AF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
+        if (s < 0)
+                return -errno;
+
+        r = setsockopt(s, SOL_PACKET, PACKET_AUXDATA, &on, sizeof(on));
+        if (r < 0)
+                return -errno;
+
+        r = setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER, &fprog, sizeof(fprog));
+        if (r < 0)
+                return -errno;
+
+        link->ll.sll_family = AF_PACKET;
+        link->ll.sll_protocol = htons(ETH_P_IP);
+        link->ll.sll_ifindex = ifindex;
+        link->ll.sll_halen = ETH_ALEN;
+        memset(link->ll.sll_addr, 0xff, ETH_ALEN);
+
+        r = bind(s, &link->sa, sizeof(link->ll));
+        if (r < 0)
+                return -errno;
+
+        r = s;
+        s = -1;
+
+        return r;
+}
+
+int dhcp_network_bind_udp_socket(be32_t address, uint16_t port) {
+        union sockaddr_union src = {
+                .in.sin_family = AF_INET,
+                .in.sin_port = htobe16(port),
+                .in.sin_addr.s_addr = address,
+        };
+        _cleanup_close_ int s = -1;
+        int r, on = 1, tos = IPTOS_CLASS_CS6;
+
+        s = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
+        if (s < 0)
+                return -errno;
+
+        r = setsockopt(s, IPPROTO_IP, IP_TOS, &tos, sizeof(tos));
+        if (r < 0)
+                return -errno;
+
+        r = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+        if (r < 0)
+                return -errno;
+
+        if (address == INADDR_ANY) {
+                r = setsockopt(s, IPPROTO_IP, IP_PKTINFO, &on, sizeof(on));
+                if (r < 0)
+                        return -errno;
+
+                r = setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
+                if (r < 0)
+                        return -errno;
+        } else {
+                r = setsockopt(s, IPPROTO_IP, IP_FREEBIND, &on, sizeof(on));
+                if (r < 0)
+                        return -errno;
+        }
+
+        r = bind(s, &src.sa, sizeof(src.in));
+        if (r < 0)
+                return -errno;
+
+        r = s;
+        s = -1;
+
+        return r;
+}
+
+int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link,
+                                 const void *packet, size_t len) {
+        int r;
+
+        assert(link);
+        assert(packet);
+        assert(len);
+
+        r = sendto(s, packet, len, 0, &link->sa, sizeof(link->ll));
+        if (r < 0)
+                return -errno;
+
+        return 0;
+}
+
+int dhcp_network_send_udp_socket(int s, be32_t address, uint16_t port,
+                                 const void *packet, size_t len) {
+        union sockaddr_union dest = {
+                .in.sin_family = AF_INET,
+                .in.sin_port = htobe16(port),
+                .in.sin_addr.s_addr = address,
+        };
+        int r;
+
+        assert(s >= 0);
+        assert(packet);
+        assert(len);
+
+        r = sendto(s, packet, len, 0, &dest.sa, sizeof(dest.in));
+        if (r < 0)
+                return -errno;
+
+        return 0;
+}
diff --git a/src/libsystemd-network/dhcp-option.c b/src/libsystemd-network/dhcp-option.c
new file mode 100644 (file)
index 0000000..b6110c5
--- /dev/null
@@ -0,0 +1,253 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright (C) 2013 Intel Corporation. All rights reserved.
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+
+#include "dhcp-internal.h"
+
+static int option_append(uint8_t options[], size_t size, size_t *offset,
+                         uint8_t code, size_t optlen, const void *optval) {
+        assert(options);
+        assert(offset);
+
+        if (code != DHCP_OPTION_END)
+                /* always make sure there is space for an END option */
+                size --;
+
+        switch (code) {
+
+        case DHCP_OPTION_PAD:
+        case DHCP_OPTION_END:
+                if (size < *offset + 1)
+                        return -ENOBUFS;
+
+                options[*offset] = code;
+                *offset += 1;
+                break;
+
+        default:
+                if (size < *offset + optlen + 2)
+                        return -ENOBUFS;
+
+                options[*offset] = code;
+                options[*offset + 1] = optlen;
+
+                if (optlen) {
+                        assert(optval);
+
+                        memcpy(&options[*offset + 2], optval, optlen);
+                }
+
+                *offset += optlen + 2;
+
+                break;
+        }
+
+        return 0;
+}
+
+int dhcp_option_append(DHCPMessage *message, size_t size, size_t *offset,
+                       uint8_t overload,
+                       uint8_t code, size_t optlen, const void *optval) {
+        size_t file_offset = 0, sname_offset =0;
+        bool file, sname;
+        int r;
+
+        assert(message);
+        assert(offset);
+
+        file = overload & DHCP_OVERLOAD_FILE;
+        sname = overload & DHCP_OVERLOAD_SNAME;
+
+        if (*offset < size) {
+                /* still space in the options array */
+                r = option_append(message->options, size, offset, code, optlen, optval);
+                if (r >= 0)
+                        return 0;
+                else if (r == -ENOBUFS && (file || sname)) {
+                        /* did not fit, but we have more buffers to try
+                           close the options array and move the offset to its end */
+                        r = option_append(message->options, size, offset, DHCP_OPTION_END, 0, NULL);
+                        if (r < 0)
+                                return r;
+
+                        *offset = size;
+                } else
+                        return r;
+        }
+
+        if (overload & DHCP_OVERLOAD_FILE) {
+                file_offset = *offset - size;
+
+                if (file_offset < sizeof(message->file)) {
+                        /* still space in the 'file' array */
+                        r = option_append(message->file, sizeof(message->file), &file_offset, code, optlen, optval);
+                        if (r >= 0) {
+                                *offset = size + file_offset;
+                                return 0;
+                        } else if (r == -ENOBUFS && sname) {
+                                /* did not fit, but we have more buffers to try
+                                   close the file array and move the offset to its end */
+                                r = option_append(message->options, size, offset, DHCP_OPTION_END, 0, NULL);
+                                if (r < 0)
+                                        return r;
+
+                                *offset = size + sizeof(message->file);
+                        } else
+                                return r;
+                }
+        }
+
+        if (overload & DHCP_OVERLOAD_SNAME) {
+                sname_offset = *offset - size - (file ? sizeof(message->file) : 0);
+
+                if (sname_offset < sizeof(message->sname)) {
+                        /* still space in the 'sname' array */
+                        r = option_append(message->sname, sizeof(message->sname), &sname_offset, code, optlen, optval);
+                        if (r >= 0) {
+                                *offset = size + (file ? sizeof(message->file) : 0) + sname_offset;
+                                return 0;
+                        } else {
+                                /* no space, or other error, give up */
+                                return r;
+                        }
+                }
+        }
+
+        return -ENOBUFS;
+}
+
+static int parse_options(const uint8_t options[], size_t buflen, uint8_t *overload,
+                         uint8_t *message_type, dhcp_option_cb_t cb,
+                         void *user_data) {
+        uint8_t code, len;
+        size_t offset = 0;
+
+        while (offset < buflen) {
+                switch (options[offset]) {
+                case DHCP_OPTION_PAD:
+                        offset++;
+
+                        break;
+
+                case DHCP_OPTION_END:
+                        return 0;
+
+                case DHCP_OPTION_MESSAGE_TYPE:
+                        if (buflen < offset + 3)
+                                return -ENOBUFS;
+
+                        len = options[++offset];
+                        if (len != 1)
+                                return -EINVAL;
+
+                        if (message_type)
+                                *message_type = options[++offset];
+                        else
+                                offset++;
+
+                        offset++;
+
+                        break;
+
+                case DHCP_OPTION_OVERLOAD:
+                        if (buflen < offset + 3)
+                                return -ENOBUFS;
+
+                        len = options[++offset];
+                        if (len != 1)
+                                return -EINVAL;
+
+                        if (overload)
+                                *overload = options[++offset];
+                        else
+                                offset++;
+
+                        offset++;
+
+                        break;
+
+                default:
+                        if (buflen < offset + 3)
+                                return -ENOBUFS;
+
+                        code = options[offset];
+                        len = options[++offset];
+
+                        if (buflen < ++offset + len)
+                                return -EINVAL;
+
+                        if (cb)
+                                cb(code, len, &options[offset], user_data);
+
+                        offset += len;
+
+                        break;
+                }
+        }
+
+        if (offset < buflen)
+                return -EINVAL;
+
+        return 0;
+}
+
+int dhcp_option_parse(DHCPMessage *message, size_t len,
+                      dhcp_option_cb_t cb, void *user_data) {
+        uint8_t overload = 0;
+        uint8_t message_type = 0;
+        int r;
+
+        if (!message)
+                return -EINVAL;
+
+        if (len < sizeof(DHCPMessage))
+                return -EINVAL;
+
+        len -= sizeof(DHCPMessage);
+
+        r = parse_options(message->options, len, &overload, &message_type,
+                          cb, user_data);
+        if (r < 0)
+                return r;
+
+        if (overload & DHCP_OVERLOAD_FILE) {
+                r = parse_options(message->file, sizeof(message->file),
+                                NULL, &message_type, cb, user_data);
+                if (r < 0)
+                        return r;
+        }
+
+        if (overload & DHCP_OVERLOAD_SNAME) {
+                r = parse_options(message->sname, sizeof(message->sname),
+                                NULL, &message_type, cb, user_data);
+                if (r < 0)
+                        return r;
+        }
+
+        if (message_type)
+                return message_type;
+
+        return -ENOMSG;
+}
diff --git a/src/libsystemd-network/dhcp-packet.c b/src/libsystemd-network/dhcp-packet.c
new file mode 100644 (file)
index 0000000..9f850fd
--- /dev/null
@@ -0,0 +1,198 @@
+/***
+  This file is part of systemd.
+
+  Copyright (C) 2013 Intel Corporation. All rights reserved.
+  Copyright (C) 2014 Tom Gundersen
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <net/ethernet.h>
+#include <net/if_arp.h>
+#include <sys/param.h>
+
+#include "util.h"
+#include "list.h"
+
+#include "dhcp-protocol.h"
+#include "dhcp-lease-internal.h"
+#include "dhcp-internal.h"
+#include "sd-dhcp-lease.h"
+#include "sd-dhcp-client.h"
+
+#define DHCP_CLIENT_MIN_OPTIONS_SIZE            312
+
+int dhcp_message_init(DHCPMessage *message, uint8_t op, uint32_t xid,
+                      uint8_t type, size_t optlen, size_t *optoffset) {
+        size_t offset = 0;
+        int r;
+
+        assert(op == BOOTREQUEST || op == BOOTREPLY);
+
+        message->op = op;
+        message->htype = ARPHRD_ETHER;
+        message->hlen = ETHER_ADDR_LEN;
+        message->xid = htobe32(xid);
+        message->magic = htobe32(DHCP_MAGIC_COOKIE);
+
+        r = dhcp_option_append(message, optlen, &offset, 0,
+                               DHCP_OPTION_MESSAGE_TYPE, 1, &type);
+        if (r < 0)
+                return r;
+
+        *optoffset = offset;
+
+        return 0;
+}
+
+uint16_t dhcp_packet_checksum(uint8_t *buf, size_t len) {
+        uint64_t *buf_64 = (uint64_t*)buf;
+        uint64_t *end_64 = buf_64 + (len / sizeof(uint64_t));
+        uint64_t sum = 0;
+
+        /* See RFC1071 */
+
+        while (buf_64 < end_64) {
+                sum += *buf_64;
+                if (sum < *buf_64)
+                        /* wrap around in one's complement */
+                        sum++;
+
+                buf_64 ++;
+        }
+
+        if (len % sizeof(uint64_t)) {
+                /* If the buffer is not aligned to 64-bit, we need
+                   to zero-pad the last few bytes and add them in */
+                uint64_t buf_tail = 0;
+
+                memcpy(&buf_tail, buf_64, len % sizeof(uint64_t));
+
+                sum += buf_tail;
+                if (sum < buf_tail)
+                        /* wrap around */
+                        sum++;
+        }
+
+        while (sum >> 16)
+                sum = (sum & 0xffff) + (sum >> 16);
+
+        return ~sum;
+}
+
+void dhcp_packet_append_ip_headers(DHCPPacket *packet, be32_t source_addr,
+                                   uint16_t source_port, be32_t destination_addr,
+                                   uint16_t destination_port, uint16_t len) {
+        packet->ip.version = IPVERSION;
+        packet->ip.ihl = DHCP_IP_SIZE / 4;
+        packet->ip.tot_len = htobe16(len);
+
+        packet->ip.tos = IPTOS_CLASS_CS6;
+
+        packet->ip.protocol = IPPROTO_UDP;
+        packet->ip.saddr = source_addr;
+        packet->ip.daddr = destination_addr;
+
+        packet->udp.source = htobe16(source_port);
+        packet->udp.dest = htobe16(destination_port);
+
+        packet->udp.len = htobe16(len - DHCP_IP_SIZE);
+
+        packet->ip.check = packet->udp.len;
+        packet->udp.check = dhcp_packet_checksum((uint8_t*)&packet->ip.ttl, len - 8);
+
+        packet->ip.ttl = IPDEFTTL;
+        packet->ip.check = 0;
+        packet->ip.check = dhcp_packet_checksum((uint8_t*)&packet->ip, DHCP_IP_SIZE);
+}
+
+int dhcp_packet_verify_headers(DHCPPacket *packet, size_t len, bool checksum) {
+        size_t hdrlen;
+
+        assert(packet);
+
+        /* IP */
+
+        if (packet->ip.version != IPVERSION) {
+                log_debug("ignoring packet: not IPv4");
+                return -EINVAL;
+        }
+
+        if (packet->ip.ihl < 5) {
+                log_debug("ignoring packet: IPv4 IHL (%u words) invalid",
+                          packet->ip.ihl);
+                return -EINVAL;
+        }
+
+        hdrlen = packet->ip.ihl * 4;
+        if (hdrlen < 20) {
+                log_debug("ignoring packet: IPv4 IHL (%zu bytes) "
+                          "smaller than minimum (20 bytes)", hdrlen);
+                return -EINVAL;
+        }
+
+        if (len < hdrlen) {
+                log_debug("ignoring packet: packet (%zu bytes) "
+                          "smaller than expected (%zu) by IP header", len,
+                          hdrlen);
+                return -EINVAL;
+        }
+
+        /* UDP */
+
+        if (packet->ip.protocol != IPPROTO_UDP) {
+                log_debug("ignoring packet: not UDP");
+                return -EINVAL;
+        }
+
+        if (len < hdrlen + be16toh(packet->udp.len)) {
+                log_debug("ignoring packet: packet (%zu bytes) "
+                          "smaller than expected (%zu) by UDP header", len,
+                          hdrlen + be16toh(packet->udp.len));
+                return -EINVAL;
+        }
+
+        if (be16toh(packet->udp.dest) != DHCP_PORT_CLIENT) {
+                log_debug("ignoring packet: to port %u, which "
+                          "is not the DHCP client port (%u)",
+                          be16toh(packet->udp.dest), DHCP_PORT_CLIENT);
+                return -EINVAL;
+        }
+
+        /* checksums - computing these is relatively expensive, so only do it
+           if all the other checks have passed
+         */
+
+        if (dhcp_packet_checksum((uint8_t*)&packet->ip, hdrlen)) {
+                log_debug("ignoring packet: invalid IP checksum");
+                return -EINVAL;
+        }
+
+        if (checksum && packet->udp.check) {
+                packet->ip.check = packet->udp.len;
+                packet->ip.ttl = 0;
+
+                if (dhcp_packet_checksum((uint8_t*)&packet->ip.ttl,
+                                  be16toh(packet->udp.len) + 12)) {
+                        log_debug("ignoring packet: invalid UDP checksum");
+                        return -EINVAL;
+                }
+        }
+
+        return 0;
+}
similarity index 77%
rename from src/libsystemd-dhcp/dhcp-protocol.h
rename to src/libsystemd-network/dhcp-protocol.h
index 81d36ce..abca942 100644 (file)
@@ -43,6 +43,8 @@ struct DHCPMessage {
         uint8_t chaddr[16];
         uint8_t sname[64];
         uint8_t file[128];
+        be32_t magic;
+        uint8_t options[0];
 } _packed_;
 
 typedef struct DHCPMessage DHCPMessage;
@@ -58,7 +60,9 @@ typedef struct DHCPPacket DHCPPacket;
 #define DHCP_IP_SIZE            (int32_t)(sizeof(struct iphdr))
 #define DHCP_IP_UDP_SIZE        (int32_t)(sizeof(struct udphdr) + DHCP_IP_SIZE)
 #define DHCP_MESSAGE_SIZE       (int32_t)(sizeof(DHCPMessage))
-#define DHCP_MIN_OPTIONS_SIZE   312
+#define DHCP_DEFAULT_MIN_SIZE   576 /* the minimum internet hosts must be able to receive */
+#define DHCP_MIN_OPTIONS_SIZE   DHCP_DEFAULT_MIN_SIZE - DHCP_IP_UDP_SIZE - DHCP_MESSAGE_SIZE
+#define DHCP_MAGIC_COOKIE       (uint32_t)(0x63825363)
 
 enum {
         DHCP_PORT_SERVER                        = 67,
@@ -74,6 +78,7 @@ enum DHCPState {
         DHCP_STATE_BOUND                        = 5,
         DHCP_STATE_RENEWING                     = 6,
         DHCP_STATE_REBINDING                    = 7,
+        DHCP_STATE_STOPPED                      = 8,
 };
 
 typedef enum DHCPState DHCPState;
@@ -91,6 +96,8 @@ enum {
         DHCP_ACK                                = 5,
         DHCP_NAK                                = 6,
         DHCP_RELEASE                            = 7,
+        DHCP_INFORM                             = 8,
+        DHCP_FORCERENEW                         = 9,
 };
 
 enum {
@@ -101,11 +108,22 @@ enum {
 enum {
         DHCP_OPTION_PAD                         = 0,
         DHCP_OPTION_SUBNET_MASK                 = 1,
+        DHCP_OPTION_TIME_OFFSET                 = 2,
         DHCP_OPTION_ROUTER                      = 3,
         DHCP_OPTION_DOMAIN_NAME_SERVER          = 6,
         DHCP_OPTION_HOST_NAME                   = 12,
+        DHCP_OPTION_BOOT_FILE_SIZE              = 13,
         DHCP_OPTION_DOMAIN_NAME                 = 15,
+        DHCP_OPTION_ROOT_PATH                   = 17,
+        DHCP_OPTION_ENABLE_IP_FORWARDING        = 19,
+        DHCP_OPTION_ENABLE_IP_FORWARDING_NL     = 20,
+        DHCP_OPTION_POLICY_FILTER               = 21,
+        DHCP_OPTION_INTERFACE_MDR               = 22,
+        DHCP_OPTION_INTERFACE_TTL               = 23,
+        DHCP_OPTION_INTERFACE_MTU_AGING_TIMEOUT = 24,
         DHCP_OPTION_INTERFACE_MTU               = 26,
+        DHCP_OPTION_BROADCAST                   = 28,
+        DHCP_OPTION_STATIC_ROUTE                = 33,
         DHCP_OPTION_NTP_SERVER                  = 42,
         DHCP_OPTION_REQUESTED_IP_ADDRESS        = 50,
         DHCP_OPTION_IP_ADDRESS_LEASE_TIME       = 51,
@@ -116,6 +134,8 @@ enum {
         DHCP_OPTION_MAXIMUM_MESSAGE_SIZE        = 57,
         DHCP_OPTION_RENEWAL_T1_TIME             = 58,
         DHCP_OPTION_REBINDING_T2_TIME           = 59,
+        DHCP_OPTION_VENDOR_CLASS_IDENTIFIER     = 60,
         DHCP_OPTION_CLIENT_IDENTIFIER           = 61,
+        DHCP_OPTION_CLASSLESS_STATIC_ROUTE      = 121,
         DHCP_OPTION_END                         = 255,
 };
diff --git a/src/libsystemd-network/dhcp-server-internal.h b/src/libsystemd-network/dhcp-server-internal.h
new file mode 100644 (file)
index 0000000..480da22
--- /dev/null
@@ -0,0 +1,91 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright (C) 2013 Intel Corporation. All rights reserved.
+  Copyright (C) 2014 Tom Gundersen
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "sd-event.h"
+#include "sd-dhcp-server.h"
+
+#include "hashmap.h"
+#include "refcnt.h"
+#include "util.h"
+#include "log.h"
+
+#include "dhcp-internal.h"
+
+typedef struct DHCPClientId {
+        size_t length;
+        uint8_t *data;
+} DHCPClientId;
+
+typedef struct DHCPLease {
+        DHCPClientId client_id;
+
+        be32_t address;
+        be32_t gateway;
+        uint8_t chaddr[16];
+        usec_t expiration;
+} DHCPLease;
+
+struct sd_dhcp_server {
+        RefCount n_ref;
+
+        sd_event *event;
+        int event_priority;
+        sd_event_source *receive_message;
+        int fd;
+        int fd_raw;
+
+        int index;
+        be32_t address;
+        be32_t netmask;
+        be32_t pool_start;
+        size_t pool_size;
+        size_t next_offer;
+
+        Hashmap *leases_by_client_id;
+        DHCPLease **bound_leases;
+};
+
+typedef struct DHCPRequest {
+        /* received message */
+        DHCPMessage *message;
+
+        /* options */
+        DHCPClientId client_id;
+        size_t max_optlen;
+        be32_t server_id;
+        be32_t requested_ip;
+        int lifetime;
+} DHCPRequest;
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(sd_dhcp_server*, sd_dhcp_server_unref);
+#define _cleanup_dhcp_server_unref_ _cleanup_(sd_dhcp_server_unrefp)
+
+#define log_dhcp_server(client, fmt, ...) log_meta(LOG_DEBUG, __FILE__, __LINE__, __func__, "DHCP SERVER: " fmt, ##__VA_ARGS__)
+
+int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message,
+                               size_t length);
+int dhcp_server_send_packet(sd_dhcp_server *server,
+                            DHCPRequest *req, DHCPPacket *packet,
+                            int type, size_t optoffset);
+
+unsigned long client_id_hash_func(const void *p, const uint8_t hash_key[HASH_KEY_SIZE]);
+int client_id_compare_func(const void *_a, const void *_b);
diff --git a/src/libsystemd-network/dhcp6-internal.h b/src/libsystemd-network/dhcp6-internal.h
new file mode 100644 (file)
index 0000000..94e3a5d
--- /dev/null
@@ -0,0 +1,79 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright (C) 2014 Intel Corporation. All rights reserved.
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <net/ethernet.h>
+#include <netinet/in.h>
+
+#include "sparse-endian.h"
+#include "sd-event.h"
+#include "list.h"
+#include "macro.h"
+
+typedef struct DHCP6Address DHCP6Address;
+
+struct DHCP6Address {
+        LIST_FIELDS(DHCP6Address, addresses);
+
+        struct {
+                struct in6_addr address;
+                be32_t lifetime_preferred;
+                be32_t lifetime_valid;
+        } _packed_;
+};
+
+struct DHCP6IA {
+        uint16_t type;
+        struct {
+                be32_t id;
+                be32_t lifetime_t1;
+                be32_t lifetime_t2;
+        } _packed_;
+        sd_event_source *timeout_t1;
+        sd_event_source *timeout_t2;
+
+        LIST_HEAD(DHCP6Address, addresses);
+};
+
+typedef struct DHCP6IA DHCP6IA;
+
+#define log_dhcp6_client(p, fmt, ...) log_meta(LOG_DEBUG, __FILE__, __LINE__, __func__, "DHCPv6 CLIENT: " fmt, ##__VA_ARGS__)
+
+int dhcp_network_icmp6_bind_router_solicitation(int index);
+int dhcp_network_icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr);
+
+int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code,
+                        size_t optlen, const void *optval);
+int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, DHCP6IA *ia);
+int dhcp6_option_parse(uint8_t **buf, size_t *buflen, uint16_t *optcode,
+                       size_t *optlen, uint8_t **optvalue);
+int dhcp6_option_parse_ia(uint8_t **buf, size_t *buflen, uint16_t iatype,
+                          DHCP6IA *ia);
+
+int dhcp6_network_bind_udp_socket(int index, struct in6_addr *address);
+int dhcp6_network_send_udp_socket(int s, struct in6_addr *address,
+                                  const void *packet, size_t len);
+
+const char *dhcp6_message_type_to_string(int s) _const_;
+int dhcp6_message_type_from_string(const char *s) _pure_;
+const char *dhcp6_message_status_to_string(int s) _const_;
+int dhcp6_message_status_from_string(const char *s) _pure_;
diff --git a/src/libsystemd-network/dhcp6-lease-internal.h b/src/libsystemd-network/dhcp6-lease-internal.h
new file mode 100644 (file)
index 0000000..109e0f4
--- /dev/null
@@ -0,0 +1,62 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright (C) 2014 Tom Gundersen
+  Copyright (C) 2014 Intel Corporation. All rights reserved.
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdint.h>
+
+#include "refcnt.h"
+
+#include "sd-dhcp6-lease.h"
+#include "dhcp6-internal.h"
+
+struct sd_dhcp6_lease {
+        RefCount n_ref;
+
+        uint8_t *serverid;
+        size_t serverid_len;
+        uint8_t preference;
+        bool rapid_commit;
+
+        DHCP6IA ia;
+
+        DHCP6Address *addr_iter;
+};
+
+int dhcp6_lease_clear_timers(DHCP6IA *ia);
+int dhcp6_lease_ia_rebind_expire(const DHCP6IA *ia, uint32_t *expire);
+DHCP6IA *dhcp6_lease_free_ia(DHCP6IA *ia);
+
+int dhcp6_lease_set_serverid(sd_dhcp6_lease *lease, const uint8_t *id,
+                             size_t len);
+int dhcp6_lease_get_serverid(sd_dhcp6_lease *lease, uint8_t **id, size_t *len);
+int dhcp6_lease_set_preference(sd_dhcp6_lease *lease, uint8_t preference);
+int dhcp6_lease_get_preference(sd_dhcp6_lease *lease, uint8_t *preference);
+int dhcp6_lease_set_rapid_commit(sd_dhcp6_lease *lease);
+int dhcp6_lease_get_rapid_commit(sd_dhcp6_lease *lease, bool *rapid_commit);
+
+int dhcp6_lease_get_iaid(sd_dhcp6_lease *lease, be32_t *iaid);
+
+int dhcp6_lease_new(sd_dhcp6_lease **ret);
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(sd_dhcp6_lease*, sd_dhcp6_lease_unref);
+#define _cleanup_dhcp6_lease_free_ _cleanup_(sd_dhcp6_lease_unrefp)
diff --git a/src/libsystemd-network/dhcp6-network.c b/src/libsystemd-network/dhcp6-network.c
new file mode 100644 (file)
index 0000000..fe56c10
--- /dev/null
@@ -0,0 +1,194 @@
+/***
+  This file is part of systemd.
+
+  Copyright (C) 2014 Intel Corporation. All rights reserved.
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <string.h>
+#include <linux/if_packet.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <netinet/ip6.h>
+#include <netinet/icmp6.h>
+#include <netinet/in.h>
+
+#include "socket-util.h"
+
+#include "dhcp6-internal.h"
+#include "dhcp6-protocol.h"
+
+#define IN6ADDR_ALL_ROUTERS_MULTICAST_INIT \
+        { { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 } } }
+
+#define IN6ADDR_ALL_NODES_MULTICAST_INIT \
+        { { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } } }
+
+int dhcp_network_icmp6_bind_router_solicitation(int index)
+{
+        struct icmp6_filter filter = { };
+        struct ipv6_mreq mreq = {
+                .ipv6mr_multiaddr = IN6ADDR_ALL_NODES_MULTICAST_INIT,
+                .ipv6mr_interface = index,
+        };
+        _cleanup_close_ int s = -1;
+        int r, zero = 0, hops = 255;
+
+        s = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK,
+                   IPPROTO_ICMPV6);
+        if (s < 0)
+                return -errno;
+
+        ICMP6_FILTER_SETBLOCKALL(&filter);
+        ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter);
+        r = setsockopt(s, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
+                       sizeof(filter));
+        if (r < 0)
+                return -errno;
+
+        /* RFC 3315, section 6.7, bullet point 2 may indicate that an
+           IPV6_PKTINFO socket option also applies for ICMPv6 multicast.
+           Empirical experiments indicates otherwise and therefore an
+           IPV6_MULTICAST_IF socket option is used here instead */
+        r = setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_IF, &index,
+                       sizeof(index));
+        if (r < 0)
+                return -errno;
+
+        r = setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &zero,
+                       sizeof(zero));
+        if (r < 0)
+                return -errno;
+
+        r = setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &hops,
+                       sizeof(hops));
+        if (r < 0)
+                return -errno;
+
+        r = setsockopt(s, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq,
+                       sizeof(mreq));
+        if (r < 0)
+                return -errno;
+
+        r = s;
+        s = -1;
+        return r;
+}
+
+int dhcp_network_icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr)
+{
+        struct sockaddr_in6 dst = {
+                .sin6_family = AF_INET6,
+                .sin6_addr = IN6ADDR_ALL_ROUTERS_MULTICAST_INIT,
+        };
+        struct {
+                struct nd_router_solicit rs;
+                struct nd_opt_hdr rs_opt;
+                struct ether_addr rs_opt_mac;
+        } _packed_ rs = {
+                .rs.nd_rs_type = ND_ROUTER_SOLICIT,
+        };
+        struct iovec iov[1] = {
+                { &rs, },
+        };
+        struct msghdr msg = {
+                .msg_name = &dst,
+                .msg_namelen = sizeof(dst),
+                .msg_iov = iov,
+                .msg_iovlen = 1,
+        };
+        int r;
+
+        if (ether_addr) {
+                memcpy(&rs.rs_opt_mac, ether_addr, ETH_ALEN);
+                rs.rs_opt.nd_opt_type = ND_OPT_SOURCE_LINKADDR;
+                rs.rs_opt.nd_opt_len = 1;
+                iov[0].iov_len = sizeof(rs);
+        } else
+                iov[0].iov_len = sizeof(rs.rs);
+
+        r = sendmsg(s, &msg, 0);
+        if (r < 0)
+                return -errno;
+
+        return 0;
+}
+
+int dhcp6_network_bind_udp_socket(int index, struct in6_addr *local_address) {
+        struct in6_pktinfo pktinfo = {
+                .ipi6_ifindex = index,
+        };
+        union sockaddr_union src = {
+                .in6.sin6_family = AF_INET6,
+                .in6.sin6_port = htobe16(DHCP6_PORT_CLIENT),
+                .in6.sin6_addr = IN6ADDR_ANY_INIT,
+        };
+        _cleanup_close_ int s = -1;
+        int r, off = 0, on = 1;
+
+        if (local_address)
+                memcpy(&src.in6.sin6_addr, local_address,
+                       sizeof(src.in6.sin6_addr));
+
+        s = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
+                   IPPROTO_UDP);
+        if (s < 0)
+                return -errno;
+
+        r = setsockopt(s, IPPROTO_IPV6, IPV6_PKTINFO, &pktinfo,
+                       sizeof(pktinfo));
+        if (r < 0)
+                return -errno;
+
+        r = setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on));
+        if (r < 0)
+                return -errno;
+
+        r = setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &off, sizeof(off));
+        if (r < 0)
+                return -errno;
+
+        r = bind(s, &src.sa, sizeof(src.in6));
+        if (r < 0)
+                return -errno;
+
+        r = s;
+        s = -1;
+        return r;
+}
+
+int dhcp6_network_send_udp_socket(int s, struct in6_addr *server_address,
+                                  const void *packet, size_t len) {
+        union sockaddr_union dest = {
+                .in6.sin6_family = AF_INET6,
+                .in6.sin6_port = htobe16(DHCP6_PORT_SERVER),
+        };
+        int r;
+
+        assert(server_address);
+
+        memcpy(&dest.in6.sin6_addr, server_address, sizeof(dest.in6.sin6_addr));
+
+        r = sendto(s, packet, len, 0, &dest.sa, sizeof(dest.in6));
+        if (r < 0)
+                return -errno;
+
+        return 0;
+}
diff --git a/src/libsystemd-network/dhcp6-option.c b/src/libsystemd-network/dhcp6-option.c
new file mode 100644 (file)
index 0000000..e9b382c
--- /dev/null
@@ -0,0 +1,314 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright (C) 2014 Intel Corporation. All rights reserved.
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <netinet/in.h>
+#include <errno.h>
+#include <string.h>
+
+#include "sparse-endian.h"
+#include "util.h"
+
+#include "dhcp6-internal.h"
+#include "dhcp6-protocol.h"
+
+#define DHCP6_OPTION_HDR_LEN                    4
+#define DHCP6_OPTION_IA_NA_LEN                  12
+#define DHCP6_OPTION_IA_TA_LEN                  4
+#define DHCP6_OPTION_IAADDR_LEN                 24
+
+static int option_append_hdr(uint8_t **buf, size_t *buflen, uint16_t optcode,
+                             size_t optlen) {
+        assert_return(buf, -EINVAL);
+        assert_return(*buf, -EINVAL);
+        assert_return(buflen, -EINVAL);
+
+        if (optlen > 0xffff || *buflen < optlen + DHCP6_OPTION_HDR_LEN)
+                return -ENOBUFS;
+
+        (*buf)[0] = optcode >> 8;
+        (*buf)[1] = optcode & 0xff;
+        (*buf)[2] = optlen >> 8;
+        (*buf)[3] = optlen & 0xff;
+
+        *buf += DHCP6_OPTION_HDR_LEN;
+        *buflen -= DHCP6_OPTION_HDR_LEN;
+
+        return 0;
+}
+
+int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code,
+                        size_t optlen, const void *optval) {
+        int r;
+
+        assert_return(optval || optlen == 0, -EINVAL);
+
+        r = option_append_hdr(buf, buflen, code, optlen);
+        if (r < 0)
+                return r;
+
+        if (optval)
+                memcpy(*buf, optval, optlen);
+
+        *buf += optlen;
+        *buflen -= optlen;
+
+        return 0;
+}
+
+int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, DHCP6IA *ia) {
+        uint16_t len;
+        uint8_t *ia_hdr;
+        size_t ia_buflen, ia_addrlen = 0;
+        DHCP6Address *addr;
+        int r;
+
+        assert_return(buf && *buf && buflen && ia, -EINVAL);
+
+        switch (ia->type) {
+        case DHCP6_OPTION_IA_NA:
+                len = DHCP6_OPTION_IA_NA_LEN;
+                break;
+
+        case DHCP6_OPTION_IA_TA:
+                len = DHCP6_OPTION_IA_TA_LEN;
+                break;
+
+        default:
+                return -EINVAL;
+        }
+
+        if (*buflen < len)
+                return -ENOBUFS;
+
+        ia_hdr = *buf;
+        ia_buflen = *buflen;
+
+        *buf += DHCP6_OPTION_HDR_LEN;
+        *buflen -= DHCP6_OPTION_HDR_LEN;
+
+        memcpy(*buf, &ia->id, len);
+
+        *buf += len;
+        *buflen -= len;
+
+        LIST_FOREACH(addresses, addr, ia->addresses) {
+                r = option_append_hdr(buf, buflen, DHCP6_OPTION_IAADDR,
+                                      DHCP6_OPTION_IAADDR_LEN);
+                if (r < 0)
+                        return r;
+
+                memcpy(*buf, &addr->address, DHCP6_OPTION_IAADDR_LEN);
+
+                *buf += DHCP6_OPTION_IAADDR_LEN;
+                *buflen -= DHCP6_OPTION_IAADDR_LEN;
+
+                ia_addrlen += DHCP6_OPTION_HDR_LEN + DHCP6_OPTION_IAADDR_LEN;
+        }
+
+        r = option_append_hdr(&ia_hdr, &ia_buflen, ia->type, len + ia_addrlen);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+
+static int option_parse_hdr(uint8_t **buf, size_t *buflen, uint16_t *opt,
+                            size_t *optlen) {
+        uint16_t len;
+
+        assert_return(buf, -EINVAL);
+        assert_return(opt, -EINVAL);
+        assert_return(optlen, -EINVAL);
+
+        if (*buflen < 4)
+                return -ENOMSG;
+
+        len = (*buf)[2] << 8 | (*buf)[3];
+
+        if (len > *buflen)
+                return -ENOMSG;
+
+        *opt = (*buf)[0] << 8 | (*buf)[1];
+        *optlen = len;
+
+        *buf += 4;
+        *buflen -= 4;
+
+        return 0;
+}
+
+int dhcp6_option_parse(uint8_t **buf, size_t *buflen, uint16_t *optcode,
+                       size_t *optlen, uint8_t **optvalue) {
+        int r;
+
+        assert_return(buf && buflen && optcode && optlen && optvalue, -EINVAL);
+
+        r = option_parse_hdr(buf, buflen, optcode, optlen);
+        if (r < 0)
+                return r;
+
+        if (*optlen > *buflen)
+                return -ENOBUFS;
+
+        *optvalue = *buf;
+        *buflen -= *optlen;
+        *buf += *optlen;
+
+        return 0;
+}
+
+int dhcp6_option_parse_ia(uint8_t **buf, size_t *buflen, uint16_t iatype,
+                          DHCP6IA *ia) {
+        int r;
+        uint16_t opt, status;
+        size_t optlen;
+        size_t iaaddr_offset;
+        DHCP6Address *addr;
+        uint32_t lt_t1, lt_t2, lt_valid, lt_pref, lt_min = ~0;
+
+        assert_return(ia, -EINVAL);
+        assert_return(!ia->addresses, -EINVAL);
+
+        switch (iatype) {
+        case DHCP6_OPTION_IA_NA:
+
+                if (*buflen < DHCP6_OPTION_IA_NA_LEN + DHCP6_OPTION_HDR_LEN +
+                    DHCP6_OPTION_IAADDR_LEN) {
+                        r = -ENOBUFS;
+                        goto error;
+                }
+
+                iaaddr_offset = DHCP6_OPTION_IA_NA_LEN;
+                memcpy(&ia->id, *buf, iaaddr_offset);
+
+                lt_t1 = be32toh(ia->lifetime_t1);
+                lt_t2 = be32toh(ia->lifetime_t2);
+
+                if (lt_t1 && lt_t2 && lt_t1 > lt_t2) {
+                        log_dhcp6_client(client, "IA T1 %ds > T2 %ds",
+                                         lt_t1, lt_t2);
+                        r = -EINVAL;
+                        goto error;
+                }
+
+                break;
+
+        case DHCP6_OPTION_IA_TA:
+                if (*buflen < DHCP6_OPTION_IA_TA_LEN + DHCP6_OPTION_HDR_LEN +
+                    DHCP6_OPTION_IAADDR_LEN) {
+                        r = -ENOBUFS;
+                        goto error;
+                }
+
+                iaaddr_offset = DHCP6_OPTION_IA_TA_LEN;
+                memcpy(&ia->id, *buf, iaaddr_offset);
+
+                ia->lifetime_t1 = 0;
+                ia->lifetime_t2 = 0;
+
+                break;
+
+        default:
+                r = -ENOMSG;
+                goto error;
+        }
+
+        ia->type = iatype;
+
+        *buflen -= iaaddr_offset;
+        *buf += iaaddr_offset;
+
+        while ((r = option_parse_hdr(buf, buflen, &opt, &optlen)) >= 0) {
+
+                switch (opt) {
+                case DHCP6_OPTION_IAADDR:
+
+                        addr = new0(DHCP6Address, 1);
+                        if (!addr) {
+                                r = -ENOMEM;
+                                goto error;
+                        }
+
+                        LIST_INIT(addresses, addr);
+
+                        memcpy(&addr->address, *buf, DHCP6_OPTION_IAADDR_LEN);
+
+                        lt_valid = be32toh(addr->lifetime_valid);
+                        lt_pref = be32toh(addr->lifetime_valid);
+
+                        if (!lt_valid || lt_pref > lt_valid) {
+                                log_dhcp6_client(client, "IA preferred %ds > valid %ds",
+                                                 lt_pref, lt_valid);
+                                free(addr);
+                        } else {
+                                LIST_PREPEND(addresses, ia->addresses, addr);
+                                if (lt_valid < lt_min)
+                                        lt_min = lt_valid;
+                        }
+
+                        break;
+
+                case DHCP6_OPTION_STATUS_CODE:
+                        if (optlen < sizeof(status))
+                                break;
+
+                        status = (*buf)[0] << 8 | (*buf)[1];
+                        if (status) {
+                                log_dhcp6_client(client, "IA status %d",
+                                                 status);
+                                r = -EINVAL;
+                                goto error;
+                        }
+
+                        break;
+
+                default:
+                        log_dhcp6_client(client, "Unknown IA option %d", opt);
+                        break;
+                }
+
+                *buflen -= optlen;
+                *buf += optlen;
+        }
+
+        if (r == -ENOMSG)
+                r = 0;
+
+        if (!ia->lifetime_t1 && !ia->lifetime_t2) {
+                lt_t1 = lt_min / 2;
+                lt_t2 = lt_min / 10 * 8;
+                ia->lifetime_t1 = htobe32(lt_t1);
+                ia->lifetime_t2 = htobe32(lt_t2);
+
+                log_dhcp6_client(client, "Computed IA T1 %ds and T2 %ds as both were zero",
+                                 lt_t1, lt_t2);
+        }
+
+        if (*buflen)
+                r = -ENOMSG;
+
+error:
+        *buf += *buflen;
+        *buflen = 0;
+
+        return r;
+}
diff --git a/src/libsystemd-network/dhcp6-protocol.h b/src/libsystemd-network/dhcp6-protocol.h
new file mode 100644 (file)
index 0000000..eaa6717
--- /dev/null
@@ -0,0 +1,141 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright (C) 2014 Intel Corporation. All rights reserved.
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <netinet/ip6.h>
+#include <netinet/udp.h>
+
+#include "macro.h"
+#include "sparse-endian.h"
+
+struct DHCP6Message {
+        union {
+                struct {
+                        uint8_t type;
+                        uint8_t _pad[3];
+                } _packed_;
+                be32_t transaction_id;
+        };
+} _packed_;
+
+typedef struct DHCP6Message DHCP6Message;
+
+#define DHCP6_MIN_OPTIONS_SIZE \
+        1280 - sizeof(struct ip6_hdr) - sizeof(struct udphdr)
+
+#define IN6ADDR_ALL_DHCP6_RELAY_AGENTS_AND_SERVERS_INIT \
+        { { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+              0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02 } } }
+
+enum {
+        DHCP6_PORT_SERVER                       = 547,
+        DHCP6_PORT_CLIENT                       = 546,
+};
+
+#define DHCP6_SOL_MAX_DELAY                     1 * USEC_PER_SEC
+#define DHCP6_SOL_TIMEOUT                       1 * USEC_PER_SEC
+#define DHCP6_SOL_MAX_RT                        120 * USEC_PER_SEC
+#define DHCP6_REQ_TIMEOUT                       1 * USEC_PER_SEC
+#define DHCP6_REQ_MAX_RT                        120 * USEC_PER_SEC
+#define DHCP6_REQ_MAX_RC                        10
+#define DHCP6_REN_TIMEOUT                       10 * USEC_PER_SEC
+#define DHCP6_REN_MAX_RT                        600 * USEC_PER_SEC
+#define DHCP6_REB_TIMEOUT                       10 * USEC_PER_SEC
+#define DHCP6_REB_MAX_RT                        600 * USEC_PER_SEC
+
+enum {
+        DHCP6_DUID_LLT                          = 1,
+        DHCP6_DUID_EN                           = 2,
+        DHCP6_DUID_LL                           = 3,
+        DHCP6_DUID_UUID                         = 4,
+};
+
+enum DHCP6State {
+        DHCP6_STATE_STOPPED                     = 0,
+        DHCP6_STATE_SOLICITATION                = 2,
+        DHCP6_STATE_REQUEST                     = 3,
+        DHCP6_STATE_BOUND                       = 4,
+        DHCP6_STATE_RENEW                       = 5,
+        DHCP6_STATE_REBIND                      = 6,
+};
+
+enum {
+        DHCP6_SOLICIT                           = 1,
+        DHCP6_ADVERTISE                         = 2,
+        DHCP6_REQUEST                           = 3,
+        DHCP6_CONFIRM                           = 4,
+        DHCP6_RENEW                             = 5,
+        DHCP6_REBIND                            = 6,
+        DHCP6_REPLY                             = 7,
+        DHCP6_RELEASE                           = 8,
+        DHCP6_DECLINE                           = 9,
+        DHCP6_RECONFIGURE                       = 10,
+        DHCP6_INFORMATION_REQUEST               = 11,
+        DHCP6_RELAY_FORW                        = 12,
+        DHCP6_RELAY_REPL                        = 13,
+        _DHCP6_MESSAGE_MAX                      = 14,
+};
+
+enum {
+        DHCP6_OPTION_CLIENTID                   = 1,
+        DHCP6_OPTION_SERVERID                   = 2,
+        DHCP6_OPTION_IA_NA                      = 3,
+        DHCP6_OPTION_IA_TA                      = 4,
+        DHCP6_OPTION_IAADDR                     = 5,
+        DHCP6_OPTION_ORO                        = 6,
+        DHCP6_OPTION_PREFERENCE                 = 7,
+        DHCP6_OPTION_ELAPSED_TIME               = 8,
+        DHCP6_OPTION_RELAY_MSG                  = 9,
+        /* option code 10 is unassigned */
+        DHCP6_OPTION_AUTH                       = 11,
+        DHCP6_OPTION_UNICAST                    = 12,
+        DHCP6_OPTION_STATUS_CODE                = 13,
+        DHCP6_OPTION_RAPID_COMMIT               = 14,
+        DHCP6_OPTION_USER_CLASS                 = 15,
+        DHCP6_OPTION_VENDOR_CLASS               = 16,
+        DHCP6_OPTION_VENDOR_OPTS                = 17,
+        DHCP6_OPTION_INTERFACE_ID               = 18,
+        DHCP6_OPTION_RECONF_MSG                 = 19,
+        DHCP6_OPTION_RECONF_ACCEPT              = 20,
+
+        DHCP6_OPTION_DNS_SERVERS                = 23,  /* RFC 3646 */
+        DHCP6_OPTION_DOMAIN_LIST                = 24,  /* RFC 3646 */
+
+        DHCP6_OPTION_SNTP_SERVERS               = 31,  /* RFC 4075 */
+
+        /* option code 35 is unassigned */
+
+        DHCP6_OPTION_NTP_SERVER                 = 56,  /* RFC 5908 */
+
+        /* option codes 89-142 are unassigned */
+        /* option codes 144-65535 are unassigned */
+};
+
+enum {
+        DHCP6_STATUS_SUCCESS                    = 0,
+        DHCP6_STATUS_UNSPEC_FAIL                = 1,
+        DHCP6_STATUS_NO_ADDRS_AVAIL             = 2,
+        DHCP6_STATUS_NO_BINDING                 = 3,
+        DHCP6_STATUS_NOT_ON_LINK                = 4,
+        DHCP6_STATUS_USE_MULTICAST              = 5,
+        _DHCP6_STATUS_MAX                       = 6,
+};
diff --git a/src/libsystemd-network/ipv4ll-internal.h b/src/libsystemd-network/ipv4ll-internal.h
new file mode 100644 (file)
index 0000000..fe5ef8e
--- /dev/null
@@ -0,0 +1,38 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright (C) 2014 Axis Communications AB. All rights reserved.
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <netinet/if_ether.h>
+
+#include "sparse-endian.h"
+#include "socket-util.h"
+
+int arp_network_bind_raw_socket(int index, union sockaddr_union *link);
+int arp_network_send_raw_socket(int fd, const union sockaddr_union *link,
+                                        const struct ether_arp *arp);
+
+void arp_packet_init(struct ether_arp *arp);
+void arp_packet_probe(struct ether_arp *arp, be32_t pa, const struct ether_addr *ha);
+void arp_packet_announcement(struct ether_arp *arp, be32_t pa, const struct ether_addr *ha);
+int arp_packet_verify_headers(struct ether_arp *arp);
+
+#define log_ipv4ll(ll, fmt, ...) log_meta(LOG_DEBUG, __FILE__, __LINE__, __func__, "IPv4LL: " fmt, ##__VA_ARGS__)
diff --git a/src/libsystemd-network/ipv4ll-network.c b/src/libsystemd-network/ipv4ll-network.c
new file mode 100644 (file)
index 0000000..93ffed4
--- /dev/null
@@ -0,0 +1,91 @@
+/***
+  This file is part of systemd.
+
+  Copyright (C) 2014 Axis Communications AB. All rights reserved.
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <linux/filter.h>
+
+#include "util.h"
+#include "ipv4ll-internal.h"
+
+int arp_network_send_raw_socket(int fd, const union sockaddr_union *link,
+                                        const struct ether_arp *arp) {
+        int r;
+
+        assert(arp);
+        assert(link);
+        assert(fd >= 0);
+
+        r = sendto(fd, arp, sizeof(struct ether_arp), 0, &link->sa, sizeof(link->ll));
+        if (r < 0)
+                return -errno;
+
+        return 0;
+}
+
+int arp_network_bind_raw_socket(int ifindex, union sockaddr_union *link) {
+
+        static const struct sock_filter filter[] = {
+                BPF_STMT(BPF_LD + BPF_W + BPF_LEN, 0),                                         /* A <- packet length */
+                BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, sizeof(struct ether_arp), 1, 0),           /* packet >= arp packet ? */
+                BPF_STMT(BPF_RET + BPF_K, 0),                                                  /* ignore */
+                BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(struct ether_arp, ea_hdr.ar_hrd)), /* A <- header */
+                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ARPHRD_ETHER, 1, 0),                       /* header == ethernet ? */
+                BPF_STMT(BPF_RET + BPF_K, 0),                                                  /* ignore */
+                BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(struct ether_arp, ea_hdr.ar_pro)), /* A <- protocol */
+                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_IP, 1, 0),                       /* protocol == IP ? */
+                BPF_STMT(BPF_RET + BPF_K, 0),                                                  /* ignore */
+                BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(struct ether_arp, ea_hdr.ar_op)),  /* A <- operation */
+                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ARPOP_REQUEST, 0, 1),                      /* protocol == request ? */
+                BPF_STMT(BPF_RET + BPF_K, 65535),                                              /* return all */
+                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ARPOP_REPLY, 0, 1),                        /* protocol == reply ? */
+                BPF_STMT(BPF_RET + BPF_K, 65535),                                              /* return all */
+                BPF_STMT(BPF_RET + BPF_K, 0),                                                  /* ignore */
+        };
+        struct sock_fprog fprog = {
+                .len = ELEMENTSOF(filter),
+                .filter = (struct sock_filter*) filter
+        };
+        _cleanup_close_ int s = -1;
+        int r;
+
+        assert(ifindex > 0);
+        assert(link);
+
+        s = socket(PF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
+        if (s < 0)
+                return -errno;
+
+        r = setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER, &fprog, sizeof(fprog));
+        if (r < 0)
+                return -errno;
+
+        link->ll.sll_family = AF_PACKET;
+        link->ll.sll_protocol = htons(ETH_P_ARP);
+        link->ll.sll_ifindex = ifindex;
+        link->ll.sll_halen = ETH_ALEN;
+        memset(link->ll.sll_addr, 0xff, ETH_ALEN);
+
+        r = bind(s, &link->sa, sizeof(link->ll));
+        if (r < 0)
+                return -errno;
+
+        r = s;
+        s = -1;
+
+        return r;
+}
diff --git a/src/libsystemd-network/ipv4ll-packet.c b/src/libsystemd-network/ipv4ll-packet.c
new file mode 100644 (file)
index 0000000..2b6c73a
--- /dev/null
@@ -0,0 +1,71 @@
+/***
+  This file is part of systemd.
+
+  Copyright (C) 2014 Axis Communications AB. All rights reserved.
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+#include <arpa/inet.h>
+
+#include "util.h"
+#include "ipv4ll-internal.h"
+
+void arp_packet_init(struct ether_arp *arp) {
+        assert(arp);
+
+        memzero(arp, sizeof(struct ether_arp));
+        /* Header */
+        arp->ea_hdr.ar_hrd = htons(ARPHRD_ETHER); /* HTYPE */
+        arp->ea_hdr.ar_pro = htons(ETHERTYPE_IP); /* PTYPE */
+        arp->ea_hdr.ar_hln = ETH_ALEN; /* HLEN */
+        arp->ea_hdr.ar_pln = sizeof arp->arp_spa; /* PLEN */
+        arp->ea_hdr.ar_op = htons(ARPOP_REQUEST); /* REQUEST */
+}
+
+void arp_packet_probe(struct ether_arp *arp, be32_t pa, const struct ether_addr *ha) {
+        assert(ha);
+
+        arp_packet_init(arp);
+        memcpy(arp->arp_sha, ha, ETH_ALEN);
+        memcpy(arp->arp_tpa, &pa, sizeof(pa));
+}
+
+void arp_packet_announcement(struct ether_arp *arp, be32_t pa, const struct ether_addr *ha) {
+        assert(ha);
+
+        arp_packet_init(arp);
+        memcpy(arp->arp_sha, ha, ETH_ALEN);
+        memcpy(arp->arp_tpa, &pa, sizeof(pa));
+        memcpy(arp->arp_spa, &pa, sizeof(pa));
+}
+
+int arp_packet_verify_headers(struct ether_arp *arp) {
+        assert(arp);
+
+        if (arp->ea_hdr.ar_hrd != htons(ARPHRD_ETHER)) {
+                log_ipv4ll(NULL, "ignoring packet: header is not ARPHRD_ETHER");
+                return -EINVAL;
+        }
+        if (arp->ea_hdr.ar_pro != htons(ETHERTYPE_IP)) {
+                log_ipv4ll(NULL, "ignoring packet: protocol is not ETHERTYPE_IP");
+                return -EINVAL;
+        }
+        if (arp->ea_hdr.ar_op != htons(ARPOP_REQUEST) &&
+            arp->ea_hdr.ar_op != htons(ARPOP_REPLY)) {
+                log_ipv4ll(NULL, "ignoring packet: operation is not ARPOP_REQUEST or ARPOP_REPLY");
+                return -EINVAL;
+        }
+
+        return 0;
+}
similarity index 52%
rename from src/shared/net-util.c
rename to src/libsystemd-network/network-internal.c
index 50cfa2c..208c314 100644 (file)
 #include <arpa/inet.h>
 #include <fnmatch.h>
 
-#include "net-util.h"
+#include "strv.h"
+#include "siphash24.h"
+#include "libudev-private.h"
+#include "dhcp-lease-internal.h"
 #include "log.h"
 #include "utf8.h"
 #include "util.h"
 #include "conf-parser.h"
 #include "condition.h"
+#include "network-internal.h"
+
+const char *net_get_name(struct udev_device *device) {
+        const char *name, *field;
+
+        assert(device);
+
+        /* fetch some persistent data unique (on this machine) to this device */
+        FOREACH_STRING(field, "ID_NET_NAME_ONBOARD", "ID_NET_NAME_SLOT", "ID_NET_NAME_PATH", "ID_NET_NAME_MAC") {
+                name = udev_device_get_property_value(device, field);
+                if (name)
+                        return name;
+        }
+
+        return NULL;
+}
+
+#define HASH_KEY SD_ID128_MAKE(d3,1e,48,fa,90,fe,4b,4c,9d,af,d5,d7,a1,b1,2e,8a)
+
+int net_get_unique_predictable_data(struct udev_device *device, uint8_t result[8]) {
+        size_t l, sz = 0;
+        const char *name = NULL;
+        int r;
+        uint8_t *v;
+
+        assert(device);
+
+        name = net_get_name(device);
+        if (!name)
+                return -ENOENT;
+
+        l = strlen(name);
+        sz = sizeof(sd_id128_t) + l;
+        v = alloca(sz);
+
+        /* fetch some persistent data unique to this machine */
+        r = sd_id128_get_machine((sd_id128_t*) v);
+        if (r < 0)
+                 return r;
+        memcpy(v + sizeof(sd_id128_t), name, l);
+
+        /* Let's hash the machine ID plus the device name. We
+        * use a fixed, but originally randomly created hash
+        * key here. */
+        siphash24(result, v, sz, HASH_KEY.bytes);
+
+        return 0;
+}
 
 bool net_match_config(const struct ether_addr *match_mac,
                       const char *match_path,
@@ -40,7 +91,7 @@ bool net_match_config(const struct ether_addr *match_mac,
                       Condition *match_virt,
                       Condition *match_kernel,
                       Condition *match_arch,
-                      const char *dev_mac,
+                      const struct ether_addr *dev_mac,
                       const char *dev_path,
                       const char *dev_parent_driver,
                       const char *dev_driver,
@@ -59,7 +110,7 @@ bool net_match_config(const struct ether_addr *match_mac,
         if (match_arch && !condition_test_architecture(match_arch))
                 return 0;
 
-        if (match_mac && (!dev_mac || memcmp(match_mac, ether_aton(dev_mac), ETH_ALEN)))
+        if (match_mac && (!dev_mac || memcmp(match_mac, dev_mac, ETH_ALEN)))
                 return 0;
 
         if (match_path && (!dev_path || fnmatch(match_path, dev_path, 0)))
@@ -81,12 +132,6 @@ bool net_match_config(const struct ether_addr *match_mac,
         return 1;
 }
 
-unsigned net_netmask_to_prefixlen(const struct in_addr *addr) {
-        assert(addr);
-
-        return 32 - u32ctz(be32toh(addr->s_addr));
-}
-
 int config_parse_net_condition(const char *unit,
                                const char *filename,
                                unsigned line,
@@ -140,7 +185,7 @@ int config_parse_ifname(const char *unit,
                         void *userdata) {
 
         char **s = data;
-        char *n;
+        _cleanup_free_ char *n = NULL;
 
         assert(filename);
         assert(lvalue);
@@ -159,12 +204,11 @@ int config_parse_ifname(const char *unit,
         }
 
         free(*s);
-        if (*n)
+        if (*n) {
                 *s = n;
-        else {
-                free(n);
+                n = NULL;
+        } else
                 *s = NULL;
-        }
 
         return 0;
 }
@@ -253,37 +297,175 @@ int config_parse_hwaddr(const char *unit,
         return 0;
 }
 
-int net_parse_inaddr(const char *address, unsigned char *family, void *dst) {
-        int r;
+void serialize_in_addrs(FILE *f, const struct in_addr *addresses, size_t size) {
+        unsigned i;
 
-        assert(address);
-        assert(family);
-        assert(dst);
-
-        /* IPv4 */
-        r = inet_pton(AF_INET, address, dst);
-        if (r > 0) {
-                /* succsefully parsed IPv4 address */
-                if (*family == AF_UNSPEC)
-                        *family = AF_INET;
-                else if (*family != AF_INET)
-                        return -EINVAL;
-        } else  if (r < 0)
-                return -errno;
-        else {
-                /* not an IPv4 address, so let's try IPv6 */
-                r = inet_pton(AF_INET6, address, dst);
-                if (r > 0) {
-                        /* successfully parsed IPv6 address */
-                        if (*family == AF_UNSPEC)
-                                *family = AF_INET6;
-                        else if (*family != AF_INET6)
-                                return -EINVAL;
-                } else if (r < 0)
-                        return -errno;
+        assert(f);
+        assert(addresses);
+        assert(size);
+
+        for (i = 0; i < size; i++)
+                fprintf(f, "%s%s", inet_ntoa(addresses[i]),
+                        (i < (size - 1)) ? " ": "");
+}
+
+int deserialize_in_addrs(struct in_addr **ret, const char *string) {
+        _cleanup_free_ struct in_addr *addresses = NULL;
+        int size = 0;
+        const char *word, *state;
+        size_t len;
+
+        assert(ret);
+        assert(string);
+
+        FOREACH_WORD(word, len, string, state) {
+                _cleanup_free_ char *addr_str = NULL;
+                struct in_addr *new_addresses;
+                int r;
+
+                new_addresses = realloc(addresses, (size + 1) * sizeof(struct in_addr));
+                if (!new_addresses)
+                        return -ENOMEM;
+                else
+                        addresses = new_addresses;
+
+                addr_str = strndup(word, len);
+                if (!addr_str)
+                        return -ENOMEM;
+
+                r = inet_pton(AF_INET, addr_str, &(addresses[size]));
+                if (r <= 0)
+                        continue;
+
+                size ++;
+        }
+
+        *ret = addresses;
+        addresses = NULL;
+
+        return size;
+}
+
+int deserialize_in6_addrs(struct in6_addr **ret, const char *string) {
+        _cleanup_free_ struct in6_addr *addresses = NULL;
+        int size = 0;
+        const char *word, *state;
+        size_t len;
+
+        assert(ret);
+        assert(string);
+
+        FOREACH_WORD(word, len, string, state) {
+                _cleanup_free_ char *addr_str = NULL;
+                struct in6_addr *new_addresses;
+                int r;
+
+                new_addresses = realloc(addresses, (size + 1) * sizeof(struct in6_addr));
+                if (!new_addresses)
+                        return -ENOMEM;
                 else
-                        return -EINVAL;
+                        addresses = new_addresses;
+
+                addr_str = strndup(word, len);
+                if (!addr_str)
+                        return -ENOMEM;
+
+                r = inet_pton(AF_INET6, addr_str, &(addresses[size]));
+                if (r <= 0)
+                        continue;
+
+                size++;
         }
 
+        *ret = addresses;
+        addresses = NULL;
+
+        return size;
+}
+
+void serialize_dhcp_routes(FILE *f, const char *key, struct sd_dhcp_route *routes, size_t size) {
+        unsigned i;
+
+        assert(f);
+        assert(key);
+        assert(routes);
+        assert(size);
+
+        fprintf(f, "%s=", key);
+
+        for (i = 0; i < size; i++)
+                fprintf(f, "%s/%" PRIu8 ",%s%s", inet_ntoa(routes[i].dst_addr),
+                        routes[i].dst_prefixlen, inet_ntoa(routes[i].gw_addr),
+                        (i < (size - 1)) ? " ": "");
+
+        fputs("\n", f);
+}
+
+int deserialize_dhcp_routes(struct sd_dhcp_route **ret, size_t *ret_size, size_t *ret_allocated, const char *string) {
+        _cleanup_free_ struct sd_dhcp_route *routes = NULL;
+        size_t size = 0, allocated = 0;
+        const char *word, *state;
+        size_t len;
+
+        assert(ret);
+        assert(ret_size);
+        assert(ret_allocated);
+        assert(string);
+
+        FOREACH_WORD(word, len, string, state) {
+                /* WORD FORMAT: dst_ip/dst_prefixlen,gw_ip */
+                _cleanup_free_ char* entry = NULL;
+                char *tok, *tok_end;
+                unsigned n;
+                int r;
+
+                if (!GREEDY_REALLOC(routes, allocated, size + 1))
+                        return -ENOMEM;
+
+                entry = strndup(word, len);
+                if(!entry)
+                        return -ENOMEM;
+
+                tok = entry;
+
+                /* get the subnet */
+                tok_end = strchr(tok, '/');
+                if (!tok_end)
+                        continue;
+                *tok_end = '\0';
+
+                r = inet_aton(tok, &routes[size].dst_addr);
+                if (r == 0)
+                        continue;
+
+                tok = tok_end + 1;
+
+                /* get the prefixlen */
+                tok_end = strchr(tok, ',');
+                if (!tok_end)
+                        continue;
+
+                *tok_end = '\0';
+
+                r = safe_atou(tok, &n);
+                if (r < 0 || n > 32)
+                        continue;
+
+                routes[size].dst_prefixlen = (uint8_t) n;
+                tok = tok_end + 1;
+
+                /* get the gateway */
+                r = inet_aton(tok, &routes[size].gw_addr);
+                if (r == 0)
+                        continue;
+
+                size++;
+        }
+
+        *ret_size = size;
+        *ret_allocated = allocated;
+        *ret = routes;
+        routes = NULL;
+
         return 0;
 }
similarity index 76%
rename from src/shared/net-util.h
rename to src/libsystemd-network/network-internal.h
index 99479e1..49387d0 100644 (file)
@@ -1,5 +1,7 @@
 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
 
+#pragma once
+
 /***
  This file is part of systemd.
 
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
-#pragma once
-
 #include <netinet/ether.h>
 #include <netinet/in.h>
 #include <stdbool.h>
 
+#include "udev.h"
 #include "condition-util.h"
 
 bool net_match_config(const struct ether_addr *match_mac,
@@ -36,15 +37,13 @@ bool net_match_config(const struct ether_addr *match_mac,
                       Condition *match_virt,
                       Condition *match_kernel,
                       Condition *match_arch,
-                      const char *dev_mac,
+                      const struct ether_addr *dev_mac,
                       const char *dev_path,
                       const char *dev_parent_driver,
                       const char *dev_driver,
                       const char *dev_type,
                       const char *dev_name);
 
-unsigned net_netmask_to_prefixlen(const struct in_addr *netmask);
-
 int config_parse_net_condition(const char *unit, const char *filename, unsigned line,
                                const char *section, unsigned section_line, const char *lvalue,
                                int ltype, const char *rvalue, void *data, void *userdata);
@@ -61,4 +60,15 @@ int config_parse_ifalias(const char *unit, const char *filename, unsigned line,
                          const char *section, unsigned section_line, const char *lvalue,
                          int ltype, const char *rvalue, void *data, void *userdata);
 
-int net_parse_inaddr(const char *address, unsigned char *family, void *dst);
+int net_get_unique_predictable_data(struct udev_device *device, uint8_t result[8]);
+const char *net_get_name(struct udev_device *device);
+
+void serialize_in_addrs(FILE *f, const struct in_addr *addresses, size_t size);
+int deserialize_in_addrs(struct in_addr **addresses, const char *string);
+int deserialize_in6_addrs(struct in6_addr **addresses, const char *string);
+
+/* don't include "dhcp-lease-internal.h" as it causes conflicts between netinet/ip.h and linux/ip.h */
+struct sd_dhcp_route;
+
+void serialize_dhcp_routes(FILE *f, const char *key, struct sd_dhcp_route *routes, size_t size);
+int deserialize_dhcp_routes(struct sd_dhcp_route **ret, size_t *ret_size, size_t *ret_allocated, const char *string);
diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c
new file mode 100644 (file)
index 0000000..8a9887d
--- /dev/null
@@ -0,0 +1,1545 @@
+/***
+  This file is part of systemd.
+
+  Copyright (C) 2013 Intel Corporation. All rights reserved.
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <net/ethernet.h>
+#include <net/if_arp.h>
+#include <netinet/ether.h>
+#include <sys/param.h>
+#include <sys/ioctl.h>
+
+#include "util.h"
+#include "list.h"
+#include "refcnt.h"
+#include "async.h"
+
+#include "dhcp-protocol.h"
+#include "dhcp-internal.h"
+#include "dhcp-lease-internal.h"
+#include "sd-dhcp-client.h"
+
+struct sd_dhcp_client {
+        RefCount n_ref;
+
+        DHCPState state;
+        sd_event *event;
+        int event_priority;
+        sd_event_source *timeout_resend;
+        int index;
+        int fd;
+        union sockaddr_union link;
+        sd_event_source *receive_message;
+        bool request_broadcast;
+        uint8_t *req_opts;
+        size_t req_opts_allocated;
+        size_t req_opts_size;
+        be32_t last_addr;
+        struct {
+                uint8_t type;
+                struct ether_addr mac_addr;
+        } _packed_ client_id;
+        char *hostname;
+        char *vendor_class_identifier;
+        uint32_t mtu;
+        uint32_t xid;
+        usec_t start_time;
+        uint16_t secs;
+        unsigned int attempt;
+        usec_t request_sent;
+        sd_event_source *timeout_t1;
+        sd_event_source *timeout_t2;
+        sd_event_source *timeout_expire;
+        sd_dhcp_client_cb_t cb;
+        void *userdata;
+        sd_dhcp_lease *lease;
+};
+
+static const uint8_t default_req_opts[] = {
+        DHCP_OPTION_SUBNET_MASK,
+        DHCP_OPTION_ROUTER,
+        DHCP_OPTION_HOST_NAME,
+        DHCP_OPTION_DOMAIN_NAME,
+        DHCP_OPTION_DOMAIN_NAME_SERVER,
+        DHCP_OPTION_NTP_SERVER,
+};
+
+static int client_receive_message_raw(sd_event_source *s, int fd,
+                                      uint32_t revents, void *userdata);
+static int client_receive_message_udp(sd_event_source *s, int fd,
+                                      uint32_t revents, void *userdata);
+static void client_stop(sd_dhcp_client *client, int error);
+
+int sd_dhcp_client_set_callback(sd_dhcp_client *client, sd_dhcp_client_cb_t cb,
+                                void *userdata) {
+        assert_return(client, -EINVAL);
+
+        client->cb = cb;
+        client->userdata = userdata;
+
+        return 0;
+}
+
+int sd_dhcp_client_set_request_broadcast(sd_dhcp_client *client, int broadcast) {
+        assert_return(client, -EINVAL);
+
+        client->request_broadcast = !!broadcast;
+
+        return 0;
+}
+
+int sd_dhcp_client_set_request_option(sd_dhcp_client *client, uint8_t option) {
+        size_t i;
+
+        assert_return(client, -EINVAL);
+        assert_return (IN_SET(client->state, DHCP_STATE_INIT,
+                              DHCP_STATE_STOPPED), -EBUSY);
+
+        switch(option) {
+        case DHCP_OPTION_PAD:
+        case DHCP_OPTION_OVERLOAD:
+        case DHCP_OPTION_MESSAGE_TYPE:
+        case DHCP_OPTION_PARAMETER_REQUEST_LIST:
+        case DHCP_OPTION_END:
+                return -EINVAL;
+
+        default:
+                break;
+        }
+
+        for (i = 0; i < client->req_opts_size; i++)
+                if (client->req_opts[i] == option)
+                        return -EEXIST;
+
+        if (!GREEDY_REALLOC(client->req_opts, client->req_opts_allocated,
+                            client->req_opts_size + 1))
+                return -ENOMEM;
+
+        client->req_opts[client->req_opts_size++] = option;
+
+        return 0;
+}
+
+int sd_dhcp_client_set_request_address(sd_dhcp_client *client,
+                                       const struct in_addr *last_addr) {
+        assert_return(client, -EINVAL);
+        assert_return (IN_SET(client->state, DHCP_STATE_INIT,
+                              DHCP_STATE_STOPPED), -EBUSY);
+
+        if (last_addr)
+                client->last_addr = last_addr->s_addr;
+        else
+                client->last_addr = INADDR_ANY;
+
+        return 0;
+}
+
+int sd_dhcp_client_set_index(sd_dhcp_client *client, int interface_index) {
+        assert_return(client, -EINVAL);
+        assert_return (IN_SET(client->state, DHCP_STATE_INIT,
+                              DHCP_STATE_STOPPED), -EBUSY);
+        assert_return(interface_index > 0, -EINVAL);
+
+        client->index = interface_index;
+
+        return 0;
+}
+
+int sd_dhcp_client_set_mac(sd_dhcp_client *client,
+                           const struct ether_addr *addr) {
+        DHCP_CLIENT_DONT_DESTROY(client);
+        bool need_restart = false;
+
+        assert_return(client, -EINVAL);
+        assert_return(addr, -EINVAL);
+
+        if (memcmp(&client->client_id.mac_addr, addr, ETH_ALEN) == 0)
+                return 0;
+
+        if (!IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED)) {
+                log_dhcp_client(client, "Changing MAC address on running DHCP "
+                                "client, restarting");
+                need_restart = true;
+                client_stop(client, DHCP_EVENT_STOP);
+        }
+
+        memcpy(&client->client_id.mac_addr, addr, ETH_ALEN);
+        client->client_id.type = 0x01;
+
+        if (need_restart && client->state != DHCP_STATE_STOPPED)
+                sd_dhcp_client_start(client);
+
+        return 0;
+}
+
+int sd_dhcp_client_set_hostname(sd_dhcp_client *client,
+                                const char *hostname) {
+        char *new_hostname = NULL;
+
+        assert_return(client, -EINVAL);
+
+        if (streq_ptr(client->hostname, hostname))
+                return 0;
+
+        if (hostname) {
+                new_hostname = strdup(hostname);
+                if (!new_hostname)
+                        return -ENOMEM;
+        }
+
+        free(client->hostname);
+        client->hostname = new_hostname;
+
+        return 0;
+}
+
+int sd_dhcp_client_set_vendor_class_identifier(sd_dhcp_client *client,
+                                               const char *vci) {
+        char *new_vci = NULL;
+
+        assert_return(client, -EINVAL);
+
+        new_vci = strdup(vci);
+        if (!new_vci)
+                return -ENOMEM;
+
+        free(client->vendor_class_identifier);
+
+        client->vendor_class_identifier = new_vci;
+
+        return 0;
+}
+
+int sd_dhcp_client_set_mtu(sd_dhcp_client *client, uint32_t mtu) {
+        assert_return(client, -EINVAL);
+        assert_return(mtu >= DHCP_DEFAULT_MIN_SIZE, -ERANGE);
+
+        client->mtu = mtu;
+
+        return 0;
+}
+
+int sd_dhcp_client_get_lease(sd_dhcp_client *client, sd_dhcp_lease **ret) {
+        assert_return(client, -EINVAL);
+        assert_return(ret, -EINVAL);
+
+        if (client->state != DHCP_STATE_BOUND &&
+            client->state != DHCP_STATE_RENEWING &&
+            client->state != DHCP_STATE_REBINDING)
+                return -EADDRNOTAVAIL;
+
+        *ret = sd_dhcp_lease_ref(client->lease);
+
+        return 0;
+}
+
+static void client_notify(sd_dhcp_client *client, int event) {
+        if (client->cb)
+                client->cb(client, event, client->userdata);
+}
+
+static int client_initialize(sd_dhcp_client *client) {
+        assert_return(client, -EINVAL);
+
+        client->receive_message =
+                sd_event_source_unref(client->receive_message);
+
+        client->fd = asynchronous_close(client->fd);
+
+        client->timeout_resend = sd_event_source_unref(client->timeout_resend);
+
+        client->timeout_t1 = sd_event_source_unref(client->timeout_t1);
+        client->timeout_t2 = sd_event_source_unref(client->timeout_t2);
+        client->timeout_expire = sd_event_source_unref(client->timeout_expire);
+
+        client->attempt = 1;
+
+        client->state = DHCP_STATE_INIT;
+        client->xid = 0;
+
+        if (client->lease)
+                client->lease = sd_dhcp_lease_unref(client->lease);
+
+        return 0;
+}
+
+static void client_stop(sd_dhcp_client *client, int error) {
+        assert(client);
+
+        if (error < 0)
+                log_dhcp_client(client, "STOPPED: %s", strerror(-error));
+        else if (error == DHCP_EVENT_STOP)
+                log_dhcp_client(client, "STOPPED");
+        else
+                log_dhcp_client(client, "STOPPED: Unknown event");
+
+        client_notify(client, error);
+
+        client_initialize(client);
+}
+
+static int client_message_init(sd_dhcp_client *client, DHCPPacket **ret,
+                               uint8_t type, size_t *_optlen, size_t *_optoffset) {
+        _cleanup_free_ DHCPPacket *packet;
+        size_t optlen, optoffset, size;
+        be16_t max_size;
+        int r;
+
+        assert(client);
+        assert(client->secs);
+        assert(ret);
+        assert(_optlen);
+        assert(_optoffset);
+        assert(type == DHCP_DISCOVER || type == DHCP_REQUEST);
+
+        optlen = DHCP_MIN_OPTIONS_SIZE;
+        size = sizeof(DHCPPacket) + optlen;
+
+        packet = malloc0(size);
+        if (!packet)
+                return -ENOMEM;
+
+        r = dhcp_message_init(&packet->dhcp, BOOTREQUEST, client->xid, type,
+                              optlen, &optoffset);
+        if (r < 0)
+                return r;
+
+        /* Although 'secs' field is a SHOULD in RFC 2131, certain DHCP servers
+           refuse to issue an DHCP lease if 'secs' is set to zero */
+        packet->dhcp.secs = htobe16(client->secs);
+
+        /* RFC2132 section 4.1
+           A client that cannot receive unicast IP datagrams until its protocol
+           software has been configured with an IP address SHOULD set the
+           BROADCAST bit in the 'flags' field to 1 in any DHCPDISCOVER or
+           DHCPREQUEST messages that client sends.  The BROADCAST bit will
+           provide a hint to the DHCP server and BOOTP relay agent to broadcast
+           any messages to the client on the client's subnet.
+
+           Note: some interfaces needs this to be enabled, but some networks
+           needs this to be disabled as broadcasts are filteretd, so this
+           needs to be configurable */
+        if (client->request_broadcast)
+                packet->dhcp.flags = htobe16(0x8000);
+
+        /* RFC2132 section 4.1.1:
+           The client MUST include its hardware address in the ’chaddr’ field, if
+           necessary for delivery of DHCP reply messages.
+         */
+        memcpy(&packet->dhcp.chaddr, &client->client_id.mac_addr, ETH_ALEN);
+
+        /* Some DHCP servers will refuse to issue an DHCP lease if the Client
+           Identifier option is not set */
+        r = dhcp_option_append(&packet->dhcp, optlen, &optoffset, 0,
+                               DHCP_OPTION_CLIENT_IDENTIFIER,
+                               sizeof(client->client_id), &client->client_id);
+        if (r < 0)
+                return r;
+
+
+        /* RFC2131 section 3.5:
+           in its initial DHCPDISCOVER or DHCPREQUEST message, a
+           client may provide the server with a list of specific
+           parameters the client is interested in. If the client
+           includes a list of parameters in a DHCPDISCOVER message,
+           it MUST include that list in any subsequent DHCPREQUEST
+           messages.
+         */
+        r = dhcp_option_append(&packet->dhcp, optlen, &optoffset, 0,
+                               DHCP_OPTION_PARAMETER_REQUEST_LIST,
+                               client->req_opts_size, client->req_opts);
+        if (r < 0)
+                return r;
+
+        /* RFC2131 section 3.5:
+           The client SHOULD include the ’maximum DHCP message size’ option to
+           let the server know how large the server may make its DHCP messages.
+
+           Note (from ConnMan): Some DHCP servers will send bigger DHCP packets
+           than the defined default size unless the Maximum Messge Size option
+           is explicitely set
+
+           RFC3442 "Requirements to Avoid Sizing Constraints":
+           Because a full routing table can be quite large, the standard 576
+           octet maximum size for a DHCP message may be too short to contain
+           some legitimate Classless Static Route options.  Because of this,
+           clients implementing the Classless Static Route option SHOULD send a
+           Maximum DHCP Message Size [4] option if the DHCP client's TCP/IP
+           stack is capable of receiving larger IP datagrams.  In this case, the
+           client SHOULD set the value of this option to at least the MTU of the
+           interface that the client is configuring.  The client MAY set the
+           value of this option higher, up to the size of the largest UDP packet
+           it is prepared to accept.  (Note that the value specified in the
+           Maximum DHCP Message Size option is the total maximum packet size,
+           including IP and UDP headers.)
+         */
+        max_size = htobe16(size);
+        r = dhcp_option_append(&packet->dhcp, client->mtu, &optoffset, 0,
+                               DHCP_OPTION_MAXIMUM_MESSAGE_SIZE,
+                               2, &max_size);
+        if (r < 0)
+                return r;
+
+        *_optlen = optlen;
+        *_optoffset = optoffset;
+        *ret = packet;
+        packet = NULL;
+
+        return 0;
+}
+
+static int dhcp_client_send_raw(sd_dhcp_client *client, DHCPPacket *packet,
+                                size_t len) {
+        dhcp_packet_append_ip_headers(packet, INADDR_ANY, DHCP_PORT_CLIENT,
+                                      INADDR_BROADCAST, DHCP_PORT_SERVER, len);
+
+        return dhcp_network_send_raw_socket(client->fd, &client->link,
+                                            packet, len);
+}
+
+static int client_send_discover(sd_dhcp_client *client) {
+        _cleanup_free_ DHCPPacket *discover = NULL;
+        size_t optoffset, optlen;
+        usec_t time_now;
+        int r;
+
+        assert(client);
+        assert(client->state == DHCP_STATE_INIT ||
+               client->state == DHCP_STATE_SELECTING);
+
+        /* See RFC2131 section 4.4.1 */
+
+        r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now);
+        if (r < 0)
+                return r;
+        assert(time_now >= client->start_time);
+
+        /* seconds between sending first and last DISCOVER
+         * must always be strictly positive to deal with broken servers */
+        client->secs = ((time_now - client->start_time) / USEC_PER_SEC) ? : 1;
+
+        r = client_message_init(client, &discover, DHCP_DISCOVER,
+                                &optlen, &optoffset);
+        if (r < 0)
+                return r;
+
+        /* the client may suggest values for the network address
+           and lease time in the DHCPDISCOVER message. The client may include
+           the ’requested IP address’ option to suggest that a particular IP
+           address be assigned, and may include the ’IP address lease time’
+           option to suggest the lease time it would like.
+         */
+        if (client->last_addr != INADDR_ANY) {
+                r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
+                                       DHCP_OPTION_REQUESTED_IP_ADDRESS,
+                                       4, &client->last_addr);
+                if (r < 0)
+                        return r;
+        }
+
+        /* it is unclear from RFC 2131 if client should send hostname in
+           DHCPDISCOVER but dhclient does and so we do as well
+        */
+        if (client->hostname) {
+                r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
+                                       DHCP_OPTION_HOST_NAME,
+                                       strlen(client->hostname), client->hostname);
+                if (r < 0)
+                        return r;
+        }
+
+        if (client->vendor_class_identifier) {
+                r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
+                                       DHCP_OPTION_VENDOR_CLASS_IDENTIFIER,
+                                       strlen(client->vendor_class_identifier),
+                                       client->vendor_class_identifier);
+                if (r < 0)
+                        return r;
+        }
+
+        r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
+                               DHCP_OPTION_END, 0, NULL);
+        if (r < 0)
+                return r;
+
+        /* We currently ignore:
+           The client SHOULD wait a random time between one and ten seconds to
+           desynchronize the use of DHCP at startup.
+         */
+        r = dhcp_client_send_raw(client, discover, sizeof(DHCPPacket) + optoffset);
+        if (r < 0)
+                return r;
+
+        log_dhcp_client(client, "DISCOVER");
+
+        return 0;
+}
+
+static int client_send_request(sd_dhcp_client *client) {
+        _cleanup_free_ DHCPPacket *request = NULL;
+        size_t optoffset, optlen;
+        int r;
+
+        r = client_message_init(client, &request, DHCP_REQUEST,
+                                &optlen, &optoffset);
+        if (r < 0)
+                return r;
+
+        switch (client->state) {
+        /* See RFC2131 section 4.3.2 (note that there is a typo in the RFC,
+           SELECTING should be REQUESTING)
+         */
+
+        case DHCP_STATE_REQUESTING:
+                /* Client inserts the address of the selected server in ’server
+                   identifier’, ’ciaddr’ MUST be zero, ’requested IP address’ MUST be
+                   filled in with the yiaddr value from the chosen DHCPOFFER.
+                 */
+
+                r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
+                                       DHCP_OPTION_SERVER_IDENTIFIER,
+                                       4, &client->lease->server_address);
+                if (r < 0)
+                        return r;
+
+                r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
+                                       DHCP_OPTION_REQUESTED_IP_ADDRESS,
+                                       4, &client->lease->address);
+                if (r < 0)
+                        return r;
+
+                break;
+
+        case DHCP_STATE_INIT_REBOOT:
+                /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
+                   option MUST be filled in with client’s notion of its previously
+                   assigned address. ’ciaddr’ MUST be zero.
+                 */
+                r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
+                                       DHCP_OPTION_REQUESTED_IP_ADDRESS,
+                                       4, &client->last_addr);
+                if (r < 0)
+                        return r;
+                break;
+
+        case DHCP_STATE_RENEWING:
+                /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
+                   option MUST NOT be filled in, ’ciaddr’ MUST be filled in with
+                   client’s IP address.
+                */
+
+                /* fall through */
+        case DHCP_STATE_REBINDING:
+                /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
+                   option MUST NOT be filled in, ’ciaddr’ MUST be filled in with
+                   client’s IP address.
+
+                   This message MUST be broadcast to the 0xffffffff IP broadcast address.
+                 */
+                request->dhcp.ciaddr = client->lease->address;
+
+                break;
+
+        case DHCP_STATE_INIT:
+        case DHCP_STATE_SELECTING:
+        case DHCP_STATE_REBOOTING:
+        case DHCP_STATE_BOUND:
+        case DHCP_STATE_STOPPED:
+                return -EINVAL;
+        }
+
+        if (client->hostname) {
+                r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
+                                       DHCP_OPTION_HOST_NAME,
+                                       strlen(client->hostname), client->hostname);
+                if (r < 0)
+                        return r;
+        }
+
+        r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
+                               DHCP_OPTION_END, 0, NULL);
+        if (r < 0)
+                return r;
+
+        if (client->state == DHCP_STATE_RENEWING) {
+                r = dhcp_network_send_udp_socket(client->fd,
+                                                 client->lease->server_address,
+                                                 DHCP_PORT_SERVER,
+                                                 &request->dhcp,
+                                                 sizeof(DHCPMessage) + optoffset);
+        } else {
+                r = dhcp_client_send_raw(client, request, sizeof(DHCPPacket) + optoffset);
+        }
+        if (r < 0)
+                return r;
+
+        switch (client->state) {
+        case DHCP_STATE_REQUESTING:
+                log_dhcp_client(client, "REQUEST (requesting)");
+                break;
+        case DHCP_STATE_INIT_REBOOT:
+                log_dhcp_client(client, "REQUEST (init-reboot)");
+                break;
+        case DHCP_STATE_RENEWING:
+                log_dhcp_client(client, "REQUEST (renewing)");
+                break;
+        case DHCP_STATE_REBINDING:
+                log_dhcp_client(client, "REQUEST (rebinding)");
+                break;
+        default:
+                log_dhcp_client(client, "REQUEST (invalid)");
+                break;
+        }
+
+        return 0;
+}
+
+static int client_start(sd_dhcp_client *client);
+
+static int client_timeout_resend(sd_event_source *s, uint64_t usec,
+                                 void *userdata) {
+        sd_dhcp_client *client = userdata;
+        DHCP_CLIENT_DONT_DESTROY(client);
+        usec_t next_timeout = 0;
+        uint64_t time_now;
+        uint32_t time_left;
+        int r;
+
+        assert(s);
+        assert(client);
+        assert(client->event);
+
+        r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now);
+        if (r < 0)
+                goto error;
+
+        switch (client->state) {
+        case DHCP_STATE_RENEWING:
+
+                time_left = (client->lease->t2 - client->lease->t1) / 2;
+                if (time_left < 60)
+                        time_left = 60;
+
+                next_timeout = time_now + time_left * USEC_PER_SEC;
+
+                break;
+
+        case DHCP_STATE_REBINDING:
+
+                time_left = (client->lease->lifetime - client->lease->t2) / 2;
+                if (time_left < 60)
+                        time_left = 60;
+
+                next_timeout = time_now + time_left * USEC_PER_SEC;
+                break;
+
+        case DHCP_STATE_REBOOTING:
+                /* start over as we did not receive a timely ack or nak */
+                r = client_initialize(client);
+                if (r < 0)
+                        goto error;
+
+                r = client_start(client);
+                if (r < 0)
+                        goto error;
+                else {
+                        log_dhcp_client(client, "REBOOTED");
+                        return 0;
+                }
+
+        case DHCP_STATE_INIT:
+        case DHCP_STATE_INIT_REBOOT:
+        case DHCP_STATE_SELECTING:
+        case DHCP_STATE_REQUESTING:
+        case DHCP_STATE_BOUND:
+
+                if (client->attempt < 64)
+                        client->attempt *= 2;
+
+                next_timeout = time_now + (client->attempt - 1) * USEC_PER_SEC;
+
+                break;
+
+        case DHCP_STATE_STOPPED:
+                r = -EINVAL;
+                goto error;
+        }
+
+        next_timeout += (random_u32() & 0x1fffff);
+
+        client->timeout_resend = sd_event_source_unref(client->timeout_resend);
+
+        r = sd_event_add_time(client->event,
+                              &client->timeout_resend,
+                              clock_boottime_or_monotonic(),
+                              next_timeout, 10 * USEC_PER_MSEC,
+                              client_timeout_resend, client);
+        if (r < 0)
+                goto error;
+
+        r = sd_event_source_set_priority(client->timeout_resend,
+                                         client->event_priority);
+        if (r < 0)
+                goto error;
+
+        switch (client->state) {
+        case DHCP_STATE_INIT:
+                r = client_send_discover(client);
+                if (r >= 0) {
+                        client->state = DHCP_STATE_SELECTING;
+                        client->attempt = 1;
+                } else {
+                        if (client->attempt >= 64)
+                                goto error;
+                }
+
+                break;
+
+        case DHCP_STATE_SELECTING:
+                r = client_send_discover(client);
+                if (r < 0 && client->attempt >= 64)
+                        goto error;
+
+                break;
+
+        case DHCP_STATE_INIT_REBOOT:
+        case DHCP_STATE_REQUESTING:
+        case DHCP_STATE_RENEWING:
+        case DHCP_STATE_REBINDING:
+                r = client_send_request(client);
+                if (r < 0 && client->attempt >= 64)
+                         goto error;
+
+                if (client->state == DHCP_STATE_INIT_REBOOT)
+                        client->state = DHCP_STATE_REBOOTING;
+
+                client->request_sent = time_now;
+
+                break;
+
+        case DHCP_STATE_REBOOTING:
+        case DHCP_STATE_BOUND:
+
+                break;
+
+        case DHCP_STATE_STOPPED:
+                r = -EINVAL;
+                goto error;
+        }
+
+        return 0;
+
+error:
+        client_stop(client, r);
+
+        /* Errors were dealt with when stopping the client, don't spill
+           errors into the event loop handler */
+        return 0;
+}
+
+static int client_initialize_io_events(sd_dhcp_client *client,
+                                       sd_event_io_handler_t io_callback) {
+        int r;
+
+        assert(client);
+        assert(client->event);
+
+        r = sd_event_add_io(client->event, &client->receive_message,
+                            client->fd, EPOLLIN, io_callback,
+                            client);
+        if (r < 0)
+                goto error;
+
+        r = sd_event_source_set_priority(client->receive_message,
+                                         client->event_priority);
+        if (r < 0)
+                goto error;
+
+error:
+        if (r < 0)
+                client_stop(client, r);
+
+        return 0;
+}
+
+static int client_initialize_time_events(sd_dhcp_client *client) {
+        int r;
+
+        assert(client);
+        assert(client->event);
+
+        client->timeout_resend = sd_event_source_unref(client->timeout_resend);
+
+        r = sd_event_add_time(client->event,
+                              &client->timeout_resend,
+                              clock_boottime_or_monotonic(),
+                              0, 0,
+                              client_timeout_resend, client);
+        if (r < 0)
+                goto error;
+
+        r = sd_event_source_set_priority(client->timeout_resend,
+                                         client->event_priority);
+
+error:
+        if (r < 0)
+                client_stop(client, r);
+
+        return 0;
+
+}
+
+static int client_initialize_events(sd_dhcp_client *client,
+                                    sd_event_io_handler_t io_callback) {
+        client_initialize_io_events(client, io_callback);
+        client_initialize_time_events(client);
+
+        return 0;
+}
+
+static int client_start(sd_dhcp_client *client) {
+        int r;
+
+        assert_return(client, -EINVAL);
+        assert_return(client->event, -EINVAL);
+        assert_return(client->index > 0, -EINVAL);
+        assert_return(client->fd < 0, -EBUSY);
+        assert_return(client->xid == 0, -EINVAL);
+        assert_return(client->state == DHCP_STATE_INIT ||
+                      client->state == DHCP_STATE_INIT_REBOOT, -EBUSY);
+
+        client->xid = random_u32();
+
+        r = dhcp_network_bind_raw_socket(client->index, &client->link, client->xid, client->client_id.mac_addr);
+        if (r < 0) {
+                client_stop(client, r);
+                return r;
+        }
+        client->fd = r;
+
+        if (client->state == DHCP_STATE_INIT) {
+                client->start_time = now(clock_boottime_or_monotonic());
+                client->secs = 0;
+        }
+
+        return client_initialize_events(client, client_receive_message_raw);
+}
+
+static int client_timeout_expire(sd_event_source *s, uint64_t usec,
+                                 void *userdata) {
+        sd_dhcp_client *client = userdata;
+        DHCP_CLIENT_DONT_DESTROY(client);
+
+        log_dhcp_client(client, "EXPIRED");
+
+        client_notify(client, DHCP_EVENT_EXPIRED);
+
+        /* lease was lost, start over if not freed or stopped in callback */
+        if (client->state != DHCP_STATE_STOPPED) {
+                client_initialize(client);
+                client_start(client);
+        }
+
+        return 0;
+}
+
+static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata) {
+        sd_dhcp_client *client = userdata;
+        DHCP_CLIENT_DONT_DESTROY(client);
+        int r;
+
+        client->receive_message = sd_event_source_unref(client->receive_message);
+        client->fd = asynchronous_close(client->fd);
+
+        client->state = DHCP_STATE_REBINDING;
+        client->attempt = 1;
+
+        r = dhcp_network_bind_raw_socket(client->index, &client->link, client->xid, client->client_id.mac_addr);
+        if (r < 0) {
+                client_stop(client, r);
+                return 0;
+        }
+        client->fd = r;
+
+        return client_initialize_events(client, client_receive_message_raw);
+}
+
+static int client_timeout_t1(sd_event_source *s, uint64_t usec,
+                             void *userdata) {
+        sd_dhcp_client *client = userdata;
+        DHCP_CLIENT_DONT_DESTROY(client);
+
+        client->state = DHCP_STATE_RENEWING;
+        client->attempt = 1;
+
+        return client_initialize_time_events(client);
+}
+
+static int client_handle_offer(sd_dhcp_client *client, DHCPMessage *offer,
+                               size_t len) {
+        _cleanup_dhcp_lease_unref_ sd_dhcp_lease *lease = NULL;
+        int r;
+
+        r = dhcp_lease_new(&lease);
+        if (r < 0)
+                return r;
+
+        r = dhcp_option_parse(offer, len, dhcp_lease_parse_options, lease);
+        if (r != DHCP_OFFER) {
+                log_dhcp_client(client, "receieved message was not an OFFER, ignoring");
+                return -ENOMSG;
+        }
+
+        lease->next_server = offer->siaddr;
+
+        lease->address = offer->yiaddr;
+
+        if (lease->address == INADDR_ANY ||
+            lease->server_address == INADDR_ANY ||
+            lease->lifetime == 0) {
+                log_dhcp_client(client, "receieved lease lacks address, server "
+                                "address or lease lifetime, ignoring");
+                return -ENOMSG;
+        }
+
+        if (lease->subnet_mask == INADDR_ANY) {
+                r = dhcp_lease_set_default_subnet_mask(lease);
+                if (r < 0) {
+                        log_dhcp_client(client, "receieved lease lacks subnet "
+                                        "mask, and a fallback one can not be "
+                                        "generated, ignoring");
+                        return -ENOMSG;
+                }
+        }
+
+        sd_dhcp_lease_unref(client->lease);
+        client->lease = lease;
+        lease = NULL;
+
+        log_dhcp_client(client, "OFFER");
+
+        return 0;
+}
+
+static int client_handle_forcerenew(sd_dhcp_client *client, DHCPMessage *force,
+                                    size_t len) {
+        int r;
+
+        r = dhcp_option_parse(force, len, NULL, NULL);
+        if (r != DHCP_FORCERENEW)
+                return -ENOMSG;
+
+        log_dhcp_client(client, "FORCERENEW");
+
+        return 0;
+}
+
+static int client_handle_ack(sd_dhcp_client *client, DHCPMessage *ack,
+                             size_t len) {
+        _cleanup_dhcp_lease_unref_ sd_dhcp_lease *lease = NULL;
+        int r;
+
+        r = dhcp_lease_new(&lease);
+        if (r < 0)
+                return r;
+
+        r = dhcp_option_parse(ack, len, dhcp_lease_parse_options, lease);
+        if (r == DHCP_NAK) {
+                log_dhcp_client(client, "NAK");
+                return -EADDRNOTAVAIL;
+        }
+
+        if (r != DHCP_ACK) {
+                log_dhcp_client(client, "receieved message was not an ACK, ignoring");
+                return -ENOMSG;
+        }
+
+        lease->next_server = ack->siaddr;
+
+        lease->address = ack->yiaddr;
+
+        if (lease->address == INADDR_ANY ||
+            lease->server_address == INADDR_ANY ||
+            lease->lifetime == 0) {
+                log_dhcp_client(client, "receieved lease lacks address, server "
+                                "address or lease lifetime, ignoring");
+                return -ENOMSG;
+        }
+
+        if (lease->subnet_mask == INADDR_ANY) {
+                r = dhcp_lease_set_default_subnet_mask(lease);
+                if (r < 0) {
+                        log_dhcp_client(client, "receieved lease lacks subnet "
+                                        "mask, and a fallback one can not be "
+                                        "generated, ignoring");
+                        return -ENOMSG;
+                }
+        }
+
+        r = DHCP_EVENT_IP_ACQUIRE;
+        if (client->lease) {
+                if (client->lease->address != lease->address ||
+                    client->lease->subnet_mask != lease->subnet_mask ||
+                    client->lease->router != lease->router) {
+                        r = DHCP_EVENT_IP_CHANGE;
+                } else
+                        r = DHCP_EVENT_RENEW;
+
+                client->lease = sd_dhcp_lease_unref(client->lease);
+        }
+
+        client->lease = lease;
+        lease = NULL;
+
+        log_dhcp_client(client, "ACK");
+
+        return r;
+}
+
+static uint64_t client_compute_timeout(sd_dhcp_client *client,
+                                       uint32_t lifetime, double factor) {
+        assert(client);
+        assert(client->request_sent);
+        assert(lifetime);
+
+        return client->request_sent + ((lifetime - 3) * USEC_PER_SEC * factor) +
+                + (random_u32() & 0x1fffff);
+}
+
+static int client_set_lease_timeouts(sd_dhcp_client *client) {
+        usec_t time_now;
+        uint64_t lifetime_timeout;
+        uint64_t t2_timeout;
+        uint64_t t1_timeout;
+        char time_string[FORMAT_TIMESPAN_MAX];
+        int r;
+
+        assert(client);
+        assert(client->event);
+        assert(client->lease);
+        assert(client->lease->lifetime);
+
+        client->timeout_t1 = sd_event_source_unref(client->timeout_t1);
+        client->timeout_t2 = sd_event_source_unref(client->timeout_t2);
+        client->timeout_expire = sd_event_source_unref(client->timeout_expire);
+
+        /* don't set timers for infinite leases */
+        if (client->lease->lifetime == 0xffffffff)
+                return 0;
+
+        r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now);
+        if (r < 0)
+                return r;
+        assert(client->request_sent <= time_now);
+
+        /* convert the various timeouts from relative (secs) to absolute (usecs) */
+        lifetime_timeout = client_compute_timeout(client, client->lease->lifetime, 1);
+        if (client->lease->t1 && client->lease->t2) {
+                /* both T1 and T2 are given */
+                if (client->lease->t1 < client->lease->t2 &&
+                    client->lease->t2 < client->lease->lifetime) {
+                        /* they are both valid */
+                        t2_timeout = client_compute_timeout(client, client->lease->t2, 1);
+                        t1_timeout = client_compute_timeout(client, client->lease->t1, 1);
+                } else {
+                        /* discard both */
+                        t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
+                        client->lease->t2 = (client->lease->lifetime * 7) / 8;
+                        t1_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
+                        client->lease->t1 = client->lease->lifetime / 2;
+                }
+        } else if (client->lease->t2 && client->lease->t2 < client->lease->lifetime) {
+                /* only T2 is given, and it is valid */
+                t2_timeout = client_compute_timeout(client, client->lease->t2, 1);
+                t1_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
+                client->lease->t1 = client->lease->lifetime / 2;
+                if (t2_timeout <= t1_timeout) {
+                        /* the computed T1 would be invalid, so discard T2 */
+                        t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
+                        client->lease->t2 = (client->lease->lifetime * 7) / 8;
+                }
+        } else if (client->lease->t1 && client->lease->t1 < client->lease->lifetime) {
+                /* only T1 is given, and it is valid */
+                t1_timeout = client_compute_timeout(client, client->lease->t1, 1);
+                t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
+                client->lease->t2 = (client->lease->lifetime * 7) / 8;
+                if (t2_timeout <= t1_timeout) {
+                        /* the computed T2 would be invalid, so discard T1 */
+                        t2_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
+                        client->lease->t2 = client->lease->lifetime / 2;
+                }
+        } else {
+                /* fall back to the default timeouts */
+                t1_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
+                client->lease->t1 = client->lease->lifetime / 2;
+                t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
+                client->lease->t2 = (client->lease->lifetime * 7) / 8;
+        }
+
+        /* arm lifetime timeout */
+        r = sd_event_add_time(client->event, &client->timeout_expire,
+                              clock_boottime_or_monotonic(),
+                              lifetime_timeout, 10 * USEC_PER_MSEC,
+                              client_timeout_expire, client);
+        if (r < 0)
+                return r;
+
+        r = sd_event_source_set_priority(client->timeout_expire,
+                                         client->event_priority);
+        if (r < 0)
+                return r;
+
+        log_dhcp_client(client, "lease expires in %s",
+                        format_timespan(time_string, FORMAT_TIMESPAN_MAX,
+                        lifetime_timeout - time_now, 0));
+
+        /* don't arm earlier timeouts if this has already expired */
+        if (lifetime_timeout <= time_now)
+                return 0;
+
+        /* arm T2 timeout */
+        r = sd_event_add_time(client->event,
+                              &client->timeout_t2,
+                              clock_boottime_or_monotonic(),
+                              t2_timeout,
+                              10 * USEC_PER_MSEC,
+                              client_timeout_t2, client);
+        if (r < 0)
+                return r;
+
+        r = sd_event_source_set_priority(client->timeout_t2,
+                                         client->event_priority);
+        if (r < 0)
+                return r;
+
+        log_dhcp_client(client, "T2 expires in %s",
+                        format_timespan(time_string, FORMAT_TIMESPAN_MAX,
+                        t2_timeout - time_now, 0));
+
+        /* don't arm earlier timeout if this has already expired */
+        if (t2_timeout <= time_now)
+                return 0;
+
+        /* arm T1 timeout */
+        r = sd_event_add_time(client->event,
+                              &client->timeout_t1,
+                              clock_boottime_or_monotonic(),
+                              t1_timeout, 10 * USEC_PER_MSEC,
+                              client_timeout_t1, client);
+        if (r < 0)
+                return r;
+
+        r = sd_event_source_set_priority(client->timeout_t1,
+                                         client->event_priority);
+        if (r < 0)
+                return r;
+
+        log_dhcp_client(client, "T1 expires in %s",
+                        format_timespan(time_string, FORMAT_TIMESPAN_MAX,
+                        t1_timeout - time_now, 0));
+
+        return 0;
+}
+
+static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message,
+                                 int len) {
+        DHCP_CLIENT_DONT_DESTROY(client);
+        int r = 0, notify_event = 0;
+
+        assert(client);
+        assert(client->event);
+        assert(message);
+
+        switch (client->state) {
+        case DHCP_STATE_SELECTING:
+
+                r = client_handle_offer(client, message, len);
+                if (r >= 0) {
+
+                        client->timeout_resend =
+                                sd_event_source_unref(client->timeout_resend);
+
+                        client->state = DHCP_STATE_REQUESTING;
+                        client->attempt = 1;
+
+                        r = sd_event_add_time(client->event,
+                                              &client->timeout_resend,
+                                              clock_boottime_or_monotonic(),
+                                              0, 0,
+                                              client_timeout_resend, client);
+                        if (r < 0)
+                                goto error;
+
+                        r = sd_event_source_set_priority(client->timeout_resend,
+                                                         client->event_priority);
+                        if (r < 0)
+                                goto error;
+                } else if (r == -ENOMSG)
+                        /* invalid message, let's ignore it */
+                        return 0;
+
+                break;
+
+        case DHCP_STATE_REBOOTING:
+        case DHCP_STATE_REQUESTING:
+        case DHCP_STATE_RENEWING:
+        case DHCP_STATE_REBINDING:
+
+                r = client_handle_ack(client, message, len);
+                if (r >= 0) {
+                        client->timeout_resend =
+                                sd_event_source_unref(client->timeout_resend);
+
+                        if (IN_SET(client->state, DHCP_STATE_REQUESTING,
+                                   DHCP_STATE_REBOOTING))
+                                notify_event = DHCP_EVENT_IP_ACQUIRE;
+                        else if (r != DHCP_EVENT_IP_ACQUIRE)
+                                notify_event = r;
+
+                        client->state = DHCP_STATE_BOUND;
+                        client->attempt = 1;
+
+                        client->last_addr = client->lease->address;
+
+                        r = client_set_lease_timeouts(client);
+                        if (r < 0)
+                                goto error;
+
+                        r = dhcp_network_bind_udp_socket(client->lease->address,
+                                                         DHCP_PORT_CLIENT);
+                        if (r < 0) {
+                                log_dhcp_client(client, "could not bind UDP socket");
+                                goto error;
+                        }
+
+                        client->fd = r;
+
+                        client_initialize_io_events(client, client_receive_message_udp);
+
+                        if (notify_event) {
+                                client_notify(client, notify_event);
+                                if (client->state == DHCP_STATE_STOPPED)
+                                        return 0;
+                        }
+
+                } else if (r == -EADDRNOTAVAIL) {
+                        /* got a NAK, let's restart the client */
+                        client->timeout_resend =
+                                sd_event_source_unref(client->timeout_resend);
+
+                        r = client_initialize(client);
+                        if (r < 0)
+                                goto error;
+
+                        r = client_start(client);
+                        if (r < 0)
+                                goto error;
+
+                        log_dhcp_client(client, "REBOOTED");
+
+                        return 0;
+                } else if (r == -ENOMSG)
+                        /* invalid message, let's ignore it */
+                        return 0;
+
+                break;
+
+        case DHCP_STATE_BOUND:
+                r = client_handle_forcerenew(client, message, len);
+                if (r >= 0) {
+                        r = client_timeout_t1(NULL, 0, client);
+                        if (r < 0)
+                                goto error;
+                } else if (r == -ENOMSG)
+                        /* invalid message, let's ignore it */
+                        return 0;
+
+                break;
+
+        case DHCP_STATE_INIT:
+        case DHCP_STATE_INIT_REBOOT:
+
+                break;
+
+        case DHCP_STATE_STOPPED:
+                r = -EINVAL;
+                goto error;
+        }
+
+error:
+        if (r < 0)
+                client_stop(client, r);
+
+        return r;
+}
+
+static int client_receive_message_udp(sd_event_source *s, int fd,
+                                      uint32_t revents, void *userdata) {
+        sd_dhcp_client *client = userdata;
+        _cleanup_free_ DHCPMessage *message = NULL;
+        int buflen = 0, len, r;
+
+        assert(s);
+        assert(client);
+
+        r = ioctl(fd, FIONREAD, &buflen);
+        if (r < 0)
+                return r;
+
+        if (buflen < 0)
+                /* this can't be right */
+                return -EIO;
+
+        message = malloc0(buflen);
+        if (!message)
+                return -ENOMEM;
+
+        len = read(fd, message, buflen);
+        if (len < 0) {
+                log_dhcp_client(client, "could not receive message from UDP "
+                                "socket: %m");
+                return 0;
+        } else if ((size_t)len < sizeof(DHCPMessage)) {
+                log_dhcp_client(client, "too small to be a DHCP message: ignoring");
+                return 0;
+        }
+
+        if (be32toh(message->magic) != DHCP_MAGIC_COOKIE) {
+                log_dhcp_client(client, "not a DHCP message: ignoring");
+                return 0;
+        }
+
+        if (message->op != BOOTREPLY) {
+                log_dhcp_client(client, "not a BOOTREPLY message: ignoring");
+                return 0;
+        }
+
+        if (message->htype != ARPHRD_ETHER || message->hlen != ETHER_ADDR_LEN) {
+                log_dhcp_client(client, "not an ethernet packet");
+                return 0;
+        }
+
+        if (memcmp(&message->chaddr[0], &client->client_id.mac_addr,
+                   ETH_ALEN)) {
+                log_dhcp_client(client, "received chaddr does not match "
+                                "expected: ignoring");
+                return 0;
+        }
+
+        if (client->state != DHCP_STATE_BOUND &&
+            be32toh(message->xid) != client->xid) {
+                /* in BOUND state, we may receive FORCERENEW with xid set by server,
+                   so ignore the xid in this case */
+                log_dhcp_client(client, "received xid (%u) does not match "
+                                "expected (%u): ignoring",
+                                be32toh(message->xid), client->xid);
+                return 0;
+        }
+
+        return client_handle_message(client, message, len);
+}
+
+static int client_receive_message_raw(sd_event_source *s, int fd,
+                                      uint32_t revents, void *userdata) {
+        sd_dhcp_client *client = userdata;
+        _cleanup_free_ DHCPPacket *packet = NULL;
+        uint8_t cmsgbuf[CMSG_LEN(sizeof(struct tpacket_auxdata))];
+        struct iovec iov = {};
+        struct msghdr msg = {
+                .msg_iov = &iov,
+                .msg_iovlen = 1,
+                .msg_control = cmsgbuf,
+                .msg_controllen = sizeof(cmsgbuf),
+        };
+        struct cmsghdr *cmsg;
+        bool checksum = true;
+        int buflen = 0, len, r;
+
+        assert(s);
+        assert(client);
+
+        r = ioctl(fd, FIONREAD, &buflen);
+        if (r < 0)
+                return r;
+
+        if (buflen < 0)
+                /* this can't be right */
+                return -EIO;
+
+        packet = malloc0(buflen);
+        if (!packet)
+                return -ENOMEM;
+
+        iov.iov_base = packet;
+        iov.iov_len = buflen;
+
+        len = recvmsg(fd, &msg, 0);
+        if (len < 0) {
+                log_dhcp_client(client, "could not receive message from raw "
+                                "socket: %m");
+                return 0;
+        } else if ((size_t)len < sizeof(DHCPPacket))
+                return 0;
+
+        for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+                if (cmsg->cmsg_level == SOL_PACKET &&
+                    cmsg->cmsg_type == PACKET_AUXDATA &&
+                    cmsg->cmsg_len == CMSG_LEN(sizeof(struct tpacket_auxdata))) {
+                        struct tpacket_auxdata *aux = (struct tpacket_auxdata*)CMSG_DATA(cmsg);
+
+                        checksum = !(aux->tp_status & TP_STATUS_CSUMNOTREADY);
+                        break;
+                }
+        }
+
+        r = dhcp_packet_verify_headers(packet, len, checksum);
+        if (r < 0)
+                return 0;
+
+        len -= DHCP_IP_UDP_SIZE;
+
+        return client_handle_message(client, &packet->dhcp, len);
+}
+
+int sd_dhcp_client_start(sd_dhcp_client *client) {
+        char buffer[ETHER_ADDR_TO_STRING_MAX];
+        int r;
+
+        assert_return(client, -EINVAL);
+
+        r = client_initialize(client);
+        if (r < 0)
+                return r;
+
+        if (client->last_addr)
+                client->state = DHCP_STATE_INIT_REBOOT;
+
+        r = client_start(client);
+        if (r >= 0)
+                log_dhcp_client(client, "STARTED on ifindex %u with address %s",
+                                client->index,
+                                ether_addr_to_string(&client->client_id.mac_addr, buffer));
+
+        return r;
+}
+
+int sd_dhcp_client_stop(sd_dhcp_client *client) {
+        DHCP_CLIENT_DONT_DESTROY(client);
+
+        assert_return(client, -EINVAL);
+
+        client_stop(client, DHCP_EVENT_STOP);
+        client->state = DHCP_STATE_STOPPED;
+
+        return 0;
+}
+
+int sd_dhcp_client_attach_event(sd_dhcp_client *client, sd_event *event,
+                                int priority) {
+        int r;
+
+        assert_return(client, -EINVAL);
+        assert_return(!client->event, -EBUSY);
+
+        if (event)
+                client->event = sd_event_ref(event);
+        else {
+                r = sd_event_default(&client->event);
+                if (r < 0)
+                        return 0;
+        }
+
+        client->event_priority = priority;
+
+        return 0;
+}
+
+int sd_dhcp_client_detach_event(sd_dhcp_client *client) {
+        assert_return(client, -EINVAL);
+
+        client->event = sd_event_unref(client->event);
+
+        return 0;
+}
+
+sd_event *sd_dhcp_client_get_event(sd_dhcp_client *client) {
+        if (!client)
+                return NULL;
+
+        return client->event;
+}
+
+sd_dhcp_client *sd_dhcp_client_ref(sd_dhcp_client *client) {
+        if (client)
+                assert_se(REFCNT_INC(client->n_ref) >= 2);
+
+        return client;
+}
+
+sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client) {
+        if (client && REFCNT_DEC(client->n_ref) <= 0) {
+                log_dhcp_client(client, "FREE");
+
+                client_initialize(client);
+
+                client->receive_message =
+                        sd_event_source_unref(client->receive_message);
+
+                sd_dhcp_client_detach_event(client);
+
+                sd_dhcp_lease_unref(client->lease);
+
+                free(client->req_opts);
+                free(client->hostname);
+                free(client->vendor_class_identifier);
+                free(client);
+        }
+
+        return NULL;
+}
+
+int sd_dhcp_client_new(sd_dhcp_client **ret) {
+        _cleanup_dhcp_client_unref_ sd_dhcp_client *client = NULL;
+
+        assert_return(ret, -EINVAL);
+
+        client = new0(sd_dhcp_client, 1);
+        if (!client)
+                return -ENOMEM;
+
+        client->n_ref = REFCNT_INIT;
+        client->state = DHCP_STATE_INIT;
+        client->index = -1;
+        client->fd = -1;
+        client->attempt = 1;
+        client->mtu = DHCP_DEFAULT_MIN_SIZE;
+
+        client->req_opts_size = ELEMENTSOF(default_req_opts);
+
+        client->req_opts = memdup(default_req_opts, client->req_opts_size);
+        if (!client->req_opts)
+                return -ENOMEM;
+
+        *ret = client;
+        client = NULL;
+
+        return 0;
+}
diff --git a/src/libsystemd-network/sd-dhcp-lease.c b/src/libsystemd-network/sd-dhcp-lease.c
new file mode 100644 (file)
index 0000000..6680d06
--- /dev/null
@@ -0,0 +1,829 @@
+/***
+  This file is part of systemd.
+
+  Copyright (C) 2013 Intel Corporation. All rights reserved.
+  Copyright (C) 2014 Tom Gundersen
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <net/ethernet.h>
+#include <arpa/inet.h>
+#include <sys/param.h>
+
+#include "util.h"
+#include "list.h"
+#include "mkdir.h"
+#include "fileio.h"
+
+#include "dhcp-protocol.h"
+#include "dhcp-internal.h"
+#include "dhcp-lease-internal.h"
+#include "sd-dhcp-lease.h"
+#include "sd-dhcp-client.h"
+#include "network-internal.h"
+
+int sd_dhcp_lease_get_address(sd_dhcp_lease *lease, struct in_addr *addr) {
+        assert_return(lease, -EINVAL);
+        assert_return(addr, -EINVAL);
+
+        addr->s_addr = lease->address;
+
+        return 0;
+}
+
+int sd_dhcp_lease_get_lifetime(sd_dhcp_lease *lease, uint32_t *lifetime) {
+        assert_return(lease, -EINVAL);
+        assert_return(lease, -EINVAL);
+
+        *lifetime = lease->lifetime;
+
+        return 0;
+}
+
+int sd_dhcp_lease_get_mtu(sd_dhcp_lease *lease, uint16_t *mtu) {
+        assert_return(lease, -EINVAL);
+        assert_return(mtu, -EINVAL);
+
+        if (lease->mtu)
+                *mtu = lease->mtu;
+        else
+                return -ENOENT;
+
+        return 0;
+}
+
+int sd_dhcp_lease_get_dns(sd_dhcp_lease *lease, const struct in_addr **addr) {
+        assert_return(lease, -EINVAL);
+        assert_return(addr, -EINVAL);
+
+        if (lease->dns_size) {
+                *addr = lease->dns;
+                return lease->dns_size;
+        } else
+                return -ENOENT;
+
+        return 0;
+}
+
+int sd_dhcp_lease_get_ntp(sd_dhcp_lease *lease, const struct in_addr **addr) {
+        assert_return(lease, -EINVAL);
+        assert_return(addr, -EINVAL);
+
+        if (lease->ntp_size) {
+                *addr = lease->ntp;
+                return lease->ntp_size;
+        } else
+                return -ENOENT;
+
+        return 0;
+}
+
+int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname) {
+        assert_return(lease, -EINVAL);
+        assert_return(domainname, -EINVAL);
+
+        if (lease->domainname)
+                *domainname = lease->domainname;
+        else
+                return -ENOENT;
+
+        return 0;
+}
+
+int sd_dhcp_lease_get_hostname(sd_dhcp_lease *lease, const char **hostname) {
+        assert_return(lease, -EINVAL);
+        assert_return(hostname, -EINVAL);
+
+        if (lease->hostname)
+                *hostname = lease->hostname;
+        else
+                return -ENOENT;
+
+        return 0;
+}
+
+int sd_dhcp_lease_get_root_path(sd_dhcp_lease *lease, const char **root_path) {
+        assert_return(lease, -EINVAL);
+        assert_return(root_path, -EINVAL);
+
+        if (lease->root_path)
+                *root_path = lease->root_path;
+        else
+                return -ENOENT;
+
+        return 0;
+}
+
+int sd_dhcp_lease_get_router(sd_dhcp_lease *lease, struct in_addr *addr) {
+        assert_return(lease, -EINVAL);
+        assert_return(addr, -EINVAL);
+
+        if (lease->router != INADDR_ANY)
+                addr->s_addr = lease->router;
+        else
+                return -ENOENT;
+
+        return 0;
+}
+
+int sd_dhcp_lease_get_netmask(sd_dhcp_lease *lease, struct in_addr *addr) {
+        assert_return(lease, -EINVAL);
+        assert_return(addr, -EINVAL);
+
+        addr->s_addr = lease->subnet_mask;
+
+        return 0;
+}
+
+int sd_dhcp_lease_get_server_identifier(sd_dhcp_lease *lease, struct in_addr *addr) {
+        assert_return(lease, -EINVAL);
+        assert_return(addr, -EINVAL);
+
+        addr->s_addr = lease->server_address;
+
+        return 0;
+}
+
+int sd_dhcp_lease_get_next_server(sd_dhcp_lease *lease, struct in_addr *addr) {
+        assert_return(lease, -EINVAL);
+        assert_return(addr, -EINVAL);
+
+        addr->s_addr = lease->next_server;
+
+        return 0;
+}
+
+int sd_dhcp_lease_get_routes(sd_dhcp_lease *lease, struct sd_dhcp_route **routes) {
+
+        assert_return(lease, -EINVAL);
+        assert_return(routes, -EINVAL);
+
+        if (lease->static_route_size) {
+                *routes = lease->static_route;
+                return lease->static_route_size;
+        } else
+                return -ENOENT;
+
+        return 0;
+}
+
+sd_dhcp_lease *sd_dhcp_lease_ref(sd_dhcp_lease *lease) {
+        if (lease)
+                assert_se(REFCNT_INC(lease->n_ref) >= 2);
+
+        return lease;
+}
+
+sd_dhcp_lease *sd_dhcp_lease_unref(sd_dhcp_lease *lease) {
+        if (lease && REFCNT_DEC(lease->n_ref) <= 0) {
+                free(lease->hostname);
+                free(lease->domainname);
+                free(lease->dns);
+                free(lease->ntp);
+                free(lease->static_route);
+                free(lease);
+        }
+
+        return NULL;
+}
+
+static void lease_parse_u32(const uint8_t *option, size_t len, uint32_t *ret, uint32_t min) {
+        be32_t val;
+
+        assert(option);
+        assert(ret);
+
+        if (len == 4) {
+                memcpy(&val, option, 4);
+                *ret = be32toh(val);
+
+                if (*ret < min)
+                        *ret = min;
+        }
+}
+
+static void lease_parse_s32(const uint8_t *option, size_t len, int32_t *ret) {
+        lease_parse_u32(option, len, (uint32_t *)ret, 0);
+}
+
+static void lease_parse_u16(const uint8_t *option, size_t len, uint16_t *ret, uint16_t min) {
+        be16_t val;
+
+        assert(option);
+        assert(ret);
+
+        if (len == 2) {
+                memcpy(&val, option, 2);
+                *ret = be16toh(val);
+
+                if (*ret < min)
+                        *ret = min;
+        }
+}
+
+static void lease_parse_be32(const uint8_t *option, size_t len, be32_t *ret) {
+        assert(option);
+        assert(ret);
+
+        if (len == 4)
+                memcpy(ret, option, 4);
+}
+
+static void lease_parse_bool(const uint8_t *option, size_t len, bool *ret) {
+        assert(option);
+        assert(ret);
+
+        if (len == 1)
+                *ret = !!(*option);
+}
+
+static void lease_parse_u8(const uint8_t *option, size_t len, uint8_t *ret, uint8_t min) {
+        assert(option);
+        assert(ret);
+
+        if (len == 1) {
+                *ret = *option;
+
+                if (*ret < min)
+                        *ret = min;
+        }
+}
+
+static int lease_parse_string(const uint8_t *option, size_t len, char **ret) {
+        assert(option);
+        assert(ret);
+
+        if (len >= 1) {
+                char *string;
+
+                string = strndup((const char *)option, len);
+                if (!string)
+                        return -errno;
+
+                free(*ret);
+                *ret = string;
+        }
+
+        return 0;
+}
+
+static int lease_parse_in_addrs_aux(const uint8_t *option, size_t len, struct in_addr **ret, size_t *ret_size, size_t mult) {
+        assert(option);
+        assert(ret);
+        assert(ret_size);
+
+        if (len && !(len % (4 * mult))) {
+                size_t size;
+                struct in_addr *addresses;
+
+                size = len / 4;
+
+                addresses = newdup(struct in_addr, option, size);
+                if (!addresses)
+                        return -ENOMEM;
+
+                free(*ret);
+                *ret = addresses;
+                *ret_size = size;
+        }
+
+        return 0;
+}
+
+static int lease_parse_in_addrs(const uint8_t *option, size_t len, struct in_addr **ret, size_t *ret_size) {
+        return lease_parse_in_addrs_aux(option, len, ret, ret_size, 1);
+}
+
+static int lease_parse_in_addrs_pairs(const uint8_t *option, size_t len, struct in_addr **ret, size_t *ret_size) {
+        return lease_parse_in_addrs_aux(option, len, ret, ret_size, 2);
+}
+
+static int class_prefixlen(uint8_t msb_octet, uint8_t *ret) {
+        if (msb_octet < 128)
+                /* Class A */
+                *ret = 8;
+        else if (msb_octet < 192)
+                /* Class B */
+                *ret = 16;
+        else if (msb_octet < 224)
+                /* Class C */
+                *ret = 24;
+        else
+                /* Class D or E -- no subnet mask */
+                return -ERANGE;
+
+        return 0;
+}
+
+static int lease_parse_routes(const uint8_t *option, size_t len, struct sd_dhcp_route **routes,
+        size_t *routes_size, size_t *routes_allocated) {
+
+        struct in_addr addr;
+
+        assert(option);
+        assert(routes);
+        assert(routes_size);
+        assert(routes_allocated);
+
+        if (!len)
+                return 0;
+
+        if (len % 8 != 0)
+                return -EINVAL;
+
+        if (!GREEDY_REALLOC(*routes, *routes_allocated, *routes_size + (len / 8)))
+                return -ENOMEM;
+
+        while (len >= 8) {
+                struct sd_dhcp_route *route = *routes + *routes_size;
+
+                if (class_prefixlen(*option, &route->dst_prefixlen) < 0) {
+                        log_error("Failed to determine destination prefix length from class based IP, ignoring");
+                        continue;
+                }
+
+                lease_parse_be32(option, 4, &addr.s_addr);
+                route->dst_addr = inet_makeaddr(inet_netof(addr), 0);
+                option += 4;
+
+                lease_parse_be32(option, 4, &route->gw_addr.s_addr);
+                option += 4;
+
+                len -= 8;
+                (*routes_size)++;
+        }
+
+        return 0;
+}
+
+/* parses RFC3442 Classless Static Route Option */
+static int lease_parse_classless_routes(const uint8_t *option, size_t len, struct sd_dhcp_route **routes,
+        size_t *routes_size, size_t *routes_allocated) {
+
+        assert(option);
+        assert(routes);
+        assert(routes_size);
+        assert(routes_allocated);
+
+        /* option format: (subnet-mask-width significant-subnet-octets gateway-ip)*  */
+
+        while (len > 0) {
+                uint8_t dst_octets;
+                struct sd_dhcp_route *route;
+
+                if (!GREEDY_REALLOC(*routes, *routes_allocated, *routes_size + 1))
+                    return -ENOMEM;
+
+                route = *routes + *routes_size;
+
+                dst_octets = (*option == 0 ? 0 : ((*option - 1) / 8) + 1);
+                route->dst_prefixlen = *option;
+                option++;
+                len--;
+
+                /* can't have more than 4 octets in IPv4 */
+                if (dst_octets > 4 || len < dst_octets)
+                        return -EINVAL;
+
+                route->dst_addr.s_addr = 0;
+                memcpy(&route->dst_addr.s_addr, option, dst_octets);
+                option += dst_octets;
+                len -= dst_octets;
+
+                if (len < 4)
+                        return -EINVAL;
+
+                lease_parse_be32(option, 4, &route->gw_addr.s_addr);
+                option += 4;
+                len -= 4;
+
+                (*routes_size)++;
+        }
+
+        return 0;
+}
+
+int dhcp_lease_parse_options(uint8_t code, uint8_t len, const uint8_t *option,
+                              void *user_data) {
+        sd_dhcp_lease *lease = user_data;
+        int r;
+
+        assert(lease);
+
+        switch(code) {
+
+        case DHCP_OPTION_TIME_OFFSET:
+                lease_parse_s32(option, len, &lease->time_offset);
+
+                break;
+
+        case DHCP_OPTION_INTERFACE_MTU_AGING_TIMEOUT:
+                lease_parse_u32(option, len, &lease->mtu_aging_timeout, 0);
+
+                break;
+
+        case DHCP_OPTION_IP_ADDRESS_LEASE_TIME:
+                lease_parse_u32(option, len, &lease->lifetime, 1);
+
+                break;
+
+        case DHCP_OPTION_SERVER_IDENTIFIER:
+                lease_parse_be32(option, len, &lease->server_address);
+
+                break;
+
+        case DHCP_OPTION_SUBNET_MASK:
+                lease_parse_be32(option, len, &lease->subnet_mask);
+
+                break;
+
+        case DHCP_OPTION_BROADCAST:
+                lease_parse_be32(option, len, &lease->broadcast);
+
+                break;
+
+        case DHCP_OPTION_ROUTER:
+                lease_parse_be32(option, len, &lease->router);
+
+                break;
+
+        case DHCP_OPTION_DOMAIN_NAME_SERVER:
+                r = lease_parse_in_addrs(option, len, &lease->dns, &lease->dns_size);
+                if (r < 0)
+                        return r;
+
+                break;
+
+        case DHCP_OPTION_NTP_SERVER:
+                r = lease_parse_in_addrs(option, len, &lease->ntp, &lease->ntp_size);
+                if (r < 0)
+                        return r;
+
+                break;
+
+        case DHCP_OPTION_POLICY_FILTER:
+                r = lease_parse_in_addrs_pairs(option, len, &lease->policy_filter, &lease->policy_filter_size);
+                if (r < 0)
+                        return r;
+
+                break;
+
+        case DHCP_OPTION_STATIC_ROUTE:
+                r = lease_parse_routes(option, len, &lease->static_route, &lease->static_route_size,
+                        &lease->static_route_allocated);
+                if (r < 0)
+                        return r;
+
+                break;
+
+        case DHCP_OPTION_INTERFACE_MTU:
+                lease_parse_u16(option, len, &lease->mtu, 68);
+
+                break;
+
+        case DHCP_OPTION_INTERFACE_MDR:
+                lease_parse_u16(option, len, &lease->mdr, 576);
+
+                break;
+
+        case DHCP_OPTION_INTERFACE_TTL:
+                lease_parse_u8(option, len, &lease->ttl, 1);
+
+                break;
+
+        case DHCP_OPTION_BOOT_FILE_SIZE:
+                lease_parse_u16(option, len, &lease->boot_file_size, 0);
+
+                break;
+
+        case DHCP_OPTION_DOMAIN_NAME:
+        {
+                _cleanup_free_ char *domainname = NULL;
+
+                r = lease_parse_string(option, len, &domainname);
+                if (r < 0)
+                        return r;
+
+                if (!hostname_is_valid(domainname) || is_localhost(domainname))
+                        break;
+
+                free(lease->domainname);
+                lease->domainname = domainname;
+                domainname = NULL;
+
+                break;
+        }
+        case DHCP_OPTION_HOST_NAME:
+        {
+                _cleanup_free_ char *hostname = NULL;
+
+                r = lease_parse_string(option, len, &hostname);
+                if (r < 0)
+                        return r;
+
+                if (!hostname_is_valid(hostname) || is_localhost(hostname))
+                        break;
+
+                free(lease->hostname);
+                lease->hostname = hostname;
+                hostname = NULL;
+
+                break;
+        }
+        case DHCP_OPTION_ROOT_PATH:
+                r = lease_parse_string(option, len, &lease->root_path);
+                if (r < 0)
+                        return r;
+
+                break;
+
+        case DHCP_OPTION_RENEWAL_T1_TIME:
+                lease_parse_u32(option, len, &lease->t1, 1);
+
+                break;
+
+        case DHCP_OPTION_REBINDING_T2_TIME:
+                lease_parse_u32(option, len, &lease->t2, 1);
+
+                break;
+
+        case DHCP_OPTION_ENABLE_IP_FORWARDING:
+                lease_parse_bool(option, len, &lease->ip_forward);
+
+                break;
+
+        case DHCP_OPTION_ENABLE_IP_FORWARDING_NL:
+                lease_parse_bool(option, len, &lease->ip_forward_non_local);
+
+                break;
+
+        case DHCP_OPTION_CLASSLESS_STATIC_ROUTE:
+                r = lease_parse_classless_routes(option, len, &lease->static_route, &lease->static_route_size,
+                        &lease->static_route_allocated);
+                if (r < 0)
+                        return r;
+
+                break;
+        }
+
+        return 0;
+}
+
+int dhcp_lease_new(sd_dhcp_lease **ret) {
+        sd_dhcp_lease *lease;
+
+        lease = new0(sd_dhcp_lease, 1);
+        if (!lease)
+                return -ENOMEM;
+
+        lease->router = INADDR_ANY;
+        lease->n_ref = REFCNT_INIT;
+
+        *ret = lease;
+        return 0;
+}
+
+int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) {
+        _cleanup_free_ char *temp_path = NULL;
+        _cleanup_fclose_ FILE *f = NULL;
+        struct in_addr address;
+        const struct in_addr *addresses;
+        const char *string;
+        uint16_t mtu;
+        struct sd_dhcp_route *routes;
+        int r;
+
+        assert(lease);
+        assert(lease_file);
+
+        r = fopen_temporary(lease_file, &f, &temp_path);
+        if (r < 0)
+                goto finish;
+
+        fchmod(fileno(f), 0644);
+
+        r = sd_dhcp_lease_get_address(lease, &address);
+        if (r < 0)
+                goto finish;
+
+        fprintf(f,
+                "# This is private data. Do not parse.\n"
+                "ADDRESS=%s\n", inet_ntoa(address));
+
+        r = sd_dhcp_lease_get_netmask(lease, &address);
+        if (r < 0)
+                goto finish;
+
+        fprintf(f, "NETMASK=%s\n", inet_ntoa(address));
+
+        r = sd_dhcp_lease_get_router(lease, &address);
+        if (r >= 0)
+                fprintf(f, "ROUTER=%s\n", inet_ntoa(address));
+
+        r = sd_dhcp_lease_get_server_identifier(lease, &address);
+        if (r >= 0)
+                fprintf(f, "SERVER_ADDRESS=%s\n",
+                        inet_ntoa(address));
+
+        r = sd_dhcp_lease_get_next_server(lease, &address);
+        if (r >= 0)
+                fprintf(f, "NEXT_SERVER=%s\n", inet_ntoa(address));
+
+        r = sd_dhcp_lease_get_mtu(lease, &mtu);
+        if (r >= 0)
+                fprintf(f, "MTU=%" PRIu16 "\n", mtu);
+
+        fputs("DNS=", f);
+        r = sd_dhcp_lease_get_dns(lease, &addresses);
+        if (r >= 0)
+                serialize_in_addrs(f, addresses, r);
+        fputs("\n", f);
+
+        fputs("NTP=", f);
+        r = sd_dhcp_lease_get_ntp(lease, &addresses);
+        if (r >= 0)
+                serialize_in_addrs(f, addresses, r);
+        fputs("\n", f);
+
+        r = sd_dhcp_lease_get_domainname(lease, &string);
+        if (r >= 0)
+                fprintf(f, "DOMAINNAME=%s\n", string);
+
+        r = sd_dhcp_lease_get_hostname(lease, &string);
+        if (r >= 0)
+                fprintf(f, "HOSTNAME=%s\n", string);
+
+        r = sd_dhcp_lease_get_root_path(lease, &string);
+        if (r >= 0)
+                fprintf(f, "ROOT_PATH=%s\n", string);
+
+        r = sd_dhcp_lease_get_routes(lease, &routes);
+        if (r >= 0)
+                serialize_dhcp_routes(f, "ROUTES", routes, r);
+
+        r = 0;
+
+        fflush(f);
+
+        if (ferror(f) || rename(temp_path, lease_file) < 0) {
+                r = -errno;
+                unlink(lease_file);
+                unlink(temp_path);
+        }
+
+finish:
+        if (r < 0)
+                log_error("Failed to save lease data %s: %s", lease_file, strerror(-r));
+
+        return r;
+}
+
+int dhcp_lease_load(const char *lease_file, sd_dhcp_lease **ret) {
+        _cleanup_dhcp_lease_unref_ sd_dhcp_lease *lease = NULL;
+        _cleanup_free_ char *address = NULL, *router = NULL, *netmask = NULL,
+                            *server_address = NULL, *next_server = NULL,
+                            *dns = NULL, *ntp = NULL, *mtu = NULL, *routes = NULL;
+        struct in_addr addr;
+        int r;
+
+        assert(lease_file);
+        assert(ret);
+
+        r = dhcp_lease_new(&lease);
+        if (r < 0)
+                return r;
+
+        r = parse_env_file(lease_file, NEWLINE,
+                           "ADDRESS", &address,
+                           "ROUTER", &router,
+                           "NETMASK", &netmask,
+                           "SERVER_IDENTIFIER", &server_address,
+                           "NEXT_SERVER", &next_server,
+                           "DNS", &dns,
+                           "NTP", &ntp,
+                           "MTU", &mtu,
+                           "DOMAINNAME", &lease->domainname,
+                           "HOSTNAME", &lease->hostname,
+                           "ROOT_PATH", &lease->root_path,
+                           "ROUTES", &routes,
+                           NULL);
+        if (r < 0) {
+                if (r == -ENOENT)
+                        return 0;
+
+                log_error("Failed to read %s: %s", lease_file, strerror(-r));
+                return r;
+        }
+
+        r = inet_pton(AF_INET, address, &addr);
+        if (r < 0)
+                return r;
+
+        lease->address = addr.s_addr;
+
+        if (router) {
+                r = inet_pton(AF_INET, router, &addr);
+                if (r < 0)
+                        return r;
+
+                lease->router = addr.s_addr;
+        }
+
+        r = inet_pton(AF_INET, netmask, &addr);
+        if (r < 0)
+                return r;
+
+        lease->subnet_mask = addr.s_addr;
+
+        if (server_address) {
+                r = inet_pton(AF_INET, server_address, &addr);
+                if (r < 0)
+                        return r;
+
+                lease->server_address = addr.s_addr;
+        }
+
+        if (next_server) {
+                r = inet_pton(AF_INET, next_server, &addr);
+                if (r < 0)
+                        return r;
+
+                lease->next_server = addr.s_addr;
+        }
+
+        if (dns) {
+                r = deserialize_in_addrs(&lease->dns, dns);
+                if (r < 0)
+                        return r;
+
+                lease->dns_size = r;
+        }
+
+        if (ntp) {
+                r = deserialize_in_addrs(&lease->ntp, ntp);
+                if (r < 0)
+                        return r;
+
+                lease->ntp_size = r;
+        }
+
+        if (mtu) {
+                uint16_t u;
+                if (sscanf(mtu, "%" SCNu16, &u) > 0)
+                        lease->mtu = u;
+        }
+
+        if (routes) {
+                r = deserialize_dhcp_routes(&lease->static_route, &lease->static_route_size,
+                                &lease->static_route_allocated, routes);
+                if (r < 0)
+                    return r;
+        }
+
+        *ret = lease;
+        lease = NULL;
+
+        return 0;
+}
+
+int dhcp_lease_set_default_subnet_mask(sd_dhcp_lease *lease) {
+        uint32_t address;
+
+        assert(lease);
+        assert(lease->address != INADDR_ANY);
+
+        address = be32toh(lease->address);
+
+        /* fall back to the default subnet masks based on address class */
+
+        if ((address >> 31) == 0x0)
+                /* class A, leading bits: 0 */
+                lease->subnet_mask = htobe32(0xff000000);
+        else if ((address >> 30) == 0x2)
+                /* class B, leading bits 10 */
+                lease->subnet_mask = htobe32(0xffff0000);
+        else if ((address >> 29) == 0x6)
+                /* class C, leading bits 110 */
+                lease->subnet_mask = htobe32(0xffffff00);
+        else
+                /* class D or E, no default mask. give up */
+                return -ERANGE;
+
+        return 0;
+}
diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c
new file mode 100644 (file)
index 0000000..ab68322
--- /dev/null
@@ -0,0 +1,988 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright (C) 2013 Intel Corporation. All rights reserved.
+  Copyright (C) 2014 Tom Gundersen
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/ioctl.h>
+#include <netinet/if_ether.h>
+
+#include "siphash24.h"
+
+#include "sd-dhcp-server.h"
+#include "dhcp-server-internal.h"
+#include "dhcp-internal.h"
+
+#define DHCP_DEFAULT_LEASE_TIME         3600 /* one hour */
+
+int sd_dhcp_server_set_lease_pool(sd_dhcp_server *server,
+                                  struct in_addr *address,
+                                  size_t size) {
+        assert_return(server, -EINVAL);
+        assert_return(address, -EINVAL);
+        assert_return(address->s_addr, -EINVAL);
+        assert_return(size, -EINVAL);
+        assert_return(server->pool_start == htobe32(INADDR_ANY), -EBUSY);
+        assert_return(!server->pool_size, -EBUSY);
+        assert_return(!server->bound_leases, -EBUSY);
+
+        server->bound_leases = new0(DHCPLease*, size);
+        if (!server->bound_leases)
+                return -ENOMEM;
+
+        server->pool_start = address->s_addr;
+        server->pool_size = size;
+
+        return 0;
+}
+
+int sd_dhcp_server_set_address(sd_dhcp_server *server, struct in_addr *address,
+                               unsigned char prefixlen) {
+        assert_return(server, -EINVAL);
+        assert_return(address, -EINVAL);
+        assert_return(address->s_addr, -EINVAL);
+        assert_return(prefixlen <= 32, -ERANGE);
+        assert_return(server->address == htobe32(INADDR_ANY), -EBUSY);
+        assert_return(server->netmask == htobe32(INADDR_ANY), -EBUSY);
+
+        server->address = address->s_addr;
+        server->netmask = htobe32(0xfffffffflu << (32 - prefixlen));
+
+        return 0;
+}
+
+bool sd_dhcp_server_is_running(sd_dhcp_server *server) {
+        assert_return(server, -EINVAL);
+
+        return !!server->receive_message;
+}
+
+sd_dhcp_server *sd_dhcp_server_ref(sd_dhcp_server *server) {
+        if (server)
+                assert_se(REFCNT_INC(server->n_ref) >= 2);
+
+        return server;
+}
+
+unsigned long client_id_hash_func(const void *p,
+                                  const uint8_t hash_key[HASH_KEY_SIZE]) {
+        uint64_t u;
+        const DHCPClientId *id = p;
+
+        assert(id);
+        assert(id->length);
+        assert(id->data);
+
+        siphash24((uint8_t*) &u, id->data, id->length, hash_key);
+
+        return (unsigned long) u;
+}
+
+int client_id_compare_func(const void *_a, const void *_b) {
+        const DHCPClientId *a, *b;
+
+        a = _a;
+        b = _b;
+
+        assert(!a->length || a->data);
+        assert(!b->length || b->data);
+
+        if (a->length != b->length)
+                return a->length < b->length ? -1 : 1;
+
+        return memcmp(a->data, b->data, a->length);
+}
+
+static void dhcp_lease_free(DHCPLease *lease) {
+        if (!lease)
+                return;
+
+        free(lease->client_id.data);
+        free(lease);
+}
+
+sd_dhcp_server *sd_dhcp_server_unref(sd_dhcp_server *server) {
+        DHCPLease *lease;
+
+        if (!server)
+                return NULL;
+
+        if (REFCNT_DEC(server->n_ref) > 0)
+                return NULL;
+
+        log_dhcp_server(server, "UNREF");
+
+        sd_dhcp_server_stop(server);
+
+        sd_event_unref(server->event);
+
+        while ((lease = hashmap_steal_first(server->leases_by_client_id)))
+                dhcp_lease_free(lease);
+        hashmap_free(server->leases_by_client_id);
+
+        free(server->bound_leases);
+        free(server);
+
+        return NULL;
+}
+
+int sd_dhcp_server_new(sd_dhcp_server **ret, int ifindex) {
+        _cleanup_dhcp_server_unref_ sd_dhcp_server *server = NULL;
+
+        assert_return(ret, -EINVAL);
+        assert_return(ifindex > 0, -EINVAL);
+
+        server = new0(sd_dhcp_server, 1);
+        if (!server)
+                return -ENOMEM;
+
+        server->n_ref = REFCNT_INIT;
+        server->fd_raw = -1;
+        server->fd = -1;
+        server->address = htobe32(INADDR_ANY);
+        server->netmask = htobe32(INADDR_ANY);
+        server->index = ifindex;
+        server->leases_by_client_id = hashmap_new(client_id_hash_func,
+                                                  client_id_compare_func);
+
+        *ret = server;
+        server = NULL;
+
+        return 0;
+}
+
+int sd_dhcp_server_attach_event(sd_dhcp_server *server, sd_event *event,
+                                int priority) {
+        int r;
+
+        assert_return(server, -EINVAL);
+        assert_return(!server->event, -EBUSY);
+
+        if (event)
+                server->event = sd_event_ref(event);
+        else {
+                r = sd_event_default(&server->event);
+                if (r < 0)
+                        return r;
+        }
+
+        server->event_priority = priority;
+
+        return 0;
+}
+
+int sd_dhcp_server_detach_event(sd_dhcp_server *server) {
+        assert_return(server, -EINVAL);
+
+        server->event = sd_event_unref(server->event);
+
+        return 0;
+}
+
+sd_event *sd_dhcp_server_get_event(sd_dhcp_server *server) {
+        assert_return(server, NULL);
+
+        return server->event;
+}
+
+int sd_dhcp_server_stop(sd_dhcp_server *server) {
+        assert_return(server, -EINVAL);
+
+        server->receive_message =
+                sd_event_source_unref(server->receive_message);
+
+        server->fd_raw = safe_close(server->fd_raw);
+        server->fd = safe_close(server->fd);
+
+        log_dhcp_server(server, "STOPPED");
+
+        return 0;
+}
+
+static int dhcp_server_send_unicast_raw(sd_dhcp_server *server,
+                                        DHCPPacket *packet, size_t len) {
+        union sockaddr_union link = {
+                .ll.sll_family = AF_PACKET,
+                .ll.sll_protocol = htons(ETH_P_IP),
+                .ll.sll_ifindex = server->index,
+                .ll.sll_halen = ETH_ALEN,
+        };
+        int r;
+
+        assert(server);
+        assert(server->index > 0);
+        assert(server->address);
+        assert(packet);
+        assert(len > sizeof(DHCPPacket));
+
+        memcpy(&link.ll.sll_addr, &packet->dhcp.chaddr, ETH_ALEN);
+
+        dhcp_packet_append_ip_headers(packet, server->address, DHCP_PORT_SERVER,
+                                      packet->dhcp.yiaddr,
+                                      DHCP_PORT_CLIENT, len);
+
+        r = dhcp_network_send_raw_socket(server->fd_raw, &link, packet, len);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+static int dhcp_server_send_udp(sd_dhcp_server *server, be32_t destination,
+                                DHCPMessage *message, size_t len) {
+        union sockaddr_union dest = {
+                .in.sin_family = AF_INET,
+                .in.sin_port = htobe16(DHCP_PORT_CLIENT),
+                .in.sin_addr.s_addr = destination,
+        };
+        struct iovec iov = {
+                .iov_base = message,
+                .iov_len = len,
+        };
+        uint8_t cmsgbuf[CMSG_LEN(sizeof(struct in_pktinfo))] = {};
+        struct msghdr msg = {
+                .msg_name = &dest,
+                .msg_namelen = sizeof(dest.in),
+                .msg_iov = &iov,
+                .msg_iovlen = 1,
+                .msg_control = cmsgbuf,
+                .msg_controllen = sizeof(cmsgbuf),
+        };
+        struct cmsghdr *cmsg;
+        struct in_pktinfo *pktinfo;
+        int r;
+
+        assert(server);
+        assert(server->fd > 0);
+        assert(message);
+        assert(len > sizeof(DHCPMessage));
+
+        cmsg = CMSG_FIRSTHDR(&msg);
+        assert(cmsg);
+
+        cmsg->cmsg_level = IPPROTO_IP;
+        cmsg->cmsg_type = IP_PKTINFO;
+        cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
+
+        /* we attach source interface and address info to the message
+           rather than binding the socket. This will be mostly useful
+           when we gain support for arbitrary number of server addresses
+         */
+        pktinfo = (struct in_pktinfo*) CMSG_DATA(cmsg);
+        assert(pktinfo);
+
+        pktinfo->ipi_ifindex = server->index;
+        pktinfo->ipi_spec_dst.s_addr = server->address;
+
+        r = sendmsg(server->fd, &msg, 0);
+        if (r < 0)
+                return -errno;
+
+        return 0;
+}
+
+static bool requested_broadcast(DHCPRequest *req) {
+        assert(req);
+
+        return req->message->flags & htobe16(0x8000);
+}
+
+int dhcp_server_send_packet(sd_dhcp_server *server,
+                            DHCPRequest *req, DHCPPacket *packet,
+                            int type, size_t optoffset) {
+        be32_t destination = INADDR_ANY;
+        int r;
+
+        assert(server);
+        assert(req);
+        assert(req->max_optlen);
+        assert(optoffset <= req->max_optlen);
+        assert(packet);
+
+        r = dhcp_option_append(&packet->dhcp, req->max_optlen, &optoffset, 0,
+                               DHCP_OPTION_SERVER_IDENTIFIER,
+                               4, &server->address);
+        if (r < 0)
+                return r;
+
+        r = dhcp_option_append(&packet->dhcp, req->max_optlen, &optoffset, 0,
+                               DHCP_OPTION_END, 0, NULL);
+        if (r < 0)
+                return r;
+
+        /* RFC 2131 Section 4.1
+
+           If the ’giaddr’ field in a DHCP message from a client is non-zero,
+           the server sends any return messages to the ’DHCP server’ port on the
+           BOOTP relay agent whose address appears in ’giaddr’. If the ’giaddr’
+           field is zero and the ’ciaddr’ field is nonzero, then the server
+           unicasts DHCPOFFER and DHCPACK messages to the address in ’ciaddr’.
+           If ’giaddr’ is zero and ’ciaddr’ is zero, and the broadcast bit is
+           set, then the server broadcasts DHCPOFFER and DHCPACK messages to
+           0xffffffff. If the broadcast bit is not set and ’giaddr’ is zero and
+           ’ciaddr’ is zero, then the server unicasts DHCPOFFER and DHCPACK
+           messages to the client’s hardware address and ’yiaddr’ address. In
+           all cases, when ’giaddr’ is zero, the server broadcasts any DHCPNAK
+           messages to 0xffffffff.
+
+           Section 4.3.2
+
+           If ’giaddr’ is set in the DHCPREQUEST message, the client is on a
+           different subnet. The server MUST set the broadcast bit in the
+           DHCPNAK, so that the relay agent will broadcast the DHCPNAK to the
+           client, because the client may not have a correct network address
+           or subnet mask, and the client may not be answering ARP requests.
+         */
+        if (req->message->giaddr) {
+                destination = req->message->giaddr;
+                if (type == DHCP_NAK)
+                        packet->dhcp.flags = htobe16(0x8000);
+        } else if (req->message->ciaddr && type != DHCP_NAK)
+                destination = req->message->ciaddr;
+
+        if (destination != INADDR_ANY)
+                return dhcp_server_send_udp(server, destination, &packet->dhcp,
+                                            sizeof(DHCPMessage) + optoffset);
+        else if (requested_broadcast(req) || type == DHCP_NAK)
+                return dhcp_server_send_udp(server, INADDR_BROADCAST,
+                                            &packet->dhcp,
+                                            sizeof(DHCPMessage) + optoffset);
+        else
+                /* we cannot send UDP packet to specific MAC address when the
+                   address is not yet configured, so must fall back to raw
+                   packets */
+                return dhcp_server_send_unicast_raw(server, packet,
+                                                    sizeof(DHCPPacket) + optoffset);
+}
+
+static int server_message_init(sd_dhcp_server *server, DHCPPacket **ret,
+                               uint8_t type, size_t *_optoffset,
+                               DHCPRequest *req) {
+        _cleanup_free_ DHCPPacket *packet = NULL;
+        size_t optoffset = 0;
+        int r;
+
+        assert(server);
+        assert(ret);
+        assert(_optoffset);
+        assert(IN_SET(type, DHCP_OFFER, DHCP_ACK, DHCP_NAK));
+
+        packet = malloc0(sizeof(DHCPPacket) + req->max_optlen);
+        if (!packet)
+                return -ENOMEM;
+
+        r = dhcp_message_init(&packet->dhcp, BOOTREPLY,
+                              be32toh(req->message->xid), type, req->max_optlen,
+                              &optoffset);
+        if (r < 0)
+                return r;
+
+        packet->dhcp.flags = req->message->flags;
+        packet->dhcp.giaddr = req->message->giaddr;
+        memcpy(&packet->dhcp.chaddr, &req->message->chaddr, ETH_ALEN);
+
+        *_optoffset = optoffset;
+        *ret = packet;
+        packet = NULL;
+
+        return 0;
+}
+
+static int server_send_offer(sd_dhcp_server *server, DHCPRequest *req,
+                             be32_t address) {
+        _cleanup_free_ DHCPPacket *packet = NULL;
+        size_t offset;
+        be32_t lease_time;
+        int r;
+
+        r = server_message_init(server, &packet, DHCP_OFFER, &offset, req);
+        if (r < 0)
+                return r;
+
+        packet->dhcp.yiaddr = address;
+
+        lease_time = htobe32(req->lifetime);
+        r = dhcp_option_append(&packet->dhcp, req->max_optlen, &offset, 0,
+                               DHCP_OPTION_IP_ADDRESS_LEASE_TIME, 4,
+                               &lease_time);
+        if (r < 0)
+                return r;
+
+        r = dhcp_option_append(&packet->dhcp, req->max_optlen, &offset, 0,
+                               DHCP_OPTION_SUBNET_MASK, 4, &server->netmask);
+        if (r < 0)
+                return r;
+
+        r = dhcp_option_append(&packet->dhcp, req->max_optlen, &offset, 0,
+                               DHCP_OPTION_ROUTER, 4, &server->address);
+        if (r < 0)
+                return r;
+
+        r = dhcp_server_send_packet(server, req, packet, DHCP_OFFER, offset);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+static int server_send_ack(sd_dhcp_server *server, DHCPRequest *req,
+                           be32_t address) {
+        _cleanup_free_ DHCPPacket *packet = NULL;
+        size_t offset;
+        be32_t lease_time;
+        int r;
+
+        r = server_message_init(server, &packet, DHCP_ACK, &offset, req);
+        if (r < 0)
+                return r;
+
+        packet->dhcp.yiaddr = address;
+
+        lease_time = htobe32(req->lifetime);
+        r = dhcp_option_append(&packet->dhcp, req->max_optlen, &offset, 0,
+                               DHCP_OPTION_IP_ADDRESS_LEASE_TIME, 4,
+                               &lease_time);
+        if (r < 0)
+                return r;
+
+        r = dhcp_option_append(&packet->dhcp, req->max_optlen, &offset, 0,
+                               DHCP_OPTION_SUBNET_MASK, 4, &server->netmask);
+        if (r < 0)
+                return r;
+
+        r = dhcp_option_append(&packet->dhcp, req->max_optlen, &offset, 0,
+                               DHCP_OPTION_ROUTER, 4, &server->address);
+        if (r < 0)
+                return r;
+
+        r = dhcp_server_send_packet(server, req, packet, DHCP_ACK, offset);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+static int server_send_nak(sd_dhcp_server *server, DHCPRequest *req) {
+        _cleanup_free_ DHCPPacket *packet = NULL;
+        size_t offset;
+        int r;
+
+        r = server_message_init(server, &packet, DHCP_NAK, &offset, req);
+        if (r < 0)
+                return r;
+
+        r = dhcp_server_send_packet(server, req, packet, DHCP_NAK, offset);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+static int server_send_forcerenew(sd_dhcp_server *server, be32_t address,
+                                  be32_t gateway, uint8_t chaddr[]) {
+        _cleanup_free_ DHCPPacket *packet = NULL;
+        size_t optoffset = 0;
+        int r;
+
+        assert(server);
+        assert(address != INADDR_ANY);
+        assert(chaddr);
+
+        packet = malloc0(sizeof(DHCPPacket) + DHCP_MIN_OPTIONS_SIZE);
+        if (!packet)
+                return -ENOMEM;
+
+        r = dhcp_message_init(&packet->dhcp, BOOTREPLY, 0,
+                              DHCP_FORCERENEW, DHCP_MIN_OPTIONS_SIZE,
+                              &optoffset);
+        if (r < 0)
+                return r;
+
+        r = dhcp_option_append(&packet->dhcp, DHCP_MIN_OPTIONS_SIZE,
+                               &optoffset, 0, DHCP_OPTION_END, 0, NULL);
+        if (r < 0)
+                return r;
+
+        memcpy(&packet->dhcp.chaddr, chaddr, ETH_ALEN);
+
+        r = dhcp_server_send_udp(server, address, &packet->dhcp,
+                                 sizeof(DHCPMessage) + optoffset);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+static int parse_request(uint8_t code, uint8_t len, const uint8_t *option,
+                         void *user_data) {
+        DHCPRequest *req = user_data;
+
+        assert(req);
+
+        switch(code) {
+        case DHCP_OPTION_IP_ADDRESS_LEASE_TIME:
+                if (len == 4)
+                        req->lifetime = be32toh(*(be32_t*)option);
+
+                break;
+        case DHCP_OPTION_REQUESTED_IP_ADDRESS:
+                if (len == 4)
+                        req->requested_ip = *(be32_t*)option;
+
+                break;
+        case DHCP_OPTION_SERVER_IDENTIFIER:
+                if (len == 4)
+                        req->server_id = *(be32_t*)option;
+
+                break;
+        case DHCP_OPTION_CLIENT_IDENTIFIER:
+                if (len >= 2) {
+                        uint8_t *data;
+
+                        data = memdup(option, len);
+                        if (!data)
+                                return -ENOMEM;
+
+                        free(req->client_id.data);
+                        req->client_id.data = data;
+                        req->client_id.length = len;
+                }
+
+                break;
+        case DHCP_OPTION_MAXIMUM_MESSAGE_SIZE:
+                if (len == 2)
+                        req->max_optlen = be16toh(*(be16_t*)option) -
+                                          - sizeof(DHCPPacket);
+
+                break;
+        }
+
+        return 0;
+}
+
+static void dhcp_request_free(DHCPRequest *req) {
+        if (!req)
+                return;
+
+        free(req->client_id.data);
+        free(req);
+}
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(DHCPRequest*, dhcp_request_free);
+#define _cleanup_dhcp_request_free_ _cleanup_(dhcp_request_freep)
+
+static int ensure_sane_request(DHCPRequest *req, DHCPMessage *message) {
+        assert(req);
+        assert(message);
+
+        req->message = message;
+
+        /* set client id based on mac address if client did not send an explicit
+           one */
+        if (!req->client_id.data) {
+                uint8_t *data;
+
+                data = new0(uint8_t, ETH_ALEN + 1);
+                if (!data)
+                        return -ENOMEM;
+
+                req->client_id.length = ETH_ALEN + 1;
+                req->client_id.data = data;
+                req->client_id.data[0] = 0x01;
+                memcpy(&req->client_id.data[1], &message->chaddr, ETH_ALEN);
+        }
+
+        if (req->max_optlen < DHCP_MIN_OPTIONS_SIZE)
+                req->max_optlen = DHCP_MIN_OPTIONS_SIZE;
+
+        if (!req->lifetime)
+                req->lifetime = DHCP_DEFAULT_LEASE_TIME;
+
+        return 0;
+}
+
+static int get_pool_offset(sd_dhcp_server *server, be32_t requested_ip) {
+        assert(server);
+
+        if (!server->pool_size)
+                return -EINVAL;
+
+        if (be32toh(requested_ip) < be32toh(server->pool_start) ||
+            be32toh(requested_ip) >= be32toh(server->pool_start) +
+                                             + server->pool_size)
+                return -EINVAL;
+
+        return be32toh(requested_ip) - be32toh(server->pool_start);
+}
+
+int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message,
+                               size_t length) {
+        _cleanup_dhcp_request_free_ DHCPRequest *req = NULL;
+        DHCPLease *existing_lease;
+        int type, r;
+
+        assert(server);
+        assert(message);
+
+        if (message->op != BOOTREQUEST ||
+            message->htype != ARPHRD_ETHER ||
+            message->hlen != ETHER_ADDR_LEN)
+                return 0;
+
+        req = new0(DHCPRequest, 1);
+        if (!req)
+                return -ENOMEM;
+
+        type = dhcp_option_parse(message, length, parse_request, req);
+        if (type < 0)
+                return 0;
+
+        r = ensure_sane_request(req, message);
+        if (r < 0)
+                /* this only fails on critical errors */
+                return r;
+
+        existing_lease = hashmap_get(server->leases_by_client_id,
+                                     &req->client_id);
+
+        switch(type) {
+        case DHCP_DISCOVER:
+        {
+                be32_t address = INADDR_ANY;
+                unsigned i;
+
+                log_dhcp_server(server, "DISCOVER (0x%x)",
+                                be32toh(req->message->xid));
+
+                if (!server->pool_size)
+                        /* no pool allocated */
+                        return 0;
+
+                /* for now pick a random free address from the pool */
+                if (existing_lease)
+                        address = existing_lease->address;
+                else {
+                        for (i = 0; i < server->pool_size; i++) {
+                                if (!server->bound_leases[server->next_offer]) {
+                                        address = htobe32(be32toh(server->pool_start) + server->next_offer);
+                                        break;
+                                } else
+                                        server->next_offer = (server->next_offer + 1) % server->pool_size;
+                        }
+                }
+
+                if (address == INADDR_ANY)
+                        /* no free addresses left */
+                        return 0;
+
+                r = server_send_offer(server, req, address);
+                if (r < 0) {
+                        /* this only fails on critical errors */
+                        log_dhcp_server(server, "could not send offer: %s",
+                                        strerror(-r));
+                        return r;
+                } else {
+                        log_dhcp_server(server, "OFFER (0x%x)",
+                                        be32toh(req->message->xid));
+                        return DHCP_OFFER;
+                }
+
+                break;
+        }
+        case DHCP_DECLINE:
+                log_dhcp_server(server, "DECLINE (0x%x)",
+                                be32toh(req->message->xid));
+
+                /* TODO: make sure we don't offer this address again */
+
+                return 1;
+
+                break;
+        case DHCP_REQUEST:
+        {
+                be32_t address;
+                bool init_reboot = false;
+                int pool_offset;
+
+                /* see RFC 2131, section 4.3.2 */
+
+                if (req->server_id) {
+                        log_dhcp_server(server, "REQUEST (selecting) (0x%x)",
+                                        be32toh(req->message->xid));
+
+                        /* SELECTING */
+                        if (req->server_id != server->address)
+                                /* client did not pick us */
+                                return 0;
+
+                        if (req->message->ciaddr)
+                                /* this MUST be zero */
+                                return 0;
+
+                        if (!req->requested_ip)
+                                /* this must be filled in with the yiaddr
+                                   from the chosen OFFER */
+                                return 0;
+
+                        address = req->requested_ip;
+                } else if (req->requested_ip) {
+                        log_dhcp_server(server, "REQUEST (init-reboot) (0x%x)",
+                                        be32toh(req->message->xid));
+
+                        /* INIT-REBOOT */
+                        if (req->message->ciaddr)
+                                /* this MUST be zero */
+                                return 0;
+
+                        /* TODO: check more carefully if IP is correct */
+                        address = req->requested_ip;
+                        init_reboot = true;
+                } else {
+                        log_dhcp_server(server, "REQUEST (rebinding/renewing) (0x%x)",
+                                        be32toh(req->message->xid));
+
+                        /* REBINDING / RENEWING */
+                        if (!req->message->ciaddr)
+                                /* this MUST be filled in with clients IP address */
+                                return 0;
+
+                        address = req->message->ciaddr;
+                }
+
+                pool_offset = get_pool_offset(server, address);
+
+                /* verify that the requested address is from the pool, and either
+                   owned by the current client or free */
+                if (pool_offset >= 0 &&
+                    server->bound_leases[pool_offset] == existing_lease) {
+                        DHCPLease *lease;
+                        usec_t time_now;
+
+                        if (!existing_lease) {
+                                lease = new0(DHCPLease, 1);
+                                lease->address = req->requested_ip;
+                                lease->client_id.data = memdup(req->client_id.data,
+                                                               req->client_id.length);
+                                if (!lease->client_id.data) {
+                                        free(lease);
+                                        return -ENOMEM;
+                                }
+                                lease->client_id.length = req->client_id.length;
+                                memcpy(&lease->chaddr, &req->message->chaddr,
+                                       ETH_ALEN);
+                                lease->gateway = req->message->giaddr;
+                        } else
+                                lease = existing_lease;
+
+                        r = sd_event_now(server->event,
+                                         clock_boottime_or_monotonic(),
+                                         &time_now);
+                        if (r < 0)
+                                time_now = now(clock_boottime_or_monotonic());
+                        lease->expiration = req->lifetime * USEC_PER_SEC + time_now;
+
+                        r = server_send_ack(server, req, address);
+                        if (r < 0) {
+                                /* this only fails on critical errors */
+                                log_dhcp_server(server, "could not send ack: %s",
+                                                strerror(-r));
+
+                                if (!existing_lease)
+                                        dhcp_lease_free(lease);
+
+                                return r;
+                        } else {
+                                log_dhcp_server(server, "ACK (0x%x)",
+                                                be32toh(req->message->xid));
+
+                                server->bound_leases[pool_offset] = lease;
+                                hashmap_put(server->leases_by_client_id,
+                                            &lease->client_id, lease);
+
+                                return DHCP_ACK;
+                        }
+                } else if (init_reboot) {
+                        r = server_send_nak(server, req);
+                        if (r < 0) {
+                                /* this only fails on critical errors */
+                                log_dhcp_server(server, "could not send nak: %s",
+                                                strerror(-r));
+                                return r;
+                        } else {
+                                log_dhcp_server(server, "NAK (0x%x)",
+                                                be32toh(req->message->xid));
+                                return DHCP_NAK;
+                        }
+                }
+
+                break;
+        }
+        case DHCP_RELEASE: {
+                int pool_offset;
+
+                log_dhcp_server(server, "RELEASE (0x%x)",
+                                be32toh(req->message->xid));
+
+                if (!existing_lease)
+                        return 0;
+
+                if (existing_lease->address != req->message->ciaddr)
+                        return 0;
+
+                pool_offset = get_pool_offset(server, req->message->ciaddr);
+                if (pool_offset < 0)
+                        return 0;
+
+                if (server->bound_leases[pool_offset] == existing_lease) {
+                        server->bound_leases[pool_offset] = NULL;
+                        hashmap_remove(server->leases_by_client_id, existing_lease);
+                        dhcp_lease_free(existing_lease);
+
+                        return 1;
+                } else
+                        return 0;
+        }
+        }
+
+        return 0;
+}
+
+static int server_receive_message(sd_event_source *s, int fd,
+                                  uint32_t revents, void *userdata) {
+        _cleanup_free_ DHCPMessage *message = NULL;
+        uint8_t cmsgbuf[CMSG_LEN(sizeof(struct in_pktinfo))];
+        sd_dhcp_server *server = userdata;
+        struct iovec iov = {};
+        struct msghdr msg = {
+                .msg_iov = &iov,
+                .msg_iovlen = 1,
+                .msg_control = cmsgbuf,
+                .msg_controllen = sizeof(cmsgbuf),
+        };
+        struct cmsghdr *cmsg;
+        int buflen = 0, len, r;
+
+        assert(server);
+
+        r = ioctl(fd, FIONREAD, &buflen);
+        if (r < 0)
+                return r;
+        if (buflen < 0)
+                return -EIO;
+
+        message = malloc0(buflen);
+        if (!message)
+                return -ENOMEM;
+
+        iov.iov_base = message;
+        iov.iov_len = buflen;
+
+        len = recvmsg(fd, &msg, 0);
+        if (len < buflen)
+                return 0;
+        else if ((size_t)len < sizeof(DHCPMessage))
+                return 0;
+
+        for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+                if (cmsg->cmsg_level == IPPROTO_IP &&
+                    cmsg->cmsg_type == IP_PKTINFO &&
+                    cmsg->cmsg_len == CMSG_LEN(sizeof(struct in_pktinfo))) {
+                        struct in_pktinfo *info = (struct in_pktinfo*)CMSG_DATA(cmsg);
+
+                        /* TODO figure out if this can be done as a filter on
+                         * the socket, like for IPv6 */
+                        if (server->index != info->ipi_ifindex)
+                                return 0;
+
+                        break;
+                }
+        }
+
+        return dhcp_server_handle_message(server, message, (size_t)len);
+}
+
+int sd_dhcp_server_start(sd_dhcp_server *server) {
+        int r;
+
+        assert_return(server, -EINVAL);
+        assert_return(server->event, -EINVAL);
+        assert_return(!server->receive_message, -EBUSY);
+        assert_return(server->fd_raw == -1, -EBUSY);
+        assert_return(server->fd == -1, -EBUSY);
+        assert_return(server->address != htobe32(INADDR_ANY), -EUNATCH);
+
+        r = socket(AF_PACKET, SOCK_DGRAM | SOCK_NONBLOCK, 0);
+        if (r < 0) {
+                r = -errno;
+                sd_dhcp_server_stop(server);
+                return r;
+        }
+        server->fd_raw = r;
+
+        r = dhcp_network_bind_udp_socket(INADDR_ANY, DHCP_PORT_SERVER);
+        if (r < 0) {
+                sd_dhcp_server_stop(server);
+                return r;
+        }
+        server->fd = r;
+
+        r = sd_event_add_io(server->event, &server->receive_message,
+                            server->fd, EPOLLIN,
+                            server_receive_message, server);
+        if (r < 0) {
+                sd_dhcp_server_stop(server);
+                return r;
+        }
+
+        r = sd_event_source_set_priority(server->receive_message,
+                                         server->event_priority);
+        if (r < 0) {
+                sd_dhcp_server_stop(server);
+                return r;
+        }
+
+        log_dhcp_server(server, "STARTED");
+
+        return 0;
+}
+
+int sd_dhcp_server_forcerenew(sd_dhcp_server *server) {
+        unsigned i;
+        int r = 0;
+
+        assert_return(server, -EINVAL);
+        assert(server->bound_leases);
+
+        for (i = 0; i < server->pool_size; i++) {
+                DHCPLease *lease = server->bound_leases[i];
+
+                if (!lease)
+                        continue;
+
+                r = server_send_forcerenew(server, lease->address,
+                                           lease->gateway,
+                                           lease->chaddr);
+                if (r < 0)
+                        return r;
+                else
+                        log_dhcp_server(server, "FORCERENEW");
+        }
+
+        return r;
+}
diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c
new file mode 100644 (file)
index 0000000..f69c0ed
--- /dev/null
@@ -0,0 +1,1113 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright (C) 2014 Intel Corporation. All rights reserved.
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <string.h>
+#include <sys/ioctl.h>
+
+#include "udev.h"
+#include "udev-util.h"
+#include "virt.h"
+#include "siphash24.h"
+#include "util.h"
+#include "refcnt.h"
+
+#include "network-internal.h"
+#include "sd-dhcp6-client.h"
+#include "dhcp6-protocol.h"
+#include "dhcp6-internal.h"
+#include "dhcp6-lease-internal.h"
+
+#define SYSTEMD_PEN 43793
+#define HASH_KEY SD_ID128_MAKE(80,11,8c,c2,fe,4a,03,ee,3e,d6,0c,6f,36,39,14,09)
+
+struct sd_dhcp6_client {
+        RefCount n_ref;
+
+        enum DHCP6State state;
+        sd_event *event;
+        int event_priority;
+        int index;
+        struct ether_addr mac_addr;
+        DHCP6IA ia_na;
+        be32_t transaction_id;
+        struct sd_dhcp6_lease *lease;
+        int fd;
+        be16_t *req_opts;
+        size_t req_opts_allocated;
+        size_t req_opts_len;
+        sd_event_source *receive_message;
+        usec_t retransmit_time;
+        uint8_t retransmit_count;
+        sd_event_source *timeout_resend;
+        sd_event_source *timeout_resend_expire;
+        sd_dhcp6_client_cb_t cb;
+        void *userdata;
+
+        struct duid_en {
+                uint16_t type; /* DHCP6_DUID_EN */
+                uint32_t pen;
+                uint8_t id[8];
+        } _packed_ duid;
+};
+
+static const uint16_t default_req_opts[] = {
+        DHCP6_OPTION_DNS_SERVERS,
+        DHCP6_OPTION_DOMAIN_LIST,
+        DHCP6_OPTION_NTP_SERVER,
+};
+
+const char * dhcp6_message_type_table[_DHCP6_MESSAGE_MAX] = {
+        [DHCP6_SOLICIT] = "SOLICIT",
+        [DHCP6_ADVERTISE] = "ADVERTISE",
+        [DHCP6_REQUEST] = "REQUEST",
+        [DHCP6_CONFIRM] = "CONFIRM",
+        [DHCP6_RENEW] = "RENEW",
+        [DHCP6_REBIND] = "REBIND",
+        [DHCP6_REPLY] = "REPLY",
+        [DHCP6_RELEASE] = "RELEASE",
+        [DHCP6_DECLINE] = "DECLINE",
+        [DHCP6_RECONFIGURE] = "RECONFIGURE",
+        [DHCP6_INFORMATION_REQUEST] = "INFORMATION-REQUEST",
+        [DHCP6_RELAY_FORW] = "RELAY-FORW",
+        [DHCP6_RELAY_REPL] = "RELAY-REPL",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(dhcp6_message_type, int);
+
+const char * dhcp6_message_status_table[_DHCP6_STATUS_MAX] = {
+        [DHCP6_STATUS_SUCCESS] = "Success",
+        [DHCP6_STATUS_UNSPEC_FAIL] = "Unspecified failure",
+        [DHCP6_STATUS_NO_ADDRS_AVAIL] = "No addresses available",
+        [DHCP6_STATUS_NO_BINDING] = "Binding unavailable",
+        [DHCP6_STATUS_NOT_ON_LINK] = "Not on link",
+        [DHCP6_STATUS_USE_MULTICAST] = "Use multicast",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(dhcp6_message_status, int);
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(sd_dhcp6_client*, sd_dhcp6_client_unref);
+#define _cleanup_dhcp6_client_unref_ _cleanup_(sd_dhcp6_client_unrefp)
+
+#define DHCP6_CLIENT_DONT_DESTROY(client) \
+        _cleanup_dhcp6_client_unref_ _unused_ sd_dhcp6_client *_dont_destroy_##client = sd_dhcp6_client_ref(client)
+
+static int client_start(sd_dhcp6_client *client, enum DHCP6State state);
+
+int sd_dhcp6_client_set_callback(sd_dhcp6_client *client,
+                                 sd_dhcp6_client_cb_t cb, void *userdata)
+{
+        assert_return(client, -EINVAL);
+
+        client->cb = cb;
+        client->userdata = userdata;
+
+        return 0;
+}
+
+int sd_dhcp6_client_set_index(sd_dhcp6_client *client, int interface_index)
+{
+        assert_return(client, -EINVAL);
+        assert_return(interface_index >= -1, -EINVAL);
+
+        client->index = interface_index;
+
+        return 0;
+}
+
+int sd_dhcp6_client_set_mac(sd_dhcp6_client *client,
+                            const struct ether_addr *mac_addr)
+{
+        assert_return(client, -EINVAL);
+
+        if (mac_addr)
+                memcpy(&client->mac_addr, mac_addr, sizeof(client->mac_addr));
+        else
+                memset(&client->mac_addr, 0x00, sizeof(client->mac_addr));
+
+        return 0;
+}
+
+int sd_dhcp6_client_set_request_option(sd_dhcp6_client *client,
+                                       uint16_t option) {
+        size_t t;
+
+        assert_return(client, -EINVAL);
+        assert_return(client->state == DHCP6_STATE_STOPPED, -EBUSY);
+
+        switch(option) {
+        case DHCP6_OPTION_DNS_SERVERS:
+        case DHCP6_OPTION_DOMAIN_LIST:
+        case DHCP6_OPTION_SNTP_SERVERS:
+        case DHCP6_OPTION_NTP_SERVER:
+                break;
+
+        default:
+                return -EINVAL;
+        }
+
+        for (t = 0; t < client->req_opts_len; t++)
+                if (client->req_opts[t] == htobe16(option))
+                        return -EEXIST;
+
+        if (!GREEDY_REALLOC(client->req_opts, client->req_opts_allocated,
+                            client->req_opts_len + 1))
+                return -ENOMEM;
+
+        client->req_opts[client->req_opts_len++] = htobe16(option);
+
+        return 0;
+}
+
+int sd_dhcp6_client_get_lease(sd_dhcp6_client *client, sd_dhcp6_lease **ret) {
+        assert_return(client, -EINVAL);
+        assert_return(ret, -EINVAL);
+
+        if (!client->lease)
+                return -ENOMSG;
+
+        *ret = sd_dhcp6_lease_ref(client->lease);
+
+        return 0;
+}
+
+static void client_notify(sd_dhcp6_client *client, int event) {
+        if (client->cb)
+                client->cb(client, event, client->userdata);
+}
+
+static int client_reset(sd_dhcp6_client *client) {
+        assert_return(client, -EINVAL);
+
+        client->receive_message =
+                sd_event_source_unref(client->receive_message);
+
+        client->fd = safe_close(client->fd);
+
+        client->transaction_id = 0;
+
+        client->ia_na.timeout_t1 =
+                sd_event_source_unref(client->ia_na.timeout_t1);
+        client->ia_na.timeout_t2 =
+                sd_event_source_unref(client->ia_na.timeout_t2);
+
+        client->retransmit_time = 0;
+        client->retransmit_count = 0;
+        client->timeout_resend = sd_event_source_unref(client->timeout_resend);
+        client->timeout_resend_expire =
+                sd_event_source_unref(client->timeout_resend_expire);
+
+        client->state = DHCP6_STATE_STOPPED;
+
+        return 0;
+}
+
+static void client_stop(sd_dhcp6_client *client, int error) {
+        DHCP6_CLIENT_DONT_DESTROY(client);
+
+        assert(client);
+
+        client_notify(client, error);
+
+        client_reset(client);
+}
+
+static int client_send_message(sd_dhcp6_client *client) {
+        _cleanup_free_ DHCP6Message *message = NULL;
+        struct in6_addr all_servers =
+                IN6ADDR_ALL_DHCP6_RELAY_AGENTS_AND_SERVERS_INIT;
+        size_t len, optlen = 512;
+        uint8_t *opt;
+        int r;
+
+        len = sizeof(DHCP6Message) + optlen;
+
+        message = malloc0(len);
+        if (!message)
+                return -ENOMEM;
+
+        opt = (uint8_t *)(message + 1);
+
+        message->transaction_id = client->transaction_id;
+
+        switch(client->state) {
+        case DHCP6_STATE_SOLICITATION:
+                message->type = DHCP6_SOLICIT;
+
+                r = dhcp6_option_append(&opt, &optlen,
+                                        DHCP6_OPTION_RAPID_COMMIT, 0, NULL);
+                if (r < 0)
+                        return r;
+
+                r = dhcp6_option_append_ia(&opt, &optlen, &client->ia_na);
+                if (r < 0)
+                        return r;
+
+                break;
+
+        case DHCP6_STATE_REQUEST:
+        case DHCP6_STATE_RENEW:
+
+                if (client->state == DHCP6_STATE_REQUEST)
+                        message->type = DHCP6_REQUEST;
+                else
+                        message->type = DHCP6_RENEW;
+
+                r = dhcp6_option_append(&opt, &optlen, DHCP6_OPTION_SERVERID,
+                                        client->lease->serverid_len,
+                                        client->lease->serverid);
+                if (r < 0)
+                        return r;
+
+                r = dhcp6_option_append_ia(&opt, &optlen, &client->lease->ia);
+                if (r < 0)
+                        return r;
+
+                break;
+
+        case DHCP6_STATE_REBIND:
+                message->type = DHCP6_REBIND;
+
+                r = dhcp6_option_append_ia(&opt, &optlen, &client->lease->ia);
+                if (r < 0)
+                        return r;
+
+                break;
+
+        case DHCP6_STATE_STOPPED:
+        case DHCP6_STATE_BOUND:
+                return -EINVAL;
+        }
+
+        r = dhcp6_option_append(&opt, &optlen, DHCP6_OPTION_ORO,
+                                client->req_opts_len * sizeof(be16_t),
+                                client->req_opts);
+        if (r < 0)
+                return r;
+
+        r = dhcp6_option_append(&opt, &optlen, DHCP6_OPTION_CLIENTID,
+                                sizeof(client->duid), &client->duid);
+        if (r < 0)
+                return r;
+
+        r = dhcp6_network_send_udp_socket(client->fd, &all_servers, message,
+                                          len - optlen);
+        if (r < 0)
+                return r;
+
+        log_dhcp6_client(client, "Sent %s",
+                         dhcp6_message_type_to_string(message->type));
+
+        return 0;
+}
+
+static int client_timeout_t2(sd_event_source *s, uint64_t usec,
+                             void *userdata) {
+        sd_dhcp6_client *client = userdata;
+
+        assert_return(s, -EINVAL);
+        assert_return(client, -EINVAL);
+        assert_return(client->lease, -EINVAL);
+
+        client->lease->ia.timeout_t2 =
+                sd_event_source_unref(client->lease->ia.timeout_t2);
+
+        log_dhcp6_client(client, "Timeout T2");
+
+        client_start(client, DHCP6_STATE_REBIND);
+
+        return 0;
+}
+
+static int client_timeout_t1(sd_event_source *s, uint64_t usec,
+                             void *userdata) {
+        sd_dhcp6_client *client = userdata;
+
+        assert_return(s, -EINVAL);
+        assert_return(client, -EINVAL);
+        assert_return(client->lease, -EINVAL);
+
+        client->lease->ia.timeout_t1 =
+                sd_event_source_unref(client->lease->ia.timeout_t1);
+
+        log_dhcp6_client(client, "Timeout T1");
+
+        client_start(client, DHCP6_STATE_RENEW);
+
+        return 0;
+}
+
+static int client_timeout_resend_expire(sd_event_source *s, uint64_t usec,
+                                        void *userdata) {
+        sd_dhcp6_client *client = userdata;
+        DHCP6_CLIENT_DONT_DESTROY(client);
+        enum DHCP6State state;
+
+        assert(s);
+        assert(client);
+        assert(client->event);
+
+        state = client->state;
+
+        client_stop(client, DHCP6_EVENT_RESEND_EXPIRE);
+
+        /* RFC 3315, section 18.1.4., says that "...the client may choose to
+           use a Solicit message to locate a new DHCP server..." */
+        if (state == DHCP6_STATE_REBIND)
+                client_start(client, DHCP6_STATE_SOLICITATION);
+
+        return 0;
+}
+
+static usec_t client_timeout_compute_random(usec_t val) {
+        return val - val / 10 +
+                (random_u32() % (2 * USEC_PER_SEC)) * val / 10 / USEC_PER_SEC;
+}
+
+static int client_timeout_resend(sd_event_source *s, uint64_t usec,
+                                 void *userdata) {
+        int r = 0;
+        sd_dhcp6_client *client = userdata;
+        usec_t time_now, init_retransmit_time = 0, max_retransmit_time = 0;
+        usec_t max_retransmit_duration = 0;
+        uint8_t max_retransmit_count = 0;
+        char time_string[FORMAT_TIMESPAN_MAX];
+        uint32_t expire = 0;
+
+        assert(s);
+        assert(client);
+        assert(client->event);
+
+        client->timeout_resend = sd_event_source_unref(client->timeout_resend);
+
+        switch (client->state) {
+        case DHCP6_STATE_SOLICITATION:
+
+                if (client->retransmit_count && client->lease) {
+                        client_start(client, DHCP6_STATE_REQUEST);
+                        return 0;
+                }
+
+                init_retransmit_time = DHCP6_SOL_TIMEOUT;
+                max_retransmit_time = DHCP6_SOL_MAX_RT;
+
+                break;
+
+        case DHCP6_STATE_REQUEST:
+                init_retransmit_time = DHCP6_REQ_TIMEOUT;
+                max_retransmit_time = DHCP6_REQ_MAX_RT;
+                max_retransmit_count = DHCP6_REQ_MAX_RC;
+
+                break;
+
+        case DHCP6_STATE_RENEW:
+                init_retransmit_time = DHCP6_REN_TIMEOUT;
+                max_retransmit_time = DHCP6_REN_MAX_RT;
+
+                /* RFC 3315, section 18.1.3. says max retransmit duration will
+                   be the remaining time until T2. Instead of setting MRD,
+                   wait for T2 to trigger with the same end result */
+
+                break;
+
+        case DHCP6_STATE_REBIND:
+                init_retransmit_time = DHCP6_REB_TIMEOUT;
+                max_retransmit_time = DHCP6_REB_MAX_RT;
+
+                if (!client->timeout_resend_expire) {
+                        r = dhcp6_lease_ia_rebind_expire(&client->lease->ia,
+                                                         &expire);
+                        if (r < 0) {
+                                client_stop(client, r);
+                                return 0;
+                        }
+                        max_retransmit_duration = expire * USEC_PER_SEC;
+                }
+
+                break;
+
+        case DHCP6_STATE_STOPPED:
+        case DHCP6_STATE_BOUND:
+                return 0;
+        }
+
+        if (max_retransmit_count &&
+            client->retransmit_count >= max_retransmit_count) {
+                client_stop(client, DHCP6_EVENT_RETRANS_MAX);
+                return 0;
+        }
+
+        r = client_send_message(client);
+        if (r >= 0)
+                client->retransmit_count++;
+
+
+        r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now);
+        if (r < 0)
+                goto error;
+
+        if (!client->retransmit_time) {
+                client->retransmit_time =
+                        client_timeout_compute_random(init_retransmit_time);
+
+                if (client->state == DHCP6_STATE_SOLICITATION)
+                        client->retransmit_time += init_retransmit_time / 10;
+
+        } else {
+                if (max_retransmit_time &&
+                    client->retransmit_time > max_retransmit_time / 2)
+                        client->retransmit_time = client_timeout_compute_random(max_retransmit_time);
+                else
+                        client->retransmit_time += client_timeout_compute_random(client->retransmit_time);
+        }
+
+        log_dhcp6_client(client, "Next retransmission in %s",
+                         format_timespan(time_string, FORMAT_TIMESPAN_MAX,
+                                         client->retransmit_time, 0));
+
+        r = sd_event_add_time(client->event, &client->timeout_resend,
+                              clock_boottime_or_monotonic(),
+                              time_now + client->retransmit_time,
+                              10 * USEC_PER_MSEC, client_timeout_resend,
+                              client);
+        if (r < 0)
+                goto error;
+
+        r = sd_event_source_set_priority(client->timeout_resend,
+                                         client->event_priority);
+        if (r < 0)
+                goto error;
+
+        if (max_retransmit_duration && !client->timeout_resend_expire) {
+
+                log_dhcp6_client(client, "Max retransmission duration %"PRIu64" secs",
+                                 max_retransmit_duration / USEC_PER_SEC);
+
+                r = sd_event_add_time(client->event,
+                                      &client->timeout_resend_expire,
+                                      clock_boottime_or_monotonic(),
+                                      time_now + max_retransmit_duration,
+                                      USEC_PER_SEC,
+                                      client_timeout_resend_expire, client);
+                if (r < 0)
+                        goto error;
+
+                r = sd_event_source_set_priority(client->timeout_resend_expire,
+                                                 client->event_priority);
+                if (r < 0)
+                        goto error;
+        }
+
+error:
+        if (r < 0)
+                client_stop(client, r);
+
+        return 0;
+}
+
+static int client_ensure_iaid(sd_dhcp6_client *client) {
+        /* name is a pointer to memory in the udev_device struct, so must
+           have the same scope */
+        _cleanup_udev_device_unref_ struct udev_device *device = NULL;
+        const char *name = NULL;
+        uint64_t id;
+
+        assert(client);
+
+        if (client->ia_na.id)
+                return 0;
+
+        if (detect_container(NULL) <= 0) {
+                /* not in a container, udev will be around */
+                _cleanup_udev_unref_ struct udev *udev;
+                char ifindex_str[2 + DECIMAL_STR_MAX(int)];
+
+                udev = udev_new();
+                if (!udev)
+                        return -ENOMEM;
+
+                sprintf(ifindex_str, "n%d", client->index);
+                device = udev_device_new_from_device_id(udev, ifindex_str);
+                if (!device)
+                        return -errno;
+
+                if (udev_device_get_is_initialized(device) <= 0)
+                        /* not yet ready */
+                        return -EBUSY;
+
+                name = net_get_name(device);
+        }
+
+        if (name)
+                siphash24((uint8_t*)&id, name, strlen(name), HASH_KEY.bytes);
+        else
+                /* fall back to mac address if no predictable name available */
+                siphash24((uint8_t*)&id, &client->mac_addr, ETH_ALEN,
+                          HASH_KEY.bytes);
+
+        /* fold into 32 bits */
+        client->ia_na.id = (id & 0xffffffff) ^ (id >> 32);
+
+        return 0;
+}
+
+static int client_parse_message(sd_dhcp6_client *client,
+                                DHCP6Message *message, size_t len,
+                                sd_dhcp6_lease *lease) {
+        int r;
+        uint8_t *optval, *option = (uint8_t *)(message + 1), *id = NULL;
+        uint16_t optcode, status;
+        size_t optlen, id_len;
+        bool clientid = false;
+        be32_t iaid_lease;
+
+        while ((r = dhcp6_option_parse(&option, &len, &optcode, &optlen,
+                                       &optval)) >= 0) {
+                switch (optcode) {
+                case DHCP6_OPTION_CLIENTID:
+                        if (clientid) {
+                                log_dhcp6_client(client, "%s contains multiple clientids",
+                                                 dhcp6_message_type_to_string(message->type));
+                                return -EINVAL;
+                        }
+
+                        if (optlen != sizeof(client->duid) ||
+                            memcmp(&client->duid, optval, optlen) != 0) {
+                                log_dhcp6_client(client, "%s DUID does not match",
+                                                 dhcp6_message_type_to_string(message->type));
+
+                                return -EINVAL;
+                        }
+                        clientid = true;
+
+                        break;
+
+                case DHCP6_OPTION_SERVERID:
+                        r = dhcp6_lease_get_serverid(lease, &id, &id_len);
+                        if (r >= 0 && id) {
+                                log_dhcp6_client(client, "%s contains multiple serverids",
+                                                 dhcp6_message_type_to_string(message->type));
+                                return -EINVAL;
+                        }
+
+                        r = dhcp6_lease_set_serverid(lease, optval, optlen);
+                        if (r < 0)
+                                return r;
+
+                        break;
+
+                case DHCP6_OPTION_PREFERENCE:
+                        if (optlen != 1)
+                                return -EINVAL;
+
+                        r = dhcp6_lease_set_preference(lease, *optval);
+                        if (r < 0)
+                                return r;
+
+                        break;
+
+                case DHCP6_OPTION_STATUS_CODE:
+                        if (optlen < 2)
+                                return -EINVAL;
+
+                        status = optval[0] << 8 | optval[1];
+                        if (status) {
+                                log_dhcp6_client(client, "%s Status %s",
+                                                 dhcp6_message_type_to_string(message->type),
+                                                 dhcp6_message_status_to_string(status));
+                                return -EINVAL;
+                        }
+
+                        break;
+
+                case DHCP6_OPTION_IA_NA:
+                        r = dhcp6_option_parse_ia(&optval, &optlen, optcode,
+                                                  &lease->ia);
+                        if (r < 0 && r != -ENOMSG)
+                                return r;
+
+                        r = dhcp6_lease_get_iaid(lease, &iaid_lease);
+                        if (r < 0)
+                                return r;
+
+                        if (client->ia_na.id != iaid_lease) {
+                                log_dhcp6_client(client, "%s has wrong IAID",
+                                                 dhcp6_message_type_to_string(message->type));
+                                return -EINVAL;
+                        }
+
+                        break;
+
+                case DHCP6_OPTION_RAPID_COMMIT:
+                        r = dhcp6_lease_set_rapid_commit(lease);
+                        if (r < 0)
+                                return r;
+
+                        break;
+                }
+        }
+
+        if ((r < 0 && r != -ENOMSG) || !clientid) {
+                log_dhcp6_client(client, "%s has incomplete options",
+                                 dhcp6_message_type_to_string(message->type));
+                return -EINVAL;
+        }
+
+        r = dhcp6_lease_get_serverid(lease, &id, &id_len);
+        if (r < 0)
+                log_dhcp6_client(client, "%s has no server id",
+                                 dhcp6_message_type_to_string(message->type));
+
+        return r;
+}
+
+static int client_receive_reply(sd_dhcp6_client *client, DHCP6Message *reply,
+                                size_t len)
+{
+        int r;
+        _cleanup_dhcp6_lease_free_ sd_dhcp6_lease *lease = NULL;
+        bool rapid_commit;
+
+        if (reply->type != DHCP6_REPLY)
+                return 0;
+
+        r = dhcp6_lease_new(&lease);
+        if (r < 0)
+                return -ENOMEM;
+
+        r = client_parse_message(client, reply, len, lease);
+        if (r < 0)
+                return r;
+
+        if (client->state == DHCP6_STATE_SOLICITATION) {
+                r = dhcp6_lease_get_rapid_commit(lease, &rapid_commit);
+                if (r < 0)
+                        return r;
+
+                if (!rapid_commit)
+                        return 0;
+        }
+
+        if (client->lease)
+                dhcp6_lease_clear_timers(&client->lease->ia);
+
+        client->lease = sd_dhcp6_lease_unref(client->lease);
+        client->lease = lease;
+        lease = NULL;
+
+        return DHCP6_STATE_BOUND;
+}
+
+static int client_receive_advertise(sd_dhcp6_client *client,
+                                    DHCP6Message *advertise, size_t len) {
+        int r;
+        _cleanup_dhcp6_lease_free_ sd_dhcp6_lease *lease = NULL;
+        uint8_t pref_advertise = 0, pref_lease = 0;
+
+        if (advertise->type != DHCP6_ADVERTISE)
+                return 0;
+
+        r = dhcp6_lease_new(&lease);
+        if (r < 0)
+                return r;
+
+        r = client_parse_message(client, advertise, len, lease);
+        if (r < 0)
+                return r;
+
+        r = dhcp6_lease_get_preference(lease, &pref_advertise);
+        if (r < 0)
+                return r;
+
+        r = dhcp6_lease_get_preference(client->lease, &pref_lease);
+        if (!client->lease || r < 0 || pref_advertise > pref_lease) {
+                sd_dhcp6_lease_unref(client->lease);
+                client->lease = lease;
+                lease = NULL;
+                r = 0;
+        }
+
+        if (pref_advertise == 255 || client->retransmit_count > 1)
+                r = DHCP6_STATE_REQUEST;
+
+        return r;
+}
+
+static int client_receive_message(sd_event_source *s, int fd, uint32_t revents,
+                                  void *userdata) {
+        sd_dhcp6_client *client = userdata;
+        DHCP6_CLIENT_DONT_DESTROY(client);
+        _cleanup_free_ DHCP6Message *message;
+        int r, buflen, len;
+
+        assert(s);
+        assert(client);
+        assert(client->event);
+
+        r = ioctl(fd, FIONREAD, &buflen);
+        if (r < 0 || buflen <= 0)
+                buflen = DHCP6_MIN_OPTIONS_SIZE;
+
+        message = malloc0(buflen);
+        if (!message)
+                return -ENOMEM;
+
+        len = read(fd, message, buflen);
+        if ((size_t)len < sizeof(DHCP6Message)) {
+                log_dhcp6_client(client, "could not receive message from UDP socket: %m");
+                return 0;
+        }
+
+        switch(message->type) {
+        case DHCP6_SOLICIT:
+        case DHCP6_REQUEST:
+        case DHCP6_CONFIRM:
+        case DHCP6_RENEW:
+        case DHCP6_REBIND:
+        case DHCP6_RELEASE:
+        case DHCP6_DECLINE:
+        case DHCP6_INFORMATION_REQUEST:
+        case DHCP6_RELAY_FORW:
+        case DHCP6_RELAY_REPL:
+                return 0;
+
+        case DHCP6_ADVERTISE:
+        case DHCP6_REPLY:
+        case DHCP6_RECONFIGURE:
+                break;
+
+        default:
+                log_dhcp6_client(client, "unknown message type %d",
+                                 message->type);
+                return 0;
+        }
+
+        if (client->transaction_id != (message->transaction_id &
+                                       htobe32(0x00ffffff)))
+                return 0;
+
+        switch (client->state) {
+        case DHCP6_STATE_SOLICITATION:
+                r = client_receive_advertise(client, message, len);
+
+                if (r == DHCP6_STATE_REQUEST) {
+                        client_start(client, r);
+
+                        break;
+                }
+
+                /* fall through for Soliciation Rapid Commit option check */
+        case DHCP6_STATE_REQUEST:
+        case DHCP6_STATE_RENEW:
+        case DHCP6_STATE_REBIND:
+
+                r = client_receive_reply(client, message, len);
+                if (r < 0)
+                        return 0;
+
+                if (r == DHCP6_STATE_BOUND) {
+
+                        r = client_start(client, DHCP6_STATE_BOUND);
+                        if (r < 0) {
+                                client_stop(client, r);
+                                return 0;
+                        }
+
+                        client_notify(client, DHCP6_EVENT_IP_ACQUIRE);
+                }
+
+                break;
+
+        case DHCP6_STATE_BOUND:
+
+                break;
+
+        case DHCP6_STATE_STOPPED:
+                return 0;
+        }
+
+        if (r >= 0) {
+                log_dhcp6_client(client, "Recv %s",
+                                 dhcp6_message_type_to_string(message->type));
+        }
+
+        return 0;
+}
+
+static int client_start(sd_dhcp6_client *client, enum DHCP6State state)
+{
+        int r;
+        usec_t timeout, time_now;
+        char time_string[FORMAT_TIMESPAN_MAX];
+
+        assert_return(client, -EINVAL);
+        assert_return(client->event, -EINVAL);
+        assert_return(client->index > 0, -EINVAL);
+        assert_return(client->state != state, -EINVAL);
+
+        client->timeout_resend_expire =
+                sd_event_source_unref(client->timeout_resend_expire);
+        client->timeout_resend = sd_event_source_unref(client->timeout_resend);
+        client->retransmit_time = 0;
+        client->retransmit_count = 0;
+
+        switch (state) {
+        case DHCP6_STATE_STOPPED:
+        case DHCP6_STATE_SOLICITATION:
+
+                r = client_ensure_iaid(client);
+                if (r < 0)
+                        return r;
+
+                r = dhcp6_network_bind_udp_socket(client->index, NULL);
+                if (r < 0)
+                        return r;
+
+                client->fd = r;
+
+                r = sd_event_add_io(client->event, &client->receive_message,
+                                    client->fd, EPOLLIN, client_receive_message,
+                                    client);
+                if (r < 0)
+                        return r;
+
+                r = sd_event_source_set_priority(client->receive_message,
+                                                 client->event_priority);
+                if (r < 0)
+                        return r;
+
+                client->state = DHCP6_STATE_SOLICITATION;
+
+                break;
+
+        case DHCP6_STATE_REQUEST:
+        case DHCP6_STATE_RENEW:
+        case DHCP6_STATE_REBIND:
+
+                client->state = state;
+
+                break;
+
+        case DHCP6_STATE_BOUND:
+
+                r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now);
+                if (r < 0)
+                        return r;
+
+                if (client->lease->ia.lifetime_t1 == 0xffffffff ||
+                    client->lease->ia.lifetime_t2 == 0xffffffff) {
+
+                        log_dhcp6_client(client, "infinite T1 0x%08x or T2 0x%08x",
+                                         be32toh(client->lease->ia.lifetime_t1),
+                                         be32toh(client->lease->ia.lifetime_t2));
+
+                        return 0;
+                }
+
+                timeout = client_timeout_compute_random(be32toh(client->lease->ia.lifetime_t1) * USEC_PER_SEC);
+
+                log_dhcp6_client(client, "T1 expires in %s",
+                                 format_timespan(time_string,
+                                                 FORMAT_TIMESPAN_MAX,
+                                                 timeout, 0));
+
+                r = sd_event_add_time(client->event,
+                                      &client->lease->ia.timeout_t1,
+                                      clock_boottime_or_monotonic(), time_now + timeout,
+                                      10 * USEC_PER_SEC, client_timeout_t1,
+                                      client);
+                if (r < 0)
+                        return r;
+
+                r = sd_event_source_set_priority(client->lease->ia.timeout_t1,
+                                                 client->event_priority);
+                if (r < 0)
+                        return r;
+
+                timeout = client_timeout_compute_random(be32toh(client->lease->ia.lifetime_t2) * USEC_PER_SEC);
+
+                log_dhcp6_client(client, "T2 expires in %s",
+                                 format_timespan(time_string,
+                                                 FORMAT_TIMESPAN_MAX,
+                                                 timeout, 0));
+
+                r = sd_event_add_time(client->event,
+                                      &client->lease->ia.timeout_t2,
+                                      clock_boottime_or_monotonic(), time_now + timeout,
+                                      10 * USEC_PER_SEC, client_timeout_t2,
+                                      client);
+                if (r < 0)
+                        return r;
+
+                r = sd_event_source_set_priority(client->lease->ia.timeout_t2,
+                                                 client->event_priority);
+                if (r < 0)
+                        return r;
+
+                client->state = state;
+
+                return 0;
+        }
+
+        client->transaction_id = random_u32() & htobe32(0x00ffffff);
+
+        r = sd_event_add_time(client->event, &client->timeout_resend,
+                              clock_boottime_or_monotonic(), 0, 0, client_timeout_resend,
+                              client);
+        if (r < 0)
+                return r;
+
+        r = sd_event_source_set_priority(client->timeout_resend,
+                                         client->event_priority);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+int sd_dhcp6_client_stop(sd_dhcp6_client *client)
+{
+        client_stop(client, DHCP6_EVENT_STOP);
+
+        return 0;
+}
+
+int sd_dhcp6_client_start(sd_dhcp6_client *client)
+{
+        int r = 0;
+
+        assert_return(client, -EINVAL);
+        assert_return(client->event, -EINVAL);
+        assert_return(client->index > 0, -EINVAL);
+
+        r = client_reset(client);
+        if (r < 0)
+                return r;
+
+        return client_start(client, DHCP6_STATE_SOLICITATION);
+}
+
+int sd_dhcp6_client_attach_event(sd_dhcp6_client *client, sd_event *event,
+                                 int priority)
+{
+        int r;
+
+        assert_return(client, -EINVAL);
+        assert_return(!client->event, -EBUSY);
+
+        if (event)
+                client->event = sd_event_ref(event);
+        else {
+                r = sd_event_default(&client->event);
+                if (r < 0)
+                        return 0;
+        }
+
+        client->event_priority = priority;
+
+        return 0;
+}
+
+int sd_dhcp6_client_detach_event(sd_dhcp6_client *client) {
+        assert_return(client, -EINVAL);
+
+        client->event = sd_event_unref(client->event);
+
+        return 0;
+}
+
+sd_event *sd_dhcp6_client_get_event(sd_dhcp6_client *client) {
+        if (!client)
+                return NULL;
+
+        return client->event;
+}
+
+sd_dhcp6_client *sd_dhcp6_client_ref(sd_dhcp6_client *client) {
+        if (client)
+                assert_se(REFCNT_INC(client->n_ref) >= 2);
+
+        return client;
+}
+
+sd_dhcp6_client *sd_dhcp6_client_unref(sd_dhcp6_client *client) {
+        if (client && REFCNT_DEC(client->n_ref) <= 0) {
+                client_reset(client);
+
+                sd_dhcp6_client_detach_event(client);
+
+                free(client->req_opts);
+                free(client);
+
+                return NULL;
+        }
+
+        return client;
+}
+
+int sd_dhcp6_client_new(sd_dhcp6_client **ret)
+{
+        _cleanup_dhcp6_client_unref_ sd_dhcp6_client *client = NULL;
+        sd_id128_t machine_id;
+        int r;
+        size_t t;
+
+        assert_return(ret, -EINVAL);
+
+        client = new0(sd_dhcp6_client, 1);
+        if (!client)
+                return -ENOMEM;
+
+        client->n_ref = REFCNT_INIT;
+
+        client->ia_na.type = DHCP6_OPTION_IA_NA;
+
+        client->index = -1;
+
+        client->fd = -1;
+
+        /* initialize DUID */
+        client->duid.type = htobe16(DHCP6_DUID_EN);
+        client->duid.pen = htobe32(SYSTEMD_PEN);
+
+        r = sd_id128_get_machine(&machine_id);
+        if (r < 0)
+                return r;
+
+        /* a bit of snake-oil perhaps, but no need to expose the machine-id
+           directly */
+        siphash24(client->duid.id, &machine_id, sizeof(machine_id),
+                  HASH_KEY.bytes);
+
+        client->req_opts_len = ELEMENTSOF(default_req_opts);
+
+        client->req_opts = new0(be16_t, client->req_opts_len);
+        if (!client->req_opts)
+                return -ENOMEM;
+
+        for (t = 0; t < client->req_opts_len; t++)
+                client->req_opts[t] = htobe16(default_req_opts[t]);
+
+        *ret = client;
+        client = NULL;
+
+        return 0;
+}
diff --git a/src/libsystemd-network/sd-dhcp6-lease.c b/src/libsystemd-network/sd-dhcp6-lease.c
new file mode 100644 (file)
index 0000000..b9d0503
--- /dev/null
@@ -0,0 +1,217 @@
+/***
+  This file is part of systemd.
+
+  Copyright (C) 2014 Tom Gundersen
+  Copyright (C) 2014 Intel Corporation. All rights reserved.
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+
+#include "util.h"
+
+#include "dhcp6-lease-internal.h"
+
+int dhcp6_lease_clear_timers(DHCP6IA *ia) {
+        assert_return(ia, -EINVAL);
+
+        ia->timeout_t1 = sd_event_source_unref(ia->timeout_t1);
+        ia->timeout_t2 = sd_event_source_unref(ia->timeout_t2);
+
+        return 0;
+}
+
+int dhcp6_lease_ia_rebind_expire(const DHCP6IA *ia, uint32_t *expire) {
+        DHCP6Address *addr;
+        uint32_t valid = 0, t;
+
+        assert_return(ia, -EINVAL);
+        assert_return(expire, -EINVAL);
+
+        LIST_FOREACH(addresses, addr, ia->addresses) {
+                t = be32toh(addr->lifetime_valid);
+                if (valid < t)
+                        valid = t;
+        }
+
+        t = be32toh(ia->lifetime_t2);
+        if (t > valid)
+                return -EINVAL;
+
+        *expire = valid - t;
+
+        return 0;
+}
+
+DHCP6IA *dhcp6_lease_free_ia(DHCP6IA *ia) {
+        DHCP6Address *address;
+
+        if (!ia)
+                return NULL;
+
+        dhcp6_lease_clear_timers(ia);
+
+        while (ia->addresses) {
+                address = ia->addresses;
+
+                LIST_REMOVE(addresses, ia->addresses, address);
+
+                free(address);
+        }
+
+        return NULL;
+}
+
+int dhcp6_lease_set_serverid(sd_dhcp6_lease *lease, const uint8_t *id,
+                             size_t len) {
+        assert_return(lease, -EINVAL);
+        assert_return(id, -EINVAL);
+
+        free(lease->serverid);
+
+        lease->serverid = memdup(id, len);
+        if (!lease->serverid)
+                return -EINVAL;
+
+        lease->serverid_len = len;
+
+        return 0;
+}
+
+int dhcp6_lease_get_serverid(sd_dhcp6_lease *lease, uint8_t **id, size_t *len) {
+        assert_return(lease, -EINVAL);
+        assert_return(id, -EINVAL);
+        assert_return(len, -EINVAL);
+
+        *id = lease->serverid;
+        *len = lease->serverid_len;
+
+        return 0;
+}
+
+int dhcp6_lease_set_preference(sd_dhcp6_lease *lease, uint8_t preference) {
+        assert_return(lease, -EINVAL);
+
+        lease->preference = preference;
+
+        return 0;
+}
+
+int dhcp6_lease_get_preference(sd_dhcp6_lease *lease, uint8_t *preference) {
+        assert_return(lease, -EINVAL);
+        assert_return(preference, -EINVAL);
+
+        *preference = lease->preference;
+
+        return 0;
+}
+
+int dhcp6_lease_set_rapid_commit(sd_dhcp6_lease *lease) {
+        assert_return(lease, -EINVAL);
+
+        lease->rapid_commit = true;
+
+        return 0;
+}
+
+int dhcp6_lease_get_rapid_commit(sd_dhcp6_lease *lease, bool *rapid_commit) {
+        assert_return(lease, -EINVAL);
+        assert_return(rapid_commit, -EINVAL);
+
+        *rapid_commit = lease->rapid_commit;
+
+        return 0;
+}
+
+int dhcp6_lease_get_iaid(sd_dhcp6_lease *lease, be32_t *iaid) {
+        assert_return(lease, -EINVAL);
+        assert_return(iaid, -EINVAL);
+
+        *iaid = lease->ia.id;
+
+        return 0;
+}
+
+int sd_dhcp6_lease_get_next_address(sd_dhcp6_lease *lease,
+                                    struct in6_addr *addr,
+                                    uint32_t *lifetime_preferred,
+                                    uint32_t *lifetime_valid) {
+        assert_return(lease, -EINVAL);
+        assert_return(addr, -EINVAL);
+        assert_return(lifetime_preferred, -EINVAL);
+        assert_return(lifetime_valid, -EINVAL);
+
+        if (!lease->addr_iter)
+                return -ENOMSG;
+
+        memcpy(addr, &lease->addr_iter->address, sizeof(struct in6_addr));
+        *lifetime_preferred = be32toh(lease->addr_iter->lifetime_preferred);
+        *lifetime_valid = be32toh(lease->addr_iter->lifetime_valid);
+
+        lease->addr_iter = lease->addr_iter->addresses_next;
+
+        return 0;
+}
+
+int sd_dhcp6_lease_get_first_address(sd_dhcp6_lease *lease,
+                                     struct in6_addr *addr,
+                                     uint32_t *lifetime_preferred,
+                                     uint32_t *lifetime_valid) {
+        assert_return(lease, -EINVAL);
+        assert_return(addr, -EINVAL);
+        assert_return(lifetime_preferred, -EINVAL);
+        assert_return(lifetime_valid, -EINVAL);
+
+        if (!lease->ia.addresses)
+                return -ENOMSG;
+
+        lease->addr_iter = lease->ia.addresses;
+
+        return sd_dhcp6_lease_get_next_address(lease, addr, lifetime_preferred,
+                                               lifetime_valid);
+}
+
+sd_dhcp6_lease *sd_dhcp6_lease_ref(sd_dhcp6_lease *lease) {
+        if (lease)
+                assert_se(REFCNT_INC(lease->n_ref) >= 2);
+
+        return lease;
+}
+
+sd_dhcp6_lease *sd_dhcp6_lease_unref(sd_dhcp6_lease *lease) {
+        if (lease && REFCNT_DEC(lease->n_ref) <= 0) {
+                free(lease->serverid);
+                dhcp6_lease_free_ia(&lease->ia);
+
+                free(lease);
+        }
+
+        return NULL;
+}
+
+int dhcp6_lease_new(sd_dhcp6_lease **ret) {
+        sd_dhcp6_lease *lease;
+
+        lease = new0(sd_dhcp6_lease, 1);
+        if (!lease)
+                return -ENOMEM;
+
+        lease->n_ref = REFCNT_INIT;
+
+        LIST_HEAD_INIT(lease->ia.addresses);
+
+        *ret = lease;
+        return 0;
+}
diff --git a/src/libsystemd-network/sd-icmp6-nd.c b/src/libsystemd-network/sd-icmp6-nd.c
new file mode 100644 (file)
index 0000000..b264e79
--- /dev/null
@@ -0,0 +1,339 @@
+/***
+  This file is part of systemd.
+
+  Copyright (C) 2014 Intel Corporation. All rights reserved.
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <netinet/icmp6.h>
+#include <string.h>
+#include <stdbool.h>
+#include <netinet/in.h>
+
+#include "socket-util.h"
+#include "refcnt.h"
+#include "async.h"
+
+#include "dhcp6-internal.h"
+#include "sd-icmp6-nd.h"
+
+#define ICMP6_ROUTER_SOLICITATION_INTERVAL      4 * USEC_PER_SEC
+#define ICMP6_MAX_ROUTER_SOLICITATIONS          3
+
+enum icmp6_nd_state {
+        ICMP6_NEIGHBOR_DISCOVERY_IDLE           = 0,
+        ICMP6_ROUTER_SOLICITATION_SENT          = 10,
+        ICMP6_ROUTER_ADVERTISMENT_LISTEN        = 11,
+};
+
+struct sd_icmp6_nd {
+        RefCount n_ref;
+
+        enum icmp6_nd_state state;
+        sd_event *event;
+        int event_priority;
+        int index;
+        struct ether_addr mac_addr;
+        int fd;
+        sd_event_source *recv;
+        sd_event_source *timeout;
+        int nd_sent;
+        sd_icmp6_nd_callback_t callback;
+        void *userdata;
+};
+
+#define log_icmp6_nd(p, fmt, ...) log_meta(LOG_DEBUG, __FILE__, __LINE__, __func__, "ICMPv6 CLIENT: " fmt, ##__VA_ARGS__)
+
+static void icmp6_nd_notify(sd_icmp6_nd *nd, int event)
+{
+        if (nd->callback)
+                nd->callback(nd, event, nd->userdata);
+}
+
+int sd_icmp6_nd_set_callback(sd_icmp6_nd *nd, sd_icmp6_nd_callback_t callback,
+                             void *userdata) {
+        assert(nd);
+
+        nd->callback = callback;
+        nd->userdata = userdata;
+
+        return 0;
+}
+
+int sd_icmp6_nd_set_index(sd_icmp6_nd *nd, int interface_index) {
+        assert(nd);
+        assert(interface_index >= -1);
+
+        nd->index = interface_index;
+
+        return 0;
+}
+
+int sd_icmp6_nd_set_mac(sd_icmp6_nd *nd, const struct ether_addr *mac_addr) {
+        assert(nd);
+
+        if (mac_addr)
+                memcpy(&nd->mac_addr, mac_addr, sizeof(nd->mac_addr));
+        else
+                memset(&nd->mac_addr, 0x00, sizeof(nd->mac_addr));
+
+        return 0;
+
+}
+
+int sd_icmp6_nd_attach_event(sd_icmp6_nd *nd, sd_event *event, int priority) {
+        int r;
+
+        assert_return(nd, -EINVAL);
+        assert_return(!nd->event, -EBUSY);
+
+        if (event)
+                nd->event = sd_event_ref(event);
+        else {
+                r = sd_event_default(&nd->event);
+                if (r < 0)
+                        return 0;
+        }
+
+        nd->event_priority = priority;
+
+        return 0;
+}
+
+int sd_icmp6_nd_detach_event(sd_icmp6_nd *nd) {
+        assert_return(nd, -EINVAL);
+
+        nd->event = sd_event_unref(nd->event);
+
+        return 0;
+}
+
+sd_event *sd_icmp6_nd_get_event(sd_icmp6_nd *nd) {
+        assert(nd);
+
+        return nd->event;
+}
+
+sd_icmp6_nd *sd_icmp6_nd_ref(sd_icmp6_nd *nd) {
+        assert (nd);
+
+        assert_se(REFCNT_INC(nd->n_ref) >= 2);
+
+        return nd;
+}
+
+static int icmp6_nd_init(sd_icmp6_nd *nd) {
+        assert(nd);
+
+        nd->recv = sd_event_source_unref(nd->recv);
+        nd->fd = asynchronous_close(nd->fd);
+        nd->timeout = sd_event_source_unref(nd->timeout);
+
+        return 0;
+}
+
+sd_icmp6_nd *sd_icmp6_nd_unref(sd_icmp6_nd *nd) {
+        if (nd && REFCNT_DEC(nd->n_ref) <= 0) {
+
+                icmp6_nd_init(nd);
+                sd_icmp6_nd_detach_event(nd);
+
+                free(nd);
+        }
+
+        return NULL;
+}
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(sd_icmp6_nd*, sd_icmp6_nd_unref);
+#define _cleanup_sd_icmp6_nd_free_ _cleanup_(sd_icmp6_nd_unrefp)
+
+int sd_icmp6_nd_new(sd_icmp6_nd **ret) {
+        _cleanup_sd_icmp6_nd_free_ sd_icmp6_nd *nd = NULL;
+
+        assert(ret);
+
+        nd = new0(sd_icmp6_nd, 1);
+        if (!nd)
+                return -ENOMEM;
+
+        nd->n_ref = REFCNT_INIT;
+
+        nd->index = -1;
+        nd->fd = -1;
+
+        *ret = nd;
+        nd = NULL;
+
+        return 0;
+}
+
+static int icmp6_router_advertisment_recv(sd_event_source *s, int fd,
+                                          uint32_t revents, void *userdata)
+{
+        sd_icmp6_nd *nd = userdata;
+        ssize_t len;
+        struct nd_router_advert ra;
+        int event = ICMP6_EVENT_ROUTER_ADVERTISMENT_NONE;
+
+        assert(s);
+        assert(nd);
+        assert(nd->event);
+
+        /* only interested in Managed/Other flag */
+        len = read(fd, &ra, sizeof(ra));
+        if ((size_t)len < sizeof(ra))
+                return 0;
+
+        if (ra.nd_ra_type != ND_ROUTER_ADVERT)
+                return 0;
+
+        if (ra.nd_ra_code != 0)
+                return 0;
+
+        nd->timeout = sd_event_source_unref(nd->timeout);
+
+        nd->state = ICMP6_ROUTER_ADVERTISMENT_LISTEN;
+
+        if (ra.nd_ra_flags_reserved & ND_RA_FLAG_OTHER )
+                event = ICMP6_EVENT_ROUTER_ADVERTISMENT_OTHER;
+
+        if (ra.nd_ra_flags_reserved & ND_RA_FLAG_MANAGED)
+                event = ICMP6_EVENT_ROUTER_ADVERTISMENT_MANAGED;
+
+        log_icmp6_nd(nd, "Received Router Advertisment flags %s/%s",
+                     (ra.nd_ra_flags_reserved & ND_RA_FLAG_MANAGED)? "MANAGED":
+                     "none",
+                     (ra.nd_ra_flags_reserved & ND_RA_FLAG_OTHER)? "OTHER":
+                     "none");
+
+        icmp6_nd_notify(nd, event);
+
+        return 0;
+}
+
+static int icmp6_router_solicitation_timeout(sd_event_source *s, uint64_t usec,
+                                             void *userdata)
+{
+        sd_icmp6_nd *nd = userdata;
+        uint64_t time_now, next_timeout;
+        struct ether_addr unset = { };
+        struct ether_addr *addr = NULL;
+        int r;
+
+        assert(s);
+        assert(nd);
+        assert(nd->event);
+
+        nd->timeout = sd_event_source_unref(nd->timeout);
+
+        if (nd->nd_sent >= ICMP6_MAX_ROUTER_SOLICITATIONS) {
+                icmp6_nd_notify(nd, ICMP6_EVENT_ROUTER_ADVERTISMENT_TIMEOUT);
+                nd->state = ICMP6_ROUTER_ADVERTISMENT_LISTEN;
+        } else {
+                if (memcmp(&nd->mac_addr, &unset, sizeof(struct ether_addr)))
+                        addr = &nd->mac_addr;
+
+                r = dhcp_network_icmp6_send_router_solicitation(nd->fd, addr);
+                if (r < 0)
+                        log_icmp6_nd(nd, "Error sending Router Solicitation");
+                else {
+                        nd->state = ICMP6_ROUTER_SOLICITATION_SENT;
+                        log_icmp6_nd(nd, "Sent Router Solicitation");
+                }
+
+                nd->nd_sent++;
+
+                r = sd_event_now(nd->event, clock_boottime_or_monotonic(), &time_now);
+                if (r < 0) {
+                        icmp6_nd_notify(nd, r);
+                        return 0;
+                }
+
+                next_timeout = time_now + ICMP6_ROUTER_SOLICITATION_INTERVAL;
+
+                r = sd_event_add_time(nd->event, &nd->timeout, clock_boottime_or_monotonic(),
+                                      next_timeout, 0,
+                                      icmp6_router_solicitation_timeout, nd);
+                if (r < 0) {
+                        icmp6_nd_notify(nd, r);
+                        return 0;
+                }
+
+                r = sd_event_source_set_priority(nd->timeout,
+                                                 nd->event_priority);
+                if (r < 0) {
+                        icmp6_nd_notify(nd, r);
+                        return 0;
+                }
+        }
+
+        return 0;
+}
+
+int sd_icmp6_nd_stop(sd_icmp6_nd *nd) {
+        assert_return(nd, -EINVAL);
+        assert_return(nd->event, -EINVAL);
+
+        log_icmp6_nd(client, "Stop ICMPv6");
+
+        icmp6_nd_init(nd);
+
+        nd->state = ICMP6_NEIGHBOR_DISCOVERY_IDLE;
+
+        return 0;
+}
+
+int sd_icmp6_router_solicitation_start(sd_icmp6_nd *nd) {
+        int r;
+
+        assert(nd);
+        assert(nd->event);
+
+        if (nd->state != ICMP6_NEIGHBOR_DISCOVERY_IDLE)
+                return -EINVAL;
+
+        if (nd->index < 1)
+                return -EINVAL;
+
+        r = dhcp_network_icmp6_bind_router_solicitation(nd->index);
+        if (r < 0)
+                return r;
+
+        nd->fd = r;
+
+        r = sd_event_add_io(nd->event, &nd->recv, nd->fd, EPOLLIN,
+                            icmp6_router_advertisment_recv, nd);
+        if (r < 0)
+                goto error;
+
+        r = sd_event_source_set_priority(nd->recv, nd->event_priority);
+        if (r < 0)
+                goto error;
+
+        r = sd_event_add_time(nd->event, &nd->timeout, clock_boottime_or_monotonic(),
+                              0, 0, icmp6_router_solicitation_timeout, nd);
+        if (r < 0)
+                goto error;
+
+        r = sd_event_source_set_priority(nd->timeout, nd->event_priority);
+
+error:
+        if (r < 0)
+                icmp6_nd_init(nd);
+        else
+                log_icmp6_nd(client, "Start Router Solicitation");
+
+        return r;
+}
diff --git a/src/libsystemd-network/sd-ipv4ll.c b/src/libsystemd-network/sd-ipv4ll.c
new file mode 100644 (file)
index 0000000..b179879
--- /dev/null
@@ -0,0 +1,637 @@
+/***
+  This file is part of systemd.
+
+  Copyright (C) 2014 Axis Communications AB. All rights reserved.
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <arpa/inet.h>
+
+#include "util.h"
+#include "siphash24.h"
+#include "list.h"
+#include "refcnt.h"
+
+#include "ipv4ll-internal.h"
+#include "sd-ipv4ll.h"
+
+/* Constants from the RFC */
+#define PROBE_WAIT 1
+#define PROBE_NUM 3
+#define PROBE_MIN 1
+#define PROBE_MAX 2
+#define ANNOUNCE_WAIT 2
+#define ANNOUNCE_NUM 2
+#define ANNOUNCE_INTERVAL 2
+#define MAX_CONFLICTS 10
+#define RATE_LIMIT_INTERVAL 60
+#define DEFEND_INTERVAL 10
+
+#define IPV4LL_NETWORK 0xA9FE0000L
+#define IPV4LL_NETMASK 0xFFFF0000L
+
+typedef enum IPv4LLTrigger{
+        IPV4LL_TRIGGER_NULL,
+        IPV4LL_TRIGGER_PACKET,
+        IPV4LL_TRIGGER_TIMEOUT,
+        _IPV4LL_TRIGGER_MAX,
+        _IPV4LL_TRIGGER_INVALID = -1
+} IPv4LLTrigger;
+
+typedef enum IPv4LLState {
+        IPV4LL_STATE_INIT,
+        IPV4LL_STATE_WAITING_PROBE,
+        IPV4LL_STATE_PROBING,
+        IPV4LL_STATE_WAITING_ANNOUNCE,
+        IPV4LL_STATE_ANNOUNCING,
+        IPV4LL_STATE_RUNNING,
+        IPV4LL_STATE_STOPPED,
+        _IPV4LL_STATE_MAX,
+        _IPV4LL_STATE_INVALID = -1
+} IPv4LLState;
+
+struct sd_ipv4ll {
+        RefCount n_ref;
+
+        IPv4LLState state;
+        int index;
+        int fd;
+        union sockaddr_union link;
+        int iteration;
+        int conflict;
+        sd_event_source *receive_message;
+        sd_event_source *timer;
+        usec_t next_wakeup;
+        usec_t defend_window;
+        int next_wakeup_valid;
+        be32_t address;
+        struct random_data *random_data;
+        char *random_data_state;
+        /* External */
+        be32_t claimed_address;
+        struct ether_addr mac_addr;
+        sd_event *event;
+        int event_priority;
+        sd_ipv4ll_cb_t cb;
+        void* userdata;
+};
+
+static void ipv4ll_run_state_machine(sd_ipv4ll *ll, IPv4LLTrigger trigger, void *trigger_data);
+
+static void ipv4ll_set_state(sd_ipv4ll *ll, IPv4LLState st, int reset_counter) {
+
+        assert(ll);
+        assert(st < _IPV4LL_STATE_MAX);
+
+        if (st == ll->state && !reset_counter) {
+                ll->iteration++;
+        } else {
+                ll->state = st;
+                ll->iteration = 0;
+        }
+}
+
+static sd_ipv4ll *ipv4ll_client_notify(sd_ipv4ll *ll, int event) {
+        assert(ll);
+
+        if (ll->cb) {
+                ll = sd_ipv4ll_ref(ll);
+                ll->cb(ll, event, ll->userdata);
+                ll = sd_ipv4ll_unref(ll);
+        }
+
+        return ll;
+}
+
+static sd_ipv4ll *ipv4ll_stop(sd_ipv4ll *ll, int event) {
+        assert(ll);
+
+        ll->receive_message = sd_event_source_unref(ll->receive_message);
+        ll->fd = safe_close(ll->fd);
+
+        ll->timer = sd_event_source_unref(ll->timer);
+
+        log_ipv4ll(ll, "STOPPED");
+
+        ll = ipv4ll_client_notify(ll, event);
+
+        if (ll) {
+                ll->claimed_address = 0;
+                ipv4ll_set_state (ll, IPV4LL_STATE_INIT, 1);
+        }
+
+        return ll;
+}
+
+static int ipv4ll_pick_address(sd_ipv4ll *ll, be32_t *address) {
+        be32_t addr;
+        int r;
+        int32_t random;
+
+        assert(ll);
+        assert(address);
+        assert(ll->random_data);
+
+        do {
+                r = random_r(ll->random_data, &random);
+                if (r < 0)
+                        return r;
+                addr = htonl((random & 0x0000FFFF) | IPV4LL_NETWORK);
+        } while (addr == ll->address ||
+                (ntohl(addr) & IPV4LL_NETMASK) != IPV4LL_NETWORK ||
+                (ntohl(addr) & 0x0000FF00) == 0x0000 ||
+                (ntohl(addr) & 0x0000FF00) == 0xFF00);
+
+        *address = addr;
+        return 0;
+}
+
+static int ipv4ll_timer(sd_event_source *s, uint64_t usec, void *userdata) {
+        sd_ipv4ll *ll = (sd_ipv4ll*)userdata;
+
+        assert(ll);
+
+        ll->next_wakeup_valid = 0;
+        ipv4ll_run_state_machine(ll, IPV4LL_TRIGGER_TIMEOUT, NULL);
+
+        return 0;
+}
+
+static void ipv4ll_set_next_wakeup(sd_ipv4ll *ll, int sec, int random_sec) {
+        usec_t next_timeout = 0;
+        usec_t time_now = 0;
+
+        assert(sec >= 0);
+        assert(random_sec >= 0);
+        assert(ll);
+
+        next_timeout = sec * USEC_PER_SEC;
+
+        if (random_sec)
+                next_timeout += random_u32() % (random_sec * USEC_PER_SEC);
+
+        if (sd_event_now(ll->event, clock_boottime_or_monotonic(), &time_now) < 0)
+                time_now = now(clock_boottime_or_monotonic());
+
+        ll->next_wakeup = time_now + next_timeout;
+        ll->next_wakeup_valid = 1;
+}
+
+static bool ipv4ll_arp_conflict (sd_ipv4ll *ll, struct ether_arp *arp) {
+        assert(ll);
+        assert(arp);
+
+        if (memcmp(arp->arp_spa, &ll->address, sizeof(ll->address)) == 0 &&
+            memcmp(arp->arp_sha, &ll->mac_addr, ETH_ALEN) != 0)
+                return true;
+
+        return false;
+}
+
+static bool ipv4ll_arp_probe_conflict (sd_ipv4ll *ll, struct ether_arp *arp) {
+        assert(ll);
+        assert(arp);
+
+        if (ipv4ll_arp_conflict(ll, arp))
+                return true;
+
+        if (memcmp(arp->arp_tpa, &ll->address, sizeof(ll->address)) == 0 &&
+            memcmp(arp->arp_sha, &ll->mac_addr, ETH_ALEN))
+                return true;
+
+        return false;
+}
+
+static void ipv4ll_run_state_machine(sd_ipv4ll *ll, IPv4LLTrigger trigger, void *trigger_data) {
+        struct ether_arp out_packet;
+        int out_packet_ready = 0;
+        int r = 0;
+
+        assert(ll);
+        assert(trigger < _IPV4LL_TRIGGER_MAX);
+
+        if (ll->state == IPV4LL_STATE_INIT) {
+
+                log_ipv4ll(ll, "PROBE");
+                ipv4ll_set_state(ll, IPV4LL_STATE_WAITING_PROBE, 1);
+                ipv4ll_set_next_wakeup(ll, 0, PROBE_WAIT);
+
+        } else if ((ll->state == IPV4LL_STATE_WAITING_PROBE && trigger == IPV4LL_TRIGGER_TIMEOUT) ||
+                (ll->state == IPV4LL_STATE_PROBING && trigger == IPV4LL_TRIGGER_TIMEOUT && ll->iteration < PROBE_NUM-2)) {
+
+                /* Send a probe */
+                arp_packet_probe(&out_packet, ll->address, &ll->mac_addr);
+                out_packet_ready = 1;
+                ipv4ll_set_state(ll, IPV4LL_STATE_PROBING, 0);
+
+                ipv4ll_set_next_wakeup(ll, PROBE_MIN, (PROBE_MAX-PROBE_MIN));
+
+        } else if (ll->state == IPV4LL_STATE_PROBING && trigger == IPV4LL_TRIGGER_TIMEOUT && ll->iteration >= PROBE_NUM-2) {
+
+                /* Send the last probe */
+                arp_packet_probe(&out_packet, ll->address, &ll->mac_addr);
+                out_packet_ready = 1;
+                ipv4ll_set_state(ll, IPV4LL_STATE_WAITING_ANNOUNCE, 1);
+
+                ipv4ll_set_next_wakeup(ll, ANNOUNCE_WAIT, 0);
+
+        } else if ((ll->state == IPV4LL_STATE_WAITING_ANNOUNCE && trigger == IPV4LL_TRIGGER_TIMEOUT) ||
+                (ll->state == IPV4LL_STATE_ANNOUNCING && trigger == IPV4LL_TRIGGER_TIMEOUT && ll->iteration < ANNOUNCE_NUM-1)) {
+
+                /* Send announcement packet */
+                arp_packet_announcement(&out_packet, ll->address, &ll->mac_addr);
+                out_packet_ready = 1;
+                ipv4ll_set_state(ll, IPV4LL_STATE_ANNOUNCING, 0);
+
+                ipv4ll_set_next_wakeup(ll, ANNOUNCE_INTERVAL, 0);
+
+                if (ll->iteration == 0) {
+                        log_ipv4ll(ll, "ANNOUNCE");
+                        ll->claimed_address = ll->address;
+                        ll = ipv4ll_client_notify(ll, IPV4LL_EVENT_BIND);
+                        if (!ll || ll->state == IPV4LL_STATE_STOPPED)
+                                goto out;
+
+                        ll->conflict = 0;
+                }
+
+        } else if ((ll->state == IPV4LL_STATE_ANNOUNCING && trigger == IPV4LL_TRIGGER_TIMEOUT &&
+                    ll->iteration >= ANNOUNCE_NUM-1)) {
+
+                ipv4ll_set_state(ll, IPV4LL_STATE_RUNNING, 0);
+                ll->next_wakeup_valid = 0;
+
+        } else if (trigger == IPV4LL_TRIGGER_PACKET) {
+
+                int conflicted = 0;
+                usec_t time_now;
+                struct ether_arp* in_packet = (struct ether_arp*)trigger_data;
+
+                assert(in_packet);
+
+                if (IN_SET(ll->state, IPV4LL_STATE_ANNOUNCING, IPV4LL_STATE_RUNNING)) {
+
+                        if (ipv4ll_arp_conflict(ll, in_packet)) {
+
+                                r = sd_event_now(ll->event, clock_boottime_or_monotonic(), &time_now);
+                                if (r < 0)
+                                        goto out;
+
+                                /* Defend address */
+                                if (time_now > ll->defend_window) {
+                                        ll->defend_window = time_now + DEFEND_INTERVAL * USEC_PER_SEC;
+                                        arp_packet_announcement(&out_packet, ll->address, &ll->mac_addr);
+                                        out_packet_ready = 1;
+                                } else
+                                        conflicted = 1;
+                        }
+
+                } else if (IN_SET(ll->state, IPV4LL_STATE_WAITING_PROBE,
+                                             IPV4LL_STATE_PROBING,
+                                             IPV4LL_STATE_WAITING_ANNOUNCE)) {
+
+                        conflicted = ipv4ll_arp_probe_conflict(ll, in_packet);
+                }
+
+                if (conflicted) {
+                        log_ipv4ll(ll, "CONFLICT");
+                        ll = ipv4ll_client_notify(ll, IPV4LL_EVENT_CONFLICT);
+                        if (!ll || ll->state == IPV4LL_STATE_STOPPED)
+                                goto out;
+
+                        ll->claimed_address = 0;
+
+                        /* Pick a new address */
+                        r = ipv4ll_pick_address(ll, &ll->address);
+                        if (r < 0)
+                                goto out;
+                        ll->conflict++;
+                        ll->defend_window = 0;
+                        ipv4ll_set_state(ll, IPV4LL_STATE_WAITING_PROBE, 1);
+
+                        if (ll->conflict >= MAX_CONFLICTS) {
+                                log_ipv4ll(ll, "MAX_CONFLICTS");
+                                ipv4ll_set_next_wakeup(ll, RATE_LIMIT_INTERVAL, PROBE_WAIT);
+                        } else
+                                ipv4ll_set_next_wakeup(ll, 0, PROBE_WAIT);
+
+                }
+        }
+
+        if (out_packet_ready) {
+                r = arp_network_send_raw_socket(ll->fd, &ll->link, &out_packet);
+                if (r < 0) {
+                        log_ipv4ll(ll, "failed to send arp packet out");
+                        goto out;
+                }
+        }
+
+        if (ll->next_wakeup_valid) {
+                ll->timer = sd_event_source_unref(ll->timer);
+                r = sd_event_add_time(ll->event, &ll->timer, clock_boottime_or_monotonic(),
+                                      ll->next_wakeup, 0, ipv4ll_timer, ll);
+                if (r < 0)
+                        goto out;
+
+                r = sd_event_source_set_priority(ll->timer, ll->event_priority);
+                if (r < 0)
+                        goto out;
+        }
+
+out:
+        if (r < 0 && ll)
+                ipv4ll_stop(ll, r);
+}
+
+static int ipv4ll_receive_message(sd_event_source *s, int fd,
+                                  uint32_t revents, void *userdata) {
+        int r;
+        struct ether_arp arp;
+        sd_ipv4ll *ll = (sd_ipv4ll*)userdata;
+
+        assert(ll);
+
+        r = read(fd, &arp, sizeof(struct ether_arp));
+        if (r < (int) sizeof(struct ether_arp))
+                return 0;
+
+        r = arp_packet_verify_headers(&arp);
+        if (r < 0)
+                return 0;
+
+        ipv4ll_run_state_machine(ll, IPV4LL_TRIGGER_PACKET, &arp);
+
+        return 0;
+}
+
+int sd_ipv4ll_set_index(sd_ipv4ll *ll, int interface_index) {
+        assert_return(ll, -EINVAL);
+        assert_return(interface_index > 0, -EINVAL);
+        assert_return(IN_SET(ll->state, IPV4LL_STATE_INIT,
+                             IPV4LL_STATE_STOPPED), -EBUSY);
+
+        ll->index = interface_index;
+
+        return 0;
+}
+
+int sd_ipv4ll_set_mac(sd_ipv4ll *ll, const struct ether_addr *addr) {
+        bool need_restart = false;
+
+        assert_return(ll, -EINVAL);
+        assert_return(addr, -EINVAL);
+
+        if (memcmp(&ll->mac_addr, addr, ETH_ALEN) == 0)
+                return 0;
+
+        if (!IN_SET(ll->state, IPV4LL_STATE_INIT, IPV4LL_STATE_STOPPED)) {
+                log_ipv4ll(ll, "Changing MAC address on running IPv4LL "
+                           "client, restarting");
+                ll = ipv4ll_stop(ll, IPV4LL_EVENT_STOP);
+                need_restart = true;
+        }
+
+        if (!ll)
+                return 0;
+
+        memcpy(&ll->mac_addr, addr, ETH_ALEN);
+
+        if (need_restart)
+                sd_ipv4ll_start(ll);
+
+        return 0;
+}
+
+int sd_ipv4ll_detach_event(sd_ipv4ll *ll) {
+        assert_return(ll, -EINVAL);
+
+        ll->event = sd_event_unref(ll->event);
+
+        return 0;
+}
+
+int sd_ipv4ll_attach_event(sd_ipv4ll *ll, sd_event *event, int priority) {
+        int r;
+
+        assert_return(ll, -EINVAL);
+        assert_return(!ll->event, -EBUSY);
+
+        if (event)
+                ll->event = sd_event_ref(event);
+        else {
+                r = sd_event_default(&ll->event);
+                if (r < 0) {
+                        ipv4ll_stop(ll, IPV4LL_EVENT_STOP);
+                        return r;
+                }
+        }
+
+        ll->event_priority = priority;
+
+        return 0;
+}
+
+int sd_ipv4ll_set_callback(sd_ipv4ll *ll, sd_ipv4ll_cb_t cb, void *userdata) {
+        assert_return(ll, -EINVAL);
+
+        ll->cb = cb;
+        ll->userdata = userdata;
+
+        return 0;
+}
+
+int sd_ipv4ll_get_address(sd_ipv4ll *ll, struct in_addr *address){
+        assert_return(ll, -EINVAL);
+        assert_return(address, -EINVAL);
+
+        if (ll->claimed_address == 0) {
+                return -ENOENT;
+        }
+
+        address->s_addr = ll->claimed_address;
+        return 0;
+}
+
+int sd_ipv4ll_set_address_seed (sd_ipv4ll *ll, uint8_t seed[8]) {
+        unsigned int entropy;
+        int r;
+
+        assert_return(ll, -EINVAL);
+        assert_return(seed, -EINVAL);
+
+        entropy = *seed;
+
+        free(ll->random_data);
+        free(ll->random_data_state);
+
+        ll->random_data = new0(struct random_data, 1);
+        ll->random_data_state = new0(char, 128);
+
+        if (!ll->random_data || !ll->random_data_state) {
+                r = -ENOMEM;
+                goto error;
+        }
+
+        r = initstate_r((unsigned int)entropy, ll->random_data_state, 128, ll->random_data);
+        if (r < 0)
+                goto error;
+
+error:
+        if (r < 0){
+                free(ll->random_data);
+                free(ll->random_data_state);
+                ll->random_data = NULL;
+                ll->random_data_state = NULL;
+        }
+        return r;
+}
+
+bool sd_ipv4ll_is_running(sd_ipv4ll *ll) {
+        assert_return(ll, -EINVAL);
+
+        return !IN_SET(ll->state, IPV4LL_STATE_INIT, IPV4LL_STATE_STOPPED);
+}
+
+#define HASH_KEY SD_ID128_MAKE(df,04,22,98,3f,ad,14,52,f9,87,2e,d1,9c,70,e2,f2)
+
+int sd_ipv4ll_start (sd_ipv4ll *ll) {
+        int r;
+
+        assert_return(ll, -EINVAL);
+        assert_return(ll->event, -EINVAL);
+        assert_return(ll->index > 0, -EINVAL);
+        assert_return(IN_SET(ll->state, IPV4LL_STATE_INIT,
+                             IPV4LL_STATE_STOPPED), -EBUSY);
+
+        ll->state = IPV4LL_STATE_INIT;
+
+        r = arp_network_bind_raw_socket(ll->index, &ll->link);
+
+        if (r < 0)
+                goto out;
+
+        ll->fd = r;
+        ll->conflict = 0;
+        ll->defend_window = 0;
+        ll->claimed_address = 0;
+
+        if (!ll->random_data) {
+                uint8_t seed[8];
+
+                /* Fallback to mac */
+                siphash24(seed, &ll->mac_addr.ether_addr_octet,
+                          ETH_ALEN, HASH_KEY.bytes);
+
+                r = sd_ipv4ll_set_address_seed(ll, seed);
+                if (r < 0)
+                        goto out;
+        }
+
+        if (ll->address == 0) {
+                r = ipv4ll_pick_address(ll, &ll->address);
+                if (r < 0)
+                        goto out;
+        }
+
+        ipv4ll_set_state (ll, IPV4LL_STATE_INIT, 1);
+
+        r = sd_event_add_io(ll->event, &ll->receive_message, ll->fd,
+                            EPOLLIN, ipv4ll_receive_message, ll);
+        if (r < 0)
+                goto out;
+
+        r = sd_event_source_set_priority(ll->receive_message, ll->event_priority);
+        if (r < 0)
+                goto out;
+
+        r = sd_event_add_time(ll->event,
+                              &ll->timer,
+                              clock_boottime_or_monotonic(),
+                              now(clock_boottime_or_monotonic()), 0,
+                              ipv4ll_timer, ll);
+
+        if (r < 0)
+                goto out;
+
+        r = sd_event_source_set_priority(ll->timer, ll->event_priority);
+
+out:
+        if (r < 0)
+                ipv4ll_stop(ll, IPV4LL_EVENT_STOP);
+
+        return 0;
+}
+
+int sd_ipv4ll_stop(sd_ipv4ll *ll) {
+        ipv4ll_stop(ll, IPV4LL_EVENT_STOP);
+        if (ll)
+                ipv4ll_set_state(ll, IPV4LL_STATE_STOPPED, 1);
+
+        return 0;
+}
+
+sd_ipv4ll *sd_ipv4ll_ref(sd_ipv4ll *ll) {
+        if (ll)
+                assert_se(REFCNT_INC(ll->n_ref) >= 2);
+
+        return ll;
+}
+
+sd_ipv4ll *sd_ipv4ll_unref(sd_ipv4ll *ll) {
+        if (ll && REFCNT_DEC(ll->n_ref) <= 0) {
+                ll->receive_message =
+                        sd_event_source_unref(ll->receive_message);
+                ll->fd = safe_close(ll->fd);
+
+                ll->timer = sd_event_source_unref(ll->timer);
+
+                sd_ipv4ll_detach_event(ll);
+
+                free(ll->random_data);
+                free(ll->random_data_state);
+                free(ll);
+
+                return NULL;
+        }
+
+        return ll;
+}
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(sd_ipv4ll*, sd_ipv4ll_unref);
+#define _cleanup_ipv4ll_free_ _cleanup_(sd_ipv4ll_unrefp)
+
+int sd_ipv4ll_new(sd_ipv4ll **ret) {
+        _cleanup_ipv4ll_free_ sd_ipv4ll *ll = NULL;
+
+        assert_return(ret, -EINVAL);
+
+        ll = new0(sd_ipv4ll, 1);
+        if (!ll)
+                return -ENOMEM;
+
+        ll->n_ref = REFCNT_INIT;
+        ll->state = IPV4LL_STATE_INIT;
+        ll->index = -1;
+        ll->fd = -1;
+
+        *ret = ll;
+        ll = NULL;
+
+        return 0;
+}
similarity index 86%
rename from src/libsystemd-dhcp/test-dhcp-client.c
rename to src/libsystemd-network/test-dhcp-client.c
index 8061e5f..c48aa04 100644 (file)
@@ -29,6 +29,8 @@
 
 #include "util.h"
 #include "socket-util.h"
+#include "sd-event.h"
+#include "event-util.h"
 
 #include "dhcp-protocol.h"
 #include "dhcp-internal.h"
@@ -44,6 +46,15 @@ static bool verbose = false;
 static int test_fd[2];
 static test_callback_recv_t callback_recv;
 static be32_t xid;
+static sd_event_source *test_hangcheck;
+
+static int test_dhcp_hangcheck(sd_event_source *s, uint64_t usec,
+                               void *userdata)
+{
+        assert_not_reached("Test case should have completed in 2 seconds");
+
+        return 0;
+}
 
 static void test_request_basic(sd_event *e)
 {
@@ -68,7 +79,9 @@ static void test_request_basic(sd_event *e)
 
         assert_se(sd_dhcp_client_set_index(client, 15) == 0);
         assert_se(sd_dhcp_client_set_index(client, -42) == -EINVAL);
-        assert_se(sd_dhcp_client_set_index(client, -1) == 0);
+        assert_se(sd_dhcp_client_set_index(client, -1) == -EINVAL);
+        assert_se(sd_dhcp_client_set_index(client, 0) == -EINVAL);
+        assert_se(sd_dhcp_client_set_index(client, 1) == 0);
 
         assert_se(sd_dhcp_client_set_request_option(client,
                                         DHCP_OPTION_SUBNET_MASK) == -EEXIST);
@@ -100,30 +113,8 @@ static void test_request_basic(sd_event *e)
         assert_se(sd_dhcp_client_set_request_option(client, 33) == -EEXIST);
         assert_se(sd_dhcp_client_set_request_option(client, 44) == 0);
         assert_se(sd_dhcp_client_set_request_option(client, 33) == -EEXIST);
-}
-
-static uint16_t client_checksum(void *buf, int len)
-{
-        uint32_t sum;
-        uint16_t *check;
-        int i;
-        uint8_t *odd;
-
-        sum = 0;
-        check = buf;
-
-        for (i = 0; i < len / 2 ; i++)
-                sum += check[i];
-
-        if (len & 0x01) {
-                odd = buf;
-                sum += odd[len - 1];
-        }
-
-        while (sum >> 16)
-                sum = (sum & 0xffff) + (sum >> 16);
 
-        return ~sum;
+        sd_dhcp_client_unref(client);
 }
 
 static void test_checksum(void)
@@ -137,12 +128,23 @@ static void test_checksum(void)
         if (verbose)
                 printf("* %s\n", __FUNCTION__);
 
-        assert_se(client_checksum(&buf, 20) == be16toh(0x78ae));
+        assert_se(dhcp_packet_checksum((uint8_t*)&buf, 20) == be16toh(0x78ae));
 }
 
 static int check_options(uint8_t code, uint8_t len, const uint8_t *option,
                 void *user_data)
 {
+        switch(code) {
+        case DHCP_OPTION_CLIENT_IDENTIFIER:
+                assert_se(len == 7);
+                assert_se(option[0] == 0x01);
+                assert_se(memcmp(&option[1], &mac_addr, ETH_ALEN) == 0);
+                break;
+
+        default:
+                break;
+        }
+
         return 0;
 }
 
@@ -156,7 +158,7 @@ int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link,
         assert_se(s >= 0);
         assert_se(packet);
 
-        size = sizeof(DHCPPacket) + 4;
+        size = sizeof(DHCPPacket);
         assert_se(len > size);
 
         discover = memdup(packet, len);
@@ -173,13 +175,13 @@ int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link,
         discover->ip.ttl = 0;
         discover->ip.check = discover->udp.len;
 
-        udp_check = ~client_checksum(&discover->ip.ttl, len - 8);
+        udp_check = ~dhcp_packet_checksum((uint8_t*)&discover->ip.ttl, len - 8);
         assert_se(udp_check == 0xffff);
 
         discover->ip.ttl = IPDEFTTL;
         discover->ip.check = ip_check;
 
-        ip_check = ~client_checksum(&discover->ip, sizeof(discover->ip));
+        ip_check = ~dhcp_packet_checksum((uint8_t*)&discover->ip, sizeof(discover->ip));
         assert_se(ip_check == 0xffff);
 
         assert_se(discover->dhcp.xid);
@@ -194,7 +196,7 @@ int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link,
         return 575;
 }
 
-int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link)
+int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link, uint32_t id, struct ether_addr mac)
 {
         if (socketpair(AF_UNIX, SOCK_STREAM, 0, test_fd) < 0)
                 return -errno;
@@ -202,7 +204,7 @@ int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link)
         return test_fd[0];
 }
 
-int dhcp_network_bind_udp_socket(int index, be32_t address, uint16_t port)
+int dhcp_network_bind_udp_socket(be32_t address, uint16_t port)
 {
         return 0;
 }
@@ -255,10 +257,9 @@ static void test_discover_message(sd_event *e)
         sd_event_run(e, (uint64_t) -1);
 
         sd_dhcp_client_stop(client);
-        sd_dhcp_client_free(client);
+        sd_dhcp_client_unref(client);
 
-        close(test_fd[0]);
-        close(test_fd[1]);
+        test_fd[1] = safe_close(test_fd[1]);
 
         callback_recv = NULL;
 }
@@ -343,7 +344,7 @@ static uint8_t test_addr_acq_ack[] = {
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
         0x63, 0x82, 0x53, 0x63, 0x35, 0x01, 0x05, 0x36,
         0x04, 0xc0, 0xa8, 0x02, 0x01, 0x33, 0x04, 0x00,
-        0x00, 0x02, 0x58, 0x01, 0x04,   0xff, 0xff, 0xff,
+        0x00, 0x02, 0x58, 0x01, 0x04, 0xff, 0xff, 0xff,
         0x00, 0x2a, 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x0f,
         0x09, 0x6c, 0x61, 0x62, 0x2e, 0x69, 0x6e, 0x74,
         0x72, 0x61, 0x03, 0x04, 0xc0, 0xa8, 0x02, 0x01,
@@ -352,8 +353,7 @@ static uint8_t test_addr_acq_ack[] = {
 };
 
 static void test_addr_acq_acquired(sd_dhcp_client *client, int event,
-                                   void *userdata)
-{
+                                   void *userdata) {
         sd_event *e = userdata;
         sd_dhcp_lease *lease;
         struct in_addr addr;
@@ -379,18 +379,21 @@ static void test_addr_acq_acquired(sd_dhcp_client *client, int event,
         if (verbose)
                 printf("  DHCP address acquired\n");
 
+        sd_dhcp_lease_unref(lease);
         sd_event_exit(e, 0);
 }
 
-static int test_addr_acq_recv_request(size_t size, DHCPMessage *request)
-{
+static int test_addr_acq_recv_request(size_t size, DHCPMessage *request) {
         uint16_t udp_check = 0;
+        uint8_t *msg_bytes = (uint8_t *)request;
         int res;
 
         res = dhcp_option_parse(request, size, check_options, NULL);
         assert_se(res == DHCP_REQUEST);
         assert_se(xid == request->xid);
 
+        assert_se(msg_bytes[size - 1] == DHCP_OPTION_END);
+
         if (verbose)
                 printf("  recv DHCP Request  0x%08x\n", be32toh(xid));
 
@@ -411,14 +414,16 @@ static int test_addr_acq_recv_request(size_t size, DHCPMessage *request)
         return 0;
 };
 
-static int test_addr_acq_recv_discover(size_t size, DHCPMessage *discover)
-{
+static int test_addr_acq_recv_discover(size_t size, DHCPMessage *discover) {
         uint16_t udp_check = 0;
+        uint8_t *msg_bytes = (uint8_t *)discover;
         int res;
 
         res = dhcp_option_parse(discover, size, check_options, NULL);
         assert_se(res == DHCP_DISCOVER);
 
+        assert_se(msg_bytes[size - 1] == DHCP_OPTION_END);
+
         xid = discover->xid;
 
         if (verbose)
@@ -436,13 +441,13 @@ static int test_addr_acq_recv_discover(size_t size, DHCPMessage *discover)
         assert_se(res == sizeof(test_addr_acq_offer));
 
         if (verbose)
-                printf("  send DHCP Offer\n");
+                printf("  sent DHCP Offer\n");
 
         return 0;
 }
 
-static void test_addr_acq(sd_event *e)
-{
+static void test_addr_acq(sd_event *e) {
+        usec_t time_now = now(clock_boottime_or_monotonic());
         sd_dhcp_client *client;
         int res, r;
 
@@ -464,25 +469,34 @@ static void test_addr_acq(sd_event *e)
 
         callback_recv = test_addr_acq_recv_discover;
 
+        assert_se(sd_event_add_time(e, &test_hangcheck,
+                                    clock_boottime_or_monotonic(),
+                                    time_now + 2 * USEC_PER_SEC, 0,
+                                    test_dhcp_hangcheck, NULL) >= 0);
+
         res = sd_dhcp_client_start(client);
         assert_se(res == 0 || res == -EINPROGRESS);
 
         sd_event_loop(e);
 
+        test_hangcheck = sd_event_source_unref(test_hangcheck);
+
         sd_dhcp_client_set_callback(client, NULL, NULL);
         sd_dhcp_client_stop(client);
-        sd_dhcp_client_free(client);
+        sd_dhcp_client_unref(client);
 
-        close(test_fd[0]);
-        close(test_fd[1]);
+        test_fd[1] = safe_close(test_fd[1]);
 
         callback_recv = NULL;
         xid = 0;
 }
 
-int main(int argc, char *argv[])
-{
-        sd_event *e;
+int main(int argc, char *argv[]) {
+        _cleanup_event_unref_ sd_event *e;
+
+        log_set_max_level(LOG_DEBUG);
+        log_parse_environment();
+        log_open();
 
         assert_se(sd_event_new(&e) >= 0);
 
similarity index 73%
rename from src/libsystemd-dhcp/test-dhcp-option.c
rename to src/libsystemd-network/test-dhcp-option.c
index 8659fd5..92c58e0 100644 (file)
@@ -78,29 +78,33 @@ static void test_invalid_buffer_length(void)
         DHCPMessage message;
 
         assert_se(dhcp_option_parse(&message, 0, NULL, NULL) == -EINVAL);
-        assert_se(dhcp_option_parse(&message, sizeof(DHCPMessage), NULL, NULL)
+        assert_se(dhcp_option_parse(&message, sizeof(DHCPMessage) - 1, NULL, NULL)
                == -EINVAL);
 }
 
-static void test_cookie(void)
+static void test_message_init(void)
 {
-        _cleanup_free_ DHCPMessage *message;
-        size_t len = sizeof(DHCPMessage) + 4;
-        uint8_t *opt;
+        _cleanup_free_ DHCPMessage *message = NULL;
+        size_t optlen = 4, optoffset;
+        size_t len = sizeof(DHCPMessage) + optlen;
+        uint8_t *magic;
 
         message = malloc0(len);
 
-        opt = (uint8_t *)(message + 1);
-        opt[0] = 0xff;
+        assert_se(dhcp_message_init(message, BOOTREQUEST, 0x12345678,
+                  DHCP_DISCOVER, optlen, &optoffset) >= 0);
 
-        assert_se(dhcp_option_parse(message, len, NULL, NULL) == -EINVAL);
+        assert_se(message->xid == htobe32(0x12345678));
+        assert_se(message->op == BOOTREQUEST);
 
-        opt[0] = 99;
-        opt[1] = 130;
-        opt[2] = 83;
-        opt[3] = 99;
+        magic = (uint8_t*)&message->magic;
 
-        assert_se(dhcp_option_parse(message, len, NULL, NULL) == -ENOMSG);
+        assert_se(magic[0] == 99);
+        assert_se(magic[1] = 130);
+        assert_se(magic[2] = 83);
+        assert_se(magic[3] = 99);
+
+        assert_se(dhcp_option_parse(message, len, NULL, NULL) >= 0);
 }
 
 static DHCPMessage *create_message(uint8_t *options, uint16_t optlen,
@@ -108,19 +112,12 @@ static DHCPMessage *create_message(uint8_t *options, uint16_t optlen,
                 uint8_t *sname, uint8_t snamelen)
 {
         DHCPMessage *message;
-        size_t len = sizeof(DHCPMessage) + 4 + optlen;
-        uint8_t *opt;
+        size_t len = sizeof(DHCPMessage) + optlen;
 
         message = malloc0(len);
-        opt = (uint8_t *)(message + 1);
-
-        opt[0] = 99;
-        opt[1] = 130;
-        opt[2] = 83;
-        opt[3] = 99;
 
         if (options && optlen)
-                memcpy(&opt[4], options, optlen);
+                memcpy(&message->options, options, optlen);
 
         if (file && filelen <= 128)
                 memcpy(&message->file, file, filelen);
@@ -248,7 +245,7 @@ static void test_options(struct option_desc *desc)
         int filelen = 0;
         int snamelen = 0;
         int buflen = 0;
-        _cleanup_free_ DHCPMessage *message;
+        _cleanup_free_ DHCPMessage *message = NULL;
         int res;
 
         if (desc) {
@@ -267,9 +264,9 @@ static void test_options(struct option_desc *desc)
                 desc->pos = 0;
         }
         message = create_message(options, optlen, file, filelen,
-                        sname, snamelen);
+                                 sname, snamelen);
 
-        buflen = sizeof(DHCPMessage) + 4 + optlen;
+        buflen = sizeof(DHCPMessage) + optlen;
 
         if (!desc) {
                 assert_se((res = dhcp_option_parse(message, buflen,
@@ -290,10 +287,6 @@ static void test_options(struct option_desc *desc)
                 printf("DHCP type %s\n", dhcp_type(res));
 }
 
-static uint8_t result[64] = {
-        'A', 'B', 'C', 'D',
-};
-
 static uint8_t options[64] = {
         'A', 'B', 'C', 'D',
         160, 2, 0x11, 0x12,
@@ -307,53 +300,71 @@ static uint8_t options[64] = {
 
 static void test_option_set(void)
 {
-        size_t len, oldlen;
-        int pos, i;
-        uint8_t *opt;
-
-        assert_se(dhcp_option_append(NULL, NULL, 0, 0, NULL) == -EINVAL);
-
-        len = 0;
-        opt = &result[0];
-        assert_se(dhcp_option_append(&opt, NULL, 0, 0, NULL) == -EINVAL);
-        assert_se(opt == &result[0] && len == 0);
-
-        assert_se(dhcp_option_append(&opt, &len, DHCP_OPTION_PAD,
-                                  0, NULL) == -ENOBUFS);
-        assert_se(opt == &result[0] && len == 0);
-
-        opt = &result[4];
-        len = 1;
-        assert_se(dhcp_option_append(&opt, &len, DHCP_OPTION_PAD,
-                                    0, NULL) >= 0);
-        assert_se(opt == &result[5] && len == 0);
-
-        pos = 4;
-        len = 60;
-        while (pos < 64 && options[pos] != DHCP_OPTION_END) {
-                opt = &result[pos];
-                oldlen = len;
-
-                assert_se(dhcp_option_append(&opt, &len, options[pos],
-                                          options[pos + 1],
-                                          &options[pos + 2]) >= 0);
-
-                if (options[pos] == DHCP_OPTION_PAD) {
-                        assert_se(opt == &result[pos + 1]);
-                        assert_se(len == oldlen - 1);
+        _cleanup_free_ DHCPMessage *result = NULL;
+        size_t offset = 0, len, pos;
+        unsigned i;
+
+        result = malloc0(sizeof(DHCPMessage) + 11);
+        assert_se(result);
+
+        result->options[0] = 'A';
+        result->options[1] = 'B';
+        result->options[2] = 'C';
+        result->options[3] = 'D';
+
+        assert_se(dhcp_option_append(result, 0, &offset, 0, DHCP_OPTION_PAD,
+                                     0, NULL) == -ENOBUFS);
+        assert_se(offset == 0);
+
+        offset = 4;
+        assert_se(dhcp_option_append(result, 5, &offset, 0, DHCP_OPTION_PAD,
+                                     0, NULL) == -ENOBUFS);
+        assert_se(offset == 4);
+        assert_se(dhcp_option_append(result, 6, &offset, 0, DHCP_OPTION_PAD,
+                                     0, NULL) >= 0);
+        assert_se(offset == 5);
+
+        offset = pos = 4;
+        len = 11;
+        while (pos < len && options[pos] != DHCP_OPTION_END) {
+                assert_se(dhcp_option_append(result, len, &offset, DHCP_OVERLOAD_SNAME,
+                                             options[pos],
+                                             options[pos + 1],
+                                             &options[pos + 2]) >= 0);
+
+                if (options[pos] == DHCP_OPTION_PAD)
                         pos++;
-                } else {
-                        assert_se(opt == &result[pos + 2 + options[pos + 1]]);
-                        assert_se(len == oldlen - 2 - options[pos + 1]);
+                else
                         pos += 2 + options[pos + 1];
-                }
+
+                if (pos < len)
+                        assert_se(offset == pos);
         }
 
-        for (i = 0; i < pos; i++) {
+        for (i = 0; i < 9; i++) {
                 if (verbose)
-                        printf("%2d: 0x%02x(0x%02x)\n", i, result[i],
+                        printf("%2d: 0x%02x(0x%02x) (options)\n", i, result->options[i],
                                options[i]);
-                assert_se(result[i] == options[i]);
+                assert_se(result->options[i] == options[i]);
+        }
+
+        if (verbose)
+                printf("%2d: 0x%02x(0x%02x) (options)\n", 9, result->options[9],
+                       DHCP_OPTION_END);
+
+        assert_se(result->options[9] == DHCP_OPTION_END);
+
+        if (verbose)
+                printf("%2d: 0x%02x(0x%02x) (options)\n", 10, result->options[10],
+                       DHCP_OPTION_PAD);
+
+        assert_se(result->options[10] == DHCP_OPTION_PAD);
+
+        for (i = 0; i < pos - 8; i++) {
+                if (verbose)
+                        printf("%2d: 0x%02x(0x%02x) (sname)\n", i, result->sname[i],
+                               options[i + 9]);
+                assert_se(result->sname[i] == options[i + 9]);
         }
 
         if (verbose)
@@ -365,7 +376,7 @@ int main(int argc, char *argv[])
         unsigned int i;
 
         test_invalid_buffer_length();
-        test_cookie();
+        test_message_init();
 
         test_options(NULL);
 
diff --git a/src/libsystemd-network/test-dhcp-server.c b/src/libsystemd-network/test-dhcp-server.c
new file mode 100644 (file)
index 0000000..3e68f31
--- /dev/null
@@ -0,0 +1,252 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright (C) 2013 Intel Corporation. All rights reserved.
+  Copyright (C) 2014 Tom Gundersen
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <netinet/if_ether.h>
+#include <assert.h>
+#include <errno.h>
+
+#include "sd-event.h"
+#include "event-util.h"
+
+#include "sd-dhcp-server.h"
+#include "dhcp-server-internal.h"
+
+static int test_basic(sd_event *event) {
+        _cleanup_dhcp_server_unref_ sd_dhcp_server *server = NULL;
+        struct in_addr address_lo = {
+                .s_addr = htonl(INADDR_LOOPBACK),
+        };
+        struct in_addr address_any = {
+                .s_addr = htonl(INADDR_ANY),
+        };
+        int r;
+
+        /* attach to loopback interface */
+        assert_se(sd_dhcp_server_new(&server, 1) >= 0);
+        assert_se(server);
+
+        assert_se(sd_dhcp_server_attach_event(server, event, 0) >= 0);
+        assert_se(sd_dhcp_server_attach_event(server, event, 0) == -EBUSY);
+        assert_se(sd_dhcp_server_get_event(server) == event);
+        assert_se(sd_dhcp_server_detach_event(server) >= 0);
+        assert_se(!sd_dhcp_server_get_event(server));
+        assert_se(sd_dhcp_server_attach_event(server, NULL, 0) >= 0);
+        assert_se(sd_dhcp_server_attach_event(server, NULL, 0) == -EBUSY);
+
+        assert_se(sd_dhcp_server_ref(server) == server);
+        assert_se(!sd_dhcp_server_unref(server));
+
+        assert_se(sd_dhcp_server_start(server) == -EUNATCH);
+        assert_se(sd_dhcp_server_set_address(server, &address_any, 28) == -EINVAL);
+        assert_se(sd_dhcp_server_set_address(server, &address_lo, 38) == -ERANGE);
+        assert_se(sd_dhcp_server_set_address(server, &address_lo, 8) >= 0);
+        assert_se(sd_dhcp_server_set_address(server, &address_lo, 8) == -EBUSY);
+
+        assert_se(sd_dhcp_server_set_lease_pool(server, &address_any, 1) == -EINVAL);
+        assert_se(sd_dhcp_server_set_lease_pool(server, &address_lo, 0) == -EINVAL);
+        assert_se(sd_dhcp_server_set_lease_pool(server, &address_lo, 1) >= 0);
+        assert_se(sd_dhcp_server_set_lease_pool(server, &address_lo, 1) == -EBUSY);
+
+        r = sd_dhcp_server_start(server);
+
+        if (r == -EPERM)
+                return EXIT_TEST_SKIP;
+        assert_se(r >= 0);
+
+        assert_se(sd_dhcp_server_start(server) == -EBUSY);
+        assert_se(sd_dhcp_server_stop(server) >= 0);
+        assert_se(sd_dhcp_server_stop(server) >= 0);
+        assert_se(sd_dhcp_server_start(server) >= 0);
+
+        return 0;
+}
+
+static void test_message_handler(void) {
+        _cleanup_dhcp_server_unref_ sd_dhcp_server *server = NULL;
+        struct {
+                DHCPMessage message;
+                struct {
+                        uint8_t code;
+                        uint8_t length;
+                        uint8_t type;
+                } _packed_ option_type;
+                struct {
+                        uint8_t code;
+                        uint8_t length;
+                        be32_t address;
+                } _packed_ option_requested_ip;
+                struct {
+                        uint8_t code;
+                        uint8_t length;
+                        be32_t address;
+                } _packed_ option_server_id;
+                struct {
+                        uint8_t code;
+                        uint8_t length;
+                        uint8_t id[7];
+                } _packed_ option_client_id;
+                uint8_t end;
+        } _packed_ test = {
+                .message.op = BOOTREQUEST,
+                .message.htype = ARPHRD_ETHER,
+                .message.hlen = ETHER_ADDR_LEN,
+                .message.xid = htobe32(0x12345678),
+                .message.chaddr = { 'A', 'B', 'C', 'D', 'E', 'F' },
+                .option_type.code = DHCP_OPTION_MESSAGE_TYPE,
+                .option_type.length = 1,
+                .option_type.type = DHCP_DISCOVER,
+                .end = DHCP_OPTION_END,
+        };
+        struct in_addr address_lo = {
+                .s_addr = htonl(INADDR_LOOPBACK),
+        };
+
+        assert_se(sd_dhcp_server_new(&server, 1) >= 0);
+        assert_se(sd_dhcp_server_set_address(server, &address_lo, 8) >= 0);
+        assert_se(sd_dhcp_server_attach_event(server, NULL, 0) >= 0);
+        assert_se(sd_dhcp_server_start(server) >= 0);
+
+        assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == 0);
+        assert_se(sd_dhcp_server_set_lease_pool(server, &address_lo, 10) >= 0);
+        assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_OFFER);
+
+        test.end = 0;
+        /* TODO, shouldn't this fail? */
+        assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_OFFER);
+        test.end = DHCP_OPTION_END;
+        assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_OFFER);
+
+        test.option_type.code = 0;
+        test.option_type.length = 0;
+        test.option_type.type = 0;
+        assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == 0);
+        test.option_type.code = DHCP_OPTION_MESSAGE_TYPE;
+        test.option_type.length = 1;
+        test.option_type.type = DHCP_DISCOVER;
+        assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_OFFER);
+
+        test.message.op = 0;
+        assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == 0);
+        test.message.op = BOOTREQUEST;
+        assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_OFFER);
+
+        test.message.htype = 0;
+        assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == 0);
+        test.message.htype = ARPHRD_ETHER;
+        assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_OFFER);
+
+        test.message.hlen = 0;
+        assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == 0);
+        test.message.hlen = ETHER_ADDR_LEN;
+        assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_OFFER);
+
+        test.option_type.type = DHCP_REQUEST;
+        assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == 0);
+        test.option_requested_ip.code = DHCP_OPTION_REQUESTED_IP_ADDRESS;
+        test.option_requested_ip.length = 4;
+        test.option_requested_ip.address = htobe32(0x12345678);
+        assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_NAK);
+        test.option_server_id.code = DHCP_OPTION_SERVER_IDENTIFIER;
+        test.option_server_id.length = 4;
+        test.option_server_id.address = htobe32(INADDR_LOOPBACK);
+        test.option_requested_ip.address = htobe32(INADDR_LOOPBACK + 3);
+        assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_ACK);
+
+        test.option_server_id.address = htobe32(0x12345678);
+        test.option_requested_ip.address = htobe32(INADDR_LOOPBACK + 3);
+        assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == 0);
+        test.option_server_id.address = htobe32(INADDR_LOOPBACK);
+        test.option_requested_ip.address = htobe32(INADDR_LOOPBACK + 4);
+        assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == 0);
+        test.option_requested_ip.address = htobe32(INADDR_LOOPBACK + 3);
+        assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_ACK);
+
+        test.option_client_id.code = DHCP_OPTION_CLIENT_IDENTIFIER;
+        test.option_client_id.length = 7;
+        test.option_client_id.id[0] = 0x01;
+        test.option_client_id.id[1] = 'A';
+        test.option_client_id.id[2] = 'B';
+        test.option_client_id.id[3] = 'C';
+        test.option_client_id.id[4] = 'D';
+        test.option_client_id.id[5] = 'E';
+        test.option_client_id.id[6] = 'F';
+        assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_ACK);
+
+        test.option_requested_ip.address = htobe32(INADDR_LOOPBACK + 30);
+        assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == 0);
+}
+
+static void test_client_id_hash(void) {
+        DHCPClientId a = {
+                .length = 4,
+        }, b = {
+                .length = 4,
+        };
+        uint8_t hash_key[HASH_KEY_SIZE] = {
+                '0', '1', '2', '3', '4', '5', '6', '7',
+                '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
+        };
+
+        a.data = (uint8_t*)strdup("abcd");
+        b.data = (uint8_t*)strdup("abcd");
+
+        assert_se(client_id_compare_func(&a, &b) == 0);
+        assert_se(client_id_hash_func(&a, hash_key) == client_id_hash_func(&b, hash_key));
+        a.length = 3;
+        assert_se(client_id_compare_func(&a, &b) != 0);
+        a.length = 4;
+        assert_se(client_id_compare_func(&a, &b) == 0);
+        assert_se(client_id_hash_func(&a, hash_key) == client_id_hash_func(&b, hash_key));
+
+        b.length = 3;
+        assert_se(client_id_compare_func(&a, &b) != 0);
+        b.length = 4;
+        assert_se(client_id_compare_func(&a, &b) == 0);
+        assert_se(client_id_hash_func(&a, hash_key) == client_id_hash_func(&b, hash_key));
+
+        free(b.data);
+        b.data = (uint8_t*)strdup("abce");
+        assert_se(client_id_compare_func(&a, &b) != 0);
+
+        free(a.data);
+        free(b.data);
+}
+
+int main(int argc, char *argv[]) {
+        _cleanup_event_unref_ sd_event *e;
+        int r;
+
+        log_set_max_level(LOG_DEBUG);
+        log_parse_environment();
+        log_open();
+
+        assert_se(sd_event_new(&e) >= 0);
+
+        r = test_basic(e);
+        if (r != 0)
+                return r;
+
+        test_message_handler();
+        test_client_id_hash();
+
+        return 0;
+}
diff --git a/src/libsystemd-network/test-dhcp6-client.c b/src/libsystemd-network/test-dhcp6-client.c
new file mode 100644 (file)
index 0000000..96c68e1
--- /dev/null
@@ -0,0 +1,590 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright (C) 2014 Intel Corporation. All rights reserved.
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <net/ethernet.h>
+
+#include "socket-util.h"
+#include "macro.h"
+#include "sd-event.h"
+#include "event-util.h"
+#include "virt.h"
+
+#include "sd-dhcp6-client.h"
+#include "dhcp6-protocol.h"
+#include "dhcp6-internal.h"
+#include "dhcp6-lease-internal.h"
+
+static struct ether_addr mac_addr = {
+        .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}
+};
+
+static bool verbose = false;
+
+static sd_event_source *hangcheck;
+static int test_dhcp_fd[2];
+static int test_index = 42;
+static int test_client_message_num;
+static be32_t test_iaid = 0;
+static uint8_t test_duid[14] = { };
+
+static int test_client_basic(sd_event *e) {
+        sd_dhcp6_client *client;
+
+        if (verbose)
+                printf("* %s\n", __FUNCTION__);
+
+        assert_se(sd_dhcp6_client_new(&client) >= 0);
+        assert_se(client);
+
+        assert_se(sd_dhcp6_client_attach_event(client, e, 0) >= 0);
+
+        assert_se(sd_dhcp6_client_set_index(client, 15) == 0);
+        assert_se(sd_dhcp6_client_set_index(client, -42) == -EINVAL);
+        assert_se(sd_dhcp6_client_set_index(client, -1) == 0);
+        assert_se(sd_dhcp6_client_set_index(client, 42) >= 0);
+
+        assert_se(sd_dhcp6_client_set_mac(client, &mac_addr) >= 0);
+
+        assert_se(sd_dhcp6_client_set_request_option(client, DHCP6_OPTION_CLIENTID) == -EINVAL);
+        assert_se(sd_dhcp6_client_set_request_option(client, DHCP6_OPTION_DNS_SERVERS) == -EEXIST);
+        assert_se(sd_dhcp6_client_set_request_option(client, DHCP6_OPTION_NTP_SERVER) == -EEXIST);
+        assert_se(sd_dhcp6_client_set_request_option(client, DHCP6_OPTION_SNTP_SERVERS) == 0);
+        assert_se(sd_dhcp6_client_set_request_option(client, DHCP6_OPTION_DOMAIN_LIST) == -EEXIST);
+        assert_se(sd_dhcp6_client_set_request_option(client, 10) == -EINVAL);
+
+        assert_se(sd_dhcp6_client_set_callback(client, NULL, NULL) >= 0);
+
+        assert_se(sd_dhcp6_client_detach_event(client) >= 0);
+        assert_se(!sd_dhcp6_client_unref(client));
+
+        return 0;
+}
+
+static int test_option(sd_event *e) {
+        uint8_t packet[] = {
+                'F', 'O', 'O',
+                0x00, DHCP6_OPTION_ORO, 0x00, 0x07,
+                'A', 'B', 'C', 'D', 'E', 'F', 'G',
+                0x00, DHCP6_OPTION_VENDOR_CLASS, 0x00, 0x09,
+                '1', '2', '3', '4', '5', '6', '7', '8', '9',
+                'B', 'A', 'R',
+        };
+        uint8_t result[] = {
+                'F', 'O', 'O',
+                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                'B', 'A', 'R',
+        };
+        uint16_t optcode;
+        size_t optlen;
+        uint8_t *optval, *buf, *out;
+        size_t zero = 0, pos = 3;
+        size_t buflen = sizeof(packet), outlen = sizeof(result);
+
+        if (verbose)
+                printf("* %s\n", __FUNCTION__);
+
+        assert_se(buflen == outlen);
+
+        assert_se(dhcp6_option_parse(&buf, &zero, &optcode, &optlen,
+                                     &optval) == -ENOMSG);
+
+        buflen -= 3;
+        buf = &packet[3];
+        outlen -= 3;
+        out = &result[3];
+
+        assert_se(dhcp6_option_parse(&buf, &buflen, &optcode, &optlen,
+                                     &optval) >= 0);
+        pos += 4 + optlen;
+        assert_se(buf == &packet[pos]);
+        assert_se(optcode == DHCP6_OPTION_ORO);
+        assert_se(optlen == 7);
+        assert_se(buflen + pos == sizeof(packet));
+
+        assert_se(dhcp6_option_append(&out, &outlen, optcode, optlen,
+                                      optval) >= 0);
+        assert_se(out == &result[pos]);
+        assert_se(*out == 0x00);
+
+        assert_se(dhcp6_option_parse(&buf, &buflen, &optcode, &optlen,
+                                     &optval) >= 0);
+        pos += 4 + optlen;
+        assert_se(buf == &packet[pos]);
+        assert_se(optcode == DHCP6_OPTION_VENDOR_CLASS);
+        assert_se(optlen == 9);
+        assert_se(buflen + pos == sizeof(packet));
+
+        assert_se(dhcp6_option_append(&out, &outlen, optcode, optlen,
+                                      optval) >= 0);
+        assert_se(out == &result[pos]);
+        assert_se(*out == 'B');
+
+        assert_se(memcmp(packet, result, sizeof(packet)) == 0);
+
+        return 0;
+}
+
+static uint8_t msg_advertise[198] = {
+        0x02, 0x0f, 0xb4, 0xe5, 0x00, 0x01, 0x00, 0x0e,
+        0x00, 0x01, 0x00, 0x01, 0x1a, 0x6b, 0xf3, 0x30,
+        0x3c, 0x97, 0x0e, 0xcf, 0xa3, 0x7d, 0x00, 0x03,
+        0x00, 0x5e, 0x0e, 0xcf, 0xa3, 0x7d, 0x00, 0x00,
+        0x00, 0x50, 0x00, 0x00, 0x00, 0x78, 0x00, 0x05,
+        0x00, 0x18, 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad,
+        0xbe, 0xef, 0x78, 0xee, 0x1c, 0xf3, 0x09, 0x3c,
+        0x55, 0xad, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00,
+        0x00, 0xb4, 0x00, 0x0d, 0x00, 0x32, 0x00, 0x00,
+        0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x28,
+        0x65, 0x73, 0x29, 0x20, 0x72, 0x65, 0x6e, 0x65,
+        0x77, 0x65, 0x64, 0x2e, 0x20, 0x47, 0x72, 0x65,
+        0x65, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x66,
+        0x72, 0x6f, 0x6d, 0x20, 0x70, 0x6c, 0x61, 0x6e,
+        0x65, 0x74, 0x20, 0x45, 0x61, 0x72, 0x74, 0x68,
+        0x00, 0x17, 0x00, 0x10, 0x20, 0x01, 0x0d, 0xb8,
+        0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x0b,
+        0x03, 0x6c, 0x61, 0x62, 0x05, 0x69, 0x6e, 0x74,
+        0x72, 0x61, 0x00, 0x00, 0x1f, 0x00, 0x10, 0x20,
+        0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+        0x02, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, 0x19,
+        0x40, 0x5c, 0x53, 0x78, 0x2b, 0xcb, 0xb3, 0x6d,
+        0x53, 0x00, 0x07, 0x00, 0x01, 0x00
+};
+
+static uint8_t msg_reply[173] = {
+        0x07, 0xf7, 0x4e, 0x57, 0x00, 0x02, 0x00, 0x0e,
+        0x00, 0x01, 0x00, 0x01, 0x19, 0x40, 0x5c, 0x53,
+        0x78, 0x2b, 0xcb, 0xb3, 0x6d, 0x53, 0x00, 0x01,
+        0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, 0x1a, 0x6b,
+        0xf3, 0x30, 0x3c, 0x97, 0x0e, 0xcf, 0xa3, 0x7d,
+        0x00, 0x03, 0x00, 0x4a, 0x0e, 0xcf, 0xa3, 0x7d,
+        0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x78,
+        0x00, 0x05, 0x00, 0x18, 0x20, 0x01, 0x0d, 0xb8,
+        0xde, 0xad, 0xbe, 0xef, 0x78, 0xee, 0x1c, 0xf3,
+        0x09, 0x3c, 0x55, 0xad, 0x00, 0x00, 0x00, 0x96,
+        0x00, 0x00, 0x00, 0xb4, 0x00, 0x0d, 0x00, 0x1e,
+        0x00, 0x00, 0x41, 0x6c, 0x6c, 0x20, 0x61, 0x64,
+        0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x20,
+        0x77, 0x65, 0x72, 0x65, 0x20, 0x61, 0x73, 0x73,
+        0x69, 0x67, 0x6e, 0x65, 0x64, 0x2e, 0x00, 0x17,
+        0x00, 0x10, 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad,
+        0xbe, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x01, 0x00, 0x18, 0x00, 0x0b, 0x03, 0x6c,
+        0x61, 0x62, 0x05, 0x69, 0x6e, 0x74, 0x72, 0x61,
+        0x00, 0x00, 0x1f, 0x00, 0x10, 0x20, 0x01, 0x0d,
+        0xb8, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x01
+};
+
+static int test_advertise_option(sd_event *e) {
+        _cleanup_dhcp6_lease_free_ sd_dhcp6_lease *lease = NULL;
+        DHCP6Message *advertise = (DHCP6Message *)msg_advertise;
+        uint8_t *optval, *opt = &msg_advertise[sizeof(DHCP6Message)];
+        uint16_t optcode;
+        size_t optlen, len = sizeof(msg_advertise);
+        be32_t val;
+        uint8_t preference = 255;
+        struct in6_addr addr;
+        uint32_t lt_pref, lt_valid;
+        int r;
+        bool opt_clientid = false;
+
+        if (verbose)
+                printf("* %s\n", __FUNCTION__);
+
+        assert_se(dhcp6_lease_new(&lease) >= 0);
+
+        assert_se(advertise->type == DHCP6_ADVERTISE);
+        assert_se((be32toh(advertise->transaction_id) & 0x00ffffff) ==
+                  0x0fb4e5);
+
+        while ((r = dhcp6_option_parse(&opt, &len, &optcode, &optlen,
+                                       &optval)) >= 0) {
+
+                switch(optcode) {
+                case DHCP6_OPTION_CLIENTID:
+                        assert_se(optlen == 14);
+
+                        opt_clientid = true;
+                        break;
+
+                case DHCP6_OPTION_IA_NA:
+                        assert_se(optlen == 94);
+                        assert_se(!memcmp(optval, &msg_advertise[26], optlen));
+
+                        val = htobe32(0x0ecfa37d);
+                        assert_se(!memcmp(optval, &val, sizeof(val)));
+
+                        val = htobe32(80);
+                        assert_se(!memcmp(optval + 4, &val, sizeof(val)));
+
+                        val = htobe32(120);
+                        assert_se(!memcmp(optval + 8, &val, sizeof(val)));
+
+                        assert_se(dhcp6_option_parse_ia(&optval, &optlen,
+                                                        optcode,
+                                                        &lease->ia) >= 0);
+
+                        break;
+
+                case DHCP6_OPTION_SERVERID:
+                        assert_se(optlen == 14);
+                        assert_se(!memcmp(optval, &msg_advertise[179], optlen));
+
+                        assert_se(dhcp6_lease_set_serverid(lease, optval,
+                                                           optlen) >= 0);
+                        break;
+
+                case DHCP6_OPTION_PREFERENCE:
+                        assert_se(optlen == 1);
+                        assert_se(!*optval);
+
+                        assert_se(dhcp6_lease_set_preference(lease,
+                                                             *optval) >= 0);
+                        break;
+
+                default:
+                        break;
+                }
+        }
+
+
+        assert_se(r == -ENOMSG);
+
+        assert_se(opt_clientid);
+
+        assert_se(sd_dhcp6_lease_get_first_address(lease, &addr, &lt_pref,
+                                                   &lt_valid) >= 0);
+        assert_se(!memcmp(&addr, &msg_advertise[42], sizeof(addr)));
+        assert_se(lt_pref == 150);
+        assert_se(lt_valid == 180);
+        assert_se(sd_dhcp6_lease_get_next_address(lease, &addr, &lt_pref,
+                                                  &lt_valid) == -ENOMSG);
+
+        assert_se(sd_dhcp6_lease_get_first_address(lease, &addr, &lt_pref,
+                                                   &lt_valid) >= 0);
+        assert_se(!memcmp(&addr, &msg_advertise[42], sizeof(addr)));
+        assert_se(sd_dhcp6_lease_get_next_address(lease, &addr, &lt_pref,
+                                                  &lt_valid) == -ENOMSG);
+        assert_se(sd_dhcp6_lease_get_next_address(lease, &addr, &lt_pref,
+                                                  &lt_valid) == -ENOMSG);
+        assert_se(sd_dhcp6_lease_get_first_address(lease, &addr, &lt_pref,
+                                                   &lt_valid) >= 0);
+        assert_se(!memcmp(&addr, &msg_advertise[42], sizeof(addr)));
+        assert_se(sd_dhcp6_lease_get_next_address(lease, &addr, &lt_pref,
+                                                  &lt_valid) == -ENOMSG);
+
+        assert_se(dhcp6_lease_get_serverid(lease, &opt, &len) >= 0);
+        assert_se(len == 14);
+        assert_se(!memcmp(opt, &msg_advertise[179], len));
+
+        assert_se(dhcp6_lease_get_preference(lease, &preference) >= 0);
+        assert_se(preference == 0);
+
+        return 0;
+}
+
+static int test_hangcheck(sd_event_source *s, uint64_t usec, void *userdata) {
+        assert_not_reached("Test case should have completed in 2 seconds");
+
+        return 0;
+}
+
+int detect_vm(const char **id) {
+        return 1;
+}
+
+int detect_container(const char **id) {
+        return 1;
+}
+
+int detect_virtualization(const char **id) {
+        return 1;
+}
+
+int dhcp6_network_bind_udp_socket(int index, struct in6_addr *local_address) {
+        assert_se(index == test_index);
+
+        if (socketpair(AF_UNIX, SOCK_STREAM, 0, test_dhcp_fd) < 0)
+                return -errno;
+
+        return test_dhcp_fd[0];
+}
+
+static int test_client_send_reply(DHCP6Message *request) {
+        DHCP6Message reply;
+
+        reply.transaction_id = request->transaction_id;
+        reply.type = DHCP6_REPLY;
+
+        memcpy(msg_reply, &reply.transaction_id, 4);
+
+        memcpy(&msg_reply[26], test_duid, sizeof(test_duid));
+
+        memcpy(&msg_reply[44], &test_iaid, sizeof(test_iaid));
+
+        assert_se(write(test_dhcp_fd[1], msg_reply, sizeof(msg_reply))
+                  == sizeof(msg_reply));
+
+        return 0;
+}
+
+static int test_client_verify_request(DHCP6Message *request, uint8_t *option,
+                                      size_t len) {
+        _cleanup_dhcp6_lease_free_ sd_dhcp6_lease *lease = NULL;
+        uint8_t *optval;
+        uint16_t optcode;
+        size_t optlen;
+        bool found_clientid = false, found_iana = false, found_serverid = false;
+        int r;
+        struct in6_addr addr;
+        be32_t val;
+        uint32_t lt_pref, lt_valid;
+
+        assert_se(request->type == DHCP6_REQUEST);
+
+        assert_se(dhcp6_lease_new(&lease) >= 0);
+
+        while ((r = dhcp6_option_parse(&option, &len,
+                                       &optcode, &optlen, &optval)) >= 0) {
+                switch(optcode) {
+                case DHCP6_OPTION_CLIENTID:
+                        assert_se(!found_clientid);
+                        found_clientid = true;
+
+                        assert_se(!memcmp(optval, &test_duid,
+                                          sizeof(test_duid)));
+
+                        break;
+
+                case DHCP6_OPTION_IA_NA:
+                        assert_se(!found_iana);
+                        found_iana = true;
+
+
+                        assert_se(optlen == 40);
+                        assert_se(!memcmp(optval, &test_iaid, sizeof(test_iaid)));
+
+                        val = htobe32(80);
+                        assert_se(!memcmp(optval + 4, &val, sizeof(val)));
+
+                        val = htobe32(120);
+                        assert_se(!memcmp(optval + 8, &val, sizeof(val)));
+
+                        assert_se(!dhcp6_option_parse_ia(&optval, &optlen,
+                                                         optcode, &lease->ia));
+
+                        break;
+
+                case DHCP6_OPTION_SERVERID:
+                        assert_se(!found_serverid);
+                        found_serverid = true;
+
+                        assert_se(optlen == 14);
+                        assert_se(!memcmp(&msg_advertise[179], optval, optlen));
+
+                        break;
+                }
+        }
+
+        assert_se(r == -ENOMSG);
+        assert_se(found_clientid && found_iana && found_serverid);
+
+        assert_se(sd_dhcp6_lease_get_first_address(lease, &addr, &lt_pref,
+                                                   &lt_valid) >= 0);
+        assert_se(!memcmp(&addr, &msg_advertise[42], sizeof(addr)));
+        assert_se(lt_pref == 150);
+        assert_se(lt_valid == 180);
+
+        assert_se(sd_dhcp6_lease_get_next_address(lease, &addr, &lt_pref,
+                                                  &lt_valid) == -ENOMSG);
+
+        return 0;
+}
+
+static int test_client_send_advertise(DHCP6Message *solicit)
+{
+        DHCP6Message advertise;
+
+        advertise.transaction_id = solicit->transaction_id;
+        advertise.type = DHCP6_ADVERTISE;
+
+        memcpy(msg_advertise, &advertise.transaction_id, 4);
+
+        memcpy(&msg_advertise[8], test_duid, sizeof(test_duid));
+
+        memcpy(&msg_advertise[26], &test_iaid, sizeof(test_iaid));
+
+        assert_se(write(test_dhcp_fd[1], msg_advertise, sizeof(msg_advertise))
+                  == sizeof(msg_advertise));
+
+        return 0;
+}
+
+static int test_client_verify_solicit(DHCP6Message *solicit, uint8_t *option,
+                                      size_t len) {
+        uint8_t *optval;
+        uint16_t optcode;
+        size_t optlen;
+        bool found_clientid = false, found_iana = false;
+        int r;
+
+        assert_se(solicit->type == DHCP6_SOLICIT);
+
+        while ((r = dhcp6_option_parse(&option, &len,
+                                       &optcode, &optlen, &optval)) >= 0) {
+                switch(optcode) {
+                case DHCP6_OPTION_CLIENTID:
+                        assert_se(!found_clientid);
+                        found_clientid = true;
+
+                        assert_se(optlen == sizeof(test_duid));
+                        memcpy(&test_duid, optval, sizeof(test_duid));
+
+                        break;
+
+                case DHCP6_OPTION_IA_NA:
+                        assert_se(!found_iana);
+                        found_iana = true;
+
+                        assert_se(optlen == 12);
+
+                        memcpy(&test_iaid, optval, sizeof(test_iaid));
+
+                        break;
+                }
+        }
+
+        assert_se(r == -ENOMSG);
+        assert_se(found_clientid && found_iana);
+
+        return 0;
+}
+
+int dhcp6_network_send_udp_socket(int s, struct in6_addr *server_address,
+                                  const void *packet, size_t len) {
+        struct in6_addr mcast =
+                IN6ADDR_ALL_DHCP6_RELAY_AGENTS_AND_SERVERS_INIT;
+        DHCP6Message *message;
+        uint8_t *option;
+
+        assert_se(s == test_dhcp_fd[0]);
+        assert_se(server_address);
+        assert_se(packet);
+        assert_se(len > sizeof(DHCP6Message) + 4);
+
+        assert_se(IN6_ARE_ADDR_EQUAL(server_address, &mcast));
+
+        message = (DHCP6Message *)packet;
+        option = (uint8_t *)(message + 1);
+        len -= sizeof(DHCP6Message);
+
+        assert_se(message->transaction_id & 0x00ffffff);
+
+        if (test_client_message_num == 0) {
+                test_client_verify_solicit(message, option, len);
+                test_client_send_advertise(message);
+                test_client_message_num++;
+        } else if (test_client_message_num == 1) {
+                test_client_verify_request(message, option, len);
+                test_client_send_reply(message);
+                test_client_message_num++;
+        }
+
+        return len;
+}
+
+static void test_client_solicit_cb(sd_dhcp6_client *client, int event,
+                                   void *userdata) {
+        sd_event *e = userdata;
+
+        assert_se(e);
+        assert_se(event == DHCP6_EVENT_IP_ACQUIRE);
+
+        assert_se(sd_dhcp6_client_set_request_option(client, DHCP6_OPTION_DNS_SERVERS) == -EBUSY);
+
+        if (verbose)
+                printf("  got DHCPv6 event %d\n", event);
+
+        sd_event_exit(e, 0);
+}
+
+static int test_client_solicit(sd_event *e) {
+        sd_dhcp6_client *client;
+        usec_t time_now = now(clock_boottime_or_monotonic());
+
+        if (verbose)
+                printf("* %s\n", __FUNCTION__);
+
+        assert_se(sd_dhcp6_client_new(&client) >= 0);
+        assert_se(client);
+
+        assert_se(sd_dhcp6_client_attach_event(client, e, 0) >= 0);
+
+        assert_se(sd_dhcp6_client_set_index(client, test_index) == 0);
+        assert_se(sd_dhcp6_client_set_mac(client, &mac_addr) >= 0);
+
+        assert_se(sd_dhcp6_client_set_callback(client,
+                                               test_client_solicit_cb, e) >= 0);
+
+        assert_se(sd_event_add_time(e, &hangcheck, clock_boottime_or_monotonic(),
+                                    time_now + 2 * USEC_PER_SEC, 0,
+                                    test_hangcheck, NULL) >= 0);
+
+        assert_se(sd_dhcp6_client_start(client) >= 0);
+
+        sd_event_loop(e);
+
+        hangcheck = sd_event_source_unref(hangcheck);
+
+        assert_se(!sd_dhcp6_client_unref(client));
+
+        test_dhcp_fd[1] = safe_close(test_dhcp_fd[1]);
+
+        return 0;
+}
+
+int main(int argc, char *argv[]) {
+        _cleanup_event_unref_ sd_event *e;
+
+        assert_se(sd_event_new(&e) >= 0);
+
+        log_set_max_level(LOG_DEBUG);
+        log_parse_environment();
+        log_open();
+
+        test_client_basic(e);
+        test_option(e);
+        test_advertise_option(e);
+        test_client_solicit(e);
+
+        assert_se(!sd_event_unref(e));
+
+        return 0;
+}
diff --git a/src/libsystemd-network/test-icmp6-rs.c b/src/libsystemd-network/test-icmp6-rs.c
new file mode 100644 (file)
index 0000000..afa8562
--- /dev/null
@@ -0,0 +1,158 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright (C) 2014 Intel Corporation. All rights reserved.
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <netinet/icmp6.h>
+
+#include "socket-util.h"
+
+#include "dhcp6-internal.h"
+#include "sd-icmp6-nd.h"
+
+static struct ether_addr mac_addr = {
+        .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}
+};
+
+static bool verbose = false;
+static sd_event_source *test_hangcheck;
+static int test_fd[2];
+
+static int test_rs_hangcheck(sd_event_source *s, uint64_t usec,
+                             void *userdata) {
+        assert(false);
+
+        return 0;
+}
+
+int dhcp_network_icmp6_bind_router_solicitation(int index) {
+        assert(index == 42);
+
+        if (socketpair(AF_UNIX, SOCK_DGRAM, 0, test_fd) < 0)
+                return -errno;
+
+        return test_fd[0];
+}
+
+static int send_ra(uint8_t flags) {
+        uint8_t advertisement[] = {
+                0x86, 0x00, 0xde, 0x83, 0x40, 0xc0, 0x00, 0xb4,
+                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x03, 0x04, 0x40, 0xc0, 0x00, 0x00, 0x01, 0xf4,
+                0x00, 0x00, 0x01, 0xb8, 0x00, 0x00, 0x00, 0x00,
+                0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef,
+                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x19, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
+                0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef,
+                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+                0x1f, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
+                0x03, 0x6c, 0x61, 0x62, 0x05, 0x69, 0x6e, 0x74,
+                0x72, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0x01, 0x01, 0x78, 0x2b, 0xcb, 0xb3, 0x6d, 0x53,
+        };
+
+        advertisement[5] = flags;
+
+        assert(write(test_fd[1], advertisement, sizeof(advertisement)) ==
+               sizeof(advertisement));
+
+        if (verbose)
+                printf("  sent RA with flag 0x%02x\n", flags);
+
+        return 0;
+}
+
+int dhcp_network_icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr) {
+        return send_ra(0);
+}
+
+static void test_rs_done(sd_icmp6_nd *nd, int event, void *userdata) {
+        sd_event *e = userdata;
+        static int idx = 0;
+        struct {
+                uint8_t flag;
+                int event;
+        } flag_event[] = {
+                { 0, ICMP6_EVENT_ROUTER_ADVERTISMENT_NONE },
+                { ND_RA_FLAG_OTHER, ICMP6_EVENT_ROUTER_ADVERTISMENT_OTHER },
+                { ND_RA_FLAG_MANAGED, ICMP6_EVENT_ROUTER_ADVERTISMENT_MANAGED }
+        };
+        assert(nd);
+
+        assert(event == flag_event[idx].event);
+        idx++;
+
+        if (verbose)
+                printf("  got event %d\n", event);
+
+        if (idx < 3)
+                send_ra(flag_event[idx].flag);
+        else
+                sd_event_exit(e, 0);
+}
+
+static void test_rs(sd_event *e) {
+        usec_t time_now = now(clock_boottime_or_monotonic());
+        sd_icmp6_nd *nd;
+
+        if (verbose)
+                printf("* %s\n", __FUNCTION__);
+
+        assert(sd_icmp6_nd_new(&nd) >= 0);
+        assert(nd);
+
+        assert(sd_icmp6_nd_attach_event(nd, e, 0) >= 0);
+
+        assert(sd_icmp6_nd_set_index(nd, 42) >= 0);
+        assert(sd_icmp6_nd_set_mac(nd, &mac_addr) >= 0);
+        assert(sd_icmp6_nd_set_callback(nd, test_rs_done, e) >= 0);
+
+        assert(sd_event_add_time(e, &test_hangcheck, clock_boottime_or_monotonic(),
+                                 time_now + 2 *USEC_PER_SEC, 0,
+                                 test_rs_hangcheck, NULL) >= 0);
+
+        assert(sd_icmp6_nd_stop(nd) >= 0);
+        assert(sd_icmp6_router_solicitation_start(nd) >= 0);
+        assert(sd_icmp6_nd_stop(nd) >= 0);
+
+        assert(sd_icmp6_router_solicitation_start(nd) >= 0);
+
+        sd_event_loop(e);
+
+        test_hangcheck = sd_event_source_unref(test_hangcheck);
+
+        nd = sd_icmp6_nd_unref(nd);
+        assert(!nd);
+
+        close(test_fd[1]);
+}
+
+int main(int argc, char *argv[]) {
+        sd_event *e;
+
+        assert(sd_event_new(&e) >= 0);
+
+        log_set_max_level(LOG_DEBUG);
+        log_parse_environment();
+        log_open();
+
+        test_rs(e);
+
+        return 0;
+}
diff --git a/src/libsystemd-network/test-ipv4ll.c b/src/libsystemd-network/test-ipv4ll.c
new file mode 100644 (file)
index 0000000..459d5c3
--- /dev/null
@@ -0,0 +1,225 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+/***
+  This file is part of systemd.
+
+  Copyright (C) 2014 Axis Communications AB. All rights reserved.
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdlib.h>
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#include "util.h"
+#include "socket-util.h"
+
+#include "sd-ipv4ll.h"
+#include "ipv4ll-internal.h"
+
+static bool verbose = false;
+static bool extended = false;
+static int test_fd[2];
+
+static int basic_request_handler_bind = 0;
+static int basic_request_handler_stop = 0;
+static void* basic_request_handler_user_data = (void*)0xCABCAB;
+static void basic_request_handler(sd_ipv4ll *ll, int event, void *userdata) {
+        assert_se(userdata == basic_request_handler_user_data);
+
+        switch(event) {
+                case IPV4LL_EVENT_STOP:
+                        basic_request_handler_stop = 1;
+                        break;
+                case IPV4LL_EVENT_BIND:
+                        basic_request_handler_bind = 1;
+                        break;
+                default:
+                        assert_se(0);
+                        break;
+        }
+}
+
+int arp_network_send_raw_socket(int fd, const union sockaddr_union *link,
+                                        const struct ether_arp *arp) {
+        assert_se(arp);
+        assert_se(link);
+        assert_se(fd >= 0);
+
+        if (send(fd, arp, sizeof(struct ether_arp), 0) < 0)
+                return -errno;
+
+        return 0;
+}
+
+int arp_network_bind_raw_socket(int index, union sockaddr_union *link) {
+        if (socketpair(AF_UNIX, SOCK_DGRAM | SOCK_NONBLOCK, 0, test_fd) < 0)
+                return -errno;
+
+        return test_fd[0];
+}
+
+static void test_arp_header(struct ether_arp *arp) {
+        assert_se(arp);
+        assert_se(arp->ea_hdr.ar_hrd == htons(ARPHRD_ETHER)); /* HTYPE */
+        assert_se(arp->ea_hdr.ar_pro == htons(ETHERTYPE_IP)); /* PTYPE */
+        assert_se(arp->ea_hdr.ar_hln == ETH_ALEN); /* HLEN */
+        assert_se(arp->ea_hdr.ar_pln == sizeof arp->arp_spa); /* PLEN */
+        assert_se(arp->ea_hdr.ar_op == htons(ARPOP_REQUEST)); /* REQUEST */
+}
+
+static void test_arp_probe(void) {
+        struct ether_arp arp;
+        struct ether_addr mac_addr = {
+                .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}};
+        be32_t pa = 0x3030;
+
+        if (verbose)
+                printf("* %s\n", __FUNCTION__);
+
+        arp_packet_probe(&arp, pa, &mac_addr);
+        test_arp_header(&arp);
+        assert_se(memcmp(arp.arp_sha, &mac_addr, ETH_ALEN) == 0);
+        assert_se(memcmp(arp.arp_tpa, &pa, sizeof(pa)) == 0);
+}
+
+static void test_arp_announce(void) {
+        struct ether_arp arp;
+        struct ether_addr mac_addr = {
+                .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}};
+        be32_t pa = 0x3131;
+
+        if (verbose)
+                printf("* %s\n", __FUNCTION__);
+
+        arp_packet_announcement(&arp, pa, &mac_addr);
+        test_arp_header(&arp);
+        assert_se(memcmp(arp.arp_sha, &mac_addr, ETH_ALEN) == 0);
+        assert_se(memcmp(arp.arp_tpa, &pa, sizeof(pa)) == 0);
+        assert_se(memcmp(arp.arp_spa, &pa, sizeof(pa)) == 0);
+}
+
+static void test_public_api_setters(sd_event *e) {
+        uint8_t seed[8];
+        sd_ipv4ll *ll;
+        struct ether_addr mac_addr = {
+                .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}};
+
+        if (verbose)
+                printf("* %s\n", __FUNCTION__);
+
+        assert_se(sd_ipv4ll_new(&ll) == 0);
+        assert_se(ll);
+
+        assert_se(sd_ipv4ll_attach_event(NULL, NULL, 0) == -EINVAL);
+        assert_se(sd_ipv4ll_attach_event(ll, e, 0) == 0);
+        assert_se(sd_ipv4ll_attach_event(ll, e, 0) == -EBUSY);
+
+        assert_se(sd_ipv4ll_set_callback(NULL, NULL, NULL) == -EINVAL);
+        assert_se(sd_ipv4ll_set_callback(ll, NULL, NULL) == 0);
+
+        assert_se(sd_ipv4ll_set_address_seed(NULL, NULL) == -EINVAL);
+        assert_se(sd_ipv4ll_set_address_seed(ll, NULL) == -EINVAL);
+        assert_se(sd_ipv4ll_set_address_seed(ll, seed) == 0);
+
+        assert_se(sd_ipv4ll_set_mac(NULL, NULL) == -EINVAL);
+        assert_se(sd_ipv4ll_set_mac(ll, NULL) == -EINVAL);
+        assert_se(sd_ipv4ll_set_mac(ll, &mac_addr) == 0);
+
+        assert_se(sd_ipv4ll_set_index(NULL, -1) == -EINVAL);
+        assert_se(sd_ipv4ll_set_index(ll, -1) == -EINVAL);
+        assert_se(sd_ipv4ll_set_index(ll, -99) == -EINVAL);
+        assert_se(sd_ipv4ll_set_index(ll, 1) == 0);
+        assert_se(sd_ipv4ll_set_index(ll, 99) == 0);
+
+        assert_se(sd_ipv4ll_ref(ll) == ll);
+        assert_se(sd_ipv4ll_unref(ll) == ll);
+
+        /* Cleanup */
+        assert_se(sd_ipv4ll_unref(ll) == NULL);
+}
+
+static void test_basic_request(sd_event *e) {
+
+        sd_ipv4ll *ll;
+        struct ether_arp arp;
+        struct ether_addr mac_addr = {
+                .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}};
+
+        if (verbose)
+                printf("* %s\n", __FUNCTION__);
+
+        assert_se(sd_ipv4ll_new(&ll) == 0);
+        assert_se(sd_ipv4ll_start(ll) == -EINVAL);
+
+        assert_se(sd_ipv4ll_attach_event(ll, e, 0) == 0);
+        assert_se(sd_ipv4ll_start(ll) == -EINVAL);
+
+        assert_se(sd_ipv4ll_set_mac(ll, &mac_addr) == 0);
+        assert_se(sd_ipv4ll_start(ll) == -EINVAL);
+
+        assert_se(sd_ipv4ll_set_callback(ll, basic_request_handler,
+                                         basic_request_handler_user_data) == 0);
+        assert_se(sd_ipv4ll_start(ll) == -EINVAL);
+
+        assert_se(sd_ipv4ll_set_index(ll, 1) == 0);
+        assert_se(sd_ipv4ll_start(ll) == 0);
+
+        sd_event_run(e, (uint64_t) -1);
+        assert_se(sd_ipv4ll_start(ll) == -EBUSY);
+
+        /* PROBE */
+        sd_event_run(e, (uint64_t) -1);
+        assert_se(read(test_fd[1], &arp, sizeof(struct ether_arp)) == sizeof(struct ether_arp));
+        test_arp_header(&arp);
+
+        if (extended) {
+                /* PROBE */
+                sd_event_run(e, (uint64_t) -1);
+                assert_se(read(test_fd[1], &arp, sizeof(struct ether_arp)) == sizeof(struct ether_arp));
+                test_arp_header(&arp);
+
+                /* PROBE */
+                sd_event_run(e, (uint64_t) -1);
+                assert_se(read(test_fd[1], &arp, sizeof(struct ether_arp)) == sizeof(struct ether_arp));
+                test_arp_header(&arp);
+
+                sd_event_run(e, (uint64_t) -1);
+                assert_se(basic_request_handler_bind == 1);
+        }
+
+        sd_ipv4ll_stop(ll);
+        assert_se(basic_request_handler_stop == 1);
+
+        /* Cleanup */
+        assert_se(sd_ipv4ll_unref(ll) == NULL);
+        safe_close(test_fd[1]);
+}
+
+int main(int argc, char *argv[]) {
+        sd_event *e;
+
+        assert_se(sd_event_new(&e) >= 0);
+
+        test_public_api_setters(e);
+        test_arp_probe();
+        test_arp_announce();
+        test_basic_request(e);
+
+        return 0;
+}
diff --git a/src/libsystemd-terminal/subterm.c b/src/libsystemd-terminal/subterm.c
new file mode 100644 (file)
index 0000000..3990fb3
--- /dev/null
@@ -0,0 +1,996 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+/***
+  This file is part of systemd.
+
+  Copyright (C) 2014 David Herrmann <dh.herrmann@gmail.com>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+/*
+ * Stacked Terminal-Emulator
+ * This is an interactive test of the term_screen implementation. It runs a
+ * fully-fletched terminal-emulator inside of a parent TTY. That is, instead of
+ * rendering the terminal as X11-window, it renders it as sub-window in the
+ * parent TTY. Think of this like what "GNU-screen" does.
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <termios.h>
+#include "macro.h"
+#include "pty.h"
+#include "ring.h"
+#include "sd-event.h"
+#include "term-internal.h"
+#include "util.h"
+
+typedef struct Output Output;
+typedef struct Terminal Terminal;
+
+struct Output {
+        int fd;
+        unsigned int width;
+        unsigned int height;
+        unsigned int in_width;
+        unsigned int in_height;
+        unsigned int cursor_x;
+        unsigned int cursor_y;
+
+        char obuf[4096];
+        size_t n_obuf;
+
+        bool resized : 1;
+        bool in_menu : 1;
+};
+
+struct Terminal {
+        sd_event *event;
+        sd_event_source *frame_timer;
+        Output *output;
+        term_utf8 utf8;
+        term_parser *parser;
+        term_screen *screen;
+
+        int in_fd;
+        int out_fd;
+        struct termios saved_in_attr;
+        struct termios saved_out_attr;
+
+        Pty *pty;
+        Ring out_ring;
+
+        bool is_scheduled : 1;
+        bool is_dirty : 1;
+        bool is_menu : 1;
+};
+
+/*
+ * Output Handling
+ */
+
+#define BORDER_HORIZ            "\xe2\x94\x81"
+#define BORDER_VERT             "\xe2\x94\x83"
+#define BORDER_VERT_RIGHT       "\xe2\x94\xa3"
+#define BORDER_VERT_LEFT        "\xe2\x94\xab"
+#define BORDER_DOWN_RIGHT       "\xe2\x94\x8f"
+#define BORDER_DOWN_LEFT        "\xe2\x94\x93"
+#define BORDER_UP_RIGHT         "\xe2\x94\x97"
+#define BORDER_UP_LEFT          "\xe2\x94\x9b"
+
+static int output_winch(Output *o) {
+        struct winsize wsz = { };
+        int r;
+
+        assert_return(o, -EINVAL);
+
+        r = ioctl(o->fd, TIOCGWINSZ, &wsz);
+        if (r < 0) {
+                log_error("error: cannot read window-size: %m");
+                return -errno;
+        }
+
+        if (wsz.ws_col != o->width || wsz.ws_row != o->height) {
+                o->width = wsz.ws_col;
+                o->height = wsz.ws_row;
+                o->in_width = MAX(o->width, 2U) - 2;
+                o->in_height = MAX(o->height, 6U) - 6;
+                o->resized = true;
+        }
+
+        return 0;
+}
+
+static int output_flush(Output *o) {
+        ssize_t len;
+
+        if (o->n_obuf < 1)
+                return 0;
+
+        len = loop_write(o->fd, o->obuf, o->n_obuf, false);
+        if (len < 0) {
+                log_error("error: cannot write to TTY (%zd): %s", len, strerror(-len));
+                return len;
+        }
+
+        o->n_obuf = 0;
+
+        return 0;
+}
+
+static int output_write(Output *o, const void *buf, size_t size) {
+        ssize_t len;
+        int r;
+
+        assert_return(o, -EINVAL);
+        assert_return(buf || size < 1, -EINVAL);
+
+        if (size < 1)
+                return 0;
+
+        if (o->n_obuf + size > o->n_obuf && o->n_obuf + size <= sizeof(o->obuf)) {
+                memcpy(o->obuf + o->n_obuf, buf, size);
+                o->n_obuf += size;
+                return 0;
+        }
+
+        r = output_flush(o);
+        if (r < 0)
+                return r;
+
+        len = loop_write(o->fd, buf, size, false);
+        if (len < 0) {
+                log_error("error: cannot write to TTY (%zd): %s", len, strerror(-len));
+                return len;
+        }
+
+        return 0;
+}
+
+_printf_(3,0)
+static int output_vnprintf(Output *o, size_t max, const char *format, va_list args) {
+        char buf[4096];
+        int r;
+
+        assert_return(o, -EINVAL);
+        assert_return(format, -EINVAL);
+        assert_return(max <= sizeof(buf), -EINVAL);
+
+        r = vsnprintf(buf, max, format, args);
+        if (r > (ssize_t)max)
+                r = max;
+
+        return output_write(o, buf, r);
+}
+
+_printf_(3,4)
+static int output_nprintf(Output *o, size_t max, const char *format, ...) {
+        va_list args;
+        int r;
+
+        va_start(args, format);
+        r = output_vnprintf(o, max, format, args);
+        va_end(args);
+
+        return r;
+}
+
+_printf_(2,0)
+static int output_vprintf(Output *o, const char *format, va_list args) {
+        char buf[4096];
+        int r;
+
+        assert_return(o, -EINVAL);
+        assert_return(format, -EINVAL);
+
+        r = vsnprintf(buf, sizeof(buf), format, args);
+
+        assert_return(r < (ssize_t)sizeof(buf), -ENOBUFS);
+
+        return output_write(o, buf, r);
+}
+
+_printf_(2,3)
+static int output_printf(Output *o, const char *format, ...) {
+        va_list args;
+        int r;
+
+        va_start(args, format);
+        r = output_vprintf(o, format, args);
+        va_end(args);
+
+        return r;
+}
+
+static int output_move_to(Output *o, unsigned int x, unsigned int y) {
+        int r;
+
+        assert_return(o, -EINVAL);
+
+        /* force the \e[H code as o->cursor_x/y might be out-of-date */
+
+        r = output_printf(o, "\e[%u;%uH", y + 1, x + 1);
+        if (r < 0)
+                return r;
+
+        o->cursor_x = x;
+        o->cursor_y = y;
+        return 0;
+}
+
+static int output_print_line(Output *o, size_t len) {
+        const char line[] =
+                BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ
+                BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ
+                BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ
+                BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ
+                BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ
+                BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ
+                BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ BORDER_HORIZ;
+        const size_t max = (sizeof(line) - 1) / (sizeof(BORDER_HORIZ) - 1);
+        size_t i;
+        int r = 0;
+
+        assert_return(o, -EINVAL);
+
+        for ( ; len > 0; len -= i) {
+                i = (len > max) ? max : len;
+                r = output_write(o, line, i * (sizeof(BORDER_HORIZ) - 1));
+                if (r < 0)
+                        break;
+        }
+
+        return r;
+}
+
+_printf_(2,3)
+static int output_frame_printl(Output *o, const char *format, ...) {
+        va_list args;
+        int r;
+
+        assert(o);
+        assert(format);
+
+        /* out of frame? */
+        if (o->cursor_y < 3 || o->cursor_y >= o->height - 3)
+                return 0;
+
+        va_start(args, format);
+        r = output_vnprintf(o, o->width - 2, format, args);
+        va_end(args);
+
+        if (r < 0)
+                return r;
+
+        return output_move_to(o, 1, o->cursor_y + 1);
+}
+
+static Output *output_free(Output *o) {
+        if (!o)
+                return NULL;
+
+        /* disable alternate screen buffer */
+        output_printf(o, "\e[?1049l");
+        output_flush(o);
+
+        /* o->fd is owned by the caller */
+        free(o);
+
+        return NULL;
+}
+
+static int output_new(Output **out, int fd) {
+        Output *o;
+        int r;
+
+        assert_return(out, -EINVAL);
+
+        o = new0(Output, 1);
+        if (!o)
+                return log_oom();
+
+        o->fd = fd;
+
+        r = output_winch(o);
+        if (r < 0)
+                goto error;
+
+        /* enable alternate screen buffer */
+        r = output_printf(o, "\e[?1049h");
+        if (r < 0)
+                goto error;
+
+        r = output_flush(o);
+        if (r < 0)
+                goto error;
+
+        *out = o;
+        return 0;
+
+error:
+        output_free(o);
+        return r;
+}
+
+static void output_draw_frame(Output *o) {
+        unsigned int i;
+
+        assert(o);
+
+        /* print header-frame */
+
+        output_printf(o, BORDER_DOWN_RIGHT);
+        output_print_line(o, o->width - 2);
+        output_printf(o, BORDER_DOWN_LEFT
+                         "\r\n"
+                         BORDER_VERT
+                         "\e[2;%uH"    /* cursor-position: 2/x */
+                         BORDER_VERT
+                         "\r\n"
+                         BORDER_VERT_RIGHT,
+                      o->width);
+        output_print_line(o, o->width - 2);
+        output_printf(o, BORDER_VERT_LEFT
+                         "\r\n");
+
+        /* print body-frame */
+
+        for (i = 0; i < o->in_height; ++i) {
+                output_printf(o, BORDER_VERT
+                                 "\e[%u;%uH"    /* cursor-position: 2/x */
+                                 BORDER_VERT
+                                 "\r\n",
+                              i + 4, o->width);
+        }
+
+        /* print footer-frame */
+
+        output_printf(o, BORDER_VERT_RIGHT);
+        output_print_line(o, o->width - 2);
+        output_printf(o, BORDER_VERT_LEFT
+                         "\r\n"
+                         BORDER_VERT
+                         "\e[%u;%uH"    /* cursor-position: 2/x */
+                         BORDER_VERT
+                         "\r\n"
+                         BORDER_UP_RIGHT,
+                      o->height - 1, o->width);
+        output_print_line(o, o->width - 2);
+        output_printf(o, BORDER_UP_LEFT);
+
+        /* print header/footer text */
+
+        output_printf(o, "\e[2;3H");
+        output_nprintf(o, o->width - 4, "systemd - embedded terminal emulator");
+        output_printf(o, "\e[%u;3H", o->height - 1);
+        output_nprintf(o, o->width - 4, "press ^C to enter menu");
+}
+
+static void output_draw_menu(Output *o) {
+        assert(o);
+
+        output_frame_printl(o, "%s", "");
+        output_frame_printl(o, "    Menu: (the following keys are recognized)");
+        output_frame_printl(o, "      q: quit");
+        output_frame_printl(o, "     ^C: send ^C to the PTY");
+}
+
+static void output_draw_screen(Output *o, term_screen *s) {
+        unsigned int i, j;
+        bool first = true;
+
+        assert(o);
+        assert(s);
+
+        for (j = 0; j < s->page->height && j < o->in_height; ++j) {
+                if (!first)
+                        output_printf(o, "\e[m\r\n" BORDER_VERT);
+                first = false;
+
+                for (i = 0; i < s->page->width && i < o->in_width; ++i) {
+                        term_charbuf_t buf;
+                        term_cell *cell = &s->page->lines[j]->cells[i];
+                        size_t k, len, ulen;
+                        const uint32_t *str;
+                        char utf8[4];
+
+                        switch (cell->attr.fg.ccode) {
+                        case TERM_CCODE_DEFAULT:
+                                output_printf(o, "\e[39m");
+                                break;
+                        case TERM_CCODE_256:
+                                output_printf(o, "\e[38;5;%um", cell->attr.fg.c256);
+                                break;
+                        case TERM_CCODE_RGB:
+                                output_printf(o, "\e[38;2;%u;%u;%um", cell->attr.fg.red, cell->attr.fg.green, cell->attr.fg.blue);
+                                break;
+                        case TERM_CCODE_BLACK ... TERM_CCODE_WHITE:
+                                if (cell->attr.bold)
+                                        output_printf(o, "\e[%um", cell->attr.fg.ccode - TERM_CCODE_BLACK + 90);
+                                else
+                                        output_printf(o, "\e[%um", cell->attr.fg.ccode - TERM_CCODE_BLACK + 30);
+                                break;
+                        case TERM_CCODE_LIGHT_BLACK ... TERM_CCODE_LIGHT_WHITE:
+                                output_printf(o, "\e[%um", cell->attr.fg.ccode - TERM_CCODE_LIGHT_BLACK + 90);
+                                break;
+                        }
+
+                        switch (cell->attr.bg.ccode) {
+                        case TERM_CCODE_DEFAULT:
+                                output_printf(o, "\e[49m");
+                                break;
+                        case TERM_CCODE_256:
+                                output_printf(o, "\e[48;5;%um", cell->attr.bg.c256);
+                                break;
+                        case TERM_CCODE_RGB:
+                                output_printf(o, "\e[48;2;%u;%u;%um", cell->attr.bg.red, cell->attr.bg.green, cell->attr.bg.blue);
+                                break;
+                        case TERM_CCODE_BLACK ... TERM_CCODE_WHITE:
+                                output_printf(o, "\e[%um", cell->attr.bg.ccode - TERM_CCODE_BLACK + 40);
+                                break;
+                        case TERM_CCODE_LIGHT_BLACK ... TERM_CCODE_LIGHT_WHITE:
+                                output_printf(o, "\e[%um", cell->attr.bg.ccode - TERM_CCODE_LIGHT_BLACK + 100);
+                                break;
+                        }
+
+                        output_printf(o, "\e[%u;%u;%u;%u;%u;%um",
+                                      cell->attr.bold ? 1 : 22,
+                                      cell->attr.italic ? 3 : 23,
+                                      cell->attr.underline ? 4 : 24,
+                                      cell->attr.inverse ? 7 : 27,
+                                      cell->attr.blink ? 5 : 25,
+                                      cell->attr.hidden ? 8 : 28);
+
+                        str = term_char_resolve(cell->ch, &len, &buf);
+
+                        if (len < 1) {
+                                output_printf(o, " ");
+                        } else {
+                                for (k = 0; k < len; ++k) {
+                                        ulen = term_utf8_encode(utf8, str[k]);
+                                        output_write(o, utf8, ulen);
+                                }
+                        }
+                }
+        }
+
+        output_move_to(o, s->cursor_x + 1, s->cursor_y + 3);
+        output_printf(o, "\e[m");
+}
+
+static void output_draw(Output *o, bool menu, term_screen *screen) {
+        assert(o);
+
+        /*
+         * This renders the contenst of the terminal. The layout contains a
+         * header, the main body and a footer. Around all areas we draw a
+         * border. It looks something like this:
+         *
+         *     +----------------------------------------------------+
+         *     |                      Header                        |
+         *     +----------------------------------------------------+
+         *     |                                                    |
+         *     |                                                    |
+         *     |                                                    |
+         *     |                       Body                         |
+         *     |                                                    |
+         *     |                                                    |
+         *     ~                                                    ~
+         *     ~                                                    ~
+         *     +----------------------------------------------------+
+         *     |                      Footer                        |
+         *     +----------------------------------------------------+
+         *
+         * The body is the part that grows vertically.
+         *
+         * We need at least 6 vertical lines to render the screen. This would
+         * leave 0 lines for the body. Therefore, we require 7 lines so there's
+         * at least one body line. Similarly, we need 2 horizontal cells for the
+         * frame, so we require 3.
+         * If the window is too small, we print an error message instead.
+         */
+
+        if (o->in_width < 1 || o->in_height < 1) {
+                output_printf(o, "\e[2J"         /* erase-in-display: whole screen */
+                                 "\e[H");        /* cursor-position: home */
+                output_printf(o, "error: screen too small, need at least 3x7 cells");
+                output_flush(o);
+                return;
+        }
+
+        /* hide cursor */
+        output_printf(o, "\e[?25l");
+
+        /* frame-content is contant; only resizes can change it */
+        if (o->resized || o->in_menu != menu) {
+                output_printf(o, "\e[2J"         /* erase-in-display: whole screen */
+                                 "\e[H");        /* cursor-position: home */
+                output_draw_frame(o);
+                o->resized = false;
+                o->in_menu = menu;
+        }
+
+        /* move cursor to child's position */
+        output_move_to(o, 1, 3);
+
+        if (menu)
+                output_draw_menu(o);
+        else
+                output_draw_screen(o, screen);
+
+        /* show cursor */
+        if (!(screen->flags & TERM_FLAG_HIDE_CURSOR))
+                output_printf(o, "\e[?25h");
+
+        /*
+         * Hack: sd-term was not written to support TTY as output-objects, thus
+         * expects callers to use term_screen_feed_keyboard(). However, we
+         * forward TTY input directly. Hence, we're not notified about keypad
+         * changes. Update the related modes djring redraw to keep them at least
+         * in sync.
+         */
+        if (screen->flags & TERM_FLAG_CURSOR_KEYS)
+                output_printf(o, "\e[?1h");
+        else
+                output_printf(o, "\e[?1l");
+
+        if (screen->flags & TERM_FLAG_KEYPAD_MODE)
+                output_printf(o, "\e=");
+        else
+                output_printf(o, "\e>");
+
+        output_flush(o);
+}
+
+/*
+ * Terminal Handling
+ */
+
+static void terminal_dirty(Terminal *t) {
+        usec_t usec;
+        int r;
+
+        assert(t);
+
+        if (t->is_scheduled) {
+                t->is_dirty = true;
+                return;
+        }
+
+        /* 16ms timer */
+        r = sd_event_now(t->event, CLOCK_MONOTONIC, &usec);
+        assert(r >= 0);
+
+        usec += 16 * USEC_PER_MSEC;
+        r = sd_event_source_set_time(t->frame_timer, usec);
+        if (r >= 0) {
+                r = sd_event_source_set_enabled(t->frame_timer, SD_EVENT_ONESHOT);
+                if (r >= 0)
+                        t->is_scheduled = true;
+        }
+
+        t->is_dirty = false;
+        output_draw(t->output, t->is_menu, t->screen);
+}
+
+static int terminal_frame_timer_fn(sd_event_source *source, uint64_t usec, void *userdata) {
+        Terminal *t = userdata;
+
+        t->is_scheduled = false;
+        if (t->is_dirty)
+                terminal_dirty(t);
+
+        return 0;
+}
+
+static int terminal_winch_fn(sd_event_source *source, const struct signalfd_siginfo *ssi, void *userdata) {
+        Terminal *t = userdata;
+        int r;
+
+        output_winch(t->output);
+
+        if (t->pty) {
+                r = pty_resize(t->pty, t->output->in_width, t->output->in_height);
+                if (r < 0)
+                        log_error("error: pty_resize() (%d): %s", r, strerror(-r));
+        }
+
+        r = term_screen_resize(t->screen, t->output->in_width, t->output->in_height);
+        if (r < 0)
+                log_error("error: term_screen_resize() (%d): %s", r, strerror(-r));
+
+        terminal_dirty(t);
+
+        return 0;
+}
+
+static int terminal_push_tmp(Terminal *t, uint32_t ucs4) {
+        char buf[4];
+        size_t len;
+        int r;
+
+        assert(t);
+
+        len = term_utf8_encode(buf, ucs4);
+        if (len < 1)
+                return 0;
+
+        r = ring_push(&t->out_ring, buf, len);
+        if (r < 0)
+                log_oom();
+
+        return r;
+}
+
+static int terminal_write_tmp(Terminal *t) {
+        struct iovec vec[2];
+        size_t num, i;
+        int r;
+
+        assert(t);
+
+        num = ring_peek(&t->out_ring, vec);
+        if (num < 1)
+                return 0;
+
+        if (t->pty) {
+                for (i = 0; i < num; ++i) {
+                        r = pty_write(t->pty, vec[i].iov_base, vec[i].iov_len);
+                        if (r < 0) {
+                                log_error("error: cannot write to PTY (%d): %s", r, strerror(-r));
+                                return r;
+                        }
+                }
+        }
+
+        ring_flush(&t->out_ring);
+        return 0;
+}
+
+static void terminal_discard_tmp(Terminal *t) {
+        assert(t);
+
+        ring_flush(&t->out_ring);
+}
+
+static int terminal_menu(Terminal *t, const term_seq *seq) {
+        switch (seq->type) {
+        case TERM_SEQ_IGNORE:
+                break;
+        case TERM_SEQ_GRAPHIC:
+                switch (seq->terminator) {
+                case 'q':
+                        sd_event_exit(t->event, 0);
+                        return 0;
+                }
+
+                break;
+        case TERM_SEQ_CONTROL:
+                switch (seq->terminator) {
+                case 0x03:
+                        terminal_push_tmp(t, 0x03);
+                        terminal_write_tmp(t);
+                        break;
+                }
+
+                break;
+        }
+
+        t->is_menu = false;
+        terminal_dirty(t);
+
+        return 0;
+}
+
+static int terminal_io_fn(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
+        Terminal *t = userdata;
+        char buf[4096];
+        ssize_t len, i;
+        int r, type;
+
+        len = read(fd, buf, sizeof(buf));
+        if (len < 0) {
+                if (errno == EAGAIN || errno == EINTR)
+                        return 0;
+
+                log_error("error: cannot read from TTY (%d): %m", -errno);
+                return -errno;
+        }
+
+        for (i = 0; i < len; ++i) {
+                const term_seq *seq;
+                const uint32_t *str;
+                size_t n_str, j;
+
+                str = term_utf8_decode(&t->utf8, &n_str, buf[i]);
+                for (j = 0; j < n_str; ++j) {
+                        type = term_parser_feed(t->parser, &seq, str[j]);
+                        if (type < 0) {
+                                log_error("error: term_parser_feed() (%d): %s", type, strerror(-type));
+                                return type;
+                        }
+
+                        if (!t->is_menu) {
+                                r = terminal_push_tmp(t, str[j]);
+                                if (r < 0)
+                                        return r;
+                        }
+
+                        if (type == TERM_SEQ_NONE) {
+                                /* We only intercept one-char sequences, so in
+                                 * case term_parser_feed() couldn't parse a
+                                 * sequence, it is waiting for more data. We
+                                 * know it can never be a one-char sequence
+                                 * then, so we can safely forward the data.
+                                 * This avoids withholding ESC or other values
+                                 * that may be one-shot depending on the
+                                 * application. */
+                                r = terminal_write_tmp(t);
+                                if (r < 0)
+                                        return r;
+                        } else if (t->is_menu) {
+                                r = terminal_menu(t, seq);
+                                if (r < 0)
+                                        return r;
+                        } else if (seq->type == TERM_SEQ_CONTROL && seq->terminator == 0x03) { /* ^C opens the menu */
+                                terminal_discard_tmp(t);
+                                t->is_menu = true;
+                                terminal_dirty(t);
+                        } else {
+                                r = terminal_write_tmp(t);
+                                if (r < 0)
+                                        return r;
+                        }
+                }
+        }
+
+        return 0;
+}
+
+static int terminal_pty_fn(Pty *pty, void *userdata, unsigned int event, const void *ptr, size_t size) {
+        Terminal *t = userdata;
+        int r;
+
+        switch (event) {
+        case PTY_CHILD:
+                sd_event_exit(t->event, 0);
+                break;
+        case PTY_DATA:
+                r = term_screen_feed_text(t->screen, ptr, size);
+                if (r < 0) {
+                        log_error("error: term_screen_feed_text() (%d): %s", r, strerror(-r));
+                        return r;
+                }
+
+                terminal_dirty(t);
+                break;
+        }
+
+        return 0;
+}
+
+static int terminal_write_fn(term_screen *screen, void *userdata, const void *buf, size_t size) {
+        Terminal *t = userdata;
+        int r;
+
+        if (!t->pty)
+                return 0;
+
+        r = ring_push(&t->out_ring, buf, size);
+        if (r < 0)
+                log_oom();
+
+        return r;
+}
+
+static int terminal_cmd_fn(term_screen *screen, void *userdata, unsigned int cmd, const term_seq *seq) {
+        return 0;
+}
+
+static Terminal *terminal_free(Terminal *t) {
+        if (!t)
+                return NULL;
+
+        ring_clear(&t->out_ring);
+        term_screen_unref(t->screen);
+        term_parser_free(t->parser);
+        output_free(t->output);
+        sd_event_source_unref(t->frame_timer);
+        sd_event_unref(t->event);
+        tcsetattr(t->in_fd, TCSANOW, &t->saved_in_attr);
+        tcsetattr(t->out_fd, TCSANOW, &t->saved_out_attr);
+        free(t);
+
+        return NULL;
+}
+
+static int terminal_new(Terminal **out, int in_fd, int out_fd) {
+        struct termios in_attr, out_attr;
+        Terminal *t;
+        int r;
+
+        assert_return(out, -EINVAL);
+
+        r = tcgetattr(in_fd, &in_attr);
+        if (r < 0) {
+                log_error("error: tcgetattr() (%d): %m", -errno);
+                return -errno;
+        }
+
+        r = tcgetattr(out_fd, &out_attr);
+        if (r < 0) {
+                log_error("error: tcgetattr() (%d): %m", -errno);
+                return -errno;
+        }
+
+        t = new0(Terminal, 1);
+        if (!t)
+                return log_oom();
+
+        t->in_fd = in_fd;
+        t->out_fd = out_fd;
+        memcpy(&t->saved_in_attr, &in_attr, sizeof(in_attr));
+        memcpy(&t->saved_out_attr, &out_attr, sizeof(out_attr));
+
+        cfmakeraw(&in_attr);
+        cfmakeraw(&out_attr);
+
+        r = tcsetattr(t->in_fd, TCSANOW, &in_attr);
+        if (r < 0) {
+                log_error("error: tcsetattr() (%d): %s", r, strerror(-r));
+                goto error;
+        }
+
+        r = tcsetattr(t->out_fd, TCSANOW, &out_attr);
+        if (r < 0) {
+                log_error("error: tcsetattr() (%d): %s", r, strerror(-r));
+                goto error;
+        }
+
+        r = sd_event_default(&t->event);
+        if (r < 0) {
+                log_error("error: sd_event_default() (%d): %s", r, strerror(-r));
+                goto error;
+        }
+
+        r = sigprocmask_many(SIG_BLOCK, SIGINT, SIGQUIT, SIGTERM, SIGWINCH, SIGCHLD, -1);
+        if (r < 0) {
+                log_error("error: sigprocmask_many() (%d): %s", r, strerror(-r));
+                goto error;
+        }
+
+        r = sd_event_add_signal(t->event, NULL, SIGINT, NULL, NULL);
+        if (r < 0) {
+                log_error("error: sd_event_add_signal() (%d): %s", r, strerror(-r));
+                goto error;
+        }
+
+        r = sd_event_add_signal(t->event, NULL, SIGQUIT, NULL, NULL);
+        if (r < 0) {
+                log_error("error: sd_event_add_signal() (%d): %s", r, strerror(-r));
+                goto error;
+        }
+
+        r = sd_event_add_signal(t->event, NULL, SIGTERM, NULL, NULL);
+        if (r < 0) {
+                log_error("error: sd_event_add_signal() (%d): %s", r, strerror(-r));
+                goto error;
+        }
+
+        r = sd_event_add_signal(t->event, NULL, SIGWINCH, terminal_winch_fn, t);
+        if (r < 0) {
+                log_error("error: sd_event_add_signal() (%d): %s", r, strerror(-r));
+                goto error;
+        }
+
+        /* force initial redraw on event-loop enter */
+        t->is_dirty = true;
+        r = sd_event_add_time(t->event, &t->frame_timer, CLOCK_MONOTONIC, 0, 0, terminal_frame_timer_fn, t);
+        if (r < 0) {
+                log_error("error: sd_event_add_time() (%d): %s", r, strerror(-r));
+                goto error;
+        }
+
+        r = output_new(&t->output, out_fd);
+        if (r < 0)
+                goto error;
+
+        r = term_parser_new(&t->parser, true);
+        if (r < 0)
+                goto error;
+
+        r = term_screen_new(&t->screen, terminal_write_fn, t, terminal_cmd_fn, t);
+        if (r < 0)
+                goto error;
+
+        r = term_screen_set_answerback(t->screen, "systemd-subterm");
+        if (r < 0)
+                goto error;
+
+        r = term_screen_resize(t->screen, t->output->in_width, t->output->in_height);
+        if (r < 0) {
+                log_error("error: term_screen_resize() (%d): %s", r, strerror(-r));
+                goto error;
+        }
+
+        r = sd_event_add_io(t->event, NULL, in_fd, EPOLLIN, terminal_io_fn, t);
+        if (r < 0)
+                goto error;
+
+        *out = t;
+        return 0;
+
+error:
+        terminal_free(t);
+        return r;
+}
+
+static int terminal_run(Terminal *t) {
+        pid_t pid;
+
+        assert_return(t, -EINVAL);
+
+        pid = pty_fork(&t->pty, t->event, terminal_pty_fn, t, t->output->in_width, t->output->in_height);
+        if (pid < 0) {
+                log_error("error: cannot fork PTY (%d): %s", pid, strerror(-pid));
+                return pid;
+        } else if (pid == 0) {
+                /* child */
+
+                char **argv = (char*[]){
+                        (char*)getenv("SHELL") ? : (char*)_PATH_BSHELL,
+                        NULL
+                };
+
+                setenv("TERM", "xterm-256color", 1);
+                setenv("COLORTERM", "systemd-subterm", 1);
+
+                execve(argv[0], argv, environ);
+                log_error("error: cannot exec %s (%d): %m", argv[0], -errno);
+                _exit(1);
+        }
+
+        /* parent */
+
+        return sd_event_loop(t->event);
+}
+
+/*
+ * Context Handling
+ */
+
+int main(int argc, char *argv[]) {
+        Terminal *t = NULL;
+        int r;
+
+        r = terminal_new(&t, 0, 1);
+        if (r < 0)
+                goto out;
+
+        r = terminal_run(t);
+        if (r < 0)
+                goto out;
+
+out:
+        if (r < 0)
+                log_error("error: terminal failed (%d): %s", r, strerror(-r));
+        terminal_free(t);
+        return -r;
+}
diff --git a/src/libsystemd-terminal/term-charset.c b/src/libsystemd-terminal/term-charset.c
new file mode 100644 (file)
index 0000000..a00a191
--- /dev/null
@@ -0,0 +1,491 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright (C) 2014 David Herrmann <dh.herrmann@gmail.com>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+/*
+ * VTE Character Sets
+ * These are predefined charactersets that can be loaded into GL and GR. By
+ * default we use unicode_lower and unicode_upper, that is, both sets have the
+ * exact unicode mapping. unicode_lower is effectively ASCII and unicode_upper
+ * as defined by the unicode standard (I guess, ISO 8859-1).
+ * Several other character sets are defined here. However, all of them are
+ * limited to the 96 character space of GL or GR. Everything beyond GR (which
+ * was not supported by the classic VTs by DEC but is available in VT emulators
+ * that support unicode/UTF8) is always mapped to unicode and cannot be changed
+ * by these character sets. Even mapping GL and GR is only available for
+ * backwards compatibility as new applications can use the Unicode functionality
+ * of the VTE.
+ *
+ * Moreover, mapping GR is almost unnecessary to support. In fact, Unicode UTF-8
+ * support in VTE works by reading every incoming data as UTF-8 stream. This
+ * maps GL/ASCII to ASCII, as UTF-8 is backwards compatible to ASCII, however,
+ * everything that has the 8th bit set is a >=2-byte haracter in UTF-8. That is,
+ * this is in no way backwards compatible to >=VT220 8bit support. Therefore, if
+ * someone maps a character set into GR and wants to use them with this VTE,
+ * then they must already send UTF-8 characters to use GR (all GR characters are
+ * 8-bits). Hence, they can easily also send the correct UTF-8 character for the
+ * unicode mapping.
+ * The only advantage is that most characters in many sets are 3-byte UTF-8
+ * characters and by mapping the set into GR/GL you can use 2 or 1 byte UTF-8
+ * characters which saves bandwidth.
+ * Another reason is, if you have older applications that use the VT220 8-bit
+ * support and you put a ASCII/8bit-extension to UTF-8 converter in between, you
+ * need these mappings to have the application behave correctly if it uses GL/GR
+ * mappings extensively.
+ *
+ * Anyway, we support GL/GR mappings so here are the most commonly used maps as
+ * defined by Unicode-standard, DEC-private maps and other famous charmaps.
+ *
+ * Characters 1-32 are always the control characters (part of CL) and cannot be
+ * mapped. Characters 34-127 (94 characters) are part of GL and can be mapped.
+ * Characters 33 and 128 are not part of GL and always mapped by the VTE.
+ * However, for GR they can be mapped differently (96 chars) so we have to
+ * include them. The mapper has to take care not to use them in GL.
+ */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include "term-internal.h"
+
+/*
+ * Lower Unicode character set. This maps the characters to the basic ASCII
+ * characters 33-126. These are all graphics characters defined in ASCII.
+ */
+term_charset term_unicode_lower = {
+        [0] = 32,
+        [1] = 33,
+        [2] = 34,
+        [3] = 35,
+        [4] = 36,
+        [5] = 37,
+        [6] = 38,
+        [7] = 39,
+        [8] = 40,
+        [9] = 41,
+        [10] = 42,
+        [11] = 43,
+        [12] = 44,
+        [13] = 45,
+        [14] = 46,
+        [15] = 47,
+        [16] = 48,
+        [17] = 49,
+        [18] = 50,
+        [19] = 51,
+        [20] = 52,
+        [21] = 53,
+        [22] = 54,
+        [23] = 55,
+        [24] = 56,
+        [25] = 57,
+        [26] = 58,
+        [27] = 59,
+        [28] = 60,
+        [29] = 61,
+        [30] = 62,
+        [31] = 63,
+        [32] = 64,
+        [33] = 65,
+        [34] = 66,
+        [35] = 67,
+        [36] = 68,
+        [37] = 69,
+        [38] = 70,
+        [39] = 71,
+        [40] = 72,
+        [41] = 73,
+        [42] = 74,
+        [43] = 75,
+        [44] = 76,
+        [45] = 77,
+        [46] = 78,
+        [47] = 79,
+        [48] = 80,
+        [49] = 81,
+        [50] = 82,
+        [51] = 83,
+        [52] = 84,
+        [53] = 85,
+        [54] = 86,
+        [55] = 87,
+        [56] = 88,
+        [57] = 89,
+        [58] = 90,
+        [59] = 91,
+        [60] = 92,
+        [61] = 93,
+        [62] = 94,
+        [63] = 95,
+        [64] = 96,
+        [65] = 97,
+        [66] = 98,
+        [67] = 99,
+        [68] = 100,
+        [69] = 101,
+        [70] = 102,
+        [71] = 103,
+        [72] = 104,
+        [73] = 105,
+        [74] = 106,
+        [75] = 107,
+        [76] = 108,
+        [77] = 109,
+        [78] = 110,
+        [79] = 111,
+        [80] = 112,
+        [81] = 113,
+        [82] = 114,
+        [83] = 115,
+        [84] = 116,
+        [85] = 117,
+        [86] = 118,
+        [87] = 119,
+        [88] = 120,
+        [89] = 121,
+        [90] = 122,
+        [91] = 123,
+        [92] = 124,
+        [93] = 125,
+        [94] = 126,
+        [95] = 127,
+};
+
+/*
+ * Upper Unicode Table
+ * This maps all characters to the upper unicode characters 161-254. These are
+ * not compatible to any older 8 bit character sets. See the Unicode standard
+ * for the definitions of each symbol.
+ */
+term_charset term_unicode_upper = {
+        [0] = 160,
+        [1] = 161,
+        [2] = 162,
+        [3] = 163,
+        [4] = 164,
+        [5] = 165,
+        [6] = 166,
+        [7] = 167,
+        [8] = 168,
+        [9] = 169,
+        [10] = 170,
+        [11] = 171,
+        [12] = 172,
+        [13] = 173,
+        [14] = 174,
+        [15] = 175,
+        [16] = 176,
+        [17] = 177,
+        [18] = 178,
+        [19] = 179,
+        [20] = 180,
+        [21] = 181,
+        [22] = 182,
+        [23] = 183,
+        [24] = 184,
+        [25] = 185,
+        [26] = 186,
+        [27] = 187,
+        [28] = 188,
+        [29] = 189,
+        [30] = 190,
+        [31] = 191,
+        [32] = 192,
+        [33] = 193,
+        [34] = 194,
+        [35] = 195,
+        [36] = 196,
+        [37] = 197,
+        [38] = 198,
+        [39] = 199,
+        [40] = 200,
+        [41] = 201,
+        [42] = 202,
+        [43] = 203,
+        [44] = 204,
+        [45] = 205,
+        [46] = 206,
+        [47] = 207,
+        [48] = 208,
+        [49] = 209,
+        [50] = 210,
+        [51] = 211,
+        [52] = 212,
+        [53] = 213,
+        [54] = 214,
+        [55] = 215,
+        [56] = 216,
+        [57] = 217,
+        [58] = 218,
+        [59] = 219,
+        [60] = 220,
+        [61] = 221,
+        [62] = 222,
+        [63] = 223,
+        [64] = 224,
+        [65] = 225,
+        [66] = 226,
+        [67] = 227,
+        [68] = 228,
+        [69] = 229,
+        [70] = 230,
+        [71] = 231,
+        [72] = 232,
+        [73] = 233,
+        [74] = 234,
+        [75] = 235,
+        [76] = 236,
+        [77] = 237,
+        [78] = 238,
+        [79] = 239,
+        [80] = 240,
+        [81] = 241,
+        [82] = 242,
+        [83] = 243,
+        [84] = 244,
+        [85] = 245,
+        [86] = 246,
+        [87] = 247,
+        [88] = 248,
+        [89] = 249,
+        [90] = 250,
+        [91] = 251,
+        [92] = 252,
+        [93] = 253,
+        [94] = 254,
+        [95] = 255,
+};
+
+/*
+ * The DEC supplemental graphics set. For its definition see here:
+ *  http://vt100.net/docs/vt220-rm/table2-3b.html
+ * Its basically a mixture of common European symbols that are not part of
+ * ASCII. Most often, this is mapped into GR to extend the basci ASCII part.
+ *
+ * This is very similar to unicode_upper, however, few symbols differ so do not
+ * mix them up!
+ */
+term_charset term_dec_supplemental_graphics = {
+        [0] = -1,       /* undefined */
+        [1] = 161,
+        [2] = 162,
+        [3] = 163,
+        [4] = 0,
+        [5] = 165,
+        [6] = 0,
+        [7] = 167,
+        [8] = 164,
+        [9] = 169,
+        [10] = 170,
+        [11] = 171,
+        [12] = 0,
+        [13] = 0,
+        [14] = 0,
+        [15] = 0,
+        [16] = 176,
+        [17] = 177,
+        [18] = 178,
+        [19] = 179,
+        [20] = 0,
+        [21] = 181,
+        [22] = 182,
+        [23] = 183,
+        [24] = 0,
+        [25] = 185,
+        [26] = 186,
+        [27] = 187,
+        [28] = 188,
+        [29] = 189,
+        [30] = 0,
+        [31] = 191,
+        [32] = 192,
+        [33] = 193,
+        [34] = 194,
+        [35] = 195,
+        [36] = 196,
+        [37] = 197,
+        [38] = 198,
+        [39] = 199,
+        [40] = 200,
+        [41] = 201,
+        [42] = 202,
+        [43] = 203,
+        [44] = 204,
+        [45] = 205,
+        [46] = 206,
+        [47] = 207,
+        [48] = 0,
+        [49] = 209,
+        [50] = 210,
+        [51] = 211,
+        [52] = 212,
+        [53] = 213,
+        [54] = 214,
+        [55] = 338,
+        [56] = 216,
+        [57] = 217,
+        [58] = 218,
+        [59] = 219,
+        [60] = 220,
+        [61] = 376,
+        [62] = 0,
+        [63] = 223,
+        [64] = 224,
+        [65] = 225,
+        [66] = 226,
+        [67] = 227,
+        [68] = 228,
+        [69] = 229,
+        [70] = 230,
+        [71] = 231,
+        [72] = 232,
+        [73] = 233,
+        [74] = 234,
+        [75] = 235,
+        [76] = 236,
+        [77] = 237,
+        [78] = 238,
+        [79] = 239,
+        [80] = 0,
+        [81] = 241,
+        [82] = 242,
+        [83] = 243,
+        [84] = 244,
+        [85] = 245,
+        [86] = 246,
+        [87] = 339,
+        [88] = 248,
+        [89] = 249,
+        [90] = 250,
+        [91] = 251,
+        [92] = 252,
+        [93] = 255,
+        [94] = 0,
+        [95] = -1,       /* undefined */
+};
+
+/*
+ * DEC special graphics character set. See here for its definition:
+ *  http://vt100.net/docs/vt220-rm/table2-4.html
+ * This contains several characters to create ASCII drawings and similar. Its
+ * commonly mapped into GR to extend the basic ASCII characters.
+ *
+ * Lower 62 characters map to ASCII 33-64, everything beyond is special and
+ * commonly used for ASCII drawings. It depends on the Unicode Standard 3.2 for
+ * the extended horizontal scan-line characters 3, 5, 7, and 9.
+ */
+term_charset term_dec_special_graphics = {
+        [0] = -1,       /* undefined */
+        [1] = 33,
+        [2] = 34,
+        [3] = 35,
+        [4] = 36,
+        [5] = 37,
+        [6] = 38,
+        [7] = 39,
+        [8] = 40,
+        [9] = 41,
+        [10] = 42,
+        [11] = 43,
+        [12] = 44,
+        [13] = 45,
+        [14] = 46,
+        [15] = 47,
+        [16] = 48,
+        [17] = 49,
+        [18] = 50,
+        [19] = 51,
+        [20] = 52,
+        [21] = 53,
+        [22] = 54,
+        [23] = 55,
+        [24] = 56,
+        [25] = 57,
+        [26] = 58,
+        [27] = 59,
+        [28] = 60,
+        [29] = 61,
+        [30] = 62,
+        [31] = 63,
+        [32] = 64,
+        [33] = 65,
+        [34] = 66,
+        [35] = 67,
+        [36] = 68,
+        [37] = 69,
+        [38] = 70,
+        [39] = 71,
+        [40] = 72,
+        [41] = 73,
+        [42] = 74,
+        [43] = 75,
+        [44] = 76,
+        [45] = 77,
+        [46] = 78,
+        [47] = 79,
+        [48] = 80,
+        [49] = 81,
+        [50] = 82,
+        [51] = 83,
+        [52] = 84,
+        [53] = 85,
+        [54] = 86,
+        [55] = 87,
+        [56] = 88,
+        [57] = 89,
+        [58] = 90,
+        [59] = 91,
+        [60] = 92,
+        [61] = 93,
+        [62] = 94,
+        [63] = 0,
+        [64] = 9830,
+        [65] = 9618,
+        [66] = 9225,
+        [67] = 9228,
+        [68] = 9229,
+        [69] = 9226,
+        [70] = 176,
+        [71] = 177,
+        [72] = 9252,
+        [73] = 9227,
+        [74] = 9496,
+        [75] = 9488,
+        [76] = 9484,
+        [77] = 9492,
+        [78] = 9532,
+        [79] = 9146,
+        [80] = 9147,
+        [81] = 9472,
+        [82] = 9148,
+        [83] = 9149,
+        [84] = 9500,
+        [85] = 9508,
+        [86] = 9524,
+        [87] = 9516,
+        [88] = 9474,
+        [89] = 8804,
+        [90] = 8805,
+        [91] = 960,
+        [92] = 8800,
+        [93] = 163,
+        [94] = 8901,
+        [95] = -1,      /* undefined */
+};
diff --git a/src/libsystemd-terminal/term-internal.h b/src/libsystemd-terminal/term-internal.h
new file mode 100644 (file)
index 0000000..345996b
--- /dev/null
@@ -0,0 +1,782 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright (C) 2014 David Herrmann <dh.herrmann@gmail.com>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#pragma once
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include "util.h"
+
+typedef struct term_char term_char_t;
+typedef struct term_charbuf term_charbuf_t;
+
+typedef struct term_color term_color;
+typedef struct term_attr term_attr;
+typedef struct term_cell term_cell;
+typedef struct term_line term_line;
+
+typedef struct term_page term_page;
+typedef struct term_history term_history;
+
+typedef struct term_utf8 term_utf8;
+typedef struct term_seq term_seq;
+typedef struct term_parser term_parser;
+typedef uint32_t term_charset[96];
+
+typedef struct term_screen term_screen;
+
+/*
+ * Miscellaneous
+ * Sundry things and external helpers.
+ */
+
+int mk_wcwidth(wchar_t ucs4);
+int mk_wcwidth_cjk(wchar_t ucs4);
+int mk_wcswidth(const wchar_t *str, size_t len);
+int mk_wcswidth_cjk(const wchar_t *str, size_t len);
+
+/*
+ * Ageing
+ * Redrawing terminals is quite expensive. Therefore, we avoid redrawing on
+ * each single modification and mark modified cells instead. This way, we know
+ * which cells to redraw on the next frame. However, a single DIRTY flag is not
+ * enough for double/triple buffered screens, hence, we use an AGE field for
+ * each cell. If the cell is modified, we simply increase the age by one. Each
+ * framebuffer can then remember its last rendered age and request an update of
+ * all newer cells.
+ * TERM_AGE_NULL is special. If used as cell age, the cell must always be
+ * redrawn (forced update). If used as framebuffer age, all cells are drawn.
+ * This way, we can allow integer wrap-arounds.
+ */
+
+typedef uint64_t term_age_t;
+
+#define TERM_AGE_NULL 0
+
+/*
+ * Characters
+ * Each cell in a terminal page contains only a single character. This is
+ * usually a single UCS-4 value. However, Unicode allows combining-characters,
+ * therefore, the number of UCS-4 characters per cell must be unlimited. The
+ * term_char_t object wraps the internal combining char API so it can be
+ * treated as a single object.
+ */
+
+struct term_char {
+        /* never access this value directly */
+        uint64_t _value;
+};
+
+struct term_charbuf {
+        /* 3 bytes + zero-terminator */
+        uint32_t buf[4];
+};
+
+#define TERM_CHAR_INIT(_val) ((term_char_t){ ._value = (_val) })
+#define TERM_CHAR_NULL TERM_CHAR_INIT(0)
+
+term_char_t term_char_set(term_char_t previous, uint32_t append_ucs4);
+term_char_t term_char_merge(term_char_t base, uint32_t append_ucs4);
+term_char_t term_char_dup(term_char_t ch);
+term_char_t term_char_dup_append(term_char_t base, uint32_t append_ucs4);
+
+const uint32_t *term_char_resolve(term_char_t ch, size_t *s, term_charbuf_t *b);
+unsigned int term_char_lookup_width(term_char_t ch);
+
+/* true if @ch is TERM_CHAR_NULL, otherwise false */
+static inline bool term_char_is_null(term_char_t ch) {
+        return ch._value == 0;
+}
+
+/* true if @ch is dynamically allocated and needs to be freed */
+static inline bool term_char_is_allocated(term_char_t ch) {
+        return !term_char_is_null(ch) && !(ch._value & 0x1);
+}
+
+/* true if (a == b), otherwise false; this is (a == b), NOT (*a == *b) */
+static inline bool term_char_same(term_char_t a, term_char_t b) {
+        return a._value == b._value;
+}
+
+/* true if (*a == *b), otherwise false; this is implied by (a == b) */
+static inline bool term_char_equal(term_char_t a, term_char_t b) {
+        const uint32_t *sa, *sb;
+        term_charbuf_t ca, cb;
+        size_t na, nb;
+
+        sa = term_char_resolve(a, &na, &ca);
+        sb = term_char_resolve(b, &nb, &cb);
+        return na == nb && !memcmp(sa, sb, sizeof(*sa) * na);
+}
+
+/* free @ch in case it is dynamically allocated */
+static inline term_char_t term_char_free(term_char_t ch) {
+        if (term_char_is_allocated(ch))
+                term_char_set(ch, 0);
+
+        return TERM_CHAR_NULL;
+}
+
+/* gcc _cleanup_ helpers */
+#define _term_char_free_ _cleanup_(term_char_freep)
+static inline void term_char_freep(term_char_t *p) {
+        term_char_free(*p);
+}
+
+/*
+ * Attributes
+ * Each cell in a terminal page can have its own set of attributes. These alter
+ * the behavior of the renderer for this single cell. We use term_attr to
+ * specify attributes.
+ * The only non-obvious field is "ccode" for foreground and background colors.
+ * This field contains the terminal color-code in case no full RGB information
+ * was given by the host. It is also required for dynamic color palettes. If it
+ * is set to TERM_CCODE_RGB, the "red", "green" and "blue" fields contain the
+ * full RGB color.
+ */
+
+enum {
+        /* special color-codes */
+        TERM_CCODE_DEFAULT,                                             /* default foreground/background color */
+        TERM_CCODE_256,                                                 /* 256color code */
+        TERM_CCODE_RGB,                                                 /* color is specified as RGB */
+
+        /* dark color-codes */
+        TERM_CCODE_BLACK,
+        TERM_CCODE_RED,
+        TERM_CCODE_GREEN,
+        TERM_CCODE_YELLOW,
+        TERM_CCODE_BLUE,
+        TERM_CCODE_MAGENTA,
+        TERM_CCODE_CYAN,
+        TERM_CCODE_WHITE,                                               /* technically: light grey */
+
+        /* light color-codes */
+        TERM_CCODE_LIGHT_BLACK          = TERM_CCODE_BLACK + 8,         /* technically: dark grey */
+        TERM_CCODE_LIGHT_RED            = TERM_CCODE_RED + 8,
+        TERM_CCODE_LIGHT_GREEN          = TERM_CCODE_GREEN + 8,
+        TERM_CCODE_LIGHT_YELLOW         = TERM_CCODE_YELLOW + 8,
+        TERM_CCODE_LIGHT_BLUE           = TERM_CCODE_BLUE + 8,
+        TERM_CCODE_LIGHT_MAGENTA        = TERM_CCODE_MAGENTA + 8,
+        TERM_CCODE_LIGHT_CYAN           = TERM_CCODE_CYAN + 8,
+        TERM_CCODE_LIGHT_WHITE          = TERM_CCODE_WHITE + 8,
+
+        TERM_CCODE_CNT,
+};
+
+struct term_color {
+        uint8_t ccode;
+        uint8_t c256;
+        uint8_t red;
+        uint8_t green;
+        uint8_t blue;
+};
+
+struct term_attr {
+        term_color fg;                          /* foreground color */
+        term_color bg;                          /* background color */
+
+        unsigned int bold : 1;                  /* bold font */
+        unsigned int italic : 1;                /* italic font */
+        unsigned int underline : 1;             /* underline text */
+        unsigned int inverse : 1;               /* inverse fg/bg */
+        unsigned int protect : 1;               /* protect from erase */
+        unsigned int blink : 1;                 /* blink text */
+        unsigned int hidden : 1;                /* hidden */
+};
+
+/*
+ * Cells
+ * The term_cell structure respresents a single cell in a terminal page. It
+ * contains the stored character, the age of the cell and all its attributes.
+ */
+
+struct term_cell {
+        term_char_t ch;         /* stored char or TERM_CHAR_NULL */
+        term_age_t age;         /* cell age or TERM_AGE_NULL */
+        term_attr attr;         /* cell attributes */
+        unsigned int cwidth;    /* cached term_char_lookup_width(cell->ch) */
+};
+
+/*
+ * Lines
+ * Instead of storing cells in a 2D array, we store them in an array of
+ * dynamically allocated lines. This way, scrolling can be implemented very
+ * fast without moving any cells at all. Similarly, the scrollback-buffer is
+ * much simpler to implement.
+ * We use term_line to store a single line. It contains an array of cells, a
+ * fill-state which remembers the amount of blanks on the right side, a
+ * separate age just for the line which can overwrite the age for all cells,
+ * and some management data.
+ */
+
+struct term_line {
+        term_line *lines_next;          /* linked-list for histories */
+        term_line *lines_prev;          /* linked-list for histories */
+
+        unsigned int width;             /* visible width of line */
+        unsigned int n_cells;           /* # of allocated cells */
+        term_cell *cells;               /* cell-array */
+
+        term_age_t age;                 /* line age */
+        unsigned int fill;              /* # of valid cells; starting left */
+};
+
+int term_line_new(term_line **out);
+term_line *term_line_free(term_line *line);
+
+#define _term_line_free_ _cleanup_(term_line_freep)
+DEFINE_TRIVIAL_CLEANUP_FUNC(term_line*, term_line_free);
+
+int term_line_reserve(term_line *line, unsigned int width, const term_attr *attr, term_age_t age, unsigned int protect_width);
+void term_line_set_width(term_line *line, unsigned int width);
+void term_line_write(term_line *line, unsigned int pos_x, term_char_t ch, unsigned int cwidth, const term_attr *attr, term_age_t age, bool insert_mode);
+void term_line_insert(term_line *line, unsigned int from, unsigned int num, const term_attr *attr, term_age_t age);
+void term_line_delete(term_line *line, unsigned int from, unsigned int num, const term_attr *attr, term_age_t age);
+void term_line_append_combchar(term_line *line, unsigned int pos_x, uint32_t ucs4, term_age_t age);
+void term_line_erase(term_line *line, unsigned int from, unsigned int num, const term_attr *attr, term_age_t age, bool keep_protected);
+void term_line_reset(term_line *line, const term_attr *attr, term_age_t age);
+
+void term_line_link(term_line *line, term_line **first, term_line **last);
+void term_line_link_tail(term_line *line, term_line **first, term_line **last);
+void term_line_unlink(term_line *line, term_line **first, term_line **last);
+
+#define TERM_LINE_LINK(_line, _head) term_line_link((_line), &(_head)->lines_first, &(_head)->lines_last)
+#define TERM_LINE_LINK_TAIL(_line, _head) term_line_link_tail((_line), &(_head)->lines_first, &(_head)->lines_last)
+#define TERM_LINE_UNLINK(_line, _head) term_line_unlink((_line), &(_head)->lines_first, &(_head)->lines_last)
+
+/*
+ * Pages
+ * A page represents the 2D table containing all cells of a terminal. It stores
+ * lines as an array of pointers so scrolling becomes a simple line-shuffle
+ * operation.
+ * Scrolling is always targeted only at the scroll-region defined via scroll_idx
+ * and scroll_num. The fill-state keeps track of the number of touched lines in
+ * the scroll-region. @width and @height describe the visible region of the page
+ * and are guaranteed to be allocated at all times.
+ */
+
+struct term_page {
+        term_age_t age;                 /* page age */
+
+        term_line **lines;              /* array of line-pointers */
+        term_line **line_cache;         /* cache for temporary operations */
+        unsigned int n_lines;           /* # of allocated lines */
+
+        unsigned int width;             /* width of visible area */
+        unsigned int height;            /* height of visible area */
+        unsigned int scroll_idx;        /* scrolling-region start index */
+        unsigned int scroll_num;        /* scrolling-region length in lines */
+        unsigned int scroll_fill;       /* # of valid scroll-lines */
+};
+
+int term_page_new(term_page **out);
+term_page *term_page_free(term_page *page);
+
+#define _term_page_free_ _cleanup_(term_page_freep)
+DEFINE_TRIVIAL_CLEANUP_FUNC(term_page*, term_page_free);
+
+term_cell *term_page_get_cell(term_page *page, unsigned int x, unsigned int y);
+
+int term_page_reserve(term_page *page, unsigned int cols, unsigned int rows, const term_attr *attr, term_age_t age);
+void term_page_resize(term_page *page, unsigned int cols, unsigned int rows, const term_attr *attr, term_age_t age, term_history *history);
+void term_page_write(term_page *page, unsigned int pos_x, unsigned int pos_y, term_char_t ch, unsigned int cwidth, const term_attr *attr, term_age_t age, bool insert_mode);
+void term_page_insert_cells(term_page *page, unsigned int from_x, unsigned int from_y, unsigned int num, const term_attr *attr, term_age_t age);
+void term_page_delete_cells(term_page *page, unsigned int from_x, unsigned int from_y, unsigned int num, const term_attr *attr, term_age_t age);
+void term_page_append_combchar(term_page *page, unsigned int pos_x, unsigned int pos_y, uint32_t ucs4, term_age_t age);
+void term_page_erase(term_page *page, unsigned int from_x, unsigned int from_y, unsigned int to_x, unsigned int to_y, const term_attr *attr, term_age_t age, bool keep_protected);
+void term_page_reset(term_page *page, const term_attr *attr, term_age_t age);
+
+void term_page_set_scroll_region(term_page *page, unsigned int idx, unsigned int num);
+void term_page_scroll_up(term_page *page, unsigned int num, const term_attr *attr, term_age_t age, term_history *history);
+void term_page_scroll_down(term_page *page, unsigned int num, const term_attr *attr, term_age_t age, term_history *history);
+void term_page_insert_lines(term_page *page, unsigned int pos_y, unsigned int num, const term_attr *attr, term_age_t age);
+void term_page_delete_lines(term_page *page, unsigned int pos_y, unsigned int num, const term_attr *attr, term_age_t age);
+
+/*
+ * Histories
+ * Scroll-back buffers use term_history objects to store scroll-back lines. A
+ * page is independent of the history used. All page operations that modify a
+ * history take it as separate argument. You're free to pass NULL at all times
+ * if no history should be used.
+ * Lines are stored in a linked list as no complex operations are ever done on
+ * history lines, besides pushing/poping. Note that history lines do not have a
+ * guaranteed minimum length. Any kind of line might be stored there. Missing
+ * cells should be cleared to the background color.
+ */
+
+struct term_history {
+        term_line *lines_first;
+        term_line *lines_last;
+        unsigned int n_lines;
+        unsigned int max_lines;
+};
+
+int term_history_new(term_history **out);
+term_history *term_history_free(term_history *history);
+
+#define _term_history_free_ _cleanup_(term_history_freep)
+DEFINE_TRIVIAL_CLEANUP_FUNC(term_history*, term_history_free);
+
+void term_history_clear(term_history *history);
+void term_history_trim(term_history *history, unsigned int max);
+void term_history_push(term_history *history, term_line *line);
+term_line *term_history_pop(term_history *history, unsigned int reserve_width, const term_attr *attr, term_age_t age);
+unsigned int term_history_peek(term_history *history, unsigned int max, unsigned int reserve_width, const term_attr *attr, term_age_t age);
+
+/*
+ * UTF-8
+ * The UTF-decoder and encoder are adjusted for terminals and provide proper
+ * fallbacks for invalid UTF-8. In terminals it's quite usual to use fallbacks
+ * instead of rejecting invalid input. This way, old legacy applications still
+ * work (this is especially important for 7bit/ASCII DEC modes).
+ */
+
+struct term_utf8 {
+        uint32_t chars[5];
+        uint32_t ucs4;
+
+        unsigned int i_bytes : 3;
+        unsigned int n_bytes : 3;
+        unsigned int valid : 1;
+};
+
+size_t term_utf8_encode(char *out_utf8, uint32_t g);
+const uint32_t *term_utf8_decode(term_utf8 *p, size_t *out_len, char c);
+
+/*
+ * Parsers
+ * The term_parser object parses control-sequences for both host and terminal
+ * side. Based on this parser, there is a set of command-parsers that take a
+ * term_seq sequence and returns the command it represents. This is different
+ * for host and terminal side so a different set of parsers is provided.
+ */
+
+enum {
+        TERM_SEQ_NONE,                  /* placeholder, no sequence parsed */
+
+        TERM_SEQ_IGNORE,                /* no-op character */
+        TERM_SEQ_GRAPHIC,               /* graphic character */
+        TERM_SEQ_CONTROL,               /* control character */
+        TERM_SEQ_ESCAPE,                /* escape sequence */
+        TERM_SEQ_CSI,                   /* control sequence function */
+        TERM_SEQ_DCS,                   /* device control string */
+        TERM_SEQ_OSC,                   /* operating system control */
+
+        TERM_SEQ_CNT
+};
+
+enum {
+        /* these must be kept compatible to (1U << (ch - 0x20)) */
+
+        TERM_SEQ_FLAG_SPACE             = (1U <<  0),   /* char:   */
+        TERM_SEQ_FLAG_BANG              = (1U <<  1),   /* char: ! */
+        TERM_SEQ_FLAG_DQUOTE            = (1U <<  2),   /* char: " */
+        TERM_SEQ_FLAG_HASH              = (1U <<  3),   /* char: # */
+        TERM_SEQ_FLAG_CASH              = (1U <<  4),   /* char: $ */
+        TERM_SEQ_FLAG_PERCENT           = (1U <<  5),   /* char: % */
+        TERM_SEQ_FLAG_AND               = (1U <<  6),   /* char: & */
+        TERM_SEQ_FLAG_SQUOTE            = (1U <<  7),   /* char: ' */
+        TERM_SEQ_FLAG_POPEN             = (1U <<  8),   /* char: ( */
+        TERM_SEQ_FLAG_PCLOSE            = (1U <<  9),   /* char: ) */
+        TERM_SEQ_FLAG_MULT              = (1U << 10),   /* char: * */
+        TERM_SEQ_FLAG_PLUS              = (1U << 11),   /* char: + */
+        TERM_SEQ_FLAG_COMMA             = (1U << 12),   /* char: , */
+        TERM_SEQ_FLAG_MINUS             = (1U << 13),   /* char: - */
+        TERM_SEQ_FLAG_DOT               = (1U << 14),   /* char: . */
+        TERM_SEQ_FLAG_SLASH             = (1U << 15),   /* char: / */
+
+        /* 16-35 is reserved for numbers; unused */
+
+        /* COLON is reserved            = (1U << 26),      char: : */
+        /* SEMICOLON is reserved        = (1U << 27),      char: ; */
+        TERM_SEQ_FLAG_LT                = (1U << 28),   /* char: < */
+        TERM_SEQ_FLAG_EQUAL             = (1U << 29),   /* char: = */
+        TERM_SEQ_FLAG_GT                = (1U << 30),   /* char: > */
+        TERM_SEQ_FLAG_WHAT              = (1U << 31),   /* char: ? */
+};
+
+enum {
+        TERM_CMD_NONE,                          /* placeholder */
+        TERM_CMD_GRAPHIC,                       /* graphics character */
+
+        TERM_CMD_BEL,                           /* bell */
+        TERM_CMD_BS,                            /* backspace */
+        TERM_CMD_CBT,                           /* cursor-backward-tabulation */
+        TERM_CMD_CHA,                           /* cursor-horizontal-absolute */
+        TERM_CMD_CHT,                           /* cursor-horizontal-forward-tabulation */
+        TERM_CMD_CNL,                           /* cursor-next-line */
+        TERM_CMD_CPL,                           /* cursor-previous-line */
+        TERM_CMD_CR,                            /* carriage-return */
+        TERM_CMD_CUB,                           /* cursor-backward */
+        TERM_CMD_CUD,                           /* cursor-down */
+        TERM_CMD_CUF,                           /* cursor-forward */
+        TERM_CMD_CUP,                           /* cursor-position */
+        TERM_CMD_CUU,                           /* cursor-up */
+        TERM_CMD_DA1,                           /* primary-device-attributes */
+        TERM_CMD_DA2,                           /* secondary-device-attributes */
+        TERM_CMD_DA3,                           /* tertiary-device-attributes */
+        TERM_CMD_DC1,                           /* device-control-1 or XON */
+        TERM_CMD_DC3,                           /* device-control-3 or XOFF */
+        TERM_CMD_DCH,                           /* delete-character */
+        TERM_CMD_DECALN,                        /* screen-alignment-pattern */
+        TERM_CMD_DECANM,                        /* ansi-mode */
+        TERM_CMD_DECBI,                         /* back-index */
+        TERM_CMD_DECCARA,                       /* change-attributes-in-rectangular-area */
+        TERM_CMD_DECCRA,                        /* copy-rectangular-area */
+        TERM_CMD_DECDC,                         /* delete-column */
+        TERM_CMD_DECDHL_BH,                     /* double-width-double-height-line: bottom half */
+        TERM_CMD_DECDHL_TH,                     /* double-width-double-height-line: top half */
+        TERM_CMD_DECDWL,                        /* double-width-single-height-line */
+        TERM_CMD_DECEFR,                        /* enable-filter-rectangle */
+        TERM_CMD_DECELF,                        /* enable-local-functions */
+        TERM_CMD_DECELR,                        /* enable-locator-reporting */
+        TERM_CMD_DECERA,                        /* erase-rectangular-area */
+        TERM_CMD_DECFI,                         /* forward-index */
+        TERM_CMD_DECFRA,                        /* fill-rectangular-area */
+        TERM_CMD_DECIC,                         /* insert-column */
+        TERM_CMD_DECID,                         /* return-terminal-id */
+        TERM_CMD_DECINVM,                       /* invoke-macro */
+        TERM_CMD_DECKBD,                        /* keyboard-language-selection */
+        TERM_CMD_DECKPAM,                       /* keypad-application-mode */
+        TERM_CMD_DECKPNM,                       /* keypad-numeric-mode */
+        TERM_CMD_DECLFKC,                       /* local-function-key-control */
+        TERM_CMD_DECLL,                         /* load-leds */
+        TERM_CMD_DECLTOD,                       /* load-time-of-day */
+        TERM_CMD_DECPCTERM,                     /* pcterm-mode */
+        TERM_CMD_DECPKA,                        /* program-key-action */
+        TERM_CMD_DECPKFMR,                      /* program-key-free-memory-report */
+        TERM_CMD_DECRARA,                       /* reverse-attributes-in-rectangular-area */
+        TERM_CMD_DECRC,                         /* restore-cursor */
+        TERM_CMD_DECREQTPARM,                   /* request-terminal-parameters */
+        TERM_CMD_DECRPKT,                       /* report-key-type */
+        TERM_CMD_DECRQCRA,                      /* request-checksum-of-rectangular-area */
+        TERM_CMD_DECRQDE,                       /* request-display-extent */
+        TERM_CMD_DECRQKT,                       /* request-key-type */
+        TERM_CMD_DECRQLP,                       /* request-locator-position */
+        TERM_CMD_DECRQM_ANSI,                   /* request-mode-ansi */
+        TERM_CMD_DECRQM_DEC,                    /* request-mode-dec */
+        TERM_CMD_DECRQPKFM,                     /* request-program-key-free-memory */
+        TERM_CMD_DECRQPSR,                      /* request-presentation-state-report */
+        TERM_CMD_DECRQTSR,                      /* request-terminal-state-report */
+        TERM_CMD_DECRQUPSS,                     /* request-user-preferred-supplemental-set */
+        TERM_CMD_DECSACE,                       /* select-attribute-change-extent */
+        TERM_CMD_DECSASD,                       /* select-active-status-display */
+        TERM_CMD_DECSC,                         /* save-cursor */
+        TERM_CMD_DECSCA,                        /* select-character-protection-attribute */
+        TERM_CMD_DECSCL,                        /* select-conformance-level */
+        TERM_CMD_DECSCP,                        /* select-communication-port */
+        TERM_CMD_DECSCPP,                       /* select-columns-per-page */
+        TERM_CMD_DECSCS,                        /* select-communication-speed */
+        TERM_CMD_DECSCUSR,                      /* set-cursor-style */
+        TERM_CMD_DECSDDT,                       /* select-disconnect-delay-time */
+        TERM_CMD_DECSDPT,                       /* select-digital-printed-data-type */
+        TERM_CMD_DECSED,                        /* selective-erase-in-display */
+        TERM_CMD_DECSEL,                        /* selective-erase-in-line */
+        TERM_CMD_DECSERA,                       /* selective-erase-rectangular-area */
+        TERM_CMD_DECSFC,                        /* select-flow-control */
+        TERM_CMD_DECSKCV,                       /* set-key-click-volume */
+        TERM_CMD_DECSLCK,                       /* set-lock-key-style */
+        TERM_CMD_DECSLE,                        /* select-locator-events */
+        TERM_CMD_DECSLPP,                       /* set-lines-per-page */
+        TERM_CMD_DECSLRM_OR_SC,                 /* set-left-and-right-margins or save-cursor */
+        TERM_CMD_DECSMBV,                       /* set-margin-bell-volume */
+        TERM_CMD_DECSMKR,                       /* select-modifier-key-reporting */
+        TERM_CMD_DECSNLS,                       /* set-lines-per-screen */
+        TERM_CMD_DECSPP,                        /* set-port-parameter */
+        TERM_CMD_DECSPPCS,                      /* select-pro-printer-character-set */
+        TERM_CMD_DECSPRTT,                      /* select-printer-type */
+        TERM_CMD_DECSR,                         /* secure-reset */
+        TERM_CMD_DECSRFR,                       /* select-refresh-rate */
+        TERM_CMD_DECSSCLS,                      /* set-scroll-speed */
+        TERM_CMD_DECSSDT,                       /* select-status-display-line-type */
+        TERM_CMD_DECSSL,                        /* select-setup-language */
+        TERM_CMD_DECST8C,                       /* set-tab-at-every-8-columns */
+        TERM_CMD_DECSTBM,                       /* set-top-and-bottom-margins */
+        TERM_CMD_DECSTR,                        /* soft-terminal-reset */
+        TERM_CMD_DECSTRL,                       /* set-transmit-rate-limit */
+        TERM_CMD_DECSWBV,                       /* set-warning-bell-volume */
+        TERM_CMD_DECSWL,                        /* single-width-single-height-line */
+        TERM_CMD_DECTID,                        /* select-terminal-id */
+        TERM_CMD_DECTME,                        /* terminal-mode-emulation */
+        TERM_CMD_DECTST,                        /* invoke-confidence-test */
+        TERM_CMD_DL,                            /* delete-line */
+        TERM_CMD_DSR_ANSI,                      /* device-status-report-ansi */
+        TERM_CMD_DSR_DEC,                       /* device-status-report-dec */
+        TERM_CMD_ECH,                           /* erase-character */
+        TERM_CMD_ED,                            /* erase-in-display */
+        TERM_CMD_EL,                            /* erase-in-line */
+        TERM_CMD_ENQ,                           /* enquiry */
+        TERM_CMD_EPA,                           /* end-of-guarded-area */
+        TERM_CMD_FF,                            /* form-feed */
+        TERM_CMD_HPA,                           /* horizontal-position-absolute */
+        TERM_CMD_HPR,                           /* horizontal-position-relative */
+        TERM_CMD_HT,                            /* horizontal-tab */
+        TERM_CMD_HTS,                           /* horizontal-tab-set */
+        TERM_CMD_HVP,                           /* horizontal-and-vertical-position */
+        TERM_CMD_ICH,                           /* insert-character */
+        TERM_CMD_IL,                            /* insert-line */
+        TERM_CMD_IND,                           /* index */
+        TERM_CMD_LF,                            /* line-feed */
+        TERM_CMD_LS1R,                          /* locking-shift-1-right */
+        TERM_CMD_LS2,                           /* locking-shift-2 */
+        TERM_CMD_LS2R,                          /* locking-shift-2-right */
+        TERM_CMD_LS3,                           /* locking-shift-3 */
+        TERM_CMD_LS3R,                          /* locking-shift-3-right */
+        TERM_CMD_MC_ANSI,                       /* media-copy-ansi */
+        TERM_CMD_MC_DEC,                        /* media-copy-dec */
+        TERM_CMD_NEL,                           /* next-line */
+        TERM_CMD_NP,                            /* next-page */
+        TERM_CMD_NULL,                          /* null */
+        TERM_CMD_PP,                            /* preceding-page */
+        TERM_CMD_PPA,                           /* page-position-absolute */
+        TERM_CMD_PPB,                           /* page-position-backward */
+        TERM_CMD_PPR,                           /* page-position-relative */
+        TERM_CMD_RC,                            /* restore-cursor */
+        TERM_CMD_REP,                           /* repeat */
+        TERM_CMD_RI,                            /* reverse-index */
+        TERM_CMD_RIS,                           /* reset-to-initial-state */
+        TERM_CMD_RM_ANSI,                       /* reset-mode-ansi */
+        TERM_CMD_RM_DEC,                        /* reset-mode-dec */
+        TERM_CMD_S7C1T,                         /* set-7bit-c1-terminal */
+        TERM_CMD_S8C1T,                         /* set-8bit-c1-terminal */
+        TERM_CMD_SCS,                           /* select-character-set */
+        TERM_CMD_SD,                            /* scroll-down */
+        TERM_CMD_SGR,                           /* select-graphics-rendition */
+        TERM_CMD_SI,                            /* shift-in */
+        TERM_CMD_SM_ANSI,                       /* set-mode-ansi */
+        TERM_CMD_SM_DEC,                        /* set-mode-dec */
+        TERM_CMD_SO,                            /* shift-out */
+        TERM_CMD_SPA,                           /* start-of-protected-area */
+        TERM_CMD_SS2,                           /* single-shift-2 */
+        TERM_CMD_SS3,                           /* single-shift-3 */
+        TERM_CMD_ST,                            /* string-terminator */
+        TERM_CMD_SU,                            /* scroll-up */
+        TERM_CMD_SUB,                           /* substitute */
+        TERM_CMD_TBC,                           /* tab-clear */
+        TERM_CMD_VPA,                           /* vertical-line-position-absolute */
+        TERM_CMD_VPR,                           /* vertical-line-position-relative */
+        TERM_CMD_VT,                            /* vertical-tab */
+        TERM_CMD_XTERM_CLLHP,                   /* xterm-cursor-lower-left-hp-bugfix */
+        TERM_CMD_XTERM_IHMT,                    /* xterm-initiate-highlight-mouse-tracking*/
+        TERM_CMD_XTERM_MLHP,                    /* xterm-memory-lock-hp-bugfix */
+        TERM_CMD_XTERM_MUHP,                    /* xterm-memory-unlock-hp-bugfix */
+        TERM_CMD_XTERM_RPM,                     /* xterm-restore-private-mode */
+        TERM_CMD_XTERM_RRV,                     /* xterm-reset-resource-value */
+        TERM_CMD_XTERM_RTM,                     /* xterm-reset-title-mode */
+        TERM_CMD_XTERM_SACL1,                   /* xterm-set-ansi-conformance-level-1 */
+        TERM_CMD_XTERM_SACL2,                   /* xterm-set-ansi-conformance-level-2 */
+        TERM_CMD_XTERM_SACL3,                   /* xterm-set-ansi-conformance-level-3 */
+        TERM_CMD_XTERM_SDCS,                    /* xterm-set-default-character-set */
+        TERM_CMD_XTERM_SGFX,                    /* xterm-sixel-graphics */
+        TERM_CMD_XTERM_SPM,                     /* xterm-set-private-mode */
+        TERM_CMD_XTERM_SRV,                     /* xterm-set-resource-value */
+        TERM_CMD_XTERM_STM,                     /* xterm-set-title-mode */
+        TERM_CMD_XTERM_SUCS,                    /* xterm-set-utf8-character-set */
+        TERM_CMD_XTERM_WM,                      /* xterm-window-management */
+
+        TERM_CMD_CNT
+};
+
+enum {
+        /*
+         * Charsets: DEC marks charsets according to "Digital Equ. Corp.".
+         *           NRCS marks charsets according to the "National Replacement
+         *           Character Sets". ISO marks charsets according to ISO-8859.
+         * The USERDEF charset is special and can be modified by the host.
+         */
+
+        TERM_CHARSET_NONE,
+
+        /* 96-compat charsets */
+        TERM_CHARSET_ISO_LATIN1_SUPPLEMENTAL,
+        TERM_CHARSET_BRITISH_NRCS = TERM_CHARSET_ISO_LATIN1_SUPPLEMENTAL,
+        TERM_CHARSET_ISO_LATIN2_SUPPLEMENTAL,
+        TERM_CHARSET_AMERICAN_NRCS = TERM_CHARSET_ISO_LATIN2_SUPPLEMENTAL,
+        TERM_CHARSET_ISO_LATIN5_SUPPLEMENTAL,
+        TERM_CHARSET_ISO_GREEK_SUPPLEMENTAL,
+        TERM_CHARSET_ISO_HEBREW_SUPPLEMENTAL,
+        TERM_CHARSET_ISO_LATIN_CYRILLIC,
+
+        TERM_CHARSET_96_CNT,
+
+        /* 94-compat charsets */
+        TERM_CHARSET_DEC_SPECIAL_GRAPHIC = TERM_CHARSET_96_CNT,
+        TERM_CHARSET_DEC_SUPPLEMENTAL,
+        TERM_CHARSET_DEC_TECHNICAL,
+        TERM_CHARSET_CYRILLIC_DEC,
+        TERM_CHARSET_DUTCH_NRCS,
+        TERM_CHARSET_FINNISH_NRCS,
+        TERM_CHARSET_FRENCH_NRCS,
+        TERM_CHARSET_FRENCH_CANADIAN_NRCS,
+        TERM_CHARSET_GERMAN_NRCS,
+        TERM_CHARSET_GREEK_DEC,
+        TERM_CHARSET_GREEK_NRCS,
+        TERM_CHARSET_HEBREW_DEC,
+        TERM_CHARSET_HEBREW_NRCS,
+        TERM_CHARSET_ITALIAN_NRCS,
+        TERM_CHARSET_NORWEGIAN_DANISH_NRCS,
+        TERM_CHARSET_PORTUGUESE_NRCS,
+        TERM_CHARSET_RUSSIAN_NRCS,
+        TERM_CHARSET_SCS_NRCS,
+        TERM_CHARSET_SPANISH_NRCS,
+        TERM_CHARSET_SWEDISH_NRCS,
+        TERM_CHARSET_SWISS_NRCS,
+        TERM_CHARSET_TURKISH_DEC,
+        TERM_CHARSET_TURKISH_NRCS,
+
+        TERM_CHARSET_94_CNT,
+
+        /* special charsets */
+        TERM_CHARSET_USERPREF_SUPPLEMENTAL = TERM_CHARSET_94_CNT,
+
+        TERM_CHARSET_CNT,
+};
+
+extern term_charset term_unicode_lower;
+extern term_charset term_unicode_upper;
+extern term_charset term_dec_supplemental_graphics;
+extern term_charset term_dec_special_graphics;
+
+#define TERM_PARSER_ARG_MAX (16)
+#define TERM_PARSER_ST_MAX (4096)
+
+struct term_seq {
+        unsigned int type;
+        unsigned int command;
+        uint32_t terminator;
+        unsigned int intermediates;
+        unsigned int charset;
+        unsigned int n_args;
+        int args[TERM_PARSER_ARG_MAX];
+        unsigned int n_st;
+        char *st;
+};
+
+struct term_parser {
+        term_seq seq;
+        size_t st_alloc;
+        unsigned int state;
+
+        bool is_host : 1;
+};
+
+int term_parser_new(term_parser **out, bool host);
+term_parser *term_parser_free(term_parser *parser);
+int term_parser_feed(term_parser *parser, const term_seq **seq_out, uint32_t raw);
+
+#define _term_parser_free_ _cleanup_(term_parser_freep)
+DEFINE_TRIVIAL_CLEANUP_FUNC(term_parser*, term_parser_free);
+
+/*
+ * Screens
+ * A term_screen object represents the terminal-side of the communication. It
+ * connects the term-parser and term-pages and handles all required commands.
+ * All state is managed by it.
+ */
+
+enum {
+        TERM_FLAG_7BIT_MODE                     = (1U << 0),    /* 7bit mode (default: off) */
+        TERM_FLAG_HIDE_CURSOR                   = (1U << 1),    /* hide cursor caret (default: off) */
+        TERM_FLAG_INHIBIT_TPARM                 = (1U << 2),    /* do not send TPARM unrequested (default: off) */
+        TERM_FLAG_NEWLINE_MODE                  = (1U << 3),    /* perform carriage-return on line-feeds (default: off) */
+        TERM_FLAG_ORIGIN_MODE                   = (1U << 4),    /* in origin mode, the cursor is bound by the margins (default: off) */
+        TERM_FLAG_PENDING_WRAP                  = (1U << 5),    /* wrap-around is pending */
+        TERM_FLAG_AUTO_WRAP                     = (1U << 6),    /* auto-wrap mode causes line-wraps at line-ends (default: off) */
+        TERM_FLAG_KEYPAD_MODE                   = (1U << 7),    /* application-keypad mode (default: off) */
+        TERM_FLAG_CURSOR_KEYS                   = (1U << 8),    /* enable application cursor-keys (default: off) */
+};
+
+enum {
+        TERM_CONFORMANCE_LEVEL_VT52,
+        TERM_CONFORMANCE_LEVEL_VT100,
+        TERM_CONFORMANCE_LEVEL_VT400,
+        TERM_CONFORMANCE_LEVEL_CNT,
+};
+
+typedef int (*term_screen_write_fn) (term_screen *screen, void *userdata, const void *buf, size_t size);
+typedef int (*term_screen_cmd_fn) (term_screen *screen, void *userdata, unsigned int cmd, const term_seq *seq);
+
+struct term_screen {
+        unsigned long ref;
+        term_age_t age;
+
+        term_page *page;
+        term_page *page_main;
+        term_page *page_alt;
+        term_history *history;
+        term_history *history_main;
+
+        unsigned int n_tabs;
+        uint8_t *tabs;
+
+        term_utf8 utf8;
+        term_parser *parser;
+
+        term_screen_write_fn write_fn;
+        void *write_fn_data;
+        term_screen_cmd_fn cmd_fn;
+        void *cmd_fn_data;
+
+        unsigned int flags;
+        unsigned int conformance_level;
+        unsigned int cursor_x;
+        unsigned int cursor_y;
+        term_attr attr;
+        term_attr default_attr;
+
+        term_charset **gl;
+        term_charset **gr;
+        term_charset **glt;
+        term_charset **grt;
+        term_charset *g0;
+        term_charset *g1;
+        term_charset *g2;
+        term_charset *g3;
+
+        char *answerback;
+
+        struct {
+                unsigned int cursor_x;
+                unsigned int cursor_y;
+                term_attr attr;
+                term_charset **gl;
+                term_charset **gr;
+                term_charset **glt;
+                term_charset **grt;
+                unsigned int flags;
+        } saved;
+};
+
+int term_screen_new(term_screen **out, term_screen_write_fn write_fn, void *write_fn_data, term_screen_cmd_fn cmd_fn, void *cmd_fn_data);
+term_screen *term_screen_ref(term_screen *screen);
+term_screen *term_screen_unref(term_screen *screen);
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(term_screen*, term_screen_unref);
+
+int term_screen_feed_text(term_screen *screen, const uint8_t *in, size_t size);
+int term_screen_feed_keyboard(term_screen *screen, uint32_t keysym, uint32_t ascii, uint32_t ucs4, unsigned int mods);
+int term_screen_resize(term_screen *screen, unsigned int width, unsigned int height);
+void term_screen_soft_reset(term_screen *screen);
+void term_screen_hard_reset(term_screen *screen);
+
+int term_screen_set_answerback(term_screen *screen, const char *answerback);
diff --git a/src/libsystemd-terminal/term-page.c b/src/libsystemd-terminal/term-page.c
new file mode 100644 (file)
index 0000000..7ae90e2
--- /dev/null
@@ -0,0 +1,2096 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright (C) 2014 David Herrmann <dh.herrmann@gmail.com>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+/*
+ * Terminal Page/Line/Cell/Char Handling
+ * This file implements page handling of a terminal. It is split into pages,
+ * lines, cells and characters. Each object is independent of the next upper
+ * object.
+ *
+ * The Terminal layer keeps each line of a terminal separate and dynamically
+ * allocated. This allows us to move lines from main-screen to history-buffers
+ * very fast. Same is true for scrolling, top/bottom borders and other buffer
+ * operations.
+ *
+ * While lines are dynamically allocated, cells are not. This would be a waste
+ * of memory and causes heavy fragmentation. Furthermore, cells are moved much
+ * less frequently than lines so the performance-penalty is pretty small.
+ * However, to support combining-characters, we have to initialize and cleanup
+ * cells properly and cannot just release the underlying memory. Therefore,
+ * cells are treated as proper objects despite being allocated in arrays.
+ *
+ * Each cell has a set of attributes and a stored character. This is usually a
+ * single Unicode character stored as 32bit UCS-4 char. However, we need to
+ * support Unicode combining-characters, therefore this gets more complicated.
+ * Characters themselves are represented by a "term_char_t" object. It
+ * should be treated as a normal integer and passed by value. The
+ * sorrounding struct is just to hide the internals. A term-char can contain a
+ * base character together with up to 2 combining-chars in a single integer.
+ * Only if you need more combining-chars (very unlikely!) a term-char is a
+ * pointer to an allocated storage. This requires you to always free term-char
+ * objects once no longer used (even though this is a no-op most of the time).
+ * Furthermore, term-char objects are not ref-counted so you must duplicate them
+ * in case you want to store it somewhere and retain a copy yourself. By
+ * convention, all functions that take a term-char object will not duplicate
+ * it but implicitly take ownership of the passed value. It's up to the caller
+ * to duplicate it beforehand, in case it wants to retain a copy.
+ *
+ * If it turns out, that more than 2 comb-chars become common in specific
+ * languages, we can try to optimize this. One idea is to ref-count allocated
+ * characters and store them in a hash-table (like gnome's libvte3 does). This
+ * way we will never have two allocated chars for the same content. Or we can
+ * simply put two uint64_t into a "term_char_t". This will slow down operations
+ * on systems that don't need that many comb-chars, but avoid the dynamic
+ * allocations on others.
+ * Anyhow, until we have proper benchmarks, we will keep the current code. It
+ * seems to compete very well with other solutions so far.
+ *
+ * The page-layer is a one-dimensional array of lines. Considering that each
+ * line is a one-dimensional array of cells, the page layer provides the
+ * two-dimensional cell-page required for terminals. The page itself only
+ * operates on lines. All cell-related operations are forwarded to the correct
+ * line.
+ * A page does not contain any cursor tracking. It only provides the raw
+ * operations to shuffle lines and modify the page.
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include "macro.h"
+#include "term-internal.h"
+#include "util.h"
+
+/* maximum UCS-4 character */
+#define CHAR_UCS4_MAX (0x10ffff)
+/* mask for valid UCS-4 characters (21bit) */
+#define CHAR_UCS4_MASK (0x1fffff)
+/* UCS-4 replacement character */
+#define CHAR_UCS4_REPLACEMENT (0xfffd)
+
+/* real storage behind "term_char_t" in case it's not packed */
+typedef struct term_character {
+        uint8_t n;
+        uint32_t codepoints[];
+} term_character;
+
+/*
+ * char_pack() takes 3 UCS-4 values and packs them into a term_char_t object.
+ * Note that UCS-4 chars only take 21 bits, so we still have the LSB as marker.
+ * We set it to 1 so others can distinguish it from pointers.
+ */
+static inline term_char_t char_pack(uint32_t v1, uint32_t v2, uint32_t v3) {
+        uint64_t packed, u1, u2, u3;
+
+        u1 = v1;
+        u2 = v2;
+        u3 = v3;
+
+        packed = 0x01;
+        packed |= (u1 & (uint64_t)CHAR_UCS4_MASK) << 43;
+        packed |= (u2 & (uint64_t)CHAR_UCS4_MASK) << 22;
+        packed |= (u3 & (uint64_t)CHAR_UCS4_MASK) <<  1;
+
+        return TERM_CHAR_INIT(packed);
+}
+
+#define char_pack1(_v1) char_pack2((_v1), CHAR_UCS4_MAX + 1)
+#define char_pack2(_v1, _v2) char_pack3((_v1), (_v2), CHAR_UCS4_MAX + 1)
+#define char_pack3(_v1, _v2, _v3) char_pack((_v1), (_v2), (_v3))
+
+/*
+ * char_unpack() is the inverse of char_pack(). It extracts the 3 stored UCS-4
+ * characters and returns them. Note that this does not validate the passed
+ * term_char_t. That's the responsibility of the caller.
+ * This returns the number of characters actually packed. This obviously is a
+ * number between 0 and 3 (inclusive).
+ */
+static inline uint8_t char_unpack(term_char_t packed, uint32_t *out_v1, uint32_t *out_v2, uint32_t *out_v3) {
+        uint32_t v1, v2, v3;
+
+        v1 = (packed._value >> 43) & (uint64_t)CHAR_UCS4_MASK;
+        v2 = (packed._value >> 22) & (uint64_t)CHAR_UCS4_MASK;
+        v3 = (packed._value >>  1) & (uint64_t)CHAR_UCS4_MASK;
+
+        if (out_v1)
+                *out_v1 = v1;
+        if (out_v2)
+                *out_v2 = v2;
+        if (out_v3)
+                *out_v3 = v3;
+
+        return (v1 > CHAR_UCS4_MAX) ? 0 :
+              ((v2 > CHAR_UCS4_MAX) ? 1 :
+              ((v3 > CHAR_UCS4_MAX) ? 2 :
+                                      3));
+}
+
+/* cast a term_char_t to a term_character* */
+static inline term_character *char_to_ptr(term_char_t ch) {
+        return (term_character*)(unsigned long)ch._value;
+}
+
+/* cast a term_character* to a term_char_t */
+static inline term_char_t char_from_ptr(term_character *c) {
+        return TERM_CHAR_INIT((unsigned long)c);
+}
+
+/*
+ * char_alloc() allocates a properly aligned term_character object and returns
+ * a pointer to it. NULL is returned on allocation errors. The object will have
+ * enough room for @n following UCS-4 chars.
+ * Note that we allocate (n+1) characters and set the last one to 0 in case
+ * anyone prints this string for debugging.
+ */
+static term_character *char_alloc(uint8_t n) {
+        term_character *c;
+        int r;
+
+        r = posix_memalign((void**)&c,
+                           MAX(sizeof(void*), (size_t)2),
+                           sizeof(*c) + sizeof(*c->codepoints) * (n + 1));
+        if (r)
+                return NULL;
+
+        c->n = n;
+        c->codepoints[n] = 0;
+
+        return c;
+}
+
+/*
+ * char_free() frees the memory allocated via char_alloc(). It is safe to call
+ * this on any term_char_t, only allocated characters are freed.
+ */
+static inline void char_free(term_char_t ch) {
+        if (term_char_is_allocated(ch))
+                free(char_to_ptr(ch));
+}
+
+/*
+ * This appends @append_ucs4 to the existing character @base and returns
+ * it as a new character. In case that's not possible, @base is returned. The
+ * caller can use term_char_same() to test whether the returned character was
+ * freshly allocated or not.
+ */
+static term_char_t char_build(term_char_t base, uint32_t append_ucs4) {
+        /* soft-limit for combining-chars; hard-limit is currently 255 */
+        const size_t climit = 64;
+        term_character *c;
+        uint32_t buf[3], *t;
+        uint8_t n;
+
+        /* ignore invalid UCS-4 */
+        if (append_ucs4 > CHAR_UCS4_MAX)
+                return base;
+
+        if (term_char_is_null(base)) {
+                return char_pack1(append_ucs4);
+        } else if (!term_char_is_allocated(base)) {
+                /* unpack and try extending the packed character */
+                n = char_unpack(base, &buf[0], &buf[1], &buf[2]);
+
+                switch (n) {
+                case 0:
+                        return char_pack1(append_ucs4);
+                case 1:
+                        if (climit < 2)
+                                return base;
+
+                        return char_pack2(buf[0], append_ucs4);
+                case 2:
+                        if (climit < 3)
+                                return base;
+
+                        return char_pack3(buf[0], buf[1], append_ucs4);
+                default:
+                        /* fallthrough */
+                        break;
+                }
+
+                /* already fully packed, we need to allocate a new one */
+                t = buf;
+        } else {
+                /* already an allocated type, we need to allocate a new one */
+                c = char_to_ptr(base);
+                t = c->codepoints;
+                n = c->n;
+        }
+
+        /* bail out if soft-limit is reached */
+        if (n >= climit)
+                return base;
+
+        /* allocate new char */
+        c = char_alloc(n + 1);
+        if (!c)
+                return base;
+
+        memcpy(c->codepoints, t, sizeof(*t) * n);
+        c->codepoints[n] = append_ucs4;
+
+        return char_from_ptr(c);
+}
+
+/**
+ * term_char_set() - Reset character to a single UCS-4 character
+ * @previous: term-char to reset
+ * @append_ucs4: UCS-4 char to set
+ *
+ * This frees all resources in @previous and re-initializes it to @append_ucs4.
+ * The new char is returned.
+ *
+ * Usually, this is used like this:
+ *   obj->ch = term_char_set(obj->ch, ucs4);
+ *
+ * Returns: The previous character reset to @append_ucs4.
+ */
+term_char_t term_char_set(term_char_t previous, uint32_t append_ucs4) {
+        char_free(previous);
+        return char_build(TERM_CHAR_NULL, append_ucs4);
+}
+
+/**
+ * term_char_merge() - Merge UCS-4 char at the end of an existing char
+ * @base: existing term-char
+ * @append_ucs4: UCS-4 character to append
+ *
+ * This appends @append_ucs4 to @base and returns the result. @base is
+ * invalidated by this function and must no longer be used. The returned value
+ * replaces the old one.
+ *
+ * Usually, this is used like this:
+ *   obj->ch = term_char_merge(obj->ch, ucs4);
+ *
+ * Returns: The new merged character.
+ */
+term_char_t term_char_merge(term_char_t base, uint32_t append_ucs4) {
+        term_char_t ch;
+
+        ch = char_build(base, append_ucs4);
+        if (!term_char_same(ch, base))
+                term_char_free(base);
+
+        return ch;
+}
+
+/**
+ * term_char_dup() - Duplicate character
+ * @ch: character to duplicate
+ *
+ * This duplicates a term-character. In case the character is not allocated,
+ * nothing is done. Otherwise, the underlying memory is copied and returned. You
+ * need to call term_char_free() on the returned character to release it again.
+ * On allocation errors, a replacement character is returned. Therefore, the
+ * caller can safely assume that this function always succeeds.
+ *
+ * Returns: The duplicated term-character.
+ */
+term_char_t term_char_dup(term_char_t ch) {
+        term_character *c, *newc;
+
+        if (!term_char_is_allocated(ch))
+                return ch;
+
+        c = char_to_ptr(ch);
+        newc = char_alloc(c->n);
+        if (!newc)
+                return char_pack1(CHAR_UCS4_REPLACEMENT);
+
+        memcpy(newc->codepoints, c->codepoints, sizeof(*c->codepoints) * c->n);
+        return char_from_ptr(newc);
+}
+
+/**
+ * term_char_dup_append() - Duplicate tsm-char with UCS-4 character appended
+ * @base: existing term-char
+ * @append_ucs4: UCS-4 character to append
+ *
+ * This is similar to term_char_merge(), but it returns a separately allocated
+ * character. That is, @base will stay valid after this returns and is not
+ * touched. In case the append-operation fails, @base is duplicated and
+ * returned. That is, the returned char is always independent of @base.
+ *
+ * Returns: Newly allocated character with @append_ucs4 appended to @base.
+ */
+term_char_t term_char_dup_append(term_char_t base, uint32_t append_ucs4) {
+        term_char_t ch;
+
+        ch = char_build(base, append_ucs4);
+        if (term_char_same(ch, base))
+                ch = term_char_dup(base);
+
+        return ch;
+}
+
+/**
+ * term_char_resolve() - Retrieve the UCS-4 string for a term-char
+ * @ch: character to resolve
+ * @s: storage for size of string or NULL
+ * @b: storage for string or NULL
+ *
+ * This takes a term-character and returns the UCS-4 string associated with it.
+ * In case @ch is not allocated, the string is stored in @b (in case @b is NULL
+ * static storage is used). Otherwise, a pointer to the allocated storage is
+ * returned.
+ *
+ * The returned string is only valid as long as @ch and @b are valid. The string
+ * is zero-terminated and can safely be printed via long-character printf().
+ * The length of the string excluding the zero-character is returned in @s.
+ *
+ * This never returns NULL. Even if the size is 0, this points to a buffer of at
+ * least a zero-terminator.
+ *
+ * Returns: The UCS-4 string-representation of @ch, and its size in @s.
+ */
+const uint32_t *term_char_resolve(term_char_t ch, size_t *s, term_charbuf_t *b) {
+        static term_charbuf_t static_b;
+        term_character *c;
+        uint32_t *cache;
+        size_t len;
+
+        if (b)
+                cache = b->buf;
+        else
+                cache = static_b.buf;
+
+        if (term_char_is_null(ch)) {
+                len = 0;
+                cache[0] = 0;
+        } else if (term_char_is_allocated(ch)) {
+                c = char_to_ptr(ch);
+                len = c->n;
+                cache = c->codepoints;
+        } else {
+                len = char_unpack(ch, &cache[0], &cache[1], &cache[2]);
+                cache[len] = 0;
+        }
+
+        if (s)
+                *s = len;
+
+        return cache;
+}
+
+/**
+ * term_char_lookup_width() - Lookup cell-width of a character
+ * @ch: character to return cell-width for
+ *
+ * This is an equivalent of wcwidth() for term_char_t. It can deal directly
+ * with UCS-4 and combining-characters and avoids the mess that is wchar_t and
+ * locale handling.
+ *
+ * Returns: 0 for unprintable characters, >0 for everything else.
+ */
+unsigned int term_char_lookup_width(term_char_t ch) {
+        term_charbuf_t b;
+        const uint32_t *str;
+        unsigned int max;
+        size_t i, len;
+        int r;
+
+        max = 0;
+        str = term_char_resolve(ch, &len, &b);
+
+        for (i = 0; i < len; ++i) {
+                /*
+                 * Oh god, C99 locale handling strikes again: wcwidth() expects
+                 * wchar_t, but there is no way for us to know the
+                 * internal encoding of wchar_t. Moreover, it is nearly
+                 * impossible to convert UCS-4 into wchar_t (except for iconv,
+                 * which is way too much overhead).
+                 * Therefore, we use our own copy of wcwidth(). Lets just hope
+                 * that glibc will one day export it's internal UCS-4 and UTF-8
+                 * helpers for direct use.
+                 */
+                assert_cc(sizeof(wchar_t) >= 4);
+                r = mk_wcwidth((wchar_t)str[i]);
+                if (r > 0 && (unsigned int)r > max)
+                        max = r;
+        }
+
+        return max;
+}
+
+/**
+ * term_cell_init() - Initialize a new cell
+ * @cell: cell to initialize
+ * @ch: character to set on the cell or TERM_CHAR_NULL
+ * @cwidth: character width of @ch
+ * @attr: attributes to set on the cell or NULL
+ * @age: age to set on the cell or TERM_AGE_NULL
+ *
+ * This initializes a new cell. The backing-memory of the cell must be allocated
+ * by the caller beforehand. The caller is responsible to destroy the cell via
+ * term_cell_destroy() before freeing the backing-memory.
+ *
+ * It is safe (and supported!) to use:
+ *   zero(*c);
+ * instead of:
+ *   term_cell_init(c, TERM_CHAR_NULL, NULL, TERM_AGE_NULL);
+ *
+ * Note that this call takes ownership of @ch. If you want to use it yourself
+ * after this call, you need to duplicate it before calling this.
+ */
+static void term_cell_init(term_cell *cell, term_char_t ch, unsigned int cwidth, const term_attr *attr, term_age_t age) {
+        assert(cell);
+
+        cell->ch = ch;
+        cell->cwidth = cwidth;
+        cell->age = age;
+
+        if (attr)
+                memcpy(&cell->attr, attr, sizeof(*attr));
+        else
+                zero(cell->attr);
+}
+
+/**
+ * term_cell_destroy() - Destroy previously initialized cell
+ * @cell: cell to destroy or NULL
+ *
+ * This releases all resources associated with a cell. The backing memory is
+ * kept as-is. It's the responsibility of the caller to manage it.
+ *
+ * You must not call any other cell operations on this cell after this call
+ * returns. You must re-initialize the cell via term_cell_init() before you can
+ * use it again.
+ *
+ * If @cell is NULL, this is a no-op.
+ */
+static void term_cell_destroy(term_cell *cell) {
+        if (!cell)
+                return;
+
+        term_char_free(cell->ch);
+}
+
+/**
+ * term_cell_set() - Change contents of a cell
+ * @cell: cell to modify
+ * @ch: character to set on the cell or cell->ch
+ * @cwidth: character width of @ch or cell->cwidth
+ * @attr: attributes to set on the cell or NULL
+ * @age: age to set on the cell or cell->age
+ *
+ * This changes the contents of a cell. It can be used to change the character,
+ * attributes and age. To keep the current character, pass cell->ch as @ch. To
+ * reset the current attributes, pass NULL. To keep the current age, pass
+ * cell->age.
+ *
+ * This call takes ownership of @ch. You need to duplicate it first, in case you
+ * want to use it for your own purposes after this call.
+ *
+ * The cell must have been initialized properly before calling this. See
+ * term_cell_init().
+ */
+static void term_cell_set(term_cell *cell, term_char_t ch, unsigned int cwidth, const term_attr *attr, term_age_t age) {
+        assert(cell);
+
+        if (!term_char_same(ch, cell->ch)) {
+                term_char_free(cell->ch);
+                cell->ch = ch;
+        }
+
+        cell->cwidth = cwidth;
+        cell->age = age;
+
+        if (attr)
+                memcpy(&cell->attr, attr, sizeof(*attr));
+        else
+                zero(cell->attr);
+}
+
+/**
+ * term_cell_append() - Append a combining-char to a cell
+ * @cell: cell to modify
+ * @ucs4: UCS-4 character to append to the cell
+ * @age: new age to set on the cell or cell->age
+ *
+ * This appends a combining-character to a cell. No validation of the UCS-4
+ * character is done, so this can be used to append any character. Additionally,
+ * this can update the age of the cell.
+ *
+ * The cell must have been initialized properly before calling this. See
+ * term_cell_init().
+ */
+static void term_cell_append(term_cell *cell, uint32_t ucs4, term_age_t age) {
+        assert(cell);
+
+        cell->ch = term_char_merge(cell->ch, ucs4);
+        cell->age = age;
+}
+
+/**
+ * term_cell_init_n() - Initialize an array of cells
+ * @cells: pointer to an array of cells to initialize
+ * @n: number of cells
+ * @attr: attributes to set on all cells or NULL
+ * @age: age to set on all cells
+ *
+ * This is the same as term_cell_init() but initializes an array of cells.
+ * Furthermore, this always sets the character to TERM_CHAR_NULL.
+ * If you want to set a specific characters on all cells, you need to hard-code
+ * this loop and duplicate the character for each cell.
+ */
+static void term_cell_init_n(term_cell *cells, unsigned int n, const term_attr *attr, term_age_t age) {
+        for ( ; n > 0; --n, ++cells)
+                term_cell_init(cells, TERM_CHAR_NULL, 0, attr, age);
+}
+
+/**
+ * term_cell_destroy_n() - Destroy an array of cells
+ * @cells: pointer to an array of cells to destroy
+ * @n: number of cells
+ *
+ * This is the same as term_cell_destroy() but destroys an array of cells.
+ */
+static void term_cell_destroy_n(term_cell *cells, unsigned int n) {
+        for ( ; n > 0; --n, ++cells)
+                term_cell_destroy(cells);
+}
+
+/**
+ * term_cell_clear_n() - Clear contents of an array of cells
+ * @cells: pointer to an array of cells to modify
+ * @n: number of cells
+ * @attr: attributes to set on all cells or NULL
+ * @age: age to set on all cells
+ *
+ * This is the same as term_cell_set() but operates on an array of cells. Note
+ * that all characters are always set to TERM_CHAR_NULL, unlike term_cell_set()
+ * which takes the character as argument.
+ * If you want to set a specific characters on all cells, you need to hard-code
+ * this loop and duplicate the character for each cell.
+ */
+static void term_cell_clear_n(term_cell *cells, unsigned int n, const term_attr *attr, term_age_t age) {
+        for ( ; n > 0; --n, ++cells)
+                term_cell_set(cells, TERM_CHAR_NULL, 0, attr, age);
+}
+
+/**
+ * term_line_new() - Allocate a new line
+ * @out: place to store pointer to new line
+ *
+ * This allocates and initialized a new line. The line is unlinked and
+ * independent of any page. It can be used for any purpose. The initial
+ * cell-count is set to 0.
+ *
+ * The line has to be freed via term_line_free() once it's no longer needed.
+ *
+ * Returns: 0 on success, negative error code on failure.
+ */
+int term_line_new(term_line **out) {
+        _term_line_free_ term_line *line = NULL;
+
+        assert_return(out, -EINVAL);
+
+        line = new0(term_line, 1);
+        if (!line)
+                return -ENOMEM;
+
+        *out = line;
+        line = NULL;
+        return 0;
+}
+
+/**
+ * term_line_free() - Free a line
+ * @line: line to free or NULL
+ *
+ * This frees a line that was previously allocated via term_line_free(). All its
+ * cells are released, too.
+ *
+ * If @line is NULL, this is a no-op.
+ */
+term_line *term_line_free(term_line *line) {
+        if (!line)
+                return NULL;
+
+        term_cell_destroy_n(line->cells, line->n_cells);
+        free(line->cells);
+        free(line);
+
+        return NULL;
+}
+
+/**
+ * term_line_reserve() - Pre-allocate cells for a line
+ * @line: line to pre-allocate cells for
+ * @width: numbers of cells the line shall have pre-allocated
+ * @attr: attribute for all allocated cells or NULL
+ * @age: current age for all modifications
+ * @protect_width: width to protect from erasure
+ *
+ * This pre-allocates cells for this line. Please note that @width is the number
+ * of cells the line is guaranteed to have allocated after this call returns.
+ * It's not the number of cells that are added, neither is it the new width of
+ * the line.
+ *
+ * This function never frees memory. That is, reducing the line-width will
+ * always succeed, same is true for increasing the width to a previously set
+ * width.
+ *
+ * @attr and @age are used to initialize new cells. Additionally, any
+ * existing cell outside of the protected area specified by @protect_width are
+ * cleared and reset with @attr and @age.
+ *
+ * Returns: 0 on success, negative error code on failure.
+ */
+int term_line_reserve(term_line *line, unsigned int width, const term_attr *attr, term_age_t age, unsigned int protect_width) {
+        unsigned int min_width;
+        term_cell *t;
+
+        assert_return(line, -EINVAL);
+
+        /* reset existing cells if required */
+        min_width = MIN(line->n_cells, width);
+        if (min_width > protect_width)
+                term_cell_clear_n(line->cells + protect_width,
+                                  min_width - protect_width,
+                                  attr,
+                                  age);
+
+        /* allocate new cells if required */
+
+        if (width > line->n_cells) {
+                t = realloc_multiply(line->cells, sizeof(*t), width);
+                if (!t)
+                        return -ENOMEM;
+
+                if (!attr && !age)
+                        memzero(t + line->n_cells,
+                                sizeof(*t) * (width - line->n_cells));
+                else
+                        term_cell_init_n(t + line->n_cells,
+                                         width - line->n_cells,
+                                         attr,
+                                         age);
+
+                line->cells = t;
+                line->n_cells = width;
+        }
+
+        line->fill = MIN(line->fill, protect_width);
+
+        return 0;
+}
+
+/**
+ * term_line_set_width() - Change width of a line
+ * @line: line to modify
+ * @width: new width
+ *
+ * This changes the actual width of a line. It is the caller's responsibility
+ * to use term_line_reserve() to make sure enough space is allocated. If @width
+ * is greater than the allocated size, it is cropped.
+ *
+ * This does not modify any cells. Use term_line_reserve() or term_line_erase()
+ * to clear any newly added cells.
+ *
+ * NOTE: The fill state is cropped at line->width. Therefore, if you increase
+ *       the line-width afterwards, but there is a multi-cell character at the
+ *       end of the line that got cropped, then the fill-state will _not_ be
+ *       adjusted.
+ *       This means, the fill-state always includes the cells up to the start
+ *       of the right-most character, but it might or might not cover it until
+ *       its end. This should be totally fine, though. You should never access
+ *       multi-cell tails directly, anyway.
+ */
+void term_line_set_width(term_line *line, unsigned int width) {
+        assert(line);
+
+        if (width > line->n_cells)
+                width = line->n_cells;
+
+        line->width = width;
+        line->fill = MIN(line->fill, width);
+}
+
+/**
+ * line_insert() - Insert characters and move existing cells to the right
+ * @from: position to insert cells at
+ * @num: number of cells to insert
+ * @head_char: character that is set on the first cell
+ * @head_cwidth: character-length of @head_char
+ * @attr: attribute for all inserted cells or NULL
+ * @age: current age for all modifications
+ *
+ * The INSERT operation (or writes with INSERT_MODE) writes data at a specific
+ * position on a line and shifts the existing cells to the right. Cells that are
+ * moved beyond the right hand border are discarded.
+ *
+ * This helper contains the actual INSERT implementation which is independent of
+ * the data written. It works on cells, not on characters. The first cell is set
+ * to @head_char, all others are reset to TERM_CHAR_NULL. See each caller for a
+ * more detailed description.
+ */
+static inline void line_insert(term_line *line, unsigned int from, unsigned int num, term_char_t head_char, unsigned int head_cwidth, const term_attr *attr, term_age_t age) {
+        unsigned int i, rem, move;
+
+        if (from >= line->width)
+                return;
+        if (from + num < from || from + num > line->width)
+                num = line->width - from;
+        if (!num)
+                return;
+
+        move = line->width - from - num;
+        rem = MIN(num, move);
+
+        if (rem > 0) {
+                /*
+                 * Make room for @num cells; shift cells to the right if
+                 * required. @rem is the number of remaining cells that we will
+                 * knock off on the right and overwrite during the right shift.
+                 *
+                 * For INSERT_MODE, @num/@rem are usually 1 or 2, @move is 50%
+                 * of the line on average. Therefore, the actual move is quite
+                 * heavy and we can safely invalidate cells manually instead of
+                 * the whole line.
+                 * However, for INSERT operations, any parameters are
+                 * possible. But we cannot place any assumption on its usage
+                 * across applications, so we just handle it the same as
+                 * INSERT_MODE and do per-cell invalidation.
+                 */
+
+                /* destroy cells that are knocked off on the right */
+                term_cell_destroy_n(line->cells + line->width - rem, rem);
+
+                /* move remaining bulk of cells */
+                memmove(line->cells + from + num,
+                        line->cells + from,
+                        sizeof(*line->cells) * move);
+
+                /* invalidate cells */
+                for (i = 0; i < move; ++i)
+                        line->cells[from + num + i].age = age;
+
+                /* initialize fresh head-cell */
+                term_cell_init(line->cells + from,
+                               head_char,
+                               head_cwidth,
+                               attr,
+                               age);
+
+                /* initialize fresh tail-cells */
+                term_cell_init_n(line->cells + from + 1,
+                                 num - 1,
+                                 attr,
+                                 age);
+
+                /* adjust fill-state */
+                DISABLE_WARNING_SHADOW;
+                line->fill = MIN(line->width,
+                                 MAX(line->fill + num,
+                                     from + num));
+                REENABLE_WARNING;
+        } else {
+                /* modify head-cell */
+                term_cell_set(line->cells + from,
+                              head_char,
+                              head_cwidth,
+                              attr,
+                              age);
+
+                /* reset tail-cells */
+                term_cell_clear_n(line->cells + from + 1,
+                                  num - 1,
+                                  attr,
+                                  age);
+
+                /* adjust fill-state */
+                line->fill = line->width;
+        }
+}
+
+/**
+ * term_line_write() - Write to a single, specific cell
+ * @line: line to write to
+ * @pos_x: x-position of cell in @line to write to
+ * @ch: character to write to the cell
+ * @cwidth: character width of @ch
+ * @attr: attributes to set on the cell or NULL
+ * @age: current age for all modifications
+ * @insert_mode: true if INSERT-MODE is enabled
+ *
+ * This writes to a specific cell in a line. The cell is addressed by its
+ * X-position @pos_x. If that cell does not exist, this is a no-op.
+ *
+ * @ch and @attr are set on this cell.
+ *
+ * If @insert_mode is true, this inserts the character instead of overwriting
+ * existing data (existing data is now moved to the right before writing).
+ *
+ * This function is the low-level handler of normal writes to a terminal.
+ */
+void term_line_write(term_line *line, unsigned int pos_x, term_char_t ch, unsigned int cwidth, const term_attr *attr, term_age_t age, bool insert_mode) {
+        unsigned int len;
+
+        assert(line);
+
+        if (pos_x >= line->width)
+                return;
+
+        len = MAX(1U, cwidth);
+        if (pos_x + len < pos_x || pos_x + len > line->width)
+                len = line->width - pos_x;
+        if (!len)
+                return;
+
+        if (insert_mode) {
+                /* Use line_insert() to insert the character-head and fill
+                 * the remains with NULLs. */
+                line_insert(line, pos_x, len, ch, cwidth, attr, age);
+        } else {
+                /* modify head-cell */
+                term_cell_set(line->cells + pos_x, ch, cwidth, attr, age);
+
+                /* reset tail-cells */
+                term_cell_clear_n(line->cells + pos_x + 1,
+                                  len - 1,
+                                  attr,
+                                  age);
+
+                /* adjust fill-state */
+                DISABLE_WARNING_SHADOW;
+                line->fill = MIN(line->width,
+                                 MAX(line->fill,
+                                     pos_x + len));
+                REENABLE_WARNING;
+        }
+}
+
+/**
+ * term_line_insert() - Insert empty cells
+ * @line: line to insert empty cells into
+ * @from: x-position where to insert cells
+ * @num: number of cells to insert
+ * @attr: attributes to set on the cells or NULL
+ * @age: current age for all modifications
+ *
+ * This inserts @num empty cells at position @from in line @line. All existing
+ * cells to the right are shifted to make room for the new cells. Cells that get
+ * pushed beyond the right hand border are discarded.
+ */
+void term_line_insert(term_line *line, unsigned int from, unsigned int num, const term_attr *attr, term_age_t age) {
+        /* use line_insert() to insert @num empty cells */
+        return line_insert(line, from, num, TERM_CHAR_NULL, 0, attr, age);
+}
+
+/**
+ * term_line_delete() - Delete cells from line
+ * @line: line to delete cells from
+ * @from: position to delete cells at
+ * @num: number of cells to delete
+ * @attr: attributes to set on any new cells
+ * @age: current age for all modifications
+ *
+ * Delete cells from a line. All cells to the right of the deleted cells are
+ * shifted to the left to fill the empty space. New cells appearing on the right
+ * hand border are cleared and initialized with @attr.
+ */
+void term_line_delete(term_line *line, unsigned int from, unsigned int num, const term_attr *attr, term_age_t age) {
+        unsigned int rem, move, i;
+
+        assert(line);
+
+        if (from >= line->width)
+                return;
+        if (from + num < from || from + num > line->width)
+                num = line->width - from;
+        if (!num)
+                return;
+
+        /* destroy and move as many upfront as possible */
+        move = line->width - from - num;
+        rem = MIN(num, move);
+        if (rem > 0) {
+                /* destroy to be removed cells */
+                term_cell_destroy_n(line->cells + from, rem);
+
+                /* move tail upfront */
+                memmove(line->cells + from,
+                        line->cells + from + num,
+                        sizeof(*line->cells) * move);
+
+                /* invalidate copied cells */
+                for (i = 0; i < move; ++i)
+                        line->cells[from + i].age = age;
+
+                /* initialize tail that was moved away */
+                term_cell_init_n(line->cells + line->width - rem,
+                                 rem,
+                                 attr,
+                                 age);
+
+                /* reset remaining cells in case the move was too small */
+                if (num > move)
+                        term_cell_clear_n(line->cells + from + move,
+                                          num - move,
+                                          attr,
+                                          age);
+        } else {
+                /* reset cells */
+                term_cell_clear_n(line->cells + from,
+                                  num,
+                                  attr,
+                                  age);
+        }
+
+        /* adjust fill-state */
+        if (from + num < line->fill)
+                line->fill -= num;
+        else if (from < line->fill)
+                line->fill = from;
+}
+
+/**
+ * term_line_append_combchar() - Append combining char to existing cell
+ * @line: line to modify
+ * @pos_x: position of cell to append combining char to
+ * @ucs4: combining character to append
+ * @age: current age for all modifications
+ *
+ * Unicode allows trailing combining characters, which belong to the
+ * char in front of them. The caller is responsible of detecting
+ * combining characters and calling term_line_append_combchar() instead of
+ * term_line_write(). This simply appends the char to the correct cell then.
+ * If the cell is not in the visible area, this call is skipped.
+ *
+ * Note that control-sequences are not 100% compatible with combining
+ * characters as they require delayed parsing. However, we must handle
+ * control-sequences immediately. Therefore, there might be trailing
+ * combining chars that should be discarded by the parser.
+ * However, to prevent programming errors, we're also being pedantic
+ * here and discard weirdly placed combining chars. This prevents
+ * situations were invalid content is parsed into the terminal and you
+ * might end up with cells containing only combining chars.
+ *
+ * Long story short: To get combining-characters working with old-fashioned
+ * terminal-emulation, we parse them exclusively for direct cell-writes. Other
+ * combining-characters are usually simply discarded and ignored.
+ */
+void term_line_append_combchar(term_line *line, unsigned int pos_x, uint32_t ucs4, term_age_t age) {
+        assert(line);
+
+        if (pos_x >= line->width)
+                return;
+
+        /* Unused cell? Skip appending any combining chars then. */
+        if (term_char_is_null(line->cells[pos_x].ch))
+                return;
+
+        term_cell_append(line->cells + pos_x, ucs4, age);
+}
+
+/**
+ * term_line_erase() - Erase parts of a line
+ * @line: line to modify
+ * @from: position to start the erase
+ * @num: number of cells to erase
+ * @attr: attributes to initialize erased cells with
+ * @age: current age for all modifications
+ * @keep_protected: true if protected cells should be kept
+ *
+ * This is the standard erase operation. It clears all cells in the targetted
+ * area and re-initializes them. Cells to the right are not shifted left, you
+ * must use DELETE to achieve that. Cells outside the visible area are skipped.
+ *
+ * If @keep_protected is true, protected cells will not be erased.
+ */
+void term_line_erase(term_line *line, unsigned int from, unsigned int num, const term_attr *attr, term_age_t age, bool keep_protected) {
+        term_cell *cell;
+        unsigned int i, last_protected;
+
+        assert(line);
+
+        if (from >= line->width)
+                return;
+        if (from + num < from || from + num > line->width)
+                num = line->width - from;
+        if (!num)
+                return;
+
+        last_protected = 0;
+        for (i = 0; i < num; ++i) {
+                cell = line->cells + from + i;
+                if (keep_protected && cell->attr.protect) {
+                        /* only count protected-cells inside the fill-region */
+                        if (from + i < line->fill)
+                                last_protected = from + i;
+
+                        continue;
+                }
+
+                term_cell_set(cell, TERM_CHAR_NULL, 0, attr, age);
+        }
+
+        /* Adjust fill-state. This is a bit tricks, we can only adjust it in
+         * case the erase-region starts inside the fill-region and ends at the
+         * tail or beyond the fill-region. Otherwise, the current fill-state
+         * stays as it was.
+         * Furthermore, we must account for protected cells. The loop above
+         * ensures that protected-cells are only accounted for if they're
+         * inside the fill-region. */
+        if (from < line->fill && from + num >= line->fill)
+                line->fill = MAX(from, last_protected);
+}
+
+/**
+ * term_line_reset() - Reset a line
+ * @line: line to reset
+ * @attr: attributes to initialize all cells with
+ * @age: current age for all modifications
+ *
+ * This resets all visible cells of a line and sets their attributes and ages
+ * to @attr and @age. This is equivalent to erasing a whole line via
+ * term_line_erase().
+ */
+void term_line_reset(term_line *line, const term_attr *attr, term_age_t age) {
+        assert(line);
+
+        return term_line_erase(line, 0, line->width, attr, age, 0);
+}
+
+/**
+ * term_line_link() - Link line in front of a list
+ * @line: line to link
+ * @first: member pointing to first entry
+ * @last: member pointing to last entry
+ *
+ * This links a line into a list of lines. The line is inserted at the front and
+ * must not be linked, yet. See the TERM_LINE_LINK() macro for an easier usage of
+ * this.
+ */
+void term_line_link(term_line *line, term_line **first, term_line **last) {
+        assert(line);
+        assert(first);
+        assert(last);
+        assert(!line->lines_prev);
+        assert(!line->lines_next);
+
+        line->lines_prev = NULL;
+        line->lines_next = *first;
+        if (*first)
+                (*first)->lines_prev = line;
+        else
+                *last = line;
+        *first = line;
+}
+
+/**
+ * term_line_link_tail() - Link line at tail of a list
+ * @line: line to link
+ * @first: member pointing to first entry
+ * @last: member pointing to last entry
+ *
+ * Same as term_line_link() but links the line at the tail.
+ */
+void term_line_link_tail(term_line *line, term_line **first, term_line **last) {
+        assert(line);
+        assert(first);
+        assert(last);
+        assert(!line->lines_prev);
+        assert(!line->lines_next);
+
+        line->lines_next = NULL;
+        line->lines_prev = *last;
+        if (*last)
+                (*last)->lines_next = line;
+        else
+                *first = line;
+        *last = line;
+}
+
+/**
+ * term_line_unlink() - Unlink line from a list
+ * @line: line to unlink
+ * @first: member pointing to first entry
+ * @last: member pointing to last entry
+ *
+ * This unlinks a previously linked line. See TERM_LINE_UNLINK() for an easier to
+ * use macro.
+ */
+void term_line_unlink(term_line *line, term_line **first, term_line **last) {
+        assert(line);
+        assert(first);
+        assert(last);
+
+        if (line->lines_prev)
+                line->lines_prev->lines_next = line->lines_next;
+        else
+                *first = line->lines_next;
+        if (line->lines_next)
+                line->lines_next->lines_prev = line->lines_prev;
+        else
+                *last = line->lines_prev;
+
+        line->lines_prev = NULL;
+        line->lines_next = NULL;
+}
+
+/**
+ * term_page_new() - Allocate new page
+ * @out: storage for pointer to new page
+ *
+ * Allocate a new page. The initial dimensions are 0/0.
+ *
+ * Returns: 0 on success, negative error code on failure.
+ */
+int term_page_new(term_page **out) {
+        _term_page_free_ term_page *page = NULL;
+
+        assert_return(out, -EINVAL);
+
+        page = new0(term_page, 1);
+        if (!page)
+                return -ENOMEM;
+
+        *out = page;
+        page = NULL;
+        return 0;
+}
+
+/**
+ * term_page_free() - Free page
+ * @page: page to free or NULL
+ *
+ * Free a previously allocated page and all associated data. If @page is NULL,
+ * this is a no-op.
+ *
+ * Returns: NULL
+ */
+term_page *term_page_free(term_page *page) {
+        unsigned int i;
+
+        if (!page)
+                return NULL;
+
+        for (i = 0; i < page->n_lines; ++i)
+                term_line_free(page->lines[i]);
+
+        free(page->line_cache);
+        free(page->lines);
+        free(page);
+
+        return NULL;
+}
+
+/**
+ * term_page_get_cell() - Return pointer to requested cell
+ * @page: page to operate on
+ * @x: x-position of cell
+ * @y: y-position of cell
+ *
+ * This returns a pointer to the cell at position @x/@y. You're free to modify
+ * this cell as much as you like. However, once you call any other function on
+ * the page, you must drop the pointer to the cell.
+ *
+ * Returns: Pointer to the cell or NULL if out of the visible area.
+ */
+term_cell *term_page_get_cell(term_page *page, unsigned int x, unsigned int y) {
+        assert_return(page, NULL);
+
+        if (x >= page->width)
+                return NULL;
+        if (y >= page->height)
+                return NULL;
+
+        return &page->lines[y]->cells[x];
+}
+
+/**
+ * page_scroll_up() - Scroll up
+ * @page: page to operate on
+ * @new_width: width to use for any new line moved into the visible area
+ * @num: number of lines to scroll up
+ * @attr: attributes to set on new lines
+ * @age: age to use for all modifications
+ * @history: history to use for old lines or NULL
+ *
+ * This scrolls the scroll-region by @num lines. New lines are cleared and reset
+ * with the given attributes. Old lines are moved into the history if non-NULL.
+ * If a new line is allocated, moved from the history buffer or moved from
+ * outside the visible region into the visible region, this call makes sure it
+ * has at least @width cells allocated. If a possible memory-allocation fails,
+ * the previous line is reused. This has the side effect, that it will not be
+ * linked into the history buffer.
+ *
+ * If the scroll-region is empty, this is a no-op.
+ */
+static void page_scroll_up(term_page *page, unsigned int new_width, unsigned int num, const term_attr *attr, term_age_t age, term_history *history) {
+        term_line *line, **cache;
+        unsigned int i;
+        int r;
+
+        assert(page);
+
+        if (num > page->scroll_num)
+                num = page->scroll_num;
+        if (num < 1)
+                return;
+
+        /* Better safe than sorry: avoid under-allocating lines, even when
+         * resizing. */
+        new_width = MAX(new_width, page->width);
+
+        cache = page->line_cache;
+
+        /* Try moving lines into history and allocate new lines for each moved
+         * line. In case allocation fails, or if we have no history, reuse the
+         * line.
+         * We keep the lines in the line-cache so we can safely move the
+         * remaining lines around. */
+        for (i = 0; i < num; ++i) {
+                line = page->lines[page->scroll_idx + i];
+
+                r = -EAGAIN;
+                if (history) {
+                        r = term_line_new(&cache[i]);
+                        if (r >= 0) {
+                                r = term_line_reserve(cache[i],
+                                                      new_width,
+                                                      attr,
+                                                      age,
+                                                      0);
+                                if (r < 0)
+                                        term_line_free(cache[i]);
+                                else
+                                        term_line_set_width(cache[i], page->width);
+                        }
+                }
+
+                if (r >= 0) {
+                        term_history_push(history, line);
+                } else {
+                        cache[i] = line;
+                        term_line_reset(line, attr, age);
+                }
+        }
+
+        if (num < page->scroll_num) {
+                memmove(page->lines + page->scroll_idx,
+                        page->lines + page->scroll_idx + num,
+                        sizeof(*page->lines) * (page->scroll_num - num));
+
+                /* update age of moved lines */
+                for (i = 0; i < page->scroll_num - num; ++i)
+                        page->lines[page->scroll_idx + i]->age = age;
+        }
+
+        /* copy remaining lines from cache; age is already updated */
+        memcpy(page->lines + page->scroll_idx + page->scroll_num - num,
+               cache,
+               sizeof(*cache) * num);
+
+        /* update fill */
+        page->scroll_fill -= MIN(page->scroll_fill, num);
+}
+
+/**
+ * page_scroll_down() - Scroll down
+ * @page: page to operate on
+ * @new_width: width to use for any new line moved into the visible area
+ * @num: number of lines to scroll down
+ * @attr: attributes to set on new lines
+ * @age: age to use for all modifications
+ * @history: history to use for new lines or NULL
+ *
+ * This scrolls the scroll-region by @num lines. New lines are retrieved from
+ * the history or cleared if the history is empty or NULL.
+ *
+ * Usually, scroll-down implies that new lines are cleared. Therefore, you're
+ * highly encouraged to set @history to NULL. However, if you resize a terminal,
+ * you might want to include history-lines in the new area. In that case, you
+ * should set @history to non-NULL.
+ *
+ * If a new line is allocated, moved from the history buffer or moved from
+ * outside the visible region into the visible region, this call makes sure it
+ * has at least @width cells allocated. If a possible memory-allocation fails,
+ * the previous line is reused. This will have the side-effect that lines from
+ * the history will not get visible on-screen but kept in history.
+ *
+ * If the scroll-region is empty, this is a no-op.
+ */
+static void page_scroll_down(term_page *page, unsigned int new_width, unsigned int num, const term_attr *attr, term_age_t age, term_history *history) {
+        term_line *line, **cache, *t;
+        unsigned int i, last_idx;
+
+        assert(page);
+
+        if (num > page->scroll_num)
+                num = page->scroll_num;
+        if (num < 1)
+                return;
+
+        /* Better safe than sorry: avoid under-allocating lines, even when
+         * resizing. */
+        new_width = MAX(new_width, page->width);
+
+        cache = page->line_cache;
+        last_idx = page->scroll_idx + page->scroll_num - 1;
+
+        /* Try pulling out lines from history; if history is empty or if no
+         * history is given, we reuse the to-be-removed lines. Otherwise, those
+         * lines are released. */
+        for (i = 0; i < num; ++i) {
+                line = page->lines[last_idx - i];
+
+                t = NULL;
+                if (history)
+                        t = term_history_pop(history, new_width, attr, age);
+
+                if (t) {
+                        cache[num - 1 - i] = t;
+                        term_line_free(line);
+                } else {
+                        cache[num - 1 - i] = line;
+                        term_line_reset(line, attr, age);
+                }
+        }
+
+        if (num < page->scroll_num) {
+                memmove(page->lines + page->scroll_idx + num,
+                        page->lines + page->scroll_idx,
+                        sizeof(*page->lines) * (page->scroll_num - num));
+
+                /* update age of moved lines */
+                for (i = 0; i < page->scroll_num - num; ++i)
+                        page->lines[page->scroll_idx + num + i]->age = age;
+        }
+
+        /* copy remaining lines from cache; age is already updated */
+        memcpy(page->lines + page->scroll_idx,
+               cache,
+               sizeof(*cache) * num);
+
+        /* update fill; but only if there's already content in it */
+        if (page->scroll_fill > 0)
+                page->scroll_fill = MIN(page->scroll_num,
+                                        page->scroll_fill + num);
+}
+
+/**
+ * page_reserve() - Reserve page area
+ * @page: page to modify
+ * @cols: required columns (width)
+ * @rows: required rows (height)
+ * @attr: attributes for newly allocated cells
+ * @age: age to set on any modified cells
+ *
+ * This allocates the required amount of lines and cells to guarantee that the
+ * page has at least the demanded dimensions of @cols x @rows. Note that this
+ * never shrinks the page-memory. We keep cells allocated for performance
+ * reasons.
+ *
+ * Additionally to allocating lines, this also clears any newly added cells so
+ * you can safely change the size afterwards without clearing new cells.
+ *
+ * Note that you must be careful what operations you call on the page between
+ * page_reserve() and updating page->width/height. Any newly allocated line (or
+ * shifted line) might not meet your new width/height expectations.
+ *
+ * Returns: 0 on success, negative error code on failure.
+ */
+int term_page_reserve(term_page *page, unsigned int cols, unsigned int rows, const term_attr *attr, term_age_t age) {
+        _term_line_free_ term_line *line = NULL;
+        unsigned int i, min_lines;
+        term_line **t;
+        int r;
+
+        assert_return(page, -EINVAL);
+
+        /*
+         * First make sure the first MIN(page->n_lines, rows) lines have at
+         * least the required width of @cols. This does not modify any visible
+         * cells in the existing @page->width x @page->height area, therefore,
+         * we can safely bail out afterwards in case anything else fails.
+         * Note that lines in between page->height and page->n_lines might be
+         * shorter than page->width. Hence, we need to resize them all, but we
+         * can skip some of them for better performance.
+         */
+        min_lines = MIN(page->n_lines, rows);
+        for (i = 0; i < min_lines; ++i) {
+                /* lines below page->height have at least page->width cells */
+                if (cols < page->width && i < page->height)
+                        continue;
+
+                r = term_line_reserve(page->lines[i],
+                                      cols,
+                                      attr,
+                                      age,
+                                      (i < page->height) ? page->width : 0);
+                if (r < 0)
+                        return r;
+        }
+
+        /*
+         * We now know the first @min_lines lines have at least width @cols and
+         * are prepared for resizing. We now only have to allocate any
+         * additional lines below @min_lines in case @rows is greater than
+         * page->n_lines.
+         */
+        if (rows > page->n_lines) {
+                t = realloc_multiply(page->lines, sizeof(*t), rows);
+                if (!t)
+                        return -ENOMEM;
+                page->lines = t;
+
+                t = realloc_multiply(page->line_cache, sizeof(*t), rows);
+                if (!t)
+                        return -ENOMEM;
+                page->line_cache = t;
+
+                while (page->n_lines < rows) {
+                        r = term_line_new(&line);
+                        if (r < 0)
+                                return r;
+
+                        r = term_line_reserve(line, cols, attr, age, 0);
+                        if (r < 0)
+                                return r;
+
+                        page->lines[page->n_lines++] = line;
+                        line = NULL;
+                }
+        }
+
+        return 0;
+}
+
+/**
+ * term_page_resize() - Resize page
+ * @page: page to modify
+ * @cols: number of columns (width)
+ * @rows: number of rows (height)
+ * @attr: attributes for newly allocated cells
+ * @age: age to set on any modified cells
+ * @history: history buffer to use for new/old lines or NULL
+ *
+ * This changes the visible dimensions of a page. You must have called
+ * term_page_reserve() beforehand, otherwise, this will fail.
+ *
+ * Returns: 0 on success, negative error code on failure.
+ */
+void term_page_resize(term_page *page, unsigned int cols, unsigned int rows, const term_attr *attr, term_age_t age, term_history *history) {
+        unsigned int i, num, empty, max, old_height;
+        term_line *line;
+
+        assert(page);
+        assert(page->n_lines >= rows);
+
+        old_height = page->height;
+
+        if (rows < old_height) {
+                /*
+                 * If we decrease the terminal-height, we emulate a scroll-up.
+                 * This way, existing data from the scroll-area is moved into
+                 * the history, making space at the bottom to reduce the screen
+                 * height. In case the scroll-fill indicates empty lines, we
+                 * reduce the amount of scrolled lines.
+                 * Once scrolled, we have to move the lower margin from below
+                 * the scroll area up so it is preserved.
+                 */
+
+                /* move lines to history if scroll region is filled */
+                num = old_height - rows;
+                empty = page->scroll_num - page->scroll_fill;
+                if (num > empty)
+                        page_scroll_up(page,
+                                       cols,
+                                       num - empty,
+                                       attr,
+                                       age,
+                                       history);
+
+                /* move lower margin up; drop its lines if not enough space */
+                num = LESS_BY(old_height, page->scroll_idx + page->scroll_num);
+                max = LESS_BY(rows, page->scroll_idx);
+                num = MIN(num, max);
+                if (num > 0) {
+                        unsigned int top, bottom;
+
+                        top = rows - num;
+                        bottom = page->scroll_idx + page->scroll_num;
+
+                        /* might overlap; must run topdown, not bottomup */
+                        for (i = 0; i < num; ++i) {
+                                line = page->lines[top + i];
+                                page->lines[top + i] = page->lines[bottom + i];
+                                page->lines[bottom + i] = line;
+                        }
+                }
+
+                /* update vertical extents */
+                page->height = rows;
+                page->scroll_idx = MIN(page->scroll_idx, rows);
+                page->scroll_num -= MIN(page->scroll_num, old_height - rows);
+                /* fill is already up-to-date or 0 due to scroll-up */
+        } else if (rows > old_height) {
+                /*
+                 * If we increase the terminal-height, we emulate a scroll-down
+                 * and fetch new lines from the history.
+                 * New lines are always accounted to the scroll-region. Thus we
+                 * have to preserve the lower margin first, by moving it down.
+                 */
+
+                /* move lower margin down */
+                num = LESS_BY(old_height, page->scroll_idx + page->scroll_num);
+                if (num > 0) {
+                        unsigned int top, bottom;
+
+                        top = page->scroll_idx + page->scroll_num;
+                        bottom = top + (rows - old_height);
+
+                        /* might overlap; must run bottomup, not topdown */
+                        for (i = num; i-- > 0; ) {
+                                line = page->lines[top + i];
+                                page->lines[top + i] = page->lines[bottom + i];
+                                page->lines[bottom + i] = line;
+                        }
+                }
+
+                /* update vertical extents */
+                page->height = rows;
+                page->scroll_num = MIN(LESS_BY(rows, page->scroll_idx),
+                                       page->scroll_num + (rows - old_height));
+
+                /* check how many lines can be received from history */
+                if (history)
+                        num = term_history_peek(history,
+                                                rows - old_height,
+                                                cols,
+                                                attr,
+                                                age);
+                else
+                        num = 0;
+
+                /* retrieve new lines from history if available */
+                if (num > 0)
+                        page_scroll_down(page,
+                                         cols,
+                                         num,
+                                         attr,
+                                         age,
+                                         history);
+        }
+
+        /* set horizontal extents */
+        page->width = cols;
+        for (i = 0; i < page->height; ++i)
+                term_line_set_width(page->lines[i], cols);
+}
+
+/**
+ * term_page_write() - Write to a single cell
+ * @page: page to operate on
+ * @pos_x: x-position of cell to write to
+ * @pos_y: y-position of cell to write to
+ * @ch: character to write
+ * @cwidth: character-width of @ch
+ * @attr: attributes to set on the cell or NULL
+ * @age: age to use for all modifications
+ * @insert_mode: true if INSERT-MODE is enabled
+ *
+ * This writes a character to a specific cell. If the cell is beyond bounds,
+ * this is a no-op. @attr and @age are used to update the cell. @flags can be
+ * used to alter the behavior of this function.
+ *
+ * This is a wrapper around term_line_write().
+ *
+ * This call does not wrap around lines. That is, this only operates on a single
+ * line.
+ */
+void term_page_write(term_page *page, unsigned int pos_x, unsigned int pos_y, term_char_t ch, unsigned int cwidth, const term_attr *attr, term_age_t age, bool insert_mode) {
+        assert(page);
+
+        if (pos_y >= page->height)
+                return;
+
+        term_line_write(page->lines[pos_y], pos_x, ch, cwidth, attr, age, insert_mode);
+}
+
+/**
+ * term_page_insert_cells() - Insert cells into a line
+ * @page: page to operate on
+ * @from_x: x-position where to insert new cells
+ * @from_y: y-position where to insert new cells
+ * @num: number of cells to insert
+ * @attr: attributes to set on new cells or NULL
+ * @age: age to use for all modifications
+ *
+ * This inserts new cells into a given line. This is a wrapper around
+ * term_line_insert().
+ *
+ * This call does not wrap around lines. That is, this only operates on a single
+ * line.
+ */
+void term_page_insert_cells(term_page *page, unsigned int from_x, unsigned int from_y, unsigned int num, const term_attr *attr, term_age_t age) {
+        assert(page);
+
+        if (from_y >= page->height)
+                return;
+
+        term_line_insert(page->lines[from_y], from_x, num, attr, age);
+}
+
+/**
+ * term_page_delete_cells() - Delete cells from a line
+ * @page: page to operate on
+ * @from_x: x-position where to delete cells
+ * @from_y: y-position where to delete cells
+ * @num: number of cells to delete
+ * @attr: attributes to set on new cells or NULL
+ * @age: age to use for all modifications
+ *
+ * This deletes cells from a given line. This is a wrapper around
+ * term_line_delete().
+ *
+ * This call does not wrap around lines. That is, this only operates on a single
+ * line.
+ */
+void term_page_delete_cells(term_page *page, unsigned int from_x, unsigned int from_y, unsigned int num, const term_attr *attr, term_age_t age) {
+        assert(page);
+
+        if (from_y >= page->height)
+                return;
+
+        term_line_delete(page->lines[from_y], from_x, num, attr, age);
+}
+
+/**
+ * term_page_append_combchar() - Append combining-character to a cell
+ * @page: page to operate on
+ * @pos_x: x-position of target cell
+ * @pos_y: y-position of target cell
+ * @ucs4: combining character to append
+ * @age: age to use for all modifications
+ *
+ * This appends a combining-character to a specific cell. This is a wrapper
+ * around term_line_append_combchar().
+ */
+void term_page_append_combchar(term_page *page, unsigned int pos_x, unsigned int pos_y, uint32_t ucs4, term_age_t age) {
+        assert(page);
+
+        if (pos_y >= page->height)
+                return;
+
+        term_line_append_combchar(page->lines[pos_y], pos_x, ucs4, age);
+}
+
+/**
+ * term_page_erase() - Erase parts of a page
+ * @page: page to operate on
+ * @from_x: x-position where to start erasure (inclusive)
+ * @from_y: y-position where to start erasure (inclusive)
+ * @to_x: x-position where to stop erasure (inclusive)
+ * @to_y: y-position where to stop erasure (inclusive)
+ * @attr: attributes to set on cells
+ * @age: age to use for all modifications
+ * @keep_protected: true if protected cells should be kept
+ *
+ * This erases all cells starting at @from_x/@from_y up to @to_x/@to_y. Note
+ * that this wraps around line-boundaries so lines between @from_y and @to_y
+ * are cleared entirely.
+ *
+ * Lines outside the visible area are left untouched.
+ */
+void term_page_erase(term_page *page, unsigned int from_x, unsigned int from_y, unsigned int to_x, unsigned int to_y, const term_attr *attr, term_age_t age, bool keep_protected) {
+        unsigned int i, from, to;
+
+        assert(page);
+
+        for (i = from_y; i <= to_y && i < page->height; ++i) {
+                from = 0;
+                to = page->width;
+
+                if (i == from_y)
+                        from = from_x;
+                if (i == to_y)
+                        to = to_x;
+
+                term_line_erase(page->lines[i],
+                                from,
+                                LESS_BY(to, from),
+                                attr,
+                                age,
+                                keep_protected);
+        }
+}
+
+/**
+ * term_page_reset() - Reset page
+ * @page: page to modify
+ * @attr: attributes to set on cells
+ * @age: age to use for all modifications
+ *
+ * This erases the whole visible page. See term_page_erase().
+ */
+void term_page_reset(term_page *page, const term_attr *attr, term_age_t age) {
+        assert(page);
+
+        return term_page_erase(page,
+                               0, 0,
+                               page->width - 1, page->height - 1,
+                               attr,
+                               age,
+                               0);
+}
+
+/**
+ * term_page_set_scroll_region() - Set scroll region
+ * @page: page to operate on
+ * @idx: start-index of scroll region
+ * @num: number of lines in scroll region
+ *
+ * This sets the scroll region of a page. Whenever an operation needs to scroll
+ * lines, it scrolls them inside of that region. Lines outside the region are
+ * left untouched. In case a scroll-operation is targeted outside of this
+ * region, it will implicitly get a scroll-region of only one line (i.e., no
+ * scroll region at all).
+ *
+ * Note that the scroll-region is clipped to the current page-extents. Growing
+ * or shrinking the page always accounts new/old lines to the scroll region and
+ * moves top/bottom margins accordingly so they're preserved.
+ */
+void term_page_set_scroll_region(term_page *page, unsigned int idx, unsigned int num) {
+        assert(page);
+
+        if (page->height < 1) {
+                page->scroll_idx = 0;
+                page->scroll_num = 0;
+        } else {
+                page->scroll_idx = MIN(idx, page->height - 1);
+                page->scroll_num = MIN(num, page->height - page->scroll_idx);
+        }
+}
+
+/**
+ * term_page_scroll_up() - Scroll up
+ * @page: page to operate on
+ * @num: number of lines to scroll up
+ * @attr: attributes to set on new lines
+ * @age: age to use for all modifications
+ * @history: history to use for old lines or NULL
+ *
+ * This scrolls the scroll-region by @num lines. New lines are cleared and reset
+ * with the given attributes. Old lines are moved into the history if non-NULL.
+ *
+ * If the scroll-region is empty, this is a no-op.
+ */
+void term_page_scroll_up(term_page *page, unsigned int num, const term_attr *attr, term_age_t age, term_history *history) {
+        page_scroll_up(page, page->width, num, attr, age, history);
+}
+
+/**
+ * term_page_scroll_down() - Scroll down
+ * @page: page to operate on
+ * @num: number of lines to scroll down
+ * @attr: attributes to set on new lines
+ * @age: age to use for all modifications
+ * @history: history to use for new lines or NULL
+ *
+ * This scrolls the scroll-region by @num lines. New lines are retrieved from
+ * the history or cleared if the history is empty or NULL.
+ *
+ * Usually, scroll-down implies that new lines are cleared. Therefore, you're
+ * highly encouraged to set @history to NULL. However, if you resize a terminal,
+ * you might want to include history-lines in the new area. In that case, you
+ * should set @history to non-NULL.
+ *
+ * If the scroll-region is empty, this is a no-op.
+ */
+void term_page_scroll_down(term_page *page, unsigned int num, const term_attr *attr, term_age_t age, term_history *history) {
+        page_scroll_down(page, page->width, num, attr, age, history);
+}
+
+/**
+ * term_page_insert_lines() - Insert new lines
+ * @page: page to operate on
+ * @pos_y: y-position where to insert new lines
+ * @num: number of lines to insert
+ * @attr: attributes to set on new lines
+ * @age: age to use for all modifications
+ *
+ * This inserts @num new lines at position @pos_y. If @pos_y is beyond
+ * boundaries or @num is 0, this is a no-op.
+ * All lines below @pos_y are moved down to make space for the new lines. Lines
+ * on the bottom are dropped. Note that this only moves lines above or inside
+ * the scroll-region. If @pos_y is below the scroll-region, a scroll-region of
+ * one line is implied (which means the line is simply cleared).
+ */
+void term_page_insert_lines(term_page *page, unsigned int pos_y, unsigned int num, const term_attr *attr, term_age_t age) {
+        unsigned int scroll_idx, scroll_num;
+
+        assert(page);
+
+        if (pos_y >= page->height)
+                return;
+        if (num >= page->height)
+                num = page->height;
+
+        /* remember scroll-region */
+        scroll_idx = page->scroll_idx;
+        scroll_num = page->scroll_num;
+
+        /* set scroll-region temporarily so we can reuse scroll_down() */
+        {
+                page->scroll_idx = pos_y;
+                if (pos_y >= scroll_idx + scroll_num)
+                        page->scroll_num = 1;
+                else if (pos_y >= scroll_idx)
+                        page->scroll_num -= pos_y - scroll_idx;
+                else
+                        page->scroll_num += scroll_idx - pos_y;
+
+                term_page_scroll_down(page, num, attr, age, NULL);
+        }
+
+        /* reset scroll-region */
+        page->scroll_idx = scroll_idx;
+        page->scroll_num = scroll_num;
+}
+
+/**
+ * term_page_delete_lines() - Delete lines
+ * @page: page to operate on
+ * @pos_y: y-position where to delete lines
+ * @num: number of lines to delete
+ * @attr: attributes to set on new lines
+ * @age: age to use for all modifications
+ *
+ * This deletes @num lines at position @pos_y. If @pos_y is beyond boundaries or
+ * @num is 0, this is a no-op.
+ * All lines below @pos_y are moved up into the newly made space. New lines
+ * on the bottom are clear. Note that this only moves lines above or inside
+ * the scroll-region. If @pos_y is below the scroll-region, a scroll-region of
+ * one line is implied (which means the line is simply cleared).
+ */
+void term_page_delete_lines(term_page *page, unsigned int pos_y, unsigned int num, const term_attr *attr, term_age_t age) {
+        unsigned int scroll_idx, scroll_num;
+
+        assert(page);
+
+        if (pos_y >= page->height)
+                return;
+        if (num >= page->height)
+                num = page->height;
+
+        /* remember scroll-region */
+        scroll_idx = page->scroll_idx;
+        scroll_num = page->scroll_num;
+
+        /* set scroll-region temporarily so we can reuse scroll_up() */
+        {
+                page->scroll_idx = pos_y;
+                if (pos_y >= scroll_idx + scroll_num)
+                        page->scroll_num = 1;
+                else if (pos_y > scroll_idx)
+                        page->scroll_num -= pos_y - scroll_idx;
+                else
+                        page->scroll_num += scroll_idx - pos_y;
+
+                term_page_scroll_up(page, num, attr, age, NULL);
+        }
+
+        /* reset scroll-region */
+        page->scroll_idx = scroll_idx;
+        page->scroll_num = scroll_num;
+}
+
+/**
+ * term_history_new() - Create new history object
+ * @out: storage for pointer to new history
+ *
+ * Create a new history object. Histories are used to store scrollback-lines
+ * from VTE pages. You're highly recommended to set a history-limit on
+ * history->max_lines and trim it via term_history_trim(), otherwise history
+ * allocations are unlimited.
+ *
+ * Returns: 0 on success, negative error code on failure.
+ */
+int term_history_new(term_history **out) {
+        _term_history_free_ term_history *history = NULL;
+
+        assert_return(out, -EINVAL);
+
+        history = new0(term_history, 1);
+        if (!history)
+                return -ENOMEM;
+
+        history->max_lines = 4096;
+
+        *out = history;
+        history = NULL;
+        return 0;
+}
+
+/**
+ * term_history_free() - Free history
+ * @history: history to free
+ *
+ * Clear and free history. You must not access the object afterwards.
+ *
+ * Returns: NULL
+ */
+term_history *term_history_free(term_history *history) {
+        if (!history)
+                return NULL;
+
+        term_history_clear(history);
+        free(history);
+        return NULL;
+}
+
+/**
+ * term_history_clear() - Clear history
+ * @history: history to clear
+ *
+ * Remove all linked lines from a history and reset it to its initial state.
+ */
+void term_history_clear(term_history *history) {
+        return term_history_trim(history, 0);
+}
+
+/**
+ * term_history_trim() - Trim history
+ * @history: history to trim
+ * @max: maximum number of lines to be left in history
+ *
+ * This removes lines from the history until it is smaller than @max. Lines are
+ * removed from the top.
+ */
+void term_history_trim(term_history *history, unsigned int max) {
+        term_line *line;
+
+        if (!history)
+                return;
+
+        while (history->n_lines > max && (line = history->lines_first)) {
+                TERM_LINE_UNLINK(line, history);
+                term_line_free(line);
+                --history->n_lines;
+        }
+}
+
+/**
+ * term_history_push() - Push line into history
+ * @history: history to work on
+ * @line: line to push into history
+ *
+ * This pushes a line into the given history. It is linked at the tail. In case
+ * the history is limited, the top-most line might be freed.
+ */
+void term_history_push(term_history *history, term_line *line) {
+        assert(history);
+        assert(line);
+
+        TERM_LINE_LINK_TAIL(line, history);
+        if (history->max_lines > 0 && history->n_lines >= history->max_lines) {
+                line = history->lines_first;
+                TERM_LINE_UNLINK(line, history);
+                term_line_free(line);
+        } else {
+                ++history->n_lines;
+        }
+}
+
+/**
+ * term_history_pop() - Retrieve last line from history
+ * @history: history to work on
+ * @new_width: width to reserve and set on the line
+ * @attr: attributes to use for cell reservation
+ * @age: age to use for cell reservation
+ *
+ * This unlinks the last linked line of the history and returns it. This also
+ * makes sure the line has the given width pre-allocated (see
+ * term_line_reserve()). If the pre-allocation fails, this returns NULL, so it
+ * is treated like there's no line in history left. This simplifies
+ * history-handling on the caller's side in case of allocation errors. No need
+ * to throw lines away just because the reservation failed. We can keep them in
+ * history safely, and make them available as scrollback.
+ *
+ * Returns: Line from history or NULL
+ */
+term_line *term_history_pop(term_history *history, unsigned int new_width, const term_attr *attr, term_age_t age) {
+        term_line *line;
+        int r;
+
+        assert_return(history, NULL);
+
+        line = history->lines_last;
+        if (!line)
+                return NULL;
+
+        r = term_line_reserve(line, new_width, attr, age, line->width);
+        if (r < 0)
+                return NULL;
+
+        term_line_set_width(line, new_width);
+        TERM_LINE_UNLINK(line, history);
+        --history->n_lines;
+
+        return line;
+}
+
+/**
+ * term_history_peek() - Return number of available history-lines
+ * @history: history to work on
+ * @max: maximum number of lines to look at
+ * @reserve_width: width to reserve on the line
+ * @attr: attributes to use for cell reservation
+ * @age: age to use for cell reservation
+ *
+ * This returns the number of available lines in the history given as @history.
+ * It returns at most @max. For each line that is looked at, the line is
+ * verified to have at least @reserve_width cells. Valid cells are preserved,
+ * new cells are initialized with @attr and @age. In case an allocation fails,
+ * we bail out and return the number of lines that are valid so far.
+ *
+ * Usually, this function should be used before running a loop on
+ * term_history_pop(). This function guarantees that term_history_pop() (with
+ * the same arguments) will succeed at least the returned number of times.
+ *
+ * Returns: Number of valid lines that can be received via term_history_pop().
+ */
+unsigned int term_history_peek(term_history *history, unsigned int max, unsigned int reserve_width, const term_attr *attr, term_age_t age) {
+        unsigned int num;
+        term_line *line;
+        int r;
+
+        assert(history);
+
+        num = 0;
+        line = history->lines_last;
+
+        while (num < max && line) {
+                r = term_line_reserve(line, reserve_width, attr, age, line->width);
+                if (r < 0)
+                        break;
+
+                ++num;
+                line = line->lines_prev;
+        }
+
+        return num;
+}
diff --git a/src/libsystemd-terminal/term-parser.c b/src/libsystemd-terminal/term-parser.c
new file mode 100644 (file)
index 0000000..c8c1d13
--- /dev/null
@@ -0,0 +1,1627 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright (C) 2014 David Herrmann <dh.herrmann@gmail.com>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+/*
+ * Terminal Parser
+ * This file contains a bunch of UTF-8 helpers and the main ctlseq-parser. The
+ * parser is a simple state-machine that correctly parses all CSI, DCS, OSC, ST
+ * control sequences and generic escape sequences.
+ * The parser itself does not perform any actions but lets the caller react to
+ * detected sequences.
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include "macro.h"
+#include "term-internal.h"
+#include "util.h"
+
+/**
+ * term_utf8_encode() - Encode single UCS-4 character as UTF-8
+ * @out_utf8: output buffer of at least 4 bytes or NULL
+ * @g: UCS-4 character to encode
+ *
+ * This encodes a single UCS-4 character as UTF-8 and writes it into @out_utf8.
+ * The length of the character is returned. It is not zero-terminated! If the
+ * output buffer is NULL, only the length is returned.
+ *
+ * Returns: The length in bytes that the UTF-8 representation does or would
+ *          occupy.
+ */
+size_t term_utf8_encode(char *out_utf8, uint32_t g) {
+        if (g < (1 << 7)) {
+                if (out_utf8)
+                        out_utf8[0] = g & 0x7f;
+                return 1;
+        } else if (g < (1 << 11)) {
+                if (out_utf8) {
+                        out_utf8[0] = 0xc0 | ((g >> 6) & 0x1f);
+                        out_utf8[1] = 0x80 | (g & 0x3f);
+                }
+                return 2;
+        } else if (g < (1 << 16)) {
+                if (out_utf8) {
+                        out_utf8[0] = 0xe0 | ((g >> 12) & 0x0f);
+                        out_utf8[1] = 0x80 | ((g >> 6) & 0x3f);
+                        out_utf8[2] = 0x80 | (g & 0x3f);
+                }
+                return 3;
+        } else if (g < (1 << 21)) {
+                if (out_utf8) {
+                        out_utf8[0] = 0xf0 | ((g >> 18) & 0x07);
+                        out_utf8[1] = 0x80 | ((g >> 12) & 0x3f);
+                        out_utf8[2] = 0x80 | ((g >> 6) & 0x3f);
+                        out_utf8[3] = 0x80 | (g & 0x3f);
+                }
+                return 4;
+        } else {
+                return 0;
+        }
+}
+
+/**
+ * term_utf8_decode() - Try decoding the next UCS-4 character
+ * @p: decoder object to operate on or NULL
+ * @out_len: output buffer for length of decoded UCS-4 string or NULL
+ * @c: next char to push into decoder
+ *
+ * This decodes a UTF-8 stream. It must be called for each input-byte of the
+ * UTF-8 stream and returns a UCS-4 stream. The length of the returned UCS-4
+ * string (number of parsed characters) is stored in @out_len if non-NULL. A
+ * pointer to the string is returned (or NULL if none was parsed). The string
+ * is not zero-terminated! Furthermore, the string is only valid until the next
+ * invokation of this function. It is also bound to the parser-state @p.
+ *
+ * This function is highly optimized to work with terminal-emulators. Instead
+ * of being strict about UTF-8 validity, this tries to perform a fallback to
+ * ISO-8859-1 in case a wrong series was detected. Therefore, this function
+ * might return multiple UCS-4 characters by parsing just a single UTF-8 byte.
+ *
+ * The parser state @p should be allocated and managed by the caller. There're
+ * no helpers to do that for you. To initialize it, simply reset it to all
+ * zero. You can reset or free the object at any point in time.
+ *
+ * Returns: Pointer to the UCS-4 string or NULL.
+ */
+const uint32_t *term_utf8_decode(term_utf8 *p, size_t *out_len, char c) {
+        uint32_t t, *res = NULL;
+        uint8_t byte;
+        size_t len = 0;
+
+        if (!p)
+                goto out;
+
+        byte = c;
+
+        if (!p->valid || p->i_bytes >= p->n_bytes) {
+                /*
+                 * If the previous sequence was invalid or fully parsed, start
+                 * parsing a fresh new sequence.
+                 */
+
+                if ((byte & 0xE0) == 0xC0) {
+                        /* start of two byte sequence */
+                        t = byte & 0x1F;
+                        p->n_bytes = 2;
+                        p->i_bytes = 1;
+                        p->valid = 1;
+                } else if ((byte & 0xF0) == 0xE0) {
+                        /* start of three byte sequence */
+                        t = byte & 0x0F;
+                        p->n_bytes = 3;
+                        p->i_bytes = 1;
+                        p->valid = 1;
+                } else if ((byte & 0xF8) == 0xF0) {
+                        /* start of four byte sequence */
+                        t = byte & 0x07;
+                        p->n_bytes = 4;
+                        p->i_bytes = 1;
+                        p->valid = 1;
+                } else {
+                        /* Either of:
+                         *  - single ASCII 7-bit char
+                         *  - out-of-sync continuation byte
+                         *  - overlong encoding
+                         * All of them are treated as single byte ISO-8859-1 */
+                        t = byte;
+                        p->n_bytes = 1;
+                        p->i_bytes = 1;
+                        p->valid = 0;
+                }
+
+                p->chars[0] = byte;
+                p->ucs4 = t << (6 * (p->n_bytes - p->i_bytes));
+        } else {
+                /*
+                 * ..otherwise, try to continue the previous sequence..
+                 */
+
+                if ((byte & 0xC0) == 0x80) {
+                        /*
+                         * Valid continuation byte. Append to sequence and
+                         * update the ucs4 cache accordingly.
+                         */
+
+                        t = byte & 0x3F;
+                        p->chars[p->i_bytes++] = byte;
+                        p->ucs4 |= t << (6 * (p->n_bytes - p->i_bytes));
+                } else {
+                        /*
+                         * Invalid continuation? Treat cached sequence as
+                         * ISO-8859-1, but parse the new char as valid new
+                         * starting character. If it's a new single-byte UTF-8
+                         * sequence, we immediately return it in the same run,
+                         * otherwise, we might suffer from starvation.
+                         */
+
+                        if ((byte & 0xE0) == 0xC0 ||
+                            (byte & 0xF0) == 0xE0 ||
+                            (byte & 0xF8) == 0xF0) {
+                                /*
+                                 * New multi-byte sequence. Move to-be-returned
+                                 * data at the end and start new sequence. Only
+                                 * return the old sequence.
+                                 */
+
+                                memmove(p->chars + 1,
+                                        p->chars,
+                                        sizeof(*p->chars) * p->i_bytes);
+                                res = p->chars + 1;
+                                len = p->i_bytes;
+
+                                if ((byte & 0xE0) == 0xC0) {
+                                        /* start of two byte sequence */
+                                        t = byte & 0x1F;
+                                        p->n_bytes = 2;
+                                        p->i_bytes = 1;
+                                        p->valid = 1;
+                                } else if ((byte & 0xF0) == 0xE0) {
+                                        /* start of three byte sequence */
+                                        t = byte & 0x0F;
+                                        p->n_bytes = 3;
+                                        p->i_bytes = 1;
+                                        p->valid = 1;
+                                } else if ((byte & 0xF8) == 0xF0) {
+                                        /* start of four byte sequence */
+                                        t = byte & 0x07;
+                                        p->n_bytes = 4;
+                                        p->i_bytes = 1;
+                                        p->valid = 1;
+                                } else
+                                        assert_not_reached("Should not happen");
+
+                                p->chars[0] = byte;
+                                p->ucs4 = t << (6 * (p->n_bytes - p->i_bytes));
+
+                                goto out;
+                        } else {
+                                /*
+                                 * New single byte sequence, append to output
+                                 * and return combined sequence.
+                                 */
+
+                                p->chars[p->i_bytes++] = byte;
+                                p->valid = 0;
+                        }
+                }
+        }
+
+        /*
+         * Check whether a full sequence (valid or invalid) has been parsed and
+         * then return it. Otherwise, return nothing.
+         */
+        if (p->valid) {
+                /* still parsing? then bail out */
+                if (p->i_bytes < p->n_bytes)
+                        goto out;
+
+                res = &p->ucs4;
+                len = 1;
+        } else {
+                res = p->chars;
+                len = p->i_bytes;
+        }
+
+        p->valid = 0;
+        p->i_bytes = 0;
+        p->n_bytes = 0;
+
+out:
+        if (out_len)
+                *out_len = len;
+        return len > 0 ? res : NULL;
+}
+
+/*
+ * Command Parser
+ * The ctl-seq parser "term_parser" only detects whole sequences, it does not
+ * detect the specific command. Once a sequence is parsed, the command-parsers
+ * are used to figure out their meaning. Note that this depends on whether we
+ * run on the host or terminal side.
+ */
+
+static unsigned int term_parse_host_control(const term_seq *seq) {
+        assert_return(seq, TERM_CMD_NONE);
+
+        switch (seq->terminator) {
+        case 0x00: /* NUL */
+                return TERM_CMD_NULL;
+        case 0x05: /* ENQ */
+                return TERM_CMD_ENQ;
+        case 0x07: /* BEL */
+                return TERM_CMD_BEL;
+        case 0x08: /* BS */
+                return TERM_CMD_BS;
+        case 0x09: /* HT */
+                return TERM_CMD_HT;
+        case 0x0a: /* LF */
+                return TERM_CMD_LF;
+        case 0x0b: /* VT */
+                return TERM_CMD_VT;
+        case 0x0c: /* FF */
+                return TERM_CMD_FF;
+        case 0x0d: /* CR */
+                return TERM_CMD_CR;
+        case 0x0e: /* SO */
+                return TERM_CMD_SO;
+        case 0x0f: /* SI */
+                return TERM_CMD_SI;
+        case 0x11: /* DC1 */
+                return TERM_CMD_DC1;
+        case 0x13: /* DC3 */
+                return TERM_CMD_DC3;
+        case 0x18: /* CAN */
+                /* this is already handled by the state-machine */
+                break;
+        case 0x1a: /* SUB */
+                return TERM_CMD_SUB;
+        case 0x1b: /* ESC */
+                /* this is already handled by the state-machine */
+                break;
+        case 0x1f: /* DEL */
+                /* this is already handled by the state-machine */
+                break;
+        case 0x84: /* IND */
+                return TERM_CMD_IND;
+        case 0x85: /* NEL */
+                return TERM_CMD_NEL;
+        case 0x88: /* HTS */
+                return TERM_CMD_HTS;
+        case 0x8d: /* RI */
+                return TERM_CMD_RI;
+        case 0x8e: /* SS2 */
+                return TERM_CMD_SS2;
+        case 0x8f: /* SS3 */
+                return TERM_CMD_SS3;
+        case 0x90: /* DCS */
+                /* this is already handled by the state-machine */
+                break;
+        case 0x96: /* SPA */
+                return TERM_CMD_SPA;
+        case 0x97: /* EPA */
+                return TERM_CMD_EPA;
+        case 0x98: /* SOS */
+                /* this is already handled by the state-machine */
+                break;
+        case 0x9a: /* DECID */
+                return TERM_CMD_DECID;
+        case 0x9b: /* CSI */
+                /* this is already handled by the state-machine */
+                break;
+        case 0x9c: /* ST */
+                return TERM_CMD_ST;
+        case 0x9d: /* OSC */
+                /* this is already handled by the state-machine */
+                break;
+        case 0x9e: /* PM */
+                /* this is already handled by the state-machine */
+                break;
+        case 0x9f: /* APC */
+                /* this is already handled by the state-machine */
+                break;
+        }
+
+        return TERM_CMD_NONE;
+}
+
+static inline int charset_from_cmd(uint32_t raw, unsigned int flags, bool require_96) {
+        static const struct {
+                uint32_t raw;
+                unsigned int flags;
+        } charset_cmds[] = {
+                /* 96-compat charsets */
+                [TERM_CHARSET_ISO_LATIN1_SUPPLEMENTAL]   = { .raw = 'A', .flags = 0 },
+                [TERM_CHARSET_ISO_LATIN2_SUPPLEMENTAL]   = { .raw = 'B', .flags = 0 },
+                [TERM_CHARSET_ISO_LATIN5_SUPPLEMENTAL]   = { .raw = 'M', .flags = 0 },
+                [TERM_CHARSET_ISO_GREEK_SUPPLEMENTAL]    = { .raw = 'F', .flags = 0 },
+                [TERM_CHARSET_ISO_HEBREW_SUPPLEMENTAL]   = { .raw = 'H', .flags = 0 },
+                [TERM_CHARSET_ISO_LATIN_CYRILLIC]        = { .raw = 'L', .flags = 0 },
+
+                /* 94-compat charsets */
+                [TERM_CHARSET_DEC_SPECIAL_GRAPHIC]       = { .raw = '0', .flags = 0 },
+                [TERM_CHARSET_DEC_SUPPLEMENTAL]          = { .raw = '5', .flags = TERM_SEQ_FLAG_PERCENT },
+                [TERM_CHARSET_DEC_TECHNICAL]             = { .raw = '>', .flags = 0 },
+                [TERM_CHARSET_CYRILLIC_DEC]              = { .raw = '4', .flags = TERM_SEQ_FLAG_AND },
+                [TERM_CHARSET_DUTCH_NRCS]                = { .raw = '4', .flags = 0 },
+                [TERM_CHARSET_FINNISH_NRCS]              = { .raw = '5', .flags = 0 },
+                [TERM_CHARSET_FRENCH_NRCS]               = { .raw = 'R', .flags = 0 },
+                [TERM_CHARSET_FRENCH_CANADIAN_NRCS]      = { .raw = '9', .flags = 0 },
+                [TERM_CHARSET_GERMAN_NRCS]               = { .raw = 'K', .flags = 0 },
+                [TERM_CHARSET_GREEK_DEC]                 = { .raw = '?', .flags = TERM_SEQ_FLAG_DQUOTE },
+                [TERM_CHARSET_GREEK_NRCS]                = { .raw = '>', .flags = TERM_SEQ_FLAG_DQUOTE },
+                [TERM_CHARSET_HEBREW_DEC]                = { .raw = '4', .flags = TERM_SEQ_FLAG_DQUOTE },
+                [TERM_CHARSET_HEBREW_NRCS]               = { .raw = '=', .flags = TERM_SEQ_FLAG_PERCENT },
+                [TERM_CHARSET_ITALIAN_NRCS]              = { .raw = 'Y', .flags = 0 },
+                [TERM_CHARSET_NORWEGIAN_DANISH_NRCS]     = { .raw = '`', .flags = 0 },
+                [TERM_CHARSET_PORTUGUESE_NRCS]           = { .raw = '6', .flags = TERM_SEQ_FLAG_PERCENT },
+                [TERM_CHARSET_RUSSIAN_NRCS]              = { .raw = '5', .flags = TERM_SEQ_FLAG_AND },
+                [TERM_CHARSET_SCS_NRCS]                  = { .raw = '3', .flags = TERM_SEQ_FLAG_PERCENT },
+                [TERM_CHARSET_SPANISH_NRCS]              = { .raw = 'Z', .flags = 0 },
+                [TERM_CHARSET_SWEDISH_NRCS]              = { .raw = '7', .flags = 0 },
+                [TERM_CHARSET_SWISS_NRCS]                = { .raw = '=', .flags = 0 },
+                [TERM_CHARSET_TURKISH_DEC]               = { .raw = '0', .flags = TERM_SEQ_FLAG_PERCENT },
+                [TERM_CHARSET_TURKISH_NRCS]              = { .raw = '2', .flags = TERM_SEQ_FLAG_PERCENT },
+
+                /* special charsets */
+                [TERM_CHARSET_USERPREF_SUPPLEMENTAL]     = { .raw = '<', .flags = 0 },
+
+                /* secondary choices */
+                [TERM_CHARSET_CNT + TERM_CHARSET_FINNISH_NRCS]            = { .raw = 'C', .flags = 0 },
+                [TERM_CHARSET_CNT + TERM_CHARSET_FRENCH_NRCS]             = { .raw = 'f', .flags = 0 },
+                [TERM_CHARSET_CNT + TERM_CHARSET_FRENCH_CANADIAN_NRCS]    = { .raw = 'Q', .flags = 0 },
+                [TERM_CHARSET_CNT + TERM_CHARSET_NORWEGIAN_DANISH_NRCS]   = { .raw = 'E', .flags = 0 },
+                [TERM_CHARSET_CNT + TERM_CHARSET_SWEDISH_NRCS]            = { .raw = 'H', .flags = 0 }, /* unused; conflicts with ISO_HEBREW */
+
+                /* tertiary choices */
+                [TERM_CHARSET_CNT + TERM_CHARSET_CNT + TERM_CHARSET_NORWEGIAN_DANISH_NRCS] = { .raw = '6', .flags = 0 },
+        };
+        size_t i, cs;
+
+        /*
+         * Secondary choice on SWEDISH_NRCS and primary choice on
+         * ISO_HEBREW_SUPPLEMENTAL have a conflict: raw=="H", flags==0.
+         * We always choose the ISO 96-compat set, which is what VT510 does.
+         */
+
+        for (i = 0; i < ELEMENTSOF(charset_cmds); ++i) {
+                if (charset_cmds[i].raw == raw && charset_cmds[i].flags == flags) {
+                        cs = i;
+                        while (cs >= TERM_CHARSET_CNT)
+                                cs -= TERM_CHARSET_CNT;
+
+                        if (!require_96 || cs < TERM_CHARSET_96_CNT || cs >= TERM_CHARSET_94_CNT)
+                                return cs;
+                }
+        }
+
+        return -ENOENT;
+}
+
+/* true if exactly one bit in @value is set */
+static inline bool exactly_one_bit_set(unsigned int value) {
+        return __builtin_popcount(value) == 1;
+}
+
+static unsigned int term_parse_host_escape(const term_seq *seq, unsigned int *cs_out) {
+        unsigned int t, flags;
+        int cs;
+
+        assert_return(seq, TERM_CMD_NONE);
+
+        flags = seq->intermediates;
+        t = TERM_SEQ_FLAG_POPEN | TERM_SEQ_FLAG_PCLOSE | TERM_SEQ_FLAG_MULT |
+            TERM_SEQ_FLAG_PLUS  | TERM_SEQ_FLAG_MINUS  | TERM_SEQ_FLAG_DOT  |
+            TERM_SEQ_FLAG_SLASH;
+
+        if (exactly_one_bit_set(flags & t)) {
+                switch (flags & t) {
+                case TERM_SEQ_FLAG_POPEN:
+                case TERM_SEQ_FLAG_PCLOSE:
+                case TERM_SEQ_FLAG_MULT:
+                case TERM_SEQ_FLAG_PLUS:
+                        cs = charset_from_cmd(seq->terminator, flags & ~t, false);
+                        break;
+                case TERM_SEQ_FLAG_MINUS:
+                case TERM_SEQ_FLAG_DOT:
+                case TERM_SEQ_FLAG_SLASH:
+                        cs = charset_from_cmd(seq->terminator, flags & ~t, true);
+                        break;
+                default:
+                        cs = -ENOENT;
+                        break;
+                }
+
+                if (cs >= 0) {
+                        if (cs_out)
+                                *cs_out = cs;
+                        return TERM_CMD_SCS;
+                }
+
+                /* looked like a charset-cmd but wasn't; continue */
+        }
+
+        switch (seq->terminator) {
+        case '3':
+                if (flags == TERM_SEQ_FLAG_HASH) /* DECDHL top-half */
+                        return TERM_CMD_DECDHL_TH;
+                break;
+        case '4':
+                if (flags == TERM_SEQ_FLAG_HASH) /* DECDHL bottom-half */
+                        return TERM_CMD_DECDHL_BH;
+                break;
+        case '5':
+                if (flags == TERM_SEQ_FLAG_HASH) /* DECSWL */
+                        return TERM_CMD_DECSWL;
+                break;
+        case '6':
+                if (flags == 0) /* DECBI */
+                        return TERM_CMD_DECBI;
+                else if (flags == TERM_SEQ_FLAG_HASH) /* DECDWL */
+                        return TERM_CMD_DECDWL;
+                break;
+        case '7':
+                if (flags == 0) /* DECSC */
+                        return TERM_CMD_DECSC;
+                break;
+        case '8':
+                if (flags == 0) /* DECRC */
+                        return TERM_CMD_DECRC;
+                else if (flags == TERM_SEQ_FLAG_HASH) /* DECALN */
+                        return TERM_CMD_DECALN;
+                break;
+        case '9':
+                if (flags == 0) /* DECFI */
+                        return TERM_CMD_DECFI;
+                break;
+        case '<':
+                if (flags == 0) /* DECANM */
+                        return TERM_CMD_DECANM;
+                break;
+        case '=':
+                if (flags == 0) /* DECKPAM */
+                        return TERM_CMD_DECKPAM;
+                break;
+        case '>':
+                if (flags == 0) /* DECKPNM */
+                        return TERM_CMD_DECKPNM;
+                break;
+        case '@':
+                if (flags == TERM_SEQ_FLAG_PERCENT) {
+                        /* Select default character set */
+                        return TERM_CMD_XTERM_SDCS;
+                }
+                break;
+        case 'D':
+                if (flags == 0) /* IND */
+                        return TERM_CMD_IND;
+                break;
+        case 'E':
+                if (flags == 0) /* NEL */
+                        return TERM_CMD_NEL;
+                break;
+        case 'F':
+                if (flags == 0) /* Cursor to lower-left corner of screen */
+                        return TERM_CMD_XTERM_CLLHP;
+                else if (flags == TERM_SEQ_FLAG_SPACE) /* S7C1T */
+                        return TERM_CMD_S7C1T;
+                break;
+        case 'G':
+                if (flags == TERM_SEQ_FLAG_SPACE) { /* S8C1T */
+                        return TERM_CMD_S8C1T;
+                } else if (flags == TERM_SEQ_FLAG_PERCENT) {
+                        /* Select UTF-8 character set */
+                        return TERM_CMD_XTERM_SUCS;
+                }
+                break;
+        case 'H':
+                if (flags == 0) /* HTS */
+                        return TERM_CMD_HTS;
+                break;
+        case 'L':
+                if (flags == TERM_SEQ_FLAG_SPACE) {
+                        /* Set ANSI conformance level 1 */
+                        return TERM_CMD_XTERM_SACL1;
+                }
+                break;
+        case 'M':
+                if (flags == 0) { /* RI */
+                        return TERM_CMD_RI;
+                } else if (flags == TERM_SEQ_FLAG_SPACE) {
+                        /* Set ANSI conformance level 2 */
+                        return TERM_CMD_XTERM_SACL2;
+                }
+                break;
+        case 'N':
+                if (flags == 0) { /* SS2 */
+                        return TERM_CMD_SS2;
+                } else if (flags == TERM_SEQ_FLAG_SPACE) {
+                        /* Set ANSI conformance level 3 */
+                        return TERM_CMD_XTERM_SACL3;
+                }
+                break;
+        case 'O':
+                if (flags == 0) /* SS3 */
+                        return TERM_CMD_SS3;
+                break;
+        case 'P':
+                if (flags == 0) /* DCS: this is already handled by the state-machine */
+                        return 0;
+                break;
+        case 'V':
+                if (flags == 0) /* SPA */
+                        return TERM_CMD_SPA;
+                break;
+        case 'W':
+                if (flags == 0) /* EPA */
+                        return TERM_CMD_EPA;
+                break;
+        case 'X':
+                if (flags == 0) { /* SOS */
+                        /* this is already handled by the state-machine */
+                        break;
+                }
+                break;
+        case 'Z':
+                if (flags == 0) /* DECID */
+                        return TERM_CMD_DECID;
+                break;
+        case '[':
+                if (flags == 0) { /* CSI */
+                        /* this is already handled by the state-machine */
+                        break;
+                }
+                break;
+        case '\\':
+                if (flags == 0) /* ST */
+                        return TERM_CMD_ST;
+                break;
+        case ']':
+                if (flags == 0) { /* OSC */
+                        /* this is already handled by the state-machine */
+                        break;
+                }
+                break;
+        case '^':
+                if (flags == 0) { /* PM */
+                        /* this is already handled by the state-machine */
+                        break;
+                }
+                break;
+        case '_':
+                if (flags == 0) { /* APC */
+                        /* this is already handled by the state-machine */
+                        break;
+                }
+                break;
+        case 'c':
+                if (flags == 0) /* RIS */
+                        return TERM_CMD_RIS;
+                break;
+        case 'l':
+                if (flags == 0) /* Memory lock */
+                        return TERM_CMD_XTERM_MLHP;
+                break;
+        case 'm':
+                if (flags == 0) /* Memory unlock */
+                        return TERM_CMD_XTERM_MUHP;
+                break;
+        case 'n':
+                if (flags == 0) /* LS2 */
+                        return TERM_CMD_LS2;
+                break;
+        case 'o':
+                if (flags == 0) /* LS3 */
+                        return TERM_CMD_LS3;
+                break;
+        case '|':
+                if (flags == 0) /* LS3R */
+                        return TERM_CMD_LS3R;
+                break;
+        case '}':
+                if (flags == 0) /* LS2R */
+                        return TERM_CMD_LS2R;
+                break;
+        case '~':
+                if (flags == 0) /* LS1R */
+                        return TERM_CMD_LS1R;
+                break;
+        }
+
+        return TERM_CMD_NONE;
+}
+
+static unsigned int term_parse_host_csi(const term_seq *seq) {
+        unsigned int flags;
+
+        assert_return(seq, TERM_CMD_NONE);
+
+        flags = seq->intermediates;
+
+        switch (seq->terminator) {
+        case 'A':
+                if (flags == 0) /* CUU */
+                        return TERM_CMD_CUU;
+                break;
+        case 'a':
+                if (flags == 0) /* HPR */
+                        return TERM_CMD_HPR;
+                break;
+        case 'B':
+                if (flags == 0) /* CUD */
+                        return TERM_CMD_CUD;
+                break;
+        case 'b':
+                if (flags == 0) /* REP */
+                        return TERM_CMD_REP;
+                break;
+        case 'C':
+                if (flags == 0) /* CUF */
+                        return TERM_CMD_CUF;
+                break;
+        case 'c':
+                if (flags == 0) /* DA1 */
+                        return TERM_CMD_DA1;
+                else if (flags == TERM_SEQ_FLAG_GT) /* DA2 */
+                        return TERM_CMD_DA2;
+                else if (flags == TERM_SEQ_FLAG_EQUAL) /* DA3 */
+                        return TERM_CMD_DA3;
+                break;
+        case 'D':
+                if (flags == 0) /* CUB */
+                        return TERM_CMD_CUB;
+                break;
+        case 'd':
+                if (flags == 0) /* VPA */
+                        return TERM_CMD_VPA;
+                break;
+        case 'E':
+                if (flags == 0) /* CNL */
+                        return TERM_CMD_CNL;
+                break;
+        case 'e':
+                if (flags == 0) /* VPR */
+                        return TERM_CMD_VPR;
+                break;
+        case 'F':
+                if (flags == 0) /* CPL */
+                        return TERM_CMD_CPL;
+                break;
+        case 'f':
+                if (flags == 0) /* HVP */
+                        return TERM_CMD_HVP;
+                break;
+        case 'G':
+                if (flags == 0) /* CHA */
+                        return TERM_CMD_CHA;
+                break;
+        case 'g':
+                if (flags == 0) /* TBC */
+                        return TERM_CMD_TBC;
+                else if (flags == TERM_SEQ_FLAG_MULT) /* DECLFKC */
+                        return TERM_CMD_DECLFKC;
+                break;
+        case 'H':
+                if (flags == 0) /* CUP */
+                        return TERM_CMD_CUP;
+                break;
+        case 'h':
+                if (flags == 0) /* SM ANSI */
+                        return TERM_CMD_SM_ANSI;
+                else if (flags == TERM_SEQ_FLAG_WHAT) /* SM DEC */
+                        return TERM_CMD_SM_DEC;
+                break;
+        case 'I':
+                if (flags == 0) /* CHT */
+                        return TERM_CMD_CHT;
+                break;
+        case 'i':
+                if (flags == 0) /* MC ANSI */
+                        return TERM_CMD_MC_ANSI;
+                else if (flags == TERM_SEQ_FLAG_WHAT) /* MC DEC */
+                        return TERM_CMD_MC_DEC;
+                break;
+        case 'J':
+                if (flags == 0) /* ED */
+                        return TERM_CMD_ED;
+                else if (flags == TERM_SEQ_FLAG_WHAT) /* DECSED */
+                        return TERM_CMD_DECSED;
+                break;
+        case 'K':
+                if (flags == 0) /* EL */
+                        return TERM_CMD_EL;
+                else if (flags == TERM_SEQ_FLAG_WHAT) /* DECSEL */
+                        return TERM_CMD_DECSEL;
+                break;
+        case 'L':
+                if (flags == 0) /* IL */
+                        return TERM_CMD_IL;
+                break;
+        case 'l':
+                if (flags == 0) /* RM ANSI */
+                        return TERM_CMD_RM_ANSI;
+                else if (flags == TERM_SEQ_FLAG_WHAT) /* RM DEC */
+                        return TERM_CMD_RM_DEC;
+                break;
+        case 'M':
+                if (flags == 0) /* DL */
+                        return TERM_CMD_DL;
+                break;
+        case 'm':
+                if (flags == 0) /* SGR */
+                        return TERM_CMD_SGR;
+                else if (flags == TERM_SEQ_FLAG_GT) /* XTERM SMR */
+                        return TERM_CMD_XTERM_SRV;
+                break;
+        case 'n':
+                if (flags == 0) /* DSR ANSI */
+                        return TERM_CMD_DSR_ANSI;
+                else if (flags == TERM_SEQ_FLAG_GT) /* XTERM RMR */
+                        return TERM_CMD_XTERM_RRV;
+                else if (flags == TERM_SEQ_FLAG_WHAT) /* DSR DEC */
+                        return TERM_CMD_DSR_DEC;
+                break;
+        case 'P':
+                if (flags == 0) /* DCH */
+                        return TERM_CMD_DCH;
+                else if (flags == TERM_SEQ_FLAG_SPACE) /* PPA */
+                        return TERM_CMD_PPA;
+                break;
+        case 'p':
+                if (flags == 0) /* DECSSL */
+                        return TERM_CMD_DECSSL;
+                else if (flags == TERM_SEQ_FLAG_SPACE) /* DECSSCLS */
+                        return TERM_CMD_DECSSCLS;
+                else if (flags == TERM_SEQ_FLAG_BANG) /* DECSTR */
+                        return TERM_CMD_DECSTR;
+                else if (flags == TERM_SEQ_FLAG_DQUOTE) /* DECSCL */
+                        return TERM_CMD_DECSCL;
+                else if (flags == TERM_SEQ_FLAG_CASH) /* DECRQM-ANSI */
+                        return TERM_CMD_DECRQM_ANSI;
+                else if (flags == (TERM_SEQ_FLAG_CASH | TERM_SEQ_FLAG_WHAT)) /* DECRQM-DEC */
+                        return TERM_CMD_DECRQM_DEC;
+                else if (flags == TERM_SEQ_FLAG_PCLOSE) /* DECSDPT */
+                        return TERM_CMD_DECSDPT;
+                else if (flags == TERM_SEQ_FLAG_MULT) /* DECSPPCS */
+                        return TERM_CMD_DECSPPCS;
+                else if (flags == TERM_SEQ_FLAG_PLUS) /* DECSR */
+                        return TERM_CMD_DECSR;
+                else if (flags == TERM_SEQ_FLAG_COMMA) /* DECLTOD */
+                        return TERM_CMD_DECLTOD;
+                else if (flags == TERM_SEQ_FLAG_GT) /* XTERM SPM */
+                        return TERM_CMD_XTERM_SPM;
+                break;
+        case 'Q':
+                if (flags == TERM_SEQ_FLAG_SPACE) /* PPR */
+                        return TERM_CMD_PPR;
+                break;
+        case 'q':
+                if (flags == 0) /* DECLL */
+                        return TERM_CMD_DECLL;
+                else if (flags == TERM_SEQ_FLAG_SPACE) /* DECSCUSR */
+                        return TERM_CMD_DECSCUSR;
+                else if (flags == TERM_SEQ_FLAG_DQUOTE) /* DECSCA */
+                        return TERM_CMD_DECSCA;
+                else if (flags == TERM_SEQ_FLAG_CASH) /* DECSDDT */
+                        return TERM_CMD_DECSDDT;
+                else if (flags == TERM_SEQ_FLAG_MULT) /* DECSRC */
+                        return TERM_CMD_DECSR;
+                else if (flags == TERM_SEQ_FLAG_PLUS) /* DECELF */
+                        return TERM_CMD_DECELF;
+                else if (flags == TERM_SEQ_FLAG_COMMA) /* DECTID */
+                        return TERM_CMD_DECTID;
+                break;
+        case 'R':
+                if (flags == TERM_SEQ_FLAG_SPACE) /* PPB */
+                        return TERM_CMD_PPB;
+                break;
+        case 'r':
+                if (flags == 0) {
+                        /* DECSTBM */
+                        return TERM_CMD_DECSTBM;
+                } else if (flags == TERM_SEQ_FLAG_SPACE) {
+                        /* DECSKCV */
+                        return TERM_CMD_DECSKCV;
+                } else if (flags == TERM_SEQ_FLAG_CASH) {
+                        /* DECCARA */
+                        return TERM_CMD_DECCARA;
+                } else if (flags == TERM_SEQ_FLAG_MULT) {
+                        /* DECSCS */
+                        return TERM_CMD_DECSCS;
+                } else if (flags == TERM_SEQ_FLAG_PLUS) {
+                        /* DECSMKR */
+                        return TERM_CMD_DECSMKR;
+                } else if (flags == TERM_SEQ_FLAG_WHAT) {
+                        /*
+                         * There's a conflict between DECPCTERM and XTERM-RPM.
+                         * XTERM-RPM takes a single argument, DECPCTERM takes 2.
+                         * Split both up and forward the call to the closer
+                         * match.
+                         */
+                        if (seq->n_args <= 1) /* XTERM RPM */
+                                return TERM_CMD_XTERM_RPM;
+                        else if (seq->n_args >= 2) /* DECPCTERM */
+                                return TERM_CMD_DECPCTERM;
+                }
+                break;
+        case 'S':
+                if (flags == 0) /* SU */
+                        return TERM_CMD_SU;
+                else if (flags == TERM_SEQ_FLAG_WHAT) /* XTERM SGFX */
+                        return TERM_CMD_XTERM_SGFX;
+                break;
+        case 's':
+                if (flags == 0) {
+                        /*
+                         * There's a conflict between DECSLRM and SC-ANSI which
+                         * cannot be resolved without knowing the state of
+                         * DECLRMM. We leave that decision up to the caller.
+                         */
+                        return TERM_CMD_DECSLRM_OR_SC;
+                } else if (flags == TERM_SEQ_FLAG_CASH) {
+                        /* DECSPRTT */
+                        return TERM_CMD_DECSPRTT;
+                } else if (flags == TERM_SEQ_FLAG_MULT) {
+                        /* DECSFC */
+                        return TERM_CMD_DECSFC;
+                } else if (flags == TERM_SEQ_FLAG_WHAT) {
+                        /* XTERM SPM */
+                        return TERM_CMD_XTERM_SPM;
+                }
+                break;
+        case 'T':
+                if (flags == 0) {
+                        /*
+                         * Awesome: There's a conflict between SD and XTERM IHMT
+                         * that we have to resolve by checking the parameter
+                         * count.. XTERM_IHMT needs exactly 5 arguments, SD
+                         * takes 0 or 1. We're conservative here and give both
+                         * a wider range to allow unused arguments (compat...).
+                         */
+                        if (seq->n_args >= 5) {
+                                /* XTERM IHMT */
+                                return TERM_CMD_XTERM_IHMT;
+                        } else if (seq->n_args < 5) {
+                                /* SD */
+                                return TERM_CMD_SD;
+                        }
+                } else if (flags == TERM_SEQ_FLAG_GT) {
+                        /* XTERM RTM */
+                        return TERM_CMD_XTERM_RTM;
+                }
+                break;
+        case 't':
+                if (flags == 0) {
+                        if (seq->n_args > 0 && seq->args[0] < 24) {
+                                /* XTERM WM */
+                                return TERM_CMD_XTERM_WM;
+                        } else {
+                                /* DECSLPP */
+                                return TERM_CMD_DECSLPP;
+                        }
+                } else if (flags == TERM_SEQ_FLAG_SPACE) {
+                        /* DECSWBV */
+                        return TERM_CMD_DECSWBV;
+                } else if (flags == TERM_SEQ_FLAG_DQUOTE) {
+                        /* DECSRFR */
+                        return TERM_CMD_DECSRFR;
+                } else if (flags == TERM_SEQ_FLAG_CASH) {
+                        /* DECRARA */
+                        return TERM_CMD_DECRARA;
+                } else if (flags == TERM_SEQ_FLAG_GT) {
+                        /* XTERM STM */
+                        return TERM_CMD_XTERM_STM;
+                }
+                break;
+        case 'U':
+                if (flags == 0) /* NP */
+                        return TERM_CMD_NP;
+                break;
+        case 'u':
+                if (flags == 0) {
+                        /* RC */
+                        return TERM_CMD_RC;
+                } else if (flags == TERM_SEQ_FLAG_SPACE) {
+                        /* DECSMBV */
+                        return TERM_CMD_DECSMBV;
+                } else if (flags == TERM_SEQ_FLAG_DQUOTE) {
+                        /* DECSTRL */
+                        return TERM_CMD_DECSTRL;
+                } else if (flags == TERM_SEQ_FLAG_WHAT) {
+                        /* DECRQUPSS */
+                        return TERM_CMD_DECRQUPSS;
+                } else if (seq->args[0] == 1 && flags == TERM_SEQ_FLAG_CASH) {
+                        /* DECRQTSR */
+                        return TERM_CMD_DECRQTSR;
+                } else if (flags == TERM_SEQ_FLAG_MULT) {
+                        /* DECSCP */
+                        return TERM_CMD_DECSCP;
+                } else if (flags == TERM_SEQ_FLAG_COMMA) {
+                        /* DECRQKT */
+                        return TERM_CMD_DECRQKT;
+                }
+                break;
+        case 'V':
+                if (flags == 0) /* PP */
+                        return TERM_CMD_PP;
+                break;
+        case 'v':
+                if (flags == TERM_SEQ_FLAG_SPACE) /* DECSLCK */
+                        return TERM_CMD_DECSLCK;
+                else if (flags == TERM_SEQ_FLAG_DQUOTE) /* DECRQDE */
+                        return TERM_CMD_DECRQDE;
+                else if (flags == TERM_SEQ_FLAG_CASH) /* DECCRA */
+                        return TERM_CMD_DECCRA;
+                else if (flags == TERM_SEQ_FLAG_COMMA) /* DECRPKT */
+                        return TERM_CMD_DECRPKT;
+                break;
+        case 'W':
+                if (seq->args[0] == 5 && flags == TERM_SEQ_FLAG_WHAT) {
+                        /* DECST8C */
+                        return TERM_CMD_DECST8C;
+                }
+                break;
+        case 'w':
+                if (flags == TERM_SEQ_FLAG_CASH) /* DECRQPSR */
+                        return TERM_CMD_DECRQPSR;
+                else if (flags == TERM_SEQ_FLAG_SQUOTE) /* DECEFR */
+                        return TERM_CMD_DECEFR;
+                else if (flags == TERM_SEQ_FLAG_PLUS) /* DECSPP */
+                        return TERM_CMD_DECSPP;
+                break;
+        case 'X':
+                if (flags == 0) /* ECH */
+                        return TERM_CMD_ECH;
+                break;
+        case 'x':
+                if (flags == 0) /* DECREQTPARM */
+                        return TERM_CMD_DECREQTPARM;
+                else if (flags == TERM_SEQ_FLAG_CASH) /* DECFRA */
+                        return TERM_CMD_DECFRA;
+                else if (flags == TERM_SEQ_FLAG_MULT) /* DECSACE */
+                        return TERM_CMD_DECSACE;
+                else if (flags == TERM_SEQ_FLAG_PLUS) /* DECRQPKFM */
+                        return TERM_CMD_DECRQPKFM;
+                break;
+        case 'y':
+                if (flags == 0) /* DECTST */
+                        return TERM_CMD_DECTST;
+                else if (flags == TERM_SEQ_FLAG_MULT) /* DECRQCRA */
+                        return TERM_CMD_DECRQCRA;
+                else if (flags == TERM_SEQ_FLAG_PLUS) /* DECPKFMR */
+                        return TERM_CMD_DECPKFMR;
+                break;
+        case 'Z':
+                if (flags == 0) /* CBT */
+                        return TERM_CMD_CBT;
+                break;
+        case 'z':
+                if (flags == TERM_SEQ_FLAG_CASH) /* DECERA */
+                        return TERM_CMD_DECERA;
+                else if (flags == TERM_SEQ_FLAG_SQUOTE) /* DECELR */
+                        return TERM_CMD_DECELR;
+                else if (flags == TERM_SEQ_FLAG_MULT) /* DECINVM */
+                        return TERM_CMD_DECINVM;
+                else if (flags == TERM_SEQ_FLAG_PLUS) /* DECPKA */
+                        return TERM_CMD_DECPKA;
+                break;
+        case '@':
+                if (flags == 0) /* ICH */
+                        return TERM_CMD_ICH;
+                break;
+        case '`':
+                if (flags == 0) /* HPA */
+                        return TERM_CMD_HPA;
+                break;
+        case '{':
+                if (flags == TERM_SEQ_FLAG_CASH) /* DECSERA */
+                        return TERM_CMD_DECSERA;
+                else if (flags == TERM_SEQ_FLAG_SQUOTE) /* DECSLE */
+                        return TERM_CMD_DECSLE;
+                break;
+        case '|':
+                if (flags == TERM_SEQ_FLAG_CASH) /* DECSCPP */
+                        return TERM_CMD_DECSCPP;
+                else if (flags == TERM_SEQ_FLAG_SQUOTE) /* DECRQLP */
+                        return TERM_CMD_DECRQLP;
+                else if (flags == TERM_SEQ_FLAG_MULT) /* DECSNLS */
+                        return TERM_CMD_DECSNLS;
+                break;
+        case '}':
+                if (flags == TERM_SEQ_FLAG_SPACE) /* DECKBD */
+                        return TERM_CMD_DECKBD;
+                else if (flags == TERM_SEQ_FLAG_CASH) /* DECSASD */
+                        return TERM_CMD_DECSASD;
+                else if (flags == TERM_SEQ_FLAG_SQUOTE) /* DECIC */
+                        return TERM_CMD_DECIC;
+                break;
+        case '~':
+                if (flags == TERM_SEQ_FLAG_SPACE) /* DECTME */
+                        return TERM_CMD_DECTME;
+                else if (flags == TERM_SEQ_FLAG_CASH) /* DECSSDT */
+                        return TERM_CMD_DECSSDT;
+                else if (flags == TERM_SEQ_FLAG_SQUOTE) /* DECDC */
+                        return TERM_CMD_DECDC;
+                break;
+        }
+
+        return TERM_CMD_NONE;
+}
+
+/*
+ * State Machine
+ * This parser controls the parser-state and returns any detected sequence to
+ * the caller. The parser is based on this state-diagram from Paul Williams:
+ *   http://vt100.net/emu/
+ * It was written from scratch and extended where needed.
+ * This parser is fully compatible up to the vt500 series. We expect UCS-4 as
+ * input. It's the callers responsibility to do any UTF-8 parsing.
+ */
+
+enum parser_state {
+        STATE_NONE,             /* placeholder */
+        STATE_GROUND,           /* initial state and ground */
+        STATE_ESC,              /* ESC sequence was started */
+        STATE_ESC_INT,          /* intermediate escape characters */
+        STATE_CSI_ENTRY,        /* starting CSI sequence */
+        STATE_CSI_PARAM,        /* CSI parameters */
+        STATE_CSI_INT,          /* intermediate CSI characters */
+        STATE_CSI_IGNORE,       /* CSI error; ignore this CSI sequence */
+        STATE_DCS_ENTRY,        /* starting DCS sequence */
+        STATE_DCS_PARAM,        /* DCS parameters */
+        STATE_DCS_INT,          /* intermediate DCS characters */
+        STATE_DCS_PASS,         /* DCS data passthrough */
+        STATE_DCS_IGNORE,       /* DCS error; ignore this DCS sequence */
+        STATE_OSC_STRING,       /* parsing OSC sequence */
+        STATE_ST_IGNORE,        /* unimplemented seq; ignore until ST */
+        STATE_NUM
+};
+
+enum parser_action {
+        ACTION_NONE,            /* placeholder */
+        ACTION_CLEAR,           /* clear parameters */
+        ACTION_IGNORE,          /* ignore the character entirely */
+        ACTION_PRINT,           /* print the character on the console */
+        ACTION_EXECUTE,         /* execute single control character (C0/C1) */
+        ACTION_COLLECT,         /* collect intermediate character */
+        ACTION_PARAM,           /* collect parameter character */
+        ACTION_ESC_DISPATCH,    /* dispatch escape sequence */
+        ACTION_CSI_DISPATCH,    /* dispatch csi sequence */
+        ACTION_DCS_START,       /* start of DCS data */
+        ACTION_DCS_COLLECT,     /* collect DCS data */
+        ACTION_DCS_CONSUME,     /* consume DCS terminator */
+        ACTION_DCS_DISPATCH,    /* dispatch dcs sequence */
+        ACTION_OSC_START,       /* start of OSC data */
+        ACTION_OSC_COLLECT,     /* collect OSC data */
+        ACTION_OSC_CONSUME,     /* consume OSC terminator */
+        ACTION_OSC_DISPATCH,    /* dispatch osc sequence */
+        ACTION_NUM
+};
+
+int term_parser_new(term_parser **out, bool host) {
+        _term_parser_free_ term_parser *parser = NULL;
+
+        assert_return(out, -EINVAL);
+
+        parser = new0(term_parser, 1);
+        if (!parser)
+                return -ENOMEM;
+
+        parser->is_host = host;
+        parser->st_alloc = 64;
+        parser->seq.st = new0(char, parser->st_alloc + 1);
+        if (!parser->seq.st)
+                return -ENOMEM;
+
+        *out = parser;
+        parser = NULL;
+        return 0;
+}
+
+term_parser *term_parser_free(term_parser *parser) {
+        if (!parser)
+                return NULL;
+
+        free(parser->seq.st);
+        free(parser);
+        return NULL;
+}
+
+static inline void parser_clear(term_parser *parser) {
+        unsigned int i;
+
+        parser->seq.command = TERM_CMD_NONE;
+        parser->seq.terminator = 0;
+        parser->seq.intermediates = 0;
+        parser->seq.charset = TERM_CHARSET_NONE;
+        parser->seq.n_args = 0;
+        for (i = 0; i < TERM_PARSER_ARG_MAX; ++i)
+                parser->seq.args[i] = -1;
+
+        parser->seq.n_st = 0;
+        parser->seq.st[0] = 0;
+}
+
+static int parser_ignore(term_parser *parser, uint32_t raw) {
+        parser_clear(parser);
+        parser->seq.type = TERM_SEQ_IGNORE;
+        parser->seq.command = TERM_CMD_NONE;
+        parser->seq.terminator = raw;
+        parser->seq.charset = TERM_CHARSET_NONE;
+
+        return parser->seq.type;
+}
+
+static int parser_print(term_parser *parser, uint32_t raw) {
+        parser_clear(parser);
+        parser->seq.type = TERM_SEQ_GRAPHIC;
+        parser->seq.command = TERM_CMD_GRAPHIC;
+        parser->seq.terminator = raw;
+        parser->seq.charset = TERM_CHARSET_NONE;
+
+        return parser->seq.type;
+}
+
+static int parser_execute(term_parser *parser, uint32_t raw) {
+        parser_clear(parser);
+        parser->seq.type = TERM_SEQ_CONTROL;
+        parser->seq.command = TERM_CMD_GRAPHIC;
+        parser->seq.terminator = raw;
+        parser->seq.charset = TERM_CHARSET_NONE;
+        if (!parser->is_host)
+                parser->seq.command = term_parse_host_control(&parser->seq);
+
+        return parser->seq.type;
+}
+
+static void parser_collect(term_parser *parser, uint32_t raw) {
+        /*
+         * Usually, characters from 0x30 to 0x3f are only allowed as leading
+         * markers (or as part of the parameters), characters from 0x20 to 0x2f
+         * are only allowed as trailing markers. However, our state-machine
+         * already verifies those restrictions so we can handle them the same
+         * way here. Note that we safely allow markers to be specified multiple
+         * times.
+         */
+
+        if (raw >= 0x20 && raw <= 0x3f)
+                parser->seq.intermediates |= 1 << (raw - 0x20);
+}
+
+static void parser_param(term_parser *parser, uint32_t raw) {
+        int new;
+
+        if (raw == ';') {
+                if (parser->seq.n_args < TERM_PARSER_ARG_MAX)
+                        ++parser->seq.n_args;
+
+                return;
+        }
+
+        if (parser->seq.n_args >= TERM_PARSER_ARG_MAX)
+                return;
+
+        if (raw >= '0' && raw <= '9') {
+                new = parser->seq.args[parser->seq.n_args];
+                if (new < 0)
+                        new = 0;
+                new = new * 10 + raw - '0';
+
+                /* VT510 tells us to clamp all values to [0, 9999], however, it
+                 * also allows commands with values up to 2^15-1. We simply use
+                 * 2^16 as maximum here to be compatible to all commands, but
+                 * avoid overflows in any calculations. */
+                if (new > 0xffff)
+                        new = 0xffff;
+
+                parser->seq.args[parser->seq.n_args] = new;
+        }
+}
+
+static int parser_esc(term_parser *parser, uint32_t raw) {
+        parser->seq.type = TERM_SEQ_ESCAPE;
+        parser->seq.command = TERM_CMD_NONE;
+        parser->seq.terminator = raw;
+        parser->seq.charset = TERM_CHARSET_NONE;
+        if (!parser->is_host)
+                parser->seq.command = term_parse_host_escape(&parser->seq, &parser->seq.charset);
+
+        return parser->seq.type;
+}
+
+static int parser_csi(term_parser *parser, uint32_t raw) {
+        /* parser->seq is cleared during CSI-ENTER state, thus there's no need
+         * to clear invalid fields here. */
+
+        if (parser->seq.n_args < TERM_PARSER_ARG_MAX) {
+                if (parser->seq.n_args > 0 ||
+                    parser->seq.args[parser->seq.n_args] >= 0)
+                        ++parser->seq.n_args;
+        }
+
+        parser->seq.type = TERM_SEQ_CSI;
+        parser->seq.command = TERM_CMD_NONE;
+        parser->seq.terminator = raw;
+        parser->seq.charset = TERM_CHARSET_NONE;
+        if (!parser->is_host)
+                parser->seq.command = term_parse_host_csi(&parser->seq);
+
+        return parser->seq.type;
+}
+
+/* perform state transition and dispatch related actions */
+static int parser_transition(term_parser *parser, uint32_t raw, unsigned int state, unsigned int action) {
+        if (state != STATE_NONE)
+                parser->state = state;
+
+        switch (action) {
+        case ACTION_NONE:
+                return TERM_SEQ_NONE;
+        case ACTION_CLEAR:
+                parser_clear(parser);
+                return TERM_SEQ_NONE;
+        case ACTION_IGNORE:
+                return parser_ignore(parser, raw);
+        case ACTION_PRINT:
+                return parser_print(parser, raw);
+        case ACTION_EXECUTE:
+                return parser_execute(parser, raw);
+        case ACTION_COLLECT:
+                parser_collect(parser, raw);
+                return TERM_SEQ_NONE;
+        case ACTION_PARAM:
+                parser_param(parser, raw);
+                return TERM_SEQ_NONE;
+        case ACTION_ESC_DISPATCH:
+                return parser_esc(parser, raw);
+        case ACTION_CSI_DISPATCH:
+                return parser_csi(parser, raw);
+        case ACTION_DCS_START:
+                /* not implemented */
+                return TERM_SEQ_NONE;
+        case ACTION_DCS_COLLECT:
+                /* not implemented */
+                return TERM_SEQ_NONE;
+        case ACTION_DCS_CONSUME:
+                /* not implemented */
+                return TERM_SEQ_NONE;
+        case ACTION_DCS_DISPATCH:
+                /* not implemented */
+                return TERM_SEQ_NONE;
+        case ACTION_OSC_START:
+                /* not implemented */
+                return TERM_SEQ_NONE;
+        case ACTION_OSC_COLLECT:
+                /* not implemented */
+                return TERM_SEQ_NONE;
+        case ACTION_OSC_CONSUME:
+                /* not implemented */
+                return TERM_SEQ_NONE;
+        case ACTION_OSC_DISPATCH:
+                /* not implemented */
+                return TERM_SEQ_NONE;
+        default:
+                assert_not_reached("invalid vte-parser action");
+                return TERM_SEQ_NONE;
+        }
+}
+
+static int parser_feed_to_state(term_parser *parser, uint32_t raw) {
+        switch (parser->state) {
+        case STATE_NONE:
+                /*
+                 * During initialization, parser->state is cleared. Treat this
+                 * as STATE_GROUND. We will then never get to STATE_NONE again.
+                 */
+        case STATE_GROUND:
+                switch (raw) {
+                case 0x00 ... 0x1f:     /* C0 */
+                case 0x80 ... 0x9b:     /* C1 \ { ST } */
+                case 0x9d ... 0x9f:
+                        return parser_transition(parser, raw, STATE_NONE, ACTION_EXECUTE);
+                case 0x9c:              /* ST */
+                        return parser_transition(parser, raw, STATE_NONE, ACTION_IGNORE);
+                }
+
+                return parser_transition(parser, raw, STATE_NONE, ACTION_PRINT);
+        case STATE_ESC:
+                switch (raw) {
+                case 0x00 ... 0x1f:     /* C0 */
+                        return parser_transition(parser, raw, STATE_NONE, ACTION_EXECUTE);
+                case 0x20 ... 0x2f:     /* [' ' - '\'] */
+                        return parser_transition(parser, raw, STATE_ESC_INT, ACTION_COLLECT);
+                case 0x30 ... 0x4f:     /* ['0' - '~'] \ { 'P', 'X', '[', ']', '^', '_' } */
+                case 0x51 ... 0x57:
+                case 0x59 ... 0x5a:
+                case 0x5c:
+                case 0x60 ... 0x7e:
+                        return parser_transition(parser, raw, STATE_GROUND, ACTION_ESC_DISPATCH);
+                case 0x50:              /* 'P' */
+                        return parser_transition(parser, raw, STATE_DCS_ENTRY, ACTION_CLEAR);
+                case 0x5b:              /* '[' */
+                        return parser_transition(parser, raw, STATE_CSI_ENTRY, ACTION_CLEAR);
+                case 0x5d:              /* ']' */
+                        return parser_transition(parser, raw, STATE_OSC_STRING, ACTION_CLEAR);
+                case 0x58:              /* 'X' */
+                case 0x5e:              /* '^' */
+                case 0x5f:              /* '_' */
+                        return parser_transition(parser, raw, STATE_ST_IGNORE, ACTION_NONE);
+                case 0x7f:              /* DEL */
+                        return parser_transition(parser, raw, STATE_NONE, ACTION_IGNORE);
+                case 0x9c:              /* ST */
+                        return parser_transition(parser, raw, STATE_GROUND, ACTION_IGNORE);
+                }
+
+                return parser_transition(parser, raw, STATE_ESC_INT, ACTION_COLLECT);
+        case STATE_ESC_INT:
+                switch (raw) {
+                case 0x00 ... 0x1f:     /* C0 */
+                        return parser_transition(parser, raw, STATE_NONE, ACTION_EXECUTE);
+                case 0x20 ... 0x2f:     /* [' ' - '\'] */
+                        return parser_transition(parser, raw, STATE_NONE, ACTION_COLLECT);
+                case 0x30 ... 0x7e:     /* ['0' - '~'] */
+                        return parser_transition(parser, raw, STATE_GROUND, ACTION_ESC_DISPATCH);
+                case 0x7f:              /* DEL */
+                        return parser_transition(parser, raw, STATE_NONE, ACTION_IGNORE);
+                case 0x9c:              /* ST */
+                        return parser_transition(parser, raw, STATE_GROUND, ACTION_IGNORE);
+                }
+
+                return parser_transition(parser, raw, STATE_NONE, ACTION_COLLECT);
+        case STATE_CSI_ENTRY:
+                switch (raw) {
+                case 0x00 ... 0x1f:     /* C0 */
+                        return parser_transition(parser, raw, STATE_NONE, ACTION_EXECUTE);
+                case 0x20 ... 0x2f:     /* [' ' - '\'] */
+                        return parser_transition(parser, raw, STATE_CSI_INT, ACTION_COLLECT);
+                case 0x3a:              /* ':' */
+                        return parser_transition(parser, raw, STATE_CSI_IGNORE, ACTION_NONE);
+                case 0x30 ... 0x39:     /* ['0' - '9'] */
+                case 0x3b:              /* ';' */
+                        return parser_transition(parser, raw, STATE_CSI_PARAM, ACTION_PARAM);
+                case 0x3c ... 0x3f:     /* ['<' - '?'] */
+                        return parser_transition(parser, raw, STATE_CSI_PARAM, ACTION_COLLECT);
+                case 0x40 ... 0x7e:     /* ['@' - '~'] */
+                        return parser_transition(parser, raw, STATE_GROUND, ACTION_CSI_DISPATCH);
+                case 0x7f:              /* DEL */
+                        return parser_transition(parser, raw, STATE_NONE, ACTION_IGNORE);
+                case 0x9c:              /* ST */
+                        return parser_transition(parser, raw, STATE_GROUND, ACTION_IGNORE);
+                }
+
+                return parser_transition(parser, raw, STATE_CSI_IGNORE, ACTION_NONE);
+        case STATE_CSI_PARAM:
+                switch (raw) {
+                case 0x00 ... 0x1f:     /* C0 */
+                        return parser_transition(parser, raw, STATE_NONE, ACTION_EXECUTE);
+                case 0x20 ... 0x2f:     /* [' ' - '\'] */
+                        return parser_transition(parser, raw, STATE_CSI_INT, ACTION_COLLECT);
+                case 0x30 ... 0x39:     /* ['0' - '9'] */
+                case 0x3b:              /* ';' */
+                        return parser_transition(parser, raw, STATE_NONE, ACTION_PARAM);
+                case 0x3a:              /* ':' */
+                case 0x3c ... 0x3f:     /* ['<' - '?'] */
+                        return parser_transition(parser, raw, STATE_CSI_IGNORE, ACTION_NONE);
+                case 0x40 ... 0x7e:     /* ['@' - '~'] */
+                        return parser_transition(parser, raw, STATE_GROUND, ACTION_CSI_DISPATCH);
+                case 0x7f:              /* DEL */
+                        return parser_transition(parser, raw, STATE_NONE, ACTION_IGNORE);
+                case 0x9c:              /* ST */
+                        return parser_transition(parser, raw, STATE_GROUND, ACTION_IGNORE);
+                }
+
+                return parser_transition(parser, raw, STATE_CSI_IGNORE, ACTION_NONE);
+        case STATE_CSI_INT:
+                switch (raw) {
+                case 0x00 ... 0x1f:     /* C0 */
+                        return parser_transition(parser, raw, STATE_NONE, ACTION_EXECUTE);
+                case 0x20 ... 0x2f:     /* [' ' - '\'] */
+                        return parser_transition(parser, raw, STATE_NONE, ACTION_COLLECT);
+                case 0x30 ... 0x3f:     /* ['0' - '?'] */
+                        return parser_transition(parser, raw, STATE_CSI_IGNORE, ACTION_NONE);
+                case 0x40 ... 0x7e:     /* ['@' - '~'] */
+                        return parser_transition(parser, raw, STATE_GROUND, ACTION_CSI_DISPATCH);
+                case 0x7f:              /* DEL */
+                        return parser_transition(parser, raw, STATE_NONE, ACTION_IGNORE);
+                case 0x9c:              /* ST */
+                        return parser_transition(parser, raw, STATE_GROUND, ACTION_IGNORE);
+                }
+
+                return parser_transition(parser, raw, STATE_CSI_IGNORE, ACTION_NONE);
+        case STATE_CSI_IGNORE:
+                switch (raw) {
+                case 0x00 ... 0x1f:     /* C0 */
+                        return parser_transition(parser, raw, STATE_NONE, ACTION_EXECUTE);
+                case 0x20 ... 0x3f:     /* [' ' - '?'] */
+                        return parser_transition(parser, raw, STATE_NONE, ACTION_NONE);
+                case 0x40 ... 0x7e:     /* ['@' - '~'] */
+                        return parser_transition(parser, raw, STATE_GROUND, ACTION_NONE);
+                case 0x7f:              /* DEL */
+                        return parser_transition(parser, raw, STATE_NONE, ACTION_IGNORE);
+                case 0x9c:              /* ST */
+                        return parser_transition(parser, raw, STATE_GROUND, ACTION_IGNORE);
+                }
+
+                return parser_transition(parser, raw, STATE_NONE, ACTION_NONE);
+        case STATE_DCS_ENTRY:
+                switch (raw) {
+                case 0x00 ... 0x1f:     /* C0 */
+                        return parser_transition(parser, raw, STATE_NONE, ACTION_IGNORE);
+                case 0x20 ... 0x2f:     /* [' ' - '\'] */
+                        return parser_transition(parser, raw, STATE_DCS_INT, ACTION_COLLECT);
+                case 0x3a:              /* ':' */
+                        return parser_transition(parser, raw, STATE_DCS_IGNORE, ACTION_NONE);
+                case 0x30 ... 0x39:     /* ['0' - '9'] */
+                case 0x3b:              /* ';' */
+                        return parser_transition(parser, raw, STATE_DCS_PARAM, ACTION_PARAM);
+                case 0x3c ... 0x3f:     /* ['<' - '?'] */
+                        return parser_transition(parser, raw, STATE_DCS_PARAM, ACTION_COLLECT);
+                case 0x40 ... 0x7e:     /* ['@' - '~'] */
+                        return parser_transition(parser, raw, STATE_DCS_PASS, ACTION_DCS_CONSUME);
+                case 0x7f:              /* DEL */
+                        return parser_transition(parser, raw, STATE_NONE, ACTION_IGNORE);
+                case 0x9c:              /* ST */
+                        return parser_transition(parser, raw, STATE_GROUND, ACTION_IGNORE);
+                }
+
+                return parser_transition(parser, raw, STATE_DCS_PASS, ACTION_DCS_CONSUME);
+        case STATE_DCS_PARAM:
+                switch (raw) {
+                case 0x00 ... 0x1f:     /* C0 */
+                        return parser_transition(parser, raw, STATE_NONE, ACTION_IGNORE);
+                case 0x20 ... 0x2f:     /* [' ' - '\'] */
+                        return parser_transition(parser, raw, STATE_DCS_INT, ACTION_COLLECT);
+                case 0x30 ... 0x39:     /* ['0' - '9'] */
+                case 0x3b:              /* ';' */
+                        return parser_transition(parser, raw, STATE_NONE, ACTION_PARAM);
+                case 0x3a:              /* ':' */
+                case 0x3c ... 0x3f:     /* ['<' - '?'] */
+                        return parser_transition(parser, raw, STATE_DCS_IGNORE, ACTION_NONE);
+                case 0x40 ... 0x7e:     /* ['@' - '~'] */
+                        return parser_transition(parser, raw, STATE_DCS_PASS, ACTION_DCS_CONSUME);
+                case 0x7f:              /* DEL */
+                        return parser_transition(parser, raw, STATE_NONE, ACTION_IGNORE);
+                case 0x9c:              /* ST */
+                        return parser_transition(parser, raw, STATE_GROUND, ACTION_IGNORE);
+                }
+
+                return parser_transition(parser, raw, STATE_DCS_PASS, ACTION_DCS_CONSUME);
+        case STATE_DCS_INT:
+                switch (raw) {
+                case 0x00 ... 0x1f:     /* C0 */
+                        return parser_transition(parser, raw, STATE_NONE, ACTION_IGNORE);
+                case 0x20 ... 0x2f:     /* [' ' - '\'] */
+                        return parser_transition(parser, raw, STATE_NONE, ACTION_COLLECT);
+                case 0x30 ... 0x3f:     /* ['0' - '?'] */
+                        return parser_transition(parser, raw, STATE_DCS_IGNORE, ACTION_NONE);
+                case 0x40 ... 0x7e:     /* ['@' - '~'] */
+                        return parser_transition(parser, raw, STATE_DCS_PASS, ACTION_DCS_CONSUME);
+                case 0x7f:              /* DEL */
+                        return parser_transition(parser, raw, STATE_NONE, ACTION_IGNORE);
+                case 0x9c:              /* ST */
+                        return parser_transition(parser, raw, STATE_GROUND, ACTION_IGNORE);
+                }
+
+                return parser_transition(parser, raw, STATE_DCS_PASS, ACTION_DCS_CONSUME);
+        case STATE_DCS_PASS:
+                switch (raw) {
+                case 0x00 ... 0x7e:     /* ASCII \ { DEL } */
+                        return parser_transition(parser, raw, STATE_NONE, ACTION_DCS_COLLECT);
+                case 0x7f:              /* DEL */
+                        return parser_transition(parser, raw, STATE_NONE, ACTION_IGNORE);
+                case 0x9c:              /* ST */
+                        return parser_transition(parser, raw, STATE_GROUND, ACTION_DCS_DISPATCH);
+                }
+
+                return parser_transition(parser, raw, STATE_NONE, ACTION_DCS_COLLECT);
+        case STATE_DCS_IGNORE:
+                switch (raw) {
+                case 0x00 ... 0x7f:     /* ASCII */
+                        return parser_transition(parser, raw, STATE_NONE, ACTION_IGNORE);
+                case 0x9c:              /* ST */
+                        return parser_transition(parser, raw, STATE_GROUND, ACTION_NONE);
+                }
+
+                return parser_transition(parser, raw, STATE_NONE, ACTION_NONE);
+        case STATE_OSC_STRING:
+                switch (raw) {
+                case 0x00 ... 0x06:     /* C0 \ { BEL } */
+                case 0x08 ... 0x1f:
+                        return parser_transition(parser, raw, STATE_NONE, ACTION_IGNORE);
+                case 0x20 ... 0x7f:     /* [' ' - DEL] */
+                        return parser_transition(parser, raw, STATE_NONE, ACTION_OSC_COLLECT);
+                case 0x07:              /* BEL */
+                case 0x9c:              /* ST */
+                        return parser_transition(parser, raw, STATE_GROUND, ACTION_OSC_DISPATCH);
+                }
+
+                return parser_transition(parser, raw, STATE_NONE, ACTION_OSC_COLLECT);
+        case STATE_ST_IGNORE:
+                switch (raw) {
+                case 0x00 ... 0x7f:     /* ASCII */
+                        return parser_transition(parser, raw, STATE_NONE, ACTION_IGNORE);
+                case 0x9c:              /* ST */
+                        return parser_transition(parser, raw, STATE_GROUND, ACTION_IGNORE);
+                }
+
+                return parser_transition(parser, raw, STATE_NONE, ACTION_NONE);
+        }
+
+        assert_not_reached("bad vte-parser state");
+        return -EINVAL;
+}
+
+int term_parser_feed(term_parser *parser, const term_seq **seq_out, uint32_t raw) {
+        int r;
+
+        assert_return(parser, -EINVAL);
+        assert_return(seq_out, -EINVAL);
+
+        /*
+         * Notes:
+         *  * DEC treats GR codes as GL. We don't do that as we require UTF-8
+         *    as charset and, thus, it doesn't make sense to treat GR special.
+         *  * During control sequences, unexpected C1 codes cancel the sequence
+         *    and immediately start a new one. C0 codes, however, may or may not
+         *    be ignored/executed depending on the sequence.
+         */
+
+        switch (raw) {
+        case 0x18:              /* CAN */
+                r = parser_transition(parser, raw, STATE_GROUND, ACTION_IGNORE);
+                break;
+        case 0x1a:              /* SUB */
+                r = parser_transition(parser, raw, STATE_GROUND, ACTION_EXECUTE);
+                break;
+        case 0x80 ... 0x8f:     /* C1 \ {DCS, SOS, CSI, ST, OSC, PM, APC} */
+        case 0x91 ... 0x97:
+        case 0x99 ... 0x9a:
+                r = parser_transition(parser, raw, STATE_GROUND, ACTION_EXECUTE);
+                break;
+        case 0x1b:              /* ESC */
+                r = parser_transition(parser, raw, STATE_ESC, ACTION_CLEAR);
+                break;
+        case 0x98:              /* SOS */
+        case 0x9e:              /* PM */
+        case 0x9f:              /* APC */
+                r = parser_transition(parser, raw, STATE_ST_IGNORE, ACTION_NONE);
+                break;
+        case 0x90:              /* DCS */
+                r = parser_transition(parser, raw, STATE_DCS_ENTRY, ACTION_CLEAR);
+                break;
+        case 0x9d:              /* OSC */
+                r = parser_transition(parser, raw, STATE_OSC_STRING, ACTION_CLEAR);
+                break;
+        case 0x9b:              /* CSI */
+                r = parser_transition(parser, raw, STATE_CSI_ENTRY, ACTION_CLEAR);
+                break;
+        default:
+                r = parser_feed_to_state(parser, raw);
+                break;
+        }
+
+        if (r <= 0)
+                *seq_out = NULL;
+        else
+                *seq_out = &parser->seq;
+
+        return r;
+}
diff --git a/src/libsystemd-terminal/term-screen.c b/src/libsystemd-terminal/term-screen.c
new file mode 100644 (file)
index 0000000..a19c684
--- /dev/null
@@ -0,0 +1,3882 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright (C) 2014 David Herrmann <dh.herrmann@gmail.com>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+/*
+ * Terminal Screens
+ * The term_screen layer implements the terminal-side. It handles all commands
+ * returned by the seq-parser and applies them to its own pages.
+ *
+ * While there are a lot of legacy control-sequences, we only support a small
+ * subset. There is no reason to implement unused codes like horizontal
+ * scrolling.
+ * If you implement new commands, make sure to document them properly.
+ *
+ * Standards:
+ *   ECMA-48
+ *   ANSI X3.64
+ *   ISO/IEC 6429
+ * References:
+ *   http://www.vt100.net/emu/ctrlseq_dec.html
+ *   http://www.vt100.net/docs/vt100-ug/chapter3.html
+ *   http://www.vt100.net/docs/vt510-rm/chapter4
+ *   http://www.vt100.net/docs/vt510-rm/contents
+ *   http://invisible-island.net/xterm/ctlseqs/ctlseqs.html
+ *   ASCII
+ *   http://en.wikipedia.org/wiki/C0_and_C1_control_codes
+ *   https://en.wikipedia.org/wiki/ANSI_color
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include "macro.h"
+#include "term-internal.h"
+#include "util.h"
+
+int term_screen_new(term_screen **out, term_screen_write_fn write_fn, void *write_fn_data, term_screen_cmd_fn cmd_fn, void *cmd_fn_data) {
+        _cleanup_(term_screen_unrefp) term_screen *screen = NULL;
+        int r;
+
+        assert_return(out, -EINVAL);
+
+        screen = new0(term_screen, 1);
+        if (!screen)
+                return -ENOMEM;
+
+        screen->ref = 1;
+        screen->age = 1;
+        screen->write_fn = write_fn;
+        screen->write_fn_data = write_fn_data;
+        screen->cmd_fn = cmd_fn;
+        screen->cmd_fn_data = cmd_fn_data;
+        screen->flags = TERM_FLAG_7BIT_MODE;
+        screen->conformance_level = TERM_CONFORMANCE_LEVEL_VT400;
+        screen->gl = &screen->g0;
+        screen->gr = &screen->g1;
+        screen->g0 = &term_unicode_lower;
+        screen->g1 = &term_unicode_upper;
+        screen->g2 = &term_unicode_lower;
+        screen->g3 = &term_unicode_upper;
+
+        screen->saved.cursor_x = 0;
+        screen->saved.cursor_y = 0;
+        screen->saved.attr = screen->attr;
+        screen->saved.gl = screen->gl;
+        screen->saved.gr = screen->gr;
+
+        r = term_page_new(&screen->page_main);
+        if (r < 0)
+                return r;
+
+        r = term_page_new(&screen->page_alt);
+        if (r < 0)
+                return r;
+
+        r = term_parser_new(&screen->parser, false);
+        if (r < 0)
+                return r;
+
+        r = term_history_new(&screen->history_main);
+        if (r < 0)
+                return r;
+
+        screen->page = screen->page_main;
+        screen->history = screen->history_main;
+
+        *out = screen;
+        screen = NULL;
+        return 0;
+}
+
+term_screen *term_screen_ref(term_screen *screen) {
+        if (!screen)
+                return NULL;
+
+        assert_return(screen->ref > 0, NULL);
+
+        ++screen->ref;
+        return screen;
+}
+
+term_screen *term_screen_unref(term_screen *screen) {
+        if (!screen)
+                return NULL;
+
+        assert_return(screen->ref > 0, NULL);
+
+        if (--screen->ref)
+                return NULL;
+
+        free(screen->answerback);
+        free(screen->tabs);
+        term_history_free(screen->history_main);
+        term_page_free(screen->page_alt);
+        term_page_free(screen->page_main);
+        term_parser_free(screen->parser);
+        free(screen);
+
+        return NULL;
+}
+
+/*
+ * Write-Helpers
+ * Unfortunately, 7bit/8bit compat mode requires us to send C1 controls encoded
+ * as 7bit if asked by the application. This is really used in the wild, so we
+ * cannot fall back to "always 7bit".
+ * screen_write() is the underlying backend which forwards any writes to the
+ * users's callback. It's the users responsibility to buffer these and write
+ * them out once their call to term_screen_feed_*() returns.
+ * The SEQ_WRITE() and SEQ_WRITE_KEY() macros allow constructing C0/C1 sequences
+ * directly in the code-base without requiring any intermediate buffer during
+ * runtime.
+ */
+
+#define C0_CSI "\e["
+#define C1_CSI "\x9b"
+
+#define SEQ(_screen, _prefix_esc, _c0, _c1, _seq) \
+                (((_screen)->flags & TERM_FLAG_7BIT_MODE) ? \
+                        ((_prefix_esc) ? ("\e" _c0 _seq) : (_c0 _seq)) : \
+                        ((_prefix_esc) ? ("\e" _c1 _seq) : (_c1 _seq)))
+
+#define SEQ_SIZE(_screen, _prefix_esc, _c0, _c1, _seq) \
+                (((_screen)->flags & TERM_FLAG_7BIT_MODE) ? \
+                        ((_prefix_esc) ? sizeof("\e" _c0 _seq) : sizeof(_c0 _seq)) : \
+                        ((_prefix_esc) ? sizeof("\e" _c1 _seq) : sizeof(_c1 _seq)))
+
+#define SEQ_WRITE_KEY(_screen, _prefix_esc, _c0, _c1, _seq) \
+                screen_write((_screen), \
+                             SEQ((_screen), (_prefix_esc), \
+                                 _c0, _c1, _seq), \
+                             SEQ_SIZE((_screen), (_prefix_esc), \
+                                     _c0, _c1, _seq) - 1)
+
+#define SEQ_WRITE(_screen, _c0, _c1, _seq) \
+                SEQ_WRITE_KEY((_screen), false, _c0, _c1, _seq)
+
+static int screen_write(term_screen *screen, const void *buf, size_t len) {
+        if (len < 1 || !screen->write_fn)
+                return 0;
+
+        return screen->write_fn(screen, screen->write_fn_data, buf, len);
+}
+
+/*
+ * Command Forwarding
+ * Some commands cannot be handled by the screen-layer directly. Those are
+ * forwarded to the command-handler of the caller. This is rarely used and can
+ * safely be set to NULL.
+ */
+
+static int screen_forward(term_screen *screen, unsigned int cmd, const term_seq *seq) {
+        if (!screen->cmd_fn)
+                return 0;
+
+        return screen->cmd_fn(screen, screen->cmd_fn_data, cmd, seq);
+}
+
+/*
+ * Screen Helpers
+ * These helpers implement common-operations like cursor-handler and more, which
+ * are used by several command dispatchers.
+ */
+
+static unsigned int screen_clamp_x(term_screen *screen, unsigned int x) {
+        if (x >= screen->page->width)
+                return (screen->page->width > 0) ? screen->page->width - 1 : 0;
+
+        return x;
+}
+
+static unsigned int screen_clamp_y(term_screen *screen, unsigned int y) {
+        if (y >= screen->page->height)
+                return (screen->page->height > 0) ? screen->page->height - 1 : 0;
+
+        return y;
+}
+
+static bool screen_tab_is_set(term_screen *screen, unsigned int pos) {
+        if (pos >= screen->page->width)
+                return false;
+
+        return screen->tabs[pos / 8] & (1 << (pos % 8));
+}
+
+static inline void screen_age_cursor(term_screen *screen) {
+        term_cell *cell;
+
+        cell = term_page_get_cell(screen->page, screen->cursor_x, screen->cursor_y);
+        if (cell)
+                cell->age = screen->age;
+}
+
+static void screen_cursor_clear_wrap(term_screen *screen) {
+        screen->flags &= ~TERM_FLAG_PENDING_WRAP;
+}
+
+static void screen_cursor_set(term_screen *screen, unsigned int x, unsigned int y) {
+        x = screen_clamp_x(screen, x);
+        y = screen_clamp_y(screen, y);
+
+        if (x == screen->cursor_x && y == screen->cursor_y)
+                return;
+
+        if (!(screen->flags & TERM_FLAG_HIDE_CURSOR))
+                screen_age_cursor(screen);
+
+        screen->cursor_x = x;
+        screen->cursor_y = y;
+
+        if (!(screen->flags & TERM_FLAG_HIDE_CURSOR))
+                screen_age_cursor(screen);
+}
+
+static void screen_cursor_set_rel(term_screen *screen, unsigned int x, unsigned int y) {
+        if (screen->flags & TERM_FLAG_ORIGIN_MODE) {
+                x = screen_clamp_x(screen, x);
+                y = screen_clamp_x(screen, y) + screen->page->scroll_idx;
+
+                if (y >= screen->page->scroll_idx + screen->page->scroll_num) {
+                        y = screen->page->scroll_idx + screen->page->scroll_num;
+                        if (screen->page->scroll_num > 0)
+                                y -= 1;
+                }
+        }
+
+        screen_cursor_set(screen, x, y);
+}
+
+static void screen_cursor_left(term_screen *screen, unsigned int num) {
+        if (num > screen->cursor_x)
+                num = screen->cursor_x;
+
+        screen_cursor_set(screen, screen->cursor_x - num, screen->cursor_y);
+}
+
+static void screen_cursor_left_tab(term_screen *screen, unsigned int num) {
+        unsigned int i;
+
+        i = screen->cursor_x;
+        while (i > 0 && num > 0) {
+                if (screen_tab_is_set(screen, --i))
+                        --num;
+        }
+
+        screen_cursor_set(screen, i, screen->cursor_y);
+}
+
+static void screen_cursor_right(term_screen *screen, unsigned int num) {
+        if (num > screen->page->width)
+                num = screen->page->width;
+
+        screen_cursor_set(screen, screen->cursor_x + num, screen->cursor_y);
+}
+
+static void screen_cursor_right_tab(term_screen *screen, unsigned int num) {
+        unsigned int i;
+
+        i = screen->cursor_x;
+        while (i + 1 < screen->page->width && num > 0) {
+                if (screen_tab_is_set(screen, ++i))
+                        --num;
+        }
+
+        screen_cursor_set(screen, i, screen->cursor_y);
+}
+
+static void screen_cursor_up(term_screen *screen, unsigned int num, bool scroll) {
+        unsigned int max;
+
+        if (screen->cursor_y < screen->page->scroll_idx) {
+                if (num > screen->cursor_y)
+                        num = screen->cursor_y;
+
+                screen_cursor_set(screen, screen->cursor_x, screen->cursor_y - num);
+        } else {
+                max = screen->cursor_y - screen->page->scroll_idx;
+                if (num > max) {
+                        if (num < 1)
+                                return;
+
+                        if (!(screen->flags & TERM_FLAG_HIDE_CURSOR))
+                                screen_age_cursor(screen);
+
+                        if (scroll)
+                                term_page_scroll_down(screen->page, num - max, &screen->attr, screen->age, NULL);
+
+                        screen->cursor_y = screen->page->scroll_idx;
+
+                        if (!(screen->flags & TERM_FLAG_HIDE_CURSOR))
+                                screen_age_cursor(screen);
+                } else {
+                        screen_cursor_set(screen, screen->cursor_x, screen->cursor_y - num);
+                }
+        }
+}
+
+static void screen_cursor_down(term_screen *screen, unsigned int num, bool scroll) {
+        unsigned int max;
+
+        if (screen->cursor_y >= screen->page->scroll_idx + screen->page->scroll_num) {
+                if (num > screen->page->height)
+                        num = screen->page->height;
+
+                screen_cursor_set(screen, screen->cursor_x, screen->cursor_y - num);
+        } else {
+                max = screen->page->scroll_idx + screen->page->scroll_num - 1 - screen->cursor_y;
+                if (num > max) {
+                        if (num < 1)
+                                return;
+
+                        if (!(screen->flags & TERM_FLAG_HIDE_CURSOR))
+                                screen_age_cursor(screen);
+
+                        if (scroll)
+                                term_page_scroll_up(screen->page, num - max, &screen->attr, screen->age, screen->history);
+
+                        screen->cursor_y = screen->page->scroll_idx + screen->page->scroll_num - 1;
+
+                        if (!(screen->flags & TERM_FLAG_HIDE_CURSOR))
+                                screen_age_cursor(screen);
+                } else {
+                        screen_cursor_set(screen, screen->cursor_x, screen->cursor_y + num);
+                }
+        }
+}
+
+static inline void set_reset(term_screen *screen, unsigned int flag, bool set) {
+        if (set)
+                screen->flags |= flag;
+        else
+                screen->flags &= ~flag;
+}
+
+static void screen_mode_change(term_screen *screen, unsigned int mode, bool dec, bool set) {
+        switch (mode) {
+        case 1:
+                if (dec) {
+                        /*
+                         * DECCKM: cursor-keys
+                         * TODO
+                         */
+                        set_reset(screen, TERM_FLAG_CURSOR_KEYS, set);
+                }
+
+                break;
+        case 6:
+                if (dec) {
+                        /*
+                         * DECOM: origin-mode
+                         * TODO
+                         */
+                        set_reset(screen, TERM_FLAG_ORIGIN_MODE, set);
+                }
+
+                break;
+        case 7:
+                if (dec) {
+                        /*
+                         * DECAWN: auto-wrap mode
+                         * TODO
+                         */
+                        set_reset(screen, TERM_FLAG_AUTO_WRAP, set);
+                }
+
+                break;
+        case 20:
+                if (!dec) {
+                        /*
+                         * LNM: line-feed/new-line mode
+                         * TODO
+                         */
+                        set_reset(screen, TERM_FLAG_NEWLINE_MODE, set);
+                }
+
+                break;
+        case 25:
+                if (dec) {
+                        /*
+                         * DECTCEM: text-cursor-enable
+                         * TODO
+                         */
+                        set_reset(screen, TERM_FLAG_HIDE_CURSOR, !set);
+                }
+
+                break;
+        }
+}
+
+/* map a character according to current GL and GR maps */
+static uint32_t screen_map(term_screen *screen, uint32_t val) {
+        uint32_t nval = -1U;
+
+        /* 32 and 127 always map to identity. 160 and 255 map to identity iff a
+         * 96 character set is loaded into GR. Values above 255 always map to
+         * identity. */
+        switch (val) {
+        case 33 ... 126:
+                if (screen->glt) {
+                        nval = (**screen->glt)[val - 32];
+                        screen->glt = NULL;
+                } else {
+                        nval = (**screen->gl)[val - 32];
+                }
+                break;
+        case 160 ... 255:
+                if (screen->grt) {
+                        nval = (**screen->grt)[val - 160];
+                        screen->grt = NULL;
+                } else {
+                        nval = (**screen->gr)[val - 160];
+                }
+                break;
+        }
+
+        return (nval == -1U) ? val : nval;
+}
+
+/*
+ * Command Handlers
+ * This is the inofficial documentation of all the TERM_CMD_* definitions. Each
+ * handled command has a separate function with an extensive comment on the
+ * semantics of the command.
+ * Note that many semantics are unknown and need to be verified. This is mostly
+ * about error-handling, though. Applications rarely rely on those features.
+ */
+
+static int screen_DA1(term_screen *screen, const term_seq *seq);
+static int screen_LF(term_screen *screen, const term_seq *seq);
+
+static int screen_GRAPHIC(term_screen *screen, const term_seq *seq) {
+        term_char_t ch = TERM_CHAR_NULL;
+        uint32_t c;
+
+        if (screen->cursor_x + 1 == screen->page->width
+            && screen->flags & TERM_FLAG_PENDING_WRAP
+            && screen->flags & TERM_FLAG_AUTO_WRAP) {
+                screen_cursor_down(screen, 1, true);
+                screen_cursor_set(screen, 0, screen->cursor_y);
+        }
+
+        screen_cursor_clear_wrap(screen);
+
+        c = screen_map(screen, seq->terminator);
+        ch = term_char_merge(ch, screen_map(screen, c));
+        term_page_write(screen->page, screen->cursor_x, screen->cursor_y, ch, 1, &screen->attr, screen->age, false);
+
+        if (screen->cursor_x + 1 == screen->page->width)
+                screen->flags |= TERM_FLAG_PENDING_WRAP;
+        else
+                screen_cursor_right(screen, 1);
+
+        return 0;
+}
+
+static int screen_BEL(term_screen *screen, const term_seq *seq) {
+        /*
+         * BEL - sound bell tone
+         * This command should trigger an acoustic bell. Usually, this is
+         * forwarded directly to the pcspkr. However, bells have become quite
+         * uncommon and annoying, so we're not implementing them here. Instead,
+         * it's one of the commands we forward to the caller.
+         */
+
+        return screen_forward(screen, TERM_CMD_BEL, seq);
+}
+
+static int screen_BS(term_screen *screen, const term_seq *seq) {
+        /*
+         * BS - backspace
+         * Move cursor one cell to the left. If already at the left margin,
+         * nothing happens.
+         */
+
+        screen_cursor_clear_wrap(screen);
+        screen_cursor_left(screen, 1);
+        return 0;
+}
+
+static int screen_CBT(term_screen *screen, const term_seq *seq) {
+        /*
+         * CBT - cursor-backward-tabulation
+         * Move the cursor @args[0] tabs backwards (to the left). The
+         * current cursor cell, in case it's a tab, is not counted.
+         * Furthermore, the cursor cannot be moved beyond position 0 and
+         * it will stop there.
+         *
+         * Defaults:
+         *   args[0]: 1
+         */
+
+        unsigned int num = 1;
+
+        if (seq->args[0] > 0)
+                num = seq->args[0];
+
+        screen_cursor_clear_wrap(screen);
+        screen_cursor_left_tab(screen, num);
+
+        return 0;
+}
+
+static int screen_CHA(term_screen *screen, const term_seq *seq) {
+        /*
+         * CHA - cursor-horizontal-absolute
+         * Move the cursor to position @args[0] in the current line. The
+         * cursor cannot be moved beyond the rightmost cell and will stop
+         * there.
+         *
+         * Defaults:
+         *   args[0]: 1
+         */
+
+        unsigned int pos = 1;
+
+        if (seq->args[0] > 0)
+                pos = seq->args[0];
+
+        screen_cursor_clear_wrap(screen);
+        screen_cursor_set(screen, pos - 1, screen->cursor_y);
+
+        return 0;
+}
+
+static int screen_CHT(term_screen *screen, const term_seq *seq) {
+        /*
+         * CHT - cursor-horizontal-forward-tabulation
+         * Move the cursor @args[0] tabs forward (to the right). The
+         * current cursor cell, in case it's a tab, is not counted.
+         * Furthermore, the cursor cannot be moved beyond the rightmost cell
+         * and will stop there.
+         *
+         * Defaults:
+         *   args[0]: 1
+         */
+
+        unsigned int num = 1;
+
+        if (seq->args[0] > 0)
+                num = seq->args[0];
+
+        screen_cursor_clear_wrap(screen);
+        screen_cursor_right_tab(screen, num);
+
+        return 0;
+}
+
+static int screen_CNL(term_screen *screen, const term_seq *seq) {
+        /*
+         * CNL - cursor-next-line
+         * Move the cursor @args[0] lines down.
+         *
+         * TODO: Does this stop at the bottom or cause a scroll-up?
+         *
+         * Defaults:
+         *   args[0]: 1
+         */
+
+        unsigned int num = 1;
+
+        if (seq->args[0] > 0)
+                num = seq->args[0];
+
+        screen_cursor_clear_wrap(screen);
+        screen_cursor_down(screen, num, false);
+
+        return 0;
+}
+
+static int screen_CPL(term_screen *screen, const term_seq *seq) {
+        /*
+         * CPL - cursor-preceding-line
+         * Move the cursor @args[0] lines up.
+         *
+         * TODO: Does this stop at the top or cause a scroll-up?
+         *
+         * Defaults:
+         *   args[0]: 1
+         */
+
+        unsigned int num = 1;
+
+        if (seq->args[0] > 0)
+                num = seq->args[0];
+
+        screen_cursor_clear_wrap(screen);
+        screen_cursor_up(screen, num, false);
+
+        return 0;
+}
+
+static int screen_CR(term_screen *screen, const term_seq *seq) {
+        /*
+         * CR - carriage-return
+         * Move the cursor to the left margin on the current line.
+         */
+
+        screen_cursor_clear_wrap(screen);
+        screen_cursor_set(screen, 0, screen->cursor_y);
+
+        return 0;
+}
+
+static int screen_CUB(term_screen *screen, const term_seq *seq) {
+        /*
+         * CUB - cursor-backward
+         * Move the cursor @args[0] positions to the left. The cursor stops
+         * at the left-most position.
+         *
+         * Defaults:
+         *   args[0]: 1
+         */
+
+        unsigned int num = 1;
+
+        if (seq->args[0] > 0)
+                num = seq->args[0];
+
+        screen_cursor_clear_wrap(screen);
+        screen_cursor_left(screen, num);
+
+        return 0;
+}
+
+static int screen_CUD(term_screen *screen, const term_seq *seq) {
+        /*
+         * CUD - cursor-down
+         * Move the cursor @args[0] positions down. The cursor stops at the
+         * bottom margin. If it was already moved further, it stops at the
+         * bottom line.
+         *
+         * Defaults:
+         *   args[0]: 1
+         */
+
+        unsigned int num = 1;
+
+        if (seq->args[0] > 0)
+                num = seq->args[0];
+
+        screen_cursor_clear_wrap(screen);
+        screen_cursor_down(screen, num, false);
+
+        return 0;
+}
+
+static int screen_CUF(term_screen *screen, const term_seq *seq) {
+        /*
+         * CUF -cursor-forward
+         * Move the cursor @args[0] positions to the right. The cursor stops
+         * at the right-most position.
+         *
+         * Defaults:
+         *   args[0]: 1
+         */
+
+        unsigned int num = 1;
+
+        if (seq->args[0] > 0)
+                num = seq->args[0];
+
+        screen_cursor_clear_wrap(screen);
+        screen_cursor_right(screen, num);
+
+        return 0;
+}
+
+static int screen_CUP(term_screen *screen, const term_seq *seq) {
+        /*
+         * CUP - cursor-position
+         * Moves the cursor to position @args[1] x @args[0]. If either is 0, it
+         * is treated as 1. The positions are subject to the origin-mode and
+         * clamped to the addressable with/height.
+         *
+         * Defaults:
+         *   args[0]: 1
+         *   args[1]: 1
+         */
+
+        unsigned int x = 1, y = 1;
+
+        if (seq->args[0] > 0)
+                y = seq->args[0];
+        if (seq->args[1] > 0)
+                x = seq->args[1];
+
+        screen_cursor_clear_wrap(screen);
+        screen_cursor_set_rel(screen, x - 1, y - 1);
+
+        return 0;
+}
+
+static int screen_CUU(term_screen *screen, const term_seq *seq) {
+        /*
+         * CUU - cursor-up
+         * Move the cursor @args[0] positions up. The cursor stops at the
+         * top margin. If it was already moved further, it stops at the
+         * top line.
+         *
+         * Defaults:
+         *   args[0]: 1
+         *
+         */
+
+        unsigned int num = 1;
+
+        if (seq->args[0] > 0)
+                num = seq->args[0];
+
+        screen_cursor_clear_wrap(screen);
+        screen_cursor_up(screen, num, false);
+
+        return 0;
+}
+
+static int screen_DA1(term_screen *screen, const term_seq *seq) {
+        /*
+         * DA1 - primary-device-attributes
+         * The primary DA asks for basic terminal features. We simply return
+         * a hard-coded list of features we implement.
+         * Note that the primary DA asks for supported features, not currently
+         * enabled features.
+         *
+         * The terminal's answer is:
+         *   ^[ ? 64 ; ARGS c
+         * The first argument, 64, is fixed and denotes a VT420, the last
+         * DEC-term that extended this number.
+         * All following arguments denote supported features. Note
+         * that at most 15 features can be sent (max CSI args). It is safe to
+         * send more, but clients might not be able to parse them. This is a
+         * client's problem and we shouldn't care. There is no other way to
+         * send those feature lists, so we have to extend them beyond 15 in
+         * those cases.
+         *
+         * Known modes:
+         *    1: 132 column mode
+         *       The 132 column mode is supported by the terminal.
+         *    2: printer port
+         *       A priner-port is supported and can be addressed via
+         *       control-codes.
+         *    3: ReGIS graphics
+         *       Support for ReGIS graphics is available. The ReGIS routines
+         *       provide the "remote graphics instruction set" and allow basic
+         *       vector-rendering.
+         *    4: sixel
+         *       Support of Sixel graphics is available. This provides access
+         *       to the sixel bitmap routines.
+         *    6: selective erase
+         *       The terminal supports DECSCA and related selective-erase
+         *       functions. This allows to protect specific cells from being
+         *       erased, if specified.
+         *    7: soft character set (DRCS)
+         *       TODO: ?
+         *    8: user-defined keys (UDKs)
+         *       TODO: ?
+         *    9: national-replacement character sets (NRCS)
+         *       National-replacement character-sets are available.
+         *   12: Yugoslavian (SCS)
+         *       TODO: ?
+         *   15: technical character set
+         *       The DEC technical-character-set is available.
+         *   18: windowing capability
+         *       TODO: ?
+         *   21: horizontal scrolling
+         *       TODO: ?
+         *   22: ANSII color
+         *       TODO: ?
+         *   23: Greek
+         *       TODO: ?
+         *   24: Turkish
+         *       TODO: ?
+         *   29: ANSI text locator
+         *       TODO: ?
+         *   42: ISO Latin-2 character set
+         *       TODO: ?
+         *   44: PCTerm
+         *       TODO: ?
+         *   45: soft keymap
+         *       TODO: ?
+         *   46: ASCII emulation
+         *       TODO: ?
+         */
+
+        return SEQ_WRITE(screen, C0_CSI, C1_CSI, "?64;1;6;9;15c");
+}
+
+static int screen_DA2(term_screen *screen, const term_seq *seq) {
+        /*
+         * DA2 - secondary-device-attributes
+         * The secondary DA asks for the terminal-ID, firmware versions and
+         * other non-primary attributes. All these values are
+         * informational-only and should not be used by the host to detect
+         * terminal features.
+         *
+         * The terminal's response is:
+         *   ^[ > 61 ; FIRMWARE ; KEYBOARD c
+         * whereas 65 is fixed for VT525 terminals, the last terminal-line that
+         * increased this number. FIRMWARE is the firmware
+         * version encoded as major/minor (20 == 2.0) and KEYBOARD is 0 for STD
+         * keyboard and 1 for PC keyboards.
+         *
+         * We replace the firmware-version with the systemd-version so clients
+         * can decode it again.
+         */
+
+        return SEQ_WRITE(screen, C0_CSI, C1_CSI, ">65;" PACKAGE_VERSION ";1c");
+}
+
+static int screen_DA3(term_screen *screen, const term_seq *seq) {
+        /*
+         * DA3 - tertiary-device-attributes
+         * The tertiary DA is used to query the terminal-ID.
+         *
+         * The terminal's response is:
+         *   ^P ! | XX AA BB CC ^\
+         * whereas all four parameters are hexadecimal-encoded pairs. XX
+         * denotes the manufacturing site, AA BB CC is the terminal's ID.
+         */
+
+        /* we do not support tertiary DAs */
+        return 0;
+}
+
+static int screen_DC1(term_screen *screen, const term_seq *seq) {
+        /*
+         * DC1 - device-control-1 or XON
+         * This clears any previous XOFF and resumes terminal-transmission.
+         */
+
+        /* we do not support XON */
+        return 0;
+}
+
+static int screen_DC3(term_screen *screen, const term_seq *seq) {
+        /*
+         * DC3 - device-control-3 or XOFF
+         * Stops terminal transmission. No further characters are sent until
+         * an XON is received.
+         */
+
+        /* we do not support XOFF */
+        return 0;
+}
+
+static int screen_DCH(term_screen *screen, const term_seq *seq) {
+        /*
+         * DCH - delete-character
+         * This deletes @argv[0] characters at the current cursor position. As
+         * characters are deleted, the remaining characters between the cursor
+         * and right margin move to the left. Character attributes move with the
+         * characters. The terminal adds blank spaces with no visual character
+         * attributes at the right margin. DCH has no effect outside the
+         * scrolling margins.
+         *
+         * Defaults:
+         *   args[0]: 1
+         */
+
+        unsigned int num = 1;
+
+        if (seq->args[0] > 0)
+                num = seq->args[0];
+
+        screen_cursor_clear_wrap(screen);
+        term_page_delete_cells(screen->page, screen->cursor_x, screen->cursor_y, num, &screen->attr, screen->age);
+
+        return 0;
+}
+
+static int screen_DECALN(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECALN - screen-alignment-pattern
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECANM(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECANM - ansi-mode
+         * Set the terminal into VT52 compatibility mode. Control sequences
+         * overlap with regular sequences so we have to detect them early before
+         * dispatching them.
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECBI(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECBI - back-index
+         * This control function moves the cursor backward one column. If the
+         * cursor is at the left margin, then all screen data within the margin
+         * moves one column to the right. The column that shifted past the right
+         * margin is lost.
+         * DECBI adds a new column at the left margin with no visual attributes.
+         * DECBI does not affect the margins. If the cursor is beyond the
+         * left-margin at the left border, then the terminal ignores DECBI.
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECCARA(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECCARA - change-attributes-in-rectangular-area
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECCRA(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECCRA - copy-rectangular-area
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECDC(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECDC - delete-column
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECDHL_BH(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECDHL_BH - double-width-double-height-line: bottom half
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECDHL_TH(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECDHL_TH - double-width-double-height-line: top half
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECDWL(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECDWL - double-width-single-height-line
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECEFR(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECEFR - enable-filter-rectangle
+         * Defines the coordinates of a filter rectangle (top, left, bottom,
+         * right as @args[0] to @args[3]) and activates it.
+         * Anytime the locator is detected outside of the filter rectangle, an
+         * outside rectangle event is generated and the rectangle is disabled.
+         * Filter rectangles are always treated as "one-shot" events. Any
+         * parameters that are omitted default to the current locator position.
+         * If all parameters are omitted, any locator motion will be reported.
+         * DECELR always cancels any prevous rectangle definition.
+         *
+         * The locator is usually associated with the mouse-cursor, but based
+         * on cells instead of pixels. See DECELR how to initialize and enable
+         * it. DECELR can also enable pixel-mode instead of cell-mode.
+         *
+         * TODO: implement
+         */
+
+        return 0;
+}
+
+static int screen_DECELF(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECELF - enable-local-functions
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECELR(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECELR - enable-locator-reporting
+         * This changes the locator-reporting mode. @args[0] specifies the mode
+         * to set, 0 disables locator-reporting, 1 enables it continously, 2
+         * enables it for a single report. @args[1] specifies the
+         * precision-mode. 0 and 2 set the reporting to cell-precision, 1 sets
+         * pixel-precision.
+         *
+         * Defaults:
+         *   args[0]: 0
+         *   args[1]: 0
+         *
+         * TODO: implement
+         */
+
+        return 0;
+}
+
+static int screen_DECERA(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECERA - erase-rectangular-area
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECFI(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECFI - forward-index
+         * This control function moves the cursor forward one column. If the
+         * cursor is at the right margin, then all screen data within the
+         * margins moves one column to the left. The column shifted past the
+         * left margin is lost.
+         * DECFI adds a new column at the right margin, with no visual
+         * attributes. DECFI does not affect margins. If the cursor is beyond
+         * the right margin at the border of the page when the terminal
+         * receives DECFI, then the terminal ignores DECFI.
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECFRA(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECFRA - fill-rectangular-area
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECIC(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECIC - insert-column
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECID(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECID - return-terminal-id
+         * This is an obsolete form of TERM_CMD_DA1.
+         */
+
+        return screen_DA1(screen, seq);
+}
+
+static int screen_DECINVM(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECINVM - invoke-macro
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECKBD(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECKBD - keyboard-language-selection
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECKPAM(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECKPAM - keypad-application-mode
+         * Enables the keypad-application mode. If enabled, the keypad sends
+         * special characters instead of the printed characters. This way,
+         * applications can detect whether a numeric key was pressed on the
+         * top-row or on the keypad.
+         * Default is keypad-numeric-mode.
+         */
+
+        screen->flags |= TERM_FLAG_KEYPAD_MODE;
+
+        return 0;
+}
+
+static int screen_DECKPNM(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECKPNM - keypad-numeric-mode
+         * This disables the keypad-application-mode (DECKPAM) and returns to
+         * the keypad-numeric-mode. Keypresses on the keypad generate the same
+         * sequences as corresponding keypresses on the main keyboard.
+         * Default is keypad-numeric-mode.
+         */
+
+        screen->flags &= ~TERM_FLAG_KEYPAD_MODE;
+
+        return 0;
+}
+
+static int screen_DECLFKC(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECLFKC - local-function-key-control
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECLL(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECLL - load-leds
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECLTOD(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECLTOD - load-time-of-day
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECPCTERM(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECPCTERM - pcterm-mode
+         * This enters/exits the PCTerm mode. Default mode is VT-mode. It can
+         * also select parameters for scancode/keycode mappings in SCO mode.
+         *
+         * Definitely not worth implementing. Lets kill PCTerm/SCO modes!
+         */
+
+        return 0;
+}
+
+static int screen_DECPKA(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECPKA - program-key-action
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECPKFMR(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECPKFMR - program-key-free-memory-report
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECRARA(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECRARA - reverse-attributes-in-rectangular-area
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECRC(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECRC - restore-cursor
+         * Restores the terminal to the state saved by the save cursor (DECSC)
+         * function. This includes more than just the cursor-position.
+         *
+         * If nothing was saved by DECSC, then DECRC performs the following
+         * actions:
+         *   * Moves the cursor to the home position (upper left of screen).
+         *   * Resets origin mode (DECOM).
+         *   * Turns all character attributes off (normal setting).
+         *   * Maps the ASCII character set into GL, and the DEC Supplemental
+         *     Graphic set into GR.
+         *
+         * The terminal maintains a separate DECSC buffer for the main display
+         * and the status line. This feature lets you save a separate operating
+         * state for the main display and the status line.
+         */
+
+        screen->attr = screen->saved.attr;
+        screen->gl = screen->saved.gl;
+        screen->gr = screen->saved.gr;
+        screen->glt = screen->saved.glt;
+        screen->grt = screen->saved.grt;
+        set_reset(screen, TERM_FLAG_AUTO_WRAP, screen->flags & TERM_FLAG_AUTO_WRAP);
+        set_reset(screen, TERM_FLAG_ORIGIN_MODE, screen->flags & TERM_FLAG_ORIGIN_MODE);
+        screen_cursor_set(screen, screen->saved.cursor_x, screen->saved.cursor_y);
+
+        return 0;
+}
+
+static int screen_DECREQTPARM(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECREQTPARM - request-terminal-parameters
+         * The sequence DECREPTPARM is sent by the terminal controller to notify
+         * the host of the status of selected terminal parameters. The status
+         * sequence may be sent when requested by the host or at the terminal's
+         * discretion. DECREPTPARM is sent upon receipt of a DECREQTPARM.
+         *
+         * If @args[0] is 0, this marks a request and the terminal is allowed
+         * to send DECREPTPARM messages without request. If it is 1, the same
+         * applies but the terminal should no longer send DECREPTPARM
+         * unrequested.
+         * 2 and 3 mark a report, but 3 is only used if the terminal answers as
+         * an explicit request with @args[0] == 1.
+         *
+         * The other arguments are ignored in requests, but have the following
+         * meaning in responses:
+         *   args[1]: 1=no-parity-set 4=parity-set-and-odd 5=parity-set-and-even
+         *   args[2]: 1=8bits-per-char 2=7bits-per-char
+         *   args[3]: transmission-speed
+         *   args[4]: receive-speed
+         *   args[5]: 1=bit-rate-multiplier-is-16
+         *   args[6]: This value communicates the four switch values in block 5
+         *            of SETUP B, which are only visible to the user when an STP
+         *            option is installed. These bits may be assigned for an STP
+         *            device. The four bits are a decimal-encoded binary number.
+         *            Value between 0-15.
+         *
+         * The transmission/receive speeds have mappings for number => bits/s
+         * which are quite weird. Examples are: 96->3600, 112->9600, 120->19200
+         *
+         * Defaults:
+         *   args[0]: 0
+         */
+
+        if (seq->n_args < 1 || seq->args[0] == 0) {
+                screen->flags &= ~TERM_FLAG_INHIBIT_TPARM;
+                return SEQ_WRITE(screen, C0_CSI, C1_CSI, "2;1;1;120;120;1;0x");
+        } else if (seq->args[0] == 1) {
+                screen->flags |= TERM_FLAG_INHIBIT_TPARM;
+                return SEQ_WRITE(screen, C0_CSI, C1_CSI, "3;1;1;120;120;1;0x");
+        } else {
+                return 0;
+        }
+}
+
+static int screen_DECRPKT(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECRPKT - report-key-type
+         * Response to DECRQKT, we can safely ignore it as we're the one sending
+         * it to the host.
+         */
+
+        return 0;
+}
+
+static int screen_DECRQCRA(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECRQCRA - request-checksum-of-rectangular-area
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECRQDE(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECRQDE - request-display-extent
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECRQKT(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECRQKT - request-key-type
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECRQLP(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECRQLP - request-locator-position
+         * See DECELR for locator-information.
+         *
+         * TODO: document and implement
+         */
+
+        return 0;
+}
+
+static int screen_DECRQM_ANSI(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECRQM_ANSI - request-mode-ansi
+         * The host sends this control function to find out if a particular mode
+         * is set or reset. The terminal responds with a report mode function.
+         * @args[0] contains the mode to query.
+         *
+         * Response is DECRPM with the first argument set to the mode that was
+         * queried, second argument is 0 if mode is invalid, 1 if mode is set,
+         * 2 if mode is not set (reset), 3 if mode is permanently set and 4 if
+         * mode is permanently not set (reset):
+         *   ANSI: ^[ MODE ; VALUE $ y
+         *   DEC:  ^[ ? MODE ; VALUE $ y
+         *
+         * TODO: implement
+         */
+
+        return 0;
+}
+
+static int screen_DECRQM_DEC(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECRQM_DEC - request-mode-dec
+         * Same as DECRQM_ANSI but for DEC modes.
+         *
+         * TODO: implement
+         */
+
+        return 0;
+}
+
+static int screen_DECRQPKFM(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECRQPKFM - request-program-key-free-memory
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECRQPSR(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECRQPSR - request-presentation-state-report
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECRQTSR(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECRQTSR - request-terminal-state-report
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECRQUPSS(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECRQUPSS - request-user-preferred-supplemental-set
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECSACE(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECSACE - select-attribute-change-extent
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECSASD(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECSASD - select-active-status-display
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECSC(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECSC - save-cursor
+         * Save cursor and terminal state so it can be restored later on.
+         * Saves the following items in the terminal's memory:
+         *   * Cursor position
+         *   * Character attributes set by the SGR command
+         *   * Character sets (G0, G1, G2, or G3) currently in GL and GR
+         *   * Wrap flag (autowrap or no autowrap)
+         *   * State of origin mode (DECOM)
+         *   * Selective erase attribute
+         *   * Any single shift 2 (SS2) or single shift 3 (SS3) functions sent
+         */
+
+        screen->saved.cursor_x = screen->cursor_x;
+        screen->saved.cursor_y = screen->cursor_y;
+        screen->saved.attr = screen->attr;
+        screen->saved.gl = screen->gl;
+        screen->saved.gr = screen->gr;
+        screen->saved.glt = screen->glt;
+        screen->saved.grt = screen->grt;
+        screen->saved.flags = screen->flags & (TERM_FLAG_AUTO_WRAP
+                                               | TERM_FLAG_ORIGIN_MODE);
+
+        return 0;
+}
+
+static int screen_DECSCA(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECSCA - select-character-protection-attribute
+         * Defines the characters that come after it as erasable or not erasable
+         * from the screen. The selective erase control functions (DECSED and
+         * DECSEL) can only erase characters defined as erasable.
+         *
+         * @args[0] specifies the new mode. 0 and 2 mark any following character
+         * as erasable, 1 marks it as not erasable.
+         *
+         * Defaults:
+         *   args[0]: 0
+         */
+
+        unsigned int mode = 0;
+
+        if (seq->args[0] > 0)
+                mode = seq->args[0];
+
+        switch (mode) {
+        case 0:
+        case 2:
+                screen->attr.protect = 0;
+                break;
+        case 1:
+                screen->attr.protect = 1;
+                break;
+        }
+
+        return 0;
+}
+
+static int screen_DECSCL(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECSCL - select-conformance-level
+         * Select the terminal's operating level. The factory default is
+         * level 4 (VT Level 4 mode, 7-bit controls).
+         * When you change the conformance level, the terminal performs a hard
+         * reset (RIS).
+         *
+         * @args[0] defines the conformance-level, valid values are:
+         *   61: Level 1 (VT100)
+         *   62: Level 2 (VT200)
+         *   63: Level 3 (VT300)
+         *   64: Level 4 (VT400)
+         * @args[1] defines the 8bit-mode, valid values are:
+         *    0: 8-bit controls
+         *    1: 7-bit controls
+         *    2: 8-bit controls (same as 0)
+         *
+         * If @args[0] is 61, then @args[1] is ignored and 7bit controls are
+         * enforced.
+         *
+         * Defaults:
+         *   args[0]: 64
+         *   args[1]: 0
+         */
+
+        unsigned int level = 64, bit = 0;
+
+        if (seq->n_args > 0) {
+                level = seq->args[0];
+                if (seq->n_args > 1)
+                        bit = seq->args[1];
+        }
+
+        term_screen_hard_reset(screen);
+
+        switch (level) {
+        case 61:
+                screen->conformance_level = TERM_CONFORMANCE_LEVEL_VT100;
+                screen->flags |= TERM_FLAG_7BIT_MODE;
+                break;
+        case 62 ... 69:
+                screen->conformance_level = TERM_CONFORMANCE_LEVEL_VT400;
+                if (bit == 1)
+                        screen->flags |= TERM_FLAG_7BIT_MODE;
+                else
+                        screen->flags &= ~TERM_FLAG_7BIT_MODE;
+                break;
+        }
+
+        return 0;
+}
+
+static int screen_DECSCP(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECSCP - select-communication-port
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECSCPP(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECSCPP - select-columns-per-page
+         * Select columns per page. The number of rows is unaffected by this.
+         * @args[0] selectes the number of columns (width), DEC only defines 80
+         * and 132, but we allow any integer here. 0 is equivalent to 80.
+         * Page content is *not* cleared and the cursor is left untouched.
+         * However, if the page is reduced in width and the cursor would be
+         * outside the visible region, it's set to the right border. Newly added
+         * cells are cleared. No data is retained outside the visible region.
+         *
+         * Defaults:
+         *   args[0]: 0
+         *
+         * TODO: implement
+         */
+
+        return 0;
+}
+
+static int screen_DECSCS(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECSCS - select-communication-speed
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECSCUSR(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECSCUSR - set-cursor-style
+         * This changes the style of the cursor. @args[0] can be one of:
+         *   0, 1: blinking block
+         *      2: steady block
+         *      3: blinking underline
+         *      4: steady underline
+         * Changing this setting does _not_ affect the cursor visibility itself.
+         * Use DECTCEM for that.
+         *
+         * Defaults:
+         *   args[0]: 0
+         *
+         * TODO: implement
+         */
+
+        return 0;
+}
+
+static int screen_DECSDDT(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECSDDT - select-disconnect-delay-time
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECSDPT(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECSDPT - select-digital-printed-data-type
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECSED(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECSED - selective-erase-in-display
+         * This control function erases some or all of the erasable characters
+         * in the display. DECSED can only erase characters defined as erasable
+         * by the DECSCA control function. DECSED works inside or outside the
+         * scrolling margins.
+         *
+         * @args[0] defines which regions are erased. If it is 0, all cells from
+         * the cursor (inclusive) till the end of the display are erase. If it
+         * is 1, all cells from the start of the display till the cursor
+         * (inclusive) are erased. If it is 2, all cells are erased.
+         *
+         * Defaults:
+         *   args[0]: 0
+         */
+
+        unsigned int mode = 0;
+
+        if (seq->args[0] > 0)
+                mode = seq->args[0];
+
+        switch (mode) {
+        case 0:
+                term_page_erase(screen->page,
+                                screen->cursor_x, screen->cursor_y,
+                                screen->page->width, screen->page->height,
+                                &screen->attr, screen->age, true);
+                break;
+        case 1:
+                term_page_erase(screen->page,
+                                0, 0,
+                                screen->cursor_x, screen->cursor_y,
+                                &screen->attr, screen->age, true);
+                break;
+        case 2:
+                term_page_erase(screen->page,
+                                0, 0,
+                                screen->page->width, screen->page->height,
+                                &screen->attr, screen->age, true);
+                break;
+        }
+
+        return 0;
+}
+
+static int screen_DECSEL(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECSEL - selective-erase-in-line
+         * This control function erases some or all of the erasable characters
+         * in a single line of text. DECSEL erases only those characters defined
+         * as erasable by the DECSCA control function. DECSEL works inside or
+         * outside the scrolling margins.
+         *
+         * @args[0] defines the region to be erased. If it is 0, all cells from
+         * the cursor (inclusive) till the end of the line are erase. If it is
+         * 1, all cells from the start of the line till the cursor (inclusive)
+         * are erased. If it is 2, the whole line of the cursor is erased.
+         *
+         * Defaults:
+         *   args[0]: 0
+         */
+
+        unsigned int mode = 0;
+
+        if (seq->args[0] > 0)
+                mode = seq->args[0];
+
+        switch (mode) {
+        case 0:
+                term_page_erase(screen->page,
+                                screen->cursor_x, screen->cursor_y,
+                                screen->page->width, screen->cursor_y,
+                                &screen->attr, screen->age, true);
+                break;
+        case 1:
+                term_page_erase(screen->page,
+                                0, screen->cursor_y,
+                                screen->cursor_x, screen->cursor_y,
+                                &screen->attr, screen->age, true);
+                break;
+        case 2:
+                term_page_erase(screen->page,
+                                0, screen->cursor_y,
+                                screen->page->width, screen->cursor_y,
+                                &screen->attr, screen->age, true);
+                break;
+        }
+
+        return 0;
+}
+
+static int screen_DECSERA(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECSERA - selective-erase-rectangular-area
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECSFC(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECSFC - select-flow-control
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECSKCV(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECSKCV - set-key-click-volume
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECSLCK(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECSLCK - set-lock-key-style
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECSLE(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECSLE - select-locator-events
+         *
+         * TODO: implement
+         */
+
+        return 0;
+}
+
+static int screen_DECSLPP(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECSLPP - set-lines-per-page
+         * Set the number of lines used for the page. @args[0] specifies the
+         * number of lines to be used. DEC only allows a limited number of
+         * choices, however, we allow all integers. 0 is equivalent to 24.
+         *
+         * Defaults:
+         *   args[0]: 0
+         *
+         * TODO: implement
+         */
+
+        return 0;
+}
+
+static int screen_DECSLRM_OR_SC(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECSLRM_OR_SC - set-left-and-right-margins or save-cursor
+         *
+         * TODO: Detect save-cursor and run it. DECSLRM is not worth
+         *       implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECSMBV(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECSMBV - set-margin-bell-volume
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECSMKR(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECSMKR - select-modifier-key-reporting
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECSNLS(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECSNLS - set-lines-per-screen
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECSPP(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECSPP - set-port-parameter
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECSPPCS(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECSPPCS - select-pro-printer-character-set
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECSPRTT(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECSPRTT - select-printer-type
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECSR(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECSR - secure-reset
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECSRFR(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECSRFR - select-refresh-rate
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECSSCLS(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECSSCLS - set-scroll-speed
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECSSDT(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECSSDT - select-status-display-line-type
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECSSL(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECSSL - select-setup-language
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECST8C(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECST8C - set-tab-at-every-8-columns
+         * Clear the tab-ruler and reset it to a tab at every 8th column,
+         * starting at 9 (though, setting a tab at 1 is fine as it has no
+         * effect).
+         */
+
+        unsigned int i;
+
+        for (i = 0; i < screen->page->width; i += 8)
+                screen->tabs[i / 8] = 0x1;
+
+        return 0;
+}
+
+static int screen_DECSTBM(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECSTBM - set-top-and-bottom-margins
+         * This control function sets the top and bottom margins for the current
+         * page. You cannot perform scrolling outside the margins.
+         *
+         * @args[0] defines the top margin, @args[1] defines the bottom margin.
+         * The bottom margin must be lower than the top-margin.
+         *
+         * This call resets the cursor position to 0/0 of the page.
+         *
+         * Defaults:
+         *   args[0]: 1
+         *   args[1]: last page-line
+         */
+
+        unsigned int top, bottom;
+
+        top = 1;
+        bottom = screen->page->height;
+
+        if (seq->args[0] > 0)
+                top = seq->args[0];
+        if (seq->args[1] > 0)
+                bottom = seq->args[1];
+
+        if (top > screen->page->height)
+                top = screen->page->height;
+        if (bottom > screen->page->height)
+                bottom = screen->page->height;
+
+        if (top >= bottom || top > screen->page->height || bottom > screen->page->height) {
+                top = 1;
+                bottom = screen->page->height;
+        }
+
+        term_page_set_scroll_region(screen->page_main, top - 1, bottom - top + 1);
+        term_page_set_scroll_region(screen->page_alt, top - 1, bottom - top + 1);
+        screen_cursor_clear_wrap(screen);
+        screen_cursor_set(screen, 0, 0);
+
+        return 0;
+}
+
+static int screen_DECSTR(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECSTR - soft-terminal-reset
+         * Perform a soft reset to the default values.
+         */
+
+        term_screen_soft_reset(screen);
+
+        return 0;
+}
+
+static int screen_DECSTRL(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECSTRL - set-transmit-rate-limit
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECSWBV(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECSWBV - set-warning-bell-volume
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECSWL(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECSWL - single-width-single-height-line
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECTID(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECTID - select-terminal-id
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECTME(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECTME - terminal-mode-emulation
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DECTST(term_screen *screen, const term_seq *seq) {
+        /*
+         * DECTST - invoke-confidence-test
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_DL(term_screen *screen, const term_seq *seq) {
+        /*
+         * DL - delete-line
+         * This control function deletes one or more lines in the scrolling
+         * region, starting with the line that has the cursor. @args[0] defines
+         * the number of lines to delete. 0 is treated the same as 1.
+         * As lines are deleted, lines below the cursor and in the scrolling
+         * region move up. The terminal adds blank lines with no visual
+         * character attributes at the bottom of the scrolling region. If it is
+         * greater than the number of lines remaining on the page, DL deletes
+         * only the remaining lines. DL has no effect outside the scrolling
+         * margins.
+         *
+         * Defaults:
+         *   args[0]: 1
+         */
+
+        unsigned int num = 1;
+
+        if (seq->args[0] > 0)
+                num = seq->args[0];
+
+        term_page_delete_lines(screen->page, screen->cursor_y, num, &screen->attr, screen->age);
+
+        return 0;
+}
+
+static int screen_DSR_ANSI(term_screen *screen, const term_seq *seq) {
+        /*
+         * DSR_ANSI - device-status-report-ansi
+         *
+         * TODO: implement
+         */
+
+        return 0;
+}
+
+static int screen_DSR_DEC(term_screen *screen, const term_seq *seq) {
+        /*
+         * DSR_DEC - device-status-report-dec
+         *
+         * TODO: implement
+         */
+
+        return 0;
+}
+
+static int screen_ECH(term_screen *screen, const term_seq *seq) {
+        /*
+         * ECH - erase-character
+         * This control function erases one or more characters, from the cursor
+         * position to the right. ECH clears character attributes from erased
+         * character positions. ECH works inside or outside the scrolling
+         * margins.
+         * @args[0] defines the number of characters to erase. 0 is treated the
+         * same as 1.
+         *
+         * Defaults:
+         *   args[0]: 1
+         */
+
+        unsigned int num = 1;
+
+        if (seq->args[0] > 0)
+                num = seq->args[0];
+
+        term_page_erase(screen->page,
+                        screen->cursor_x, screen->cursor_y,
+                        screen->cursor_x + num, screen->cursor_y,
+                        &screen->attr, screen->age, false);
+
+        return 0;
+}
+
+static int screen_ED(term_screen *screen, const term_seq *seq) {
+        /*
+         * ED - erase-in-display
+         * This control function erases characters from part or all of the
+         * display. When you erase complete lines, they become single-height,
+         * single-width lines, with all visual character attributes cleared. ED
+         * works inside or outside the scrolling margins.
+         *
+         * @args[0] defines the region to erase. 0 means from cursor (inclusive)
+         * till the end of the screen. 1 means from the start of the screen till
+         * the cursor (inclusive) and 2 means the whole screen.
+         *
+         * Defaults:
+         *   args[0]: 0
+         */
+
+        unsigned int mode = 0;
+
+        if (seq->args[0] > 0)
+                mode = seq->args[0];
+
+        switch (mode) {
+        case 0:
+                term_page_erase(screen->page,
+                                screen->cursor_x, screen->cursor_y,
+                                screen->page->width, screen->page->height,
+                                &screen->attr, screen->age, false);
+                break;
+        case 1:
+                term_page_erase(screen->page,
+                                0, 0,
+                                screen->cursor_x, screen->cursor_y,
+                                &screen->attr, screen->age, false);
+                break;
+        case 2:
+                term_page_erase(screen->page,
+                                0, 0,
+                                screen->page->width, screen->page->height,
+                                &screen->attr, screen->age, false);
+                break;
+        }
+
+        return 0;
+}
+
+static int screen_EL(term_screen *screen, const term_seq *seq) {
+        /*
+         * EL - erase-in-line
+         * This control function erases characters on the line that has the
+         * cursor. EL clears all character attributes from erased character
+         * positions. EL works inside or outside the scrolling margins.
+         *
+         * @args[0] defines the region to erase. 0 means from cursor (inclusive)
+         * till the end of the line. 1 means from the start of the line till the
+         * cursor (inclusive) and 2 means the whole line.
+         *
+         * Defaults:
+         *   args[0]: 0
+         */
+
+        unsigned int mode = 0;
+
+        if (seq->args[0] > 0)
+                mode = seq->args[0];
+
+        switch (mode) {
+        case 0:
+                term_page_erase(screen->page,
+                                screen->cursor_x, screen->cursor_y,
+                                screen->page->width, screen->cursor_y,
+                                &screen->attr, screen->age, false);
+                break;
+        case 1:
+                term_page_erase(screen->page,
+                                0, screen->cursor_y,
+                                screen->cursor_x, screen->cursor_y,
+                                &screen->attr, screen->age, false);
+                break;
+        case 2:
+                term_page_erase(screen->page,
+                                0, screen->cursor_y,
+                                screen->page->width, screen->cursor_y,
+                                &screen->attr, screen->age, false);
+                break;
+        }
+
+        return 0;
+}
+
+static int screen_ENQ(term_screen *screen, const term_seq *seq) {
+        /*
+         * ENQ - enquiry
+         * Transmit the answerback-string. If none is set, do nothing.
+         */
+
+        if (screen->answerback)
+                return screen_write(screen, screen->answerback, strlen(screen->answerback));
+
+        return 0;
+}
+
+static int screen_EPA(term_screen *screen, const term_seq *seq) {
+        /*
+         * EPA - end-of-guarded-area
+         *
+         * TODO: What is this?
+         */
+
+        return 0;
+}
+
+static int screen_FF(term_screen *screen, const term_seq *seq) {
+        /*
+         * FF - form-feed
+         * This causes the cursor to jump to the next line. It is treated the
+         * same as LF.
+         */
+
+        return screen_LF(screen, seq);
+}
+
+static int screen_HPA(term_screen *screen, const term_seq *seq) {
+        /*
+         * HPA - horizontal-position-absolute
+         * HPA causes the active position to be moved to the n-th horizontal
+         * position of the active line. If an attempt is made to move the active
+         * position past the last position on the line, then the active position
+         * stops at the last position on the line.
+         *
+         * @args[0] defines the horizontal position. 0 is treated as 1.
+         *
+         * Defaults:
+         *   args[0]: 1
+         */
+
+        unsigned int num = 1;
+
+        if (seq->args[0] > 0)
+                num = seq->args[0];
+
+        screen_cursor_clear_wrap(screen);
+        screen_cursor_set(screen, num - 1, screen->cursor_y);
+
+        return 0;
+}
+
+static int screen_HPR(term_screen *screen, const term_seq *seq) {
+        /*
+         * HPR - horizontal-position-relative
+         * HPR causes the active position to be moved to the n-th following
+         * horizontal position of the active line. If an attempt is made to move
+         * the active position past the last position on the line, then the
+         * active position stops at the last position on the line.
+         *
+         * @args[0] defines the horizontal position. 0 is treated as 1.
+         *
+         * Defaults:
+         *   args[0]: 1
+         */
+
+        unsigned int num = 1;
+
+        if (seq->args[0] > 0)
+                num = seq->args[0];
+
+        screen_cursor_clear_wrap(screen);
+        screen_cursor_right(screen, num);
+
+        return 0;
+}
+
+static int screen_HT(term_screen *screen, const term_seq *seq) {
+        /*
+         * HT - horizontal-tab
+         * Moves the cursor to the next tab stop. If there are no more tab
+         * stops, the cursor moves to the right margin. HT does not cause text
+         * to auto wrap.
+         */
+
+        screen_cursor_clear_wrap(screen);
+        screen_cursor_right_tab(screen, 1);
+
+        return 0;
+}
+
+static int screen_HTS(term_screen *screen, const term_seq *seq) {
+        /*
+         * HTS - horizontal-tab-set
+         * HTS sets a horizontal tab stop at the column position indicated by
+         * the value of the active column when the terminal receives an HTS.
+         *
+         * Executing an HTS does not effect the other horizontal tab stop
+         * settings.
+         */
+
+        unsigned int pos;
+
+        pos = screen->cursor_x;
+        if (screen->page->width > 0)
+                screen->tabs[pos / 8] |= 1U << (pos % 8);
+
+        return 0;
+}
+
+static int screen_HVP(term_screen *screen, const term_seq *seq) {
+        /*
+         * HVP - horizontal-and-vertical-position
+         * This control function works the same as the cursor position (CUP)
+         * function. Origin mode (DECOM) selects line numbering and the ability
+         * to move the cursor into margins.
+         *
+         * Defaults:
+         *   args[0]: 1
+         *   args[1]: 1
+         */
+
+        return screen_CUP(screen, seq);
+}
+
+static int screen_ICH(term_screen *screen, const term_seq *seq) {
+        /*
+         * ICH - insert-character
+         * This control function inserts one or more space (SP) characters
+         * starting at the cursor position. @args[0] is the number of characters
+         * to insert. 0 is treated as 1.
+         *
+         * The ICH sequence inserts blank characters with the normal
+         * character attribute. The cursor remains at the beginning of the blank
+         * characters. Text between the cursor and right margin moves to the
+         * right. Characters scrolled past the right margin are lost. ICH has no
+         * effect outside the scrolling margins.
+         *
+         * Defaults:
+         *   args[0]: 1
+         */
+
+        unsigned int num = 1;
+
+        if (seq->args[0] > 0)
+                num = seq->args[0];
+
+        screen_cursor_clear_wrap(screen);
+        term_page_insert_cells(screen->page, screen->cursor_x, screen->cursor_y, num, &screen->attr, screen->age);
+
+        return 0;
+}
+
+static int screen_IL(term_screen *screen, const term_seq *seq) {
+        /*
+         * IL - insert-line
+         * This control function inserts one or more blank lines, starting at
+         * the cursor. @args[0] is the number of lines to insert. 0 is treated
+         * as 1.
+         *
+         * As lines are inserted, lines below the cursor and in the scrolling
+         * region move down. Lines scrolled off the page are lost. IL has no
+         * effect outside the page margins.
+         *
+         * Defaults:
+         *   args[0]: 1
+         */
+
+        unsigned int num = 1;
+
+        if (seq->args[0] > 0)
+                num = seq->args[0];
+
+        screen_cursor_clear_wrap(screen);
+        term_page_insert_lines(screen->page, screen->cursor_y, num, &screen->attr, screen->age);
+
+        return 0;
+}
+
+static int screen_IND(term_screen *screen, const term_seq *seq) {
+        /*
+         * IND - index
+         * IND moves the cursor down one line in the same column. If the cursor
+         * is at the bottom margin, then the screen performs a scroll-up.
+         */
+
+        screen_cursor_down(screen, 1, true);
+
+        return 0;
+}
+
+static int screen_LF(term_screen *screen, const term_seq *seq) {
+        /*
+         * LF - line-feed
+         * Causes a line feed or a new line operation, depending on the setting
+         * of line feed/new line mode.
+         */
+
+        screen_cursor_down(screen, 1, true);
+        if (screen->flags & TERM_FLAG_NEWLINE_MODE)
+                screen_cursor_left(screen, screen->cursor_x);
+
+        return 0;
+}
+
+static int screen_LS1R(term_screen *screen, const term_seq *seq) {
+        /*
+         * LS1R - locking-shift-1-right
+         * Map G1 into GR.
+         */
+
+        screen->gr = &screen->g1;
+
+        return 0;
+}
+
+static int screen_LS2(term_screen *screen, const term_seq *seq) {
+        /*
+         * LS2 - locking-shift-2
+         * Map G2 into GL.
+         */
+
+        screen->gl = &screen->g2;
+
+        return 0;
+}
+
+static int screen_LS2R(term_screen *screen, const term_seq *seq) {
+        /*
+         * LS2R - locking-shift-2-right
+         * Map G2 into GR.
+         */
+
+        screen->gr = &screen->g2;
+
+        return 0;
+}
+
+static int screen_LS3(term_screen *screen, const term_seq *seq) {
+        /*
+         * LS3 - locking-shift-3
+         * Map G3 into GL.
+         */
+
+        screen->gl = &screen->g3;
+
+        return 0;
+}
+
+static int screen_LS3R(term_screen *screen, const term_seq *seq) {
+        /*
+         * LS3R - locking-shift-3-right
+         * Map G3 into GR.
+         */
+
+        screen->gr = &screen->g3;
+
+        return 0;
+}
+
+static int screen_MC_ANSI(term_screen *screen, const term_seq *seq) {
+        /*
+         * MC_ANSI - media-copy-ansi
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_MC_DEC(term_screen *screen, const term_seq *seq) {
+        /*
+         * MC_DEC - media-copy-dec
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_NEL(term_screen *screen, const term_seq *seq) {
+        /*
+         * NEL - next-line
+         * Moves cursor to first position on next line. If cursor is at bottom
+         * margin, then screen performs a scroll-up.
+         */
+
+        screen_cursor_clear_wrap(screen);
+        screen_cursor_down(screen, 1, true);
+        screen_cursor_set(screen, 0, screen->cursor_y);
+
+        return 0;
+}
+
+static int screen_NP(term_screen *screen, const term_seq *seq) {
+        /*
+         * NP - next-page
+         * This control function moves the cursor forward to the home position
+         * on one of the following pages in page memory. If there is only one
+         * page, then the terminal ignores NP.
+         * If NP tries to move the cursor past the last page in memory, then the
+         * cursor stops at the last page.
+         *
+         * @args[0] defines the number of pages to forward. 0 is treated as 1.
+         *
+         * Defaults:
+         *   args[0]: 1
+         *
+         * Probably not worth implementing. We only support a single page.
+         */
+
+        return 0;
+}
+
+static int screen_NULL(term_screen *screen, const term_seq *seq) {
+        /*
+         * NULL - null
+         * The NULL operation does nothing. ASCII NULL is always ignored.
+         */
+
+        return 0;
+}
+
+static int screen_PP(term_screen *screen, const term_seq *seq) {
+        /*
+         * PP - preceding-page
+         * This control function moves the cursor backward to the home position
+         * on one of the preceding pages in page memory. If there is only one
+         * page, then the terminal ignores PP.
+         * If PP tries to move the cursor back farther than the first page in
+         * memory, then the cursor stops at the first page.
+         *
+         * @args[0] defines the number of pages to go backwards. 0 is treated
+         * as 1.
+         *
+         * Defaults:
+         *   args[0]: 1
+         *
+         * Probably not worth implementing. We only support a single page.
+         */
+
+        return 0;
+}
+
+static int screen_PPA(term_screen *screen, const term_seq *seq) {
+        /*
+         * PPA - page-position-absolute
+         * This control function can move the cursor to the corresponding row
+         * and column on any page in page memory. You select the page by its
+         * number. If there is only one page, then the terminal ignores PPA.
+         *
+         * @args[0] is the number of the page to move the cursor to. If it is
+         * greater than the number of the last page in memory, then the cursor
+         * stops at the last page. If it is less than the number of the first
+         * page, then the cursor stops at the first page.
+         *
+         * Defaults:
+         *   args[0]: 1
+         *
+         * Probably not worth implementing. We only support a single page.
+         */
+
+        return 0;
+}
+
+static int screen_PPB(term_screen *screen, const term_seq *seq) {
+        /*
+         * PPB - page-position-backward
+         * This control function moves the cursor backward to the corresponding
+         * row and column on one of the preceding pages in page memory. If there
+         * is only one page, then the terminal ignores PPB.
+         *
+         * @args[0] indicates the number of pages to move the cursor backward.
+         * If it tries to move the cursor back farther than the first page in
+         * memory, then the cursor stops at the first page. 0 is treated as 1.
+         *
+         * Defaults:
+         *   args[0]: 1
+         *
+         * Probably not worth implementing. We only support a single page.
+         */
+
+        return 0;
+}
+
+static int screen_PPR(term_screen *screen, const term_seq *seq) {
+        /*
+         * PPR - page-position-relative
+         * This control function moves the cursor forward to the corresponding
+         * row and column on one of the following pages in page memory. If there
+         * is only one page, then the terminal ignores PPR.
+         *
+         * @args[0] indicates how many pages to move the cursor forward. If it
+         * tries to move the cursor beyond the last page in memory, then the
+         * cursor stops at the last page. 0 is treated as 1.
+         *
+         * Defaults:
+         *   args[0]: 1
+         *
+         * Probably not worth implementing. We only support a single page.
+         */
+
+        return 0;
+}
+
+static int screen_RC(term_screen *screen, const term_seq *seq) {
+        /*
+         * RC - restore-cursor
+         */
+
+        return screen_DECRC(screen, seq);
+}
+
+static int screen_REP(term_screen *screen, const term_seq *seq) {
+        /*
+         * REP - repeat
+         * Repeat the preceding graphics-character the given number of times.
+         * @args[0] specifies how often it shall be repeated. 0 is treated as 1.
+         *
+         * Defaults:
+         *   args[0]: 1
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_RI(term_screen *screen, const term_seq *seq) {
+        /*
+         * RI - reverse-index
+         * Moves the cursor up one line in the same column. If the cursor is at
+         * the top margin, the page scrolls down.
+         */
+
+        screen_cursor_up(screen, 1, true);
+
+        return 0;
+}
+
+static int screen_RIS(term_screen *screen, const term_seq *seq) {
+        /*
+         * RIS - reset-to-initial-state
+         * This control function causes a nonvolatile memory (NVR) recall to
+         * occur. RIS replaces all set-up features with their saved settings.
+         *
+         * The terminal stores these saved settings in NVR memory. The saved
+         * setting for a feature is the same as the factory-default setting,
+         * unless you saved a new setting.
+         */
+
+        term_screen_hard_reset(screen);
+
+        return 0;
+}
+
+static int screen_RM_ANSI(term_screen *screen, const term_seq *seq) {
+        /*
+         * RM_ANSI - reset-mode-ansi
+         *
+         * TODO: implement (see VT510rm manual)
+         */
+
+        unsigned int i;
+
+        for (i = 0; i < seq->n_args; ++i)
+                screen_mode_change(screen, seq->args[i], false, false);
+
+        return 0;
+}
+
+static int screen_RM_DEC(term_screen *screen, const term_seq *seq) {
+        /*
+         * RM_DEC - reset-mode-dec
+         * This is the same as RM_ANSI but for DEC modes.
+         */
+
+        unsigned int i;
+
+        for (i = 0; i < seq->n_args; ++i)
+                screen_mode_change(screen, seq->args[i], true, false);
+
+        return 0;
+}
+
+static int screen_S7C1T(term_screen *screen, const term_seq *seq) {
+        /*
+         * S7C1T - set-7bit-c1-terminal
+         * This causes the terminal to start sending C1 controls as 7bit
+         * sequences instead of 8bit C1 controls.
+         * This is ignored if the terminal is below level-2 emulation mode
+         * (VT100 and below), the terminal already sends 7bit controls then.
+         */
+
+        if (screen->conformance_level > TERM_CONFORMANCE_LEVEL_VT100)
+                screen->flags |= TERM_FLAG_7BIT_MODE;
+
+        return 0;
+}
+
+static int screen_S8C1T(term_screen *screen, const term_seq *seq) {
+        /*
+         * S8C1T - set-8bit-c1-terminal
+         * This causes the terminal to start sending C1 controls as 8bit C1
+         * control instead of 7bit sequences.
+         * This is ignored if the terminal is below level-2 emulation mode
+         * (VT100 and below). The terminal always sends 7bit controls in those
+         * modes.
+         */
+
+        if (screen->conformance_level > TERM_CONFORMANCE_LEVEL_VT100)
+                screen->flags &= ~TERM_FLAG_7BIT_MODE;
+
+        return 0;
+}
+
+static int screen_SCS(term_screen *screen, const term_seq *seq) {
+        /*
+         * SCS - select-character-set
+         * Designate character sets to G-sets. The mapping from intermediates
+         * and terminal characters in the escape sequence to G-sets and
+         * character-sets is non-trivial and implemented separately. See there
+         * for more information.
+         * This call simply sets the selected G-set to the desired
+         * character-set.
+         */
+
+        term_charset *cs = NULL;
+
+        /* TODO: support more of them? */
+        switch (seq->charset) {
+        case TERM_CHARSET_ISO_LATIN1_SUPPLEMENTAL:
+        case TERM_CHARSET_ISO_LATIN2_SUPPLEMENTAL:
+        case TERM_CHARSET_ISO_LATIN5_SUPPLEMENTAL:
+        case TERM_CHARSET_ISO_GREEK_SUPPLEMENTAL:
+        case TERM_CHARSET_ISO_HEBREW_SUPPLEMENTAL:
+        case TERM_CHARSET_ISO_LATIN_CYRILLIC:
+                break;
+
+        case TERM_CHARSET_DEC_SPECIAL_GRAPHIC:
+                cs = &term_dec_special_graphics;
+                break;
+        case TERM_CHARSET_DEC_SUPPLEMENTAL:
+                cs = &term_dec_supplemental_graphics;
+                break;
+        case TERM_CHARSET_DEC_TECHNICAL:
+        case TERM_CHARSET_CYRILLIC_DEC:
+        case TERM_CHARSET_DUTCH_NRCS:
+        case TERM_CHARSET_FINNISH_NRCS:
+        case TERM_CHARSET_FRENCH_NRCS:
+        case TERM_CHARSET_FRENCH_CANADIAN_NRCS:
+        case TERM_CHARSET_GERMAN_NRCS:
+        case TERM_CHARSET_GREEK_DEC:
+        case TERM_CHARSET_GREEK_NRCS:
+        case TERM_CHARSET_HEBREW_DEC:
+        case TERM_CHARSET_HEBREW_NRCS:
+        case TERM_CHARSET_ITALIAN_NRCS:
+        case TERM_CHARSET_NORWEGIAN_DANISH_NRCS:
+        case TERM_CHARSET_PORTUGUESE_NRCS:
+        case TERM_CHARSET_RUSSIAN_NRCS:
+        case TERM_CHARSET_SCS_NRCS:
+        case TERM_CHARSET_SPANISH_NRCS:
+        case TERM_CHARSET_SWEDISH_NRCS:
+        case TERM_CHARSET_SWISS_NRCS:
+        case TERM_CHARSET_TURKISH_DEC:
+        case TERM_CHARSET_TURKISH_NRCS:
+                break;
+
+        case TERM_CHARSET_USERPREF_SUPPLEMENTAL:
+                break;
+        }
+
+        if (seq->intermediates & TERM_SEQ_FLAG_POPEN)
+                screen->g0 = cs ? : &term_unicode_lower;
+        else if (seq->intermediates & TERM_SEQ_FLAG_PCLOSE)
+                screen->g1 = cs ? : &term_unicode_upper;
+        else if (seq->intermediates & TERM_SEQ_FLAG_MULT)
+                screen->g2 = cs ? : &term_unicode_lower;
+        else if (seq->intermediates & TERM_SEQ_FLAG_PLUS)
+                screen->g3 = cs ? : &term_unicode_upper;
+        else if (seq->intermediates & TERM_SEQ_FLAG_MINUS)
+                screen->g1 = cs ? : &term_unicode_upper;
+        else if (seq->intermediates & TERM_SEQ_FLAG_DOT)
+                screen->g2 = cs ? : &term_unicode_lower;
+        else if (seq->intermediates & TERM_SEQ_FLAG_SLASH)
+                screen->g3 = cs ? : &term_unicode_upper;
+
+        return 0;
+}
+
+static int screen_SD(term_screen *screen, const term_seq *seq) {
+        /*
+         * SD - scroll-down
+         * This control function moves the user window down a specified number
+         * of lines in page memory.
+         * @args[0] is the number of lines to move the
+         * user window up in page memory. New lines appear at the top of the
+         * display. Old lines disappear at the bottom of the display. You
+         * cannot pan past the top margin of the current page. 0 is treated
+         * as 1.
+         *
+         * Defaults:
+         *   args[0]: 1
+         */
+
+        unsigned int num = 1;
+
+        if (seq->args[0] > 0)
+                num = seq->args[0];
+
+        term_page_scroll_down(screen->page, num, &screen->attr, screen->age, NULL);
+
+        return 0;
+}
+
+static int screen_SGR(term_screen *screen, const term_seq *seq) {
+        /*
+         * SGR - select-graphics-rendition
+         */
+
+        term_color *dst;
+        unsigned int i, code;
+        int v;
+
+        if (seq->n_args < 1) {
+                zero(screen->attr);
+                return 0;
+        }
+
+        for (i = 0; i < seq->n_args; ++i) {
+                v = seq->args[i];
+                switch (v) {
+                case 1:
+                        screen->attr.bold = 1;
+                        break;
+                case 3:
+                        screen->attr.italic = 1;
+                        break;
+                case 4:
+                        screen->attr.underline = 1;
+                        break;
+                case 5:
+                        screen->attr.blink = 1;
+                        break;
+                case 7:
+                        screen->attr.inverse = 1;
+                        break;
+                case 8:
+                        screen->attr.hidden = 1;
+                        break;
+                case 22:
+                        screen->attr.bold = 0;
+                        break;
+                case 23:
+                        screen->attr.italic = 0;
+                        break;
+                case 24:
+                        screen->attr.underline = 0;
+                        break;
+                case 25:
+                        screen->attr.blink = 0;
+                        break;
+                case 27:
+                        screen->attr.inverse = 0;
+                        break;
+                case 28:
+                        screen->attr.hidden = 0;
+                        break;
+                case 30 ... 37:
+                        screen->attr.fg.ccode = v - 30 + TERM_CCODE_BLACK;
+                        break;
+                case 39:
+                        screen->attr.fg.ccode = 0;
+                        break;
+                case 40 ... 47:
+                        screen->attr.bg.ccode = v - 40 + TERM_CCODE_BLACK;
+                        break;
+                case 49:
+                        screen->attr.bg.ccode = 0;
+                        break;
+                case 90 ... 97:
+                        screen->attr.fg.ccode = v - 90 + TERM_CCODE_LIGHT_BLACK;
+                        break;
+                case 100 ... 107:
+                        screen->attr.bg.ccode = v - 100 + TERM_CCODE_LIGHT_BLACK;
+                        break;
+                case 38:
+                        /* fallthrough */
+                case 48:
+
+                        if (v == 38)
+                                dst = &screen->attr.fg;
+                        else
+                                dst = &screen->attr.bg;
+
+                        ++i;
+                        if (i >= seq->n_args)
+                                break;
+
+                        switch (seq->args[i]) {
+                        case 2:
+                                /* 24bit-color support */
+
+                                i += 3;
+                                if (i >= seq->n_args)
+                                        break;
+
+                                dst->ccode = TERM_CCODE_RGB;
+                                dst->red = (seq->args[i - 2] >= 0) ? seq->args[i - 2] : 0;
+                                dst->green = (seq->args[i - 1] >= 0) ? seq->args[i - 1] : 0;
+                                dst->blue = (seq->args[i] >= 0) ? seq->args[i] : 0;
+
+                                break;
+                        case 5:
+                                /* 256-color support */
+
+                                ++i;
+                                if (i >= seq->n_args || seq->args[i] < 0)
+                                        break;
+
+                                code = seq->args[i];
+                                if (code < 16) {
+                                        dst->ccode = code;
+                                } else if (code < 232) {
+                                        static const uint8_t bval[] = {
+                                                0x00, 0x5f, 0x87,
+                                                0xaf, 0xd7, 0xff,
+                                        };
+
+                                        dst->ccode = TERM_CCODE_256;
+                                        dst->c256 = code;
+                                        code -= 16;
+                                        dst->blue = bval[code % 6];
+                                        code /= 6;
+                                        dst->green = bval[code % 6];
+                                        code /= 6;
+                                        dst->red = bval[code % 6];
+                                } else if (code < 256) {
+                                        dst->ccode = TERM_CCODE_256;
+                                        dst->c256 = code;
+                                        code = (code - 232) * 10 + 8;
+                                        dst->red = code;
+                                        dst->green = code;
+                                        dst->blue = code;
+                                }
+
+                                break;
+                        }
+
+                        break;
+                case -1:
+                        /* fallthrough */
+                case 0:
+                        zero(screen->attr);
+                        break;
+                }
+        }
+
+        return 0;
+}
+
+static int screen_SI(term_screen *screen, const term_seq *seq) {
+        /*
+         * SI - shift-in
+         * Map G0 into GL.
+         */
+
+        screen->gl = &screen->g0;
+
+        return 0;
+}
+
+static int screen_SM_ANSI(term_screen *screen, const term_seq *seq) {
+        /*
+         * SM_ANSI - set-mode-ansi
+         *
+         * TODO: implement
+         */
+
+        unsigned int i;
+
+        for (i = 0; i < seq->n_args; ++i)
+                screen_mode_change(screen, seq->args[i], false, true);
+
+        return 0;
+}
+
+static int screen_SM_DEC(term_screen *screen, const term_seq *seq) {
+        /*
+         * SM_DEC - set-mode-dec
+         * This is the same as SM_ANSI but for DEC modes.
+         */
+
+        unsigned int i;
+
+        for (i = 0; i < seq->n_args; ++i)
+                screen_mode_change(screen, seq->args[i], true, true);
+
+        return 0;
+}
+
+static int screen_SO(term_screen *screen, const term_seq *seq) {
+        /*
+         * SO - shift-out
+         * Map G1 into GL.
+         */
+
+        screen->gl = &screen->g1;
+
+        return 0;
+}
+
+static int screen_SPA(term_screen *screen, const term_seq *seq) {
+        /*
+         * SPA - start-of-protected-area
+         *
+         * TODO: What is this?
+         */
+
+        return 0;
+}
+
+static int screen_SS2(term_screen *screen, const term_seq *seq) {
+        /*
+         * SS2 - single-shift-2
+         * Temporarily map G2 into GL for the next graphics character.
+         */
+
+        screen->glt = &screen->g2;
+
+        return 0;
+}
+
+static int screen_SS3(term_screen *screen, const term_seq *seq) {
+        /*
+         * SS3 - single-shift-3
+         * Temporarily map G3 into GL for the next graphics character
+         */
+
+        screen->glt = &screen->g3;
+
+        return 0;
+}
+
+static int screen_ST(term_screen *screen, const term_seq *seq) {
+        /*
+         * ST - string-terminator
+         * The string-terminator is usually part of control-sequences and
+         * handled by the parser. In all other situations it is silently
+         * ignored.
+         */
+
+        return 0;
+}
+
+static int screen_SU(term_screen *screen, const term_seq *seq) {
+        /*
+         * SU - scroll-up
+         * This control function moves the user window up a specified number of
+         * lines in page memory.
+         * @args[0] is the number of lines to move the
+         * user window down in page memory. New lines appear at the bottom of
+         * the display. Old lines disappear at the top of the display. You
+         * cannot pan past the bottom margin of the current page. 0 is treated
+         * as 1.
+         *
+         * Defaults:
+         *   args[0]: 1
+         */
+
+        unsigned int num = 1;
+
+        if (seq->args[0] > 0)
+                num = seq->args[0];
+
+        term_page_scroll_up(screen->page, num, &screen->attr, screen->age, screen->history);
+
+        return 0;
+}
+
+static int screen_SUB(term_screen *screen, const term_seq *seq) {
+        /*
+         * SUB - substitute
+         * Cancel the current control-sequence and print a replacement
+         * character. Our parser already handles this so all we have to do is
+         * print the replacement character.
+         */
+
+        static const term_seq rep = {
+                .type = TERM_SEQ_GRAPHIC,
+                .command = TERM_CMD_GRAPHIC,
+                .terminator = 0xfffd,
+        };
+
+        return screen_GRAPHIC(screen, &rep);
+}
+
+static int screen_TBC(term_screen *screen, const term_seq *seq) {
+        /*
+         * TBC - tab-clear
+         * This clears tab-stops. If @args[0] is 0, the tab-stop at the current
+         * cursor position is cleared. If it is 3, all tab stops are cleared.
+         *
+         * Defaults:
+         *   args[0]: 0
+         */
+
+        unsigned int mode = 0, pos;
+
+        if (seq->args[0] > 0)
+                mode = seq->args[0];
+
+        switch (mode) {
+        case 0:
+                pos = screen->cursor_x;
+                if (screen->page->width > 0)
+                        screen->tabs[pos / 8] &= ~(1U << (pos % 8));
+                break;
+        case 3:
+                if (screen->page->width > 0)
+                        memset(screen->tabs, 0, (screen->page->width + 7) / 8);
+                break;
+        }
+
+        return 0;
+}
+
+static int screen_VPA(term_screen *screen, const term_seq *seq) {
+        /*
+         * VPA - vertical-line-position-absolute
+         * VPA causes the active position to be moved to the corresponding
+         * horizontal position. @args[0] specifies the line to jump to. If an
+         * attempt is made to move the active position below the last line, then
+         * the active position stops on the last line. 0 is treated as 1.
+         *
+         * Defaults:
+         *   args[0]: 1
+         */
+
+        unsigned int pos = 1;
+
+        if (seq->args[0] > 0)
+                pos = seq->args[0];
+
+        screen_cursor_clear_wrap(screen);
+        screen_cursor_set_rel(screen, screen->cursor_x, pos - 1);
+
+        return 0;
+}
+
+static int screen_VPR(term_screen *screen, const term_seq *seq) {
+        /*
+         * VPR - vertical-line-position-relative
+         * VPR causes the active position to be moved to the corresponding
+         * horizontal position. @args[0] specifies the number of lines to jump
+         * down relative to the current cursor position. If an attempt is made
+         * to move the active position below the last line, the active position
+         * stops at the last line. 0 is treated as 1.
+         *
+         * Defaults:
+         *   args[0]: 1
+         */
+
+        unsigned int num = 1;
+
+        if (seq->args[0] > 0)
+                num = seq->args[0];
+
+        screen_cursor_clear_wrap(screen);
+        screen_cursor_down(screen, num, false);
+
+        return 0;
+}
+
+static int screen_VT(term_screen *screen, const term_seq *seq) {
+        /*
+         * VT - vertical-tab
+         * This causes a vertical jump by one line. Terminals treat it exactly
+         * the same as LF.
+         */
+
+        return screen_LF(screen, seq);
+}
+
+static int screen_XTERM_CLLHP(term_screen *screen, const term_seq *seq) {
+        /*
+         * XTERM_CLLHP - xterm-cursor-lower-left-hp-bugfix
+         * Move the cursor to the lower-left corner of the page. This is an HP
+         * bugfix by xterm.
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_XTERM_IHMT(term_screen *screen, const term_seq *seq) {
+        /*
+         * XTERM_IHMT - xterm-initiate-highlight-mouse-tracking
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_XTERM_MLHP(term_screen *screen, const term_seq *seq) {
+        /*
+         * XTERM_MLHP - xterm-memory-lock-hp-bugfix
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_XTERM_MUHP(term_screen *screen, const term_seq *seq) {
+        /*
+         * XTERM_MUHP - xterm-memory-unlock-hp-bugfix
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_XTERM_RPM(term_screen *screen, const term_seq *seq) {
+        /*
+         * XTERM_RPM - xterm-restore-private-mode
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_XTERM_RRV(term_screen *screen, const term_seq *seq) {
+        /*
+         * XTERM_RRV - xterm-reset-resource-value
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_XTERM_RTM(term_screen *screen, const term_seq *seq) {
+        /*
+         * XTERM_RTM - xterm-reset-title-mode
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_XTERM_SACL1(term_screen *screen, const term_seq *seq) {
+        /*
+         * XTERM_SACL1 - xterm-set-ansi-conformance-level-1
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_XTERM_SACL2(term_screen *screen, const term_seq *seq) {
+        /*
+         * XTERM_SACL2 - xterm-set-ansi-conformance-level-2
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_XTERM_SACL3(term_screen *screen, const term_seq *seq) {
+        /*
+         * XTERM_SACL3 - xterm-set-ansi-conformance-level-3
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_XTERM_SDCS(term_screen *screen, const term_seq *seq) {
+        /*
+         * XTERM_SDCS - xterm-set-default-character-set
+         * Select the default character set. We treat this the same as UTF-8 as
+         * this is our default character set. As we always use UTF-8, this
+         * becomes as no-op.
+         */
+
+        return 0;
+}
+
+static int screen_XTERM_SGFX(term_screen *screen, const term_seq *seq) {
+        /*
+         * XTERM_SGFX - xterm-sixel-graphics
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_XTERM_SPM(term_screen *screen, const term_seq *seq) {
+        /*
+         * XTERM_SPM - xterm-set-private-mode
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_XTERM_SRV(term_screen *screen, const term_seq *seq) {
+        /*
+         * XTERM_SRV - xterm-set-resource-value
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_XTERM_STM(term_screen *screen, const term_seq *seq) {
+        /*
+         * XTERM_STM - xterm-set-title-mode
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+static int screen_XTERM_SUCS(term_screen *screen, const term_seq *seq) {
+        /*
+         * XTERM_SUCS - xterm-select-utf8-character-set
+         * Select UTF-8 as character set. This is our default on only character
+         * set. Hence, this is a no-op.
+         */
+
+        return 0;
+}
+
+static int screen_XTERM_WM(term_screen *screen, const term_seq *seq) {
+        /*
+         * XTERM_WM - xterm-window-management
+         *
+         * Probably not worth implementing.
+         */
+
+        return 0;
+}
+
+/*
+ * Feeding data
+ * The screen_feed_*() handlers take data from the user and feed it into the
+ * screen. Once the parser has detected a sequence, we parse the command-type
+ * and forward it to the command-dispatchers.
+ */
+
+static int screen_feed_cmd(term_screen *screen, const term_seq *seq) {
+        switch (seq->command) {
+        case TERM_CMD_GRAPHIC:
+                return screen_GRAPHIC(screen, seq);
+        case TERM_CMD_BEL:
+                return screen_BEL(screen, seq);
+        case TERM_CMD_BS:
+                return screen_BS(screen, seq);
+        case TERM_CMD_CBT:
+                return screen_CBT(screen, seq);
+        case TERM_CMD_CHA:
+                return screen_CHA(screen, seq);
+        case TERM_CMD_CHT:
+                return screen_CHT(screen, seq);
+        case TERM_CMD_CNL:
+                return screen_CNL(screen, seq);
+        case TERM_CMD_CPL:
+                return screen_CPL(screen, seq);
+        case TERM_CMD_CR:
+                return screen_CR(screen, seq);
+        case TERM_CMD_CUB:
+                return screen_CUB(screen, seq);
+        case TERM_CMD_CUD:
+                return screen_CUD(screen, seq);
+        case TERM_CMD_CUF:
+                return screen_CUF(screen, seq);
+        case TERM_CMD_CUP:
+                return screen_CUP(screen, seq);
+        case TERM_CMD_CUU:
+                return screen_CUU(screen, seq);
+        case TERM_CMD_DA1:
+                return screen_DA1(screen, seq);
+        case TERM_CMD_DA2:
+                return screen_DA2(screen, seq);
+        case TERM_CMD_DA3:
+                return screen_DA3(screen, seq);
+        case TERM_CMD_DC1:
+                return screen_DC1(screen, seq);
+        case TERM_CMD_DC3:
+                return screen_DC3(screen, seq);
+        case TERM_CMD_DCH:
+                return screen_DCH(screen, seq);
+        case TERM_CMD_DECALN:
+                return screen_DECALN(screen, seq);
+        case TERM_CMD_DECANM:
+                return screen_DECANM(screen, seq);
+        case TERM_CMD_DECBI:
+                return screen_DECBI(screen, seq);
+        case TERM_CMD_DECCARA:
+                return screen_DECCARA(screen, seq);
+        case TERM_CMD_DECCRA:
+                return screen_DECCRA(screen, seq);
+        case TERM_CMD_DECDC:
+                return screen_DECDC(screen, seq);
+        case TERM_CMD_DECDHL_BH:
+                return screen_DECDHL_BH(screen, seq);
+        case TERM_CMD_DECDHL_TH:
+                return screen_DECDHL_TH(screen, seq);
+        case TERM_CMD_DECDWL:
+                return screen_DECDWL(screen, seq);
+        case TERM_CMD_DECEFR:
+                return screen_DECEFR(screen, seq);
+        case TERM_CMD_DECELF:
+                return screen_DECELF(screen, seq);
+        case TERM_CMD_DECELR:
+                return screen_DECELR(screen, seq);
+        case TERM_CMD_DECERA:
+                return screen_DECERA(screen, seq);
+        case TERM_CMD_DECFI:
+                return screen_DECFI(screen, seq);
+        case TERM_CMD_DECFRA:
+                return screen_DECFRA(screen, seq);
+        case TERM_CMD_DECIC:
+                return screen_DECIC(screen, seq);
+        case TERM_CMD_DECID:
+                return screen_DECID(screen, seq);
+        case TERM_CMD_DECINVM:
+                return screen_DECINVM(screen, seq);
+        case TERM_CMD_DECKBD:
+                return screen_DECKBD(screen, seq);
+        case TERM_CMD_DECKPAM:
+                return screen_DECKPAM(screen, seq);
+        case TERM_CMD_DECKPNM:
+                return screen_DECKPNM(screen, seq);
+        case TERM_CMD_DECLFKC:
+                return screen_DECLFKC(screen, seq);
+        case TERM_CMD_DECLL:
+                return screen_DECLL(screen, seq);
+        case TERM_CMD_DECLTOD:
+                return screen_DECLTOD(screen, seq);
+        case TERM_CMD_DECPCTERM:
+                return screen_DECPCTERM(screen, seq);
+        case TERM_CMD_DECPKA:
+                return screen_DECPKA(screen, seq);
+        case TERM_CMD_DECPKFMR:
+                return screen_DECPKFMR(screen, seq);
+        case TERM_CMD_DECRARA:
+                return screen_DECRARA(screen, seq);
+        case TERM_CMD_DECRC:
+                return screen_DECRC(screen, seq);
+        case TERM_CMD_DECREQTPARM:
+                return screen_DECREQTPARM(screen, seq);
+        case TERM_CMD_DECRPKT:
+                return screen_DECRPKT(screen, seq);
+        case TERM_CMD_DECRQCRA:
+                return screen_DECRQCRA(screen, seq);
+        case TERM_CMD_DECRQDE:
+                return screen_DECRQDE(screen, seq);
+        case TERM_CMD_DECRQKT:
+                return screen_DECRQKT(screen, seq);
+        case TERM_CMD_DECRQLP:
+                return screen_DECRQLP(screen, seq);
+        case TERM_CMD_DECRQM_ANSI:
+                return screen_DECRQM_ANSI(screen, seq);
+        case TERM_CMD_DECRQM_DEC:
+                return screen_DECRQM_DEC(screen, seq);
+        case TERM_CMD_DECRQPKFM:
+                return screen_DECRQPKFM(screen, seq);
+        case TERM_CMD_DECRQPSR:
+                return screen_DECRQPSR(screen, seq);
+        case TERM_CMD_DECRQTSR:
+                return screen_DECRQTSR(screen, seq);
+        case TERM_CMD_DECRQUPSS:
+                return screen_DECRQUPSS(screen, seq);
+        case TERM_CMD_DECSACE:
+                return screen_DECSACE(screen, seq);
+        case TERM_CMD_DECSASD:
+                return screen_DECSASD(screen, seq);
+        case TERM_CMD_DECSC:
+                return screen_DECSC(screen, seq);
+        case TERM_CMD_DECSCA:
+                return screen_DECSCA(screen, seq);
+        case TERM_CMD_DECSCL:
+                return screen_DECSCL(screen, seq);
+        case TERM_CMD_DECSCP:
+                return screen_DECSCP(screen, seq);
+        case TERM_CMD_DECSCPP:
+                return screen_DECSCPP(screen, seq);
+        case TERM_CMD_DECSCS:
+                return screen_DECSCS(screen, seq);
+        case TERM_CMD_DECSCUSR:
+                return screen_DECSCUSR(screen, seq);
+        case TERM_CMD_DECSDDT:
+                return screen_DECSDDT(screen, seq);
+        case TERM_CMD_DECSDPT:
+                return screen_DECSDPT(screen, seq);
+        case TERM_CMD_DECSED:
+                return screen_DECSED(screen, seq);
+        case TERM_CMD_DECSEL:
+                return screen_DECSEL(screen, seq);
+        case TERM_CMD_DECSERA:
+                return screen_DECSERA(screen, seq);
+        case TERM_CMD_DECSFC:
+                return screen_DECSFC(screen, seq);
+        case TERM_CMD_DECSKCV:
+                return screen_DECSKCV(screen, seq);
+        case TERM_CMD_DECSLCK:
+                return screen_DECSLCK(screen, seq);
+        case TERM_CMD_DECSLE:
+                return screen_DECSLE(screen, seq);
+        case TERM_CMD_DECSLPP:
+                return screen_DECSLPP(screen, seq);
+        case TERM_CMD_DECSLRM_OR_SC:
+                return screen_DECSLRM_OR_SC(screen, seq);
+        case TERM_CMD_DECSMBV:
+                return screen_DECSMBV(screen, seq);
+        case TERM_CMD_DECSMKR:
+                return screen_DECSMKR(screen, seq);
+        case TERM_CMD_DECSNLS:
+                return screen_DECSNLS(screen, seq);
+        case TERM_CMD_DECSPP:
+                return screen_DECSPP(screen, seq);
+        case TERM_CMD_DECSPPCS:
+                return screen_DECSPPCS(screen, seq);
+        case TERM_CMD_DECSPRTT:
+                return screen_DECSPRTT(screen, seq);
+        case TERM_CMD_DECSR:
+                return screen_DECSR(screen, seq);
+        case TERM_CMD_DECSRFR:
+                return screen_DECSRFR(screen, seq);
+        case TERM_CMD_DECSSCLS:
+                return screen_DECSSCLS(screen, seq);
+        case TERM_CMD_DECSSDT:
+                return screen_DECSSDT(screen, seq);
+        case TERM_CMD_DECSSL:
+                return screen_DECSSL(screen, seq);
+        case TERM_CMD_DECST8C:
+                return screen_DECST8C(screen, seq);
+        case TERM_CMD_DECSTBM:
+                return screen_DECSTBM(screen, seq);
+        case TERM_CMD_DECSTR:
+                return screen_DECSTR(screen, seq);
+        case TERM_CMD_DECSTRL:
+                return screen_DECSTRL(screen, seq);
+        case TERM_CMD_DECSWBV:
+                return screen_DECSWBV(screen, seq);
+        case TERM_CMD_DECSWL:
+                return screen_DECSWL(screen, seq);
+        case TERM_CMD_DECTID:
+                return screen_DECTID(screen, seq);
+        case TERM_CMD_DECTME:
+                return screen_DECTME(screen, seq);
+        case TERM_CMD_DECTST:
+                return screen_DECTST(screen, seq);
+        case TERM_CMD_DL:
+                return screen_DL(screen, seq);
+        case TERM_CMD_DSR_ANSI:
+                return screen_DSR_ANSI(screen, seq);
+        case TERM_CMD_DSR_DEC:
+                return screen_DSR_DEC(screen, seq);
+        case TERM_CMD_ECH:
+                return screen_ECH(screen, seq);
+        case TERM_CMD_ED:
+                return screen_ED(screen, seq);
+        case TERM_CMD_EL:
+                return screen_EL(screen, seq);
+        case TERM_CMD_ENQ:
+                return screen_ENQ(screen, seq);
+        case TERM_CMD_EPA:
+                return screen_EPA(screen, seq);
+        case TERM_CMD_FF:
+                return screen_FF(screen, seq);
+        case TERM_CMD_HPA:
+                return screen_HPA(screen, seq);
+        case TERM_CMD_HPR:
+                return screen_HPR(screen, seq);
+        case TERM_CMD_HT:
+                return screen_HT(screen, seq);
+        case TERM_CMD_HTS:
+                return screen_HTS(screen, seq);
+        case TERM_CMD_HVP:
+                return screen_HVP(screen, seq);
+        case TERM_CMD_ICH:
+                return screen_ICH(screen, seq);
+        case TERM_CMD_IL:
+                return screen_IL(screen, seq);
+        case TERM_CMD_IND:
+                return screen_IND(screen, seq);
+        case TERM_CMD_LF:
+                return screen_LF(screen, seq);
+        case TERM_CMD_LS1R:
+                return screen_LS1R(screen, seq);
+        case TERM_CMD_LS2:
+                return screen_LS2(screen, seq);
+        case TERM_CMD_LS2R:
+                return screen_LS2R(screen, seq);
+        case TERM_CMD_LS3:
+                return screen_LS3(screen, seq);
+        case TERM_CMD_LS3R:
+                return screen_LS3R(screen, seq);
+        case TERM_CMD_MC_ANSI:
+                return screen_MC_ANSI(screen, seq);
+        case TERM_CMD_MC_DEC:
+                return screen_MC_DEC(screen, seq);
+        case TERM_CMD_NEL:
+                return screen_NEL(screen, seq);
+        case TERM_CMD_NP:
+                return screen_NP(screen, seq);
+        case TERM_CMD_NULL:
+                return screen_NULL(screen, seq);
+        case TERM_CMD_PP:
+                return screen_PP(screen, seq);
+        case TERM_CMD_PPA:
+                return screen_PPA(screen, seq);
+        case TERM_CMD_PPB:
+                return screen_PPB(screen, seq);
+        case TERM_CMD_PPR:
+                return screen_PPR(screen, seq);
+        case TERM_CMD_RC:
+                return screen_RC(screen, seq);
+        case TERM_CMD_REP:
+                return screen_REP(screen, seq);
+        case TERM_CMD_RI:
+                return screen_RI(screen, seq);
+        case TERM_CMD_RIS:
+                return screen_RIS(screen, seq);
+        case TERM_CMD_RM_ANSI:
+                return screen_RM_ANSI(screen, seq);
+        case TERM_CMD_RM_DEC:
+                return screen_RM_DEC(screen, seq);
+        case TERM_CMD_S7C1T:
+                return screen_S7C1T(screen, seq);
+        case TERM_CMD_S8C1T:
+                return screen_S8C1T(screen, seq);
+        case TERM_CMD_SCS:
+                return screen_SCS(screen, seq);
+        case TERM_CMD_SD:
+                return screen_SD(screen, seq);
+        case TERM_CMD_SGR:
+                return screen_SGR(screen, seq);
+        case TERM_CMD_SI:
+                return screen_SI(screen, seq);
+        case TERM_CMD_SM_ANSI:
+                return screen_SM_ANSI(screen, seq);
+        case TERM_CMD_SM_DEC:
+                return screen_SM_DEC(screen, seq);
+        case TERM_CMD_SO:
+                return screen_SO(screen, seq);
+        case TERM_CMD_SPA:
+                return screen_SPA(screen, seq);
+        case TERM_CMD_SS2:
+                return screen_SS2(screen, seq);
+        case TERM_CMD_SS3:
+                return screen_SS3(screen, seq);
+        case TERM_CMD_ST:
+                return screen_ST(screen, seq);
+        case TERM_CMD_SU:
+                return screen_SU(screen, seq);
+        case TERM_CMD_SUB:
+                return screen_SUB(screen, seq);
+        case TERM_CMD_TBC:
+                return screen_TBC(screen, seq);
+        case TERM_CMD_VPA:
+                return screen_VPA(screen, seq);
+        case TERM_CMD_VPR:
+                return screen_VPR(screen, seq);
+        case TERM_CMD_VT:
+                return screen_VT(screen, seq);
+        case TERM_CMD_XTERM_CLLHP:
+                return screen_XTERM_CLLHP(screen, seq);
+        case TERM_CMD_XTERM_IHMT:
+                return screen_XTERM_IHMT(screen, seq);
+        case TERM_CMD_XTERM_MLHP:
+                return screen_XTERM_MLHP(screen, seq);
+        case TERM_CMD_XTERM_MUHP:
+                return screen_XTERM_MUHP(screen, seq);
+        case TERM_CMD_XTERM_RPM:
+                return screen_XTERM_RPM(screen, seq);
+        case TERM_CMD_XTERM_RRV:
+                return screen_XTERM_RRV(screen, seq);
+        case TERM_CMD_XTERM_RTM:
+                return screen_XTERM_RTM(screen, seq);
+        case TERM_CMD_XTERM_SACL1:
+                return screen_XTERM_SACL1(screen, seq);
+        case TERM_CMD_XTERM_SACL2:
+                return screen_XTERM_SACL2(screen, seq);
+        case TERM_CMD_XTERM_SACL3:
+                return screen_XTERM_SACL3(screen, seq);
+        case TERM_CMD_XTERM_SDCS:
+                return screen_XTERM_SDCS(screen, seq);
+        case TERM_CMD_XTERM_SGFX:
+                return screen_XTERM_SGFX(screen, seq);
+        case TERM_CMD_XTERM_SPM:
+                return screen_XTERM_SPM(screen, seq);
+        case TERM_CMD_XTERM_SRV:
+                return screen_XTERM_SRV(screen, seq);
+        case TERM_CMD_XTERM_STM:
+                return screen_XTERM_STM(screen, seq);
+        case TERM_CMD_XTERM_SUCS:
+                return screen_XTERM_SUCS(screen, seq);
+        case TERM_CMD_XTERM_WM:
+                return screen_XTERM_WM(screen, seq);
+        }
+
+        return 0;
+}
+
+int term_screen_feed_text(term_screen *screen, const uint8_t *in, size_t size) {
+        const uint32_t *ucs4_str;
+        size_t i, j, ucs4_len;
+        const term_seq *seq;
+        int r;
+
+        assert_return(screen, -EINVAL);
+
+        /* Feed bytes into utf8 decoder and handle parsed ucs4 chars. We always
+         * treat data as UTF-8, but the parser makes sure to fall back to raw
+         * 8bit mode if the stream is not valid UTF-8. This should be more than
+         * enough to support old 7bit/8bit modes. */
+        for (i = 0; i < size; ++i) {
+                ucs4_str = term_utf8_decode(&screen->utf8, &ucs4_len, in[i]);
+                for (j = 0; j < ucs4_len; ++j) {
+                        r = term_parser_feed(screen->parser, &seq, ucs4_str[j]);
+                        if (r < 0) {
+                                return r;
+                        } else if (r != TERM_SEQ_NONE) {
+                                r = screen_feed_cmd(screen, seq);
+                                if (r < 0)
+                                        return r;
+                        }
+                }
+        }
+
+        return 0;
+}
+
+int term_screen_feed_keyboard(term_screen *screen, uint32_t keysym, uint32_t ascii, uint32_t ucs4, unsigned int mods) {
+        assert_return(screen, -EINVAL);
+
+        /* TODO */
+
+        return 0;
+}
+
+int term_screen_resize(term_screen *screen, unsigned int x, unsigned int y) {
+        unsigned int i;
+        uint8_t *t;
+        int r;
+
+        assert_return(screen, -EINVAL);
+
+        r = term_page_reserve(screen->page_main, x, y, &screen->attr, screen->age);
+        if (r < 0)
+                return r;
+
+        r = term_page_reserve(screen->page_alt, x, y, &screen->attr, screen->age);
+        if (r < 0)
+                return r;
+
+        if (x > screen->n_tabs) {
+                t = realloc(screen->tabs, (x + 7) / 8);
+                if (!t)
+                        return -ENOMEM;
+
+                screen->tabs = t;
+                screen->n_tabs = x;
+        }
+
+        for (i = (screen->page->width + 7) / 8 * 8; i < x; i += 8)
+                screen->tabs[i / 8] = 0x1;
+
+        term_page_resize(screen->page_main, x, y, &screen->attr, screen->age, screen->history);
+        term_page_resize(screen->page_alt, x, y, &screen->attr, screen->age, NULL);
+
+        screen->cursor_x = screen_clamp_x(screen, screen->cursor_x);
+        screen->cursor_y = screen_clamp_x(screen, screen->cursor_y);
+        screen_cursor_clear_wrap(screen);
+
+        return 0;
+}
+
+void term_screen_soft_reset(term_screen *screen) {
+        unsigned int i;
+
+        assert(screen);
+
+        screen->gl = &screen->g0;
+        screen->gr = &screen->g1;
+        screen->glt = NULL;
+        screen->grt = NULL;
+        screen->g0 = &term_unicode_lower;
+        screen->g1 = &term_unicode_upper;
+        screen->g2 = &term_unicode_lower;
+        screen->g3 = &term_unicode_upper;
+
+        screen->page = screen->page_main;
+        screen->history = screen->history_main;
+        screen->flags = TERM_FLAG_7BIT_MODE;
+        screen->conformance_level = TERM_CONFORMANCE_LEVEL_VT400;
+        screen->attr = screen->default_attr;
+
+        screen->saved.cursor_x = 0;
+        screen->saved.cursor_y = 0;
+        screen->saved.attr = screen->attr;
+        screen->saved.gl = screen->gl;
+        screen->saved.gr = screen->gr;
+        screen->saved.glt = NULL;
+        screen->saved.grt = NULL;
+        screen->flags = 0;
+
+        for (i = 0; i < screen->page->width; i += 8)
+                screen->tabs[i / 8] = 0x1;
+
+        term_page_set_scroll_region(screen->page_main, 0, screen->page->height);
+        term_page_set_scroll_region(screen->page_alt, 0, screen->page->height);
+}
+
+void term_screen_hard_reset(term_screen *screen) {
+        assert(screen);
+
+        term_screen_soft_reset(screen);
+        zero(screen->utf8);
+        screen->cursor_x = 0;
+        screen->cursor_y = 0;
+        term_page_erase(screen->page_main, 0, 0, screen->page->width, screen->page->height, &screen->attr, screen->age, false);
+        term_page_erase(screen->page_alt, 0, 0, screen->page->width, screen->page->height, &screen->attr, screen->age, false);
+}
+
+int term_screen_set_answerback(term_screen *screen, const char *answerback) {
+        char *t = NULL;
+
+        assert_return(screen, -EINVAL);
+
+        if (answerback) {
+                t = strdup(answerback);
+                if (!t)
+                        return -ENOMEM;
+        }
+
+        free(screen->answerback);
+        screen->answerback = t;
+
+        return 0;
+}
diff --git a/src/libsystemd-terminal/term-wcwidth.c b/src/libsystemd-terminal/term-wcwidth.c
new file mode 100644 (file)
index 0000000..df20a40
--- /dev/null
@@ -0,0 +1,313 @@
+/*
+ * (Minimal changes made by David Herrmann, to make clean for inclusion in
+ *  systemd. Original header follows.)
+ *
+ * This is an implementation of wcwidth() and wcswidth() (defined in
+ * IEEE Std 1002.1-2001) for Unicode.
+ *
+ * http://www.opengroup.org/onlinepubs/007904975/functions/wcwidth.html
+ * http://www.opengroup.org/onlinepubs/007904975/functions/wcswidth.html
+ *
+ * In fixed-width output devices, Latin characters all occupy a single
+ * "cell" position of equal width, whereas ideographic CJK characters
+ * occupy two such cells. Interoperability between terminal-line
+ * applications and (teletype-style) character terminals using the
+ * UTF-8 encoding requires agreement on which character should advance
+ * the cursor by how many cell positions. No established formal
+ * standards exist at present on which Unicode character shall occupy
+ * how many cell positions on character terminals. These routines are
+ * a first attempt of defining such behavior based on simple rules
+ * applied to data provided by the Unicode Consortium.
+ *
+ * For some graphical characters, the Unicode standard explicitly
+ * defines a character-cell width via the definition of the East Asian
+ * FullWidth (F), Wide (W), Half-width (H), and Narrow (Na) classes.
+ * In all these cases, there is no ambiguity about which width a
+ * terminal shall use. For characters in the East Asian Ambiguous (A)
+ * class, the width choice depends purely on a preference of backward
+ * compatibility with either historic CJK or Western practice.
+ * Choosing single-width for these characters is easy to justify as
+ * the appropriate long-term solution, as the CJK practice of
+ * displaying these characters as double-width comes from historic
+ * implementation simplicity (8-bit encoded characters were displayed
+ * single-width and 16-bit ones double-width, even for Greek,
+ * Cyrillic, etc.) and not any typographic considerations.
+ *
+ * Much less clear is the choice of width for the Not East Asian
+ * (Neutral) class. Existing practice does not dictate a width for any
+ * of these characters. It would nevertheless make sense
+ * typographically to allocate two character cells to characters such
+ * as for instance EM SPACE or VOLUME INTEGRAL, which cannot be
+ * represented adequately with a single-width glyph. The following
+ * routines at present merely assign a single-cell width to all
+ * neutral characters, in the interest of simplicity. This is not
+ * entirely satisfactory and should be reconsidered before
+ * establishing a formal standard in this area. At the moment, the
+ * decision which Not East Asian (Neutral) characters should be
+ * represented by double-width glyphs cannot yet be answered by
+ * applying a simple rule from the Unicode database content. Setting
+ * up a proper standard for the behavior of UTF-8 character terminals
+ * will require a careful analysis not only of each Unicode character,
+ * but also of each presentation form, something the author of these
+ * routines has avoided to do so far.
+ *
+ * http://www.unicode.org/unicode/reports/tr11/
+ *
+ * Markus Kuhn -- 2007-05-26 (Unicode 5.0)
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * for any purpose and without fee is hereby granted. The author
+ * disclaims all warranties with regard to this software.
+ *
+ * Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
+ */
+
+#include <wchar.h>
+#include "term-internal.h"
+
+struct interval {
+  wchar_t first;
+  wchar_t last;
+};
+
+/* auxiliary function for binary search in interval table */
+static int bisearch(wchar_t ucs, const struct interval *table, int max) {
+  int min = 0;
+  int mid;
+
+  if (ucs < table[0].first || ucs > table[max].last)
+    return 0;
+  while (max >= min) {
+    mid = (min + max) / 2;
+    if (ucs > table[mid].last)
+      min = mid + 1;
+    else if (ucs < table[mid].first)
+      max = mid - 1;
+    else
+      return 1;
+  }
+
+  return 0;
+}
+
+
+/* The following two functions define the column width of an ISO 10646
+ * character as follows:
+ *
+ *    - The null character (U+0000) has a column width of 0.
+ *
+ *    - Other C0/C1 control characters and DEL will lead to a return
+ *      value of -1.
+ *
+ *    - Non-spacing and enclosing combining characters (general
+ *      category code Mn or Me in the Unicode database) have a
+ *      column width of 0.
+ *
+ *    - SOFT HYPHEN (U+00AD) has a column width of 1.
+ *
+ *    - Other format characters (general category code Cf in the Unicode
+ *      database) and ZERO WIDTH SPACE (U+200B) have a column width of 0.
+ *
+ *    - Hangul Jamo medial vowels and final consonants (U+1160-U+11FF)
+ *      have a column width of 0.
+ *
+ *    - Spacing characters in the East Asian Wide (W) or East Asian
+ *      Full-width (F) category as defined in Unicode Technical
+ *      Report #11 have a column width of 2.
+ *
+ *    - All remaining characters (including all printable
+ *      ISO 8859-1 and WGL4 characters, Unicode control characters,
+ *      etc.) have a column width of 1.
+ *
+ * This implementation assumes that wchar_t characters are encoded
+ * in ISO 10646.
+ */
+
+int mk_wcwidth(wchar_t ucs)
+{
+  /* sorted list of non-overlapping intervals of non-spacing characters */
+  /* generated by "uniset +cat=Me +cat=Mn +cat=Cf -00AD +1160-11FF +200B c" */
+  static const struct interval combining[] = {
+    { 0x0300, 0x036F }, { 0x0483, 0x0486 }, { 0x0488, 0x0489 },
+    { 0x0591, 0x05BD }, { 0x05BF, 0x05BF }, { 0x05C1, 0x05C2 },
+    { 0x05C4, 0x05C5 }, { 0x05C7, 0x05C7 }, { 0x0600, 0x0603 },
+    { 0x0610, 0x0615 }, { 0x064B, 0x065E }, { 0x0670, 0x0670 },
+    { 0x06D6, 0x06E4 }, { 0x06E7, 0x06E8 }, { 0x06EA, 0x06ED },
+    { 0x070F, 0x070F }, { 0x0711, 0x0711 }, { 0x0730, 0x074A },
+    { 0x07A6, 0x07B0 }, { 0x07EB, 0x07F3 }, { 0x0901, 0x0902 },
+    { 0x093C, 0x093C }, { 0x0941, 0x0948 }, { 0x094D, 0x094D },
+    { 0x0951, 0x0954 }, { 0x0962, 0x0963 }, { 0x0981, 0x0981 },
+    { 0x09BC, 0x09BC }, { 0x09C1, 0x09C4 }, { 0x09CD, 0x09CD },
+    { 0x09E2, 0x09E3 }, { 0x0A01, 0x0A02 }, { 0x0A3C, 0x0A3C },
+    { 0x0A41, 0x0A42 }, { 0x0A47, 0x0A48 }, { 0x0A4B, 0x0A4D },
+    { 0x0A70, 0x0A71 }, { 0x0A81, 0x0A82 }, { 0x0ABC, 0x0ABC },
+    { 0x0AC1, 0x0AC5 }, { 0x0AC7, 0x0AC8 }, { 0x0ACD, 0x0ACD },
+    { 0x0AE2, 0x0AE3 }, { 0x0B01, 0x0B01 }, { 0x0B3C, 0x0B3C },
+    { 0x0B3F, 0x0B3F }, { 0x0B41, 0x0B43 }, { 0x0B4D, 0x0B4D },
+    { 0x0B56, 0x0B56 }, { 0x0B82, 0x0B82 }, { 0x0BC0, 0x0BC0 },
+    { 0x0BCD, 0x0BCD }, { 0x0C3E, 0x0C40 }, { 0x0C46, 0x0C48 },
+    { 0x0C4A, 0x0C4D }, { 0x0C55, 0x0C56 }, { 0x0CBC, 0x0CBC },
+    { 0x0CBF, 0x0CBF }, { 0x0CC6, 0x0CC6 }, { 0x0CCC, 0x0CCD },
+    { 0x0CE2, 0x0CE3 }, { 0x0D41, 0x0D43 }, { 0x0D4D, 0x0D4D },
+    { 0x0DCA, 0x0DCA }, { 0x0DD2, 0x0DD4 }, { 0x0DD6, 0x0DD6 },
+    { 0x0E31, 0x0E31 }, { 0x0E34, 0x0E3A }, { 0x0E47, 0x0E4E },
+    { 0x0EB1, 0x0EB1 }, { 0x0EB4, 0x0EB9 }, { 0x0EBB, 0x0EBC },
+    { 0x0EC8, 0x0ECD }, { 0x0F18, 0x0F19 }, { 0x0F35, 0x0F35 },
+    { 0x0F37, 0x0F37 }, { 0x0F39, 0x0F39 }, { 0x0F71, 0x0F7E },
+    { 0x0F80, 0x0F84 }, { 0x0F86, 0x0F87 }, { 0x0F90, 0x0F97 },
+    { 0x0F99, 0x0FBC }, { 0x0FC6, 0x0FC6 }, { 0x102D, 0x1030 },
+    { 0x1032, 0x1032 }, { 0x1036, 0x1037 }, { 0x1039, 0x1039 },
+    { 0x1058, 0x1059 }, { 0x1160, 0x11FF }, { 0x135F, 0x135F },
+    { 0x1712, 0x1714 }, { 0x1732, 0x1734 }, { 0x1752, 0x1753 },
+    { 0x1772, 0x1773 }, { 0x17B4, 0x17B5 }, { 0x17B7, 0x17BD },
+    { 0x17C6, 0x17C6 }, { 0x17C9, 0x17D3 }, { 0x17DD, 0x17DD },
+    { 0x180B, 0x180D }, { 0x18A9, 0x18A9 }, { 0x1920, 0x1922 },
+    { 0x1927, 0x1928 }, { 0x1932, 0x1932 }, { 0x1939, 0x193B },
+    { 0x1A17, 0x1A18 }, { 0x1B00, 0x1B03 }, { 0x1B34, 0x1B34 },
+    { 0x1B36, 0x1B3A }, { 0x1B3C, 0x1B3C }, { 0x1B42, 0x1B42 },
+    { 0x1B6B, 0x1B73 }, { 0x1DC0, 0x1DCA }, { 0x1DFE, 0x1DFF },
+    { 0x200B, 0x200F }, { 0x202A, 0x202E }, { 0x2060, 0x2063 },
+    { 0x206A, 0x206F }, { 0x20D0, 0x20EF }, { 0x302A, 0x302F },
+    { 0x3099, 0x309A }, { 0xA806, 0xA806 }, { 0xA80B, 0xA80B },
+    { 0xA825, 0xA826 }, { 0xFB1E, 0xFB1E }, { 0xFE00, 0xFE0F },
+    { 0xFE20, 0xFE23 }, { 0xFEFF, 0xFEFF }, { 0xFFF9, 0xFFFB },
+    { 0x10A01, 0x10A03 }, { 0x10A05, 0x10A06 }, { 0x10A0C, 0x10A0F },
+    { 0x10A38, 0x10A3A }, { 0x10A3F, 0x10A3F }, { 0x1D167, 0x1D169 },
+    { 0x1D173, 0x1D182 }, { 0x1D185, 0x1D18B }, { 0x1D1AA, 0x1D1AD },
+    { 0x1D242, 0x1D244 }, { 0xE0001, 0xE0001 }, { 0xE0020, 0xE007F },
+    { 0xE0100, 0xE01EF }
+  };
+
+  /* test for 8-bit control characters */
+  if (ucs == 0)
+    return 0;
+  if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0))
+    return -1;
+
+  /* binary search in table of non-spacing characters */
+  if (bisearch(ucs, combining,
+               sizeof(combining) / sizeof(struct interval) - 1))
+    return 0;
+
+  /* if we arrive here, ucs is not a combining or C0/C1 control character */
+
+  return 1 +
+    (ucs >= 0x1100 &&
+     (ucs <= 0x115f ||                    /* Hangul Jamo init. consonants */
+      ucs == 0x2329 || ucs == 0x232a ||
+      (ucs >= 0x2e80 && ucs <= 0xa4cf &&
+       ucs != 0x303f) ||                  /* CJK ... Yi */
+      (ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */
+      (ucs >= 0xf900 && ucs <= 0xfaff) || /* CJK Compatibility Ideographs */
+      (ucs >= 0xfe10 && ucs <= 0xfe19) || /* Vertical forms */
+      (ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */
+      (ucs >= 0xff00 && ucs <= 0xff60) || /* Fullwidth Forms */
+      (ucs >= 0xffe0 && ucs <= 0xffe6) ||
+      (ucs >= 0x20000 && ucs <= 0x2fffd) ||
+      (ucs >= 0x30000 && ucs <= 0x3fffd)));
+}
+
+
+int mk_wcswidth(const wchar_t *pwcs, size_t n)
+{
+  int w, width = 0;
+
+  for (;*pwcs && n-- > 0; pwcs++)
+    if ((w = mk_wcwidth(*pwcs)) < 0)
+      return -1;
+    else
+      width += w;
+
+  return width;
+}
+
+
+/*
+ * The following functions are the same as mk_wcwidth() and
+ * mk_wcswidth(), except that spacing characters in the East Asian
+ * Ambiguous (A) category as defined in Unicode Technical Report #11
+ * have a column width of 2. This variant might be useful for users of
+ * CJK legacy encodings who want to migrate to UCS without changing
+ * the traditional terminal character-width behaviour. It is not
+ * otherwise recommended for general use.
+ */
+int mk_wcwidth_cjk(wchar_t ucs)
+{
+  /* sorted list of non-overlapping intervals of East Asian Ambiguous
+   * characters, generated by "uniset +WIDTH-A -cat=Me -cat=Mn -cat=Cf c" */
+  static const struct interval ambiguous[] = {
+    { 0x00A1, 0x00A1 }, { 0x00A4, 0x00A4 }, { 0x00A7, 0x00A8 },
+    { 0x00AA, 0x00AA }, { 0x00AE, 0x00AE }, { 0x00B0, 0x00B4 },
+    { 0x00B6, 0x00BA }, { 0x00BC, 0x00BF }, { 0x00C6, 0x00C6 },
+    { 0x00D0, 0x00D0 }, { 0x00D7, 0x00D8 }, { 0x00DE, 0x00E1 },
+    { 0x00E6, 0x00E6 }, { 0x00E8, 0x00EA }, { 0x00EC, 0x00ED },
+    { 0x00F0, 0x00F0 }, { 0x00F2, 0x00F3 }, { 0x00F7, 0x00FA },
+    { 0x00FC, 0x00FC }, { 0x00FE, 0x00FE }, { 0x0101, 0x0101 },
+    { 0x0111, 0x0111 }, { 0x0113, 0x0113 }, { 0x011B, 0x011B },
+    { 0x0126, 0x0127 }, { 0x012B, 0x012B }, { 0x0131, 0x0133 },
+    { 0x0138, 0x0138 }, { 0x013F, 0x0142 }, { 0x0144, 0x0144 },
+    { 0x0148, 0x014B }, { 0x014D, 0x014D }, { 0x0152, 0x0153 },
+    { 0x0166, 0x0167 }, { 0x016B, 0x016B }, { 0x01CE, 0x01CE },
+    { 0x01D0, 0x01D0 }, { 0x01D2, 0x01D2 }, { 0x01D4, 0x01D4 },
+    { 0x01D6, 0x01D6 }, { 0x01D8, 0x01D8 }, { 0x01DA, 0x01DA },
+    { 0x01DC, 0x01DC }, { 0x0251, 0x0251 }, { 0x0261, 0x0261 },
+    { 0x02C4, 0x02C4 }, { 0x02C7, 0x02C7 }, { 0x02C9, 0x02CB },
+    { 0x02CD, 0x02CD }, { 0x02D0, 0x02D0 }, { 0x02D8, 0x02DB },
+    { 0x02DD, 0x02DD }, { 0x02DF, 0x02DF }, { 0x0391, 0x03A1 },
+    { 0x03A3, 0x03A9 }, { 0x03B1, 0x03C1 }, { 0x03C3, 0x03C9 },
+    { 0x0401, 0x0401 }, { 0x0410, 0x044F }, { 0x0451, 0x0451 },
+    { 0x2010, 0x2010 }, { 0x2013, 0x2016 }, { 0x2018, 0x2019 },
+    { 0x201C, 0x201D }, { 0x2020, 0x2022 }, { 0x2024, 0x2027 },
+    { 0x2030, 0x2030 }, { 0x2032, 0x2033 }, { 0x2035, 0x2035 },
+    { 0x203B, 0x203B }, { 0x203E, 0x203E }, { 0x2074, 0x2074 },
+    { 0x207F, 0x207F }, { 0x2081, 0x2084 }, { 0x20AC, 0x20AC },
+    { 0x2103, 0x2103 }, { 0x2105, 0x2105 }, { 0x2109, 0x2109 },
+    { 0x2113, 0x2113 }, { 0x2116, 0x2116 }, { 0x2121, 0x2122 },
+    { 0x2126, 0x2126 }, { 0x212B, 0x212B }, { 0x2153, 0x2154 },
+    { 0x215B, 0x215E }, { 0x2160, 0x216B }, { 0x2170, 0x2179 },
+    { 0x2190, 0x2199 }, { 0x21B8, 0x21B9 }, { 0x21D2, 0x21D2 },
+    { 0x21D4, 0x21D4 }, { 0x21E7, 0x21E7 }, { 0x2200, 0x2200 },
+    { 0x2202, 0x2203 }, { 0x2207, 0x2208 }, { 0x220B, 0x220B },
+    { 0x220F, 0x220F }, { 0x2211, 0x2211 }, { 0x2215, 0x2215 },
+    { 0x221A, 0x221A }, { 0x221D, 0x2220 }, { 0x2223, 0x2223 },
+    { 0x2225, 0x2225 }, { 0x2227, 0x222C }, { 0x222E, 0x222E },
+    { 0x2234, 0x2237 }, { 0x223C, 0x223D }, { 0x2248, 0x2248 },
+    { 0x224C, 0x224C }, { 0x2252, 0x2252 }, { 0x2260, 0x2261 },
+    { 0x2264, 0x2267 }, { 0x226A, 0x226B }, { 0x226E, 0x226F },
+    { 0x2282, 0x2283 }, { 0x2286, 0x2287 }, { 0x2295, 0x2295 },
+    { 0x2299, 0x2299 }, { 0x22A5, 0x22A5 }, { 0x22BF, 0x22BF },
+    { 0x2312, 0x2312 }, { 0x2460, 0x24E9 }, { 0x24EB, 0x254B },
+    { 0x2550, 0x2573 }, { 0x2580, 0x258F }, { 0x2592, 0x2595 },
+    { 0x25A0, 0x25A1 }, { 0x25A3, 0x25A9 }, { 0x25B2, 0x25B3 },
+    { 0x25B6, 0x25B7 }, { 0x25BC, 0x25BD }, { 0x25C0, 0x25C1 },
+    { 0x25C6, 0x25C8 }, { 0x25CB, 0x25CB }, { 0x25CE, 0x25D1 },
+    { 0x25E2, 0x25E5 }, { 0x25EF, 0x25EF }, { 0x2605, 0x2606 },
+    { 0x2609, 0x2609 }, { 0x260E, 0x260F }, { 0x2614, 0x2615 },
+    { 0x261C, 0x261C }, { 0x261E, 0x261E }, { 0x2640, 0x2640 },
+    { 0x2642, 0x2642 }, { 0x2660, 0x2661 }, { 0x2663, 0x2665 },
+    { 0x2667, 0x266A }, { 0x266C, 0x266D }, { 0x266F, 0x266F },
+    { 0x273D, 0x273D }, { 0x2776, 0x277F }, { 0xE000, 0xF8FF },
+    { 0xFFFD, 0xFFFD }, { 0xF0000, 0xFFFFD }, { 0x100000, 0x10FFFD }
+  };
+
+  /* binary search in table of non-spacing characters */
+  if (bisearch(ucs, ambiguous,
+               sizeof(ambiguous) / sizeof(struct interval) - 1))
+    return 2;
+
+  return mk_wcwidth(ucs);
+}
+
+
+int mk_wcswidth_cjk(const wchar_t *pwcs, size_t n)
+{
+  int w, width = 0;
+
+  for (;*pwcs && n-- > 0; pwcs++)
+    if ((w = mk_wcwidth_cjk(*pwcs)) < 0)
+      return -1;
+    else
+      width += w;
+
+  return width;
+}
diff --git a/src/libsystemd-terminal/test-term-page.c b/src/libsystemd-terminal/test-term-page.c
new file mode 100644 (file)
index 0000000..bba83ee
--- /dev/null
@@ -0,0 +1,463 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+/***
+  This file is part of systemd.
+
+  Copyright (C) 2014 David Herrmann <dh.herrmann@gmail.com>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+/*
+ * Terminal Page/Line/Cell/Char Tests
+ * This tests internals of terminal page, line, cell and char handling. It
+ * relies on some implementation details, so it might need to be updated if
+ * those internals are changed. They should be fairly obvious, though.
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "macro.h"
+#include "term-internal.h"
+#include "util.h"
+
+#define MY_ASSERT_VALS __FILE__, __LINE__, __PRETTY_FUNCTION__
+#define MY_ASSERT_FORW _FILE, _LINE, _FUNC
+#define MY_ASSERT_ARGS const char *_FILE, int _LINE, const char *_FUNC
+#define MY_ASSERT(expr)                                                 \
+        do {                                                            \
+                if (_unlikely_(!(expr)))                                \
+                        log_assert_failed(#expr, _FILE, _LINE, _FUNC);  \
+        } while (false)                                                 \
+
+/*
+ * Character Tests
+ *
+ * These tests rely on some implementation details of term_char_t, including
+ * the way we pack characters and the internal layout of "term_char_t". These
+ * tests have to be updated once we change the implementation.
+ */
+
+#define PACK(v1, v2, v3) \
+                TERM_CHAR_INIT( \
+                        (((((uint64_t)v1) & 0x1fffffULL) << 43) | \
+                         ((((uint64_t)v2) & 0x1fffffULL) << 22) | \
+                         ((((uint64_t)v3) & 0x1fffffULL) <<  1) | \
+                         0x1) \
+                )
+#define PACK1(v1) PACK2((v1), 0x110000)
+#define PACK2(v1, v2) PACK3((v1), (v2), 0x110000)
+#define PACK3(v1, v2, v3) PACK((v1), (v2), (v3))
+
+static void test_term_char_misc(void) {
+        term_char_t c, t;
+
+        /* test TERM_CHAR_NULL handling */
+
+        c = TERM_CHAR_NULL;                     /* c is NULL */
+        assert_se(term_char_same(c, TERM_CHAR_NULL));
+        assert_se(term_char_equal(c, TERM_CHAR_NULL));
+        assert_se(term_char_is_null(c));
+        assert_se(term_char_is_null(TERM_CHAR_NULL));
+        assert_se(!term_char_is_allocated(c));
+
+        /* test single char handling */
+
+        t = term_char_dup_append(c, 'A');       /* t is >A< now */
+        assert_se(!term_char_same(c, t));
+        assert_se(!term_char_equal(c, t));
+        assert_se(!term_char_is_allocated(t));
+        assert_se(!term_char_is_null(t));
+
+        /* test basic combined char handling */
+
+        t = term_char_dup_append(t, '~');
+        t = term_char_dup_append(t, '^');       /* t is >A~^< now */
+        assert_se(!term_char_same(c, t));
+        assert_se(!term_char_is_allocated(t));
+        assert_se(!term_char_is_null(t));
+
+        c = term_char_dup_append(c, 'A');
+        c = term_char_dup_append(c, '~');
+        c = term_char_dup_append(c, '^');       /* c is >A~^< now */
+        assert_se(term_char_same(c, t));
+        assert_se(term_char_equal(c, t));
+
+        /* test more than 2 comb-chars so the chars are allocated */
+
+        t = term_char_dup_append(t, '`');       /* t is >A~^`< now */
+        c = term_char_dup_append(c, '`');       /* c is >A~^`< now */
+        assert_se(!term_char_same(c, t));
+        assert_se(term_char_equal(c, t));
+
+        /* test dup_append() on allocated chars */
+
+        term_char_free(t);
+        t = term_char_dup_append(c, '"');       /* t is >A~^`"< now */
+        assert_se(!term_char_same(c, t));
+        assert_se(!term_char_equal(c, t));
+        c = term_char_merge(c, '"');            /* c is >A~^`"< now */
+        assert_se(!term_char_same(c, t));
+        assert_se(term_char_equal(c, t));
+
+        term_char_free(t);
+        term_char_free(c);
+}
+
+static void test_term_char_packing(void)  {
+        uint32_t seqs[][1024] = {
+                { -1 },
+                { 0, -1 },
+                { 'A', '~', -1 },
+                { 'A', '~', 0, -1 },
+                { 'A', '~', 'a', -1 },
+        };
+        term_char_t res[] = {
+                TERM_CHAR_NULL,
+                PACK1(0),
+                PACK2('A', '~'),
+                PACK3('A', '~', 0),
+                PACK3('A', '~', 'a'),
+        };
+        uint32_t next;
+        unsigned int i, j;
+        term_char_t c = TERM_CHAR_NULL;
+
+        /*
+         * This creates term_char_t objects based on the data in @seqs and
+         * compares the result to @res. Only basic packed types are tested, no
+         * allocations are done.
+         */
+
+        for (i = 0; i < ELEMENTSOF(seqs); ++i) {
+                for (j = 0; j < ELEMENTSOF(seqs[i]); ++j) {
+                        next = seqs[i][j];
+                        if (next == (uint32_t)-1)
+                                break;
+
+                        c = term_char_merge(c, next);
+                }
+
+                assert_se(!memcmp(&c, &res[i], sizeof(c)));
+                c = term_char_free(c);
+        }
+}
+
+static void test_term_char_allocating(void) {
+        uint32_t seqs[][1024] = {
+                { 0, -1 },
+                { 'A', '~', -1 },
+                { 'A', '~', 0, -1 },
+                { 'A', '~', 'a', -1 },
+                { 'A', '~', 'a', 'b', 'c', 'd', -1 },
+                { 'A', '~', 'a', 'b', 'c', 'd', 0, '^', -1 },
+                /* exceeding implementation-defined soft-limit of 64 */
+                { 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd',
+                  'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd',
+                  'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd',
+                  'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd',
+                  'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd',
+                  'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd',
+                  'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd',
+                  'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', -1 },
+        };
+        term_char_t res[] = {
+                PACK1(0),
+                PACK2('A', '~'),
+                PACK3('A', '~', 0),
+                PACK3('A', '~', 'a'),
+                TERM_CHAR_NULL,                 /* allocated */
+                TERM_CHAR_NULL,                 /* allocated */
+                TERM_CHAR_NULL,                 /* allocated */
+        };
+        uint32_t str[][1024] = {
+                { 0, -1 },
+                { 'A', '~', -1 },
+                { 'A', '~', 0, -1 },
+                { 'A', '~', 'a', -1 },
+                { 'A', '~', 'a', 'b', 'c', 'd', -1 },
+                { 'A', '~', 'a', 'b', 'c', 'd', 0, '^', -1 },
+                { 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd',
+                  'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd',
+                  'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd',
+                  'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd',
+                  'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd',
+                  'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd',
+                  'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd',
+                  'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', -1 },
+        };
+        size_t n;
+        uint32_t next;
+        unsigned int i, j;
+        const uint32_t *t;
+
+        /*
+         * This builds term_char_t objects based on the data in @seqs. It
+         * compares the result to @res for packed chars, otherwise it requires
+         * them to be allocated.
+         * After that, we resolve the UCS-4 string and compare it to the
+         * expected strings in @str.
+         */
+
+        for (i = 0; i < ELEMENTSOF(seqs); ++i) {
+                _term_char_free_ term_char_t c = TERM_CHAR_NULL;
+
+                for (j = 0; j < ELEMENTSOF(seqs[i]); ++j) {
+                        next = seqs[i][j];
+                        if (next == (uint32_t)-1)
+                                break;
+
+                        c = term_char_merge(c, next);
+                }
+
+                /* we use TERM_CHAR_NULL as marker for allocated chars here */
+                if (term_char_is_null(res[i]))
+                        assert_se(term_char_is_allocated(c));
+                else
+                        assert_se(!memcmp(&c, &res[i], sizeof(c)));
+
+                t = term_char_resolve(c, &n, NULL);
+                for (j = 0; j < ELEMENTSOF(str[i]); ++j) {
+                        next = str[i][j];
+                        if (next == (uint32_t)-1)
+                                break;
+
+                        assert_se(t[j] == next);
+                }
+
+                assert_se(n == j);
+        }
+}
+
+/*
+ * Line Tests
+ *
+ * The following tests work on term_line objects and verify their behavior when
+ * we modify them. To verify and set line layouts, we have two simple helpers
+ * to avoid harcoding the cell-verification all the time:
+ *   line_set(): Set a line to a given layout
+ *   line_assert(): Verify that a line has a given layout
+ *
+ * These functions take the line-layout encoded as a string and verify it
+ * against, or set it on, a term_line object. The format used to describe a
+ * line looks like this:
+ *       example: "|   | A |   |   |   |   |   | 10 *AB* |"
+ *
+ * The string describes the contents of all cells of a line, separated by
+ * pipe-symbols ('|'). Whitespace are ignored, the leading pipe-symbol is
+ * optional.
+ * The description of each cell can contain an arbitrary amount of characters
+ * in the range 'A'-'Z', 'a'-'z'. All those are combined and used as term_char_t
+ * on this cell. Any numbers in the description are combined and are used as
+ * cell-age.
+ * The occurance of a '*'-symbol marks the cell as bold, '/' marks it as italic.
+ * You can use those characters multiple times, but only the first one has an
+ * effect.
+ * For further symbols, see parse_attr().
+ *
+ * Therefore, the following descriptions are equivalent:
+ *       1) "|   | /A*   |   |   |   |   |   | 10 *AB*  |"
+ *       2) "|   | /A**  |   |   |   |   |   | 10 *AB*  |"
+ *       3) "|   | A* // |   |   |   |   |   | 10 *AB*  |"
+ *       4) "|   | A* // |   |   |   |   |   | 1 *AB* 0 |"
+ *       5) "|   | A* // |   |   |   |   |   | A1B0*    |"
+ *
+ * The parser isn't very strict about placement of alpha/numerical characters,
+ * but simply appends all found chars. Don't make use of that feature! It's
+ * just a stupid parser to simplify these tests. Make them readable!
+ */
+
+static void parse_attr(char c, term_char_t *ch, term_attr *attr, term_age_t *age) {
+        switch (c) {
+        case ' ':
+                /* ignore */
+                break;
+        case '0' ... '9':
+                /* increase age */
+                *age = *age * 10;
+                *age = *age + c - '0';
+                break;
+        case 'A' ... 'Z':
+        case 'a' ... 'z':
+                /* add to character */
+                *ch = term_char_merge(*ch, c);
+                break;
+        case '*':
+                attr->bold = true;
+                break;
+        case '/':
+                attr->italic = true;
+                break;
+        default:
+                assert_se(0);
+                break;
+        }
+}
+
+static void cell_assert(MY_ASSERT_ARGS, term_cell *c, term_char_t ch, const term_attr *attr, term_age_t age) {
+        MY_ASSERT(term_char_equal(c->ch, ch));
+        MY_ASSERT(!memcmp(&c->attr, attr, sizeof(*attr)));
+        MY_ASSERT(c->age == age);
+}
+#define CELL_ASSERT(_cell, _ch, _attr, _age) cell_assert(MY_ASSERT_VALS, (_cell), (_ch), (_attr), (_age))
+
+static void line_assert(MY_ASSERT_ARGS, term_line *l, const char *str, unsigned int fill) {
+        unsigned int cell_i;
+        term_char_t ch = TERM_CHAR_NULL;
+        term_attr attr = { };
+        term_age_t age = TERM_AGE_NULL;
+        char c;
+
+        assert_se(l->fill == fill);
+
+        /* skip leading whitespace */
+        while (*str == ' ')
+                ++str;
+
+        /* skip leading '|' */
+        if (*str == '|')
+                ++str;
+
+        cell_i = 0;
+        while ((c = *str++)) {
+                switch (c) {
+                case '|':
+                        /* end of cell-description; compare it */
+                        assert_se(cell_i < l->n_cells);
+                        cell_assert(MY_ASSERT_FORW,
+                                    &l->cells[cell_i],
+                                    ch,
+                                    &attr,
+                                    age);
+
+                        ++cell_i;
+                        ch = term_char_free(ch);
+                        zero(attr);
+                        age = TERM_AGE_NULL;
+                        break;
+                default:
+                        parse_attr(c, &ch, &attr, &age);
+                        break;
+                }
+        }
+
+        assert_se(cell_i == l->n_cells);
+}
+#define LINE_ASSERT(_line, _str, _fill) line_assert(MY_ASSERT_VALS, (_line), (_str), (_fill))
+
+static void line_set(term_line *l, unsigned int pos, const char *str, bool insert_mode) {
+        term_char_t ch = TERM_CHAR_NULL;
+        term_attr attr = { };
+        term_age_t age = TERM_AGE_NULL;
+        char c;
+
+        while ((c = *str++))
+                parse_attr(c, &ch, &attr, &age);
+
+        term_line_write(l, pos, ch, 1, &attr, age, insert_mode);
+}
+
+static void line_resize(term_line *l, unsigned int width, const term_attr *attr, term_age_t age) {
+        assert_se(term_line_reserve(l, width, attr, age, width) >= 0);
+        term_line_set_width(l, width);
+}
+
+static void test_term_line_misc(void) {
+        term_line *l;
+
+        assert_se(term_line_new(&l) >= 0);
+        assert_se(!term_line_free(l));
+
+        assert_se(term_line_new(NULL) < 0);
+        assert_se(!term_line_free(NULL));
+
+        assert_se(term_line_new(&l) >= 0);
+        assert_se(l->n_cells == 0);
+        assert_se(l->fill == 0);
+        assert_se(term_line_reserve(l, 16, NULL, 0, 0) >= 0);
+        assert_se(l->n_cells == 16);
+        assert_se(l->fill == 0);
+        assert_se(term_line_reserve(l, 512, NULL, 0, 0) >= 0);
+        assert_se(l->n_cells == 512);
+        assert_se(l->fill == 0);
+        assert_se(term_line_reserve(l, 16, NULL, 0, 0) >= 0);
+        assert_se(l->n_cells == 512);
+        assert_se(l->fill == 0);
+        assert_se(!term_line_free(l));
+}
+
+static void test_term_line_ops(void) {
+        term_line *l;
+        term_attr attr_regular = { };
+        term_attr attr_bold = { .bold = true };
+        term_attr attr_italic = { .italic = true };
+
+        assert_se(term_line_new(&l) >= 0);
+        line_resize(l, 8, NULL, 0);
+        assert_se(l->n_cells == 8);
+
+        LINE_ASSERT(l, "| | | | | | | | |", 0);
+
+        term_line_write(l, 4, TERM_CHAR_NULL, 0, NULL, TERM_AGE_NULL, 0);
+        LINE_ASSERT(l, "| | | | | | | | |", 5);
+
+        term_line_write(l, 1, PACK1('A'), 1, NULL, TERM_AGE_NULL, 0);
+        LINE_ASSERT(l, "| |A| | | | | | |", 5);
+
+        term_line_write(l, 8, PACK2('A', 'B'), 1, NULL, TERM_AGE_NULL, 0);
+        LINE_ASSERT(l, "| |A| | | | | | |", 5);
+
+        term_line_write(l, 7, PACK2('A', 'B'), 1, &attr_regular, 10, 0);
+        LINE_ASSERT(l, "| |A| | | | | | 10 AB |", 8);
+
+        term_line_write(l, 7, PACK2('A', 'B'), 1, &attr_bold, 10, 0);
+        LINE_ASSERT(l, "| |A| | | | | | 10 *AB* |", 8);
+
+        term_line_reset(l, NULL, TERM_AGE_NULL);
+
+        LINE_ASSERT(l, "|   |   |          |          |          |   |   |   |", 0);
+        line_set(l, 2, "*wxyz* 8", 0);
+        line_set(l, 3, "/wxyz/ 8", 0);
+        LINE_ASSERT(l, "|   |   | *wxyz* 8 | /wxyz/ 8 |          |   |   |   |", 4);
+        line_set(l, 2, "*abc* 9", true);
+        LINE_ASSERT(l, "|   |   | *abc* 9  | *wxyz* 9 | /wxyz/ 9 | 9 | 9 | 9 |", 5);
+        line_set(l, 7, "*abc* 10", true);
+        LINE_ASSERT(l, "|   |   | *abc* 9  | *wxyz* 9 | /wxyz/ 9 | 9 | 9 | *abc* 10 |", 8);
+
+        term_line_erase(l, 6, 1, NULL, 11, 0);
+        LINE_ASSERT(l, "|   |   | *abc* 9  | *wxyz* 9 | /wxyz/ 9 | 9 | 11 | *abc* 10 |", 8);
+        term_line_erase(l, 6, 2, &attr_italic, 12, 0);
+        LINE_ASSERT(l, "|   |   | *abc* 9  | *wxyz* 9 | /wxyz/ 9 | 9 | 12 // | 12 // |", 6);
+        term_line_erase(l, 7, 2, &attr_regular, 13, 0);
+        LINE_ASSERT(l, "|   |   | *abc* 9  | *wxyz* 9 | /wxyz/ 9 | 9 | 12 // | 13 |", 6);
+        term_line_delete(l, 1, 3, &attr_bold, 14);
+        LINE_ASSERT(l, "|   | /wxyz/ 14 | 14 | 14 // | 14 | 14 ** | 14 ** | 14 ** |", 3);
+        term_line_insert(l, 2, 2, &attr_regular, 15);
+        LINE_ASSERT(l, "|   | /wxyz/ 14 | 15 | 15 | 15 | 15 // | 15 | 15 ** |", 5);
+
+        assert_se(!term_line_free(l));
+}
+
+int main(int argc, char *argv[]) {
+        test_term_char_misc();
+        test_term_char_packing();
+        test_term_char_allocating();
+
+        test_term_line_misc();
+        test_term_line_ops();
+
+        return 0;
+}
diff --git a/src/libsystemd-terminal/test-term-parser.c b/src/libsystemd-terminal/test-term-parser.c
new file mode 100644 (file)
index 0000000..ed16f5f
--- /dev/null
@@ -0,0 +1,143 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+/***
+  This file is part of systemd.
+
+  Copyright (C) 2014 David Herrmann <dh.herrmann@gmail.com>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+/*
+ * Terminal Parser Tests
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "macro.h"
+#include "term-internal.h"
+#include "util.h"
+
+static void test_term_utf8_invalid(void) {
+        term_utf8 p = { };
+        const uint32_t *res;
+        size_t len;
+
+        res = term_utf8_decode(NULL, NULL, 0);
+        assert_se(res == NULL);
+
+        res = term_utf8_decode(&p, NULL, 0);
+        assert_se(res != NULL);
+
+        len = 5;
+        res = term_utf8_decode(NULL, &len, 0);
+        assert_se(res == NULL);
+        assert_se(len == 0);
+
+        len = 5;
+        res = term_utf8_decode(&p, &len, 0);
+        assert_se(res != NULL);
+        assert_se(len == 1);
+
+        len = 5;
+        res = term_utf8_decode(&p, &len, 0xCf);
+        assert_se(res == NULL);
+        assert_se(len == 0);
+
+        len = 5;
+        res = term_utf8_decode(&p, &len, 0x0);
+        assert_se(res != NULL);
+        assert_se(len == 2);
+}
+
+static void test_term_utf8_range(void) {
+        term_utf8 p = { };
+        const uint32_t *res;
+        char u8[4];
+        uint32_t i, j;
+        size_t ulen, len;
+
+        /* Convert all ucs-4 chars to utf-8 and back */
+
+        for (i = 0; i < 0x10FFFF; ++i) {
+                ulen = term_utf8_encode(u8, i);
+                if (!ulen)
+                        continue;
+
+                for (j = 0; j < ulen; ++j) {
+                        res = term_utf8_decode(&p, &len, u8[j]);
+                        if (!res) {
+                                assert_se(j + 1 != ulen);
+                                continue;
+                        }
+
+                        assert_se(j + 1 == ulen);
+                        assert_se(len == 1 && *res == i);
+                        assert_se(i <= 127 || ulen >= 2);
+                }
+        }
+}
+
+static void test_term_utf8_mix(void) {
+        static const char source[] = {
+                0x00,                           /* normal 0 */
+                0xC0, 0x80,                     /* overlong 0 */
+                0xC0, 0x81,                     /* overlong 1 */
+                0xE0, 0x80, 0x81,               /* overlong 1 */
+                0xF0, 0x80, 0x80, 0x81,         /* overlong 1 */
+                0xC0, 0x00,                     /* invalid continuation */
+                0xC0, 0xC0, 0x81,               /* invalid continuation with a following overlong 1 */
+                0xF8, 0x80, 0x80, 0x80, 0x81,   /* overlong 1 with 5 bytes */
+                0xE0, 0x80, 0xC0, 0x81,         /* invalid 3-byte followed by valid 2-byte */
+                0xF0, 0x80, 0x80, 0xC0, 0x81,   /* invalid 4-byte followed by valid 2-byte */
+        };
+        static const uint32_t result[] = {
+                0x0000,
+                0x0000,
+                0x0001,
+                0x0001,
+                0x0001,
+                0x00C0, 0x0000,
+                0x00C0, 0x0001,
+                0x00F8, 0x0080, 0x0080, 0x0080, 0x0081,
+                0x00E0, 0x0080, 0x0001,
+                0x00F0, 0x0080, 0x0080, 0x0001,
+        };
+        term_utf8 p = { };
+        const uint32_t *res;
+        unsigned int i, j;
+        size_t len;
+
+        for (i = 0, j = 0; i < sizeof(source); ++i) {
+                res = term_utf8_decode(&p, &len, source[i]);
+                if (!res)
+                        continue;
+
+                assert_se(j + len <= ELEMENTSOF(result));
+                assert_se(!memcmp(res, &result[j], sizeof(uint32_t) * len));
+                j += len;
+        }
+
+        assert_se(j == ELEMENTSOF(result));
+}
+
+int main(int argc, char *argv[]) {
+        test_term_utf8_invalid();
+        test_term_utf8_range();
+        test_term_utf8_mix();
+
+        return 0;
+}
diff --git a/src/libsystemd-terminal/test-unifont.c b/src/libsystemd-terminal/test-unifont.c
new file mode 100644 (file)
index 0000000..2c41594
--- /dev/null
@@ -0,0 +1,128 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+/***
+  This file is part of systemd.
+
+  Copyright (C) 2014 David Herrmann <dh.herrmann@gmail.com>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+/*
+ * Test Unifont Helper
+ * This tries opening the binary unifont glyph-array and renders some glyphs.
+ * The glyphs are then compared to hard-coded glyphs.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "macro.h"
+#include "unifont-def.h"
+#include "unifont-internal.h"
+#include "util.h"
+
+static void render(char *w, const unifont_glyph *g) {
+        unsigned int i, j;
+        const uint8_t *d = g->data;
+
+        for (j = 0; j < 16; ++j) {
+                for (i = 0; i < 8 * g->cwidth; ++i) {
+                        if (d[i / 8] & (1 << (7 - i % 8)))
+                                *w++ = '#';
+                        else
+                                *w++ = ' ';
+                }
+                *w++ = '\n';
+                d += g->stride;
+        }
+
+        *w++ = 0;
+}
+
+static void test_unifont(void) {
+        char buf[4096];
+        unifont_glyph g;
+        unifont *u;
+
+        assert_se(unifont_new(&u) >= 0);
+
+        /* lookup invalid font */
+        assert_se(unifont_lookup(u, &g, 0xffffffffU) < 0);
+
+        /* lookup and render 'A' */
+        assert_se(unifont_lookup(u, &g, 'A') >= 0);
+        assert_se(g.width == 8);
+        assert_se(g.height == 16);
+        assert_se(g.stride >= 1);
+        assert_se(g.cwidth == 1);
+        assert_se(g.data != NULL);
+        render(buf, &g);
+        assert_se(!strcmp(buf,
+                          "        \n"
+                          "        \n"
+                          "        \n"
+                          "        \n"
+                          "   ##   \n"
+                          "  #  #  \n"
+                          "  #  #  \n"
+                          " #    # \n"
+                          " #    # \n"
+                          " ###### \n"
+                          " #    # \n"
+                          " #    # \n"
+                          " #    # \n"
+                          " #    # \n"
+                          "        \n"
+                          "        \n"
+                          ));
+
+        /* lookup and render '什' */
+        assert_se(unifont_lookup(u, &g, 0x4ec0) >= 0);
+        assert_se(g.width == 16);
+        assert_se(g.height == 16);
+        assert_se(g.stride >= 2);
+        assert_se(g.cwidth == 2);
+        assert_se(g.data != NULL);
+        render(buf, &g);
+        assert_se(!strcmp(buf,
+                          "    #     #     \n"
+                          "    #     #     \n"
+                          "    #     #     \n"
+                          "   #      #     \n"
+                          "   #      #     \n"
+                          "  ##      #     \n"
+                          "  ## ########## \n"
+                          " # #      #     \n"
+                          "#  #      #     \n"
+                          "   #      #     \n"
+                          "   #      #     \n"
+                          "   #      #     \n"
+                          "   #      #     \n"
+                          "   #      #     \n"
+                          "   #      #     \n"
+                          "   #      #     \n"
+                          ));
+
+        unifont_unref(u);
+}
+
+int main(int argc, char **argv) {
+        if (access(UNIFONT_PATH, F_OK))
+                return 77;
+
+        test_unifont();
+
+        return 0;
+}
diff --git a/src/libsystemd-terminal/unifont-def.h b/src/libsystemd-terminal/unifont-def.h
new file mode 100644 (file)
index 0000000..7a0d485
--- /dev/null
@@ -0,0 +1,137 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright (C) 2014 David Herrmann <dh.herrmann@gmail.com>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#pragma once
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include "sparse-endian.h"
+#include "util.h"
+
+typedef struct unifont_header unifont_header;
+typedef struct unifont_glyph_header unifont_glyph_header;
+
+/*
+ * Unifont: On-disk data
+ * Conventional font-formats have the problem that you have to pre-render each
+ * glyph before you can use it. If you just need one glyph, you have to parse
+ * the font-file until you found that glyph.
+ * GNU-Unifont is a bitmap font with very good Unicode coverage. All glyphs are
+ * (n*8)x16 bitmaps. Our on-disk data stores all those glyphs pre-compiled with
+ * fixed offsets. Therefore, the font-file can be mmap()ed and all glyphs can
+ * be accessed in O(1) (because all glyphs have the same size and thus their
+ * offsets can be easily computed). This guarantees, that the kernel only loads
+ * the pages that are really accessed. Thus, we have a far lower overhead than
+ * traditional font-formats like BDF. Furthermore, the backing file is read-only
+ * and can be shared in memory between multiple users.
+ *
+ * The binary-format starts with a fixed header:
+ *
+ *      | 2bytes | 2bytes | 2bytes | 2bytes |
+ *
+ *      +-----------------------------------+
+ *      |             SIGNATURE             |   8 bytes
+ *      +-----------------+-----------------+
+ *      |  COMPAT FLAGS   | INCOMPAT FLAGS  |   8 bytes
+ *      +-----------------+--------+--------+
+ *      |   HEADER SIZE   |GH-SIZE |G-STRIDE|   8 bytes
+ *      +-----------------+--------+--------+
+ *      |          GLYPH BODY SIZE          |   8 bytes
+ *      +-----------------------------------+
+ *
+ *  * The 8 bytes signature must be set to the ASCII string "DVDHRMUF".
+ *  * The 4 bytes compatible-flags field contains flags for new features that
+ *    might be added in the future and which are compatible to older parsers.
+ *  * The 4 bytes incompatible-flags field contains flags for new features that
+ *    might be added in the future and which are incompatible to old parses.
+ *    Thus, if you encounter an unknown bit set, you must abort!
+ *  * The 4 bytes header-size field contains the size of the header in bytes. It
+ *    must be at least 32 (the size of this fixed header). If new features are
+ *    added, it might be increased. It can also be used to add padding to the
+ *    end of the header.
+ *  * The 2 bytes glyph-header-size field specifies the size of each glyph
+ *    header in bytes (see below).
+ *  * The 2 bytes glyph-stride field specifies the stride of each line of glyph
+ *    data in "bytes per line".
+ *  * The 8 byte glyph-body-size field defines the size of each glyph body in
+ *    bytes.
+ *
+ * After the header, the file can contain padding bytes, depending on the
+ * header-size field. Everything beyond the header+padding is treated as a big
+ * array of glyphs. Each glyph looks like this:
+ *
+ *      |              1 byte               |
+ *
+ *      +-----------------------------------+
+ *      |               WIDTH               |   1 byte
+ *      +-----------------------------------+
+ *      ~              PADDING              ~
+ *      +-----------------------------------+
+ *      ~                                   ~
+ *      ~                                   ~
+ *      ~                DATA               ~
+ *      ~                                   ~
+ *      ~                                   ~
+ *      +-----------------------------------+
+ *
+ *  * The first byte specifies the width of the glyph. If it is 0, the glyph
+ *    must be treated as non-existant.
+ *    All glyphs are "8*n" pixels wide and "16" pixels high. The width-field
+ *    specifies the width multiplier "n".
+ *  * After the width field padding might be added. This depends on the global
+ *    glyph-header-size field. It defines the total size of each glyph-header.
+ *    After the glyph-header+padding, the data-field starts.
+ *  * The data-field contains a byte-array of bitmap data. The array is always
+ *    as big as specified in the global glyph-body-size header field. This might
+ *    include padding.
+ *    The array contains all 16 lines of bitmap information for that glyph. The
+ *    stride is given in the global glyph-stride header field. This can be used
+ *    to add padding after each line.
+ *    Each line is encoded as 1 bit per pixel bitmap. That is, each byte encodes
+ *    data for 8 pixels (left most pixel is encoded in the LSB, right most pixel
+ *    in the MSB). The width field defines the number of bytes valid per line.
+ *    For width==1, you need 1 byte to encode the 8 pixels. The stride defines
+ *    where the encoding of the next line starts.
+ *    Any data beyond the 16th line is padding and must be ignored.
+ */
+
+/* path to binary file */
+#define UNIFONT_PATH "/usr/share/unifont/unifont-glyph-array.bin"
+
+/* header-size of version 1 */
+#define UNIFONT_HEADER_SIZE_MIN 32
+
+struct unifont_header {
+        /* fields available in version 1 */
+        uint8_t signature[8];
+        le32_t compatible_flags;
+        le32_t incompatible_flags;
+        le32_t header_size;
+        le16_t glyph_header_size;
+        le16_t glyph_stride;
+        le64_t glyph_body_size;
+} _packed_;
+
+struct unifont_glyph_header {
+        /* fields available in version 1 */
+        uint8_t width;
+} _packed_;
diff --git a/src/libsystemd-terminal/unifont-glyph-array.bin b/src/libsystemd-terminal/unifont-glyph-array.bin
new file mode 100644 (file)
index 0000000..46f150c
Binary files /dev/null and b/src/libsystemd-terminal/unifont-glyph-array.bin differ
diff --git a/src/libsystemd-terminal/unifont-internal.h b/src/libsystemd-terminal/unifont-internal.h
new file mode 100644 (file)
index 0000000..c39512d
--- /dev/null
@@ -0,0 +1,54 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright (C) 2014 David Herrmann <dh.herrmann@gmail.com>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#pragma once
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include "util.h"
+
+typedef struct unifont unifont;
+typedef struct unifont_glyph unifont_glyph;
+
+/*
+ * Unifont
+ * The unifont API provides a glyph-lookup for bitmap fonts which can be used
+ * as fallback if no system-font is available or if you don't want to deal with
+ * full font renderers.
+ */
+
+struct unifont_glyph {
+        unsigned int width;
+        unsigned int height;
+        unsigned int stride;
+        unsigned int cwidth;
+        const void *data;       /* unaligned! */
+};
+
+int unifont_new(unifont **out);
+unifont *unifont_ref(unifont *u);
+unifont *unifont_unref(unifont *u);
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(unifont*, unifont_unref);
+
+unsigned int unifont_get_stride(unifont *u);
+int unifont_lookup(unifont *u, unifont_glyph *out, uint32_t ucs4);
diff --git a/src/libsystemd-terminal/unifont.c b/src/libsystemd-terminal/unifont.c
new file mode 100644 (file)
index 0000000..9e0f718
--- /dev/null
@@ -0,0 +1,211 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright (C) 2014 David Herrmann <dh.herrmann@gmail.com>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+/*
+ * Unifont
+ * This implements the unifont glyph-array parser and provides it via a simple
+ * API to the caller. No heavy transformations are performed so glyph-lookups
+ * stay as fast as possible.
+ */
+
+#include <endian.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include "macro.h"
+#include "unifont-def.h"
+#include "unifont-internal.h"
+#include "util.h"
+
+struct unifont {
+        unsigned long ref;
+
+        int fd;
+        const uint8_t *map;
+        size_t size;
+
+        unifont_header header;
+        const void *glyphs;     /* unaligned! */
+        size_t n_glyphs;
+        size_t glyphsize;
+};
+
+static int unifont_fetch_header(unifont *u) {
+        unifont_header h = { };
+        uint64_t glyphsize;
+
+        if (u->size < UNIFONT_HEADER_SIZE_MIN)
+                return -EBFONT;
+
+        assert_cc(sizeof(h) >= UNIFONT_HEADER_SIZE_MIN);
+        memcpy(&h, u->map, UNIFONT_HEADER_SIZE_MIN);
+
+        h.compatible_flags = le32toh(h.compatible_flags);
+        h.incompatible_flags = le32toh(h.incompatible_flags);
+        h.header_size = le32toh(h.header_size);
+        h.glyph_header_size = le16toh(h.glyph_header_size);
+        h.glyph_stride = le16toh(h.glyph_stride);
+        h.glyph_body_size = le64toh(h.glyph_body_size);
+
+        if (memcmp(h.signature, "DVDHRMUF", 8))
+                return -EBFONT;
+        if (h.incompatible_flags != 0)
+                return -EBFONT;
+        if (h.header_size < UNIFONT_HEADER_SIZE_MIN || h.header_size > u->size)
+                return -EBFONT;
+        if (h.glyph_header_size + h.glyph_body_size < h.glyph_header_size)
+                return -EBFONT;
+        if (h.glyph_stride * 16ULL > h.glyph_body_size)
+                return -EBFONT;
+
+        glyphsize = h.glyph_header_size + h.glyph_body_size;
+
+        if (glyphsize == 0 || glyphsize > u->size - h.header_size) {
+                u->n_glyphs = 0;
+        } else {
+                u->glyphs = u->map + h.header_size;
+                u->n_glyphs = (u->size - h.header_size) / glyphsize;
+                u->glyphsize = glyphsize;
+        }
+
+        memcpy(&u->header, &h, sizeof(h));
+        return 0;
+}
+
+static int unifont_fetch_glyph(unifont *u, unifont_glyph_header *out_header, const void **out_body, uint32_t ucs4) {
+        unifont_glyph_header glyph_header = { };
+        const void *glyph_body = NULL;
+        const uint8_t *p;
+
+        if (ucs4 >= u->n_glyphs)
+                return -ENOENT;
+
+        p = u->glyphs;
+
+        /* copy glyph-header data */
+        p += ucs4 * u->glyphsize;
+        memcpy(&glyph_header, p, MIN(sizeof(glyph_header), u->header.glyph_header_size));
+
+        /* copy glyph-body pointer */
+        p += u->header.glyph_header_size;
+        glyph_body = p;
+
+        if (glyph_header.width < 1)
+                return -ENOENT;
+        if (glyph_header.width > u->header.glyph_stride)
+                return -EBFONT;
+
+        memcpy(out_header, &glyph_header, sizeof(glyph_header));
+        *out_body = glyph_body;
+        return 0;
+}
+
+int unifont_new(unifont **out) {
+        _cleanup_(unifont_unrefp) unifont *u = NULL;
+        struct stat st;
+        int r;
+
+        assert_return(out, -EINVAL);
+
+        u = new0(unifont, 1);
+        if (!u)
+                return -ENOMEM;
+
+        u->ref = 1;
+        u->fd = -1;
+        u->map = MAP_FAILED;
+
+        u->fd = open(UNIFONT_PATH, O_RDONLY | O_CLOEXEC | O_NOCTTY);
+        if (u->fd < 0)
+                return -errno;
+
+        r = fstat(u->fd, &st);
+        if (r < 0)
+                return -errno;
+
+        u->size = st.st_size;
+        u->map = mmap(NULL, u->size, PROT_READ, MAP_PRIVATE, u->fd, 0);
+        if (u->map == MAP_FAILED)
+                return -errno;
+
+        r = unifont_fetch_header(u);
+        if (r < 0)
+                return r;
+
+        *out = u;
+        u = NULL;
+        return 0;
+}
+
+unifont *unifont_ref(unifont *u) {
+        if (!u || !u->ref)
+                return NULL;
+
+        ++u->ref;
+
+        return u;
+}
+
+unifont *unifont_unref(unifont *u) {
+        if (!u || !u->ref || --u->ref)
+                return NULL;
+
+        if (u->map != MAP_FAILED)
+                munmap((void*)u->map, u->size);
+        u->fd = safe_close(u->fd);
+        free(u);
+
+        return NULL;
+}
+
+unsigned int unifont_get_stride(unifont *u) {
+        assert(u);
+
+        return u->header.glyph_stride;
+}
+
+int unifont_lookup(unifont *u, unifont_glyph *out, uint32_t ucs4) {
+        unifont_glyph_header h = { };
+        const void *b = NULL;
+        unifont_glyph g = { };
+        int r;
+
+        assert_return(u, -EINVAL);
+
+        r = unifont_fetch_glyph(u, &h, &b, ucs4);
+        if (r < 0)
+                return r;
+
+        g.width = h.width * 8U;
+        g.height = 16U;
+        g.stride = u->header.glyph_stride;
+        g.cwidth = h.width;
+        g.data = b;
+
+        if (out)
+                memcpy(out, &g, sizeof(g));
+        return 0;
+}
diff --git a/src/libsystemd-terminal/unifont.hex b/src/libsystemd-terminal/unifont.hex
new file mode 100644 (file)
index 0000000..90672a8
--- /dev/null
@@ -0,0 +1,63488 @@
+0000:AAAA00018000000180004A51EA505A51C99E0001800000018000000180005555
+0001:AAAA00018000000180003993C252325F8A527193800000018000000180005555
+0002:AAAA00018000000180003BA5C124311989247125800000018000000180005555
+0003:AAAA00018000000180007BA5C1247919C1247925800000018000000180005555
+0004:AAAA000180000001800079BFC2487A49C2487989800000018000000180005555
+0005:AAAA00018000000180007A4DC2527B53C2D67A4F800000018000000180005555
+0006:AAAA000180000001800031A5CA287A31CA2849A5800000018000000180005555
+0007:AAAA000180000001800073D1CA1073D1CA1073DF800000018000000180005555
+0008:AAAA00018000000180001E3991401E3191081E71800000018000000180005555
+0009:AAAA000180000001800022F9A2203E21A2202221800000018000000180005555
+000A:AAAA000180000001800020F9A08020F9A0803E81800000018000000180005555
+000B:AAAA000180000001800022F9A220222194200821800000018000000180005555
+000C:AAAA00018000000180003EF9A0803EF9A0802081800000018000000180005555
+000D:AAAA00018000000180001EF1A08820F1A0901E89800000018000000180005555
+000E:AAAA00018000000180001E71A0881C8982883C71800000018000000180005555
+000F:AAAA00018000000180001EF9A0201C2182203CF9800000018000000180005555
+0010:AAAA0001800000018000391DA510251DA51039DD800000018000000180005555
+0011:AAAA00018000000180007189CA184A09CA08719D800000018000000180005555
+0012:AAAA00018000000180007199CA044A09CA10719D800000018000000180005555
+0013:AAAA00018000000180007199CA044A19CA047199800000018000000180005555
+0014:AAAA00018000000180007185CA0C4A15CA1C7185800000018000000180005555
+0015:AAAA00018000000180004993EA546A59DBD44A53800000018000000180005555
+0016:AAAA00018000000180003453C29A311789127113800000018000000180005555
+0017:AAAA00018000000180007BB9C1247939C1247939800000018000000180005555
+0018:AAAA00018000000180003325C4B447ADC4A434A5800000018000000180005555
+0019:AAAA00018000000180003E89A0D83EA9A0883E89800000018000000180005555
+001A:AAAA00018000000180003A5DC252325D8A52719D800000018000000180005555
+001B:AAAA000180000001800079CFC2107991C0507B8F800000018000000180005555
+001C:AAAA00018000000180001E7190801E61901010E1800000018000000180005555
+001D:AAAA00018000000180000E719080166192100EE1800000018000000180005555
+001E:AAAA00018000000180001C7192801C61941012E1800000018000000180005555
+001F:AAAA000180000001800012719280126192100CE1800000018000000180005555
+0020:00000000000000000000000000000000
+0021:00000000080808080808080008080000
+0022:00002222222200000000000000000000
+0023:000000001212127E24247E4848480000
+0024:00000000083E4948380E09493E080000
+0025:00000000314A4A340808162929460000
+0026:000000001C2222221C39454246390000
+0027:00000808080800000000000000000000
+0028:00000004080810101010101008080400
+0029:00000020101008080808080810102000
+002A:00000000000008492A1C2A4908000000
+002B:0000000000000808087F080808000000
+002C:00000000000000000000000018080810
+002D:0000000000000000003C000000000000
+002E:00000000000000000000000018180000
+002F:00000000020204080810102040400000
+0030:00000000182442424242424224180000
+0031:000000000818280808080808083E0000
+0032:000000003C4242020C102040407E0000
+0033:000000003C4242021C020242423C0000
+0034:00000000040C142444447E0404040000
+0035:000000007E4040407C020202423C0000
+0036:000000001C2040407C424242423C0000
+0037:000000007E0202040404080808080000
+0038:000000003C4242423C424242423C0000
+0039:000000003C4242423E02020204380000
+003A:00000000000018180000001818000000
+003B:00000000000018180000001808081000
+003C:00000000000204081020100804020000
+003D:000000000000007E0000007E00000000
+003E:00000000004020100804081020400000
+003F:000000003C4242020408080008080000
+0040:000000001C224A565252524E201E0000
+0041:0000000018242442427E424242420000
+0042:000000007C4242427C424242427C0000
+0043:000000003C42424040404042423C0000
+0044:00000000784442424242424244780000
+0045:000000007E4040407C404040407E0000
+0046:000000007E4040407C40404040400000
+0047:000000003C424240404E4242463A0000
+0048:00000000424242427E42424242420000
+0049:000000003E08080808080808083E0000
+004A:000000001F0404040404044444380000
+004B:00000000424448506060504844420000
+004C:000000004040404040404040407E0000
+004D:00000000424266665A5A424242420000
+004E:0000000042626252524A4A4646420000
+004F:000000003C42424242424242423C0000
+0050:000000007C4242427C40404040400000
+0051:000000003C4242424242425A663C0300
+0052:000000007C4242427C48444442420000
+0053:000000003C424240300C0242423C0000
+0054:000000007F0808080808080808080000
+0055:000000004242424242424242423C0000
+0056:00000000414141222222141408080000
+0057:00000000424242425A5A666642420000
+0058:00000000424224241818242442420000
+0059:00000000414122221408080808080000
+005A:000000007E02020408102040407E0000
+005B:0000000E080808080808080808080E00
+005C:00000000404020101008080402020000
+005D:00000070101010101010101010107000
+005E:00001824420000000000000000000000
+005F:00000000000000000000000000007F00
+0060:00201008000000000000000000000000
+0061:0000000000003C42023E4242463A0000
+0062:0000004040405C6242424242625C0000
+0063:0000000000003C4240404040423C0000
+0064:0000000202023A4642424242463A0000
+0065:0000000000003C42427E4040423C0000
+0066:0000000C1010107C1010101010100000
+0067:0000000000023A44444438203C42423C
+0068:0000004040405C624242424242420000
+0069:000000080800180808080808083E0000
+006A:0000000404000C040404040404044830
+006B:00000000404044485060504844420000
+006C:000000001808080808080808083E0000
+006D:00000000000076494949494949490000
+006E:0000000000005C624242424242420000
+006F:0000000000003C4242424242423C0000
+0070:0000000000005C6242424242625C4040
+0071:0000000000003A4642424242463A0202
+0072:0000000000005C624240404040400000
+0073:0000000000003C4240300C02423C0000
+0074:0000000010107C1010101010100C0000
+0075:000000000000424242424242463A0000
+0076:00000000000042424224242418180000
+0077:00000000000041494949494949360000
+0078:00000000000042422418182442420000
+0079:0000000000004242424242261A02023C
+007A:0000000000007E0204081020407E0000
+007B:0000000C101008081010080810100C00
+007C:00000808080808080808080808080808
+007D:00000030080810100808101008083000
+007E:00000031494600000000000000000000
+007F:AAAA000180000001800073D1CA104BD1CA1073DF800000018000000180005555
+0080:AAAA0001800000018000719DCA5273D3C252425D800000018000000180005555
+0081:AAAA0001800000018000499DCA527A5DCA504991800000018000000180005555
+0082:AAAA00018000000180007393CA52739FCA127213800000018000000180005555
+0083:AAAA00018000000180004B93EA525B9FCA524B93800000018000000180005555
+0084:AAAA000180000001800074B9A6A425A5A4A474B9800000018000000180005555
+0085:AAAA00018000000180004BD1EA105BD1CA104BDF800000018000000180005555
+0086:AAAA000180000001800039CDC212319F88527393800000018000000180005555
+0087:AAAA000180000001800079CDC212799FC0527B93800000018000000180005555
+0088:AAAA00018000000180004B9DC9207919C9044939800000018000000180005555
+0089:AAAA000180000001800025DDA4843C85A4842499800000018000000180005555
+008A:AAAA000180000001800045CDC4904489A8841099800000018000000180005555
+008B:AAAA0001800000018000721DCA127213C21243DD800000018000000180005555
+008C:AAAA00018000000180007213CA127213C21243CD800000018000000180005555
+008D:AAAA00018000000180000E2189200E218A200921800000018000000180005555
+008E:AAAA000180000001800039DDC202318D8850739F800000018000000180005555
+008F:AAAA000180000001800039DDC202318D8842739D800000018000000180005555
+0090:AAAA000180000001800071CFCA104A0DCA0271DD800000018000000180005555
+0091:AAAA00018000000180007245CA4C7245C244418F800000018000000180005555
+0092:AAAA0001800000018000725DCA42724DC250419F800000018000000180005555
+0093:AAAA00018000000180003B9DC120311989047139800000018000000180005555
+0094:AAAA000180000001800039D3C212421FC21239D3800000018000000180005555
+0095:AAAA00018000000180002289B6882AA9A2D82289800000018000000180005555
+0096:AAAA00018000000180003B8DC252339F8A127213800000018000000180005555
+0097:AAAA00018000000180007B8DC2527B9FC2127A13800000018000000180005555
+0098:AAAA0001800000018000398FC250324D8A42719D800000018000000180005555
+0099:AAAA0001800000018000339BC42225A394A2639B800000018000000180005555
+009A:AAAA000180000001800039DDC20832098A0871DD800000018000000180005555
+009B:AAAA000180000001800039DDC2084189C0483B9D800000018000000180005555
+009C:AAAA00018000000180000EF990200C2182201C21800000018000000180005555
+009D:AAAA000180000001800031CFCA104991C850338F800000018000000180005555
+009E:AAAA00018000000180001C8992D81CA990881089800000018000000180005555
+009F:AAAA0001800000018000338FCA507B91CA104A0F800000018000000180005555
+00A0:00000000000000000000000000000000
+00A1:00000000080800080808080808080000
+00A2:0000000008083E494848493E08080000
+00A3:000000000E1010107C1010103E610000
+00A4:000000000042243C24243C2442000000
+00A5:00000000412214087F087F0808080000
+00A6:00000000080808080000080808080000
+00A7:000000003C42403C42423C02423C0000
+00A8:24240000000000000000000000000000
+00A9:000000003C4299A5A1A1A599423C0000
+00AA:00001C021E221E003E00000000000000
+00AB:00000000001212242448242412120000
+00AC:000000000000000000007E0202020000
+00AD:AAAA000180003A63C25433C98A48724980000001800003C18000000180005555
+00AE:000000003C42B9A5A5B9A9A5423C0000
+00AF:00007E00000000000000000000000000
+00B0:10282810000000000000000000000000
+00B1:000000000808087F080808007F000000
+00B2:00001C22021C20203E00000000000000
+00B3:00001C22021C02221C00000000000000
+00B4:00040810000000000000000000000000
+00B5:000000000000000022222222362A2020
+00B6:0000003E7A7A7A7A3A0A0A0A0A0A0E00
+00B7:00000000000000001818000000000000
+00B8:00000000000000000000000000000830
+00B9:00000818280808080800000000000000
+00BA:00001C2222221C003E00000000000000
+00BB:00000000004848242412242448480000
+00BC:00000000226224282812162A4E420000
+00BD:000000002262242828141A22444E0000
+00BE:00000000621224186812162A4E420000
+00BF:000000000808000808304242423C0000
+00C0:300C000018242442427E424242420000
+00C1:0C30000018242442427E424242420000
+00C2:1824000018242442427E424242420000
+00C3:324C000018242442427E424242420000
+00C4:2424000018242442427E424242420000
+00C5:1824180018242442427E424242420000
+00C6:000000001F2848487F484848484F0000
+00C7:000000003C42424040404042423C0830
+00C8:300C00007E4040407C404040407E0000
+00C9:0C3000007E4040407C404040407E0000
+00CA:182400007E4040407C404040407E0000
+00CB:242400007E4040407C404040407E0000
+00CC:180600003E08080808080808083E0000
+00CD:0C3000003E08080808080808083E0000
+00CE:182400003E08080808080808083E0000
+00CF:242400003E08080808080808083E0000
+00D0:0000000078444242F242424244780000
+00D1:324C000042626252524A4A4646420000
+00D2:300C00003C42424242424242423C0000
+00D3:0C3000003C42424242424242423C0000
+00D4:182400003C42424242424242423C0000
+00D5:324C00003C42424242424242423C0000
+00D6:242400003C42424242424242423C0000
+00D7:00000000000000422418244200000000
+00D8:000000023A44464A4A525262225C4000
+00D9:300C00004242424242424242423C0000
+00DA:0C3000004242424242424242423C0000
+00DB:182400004242424242424242423C0000
+00DC:242400004242424242424242423C0000
+00DD:0C300000414122221408080808080000
+00DE:00000040407844424244784040400000
+00DF:00000000384444447C424242625C0000
+00E0:0000300C00003C42023E4242463A0000
+00E1:00000C3000003C42023E4242463A0000
+00E2:0000182400003C42023E4242463A0000
+00E3:0000324C00003C42023E4242463A0000
+00E4:0000242400003C42023E4242463A0000
+00E5:0018241800003C42023E4242463A0000
+00E6:0000000000003E49093F4848493E0000
+00E7:0000000000003C4240404040423C0830
+00E8:0000300C00003C42427E4040423C0000
+00E9:00000C3000003C42427E4040423C0000
+00EA:0000182400003C42427E4040423C0000
+00EB:0000242400003C42427E4040423C0000
+00EC:0000300C0000180808080808083E0000
+00ED:00000C300000180808080808083E0000
+00EE:000018240000180808080808083E0000
+00EF:000024240000180808080808083E0000
+00F0:0000320C1422023E42424242423C0000
+00F1:0000324C00005C624242424242420000
+00F2:0000300C00003C4242424242423C0000
+00F3:00000C3000003C4242424242423C0000
+00F4:0000182400003C4242424242423C0000
+00F5:0000324C00003C4242424242423C0000
+00F6:0000242400003C4242424242423C0000
+00F7:0000000000001800007E000018000000
+00F8:0000000000023C464A4A5252623C4000
+00F9:0000300C0000424242424242463A0000
+00FA:00000C300000424242424242463A0000
+00FB:000018240000424242424242463A0000
+00FC:000024240000424242424242463A0000
+00FD:00000C3000004242424242261A02023C
+00FE:0000000020203C222222242830202020
+00FF:0000242400004242424242261A02023C
+0100:003C000018242442427E424242420000
+0101:0000003C00003C42023E4242463A0000
+0102:42423C0018242442427E424242420000
+0103:0042423C00003C42023E4242463A0000
+0104:0000000018242442427E424242420403
+0105:0000000000003C42023E4242463A0403
+0106:0C3000003C42424040404042423C0000
+0107:00000C3000003C4240404040423C0000
+0108:182400003C42424040404042423C0000
+0109:0000182400003C4240404040423C0000
+010A:101000003C42424040404042423C0000
+010B:0000101000003C4240404040423C0000
+010C:241800003C42424040404042423C0000
+010D:0000241800003C4240404040423C0000
+010E:48300000784442424242424244780000
+010F:2418000202023A4642424242463A0000
+0110:0000000078444242F242424244780000
+0111:0000020F02023A4642424242463A0000
+0112:003C00007E4040407C404040407E0000
+0113:0000003C00003C42427E4040423C0000
+0114:42423C007E4040407C404040407E0000
+0115:000042423C003C42427E4040423C0000
+0116:101000007E4040407C404040407E0000
+0117:0000101000003C42427E4040423C0000
+0118:000000007E4040407C404040407E0806
+0119:0000000000003C42427E4040423C100C
+011A:241800007E4040407C404040407E0000
+011B:0000241800003C42427E4040423C0000
+011C:182400003C424240404E4242463A0000
+011D:0000182400023A44444438203C42423C
+011E:42423C003C424240404E4242463A0000
+011F:0042423C00023A44444438203C42423C
+0120:101000003C424240404E4242463A0000
+0121:0000101000023A44444438203C42423C
+0122:000000003C424240404E4242463A0830
+0123:00000C1000023A44444438203C42423C
+0124:18240000424242427E42424242420000
+0125:3048004040405C624242424242420000
+0126:000000004242FF42427E424242420000
+0127:000040F040405C624242424242000000
+0128:324C00003E08080808080808083E0000
+0129:0000324C0000180808080808083E0000
+012A:003C00003E08080808080808083E0000
+012B:0000003C0000180808080808083E0000
+012C:42423C003E08080808080808083E0000
+012D:000042423C00180808080808083E0000
+012E:000000003E08080808080808083E0806
+012F:000000080800180808080808083E0806
+0130:080800003E08080808080808083E0000
+0131:000000000000180808080808083E0000
+0132:000000004242424242420202423C0000
+0133:0000222200002222222222221A02221C
+0134:0C1200001F0404040404044444380000
+0135:00000C1200000C040404040404044830
+0136:000000004244485060605048444220C0
+0137:000000004040444850605048444220C0
+0138:00000000000042444870704844420000
+0139:186000004040404040404040407E0000
+013A:0C3000001808080808080808083E0000
+013B:000000004040404040404040407E0830
+013C:000000001808080808080808083E0830
+013D:241800004040404040404040407E0000
+013E:241800001808080808080808083E0000
+013F:000000004040404044444040407E0000
+0140:000000003010101014141010107C0000
+0141:000000004040485060C04040407E0000
+0142:0000000018080A0C18280808083E0000
+0143:0C30000042626252524A4A4646420000
+0144:00000C3000005C624242424242420000
+0145:0000000042626252524A4A46464220C0
+0146:0000000000005C6242424242424220C0
+0147:2418000042626252524A4A4646420000
+0148:0000241800005C624242424242420000
+0149:0060202040005C624242424242420000
+014A:000000005C62424242424242424C0000
+014B:0000000000005C62424242424242020C
+014C:003C00003C42424242424242423C0000
+014D:0000003C00003C4242424242423C0000
+014E:42423C003C42424242424242423C0000
+014F:000042423C003C4242424242423C0000
+0150:334400003C42424242424242423C0000
+0151:0000334400003C4242424242423C0000
+0152:00000000374848484E48484848370000
+0153:0000000000003649494F484849360000
+0154:0C3000007C4242427C48444442420000
+0155:00000C3000005C624240404040400000
+0156:000000007C4242427C484444424220C0
+0157:0000000000005C6242404040404020C0
+0158:241800007C4242427C48444442420000
+0159:0000241800005C624240404040400000
+015A:0C3000003C424240300C0242423C0000
+015B:00000C3000003C4240300C42423C0000
+015C:182400003C424240300C0242423C0000
+015D:0000182400003C4240300C02423C0000
+015E:000000003C424240300C0242423C0830
+015F:0000000000003C4240300C02423C0830
+0160:241800003C424240300C0242423C0000
+0161:0000241800003C4240300C02423C0000
+0162:000000007F0808080808080808080830
+0163:0000000010107C1010101010100C0830
+0164:241800007F0808080808080808080000
+0165:2418000010107C1010101010100C0000
+0166:000000007F08080A0C18280808080000
+0167:0000000010107C1014183050100C0000
+0168:324C00004242424242424242423C0000
+0169:0000324C0000424242424242463A0000
+016A:003C00004242424242424242423C0000
+016B:0000003C0000424242424242463A0000
+016C:42423C004242424242424242423C0000
+016D:0042423C0000424242424242463A0000
+016E:182418004242424242424242423C0000
+016F:000018241800424242424242463A0000
+0170:334400004242424242424242423C0000
+0171:000033440000424242424242463A0000
+0172:000000004242424242424242423C100C
+0173:000000000000424242424242463A0403
+0174:18240000424242425A5A666642420000
+0175:00001824000041494949494949360000
+0176:18240000414122221408080808080000
+0177:0000182400004242424242261A02023C
+0178:24240000414122221408080808080000
+0179:0C3000007E02020408102040407E0000
+017A:00000C3000007E0204081020407E0000
+017B:101000007E02020408102040407E0000
+017C:0000101000007E0204081020407E0000
+017D:241800007E02020408102040407E0000
+017E:0000241800007E0204081020407E0000
+017F:0000000C101010301010101010100000
+0180:00000040F0405C6242424242625C0000
+0181:000000007CA2A2223C222222223C0000
+0182:000000007E4040407C424242427C0000
+0183:000000007E40405C62424242625C0000
+0184:00000000602020203C222222223C0000
+0185:000000000000602020203C22223C0000
+0186:000000003C42420202020242427C0000
+0187:000003043C4444404040404444380000
+0188:0000000003043C444040404044380000
+0189:0000000078444242F242424244780000
+018A:0000000078A4A2222222222224380000
+018B:000000007E0202023E424242423E0000
+018C:000000007E02023A46424242463A0000
+018D:0000000000003C424242422418040438
+018E:000000007E0202023E020202027E0000
+018F:0000000018244202027E424224180000
+0190:000000003C42424038404042423C0000
+0191:000000001F1010101E10101010106000
+0192:0000000C1010107C1010101010106000
+0193:000000033C444440405C44444C340000
+0194:00000000424242242418182424180000
+0195:00000040404040724A4A4A4A4A440000
+0196:000000007010101010101010100C0000
+0197:000000003E0808083E080808083E0000
+0198:00000000464A50506060504844420000
+0199:00000030404044485060504844420000
+019A:00000000180808083E080808083E0000
+019B:00000000242810304818242442420000
+019C:00000000494949494949494949370000
+019D:00000000222232322A2A26262222C000
+019E:0000000000005C624242424242420202
+019F:000000003C4242427E424242423C0000
+01A0:000000023A4444444444444444380000
+01A1:0000000000023A444444444444380000
+01A2:00000000364A4A4A4A4A4A4A4A320202
+01A3:000000000000364A4A4A4A4A4A320202
+01A4:000000003E5151111E10101010100000
+01A5:0000000000035C644444444464584040
+01A6:0000000070203C22223C282422210000
+01A7:000000003C4242020C304042423C0000
+01A8:0000000000003C42020C3040423C0000
+01A9:000000007E40201008081020407E0000
+01AA:00000020505030101010101010100C00
+01AB:0000000010107C1010101010100C0418
+01AC:000000003F4848080808080808080000
+01AD:0000000C1010107C10101010100C0000
+01AE:000000007F0808080808080808080600
+01AF:00000101464444444444444444380000
+01B0:0000000001014644444444444C340000
+01B1:00000000422424424242424224180000
+01B2:000000004C4242424242424448300000
+01B3:00000000464544282810101010100000
+01B4:0000000000034444444444241C040438
+01B5:000000007E0204083C102040407E0000
+01B6:0000000000007E04083C1020407E0000
+01B7:000000007E0408101C020202463C0000
+01B8:000000007E20100838404040623C0000
+01B9:0000000000007C20100838404040423C
+01BA:0000000000003E04081C02023C40423C
+01BB:000000003C424204087E2040407E0000
+01BC:000000007E2020203C020202423C0000
+01BD:0000000000007E20203C0202423C0000
+01BE:0000000010107C101018040444380000
+01BF:0000000000005C624242444850604040
+01C0:00000010101010101010101010100000
+01C1:00000028282828282828282828280000
+01C2:000000101010107C107C101010100000
+01C3:00000000080808080808080008080000
+01C4:05020000675151515252545454670000
+01C5:00000502605057515152525454670000
+01C6:00000512101037515152525454370000
+01C7:00000000474141414141414949760000
+01C8:0000000141404341414141414179020C
+01C9:00000001612023212121212121F9020C
+01CA:000000004B4949696959594D4D4A0000
+01CB:0000000149486B69695959594949120C
+01CC:0000000101005369494949494949120C
+01CD:2418000018242442427E424242420000
+01CE:0000241800003C42023E4242463A0000
+01CF:241800003E08080808080808083E0000
+01D0:000024180000180808080808083E0000
+01D1:241800003C42424242424242423C0000
+01D2:0000241800003C4242424242423C0000
+01D3:241800004242424242424242423C0000
+01D4:000024180000424242424242463A0000
+01D5:3C0024004242424242424242423C0000
+01D6:003C00242400424242424242463A0000
+01D7:0C3000240042424242424242423C0000
+01D8:0C3000242400424242424242463A0000
+01D9:241800240042424242424242423C0000
+01DA:241800242400424242424242463A0000
+01DB:300C00240042424242424242423C0000
+01DC:300C00242400424242424242463A0000
+01DD:0000000000003C4202027E42423C0000
+01DE:3C00240018242442427E424242420000
+01DF:003C002424003C42023E4242463A0000
+01E0:3C00180018242442427E424242420000
+01E1:003C001010003C42023E4242463A0000
+01E2:003C00001F2848487F484848484F0000
+01E3:0000003C00003E49093F4848493E0000
+01E4:000000003C424240404E424F423E0000
+01E5:0000000000023A44444438203C4F423C
+01E6:241800003C424240404E4242463A0000
+01E7:0000241800023A44444438203C42423C
+01E8:24180000424448506060504844420000
+01E9:48300000404044485060504844420000
+01EA:000000003C42424242424242423C100C
+01EB:0000000000003C4242424242423C100C
+01EC:003C00003C42424242424242423C100C
+01ED:0000003C00003C4242424242423C100C
+01EE:241800007E0408101C020202463C0000
+01EF:0000241800003E0408101C020202423C
+01F0:0000120C00000C040404040404044830
+01F1:00000000675151515252545454670000
+01F2:00000000605057515152525454670000
+01F3:00000010101037515152525454370000
+01F4:0C3000003C424240404E4242463A0000
+01F5:00000C3000023A44444438203C42423C
+01F6:000000004848484A7A4A4A4A4A440000
+01F7:000000005C6242424448506040404000
+01F8:00300C0042626252524A4A4646420000
+01F9:000000300C005C624242424242420000
+01FA:0C30182418182424427E424242420000
+01FB:0C3000182418003C42023E42463A0000
+01FC:061800001F2848487F484848484F0000
+01FD:0000061800003E49093F4848493E0000
+01FE:0C3000023A44464A4A525262225C4000
+01FF:00000C3000023C464A4A5252623C4000
+0200:CC22000018242442427E424242420000
+0201:0000CC2200003C42023E4242463A0000
+0202:3C42420018242442427E424242420000
+0203:00003C4242003C42023E4242463A0000
+0204:CC2200007E4040407C404040407E0000
+0205:0000CC2200003C42427E4040423C0000
+0206:3C4242007E4040407C404040407E0000
+0207:00003C4242003C42427E4040423C0000
+0208:CC2200003E08080808080808083E0000
+0209:0000CC220000180808080808083E0000
+020A:3C4242003E08080808080808083E0000
+020B:00003C424200180808080808083E0000
+020C:CC2200003C42424242424242423C0000
+020D:0000CC2200003C4242424242423C0000
+020E:3C4242003C42424242424242423C0000
+020F:00003C4242003C4242424242423C0000
+0210:CC2200007C4242427C48444442420000
+0211:0000CC2200005C624240404040400000
+0212:3C4242007C4242427C48444442420000
+0213:00003C4242005C624240404040400000
+0214:CC2200004242424242424242423C0000
+0215:0000CC220000424242424242463A0000
+0216:3C4242004242424242424242423C0000
+0217:00003C424200424242424242463A0000
+0218:000000003C424240300C0242423C0810
+0219:0000000000003C4240300C02423C0810
+021A:000000007F0808080808080808080204
+021B:0000000010107C1010101010100C2040
+021C:000000003C4242020C340202023C0000
+021D:0000000000003C42020C32020C300000
+021E:00241800424242427E42424242420000
+021F:002418004040405C6242424242420000
+0220:0000000000005C624242424242420202
+0221:0000000202023A4642424242473B0204
+0222:0000000008244242243C4242423C0000
+0223:000000000000122224182422221C0000
+0224:000000007E02020408102040407E0204
+0225:0000000000007E0204081020407E0204
+0226:0000080018242442427E424242420000
+0227:0000000008003C42023E4242463A0000
+0228:000000007E4040407C404040407E0830
+0229:0000000000003C42427E4040423C0830
+022A:3C0024003C42424242424242423C0000
+022B:00003C0024003C4242424242423C0000
+022C:3C00324C003C424242424242423C0000
+022D:003C00324C003C4242424242423C0000
+022E:000008003C42424242424242423C0000
+022F:0000000008003C4242424242423C0000
+0230:3C0008003C42424242424242423C0000
+0231:00003C0008003C4242424242423C0000
+0232:00003E00414122221408080808080000
+0233:000000003C004242424242261A02023C
+0234:0000000018080808080808080C0C1020
+0235:0000000000005C624242424243430204
+0236:0000000010107C1010101010160E0810
+0237:0000000000000C040404040404044830
+0238:00000010101054BA92929292BA540000
+0239:00000000000054BA92929292BA541010
+023A:000000021A242C4A527E624242C20000
+023B:000000023C464A4850506062427C8000
+023C:0000000002043C4A50506060427C8000
+023D:000000002020202078202020203E0000
+023E:000001027F0C0C080818182828480000
+023F:0000000000003C4240300C02423C0906
+0240:0000000000007E02040810204060100E
+0241:000000003C4242020408080808080000
+0242:0000000000003C424202040808080000
+0243:000000003C2222223C227A22223C0000
+0244:000000004444444444FE444444380000
+0245:00000000181818242424244242420000
+0246:000004047E4848507C505060607E4040
+0247:0000000000023C464A7E5060427C8000
+0248:000000001F040404041F044444380000
+0249:0000000404000C04041F040404044830
+024A:0000000038444444444444444C340403
+024B:000000000000344C444444444C340403
+024C:000000003C2222227C28242422220000
+024D:0000000000002C322270202020200000
+024E:000000004141227F1408080808080000
+024F:0000000000002222227F22120E02021C
+0250:0000000000005C6242427C40423C0000
+0251:0000000000003A46424242464A320000
+0252:0000000000004C5262424242625C0000
+0253:0000003840405C6242424242625C0000
+0254:0000000000003C4202020202423C0000
+0255:0000000000003C424040404C523C4000
+0256:000000040404344C444444444C340300
+0257:000000030404344C444444444C340000
+0258:0000000000003C42427E0202423C0000
+0259:0000000000003C4202027E42423C0000
+025A:000000000000394604047C4444380000
+025B:0000000000003C42403C4040423C0000
+025C:0000000000003C42023C0202423C0000
+025D:00000000000039460438040444380000
+025E:0000000000003C42425C4242423C0000
+025F:0000000000000C0404041F0404044830
+0260:000000000003344C4444444C34044438
+0261:0000000000003A46424242463A02423C
+0262:0000000000003C4240404E42423E0000
+0263:00000000000042424224241818242418
+0264:00000000000042422424181824180000
+0265:0000000000424242424242463A020202
+0266:0000003840405C624242424242420000
+0267:0000003840405C6242424242424C0000
+0268:0000000808001808083E0808083E0000
+0269:000000000000101010101010100C0000
+026A:0000000000003E0808080808083E0000
+026B:00000000180808083A4C0808083E0000
+026C:0000000018080838483E0808083E0000
+026D:00000000180808080808080808080600
+026E:0000000030101F1112141611117D0906
+026F:00000000000049494949494949370000
+0270:00000000000049494949494949370101
+0271:00000000000076494949494949410600
+0272:00000000000016191111111111116000
+0273:00000000000058644444444444440300
+0274:000000000000424262524A4642420000
+0275:0000000000003C42427E4242423C0000
+0276:0000000000003748484E484848370000
+0277:0000000000003E414149494949360000
+0278:0000000008083E4949494949493E0808
+0279:000000000000020202020242463A0000
+027A:000000000202020202020242463A0000
+027B:0000000000000404040404444C340300
+027C:0000000000005C624240404040404040
+027D:0000000000005C624240404040403000
+027E:0000000000003C424240404040400000
+027F:0000000000003C424202020202020000
+0280:0000000000007C42427C444242420000
+0281:000000000000424242447C42427C0000
+0282:0000000000003C4240300C02427C4030
+0283:0000000C101010101010101010106000
+0284:0000000C1010101010107C1010106000
+0285:00000000000060101010101010100C00
+0286:000000060808080808080808384E3000
+0287:00000000601010101010107C10100000
+0288:0000000010107C101010101010100E00
+0289:0000000000002222227F2222261A0000
+028A:00000000000042244242424224180000
+028B:0000000000004C424242424448300000
+028C:00000000000018182424244242420000
+028D:00000000000036494949494949410000
+028E:0000000000003C404058644242424242
+028F:00000000000041412214080808080000
+0290:0000000000007C0808101020207C0403
+0291:0000000000007E0204081026497E1000
+0292:0000000000003E0408101C020202423C
+0293:0000000000003E0408101C0202324A3C
+0294:000000003C4242020408080808080000
+0295:000000003C4242402010101010100000
+0296:000000000808080808040242423C0000
+0297:0000000000003C42404040404040423C
+0298:0000000000003C42425A5A42423C0000
+0299:0000000000007C42427C4242427C0000
+029A:0000000000003C42423A4242423C0000
+029B:0000000000003B4440404C44443C0000
+029C:0000000000002222223E222222220000
+029D:0000000404000C0404040404043E4830
+029E:0000000000004222120A060A12220202
+029F:000000000000404040404040407E0000
+02A0:000000000003344C444444444C340404
+02A1:000000003C4242020408083E08080000
+02A2:000000003C4242402010107C10100000
+02A3:0000001010103F5152525454583F0000
+02A4:0000001010103F515254565151310906
+02A5:0000001010103F515254585A553E0400
+02A6:000000002020762828242221211E0000
+02A7:0000000324247C2424242424241C0418
+02A8:00000000202076292828282A2D1E0400
+02A9:000000003048406E515151515151020C
+02AA:000000002020202728282621213E0000
+02AB:00000000404040407E444850607E0000
+02AC:00000041494949360041494949360000
+02AD:000000007E42424200007E4242420000
+02AE:0000000000006424242424242C140404
+02AF:0000000000006424242424242C140403
+02B0:0000000020202C322222000000000000
+02B1:0000001C22202C322222000000000000
+02B2:00000004000404042418000000000000
+02B3:000000002C3220202000000000000000
+02B4:000000000404044C3400000000000000
+02B5:000000000404044C3403000000000000
+02B6:00000000444878444478000000000000
+02B7:00000000445454280000000000000000
+02B8:0000000044443C043800000000000000
+02B9:00000000081020000000000000000000
+02BA:00000000122448000000000000000000
+02BB:00000000081010180000000000000000
+02BC:00000000180808100000000000000000
+02BD:00000000181010080000000000000000
+02BE:00000030080404083000000000000000
+02BF:0000000C102020100C00000000000000
+02C0:0000003C4202021C1010000000000000
+02C1:0000003C424040380808000000000000
+02C2:00000004081020100804000000000000
+02C3:00000020100804081020000000000000
+02C4:00000000081422410000000000000000
+02C5:00000000412214080000000000000000
+02C6:00000000182400000000000000000000
+02C7:00000000241800000000000000000000
+02C8:00000000080808000000000000000000
+02C9:000000003C0000000000000000000000
+02CA:000000000C3000000000000000000000
+02CB:00000000300C00000000000000000000
+02CC:00000000000000000000080808080000
+02CD:000000000000000000000000003C0000
+02CE:00000000000000000000000000300C00
+02CF:000000000000000000000000000C3000
+02D0:00000000000000381000001038000000
+02D1:00000000000000003810000000000000
+02D2:00000000000030080404083000000000
+02D3:0000000000000C102020100C00000000
+02D4:00000000000000101010107C00000000
+02D5:000000000000007C1010101000000000
+02D6:0000000000000010107C101000000000
+02D7:0000000000000000007C000000000000
+02D8:000042423C0000000000000000000000
+02D9:00001818000000000000000000000000
+02DA:00001824180000000000000000000000
+02DB:00000000000000000000000000000806
+02DC:0000324C000000000000000000000000
+02DD:00003344000000000000000000000000
+02DE:000000000000002060A21C0000000000
+02DF:00000000422418244200000000000000
+02E0:00000000442810282810000000000000
+02E1:00003010101010380000000000000000
+02E2:000000003C4038047800000000000000
+02E3:00000000442810284400000000000000
+02E4:00003C40403808000000000000000000
+02E5:0000007C040404040404040404040000
+02E6:00000004047C04040404040404040000
+02E7:00000004040404047C04040404040000
+02E8:00000004040404040404047C04040000
+02E9:000000040404040404040404047C0000
+02EA:000000000000000040404040407C0000
+02EB:00000000000000404040784040400000
+02EC:00000000000000000000004428100000
+02ED:00007E007E0000000000000000000000
+02EE:00006622224400000000000000000000
+02EF:00000000000000000000000044281000
+02F0:00000000000000000000000010284400
+02F1:00000000000000000000040810080400
+02F2:00000000000000000000100804081000
+02F3:00000000000000000000000018241800
+02F4:00002010080000000000000000000000
+02F5:00004824120000000000000000000000
+02F6:00001224480000000000000000000000
+02F7:0000000000000000000000000000324C
+02F8:00000018180000001818000000000000
+02F9:00000038202020000000000000000000
+02FA:00000038080808000000000000000000
+02FB:00000000000000000000202020380000
+02FC:00000000000000000000080808380000
+02FD:0000000000000000000000000042427E
+02FE:0000000000000000000000000040407E
+02FF:00000000000010207E20100000000000
+0300:00201008000000000000000000000000
+0301:00040810000000000000000000000000
+0302:00182442000000000000000000000000
+0303:0000324C000000000000000000000000
+0304:00007E00000000000000000000000000
+0305:0000FF00000000000000000000000000
+0306:0042423C000000000000000000000000
+0307:00001818000000000000000000000000
+0308:00006666000000000000000000000000
+0309:00182404080800000000000000000000
+030A:00182424180000000000000000000000
+030B:00122448000000000000000000000000
+030C:00422418000000000000000000000000
+030D:00080808000000000000000000000000
+030E:00242424000000000000000000000000
+030F:00482412000000000000000000000000
+0310:00185A423C0000000000000000000000
+0311:003C4242000000000000000000000000
+0312:00081018000000000000000000000000
+0313:00180810000000000000000000000000
+0314:00181008000000000000000000000000
+0315:00060204000000000000000000000000
+0316:00000000000000000000000010080400
+0317:00000000000000000000000008102000
+0318:00000000000000000000000008380800
+0319:000000000000000000000000101C1000
+031A:000E0202000000000000000000000000
+031B:0000040A020408000000000000000000
+031C:00000000000000000000000018201800
+031D:00000000000000000000000010103800
+031E:00000000000000000000000038101000
+031F:000000000000000000000010107C1010
+0320:000000000000000000000000003C0000
+0321:00000000000000000000000202120C00
+0322:00000000000000000000000808090600
+0323:00000000000000000000000000181800
+0324:00000000000000000000000000666600
+0325:00000000000000000000000018242418
+0326:00000000000000000000000000180810
+0327:00000000000000000000001018043800
+0328:00000000000000000000000808060000
+0329:00000000000000000000000010101000
+032A:000000000000000000000000007E4200
+032B:00000000000000000000000049493600
+032C:00000000000000000000000042241800
+032D:00000000000000000000000018244200
+032E:00000000000000000000000042423C00
+032F:0000000000000000000000003C424200
+0330:00000000000000000000000000324C00
+0331:000000000000000000000000007E0000
+0332:00000000000000000000000000FF0000
+0333:000000000000000000000000FF00FF00
+0334:0000000000000000324C000000000000
+0335:00000000000000003C00000000000000
+0336:0000000000000000BD00000000000000
+0337:000000000000020C1830400000000000
+0338:000000000003020C183040C000000000
+0339:00000000000000000000000018040418
+033A:00000000000000000000000000427E00
+033B:0000000000000000000000003C24243C
+033C:000000000000000000000000006C9210
+033D:00661866000000000000000000000000
+033E:08101008100000000000000000000000
+033F:00FF00FF000000000000000000000000
+0340:00402010000000000000000000000000
+0341:00020408000000000000000000000000
+0342:00003448000000000000000000000000
+0343:00301020000000000000000000000000
+0344:00101054440000000000000000000000
+0345:0000000000000000000000001010100C
+0346:007E4200000000000000000000000000
+0347:000000000000000000000000007E007E
+0348:00000000000000000000000000002424
+0349:00000000000000000000000000001808
+034A:00083A5C100000000000000000000000
+034B:1010325C101000000000000000000000
+034C:324C00324C0000000000000000000000
+034D:00000000000000000000000000227F22
+034E:000000000000000000000000081C0808
+034F:555580000001800039C3C20242E3C22A39C5800002418000042180000241AAAA
+0350:04020408000000000000000000000000
+0351:18202018000000000000000000000000
+0352:3C425A18000000000000000000000000
+0353:00000000000000000000000000241818
+0354:00000000000000000000000004081008
+0355:00000000000000000000000010080408
+0356:000000000000000000000000844A2A51
+0357:18040418000000000000000000000000
+0358:00060600000000000000000000000000
+0359:00000000000000000000000054387C38
+035A:00000000000000000000000038545454
+035B:08103E04080000000000000000000000
+035C:00000000000000000000000000413E00
+035D:00000000413E00000000000000000000
+035E:00000000007F00000000000000000000
+035F:00000000000000000000000000007F00
+0360:0000314E000000000000000000000000
+0361:00003E41000000000000000000000000
+0362:00000000000000000000000000027F02
+0363:3C44444C340000000000000000000000
+0364:384478403C0000000000000000000000
+0365:10003010380000000000000000000000
+0366:38444444380000000000000000000000
+0367:444444443C0000000000000000000000
+0368:38404040380000000000000000000000
+0369:04043C243C0000000000000000000000
+036A:20203C24240000000000000000000000
+036B:0000EC92920000000000000000000000
+036C:00382420200000000000000000000000
+036D:20782020180000000000000000000000
+036E:00444428100000000000000000000000
+036F:24181824000000000000000000000000
+0370:00000000404040407C40404040400000
+0371:0000000000002050501E101010100000
+0372:00000000FE9292921010101010100000
+0373:000000007C5454541010101010100000
+0374:000000000C1810200000000000000000
+0375:0000000000000000000000000C181020
+0376:000000004246464A4A52526262420000
+0377:000000000000889898A8A8CACA840000
+0378:00007FFE738E6DF66DC66DF6738E7FFE7FFE61CE7DB67BCE77B677CE7FFE0000
+0379:00007FFE738E6DF66DC66DF6738E7FFE7FFE61CE7DB67BC677F677CE7FFE0000
+037A:00000000000000000000000000001018
+037B:0000000000003C4202020202423C0000
+037C:0000000000003C4240585840423C0000
+037D:0000000000003C42021A1A02423C0000
+037E:00000000000000001818000018080810
+037F:00007FFE738E6DF66DC66DF6738E7FFE7FFE61867DBE7B8E77BE77BE7FFE0000
+0380:00007FFE738E6DF66DC66DF6738E7FFE7FFE73CE6DB673B66DB673CE7FFE0000
+0381:00007FFE738E6DF66DC66DF6738E7FFE7FFE73EE6DCE73EE6DEE73C67FFE0000
+0382:00007FFE738E6DF66DC66DF6738E7FFE7FFE73866DF673866DBE73867FFE0000
+0383:00007FFE738E6DF66DC66DF6738E7FFE7FFE738E6DF673C66DF6738E7FFE0000
+0384:10101000000000000000000000000000
+0385:10101044440000000000000000000000
+0386:4040400018242442427E424242420000
+0387:0000000000000000081C080000000000
+0388:404040007E4040407C404040407E0000
+0389:40404000424242427E42424242420000
+038A:404040003E08080808080808083E0000
+038B:00007FFE738E6DF66DC66DF6738E7FFE7FFE738E6DB6738E6DB6738E7FFE0000
+038C:404040003C42424242424242423C0000
+038D:00007FFE738E6DF66DC66DF6738E7FFE7FFE738E6DB673B66DB6738E7FFE0000
+038E:40404000414122221408080808080000
+038F:404040003E4141414141412214147700
+0390:101010444400101010101010100C0000
+0391:0000000018242442427E424242420000
+0392:000000007C4242427C424242427C0000
+0393:000000007E4040404040404040400000
+0394:000000000808141422222241417F0000
+0395:000000007E4040407C404040407E0000
+0396:000000007E02020408102040407E0000
+0397:00000000424242427E42424242420000
+0398:000000003C4242427E424242423C0000
+0399:000000003E08080808080808083E0000
+039A:00000000424448506060504844420000
+039B:00000000080814142222224141410000
+039C:00000000424266665A5A424242420000
+039D:0000000042626252524A4A4646420000
+039E:000000007E0000003C000000007E0000
+039F:000000003C42424242424242423C0000
+03A0:000000007F2222222222222222220000
+03A1:000000007C4242427C40404040400000
+03A2:00007FFE738E6DF66DC66DF6738E7FFE7FFE61866DF661866DBE6D867FFE0000
+03A3:000000007E40201008081020407E0000
+03A4:000000007F0808080808080808080000
+03A5:00000000414122221408080808080000
+03A6:000000007F083E494949493E087F0000
+03A7:00000000424224241818242442420000
+03A8:0000000049494949493E080808080000
+03A9:000000003E4141414141221414770000
+03AA:242400003E08080808080808083E0000
+03AB:24240000414122221408080808080000
+03AC:001010100000324A444444444A320000
+03AD:0010101000003E40403C4040403E0000
+03AE:0010101000005C624242424242420202
+03AF:001010100000101010101010100C0000
+03B0:101010444400424242424242423C0000
+03B1:000000000000324A444444444A320000
+03B2:00000000384444447C424242625C4040
+03B3:00000000000031490A04080810100000
+03B4:000000001C20202018244242423C0000
+03B5:0000000000003C42403C4040423C0000
+03B6:0000000020201C0810202020201C021C
+03B7:0000000000005C624242424242420202
+03B8:00000000182424427E42422424180000
+03B9:000000000000101010101010100C0000
+03BA:00000000000022242830302824220000
+03BB:00000000202010100818242442420000
+03BC:0000000000004242424266665A424040
+03BD:00000000000042424244444850600000
+03BE:0000000040403C40403C40403C02023C
+03BF:0000000000003C4242424242423C0000
+03C0:0000000000007E242424242424240000
+03C1:0000000000003C4242424242625C4040
+03C2:0000000000001E20404040201C02021C
+03C3:0000000000003F484444444444380000
+03C4:0000000000007E1010101010100C0000
+03C5:000000000000424242424242423C0000
+03C6:000000000000264949494949493E0808
+03C7:00000000000042422424181824244242
+03C8:000000000000494949494949493E0808
+03C9:00000000000022414149494949360000
+03CA:000024240000101010101010100C0000
+03CB:000024240000424242424242423C0000
+03CC:0010101000003C4242424242423C0000
+03CD:001010100000424242424242423C0000
+03CE:00080808000022414149494949360000
+03CF:00000000424448506060504844420408
+03D0:000000001C2242447844424244380000
+03D1:000000000C1212120F226222221C0000
+03D2:000000003649080808080808081C0000
+03D3:004040003649080808080808081C0000
+03D4:003636003649080808080808081C0000
+03D5:0000000008083E4949494949493E0808
+03D6:0000000000007F224141494949360000
+03D7:0000000000004224283828282543020C
+03D8:000000003C42424242424242423C183C
+03D9:0000000000003C4242424242423C1818
+03DA:000000003844404040300C02023C0000
+03DB:000000000000003E4040201C021C0000
+03DC:000000007E4240407848404040400000
+03DD:000000000000003C2220203820202020
+03DE:0000000060202020203E040408080000
+03DF:000000000000000010207C0810000000
+03E0:000000001C22060A12264A12224C0000
+03E1:00000000000000601008182C14040404
+03E2:00000000DB49494949494937013E4000
+03E3:000000000000494949494937013E4000
+03E4:00000000324A4242463A020202020000
+03E5:0000000000001A2222221E0202020000
+03E6:000000007020202C32222202621C0000
+03E7:0000000000083C5252220202324C0000
+03E8:000000003C4242020C304242423C0000
+03E9:0000000000003C4242241820403E0000
+03EA:00000000C3A5241818242442427E0000
+03EB:000000000000245A18181824427E0000
+03EC:000000023C405C6242424242423C0000
+03ED:0000000000023C405C624242423C0000
+03EE:000000001C083E492A080808081C0000
+03EF:00000000000C08093E48080808180000
+03F0:00000000000062121418103048460000
+03F1:0000000000003C4242427C40403C0200
+03F2:0000000000023C4040404040403C0200
+03F3:0000020200000E020202020202221C00
+03F4:00000000182442427E42424224180000
+03F5:0000000000001C2040784040201C0000
+03F6:0000000000007008043C040408700000
+03F7:0000000000405C6242424242625C4040
+03F8:0000004040405C6242424242625C4040
+03F9:000000003C42424040404042423C0000
+03FA:00000000424266665A5A424242420000
+03FB:0000000000446C6C5454444445424040
+03FC:00000000002C3222222222322C207820
+03FD:000000003C42420202020242423C0000
+03FE:000000003C42424058584042423C0000
+03FF:000000003C4242021A1A0242423C0000
+0400:00300C007E4040407C404040407E0000
+0401:242400007E4040407C404040407E0000
+0402:000000007E1010101E11111111160000
+0403:0C3000007E4040404040404040400000
+0404:000000001C2240407C404040221C0000
+0405:000000003C424240300C0242423C0000
+0406:000000003E08080808080808083E0000
+0407:242400003E08080808080808083E0000
+0408:000000000E0404040404044444380000
+0409:00000000784848484E494949498E0000
+040A:00000000484848487E494949494E0000
+040B:000000007E1010101E11111111110000
+040C:0C300000404648506060504844420000
+040D:00300C004246464A4A52526262420000
+040E:42423C00414122221414080810300000
+040F:000000004141414141417F0808080000
+0410:0000000018242442427E424242420000
+0411:000000007C4040407C424242427C0000
+0412:000000007C4242427C424242427C0000
+0413:000000007E4040404040404040400000
+0414:000000000E1212122222224242FF8181
+0415:000000007E4040407C404040407E0000
+0416:0000000049492A2A1C1C2A2A49490000
+0417:000000003C4202023C040202423C0000
+0418:000000004246464A4A52526262420000
+0419:002418004246464A4A52526262420000
+041A:00000000404648506060504844420000
+041B:000000001E1212121212122222420000
+041C:00000000424266665A5A424242420000
+041D:00000000424242427E42424242420000
+041E:000000003C42424242424242423C0000
+041F:000000007E4242424242424242420000
+0420:000000007C4242427C40404040400000
+0421:000000003C42424040404042423C0000
+0422:000000007F0808080808080808080000
+0423:00000000414122221414080810300000
+0424:000000083E49494949493E0808080000
+0425:00000000424224241818242442420000
+0426:000000004242424242424242427F0101
+0427:0000000042424242427E020202020000
+0428:000000004949494949494949497F0000
+0429:00000000929292929292929292FF0101
+042A:00000000701010101E111111111E0000
+042B:0000000042424242724A4A4A4A720000
+042C:00000000404040407C424242427C0000
+042D:00000000384402023E02020244380000
+042E:000000004C52525272525252524C0000
+042F:000000003E4242423E12222242420000
+0430:0000000000003C42023E4242463A0000
+0431:0000021C20407C4242424242423C0000
+0432:0000000000007C42427C4242427C0000
+0433:0000000000007E404040404040400000
+0434:0000000000001E1222224242427F4100
+0435:0000000000003C42427E4040423C0000
+0436:00000000000049492A1C1C2A49490000
+0437:0000000000003C42023C0402423C0000
+0438:00000000000046464A4A525262620000
+0439:00002418000046464A4A525262620000
+043A:00000000000046485060504844420000
+043B:0000000000001E121212122222420000
+043C:0000000000004266665A5A4242420000
+043D:0000000000004242427E424242420000
+043E:0000000000003C4242424242423C0000
+043F:0000000000007E424242424242420000
+0440:0000000000007C424242427C40404040
+0441:0000000000003C4240404040423C0000
+0442:0000000000007F080808080808080000
+0443:00000000000042422424181810102060
+0444:000000000008083E494949493E080800
+0445:00000000000042422418182442420000
+0446:000000000000424242424242427F0101
+0447:000000000000424242427E0202020000
+0448:000000000000494949494949497F0000
+0449:00000000000092929292929292FF0101
+044A:0000000000007010101E1111111E0000
+044B:000000000000424242724A4A4A720000
+044C:0000000000004040407C4242427C0000
+044D:0000000000003844023E020244380000
+044E:0000000000004C5252725252524C0000
+044F:0000000000003E4242423E1222420000
+0450:0000300C00003C42427E4040423C0000
+0451:0000242400003C42427E4040423C0000
+0452:0000000020207820203C222222220C00
+0453:00000C3000007E404040404040400000
+0454:0000000000001C22407C4040221C0000
+0455:0000000000003C4240300C02423C0000
+0456:000000080800180808080808083E0000
+0457:000000242400180808080808083E0000
+0458:0000000404000C040404040404044830
+0459:0000000000007848484E4949498E0000
+045A:0000000000004848487E4949494E0000
+045B:0000000020207820202C322222220000
+045C:00000C30000046485060504844420000
+045D:0000300C000046464A4A525262620000
+045E:0042423C000042422424181810102060
+045F:0000000000002222222222223E080808
+0460:0000000049494949494949495A240000
+0461:00000000000022414149494949360000
+0462:00000000107C10101E111111111E0000
+0463:0000000020207820203C2222223C0000
+0464:00000000464950507E50505049460000
+0465:0000000000004649507E505049460000
+0466:000000000808141422362A4949490000
+0467:00000000000008141422364949490000
+0468:000000004848545452766A4949490000
+0469:00000000000048545452764949490000
+046A:000000003E222214081C2A4949490000
+046B:0000000000003E2214083E4949490000
+046C:000000005F51514A744E555555550000
+046D:0000000000005F514A744E5555550000
+046E:000024183C4202023C040202023C4040
+046F:0000002418003C42023C0402023C4040
+0470:0000000049494949493E080808080000
+0471:000000000000000049494949493E0808
+0472:000000003C4242427E424242423C0000
+0473:0000000000003C42427E4242423C0000
+0474:00000000434444442828281010100000
+0475:00000000000046484828282810100000
+0476:66110000434444442828281010100000
+0477:00006611000046484828282810100000
+0478:00000000205059595955565454240808
+0479:00000000000029595955565454240808
+047A:000000083E49414141414141493E0800
+047B:0000000000083E4941414141493E0800
+047C:3C431804080036414149494949360000
+047D:0000003C431804080036414949360000
+047E:007F080049494949494949495A240000
+047F:000000007F080049494949495A240000
+0480:000000003C424240404040403C040404
+0481:0000000000003C42424040403C040404
+0482:000000000000120C442A111824000000
+0483:00087840000000000000000000000000
+0484:00102848800000000000000000000000
+0485:00384030000000000000000000000000
+0486:00380418000000000000000000000000
+0487:00304C83000000000000000000000000
+0488:000000000100028010102828000000004008A014000000000000101029280280
+0489:000000000080108409880C30000000000008700E1000000000000CD808881084
+048A:002418004246464A4A52526262430204
+048B:00002418000046464A4A525262630204
+048C:0000000020702020203C2222263C0000
+048D:000000000000002070203C22223C0000
+048E:000000007C424A447A40404040400000
+048F:0000000000005C624242424A645A4040
+0490:000002027E4040404040404040400000
+0491:0000000002027E404040404040400000
+0492:000000001F101010107C101010100000
+0493:0000000000001F1010107C1010100000
+0494:000000007E404040407C424242420C00
+0495:0000000000007E4040407C4242420C00
+0496:0000000049492A2A1C1C2A2A49490101
+0497:00000000000049492A1C1C2A49490101
+0498:000000003C4202023C040202423C0830
+0499:0000000000003C42023C0402423C0830
+049A:00000000404648506060504844420202
+049B:00000000000046485060504844420202
+049C:00000000404354547854545442410000
+049D:00000000000043545478545442410000
+049E:00000000207324283030282422210000
+049F:00000000000023742830282422210000
+04A0:00000000E02324283030282422210000
+04A1:000000000000E3242830282422210000
+04A2:00000000424242427E42424242430101
+04A3:0000000000004242427E424242430101
+04A4:00000000474444447C44444444440000
+04A5:0000000000004744447C444444440000
+04A6:0000000078484848484E494949490106
+04A7:000000000000784848484E4949490106
+04A8:000000204C525252525252522C180600
+04A9:000000000000204C525252522C180600
+04AA:000000003C42424040404042423C100C
+04AB:0000000000003C4242404042423C100C
+04AC:000000007F08080808080808080C0404
+04AD:0000000000007F0808080808080C0404
+04AE:00000000414122221408080808080000
+04AF:00000000000022222214140808080808
+04B0:00000000414122221408083E08080000
+04B1:0000000000002222221408083E080000
+04B2:00000000424224241818242442430101
+04B3:00000000000042422418182442430101
+04B4:00000000FA22222222222222223F0101
+04B5:000000000000FA2222222222223F0101
+04B6:000000004242424242463A0202030101
+04B7:00000000000042424242463A02030101
+04B8:000000004242424252563A1212020000
+04B9:00000000000042424252563A12020000
+04BA:000000004040405C6242424242420000
+04BB:00000000000040405C62424242420000
+04BC:000000004C5252523E101012120C0000
+04BD:0000000000004C52523E1010120C0000
+04BE:000000004C5252523E101012120C0808
+04BF:000000004C5252523E101012120C0808
+04C0:000000003E08080808080808083E0000
+04C1:41413E0049492A2A1C1C2A2A49490000
+04C2:0022221C000049492A1C1C2A49490000
+04C3:0000000040464850607C42424242020C
+04C4:000000000000464850607C424242020C
+04C5:000000001E1212121212122222430204
+04C6:0000000000001E121212122222430204
+04C7:00000000424242427E4242424242020C
+04C8:0000000000004242427E42424242020C
+04C9:00000000424242427E42424242430204
+04CA:0000000000004242427E424242430204
+04CB:000000004242424242463A0202060404
+04CC:00000000000042424242463A02060404
+04CD:00000000424266665A5A424242430204
+04CE:0000000000004266665A5A4242430204
+04CF:000000001C08080808080808081C0000
+04D0:42423C0018242442427E424242420000
+04D1:0042423C00003C42023E4242463A0000
+04D2:2424000018242442427E424242420000
+04D3:0000242400003C42023E4242463A0000
+04D4:000000001F2848487F484848484F0000
+04D5:0000000000003E49093F4848493E0000
+04D6:42423C007E4040407C404040407E0000
+04D7:000042423C003C42427E4040423C0000
+04D8:0000000018244202027E424224180000
+04D9:0000000000003C4202027E42423C0000
+04DA:2424000018244202027E424224180000
+04DB:0000242400003C4202027E42423C0000
+04DC:2424000049492A2A1C1C2A2A49490000
+04DD:00002424000049492A1C1C2A49490000
+04DE:242400003C4202023C040202423C0000
+04DF:0000242400003C42023C0402423C0000
+04E0:000000007E0408101C020202463C0000
+04E1:0000000000003E0408101C020202423C
+04E2:003C00004246464A4A52526262420000
+04E3:0000003C000046464A4A525262620000
+04E4:242400004246464A4A52526262420000
+04E5:00002424000046464A4A525262620000
+04E6:242400003C42424242424242423C0000
+04E7:0000242400003C4242424242423C0000
+04E8:000000003C4242427E424242423C0000
+04E9:0000000000003C42427E4242423C0000
+04EA:242400003C4242427E424242423C0000
+04EB:0000242400003C42427E4242423C0000
+04EC:000024003C4202023E020202423C0000
+04ED:0000000024003C42021E0202423C0000
+04EE:003E0000414122221414080810300000
+04EF:0000003C000042422424181810102060
+04F0:24240000414122221414080810300000
+04F1:00002424000042422424181810102060
+04F2:33440000414122221414080810300000
+04F3:00003344000042422424181810102060
+04F4:242400004242424242463A0202020000
+04F5:00002424000042424242463A02020000
+04F6:000000007E4040404040404040703010
+04F7:0000000000007E404040404040703010
+04F8:2424000042424242724A4A4A4A720000
+04F9:000024240000424242724A4A4A720000
+04FA:000000007E4040407C40404040602060
+04FB:0000000000007C404078404040602060
+04FC:00000000424224241818242442420204
+04FD:00000000000042422418182442420204
+04FE:0000000042422424187E242442420000
+04FF:000000000000424224187E2442420000
+0500:0000000202023E4242424242463A0000
+0501:000000020202023A46424242463A0000
+0502:0000000404043C44444545454D360000
+0503:00000004040404344C4444454D360000
+0504:00000000384444041805050505020000
+0505:00000000000038444404180505020000
+0506:00000000384444041804040404030101
+0507:00000000000038444404180404030101
+0508:000000003C2424242425254545820000
+0509:0000000000003C242424244545820000
+050A:00000000444444447C45454545460000
+050B:0000000000004444447C444545460000
+050C:000000003C424240404E424244380000
+050D:0000000000003C4240404E42423C0000
+050E:000000007F08080808090909090E0000
+050F:0000000000007F0808080909090E0000
+0510:000000003C4240403C204040423C0000
+0511:0000000000003C42403C2040423C0000
+0512:000000001E1212121212122222420A0C
+0513:0000000000001E121212122222420A0C
+0514:00000000F1514A4A44444A4A51910000
+0515:000000000000F1514A44444A51910000
+0516:00000000E192949890F0888482810000
+0517:00000000000001E294989894E2818080
+0518:000000007F8888887F284848888F0000
+0519:0000000000007E89897F282849460000
+051A:000000003C4242424242425A663C0300
+051B:0000000000003A4642424242463A0202
+051C:00000000424242425A5A666642420000
+051D:00000000000041494949494949360000
+051E:000000004A444A506060504844420000
+051F:00000000000054485460504844420000
+0520:00000000705050505E51519191910502
+0521:0000000000007050505E515191910502
+0522:0000000090909090FE91919191910502
+0523:000000000000909090FE919191910502
+0524:000000007C4444444444444444470101
+0525:0000000000007C444444444444470101
+0526:0000000080808080F088848484870101
+0527:0000000080808080F0888888888E0202
+0528:00007FFE73866DBE6D866DF673867FFE7FFE61CE7DB661CE6FB661CE7FFE0000
+0529:00007FFE73866DBE6D866DF673867FFE7FFE61CE7DB661C66FF661CE7FFE0000
+052A:00007FFE73866DBE6D866DF673867FFE7FFE61867DB661866FB661B67FFE0000
+052B:00007FFE73866DBE6D866DF673867FFE7FFE618E7DB6618E6FB6618E7FFE0000
+052C:00007FFE73866DBE6D866DF673867FFE7FFE61C67DBE61BE6FBE61C67FFE0000
+052D:00007FFE73866DBE6D866DF673867FFE7FFE618E7DB661B66FB6618E7FFE0000
+052E:00007FFE73866DBE6D866DF673867FFE7FFE61867DBE618E6FBE61867FFE0000
+052F:00007FFE73866DBE6D866DF673867FFE7FFE61867DBE618E6FBE61BE7FFE0000
+0530:00007FFE73866DBE6D866DF673867FFE7FFE63CE7DB671B67DB663CE7FFE0000
+0531:00000000444444444444444745380000
+0532:000000003C4242407C42404040400000
+0533:0000000038444444443E050404040000
+0534:00000000384444040406050404040000
+0535:0000000040407C4240404042423C0000
+0536:000000001C222222221C0408107C0200
+0537:000000004040407C42404040407C0200
+0538:000000003C42424040404040407C0200
+0539:000000003844444F5454484040400000
+053A:00000000040404043F44444444380000
+053B:0000000040405C624240404040400000
+053C:000000004040404040404040407C0200
+053D:00000000404040794949464040400000
+053E:000000007E1824424242424224180000
+053F:00000000424242424242423E02020000
+0540:00000000081010081020406018060000
+0541:000000001C222222221C245848360000
+0542:00000000384444040404040404060100
+0543:000000000464182424424242427E0000
+0544:00000000474544444444444444380000
+0545:000000001C2202427C420202221C0000
+0546:00000000403010101010101011110E00
+0547:000000403C20404042424242423C0000
+0548:000000003C4242424242424242420000
+0549:000000001C222222221C0808107E0000
+054A:000000003E4949494909090101010000
+054B:000000001C22222222140C08107C0200
+054C:00000000384444474544444444440000
+054D:000000004242424242424242423C0000
+054E:00000000444444444444443C04060100
+054F:000000003C424240300C0242423C0000
+0550:000000003C4242404040404040400000
+0551:000000003C4242423C420202423C0000
+0552:00000000404058644444434040400000
+0553:00000000103854545454545438100000
+0554:000000000C1212121C107C1010100000
+0555:000000003C42424242424242423C0000
+0556:00000000384848380E090909493E0000
+0557:00007FFE73866DBE6D866DF673867FFE7FFE61866FF661EE7DDE61DE7FFE0000
+0558:00007FFE73866DBE6D866DF673867FFE7FFE61CE6FB661CE7DB661CE7FFE0000
+0559:10202010000000000000000000000000
+055A:20101020000000000000000000000000
+055B:08183000000000000000000000000000
+055C:0C300000000000000000000000000000
+055D:20100800000000000000000000000000
+055E:38445418000000000000000000000000
+055F:3050403C000000000000000000000000
+0560:00007FFE73866DBE6D866DF673867FFE7FFE73CE6FB663B66DB673CE7FFE0000
+0561:00000000000049494949494949370000
+0562:000000000000005C624242407E404040
+0563:000000000000344C444444443F040404
+0564:00000000000058644444444444470404
+0565:00000000004040407E404242625C0000
+0566:000000000000344C444444443C040407
+0567:0000000040407C404040404040380400
+0568:0000000000005C62424242424242407E
+0569:0000000000005864444F545448404040
+056A:000000000404043F4444444444380000
+056B:0000000040405C624242424242424040
+056C:0000000000004040404040404040407C
+056D:00000000404040794949494946404040
+056E:000000007008043F4444444444380000
+056F:000000004040424242424242423E0202
+0570:000000004040405C6242424242420000
+0571:000000000810083E42424242423E0000
+0572:00000000000058644444444444440407
+0573:000000000E11107F11111111130D0000
+0574:0000000002050444444444444C340000
+0575:0000000000000C040404040404044830
+0576:000000003C42404242424242463A0000
+0577:000000003844040808101020203F0000
+0578:0000000000005C624242424242420000
+0579:000000001020100808101020203F0000
+057A:00000000000049494949494949370101
+057B:000000003844444828101020203F0000
+057C:00000000000058644444444444470000
+057D:000000000000424242424242463A0000
+057E:0000000004040444444444444C340407
+057F:0000000000004A4D4949494959290000
+0580:0000000000005C624242424242424040
+0581:0000000000003A46424242463A02423C
+0582:000000000000180808080808080E0000
+0583:0000000008084A4D4949494959290808
+0584:0000000E1110107C1010101010100000
+0585:0000000000003C4242424242423C0000
+0586:00000000384848380E090909493E0808
+0587:000000004040404444444444443B0000
+0588:00007FFE73866DBE6D866DF673867FFE7FFE73CE6DB673CE6DB673CE7FFE0000
+0589:00000000000018180000001818000000
+058A:0000000000000000000000623C000000
+058B:00007FFE73866DBE6D866DF673867FFE7FFE738E6DB6738E6DB6738E7FFE0000
+058C:00007FFE73866DBE6D866DF673867FFE7FFE73C66DBE73BE6DBE73C67FFE0000
+058D:00007FFE73866DBE6D866DF673867FFE7FFE738E6DB673B66DB6738E7FFE0000
+058E:00007FFE73866DBE6D866DF673867FFE7FFE73866DBE738E6DBE73867FFE0000
+058F:00000000384444041F041F0404040000
+0590:00007FFE73866DBE6D866DF673867FFE7FFE73CE6DB671B67DB673CE7FFE0000
+0591:000000000000000000000008081C2200
+0592:00001800660000000000000000000000
+0593:0C300C300C3000000000000000000000
+0594:00180018000000000000000000000000
+0595:002C202C000000000000000000000000
+0596:00000000000000000000000010100C00
+0597:081C3E1C080000000000000000000000
+0598:0024524A240000000000000000000000
+0599:0000C020200000000000000000000000
+059A:00000000000000000000000002040200
+059B:00000000000000000000000068680870
+059C:000C1010000000000000000000000000
+059D:00000304040000000000000000000000
+059E:06081314040000000000000000000000
+059F:0042A542240000000000000000000000
+05A0:00020502040000000000000000000000
+05A1:00000050608000000000000000000000
+05A2:00000000000000000000000000443810
+05A3:00000000000000000000000008083800
+05A4:00000000000000000000000008100800
+05A5:00000000000000000000000008083000
+05A6:00000000000000000000000014640830
+05A7:00000000000000000000001820180418
+05A8:00003008080000000000000000000000
+05A9:00205020100000000000000000000000
+05AA:000000000000000000000000221C0808
+05AB:00102010000000000000000000000000
+05AC:0004041C000000000000000000000000
+05AD:00000000000000000000000004040300
+05AE:0048A8A8900000000000000000000000
+05AF:00182424180000000000000000000000
+05B0:00000000000000000000000018001800
+05B1:0000000000000000000000002A001200
+05B2:0000000000000000000000003A000200
+05B3:0000000000000000000000003A101200
+05B4:00000000000000000000000018180000
+05B5:00000000000000000000000066660000
+05B6:00000000000000000000000000660018
+05B7:000000000000000000000000003C0000
+05B8:000000000000000000000000003E0808
+05B9:00003030000000000000000000000000
+05BA:00006060000000000000000000000000
+05BB:00000000000000000000000020080200
+05BC:00000000000000001800000000000000
+05BD:00000000000000000000000008080800
+05BE:00003E7C000000000000000000000000
+05BF:0000003C000000000000000000000000
+05C0:00000000000808080808080808080000
+05C1:00000606000000000000000000000000
+05C2:00006060000000000000000000000000
+05C3:000000000000081C080000081C080000
+05C4:00001818000000000000000000000000
+05C5:00001818000000000000000000000000
+05C6:000000000038202020202020203C0000
+05C7:0000000000000000000000003E080808
+05C8:00007FFE73866DBE6D866DF673867FFE7FFE71CE6FB66FCE6FB671CE7FFE0000
+05C9:00007FFE73866DBE6D866DF673867FFE7FFE71CE6FB66FC66FF671CE7FFE0000
+05CA:00007FFE73866DBE6D866DF673867FFE7FFE71866FB66F866FB671B67FFE0000
+05CB:00007FFE73866DBE6D866DF673867FFE7FFE718E6FB66F8E6FB6718E7FFE0000
+05CC:00007FFE73866DBE6D866DF673867FFE7FFE71C66FBE6FBE6FBE71C67FFE0000
+05CD:00007FFE73866DBE6D866DF673867FFE7FFE718E6FB66FB66FB6718E7FFE0000
+05CE:00007FFE73866DBE6D866DF673867FFE7FFE71866FBE6F8E6FBE71867FFE0000
+05CF:00007FFE73866DBE6D866DF673867FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+05D0:0000000000424222122C484442420000
+05D1:00000000007C040404040404047F0000
+05D2:000000000030080808040C1422420000
+05D3:00000000007E04040404040404040000
+05D4:00000000007E02022222222222220000
+05D5:00000000003808080808080808080000
+05D6:0000000000300C0A0808080808080000
+05D7:00000000007E22222222222222220000
+05D8:0000000000464A4242424242427E0000
+05D9:00000000003808080800000000000000
+05DA:00000000007E02020202020202020202
+05DB:00000000007E020202020202027C0000
+05DC:00000020203E02020202040408300000
+05DD:0000000000FE222222222222223E0000
+05DE:00000000004E31214141414141470000
+05DF:00000000003808080808080808080808
+05E0:00000000001C040404040404043C0000
+05E1:00000000007E42424242424244780000
+05E2:00000000001212121212121212FE0000
+05E3:00000000007E42424272020202020202
+05E4:00000000007E424242720202027E0000
+05E5:00000000002222242830202020202020
+05E6:000000000042422418080402027E0000
+05E7:00000000007E22222424282020202020
+05E8:00000000007E02020202020202020000
+05E9:000000000049494949494949497F0000
+05EA:00000000003E22222222222222620000
+05EB:00007FFE73866DBE6D866DF673867FFE7FFE618E6FB6638E6FB6618E7FFE0000
+05EC:00007FFE73866DBE6D866DF673867FFE7FFE61C66FBE63BE6FBE61C67FFE0000
+05ED:00007FFE73866DBE6D866DF673867FFE7FFE618E6FB663B66FB6618E7FFE0000
+05EE:00007FFE73866DBE6D866DF673867FFE7FFE61866FBE638E6FBE61867FFE0000
+05EF:00007FFE73866DBE6D866DF673867FFE7FFE61866FBE638E6FBE61BE7FFE0000
+05F0:00000000007711111111111111110000
+05F1:00000000007711111101010101010000
+05F2:00000000007711111100000000000000
+05F3:00000204080000000000000000000000
+05F4:00001224480000000000000000000000
+05F5:00007FFE73866DBE6D866DF673867FFE7FFE61866FBE63866FF66F867FFE0000
+05F6:00007FFE73866DBE6D866DF673867FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+05F7:00007FFE73866DBE6D866DF673867FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+05F8:00007FFE73866DBE6D866DF673867FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+05F9:00007FFE73866DBE6D866DF673867FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+05FA:00007FFE73866DBE6D866DF673867FFE7FFE61866FB663866FB66FB67FFE0000
+05FB:00007FFE73866DBE6D866DF673867FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+05FC:00007FFE73866DBE6D866DF673867FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+05FD:00007FFE73866DBE6D866DF673867FFE7FFE618E6FB663B66FB66F8E7FFE0000
+05FE:00007FFE73866DBE6D866DF673867FFE7FFE61866FBE638E6FBE6F867FFE0000
+05FF:00007FFE73866DBE6D866DF673867FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+0600:5555800000018000000180000001800000018004000980083FFD80000001AAAA
+0601:55558000000180000001800000018000000180042A0DAA0C35F580000001AAAA
+0602:5555800000018000000180000001800000018E000E1987E0000180000001AAAA
+0603:555580000001800000018000001980240045814401499EF0000180000001AAAA
+0604:55558000000180000001800000018000000180000195827C0201BF000001AAAA
+0605:00007FFE73CE6DBE6D8E6DB673CE7FFE7FFE73866DBE6D866DF673867FFE0000
+0606:000000A870A810D0088008800480040002700240014001800180010001000000
+0607:00200040708010A0084008900460040002700240014001800180010001000000
+0608:000000000000000000640E9832B004500410082007C000000000000000000000
+0609:00000004042808101020204450000000
+060A:00000004042808101020214450000000
+060B:000000000600060000C0012000E0002001C01E10000800080000000000000000
+060C:00000000000000081018180000000000
+060D:00000000000000000C18204000000000
+060E:0000000000000000000000000000000000000E00110011060FF8000000000000
+060F:0000000000000600080008000600080013001480188009001600200000000000
+0610:00060939160000000000000000000000
+0611:0000003000400278038004000800000000000000000000000000000000000000
+0612:00001F880208041008E008000000000000000000000000000000000000000000
+0613:0000060809083910166000000000000000000000000000000000000000000000
+0614:0000000000081FC8002800100000000000000000000000000000000000000000
+0615:0000040005C006200FC000000000000000000000000000000000000000000000
+0616:0500050005000D0010000FE00000000000000000000000000000000000000000
+0617:0000008000000080008003000000000000000000000000000000000000000000
+0618:0000000000C00300000000000000000000000000000000000000000000000000
+0619:0000008001400180030004800000000000000000000000000000000000000000
+061A:00000000000003C0000000000000000000000000000000000000000000C00300
+061B:00000000000000081018001800000000
+061C:AAAA000180000001B2224A37FA2A4A23CBA20001800000018000000180005555
+061D:00007FFE73CE6DBE6D8E6DB673CE7FFE7FFE7B8E73B67BB67BB6718E7FFE0000
+061E:0000000000000000000000000000000000000000000000800000014000000000
+061F:0000003E414020100808000800000000
+0620:000000000000000C5248443810281000
+0621:000000000000001C203C102000000000
+0622:00013E40080808080808080000000000
+0623:18201820080808080808080000000000
+0624:00000C100C10000C12121E0204483000
+0625:0000000008080808080808000C100C10
+0626:00000000182018200046484846423C00
+0627:00000008080808080808080000000000
+0628:000000000000000422423C0000080000
+0629:000000240000182422221C0000000000
+062A:000000001400000422423C0000000000
+062B:000010002800000422423C0000000000
+062C:00000000000000007E1020404840221C
+062D:00000000000000007E1020404040221C
+062E:00000000001000007E1020404040221C
+062F:000000000000080402427C0000000000
+0630:000000002000080402427C0000000000
+0631:00000000000000000402020204483000
+0632:00000000001000000402020204483000
+0633:00000000000000000115155E48483000
+0634:00000008001200000115155E48483000
+0635:000000000000000006194E4848300000
+0636:000000000004000006194E4848300000
+0637:000000202020202C32227C0000000000
+0638:000000202420202C32227C0000000000
+0639:000000000000001824201C204040423C
+063A:000000000800001824201C204040423C
+063B:00005004081020403C827E0000000000
+063C:00000004081020403C827E0028001000
+063D:0000000000205050044A484442423C00
+063E:0000000000005000044A484442423C00
+063F:0000000000200050044A484442423C00
+0640:00000000000000000000FF0000000000
+0641:0000000800060A0642423C0000000000
+0642:000000002400001C120A264244380000
+0643:000000020A120A2242423C0000000000
+0644:000000020202020202224242443C0000
+0645:00000000000000001C061E2020202020
+0646:00000000001000000422424244380000
+0647:00000000000000000200018003400520052003200CC030004000000000000000
+0648:000000000000000C12121E0204483000
+0649:0000000000000000044A484442423C00
+064A:0000000000000000044A4844423C0028
+064B:000C300C300000000000000000000000
+064C:00060632143800000000000000000000
+064D:0000000000000000000008300C300000
+064E:0000000C300000000000000000000000
+064F:00001028281C10200000000000000000
+0650:00000000000000000000000000000C30
+0651:00000004145860000000000000000000
+0652:00000018242418000000000000000000
+0653:0000013E400000000000000000000000
+0654:18201820000000000000000000000000
+0655:00000000000000000000000018201820
+0656:0000000000000000000000000000000000000000000000000000004000200020
+0657:0040008001000700030000000000000000000000000000000000000000000000
+0658:0000000002400240018000000000000000000000000000000000000000000000
+0659:00000000000003C0000000000000000000000000000000000000000000000000
+065A:0000044002800100010000000000000000000000000000000000000000000000
+065B:0000010001000280044000000000000000000000000000000000000000000000
+065C:0000000000000000000000000000000000000000000000000180018000000000
+065D:0300070001000080004000000000000000000000000000000000000000000000
+065E:0000024001800180024000000000000000000000000000000000000000000000
+065F:00000000000000000000001C203C1020
+0660:00000000000010381000000000000000
+0661:00000020201010080804040400000000
+0662:00000022241810080804040400000000
+0663:00000049523C20101008080800000000
+0664:00000004081020182040423C00000000
+0665:00000018242442424242241800000000
+0666:000000403C0404020202010100000000
+0667:00000041412222141408080800000000
+0668:00000008080814142222414100000000
+0669:0000001824444C340202010100000000
+066A:00000404484810102424404000000000
+066B:00000000000000000004040438000000
+066C:00000018180810000000000000000000
+066D:000000000008087F1C36220000000000
+066E:000000000000000422423C0000000000
+066F:00000000000000000300048004800380208041003E0000000000000000000000
+0670:00000008080808000000000000000000
+0671:040A1E20080808080808080000000000
+0672:06082658000808080808080000000000
+0673:00000000080808080808080006082658
+0674:18201820000000000000000000000000
+0675:06080608202020202020200000000000
+0676:000003040304000C12121E0204483000
+0677:000033341324400C12121E0204483000
+0678:00000000030403040046484846423C00
+0679:000020203838000422423C0000000000
+067A:000010001000000422423C0000000000
+067B:000000000000000422423C0008000800
+067C:000000001400000422423C0814080000
+067D:000028001000000422423C0000000000
+067E:000000000000000422423C0014000800
+067F:000028002800000422423C0000000000
+0680:000000000000000422423C0014001400
+0681:00000018201820007E1020404040221C
+0682:00000010001000007E1020404040221C
+0683:00000000000000007E1020405440221C
+0684:00000000000000007E1020484048221C
+0685:00000010002400007E1020404040221C
+0686:00000000000000007E2040544048221C
+0687:00000000000000007E2040544054221C
+0688:002020383800080402427C0000000000
+0689:000000000000080402427C0814080000
+068A:000000000000080402427C0008000000
+068B:002020383800080402427C0008000000
+068C:000000280000080402427C0000000000
+068D:000000000000080402427C0028000000
+068E:000010002800080402427C0000000000
+068F:000028001000080402427C0000000000
+0690:000028002800080402427C0000000000
+0691:000008080E0E00000402020204483000
+0692:0000110A040400000402020204483000
+0693:000000000000000004020202044C3A04
+0694:00000000000000000402020204483200
+0695:00000000000000000804040408483502
+0696:00000000000000000402021204483200
+0697:00000000001200000402020204483000
+0698:00000008001400000402020204483000
+0699:00000012001200000402020204483000
+069A:000000000400000115155E484A300000
+069B:000000000000000115155E5055200200
+069C:000008001200000115155E5055200200
+069D:000000000000000006194E5055200000
+069E:000000080012000006194E4848300000
+069F:00000024202A202C32227C0000000000
+06A0:000010002400001824201C204040423C
+06A1:0000000000060A0642423C0000000000
+06A2:0000000000060A0642423C0008000000
+06A3:0000040000060A0642423C0008000000
+06A4:0008001200060A0642423C0000000000
+06A5:0000000000060A0642423C0024001000
+06A6:000A000A00060A0642423C0000000000
+06A7:000000000400001C120A264244380000
+06A8:000010002400001C120A264244380000
+06A9:00000004081020403C827E0000000000
+06AA:0000000000000018006001800600080007FC40023FFC00000000000000000000
+06AB:000000040C1A24403C827E0000000000
+06AC:000800020A120A2242423C0000000000
+06AD:100028020A120A2242423C0000000000
+06AE:000000020A120A2242423C0014000800
+06AF:00081024481020403C827E0000000000
+06B0:000810244C1A24403C827E0000000000
+06B1:00500618620C30403C827E0000000000
+06B2:00081024481020403C827E0028000000
+06B3:00081024481020403C827E0010001000
+06B4:4000A618620C30403C827E0000000000
+06B5:110A04040002020202224242443C0000
+06B6:000200020202020202224242443C0000
+06B7:040009000202020202224242443C0000
+06B8:00000002020202020222423C00140008
+06B9:00000000000800000422424244380008
+06BA:00000000000000000422424244380000
+06BB:000010101C1C00000422424244380000
+06BC:000000000008000004224242443C0A04
+06BD:00000010002400000422424244380000
+06BE:000000000000102C2A1A244000000000
+06BF:00000000001000007E2040544048221C
+06C0:001820182000101824243C0000000000
+06C1:000000000000000000102E4000000000
+06C2:000000001820182000102E4000000000
+06C3:000000000000280000102E4000000000
+06C4:000000000000000C12120E2252247800
+06C5:000000000000000C12121E021C483000
+06C6:000022140808000C12121E0204483000
+06C7:001028281C10204C12121E0204483000
+06C8:000000080404000C12121E0204483000
+06C9:000000081422000C12121E0204483000
+06CA:000000001400000C12121E0204483000
+06CB:000008001200000C12121E0204483000
+06CC:0000000000000000044A484442423C00
+06CD:0000000000000000042A68A422221C00
+06CE:0000004428101000044A484442423C00
+06CF:000000000800000C12121E0204483000
+06D0:000000000000000C5248443800100010
+06D1:000000000000000C5248443800280010
+06D2:00000000000000000008141020407F00
+06D3:00000000003040304008141020407F00
+06D4:000000000000000000003C0000000000
+06D5:000000000000101824243C0000000000
+06D6:0208025C0FFC10001FC000000000000000000000000000000000000000000000
+06D7:024802200FE010001FC000000000000000000000000000000000000000000000
+06D8:0000004000A001E0060000000000000000000000000000000000000000000000
+06D9:0880048003000100030000000000000000000000000000000000000000000000
+06DA:1F8004000900042003C000000000000000000000000000000000000000000000
+06DB:0000000A000800000000000000000000
+06DC:0000012809F80900060000000000000000000000000000000000000000000000
+06DD:5555800001C186300BE98C181005900410058C180BE9863001C180000001AAAA
+06DE:0000008001401FFC1414180C11C432265225322611C4180C14141FFC01400080
+06DF:0000018002800280018000000000000000000000000000000000000000000000
+06E0:0180024002400240018000000000000000000000000000000000000000000000
+06E1:000007E000400300000000000000000000000000000000000000000000000000
+06E2:0180038002000200010000000000000000000000000000000000000000000000
+06E3:000000000000000000000000000000000000000000000000012809F809000600
+06E4:0000000000600780000000000000000000000000000000000000000000000000
+06E5:00060604380000000000000000000000
+06E6:001020407F0000000000000000000000
+06E7:00000400080010001FC000000000000000000000000000000000000000000000
+06E8:000000800420042003E000000000000000000000000000000000000000000000
+06E9:00000080014002A005500AA815542A2A15541554155415D4141417F430067FFF
+06EA:0100028004400280010000000000000000000000000000000000000000000000
+06EB:0000000000000000000000000000000000000000000001000280044002800100
+06EC:0000018001800000000000000000000000000000000000000000000000000000
+06ED:0000000000000000000000000000000000000000000000000180010001000080
+06EE:000008142200080402427C0000000000
+06EF:00000000040A11000402020204483000
+06F0:00000000000010381000000000000000
+06F1:00000020201010080804040400000000
+06F2:00000022241810080804040400000000
+06F3:00000049523C20101008080800000000
+06F4:000000182460722C2010101000000000
+06F5:00000000080814142222495563000000
+06F6:000000001C2220201806186000000000
+06F7:00000041412222141408080800000000
+06F8:00000008080814142222414100000000
+06F9:0000001824444C340202010100000000
+06FA:000008001200000115155E484A300000
+06FB:000000000004000006194E484A300000
+06FC:000000000800001824201C204840423C
+06FD:0000000000001C203C10200014141414
+06FE:00000000000000001C063E404A4A4A4A
+06FF:00000200050008800200018003400520052003200CC030004000000000000000
+0700:000000000000000001000380010008201C700820010003800100000000000000
+0701:0000000000001800180000000000000000000000000000000000000000000000
+0702:0000000000000000000000000000000000001800180000000000000000000000
+0703:0000000000001800180000000000000000001800180000000000000000000000
+0704:0000000000000000000000000000000018001800000000000000000018001800
+0705:0000000000000000000000006600660000000000000000000000000000000000
+0706:0000000000000000000000006000600000000000060006000000000000000000
+0707:0000000000000000000000000600060000000000000060006000000000000000
+0708:0000000060006000000000000600060000000000000000000000000000000000
+0709:0000000000000000000000000000000000000000600060000000000006000600
+070A:0000240024007E00000000000000000018001800000000000000000018001800
+070B:00000000000000007FFE00000000018001800000000000000000000000000000
+070C:00004000200010000800040002000100008000400024001C001C003C00000000
+070D:00000180018019981998018001807FFE7FFE0180018019981998018001800000
+070E:00007FFE73866DF66DEE6DDE73DE7FFE7FFE73866DBE6D8E6DBE73867FFE0000
+070F:00000000318C3FFC318C00000000000000000000000000000000000000000000
+0710:0000000000070007000E003C7FF8FFC0C600C300C1C0C0F04070000000000000
+0711:02000C00780050000C0000000000000000000000000000000000000000000000
+0712:000000000000000000000C000FF007F80008600860087FF83FF0000000000000
+0713:00000600070003000180018070C07C600F3003F000F8001C0006000000000000
+0714:00000600070003000180018073C07E600F3003F000F8001C0006000000000000
+0715:0000000000003F003E000E000600060006000600260006000200000000000000
+0716:0000000000003F003E000E000600060006000600060006000200000000000000
+0717:000000000000000000001F783FFC60844082408241026106320C000000000000
+0718:0000000000000000000007800CC0186010201030101019980F98000000000000
+0719:0000000000000C000E000E000600060006000600060006000200000000000000
+071A:00000000000000000000030C030C010601020082408260843FFC1F7800000000
+071B:00000C000E00060003000100018060807FF83FFC004200420042002400180000
+071C:00000C000E00060003000100018060807FF83FFC0042005A005A002400180000
+071D:000000000000000000000000000000000000300018000C000C000C0018003000
+071E:000002000000050000001DC03FE062204224422244126412240C008000000000
+071F:00000000000000001800186018701C9804980788030C00040004000200020001
+0720:000000000E000E0006000300018000C00060303030303FF01FF0000000000000
+0721:00000000000070007E001FF803FC03040304030403FC06F80C00180010000000
+0722:00000000000000000000000000001C003E003F8007C000F00018000400020000
+0723:000000000000000000003C00667843CC4184618431881FF00FE0000000000000
+0724:000000000000000000003C00667843CC4184618431881FF00FE0018001800000
+0725:00000000000000000000000003000300018060C060607FFE3FFE000000000000
+0726:000000000000000001E002300210021801E8600C60047FFE3FFE000000000000
+0727:00000000000000000F001880108030802F00600C400CFFFCFFF8000000000000
+0728:0000000000000000001000380FFC1FFC10000C0003C0003000180038FFF00000
+0729:00000000000000000000000001F003F802080204020413FC17FC0C0000000000
+072A:0200000000003F003E000E000600060006000600060006000200000000000000
+072B:0000000000000000000006600FF00FF007E003C061867FFE3FFE000000000000
+072C:000060007000300008C005E0061006100A081108208C3F8C1F0C000000000000
+072D:000000000020006000C0018003FC03FE0002000260027FFE3FFC000000000000
+072E:00000300018019801F000C000200010060807C403FE007F8001C000600020000
+072F:0000000000003F003E000E000600060006000600460006001200000000000000
+0730:3E00240028003000200000000000000000000000000000000000000000000000
+0731:0000000000000000000000000000000000000000000004000C00140024007C00
+0732:0000000004000000000000000000000000000000000000000000000020000000
+0733:1800240024001800100020000000000000000000000000000000000000000000
+0734:0000000000000000000000000000000000000000040008001800240024001800
+0735:0000080000002000000000000000000000000000000000000000000000000000
+0736:180004000A001200000000000000000000000000000000000000000000000000
+0737:0000000000000000000000000000000000000000000000002400280010000C00
+0738:0000000000000000000000000000000000000000000000000000000000002400
+0739:0000000000000000000000000000000000000000000000000000000008002000
+073A:7C0010007C000000000000000000000000000000000000000000000000000000
+073B:00000000000000000000000000000000000000000000000000003E0008003E00
+073C:0000000000000000000000000000000000000000000000000000000000001000
+073D:0100020005000880124005200210000000000000000000000000000000000000
+073E:0000000000000000000000000000000000001080094004900220014000800100
+073F:0000000000000800000000000000000000000000000000000000000000000000
+0740:0000000000002000000000000000000000000000000000000000000000000000
+0741:0000000000001000000000000000000000000000000000000000000000000000
+0742:0000000000000000000000000000000000000000000000000000000010000000
+0743:0000100000001000000000000000000000000000000000000000000000000000
+0744:0000000000000000000000000000000000000000000000000000100000001000
+0745:0000100000002800000000000000000000000000000000000000000000000000
+0746:0000000000000000000000000000000000000000000000000000280000001000
+0747:0000000008001000200000000000000000000000000000000000000000000000
+0748:0000000000000000000000000000000000000000000000000000200010000800
+0749:012000D000E8017400BA005C002C001200000000000000000000000000000000
+074A:540010007C001000540000000000000000000000000000000000000000000000
+074B:00007FFE73866DF66DEE6DDE73DE7FFE7FFE6D8E6DB6618E7DB67D8E7FFE0000
+074C:00007FFE73866DF66DEE6DDE73DE7FFE7FFE6DC66DBE61BE7DBE7DC67FFE0000
+074D:00001818181818180C300C30042004600660066002C002C003C0018001800000
+074E:00000000000C000600E600FC003000100008000860047FFE3FFE000000000000
+074F:00000180018000C0002C00320012001C0008000860047FFE3FFE000000000000
+0750:000000000000000422423C00002A0000
+0751:000000100028000422423C0000080000
+0752:000000000000000422423C0008001400
+0753:000000000820000422423C0008001400
+0754:000000000010000422423C0000140000
+0755:000000000000000422423C0008142200
+0756:000000442810000422423C0000000000
+0757:00000000000028007E1020404040221C
+0758:00000000000000007E1024404A40221C
+0759:002038247800080402427C0010001000
+075A:000000000000080402427C0008142200
+075B:00000000000000000402021F04483000
+075C:00000000001400140115155E48483000
+075D:000000000028001824201C204040423C
+075E:000000280010001824201C204040423C
+075F:000000100010001824201C204040423C
+0760:0000000000060A0642423C000A000000
+0761:0000000000060A0642423C0004000A00
+0762:00000004881020403C827E0000000000
+0763:004000A4081020403C827E0000000000
+0764:00000004081020403C827E0008001400
+0765:00000000000800001C061E2020202020
+0766:00000000000000001C061E2028202020
+0767:00000000000020000422424244380014
+0768:00203824780020000422424244380000
+0769:00004428100020000422424244380000
+076A:000000040404041E0424444444380000
+076B:00000000100010000402020204483000
+076C:00000018201820000402020204483000
+076D:00000000040004000115155E48483000
+076E:00000000000000007E10284C4A5C221C
+076F:00000000007E10284C4A5C405440221C
+0770:202028347800140115155E4848300000
+0771:20202834780010400402020204483000
+0772:00001010141A3C007E1020404040221C
+0773:28283020282808080808080000000000
+0774:2A2A3420282808080808080000000000
+0775:00000014141810101046484846423C00
+0776:00000015151A10101046484846423C00
+0777:0000000046484846423C000816101010
+0778:000050506040404C12121E0204483000
+0779:000054546840404C12121E0204483000
+077A:00000000005050604048541020407F00
+077B:00000000005454684048541020407F00
+077C:00000000000000007E10244B4848221C
+077D:000008161010100115155E4848300000
+077E:000000081414000115155E4848300000
+077F:0000000A22020A120A0A3202047C0000
+0780:00000000000000000000101020400000
+0781:00000000000000000000121C20400000
+0782:000000000000000000002A3440800000
+0783:0000000000000000120C0C1220400000
+0784:00000000000000000000285454280000
+0785:00000000000000000010241810200000
+0786:00000000000000000000242830200000
+0787:00000000000000000000040C14240000
+0788:00000000000000000814140810200000
+0789:00000000000000003804040810200000
+078A:00000000000002040204020408100000
+078B:00000000000000000002040418204000
+078C:00000000000000000C122C4020400000
+078D:000000000000000008123C0810200000
+078E:00000000000000000004081008300000
+078F:00000000000000000054284040380000
+0790:000000000000000000000000000000000000000018081FF02000000000000000
+0791:000000000000000008100C08101E0000
+0792:00000000000000120C0C1220201C0000
+0793:00000000000000142A2A1420201C0000
+0794:000000000000000000161A1220400000
+0795:00000000000002040204020408120000
+0796:00000000000000040808704040380000
+0797:00000000000102040C1A2A4420C00000
+0798:0000000004000A000C1A2A4420C00000
+0799:00000000000000000000101020480000
+079A:00000000000000001000101020400000
+079B:00000000000000040002040418204000
+079C:0000000000000400120C0C1220400000
+079D:000000000000000000000000000000800000014018081FF02000000000000000
+079E:000000000000000000000000000000000000000018081FF02000010000000000
+079F:000000000000000000000000000000000000010018081FF02000000000000000
+07A0:00000000000000000C122C4024400000
+07A1:00000000000004000C122C4020400000
+07A2:00000000000000000000040C14240010
+07A3:00000000000000000400040C14240000
+07A4:00000000000000140004081008300000
+07A5:00000000000008000814140810200000
+07A6:00102040000000000000000000000000
+07A7:00000000006000000000000000000000
+07A8:00000000000000000000000000102040
+07A9:00000000000000000000000000102448
+07AA:00601020400000000000000000000000
+07AB:00661122440000000000000000000000
+07AC:00102040300000000000000000000000
+07AD:22448866000000000000000000000000
+07AE:42241866000000000000000000000000
+07AF:00244048300000000000000000000000
+07B0:00304830000000000000000000000000
+07B1:00000000000010282810204040380000
+07B2:00007FFE73866DF66DEE6DDE73DE7FFE7FFE63866DF663866DBE63867FFE0000
+07B3:00007FFE73866DF66DEE6DDE73DE7FFE7FFE638E6DF663C66DF6638E7FFE0000
+07B4:00007FFE73866DF66DEE6DDE73DE7FFE7FFE63B66DB663866DF663F67FFE0000
+07B5:00007FFE73866DF66DEE6DDE73DE7FFE7FFE63866DBE63866DF663867FFE0000
+07B6:00007FFE73866DF66DEE6DDE73DE7FFE7FFE63CE6DBE638E6DB663CE7FFE0000
+07B7:00007FFE73866DF66DEE6DDE73DE7FFE7FFE63866DF663EE6DDE63DE7FFE0000
+07B8:00007FFE73866DF66DEE6DDE73DE7FFE7FFE63CE6DB663CE6DB663CE7FFE0000
+07B9:00007FFE73866DF66DEE6DDE73DE7FFE7FFE63CE6DB663C66DF663CE7FFE0000
+07BA:00007FFE73866DF66DEE6DDE73DE7FFE7FFE63866DB663866DB663B67FFE0000
+07BB:00007FFE73866DF66DEE6DDE73DE7FFE7FFE638E6DB6638E6DB6638E7FFE0000
+07BC:00007FFE73866DF66DEE6DDE73DE7FFE7FFE63C66DBE63BE6DBE63C67FFE0000
+07BD:00007FFE73866DF66DEE6DDE73DE7FFE7FFE638E6DB663B66DB6638E7FFE0000
+07BE:00007FFE73866DF66DEE6DDE73DE7FFE7FFE63866DBE638E6DBE63867FFE0000
+07BF:00007FFE73866DF66DEE6DDE73DE7FFE7FFE63866DBE638E6DBE63BE7FFE0000
+07C0:00000000182424424242422424180000
+07C1:000000001814121010101010107E0000
+07C2:000000002222223E2020202020200000
+07C3:0000000000000404040404043C04043C
+07C4:00000000000004040404043C2020203C
+07C5:00000000202020203820202020200000
+07C6:00000000404040407C04040404040000
+07C7:00000000404040404244485060600000
+07C8:00000000404040407E44485060600000
+07C9:00000000384444443810101010100000
+07CA:00000000101010101010101010100000
+07CB:00000000000000001824424224180000
+07CC:00000000824428281010101010100000
+07CD:00000000000000000010282844440000
+07CE:000000000000000044444444447C0000
+07CF:00000000000000007C040404047C0000
+07D0:000000003844444438101010107C0000
+07D1:000000000010202018000000007E0000
+07D2:000000001028281E0A12020202020000
+07D3:00000000003C20203C20202020202000
+07D4:00000000003C04043C04040404040400
+07D5:00000000404040407844444444780000
+07D6:00000000003E20201010080804040400
+07D7:00000000182848080808080808080000
+07D8:00000000000000002C525252527E0000
+07D9:0000000008083E080808080808080000
+07DA:00000000242424247E242424243C0000
+07DB:00000000000000007E424242427E0000
+07DC:00000000000000007C44442828100000
+07DD:00000000040A0A0A0C78484848780000
+07DE:00000000000424243C24240404040400
+07DF:00000000304848483E08080808080000
+07E0:000000007C1010101010101010100000
+07E1:000000000000000010282844447C0000
+07E2:00000000701010384444381010100000
+07E3:00000000003E22220202020202020200
+07E4:000000000020203C2424040404040400
+07E5:00000000003C0404043C242424243C00
+07E6:00000000101010384444381010100000
+07E7:000000007C1010384444381010100000
+07E8:0000000002021C040808102244780000
+07E9:0000000002021C0408081C2244780000
+07EA:00000000080808083E08080808080000
+07EB:00003C00000000000000000000000000
+07EC:00122C40000000000000000000000000
+07ED:00100000000000000000000000000000
+07EE:00102844000000000000000000000000
+07EF:0804027E000000000000000000000000
+07F0:00483402000000000000000000000000
+07F1:001020407E0000000000000000000000
+07F2:00000000000000000000000000100000
+07F3:00002400000000000000000000000000
+07F4:00000000000030080810000000000000
+07F5:00000000000010202018000000000000
+07F6:00000000001C2222221E040810203E00
+07F7:000000001C222A224155412A1C000000
+07F8:00000000000000000000100000380000
+07F9:00000000000000003800100010000000
+07FA:000000000000000000000000003C0000
+07FB:00007FFE73866DF66DEE6DDE73DE7FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+07FC:00007FFE73866DF66DEE6DDE73DE7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+07FD:00007FFE73866DF66DEE6DDE73DE7FFE7FFE618E6FB663B66FB66F8E7FFE0000
+07FE:00007FFE73866DF66DEE6DDE73DE7FFE7FFE61866FBE638E6FBE6F867FFE0000
+07FF:00007FFE73866DF66DEE6DDE73DE7FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+0800:000000000000000000000008011002A0044008240828103010200C4000000000
+0801:0000000000000000000000000380044008200FE00010001000083FF800000000
+0802:000000000000000000000000003007C00440084000200010002000C000000000
+0803:00000000000000000000000003F8042008100FF0000800080010002000000000
+0804:000000000000000000000000003007C004C00940026004900520004000000000
+0805:000000000000000000000000004007A004900900030004E00010002000000000
+0806:000000000000000000000000038004401C6013901010101010201CC000000000
+0807:000000000000000000000000002007C004C0094032600C900510022000000000
+0808:000000000000000000000200040009F0111008A004A002400140008000000000
+0809:000000000000000000000000000000F003900490049009200920092000000000
+080A:0000000000000000000008080C081FF0001000100010021007900FF000000000
+080B:00000000000000000000008000800080030004000800081018301FF000000000
+080C:00000000000000000000000008881DD81FF82008000808101E103FF000000000
+080D:00000000040004000400080008000FF0001000100010021007900FF000000000
+080E:0000000000000000060009000A0019C00078009008A01F600100020007800000
+080F:00000000000000000000000000001FE008400440028001800080000000000000
+0810:00000000000000000000000000000FF0001000100010021007900FF000000000
+0811:000000000000000000000000000003F014901C90149005201920092000000000
+0812:000000000000000000000000080007E00610091000A000400180020001800000
+0813:00000000000000000000000003C0042008100FF0000800080010002000000000
+0814:00000000000000000000000008881DD81FF82004000000000000000000000000
+0815:00000000000000000000000001000280044008240828103010200C4000000000
+0816:00000010002000280012000C0000000000000000000000000000000000000000
+0817:000000100010001200140016000C000000000000000000000000000000000000
+0818:00000FFC00000000000000000000000000000000000000000000000000000000
+0819:0080004000200040008000000000000000000000000000000000000000000000
+081A:0000071008E00000000000000000000000000000000000000000000000000000
+081B:0000071008E00000000000000000000000000000000000000000000000000000
+081C:0000440044002800280010001000000000000000000000000000000000000000
+081D:0000440028001000000000000000000000000000000000000000000000000000
+081E:0000100010001000100010001000100010000000000000000000000000000000
+081F:0000100010001000100010000000000000000000000000000000000000000000
+0820:0000100010001000000000000000000000000000000000000000000000000000
+0821:00007F8000000000000000000000000000000000000000000000000000000000
+0822:00001F0000000000000000000000000000000000000000000000000000000000
+0823:00000E0000000000000000000000000000000000000000000000000000000000
+0824:0000008000800100010002000200000000000000000000000000000000000000
+0825:0000080008001000100020002000000000000000000000000000000000000000
+0826:0000100010002800280044004400000000000000000000000000000000000000
+0827:0000100028004400000000000000000000000000000000000000000000000000
+0828:0000008001000200010000800000000000000000000000000000000000000000
+0829:000003000C0030000C0003000000000000000000000000000000000000000000
+082A:0000020004000800040002000000000000000000000000000000000000000000
+082B:0000100010002800280044007C00000000000000000000000000000000000000
+082C:000000C00120012000C000000000000000000000000000000000000000000000
+082D:0000018001800000000000000000000000000000000000000000000000000000
+082E:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE61867DBE618E6FBE61867FFE0000
+082F:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE61867DBE618E6FBE61BE7FFE0000
+0830:0000000000000000000000000180018000000000000000000000000000000000
+0831:0000000000000000018001800000000000000000018001800000000000000000
+0832:0000000000000000000000000C600C6000000000000000000000000000000000
+0833:000000000000000000003F183018100008000400020002000400000000000000
+0834:000000000000000000003F183018100008000400021802180400000000000000
+0835:000000000000000000000240000003C004000400030000C00000000000000000
+0836:00000000003000300000008000400040008001000200060007E0000000000000
+0837:00000000000000000000007E006000207F900008000400040008000000000000
+0838:000000000000000000000000000000067FE60000000000000000000000000000
+0839:000000000000000000000006000600007FE00000000600060000000000000000
+083A:0000000000000000000000067FE600000000000000067FE60000000000000000
+083B:0000000000000000000004600460040004000400046004600000000000000000
+083C:0000000000000010002000400080010002000400080010002000000000000000
+083D:0000000000000010002000400080011802180400080011982198000000000000
+083E:0000000000000000000000000180024002400180000000000000000000000000
+083F:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE63867DBE718E7DBE63BE7FFE0000
+0840:0000000000000000000000000000038004400820082004400380000000000000
+0841:0000000000000000000000840104020403F8004000203FFE0000000000000000
+0842:000000000000000000600090016001000080004000303FFC0000000000000000
+0843:00000000000000000000001400240044007C000400043FF80000000000000000
+0844:000000000000000000000000000000000000005400543FF80000000000000000
+0845:0000000000000000000000100008000403FC0000000000000000000000000000
+0846:0000000000000000008000800080008000800080008000800000000000000000
+0847:0000000000000000000000000000000003E00410040803FC0000000000000000
+0848:00000000000000E001200140014000A03FF00000000000000000000000000000
+0849:0000000000000000000000800100020003F00000000000000000000000000000
+084A:0000000000000000004010800900090004E004200440048009000E0000000000
+084B:0000000000000000000400040004000400040004000401F80000000000000000
+084C:0000000000000000000000840104020403FC004400243FC40000000000000000
+084D:00000000000000000000104008200820042004400440048009000E0000000000
+084E:000000000000000000000000000000000018008400443FF80000000000000000
+084F:0000000000000000000000400080010001F8000400043FF80000000000000000
+0850:000000000000000000C01120096008A0042004400440048009000E0000000000
+0851:0000000000000000002A102A083E0820042004400440048009000E0000000000
+0852:0000000000000000000000840104020403FC004400243FF80000000000000000
+0853:0000000000000000000000840104020403FC000400043FF80000000000000000
+0854:000000000000000000000C18122412240D580140014000800080000000000000
+0855:000000000000000000000084007C002400240FC4000000000000000000000000
+0856:000000000000000000000210042008400FF00000000000000000000000000000
+0857:00000000000000000008111020A020A01F9C008400880090012001C000000000
+0858:0000000000000000008001000200020001C002000200020001C0000000000000
+0859:0000000000000000000000000000000000000000000000000000024002400000
+085A:000000000000000000000000000000000000000000000000000003E000000000
+085B:0000000000000000000000000000000000000000000000000000008000800000
+085C:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE61C66FBE61BE7DBE61C67FFE0000
+085D:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE618E6FB661B67DB6618E7FFE0000
+085E:0000000000000180066008100990124812480990081006600180000000000000
+085F:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE61866FBE618E7DBE61BE7FFE0000
+0860:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73CE6FB663B66DB673CE7FFE0000
+0861:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73EE6FCE63EE6DEE73C67FFE0000
+0862:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73866FF663866DBE73867FFE0000
+0863:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE738E6FF663C66DF6738E7FFE0000
+0864:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73B66FB663866DF673F67FFE0000
+0865:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73866FBE63866DF673867FFE0000
+0866:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73CE6FBE638E6DB673CE7FFE0000
+0867:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73866FF663EE6DDE73DE7FFE0000
+0868:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73CE6FB663CE6DB673CE7FFE0000
+0869:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73CE6FB663C66DF673CE7FFE0000
+086A:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73866FB663866DB673B67FFE0000
+086B:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE738E6FB6638E6DB6738E7FFE0000
+086C:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73C66FBE63BE6DBE73C67FFE0000
+086D:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE738E6FB663B66DB6738E7FFE0000
+086E:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73866FBE638E6DBE73867FFE0000
+086F:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73866FBE638E6DBE73BE7FFE0000
+0870:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE61CE7DB67BB677B677CE7FFE0000
+0871:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE61EE7DCE7BEE77EE77C67FFE0000
+0872:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE61867DF67B8677BE77867FFE0000
+0873:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE618E7DF67BC677F6778E7FFE0000
+0874:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE61B67DB67B8677F677F67FFE0000
+0875:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE61867DBE7B8677F677867FFE0000
+0876:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE61CE7DBE7B8E77B677CE7FFE0000
+0877:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE61867DF67BEE77DE77DE7FFE0000
+0878:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE61CE7DB67BCE77B677CE7FFE0000
+0879:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE61CE7DB67BC677F677CE7FFE0000
+087A:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE61867DB67B8677B677B67FFE0000
+087B:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE618E7DB67B8E77B6778E7FFE0000
+087C:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE61C67DBE7BBE77BE77C67FFE0000
+087D:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE618E7DB67BB677B6778E7FFE0000
+087E:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE61867DBE7B8E77BE77867FFE0000
+087F:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE61867DBE7B8E77BE77BE7FFE0000
+0880:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73CE6DB673B66DB673CE7FFE0000
+0881:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73EE6DCE73EE6DEE73C67FFE0000
+0882:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73866DF673866DBE73867FFE0000
+0883:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE738E6DF673C66DF6738E7FFE0000
+0884:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73B66DB673866DF673F67FFE0000
+0885:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73866DBE73866DF673867FFE0000
+0886:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73CE6DBE738E6DB673CE7FFE0000
+0887:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73866DF673EE6DDE73DE7FFE0000
+0888:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73CE6DB673CE6DB673CE7FFE0000
+0889:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73CE6DB673C66DF673CE7FFE0000
+088A:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73866DB673866DB673B67FFE0000
+088B:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE738E6DB6738E6DB6738E7FFE0000
+088C:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73C66DBE73BE6DBE73C67FFE0000
+088D:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE738E6DB673B66DB6738E7FFE0000
+088E:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73866DBE738E6DBE73867FFE0000
+088F:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73866DBE738E6DBE73BE7FFE0000
+0890:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73CE6DB671B67DB673CE7FFE0000
+0891:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73EE6DCE71EE7DEE73C67FFE0000
+0892:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73866DF671867DBE73867FFE0000
+0893:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE738E6DF671C67DF6738E7FFE0000
+0894:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73B66DB671867DF673F67FFE0000
+0895:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73866DBE71867DF673867FFE0000
+0896:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73CE6DBE718E7DB673CE7FFE0000
+0897:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73866DF671EE7DDE73DE7FFE0000
+0898:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73CE6DB671CE7DB673CE7FFE0000
+0899:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73CE6DB671C67DF673CE7FFE0000
+089A:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73866DB671867DB673B67FFE0000
+089B:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE738E6DB6718E7DB6738E7FFE0000
+089C:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73C66DBE71BE7DBE73C67FFE0000
+089D:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE738E6DB671B67DB6738E7FFE0000
+089E:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73866DBE718E7DBE73867FFE0000
+089F:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE73866DBE718E7DBE73BE7FFE0000
+08A0:000000000000000422423C0028281000
+08A1:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE61EE6DCE61EE6DEE6DC67FFE0000
+08A2:00000000000820007E1020404840221C
+08A3:000000202228202C32227C0000000000
+08A4:0010002800060A0642423C0010000000
+08A5:000000002400001C120A264244380010
+08A6:00000004041F041F0424444448380000
+08A7:00000000080014001C061E2020202020
+08A8:0000000018201820044A4844423C0028
+08A9:0000000000001000044A4844423C0028
+08AA:00000000000000000402020234483402
+08AB:000000000000000C12120E2204483000
+08AC:000000000000000000000814146E404A
+08AD:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE618E6DB661B66DB66D8E7FFE0000
+08AE:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE61866DBE618E6DBE6D867FFE0000
+08AF:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE61866DBE618E6DBE6DBE7FFE0000
+08B0:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE63CE6DB663B66DB663CE7FFE0000
+08B1:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE63EE6DCE63EE6DEE63C67FFE0000
+08B2:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE63866DF663866DBE63867FFE0000
+08B3:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE638E6DF663C66DF6638E7FFE0000
+08B4:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE63B66DB663866DF663F67FFE0000
+08B5:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE63866DBE63866DF663867FFE0000
+08B6:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE63CE6DBE638E6DB663CE7FFE0000
+08B7:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE63866DF663EE6DDE63DE7FFE0000
+08B8:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE63CE6DB663CE6DB663CE7FFE0000
+08B9:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE63CE6DB663C66DF663CE7FFE0000
+08BA:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE63866DB663866DB663B67FFE0000
+08BB:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE638E6DB6638E6DB6638E7FFE0000
+08BC:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE63C66DBE63BE6DBE63C67FFE0000
+08BD:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE638E6DB663B66DB6638E7FFE0000
+08BE:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE63866DBE638E6DBE63867FFE0000
+08BF:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE63866DBE638E6DBE63BE7FFE0000
+08C0:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE71CE6FB66FB66FB671CE7FFE0000
+08C1:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE71EE6FCE6FEE6FEE71C67FFE0000
+08C2:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE71866FF66F866FBE71867FFE0000
+08C3:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE718E6FF66FC66FF6718E7FFE0000
+08C4:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE71B66FB66F866FF671F67FFE0000
+08C5:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE71866FBE6F866FF671867FFE0000
+08C6:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000
+08C7:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE71866FF66FEE6FDE71DE7FFE0000
+08C8:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE71CE6FB66FCE6FB671CE7FFE0000
+08C9:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE71CE6FB66FC66FF671CE7FFE0000
+08CA:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE71866FB66F866FB671B67FFE0000
+08CB:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE718E6FB66F8E6FB6718E7FFE0000
+08CC:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE71C66FBE6FBE6FBE71C67FFE0000
+08CD:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE718E6FB66FB66FB6718E7FFE0000
+08CE:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE71866FBE6F8E6FBE71867FFE0000
+08CF:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+08D0:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE63CE6DB66DB66DB663CE7FFE0000
+08D1:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000
+08D2:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE63866DF66D866DBE63867FFE0000
+08D3:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE638E6DF66DC66DF6638E7FFE0000
+08D4:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE63B66DB66D866DF663F67FFE0000
+08D5:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE63866DBE6D866DF663867FFE0000
+08D6:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE63CE6DBE6D8E6DB663CE7FFE0000
+08D7:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE63866DF66DEE6DDE63DE7FFE0000
+08D8:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE63CE6DB66DCE6DB663CE7FFE0000
+08D9:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE63CE6DB66DC66DF663CE7FFE0000
+08DA:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE63866DB66D866DB663B67FFE0000
+08DB:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE638E6DB66D8E6DB6638E7FFE0000
+08DC:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE63C66DBE6DBE6DBE63C67FFE0000
+08DD:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE638E6DB66DB66DB6638E7FFE0000
+08DE:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE63866DBE6D8E6DBE63867FFE0000
+08DF:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE63866DBE6D8E6DBE63BE7FFE0000
+08E0:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE61CE6FB663B66FB661CE7FFE0000
+08E1:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE61EE6FCE63EE6FEE61C67FFE0000
+08E2:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE61866FF663866FBE61867FFE0000
+08E3:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE618E6FF663C66FF6618E7FFE0000
+08E4:0004020C100800000000000000000000
+08E5:00020505022518000000000000000000
+08E6:000000000000000000000004020C1008
+08E7:00221166884400000000000000000000
+08E8:1C22225522221C000000000000000000
+08E9:00000000000000000000002211668844
+08EA:00001000000000000000000000000000
+08EB:00000420000000000000000000000000
+08EC:001A241A000000000000000000000000
+08ED:00000000000000000000000000000010
+08EE:00000000000000000000000000001040
+08EF:00000000000000000000000000344834
+08F0:00061800186000000000000000000000
+08F1:00225555225588100000000000000000
+08F2:00000000000000000000000618001860
+08F3:00040A0E021C00000000000000000000
+08F4:00344854245800000000000000000000
+08F5:00002006186000000000000000000000
+08F6:00000000000000000000000618600400
+08F7:00102040201000000000000000000000
+08F8:00201008102000000000000000000000
+08F9:00000000000000000000000810201008
+08FA:00000000000000000000002010081020
+08FB:00482412244800000000000000000000
+08FC:00482492244800000000000000000000
+08FD:00100824081000000000000000000000
+08FE:00000814144E08300000000000000000
+08FF:00007FFE73CE6DB66DCE6DB673CE7FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+0900:000001C0023005B0098000000000000000000000000000000000000000000000
+0901:0000098005B0023001C000000000000000000000000000000000000000000000
+0902:0000018001800000000000000000000000000000000000000000000000000000
+0903:000000000000000000000000000C000C0000000C000C00000000000000000000
+0904:080007C000200E7F1130013003300E30023021F021B013B00F30003000100000
+0905:0000000000001CFF2260026006601C60046043E0436027601E60006000200000
+0906:0000000000001CFF2266026606661C66046643E6436627661E66006600220000
+0907:000000000000FFFF00C000C00FC0180018000FE00030033005B007E000400020
+0908:03C006200100FFFF00C000C00FC0180018000FE00030033005B007E000400020
+0909:000000000000FFFF018000C000C001C00F80418040C020C010C009C007800000
+090A:000000000000FFFF018000C000C001C00F9C41B240E220C210C609C407800000
+090B:000000000000FFFF018039806598039807F81F883988219C01B801A000A0001E
+090C:000000000000FFFF00200020382074F863CC630C300C10780CC00280007C0000
+090D:009800700000FFFF0C300C300C300C300C600400020001800060001000180018
+090E:10000FE00010FFFF0C300C300C300C300C600400020001800060001000180018
+090F:000000000000FFFF0C300C300C300C300C600400020001800060001000180018
+0910:0F0000800040FFFF0C300C300C300C300C600400020001800060001000180018
+0911:0026001E00001CFF2266026606661C66046643E6436627661E66006600220000
+0912:010000F800041CFF2266026606661C66046643E6436627661E66006600220000
+0913:00E0001000081CFF2266026606661C66046643E6436627661E66006600220000
+0914:007000E800141CFF2266026606661C66046643E6436627661E66006600220000
+0915:000000000000FFFF018001801D8033E0239027981D9801980198018000800000
+0916:000000000000FFFF0818081809D83B383A18123811D808180618019800080000
+0917:000000000000FFFF019801980198019807980398019800980018001800080000
+0918:000000000000FFFF0C180C1807D8021804180438047803D80018001800080000
+0919:000000000000FFFF006000600FE0180018040FCE00641060086007C000000000
+091A:000000000000FFFF0018001800181FF803180638067803D80018001800080000
+091B:000000000000FFFF001000103C7870E460C420441F2C0C181838186407860006
+091C:000000000000FFFF00180018001803F8119808D808D807980018001800080000
+091D:000000000000FFFF031803181F18301830181FF801180D1816181D1800880000
+091E:000000000000FFFF001800180718059821B821F821D813980F18001800080000
+091F:000000000000FFFF00C000C000C007C00C001800180018000C1007E000000000
+0920:000000000000FFFF018001800180038007600C10081808180838047003E00000
+0921:000000000000FFFF0018001803F80600060003F000180418021801F000000000
+0922:000000000000FFFF0060006007E00C00180018C019A009100510033001E00000
+0923:000000000000FFFF199819981998199819980998071800180018001800080000
+0924:000000000000FFFF00180018001807F80E180C180C1806180218011800880000
+0925:0000000000001C7F1B181998099803980F180C38047803D80018001800080000
+0926:000000000000FFFF00180018001801F8020006000618022801F0000800040000
+0927:0000000000000E7F1918181818180C18039806180C180C380C7803D800080000
+0928:000000000000FFFF00180018001807F806180618021800180018001800080000
+0929:000000000000FFFF00180018001807F806180618021800180118039801080000
+092A:000000000000FFFF06180618061806180618023801D800180018001800080000
+092B:000000000000FFFF31803180318031F031C813840F840184018C018C00800000
+092C:000000000000FFFF0018001807D80E780D180C980C7807F80018001800080000
+092D:00000000000038FF3618321813180F18031807F8071803180018001800080000
+092E:000000000000FFFF061806180618061806180FF8061802180018001800080000
+092F:000000000000FFFF031803180318031806180438047803D80018001800080000
+0930:000000000000FFFF00C000C000C003C003800380010000800040002000180000
+0931:000000000000FFFF00C000C000C003C0038003800100008004400E2004180000
+0932:000000000000FFFF001800181C383AF831D83198181808180418031800080000
+0933:000000000000FFFF0030003000700EC8198C318C318C319813700E0000000000
+0934:000000000000FFFF0030003000700EC8198C318C318C319813700E0000C000C0
+0935:000000000000FFFF0018001803D80F380C180C38047803D80018001800080000
+0936:000000000000FFFF061806181F1801980198199815181E180218011800880000
+0937:000000000000FFFF0C180E180D180C980C580C38063801D80018001800080000
+0938:000000000000FFFF0318031803180B180F180EF8041804180218011800880000
+0939:000000000000FFFF0018001807F80C000C0006F0019803100300018000FC0000
+093A:0180018001800180000000000000000000000000000000000000000000000000
+093B:000C000C000C003F000C000C000C000C000C000C000C000C000C000C000C0004
+093C:0000000000000000000000000000000000000000000000000000018001800000
+093D:000000000000007F0080008000C000600030001000180018013800F000000000
+093E:000000000000003F000C000C000C000C000C000C000C000C000C000C000C0004
+093F:3C0062003100FC00300030003000300030003000300030003000100000000000
+0940:00F001080108003F000C000C000C000C000C000C000C000C000C000C000C0004
+0941:0000000000000000000000000000000000000000000000000980044003800000
+0942:00000000000000000000000000000000000000000000000001C0022001900000
+0943:0000000000000000000000000000000000000000000000000180020001C00000
+0944:0000000000000000000000000000000000000000018002000180020001800000
+0945:0000044002400180000000000000000000000000000000000000000000000000
+0946:0000080007000080000000000000000000000000000000000000000000000000
+0947:00000E0001000080000000000000000000000000000000000000000000000000
+0948:00000E0001001C80038000000000000000000000000000000000000000000000
+0949:0022001E0000003F000C000C000C000C000C000C000C000C000C000C000C0004
+094A:008000780004003F000C000C000C000C000C000C000C000C000C000C000C0004
+094B:00F000080004003F000C000C000C000C000C000C000C000C000C000C000C0004
+094C:00F001E80014003F000C000C000C000C000C000C000C000C000C000C000C0004
+094D:0000000000000000000000000000000000000000000000000380004000200000
+094E:0000000000003C00300030003000300030003000300030003000300030002000
+094F:0040003C010200FB0006003E0006000600060006000600060006000600020000
+0950:00300030000038847C780200020C0C1E18120412423E43EC3CC0180000000000
+0951:0000008000800080000000000000000000000000000000000000000000000000
+0952:000000000000000000000000000000000000000000000000000003C000000000
+0953:0000020001000080000000000000000000000000000000000000000000000000
+0954:0000004000800100000000000000000000000000000000000000000000000000
+0955:0000044002400180000007C00000000000000000000000000000000000000000
+0956:0000000000000000000000000000000000000000000000000000000010800F00
+0957:00000000000000000000000000000000000000000000000010800F0020401F80
+0958:000000000000FFFF00C000C00EC019F811C813CC0ECC00CC00CC04C00E400400
+0959:000000000000FFFF0818081809D83B383A18123811D808180418009801C80080
+095A:000000000000FFFF019801980198019807980398019800980018009801C80080
+095B:000000000000FFFF00180018001803F8119808D808D807980018009801C80080
+095C:000000000000FFFF0018001803F80600060003F00018041803F0000000C000C0
+095D:000000000000FFFF0060006007E00C0018E0199019100D3007E0000001800180
+095E:000000000000FFFF31803180318031F031C813840F840184018C098C1C800800
+095F:000000000000FFFF031803180318031806180438047803D80018011803880100
+0960:000000000000FFFF0300030033184B2807F00F18330843180330031C0110000E
+0961:000000000000FFFF002000201E70319831981030086004C0003C00C000C0003C
+0962:0000000000000000000000000000000000000000048009200820044000300000
+0963:0000000000000000000000000000000000000000048009200840043000400030
+0964:0000000000000100018001800180018001800180018001800180018000800000
+0965:0000000000000240036003600360036003600360036003600360036001200000
+0966:0000000000000000000003C004E00C700C300E30072003C00000000000000000
+0967:0000000000000380074006600660026001E000C0018003000100008000400020
+0968:0000000000000FC00E200010001000100030036002C003800040002000100008
+0969:0000000000000FC00E200020002003C000200010033002E003C0004000200010
+096A:0000000000002004100C08180430026001C00180034002600260026001C00000
+096B:0000000000000C000C300C30043003E000C000C0068005800780004000200010
+096C:00000000000003C00C0008000C0007C0010002000230033000F0004000400020
+096D:000000000000100010E011D81188088C087C080404040408031800E000000000
+096E:0000000000001FF80400080010001000106010F00F9007100010000000000000
+096F:00000000000003800640062006100200038004800C000C000C00020001F00000
+0970:000000000000000000000000000001C00220022001C000000000000000000000
+0971:00000000000000000000000000C000C000000000000000000000000000000000
+0972:0100009000601CFF2260026006601C60046043E0436027601E60006000200000
+0973:0060006000601CFF2260026006601C60046043E0436027601E60006000200000
+0974:0006000600061CFF2266026606661C66046643E6436627661E66006600220000
+0975:0040003C01021CFB2206023E06661C66046643E6436627661E66006600220000
+0976:0100009000601CFF2260026006601C60046043E0436027601E60002010800F00
+0977:0100009000601CFF2260026006601C60046043E027601E6010E00F0020401F80
+0978:00007FFE73CE6DB66DC66DF673CE7FFE7FFE61CE7DB67BCE77B677CE7FFE0000
+0979:000000000000FFFF00180018001803F8119808D808D807980018089802080000
+097A:000000000000FFFF031803180318039806580438047803D80018001800080000
+097B:000000000000FFFF01980198019801980798039801980098001800180FF80000
+097C:000000000000FFFF00180018001803F8119808D808D80798001800181FF80000
+097D:00000000000007C00E200C1000100010003003E003C003000300030003000100
+097E:000000000000FFFF0018001803F80600060003F000180418021801F000000FFE
+097F:000000000000FFFF0018001807D80E780D180C980C7807F8001800180FF80000
+0980:00007FFE73CE6DB66DC66DF673CE7FFE7FFE73CE6DB673B66DB673CE7FFE0000
+0981:0000018005A0042003C000000000000000000000000000000000000000000000
+0982:000000000000000000000000000C0012000C00000018000C0006000100000000
+0983:000000000000000000000000000C0012000C0000000C0012000C000000000000
+0984:00007FFE73CE6DB66DC66DF673CE7FFE7FFE73B66DB673866DF673F67FFE0000
+0985:000000000000FFFF000C400C438C47CC47EC632C206C307C18DC0F8C00040000
+0986:000000000006FFF7006E406646664F664F6645664166616633E61E6600220000
+0987:20001FC00020FFFF00000FC018603C303C30183000603FC0070001C0007C0000
+0988:20001FF00008FFFF1E003F0C3B1E193801F801F003904F103C101018000E0000
+0989:10000FE00010FFFF03000300430043104338636C21CC300C180C0E1803F00000
+098A:10000FE00010FFFF03000300530053105338536C49CC280C240C12180FF00000
+098B:000020007200736742E63CE601E607663C6630763C7E076E01E600E600220000
+098C:000020004000400020003FE00FF8001C07860C461C261C261C26086C01F80000
+098D:00007FFE73CE6DB66DC66DF673CE7FFE7FFE738E6DB673B66DB6738E7FFE0000
+098E:00007FFE73CE6DB66DC66DF673CE7FFE7FFE73866DBE738E6DBE73867FFE0000
+098F:000000000018007C00C6018643C643C64186400660062036304E198607020000
+0990:000400080008006C01F6031A461A4F1A4F1A461C601820D831381E180C080000
+0991:00007FFE73CE6DB66DC66DF673CE7FFE7FFE73EE6DCE71EE7DEE73C67FFE0000
+0992:00007FFE73CE6DB66DC66DF673CE7FFE7FFE73866DF671867DBE73867FFE0000
+0993:000000000078018C030607064706433C607C203C300618060C06060C03F80000
+0994:00040008000803EC04360E1A0E1A4E1A44F241FC60F02018301818380FF00000
+0995:000000000000FFFF0060006001F807643C6230623C6E076C01E000E000200000
+0996:000000001000388F38CC314C1E4C004C018C1E0C1F8C006C001C000C00040000
+0997:0000000000000F9F1C58383838183F1811980198019807181E18081800080000
+0998:000000000000FFFF1818301838181F98019806180C181F1801D8003800080000
+0999:00000000080008F00590031003E023002208221C31EC100C180C0C1807E00000
+099A:000000000000FFFF180018001C001B0018FC180C180C180C18181C300FC00000
+099B:000000000000FFFF180018001C001BE0183818681CC80F10006001F8000E0000
+099C:000000000000FFFF01F0031C460F4C024CC44F24662C202C306418C40F830000
+099D:000000000000FFE70066006601E607663C6630663C66077E01EE00E600220000
+099E:00000000038006C00CD818FC1CE65CC648DC40C660E663FC37D83CC018400000
+099F:10000FC00020FFFF180018001800186018F018701830186018C00F8007000000
+09A0:10000F000080FFFF0080008000C001C0016023303A18141818180C3007E00000
+09A1:000000000000FFFF03000300430043104338636C21CC300C180C0E1803F00000
+09A2:000000000000FFFF180018001800186018F018701830186018C00F8007000000
+09A3:00000000038C07CF0C2C181C181C1C0C1C0C080C000C000C000C000C00040000
+09A4:000000000000FFFF000041F8430C43844386638621063006180C0C1C07F00000
+09A5:000000001E00311F789878983098009803183C183F1800D80038001800080000
+09A6:000000000000FFFF0C000C000C780CF00DE00D600F600E600E600C30081C0000
+09A7:0000000006000F0F0E0C080C063C01EC038C0E0C0F8C00EC003C001C00040000
+09A8:000000000000FFFF00180018001800181E183F983CD838780038001800080000
+09A9:00007FFE73CE6DB66DC66DF673CE7FFE7FFE61CE6DB661C66DF66DCE7FFE0000
+09AA:0000000007180FDF1878303878784DD807180C18101800180018001800080000
+09AB:000000000000FFFF100038780C6406620C62186E306C3F6001E0006000200000
+09AC:000000000000FFFF00180018007803D807181C181F1801D80078003800080000
+09AD:000000000000FFFF000042104708470C461463E620063006180C0C1C07F00000
+09AE:000000000000FFFF0C181C180E180318031803180FD81E780C38001800080000
+09AF:000000000000FFFF08301C300630033006300C3018301FB000F0003000100000
+09B0:000000000000FFFF0018007803D807181C181F1801D802780738071802080000
+09B1:00007FFE73CE6DB66DC66DF673CE7FFE7FFE63EE6DCE63EE6DEE63C67FFE0000
+09B2:000000000000FFFF000600061C163E3E636641C641C640867C063C0618020000
+09B3:00007FFE73CE6DB66DC66DF673CE7FFE7FFE638E6DF663C66DF6638E7FFE0000
+09B4:00007FFE73CE6DB66DC66DF673CE7FFE7FFE63B66DB663866DF663F67FFE0000
+09B5:00007FFE73CE6DB66DC66DF673CE7FFE7FFE63866DBE63866DF663867FFE0000
+09B6:0000000038667CF7479E478E0FC61FE60CC60006000600060006000600020000
+09B7:000000000000FFFF1C180E18079801D806781C181F1801D80078003800080000
+09B8:000000000000FFFF100C380C1C0C060C02CC01EC031C660C3C0C180C00040000
+09B9:000000000000FFFF00000FC018603C303C30183000603FC0070001C0007C0000
+09BA:00007FFE73CE6DB66DC66DF673CE7FFE7FFE63866DB663866DB663B67FFE0000
+09BB:00007FFE73CE6DB66DC66DF673CE7FFE7FFE638E6DB6638E6DB6638E7FFE0000
+09BC:0000000000000000000000000000000000000000000000000000018001800000
+09BD:000000000000F00008000FC01C603C303C30183000603FC0070001C0007C0000
+09BE:0000000000000000000000060017000E00060006000600060006000600020000
+09BF:00000F803FE0601060082000F800300030003000300030003000300010000000
+09C0:000003F00418080C0BE40414001F000C000C000C000C000C000C000C00040000
+09C1:0000000000000000000000000000000000000000000000200340048003400020
+09C2:000000000000000000000000000000000000000000000180020001C000200010
+09C3:0000000000000000000000000000000000000000000000C003000400030000C0
+09C4:0000000000000000000000000000000000000000018002000180020001000000
+09C5:00007FFE73CE6DB66DC66DF673CE7FFE7FFE71866FBE6F866FF671867FFE0000
+09C6:00007FFE73CE6DB66DC66DF673CE7FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000
+09C7:000000000000000000000000F800180030006000400040004000580038000000
+09C8:000000000000800070000800F800180030006000400040004000580038000000
+09C9:00007FFE73CE6DB66DC66DF673CE7FFE7FFE71CE6FB66FC66FF671CE7FFE0000
+09CA:00007FFE73CE6DB66DC66DF673CE7FFE7FFE71866FB66F866FB671B67FFE0000
+09CB:000000000000000000000006F817180E30066006400640064006580638020000
+09CC:000000000080007000080004F817180E30066006400640064006580638020000
+09CD:00000000000000000000000000000000000000000000030000C0002000000000
+09CE:000000000000038005C00CC00EC00D800C000600038000C00060003000100000
+09CF:00007FFE73CE6DB66DC66DF673CE7FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+09D0:00007FFE73CE6DB66DC66DF673CE7FFE7FFE63CE6DB66DB66DB663CE7FFE0000
+09D1:00007FFE73CE6DB66DC66DF673CE7FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000
+09D2:00007FFE73CE6DB66DC66DF673CE7FFE7FFE63866DF66D866DBE63867FFE0000
+09D3:00007FFE73CE6DB66DC66DF673CE7FFE7FFE638E6DF66DC66DF6638E7FFE0000
+09D4:00007FFE73CE6DB66DC66DF673CE7FFE7FFE63B66DB66D866DF663F67FFE0000
+09D5:00007FFE73CE6DB66DC66DF673CE7FFE7FFE63866DBE6D866DF663867FFE0000
+09D6:00007FFE73CE6DB66DC66DF673CE7FFE7FFE63CE6DBE6D8E6DB663CE7FFE0000
+09D7:0000000000800070000800040017000E00060006000600060006000600020000
+09D8:00007FFE73CE6DB66DC66DF673CE7FFE7FFE63CE6DB66DCE6DB663CE7FFE0000
+09D9:00007FFE73CE6DB66DC66DF673CE7FFE7FFE63CE6DB66DC66DF663CE7FFE0000
+09DA:00007FFE73CE6DB66DC66DF673CE7FFE7FFE63866DB66D866DB663B67FFE0000
+09DB:00007FFE73CE6DB66DC66DF673CE7FFE7FFE638E6DB66D8E6DB6638E7FFE0000
+09DC:000000000000FFFF030043104338636C23CC318C180C0E1803F0000000C000C0
+09DD:000000000000FFFF0C000C000C000C300C780C380C3007E003C0000001800180
+09DE:00007FFE73CE6DB66DC66DF673CE7FFE7FFE63866DBE6D8E6DBE63867FFE0000
+09DF:000000000000FFFF04180E1803180198031806180C180FD80078011803880100
+09E0:000020007200736742E63CE601E607663C6630763C7E076E3DE630E63C220700
+09E1:0000080007C0003007900C500CD009E0080007C0003007900C500CD009E00000
+09E2:000000000000000000000000000000000000000003E000100390065006E00000
+09E3:000000000000000000000000000000000000001C03820052026A056C05800000
+09E4:00007FFE73CE6DB66DC66DF673CE7FFE7FFE61B66FB663866FF661F67FFE0000
+09E5:00007FFE73CE6DB66DC66DF673CE7FFE7FFE61866FBE63866FF661867FFE0000
+09E6:00000000000003C007E00C30181818181818181818180C3007E003C000000000
+09E7:00000000040004000600038000E00030001806180E180E180C3007E000000000
+09E8:0000000000001C00070001C0006000601C600FC0038000C00030000800000000
+09E9:00000000000020F02118220C230C238C238C218C100C10180818047003C00000
+09EA:0000000007C00FE01830101018300C6007C018303018301838381FF007C00000
+09EB:0000000001C007800E581C30186030C0318031803180318018D80C3007E00000
+09EC:000000000000070003000300230023182328236C31CC100C180C0C1807F00000
+09ED:0000000003C007E00C300C300C7007F003B00030003000300030003000180000
+09EE:00000000700030003000300433F83FE0383030303030303038601FC00F000000
+09EF:00002000200018000F0003C000F00038000C0F0C108C384C384C385810700040
+09F0:000000000000FFFF00180018007803D807981C781F1801D80078003800080000
+09F1:000000000000FFFF00180018007803D807181C181F1801D81C78073801880040
+09F2:0000000000001C001F000F8001C0006000200010001000000000000000000000
+09F3:0000000018003C00660006000FF806000630067806780618063003E001C00000
+09F4:0000000000000000001000100020006001C00F801F001C000000000000000000
+09F5:0000000000000E041F0438883C983CB018B001E003C003800000000000000000
+09F6:000000000004000400040E041F041F840F84018C03183E3830701FE007800000
+09F7:00000000008000C000C000C000C000C000C000C000C000C000C000C000400000
+09F8:00000000380018001830187018F018B019B01B301E301C301830003000180000
+09F9:00000000000003E007F00C18180C180C180C180C0C1807F003E0000000000000
+09FA:00000000000000000000000000020102438443842108301818300FE007800000
+09FB:0000000000000000000000000000000003000400040002000100008000400020
+09FC:00007FFE73CE6DB66DC66DF673CE7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+09FD:00007FFE73CE6DB66DC66DF673CE7FFE7FFE618E6FB663B66FB66F8E7FFE0000
+09FE:00007FFE73CE6DB66DC66DF673CE7FFE7FFE61866FBE638E6FBE6F867FFE0000
+09FF:00007FFE73CE6DB66DC66DF673CE7FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+0A00:00007FFE73866DB66D866DB673B67FFE7FFE73CE6DB66DB66DB673CE7FFE0000
+0A01:02A0022001C00000000000000000000000000000000000000000000000000000
+0A02:0180018000000000000000000000000000000000000000000000000000000000
+0A03:0000000000000000000000000002000500020000000200050002000000000000
+0A04:00007FFE73866DB66D866DB673B67FFE7FFE73B66DB66D866DF673F67FFE0000
+0A05:0000000000000000C00720041304149C386430C420C400840004000000000000
+0A06:0000000000000000C03F20241024166439A03320232002200020000000000000
+0A07:3C00420042004000FFFF44044404420441FC42004400420441F8000000000000
+0A08:0078008400840004FFFE4044404420441FC42004400420441F84000000000000
+0A09:07C0082010102008FFFF2008200820103FE010100810042003C00000081007E0
+0A0A:07C0082010102008FFFF200820103FE010100810042003C0081007E0081007E0
+0A0B:00007FFE73866DB66D866DB673B67FFE7FFE738E6DB66D8E6DB6738E7FFE0000
+0A0C:00007FFE73866DB66D866DB673B67FFE7FFE73C66DBE6DBE6DBE73C67FFE0000
+0A0D:00007FFE73866DB66D866DB673B67FFE7FFE738E6DB66DB66DB6738E7FFE0000
+0A0E:00007FFE73866DB66D866DB673B67FFE7FFE73866DBE6D8E6DBE73867FFE0000
+0A0F:00C0002000100010FFFF10101010081007F008001000080007F0000000000000
+0A10:00F0000800F4000CC01F20041304149C386430C420C400840004000400000000
+0A11:00007FFE73866DB66D866DB673B67FFE7FFE7BEE73CE7BEE7BEE71C67FFE0000
+0A12:00007FFE73866DB66D866DB673B67FFE7FFE7B8673F67B867BBE71867FFE0000
+0A13:07F0080010002000FFFF2008200820103FE010100810042003C0000000000000
+0A14:020001F000480048C01F20041304149C386430C420C400840004000400000000
+0A15:0000000000000000FFFF001000100F1010A020602060209011100E1000000000
+0A16:0000000000000000F01F101008100FF01010201010300FD00010001000000000
+0A17:0000000000000000FFFF0090009000901F902090209010900910061000000000
+0A18:0000000000000000F11F1110091009101110211011300ED00010000000000000
+0A19:0000000000000000FFFF100010001FC0002003A0044004A00310000000000000
+0A1A:0000000000000000FFFF0020002018201FE008200820042003C0000000000000
+0A1B:0000000000000000FFFF001000101FF020001FF0210821081FF0000000000000
+0A1C:0000000000000000FFFF0010001018101FF00810081008100810000000000000
+0A1D:0000000000000000FFFF0C3002400FE01010260807F001000080004000000000
+0A1E:0000000000000000FFFF201020101FF0200020001FF0040003F0000000000000
+0A1F:0000000000000000FFFF0040004001C0020004000800041003E0000000000000
+0A20:0000000000000000FFFF0100010002800440082010101010082007C000000000
+0A21:0000000000000000FFFF0008000803F0001000101F08208810700FC000000000
+0A22:0000000000000000FFFF0010001018101FF00800080009E00A10042003C00000
+0A23:00000000000000000000FFFF010000C000600F5010C020001010082007C00000
+0A24:0000000000000000FFFF0010001007A007E00030201030100C2003C000000000
+0A25:0000000000000000FFFF101008100FF0101030100C3003D00010001000000000
+0A26:0000000000000000FFFF0020002030203FE0100010000800041003E000000000
+0A27:0000000000000000FFFF08100410041008101010081006700190001000000000
+0A28:0000000000000000FFFF01000100028004400820101010100820000000000000
+0A29:00007FFE73866DB66D866DB673B67FFE7FFE61CE7DB661C66FF661CE7FFE0000
+0A2A:0000000000000000F81F08100410041008101010081006700190001000000000
+0A2B:0000000000000000FFFF001000101FF02000200021E012100C2003C000000000
+0A2C:0000000000000000FFFF0810041007F008101010081006700190001000000000
+0A2D:0000000000000000FFFF0010001003D0043003C800081010082007C000000000
+0A2E:0000000000000000F01F0810081008100FF01810181000100190019000000000
+0A2F:0000000000000000FFFF08100410041008F01090089004900390001000000000
+0A30:0000000000000000FFFF0010001007F00810081008100410021001E000000000
+0A31:00007FFE73866DB66D866DB673B67FFE7FFE63EE7DCE71EE7DEE63C67FFE0000
+0A32:0000000000000000FFFF0820082004400AA01110101008200440000000000000
+0A33:0000000000000000FFFF0820082004400AA0111010100820044C000C00000000
+0A34:00007FFE73866DB66D866DB673B67FFE7FFE63B67DB671867DF663F67FFE0000
+0A35:0000000000000000FFFF001000101FF0200030000FF0040003E0000000000000
+0A36:0000000000000000FFFF0810081008100FF01810181000100190019000000000
+0A37:00007FFE73866DB66D866DB673B67FFE7FFE63867DF671EE7DDE63DE7FFE0000
+0A38:0000000000000000FFFF0810081008100FF01810181000100010001000000000
+0A39:0000000000000000FFFF0010001007100810081008100410021001E000000000
+0A3A:00007FFE73866DB66D866DB673B67FFE7FFE63867DB671867DB663B67FFE0000
+0A3B:00007FFE73866DB66D866DB673B67FFE7FFE638E7DB6718E7DB6638E7FFE0000
+0A3C:0000000000000000000000000000000000000000000000000000000001800180
+0A3D:00007FFE73866DB66D866DB673B67FFE7FFE638E7DB671B67DB6638E7FFE0000
+0A3E:0000000000000000001F00040004000400040004000000000000000000000000
+0A3F:7800840084008400E00080008000800080008000800080008000800080000000
+0A40:0078008400840084001F00040004000400040004000400040004000400040000
+0A41:0000000000000000000000000000000000000000000000000000082007C00000
+0A42:000000000000000000000000000000000000000000000000082007C0082007C0
+0A43:00007FFE73866DB66D866DB673B67FFE7FFE6D8E6DF661C67DF67D8E7FFE0000
+0A44:00007FFE73866DB66D866DB673B67FFE7FFE6DB66DB661867DF67DF67FFE0000
+0A45:00007FFE73866DB66D866DB673B67FFE7FFE6D866DBE61867DF67D867FFE0000
+0A46:00007FFE73866DB66D866DB673B67FFE7FFE6DCE6DBE618E7DB67DCE7FFE0000
+0A47:000000E000100008000000000000000000000000000000000000000000000000
+0A48:01E0001000F80008000000000000000000000000000000000000000000000000
+0A49:00007FFE73866DB66D866DB673B67FFE7FFE6DCE6DB661C67DF67DCE7FFE0000
+0A4A:00007FFE73866DB66D866DB673B67FFE7FFE6D866DB661867DB67DB67FFE0000
+0A4B:020001F000080008000000000000000000000000000000000000000000000000
+0A4C:020001F000480048000000000000000000000000000000000000000000000000
+0A4D:0000000000000000000000000000000000000000000000000000001800040002
+0A4E:00007FFE73866DB66D866DB673B67FFE7FFE6D866DBE618E7DBE7D867FFE0000
+0A4F:00007FFE73866DB66D866DB673B67FFE7FFE6D866DBE618E7DBE7DBE7FFE0000
+0A50:00007FFE73866DB66D866DB673B67FFE7FFE61CE6FB661B67DB661CE7FFE0000
+0A51:0000000000000000000000000000000000000000000000000000080006000180
+0A52:00007FFE73866DB66D866DB673B67FFE7FFE61866FF661867DBE61867FFE0000
+0A53:00007FFE73866DB66D866DB673B67FFE7FFE618E6FF661C67DF6618E7FFE0000
+0A54:00007FFE73866DB66D866DB673B67FFE7FFE61B66FB661867DF661F67FFE0000
+0A55:00007FFE73866DB66D866DB673B67FFE7FFE61866FBE61867DF661867FFE0000
+0A56:00007FFE73866DB66D866DB673B67FFE7FFE61CE6FBE618E7DB661CE7FFE0000
+0A57:00007FFE73866DB66D866DB673B67FFE7FFE61866FF661EE7DDE61DE7FFE0000
+0A58:00007FFE73866DB66D866DB673B67FFE7FFE61CE6FB661CE7DB661CE7FFE0000
+0A59:0000000000000000F81F0810041007F008101010081006700190181018000000
+0A5A:0000000000000000FFFF009000900F9010901090109008900490031018001800
+0A5B:0000000000000000FFFF0010001018101FF00810081008100810099001800000
+0A5C:0000000000000000FFFF00200020002007E0001000101020084007C004200210
+0A5D:00007FFE73866DB66D866DB673B67FFE7FFE618E6FB661B67DB6618E7FFE0000
+0A5E:0000000000000000FFFF001000101FF02000200021E012100C2063C060000000
+0A5F:00007FFE73866DB66D866DB673B67FFE7FFE61866FBE618E7DBE61BE7FFE0000
+0A60:00007FFE73866DB66D866DB673B67FFE7FFE73CE6FB663B66DB673CE7FFE0000
+0A61:00007FFE73866DB66D866DB673B67FFE7FFE73EE6FCE63EE6DEE73C67FFE0000
+0A62:00007FFE73866DB66D866DB673B67FFE7FFE73866FF663866DBE73867FFE0000
+0A63:00007FFE73866DB66D866DB673B67FFE7FFE738E6FF663C66DF6738E7FFE0000
+0A64:00007FFE73866DB66D866DB673B67FFE7FFE73B66FB663866DF673F67FFE0000
+0A65:00007FFE73866DB66D866DB673B67FFE7FFE73866FBE63866DF673867FFE0000
+0A66:0000000000000000078008401020201020102010102008400780000000000000
+0A67:000000000000000007000880084008C007400040004000400040003000000000
+0A68:000000000000000007C000200010001000200FC0004000200010000000000000
+0A69:00000000000000000F800040002000401F800040002030403F80080004000200
+0A6A:0000000000000000044008200820044003800440082008200440038000000000
+0A6B:0000000000000000103C1020082008201020202010200CE00320002000000000
+0A6C:00E00100010000C003F004300800040003F004000800040803F0000000000000
+0A6D:000000000000000003C004200810081006100020004000800300040000000000
+0A6E:00000000000030003FF0100010001000100010000800040003F0000000000000
+0A6F:00600080008030603FF0103010001000100010000800040003F0000000000000
+0A70:03C0042002400000000000000000000000000000000000000000000000000000
+0A71:0420042003C00000000000000000000000000000000000000000000000000000
+0A72:0000000000000000FFFF10101010081007F0080010000810042003C000000000
+0A73:07E0081010082008FFFF2008200820103FE010100810042003C0000000000000
+0A74:00000000180424F8250C1D920B421482280C280228022404120809F000000000
+0A75:0000000000000000000000000000000000000000000000000200020002400180
+0A76:00007FFE73866DB66D866DB673B67FFE7FFE61CE7DBE7B8E77B677CE7FFE0000
+0A77:00007FFE73866DB66D866DB673B67FFE7FFE61867DF67BEE77DE77DE7FFE0000
+0A78:00007FFE73866DB66D866DB673B67FFE7FFE61CE7DB67BCE77B677CE7FFE0000
+0A79:00007FFE73866DB66D866DB673B67FFE7FFE61CE7DB67BC677F677CE7FFE0000
+0A7A:00007FFE73866DB66D866DB673B67FFE7FFE61867DB67B8677B677B67FFE0000
+0A7B:00007FFE73866DB66D866DB673B67FFE7FFE618E7DB67B8E77B6778E7FFE0000
+0A7C:00007FFE73866DB66D866DB673B67FFE7FFE61C67DBE7BBE77BE77C67FFE0000
+0A7D:00007FFE73866DB66D866DB673B67FFE7FFE618E7DB67BB677B6778E7FFE0000
+0A7E:00007FFE73866DB66D866DB673B67FFE7FFE61867DBE7B8E77BE77867FFE0000
+0A7F:00007FFE73866DB66D866DB673B67FFE7FFE61867DBE7B8E77BE77BE7FFE0000
+0A80:00007FFE73866DB66D866DB673B67FFE7FFE73CE6DB673B66DB673CE7FFE0000
+0A81:02A0022001C00000000000000000000000000000000000000000000000000000
+0A82:0180018000000000000000000000000000000000000000000000000000000000
+0A83:0000000000000000000000000003000300000000000300030000000000000000
+0A84:00007FFE73866DB66D866DB673B67FFE7FFE73B66DB673866DF673F67FFE0000
+0A85:000000000000000078080408048838F810480888070A00040000000000000000
+0A86:0000000000000000F0220822092271E220A211220E2A00110000000000000000
+0A87:000000180020002003A004200420042003200420044003800000000000000000
+0A88:0000003000480048074008400840084006400840088007000000000000000000
+0A89:000003C00420081009C008200820082008C00420022001C00000000000000000
+0A8A:00000F0010802040272020902090209023101090089407080000000000000000
+0A8B:0000000000000000391005280328011803E40502094210840000000000000000
+0A8C:000000000000000000200F7010882084201810200C20001C0000000000000000
+0A8D:004000200018000078080408048838F810480888070A00040000000000000000
+0A8E:00007FFE73866DB66D866DB673B67FFE7FFE73866DBE738E6DBE73867FFE0000
+0A8F:000000600010000878080408048838F810480888070A00040000000000000000
+0A90:00E0001800F8000878080408048838F810480888070A00040000000000000000
+0A91:0010000800060000F0220822092271E220A211220E2A00110000000000000000
+0A92:00007FFE73866DB66D866DB673B67FFE7FFE73866DF671867DBE73867FFE0000
+0A93:0000001800040002F0220822092271E220A211220E2A00110000000000000000
+0A94:00380006003E0002F0220822092271E220A211220E2A00110000000000000000
+0A95:0000000000000000018002000240018001800240084007800000000000000000
+0A96:000000000000000020405040124013C00C400040005000200000000000000000
+0A97:00000000000000000C2012200120012012200C20002800100000000000000000
+0A98:0000000000000000039004100410041003100430045403880000000000000000
+0A99:000000000000000001000100026004600200210011000E000000000000000000
+0A9A:00000000000000003C10021002101C1008300450039400080000000000000000
+0A9B:00000000000000001CC021202120212018A0204020801F000000000000000000
+0A9C:00000000000000000E10112028C0488049403120012000C00000000000000000
+0A9D:00000000000000000C401240014001E012100C10001000600000000000000000
+0A9E:00000000000000000C201220012001E012200C20002800100000000000000000
+0A9F:0000000000000000380004000400180020004000440038000000000000000000
+0AA0:0000000000000000018002000200010007000880088007000000000000000000
+0AA1:000000000000000001000100020004000200210011000E000000000000000000
+0AA2:00000000000000001C0002000C0010C02120212010C00F800000000000000000
+0AA3:00000000000000004C4052404140414052404C40405040202000100008001000
+0AA4:00000000000000000040004003C0044008400840045002200000000000000000
+0AA5:00000000000000000C4012400A40044008C00740005000200000000000000000
+0AA6:0000000000000000038004000400040003000400044003800000000000000000
+0AA7:00000600080008000640084008C0074000400040005000200000000000000000
+0AA8:00000000000000000080008000801F801880008000A000400000000000000000
+0AA9:00007FFE73866DB66D866DB673B67FFE7FFE61CE6DB661C66DF66DCE7FFE0000
+0AAA:000000000000000010402840084008C007400040005000200000000000000000
+0AAB:000000000000000001800200024001800180024018401F800400020001800000
+0AAC:000000000000000008081008208820F811080E08000A00040000000000000000
+0AAD:000000000000000007080888108810F810080808040A00040000000000000000
+0AAE:00000000000000000C200220022003E000200020002800100000000000000000
+0AAF:00000000000000000C20022004200820046003A0002800100000000000000000
+0AB0:00000000000000001E00010001000E000400020001C000000000000000000000
+0AB1:00007FFE73866DB66D866DB673B67FFE7FFE63EE6DCE63EE6DEE63C67FFE0000
+0AB2:00000000000000000C80108020802780208010800CA000400000000000000000
+0AB3:0000000000000000000021802240224022401C40004000500020000000000000
+0AB4:00007FFE73866DB66D866DB673B67FFE7FFE63B66DB663866DF663F67FFE0000
+0AB5:00000000000000000000074008C0084008C00740004000500020000000000000
+0AB6:00000000000000000C20122012200C2004201820082807100000000000000000
+0AB7:00000000000000000C400A40094008C007400040005000200000000000000000
+0AB8:00000000000000003C20022003E01C2008200420032800100000000000000000
+0AB9:000000000000000021002200210020802480232010200FC00000000000000000
+0ABA:00007FFE73866DB66D866DB673B67FFE7FFE63866DB663866DB663B67FFE0000
+0ABB:00007FFE73866DB66D866DB673B67FFE7FFE638E6DB6638E6DB6638E7FFE0000
+0ABC:0000000000000000000000000000000000000000000000000000000001800180
+0ABD:0000000000000000380040004000300008000400440038000000000000000000
+0ABE:0000000000000000000400040004000400040004000500020000000000000000
+0ABF:6000900088008000800080008000800080008000A00040000000000000000000
+0AC0:0018002400240004000400040004000400040004000500020000000000000000
+0AC1:00000000000000000000000000000000000000000000000000000260011000E0
+0AC2:000000000000000000000000000000000000000000000000000001C002200190
+0AC3:000000000000000000000000000000000000000000000000000001C0020001C0
+0AC4:00000000000000000000000000000000000000000000018002000180020001C0
+0AC5:0010000800060000000000000000000000000000000000000000000000000000
+0AC6:00007FFE73866DB66D866DB673B67FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000
+0AC7:0000001800040002000000000000000000000000000000000000000000000000
+0AC8:00380006003E0002000000000000000000000000000000000000000000000000
+0AC9:00200010000C0000000400040004000400040004000500020000000000000000
+0ACA:00007FFE73866DB66D866DB673B67FFE7FFE71866FB66F866FB671B67FFE0000
+0ACB:0030000800040000000400040004000400040004000500020000000000000000
+0ACC:000C007C00040000000400040004000400040004000500020000000000000000
+0ACD:000000000000000000000000000000000000000000000000000001C000200010
+0ACE:00007FFE73866DB66D866DB673B67FFE7FFE71866FBE6F8E6FBE71867FFE0000
+0ACF:00007FFE73866DB66D866DB673B67FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+0AD0:00300030000000843C780200020C0C121832044C438042003C00000000000000
+0AD1:00007FFE73866DB66D866DB673B67FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000
+0AD2:00007FFE73866DB66D866DB673B67FFE7FFE63866DF66D866DBE63867FFE0000
+0AD3:00007FFE73866DB66D866DB673B67FFE7FFE638E6DF66DC66DF6638E7FFE0000
+0AD4:00007FFE73866DB66D866DB673B67FFE7FFE63B66DB66D866DF663F67FFE0000
+0AD5:00007FFE73866DB66D866DB673B67FFE7FFE63866DBE6D866DF663867FFE0000
+0AD6:00007FFE73866DB66D866DB673B67FFE7FFE63CE6DBE6D8E6DB663CE7FFE0000
+0AD7:00007FFE73866DB66D866DB673B67FFE7FFE63866DF66DEE6DDE63DE7FFE0000
+0AD8:00007FFE73866DB66D866DB673B67FFE7FFE63CE6DB66DCE6DB663CE7FFE0000
+0AD9:00007FFE73866DB66D866DB673B67FFE7FFE63CE6DB66DC66DF663CE7FFE0000
+0ADA:00007FFE73866DB66D866DB673B67FFE7FFE63866DB66D866DB663B67FFE0000
+0ADB:00007FFE73866DB66D866DB673B67FFE7FFE638E6DB66D8E6DB6638E7FFE0000
+0ADC:00007FFE73866DB66D866DB673B67FFE7FFE63C66DBE6DBE6DBE63C67FFE0000
+0ADD:00007FFE73866DB66D866DB673B67FFE7FFE638E6DB66DB66DB6638E7FFE0000
+0ADE:00007FFE73866DB66D866DB673B67FFE7FFE63866DBE6D8E6DBE63867FFE0000
+0ADF:00007FFE73866DB66D866DB673B67FFE7FFE63866DBE6D8E6DBE63BE7FFE0000
+0AE0:000000000000000072200A500650023007DC0A101292210C0000000000000000
+0AE1:000000000000000000200F7010882084201810200C20001C00200020001C0000
+0AE2:0000000000000000000000000000000000000000000000000360049004200018
+0AE3:00000000000000000000000000000000000000000000036004900424001A000C
+0AE4:00007FFE73866DB66D866DB673B67FFE7FFE61B66FB663866FF661F67FFE0000
+0AE5:00007FFE73866DB66D866DB673B67FFE7FFE61866FBE63866FF661867FFE0000
+0AE6:0000000000000000078008401020201020102010102008400780000000000000
+0AE7:000000000000000007000880084008C007400040004000400040003000000000
+0AE8:000000000000000007C00020001000100C200FC00200010000C0000000000000
+0AE9:000000000000000001C000200010002003C010200810042003C0000000000000
+0AEA:00000000000000001C080210012000C000C0012002200220022001C000000000
+0AEB:000000000000000010402840084008C007400040005000200000000000000000
+0AEC:0000000000000000070008001000080007E004000800040003F0000800080070
+0AED:000000000000000003C0046008900910061020102010202010400F8000000000
+0AEE:0000000000000080010002000400080010001000100008400780000000000000
+0AEF:000000000000000008001040208021002200200010000F800000000000000000
+0AF0:0000000000000000000000000000000018002400240018000000000000000000
+0AF1:00000000000000000C000200010002001C1C0222012232223C1C080004000300
+0AF2:00007FFE73866DB66D866DB673B67FFE7FFE61866FF663866FBE6F867FFE0000
+0AF3:00007FFE73866DB66D866DB673B67FFE7FFE618E6FF663C66FF66F8E7FFE0000
+0AF4:00007FFE73866DB66D866DB673B67FFE7FFE61B66FB663866FF66FF67FFE0000
+0AF5:00007FFE73866DB66D866DB673B67FFE7FFE61866FBE63866FF66F867FFE0000
+0AF6:00007FFE73866DB66D866DB673B67FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+0AF7:00007FFE73866DB66D866DB673B67FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+0AF8:00007FFE73866DB66D866DB673B67FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+0AF9:00007FFE73866DB66D866DB673B67FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+0AFA:00007FFE73866DB66D866DB673B67FFE7FFE61866FB663866FB66FB67FFE0000
+0AFB:00007FFE73866DB66D866DB673B67FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+0AFC:00007FFE73866DB66D866DB673B67FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+0AFD:00007FFE73866DB66D866DB673B67FFE7FFE618E6FB663B66FB66F8E7FFE0000
+0AFE:00007FFE73866DB66D866DB673B67FFE7FFE61866FBE638E6FBE6F867FFE0000
+0AFF:00007FFE73866DB66D866DB673B67FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+0B00:00007FFE738E6DB66D8E6DB6738E7FFE7FFE73CE6DB66DB66DB673CE7FFE0000
+0B01:02A0022001C00000000000000000000000000000000000000000000000000000
+0B02:0002000500020000000000000000000000000000000000000000000000000000
+0B03:0000000000000000000000020005000500020005000500020000000000000000
+0B04:00007FFE738E6DB66D8E6DB6738E7FFE7FFE73B66DB66D866DF673F67FFE0000
+0B05:0000000000000000361049104910221004100810083007D00000000000000000
+0B06:0000000000000000361449144914221404140414023401D40000000000000000
+0B07:00000000000000000F803040402040204A20354015400A200000000000000000
+0B08:0000000000000000038004403E2040204A20354015400A200000000000000000
+0B09:00000000000000000F803040402041205220264022401C200000000000000000
+0B0A:00000000000000000F803040404041405220261022201C100000000000000000
+0B0B:000000000000000007001880208020802C40122012400C200000000000000000
+0B0C:00000000000000000000038004400180020004C0052003C00000000000000000
+0B0D:00007FFE738E6DB66D8E6DB6738E7FFE7FFE738E6DB66DB66DB6738E7FFE0000
+0B0E:00007FFE738E6DB66D8E6DB6738E7FFE7FFE73866DBE6D8E6DBE73867FFE0000
+0B0F:0000000000000000020006000A004200220012000A0006000000000000000000
+0B10:000001E00210001001200320052021E011200920052003200000000000000000
+0B11:00007FFE738E6DB66D8E6DB6738E7FFE7FFE7BEE73CE7BEE7BEE71C67FFE0000
+0B12:00007FFE738E6DB66D8E6DB6738E7FFE7FFE7B8673F67B867BBE71867FFE0000
+0B13:000000000000000004C009200820082008C00420022001C00000000000000000
+0B14:000000F00108000813102490209020F023101090089007100000000000000000
+0B15:00000000000000000FC03020401040104980364016400A400000000000000000
+0B16:000000000000000003900510093008D008100710049003100000000000000000
+0B17:0000000000000000039004500830081008100710049003100000000000000000
+0B18:00000000000000000390045008300A100C10111011300ED00000000000000000
+0B19:00000000000000000F003080407041485230260022001C000000000000000000
+0B1A:000000000000000003C004200810081008100720048003000000000000000000
+0B1B:000000000000000003C0042008100B10048017000A8005000000000000000000
+0B1C:000000000000000003C00420081008000A6004A004A003200000000000000000
+0B1D:000000000000000003A00490091010E016000900098006400000000000000000
+0B1E:00000000000000001360249020101FE01360249020101FE00000000000000000
+0B1F:0000000000000000039004500830081008000700048003000000000000000000
+0B20:0000000000000000000007000880104010401040088007000000000000000000
+0B21:000000000000000003C00C2010101050149009A0088007000000000000000000
+0B22:000000000000000003C00C2010101010141009200A8007000200010000000000
+0B23:0000000000000000039004500A3011101C10021002100C100000000000000000
+0B24:00000000000000000F803040402040205340230023001C000000000000000000
+0B25:00000000000000000610091001100E1010101010083007D00000000000000000
+0B26:00000000000000000F803040402041205300230023001D000000000000000000
+0B27:0000000000000000001004100210031004900410043003D00000000000000000
+0B28:00000000000000000F80104020202020272019400D000D000000000000000000
+0B29:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61CE7DB661C66FF661CE7FFE0000
+0B2A:000000000000000007900850103012100C100810083007D00000000000000000
+0B2B:00000000000000001CB022C841C848B03080208021801E800000000000000000
+0B2C:00000000000000000780184020202E203120110011800E800000000000000000
+0B2D:00000000000000000F803040402045205520234021401E200000000000000000
+0B2E:000000000000000007900850103012100C101010601060100010000000000000
+0B2F:000000000000000007900850103012100C101810683067D00000000000000000
+0B30:000000000000000003C00420081008100810072004A003100000000000000000
+0B31:00007FFE738E6DB66D8E6DB6738E7FFE7FFE63EE7DCE71EE7DEE63C67FFE0000
+0B32:00000000000000001FC02020401040105B1024A024A024900000000000000000
+0B33:00000000000000001FC02020401040105B202480248024800000000000000000
+0B34:00007FFE738E6DB66D8E6DB6738E7FFE7FFE63B67DB671867DF663F67FFE0000
+0B35:00000000000000000780184020202E203120150011800E800000000000000000
+0B36:0000000000000000079008500C30121010100E10091006100000000000000000
+0B37:000000000000000007900C50123013100C900850083007D00000000000000000
+0B38:00000000000000000F9010502030211026101E10019000700000000000000000
+0B39:00000000000000000F803040402041205300230023001D000800060001800000
+0B3A:00007FFE738E6DB66D8E6DB6738E7FFE7FFE63867DB671867DB663B67FFE0000
+0B3B:00007FFE738E6DB66D8E6DB6738E7FFE7FFE638E7DB6718E7DB6638E7FFE0000
+0B3C:0000000000000000000000000000000000000000000000000000000001800180
+0B3D:00000000000000000C003000400030000C003000400030000C00000000000000
+0B3E:0000000000000000000800080008000800080008000800080008000000000000
+0B3F:07F0080808080000000000000000000000000000000000000000000000000000
+0B40:0000000000000000000800180028000800080008000800080008000000000000
+0B41:000000000000000000000000000000000000000000000000002007A008C007B0
+0B42:00000000000000000000000000000000000000000000000003000400044003B0
+0B43:000000000000000000000000000000000000000000000000024004A0042003C0
+0B44:000000000000000000000000000000000000000000000400084006A0082007C0
+0B45:00007FFE738E6DB66D8E6DB6738E7FFE7FFE6D866DBE61867DF67D867FFE0000
+0B46:00007FFE738E6DB66D8E6DB6738E7FFE7FFE6DCE6DBE618E7DB67DCE7FFE0000
+0B47:00000000000000006000800080008000E0009000900090006000000000000000
+0B48:010000F8000400046000800080008000E0009000900090006000000000000000
+0B49:00007FFE738E6DB66D8E6DB6738E7FFE7FFE6DCE6DB661C67DF67DCE7FFE0000
+0B4A:00007FFE738E6DB66D8E6DB6738E7FFE7FFE6D866DB661867DB67DB67FFE0000
+0B4B:00000000000000006008800880088008E0089008900890086008000000000000
+0B4C:00000078008400046008800880088008E0089008900890086008000000000000
+0B4D:0000000000000000000000000000000000000000000000000000008000400020
+0B4E:00007FFE738E6DB66D8E6DB6738E7FFE7FFE6D866DBE618E7DBE7D867FFE0000
+0B4F:00007FFE738E6DB66D8E6DB6738E7FFE7FFE6D866DBE618E7DBE7DBE7FFE0000
+0B50:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61CE6FB661B67DB661CE7FFE0000
+0B51:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61EE6FCE61EE7DEE61C67FFE0000
+0B52:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61866FF661867DBE61867FFE0000
+0B53:00007FFE738E6DB66D8E6DB6738E7FFE7FFE618E6FF661C67DF6618E7FFE0000
+0B54:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61B66FB661867DF661F67FFE0000
+0B55:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61866FBE61867DF661867FFE0000
+0B56:010000F800040004000000000000000000000000000000000000000000000000
+0B57:0000007800840004000800080008000800080008000800080008000000000000
+0B58:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61CE6FB661CE7DB661CE7FFE0000
+0B59:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61CE6FB661C67DF661CE7FFE0000
+0B5A:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61866FB661867DB661B67FFE0000
+0B5B:00007FFE738E6DB66D8E6DB6738E7FFE7FFE618E6FB6618E7DB6618E7FFE0000
+0B5C:000000000000000003C00C2010101050149009A0088007000000030003000000
+0B5D:000000000000000003C00C2010101010141009200A800700020001000C000C00
+0B5E:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61866FBE618E7DBE61867FFE0000
+0B5F:000000000000000007900850103012100C1018306848679C0000000000000000
+0B60:00000000000000000780184020C020202CC0122012C00C200010000000000000
+0B61:00000000000000000000038004400180020004C0052003C00080004000200000
+0B62:00000000000000000000000000000000000000000080014001400098012400F8
+0B63:000000000000000000000000000000000000000000800140015800A4013800D0
+0B64:00007FFE738E6DB66D8E6DB6738E7FFE7FFE73B66FB663866DF673F67FFE0000
+0B65:00007FFE738E6DB66D8E6DB6738E7FFE7FFE73866FBE63866DF673867FFE0000
+0B66:0000000000000000000000000380044010101010101004400380000000000000
+0B67:000000000000000003C004200A100A1009E004000200010000C0002000000000
+0B68:000000000000000003C004200850085007900020004000800300040000000000
+0B69:00000000000000000EE011102110291025101910011001100000000000000000
+0B6A:000000000000000004080210012000C000C0012002200220022001C000000000
+0B6B:000000000000000001C012200A20064001800260045004480380000000000000
+0B6C:000000000000000003C004200310009008900720004000800300040000000000
+0B6D:000000000000000003C0042009100A900A900720004000800300040000000000
+0B6E:0000000000000FE0080008000800080008000800080008000800000000000000
+0B6F:0000000000000000072008A00860080008000800040003000000000000000000
+0B70:0000000000000000001000200C400C8041002200140008000000000000000000
+0B71:000000000000000009E0121010E0081007F00810083007D00000000000000000
+0B72:0000000000000000008000800080008000800080008000800000000000000000
+0B73:0000000000000000088008800880098006800080008000800000000000000000
+0B74:0000000000000000222022202220266019A00020002000200000000000000000
+0B75:0000000000000000002000400080010002000400080010000000000000000000
+0B76:000000000000000000201C402A802B0012000400080010000000000000000000
+0B77:0000000000000000000200040008001036204940498049000000000000000000
+0B78:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61CE7DB67BCE77B677CE7FFE0000
+0B79:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61CE7DB67BC677F677CE7FFE0000
+0B7A:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61867DB67B8677B677B67FFE0000
+0B7B:00007FFE738E6DB66D8E6DB6738E7FFE7FFE618E7DB67B8E77B6778E7FFE0000
+0B7C:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61C67DBE7BBE77BE77C67FFE0000
+0B7D:00007FFE738E6DB66D8E6DB6738E7FFE7FFE618E7DB67BB677B6778E7FFE0000
+0B7E:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61867DBE7B8E77BE77867FFE0000
+0B7F:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61867DBE7B8E77BE77BE7FFE0000
+0B80:00007FFE738E6DB66D8E6DB6738E7FFE7FFE73CE6DB673B66DB673CE7FFE0000
+0B81:00007FFE738E6DB66D8E6DB6738E7FFE7FFE73EE6DCE73EE6DEE73C67FFE0000
+0B82:0100028001000000000000000000000000000000000000000000000000000000
+0B83:0000000000000000018002400240018018182424242418180000000000000000
+0B84:00007FFE738E6DB66D8E6DB6738E7FFE7FFE73B66DB673866DF673F67FFE0000
+0B85:0000000000000000061009100990069000901FF020901F100000000000000000
+0B86:00000000000000001840244026401A4002407FE082507C500150021001E00000
+0B87:000000000F801040232024902490135008401F8022401D800000000000000000
+0B88:00000000000000000000000000007FE042005AC05AC042000000000000000000
+0B89:00000000000000003C004A004900310002003C0040003FF00000000000000000
+0B8A:00000000000000007000980099F86AD00950705080007FF80000000000000000
+0B8B:00007FFE738E6DB66D8E6DB6738E7FFE7FFE738E6DB6738E6DB6738E7FFE0000
+0B8C:00007FFE738E6DB66D8E6DB6738E7FFE7FFE73C66DBE73BE6DBE73C67FFE0000
+0B8D:00007FFE738E6DB66D8E6DB6738E7FFE7FFE738E6DB673B66DB6738E7FFE0000
+0B8E:000000000000000007FC081010101C102210221022101C100000000000000000
+0B8F:000000000000000007FC081010101C102210221022101C100020004000800000
+0B90:00000000000000003EE04910311000103FE0400042103FE00000000000000000
+0B91:00007FFE738E6DB66D8E6DB6738E7FFE7FFE73EE6DCE71EE7DEE73C67FFE0000
+0B92:00000000000000001FC020204010401071D04A504A903260020011E010400F80
+0B93:00000000000000001FC020204010401071D04A504A903260020031E048403F80
+0B94:00000000000000003C0042008100817CCDA8B568B928560010008F0082007C00
+0B95:000000000000000000000FE00880088008803FE040903F200000000000000000
+0B96:00007FFE738E6DB66D8E6DB6738E7FFE7FFE73CE6DBE718E7DB673CE7FFE0000
+0B97:00007FFE738E6DB66D8E6DB6738E7FFE7FFE73866DF671EE7DDE73DE7FFE0000
+0B98:00007FFE738E6DB66D8E6DB6738E7FFE7FFE73CE6DB671CE7DB673CE7FFE0000
+0B99:00000000000000007E1048104F1048904890411042104FF00000000000000000
+0B9A:000000000000000000000FE00880088008803FE040803F000000000000000000
+0B9B:00007FFE738E6DB66D8E6DB6738E7FFE7FFE738E6DB6718E7DB6738E7FFE0000
+0B9C:00000000000000003EE04910311000103FE0400043E03C1000E0000000000000
+0B9D:00007FFE738E6DB66D8E6DB6738E7FFE7FFE738E6DB671B67DB6738E7FFE0000
+0B9E:000000000000000027E0488090809CA0A2D0A290A2909C90801040203FC00000
+0B9F:000000000000000000000000000010001000100010001FF00000000000000000
+0BA0:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61CE6DB661B66DB66DCE7FFE0000
+0BA1:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61EE6DCE61EE6DEE6DC67FFE0000
+0BA2:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61866DF661866DBE6D867FFE0000
+0BA3:00000000000000003BBF44488AA8CAA8AAA8AAA8444800080000000000000000
+0BA4:000000000000000000000FE00880088008803FE040903F10001000203FC04000
+0BA5:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61866DBE61866DF66D867FFE0000
+0BA6:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61CE6DBE618E6DB66DCE7FFE0000
+0BA7:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61866DF661EE6DDE6DDE7FFE0000
+0BA8:000000000000000000000FE008800880088008E008900010001000203FC04000
+0BA9:00000000000000001EFC2110429072904A904A90311000100000000000000000
+0BAA:00000000000000000000088008800880088008800F8000000000000000000000
+0BAB:00007FFE738E6DB66D8E6DB6738E7FFE7FFE618E6DB6618E6DB66D8E7FFE0000
+0BAC:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61C66DBE61BE6DBE6DC67FFE0000
+0BAD:00007FFE738E6DB66D8E6DB6738E7FFE7FFE618E6DB661B66DB66D8E7FFE0000
+0BAE:000000000000000000000000000011C01120112011201FC00000000000000000
+0BAF:000000000000000000000000000012101210121012100FF00000000000000000
+0BB0:00000000000000000FF008400840084008400840084008400040008001000200
+0BB1:000000000000000007700888088808880888088808880888001000100FE01000
+0BB2:00000000000000001C2022104110411071104910491030E00000000000000000
+0BB3:00000000000000001CFC23104110411071104910491031100000000000000000
+0BB4:000000000000000021C02220222022202220222022203FC0020023C020801F00
+0BB5:00000000000000001C1023104090409070904890491033F00000000000000000
+0BB6:00000000000000008FF888888888888888888888888888887070000000000000
+0BB7:00000000000000001C10222841284128711049284A4833F00080010000000000
+0BB8:00000000000000001D9022484248424872484A484A4832300000000000000000
+0BB9:0000000000000000386C449282928292E292929294926792000400043FF84000
+0BBA:00007FFE738E6DB66D8E6DB6738E7FFE7FFE63866DB663866DB663B67FFE0000
+0BBB:00007FFE738E6DB66D8E6DB6738E7FFE7FFE638E6DB6638E6DB6638E7FFE0000
+0BBC:00007FFE738E6DB66D8E6DB6738E7FFE7FFE63C66DBE63BE6DBE63C67FFE0000
+0BBD:00007FFE738E6DB66D8E6DB6738E7FFE7FFE638E6DB663B66DB6638E7FFE0000
+0BBE:0000000000000000001F00120012001200120012001200120000000000000000
+0BBF:001C002200220012000200020002000200020002000200020000000000000000
+0BC0:01C0022002C00100008000000000000000000000000000000000000000000000
+0BC1:0000000000000000000000000000000000000000000000000001000100010001
+0BC2:00000000000000000000000000000000000000000000004006600850081007E0
+0BC3:00007FFE738E6DB66D8E6DB6738E7FFE7FFE718E6FF66FC66FF6718E7FFE0000
+0BC4:00007FFE738E6DB66D8E6DB6738E7FFE7FFE71B66FB66F866FF671F67FFE0000
+0BC5:00007FFE738E6DB66D8E6DB6738E7FFE7FFE71866FBE6F866FF671867FFE0000
+0BC6:00000000000000003000480084008400E4009400940064000000000000000000
+0BC7:000000000000000030004800B00080008000B000480030000000000000000000
+0BC8:00000000000000003D80424087408540E5409540924060000000000000000000
+0BC9:00007FFE738E6DB66D8E6DB6738E7FFE7FFE71CE6FB66FC66FF671CE7FFE0000
+0BCA:0000000000000000301F481284128412E4129412941264120000000000000000
+0BCB:0000000000000000301F4812B01280128012B012481230120000000000000000
+0BCC:0000000000000000301F482A844A84CAE4AA94AA94AA644A0000000000000000
+0BCD:0300030000000000000000000000000000000000000000000000000000000000
+0BCE:00007FFE738E6DB66D8E6DB6738E7FFE7FFE71866FBE6F8E6FBE71867FFE0000
+0BCF:00007FFE738E6DB66D8E6DB6738E7FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+0BD0:0000000000000FF0300C400280018001E01D9025942961261AA0279E20041FF8
+0BD1:00007FFE738E6DB66D8E6DB6738E7FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000
+0BD2:00007FFE738E6DB66D8E6DB6738E7FFE7FFE63866DF66D866DBE63867FFE0000
+0BD3:00007FFE738E6DB66D8E6DB6738E7FFE7FFE638E6DF66DC66DF6638E7FFE0000
+0BD4:00007FFE738E6DB66D8E6DB6738E7FFE7FFE63B66DB66D866DF663F67FFE0000
+0BD5:00007FFE738E6DB66D8E6DB6738E7FFE7FFE63866DBE6D866DF663867FFE0000
+0BD6:00007FFE738E6DB66D8E6DB6738E7FFE7FFE63CE6DBE6D8E6DB663CE7FFE0000
+0BD7:0000000000000000001F002A004A00CA00AA00AA00AA004A0000000000000000
+0BD8:00007FFE738E6DB66D8E6DB6738E7FFE7FFE63CE6DB66DCE6DB663CE7FFE0000
+0BD9:00007FFE738E6DB66D8E6DB6738E7FFE7FFE63CE6DB66DC66DF663CE7FFE0000
+0BDA:00007FFE738E6DB66D8E6DB6738E7FFE7FFE63866DB66D866DB663B67FFE0000
+0BDB:00007FFE738E6DB66D8E6DB6738E7FFE7FFE638E6DB66D8E6DB6638E7FFE0000
+0BDC:00007FFE738E6DB66D8E6DB6738E7FFE7FFE63C66DBE6DBE6DBE63C67FFE0000
+0BDD:00007FFE738E6DB66D8E6DB6738E7FFE7FFE638E6DB66DB66DB6638E7FFE0000
+0BDE:00007FFE738E6DB66D8E6DB6738E7FFE7FFE63866DBE6D8E6DBE63867FFE0000
+0BDF:00007FFE738E6DB66D8E6DB6738E7FFE7FFE63866DBE6D8E6DBE63BE7FFE0000
+0BE0:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61CE6FB663B66FB661CE7FFE0000
+0BE1:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61EE6FCE63EE6FEE61C67FFE0000
+0BE2:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61866FF663866FBE61867FFE0000
+0BE3:00007FFE738E6DB66D8E6DB6738E7FFE7FFE618E6FF663C66FF6618E7FFE0000
+0BE4:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61B66FB663866FF661F67FFE0000
+0BE5:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61866FBE63866FF661867FFE0000
+0BE6:0000000000000000018002400420042004200420024001800000000000000000
+0BE7:000000000000000000000FE00880088008803FE040903F200000000000000000
+0BE8:000000000000000000003800440044004400380010001FFC0000000000000000
+0BE9:00000000000000003F802200220022C023202220204023FC0000000000000000
+0BEA:000000000000000000000FE40884088408843FFC40803F000000000000000000
+0BEB:000000000000000013F82220422042204220423842244224400420081FF00000
+0BEC:000000000000000000000FE00880088008803FFE40A43F240000000000000000
+0BED:000000000000000007FC081010101C102210221022101C100000000000000000
+0BEE:0000000000000E0011101090085006503FF0405020901F100000000000000000
+0BEF:000000000000000000000FC009000900091C3FE241323E2A0012000000000000
+0BF0:0000038000400020222022202220222022202220222022201DC0000000000000
+0BF1:00000000000000001BF826202220222022202220222022200000000000000000
+0BF2:000000000000000000000FE00880088008803FFC40903F780054003400040078
+0BF3:00000000000000001C0023004080408070804880490033F00000000000000000
+0BF4:007000C800AE00C021C02220222022202220222022203FC00000000000000000
+0BF5:000000003FFC40029C3AA252A154A155B152A958AA5493D4800440083FF00000
+0BF6:000000000000000008800880088008900890089008900790009007F008800700
+0BF7:00000000000000001F002400440064C4952497949554649C0000000000000000
+0BF8:00000000000000003E024105808583C5E4A2949594A5633E0008001000000000
+0BF9:0E0011003C8052F04C0047E0484048404840487048484848400820101FE00000
+0BFA:0038004400F2014B01300F8011001100110011C011201120002000401F802000
+0BFB:00007FFE738E6DB66D8E6DB6738E7FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+0BFC:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+0BFD:00007FFE738E6DB66D8E6DB6738E7FFE7FFE618E6FB663B66FB66F8E7FFE0000
+0BFE:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61866FBE638E6FBE6F867FFE0000
+0BFF:00007FFE738E6DB66D8E6DB6738E7FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+0C00:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE73CE6DB66DB66DB673CE7FFE0000
+0C01:0000000000000000000000010002000400040004000200010000000000000000
+0C02:0000000000000000000000000006000900090006000000000000000000000000
+0C03:0000000000000000000200050005000200000002000500050002000000000000
+0C04:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE73B66DB66D866DF673F67FFE0000
+0C05:00000000000000000C60129032482CC82008200810100FE00000000000000000
+0C06:00000000000000000C10122832282CF02010201010200FC00000000000000000
+0C07:00000000000000003B804440444000401E8021001E8000400040004000000000
+0C08:00000000000000004200240018603C9042207FE042903C600000000000000000
+0C09:00000000010001000FE0101020007FF84000406022901DE00000000000000000
+0C0A:00000000050005001F8820444008FFF88014808845403B800000000000000000
+0C0B:000000000000000064909248124822484248824892486DB00000000000000000
+0C0C:00000000000000001B0024802480011002100210022001C00000000000000000
+0C0D:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE738E6DB66DB66DB6738E7FFE0000
+0C0E:0000000000000000002000100008000800080E0813100CE00000000000000000
+0C0F:000000000000020004E008100808000800080E0813100CE00000000000000000
+0C10:00000000000000000EE011101108000800080E0813100CE00000000000000000
+0C11:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE7BEE73CE7BEE7BEE71C67FFE0000
+0C12:00000000000000000C001200120004000800100011100EE00000000000000000
+0C13:00000600090004000C001200120004000800100011100EE00000000000000000
+0C14:00003FE001503E200C001200120004000800100011100EE00000000000000000
+0C15:0000002002400180018002400200018000400020082007C00000000000000000
+0C16:00000000000000003000480034800440042034204C4037800400000000000000
+0C17:0000000000000000088005000200050005000880088008800000000000000000
+0C18:00000000000000000000040049303088004830484C9037600400000000000000
+0C19:00000000000000000C40124013F004000800100011100EE00000000000000000
+0C1A:000000000010002001C001A0001000087808090813900C600000000000000000
+0C1B:000000000010002001C001A0001000087808090813900D600100000000000000
+0C1C:00000000000000000C40132012C004000800100011100EE00000000000000000
+0C1D:00000080210012000C901248124812481248124812E80D500040000000000000
+0C1E:00000000000000001B00248024A000F000801D0022001D000100010000000000
+0C1F:000000001000100018C02420582040104010401022101DE00000000000000000
+0C20:000000000000000010400880070008801040124010400F800000000000000000
+0C21:00000020084004800F001200210040804000406022901DE00000000000000000
+0C22:00000020084004800F001200210040804000406022901FE00200000000000000
+0C23:00000000000000000C601290210820081808203822481C300000000000000000
+0C24:0008011000A000400C6012902C6820082008200810100FE00000000000000000
+0C25:000000000000000010400880070008801240104012400F800200000000000000
+0C26:000000000000000010400880070008801040104012400D800000000000000000
+0C27:000000000000000010400880070008801040104012400F800200000000000000
+0C28:008001001A001C00038000400020001018102410222011C00000000000000000
+0C29:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61CE7DB661C66FF661CE7FFE0000
+0C2A:004000800900060000E000100008000800080E0813100CE00000000000000000
+0C2B:004000800900060000E000100008000800080E0813100DE00100000000000000
+0C2C:000000000000000030C04820081010082008210812900C600000000000000000
+0C2D:00000004000800D030E04820081010082008210812900C600100000000000000
+0C2E:00400080010006000730008800480048004838484CC833300000000000000000
+0C2F:004000800D0002000130008830484848484848484CC833300000000000000000
+0C30:000000000000000010400880070008801040104010400F800000000000000000
+0C31:00000000000000000C60129032882FC82008200810100FE00000000000000000
+0C32:000000000000000018C02420641058104010402020401F800000000000000000
+0C33:0008001001A001C00040182024102C1010200FC0090006000000000000000000
+0C34:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE63B67DB671867DF663F67FFE0000
+0C35:000000100020004001E001900008000800080E0813100CE00000000000000000
+0C36:00000040008001000780064000200E2011401380048003000000000000000000
+0C37:004000800900060000E000100008000800080E0813100CE00010000800040000
+0C38:004000800500020000E000100008000800080E08131010E00000000000000000
+0C39:040008005000200007F8022801100080008038804C8033000000000000000000
+0C3A:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE63867DB671867DB663B67FFE0000
+0C3B:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE638E7DB6718E7DB6638E7FFE0000
+0C3C:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE63C67DBE71BE7DBE63C67FFE0000
+0C3D:0000000000000000000007000080008003000400040003F80000000000000000
+0C3E:000000000000000000FF00050002000000000000000000000000000000000000
+0C3F:0180024001C00780000000000000000000000000000000000000000000000000
+0C40:04000980064001C0078000000000000000000000000000000000000000000000
+0C41:0000000000000000000000060001000100010001000900060000000000000000
+0C42:000000000000000000FF002500120008000400020012000C0000000000000000
+0C43:0000000000000000000000060001000100010005000B00060000000000000000
+0C44:0000000000000000001F0011000800040002000A0016000C0000000000000000
+0C45:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE6D866DBE61867DF67D867FFE0000
+0C46:0FC00020002000C0000000000000000000000000000000000000000000000000
+0C47:006000800FC0002000C000000000000000000000000000000000000000000000
+0C48:0FC00020002000C000000000000000000000000000000000000004000A000FF0
+0C49:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE6DCE6DB661C67DF67DCE7FFE0000
+0C4A:000037E008900060000000000000000000000000000000000000000000000000
+0C4B:0030004837E04850002000000000000000000000000000000000000000000000
+0C4C:00003FE004903860000000000000000000000000000000000000000000000000
+0C4D:0F0010000C0010000C0000000000000000000000000000000000000000000000
+0C4E:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE6D866DBE618E7DBE7D867FFE0000
+0C4F:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE6D866DBE618E7DBE7DBE7FFE0000
+0C50:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61CE6FB661B67DB661CE7FFE0000
+0C51:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61EE6FCE61EE7DEE61C67FFE0000
+0C52:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61866FF661867DBE61867FFE0000
+0C53:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE618E6FF661C67DF6618E7FFE0000
+0C54:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61B66FB661867DF661F67FFE0000
+0C55:0060009000480000000000000000000000000000000000000000000000000000
+0C56:000000000000000000000000000000000000000000000000000004000A000FF0
+0C57:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61866FF661EE7DDE61DE7FFE0000
+0C58:010002807F90002001C001A0001000087808090813900C600000000000000000
+0C59:004000A01FE000000C40132012C004000800100011100EE00000000000000000
+0C5A:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61866FB661867DB661B67FFE0000
+0C5B:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE618E6FB6618E7DB6618E7FFE0000
+0C5C:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61C66FBE61BE7DBE61C67FFE0000
+0C5D:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE618E6FB661B67DB6618E7FFE0000
+0C5E:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61866FBE618E7DBE61867FFE0000
+0C5F:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61866FBE618E7DBE61BE7FFE0000
+0C60:0000000000000000493EA4952492249044908490A4905B600000000000000000
+0C61:00000000000000001B3E24A524A2011002100210022001C00000000000000000
+0C62:00000000000000000000000000000000000000000000000006C0092800280010
+0C63:0000000000000000000000000000000000000000000000001B3824B400A80040
+0C64:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE73B66FB663866DF673F67FFE0000
+0C65:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE73866FBE63866DF673867FFE0000
+0C66:0000000000000000018002400420042004200420024001800000000000000000
+0C67:000000000000000003C004200810081008100810042002400000000000000000
+0C68:0000000000000000000000E0011001480088000800103FE00000000000000000
+0C69:000000000000000001E00210021000E000100210021001E00000000000000000
+0C6A:0000000000000000042008100810042003C00420042003C00000000000000000
+0C6B:00000000000000000004030400C8003000300048008807100000000000000000
+0C6C:00000000000000003800400040003F004000400020001FF80000000000000000
+0C6D:000000000000000001C002200420004003880408041003E00000000000000000
+0C6E:000000000000000010FC2080404040404040404020801F000000000000000000
+0C6F:00000000000000001FF82000400040003F004000400038000000000000000000
+0C70:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61CE7DB67BB677B677CE7FFE0000
+0C71:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61EE7DCE7BEE77EE77C67FFE0000
+0C72:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61867DF67B8677BE77867FFE0000
+0C73:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE618E7DF67BC677F6778E7FFE0000
+0C74:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61B67DB67B8677F677F67FFE0000
+0C75:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61867DBE7B8677F677867FFE0000
+0C76:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61CE7DBE7B8E77B677CE7FFE0000
+0C77:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61867DF67BEE77DE77DE7FFE0000
+0C78:000000000000000003C0042004200420042003C0002000100060018000000000
+0C79:0000000000000000008000800080008000800080008000800000000000000000
+0C7A:0000000000000000022002200220022001E00020002000200000000000000000
+0C7B:0000000000000000092009200920092006E00020002000200000000000000000
+0C7C:000000000000000000000000000000000000000000001FF80000000000000000
+0C7D:000000000000000007C00020002001C002000400040003F80000000000000000
+0C7E:0000000000000700008003000400030000800300040003F80000000000000000
+0C7F:0000000000000000060009001608100810101010082007C00000000000000000
+0C80:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE73CE6DB673B66DB673CE7FFE0000
+0C81:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE73EE6DCE73EE6DEE73C67FFE0000
+0C82:0000000000000000000000000006000900090006000000000000000000000000
+0C83:0000000000000000000200050005000200020005000500020000000000000000
+0C84:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE73B66DB673866DF673F67FFE0000
+0C85:00000000000000000C60129032482CE82008200810100FE00000000000000000
+0C86:00000000000000000C30124832282CF02008200810100FE00000000000000000
+0C87:00000000000000003B804440444000401E8021001E8000400040004000000000
+0C88:000000000000000002000200FE603C9042607FE042203C400000000000000000
+0C89:00000000000000004620A910A910C91089108910492030C00000000000000000
+0C8A:0000000000000000461CA922A922C9228926892A492A30C40000000000000000
+0C8B:000000000080008067909088684408440844684494A463180000000000000000
+0C8C:00000000000000001B0024802480011002100210022001C00000000000000000
+0C8D:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE738E6DB673B66DB6738E7FFE0000
+0C8E:00000000000000003E000180004000202010510842883C500000000000000000
+0C8F:000000000000200010000980064000202010510842883C700000000000000000
+0C90:00000000000000001C602290410800082008510842883C700000000000000000
+0C91:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE73EE6DCE71EE7DEE73C67FFE0000
+0C92:000000000000000030004800480010202010410842883C700000000000000000
+0C93:000000001800200030004800480010202010410842883C700000000000000000
+0C94:7FE0021002107C90312048C0480010202010410842883C700000000000000000
+0C95:0000000000C000201FC0020002001FC00880104010400F800000000000000000
+0C96:00000000000000000E2011102088208401040F0412840C780000000000000000
+0C97:000000E0001000103FE004400820082008200820082008200000000000000000
+0C98:0000000007000080FF200010020860289030622027201AC00200000000000000
+0C99:000000000000000033F04C08483011002010410842883C700000000000000000
+0C9A:000000000030000860F09080904020E0404084408A4071800000000000000000
+0C9B:000000000030000860F090809040E040804084408E4075800400000000000000
+0C9C:0000000000000000318048404F80100020404220452038C00000000000000000
+0C9D:00000E0001003E001C902248224822482248224822E81D500040000000000000
+0C9E:00000000000000001B6024902490008000801D0022001D000100010000000000
+0C9F:201020102010102018C02420582040104010401022101DE00000000000000000
+0CA0:000000000000038000401F80070008801040124010400F800000000000000000
+0CA1:000000000000038000407F802000400040204250251018E00000000000000000
+0CA2:000000000000038000407F80200040004020425027101AE00200000000000000
+0CA3:000000000000000018E025104208400820884148415030E00000000000000000
+0CA4:0000000001C000200FC00020001010D0112008D0041003E00000000000000000
+0CA5:000000000000038000401F80070008801240104012400F800200000000000000
+0CA6:000000000000038000401F80070008801040104012400D800000000000000000
+0CA7:000000000000038000401F80070008801040104012400F800200000000000000
+0CA8:0000000000E0001007E000400020001018102410222011C00000000000000000
+0CA9:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61CE6DB661C66DF66DCE7FFE0000
+0CAA:0000000000E000101FE00000202051105008610842883C700000000000000000
+0CAB:0000000000E000101FE00000202051105008610842883D700100000000000000
+0CAC:000000000000000030C04820081010082008210812900C600000000000000000
+0CAD:000000000070000831F04840082010102008210812900D600100000000000000
+0CAE:00000000038000403F8000004090A048A048C4488A4871B00000000000000000
+0CAF:00000000000000C0002033C048908448844884488A4871B00000000000000000
+0CB0:000000000000038000401F80070008801040104010400F800000000000000000
+0CB1:00000000000000000C60129032983FF82008210812900C600000000000000000
+0CB2:000000000000000001003080484070204020402020401F800000000000000000
+0CB3:000000000060001001E03080484070204020402020401F800900060000000000
+0CB4:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE63B66DB663866DF663F67FFE0000
+0CB5:0000000000000030000803F0202050105008610842883C700000000000000000
+0CB6:0000000001C000207FC030804840442024200420044003800000000000000000
+0CB7:0000000000C000200FC00000202051105008612842983C740000000000000000
+0CB8:00000000018000400F800000042000100E101110209020600000000000000000
+0CB9:0000000000E0001007E0000002A005D008880888049003600000000000000000
+0CBA:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE63866DB663866DB663B67FFE0000
+0CBB:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE638E6DB6638E6DB6638E7FFE0000
+0CBC:0000000000000000000000000000000000000000000000000000000002400000
+0CBD:00000000000000000E001000200010000C00020042003C000000000000000000
+0CBE:000000000000000000000000001E000100050009000600000000000000000000
+0CBF:00C0012000E00040018000000000000000000000000000000000000000000000
+0CC0:00C0012000E00040018200050005000600040004000400040002000000000000
+0CC1:0000000000000000000000040002000100010001000900060000000000000000
+0CC2:00000000000000000000000600090009000B000B000B00080008003000000000
+0CC3:00000000000000000000000C0002000100010007000700070000000000000000
+0CC4:007E002100150016001000080004000200010005000900060000000000000000
+0CC5:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE71866FBE6F866FF671867FFE0000
+0CC6:0018002400040FF8000000000000000000000000000000000000000000000000
+0CC7:0018002400040FF8000200050005000600040004000400020000000000000000
+0CC8:0018002400040FF800040002000400020001000D000D00060000000000000000
+0CC9:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE71CE6FB66FC66FF671CE7FFE0000
+0CCA:0018002400040FF80000000600090009000B000B000B00080008003000000000
+0CCB:0063009300120FE20001000700090009000B000B000B00080008003000000000
+0CCC:1FFC008200BA1F3C000000000000000000000000000000000000000000000000
+0CCD:0018002007F00028001000000000000000000000000000000000000000000000
+0CCE:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE71866FBE6F8E6FBE71867FFE0000
+0CCF:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+0CD0:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE63CE6DB66DB66DB663CE7FFE0000
+0CD1:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000
+0CD2:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE63866DF66D866DBE63867FFE0000
+0CD3:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE638E6DF66DC66DF6638E7FFE0000
+0CD4:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE63B66DB66D866DF663F67FFE0000
+0CD5:0000000000000000000200050005000600040004000400020000000000000000
+0CD6:000000000000000000040002000400020001000D000D00060000000000000000
+0CD7:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE63866DF66DEE6DDE63DE7FFE0000
+0CD8:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE63CE6DB66DCE6DB663CE7FFE0000
+0CD9:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE63CE6DB66DC66DF663CE7FFE0000
+0CDA:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE63866DB66D866DB663B67FFE0000
+0CDB:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE638E6DB66D8E6DB6638E7FFE0000
+0CDC:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE63C66DBE6DBE6DBE63C67FFE0000
+0CDD:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE638E6DB66DB66DB6638E7FFE0000
+0CDE:00000000000000000C60129032982C682008200811100EE00000000000000000
+0CDF:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE63866DBE6D8E6DBE63BE7FFE0000
+0CE0:00000000004000400F80620E9111711111137115999566620000000000000000
+0CE1:0000000000000000319F4A534453204800880088008800700000000000000000
+0CE2:00000000000000000000000000000000000000000000000006C0092008200418
+0CE3:0000000000000000000000000000000000000000000000000D80124C1050083C
+0CE4:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61B66FB663866FF661F67FFE0000
+0CE5:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61866FBE63866FF661867FFE0000
+0CE6:0000000000000000018002400420042004200420024001800000000000000000
+0CE7:000000000000000003C004200810081008100810042002400000000000000000
+0CE8:000000000000000000E00110013000D000100010001007E00000000000000000
+0CE9:00000000000000000F00128012400C400E40114810900F600000000000000000
+0CEA:0000000000000000062009100E10042003C00420042003C00000000000000000
+0CEB:000000000000000000181C24232410F807E0191022101C600000000000000000
+0CEC:00000000080008003E004900490046004000400020001FF80000000000000000
+0CED:000000000000000000C0012000A0004003800400040003F80000000000000000
+0CEE:000000000020004018802480444078404040404020801F000000000000000000
+0CEF:00000000000000001FF82000400040003F004000400038000000000000000000
+0CF0:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61CE6FB663B66FB66FCE7FFE0000
+0CF1:000000000000000000000FE0044002800100028004400FE00000000000000000
+0CF2:0000000000000000000000001C702288228822881C7000000000000000000000
+0CF3:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE618E6FF663C66FF66F8E7FFE0000
+0CF4:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61B66FB663866FF66FF67FFE0000
+0CF5:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61866FBE63866FF66F867FFE0000
+0CF6:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+0CF7:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+0CF8:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+0CF9:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+0CFA:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61866FB663866FB66FB67FFE0000
+0CFB:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+0CFC:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+0CFD:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE618E6FB663B66FB66F8E7FFE0000
+0CFE:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61866FBE638E6FBE6F867FFE0000
+0CFF:00007FFE73C66DBE6DBE6DBE73C67FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+0D00:00007FFE738E6DB66DB66DB6738E7FFE7FFE73CE6DB66DB66DB673CE7FFE0000
+0D01:00007FFE738E6DB66DB66DB6738E7FFE7FFE73EE6DCE6DEE6DEE73C67FFE0000
+0D02:0000000000000000000000000006000900090006000000000000000000000000
+0D03:0000000000000000000200050005000200000002000500050002000000000000
+0D04:00007FFE738E6DB66DB66DB6738E7FFE7FFE73B66DB66D866DF673F67FFE0000
+0D05:00000000000000001E3021487C84A284BC9CA2A4A2A41C980000000000000000
+0D06:00000000000000001E32214D7C8DA295BCA5A2A5A2A51C990001003E00000000
+0D07:000000000000000018C025204210421072104A104A10321000103FE040003FE0
+0D08:000000000000000074508AA88AA88AA8CA08AA48AA30420002007C0080007C00
+0D09:00000000000000000F00128012400C4000400F8010001FC00000000000000000
+0D0A:00000000000000001C502AA82AA812A802081C4820303E000000000000000000
+0D0B:00000000000000000C6012901C701010082007C0082007C00000000000000000
+0D0C:00000000000000000C6012902128214839482548254819300000000000000000
+0D0D:00007FFE738E6DB66DB66DB6738E7FFE7FFE738E6DB66DB66DB6738E7FFE0000
+0D0E:0000000000F001087128892889285FE801280128012800C00000000000000000
+0D0F:0000000001E0021072888A888A885F9002880288028801300000000000000000
+0D10:00000000000E00117395AC55AC554AFD08150015001500080000000000000000
+0D11:00007FFE738E6DB66DB66DB6738E7FFE7FFE7BEE73CE7BEE7BEE71C67FFE0000
+0D12:0000000000000000078008401020201020103C2022101C600000000000000000
+0D13:00000000000000000E181124210420842084310428A413180000000000000000
+0D14:00000000000000001C2822544254415441046224511826000000000000000000
+0D15:00000000000000000380044004403FF04C483448045003800000000000000000
+0D16:00000000000000001E0421044084404470444844488431FC0000000000000000
+0D17:000000000000000000000000187020884104410422081C700000000000000000
+0D18:00000000000000000072008A388A448A448A2FFA008200FE0000000000000000
+0D19:000000000000000018E025104208420872704A084A0832700000000000000000
+0D1A:000000000000000000080008000806080908010802083FF80000000000000000
+0D1B:00000000000000000030004800840C84128C029404543FC80000000000000000
+0D1C:00000000000000003EE041107110491030203FF040C83F300000000000000000
+0D1D:00000000000000003C245E22A522A52299228122412400D80000000000000000
+0D1E:000000000000000018C025384254429472944A944A9432600000000000000000
+0D1F:0000000000000000000007C00800080007C00020002007C00000000000000000
+0D20:0000000000000000000000000780084008400840078000000000000000000000
+0D21:000000000000000000000C4812442244224422441244024801B0000000000000
+0D22:00000000000000000000189024A824A824A824A8049804900360000000000000
+0D23:000000000000000019B0264842484248424872484A4832500000000000000000
+0D24:00000000000000000CF013082284244424242424224411880000000000000000
+0D25:000000000000000040F04108410841084108410841087FF80000000000000000
+0D26:000000000000000007C00820102011C010201020122009C00000000000000000
+0D27:0000000000000000092011102108210821082108111006E00000000000000000
+0D28:00000000000000000EE011102108210821082108111009200000000000000000
+0D29:00000000000000000CE013102108390825082508251019200000000000000000
+0D2A:000000000000000000080008000800083808440844082FF80000000000000000
+0D2B:000000000000000000700088008800883888448844882FF80000000000000000
+0D2C:00000000000000001988264842484248424872484A4832780000000000000000
+0D2D:000000000000000007C00820102011C0120011C010200BC00000000000000000
+0D2E:000000000000000007E0091010881088110812081C081FF80000000000000000
+0D2F:00000000000011882244242424242444228413080CF000000000000000000000
+0D30:00000000000000000F0010C020A0211021082108209010600000000000000000
+0D31:000000000000000007C008201010101010101010101008200000000000000000
+0D32:00000000000000000C081208210821083F08200820083FF80000000000000000
+0D33:00000000000000000FC01020202038C02420182000200FC010000FF000000000
+0D34:000000000000000010E011101110092007C0010011000E000000000000000000
+0D35:00000000000000001E0821084088408840884088410823F80000000000000000
+0D36:00000000000000000870108821042104211C212412240C180000000000000000
+0D37:000000000000000000000100029802A839C8448844882FF80000000000000000
+0D38:0000000000000000361049088888888888888888889048E00000000000000000
+0D39:000000000000000000E001100208020872088A0889105F200000000000000000
+0D3A:000000000000000010C0112011201120112010A010601FF80020002000200000
+0D3B:00007FFE738E6DB66DB66DB6738E7FFE7FFE638E7DB6718E7DB6638E7FFE0000
+0D3C:00007FFE738E6DB66DB66DB6738E7FFE7FFE63C67DBE71BE7DBE63C67FFE0000
+0D3D:0000001000280028004000400040004000400040004002800280010000000000
+0D3E:0000000000000000000600090001000100010001000900060000000000000000
+0D3F:0000000600090009000100010001000100010001000100010000000000000000
+0D40:0006000900070001000100010001000100010001000100010000000000000000
+0D41:00000000000000000000000600090001000200040004000A0004000000000000
+0D42:00000000000000000000000600090001000200040004000A00050001000E0000
+0D43:0000000000000000000100020004000400040002000100010001001F0021001E
+0D44:000000000000000000010002000400040004000200010001000100FF015500FE
+0D45:00007FFE738E6DB66DB66DB6738E7FFE7FFE6D866DBE61867DF67D867FFE0000
+0D46:00000000000000007000880088008800C800A800A80048001000000000000000
+0D47:000000000000000060009000E00080008000E000900060000000000000000000
+0D48:0000000000000000D800B400B400B40090009000D800D8000000000000000000
+0D49:00007FFE738E6DB66DB66DB6738E7FFE7FFE6DCE6DB661C67DF67DCE7FFE0000
+0D4A:00000000000000007006880988018801C801A801A80948061000000000000000
+0D4B:000000000000000060069009E00180018001E001900960060000000000000000
+0D4C:0000000000000000700A881588158801C802A804A80048001000000000000000
+0D4D:001200210021001E000000000000000000000000000000000000000000000000
+0D4E:0000000000000060006000000000000000000000000000000000000000000000
+0D4F:00007FFE738E6DB66DB66DB6738E7FFE7FFE6D866DBE618E7DBE7DBE7FFE0000
+0D50:00007FFE738E6DB66DB66DB6738E7FFE7FFE61CE6FB661B67DB661CE7FFE0000
+0D51:00007FFE738E6DB66DB66DB6738E7FFE7FFE61EE6FCE61EE7DEE61C67FFE0000
+0D52:00007FFE738E6DB66DB66DB6738E7FFE7FFE61866FF661867DBE61867FFE0000
+0D53:00007FFE738E6DB66DB66DB6738E7FFE7FFE618E6FF661C67DF6618E7FFE0000
+0D54:00007FFE738E6DB66DB66DB6738E7FFE7FFE61B66FB661867DF661F67FFE0000
+0D55:00007FFE738E6DB66DB66DB6738E7FFE7FFE61866FBE61867DF661867FFE0000
+0D56:00007FFE738E6DB66DB66DB6738E7FFE7FFE61CE6FBE618E7DB661CE7FFE0000
+0D57:0000000000000000000A00150015000100020004000000000000000000000000
+0D58:00007FFE738E6DB66DB66DB6738E7FFE7FFE61CE6FB661CE7DB661CE7FFE0000
+0D59:00007FFE738E6DB66DB66DB6738E7FFE7FFE61CE6FB661C67DF661CE7FFE0000
+0D5A:00007FFE738E6DB66DB66DB6738E7FFE7FFE61866FB661867DB661B67FFE0000
+0D5B:00007FFE738E6DB66DB66DB6738E7FFE7FFE618E6FB6618E7DB6618E7FFE0000
+0D5C:00007FFE738E6DB66DB66DB6738E7FFE7FFE61C66FBE61BE7DBE61C67FFE0000
+0D5D:00007FFE738E6DB66DB66DB6738E7FFE7FFE618E6FB661B67DB6618E7FFE0000
+0D5E:00007FFE738E6DB66DB66DB6738E7FFE7FFE61866FBE618E7DBE61867FFE0000
+0D5F:00007FFE738E6DB66DB66DB6738E7FFE7FFE61866FBE618E7DBE61BE7FFE0000
+0D60:0000000000000000186024905868400820101FE02010249020101FE000000000
+0D61:000000000000000018C025384254429472944A944A9432640004004800300000
+0D62:0000000000000000000000000000000000000000000000001EF0393825481930
+0D63:000000000000000000000000000000000000000000001EF039382548183800F0
+0D64:00007FFE738E6DB66DB66DB6738E7FFE7FFE73B66FB663866DF673F67FFE0000
+0D65:00007FFE738E6DB66DB66DB6738E7FFE7FFE73866FBE63866DF673867FFE0000
+0D66:00000000000000000000000003C004200420042003C000000000000000000000
+0D67:000000000000000000F00108010801080108010801081FF820001F0000000000
+0D68:00000000000000001E0021004080408040804080410023F80000000000000000
+0D69:00000000000000001B00248044404440444044404440247C0000000000000000
+0D6A:000000000000000006000100010007C009201120112010C00000000000000000
+0D6B:000000000000000007E008101188124812881248085007E00000000000000000
+0D6C:00000000000000001B1824A44442444244424442444224420004000800100000
+0D6D:0000000000000000038005400920092006200040088007000000000000000000
+0D6E:000000000000000000201C202220222017E00020002001C00000000000000000
+0D6F:00000000000000000380008000801BE024904490449024600000000000000000
+0D70:00000000000000000000024802440244024402440244024803B002003C000000
+0D71:00000000000000000EE0111021082108210811080010022001C0000000000000
+0D72:00000000000000001B84244A442A44FE4520452044A024400000000000000000
+0D73:00000000000000000000000000000FF810001C0012000C000000000000000000
+0D74:000001C0002000100FD010202050209038902490249018600000000000000000
+0D75:000000E0001000080C6812902128214839482548254819300000000000000000
+0D76:00007FFE738E6DB66DB66DB6738E7FFE7FFE61CE7DBE7B8E77B677CE7FFE0000
+0D77:00007FFE738E6DB66DB66DB6738E7FFE7FFE61867DF67BEE77DE77DE7FFE0000
+0D78:00007FFE738E6DB66DB66DB6738E7FFE7FFE61CE7DB67BCE77B677CE7FFE0000
+0D79:00000000000000001B802440442044FE4520452044A024400000000000000000
+0D7A:00000030004800041B342488449844A864A854A854A824900000000000000000
+0D7B:000000E0001000080C6812902128214821482148114809300000000000000000
+0D7C:000000C00020001007D008201050109010901090089004600000000000000000
+0D7D:000000E0001000081CE823104528494849484948494826300000000000000000
+0D7E:000000E00010000800681090212821482148214812480C300000000000000000
+0D7F:0000038004400020072008A008A03FF848A448A4489837000000000000000000
+0D80:00007FFE738E6DB66DB66DB6738E7FFE7FFE73CE6DB673B66DB673CE7FFE0000
+0D81:00007FFE738E6DB66DB66DB6738E7FFE7FFE73EE6DCE73EE6DEE73C67FFE0000
+0D82:0000000000000000000000000006000900090006000000000000000000000000
+0D83:0000000000000000000600090009000600000006000900090006000000000000
+0D84:00007FFE738E6DB66DB66DB6738E7FFE7FFE73B66DB673866DF673F67FFE0000
+0D85:0000000000000000031804A800680FF010201020082007E00020002000200020
+0D86:000000000000000018D8256403427F828102810241243F180100010001000100
+0D87:00000000000000000C4012A001BE3FC24084408420841F840084008400840083
+0D88:00000000000000000C4012A001BE3FC44088409E20821F840084008400840083
+0D89:000000000000000007C008201110129011100E60001000E00000000000000000
+0D8A:0800150009200250042007000880104010401040088007000000000000000000
+0D8B:00000000000000000180024000200FE01000101010200FC00000000000000000
+0D8C:0000000000000000062C092A00923F824012404C40803F000000000000000000
+0D8D:0000000000000000618092400A267BE9802184278A4971868001000000000000
+0D8E:00000000000000004200A500149277AD8089889B952D62120000000000000000
+0D8F:00000000000000001C382A5442424E72500A481227E410080FF0000000000000
+0D90:000000000000000071C0AAA08A36BBB5A0A9A0A19F2940463F80000000000000
+0D91:03800480038000800C8002403E2010202020202010400F800000000000000000
+0D92:03B804A403B800A00CA002603E2010202020202010400F800000000000000000
+0D93:001C0024001C00040064701289F18481B301B9018882707C0000000000000000
+0D94:0000000000003FE0401001C861A450244FC4400421081EF00000000000000000
+0D95:00007FC020203FF0401001C861A450244FC4400421081EF00000000000000000
+0D96:0000000000007F0080800E400D6CC16ABE5280428892770C0007000000000000
+0D97:00007FFE738E6DB66DB66DB6738E7FFE7FFE73866DF671EE7DDE73DE7FFE0000
+0D98:00007FFE738E6DB66DB66DB6738E7FFE7FFE73CE6DB671CE7DB673CE7FFE0000
+0D99:00007FFE738E6DB66DB66DB6738E7FFE7FFE73CE6DB671C67DF673CE7FFE0000
+0D9A:0000000000000000600093E08C100FC8102820284448BB900000000000000000
+0D9B:00000000000000001FE020100F081088204820482C901CE00100000000000000
+0D9C:000000000000000000000000278048408E208220444038800000000000000000
+0D9D:00000000000000003080494005407D8010402020272018C00000000000000000
+0D9E:000000003F8040401C201A1002103E104010401022201DC00000000000000000
+0D9F:00000000000000001C382A4442424E725012482227C41F880000000000000000
+0DA0:000000001F0020800C4002203E2010202020202010400F800000000000000000
+0DA1:00000020004000800CB002C83E78104C2032200210040FF80000000000000000
+0DA2:00000008001000200C2002703EA810A82070202010400F800000000000000000
+0DA3:0000000000000070E088900427C2782286428182C992B66C0000000000000000
+0DA4:000000000000000039F056288404987CA680C180C944B638000800100010000C
+0DA5:000000000000000038385454848299BEA1E0C240C44C38340004000800080006
+0DA6:00000004000800101D902A3842544C545038601060201FC00000000000000000
+0DA7:00000000000000001F80204000201C202020202010400F800000000000000000
+0DA8:01C0024001C0004000400020001020104010401022201DC00000000000000000
+0DA9:000000001FC020200C1002083E0810082008200811100EE00000000000000000
+0DAA:01C0024001C00040184004207C1020104010401022201DC00000000000000000
+0DAB:0000000000F801001E002600390C355239B24152820CFC000000000000000000
+0DAC:000000001FC0202007100A88108813081408180811100EE00000000000000000
+0DAD:0000000000000000600093E08C100FC8102820284048BF900000000000000000
+0DAE:01C0024001C0004010402020401040104010401020201FC00000000000000000
+0DAF:0000000000000000000000C00120002007E00400043003D00010002000200018
+0DB0:000000000FC01020201000080C0810082008200811100EE00000000000000000
+0DB1:00000000000000E0611092088C040F04108420844124BE180000000000000000
+0DB2:00007FFE738E6DB66DB66DB6738E7FFE7FFE63866DF663866DBE63867FFE0000
+0DB3:00000000000000000380054008200BE00C000C00022001C00040008000800060
+0DB4:000000000000000000000610012803680C1810040C1803E00000000000000000
+0DB5:000000E0012000E000200620011003080C0810040C1803E00000000000000000
+0DB6:00000000000000001FE020100F081088204820482C901C600000000000000000
+0DB7:00000000000000003070488805047DC41044208421081E100000000000000000
+0DB8:0000000000001FE0201001C81A281AA8162813C8081007E00000000000000000
+0DB9:0000000000001FE0201001C81B281BE817E81008099006600000000000000000
+0DBA:000000000000000000000080014001C01040202022201DC00000000000000000
+0DBB:0000010001000200040007000880104010401040088007000000000000000000
+0DBC:00007FFE738E6DB66DB66DB6738E7FFE7FFE63C66DBE63BE6DBE63C67FFE0000
+0DBD:00000000000000000F801040272022482188201010200FC00000000000000000
+0DBE:00007FFE738E6DB66DB66DB6738E7FFE7FFE63866DBE638E6DBE63867FFE0000
+0DBF:00007FFE738E6DB66DB66DB6738E7FFE7FFE63866DBE638E6DBE63BE7FFE0000
+0DC0:00000000000000001FC02020461041100F101010082007C00000000000000000
+0DC1:00000000000000000000000027C048208E10825044A038400000000000000000
+0DC2:0000000000000C4002A00EE0102023502490231010200FC00000000000000000
+0DC3:00000000000000003080494005407D801040202022201DC00000000000000000
+0DC4:00000000000000003070488805041DC41044208421081E100000000000000000
+0DC5:000000000000000006C0092008201FE0180A17F210040FF80000000000000000
+0DC6:0000000000000000000000000EE011102008200810100C600000000000000000
+0DC7:00007FFE738E6DB66DB66DB6738E7FFE7FFE71866FF66FEE6FDE71DE7FFE0000
+0DC8:00007FFE738E6DB66DB66DB6738E7FFE7FFE71CE6FB66FCE6FB671CE7FFE0000
+0DC9:00007FFE738E6DB66DB66DB6738E7FFE7FFE71CE6FB66FC66FF671CE7FFE0000
+0DCA:000E0009000E0008000800080008000000000000000000000000000000000000
+0DCB:00007FFE738E6DB66DB66DB6738E7FFE7FFE718E6FB66F8E6FB6718E7FFE0000
+0DCC:00007FFE738E6DB66DB66DB6738E7FFE7FFE71C66FBE6FBE6FBE71C67FFE0000
+0DCD:00007FFE738E6DB66DB66DB6738E7FFE7FFE718E6FB66FB66FB6718E7FFE0000
+0DCE:00007FFE738E6DB66DB66DB6738E7FFE7FFE71866FBE6F8E6FBE71867FFE0000
+0DCF:0000000000000000000000000006000900010001000900060000000000000000
+0DD0:0000000000000000000200020004000400040004000400040004000300000000
+0DD1:000000000000000000000000000E000200040002000400040004000300000000
+0DD2:07F0080808080410000000000000000000000000000000000000000000000000
+0DD3:07F0084808480430000000000000000000000000000000000000000000000000
+0DD4:00000000000000000000000000000000000000000000000000000C1010100FF0
+0DD5:00007FFE738E6DB66DB66DB6738E7FFE7FFE63866DBE6D866DF663867FFE0000
+0DD6:00000000000000000000000000000000000000000000000000000C1010D00F30
+0DD7:00007FFE738E6DB66DB66DB6738E7FFE7FFE63866DF66DEE6DDE63DE7FFE0000
+0DD8:0000000000000000004000000006000900010007000900060001000000000000
+0DD9:00000000000000004000A000900090008000E000E000E0000000000000000000
+0DDA:000E0009000E00084008A008900890008000E000E000E0000000000000000000
+0DDB:00000000000000004800B400900090009000FC00FC00FC000000000000000000
+0DDC:00000000000000004000A000900690098001E001E009E0060000000000000000
+0DDD:000E0009000E00084008A008900E90098001E001E009E0060FF0000000000000
+0DDE:00000000000000004004A008900A900D8001E001E009E0060000000000000000
+0DDF:000000000000000000040008000A000D00010001000900060000000000000000
+0DE0:00007FFE738E6DB66DB66DB6738E7FFE7FFE61CE6FB663B66FB661CE7FFE0000
+0DE1:00007FFE738E6DB66DB66DB6738E7FFE7FFE61EE6FCE63EE6FEE61C67FFE0000
+0DE2:00007FFE738E6DB66DB66DB6738E7FFE7FFE61866FF663866FBE61867FFE0000
+0DE3:00007FFE738E6DB66DB66DB6738E7FFE7FFE618E6FF663C66FF6618E7FFE0000
+0DE4:00007FFE738E6DB66DB66DB6738E7FFE7FFE61B66FB663866FF661F67FFE0000
+0DE5:00007FFE738E6DB66DB66DB6738E7FFE7FFE61866FBE63866FF661867FFE0000
+0DE6:00007FFE738E6DB66DB66DB6738E7FFE7FFE61CE6FBE638E6FB661CE7FFE0000
+0DE7:00007FFE738E6DB66DB66DB6738E7FFE7FFE61866FF663EE6FDE61DE7FFE0000
+0DE8:00007FFE738E6DB66DB66DB6738E7FFE7FFE61CE6FB663CE6FB661CE7FFE0000
+0DE9:00007FFE738E6DB66DB66DB6738E7FFE7FFE61CE6FB663C66FF661CE7FFE0000
+0DEA:00007FFE738E6DB66DB66DB6738E7FFE7FFE61866FB663866FB661B67FFE0000
+0DEB:00007FFE738E6DB66DB66DB6738E7FFE7FFE618E6FB6638E6FB6618E7FFE0000
+0DEC:00007FFE738E6DB66DB66DB6738E7FFE7FFE61C66FBE63BE6FBE61C67FFE0000
+0DED:00007FFE738E6DB66DB66DB6738E7FFE7FFE618E6FB663B66FB6618E7FFE0000
+0DEE:00007FFE738E6DB66DB66DB6738E7FFE7FFE61866FBE638E6FBE61867FFE0000
+0DEF:00007FFE738E6DB66DB66DB6738E7FFE7FFE61866FBE638E6FBE61BE7FFE0000
+0DF0:00007FFE738E6DB66DB66DB6738E7FFE7FFE61CE6FB663B66FB66FCE7FFE0000
+0DF1:00007FFE738E6DB66DB66DB6738E7FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000
+0DF2:0000000000000000000000000012002D0009001B002D00120000000000000000
+0DF3:000000000000000000040008000A000D00010005000B00060000000000000000
+0DF4:0000000000000000000000000AA04AA4555425485014C0060000000000000000
+0DF5:00007FFE738E6DB66DB66DB6738E7FFE7FFE61866FBE63866FF66F867FFE0000
+0DF6:00007FFE738E6DB66DB66DB6738E7FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+0DF7:00007FFE738E6DB66DB66DB6738E7FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+0DF8:00007FFE738E6DB66DB66DB6738E7FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+0DF9:00007FFE738E6DB66DB66DB6738E7FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+0DFA:00007FFE738E6DB66DB66DB6738E7FFE7FFE61866FB663866FB66FB67FFE0000
+0DFB:00007FFE738E6DB66DB66DB6738E7FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+0DFC:00007FFE738E6DB66DB66DB6738E7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+0DFD:00007FFE738E6DB66DB66DB6738E7FFE7FFE618E6FB663B66FB66F8E7FFE0000
+0DFE:00007FFE738E6DB66DB66DB6738E7FFE7FFE61866FBE638E6FBE6F867FFE0000
+0DFF:00007FFE738E6DB66DB66DB6738E7FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+0E00:00007FFE73866DBE6D8E6DBE73867FFE7FFE73CE6DB66DB66DB673CE7FFE0000
+0E01:0000000000003C426222222222220000
+0E02:00000000000064642444444444380000
+0E03:000000000000527212222222221C0000
+0E04:0000000000003C42425A7A6242420000
+0E05:000000000000344A425A7A6242420000
+0E06:000000000000527212222222726C0000
+0E07:0000000000000C0C04044424140C0000
+0E08:0000000000003C42021A1A0A0A0C0000
+0E09:0000000000003844046464242E360000
+0E0A:000000000002323412222222221C0000
+0E0B:000000000002527412222222221C0000
+0E0C:0000000000003945254545456F6D0000
+0E0D:000000000000324A2A4A4A4A6E620E00
+0E0E:0000000000003C4262222222667A1600
+0E0F:0000000000003C42622222226A6E1A00
+0E10:0000000000001E201C021A1A06022A16
+0E11:000000000000547A1222222222220000
+0E12:0000000000002955457575556F4D0000
+0E13:000000000000324A2A4A4A4A6F6B0000
+0E14:0000000000003C42425A5A4A72420000
+0E15:000000000000344A425A5A4A72420000
+0E16:0000000000003C426222222232320000
+0E17:000000000000646A3222222222220000
+0E18:0000000000003C407824242424180000
+0E19:0000000000006464244444444E360000
+0E1A:000000000000323212222222221C0000
+0E1B:000000000002023232122222221C0000
+0E1C:00000000000069694949494949360000
+0E1D:00000000000101696949494949360000
+0E1E:00000000000069692949494949360000
+0E1F:00000000000101696929494949360000
+0E20:0000000000003C426222222262620000
+0E21:000000000000626222222222726C0000
+0E22:000000000000626242324242423C0000
+0E23:0000000000003C40780404040C0C0000
+0E24:0000000000003C426222222232320200
+0E25:0000000000003C42021A262232320000
+0E26:0000000000003C426222222262620200
+0E27:0000000000003844040404040C0C0000
+0E28:000000000002023C425A7A6242420000
+0E29:0000000000006262222A2F22221C0000
+0E2A:0000000000033C42021A262232320000
+0E2B:0000000000006666242A322222220000
+0E2C:000000000001016A6929494949360000
+0E2D:0000000000003C4202626242427E0000
+0E2E:0000000000033C7A02626242427E0000
+0E2F:0000000000006C740404040404040000
+0E30:00000000000000343800343800000000
+0E31:000000313E0000000000000000000000
+0E32:00000000000038440404040404040000
+0E33:0000006060001C220202020202020000
+0E34:0000003C420000000000000000000000
+0E35:0000003E460000000000000000000000
+0E36:0000003A4E0000000000000000000000
+0E37:0000003A460000000000000000000000
+0E38:00000000000000000000000000000602
+0E39:00000000000000000000000000001A0E
+0E3A:00000000000000000000000000000C0C
+0E3B:00007FFE73866DBE6D8E6DBE73867FFE7FFE638E7DB6718E7DB6638E7FFE0000
+0E3C:00007FFE73866DBE6D8E6DBE73867FFE7FFE63C67DBE71BE7DBE63C67FFE0000
+0E3D:00007FFE73866DBE6D8E6DBE73867FFE7FFE638E7DB671B67DB6638E7FFE0000
+0E3E:00007FFE73866DBE6D8E6DBE73867FFE7FFE63867DBE718E7DBE63867FFE0000
+0E3F:00000000087C2A2A2A3C2A2A2A7C0800
+0E40:0000000000000808080808080C0C0000
+0E41:0000000000001212121212121B1B0000
+0E42:0000003E417C04040404040406060000
+0E43:00000038445434040404040406060000
+0E44:0000006C140404040404040406060000
+0E45:00000000000038440404040404040404
+0E46:0000000000006C720202020202020408
+0E47:0000003E540000000000000000000000
+0E48:04040400000000000000000000000000
+0E49:18091E00000000000000000000000000
+0E4A:28556600000000000000000000000000
+0E4B:040E0400000000000000000000000000
+0E4C:010E0C00000000000000000000000000
+0E4D:00060600000000000000000000000000
+0E4E:0007040A0C0000000000000000000000
+0E4F:00000000000000003C425A5A423C0000
+0E50:000000000000003C42424242423C0000
+0E51:000000000000003C42425A3A023C0000
+0E52:000000000040404A56525A5A423C0000
+0E53:00000000000000344A4A4A4272720000
+0E54:000000000002023C40404C4C483E0000
+0E55:00000000001A163C40404C4C483E0000
+0E56:000000000000402C12020232323C0000
+0E57:000000000002022A5A4A4A4A6A6C0000
+0E58:000000000000033C40404656526E0000
+0E59:000000000002021A3450484864640000
+0E5A:00000000000002363A02020206040000
+0E5B:00000000000020505857545060600000
+0E5C:00007FFE73866DBE6D8E6DBE73867FFE7FFE61C66FBE61BE7DBE61C67FFE0000
+0E5D:00007FFE73866DBE6D8E6DBE73867FFE7FFE618E6FB661B67DB6618E7FFE0000
+0E5E:00007FFE73866DBE6D8E6DBE73867FFE7FFE61866FBE618E7DBE61867FFE0000
+0E5F:00007FFE73866DBE6D8E6DBE73867FFE7FFE61866FBE618E7DBE61BE7FFE0000
+0E60:00007FFE73866DBE6D8E6DBE73867FFE7FFE73CE6FB663B66DB673CE7FFE0000
+0E61:00007FFE73866DBE6D8E6DBE73867FFE7FFE73EE6FCE63EE6DEE73C67FFE0000
+0E62:00007FFE73866DBE6D8E6DBE73867FFE7FFE73866FF663866DBE73867FFE0000
+0E63:00007FFE73866DBE6D8E6DBE73867FFE7FFE738E6FF663C66DF6738E7FFE0000
+0E64:00007FFE73866DBE6D8E6DBE73867FFE7FFE73B66FB663866DF673F67FFE0000
+0E65:00007FFE73866DBE6D8E6DBE73867FFE7FFE73866FBE63866DF673867FFE0000
+0E66:00007FFE73866DBE6D8E6DBE73867FFE7FFE73CE6FBE638E6DB673CE7FFE0000
+0E67:00007FFE73866DBE6D8E6DBE73867FFE7FFE73866FF663EE6DDE73DE7FFE0000
+0E68:00007FFE73866DBE6D8E6DBE73867FFE7FFE73CE6FB663CE6DB673CE7FFE0000
+0E69:00007FFE73866DBE6D8E6DBE73867FFE7FFE73CE6FB663C66DF673CE7FFE0000
+0E6A:00007FFE73866DBE6D8E6DBE73867FFE7FFE73866FB663866DB673B67FFE0000
+0E6B:00007FFE73866DBE6D8E6DBE73867FFE7FFE738E6FB6638E6DB6738E7FFE0000
+0E6C:00007FFE73866DBE6D8E6DBE73867FFE7FFE73C66FBE63BE6DBE73C67FFE0000
+0E6D:00007FFE73866DBE6D8E6DBE73867FFE7FFE738E6FB663B66DB6738E7FFE0000
+0E6E:00007FFE73866DBE6D8E6DBE73867FFE7FFE73866FBE638E6DBE73867FFE0000
+0E6F:00007FFE73866DBE6D8E6DBE73867FFE7FFE73866FBE638E6DBE73BE7FFE0000
+0E70:00007FFE73866DBE6D8E6DBE73867FFE7FFE61CE7DB67BB677B677CE7FFE0000
+0E71:00007FFE73866DBE6D8E6DBE73867FFE7FFE61EE7DCE7BEE77EE77C67FFE0000
+0E72:00007FFE73866DBE6D8E6DBE73867FFE7FFE61867DF67B8677BE77867FFE0000
+0E73:00007FFE73866DBE6D8E6DBE73867FFE7FFE618E7DF67BC677F6778E7FFE0000
+0E74:00007FFE73866DBE6D8E6DBE73867FFE7FFE61B67DB67B8677F677F67FFE0000
+0E75:00007FFE73866DBE6D8E6DBE73867FFE7FFE61867DBE7B8677F677867FFE0000
+0E76:00007FFE73866DBE6D8E6DBE73867FFE7FFE61CE7DBE7B8E77B677CE7FFE0000
+0E77:00007FFE73866DBE6D8E6DBE73867FFE7FFE61867DF67BEE77DE77DE7FFE0000
+0E78:00007FFE73866DBE6D8E6DBE73867FFE7FFE61CE7DB67BCE77B677CE7FFE0000
+0E79:00007FFE73866DBE6D8E6DBE73867FFE7FFE61CE7DB67BC677F677CE7FFE0000
+0E7A:00007FFE73866DBE6D8E6DBE73867FFE7FFE61867DB67B8677B677B67FFE0000
+0E7B:00007FFE73866DBE6D8E6DBE73867FFE7FFE618E7DB67B8E77B6778E7FFE0000
+0E7C:00007FFE73866DBE6D8E6DBE73867FFE7FFE61C67DBE7BBE77BE77C67FFE0000
+0E7D:00007FFE73866DBE6D8E6DBE73867FFE7FFE618E7DB67BB677B6778E7FFE0000
+0E7E:00007FFE73866DBE6D8E6DBE73867FFE7FFE61867DBE7B8E77BE77867FFE0000
+0E7F:00007FFE73866DBE6D8E6DBE73867FFE7FFE61867DBE7B8E77BE77BE7FFE0000
+0E80:00007FFE73866DBE6D8E6DBE73867FFE7FFE73CE6DB673B66DB673CE7FFE0000
+0E81:00000000005C22222222222262000000
+0E82:00000000003C420418204C5222000000
+0E83:00007FFE73866DBE6D8E6DBE73867FFE7FFE738E6DF673C66DF6738E7FFE0000
+0E84:00000000003C42423242424232000000
+0E85:00007FFE73866DBE6D8E6DBE73867FFE7FFE73866DBE73866DF673867FFE0000
+0E86:00007FFE73866DBE6D8E6DBE73867FFE7FFE73CE6DBE738E6DB673CE7FFE0000
+0E87:0000000000182C140404040464444438
+0E88:00000000003C42021A26020202000000
+0E89:00007FFE73866DBE6D8E6DBE73867FFE7FFE73CE6DB673C66DF673CE7FFE0000
+0E8A:00000000003C42640810204C72020202
+0E8B:00007FFE73866DBE6D8E6DBE73867FFE7FFE738E6DB6738E6DB6738E7FFE0000
+0E8C:00007FFE73866DBE6D8E6DBE73867FFE7FFE73C66DBE73BE6DBE73C67FFE0000
+0E8D:0000000000324242324242423C000000
+0E8E:00007FFE73866DBE6D8E6DBE73867FFE7FFE73866DBE738E6DBE73867FFE0000
+0E8F:00007FFE73866DBE6D8E6DBE73867FFE7FFE73866DBE738E6DBE73BE7FFE0000
+0E90:00007FFE73866DBE6D8E6DBE73867FFE7FFE73CE6DB671B67DB673CE7FFE0000
+0E91:00007FFE73866DBE6D8E6DBE73867FFE7FFE73EE6DCE71EE7DEE73C67FFE0000
+0E92:00007FFE73866DBE6D8E6DBE73867FFE7FFE73866DF671867DBE73867FFE0000
+0E93:00007FFE73866DBE6D8E6DBE73867FFE7FFE738E6DF671C67DF6738E7FFE0000
+0E94:00000000003C42424242425222000000
+0E95:0000000000245A424242424222000000
+0E96:00000000005C22222222222232020202
+0E97:00000000008C52525252525222000000
+0E98:00007FFE73866DBE6D8E6DBE73867FFE7FFE73CE6DB671CE7DB673CE7FFE0000
+0E99:0000000000225222222222225C000000
+0E9A:0000000000225222424242423C000000
+0E9B:0002020202225222424242423C000000
+0E9C:0000000001668682828292926C000000
+0E9D:0002020202628282828292926C000000
+0E9E:000000000042A242828292926C000000
+0E9F:000202020242A242828292926C000000
+0EA0:00007FFE73866DBE6D8E6DBE73867FFE7FFE61CE6DB661B66DB66DCE7FFE0000
+0EA1:0000000000222222222222225C000000
+0EA2:0002020202324242224242423C000000
+0EA3:00000000003C42403C0262423C000000
+0EA4:00007FFE73866DBE6D8E6DBE73867FFE7FFE61B66DB661866DF66DF67FFE0000
+0EA5:00000000003C42020202324A24000000
+0EA6:00007FFE73866DBE6D8E6DBE73867FFE7FFE61CE6DBE618E6DB66DCE7FFE0000
+0EA7:00000000003C4202020242423C000000
+0EA8:00007FFE73866DBE6D8E6DBE73867FFE7FFE61CE6DB661CE6DB66DCE7FFE0000
+0EA9:00007FFE73866DBE6D8E6DBE73867FFE7FFE61CE6DB661C66DF66DCE7FFE0000
+0EAA:00000000003A44467A02324A44000000
+0EAB:00000000009649494949494931000000
+0EAC:00007FFE73866DBE6D8E6DBE73867FFE7FFE61C66DBE61BE6DBE6DC67FFE0000
+0EAD:00000000003C4242463A024438000000
+0EAE:0000000000324C403C0262423C000000
+0EAF:000000000022261A0204040808101020
+0EB0:00000000000000343800343800000000
+0EB1:61627C00000000000000000000000000
+0EB2:00000000001824140404040404000000
+0EB3:0000C0C0000C120A0202020202000000
+0EB4:7C442800000000000000000000000000
+0EB5:7C442E00000000000000000000000000
+0EB6:7C542800000000000000000000000000
+0EB7:7C542E00000000000000000000000000
+0EB8:00000000000000000000000000001808
+0EB9:00000000000000000000000000001A0C
+0EBA:00007FFE73866DBE6D8E6DBE73867FFE7FFE63866DB663866DB663B67FFE0000
+0EBB:3E616000000000000000000000000000
+0EBC:0000000000000000000000000000324C
+0EBD:00000000003A24180404040464444438
+0EBE:00007FFE73866DBE6D8E6DBE73867FFE7FFE63866DBE638E6DBE63867FFE0000
+0EBF:00007FFE73866DBE6D8E6DBE73867FFE7FFE63866DBE638E6DBE63BE7FFE0000
+0EC0:00000000000808080808080C0C000000
+0EC1:00000000002424242424243636000000
+0EC2:00304C22180404040404040606000000
+0EC3:00384454340404040404040606000000
+0EC4:00804C34040404040404040606000000
+0EC5:00007FFE73866DBE6D8E6DBE73867FFE7FFE71866FBE6F866FF671867FFE0000
+0EC6:00000000006C52522202020202020408
+0EC7:00007FFE73866DBE6D8E6DBE73867FFE7FFE71866FF66FEE6FDE71DE7FFE0000
+0EC8:10101000000000000000000000000000
+0EC9:32143800000000000000000000000000
+0ECA:28556600000000000000000000000000
+0ECB:081C0800000000000000000000000000
+0ECC:021C1800000000000000000000000000
+0ECD:00000814080000000000000000000000
+0ECE:00007FFE73866DBE6D8E6DBE73867FFE7FFE71866FBE6F8E6FBE71867FFE0000
+0ECF:00007FFE73866DBE6D8E6DBE73867FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+0ED0:0000000000003C42424242423C000000
+0ED1:0000000000003C42425A3A023C000000
+0ED2:0000000000003844405C5C4438000000
+0ED3:00000008140A4422222222225C000000
+0ED4:0000000002023C40404C4C483E000000
+0ED5:00000000021A3C40404C4C483E000000
+0ED6:00000008140A2442424252522C000000
+0ED7:0000000000005C222222222262020202
+0ED8:0000000000002C52524242260A142C30
+0ED9:000000000000324A4A4A4A4A24000000
+0EDA:00007FFE73866DBE6D8E6DBE73867FFE7FFE63866DB66D866DB663B67FFE0000
+0EDB:00007FFE73866DBE6D8E6DBE73867FFE7FFE638E6DB66D8E6DB6638E7FFE0000
+0EDC:00000000B9D555555555555526000000
+0EDD:0000000089D555555555555D2E000000
+0EDE:0000000000B84444546D5E44C4000000
+0EDF:000000000064848474AD9E8478000000
+0EE0:00007FFE73866DBE6D8E6DBE73867FFE7FFE61CE6FB663B66FB661CE7FFE0000
+0EE1:00007FFE73866DBE6D8E6DBE73867FFE7FFE61EE6FCE63EE6FEE61C67FFE0000
+0EE2:00007FFE73866DBE6D8E6DBE73867FFE7FFE61866FF663866FBE61867FFE0000
+0EE3:00007FFE73866DBE6D8E6DBE73867FFE7FFE618E6FF663C66FF6618E7FFE0000
+0EE4:00007FFE73866DBE6D8E6DBE73867FFE7FFE61B66FB663866FF661F67FFE0000
+0EE5:00007FFE73866DBE6D8E6DBE73867FFE7FFE61866FBE63866FF661867FFE0000
+0EE6:00007FFE73866DBE6D8E6DBE73867FFE7FFE61CE6FBE638E6FB661CE7FFE0000
+0EE7:00007FFE73866DBE6D8E6DBE73867FFE7FFE61866FF663EE6FDE61DE7FFE0000
+0EE8:00007FFE73866DBE6D8E6DBE73867FFE7FFE61CE6FB663CE6FB661CE7FFE0000
+0EE9:00007FFE73866DBE6D8E6DBE73867FFE7FFE61CE6FB663C66FF661CE7FFE0000
+0EEA:00007FFE73866DBE6D8E6DBE73867FFE7FFE61866FB663866FB661B67FFE0000
+0EEB:00007FFE73866DBE6D8E6DBE73867FFE7FFE618E6FB6638E6FB6618E7FFE0000
+0EEC:00007FFE73866DBE6D8E6DBE73867FFE7FFE61C66FBE63BE6FBE61C67FFE0000
+0EED:00007FFE73866DBE6D8E6DBE73867FFE7FFE618E6FB663B66FB6618E7FFE0000
+0EEE:00007FFE73866DBE6D8E6DBE73867FFE7FFE61866FBE638E6FBE61867FFE0000
+0EEF:00007FFE73866DBE6D8E6DBE73867FFE7FFE61866FBE638E6FBE61BE7FFE0000
+0EF0:00007FFE73866DBE6D8E6DBE73867FFE7FFE61CE6FB663B66FB66FCE7FFE0000
+0EF1:00007FFE73866DBE6D8E6DBE73867FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000
+0EF2:00007FFE73866DBE6D8E6DBE73867FFE7FFE61866FF663866FBE6F867FFE0000
+0EF3:00007FFE73866DBE6D8E6DBE73867FFE7FFE618E6FF663C66FF66F8E7FFE0000
+0EF4:00007FFE73866DBE6D8E6DBE73867FFE7FFE61B66FB663866FF66FF67FFE0000
+0EF5:00007FFE73866DBE6D8E6DBE73867FFE7FFE61866FBE63866FF66F867FFE0000
+0EF6:00007FFE73866DBE6D8E6DBE73867FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+0EF7:00007FFE73866DBE6D8E6DBE73867FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+0EF8:00007FFE73866DBE6D8E6DBE73867FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+0EF9:00007FFE73866DBE6D8E6DBE73867FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+0EFA:00007FFE73866DBE6D8E6DBE73867FFE7FFE61866FB663866FB66FB67FFE0000
+0EFB:00007FFE73866DBE6D8E6DBE73867FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+0EFC:00007FFE73866DBE6D8E6DBE73867FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+0EFD:00007FFE73866DBE6D8E6DBE73867FFE7FFE618E6FB663B66FB66F8E7FFE0000
+0EFE:00007FFE73866DBE6D8E6DBE73867FFE7FFE61866FBE638E6FBE6F867FFE0000
+0EFF:00007FFE73866DBE6D8E6DBE73867FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+0F00:180067001C005D004900550053004B0039000100000000000000000000000000
+0F01:0000000000005C004800540052004A0039000100000000000000000000000000
+0F02:1000100018004430BA487C487830840088309C48224802300600610012000C00
+0F03:1000100018004430BA487C487830840088789C00223002480648613012000C00
+0F04:00000000000000000600C10031004E0031000E00000000000000000000000000
+0F05:00000000000000000C00020062001C0062001C00000000000000000000000000
+0F06:00000000000000000600C10031004E0031000E0000000C000400040004000400
+0F07:000000000000000008001500C400390000000000000000000000000000000000
+0F08:0000000032004C0000006C001000380010001000100010001000100000000000
+0F09:0000000000001E002100010002000E0011000E00110001000000000000000000
+0F0A:00000F0030004E005100410042004E0051004E005100400031000F0000000000
+0F0B:0000000000001800180000000000000000000000000000000000000000000000
+0F0C:00000018180000000000000000000000
+0F0D:0000000000001800180008000800080008000800080008000800080000000000
+0F0E:0000000000003600360012001200120012001200120012001200120000000000
+0F0F:0000000000001800180000001800080008000800080008000800080000000000
+0F10:0000000000001800000018000000180008000800080008000800080000000000
+0F11:0000000000006600000018000000180008000800080008000800080000000000
+0F12:0800140049003E000000770000001A002C000800080008000800080008000000
+0F13:0000000000000000180000001800A500A5001800000018000000000000000000
+0F14:000000000000180024002400180000003C000000180024002400180000000000
+0F15:0000FF00E7008100A5008100FF00B1008D00E300130009000500030003000100
+0F16:00027F827F8260027FFE7FFE01827F827F8200027FFE00827FFE40027FFE0002
+0F17:001100890449224A1252129413FC57145814582457C4500837F0180010000000
+0F18:0000000000000000000200010019002500260018019002600240018009000600
+0F19:0000000000000000000000000000000000001800080008000800080008000000
+0F1A:0000000000000000000000001800240024001800000000000000000000000000
+0F1B:0000000000000000000000002200550055002200000000000000000000000000
+0F1C:0000000000000000080014001400080022005500550022000000000000000000
+0F1D:0000000000000000000000000000140008001400000000000000000000000000
+0F1E:0000000000000000000000000000550022005500000000000000000000000000
+0F1F:0000000000000000000000000000250052002500000000000000000000000000
+0F20:0000000000000E0011002100210022001C000000000000000000000000000000
+0F21:00000000000006000B0011000100020004000800000000000000000000000000
+0F22:0000000000001E002100010002000E0011000100000000000000000000000000
+0F23:0000000000001E00210002000E00010002001E00210000000000000000000000
+0F24:000000000000000012002C00400041007E000000000000000000000000000000
+0F25:0000000000002200440044003C00040002000100000000000000000000000000
+0F26:0000000000004000440028002700110011000E00000000000000000000000000
+0F27:0000000000000100010031004A0012003C000000000000000000000000000000
+0F28:0000000000000800100020007000080004000200010001000000000000000000
+0F29:0000000000001C002200240049004E0040004000000000000000000000000000
+0F2A:0000000000000C00160022000F00740008001000000000000000000000000000
+0F2B:0000000000003C0042000F0074001C0022000200000000000000000000000000
+0F2C:0000000000003C00420004001F00720004003C00420000000000000000000000
+0F2D:000000000000000012002C00460049007E002000400000000000000000000000
+0F2E:00000000000022004E0055003C00440002000100000000000000000000000000
+0F2F:000000000000400045002A002700190011002E00400000000000000000000000
+0F30:0000000000000100010031004F0072003C000000000000000000000000000000
+0F31:00000000000008001000200072000D0034004200010001000000000000000000
+0F32:0000000003001D002A00340069004E0040004000000000000000000000000000
+0F33:0000000000001D00220046004A00540038004000000000000000000000000000
+0F34:000000000000000018001800000010001C00040010001C000400000000000000
+0F35:000000000000000000000000000000000000000000000000080055002A001C00
+0F36:0000000000000000180018000000660066000000180018000000000000000000
+0F37:0000000000000000000000000000000000000000000000001800240024001800
+0F38:33004A0052005C00000000000000000000000000000000000000000000000000
+0F39:0700040002000000000000000000000000000000000000000000000000000000
+0F3A:000000000000008009401490C428389001400080000000000000000000000000
+0F3B:0000000000000200052012502846123805000200000000000000000000000000
+0F3C:0000000002000200040008000800180020002000200020002000200040000000
+0F3D:00000000200020001000080008000C0002000200020002000200020001000000
+0F3E:00000000000000000000000000000C0002000200020002000200020001000000
+0F3F:0000000000000000000000000000300040004000400040004000400080000000
+0F40:0000000000003F00150065000500010001000100000000000000000000000000
+0F41:0000000000003F0049004D004B00410041000000000000000000000000000000
+0F42:0000000000003F00490069005900090001000100000000000000000000000000
+0F43:0000000000003F0049006900590009001F0020004E0031001100010000000000
+0F44:0000000000001E00200040007800440002000100000000000000000000000000
+0F45:0000000000003E00080008004E00310011000E00000000000000000000000000
+0F46:0000000000003E00080008003E00490049003600000000000000000000000000
+0F47:0000000000001E0020003C0040007C0042000100000000000000000000000000
+0F48:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE6DCE6DB661CE7DB67DCE7FFE0000
+0F49:000000000000380044004E001100110001000100020000000000000000000000
+0F4A:0000000000007F0001003D004300410040004000000000000000000000000000
+0F4B:0000000000003F0021003A002C0022002F003000200000000000000000000000
+0F4C:0000000000003C00020001001F00210040004000400000000000000000000000
+0F4D:0000000000003C00020001001F0020005E0060004E0031001100010000000000
+0F4E:0000000000003F0008001C00120032002C002000200000000000000000000000
+0F4F:0000000000007F0040005E006100410001000100000000000000000000000000
+0F50:0000000000003F00210017000D0011003D000300010000000000000000000000
+0F51:0000000000001E00200040007C00420001000100010000000000000000000000
+0F52:0000000000001E00200040007C0042001F0020004E0031001100010000000000
+0F53:0000000000003F0004000E00120013000D000100010000000000000000000000
+0F54:0000000000003300210041007D00430001000100000000000000000000000000
+0F55:0000000000003300230045007D00430001000100000000000000000000000000
+0F56:0000000000001F00210041007D00430001000100000000000000000000000000
+0F57:0000000000001F00210041007D0043001F0020004E0031001100010000000000
+0F58:0000000000007D00090031004D004B0031000100000000000000000000000000
+0F59:0000010001003E00080008004E00310011000E00000000000000000000000000
+0F5A:0000010001003E00080008003E00490049003600000000000000000000000000
+0F5B:0000010001001E002000380040007C0042000100000000000000000000000000
+0F5C:0000010001001E002000380040007C0042001F0020004E003100110001000000
+0F5D:000000000000310049004F00090011001D001300010000000000000000000000
+0F5E:0000000000001C0022004C00520053004D002100010000000000000000000000
+0F5F:0000000000003F0001001F0001003D0003000100000000000000000000000000
+0F60:00000000000038004400440048001C0002000100000000000000000000000000
+0F61:0000000000006B00490049004900350003000100000000000000000000000000
+0F62:0000000000003E0008001C000200010001000000000000000000000000000000
+0F63:0000000000003900450049000D00030001000000000000000000000000000000
+0F64:0000000000000F00110011004F00310011000100010000000000000000000000
+0F65:0000000000003C00220022003D00230022002000200000000000000000000000
+0F66:0000000000007B00110029006500030001000000000000000000000000000000
+0F67:0000000000001E0020004E003100110001000100000000000000000000000000
+0F68:0000000000005D004900550053004B0031000100000000000000000000000000
+0F69:0000000000003F0015006500050001003900250024003D002200240020000000
+0F6A:0000000000007C00080030004C00020001000100000000000000000000000000
+0F6B:0000000000007E00540053005000400040004000400040004000400040000000
+0F6C:0000000000001F00080006001900200040004000000000000000000000000000
+0F6D:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE738E6FB663B66DB6738E7FFE0000
+0F6E:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE73866FBE638E6DBE73867FFE0000
+0F6F:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE73866FBE638E6DBE73BE7FFE0000
+0F70:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61CE7DB67BB677B677CE7FFE0000
+0F71:0000000000000000000000000000000000000000180028000400000000000000
+0F72:7000480004000000000000000000000000000000000000000000000000000000
+0F73:7000480004000000000000000000000000003F004200420004001C0022000200
+0F74:0000000000000000000000000000000000000000000000000000400024001C00
+0F75:000000000000000000000000000000003E004200420004000C00420022001C00
+0F76:70004800040000000000000000000000000072000A0006000200000000000000
+0F77:700048000400000000000000000002007A0006003F00420004001C0022000000
+0F78:700048000400000000000000000000000000000000000000220052005E000200
+0F79:700048000400000000000000000032005E0002003F00420004001C0022000000
+0F7A:E000180004000000000000000000000000000000000000000000000000000000
+0F7B:CC00220000000000000000000000000000000000000000000000000000000000
+0F7C:CF00280010000000000000000000000000000000000000000000000000000000
+0F7D:4500EE0010000000000000000000000000000000000000000000000000000000
+0F7E:1000280010000000000000000000000000000000000000000000000000000000
+0F7F:0000000000001800240024001800000018002400240018000000000000000000
+0F80:1C00240040000000000000000000000000000000000000000000000000000000
+0F81:1C00240040000000000000000000000000003F004200420004001C0022000200
+0F82:080008000C0022005D003F000000000000000000000000000000000000000000
+0F83:0800140049003E00000000000000000000000000000000000000000000000000
+0F84:0000000000000000000000000000000000000400060002000300010001000100
+0F85:0000000000000000000038004400440008001C00120012000A00020002000100
+0F86:1000100010002400180000000000000000000000000000000000000000000000
+0F87:1000100010001000100010000000000000000000000000000000000000000000
+0F88:00003F800A0004000A003F800000000000000000000000000000000000000000
+0F89:0000360049000000000000000000000000000000000000000000000000000000
+0F8A:00000000000000000000000000000000EE00AA00AA00AA00BA00000000000000
+0F8B:00000000000000000000000000000000010002003A004A004A002E0000000000
+0F8C:0000490036000000000000000000000000000000000000000000000000000000
+0F8D:0000000000000000000000000000000000007F00220014000800140022007F00
+0F8E:0000000000000000000000000000000000000000000000000000360049000000
+0F8F:0000000000000000000000000000000000000000000000000000490036000000
+0F90:00000000000000000000000000003F0015002500010000000000000000000000
+0F91:000000000000000000000000000000003F0049004D004B004100000000000000
+0F92:00000000000000000000000000003F0049007900090000000000000000000000
+0F93:00000000000000000000000000003F004900790001001E0020004E0031001100
+0F94:000000000000000000000000000000001E0020007C0042000100000000000000
+0F95:000000000000000000000000000000003E0008004E0031000E00000000000000
+0F96:000000000000000000000000000000003E0008003E0049003600000000000000
+0F97:000000000000000000000000000000001E002000380040007E00410000000000
+0F98:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE73CE6DB671CE7DB673CE7FFE0000
+0F99:00000000000000000000000000000000380044000E0011000100020000000000
+0F9A:000000000000000000000000000000007F0001003D0043004100400000000000
+0F9B:000000000000000000000000000000007E004400780044007E00400000000000
+0F9C:000000000000000000000000000000003C0002001F0021004000400000000000
+0F9D:000000000000000000000000000000003C0002001F0020007E00510001000000
+0F9E:0000000000000000000000001E0008001C0032004C0040000000000000000000
+0F9F:000000000000000000000000000000007F0040005E0061004100010000000000
+0FA0:000000000000000000000000000000003F0011000F0011003F00010000000000
+0FA1:000000000000000000000000000000001E0020007C0042000100010000000000
+0FA2:000000000000000000000000000000001E0020007C0042001F0020004E003100
+0FA3:0000000000000000000000003C0008001C002600190001000000000000000000
+0FA4:0000000000000000000000000000330021007D00030001000000000000000000
+0FA5:0000000000000000000000000000270049007D00030001000000000000000000
+0FA6:00000000000000000000000000001F0021007D00030001000000000000000000
+0FA7:00000000000000000000000000001F0021007D0003001F0020004E0031001100
+0FA8:0000000000000000000000000000790031004D00330001000000000000000000
+0FA9:000000000000000000003C000A0009004C00320012000C000000000000000000
+0FAA:000000000000000000000000000000003E0009003E0049004900360000000000
+0FAB:000000000000000000001C002200390041007C00420000000000000000000000
+0FAC:000000000000000000001C002200390041007C0042001E0020004E0031001100
+0FAD:0000000000000000000000000000000000000000000000000100030005000300
+0FAE:000000000000000000000000000000001C0022004C0053004D00210001000000
+0FAF:000000000000000000000000000000003F0001001F0001003F00010000000000
+0FB0:000000000000000000000000000000003800440048001C000200010000000000
+0FB1:0000000000000000000000000000000001000100010012001C00090006000000
+0FB2:0000000000000000000000000000000001000100010039004500030001000000
+0FB3:000000000000000000000000000000003900450049001D000300010000000000
+0FB4:00000000000000000000000000000000070009002F0011000900010001000000
+0FB5:00000000000000000000000000000000380024003D0022002400200020000000
+0FB6:000000000000000000000000000000007B002900450063000100000000000000
+0FB7:000000000000000000000000000000001E0020004E0031001100010000000000
+0FB8:000000000000000000000000000000005D004900550053003100010000000000
+0FB9:00000000000000000000000000003F00150065000500390024003D0022002000
+0FBA:00000000000000000000000000000000310049004F0009001D00030001000000
+0FBB:000000000000000000000000000000006B004900490035000300010000000000
+0FBC:000000000000000000000000000000003E0008001C0002000100010000000000
+0FBD:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE638E6DB663B66DB6638E7FFE0000
+0FBE:0000000000000000000041002200140008001400220041000000000000000000
+0FBF:0000000000000000000049002200140049001400220049000000000000000000
+0FC0:000000000000000000001C0022004100410022001C0000000000000000000000
+0FC1:00000000000000000000000000001C00220022001C0000000000000000000000
+0FC2:00000000000000001C0002001A00240024005800400038000000000000000000
+0FC3:00000000000000001C0022004900550049002A001C0000000000000000000000
+0FC4:0000000000006B00140008001C002200220022003E0041007F00000000000000
+0FC5:0D600280010003800C601930145022882108155011100D600380010002800D60
+0FC6:00000000000000000000000000000000000045442AA82AA812900FE015502548
+0FC7:0D600280010003808C6299325454A28AA10A555491128D620380010002800D60
+0FC8:00000D60028001003FF824481290129009200920044004400280028001000000
+0FC9:0000000003800440092014501390282827C8200820081010183007C000000000
+0FCA:000007C008203018200840049E06A126C106C90AC0F2400420083018082007C0
+0FCB:000007C0082030183C0C424C810A911281E281028202424422083218092007C0
+0FCC:000007C00820303821287C2482428182892283028482487C29083818082007C0
+0FCD:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE718E6FB66FB66FB6718E7FFE0000
+0FCE:0000000000000000000000000000243018481848243000000000000000000000
+0FCF:0000000002400180018002400000000000002448183018302448000000000000
+0FD0:000000001F00208040440F381080008001000700088000000000000000000000
+0FD1:00003C004200020004001C0022001C0022001800240004000800040002000000
+0FD2:000000000000000007C00380010000000000000007C003800100000000000000
+0FD3:00000000000000000000000000300048604418340604010800F0000000000000
+0FD4:00000000000000000000000000C00120011000D00810042003C0000000000000
+0FD5:0000000041FC410041004100410041007FFC010401040104010401047F040000
+0FD6:000000007F04010401040104010401047FFC4100410041004100410041FC0000
+0FD7:0000000041FC410041004920410041007FFC010401040924010401047F040000
+0FD8:000000007F04010401040924010401047FFC4100410049204100410041FC0000
+0FD9:0000000000004000600040000000100218061002000002100738000000000000
+0FDA:0000000000000002000600020000400860184008000008401CE0000000000000
+0FDB:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE638E6DB66D8E6DB6638E7FFE0000
+0FDC:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE63C66DBE6DBE6DBE63C67FFE0000
+0FDD:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE638E6DB66DB66DB6638E7FFE0000
+0FDE:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE63866DBE6D8E6DBE63867FFE0000
+0FDF:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE63866DBE6D8E6DBE63BE7FFE0000
+0FE0:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61CE6FB663B66FB661CE7FFE0000
+0FE1:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61EE6FCE63EE6FEE61C67FFE0000
+0FE2:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61866FF663866FBE61867FFE0000
+0FE3:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE618E6FF663C66FF6618E7FFE0000
+0FE4:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61B66FB663866FF661F67FFE0000
+0FE5:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61866FBE63866FF661867FFE0000
+0FE6:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61CE6FBE638E6FB661CE7FFE0000
+0FE7:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61866FF663EE6FDE61DE7FFE0000
+0FE8:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61CE6FB663CE6FB661CE7FFE0000
+0FE9:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61CE6FB663C66FF661CE7FFE0000
+0FEA:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61866FB663866FB661B67FFE0000
+0FEB:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE618E6FB6638E6FB6618E7FFE0000
+0FEC:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61C66FBE63BE6FBE61C67FFE0000
+0FED:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE618E6FB663B66FB6618E7FFE0000
+0FEE:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61866FBE638E6FBE61867FFE0000
+0FEF:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61866FBE638E6FBE61BE7FFE0000
+0FF0:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61CE6FB663B66FB66FCE7FFE0000
+0FF1:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000
+0FF2:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61866FF663866FBE6F867FFE0000
+0FF3:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE618E6FF663C66FF66F8E7FFE0000
+0FF4:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61B66FB663866FF66FF67FFE0000
+0FF5:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61866FBE63866FF66F867FFE0000
+0FF6:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+0FF7:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+0FF8:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+0FF9:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+0FFA:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61866FB663866FB66FB67FFE0000
+0FFB:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+0FFC:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+0FFD:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE618E6FB663B66FB66F8E7FFE0000
+0FFE:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61866FBE638E6FBE6F867FFE0000
+0FFF:00007FFE73866DBE6D8E6DBE73BE7FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+1000:000000000000000000003DE04210810881088108421024200000000000000000
+1001:000000000000000000000F00108000403E40214010800F000000000000000000
+1002:000000000000000000000F001080204020402040108009000000000000000000
+1003:000000000000000060009210210840844084408421081EF00000000000000000
+1004:000000000000000000000F00108020002000200010800F000000000000000000
+1005:000000000000000000000F00108028402840284010800F000000000000000000
+1006:0000000000000000000031E04A100408E40894084A1031200000000000000000
+1007:000000000000000000000F00108021402080206010000F000000000000000000
+1008:38404440A240A240A24044403840104010401040084007800000000000000000
+1009:384044400240024002404440784040404040404040407FC00000000000000000
+100A:38E04410020802080208451078E040004000400840087FF80000000000000000
+100B:380044008000800080006400580042003E000200020003800000000000000000
+100C:3844808080463A020232427E00000000
+100D:380044000200020002006400580042003E000200020003800000000000000000
+100E:0000000000000000380044804840102010201020084007800000000000000000
+100F:000000000000000000003760489085088508850848900F800000000000000000
+1010:0000000000000000000031804A40842084208420484030800000000000000000
+1011:0000000000000000000031804A408420842084204A4031800000000000000000
+1012:00000000000000001E002100208010800300008020801F000000000000000000
+1013:0000000000000000070008801040104010401740088007000000000000000000
+1014:000000000000000007000880080007000080204050403F801000100010001000
+1015:000000000000000000000000108020402040204010800F000000000000000000
+1016:000000000000000003000A801240124012401140088007000000000000000000
+1017:0000000000000000000008801740104010401040088007000000000000000000
+1018:0000000000000000000031804A40042004200420484031800000000000000000
+1019:0000000000000000000008801040104010401740088007000000000000000000
+101A:00000000000000000000018048408420842084204A4031800000000000000000
+101B:00000000000000001E0021005100490031000100010001C00000000000000000
+101C:0000000000000000000031804840842084208420424031800000000000000000
+101D:000000000000000000000E00110020802080208011000E000000000000000000
+101E:00000000000000000000318048400420042004204A4031800000000000000000
+101F:0000000000000000000001804A40842084208420484031800000000000000000
+1020:3844808080661A427C40427E00000000
+1021:0000000000000000700089C0862044301850049084A078C00000000000000000
+1022:000000000000000000001DC02220421042104210222064400000000000000000
+1023:00000000000000001DC022202220104000001DC0222022401078000000000000
+1024:000000000000000038E045108210441000103E1040103FE00000000000000000
+1025:380044000200020002004400780040004380444040407FC00000000000000000
+1026:3800440054006C0038004400020044007800438040407FC00000000000000000
+1027:0000000000000000000007800840178010001780084007800000000000000000
+1028:07800840132014A010A0112010C0100010201020084007800000000000000000
+1029:0000FFE080008E38910480828082808291448E388010FFF00000000000000000
+102A:00060FE80808080608006B368889F88998C96B3208100FF00000000000000000
+102B:0038004400420002000200020002000200020002000200020000000000000000
+102C:0000000000000000000000000006000900010001000600000000000000000000
+102D:0180024002400180000000000000000000000000000000000000000000000000
+102E:01C0022002A0022001C000000000000000000000000000000000000000000000
+102F:00000000000000000000000000000000000000000000000000800080008000E0
+1030:0000000000000000000000000000000000000000000000000140014001400170
+1031:0000000000000000000000001800200040005800680030000000000000000000
+1032:0000010000800040002000000000000000000000000000000000000000000000
+1033:000001C002A0036002A001C00000000000000000000000000000000000000000
+1034:0000008001000200040000000000000000000000000000000000000000000000
+1035:01C0022003800240018000000000000000000000000000000000000000000000
+1036:0000010002800100000000000000000000000000000000000000000000000000
+1037:0000000000000000000000000000000000000000000000000000002000500020
+1038:0000000000000000000000020005000200000002000500020000000000000000
+1039:0000000000000000000000000000000000000000000000000000008001C00080
+103A:0180024002000180000000000000000000000000000000000000000000000000
+103B:00000000000000000000000000020002000200020002000200120012000A0004
+103C:7FFE40024002400040004000400040004000400040004002400240027FFE0000
+103D:00000000000000000000000000000000000000000000000000800140022001C0
+103E:00000000000000000000000000000000000000000000000000000040004001C0
+103F:00000000000000000000318C48420421042104214A52318C0000000000000000
+1040:000000000000000000000D80104020202020202010400D800000000000000000
+1041:000000000000000000000F00108000400040004010800F000000000000000000
+1042:00000000010101010111110E00000000
+1043:000000000E1101221C10080402000000
+1044:0000000000000000070008800800044003800080010002000400000000000000
+1045:0000000000000000038005400540024000400040044003800000000000000000
+1046:00000000000000000380044004000480050004C0044003800000000000000000
+1047:0000000000000000070008800080010002000400048003000000000000000000
+1048:00000000000000000700088014401240124012400A8006000000000000000000
+1049:00000000000000000380044004C0050004800400044003800000000000000000
+104A:00000000080808080808080800000000
+104B:00000000242424242424242400000000
+104C:18201838040438427E02427E00000000
+104D:003000480040002003900550055002500050005000500350041003E000000000
+104E:0000006000800084006A066408800884098A0664000000000000000000000000
+104F:003000480040002001903A504450B8508050B850445038500000000000000000
+1050:0000000000000000000007000880104012401040088005000000000000000000
+1051:0000000000000000000005000880104012401040088007000000000000000000
+1052:000000000000000000C005000880104010401040088007000000000000000000
+1053:000000000000000018C005000880104010401040088007000000000000000000
+1054:00000000000E112E2020110E00000000
+1055:000000000000000000000E0011002E002000204024801B000000000000000000
+1056:00000000000000000003000400040002000100010011000E0000000000000000
+1057:00000000000000000003000400040002000100010015000A0000000000000000
+1058:00000000000000000000000000000000000000000000038004400780042003C0
+1059:0000000000000000000000000000000000000000000003800440078004900360
+105A:0000000000000000000003C0042004000400042003C001800240024000400030
+105B:0000000000000000000003C404A4045C0404040403C400840084008400480030
+105C:000000000000000003C0042009900A500A500990042003C00000000000000000
+105D:0000000000000000000002400420042007E0042003D0001001900290022001C0
+105E:000000000000000000000000000000000000000000000000008003C004A00300
+105F:00000000000000000000000000000000000000000000008000800180022001C0
+1060:00000000000000000000000000000000000000000000000000800100020003C0
+1061:00000380044008200E20092004A003A000A000A000A007A00000000000000000
+1062:000000000000000000000000000E000200020002000200020000000000000000
+1063:00000000000000000000000C001200020012001C001000100010001000100010
+1064:000000000000000000000000000C000400040004000400060000000000000000
+1065:0000000000000000000003C0042000200020042003C000000000000000000000
+1066:000000000000000000000240042004200420042003D0001000100010001000F0
+1067:000000000000000000000002000200020006000A000A00040000000000000000
+1068:000000000004000A0004000000020002000200020002000E0000000000000000
+1069:00000000000000000000000C0002000200040008000800060000000000000000
+106A:0000000000000000000000000000000200020002000A00040000000000000000
+106B:00000000000000000000000000000004000A0002000200020000000000000000
+106C:0000000000000000000000000000000800080008000A00040000000000000000
+106D:00000000000000000000000600080008000400020002000C0000000000000000
+106E:000000000000000000001DB02248424442444244424424980000000000000000
+106F:000000000000000000002270418841044104410422441C380008000800080038
+1070:000000000000000000006440222042104210421022201DD00010001000100070
+1071:0220055002200000000000000000000000000000000000000000000000000000
+1072:01C002200200022001C000000000000000000000000000000000000000000000
+1073:0080014002200410000000000000000000000000000000000000000000000000
+1074:014002200220022001C000000000000000000000000000000000000000000000
+1075:0000000000000000000007800840102010201020084018800000000000000000
+1076:00000000000000000000138014400820002007A0084007800000000000000000
+1077:000000000000000000000780084010A010A010A008A018400000000000000000
+1078:0000000000000000000038C04520821082108210412030C00000000000000000
+1079:0000000000000000000038C045208210E2109210492030C00000000000000000
+107A:0000000000000000000038C04420821082108210432032C00200020002000380
+107B:0000000000000000000031C04A20841084708490492030C00000000000000000
+107C:0000000000000000000038E04510020002003FE0451038E00000000000000000
+107D:0000000000000000000060E021104200420043E0451038E00000000000000000
+107E:0000000000000000000060E021104200420043E0451038E000400040004001C0
+107F:00000000000000000000000008801440144014400C8007000000000000000000
+1080:0000000000000000000038604410020802083E08451038E00000000000000000
+1081:00000000000000000000070008801040104014400C8005000400040004001C00
+1082:0000000000000000000000000000000000000000000000000060008000900060
+1083:00000000000000000000001C0004000400040004000400040004000400040007
+1084:00000000007088601060887000000000
+1085:01C002200100022001C000000000000000000000000000000000000000000000
+1086:004000A000600020004000000000000000000000000000000000000000000000
+1087:000000000000000000000000000000000000000000000004000A000600020004
+1088:00000000000000000000000000000004000A000400000004000A000600020004
+1089:000000000000000000000000000000000000000000000004000A000400000000
+108A:00000000000000000000000000080015000E000000080015000E000000000000
+108B:000000000000000000000000000000000004000A000400000000000000000000
+108C:0000000000000000000000000000000000020055002200000000000000000000
+108D:0000000000000000000000000000000000000000000000000000000000F00000
+108E:00000000000000000000038004400BA008200820044003800000000000000000
+108F:00000000000000000000000000000004000A000400000004000A000C00080004
+1090:0000000000000000000003C00420042004200420042003C00000000000000000
+1091:0000000000000000000003000500010001000100014001800000000000000000
+1092:000000000000000000000B800C40004000800100020002000000000000000000
+1093:0000000000000000008000800100010002000380044004400000000000000000
+1094:000000000000000000800080018001800280028004A004C00000000000000000
+1095:0000000000000000000000400040004007E00840084007800000000000000000
+1096:0000000000000000000007800840084007E00040004000400000000000000000
+1097:0000000000000000000007C00040008001000200040007E00000000000000000
+1098:0000000000000000000004200420024003C00420042003C00000000000000000
+1099:0000000000000000000003C00420042003C00240042004200000000000000000
+109A:00000000000000000004000A0004000000000000000000000000000000000000
+109B:00000000000000000004000A0006000200040000000000000000000000000000
+109C:000000000000000000000000000E001500080000000E00150008000000000000
+109D:000001C002200220002000200020002000200000000000000000000000000000
+109E:008001400080000001C000400040004000400040004000400070000000000000
+109F:0030004800400020031004880848084804480048004800300000000000000000
+10A0:00000080FE22408080808082463A0000
+10A1:000000006888888898680808080E0200
+10A2:00000000F888880808080808080E0200
+10A3:0000000080FE12103844828244380000
+10A4:000000007C4444040404040404040000
+10A5:00000000F88888080E0A080808080000
+10A6:0000000080E02020202C322222221C00
+10A7:00000000305090909E92909050300000
+10A8:000000407C0404040404040404040000
+10A9:000000004040586444444C3404040000
+10AA:0000000000E0A020202C322222221C00
+10AB:00000080F80808087E8A8A8888700000
+10AC:000000047C4040407C44444444440000
+10AD:00000000708888888888888A8A740000
+10AE:00000080E222222222222222221C0000
+10AF:000000407A122222261A020202020000
+10B0:000000001010141A1292909090600000
+10B1:00000000404040404844444444380000
+10B2:000000007C4242427C404040407E0200
+10B3:00000000708888888888888C8A720000
+10B4:000000007C9292927C10101010100000
+10B5:00000000101010507C14101010100000
+10B6:000000003C4242424242424242420000
+10B7:000000002444444444444C3404040000
+10B8:00000000344444444C34044444380000
+10B9:00000000404040407C44444444440000
+10BA:000000001C22424040404042221C0408
+10BB:00000000080808083E4A4A4848300000
+10BC:000000007C4242427C40407844484040
+10BD:0000000000003844442010080442423C
+10BE:0000000044444444447C4040407C0400
+10BF:00000080FE2222141408141422224080
+10C0:00000000F090901010101212120C0000
+10C1:00000000404078444640404040400000
+10C2:00000040784402020202024244380000
+10C3:00000000344444444C34040404040000
+10C4:00000000828282824428101010100000
+10C5:000000001C12121C107C949690600000
+10C6:00007FFE7BCE73B67BB67BB671CE7FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000
+10C7:0000000000001C22220408102042423C
+10C8:00007FFE7BCE73B67BB67BB671CE7FFE7FFE71CE6FB66FCE6FB671CE7FFE0000
+10C9:00007FFE7BCE73B67BB67BB671CE7FFE7FFE71CE6FB66FC66FF671CE7FFE0000
+10CA:00007FFE7BCE73B67BB67BB671CE7FFE7FFE71866FB66F866FB671B67FFE0000
+10CB:00007FFE7BCE73B67BB67BB671CE7FFE7FFE718E6FB66F8E6FB6718E7FFE0000
+10CC:00007FFE7BCE73B67BB67BB671CE7FFE7FFE71C66FBE6FBE6FBE71C67FFE0000
+10CD:000000007C04040810102020407C0000
+10CE:00007FFE7BCE73B67BB67BB671CE7FFE7FFE71866FBE6F8E6FBE71867FFE0000
+10CF:00007FFE7BCE73B67BB67BB671CE7FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+10D0:0000000000000010100C0202423C0000
+10D1:00000000203010103C424242423C0000
+10D2:000000000030484808083C424242423C
+10D3:000000000000002C525252524C201C02
+10D4:000000003C424202020202020242423C
+10D5:0000000000003C4242021C020242423C
+10D6:0000000020505054381C1212120C0000
+10D7:00000000000000344A4A4A4A4A320000
+10D8:000000000000003C4242424242240000
+10D9:0000000000000C0202021C020242423C
+10DA:000000000000002A5555554142403E01
+10DB:000000003C424202023E4242423C0000
+10DC:00000000023C4040407C4242423C0000
+10DD:00000000000000285454545444240000
+10DE:0000000020180402021C0242423C0000
+10DF:00000000000000060A5252220222221C
+10E0:00000000043840685454545444240000
+10E1:00000000404040485048444444380000
+10E2:000000001824243C66665A424242423C
+10E3:000000000000006C121202020222221C
+10E4:00000000000000344A4A4A4A3402021C
+10E5:00000000040C0404041C240404044438
+10E6:00000000000000285454544448403804
+10E7:0000000000000022424242261A42423C
+10E8:0000000028545404041C242424180000
+10E9:00000000384478405C62424242420000
+10EA:0000000000004C4242425C424242423C
+10EB:0000000004020202023E4242423C0000
+10EC:0000000028545440407C444428281010
+10ED:00000000081828080819261D04044438
+10EE:00000000404040485078444444380000
+10EF:00000000000000004224181824422040
+10F0:0000100C02120C02120C0242423C0000
+10F1:0000504C42524C42524C4242423C0000
+10F2:0000000000003C4242424224187E0000
+10F3:0000000000003E0204081C020242423C
+10F4:0000000008100C0202021C020242423C
+10F5:00000000003844443E043E4444380000
+10F6:00000000201010103854543810101008
+10F7:0000000000003C42420408102042423C
+10F8:0000000000000044424242645842423C
+10F9:00000000003C424242423C101012120C
+10FA:0000000000003C4242300C1C22400000
+10FB:00000000000030300606303000000000
+10FC:0000021C20203C22221C000000000000
+10FD:0000000000003C42422010080442423C
+10FE:00000000000000C0221C2222221C0000
+10FF:0000000000000000001C2222221C0000
+1100:000000007F800080008000800080010001000200040018006000000000000000
+1101:0000000000007B80088008800880088011001100220044000800000000000000
+1102:000020002000200020003F800000000000000000000000000000000000000000
+1103:00003F802000200020003F800000000000000000000000000000000000000000
+1104:00003B802200220022003B800000000000000000000000000000000000000000
+1105:000000003F8000803F8020003F80000000000000000000000000000000000000
+1106:00003F802080208020803F800000000000000000000000000000000000000000
+1107:0000208020803F8020803F800000000000000000000000000000000000000000
+1108:00002A802A803B802A803B800000000000000000000000000000000000000000
+1109:00000400040004000A0011000000000000000000000000000000000000000000
+110A:00001100110011002A8044400000000000000000000000000000000000000000
+110B:00000E001100110011000E000000000000000000000000000000000000000000
+110C:00003F80010002000D0030800000000000000000000000000000000000000000
+110D:000000003BC00880150022800440000000000000000000000000000000000000
+110E:0E0000003F8002000D0030800000000000000000000000000000000000000000
+110F:00003F8000803F80008000800000000000000000000000000000000000000000
+1110:00003F8020003F8020003F800000000000000000000000000000000000000000
+1111:00007F801200120012007F800000000000000000000000000000000000000000
+1112:00000E0000003F8000001F002080208020801F00000000000000000000000000
+1113:000021FC2004200420043F840000000000000000000000000000000000000000
+1114:000020402040204020403E7C0000000000000000000000000000000000000000
+1115:0000207C2040204020403E7C0000000000000000000000000000000000000000
+1116:000020442044207C20443E7C0000000000000000000000000000000000000000
+1117:00003E7C2004200420043E040000000000000000000000000000000000000000
+1118:000000003E4002403E4020403E7C000000000000000000000000000000000000
+1119:000000003E7C02043E7C20403E7C000000000000000000000000000000000000
+111A:000000003E3002FC3E3020483E30000000000000000000000000000000000000
+111B:000000001FF800081FF810001FF803C00420042003C000000000000000000000
+111C:00003E442244227C22443E7C0000000000000000000000000000000000000000
+111D:00001FFC1004100410041FFC00000000000003E004100410041003E000000000
+111E:0000227C22043E0422043E040000000000000000000000000000000000000000
+111F:0000224022403E4022403E7C0000000000000000000000000000000000000000
+1120:0000227C22403E4022403E7C0000000000000000000000000000000000000000
+1121:0000221022103E1022283E440000000000000000000000000000000000000000
+1122:0000489E4882788249427A220000000000000000000000000000000000000000
+1123:0000488E4888788849487A2E0000000000000000000000000000000000000000
+1124:000049244924793C4AA47C7C0000000000000000000000000000000000000000
+1125:000048884888788849547A220000000000000000000000000000000000000000
+1126:0000493E490479084A947C620000000000000000000000000000000000000000
+1127:0000227C22083E1022283E440000000000000000000000000000000000000000
+1128:00382200227C3E1022283E440000000000000000000000000000000000000000
+1129:0000227C22403E7C22403E7C0000000000000000000000000000000000000000
+112A:0000227C22283E2822283E7C0000000000000000000000000000000000000000
+112B:000008080FF808080FF801C0022001C000000000000000000000000000000000
+112C:000022443E7C22443E7C03C0042003C000000000000000000000000000000000
+112D:0000047C040404040A0411040000000000000000000000000000000000000000
+112E:00000440044004400A40117C0000000000000000000000000000000000000000
+112F:0000047C044004400A40117C0000000000000000000000000000000000000000
+1130:0000047C0404047C0A40117C0000000000000000000000000000000000000000
+1131:0000047C044404440A44117C0000000000000000000000000000000000000000
+1132:000004440444047C0A44117C0000000000000000000000000000000000000000
+1133:0000112E112211E2292245E20000000000000000000000000000000000000000
+1134:0000088808880888155422220000000000000000000000000000000000000000
+1135:00000438044404440A4411380000000000000000000000000000000000000000
+1136:0000047C040804100A2811440000000000000000000000000000000000000000
+1137:00380400047C04100A2811440000000000000000000000000000000000000000
+1138:0000047C0404047C0A0411040000000000000000000000000000000000000000
+1139:0000047C0440047C0A40117C0000000000000000000000000000000000000000
+113A:0000047C042804280A28117C0000000000000000000000000000000000000000
+113B:0000043004FC04300A4811300000000000000000000000000000000000000000
+113C:0000004000400180068018400000000000000000000000000000000000000000
+113D:00000120012002A0045019880000000000000000000000000000000000000000
+113E:0000008000800100068018400000000000000000000000000000000000000000
+113F:00000480048005400A30118C0000000000000000000000000000000000000000
+1140:000002000500088010403FE00000000000000000000000000000000000000000
+1141:00000E7C1104110411040E040000000000000000000000000000000000000000
+1142:00000E3C1120112011200E3C0000000000000000000000000000000000000000
+1143:00000E3E1122112211220E3E0000000000000000000000000000000000000000
+1144:00000E241124113C11240E3C0000000000000000000000000000000000000000
+1145:00000E081108110811140E220000000000000000000000000000000000000000
+1146:0000382044504488450439FC0000000000000000000000000000000000000000
+1147:00000E381144114411440E380000000000000000000000000000000000000000
+1148:00000E7C1108111011280E440000000000000000000000000000000000000000
+1149:00380E00117C111011280E440000000000000000000000000000000000000000
+114A:00000E3C1120113C11200E3C0000000000000000000000000000000000000000
+114B:00000E7C1128112811280E7C0000000000000000000000000000000000000000
+114C:00000E001100110011000E000000000000000000000000000000000000000000
+114D:00003E3804440844144422380000000000000000000000000000000000000000
+114E:00003FE000C003800C4030200000000000000000000000000000000000000000
+114F:000000001FF0012002A00C503188000000000000000000000000000000000000
+1150:00001FF0006001C0062018100000000000000000000000000000000000000000
+1151:000000003FE0084014A02310018C000000000000000000000000000000000000
+1152:1C00007C3E04087C140422040000000000000000000000000000000000000000
+1153:180000303EFC0830144822300000000000000000000000000000000000000000
+1154:078000001FC00180064038200000000000000000000000000000000000000000
+1155:0E0000003F0002000D8030700000000000000000000000000000000000000000
+1156:00003E441444147C14443E7C0000000000000000000000000000000000000000
+1157:00001FF804201FF803C0042003C0000000000000000000000000000000000000
+1158:000018307EFC1C70228822881C70000000000000000000000000000000000000
+1159:1FF0010007C00820082007C00000000000000000000000000000000000000000
+115A:00003E7C024002400240027C0000000000000000000000000000000000000000
+115B:000010101010101010281F440000000000000000000000000000000000000000
+115C:0000107C1008101010281F440000000000000000000000000000000000000000
+115D:0000107011FC107010881E700000000000000000000000000000000000000000
+115E:000000003E7C2004207C20403E7C000000000000000000000000000000000000
+115F:555580000001A2382241BE402241A238000183E002018380020182000001AAAA
+1160:555580000001A2782211BE102251A220000183E002018380020182000001AAAA
+1161:0000001000100010001E00100010001000000000000000000000000000000000
+1162:0000001200120012001E00120012001200000000000000000000000000000000
+1163:0000001000100010001E0010001E001000000000000000000000000000000000
+1164:0000001200120012001E0012001E001200000000000000000000000000000000
+1165:0000001000100010007000100010001000000000000000000000000000000000
+1166:0000001200120012007200120012001200000000000000000000000000000000
+1167:0000001000100010007000100070001000000000000000000000000000000000
+1168:0000001200120012007200120072001200000000000000000000000000000000
+1169:000000000000000000000000000000000000008000803FFE0000000000000000
+116A:0000001000100010001E041004103FF000000000000000000000000000000000
+116B:0000001200120012001E041204123FF200000000000000000000000000000000
+116C:00000010001000100010041004103FF000000000000000000000000000000000
+116D:00000000000000000000024002403FFE00000000000000000000000000000000
+116E:00000000000000000000000000003FFE00800080000000000000000000000000
+116F:00000010001000100010001000103F90041004F0041000000000000000000000
+1170:00000012001200120012001200123F92041204F2041200000000000000000000
+1171:00000010001000100010001000103FF004100410041000000000000000000000
+1172:00000000000000000000000000003FFE02200220000000000000000000000000
+1173:00000000000000000000000000003FFE00000000000000000000000000000000
+1174:000000100010001000100010001000100010001000103FF00010001000000000
+1175:0000001000100010001000100010001000000000000000000000000000000000
+1176:00000000000000000000002000200020003800A000A03FF80000000000000000
+1177:0000001000100010001C001000103FFE00800080000000000000000000000000
+1178:000000000000000000080008000E0008000E008800883FFE0000000000000000
+1179:00080008000E0008000E024802483FFE00000000000000000000000000000000
+117A:000000000000000800080008003800080008008800883FFE0000000000000000
+117B:00000000000400040004001C0004000400043FFE008000800000000000000000
+117C:00200020002000E000200020002000203FF00000000000000000000000000000
+117D:000000000000000000080008003800080038008800883FFE0000000000000000
+117E:00080008000800380008003800083FFE00800080000000000000000000000000
+117F:00000000000200020002000200023FFE0082008E000200000000000000000000
+1180:000000000000001200120012007200120012011201123FF20012000000000000
+1181:000000000000001200120012007200120012017201123FF20012000000000000
+1182:000000000000000000000000000000803FFE00803FFE00000000000000000000
+1183:000000000000000000000000008000803FFE00003FFE00800080000000000000
+1184:0000000000100010001E091009103FFE00100000000000000000000000000000
+1185:000000A400A400A404BC04A404FC3FA400000000000000000000000000000000
+1186:00020002000E0002000E048204823FFE00020000000000000000000000000000
+1187:0000000000000000000002203FFE00803FFE0000000000000000000000000000
+1188:00000000000200020002024202423FFE00020000000000000000000000000000
+1189:00000000000000000008000800083FFE02080208000800000000000000000000
+118A:00000000000000000012001200123FFE02120212001200000000000000000000
+118B:000000080008000800081FC80208027802083FFE000000000000000000000000
+118C:0000000A000A000A000A000A000A3FEA020A023A000A003A000A000000000000
+118D:00000000000000000000000000003FFE00803FFE008000000000000000000000
+118E:00000008000800080008000800083FFE02480248000800000000000000000000
+118F:00000001000100010001000100013FFF0221022F000100000000000000000000
+1190:00000000000A000A000A000A000A3FFA048A04BA000A00000000000000000000
+1191:00000000000200020002000200023FFE0242024E0002000E0002000000000000
+1192:00000000000A000A000A000A000A3FFA048A04BA000A003A000A000000000000
+1193:00000000000000000000000000003FFE02203FFE008000000000000000000000
+1194:00000000000100010001000100013FFF02210221000100000000000000000000
+1195:00000000000000000000000000003FFE00003FFE008000000000000000000000
+1196:00000000000000000000000000003FFE00003FFE000000000000000000000000
+1197:00040004000400040004000400040FFC00043FFE008000000000000000000000
+1198:0000004800480048004E00480048004800000000000000000000000000000000
+1199:000000480048004E0048004E0048004800000000000000000000000000000000
+119A:000000000000000400040004000400040004008400843FFE0000000000000000
+119B:00040004000400040004000400043FFE00800080000000000000000000000000
+119C:00000004000400040004000400043FFE00000000000000000000000000000000
+119D:00000020002000200020002000200020000000C0002000100000000000000000
+119E:00000000000000000000000000000000000000C0002000100000000000000000
+119F:000000100010001000700C100210011000000000000000000000000000000000
+11A0:000000000000000000000060001000083FFE0080008000000000000000000000
+11A1:0000001000100010001018100410021000000000000000000000000000000000
+11A2:0000000000000000000018600410020800000000000000000000000000000000
+11A3:000000000000000000000020002000200038002000203FF80000000000000000
+11A4:000000000000000000080008000E0008000E000800083FFE0080008000000000
+11A5:000000000000000000280028002E00E8002800EE002800280028000000000000
+11A6:0000000000100010001E011001103FFE00100000000000000000000000000000
+11A7:0000002400240024003C042404FC3F2400000000000000000000000000000000
+11A8:00000000000000000000000000000000000007F0001000100010001000000000
+11A9:0000000000000000000000000000000000000F78010801080108010800000000
+11AA:0000000000000000000000000000000000000F10011001100128014400000000
+11AB:000000000000000000000000000000000000040004000400040007F000000000
+11AC:00000000000000000000000000000000000008F80820082008500F8800000000
+11AD:000000000000000000000000000000000000083008FC083008480F3000000000
+11AE:00000000000000000000000000000000000007F004000400040007F000000000
+11AF:00000000000000000000000000000000000007F0001007F0040007F000000000
+11B0:0000000000000000000000000000000000000F7801080F0808080F0800000000
+11B1:0000000000000000000000000000000000001EF002901E9010901EF000000000
+11B2:0000000000000000000000000000000000001E9002901EF010901EF000000000
+11B3:0000000000000000000000000000000000001E2002201E2010501E8800000000
+11B4:0000000000000000000000000000000000001EF002801EF010801EF000000000
+11B5:0000000000000000000000000000000000001EF802501E5010501EF800000000
+11B6:0000000000000000000000000000000000001E6003F81E6010901E6000000000
+11B7:00000000000000000000000000000000000007F004100410041007F000000000
+11B8:0000000000000000000000000000000000000410041007F0041007F000000000
+11B9:000000000000000000000000000000000000122012201E2012501E8800000000
+11BA:0000000000000000000000000000000000000040004000C003201C1000000000
+11BB:0000000000000000000000000000000000000120012003A00C50318800000000
+11BC:00000000000000000000000000000000000001C002200220022001C000000000
+11BD:00000000000000000000000000000000000007F0008000800140022000000000
+11BE:00000000000000000000000000000000000001E0000007F8004003A00C180000
+11BF:00000000000000000000000000000000000007F0001007F00010001000000000
+11C0:00000000000000000000000000000000000007F0040007F0040007F000000000
+11C1:0000000000000000000000000000000000000FF00240024002400FF000000000
+11C2:000000000000000000000000000001C0000007F0000001C0022001C000000000
+11C3:0000000000000000000000000000000000007E7C0204027C0240027C00000000
+11C4:00000000000000000000000000000000789E0882088209420A22000000000000
+11C5:00000000000000000000000000000000000021FC2004200420043F8400000000
+11C6:000000000000000000000000000000000000207C2040204020403E7C00000000
+11C7:00000000000000000000000000000000000020202020202020503E8800000000
+11C8:00000000000000000000000000000000000040104028404440827CFE00000000
+11C9:000000000000000000000000000000000000207C2040207C20403E7C00000000
+11CA:0000000000000000000000000000000000003E7C2004200420043E0400000000
+11CB:0000000000000000000000000000000000003E7C2004207C20403E7C00000000
+11CC:0000000000000000000000000000000000007BC408447844404A785100000000
+11CD:0000000000000000000000000000000000003E4002403E4020403E7C00000000
+11CE:0000000000000000000000000000000000003E7C02403E4020403E7C00000000
+11CF:000000000000000000000000000000000000F78C143FF40C8412F78C00000000
+11D0:0000000000000000000000000000000000003E7C02043E7C20403E7C00000000
+11D1:0000000000000000000000000000000000007BDE0A427A4242427BC200000000
+11D2:0000000000000000000000000000000000007BC40A447A44424A7BD100000000
+11D3:0000000000000000000000000000000000007A440A447BC4424A7BD100000000
+11D4:000000000000000000000000000000000000F48C14BFF78C8492F78C00000000
+11D5:0000000000000000000000000000004800783E4802783E3020483E3000000000
+11D6:00000000000000000000000000000000000078880888788841547A2200000000
+11D7:0000000000000000000000000000000000003C2004503C8821043DFC00000000
+11D8:0000000000000000000000000000000000003E7C02043E7C20043E0400000000
+11D9:0000000000000000000000000000000000003E3802FE3E3820443E3800000000
+11DA:0000000000000000000000000000000000003E7C2204220422043E0400000000
+11DB:0000000000000000000000000000000000003E7C2204227C22403E7C00000000
+11DC:0000000000000000000000000000000000003E442244227C22443E7C00000000
+11DD:0000000000000000000000000000000000001F101110111011281F4400000000
+11DE:0000000000000000000000000000000000007C444444444444AA7D1100000000
+11DF:0000000000000000000000000000000000003E102228224422823EFE00000000
+11E0:0000000000000000000000000000000000383E0022FE220822343EC200000000
+11E1:0000000000000000000000000000000000003E3822FE223822443E3800000000
+11E2:00000000000000000000000000000FE008200FE0000003800440038000000000
+11E3:000000000000000000000000000000000000227C22043E7C22403E7C00000000
+11E4:000000000000000000000000000000000000227C22283E2822283E7C00000000
+11E5:000000000000000000000000000000000000223822FE3E3822443E3800000000
+11E6:0000000000000000000000000000041007F0041007F001C0022001C000000000
+11E7:00000000000000000000000000000000000004F8040804080A08110800000000
+11E8:000000000000000000000000000000000000047C044004400A40117C00000000
+11E9:00000000000000000000000000000000000008F8080808F8148022F800000000
+11EA:00000000000000000000000000000000000004440444047C0A44117C00000000
+11EB:00000000000000000000000000000000000001000280044008201FF000000000
+11EC:0000000000000000000000000000000000000E7C1104110411040E0400000000
+11ED:00000000000000000000000000000000000039DC444444444444384400000000
+11EE:0000000000000000000000000000000000001C382244224422441C3800000000
+11EF:0000000000000000000000000000000000001C7C2204227C22041C0400000000
+11F0:0000000000000000000000000000010001000380044004400440038000000000
+11F1:0000000000000000000000000000000000001C202220222022501C8800000000
+11F2:000000000000000000000000000000000000382044504488450439FC00000000
+11F3:0000000000000000000000000000000000003E441444147C14443E7C00000000
+11F4:000000000000000000000000000000000FF002400FF003C0042003C000000000
+11F5:0000000000000000000000000000000000001C407F401C4022401C7C00000000
+11F6:0000000000000000000000000000000000001C7C7F041C7C22401C7C00000000
+11F7:0000000000000000000000000000000000001C7C7F441C4422441C7C00000000
+11F8:0000000000000000000000000000000000001C447F441C7C22441C7C00000000
+11F9:00000000000000000000000000000000000003800FE003800440038000000000
+11FA:0000000000000000000000000000000000003E40024002400240027C00000000
+11FB:0000000000000000000000000000000000003E440244027C0244027C00000000
+11FC:0000000000000000000000000000000000383E0002FE0208023402C200000000
+11FD:0000000000000000000000000000000000003E7C0204027C0204020400000000
+11FE:0000000000000000000000000000000000003E3802FE02380244023800000000
+11FF:00000000000000000000000000000000000020402040204020403E7C00000000
+1200:00000000000001C030C030C030C030C030C030C0318031801F000E0000000000
+1201:00000000000001C030C030C030C030FC30CC30C0318031801F000E0000000000
+1202:0000000006600C600C600C600C6007C003C000C001800300033003F000000000
+1203:0000000006600C600C600C600C6007C003C000C0018003000300030000000000
+1204:0000000006600C600C600C600C6007C003C000C001C00340032003E000000000
+1205:000000000000187018301C300E3006300C300C300C300C6007E003C000000000
+1206:00000000000000F030C830D830E030C030C030C0318031801F000E0000000000
+1207:000000000000003C0C320C360C386C307C306C300C600C6007C0038000000000
+1208:00000000030003000300078007C00CE00C600C600C600C600C600C6000000000
+1209:000000000C000C000C001E001F0033803180318031F831983180318000000000
+120A:000000000C000C000C001E001F0033803180318031803180319831F800000000
+120B:00000000030003000300078007C00CE00C600C600C6000600060006000000000
+120C:000000000C000C000C001E001F00338031803180318031F0319831F000000000
+120D:00000000030003000300078007C00CE00C60186018601E601B601E6000000000
+120E:000000000C000C000C001E001F003380318031F831AC31B83180318000000000
+120F:00000000030003000300078007C00CE00C600C600C6000600060006003FC070E
+1210:000000000180018001800180018007E00DB00DB0199819981998199800000000
+1211:00000000060006000600060006001F8036C036C0667E66666660666000000000
+1212:00000000060006000600060006001F8036C036C0666066606666667E00000000
+1213:000000000180018001800180018007E00DB00DB0199800180018001800000000
+1214:00000000060006000600060006001F8036C036C066406678664C667800000000
+1215:000000000600060006000780018007E00DB00DB0199819981998199800000000
+1216:000000000180018001800180018007E00DB00DB0199818001800180000000000
+1217:0000030003000300030003000FC01B601B60333000300030003001FE03870000
+1218:000000000000000000000FFC1FFC112431642344264C3C783C70000000000000
+1219:000000000000000000003FF07FF04490C59E8D129932F1E0F1C0000000000000
+121A:000000001FF83FF86288428845087DF838F80010001000200026003E00000000
+121B:000000000FFC1FFC3144214422843EFC1C7C0008000800100010001000000000
+121C:000000001FF83FF86288428845087DF838F800100010003C0026003C00000000
+121D:000000001FF01FF832882288228822F83E701E00020006000C00180000000000
+121E:000000001FF01FF832882288228822F83E701E00020002000200030000000000
+121F:000000001FF83FF86288428845087DF838F80010001000300020002001F8030C
+1220:00000000000000000998199819981998199819B019F00D800780000000000000
+1221:000000000000000026C066C066FC66CC66C066C067C036001E00000000000000
+1222:000000006640666066606660666076E03FE00060006000600066007E00000000
+1223:00000000199019981998199819981DB80FF80018001800180018001800000000
+1224:00000000332033303330333033303B701FF00030003000380064007800000000
+1225:00000000199019981998199819981DB81FF01C00180018001800180000000000
+1226:00000000199819981998199819981DB80FF00380030007000E000C0000000000
+1227:00006640666066606660666076E03FE00060006000600060006003FC070E0000
+1228:00000000018001800180030007000E001C00180018001C600FE007E000000000
+1229:000000000300030007000E001C001800300038001FF00FF00180018000000000
+122A:00000000018001800180030007000E001C00186018701C300FE007C000000000
+122B:0000000003000300030006000E001C003800307830F839981F800F0000000000
+122C:00000000018001800180030007000E001C00180018001CF00F9807F000000000
+122D:00000000000007E00FE018601800180018001800180018601FE00FC000000000
+122E:00000000000007F00F9818F01800180018001800180018601FE00FC000000000
+122F:0000000030301CE00300030006000E001C003800307830F839981F800F000000
+1230:0000000001000100038007C00C600C600C600C600C600C600C600C6000000000
+1231:00000000040004000E001F0031803180318031F8319831803180318000000000
+1232:00000000040004000E001F00318031803180318031803180319831F800000000
+1233:0000000001000100038007C00C600C600C600C600C6000600060006000000000
+1234:000000000200020007000F8018C018C018C018C018E018D018C818F800000000
+1235:0000000000000300018001C003E0063006300630063006300630063000000000
+1236:0000000001000100038007C00C600C600C600C600C600C000C000C0000000000
+1237:0000000001000100038007C00C600C600C600C600C6000600060006001F8030C
+1238:0000000030601FC0020007000F8018C018C018C018C018C018C018C000000000
+1239:0000000030601FC0020007000F8018C018C018FC18CC18CC18C018C000000000
+123A:0000000030601FC0020007000F8018C018C018C018C018C018CC18FC00000000
+123B:0000000018300FE00100038007C00C600C600C600C6000600060006000000000
+123C:0000000030601FC0020007000F8018C018C018C018C018F818CC18F800000000
+123D:0000000018600FC0018001C003E0033006300630063006300630063000000000
+123E:0000000018300FE00100038007C00C600C600C600C600C000C000C0000000000
+123F:0000000030601FC0020007000F8018C018C018C018C018C000C000C003F00618
+1240:0000000001800180018003F00D98199819B00FC0018001800180018000000000
+1241:0000000003000300030007E01B30333033601F80030003F00330030000000000
+1242:0000000003000300030007E01B30333033601F8003000300033003F000000000
+1243:0000000001800180018003F00D98199819B00FC00180030006000C0000000000
+1244:0000000003000300030007E01B30333033601F80030003E0033003E000000000
+1245:00000000060006000780018003F00D98199819B00FC001800180018000000000
+1246:0000000001C0026002C0030007E01B30333033601F8003000300030000000000
+1247:0000000001C0026002C0030007E01B30333033601F80030033003F0030000000
+1248:0000000001800180018003F00D98199819B00FC001F801AC01B8018000000000
+1249:00007FFE7B8673F67B867BBE71867FFE7FFE6DCE6DB661C67DF67DCE7FFE0000
+124A:000000000600060006000FC0366C666C66FC3F07060306000600060000000000
+124B:0000000001800180018003F00D98199819B00FC0018001800180018007E00C30
+124C:0000000001800180018003F00D98199819B00FC00180018001F0019807F00C00
+124D:000000000600061806180FFE3666666066C03F00060006000600060000000000
+124E:00007FFE7B8673F67B867BBE71867FFE7FFE6D866DBE618E7DBE7D867FFE0000
+124F:00007FFE7B8673F67B867BBE71867FFE7FFE6D866DBE618E7DBE7DBE7FFE0000
+1250:000000000C3007E00180018003F00D98199819B00FC001800180018000000000
+1251:0000000018600FC00300030007E01B30333033601F80030003F0033000000000
+1252:0000000018600FC00300030007E01B30333033601F800300033003F000000000
+1253:000000000C3007E00180018003F00D98199819B00FC001800300060000000000
+1254:0000000018600FC0030007E01B30333033601F80030003E0033003E000000000
+1255:0000000030C01F8006000780018003F00D98199819B00FC00180018000000000
+1256:000000000C1807F001200160018003F00D98199819B00FC00180018000000000
+1257:00007FFE7B8673F67B867BBE71867FFE7FFE61866FF661EE7DDE61DE7FFE0000
+1258:0000000018600FC0030007E01B30333033601F8003F003580370030000000000
+1259:00007FFE7B8673F67B867BBE71867FFE7FFE61CE6FB661C67DF661CE7FFE0000
+125A:0000000030C01F80060006000FC0366C666C66FC3F0706030600060000000000
+125B:000000000C3007E00180018003F00D98199819B00FC001800180018007E00C30
+125C:000000000C3007E00180018003F00D98199819B00FC0018001F0019807F00C00
+125D:0000000030C01F80061806180FFE3666666066C03F0006000600060000000000
+125E:00007FFE7B8673F67B867BBE71867FFE7FFE61866FBE618E7DBE61867FFE0000
+125F:00007FFE7B8673F67B867BBE71867FFE7FFE61866FBE618E7DBE61BE7FFE0000
+1260:000000000000038007C00C600C600C600C600C600C600C600C600C6000000000
+1261:0000000000000E001F0031803180318031F83198319831803180318000000000
+1262:0000000000000E001F003180318031803180318031803180319831F800000000
+1263:000000000000038007C00C600C600C600C600C60006000600060006000000000
+1264:00000000000007000F8018C018C018C018C018C018C018F818CC18F800000000
+1265:00000000000000E001F00318031803183F183318331803180318031800000000
+1266:000000000000038007C00C600C600C600C600C600C000C000C000C0000000000
+1267:000000000000038007C00C600C600C600C600C60006000600060006001F8030C
+1268:0000000030601FC0000007000F8018C018C018C018C018C018C018C000000000
+1269:0000000030601FC0000007000F8018C018C018FC18CC18CC18C018C000000000
+126A:0000000030601FC0000007000F8018C018C018C018C018C018CC18FC00000000
+126B:0000000030601FC0000007000F8018C018C018C018C018C000C000C000000000
+126C:0000000060C03F8000000E001F00318031803180318031F0319831F000000000
+126D:000000000C1807F0000001C003E0063006307E30663066300630063000000000
+126E:0000000030601FC0000007000F8018C018C018C018C018C01800180000000000
+126F:0000000030601FC0000007000F8018C018C018C018C018C000C000C003F00618
+1270:0000000007000300030003003FF07FF863180300030003000300030000000000
+1271:0000000007000300030003003FF07FF86318030003F003300300030000000000
+1272:0000000007000300030003003FF07FF86318030003000300033003F000000000
+1273:0000000007000300030003003FF07FF863180300030007000E001C0000000000
+1274:0000000007000300030003003FF07FF863180300030003E0033003E000000000
+1275:00000000060007000380018001801FF83FFC318C018001800180018000000000
+1276:0000000003E00320016001801FF83FFC318C0180018001800180018000000000
+1277:0000000003800180018001801FF83FFC318C0180018001800180018007E00C30
+1278:0000000018181FF83FFC318C01801FF83FFC318C018001800180018000000000
+1279:0000000018181FF83FFC318C01801FF83FFC318C018001F80198018000000000
+127A:0000000018181FF83FFC318C01801FF83FFC318C01800180019801F800000000
+127B:0000000030303FF07FF8631803003FF07FF86318030007000E001C0000000000
+127C:0000000030303FF07FF8631803003FF07FF86318030003E0033003E000000000
+127D:0000000030C03FC07FE06660070001801FF83FFC318C01800180018000000000
+127E:000000000C301FF81A58024001801FF83FFC318C018001800180018000000000
+127F:0000000018181FF83FFC318C01801FF83FFC318C018001800180018007E00C30
+1280:000000000180018001801F8019E0006000600060006000600060006000000000
+1281:000000000300030003003F0033C000C000C000FC00CC00C000C000C000000000
+1282:000000000300030003003F0033C000C000C000C000C000C000CC00FC00000000
+1283:0000000000C000C000C00FC00CF000300030003000E001800300030000000000
+1284:000000000300030003003F0033C000C000C000C000C000F800CC00F800000000
+1285:0000000000C000C000C003C006F00C300C300030003000300030003000000000
+1286:0000000001F803E406383E003600060007E003E0006000600060006000000000
+1287:0000000001F803E406383E003600060007E003E000600060066007E006000000
+1288:000000000600060006007E006780018001F801AC01B801800180018000000000
+1289:00007FFE7B8673F67B867BBE71867FFE7FFE73CE6DB673C66DF673CE7FFE0000
+128A:000000000600060006007E0067800198019801F8018E01860180018000000000
+128B:000000000180018001801F8019E0006000600060006000600060006001F8030C
+128C:000000000300030003003F0033C000C000C000C000C000C000F800CC03F80600
+128D:000000000600060006007E3067B001FC018C0180018001800180018000000000
+128E:00007FFE7B8673F67B867BBE71867FFE7FFE73866DBE738E6DBE73867FFE0000
+128F:00007FFE7B8673F67B867BBE71867FFE7FFE73866DBE738E6DBE73BE7FFE0000
+1290:00000000060006000600078001C0018001800180030003000300030000000000
+1291:00000000060006000600078001C00180018001F0033003000300030000000000
+1292:000000000C000C000C000F00038003000300030006000600066007E000000000
+1293:0000000007C00FE01860300038001F0003800180010003000300030000000000
+1294:00000000060006000600078001C001800180018003C00320036003C000000000
+1295:000000003FC03F803180030007C000C0018003000300060006000C0000000000
+1296:0000000007F00FC81858303038001F0003800180010003000300030000000000
+1297:00000000000007C00FE01860300038001F00038001800100030003000FC01860
+1298:000000000C301FF81188018001E000700060006000C000C000C000C000000000
+1299:0000000018603FF02310030003C000E000C000F8019801800180018000000000
+129A:0000000018603FF02310030003C000E000C000C001800180019801F800000000
+129B:00000C301FF8118807C00FE01860300038001F00038001800300030000000000
+129C:0000000018603FF02310030003C000E000C000C001E0019001B001E000000000
+129D:000030C07FE046201FC03F803180030007C000C0018003000300030000000000
+129E:00000C601FF0111007F00FC81858303038001F00038001800300030000000000
+129F:00000C301FF8118807C00FE01860300038001F0003800180030003000FC01860
+12A0:0000000006000600060007800180038003C006E00E600C600C600C6000000000
+12A1:000000001800180018001E0006000E000F001B8039F831983180318000000000
+12A2:000000001800180018001E0006000E000F001B8039803180319831F800000000
+12A3:000000000600060006000780018003C006E00C600C600C600060006000000000
+12A4:000000001800180018001E0006000E000F001B80398031F0319831F000000000
+12A5:000000000C000C000E0006000300038007C00EE00C600C600C600C6000000000
+12A6:000000000600060006000780018003C006E00C600C600C600C000C0000000000
+12A7:000018C01FC03660060007800180038003C006E00E600C600C600C6000000000
+12A8:000000000000180019C01FE01E30063006300630063006300630063000000000
+12A9:000000000000600067007F8078C018C018C018FC18CC18C018C018C000000000
+12AA:000000000000600067007F8078C018C018C018C018C018C018CC18FC00000000
+12AB:000000000000180019C01FE01E30063006300630063000300030003000000000
+12AC:000000000000600067007F8078C018C018C018C018C018F818CC18F800000000
+12AD:000000000000180019C01BE01E300C300E300630063006300630063000000000
+12AE:000000000000180019C01FE01E30063006300630063006000600060000000000
+12AF:0000000000000C000CE00FF00F18031833183F18331803000300030000000000
+12B0:000000000000600066007F007980198019F819AC19B819801980198000000000
+12B1:00007FFE7B8673F67B867BBE71867FFE7FFE63EE6DCE63EE6DEE63C67FFE0000
+12B2:000000000000600066007F0079801998199819F8198E19861980198000000000
+12B3:000000000000180019C01FE01E30063006300630063000300030003000FC0186
+12B4:000000000000600067007F8078C018C018C018C018C000C000F800CC03F80600
+12B5:000000000000600066307F3079FC198C19801980198019801980198000000000
+12B6:00007FFE7B8673F67B867BBE71867FFE7FFE63CE6DBE638E6DB663CE7FFE0000
+12B7:00007FFE7B8673F67B867BBE71867FFE7FFE63866DF663EE6DDE63DE7FFE0000
+12B8:0000000061803F000C000DC00FE0063006300630063006300630063000000000
+12B9:00000000C3007E0018001B801FC00C600C600C7E0C660C600C600C6000000000
+12BA:00000000C3007E0018001B801FC00C600C600C600C600C600C660C7E00000000
+12BB:0000000061803F000C000DC00FE0063006300630063000300030003000000000
+12BC:0000000061803F000C000DC00FE00630063006300630063E0633063E00000000
+12BD:0000000061803F000C000EE00FF0031803980198019801980198019800000000
+12BE:0000000061803F000C000DC00FE0063006300630063006000600060000000000
+12BF:00007FFE7B8673F67B867BBE71867FFE7FFE63866DBE638E6DBE63BE7FFE0000
+12C0:00000000C3007E0018001B801FC00C600C7E0C6B0C6E0C600C600C6000000000
+12C1:00007FFE7B8673F67B867BBE71867FFE7FFE71EE6FCE6FEE6FEE71C67FFE0000
+12C2:00000000C3007E0018001B001F800CCC0CCC0CFC0CC70CC30CC00CC000000000
+12C3:0000000061803F000C000DC00FE0067006300630063000300030003000FC0186
+12C4:0000000061803F000C000DC00FE006700630063006300030003E003300FE0180
+12C5:00000000C3007E00180C1B8C1FFF0C630C600C600C600C600C600C6000000000
+12C6:00007FFE7B8673F67B867BBE71867FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000
+12C7:00007FFE7B8673F67B867BBE71867FFE7FFE71866FF66FEE6FDE71DE7FFE0000
+12C8:000000000000000000000FF01DB831983198331833303B701FC0000000000000
+12C9:000000000000000000003FC076E0C660C660CC60CCE0EDC67FFC000C00000000
+12CA:000000000FF01DB83198319833183BB01FE0030003000700066007E000000000
+12CB:000000000FF01DB83198319833183BB01FE00300030003000300070000000000
+12CC:000000000FF01DB83198319833183BB01FE0030003000780066007C000000000
+12CD:000000000000000000003FC076E0C660C67ECC66CCC2EDC07F00000000000000
+12CE:000000000FF01DB83198319833183BB01FE0030006000C001800180000000000
+12CF:0000000003FC076E6C667C666CC60EEC07F800C0018003000600060000000000
+12D0:00000000000001E006300C300C300C300C300C300C300C3007F0060000000000
+12D1:000000000000078018C030C030C030C030C030FC30CC30C01FC0180000000000
+12D2:0000000000001F0031806180618061803FC000C000C00180019801F800000000
+12D3:00000000000007C00C601860186018600FF00030003000300060006000000000
+12D4:0000000000001F0031806180618061803FC000C000C001F0019801F000000000
+12D5:000001800180018007E00E300C300C300C300C300C300C3007F0060000000000
+12D6:0000000003C006600C300C300C300E7007E003C007000C000C000C0000000000
+12D7:00007FFE7B8673F67B867BBE71867FFE7FFE63866DF66DEE6DDE63DE7FFE0000
+12D8:000000000C600C600C600C600C600FE00FE00C600C600C600C600C6000000000
+12D9:00000000318031803180318031803F803F8031F8319831983180318000000000
+12DA:00000000318031803180318031803F803F80318031803180319831F800000000
+12DB:000000000C600C600C600C600FE00FE00C600C600C6000600060006000000000
+12DC:0000000018C018C018C018C018C01FC01FC018C018C018F818CC18F800000000
+12DD:000000001C30363036300630063007F007F00630063006300630063000000000
+12DE:000000000C600C600C600C600FE00FE00C600C600C600C000C000C0000000000
+12DF:000000000C600C600C600C600FE00FE00C600C600C6000600060006001F8030C
+12E0:000000001C38366C366C0660066007E007E00660066006600660066000000000
+12E1:0000000038706CD86CD80CC00CC00FC00FC00CFC0CCC0CCC0CC00CC000000000
+12E2:0000000038706CD86CD80CC00CC00FC00FC00CC00CC00CC00CCC0CFC00000000
+12E3:000000001C38366C366C066007E007E006600660066000600060006000000000
+12E4:0000000038706CD86CD80CC00CC00FC00FC00CC00CC00CF80CCC0CF800000000
+12E5:000061803F000C001C38366C366C066007E007E0066006600660066000000000
+12E6:000000001C38366C366C066007E007E006600660066006000600060000000000
+12E7:000000001C38366C366C066007E007E006600660066000600060006001F8030C
+12E8:00000000038006C00C600C600C600C600EC00780030003000300030000000000
+12E9:00000000038006C00C600C600C600C600EC00780030003F00330030000000000
+12EA:0000000007000D8018C018C018C018C01D800F00066007F80618060000000000
+12EB:0000000001C00360063006300630066007C0038001C0006001C0038000000000
+12EC:0000000007000D8018C018C018C018C01D800F0006F0079806F0060000000000
+12ED:00000000000007800CC018C018C018C00D800F30073003E03E00700060000000
+12EE:000000000E001B00318031F8319831803B001E000C000C000C000C0000000000
+12EF:00000000038006C00C600C7E0C660C606EC07F80630003000300030000000000
+12F0:00000000038007C00C400C400CC00F8006000300030001801FF8181800000000
+12F1:0000000007000F80188019801F000C0006001FC030C030FC018C018000000000
+12F2:0000000007000F80188019801F000C0006001FC030C030C0019801F800000000
+12F3:0000000001C003E00620066007C0030001800FF00C300C300030003000000000
+12F4:0000000007000F801880188019801F000C000600060003F03F9830F000000000
+12F5:0000000007000F8018F8189819801F000C000600060003003FF0303000000000
+12F6:0000000001C003E00620066007C0038007F00C30180018001800180000000000
+12F7:0000000001C003E00620066007C0030001800FF00C300C300030003000FC0186
+12F8:0000000001000100038007C00C400CC00F800600030001800FF00C3000000000
+12F9:000000000200020007000F80188019801F000C001FC030FC318C018000000000
+12FA:000000000200020007000F80188019801F000C001FC030C0319801F800000000
+12FB:0000000001000100038007C00C400CC00F8006001FE018600060006000000000
+12FC:00000000040004000E001F00310033003E0018000C0006F03F9830F000000000
+12FD:000000000200020007000F8018F819981F000C00060003001FE0186000000000
+12FE:0000000001000100038007C00C400CC00F8007F00C3018001800180000000000
+12FF:0080008001C003E00620066007C0030001800FF00C300C300030003000FC0186
+1300:000030301FE0030007800CC00C400CC007800600070003001FE0186000000000
+1301:000060603FC006000F00198019800F0006001FC030C030FC018C018000000000
+1302:000060603FC006000F00198019800F0006001FC030C030C0019801F800000000
+1303:000030301FE0030007800CC00CC0078003001FE0186018600060006000000000
+1304:000060603FC006000F001980188019800F000C000E0007F03F9830F000000000
+1305:000030301FE0030007800CC00C7C0CCC07800600070003001FE0186000000000
+1306:000030301FE0030007800CC00CC0078007F00C30180018001800180000000000
+1307:000030301FE0030007800CC00CC0078003001FE0186018600060006003FC070E
+1308:0000000000000F8018C018C000C000C000C00180018001800180018000000000
+1309:0000000000001F003180318001800180018003F8031803000300030000000000
+130A:0000000000000F8018C018C000C000C000C0018001800180019801F800000000
+130B:00000000000007800FE00C6000600060006000C001C007800E000C0000000000
+130C:0000000000000F8018C018C000C000C000C00180018001F0019801F000000000
+130D:0000000000000FE019B00F300030003000600060006000600060006000000000
+130E:0000000001000100010007C00C600C600060004000C000C000C000C000000000
+130F:0000000001000100010007C00C600C600060004000C000C00CC00FC00C000000
+1310:0000000000001F00318031800180018001F803AC033803000300030000000000
+1311:00007FFE7B8E73F67BC67BF6718E7FFE7FFE7BEE73CE7BEE7BEE71C67FFE0000
+1312:0000000000001F0031803180018001B001B003F0031C030C0300030000000000
+1313:00000000000007800CC00CC000C007E006600060006000600060006000000000
+1314:0000000000000F8018C018C000C000C000C001800180018001F0019807F00C00
+1315:0000000000001F0031B031B001FC018C01800380030003000300030000000000
+1316:00007FFE7B8E73F67BC67BF6718E7FFE7FFE7BCE73BE7B8E7BB671CE7FFE0000
+1317:00007FFE7B8E73F67BC67BF6718E7FFE7FFE7B8673F67BEE7BDE71DE7FFE0000
+1318:000000000C3007E0000007C00C600C600060004000C000C000C000C000000000
+1319:0000000030C01F8000001F00318031800180018003F803180300030000000000
+131A:0000000018600FC000000F8018C018C000C0008001800180019801F800000000
+131B:000000000C3007E0000003C007F004300030003000E003C007000E0000000000
+131C:0000000018600FC000000F8018C018C000C00080018001F0019801F000000000
+131D:0000000018600FC000000FE019B00F3000300020006000600060006000000000
+131E:000000000C6007C0010007C00C600C600060004000C000C000C000C000000000
+131F:0000000018600FC002000F8018C018C000C000800180018001800FF00C300000
+1320:000000000000000007C00D600D60193019301930193019301930193000000000
+1321:00000000000000001F003580358064C064C064FC64CC64C064C064C000000000
+1322:00000000000000001F003580358064C064C064C064C064C064CC64FC00000000
+1323:00000000000007C00D600D601930193019301930003000300030003000000000
+1324:0000000000001F003580358064C064C064C064C064C064F864CC64F800000000
+1325:0000000000000FE01FF013303318339831980180018001800180018000000000
+1326:00000000000007C00D600D601930193019301930180018001800180000000000
+1327:00000000000007C00D600D601930193019301930003000300030003000FC0186
+1328:00000000000000001F803FC06260C230C230C230F338DAB6CAB2FBBE00000000
+1329:00000000000000001F803FC06260C230C23FC233F338DAB4CAB2FBBE00000000
+132A:00000000000000001F803FC06260C230C230C230F330DAB0CAB3FBBF00000000
+132B:000000000FE01FF0311861187198695865587DD8001800340032003E00000000
+132C:00000000000000001F803FC06260C23FC239C237F330DABCCAB2FBBE00000000
+132D:0000000000001FC07FE0C630E6389724F33C030003800340032003E000000000
+132E:000000000FE01FF01A183218231862946252639C7000680064007C0000000000
+132F:0000000000000FE01FF0311861187198695865587DD800180030003000FC0186
+1330:0000000001800180018003C00660066003C007E00E700C300C300C3000000000
+1331:000000000600060006000F00198019800F001F8039C030FC30CC30C000000000
+1332:000000000600060006000F00198019800F001F8039C030C030CC30FC00000000
+1333:0000000001800180018003C0066003C007E00E700C700C300030003000000000
+1334:000000000600060006000F00198019800F001F8039C030F830CC30F800000000
+1335:000000000600060006000F0019F819980F001F8039C030C030C030C000000000
+1336:0000000001800180018003C0066003C007E00E700C300C300C000C0000000000
+1337:0000000003000300030007800CC007800FC01CC018E018600060006001F8030C
+1338:0000000000000000018003C00660066003C007E00E700C300C300C3000000000
+1339:000000000000000006000F00198019800F001F8039C030FC30CC30C000000000
+133A:000000000000000006000F00198019800F001F8039C030C030CC30FC00000000
+133B:000000000000030007800CC00CC007800FC01CC018E018600060006000000000
+133C:000000000000000006000F00198019800F001F8039C030F030D830F000000000
+133D:000000000000000006000F0019F819980F001F8039C030C030C030C000000000
+133E:000000000000030007800CC00CC007800FC01CE0186018601800180000000000
+133F:000000000000030007800CC00CC007800FC01CC018E018600060006001F8030C
+1340:00000000000001E006300C300C300C300FF00C300C300C3007F0060000000000
+1341:000000000000078018C030C030C030C03FC030FC30CC30C01FC0180000000000
+1342:000000007E00C300C300FF00C300C3007F00030003000300033003F000000000
+1343:00007EC3C3FFC3C37F03030303030000
+1344:000000007E00C300C300FF00C300C3007F000300030003E0033003E000000000
+1345:000001800180018007E00E300C300C300FF00C300C300C3007F0060000000000
+1346:0000000003C006600C300FF00C300E7007E003C007000C000C000C0000000000
+1347:0000000001E0033036183FF83618073803F001E0038006000600060000000000
+1348:00000000000000C0004000C00180030006000F00198018880FF803E800000000
+1349:000000000000000000800180030006000C001F00191019F01FC0030006000600
+134A:000000000000018000800180030006000C001E30331031301FE00F8000000000
+134B:000000000000000002000300060004000C001C00360033201FF0031003000300
+134C:00000000018000800180030006000C001E00330031301FE807C8007000000000
+134D:00000000000000000F8019C010C0300030003E0033C037401B00030003000300
+134E:00000000000007E00F9018F03000300030003C003A0031301B600FE000000000
+134F:00000000000002000300060004000C001C00360033201FF0031003000FC01860
+1350:000000000C300FF01FF819980180018001800180018001800180018000000000
+1351:000000000C300FF01FF8199801800180018001F8019801800180018000000000
+1352:000000000C300FF01FF81998018001800180018001800180019801F800000000
+1353:000000000C300FF01FF819980180018001800180030006000C00080000000000
+1354:000000000C300FF01FF819980180018001800180018001F0019801F000000000
+1355:000000000C300FF01FF81998018001E000600060006000600060006000000000
+1356:000000000C300FF01FF819980180018003000300060006000600060000000000
+1357:000000000C300FF01FF81998018001800180018001800180018001800FF01C38
+1358:000018180FF0018001800180030007000E001C00186018701C300FE007C00000
+1359:1C1C07F001C00FFC1FFC3144214422843EFC1C7C000800080010001000100000
+135A:000018180FF0018000800180030006000C001E30331031301FE00F8000000000
+135B:00007FFE7B8E73F67BC67BF6718E7FFE7FFE618E6FB6618E7DB6618E7FFE0000
+135C:00007FFE7B8E73F67BC67BF6718E7FFE7FFE61C66FBE61BE7DBE61C67FFE0000
+135D:1998199800000000000000000000000000000000000000000000000000000000
+135E:0180018000000000000000000000000000000000000000000000000000000000
+135F:0C300C3000000000000000000000000000000000000000000000000000000000
+1360:0000000000000180099004200240199819980240042009900180000000000000
+1361:00000000000303000003030000000000
+1362:0000000000000000000006600660000000000660066000000000000000000000
+1363:000000000000000007E000000180018000000180018000000000000000000000
+1364:000000000000000007E0000001800180000001800180000007E0000000000000
+1365:00000000000000000600060000001F8000000600060000000000000000000000
+1366:000000000000000006000600000003C000000600060000000000000000000000
+1367:0000000000000180018000000000018001800000000001800180000000000000
+1368:000000000000018001800C300C30018001800C300C3001800180000000000000
+1369:0000000018300FE0000001800180030007C00C600C6007C000000FE018300000
+136A:000000000C1807F0000001C00360066007C0060007C0036001C007F00C180000
+136B:0000000000000C3007E0000007E006600600060006000600000007E00C300000
+136C:0000000000000C3007E0000003C0066006600660066003C0000007E00C300000
+136D:0000000018300FE000000300030007E00E600C000C6007E000000FE018300000
+136E:000018300FE0000007800FC00CC000C0018001C0036003C000000FE018300000
+136F:000018300FE0000007800FC00CC000C001800100032003E000000FE018300000
+1370:0000000018180FF000000FF00DB00180018001800FF00C3000000FF018180000
+1371:000000000C3007E0000000000660066007E0066006400380000007E00C300000
+1372:0000000000000C3007E00000018001800180018001800180000007E00C300000
+1373:00000000000018180FF0000007E005A0018003C00660066000000FF018180000
+1374:00000000000018180FF0000005E00DB00DB00DB00DB0073000000FF018180000
+1375:0000000018180FF000000DB00DB00DB007F000300030003000000FF018180000
+1376:000000000C3007E0000003E0066003E0006000C000C000C0000007E00C300000
+1377:0000000018180FF000000FF00DB0018001C000C00FF00C3000000FF018180000
+1378:0000000000000C3007E0000003E006B006E00600066003E0000007E00C300000
+1379:00000000000030181FF000001FF016D006C006C006C006C000001FF030180000
+137A:000018300FE0000007C006C0018001C000C001800180018000000FE018300000
+137B:000000000C3007E0000003C0066007C00600030003000300000007E00C300000
+137C:00000000300C1FF800001E7833CC3EF830C018601860186000001FF8300C0000
+137D:00007FFE7B8E73F67BC67BF6718E7FFE7FFE618E7DB67BB677B6778E7FFE0000
+137E:00007FFE7B8E73F67BC67BF6718E7FFE7FFE61867DBE7B8E77BE77867FFE0000
+137F:00007FFE7B8E73F67BC67BF6718E7FFE7FFE61867DBE7B8E77BE77BE7FFE0000
+1380:000000000000000000003FF07FF04490C59F8D159937F1E0F1C0000000000000
+1381:000000003FE07FE0C52C853C8A2FFBE371E0004000400080009800F800000000
+1382:000000001FF83FF86288428845087DF838F800100010003C002403FC03000000
+1383:000000003FE07FE0C53E852A8A2EFBE071E01000100030002000200000000000
+1384:00000000000000000E001F003180318031F831A831B831803180318000000000
+1385:00000000000000000E001F0031B031B031FC318C318031803180318000000000
+1386:00000000000000000E001F003180318031803180318031E031A031E006000600
+1387:0000000000000000038007C00C600C607C7E6C6A0C6E0C600C600C6000000000
+1388:00000000000000C0004000FC0194031C06000F0019B018F00F30000000000000
+1389:000000000000018000B001F0033C060C0C001E00336031E01E60000000000000
+138A:00000000000003000100030006000C001E0011F813A80F3806000C0008000C00
+138B:00000000000000000F8019C010C0300037F03350337033001FE0036003000300
+138C:000000000C300FF01FF819980180018001F801AC01B801800180018000000000
+138D:0000000018601FE03FF0333003000300036003E0031803180300030000000000
+138E:000000000C300FF01FF819980180018001800180018001F001980FF00C000C00
+138F:0000000018601FE03FF033300300030001F801AC01B801800180018000000000
+1390:00000000000000000000000018180000
+1391:000000000000000000000024243C0000
+1392:00001818000000181800000018180000
+1393:00000000000000181800000018180000
+1394:00000000000000000000003C24240000
+1395:00000000000000000000000000000000001800180018003807F0780000000000
+1396:00000000000000000606060E1C600000
+1397:00000000000000000000000000000000000000000000000000007FFE00000000
+1398:00000000000000000000000000000000000000000000480048007FFE00000000
+1399:0000000000606060667E666060600000
+139A:00007FFE7B8E73F67BC67BF6718E7FFE7FFE73866DB671867DB673B67FFE0000
+139B:00007FFE7B8E73F67BC67BF6718E7FFE7FFE738E6DB6718E7DB6738E7FFE0000
+139C:00007FFE7B8E73F67BC67BF6718E7FFE7FFE73C66DBE71BE7DBE73C67FFE0000
+139D:00007FFE7B8E73F67BC67BF6718E7FFE7FFE738E6DB671B67DB6738E7FFE0000
+139E:00007FFE7B8E73F67BC67BF6718E7FFE7FFE73866DBE718E7DBE73867FFE0000
+139F:00007FFE7B8E73F67BC67BF6718E7FFE7FFE73866DBE718E7DBE73BE7FFE0000
+13A0:00000000782422222222222224780000
+13A1:00000000784442447850484444430000
+13A2:000000007F4908080808080808080000
+13A3:000000001C0814122151515155560000
+13A4:000000003048484B494E484848300000
+13A5:000000000008080008080808083E0000
+13A6:000000003C424240207F0442423C0000
+13A7:000000001C02725252526242423C0000
+13A8:000000007020222A3E20202020700000
+13A9:000000004242424242261A02023C0000
+13AA:0000000018242442427E424242420000
+13AB:000000001F0404040404044444380000
+13AC:000000007E4040407C404040407E0000
+13AD:0000000010101010507E521414180000
+13AE:000000003C220272223C202020200000
+13AF:000000000E111111111F111155770000
+13B0:000000007C1010121E121010107C0000
+13B1:000000007E4240404040404040400000
+13B2:000000001824242424185B595A240000
+13B3:000000005252524A5A5A666642420000
+13B4:00000000040A0A083844444444380000
+13B5:000000003C4242524C40404040400000
+13B6:000000003C424240484C4A4244380000
+13B7:00000000424266665A5A424242420000
+13B8:000000003864620242725E0202020000
+13B9:00000000180A15207C541414141C0000
+13BA:00000000324A4A4A4E4E4A4A4A320000
+13BB:00000000424242427E42424242420000
+13BC:000000003810384402020242423C0000
+13BD:000000004742424242261A02723C0000
+13BE:000000003C424242427E4242423C0000
+13BF:000000002078202020202027221E0000
+13C0:000000003C424240404E4242463A0000
+13C1:00000000304848484444444242470000
+13C2:00000040404040405C62424242420000
+13C3:000000007E42020408102040427E0000
+13C4:000000001C22720272221E0202020000
+13C5:00000000304848484A4F484848300000
+13C6:000000007F49080808080808497F0000
+13C7:000000000C1202424A4A4A4A4A340000
+13C8:00000000245A4A162848484848300000
+13C9:00000000672524242828282828100000
+13CA:000000004141414149555151512E0000
+13CB:000000003C4240403C404046423C0000
+13CC:0000000077222222223E2222221C0000
+13CD:000000000609090909011D6959660000
+13CE:00000000040C142444447E0404040000
+13CF:0000000070202020203C2222227C0000
+13D0:000000001C0808080B5D6808081C0000
+13D1:00000000724D7127407C4242423C0000
+13D2:000000007844424478504844444E0000
+13D3:000000007020202020202022221C0000
+13D4:00000000555555495959656543410000
+13D5:000000003C424F40201F0442423C0000
+13D6:000000007E50101010101013110E0000
+13D7:000000000702020202060A1222470000
+13D8:000000007F42020202060A1222470000
+13D9:00000000414141222222141408080000
+13DA:000000003C424240300C0242423C0000
+13DB:00000000364962504848484828100000
+13DC:00000000182418242255555555220000
+13DD:000000001824404040404042427E0000
+13DE:000000004040404040404042427E0000
+13DF:000000003C42424040404042423C0000
+13E0:000000000722527F12121212120C0000
+13E1:00000000245A595B1824242424180000
+13E2:000000007C4242427C40404040400000
+13E3:000000003C42474040464642423C0000
+13E4:000000007B5112121414141818100000
+13E5:00000040404040434D74444444440000
+13E6:00000000424448506060504844420000
+13E7:00000000070202021E224242221C0000
+13E8:0000000030484A454040454A48300000
+13E9:0000000038444C4C40404E44443B0000
+13EA:00000000225555535131115955620000
+13EB:000000003C424272525E4242423C0000
+13EC:000000002255515161414141221C0000
+13ED:00000000081412120A06026264380000
+13EE:000000003C464640407C4242423C0000
+13EF:0000000006090101015D49492A140000
+13F0:000000001C2222223C222262322C0000
+13F1:000000001C081C222242424A524C0000
+13F2:0000003C424240405C62424242420000
+13F3:0000000030484A4540405C4848300000
+13F4:000000007C4242427C424242427C0000
+13F5:00007FFE7B8E73F67BC67BF6718E7FFE7FFE61866FBE63866FF66F867FFE0000
+13F6:00007FFE7B8E73F67BC67BF6718E7FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+13F7:00007FFE7B8E73F67BC67BF6718E7FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+13F8:00007FFE7B8E73F67BC67BF6718E7FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+13F9:00007FFE7B8E73F67BC67BF6718E7FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+13FA:00007FFE7B8E73F67BC67BF6718E7FFE7FFE61866FB663866FB66FB67FFE0000
+13FB:00007FFE7B8E73F67BC67BF6718E7FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+13FC:00007FFE7B8E73F67BC67BF6718E7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+13FD:00007FFE7B8E73F67BC67BF6718E7FFE7FFE618E6FB663B66FB66F8E7FFE0000
+13FE:00007FFE7B8E73F67BC67BF6718E7FFE7FFE61866FBE638E6FBE6F867FFE0000
+13FF:00007FFE7B8E73F67BC67BF6718E7FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+1400:0000000000007E0000007E0000000000
+1401:0000007F412222221414140808080000
+1402:081408000808141414222222417F0000
+1403:000000080808141414222222417F0000
+1404:080800080808141414222222417F0000
+1405:00000040605048444244485060400000
+1406:10100040605048444244485060400000
+1407:24240040605048444244485060400000
+1408:00000040605048545254485060400000
+1409:00000040605048445244485060400000
+140A:00000002060A12224222120A06020000
+140B:10100002060A12224222120A06020000
+140C:0000007F412222221454540808080000
+140D:0000007F412222221415150808080000
+140E:000000080808545414222222417F0000
+140F:000000080808151514222222417F0000
+1410:080800080808545414222222417F0000
+1411:080800080808151514222222417F0000
+1412:00000000101814525112141810000000
+1413:00000000406050494548506040000000
+1414:00080800101814525112141810000000
+1415:00202000406050494548506040000000
+1416:20200040625248444244485060400000
+1417:00000000010305495109050301000000
+1418:00000000040C14254524140C04000000
+1419:00020200010305495109050301000000
+141A:00080800040C14254524140C04000000
+141B:04040002464A12224222120A06020000
+141C:00000049494936000000000000000000
+141D:0000040A247020000000000000000000
+141E:0000001028447C000000000000000000
+141F:00000004081020000000000000000000
+1420:00000020100804000000000000000000
+1421:0000004141221C000000000000000000
+1422:0000001C224141000000000000000000
+1423:00000030080404083000000000000000
+1424:00000018242418000000000000000000
+1425:00000009122448000000000000000000
+1426:00000024242424000000000000000000
+1427:00000000000000103810000000000000
+1428:0000007C000000000000000000000000
+1429:00000010107C10100000000000000000
+142A:0000007C101010000000000000000000
+142B:0402017F412222221414140808080000
+142C:000402090808141414222222417F0000
+142D:00080442605048444244485060400000
+142E:08040200060A12224222120A06020000
+142F:00000041412222221414140808080000
+1430:08140800080814141422222241410000
+1431:00000008080814141422222241410000
+1432:08080008080814141422222241410000
+1433:00000040201008040204081020400000
+1434:10100040201008040204081020400000
+1435:24240040201008040204081020400000
+1436:00000040201008242224081020400000
+1437:00000040201008042204081020400000
+1438:00000002040810204020100804020000
+1439:10100002040810204020100804020000
+143A:00000041412222221454540808080000
+143B:00000041412222221415150808080000
+143C:00000008080854541422222241410000
+143D:00000008080815151422222241410000
+143E:08080008080854541422222241410000
+143F:08080008080815151422222241410000
+1440:00000000100804424102040810000000
+1441:00000000402010090508102040000000
+1442:00080800100804424102040810000000
+1443:00202000402010090508102040000000
+1444:00000000010204485008040201000000
+1445:00000000040810214120100804000000
+1446:00020200010204485008040201000000
+1447:00080800040810214120100804000000
+1448:24240002040810204020100804020000
+1449:00000004081020100804000000000000
+144A:00000010101010000000000000000000
+144B:00000040506848480000000000000000
+144C:000000414141414141414141221C0000
+144D:0814081C224141414141414141410000
+144E:0000001C224141414141414141410000
+144F:0808001C224141414141414141410000
+1450:000000700C020201010102020C700000
+1451:080800700C020201010102020C700000
+1452:121200700C020201010102020C700000
+1453:000000700C020221212102020C700000
+1454:000000700C020201210102020C700000
+1455:00000007182020404040202018070000
+1456:08080007182020404040202018070000
+1457:000000111111111151511111110E0000
+1458:00000044444444444545444444380000
+1459:0000000E111111515111111111110000
+145A:00000038444444454544444444440000
+145B:0404000E111111515111111111110000
+145C:10100038444444454544444444440000
+145D:0000001C0202014141010102021C0000
+145E:00000070080804050504040808700000
+145F:0808001C0202014141010102021C0000
+1460:20200070080804050504040808700000
+1461:00000007080810505010100808070000
+1462:0000001C2020404141404020201C0000
+1463:02020007080810505010100808070000
+1464:0808001C2020404141404020201C0000
+1465:00000007080850501050500808070000
+1466:0000001C20404040201C000000000000
+1467:00000045454544444444444444380000
+1468:00000039454544444444444444440000
+1469:000101710C020201010102020C700000
+146A:0001011D2020404040404020201C0000
+146B:000000384444443C0404040404040000
+146C:10281038444444784040404040400000
+146D:00000038444444784040404040400000
+146E:10100038444444784040404040400000
+146F:0000000404040404043C444444380000
+1470:0404000404040404043C444444380000
+1471:0A0A000404040404043C444444380000
+1472:00000040404040404078444444380000
+1473:40400040404040404078444444380000
+1474:0000000E1111514F0101010101010000
+1475:000000384444453D0404040404040000
+1476:0000000E1111515E1010101010100000
+1477:00000038444445794040404040400000
+1478:0404000E1111515E1010101010100000
+1479:10100038444445794040404040400000
+147A:0000000101010101414F1111110E0000
+147B:0000000404040404053D444444380000
+147C:0101000101010101414F1111110E0000
+147D:0404000404040404053D444444380000
+147E:0000001010101010505E1111110E0000
+147F:00000040404040404179444444380000
+1480:1010001010101010505E1111110E0000
+1481:40400040404040404179444444380000
+1482:0000001010105050105E5111110E0000
+1483:00000020202038242418000000000000
+1484:0000000404041C242418000000000000
+1485:000000394545443C0404040404040000
+1486:00000039454544784040404040400000
+1487:0000000505050404043C444444380000
+1488:00000041414140404078444444380000
+1489:00000038444444040404040404040000
+148A:10281038444444404040404040400000
+148B:00000038444444404040404040400000
+148C:10100038444444404040404040400000
+148D:00000004040404040404444444380000
+148E:04040004040404040404444444380000
+148F:0A0A0004040404040404444444380000
+1490:00000040404040404040444444380000
+1491:40400040404040404040444444380000
+1492:0000000E111151410101010101010000
+1493:00000038444445050404040404040000
+1494:0000000E111151501010101010100000
+1495:00000038444445414040404040400000
+1496:0404000E111151501010101010100000
+1497:10100038444445414040404040400000
+1498:000000010101010141411111110E0000
+1499:00000004040404040505444444380000
+149A:010100010101010141411111110E0000
+149B:04040004040404040505444444380000
+149C:000000101010101050501111110E0000
+149D:00000040404040404141444444380000
+149E:101000101010101050501111110E0000
+149F:40400040404040404141444444380000
+14A0:000000101010505010505111110E0000
+14A1:00000020202020242418000000000000
+14A2:00000004040404242418000000000000
+14A3:0000007C040404040404040404040000
+14A4:1028107C404040404040404040400000
+14A5:0000007C404040404040404040400000
+14A6:1010007C404040404040404040400000
+14A7:000000040404040404040404047C0000
+14A8:040400040404040404040404047C0000
+14A9:0A0A00040404040404040404047C0000
+14AA:000000404040404040404040407C0000
+14AB:404000404040404040404040407C0000
+14AC:0000001F010141410101010101010000
+14AD:0000007C040405050404040404040000
+14AE:0000001F101050501010101010100000
+14AF:0000007C404041414040404040400000
+14B0:0404001F101050501010101010100000
+14B1:1010007C404041414040404040400000
+14B2:000000010101010141410101011F0000
+14B3:000000040404040405050404047C0000
+14B4:010100010101010141410101011F0000
+14B5:040400040404040405050404047C0000
+14B6:000000101010101050501010101F0000
+14B7:000000404040404041414040407C0000
+14B8:101000101010101050501010101F0000
+14B9:404000404040404041414040407C0000
+14BA:000000101010505010505010101F0000
+14BB:0000002020202020203C000000000000
+14BC:0000000C102020100C00000000000000
+14BD:0000000404040404043C000000000000
+14BE:000000182408103C0000000000000000
+14BF:000000003C42020204081020427E0000
+14C0:00000000000000007E09090909060000
+14C1:00000000081408003F48484848300000
+14C2:00000000000000003F48484848300000
+14C3:00000000000808003F48484848300000
+14C4:000000000000000006090909097E0000
+14C5:000000000002020006090909097E0000
+14C6:000000000009090006090909097E0000
+14C7:000000000000000030484848483F0000
+14C8:000000000020200030484848483F0000
+14C9:00000000000000005E45050505020000
+14CA:00000000000000007915141414080000
+14CB:000000000000000048541414140F0000
+14CC:000000000000000031494848483E0000
+14CD:000000000008080048541414140F0000
+14CE:000000000020200031494848483E0000
+14CF:000000000048480030484848483F0000
+14D0:0000002050503F000000000000000000
+14D1:000000414141221C0000000000000000
+14D2:0000000205057E000000000000000000
+14D3:00000000000000007E01010101060000
+14D4:00000000081408003F40404040300000
+14D5:00000000000000003F40404040300000
+14D6:00000000000808003F40404040300000
+14D7:000000000000000006010101017E0000
+14D8:000000000002020006010101017E0000
+14D9:000000000009090006010101017E0000
+14DA:000000000000000030404040403F0000
+14DB:000000000020200030404040403F0000
+14DC:00000000000000005E41010101020000
+14DD:00000000000000007905040404080000
+14DE:00000000000000004F50101010080000
+14DF:00000000000000003D41404040200000
+14E0:00000000000404004F50101010080000
+14E1:00000000001010003D41404040200000
+14E2:000000000000000042410101013E0000
+14E3:00000000000000000905040404780000
+14E4:000000000004040042410101013E0000
+14E5:00000000000808000905040404780000
+14E6:000000000000000048501010100F0000
+14E7:000000000000000021414040403E0000
+14E8:000000000004040048501010100F0000
+14E9:000000000010100021414040403E0000
+14EA:0000002040403F000000000000000000
+14EB:0000000C300C300C0000000000000000
+14EC:000000061860300C020C306018060000
+14ED:00000040404040201C04040404040000
+14EE:040A0400040404087040404040400000
+14EF:00000004040404087040404040400000
+14F0:04040004040404087040404040400000
+14F1:00000004040404041C20404040400000
+14F2:04040004040404041C20404040400000
+14F3:0A0A0004040404041C20404040400000
+14F4:00000040404040407008040404040000
+14F5:40400040404040407008040404040000
+14F6:00000010101050480701010101010000
+14F7:00000040404041211C04040404040000
+14F8:00000001010141421C10101010100000
+14F9:00000004040405097040404040400000
+14FA:01010001010141421C10101010100000
+14FB:04040004040405097040404040400000
+14FC:00000001010141410708101010100000
+14FD:00000004040405051C20404040400000
+14FE:01010001010141410708101010100000
+14FF:04040004040405051C20404040400000
+1500:00000010101050501C02010101010000
+1501:00000040404041417008040404040000
+1502:10100010101050501C02010101010000
+1503:40400040404041417008040404040000
+1504:00000010101050501C42410101010000
+1505:00000020202030080808000000000000
+1506:0000003C42403C02423C000000000000
+1507:00000008080818202020000000000000
+1508:0000004040403E000000000000000000
+1509:00000020202030081828100000000000
+150A:00000008080818203028100000000000
+150B:20200020202030080800080800000000
+150C:2000200000002008201020203040088009000080084008200010000800000000
+150D:200020000000201C206020803080090009000100088008800060001C00000000
+150E:20002000000020802080208030800880088000F0088808880088007000000000
+150F:2000200000002080208020803080088008800080088808880088007000000000
+1510:00000030484848080808090909060000
+1511:00000006090909080808484848300000
+1512:08080006090909080808484848300000
+1513:00000006010101013E40404040300000
+1514:08080006010101013E40404040300000
+1515:00000030404040403E01010101060000
+1516:08080030404040403E01010101060000
+1517:00000008141414444404050505020000
+1518:00000020505050111110141414080000
+1519:00000002050505444404141414080000
+151A:00000008141414111110505050200000
+151B:00080802050505444404141414080000
+151C:00202008141414111110505050200000
+151D:00000002010101014E50101010080000
+151E:00000008040404043941404040200000
+151F:04040002010101014E50101010080000
+1520:20200008040404043941404040200000
+1521:00000008101010104E41010101020000
+1522:00000020404040403905040404080000
+1523:02020008101010104E41010101020000
+1524:10100020404040403905040404080000
+1525:0000002040403E010102000000000000
+1526:00000002040810207E02020202020000
+1527:20502040201008047E40404040400000
+1528:00000040201008047E40404040400000
+1529:20200040201008047E40404040400000
+152A:00000002020202027E20100804020000
+152B:02020002020202027E20100804020000
+152C:12120002020202027E20100804020000
+152D:00000040404040407E04081020400000
+152E:40400040404040407E04081020400000
+152F:00000001020408505F01010101010000
+1530:00000004081020417D04040404040000
+1531:00000010080402415F10101010100000
+1532:00000040201008057D40404040400000
+1533:10100010080402415F10101010100000
+1534:40400040201008057D40404040400000
+1535:00000001010101015F50080402010000
+1536:00000004040404047D41201008040000
+1537:01010001010101015F50080402010000
+1538:04040004040404047D41201008040000
+1539:00000010101010105F41020408100000
+153A:00000040404040407D05081020400000
+153B:10100010101010105F41020408100000
+153C:40400040404040407D05081020400000
+153D:00000010101050501F41420408100000
+153E:00000020203C08102000000000000000
+153F:00000000282854540000000000000000
+1540:00000010107C10100000000000000000
+1541:00000044281028440000000000000000
+1542:00000000000000000047444444380000
+1543:000000000000000000711111110E0000
+1544:0000000000000000000E111111710000
+1545:00000000001028100038444444470000
+1546:00000000000000000038444444470000
+1547:00000000000010100038444444470000
+1548:00000070080404087040404040400000
+1549:20200070080404087040404040400000
+154A:00000040404040407008040408700000
+154B:0000001C204040201C04040404040000
+154C:0808001C204040201C04040404040000
+154D:00000004040404041C204040201C0000
+154E:02020007081010484701010101010000
+154F:0808001C204040211D04040404040000
+1550:00000018201808080000000000000000
+1551:000000300C300C300000000000000000
+1552:0000006018060C3040300C0618600000
+1553:00000031493222221414140808080000
+1554:08140800080814141422223249310000
+1555:00000008080814141422223249310000
+1556:08080008080814141422223249310000
+1557:00000020502804020102040810200000
+1558:08080020502804020102040810200000
+1559:00000002050A10204020100804020000
+155A:08080002050A10204020100804020000
+155B:0404000002050A90A010080402000000
+155C:08080000040A14214120100804000000
+155D:00000008142840201008000000000000
+155E:000000314971414141414141221C0000
+155F:000000464947414141414141221C0000
+1560:0000001C224141414141417149310000
+1561:0000001C224141414141414749460000
+1562:0808001C224141414141417149310000
+1563:0808001C224141414141414749460000
+1564:000000304C320201010102020C700000
+1565:080800304C320201010102020C700000
+1566:00000006192620404040202018070000
+1567:08080006192620404040202018070000
+1568:02020006090E10505010100808070000
+1569:080800182438404141404020201C0000
+156A:0000001834484040201C000000000000
+156B:000000494949494949414141221C0000
+156C:0000001C224141414949494949490000
+156D:000000700C020201790102020C700000
+156E:00000007182020404F40202018070000
+156F:0000000000002AA81C703EF81C702AA800000000000000000000000000000000
+1570:000000555555555549414141221C0000
+1571:0000001C224141414955555555550000
+1572:000000700C027209090972020C700000
+1573:00000007182027484848272018070000
+1574:000000384444443C0404040506040000
+1575:0000000E1111111E1010105030100000
+1576:0404000E1111111E1010105030100000
+1577:0000000406050404043C444444380000
+1578:0404000406050404043C444444380000
+1579:0000001030501010101E1111110E0000
+157A:1010001030501010101E1111110E0000
+157B:00000020602038242418000000000000
+157C:00000042424242427E42424242420000
+157D:00000044281028440000000000000000
+157E:002000500020187020881888088808F000800080008000800080008000000000
+157F:000000000000187020881888088808F000800080008000800080008000000000
+1580:002000200000187020881888088808F000800080008000800080008000000000
+1581:0000000000001808200818080808080800080078008800880088007000000000
+1582:0008000800001808200818080808080800080078008800880088007000000000
+1583:00000000000018802080188008800880008000F0008800880088007000000000
+1584:00800080000018802080188008800880008000F0008800880088007000000000
+1585:00000034443615120000000000000000
+1586:000000384444443C1414242444440000
+1587:00000038444444785050484844440000
+1588:0000004444242414143C444444380000
+1589:00000044444848505078444444380000
+158A:00000038444444040404040506040000
+158B:0000000E111111101010105030100000
+158C:00000004060504040404444444380000
+158D:000000103050101010101111110E0000
+158E:0004000A3004480E48113C110491049003100010001000100010001000000000
+158F:000000003000480E48113C110491049003100010001000100010001000000000
+1590:000400043000480E48113C110491049003100010001000100010001000000000
+1591:000000003000480148013C010481048103010001001100110011000E00000000
+1592:000100013000480148013C010481048103010001001100110011000E00000000
+1593:000000003000481048103C100490049003100010001100110011000E00000000
+1594:001000103000481048103C100490049003100010001100110011000E00000000
+1595:00003048483C05050200000000000000
+1596:0000000031804A404A403FF80009000900060000000000000000000000000000
+1597:0000003C425A4A320202020202020000
+1598:0000003C425A524C4040404040400000
+1599:000000020202020202324A5A423C0000
+159A:0000004040404040404C525A423C0000
+159B:0000000000007E007E09090909060000
+159C:0000000000003F003F48484848300000
+159D:0000000000007E0006090909097E0000
+159E:0000000000003F0030484848483F0000
+159F:0000003F002050503F00000000000000
+15A0:00000000000004023F40404040300000
+15A1:00000000001014023F40404040300000
+15A2:000000000000000006010101017E2010
+15A3:000000000002020006010101017E2010
+15A4:000000000000000030404040403F0204
+15A5:000000000020200030404040403F0204
+15A6:0000002040403F020000000000000000
+15A7:00000002040810207C04041F04040000
+15A8:00000020100804021F10107C10100000
+15A9:10100020100804021F10107C10100000
+15AA:00000004041F04047C20100804020000
+15AB:04040004041F04047C20100804020000
+15AC:00000010107C10101F02040810200000
+15AD:10100010107C10101F02040810200000
+15AE:0000002070203C081020000000000000
+15AF:00000040404040405C624141625C0000
+15B0:0000005C7E7F7F7E5C40404040400000
+15B1:00000001010101011D3F7F7F3F1D0000
+15B2:00000040404040405C7E7F7F7E5C0000
+15B3:0000001D3F7F7F3F1D01010101010000
+15B4:0000007C4040407C4040404040400000
+15B5:0000000404040404047C0404047C0000
+15B6:0000004040404040407C4040407C0000
+15B7:0000007C0404047C0404040404040000
+15B8:0000007252524C404040404040400000
+15B9:00000002020202020202324A4A4E0000
+15BA:000000404040404040404C5252720000
+15BB:0000004E4A4A32020202020202020000
+15BC:00000041625448404040404040400000
+15BD:00000001010101010101091523410000
+15BE:00000040404040404040485462410000
+15BF:00000041231509010101010101010000
+15C0:00000001010101013945454503010000
+15C1:00000040404040404E51515160400000
+15C2:00000003454545390101010101010000
+15C3:000000605151514E4040404040400000
+15C4:000000414122223E1414140808080000
+15C5:0000000808081414143E222241410000
+15C6:00000040201018141214181020400000
+15C7:00000040201018545254181020400000
+15C8:00000040201018145214181020400000
+15C9:00000002040818284828180804020000
+15CA:000000417F2222221414140808080000
+15CB:0000000808081414142222227F410000
+15CC:00000040203028242224283020400000
+15CD:00000040203028343234283020400000
+15CE:00000040203028243224283020400000
+15CF:00000002040C14244424140C04020000
+15D0:00000049492A2A2A1C1C1C0808080000
+15D1:0000000808081C1C1C2A2A2A49490000
+15D2:00000040201008047E04081020400000
+15D3:00000040201028247E24281020400000
+15D4:00000040201008347E34081020400000
+15D5:00000002040810207E20100804020000
+15D6:00000049493E2A2A1C1C1C0808080000
+15D7:0000000808081C1C1C2A2A3E49490000
+15D8:00000040301814127F12141830400000
+15D9:0000004020105854FE54581020400000
+15DA:0000004020101874FE74181020400000
+15DB:00000001060C14247F24140C06010000
+15DC:0000007E424242424242424224180000
+15DD:000000182442424242424242427E0000
+15DE:00000078444242424242424244780000
+15DF:00000078444242525252424244780000
+15E0:000000784442425A5A42424244780000
+15E1:0000001E2242424242424242221E0000
+15E2:00000042665A42424242424224180000
+15E3:00000018244242424242425A66420000
+15E4:00000078444222221222224244780000
+15E5:000000784442222A1A2A224244780000
+15E6:000000F08C82425A3A4242828CF00000
+15E7:0000001E2242444448444442221E0000
+15E8:00000042427E42424242424224180000
+15E9:00000018244242424242427E42420000
+15EA:000000F8242222222222222224F80000
+15EB:000000F82422222A2A2A222224F80000
+15EC:000000F04C42425A5A4242424CF00000
+15ED:0000003E4888888888888888483E0000
+15EE:0000001010107C000000000000000000
+15EF:0000004949494949494949492A140000
+15F0:000000142A4949494949494949490000
+15F1:00000078040202027C02020204780000
+15F2:00000078040202127C12020204780000
+15F3:000000700C0202327C3202020C700000
+15F4:0000001E204040403E404040201E0000
+15F5:0000007F49494949494949492A140000
+15F6:000000142A49494949494949497F0000
+15F7:00000078444242427C42424244780000
+15F8:00000078444242527C52424244780000
+15F9:000000F08C8282B2FCB282828CF00000
+15FA:0000001E224242423E424242221E0000
+15FB:000000496B5D4949494949492A140000
+15FC:000000142A4949494949495D6B490000
+15FD:00000078444222227E22224244780000
+15FE:000000784442222A7E2A224244780000
+15FF:000000F08C82425AFE5A42828CF00000
+1600:0000001E224244447E444442221E0000
+1601:00000000442810000000000000000000
+1602:00000040404040404042424224180000
+1603:00000018244242420202020202020000
+1604:000000000000000000FC0202020C0000
+1605:000000000000000000FC0222220C0000
+1606:000000000000000000FC0262620C0000
+1607:000000000000000000608080807E0000
+1608:0000004040404040404949492A140000
+1609:000000142A4949490101010101010000
+160A:00000078040202021C02020204180000
+160B:00000078040202121C12020204180000
+160C:000000F00C0202327C3202020C300000
+160D:000000182040404038404040201E0000
+160E:0000004C5252524A4242424224180000
+160F:000000182442424242524A4A4A320000
+1610:00000000007804020232424244380000
+1611:00000000007804021232524244380000
+1612:00000000007804021A3E5A4244380000
+1613:00000000001C2242424C4040201E0000
+1614:00000000FE040810204098A484780000
+1615:00000000FE4020100804324A423C0000
+1616:0000003C424A320408102040FE000000
+1617:000000000000000000000000000020E02110220824C82908311020E000000000
+1618:000000000000000000000000000020E02110224824C82948311020E000000000
+1619:000000000000000000000000000020E02110226824F82968311020E000000000
+161A:000000000000000000000000000020E03110290824C82208211020E000000000
+161B:00000000000000000000000000000E08111821282648208811080E0800000000
+161C:000008200440028001000200040009C00A200A1009100410022001C000000000
+161D:0000038004400820089008500450039000200040008001400220041000000000
+161E:000000000000000020F011080A64049208821082204400380000000000000000
+161F:000000000000000020F011080A04041208721092204400380000000000000000
+1620:000000000000000020F011080A04041A087A109A204400380000000000000000
+1621:00000000000000001C002204410841104920265010880F040000000000000000
+1622:0000000000000000000000000000000000001F8801080208011000E000000000
+1623:000000000000000000000000000000000000070008801040108011F800000000
+1624:00000000404040506844040408700000
+1625:00000000404040506844141408700000
+1626:00000000404040506844343408700000
+1627:00000000040404142C444040201C0000
+1628:0000000000000000000000000000100010001F8811081208011000E000000000
+1629:000000000000000000000000000000000000070008801048108811F800080008
+162A:00000000F82020283422020204380000
+162B:00000000F820202834220A0A04380000
+162C:00000000F820202834221A1A04380000
+162D:000000001F0404142C444040201C0000
+162E:00000000000000C64482828244380000
+162F:00000000000000384482828244C60000
+1630:00000000000000B8C4020202C4B80000
+1631:00000000000000B8C4121212C4B80000
+1632:00000000000000B8C41A3E1AC4B80000
+1633:000000000000003A46808080463A0000
+1634:00000000000000000000000800080C7804480828082008200440038000000000
+1635:000000000000000000000000000001C0022004100410141012201E3010001000
+1636:0000000000F0405C62010101625C0000
+1637:0000000000F0405C62090909625C0000
+1638:0000000000F0405C620D1F0D625C0000
+1639:00000000000F023A46808080463A0000
+163A:000000040004203C2024222422202220222022202220222012400D8000000000
+163B:0000000000000000036004900888088808880888088808884888480878084000
+163C:00000000F800200020003FE00010000800080FF00008000800103FE000000000
+163D:00000000F800200020003FE00010080808080FF00808080800103FE000000000
+163E:00000000F800200020003FE00010000806080FF00608000800103FE000000000
+163F:00000000003E000800080FF81000200020001FE02000200010000FF800000000
+1640:00000082444444444444444428100000
+1641:00000010284444444444444444820000
+1642:0000000000000000000010000FF0000800080008000800080FF0100000000000
+1643:0000000000000000000010000FF0000800880088008800080FF0100000000000
+1644:0000000000000000000010000FF0000800C801E800C800080FF0100000000000
+1645:0000000000000000000000080FF0100010001000100010000FF0000800000000
+1646:0000000000FE0408102040FE00000000
+1647:0000001010FE1418103050FE10100000
+1648:000000BA545444444444444428100000
+1649:00000010284444444444445454BA0000
+164A:0000000000000000000010000FF0000810081C08100800080FF0100000000000
+164B:0000000000000000000010000FF0000810881C88108800080FF0100000000000
+164C:0000000000000000000010000FF0000810C81DE810C800080FF0100000000000
+164D:0000000000000000000000080FF0100010081038100810000FF0000800000000
+164E:000000000000200810101110111011101110111011101110092006C000000000
+164F:000000000000000006C009201110111011101110111011101110101020080000
+1650:000000000000000020001FE00010000800080FF00008000800101FE020000000
+1651:000000000000000020001FE00010080808080FF00808080800101FE020000000
+1652:000000000000000020001FE00010000806080FF00608000800101FE020000000
+1653:000000000000000000080FF01000200020001FE02000200010000FF000080000
+1654:000000000000210811101FF0111011101110111011101110092006C000000000
+1655:000000000000000006C009201110111011101110111011101FF0111021080000
+1656:000000000000000020001FE00810080808083FF00808080808101FE020000000
+1657:000000000000000020001FE00810088808883FF00888088808101FE020000000
+1658:000000000000000020001FE00810080809883FF00988080808101FE020000000
+1659:000000000000000000080FF01020202020201FF82020202010200FF000080000
+165A:00101038545038145438101000000000
+165B:00000000000027C811101FF0111011101110111011101110092006C000000000
+165C:000000000000000006C009201110111011101110111011101FF0111027C80000
+165D:000000000000000020001FE00810280828083FF02808280808101FE020000000
+165E:000000000000000020001FE00810288828883FF02888288808101FE020000000
+165F:000000000000000020001FE00810280829883FF02988280808101FE020000000
+1660:000000000000000000080FF01020202820281FF82028202810200FF000080000
+1661:00000000000027C811101110111011101110111011101110092006C000000000
+1662:000000000000000006C009201110111011101110111011101110111027C80000
+1663:000000000000000020001FE00010200820083FF02008200800101FE020000000
+1664:000000000000000020001FE00010208820883FF02088208800101FE020000000
+1665:000000000000000020001FE00010200821883FF02188200800101FE020000000
+1666:000000000000000000080FF01000200820081FF82008200810000FF000080000
+1667:00000000000027C811101930155013901110111011101110092006C000000000
+1668:000000000000000006C009201110111011101110139015501930111027C80000
+1669:000000000000000020001FE00810240822083FF02208240808101FE020000000
+166A:000000000000000020001FE00810248822883FF02288248808101FE020000000
+166B:000000000000000020001FE00810240822E83FF022E8240808101FE020000000
+166C:000000000000000000080FF01020204820881FF82088204810200FF000080000
+166D:00000062221414080808141422230000
+166E:00000000000000000000000028102800
+166F:0000000000001870208818880888087800080008000800080008000800000000
+1670:000000003000480E48113C110491048103010001000100010001000100000000
+1671:0000000024005A0E5A113F110151015000900010001000100010001000000000
+1672:0004000424005A0E5A113F110151015000900010001000100010001000000000
+1673:0000000024005A015A013F010141014100810001001100110011000E00000000
+1674:0001000124005A015A013F010141014100810001001100110011000E00000000
+1675:0000000024005A105A103F100150015000900010001100110011000E00000000
+1676:0010001024005A105A103F100150015000900010001100110011000E00000000
+1677:00000010102020464680F8083E080000
+1678:000000202010130B08047C40F0400000
+1679:000C0C202010130B08047C40F0400000
+167A:000000083E08F8804646202010100000
+167B:000C0C00083E08F88046462020101000
+167C:00000040F0407C04080B131020200000
+167D:00C0C00040F0407C04080B1310202000
+167E:0010107C107C10100000000000000000
+167F:0000007C007C00000000000000000000
+1680:0000000000000000000000000000FFFF00000000000000000000000000000000
+1681:0000000000000000000000000000FFFF01000100010001000100010000000000
+1682:0000000000000000000000000000FFFF02800280028002800280028000000000
+1683:0000000000000000000000000000FFFF05400540054005400540054000000000
+1684:0000000000000000000000000000FFFF0AA00AA00AA00AA00AA00AA000000000
+1685:0000000000000000000000000000FFFF15501550155015501550155000000000
+1686:0000010001000100010001000100FFFF00000000000000000000000000000000
+1687:0000028002800280028002800280FFFF00000000000000000000000000000000
+1688:0000054005400540054005400540FFFF00000000000000000000000000000000
+1689:00000AA00AA00AA00AA00AA00AA0FFFF00000000000000000000000000000000
+168A:0000155015501550155015501550FFFF00000000000000000000000000000000
+168B:0000000000400040008000800100FFFF01000200020004000400000000000000
+168C:0000000000A000A0014001400280FFFF0280050005000A000A00000000000000
+168D:000000000150015002A002A00540FFFF05400A800A8015001500000000000000
+168E:0000000002A802A8055005500AA0FFFF0AA0154015402A802A80000000000000
+168F:00000000055405540AA80AA81550FFFF15502AA02AA055405540000000000000
+1690:0000000000000000000001000100FFFF01000100000000000000000000000000
+1691:0000000000000000000002800280FFFF02800280000000000000000000000000
+1692:0000000000000000000005400540FFFF05400540000000000000000000000000
+1693:000000000000000000000AA00AA0FFFF0AA00AA0000000000000000000000000
+1694:0000000000000000000015501550FFFF15501550000000000000000000000000
+1695:0000000004400440028002800100FFFF01000280028004400440000000000000
+1696:0000010001000280028004400440FFFF04400440028002800100010000000000
+1697:0000000000000000000000000000FFFF0800080009C0084008400FC000000000
+1698:0000000000000000000000000000FFFF1290092006C006C00920129024480000
+1699:05500FF805500FF805500FF80550FFFF00000000000000000000000000000000
+169A:0000000000000000000000000000FFFF00000FF0000000000000000000000000
+169B:000000002000100008000400020001FF02000400080010002000000000000000
+169C:0000000000040008001000200040FF8000400020001000080004000000000000
+169D:00007FFE7BCE73BE7B8E7BB671CE7FFE7FFE738E6DB671B67DB6738E7FFE0000
+169E:00007FFE7BCE73BE7B8E7BB671CE7FFE7FFE73866DBE718E7DBE73867FFE0000
+169F:00007FFE7BCE73BE7B8E7BB671CE7FFE7FFE73866DBE718E7DBE73BE7FFE0000
+16A0:0092A4C890A0C0808080808080808000
+16A1:00AA94A8D0A0C0808080808080808000
+16A2:0080C0A0908884848484848484848400
+16A3:0080C0A0908884829292929292929200
+16A4:0080C0A090888484B4B4848484848400
+16A5:0080C0A0908884C2A292929292929200
+16A6:00808080C0A090888890A0C080808000
+16A7:00808080C0A090A8A890A0C080808000
+16A8:0080C0A090C8A0908880808080808000
+16A9:0080C2A498C2A4988080808080808000
+16AA:0080C2A498C0A0908080808080808000
+16AB:0080C0A090C8A0908880808080808000
+16AC:00101090503090583412181412101000
+16AD:00101010101018141218141210101000
+16AE:00080808080818284818284808080808
+16AF:00101012141812345890305090101000
+16B0:00101012141810305090305090101000
+16B1:0080C0A09088848890A0A09088848200
+16B2:00000004081020402010080400000000
+16B3:008080808080808080C0A09088848200
+16B4:0082848890A0C0808080808080808000
+16B5:00B2B48890A0C0808080808080808000
+16B6:0042444850E0E0E04040404040404000
+16B7:00828244442828101028284444828200
+16B8:00828244442828545428284444828200
+16B9:0080C0A0908890A0C080808080808000
+16BA:008282828282E2928E82828282828200
+16BB:0082828282E2928EE2928E8282828200
+16BC:00101010925438103854921010101000
+16BD:00101010101038383810101010101000
+16BE:00101010905030101814121010101000
+16BF:00202020202030282422202020202000
+16C0:00101010905038383814121010101000
+16C1:00101010101010101010101010101000
+16C2:00101010101038383810101010101000
+16C3:00000010204088442204081000000000
+16C4:00101010103854929254381010101000
+16C5:00101010121418103050901010101000
+16C6:00080808080808182848880808080800
+16C7:00101814121010101010109050301000
+16C8:0082C4A89080808080808090A8C48200
+16C9:00929254543838101010101010101000
+16CA:00081020402010081020402010080000
+16CB:0040404040444C546444040404040400
+16CC:00101010101010100000000000000000
+16CD:00101010101038383800000000000000
+16CE:00101010109254381000000000000000
+16CF:00103854921010101010101010101000
+16D0:00081828488808080808080808080800
+16D1:000818284888081C1C1C080808080800
+16D2:00605048444850606050484448506000
+16D3:00404044485064485060404040404000
+16D4:00C0A090A890A0C0C0A090A890A0C000
+16D5:0082848890A0C08080C0A09088848200
+16D6:0082C6C6AAAA92928282828282828200
+16D7:0082C6AA92AAC6828282828282828200
+16D8:00929254543838101010101010101000
+16D9:00383838101010101010101010101000
+16DA:00406050484442404040404040404000
+16DB:00406050484442E0E0E0404040404000
+16DC:00000000102844828244281000000000
+16DD:00824428102844828244281028448200
+16DE:0082C6C6AAAA92929292AAAAC6C68200
+16DF:00001028448282442810284482000000
+16E0:0000820847102AA0124002000200020002000200020002000200020002000000
+16E1:00101010925438103854921010101000
+16E2:00000208031002A0024002000200020002000200020012002A00460082000000
+16E3:00101010101010101038385454929200
+16E4:00929254543838545438385454929200
+16E5:0082C6AA92AAC68282C6AA92AAC68200
+16E6:00101010101010101038385454929200
+16E7:00000000000000001010101010101000
+16E8:00103854921010101010109254381000
+16E9:00040C14244424140C04040404040400
+16EA:004040E040444C546444040E04040400
+16EB:00000000000038383800000000000000
+16EC:00007070700000000000707070000000
+16ED:000000383810D6FED610383800000000
+16EE:00101814121010305090101010101000
+16EF:00925454383810101010383854549200
+16F0:00101010385492929292925438101000
+16F1:00007FFE7BCE73BE7B8E7BB671CE7FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000
+16F2:00007FFE7BCE73BE7B8E7BB671CE7FFE7FFE61866FF663866FBE6F867FFE0000
+16F3:00007FFE7BCE73BE7B8E7BB671CE7FFE7FFE618E6FF663C66FF66F8E7FFE0000
+16F4:00007FFE7BCE73BE7B8E7BB671CE7FFE7FFE61B66FB663866FF66FF67FFE0000
+16F5:00007FFE7BCE73BE7B8E7BB671CE7FFE7FFE61866FBE63866FF66F867FFE0000
+16F6:00007FFE7BCE73BE7B8E7BB671CE7FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+16F7:00007FFE7BCE73BE7B8E7BB671CE7FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+16F8:00007FFE7BCE73BE7B8E7BB671CE7FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+16F9:00007FFE7BCE73BE7B8E7BB671CE7FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+16FA:00007FFE7BCE73BE7B8E7BB671CE7FFE7FFE61866FB663866FB66FB67FFE0000
+16FB:00007FFE7BCE73BE7B8E7BB671CE7FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+16FC:00007FFE7BCE73BE7B8E7BB671CE7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+16FD:00007FFE7BCE73BE7B8E7BB671CE7FFE7FFE618E6FB663B66FB66F8E7FFE0000
+16FE:00007FFE7BCE73BE7B8E7BB671CE7FFE7FFE61866FBE638E6FBE6F867FFE0000
+16FF:00007FFE7BCE73BE7B8E7BB671CE7FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+1700:00000000000000006004100A7808081008100820084008800700000000000000
+1701:0000000000000000400030000FFC04020A8073400222001C0000000000000000
+1702:000000000000000003E0041000100020005000100010082007C0000000000000
+1703:0000000000000000400020021FFC0100010043FC3C0200020004000000000000
+1704:00000000000000001F6020900090011002900090009001103E0C000000000000
+1705:0000000000000000000000004E0C511221E201023E0C40000000000000000000
+1706:0000000000000000401C4022404220801F000800100010000000000000000000
+1707:000000000000000040FC43022C02303010480F80000000000000000000000000
+1708:000000000000000007C009201110121001000080010002000100000000000000
+1709:0000000000000000780C08120812101010182024204010800F00000000000000
+170A:00000000000000000FC010202010400840084008410822901C60000000000000
+170B:00000000000000000006000870080BD00C300820084008800700000000000000
+170C:00000000000000000004000A300A481C08100820084008800700000000000000
+170D:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE738E6DB66DB66DB6738E7FFE0000
+170E:0000000000000000407C43823C82010000800100010000800300000000000000
+170F:000000000000000001C00220041000080008010803080C900060000000000000
+1710:0000000000000000000C001238220824084A0442048202840318000000000000
+1711:0000000000000000001C106221822602180C0000000000000000000000000000
+1712:0000000C000C0000000000000000000000000000000000000000000000000000
+1713:0000000000000000000000000000000000000000000000000000001800180000
+1714:0000000000000000000000000000000000000000000000000000010003800100
+1715:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE7B8673BE7B867BF671867FFE0000
+1716:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE7BCE73BE7B8E7BB671CE7FFE0000
+1717:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE7B8673F67BEE7BDE71DE7FFE0000
+1718:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE7BCE73B67BCE7BB671CE7FFE0000
+1719:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE7BCE73B67BC67BF671CE7FFE0000
+171A:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE7B8673B67B867BB671B67FFE0000
+171B:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE7B8E73B67B8E7BB6718E7FFE0000
+171C:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE7BC673BE7BBE7BBE71C67FFE0000
+171D:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE7B8E73B67BB67BB6718E7FFE0000
+171E:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE7B8673BE7B8E7BBE71867FFE0000
+171F:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE7B8673BE7B8E7BBE71BE7FFE0000
+1720:000000000000000000040008181068200840088009000A000C00000000000000
+1721:000000000000000000040008181068200848089009200A000C00000000000000
+1722:000000000000000007E000400080010007F00020004000800100000000000000
+1723:000000000000000010E011100A10062005C00800080008000000000000000000
+1724:0000000000000000101010301050109011101210141018101010000000000000
+1725:0000000000000000101010201040108011401220140018001000000000000000
+1726:00000000000000001080118811881290129014A014A018C01080000000000000
+1727:00000000000000000808081008200040388009000A000C000800000000000000
+1728:000000000000000047183AE80208020802080208020802080208000000000000
+1729:0000000000000000000478080808081008180824084008800700000000000000
+172A:00000000000000003FC000400080008001000100020002000200000000000000
+172B:00000000000000000C0436080508089008500820085008880F00000000000000
+172C:00000000000000001008281848280848088809080A080C080808000000000000
+172D:000000000000000000000000000000001FF80000000000000000000000000000
+172E:0000000000000000210023002300250025002960299031102020000000000000
+172F:0000000000000000304048C208A4091811001200120014001800000000000000
+1730:000000000000000000200060186068A008A00924094C0A740C02000000000000
+1731:0000000000000000100808100820084008800900120014001800000000000000
+1732:00000000003C0000000000000000000000000000000000000000000000000000
+1733:0000000000000000000000000000000000000000000000000000000000780000
+1734:0000000000020002000200020002000200020002000200040004000800301FC0
+1735:0000000000000000004000800080010001000200020004000400000000000000
+1736:0000000000000000010802100210042004200840084010801080000000000000
+1737:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE63867DF671EE7DDE63DE7FFE0000
+1738:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE63CE7DB671CE7DB663CE7FFE0000
+1739:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE63CE7DB671C67DF663CE7FFE0000
+173A:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE63867DB671867DB663B67FFE0000
+173B:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE638E7DB6718E7DB6638E7FFE0000
+173C:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE63C67DBE71BE7DBE63C67FFE0000
+173D:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE638E7DB671B67DB6638E7FFE0000
+173E:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE63867DBE718E7DBE63867FFE0000
+173F:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE63867DBE718E7DBE63BE7FFE0000
+1740:000000080008001038103820082008400FC00F80000000000000000000000000
+1741:000000080008001038103820082008400FC00F8000001F001F00000000000000
+1742:00000000000000000F800F80008000F001E00040004000800080000000000000
+1743:000000000000000003F003F0000000000000000000001F801F80000000000000
+1744:000000000000000002000200040007F007F00010002000200040000000000000
+1745:000000000000000007F007F000200020007C007C00801F801F80000000000000
+1746:000000000000000011E211E2112222442244224444887CF87CF8000000000000
+1747:00000000000000000108010801083E103E100210042007E007E0000000000000
+1748:000000000000000007F807F80040008000800080010001000100000000000000
+1749:00000000000000003C3C3C3C042008400840084010801F801F80000000000000
+174A:000000000000000000000FE00FE000200020004000400FC00FC0000000000000
+174B:00000000000800080010041007F007F00820082008201FE01FC0000000000000
+174C:00000000000000003E7C3E7C024404880488048809100F100F10000000000000
+174D:00000000000000000000000000001FF81FF80000000000000000000000000000
+174E:000000000000000001F001F00110221022203FE03FE004000400080008000000
+174F:000000000400040008F808F80888110810101FF01FF000000000000000000000
+1750:000000003E003E000200040007C007C00040008000F800F80008001000100020
+1751:000000000000000002000200020004000400040008000FE00FE0000000000000
+1752:0000007C007C0000000000000000000000000000000000000000000000000000
+1753:000000000000000000000000000000000000000000000000000000F800F80000
+1754:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61B66FB661867DF661F67FFE0000
+1755:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61866FBE61867DF661867FFE0000
+1756:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61CE6FBE618E7DB661CE7FFE0000
+1757:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61866FF661EE7DDE61DE7FFE0000
+1758:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61CE6FB661CE7DB661CE7FFE0000
+1759:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61CE6FB661C67DF661CE7FFE0000
+175A:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61866FB661867DB661B67FFE0000
+175B:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE618E6FB6618E7DB6618E7FFE0000
+175C:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61C66FBE61BE7DBE61C67FFE0000
+175D:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE618E6FB661B67DB6618E7FFE0000
+175E:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61866FBE618E7DBE61867FFE0000
+175F:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61866FBE618E7DBE61BE7FFE0000
+1760:00000000000000000004000A3008481008100820084008801700200020001000
+1761:0000000000000010002600483008481008100820084008800700000000000000
+1762:00000000100810201008102010081000
+1763:0000000000000000301808200440028001000280044008201018000000000000
+1764:0000000000000FE0311840840100020001000080010002000100008001000000
+1765:000000000000000000000000401C20221FC22004400000000000000000000000
+1766:0000000000000000400020004000803840443F84400880004000200040000000
+1767:0000000000E00100020604083408481008100820084008800700000000000000
+1768:0000000000000FE0311841040100010001000100010001000100010001000000
+1769:0000000000000000000600083008481008100828084408820700000000000000
+176A:00000000000007F0080810042004200420042004200810100FE0000000000000
+176B:00000000000000000006000833C84C3008100820084008800700000000000000
+176C:0000000000000000000C00123012482408200840084008800700000000000000
+176D:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE738E6FB663B66DB6738E7FFE0000
+176E:0000000000000000000E00103010482008200854085A08AC0716000800000000
+176F:000000000000000003C00C20102020004000400041FC46023802000000000000
+1770:0000000000000000002000503050489008A009180910090C0608000000000000
+1771:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61EE7DCE7BEE77EE77C67FFE0000
+1772:0000000800040008000000000000000000000000000000000000000000000000
+1773:0000000000000000000000000000000000000000000000000010000800100000
+1774:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61B67DB67B8677F677F67FFE0000
+1775:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61867DBE7B8677F677867FFE0000
+1776:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61CE7DBE7B8E77B677CE7FFE0000
+1777:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61867DF67BEE77DE77DE7FFE0000
+1778:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61CE7DB67BCE77B677CE7FFE0000
+1779:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61CE7DB67BC677F677CE7FFE0000
+177A:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61867DB67B8677B677B67FFE0000
+177B:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE618E7DB67B8E77B6778E7FFE0000
+177C:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61C67DBE7BBE77BE77C67FFE0000
+177D:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE618E7DB67BB677B6778E7FFE0000
+177E:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61867DBE7B8E77BE77867FFE0000
+177F:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61867DBE7B8E77BE77BE7FFE0000
+1780:00000000000000000760089004000FF008100810081008100810000000000000
+1781:0000000000000040038004400420022000400380042004400380000000000000
+1782:00000000000000000760089004000FF00810081009900A900C10000000000000
+1783:000000000000000019982A202B300910091009100910091006E0000000000000
+1784:0000000004000200028003400180004006200A200AA003600220000000000000
+1785:0000000000000000076008901000087008901E702910291000E0000000000000
+1786:00000000000000200310049008600C0004400440054006C00440000000000000
+1787:00000000000000001C66228822CC2244224432442A442A4431B8000000000000
+1788:00000000000000000DB8124410441044104418441444144418440010070808F0
+1789:00000000038000400320042003C000000220022002A003600220000000000000
+178A:00000020001000100330054005600120012001200120012000C0000000000000
+178B:00000000000000000EE011101010082000C003100C3010300FD0000000000000
+178C:00000000000000001B062488208C2084208431C42AA42AA43198000000000000
+178D:00000000000000001C38224422642224222432242AA42B643224000000000000
+178E:00000000000000003E38224422642224222422243AA42B643224000000000000
+178F:00000000000000000760089004000FE008200C200A200A200C20000000000000
+1790:0000000000200010031004E008000C6004A004A00460042007E0000000000000
+1791:000000000000000003F8040408080860049003E0008008800F80000000000000
+1792:00000000000000000EC01120100018300850085009300A900C70000000000000
+1793:000000000000000001C002200440040003C00040054006C00440000000000000
+1794:0000000000000000061808200C300410041004100410041003E0000000000000
+1795:000000000020031004900860080008300850085009300A900C70000000000000
+1796:0000000000000000077008880808080808080C080A080A080C08000000000000
+1797:0000000000000000076008900400000003F002100A1012100E10000000000000
+1798:00000000000000000C3010401860082008200FE00820082007C0000000000000
+1799:000000000000000008CC15101598188810881088108810881F70000000000000
+179A:000000000000000000C001000180008000800080028004800300000000000000
+179B:00000000000000000F0C10901098108810881888148814881870000000000000
+179C:0000004000A0002000E001200180008000800080028004800300000000000000
+179D:00000000000000000760089004000FE0082008A80A700D200C20000000000000
+179E:00000000000000000C3010401860082008A808700820082007C0000000000000
+179F:00000000000000000C18102018300F10111019101510151018E0000000000000
+17A0:00000000000000000C78108418C4084408440844084408440784000000000000
+17A1:000000000F80104011180AA007301E1000100710095005B00110000000000000
+17A2:0000000000000000061808200C30041007F00410145024901C70000000000000
+17A3:0000000000000000061808200C30041007F00410145024901C70000000000000
+17A4:00000000000000000C6C109418C408440FC4084429444A4439C4000000000000
+17A5:000000000020031004900260000007F004100610051005100610000000000000
+17A6:00000004000A1F82108E1C9212981C8800081F881888148818F8000000000000
+17A7:0000000000000000038004400420022000400390043004500390000000000000
+17A8:000000000000000007600890040003C0042000400390043003D0000000000000
+17A9:00000000000000000E0011001080089001100E5010D011500E50000000000000
+17AA:010000800040074008C00640010003C0042000400390043003D0000000000000
+17AB:0000000000000000061808200C300410041004100410041003E00030070808F0
+17AC:0000000000000000061808200C300410041004100410041003E00030070808F6
+17AD:0000000000000000077008880808080808080C080A080A080C080060071008E0
+17AE:0000000000000000077008880808080808080C080A080A080C080060071008EC
+17AF:0000000000000000030001000170019000100710095005B00110000000000000
+17B0:000000000000000007700888080808080C080A080A080C08000003F804900360
+17B1:000000000000038004400620010003C0042000400390043003D0000000000000
+17B2:000000000000001007E0080008E00910091008200810081007E0000000000000
+17B3:000000000000038804500620010003C0042000400390043003D0000000000000
+17B4:555580002545A9443129A92825118000000188701489A2A83E99A2780005AAAA
+17B5:555580002545A9443129A92825118000000188101429A2443E7DA2440001AAAA
+17B6:000000000000001E002200020002000200020002000200020002000000000000
+17B7:00000380044003F8000000000000000000000000000000000000000000000000
+17B8:00000390045003F0000000000000000000000000000000000000000000000000
+17B9:00000390046803F8000000000000000000000000000000000000000000000000
+17BA:005003D0047003F8000000000000000000000000000000000000000000000000
+17BB:00000000000000000000000000010101
+17BC:00000000000000000000000000000000000000000000000000000240024003C0
+17BD:0000000000000000000000000000000000000000000000000000022002A00360
+17BE:00000390045003F0C000A000800080008000C000A000A000C000000000000000
+17BF:005003D0047003FEC001A001800180018001C001A001A001C0011007080107FE
+17C0:001800080010003EC001A001800180018001C001A001A001C0011007080107FE
+17C1:00000000C0A0808080C0A0A0C0000000
+17C2:18887000C0A0808080C0A0A0C0000000
+17C3:98644418C0A0808080C0A0A0C0000000
+17C4:000000000000001EC022A002800280028002C002A002A002C002000000000000
+17C5:000400020002001EC022A002800280028002C002A002A002C002000000000000
+17C6:0180024001800000000000000000000000000000000000000000000000000000
+17C7:0000000000000000000200050005000200000002000500050002000000000000
+17C8:0000000000000000000000000000000200000002000000000000000000000000
+17C9:0000014001400140000000000000000000000000000000000000000000000000
+17CA:0760089004000000000000000000000000000000000000000000000000000000
+17CB:00010101000000000000000000000000
+17CC:0388045002200400000000000000000000000000000000000000000000000000
+17CD:03880450022001A0000000000000000000000000000000000000000000000000
+17CE:008003E000800080000000000000000000000000000000000000000000000000
+17CF:01E6021C02A00360000000000000000000000000000000000000000000000000
+17D0:000C004400380000000000000000000000000000000000000000000000000000
+17D1:00003FF000000000000000000000000000000000000000000000000000000000
+17D2:555580000001800000018000000180000001800000018000010183800101AAAA
+17D3:0380044003800000000000000000000000000000000000000000000000000000
+17D4:00000000000000000180098012800C8000800080008000800080000000000000
+17D5:0000000000000000068026804A80328002800280028002800280000000000000
+17D6:00000000304830007800304830000000
+17D7:3E3C414270824802700200020002000200020002000200020002400240023FFC
+17D8:0000131914A114B11491B49B5495149114911651155115511631000000000000
+17D9:00000000000000000380044009200AA00AA00920082004400380000000000000
+17DA:00000000000000000000000071008A88AA959252445038200000000000000000
+17DB:000000000000000000C001000180008003E00080028004800300000000000000
+17DC:00000000001C22201C02122418000000
+17DD:000003C004200810000000000000000000000000000000000000000000000000
+17DE:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE63866DBE6D8E6DBE63867FFE0000
+17DF:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE63866DBE6D8E6DBE63BE7FFE0000
+17E0:000000000000000007C0082008200820082008200820082007C0000000000000
+17E1:000000000000000007C00820091006100010001000100E1011E0000000000000
+17E2:0000200020002000277028882C082A082A082C08200820081FF0000000000000
+17E3:00000000000000001EF021082108210821083108290829083108000000000000
+17E4:0000000000000004000803E8041808C0092008800840082007E0000000000000
+17E5:00000600091009200A2007E0040008C0092008800840082007E0000000000000
+17E6:0000000000000000180008000BE00C10001006100910082007C0000000000000
+17E7:00000002000400041DC422242024202420243024282428243018000000000000
+17E8:00000008001007D0083010001030105010901050101013D00C30000000000000
+17E9:000000000000000000080F1010D0103008001F00208024401830000000000000
+17EA:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61866FB663866FB661B67FFE0000
+17EB:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE618E6FB6638E6FB6618E7FFE0000
+17EC:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61C66FBE63BE6FBE61C67FFE0000
+17ED:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE618E6FB663B66FB6618E7FFE0000
+17EE:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61866FBE638E6FBE61867FFE0000
+17EF:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61866FBE638E6FBE61BE7FFE0000
+17F0:00000000000000003048484830000000
+17F1:00000000000000001028284440000000
+17F2:00000000000000002020202020000000
+17F3:00000000000000000000245A89000000
+17F4:00000000000000004444282810000000
+17F5:00000000000000442810282810000000
+17F6:00000000000000002010100808000000
+17F7:00000000000000000000225488000000
+17F8:00000000000000000810102020000000
+17F9:00000000000000182040780418000000
+17FA:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61866FB663866FB66FB67FFE0000
+17FB:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+17FC:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+17FD:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE618E6FB663B66FB66F8E7FFE0000
+17FE:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61866FBE638E6FBE6F867FFE0000
+17FF:00007FFE7B8673F67BEE7BDE71DE7FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+1800:000000000000000000000078708408840404020801F000000000000000000000
+1801:0000018001800000000001800180000000000180018000000000018001800000
+1802:000000000000000000000000010003800FE00380010000000000000000000000
+1803:00000000010003800FE00380010000000000010003800FE00380010000000000
+1804:00000000000000000000000000000C300C300000000000000000000000000000
+1805:0000010003800FE00380010010103838FEFE3838111003800FE0038001000000
+1806:0000000000000000000001800180018001800180018000000000000000000000
+1807:000000000000000000000180018007800F800180018000000000000000000000
+1808:000000000000000000001008081007E003C00000000000000000000000000000
+1809:0000000000001008081007E003C0000000001008081007E003C0000000000000
+180A:0000000000000000000000000180018001800000000000000000000000000000
+180B:555580003C45A0443829A0282011800000019C10203198100411B87C0001AAAA
+180C:555580003C45A0443829A0282011800000019C78200598380441B87C0001AAAA
+180D:555580003C45A0443829A0282011800000019C78200598380405B8780001AAAA
+180E:555580002245B6442A29A22822118000000181C002018180004183800001AAAA
+180F:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE73866DBE6D8E6DBE73BE7FFE0000
+1810:000000000000000007E018182004200420042004181807E00000000000000000
+1811:000000000000000008E013182004200420042004181807E00000000000000000
+1812:000000000000000007E018182004000400040004181817E01000080006000000
+1813:000000000000000007E018182004000401F80004181817E01000080006000000
+1814:0000000000000000070018C82024200420042004181807E00000000000000000
+1815:0000000000000000070018002000200010000FE0001800600180060018000000
+1816:000000000000000007E018182004200423E42084188007000000000000000000
+1817:000000000000000007881864001400141FE420042004181807E0000000000000
+1818:0000000000000000000038002600218020602018180006000000000000000000
+1819:000000000000000007E0181820042004200421C4193800000000000000000000
+181A:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE7B8673B67B867BB671B67FFE0000
+181B:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE7B8E73B67B8E7BB6718E7FFE0000
+181C:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE7BC673BE7BBE7BBE71C67FFE0000
+181D:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE7B8E73B67BB67BB6718E7FFE0000
+181E:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE7B8673BE7B8E7BBE71867FFE0000
+181F:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE7B8673BE7B8E7BBE71BE7FFE0000
+1820:0000001000080FF8018001800780080010001C00038800700000000000000000
+1821:0000001000080FF8018001800180618021801F00000000000000000000000000
+1822:0000001000080FF80180018007F0080810082008007000000000000000000000
+1823:0000001000080FF80180018001800F80118011800F8000000000000000000000
+1824:0000001000080FF80180018001800F80118011800F8001800180000000000000
+1825:0000001000080FF80180018001800F80118011800F800180018003800F000000
+1826:0000001000080FF80180018001800F80118011800F8001800380058009800000
+1827:0000001000080FF80180018001800F801180118009800180018003800F000000
+1828:0000001000086FF8018001800000000000000000000000000000000000000000
+1829:0000000000000F8003800180018007F008081004000400040078000000000000
+182A:0000000000000FF0118811880F880008000801F0000000000000000000000000
+182B:00000000000031F0318831881F880008000803F0000000000000000000000000
+182C:000000000000018001800BF00D88018801881FF0018001800000000000000000
+182D:00000000000001800180ABF0AD88018801881FF0018001800000000000000000
+182E:0000004000200FF8018801860000000000000000000000000000000000000000
+182F:0000004600280FF8018001800000000000000000000000000000000000000000
+1830:000000400080007000080FF80180018000000000000000000000000000000000
+1831:00000080010000E600160FF00186018600000000000000000000000000000000
+1832:008001400220041002200FC00380018001800000000000000000000000000000
+1833:0000000000000FF0118029802580198001800180000000000000000000000000
+1834:0000000000000180018031801980198019801F80018001800000000000000000
+1835:0000000000000780198061800180018000000000000000000000000000000000
+1836:0000000000000780298011800180018000000000000000000000000000000000
+1837:0000000040002780198061800180018000000000000000000000000000000000
+1838:0000000000000F80118011800980018000000000000000000000000000000000
+1839:0000000000006FF0118811880F880008000801F0000000000000000000000000
+183A:0000000000003FF0080830080008000801F00000000000000000000000000000
+183B:0000000000003FF0098831880008000801F00000000000000000000000000000
+183C:00000000000001802180318031801F8029802980118001800000000000000000
+183D:00000000000001802180318031801F8021802180118001800000000000000000
+183E:0000001000080FF8018001800F80100020001780098001800180000000000000
+183F:00001FF020082844102407F80180018000000000000000000000000000000000
+1840:0000004400280FF8018001800F80100020001780098001800180000000000000
+1841:0000000000000F80100020001780098001800180000000000000000000000000
+1842:0000000000000F80118011800F8001800F80118011800F800180018000000000
+1843:00000000000001F0018001800000000000000000000000000000000000000000
+1844:0000001000081FF8018001800F80118011800180000000000000000000000000
+1845:0000001000080FF8018001800FFC000400080C3003C000000000000000000000
+1846:0000001000081FF8018001800F80118011801F80000000000000000000000000
+1847:0000001000081FF8018001800FF0118831884F884008001001E0000000000000
+1848:0000001000081FF8018001800F80119011E01F80000000000000000000000000
+1849:0000001000081FF8018001800FF0118811880F880008001001E0000000000000
+184A:0000000000000F80038001800F801180118001806180218011800F0000000000
+184B:0000000000000F80118011800F806180218011800F0000000000000000000000
+184C:0000018001801FF8118017E0181000080008001001E000000000000000000000
+184D:0000001000086FF8038001806F80038001800180000000000000000000000000
+184E:00000010000827F8538051802780038001800180000000000000000000000000
+184F:00000000018001F00208041008200FE4001C0000000000000000000000000000
+1850:00000000000003E0041008100FE0018001800000000000000000000000000000
+1851:0000000000000780198013800D80018000000000000000000000000000000000
+1852:00000000000021805180518031800F8001800180000000000000000000000000
+1853:00000000000001802180518051804F8001800180000000000000000000000000
+1854:00000000000001802180118011800F8001800180000000000000000000000000
+1855:0000000000000780198001800180000000000000000000000000000000000000
+1856:0000000000000780198029802980118001800000000000000000000000000000
+1857:000000000000000003FC14021802000200040038000000000000000000000000
+1858:00000000000001800BFC04020802000200040038000000000000000000000000
+1859:0000000000000F80038001800F801000200017800980018003800F0000000000
+185A:0000000000000FF0118811844F84600450084FF0018001800000000000000000
+185B:0000000000001FF02190219011F8018001800000000000000000000000000000
+185C:00000000000001801D804D802D803F8001800180000000000000000000000000
+185D:0000000000000798180020003FC00030000A0004000000000000000000000000
+185E:0000000000000F80038001800780198021800180000000000000000000000000
+185F:0000000001900FA003C001A00190018001800000000000000000000000000000
+1860:0000001000081FF8018001800F80119811840F80000000000000000000000000
+1861:0000000000000F80118011800F80018003800580098001800000000000000000
+1862:0000000000000F80038001800F8003800180618011800F800000000000000000
+1863:0000000000000780080010001FE0001A48042400000000000000000000000000
+1864:000000000180118017E0181800040004181807E0018801840000000000000000
+1865:000000000180118017E0181800040004181C07EA018A01840180000000000000
+1866:0000000000000FF0118811880FB00008000801F0000000000000000000000000
+1867:00000000000004200840103000081FF801800180000000000000000000000000
+1868:00000000000000000180019001A801C4018401840FF801800180000000000000
+1869:008001400220041002200FC00390018801800000000000000000000000000000
+186A:0000000001804380458039800180018000000000000000000000000000000000
+186B:000000000000000800040004001807E019802180218011800180000000000000
+186C:0000000000001FE0041018100014002201C00000000000000000000000000000
+186D:0000000000001FC00424182A002A004401800000000000000000000000000000
+186E:00000100020001C800280FFE0188018801800000000000000000000000000000
+186F:00000100020001C400240FFC0184018401800000000000000000000000000000
+1870:0000000000001FF8018001800000000000000000000000000000000000000000
+1871:0000000000000180219011A811A80F9001800180000000000000000000000000
+1872:000000000180439045A839A80190018000000000000000000000000000000000
+1873:0000000000000780198061800180078019806180018000000000000000000000
+1874:0000000000000F800380018001800780180020003FC00030240A120400000000
+1875:000000000000378009803180018003800F000000000000000000000000000000
+1876:000000000180018801840184019807E019802180218011800180000000000000
+1877:0000000000000780199001A801A8019001800000000000000000000000000000
+1878:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE61CE7DB67BCE77B677CE7FFE0000
+1879:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE61CE7DB67BC677F677CE7FFE0000
+187A:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE61867DB67B8677B677B67FFE0000
+187B:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE618E7DB67B8E77B6778E7FFE0000
+187C:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE61C67DBE7BBE77BE77C67FFE0000
+187D:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE618E7DB67BB677B6778E7FFE0000
+187E:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE61867DBE7B8E77BE77867FFE0000
+187F:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE61867DBE7B8E77BE77BE7FFE0000
+1880:00000000000003C00420042013C8081007E003C0000000000000000000000000
+1881:0000000000000180024002400180018002400240018000000000000000000000
+1882:0000000000000FF0042002400180024004200FF0000000000000000000000000
+1883:00000000000011102108210822881C7000000000000000000000000000000000
+1884:0000000000001C70228821082108111000000000000000000000000000000000
+1885:0000000003800440042002200040038004400420022000400780004000200000
+1886:000000000000631894A452941084631894A452941084E7381084084200000000
+1887:0000001000081FF8018001800180018001800180018009800580030000000000
+1888:0000001000081FF8018007E00810100810040804001800000000000000000000
+1889:00000000000007E0181820040004000801F00180018001800000000000000000
+188A:0000001040082FF8018001800FE010100010002000C000000000000000000000
+188B:00000000000001803180098009800F8049804980318001800000000000000000
+188C:0000000001800980138025803980018000000000000000000000000000000000
+188D:0000000000000F80118011800F80038005800980058003800180018000000000
+188E:00000000000007801980218021801D8005801980018001800000000000000000
+188F:0000000000000780198031803180018001800180018001800000000000000000
+1890:0000000000000780198023802580198001800180000000000000000000000000
+1891:0000000000000780198021801580098001800000000000000000000000000000
+1892:00000000000001E00998118411840F88001000E0000000000000000000000000
+1893:00000000000031E04998498429840788001000E0000000000000000000000000
+1894:00000000000007C0083C000260020002600407F8018001800000000000000000
+1895:00000000000000001FFC200220022002100407F8018001800000000000000000
+1896:00000000000001E00998298429841788001000E0000000000000000000000000
+1897:00000000000000000FF01008100810080C1000E0000000000000000000000000
+1898:0000000000000780198013800D80098009800180000000000000000000000000
+1899:0000000000000FE0101027102990299027E00180018000000000000000000000
+189A:00000180118011801FF000080008001007E0018E01800184018A018401800000
+189B:0000001000081FF8018009801580158009800180000000000000000000000000
+189C:0000020004000394007A0FFA019A019401800000000000000000000000000000
+189D:000002000400039000700FF001900180019001A801A801900180000000000000
+189E:000000000000000C003003C00D9031A801A80190018001800180000000000000
+189F:00000000000003800D9031A801900180019001A8019001800180000000000000
+18A0:00000000000007801980238015B0098801800000000000000000000000000000
+18A1:008001400220041002200FC0039C018001880194018801800000000000000000
+18A2:000000000000002000406030000867F801800180000000000000000000000000
+18A3:000000000000000C003003C00D80318001800180018001800180000000000000
+18A4:0000000000000480090010C4002A1FEA01840180000000000000000000000000
+18A5:0000000000000080010000C4002A1FEA01840180000000000000000000000000
+18A6:0000000000000380058009800580038000000000000000000000000000000000
+18A7:00000000000003804C0071804780398001800000000000000000000000000000
+18A8:0000000000000FF0118811880F88001001E00188019401940188018000000000
+18A9:0000200020004000800000000000000000000000000000000000000000000000
+18AA:0000004600281FF80180019001A801A801900180000000000000000000000000
+18AB:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE618E6DB6618E6DB66D8E7FFE0000
+18AC:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE61C66DBE61BE6DBE6DC67FFE0000
+18AD:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE618E6DB661B66DB66D8E7FFE0000
+18AE:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE61866DBE618E6DBE6D867FFE0000
+18AF:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE61866DBE618E6DBE6DBE7FFE0000
+18B0:00081448605048444244485060400000
+18B1:00102812060A12224222120A06020000
+18B2:0058BC5A060A12224222120A06020000
+18B3:00040A04010305495109050301000000
+18B4:00081448201008040204081020400000
+18B5:00102812040810204020100804020000
+18B6:00081448201008046264081020400000
+18B7:00081408001E204040404040201E0000
+18B8:00081448404040404078444444380000
+18B9:0002051210101010505E1111110E0000
+18BA:002050200020202020202020203E0000
+18BB:00000008140800000C121212127C0000
+18BC:000000102810000030484848483E0000
+18BD:000000040A04000030404040403F0000
+18BE:00081409010101010708101010100000
+18BF:00020512101010101C02010101010000
+18C0:00081408003E0101013E4040403E0000
+18C1:00081408003E4040403E0101013E0000
+18C2:00040A04000E0101616E1010100E0000
+18C3:00102812020202023E20100804020000
+18C4:00040A24202020203E02040810200000
+18C5:102810001C204040201C040404040000
+18C6:00000000000000004F54141414080000
+18C7:00000000000000003D51505050200000
+18C8:00000000000808004F54141414080000
+18C9:00000000002020003D51505050200000
+18CA:000000000000000006094949093E0000
+18CB:00000000000000000915141414780000
+18CC:000000000004040006094949093E0000
+18CD:00000000000404000815151414780000
+18CE:000000000000000080B9090909060000
+18CF:00000000000000008098242424270000
+18D0:00000000000008088098242424270000
+18D1:0000001C020101425C10101010100000
+18D2:0808001C020101425C10101010100000
+18D3:00000007081010484701010101010000
+18D4:00000010102828444400000000000000
+18D5:00000018242424240000000000000000
+18D6:00000018243820200000000000000000
+18D7:00000018242420200000000000000000
+18D8:00000038202020200000000000000000
+18D9:0000001E282810000000000000000000
+18DA:00000404083020200000000000000000
+18DB:00000031494600000000000000000000
+18DC:00000008485414223E00000000000000
+18DD:00000010122A28447C00000000000000
+18DE:00001028100000000000000000000000
+18DF:00001818000000000000000000000000
+18E0:0000000000000001E524242418000000
+18E1:08080020202020203804020204380000
+18E2:08080002020202020E102020100E0000
+18E3:00000044A4C485858484848448300000
+18E4:0000000E1522404041414020100F0000
+18E5:00000054545455555444444444380000
+18E6:00000808007C020101790101027C0000
+18E7:00000808001F2040404F4040201F0000
+18E8:000000384444443D1514242444440000
+18E9:0010104444242414143C444444380000
+18EA:00000038445454250504040404040000
+18EB:000202000002020202324A5A423C0000
+18EC:00080803454545390101010101010000
+18ED:00000054545454555554545454280000
+18EE:00000808007C0202027C0202027C0000
+18EF:00001010003E4040403E4040403E0000
+18F0:00000000003C4040423A4040403C0000
+18F1:00101000FE040810204098A484780000
+18F2:00000000000000000000000000001C14223442504C90411022101C1000000000
+18F3:00000018080808083E00000000000000
+18F4:0000002C322020200000000000000000
+18F5:0000001C201804380000000000000000
+18F6:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+18F7:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+18F8:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+18F9:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+18FA:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE61866FB663866FB66FB67FFE0000
+18FB:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+18FC:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+18FD:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE618E6FB663B66FB66F8E7FFE0000
+18FE:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE61866FBE638E6FBE6F867FFE0000
+18FF:00007FFE7BCE73B67BCE7BB671CE7FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+1900:000000000000FF801080208040807C800880108020804E807180000000000000
+1901:0000000000001F00010001000200020004000400080008000F80000000000000
+1902:0000000000003F8042008400840084008400840084004A403180000000000000
+1903:00000000000078000840108021007E0005000880088008800700000000000000
+1904:000000000000FF80208020802080208011800E80008000800080000000000000
+1905:0000000000005F204150422044004F0040804040204010400F80000000000000
+1906:000000000000780004400240014001400140114029402A401C40000000000000
+1907:0000000000007F8008001000200078004E004000408021001E00000000000000
+1908:0000000000007F80008078800480048078800080008000800080000000000000
+1909:0000000000001F002000200020001F0020002000200020001F00020004000800
+190A:0000000000003FC0020002001A002600230024A0184000A00120000000000000
+190B:0000000000001F00208040800100060001000080408020801F00000000000000
+190C:0000000000007C0004000400040004003F804440444044403880000000000000
+190D:00000000000060C01F0004000400070000800040404020801F00000000000000
+190E:0000000000007C80188020802080188020802080208011000E00000000000000
+190F:0000000000001F00010001000200020007800400080008000F80000000000000
+1910:000000000000208040408020802080208020802084204A403180000000000000
+1911:0000000000000000770088800880088008800880888088807700000000000000
+1912:00000000000060C01F00040004001C0020004180424022801F00000000000000
+1913:0000000000003880448044804880508051804E80208000800080000000000000
+1914:0000000000007F80088008801080108020804080788006800180000000000000
+1915:0000000000007C000400080010003C0002000100310049003E00080008000000
+1916:0000000000001F00010001000200020006000600090008801040000000000000
+1917:00000000000031802E80208010800E8000800080008000800080000000000000
+1918:0000000000001080308050809080108009800680008000800080000000000000
+1919:00000000000041E0410041004100410041004100410041003E00000000000000
+191A:0000000000001A00260022002200220026001A00020002000200000000000000
+191B:0000000000001FC0224022402240224022401C40004000400040000000000000
+191C:0000000000001F002100420044004F0040804000200010400F80000000000000
+191D:00007FFE7BCE73B67BC67BF671CE7FFE7FFE7B8E73B67BB67BB6718E7FFE0000
+191E:00007FFE7BCE73B67BC67BF671CE7FFE7FFE7B8673BE7B8E7BBE71867FFE0000
+191F:00007FFE7BCE73B67BC67BF671CE7FFE7FFE7B8673BE7B8E7BBE71BE7FFE0000
+1920:0600090007F00000000000000000000000000000000000000000000000000000
+1921:03E0041002200038000000000000000000000000000000000000000000000000
+1922:00000000000000000000000000000000000000000000000000000600090007F0
+1923:0000000000000004000A000A0006000200020004000400080008000000000000
+1924:0000000000000012002D002D001B000900090012001200240024000000000000
+1925:0600090007F00004000A000A0006000200020004000400080008000000000000
+1926:0600090007F00012002D002D001B000900090012001200240024000000000000
+1927:1000080004000000000000000000000000000000000000000000000000000000
+1928:1840248005000200000000000000000000000000000000000000000000000000
+1929:000000000000000000000000000000000001004200A20022001C000000000000
+192A:0000000000000000000000000000000000000000000000000000000800140022
+192B:000000000000000000000000000000000000004200A200620046003A00020000
+192C:00007FFE7BCE73B67BC67BF671CE7FFE7FFE61C67DBE61BE6FBE61C67FFE0000
+192D:00007FFE7BCE73B67BC67BF671CE7FFE7FFE618E7DB661B66FB6618E7FFE0000
+192E:00007FFE7BCE73B67BC67BF671CE7FFE7FFE61867DBE618E6FBE61867FFE0000
+192F:00007FFE7BCE73B67BC67BF671CE7FFE7FFE61867DBE618E6FBE61BE7FFE0000
+1930:000000000000001F000800100011000E00000000000000000000000000000000
+1931:0000000000000000000000000000000000000006000900090006000000000000
+1932:0000000000000000000000000000000000000000000000000000018002400180
+1933:0000000000000000000000000000000000000000000000000000003800440000
+1934:000000000000002000100010001200150015000E000000000000000000000000
+1935:0000000000000021001100110013000D00010000000000000000000000000000
+1936:000000000000002200150015000E000400040004000400040004000000000000
+1937:0000000000000000000000000000000000000000000000000000001000080004
+1938:0000000000000009000900090006000000000000000000000000000000000000
+1939:0000000000000000000000000000000000000000000000000000000800100020
+193A:0000024000000000000000000000000000000000000000000000000000000000
+193B:000000000000000000000000000000000000000000000000000000000FE00000
+193C:00007FFE7BCE73B67BC67BF671CE7FFE7FFE63C67DBE71BE7DBE63C67FFE0000
+193D:00007FFE7BCE73B67BC67BF671CE7FFE7FFE638E7DB671B67DB6638E7FFE0000
+193E:00007FFE7BCE73B67BC67BF671CE7FFE7FFE63867DBE718E7DBE63867FFE0000
+193F:00007FFE7BCE73B67BC67BF671CE7FFE7FFE63867DBE718E7DBE63BE7FFE0000
+1940:0000000000001000200040004000418042404240214010800F00000000000000
+1941:00007FFE7BCE73B67BC67BF671CE7FFE7FFE6DEE6DCE61EE7DEE7DC67FFE0000
+1942:00007FFE7BCE73B67BC67BF671CE7FFE7FFE6D866DF661867DBE7D867FFE0000
+1943:00007FFE7BCE73B67BC67BF671CE7FFE7FFE6D8E6DF661C67DF67D8E7FFE0000
+1944:0000000000003000480048002800080008000800080000000800000000000000
+1945:0000000000004180224014401480080008000800080000000800000000000000
+1946:0000000000000380044008200820082008200820082004400380000000000000
+1947:00000000000008000800080008000860089008900850042003C0000000000000
+1948:0000000000000100028002800440044008200820101010101010000000000000
+1949:00000000000007800840080004000380004000200020042003C0000000000000
+194A:0000000000001830044002800280010002800280044008203018000000000000
+194B:00000000000003C004A008A0084008000800084008A004A003C0000000000000
+194C:000000000000038004400820080008000800084008A004A003C0008000400020
+194D:0000000000000C4010A011000900060003000480044004400380000000000000
+194E:0000000000001010101010100820082004400440028002800100000000000000
+194F:0000000000001FE012200A200640024000800080010002000400000000000000
+1950:00000000000048542404040404000000
+1951:000000000000485424041C241C000000
+1952:00000000000058644444444444000000
+1953:000000000000A0561A1212161A000000
+1954:000000000000A052121212161A000000
+1955:0000000000004242424242562A000000
+1956:00000000000036DA929292B2D2000000
+1957:000000000000B6DA929292B6DA000000
+1958:0000000000000202020242562A000000
+1959:00000000000000242424242C34000000
+195A:000000000000969A929292B6DA000000
+195B:0000000000000024243C242C34000000
+195C:000000000000969A929292B6DA020408
+195D:000000000000002C3424242C34000000
+195E:000000000000B6DA929292B2D2102040
+195F:0000000000001BAD4909090909081020
+1960:000000000000485424041C241C040810
+1961:000000000000A052121212161A020408
+1962:000000000000464A4A52526242000000
+1963:00000004040404040404040404000000
+1964:0000003C2424243C242424342C000000
+1965:0000003C242424242424242424000000
+1966:0000003C24242424242424242404041C
+1967:0000002020202020202020203C003C00
+1968:0000002020202020202020203C000000
+1969:0000002424242424242424243C000000
+196A:0000003C2424243C242424342C202038
+196B:0000003C242424242424242424202038
+196C:0000003C202020202020202020000000
+196D:000000000000A052121212161A020408
+196E:00007FFE7BCE73B67BC67BF671CE7FFE7FFE73866FBE638E6DBE73867FFE0000
+196F:00007FFE7BCE73B67BC67BF671CE7FFE7FFE73866FBE638E6DBE73BE7FFE0000
+1970:0000000000007C242424242542000000
+1971:0000000000001824447C404438000000
+1972:0000000000001C244444444C34000000
+1973:00000000000040242A2A26221C000000
+1974:00000000000018244040404438000000
+1975:00007FFE7BCE73B67BC67BF671CE7FFE7FFE61867DBE7B8677F677867FFE0000
+1976:00007FFE7BCE73B67BC67BF671CE7FFE7FFE61CE7DBE7B8E77B677CE7FFE0000
+1977:00007FFE7BCE73B67BC67BF671CE7FFE7FFE61867DF67BEE77DE77DE7FFE0000
+1978:00007FFE7BCE73B67BC67BF671CE7FFE7FFE61CE7DB67BCE77B677CE7FFE0000
+1979:00007FFE7BCE73B67BC67BF671CE7FFE7FFE61CE7DB67BC677F677CE7FFE0000
+197A:00007FFE7BCE73B67BC67BF671CE7FFE7FFE61867DB67B8677B677B67FFE0000
+197B:00007FFE7BCE73B67BC67BF671CE7FFE7FFE618E7DB67B8E77B6778E7FFE0000
+197C:00007FFE7BCE73B67BC67BF671CE7FFE7FFE61C67DBE7BBE77BE77C67FFE0000
+197D:00007FFE7BCE73B67BC67BF671CE7FFE7FFE618E7DB67BB677B6778E7FFE0000
+197E:00007FFE7BCE73B67BC67BF671CE7FFE7FFE61867DBE7B8E77BE77867FFE0000
+197F:00007FFE7BCE73B67BC67BF671CE7FFE7FFE61867DBE7B8E77BE77BE7FFE0000
+1980:000000000000066009900110011001100120011001100910061000A000400000
+1981:0100028000000CC0132002200220022002200240022012200C20014000800000
+1982:00000000000006C00920101010100C6000000000000000000000000000000000
+1983:00000000000001C002200020002001A0024001A0002004400380000000000000
+1984:00000000000000000C6010901110111012100C60000003E00410079010500FE0
+1985:00000000000007C0082010101010101010101010101008200440000000000000
+1986:0000078008401020100017801840102010201020102008400480000000000000
+1987:0000078008401020102016201920002000200020102008400780000000000000
+1988:0000000000000380044004200420042003200420042004400380000000000000
+1989:0000000000000660091001100110011001100110011009900660000000000000
+198A:00000018002403A4042004200420042003200420042004400380000000000000
+198B:0000000000000380044008400840084001800040004008400780000000000000
+198C:000007C008200B800C4008400840084001800040004008400780000000000000
+198D:0000000000000000000018C02020202020202020202022201DC0000000000000
+198E:0000000000001DC0222022202220222022202220222022201CC0000000000000
+198F:0000000000000380044004200420042003200420042004A00320004001800000
+1990:00000000000000000C6010901110111012500C60004000600010021001E00000
+1991:000003C0042009800A4008400840084009800840084004400380000000000000
+1992:0000000000000000000007C0082010101010092006C000000000000000000000
+1993:000000000000038004400800080008000FE00020002004400380000000000000
+1994:0000000000300048004000400840104010401040104008800700000000000000
+1995:0000000000000E4010A010A010A010A00CA010A810A810480FB0000000000000
+1996:00000000000000000C6010901110111012100CE0004000600010021001E00000
+1997:0000000000000EE011101010101010300CD0001000100F101090172010400F80
+1998:0000000000000660099001100110011001100110011009100660000000000000
+1999:000000000000044008201010101013901450082007D0001000101010082007C0
+199A:0FC010000F8000400E4010401040104010400C40104010800F00000000000000
+199B:00000000000000000C6010901110111012100C60000007800840078000000000
+199C:00000000000000000C6010901110111012100CE000401C402380100000000000
+199D:0F001080100016C00920101010100C6000000000000000000000000000000000
+199E:00000000000003C00420081008100810081008100810042003C0000000000000
+199F:00000000000000000C6012101110111010900C60000000000000000000000000
+19A0:00000000000000000C6010901110111012100C60000000000000000000000000
+19A1:0000000000000380044000400040004001800040084004400380000000000000
+19A2:00000000000004400820101010101010101010101010082007C0000000000000
+19A3:000000000000070008800840044002200A200420004000400080000000000000
+19A4:0100028000000380044008400040004001800040004008400780000000000000
+19A5:01000280000004400820101010101010101010101010082007C0000000000000
+19A6:00000000000006C00920101010100C6000000000000007800840078000000000
+19A7:0000000000000380044000400040034004800340002007800840078000000000
+19A8:00000000000007C0082010101010101008200440000003800440038000000000
+19A9:0FC01020100017C0082010101010101008200440000003800440038000000000
+19AA:0000000000000660091001100110011009900660000003800440038000000000
+19AB:0FC01020100017C0082010101010101008200440002003900450038000000000
+19AC:00007FFE7BCE73B67BC67BF671CE7FFE7FFE61C66DBE61BE6DBE6DC67FFE0000
+19AD:00007FFE7BCE73B67BC67BF671CE7FFE7FFE618E6DB661B66DB66D8E7FFE0000
+19AE:00007FFE7BCE73B67BC67BF671CE7FFE7FFE61866DBE618E6DBE6D867FFE0000
+19AF:00007FFE7BCE73B67BC67BF671CE7FFE7FFE61866DBE618E6DBE6DBE7FFE0000
+19B0:0000000000000000000000180025001A000000180025001A0000000000000000
+19B1:0000000000000000000000060009000100010009000600000000000000000000
+19B2:00000000000000000000000600090009000F0009000900060000000000000000
+19B3:00000000000000000000000600090001000F0008000900060000000000000000
+19B4:00000000000000000000001400140014000C0004000500050002000000000000
+19B5:0000000000000000000000006000900090009000900050000000000000000000
+19B6:0000000000000000000000004800B400B400B400B400B4000000000000000000
+19B7:0000000000006000900080008000800040008000800090006000000000000000
+19B8:000000000000000000000004000A000A000A000A000A0004001B000000000000
+19B9:00000000000000000000000E00150015001F00110011000E0000000000000000
+19BA:0000200050005000100070009000800080009000600000000000000000000000
+19BB:0000000000000000000000180025000500050025001D00050002000000000000
+19BC:0000000000000000000000240025002500250025001D00050002000000000000
+19BD:0000000000000000000000180025002500250025001D00050002000000000000
+19BE:0000000200050004000400040014002C002C002C002C003400D8000000000000
+19BF:00000000000000000000003800550055007D00450045003D0002000000000000
+19C0:00000000000000000000001800250025003D00250025001D0002000000000000
+19C1:0000000000000380044004400440044003C0004001C002400180000000000000
+19C2:000007800840102010201620192000200020002000E0012000C0000000000000
+19C3:000000000000038004400400040004000780004001C002400180000000000000
+19C4:000000000000044008201010101013901450082007D000100070009000600000
+19C5:00000000000006C00920101010100C7000100010007000900060000000000000
+19C6:0000000000000380044008400040004001800040064009400780000000000000
+19C7:0000000000000440082010101010083007D00010007000900060000000000000
+19C8:00000000000000000000000600090008000E0009000600000000000000000000
+19C9:00000000000000000000000000060009000E0008000900060000000000000000
+19CA:00007FFE7BCE73B67BC67BF671CE7FFE7FFE71866FB66F866FB671B67FFE0000
+19CB:00007FFE7BCE73B67BC67BF671CE7FFE7FFE718E6FB66F8E6FB6718E7FFE0000
+19CC:00007FFE7BCE73B67BC67BF671CE7FFE7FFE71C66FBE6FBE6FBE71C67FFE0000
+19CD:00007FFE7BCE73B67BC67BF671CE7FFE7FFE718E6FB66FB66FB6718E7FFE0000
+19CE:00007FFE7BCE73B67BC67BF671CE7FFE7FFE71866FBE6F8E6FBE71867FFE0000
+19CF:00007FFE7BCE73B67BC67BF671CE7FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+19D0:00000000000003C00420081008100810081008100810042003C0000000000000
+19D1:00000000000000000000000003C00420001000100010042003C0000000000000
+19D2:00000000000000C0002000200020002000200020042004400380000000000000
+19D3:00000000000001C0022002000200022001C00040008001000200000000000000
+19D4:000000000000070008800800084008C007400040005000500020000000000000
+19D5:00000000000006C00920101010100C7000100010005000500020000000000000
+19D6:000001C002200400040004C005200500048004400420022001C0000000000000
+19D7:0000000000000D8012402020202018E000200020002800280010000000000000
+19D8:0000000000000180018002400240042004200810081010086006000000000000
+19D9:0000000000000380044008200A2009C008000800082004400380000000000000
+19DA:0000000000000000002000200020074008800800080008800700000000000000
+19DB:00007FFE7BCE73B67BC67BF671CE7FFE7FFE638E6DB66D8E6DB6638E7FFE0000
+19DC:00007FFE7BCE73B67BC67BF671CE7FFE7FFE63C66DBE6DBE6DBE63C67FFE0000
+19DD:00007FFE7BCE73B67BC67BF671CE7FFE7FFE638E6DB66DB66DB6638E7FFE0000
+19DE:000000180024002400201C20222021202120252018C000000000000000000000
+19DF:000000180024002400201C20222021202120252018C000000380044003800000
+19E0:0000000001C0022002200220022001C0000803F8040008E0092008A00A200DE0
+19E1:000003800440054002400040044003800000024004C003400040004000400000
+19E2:00001000136014901410131010100FE00000024004C003400040004000400000
+19E3:000000000EE0111011101910151019100000024004C003400040004000400000
+19E4:00000200040009000A800A00090007800000024004C003400040004000400000
+19E5:04800B80040009000A800A00090007800000024004C003400040004000400000
+19E6:040005800640004002400540044003800000024004C003400040004000400000
+19E7:0000001006C8092808280C280A280C100000024004C003400040004000400000
+19E8:002003E0040008E0092008A00A200DC00000024004C003400040004000400000
+19E9:00000040004003C004000300044003800000024004C003400040004000400000
+19EA:00001C3822442A441244024422441C380000024004C003400040004000400000
+19EB:00001C3822442A541224020422441C380000024004C003400040004000400000
+19EC:00003900452C555225420522450238FC0000024004C003400040004000400000
+19ED:000038EC4512551225120592455239920000024004C003400040004000400000
+19EE:00001C1022202A481254025022481C3C0000024004C003400040004000400000
+19EF:00241C5C22202A481254025022481C3C0000024004C003400040004000400000
+19F0:002003E0040008E0092008A00A200DC0002003E0040008E0092008A00A200DC0
+19F1:0000048009800680008000800080000003800440054002400040044003800000
+19F2:000004800980068000800080008000001000136014901410131010100FE00000
+19F3:0000048009800680008000800080000000000EE0111011101910151019100000
+19F4:000004800980068000800080008000000200040009000A800A00090007800000
+19F5:000004800980068000800080008004200BE0040009000A800A00090007800000
+19F6:0000048009800680008000800080040005800640004002400540044003800000
+19F7:00000480098006800080008000800000001006C8092808280C280A280C100000
+19F8:0000048009800680008000800080002003E0040008E0092008A00A200DC00000
+19F9:000004800980068000800080008000000040004003C004000300044003800000
+19FA:000004800980068000800080008000001C3822442A441244024422441C380000
+19FB:000004800980068000800080008000001C3822442A541224020422441C380000
+19FC:000004800980068000800080008000003900452C555225420522450238FC0000
+19FD:0000048009800680008000800080000038EC4512551225120592455239920000
+19FE:000004800980068000800080008000001C1022202A481254025022481C3C0000
+19FF:000004800980068000800080008000241C5C22202A481254025022481C3C0000
+1A00:000000000000000000000000000000000C001900330066004C00180000000000
+1A01:000000000000000000000000000000C00060023007180DB018E0124002000000
+1A02:000000000000000000000000000000002000300018001C003600220000000000
+1A03:000000000000000000000000000004000E001B0039006C00C400800000000000
+1A04:000000000000000000000000000000C00060023007180DB018E0104000000000
+1A05:0000000000000000100038006C00C6006200300038006C00C600820000000000
+1A06:0000000000000000000000000000000000004100630036001C00080000000000
+1A07:0000000000000000000000000000318018C00C600E301B6031C0208000000000
+1A08:00000000000000000000000000000000000008001C0036006300410000000000
+1A09:0000000000000000000000000000000008004900630036001C00080000000000
+1A0A:00000000000000000000000000000000000008001C0036006300490008000000
+1A0B:000000000000000000000000000000C00060023007180DB018E0124005000D80
+1A0C:000000000000000000000000000000C00060033007980C981A30136001C00080
+1A0D:000000000000000000000000000000C001E0033006180DB018E0104000000000
+1A0E:00000000000000000000000000000000000008201C7036D8638C454402800100
+1A0F:000000000000000000000000000004200E701BD8318C63C64242000000000000
+1A10:00000000000000000000000000000000000008201C7036D8638C492408200000
+1A11:00000000000000000000100038006C004400100038006C004400000000000000
+1A12:0000000000000000000000000000008001C009601C303698638C410400000000
+1A13:00000000000000000000000000000000000008201C7036D8638C410400000000
+1A14:000000000000000000000000000000C001E00330031801B000E0004000000000
+1A15:00000000000000000000000000000000000008201C7036D8638C412400200000
+1A16:00000000000000000000000008201C7036D8638C638C36D81C70082000000000
+1A17:0000000000060006000000000000000000000000000000000000000000000000
+1A18:0000000000000000000000000000000000000000000000000000000000030003
+1A19:000000000000000000000000000000000000000020006000C000600030001000
+1A1A:000000000000000000000000000000000000000000000008001C003600030001
+1A1B:8000C00060003000600040000000000000000000000000000000000000000000
+1A1C:00007FFE7B8673B67B867BB671B67FFE7FFE7BC673BE7BBE7BBE71C67FFE0000
+1A1D:00007FFE7B8673B67B867BB671B67FFE7FFE7B8E73B67BB67BB6718E7FFE0000
+1A1E:000000000000000000000000C000C00000001800180000000300030000000000
+1A1F:0000000000000000000000000000100038004400000044003800100000000000
+1A20:0000000000000000000000000EE0111020882088208811100000000000000000
+1A21:0000000000000000000007800840002007A00860086007900000000000000000
+1A22:000003800440082008000B800C40002007A00860086007900000000000000000
+1A23:0000000000000000000000000380044008200820082004400000000000000000
+1A24:0000038004400820080008000B800C4008200820082004400000000000000000
+1A25:000000000000000000002800551004880888108815100AE00000000000000000
+1A26:000000000000000000000F00108020401020202025201AA00100000000000000
+1A27:0000000000000000000003800440022001200220044003800000000000000000
+1A28:000000000100010000800E60111020880088208811100EE00000000000000000
+1A29:0000000000000000000003C00420082008400820042003200000000000000000
+1A2A:0000038004400820080008000BC00C2008400820042003200000000000000000
+1A2B:000000000100010000800E60111008880488088811100EE00000000000000000
+1A2C:00000000000000000E60111000880088208831102EE020002000200810080FF0
+1A2D:000000000000000002400520041002100410041002A001400000000000000000
+1A2E:00000000000002400520041002100410041002B001500010001007D0083007E0
+1A2F:00000000000000000000000003C00420042000C0030004C00020000000000000
+1A30:000000000000000000002800541004080808100811100EE00000000000000000
+1A31:0000000000000000000000000EE0111022882288228811100000000000000000
+1A32:0000000000000000000000000EE011102088208811100E600000000000000000
+1A33:00000000000007E00810100810080C681068102812480D880000000000000000
+1A34:00000000000004C008A010501010106010101010081007E00000000000000000
+1A35:00000000000000000000000003800440082009200AA004400000000000000000
+1A36:00000000000003C0042008600860080007000080004000400000000000000000
+1A37:0000000000000000000002800440082008200820044003800000000000000000
+1A38:0000001800200040004000400840104010401040088007000000000000000000
+1A39:000000000000000006200850105010500C50105010200FD00008000000000000
+1A3A:01E0021004000400020801F80008060806080408024801B00000000000000000
+1A3B:00000000000000000000000004400AA009200820044002800000000000000000
+1A3C:0000038004400820080008000C400AA009200820044002800000000000000000
+1A3D:000000000000000000000EE0111020880088208811100E600000000000000000
+1A3E:0000000000000000000003800440082009A009A0044003A00020000000000000
+1A3F:000000000000000000000A60111020882088208811100EE00000000000000000
+1A40:000C001000100010001007100810081006100810082007C00000000000000000
+1A41:0000000000000000070008800440022005100890089007200000000000000000
+1A42:00000000000004400AA01110211030102810101000100010001007F0091007E8
+1A43:0000000000000000000000000C60121021082108109008600000000000000000
+1A44:00000000000003C0042008100810002000C0030000C00020001007F0091007E8
+1A45:00000000000000000000000001C0022004100410022001C00000000000000000
+1A46:0000000000000000002003A0044009A009A00820044003800000000000000000
+1A47:000000000000000000001C10220841040134413422881C740004000000000000
+1A48:000000000000000000000E20111020880088208811100EE00000000000000000
+1A49:0000000000000000000000000C6010902108210812100C200000000000000000
+1A4A:00000000000003E0041008080608080809880E480800080008000FE0081007E0
+1A4B:000000000000000000000EE0111020880088208811100E200010000800000000
+1A4C:0000000000000000000000000C6010902108210812100C60002007E0082007C0
+1A4D:000000000000063009480888080804100220000003C00420081009900A900410
+1A4E:00C001200108011800E800080368049804180228000807C8082809A80AA80430
+1A4F:000000000000038004400020002008200C400B80080008000820044003800000
+1A50:0000038004400400040007800440004000400440078004000400044003800000
+1A51:0000000000000380044008200820082008400980080008000820044003800000
+1A52:0000000000003000400047704888504440445044488847104008400430000000
+1A53:0000000600080010001000101810241042104210212010C00000000000000000
+1A54:0000000000000000000000003330488804440444488837700000000000000000
+1A55:0000000000003000400040004000400040004000400040004000400040003000
+1A56:0000000000000000000000000000000000000000000000000660091008900660
+1A57:000000000000000C000200020002000200020002000200020382045A0444023A
+1A58:0000000000000000000E000A0064009B00600000000000000000000000000000
+1A59:000007C00820119012500D900000000000000000000000000000000000000000
+1A5A:00000000014002A0022001400000000000000000000000000000000000000000
+1A5B:000000000000000000000000000000000000000000080008000803C8041003E0
+1A5C:00000000000000000000000000000000000000000000024004200460043003C8
+1A5D:00000000000000000000000000000000000000000000024004200420042003C0
+1A5E:0000000000000000000000000000000000000000000007300888008808880770
+1A5F:00007FFE7B8673B67B867BB671B67FFE7FFE61866FBE618E7DBE61BE7FFE0000
+1A60:000000000000000000000000000000000000000000000080008003E000800080
+1A61:0000000000000000000000000000000E000D00000000000E000D000000000000
+1A62:00000000003000C0030000000000000000000000000000000000000000000000
+1A63:0000000000000000000000000000000600090001000900060000000000000000
+1A64:0000003800440082008200020002000200020002000200020000000000000000
+1A65:01C002200410051002A001000000000000000000000000000000000000000000
+1A66:01E0021004200510028801000000000000000000000000000000000000000000
+1A67:07F0084808A80A48050802100000000000000000000000000000000000000000
+1A68:01D802240412051202A401000000000000000000000000000000000000000000
+1A69:0000000000000000000000000000000000000000004000000040004000480030
+1A6A:00000000000000000000000000000000000000000000000000C000C000C800B0
+1A6B:00000000000000E000D000080000000000000000000000000000000000000000
+1A6C:0000000000000000000000000000000000000000080014002800210811880E70
+1A6D:0000000300040004000400040004000400040004007400B40084006400880070
+1A6E:000000000000000000003C004200800084008A00460038000000000000000000
+1A6F:00000000000000000000000000000000660089008A00BB007700000000000000
+1A70:0000000000003000480080008000400030004800800080004800300000000000
+1A71:00000000C0002000200010001000080038004800800080004800300000000000
+1A72:0000000070008800880008000800080038004800800080004800300000000000
+1A73:0000000000800080014006300000000000000000000000000000000000000000
+1A74:0000000000800140008000000000000000000000000000000000000000000000
+1A75:0000000000800080008000000000000000000000000000000000000000000000
+1A76:00000008009000A000C000000000000000000000000000000000000000000000
+1A77:0000000000080008001400630000000000000000000000000000000000000000
+1A78:0000000000010001000100090005000200000000000000000000000000000000
+1A79:0000000000000006000900010009000E00080009000600000000000000000000
+1A7A:00000000007000C800A400440000000000000000000000000000000000000000
+1A7B:0000000000000006000900080008000800080004000000000000000000000000
+1A7C:000000000031000D008A008A0070000000000000000000000000000000000000
+1A7D:00007FFE7B8673B67B867BB671B67FFE7FFE618E7DB67BB677B6778E7FFE0000
+1A7E:00007FFE7B8673B67B867BB671B67FFE7FFE61867DBE7B8E77BE77867FFE0000
+1A7F:0000000000000000000000000000000000000000000000000060009000900060
+1A80:0000000000000000000001C00220041004100410022001C00000000000000000
+1A81:0000000000000000000001C00220041000100410022001C00000000000000000
+1A82:00000000000000100010001000100010001000100010041004100410022001C0
+1A83:0000000000000000038004400820002008200440038002000100010000800040
+1A84:0000000000000000038004400820080008200440038000800100010002000400
+1A85:000007C0082010101010101016100910061000100010101010101010082007C0
+1A86:000003E00410080808080808080008000860089008E0088008600810041003E0
+1A87:000003C00420081008100C100A1004100010001000100010000C000000000000
+1A88:0000000000000000000003C00420081008100A10051002600000000000000000
+1A89:000003E0041008100860088008E00890086008000800080808080808041003E0
+1A8A:00007FFE7B8673B67B867BB671B67FFE7FFE73866DB673866DB673B67FFE0000
+1A8B:00007FFE7B8673B67B867BB671B67FFE7FFE738E6DB6738E6DB6738E7FFE0000
+1A8C:00007FFE7B8673B67B867BB671B67FFE7FFE73C66DBE73BE6DBE73C67FFE0000
+1A8D:00007FFE7B8673B67B867BB671B67FFE7FFE738E6DB673B66DB6738E7FFE0000
+1A8E:00007FFE7B8673B67B867BB671B67FFE7FFE73866DBE738E6DBE73867FFE0000
+1A8F:00007FFE7B8673B67B867BB671B67FFE7FFE73866DBE738E6DBE73BE7FFE0000
+1A90:0000000000000000000001C00220041004100410022001C00000000000000000
+1A91:0000000000000010000801C80228041004000500028001000000000000000000
+1A92:01C0022004100410041004000400040004000400040006000500020000000000
+1A93:000001000100008000800E60111020880088208811100EE00000000000000000
+1A94:0480094010A01020102010C01020182017C010001000100011E01210081007E0
+1A95:0000000000100010002000C00300041008280814080408040818088404840378
+1A96:00000000000C0010001000100010081014102810201020101810211021201EC0
+1A97:00000000000004300A081404100410040C04108410880F700000000000000000
+1A98:0000000002200550049004100260004000400040004003F0044009F00A480430
+1A99:0000000000000000000000000C60121021082908149008600000000000000000
+1A9A:00007FFE7B8673B67B867BB671B67FFE7FFE73866DB671867DB673B67FFE0000
+1A9B:00007FFE7B8673B67B867BB671B67FFE7FFE738E6DB6718E7DB6738E7FFE0000
+1A9C:00007FFE7B8673B67B867BB671B67FFE7FFE73C66DBE71BE7DBE73C67FFE0000
+1A9D:00007FFE7B8673B67B867BB671B67FFE7FFE738E6DB671B67DB6738E7FFE0000
+1A9E:00007FFE7B8673B67B867BB671B67FFE7FFE73866DBE718E7DBE73867FFE0000
+1A9F:00007FFE7B8673B67B867BB671B67FFE7FFE73866DBE718E7DBE73BE7FFE0000
+1AA0:0000000003E004900888108410841FFC108410840888049003E0000000000000
+1AA1:00000000038004800880108010801FFC108410840888049003E0000000000000
+1AA2:00090026001C006800100E60111020880088208811100EE00000000000000000
+1AA3:000000000080014001C002200C9815540C98022001C001400080000000000000
+1AA4:0000000000000FE0101027C8282829C8281027E0100C0FF00000000000000000
+1AA5:000003E00220094815540AA865535A2D44115A2D65530AA815540948022003E0
+1AA6:000001C00220041004100190026002000260019004100410022001C000000000
+1AA7:000003B004480A48040800080010006001800200040004000400020000000000
+1AA8:0000000000000000000000800080008000800080008000000000000000000000
+1AA9:0000000000000000000002400240024002400240024000000000000000000000
+1AAA:00000000000000000000000001000200024001C0004000400000000000000000
+1AAB:0000000000000000000000200220042004A003A000A000A00000000000000000
+1AAC:000000380004000401C4022800300E201140018011000E000000000000000000
+1AAD:0000000000000100028005200410020804080408021001E00000000000000000
+1AAE:00007FFE7B8673B67B867BB671B67FFE7FFE61866DBE618E6DBE6D867FFE0000
+1AAF:00007FFE7B8673B67B867BB671B67FFE7FFE61866DBE618E6DBE6DBE7FFE0000
+1AB0:00007FFE7B8673B67B867BB671B67FFE7FFE63CE6DB663B66DB663CE7FFE0000
+1AB1:00007FFE7B8673B67B867BB671B67FFE7FFE63EE6DCE63EE6DEE63C67FFE0000
+1AB2:00007FFE7B8673B67B867BB671B67FFE7FFE63866DF663866DBE63867FFE0000
+1AB3:00007FFE7B8673B67B867BB671B67FFE7FFE638E6DF663C66DF6638E7FFE0000
+1AB4:00007FFE7B8673B67B867BB671B67FFE7FFE63B66DB663866DF663F67FFE0000
+1AB5:00007FFE7B8673B67B867BB671B67FFE7FFE63866DBE63866DF663867FFE0000
+1AB6:00007FFE7B8673B67B867BB671B67FFE7FFE63CE6DBE638E6DB663CE7FFE0000
+1AB7:00007FFE7B8673B67B867BB671B67FFE7FFE63866DF663EE6DDE63DE7FFE0000
+1AB8:00007FFE7B8673B67B867BB671B67FFE7FFE63CE6DB663CE6DB663CE7FFE0000
+1AB9:00007FFE7B8673B67B867BB671B67FFE7FFE63CE6DB663C66DF663CE7FFE0000
+1ABA:00007FFE7B8673B67B867BB671B67FFE7FFE63866DB663866DB663B67FFE0000
+1ABB:00007FFE7B8673B67B867BB671B67FFE7FFE638E6DB6638E6DB6638E7FFE0000
+1ABC:00007FFE7B8673B67B867BB671B67FFE7FFE63C66DBE63BE6DBE63C67FFE0000
+1ABD:00007FFE7B8673B67B867BB671B67FFE7FFE638E6DB663B66DB6638E7FFE0000
+1ABE:00007FFE7B8673B67B867BB671B67FFE7FFE63866DBE638E6DBE63867FFE0000
+1ABF:00007FFE7B8673B67B867BB671B67FFE7FFE63866DBE638E6DBE63BE7FFE0000
+1AC0:00007FFE7B8673B67B867BB671B67FFE7FFE71CE6FB66FB66FB671CE7FFE0000
+1AC1:00007FFE7B8673B67B867BB671B67FFE7FFE71EE6FCE6FEE6FEE71C67FFE0000
+1AC2:00007FFE7B8673B67B867BB671B67FFE7FFE71866FF66F866FBE71867FFE0000
+1AC3:00007FFE7B8673B67B867BB671B67FFE7FFE718E6FF66FC66FF6718E7FFE0000
+1AC4:00007FFE7B8673B67B867BB671B67FFE7FFE71B66FB66F866FF671F67FFE0000
+1AC5:00007FFE7B8673B67B867BB671B67FFE7FFE71866FBE6F866FF671867FFE0000
+1AC6:00007FFE7B8673B67B867BB671B67FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000
+1AC7:00007FFE7B8673B67B867BB671B67FFE7FFE71866FF66FEE6FDE71DE7FFE0000
+1AC8:00007FFE7B8673B67B867BB671B67FFE7FFE71CE6FB66FCE6FB671CE7FFE0000
+1AC9:00007FFE7B8673B67B867BB671B67FFE7FFE71CE6FB66FC66FF671CE7FFE0000
+1ACA:00007FFE7B8673B67B867BB671B67FFE7FFE71866FB66F866FB671B67FFE0000
+1ACB:00007FFE7B8673B67B867BB671B67FFE7FFE718E6FB66F8E6FB6718E7FFE0000
+1ACC:00007FFE7B8673B67B867BB671B67FFE7FFE71C66FBE6FBE6FBE71C67FFE0000
+1ACD:00007FFE7B8673B67B867BB671B67FFE7FFE718E6FB66FB66FB6718E7FFE0000
+1ACE:00007FFE7B8673B67B867BB671B67FFE7FFE71866FBE6F8E6FBE71867FFE0000
+1ACF:00007FFE7B8673B67B867BB671B67FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+1AD0:00007FFE7B8673B67B867BB671B67FFE7FFE63CE6DB66DB66DB663CE7FFE0000
+1AD1:00007FFE7B8673B67B867BB671B67FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000
+1AD2:00007FFE7B8673B67B867BB671B67FFE7FFE63866DF66D866DBE63867FFE0000
+1AD3:00007FFE7B8673B67B867BB671B67FFE7FFE638E6DF66DC66DF6638E7FFE0000
+1AD4:00007FFE7B8673B67B867BB671B67FFE7FFE63B66DB66D866DF663F67FFE0000
+1AD5:00007FFE7B8673B67B867BB671B67FFE7FFE63866DBE6D866DF663867FFE0000
+1AD6:00007FFE7B8673B67B867BB671B67FFE7FFE63CE6DBE6D8E6DB663CE7FFE0000
+1AD7:00007FFE7B8673B67B867BB671B67FFE7FFE63866DF66DEE6DDE63DE7FFE0000
+1AD8:00007FFE7B8673B67B867BB671B67FFE7FFE63CE6DB66DCE6DB663CE7FFE0000
+1AD9:00007FFE7B8673B67B867BB671B67FFE7FFE63CE6DB66DC66DF663CE7FFE0000
+1ADA:00007FFE7B8673B67B867BB671B67FFE7FFE63866DB66D866DB663B67FFE0000
+1ADB:00007FFE7B8673B67B867BB671B67FFE7FFE638E6DB66D8E6DB6638E7FFE0000
+1ADC:00007FFE7B8673B67B867BB671B67FFE7FFE63C66DBE6DBE6DBE63C67FFE0000
+1ADD:00007FFE7B8673B67B867BB671B67FFE7FFE638E6DB66DB66DB6638E7FFE0000
+1ADE:00007FFE7B8673B67B867BB671B67FFE7FFE63866DBE6D8E6DBE63867FFE0000
+1ADF:00007FFE7B8673B67B867BB671B67FFE7FFE63866DBE6D8E6DBE63BE7FFE0000
+1AE0:00007FFE7B8673B67B867BB671B67FFE7FFE61CE6FB663B66FB661CE7FFE0000
+1AE1:00007FFE7B8673B67B867BB671B67FFE7FFE61EE6FCE63EE6FEE61C67FFE0000
+1AE2:00007FFE7B8673B67B867BB671B67FFE7FFE61866FF663866FBE61867FFE0000
+1AE3:00007FFE7B8673B67B867BB671B67FFE7FFE618E6FF663C66FF6618E7FFE0000
+1AE4:00007FFE7B8673B67B867BB671B67FFE7FFE61B66FB663866FF661F67FFE0000
+1AE5:00007FFE7B8673B67B867BB671B67FFE7FFE61866FBE63866FF661867FFE0000
+1AE6:00007FFE7B8673B67B867BB671B67FFE7FFE61CE6FBE638E6FB661CE7FFE0000
+1AE7:00007FFE7B8673B67B867BB671B67FFE7FFE61866FF663EE6FDE61DE7FFE0000
+1AE8:00007FFE7B8673B67B867BB671B67FFE7FFE61CE6FB663CE6FB661CE7FFE0000
+1AE9:00007FFE7B8673B67B867BB671B67FFE7FFE61CE6FB663C66FF661CE7FFE0000
+1AEA:00007FFE7B8673B67B867BB671B67FFE7FFE61866FB663866FB661B67FFE0000
+1AEB:00007FFE7B8673B67B867BB671B67FFE7FFE618E6FB6638E6FB6618E7FFE0000
+1AEC:00007FFE7B8673B67B867BB671B67FFE7FFE61C66FBE63BE6FBE61C67FFE0000
+1AED:00007FFE7B8673B67B867BB671B67FFE7FFE618E6FB663B66FB6618E7FFE0000
+1AEE:00007FFE7B8673B67B867BB671B67FFE7FFE61866FBE638E6FBE61867FFE0000
+1AEF:00007FFE7B8673B67B867BB671B67FFE7FFE61866FBE638E6FBE61BE7FFE0000
+1AF0:00007FFE7B8673B67B867BB671B67FFE7FFE61CE6FB663B66FB66FCE7FFE0000
+1AF1:00007FFE7B8673B67B867BB671B67FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000
+1AF2:00007FFE7B8673B67B867BB671B67FFE7FFE61866FF663866FBE6F867FFE0000
+1AF3:00007FFE7B8673B67B867BB671B67FFE7FFE618E6FF663C66FF66F8E7FFE0000
+1AF4:00007FFE7B8673B67B867BB671B67FFE7FFE61B66FB663866FF66FF67FFE0000
+1AF5:00007FFE7B8673B67B867BB671B67FFE7FFE61866FBE63866FF66F867FFE0000
+1AF6:00007FFE7B8673B67B867BB671B67FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+1AF7:00007FFE7B8673B67B867BB671B67FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+1AF8:00007FFE7B8673B67B867BB671B67FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+1AF9:00007FFE7B8673B67B867BB671B67FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+1AFA:00007FFE7B8673B67B867BB671B67FFE7FFE61866FB663866FB66FB67FFE0000
+1AFB:00007FFE7B8673B67B867BB671B67FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+1AFC:00007FFE7B8673B67B867BB671B67FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+1AFD:00007FFE7B8673B67B867BB671B67FFE7FFE618E6FB663B66FB66F8E7FFE0000
+1AFE:00007FFE7B8673B67B867BB671B67FFE7FFE61866FBE638E6FBE6F867FFE0000
+1AFF:00007FFE7B8673B67B867BB671B67FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+1B00:0FE0111012900920000000000000000000000000000000000000000000000000
+1B01:01000AA00AA007C0000000000000000000000000000000000000000000000000
+1B02:0100028000400020000000000000000000000000000000000000000000000000
+1B03:00000200010000F0000000000000000000000000000000000000000000000000
+1B04:0000000000000000000200050001000200010001000100010001000000000000
+1B05:000000000000000000000E70112824A42A2422FC24A412240CC4000000000000
+1B06:00000000000000000000380044389244A8828882928249443628000000000000
+1B07:000000000000000011B02A480A080A0804C8010000C0022001C0000000000000
+1B08:000000000000000046CCA9222821282113260400030008800700000000000000
+1B09:00000000000000000B800440004000800300040009C00A200410000000000000
+1B0A:0000000000000000173008880084010406180800138014400820000000000000
+1B0B:000000000000000008101428042803C801800200018004400380000000000000
+1B0C:00000000000000004098A14421421E420C0C10000C0022001C00000000000000
+1B0D:000000000000000011B02A480A0A0A7C04880110009000600040000000000000
+1B0E:000000000000000046C0A920282E29F112210442024901890106000000000000
+1B0F:000000000000000003800C001000138014400C20000000000000000000000000
+1B10:000000000000000046C5A92B282E282210420782080210C20F3C000000000000
+1B11:000000000000000046C0A9202820282010400780080011C00E20000000000000
+1B12:000000000000000046CCA9222821282110460780080011C00E20000000000000
+1B13:000000000000000023CC542A142A3F2A54AA2312000000000000000000000000
+1B14:000000000000000023C0542014203F2054A0231C000200000000000000000000
+1B15:0000000000000000239854541454145412940EE4000000000000000000000000
+1B16:00000000000000002338551415141514155408A4000000000000000000000000
+1B17:0000000000000000236054901410141014100C10000000000000000000000000
+1B18:00000000000000000870144804280E28152808C8000000000000000000000000
+1B19:00000000000000003C30422842284A284A2831C8000000000000000000000000
+1B1A:000000000000000011E02A100A100A600A100608000800000000000000000000
+1B1B:0000000C0012000F46C2A9222822282210420782080210C20F3C000000000000
+1B1C:000000000000000046C6A9292829282928291832000000000000000000000000
+1B1D:0000000000000000236054901010381054104800210022001C00000000000000
+1B1E:0000000000000000236054901010111011100E00000000000000000000000000
+1B1F:0000000000000000203050281028102813280CC8000000000000000000000000
+1B20:0000000000000000101028100810081009900660000000000000000000000000
+1B21:00000000000000009CE2A3154015001500150019000000000000000000000000
+1B22:000000000000000023CC542A172A10AA10AA0F12000000000000000000000000
+1B23:000000000000000011E0289008500A5009500790010000000000000000000000
+1B24:000000000000000008701488048809C812A80C48000000000000000000000000
+1B25:0000000000000000107828240814081409940664000000000000000000000000
+1B26:000000000000000008F0150805080FC8152808C8000000000000000000000000
+1B27:0000000000000000106028500850085008500790000000000000000000000000
+1B28:00000000000000001088295008E0084008400780000000000000000000000000
+1B29:000000000000000046CCA92A282A282A282A1832000000000000000000000000
+1B2A:000000000000000020F05108090803C8152808C8000000000000000000000000
+1B2B:00000000000000001FB024282428032804280448038800000000000000000000
+1B2C:0000000000000000200850141114111412940C64000000000000000000000000
+1B2D:000000000000000010E029100510051005100610000000000000000000000000
+1B2E:0000000000000000460CA90A290A290A290A10F2000000000000000000000000
+1B2F:000000000000000008F0144804280428042803C8000000000000000000000000
+1B30:000000000000000047E6A9152A95289524A51C39000000000000000000000000
+1B31:0000000000000000206050501250155011500FD0010000000000000000000000
+1B32:00000000000000001060285008501C502A501190000000000000000000000000
+1B33:000000000000000040CCA12A212A212A212A1E12000000000000000000000000
+1B34:0000010000000440000000000000000000000000000000000000000000000000
+1B35:0000000000000000000C00020001000100090006000000000000000000000000
+1B36:03C014200C200240000000000000000000000000000000000000000000000000
+1B37:03C015200EA00460000000000000000000000000000000000000000000000000
+1B38:000000000000000000000000000000010003000300030005000900110012000C
+1B39:0000000000000000000000000000000100020004000400020001000100020004
+1B3A:000000000000000000000000000000000000002000100410099008A007C00080
+1B3B:0000000000000000000C0002000100010009002600100410099008A007C00080
+1B3C:00E0012012400A80000000000000000000000000000000002308548814880870
+1B3D:00E0012012400A80000C00020001000100090006000000002308548814880870
+1B3E:0000000000000000300048000800100010002000200020001000000000000000
+1B3F:38004000300008003000B000C800900010002000200020001000000000000000
+1B40:0000000000000000300C48020801100110092006200020001000000000000000
+1B41:3800400030000800300CB002C801900110092006200020001000000000000000
+1B42:00E0012012400A80000000000000000000000000000000000000000000000000
+1B43:00E0012012400A80000C00020001000100090006000000000000000000000000
+1B44:000E001100110001000200020002000200020002000200010001000000000000
+1B45:000000000000000023CC542A1C2A3F2A5CAA2B12080008800700000000000000
+1B46:00000000000000004716A8AD28AD7CADAAAD4444000000000000000000000000
+1B47:000000000000000023CC542A172A10AA14AA0F12040004400380000000000000
+1B48:00000000000000000830142804280528052803C80100011000E0000000000000
+1B49:000000000000000008F0144804280528052803C80100011000E0000000000000
+1B4A:00000000000000001060285008501D502B5011900100011000E0000000000000
+1B4B:00000000000000004302A2A522A572B5AAB544B5004D00000000000000000000
+1B4C:00007FFE7B8E73B67B8E7BB6718E7FFE7FFE6DC66DBE61BE7DBE7DC67FFE0000
+1B4D:00007FFE7B8E73B67B8E7BB6718E7FFE7FFE6D8E6DB661B67DB67D8E7FFE0000
+1B4E:00007FFE7B8E73B67B8E7BB6718E7FFE7FFE6D866DBE618E7DBE7D867FFE0000
+1B4F:00007FFE7B8E73B67B8E7BB6718E7FFE7FFE6D866DBE618E7DBE7DBE7FFE0000
+1B50:0000000000000000018002400240018000000000000000000000000000000000
+1B51:00000004000A0007236254921412141214140C38000000000000000000000000
+1B52:000000000000000011B02A480A0A0A7C04880110009000600040000000000000
+1B53:000000000000000046C0A9202820282010400780080011C00E20000000000000
+1B54:0000000000000000000000000B00088009000880048003000000000000000000
+1B55:0000000000000000078008400B2008A0092008A004A003200020002000100000
+1B56:000000000000000003800C001000138014400C20000000000000000000000000
+1B57:00000000000000004622A95429382910291018E0000000000000000000000000
+1B58:00000000000000001088295008E0084008400780000000000000000000000000
+1B59:0000000000000000202250541138111012900C60000000000000000000000000
+1B5A:00000000000000000C3012481248924892486189000900060000000000000000
+1B5B:000000000000000046CCA92A282A282A282A180A023F124A118A100A118A0E72
+1B5C:0000000000000000018002400240018000000000000000000000000000000000
+1B5D:0000000000000000031004A003C00000031004A003C000000000000000000000
+1B5E:0000000000000000020005000080008000400040002000200020000000000000
+1B5F:0000000000000000100028A00410041002080208010401040104000000000000
+1B60:0000000000000000018000400180044003800000000000000000000000000000
+1B61:0000000000000000000C00020001000100090006000000000000000000000000
+1B62:0000000000000000058006400440008000800100010001000080000000000000
+1B63:0000000000000000004000C000C000C001400240044004800300000000000000
+1B64:0000000000000000000002000500008000800040004000000000000000000000
+1B65:00000000000000000000000002000200010000F0000000000000000000000000
+1B66:00000000000000000000000003C014200C200240000000000000000000000000
+1B67:0000000000000000000000000070009009200540000000000000000000000000
+1B68:0000000000000000080010002000200010000800080010002000000000000000
+1B69:000000000000000046CCA92A282A282A104A078A080A118A0E72000000000000
+1B6A:0000000000000000080014000400080004000400040008000800080004000400
+1B6B:0080010000800000000000000000000000000000000000000000000000000000
+1B6C:0000000000000000000000000000000000000000000000000000008001000080
+1B6D:0300010007C00100010000000000000000000000000000000000000000000000
+1B6E:000003C000000000000000000000000000000000000000000000000000000000
+1B6F:0100028004400000000000000000000000000000000000000000000000000000
+1B70:070001000FE00380054000000000000000000000000000000000000000000000
+1B71:07F0014002200410000000000000000000000000000000000000000000000000
+1B72:0440028001000000000000000000000000000000000000000000000000000000
+1B73:0380044005400440038000000000000000000000000000000000000000000000
+1B74:0000000000000000000010002800280044004400000000000000000000000000
+1B75:0000000000000000000030004800480048003000000000000000000000000000
+1B76:0000000000000000000090006800280054004400000000000000000000000000
+1B77:00000000000000000000B8004400640054003800000000000000000000000000
+1B78:0000000000000000000000000000000078000000000000000000000000000000
+1B79:0000000000000000000010001000200020004000780000000000000000000000
+1B7A:0000000000000000000000004000200078001000080000000000000000000000
+1B7B:00000000000000000000900050002000300048007C0000000000000000000000
+1B7C:0000000000000000000000000000300030000000000000000000000000000000
+1B7D:00007FFE7B8E73B67B8E7BB6718E7FFE7FFE618E7DB67BB677B6778E7FFE0000
+1B7E:00007FFE7B8E73B67B8E7BB6718E7FFE7FFE61867DBE7B8E77BE77867FFE0000
+1B7F:00007FFE7B8E73B67B8E7BB6718E7FFE7FFE61867DBE7B8E77BE77BE7FFE0000
+1B80:0180024004800300000000000000000000000000000000000000000000000000
+1B81:0010022005400880000000000000000000000000000000000000000000000000
+1B82:0000000000000000000000000000000000040012000A00080000000000000000
+1B83:000000000000000000000180024000C001201020084007800000000000000000
+1B84:000000000000000000000180020002000400040008000FC00000000000000000
+1B85:0000000000000000000007C00040008001000230044007E00000000000000000
+1B86:000000000000000000000180024800D401241020084007800000000000000000
+1B87:0000000000000000000007C00440028001000230044807E80000000000000000
+1B88:000000000000000000000380040004400380108011000E000000000000000000
+1B89:000000200240018000000180024000C001201020084007800000000000000000
+1B8A:000000000000000000003E7C0204020404080408081008100000000000000000
+1B8B:000000000000000000001FFC1084108421082108421042100000000000000000
+1B8C:0000000000000000000007C00040008001380208041007F00000000000000000
+1B8D:0000000000000000000007C00040008001000220041007F00000000000000000
+1B8E:0000000000000000000007C000440084010802081D1018F00000000000000000
+1B8F:000000000000000000000100022004100988124822203F200000000000000000
+1B90:0000000000000000000007C00040008001000230044807E40000000000000000
+1B91:000000000000000000001F3E01020202040408C411281F980000000000000000
+1B92:00000000000000000000002000200040087814C8049003100000000000000000
+1B93:000000000000000000000100020004000980124022203F100000000000000000
+1B94:0000000000000000000003E00020004000800100020003E00000000000000000
+1B95:000000000000000000003E7C020402040408040808100FF00000000000000000
+1B96:000000000000000000000E04020402040408040808100FF00000000000000000
+1B97:000000000000000000000204020402040408040808100FF00000000000000000
+1B98:00000000000000000000013E020204040984124822283F300000000000000000
+1B99:000000000000000000000FF000100E100220042008400FC00000000000000000
+1B9A:00000000000000000000002000200048084414C404B803000000000000000000
+1B9B:0000000000000000000007E0000007E0002003C0008001000000000000000000
+1B9C:0000000000000000000004100A100A100A100A10091008E00000000000000000
+1B9D:0000000000000000000007F00200020002700210021001E00000000000000000
+1B9E:000000000000000000003E7C020402041C380408081008100000000000000000
+1B9F:000000000000000000001FF8010801080FF00210042004200000000000000000
+1BA0:00000000000000000000001E0021072109110112022203C20000000000000000
+1BA1:00000000000000000000000200020002000600060006000A000A018A021201E2
+1BA2:00000000000000000000000000000000000000000000000000000430020801F0
+1BA3:00000000000000000000000000000000000000000000000000000180028004F0
+1BA4:07C0004002800100000000000000000000000000000000000000000000000000
+1BA5:000000000000000000000000000000000000000000000000000003C000800100
+1BA6:0000000000000000000000000000E00020004000B000E0000000000000000000
+1BA7:0000000000000000000000000000000700010002001C00070000000000000000
+1BA8:0400028001000000000000000000000000000000000000000000000000000000
+1BA9:0500022001400080000000000000000000000000000000000000000000000000
+1BAA:00000000000000000000001F0001000200040007000100020004000400040003
+1BAB:0000000000000000000000000000000000000000000000000000008001C00080
+1BAC:0000000000000000000000000000000000000000000000000C40108011000E00
+1BAD:000000000000000000000000000000000000000000001EF00210042008400F78
+1BAE:000000000000000000007F9E08A108A111111112222223C20000000000000000
+1BAF:000000000000000000007F84088408887F081112229922660000000000000000
+1BB0:0000000000000000000003C00420081008100810042003C00000000000000000
+1BB1:0000000000000000000007C00040008001380208041007F00000000000000000
+1BB2:0000000000000000000007C000400080010002F0040007E00000000000000000
+1BB3:0000000000000000000007C00040008001380240042007F00000000000000000
+1BB4:0000000000000000000007E0000007E0002003F0008001000000000000000000
+1BB5:000000000000000000007C7E048008801040202040107FF00000000000000000
+1BB6:0000000000000000000001000100026002800460041007E00000000000000000
+1BB7:0000000000000000000004100A100A100A100A10091008E00000000000000000
+1BB8:0000000000000000000007C8004800900D101220152008C00000000000000000
+1BB9:0000000000000000000003C00100026002800460041007E00000000000000000
+1BBA:0000000000000000000007E00020002007C00040008000800100010002000200
+1BBB:000000000000000000003E7C0204020404080408081008100FF000000FF00000
+1BBC:000000000000000000001C382008200844104A108920FDA0002000E0013400C8
+1BBD:000000000000000000003E7C2244324C0480048004801FF00000000000000000
+1BBE:000000000000000000003E7C0204326414282448285008103FFC000000000000
+1BBF:0000000000000000000003F8000803C800100390002003200000000000000000
+1BC0:000000000000000000000000000000E011100908063800000000000000000000
+1BC1:000000000000000000000000000000E011100900063000000000000000000000
+1BC2:0000000000000000000000000EE0111002100420084000000000000000000000
+1BC3:0000000000000000000003800C60101000000000033000000000000000000000
+1BC4:0000000000000000000003800C60101002200440088000000000000000000000
+1BC5:0000000000000000000003800C601010111012900C6000000000000000000000
+1BC6:0000000000000000000007E0081010081008081007E000000000000000000000
+1BC7:000000000000000000000000000000001FF00000000000000000000000000000
+1BC8:000000000000000000000000000000E011100E00000000000000000000000000
+1BC9:00000000000000003F00000003E004100808041003E000000000000000000000
+1BCA:00000000000000003F0000000E7001800240042003C000000000000000000000
+1BCB:0000000000000000000003800C60101010101C70000000000000000000000000
+1BCC:0000000000000000000003800C60101000001C70000000000000000000000000
+1BCD:0000000000000000000000000F80080008000780004000400000000000000000
+1BCE:0000000000000000000003800C60101000200040000000000000000000000000
+1BCF:0000000000000000000003800C60101000000070000000000000000000000000
+1BD0:0000000000000000000000000060018006001838030000C00000000000000000
+1BD1:0000000000000000000000000060018006001800030000C00000000000000000
+1BD2:0000000000000000000003800C60101007C00820101000200000000000000000
+1BD3:0000000000000000000000001F0000001FF00000007000000000000000000000
+1BD4:0000000000000000000000001F380440048004C0033000000000000000000000
+1BD5:000000000000000000000700089800600180060000C000300000000000000000
+1BD6:000000000000000000000FF004200240018002400C3000000000000000000000
+1BD7:00000000000000000000000000000E3004480488033800000000000000000000
+1BD8:0000000000000000000000000EF011080200030000C000000000000000000000
+1BD9:0000000000000000000003800C60101000000380000000000000000000000000
+1BDA:0000000000000000000003800C60121001000080000000000000000000000000
+1BDB:00000000000000000000000000000E3004480488030000000000000000000000
+1BDC:0000000000000000000000000E00113004480488030000000000000000000000
+1BDD:0000000000000000000000600180060018000600018000600000000000000000
+1BDE:0000000000000000000001C00630080804000200000000000000000000000000
+1BDF:0000000000000000000003800C60101000001C00000000000000000000000000
+1BE0:00000000000000000000000007C0082011001880064000000000000000000000
+1BE1:0000000000000000000000001CC22324221822001C0000000000000000000000
+1BE2:000000000000000000000000060001800060001800C003000000000000000000
+1BE3:0000000000000000000007E0081011881188081007E000000000000000000000
+1BE4:0000000000000000000003800C60101003800440000003800000000000000000
+1BE5:00000000000000000000038000000440038010100C6003800000000000000000
+1BE6:0000000000003800000038000000000000000000000000000000000000000000
+1BE7:0000000000000000000000000008000400020004000800000000000000000000
+1BE8:0000000000100008000400080010000000000000000000000000000000000000
+1BE9:0000000000000000380000000000000000000000000000000000000000000000
+1BEA:000000000000000000000000000C001200120012000C00000000000000000000
+1BEB:0000000000000000000000000000000000060000000600000000000000000000
+1BEC:0000000000000000000000000011000A0004000A001100000000000000000000
+1BED:0000000000100708000400080010000000000000000000000000000000000000
+1BEE:0000000000000000000000000000000000000010000800040008001000000000
+1BEF:0000000000000080010002000000000000000000000000000000000000000000
+1BF0:0000000000000000001C00000000000000000000000000000000000000000000
+1BF1:000000000000001C0000001C0000000000000000000000000000000000000000
+1BF2:0000000000000000000000000000000000080004000200000000000000000000
+1BF3:00000000000000000000000000000000000E0000000000000000000000000000
+1BF4:00007FFE7B8E73B67B8E7BB6718E7FFE7FFE61B66FB663866FF66FF67FFE0000
+1BF5:00007FFE7B8E73B67B8E7BB6718E7FFE7FFE61866FBE63866FF66F867FFE0000
+1BF6:00007FFE7B8E73B67B8E7BB6718E7FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+1BF7:00007FFE7B8E73B67B8E7BB6718E7FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+1BF8:00007FFE7B8E73B67B8E7BB6718E7FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+1BF9:00007FFE7B8E73B67B8E7BB6718E7FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+1BFA:00007FFE7B8E73B67B8E7BB6718E7FFE7FFE61866FB663866FB66FB67FFE0000
+1BFB:00007FFE7B8E73B67B8E7BB6718E7FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+1BFC:0000101020082388145008201450228821082288145008201450238820081010
+1BFD:00000000000001000280028004401AB021081AB0044002800280010000000000
+1BFE:0000000000000000111022202220222011100888088808881110000000000000
+1BFF:0000000000000000007000080004000400040004000400080070000000000000
+1C00:000000000000000001F00200040004001FF004000400020001F0000000000000
+1C01:00000000000000000FC004000400058006400840108001000000000000000000
+1C02:0000000000000000000002600490088008400820042003C00000000000000000
+1C03:0000000000000000000004200810110811081088099006600000000000000000
+1C04:000000000000000000000420081011083FFC1088099006600000000000000000
+1C05:0000000000000000020001F80010002000400040008000800000000000000000
+1C06:000000000000000000000180024002201C200220014000800000000000000000
+1C07:0000000000000000000000300FC810C00320041009C81E380000000000000000
+1C08:0000000000000000000001DC0220045008900860040002000000000000000000
+1C09:00000000000000003FC001000100028804700800040002000000000000000000
+1C0A:0000000000000000000000800040002001900260010000800000000000000000
+1C0B:000000000000000000000800040002E0031002E0040004000000000000000000
+1C0C:00000000000000000000008011200FC002000FC0122001000000000000000000
+1C0D:0000000000000000000001800240042008200910111010E00000000000000000
+1C0E:000000000000000007F000200020001000100008078808700000000000000000
+1C0F:000000000000000000000C1013E0100008001FF0000000000000000000000000
+1C10:00000000000000001FF0042008201010101008080F0810F00000000000000000
+1C11:000000000000000001F00200040004081FF004200410061009E0000000000000
+1C12:0000000000000000000004200A5012501130111008A004C00000000000000000
+1C13:0000000000000000000003000480084008200820044003800000000000000000
+1C14:00000000000000000000024005A0089008100810042002400000000000000000
+1C15:00000000000000000FF000C00100020007C00A20112000C00000000000000000
+1C16:00000000000000000FF000800040004003F00440048003000000000000000000
+1C17:00000000000000001FF804100820082008200810041003E00000000000000000
+1C18:000000000000000000000800101010281128109008EC07000000000000000000
+1C19:000000000000000000000440088008B80BC03C80088004400000000000000000
+1C1A:000000000000000000C00300040004C003000420044003800000000000000000
+1C1B:000000000000081807E004000200010001000200020004000000000000000000
+1C1C:0000000000000000000004400A2012101110111008A004C00000000000000000
+1C1D:000000000000000000000030184804400FE00440044003800000000000000000
+1C1E:0000000000000000000008200440028001000280044008200000000000000000
+1C1F:000000000000000000000300048008400FE00820044003800000000000000000
+1C20:00000000000000000000080010001150115010A0088007000000000000000000
+1C21:0000000000000000000004000800094009400A80042003C00000000000000000
+1C22:0000000000000000000006EC091012A812A81110080004000000000000000000
+1C23:00000000000000000FC014200220014003800450042003D00000000000000000
+1C24:0000000000000000001000080008000500050005000600040000000000000000
+1C25:0000000000000000000000020001000100010001000100020000000000000000
+1C26:0000000000000000000000010002000200020002000200010000000000000000
+1C27:0000200050008800400040002000200020002000A00040000000000000000000
+1C28:0000000000000000000040008000800080008000800040000000000000000000
+1C29:0000000000001FFC200040008000800080008000800040000000000000000000
+1C2A:000000000004000200010001000100010001000100010001000100010012000C
+1C2B:000000180024000200020005000900010001000100010001000100010012000C
+1C2C:0000000000000000000000000000000000000000000000000080010001C00220
+1C2D:0100020002000100000000000000000000000000000000000000000000000000
+1C2E:0000000005000000000000000000000000000000000000000000000000000000
+1C2F:0200000005000000000000000000000000000000000000000000000000000000
+1C30:03C00420092000C0000000000000000000000000000000000000000000000000
+1C31:0100028002800100000000000000000000000000000000000000000000000000
+1C32:1880244022401180000000000000000000000000000000000000000000000000
+1C33:000000003F000000000000000000000000000000000000000000000000000000
+1C34:0000000000000000400020005000900090005000200040000000000000000000
+1C35:0000000000000000000000004000800080004000000000000000000000000000
+1C36:010002C404380000000000000000000000000000000000000000000000000000
+1C37:0000000000000000000000000000000000000000000000000000000004000000
+1C38:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE63CE7DB671CE7DB663CE7FFE0000
+1C39:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE63CE7DB671C67DF663CE7FFE0000
+1C3A:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE63867DB671867DB663B67FFE0000
+1C3B:0000000000000000008000800080008000800080008000800000000000000000
+1C3C:0000000000000000024002400240024002400240024002400000000000000000
+1C3D:0000000000000000000000000000022001400080014002200000000000000000
+1C3E:0000000000000000000000000000022001400490014002200000000000000000
+1C3F:00000000000010880910091004A0042004A00910091010880000000000000000
+1C40:0000000000000000000000000100028004400440028001000000000000000000
+1C41:000000000000000000000100028002C001400040008001000000000000000000
+1C42:000000000000000007C0082000C003000400030000C000300000000000000000
+1C43:000000000000000007C00820004001E00210002001C000200000000000000000
+1C44:00000000000000000000022005C004000800083007C000000000000000000000
+1C45:0000000000000000000008100420046004A00520062008100000000000000000
+1C46:0000000000000000004000A001100080004010200C2003C00000000000000000
+1C47:00000000000000000000004002200120012000A000C001000000000000000000
+1C48:0000000000000000000001800240020004000400038000600000000000000000
+1C49:0000000000000000000001800240028002600200020001000000000000000000
+1C4A:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE6D866DB661867DB67DB67FFE0000
+1C4B:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE6D8E6DB6618E7DB67D8E7FFE0000
+1C4C:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE6DC66DBE61BE7DBE7DC67FFE0000
+1C4D:000000000000000010C00F400040004001F00040004000800000000000000000
+1C4E:000000000000000010C00F40004001F0004001F0004000800000000000000000
+1C4F:00000000000000801D3823C8010801080108008807C808100000000000000000
+1C50:00000038444444444444444444380000
+1C51:00000062524A464040404020100E0000
+1C52:00000018242414081020424224180000
+1C53:000000324A4A3E1020204040300C0000
+1C54:0000001E2040404060524E4224180000
+1C55:00000010204648505048464224180000
+1C56:0000005C22524C4040404020100C0000
+1C57:0000000C523204081020424224180000
+1C58:000000344A5A64404040404224180000
+1C59:0000001C204040404C52524A24180000
+1C5A:0000001C22660A1222424242221C0000
+1C5B:0000003C4242424242424242423C0000
+1C5C:0000001C2240404E50504E4224180000
+1C5D:0000001C2244481026104844221C0000
+1C5E:00000048546242424242625448400000
+1C5F:000000245ADA1232525292A2A4480000
+1C60:00000040485462424242422214080000
+1C61:00000048444242424242426254480000
+1C62:0000001222424242424242462A120000
+1C63:00000064928A0A0A12E2824224180000
+1C64:0000003844060A0A1212222242420000
+1C65:000000424244444848505060221C0000
+1C66:000000444482828282828292AA440000
+1C67:00000010284442424242462A12020000
+1C68:0000007804024222120A0622528C0000
+1C69:00000040485462420202422214080000
+1C6A:0000003844444444444444BA827C0000
+1C6B:00000010284482925410704044380000
+1C6C:00000044AA9282828282828244440000
+1C6D:000000304884848C90A0A0A2924C0000
+1C6E:000000384404080810102020423C0000
+1C6F:0000003C62A4A42424242525463C0000
+1C70:00000058949292929292929252340000
+1C71:0000003CC644444848505060221C0000
+1C72:0000003844060A0A12122222C37E0000
+1C73:0000001824420E1212120E4224180000
+1C74:00000048546242424242424244480000
+1C75:00000034529292929292929294580000
+1C76:000000629288080A12E2824224180000
+1C77:000000182422124E82828292AA440000
+1C78:00000000181800000000000000000000
+1C79:00000000000000000000001818000000
+1C7A:00000000181800000000001818000000
+1C7B:00000000000060920C00000000000000
+1C7C:00000000000000380000000000000000
+1C7D:000000304844241C0404044428100000
+1C7E:00000000001010101010101000000000
+1C7F:00000000002424242424242400000000
+1C80:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE73CE6DB673B66DB673CE7FFE0000
+1C81:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE73EE6DCE73EE6DEE73C67FFE0000
+1C82:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE73866DF673866DBE73867FFE0000
+1C83:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE738E6DF673C66DF6738E7FFE0000
+1C84:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE73B66DB673866DF673F67FFE0000
+1C85:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE73866DBE73866DF673867FFE0000
+1C86:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE73CE6DBE738E6DB673CE7FFE0000
+1C87:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE73866DF673EE6DDE73DE7FFE0000
+1C88:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE73CE6DB673CE6DB673CE7FFE0000
+1C89:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE73CE6DB673C66DF673CE7FFE0000
+1C8A:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE73866DB673866DB673B67FFE0000
+1C8B:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE738E6DB6738E6DB6738E7FFE0000
+1C8C:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE73C66DBE73BE6DBE73C67FFE0000
+1C8D:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE738E6DB673B66DB6738E7FFE0000
+1C8E:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE73866DBE738E6DBE73867FFE0000
+1C8F:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE73866DBE738E6DBE73BE7FFE0000
+1C90:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE73CE6DB671B67DB673CE7FFE0000
+1C91:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE73EE6DCE71EE7DEE73C67FFE0000
+1C92:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE73866DF671867DBE73867FFE0000
+1C93:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE738E6DF671C67DF6738E7FFE0000
+1C94:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE73B66DB671867DF673F67FFE0000
+1C95:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE73866DBE71867DF673867FFE0000
+1C96:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE73CE6DBE718E7DB673CE7FFE0000
+1C97:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE73866DF671EE7DDE73DE7FFE0000
+1C98:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE73CE6DB671CE7DB673CE7FFE0000
+1C99:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE73CE6DB671C67DF673CE7FFE0000
+1C9A:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE73866DB671867DB673B67FFE0000
+1C9B:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE738E6DB6718E7DB6738E7FFE0000
+1C9C:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE73C66DBE71BE7DBE73C67FFE0000
+1C9D:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE738E6DB671B67DB6738E7FFE0000
+1C9E:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE73866DBE718E7DBE73867FFE0000
+1C9F:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE73866DBE718E7DBE73BE7FFE0000
+1CA0:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE61CE6DB661B66DB66DCE7FFE0000
+1CA1:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE61EE6DCE61EE6DEE6DC67FFE0000
+1CA2:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE61866DF661866DBE6D867FFE0000
+1CA3:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE618E6DF661C66DF66D8E7FFE0000
+1CA4:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE61B66DB661866DF66DF67FFE0000
+1CA5:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE61866DBE61866DF66D867FFE0000
+1CA6:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE61CE6DBE618E6DB66DCE7FFE0000
+1CA7:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE61866DF661EE6DDE6DDE7FFE0000
+1CA8:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE61CE6DB661CE6DB66DCE7FFE0000
+1CA9:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE61CE6DB661C66DF66DCE7FFE0000
+1CAA:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE61866DB661866DB66DB67FFE0000
+1CAB:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE618E6DB6618E6DB66D8E7FFE0000
+1CAC:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE61C66DBE61BE6DBE6DC67FFE0000
+1CAD:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE618E6DB661B66DB66D8E7FFE0000
+1CAE:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE61866DBE618E6DBE6D867FFE0000
+1CAF:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE61866DBE618E6DBE6DBE7FFE0000
+1CB0:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE63CE6DB663B66DB663CE7FFE0000
+1CB1:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE63EE6DCE63EE6DEE63C67FFE0000
+1CB2:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE63866DF663866DBE63867FFE0000
+1CB3:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE638E6DF663C66DF6638E7FFE0000
+1CB4:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE63B66DB663866DF663F67FFE0000
+1CB5:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE63866DBE63866DF663867FFE0000
+1CB6:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE63CE6DBE638E6DB663CE7FFE0000
+1CB7:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE63866DF663EE6DDE63DE7FFE0000
+1CB8:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE63CE6DB663CE6DB663CE7FFE0000
+1CB9:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE63CE6DB663C66DF663CE7FFE0000
+1CBA:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE63866DB663866DB663B67FFE0000
+1CBB:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE638E6DB6638E6DB6638E7FFE0000
+1CBC:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE63C66DBE63BE6DBE63C67FFE0000
+1CBD:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE638E6DB663B66DB6638E7FFE0000
+1CBE:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE63866DBE638E6DBE63867FFE0000
+1CBF:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE63866DBE638E6DBE63BE7FFE0000
+1CC0:000000000000028001000380044029281AB02928044003800100028000000000
+1CC1:0000000000000000000001C00220055004900550022001C00000000000000000
+1CC2:0000000000000000000001C0022005D0041005D0022001C00000000000000000
+1CC3:0000000000000000000001C00220041004100410022001C00000000000000000
+1CC4:000000000000000000001BBB200821CB44104AD68920FDAC002000E0013400C8
+1CC5:000000000000000000001F3801000170020002E0040005C00000000000000000
+1CC6:00000000000003BF0400043E0800083E1100129C22403F280000000000000000
+1CC7:00000000000000000000F97D0204E409090892932250BF670000000000000000
+1CC8:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE71CE6FB66FCE6FB671CE7FFE0000
+1CC9:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE71CE6FB66FC66FF671CE7FFE0000
+1CCA:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE71866FB66F866FB671B67FFE0000
+1CCB:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE718E6FB66F8E6FB6718E7FFE0000
+1CCC:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE71C66FBE6FBE6FBE71C67FFE0000
+1CCD:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE718E6FB66FB66FB6718E7FFE0000
+1CCE:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE71866FBE6F8E6FBE71867FFE0000
+1CCF:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+1CD0:0080014002200000000000000000000000000000000000000000000000000000
+1CD1:008001C002A00000000000000000000000000000000000000000000000000000
+1CD2:000003E000000000000000000000000000000000000000000000000000000000
+1CD3:0000012002400480000000000000000000000000000000000000000000000000
+1CD4:0000000000000000000000000000003800000000000000000000000000000000
+1CD5:0000000000000000000000000000000000000000000000000000089004900360
+1CD6:00000000000000000000000000000000000000000000000000000000040007E0
+1CD7:00000000000000000000000000000000000000000000000000000300040003E0
+1CD8:00000000000000000000000000000000000000000000000000000420022001C0
+1CD9:0000000000000000000000000000000000000000000000000000008001400220
+1CDA:0140014001400000000000000000000000000000000000000000000000000000
+1CDB:02A002A002A00000000000000000000000000000000000000000000000000000
+1CDC:0000000000000000000000000000000000000000000000000000008000800080
+1CDD:0000000000000000000000000000000000000000000000000000000000800000
+1CDE:0000000000000000000000000000000000000000000000000000000001200000
+1CDF:0000000000000000000000000000000000000000000000000000000004900000
+1CE0:007C008000600000000000000000000000000000000000000000000000000000
+1CE1:000C0012001100100010001000100010001000100010001000100010001000F0
+1CE2:0000000000000000000000000240000007E00000024000000000000000000000
+1CE3:0000000000000000002000100008000800700000000000000000000000000000
+1CE4:000000000000000004000800100010000E000000000000000000000000000000
+1CE5:000000000000000000000000000000000E001000100008000400000000000000
+1CE6:0000000000000000000000000000000000700008000800100020000000000000
+1CE7:0000000000180024002000100008000800700000000000000000000000000000
+1CE8:000000000000000000000000000000000E001000100008000400240018000000
+1CE9:00000000000000000C6012902C682008200820081010082007C0000000000000
+1CEA:00000000000004400AA00AA004400820101010101010082007C0000000000000
+1CEB:00000000000004600A900A7004100810101010101010082007C0000000000000
+1CEC:00000000000004000A200A500450083010181014102408480780000000000000
+1CED:0000000000000000000000000000000000000000000000000100008000400020
+1CEE:0000000000000780080008000800072004000400044003800000000000000000
+1CEF:000000000000078008400900040003C004000500048003000000000000000000
+1CF0:0000018002400200011001800240042004200420024001800000000000000000
+1CF1:0000000000000000020004000840080007E00010021000200040000000000000
+1CF2:0000000000000000000000000009000600000006000900000000000000000000
+1CF3:0000000000000000000000000008000500050008000000000000000000000000
+1CF4:0000108008800700000000000000000000000000000000000000000000000000
+1CF5:0000000000000000022002200140014000800140014002200220000000000000
+1CF6:00000000000000000000124012400D80000000000D8012401240000000000000
+1CF7:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+1CF8:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+1CF9:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+1CFA:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE61866FB663866FB66FB67FFE0000
+1CFB:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+1CFC:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+1CFD:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE618E6FB663B66FB66F8E7FFE0000
+1CFE:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE61866FBE638E6FBE6F867FFE0000
+1CFF:00007FFE7BC673BE7BBE7BBE71C67FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+1D00:000000000000102844447C4444440000
+1D01:0000000000001E28487E4848484E0000
+1D02:0000000000007C921212FC90927C0000
+1D03:000000000000784448FE484444780000
+1D04:0000000000003C4240404040423C0000
+1D05:00000000000078444444444444780000
+1D06:000000000000784444E4444444780000
+1D07:0000000000007C4040784040407C0000
+1D08:0000000000003C42021C0242423C0000
+1D09:00000000007C10101010101018001010
+1D0A:0000000000007C101010101010600000
+1D0B:00000000000022242830302824220000
+1D0C:000000000000202028302060203E0000
+1D0D:000000000000222236362A2A22220000
+1D0E:000000000000444C4C54546464440000
+1D0F:0000000000003C4242424242423C0000
+1D10:00000000003C4202020202423C000000
+1D11:00000000000000003E414141413E0000
+1D12:00000000000000003E41414141220000
+1D13:00000000000000203E514949453E0200
+1D14:00000000000036490909794949360000
+1D15:00000000000044444438444444380000
+1D16:0000000000001C222200000000000000
+1D17:00000000000000000000004444380000
+1D18:0000000000007C42427C404040400000
+1D19:0000000000003E42423E122242420000
+1D1A:000000000000424222123E42423E0000
+1D1B:0000000000007F080808080808080000
+1D1C:000000000000424242424242423C0000
+1D1D:000000000000003F02010101013E0000
+1D1E:000000000000001F42010101411E0000
+1D1F:0000000000007F0101017E01017E0000
+1D20:00000000000041412222141408080000
+1D21:00000000000042425A5A666642420000
+1D22:0000000000007E0204081020407E0000
+1D23:0000000000007E04081C0202423C0000
+1D24:000000003C42020418182040423C0000
+1D25:0000000000387CFEFE7C3810926C0000
+1D26:0000000000007E404040404040400000
+1D27:00000000000008081414222241410000
+1D28:0000000000007F222222222222220000
+1D29:0000000000007C42427C404040400000
+1D2A:000000000000494949493E0808080000
+1D2B:0000000000001E121212121222620000
+1D2C:0000102844447C444444000000000000
+1D2D:00001E28487E4848484E000000000000
+1D2E:00007844447844444478000000000000
+1D2F:00784448FE4844447800000000000000
+1D30:00007844444444444478000000000000
+1D31:00007C4040784040407C000000000000
+1D32:00007C04043C0404047C000000000000
+1D33:00003C4240404E42463A000000000000
+1D34:00004242427E42424242000000000000
+1D35:00007C1010101010107C000000000000
+1D36:00007C10101010101060000000000000
+1D37:00002224283030282422000000000000
+1D38:0000202020202020203E000000000000
+1D39:0000222236362A2A2222000000000000
+1D3A:000044646454544C4C44000000000000
+1D3B:0000444C4C5454646444000000000000
+1D3C:00003C4242424242423C000000000000
+1D3D:00004444443844444438000000000000
+1D3E:00007C42427C40404040000000000000
+1D3F:00007C42427C48444242000000000000
+1D40:00007F08080808080808000000000000
+1D41:0000424242424242423C000000000000
+1D42:000042425A5A66664242000000000000
+1D43:00003C42023E4242463A000000000000
+1D44:00005C6242427C40423C000000000000
+1D45:0000324A444444444A32000000000000
+1D46:00007C921212FC90927C000000000000
+1D47:00004040407844444478000000000000
+1D48:00000404043C4444443C000000000000
+1D49:00003C42427E4040423C000000000000
+1D4A:00003C4202027E42423C000000000000
+1D4B:00003C4242403840423C000000000000
+1D4C:00003C42021C0242423C000000000000
+1D4D:00023A44444438203C42423C00000000
+1D4E:00007C10101010101800100000000000
+1D4F:00004040404850605048000000000000
+1D50:00007649494949494949000000000000
+1D51:00005C624242424242420A0400000000
+1D52:00003C4242424242423C000000000000
+1D53:00003C4202020202423C000000000000
+1D54:00001C22220000000000000000000000
+1D55:0000000022221C000000000000000000
+1D56:00005C6242424242625C404000000000
+1D57:000010107C101010100C000000000000
+1D58:0000424242424242463A000000000000
+1D59:000000007E040202027C000000000000
+1D5A:00004949494949494937000000000000
+1D5B:00004242422424241818000000000000
+1D5C:00387CFEFE7C3810926C000000000000
+1D5D:00003844447C4242625C400000000000
+1D5E:000031490A0408081010000000000000
+1D5F:00001C2020182442423C000000000000
+1D60:0000264949494949493E080800000000
+1D61:00006212141810304846000000000000
+1D62:0000000000001010003010101010107C
+1D63:0000000000000000005C624240404040
+1D64:0000000000000000004242424242463A
+1D65:00000000000000000042424224241818
+1D66:000000000000003844447C4242625C40
+1D67:00000000000000000000314906081010
+1D68:00000000000000000038444478403804
+1D69:000000000000000026494949493E0808
+1D6A:00000000000000006212141810304846
+1D6B:0000000000008E89898F8888996E0000
+1D6C:0000002870A02C3222222222322C0000
+1D6D:000000050E1404344C4444444C340000
+1D6E:0000000C1010107C1010143850100000
+1D6F:0000000000007C4A4A4A7BCE4A4A0000
+1D70:0000000000002C322222336E22220000
+1D71:0000000000002C3222336E22322C2020
+1D72:0000000000002C322220396620200000
+1D73:0000000000000C122220396620200000
+1D74:0000000000003C424033CC0242340000
+1D75:0000000010107C1010325C10100C0000
+1D76:0000000000007E02046A9C20407E0000
+1D77:00000000003C42423C20384444443A02
+1D78:00004242427E42424242000000000000
+1D79:0000000000007E04081010083C42423C
+1D7A:000000000008009008A008C03EB809C40A840C84088418842884068400000000
+1D7B:0000000000007C10107C1010107C0000
+1D7C:0000000000007010107C1010100C0000
+1D7D:0000000000002C32227F2222322C2020
+1D7E:0000000000002222227F2222221C0000
+1D7F:0000000000004122227F2222221C0000
+1D80:0000004040405C6242424242635D0106
+1D81:0000000202023A4642424242463B0106
+1D82:0000000C1010107C1010101018180830
+1D83:000000000000003C4444444447390972
+1D84:0000000040404448506050484642020C
+1D85:0000000018080808080808080A3E020C
+1D86:000000000000744A4A4A4A4A4B4B0106
+1D87:0000000000005C624242424243430106
+1D88:000000000000586444444444665A424C
+1D89:0000000000002C322220202030301060
+1D8A:0000000000003C4240300C02433D0106
+1D8B:0000000C101010101010101E1212620C
+1D8C:0000000000004242422424261A1A020C
+1D8D:0000000000004444281010284646020C
+1D8E:0000000000007E0204081020407E020C
+1D8F:0000000000003844043C44444E36020C
+1D90:0000000000003844043C44444C340403
+1D91:000003040404344C44444444443C0404
+1D92:0000000000003C42427E4040423C0403
+1D93:0000000000003C42403C4040423C0403
+1D94:0000000000003C42023C0202423C1060
+1D95:0000000000000000000000000F001080008000801FE010A010A00F2000200018
+1D96:000000080800180808080808083C0403
+1D97:0000000000003C4202020202427C4030
+1D98:0000000C101010101010101010604030
+1D99:0000000000008888888888889C6C0403
+1D9A:0000000000007E0408101C02023C2018
+1D9B:0000005C6242424242625C0000000000
+1D9C:00000038444040404438000000000000
+1D9D:00000038444040586438400000000000
+1D9E:320C14021E22222222221C0000000000
+1D9F:0000001C22021C02221C000000000000
+1DA0:00000C10107C10101010000000000000
+1DA1:0000080808083E080830000000000000
+1DA2:00003848484848380808700000000000
+1DA3:0000444444444C340404040000000000
+1DA4:0000100030103810107C000000000000
+1DA5:0000000030101010100C000000000000
+1DA6:00007C10101010107C00000000000000
+1DA7:00007C10107C10107C00000000000000
+1DA8:0000080018080808384C320000000000
+1DA9:0000701010101010100C000000000000
+1DAA:00001010101010181808300000000000
+1DAB:000010101010101E0000000000000000
+1DAC:00007649494949494949010600000000
+1DAD:00004949494949494937010101000000
+1DAE:00001619111111111111106000000000
+1DAF:00005864444444444404030000000000
+1DB0:00002232322A2A262622000000000000
+1DB1:00001824427E42241800000000000000
+1DB2:00001010385454543810100000000000
+1DB3:00001824100824382018000000000000
+1DB4:0000000C101010101010106000000000
+1DB5:000010107C101010120E020C00000000
+1DB6:00002222227F2222261A000000000000
+1DB7:0000771422222222221C000000000000
+1DB8:0000222222222222221C000000000000
+1DB9:00046222242830200000000000000000
+1DBA:00000814142222000000000000000000
+1DBB:00003E0408103E000000000000000000
+1DBC:00007C0810247C040300000000000000
+1DBD:00007C0816297E100000000000000000
+1DBE:00007E04081C02423C00000000000000
+1DBF:00000814223E22221408000000000000
+1DC0:00241008240000000000000000000000
+1DC1:00240810240000000000000000000000
+1DC2:00000000000000000000000070381C0E
+1DC3:00022418000000000000000000000000
+1DC4:00020478000000000000000000000000
+1DC5:0040201E000000000000000000000000
+1DC6:00780402000000000000000000000000
+1DC7:003C4080000000000000000000000000
+1DC8:00885422000000000000000000000000
+1DC9:00225488000000000000000000000000
+1DCA:0000000000000000000000002C302020
+1DCB:008E7000000000000000000000000000
+1DCC:00708E00000000000000000000000000
+1DCD:00186681000000000000000000000000
+1DCE:00300808100000000000000000000000
+1DCF:000000000000000000000010203C0408
+1DD0:00000000000000000000000812394600
+1DD1:0064924C000000000000000000000000
+1DD2:00182414040810000000000000000000
+1DD3:00926C00000000000000000000000000
+1DD4:EC127C906E0000000000000000000000
+1DD5:EC1272926C0000000000000000000000
+1DD6:E1117A9A640000000000000000000000
+1DD7:1C2020201C0810000000000000000000
+1DD8:30081C24180000000000000000000000
+1DD9:2810281C241800000000000000000000
+1DDA:1C241C04380000000000000000000000
+1DDB:1C202C24180000000000000000000000
+1DDC:20242834240000000000000000000000
+1DDD:180808081C0000000000000000000000
+1DDE:202020203C0000000000000000000000
+1DDF:446C5444440000000000000000000000
+1DE0:58644444000000000000000000000000
+1DE1:4464544C440000000000000000000000
+1DE2:38243828240000000000000000000000
+1DE3:18240408040200000000000000000000
+1DE4:1C201804380000000000000000000000
+1DE5:18242060202000000000000000000000
+1DE6:3C0418203C0000000000000000000000
+1DE7:00007FFE7B8E73B67BB67BB6718E7FFE7FFE61866FF663EE6FDE61DE7FFE0000
+1DE8:00007FFE7B8E73B67BB67BB6718E7FFE7FFE61CE6FB663CE6FB661CE7FFE0000
+1DE9:00007FFE7B8E73B67BB67BB6718E7FFE7FFE61CE6FB663C66FF661CE7FFE0000
+1DEA:00007FFE7B8E73B67BB67BB6718E7FFE7FFE61866FB663866FB661B67FFE0000
+1DEB:00007FFE7B8E73B67BB67BB6718E7FFE7FFE618E6FB6638E6FB6618E7FFE0000
+1DEC:00007FFE7B8E73B67BB67BB6718E7FFE7FFE61C66FBE63BE6FBE61C67FFE0000
+1DED:00007FFE7B8E73B67BB67BB6718E7FFE7FFE618E6FB663B66FB6618E7FFE0000
+1DEE:00007FFE7B8E73B67BB67BB6718E7FFE7FFE61866FBE638E6FBE61867FFE0000
+1DEF:00007FFE7B8E73B67BB67BB6718E7FFE7FFE61866FBE638E6FBE61BE7FFE0000
+1DF0:00007FFE7B8E73B67BB67BB6718E7FFE7FFE61CE6FB663B66FB66FCE7FFE0000
+1DF1:00007FFE7B8E73B67BB67BB6718E7FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000
+1DF2:00007FFE7B8E73B67BB67BB6718E7FFE7FFE61866FF663866FBE6F867FFE0000
+1DF3:00007FFE7B8E73B67BB67BB6718E7FFE7FFE618E6FF663C66FF66F8E7FFE0000
+1DF4:00007FFE7B8E73B67BB67BB6718E7FFE7FFE61B66FB663866FF66FF67FFE0000
+1DF5:00007FFE7B8E73B67BB67BB6718E7FFE7FFE61866FBE63866FF66F867FFE0000
+1DF6:00007FFE7B8E73B67BB67BB6718E7FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+1DF7:00007FFE7B8E73B67BB67BB6718E7FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+1DF8:00007FFE7B8E73B67BB67BB6718E7FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+1DF9:00007FFE7B8E73B67BB67BB6718E7FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+1DFA:00007FFE7B8E73B67BB67BB6718E7FFE7FFE61866FB663866FB66FB67FFE0000
+1DFB:00007FFE7B8E73B67BB67BB6718E7FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+1DFC:000000000000000000000000000000000000000000000000000001E006180804
+1DFD:0000000000000000000000324C00324C
+1DFE:08102010080000000000000000000000
+1DFF:000000000000000000000000004A2440
+1E00:000000001028448282D6828282922810
+1E01:0000000000003C42023E42463A081408
+1E02:001000007C4242427C424242427C0000
+1E03:0000004840405C6242424242625C0000
+1E04:000000007C4242427C424242427C0010
+1E05:0000004040405C6242424242625C0008
+1E06:000000007C4242427C424242427C003C
+1E07:0000004040405C6242424242625C003C
+1E08:081020003C42424040404042423C0830
+1E09:0000081020003C4240404040423C0830
+1E0A:00100000784442424242424244780000
+1E0B:0000001202023A4642424242463A0000
+1E0C:00000000784442424242424244780010
+1E0D:0000000202023A4642424242463A0010
+1E0E:0000000078444242424242424478003C
+1E0F:0000000202023A4642424242463A003C
+1E10:00000000784442424242424244781020
+1E11:0000000202023A4642424242463A0810
+1E12:00000000784442424242424244783048
+1E13:0000000202023A4642424242463A1824
+1E14:10083C007E4040407C404040407E0000
+1E15:201008003C003C42427E4040423C0000
+1E16:08103C007E4040407C404040407E0000
+1E17:081020003C003C42427E4040423C0000
+1E18:000000007E4040407C404040407E1824
+1E19:0000000000003C42427E4040423C1824
+1E1A:000000007E4040407C404040407E324C
+1E1B:0000000000003C42427E4040423C324C
+1E1C:00221C007E4040407C404040407E0418
+1E1D:0000221C00003C42427E4040423C0830
+1E1E:001000007E4040407C40404040400000
+1E1F:0800000C1010107C1010101010100000
+1E20:00003C003C424240404E4242463A0000
+1E21:0000000078023A44444438203C42423C
+1E22:00001000444444447C44444444440000
+1E23:0000004840405C624242424242420000
+1E24:00000000444444447C44444444440010
+1E25:0000004040405C624242424242420008
+1E26:00240000424242427E42424242420000
+1E27:2400004040405C624242424242420000
+1E28:00000000424242427E42424262621060
+1E29:0000004040405C624242424262621060
+1E2A:0000000082828282FE82828282822838
+1E2B:0000004040404E51614141414141141C
+1E2C:000000003E08080808080808083E324C
+1E2D:000000080800180808080808083E324C
+1E2E:04082A003E08080808080808083E0000
+1E2F:000204082200180808080808083E0000
+1E30:00040810424448506060504844420000
+1E31:00040810404044485060504844420000
+1E32:00000000424448506060504844420010
+1E33:00000000404044485060504844420010
+1E34:0000000042444850606050484442003C
+1E35:0000000040404448506050484442003C
+1E36:000000004040404040404040407E0010
+1E37:000000001808080808080808083E0008
+1E38:00003C004040404040404040407E0010
+1E39:00003C001808080808080808083E0008
+1E3A:000000004040404040404040407E003C
+1E3B:000000001808080808080808083E001C
+1E3C:000000004040404040404040407E1824
+1E3D:000000001808080808080808083E1824
+1E3E:00040810424266665A5A424242420000
+1E3F:00000408100076494949494949490000
+1E40:00001000424266665A5A424242420000
+1E41:00000008000076494949494949490000
+1E42:00000000424266665A5A424242420008
+1E43:00000000000076494949494949490008
+1E44:0000080042626252524A4A4646420000
+1E45:0000000800005C624242424242420000
+1E46:0000000042626252524A4A4646420008
+1E47:0000000000005C624242424242420008
+1E48:0000000042626252524A4A464642003C
+1E49:0000000000005C62424242424242003C
+1E4A:0000000042626252524A4A4646421824
+1E4B:0000000000005C624242424242421824
+1E4C:0408324C3C42424242424242423C0000
+1E4D:020408324C003C4242424242423C0000
+1E4E:2400324C3C42424242424242423C0000
+1E4F:002400324C003C4242424242423C0000
+1E50:10083C003C42424242424242423C0000
+1E51:201008003C003C4242424242423C0000
+1E52:08103C003C42424242424242423C0000
+1E53:081020003C003C4242424242423C0000
+1E54:000408107C4242427C40404040400000
+1E55:0000040810005C6242424242625C4040
+1E56:001000007C4242427C40404040400000
+1E57:0000000800005C6242424242625C4040
+1E58:001000007C4242427C48444442420000
+1E59:0000001000005C624240404040400000
+1E5A:000000007C4242427C48444442420008
+1E5B:0000000000005C624240404040400800
+1E5C:00003C007C4242427C48444442420008
+1E5D:000000003C005C624240404040400800
+1E5E:000000007C4242427C4844444242003C
+1E5F:0000000000005C62424040404040003C
+1E60:001000003C424240300C0242423C0000
+1E61:0000001000003C4240300C02423C0000
+1E62:000000003C424240300C0242423C0008
+1E63:0000000000003C4240300C02423C0008
+1E64:240810003C424240300C0242423C0000
+1E65:0020081020003C4240300C02423C0000
+1E66:082214083C424240300C0242423C0000
+1E67:0008002214083C4240300C02423C0000
+1E68:000800003C424240300C0242423C0008
+1E69:0000000800003C4240300C02423C0008
+1E6A:000800007F0808080808080808080000
+1E6B:0010000010107C1010101010100C0000
+1E6C:000000007F0808080808080808080008
+1E6D:0000000010107C1010101010100C0010
+1E6E:000000007F080808080808080808003E
+1E6F:0000000010107C1010101010100C003C
+1E70:000000007F0808080808080800081422
+1E71:0000000010107C1010101010120C1422
+1E72:000000004242424242424242423C0024
+1E73:000000000000424242424242463A0028
+1E74:000000004242424242424242423C324C
+1E75:000000000000424242424242463A324C
+1E76:000000004242424242424242423C1422
+1E77:000000000000424242424242463A1422
+1E78:0408324C0042424242424242423C0000
+1E79:020408324C00424242424242463A0000
+1E7A:24003C004242424242424242423C0000
+1E7B:000024003C00424242424242463A0000
+1E7C:0000324C004141222222141408080000
+1E7D:0000324C000042424224242418180000
+1E7E:00000000414141222222141408080008
+1E7F:00000000000044444428282810100010
+1E80:00201008424242425A5A666642420000
+1E81:00001008040041494949494949360000
+1E82:00040810424242425A5A666642420000
+1E83:00000408100041494949494949360000
+1E84:00240000424242425A5A666642420000
+1E85:00000022000041494949494949360000
+1E86:001000004444444454546C6C44440000
+1E87:00000008000041494949494949360000
+1E88:000000004444444454546C6C44440010
+1E89:00000000000041494949494949360008
+1E8A:00100000444428281010282844440000
+1E8B:00000010000044442810102844440000
+1E8C:00240000424224241818242442420000
+1E8D:00000024000042422418182442420000
+1E8E:00080000414122221408080808080000
+1E8F:0000000800004242424242261A02023C
+1E90:081422007E02020408102040407E0000
+1E91:0008142200007E0204081020407E0000
+1E92:000000007E02020408102040407E0008
+1E93:0000000000007E0204081020407E0008
+1E94:000000007E02020408102040407E003C
+1E95:0000000000007E0204081020407E003C
+1E96:0000004040405C62424242424242003C
+1E97:0000440010107C1010101010100C0000
+1E98:00081408000041494949494949360000
+1E99:0008140800004242424242261A02023C
+1E9A:0002010102003C42023E4242463A0000
+1E9B:0010000C101010301010101010100000
+1E9C:0000000C101010341830501010100000
+1E9D:0000000C107C10301010101010100000
+1E9E:0000003E424444484C424242524C0000
+1E9F:000000001C20202018244242423C0000
+1EA0:0000000010282844447C444444440010
+1EA1:0000000000003C42023E4242463A0010
+1EA2:4020204018242442427E424242420000
+1EA3:0008040408003C42023E4242463A0000
+1EA4:0214284410282844447C444444440000
+1EA5:0002142844003C42023E4242463A0000
+1EA6:4028142208141422223E222222220000
+1EA7:0040281422003C42023E4242463A0000
+1EA8:0402142854282844447C444444440000
+1EA9:02010A1422003C42023E4242463A0000
+1EAA:192608142208141422223E2222220000
+1EAB:1926081422003C42023E4242463A0000
+1EAC:0008142208141422223E222222220008
+1EAD:0000081422003C42023E4242463A0008
+1EAE:0810443810282844447C444444440000
+1EAF:0408104438003C42023E4242463A0000
+1EB0:2010443810282844447C444444440000
+1EB1:201008221C003C42023E4242463A0000
+1EB2:1008B27C10282844447C444444440000
+1EB3:0808104438003C42023E4242463A0000
+1EB4:324C827C10282844447C444444440000
+1EB5:324C00423C003C42023E4242463A0000
+1EB6:0000443810282844447C444444440010
+1EB7:0000002418003C42023E4242463A0010
+1EB8:000000007E4040407C404040407E0010
+1EB9:0000000000003C42427E4040423C0010
+1EBA:100808107E4040407C404040407E0000
+1EBB:1008081000003C42427E4040423C0000
+1EBC:00324C007E4040407C404040407E0000
+1EBD:000000324C003C42427E4040423C0000
+1EBE:021428447E4040407C404040407E0000
+1EBF:0002142844003C42427E4040423C0000
+1EC0:402814227E4040407C404040407E0000
+1EC1:0040281422003C42427E4040423C0000
+1EC2:04122A447E4040407C404040407E0000
+1EC3:0402122C44003C42427E4040423C0000
+1EC4:324C1028447E40407C404040407E0000
+1EC5:324C102844003C42427E4040423C0000
+1EC6:000814227E4040407C404040407E0008
+1EC7:0000081422003C42427E4040423C0008
+1EC8:080404083E08080808080808083E0000
+1EC9:001008081000180808080808083E0000
+1ECA:000000003E08080808080808083E0008
+1ECB:000000080800180808080808083E0008
+1ECC:000000003C42424242424242423C0008
+1ECD:0000000000003C4242424242423C0008
+1ECE:100808103C42424242424242423C0000
+1ECF:0010080810003C4242424242423C0000
+1ED0:021428443C42424242424242423C0000
+1ED1:0002142844003C4242424242423C0000
+1ED2:402814223C42424242424242423C0000
+1ED3:0040281422003C4242424242423C0000
+1ED4:04122A443C42424242424242423C0000
+1ED5:0402122C44003C4242424242423C0000
+1ED6:324C1028443C424242424242423C0000
+1ED7:324C102844003C4242424242423C0000
+1ED8:001028443C42424242424242423C0008
+1ED9:0000081422003C4242424242423C0008
+1EDA:08102201394644444444444444380000
+1EDB:00000810220139464444444444380000
+1EDC:20100A01394644444444444444380000
+1EDD:000020100A0139464444444444380000
+1EDE:10080A11394644444444444444380000
+1EDF:00100808120139464444444444380000
+1EE0:00324C02394546444444444444380000
+1EE1:00324C00020139464444444444380000
+1EE2:00000201394644444444444444380010
+1EE3:00000000020139464444444444380010
+1EE4:000000004242424242424242423C0008
+1EE5:000000000000424242424242463A0008
+1EE6:100808104242424242424242423C0000
+1EE7:001008081000424242424242463A0000
+1EE8:04081201454644444444444444380000
+1EE9:0000040812014546444444444C340000
+1EEA:40201201454644444444444444380000
+1EEB:0000402012014546444444444C340000
+1EEC:10080A11454644444444444444380000
+1EED:0010080812014546444444444C340000
+1EEE:324C0201454644444444444444380000
+1EEF:00324C0002014546444444444C340000
+1EF0:00000201454644444444444444380010
+1EF1:0000000002014546444444444C340010
+1EF2:20100800414122221408080808080000
+1EF3:0020100800004242424242261A02023C
+1EF4:00000000414122221408080808080008
+1EF5:0000000000004242424242261A023C08
+1EF6:08040408414122221408080808080000
+1EF7:0010080810004242424242261A02023C
+1EF8:00324C00414122221408080808080000
+1EF9:0000324C00004242424242261A02023C
+1EFA:00000000F05050505050505050FE0000
+1EFB:000000006C24247E2424242424FF0000
+1EFC:000000000408101020244242423C0000
+1EFD:00000000000008102020484444380000
+1EFE:00000000424222141408080808384830
+1EFF:00000000000042422214140808384830
+1F00:000030102000324A444444444A320000
+1F01:000030201000324A444444444A320000
+1F02:000068284400324A444444444A320000
+1F03:000068482400324A444444444A320000
+1F04:000064284800324A444444444A320000
+1F05:000064482800324A444444444A320000
+1F06:64980030102000324A4444444A320000
+1F07:64980030201000324A4444444A320000
+1F08:C040800018242442427E424242420000
+1F09:C080400018242442427E424242420000
+1F0A:D050880018242442427E424242420000
+1F0B:D090480018242442427E424242420000
+1F0C:C850900018242442427E424242420000
+1F0D:C890500018242442427E424242420000
+1F0E:6498602040182424427E424242420000
+1F0F:6498604020182424427E424242420000
+1F10:0000180810003C42403C4040423C0000
+1F11:0000181008003C42403C4040423C0000
+1F12:0000341422003C42403C4040423C0000
+1F13:0000342412003C42403C4040423C0000
+1F14:0000321424003C42403C4040423C0000
+1F15:0000322414003C42403C4040423C0000
+1F16:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE7BCE73BE7B8E7BB671CE7FFE0000
+1F17:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE7B8673F67BEE7BDE71DE7FFE0000
+1F18:C04080007E4040407C404040407E0000
+1F19:C08040007E4040407C404040407E0000
+1F1A:D05088007E4040407C404040407E0000
+1F1B:D09048007E4040407C404040407E0000
+1F1C:C85090007E4040407C404040407E0000
+1F1D:C89050007E4040407C404040407E0000
+1F1E:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE7B8673BE7B8E7BBE71867FFE0000
+1F1F:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE7B8673BE7B8E7BBE71BE7FFE0000
+1F20:0000180810005C624242424242420202
+1F21:0000181008005C624242424242420202
+1F22:0000341422005C624242424242420202
+1F23:0000342412005C624242424242420202
+1F24:0000321424005C624242424242420202
+1F25:0000322414005C624242424242420202
+1F26:324C00180810005C6242424242420202
+1F27:324C00181008005C6242424242420202
+1F28:C0408000424242427E42424242420000
+1F29:C0804000424242427E42424242420000
+1F2A:D0508800424242427E42424242420000
+1F2B:D0904800424242427E42424242420000
+1F2C:C8509000424242427E42424242420000
+1F2D:C8905000424242427E42424242420000
+1F2E:64986020404242427E42424242420000
+1F2F:64986040204242427E42424242420000
+1F30:000018081000101010101010100C0000
+1F31:000018100800101010101010100C0000
+1F32:000068284400101010101010100C0000
+1F33:000068482400101010101010100C0000
+1F34:000064284800101010101010100C0000
+1F35:000064482800101010101010100C0000
+1F36:324C00180810001010101010100C0000
+1F37:324C00181008001010101010100C0000
+1F38:C04080003E08080808080808083E0000
+1F39:C08060003E08080808080808083E0000
+1F3A:D05088003E08080808080808083E0000
+1F3B:D09048003E08080808080808083E0000
+1F3C:C85090003E08080808080808083E0000
+1F3D:C89050003E08080808080808083E0000
+1F3E:64986020403E080808080808083E0000
+1F3F:64986040203E080808080808083E0000
+1F40:0000180810003C4242424242423C0000
+1F41:0000181008003C4242424242423C0000
+1F42:0000341422003C4242424242423C0000
+1F43:0000342412003C4242424242423C0000
+1F44:0000321424003C4242424242423C0000
+1F45:0000322414003C4242424242423C0000
+1F46:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE6DCE6DBE618E7DB67DCE7FFE0000
+1F47:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE6D866DF661EE7DDE7DDE7FFE0000
+1F48:C04080003C42424242424242423C0000
+1F49:C08040003C42424242424242423C0000
+1F4A:D05088003C42424242424242423C0000
+1F4B:D09048003C42424242424242423C0000
+1F4C:C85090003C42424242424242423C0000
+1F4D:C89050003C42424242424242423C0000
+1F4E:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE6D866DBE618E7DBE7D867FFE0000
+1F4F:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE6D866DBE618E7DBE7DBE7FFE0000
+1F50:000018081000424242424242423C0000
+1F51:000018100800424242424242423C0000
+1F52:000034142200424242424242423C0000
+1F53:000034241200424242424242423C0000
+1F54:000032142400424242424242423C0000
+1F55:000032241400424242424242423C0000
+1F56:324C00180810424242424242423C0000
+1F57:324C00181008424242424242423C0000
+1F58:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE61CE6FB661CE7DB661CE7FFE0000
+1F59:C0804000414122221408080808080000
+1F5A:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE61866FB661867DB661B67FFE0000
+1F5B:D0904800414122221408080808080000
+1F5C:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE61C66FBE61BE7DBE61C67FFE0000
+1F5D:C8905000414122221408080808080000
+1F5E:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE61866FBE618E7DBE61867FFE0000
+1F5F:64986040204122221408080808080000
+1F60:00000C04080022414149494949360000
+1F61:00000C08040022414149494949360000
+1F62:00003414220022414149494949360000
+1F63:00003424120022414149494949360000
+1F64:00003214240022414149494949360000
+1F65:00003224140022414149494949360000
+1F66:324C0018081000224149494949360000
+1F67:324C0018100800224149494949360000
+1F68:C04080003E4141414141221414770000
+1F69:C08040003E4141414141221414770000
+1F6A:D05088003E4141414141221414770000
+1F6B:D09048003E4141414141221414770000
+1F6C:C85090003E4141414141221414770000
+1F6D:C89050003E4141414141221414770000
+1F6E:324C1808101C22414141221414770000
+1F6F:324C1810081C23414141221414770000
+1F70:000020201000324A444444444A320000
+1F71:000010202000324A444444444A320000
+1F72:0000101008003C42403C4040423C0000
+1F73:0000081010003C42403C4040423C0000
+1F74:0000101008005C624242424242420202
+1F75:0000081010005C624242424242420202
+1F76:000010100800101010101010100C0000
+1F77:000008101000101010101010100C0000
+1F78:0000101008003C4242424242423C0000
+1F79:0000081010003C4242424242423C0000
+1F7A:000010100800424242424242423C0000
+1F7B:000008101000424242424242423C0000
+1F7C:00001010080022414149494949360000
+1F7D:00000408080022414149494949360000
+1F7E:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE61867DBE7B8E77BE77867FFE0000
+1F7F:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE61867DBE7B8E77BE77BE7FFE0000
+1F80:000030102000324A444444444A322030
+1F81:000030201000324A444444444A322030
+1F82:000068284400324A444444444A322030
+1F83:000068482400324A444444444A322030
+1F84:000064284800324A444444444A322030
+1F85:000064482800324A444444444A322030
+1F86:324C0030102000324A4444444A322030
+1F87:324C0030201000324A4444444A322030
+1F88:C040800018242442427E42424242100C
+1F89:C080400018242442427E42424242100C
+1F8A:D050880018242442427E42424242100C
+1F8B:D090480018242442427E42424242100C
+1F8C:C850900018242442427E42424242100C
+1F8D:C890500018242442427E42424242100C
+1F8E:6498602040182424427E42424242100C
+1F8F:6498604020182424427E42424242100C
+1F90:0000180810005C624242424242422232
+1F91:0000181008005C624242424242422232
+1F92:0000341422005C624242424242422232
+1F93:0000342412005C624242424242422232
+1F94:0000321424005C624242424242422232
+1F95:0000322414005C624242424242422232
+1F96:324C00180810005C6242424242422232
+1F97:324C00181008005C6242424242422232
+1F98:C0408000424242427E42424242422018
+1F99:C0804000424242427E42424242422018
+1F9A:D0508800424242427E42424242422018
+1F9B:D0904800424242427E42424242422018
+1F9C:C8509000424242427E42424242422018
+1F9D:C8905000424242427E42424242422018
+1F9E:64986020404242427E42424242422018
+1F9F:64986040204242427E42424242422018
+1FA0:0000180810002241414949494936080C
+1FA1:0000181008002241414949494936080C
+1FA2:0000341422002241414949494936080C
+1FA3:0000342412002241414949494936080C
+1FA4:0000321424002241414949494936080C
+1FA5:0000322414002241414949494936080C
+1FA6:324C001808100022414949494936080C
+1FA7:324C001810080022414949494936080C
+1FA8:C04080003E4141414141221414770806
+1FA9:C08040003E4141414141221414770806
+1FAA:D05088003E4141414141221414770806
+1FAB:D09048003E4141414141221414770806
+1FAC:C85090003E4141414141221414770806
+1FAD:C89050003E4141414141221414770806
+1FAE:64986020401C22414141221414770806
+1FAF:64986040201C22414141221414770806
+1FB0:000044443800324A444444444A320000
+1FB1:000000007C00324A444444444A320000
+1FB2:000020201000324A444444444A322030
+1FB3:000000000000324A444444444A322030
+1FB4:000010202000324A444444444A322030
+1FB5:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE63866DBE63866DF663867FFE0000
+1FB6:000000324C00324A444444444A320000
+1FB7:000000324C00324A444444444A322030
+1FB8:42423C0018242442427E424242420000
+1FB9:003C000018242442427E424242420000
+1FBA:8080400018242442427E424242420000
+1FBB:4080800018242442427E424242420000
+1FBC:0000000018242442427E42424242100C
+1FBD:00000000180810000000000000000000
+1FBE:0000000000000000000000000000100C
+1FBF:18081000000000000000000000000000
+1FC0:324C0000000000000000000000000000
+1FC1:324C0066000000000000000000000000
+1FC2:0000101008005C624242424242422232
+1FC3:0000000000005C624242424242422232
+1FC4:0000081010005C624242424242422232
+1FC5:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE71866FBE6F866FF671867FFE0000
+1FC6:000000324C005C624242424242420202
+1FC7:000000324C005C624242424242422232
+1FC8:808040007E4040407C404040407E0000
+1FC9:408080007E4040407C404040407E0000
+1FCA:80804000424242427E42424242420000
+1FCB:40808000424242427E42424242420000
+1FCC:00000000424242427E4242424242100C
+1FCD:68284400000000000000000000000000
+1FCE:64284800000000000000000000000000
+1FCF:324C0018081000000000000000000000
+1FD0:000044443800101010101010100C0000
+1FD1:000000003C00101010101010100C0000
+1FD2:101008006600101010101010100C0000
+1FD3:081010006600101010101010100C0000
+1FD4:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE63B66DB66D866DF663F67FFE0000
+1FD5:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE63866DBE6D866DF663867FFE0000
+1FD6:000000324C00101010101010100C0000
+1FD7:00324C006600101010101010100C0000
+1FD8:22221C003E08080808080808083E0000
+1FD9:003E00003E08080808080808083E0000
+1FDA:808040003E08080808080808083E0000
+1FDB:408080003E08080808080808083E0000
+1FDC:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE63C66DBE6DBE6DBE63C67FFE0000
+1FDD:68482400000000000000000000000000
+1FDE:64482800000000000000000000000000
+1FDF:324C0018100800000000000000000000
+1FE0:000042423C00424242424242423C0000
+1FE1:0000003C0000424242424242423C0000
+1FE2:101008006600424242424242423C0000
+1FE3:081010006600424242424242423C0000
+1FE4:0000180810003C4242424242625C4040
+1FE5:0000181008003C4242424242625C4040
+1FE6:000000324C00424242424242423C0000
+1FE7:00324C006600424242424242423C0000
+1FE8:22221C00414122221408080808080000
+1FE9:00003E00414122221408080808080000
+1FEA:80804000414122221408080808080000
+1FEB:40808000414122221408080808080000
+1FEC:C08040007C4242427C40404040400000
+1FED:10100800660000000000000000000000
+1FEE:08101000660000000000000000000000
+1FEF:10100800000000000000000000000000
+1FF0:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE61CE6FB663B66FB66FCE7FFE0000
+1FF1:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000
+1FF2:0000101008002241414949494936080C
+1FF3:0000000000002241414949494936080C
+1FF4:0000040808002241414949494936080C
+1FF5:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE61866FBE63866FF66F867FFE0000
+1FF6:000000324C0022414149494949360000
+1FF7:000000324C002241414949494936080C
+1FF8:808040003C42424242424242423C0000
+1FF9:408080003C42424242424242423C0000
+1FFA:808040003E4141414141221414770000
+1FFB:408080003E4141414141221414770000
+1FFC:000000003E4141414141221414770806
+1FFD:08101000000000000000000000000000
+1FFE:18100800000000000000000000000000
+1FFF:00007FFE7B8673BE7B8E7BBE71BE7FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+2000:00000000000000000000000000000000
+2001:00000000000000000000000000000000
+2002:00000000000000000000000000000000
+2003:00000000000000000000000000000000
+2004:00000000000000000000000000000000
+2005:00000000000000000000000000000000
+2006:00000000000000000000000000000000
+2007:00000000000000000000000000000000
+2008:00000000000000000000000000000000
+2009:00000000000000000000000000000000
+200A:00000000000000000000000000000000
+200B:AAAA00019E44024584540855906C1E4580000E3990240C3982201C2180005555
+200C:AAAA00019E44024584540855906C1E45800012099A0816499248123180005555
+200D:AAAA00019E44024584540855906C1E4580000041804002418240018180005555
+200E:AAAA000180000001C72244B7C72A4523F4A20001800000018000000180005555
+200F:AAAA000180000001F2224A37F22A5223CBA20001800000018000000180005555
+2010:0000000000000000003C000000000000
+2011:AAAA0001800012719A481671924812718000000183C000018000000180005555
+2012:0000000000000000007E000000000000
+2013:0000000000000000007E000000000000
+2014:000000000000000000FF000000000000
+2015:000000000000000000FF000000000000
+2016:00000014141414141414141414140000
+2017:00000000000000000000000000FF00FF
+2018:00000810101800000000000000000000
+2019:00001808081000000000000000000000
+201A:00000000000000000000000018080810
+201B:00001810100800000000000000000000
+201C:00002244446600000000000000000000
+201D:00006622224400000000000000000000
+201E:00000000000000000000000066222244
+201F:00006644442200000000000000000000
+2020:0000081C082A7F2A081C080808080000
+2021:00081C082A7F2A08082A7F2A081C0800
+2022:00000000000000387C7C7C3800000000
+2023:0000000000002030383C383020000000
+2024:00000000000000000000000018180000
+2025:00000000000000000000000036360000
+2026:00000000000000000000000049490000
+2027:00000000000000000018180000000000
+2028:AAAA00018000020182000201820003C180003BDDC21233DD8A1073D180005555
+2029:AAAA000180000381824003818200020180003BDDC21233DD8A1073D180005555
+202A:AAAA000180000001C39E4251C39E4291FA5E0001800000018000000180005555
+202B:AAAA000180000001F21E4A11F21E5211CBDE0001800000018000000180005555
+202C:AAAA000180000001F39E4A51F25E4251C3900001800000018000000180005555
+202D:AAAA000180000001C38C4253C3924293FA4C0001800000018000000180005555
+202E:AAAA000180000001F20C4A13F2125213CBCC0001800000018000000180005555
+202F:AAAA000180004A5DEB525ADDCA524A5D80000E3990240C3982201C2180005555
+2030:0000000042A4A44810102A55558A0000
+2031:0000000040A0A04C30C02A55552A0000
+2032:000000000C1810200000000000000000
+2033:00000000336644880000000000000000
+2034:000000003F7E54A80000000000000000
+2035:00000000301808040000000000000000
+2036:00000000CC6622110000000000000000
+2037:00000000FC7E2A150000000000000000
+2038:00000000000000000000000000102844
+2039:00000000020204040808040402020000
+203A:00000000404020201010202040400000
+203B:00000000004922144914224900000000
+203C:00000000242424242424240024240000
+203D:000000003C4A4A0A0C08080008080000
+203E:7E000000000000000000000000000000
+203F:0000000000000000000000000000423C
+2040:3C420000000000000000000000000000
+2041:00000000000000000000020408102844
+2042:000000000000081C0800227722000000
+2043:00000000000000003C3C000000000000
+2044:00000000020204080810102040400000
+2045:0000000E080808080E08080808080E00
+2046:00000070101010107010101010107000
+2047:000000EE111122CC8888880000880000
+2048:000000720A0A12624242420000420000
+2049:0000005C424244585050500000500000
+204A:0000000000000000007C040810200000
+204B:00000000FC5E5E5E5C50505050505000
+204C:000000001E3A3A3A1E00000000000000
+204D:00000000785C5C5C7800000000000000
+204E:0000000000000008492A1C2A49080000
+204F:00000000000018180000001810100800
+2050:0000003C424200000042423C00000000
+2051:0008492A1C2A49080008492A1C2A4908
+2052:00000000626204080810102046460000
+2053:000000000000000000718E0000000000
+2054:00000000000000000000000000003C42
+2055:00000000925438FE3854920000000000
+2056:00000000000400002000000400000000
+2057:0000000000000000333366664444888800000000000000000000000000000000
+2058:00000000001000440010000000000000
+2059:00000000000044001000440000000000
+205A:00000000001000000000000000100000
+205B:00000000100000820000100000000000
+205C:00000000000054107C10540000000000
+205D:00000000001000000010000000100000
+205E:00000000100000100000100000100000
+205F:00000000000000000000000000000000
+2060:AAAA00018000000180000001A2082209AA083689A27000018000000180005555
+2061:AAAA00018C001001908810899104110591047D05910411059088608980005555
+2062:AAAA4005A008101188200441828001018280044188201011A008400580005555
+2063:AAAA000180000001800000018000000180000001800018018800080190005555
+2064:AAAA00018000000180000101810001018FE00101810001018100000180005555
+2065:00007FFE61CE7DB661B66FB661CE7FFE7FFE73866FBE63866DF673867FFE0000
+2066:AAAA000180000001A39C2249A3882289BA5C0001800000018000000180005555
+2067:AAAA000180000001B91C2509B9082909A5DC0001800000018000000180005555
+2068:AAAA000180000001B9DC2209B9882049A39C0001800000018000000180005555
+2069:AAAA000180000001F39C4A49F2484249C39C0001800000018000000180005555
+206A:AAAA0001800007C181000101810007C180001E79A0801C7182083CF180005555
+206B:AAAA000180000381844007C18440044180001E79A0801C7182083CF180005555
+206C:AAAA0001800003E180800081808003E1800039F6C5087DE7C501450F80005555
+206D:AAAA0001800001C1822003E182200221800039F6C5087DE7C501450F80005555
+206E:AAAA000180002271B2882AF9A688228980003C79A2802271A2083CF180005555
+206F:AAAA000180002271B2882A89A688227180003C79A2802271A2083CF180005555
+2070:00000814222222140800000000000000
+2071:00000800080808080800000000000000
+2072:00007FFE61CE7DB661B66FB661CE7FFE7FFE61867DF67B8677BE77867FFE0000
+2073:00007FFE61CE7DB661B66FB661CE7FFE7FFE618E7DF67BC677F6778E7FFE0000
+2074:0000040C14243E040400000000000000
+2075:00003E20203C02023C00000000000000
+2076:00001C22203C22221C00000000000000
+2077:00003E02020408080800000000000000
+2078:00001C22221C22221C00000000000000
+2079:00001C22221E02221C00000000000000
+207A:00000008083E08080000000000000000
+207B:00000000003E00000000000000000000
+207C:000000003E003E000000000000000000
+207D:00000408080808080400000000000000
+207E:00001008080808081000000000000000
+207F:000000002C3222222200000000000000
+2080:00000000000000000008142222221408
+2081:00000000000000000008182808080808
+2082:0000000000000000001C22021C20203E
+2083:0000000000000000001C22021C02221C
+2084:000000000000000000040C14243E0404
+2085:0000000000000000003E20203C02023C
+2086:0000000000000000001C22203C22221C
+2087:0000000000000000003E020204080808
+2088:0000000000000000001C22221C22221C
+2089:0000000000000000001C22221E02221C
+208A:0000000000000000000008083E080800
+208B:0000000000000000000000003E000000
+208C:00000000000000000000003E003E0000
+208D:00000000000000000004080808080804
+208E:00000000000000000010080808080810
+208F:00007FFE61CE7DB661B66FB661CE7FFE7FFE73866DBE738E6DBE73BE7FFE0000
+2090:0000000000000000003844043C444C34
+2091:0000000000000000003844447C404438
+2092:00000000000000000038444444444438
+2093:00000000000000000000422418182442
+2094:0000000000000000003844047C444438
+2095:00000000000000000040404070484848
+2096:00000000000000000040404850605048
+2097:00000000000000000030101010101038
+2098:00000000000000000000007649494949
+2099:00000000000000000000005864444444
+209A:00000000000000000058644464584040
+209B:00000000000000000000304820104830
+209C:00000000000000000020207820202018
+209D:00007FFE61CE7DB661B66FB661CE7FFE7FFE738E6DB671B67DB6738E7FFE0000
+209E:00007FFE61CE7DB661B66FB661CE7FFE7FFE73866DBE718E7DBE73867FFE0000
+209F:00007FFE61CE7DB661B66FB661CE7FFE7FFE73866DBE718E7DBE73BE7FFE0000
+20A0:000000003C40405E50503C10101E0000
+20A1:000000000A3E4A54546868725C100000
+20A2:000000001C22424056585050321C0000
+20A3:000000003F2020203E2020FC20200000
+20A4:000000000E10107E107E10103E610000
+20A5:000000000101764D4D49495969690000
+20A6:000000002222327F2A7F262622220000
+20A7:0000000068585F5C6C4A4949494E0000
+20A8:0000000070484B4C74545249494E0000
+20A9:000000002222227F2A7F363622220000
+20AA:0000000000007A4A5A5A5A5A525E0000
+20AB:00000002023E023A46424242463A003C
+20AC:000000000C12207C207C2020120C0000
+20AD:000000004244485060FE504844420000
+20AE:000000007F08080E380E380808080000
+20AF:0000000070484848484E4D4D4E740404
+20B0:000000001C222222140C2A3231210204
+20B1:00007C42FF42FF427C40404040400000
+20B2:000010103C52525050565252563A1010
+20B3:00000000182424FF42FF424242420000
+20B4:000000003C420202FF30FF40423C0000
+20B5:000010103C52525050505052523C1010
+20B6:000000002828287E2828282829260000
+20B7:000000003C424220180452AAAAFCA8A8
+20B8:000000000000FE00FE10101010100000
+20B9:0000000000001FF801801FF800C000C003C00380038001000080004000200010
+20BA:002020283060A83062A2243800000000
+20BB:00007FFE61CE7DB661B66FB661CE7FFE7FFE638E6DB6638E6DB6638E7FFE0000
+20BC:00007FFE61CE7DB661B66FB661CE7FFE7FFE63C66DBE63BE6DBE63C67FFE0000
+20BD:00007FFE61CE7DB661B66FB661CE7FFE7FFE638E6DB663B66DB6638E7FFE0000
+20BE:00007FFE61CE7DB661B66FB661CE7FFE7FFE63866DBE638E6DBE63867FFE0000
+20BF:00007FFE61CE7DB661B66FB661CE7FFE7FFE63866DBE638E6DBE63BE7FFE0000
+20C0:00007FFE61CE7DB661B66FB661CE7FFE7FFE71CE6FB66FB66FB671CE7FFE0000
+20C1:00007FFE61CE7DB661B66FB661CE7FFE7FFE71EE6FCE6FEE6FEE71C67FFE0000
+20C2:00007FFE61CE7DB661B66FB661CE7FFE7FFE71866FF66F866FBE71867FFE0000
+20C3:00007FFE61CE7DB661B66FB661CE7FFE7FFE718E6FF66FC66FF6718E7FFE0000
+20C4:00007FFE61CE7DB661B66FB661CE7FFE7FFE71B66FB66F866FF671F67FFE0000
+20C5:00007FFE61CE7DB661B66FB661CE7FFE7FFE71866FBE6F866FF671867FFE0000
+20C6:00007FFE61CE7DB661B66FB661CE7FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000
+20C7:00007FFE61CE7DB661B66FB661CE7FFE7FFE71866FF66FEE6FDE71DE7FFE0000
+20C8:00007FFE61CE7DB661B66FB661CE7FFE7FFE71CE6FB66FCE6FB671CE7FFE0000
+20C9:00007FFE61CE7DB661B66FB661CE7FFE7FFE71CE6FB66FC66FF671CE7FFE0000
+20CA:00007FFE61CE7DB661B66FB661CE7FFE7FFE71866FB66F866FB671B67FFE0000
+20CB:00007FFE61CE7DB661B66FB661CE7FFE7FFE718E6FB66F8E6FB6718E7FFE0000
+20CC:00007FFE61CE7DB661B66FB661CE7FFE7FFE71C66FBE6FBE6FBE71C67FFE0000
+20CD:00007FFE61CE7DB661B66FB661CE7FFE7FFE718E6FB66FB66FB6718E7FFE0000
+20CE:00007FFE61CE7DB661B66FB661CE7FFE7FFE71866FBE6F8E6FBE71867FFE0000
+20CF:00007FFE61CE7DB661B66FB661CE7FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+20D0:0010207E000000000000000000000000
+20D1:0008047E000000000000000000000000
+20D2:00000000101010101010101010100000
+20D3:00000000001010101010101000000000
+20D4:004C5260780000000000000000000000
+20D5:00324A061E0000000000000000000000
+20D6:10207E20100000000000000000000000
+20D7:08047E04080000000000000000000000
+20D8:00000000000000182424180000000000
+20D9:00000000000000383424180000000000
+20DA:000000000000001C2C24180000000000
+20DB:00002A2A000000000000000000000000
+20DC:00005555000000000000000000000000
+20DD:000003800C60301820084004400480028002800240044004200830180C600380
+20DE:00007FFE4002400240024002400240024002400240024002400240027FFE0000
+20DF:0000010002800440082010102008400480024004200810100820044002800100
+20E0:000003800C603018300858044C0486028302818240C44064203830180C600380
+20E1:2442FF42240000000000000000000000
+20E2:0000000000003FFC4002400240024002400240024002400240023FFC7FFE0000
+20E3:00003FFC60065FFA500A500A500A500A500A500A500A500A5FFA60063FFC0000
+20E4:008001C00140036002200410041008080808180C10041004200220023FFE0000
+20E5:00002020201010101010080808080000
+20E6:00002828282828282828282828280000
+20E7:00003FFE00020002000200020002000200020002000200020002000200020000
+20E8:00000000000000000000000000000054
+20E9:00FF8100000000000000000000000000
+20EA:000000000000000000000000040008001FFC0800040000000000000000000000
+20EB:00000A0A0A1414141414282828280000
+20EC:000000000000000000000000007E0408
+20ED:000000000000000000000000007E2010
+20EE:000000000000000000000010207E2010
+20EF:000000000000000000000008047E0408
+20F0:24187E18240000000000000000000000
+20F1:00007FFE61CE7DB661B66FB661CE7FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000
+20F2:00007FFE61CE7DB661B66FB661CE7FFE7FFE61866FF663866FBE6F867FFE0000
+20F3:00007FFE61CE7DB661B66FB661CE7FFE7FFE618E6FF663C66FF66F8E7FFE0000
+20F4:00007FFE61CE7DB661B66FB661CE7FFE7FFE61B66FB663866FF66FF67FFE0000
+20F5:00007FFE61CE7DB661B66FB661CE7FFE7FFE61866FBE63866FF66F867FFE0000
+20F6:00007FFE61CE7DB661B66FB661CE7FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+20F7:00007FFE61CE7DB661B66FB661CE7FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+20F8:00007FFE61CE7DB661B66FB661CE7FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+20F9:00007FFE61CE7DB661B66FB661CE7FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+20FA:00007FFE61CE7DB661B66FB661CE7FFE7FFE61866FB663866FB66FB67FFE0000
+20FB:00007FFE61CE7DB661B66FB661CE7FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+20FC:00007FFE61CE7DB661B66FB661CE7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+20FD:00007FFE61CE7DB661B66FB661CE7FFE7FFE618E6FB663B66FB66F8E7FFE0000
+20FE:00007FFE61CE7DB661B66FB661CE7FFE7FFE61866FBE638E6FBE6F867FFE0000
+20FF:00007FFE61CE7DB661B66FB661CE7FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+2100:00000000003051523408132444030000
+2101:0000000000305152340B142241060000
+2102:000000001E31505050505050311E0000
+2103:000000609090600C12101010120C0000
+2104:0000000010103C505050503C101E0000
+2105:00000000003041423408162949060000
+2106:00000000003041423408102949060000
+2107:000000003E42404038404042423C0000
+2108:000000007C4202121E120202423C0000
+2109:00000060909060001E10101C10100000
+210A:0000000000003A4642423E023F423C00
+210B:00000000127596141C34549494630000
+210C:0000000077B7B6B6363E363676670000
+210D:00000000715151515F51515151710000
+210E:00000000404040586444444444460000
+210F:00000008506040D86444444444460000
+2110:000000000C14240404060C1424283000
+2111:000000003F7E442406060606765C0000
+2112:0000000C12123C101010107099660000
+2113:000000182424242830602020221C0000
+2114:000000004848FE484A4D494949360000
+2115:00000000715159595555535351710000
+2116:00000000929595D2D0B7B09090900000
+2117:000000003C42B9A5A5B9A1A1423C0000
+2118:000000004E5151212E50505050600000
+2119:000000007C525252525C505050700000
+211A:000000001C32515151515151361E0100
+211B:000000402E113151515E545252210000
+211C:00000000EEB333333E3C363676E30000
+211D:000000007E515151515E585452710000
+211E:000000007C4242427C504A444A500000
+211F:000038087C4A4A4A7C6858484C4A0800
+2120:00000000719B5531D100000000000000
+2121:00000000FE525A525F00000000000000
+2122:00000000F15B55515100000000000000
+2123:0000300C85894A525424287850800000
+2124:000000007E0A0A1214242848507E0000
+2125:000000003C08103E0408180402423C00
+2126:000000003E4141414141221455770000
+2127:000000007755142241414141413E0000
+2128:000000003C7E063C260606663C000000
+2129:0000000000000070080808080E080000
+212A:00000000000044485060605048440000
+212B:1824180018242442427E424242420000
+212C:000000002E5151515E515151512E0000
+212D:000000061E3C6C66666C6060663C1800
+212E:0000000000003C66667E6060663C0000
+212F:00000000000000182448704044380000
+2130:000000000E1220201C204044423C0000
+2131:000000003C42020404083E1020200000
+2132:0000000002020202023E0202027E0000
+2133:0000000063362A2A2A2A2A6AAA490000
+2134:0000000000001824534E424224180000
+2135:00000000000044462214286472620000
+2136:0000000000103E02020202023F7E0000
+2137:00000000403C1E0202020E3232320000
+2138:0000000000403E1F0202020203020000
+2139:000000000018180038181818187E0000
+213A:000000000000000000000000000000081FE820302050205020301FE000000000
+213B:00000000000000007C004000400040007222451448884F88489448A200000000
+213C:0000000000000000000000001FF80A500A500A500A500A480A240E1C00000000
+213D:0000000000000000000000000C040A08091004A0024002400480090012001C00
+213E:000000007F5553515050505050700000
+213F:00000000000000003FF8145014501450145014501450145014501C7000000000
+2140:00000000000000001FF8122809180488024004800908121814281FF800000000
+2141:000000007C42424272020202423C0000
+2142:000000007E0202020202020202020000
+2143:000000000202020202020202027E0000
+2144:00000000101010102844828282820000
+2145:000000000000000007E00530052809280A280A481250145014601FC000000000
+2146:0000000000000000003800280028004807D00A50129014A014A00FE000000000
+2147:00000000000000003C529EA0A27C0000
+2148:00000000000404003E121424287C0000
+2149:00000000000404003E121414242828F0
+214A:000010107C525252525C1010101E0000
+214B:000000004E3121514E1C2222221C0000
+214C:000000000000000034C04D20252005201FF825241FC405080500020000000000
+214D:0000000042A2E4A80813142241460000
+214E:000000000000000404043C04047C0000
+214F:0000000000000000000000000000000011102AA82AA82AA811106EEC00000000
+2150:0000000022622428281E122244440400
+2151:0000000022622428281E1A2E424C0000
+2152:0000000042C24448502255B595120000
+2153:0000000022622428281C1224424C0000
+2154:0000000062122448781C1224424C0000
+2155:0000000022622428281E182C424C0000
+2156:0000000062122448781E182C424C0000
+2157:0000000062122418681E182C424C0000
+2158:000000002262F428281E182C424C0000
+2159:00000000226224282816182E4A4E0000
+215A:00000000724264186816182E4A4E0000
+215B:000000002262242828141A244A4E0000
+215C:000000006212241868141A244A4E0000
+215D:000000007242641868141A244A4E0000
+215E:000000007212244848141A244A4E0000
+215F:00000000226224282810102040400000
+2160:000000001C08080808080808081C0000
+2161:000000007E24242424242424247E0000
+2162:000000007F2A2A2A2A2A2A2A2A7F0000
+2163:000000007F29292929292626267F0000
+2164:000000007F22222214141408083E0000
+2165:00000000FF4A4A4A4A4A3232327F0000
+2166:00000000FF55555555252525257F0000
+2167:00000000FFB5B5B5B555555555FF0000
+2168:000000007F2A2A2A24242A2A2A7F0000
+2169:000000007F2222221C1C2222227F0000
+216A:000000007F2A2A2A12122A2A2A7F0000
+216B:000000007F55555525255555557F0000
+216C:000000007020202020202020227E0000
+216D:000000001A26404040404040221C0000
+216E:00000000782422222222222224780000
+216F:0000000063223636362A2A2A2A7F0000
+2170:000000000808000818080808081C0000
+2171:00000000242400246C242424247E0000
+2172:000000002A2A002A7E2A2A2A2A7F0000
+2173:000000002020003B69292926267F0000
+2174:000000000000007722222214083E0000
+2175:000000000202005A4E4A4A32327F0000
+2176:00000000050500555F555525257F0000
+2177:00000000151500B5BFB5555555FF0000
+2178:000000002020002A6A24242A2A7F0000
+2179:00000000000000772214081422770000
+217A:000000000202002A2E12122A2A7F0000
+217B:00000000050500555F252555557F0000
+217C:000000000818080808080808081C0000
+217D:000000000000001A26404040221C0000
+217E:000000000206021A26424242261B0000
+217F:000000000000742A2A2A2A2A2A7F0000
+2180:000000002C5A4A4A4A4A4A4A5A2C0000
+2181:000000007824322A2A2A2A3224780000
+2182:000000000000000007C00920139015501550155015501390092007C000000000
+2183:00000000586402020202020244380000
+2184:00000000000000384402020264580000
+2185:000000003A46808080808080463A0202
+2186:00000000101010101010925438100000
+2187:000000F8467149655565497146F80000
+2188:0000000000000FE0311847C44924539455545394492447C431180FE000000000
+2189:0000000022525458281C1224424C0000
+218A:00007FFE61EE7DCE61EE6FEE61C67FFE7FFE73866DB673866DB673B67FFE0000
+218B:00007FFE61EE7DCE61EE6FEE61C67FFE7FFE738E6DB6738E6DB6738E7FFE0000
+218C:00007FFE61EE7DCE61EE6FEE61C67FFE7FFE73C66DBE73BE6DBE73C67FFE0000
+218D:00007FFE61EE7DCE61EE6FEE61C67FFE7FFE738E6DB673B66DB6738E7FFE0000
+218E:00007FFE61EE7DCE61EE6FEE61C67FFE7FFE73866DBE738E6DBE73867FFE0000
+218F:00007FFE61EE7DCE61EE6FEE61C67FFE7FFE73866DBE738E6DBE73BE7FFE0000
+2190:0000000000000010207F201000000000
+2191:0000081C2A0808080808080808080808
+2192:000000000000000804FE040800000000
+2193:08080808080808080808082A1C080000
+2194:000000000000002442FF422400000000
+2195:0000081C2A0808080808082A1C080000
+2196:00000000007860504804020000000000
+2197:00000000001E060A1220400000000000
+2198:00000000004020120A061E0000000000
+2199:00000000000002044850607800000000
+219A:0000000000040414247F241404040000
+219B:000000000020202824FE242820200000
+219C:00000000000000102679201000000000
+219D:0000000000000008649E040800000000
+219E:0000000000002448FF48240000000000
+219F:0000081C2A081C2A0808080808080808
+21A0:000000000000002412FF122400000000
+21A1:0808080808080808082A1C082A1C0800
+21A2:0000000000000011227C221100000000
+21A3:0000000000000088443E448800000000
+21A4:0000000000000012227E221200000000
+21A5:0000081C2A08080808080808083E0000
+21A6:0000000000000048447E444800000000
+21A7:00003E08080808080808082A1C080000
+21A8:0000081C2A08080808082A1C083E0000
+21A9:0000000000000211217E201000000000
+21AA:0000000000002044423F020400000000
+21AB:0000000000000215257E241400000000
+21AC:0000000000002054523F121400000000
+21AD:00000000000000245AE7422400000000
+21AE:000000000008082C4AFF4A2C08080000
+21AF:00004040404858684808082A1C080000
+21B0:00000000000000102078241404040404
+21B1:0000000000000008041E242820202020
+21B2:04040404040404142478201000000000
+21B3:2020202020202028241E040800000000
+21B4:000000000000000000FC04150E040000
+21B5:0404040404040414247C201000000000
+21B6:00000000000000001E21A97120000000
+21B7:00000000000000007884958E04000000
+21B8:0000007E007860504804020000000000
+21B9:00000050607E6050000A067E060A0000
+21BA:000000000000002E4C4A42423C000000
+21BB:0000000000000074325242423C000000
+21BC:0000000000000010207F000000000000
+21BD:0000000000000000007F201000000000
+21BE:0000080C0A0808080808080808080808
+21BF:00000818280808080808080808080808
+21C0:000000000000000804FE000000000000
+21C1:000000000000000000FE040800000000
+21C2:08080808080808080808080A0C080000
+21C3:08080808080808080808082818080000
+21C4:00000008047E04080010207E20100000
+21C5:00002474AC242424242424352E240000
+21C6:00000010207E20100008047E04080000
+21C7:00000010207E20100010207E20100000
+21C8:0000247EA52424242424242424240000
+21C9:00000008047E04080008047E04080000
+21CA:0000242424242424242424A57E240000
+21CB:00000000000010207E007E0408000000
+21CC:00000000000008047E007E2010000000
+21CD:00000000000808287E887E2808080000
+21CE:000000000008082C7E897E2C08080000
+21CF:00000000001010147E117E1410100000
+21D0:00000000000000103E403E1000000000
+21D1:00000814361414141414141414140000
+21D2:00000000000000087C027C0800000000
+21D3:00001414141414141414143614080000
+21D4:00000000000000247E817E2400000000
+21D5:00000814361414141414143614080000
+21D6:0000000000785068540A040000000000
+21D7:00000000001E0A162A50200000000000
+21D8:0000000000040A546850780000000000
+21D9:000000000020502A160A1E0000000000
+21DA:000000000000103E40FE403E10000000
+21DB:000000000000087C027F027C08000000
+21DC:000000000000002042F5482000000000
+21DD:000000000000000442AF120400000000
+21DE:0000081C2A0808083E083E0808080808
+21DF:08080808083E083E0808082A1C080000
+21E0:00000000000000102077201000000000
+21E1:0000081C2A0808000808080800080808
+21E2:000000000000000402EF020400000000
+21E3:08080800080808080008082A1C080000
+21E4:0000000000000050607F605000000000
+21E5:000000000000000A06FE060A00000000
+21E6:00000000000010305F815F3010000000
+21E7:000008142277141414141414141C0000
+21E8:0000000000080CFA81FA0C0800000000
+21E9:00001C14141414141414772214080000
+21EA:0000081422771414141C001C141C0000
+21EB:000008142263222222222263417F0000
+21EC:000008143E63222222222263417F0000
+21ED:0000081C2A6B2A2A2A2A2A6B497F0000
+21EE:0008142A7722632222222222223E0000
+21EF:0008142A7722632222222263417F0000
+21F0:000000000000086C7A417A6C08000000
+21F1:00000000007F405C5854424140400000
+21F2:000000000001014121150D1D017F0000
+21F3:00000814361414141414143614080000
+21F4:0000000000000000000000000000071008887FFC088807100000000000000000
+21F5:0000242E35242424242424AC74240000
+21F6:000402FF02040402FF02040402FF0204
+21F7:000000000000002444FF442400000000
+21F8:000000000000002422FF222400000000
+21F9:0000000000000000000000000000092011103FF8111009200000000000000000
+21FA:0000000000000000000000000000114021407FFF214011400000000000000000
+21FB:000000000000000000000000000002880284FFFE028402880000000000000000
+21FC:0000000000000000000000000000129022887FFC228812900000000000000000
+21FD:000000000000002060BF602000000000
+21FE:000000000000000406FD060400000000
+21FF:0000000000000000000000000000081018182FF4181808100000000000000000
+2200:0000000041413E222214141408080000
+2201:00000000182424202020202424180000
+2202:000000001C2202021E22424444380000
+2203:000000007E0202027E020202027E0000
+2204:000010107E1212127E121212127E1000
+2205:000000000000001D22454951225C0000
+2206:000000000808141414222222417F0000
+2207:000000007F4122222214141408080000
+2208:000000000000003E40407E40403E0000
+2209:000000000008083E48487E48483E0800
+220A:0000000000000000003E407E403E0000
+220B:000000000000007C02027E02027C0000
+220C:000000000010107C12127E12127C1000
+220D:0000000000000000007C027E027C0000
+220E:000000007E7E7E7E7E7E7E7E7E7E0000
+220F:000000007F2222222222222222220000
+2210:000000002222222222222222227F0000
+2211:000000007E42201008081020427E0000
+2212:0000000000000000007E000000000000
+2213:000000007F000808087F080808000000
+2214:0000081C08000808087F080808000000
+2215:00000000020404080810102020400000
+2216:00000000402020101008080404020000
+2217:000000000000082A1C081C2A08000000
+2218:00000000000000001824241800000000
+2219:0000000000000000183C3C1800000000
+221A:00000704040404047414140C0C040400
+221B:00006714641464047414140C0C040400
+221C:00005754741414047414140C0C040400
+221D:00000000000000364848360000000000
+221E:00000000000000364949360000000000
+221F:000000000000004040404040407E0000
+2220:000000000000000002040810207E0000
+2221:000000000000000002140814247E0000
+2222:000000000000000A0C1464140C0A0000
+2223:00000000181818181818181818180000
+2224:0000000018181A1C1818385818180000
+2225:00000000242424242424242424240000
+2226:00000000242426242C34246424240000
+2227:00000000000008081414222241410000
+2228:00000000000041412222141408080000
+2229:0000000000003C424242424242420000
+222A:000000000000424242424242423C0000
+222B:00060A08080808080808080808283000
+222C:000A1514141414141414141414546800
+222D:00152A2A2A2A2A2A2A2A2A2A2AAAD400
+222E:00060A0808081C2A2A1C080808283000
+222F:000A151414143E55553E141414546800
+2230:00152A2A2A7EABABAB7E2A2A2AAAD400
+2231:00060A0808081D2B2F08080808283000
+2232:00060A08081D2B2F2A1C080808283000
+2233:00060A0808085C6A7A2A1C0808283000
+2234:00000000000018180000006666000000
+2235:00000000000066660000001818000000
+2236:00000000000018180000001818000000
+2237:00000000000066660000006666000000
+2238:0000000000001818007E000000000000
+2239:00000000000006060078000606000000
+223A:0000000000006666007E006666000000
+223B:0000000000181800324C001818000000
+223C:0000000000000000324C000000000000
+223D:00000000000000004C32000000000000
+223E:00000000000000324926000000000000
+223F:00000000000030484909060000000000
+2240:00000000001008080810101008000000
+2241:000000000808083A4C08080800000000
+2242:00000000000000007E0000324C000000
+2243:00000000000000324C00007E00000000
+2244:000000000008083A4C08087E08080000
+2245:00000000324C00007E00007E00000000
+2246:0000000000324C087E08087E08080000
+2247:00000008083A4C087E08087E08080000
+2248:00000000000000324C00324C00000000
+2249:000000000008083A4C083A4C08080000
+224A:0000000000324C00324C007E00000000
+224B:0000000000324C00324C00324C000000
+224C:00000000304906007E00007E00000000
+224D:000000000000423C00003C4200000000
+224E:00000000000018660000661800000000
+224F:00000000000000186600007E00000000
+2250:00000000181800007E00007E00000000
+2251:0000001818007E00007E001818000000
+2252:0000006060007E00007E000606000000
+2253:0000000606007E00007E006060000000
+2254:000000000000005E00005E0000000000
+2255:000000000000007A00007A0000000000
+2256:000000000000007E24247E0000000000
+2257:00000018242418007E00007E00000000
+2258:000000003C4200007E00007E00000000
+2259:00000018244200007E00007E00000000
+225A:00000042241800007E00007E00000000
+225B:0000083E1C1400007E00007E00000000
+225C:00000814223E00007E00007E00000000
+225D:0000121476547400007E00007E000000
+225E:00000068545454007E00007E00000000
+225F:0030480810100010007E00007E000000
+2260:00000000000008087E08087E08080000
+2261:000000000000007E007E007E00000000
+2262:000000000008087E087E087E08080000
+2263:00000000007E007E007E007E00000000
+2264:0000000000000618601806007E000000
+2265:0000000000006018061860007E000000
+2266:0000000618601806007E00007E000000
+2267:0000006018061860007E00007E000000
+2268:0000000618601816107E10107E101000
+2269:0000006018061868087E08087E080800
+226A:00000000000912244890482412090000
+226B:00000000009048241209122448900000
+226C:00000000241818242424241818240000
+226D:0000000008084A3C08083C4A08080000
+226E:00000000080A0C08182818080C0A0800
+226F:00000000105030101814181030501000
+2270:0000000008080E1868180E087E080800
+2271:0000000010107018161870107E101000
+2272:000000000000061860180600324C0000
+2273:000000000000601806186000324C0000
+2274:0000000008080E1868180E083A4C0800
+2275:000000001010701816187010325C1000
+2276:00000000061860180660180618600000
+2277:00000000601806186006186018060000
+2278:000008080E1868180E68180E18680800
+2279:0000080868180E18680E1868180E0800
+227A:00000000020204186018040202000000
+227B:00000000404020180618204040000000
+227C:000000000202041860180402007E0000
+227D:000000004040201806182040007E0000
+227E:000000000202041860180402324C0000
+227F:000000004040201806182040324C0000
+2280:00000000021214187018141202000000
+2281:00000000404828180E18284840000000
+2282:0000000000003E404040403E00000000
+2283:0000000000007C020202027C00000000
+2284:0000000008083E484848483E08080000
+2285:0000000010107C121212127C10100000
+2286:0000000000003E404040403E007E0000
+2287:0000000000007C020202027C007E0000
+2288:0000000008083E484848483E087E0800
+2289:0000000010107C121212127C107E1000
+228A:0000000000003E404040403E087E0800
+228B:0000000000007C020202027C107E1000
+228C:000000004242424A527E524A423C0000
+228D:0000000042424242425A5A42423C0000
+228E:0000000042424252527A5252423C0000
+228F:0000000000007E404040407E00000000
+2290:0000000000007E020202027E00000000
+2291:0000000000007E404040407E007E0000
+2292:0000000000007E020202027E007E0000
+2293:0000000000007E424242424200000000
+2294:00000000000042424242427E00000000
+2295:0000000000001C2A497F492A1C000000
+2296:0000000000001C22417F41221C000000
+2297:0000000000001C22554955221C000000
+2298:0000000000001C22454951221C000000
+2299:0000000000001C22414941221C000000
+229A:0000000000001C22495549221C000000
+229B:0000000000001C22495D49221C000000
+229C:0000000000001C225D415D221C000000
+229D:0000000000001C22415D41221C000000
+229E:0000000000007F49497F49497F000000
+229F:0000000000007F41417F41417F000000
+22A0:0000000000007F63554955637F000000
+22A1:0000000000007F41414941417F000000
+22A2:0000000000004040407E404040000000
+22A3:0000000000000202027E020202000000
+22A4:0000000000007F080808080808000000
+22A5:0000000000000808080808087F000000
+22A6:00000020202020203C20202020200000
+22A7:000000202020203C203C202020200000
+22A8:000000404040407E407E404040400000
+22A9:00000050505050505E50505050500000
+22AA:00000054545454545754545454540000
+22AB:000000505050505E505E505050500000
+22AC:00000040404848487E48484840400000
+22AD:000000404848487E487E484848400000
+22AE:00000050505454545E54545450500000
+22AF:000000505454545E545E545454500000
+22B0:000000000C020418601804020C000000
+22B1:00000000304020180618204030000000
+22B2:00000000000000061A621A0600000000
+22B3:00000000000000605846586000000000
+22B4:00000000000000061A621A06007E0000
+22B5:000000000000006058465860007E0000
+22B6:0000000000000000225F220000000000
+22B7:0000000000000000227D220000000000
+22B8:0000000000000000027D020000000000
+22B9:00000000000808006300080800000000
+22BA:000000003E0808080808080808080000
+22BB:000000000000002222141408003E0000
+22BC:00000000003E00081414222200000000
+22BD:00000000003E00222214140800000000
+22BE:000000000000004040407848487E0000
+22BF:000000000000000002060A12227E0000
+22C0:00000000081414142222224141410000
+22C1:00000000414141222222141414080000
+22C2:000000003C4242424242424242420000
+22C3:000000004242424242424242423C0000
+22C4:00000000000000081422140800000000
+22C5:00000000000000001818000000000000
+22C6:00000000000000083E1C140000000000
+22C7:00000000000822143E14220800000000
+22C8:000000000000000022362A3622000000
+22C9:00000000000000002234283422000000
+22CA:000000000000000022160A1622000000
+22CB:00000000000000002010081422000000
+22CC:00000000000000000204081422000000
+22CD:000000000000004C3200007E00000000
+22CE:00000000000041222214141408000000
+22CF:00000000000008141414222241000000
+22D0:0000000000003E405E50505E403E0000
+22D1:0000000000007C027A0A0A7A027C0000
+22D2:000000000000003E415D555555000000
+22D3:000000000000005555555D413E000000
+22D4:000000000808081C2A2A2A2A2A2A0000
+22D5:00000000242424247E24247E24240000
+22D6:00000000000204081022100804020000
+22D7:00000000004020100844081020400000
+22D8:00000000000000152A542A1500000000
+22D9:00000000000000542A152A5400000000
+22DA:000618601806007E0060180618600000
+22DB:006018061860007E0006186018060000
+22DC:00000000007E00061860180600000000
+22DD:00000000007E00601806186000000000
+22DE:000000007E0202041860180402020000
+22DF:000000007E4040201806182040400000
+22E0:000000080A0A0C1868180C0A0A7E0800
+22E1:00000008484828180E182848487E0800
+22E2:0000000808087E484848487E087E0800
+22E3:0000000808087E0A0A0A0A7E087E0800
+22E4:0000000000007E404040407E087E0800
+22E5:0000000000007E020202027E087E0800
+22E6:00000000000618601806083A4C080800
+22E7:00000000006018061860083A4C080800
+22E8:000000020204186018040A3A4C080800
+22E9:00004040201806182040483A4C080800
+22EA:000000000008080E1A6A1A0E08080000
+22EB:0000000000080868584E586808080000
+22EC:000000000008080E1A6A1A0E087E0800
+22ED:0000000000080868584E5868087E0800
+22EE:00000000181800001818000018180000
+22EF:0000000000000000DBDB000000000000
+22F0:000000000303000018180000C0C00000
+22F1:00000000C0C000001818000003030000
+22F2:00000000000007F00800100010007FF010001000080007F00000000000000000
+22F3:00000000000007F00800100010101FF010101000080007F00000000000000000
+22F4:00000000003E40427E42403E00000000
+22F5:00000000000007F00800100010001FF010001000080007F00000000000000000
+22F6:00001FF0000007F00800100010001FF010001000080007F00000000000000000
+22F7:0000007E003E40407E40403E00000000
+22F8:0000000000001FC02000400040007FC04000400020001FC000007FC000000000
+22F9:0000000000001FC0200040007FC040007FC0400020001FC00000000000000000
+22FA:0000000000003F800040002000203FF80020002000403F800000000000000000
+22FB:0000000000003F800040002020203FE02020002000403F800000000000000000
+22FC:00000000007C02427E42027C00000000
+22FD:00003FE000003F800040002000203FE00020002000403F800000000000000000
+22FE:0000007E007C02027E02027C00000000
+22FF:0000000000000FF80800080008000FF80800080008000FF80000000000000000
+2300:0000000000001D22454951225C000000
+2301:00000000000000009058341200000000
+2302:000000000000182442424242427E0000
+2303:00000000081422000000000000000000
+2304:00000000000000000000002214080000
+2305:000000003E0008142200000000000000
+2306:000000003E003E000814220000000000
+2307:00000010080408100804081008040000
+2308:00001E10101010101010101010100000
+2309:00007808080808080808080808080000
+230A:000010101010101010101010101E0000
+230B:00000808080808080808080808780000
+230C:00000000000000000708080800000000
+230D:00000000000000007008080800000000
+230E:00000000000808080700000000000000
+230F:00000000000808087000000000000000
+2310:000000000000000000007E4040400000
+2311:000000000000413E2222223E41000000
+2312:00000000000000001C22414100000000
+2313:00000000000000001C22417F00000000
+2314:00000000000000001C22412214080000
+2315:000000000000001C22414151225C0000
+2316:0000000808081C2A7F2A1C0808080000
+2317:000000002424FF2424FF242400000000
+2318:000000000022553E143E552200000000
+2319:000000000000004040407E0000000000
+231A:00282828283854929B82443828282800
+231B:000000007E242424181824243C7E0000
+231C:00784040400000000000000000000000
+231D:001E0202020000000000000000000000
+231E:00000000000000000000004040407800
+231F:00000000000000000000000202021E00
+2320:00000000060A08080808080808080808
+2321:08080808080808080808283000000000
+2322:0000000000000000003C420000000000
+2323:0000000000000000423C000000000000
+2324:00000000770814220000000000000000
+2325:00000000000067100807000000000000
+2326:000000000000FCAA91AAFC0000000000
+2327:0000000000007F5549557F0000000000
+2328:00000000007E7E7E003C000000000000
+2329:00000808101020204020201010080800
+232A:00001010080804040204040808101000
+232B:0000000000003F5589553F0000000000
+232C:000000081C2663616163261C08000000
+232D:000000000000081825669C0800000000
+232E:000000000000000018242F3860600000
+232F:0000000000000018007E001800000000
+2330:00000000091B12122424244848780000
+2331:0000000000202070AABFAA7020200000
+2332:0000000000006058467F465860000000
+2333:0000000000000000006058467F000000
+2334:0000000000000000004242427E000000
+2335:00000000000000000000422418000000
+2336:000000007F08080808080808087F0000
+2337:000000003E22222222222222223E0000
+2338:0000007F4141417F41417F41417F0000
+2339:0000007F414949417F414949417F0000
+233A:0000007F4149556341635549417F0000
+233B:0000007F4141415D555D4141417F0000
+233C:0000007F41415D634141635D417F0000
+233D:00000008081C2A4949492A1C08080000
+233E:00000000001C225D555D221C00000000
+233F:000000000204040808FF102020400000
+2340:000000004020201010FF080404020000
+2341:0000007F4143454549515161417F0000
+2342:0000007F4161515149454543417F0000
+2343:0000007F4141475961594741417F0000
+2344:0000007F4141714D434D7141417F0000
+2345:00000008080808287F28080808080000
+2346:000000080808080A7F0A080808080000
+2347:0000007F414149517F514941417F0000
+2348:0000007F414149457F454941417F0000
+2349:000000000000005C22514945221D0000
+234A:00000000080808080808087F007F0000
+234B:000000000808081C1C2A2A3E08080000
+234C:00007F414141416363555549417F0000
+234D:00007F41414949555563637F417F0000
+234E:000000000808081C2A2A1C08087F0000
+234F:00000000081C2A087F08080808080000
+2350:00007F495D6B494949494949497F0000
+2351:000000003E003E080808080808080000
+2352:0000000008083E2A2A1C1C0808080000
+2353:00007F414955556363414141417F0000
+2354:00007F41417F636355554949417F0000
+2355:000000007F08081C2A2A1C0808080000
+2356:0000000808080808087F082A1C080000
+2357:00007F494949494949496B5D497F0000
+2358:000000000808080000000000003E0000
+2359:00000000000808141422223E003E0000
+235A:000000000008142241221408003E0000
+235B:000000000000001C2222221C003E0000
+235C:00000000001C22414141221C007F0000
+235D:000000001C2249554941414141410000
+235E:00007F414949494141414141417F0000
+235F:000000001C22497F5D55221C00000000
+2360:00007F414149494141494941417F0000
+2361:002424007F0808080808080808080000
+2362:00242400003E22221414080800000000
+2363:0024240000083E1C1400000000000000
+2364:002424000000001C2222221C00000000
+2365:002424000000001C22414141221C0000
+2366:00000000494949494949492A1C080000
+2367:00000008081F28484848281F08080000
+2368:00242400000000324C00000000000000
+2369:00242400402010080402040810204000
+236A:000000003C0000180808100000000000
+236B:00000000003E22221414394E00000000
+236C:000000001C222222336E2222221C0000
+236D:0000000008080808083A4C0808080000
+236E:000000001818000018080810003E0000
+236F:00007F4149497F49497F4949417F0000
+2370:00007F414955554549494149417F0000
+2371:00000000324C00222214140800000000
+2372:0000000000324C000814142222000000
+2373:00000000000000180808080808060000
+2374:0000000000003C4242424242625C4040
+2375:00000000000014224949494949360000
+2376:0000000000324A4444444A32007E0000
+2377:00000000003C42407840423C007E0000
+2378:000000000018080808080806001E0000
+2379:000000001422414949494936007F0000
+237A:000000000000324A444444444A320000
+237B:000000000000000200040008001001FC00400080410022001400080000000000
+237C:000000000A000C00080018002800180008000C000A000C004FFE500060007800
+237D:0000000000000000000000000000000000000000783C082008200FE000000000
+237E:000000000000000003C004200810100810081FF80420042004201C3800000000
+237F:000008080808081C3E1C080808080000
+2380:00000038043C44443A00824428100000
+2381:000000000000000000000000380004003C00440044003A5400007FFC00000000
+2382:000000000000000000000000387004083C78448844883A7400007EFC00000000
+2383:0000000000000000400420081390004073DC0440145023A84004000000000000
+2384:0000000000000000000000003FF02108220422042204220421083FF000000000
+2385:0000000000000000010001001D701110111011101110111011101D7001000100
+2386:00000100028004400820121003087E8440427E84030812100820044002800100
+2387:00000000000000000000000000000020003000E801300220040078FE00000000
+2388:00000100010023881D701930155023882388155019301D702388010001000000
+2389:000000000F8030604010401080088008F078888888884510451032600F800000
+238A:000000000F80306040107FF0A02890489048888888884510451032600F800000
+238B:0000000001807C6048105010680844080208810880884050401030600F800000
+238C:000000000000000007E0081010087C0828081008381C44224422381C00000000
+238D:000000000000000007E0042004200420042004200420042004203C3C00000000
+238E:000000000000000001FC021004200420042004200420042008403F8000000000
+238F:000000000000000000001FF00280044008201010082004400280010000000000
+2390:00000000000000000000010002800440082010100820044002801FF000000000
+2391:000000000000000000001FF00280044008201FF0082004400280010000000000
+2392:0000000000000000000001000280044008201FF00820044002801FF000000000
+2393:0000000000000000000000007FFC0000739C0000000000000000000000000000
+2394:0000000000000000000007E0081010082004400220041008081007E000000000
+2395:00007F414141414141414141417F0000
+2396:00000000000000007C78707060604000
+2397:00006DB040104FFC48044A044E044BE450244BE44E047A0408040FFC00000000
+2398:00007FF040104EDC4804490449845F4050245F444980790408040CDC00000000
+2399:000001E0032005200F20082038384824882288228FE2800240043FF800000000
+239A:000000000000000000001FF020284244449449245244448428081FF000000000
+239B:000E1830303030303030303030303030
+239C:30303030303030303030303030303030
+239D:3030303030303030303030303030180E
+239E:0070180C0C0C0C0C0C0C0C0C0C0C0C0C
+239F:0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C
+23A0:0C0C0C0C0C0C0C0C0C0C0C0C0C0C1870
+23A1:003E3030303030303030303030303030
+23A2:30303030303030303030303030303030
+23A3:3030303030303030303030303030303E
+23A4:007C0C0C0C0C0C0C0C0C0C0C0C0C0C0C
+23A5:0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C
+23A6:0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C7C
+23A7:00060C18181818181818181818181818
+23A8:18181818181810204020101818181818
+23A9:18181818181818181818181818180C06
+23AA:18181818181818181818181818181818
+23AB:00603018181818181818181818181818
+23AC:18181818181808040204081818181818
+23AD:18181818181818181818181818183060
+23AE:08080808080808080808080808080808
+23AF:000000000000000000FF000000000000
+23B0:00060C18181818181818181818183060
+23B1:00603018181818181818181818180C06
+23B2:00000000000000007FFE300E3006180218000C000C0006000600030003000180
+23B3:018003000300060006000C000C00180018023006300E7FFE0000000000000000
+23B4:00000000000000007FFE40024002000000000000000000000000000000000000
+23B5:0000000000000000000000000000000000000000000000000000400240027FFE
+23B6:00000000000000000000400240027FFE00007FFE400240020000000000000000
+23B7:00000000010101020262241414080000
+23B8:80808080808080808080808080808080
+23B9:01010101010101010101010101010101
+23BA:FF000000000000000000000000000000
+23BB:00000000FF0000000000000000000000
+23BC:0000000000000000000000FF00000000
+23BD:000000000000000000000000000000FF
+23BE:000000003E2020202020202020200000
+23BF:000000002020202020202020203E0000
+23C0:00000100010003800D601110111021082108111011100D600380010001000000
+23C1:00003FF8010003800D601110111021082108111011100D600380010001000000
+23C2:00000100010003800D601110111021082108111011100D60038001003FF80000
+23C3:0000000001000100038005400540092009201110111021083FF8010001000000
+23C4:000000003FF80100038005400540092009201110111021083FF8010001000000
+23C5:0000000001000100038005400540092009201110111021083FF801003FF80000
+23C6:0000010001000100010001001D00230001880170010001000100010001000000
+23C7:00003FF801000100010001001D00230001880170010001000100010001000000
+23C8:0000010001000100010001001D0023000188017001000100010001003FF80000
+23C9:00003FF801000100010001000100010001000100010001000100010001000000
+23CA:000001000100010001000100010001000100010001000100010001003FF80000
+23CB:003F0101010101010101010101010100
+23CC:00010101010101010101010101013F00
+23CD:00000080793C42044404400440044004400440044004400440047FFC00000000
+23CE:00000000003E00220022002204220C42178220024004200817F00C0004000000
+23CF:00000000000010387CFE00FEFEFE0000
+23D0:08080808080808080808080808080808
+23D1:00000000000000008244380000000000
+23D2:000000000000FE008244380000000000
+23D3:000000000000000082443800FE000000
+23D4:000000000000000000000000FFFE000082824444383800000000000000000000
+23D5:000000000000000000000000000000008282444438380000FFFE000000000000
+23D6:0000000000000000000000000000000082824444383800000000000000000000
+23D7:000000000000000200020002000200027FFE0000000000000000000000000000
+23D8:000000000000400240024002400240027FFE0000000000000000000000000000
+23D9:000000000000410241024102410241027FFE0000000000000000000000000000
+23DA:08080808080808080808087F001C0008
+23DB:0000000000000000000000001FF810081008FFFF100810081FF8000000000000
+23DC:000000000000000000000000000007E0381C4002800100000000000000000000
+23DD:000000000000000080014002381C07E000000000000000000000000000000000
+23DE:000000000000000000000000010002803C784004800200000000000000000000
+23DF:0000000000000000800240043C78028001000000000000000000000000000000
+23E0:00000000000000000000000000000FF010082004400200000000000000000000
+23E1:00000000000000004002200410080FF000000000000000000000000000000000
+23E2:000000000000000000007FC040204020401040104008400840047FFC00000000
+23E3:000000000000008001400220041009C80A280A280A2809C80410022001400080
+23E4:0000000000000000000000000000000000007FFE000000000000000000000000
+23E5:000000000000000000000000000000000FFC10081008201020107FE000000000
+23E6:000000000000000000001800240042007FFC0084004800300000000000000000
+23E7:00002400240022002206A91871A021C003E001C002A004100808100400000000
+23E8:0000000000000000246A2A2A2A240000
+23E9:00000000000000000000208030C038E03CF03EF83CF038E030C0208000000000
+23EA:00000000000000000000020806180E381E783EF81E780E380618020800000000
+23EB:0000000000000100038007C00FE01FF000000100038007C00FE01FF000000000
+23EC:00000000000000001FF00FE007C00380010000001FF00FE007C0038001000000
+23ED:000000000000000000004104618471C479E47DF479E471C46184410400000000
+23EE:000000000000000000004104430C471C4F3C5F7C4F3C471C430C410400000000
+23EF:00000000000000000000104818481C481E481F481E481C481848104800000000
+23F0:00000100193037D82828111021082108210822082408101008200FE01C700000
+23F1:00000300030007D808381110210821082108200820081010082007C000000000
+23F2:00000000000007C008201010240822082108200820081010082007C000000000
+23F3:00007FFC1010101012900D6006C0028006C0082011101AB015507FFC00000000
+23F4:00007FFE618E7DF661C66FF6618E7FFE7FFE61B66FB663866FF66FF67FFE0000
+23F5:00007FFE618E7DF661C66FF6618E7FFE7FFE61866FBE63866FF66F867FFE0000
+23F6:00007FFE618E7DF661C66FF6618E7FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+23F7:00007FFE618E7DF661C66FF6618E7FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+23F8:00007FFE618E7DF661C66FF6618E7FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+23F9:00007FFE618E7DF661C66FF6618E7FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+23FA:00007FFE618E7DF661C66FF6618E7FFE7FFE61866FB663866FB66FB67FFE0000
+23FB:00007FFE618E7DF661C66FF6618E7FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+23FC:00007FFE618E7DF661C66FF6618E7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+23FD:00007FFE618E7DF661C66FF6618E7FFE7FFE618E6FB663B66FB66F8E7FFE0000
+23FE:00007FFE618E7DF661C66FF6618E7FFE7FFE61866FBE638E6FBE6F867FFE0000
+23FF:00007FFE618E7DF661C66FF6618E7FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+2400:000000000000000000004A506A505A50499E0000000000000000000000000000
+2401:0000000000000000000039924252325E0A527192000000000000000000000000
+2402:000000000000000000003BA44124311809247124000000000000000000000000
+2403:000000000000000000007BA44124791841247924000000000000000000000000
+2404:0000000000000000000079BE42487A4842487988000000000000000000000000
+2405:000000000000000000007A4C42527B5242D67A4E000000000000000000000000
+2406:0000000000000000000031A44A287A304A2849A4000000000000000000000000
+2407:0000000000000000000073D04A1073D04A1073DE000000000000000000000000
+2408:000000000000000000001E3811401E3011081E70000000000000000000000000
+2409:0000000000000000000022F822203E2022202220000000000000000000000000
+240A:0000000000000000000020F8208020F820803E80000000000000000000000000
+240B:0000000000000000000022F82220222014200820000000000000000000000000
+240C:000000000000000000003EF820803EF820802080000000000000000000000000
+240D:000000000000000000001EF0208820F020901E88000000000000000000000000
+240E:000000000000000000001E7020881C8802883C70000000000000000000000000
+240F:000000000000000000001EF820201C2002203CF8000000000000000000000000
+2410:00000000000000000000391C2510251C251039DC000000000000000000000000
+2411:0000000000000000000071884A184A084A08719C000000000000000000000000
+2412:0000000000000000000071984A044A084A10719C000000000000000000000000
+2413:0000000000000000000071984A044A184A047198000000000000000000000000
+2414:0000000000000000000071844A0C4A144A1C7184000000000000000000000000
+2415:0000000000000000000049926A546A585BD44A52000000000000000000000000
+2416:000000000000000000003452429A311609127112000000000000000000000000
+2417:000000000000000000007BB84124793841247938000000000000000000000000
+2418:00000000000000000000332444B447AC44A434A4000000000000000000000000
+2419:000000000000000000003E8820D83EA820883E88000000000000000000000000
+241A:000000000000000000003A5C4252325C0A52719C000000000000000000000000
+241B:0000000000000000000079CE4210799040507B8E000000000000000000000000
+241C:000000000000000000001E7010801E60101010E0000000000000000000000000
+241D:000000000000000000000E701080166012100EE0000000000000000000000000
+241E:000000000000000000001C7012801C60141012E0000000000000000000000000
+241F:0000000000000000000012701280126012100CE0000000000000000000000000
+2420:000000000000000000003B80424033800A007200000000000000000000000000
+2421:0000000000000000000073D04A104BD04A1073DE000000000000000000000000
+2422:00000000141810305C121212121C0000
+2423:000000000000000000000000427E0000
+2424:0000000048685848001010101E000000
+2425:0000000000010A152A54284000000000
+2426:0000003C424240201008080008080000
+2427:00007FFE61B67DB661866FF661F67FFE7FFE61867DF661EE6FDE61DE7FFE0000
+2428:00007FFE61B67DB661866FF661F67FFE7FFE61CE7DB661CE6FB661CE7FFE0000
+2429:00007FFE61B67DB661866FF661F67FFE7FFE61CE7DB661C66FF661CE7FFE0000
+242A:00007FFE61B67DB661866FF661F67FFE7FFE61867DB661866FB661B67FFE0000
+242B:00007FFE61B67DB661866FF661F67FFE7FFE618E7DB6618E6FB6618E7FFE0000
+242C:00007FFE61B67DB661866FF661F67FFE7FFE61C67DBE61BE6FBE61C67FFE0000
+242D:00007FFE61B67DB661866FF661F67FFE7FFE618E7DB661B66FB6618E7FFE0000
+242E:00007FFE61B67DB661866FF661F67FFE7FFE61867DBE618E6FBE61867FFE0000
+242F:00007FFE61B67DB661866FF661F67FFE7FFE61867DBE618E6FBE61BE7FFE0000
+2430:00007FFE61B67DB661866FF661F67FFE7FFE63CE7DB671B67DB663CE7FFE0000
+2431:00007FFE61B67DB661866FF661F67FFE7FFE63EE7DCE71EE7DEE63C67FFE0000
+2432:00007FFE61B67DB661866FF661F67FFE7FFE63867DF671867DBE63867FFE0000
+2433:00007FFE61B67DB661866FF661F67FFE7FFE638E7DF671C67DF6638E7FFE0000
+2434:00007FFE61B67DB661866FF661F67FFE7FFE63B67DB671867DF663F67FFE0000
+2435:00007FFE61B67DB661866FF661F67FFE7FFE63867DBE71867DF663867FFE0000
+2436:00007FFE61B67DB661866FF661F67FFE7FFE63CE7DBE718E7DB663CE7FFE0000
+2437:00007FFE61B67DB661866FF661F67FFE7FFE63867DF671EE7DDE63DE7FFE0000
+2438:00007FFE61B67DB661866FF661F67FFE7FFE63CE7DB671CE7DB663CE7FFE0000
+2439:00007FFE61B67DB661866FF661F67FFE7FFE63CE7DB671C67DF663CE7FFE0000
+243A:00007FFE61B67DB661866FF661F67FFE7FFE63867DB671867DB663B67FFE0000
+243B:00007FFE61B67DB661866FF661F67FFE7FFE638E7DB6718E7DB6638E7FFE0000
+243C:00007FFE61B67DB661866FF661F67FFE7FFE63C67DBE71BE7DBE63C67FFE0000
+243D:00007FFE61B67DB661866FF661F67FFE7FFE638E7DB671B67DB6638E7FFE0000
+243E:00007FFE61B67DB661866FF661F67FFE7FFE63867DBE718E7DBE63867FFE0000
+243F:00007FFE61B67DB661866FF661F67FFE7FFE63867DBE718E7DBE63BE7FFE0000
+2440:000000000E0A0A0A0808282828380000
+2441:0000000002020202023E222222220000
+2442:0000000022222222223E080808080000
+2443:0000000008080808083E222222220000
+2444:000000003E2A2A2A08082A2A2A3E0000
+2445:0000000022362A362200000000000000
+2446:00000000000E6E6E60606E6E0E000000
+2447:000000000303031B1818D8C0C0C00000
+2448:00000000075757505050505050500000
+2449:00000000006D6D6D6D6D6D6D6D6D0000
+244A:00000000A0A050282814140A05050000
+244B:00007FFE61B67DB661866FF661F67FFE7FFE6D8E6DB6618E7DB67D8E7FFE0000
+244C:00007FFE61B67DB661866FF661F67FFE7FFE6DC66DBE61BE7DBE7DC67FFE0000
+244D:00007FFE61B67DB661866FF661F67FFE7FFE6D8E6DB661B67DB67D8E7FFE0000
+244E:00007FFE61B67DB661866FF661F67FFE7FFE6D866DBE618E7DBE7D867FFE0000
+244F:00007FFE61B67DB661866FF661F67FFE7FFE6D866DBE618E7DBE7DBE7FFE0000
+2450:00007FFE61B67DB661866FF661F67FFE7FFE61CE6FB661B67DB661CE7FFE0000
+2451:00007FFE61B67DB661866FF661F67FFE7FFE61EE6FCE61EE7DEE61C67FFE0000
+2452:00007FFE61B67DB661866FF661F67FFE7FFE61866FF661867DBE61867FFE0000
+2453:00007FFE61B67DB661866FF661F67FFE7FFE618E6FF661C67DF6618E7FFE0000
+2454:00007FFE61B67DB661866FF661F67FFE7FFE61B66FB661867DF661F67FFE0000
+2455:00007FFE61B67DB661866FF661F67FFE7FFE61866FBE61867DF661867FFE0000
+2456:00007FFE61B67DB661866FF661F67FFE7FFE61CE6FBE618E7DB661CE7FFE0000
+2457:00007FFE61B67DB661866FF661F67FFE7FFE61866FF661EE7DDE61DE7FFE0000
+2458:00007FFE61B67DB661866FF661F67FFE7FFE61CE6FB661CE7DB661CE7FFE0000
+2459:00007FFE61B67DB661866FF661F67FFE7FFE61CE6FB661C67DF661CE7FFE0000
+245A:00007FFE61B67DB661866FF661F67FFE7FFE61866FB661867DB661B67FFE0000
+245B:00007FFE61B67DB661866FF661F67FFE7FFE618E6FB6618E7DB6618E7FFE0000
+245C:00007FFE61B67DB661866FF661F67FFE7FFE61C66FBE61BE7DBE61C67FFE0000
+245D:00007FFE61B67DB661866FF661F67FFE7FFE618E6FB661B67DB6618E7FFE0000
+245E:00007FFE61B67DB661866FF661F67FFE7FFE61866FBE618E7DBE61867FFE0000
+245F:00007FFE61B67DB661866FF661F67FFE7FFE61866FBE618E7DBE61BE7FFE0000
+2460:07C0183020084104430485028102810281028102410447C42008183007C00000
+2461:07C01830200847C448248022802280C28302840248244FE42008183007C00000
+2462:07C01830200847C448248022802280C280228022482447C42008183007C00000
+2463:07C018302008404440C481428242844288429FF2404441F42008183007C00000
+2464:07C0183020084FE4480488028FC2802280228022482447C42008183007C00000
+2465:07C01830200847C44824880288028FC288228822482447C42008183007C00000
+2466:07C0183020084FE4482480428042808281028102420442042008183007C00000
+2467:07C01830200847C448248822882287C288228822482447C42008183007C00000
+2468:07C01830200847C448248822882287E280228022482447C42008183007C00000
+2469:07C01830200848E459148912891289128912891249145CE42008183007C00000
+246A:00000FF0100824244C624422442244224422442244224E72200410080FF00000
+246B:00000FF0100824E44D1245924412446244824502450A4FF2200410080FF00000
+246C:00000FF0100824E44D124412441244624412451245124EE2200410080FF00000
+246D:00000FF0100824244C62446244A244A2452247FA44224E72200410080FF00000
+246E:00000FF0100825944D624502456245924412441245124EE2200410080FF00000
+246F:00000FF0100824644C924502456245924512451245124EE2200410080FF00000
+2470:00000FF0100825F44D124412442244424442444244424EE2200410080FF00000
+2471:00000FF0100824E44D124512451244E24512451245124EE2200410080FF00000
+2472:00000FF0100824E44D124512451244F24412441245124EE2200410080FF00000
+2473:00000FF010082C6452924292429244924892509252925E62200410080FF00000
+2474:0000400481028102810281028102810281028102810281028102810240040000
+2475:00004004878288428842804280428042808283028402884288428FC240040000
+2476:0000400487828842884280428082830280828042804288428842878240040000
+2477:0000418482828282828284828482888288828FE2808280828082808240040000
+2478:000040048FC28802880288028B828C4288428042804288428842878240040000
+2479:00004004878288428842880288028B828C428842884288428842878240040000
+247A:000040048FE28822882280428082808280828102810281028102810240040000
+247B:0000400487828842884288428842878288428842884288428842878240040000
+247C:000040048782884288428842884288C287428042804288428842878240040000
+247D:0000400488E2891289128912891289128912891289128912891288E240040000
+247E:0000400488228822882288228822882288228822882288228822882240040000
+247F:0000400491E29212921290129012902290C2910292029212921293F240040000
+2480:0000400491E2921292129012902290C29022901290129212921291E240040000
+2481:00004004906290A290A290A2912291229222922293FA90229022902240040000
+2482:0000400493F292029202920292E293129212901290129212921291E240040000
+2483:0000400491E2921292129202920292E29312921292129212921291E240040000
+2484:0000400493F29212921290229042904290429082908290829082908240040000
+2485:0000400491E2921292129212921291E29212921292129212921291E240040000
+2486:0000400491E29212921292129212923291D2901290129212921291E240040000
+2487:000040049C72A28AA28A828A828A848A888A908AA08AA28AA28ABE7240040000
+2488:0000020006000A00020002000200020002000200020002000200020002400000
+2489:00000F001080108000800080008001000600080010001000108010801F900000
+248A:00000F001080108000800080010006000100008000801080108010800F100000
+248B:00000300050005000500090009000900110011001FC001000100010001080100
+248C:00001F801000100010001000100017001880108000800080108010800F100000
+248D:00000F001080108010801000100017001880108010801080108010800F100000
+248E:00001FC010401040008001000100010002000200020002000200020002080000
+248F:00000F001080108010801080090006000900108010801080108010800F100000
+2490:00000F001080108010801080108011800E80008000801080108010800F100000
+2491:000023C06420A420242024202420242024202420242024202420242023C80000
+2492:000020806180A280208020802080208020802080208020802080208020900000
+2493:000023C06420A420202020202020204021802200240024002420242027E40000
+2494:000023C06420A420202020202040218020402020202024202420242023C40000
+2495:000020C06140A14021402240224022402440244027F020402040204020480000
+2496:000027E06400A40024002400240025C026202420202020202420242023C40000
+2497:000023C06420A42024202400240025C026202420242024202420242023C40000
+2498:000027F06410A410202020402040204020802080208020802080208020840000
+2499:000023C06420A420242024202240218022402420242024202420242023C40000
+249A:000023C06420A420242024202420246023A02020202024202420242023C40000
+249B:000038E04510451005100510051019102110411041104110451045107CE40000
+249C:0000181820044002400243C24422402243E24422442243DA4002200418180000
+249D:0000181824044C02440245C2462244124412441246224DC24002200418180000
+249E:0000181820044002400243C24422480248024812442243C24002200418180000
+249F:0000181820244062402243A24462482248224822446243B24002200418180000
+24A0:0000181820044002400247C2482248224FE24802482247C24002200418180000
+24A1:0000181820C44162410247C24102410241024102410243824002200418180000
+24A2:0000181820044002403243C2442244224FC2480247E24812481227E418180000
+24A3:0000181824044C02440244E2472244224422442244224E724002200418180000
+24A4:0000189820844002400240824182408240824082408241C24002200418180000
+24A5:0000189820844002400240824182408240824082408240824482230418180000
+24A6:0000181824044C02440244E244424482478244C244624E724002200418180000
+24A7:0000181821044302410241024102410241024102410243824002200418180000
+24A8:000018182004400240024B625DA249224922492249225DB24002200418180000
+24A9:0000181820044002400244E24F2244224422442244224E724002200418180000
+24AA:0000181820044002400247C24822482248224822482247C24002200418180000
+24AB:0000181820044002400245C24E22441244124412462245C244022E0418180000
+24AC:0000181820044002400243A24462482248224822446243A24022207418180000
+24AD:0000181820044002400244E24F3244024402440244024E024002200418180000
+24AE:0000181820044002400243E24412440243E24012441243E24002200418180000
+24AF:00001818200440024102410247C2410241024102412241C24002200418180000
+24B0:0000181820044002400244224C62442244224422446247B24002200418180000
+24B1:000018182004400240024E3A4412422242224142414240824002200418180000
+24B2:000018182004400240025FBA4912491244A245A2424242424002200418180000
+24B3:000018182004400240024E72442242424182424244224E724002200418180000
+24B4:000018182004400240025C724822444242824102410243824002200418180000
+24B5:0000181820044002400243F24222444240824102421247E24002200418180000
+24B6:07C018302108428444448442844287C28442844244444C642008183007C00000
+24B7:07C0183020084F8444448422844287828442842244444FC42008183007C00000
+24B8:07C01830200843C4442484028402840284028402442443C42008183007C00000
+24B9:07C0183020084F8444448422842284228422842244444F842008183007C00000
+24BA:07C0183020084FE444248402840287828402840244244FE42008183007C00000
+24BB:07C0183020084FE444248402840287828402840244044E042008183007C00000
+24BC:07C01830200843C444248402840284E284228422446443A42008183007C00000
+24BD:07C0183020084EE444448442844287C28442844244444EE42008183007C00000
+24BE:07C0183020084384410481028102810281028102410443842008183007C00000
+24BF:07C01830200841C4408480828082808280828082488447042008183007C00000
+24C0:07C0183020084E6444448482850286028502848244444E642008183007C00000
+24C1:07C0183020084E0444048402840284028402840244244FC42008183007C00000
+24C2:07C0183020084C6446C486C2854285428442844244444EE42008183007C00000
+24C3:07C0183020084C644444864286428542854284C244C44C642008183007C00000
+24C4:07C0183020084384444488228822882288228822444443842008183007C00000
+24C5:07C0183020084F8444448442844287828402840244044E042008183007C00000
+24C6:07C01830200843844444882288228822882289A2444443A42008183007C00000
+24C7:07C0183020084F8444448442844287828502848244444E242008183007C00000
+24C8:07C0183020084384444484028402838280428042444443842008183007C00000
+24C9:07C0183020084FE4492481028102810281028102410443842008183007C00000
+24CA:07C0183020084EE4444484428442844284428442444443842008183007C00000
+24CB:07C0183020084C64444484428442828282828282410441042008183007C00000
+24CC:07C0183020084C644544854285428542854286C2444444442008183007C00000
+24CD:07C0183020084EE444448442828281028282844244444EE42008183007C00000
+24CE:07C0183020084EE4444484428282810281028102410443842008183007C00000
+24CF:07C0183020084FE448248042808281028202840248244FE42008183007C00000
+24D0:00000FF010082004400247C24822402247E24822482247DA200410080FF00000
+24D1:00000FF014082C04440245C2462244124412441246224DC2200410080FF00000
+24D2:00000FF010082004400243C24422480248024802443243C2200410080FF00000
+24D3:00000FF010282064402243A24462482248224822482247D2200410080FF00000
+24D4:00000FF010082004400243C2442248124FF24802441243E2200410080FF00000
+24D5:00000FF011C82164410247C2410241024102410241024382200410080FF00000
+24D6:00000FF010082004406243C24422442247C248024FE24812281417E80FF00000
+24D7:00000FF014082C04440245E2462244224422442244224E72200410080FF00000
+24D8:00000FF010882084400240824182408240824082408241C2200410080FF00000
+24D9:00000FF010882084400240824182408240824082408240822C8413080FF00000
+24DA:00000FF014082C04440244F24442458246C2446244324E7A200410080FF00000
+24DB:00000FF01108230441024102410241024102410241024382200410080FF00000
+24DC:00000FF01008200440024B625DA249224922492249225DB2200410080FF00000
+24DD:00000FF010082004400245E24E2244224422442244224E72200410080FF00000
+24DE:00000FF010082004400243E24412441244124412441243E2200410080FF00000
+24DF:00000FF010082004400245C24E22441244124412462245C2240414080FF00000
+24E0:00000FF010082004400243A24462482248224822446243A2202410280FF00000
+24E1:00000FF010082004400244E24F3244024402440244024E02200410080FF00000
+24E2:00000FF010082004400243E24412460241C24032441243E2200410080FF00000
+24E3:00000FF0100820044102410247C2410241024102412241C2200410080FF00000
+24E4:00000FF010082004400244224C62442244224422442247D2200410080FF00000
+24E5:00000FF01008200440024E3A441242224222414241424082200410080FF00000
+24E6:00000FF01008200440027BBA5112511249A24AA244424442200410080FF00000
+24E7:00000FF01008200440025C72444242824102428244425C72200410080FF00000
+24E8:00000FF01008200440025C72482244424282410241024382200410080FF00000
+24E9:00000FF010082004400247E2442248424182420244224FC2200410080FF00000
+24EA:000007E01818200443C2442284218421842184218421442243C22004181807E0
+24EB:0000000007E01FF83FFC3FFC7BDE739E7BDE7BDE718E3FFC3FFC1FF807E00000
+24EC:0000000007E01FF83FFC3FFC7B9E73EE7BDE7BBE718E3FFC3FFC1FF807E00000
+24ED:0000000007E01FF83FFC3FFC7B9E73EE7B9E7BEE719E3FFC3FFC1FF807E00000
+24EE:0000000007E01FF83FFC3FFC7B5E735E7B0E7BDE71DE3FFC3FFC1FF807E00000
+24EF:0000000007E01FF83FFC3FFC7B8E73BE7B9E7BEE719E3FFC3FFC1FF807E00000
+24F0:0000000007E01FF83FFC3FFC7B9E737E7B1E7B6E719E3FFC3FFC1FF807E00000
+24F1:0000000007E01FF83FFC3FFC7B1E73DE7BDE7BBE71BE3FFC3FFC1FF807E00000
+24F2:0000000007E01FF83FFC3FFC7B9E736E7B9E7B6E719E3FFC3FFC1FF807E00000
+24F3:0000000007E01FF83FFC3FFC7B9E736E7B8E7BEE719E3FFC3FFC1FF807E00000
+24F4:0000000007E01FF83FFC3FFC73CE7DB67BB677B671CE3FFC3FFC1FF807E00000
+24F5:000007E0181823C44C32500A9089A185A085A08591C9500A4C3223C4181807E0
+24F6:000007E0181823C44C32500A9189A045A085A10591C9500A4C3223C4181807E0
+24F7:000007E0181823C44C32500A9189A045A185A0459189500A4C3223C4181807E0
+24F8:000007E0181823C44C32500A9289A285A3C5A0859089500A4C3223C4181807E0
+24F9:000007E0181823C44C32500A91C9A105A185A0459189500A4C3223C4181807E0
+24FA:000007E0181823C44C32500A9189A205A385A2459189500A4C3223C4181807E0
+24FB:000007E0181823C44C32500A91C9A045A045A0859089500A4C3223C4181807E0
+24FC:000007E0181823C44C32500A9189A245A185A2459189500A4C3223C4181807E0
+24FD:000007E0181823C44C32500A9189A245A1C5A0459189500A4C3223C4181807E0
+24FE:000007E0181823C44C32500A9269A695A295A2959769500A4C3223C4181807E0
+24FF:0000000007E01FF83FFC3FFC7E7E7DBE7DBE7DBE7E7E3FFC3FFC1FF807E00000
+2500:00000000000000FF0000000000000000
+2501:00000000000000FFFF00000000000000
+2502:08080808080808080808080808080808
+2503:18181818181818181818181818181818
+2504:00000000000000DB0000000000000000
+2505:00000000000000DBDB00000000000000
+2506:08080808000008080808000008080808
+2507:18181818000018181818000018181818
+2508:00000000000000AA0000000000000000
+2509:00000000000000AAAA00000000000000
+250A:08080800080808000808080008080800
+250B:18181800181818001818180018181800
+250C:000000000000000F0808080808080808
+250D:000000000000000F0F08080808080808
+250E:000000000000001F1818181818181818
+250F:000000000000001F1F18181818181818
+2510:00000000000000F80808080808080808
+2511:00000000000000F8F808080808080808
+2512:00000000000000F81818181818181818
+2513:00000000000000F8F818181818181818
+2514:080808080808080F0000000000000000
+2515:080808080808080F0F00000000000000
+2516:181818181818181F0000000000000000
+2517:181818181818181F1F00000000000000
+2518:08080808080808F80000000000000000
+2519:08080808080808F8F800000000000000
+251A:18181818181818F80000000000000000
+251B:18181818181818F8F800000000000000
+251C:080808080808080F0808080808080808
+251D:080808080808080F0F08080808080808
+251E:181818181818181F0808080808080808
+251F:080808080808081F1818181818181818
+2520:181818181818181F1818181818181818
+2521:181818181818181F1F08080808080808
+2522:080808080808081F1F18181818181818
+2523:181818181818181F1F18181818181818
+2524:08080808080808F80808080808080808
+2525:08080808080808F8F808080808080808
+2526:18181818181818F80808080808080808
+2527:08080808080808F81818181818181818
+2528:18181818181818F81818181818181818
+2529:18181818181818F8F808080808080808
+252A:08080808080808F8F818181818181818
+252B:18181818181818F8F818181818181818
+252C:00000000000000FF0808080808080808
+252D:00000000000000FFF808080808080808
+252E:00000000000000FF0F08080808080808
+252F:00000000000000FFFF08080808080808
+2530:00000000000000FF1818181818181818
+2531:00000000000000FFF818181818181818
+2532:00000000000000FF1F18181818181818
+2533:00000000000000FFFF18181818181818
+2534:08080808080808FF0000000000000000
+2535:08080808080808FFF800000000000000
+2536:08080808080808FF0F00000000000000
+2537:08080808080808FFFF00000000000000
+2538:18181818181818FF0000000000000000
+2539:18181818181818FFF800000000000000
+253A:18181818181818FF1F00000000000000
+253B:18181818181818FFFF00000000000000
+253C:08080808080808FF0808080808080808
+253D:08080808080808FFF808080808080808
+253E:08080808080808FF0F08080808080808
+253F:08080808080808FFFF08080808080808
+2540:18181818181818FF0808080808080808
+2541:08080808080808FF1818181818181818
+2542:18181818181818FF1818181818181818
+2543:18181818181818FFFF08080808080808
+2544:18181818181818FF1F08080808080808
+2545:08080808080808FFF818181818181818
+2546:08080808080808FF1F18181818181818
+2547:18181818181818FFFF08080808080808
+2548:08080808080808FFFF18181818181818
+2549:18181818181818FFF818181818181818
+254A:18181818181818FF1F18181818181818
+254B:18181818181818FFFF18181818181818
+254C:00000000000000EE0000000000000000
+254D:00000000000000EEEE00000000000000
+254E:08080808080800000808080808080000
+254F:18181818181800001818181818180000
+2550:000000000000FF00FF00000000000000
+2551:14141414141414141414141414141414
+2552:0000000000000F080F08080808080808
+2553:000000000000001F1414141414141414
+2554:0000000000001F101714141414141414
+2555:000000000000F808F808080808080808
+2556:00000000000000FC1414141414141414
+2557:000000000000FC04F414141414141414
+2558:0808080808080F080F00000000000000
+2559:141414141414141F0000000000000000
+255A:14141414141417101F00000000000000
+255B:080808080808F808F800000000000000
+255C:14141414141414FC0000000000000000
+255D:141414141414F404FC00000000000000
+255E:0808080808080F080F08080808080808
+255F:14141414141414171414141414141414
+2560:14141414141417101714141414141414
+2561:080808080808F808F808080808080808
+2562:14141414141414F41414141414141414
+2563:141414141414F404F414141414141414
+2564:000000000000FF00FF08080808080808
+2565:00000000000000FF1414141414141414
+2566:000000000000FF00F714141414141414
+2567:080808080808FF00FF00000000000000
+2568:14141414141414FF0000000000000000
+2569:141414141414F700FF00000000000000
+256A:080808080808FF08FF08080808080808
+256B:14141414141414FF1414141414141414
+256C:141414141414F700F714141414141414
+256D:00000000000000030408080808080808
+256E:00000000000000E01008080808080808
+256F:08080808080810E00000000000000000
+2570:08080808080804030000000000000000
+2571:01010202040408081010202040408080
+2572:80804040202010100808040402020101
+2573:81814242242418181818242442428181
+2574:00000000000000F00000000000000000
+2575:08080808080808080000000000000000
+2576:000000000000000F0000000000000000
+2577:00000000000000000808080808080808
+2578:00000000000000F0F000000000000000
+2579:18181818181818180000000000000000
+257A:000000000000000F0F00000000000000
+257B:00000000000000001818181818181818
+257C:00000000000000FF0F00000000000000
+257D:08080808080808081818181818181818
+257E:00000000000000FFF000000000000000
+257F:18181818181818180808080808080808
+2580:FFFFFFFFFFFFFFFF0000000000000000
+2581:0000000000000000000000000000FFFF
+2582:000000000000000000000000FFFFFFFF
+2583:00000000000000000000FFFFFFFFFFFF
+2584:0000000000000000FFFFFFFFFFFFFFFF
+2585:000000000000FFFFFFFFFFFFFFFFFFFF
+2586:00000000FFFFFFFFFFFFFFFFFFFFFFFF
+2587:0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF
+2588:FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+2589:FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE
+258A:FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC
+258B:F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8
+258C:F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0
+258D:E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0
+258E:C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0
+258F:80808080808080808080808080808080
+2590:0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F
+2591:88228822882288228822882288228822
+2592:AA55AA55AA55AA55AA55AA55AA55AA55
+2593:EEBBEEBBEEBBEEBBEEBBEEBBEEBBEEBB
+2594:FFFF0000000000000000000000000000
+2595:01010101010101010101010101010101
+2596:0000000000000000F0F0F0F0F0F0F0F0
+2597:00000000000000000F0F0F0F0F0F0F0F
+2598:F0F0F0F0F0F0F0F00000000000000000
+2599:F0F0F0F0F0F0F0F0FFFFFFFFFFFFFFFF
+259A:F0F0F0F0F0F0F0F00F0F0F0F0F0F0F0F
+259B:FFFFFFFFFFFFFFFFF0F0F0F0F0F0F0F0
+259C:FFFFFFFFFFFFFFFF0F0F0F0F0F0F0F0F
+259D:0F0F0F0F0F0F0F0F0000000000000000
+259E:0F0F0F0F0F0F0F0FF0F0F0F0F0F0F0F0
+259F:0F0F0F0F0F0F0F0FFFFFFFFFFFFFFFFF
+25A0:0000000000007F7F7F7F7F7F7F000000
+25A1:0000000000007F41414141417F000000
+25A2:0000000000003E41414141413E000000
+25A3:0000000000007F415D5D5D417F000000
+25A4:0000000000007F417F417F417F000000
+25A5:0000000000007F55555555557F000000
+25A6:0000000000007F557F557F557F000000
+25A7:0000000000007F53496553497F000000
+25A8:0000000000007F65495365497F000000
+25A9:0000000000007F556B556B557F000000
+25AA:0000000000003C3C3C3C000000000000
+25AB:0000000000003C24243C000000000000
+25AC:0000000000007F7F7F7F000000000000
+25AD:0000000000007F41417F000000000000
+25AE:00000000003C3C3C3C3C3C3C00000000
+25AF:00000000003C24242424243C00000000
+25B0:000000000000003F7EFC000000000000
+25B1:000000000000003F42FC000000000000
+25B2:000000000018183C3C7E7E0000000000
+25B3:000000000018182424427E0000000000
+25B4:0000000000000000183C7E0000000000
+25B5:000000000000000018247E0000000000
+25B6:000000000060787E7E78600000000000
+25B7:00000000006058464658600000000000
+25B8:000000000000303C3C30000000000000
+25B9:000000000000302C2C30000000000000
+25BA:00000000000060787E78600000000000
+25BB:00000000000060584658600000000000
+25BC:00000000007E7E3C3C18180000000000
+25BD:00000000007E42242418180000000000
+25BE:00000000000000007E3C180000000000
+25BF:00000000000000007E24180000000000
+25C0:0000000000061E7E7E1E060000000000
+25C1:0000000000061A62621A060000000000
+25C2:0000000000000C3C3C0C000000000000
+25C3:0000000000000C34340C000000000000
+25C4:000000000000061E7E1E060000000000
+25C5:000000000000061A621A060000000000
+25C6:0000000000081C3E7F3E1C0800000000
+25C7:00000000000814224122140800000000
+25C8:000000000008142A5D2A140800000000
+25C9:00000000001C22595D4D221C00000000
+25CA:00000018182424424224241818000000
+25CB:00000000001C22414141221C00000000
+25CC:00000000001400410041001400000000
+25CD:00000000001C36555555361C00000000
+25CE:00000000001C22495549221C00000000
+25CF:00000000001C3E7F7F7F3E1C00000000
+25D0:00000000001C32717171321C00000000
+25D1:00000000001C26474747261C00000000
+25D2:00000000001C2241417F3E1C00000000
+25D3:00000000001C3E7F4141221C00000000
+25D4:00000000001C2E4F4F41221C00000000
+25D5:00000000001C2647477F3E1C00000000
+25D6:00000000001838787878381800000000
+25D7:00000000000C0E0F0F0F0E0C00000000
+25D8:FFFFFFFFFFFFE7C3C3E7FFFFFFFFFFFF
+25D9:FFFFFFFFFFE7DBBDBDDBE7FFFFFFFFFF
+25DA:FFFFFFFFFFE7DBBD0000000000000000
+25DB:0000000000000000BDDBE7FFFFFFFFFF
+25DC:00000000001820404000000000000000
+25DD:00000000000C02010100000000000000
+25DE:00000000000000000101020C00000000
+25DF:00000000000000004040201800000000
+25E0:00000000001C22414100000000000000
+25E1:00000000000000004141221C00000000
+25E2:00000000000000000002060E1E3E7E00
+25E3:000000000000000000406070787C7E00
+25E4:00007E7C787060400000000000000000
+25E5:00007E3E1E0E06020000000000000000
+25E6:00000000000000384444443800000000
+25E7:00000000007E727272727E0000000000
+25E8:00000000007E4E4E4E4E7E0000000000
+25E9:00000000007E7A7262427E0000000000
+25EA:00000000007E42464E5E7E0000000000
+25EB:00000000007F494949497F0000000000
+25EC:0000000000081414222A417F00000000
+25ED:00000000000018183434727E00000000
+25EE:000000000018182C2C4E4E7E00000000
+25EF:000000003C4281818181423C00000000
+25F0:00000000000000007E527242427E0000
+25F1:00000000000000007E424272527E0000
+25F2:00000000000000007E42424E4A7E0000
+25F3:00000000000000007E4A4E42427E0000
+25F4:0000000000003C5291F18181423C0000
+25F5:0000000000003C428181F191523C0000
+25F6:0000000000003C4281818F894A3C0000
+25F7:0000000000003C4A898F8181423C0000
+25F8:00007E44485060400000000000000000
+25F9:00007E22120A06020000000000000000
+25FA:00000000000000000040605048447E00
+25FB:0000000000000000007E424242427E00
+25FC:0000000000000000007E7E7E7E7E7E00
+25FD:000000000000000000003C24243C0000
+25FE:000000000000000000003C3C3C3C0000
+25FF:00000000000000000002060A12227E00
+2600:0000084922001C3E3E1C002249080000
+2601:000000002076FF7E0000000000000000
+2602:000000001C3E7F080808081000000000
+2603:8BC803C02FF104248A5028120A504994042147E008101088781E1088081007E0
+2604:00000022222424282902304848300000
+2605:000000000008087F1C36220000000000
+2606:00000000080877222A36220000000000
+2607:00000000000204081020100A060E0000
+2608:0000000000007E424448504A464E0000
+2609:0000000000003C4281999981423C0000
+260A:00000000000018242466A54200000000
+260B:00000000000042A56624241800000000
+260C:00000000000004083048483000000000
+260D:00000000000609090608304848300000
+260E:000000000000003E63002A637F000000
+260F:0000000000003E415D3E49417F000000
+2610:000000000000007F41414141417F0000
+2611:000000000000047F45456559417F0000
+2612:000000000000007F41554955417F0000
+2613:00000000222214140808141422220000
+2614:055004411C3E7F080808081000000000
+2615:000009201240124009200920124000001FC83FF42FD4201420381FC000000000
+2616:00000100028004400820101020082008200820082008200820083FF800000000
+2617:00000100038007C00FE01FF03FF83FF83FF83FF83FF83FF83FF83FF800000000
+2618:00000000028007C007C03398793C3FF8793C3118020002000200040008000000
+2619:0000330C278C6FD84FD07FD07F907F9C3F723F923F941FCC1FC80FD807900300
+261A:00000000000000007E1F1F0E00000000
+261B:00000000000000003F7C7C3800000000
+261C:00000000000000007E11190E00000000
+261D:000000000004041C3424241800000000
+261E:00000000000000003F444C3800000000
+261F:00000000000000182424341C04040000
+2620:0000E7A57E81A5A5815A5A42BDE70000
+2621:000000003804040808101020201C0000
+2622:00000FE01010228846C44EE45EF47FFC4104438447C42FE810100FE000000000
+2623:00000000044008201010101013900C603EF84444854283820280044018300000
+2624:0000030001007FFC23881FF001000D6011100FE0092007C00540038005400100
+2625:0000000000001C2214083E0808080000
+2626:0000000000081C083E08180C08080000
+2627:000000001C12121C1054381038540000
+2628:0000000000081C083E08080808080000
+2629:000000000000001C08497F49081C0000
+262A:000000001E2140C2C7C240211E000000
+262B:000000000000054006C0000015502928292829282548139007C0010000000000
+262C:000000000000008002A0049009C81AAC1AAC19CC1C9C1BEC11C402A000800000
+262D:0000000000000C0239790D3E63C10000
+262E:0000000000003E4949495D6B493E0000
+262F:000000000FE01010200820084C245E047F0C779C7FFC3FF81FF00FE000000000
+2630:00000000000000007FFC7FFC000000007FFC7FFC000000007FFC7FFC00000000
+2631:00000000000000007C7C7C7C000000007FFC7FFC000000007FFC7FFC00000000
+2632:00000000000000007FFC7FFC000000007C7C7C7C000000007FFC7FFC00000000
+2633:00000000000000007C7C7C7C000000007C7C7C7C000000007FFC7FFC00000000
+2634:00000000000000007FFC7FFC000000007FFC7FFC000000007C7C7C7C00000000
+2635:00000000000000007C7C7C7C000000007FFC7FFC000000007C7C7C7C00000000
+2636:00000000000000007FFC7FFC000000007C7C7C7C000000007C7C7C7C00000000
+2637:00000000000000007C7C7C7C000000007C7C7C7C000000007C7C7C7C00000000
+2638:00000000000000493E3E773E3E490000
+2639:0000003C4281A58199A581423C000000
+263A:000000003C4281A581A599423C000000
+263B:000000003C7EFFDBFFDBE77E3C000000
+263C:0000000000492A1C771C2A4900000000
+263D:00000000380C0605050505060C380000
+263E:000000000E18305050505030180E0000
+263F:00000022221C2222221C083E08080000
+2640:00000000001C2222221C083E08080000
+2641:00000008083E08081C2222221C000000
+2642:00000000000703053844444438000000
+2643:000000000202023A46060A7E02020000
+2644:00000000202070202C32222424240000
+2645:00000000006B2A3E2A6B081C141C0000
+2646:000000000859CB4949493E083E080800
+2647:000000007C4242427C404040407E0000
+2648:00000000225514140808080808080000
+2649:0000000000000041221C2222221C0000
+264A:00000000413E1414141414143E410000
+264B:0000000000003E4948300609493E0000
+264C:00000000001C22221274949465020000
+264D:00000000547C555755555555067C0000
+264E:000000000000001C222277007F000000
+264F:00000000547C54545454545455030000
+2650:000000000000000F0345291028440000
+2651:00000000407848484E0A0E0808300000
+2652:0000000000002A5400002A5400000000
+2653:0000000000424224247E242442420000
+2654:00081C495D63412222224141417F0000
+2655:000000081C63412222224141417F0000
+2656:0000000000557F4141222241417F0000
+2657:000000000814222222221477417F0000
+2658:000000021E2242423A122242427E0000
+2659:000000000000182424182424427E0000
+265A:00081C495D7F7F3E3E3E7F7F7F7F0000
+265B:000000081C7F773E3E3E7F7F7F7F0000
+265C:000000000000557F7F3E3E7F7F7F0000
+265D:00000000081C3622363E1C7F7F7F0000
+265E:000000021E367E7E3E1E3E7E7E7E0000
+265F:000000000000183C3C183C3C7E7E0000
+2660:0000000008081C3E7F7F7F3E081C0000
+2661:00000000003649414141221408080000
+2662:00000000080814142222141408080000
+2663:000000001C1C1C087F7F6B08081C0000
+2664:00000000080814224141413E081C0000
+2665:0000000000367F7F7F7F3E1C08080000
+2666:0000000008081C1C3E3E1C1C08080000
+2667:000000001C141C08775D6B08081C0000
+2668:000000085192929249494952817E0000
+2669:00000000080808080808083878700000
+266A:00000000080C0A0A0808083878700000
+266B:0000001C171111111171F1E70F0E0000
+266C:0000001C17111D171171F1E70F0E0000
+266D:000040404040405C6646444850600000
+266E:00000040404E7E72424E7E7202020000
+266F:00000424263E7C6424263E7C64242000
+2670:00000000140808493E49080808140000
+2671:000000001C14086B5D6B080814080000
+2672:03B804A508B3050912052809441FEE00280F304924C90D65161325783CC00040
+2673:0380044004400820002839181B382900210843844004802280427EFC00400020
+2674:038004400440082000283B1818B82900220843844004802280427EFC00400020
+2675:03800440044008200028391818B82B00208843044004802280427EFC00400020
+2676:038004400440082000283A981AB82B80208840844004802280427EFC00400020
+2677:038004400440082000283B981A382B00208843044004802280427EFC00400020
+2678:0380044004400820002839981A382B80224841844004802280427EFC00400020
+2679:038004400440082000283B9818B82900210841044004802280427EFC00400020
+267A:03800440044008200028381818382800200840044004802280427EFC00400020
+267B:03B807BD0FBF070F1207380F7C1FFE00380F304F24CF0DE71FF33DF83CC00040
+267C:07C00FE03C787BBC77AC7FCCC78EE7FED7EEDFEE6F6C76DC7C3C3EF80F6007C0
+267D:07C018302008438444544034B8729802A812A0125094492443C4210818B007C0
+267E:000000000000070018C0202040104D90924892484D904010202018C007000000
+267F:0000000000000600060004000780040017E0202020102050108C0F0000000000
+2680:00000000000000001FF010101010101011101010101010101FF0000000000000
+2681:00000000000000001FF010101010141010101050101010101FF0000000000000
+2682:00000000000000001FF010101410101011101010105010101FF0000000000000
+2683:00000000000000001FF010101450101010101010145010101FF0000000000000
+2684:00000000000000001FF010101450101011101010145010101FF0000000000000
+2685:00000000000000001FF010101450101014501010145010101FF0000000000000
+2686:000000000000070018C020204010401080C880C840104010202018C007000000
+2687:000000000000070018C020204010401098C898C840104010202018C007000000
+2688:00000000000007001FC03FE07FF07FF0FF38FF387FF07FF03FE00F8007000000
+2689:00000000000007001FC03FE07FF07FF0E738E7387FF07FF03FE00F8007000000
+268A:000000000000000000000000000000007FFC7FFC000000000000000000000000
+268B:000000000000000000000000000000007C7C7C7C000000000000000000000000
+268C:0000000000000000000000007FFC7FFC000000007FFC7FFC0000000000000000
+268D:0000000000000000000000007C7C7C7C000000007FFC7FFC0000000000000000
+268E:0000000000000000000000007FFC7FFC000000007C7C7C7C0000000000000000
+268F:0000000000000000000000007C7C7C7C000000007C7C7C7C0000000000000000
+2690:000000704E4242724E40404040400000
+2691:000000707E7E7E7E4E40404040400000
+2692:000007325F7C3E7E7C1FF8277443228101000280044008201010200840040000
+2693:0000000001C00220022001C0008003E000802084708E208410880FF000000000
+2694:0000400420081010082004400280010002800440282810102828400400000000
+2695:0000010001000FF0113011000FC00120012007C0090007800140038001000000
+2696:000000000000010011107FFC39385454545492929292FEFE7C7C383800000000
+2697:0000000000000000000000000FE017F023F021E0200003E00490088800000000
+2698:0000000003800440044004400380010039383D781D700D600380010001000000
+2699:000000000100210817D0082010101010711C10101010082017D0210801000000
+269A:00000100028039387FFCFD7E0540038001000100010001000100010000000000
+269B:000001003AB846C446C4454426C814500D60145026C8454446C446C43AB80100
+269C:010002803AB844448442F29E8AA206C006C0082006C006C00AA0329846C4793C
+269D:010002800440044008006BFC8802882260241810065000882108264818300000
+269E:30000C00030000C00030000C00003FFC0000000C003000C003000C0030000000
+269F:000C003000C003000C00300000003FFC000030000C00030000C00030000C0000
+26A0:000001000280028004400440092009201110111021082008410440047FFC0000
+26A1:0000000002040810207E040810204000
+26A2:000000000000000000000EE011102288228811100EE004400EE0044000000000
+26A3:00000000000001C000C001400E38111823A825401A200C200440038000000000
+26A4:000000380018002801C0022007100A90116010C0088007000200070002000000
+26A5:0000000000000000007000300050038004400820082004400380010003800100
+26A6:00000000000000000038001800A800400EA011002080208011000E0000000000
+26A7:000000000000E00EC006A80A10102BA004400820082004400380010003800100
+26A8:00001038541038103844828244380000
+26A9:0000000000000000000000000000000038004410828883FC8288441038000000
+26AA:00000000000000003844828282443800
+26AB:0000000000000000387CFEFEFE7C3800
+26AC:0000000000000000001C2222221C0000
+26AD:000000000000000000000000000000000EE011102288228811100EE000000000
+26AE:0000000000000000000000000000000000800EB811C411C411C40EB800800000
+26AF:0000000000000000000000000000000000003838444447C44444383800000000
+26B0:0000000000000000060009E0101F2000200020002000101F09E0060000000000
+26B1:000007C002800FE010102008200810101010101008200820082007C000000000
+26B2:00000000000000384482824438101010
+26B3:0000000000000070880404083020F820
+26B4:00000000000010284482442810107C10
+26B5:000000000000925438FE385492107C10
+26B6:0000000000000100010001000100393804400280793C04400280010000000000
+26B7:00000012141814121038444444380000
+26B8:0000000000001C38707070381C083E08
+26B9:00000000422418FF1824420000000000
+26BA:00000000000044444428282810FE0000
+26BB:000000000000FE102828284444440000
+26BC:0000000000007E4242424A7E080F0000
+26BD:0000000007001CC03CE05CF0401087088F88E7387070603027201FC007000000
+26BE:00000000070018C030604890401085088008850840104890306018C007000000
+26BF:000000007FFC4004438444444444438441044104410441C4410440047FFC0000
+26C0:0000000000000000000007E0181821842184381C2FF42A541A5807E000000000
+26C1:0000000007E0181821842184381C2FF42A543A5C2FF42A541A5807E000000000
+26C2:00000000000000000FF0381C67E65E7A5E7A47E2500A55AA65A6381C0FF00000
+26C3:00000FF0381C67E65E7A5E7A47E2500A55AA45A2500A55AA65A6381C0FF00000
+26C4:03C003C00FF004200A5008100A500990042007E008101088781E1088081007E0
+26C5:00000000000001200148001000C0072C09A010602010201010600F8000000000
+26C6:0000222244440088100022224444008810002222444400801012222444480000
+26C7:8BC803C02FF107E48DB02FF20DB04E7407E147E00FF01F787FFE1F780FF007E0
+26C8:0000072008CC10B22102208211040A1807E02000444000801010222044400000
+26C9:0000000000003FF83FF8200820082008200820082008200830180C6003800100
+26CA:0000000000003FF83FF83FF83FF83FF83FF83FF83FF83FF83FF80FE003800100
+26CB:0000000000007FF04510489050506030401060305050489045107FF000000000
+26CC:0000000000000000202010400880040002000100088010402020000000000000
+26CD:00003C00420042008100FF00FF00FF0042004200004000A00110020804040FFE
+26CE:000000000000000000000440044004501E48254824F014400440066000000000
+26CF:000040C027001C001C003E003300218040C0406000300018000C000600000000
+26D0:000000E0031005C803F804E8003000401C00218022001AC002203C2000000000
+26D1:0000000007001DC038E07DF0FFF84010401040102020202018C0070000000000
+26D2:00000000070018C020205050489081088208840848905050202018C007000000
+26D3:000022102A381C5408441C442A54223822102A381C5408441C442A5422380010
+26D4:00000000000007001FC03FE07FF07FF0C018C0187FF07FF03FE01FC007000000
+26D5:000000000C301E302D300C3008E00BC00A000BC008E00C300CB40C780C300000
+26D6:00000000018003C007E00BD011D82ADC7BDE3B541B880FD007E003C001800000
+26D7:0000018002400420081014282E245522842144AA247410280810042002400180
+26D8:0000000007FC07FC07FC0FFC1FFC3FFC3FFC3FFC3FFC3FFC3FFC3FFC00000000
+26D9:00000000180619061906190630066106C106C106C006C106C106C10600000000
+26DA:00000000781E781E700E600600000000000000006006700E781E781E00000000
+26DB:00000000000000001FF018300C600C6006C007C0038003800100010000000000
+26DC:00000000180318431843184330036043C043C043C403C443C443C44300000000
+26DD:0000000000003FF83018282824482288210822882448282830183FF800000000
+26DE:00000000FDF8F8F8E038D018C818840802008108C098C058E038F8F8FDF80000
+26DF:0000000000000000000000007FE07FE07FFC7FE27FFE7FFE7FFE301830180000
+26E0:00007FFE3E021C42084200020042004200020042004200020042004200020000
+26E1:0000400060007000780070006000400040804040422046104E085E047FFE0000
+26E2:00000010387C10107C82BABA827C0000
+26E3:00000100193019300100010003800C60082010101010101008200C6003800000
+26E4:0000010001000280028002807FFC244814500C600AA0092016D0183020080000
+26E5:0000010001000280028000807F5C2048141008600A00092014D0183020080000
+26E6:00000100010002800280020075FC240810500C2000A009201650183020080000
+26E7:00002008183016D009200AA00C60145024487FFC028002800280010001000000
+26E8:0000000000003FF02010231023102FD02FD023102310201030300CC003000000
+26E9:00000000FFFE1010101010101FF0101010101010101010101010101000000000
+26EA:0100010007C001000100038007C01FF07C7C3838339837D837D837D800000000
+26EB:0000000000000F80088078F04010401040104010401040104010401000000000
+26EC:000000000000000000000180018000000000000000000C300C30000000000000
+26ED:000000000000010011100BA0044008203838082004400BA01110010000000000
+26EE:000000000000010011100BA004440824783C482044400BA01110010000000000
+26EF:000000000000010011100BA004400BA03BB80BA004400BA01110010000000000
+26F0:0000000000000000010001000380038007C007C00FE00FE01FF01FF000000000
+26F1:000007E01818282447E2791E41020200020002000400040004007FFE7FFE0000
+26F2:00001450228842844004438447C407C000007FFC3FF80FE00FE01FF03FF80000
+26F3:0000018001E001F8010001000100010001003D787D7CFC7E7EFC3FF807C00000
+26F4:0000000003000300030007E00A5012482248FFFC3FF81FF80FF0000000000000
+26F5:000001000180014005400D20152025104510FDF80100FFFC3FF81FF80FF00000
+26F6:00000000381C4002400240020000000000000000400240024002381C00000000
+26F7:0000000038003800380006000E207FF01C201C0C0E300FC003001C0000000000
+26F8:0000000000000000000000F000F000F000F01FF03FF03FE008403FF800000000
+26F9:0000038003800380000003FC07800B80138C238C038006C006C00C600C60783C
+26FA:0000060005000E800E400E201F101F081F043F823F84318871C871D071E00000
+26FB:0000000007C01830200830180820044004400440082030182008183007C00000
+26FC:00000000010001000100010007C00000000010101010101010107C7C00000000
+26FD:000000000F801FD8104410421FF21FCA1FCA1FCA1FCA1FC41FC07FF000000000
+26FE:00007FFE7FFE7006701A701A701A7006780E7C1E4FF247E26006781E7FFE0000
+26FF:000000007FFC400440047FFC7FFC400440047FFC400040004000400040000000
+2700:00007FFE61867DF661EE6FDE61DE7FFE7FFE73CE6DB66DB66DB673CE7FFE0000
+2701:000038007C006C007C003C000E007FFCFFFED9C0F8E070000000000000000000
+2702:000000007008F83CD878FEF07FE007C07FE0FEF0D878F83C7008000000000000
+2703:00000000000000007000F8E0D9C0FFFE7FFC0E003C007C006C007C0038000000
+2704:00000000700C8832AE4481887910062078508188AE448832700C000000000000
+2705:00000000000000000004000A001200242048509051202A40248011000E000000
+2706:07C01830200841C447E48FF28F729E629C029F024F0446042008183007C00000
+2707:07C01930238843844104838287C287C287C28BA25C7458342008183007C00000
+2708:000008000F00060007C0C380E3C07FFE7FFEE3C0C38007C006000F0008000000
+2709:00000000000000007FFE6006581A4662599A60067FFE00000000000000000000
+270A:000000000000000003600C90149035F8550454E454C43704280810100FE00000
+270B:00000A801540154035405540554C5552402240044008201010100FE000000000
+270C:18302448228812901110092008207CFC92829272922292427C0420081FF00000
+270D:00000008001C003803F70CF511CD238547056FE512052FFD7005600700000000
+270E:000000001800260055004A80714028A014500A28052802C8011800F800000000
+270F:00000000000000003FF050288FF4A8168FF450283FF000000000000000000000
+2710:0000000000F8011802C805280A28145028A071404A8055002600180000000000
+2711:000000000000000000F07908866C80FE866C790800F000000000000000000000
+2712:000000000000000000E079F0FF38FF0EFF3879F000E000000000000000000000
+2713:0000000000000000000000040008001040204040208021001200140008000000
+2714:00000000000000000004000E401CE038E07070E071C03B803F001E000C000000
+2715:00000000101038381C700EE007C0038007C00EE01C7038381010000000000000
+2716:101038387C7CFEFE7FFC3FF81FF00FE01FF03FF87FFCFEFE7C7C383810100000
+2717:00006018306031C01B000E000E001B00198030C0306060306018200000000000
+2718:00006018707031E03B801F000E001F001B8039C030E070706038601020000000
+2719:07C00440054005400540FD7E8102BFFA8102FD7E054005400540044007C00000
+271A:07C007C007C007C007C0FFFEFFFEFFFEFFFEFFFE07C007C007C007C007C00000
+271B:038003800380038003800380FC7EFC7EFC7E0380038003800380038003800000
+271C:07C007C007C007C007C0F83EF83EF83EF83EF83E07C007C007C007C007C00000
+271D:000000000380038003801FF01FF01FF003800380038003800380000000000000
+271E:078004C004C004C07CF8400C400C7CFC3CFC04C004C004C004C007C003C00000
+271F:00000FE008207BBC43845FF45FF45FF443847BBC0BA00BA00BA008200FE00000
+2720:1FF007C0038083828382C386FFFEFFFEFFFEC38683828382038007C01FF00000
+2721:0100028004400440FFFE50145014200850145014FFFE04400440028001000000
+2722:038007C007C003800380610CF93EFFFEF93E610C0380038007C007C003800000
+2723:038007C007C007C00380711CF93EFFFEF93E711C038007C007C007C003800000
+2724:07C00FE00FE007C0638CF39EFFFEFFFEFFFEF39E638C07C00FE00FE007C00000
+2725:0100038007C007C00100310C710EFFFF710E310C010007C007C0038001000000
+2726:01000380038007C007C01FF07FFCFFFE7FFC1FF007C007C00380038001000000
+2727:010002800280044004401830600C8002600C1830044004400280028001000000
+2728:0000040004000A00110060C011100A10042804C6002800100110028001000000
+2729:0000010002800280FC7E4004383808201010111026C828283018000000000000
+272A:07C01FF03EF87EFC7C7CC006F01EF83EF01EF11E67CC6FEC3FF81FF007C00000
+272B:0000010003800380FFFE7C7C383808201C701FF03EF838383018000000000000
+272C:0000010002800280FC7E438427C817D01390101027C828283018000000000000
+272D:0000010002801C70E10E4FE4238817D01450111022882C683018000000000000
+272E:0000010002801D70E38E5FF42FE817D016D0155022882C683018000000000000
+272F:00000100038005C0F9FE5D8C27B813F00FD01D9019D032E82C78301800000000
+2730:00000100028002C0FFFE4447383E083C16D0111827C82F2C3C1C180C00000000
+2731:00000380038003804384F39E3FFC0FF03FFCF39E438403800380038000000000
+2732:00000380038003804384F39E3C7C08303C7CF39E438403800380038000000000
+2733:01000100210811100D600FE007C0FFFE07C00FE00D6011102108010001000000
+2734:0100010021081BB01FF00FE01FE0FFFE1FF00FE01FF01BB02108010001000000
+2735:010002803CF82CC8269832B87D4C83864D7C3A9832C826683E78028001000000
+2736:000001000100010043843BB81FF00FE01FF03BB8438401000100010000000000
+2737:082008200C6006C0E6CE3BB81FF007C01FF03BB8E6CE06C00C60082008200000
+2738:08200C600EE00FE0FFFE7FFC3FF81FF03FF87FFCFFFE0FE00EE00C6008200000
+2739:010019300FE04FE47FFC3FF83FF8FFFE3FF83FF87FFC4FE40FE0193001000000
+273A:0920492425481550CBA637D80FE0FFFE0FE037D8CBA615502548492409200000
+273B:0100038003800380E10E711C0D6003800D60711CE10E03800380038001000000
+273C:038007C007C0638CF11EF39E3C7808203C78F39EF11E638C07C007C003800000
+273D:038007C007C0638CF39EF11E3D7807C03D78F11EF39E638C07C007C003800000
+273E:038004400440745CFC7EFEFE7FFC2108438487C28FE277DC07C007C003800000
+273F:038007C00FE077DCFFFEFC7EF01E701C18303EF87FFC7EFC7EFC3C7800000000
+2740:038004400920793C8542B39A8FE26FEC17D027C84924529442843C7800000000
+2741:03803C78454451144D646FEC86C2BC7A86C26FEC4D64511445443C7803800000
+2742:07C01EF03EF85C7467CCFC7EE82E8822E82EFC7E67CC5C743EF81EF007C00000
+2743:038004C004C074DCBCE69F9E4F3C3FF87264E672CE7A765C0640064003800000
+2744:0000010005400380C92631184D6403804D643118C92603800540010000000000
+2745:0000010005400BA0C92631184D6483824D643118C9260BA00540010000000000
+2746:09200D6007C01390C9263118ED6E0380ED6E3118C926111007C00D6009200000
+2747:000003C023C413C8099005A0700E7DBE7DBE700E05A0099013C823C403C00000
+2748:07C047C427C813900BA0E00EFBBEFBBEFBBEE00E0BA0139027C847C407C00000
+2749:038007C007C077DCFBBEF93E7D7C07C07D7CF93EFBBE77DC07C007C003800000
+274A:010003803398311809200540638CFFFE638C0540092031183398038001000000
+274B:0100038033983BB8193007C077DCFFFE77DC07C019303BB83398038001000000
+274C:0000000018303C781EF00FE007C007C00FE01EF03C7838381010000000000000
+274D:0000000003C00C301008100C2004200620062006100E100C0C3C03F801E00000
+274E:0000FFF8DFD88F88C718E238F078F8F8F078E238C7188F88DFD8FFF800000000
+274F:00001FF81008100E100E100E100E100E100E100E1FFE07FE07FE000000000000
+2750:000007FE07FE1FFE100E100E100E100E100E100E100E10081FF8000000000000
+2751:00001FF8100C100E100E100E100E100E100E100E1FFE0FFE07FE000000000000
+2752:000007FE0FFE1FFE100E100E100E100E100E100E100E100C1FF8000000000000
+2753:000003800FE01E70183018F001E0038003000300030000000300078007800300
+2754:07C0082013901450085000900120024002800280038000000380044004400380
+2755:038006C00C6008200C60044006C0028002800380000003800440044003800000
+2756:00000100038007C00380111038387C7C38381110038007C00380010000000000
+2757:018003C003C003C003C003C003C0018001800180018000000180018000000000
+2758:0180018001800180018001800180018001800180018001800180018001800000
+2759:03C003C003C003C003C003C003C003C003C003C003C003C003C003C003C00000
+275A:0FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00000
+275B:01C007000C000F800FC00FE00FE00FE007C00380000000000000000000000000
+275C:038007C00FE00FE00FE007E003E0006001C00700000000000000000000000000
+275D:1C1C7070C0C0F8F8FCFCFEFEFEFEFEFE7C7C3838000000000000000000000000
+275E:38387C7CFEFEFEFEFEFE7E7E3E3E06061C1C7070000000000000000000000000
+275F:000000000000000007000F801FC01FC01FC00FC007C000C003800E0000000000
+2760:000000000000000038387C7CFEFEFEFEFEFE7E7E3E3E06061C1C707000000000
+2761:0000001000100FFE3FF87E107E103F100FF0001030307820786031C01F000000
+2762:03800FE01FF01FF01FF00FE00380010001000000038007C007C007C003800000
+2763:00000EE01FF01FF01FF00FE0038001000000038007C007C007C0038000000000
+2764:000000003C787EFCFFFEFFFEFFFE7FFC7FFC3FF81FF00FE007C0038001000000
+2765:1C003F007F807FC07FE07FF03FF81FFC3FF87FF07FE07FC07F803F001C000000
+2766:000003000C86388E67F8010039387EFCFFFEFFFE7FFC3FF81FE207EE00F80000
+2767:000030CC31E41BF60BF20BFE09FE39FE4EFC49FC29FC33F813F81BF009E000C0
+2768:00000002040C1818181818180C040200
+2769:0000002010180C0C0C0C0C0C18102000
+276A:000000060C1C3838383838381C0C0600
+276B:00000030181C0E0E0E0E0E0E1C183000
+276C:000000060C0C1818303018180C0C0600
+276D:0000003018180C0C06060C0C18183000
+276E:000000070E0E1C1C38381C1C0E0E0700
+276F:0000007038381C1C0E0E1C1C38387000
+2770:0000000F1E1E3C3C78783C3C1E1E0F00
+2771:000000F078783C3C1E1E3C3C7878F000
+2772:00000004081010101010101010080400
+2773:00000020100808080808080808102000
+2774:0000001E383030181870181830381E00
+2775:000000781C0C0C18180E18180C1C7800
+2776:07C01FF03FF87EFC7CFCFAFEFEFEFEFEFEFEFEFE7EFC783C3FF81FF007C00000
+2777:07C01FF03FF8783C77DCFFDEFFDEFF3EFCFEFBFE77DC701C3FF81FF007C00000
+2778:07C01FF03FF8783C77DCFFDEFFDEFF3EFFDEFFDE77DC783C3FF81FF007C00000
+2779:07C01FF03FF87FBC7F3CFEBEFDBEFBBEF7BEE00E7FBC7E0C3FF81FF007C00000
+277A:07C01FF03FF8701C77FCF7FEF03EFFDEFFDEFFDE77DC783C3FF81FF007C00000
+277B:07C01FF03FF8783C77DCF7FEF7FEF03EF7DEF7DE77DC783C3FF81FF007C00000
+277C:07C01FF03FF8701C77DCFFBEFFBEFF7EFEFEFEFE7DFC7DFC3FF81FF007C00000
+277D:07C01FF03FF8783C77DCF7DEF7DEF83EF7DEF7DE77DC783C3FF81FF007C00000
+277E:07C01FF03FF8783C77DCF7DEF7DEF81EFFDEFFDE77DC783C3FF81FF007C00000
+277F:07C01FF03FF8771C66ECF6EEF6EEF6EEF6EEF6EE76EC631C3FF81FF007C00000
+2780:07C0183020084084418483828182818281828182418441842008183007C00000
+2781:07C01830200847C44FE48C62806281C287028C024FE44FE42008183007C00000
+2782:07C01830200847C44FE48C62806281C280628C624FE447C42008183007C00000
+2783:07C01830200840E441E4836286628C629FF29FF2406440642008183007C00000
+2784:07C0183020084FE44FE48C028FC28FE280628C624FE447C42008183007C00000
+2785:07C01830200847C44FE48C028FC28FE28C628C624FE447C42008183007C00000
+2786:07C0183020084FE44FE48062806280C283828602460446042008183007C00000
+2787:07C01830200847C44FE48C628C6287C28C628C624FE447C42008183007C00000
+2788:07C01830200847C44FE48C628C628FE287E280624FE447C42008183007C00000
+2789:07C01830200844E44DF49DB28DB28DB28DB28DB24DF44CE42008183007C00000
+278A:07C01FF03FF87F7C7E7CFC7EFE7EFE7EFE7EFE7E7E7C7E7C3FF81FF007C00000
+278B:07C01FF03FF8783C701CF39EFF9EFE3EF8FEF3FE701C701C3FF81FF007C00000
+278C:07C01FF03FF8783C701CF39EFF9EFE3EFF9EF39E701C783C3FF81FF007C00000
+278D:07C01FF03FF87F1C7E1CFC9EF99EF39EE00EE00E7F9C7F9C3FF81FF007C00000
+278E:07C01FF03FF8701C701CF3FEF03EF01EFF9EF39E701C783C3FF81FF007C00000
+278F:07C01FF03FF8783C701CF3FEF03EF01EF39EF39E701C783C3FF81FF007C00000
+2790:07C01FF03FF8701C701CFF9EFF9EFF3EFC7EF9FE79FC79FC3FF81FF007C00000
+2791:07C01FF03FF8783C701CF39EF39EF83EF39EF39E701C783C3FF81FF007C00000
+2792:07C01FF03FF8783C701CF39EF39EF01EF81EFF9E701C783C3FF81FF007C00000
+2793:07C01FF03FF87B1C720CE24EF24EF24EF24EF24E720C731C3FF81FF007C00000
+2794:00001F800FC007E003F0FFF8FFFCFFFEFFFCFFF803F007E00FC01F8000000000
+2795:0000000003800380038003803FF83FF83FF80380038003800380000000000000
+2796:0000000000000000000000007FFC7FFC7FFC0000000000000000000000000000
+2797:0000000003800380038000007FFC7FFC7FFC0000038003800380000000000000
+2798:0000000008001C003E001E000F20032000E000F003F000700008000000000000
+2799:00000000000001000180E0C0FCF0FFFEFCF0E0C0018001000000000000000000
+279A:0000000000000008007003F000F000E003200F201E003E001C00080000000000
+279B:0000000000000200010001C000F0FFFE00F001C0010002000000000000000000
+279C:000000C001E001F000F87FFCFFFEFFFEFFFE7FFC00F801F001E000C000000000
+279D:000000000010001000180018FFFCFFFEFFFC0018001800100010000000000000
+279E:00000010001000180018FFFCFFFCFFFEFFFCFFFC001800180010001000000000
+279F:000000000000002000300038AAFCAAFEAAFC0038003000200000000000000000
+27A0:00000000000000200030AAF8AAFCAAFEAAFCAAF8003000200000000000000000
+27A1:000000000000002000300038FFFCFFFEFFFC0038003000200000000000000000
+27A2:400070002C00230010C01030080C07FE0FFC1FF01FC03F003C00700040000000
+27A3:400070003C003F001FC01FF00FFC07FE080C103010C023002C00700040000000
+27A4:400070003C003F001FC01FF00FFC07FE0FFC1FF01FC03F003C00700040000000
+27A5:00000000000080008010C0187FFC7FFE3FFC0018001000000000000000000000
+27A6:0000000000000000001000183FFC7FFE7FFCC018801080000000000000000000
+27A7:00000080008000C007C007E007E007F007E007E007C000C00080008000000000
+27A8:00000000000000400040FFE0FFF0FFFEFFF0FFE0004000400000000000000000
+27A9:000000000000006000707FD8400C4006400C7FD8007000600000000000000000
+27AA:000000000000006000707FE86004600260047FE8007000600000000000000000
+27AB:0000000000080018002400443F8240028006FF1EFE7C05F00FC00F000C000000
+27AC:00000C000F000FC005F0FE7CFF1E800640023F82004400240018000800000000
+27AD:00000000008000C0FFA0801080088004800E801CFFB87FF000E0004000000000
+27AE:0000004000E07FF0FFB8801C800E800480088010FFA000C00080000000000000
+27AF:00000000004000600050FFC8400440024007FFCE7FDC00780070002000000000
+27B0:0000000000631C2222221C0000000000
+27B1:00000020007000787FDCFFCE400740024004FFC8005000600040000000000000
+27B2:07C01FF03F787F3C7F1C000E000600020006000E7F1C7F3C3F781FF007C00000
+27B3:0000000000000000FE004908248C1FFE248C4908FE0000000000000000000000
+27B4:000000000400060007003F001F000F08008800580038007801F8000000000000
+27B5:000000000000000000007C083E0C1FFE3E0C7C08000000000000000000000000
+27B6:00000000000001F800780038005800880F081F003F0007000600040000000000
+27B7:0000000002000300038003803F881F880FD800F8007800F803F8000000000000
+27B8:0000000000000020FC107E183FFC1FFE3FFC7E18FC1000200000000000000000
+27B9:00000000000003F800F8007800F80FD81F883F88038003800300020000000000
+27BA:00000000006000F000F07838FF0CFFFEFF0C783800F000F00060000000000000
+27BB:000000000000004060E078F0FC78FFFEFC7878F060E000400000000000000000
+27BC:0000000000000000F8107C183E1C1FFE3E1C7C18F81000000000000000000000
+27BD:000000000000F860FC707E787FFC3FFE7FFC7E78FC70F8600000000000000000
+27BE:000000000000022001100088FFC40002FFC40088011002200000000000000000
+27BF:00000000000000000000E3C71C382244224422441C3800000000000000000000
+27C0:000000000000000040444850607E0000
+27C1:000000000100028002800440044009200AA01290145027C820083FF800000000
+27C2:000000000000000010101010107C0000
+27C3:0000000000000000000007F808001030104810481030080007F8000000000000
+27C4:000000000000000000001FE000100C08120812080C0800101FE0000000000000
+27C5:000000001C22220404080810100E0000
+27C6:000000001C2222101008080404380000
+27C7:00000000000082825444282810100000
+27C8:0000000000000000000040FE41002200220012001200090008FE000000000000
+27C9:000000000000000000007F020082004400440048004800907F10000000000000
+27CA:00000000101010103810101010100000
+27CB:0000000000000000000000100020004000800100020004000800000000000000
+27CC:000000003FFC2000100010000800080008000800080008001000100020002000
+27CD:0000000000000000000008000400020001000080004000200010000000000000
+27CE:00007FFC4104410442844284444444444824482450145014600C7FFC00000000
+27CF:00007FFC600C50145014482448244444444442844284410441047FFC00000000
+27D0:0000000000000000000000800140022004100888041002200140008000000000
+27D1:00000000000010102828445482820000
+27D2:000000000000000011101110111011101110111011101110092007C000000000
+27D3:000000000000000002021202027E0000
+27D4:00000000000000007E40404840400000
+27D5:000000000000000038040C0C0A14092408C408C409240A140C0C380400000000
+27D6:0000000000000000201C30302850249023102310249028503030201C00000000
+27D7:0000000000000000700E18181428124811881188124814281818700E00000000
+27D8:00000000010001000100010001000100010001000100010001001FF000000000
+27D9:000000001FF00100010001000100010001000100010001000100010000000000
+27DA:00000000000000000000028002807EFC02807EFC028002800000000000000000
+27DB:000000000000000000000280028002807EFC0280028002800000000000000000
+27DC:000000000000000000000000000020005FFE2000000000000000000000000000
+27DD:000000000000000000000000000040007FFE4000000000000000000000000000
+27DE:000000000000000000000000000000027FFE0002000000000000000000000000
+27DF:0000000000000000008001400080008000800080008000800080008001C00000
+27E0:0000001028284444FE44442828100000
+27E1:0000010002800280044008203018400430180820044002800280010000000000
+27E2:000000800140014002200410180CE002180C0410022001400140008000000000
+27E3:0000010002800280044008203018400730180820044002800280010000000000
+27E4:00001FFE10021002100210021002F002100210021002100210021FFE00000000
+27E5:00007FF840084008400840084008400F400840084008400840087FF800000000
+27E6:003E28282828282828282828283E0000
+27E7:007C14141414141414141414147C0000
+27E8:00000408081010202010100808040000
+27E9:00002010100808040408081010200000
+27EA:00000A141428285050282814140A0000
+27EB:000050282814140A0A14142828500000
+27EC:00000002040C1414141414140C040200
+27ED:00000040203028282828282830204000
+27EE:00000002040808080808080808040200
+27EF:00000040201010101010101010204000
+27F0:000000000100028006C00AA01AB02AA80AA00AA00AA00AA00AA00AA000000000
+27F1:000000000AA00AA00AA00AA00AA00AA02AA81AB00AA006C00280010000000000
+27F2:000000000000000001E00210040808042A041C0408040008021001E000000000
+27F3:0000000000000000078008401020201020542038201010000840078000000000
+27F4:000000000000000000000000038005480924FFFE092405480380000000000000
+27F5:0000000000000000000000000000100020007FFF200010000000000000000000
+27F6:000000000000000000000000000000080004FFFE000400080000000000000000
+27F7:0000000000000000000000000000100820047FFE200410080000000000000000
+27F8:000000000000000000000000100020007FFE80007FFE20001000000000000000
+27F9:00000000000000000000000000100008FFFC0002FFFC00080010000000000000
+27FA:000000000000000000000000081010083FFC40023FFC10080810000000000000
+27FB:0000000000000000000000000000100220027FFE200210020000000000000000
+27FC:0000000000000000000000000000400840047FFE400440080000000000000000
+27FD:000000000000000000000000080210023FFE40023FFE10020802000000000000
+27FE:000000000000000000000000401040087FFC40027FFC40084010000000000000
+27FF:000000000000000000000000000000082224D55E088400080000000000000000
+2800:00000022000022000022000022000000
+2801:00000032300022000022000022000000
+2802:00000022000032300022000022000000
+2803:00000032300032300022000022000000
+2804:00000022000022000032300022000000
+2805:00000032300022000032300022000000
+2806:00000022000032300032300022000000
+2807:00000032300032300032300022000000
+2808:00000026060022000022000022000000
+2809:00000036360022000022000022000000
+280A:00000026060032300022000022000000
+280B:00000036360032300022000022000000
+280C:00000026060022000032300022000000
+280D:00000036360022000032300022000000
+280E:00000026060032300032300022000000
+280F:00000036360032300032300022000000
+2810:00000022000026060022000022000000
+2811:00000032300026060022000022000000
+2812:00000022000036360022000022000000
+2813:00000032300036360022000022000000
+2814:00000022000026060032300022000000
+2815:00000032300026060032300022000000
+2816:00000022000036360032300022000000
+2817:00000032300036360032300022000000
+2818:00000026060026060022000022000000
+2819:00000036360026060022000022000000
+281A:00000026060036360022000022000000
+281B:00000036360036360022000022000000
+281C:00000026060026060032300022000000
+281D:00000036360026060032300022000000
+281E:00000026060036360032300022000000
+281F:00000036360036360032300022000000
+2820:00000022000022000026060022000000
+2821:00000032300022000026060022000000
+2822:00000022000032300026060022000000
+2823:00000032300032300026060022000000
+2824:00000022000022000036360022000000
+2825:00000032300022000036360022000000
+2826:00000022000032300036360022000000
+2827:00000032300032300036360022000000
+2828:00000026060022000026060022000000
+2829:00000036360022000026060022000000
+282A:00000026060032300026060022000000
+282B:00000036360032300026060022000000
+282C:00000026060022000036360022000000
+282D:00000036360022000036360022000000
+282E:00000026060032300036360022000000
+282F:00000036360032300036360022000000
+2830:00000022000026060026060022000000
+2831:00000032300026060026060022000000
+2832:00000022000036360026060022000000
+2833:00000032300036360026060022000000
+2834:00000022000026060036360022000000
+2835:00000032300026060036360022000000
+2836:00000022000036360036360022000000
+2837:00000032300036360036360022000000
+2838:00000026060026060026060022000000
+2839:00000036360026060026060022000000
+283A:00000026060036360026060022000000
+283B:00000036360036360026060022000000
+283C:00000026060026060036360022000000
+283D:00000036360026060036360022000000
+283E:00000026060036360036360022000000
+283F:00000036360036360036360022000000
+2840:00000022000022000022000032300000
+2841:00000032300022000022000032300000
+2842:00000022000032300022000032300000
+2843:00000032300032300022000032300000
+2844:00000022000022000032300032300000
+2845:00000032300022000032300032300000
+2846:00000022000032300032300032300000
+2847:00000032300032300032300032300000
+2848:00000026060022000022000032300000
+2849:00000036360022000022000032300000
+284A:00000026060032300022000032300000
+284B:00000036360032300022000032300000
+284C:00000026060022000032300032300000
+284D:00000036360022000032300032300000
+284E:00000026060032300032300032300000
+284F:00000036360032300032300032300000
+2850:00000022000026060022000032300000
+2851:00000032300026060022000032300000
+2852:00000022000036360022000032300000
+2853:00000032300036360022000032300000
+2854:00000022000026060032300032300000
+2855:00000032300026060032300032300000
+2856:00000022000036360032300032300000
+2857:00000032300036360032300032300000
+2858:00000026060026060022000032300000
+2859:00000036360026060022000032300000
+285A:00000026060036360022000032300000
+285B:00000036360036360022000032300000
+285C:00000026060026060032300032300000
+285D:00000036360026060032300032300000
+285E:00000026060036360032300032300000
+285F:00000036360036360032300032300000
+2860:00000022000022000026060032300000
+2861:00000032300022000026060032300000
+2862:00000022000032300026060032300000
+2863:00000032300032300026060032300000
+2864:00000022000022000036360032300000
+2865:00000032300022000036360032300000
+2866:00000022000032300036360032300000
+2867:00000032300032300036360032300000
+2868:00000026060022000026060032300000
+2869:00000036360022000026060032300000
+286A:00000026060032300026060032300000
+286B:00000036360032300026060032300000
+286C:00000026060022000036360032300000
+286D:00000036360022000036360032300000
+286E:00000026060032300036360032300000
+286F:00000036360032300036360032300000
+2870:00000022000026060026060032300000
+2871:00000032300026060026060032300000
+2872:00000022000036360026060032300000
+2873:00000032300036360026060032300000
+2874:00000022000026060036360032300000
+2875:00000032300026060036360032300000
+2876:00000022000036360036360032300000
+2877:00000032300036360036360032300000
+2878:00000026060026060026060032300000
+2879:00000036360026060026060032300000
+287A:00000026060036360026060032300000
+287B:00000036360036360026060032300000
+287C:00000026060026060036360032300000
+287D:00000036360026060036360032300000
+287E:00000026060036360036360032300000
+287F:00000036360036360036360032300000
+2880:00000022000022000022000026060000
+2881:00000032300022000022000026060000
+2882:00000022000032300022000026060000
+2883:00000032300032300022000026060000
+2884:00000022000022000032300026060000
+2885:00000032300022000032300026060000
+2886:00000022000032300032300026060000
+2887:00000032300032300032300026060000
+2888:00000026060022000022000026060000
+2889:00000036360022000022000026060000
+288A:00000026060032300022000026060000
+288B:00000036360032300022000026060000
+288C:00000026060022000032300026060000
+288D:00000036360022000032300026060000
+288E:00000026060032300032300026060000
+288F:00000036360032300032300026060000
+2890:00000022000026060022000026060000
+2891:00000032300026060022000026060000
+2892:00000022000036360022000026060000
+2893:00000032300036360022000026060000
+2894:00000022000026060032300026060000
+2895:00000032300026060032300026060000
+2896:00000022000036360032300026060000
+2897:00000032300036360032300026060000
+2898:00000026060026060022000026060000
+2899:00000036360026060022000026060000
+289A:00000026060036360022000026060000
+289B:00000036360036360022000026060000
+289C:00000026060026060032300026060000
+289D:00000036360026060032300026060000
+289E:00000026060036360032300026060000
+289F:00000036360036360032300026060000
+28A0:00000022000022000026060026060000
+28A1:00000032300022000026060026060000
+28A2:00000022000032300026060026060000
+28A3:00000032300032300026060026060000
+28A4:00000022000022000036360026060000
+28A5:00000032300022000036360026060000
+28A6:00000022000032300036360026060000
+28A7:00000032300032300036360026060000
+28A8:00000026060022000026060026060000
+28A9:00000036360022000026060026060000
+28AA:00000026060032300026060026060000
+28AB:00000036360032300026060026060000
+28AC:00000026060022000036360026060000
+28AD:00000036360022000036360026060000
+28AE:00000026060032300036360026060000
+28AF:00000036360032300036360026060000
+28B0:00000022000026060026060026060000
+28B1:00000032300026060026060026060000
+28B2:00000022000036360026060026060000
+28B3:00000032300036360026060026060000
+28B4:00000022000026060036360026060000
+28B5:00000032300026060036360026060000
+28B6:00000022000036360036360026060000
+28B7:00000032300036360036360026060000
+28B8:00000026060026060026060026060000
+28B9:00000036360026060026060026060000
+28BA:00000026060036360026060026060000
+28BB:00000036360036360026060026060000
+28BC:00000026060026060036360026060000
+28BD:00000036360026060036360026060000
+28BE:00000026060036360036360026060000
+28BF:00000036360036360036360026060000
+28C0:00000022000022000022000036360000
+28C1:00000032300022000022000036360000
+28C2:00000022000032300022000036360000
+28C3:00000032300032300022000036360000
+28C4:00000022000022000032300036360000
+28C5:00000032300022000032300036360000
+28C6:00000022000032300032300036360000
+28C7:00000032300032300032300036360000
+28C8:00000026060022000022000036360000
+28C9:00000036360022000022000036360000
+28CA:00000026060032300022000036360000
+28CB:00000036360032300022000036360000
+28CC:00000026060022000032300036360000
+28CD:00000036360022000032300036360000
+28CE:00000026060032300032300036360000
+28CF:00000036360032300032300036360000
+28D0:00000022000026060022000036360000
+28D1:00000032300026060022000036360000
+28D2:00000022000036360022000036360000
+28D3:00000032300036360022000036360000
+28D4:00000022000026060032300036360000
+28D5:00000032300026060032300036360000
+28D6:00000022000036360032300036360000
+28D7:00000032300036360032300036360000
+28D8:00000026060026060022000036360000
+28D9:00000036360026060022000036360000
+28DA:00000026060036360022000036360000
+28DB:00000036360036360022000036360000
+28DC:00000026060026060032300036360000
+28DD:00000036360026060032300036360000
+28DE:00000026060036360032300036360000
+28DF:00000036360036360032300036360000
+28E0:00000022000022000026060036360000
+28E1:00000032300022000026060036360000
+28E2:00000022000032300026060036360000
+28E3:00000032300032300026060036360000
+28E4:00000022000022000036360036360000
+28E5:00000032300022000036360036360000
+28E6:00000022000032300036360036360000
+28E7:00000032300032300036360036360000
+28E8:00000026060022000026060036360000
+28E9:00000036360022000026060036360000
+28EA:00000026060032300026060036360000
+28EB:00000036360032300026060036360000
+28EC:00000026060022000036360036360000
+28ED:00000036360022000036360036360000
+28EE:00000026060032300036360036360000
+28EF:00000036360032300036360036360000
+28F0:00000022000026060026060036360000
+28F1:00000032300026060026060036360000
+28F2:00000022000036360026060036360000
+28F3:00000032300036360026060036360000
+28F4:00000022000026060036360036360000
+28F5:00000032300026060036360036360000
+28F6:00000022000036360036360036360000
+28F7:00000032300036360036360036360000
+28F8:00000026060026060026060036360000
+28F9:00000036360026060026060036360000
+28FA:00000026060036360026060036360000
+28FB:00000036360036360026060036360000
+28FC:00000026060026060036360036360000
+28FD:00000036360026060036360036360000
+28FE:00000026060036360036360036360000
+28FF:00000036360036360036360036360000
+2900:000000000000000000000000000002280214FFFE021402280000000000000000
+2901:000000000000000000000000000005280514FFFE051405280000000000000000
+2902:000000000000000000000000088010803FFF40803FFF10800880000000000000
+2903:00000000000000000000000001100108FFFC0102FFFC01080110000000000000
+2904:000000000000000000000000049008881FFC20821FFC08880490000000000000
+2905:0000000000000000000000000000402840147FFE401440280000000000000000
+2906:000000000000000000000000080010043FFE40043FFE10040800000000000000
+2907:000000000000000000000000001040087FFC40027FFC40080010000000000000
+2908:0808080808083E080808082A1C080000
+2909:0000081C2A080808083E080808080808
+290A:000000000100038005400D601550054005400540054005400540054000000000
+290B:00000000054005400540054005400540054015500D6005400380010000000000
+290C:0000000000000000000000000000100020007F7F200010000000000000000000
+290D:000000000000000000000000000000080004FEFE000400080000000000000000
+290E:0000000000000000000000000000100020007DEF200010000000000000000000
+290F:000000000000000000000000000000080004F7BE000400080000000000000000
+2910:00000000000000000000000000008050402836FC402880500000000000000000
+2911:000000000000000000000000000000080004AAAE000400080000000000000000
+2912:00007F1C2A0808080808080808080808
+2913:08080808080808080808082A1C7F0000
+2914:0000000000000000000000000000410821041FFE210441080000000000000000
+2915:0000000000000000000000000000428822841FFE228442880000000000000000
+2916:0000000000000000000000000000402820141FFE201440280000000000000000
+2917:0000000000000000000000000000412821141FFE211441280000000000000000
+2918:0000000000000000000000000000452825141FFE251445280000000000000000
+2919:0000000000000000000000000000000200047FF8000400020000000000000000
+291A:0000000000000000000000000000400020001FFE200040000000000000000000
+291B:0000000000000000000000000000001200247FF8002400120000000000000000
+291C:0000000000000000000000000000480024001FFE240048000000000000000000
+291D:000000000000000000000000000011003A007FFF3A0011000000000000000000
+291E:00000000000000000000000000000044002E7FFF002E00440000000000000000
+291F:000000000000000000000000000011023A027FFE3A0211020000000000000000
+2920:00000000000000000000000000004088405C7FFE405C40880000000000000000
+2921:00003C00300028002400020001000080004000200012000A0006001E00000000
+2922:0000001E0006000A0012002000400080010002002400280030003C0000000000
+2923:00003C0030002800240002000100008000400020001000080024001800000000
+2924:0000007800180028004800800100020004000800100020004800300000000000
+2925:0000300048002000100008000400020001000080004800280018007800000000
+2926:0000003000480010002000400080010002000400480050006000780000000000
+2927:0000781E6006500A481204200240018001800240042008101008200400000000
+2928:0000001E2006100A08120420024001800180024004200812100A2006001E0000
+2929:00002004100808100420024001800180024004204812500A6006781E00000000
+292A:0000780060045008481004200240018001800240042048105008600478000000
+292B:0000000020041008081004200240008001000240042008101008200400000000
+292C:0000000020041008081004200240010000800240042008101008200400000000
+292D:0000001E2006100A08120420024001000080024004200812100A2006001E0000
+292E:0000001E2006100A08120420024000800100024004200812100A2006001E0000
+292F:0000001E2006100A081204200240010000800240042008101008200400000000
+2930:00002004100808100420024000800100024004200812100A2006001E00000000
+2931:0000781E6006500A481204200240008001000240042008101008200400000000
+2932:0000781E6006500A481204200240010000800240042008101008200400000000
+2933:0000000000000000000000001C002208410440FE000400080000000000000000
+2934:000000000010003800540010001000100020FFC0000000000000000000000000
+2935:00000000FFC00020001000100010005400380010000000000000000000000000
+2936:0008000800080008000800080008040808101FE0080004000000000000000000
+2937:10001000100010001000100010001020081007F8001000200000000000000000
+2938:000020100808040404042828303C0000
+2939:0000040810102020202014140C3C0000
+293A:0000000000000000000000000000000023C02C3030083C040000000000000000
+293B:00000000000000000000000000000000203C100C0C3403C40000000000000000
+293C:0000000000000000000000000000000003C40C34100C203C0700000000000000
+293D:0000000000000000000000000000000023C02C3030083C4400E0004000000000
+293E:000000000000000000100008000400043C0430082C3023C00000000000000000
+293F:00000000000000000800100020002000203C100C0C3403C40000000000000000
+2940:000000000080010003800D601090101020082008101010100C60038000000000
+2941:000000000200010003800D601210101020082008101010100C60038000000000
+2942:000000000000000800047FFE00040008100020007E0020001000000000000000
+2943:000000000000100020007FFE2000100000080004007E00040008000000000000
+2944:00000000000000080004007E00040008100020007FFE20001000000000000000
+2945:00000000000000000000000000080004FFFE0004080808003E00080008000000
+2946:00000000000000000000000020004000FFFF40002020002000F8002000200000
+2947:000000000000000000000000001011080A04FFFE0A0411080010000000000000
+2948:000000000000000000000000101023884444FFFE444423881010000000000000
+2949:00001038543854101010384444380000
+294A:0000000000000000000000000000100020007FFE000400080000000000000000
+294B:0000000000000000000000000000000800047FFE200010000000000000000000
+294C:00001018141010101010105030100000
+294D:00001030501010101010101418100000
+294E:0000000000000000000000000000100820047FFE000000000000000000000000
+294F:00002030282020202020202830200000
+2950:0000000000000000000000000000000000007FFE200410080000000000000000
+2951:00000818280808080808082818080000
+2952:0000000000000000000000000000480050007FFF400040000000000000000000
+2953:00000000000000000000000000000012000AFFFE000200020000000000000000
+2954:00003E080C0A08080808080808080808
+2955:000008080808080808080A0C083E0000
+2956:0000000000000000000000000000400040007FFF500048000000000000000000
+2957:000000000000000000000000000000020002FFFE000A00120000000000000000
+2958:00003E08182808080808080808080808
+2959:000008080808080808082818083E0000
+295A:0000000000000000000000000000080210023FFE000200020000000000000000
+295B:0000000000000000000000000000401040087FFC400040000000000000000000
+295C:000010181410101010101010107C0000
+295D:00007C10101010101010101418100000
+295E:0000000000000000000000000000000200023FFE100208020000000000000000
+295F:0000000000000000000000000000400040007FFC400840100000000000000000
+2960:000010305010101010101010107C0000
+2961:00007C10101010101010105030100000
+2962:00000000000000000000100020007FFE0000000000007FFE2000100000000000
+2963:00000000022006300A2802200220022002200220022002200220022000000000
+2964:00000000000000000000000800047FFE0000000000007FFE0004000800000000
+2965:000000000220022002200220022002200220022002200A280630022000000000
+2966:00000000000000000000100020007FFE0000000800047FFE0000000000000000
+2967:00000000000000000000000000007FFE2000100000007FFE0004000800000000
+2968:00000000000000000000000800047FFE0000100020007FFE0000000000000000
+2969:00000000000000000000000000007FFE0004000800007FFE2000100000000000
+296A:000000000000000000000000100020007FFE00007FFE00000000000000000000
+296B:000000000000000000000000000000007FFE00007FFE20001000000000000000
+296C:000000000000000000000000000800047FFE00007FFE00000000000000000000
+296D:000000000000000000000000000000007FFE00007FFE00040008000000000000
+296E:00000000022006200A2002200220022002200220022002280230022000000000
+296F:000000000220023002280220022002200220022002200A200620022000000000
+2970:00000000000000000000000000007FFC000200027FFC00000000000000000000
+2971:000000000000000000001F8000001F880004FFFE000400080000000000000000
+2972:000000000000000000003800444003880004FFFE000400080000000000000000
+2973:0000000000000000000000000000100020007FFF200011C00222001C00000000
+2974:000000000000000000000000000000080004FFFE000438084440038000000000
+2975:000000000000000000000000000000080004FFFE380444480380380044400380
+2976:0000000000180060018006000800060001800060021804000FF8040002000000
+2977:0000000000000000000000060018106021807FF0218010600018000600000000
+2978:000000000C00030000C000300008003000C003000C2000100FF8001000200000
+2979:0000000003F80400080008000800040003F80000020004000FF8040002000000
+297A:00000000000000000000000001FE120024007FFE2400120001FE000000000000
+297B:000000000FE0001000080008000800100FE00000020004000FF8040002000000
+297C:0000000000204040201F204040200000
+297D:0000000000020101027C020101020000
+297E:000000000000000000000C601290010001000100010001000100000000000000
+297F:00000000000000000000000001000100010001000100010012900C6000000000
+2980:000000002A2A2A2A2A2A2A2A2A2A0000
+2981:00000000000000000000000000000000018003C003C001800000000000000000
+2982:00000000182424180000182424180000
+2983:00001E24241414244424141424241E00
+2984:00007824242828242224282824247800
+2985:0000000C181828282828282818180C00
+2986:00000030181814141414141418183000
+2987:0000000C141424242424242414140C00
+2988:00000030282824242424242428283000
+2989:000000040C0C1414242414140C0C0400
+298A:00000020303028282424282830302000
+298B:0000000E0808080808080808080E000E
+298C:00000070101010101010101010700070
+298D:0000001E181412101010101010101E00
+298E:00000078080808080808084828187800
+298F:0000001E101010101010101214181E00
+2990:00000078182848080808080808087800
+2991:00000004080810102626101008080400
+2992:00000020101008086464080810102000
+2993:0000000000000040008C00F0018003000D0011000D000300018000F0008C0040
+2994:00000000000001001880078000C00060005800440058006000C0078018800100
+2995:00000000000000A019400740038002E0029802840298026001C0074018A00000
+2996:0000000000000280014C017000E003A00CA010A00CA0032001C00170028C0000
+2997:0000000C183838383838383838180C00
+2998:00000030181C1C1C1C1C1C1C1C183000
+2999:00000000000000010001000100010000
+299A:0000020001000080010002000100008001000200010000800100020001000080
+299B:00000000000000000400024001800180024002200410040804043FFE04000000
+299C:0000000000000000200020002000200020003E002200220022003FFC00000000
+299D:000000000000000020002000200020003C0022002100290021003FFC00000000
+299E:0000000000000000001000200040009C012002180404083810003FFE00000000
+299F:0000000000000000000000000000000C003000C003000C0010003FFE00000000
+29A0:0000000000000000184006800180016002180204021801600180068018400000
+29A1:000000000000000010041004080809C806300C18122402200140014000800000
+29A2:00000000000000003FFE00040008001000200040008001000200040000000000
+29A3:00000000000000000400020001000080004000200010000800043FFE00000000
+29A4:00000000000000000010002000400080010002000400080010003FFE00003FFE
+29A5:00000000000000000400020001000080004000200010000800043FFE00003FFE
+29A6:000000000000000000000040201E0000
+29A7:00000000000000000000001E20400000
+29A8:00000000000000780018012800C800C0012002200410081010103FFE00100000
+29A9:0000000000000F000C000A4009800180024002200410040804043FFE04000000
+29AA:00000000000000103FFE1010081004100220012000C000C80128001800780000
+29AB:00000000000004003FFE04040408041002200240018009800A400C000F000000
+29AC:00000000000010001000103C3E0C119410641060109011001200140018001000
+29AD:000000000000000800083C08307C298826080608090800880048002800180008
+29AE:0000000000001000180014001200110010901060106411943E0C103C10001000
+29AF:000000000000000800180028004800880908060826082988307C3C0800080008
+29B0:0000000000000000000017C0082014101210111010901050082007D000000000
+29B1:00000000000007C0000007D0082010501090111012101410082017C000000000
+29B2:0000010002800100000007D0082010501090111012101410082017C000000000
+29B3:010000800FC00080010007D0082010501090111012101410082017C000000000
+29B4:020004000FC00400020007D0082010501090111012101410082017C000000000
+29B5:0000000000000000000007C00820101010103FF810101010082007C000000000
+29B6:0000000000000000000007C0092011101110111011101110092007C000000000
+29B7:0000000000000000000007C0082012901290129012901290082007C000000000
+29B8:0000000000000000000007C0082014101210111010901050082007C000000000
+29B9:0000000000000000000007C00820111011101110111017D0082007C000000000
+29BA:0000000000000000000007C00920111011101FF010101010082007C000000000
+29BB:0000000000000000000017D0082014501290111012901450082017D000000000
+29BC:00000000000003E004100808122410441084110412240808041003E000000000
+29BD:0000010003800500010007C0092011101110111011101110092007C001000000
+29BE:00000000000003E0041009C81224141414141414122409C8041003E000000000
+29BF:00000000000003E0041009C813E417F417F417F413E409C8041003E000000000
+29C0:00000000000003E00410080810C413041404130410C40808041003E000000000
+29C1:00000000000003E004100808118410641014106411840808041003E000000000
+29C2:000000000000000000001F4020804140424844544848504020805F0000000000
+29C3:000000000000000000000FA0104020A0213C2220243C282010402F8000000000
+29C4:0000000000007FF04030405040904110421044104810501060107FF000000000
+29C5:0000000000007FF06010501048104410421041104090405040307FF000000000
+29C6:0000000000007FF04010421052504A9047104A905250421040107FF000000000
+29C7:0000000000007FF04010401047104890489048904710401040107FF000000000
+29C8:0000000000007FF040105FD0505050505050505050505FD040107FF000000000
+29C9:000000003FC020402040204023FC224422443FC402040204020403FC00000000
+29CA:000001000000010002800280044004400820082010101010200820087FFC0000
+29CB:00000000010002800280044004400820082010101010200820087FFC00007FFC
+29CC:0000008001400140022002200410041009C80A0811841044238220027FFF0000
+29CD:0000000001000280028004400440082008201010101020082008FFFE00000000
+29CE:1800160011801060101010601180163018D003100C1010100C10031000D00030
+29CF:00000000000000000000006801A80628182820281828062801A8006800000000
+29D0:000000000000000000002C002B0028C028302808283028C02B002C0000000000
+29D1:0000000000000082C6EAF2EAC6820000
+29D2:0000000000000082C6AE9EAEC6820000
+29D3:0000000000000082C6EEFEEEC6820000
+29D4:0000000000000082C4E8F0E8C4820000
+29D5:0000000000000082462E1E2E46820000
+29D6:00000000000000FE4428102844FE0000
+29D7:00000000000000FE7C3810387CFE0000
+29D8:00002010081020100810201008102000
+29D9:00000810201008102010081020100800
+29DA:0000000004400220011002200440022001100220044002200110022004400000
+29DB:0000000001100220044002200110022004400220011002200440022001100000
+29DC:00000000000000000000000000000000000000001E00210022881C7000000000
+29DD:00000000000000000000000000000380044004400EE0111011100EE000000000
+29DE:00000000000000000000000000000000010001001D70238823881D7001000100
+29DF:000000000000000000000000300C48124FF24812300C00000000000000000000
+29E0:000000003FF83FFC3004300430043004300430043004300430043FFC00000000
+29E1:0000000000000000000000000000000C003000C003000C0010003FFE00003FFE
+29E2:00000000000000000000000000000000210821082108210821083FF800000000
+29E3:00000000000000120024004800907FFE02407FFE090012002400480000000000
+29E4:00000000064009920024004800907FFE02407FFE090012002400480000000000
+29E5:000000000012002400487FFE01207FFE04807FFE120024004800000000000000
+29E6:0000000000000000400240027FFE400240027FFE400240020000000000000000
+29E7:0000000000000000010001001FF0010001001FF0010001000000000000000000
+29E8:0000000000007FFC3F083F081F101F100F200F20074007400380038001000000
+29E9:0000000000007FFC21F821F811F011F009E009E005C005C00380038001000000
+29EA:0000000000000100038007C00FE01FF00FE007C0038001000540038001000000
+29EB:00001038387C7CFE7C7C383810000000
+29EC:000000000000000001C00220041004100410022001C0008002A001C000800000
+29ED:000000000000000001C003E007F007F007F003E001C0008002A001C000800000
+29EE:0000000000000F8002001FC0104010401040104010401FC002000F8000000000
+29EF:0000000000000F8002001FC01FC01FC01FC01FC01FC01FC002000F8000000000
+29F0:0000000000000F800200020005000880104008800500020002000F8000000000
+29F1:0000000000000F800200020007000F801FC00F800700020002000F8000000000
+29F2:0000000000000F800200070008801040104010400880070002000F8000000000
+29F3:0000000000000F80020007000F801FC01FC01FC00F80070002000F8000000000
+29F4:000000000000000000000000400800041FFE0004400800000000000000000000
+29F5:00000000404020201010080804040000
+29F6:00007800040408081010202040400000
+29F7:00000000404020207C10080804040000
+29F8:01010202040408081010202040400000
+29F9:80804040202010100808040402020000
+29FA:0000000000002828FE28280000000000
+29FB:0000000000005454FE54540000000000
+29FC:00000002020418608060180402020000
+29FD:000000808040300C020C304080800000
+29FE:00000000000007C007C00380610C793C7FFC793C610C0380038007C007C00000
+29FF:000000000000000000000000600C783C7FFC783C600C00000000000000000000
+2A00:00000000000003E004100808100410041084100410040808041003E000000000
+2A01:00000000000003E004900888108410841FFC108410840888049003E000000000
+2A02:00000000000003E004100C18122411441084114412240C18041003E000000000
+2A03:0000000000001020102010201020102013201320102010200840078000000000
+2A04:00000000000010101010101010101110111017D011101110082007C000000000
+2A05:00000000000010101010101010101010101010101010101010101FF000000000
+2A06:0000000000001FF0101010101010101010101010101010101010101000000000
+2A07:000000000000024005A005A00990099012481248242424244812481200000000
+2A08:0000000000004812481224242424124812480990099005A005A0024000000000
+2A09:0000000000002008101008200440028001000280044008201010200800000000
+2A0A:00000000000000001FF010000B0004800A400A4004800B0010001FF000000000
+2A0B:000000C0012001001FF011000900050003000500090011001FF0010009000600
+2A0C:00000000000012482DB42490249024902490249024902490B6D0492000000000
+2A0D:000000C001200100010001000100010007C00100010001000100010009000600
+2A0E:000000C00120010001000100010007C0010007C0010001000100010009000600
+2A0F:000000C001200100010001200140018001000300050009000100010009000600
+2A10:000000C001200100010001000380054005000500038001000100010009000600
+2A11:000000C0012001000110113811541110092007C0010001000100010009000600
+2A12:000000C0012001000100010001C000400140004001C001000100010009000600
+2A13:000000C001200100010001000180004001400040018001000100010009000600
+2A14:000000C001200100010001600190001001100010019001600100010009000600
+2A15:000000C001200100010001000380044005400440038001000100010009000600
+2A16:000000C0012001000100010007C004400540044007C001000100010009000600
+2A17:000000C0012001000100050009001FE009100510016001000100010009000600
+2A18:000000C001200100010009200540038001000380054009200100010009000600
+2A19:000000C001200100010001000380054005400540054001000100010009000600
+2A1A:000000C001200100010001000540054005400540038001000100010009000600
+2A1B:000003E0000000C0012001000100010001000100010001000100010009000600
+2A1C:000000C001200100010001000100010001000100010001000900060000000FC0
+2A1D:0000000000000000000000002008383826C8210826C838382008000000000000
+2A1E:000000000000020E3242320E02000000
+2A1F:000000000018242418001824241C0418
+2A20:0000000000001100088004400220011000880110022004400880110000000000
+2A21:00000000203028242020202020200000
+2A22:000000001028100010107C1010000000
+2A23:000000001028440010107C1010000000
+2A24:000000006498000010107C1010000000
+2A25:000000000000000010107C1010001000
+2A26:000000000000000010107C101000324C
+2A27:0000000000000000000000000000020002000F80020002C000200040008000E0
+2A28:000000000000000010107C10387C1000
+2A29:000000000030380830007C0000000000
+2A2A:000000000000000000007C0010000000
+2A2B:000000000000000040007C0004000000
+2A2C:000000000000000004007C0040000000
+2A2D:000000000000000000000000000003800400088008800BE00880088004000380
+2A2E:000000000000000000000000000003800040022002200FA00220022000400380
+2A2F:00000000000000002214081422000000
+2A30:00000000000010004428102844000000
+2A31:00000000000000004428102844007C00
+2A32:000000000000000044281028447C0000
+2A33:000000000000000000000440028011100AA004400AA011100280044000000000
+2A34:00000000000000000000000003800400091008A0084008A00910040003800000
+2A35:00000000000000000000000001C0002008900510021005100890002001C00000
+2A36:0000000001000280044000000FE010102448228821082288244810100FE00000
+2A37:0000000000001FF020084FE49012A44AA28AA10AA28AA44A90124FE420081FF0
+2A38:0000000000000000000000003E00410088808080BE808080888041003E000000
+2A39:00000100028002800440044008200920111017D02108210840047FFC00000000
+2A3A:00000100028002800440044008200820101017D02008200840047FFC00000000
+2A3B:00000100028002800440044008200C60129011102288244840047FFC00000000
+2A3C:000000000000000002027E0000000000
+2A3D:000000000000000040407E0000000000
+2A3E:000000000008141408000814140C0418
+2A3F:0000000000001C380810081008100810081008100810081008101FF800000000
+2A40:00000000000003C0042008100990099008100810081008100810081000000000
+2A41:0000000000000810081008100810081008100BD008100810042003C000000000
+2A42:000000000FF0000008100810081008100810081008100810042003C000000000
+2A43:000000000FF0000003C004200810081008100810081008100810081000000000
+2A44:00000000000007C0082010101010101010101010101011101290145000000000
+2A45:000000000000145012901110101010101010101010101010082007C000000000
+2A46:00000000002424241800182424240000
+2A47:00000000001824242400242424180000
+2A48:00000024242418003C00182424240000
+2A49:00000018242424003C00242424180000
+2A4A:000000000000000000009292926C0000
+2A4B:000000000000000000006C9292920000
+2A4C:0000000000000FF0042004200420042004200420042004200240018000000000
+2A4D:0000000000000180024004200420042004200420042004200FF0000000000000
+2A4E:0000000000001FF0101017D01450145014501450145014501450145000000000
+2A4F:0000000000001450145014501450145014501450145017D010101FF000000000
+2A50:00000000000000003FFE1004100411441084155412241554108C094807F00000
+2A51:0000000000000100000001000280028004400440082008201010101000000000
+2A52:0000000000000100000010101010082008200440044002800280010000000000
+2A53:0000000000000100028002800440044008200920129012902448244800000000
+2A54:0000000000002448244812901290092008200440044002800280010000000000
+2A55:00000000000000000000024005A005A009900990124812482424242400000000
+2A56:0000000000000000000024242424124812480990099005A005A0024000000000
+2A57:0000000000000000100810101020104010801100120014001800100000000000
+2A58:00000000000000000004000C0014002400440084010402040404080400000000
+2A59:000000000000000000004004200811100AA004400AA011102008400400000000
+2A5A:0000000000000100038003800540054009200920111011102108210800000000
+2A5B:0000000000002108210811101110092009200540054003800380010000000000
+2A5C:000000000000010002800280044004403FF80820101010102008200800000000
+2A5D:000000000000200820081010101008203FF80440044002800280010000000000
+2A5E:00001FF000001FF0000001000280028004400440082008201010101000000000
+2A5F:00000000000001000280028004400440082008201010101000001FF000000000
+2A60:00000000000001000280028004400440082008201010101000001FF000001FF0
+2A61:00000000000000000000000000000000000004400280010000001FF000000000
+2A62:0000000000001FF000001FF00000101010100820082004400440028002800100
+2A63:00000000000010101010082008200440044002800280010000001FF000001FF0
+2A64:000000000000001800680188060818083FF81808060801880068001800000000
+2A65:00000000000030002C00230020C020303FF8203020C023002C00300000000000
+2A66:000000000000007F007F000800000000
+2A67:000000000008007F007F007F00000000
+2A68:00000000000000000000028002803FF802803FF802803FF80280000000000000
+2A69:00000000000000000000054005403FF805403FF805403FF80540000000000000
+2A6A:00000000000020006498000000000000
+2A6B:00000000000008006498004000000000
+2A6C:00000000000000649800FC0064980000
+2A6D:00000000002000649800FC00FC000000
+2A6E:00000000000000000540038001000380054000003FF800003FF8000000000000
+2A6F:00000030488400649800649800000000
+2A70:00000000649800649800FC00FC000000
+2A71:0000000000FC00FC0010107C10100000
+2A72:000000000010107C101000FC00FC0000
+2A73:00000000000000FC00FC009864000000
+2A74:00000000000000000000000000000000000000002BF800002BF8000000000000
+2A75:00000000000000000000000000000000000000007EFC00007EFC000000000000
+2A76:00000000000000000000000000000000000000007BDE00007BDE000000000000
+2A77:00000000000000004800FC00FC004800
+2A78:0000000000000000000000000000124800003FFC00003FFC00003FFC00000000
+2A79:0000000000000000003000C003000C4010A00C40030000C00030000000000000
+2A7A:000000000000000018000600018004600A100460018006001800000000000000
+2A7B:1800240008000800003008C003000C0010000C00030000C00030000000000000
+2A7C:0030004800100010180006100180006000100060018006001800000000000000
+2A7D:0000000000000000000000600180060008000600018008600600018000600000
+2A7E:000000000000000000000C00030000C0002000C003000C2000C003000C000000
+2A7F:0000000000000000000000600180060008400600018008600600018000600000
+2A80:000000000000000000000C00030000C0082000C003000C2000C003000C000000
+2A81:0000000000000000040000600180060008000600018008600600018000600000
+2A82:000000000000000000400C00030000C0002000C003000C2000C003000C000000
+2A83:0000000000000020000000600180060008000600018008600600018000600000
+2A84:000000000000080000000C00030000C0002000C003000C2000C003000C000000
+2A85:000000000000006001800600080006000180006000000000071008E0071008E0
+2A86:0000000000000C00030000C0002000C003000C00000000000E2011C00E2011C0
+2A87:00000000000000000060018006000800060001800060004000800FE002000400
+2A88:00000000000000000C00030000C0002000C003000C00040002000FE000800040
+2A89:0000006001800600080006000180006000100020075008E007100AE004000800
+2A8A:00000C00030000C0002000C003000C00002000400EA011C00E2015C008001000
+2A8B:00186080601800FC00FC006018041860
+2A8C:00601804186000FC00FC001860806018
+2A8D:000000000000006001800600080006000180006000000000071008E000000FF0
+2A8E:0000000000000C00030000C0002000C003000C00000000000E2011C000001FE0
+2A8F:00186080601800649800601804186000
+2A90:00601804186000986400186080601800
+2A91:000C3040300C6018041860007C007C00
+2A92:0060180418600C3040300C007C007C00
+2A93:000C3040300C40300C60180418620C30
+2A94:00300C020C30020C300618201846300C
+2A95:0000000000000000000000600180060008600180060008000600018000600000
+2A96:000000000000000000000C00030000C00C20030000C0002000C003000C000000
+2A97:0000000000000000000000600180060008600180060008400600018000600000
+2A98:000000000000000000000C00030000C00C20030000C0042000C003000C000000
+2A99:00000000000000000FE000000FE0000000600180060008000600018000600000
+2A9A:00000000000000000FE000000FE000000C00030000C0002000C003000C000000
+2A9B:0000000000600180060008600180060008600180060008000600018000600000
+2A9C:000000000C00030000C00C20030000C00C20030000C0002000C003000C000000
+2A9D:00000000000000000000071008E00000003000C003000400030000C000300000
+2A9E:0000000000000000071008E0000000000C00030000C0002000C003000C000000
+2A9F:00000000071008E00000003000C003000400030000C0003000000FF000000FF0
+2AA0:0000000008E0071000000C00030000C0002000C003000C0000000FF000000FF0
+2AA1:00000000000000000000003000C003300CC011000CC0033000C0003000000000
+2AA2:0000000000000000000018000600198006600110066019800600180000000000
+2AA3:0000000000000000018C063018C0210018C00630018C00003FFC000000000000
+2AA4:0000000000000000060C01B000E0011000E001B0060C00000000000000000000
+2AA5:0000000000000000400430180C6002800C603018400400000000000000000000
+2AA6:000000000000000000000000000000C003200C1010100C10032000C000000000
+2AA7:0000000000000000000000000000060009801060101010600980060000000000
+2AA8:0000000000000000000000C003200C1010100C10032010C00C00030000C00000
+2AA9:0000000000000000000006000980106010101060098006100060018006000000
+2AAA:00000000000000000000003000C003000C001FF00C00030000C0003000000000
+2AAB:0000000000000000000018000600018000601FF0006001800600180000000000
+2AAC:000000000000003000C003000C001FF00C00030000C0003000001FF000000000
+2AAD:00000000000018000600018000601FF0006001800600180000001FF000000000
+2AAE:000000000000000000000000038004403C7800003FF800003FF8000000000000
+2AAF:0000000000000010002000C003001C00030000C00020001000001FF000000000
+2AB0:00000000000008000400030000C0003800C003000400080000000FF800000000
+2AB1:0000000000000010002000C003001C00030000C00020005000801FF002000400
+2AB2:00000000000010000800060001800070018006000800108001001FF004000800
+2AB3:00000010002000C003001C00030000C00020001000001FF000001FF000000000
+2AB4:000010000800060001800070018006000800100000001FF000001FF000000000
+2AB5:00000010002000C003001C00030000C00020003000401FF001001FF004000800
+2AB6:000010000800060001800070018006000800104000801FF002001FF008001000
+2AB7:0010002000C003001C00030000C000200010000007900860071008E000000000
+2AB8:10000800060001800070018006000800100000000E2011C00E2011C000000000
+2AB9:0010002000C003001C00030000C0002000500040079008E0071009E002000200
+2ABA:10000800060001800070018006000800108000800F2011C00E2013C004000400
+2ABB:0000000000000042008403180C6073800C600318008400420000000000000000
+2ABC:0000000000004200210018C0063001CE063018C0210042000000000000000000
+2ABD:0000000000000000000000000FF81000200026002600200010000FF800000000
+2ABE:0000000000000000000000003FE00010000800C800C8000800103FE000000000
+2ABF:0000003E4040403E0008083E08080000
+2AC0:0000007C0202027C0010107C10100000
+2AC1:0000003E4040403E0022140814220000
+2AC2:0000007C0202027C0044281028440000
+2AC3:000000001818003E4040403E007E0000
+2AC4:000000003030007C0202027C007E0000
+2AC5:00000000003E4040403E007E007E0000
+2AC6:00000000007C0202027C007E007E0000
+2AC7:00000000000000000FF81000200020002000200010000FF80000071008E00000
+2AC8:00000000000000003FE00010000800080008000800103FE000000E2011C00000
+2AC9:00000000003E4040403E00324C324C00
+2ACA:00000000007C0202027C00324C324C00
+2ACB:000000003E4040403E00047E087E1000
+2ACC:000000007C0202027C00047E087E1000
+2ACD:00000000000000007FFE400040004000400040004000400040007F0000000000
+2ACE:00000000000000007FFE0002000200020002000200020002000200FE00000000
+2ACF:00000000000000000000000007F008101010101010101010081007F000000000
+2AD0:0000000000000000000000001FC01020101010101010101010201FC000000000
+2AD1:000000000000000007F008101010101010101010081007F000001FF000000000
+2AD2:00000000000000001FC01020101010101010101010201FC000001FF000000000
+2AD3:0000003E4040403E007C0202027C0000
+2AD4:0000007C0202027C003E4040403E0000
+2AD5:0000003E4040403E003E4040403E0000
+2AD6:0000007C0202027C007C0202027C0000
+2AD7:0000000000000000000000000000000000007C7C0280028002807C7C00000000
+2AD8:0000000000000000000000000000000000007C7C02800FE002807C7C00000000
+2AD9:000000000000000007C009201110111011101110111011101110111000000000
+2ADA:000000000FE0010007C009201110111011101110111011101110111000000000
+2ADB:000000000100010007C009201110111011101110111011101110111001000100
+2ADC:000000000000000001000110012001400180111013101510092017C000000000
+2ADD:000000000000000001000100010001000100111011101110092007C000000000
+2ADE:0000000000040404043C040404040000
+2ADF:000000000000000000000000000000001FF00100010001000000000000000000
+2AE0:000000000000000000000000000000000100010001001FF00000000000000000
+2AE1:000000000000010001000138014001300108017001003FF80000000000000000
+2AE2:00000000000000000000200020003FF020003FF020003FF02000200000000000
+2AE3:0000000000000000000000140014001400143FF4001400140014001400000000
+2AE4:000000000000000000000008000800081FF800081FF800080008000800000000
+2AE5:000000000000000000000014001400143FF400143FF400140014001400000000
+2AE6:0000000000000000000028002800280028003FFC280028002800280000000000
+2AE7:0000000000000000000000001FF000001FF00100010001000000000000000000
+2AE8:0000000000000000000000000100010001001FF000001FF00000000000000000
+2AE9:0000000000000100010001001FF000001FF00100010001000000000000000000
+2AEA:00000000000000001FF002800280028002800280028002800280028000000000
+2AEB:00000000000000000280028002800280028002800280028002801FF000000000
+2AEC:000000000000000000000000000000001FF800081FF800080008000000000000
+2AED:000000000000000000000000000000001FF810001FF810001000000000000000
+2AEE:00000000101010503010181410100000
+2AEF:00000000384444381010101010100000
+2AF0:00000000101010101010384444380000
+2AF1:000000007C1010101010384444380000
+2AF2:000000002828282828FE282828280000
+2AF3:00000000000000000240024002400240024007500AE002400240024000000000
+2AF4:0000000000000000092009200920092009200920092009200920092000000000
+2AF5:0000000000000000092009200920092009203FF8092009200920092000000000
+2AF6:00000000000000100000100000100000
+2AF7:0000000000000018006001980660199822201998066001980060001800000000
+2AF8:00000000000030000C0033000CC03330088833300CC033000C00300000000000
+2AF9:0000000000600180060008000600018008600600018008600600018000600000
+2AFA:000000000C00030000C0002000C003000C2000C003000C2000C003000C000000
+2AFB:0000000000000000024802480490049009200920124012402480248000000000
+2AFC:0000000000000000000009200920092009200920092009200920092009200000
+2AFD:0000000000000000009000900120012002400240048004800900090000000000
+2AFE:00000000000000003828282828380000
+2AFF:00000000382828282828282828380000
+2B00:00000000000001F8010800880108022804580880110022001400080000000000
+2B01:0000000000003F00210022002100288034400220011000880050002000000000
+2B02:000000000000080014002200110008800458022801080088010801F800000000
+2B03:00000000000000200050008801100220344028802100220021003F0000000000
+2B04:000000000000000000000000081018182FF440022FF418180810000000000000
+2B05:000000000000000000000000080018003FFC7FFC3FFC18000800000000000000
+2B06:000010387CFE38383838383838380000
+2B07:00003838383838383838FE7C38100000
+2B08:00000000000001F801F800F801F803F807D80F801F003E001C00080000000000
+2B09:0000000000003F003F003E003F003F8037C003E001F000F80070002000000000
+2B0A:00000000000008001C003E001F000F8007D803F801F800F801F801F800000000
+2B0B:0000000000000020007000F801F003E037C03F803F003E003F003F0000000000
+2B0C:000000000000000000000000081018183FFC7FFE3FFC18180810000000000000
+2B0D:000010387CFE38383838FE7C38100000
+2B0E:000000000000000000000000000000000000FFF80008002A001C000800000000
+2B0F:000000000000000000000008001C002A0008FFF8000000000000000000000000
+2B10:0000000000000000000000000000000000001FFF100054003800100000000000
+2B11:0000000000000000000010003800540010001FFF000000000000000000000000
+2B12:000000000000000000001FF81FF81FF81FF81FF810081008100810081FF80000
+2B13:000000000000000000001FF810081008100810081FF81FF81FF81FF81FF80000
+2B14:000000000000000000001FF81FF817F813F811F810F81078103810181FF80000
+2B15:000000000000000000001FF818081C081E081F081F881FC81FE81FF81FF80000
+2B16:000000000000000000000180034007200F101F081F080F100720034001800000
+2B17:00000000000000000000018002C004E008F010F810F808F004E002C001800000
+2B18:00000000000000000000018003C007E00FF01FF8100808100420024001800000
+2B19:00000000000000000000018002400420081010081FF80FF007E003C001800000
+2B1A:0000000000002AA80000200800002008000020080000200800002AA800000000
+2B1B:00007FFE7FFE7FFE7FFE7FFE7FFE7FFE7FFE7FFE7FFE7FFE7FFE7FFE7FFE0000
+2B1C:00007FFE4002400240024002400240024002400240024002400240027FFE0000
+2B1D:00000000000000003C3C3C3C00000000
+2B1E:00000000000000003C24243C00000000
+2B1F:000000000000018003C007E00FF01FF83FFC1FF81FF80FF00FF007E000000000
+2B20:000000000000018002400420081010082004100810080810081007E000000000
+2B21:0000000000000000010006C0183020082008200820082008183006C001000000
+2B22:0000000000000000010007C01FF03FF83FF83FF83FF83FF81FF007C001000000
+2B23:000000000000000007E00FF01FF83FFC7FFE7FFE3FFC1FF80FF007E000000000
+2B24:0000000000000FF01FF83FFC7FFE7FFE7FFE7FFE7FFE7FFE7FFE3FFC1FF80FF0
+2B25:0000000000000010387CFE7C38100000
+2B26:00000000000000102844824428100000
+2B27:0000001038387C7CFE7C7C3838100000
+2B28:00000010282844448244442828100000
+2B29:00000000000010387C38100000000000
+2B2A:000000000000001038387C3838100000
+2B2B:00000000000000102828442828100000
+2B2C:000000000000000000000000000000000FE07FFCFFFEFFFE7FFC0FE000000000
+2B2D:000000000000000000000000000000000FE0701C80028002701C0FE000000000
+2B2E:00183C3C3C7E7E7E7E7E3C3C3C180000
+2B2F:00182424244242424242242424180000
+2B30:000000000000000000000000000010E021107FFF211010E00000000000000000
+2B31:0000100020007FFE20001000100020007FFE20001000100020007FFE20001000
+2B32:000000000000000000000000000010E021507FFF215010E00000000000000000
+2B33:0000000000000000000000000000111022A87AAF244010000000000000000000
+2B34:0000000000000000000000000000142028207FFF282014200000000000000000
+2B35:0000000000000000000000000000145028507FFF285014500000000000000000
+2B36:0000000000000000000000000000140228027FFE280214020000000000000000
+2B37:0000000000000000000000000000140228047ED8280414020000000000000000
+2B38:0000000000000000000000000000100020006AAA200010000000000000000000
+2B39:0000000000000000000000000000104220447FF8204410420000000000000000
+2B3A:000000000000000000000000000010A220A47FF820A410A20000000000000000
+2B3B:0000000000000000000000000000140228047FF8280414020000000000000000
+2B3C:0000000000000000000000000000144228447FF8284414420000000000000000
+2B3D:000000000000000000000000000014A228A47FF828A414A20000000000000000
+2B3E:0000000000000000000000000000144828307FFF283014480000000000000000
+2B3F:0000000000000000000000000000103C20427F81200010000000000000000000
+2B40:0000000000000000000001F8000011F820007FFF200010000000000000000000
+2B41:00000000000000000000001C022211C020007FFF200010000000000000000000
+2B42:0000000000000000000000000000100020007FFF201C122201C0001C022201C0
+2B43:0000000000000000000070000C00030800840FFE008403080C00700000000000
+2B44:00000000000000007E0001000080004800447FFE00440048008001007E000000
+2B45:0000000000000000040008001FFE20007FFE80007FFE20001FFE080004000000
+2B46:000000000000000000400020FFF00008FFFC0002FFFC0008FFF0002000400000
+2B47:000000000000000000000380444038080004FFFE000400080000000000000000
+2B48:000000000000000000000000000000080004FFFE038444483800038044403800
+2B49:0000000000000000000001C00222101C20007FFF200010000000000000000000
+2B4A:0000000000000000000000000000100020007FFF21C01222001C01C00222001C
+2B4B:0000000000000000000000000000100020007FFF2000101C022201C000000000
+2B4C:000000000000000000000000000000080004FFFE000403884440380000000000
+2B4D:00007FFE618E7DB6618E6FB6618E7FFE7FFE6D8E6DB661B67DB67D8E7FFE0000
+2B4E:00007FFE618E7DB6618E6FB6618E7FFE7FFE6D866DBE618E7DBE7D867FFE0000
+2B4F:00007FFE618E7DB6618E6FB6618E7FFE7FFE6D866DBE618E7DBE7DBE7FFE0000
+2B50:000001000100028002807C7C20081010082004400820111026C8383800000000
+2B51:0000000000000100038003803FF81FF00FE00FE01EF03C783018000000000000
+2B52:0000000000000100028002803C7810100820092012902C683018000000000000
+2B53:00000000008003C00FE01FF01FF81FFC1FFC1FF81FF00FE003C0008000000000
+2B54:00000000008003400C201010100810041004100810100C200340008000000000
+2B55:000007C00FE018303018600C600C600C600C600C301818300FE007C000000000
+2B56:0000000000000FE01FF0301867CC682C682C67CC30181FF00FE0000000000000
+2B57:000007C00FE018303018638C644C644C644C638C301818300FE007C000000000
+2B58:000000000000000003800FE00C601830183018300C600FE00380000000000000
+2B59:000007C00FE018303838644C628C610C628C644C383818300FE007C000000000
+2B5A:00007FFE618E7DB6618E6FB6618E7FFE7FFE61866FB661867DB661B67FFE0000
+2B5B:00007FFE618E7DB6618E6FB6618E7FFE7FFE618E6FB6618E7DB6618E7FFE0000
+2B5C:00007FFE618E7DB6618E6FB6618E7FFE7FFE61C66FBE61BE7DBE61C67FFE0000
+2B5D:00007FFE618E7DB6618E6FB6618E7FFE7FFE618E6FB661B67DB6618E7FFE0000
+2B5E:00007FFE618E7DB6618E6FB6618E7FFE7FFE61866FBE618E7DBE61867FFE0000
+2B5F:00007FFE618E7DB6618E6FB6618E7FFE7FFE61866FBE618E7DBE61BE7FFE0000
+2B60:00007FFE618E7DB6618E6FB6618E7FFE7FFE73CE6FB663B66DB673CE7FFE0000
+2B61:00007FFE618E7DB6618E6FB6618E7FFE7FFE73EE6FCE63EE6DEE73C67FFE0000
+2B62:00007FFE618E7DB6618E6FB6618E7FFE7FFE73866FF663866DBE73867FFE0000
+2B63:00007FFE618E7DB6618E6FB6618E7FFE7FFE738E6FF663C66DF6738E7FFE0000
+2B64:00007FFE618E7DB6618E6FB6618E7FFE7FFE73B66FB663866DF673F67FFE0000
+2B65:00007FFE618E7DB6618E6FB6618E7FFE7FFE73866FBE63866DF673867FFE0000
+2B66:00007FFE618E7DB6618E6FB6618E7FFE7FFE73CE6FBE638E6DB673CE7FFE0000
+2B67:00007FFE618E7DB6618E6FB6618E7FFE7FFE73866FF663EE6DDE73DE7FFE0000
+2B68:00007FFE618E7DB6618E6FB6618E7FFE7FFE73CE6FB663CE6DB673CE7FFE0000
+2B69:00007FFE618E7DB6618E6FB6618E7FFE7FFE73CE6FB663C66DF673CE7FFE0000
+2B6A:00007FFE618E7DB6618E6FB6618E7FFE7FFE73866FB663866DB673B67FFE0000
+2B6B:00007FFE618E7DB6618E6FB6618E7FFE7FFE738E6FB6638E6DB6738E7FFE0000
+2B6C:00007FFE618E7DB6618E6FB6618E7FFE7FFE73C66FBE63BE6DBE73C67FFE0000
+2B6D:00007FFE618E7DB6618E6FB6618E7FFE7FFE738E6FB663B66DB6738E7FFE0000
+2B6E:00007FFE618E7DB6618E6FB6618E7FFE7FFE73866FBE638E6DBE73867FFE0000
+2B6F:00007FFE618E7DB6618E6FB6618E7FFE7FFE73866FBE638E6DBE73BE7FFE0000
+2B70:00007FFE618E7DB6618E6FB6618E7FFE7FFE61CE7DB67BB677B677CE7FFE0000
+2B71:00007FFE618E7DB6618E6FB6618E7FFE7FFE61EE7DCE7BEE77EE77C67FFE0000
+2B72:00007FFE618E7DB6618E6FB6618E7FFE7FFE61867DF67B8677BE77867FFE0000
+2B73:00007FFE618E7DB6618E6FB6618E7FFE7FFE618E7DF67BC677F6778E7FFE0000
+2B74:00007FFE618E7DB6618E6FB6618E7FFE7FFE61B67DB67B8677F677F67FFE0000
+2B75:00007FFE618E7DB6618E6FB6618E7FFE7FFE61867DBE7B8677F677867FFE0000
+2B76:00007FFE618E7DB6618E6FB6618E7FFE7FFE61CE7DBE7B8E77B677CE7FFE0000
+2B77:00007FFE618E7DB6618E6FB6618E7FFE7FFE61867DF67BEE77DE77DE7FFE0000
+2B78:00007FFE618E7DB6618E6FB6618E7FFE7FFE61CE7DB67BCE77B677CE7FFE0000
+2B79:00007FFE618E7DB6618E6FB6618E7FFE7FFE61CE7DB67BC677F677CE7FFE0000
+2B7A:00007FFE618E7DB6618E6FB6618E7FFE7FFE61867DB67B8677B677B67FFE0000
+2B7B:00007FFE618E7DB6618E6FB6618E7FFE7FFE618E7DB67B8E77B6778E7FFE0000
+2B7C:00007FFE618E7DB6618E6FB6618E7FFE7FFE61C67DBE7BBE77BE77C67FFE0000
+2B7D:00007FFE618E7DB6618E6FB6618E7FFE7FFE618E7DB67BB677B6778E7FFE0000
+2B7E:00007FFE618E7DB6618E6FB6618E7FFE7FFE61867DBE7B8E77BE77867FFE0000
+2B7F:00007FFE618E7DB6618E6FB6618E7FFE7FFE61867DBE7B8E77BE77BE7FFE0000
+2B80:00007FFE618E7DB6618E6FB6618E7FFE7FFE73CE6DB673B66DB673CE7FFE0000
+2B81:00007FFE618E7DB6618E6FB6618E7FFE7FFE73EE6DCE73EE6DEE73C67FFE0000
+2B82:00007FFE618E7DB6618E6FB6618E7FFE7FFE73866DF673866DBE73867FFE0000
+2B83:00007FFE618E7DB6618E6FB6618E7FFE7FFE738E6DF673C66DF6738E7FFE0000
+2B84:00007FFE618E7DB6618E6FB6618E7FFE7FFE73B66DB673866DF673F67FFE0000
+2B85:00007FFE618E7DB6618E6FB6618E7FFE7FFE73866DBE73866DF673867FFE0000
+2B86:00007FFE618E7DB6618E6FB6618E7FFE7FFE73CE6DBE738E6DB673CE7FFE0000
+2B87:00007FFE618E7DB6618E6FB6618E7FFE7FFE73866DF673EE6DDE73DE7FFE0000
+2B88:00007FFE618E7DB6618E6FB6618E7FFE7FFE73CE6DB673CE6DB673CE7FFE0000
+2B89:00007FFE618E7DB6618E6FB6618E7FFE7FFE73CE6DB673C66DF673CE7FFE0000
+2B8A:00007FFE618E7DB6618E6FB6618E7FFE7FFE73866DB673866DB673B67FFE0000
+2B8B:00007FFE618E7DB6618E6FB6618E7FFE7FFE738E6DB6738E6DB6738E7FFE0000
+2B8C:00007FFE618E7DB6618E6FB6618E7FFE7FFE73C66DBE73BE6DBE73C67FFE0000
+2B8D:00007FFE618E7DB6618E6FB6618E7FFE7FFE738E6DB673B66DB6738E7FFE0000
+2B8E:00007FFE618E7DB6618E6FB6618E7FFE7FFE73866DBE738E6DBE73867FFE0000
+2B8F:00007FFE618E7DB6618E6FB6618E7FFE7FFE73866DBE738E6DBE73BE7FFE0000
+2B90:00007FFE618E7DB6618E6FB6618E7FFE7FFE73CE6DB671B67DB673CE7FFE0000
+2B91:00007FFE618E7DB6618E6FB6618E7FFE7FFE73EE6DCE71EE7DEE73C67FFE0000
+2B92:00007FFE618E7DB6618E6FB6618E7FFE7FFE73866DF671867DBE73867FFE0000
+2B93:00007FFE618E7DB6618E6FB6618E7FFE7FFE738E6DF671C67DF6738E7FFE0000
+2B94:00007FFE618E7DB6618E6FB6618E7FFE7FFE73B66DB671867DF673F67FFE0000
+2B95:00007FFE618E7DB6618E6FB6618E7FFE7FFE73866DBE71867DF673867FFE0000
+2B96:00007FFE618E7DB6618E6FB6618E7FFE7FFE73CE6DBE718E7DB673CE7FFE0000
+2B97:00007FFE618E7DB6618E6FB6618E7FFE7FFE73866DF671EE7DDE73DE7FFE0000
+2B98:00007FFE618E7DB6618E6FB6618E7FFE7FFE73CE6DB671CE7DB673CE7FFE0000
+2B99:00007FFE618E7DB6618E6FB6618E7FFE7FFE73CE6DB671C67DF673CE7FFE0000
+2B9A:00007FFE618E7DB6618E6FB6618E7FFE7FFE73866DB671867DB673B67FFE0000
+2B9B:00007FFE618E7DB6618E6FB6618E7FFE7FFE738E6DB6718E7DB6738E7FFE0000
+2B9C:00007FFE618E7DB6618E6FB6618E7FFE7FFE73C66DBE71BE7DBE73C67FFE0000
+2B9D:00007FFE618E7DB6618E6FB6618E7FFE7FFE738E6DB671B67DB6738E7FFE0000
+2B9E:00007FFE618E7DB6618E6FB6618E7FFE7FFE73866DBE718E7DBE73867FFE0000
+2B9F:00007FFE618E7DB6618E6FB6618E7FFE7FFE73866DBE718E7DBE73BE7FFE0000
+2BA0:00007FFE618E7DB6618E6FB6618E7FFE7FFE61CE6DB661B66DB66DCE7FFE0000
+2BA1:00007FFE618E7DB6618E6FB6618E7FFE7FFE61EE6DCE61EE6DEE6DC67FFE0000
+2BA2:00007FFE618E7DB6618E6FB6618E7FFE7FFE61866DF661866DBE6D867FFE0000
+2BA3:00007FFE618E7DB6618E6FB6618E7FFE7FFE618E6DF661C66DF66D8E7FFE0000
+2BA4:00007FFE618E7DB6618E6FB6618E7FFE7FFE61B66DB661866DF66DF67FFE0000
+2BA5:00007FFE618E7DB6618E6FB6618E7FFE7FFE61866DBE61866DF66D867FFE0000
+2BA6:00007FFE618E7DB6618E6FB6618E7FFE7FFE61CE6DBE618E6DB66DCE7FFE0000
+2BA7:00007FFE618E7DB6618E6FB6618E7FFE7FFE61866DF661EE6DDE6DDE7FFE0000
+2BA8:00007FFE618E7DB6618E6FB6618E7FFE7FFE61CE6DB661CE6DB66DCE7FFE0000
+2BA9:00007FFE618E7DB6618E6FB6618E7FFE7FFE61CE6DB661C66DF66DCE7FFE0000
+2BAA:00007FFE618E7DB6618E6FB6618E7FFE7FFE61866DB661866DB66DB67FFE0000
+2BAB:00007FFE618E7DB6618E6FB6618E7FFE7FFE618E6DB6618E6DB66D8E7FFE0000
+2BAC:00007FFE618E7DB6618E6FB6618E7FFE7FFE61C66DBE61BE6DBE6DC67FFE0000
+2BAD:00007FFE618E7DB6618E6FB6618E7FFE7FFE618E6DB661B66DB66D8E7FFE0000
+2BAE:00007FFE618E7DB6618E6FB6618E7FFE7FFE61866DBE618E6DBE6D867FFE0000
+2BAF:00007FFE618E7DB6618E6FB6618E7FFE7FFE61866DBE618E6DBE6DBE7FFE0000
+2BB0:00007FFE618E7DB6618E6FB6618E7FFE7FFE63CE6DB663B66DB663CE7FFE0000
+2BB1:00007FFE618E7DB6618E6FB6618E7FFE7FFE63EE6DCE63EE6DEE63C67FFE0000
+2BB2:00007FFE618E7DB6618E6FB6618E7FFE7FFE63866DF663866DBE63867FFE0000
+2BB3:00007FFE618E7DB6618E6FB6618E7FFE7FFE638E6DF663C66DF6638E7FFE0000
+2BB4:00007FFE618E7DB6618E6FB6618E7FFE7FFE63B66DB663866DF663F67FFE0000
+2BB5:00007FFE618E7DB6618E6FB6618E7FFE7FFE63866DBE63866DF663867FFE0000
+2BB6:00007FFE618E7DB6618E6FB6618E7FFE7FFE63CE6DBE638E6DB663CE7FFE0000
+2BB7:00007FFE618E7DB6618E6FB6618E7FFE7FFE63866DF663EE6DDE63DE7FFE0000
+2BB8:00007FFE618E7DB6618E6FB6618E7FFE7FFE63CE6DB663CE6DB663CE7FFE0000
+2BB9:00007FFE618E7DB6618E6FB6618E7FFE7FFE63CE6DB663C66DF663CE7FFE0000
+2BBA:00007FFE618E7DB6618E6FB6618E7FFE7FFE63866DB663866DB663B67FFE0000
+2BBB:00007FFE618E7DB6618E6FB6618E7FFE7FFE638E6DB6638E6DB6638E7FFE0000
+2BBC:00007FFE618E7DB6618E6FB6618E7FFE7FFE63C66DBE63BE6DBE63C67FFE0000
+2BBD:00007FFE618E7DB6618E6FB6618E7FFE7FFE638E6DB663B66DB6638E7FFE0000
+2BBE:00007FFE618E7DB6618E6FB6618E7FFE7FFE63866DBE638E6DBE63867FFE0000
+2BBF:00007FFE618E7DB6618E6FB6618E7FFE7FFE63866DBE638E6DBE63BE7FFE0000
+2BC0:00007FFE618E7DB6618E6FB6618E7FFE7FFE71CE6FB66FB66FB671CE7FFE0000
+2BC1:00007FFE618E7DB6618E6FB6618E7FFE7FFE71EE6FCE6FEE6FEE71C67FFE0000
+2BC2:00007FFE618E7DB6618E6FB6618E7FFE7FFE71866FF66F866FBE71867FFE0000
+2BC3:00007FFE618E7DB6618E6FB6618E7FFE7FFE718E6FF66FC66FF6718E7FFE0000
+2BC4:00007FFE618E7DB6618E6FB6618E7FFE7FFE71B66FB66F866FF671F67FFE0000
+2BC5:00007FFE618E7DB6618E6FB6618E7FFE7FFE71866FBE6F866FF671867FFE0000
+2BC6:00007FFE618E7DB6618E6FB6618E7FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000
+2BC7:00007FFE618E7DB6618E6FB6618E7FFE7FFE71866FF66FEE6FDE71DE7FFE0000
+2BC8:00007FFE618E7DB6618E6FB6618E7FFE7FFE71CE6FB66FCE6FB671CE7FFE0000
+2BC9:00007FFE618E7DB6618E6FB6618E7FFE7FFE71CE6FB66FC66FF671CE7FFE0000
+2BCA:00007FFE618E7DB6618E6FB6618E7FFE7FFE71866FB66F866FB671B67FFE0000
+2BCB:00007FFE618E7DB6618E6FB6618E7FFE7FFE718E6FB66F8E6FB6718E7FFE0000
+2BCC:00007FFE618E7DB6618E6FB6618E7FFE7FFE71C66FBE6FBE6FBE71C67FFE0000
+2BCD:00007FFE618E7DB6618E6FB6618E7FFE7FFE718E6FB66FB66FB6718E7FFE0000
+2BCE:00007FFE618E7DB6618E6FB6618E7FFE7FFE71866FBE6F8E6FBE71867FFE0000
+2BCF:00007FFE618E7DB6618E6FB6618E7FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+2BD0:00007FFE618E7DB6618E6FB6618E7FFE7FFE63CE6DB66DB66DB663CE7FFE0000
+2BD1:00007FFE618E7DB6618E6FB6618E7FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000
+2BD2:00007FFE618E7DB6618E6FB6618E7FFE7FFE63866DF66D866DBE63867FFE0000
+2BD3:00007FFE618E7DB6618E6FB6618E7FFE7FFE638E6DF66DC66DF6638E7FFE0000
+2BD4:00007FFE618E7DB6618E6FB6618E7FFE7FFE63B66DB66D866DF663F67FFE0000
+2BD5:00007FFE618E7DB6618E6FB6618E7FFE7FFE63866DBE6D866DF663867FFE0000
+2BD6:00007FFE618E7DB6618E6FB6618E7FFE7FFE63CE6DBE6D8E6DB663CE7FFE0000
+2BD7:00007FFE618E7DB6618E6FB6618E7FFE7FFE63866DF66DEE6DDE63DE7FFE0000
+2BD8:00007FFE618E7DB6618E6FB6618E7FFE7FFE63CE6DB66DCE6DB663CE7FFE0000
+2BD9:00007FFE618E7DB6618E6FB6618E7FFE7FFE63CE6DB66DC66DF663CE7FFE0000
+2BDA:00007FFE618E7DB6618E6FB6618E7FFE7FFE63866DB66D866DB663B67FFE0000
+2BDB:00007FFE618E7DB6618E6FB6618E7FFE7FFE638E6DB66D8E6DB6638E7FFE0000
+2BDC:00007FFE618E7DB6618E6FB6618E7FFE7FFE63C66DBE6DBE6DBE63C67FFE0000
+2BDD:00007FFE618E7DB6618E6FB6618E7FFE7FFE638E6DB66DB66DB6638E7FFE0000
+2BDE:00007FFE618E7DB6618E6FB6618E7FFE7FFE63866DBE6D8E6DBE63867FFE0000
+2BDF:00007FFE618E7DB6618E6FB6618E7FFE7FFE63866DBE6D8E6DBE63BE7FFE0000
+2BE0:00007FFE618E7DB6618E6FB6618E7FFE7FFE61CE6FB663B66FB661CE7FFE0000
+2BE1:00007FFE618E7DB6618E6FB6618E7FFE7FFE61EE6FCE63EE6FEE61C67FFE0000
+2BE2:00007FFE618E7DB6618E6FB6618E7FFE7FFE61866FF663866FBE61867FFE0000
+2BE3:00007FFE618E7DB6618E6FB6618E7FFE7FFE618E6FF663C66FF6618E7FFE0000
+2BE4:00007FFE618E7DB6618E6FB6618E7FFE7FFE61B66FB663866FF661F67FFE0000
+2BE5:00007FFE618E7DB6618E6FB6618E7FFE7FFE61866FBE63866FF661867FFE0000
+2BE6:00007FFE618E7DB6618E6FB6618E7FFE7FFE61CE6FBE638E6FB661CE7FFE0000
+2BE7:00007FFE618E7DB6618E6FB6618E7FFE7FFE61866FF663EE6FDE61DE7FFE0000
+2BE8:00007FFE618E7DB6618E6FB6618E7FFE7FFE61CE6FB663CE6FB661CE7FFE0000
+2BE9:00007FFE618E7DB6618E6FB6618E7FFE7FFE61CE6FB663C66FF661CE7FFE0000
+2BEA:00007FFE618E7DB6618E6FB6618E7FFE7FFE61866FB663866FB661B67FFE0000
+2BEB:00007FFE618E7DB6618E6FB6618E7FFE7FFE618E6FB6638E6FB6618E7FFE0000
+2BEC:00007FFE618E7DB6618E6FB6618E7FFE7FFE61C66FBE63BE6FBE61C67FFE0000
+2BED:00007FFE618E7DB6618E6FB6618E7FFE7FFE618E6FB663B66FB6618E7FFE0000
+2BEE:00007FFE618E7DB6618E6FB6618E7FFE7FFE61866FBE638E6FBE61867FFE0000
+2BEF:00007FFE618E7DB6618E6FB6618E7FFE7FFE61866FBE638E6FBE61BE7FFE0000
+2BF0:00007FFE618E7DB6618E6FB6618E7FFE7FFE61CE6FB663B66FB66FCE7FFE0000
+2BF1:00007FFE618E7DB6618E6FB6618E7FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000
+2BF2:00007FFE618E7DB6618E6FB6618E7FFE7FFE61866FF663866FBE6F867FFE0000
+2BF3:00007FFE618E7DB6618E6FB6618E7FFE7FFE618E6FF663C66FF66F8E7FFE0000
+2BF4:00007FFE618E7DB6618E6FB6618E7FFE7FFE61B66FB663866FF66FF67FFE0000
+2BF5:00007FFE618E7DB6618E6FB6618E7FFE7FFE61866FBE63866FF66F867FFE0000
+2BF6:00007FFE618E7DB6618E6FB6618E7FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+2BF7:00007FFE618E7DB6618E6FB6618E7FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+2BF8:00007FFE618E7DB6618E6FB6618E7FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+2BF9:00007FFE618E7DB6618E6FB6618E7FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+2BFA:00007FFE618E7DB6618E6FB6618E7FFE7FFE61866FB663866FB66FB67FFE0000
+2BFB:00007FFE618E7DB6618E6FB6618E7FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+2BFC:00007FFE618E7DB6618E6FB6618E7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+2BFD:00007FFE618E7DB6618E6FB6618E7FFE7FFE618E6FB663B66FB66F8E7FFE0000
+2BFE:00007FFE618E7DB6618E6FB6618E7FFE7FFE61866FBE638E6FBE6F867FFE0000
+2BFF:00007FFE618E7DB6618E6FB6618E7FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+2C00:00000000101010107C54541010100000
+2C01:0000000092929292FE80808080FE0000
+2C02:0000000044AA6C284444444444380000
+2C03:000000006090907020204C52928C0000
+2C04:00000000384444444444286CAA440000
+2C05:000000003844041C041C040444380000
+2C06:000000000000824428286C92926C0000
+2C07:000000003844824438FE926428100000
+2C08:000000000020508888FF8D8D55220000
+2C09:000000007C6C92927C10101010380000
+2C0A:000000007C6C92926C28444482FE0000
+2C0B:00000000FE8244285482828244380000
+2C0C:00000000626565669696969991000000
+2C0D:000000002020203C04043C2020200000
+2C0E:0000000038444444447CAAAAAA440000
+2C0F:00000000000000000FF812A412A40C98008003E0077009480948063000000000
+2C10:000000003C222222FCA0A02020200000
+2C11:000000001C221E020202021E221C0000
+2C12:000000003E2A2A2AE420202020200000
+2C13:00000000404040407C424242427C0000
+2C14:00000000384482828254284482FE0000
+2C15:00000000FEAAAAAAAAAAAAAAAA440000
+2C16:0000000048B46C242724246CB4480000
+2C17:00000000101038549292929254381010
+2C18:000000002020202020202C32528C0000
+2C19:000000007CAAAA92828292AAAA7C0000
+2C1A:000000001E1212127292929292720000
+2C1B:0000000092929292FE44828244380000
+2C1C:000000007191916A0A0A0A0404040000
+2C1D:0000000044447C92FE44828244380000
+2C1E:00000000929292929292929292FE0000
+2C1F:000000000000000003F8011000A000E01F10151008E000A0011003F800000000
+2C20:000000007E422418F898A424427E0000
+2C21:0000000010282844447C929292FE0000
+2C22:00002090786C4482828282446C3C1208
+2C23:000000007C4A4A4A4C50506060400000
+2C24:000000001C222060B8602020221C0000
+2C25:000000000C121030DCB01010120C0000
+2C26:0000000010284C92FE444444447C0000
+2C27:00000000000000001C38224402400EC003700EC00240024022441C3800000000
+2C28:0000000000000000387044883C80058006E0058004803C804488387000000000
+2C29:0000000000000000103828444C4092C0FF7038C0444082404444383800000000
+2C2A:0000000018242424FFA5242424180000
+2C2B:00000000F88850708E8A705088F80000
+2C2C:000000001C0404040404040408100000
+2C2D:0000000082C2B28AFE8AB2C282020000
+2C2E:00000000245456525252565A52520000
+2C2F:00007FFE61C67DBE61BE6FBE61C67FFE7FFE61867DBE618E6FBE61BE7FFE0000
+2C30:0000000000001010107C545410100000
+2C31:0000000000002A2A2A3E2020203E0000
+2C32:00000000000044AA6C28444444380000
+2C33:000000000000609090702C52928C0000
+2C34:00000000000038444444286CAA440000
+2C35:00000000000038441C041C0444380000
+2C36:0000000000000000C6286C92926C0000
+2C37:0000000000001C221C7F493214080000
+2C38:00000000000000205088FF8D55220000
+2C39:0000000000007C6C92927C1010380000
+2C3A:0000000000007C6C92926C4482FE0000
+2C3B:000000000000FE824428544444380000
+2C3C:000000000000444A4AACACB2A2000000
+2C3D:00000000000020203C04043C20200000
+2C3E:000000000000182424243C5A5A240000
+2C3F:0000000000000000000000001FF025481930010007C00EE012900C6000000000
+2C40:0000000000001C12127C505010100000
+2C41:0000000000001C221E02021E221C0000
+2C42:0000000000003E2A2A2A642020200000
+2C43:00000000000040404078444444780000
+2C44:00000000000038444454284482FE0000
+2C45:000000000000FEAAAAAAAAAAAA440000
+2C46:00000000000048B46C26246CB4480000
+2C47:00000000000010103854929254381010
+2C48:000000000000202020202C32528C0000
+2C49:0000000000007CAA92828292AA7C0000
+2C4A:0000000000000E0A0A3A4A4A4A3A0000
+2C4B:0000000000002A2A2A3E1422221C0000
+2C4C:00000000000062A2A274141408080000
+2C4D:000000000000447C92FE444444380000
+2C4E:000000000000545454545454547C0000
+2C4F:00000000000000000000000003F8011000E01F10151008E0011003F800000000
+2C50:0000000000003E2214784854223E0000
+2C51:000000000000001028447C9292FE0000
+2C52:000000002090786C448282446C3C1208
+2C53:00000000000078545458505060400000
+2C54:0000000000000C12305C3010120C0000
+2C55:000000000000040A186E58080A040000
+2C56:00000000000010284C92FE44447C0000
+2C57:0000000000000000000000001C3822440EC003700EC0024022441C3800000000
+2C58:0000000000000000000000001C3822441EC0037002C01E4022441C3800000000
+2C59:000000000000000000000000081C1422266049B87F601C2022221C1C00000000
+2C5A:000000000000102828FEAA2828100000
+2C5B:0000000000007848304E4A3048780000
+2C5C:0000000000001C040404040408100000
+2C5D:0000000000000262524A7E4A52620000
+2C5E:00000000000024545652565A52520000
+2C5F:00007FFE61C67DBE61BE6FBE61C67FFE7FFE61866FBE618E7DBE61BE7FFE0000
+2C60:000000002020207020702020203E0000
+2C61:000000003010103810381010107C0000
+2C62:000000001010101034581010101F0000
+2C63:000000003C2272223C20202020200000
+2C64:000000007C4242427C48444442425020
+2C65:0000000000003946043C54644CB40000
+2C66:0000000010107D1214181030508C0000
+2C67:00000000444444447C44444444460202
+2C68:00000040404058644444444444460202
+2C69:00000000424448506060504844430101
+2C6A:00000000404044485060504844430101
+2C6B:000000007E02020408102040407E0202
+2C6C:0000000000007E0204081020407E0202
+2C6D:000000001A26424242424242261A0000
+2C6E:00000000424266665A5A424242420A04
+2C6F:00000000424242427E42422424180000
+2C70:000000004C52624242424242625C0000
+2C71:00000000000082858548484830300000
+2C72:00000000848A8A88A8A8D8D888880000
+2C73:00000000000042555554545454280000
+2C74:0000000020505262C224242418180000
+2C75:00000000702020203C20202020700000
+2C76:0000000000007020203C202020700000
+2C77:000000000026494949494949493E0000
+2C78:000000000000708888F8808A8A740000
+2C79:0000001824240404040404044C360000
+2C7A:0000000000007C82828292AAAA7C0000
+2C7B:0000000000003E0202021E02023E0000
+2C7C:000000000000000004000C0404041408
+2C7D:00444428281000000000000000000000
+2C7E:000000003C424040300C0202423C0906
+2C7F:000000007E020404081020204060100E
+2C80:00000000C0201010384844444A310000
+2C81:000000000000C020103844444A310000
+2C82:000000007844444878444442427C0000
+2C83:00000000000070485070484444780000
+2C84:000000007E4040404040404040400000
+2C85:0000000000007C404040404040400000
+2C86:0000000010080C0C14121212A1FF0000
+2C87:000000000000201018181414A2FE0000
+2C88:000000003C664280FE808042663C0000
+2C89:0000000000003C4280FE8080423C0000
+2C8A:000000007E4040403C02040408080000
+2C8B:0000000000007E4040403C0204080000
+2C8C:00000080FE0202040810204040FE0200
+2C8D:000000000080FE020408102040FE0200
+2C8E:00000000424242427E42424242420000
+2C8F:0000000000004242427E424242420000
+2C90:00000000182424A4FF25242424180000
+2C91:0000000000001824A4FF252424180000
+2C92:00000000301010101010101010080000
+2C93:00000000000030101010101010080000
+2C94:000000004C4448507048444242420000
+2C95:0000000000004C444850704844420000
+2C96:0000000060101808080C142442830000
+2C97:000000000000C0201010182844860000
+2C98:000000008282C6AA9282828282820000
+2C99:000000000000446C5444444444440000
+2C9A:000000008282C2A292928A8682820000
+2C9B:00000000000044646454544C4C440000
+2C9C:00000080FF020C30F80402020C7F0100
+2C9D:000000000080FC041860F008187E0200
+2C9E:00000000386C4482828282446C380000
+2C9F:000000000000386C448282446C380000
+2CA0:00000000FF4242424242424242420000
+2CA1:0000000000007E242424242424240000
+2CA2:000000007C4242427C40404040404040
+2CA3:0000000000007C4242427C4040404040
+2CA4:000000001C36224040404022361C0000
+2CA5:0000000000001C3622404022361C0000
+2CA6:00000000FE1010101010101010100000
+2CA7:000000000000FE101010101010100000
+2CA8:00000000838244281010101010100000
+2CA9:00000000000083442810101010100000
+2CAA:00001010387C5492929292547C381010
+2CAB:000000001010387C549292547C381010
+2CAC:00000000434224181818242442420000
+2CAD:00000000000043241818242442420000
+2CAE:00001010939254381010101010100000
+2CAF:00000000101093543810101010100000
+2CB0:000000004492929292929292926C0000
+2CB1:000000000000449292929292926C0000
+2CB2:0000000000101010FE00000000000000
+2CB3:000000000000000010107C0000000000
+2CB4:00000000040810204620100804000000
+2CB5:00000000000000081020442010080000
+2CB6:0000000002FE000002FE000002FE0000
+2CB7:000000000000027E00027E00027E0000
+2CB8:0000004040201008040810207C000000
+2CB9:000000000000202010080408103C0000
+2CBA:000000000000000002FE000000000000
+2CBB:000000000000000000027E0000000000
+2CBC:0000000092929292FF92929292DB0000
+2CBD:000000000000929292FF929292DB0000
+2CBE:00000000929292929292929292DB0000
+2CBF:00000000000092929292929292DB0000
+2CC0:000000003C2222223C20FEA020202020
+2CC1:0000000000003C2222223C20FEA02020
+2CC2:54107C104492929292929292926C0000
+2CC3:000054107C10449292929292926C0000
+2CC4:00000080FF020C30F80402020C780000
+2CC5:000000000080FC041860F00818700000
+2CC6:00000000040404080808081010102020
+2CC7:00000000000004040808081010102020
+2CC8:000000003C6262021F0408F0817E0000
+2CC9:0000000000003C62021F08F0817E0000
+2CCA:000000003C424A320204081020400000
+2CCB:0000000000003C424A32040810200000
+2CCC:0000000078C4C202047C02020202827C
+2CCD:00000000000078C4C2023C040202827C
+2CCE:000000000000000001F001080108020802100200020004000400040008000800
+2CCF:00000000000000000000000001E0011002100210022004000400040008000800
+2CD0:000000004040404040404040427E0000
+2CD1:000000000000404040404040447C0000
+2CD2:000000000204081020404C52423C0000
+2CD3:000000000000040810204C52423C0000
+2CD4:000C1020180808080808080808180000
+2CD5:0000000C102018080808080808180000
+2CD6:000000002020202020202020227EA040
+2CD7:000000000000101010101010123E5020
+2CD8:00000000424242424242424242FF0000
+2CD9:000000000000242424242424247E0000
+2CDA:0000000010080C0C54321A16A3FF0000
+2CDB:00000000000010080C2C1A0E537F0000
+2CDC:003C4040386C4482828282446C380000
+2CDD:0000003C4040386C448282446C380000
+2CDE:000000007E22202020202020223E0000
+2CDF:0000000000007E2220202020243C0000
+2CE0:00000000102649516224584080800000
+2CE1:00000000000010264972245880800000
+2CE2:00000000FC203C2222223C2020202020
+2CE3:000000000000FC203C2222223C202020
+2CE4:0000000000004C44485070484442021C
+2CE5:00001E11111E1092D6BA929292921010
+2CE6:001E11111E10FE545454545454541010
+2CE7:0110011001E001007FFE0100391C6D3645228140814045226D36391C01000100
+2CE8:001E11111E107E101010101010101010
+2CE9:1E11111E101056545438383854541010
+2CEA:0000000000000000000000003FFC6C3644228240824044226C36381C00000000
+2CEB:0000000030C0492049204920492030C0000000200070FFF0FFF0E00040000000
+2CEC:0000000000000000000031804A404A4031800000004000E0FFE0E00040000000
+2CED:000000007038F0787038383834583298311832983458383C3C1E381C00000000
+2CEE:00000000000000000000186038601C600AA009200AA00C700E380C3000000000
+2CEF:00000000060007FE000600000000000000000000000000000000000000000000
+2CF0:0060703E706000000000000000000000
+2CF1:00060E7C0E0600000000000000000000
+2CF2:000810203C82424242424242423C0000
+2CF3:0000000810203C8242424242423C0000
+2CF4:00007FFE61C67DBE61BE6FBE61C67FFE7FFE61B66FB663866FF66FF67FFE0000
+2CF5:00007FFE61C67DBE61BE6FBE61C67FFE7FFE61866FBE63866FF66F867FFE0000
+2CF6:00007FFE61C67DBE61BE6FBE61C67FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+2CF7:00007FFE61C67DBE61BE6FBE61C67FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+2CF8:00007FFE61C67DBE61BE6FBE61C67FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+2CF9:00000000D8D848242424241212120000
+2CFA:0000000018181020202020404C4C0000
+2CFB:00000000303010080808080464640000
+2CFC:00000000363624484848489090900000
+2CFD:00000000000000040810100804380000
+2CFE:00000000201008046204081020000000
+2CFF:00300804000000000000000000000000
+2D00:00000000000000007E222020203E0200
+2D01:0000000000000000C444447C0402423C
+2D02:0000000000000000FC4444444442023C
+2D03:0000000000407C141038444444380000
+2D04:0000000000000000FC44444444460202
+2D05:000000000000000000000000000000003FF01110111011101110111001000080
+2D06:00000040701010101C121212121C0000
+2D07:000000000000000000000000000000001FF808880888088808880F8800000000
+2D08:00000000000000007E32220202020000
+2D09:0000000020202038242424241C040404
+2D0A:000000000000000000000000000000001FF8088808880888088808F800000000
+2D0B:000000203C0404041E24242424180000
+2D0C:000000007C4440407C44444444440000
+2D0D:00000000000000000000000000000000311011101110111011101FF800000000
+2D0E:0000000000000000B2D21212121F0000
+2D0F:0000000000000000B2D21212121F0202
+2D10:0000000000000000010001000100010011F011101110111011101F1000000000
+2D11:000000004040404048484848487C0400
+2D12:0000000000000000FC44447C4040403C
+2D13:00000000000000000008000800080008188808880888088808880FF800080008
+2D14:000000000000000000000000000000001FF808880888088808880FF800800080
+2D15:0000000010101016BAD0101010100000
+2D16:0000000000000000FC44444444460000
+2D17:0000000000000000622222223E020202
+2D18:00000000000000622222223E0202423C
+2D19:000000002020203C2424242020202020
+2D1A:0000000000000000FC44444444444038
+2D1B:000000000000000001000100010001001FF011101110111011101F1000000000
+2D1C:000000000000000000000000000000001FF80888088808880888089808000800
+2D1D:00000000000000007C24203804242418
+2D1E:000000000000000066222222223E2020
+2D1F:00000000000000C0FE22140C12214080
+2D20:000000000000000000000000000000003F10111011101110111011F800000000
+2D21:00000000404040784C40404040400000
+2D22:00000000000000004078040404780000
+2D23:00000000040404046424243C04040404
+2D24:000000000000000000006222223E0808
+2D25:000000000000000000F00110010001001FF011101110111011101F1000000000
+2D26:00007FFE618E7DB661B66FB6618E7FFE7FFE61CE7DBE618E6FB661CE7FFE0000
+2D27:00000000000000001824040830404438
+2D28:00007FFE618E7DB661B66FB6618E7FFE7FFE61CE7DB661CE6FB661CE7FFE0000
+2D29:00007FFE618E7DB661B66FB6618E7FFE7FFE61CE7DB661C66FF661CE7FFE0000
+2D2A:00007FFE618E7DB661B66FB6618E7FFE7FFE61867DB661866FB661B67FFE0000
+2D2B:00007FFE618E7DB661B66FB6618E7FFE7FFE618E7DB6618E6FB6618E7FFE0000
+2D2C:00007FFE618E7DB661B66FB6618E7FFE7FFE61C67DBE61BE6FBE61C67FFE0000
+2D2D:00000000000000003C040810203C0000
+2D2E:00007FFE618E7DB661B66FB6618E7FFE7FFE61867DBE618E6FBE61867FFE0000
+2D2F:00007FFE618E7DB661B66FB6618E7FFE7FFE61867DBE618E6FBE61BE7FFE0000
+2D30:00000000000000000000182424180000
+2D31:00000000000000384482FE8244380000
+2D32:00000000000000385492FE9254380000
+2D33:000000000000FE442810102844820000
+2D34:00000000000082442810102844FE0000
+2D35:000000000000FE442810102844FE0000
+2D36:000000000000D6D61010101010100000
+2D37:00000000000010282828284444440000
+2D38:00000000000044444428282828100000
+2D39:00000000007E404040784040407E0000
+2D3A:00000000007E0202027E0202027E0000
+2D3B:00000018242418007E00182424180000
+2D3C:000000000000EE28282838282828EE00
+2D3D:000000000000FE84889090A8C4820000
+2D3E:0000000000606000000C0C0000606000
+2D3F:00000000000082C4A890908884FE0000
+2D40:00000000000000385492929254380000
+2D41:000000000000003A448A92A244B80000
+2D42:00001818000018180000181800001818
+2D43:00000000000001020408182442810000
+2D44:0000000000001010107C444444440000
+2D45:00000000000092543810102844820000
+2D46:00000000000000006666000066660000
+2D47:000000000000FE84889090A0C0FE0000
+2D48:0000000000000000000000000000000000001998199800000000000000000000
+2D49:00000000000810201008102010080000
+2D4A:00000000007C101010101010107C0000
+2D4B:00000000000000C62810101028C60000
+2D4C:000000000000282828FE28FE28282800
+2D4D:0000000000002424242C342424242400
+2D4E:00000000007E404040404040407E0000
+2D4F:00000000000010101010101010101000
+2D50:000000000000101010FE10FE10101000
+2D51:00000000101010101010101010001010
+2D52:000000000000003C0408182424180000
+2D53:00000000182424180000182424180000
+2D54:00000000000000384482828244380000
+2D55:00000000000000384482928A443A0000
+2D56:000000000000444444447C1010100000
+2D57:00000000181800001818000018180000
+2D58:0000000000C3C3000018180000C3C300
+2D59:000000000000003844BABABA44380000
+2D5A:000000000000003A448A928244380000
+2D5B:00000000001E294640404046291E0000
+2D5C:000000000000101010107C1010101000
+2D5D:00000000000082442810102844820000
+2D5E:00000000001E294650785046291E0000
+2D5F:00000000007E4048487C4848407E0000
+2D60:000000000000102828282844447C0000
+2D61:000000000000444444444444447C0000
+2D62:00000000000000081020100810200000
+2D63:00000092925438101010385492920000
+2D64:00000000000030282420202020200000
+2D65:0000009292543810FE10385492920000
+2D66:00000000000408102040201008040000
+2D67:000000000000000000EE000000000000
+2D68:00007FFE618E7DB661B66FB6618E7FFE7FFE73CE6FB663CE6DB673CE7FFE0000
+2D69:00007FFE618E7DB661B66FB6618E7FFE7FFE73CE6FB663C66DF673CE7FFE0000
+2D6A:00007FFE618E7DB661B66FB6618E7FFE7FFE73866FB663866DB673B67FFE0000
+2D6B:00007FFE618E7DB661B66FB6618E7FFE7FFE738E6FB6638E6DB6738E7FFE0000
+2D6C:00007FFE618E7DB661B66FB6618E7FFE7FFE73C66FBE63BE6DBE73C67FFE0000
+2D6D:00007FFE618E7DB661B66FB6618E7FFE7FFE738E6FB663B66DB6738E7FFE0000
+2D6E:00007FFE618E7DB661B66FB6618E7FFE7FFE73866FBE638E6DBE73867FFE0000
+2D6F:002424243C0000000000000000000000
+2D70:00000000000002020202040408106000
+2D71:00007FFE618E7DB661B66FB6618E7FFE7FFE61EE7DCE7BEE77EE77C67FFE0000
+2D72:00007FFE618E7DB661B66FB6618E7FFE7FFE61867DF67B8677BE77867FFE0000
+2D73:00007FFE618E7DB661B66FB6618E7FFE7FFE618E7DF67BC677F6778E7FFE0000
+2D74:00007FFE618E7DB661B66FB6618E7FFE7FFE61B67DB67B8677F677F67FFE0000
+2D75:00007FFE618E7DB661B66FB6618E7FFE7FFE61867DBE7B8677F677867FFE0000
+2D76:00007FFE618E7DB661B66FB6618E7FFE7FFE61CE7DBE7B8E77B677CE7FFE0000
+2D77:00007FFE618E7DB661B66FB6618E7FFE7FFE61867DF67BEE77DE77DE7FFE0000
+2D78:00007FFE618E7DB661B66FB6618E7FFE7FFE61CE7DB67BCE77B677CE7FFE0000
+2D79:00007FFE618E7DB661B66FB6618E7FFE7FFE61CE7DB67BC677F677CE7FFE0000
+2D7A:00007FFE618E7DB661B66FB6618E7FFE7FFE61867DB67B8677B677B67FFE0000
+2D7B:00007FFE618E7DB661B66FB6618E7FFE7FFE618E7DB67B8E77B6778E7FFE0000
+2D7C:00007FFE618E7DB661B66FB6618E7FFE7FFE61C67DBE7BBE77BE77C67FFE0000
+2D7D:00007FFE618E7DB661B66FB6618E7FFE7FFE618E7DB67BB677B6778E7FFE0000
+2D7E:00007FFE618E7DB661B66FB6618E7FFE7FFE61867DBE7B8E77BE77867FFE0000
+2D7F:AAAA0001800000018000000180000001800000018000000180002AA980005555
+2D80:000000000600060006000F000F8019C0D8C0F8FCD8D618DC18C018C000000000
+2D81:0000000007FC0FFC18A610A611461F7C0E3C0200020036003C00340000000000
+2D82:00000000000001F803E4063C6C007C006C000C000C000C00043003F000300000
+2D83:000000000600060006000F000F8019C0D8C0F800D80018001800180000000000
+2D84:0000000060607FE006000F000F8019C0D8C0F800D80018001800180000000000
+2D85:000000000000000000000F000F8019C0D8C0F800D80018001800180000000000
+2D86:00000000038006C00C600C600C600C600EC007803FF0333003003F0030000000
+2D87:000018301FF006C00C600C600C600C600EC007803FF0333003003F0030000000
+2D88:0000000007F80FCC187818001C000C0007C000C000C00CC00FC00C0000000000
+2D89:18181FF8018007F80FCC187818000C0007C000C000C00CC00FC00C0000000000
+2D8A:0000000003000300030003C000C001C031E03F70373006300630060000000000
+2D8B:000000000000000001803180B180FF80B1803180300030003000300000000000
+2D8C:0000000001C003E036203E20364007F801980300030006000E00000000000000
+2D8D:0180018001C003E036203E20364007F801980300030006000E00000000000000
+2D8E:0C300FF0018001C033E03E20364007F801980300030006000E00000000000000
+2D8F:00000000000001F003580358364C3E4C364C064C060006000600060000000000
+2D90:00000000000001FC03CC06CC0CAA0CEE6C007F006E800C4006C0038000000000
+2D91:0000000001C003E00230033001F0006000C007F006187E186300030000000000
+2D92:000000000C300FF01FF819980180018031803F80330006000C00080000000000
+2D93:01C063C07E000C001C003300638061C060C000FC00D400DC00C000C007F80E1C
+2D94:00000000C0C0FFC00C001E003E007300636003E0037C030C0300030000000000
+2D95:0000000060607FE006000F001F00398031800180018001F001900FF00C000000
+2D96:01C063C07E000C001C003300638061D860D800FE00C600C000C000C007F80E1C
+2D97:00007FFE618E7DB661B66FB6618E7FFE7FFE73866DF671EE7DDE73DE7FFE0000
+2D98:00007FFE618E7DB661B66FB6618E7FFE7FFE73CE6DB671CE7DB673CE7FFE0000
+2D99:00007FFE618E7DB661B66FB6618E7FFE7FFE73CE6DB671C67DF673CE7FFE0000
+2D9A:00007FFE618E7DB661B66FB6618E7FFE7FFE73866DB671867DB673B67FFE0000
+2D9B:00007FFE618E7DB661B66FB6618E7FFE7FFE738E6DB6718E7DB6738E7FFE0000
+2D9C:00007FFE618E7DB661B66FB6618E7FFE7FFE73C66DBE71BE7DBE73C67FFE0000
+2D9D:00007FFE618E7DB661B66FB6618E7FFE7FFE738E6DB671B67DB6738E7FFE0000
+2D9E:00007FFE618E7DB661B66FB6618E7FFE7FFE73866DBE718E7DBE73867FFE0000
+2D9F:00007FFE618E7DB661B66FB6618E7FFE7FFE73866DBE718E7DBE73BE7FFE0000
+2DA0:000000001FF81998018003C003E0067036303E30363006300630063000000000
+2DA1:000000003FF033300300078007C00CE06C6C7C7C6C6C0C600C600C6000000000
+2DA2:000000003FF033300300078007C00CE06C607C606C600C600C6C0C7C000C0000
+2DA3:000000001FF81998018003C003E0067036303E30363000300030003000000000
+2DA4:000000003FF033300300078007C00CE06C607C606C600C7C0C640C7C00000000
+2DA5:000000007FE066600300078007C00CE06C607C606C600C600C600C6000000000
+2DA6:000000000FFC0CCC00C001E003E0073036303E30363006000600060000000000
+2DA7:00007FFE618E7DB661B66FB6618E7FFE7FFE61866DF661EE6DDE6DDE7FFE0000
+2DA8:000018181FF81998018001801FF81998018001801F8019800180000000000000
+2DA9:000018181FF81998018001801FF81998018001981FF819980180000000000000
+2DAA:000018181FF81998018001801FF81998018001801F80199801F8001800000000
+2DAB:000018181FF81998018001801FF81998018001801F8019800380070018001800
+2DAC:000018181FF81998018001801FF81998018001801FF0199001F0000000000000
+2DAD:000030303FF03330018001801FF81998018001801F8019800180000000000000
+2DAE:301830183BA006C00C600C600C600C600EC07FF8631803003F00330003000000
+2DAF:00007FFE618E7DB661B66FB6618E7FFE7FFE61866DBE618E6DBE6DBE7FFE0000
+2DB0:000000000000000000007C3E666606607FE06660066006600660000000000000
+2DB1:000000000000000000007C3E666606607FFE6666066006600660000000000000
+2DB2:000000000000000000007C3E666606607FE0666006600666067E000600000000
+2DB3:000000000000000000007C3E666606607FE06660066000600060000000000000
+2DB4:000000000000000000007C3E666606607FE06660067C0664067C000000000000
+2DB5:61807F800C000C007C3E666606607FE066600660066006600660000000000000
+2DB6:000000000000000000007C3E666606607FE06660066006000600000000000000
+2DB7:00007FFE618E7DB661B66FB6618E7FFE7FFE63866DF663EE6DDE63DE7FFE0000
+2DB8:000000000000000003E007F00C98188CF88CC88C1CCE1AAD1AAD1EEF00000000
+2DB9:000000000000000003E007F00C98188FF88BC8881CCC1AAA1AAA1EEE00000000
+2DBA:000000000000000003E007F00C98188CF88CC88C1CCC1AAC1AAC1EEF00030000
+2DBB:000000000000000003E007F00C981CCCFAACDAAC1EEC0018001C0032003E0000
+2DBC:000000000000000003F007F80C9B188EF88BC8881CCC1AAA1AAA1EEE00000000
+2DBD:000000000000000003F007F80CD81CCCFAEADA6A1E6E00500050007000000000
+2DBE:000000000000000003F007F80C9818CCF8AAC8AA1CEE1A001A001E0000000000
+2DBF:00007FFE618E7DB661B66FB6618E7FFE7FFE63866DBE638E6DBE63BE7FFE0000
+2DC0:00000C300E700180018003F00D98199819B00FC0018001800180018000000000
+2DC1:00000C300E700180018003F00D98199819B00FC0019801F80198018000000000
+2DC2:00000C300E700180018003F00D98199819B00FC001800180019801F800180000
+2DC3:000018601CE00300030007E01B30333033601F80030006000C00380038003800
+2DC4:00000C300E700180018003F00D98199819B00FC0018001F0019001F000000000
+2DC5:000030C039C00600018003F00D98199819B00FC0018001800180018000000000
+2DC6:00000C300E70018002400240018003F00D98199819B00FC00180018000000000
+2DC7:00007FFE618E7DB661B66FB6618E7FFE7FFE71866FF66FEE6FDE71DE7FFE0000
+2DC8:0000000000000D980DD80FF00E60066006600660066006600660066000000000
+2DC9:0000000000001B301BB01FE01CC00CC00CF80CD80CC00CC00CC00CC000000000
+2DCA:0000000000001B301BB01FE01CC00CC00CC00CC00CC00CC00CC00CF800180000
+2DCB:0000000000000D980DD80FF00E60066006600060006000600060006000000000
+2DCC:0000000000001B301BB01FE01CC00CC00CC00CC00CC00CF80CC80CF800000000
+2DCD:000000000000199819D81FF01860066006600660066006600660066000000000
+2DCE:0000000000000D980DD80FF00E60066006600660060006000600060000000000
+2DCF:00007FFE618E7DB661B66FB6618E7FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+2DD0:30C039C0C630FFF0C63001C003E0067006300630063006300630063000000000
+2DD1:30C039C0C630FFF0C63001C003E006700636063E063606300630063000000000
+2DD2:30C039C0C630FFF0C63001C003E0067036303E30363006300636063E00060000
+2DD3:30C039C0C630FFF0C63001C003E0067006300630003000300030003000000000
+2DD4:30C039C0C630FFF0C63001C003E00670063006300630063E0632063E00000000
+2DD5:30C039C0C630FFF0C63003C00FE0187006300630063006300630063000000000
+2DD6:30C039C0C630FFF0C63001C003E0067006300630060006000600060000000000
+2DD7:00007FFE618E7DB661B66FB6618E7FFE7FFE63866DF66DEE6DDE63DE7FFE0000
+2DD8:0000000018601CE00FC007803F8030C000C000C000C000C000C000C000000000
+2DD9:0000000030C039C01F800F007F00618001F001B0018001800180018000000000
+2DDA:0000000030C039C01F800F007F0061800180018001800180018001F000300000
+2DDB:0000000030C039C01F800F007F006180018001800180038007007C0060000000
+2DDC:0000000030C039C01F800F007F00618001800180018001F0019001F000000000
+2DDD:0000000030C039C01F800F003F0025803D800180018001800180018000000000
+2DDE:30C039C01F80060006000F007F00618001800180018001800180018000000000
+2DDF:00007FFE618E7DB661B66FB6618E7FFE7FFE63866DBE6D8E6DBE63BE7FFE0000
+2DE0:04182038241800000000000000000000
+2DE1:38243824380000000000000000000000
+2DE2:38202020200000000000000000000000
+2DE3:1C1414243E4200000000000000000000
+2DE4:54543854540000000000000000000000
+2DE5:18240824180000000000000000000000
+2DE6:24283028240000000000000000000000
+2DE7:1E121252220000000000000000000000
+2DE8:446C5444440000000000000000000000
+2DE9:24243C24240000000000000000000000
+2DEA:18242418000000000000000000000000
+2DEB:3C242424240000000000000000000000
+2DEC:38243820200000000000000000000000
+2DED:18202018000000000000000000000000
+2DEE:7C101010100000000000000000000000
+2DEF:44281028440000000000000000000000
+2DF0:242424243E0200000000000000000000
+2DF1:24241C04040000000000000000000000
+2DF2:545454547C0000000000000000000000
+2DF3:545454547E0200000000000000000000
+2DF4:18243C24180000000000000000000000
+2DF5:3F444434000000000000000000000000
+2DF6:18041C241C0000000000000000000000
+2DF7:18243C201C0000000000000000000000
+2DF8:081C081C222200000000000000000000
+2DF9:04281028281000000000000000000000
+2DFA:7C54101C121C00000000000000000000
+2DFB:4C5272524C0000000000000000000000
+2DFC:4C427E524E0000000000000000000000
+2DFD:10283854540000000000000000000000
+2DFE:7C442838545400000000000000000000
+2DFF:7C4428F8545400000000000000000000
+2E00:0000003C202020202000000000000000
+2E01:0000003C202420202000000000000000
+2E02:00000004081020202020000000000000
+2E03:00000020100804040404000000000000
+2E04:00000004081020242020000000000000
+2E05:00000020100804240404000000000000
+2E06:0000007C101010101000000000000000
+2E07:0000007C101410101000000000000000
+2E08:00000038444024108848300000000000
+2E09:00000038444020108848300000000000
+2E0A:00000070880810204448300000000000
+2E0B:0000007C4444447C0000000000000000
+2E0C:00000040201008040000000000000000
+2E0D:00000004081020400000000000000000
+2E0E:000000800100038000000FE0010002807FFC028001000FE00000038001000200
+2E0F:0000000000000000000000000000000000000000000000000000000000007FFE
+2E10:0000000000000000000000000000000000000000000000007FFE100020004000
+2E11:0000000000000000000000000000000000000000000000007FFF000800040002
+2E12:00000000000000000000000000402040
+2E13:0000000000000008001000200440008001000200044008001000200000000000
+2E14:00000000000000080010002000400080010022002400280010000E0000000000
+2E15:00000000000000E0001000280048008801000200040008001000200000000000
+2E16:00000000000820100804081020080000
+2E17:00000000000000000618600618600000
+2E18:000000001010001010305052523C0000
+2E19:0000000000000A2BACAFB07EE0DC0000
+2E1A:0000000000240000007E000000000000
+2E1B:00001824241800314946000000000000
+2E1C:00000000000000000000004020100804
+2E1D:00000000000000000000000408102040
+2E1E:00000018180000314946000000000000
+2E1F:00000031494600000C0C000000000000
+2E20:00000030303030303C30303030300000
+2E21:0000000C0C0C0C0C3C0C0C0C0C0C0000
+2E22:0000003C303030303000000000000000
+2E23:0000003C0C0C0C0C0C00000000000000
+2E24:000000000000000030303030303C0000
+2E25:00000000000000000C0C0C0C0C3C0000
+2E26:000000000000003E4040403E00000000
+2E27:000000000000007C0202027C00000000
+2E28:00000012242448484848484824241200
+2E29:00000090484824242424242448489000
+2E2A:00000000000000006666000018180000
+2E2B:00000000000000001818000066660000
+2E2C:00000000000000006666000066660000
+2E2D:000000000000181800DBDB0018180000
+2E2E:000000003C4242402010100010100000
+2E2F:08101008081000000000000000000000
+2E30:00000000000000182424180000000000
+2E31:00000000000000183C3C180000000000
+2E32:00000000000000081018180000000000
+2E33:00000000000000000000181800000000
+2E34:00000000000000000000180808100000
+2E35:00000000000000081018001800000000
+2E36:00000818082878280818080808080000
+2E37:0000080C080A0F0A080C080808080000
+2E38:0000080808081C082A7F2A081C080000
+2E39:000000003C42403C42423C0000000000
+2E3A:0000000000000000007F000000000000
+2E3B:0000000000000000007F000000000000
+2E3C:00007FFE61867DBE618E6FBE61867FFE7FFE63C67DBE71BE7DBE63C67FFE0000
+2E3D:00007FFE61867DBE618E6FBE61867FFE7FFE638E7DB671B67DB6638E7FFE0000
+2E3E:00007FFE61867DBE618E6FBE61867FFE7FFE63867DBE718E7DBE63867FFE0000
+2E3F:00007FFE61867DBE618E6FBE61867FFE7FFE63867DBE718E7DBE63BE7FFE0000
+2E40:00007FFE61867DBE618E6FBE61867FFE7FFE6DCE6DB661B67DB67DCE7FFE0000
+2E41:00007FFE61867DBE618E6FBE61867FFE7FFE6DEE6DCE61EE7DEE7DC67FFE0000
+2E42:00007FFE61867DBE618E6FBE61867FFE7FFE6D866DF661867DBE7D867FFE0000
+2E43:00007FFE61867DBE618E6FBE61867FFE7FFE6D8E6DF661C67DF67D8E7FFE0000
+2E44:00007FFE61867DBE618E6FBE61867FFE7FFE6DB66DB661867DF67DF67FFE0000
+2E45:00007FFE61867DBE618E6FBE61867FFE7FFE6D866DBE61867DF67D867FFE0000
+2E46:00007FFE61867DBE618E6FBE61867FFE7FFE6DCE6DBE618E7DB67DCE7FFE0000
+2E47:00007FFE61867DBE618E6FBE61867FFE7FFE6D866DF661EE7DDE7DDE7FFE0000
+2E48:00007FFE61867DBE618E6FBE61867FFE7FFE6DCE6DB661CE7DB67DCE7FFE0000
+2E49:00007FFE61867DBE618E6FBE61867FFE7FFE6DCE6DB661C67DF67DCE7FFE0000
+2E4A:00007FFE61867DBE618E6FBE61867FFE7FFE6D866DB661867DB67DB67FFE0000
+2E4B:00007FFE61867DBE618E6FBE61867FFE7FFE6D8E6DB6618E7DB67D8E7FFE0000
+2E4C:00007FFE61867DBE618E6FBE61867FFE7FFE6DC66DBE61BE7DBE7DC67FFE0000
+2E4D:00007FFE61867DBE618E6FBE61867FFE7FFE6D8E6DB661B67DB67D8E7FFE0000
+2E4E:00007FFE61867DBE618E6FBE61867FFE7FFE6D866DBE618E7DBE7D867FFE0000
+2E4F:00007FFE61867DBE618E6FBE61867FFE7FFE6D866DBE618E7DBE7DBE7FFE0000
+2E50:00007FFE61867DBE618E6FBE61867FFE7FFE61CE6FB661B67DB661CE7FFE0000
+2E51:00007FFE61867DBE618E6FBE61867FFE7FFE61EE6FCE61EE7DEE61C67FFE0000
+2E52:00007FFE61867DBE618E6FBE61867FFE7FFE61866FF661867DBE61867FFE0000
+2E53:00007FFE61867DBE618E6FBE61867FFE7FFE618E6FF661C67DF6618E7FFE0000
+2E54:00007FFE61867DBE618E6FBE61867FFE7FFE61B66FB661867DF661F67FFE0000
+2E55:00007FFE61867DBE618E6FBE61867FFE7FFE61866FBE61867DF661867FFE0000
+2E56:00007FFE61867DBE618E6FBE61867FFE7FFE61CE6FBE618E7DB661CE7FFE0000
+2E57:00007FFE61867DBE618E6FBE61867FFE7FFE61866FF661EE7DDE61DE7FFE0000
+2E58:00007FFE61867DBE618E6FBE61867FFE7FFE61CE6FB661CE7DB661CE7FFE0000
+2E59:00007FFE61867DBE618E6FBE61867FFE7FFE61CE6FB661C67DF661CE7FFE0000
+2E5A:00007FFE61867DBE618E6FBE61867FFE7FFE61866FB661867DB661B67FFE0000
+2E5B:00007FFE61867DBE618E6FBE61867FFE7FFE618E6FB6618E7DB6618E7FFE0000
+2E5C:00007FFE61867DBE618E6FBE61867FFE7FFE61C66FBE61BE7DBE61C67FFE0000
+2E5D:00007FFE61867DBE618E6FBE61867FFE7FFE618E6FB661B67DB6618E7FFE0000
+2E5E:00007FFE61867DBE618E6FBE61867FFE7FFE61866FBE618E7DBE61867FFE0000
+2E5F:00007FFE61867DBE618E6FBE61867FFE7FFE61866FBE618E7DBE61BE7FFE0000
+2E60:00007FFE61867DBE618E6FBE61867FFE7FFE73CE6FB663B66DB673CE7FFE0000
+2E61:00007FFE61867DBE618E6FBE61867FFE7FFE73EE6FCE63EE6DEE73C67FFE0000
+2E62:00007FFE61867DBE618E6FBE61867FFE7FFE73866FF663866DBE73867FFE0000
+2E63:00007FFE61867DBE618E6FBE61867FFE7FFE738E6FF663C66DF6738E7FFE0000
+2E64:00007FFE61867DBE618E6FBE61867FFE7FFE73B66FB663866DF673F67FFE0000
+2E65:00007FFE61867DBE618E6FBE61867FFE7FFE73866FBE63866DF673867FFE0000
+2E66:00007FFE61867DBE618E6FBE61867FFE7FFE73CE6FBE638E6DB673CE7FFE0000
+2E67:00007FFE61867DBE618E6FBE61867FFE7FFE73866FF663EE6DDE73DE7FFE0000
+2E68:00007FFE61867DBE618E6FBE61867FFE7FFE73CE6FB663CE6DB673CE7FFE0000
+2E69:00007FFE61867DBE618E6FBE61867FFE7FFE73CE6FB663C66DF673CE7FFE0000
+2E6A:00007FFE61867DBE618E6FBE61867FFE7FFE73866FB663866DB673B67FFE0000
+2E6B:00007FFE61867DBE618E6FBE61867FFE7FFE738E6FB6638E6DB6738E7FFE0000
+2E6C:00007FFE61867DBE618E6FBE61867FFE7FFE73C66FBE63BE6DBE73C67FFE0000
+2E6D:00007FFE61867DBE618E6FBE61867FFE7FFE738E6FB663B66DB6738E7FFE0000
+2E6E:00007FFE61867DBE618E6FBE61867FFE7FFE73866FBE638E6DBE73867FFE0000
+2E6F:00007FFE61867DBE618E6FBE61867FFE7FFE73866FBE638E6DBE73BE7FFE0000
+2E70:00007FFE61867DBE618E6FBE61867FFE7FFE61CE7DB67BB677B677CE7FFE0000
+2E71:00007FFE61867DBE618E6FBE61867FFE7FFE61EE7DCE7BEE77EE77C67FFE0000
+2E72:00007FFE61867DBE618E6FBE61867FFE7FFE61867DF67B8677BE77867FFE0000
+2E73:00007FFE61867DBE618E6FBE61867FFE7FFE618E7DF67BC677F6778E7FFE0000
+2E74:00007FFE61867DBE618E6FBE61867FFE7FFE61B67DB67B8677F677F67FFE0000
+2E75:00007FFE61867DBE618E6FBE61867FFE7FFE61867DBE7B8677F677867FFE0000
+2E76:00007FFE61867DBE618E6FBE61867FFE7FFE61CE7DBE7B8E77B677CE7FFE0000
+2E77:00007FFE61867DBE618E6FBE61867FFE7FFE61867DF67BEE77DE77DE7FFE0000
+2E78:00007FFE61867DBE618E6FBE61867FFE7FFE61CE7DB67BCE77B677CE7FFE0000
+2E79:00007FFE61867DBE618E6FBE61867FFE7FFE61CE7DB67BC677F677CE7FFE0000
+2E7A:00007FFE61867DBE618E6FBE61867FFE7FFE61867DB67B8677B677B67FFE0000
+2E7B:00007FFE61867DBE618E6FBE61867FFE7FFE618E7DB67B8E77B6778E7FFE0000
+2E7C:00007FFE61867DBE618E6FBE61867FFE7FFE61C67DBE7BBE77BE77C67FFE0000
+2E7D:00007FFE61867DBE618E6FBE61867FFE7FFE618E7DB67BB677B6778E7FFE0000
+2E7E:00007FFE61867DBE618E6FBE61867FFE7FFE61867DBE7B8E77BE77867FFE0000
+2E7F:00007FFE61867DBE618E6FBE61867FFE7FFE61867DBE7B8E77BE77BE7FFE0000
+2E80:00000000000000000E000180006000101C00030000C000200000000000000000
+2E81:0000007C1F801000100010001000100010001000100020002000200040008000
+2E82:000000000000000000003FF80008000800100010002000200000000000000000
+2E83:0000100010001000100010001000100010001000100010001010101010100FF0
+2E84:00000000FFE00020002000200020002000200020002000100012000A00060002
+2E85:0040004000800100010003000500090001000100010001000100010001000100
+2E86:00000FF008100810081008100810081008100810081010101010101020504020
+2E87:00001FF01010101010101010101010101010101010102008200A200A40068002
+2E88:0400040007F00820084010002000000000000000000000000000000000000000
+2E89:0004000400040044004400440044004400440044004400440004000400140008
+2E8A:040004000400040004000400040007F004000400040004000400040004000400
+2E8B:00000000000000000000000000003FF020102010201020502020200420041FFC
+2E8C:0100111009200100000000000000000000000000000000000000000000000000
+2E8D:0208210810900820000000000000000000000000000000000000000000000000
+2E8E:000000000000FFFE0440044004400440044008400840104210422042403E8000
+2E8F:022002100408080410026422042004200420042004200420082208221022601E
+2E90:01000100010001000100FFFE024002400240044004400840084210422042C03E
+2E91:0220021004080804100267E2042004200420042004200420082208221022601E
+2E92:000000003FF020102010201020103FF02000200020002004200420041FFC0000
+2E93:00000100010002100410082010401F80010002000420081010083FFC00040004
+2E94:000004000400040007F0042008200820082008401FC00040004000407FFC0000
+2E95:00000000000000003FF8000800083FF80008000800083FF80008000000000000
+2E96:08000800080008000C004A004A00880008000800080008000800080008000800
+2E97:000000000000000000000200020002200290124812242214221042000A000400
+2E98:0100010001001FC001000100010001C007001900010001000100010005000200
+2E99:0800080008000FFC18102410442082200140008001800240042008101008E006
+2E9A:00007FFE61867DBE618E6FBE61867FFE7FFE73866DB671867DB673B67FFE0000
+2E9B:3FF002000200420042007FFC0480048004800880088010842084407C80000000
+2E9C:3FF820082FE820082FE800000000000000000000000000000000000000000000
+2E9D:00001FF01010101010101FF01010101010101FF0101010101010101010501020
+2E9E:0080008000FE088008800FF8100814102210412001400080010002000C007000
+2E9F:000000001FF8100811081188108810087FFC200821082188208820083FF80010
+2EA0:000000103FF82008200820083FF8200020883FFC2080204020202010380E3004
+2EA1:200010001000800040004800080010001000E000200020002000200000000000
+2EA2:01000100010021081110092001000140052009101108E1044104010005000200
+2EA3:0000000000000000000000000000000000000000248822444244800400000000
+2EA4:0010007C0780F808210818900890000000000000000000000000000000000000
+2EA5:007C1F9011101110210821044002000000000000000000000000000000000000
+2EA6:020002000200220012000A000200020006000A00120062002200020002000200
+2EA7:010011001FF821000100FFFE0000000000000000000000000000000000000000
+2EA8:4400280010002800480088000800180028004800880008000800500020000000
+2EA9:7FFC010001000100010001003FF8010001000100010001000100FFFE00000000
+2EAA:00000000FC0008001000100010005C0050005000500050005C00F00040000000
+2EAB:3FF82448244824483FF800000000000000000000000000000000000000000000
+2EAC:00007C000000FC00100054005400540054005400540094001000000000000000
+2EAD:200010001000F800080010001000380054009400100010001000100010001000
+2EAE:10401040104010403EFE289049108A1008100810081008100810081008500820
+2EAF:080008001000120022007C000800100024007E00020000005200490089000000
+2EB0:10001000200024004400F800100020004000FC00400000001C00E00040000000
+2EB1:3FF8200824482288210822882448200800000000000000000000000000000000
+2EB2:3FF82448244824483FF800000000000000000000000000000000000000000000
+2EB3:00003FFC20044008044008201010000000000000000000000000000000000000
+2EB4:00007FFE4444844804400440044004400440044008400842104210422042403E
+2EB5:0000000000003FFC224422442244224422442244224422442244200400000000
+2EB6:101008203FF801001FF001000200FFFE040008001000E0000000000000000000
+2EB7:082004407FFC01001FF00100FFFE000000000000000000000000000000000000
+2EB8:0440044004407C7C044004400000FFFE010001003FF801000100010001000100
+2EB9:020002083FC802100220FFFE0080010002000C003000C0000000000000000000
+2EBA:010001003FF80108FFFE01083FF8010801000100010001000100010001000100
+2EBB:010001001FF80108FFFE01081FF80100FFFE0000000000000000000000000000
+2EBC:07F8040805080488044804680408041804280448058808880808100820284010
+2EBD:02000C00707C400440044004400440047CFC400440044004400440047CFC4004
+2EBE:08200820FFFE0820082000000000000000000000000000000000000000000000
+2EBF:08200820FEFE0820082000000000000000000000000000000000000000000000
+2EC0:08200820FFFE0820082000000000000000000000000000000000000000000000
+2EC1:010001F801003FFC210421602F88210820F8200023E02220222044244824901C
+2EC2:200010000000FC00080010001000340058009400140010001000100010001000
+2EC3:7FFC044004403FF8244824483FF8000000000000000000000000000000000000
+2EC4:00000000FFFE0480048004807FFC4484448444844484489448F4500440047FFC
+2EC5:1FF01010101011101110111011101110129012900480048008823082C07E0000
+2EC6:080008001FE020204040BFF8210821083FF8210821083FF82108410841288010
+2EC7:0400040007F0082010403FF85108118812481528198812481428180810281010
+2EC8:20001000100000000000F0001000100010001000100014001800100000000000
+2EC9:1FF0101010101010111011101110111011101210028004400820101020080000
+2ECA:00007F004100410041007F004900080008004F004800480048004F00F0004000
+2ECB:0200020002007FFC04000900110021003FF801000100FFFE0100010001000100
+2ECC:20001000100000000000F000100010001000100010001000280047FE00000000
+2ECD:2000100008004000200010000000F000100010001000100010002800440083FE
+2ECE:00002000100000000000F800080010002000780008000800100010002800C7FE
+2ECF:0000003C00240028002800300028002400240024003400280020002000200020
+2ED0:100010001E00200020007C0090001000FE001000100012001400180010000000
+2ED1:0FF808000FF008000FF00800FFFE1200111010A0104012201418180610000000
+2ED2:0FF8080008000FF0080008000FF008000800FFFE0400082010103FF810080000
+2ED3:0800081008200840088009000800FFFE0A0009000880084009200A180C060800
+2ED4:200013FC10044004400440044004400440044004400440044004400440144008
+2ED5:020004001FF0101010101FF010001FF8100810081FF810001FF8100810081FF8
+2ED6:F800880090009000A000900090008800880088008800F0008000800080008000
+2ED7:7FFC0100FFFE91128D6201001D70610C00000000000000000000000000000000
+2ED8:020002007FF802003FF00200FFFC00001FE010201FE010201FE01020102010C0
+2ED9:010001000104FFFE010001103FF8010001047FFE010401040104012801100100
+2EDA:7FFC020004001FF0101011101110111011101110129002400420181060080000
+2EDB:3FF02010201028502450229022902110211022902292244A484A400680020000
+2EDC:FFC000400044004800500060005000480044002000200012000A000600020000
+2EDD:0100028004400A203118DFF610101FF010101FF0100811901060121014081804
+2EDE:1000100028004400FE0044007C0044007C0040007C00400040007C0040000000
+2EDF:080008001400120029007E00A2003E0022003E002000280024002A0032002000
+2EE0:2000200020003E00440048008000100010001000100012001400180010000000
+2EE1:088808881110222011100888FFFE02001FF010101FF010101FF010101FF01010
+2EE2:7FE0002000201020102010201FFC000400040004FFE400040004002800100000
+2EE3:1FF010101F90109010907FFE40029FF410101FF010101FF01010101010501020
+2EE4:020004003FF8210821083FF8220822083FF8051009200948117C2102410280FE
+2EE5:040004000FE0102020407FF8A10821083FF8210821083FF800000000FFFE0000
+2EE6:010002001FF01010121011101150102010001FFC000400047FE4000400280010
+2EE7:0100010001FE010001003FF8200829282448228829282288244829283FF82008
+2EE8:010001007FFC010001003FF801000100FFFE08001FF02820444003801C70E00E
+2EE9:04403FF804400440FFFE01001FF0111011101FF0111011101FF0044008201010
+2EEA:1FF0101010101FF001003FF8210821083FF8210821083FF8210A0102010200FE
+2EEB:020001007FFC0820044003801C70F01E10101FF0101010101FF0101020104010
+2EEC:020001007FFC0820044003800C603018C8260820082008200820102010202020
+2EED:0100010001F801000100FFFE00002928254823883FF823882548292821083FF8
+2EEE:0100010011F8110011001100FFFE00002108210822882448282820083FF80008
+2EEF:020001007FFC10100820FFFE01001FF011101FF0111011101FF01112010200FE
+2EF0:0420041004100400FFFE048004880488049008A008C0108211822282447E8000
+2EF1:04003FF820083EF802807A800AFCFE940AD47AA402A47AD40A94FEFC0A8279FE
+2EF2:04000FC010803FF0D1101FF011101FF001003FF821083FF821083FF8010200FE
+2EF3:040004000FE0102020407FF8A10821083FF8210821083FF821080102010200FE
+2EF4:00007FFE61867DBE618E6FBE61867FFE7FFE61B66FB663866FF66FF67FFE0000
+2EF5:00007FFE61867DBE618E6FBE61867FFE7FFE61866FBE63866FF66F867FFE0000
+2EF6:00007FFE61867DBE618E6FBE61867FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+2EF7:00007FFE61867DBE618E6FBE61867FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+2EF8:00007FFE61867DBE618E6FBE61867FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+2EF9:00007FFE61867DBE618E6FBE61867FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+2EFA:00007FFE61867DBE618E6FBE61867FFE7FFE61866FB663866FB66FB67FFE0000
+2EFB:00007FFE61867DBE618E6FBE61867FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+2EFC:00007FFE61867DBE618E6FBE61867FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+2EFD:00007FFE61867DBE618E6FBE61867FFE7FFE618E6FB663B66FB66F8E7FFE0000
+2EFE:00007FFE61867DBE618E6FBE61867FFE7FFE61866FBE638E6FBE6F867FFE0000
+2EFF:00007FFE61867DBE618E6FBE61867FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+2F00:000000000000000000047FFE0000000000000000000000000000000000000000
+2F01:0100018001000100010001000100010001000100010001000100010001000000
+2F02:0000000004000200010000800040004000000000000000000000000000000000
+2F03:0200020002000200020002000200020002000200040004000800100020000000
+2F04:00403FE000400080010002000400080010002004200420061FFC000000000000
+2F05:00400040004000400040004000400040004000400040004003C0004000000000
+2F06:00101FF80000000000000000000000000000000000047FFE0000000000000000
+2F07:000000000100008000847FFE0000000000000000000000000000000000000000
+2F08:0100010001000100010001000100010001000280044008201010200E40040000
+2F09:08400C60084008400840084008400840084008401040104420444046803C0000
+2F0A:1E000100010001000100028002800440044008201010200C4006800200000000
+2F0B:00C0004000400640044004400420082008200810101010082004400680020000
+2F0C:20043FFE20042004200420042004200420042004200420042024201C20080000
+2F0D:00000000000020023FFE20044008000000000000000000000000000000000000
+2F0E:0400030001000000004000800080010001000600020002000200020000000000
+2F0F:00200FF0082008200820082008200820082008200820082210222022401E0000
+2F10:2004300620042004200420042004200420042004200420043FFC200400000000
+2F11:00043FFE01040104010401040104010402040204040404040844103860100000
+2F12:01000100010001083FFC01080108010801080208020804080888107060200000
+2F13:1000100010041FFE100420044004000400040004000400040044003800100000
+2F14:08000C00080008100820084009800A000C003800C80008040804080607FC0000
+2F15:20083FFC20002000200020002000200020002000200020083FFC200000000000
+2F16:7FFC200020002000200020002000200020002000200020083FFC000000000000
+2F17:0100010001000100010001047FFE010001000100010001000100010001000000
+2F18:0200020002000200020003800240023002180208020002000200020002000000
+2F19:042007F0042004200420042004200420042004E0044004000400040004000000
+2F1A:20043FFE20002000200020002000200020002000200020004000400080000000
+2F1B:018001000100020002000400040008200810100811FCFE044004000000000000
+2F1C:00103FF80810081004200420024002400180018002400420181E600400000000
+2F1D:10081FFC1008100810081008100810081008100810081FF81008000000000000
+2F1E:20043FFE20042004200420042004200420042004200420043FFC200400000000
+2F1F:0100018001000100010001083FFC01000100010001000100010001047FFE0000
+2F20:0100018001000100010001047FFE01000100010001000100010001083FFC0000
+2F21:0400041007F80C101220214001800E70700E0000000000000000000000000000
+2F22:0200020012100BF8041004100A200A20114021404080014006201818E0060000
+2F23:02000200020803FC040804080C10121021204120004000800100060038000000
+2F24:010001800100010001047FFE0100010001000280044008201010200E40040000
+2F25:020003000200020002047FFE042004200820082010400E8001800670780E0000
+2F26:00083FFC0010002000C0008000847FFE00800080008000800480038001000000
+2F27:00000100008020843FFE20044008000000000000000000000000000000000000
+2F28:00200020002000247FFE0020002008200420042004200020012000E000400000
+2F29:008000800080008000800C900888108410862082408200800480038001000000
+2F2A:0200020002000208FFFC020002000280028004800484088410842086C07C0000
+2F2B:10081FFC1008100810081FF81008100010001000100020002000400080000000
+2F2C:010001000100210421042104210421043FFC21040100010002000C0070000000
+2F2D:01000100010001004104410441044104410441044104410441047FFC40040000
+2F2E:0444044408880888111011102220444022201110088808880444044404440000
+2F2F:00083FFC01000100010001000100010001000100010001047FFE000000000000
+2F30:00107FF800100010001000103FF020102000200020002004200420061FFC0000
+2F31:00800080008010841FFE10841084108410841084108410BC1088008000800000
+2F32:00083FFC010001000100010001047FFE01000100010001000100010001000000
+2F33:0300020004000430082010407F80210002000420081013E87C0C200400000000
+2F34:0100008000841FFE100010001000100010001000100020002000400080000000
+2F35:08007C0008000800100024003E00040084004400280010002800C40683FC0000
+2F36:0410041004100410041004107FFE041004100410041008100810101020100000
+2F37:0120011801080100011E01E07F003080008000800040004200220012000E0000
+2F38:00103FF80010001000101FF0100010083FFC000800080008010800F000200000
+2F39:00083FFC000800080008000800081FF8000800080008000800083FF800080000
+2F3A:00C0008001000200040000C00080010002000460004000800100020004000000
+2F3B:00C000800100020004C008800100030005000900110001000100010001000000
+2F3C:0100008000C00040040004002408240424062402440084100410041803F00000
+2F3D:0200024002200200021C02E07F000218021002200140018202440C24701E0000
+2F3E:001010381FC010081FFC1008100810081FF81008100020002000400080000000
+2F3F:001000787F80010001103FF8010001047FFE0100010001000900070002000000
+2F40:0080008000847FFE008000901FF80410041002200140008001400630380E0000
+2F41:01000100010401FE010001103FF80810042004200240018001800E70700E0000
+2F42:0100008000847FFE082008200820044004400240028001800660181860060000
+2F43:002008200420022002200820042002200224003E03E07C202020002000200000
+2F44:002010701F801000100010041FFE104010401040104020402040404080400000
+2F45:0100008000847FFE02000200020803FC02080208020804080888107060200000
+2F46:00081FFC01000100010001047FFE0240024002400240044208421042603E0000
+2F47:10101FF8101010101010101010101FF0101010101010101010101FF010100000
+2F48:20083FFC20082008200820083FF820082008200820083FF82008000000000000
+2F49:08100FF80810081008100FF00810081008100FF0081008101090207040200000
+2F4A:00800080008000847FFE0080028002A004A00490089008881086608400800000
+2F4B:0800080008040FFE100821104100010001000100018002400420181860060000
+2F4C:00800080008000800080088808FC08800880088008800880088008847FFE0000
+2F4D:00047FFE02000200021003F804100C1012202120414000800100060078000000
+2F4E:042007F00420042004200820101C20001FF808100420024001800E70700C0000
+2F4F:00081FFC10881088108810887FFE11081108210822087FFE041009F030200000
+2F50:0040104010401040104C12481F501060104010401040104413443C46103C0000
+2F51:001000383FC001000100011C3FE00100010E01F07F0001020102010200FE0000
+2F52:001010381FC01080108010881FFC1080108010801080124214227812200E0000
+2F53:080008080FFC10002FF04000BFF000100010001000100012000A000600020000
+2F54:010001000100011801107D2005400580094009201110210C4906870202000000
+2F55:0080008000800080088C0888089010A020C00080018002400420181860060000
+2F56:001010381FE01120112011201120112011101110111021082108410681020000
+2F57:044004200810100C2004402004200440024002800180018002400C30300E0000
+2F58:00181810062001C002300C0C30240420044002400280018002C00C30300E0000
+2F59:0010041004100410041007F0001000103FF00410041004100410081030100000
+2F5A:104010401040104010441FFE100010201FF01020102010201020202040200000
+2F5B:00047FFE00400840084010443FFE01400240044008401040224041C000800000
+2F5C:00800080108010881FFC10802080408000847FFE008000800080008000800000
+2F5D:010001A00110011001047FFE0100010001000280044008201010200E40040000
+2F5E:0100008000847FFE01000100023005E01E4008800100021005F81E0C08040000
+2F5F:00083FFC01000100010001101FF80100012001100110010001047FFE00000000
+2F60:0008103C1FE0112011201120112011201110111011501148214843A681220000
+2F61:00047FFE04000400042007F008200A20092009201020102213227C22201E0000
+2F62:0810081008147FFE08100810081008100FF008100810081008100FF008100000
+2F63:00801080108010881FFC10802080408000901FF800800080008000847FFE0000
+2F64:10041FFE1084108410841FFC1084108410841FFC1084208420A4409C80880000
+2F65:20043FFE20842084208420843FFC208420842084208420843FFC200400000000
+2F66:00047FFE0084008800801080108810FC10801080188014802280C18080FE0000
+2F67:008008440FFE4800280028000800180068004800080010001000200040000000
+2F68:00087F1002A22244142808101008200440020000000000000000000000000000
+2F69:0100010012081FFC10081008100810081FF810081008100810081FF810080000
+2F6A:0080008010841FFE1084108810801FF812101210112020C020C043309C0E0000
+2F6B:10081FFC12481248124812481248124812481248124812487FFE000000000000
+2F6C:10101FF81010101010101FF01010101010101FF01010101010101FF010100000
+2F6D:00101FF800200340008000847FFE018802900480088010802480438001000000
+2F6E:0800080008080FFC10802080008000847FFE0080014002200410180E60040000
+2F6F:00047FFE01000100020004080FFC1408240844080408040807F8040800000000
+2F70:00101FF800000000000000047FFE00800CA00890108820844484038001000000
+2F71:0100010021043FFE210422042244222424F43F14281420042004203C20080000
+2F72:0008003C1FC00080008000847FFE008001C002A0049008881086608200800000
+2F73:0100008020823FFE200440080440044004400420082008101008200C40060000
+2F74:02000100008000883FFC000008100810042004200240024000847FFE00000000
+2F75:10001060104012441F7E289049108A1008100810081008100890087008200000
+2F76:0080108C08880C9004A000C47FFE028002C004A0089010882086408200800000
+2F77:01800100023004201FC00880012002103FFC108400800C900888108620820000
+2F78:0800080008080FFC1080208000847FFE008010841084108410841FFC10040000
+2F79:20043FFE2004211421142A942464222425242954309421042024201C20080000
+2F7A:0830042002447FFE0100010001101FF8010001047FFE01000100010001000000
+2F7B:02047FFE02042244122412240204060C1A3462C40204020412240E1C04080000
+2F7C:01000100010C3FE8011001247FFE0080010006300CC017046404040603FC0000
+2F7D:00047FFE0080008021043FFE2244224422442244224422442244225C20080000
+2F7E:01000104FFFE010001103FF801000104FFFE054005200910110C2106C1020000
+2F7F:00047FFE082008200FE00820082008200FE00824083E0FE07820002000200000
+2F80:010001081FFC01087FFE01081FF8010801003FF801047FFE0100010001000000
+2F81:0100010021043FFE210421842244243429142104218422442424281C20080000
+2F82:20083FFC2100210021083FFC2008200820083FF82108210021043FFE20000000
+2F83:0180010002081FFC100810081FF81008100810081FF8100810081FF810080000
+2F84:00047FFE01000200042008107FF82104010001083FFC0100010001047FFE0000
+2F85:02002704387E20042004200420043E7C200420042004200420043FFC20040000
+2F86:001000783F80008000847FFE0080008008880FFC0808080808080FF808080000
+2F87:10101010101012141F7E1210225052500A900AFE041008101010201040100000
+2F88:010001000A100FF809100890089008147FFE091008900890081010F020200000
+2F89:10101FF8101010101FF0101010101FF01200110C113010C01660781820060000
+2F8A:0400042007F0084010883FFC5108110811081FF810081002100210020FFE0000
+2F8B:0810081008102A542A542A542A542A542A543E7C2A5408101010201040100000
+2F8C:010001FC010001003FFE200221042110213821C02F0021022102410280FE0000
+2F8D:00800080008010881FFC1088108810881FF810880080008800847FFE30020000
+2F8E:00C00080010012081FFC124812481248124812481248124812487FFE00000000
+2F8F:180811FC200040000C040BFE1010301050109010101010101090107010200000
+2F90:0100008000847FFE0180028C04880C50146024404420049005080E0604020000
+2F91:00047FFE0220022022243FFE222422242224222423E422242004200420040000
+2F92:00201FF0102010201FE0102010201FE0102010201FE014A408843086C07C0000
+2F93:042007F0042008441FFE288448840FFC088408840FFC10841084209C40880000
+2F94:02000104FFFE000000001FF000001FF0000010101FF8101010101FF010100000
+2F95:044004200810100C218402400420181860060FF00810081008100FF008100000
+2F96:00083FFC000008100FF80810081008100FF0081004600440024002847FFE0000
+2F97:00047FFE01000200040C1A08631004A019C062A00490188E6084048003000000
+2F98:006000C00188065C1A2001C003200C60109003301C50009003101D2000C00000
+2F99:08080FFC080808080FF8080808080FF8080808080FF8080803600C1830060000
+2F9A:0080008000881FFC008000847FFE02401248124422442442444209C030800000
+2F9B:0100010001101FF8010001047FFE01000900090809FC09001500230040FE0000
+2F9C:08100FF80810081008100FF008900080088808FC088014801280218640FC0000
+2F9D:008009100FF808100FF0081008160FF408187FF000500190061018F060200000
+2F9E:010001047FFE010011081FFC11081FF811081FF8110801047FFE010001000000
+2F9F:010000883FFC08200420024002447FFE010001083FFC01000100010001000000
+2FA0:10041FFE1000101017F8100010041FFE124012481250222022904F0884060000
+2FA1:006001801E3800C01F1800601F8000801080108818FC148022804180807E0000
+2FA2:1FF0101010101FF0101000003FF8210821083FF820082004200420061FFC0000
+2FA3:00047FFE024012441FFE124412441244143C180410041FFC10041FFC10040000
+2FA4:003000F83F0001101110092009447FFE0380054009201110210E410401000000
+2FA5:10081FFC110811081FF8110811081FF81108010001083FFC010001047FFE0000
+2FA6:0080018002400420081010086FF6010001083FFC01001118091009247FFE0000
+2FA7:08100FF808000FF008000FF0080008047FFE08880850082009900E0E38040000
+2FA8:7EFC428442847EFC428442847EFC400440044004400440044024401C40080000
+2FA9:010012101FF810101FF010001FF810081FF8108800847FFE0080008000800000
+2FAA:010001103FF801107FFE01103FF0011031880990076009207118270602000000
+2FAB:0480044004440FFE0840184028484FFC084008480FFC084008440FFE08000000
+2FAC:00047FFE010021043FFE21042944252425242104294425242524211C21080000
+2FAD:0104FFFE01003FF80104FFFE00003FF82108210821083FF82008207820100000
+2FAE:0240024002447E7E0240024002483E7C0240024002447E7E0240024002400000
+2FAF:00047FFE008021043FFE2244224423C42244224423C4224422443FFC20040000
+2FB0:08200824FFFE08200FE001003FF821083FF821080100FFFE0100010001000000
+2FB1:020002201FF004247FFE00000FF008100FF000803FFC10803FFC008000800000
+2FB2:02400240024002447E7E024002403E7C024002447E7E0240024002447FFE0000
+2FB3:030001087FFC102008200440FFFE000010101FF810101FF010101FF010100000
+2FB4:00047FFE008011081FFC10081FF810081FF810081FF8100803600C1830060000
+2FB5:20083FFC204821E82F0821082FE8292829282FE82928214A21EA4F2684020000
+2FB6:3FE0002400280D30392C092209127FEE092409280930112C1112210A41060000
+2FB7:008001800240052018986FF608100FF008100FF0080809900A603C1810060000
+2FB8:083004207FFE008011101FF8101010101FF010101FF0101010101FF010100000
+2FB9:002000703F8001047FFE054009203118C8160FF808100FF008100FF008100000
+2FBA:10081FFC110011101FF811001FF8110011041FFE002409142494248440380000
+2FBB:08100FF8081009F029123FFE20044FF408100FF008100FF00810087008200000
+2FBC:010000847FFE00000FF008100FF020043FFE200427E4242427E4243C20080000
+2FBD:22003F0C200820103F2620443F8820107F26104410082210FF20414001800000
+2FBE:8002BEFA8822BEFA8822BEFA8002800280028002800280028012800E80040000
+2FBF:02102924244432A42994224424A43FFC2004103010C01700180410040FFC0000
+2FC0:00047FFE00000FF008100FF000003FFC2004244422842FF42104211C21080000
+2FC1:010012081FFC110811081FF8110811081FF81088019002A804FE1882607E0000
+2FC2:042007F0042008401FF8288848880FF8088808880FF808082444222242220000
+2FC3:01000A100FF808100FF008100FF008080FFC08000FFC29242494449400180000
+2FC4:0100010401FE01003FFC22142924244432A429942244252428943FFC20040000
+2FC5:010020843FFE222022243FFE22243FFC280428202FA4283829A25E22883E0000
+2FC6:008000847FFE08880888149423E20490190863F604200B4030C001201E100000
+2FC7:010040847FFE441044107F7E4410555455545554555455546494A49684100000
+2FC8:04247FFE042007E000047FFE01001FF811081FF811081FF810080C30700E0000
+2FC9:00701F8001087FFE010007E0191862860D60711E0D6403800560191863060000
+2FCA:10081FFC1108192815481FF8110801003FF8010001007FFE2444222242220000
+2FCB:124812480A500A507FFE108820845FFE1084118412C414A41894109C10880000
+2FCC:3FFC224422443E7C224402403E7C22443E7C22443E7C22440242024201FE0000
+2FCD:07E0042027E4242427E4242427E424243E7C02407E7E12481248224842480000
+2FCE:08200820FF2408FE7E2000247FFE424442447E48422824101E30704E21840000
+2FCF:060838FC20083EF820083FF820080940252821082948252A210A294673820000
+2FD0:01000FF008100FF008100FF008101FF811081FF811087FFE0420042038200000
+2FD1:020001047FFE02483EB0152815282534592208100FF008100FF0101060100000
+2FD2:0080089008F80880FFFE044044444AA451147FFC44444AA451147FFC40040000
+2FD3:104008447F7E2240147C7F04007C3E40227C3E40227C3E40227E2E42243E0000
+2FD4:08400FE0084010807FFC11447F7C05447F6C05547D6C05447F7E05027CFC0000
+2FD5:01800660181863C600007BDE4A527BDE00003FFC22443FFC2244225C22480000
+2FD6:00007FFE61867DBE618E6FBE61BE7FFE7FFE63CE6DBE6D8E6DB663CE7FFE0000
+2FD7:00007FFE61867DBE618E6FBE61BE7FFE7FFE63866DF66DEE6DDE63DE7FFE0000
+2FD8:00007FFE61867DBE618E6FBE61BE7FFE7FFE63CE6DB66DCE6DB663CE7FFE0000
+2FD9:00007FFE61867DBE618E6FBE61BE7FFE7FFE63CE6DB66DC66DF663CE7FFE0000
+2FDA:00007FFE61867DBE618E6FBE61BE7FFE7FFE63866DB66D866DB663B67FFE0000
+2FDB:00007FFE61867DBE618E6FBE61BE7FFE7FFE638E6DB66D8E6DB6638E7FFE0000
+2FDC:00007FFE61867DBE618E6FBE61BE7FFE7FFE63C66DBE6DBE6DBE63C67FFE0000
+2FDD:00007FFE61867DBE618E6FBE61BE7FFE7FFE638E6DB66DB66DB6638E7FFE0000
+2FDE:00007FFE61867DBE618E6FBE61BE7FFE7FFE63866DBE6D8E6DBE63867FFE0000
+2FDF:00007FFE61867DBE618E6FBE61BE7FFE7FFE63866DBE6D8E6DBE63BE7FFE0000
+2FE0:00007FFE61867DBE618E6FBE61BE7FFE7FFE61CE6FB663B66FB661CE7FFE0000
+2FE1:00007FFE61867DBE618E6FBE61BE7FFE7FFE61EE6FCE63EE6FEE61C67FFE0000
+2FE2:00007FFE61867DBE618E6FBE61BE7FFE7FFE61866FF663866FBE61867FFE0000
+2FE3:00007FFE61867DBE618E6FBE61BE7FFE7FFE618E6FF663C66FF6618E7FFE0000
+2FE4:00007FFE61867DBE618E6FBE61BE7FFE7FFE61B66FB663866FF661F67FFE0000
+2FE5:00007FFE61867DBE618E6FBE61BE7FFE7FFE61866FBE63866FF661867FFE0000
+2FE6:00007FFE61867DBE618E6FBE61BE7FFE7FFE61CE6FBE638E6FB661CE7FFE0000
+2FE7:00007FFE61867DBE618E6FBE61BE7FFE7FFE61866FF663EE6FDE61DE7FFE0000
+2FE8:00007FFE61867DBE618E6FBE61BE7FFE7FFE61CE6FB663CE6FB661CE7FFE0000
+2FE9:00007FFE61867DBE618E6FBE61BE7FFE7FFE61CE6FB663C66FF661CE7FFE0000
+2FEA:00007FFE61867DBE618E6FBE61BE7FFE7FFE61866FB663866FB661B67FFE0000
+2FEB:00007FFE61867DBE618E6FBE61BE7FFE7FFE618E6FB6638E6FB6618E7FFE0000
+2FEC:00007FFE61867DBE618E6FBE61BE7FFE7FFE61C66FBE63BE6FBE61C67FFE0000
+2FED:00007FFE61867DBE618E6FBE61BE7FFE7FFE618E6FB663B66FB6618E7FFE0000
+2FEE:00007FFE61867DBE618E6FBE61BE7FFE7FFE61866FBE638E6FBE61867FFE0000
+2FEF:00007FFE61867DBE618E6FBE61BE7FFE7FFE61866FBE638E6FBE61BE7FFE0000
+2FF0:EDB600008102810200008102810200008102810200008102810201008002B6DA
+2FF1:EDB6000080028002800200008002800236D8800280020000800280020000EDB6
+2FF2:EDB600008442844284420000844284420000844284420000844284420000EDB6
+2FF3:EDB6000080028002800236D88002800200008002B6DA0000800280020000EDB6
+2FF4:AAAA00008002155080021010800210108002101090120000955280020000AAAA
+2FF5:DB6B000080019B6910088001900910088001900910088001900910088001DB6D
+2FF6:DBB600008822882200008822882200008822800288220D60800280020000DBB6
+2FF7:DB6D0001800080010B6D8800800108018800800108018B6C800100018000B6DB
+2FF8:DB6D0001800080010B6D8800800108018800800108018800800108018800B6DB
+2FF9:B6DB8000000180018B6C0801800188000801800188000B6D800180000001DB6D
+2FFA:DB6D000190009001000190009001000190009001000190009B6D00018000B6DB
+2FFB:0000DB60802000009B6C902400009024902400009024DB64000010041B6C0000
+2FFC:00007FFE61867DBE618E6FBE61BE7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+2FFD:00007FFE61867DBE618E6FBE61BE7FFE7FFE618E6FB663B66FB66F8E7FFE0000
+2FFE:00007FFE61867DBE618E6FBE61BE7FFE7FFE61866FBE638E6FBE6F867FFE0000
+2FFF:00007FFE61867DBE618E6FBE61BE7FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+3000:0000000000000000000000000000000000000000000000000000000000000000
+3001:000000000000000000000000000010000C000600020000000000000000000000
+3002:000000000000000000000000000000000C00120012000C000000000000000000
+3003:0000000000000240024002400480048009000900000000000000000000000000
+3004:0000060018202030412841A881448D0493044908440824101860018000000000
+3005:1000100010003FC0204040808080090006000200010001000000000000000000
+3006:00000020001000203840448043008300850089009000A000C000000000000000
+3007:0000078018602010400840088004800480048004400840082010186007800000
+3008:0008000800100010002000200040004000400020002000100010000800080000
+3009:2000200010001000080008000400040004000800080010001000200020000000
+300A:0012001200240024004800480090009000480048002400240012001200000000
+300B:4800480024002400120012000900090012001200240024004800480000000000
+300C:007C004000400040004000400040004000400040004000000000000000000000
+300D:0000000002000200020002000200020002000200020002003E00000000000000
+300E:007E0042005E0050005000500050005000500050007000000000000000000000
+300F:00000000070005000500050005000500050005003D0021003F00000000000000
+3010:007C0078007000700070006000600060006000600060007000700078007C0000
+3011:1F000F00070007000300030003000300030003000300070007000F001F000000
+3012:7FFE000000007FFE010001000100010001000100010001000000000000000000
+3013:3FFE3FFE3FFE3FFE3FFE0000000000003FFE3FFE3FFE3FFE3FFE000000000000
+3014:0008001000200040004000400040004000400040004000400040002000100008
+3015:1000080004000200020002000200020002000200020002000200040008001000
+3016:07F00420044004800480050005000500050005000500048004800440042007F0
+3017:1FC0084004400240024001400140014001400140014002400240044008401FC0
+3018:10006000A000A000A000A000A000A000A000A000A000A000A000A00060001000
+3019:8000600050005000500050005000500050005000500050005000500060008000
+301A:F000A000A000A000A000A000A000A000A000A000A000A000A000A000A000F000
+301B:F00050005000500050005000500050005000500050005000500050005000F000
+301C:00000000000000000000000000F883047C000000000000000000000000000000
+301D:0048002400120000000000000000000000000000000000000000000000000000
+301E:1200240048000000000000000000000000000000000000000000000000000000
+301F:0000000000000000000000000000000000000000000024004800D80090000000
+3020:00003FFC3FFC00003FFC3FFC5596D9B9A5A5A5A5599A4182242413C8081007E0
+3021:C000800080008000800080008000800080008000800080008000800080008000
+3022:006000400C400840084008400840084008400840084000400040004000000000
+3023:0004100410841084108410841084108410841084108410041004000400000000
+3024:001000101020082004400240018000C001200210040808083000000000000000
+3025:00000420043008201CC003000480084008201020102010201040084007800000
+3026:00000100008000847FFE00000000000000000000000000000000000000000000
+3027:00000400040004000400FFF0000000000000FFF0000000000000000000000000
+3028:0100010001007FFE0000000000003FFC00000000000000007FFE000000000000
+3029:0800080008000FFC10102810042002200140008000C0012002100C1030000000
+302A:0000000000000000000000000000000000000000000000006000900090006000
+302B:0000600090009000600000000000000000000000000000000000000000000000
+302C:0000000600090009000600000000000000000000000000000000000000000000
+302D:0000000000000000000000000000000000000000000000000006000900090006
+302E:00000000000000000000000000000000C000C000000000000000000000000000
+302F:000000000000000000000000C000C0000000C000C00000000000000000000000
+3030:0000000000000000000000007070888807070000000000000000000000000000
+3031:08000C0008001000100020004000800080004000200010000800080004000400
+3032:08000C0008801040124021004100800080004000200010000800080004000400
+3033:0400060004000800080008001000100010002000200020004000400080008000
+3034:0400060004400820088008401040100010002000200020004000400080008000
+3035:0000800040002000200010001000080008000400040002000200010001000100
+3036:07C0183020085FF45FF480029FF29FF2810281028102410441042108183007C0
+3037:8282828282824444444428282828101010102828282844444444828282828282
+3038:010001000100010001000100FFFE010001000100010001000100010001000100
+3039:082008200820082008200820FFFE082008200820082008200820082008200820
+303A:108810881088108810881088FFFE108810881088108810882088208840888008
+303B:0000000002000100008000400080010000800040002000000000000000000000
+303C:0000000000007FF04030405040904110421044104810501060107FF000000000
+303D:0000000010002860449003100010001000100010001000100008000800040000
+303E:DB6D80010E00918980710000801180211FF8808181011FF8840188000001DB6D
+303F:00FE82C6C6AAAA92AAAAC6C682FE0000
+3040:00007FFE63CE7DB671B67DB663CE7FFE7FFE6DCE6DB661B67DB67DCE7FFE0000
+3041:00000000000000000400020013800E00048007E00D10161026102A2010C00000
+3042:00000400020002C01F000480048007E00D101508220826082A10106000000000
+3043:000000000000000000000000000010401020101010300A000C00040000000000
+3044:0000000000000000400020602010200822082418140818000800000000000000
+3045:0000000000000000000002000180000013800C40004000400040008003000000
+3046:0000020001C00000000003C01C20002000200020002000400040008001000000
+3047:0000000000000000000002000180000001C00E80010002000700090010F00000
+3048:0000040003800000000011C00E800100020004000E001100210020F800000000
+3049:00000000000000000000104008300C2038000BC00C201820282018C008000000
+304A:00000000080004300508060C1C000460059006080C0834880C70040000000000
+304B:0000000008000400046047103C88089808800880108011002500220000000000
+304C:0000000808240410044047203C90088808980880108011002500220000000000
+304D:00000200010001600F80008000F01F400020002007F008100800060001C00000
+304E:00000408022402D01F00010001E03E80004000400FE0102010000C0003800000
+304F:0000008000400040008001000600080008000400020001000080004000400000
+3050:0000008000400040008801240610080008000400020001000080004000400000
+3051:00000080204010201020103C23E0202020202020202018201040104000800000
+3052:0000010840A420502040207847C0404040404040404030402080208001000000
+3053:00000000080007E00080010000000000000000002000200010100FE000000000
+3054:00000008080407F00088010000000000000000002000200010100FE000000000
+3055:000004000200013021C01E800040004007E00820100010000C0003C000000000
+3056:000004080204013021C81E800040004007E00820100010000C0003C000000000
+3057:0000000010000800080008000800080008000800080808100460038000000000
+3058:0000000010200890084008000800080008000800080808100460038000000000
+3059:00000100008040F83F800080038004C0044003C0004000800080010002000000
+305A:00000128009440F83F800080038004C0044003C0004000800080010002000000
+305B:0000000000801040084008784BC03C400840084008C00840040003E000000000
+305C:0000000800841050084808784BC03C400840084008C00840040003E000000000
+305D:0000000009C0064000800100023807C038800100020002000200010000E00000
+305E:0000000009C8066400900100023807C038800100020002000200010000E00000
+305F:000000000800048007003C0008F008180820100010001100210020F800000000
+3060:000000080824049007003C0008F008180820100010001100210020F800000000
+3061:00000800040004C047003C00080008C00B201C1010100010002000C007000000
+3062:00000800040804C447103C08080008C00B201C1010100010002000C007000000
+3063:000000000000000000000000000001C00620381000100010002000C007000000
+3064:000000000000000003E04C103008000800080008001000600380000000000000
+3065:000000080024001003E04C103008000800080008001000600380000000000000
+3066:00000000003843C03C800100010002000200020002000200010000E000000000
+3067:00000000003843C03C880124011002000200020002000200010000E000000000
+3068:000000000400020002000200027003800600080010001000080007F000000000
+3069:000000000408022402100200027003800600080010001000080007F000000000
+306A:00000400020002803F0004700818082010401040204003C00460045003800000
+306B:000000002000100010F01318202020002000200022002A0011F8100010000000
+306C:0000000001000080008013E01510190812082A084C084C685490206800000000
+306D:000010000800080008004CE03F100C1008101810181028F0591808E000000000
+306E:00000000000003C00D2011101108220822082408241028101060018000000000
+306F:0000004020201020143813E0202020202020202029E01230122811C000000000
+3070:0000008840442050287827C0404040404040404053C024602450238000000000
+3071:0000009840642064287827C0404040404040404053C024602450238000000000
+3072:00000000004004403C2008200830102810201020104010400880070000000000
+3073:00000008004404503C2808200830102810201020104010400880070000000000
+3074:00000030004804483C3008200830102810201020104010400880070000000000
+3075:00000000040003800080010002000200010002B04C88389C2480030000000000
+3076:000000000400038800A4011002000200010002B04C88389C2480030000000000
+3077:000000000400039800A4012402180200010002B04C88389C2480030000000000
+3078:0000000000000000000006000900108020400030000C00000000000000000000
+3079:0000000000000010004806200900108020400030000C00000000000000000000
+307A:0000000000300048004806300900108020400030000C00000000000000000000
+307B:00000000223011C01040103823E020202020202029E01230122811C000000000
+307C:00000000446823842090207847C040404040404053C024602450238000000000
+307D:00000018446423A42098207047C040404040404053C024602450238000000000
+307E:00000100008010F00F80008010E00F80008000800F8010E010900F0000000000
+307F:000000000880078001000100022002100FF03418442448203040008000000000
+3080:00000800040027001C3004081C0C240024002C2018100810081007E000000000
+3081:0000000001000080108013C01CA0111029082A08460844084A10306000000000
+3082:00000200010011000E000380120024201C200710041004100410022001C00000
+3083:000000000000000000000100088009E00E103C10046002000200010001000000
+3084:00000100008001C0180010F00B084C0834080270020001000100008000800000
+3085:000000000000000000000200010021E0271029103110232021C0010002000000
+3086:000000000300408021E022902488288830883488229021E00080010002000000
+3087:000000000000000002000100012001C00100010001000F0011C011200E000000
+3088:0000020001000100013001C001000100010001001F80216021101E0000000000
+3089:00000200010001C0060008000800080009E00E1008100810002000C003000000
+308A:0000100009800A400C200C200820082008200820004000400080010002000000
+308B:0000000008C0074000800100020007C00C201010201003900460044003800000
+308C:000000001000080009C00A201C206C2008201820182028204824181808000000
+308D:0000000011800E800100020004000FC00820101020100010002000C007000000
+308E:0000000000000000000008000400040006E01D1006100C100C10142004400000
+308F:000010000800080008004CE03F100C080808180818082810482018C008000000
+3090:00000000098006800100010003E00E1012082408240828C8193010E000000000
+3091:0000000009800700020007C008201020062009C0070008001CE0231040380000
+3092:00000400020012C00F00040004200F3818C02180028004800800080007E00000
+3093:000002000100010002000200040004000F000880108010882090206000000000
+3094:0000020001C80004001003C81C20002000200020002000400040008001000000
+3095:00000000000000000000040004603F1004880898108011002500220000000000
+3096:0000000000000080004008200820083811E01020102014201440084000800000
+3097:00007FFE63CE7DB671B67DB663CE7FFE7FFE73866DF671EE7DDE73DE7FFE0000
+3098:00007FFE63CE7DB671B67DB663CE7FFE7FFE73CE6DB671CE7DB673CE7FFE0000
+3099:0000000400120008000000000000000000000000000000000000000000000000
+309A:0000000600090009000600000000000000000000000000000000000000000000
+309B:0000100048002000000000000000000000000000000000000000000000000000
+309C:0000300048004800300000000000000000000000000000000000000000000000
+309D:000000000000000000000C000300008000C00100000000000000000000000000
+309E:000000000000002000900C400300008000C00100000000000000000000000000
+309F:000000000600018008000800080008000FC0102000100010002000C003000000
+30A0:00000000000000000000000000007E000000000000007E000000000000000000
+30A1:000000000000000000000000000021E01E200240018001000100020004000000
+30A2:00000000000021F01E1000200240018001000100010002000200040008000000
+30A3:0000000000000000000000200040008003801C80008000800080008000800000
+30A4:00000000002000200040008003000D0030800080008000800080008000800000
+30A5:000000000000000000000200010001E01E200820084000400080010002000000
+30A6:0000000002000100010001F03E10101010200820084000400080010002000000
+30A7:000000000000000000000000000000E00F0001000100010001E01E1000000000
+30A8:000000000000000000701F800200010001000100010003F03C08000000000000
+30A9:000000000000000000000100008010E00F800180028004800880118000800000
+30AA:0000000000800040004020781FC000C00140024004400840104000C000400000
+30AB:0000000002000100010021F01F1002100210042004200820114020C000800000
+30AC:0000000802240114011021F01F1002100210042004200820114020C000800000
+30AD:0000000004000200027003801D000100017803803C8000800040004000400000
+30AE:0000000804240214027003801D000100017803803C8000800040004000400000
+30AF:0000000004000270039002200420044008401080008001000200040008000000
+30B0:00000008082404D4075004400840088010802100010002000400080010000000
+30B1:0000000008000400040004380FC0090010802080008001000100020004000000
+30B2:0000000808240414041004380FC0090010802080008001000100020004000000
+30B3:000000000000000021F01E100010001000100020002003E01C20000000000000
+30B4:000000080024001443D03C400040004000400080008007803880000000000000
+30B5:00000000008008400440044024F81F4004400440044000800080010002000000
+30B6:0000000800A408540450044024F81F4004400440044000800080010002000000
+30B7:0000000000000C000200000018000408001000200040008013000C0000000000
+30B8:0000000000080C240214001018000408001000200040008013000C0000000000
+30B9:00000000000010E00F200040004000800080014002200C103010000000000000
+30BA:00000008002421D41E5000800080010001000280044018206020000000000000
+30BB:000000000800040004000478058826101C20044004000400020001F000000000
+30BC:000000080824041404100478058826101C20044004000400020001F800000000
+30BD:0000000000201010081004100420042000400040008000800100020004000000
+30BE:0000000800A42054105008400840084000800080010001000200040008000000
+30BF:000000000200010001F002100220052008C010400080010002000C0030000000
+30C0:000000080424021403F0042004200A4011402080010002000400180060000000
+30C1:00000000004001801E00010000F823801C800080008001000100020004000000
+30C2:00000008006401941E10010000F823801C800080008001000100020004000000
+30C3:0000000000000000000000000000044012200A20084000400080010002000000
+30C4:0000000000000410220811080910081000200020004000800100020000000000
+30C5:0000000800241094085044402440104010800080010002000400080000000000
+30C6:00000000000011E00E000000007823801C800080010001000200040008000000
+30C7:00000008002411D40E10000020F01F0000800080010001000200040008000000
+30C8:0000000008000400040004000400070004C00420040004000400040004000000
+30C9:00000020109008500840080008000E0009800840080008000800080008000000
+30CA:0000000001000080008020F81F80008000800080010001000200040008000000
+30CB:000000000000000000E01F00000000000000000001F03E080000000000000000
+30CC:00000000000010F00F10002000200E4001C000C0012002100C10300000000000
+30CD:000000000200010001E01E2000400080010003400D3031080100010001000000
+30CE:0000000000400020002000200040004000800080010002000400080010000000
+30CF:0000000000000000000008800440042008100810100820084008000000000000
+30D0:0000000000080024001408900440042008100810100820084008000000000000
+30D1:0000001800240024001808800440042008100810100820084008000000000000
+30D2:00000000000010000800080008E00F000800080008000800040003F000000000
+30D3:000000000010104808280820080008E00F00080008000800040003F000000000
+30D4:000000000030104808480830080008E00F00080008000800040003F000000000
+30D5:00000000000010F00F1000100020002000400040008001000200040000000000
+30D6:00000008002423D41C5000400080008001000100020004000800100000000000
+30D7:00000018002423E41C5800400080008001000100020004000800100000000000
+30D8:0000000000000000000002000500488030400030000C00000000000000000000
+30D9:0000000000200090005002400500488030400030000C00000000000000000000
+30DA:0000000000600090009002600500488030400030000C00000000000000000000
+30DB:0000000002000100010021F01F00010001400920091011102100030001000000
+30DC:0000000802240114011021F01F00010001400920091011102100030001000000
+30DD:0000001802240124011821F01F00010001400920091011102100030001000000
+30DE:000000000000000020F01F080010002000400C80030000800040000000000000
+30DF:000000000400030000C00020080006000180004010000C00030000C000200000
+30E0:0000000002000100010001000200020002400420043029C81E08000000000000
+30E1:000000000040002000200020062001C0004000A00090010002000C0030000000
+30E2:00000000000010E00F000200020023F81E0002000200020001F0000000000000
+30E3:0000000000000000000000000400027003901E20014001000080008000800000
+30E4:00000000080004000478038826101A2001400100010000800080008000000000
+30E5:000000000000000000000000000001C00E400040008001E01E10000000000000
+30E6:0000000000000000000011C00E4000400080008001F03E080000000000000000
+30E7:00000000000000000000000001E00E20002001E00E40004001C00E2000000000
+30E8:00000000000001F01E100010001001E00E2000200020002001E00E1000000000
+30E9:00000000000011C00E00007023901C100010002000200040008003000C000000
+30EA:0000000000400820042004200420042004200420004000400080010002000000
+30EB:0000000000000100088004800480048804880490089008A010C0208000000000
+30EC:0000000010000800080008000800080008100820084008800B000C0000000000
+30ED:000000000000000021F01E10101010100820082009E00E100800000000000000
+30EE:000000000000000000000000000010F00F100820042004400040008001000000
+30EF:00000000000021F01E1010100810082008200040004000800100020004000000
+30F0:0000000001000080008001F01E800880048005F03E8800800080008000800000
+30F1:000000000000000001E01E20024001800100010001F03E080000000000000000
+30F2:00000000000001F01E100010002001E00E200040004000800100060018000000
+30F3:00000000000000001800040802080010001000200040008013000C0000000000
+30F4:0000000804240214021043E03C20202010401040008000800100020004000000
+30F5:0000000000000000000000000200010011E00E2002200220042008C010400000
+30F6:0000000000000000000000000800040004600780088010800100020004000000
+30F7:00040012000821F01E1010100810082008200040004000800100020004000000
+30F8:0000000801040090008801F01E800880048005F03E8800800080008000800000
+30F9:000000080004001001E81E20024001800100010001F03E080000000000000000
+30FA:00040002000801F41E100010002001E00E200040004000800100060018000000
+30FB:0000000000000000000000000300078007800300000000000000000000000000
+30FC:000000000000000000000000000040F83F000000000000000000000000000000
+30FD:000000000000000000000C000300008000400020000000000000000000000000
+30FE:000000000000002000900C400300008000400020000000000000000000000000
+30FF:0000000021E01E10001000100010001000100010001000100010001000100000
+3100:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE73CE6DB66DB66DB673CE7FFE0000
+3101:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE73EE6DCE6DEE6DEE73C67FFE0000
+3102:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE73866DF66D866DBE73867FFE0000
+3103:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE738E6DF66DC66DF6738E7FFE0000
+3104:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE73B66DB66D866DF673F67FFE0000
+3105:04000400080011F03E1000100010002000200040004002800100000000000000
+3106:01000100020007F0001000100220014000800160062038000000000000000000
+3107:00183FEC10081008100810081008100810081008100800080000000000000000
+3108:000000301FF810001000100010001000100010000FFC00000000000000000000
+3109:02000200040008001FF82108010802080208040808101010012000C000000000
+310A:00C000C00080008043FE3D00010001000220021005F006080008000000000000
+310B:01E00E200040004000F800180010001000200020024001C00100000000000000
+310C:008000800480048008F80F8800880108010802100210041008A0104000000000
+310D:0210031C0218021004100C200840108018400820041002100308000800000000
+310E:00083FFE0300020007F804180010001000300020016001C00080000000000000
+310F:001E07E004000400040004000800080008001000100020000000000000000000
+3110:0040002000200020062004200420046005A00E20082000200020002000200000
+3111:001000180038006000C003000C0006000180004000300018000C000000000000
+3112:3FFE1C8000800080008000800080008000800080008000800000000000000000
+3113:02000100010011101110111011F01F10010001007FFC20000000000000000000
+3114:004000300060008001180630006000C003400440184000400040004000400000
+3115:001C0FEE000C000C047807800400040004000400080010000000000000000000
+3116:FFC08040804080408040A0409840864081408040804080408040FFC080408040
+3117:00FC1F0401040104010801080138011001000100010001000000000000000000
+3118:01800080008001003FFE01000100020003F002300020004000C0008000000000
+3119:01000180018001000300020004000820181010383FCC20040000000000000000
+311A:203010200C400480030002000200020002000200020002000000000000000000
+311B:00003FFE0040004000400FC01800100010000C1807E000000000000000000000
+311C:010000800080008003FC3C80008007800800100010001000081007E000000000
+311D:00000C300420042004FE0F207440044004400400040003F00000000000000000
+311E:1FFC0880088019901FF801180218021004100820102000400000000000000000
+311F:0000018006803880008000800040004000200010001C000C0000000000000000
+3120:0180018001100218021804300FE038C00180022004301FC81008000000000000
+3121:00380FD800100420026001C000C001300218040C180420000000000000000000
+3122:0FF000100420082008401FFC300C000800100030002000400000000000000000
+3123:0C00080008001800100011FC3E0C000800080010001000200000000000000000
+3124:008000800080010001F81F80028002800680048008801080207E000000000000
+3125:010000C000C0018001000300020004000C00080017FC78000000000000000000
+3126:00400660044004400440044004400840084008401040203E0000000000000000
+3127:0100018001000100010001000100010001000100010001000100010001000000
+3128:0018001804100220016000C000C0012002300418080C100C0000000000000000
+3129:10101818080808080808080808080808100810081FF800080000000000000000
+312A:0000FFFC040004000400040007E0082008200820082010201020214040800000
+312B:0000FFF808800880088008800880088010801080108020802080408080780000
+312C:0100008000003FFE200020002000200020002000200020002000400040008000
+312D:000000007FFC0100010001003FF8210821082108210821082108010001000100
+312E:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE61867DBE618E6FBE61867FFE0000
+312F:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE61867DBE618E6FBE61BE7FFE0000
+3130:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE63CE7DB671B67DB663CE7FFE0000
+3131:00000000000020081FFC08080008000800080008000800080008000000000000
+3132:00000000000041083FFC11080108010801080108010801080000000000000000
+3133:00000000000082607F1022100210023002280248024402820301000000000000
+3134:0000000000000000000030000800080008000800080807FC0000000000000000
+3135:00000000000000000204C1FE20A02020205023881D0402020000000000000000
+3136:00000000000000400038C40223FF21002078208423841C840078000000000000
+3137:000000000000000070101FF8100010001000100010080FFC0000000000000000
+3138:000000000000000062883FFC208020802080208023841C7E0000000000000000
+3139:00000000000020101FF80810001030101FF81000100010100FF8000000000000
+313A:00000000000082047FFE22840204FF044004400443043C040000000000000000
+313B:00000000000041443FFE114401447FC42044204423C41C7E0040000000000000
+313C:00000000000042083F04028402847EFC2084208423841CFC0000000000000000
+313D:00000000000084607E1024100410FE3040284048468439020000000000000000
+313E:00000000000042C43F7E024002447F7E2040204023441C3E0000000000000000
+313F:00000000000085087EFC04000400FE8440484048464A3BFF0000000000000000
+3140:00000000000084407E38050204FFFE0040384044464438380000000000000000
+3141:00000000000038100FF80810081008100810081008100FF80800000000000000
+3142:00000000002000101010081008100FF00810081008100FF00810000000000000
+3143:00000000000802842144114411441F7C1144114411441F7C1144000000000000
+3144:00000000000004604210221022103E102228222822443E442282000000000000
+3145:0000000002000180008000800080014001400220041008083004000000000000
+3146:00000000000008400420042004200A200A5011482084C3020000000000000000
+3147:0000000000000200010007C008201010101010101010082007C0000000000000
+3148:00000000000020101FF809000100010002800440082010106008000000000000
+3149:000000000000000081047FFE242004200A50095010882104C602000000000000
+314A:00000000040003E0000020081FFC088001400220041008083004000000000000
+314B:00000000000010080FFC0408000800F83F081008000800080008000000000000
+314C:00000000000038200FF0080008200FF008000800081007F80000000000000000
+314D:00000000000020101FF80800000008100420022042483FFC1000000000000000
+314E:000000000000040003C040083FFC100003C0042008100810042003C000000000
+314F:004000300010001000100012001F001000100010001000100010001000100000
+3150:0020011800C80048004800480078004800480048004800480048004800080000
+3151:00400030001000100012001F00100012001F0010001000100010001000100000
+3152:0020011800C80048004800780048004800780048004800480048004800080000
+3153:004000300010001000100010001003F001100010001000100010001000100000
+3154:0010008C006400240024002403E4012400240024002400240024002400040000
+3155:0040003000100010001003F00110001003F00110001000100010001000100000
+3156:0010008C00640024002403E40124002403E40124002400240024002400040000
+3157:000000000000000000000000010000800080008040823FFF1000000000000000
+3158:00400030001000100010001008100412041F05F07E1020100010001000100000
+3159:0010008C00640024002408240424043C042407E47C2420240024002400040000
+315A:00200018000800080008040802080208020803F87E0820080008000800080000
+315B:000000000000000000000000004004200220022042223FFF1000000000000000
+315C:00000000000000000000000040023FFF10800080008000800080008000800000
+315D:00200018000800080008000801E87E08280809F8088808080808080800080000
+315E:002000980048004800480048004803C87C4828480BC808480848084800080000
+315F:002000180008000800080008000801E87E082408040804080408040800080000
+3160:00000000000000000000000040023FFF12200220022002200220022002200000
+3161:00000000000000000000000000000000000040023FFF10000000000000000000
+3162:0020001800080008000800080008000801F87E08200800080008000800080000
+3163:0040003000100010001000100010001000100010001000100010001000100000
+3164:AAAA00018000000180000001913C11219F381121912000018000000180005555
+3165:000000000000C1802040204020402040204023441C3E00000000000000000000
+3166:000000000000C0C4207E204020402040204023421C3F00000000000000000000
+3167:000000000000C0202010201020102010202823481C8401020000000000000000
+3168:000000000000C0102010202820282044204423821CFF00000000000000000000
+3169:00000000000088507FE808480848FC54405440623C4100000000000000000000
+316A:00000000000042C83F7C024002407F402040204023441C3E0000000000000000
+316B:00000000000088907C480A480A48FFD442544E6233C100000000000000000000
+316C:0000000084207E2004200450FC504088408847043BFE00000000000000000000
+316D:00000000000084007E00050404FEFE4040384044464438380000000000000000
+316E:000000000000000862843F442244227C2244224422443F7C2044000000000000
+316F:00000000000062203F10221022102210222822283E4422820000000000000000
+3170:00000000000062103F102228222822442244224422823FFF2000000000000000
+3171:000030081FFC1008100810081FFC1100008007E0081010081008081007E00000
+3172:00000000000004000282827F42227E024202420242027E024202000000000000
+3173:00000000040002C8827C424042407E404240424042447E3E4200000000000000
+3174:000000000000114288BF48824882798249424A427A224C120000000000000000
+3175:0000000000001132889F48904890799049504A507A524C2F0000000000000000
+3176:0000000000000800860445FE44A07C20442044507C8847060000000000000000
+3177:00000000040002C4827E424042447E7E4240424042447E3E4200000000000000
+3178:0010200810081FF8100810081FF81108008007E0081010081008081007E00000
+3179:0010248812481E78124812481E781248008007E0081010081008081007E00000
+317A:000000000000090404FE044404040A040A0411042104C0840000000000000000
+317B:00000000000008000580044006400A400A401140214440BE0000000000000000
+317C:00000000000010C4087E08400840144014402240414480BE0000000000000000
+317D:000000000004100208820842087E144214422242217E40C20000000000000000
+317E:000000000000120209FF08900810142814282244414281810000000000000000
+317F:000000000100010002800280044004400820082010103FF80000000000000000
+3180:00000000181808083C3C4242424242424242424242423C3C0000000000000000
+3181:0000030001000FE0101020082008200820082008200810100FE0000000000000
+3182:00003000120479FE84A08420842084508450848885047A020000000000000000
+3183:000030001020782084508450848884888488850485047BFE0000000000000000
+3184:000020101FF80000042042483FFC1100008007E0081010081008081007E00000
+3185:0000000020401C3881027FFF20001C382244224422441C380000000000000000
+3186:0000000040083FFC1200010007C0082008200820082007C00000000000000000
+3187:004000300010001000100912091F091009F27E1F201000100010001000100000
+3188:0020011800C800480048047802482248127813C87C4820480048004800080000
+3189:0020001800080008000802081108090809080BE87C0820080008000800080000
+318A:00200018000800080008000801E87F0829780908097809080908090800080000
+318B:0020011800C80048004800480348FC4855C8144815C814481448004800080000
+318C:002000180008000800080008000801E87F082908090809080908090800080000
+318D:0000000000000000000000000100038001000000000000000000000000000000
+318E:0020001800080008000800080008000802080708020800080008000800080000
+318F:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE73866DBE738E6DBE73BE7FFE0000
+3190:0000000000800080008000800080008000800000000000000000000000000000
+3191:0000000002000200020002200240028003000000000000000000000000000000
+3192:000000000000000000003FC00000000000000000000000000000000000000000
+3193:0000000000001F800000000000003FC000000000000000000000000000000000
+3194:000000001FE000000FC0000000003FF000000000000000000000000000000000
+3195:000000003FE02520252028E020203FE000000000000000000000000000000000
+3196:000000000400040007800400040004003FC00000000000000000000000000000
+3197:0000040004003FC0244024403FC0040004000400000000000000000000000000
+3198:000000003FC00400060005000400040004000000000000000000000000000000
+3199:000000003FC022403FC022403FC0224002000200000000000000000000000000
+319A:000000003F80030004000800104020401FC00000000000000000000000000000
+319B:000000003FE002003FE02220232024A028600000000000000000000000000000
+319C:000000003FE0020002000200020002000A000400000000000000000000000000
+319D:000000001FC0020002003FE00200050008E01040000000000000000000000000
+319E:0000084009503DF00B50095009280D0830F80000000000000000000000000000
+319F:000004000400040004000A000900108020400000000000000000000000000000
+31A0:00001000100020007FF0001000100010001000100010001001A0026002400180
+31A1:000000003FF0041004100410041004100420052004C0040034004C004C003400
+31A2:0000004008400840084008400840084010C013401C400040034004C004C00340
+31A3:000000000880088011001100220022004400220022001130114808C808B00000
+31A4:00000000100010001000FFF810081010101010001000100010000FF000000000
+31A5:00000000100010001000FFF810081010101010001030104810480FF000100000
+31A6:00000000FFF80200020002001E00200040004000202010400880050002000000
+31A7:00000000FFF80200020002001E002000406040904090405020601F9000000000
+31A8:00000000202010401040088008800500050003F8050008803060C01800000000
+31A9:0000201010200840048001000200020002000200020002001A00260026001A00
+31AA:0000000000000000001800240024FFF800100008000000000000000000000000
+31AB:0000000020201040104008800880050005000200051808A43064C01800080000
+31AC:000000000000FFF8210821082108210821082108210821082128001000000000
+31AD:00000000FFF8124012401240124012401240124012401240223CC20000000000
+31AE:00000000FFF81200120022003FF0021002100210041064109820902068400000
+31AF:00000400040008400840108010803F0002000460089010903FE0002000100000
+31B0:0000306008800500FFF882088208820882088208820882088208820882280010
+31B1:0000FFF80200FFF882088E089008A008A008A02890488F888008802800100000
+31B2:00000000FFF802000200020002000200020002000200020002000200FFF80000
+31B3:000002000200020002000200020002000200020002001A00260026001A000000
+31B4:000000000000000000000000100020007E000200020002001400080000000000
+31B5:000000000000000000000000100020007E001200220042009400080000000000
+31B6:000000000000000000000000FC0020004000F800080008002800100000000000
+31B7:00000000000000000000000000007E0020002000200020004000800000000000
+31B8:000000007FF00020004000800100020004000800100020007FF0000000000000
+31B9:00002000200020002000200020003FF800000000000000000000000000000000
+31BA:00000000000001000100010001007FFC01000100010001000000000000000000
+31BB:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE638E6DB6638E6DB6638E7FFE0000
+31BC:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE63C66DBE63BE6DBE63C67FFE0000
+31BD:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE638E6DB663B66DB6638E7FFE0000
+31BE:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE63866DBE638E6DBE63867FFE0000
+31BF:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE63866DBE638E6DBE63BE7FFE0000
+31C0:0000000000000000004001800600380010000000000000000000000000000000
+31C1:0400020002000100010001000100010001000100010001000100010005000200
+31C2:1000100010001000080008000800040004000200020001000090005000200000
+31C3:000000000000000000008000400020001804060201FC00000000000000000000
+31C4:00000800080008000800080008000800080008000800080008000FF000000000
+31C5:000000003F00010001000100010001000100010001000100010001F000000000
+31C6:0000000000003FF0001000100010001000100010001000100010005000200000
+31C7:000000003FF00010001000100010002000200040004000800080010002000400
+31C8:000000007F80008000800080008000800080008000800080008200820082007C
+31C9:00002000200020002000200020003FF800080008000800080010001000A00040
+31CA:000000003E000200020002000200020002000240028003000200000000000000
+31CB:000000003FFC000800100020007C000400040004000800080010002000400080
+31CC:000003E000200040008000800040004000200020002000200140008000000000
+31CD:0000000000007F800080008000800080008000800040003E0000000000000000
+31CE:000000003F80008000800080008000F000100010001000100010001000100000
+31CF:00000800080008000800040004000200020001000100008000400020001C0008
+31D0:00000000000000000000000000007FFE00000000000000000000000000000000
+31D1:0000010001000100010001000100010001000100010001000100010001000000
+31D2:0000000000200020004000400080010002000400000000000000000000000000
+31D3:0000004000400040004000400040004000800080010001000200040008000000
+31D4:0000000000000000040002000100008000400040000000000000000000000000
+31D5:0000000000001FF8000800080008000800080008000800080008000800000000
+31D6:0000000000007FFC000800100000000000000000000000000000000000000000
+31D7:00000000100010001000100010001000100010001000100010001FFC00000000
+31D8:0000001000100010001000100010001000100010001000103FF0001000000000
+31D9:0000040004000400040004000400040004200440048005000600040000000000
+31DA:0000008000800080008000800080008000800080008000800080028001000000
+31DB:0000004000400080008001000200040002000100008000400020000000000000
+31DC:00000040004000800080010001000200040008001FF800000000000000000000
+31DD:0000080008001400240002000200010001000080004000200010000E00040000
+31DE:00002000200020002000200020003FF800080008000800080008000800080000
+31DF:0000080008000800080008000800080008000800080008080808080807F80000
+31E0:00007FF00020004000800100020004000800100020004004400440063FFC0000
+31E1:000000003FF8001000100020007C000400040004000400040008002800100000
+31E2:0000000000100010002000200040004000800080010001002200240038000000
+31E3:0000000000001FF020084004400440044004400420081FF00000000000000000
+31E4:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE61B66FB663866FF661F67FFE0000
+31E5:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE61866FBE63866FF661867FFE0000
+31E6:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE61CE6FBE638E6FB661CE7FFE0000
+31E7:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE61866FF663EE6FDE61DE7FFE0000
+31E8:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE61CE6FB663CE6FB661CE7FFE0000
+31E9:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE61CE6FB663C66FF661CE7FFE0000
+31EA:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE61866FB663866FB661B67FFE0000
+31EB:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE618E6FB6638E6FB6618E7FFE0000
+31EC:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE61C66FBE63BE6FBE61C67FFE0000
+31ED:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE618E6FB663B66FB6618E7FFE0000
+31EE:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE61866FBE638E6FBE61867FFE0000
+31EF:00007FFE63EE7DCE71EE7DEE63C67FFE7FFE61866FBE638E6FBE61BE7FFE0000
+31F0:00000000000000000000000040002E0032002400440008001000200040000000
+31F1:0000000000000000000000000000600010000000610012000400480030000000
+31F2:00000000000000000000000000008E00720004000400080014002200C2000000
+31F3:0000000000000000000000002000200020003000280024002000200020000000
+31F4:00000000000000000000000000008E00720004003400080014002200C2000000
+31F5:0000000000000000000000000000048002400220042008101010000000000000
+31F6:0000000000000000000000004000400040004E0070004000400040003E000000
+31F7:00000000000000000000000000008E00720004000400080010002000C0000000
+31F8:0000000000000000000000000000000000000200050008C00030000000000000
+31F9:00000000000000000000200010001E00F0001000540092001000500030000000
+31FA:000000000000000000000000020001000100010001000200022014D00F080000
+31FB:0000000000000000000000008C00700000008E00720002000400080070000000
+31FC:0000000000000000000000000000880044004400440004000400080030000000
+31FD:0000000000000000000000000240012001200120012001240224042808300000
+31FE:0000000000000000000000000000800040004000400044004800500060000000
+31FF:00000000000000000000000000F01F10101010101020102011F01E0000000000
+3200:00001818200440024FF240124012401240124012401240124002200418180000
+3201:000018182004400244024402440244024402440247FA40024002200418180000
+3202:000018182004400240024FF2480248024802480248024FF24002200418180000
+3203:00001818200440024FF2401240124FF24802480248024FFA4002200418180000
+3204:000018182004400240024FF248124812481248124FF240024002200418180000
+3205:00001818200440024812481248124FF24812481248124FF24002200418180000
+3206:0000181820044082408240824142414242224412480A40024002200418180000
+3207:000018182004400243C244224812481248124812442243C24002200418180000
+3208:00001818200440025FF241024102428242824442482250124002200418180000
+3209:00001818200443E2400240024FFA4082414242224412480A4002200418180000
+320A:00001818200440024FF2401240125FF240124012401240124012200418180000
+320B:00001818200440024FF2480248024FF24802480248024FF24002200418180000
+320C:000018182004400240024FF2400244224422424242425FFA4002200418180000
+320D:000018182004400243C240025FFA400243C244224422442243C2200418180000
+320E:00001818202440225FA240A2413E422244224822502260224022202418180000
+320F:0000181820244022502250225022503E50225FE2402240224022202418180000
+3210:00001818202440225FA250225022503E50225FA2402240224022202418180000
+3211:00001818202440225FA240A240A25FBE502250225FA240224022202418180000
+3212:000018182024402240225F225122513E51225F22402240224022202418180000
+3213:0000181820244022512251225F22513E51225F22402240224022202418180000
+3214:0000181820244022442244224A224A3E512260A2402240224022202418180000
+3215:00001818202440224E2251225122513E512251224E2240224022202418180000
+3216:00001818202440225FE242224222453E452248A2506240224022202418180000
+3217:000018182024472240225FE24222423E452248A2506240224022202418180000
+3218:00001818202440225FA240A27F22423E44224822502260224022202418180000
+3219:00001818202440225FA250225FA2503E50225FA2402260224022202418180000
+321A:00001818202440225FA2402250A2493E49224BE27C2240224022202418180000
+321B:0000181820244F2240227FE240224F3E50A250A24F2260224022202418180000
+321C:0000301840049FF2810282828C62B01A8002BFFA810281028102410431180000
+321D:00003018400499EAA44AA4DAA52A992A800A88828882BEFA8002400430180000
+321E:30184004806299FAA462A492A4929862800288FA8822BE228022400430180000
+321F:00007FFE63867DF671867DBE63867FFE7FFE7B8673BE7B8E7BBE71BE7FFE0000
+3220:0000200840048002800280028012BFFA80028002800280028002400420080000
+3221:00002008400480229FF280028002800280028012BFFA80028002400420080000
+3222:0000200840249FF28002800280428FE2800280028012BFFA8002400420080000
+3223:0000200840048002BFFAA44AA44AA44AA44AA44ABFFA80028002400420080000
+3224:0000200840249FF28202820282229FF28422842284228422BFFA400420080000
+3225:000020084004820281028012BFFA800280028442842288129012400420080000
+3226:000020084204820282028212827A8382BE02820282028222822241E420080000
+3227:0000200840848482848284828482848288428822901AA0128002400420080000
+3228:000020084204820282429FE28242824282428442844A884A903A400420080000
+3229:000020084104810281028112BFFA810281028102810281028102400420080000
+322A:0000301847F48412841287F28412841287F28412841288529022400430180000
+322B:000030184104810289128922894291028282828284428822B01A400430180000
+322C:00003018410481028112BDA285428542892289229112A50A8202400430180000
+322D:00003018410481028102BFFA8102838285428922B11A81128102400430180000
+322E:000030184104828284428822B7DA81029FF2810289228542BFFA400430180000
+322F:0000301841048102810281029FF281028102810281028102BFFA400430180000
+3230:0000301840048FE28822882288228FE28822882288228FE28822400430180000
+3231:0000301848448942BDF28A429C429BFAA842A8E289528A4A8842400430180000
+3232:000030184204BFFA840287E28C2297E2A42287E2842284228462400430180000
+3233:0000301850448842BE42844289F28C429A42A842884288428BFA400430180000
+3234:00003018440487F284228A429182810287F2BC128412841287F2400430180000
+3235:000030184844A9F2BC42A842ABFA8C229BFAA92288A2882288E2400430180000
+3236:0000301840149E1293FA9E1292329E5292929F1280129252A122400430180000
+3237:0000301851F48912BF12831285F28CA29AA2AAA288AA892A8A1A400430180000
+3238:000030185214891289229FFA910AA1029FF28112821284129862400430180000
+3239:0000301844A48492888288FA9B82A88288828842884A882A881A400430180000
+323A:000030184034BBC2A84AAA4AA952AFFAB842A8428042804281C2400430180000
+323B:00003018491484A29FFA900A87E2804280829FFA808280828382400430180000
+323C:000030185F2494229F3A91429F52940A9F8280029FF29292BFFA400430180000
+323D:000030184104818282428422889AB08284E28482848284829FFA400430180000
+323E:0000301851048BFA844A9FE28C3A87E2842287E2842287E29C3A400430180000
+323F:00003018488489F28892BE92892289228FFA8AAA8AAA8CCA8912400430180000
+3240:0000301848FC8F9292A2AA4294228BD2900AAFF284A28A92B10A400430180000
+3241:000030184444844288428FFA9842A8E288E289528A4A8C428842400430180000
+3242:00003018420484028FE2882288228FE288228FE2882288228FE2400430180000
+3243:000030185FF48202844288229FF2810281028FE281028102BFF2400430180000
+3244:00003FF84004BEFAA28ABEFAA28ABEFAA00AA7CAA44AA44AA7CAA01A40043FF8
+3245:00003FF8400484428442884293FABE4A844A884A924ABD4A90AA811240043FF8
+3246:00003FF8400482028102BFFA84428442844282828282810286C2B83A40043FF8
+3247:00003FF840049EF2A5229FE289429FE28122BFFA81229FE28102830240043FF8
+3248:0000FC7EE00EC0068872988A088808880888888A888ABE72C006E00EFC7E0000
+3249:0000FC7EE00EC0069C72A28A028802881C88A08AA08ABE72C006E00EFC7E0000
+324A:0000FC7EE00EC0069C72A28A02880C880288828AA28A9C72C006E00EFC7E0000
+324B:0000FC7EE00EC006A472A48A24883E880488848A848A8472C006E00EFC7E0000
+324C:0000FC7EE00EC006BE72A08A20881C880288828AA28A9C72C006E00EFC7E0000
+324D:0000FC7EE00EC0069C72A28A20883C882288A28AA28A9C72C006E00EFC7E0000
+324E:0000FC7EE00EC006BE72A28A028804880488888A888A8872C006E00EFC7E0000
+324F:0000FC7EE00EC0069C72A28A22881C882288A28AA28A9C72C006E00EFC7E0000
+3250:000000000000000077DE491049104910711E4110411041104110411E00000000
+3251:00001FF0200840049C22A262822282229C22A022A022BEFA400420081FF00000
+3252:00001FF0200840049C72A28A820A820A9C72A082A082BEFA400420081FF00000
+3253:00001FF0200840049C72A28A820A82329C0AA00AA08ABE72400420081FF00000
+3254:00001FF0200840049C92A292829282FA9C12A012A012BE12400420081FF00000
+3255:00001FF0200840049CFAA282828282729C0AA00AA08ABE72400420081FF00000
+3256:00001FF0200840049C72A28A828282F29C8AA08AA08ABE72400420081FF00000
+3257:00001FF0200840049CFAA28A820A82129C12A022A022BE22400420081FF00000
+3258:00001FF0200840049C72A28A828A82729C8AA08AA08ABE72400420081FF00000
+3259:00001FF0200840049C72A28A828A828A9C7AA00AA08ABE72400420081FF00000
+325A:00001FF0200840049C72A28A828A8C8A828A828AA28A9C72400420081FF00000
+325B:00001FF0200840049C22A26282228C2282228222A2229CFA400420081FF00000
+325C:00001FF0200840049C72A28A820A8C0A82728282A2829CFA400420081FF00000
+325D:00001FF0200840049C72A28A820A8C32820A820AA28A9C72400420081FF00000
+325E:00001FF0200840049C92A29282928CFA82128212A2129C12400420081FF00000
+325F:00001FF0200840049CFAA28282828C72820A820AA28A9C72400420081FF00000
+3260:00000FF01008200440025FF2401240124012401240124012200410080FF00000
+3261:00000FF01008200440024802480248024802480248024FF2200410080FF00000
+3262:00000FF0100820044FF2480248024802480248024FF24002200410080FF00000
+3263:00000FF0100820044FF2401240124FF24802480248024FFA200410080FF00000
+3264:00000FF0100820044FF2481248124812481248124FF24002200410080FF00000
+3265:00000FF0100820044812481248124FF24812481248124FF2200410080FF00000
+3266:00000FF0100820844082408241424142422242224412480A200410080FF00000
+3267:00000FF01008200443C244224812481248124812442243C2200410080FF00000
+3268:00000FF01008200440024FFA40824082414242224412480A200410080FF00000
+3269:00000FF01008200443E240024FFA4082414242224412480A200410080FF00000
+326A:00000FF0100820044FF2401240125FF24012401240124012200410080FF00000
+326B:00000FF0100820044FE2480248024FE24802480248024FF2200410080FF00000
+326C:00000FF01008200440024FF2400244224222424242425FFA200410080FF00000
+326D:00000FF01008200447E240025FFA400243C24422442243C2200410080FF00000
+326E:00000FF0102820245FA240A2413E41224222442248225022202410280FF00000
+326F:00000FF010282024502250225022503E50225FE240224022202410280FF00000
+3270:00000FF0102820245FA250225022503E50225FA240224022202410280FF00000
+3271:00000FF0102820245FA240A240A25FBE502250225FA24022202410280FF00000
+3272:00000FF01028202440225F225122513E512251225F224022202410280FF00000
+3273:00000FF010282024512251225F22513E512251225F224022202410280FF00000
+3274:00000FF010282224422244224622493E50A2602240224022202410280FF00000
+3275:00000FF0102820244E2251225122513E512251224E224022202410280FF00000
+3276:00000FF0102820245FE242224222453E48A2506260224022202410280FF00000
+3277:00000FF0102827A440225FE24222453E48A2506260224022202410280FF00000
+3278:00000FF0102820245FA240A241225E3E4422482250226022202410280FF00000
+3279:00000FF0102820245FA250225FA2503E50225FA240226022202410280FF00000
+327A:00000FF0102820245FA2402250A2493E49224BE27C224022202410280FF00000
+327B:00000FF010282F2440227FE240224F3E50A250A24F224022202410280FF00000
+327C:00000FF010082E8440BA5E8A44EA4A8A51AA40AA5E2252223EFC10080FF00000
+327D:00000FF010083F6C429A449A4A9A516A400A7F8A440A44FA200C10080FF00000
+327E:00000FE010102388444444444444438440044FE441044104210810100FE00000
+327F:00001FF020085EF48C428C80ED0E0E020D028C828C425EF420081FF000000000
+3280:00001FF020084004800280028012BFFA8002800280028002400420081FF00000
+3281:00001FF0200840249FF280028002800280028012BFFA8002400420081FF00000
+3282:00001FF0200840249FF2800280428FE280028012BFFA8002400420081FF00000
+3283:00001FF020085FF4929292929292929294F2981290129FF2501420081FF00000
+3284:00001FF0200840049FF2810281028FE282228222822282227FFC20081FF00000
+3285:00001FF0220841048002BFFA8002844284228812900AA00A400420081FF00000
+3286:00000FF0100822044202423243C25E02420242024212421221F410080FF00000
+3287:00001FF0200840848482848284428442882288229012A00A400420081FF00000
+3288:00001FF02208420482029FC28242824282428442844A884A503C20081FF00000
+3289:00000FE010102108410441045FF441044104410441044104200810100FE00000
+328A:00001FF0200847F48412841287F28412841287F284128412485430281FF00000
+328B:00001FF02008410489128922894291028282828284428822701C20081FF00000
+328C:00001FF0210841048112BDA285428542892289229112A50A420420081FF00000
+328D:00001FF0210841048102BFFA8102838285428922B11A8112410420081FF00000
+328E:00001FF02108428484428822B7DA81029FF28102892285427FFC20081FF00000
+328F:00001FF021084104810281029FF2810281028102810281027FFC20081FF00000
+3290:000007F0080817F424122412241227F224122412241227F21414080807F00000
+3291:00001FF028484944BDF28A429C429BFAA842A8E289528A4A484420081FF00000
+3292:00001FF022087FFC840287E28C2297E2A42287E284228422446420081FF00000
+3293:00001FF030484844BE42844289F28C429A42A842884288424BFC20081FF00000
+3294:00001FF0240847F484228A429182810287F2BC128412841247F420081FF00000
+3295:00001FF0284869F4BC42A842ABFA8C229BFAA92288A2882248E420081FF00000
+3296:00001FF020185E1493FA9E1292329E5292929F1280129252612420081FF00000
+3297:00001FF0200851F48912BF12831285F28CA29AA2AAAA892A4A1C20081FF00000
+3298:00001FF03218491489229FFA910AA1029FF2811282128412586420081FF00000
+3299:00001FF0248878548892BE9288A28DA29AAAAACA889289924E7420081FF00000
+329A:00000FF010083FFC49124FF249124FF241025FFA410A420A244C18380FF00000
+329B:00001FF0220842048202BFFA8442844288428E82818282625C1420081FF00000
+329C:00001FF030484BFC88A283FABA4A8BFA8AAA8AEA8A1A940263FC20081FF00000
+329D:00001FF02BF8491489F289129BFAAC8A8B528DEA892288C24F3C20081FF00000
+329E:00000FF012083CFC508A508A5E8A508A508A528A5CB25082208410080FF00000
+329F:00001FF030884844A3FA94428442884289F2B0429042904253FC20081FF00000
+32A0:00001FF8200441FABE4189F9890989F989098FF9B10981F94092230C1FF80000
+32A1:00001FF02448444488428FFA9842A8E288E289528A4A8C42484420081FF00000
+32A2:00001FF020085FFC900AA41287E2840287F280129FD2801240A420481FF00000
+32A3:00001FF02008400480029FF28102810289E2890289029FF2400420081FF00000
+32A4:00001FF0210841048102810281F2810281028102810281027FFC20081FF00000
+32A5:000007F0088810842FFA288A288A288A2FFA288A208220821084080807F00000
+32A6:00001FF020087FFC81028102818281428122812281028102410420081FF00000
+32A7:00001FF022084204BFFA8202840287F2888288829082A0824FFC20081FF00000
+32A8:00001FF021084104BFFA8202840287E28C229422A42287E2442420081FF00000
+32A9:00000FF010083FFC520253F254825FFA50825142522254123FFC10080FF00000
+32AA:00001FF0200840849FFA900AA7E280029FFA808288A28892529421081FF00000
+32AB:00000FF0191824A45FFA500A47E2404240825FFA40824082238410080FF00000
+32AC:00001FF03E486844BE7AA282BEA2A812BF0280029FF292927FFC20081FF00000
+32AD:00001FF02108418482428422889AB08284E28482848284825FFC20081FF00000
+32AE:00000FF011082BFC444A5FE24C3A47E2442247E2442247E23C3C10080FF00000
+32AF:00000FF0188829F448927E92492249224FFA4AAA4AAA4CCA291410080FF00000
+32B0:00001FF021087FFC848284F289929A52AD2288A2884288A24B1C20081FF00000
+32B1:00001FF0200840049C72A28A82828CF2828A828AA28A9C72400420081FF00000
+32B2:00001FF0200840049CFAA28A820A8C1282128222A2229C22400420081FF00000
+32B3:00001FF0200840049C72A28A828A8C72828A828AA28A9C72400420081FF00000
+32B4:00001FF0200840049C72A28A828A8C8A827A820AA28A9C72400420081FF00000
+32B5:00001FF020084004A472A48AA48ABE8A848A848A848A8472400420081FF00000
+32B6:00001FF020084004A422A462A422BE2284228422842284FA400420081FF00000
+32B7:00001FF020084004A472A48AA40ABE0A84728482848284FA400420081FF00000
+32B8:00001FF020084004A472A48AA40ABE32840A840A848A8472400420081FF00000
+32B9:00001FF020084004A492A492A492BEFA8412841284128412400420081FF00000
+32BA:00001FF020084004A4FAA482A482BE72840A840A848A8472400420081FF00000
+32BB:00001FF020084004A472A48AA482BEF2848A848A848A8472400420081FF00000
+32BC:00001FF020084004A4FAA48AA40ABE128412842284228422400420081FF00000
+32BD:00001FF020084004A472A48AA48ABE72848A848A848A8472400420081FF00000
+32BE:00001FF020084004A472A48AA48ABE8A847A840A848A8472400420081FF00000
+32BF:00001FF020084004BE72A08AA08A9C8A828A828AA28A9C72400420081FF00000
+32C0:0000107C304410441044107C104410441044107C10441044104410447C940088
+32C1:0000007C184424442444047C044408440844087C104410441044204420943C88
+32C2:0000007C184424442444047C044404441844047C044404440444244424941888
+32C3:0000007C244424442444247C244424443C44047C044404440444044404940488
+32C4:0000007C3C4420442044207C204420443844047C044404440444244424941888
+32C5:0000007C184424442444207C204420443844247C244424442444244424941888
+32C6:0000007C3C4404440444047C084408440844107C104410441044104410941088
+32C7:0000007C184424442444247C244424441844247C244424442444244424941888
+32C8:0000007C184424442444247C244424441844047C044404440444244424941888
+32C9:0000003E232264A224A224BE24A224A224A224BE24A224A224A224A224CA7344
+32CA:0000003E222266222222223E222222222222223E2222222222222222224A7744
+32CB:0000003E232264A224A220BE20A221222122213E2222222222222422244A77C4
+32CC:000000000000000042004204427442887E884288427042404278428400840078
+32CD:000000000000000000000002651A96A494A4F42484188410941C64220022001C
+32CE:0000000000000000008200823C82424442447E444028402842103C1000000000
+32CF:00000000000000004FB8422442224222422242224222422242247A3800000000
+32D0:000003800C60101020082FE840244144418441042208240810100C6003800000
+32D1:000003800C6010102048208841044304450449042108210810100C6003800000
+32D2:000003800C60111021082FE848244824402440442048208811100C6003800000
+32D3:000003800C6010102008200847C44104410441042FE8200810100C6003800000
+32D4:000003800C60101020882FE841844284448448842288218810100C6003800000
+32D5:000003800C60111021082FE841244224444448442288210810100C6003800000
+32D6:000003800C601010220823C84F04410441F44FC42048204810100C6003800000
+32D7:000003800C601010220823E842244424484440442088230810100C6003800000
+32D8:000003800C601010240827E844844884508440842108260810100C6003800000
+32D9:000003800C60101020082FE840244024404440442FE8200810100C6003800000
+32DA:000003800C601010224822484FF44244424442442088230810100C6003800000
+32DB:000003800C601010260821084C044224404440842908260810100C6003800000
+32DC:000003800C60101020082FC840444044408441842248244810100C6003800000
+32DD:000003800C60101022082FE84224424442844204220821E810100C6003800000
+32DE:000003800C6010102008282844244424404440842108260810100C6003800000
+32DF:000003800C601010220823E842244624454448C420A8230810100C6003800000
+32E0:000003800C60101020E82F8840F45F84408440842108260810100C6003800000
+32E1:000003800C6010102208292845244424404440842108260810100C6003800000
+32E2:000003800C60101027C820084FE44084408440842108260810100C6003800000
+32E3:000003800C6010102208220842044304428442442208220810100C6003800000
+32E4:000003800C60111020882FE840844084408440842108260810100C6003800000
+32E5:000003800C601010200821E84E04400440F44F042008200810100C6003800000
+32E6:000003800C60101020082FC840444644418441842248244810100C6003800000
+32E7:000003800C60101020082FC840444084410443442528210811100C6003800000
+32E8:000003800C6010102008202840244024404440842108260810100C6003800000
+32E9:000003800C6010102008228842444424582440042008200810100C6003800000
+32EA:000003800C6010102008280849844E0448044804280827C810100C6003800000
+32EB:000003800C60101020082FE840244024402440442048208811100C6003800000
+32EC:000003800C6010102008220845044884404440242008200810100C6003800000
+32ED:000003800C60111021082FE841044544492441242508230810100C6003800000
+32EE:000003800C60101020082FE840244344408440442048200810100C6003800000
+32EF:000003800C601010230820C8460441844004460421C8201810100C6003800000
+32F0:000003800C60111021082108420442044444442427E8282810100C6003800000
+32F1:000003800C6010102008202840244224414440C420A8230810100C6003800000
+32F2:000003800C6010102FC8220843C45E0442044204220821E810100C6003800000
+32F3:000003800C60121022082FE842244144410441042088208810900C6003800000
+32F4:000003800C6010102008200847E44024404440842FE8200810100C6003800000
+32F5:000003800C601010200827E8402447E44024402427E8200810100C6003800000
+32F6:000003800C60101027C820084FE44024402440442048208813100C6003800000
+32F7:000003800C6010102248224842444244424440442088230810100C6003800000
+32F8:000003800C6010102108250845044514452445442588290810100C6003800000
+32F9:000003800C6010102408240844044424444444842508260810100C6003800000
+32FA:000003800C601010200828E84F244824484449E42E08280810100C6003800000
+32FB:000003800C60101020082FE848244824402440442048208811100C6003800000
+32FC:000003800C60109020882FE8448444845FE440842088208810900C6003800000
+32FD:000003800C60101020082FE840244344408440443FF8200810100C6003800000
+32FE:000003800C60101020082FE8402447E4402440442088230810100C6003800000
+32FF:00007FFE63867DF671867DBE63867FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+3300:7C04040A154A192411201220200000000040004000407C600050004000400000
+3301:3E0002100A500C50085408541058000000003E00027C02040218041018200000
+3302:3E0002400A200C040818086010000000013E2282528A090C0408000800100000
+3303:3E0002000A000C7C080008001000000000000800280028002A002A002C000000
+3304:02000438080018002800087C08000000010281E941240A203020C04001800000
+3305:020004400820180428180860080000000400380008003E000800080010000000
+3306:08003E002208227C021804280848000000002000100002000C00300000000000
+3307:00007CF810081010102010507C8800004022782948248BB00828102060200000
+3308:00003E000800087C080008003E00000010003E001200127C1200120024000000
+3309:04003E4004200C04141824600C00000000003E00020004000800140022000000
+330A:04003E0004000C7C140024000C000000080008001000200022003E0002000000
+330B:10043E0812101230125012102410000024002400240024000400080030000000
+330C:10383E00127C12041204120824300000002000202A202A300228042018200000
+330D:10003E7C124412441244127C24000000240024002400247C0400080030000000
+330E:4100FCBE4A2248224822483E9000000000004000200004001800600000000000
+330F:4080FA5049084802480C48309000000000007C00040004002800100008000000
+3310:20407D2010807C001000080008000000020407D2024802400240024004800000
+3311:4080FA5C2100F8002000103E100000000000000000007C000000000000000000
+3312:10003E0008003E380808047C04000000240024002400247C0400080030000000
+3313:4080FA442114F814201510151016000040807A404900A83E1800100060000000
+3314:10003E0008003E0008000400040000000000007C004400440044007C00000000
+3315:20007CF810887C88108808F80800000041327482527490141015202740410000
+3316:4002FBC22242FA54224813D410200000020002080228FB2802AA022A022C0000
+3317:10003E3E08223E220822043E040000000008F8088AA88AAC082A104861880000
+3318:408C7A40491E88020802100460080000100010002000400044007C0004000000
+3319:408C7A40491E8802080210046008000022002210420883028A8CFA300A000000
+331A:20003C2024A044A004A808A830B000004110FCAF4A4950C941494049384F0000
+331B:10001E7C124422440244047C180000000010007C00083E100038005400100000
+331C:10001E002400047C040004000800000000003E00020004000800140022000000
+331D:00003E1002500250025402543E580000080008003E0008000800100020000000
+331E:00003E000200027C020002003E00000008403EA008A02A402A00080018000000
+331F:14043E0814101430045008101010000010001E10125022500254045418580000
+3320:14003E401420140404180860100000001008E0082010FBA02022203E40020000
+3321:20901490449024900810702000C00000010281E941240A203020C04001800000
+3322:10003E4012201404101810600E0000000400380008003E000800080010000000
+3323:10003E4012201404101810600E00000010001000100018001400100010000000
+3324:40807A404900A83E180010006000000000007C00040008001000280044000000
+3325:1C2000903E400800080008001000000000200014004400240008007000000000
+3326:2100248022003000280020002000000000000010005000500054005400580000
+3327:1000100010001800140010001000000000000040002000040018006000000000
+3328:080008003E000800080010002000000000000008000800080008001000200000
+3329:040004000454045404040808103000000800080008000C000A00080008000000
+332A:0004000814101230125022100010000000002A002A0002000200040018000000
+332B:010002805280493E48008800000000004008FA084908502C40CA430838080000
+332C:010002805280493E480088000000000000005400540004000400080030000000
+332D:010004805200483E48008800000000000000402040A044A048A850A860B00000
+332E:813E9A82E28A810C80088008781000000200FA080A28132822AA522A8A2C0000
+332F:81109A9EE2928122800280047818000000001000500050005400540058000000
+3330:204026A038A02040200020001E0000000000007C0004000400040004007C0000
+3331:40404D2070804000400040003C00000000000010005000500054005400580000
+3332:00007C0004F804080430082030400000E0220029EAA42AB020A8412086200000
+3333:00003E000208021002300450181000000020002000203E300028002000200000
+3334:0100F480122A102A10022004C01800004000280488144FD41115E11507D60000
+3335:00383E00027C0204020404081830000000002000100002000C00300000000000
+3336:00402078504808880408001000600000400078044814ABD41815101560160000
+3337:0100228052800900040000000000000000000024001400140004000800300000
+3338:0100229C528009000400003E000000002000260038002000200020001E000000
+3339:0000101028500450025400540058000000002A002A0002000200040018000000
+333A:010022A052900902040C00300000000000003E00020004000800140022000000
+333B:010022805280093E040000000000000020401520448024000800700000000000
+333C:010024805200083E040000000000000010001E0012002A000600040018000000
+333D:10827D4411485498542810083008000000202020102002300C28302000200000
+333E:10407D2410945414541510153016000010001000100018001400100010000000
+333F:08003E0008002A002A0008001800000000000040002000040018006000000000
+3340:10807D5011485482540C10303000000010801240110018001400100010000000
+3341:08003E0008002A7C2A0008001800000000000800280028002A002A002C000000
+3342:08003E0008002A7C2A0008001800000000002000100002000C00300000000000
+3343:00043E0802100230145008100410000010001E7C124402440244047C18000000
+3344:00043E0802100230145008100410000000000800280028002A002A002C000000
+3345:00003E0002540254140408080430000000000000140012001200220000000000
+3346:00003E1002500250145408540458000010001E00120022000200040018000000
+3347:00007C8004400408283010C008000000000040202B9088824B8C10B0E3800000
+3348:1820043C30240844000430080C30000000003E402220220422183E6000000000
+3349:1800040030000800000030000C00000000480048004800480008001000600000
+334A:1848044830480848000830100C600000010004845214481449D5881500160000
+334B:04000400040028001000280040000000020407D2024802400240024004800000
+334C:09020BE90924512021205120824000002000208020403008283020C020000000
+334D:020002000200147C080014002000000010001010105018501454105410580000
+334E:100010003E00127C140010001000000021002480220030002800200020000000
+334F:100010003E00127C140010001000000000000800280028002A002A002C000000
+3350:007C1C040414041804103E100020000000002000100002000C00300000000000
+3351:2400240024542454040408083030000010001010105018501454105410580000
+3352:2400240024002400040008003000000000380000007C00040004000800300000
+3353:1102513551C551025500550058F000000000000000007C000000000000000000
+3354:000008002800287C2A002A002C0000000080FA44091408140815101560160000
+3355:0000200020002200240028003000000000100010002000400044007C00040000
+3356:0000408040404408483050C06000000088208E949442C400A401840688180000
+3357:00003E0022542254020404081830000010001000100018001400100010000000
+3358:001018102410241E24102410247C244424442444247C24442400245418AA00AA
+3359:001010103010101E10101010107C104410441044107C1044100010547CAA00AA
+335A:001018102410241E04100410087C084408441044107C1044200020543CAA00AA
+335B:001018102410241E04100410047C184404440444047C04442400245418AA00AA
+335C:001024102410241E24102410247C3C4404440444047C04440400045404AA00AA
+335D:00103C102010201E20102010207C384404440444047C04442400245418AA00AA
+335E:001018102410241E20102010207C384424442444247C24442400245418AA00AA
+335F:00103C100410041E04100810087C084410441044107C10441000105410AA00AA
+3360:001018102410241E24102410247C184424442444247C24442400245418AA00AA
+3361:001018102410241E24102410247C184404440444047C04442400245418AA00AA
+3362:001026106910291E29102910297C294429442944297C29442900295476AA00AA
+3363:001022106610221E22102210227C224422442244227C22442200225477AA00AA
+3364:001026106910291E21102110227C224422442444247C2444280028547FAA00AA
+3365:001026106910291E21102110217C264421442144217C21442900295476AA00AA
+3366:001029106910291E29102910297C2F4421442144217C21442100215471AA00AA
+3367:00102F106810281E28102810287C2E4421442144217C21442900295476AA00AA
+3368:001026106910291E28102810287C2E4429442944297C29442900295476AA00AA
+3369:00102F106110211E21102210227C224424442444247C24442400245474AA00AA
+336A:001026106910291E29102910297C264429442944297C29442900295476AA00AA
+336B:001026106910291E29102910297C264421442144217C21442900295476AA00AA
+336C:000863089488948F1488148824BE24A224A244A244BE44A2848084AAF3550055
+336D:000862089608920F12081208223E222222224222423E42228200822AF7550055
+336E:000863089488948F10881088213E212221224222423E42228400842AF7D50055
+336F:000863089488948F1088108820BE232220A240A240BE40A2848084AAF3550055
+3370:000864889488948F1488148824BE27A220A240A240BE40A2808080AAF0D50055
+3371:0000000043C042204220422053CC6A124A024A0E4A124A124A164A0A00000000
+3372:0000000002000200020002003A3C46424202423E4242424246463A3A00000000
+3373:000000000842144214421442224222423E422242414241424142413C00000000
+3374:00000000400040004000400071944A5A485249D04A504A504AD0715000000000
+3375:0000000000820082008200827882844484448444842884288410781000000000
+3376:0000000000000000000000005C3C6242424042404240424062425C3C40004000
+3377:0000000001000100010001001D682354415441544154415423541D5400000000
+3378:001E0002021E0210021E02003AD046A882A882A882A882A846A83AA800000000
+3379:001E0002020E0202021E02003AD046A882A882A882A882A846A83AA800000000
+337A:000000007C8410841084108410841084108410841084108410847C7800000000
+337B:0000000A0009FE091008927F524854481078FE551055109510D610B5110A0010
+337C:00001E300AEEEA4AAAFAAA4AEA4AB6CAA0EAAEDAEB4AAA4A0E4E0A4A00000000
+337D:0000000010FE10101010FE5010501050285E2850285044504450445082FE0000
+337E:000000010E81EA42AA02AA94EE55AA17AA21AA20EE6FAA290A29122F26290000
+337F:2A057F842A3F7702A23A27122AB90000104428F4441EBA2400D4FE4424447A5F
+3380:0000000000100028002800285C446244427C4244428262825C82408240004000
+3381:00000000001000280028002858446444447C4444448244824482448200000000
+3382:00000000001000280028002811441144117C12442282228222823D8240004000
+3383:00000000001000280028002868445444547C5444548254825482548200000000
+3384:00000000801080288028802884448844907CA044D08288828482828200000000
+3385:00000000407C4042404240424242447C48425042684244424242417C00000000
+3386:00000000417C4142634263425542557C49424942414241424142417C00000000
+3387:000000003C7C42424242404240424E7C424242424242424246423A7C00000000
+3388:00000000000C00040004000471E48A14801481F4821482148A3471DE00000000
+3389:00000000800C80048004800493649494A414C474A49494948CB48F5E00000000
+338A:0000000000FE0080008000805C8062F842804280428062805C80408040004000
+338B:0000000000FE00800080008058F8648044804480448044804480448000000000
+338C:00000000007E004000400040227C2240224022404440444044407B4080008000
+338D:00000000000000000000000411341148114811482230222022383DC440444038
+338E:0000000000000000000000086868549054905490546054405470548800880070
+338F:0000000040004000400040044234444848485048683044204238414400440038
+3390:000041004100410041004100413E7F0241044108411041204140417E00000000
+3391:000084408440844084408440945E97C2A444C448A44894508C608C7E00000000
+3392:00008A408A40DA40DA40AA40AA5E8BC28A448A448A488A488A508A5E00000000
+3393:0000000072408A408A408240825E83C29E448A448A488A488A507A5E00000000
+3394:00000000FC8024802480248024BE2782248424882488249024A024BE00000000
+3395:00000000000800140014002411281148114822502252226222645DD840004000
+3396:000000000008001400140024762849484948495049524962496448D800000000
+3397:0000000002080214021402243A284648424842504252426246643BD800000000
+3398:000000004008401440144024422844484848505068524462426441D800000000
+3399:000000001C0022002000200078C8213421242124212421242124212400000000
+339A:00000000000000000000000059D8652445244524452445244524452400000000
+339B:00000000000000000000000022A422DA229242924492449244927B9280008000
+339C:00000000000000000000000034682A542A542A542A542A542A542A5400000000
+339D:0000000000000000000000001C682254405440544054405422541C5400000000
+339E:0000000040004000400040004268445448545054685444544254415400000000
+339F:001E0002001E0010001E000068D054A854A854A854A854A854A854A800000000
+33A0:001E0002001E0010001E000038D044A880A880A880A880A844A838A800000000
+33A1:003C0004003C0020003C00002CC0332022202220222022202220222000000000
+33A2:001E0002801E8010801E800084D088A890A8A0A8D0A888A884A882A800000000
+33A3:001E0002000E0002001E000068D054A854A854A854A854A854A854A800000000
+33A4:001E0002000E0002001E000038D044A880A880A880A880A844A838A800000000
+33A5:003C0004001C0004003C00002CC0332022202220222022202220222000000000
+33A6:001E0002800E8002801E800084D088A890A8A0A8D0A888A884A882A800000000
+33A7:0002D004A808A810A820A840A880A978AA840280047808041084207840008000
+33A8:0010D02EA822A84EA888A88EA900AA78AC840480087810041084207840008000
+33A9:000000007C0042004200420042F07D08400840F841084108411840E800000000
+33AA:0000000081C0812081208120853C89C29102A11ED12289228526831A00000000
+33AB:0000000089C08920D920D920A93CA9C28902891E892289228926891A00000000
+33AC:0000000071C0892089208120813C81C29D02891E892289228926791A00000000
+33AD:0000000000020002000200025B1A64A640A247A248A248A249A646DA00000000
+33AE:008200840084B188CA889A90AA90AAA0AAAC9DD20090010C01020212040C0800
+33AF:0090009E0092B1AECAA89AAEAAC0AAC0AA989DA400A001180104022402180400
+33B0:0000000000000000000000005C786284428042704208420462845C7840004000
+33B1:0000000000000000000000005878648444804470440844044484447800000000
+33B2:000000000000000000000000113C1142114011382204220222423DBC40004000
+33B3:0000000000000000000000006878548454805470540854045484547800000000
+33B4:000000000104010401040104B904C488848884888450C450B820802080008000
+33B5:0000000001040104010401045888648844884450445044204420442000000000
+33B6:00000000008200820082008222822244224422444428442844107B1080008000
+33B7:00000000008200820082008234822A442A442A442A282A282A102A1000000000
+33B8:000000008104810481048104850488889088A088D05088508420822000000000
+33B9:0000000082828282C682C682AA82AA4492449244822882288210821000000000
+33BA:000000000222022202220122591465144494449444B464C85848404840004000
+33BB:000000000222022202220122591465144494449444B444C84448444800000000
+33BC:000000000222022202220122251425142494249448B448C84848764880008000
+33BD:000000000222022202220122691455145494549454B454C85448544800000000
+33BE:000000008222822282228122851489149094A094D0B488C88448834800000000
+33BF:0000000083228322C722C722AA94AA949294929482B482488248824800000000
+33C0:000000004070408841044104490449045104610450884888465247DE00000000
+33C1:0000000088708888D904D904A904A90489048904888888888A528BDE00000000
+33C2:00000000000000000000000030D048A808A838A848A848A858A82AAA00000000
+33C3:000000003C0022002200220022343C4C224421442144214C22343C0400040004
+33C4:0000000000000000000000001C382244408040804080408022441C3800000000
+33C5:0000000400040004000400043C74428C4084408440844084428C3C7400000000
+33C6:001070208840808081008A0076010A4D125222924312828C0248024E0011000E
+33C7:000000003C0042008100800080708088808880888088818842883C7200000000
+33C8:0000000004F804840484048474848CF884848482848284828C8474F800000000
+33C9:000000001E0021004100400040424042402243A44114411823081D1000100060
+33CA:0000000020002000200020002C7832842204227C22842284228C227400000000
+33CB:00000000427C42424242424242427E7C42404240424042404240424000000000
+33CC:00000000000010001000000030B810C4108410841084108410847C8400000000
+33CD:000000008282848488889090A0A0C0C0C0C0A0A0909088888484828200000000
+33CE:0000000045044504458C498C5154615451244924450445044504450400000000
+33CF:0000000040004020402040204278442048205020682044244224411800000000
+33D0:000000006000200020002000200021D821242124212421242124F92400000000
+33D1:000000006000200020002000217821842104210421042104F904000000000000
+33D2:000000006000200020002002271A28A428A428A428982890289CF7220022001C
+33D3:0000600020002000200020002204210820902060206020902108FA0400000000
+33D4:00000000008000800080008034B82AC42A842A842A842A842AC42AB800000000
+33D5:000000000018008800880008698854885488548854885488548857FE00000000
+33D6:00000000000C000400040004D1C4AA24AA24AA24AA24AA24AA24A9DF00000000
+33D7:000000007C4242424242424242427C7E40424042404240424042404200000000
+33D8:00000000000000000000000058D064A844A844A844A878A840A844AA40004000
+33D9:00000000E72294A294B694B694AAE72A84228422842284228422842200000000
+33DA:000000007C7C42424242424242427C7C40484048404440444042404200000000
+33DB:0000000000000000000000003C2C4232402038200420022042203C2000000000
+33DC:000000001E0021004000400030820C82034400C400A840A821101E1000000000
+33DD:0000000088A088A088A088A044BC45224D224D22552222222222223C00000000
+33DE:000000022204220822102220144014B4092A0A2A042A082A102A202A40000000
+33DF:00000802140422083E102220224022B4012A022A042A082A102A202A40000000
+33E0:0000107C30441044104410441044107C10441044104410441044107C7C440044
+33E1:0000187C24442444044404440844087C08441044104410442044207C3C440044
+33E2:0000187C24442444044404440444187C04440444044404442444247C18440044
+33E3:0000247C244424442444244424443C7C04440444044404440444047C04440044
+33E4:00003C7C20442044204420442044387C04440444044404442444247C18440044
+33E5:0000187C24442444204420442044387C24442444244424442444247C18440044
+33E6:00003C7C04440444044408440844087C10441044104410441044107C10440044
+33E7:0000187C24442444244424442444187C24442444244424442444247C18440044
+33E8:0000187C24442444244424442444187C04440444044404442444247C18440044
+33E9:0000267C69442944294429442944297C29442944294429442944297C76440044
+33EA:0000227C66442244224422442244227C22442244224422442244227C77440044
+33EB:0000267C69442944214421442244227C22442444244424442844287C7F440044
+33EC:0000267C69442944214421442144267C21442144214421442944297C76440044
+33ED:0000297C694429442944294429442F7C21442144214421442144217C71440044
+33EE:00002F7C684428442844284428442E7C21442144214421442944297C76440044
+33EF:0000267C694429442844284428442E7C29442944294429442944297C76440044
+33F0:00002F7C61442144214422442244227C24442444244424442444247C74440044
+33F1:0000267C69442944294429442944267C29442944294429442944297C76440044
+33F2:0000267C69442944294429442944267C21442144214421442944297C76440044
+33F3:0000633C94A494A414A414A424A424BC24A444A444A444A484A484BCF3240024
+33F4:0000623C96249224122412242224223C22244224422442248224823CF7240024
+33F5:0000633C94A494A410A410A42124213C21244224422442248424843CF7A40024
+33F6:0000633C94A494A410A410A420A4233C20A440A440A440A484A484BCF3240024
+33F7:000064BC94A494A414A414A424A427BC20A440A440A440A480A480BCF0A40024
+33F8:000067BC94249424142414242424273C20A440A440A440A484A484BCF3240024
+33F9:0000633C94A494A4142414242424273C24A444A444A444A484A484BCF3240024
+33FA:000067BC90A490A410A411242124213C22244224422442248224823CF2240024
+33FB:0000633C94A494A414A414A424A4233C24A444A444A444A484A484BCF3240024
+33FC:0000633C94A494A414A414A424A4233C20A440A440A440A484A484BCF3240024
+33FD:0000633C94A494A414A414A414A464BC14A414A414A414A494A494BC63240024
+33FE:0000623C96249224122412241224623C12241224122412249224923C67240024
+33FF:00000000000C00040004080469C49224902491E462244224726489AE88007000
+3400:0440044004400440044004407C7C0440044004400440044004400440FFFE0000
+3401:0000FFFE010001003FF82108210821082288224824282828200820083FF82008
+3402:0100010001F83F000104010400FC100010201020163CF8E010221122161E1800
+3403:0100028004400820101020084004FFFE01000100010001000100010001000100
+3404:01000100010001003FF801002100210041007FFE010001000100010001000100
+3405:0000001000102020102008400440028001000280044008201010200840000000
+3406:001000F81F0010001FF810081FF810081FF810001FFC10042004200440288010
+3407:020002003FE00420042008223022C01E00007FF0006001800600180420041FFC
+3408:060001000280044008203018C0063FF80010006001800600180420041FFC0000
+3409:00007FFC01000100010001000100050002007FF0006001800600180420041FFC
+340A:010001000100FFFE010001003FF8000000007FF0006001800600180420041FFC
+340B:0100010001003FF801000100FFFE000000007FF0006001800600180420041FFC
+340C:080008001FFC200041008100117013901D10F11011501122110210020FFE0000
+340D:00FC7F00020821081110102000003FF80010006001800600180420041FFC0000
+340E:020001007FFC0820044003801C70E00E00003FF80010006003801C0420041FFC
+340F:00003FFC010001001FF0021004107FFE00007FF0006001800600180420041FFC
+3410:10001000FEFC22844488285010202858C58600007FF0006003801C0420041FFC
+3411:08001FF0282007C01830E18E0C40030000807FF0006001800600180420041FFC
+3412:00007FF8040808503020DFF8100810081FF800007FF0006003801C0420041FFC
+3413:0000FFFE00101F90109010901F90005000207FF0006001800600180420041FFC
+3414:02000100FFFE00001FF0101010101FF000007FF0006001800600180420041FFC
+3415:010001003FF8210821083FF8210821083FF800007FF0006003801C0420041FFC
+3416:082008200820FFA0082008207F20002000207F204120412241227F22411E0000
+3417:02083FD00220FFFE02000C703F84C80407FC00007FF0006003801C0420041FFC
+3418:010011100920FFFE054009203118C10600007FF0006001800600180420041FFC
+3419:00007FFC00001FF010101FF008200440FFFE00007FF0006003801C0420041FFC
+341A:7FFC02003FF00410FFFE00001FF010101FF000007FF0006003801C0420041FFC
+341B:0840084017FC3080510093F81508110811F800007FF0006003801C0420041FFC
+341C:1040144012401040FEF8104810489248544810483848548A928A110A52062400
+341D:11001100F9F8120819E83128D1E81008505020207FF0006003801C0420041FFC
+341E:082008207FFC08200FE008200FE00820FFFE10102FE8404483820C0810080FF8
+341F:044004407C7C04403C7804407C7C044004407FF0006001800600180420041FFC
+3420:07A0F82048A025207F20022007A2FC2244220C1E00003FF001C01E0420041FFC
+3421:200027FC204023F8FAA82AA82AA82A1828402FFC28A029122A0A480247FE8000
+3422:203C17C08244492813F8E01027FE202020A000407FF0006003801C0420041FFC
+3423:00803FFE20802FF8208027F0249027F024903FFC20802FF840604380840403FC
+3424:204023F8204021F0F91029F0291029F0291029F029102BFA28A2491247FE8000
+3425:100829C8455EB94A11CA7D4A11CA55523D6AE38400003FF001C01E0420041FFC
+3426:3BB822083BB82488FFFE10502788C1061FF0010003003FF001C01E0420041FFC
+3427:0080108008800480048000807FFC01840288049008803080C080008002800100
+3428:00007CFC0404282810100808FEFE121214141010101010101010101050502020
+3429:24242424242424247E7E242424242424FEFE2424242424242424444444448484
+342A:020001000100FFFE0000010021082108210821083FF80288044008203018C006
+342B:020001000100FFFE00000820044022882108228824482828200820083FF80008
+342C:02000100FFFE0400082010103FF810080000111011101110211021124112800E
+342D:02000100FFFE000000003FF82008200827C82448244827C8200820083FF82008
+342E:02000100FFFE1010244844441FF004401FF004407FFC04900C603518C6060400
+342F:01007FFC08201FF010101FF000001FE001007FFC09203FF8C8260FE008200FE0
+3430:080009FC0904110411043104310451049104110411041104110411FC11041000
+3431:0100010002800440082010502188C606382000C007003818006003807C000000
+3432:0840084008401040104037FE30405040904010A010A010901110110812041402
+3433:080008000BFC10901090309030905090909010901090109211121112120E1400
+3434:08800880088010FC110431043284544890281010101010201040108011001600
+3435:08000BFC08401040104030403FFE504090401040104010401040104011401080
+3436:080008000BFC120412043204320453FC92041200120012021202120211FE1000
+3437:08000FF00810101012103210321053FC90041004100417F41004100410281010
+3438:08800880088010FC1104310832405440904010A010A010901110110812041402
+3439:0900090009FC1200140031F83000500093F8100810081008100A100A10061002
+343A:1120112011202220222066206620AA2022202250225022502248228822842302
+343B:082008200820102013FE3222322252229252124A128A130212021202120A1204
+343C:080808680B88108810883088308853FE90881088108810881108110812081408
+343D:08000BF80A081208132832A832A85248924812A812A8132A140A140A18061002
+343E:080008000BF810001000300037FC5120912011201120112012221222141E1800
+343F:081008780BC01040104033F830405040904017FE104010401040104011401080
+3440:084008400840104017FE3040304050A090A010A0111011101288124814441802
+3441:084008400A4812481248324833F8504890401040144414441444144417FC1004
+3442:100017FC10402040204067FC6444A44424A42494251426042404240424142408
+3443:1220122012202420257C69246E24A2242424242429242F242144204420942108
+3444:080009F8090811481128312837FE520892481228122813FE1008100810501020
+3445:09000900090011FE1240324034405040907C1040104010401040104017FE1000
+3446:08000BFC0A0412041204320433FC5090909010901090111211121212140E1800
+3447:0880088008F811081210342033FC50049004100411FC10041004100413FC1004
+3448:08400840084017FE108031203120522093FC1020112811241222142210A01040
+3449:100017F81408240827F864886488A4E82528252826A8244A244A288A29063202
+344A:08400820082017FE109030903090529492921292149210901110111012501420
+344B:10A010A010A020A027FC64A464A4A4A424A427FC24A424A424A424A427FC2404
+344C:08000BFE0A00120013FC3220322052F892201220122013FC1200120013FE1000
+344D:1040104017FC2040204063F86040A04027FE20E0215021502248244428422040
+344E:1000124812482490249062486248A00020402444244424442444244427FC2004
+344F:084008200BFE120214143010301053FE90101110109010901010101010501020
+3450:084008400840107C1040304037FE500090401040125012481444184411401080
+3451:08400840088013FC12043204320453FC9204120413FC12041204120413FC1204
+3452:01000280044008203018CFE6010001001FF0111011101FF0028004401830E00E
+3453:082008400888110413FE3042304057FE908010FC114411441228121014681186
+3454:08000BFE0820104011FC31043104512491241124112411441050108811041204
+3455:082008200A221222122233FE3040504090FC1104128414481050102010C01700
+3456:111011101110221022FE66926692AA92229222FE229222102210221022102210
+3457:088009000BF8120813F8320833FA520A920C17F810181028104811881E281010
+3458:1014101210102FFE201062906292A2922FD2229422942288228A249A24262842
+3459:10001FFE14802490249067906490A490249027902490249224D22F92208E2080
+345A:100017DE12522252225467D46258A25422522FD22252225A2254245025502890
+345B:084008400FFE1040104037FC3444544497FC104010E0115012481C4610401040
+345C:1208121C126022402FC06240627EA2C823482E4822482248224822482A882508
+345D:100017FC1040204023F860406040A7FC211021102FFE21102110221022102410
+345E:104010401244224424A861106208AC06211021102FFE21102110221022102410
+345F:0808081C09E01100110031FE311051109110111017FE10001090110812041402
+3460:08800AFC0AA412A412A8329032A850C69020102011FC10201020102013FE1000
+3461:100017BC14A424A424A467A464A4A4A424A427A42434252824A0256026202020
+3462:09000900091E139211123112311257D291121112121A129417D0125010101010
+3463:091009100910111017BC31103110533893B81554155419921110111011101110
+3464:120812081FFE22082208600067FCA4442444244427FC24442444244427FC2404
+3465:08000BF80A0813F8120833F83100510093FC1494189411241244148411281210
+3466:084008200BFC1204120433FC32005228922413FE122012501250148815041A02
+3467:103813C0104027FC20E061506248AC4623F02020204027FC2040204021402080
+3468:08000BF80A08120813F83100310053F8944010401FFE104010A0111012081C06
+3469:08000BFE0A521252125233FE3020504090FC1104128810501020104011801600
+346A:084008200FFE11081090306031985606910811F8110811F81108110812081408
+346B:0840084008A011101288344633F0501090A01040114815041514151418F01000
+346C:12101210121022102F7E65106510A510257C29442544224422442544257C2844
+346D:100017FC1444244427FC64446444A7FC200020002FFE22082208220824082808
+346E:08000BFE0A22102013FE302031FC512491FC112411FC102013FE102010201020
+346F:08000FFE0840108013FC3204320453FC920413FC1204120413FC100011081204
+3470:090009F80A0813F0101037FE30805144966810B01128166810A4112216A01040
+3471:08000BF80890106017FC30A4312852209460104017FC10E0115012481C461040
+3472:104010401FFE2040204067FC6514A4A425F42444244425F42444244424542408
+3473:090009000BFE1442125233F230825114960813FE14421A5213F2108211141608
+3474:0BF8080809F8100813F8300037FC544493F812481258104013F8111010E0171E
+3475:0820081009FE110011203520333C51509190131015FE11101128122812441482
+3476:0900090009FC120015F8300033F8508892A811C817F8108A11CA16AA10861082
+3477:11101212145427D82010601267D2A44E244027D22454245827D024522552248E
+3478:084008400FFC104013F8320833F850009FFE100813E8122813E8100810281010
+3479:0100028004400FE03118DFF611101FF011101FF000000FE008200FE008200FE0
+347A:08A0089009FE132015FC312031FC512091FE110013FC1088109E1102120A1404
+347B:1080104017FE2402289460506524A54A28FA2300204024442444244427FC2004
+347C:10101010103C2FA42AC46AA86A90AFA82AC62A802ABC2AA42FA428A4203C2024
+347D:1040144412482FFE280263F86208A20823F82040204027FC204020402FFE2000
+347E:084008FC09081650112030C033205FFE900013FC100013FC100013FC120413FC
+347F:124814901248200023F8624863F8A24823F8204027FC20E0215022482C462040
+3480:1080104017FC211020A067FC6444A5F4244425F42514251425F4240424142408
+3481:100017FC1444244425F4644467FCA51424A425F4244427FC2444244427FC2404
+3482:090809080FFE1108104433F43048505097FE108011FC130415FC190411FC1104
+3483:08140BFE081013D0101033D0301053D0925013D0125013C8124A13CA11861242
+3484:0910091409D21250127E3550309052A89128114412441482100812A412521452
+3485:08200BFE084010F81348303033D0503C91C41048103013C410A8119016A810C6
+3486:084008A0091816E6100033F8320853F8900017BC108414A4129414A412941108
+3487:1100110013FC26A82AA862A867FCA2A822A822A82FFE200022A8225424542000
+3488:10081788108821102FDE649464A4A79424942794249424C827882C9420A420C2
+3489:08400A48095017FC140431F03110511091F0104017FC10E01150124814461040
+348A:100017BC129426B42AD464A465ACA8402108210825A8252C252825A82E7E2000
+348B:14801482149C2FD024906790649EA794249424942FD42014251428A430242044
+348C:1110155415B8291022A864446000A7FC240429E821202120212022222422281E
+348D:088009100BF8121014A437BC3080511093E01040108817FC1044124815441080
+348E:08000BF8088017FC111032083CA650A097BC10A013B810A017BC10A010A010A0
+348F:084008200FFE149213FC309033FC509097FE1108120414621010118010601010
+3490:0910091009DE12A81444310031FC520495F4111411F4111411F4111410281010
+3491:100017FE14282624257E644864C8A47E2648257E24482448257E264027FE2000
+3492:10A014A412A820A027FC611060A0A7FC204023F8204027FC215022482C462040
+3493:10101410127C201020FE60446628A2FE2210227C221022FE2210221025FE2800
+3494:100017FC14A424A427FC620063FEA4422BFA224A23FA2052207A278A22142008
+3495:1040102017FE20282224627E64C8A748217E224824C82F7E21482248247E2840
+3496:1110111017FC211023F8624863F8A24823F8204027FC2444245425F42414240C
+3497:111017FC111021F0211061F06110A7FE24022BFC211023F8204023F8204027FC
+3498:100017BC15142794248867886514A7A22080204027FC2000220821102FFE2000
+3499:11081110123E22A224BE6F22613EA20824BE2FAA20AA202A2AAA2AAE28082008
+349A:103E17C01244212823F8604067FCA00023F8200823F8200823F82544252A28FA
+349B:100017BC108424A4229464A46120A21027FC2A2023FC222023FC222023FE2200
+349C:09400A4C0A641244134C326432A453AC92A412A417FE10001110110812041404
+349D:09080FFE0908100013FC3294329453FC902813FE1220132412A81292142A18C6
+349E:08200A220BFE109011FE331035FE511091FE111011FE110013DE125212721206
+349F:104017FE100023FC224063F86240A3F8224023FC2004255420A823102D482186
+34A0:110011BC152427A824906AA86146A2A027BC20A023B820A027BC20A02FFE2000
+34A1:11821E3C10882A902522643C6788AA12223E2F8822082AAC2AAA2BCA2EA82090
+34A2:104010A0111022082DF660006EEEAAAA2EEE20002FFE29222FFE2922292A2804
+34A3:1040102017FE24A824FE6550677CA550257C2550257E254028A42A8A328A2478
+34A4:0BFC090809F8110811F8310E37F8500897FE1294139C1294139C12D617BC1084
+34A5:115013F8155427FC255467FC6554A7FC200027FC200023F8220823F821102FFE
+34A6:17FC144417FC244427FC60006FBEAAAA2FBE2AAA2FBE2040204027FC20402FFE
+34A7:141812141F90253E2AA86DE868BEAFA822282FBE2AA82AA82BA828BE2AA02920
+34A8:104015F6191229B22D5669B26912ADF620802FFE220825F4291221F0210420FC
+34A9:11F0121013E0202027FC61886650A1A8266421A022482FBE2AAA2FBE228A2FBE
+34AA:03800C603EF8E8A63EF822883EF828A03EF8100011FC5CA0515450B85D54E0B2
+34AB:00000FF8080008000FF008000800FFFE0440044004400440084408441044603C
+34AC:00007DFC002000200020FCF8282028202820282029FC28002800480247FE8000
+34AD:00003E7C22442244224422443E7C1428142814281428144A254A268A44868100
+34AE:000001FE7820004000A20334FC5828942B34285228922B502822480247FE8000
+34AF:108813FE9088540059FC10A8FCA82BFE28A828A829FC28202BFE4C2048208020
+34B0:060001000280044008203018C00600001FF0010001000100010001007FFC0000
+34B1:060001000280044008203218C20607F00810141022200140008003001C00E000
+34B2:060001000280044008203018DFF61010101010101FF01010101010101FF01010
+34B3:00007FFC4104410441045144492449245554638C410441044104410441144108
+34B4:060001000280044008203118D116111011101FF001002108210821083FF80008
+34B5:040008003FF8200820083FF8200820083FF80000000004400820101020084004
+34B6:04400440082010102108C2061FF01010101010101FF01010101010101FF01010
+34B7:00001FF0101011101110111012901450101010107FFC00000440082010102008
+34B8:0820042004407FFC020006001908629004A018C061A002980C863080C2800100
+34B9:10101010FEFE10107C7C44447C7C44447C7C44447C7C4444FEFE282844448282
+34BA:00007FFC4004482444445FF440044884488449444A2448044FF4400440144008
+34BB:7FFC40045FF440045FF400001FF010101FF010101FF010101FF004421842E03E
+34BC:08200820FFFE082008200FE001007FFC4104514449245554638C410441144108
+34BD:3FF820082FE820082FE8111009207FFC0400FFFE10102FE8C82608A0084807F8
+34BE:00003FF820082FE820082FE820401040FEFE21203CAC24F427A444AC54A2887E
+34BF:3FF820082FE820082FE808007F281424497E55C87F7E08487F7E55485D7E4340
+34C0:00007FFE40028004020002000200020002800240022002100200020002000200
+34C1:000000007FFE4002844408201010000000000000000000000000000000000000
+34C2:00007FFE400280243E2001FE00447E4414C814281410146A2586240243FE8000
+34C3:00007FFE4002900408007F1C00E03E2000203E3E01E03E22222222223E1E2200
+34C4:101022107F10421094FEF79208923610C92830A8C428192862480C4A308AC106
+34C5:0000400023FE202000200820082010201020E020202020202020202020A00040
+34C6:0040404020A020A001100A080C0611101120E140218021002104210420FC0000
+34C7:0010407827C0204000400840084017FE1040E0A020A021102110220824040802
+34C8:0000400027FE204000400880088011F81308E508290821082108210821F80108
+34C9:0010407823C02040004007FE104010402040E3F8220822082208220823F80208
+34CA:000047FC2404240405F40404140415F42514E514251425F42404240424140408
+34CB:011041102110211007FC0110111011102110EFFE200021102108220824040804
+34CC:0040404020A021100208040613F810402040E04023F820402040204027FE0000
+34CD:00804040204027FE00800110120817FC2124E1202120212022222222241E0800
+34CE:000043F8200821F800080BF8080017FC1404E3F02110211020A0204021B0060E
+34CF:000047FC240424A40514060C140415F42514E514251425F42514240424140408
+34D0:0040404023F82040004007FC111012082444E04023F820402040204027FC0000
+34D1:0040404027FC204000400FFE111010A027FCE04020402FFE2040204020400040
+34D2:2040104004780BC47044103C110012800C603118C10609901148214805000200
+34D3:004040402FFE2040004007FC151414A425F4E444244425F42444244424540408
+34D4:010842082788248807BE0488178814C824A8EFA8218822882488288822A80110
+34D5:00144012201027FE0410041017F214922492E5B426D42488254A293A2A261042
+34D6:000047FC244427FC044407FC124812482FFEE248224827FC20402FFE20400040
+34D7:010047BC21142394011407A4114C10802110E3E0204827FC2044224825440080
+34D8:00003FF820082FE8210823C824482A88210826083BE8210A2FEA414A41269FF2
+34D9:0200010001001FF040444844448442844104428444444824502440047FFC0004
+34DA:000400047F04082408240824082408240824082408240F24F004400400140008
+34DB:000001FC00447E440844084408440844084408440E84F0844104010402280410
+34DC:0800080010FC102422244224FC2404240824102424244224FE44424400940108
+34DD:22042204220422247F24222422242224FFA42224222422242204420442148208
+34DE:0800080008FC7F240824082408247F24082408240824FFA40844084408940908
+34DF:0404040404043FA424A4252424243FA420A42924252422242504488490940008
+34E0:08040804080408240FA40824082408247F24412441244124410441047F144108
+34E1:200420043F04482488240824FF24082408244924492449044F04790401140008
+34E2:100410041F042124612492240C2412242124C0A43F242124210421043F142108
+34E3:08040804140422244124BEA4002400243E2422242224222422043E0422140008
+34E4:080408040804FFA4082408247F24002400247F244124412441047F0441140008
+34E5:08044904290429242A240824FF240124012401247F24012401040104FF140108
+34E6:0004FFC40804082410247F244124412441247F2441244124410441047F144108
+34E7:0804080414042224512488A47E240224042408247F244124410441047F144108
+34E8:080408040804FFA408242A242A242A245D2488A4082414241204210441148008
+34E9:100410041F0421244224BFA424A424A43FA424A424A43FA42484448442948108
+34EA:100008007EFC422442247E24422442247E244024482444244A44524460944108
+34EB:08040804FFC41224212440A4BF241224122412247FA412241204220422144208
+34EC:080449042A047F2408241024FFA42224412480A47F241124110421044A148408
+34ED:00047F0441047F2441247F2420247FA488A448A454A440A47E84008405140208
+34EE:00043F84248424A42EA424A43FA420A42EA42AA42AA42EA42084408442948108
+34EF:2484248449049224492424A424A400247FA448A448A47FA4488448847F944088
+34F0:0004FF84080408243E24AAA4AAA4BEA4AAA4AAA4AAA4BEA480848F84F0940008
+34F1:0804140422044124BEA4002478A44AA44AA47AA44AA44AA47A8448844A945908
+34F2:080204023FC2204220523FD2201220123FD2355235525FD255425542944A10C4
+34F3:00083E0822483E4822483E480048FF48084808482F082828281058004FFE8000
+34F4:0004FF84080410247F2455245524552455244B240824FFA41404220441148088
+34F5:0004F784948494A4F7A400247F240024FFA4202440247F24010401040A140408
+34F6:20042F04F504252475242524F5242924232408240824FFA41404220441148088
+34F7:080410047F0441247F2441247F2441247F240824FFA41C242A04490488140808
+34F8:00047704550455247724142414247724412441247724142414041F04F0144008
+34F9:00047FC4440454A4652444244A24512460A4442454A4652444044A0491142088
+34FA:08040F8408047FA448A44F2478A447A4482444247FA441245A0444048A143108
+34FB:0004FF84948494A4FFA400240024FFA4082408244F24482448044F84F8140008
+34FC:08040804FF841C242B24C8A414242224492488A449242A244904888428141008
+34FD:0804490449047F2410240824FFA480A43F240024FFA408242A044904A8941008
+34FE:00027FC240427FC242124A9247124A9250524A124FD252124202BFE2820A0204
+34FF:070478040804FFA42A24492494A42224492488A449242A244904888428141008
+3500:00047F0441047F2441247F240824FFA400247F2441247F240804490488941808
+3501:050472041284512421245EA480A43F24212421243F2421241204078478142008
+3502:0404248415047FD4151424944454209420943BF44894AA8413E4208440948088
+3503:108010F825107BFC112425247DFC0102550294FE00007FF80408080810506020
+3504:00027FC20A027FC24A524A527FD2041224921512FFD20E1215022482444A0404
+3505:04023F8204827FC204923F920412555275D244527FD2445275C25542554A8444
+3506:0004F7842104A524F7A46324B5A421247FA440A440A47FA4408440847F944088
+3507:0904F6441284A12440A4F7641524152479A440248F24F1241504120455142908
+3508:22042204FF84222414241424F7A414241424772414241424F784140414141408
+3509:00027FC240427FCA400A5FCA420A5FCA524A5FCA420A7FEA62A26FA2A0AA2064
+350A:0402FFE200027FC240525F5251527FD200123F9220923F9220823F82000AFFE4
+350B:00047A0452047BA44A247B2454A478A400247F245524552455045784FC140008
+350C:FC044B8478844AA479244D24FAA40CA407A4F82428A44D241A042904C8940808
+350D:42047BC4A50410A47FA440A47FA440A47FA440A47FA42124FFC4210441148108
+350E:52107EFE28447E28A2FE3E1020103E7C22103E1000007FF80408080810506020
+350F:00027FC210023F8A508A108A1F8A000AFBEA208A79EA492ACB22492279EA4924
+3510:210221023DE2528288527FD20A127BD20A123B920A127BD20A020FC2F80A4004
+3511:0820FFFE28207DFC44887C5041FE7C2045FC7C2000007FF80408080810506020
+3512:44427FC212023FC26212BFD222123FD222123FD220127FD251426EC24A4A4EC4
+3513:04200E207820082008FC08240824FF2408240824082408440844088409280A10
+3514:100010007E7C1244124412442244227C4A4484001FF02008200820081FF00000
+3515:202020203F20402080FC7E24002400247C240424052405240344014400A80110
+3516:100010007E7C1244124412442244227C4A44840000003FF00010001000100010
+3517:1210121012107F9012FE12927F92521252127FD212521252235222A2422A8244
+3518:102010209220922092FC9224FE24102410249224922492449E44F28401280210
+3519:4220242000207E2024FC242424242424FF242424242424242444444444A88510
+351A:04200E203820082008FCFF24082408243E2422242224222422443E4422A80110
+351B:010001007FFC01001FF000001FF0101010101FF002007FF80408080810506020
+351C:02200F20F020012091FC4A240024FE24042408240F24F8444844088429281210
+351D:0010FF9008100810FF9088FE8892CC92AA92AA92DD929992889288A28AAA8144
+351E:02200F2078200820FF7C08242A242A24EBA42A242AA46B24AA44084408940908
+351F:082028203EF8482808A83E48084A0EAA7926020202007FF80408080810506020
+3520:00207E2042207E2042FC7E2420247F2489244924552441247D4401440AA80510
+3521:082010207F20552049FC552441247F2400244424772444245544664444A80110
+3522:108010F825107BFC112425247DFC0102550294FE02007FF80408080810506020
+3523:00083F8824883F8824BE3F8A000AFBEAAAAAAAAAFBEAAAAAAAB2FBF2002A0044
+3524:102008207F20412086FC782449242A24FF242A244124BE242A443E442AA83F10
+3525:0010FF10A510A510FF7E44129492F7120492F3929012F4929712F42294AAB3C4
+3526:2210FF9008107F10107EFF9222124912BE9222123E1222123E9225222A2A3144
+3527:08100F9008107F9048FE7E1248925F9255125F1255125F124012BFA22AAA7FC4
+3528:100010003FFC4524BDC405141CF464041FC410441FC410441FC4104411541088
+3529:100010003FFC22045FC482043FE4040408841FC400041FC4154415443FE80010
+352A:100010003FFC2204420483F402043FE42AA42524326425242AA43FE420280010
+352B:0400040004000400FFFE0480048004840488089008E0108210822082407E8000
+352C:203021C03E0820081FF800001FF010101FF010101FF00100FFFE010001000100
+352D:000043F84208420843F87A08420843F8400047FE40404A4052786240454008FE
+352E:51105112FA5453D870102012FBD2AA4EFA4023D2FA542258FBD0225252528ACE
+352F:00007FFC400047F044104410480C500047F044104410441047F040007FFE0000
+3530:00007FFC4220422043A044B044A844A44AA4512041204220442048207FFE0000
+3531:00007FFC400042804CB848884EB848884FF8414042204410580840007FFE0000
+3532:00007FFC422045204AA05F7869284F2849284F28482A4A2A4D4648807FFE0000
+3533:00007FFC420045384AA85F6869284F2849284F2A482A4A4A4D4648807FFE0000
+3534:00007FFC40004FF848884FF848884FF842204FF842205FFC441048087FFE0000
+3535:7FFE40005E7852485E7851444F3C42204FF8422042205FFC4220441048087FFE
+3536:7FFE44207FBC4A647F9840665F7C51105FFE51445F7C44447FFC442844447FFE
+3537:00007FFC40004FF8408040804FF8488849484A284C284808482848107FFE0000
+3538:7FFE4000403E4FC0487C48404BFE4A424A784AC44A3C520054F06494490C7FFE
+3539:104010401040104011FC1044FE44104410441084108410841104110412281410
+353A:0100010001007FFC0100110011201020FFFE102010201022100210020FFE0000
+353B:00007FFC010003000560191861040100000001000100FFFE0100010001000100
+353C:10A01090FDFE13201DFC3120D1FC112051FE210000000100FFFE010001000100
+353D:0100010001FE010001003FF82008200827C82448244827C8200820083FF82008
+353E:00003FE02020202020202020202020202140208020002004200420041FFC0000
+353F:0000FFFE10101010101010101010101010101070119016101810001000100010
+3540:010001003FF821083FF821083FF800001FF0101010101052102210020FFE0000
+3541:010032000C7C124469440844FFC410442444244448448A5411483F4011400040
+3542:00003FFE208020802140222024102908308620802FF020102020402040408080
+3543:00003FFE2000200027FC21102110211021102FFE211021102210421044108810
+3544:00003FFE200020002FFC20802100221024202FC020802100221044084FFC8404
+3545:00003FFE2000200027FC2444244427FC2444244427FC24442040404040408040
+3546:00003FFE2000204020402FFE20402040204027FC240424042404440447FC8404
+3547:00003FFE20002080204020402FFC20002408220822102110212040005FFE8000
+3548:00003FFE2080204020003FFE20802100228426882A5032202210428843068200
+3549:00003FFE208020802140222024102BE83006200027F024102410441047F08410
+354A:00003FFE2000204820442FFE204027FC244427FC244427FC2444444444548408
+354B:00003FFE2080214022202410280837F6208020802FF82080249042A05FFE8000
+354C:00003FFE200027F8240827F8240827F820002FFC20103FFE2410421042508020
+354D:00003FFE22802240224027FC24402C4037F82440244027F82440444047FC8400
+354E:00003FFE208020802FFC20803FFE220024082FFC20002FFC292449247FFE8000
+354F:00003FFE20003F8820482F282908294829282F0E20782908260843885C088808
+3550:00003FFE2100263824082738240827F8220027FC280425542554480440288010
+3551:00003FFE220422043FC422042FBE20042FA428942F942884250443845C148808
+3552:3FFE240822103FFE20802FFC20803FFE20A02F2822243FFE42285F12822A06C6
+3553:00003FFE200027FC255424E427FC204027FC20402FFE24A4285247FC40408FFE
+3554:3FFE20103F102AFE2E102AFE2EAA2AAA3EFE22003EFE2A205E144AA2BF280218
+3555:0100010002000420081010083FFC10040100010002000420081010083FFC1004
+3556:0400082010103FF80810102024487EFC02040100FFFE054009203118C1060100
+3557:41002210FF9008107F200820FFA0104010483E8442FC84040800140023FEC000
+3558:0400082010103FF80810102024487EFC010006C01830E10E0920111025080200
+3559:1080108020F04510FE2029FC4524A3243D2445FC4450A858109428924512820E
+355A:00003FF01010121011200920082044402440228001000280044008203018C006
+355B:00003FF000201E40018006601818E0043FF010100820044003800C603018C006
+355C:010001003FF8210821083FF8010001003FF010100820044003800C603018C006
+355D:010001007FFC010001001FF0101010101FF000003FF00820044003801C70E00E
+355E:00003F00217C21243F242424242424283F283528351055105528972804440482
+355F:080008000F0008FC08447F445544554455287F28551055105528512845444282
+3560:4140212003FE0A2017FCEA2023FC222023FE02003FF00820044003801C70E00E
+3561:08000F00087CFFA480A47F2414242228492816282110FE10222822283E442282
+3562:10001E00107CFF4481447E4400447E2842287E2842107E1042287E2824444282
+3563:00400840082010201010200840049FF2101010101010101010101FF010100000
+3564:01000100790049004BF04910491049104910491079104A1202120412080E1000
+3565:004000407C404440444044404440444044A044A07CA045100110020804040802
+3566:00001FF01010101010101FF0010001000100FFFE02800440082010102008C006
+3567:000001FC790449044904490449FC490449004900790049000200020004000800
+3568:000001F0791049104910491049904950495049107910491202120212040E0800
+3569:0020002078204BFE48204820482049FC4820482078204BFE0020002000200020
+356A:0040004078404BFC4A444C484840484048A048A078A0492001220222041E0800
+356B:0080004078404FFE49004900490049F849084908790849080208020804500820
+356C:002001207920491049104A484A484C444882488079104908020807FC02040000
+356D:001000787BC048404840484048404FFE484048A078A048900110010802040402
+356E:0020011079084A044A044C104910491048A048A0784048A00110020804040802
+356F:0100010001007FFC410442844444482457D444444444444447C4444440144008
+3570:0008003C79E048204820483C49E048204820483E7BE04820002200220022001E
+3571:00900088788848804FFE48A048A048A048A048A07920492201220222021E0400
+3572:00400040F040904097FE904090E090E091509150F24894440842004000400040
+3573:00000008790848884A524A524A224A224A524A927B0A4A0A020203FE00020000
+3574:000000007BFE4A024C04480049F04910491049107910491202120212040E0800
+3575:000003FE7820482048204820482049FC48204820482078204820002007FE0000
+3576:000003FC78404840484048404BF8488848884888788849080108010807FE0000
+3577:00200020784049FC490449044904490449FC4904490479044904010401FC0104
+3578:00800040784048004FFC480048084A084A08491079104910012000200FFE0000
+3579:00400048784448404BFE4880488048FC4944494479484A500220045008880306
+357A:00007CF84488448844887CF800000000FFFE080010001FF00010001000A00040
+357B:0200010000007FFC010003000D603118C10401001FF01010101010101FF01010
+357C:0100010079FE4A024A024C8A48524A224A524A8A7A024BFE0002000200140008
+357D:0008008878484A284A284A084A084A084A084A084A107A984B24022400420082
+357E:0100010009200910110821044104000000403E4422482270224022423E42223E
+357F:00701F8001000100FFFE054009203118C0061FF010101010101010101FF01010
+3580:004000407BF848484FFE48484BF8484048404BF87840484007FC004000400040
+3581:00080190786048984B04484048404FFE48804890791049200248048409FC0084
+3582:004000407BF84A484A484BF84A484A484BF848407848483000640194060C0004
+3583:0008003C7BC04A004A004BFE4A004A004A004AFC7A844A840484048408FC0084
+3584:0104012479244924492449244BB44B6C4D244924792449240124022402040404
+3585:00280024782448204BFE4A204A244A244A244BA87A284A100212042A04460882
+3586:00500050785048504BFE4A524A524A524A524BFE7A524A520252025203FE0202
+3587:000003FE7820482048404BFE4A524A524A524A527A524A5202520242020A0204
+3588:02083FD00220FFFE02000C703F84C80407FC00001FF01010101010101FF01010
+3589:002000207850488849244A224C204920493C492079204920012007FE00000000
+358A:000003FC7804480449FC480448044BFC480848084FFE79084888008800280010
+358B:0100028004401830E44E0440044004400840104000007C8844B044C47C84447C
+358C:0880088013F03090509090921112120E140000003E442258226022423E42223E
+358D:0040044002401240084009FC7E400040004000003E442258226022423E42223E
+358E:00807C8844B044C444847C7C0100028004401830E44E04400440044008401040
+358F:000001FC7904490449FC4904490449FC4820482079FC48200020002003FE0000
+3590:7CF8448844887CF800003FF002100210FFFE021004103FF0081010002000C000
+3591:0014001278104FFE48104A904A924A924FD24A947A944A88028A049A04260842
+3592:0108008878904BFC482448244BFC4A204A204BFE786248A2012A022404200020
+3593:010001F87B084C90486049984E4648404BF848407BF8484007FC004000400040
+3594:000001FC7820482048204BFE4850488849044AFA7C8848880088008800F80088
+3595:0040002079FC4800488848504BFE48204820482079FC48200020002000200020
+3596:020001003FF808200440FFFE010001003FF8010001003FF8200820083FF82008
+3597:004002487A484A484BF8484048A049104A884C4678404BF00010002000200040
+3598:000003FC7A004A004AF84A004A004BFC4AA04AA47AA84A900290048804A408C2
+3599:100010007E7C124412441244227C4A44840000003E442258226022423E42223E
+359A:0810081017FE30105210911011101050102000003E442258226022423E42223E
+359B:010001007FFC010001001FF0101010101FF000003E442258226022423E42223E
+359C:02000100FFFE00001FF0101010101FF0000000003E442258226022423E42223E
+359D:010001003FF801000100FFFE09203118C10600003E442258226022423E42223E
+359E:000001FC79044904490449FC482048204BFE4A227A524A8A030A0202020A0204
+359F:001C03E0F08492449148911097FE9402900093F8F108911000A0004001B0060E
+35A0:002000207BFE4850488849044AFA480048004BFE782049240122022200A00040
+35A1:00800040F7FE91209120923C9244966492949348F24892300220025002880306
+35A2:00800040EFFEA800A890A890AA90AA92AADCAA90EA90AA92129212D2270E0000
+35A3:0040002079FC48004908489048004BFE4800480079FC49040104010401FC0104
+35A4:000001FC780848104A224AAA4A724A224A724AAA7B264AA20242020203FE0002
+35A5:000007FCF404943495C49444944497FC944494E4F554964C0444044407FC0404
+35A6:00400040F7FC904093F8924893F8924893F89040F0E0915002480C4600400040
+35A7:001C03E07A204BFE4A204A924B0A4A0649FC4904790449FC0104010401FC0104
+35A8:000001F87808480849F8480848084BFE48204A22797448A80124022200A00040
+35A9:00000FC0F4BC94A494A497A494A494A897A894A8F49095D00EA800A800C40082
+35AA:0014001278104FFE481048104BD24A524A524A547BD4480800EA071A02260042
+35AB:0020002079FC482048204BFE488849444A4248F879884A500020005001880606
+35AC:0080031C7A044A044B9C4A044A044BFC480048007BF849080090006001980606
+35AD:000003FCF040904097FE90A09110920894469040F04892640252045201400080
+35AE:00400040F0A0911092089DF6900097FC94A494A4F7FC94A404A404A404140408
+35AF:3FF820082FE8200827C8244827C82028201000003E442258226022423E42223E
+35B0:00807C8844B044C444847C7C00003FF820082FE8200827C8244827C820282010
+35B1:0100FFFE088010F83148D328149010601198160600003FF8200820083FF82008
+35B2:10001000FE7C2244444434440844147C2244C0003E442258226022423E42223E
+35B3:1080088047FC21100A1011A070601090130800003E442258226022423E42223E
+35B4:011001107BFE49104880488049FC49544A544C9478A449240244008401280210
+35B5:000001F87908490849F8490849F8490849F8490879084FFE0000011002080404
+35B6:000007FCF0A090A097FC94A494A494A497FC9040F04097FC004000400FFE0000
+35B7:000001FC7904490449FC4904490449FC48004BFE78204920013C012002A0047E
+35B8:0040007C78404BFE4A424A784BC04A444A3C4A007AFC4A8003FE0480048008FC
+35B9:0010011079084A044DFA488849084A284C104BF87AA84AA802A802A80FFE0000
+35BA:00400040F7FC904093F8908097FC9110920895F6F110911001F00110011001F0
+35BB:000003F8F090906097FC90A49128922094609040F7FC90E0015002480C460040
+35BC:008800887BFE4888488848F84888488848F848207BFE487000A8012402220020
+35BD:000003FE7820484049FC4904490449FC490449FC7904490401FC000000880104
+35BE:00007EFC428442847EFC10100820FFFE0100210821083FF8040808003000C000
+35BF:00000FDEF4929492949497949498949497929492F49295DA0E94009000900090
+35C0:00400040E148A148A94AAA52AAD6AB5AA94AAA52ED6AAF7A094A08420FFE0002
+35C1:000003DE7A524A524BDE480049FC48004BFE4880790049FC0004000400280010
+35C2:00200020792449224A2A483048C04F0049FC490479FC490401FC010401FC0104
+35C3:000003FC7A044BFC4A204BFE4A104A8A4B0648007BFC4A0403FC020403FC0204
+35C4:000003FC7A944A944A944BFC488048404FFE488078F848880108010802280410
+35C5:0100013C79244FE44924493C49244BA44AA44ABC7AA44AA403A4004400540088
+35C6:008800887BFE488848F8482049FC4924492449FC78204BFE0020002000200020
+35C7:000003DE7A424A424A424BDE4A004A3E4BD24A127A144BD40208021402240242
+35C8:000003FC788848504BFE4A224BFE4A224BFE4A2278404BFE0042008201140208
+35C9:08007F7C08243E2408447F54088804000FE0144003801C70EFEE08200FE00820
+35CA:00003C7824482448244824483C78000000007EFC42844284428442847EFC4284
+35CB:0080008079FC4A044C084BFE4A004A804AFC4B207A204BFE0420045008881306
+35CC:0040002079FE49024A0449FC4840488849FC4824782049FC0020002003FE0000
+35CD:003803C0F040904097FC91509248944693F89208F20893F80208020803F80208
+35CE:02000200F7BC92A492A494A495BC9840904097FCF0E091500248044408420040
+35CF:000003FE78104820486848A44B22482048004BFE78204920013C0120012007FE
+35D0:004000407BFC484048A049104A884C4648004BF87AA84AA802A802A80FFE0000
+35D1:010003BCEE10A210A23CAF90A210A23CA210AF90E27EA2100210021004100810
+35D2:00800040F7FE900093F892089208920893F890A4F12893100510094801860100
+35D3:00100420F2F89288908890F89E80928092FC9284F28492FC0284050008FE0000
+35D4:0040007C78404BFE4A424A784BC44A3C4A404A207BFE4A880250042004580986
+35D5:008800887BFE488849FC48884BFE482049FC492479FC492403FE010401140108
+35D6:003C03C078444A244928490048404B9C4A044A047B9C4A040204020403FC0204
+35D7:00407C8045FC452445247DFC212421447DFC2490251027FE4410441094100810
+35D8:002800247BFE482049FC492449FC492449FC492478084BFE0088004800480018
+35D9:0080008079FC4A44495449F4488449284A9049FC7A444D5401F4008401280210
+35DA:000007FCF0A090A097FC94A494A497FC90409040F7FC90E0015002480C460040
+35DB:02100210F3DE95289884903893C09040904097FCF04090A000A0011002080C06
+35DC:00800040F7FC9080910893F09060918497FE9002F7FC944407FC044407FC0404
+35DD:01040084788848004BFE4820482049FC482048207BFE480002A4025204520000
+35DE:000800087788527E524A544A57485D7C55545554755457540548008801140022
+35DF:2080104087FC4040104023F8E040204027FC200000007C8844B044C47C84447C
+35E0:084008407E8413FE220214FC0884148462FC00003E442258226022423E42223E
+35E1:0440FFFE0440100027F86110A13C21042214240800007C8844B044C47C84447C
+35E2:01C8070871085FE8511E57CA554A57CA554A57CA710A57CA011201D20E2A0444
+35E3:02A802A877FC52A852AA54E6580057FC5444504073F852480248024802580040
+35E4:002800243FFE2220232422242FA822182A92522A464680820FF808080FF80808
+35E5:0200011E77D2501257D4545457D8501457D25092711251DA0714011005100210
+35E6:00101F20EACEAAAAAEAAAAAAAAAAAEAAAAAAAAAAEBEAAEAC1A28024802480288
+35E7:004000207BFE4A8A49044BFE4840488849FC4824782049FC0020002003FE0000
+35E8:00007F7848485F4C64805F7844484A4851307F4C00003FF8200820083FF82008
+35E9:000003DE78424A52494A4A524842482049FC4904790449FC0104010401FC0104
+35EA:009000927AD44A9A4AD24F4E488849F0482048447BFE48220128022404A20040
+35EB:010001107BDC4A544D544A8849084AF44C0248007BFC48400150024805440080
+35EC:111009207FFE40029FF410101FF002000FE034C00700388003F81D3001C03E00
+35ED:001C01E07820492448A84BFE487048A849244A227840482402A2028A04880078
+35EE:202020103DFE4510457CA9141914117E21147D14A57C251025283E2802440482
+35EF:01081FD001207FFC02000FF03810CFF008100FF000007C8844B044C47C84447C
+35F0:01240124722454245954514A529256105A105250725C5250025002B0029E0300
+35F1:014001207BFE4E204BFC4A204BFC4A204BFE4A4078404FFE015002480C460040
+35F2:004003F878484FFE48484BF848404FFE48004BF87A484BF8024803F8000007FE
+35F3:021002107BDE4A284D4448A049104A084DF6480078004BF80208020803F80208
+35F4:079E0492F79E9492979E940294F2949294F29492F4F294920492053204020406
+35F5:02100290EA90AB3EB222A544A890B210A290AB10EA28B228052808C410440082
+35F6:002403A878924D144A084C044BBA48A848C64B807A3C4B8400A8009002A80144
+35F7:002003FE7A5249FC485049FC48504BFE480049FC790449240124005800840302
+35F8:0280048EE8E0B140A040A24EA5F4AC44B444A554E554A5740594040404140408
+35F9:0140012073FE56205BFC522053FC5220522053FE724050240522050A08F80000
+35FA:000003F8708057FC511052085CA650A057BC50A073B850A007BC00A000A000A0
+35FB:000004F8728852E850A850A85DFC55045574555475745504051405080A0011FE
+35FC:00A004A4F2A890A097FC911090A097FC904093F8F04097FC015002480C460040
+35FD:11002BDE4A5273D42A524BD27A1A12942350C24000003FF8200820083FF82008
+35FE:05100518EFA8A528A76AA2AAAFAAAAACAAACAFA8E238AFAA022A022A02260220
+35FF:0000079E7492579E5492579E540255FA541255D2755255D204120452042A0404
+3600:008003387A084BB84A084A084BF848404A4849504FFE78E0495002480C460040
+3601:000007FCF4A497FC904093F8904097FC911090A0F3F890400FFE004000400040
+3602:010800907BFE490849084A524B9C49084A524BDE784048A402AA028A04780000
+3603:008803FE788848204BFE484048F849884A8848F87840482402A2028A04880078
+3604:020002FEE2AAA2AAAFAAA2FEA620A710AAFEAA20F220A23C0224024402540288
+3605:02400240E4AEA890B300A2E0A45EAC44B5E4A444E554A4E4044404640584040C
+3606:00400FFEE040A7FCA000A3F8A208AFFEA802A7FCE110A3F8004007FC00400FFE
+3607:01100554F5B8991092A89444900097FC94449040F7FC90E0015002480C460040
+3608:0400057CF60494A89390907C941497949A5092509FDCF250955004B0089E0100
+3609:02100210F3DE95289084900097BC94A497A494A4F7A49434052806A004200020
+360A:07FC0040EFFEA842A358A040A358A080A040AFFEE000A7FC000007FC040407FC
+360B:07DE051277D2545457C8551457E2500053FC520473FC520403FC020403FC0108
+360C:020203C2E202AFEAAA2AAB8AAE4AA9CAA80AAFEAEA0AAD4A0A820DC212AA2584
+360D:0108014CE52AA548A88EA138A288A7EABC8AA7ECE48CA7E8048A07FA04260442
+360E:040002FEE202A802AB92A892AFDEAAAAABCAAAAAEB92AAD20FAA08C608820806
+360F:211017FE108003F8F20813F8120813F8120813F8280047FE00903EE422843E7C
+3610:001007C8753E57C0551457D25522550057D450547554554805480454005401A2
+3611:041004101F7CE414A414AEFEA014AE14A07CBF10E45404381654251214500820
+3612:0C3871E0102013FEFD2431FC392455FC502093FE10007C8844B044C47C84447C
+3613:07BC04A4F7BC94A497BC944495F4944495F49554F5F4955405F404E40554044C
+3614:004007FE749253FC509053FC509057FE510853FC750A51F8010801F800900108
+3615:009007FE78904BE84A884BCE4A504BD44AA24BE278004BFC0294029407FE0000
+3616:0200011EEFC4A448A29EAFD2A912AA1EAC92A91EEA12AC52089E0900120C0412
+3617:07BC04A4F7BC94A497BC94A497BC912093FE9220F7FC9A2003FC022003FE0200
+3618:210447C88812F3BC20084B92F83E0380AAAAABAA00003FF8200820083FF82008
+3619:07BC04A477BC500057FE54005590549E57D4556475D4555405D405680BC81054
+361A:0FBE08A2EFBEA8A2AFBEA802AB92A892AFDEAAAAEBCAAAAA0B920AD20FAA08C4
+361B:004000A073185DF6500053F8520853F8511057DC72844FFC045007DC045204CE
+361C:51184B947C3ED3A87C7E53A87C3E53A87EBE43A000003FF8200820083FF82008
+361D:00007FFC400440044FC44044484444844284410442844444484440047FFC4004
+361E:00007FFC4204420442045FE4422442244224442444244824494450847FFC4004
+361F:00007FFC40044444444444445FF444444444444448444844504440047FFC4004
+3620:00007FFC4004420441444144448454A45514665444444BC4500440047FFC4004
+3621:00007FFC400440045FF4511451145FF4511451145FF45114410441047FFC4004
+3622:00007FFC41044924452445445FF442844284428444944894507440047FFC4004
+3623:7FFC400447C4444447C440044FE448244FE448244FE4482448A448447FFC4004
+3624:00007FFC4144655455544774641457F44414577465544554495450147FFC4004
+3625:FFFE8002861AF8E2AA42949290E2BE4AC8FABE2288AAAB26BE628002FFFE8002
+3626:104010401040104011FCFE44104410441044108416841884E104410402280410
+3627:100011F8100810501020FC1013FE10221024102010201C20E020402000A00040
+3628:202020202020202023FEFA22222222222252224A228A3B02E2024202020A0204
+3629:10101110111011121112FD1411D811101110111011101D12E1524192010E0000
+362A:1008103C11E010201020FC3C11E010201020103E13E01C20E02240220022001E
+362B:108810881088108811FCFC881088108813FE108810881C88E088410801080208
+362C:21002100210021FCFA042484208421042144222427F43A14E004400400280010
+362D:20802080213E21022242FA4227C220822082210221423A22E7E24222000A0004
+362E:100011FC110411041104FD0411FC11241120112011101D10E208420804040802
+362F:10801080110011FE1200FC40104013FC1044104410841C84E104410402280410
+3630:10101110109010901010FD10109010901010101E13F01C10E010401000100010
+3631:10201020102011FC1124FD2411FC11241124112413FE1D04E104410401140108
+3632:200023FC2204220423FCFA402240224023F8224822483A48E488448A090A0206
+3633:044004447C48047004400C423442C43E010001003FF8010001000100FFFE0000
+3634:01000110791049104910492849247944010001003FF8010001000100FFFE0000
+3635:10401040104017FE1080FCA0112011FC1324152411241D24E134412800200020
+3636:081008101EFC221052900C9008FE10102010411001003FF801000100FFFE0000
+3637:1110111013FC11101110FC00120812081110111010A01C40E0A0411002080C06
+3638:0000FFFE104010443E484270A44018421042213EC1003FF801000100FFFE0000
+3639:0880088828902EA028C028842E84F07C010001003FF8010001000100FFFE0000
+363A:2120212821242224FA20263E2BE022242224222822283A10E212422A02460282
+363B:200023FE220222222222FA2223FE222222222252224A3A8AE302420203FE0202
+363C:1040104411F410481050FDFE1040108011FE124014801CFCE004400400280010
+363D:084008487F4408440840FFFE0040084408447F440828082A0F12F02A40460082
+363E:2040202023FE22022404F80021FC20202020202023FE3820E020402000A00040
+363F:100011FC1104110411FCFD04110411FC1020102011FC1C20E020402003FE0000
+3640:2080204027FC24042110FA082484208023F0209020903910E1124212040E0800
+3641:1080108010FE110012FCFC8410A4109413FE108411241D14E1FE400400280010
+3642:110410841088101011FCFD041104110411FC105010501C90E0924112020E0400
+3643:1010103811C011001100FDFC111011101110111013FE1C00E090410802040402
+3644:11101112111411D81110FD121152118E1120102011FC1C20E020402003FE0000
+3645:200023F8220822082208FBF82040204027FC20E021503A48E444484200400040
+3646:2040202023FE22022444F84023FE20402090209021103920E224424204FE0842
+3647:100013FE104010801144FE24106812B0113012A810681CA4E122422000A00040
+3648:20402040207C204023FCFA44227023C02244223C22003AF0E49044920912120E
+3649:10501050105011FC1154FD54115411FC115411541D54E3FE4000008801040202
+364A:200021FC210021F82100F9F821002FFE2280224822503A20E210428803060200
+364B:1088108813FE10881088FCF81088108810F810881C88E3FE4000008801040202
+364C:1020102011FC102413FEFC2411FC10201124112411741DACE124412402240424
+364D:200027BC208422942108FA9424A42840200027BC20A43AA4E128429004A80846
+364E:2014201227FE2410F41027F02492249227D225543554E488454A0A1A08261042
+364F:1100110011FE120015FCFD0411FC110411FC108010FC1D08E290406001980606
+3650:102011241124112411FCFC0013FE1020104011FC11541D54E15441540154010C
+3651:00F03F0001001FF011101FF001007FFC412441F45E14400801003FF80100FFFE
+3652:00F87E084A504A207EFC4A244A287E2000A0014001003FF801000100FFFE0000
+3653:010001003FF80100FFFE08203EF808200E2078FC01003FF801000100FFFE0000
+3654:1040104011FC108413FEFC0011FC110411FC102013FE1C20E22043FE00200020
+3655:200023FE222223FE2222FBFE200021FC210421FC210439FCE104410401140108
+3656:1004101E13E0102011FCFD24112411FC102013FE12221E2AE2FA4202020A0204
+3657:200023F82248224823F8FA48224823F8200027FE22403A44E228429003080206
+3658:200023FE2050205023FEFA52225223FE2000204027FE3888E190406000D80304
+3659:2120111097FE4128493409281132E124223A2262259E01003FF801000100FFFE
+365A:1088105013FE102011FCFC2013FE100010A010FC11201C20E3FE402000200020
+365B:1028102413FE102011FCFD2411FC112411FC11241C08E3FE4088004800480018
+365C:0100FFFE00001FF010101FF000007FFC40044FE448244FEC01003FF80100FFFE
+365D:204021FC204420942108FBDE214A214A229421FC210439FCE10441FC0104010C
+365E:1020104011FC110411FCFD0411FC110411FC102013FE1C70E0A8412402220020
+365F:2100209E23D222522252FBDE2252225223D2221E22923A52E2D24352022A0044
+3660:7F7848485F4C64805F7844484A4851307F4C000001003FF801000100FFFE0000
+3661:21242124222424242954F94A229226102A102250225C3A50E25042B0029E0300
+3662:2088208823FE20882088F8F8202023FE2222233222AA3B76E2224222022A0224
+3663:20002F3E2120213CF1202F3C282028FE28502F523154E148414801440A620440
+3664:2040207C204023FE2242FA7823C4223C220822F023243AA8E5FE442008A00040
+3665:2080204027FC2110FA482484212023F02010208821503B20E510494801860100
+3666:0808144822285C8888487F0E08F82A084908180801003FF801000100FFFE0000
+3667:200023FE205023DE2252FA5223DE205023FE222222223BFEE222422203FE0202
+3668:224822482554275C2248FD54275C22482FFE222022283A28E5144494042C0844
+3669:2040204027FC20A02514FA0827FC2A0A23F8220823F83840E248444409440080
+366A:202023FE202021FC2000FBFE220221FC200021FC210439FCE104408803FE0000
+366B:10A0109011FE132011FCFD2011FC112011FE11001C20E3FE407000A803260020
+366C:081408127F102AFE2A105D101C282A284944888201003FF801000100FFFE0000
+366D:20002FFE28002A28F9482BEE289228842AA02AA83BE8E8884894091409241242
+366E:2210221023DE22282544F8A02110220825F6200020003BF8E208420803F80208
+366F:08203E2008F87F282228496A3E2A08567E8200003FF80000FFFE082010103FF8
+3670:10001EFC22247F44A99C3F50297C3F9029FE29104510821001003FF80100FFFE
+3671:00207C3C44207DFE0122FD3841E47D1C05702A54148C01003FF801000100FFFE
+3672:2040202027FE20282224F27E24C82748217E224824C8377EE1484248047E0840
+3673:2014201227FE2410F5D0241425D4255825CA24163442E82442A2028A04780000
+3674:210021F8220827FE2288FB2423FE220022FC220022FC3A00E2FC448404FC0884
+3675:102013FE100010F81088FCF8100013FE120212FA128A1EFAE22641F8002003FE
+3676:0100FFFE10101FF00000111009207FFE40029FF410101FF001003FF80100FFFE
+3677:200023FE220223FE2202FBFE21082252239C210822523BDEE00042A402520452
+3678:212821AA216C2228FAFE264426282AFE2210227C22103AFEE210422802440282
+3679:2088208823FE208823FEFA5223FE200023FE224220F83908E290406000C00700
+367A:27FE242025FC252425FCFC2027FE250425FC250425FC3D04E5FC4488050407FE
+367B:202027FE240025FC2524F5FC252425FC242025FC242037FEE5244AFA082013FE
+367C:23F82248224823F82248FA4823F820002FBE2AAA2AAA3FBEEAAA4AAA0FBE08A2
+367D:2020202027FE202023AEF92423AE22AA23AE22AA23AE3850E050408801040602
+367E:22A0244C24A4260CF4A4264C24A42FFE280223F03020E04047FC004001400080
+367F:211027FC204023F82040F7FC200023D4211227FE23503534E78C42CA045608C2
+3680:210821EC210A27E8F52825DE272824EA240A27EA340CE7EC4A2A0BEA115607E2
+3681:101010107C7C1010FEFE4444EEEE44446464DEDE0000FEFE28282A284C4A8886
+3682:204027FC224823F8F0402FFE2AAA23B8211027FC3110EFFE412803100D480186
+3683:010001007FFC01001FF000007FFE400284442388244820083FF8082004407FFC
+3684:01007FFC01001FF000007FFE51129FF411101FF000007FFC010411F0290047FE
+3685:020007E00820144003801C70E00E1FF0010011001FF821005FF00100FFFE0000
+3686:02000100FFFE00001FF010101FF010101FF008000FF01420224041800E60701C
+3687:044022882108228824483FF81210220847E4082014402280010006C01830E00E
+3688:1010101010101E101210221022FE52108A100410041008100810101020104010
+3689:00003FF008100820083C120417E438544588068039F80610192000C003003C00
+368A:202020103C1045FE4820A824104428F84E12122224445588081010282044C182
+368B:200021FC3D2445244974A92411FC29044F74135425545574090412042214C408
+368C:200021FC3D24452449FCA924112429FC4E2013FE247054A8092412222020C020
+368D:202021FC3D2445FC4820ABFE100029FC4F0413FC250455FC090411FC2088C104
+368E:010001007FFC0280044008203018C0060000200820082008200820083FF80008
+368F:010001007FFC0280044008203018C006082008207FFC08200820102010202020
+3690:010001007FFC010002C004201810600801000100FFFE0280044008203018C006
+3691:00003FF8000800081FF8000800083FF801000100FFFE0280044008203018C006
+3692:0100010001007FFC01002120111011102928454402800280044008203018C006
+3693:010001007FFC028004400820311001007FFC0380054009203118C10601000100
+3694:020002007FFC044008203018C82604403FF801000100FFFE0100010001000100
+3695:020002007FFC044008203458C4467FF804483FF824403FFC0844105420484040
+3696:010002001FF0101010101FF0101010101FF0010001007FFC028004401830E00E
+3697:020002007FFC044008203018DFF6101010101FF010101FF010101010FFFE0000
+3698:10201020102010207DFC102010201020FDFE1020105010502888248845048202
+3699:100010007E7C124412441244227C4A4485000100FFFE0280044008203018C006
+369A:020002007FFC044008203218C7E608203440028003001FF0E81008100FF00810
+369B:020002007FFC0440082038D8CF06081007F000001FF010101FF010101FF01010
+369C:020002007FFC044008203098C0A63FF800803E8022483E5000240E54718C0604
+369D:020002007FFC044008203018C806084013F8304057FC904013F8104017FC1000
+369E:020002007FFC044008203018C82608207EFC08201C702A6848A4892208200820
+369F:08001FC020807FF0A0103FF020883CF420843D7C01007FFC028004401830E00E
+36A0:020002007FFC044008203458C2863FF801001FF001007FFC0000248822444244
+36A1:10101010FEFE101028284444FEFE040474745454545474745454040414140808
+36A2:10801080108020802FFE61086108A2082210261021A0204020A0211022082C04
+36A3:02000200FFFE08401C8003800470180862000200FFFE08201C4003800C707008
+36A4:1048104410441040FE4E23F02240224042402440142008221412220A42068002
+36A5:100011FC10201020FC202420242027FE24204820282010202820442084A00040
+36A6:100011FE10481048FC4824482448244824484848284810482888448885080208
+36A7:10201010101010FEFC8024802480248024804880288010802880450085000200
+36A8:100013F010901090FC902490249027F02490489028901092288A448A84860082
+36A9:100010FC10841084FC8425FE24842484248449FE288410842884448484940088
+36AA:1008103C11E01020FC20243C25E024202420483E2BE01020282244228422001E
+36AB:200023FC20842088F8884890489C488489444944312811282A104A2884440182
+36AC:10401040108010FCFD0426042484244424444814282410442984440484280010
+36AD:1040105010481048FC4025FE24502450245048502890109028924512850E0200
+36AE:1000100011FE1102FD02240024782448244848482848104A284A448A84860100
+36AF:200023F822082208FB284AA84AA84A488A484AA832A8132A2C0A440A88061002
+36B0:100011FE10101010FC202420246824A425224A22282010202820440083FE0000
+36B1:1008101C10E01080FC802480248024FE24884888288810882888448885FE0000
+36B2:1020102010201020FC3E24202420242025FC4904290411042904450485FC0104
+36B3:210021002100211CFBD4495449544954895449543154115429544A5C83540480
+36B4:20402040204023FEF88048A0492049FC8B244D24312411242934492880200020
+36B5:10401040107C1084FD8826502420245024884B0628601010280844C084200010
+36B6:100011F811081108FD08250825F82500250049FC290411042904450485FC0104
+36B7:2020202020502050F88849044A22482048A890A4512421223222482048A08040
+36B8:100011FC10041004FDF42404240425F42514491429F411142804440484280010
+36B9:20002080231E2252FA524A524A524A524A5292D2535A22543090489049108210
+36BA:100011FC10441048FC8E2482257A2614242048202BFE10202820442084A00040
+36BB:00003FF8210821083FF8210821083FF804000400FFFE08201C4003800C703008
+36BC:1000100011FC1124FD2425242524252425FC4924292411242924452485FC0104
+36BD:00007DFE1040108011FC10041E04E00442280210FFFE08201C4003800C707008
+36BE:100011FC11041104FD04250425FC2450245048502850109228924512820E0400
+36BF:1040104010FC1084FD0426F42494249424F448842894108828824482847E0000
+36C0:1080108010F81108FE10242025FC24042404480429FC10042804440485FC0004
+36C1:100011FC10201020FD2424A424A8242027FE4820282010202820442084200020
+36C2:1008101C11E01100FD00257C2554255425544954297C1140294046428242043E
+36C3:080008007F7C08243E2408247F4408540A880200FFFE08201C4003800C707008
+36C4:10401020102011FEFC40244024A024A225A44A982C901088288844A484C20080
+36C5:100013FE10881088FCF82488248824F824884888288E13F82808440884080008
+36C6:100011FC10441048FC5E2482248A252424204BFE2820107028A8452482220020
+36C7:10201010101011FEFD00251025102510257C4910291011102910461082FE0400
+36C8:1040104411F41048FC5025FE2440248025FE4A402C8010FC2804440484280010
+36C9:100013FE10501050FDFC25542554255425544954298C11042904450485FC0104
+36CA:100010F810881088FC8824882526262025FE4820287010A82924462284200020
+36CB:2040204020A020A0F9104A484C46484049449152524A244A3048484049408080
+36CC:2040204020902108FBFC48244920492049FC9220502027FE3020482048208020
+36CD:10201020102013FEFC2024202524252425244AAA282010502850448881040202
+36CE:100010FC10841084FC84248424FC2400240049FE290211022902450285FE0102
+36CF:1028102410241020FDFE2420252024B224B4486828A811242A22442084A00040
+36D0:100013FE10201020FDFC2524252425FC2524492429FC112028A0444080B0030E
+36D1:08000F7C28443F44612892100C683186C0000400FFFE08201C4003800C707008
+36D2:100011FE10001000FCFC24842484248424FC4800288410442848440085FE0000
+36D3:21842068203020C8FB0448404BFE48A0492093FC552421243134492848208020
+36D4:1040104010FC1088FD50242024D8272624F8482028F810202BFE442080200020
+36D5:100010F810881088FCF8240025FC25242524492429FC110029004502850200FE
+36D6:2040204020882104FBFE4802488849448A4248F8318812502820485081880606
+36D7:1020102010A810A8FCA8257426222420242049FC282010202820442083FE0000
+36D8:2020202023FE2020F8204BFE4A024C0449F89010502023FE3020482048A08040
+36D9:1040102011FC1000FC88245027FE24202420482029FC10202820442084200020
+36DA:100011F8100810D0FC2025FC2524252425FC4924292411FC292445248524010C
+36DB:1040108011F81108FDF8250825FA250A250C4BF8281810282848458886280010
+36DC:1040104024FE6488A548245024202450228C0200FFFE08201C4003800C707008
+36DD:100011FC11041104FDFC2504250425FC2504490429FC10002888448481020202
+36DE:100013FE10201020FDFC2420242027FE248848882BFE10882888450881080208
+36DF:1080108010F81108FE1025FC25242524252449242BFE10502850448881040602
+36E0:210020BE22822202FA024AFA4A8A4A8A4AFA928A528A22FA32024A024A0A8204
+36E1:1040102013FE1202FC0425F82400240027FE48902890109029124512820E0400
+36E2:201C21E020202020FBFE48A849244A2289F84888309010BE2902490282140408
+36E3:100010F810881088FCF8240025FC250425244924292411242850444880840304
+36E4:200023FE20002000FBDE4A524A524A524B5A92D65252225232524A524A5282D6
+36E5:1020102213B410A8FCA8252426A2244025FC4904290411FC2904450485FC0104
+36E6:2110211021102110F7BC51105110533853B89554555429922110511051108110
+36E7:1020112411241124FDFC2400240027FE2440488028FC11842A84448484FC0084
+36E8:21082088209023FCF84048404BF8484088404FFE30A010A0292049228222041E
+36E9:1040102013FE1080FD0427FE240225FC250449FC290411FC2904450485140108
+36EA:1020102013FE1050FC882524262225FC252449FC292411FC28224422841E0000
+36EB:100010FC10841084FCFC2484248424FC244048FE292A124A28924522844A0084
+36EC:2020202021FC2020F8204BFE488849044A22902051FC2020302048204BFE8000
+36ED:10881088108813FEFC88248827FE240025FC4904290411FC2904450485FC0104
+36EE:1040102013FE1222FCA4252824502488250448F8288810882850442080D80306
+36EF:22102210239024BCF91457D455545554555497D452A422AC22C25482547E8800
+36F0:100011FC110411FCFD1025FE2510254A2586480029FC110429FC450485FC0104
+36F1:100011FC11241124FDFC2524252425FC24004BFE292011222914454885840102
+36F2:100013FE10201040FDFC2504250425FC250449FC2904110429FC440084880104
+36F3:01007FFC082004407FFC41041FF01110115011200200FFFE08201C4003C03C38
+36F4:2092212422482124F892484048804BFE4A02928A5252222232524A8A4BFE8202
+36F5:101E13E010441124FC88242025FC2524252449FC292411242BFE450485140108
+36F6:1020112411241124FDFC2480248027FE24904910295212542AA8442888440082
+36F7:0C48704413FEFC50305058929492110E12000200FFFE08201C4003800C707008
+36F8:1020102013FE1020FC2025FC2400240025FC4904290411FC28004488845003FE
+36F9:210021FE21102210FAFE4A924E924AFE4A92929252FE229032504A204A588286
+36FA:1040102013FE1000FD04248827FE240025FC4904290411FC2904450485FC0104
+36FB:2020202023FE2050F8884B2649FC4820482093FE5000202031FC4820482083FE
+36FC:1008103C11E01020FC2027FE242024A0252C4924292411AC2924452485FC0104
+36FD:2040202023FE2202F820492448A848204BFE907050A820A831244A2248208020
+36FE:2008200C200A23FEFA084A084AE84A0A4A0A92EC52AC22A832EA4A1A4A268442
+36FF:20A820A823FE20A8F8A848004BFE4A22882049FC312411242934492880200020
+3700:21002100213C2124FBA44924493C4BA44B649524593C212431244924493C8124
+3701:1020102013FE1070FCA82524262225FC250449FC290411FC2904440083FE0000
+3702:08087E0808FEFE0808487E2808080F28F0100400FFFE08201C4003800C707008
+3703:2090208820FE2100F9004B3C4D004900493C91005100213C31244924493C8124
+3704:200027FC24042434F5C4544455F45554555495F45444245425F4549458069002
+3705:1040102013FE1040FC8825F02420244425FE480229FC112429FC452485FC0104
+3706:2010209224522254FA1048FE48104E388A544A92331012102A10450088FE0000
+3707:2020202021FC2020FBFE482049FC48208BFE4800304010242AA24A8A84880078
+3708:00207E7C14C40838FEC62A2048FCA844128C0200FFFE08201C4003800C707008
+3709:2124224822482124FBF84A084BF848004BF89248524823F832024A0249FE8000
+370A:200023FC22042204FBFC4A484A484AFC8A484A4833FE12A42AA8449084C80886
+370B:2104208420882000FBFE4800488849048A0249FC315411542954495487FE0000
+370C:10001078FE4810487C480086FE0082FC7C441044FC2824286810302848448582
+370D:1020101011FE1110FD7C251425FE2514257C4910297C114429444644827C0444
+370E:101E13E011221094FC40248825F0242024C449FE282210202BFE445084880306
+370F:100010FC10841084FCFC240025FE250225FE490229FE110229FE444884840102
+3710:1020112411241124FDFC240027FE240025FC4904290411FC2888445083FE0000
+3711:40482FFE004087FC544417FCE44427FC244420000200FFFE08201C4003C03C38
+3712:1040119C11041104FDDC2504250425FC248848882BFE10882888448885080208
+3713:1088108813FE1088FC2024502488250426FA4800280011FC2904450485FC0104
+3714:1080104013FC1108FC9027FE240025F82508490829F81090289045128212040E
+3715:2010201022FE2110F97C4854487C4B54897C491031FE111029104A90847E0000
+3716:2090209027FE2090FBFC4A944BFC4A944BFC900051F8210831F8490849F88108
+3717:2040208821FC2108FA524BFE485049884E2690C0531020643388483048C08700
+3718:1020103C102011FEFD22253825E4251C2500497C2944117C2944457C854402FE
+3719:2040202023FE2250FA504BFE4A524A528BFE4A00329212D42A98449284D2088E
+371A:2040202027FE2402F90049FE4A104E204A7C92445244227C32444A444A7C8244
+371B:21082108210827C8F11E57D2556457C0554897C8510827C82114511451248142
+371C:21082108210827D0F11E579451245FD4521493D452542248224854D454248842
+371D:2020205020882124FAFA481048204BFE485091FC5154218C310449FC490481FC
+371E:08047F7808407F40497E7F4849487F4808487F480A88FFFE08201C4003C03C38
+371F:2008238820882110F7DE529452A4539452949394529422C82388569450A480C2
+3720:1020122213FE1090FC8825FE2710251025FE4910291011FE2910451085FE0100
+3721:2124212422242424F954494A4A924E104A109250525C225032504AB04A9E8300
+3722:102011FC112413FEFD2425FC242025FC252449FC284013FE288845D08470038C
+3723:2110211421D22250FA7E4D5048904AA8492891445244248230084AA44A528452
+3724:200023FE205023FEFA524BFE480049FC490491FC510421FC30204BFE48208020
+3725:200023FE22522252FBFE480049FC490449FC910451FC210431FC488849048202
+3726:200023FC200423FCF8044BFC48004BBC492497BC500823FE3108488848A88010
+3727:200027FE24002628F54857EE5492548456A096A857E824882494551459249242
+3728:200023FE220223FEFA104A544A384A548A824A50327C12902A1045FE84100810
+3729:2040208023FE2222FAAA4A224BFE4A724AAA9202502023FE3020485048888306
+372A:08047F782240FF40087E7F482A484948A8881400FFFE08201C4003800C707008
+372B:228822A826A82BF0F01E522455D45C14541495D4555425482568555456148422
+372C:210021F8220827FEFA884B244BFE4A008AFC4A0032FC12002AFC448484FC0884
+372D:1020112410A813FEFE0224F82488248824F8480029FC112429FC452485FC0104
+372E:200823E8228823EEFA284BF44A824BE2880049FC315411542954495487FE0000
+372F:200027DE24922492F5D2555E555055D05492949257CE20002000552454928892
+3730:21242174225822DAFBFE49544ADA4BFE88A2482033FE107028A8492482220020
+3731:2042239C221023DEFA944A944C204BFC4A0493FC520423FC32044BFC49088204
+3732:20402FFE240027FCF00057FC540457FC50809C9C57D43D54355C5C965556AE22
+3733:2080204027FC2000FBF84AA84BF848404A449118524420A831904A884CA680C0
+3734:210827FE210823FCFA944BFC48004FFE4C0291F8510821F8310849F8490881F8
+3735:204027FE200023FCFA404BF84A404BF84A4093FC5004255430A84B104D488186
+3736:21F0221027FC2204FBFC4A244BB84A2249FE921057FC224433FC48D0494A863E
+3737:F7FC124817FCFC4686ECF55416EC155456EC24440200FFFE08201C4003C03C38
+3738:0820FFFE28207DFC44887C5041FE7C2045FC7C200200FFFE08201C4003C03C38
+3739:23DE225223DE2252FBDE4A524BDE489049FE911053FE251031FE491049FE8100
+373A:252827BE294827BEFB184DAA49464BFC4A0493FC520423FC32044BFC49088204
+373B:244424E42A0A2EEEF4045AEA5E0E50E05AAA9AEA504020242522550A590880F8
+373C:21FC212421FC2124FBFE4AAA4BFE4AAA4BFE900053FE228A30F84888488883FE
+373D:0888111022201110088800001FE0004000800100FFFE01000100010005000200
+373E:0020FC200450085010881104160218883088D088108810881088110851082208
+373F:0000FDF8040808501020101015FE18223024D020102010201020102050A02040
+3740:00003E7C22042A08260822102210FF7E421052104A1042107F90021014500820
+3741:10001FF820085FC890481FC810481FE800103FE000800100FFFE010005000200
+3742:0104FD0E0530092017E01120153E196431A4D724112411241124112455442284
+3743:0080FC8004F80908121011FC152419243124D1FC10501050109010925112220E
+3744:20201020FE2001FC7C2044A87CA800A87CA804A808F81E22F0221022501E2000
+3745:1000FE7810487C480048FE8682007CFC00447C4408281E28F010102850442182
+3746:0020FDFE042009FC100011FC150419FC3088D3FE100011FC1104110451FC2104
+3747:20201010FEFE00007C7C44447C7C00007C7C080810101EFEF010101050502020
+3748:210447C88812F3BC20084B92F83E0380AAAAABAA00007C7C0808FEFE10103030
+3749:0200010001007FFE400280040000000000000000000000007FFC000000000000
+374A:0200010001007FFE4002800400003FF01010082004400280010006C01830E00E
+374B:0200010001007FFE400280041FE0004000800100010001000100010005000200
+374C:0200010001007FFE4202820407E004200840104000800180024004201810600C
+374D:020001007FFE500290041FF8100020003FF800080008FFC80008000800500020
+374E:020001007FFE40028204010001007FF8003000C003000C003000480087FE0000
+374F:020001007FFE400281040280044008203458C446044004400840084010402040
+3750:0200010001007FFE40828484044008401020221042088406084010203FF01010
+3751:020001007FFE4002820401007FFC0400040007F0041008100810101020A04040
+3752:0200010001007FFE4002810401007FFC010001001FF01010101010101FF01010
+3753:020001007FFE4002810402800C603018CFE600001FF01010101010101FF01010
+3754:020001007FFE4002820401007FFC08201010244844440280010006C01830E00E
+3755:020001007FFE4202810409002828282447E400003FF00820044003801C70E00E
+3756:020001007FFE420287E41840648003200C4071F806081A10012000C007007800
+3757:020001007FFE420281041FF010101FF010101FF0110410881050122014181806
+3758:020001007FFE420281043FF800001FF000001FF000001FF0101010101FF01010
+3759:020001007FFE400280043FF801001FF001007FFC0000FFFE0000082010102008
+375A:020001007FFE4002801C7BE00840104022787A400A402BFC1000280047FE8000
+375B:020001007FFE400288040FFC1040304053F89248124812A81318120813F81208
+375C:020001007FFE444284443FF804400440FFFE00001FF010101FF010101FF01010
+375D:020001007FFE40028824082008207EFC08201C301A702A6848A4892208200820
+375E:020001007FFE400280047FFC044004403C78200820083C7804400440FFFE0000
+375F:020001007FFE4002BFFC00001FF010101FF010101FF010101FF004421842E03E
+3760:020001007FFE40029FF410101FF010101FF012100100FFFE0000082010102008
+3761:020001007FFE400280047F0022FC3E4422443E44222822282F10F22842440282
+3762:020001007FFE400280F43F0001001FF011101FF001007FFC412441F45E144008
+3763:020001007FFE400288047F7C08243E2408447F5408880200FFFE04401830E00E
+3764:01007FFE4822BFFC08203FF80820FFFE01003FF821083FF82108FFFE20082018
+3765:020001007FFE400284242420252424A83C2007FE0470FCA82524262224204420
+3766:01007FFE49029FFC31005FF091001FF011001FF810003FE0084008F810086030
+3767:01007FFE4402BFFC082007C0783811101110292845443FF801000100FFFE0000
+3768:020001007FFE41029FF401007FFC00001FF010101FF0048808503820CB180C06
+3769:01007FFE400281043FF820802FF820883FFE20882FF824C422A8449858868180
+376A:020001007FFE4002904410407C4011F8FE48444828C87C4810AAFEAA11061202
+376B:01007FFE4002810479F04A9050606198560649F04A406BF8544043F8404047FC
+376C:20201020FE20822011FC7C2010207C2011FEFE2010507C50448844887D044602
+376D:01007FFE4002900413F812085BF8560853F8914013F8144011F0104017FC1000
+376E:01007FFE400288042A003E7C49447F4400443E2800287F1008102A2849441882
+376F:020001007FFE400280741F800200FFFE082037D8C4463FF8200827C8244827D8
+3770:01007FFE42029FF41490125011301FF00100FFFE92122FE8440407E008203060
+3771:01007FFE408A8BFC488849FC495479FC08000BFEFA4248784888495088600980
+3772:01007FFE411297FC511053F852A877FC141411F0F01057FC544453F892481258
+3773:0200020002000200FFFC0200020012901248122422242212421282000A000400
+3774:00087C08000801FE0008FE082488244824482408240824282412440243FE8000
+3775:00003FF820083FF820083FF800007FFC00200020FFFE08200420042000A00040
+3776:3FF8244824483FF80000044004420842303EC0000020FFFE0820042004A00040
+3777:3FF000101FF000103FF000407DF011501C94E14C0020FFFE0820042004A00040
+3778:010011102108450408003FF8200820083FF8200820083FF8044008421042603E
+3779:01001110216843841C00E8001FE020204040BFF8210821083FF80492188AE07E
+377A:22101410FF90141014147F521552FF9215107F1414043608551094A014401580
+377B:22102210FF9022103E5408527F5249907F1008147F0408087F0808100F20F0C0
+377C:200021FC20202020FC2028202BFE282028202820282028A02842480247FE8000
+377D:2020202020202024FDA828B028B0292829242A2428A028402802480247FE8000
+377E:20402040204023FCFC80288028F8292029202A20282029FC2802480247FE8000
+377F:2020202021FC2124FD28292029F82908295029202A502A882D0A480247FE8000
+3780:20402040204023FEFC802890291229542A902C28282428442982480247FE8000
+3781:200021F8210821F8FD0829F82800291829E02904290428FC2802480247FE8000
+3782:201C21E020442124FC88282028202BFE284828C8283028682986480247FE8000
+3783:2840244842449244104029FE445082507C5044504450445244527C92448E0100
+3784:2040204023FC20A0FD102A482DF4295029F0295029F42844283E480247FE8000
+3785:200021FC212421FCFD2429FC282029FE287028A829242A202822480247FE8000
+3786:2020202021FC2050FC882BFE280829E82928292829E829282808481A480287FE
+3787:200021FC212421FCFD2429FC28002BFE29222914294829842902480247FE8000
+3788:2040202021FC2104FD0429FC290029FC2B542B542DFC29542954490E480287FE
+3789:2088205023FE2020FDFC28402BFE288029FC2A202C202BFE2802480247FE8000
+378A:1040544054407C4092FC9250FE5000507C500050FE50105254929292510E2200
+378B:00003FFC200420043FFC200020002FF82408241022202140208041404630980E
+378C:00003FFC200420043FFC200027F82010202020402FFE20402040404041408080
+378D:00003FFC200420043FFC210021002FE0212025202220232024A24422481E9000
+378E:00003FFC200420043FFC20002FF82888288828882FF8280028024802480287FE
+378F:00003FFC200420043FFC200020782780208020402FF8201020604180460099FE
+3790:00003FFC200420043FFC2000208020402FFC200024082210212040005FFE8000
+3791:00003FFC200420043FFC20002888249022A0208022A02492288A4082407E8000
+3792:00003FFC20043FFC210022002FF8280828082FF8280828084FF8480888080FF8
+3793:00003FFC20043FFC200028602F88280827F820002FF828084FF848088FF80808
+3794:00003FFC20043FFC210023F02C202240218022402CF821084690406081800E00
+3795:00003FFC20043FFC22202410280837F6241027F0241027F04410441084500420
+3796:00003FFC200420043FFC20803FFC20802FF8288828A829D022A04490588C8080
+3797:00003FFC200420043FFC209020882FFC2080288825D022A02490488C42808100
+3798:3FFC20043FFC20002FFC2100230824882D50226025E029504250444899440080
+3799:3FFC20043FFC200020F03F0021E02F0021F43F0420FC20884ED042A084981986
+379A:3FFC20043FFC2000203827C020402FFE20402140265C2444475C444487FC0404
+379B:00003FFC20043FFC2288249028E43284247C2C0034FC248444FC448484FC0484
+379C:3FFC20043FFC220C2470281030FE223824542C92342025FE444444C8843805C6
+379D:00243FFE222023A422243FA82B10529A462680421FF810081FF8100020004000
+379E:00003FFC20043FFC24482848305422A425002C103490249C44904550863E0400
+379F:3FFC20043FFC22202FF821402FF82A282DD828082FF820805FFC41408630180C
+37A0:3FFC20043FFC20802FF821402A2827F02C1837F4241027F04080488892840100
+37A1:3FFC20043FFC2000273822102F7C20002738221023BC2EC8413043108D480186
+37A2:010001002108210821082108210821083FF801000100010001000100FFFE0000
+37A3:01002108210821083FF80100054008203018DFF6021002100210041008A01040
+37A4:010001002108210821083FF800000100010001000280044008203018C0060000
+37A5:01002108210821083FF80000060001000100028002800440082010102008C006
+37A6:100010F01090109054905490549054905490549054905C9264920112010E0200
+37A7:01002108210821083FF8000000003FF004100420087C08041004200440288010
+37A8:100011FC1004100854105420542057FE5420542054205C206420002000A00040
+37A9:0100210821083FF8000000000FE0082008200A200920092210221022201E4000
+37AA:00003FF0001000101FF000100010FFFE0100010021082108210821083FF80008
+37AB:01002108210821083FF80200010001007FF8003000C003000C003000480087FE
+37AC:010001002108210821083FF8000000003FF801000100010001000100FFFE0000
+37AD:010001007FFC01000280044008203018C106010021082108210821083FF80008
+37AE:01002108210821083FF8080008001FF810082010402000400C80030000800040
+37AF:00003FF0001000103FF02000200420041FFC010001002108210821083FF80008
+37B0:10801080108011FC552056205420542057FE542054205C206420002000200020
+37B1:0100210821083FF8000000003FF82008200820083FF82008200820083FF82008
+37B2:102010201020102055FC552455245524552455FC55245C206420002000200020
+37B3:100810881048104854085488544854485408540E55F85C086408000800080008
+37B4:1004101E11F0111055105510551055FE5510551055105D08650A014A01860102
+37B5:01002108210821083FF8020001007FFC0820082004400280010006C01830E00E
+37B6:10401020102013FE54885488548854885488545054505C206450008801040602
+37B7:01002108210821083FF80100010000007FFC010001003FF801000100FFFE0000
+37B8:01002108210821083FF8000000007FFC01000300056009103108C10401000100
+37B9:1000100013FE1008540855E8552855285528552855E85D286408000800280010
+37BA:01002108210821083FF8080008001FF0210001007FFC0280044008203018C006
+37BB:0100210821083FF800001FF010101FF00000FFFE10001FF00010001000A00040
+37BC:00003FF0002000C07D040588095011202118C50602000100210821083FF80008
+37BD:2028202420242020ABFEAA20AA24AA24AA24AA28AA28BA90CB12022A00460082
+37BE:100011FC11041104550455FC550055405544554855705D4065420242023E0400
+37BF:0100210821083FF8000001003FF801000100FFFE10100820044003801C70E00E
+37C0:00701F8001000100FFFE054009203118C006010001002108210821083FF80008
+37C1:100011FE11001100557C551055105510551055FE55105D106510021002100410
+37C2:100010FC108410A454945484548457FE5504554455245D0465FE000400280010
+37C3:100011FC1004100455F45404540455F45514551455F45D146404000400280010
+37C4:108410441048100055FE5420542054FC5420542055FE5C206420002000200020
+37C5:10001088105011245554558C550455FC5400549054905C90651001120212040E
+37C6:2090209421142118AB10AD32A952A90EA920A820ABFEB820C820002000200020
+37C7:10201020112411245524552456AA54725420542055FC5C206420002003FE0000
+37C8:102810241024102055FE5420552054B254B4546854A85D246222002000A00040
+37C9:2040202023FE2202AC24A920A9FCA920AA20A820ABFEB820C820002000200020
+37CA:1008103C11C01004554454A8540055F85410542057FE5C206420002000A00040
+37CB:110410841088101055FC55045504550455FC545054505C9064920112020E0400
+37CC:10901088108013FE54A054A854B054A454A854B055245D2A6532022202DE0400
+37CD:1040102011FC1104550455FC5504550455FC552055225D146508014401820100
+37CE:2008203C23C02044AA24A928A900A840ABFEA888A908BB90C860005001880604
+37CF:10201020105010885544562254F854085410542055FC5D046504010401FC0104
+37D0:1048104811FE104854485420541055FE5480548054805C806480008000FC0000
+37D1:2020202023FE2020A820ABFEAA02AC04A9F8A810A820BBFEC820002000A00040
+37D2:0100210821083FF800003FF80408FFFE04083FF808001FF8280848088FF80808
+37D3:21842068203020C8AB04A840ABFEA8A0A920ABFCAD24B924C934012800200020
+37D4:0100210821083FF8010002800C603118CFE6004000801FF0101010101FF01010
+37D5:0100210821083FF800000020792048A04A204920483C4BE07820482000200020
+37D6:0100210821083FF800003FF801001FF001007FFC00000820FFFE082010202020
+37D7:01000100410451445554638C41047DF455545554555465944D3441047FFC0004
+37D8:100011FC112411245574552455FC55045574555455545D746504020402140408
+37D9:10881088108813FE5488548857FE540055FC550455045DFC6504010401FC0104
+37DA:10201020FDFC1020302039F85488905010201050118C0100210821083FF80008
+37DB:0100210821083FF8000010881088FBFE108810881CF8F0881088108850F82088
+37DC:0100210821083FF800407C4004FC04847D28402040A87CA404A4052428A01040
+37DD:1040102011FC100055085490540057FE5400540055FC5D046504010401FC0104
+37DE:10481044105E11E054285412546A55965448545E55E05C2464280012006A0186
+37DF:0100210821083FF8000008207FFC0820FFFE10102FC848448FC20810081007F0
+37E0:200023FE2202228AAA52ABFEAA22AA22AAAAAAAAAAAABAFACA020202020A0204
+37E1:0100210821083FF80000111009207FFC0400FFFE10102FE8C82608A0084807F8
+37E2:0100210821083FF802003FF804800840FFFE00101F90109010901F9000500020
+37E3:2104211421142114ABD2A922A92AAB48AB88AD50AD10B914C922017E01220100
+37E4:0100210821083FF800003FF000101FF00010FFFE111009A005401930E50E0200
+37E5:0100210821083FF8040008201FF00210FFFE08A03318CC4603801C3001C03E00
+37E6:010041047FFC00007FFC41043FF801001FF011101FF011101FF00100FFFE0100
+37E7:010041047FFC00003EF822883EF800003FF80000FFFE08000FF0001000A00040
+37E8:102011241124112455FC540057FE5420544055FC55545D54655401540154010C
+37E9:00207F20413E7F4448A47F24482845105328614600000100210821083FF80008
+37EA:100011FC1124112455FC5524552455FC540057FE55205D226514014801840102
+37EB:1040108011FC110455FC550455FC5420543257B454A85D286524022404A20040
+37EC:010041047FFC0500397821083D7821083FF801003FF00820044003801C70E00E
+37ED:100011FC110411FC551055FE5510554A5586540055FC5D0465FC010401FC0104
+37EE:1040102013FE12025488550456225428542457FE54205C506450008801040202
+37EF:010041047FFC020001007FFE48029FF4282007C01830E00E1FF010101FF01010
+37F0:200023FE22022000A9FCA904A9FCA904A9FCA840A820BBFEC800008801040202
+37F1:2104208420882000ABFEA820A820A9FCA820A820ABFEB800CAA4025204520000
+37F2:100011FE11101120557C5544557C5544557C551055105D546552029202500420
+37F3:200023FE20502050ABFEAA52AA52ABFEA820A820ABFEB870C8A8012406220020
+37F4:2020204023FC2224AA24ABFCAA24AA44ABFCA840A8A8B8B4C93C01220222041E
+37F5:0100210821083FF800003FF824483FF800007FFC010011F811001100FFFE0000
+37F6:010041047FFC00003FFC2080210027F0241027F0241027F0408044908A881104
+37F7:1088108813FE1088542054505488550456FA540054005DFC6504010401FC0104
+37F8:2020204021FC2104A9FCA904A9FCA840ABFEA888A924BA22CDFC002000200020
+37F9:20103F202ACE2AAAAEAAAAAAAAAAAEAAAAAAAAAAABEABEACDA28024802480288
+37FA:010041047FFC01003FF82108FFFE21083FF811101FF00400FFFE082007C07838
+37FB:08047F7808407F40497E7F4849487F4808487F4808880100210821083FF80008
+37FC:0100210821083FF8082008207F3E08443EA40824FF2810281E1022284A448482
+37FD:100013FE105011FC5554555455FC540055FC540057FE5C2064A8012402A20040
+37FE:101011FE1110117C551455FE5514557C5510557C55545D7C6554027C0254044C
+37FF:2088208823FE2088A824ABFEA850A888A904AA8AA888BBFEC888008801080208
+3800:04001FF010101FF010101FF010001FFC10001FFC4924849C0100210821083FF8
+3801:2040208821FC2108AA52ABFEA850A988AE26A8C0AB10B864CB88003000C00700
+3802:21082108210827D0A91EAF94A924AFD4AA14ABD4AA54BA48CA4804D404240842
+3803:2040202023FE2088A850ABFEAA22AAFAAA22AAFAAA8ABA8ACAFA0202020A0204
+3804:0100210821083FF800007EFC22441A3462C404001FF010101FF010101FF01010
+3805:010041047FFC020013FC240043F88A0813F8320853F8910013F8151010E0171C
+3806:200023DE22522252ABDEA800A9FCA924A9FCA924A9FCB820CBFE002000200020
+3807:0100210821083FF820501048FE4801FE7C5044507C501050545052929292310E
+3808:200023DE225223DEAA52ABDEAA02AAFAAA22AA72AA22BA22CAFA0202020A0204
+3809:102011FC1088105055FE540055FC552455FC552455FC5C2065FC002003FE0000
+380A:2040207C204023FEAA42AA78ABC4AA3CAA00AA50AA54BB54C4D8045009FE0000
+380B:21083FF800001FF010107FFC44447C7C00003FF80000FFFE10001FF800080070
+380C:0100210821083FF800202220FFBE22423E9422103E102210FFA8242842448282
+380D:010041047FFC08801FFC30805FF890801FF810801FFC11007FFC05401930E10E
+380E:20A0209021FE2320A9FCA920A9FCA920A9FEA900A820BBFEC87000A803260020
+380F:108813FE1088100055FC54A854A857FE54A854A855FC5C2063FE002000200020
+3810:010041047FFC000000701F800200FFFE082037D8C4463FF8200827C8244827D8
+3811:0100210821083FF800003FF824483FF802807EFC02803EF802807EFC02800280
+3812:20022FE222822FEAAAAAAAAAAFEAA80AABCAA80AAFEAB90AC5420522092A0304
+3813:208823FE208823FEAA02A9FCA800ABFEA840A8A2AB54B8B8CB54009203500020
+3814:0100210821083FF800403E2022FC22883E5021FE20203E2052FC52209E201220
+3815:010041047FFC004078804BF8524863F852484BF8484868B450BC41224222441E
+3816:41047FFC08207FFC01003FF80100FFFE02403C500848FFFE08507E240854198C
+3817:2040208023FE2222AAAAAA22ABFEAA72AAAAAA02A820BBFEC850008801040602
+3818:0100210821083FF80A0033B822083A38238820883AB82288FFFE082010102008
+3819:202023FE200021FCA904A9FCA800ABFEAA02A9FCA840BBA4C8D8033400D20330
+381A:2144214425542364A94EABE4A804AA2CA944ABE4A884BBE4C88400E407140008
+381B:108813FE10A8109055FE572055FC552055FC552055FE5D0063FC00880070038E
+381C:220022BE23022254A9C8A83EAA0AABCAAD28A928AFEEB928CAA80258044E0080
+381D:108811DC108813DE54885554562255FC550455FC55045DFC650401FC00880104
+381E:22204AA08ABE1FC420A46F24A0282FA82210272822442F820100210821083FF8
+381F:10501190109E13EA548A55D2568A54A45450548857265CA8647000A801240060
+3820:2040207C204023FCAA44ABF0AA44AAFCAAA8AAF8AAA8BAF8CA0005FC05540BFE
+3821:202023FE200023FCAA20ABF8AA20ABF8AA20ABFEA802BAAAC854018806A400C2
+3822:21083FF802001FF011101FF012101FF004A808BA3082C27E01007FFC0C48763E
+3823:200023FE222222CCAA44ABEEAA44AAEEAB54AA44AA10BA90CA9E049004900BFE
+3824:202023FE200021DCA954A9DCA888ABFEA888ABFEA888BBFEC894018802A400C2
+3825:27FC244427FC2444AFFCA800AFBEAAAAAFBEAAAAAFBEB840C84007FC00400FFE
+3826:20A821FC22AA23FEAAAAABFEAAAAABFEA800ABFEA800B9FCC90401FC008803FE
+3827:202023FE224823FEAA48AAECAB5AAA48AA50ABDEAA50BBDCCA5005DE04500850
+3828:2154212423DE2154ABAEAD54AFFEAC92AFFEAA44ABDEBA44CBD4020C0284034C
+3829:0080008021402220241020003FFC0000092009200920112011222122411E8000
+382A:00007FFC0100010001000100010001F8010001000100010001000100FFFE0000
+382B:00007DF01110119011521D12E20E440001003FF80100FFFE028004401830600C
+382C:00007CF81088108810881CF8E00041003FF801000100FFFE028004401830E00E
+382D:00007C7C1010101010101010FEFE000000007C7C1010101010101E10F0FE4000
+382E:220014007F7C141055103610FF9000103E10221022103E10221022103EFE2200
+382F:00001FF01010101010101FF01000100010001FF81008100810081FF810080000
+3830:10007E7C124412441244227C4A4484001FF0001000101FF01000100410040FFC
+3831:3FF000103FF020041FFC08207FFC08200FE008200FE00820FFFE082010102008
+3832:0840084008407F4249444948495049604940494049404B4208420842083E0800
+3833:060001000280044008203118C10601001FF01110111011101150112001000100
+3834:1000100011FC7C24542454A454A454A45524542454245C441044108411141208
+3835:02000100FFFE1000100010001FF8010001003FF8210821082128211001000100
+3836:1020102010407CF854885488548854885488548854885C8A108A110A11061200
+3837:100013FC10847C8854885490549C54845544554455285D281210122814441182
+3838:1020102010207C2055FC54205420542057FE542054505C501088108811041202
+3839:1020102010507C5054885504560254885488548854885C881088110811081208
+383A:1020102010207CA854A454A2552255205624542454285C081010102010C01300
+383B:020002083FD002200240FFFE010002800C801FF82888488888A8089000800080
+383C:1004100E10F07C805480548054FE54885488548854885C881088110811081208
+383D:10401040107C7C8455885650542054505488570654605C10100810C010201010
+383E:10001EF8228862A894920882307EC10001003FF8210821082128211001000100
+383F:0880088828902EA028C028842E84F17C01003FF8210821082128211001000100
+3840:0100210811080910092001007FFC410441044384454449244104410441144008
+3841:1020102013FE7C505488550456FA540057FE544054805DFC1004100410281010
+3842:00047FA410243F2451240A040C043114C1083FF8210821082128211001000100
+3843:1010111011107D285544550055FE540054A854A854A85CA810A810AA112A1206
+3844:1040104010807CFE5502560255F25512551255F255125D1211F2100210141008
+3845:10201020107C7C8455485430542054485590543E54425DA41018101010601180
+3846:1080104013FC7D005500550055F854005550555055505D50125012521452180E
+3847:100013FE11207D28552855E855285528552855E855285D2A113A13EA10261020
+3848:1080108010F87D08561055FC55245524552455FC54505C50109010921112120E
+3849:201023882088F8FEA890AB90AA24AA24AA38AB88A890B89020A420BE22822100
+384A:10401040107C7C8455085600542055CE5502550255CE5D021102110211FE1102
+384B:1020102013FE7C5054885524562255FC552455FC55245DFC10221022101E1000
+384C:100011FE11027D7A5502557A540054FC548454FC54845CFC1084108410941088
+384D:02001FF010101FF010101FF00200FFFE08203118DFF611101150112001000100
+384E:1040104810847DFE542057FE548855245642558854105C621184101810601380
+384F:204020A02110FA08ADF6A800ABC4AA54AA54ABD4AA54BA5423D42244225422C8
+3850:210820882090FBFEA800ABC4AA54AA54ABD4AA54AA54BBD422542244225422C8
+3851:0610381008527E5408901C282A284844088201003FF821082108212821100100
+3852:1008101C11F07D10551055FE5510557C5544557C55445D7C11441244127C1444
+3853:200023FE2222F820ABFEA820A9FCA924A9FCA924A9FCB82023FE202020202020
+3854:00407F40127E0C88FF4819482A504820A850118C01003FF82108212821100100
+3855:1088108813FE7C8854A8542055FC55245524552457FE5C201050108811041202
+3856:1008103C11E07C2057FE542055FC552455FC552455FC5C2011FC102013FE1000
+3857:2004201E23F0FA1EAA10AAFEAA92AA98AAF2AA8EAA80BAB822A824AA254A2A86
+3858:1088105010007DFE545055FC545457FE545455FC54505CD81154125210501050
+3859:1020104011FC7D04555455245554550455FC540055125DD4111811521192110E
+385A:1088108813FE7C8855FC548857FE542055FC552455FC5D2413FE110411141108
+385B:1088108813FE7CA8541057FE5480548054FC540054A85CA810A810AA112A1206
+385C:2100211023DCFA54AD54AA88A908AAF4AC02A800ABFCB8402150224825442080
+385D:2020247C2284F948A830A8CEAE10AA7CAA10AA7CAA10BAFE2210221025FE2800
+385E:202021FC2124FBFEA924A9FCA820A9FCA924A9FCA840BBFE208821D02070238C
+385F:2090209027FEF890ABFCAA94ABFCAA94ABFCA800A9F8B90821F8210821F82108
+3860:202027A420A8FA92A914AA08ADF4A802ABF8AA08AA08BBF8220821102FFE2000
+3861:200023FE2200FA04ABF4AA04AAEEAAA4AAA4AAECAA04BAA42244227425942008
+3862:21FC210421FCF904A9FCA800ABFEAA52ABFEA800ABFEB88020FC208421142208
+3863:102008207F3E0020223E1402FFBE88A0093E7F20493E49204D3E4A200822081E
+3864:205022522154F850ABFEA888A850ABFEA820A9FCA820BBFE20A8212426222020
+3865:203E27C02244F928ABF8A840AFFCA800ABF8A808ABF8B80823F82544252A28FA
+3866:1020101011FE7D0254FC54A8553054FC558454FC54845CFC108410FC10481084
+3867:2040202023FEFA8AA904A812ABD4A848AA8AA974AA02B9FC210421FC208823FE
+3868:2148214C22AAF808AFFEA948AB68A94AAB6AA94CAB6CB948216A239A20262042
+3869:210447C88812F3BC20084B92F83E0380AAAAABAA01003FF82108212821100100
+386A:203E27C42128FBFEAA02ABFEAAA0AAEEAAAAAAEEABA8BA4622F82548243029CE
+386B:100011FC210421FC450445FCF88009FE1222112229524502FDFA440200140008
+386C:1110212045447978111025247D7C05240110FFFE20803E88225222224A5A8586
+386D:441049245E7844104A285F7C40007FFE441049245E7844104A285F7C40007FFE
+386E:49204920AABEEBA04940AABCEB802900FFB8240825082508228A528A45868882
+386F:010000803FFE2000201020F827802080208020FE3F802080408240828082007E
+3870:010000803FFE2000200027F82080208020803FFE208020804080408082800100
+3871:010000803FFE21002100210023F0221024202820204020C0412042108C083006
+3872:010000803FFE20002090208820FE2F802080208820902060204241A24E1A8006
+3873:010000803FFE2000203C27C024402440244027FE242024202412450A46068402
+3874:010000803FFE2080204020402FFC20002408220822102110412040009FFE0000
+3875:010000803FFE20802140222024902848304627F0201020204340408080400020
+3876:010000803FFE2000200027F8240824082408240827F824084120421084080804
+3877:010000803FFE2000208020802FFC21C022A022A02490288857F4408080800080
+3878:010000803FFE2200220023FE2500290031F82100210021FC4100410081000100
+3879:010000803FFE2000200023F82208220823F82208220823F8420842088FFE0000
+387A:010000803FFE2000200027F82408240827F82408240827F8400040009FFE0000
+387B:010000803FFE20002180263C24A424A424A424A425A426B42528412042208420
+387C:010000803FFE208020802FF828882FF828882FF820842048203041D45E0C8004
+387D:010000803FFE2000204027F820483FFE204827F8204027FC40405FFE80400040
+387E:010000803FFE200027F8240827F8240827F82484248824502420451846068400
+387F:010000803FFE2208210821102FFE204024442444244427FC2084410046009800
+3880:010000803FFE204020402FFE204027FC2444245424E8215042484C4680400040
+3881:010000803FFE208021F022102D2020D023202C7C218426884050406081800E00
+3882:010000803FFE2040208027F82408240827F82400240027FC4404440487FC0404
+3883:010000803FFE2100208027F8240827F8240827F8248224442428451046088406
+3884:010000803FFE200020002FFC200023F822082208220823F82000420841109FFE
+3885:010000803FFE200027FC204023F820402FFE211021102FFE2110421042108410
+3886:010000803FFE200027FC2444244427FC2444244427FC204027FC404040408FFE
+3887:010000803FFE210020802FFC200027F8200027F8200027F82408440847F88408
+3888:010000803FFE2280224027FE24402C4037FC2440244027FC4440444087FE0400
+3889:010000803FFE2000218C2E70221022103F90261E27702A902A1252124212820E
+388A:010000803FFE20802FF82140222024103FFE201027D0245047D0401080500020
+388B:010000803FFE22202278248825502C243448259E242224642598441044608580
+388C:010000803FFE20002EFC2A082AE82CA82AA82AA82AA82AE84EA8480888280810
+388D:010000803FFE200021102FFE2110204023F8224822482FFE20A0411046089806
+388E:010000803FFE2000203827C020402FFE20402140265C2444275C444447FC8404
+388F:010000803FFE204020A023182DF62000278424A427A424A427A4448444948588
+3890:010000803FFE200023F0221023D0225022502FFC280429E4292449E448148808
+3891:00803FFE2280224027FC24402FF8344027F8244027FC248040805FFE80800080
+3892:00803FFE2040207E20402FFE28422BF8284229FE290429FC490451FC910427FE
+3893:00803FFE204027FC21102FFE200023F8220823F8220823F840404FFE80400040
+3894:010000803FFE220024482848305422A425002C103490249C44904550863E0400
+3895:010000803FFE22282224257E29482E4822FE254829482F7E42484448887E1040
+3896:010000803FFE200020782F80249022A03FFE2490280837F6449047F0849007F0
+3897:00803FFE203827C020802FFC211027F8391621F020002FFE480249F2891209F6
+3898:010000803FFE221021202FFC21202FF821283FFE21282FF820004A4849249124
+3899:00803FFE251025103FD0253C271422142F942A942F9422144FA4422483541C88
+389A:00803FFE208020F820802FFC28842BF028882BF82A482BF84A4857FC9084230C
+389B:00803FFE204020A0211022082DF6200027BC24A424A427BC411042A884440882
+389C:00803FFE22083FFE220823F8200027FC244427FC244427FC40404524850A08FA
+389D:010000803FFE24002706293832082F882ABE2F882A9C2FAA4008554895482008
+389E:00807FFE40007E7C52244A1452244FF848884FF848884FF842205FFC44108808
+389F:00000020F82008201020113C2120792009200920492031FC10002C0043FE8000
+38A0:000003FCFA040A0412F4129422947A940AF40A944A04321412082C0043FE8000
+38A1:0440247C24A83D5004287DFE24884448841808200820FFFE0820102020204020
+38A2:082049202A3E7F4841A85D2855105D28424608200820FFFE0820102020204020
+38A3:2420FF20247E7EC482287A104A287AC6040008200820FFFE0820102020204020
+38A4:084008487F4408440840FFFE104010401F401140112021222112410A4A068402
+38A5:00207F28412441245D20413E41E05D205520552055205D2441144114450C4204
+38A6:0020FF2802247A244A207A2E00F0FF2002207A204A204A107A12020A0A060402
+38A7:00007FF0001000103FF0200020003FF800080008FFE800080008000800500020
+38A8:00007DFC0420042004207C20402043FE40207C20042004200420042028201020
+38A9:00407C40048004FC05047E044004410440847C44044404040404040428281010
+38AA:0000F9FC0800080008007BFE40804080410079FC080408040804080450282010
+38AB:0020F8200820082009247924412441244124792409240924092409FC50042000
+38AC:0040F840084008400BFE7840408040904090792009200A480A440C8451FE2082
+38AD:00207C200420043E04207C20402041FC40847C88044804500420045029881606
+38AE:0080F88008FE09000A207920412C417443A47924093409280922090250FE2000
+38AF:0000FBFC0A040A040A047BFC4220422043FE7A200A200A100A120A8A53062202
+38B0:0010F810081009FE09127914411041FC414479440928092809100A2852442482
+38B1:0020F840088809040BFE780240204020412879240A240A220C22082050A02040
+38B2:00007CF804087CF840807CF804080408285010200000FFFE0000082010102008
+38B3:00807C8004FE050006007C1C41E0412041227D24052805100510054829841102
+38B4:00003FF8000800083FF8200020003FFC00043FE42AA424A42B2424A43FE80010
+38B5:0020F8200850088809047A0241FC4000400079FC090409040904090451FC2104
+38B6:0000FBFE08200820084079FC41044104410479FC090409040904090451FC2104
+38B7:00107C920492049204FE7C204020407E40827D42042404280410042028401180
+38B8:0020F7201120113E1144F744844484A48428F7281110111011281148AA844502
+38B9:00407C2005FC040004887C5043FE402040207C2005FC04200420042028201020
+38BA:0040F82009FC08000888785043FE404040407BFE088809880850083050C82304
+38BB:001CF9E0082008200BFE78A84124424240407BFE0888090808D0083050482184
+38BC:00207D2404A404A804207DFC4124412441747DAC052405240524050429141108
+38BD:0000F7EE124212421242F3CE8248824883C8F24E124212E217421042A0544048
+38BE:0000FBFE0850085009FC79544154415441FC7820082009FC0820082053FE2000
+38BF:0080F8BC0884090809FE7B204520417C4190791009FE09100928092851442182
+38C0:0020F8200BFE082009FC790441FC410441FC790409FC09040BFE088851042202
+38C1:0088F8880BFE088808887BFE408041FC43247DFC092409FC092409245124210C
+38C2:0000FBFE080009FC0904790441FC400043FE7A8A0A520BFE0A220A22522A2204
+38C3:0200F11E17C212021482F7DE805087908490F79E1482178214821482A4944588
+38C4:0200F97E08400C7C0A4478FC4140467E422078200BFE087008A8092452222020
+38C5:0000FBDE08880AA80BFE798842DA44A641F87908090809F80908090851F82108
+38C6:07FCF24817FC1C4616ECF55486EC855486ECF454140817FC104013F8A0404FFE
+38C7:08000FE010201FC000407FFC09003200CC803080CFF80888088808A808900080
+38C8:20203C3C444478780808FEFE5050A8A84848BEBE2A2A2A2A2A2A2E2E08080808
+38C9:000400047F08081008200844080408080810082208420F04F008401000600180
+38CA:040008001FF02820444003801C70E10E0600384001880610382000C007007800
+38CB:11001104110411087FD01122190215041108FFD0112211021104210821104160
+38CC:08000804080408080F900822080208047F08411041224102410441087F104160
+38CD:08000804100422084110FFA2008200047F08411041224102410441087F104160
+38CE:010002001FF010101FF010101FF001001150218846441990062018C007003800
+38CF:08000804FF84140822104122BE8222043E0822103E220802FF84080808100860
+38D0:080010047F0441087F1041227F0208040808E8902D222A024904888828101060
+38D1:02023FC222042F8822903FC222822F8422082F902A822F824A844F888A9009A0
+38D2:410022040004FF888890AAA29C828884FF8800107F2241027F0441087F104160
+38D3:08020DC228443D484490A9423242C404248815107FC20E0215042488C4500420
+38D4:0800080013FE2020482008201020302050209020102010201020102010A01040
+38D5:084008401040204048400FFE10403040504090A010A010901110110812041402
+38D6:08400840104020404BFE0840104030A050A090A0111011101288124814441802
+38D7:08400820102021FC49040904110431FC51049100110011001100120012001400
+38D8:08800880110021FC4A040C0411E431245124912411E411241004100410281010
+38D9:104010402040404097FC144424446444A44427FC244424442444244427FC2404
+38DA:08000BFC120422044AF40A04120432F452949294129412F41204120412141208
+38DB:0840084010A021104A080C0613F83000500093F8120812081208120813F81208
+38DC:100217E22242424A924A124A224A67EAA24A224A224A224A22422442244A2844
+38DD:08280824102420204BFE082011243124512493A8112811101212122A14461082
+38DE:08900890110821484A440C92110833FC509490901090109011121112120E1400
+38DF:08200820102023FE4820082011FC3000500091FC110411041104110411FC1104
+38E0:10401040207C40849588165024206450A488270624602410240820C020202010
+38E1:111011102110421092FE169226926A92A29222FE229222102210221022102210
+38E2:09080888109023FC4824082413FC3220522093FE106210A2112A122414201020
+38E3:10401040204047FE9040145022486248A55428A220A021102110220824042802
+38E4:08500848105E23E44828083210CA370650509048105E13E41028103210CA1706
+38E5:111011102110427C921016102AFE6208A20822FE220822482228220822282210
+38E6:08380BC0104020404FFC095012483486508097FC1110121011A0106010901308
+38E7:11001208244847889108124827C86008A7C8244827C8244827CA244A244A24C6
+38E8:12101210221042109F7E151025106510A57C29442544224422442544257C2844
+38E9:111011102110411097BC111021106338A3B82554255429922110211021102110
+38EA:083C0FC01244212848000BFC1080308057FE910011F812881250142018D81306
+38EB:0808083C11E020204BFE082011FC312451FC912411FC102011FC102013FE1000
+38EC:080009F81108210849F8080017FE310851F8910811F81108113E17C810081008
+38ED:08000888125222224A520A8A120233FE50889144127A10881150102010D81706
+38EE:0820082013FE202048200BFE128A325252FA9222122212FA12221222122A1204
+38EF:08000BFE120222024BFE0A101292325452FE928212FE128212FE1482148A1884
+38F0:081C09E01020212448A80BFE107030A8512492221040102412A2128A14881078
+38F1:08200BFE102021FC48200BFE100031FC510491FC110411FC110411FC10881104
+38F2:121012102A904A909FBE102420546F94A01420142F94288828882F9428942022
+38F3:1100110023FC46A89AA812A827FC62A8A2A822A82FFE200022A8225424542000
+38F4:1110111027FC411091101FFE204067FCA44427FC244427FC2000211022082404
+38F5:10101410227C401090FE1044262862FEA210227C221022FE2210221025FE2800
+38F6:10401FFE200047FC940415F4251467FCA00023F8220823F8220823F820002FFE
+38F7:1080104027FC444492A8129424746000A3F822A82FFE200027FC204021402080
+38F8:150815482DA8453E9FA8124824486ABEA30825882988237E25402920251E2200
+38F9:1040102027FE44A894FE1550277C6550A57C2550257E254028A42A8A328A2478
+38FA:0400040004000400251024882444444404000400040004000400040004000400
+38FB:1010082004400280010002800C603018C0060100088848844812481287F00000
+38FC:1000100011FC1044184455445144514491441244104410841084110412281410
+38FD:02000200FFFE042008201C4003800C7070080100088848844812481287F00000
+38FE:100013FC11041144192454A85088508890501050102010201050108811041602
+38FF:10401040108018FC550452045004910410841044104410041004100410281010
+3900:030000802140222024102808300620003FFC0100088848844812481287F00000
+3901:00003FF801000100FFFE0280044008203018C106088848844812481287F00000
+3902:00003FE0082008400C780A081210112020C043308C0E02005104511290120FF0
+3903:10401020102013FE18805480508050FC90841084108410841104110412281410
+3904:10201020102013FE1820542051FC512491241124112411341128102010201020
+3905:7FF80200420042007FFC0480088010842084C07C010008844892481287F00000
+3906:1008101C11E01100190055FC5144514491441128112811101110122812441482
+3907:1010107813C0104018405440504057FE904010A010A010901110110812041402
+3908:1000104010201010189054805080528492821282128214881088108810781000
+3909:100013FC1010191055105110521093FE10301050109011101210141010501020
+390A:1004130810D01020185054885104500090041104108810501020105011881606
+390B:101010901090188855085104520495FA10881088108810881108110812281410
+390C:10881088108810881BFE548850885088908810F8108810881088108810F81088
+390D:00007DFE1040108011FC10041E04E00440280110088848844812481287F00000
+390E:100010007E7C1244124412442244227C4A448400010008844892481287F00000
+390F:1080108010F811081B1054A0504050A093181C0610C010201010118010601010
+3910:0100010001FE010001003FF8200820083FF82008010008844892481287F00000
+3911:10201020102010201BFE54405040508090FC1184128410841084108410FC1084
+3912:10201020102013FE18505450508851249222102011FC10201020102010201020
+3913:10401040104010401BFC544050E050E091501150124815F41842104010401040
+3914:1088108810881908557E53085508914811281128110811081108110811281110
+3915:10201020112411241924552451FC502090201124112411241124112411FC1004
+3916:10401020102013FE1A0254045000500093FE1020102010201020102010A01040
+3917:010001007FFC01003FF80200FFFE082012102208C2261290124822480A000400
+3918:1080108010F811081A10542053FC50049004100411FC10041004100413FC1004
+3919:3FF8200820083FC8204820483FC8200820083FF8010008844892481287F00000
+391A:10801080113C1A0054805080517E930815081108110811081108110811281110
+391B:10801088109C1970551053105510911011FE11101110111011101110117C1100
+391C:202820242024202033FEAA20A224A224A32422A8222822102212242A24462882
+391D:10401020102013FE18405488510453FE909210901090109011121112120E1400
+391E:1040102013FE1A025400503853C090401040107C17C0104010421042103E1000
+391F:044004403FF8244824483FF8244824483FF80100088848844812481287F00000
+3920:7F84082410243F2451240A24040408043014C008010008844892481287F00000
+3921:200420042FC422143214ABD4A254A454A6542554289420942104220424142808
+3922:1040104017FE1080190055FC5304550499FC1104110411FC1104110411141108
+3923:101008207FFC08200820FFFE0820102020204120088848844812481287F00000
+3924:1020102013FE12221A2257FE5222522293FE1020112010A0104010A011181606
+3925:10401020102017FE18405484510853F090221044118816101020105011881604
+3926:204020402FFE3040A840A7FCA444A44427FC2040224021402080214022302C0E
+3927:1008101C11E01100190055FE51005100917C1144114411441144127C12441400
+3928:10881088108810881BFE548850885088908817FE100010881084110412021402
+3929:08000FF010202C4003801C70E00E1FF0101010101FF002005104511290120FF0
+392A:0000FFFE100010F83E884288A4A818941084207CC10008844892481287F00000
+392B:040004007FFC08001FF028104FF088100FF0081008500A205104511290120FF0
+392C:1020102011FC18205420502053FE90001020102011FC10201020102013FE1000
+392D:1010107813C01040184057FE50A0511092081516111011101110121012101410
+392E:2200140019FC24204C2014F82420442005FC2800110008844892481287F00000
+392F:100013FE120212521A8A5706520252FA928A128A128A12FA128A1202120A1204
+3930:0900090011FE1280348050FC9080108010FC1080108002005104511290120FF0
+3931:100013FC1000100019F855085108510891F81000110810881090100017FE1000
+3932:010001007FFC11101110292845440280044008203018C106088828A4282447E0
+3933:100013FE10101820546850A453229020100011FC110411041104110411FC1104
+3934:20002FFE248024903490AF90A490A490A49027902490249224D22F92208E2080
+3935:00407E40047E08880E881948E850082008502888130602005104511290120FF0
+3936:10901088108013FE18A054A850B050A490A810B01124112A1132122212DE1400
+3937:1040104010A011101A88544651F050109020104013F812081208120813F81208
+3938:1040104013FC18405440504057FE909012941292149219121110121014501820
+3939:105010481048184057FE504052449164116810D0115012481444104211401080
+393A:208020402FFE22003200AA00A3F8A000A2482248224822482248244A244A2806
+393B:0600387C224432642A5422442A54324804401840610008844892481287F00000
+393C:1110111011101390193C5514511457D4911411141214129417D4122410541088
+393D:1020102013FE182055FC504053FE9048108810FE110811481228140810281010
+393E:100013FE12021252188855045020502093FE1020107010A81124162210201020
+393F:1040108017FE11101A48544653F85248924813F81248124813F810421042103E
+3940:1040104013FC1040184055F8510851F8910811F8110811F81108110817FE1000
+3941:010001007FFC01001FF01290129052905FF040007FFC02005104511290120FF0
+3942:100013F8120813F81A0857F8500053FC901017FE101012101110101010501020
+3943:100013DE125212521BDE5652525253DE920212021202120212021202120A1204
+3944:1020102011FC1820542053FE50889144124210F8118812501020105011881606
+3945:101C13E010841A445548511057FE9402100013F81108111010A0104011B0160E
+3946:1040104013F81848544857FE5048904813F8144412E811501248144611401080
+3947:10501048105E13E41828543250CA570690501048105E13E41028103210CA1706
+3948:10201020FE3E9220922092FC9A84948410FC1100088848844812481287F00000
+3949:1040102011FC100019085490500053FE9000100011FC11041104110411FC1104
+394A:200027BC24A424A434A4AFBCA4A4A4A4A4A427BC24A424A424A424A42AA4314C
+394B:0840082017FE104030A451A89290148810C41082010008844892481287F00000
+394C:1100110011FC1A045484549452A4908417FC108411C412A41494108410A81010
+394D:1108110817FE1108190855F85108510891F81108110817FE1000109011081204
+394E:0C80708011FCFD24322438445444508491041228111008844892481287F00000
+394F:10901090109013FC1A945694529453FC92941294129417FE1000109011081204
+3950:010002800C603018C7C600003EF8228822883EA8009002005104511290120FF0
+3951:00007FFC02001FF010101FF010101FF010107FFE410288844892481287F00000
+3952:1008103C13C010441A2455285100502093FE107010A810A81124122214201020
+3953:1040104013FC18A05510520857FE900813C812481248124813C8100810281010
+3954:1040102013FE1880550453FE500291FC110411FC110411FC1104110411141108
+3955:01000910092012C0043019086914091012A004401830600C01004884481287F2
+3956:00907890490849086A445C524888FDF84808484048244AA24A8A4C8888781800
+3957:11FC1104110411FC1904550451FC5040902013FE108810881050102010D81706
+3958:22002200227E27123212AA52A252AFD2A2522292241225122FA224A2204A2084
+3959:1020102011FC11241924552451FC50209040102010A41282128A128A14781000
+395A:20402140265C3444AC44A75CA444A44427FC244420A020A02110220824042802
+395B:100013FC10081810542053AE52A292AA12A412A413AA103210A0104017FE1000
+395C:100013FE12221BFE562253FE500091FC110411FC110411FC1104110411141108
+395D:2000277E21243124A93CA724A424A43C242427242126217C210421042A042404
+395E:11041088100013FE184054C25122525490981138125410941112161010501020
+395F:110011F8120813F0181057FE50805144966810B01128166810A4112216A01040
+3960:100013FE10221920553C512052FE940011FC110411FC110411FC110411141108
+3961:100013FC120413FC1A00569852E05284927C122013FE127014A815241A221020
+3962:11081088109017FE1890549053FC52949294130C120413FC1204120413FC1204
+3963:020002007FFC0440092037D8C1061FF001000FE001003FF801004884481287F2
+3964:00207E20145008887F442A2249F8880828101020010008844892481287F00000
+3965:11FC1124112411FC1924552451FC5020902013FE1222122A12FA120A12021206
+3966:3FFC20802FF82080249024902AA83144222024103FFE02005104511290120FF0
+3967:100013FE1020104019FC5504510451FC910411FC1104110411FC100010881104
+3968:102010F8FC20242025FC4800282010F82820442081FC02005104511290120FF0
+3969:1040104413F41848545057FE5040908011F81308150811F81108110811F81108
+396A:1020112410A810201BFE54A851245202904017FE108811081190106011981604
+396B:1040102017FE100019F8550851F8500093FC1204120413FC1204120413FC1204
+396C:2080204027FC3208A910A7FEA402A884204027FC210021F82108220822282410
+396D:1020102013FE102019FC544053FE508891241222112410A81124122210A01040
+396E:1080108011FC1244195455F450845128929011FC1244155411F4108411281210
+396F:007C7F80110808903FF80100FFFE00003FF800081FF800083FF8020851249FE4
+3970:10A0132E122212221BAE5622522253FE902013FE110410881050102010D81306
+3971:100013FE122812281AEE5628522852EE9228122812EE12281228122813FE1000
+3972:01007FFC01001FF010101FF010101FF01010FFFE1010200801004884481287F2
+3973:200027FE2420244035FCAD04A5FCA504A5FC2524242024A829242A2230A02040
+3974:2004203E27E0343EAC20A5FEA522A53825E2251E250029782A48324A248A2906
+3975:200027FE240225FA3442ACC2A52AA46AA4B2252A246A24AA2522244227FE2402
+3976:01007FFE44429FF404403FF80440FFFE082012102108C9062828282447E40000
+3977:010000803FFE20402FFE22482248255428A223182C0620804A444A4A920A01F8
+3978:0000FDFC85248524FDFC9124912491FCFD049000902090149552B542CE488438
+3979:1010545038881104FEFA10483848548891281210010008844892481287F00000
+397A:1020102011FC1820542053FE5080910413FE100213FC12941294129417FE1000
+397B:002800243FFE20A02F2422242FA822182B1252AA4A46848201004884481287F2
+397C:200027FC20403278AA40AFFEA100A1FC220023FC200425542554280420282010
+397D:102013FE102019FC542053FE500091FC110411FC110411FC110411FC10881104
+397E:100013FE124812481BFE5648522053FE924012FC13441244127C120013FE1000
+397F:08207F20087E7E4408A4FF2810101E2822444682810008844892481287F00000
+3980:2020247C22843148A830A0CEA610A27C2210227C221022FE2210221025FE2800
+3981:004027FC104013F8024873F8124813F8104017FC284047FE01004884481287F2
+3982:111009203FFC20044FE808200FE001003FF82108211802005104511290120FF0
+3983:1040102013FC18005508509053FE922012A012FC1320122012FC1420142019FE
+3984:010000803FFE222022202F7C222027702AA83224208020484A444A1491F00000
+3985:22A822A827FC32A8AAAAA4E6A800A7FC2444204023F822482248224822582040
+3986:1040107C10401BFE5642527853C4923C120812F0132412A815FE142018A01040
+3987:1040102013FE12501A5057FE5252525293FE1200129212D41298149214D2188E
+3988:22082110200027FC3040ABF8A040A7FCA00023F822A822A822A822A82FFE2000
+3989:102013FE102019FC540053FE520291FC100011FC110411FC1104108813FE1000
+398A:108813FE1088100019FC54A850A853FE90A810A811FC102013FE102010201020
+398B:2040204027FC3110AA48A446A3F8A05027FC208023F82D0821F8210821F82108
+398C:01F03E0003F03E0003FA7E0201FE0C20703C1DE2F0221C1E01004884481287F2
+398D:100013DE125212521BDE5488505053FE90201124112411FC1024104010801100
+398E:102011FC102413FE182455FC502053FE900011FC112411FC112411FC100013FE
+398F:200027BC24A427BC3420ACA4A39CA000A11027FC211021102FFE211022082404
+3990:101417FE10101BD0541053D0501093D0125013D0125013C8124A13CA11861242
+3991:2008278820883110AFDEA494A4A4A79424942794249424C827882C9420A420C2
+3992:100013FE125212521BFE542053FE500091FC100011FC100011FC110411FC1104
+3993:1110111411D212501A7E5550509052A89128114412441482100812A412521452
+3994:3E1022143E1222103EFE00103E2822283E2822443E44228227004884481287F2
+3995:20202720253C254435A8AE10A528A546A53825102550267E2490247C241024FE
+3996:2000279E2492279E3492AF9EA442A422A40A25462542255226322402240A2404
+3997:2110211027BC3110ABB8A554A912A00023F8200027FC20402248244429422080
+3998:10207E20423E7E4442A47E241028FF2820103E284244868201004884481287F2
+3999:11FC112411FC192455FC502053FE922A12FA120A1246102010A4128A128A1478
+399A:401020082108F8BE008050142208FA3E22082A487A3C2AA82AA8528841888008
+399B:0A0033B822083BB820883AB82288FFFE082012102108C9062828282447E40000
+399C:210827FE2148222037FEAA20A3FCA220A3FC222023FE220027F8211020E02F1E
+399D:3C20D0404DFC3104C9FC150425FCCC5014502492D50E0A0001004884481287F2
+399E:01007FFC01003FF80000FFFE00023FF00100FFFE00107DFC44907D30489487F2
+399F:31FCCB242D2431FCC924152425FCCC2015FC2420D4200BFE01004884481287F2
+39A0:228422842AA426C4329EAFE4A004A454A28C2FE4210427C4210421C42E142008
+39A1:244424E428A83AAAAEEEA4A4AAAAAEEE224220402FFE20E0215022482C462040
+39A2:1108110811EE12941842540053DE525293D2125213D2121A1294135012101010
+39A3:2100479C828017C0203E6788A4882788210827C829082FE821104884481287F2
+39A4:1040FE40107C7C840028FE2082207C5000887D2644107C5445422F4AF2384000
+39A5:20402FFE284227FC3040ABF8A040A7FCA04027FC24A427FC20402524252A28FA
+39A6:2000279E2492379EAC92A79EA482A532251225B2251225F224A2252A261A2404
+39A7:2108252827BE294837BEAB18A5AAA946A3F82208220823F82208220823F82208
+39A8:27BC24A427BC24A437BCAC44A5F4A444A5F4255425F4255425F424E42554244C
+39A9:201C2EE02A542A283A7CAC10AAFEAA00AAFC2A042A7C2C0428FC2814294A2A38
+39AA:224822E8230836EAAA1CA2E8A208A2E825B428E2200023F8211020E023182C06
+39AB:252827BE294837BEAB18A5AAA946A3FC220423FC220423FC220423FC21082204
+39AC:200027FC24A424A437FCAA10A2A8A4BEAF68223C24A82FBC20282AA82ABE2020
+39AD:27FC20402FFE28423358A840A358A000AEEE2AAA2EEE20002FFE224825542FFE
+39AE:0240022003F87E00020003F83E00020002FC7F100120014001840E447034000C
+39AF:004800440040FFFE004008400844104422447F28012800120F32F04A40860302
+39B0:225022482248554088C00040FFFE00400040002400280012003200CA03060002
+39B1:004000487F4400440040FFFE0040084408447F440828082A0F12F02A40460082
+39B2:084008487F4408440840FFFE104010441F4411441128112A2112252A42468082
+39B3:084008487F4408440840FFFE0040084408447F440828082A0F12F02A40460082
+39B4:004800440040FFFE20403E404244B4440C443228C1287E124232424A7E864302
+39B5:0828482448247F20482E88F00820FFA418241C282A2829104912882A08460882
+39B6:004800440040FFFE00407F40104422447F4409283E2808120F32F04A00860302
+39B7:0028FC2404246820102EFEF092209224FE2492289228FE109212922A92468682
+39B8:082808240FA408207F2E41F07F2041247F2449280828FF900812082A08460882
+39B9:00207C2844247C2444207C3E01E0FE2440247E28AA282A104A32924A2A864502
+39BA:00287FA440245F20402E7FF055205224592450A842287F9052124A2A82460682
+39BB:0028EF242124A920652EA9F0212010247E24422842287E104212422A7E464282
+39BC:082808247F2410203E2E1070FFA02224412490A8262822103612222A3E462282
+39BD:20142012FC1023FE40107BD04A50CBD278124BD248147AAC4D4A4AAA48165822
+39BE:020001003FFC200420043FFC2080248024F027903C90249244B2440283FE0000
+39BF:020001003FFC200420043FFC208020802FF821C022A022A04490488890840080
+39C0:020001003FFC200420043FFC20002FF022102220233822884450442088D81306
+39C1:010000803FFC20043FFC208020802FFC208020803FFE2100421044088FFC0404
+39C2:020001003FFC200420043FFC200020002FFC288428842FFC488448848FFC0804
+39C3:1004100410841084FE841084108412841C8C30B4D0C410841004100450042004
+39C4:1000100011041104FD0411041104150419043104D1041104110411FC50042000
+39C5:1000100011FC1044FE441044104412441C443044D04410841084110452282410
+39C6:1020102010201020FDFC11241124152419243124D12411341128102050202020
+39C7:1000100011FC1104FD0411041104150419743104D10411041104110451142108
+39C8:100011FC10041004FC0410FC10801480190031FCD00410041004100450282010
+39C9:1100110011FC1200FC0011F8100014001BF83008D0081008100A100A50062002
+39CA:10201020102013FEFC20102011FC152419243124D12411341128102050202020
+39CB:1040104810441044FC4013FE10401440184030A0D0A010901110110852042402
+39CC:1008103C11E01020FC20103C11E014201820303ED3E01020102210225022201E
+39CD:10401020102013FEFC801080108014FC18843084D08410841104110452282410
+39CE:100011FE10081088FC881088110815FE18183028D04810881108120850282010
+39CF:200023FC22042204FA94225422242A243254E2542294230422042204A2144208
+39D0:2000200027BC20A4F8A424A422A42AA83128E1282290229024A82828A0444082
+39D1:1020112010A010A0FC2013FE1022142218423052D04A108A1082110252142408
+39D2:20402020202023FEFA022404200028903090E0902088210821082104A2044402
+39D3:1008103C13D01290FE901290129016901A903288D28812C812A414D454922800
+39D4:2028202420242020FBFE222022242A243224E228222822102212242AA4464882
+39D5:20002080231E2252FA52225222522A523252E2D2235A225420902090A1104210
+39D6:1040102011FC1104FD0411FC11001500197C3108D110112011421282527E2400
+39D7:1090109010901290FE9212D4129816901A903290D290129212D21712520E2000
+39D8:088008882E9028E428842E7CF00000E01F0001003FF801007FFC010005000200
+39D9:1000104010201028FC08108814901A9432A2D2A214C210881188128854782000
+39DA:1000100013FC1100FD0011F01110151019903250D2501210121212925312220E
+39DB:04402440247C248024902508040800E01F0001003FF801007FFC010005000200
+39DC:100013FE12101210FE1012FE129216921A923292D29A12941210121053FE2000
+39DD:100010007E7C124422442A7C440080E01F0001003FF801007FFC010005000200
+39DE:1008103C11E01020FC2011FE10401440187C30A4D0A811281110122854442082
+39DF:2200217E21402440FA402240204029403140E2402640224022402240A27E4000
+39E0:1020104010881104FBFE1002142018203128D124122412221422102050A02040
+39E1:10201010101013FEFC201042108415F818103022D0C413081010102850C42302
+39E2:200027FC24042444FC44244427FC2C443444E4A42494251426042404A7FC4404
+39E3:10201120112011FCFD201220102013FE187030A8D0A811241124122250202020
+39E4:10401020102013FEFC40108815041BFE3092D0901090109011121112520E2400
+39E5:10201120112011FCFD201220102013FE18903090D0901090111211125212240E
+39E6:20802080210021FCFA04240423E42A243224E3E42224222423E42004A0284010
+39E7:1040102013FC1040FC90110813FC100419503150D1501150125012525452280E
+39E8:1008101C11E01100FD0011FE11001500197C3144D14411441144127C52442400
+39E9:200027FC24042404F5F42444244425F43554E5542554255425742446A4464842
+39EA:1040104010FC1104FA0811FE1500197C3144D1441154114811421242523E2400
+39EB:100013FE10201020FC4011FC1154155419543154D15411541154114451142108
+39EC:00007DF0111011901D52F20E440000E01F0001003FF801007FFC010005000200
+39ED:7CFC1088109010881E84F094408800E01F0001003FF801007FFC010005000200
+39EE:10001040119C1104FD041104110415DC19043104D1041104110411FC51042000
+39EF:10401040104411F4FC48105013FE104018803184D29814E010821082507E2000
+39F0:1008103C13C01200FE201220122013FE18203020D12811241222142250A02040
+39F1:0808081C147022104110BEFC001000103E1022FE2210221022103E1022500020
+39F2:2080204027FC2404F848204020402BFC30E0E1502150224824442842A0404040
+39F3:1088FD0412FA1C48F0881128321000E01F0001003FF801007FFC010005000200
+39F4:101010D813941094FC9013FE10901494189430D8D398109010AA10CA52862102
+39F5:100013FE10101020FC6810A413221020180031FCD10411041104110451FC2104
+39F6:1040108011F81108FDF8110811FA150A190C33F8D01810281048118856282010
+39F7:100011FC10201020FC2013FE10501488190432FAD48810881088108850F82088
+39F8:1040102013FE1000FDF81108110815F8180033FCD00810301020102050A02040
+39F9:100011FC110411FCFD0411FC100015FE180833FED00811081088100850282010
+39FA:1020102213B410A8FCA8112412A2104019FC3104D10411FC1104110451FC2104
+39FB:100013FE10401080FD441224106812B0193032A8D06810A41122122050A02040
+39FC:1020102013FE1020FC2011FC102014201BFE3040D0A411A81290148850C62080
+39FD:100011FC11041124FD2411FC1124152419743154D15411741104110451FC2104
+39FE:1080108010FC1154FA5410A415241A443094D108104010A412AA128A54782000
+39FF:1088108810881088FD5412221442102018203120D13C112012A01260543E2800
+3A00:103C11E0102013FEFC2011FC14241BFE3024D1FC107010A81124162250202020
+3A01:1040104013FC1040FC4011F8110815F8190831F8D10811F81108110857FE2000
+3A02:1020102013FE1020FDFC112411FC152419FC3020D07010A81124162250202020
+3A03:1040102013FE1000FDFC110411FC140019FC3008D01013FE1020102050A02040
+3A04:200027FC24442444FDF4244424442FFC3404E5F42514251425F42404A4144808
+3A05:1088108813FE1088FCA8102011FC152419243154D14C11841104110451142108
+3A06:2110211021102110F7BC21102110233833B8E5542554299221102110A1104110
+3A07:102049FC212409F871481230144C00E01F0001003FF801007FFC010005000200
+3A08:1040102017FE1108F890106011981E063108D1F8110811F81108110852082408
+3A09:100013FC120413FCFE2013FE1210128A1B063000D3FC120413FC120453FC2204
+3A0A:1040104013FE1080FDFC122015FE100019FC3104D1FC110411FC110451142108
+3A0B:1040104413F41048F85017FE1040188031F8D308150811F81108110851F82108
+3A0C:08007F7808483E4800487F86410082FC3C4408447E2808287F10082828441182
+3A0D:08083EFE08087F4808283E0808287F1000201FC001003FF801007FFC01000300
+3A0E:100013FE10201040FDFC1154115415541954312CD02013FE1050108851042202
+3A0F:1020112411241124FDFC108014801BFE3090D1101152125412A8142858442082
+3A10:2100217C21442244F244267C2A10221032FEE2382254225422942312A2104210
+3A11:1000108812521222FE52128A120217FE18883144D27A10881150102050D82706
+3A12:1020102013FE1050FC88132611FC1420182033FED000102011FC1020502023FE
+3A13:1040102013FE1202FC8811041222112019FC3220D02017FE1020102050202020
+3A14:20142012201027FEF410241025D024123412E5D42554254825DA242AA8465082
+3A15:100013F811081110F91C12E412A41A5434A8D10013FC12941294129457FE2000
+3A16:2008200827C82210FA1E24A427D429143114E7D42114210821C82E14A4144022
+3A17:10401040107E1040FBFC100415FC180433FCD0401240127C1240154054FE2800
+3A18:1020102010A410A2FD2A10101460198036FCD08410FC108410FC108450FC2084
+3A19:101E13E011221094FC40108811F0142018C431FED022102013FE105050882306
+3A1A:1090109013FE1090FD0011FC120411E4192431E4D12411E41124100450282010
+3A1B:100013DE125213DEFA5213DE12021A223222D2221252124A128A1202520A2204
+3A1C:1040107C104013FEFA42127813C41A3C3240D22013FE12881250142054582986
+3A1D:100013FE12021202FBFE121012921A5432FED28212FE128212FE1482548A2884
+3A1E:1020102013FE1020FDFC102013FE1440188831F0D02413FE1022112452A22040
+3A1F:1020112411241124FDFC100013FE140019FC3104D10411FC1088105053FE2000
+3A20:100013FE12021000FDFC110411FC150419FC3040D02013FE1000108851042202
+3A21:200027FE240225FAFC4224C2252A2C6A34B2E52A246A24AA25222442A7FE4402
+3A22:21102212245427D8F810201227D22C4E3440E7D22454245827D02452A552448E
+3A23:2120211022082486F91023F82008280037BCE08424A4229424A42084A2944108
+3A24:200027FE24502488FDFE269024FC2C9034FCE490249024FE24802400A7FE4000
+3A25:2008210821082208F2BE24AA2F2A212A322AE4AA2FB620A220222AA2AAAA4824
+3A26:10A0109011FE1320FDFC112011FC152019FE3100D3F811081090106051982606
+3A27:10401048108411FEFC2013FE108815041BFE3524D12411FC1124112451FC2104
+3A28:104013BE12121292FE5212AA132410401BFE3222D22213FE1222122253FE2202
+3A29:1040102013FE1202FAEC122412441A4432EED22412A412A4124E1460549E2900
+3A2A:100011FC110411FCFD0411FC1020152418A83020D3FE1090109011125212240E
+3A2B:20902290229C22A0FAD02288228828803000E3F822A822A822A822A8AFFE4000
+3A2C:2040204023F82040F7FE200023F822083208E3F820A4212823102D48A1864100
+3A2D:1040102013FC1204FBFC120012F81A8832F8D20013FC132415FC1502590220FE
+3A2E:2020224024EC24A4F4A424E424A424A436E4E40C2110211021102112A212440E
+3A2F:2200211E27D22012F7D4245427D8201437D2E092211221DA27142110A5104210
+3A30:1040102013FE1088FD241242109015F818083044D0A81190128814A450C22080
+3A31:204020FC21082650F92020C023202FFE3000E3FC200023FC200023FCA20443FC
+3A32:2110211027FC2110F840202027FC2C043444E04027FC20E021502248AC464040
+3A33:1040102013FE1202FC2011FC105014881BFE3008D1E8112811E8100850282010
+3A34:2110211021102FDEF12027C0245C27C43448E7C821102FD021222122A11E4100
+3A35:1108109017FE1000FBC4125413D41A5433D4D24412CC100013FC108451142608
+3A36:1040108011FC1104FDFC110411FC150019FE3100D1FE100212AA12AA5202200C
+3A37:1088108813FE1088FCF8102011FC152419FC3020D3FE102011FC102053FE2000
+3A38:1040102013FE1242FC28129412AA14CA18F83300D02011241124112451FC2004
+3A39:108813DE108811DCFC8813DE108814001BFC3004D00411FC1004100453FC2004
+3A3A:1088108813FE1088FC8810F814201BFE3222D33212AA137612221222522A2224
+3A3B:08047F7808403E402A7E3E482A48FF4808A81FC001003FF801007FFC01000300
+3A3C:00407CF8554854307DCE54F854887CF800201FC001003FF801007FFC01000300
+3A3D:200427C420042394FA94239420142FD43554E55427D42554254427C4A4544008
+3A3E:2208211027FC2040FBF8204027FC28403020E1C02044276821502248AD464080
+3A3F:2040207C204027FEF442247825C2243E3500E53825A826AA2AA62940B2FE4400
+3A40:2040207C204027FEF442247825C224BE3480E5FC255426D424B4292EAA24504C
+3A41:1040102013FE1202FCA0109011FE15201B2031FCD12011FC1120112051FE2100
+3A42:220422042784F494290C27C425643554E7C42546257C27C425442544A44448C4
+3A43:2040202027FE2492FBFC209023FC289037FEE1082204246220102180A0604010
+3A44:10201124112411FCFC0011FC112415FC192431FCD040102412A2128A54782000
+3A45:100013FE105013DEFE52125213DE10501BFE3222D22213FE1222122253FE2202
+3A46:221421122FD22010F07E2790249024903790E12825A825682928214AA54A4286
+3A47:102011FC102413FEFC2411FC14201BFE3000D1FC112411FC112411FC500023FE
+3A48:1040102013FE128AFD0411FC14441BFE3044D1FC108011FC1284148450FC2084
+3A49:204020A0211826E6F80023F822082BF83000E7BC208424A4229424A4A2944108
+3A4A:101C13E010441124FC8811FC1154155419FC3008D7FE11081088108850282010
+3A4B:204023F8204827FEF04823F820402554375CE44427FC2444275C2554A5544844
+3A4C:109017FC109413FCFA9013FE11121BFA350ED1F8110811F8110811F850902108
+3A4D:1210121013DE1528FCA4102013FE10201BFE3222D22A127410A8112456222020
+3A4E:20082788248C278AF48827BE200827883488E7882494279424942494A49445A2
+3A4F:100011FC112411ACFD74112411FC142019FC3020D3FE100012A4125254522000
+3A50:2210221023DE2528F8C4204023FC284037FCE0102FFE201022102110A0504020
+3A51:200023F8208027FCF11022082CA620A037BCE0A023B820A027BC20A0A0A040A0
+3A52:2110211027BC2110FBB825542912280033F8E00027FC204022482444A9424080
+3A53:2C7844486C4844867D7800487C301048FCA41FC001003FF801007FFC01000300
+3A54:40004FDC48544854EFD44A944AA64FC06A9CCA944FD44814528852486454C822
+3A55:100011FC102013FEFA2211AC142019AC3050D0C8132610F8100810D050202010
+3A56:100013FE100011FCFD2411FC15241BFE3000D1FC112411FC112411FC500023FE
+3A57:244427FC212023FEF6202BFC222023FC3220E3FE220027FC2108211EA2024C1C
+3A58:1104108813FE1020FDFC102013FE145419923090D3FE109010D4138A509621A2
+3A59:2080204027FE2512FBFC211027FC291037FEE110224825F428422040A7FC4000
+3A5A:211027FC211027FCF40423F8200027FC3080E14426A8217026A82126A6A04040
+3A5B:27FC244427FCF44425F4255425F43554E5F4244C27FC241427FC2514A4B447FC
+3A5C:201027D0251027DEF45027E8250427C43000E3F822A822A822A822A8AFFE4000
+3A5D:204027FE200021F8F90821F820002FFE3402E3F82180264421B82668A1A64E60
+3A5E:2110255425B82910F2A82444200027FC3444E04027FC20E021502248AC464040
+3A5F:1040102013FE1252FDFC105011FC14501BFE3088D12412FA1020112452A22040
+3A60:2080204027FC24A0F7FC24A427FC24003524E5A8253025A4251C2800AAA45452
+3A61:200027FC2100F3F82508210821F83000EFBE2208279E24922CB22492A79E4492
+3A62:210827FE21082000FBFC229422942BFC3028E3FE2220232422A82292A42A48C6
+3A63:27BC24A42294F4A42FFE284227FC3040E3F8224823F8224823F82040A7FC4040
+3A64:214827C8210827D0F55E27E4255427D43554E11427D4220823C82254A55448A2
+3A65:2114211227D22110F1102FFE229026D23292E6D2229426D4228A22CAAF164022
+3A66:10A0109011FE1320FDFC112011FC152019FE3100D3FE1252128A137652522276
+3A67:11FC110411FC1104FDFC108811FC14881BFE3088D12412AA107010A851242060
+3A68:108813DE108811DCFC8813DE108817FC180431FCD00413FC104012A4528A247A
+3A69:2400249E25042608F45E245223D2211E3112ED5E25522592295E2920B52C4212
+3A6A:2100213E22082290F4BE2F222122223E34A2EFBE20A220222ABE2A80A8144022
+3A6B:2042239C221023DEFA94229424202BFC3204E3FC220423FC220423FCA1084204
+3A6C:210821CC210A27E8F52E25D8274824CA340AE54C276C2548254A297AA7A64042
+3A6D:22A0244C24A4260CF4A4264C24A42FFE3802E3F02020204027FC2040A1404080
+3A6E:2140226C2244236CFAA423AC22A42FFE3108E2F4244223F8204027FCA04040C0
+3A6F:221023D0241E2FE4F5542FF4254827D431B2E22027C0208827FC2044A3504488
+3A70:211027FE211023F8FA0823F820002FBC34A4E7BC20402FFE21502248AC464040
+3A71:101E13E011221094FBFE125217FE180433C4D27E13C4125413CC128452D42348
+3A72:21102FFE211027BCFCA427BC2140292033FEE22027FC2A2023FC2220A3FE4200
+3A73:2108229423DE26B4FBDE229423DE2A9433DEE21027FC210820902060A1984606
+3A74:27BC24A427BC24A4F7BC24A427BC212033FEE22027FC2A2023FC2220A3FE4200
+3A75:210821EC210A2FEAF9282BC8293E2FE83948EBE82A282B682AA82BF4AAB452A2
+3A76:221023DE25282084F7FE224827FC2C4636ECE55426EC255426EC2444A4544408
+3A77:204027FE249223FCF89023FC20902FFE3108E3FC252221F8212021FEA0024556
+3A78:11FC112411FC1124FBFE12AA17FE1AAA33FED02013FE124210F81150502023FE
+3A79:11FC112411FC1124FBFE12AA17FE1AAA33FED00013FE128A10F81088508823FE
+3A7A:00100410441044FE4410441044FC774444444444442844285510662844440182
+3A7B:201020107E1042FE84107F1040FC5E44524452445A2854285010942898441182
+3A7C:101010103E1042FEA410181010FC2444C8441F442128D2280C1008283044C182
+3A7D:10101010FE1010FE1010FE1092FC9244FE441044382854289210102810441182
+3A7E:02100F10781008FEFF102A102AFCFF442A442A44FF28082808100E2870442182
+3A7F:1020102020203F3E404480443E4402A40428082810102010212821281F440082
+3A80:00407C401040108010FE11081288FC8810881050105010201050108851042202
+3A81:081008101410141E2210521088FC084400447E44022804280410082808440082
+3A82:201020107F10801E00107E1000FC0044FC440444042805280510032801440082
+3A83:00100010FF90021E02107A104AFC4A444A444A447A284A28021002280A440482
+3A84:282028202820FE3E2A442A44FE44A8A4A828FF28291029102D284A4848848902
+3A85:7FFC01003FF82108228824482118010001FC01003FF00820044003801C70E00E
+3A86:021007107810481E481048107EFC484448444844482844284510632849440482
+3A87:0820282028203E3E4844084408447FA414281428141014102528264844848102
+3A88:08100810081E7F10081008FCFF440044084408287F28081008100F28F0444082
+3A89:082008201420223E4144BEC4004400A43E2822282210221022283E4822840102
+3A8A:00107E101210121EFF10121012FC7E44204420447E286228A21022283E442282
+3A8B:00107F1041107F1E41107F1000FC00447F4408440828FFA80810082808440882
+3A8C:0010FC100410681E1010FE1092FC9244FE4492449228FE289210922892448682
+3A8D:082008207F20083E08447F44414482A43C28042808100F107828082828441082
+3A8E:081008100810FF9E08102A102AFC2A445D4488C4082814281210212841448082
+3A8F:101020107F10491E49107F1049FC51447F4424444428FFA80410042804440482
+3A90:081004103F10211E21103F1024FC264425443F44242824284A10492891442082
+3A91:08100810FF90141E2210491088FC7F4449447F4449287F2808100A280C440882
+3A92:101067104110411E7710411041FC7F4414441444142814282510262844448082
+3A93:02100F107810081EFF9008102AFC2A44EBC42A442AA86B28AA10082808440882
+3A94:221022102210221EF790221022FC66447744AAC4AA2832282210222822442282
+3A95:081008100F9E08107F1041FC7F4441447F4449280828FF900810082808440882
+3A96:00107E1002103E1E0210FF9008FC094449442A441C282A28C910092828441082
+3A97:101008107F1E0010221014FCFF44004400443E282228221022103E2822440082
+3A98:082008201420223E4144BEC4084408A47F28492849107F100828144822844102
+3A99:00207F204920493E7F44494449447FA40828FF281C102A104928884808840902
+3A9A:242024207E20243E2444FF4400447EA4422842287E10421042287E4842840102
+3A9B:22102210FF10221E3E1022103EFC22442244FF4440285428621040287E440082
+3A9C:101092109210921EFE100010FEFC10442044FE44AA28AA28AA10AA28AA448682
+3A9D:08100810FF90081E7F1049106BFC5D4449447F4408281C282A10492888440882
+3A9E:0010FF108110BD1E8110BD1081FC00447E4442447E2842287E1042287E444282
+3A9F:10200820FF20003E3E4422443E4400A47F28412841107F10412841487F844102
+3AA0:441028100010FF1E2810FE102AFCFF442A44FE4428286C28AA10292828442882
+3AA1:101008107F10411E08103E1008FC3E4408447F4408283E28221022283E442282
+3AA2:28104B104910491E6B10491049FC7F4408447F44012832280C10122861440082
+3AA3:102008207F20003E3E4422443E4400A47F2841285D1055105D28412845444282
+3AA4:00207F2049207F3E49447F442A442AA4FFA82A282A107F100828FFA808440882
+3AA5:10101E1010107F1E51105C1072FC4E4440445F4451285F2851105F285144BF82
+3AA6:10200820FF20813E00447E4408447EA44A287E284A107E100028244842848102
+3AA7:0810141022105D1E80903E1022FC3E4400447744112855283310552811443382
+3AA8:22101410FF9E08107F1008FCFFC449442A44FFA800287F10411041287F444182
+3AA9:04083F8804887FEE04883F88043C555475D444547FD4444875C8555455548462
+3AAA:00107F101010FF9E2210411094FC1444F7C4144477281428F790142814441482
+3AAB:10101F101010FF9E80907F102AFC5544A2447F44A2A83E2822103E2822443E82
+3AAC:0010EE102210AA1E6610AA1000FC24447F44C8447E2848287E1048287F444082
+3AAD:10101F10101EFF109110FCFC9144BF44AA44BE28AA28BE1080107F285544FF82
+3AAE:00087FC80408FFEE84283588041C359400140014EEF4AAA8AAA8AAB4EEF4AAA2
+3AAF:020001007FFC0820044003801C70E10E01001FF801000100FFFE010001000100
+3AB0:020001007FFC0820044003801C70E10E1110092005407FFC054009203118C106
+3AB1:0080208010F80108FE1009FC092449242924112413FE28502850488881040202
+3AB2:00400440024012400840084001FC7E400040004000407FF80008000800080008
+3AB3:0040044002401240084009FC7E400040004000001FF02008200820081FF00000
+3AB4:00107C10009000500010FE9028502810281E29F028102A104C10481080100010
+3AB5:101010109490585010107C9010501010FE1E11F0101010102010201040108010
+3AB6:0010FE101090105020107C9044504410441E7DF04410441044107C1044100010
+3AB7:0010FE10009000507C104490445044107C1E01F04410241028100E10F0104010
+3AB8:22082248FFA8222822083E48222822283E0E22782208FF080008140822084108
+3AB9:08087F484928FFA849087F4808287F28490E7F781008FF08210872080C08F308
+3ABA:08080848FFA80828EB88AAC8EBA8AAA8EB8EAAF8EB8814081208220841088108
+3ABB:210447C88812F3BC20084B92F83E0380AAAAABAA04401240087EFFC000400040
+3ABC:00000004FF78044004407440547E544854485448744854480448048814880908
+3ABD:0000FFFE0000000C7CF04480448044807CFE4488448844887C88450801080208
+3ABE:100010041E78224062409440087E144822484148BE482248224822883E882308
+3ABF:08004904497849407F401040207E48488848494849487F480848108820884108
+3AC0:00007C0444787C4044407C40007EFE4882488248FE4882488248FE8882880108
+3AC1:11009102AABCBBA09120AAA0BBBE8024FFA492249224A1A48024FFC400440084
+3AC2:100008047F784040524052407F7E524852485E48404855485548558880880108
+3AC3:202010201020FF20202020203E202220225022502250225042884A8885040202
+3AC4:02000100FFFE100010003FF8480884087FE810081F8810882088208842A88110
+3AC5:2020102010500088FD04220220F83C00240027FE248824882488448855088A08
+3AC6:202010200050FE50208821043E22242024A824A4252425224622542088A00040
+3AC7:10100810FF2820443E822210220842204A10840800003FF80008000800080008
+3AC8:10100810FF2820443E822210220842204A1084081FF02008200820081FF00000
+3AC9:2040104010FC0104FE0821FE21003D7C254425442554254825424542553E8A00
+3ACA:2100110011FE0200FC0021FE20083C0825E825282528252825E8440854288810
+3ACB:2080108010FE0120FE2021FC21243D2425FC2524252427FE2504450455148908
+3ACC:2080108010FE0100FE00200021FE3C1024102490249C24902490449055FE8800
+3ACD:2100110011FE0200FC902090215E3D6427542554255425482548455455148922
+3ACE:2100110013FEFC0023FE222239FC282029FC292429FC292429FC48205BFE8020
+3ACF:2100110011FE0200FDFC205021FC3D54255425FC244027FE2488459054708B8C
+3AD0:00001FF0101010101FF0101010101FF00000203823C03C04200420041FFC0000
+3AD1:004000407C40444045FC444444447C4444444484448444847D04450402280410
+3AD2:00001FF0101010101FF0101010101FF008200820FFFE08200820102020204020
+3AD3:004000407C8044FE4500460044FC7C0844104420444044807D02450200FE0000
+3AD4:00001FF0101010101FF0101010101FF00200020003F8020002000200FFFE0000
+3AD5:00001FF0101010101FF0101010101FF000007FFC04400440084010422042C03E
+3AD6:0200020003F802000200FFFE000000001FF0101010101FF0101010101FF01010
+3AD7:00001FF010101FF010101FF000001FE000400180FFFE01000100010005000200
+3AD8:00007FFC010003000570190CE10201001FF0101010101FF0101010101FF01010
+3AD9:002000207C20442045FC442044207C2047FE4420445044507C88448801040202
+3ADA:08001FF82248444808881108222804101FF0101010101FD0101010101FF01010
+3ADB:000001FC7D0445044504450445FC7C5044504450445044927C924512020E0400
+3ADC:000001F8790849084908490879F8490849084908490879F84800000007FE0000
+3ADD:0008003C7BE04A204A204A204A207BFE4A204A104A104A127A0A4A8A03260212
+3ADE:002001247924492449FC482048207BFC49044888488848507820485001880606
+3ADF:000000F87C8844884488448845067E00440044FC448444847C84448400FC0084
+3AE0:002000207D2444A444A8442045FC7C204420442047FE44207C20442000200020
+3AE1:1FF010101FF010101FF008001FF02820444003801C70E30E00C00E0001800040
+3AE2:00200020782049FC4820482048207BFE482048404840488879044BFE01020000
+3AE3:1FF010101FF010101FF001003FF8210821083FF8210821083FFA0102010200FE
+3AE4:00001FF010101FF010101FF0010000801F0001047D88095011202118C5060200
+3AE5:004000407CFC45044688445044207C40448045FC468444847C84448400FC0084
+3AE6:0840084010FC10883550542094D8170614F81488148814F81488108810F81088
+3AE7:00001FF010101FF010101FF0111009200100FFFE0380054009203118C1060100
+3AE8:0040002078204BFE4A024C4478404BFE48884888490878D04820005000880304
+3AE9:010001007FFC01000820FFFE082008201FF0101010101FF0101010101FF01010
+3AEA:01007FFC01003FF80200FFFE08203018D3F61210121013F01210121013F01210
+3AEB:00001FF010101FF010101FF000007FFC044004402448144814500440FFFE0000
+3AEC:00800080790049FC4A044C047BE44A244A244BE44A247A244BE4000400280010
+3AED:00001FF010101FF010101FF001003FF80100FFFE00407FFC0840044001400080
+3AEE:088008882E9028E028842E84F07C00001FF0101010101FF0101010101FF01010
+3AEF:1FF010101FF010101FF000003FF820083FF820083FF800007FFC04401842E03E
+3AF0:008000407BF84A084A084BF84A087A084BF84A404A444A287A104A8803060200
+3AF1:00001FF010101FF010101FF001003FF80100FFFE044024484444884211402080
+3AF2:002000207BFE482048204BFE7A024C0449F8481048207BFE4820002000A00040
+3AF3:00003FFC20002FF820003FFC24482530260E20002FF828084FF848088FF80808
+3AF4:004000447BF4484848484FFE782048404BF849104A207DFE4820002000A00040
+3AF5:0090009078904F9E4890489048907B9C4890489048904F9E7890489000900090
+3AF6:000001FC780448FC480449FC78004BFE4A22482049FC79244924013401280020
+3AF7:08207FFC08200FE008200FE00820FFFE10102008DFF610101FF010101FF01010
+3AF8:00400040F7FE904093F8904897FEF04893F890409240927CF240954004FE0800
+3AF9:1FF010101FF010101FF00000061838E020803E8022FC3E902090209040908110
+3AFA:08200820082014502288492408201450228841061FF010101FF010101FF01010
+3AFB:00400040F0A0911092089DF69000F7FC94A494A497FC94A4F4A494A404140408
+3AFC:008200827A824BEA4C8A488A4FFA788A4BEA4AAA4AAA4AAA7AA24AE2008A0084
+3AFD:000001F87808480849F8480848087BFE48204A22497448A879244A2200A00040
+3AFE:0020012478A448A848204BFE4A027A024AFA4A8A4A8A4A8A7AFA4A02020A0204
+3AFF:00A00090788049FE49104B104DFC7910491049FC49104910791049FE01000100
+3B00:004000207BFE480049FC490479FC480049FC480848107BFE4820002000A00040
+3B01:00001FF010101FF010101FF0204010A0811042E8140623F8E208220823F82208
+3B02:01FC0124792449FC4924492479FC482048204BFE4A227A2A4AFA020A02020206
+3B03:3FF820083FF820083FF8100020087FFC00043FF820083FF8110822900C60F01E
+3B04:1FF010101FF010101FF000003FFC20802FF820803FFC22204A285424A4A20840
+3B05:3FF820083FF820083FF800007FFC44447FFC0000FFFE08000FF810082028C010
+3B06:000003FC7A044BFC4A204BFE4A107A8A4B0648004BFC4A047BFC4A0403FC0204
+3B07:0080008078F849084A104DFC79244924492449244BFE78504850008801040602
+3B08:000001F87908490849F84908790849F848004BFC4A947A944A94029407FE0000
+3B09:000003FE7820484049FC4954795449544954492C48207BFE4850008801040202
+3B0A:1FF010101FF010101FF000FC7F0811103FF80200FFFE080017F02220C1C00E3C
+3B0B:008000BC7884490849FE4B204D20797C4990491049FE49107928492801440182
+3B0C:1FF010101FF010101FF00100FFFE00001FF010101FF010101FF0092011102308
+3B0D:002800247BFE482049FC492479FC492449FC492448087BFE4888004800480018
+3B0E:00001FF010101FF010101FF0082012483CF0082014503EF80000248822444244
+3B0F:000003FE780049FC4904490479FC48004BFE4A8A4A527BFE4A220222022A0204
+3B10:000003FC78904A94499848904FFE780049F84908490849F87908490801F80108
+3B11:0200011EF7D2901297D4945497D8F01497D29092911291DAF714911005100210
+3B12:008800887BFE488848244BFE7850488849044A8A48887BFE4888008801080208
+3B13:000003FE785049FC4954495449FC780049FC48004BFE482078A8492402A20040
+3B14:000007BCF08494A4929494A49050F188962690C093109064F388903000C00700
+3B15:022201127914483E4F8848884908793E4B884D484908493E7908490801080108
+3B16:02100110F79E94A494D497949408F4149462980093F89208F208920803F80208
+3B17:0110011479D24A504A7E4D5048907AA8492849444A444C8278084AA402520452
+3B18:002001FC78244BFE482449FC48207AAA4BAE4A224BFE4A227BAE4AAA02AA0422
+3B19:000E03F078444A2449084BF87A084BFC4A044BFE4A027AAA4AAA050204140808
+3B1A:02080108F7C89210949E9FD49064F7949494979494949788F488949404A405C2
+3B1B:004000A0F11896E6900093F89208F3F8900097BC908494A4F29494A402940108
+3B1C:0000FEFE20204444FEFE12127C7C10101EFEE0001FF010101FF010101FF01010
+3B1D:0104008878004BFE4A224AAA4A727A224BFE480049FC490479FC490401FC0104
+3B1E:002002227BFE480049FC490449FC790449FC488049FE4A227D52490201FA0006
+3B1F:4044402440287EFEAA922AD62ABA4A924AFE9200127C2244227C4244947C0844
+3B20:02100210F3D0945E98A493D49054F05493C89048905497E2F00092A402520452
+3B21:000001FC78204BFE4A2249AC782049AC485048C84B2678F8480800D000200010
+3B22:010400887BFE482049FC48207BFE4854499248904BFE789048D4038A009601A2
+3B23:02840284FAA496C4929E97C49004F454928C97C4910497C4F10491C40E140008
+3B24:000003FE7A024BFE4A024BFE79084A524B9C49084A527BDE480002A402520452
+3B25:3FF820083FF820083FF811101FF041047FFC0200FFFE09203558DFF605400920
+3B26:008803FE78A8489049FE4B2079FC492049FC492049FE79004BFC00880070038E
+3B27:3FF820083FF820083FF811101FF00100FFFE0A203458CF8601201FF009501320
+3B28:01100110F11097BC911091109FFEF2A892A896EC9AAA92AAF2A895A804480898
+3B29:008803DE788849DC48884BDE48887BFC480449FC48044BFC78404AA4028A047A
+3B2A:0FE008200FE008200FE07C7C44447C7C4544FFFE88020FF010101FE00020FFFE
+3B2B:0440FFFE044017D2F01C17D03452D7CE0000444482221FF010101FF010101FF0
+3B2C:07BC04A4F7BC94A497BC94A497BCF12093FE922097FC9A20F3FC922003FE0200
+3B2D:001E03E0792248944BFE4A527BFE48044BC44A7E4BC47A544BCC028402D40348
+3B2E:3FF820083FF820083FF84450FE4844FE7D9010FCFE9092FCFE901090FEFE2880
+3B2F:00803FFE0800EFF8A000AFF8A808EFF8A220BD5CB7F4BC94F5DC1C9617F62CA2
+3B30:0100010001003FF8210821083FF8210821083FF801000280044008203018C006
+3B31:28503E7C4890FEFE14281528264A44861FF0101010101FF0101010101FF01010
+3B32:00887C50100011FC7C50548855047DFC555455547D5493FE600020005FFE8000
+3B33:00803C80248025FC25203E202420242027FE3C20242024202420442054208820
+3B34:00907890489048904BFC78904890489048907BFE480048904888490849049A04
+3B35:00403C20242025FE24003C882504260224883C88245024502420445054888B06
+3B36:00207920492049FC49207A2048204BFE4800780049FC49044904490449FC9904
+3B37:00007BFE4A224A224A227BFE4A224A624A727AAA4B224A224A224A024BFE9A02
+3B38:00883C8825FE248824883C502450249425943E98249024B224D24492548E8880
+3B39:00803C8024F8250826103DFC2424242425FE3C24242425FC2424442054A08840
+3B3A:0020792448A849FC48407BFE49084A244C2279FC492449244934492848209820
+3B3B:008878884BFE48A848107BFE4880488048FC780048A848A848A848AA492A9A06
+3B3C:104010407EFE108021FC3E8424FC6484BCFC2440247C3CC42528241024682D86
+3B3D:00003CF8248824F824003DDC255425DC24003DFE248024FC2404440454288810
+3B3E:7F7848485F4C64805F784A4851307F4C00001FF010101FF010101FF010101070
+3B3F:010878884BC848104BDE7A644BD448144BD47854489448E84B8848944A949922
+3B40:0110791049DE4AA84C4478004BFC48204928792849284AB44C6248204BFE9800
+3B41:1000100013F81088FC90109030A038BC54845484910411041104120412281410
+3B42:1020102010201020FC2010A830A438A455225122922210201020102010A01040
+3B43:1020102010401040FC84108431083BF855105410902010401088110413FE1102
+3B44:100013F010901090FC90109030903BF05490549090901092108A108A10861082
+3B45:1000100013FC1000FC001000300039F85400540090001000100017FE10001000
+3B46:00003FE00420047C08043014C10801007FFC01003FF8054009203118C1060100
+3B47:1040104010801088FD0413FE30023890549054909090109011121112120E1400
+3B48:10401040104013F8FC4810483048384857FE544090A010A01110111012081406
+3B49:08200820FFFE08200920010001007FFC03800540092011102108C10601000100
+3B4A:1010111011101110FD1011FE31003900550055F8910811081108120812081408
+3B4B:10201020102013FEFC201020302039FC54205420902013FE1020102010201020
+3B4C:1020102011201120FDFC112032203820542053FE902010201020102010201020
+3B4D:40802080089C17E0E08020842084207C01000100FFFE054009203118C1060100
+3B4E:100013FC12041204FE94125432243A2456545254929413041204120412141208
+3B4F:10201020102011FEFC20102030FC3820542055FE90221022102A102410201020
+3B50:020002007FFC044008203018C10601007FFC01003FF8054009203118C1060100
+3B51:10201020102011FCFC20102030203BFE547054A890A811241124122210201020
+3B52:100011F811081108FD08110831F83900550055FC910411041104110411FC1104
+3B53:1020102010401088FD0413FE30023888548853FE908810881108110812081408
+3B54:1008103C13E01020FD2410A430A8382057FE5420902010201020102010A01040
+3B55:10201020102011FCFC20102030203BFE5420544090401088110413FE11021000
+3B56:10A010A810A41124FD20133E3BE03520512051209120112011141114110C1104
+3B57:010001007FFC0380054009203118C10600003FF82448244824482448FFFE0000
+3B58:1020102010501088FD04120231FC3800540055FC910411041104110411FC1104
+3B59:10201020102011FCFC20102033FE3808540855FE900810881048100810281010
+3B5A:1080108010FE1100FE00101C31E0392055225524912811101110114811841102
+3B5B:1004101E11E01100FD0611783150395055525554914811481144125412621440
+3B5C:1028102410241020FBFE102031243924552453A8912811101212122A14461082
+3B5D:082008207EFC08201C702AA8C826020002001FE00420042008221022201E4000
+3B5E:1020102011241122FA2A101030603B805440504093FC10441084108411141208
+3B5F:044004403FF8044004400440FFFE08203118C1061FF0030005C0193061080100
+3B60:10201120112011FCFD20122030203BFE5490549090901090111211121212140E
+3B61:10201020104011FCFD0411043194395455245524915411941104110411FC1104
+3B62:200427C422842294FA942294229477D46A94A294A29422942284248424942888
+3B63:1100108010BC1204FE0412F432943A945694529492F412941204120412141208
+3B64:1020104011FC1104FD4411243124390C550055FE9002100213FA100210141008
+3B65:1040104010F81088FD1013FC3104392455245124912411241050108811041202
+3B66:1040102013FE1202FC00103833C038405440507C93C0104010421042103E1000
+3B67:020004001FF011101090FFFE101012102150402001007FFC05401930E10E0100
+3B68:200027DE20922492FC94249427D870946992A192A292229A2494289022902110
+3B69:1004101E11E01022FD1210943080380855FE5408908810481048100810281010
+3B6A:1028102413FE1020FC2011FC3124392455FC5524912411FC112411241124110C
+3B6B:1020102010A810A8FCA8117432223820542055FC902010201020102013FE1000
+3B6C:100013FE10401080FD441224306838B055305228906810A41122122010A01040
+3B6D:200223E22222222AFA2A23EA210A710A6BEAA12AA12A212A2222222224AA2844
+3B6E:2124212422482248F9242124200077FE6880A1FCA10422882450202020C02700
+3B6F:100013FE11201128FD2811E831283928552855E89128112A113A13EA10261020
+3B70:088028882EF028842E84F17C0100FFFE01003FF821082388255809201110610C
+3B71:100011FE1100117CFD541154317C39545554557C911011101110110011FE1000
+3B72:1000105010481084FD24102030503888550652F8908810881088108810F81088
+3B73:1020102211FA1024FC2413FE3010382055FC5488911012FE1410101010501020
+3B74:108012FC12A412A4FEA8129032A838C65420542091FC10201020102013FE1000
+3B75:1100110011FC1204FA0415F43154395455F45154915411F41114100410281010
+3B76:1104110417FE1104FD44102037FE3880548054FC908410841104110412141408
+3B77:11FC1124112411FCFD24112431FC3840544053FE904210821082110212141408
+3B78:1080108010F81108FA1011FC31243924552451FC90501058109410921112120E
+3B79:10101388108810FEFC90139032243A24563853889090109010A410BE12821100
+3B7A:1020102013FE1050FC881124322239FC552455FC912411FC10221022101E1000
+3B7B:1020112410A410A8FC2013FE32023A0256FA528A928A128A12FA1202120A1204
+3B7C:1020102213B410A8FCA8112432A2384055FC5504910411FC1104110411FC1104
+3B7D:1040102013FE1200FE1C12F032903A9056FE52909290129012AA12CA14A61812
+3B7E:100013FE12021202FBFE121032923A92569252FE921012921292149214FE1802
+3B7F:200023FC220423FCFA0423FC200071806E3EA422A422242225A2262A24242020
+3B80:100011FC10081010FA2212AA32723A22567252AA932612A21242120213FE1002
+3B81:11841068103010C8FB24102033FE384054FC518492FC108410FC108410941088
+3B82:1FF010101FF010101FF010101FF01010FFFE08203118C1061FF0054009201110
+3B83:101C11E010201020FBFE10A831243A42544053FE9088110810D0103010481184
+3B84:1040102013FE1080FC8011FE31423A2255FA508290F2109211121152122A1004
+3B85:010001007FFC054009203118C90608801FFC30805FF890801FF810801FFC1000
+3B86:1020102010501088FD04128A305039FC542054F8902013FE1020102010201020
+3B87:100013FC10401040FBFE10A031103A0854465040904812641252145211401080
+3B88:1020102013FE1050FC88110432FA3800540053FE902011241122122210A01040
+3B89:211021102110227CFA10269236546A1062FEA210A22822282228224422442282
+3B8A:200827C820482288F93E208827D8715C692CA12AA14821082108210825082208
+3B8B:2100211E27F22112FA1423D4225876546BD2A252A25223DA22542250225022D0
+3B8C:100017FE10401080FBFC129432943AF45694529492F412941294129413FC1204
+3B8D:0820FFFE00003E0822483E4822483E482208261801007FFC05401930E10E0100
+3B8E:100013FE10101020FC6810A433223820540051FC915411541154115417FE1000
+3B8F:2040204027FC20E0F95022482C4673F86800A000A7FC20402248244429422080
+3B90:1020102010A410A2FD2A10103860358056FC508490FC108410FC108410FC1084
+3B91:1008103C11E01020FC2013FE302038A0552C5524912411AC1124112411FC1104
+3B92:100013FE10501050FDFC11543154395455FC5420902011FC1020102013FE1000
+3B93:1100117E11101110FD90115E3B22352A512651429152110C11041104117E1100
+3B94:1008103C11E01020FBFE102031FC392455FC512491FC102011FC102013FE1000
+3B95:100013FE10201040FDFC1154315439545554552C902013FE1050108811041202
+3B96:1088108813FE1088FCF8102031FC3924552455FC902013FE1020102010201020
+3B97:00207E20145008887F442A2249F888082810102001007FFC05401930E10E0100
+3B98:2008278820882290F91E211427E471546B14A314A51425082908211425242242
+3B99:100013DE12521252FBDE100031FC380057FE5080910011FC1004100410281010
+3B9A:010001F801003FF8210822C82D28228824483FF801007FFC05401930E10E0100
+3B9B:100011FC11041104FDFC1104310439FC540053FE90201120113C112012A0147E
+3B9C:100013FE12001224FAA412A432E43A3E57E452A492A412A4132E120013FE1000
+3B9D:2000229E22522252F5522112229272526C32A3D2A25A22542250225023D02250
+3B9E:1020112010BE1042FC841310311039285544548290FC10841084108410FC1084
+3B9F:2008200827E82108F93E220823D8765C6A6CA26AA248224823C8224820082008
+3BA0:1088108813FE1088FC0013FE3A023424502053FE907010A810A8112412221020
+3BA1:080008FC2A802CF8488808F8148022FC40000100FFFE054009203118C1060100
+3BA2:108010BC10841108FDFE13203520397C5590511091FE11101128112811441182
+3BA3:00007DFC44207D2045FE7C5048525492650E0100FFFE054009203118C1060100
+3BA4:020001007FFC49241290244818306FEC082008200FE001007FFC05401930E10E
+3BA5:10401048108411FEFC2013FE3888350453FE5524912411FC1124112411FC1104
+3BA6:1020102013FE1020FBFE1242348C39F05420504493FE10221128122414A41040
+3BA7:1040108011FC1104FD0411FC310039FE550055FE900212AA12AA140210141008
+3BA8:100011FC112411FCFD2411FC38883544524250F8918812501020105011881606
+3BA9:1020104011FC1104FDFC110431FC390455FC5440902010A4128A128A14781000
+3BAA:100013B811281128FD3A11AA37263A405420502093FE107010A8112412221020
+3BAB:1040102013FE1202FC2411FC382035FC502053FE902011FC1104110411FC1104
+3BAC:1090108811041242FC8811FC3804340053DE50429252114A12521042114A1084
+3BAD:100013FC100810D0FC2013FE328A3A5256FA5222922213FE1222122213FE1202
+3BAE:108013DE108A11CAFC8A13D230A6380854F0542091FC102013FE102010A01040
+3BAF:200027FE240225FAFC4224C2252A746A6CB2A52AA46A24AA2522244227FE2402
+3BB0:1020104011FC1104FD5411243154390455FC5400911211D4111811521192110E
+3BB1:1088108813FE1088FC2010A038FC3520502053FE90501050109010921112120E
+3BB2:1080108011FC1244FD5411F438843528529051FC9244155411F4108411281210
+3BB3:2044272425282500FD7C2710251075106DFEA710A5102528252825442B442082
+3BB4:10A0112C11241124FDAC1124312439FC542055FC908810501020105010881306
+3BB5:22202120213E27A0FA40223C23A472B46AACA2A4A2FE22A424A424A429A4304C
+3BB6:2440225E22922012F7D2211E255275526D52A7DEA152211222122222242A2844
+3BB7:1050104813FC10A0FD22121E311039E0550454FC900011FC110411FC110411FC
+3BB8:1044102412281100FD7C101030103B7E551051109128112411441280147E1000
+3BB9:2008200827C82210FA1E24A427D471146914A7D4A114210821C82E1424142022
+3BBA:010001007FFC03800540092037D8C10600007BBC4AA44AA44AA44AA47BBC4AA4
+3BBB:100011FC10A41088FC50102030D83B26542051FC9124112411FC102213FE1002
+3BBC:1040102013FC1204FA0413FC32003BDC5644535492CC124412CC1554144418CC
+3BBD:2100223C27A424A4F6A425A424C27F806CBCA4A4A6A425A424942488249429A2
+3BBE:10007E7C42447E7C42447E7C484444445A94610801007FFC05401930E10E0100
+3BBF:100011FC112411FCFD2411FC30A838A857FE54A890A811FC102013FE10201020
+3BC0:22102110211027BEFA40220023BE728A6A88A2A8A2AE22A824A825A8285E3080
+3BC1:20202710257C2500FD442628250075FE6D00A500A57C264424442444247C2444
+3BC2:22A822A827FC22A8FAAA24E6280077FC6C44A040A3F822482248224822582040
+3BC3:1020102013FE1070FCAC13223850348851245222912410A81124122210A01040
+3BC4:08207EFC08701CA82B26C820087C3F8020003FFC20002FF828884FF8480287FE
+3BC5:2040202027FE2420FC4025FC252475FC6D44A5FCA45024902BFE281030102010
+3BC6:1040102013FC1000FD08109033FE3A2056A052FC9320122012FC1420142019FE
+3BC7:1050105013DE1050FDDC105033DE385054505420902011FC1020102013FE1000
+3BC8:2010201024FE2210FA1020FE209276926AFEA210A238225422922210251028FE
+3BC9:1020103E102011FEFD20113C31E2391E550455789192115412FE121014501020
+3BCA:200027FC20402278F2402FFE210071FC6A00A3FCA00425542554280420282010
+3BCB:40004CFE7010422042FC3E84108410FCFE8430FC3884548452FC904810841102
+3BCC:2000227E21102130F84A209A262C724C6A9AA22AA24A22882228251028FE2000
+3BCD:20902290229E22A2FAD423A8209470A46FFEA284A2A422942294228424942888
+3BCE:22082108210827C8F83E27882018779C682CA7AAA4C824882488278824882008
+3BCF:08007F7808483E4800863E782A483E304048808401007FFC05401930E10E0100
+3BD0:00407BFC488049F852204DFC488868F8508840F8408801007FFC05401930E10E
+3BD1:20002F3E2120213CF1202F3C282078FE6850AF52A1542148214821442A622440
+3BD2:200E27F020442224F90823FC220473FC6A04A3FCA20423FC2090211022122C0E
+3BD3:204020A0211826E6F80023F8220873F86800A7BCA08424A4229424A422942108
+3BD4:01F03E0003F03E0003FA7E0201FE0C20703C1DE2F0221C1E0100FFFE0920711C
+3BD5:22402242225C27F0FA5023D0225E73D46A54A254A7F420142294246428242044
+3BD6:1020102013FE1020FDFC1154315439FC540053FE9040102412A2128A14881078
+3BD7:200027BC24A427BCFCA427BC244474446DF4A444A4E42554264C244424542408
+3BD8:2108210827C82108F91E2392202473806808A7C8A10821082594295425242242
+3BD9:2208210827C82210F49E2FD4206477946C94A794A49427882488249424A425C2
+3BDA:1210121013DE1228FD4410A031103A0855F65000900013F81208120813F81208
+3BDB:1020102013FE1020FDFC100033FE3A52545051DC910411DC1050105013FE1000
+3BDC:1088108813FE1088FC2013FE3088388855545222902017FE1020102010201020
+3BDD:2010279024BC24A4F4C427A8211071286946A5C0A53C2524252425A42E3C2024
+3BDE:2080209E21122152FA5E2780209E71126A52A7DEA052201E2552255224122016
+3BDF:10101010FEFE3838545492823FF000101FF00010FFFE111009A005401930E30E
+3BE0:102013FE104810F0FC2013FE3242389055F85028912011FC122017FE10201020
+3BE1:10401040FEFC3884550492F42894449492F410845494388854829282507E2000
+3BE2:100013DE125213DEFE10125231CE3800548853FE9088108813FE108811041202
+3BE3:21082FFE21082090F10823FC2C8A71286A50A040A7FC20E0215022482C462040
+3BE4:101010101010FEFE1010545454545454BABA1010383854549292101010101010
+3BE5:10101010FEFE10107C7C54547C7C54547C7C1010383854549292101010101010
+3BE6:211027FC211021F0F91021F0211077FC6910A248A44623F820E0215826442040
+3BE7:2100213C211427D4F91421242FCC7100693CA524A5E4253C2724250024FE2800
+3BE8:100013FE10501050FBFE125232523BFE552450A893FE107010A8112416221020
+3BE9:00107E1022FE1C10227C7714557C2250557E08127F121C162A28492888440882
+3BEA:100011FC102013FEFA2211AC302039AC545050C8932610F8100810D010201010
+3BEB:1040107C104013FEFA42127833C43A3C560053FE924013A4125815B4145219B0
+3BEC:1010FEFE5454929200407BF8084817FE20487BF808400BF8504027FC584087FE
+3BED:1040107C104013FEFA4213F832443AFC56A852F892A812F8122015FC1444198C
+3BEE:100011FC11541154FDFC108031FE3A4255F25152915211F2104A13FA100A1004
+3BEF:108011FC12881070FBAE10F8312039FC542051FC910411FC110411FC10881104
+3BF0:11FC1154115411FCFC2013FE302039FC550455FC910411FC110411FC110417FE
+3BF1:01007FFC11101FF00100FFFE90021FF821007FFC11101FF00100FFFE0920711C
+3BF2:2110211027BC2110FBB82554291270006BF8A000A7FC20402248244429422080
+3BF3:2288228827E8FA90241E27E474546854AF54A554255427482548205422942122
+3BF4:1088108813FE1088FC2013FE3202388855245450908811FC128A108810F81088
+3BF5:211027FE211023F8F84027FC204073F86A48A3F8A24823F8204027FC20402FFE
+3BF6:1020108812521326FE52128A32223BFE54885144927A10881150102010D81706
+3BF7:212821AA216C2228FAFE264436286AFE6210A27CA21022FE2210222822442282
+3BF8:204023F8204827FEF84823F8204077FE6800A2A4A45223F822A822A82FFE2000
+3BF9:20042FE422842FE4FABE2AA42FE470046FD4A00CAFEC2104254425242924230C
+3BFA:00407E40487E7EA043107EFE48AA48AA7EFE000001007FFC05401930E10E0100
+3BFB:01007FFC11101FF00100FFFE82120D2032C00DA032900D883100FFFE0920711C
+3BFC:108813FE10881020FDFC102033FE3840548855FC900011FC1154115417FE1000
+3BFD:102017FE140213FCFE2413FC32003AFC568452FC928412FC128414FC14481884
+3BFE:202824FE222822FEF8AA20FE2EAA72FE6A00A27CA244227C2244227C250028FE
+3BFF:1124124811241000FBFC129432643A9457FC524893681248136A124A12461362
+3C00:10501190109E13EAFC8A11D2328A38A454505088932610A8107010A811241060
+3C01:200027FC2100FBF82508210871F86800AFBEA208279E24922CB22492279E2492
+3C02:202023FE2202241CFBE0212420A873FE6924A202A5FC212421FC212421FC2104
+3C03:220624382F882892FFA428BC2F8872146FBEAA8AAA882AAC2AAA2BCA22282210
+3C04:20142792249E24F0F794248A249677E26C94A492A79E20702514248A28962062
+3C05:2020201024FE2244FA2820FE209276FE6A92A2BAA2AA22BA2286250028FE2000
+3C06:01007FFC11101FF00100FFFE82823EF802807EFC028001007FFC05401930E10E
+3C07:2114211227D22110F1102FFE229076D26A92A6D2A29426D4228A22CA2F162022
+3C08:1010FEFE54549292004027FC104013F8024873F8124813F8104017FC284047FE
+3C09:201020102F7E2410F43C29102F7E72246A4AAF30A210227E23382E5424922010
+3C0A:2108210827AA212CF1082FD4201274A26948A108A7AA212C210821942E242442
+3C0B:2100213E250825D0F53E25222FE2703E6922A57EA56225A228BE210022142C22
+3C0C:11FC102013FE1222FDAC102031AC389055FE532095FC112011FC112011FE1100
+3C0D:08407F7C1440FF7C22043E7C22403E7C2242263E01007FFC05401930E10E0100
+3C0E:1020122213FE1090FDFE131035FE391055FE551091FE110013DE125212721206
+3C0F:110811EE12941020FBFE100030F8388854F8500093FE120212FA128A12FA1206
+3C10:2008273E2590255EFD64265E250075DE6D52A55EA552265E2452245624A0251E
+3C11:20202294228A247AF800228A31446A286AAAA186A0402FFE215022482C462040
+3C12:22A0244C24A4260CFCA4264C34A46FFE6802A3F0A020204027FC204021402080
+3C13:27D0251027DE2450F7E8250427C473F86A08A3F8A20823F8220823F821102208
+3C14:224822E8230826EAFA1C22E832086AE865B4A8E2A00023F8211020E023182C06
+3C15:211027FC204023F8F84027FC200073D46912A7FEA3502534238C208A22962102
+3C16:13D0129013DE1268FBC4128433F8390855F8510891F8110811F810901112160E
+3C17:201427FE249024D4FC9427FA35AA6A9661A2A3F8A20823F82040227C254028FE
+3C18:208020F8210821F0F81027FE255473BC6FCAA13EA388256A208827FE20882108
+3C19:251825142F90253EF72822682FBE7AA86FA8A23EAFA822283FE8253E28A03060
+3C1A:220C210A27C8229EF55426F4245E77D46914A7DEA554255425D4245E25502490
+3C1B:21102FFE255424E4F8A82AAA2EEE74A46AAAAEEEA2422FFE215022482C462040
+3C1C:2200221E2FC42208F79E24922792749E6F92A49EA79224922FDE2500248C2892
+3C1D:00403E402240227C2284228823203E2020202050205022502C88308821040202
+3C1E:082008200820087E49424984491049104910491049284F287948004400840102
+3C1F:202020207F20807E00427E8400100010FC100410042805280528034401440082
+3C20:102008200820FF7E004200843C10241024102410242825284648444480840102
+3C21:082008201420127E214240849210121012101210122812282228224442448282
+3C22:00207E202420247E244224842410FF1024102410242824282448244444848502
+3C23:142014201420547E55425E845410541054105410542854285D487644C4840102
+3C24:00200020FFA0027E02427A844A104A104A104A107A284A28024802440A840502
+3C25:122052205220527E5242FF845210521052105E104028402840487FC400840102
+3C26:0820082008207F7E084208840810FF901010101024284228FF48414400840102
+3C27:104010402040287C4484FE88432000207C2044504450445044887C8845040202
+3C28:002000207E20427E4242428442107E1042100010242822284248424480840102
+3C29:0820082008207F7E49424984491049107F10481008280A280F48F14440840102
+3C2A:0820082008207F7E08420884FF100010081008107F28082808480F44F0844102
+3C2B:0820282028203E7E4842088408107F1014101410142814282548264444848102
+3C2C:2020202020207F7E41428184791049104910791049284928792801440A440482
+3C2D:10401040FE40287C448482887D200020FE20205040507C500488048829041202
+3C2E:00207F204020407E5E42408440107F10501051105A2854285228914498441082
+3C2F:0020FF200020007E7E424284421042107E1000104228222824280F44F0444082
+3C30:082008207F20087E08422A842A102A105D108890082814281428224442448082
+3C31:072078200820087E7F4208847F10491049107F10492849287F28084408440882
+3C32:0420052004A0FFBE042204447550559055107310029032A8C5A808C410440082
+3C33:0040FE402840287C2884EE88832082208220EE50285028502E88F08841040202
+3C34:102008207F20007E22421484FF10001000103E102228222822483E4422840102
+3C35:1020082000207F7E004222842210551088900810FF2808280848084408840902
+3C36:222022203A204B3E4AA2AA4412502890479080103F102128212821443F442182
+3C37:00200020FFA0227E22423A844A104B904A10AA101228122822A8234442448082
+3C38:082008201420227E4142BE84081008107F10491049287F280848144422844102
+3C39:0110019001507F9E411241225D08414841485D48558855945D54415442D48462
+3C3A:002077205120513E512277444050409077104110491075284228424445444982
+3C3B:08200820FF20083E08227E4400507E90421042107E10422824280F44F0444082
+3C3C:0020FF208820887EFE428884AA10AA10DD10881094289228A128C044FF440082
+3C3D:0020FFA08020BF7EA142BF84A110BF108810FF909228B2288C289244A144FF82
+3C3E:082010207E20427E7E4242847E1010100810FF1020283E28224842444A848502
+3C3F:0E40F0402240927C448420884520F82010202450FE501050FE88288845048202
+3C40:202020207F20917E55427D8421104A10A4107F10912855287D2821444A448482
+3C41:08202A202A203E7E494249847F1000103E1000107F2808282A48494428841102
+3C42:041002103FD0221E2F9222A43FC822882F88220832482A9427144A9452548622
+3C43:082014202220497EBEC204840810FF9014107F105528632841487F4441847F02
+3C44:00207F2049206B7E5D4249847F1008107F1008100F28F0280128554454444082
+3C45:0820FFA008207F7E0042FF8480907F1000107F1041287F28412822440FC4F082
+3C46:08200F2008207F7E49424C847910471040105F1040285F2851285F448A443F82
+3C47:08207F202A202A3E5D220844FF5000907F1041105D1055285D2841447F444182
+3C48:22202220F7A0227E7742AA84225000107F100010FFA80828492888C428441082
+3C49:142055203620147EFF42228414107F1008107F100828FF281C282A4449440882
+3C4A:FF2010207E20427E7E424284FF1091104A10A5101C2820287E28A2441C44E282
+3C4B:3F9004107FD0445EB5920424358812083FC86408BF8824143F9424143FD42022
+3C4C:7F8821083F0821083F1E21D2FF240100FFC852887388528873945AD4F7A410C2
+3C4D:4848444840485E4EA0AAAEB2C0C44E4440448E84AAA4EAEA0A0AAEAAAAAA0010
+3C4E:7F2055207F202A7E49422A8461103E104410FF1049287F2849287F440044AA82
+3C4F:00001FF00000000000007FFC01000100110011F81100110011001100FFFE0000
+3C50:000000103F0800080000FFFE00000400040027002400240024002780F8004000
+3C51:0100010011F811001100FFFE020004000FF0101068200440028003001C00E000
+3C52:0100010011F811001100FFFE0000FFFE00101F90109010901F90001000500020
+3C53:08200820085048504E8849244A12481049FC4804480848884E50F02000100010
+3C54:044004441748147014421742783E020007F0081034200240008003000C007000
+3C55:100011FC100410FC50045DFC500053FE5222502051FC5D247124C13401280020
+3C56:1040102013FE100050885C88515452225000502053FE5C207020C02000200020
+3C57:1020104011FC110451FC5D0451FC510451FC502850245DFE7050C08801040202
+3C58:3FFE29142F1229102F7E20102F2829282F2829442F4429824B40447C84401FFE
+3C59:000003FEFC40204020803C80450045FC64049404080408041004200440288010
+3C5A:000000FCFC84208420843CFC44844484648494FC088408841104210442148408
+3C5B:00000000FDFE202020203C7C44444484648495480A2808101010202040408080
+3C5C:00000020FC20202020203C204520453C652095200920092012A02260443E8800
+3C5D:00100010FF902210227E3A124A124B924A12AA121212121222922322422A8044
+3C5E:00800040FC40200023FC3C0044084508650894900890089010A0202047FE8000
+3C5F:00100010FC1021FE21123D14451045FC65449544092809281110222842448482
+3C60:00200020FC20202023FE3C204420442065FC9504090409041104210441FC8104
+3C61:00200120FD2021FC21203E20442047FE6490949008900890111221124212840E
+3C62:00400020FDFC210421043DFC4504450465FC9520092209141108214441828100
+3C63:0004001EFDE0202221123C944480442065FE9444088409C81030202840C48302
+3C64:00800086F898209023D03890489E499469D49AB40A94149410942094409480A4
+3C65:00200020F9FC202020203BFE488849446A4298F8098812501020205041888606
+3C66:00200020FDFC205020883D0447FE440865E89528092809E81128200840288010
+3C67:00400020FBFE22022504390049DE4A526A529B520C9A1094111021124212840E
+3C68:00400020FBFE2202240438004BFE482068209920093C112012A02260443E8800
+3C69:00200020F9FC202020203BFE4802489468509910089013FE1028204440828302
+3C6A:000001FCFD0421FC21103DFE4510454A6586940009FC090411FC210441FC8104
+3C6B:0020FC2023FE202021FC3D2445AC4574652495FC0820087010A8212442228020
+3C6C:000003F8FA48224823F83A484A484BF868009FFE0A4012441228229043088206
+3C6D:00800338FA28222823A83A464A004A7C6BA49A240A2813A81610222842448282
+3C6E:00200020FDFC212421FC3C2047FE440065FC9504092409241124205040888304
+3C6F:00200124FD24212421FC3C0047FE440065FC9504090409FC1088205043FE8000
+3C70:0040FC2023FE224220203DFC4488445067FE9420082009FC1020202040208020
+3C71:00200040FBFC222422243BFC4A244A446BFC984008A810B4113C21224222841E
+3C72:02080108F910200027FC380049104A086C049BF80AA812A812A822A84FFE8000
+3C73:04407FFC04401FF010101FF010101FF00400FFFE10102FE8C2060FE004403F80
+3C74:002003FEF82021FC20203BFE480049FC690499FC090411FC110421FC40888104
+3C75:002001FCFC20208823FE3C8845FC450465FC950409FC090411FC208841048202
+3C76:00820082FBF4208820803BE248024BE46A289A200BE012221142207447888210
+3C77:00A00090FDFE232021FC3D2045FC452065FE950008200BFE107020A843268020
+3C78:001003C8FA7E224022623BD44A004A3E6BC89A480E7E1248124823C842488008
+3C79:000003FEFA2222CC22443BEE4A444AEE6B549A440A101290129E249044908BFE
+3C7A:0040007CF84023FC22443BF04A444AFC6AA89AF80AA812F8120025FC45548BFE
+3C7B:00401FFEE40047FC400077FC540497FC51102EAE2BFA2E4A4AEE4E4A8BFA1650
+3C7C:00003E78224822482248228622003EFC20442044202822282C10302820440182
+3C7D:0800087808487F4849480886080014FC14441444142825282610442880440182
+3C7E:100008780848FF480848108622007CFC094412442428C82814102228C0440182
+3C7F:10001078FE48104810487C86000000FCFE4482448228BA28821082288A448582
+3C80:00007F78404840485E48408640007EFC504451445A2854285210512898441182
+3C81:20001078FE48824828484486820000FC7C441044102810281E10F02840440182
+3C82:10009278524854481048FE86820082FCBA44AA44AA28AA28BA1082288A448582
+3C83:100010781E4810487E4842867E0042FC7E44004420283E28201022282C443182
+3C84:10001078FE4810487C480086FE0082FC00447C4410287C2810101E28F0444182
+3C85:20001078FE48824810487C8610007CFC1044FE4410287C28441044287C444582
+3C86:08007F7808483E4800863E782A483E30414882840C603118CFE6004006800180
+3C87:08007F7808483E4800863E782A483E3048489FF4282007C01830E18E0C400300
+3C88:08007F7808483E4800863E782A483E30404880867FF8080810303FF8D0081FF8
+3C89:1000FE7810487C480048FE8682007CFC2044CE44AA28EE28AA10EE2828444982
+3C8A:10001F381028FFA880A87F462A00557CA2247F24A2A83E2822103E2822443E82
+3C8B:080008001FE020204040BFF8200820083FF8000020843E9820E020842684387C
+3C8C:08001DF87048104810501C5C7084108410841D04F1281212100210020FFE0000
+3C8D:1010103811C0FE40107811C0FC40447C47C0284428441044183C240043FE8000
+3C8E:04080E1C70E0102010201C3C70E0102010201E3CF0E0102214221822101E0000
+3C8F:0408243C25E0242024203E3C21E020203C20243E27E02420242244224422841E
+3C90:08201C207050105010881D44722210F810081C10F0101022102210020FFE0000
+3C91:08201C207020102411A81CB070B0112811281D24F22410A0104010020FFE0000
+3C92:2008201C40E07E208220023C7AE04A204A204A3C7AE04A2202220222141E0800
+3C93:08281C24702411FE11201D2871A8115011141D34F14C1104120010020FFE0000
+3C94:1004080E7F7000102210141CFF7008100810081E7F700810081208120812080E
+3C95:04081E1CE0E022209220543C40E00420FF20043C44E0242224220422141E0800
+3C96:0804490E29702A1008107F1C417041107F10411E41707F10411241124512420E
+3C97:04081E1CE0E0022092204C3C00E0FE200420083C0EE0F82248220822281E1000
+3C98:00087E1C42E042207E20423C42E07E204220423C7EE0002224222222411E8100
+3C99:08401C2071FE104010881DFC700410A810A81CA8F12A1226100010020FFE0000
+3C9A:1020082040A824A4092A723010C0170000F03F0001F03F0001F87F02010200FE
+3C9B:20003E7C48440844FF441444227C400000F03F0001F03F0001F87F02010200FE
+3C9C:1008521C54E090202820443C82E010201020523C54E0902228222422421E8000
+3C9D:08501C4870FE119012901CFE7090109010FE1C90F09010FE108010020FFE0000
+3C9E:1004080E00707F100010221C227055108890081EFF700810081208120812080E
+3C9F:2204220E7F7022102A10081C3E702A102A102A1EFF700810141212122212400E
+3CA0:082008207E7E08C4FF281C102A2848C600F03F0001F03F0001F87F02010200FE
+3CA1:0804080E7F701C102A10491C00707E100010FF1E08704A10491289122812100E
+3CA2:1004080E7E70421042107E1C427040107F10551E55707F10D51255125512430E
+3CA3:5008961C92E09220D620923C92E0FE201020FE3C02E0642218222422C21E0000
+3CA4:1004080E7F7000103E10221CFF7022103E10189E35705210911214921812100E
+3CA5:1004080E7F7048105E104A1C7F704A105E10481E5E705210521252125E12920E
+3CA6:102010201050FE8811067C1844E07C2044387CE01020FE3C11E010221022101E
+3CA7:10003BF0E150211020A03840E1B0264E21F03950E1F0204823FA200A20021FFE
+3CA8:2408241CFEE024200020FE3C24E03C2024203C3C24E02E22F4220422041E0400
+3CA9:10003BF8E20823F822083BF8E00027BC20843CA4E29424A42296210A20021FFE
+3CAA:0A04740E157052102210211C5D7080107E10421E42707E10421224120F12F00E
+3CAB:2808AA1C6CE02820FE20443C28E0FE2010207C3C10E0FE2210222822441E8200
+3CAC:2808241C7EE0C82048207E3C48E048207E20483C48E07E224022AA22AA1E0000
+3CAD:0804290E29704A101410221C4170001022102A9EB7706210221252124512888E
+3CAE:12103A10E3DE252820843840E0A0211022E83C04E1F02110211221F220021FFE
+3CAF:00047A0E52707B904A107B1C54F0789000107F1E5570551055125792FC12000E
+3CB0:0804FF0E91704A10A5101C1C00707F105510FF9E00707F10081208122812100E
+3CB1:11243A48E12423FC22943A64E29423FC22483B68E248236A2246236220021FFE
+3CB2:7F04490E7F704910FF90AA9CFFF0AA90FF90001EFFF0A2903E1222122792F80E
+3CB3:08201C20F120912091FC9120FE20902093FE902090508A50A688D28809040202
+3CB4:20003FFC40009FF000007FF0041004107FD0445044507FD2444A040A04060402
+3CB5:20003FFC40009FF000007FF0249015107FD040507FD040527FCA404A41464082
+3CB6:20003FFC40009FF000007FF0041007F004107FD055504A5264CA4A4A55467FC2
+3CB7:20003FFC40009FF000007FF02A903B9000103F9024903F92248AFFEA04060402
+3CB8:0000200013FC1008801040204840088010801100E10022022202220221FE0000
+3CB9:000021F011101110811041104910091011101110E210221222122412240E0800
+3CBA:00402040104010408040404E48700FC010401040E040204220422042203E0000
+3CBB:0840084008401044176831703160515091501248124814441842104011401080
+3CBC:0000200812081208820841104910091010A010A0E040204020A0211022080C06
+3CBD:000023FC10841084808442844A840A8414841084E08420842104210422280410
+3CBE:020001007FFE40028104010001003D8405880950092011102108C10605000200
+3CBF:00402020102013FE820042004A000A0012001200E20022002200240024000800
+3CC0:009020881088108080BE47C04080104410442048E03020222052218A26060002
+3CC1:000023FE12001220822042204A200A2012201250E25022502488248829041202
+3CC2:0020212011201110811042484248144418822080E1102108220827FC22040000
+3CC3:0080208013F010908090411249120A4E14401040EFFE20402040204020400040
+3CC4:00802080108010FC8104410842401440104020A0E0A021102110220824040802
+3CC5:0000200017FE102080204040484008D011481244E44220402040204020400040
+3CC6:00102110109010908010421049100910101E17F0E01020102010201020100010
+3CC7:0020211011081204820444104110111010A020A0E04020A02110220824040802
+3CC8:004020401040104087FC40404950095011501150E1522252224E244020400040
+3CC9:000021FC11041104810441FC49040904110411FCE10421042204220424140808
+3CCA:00802080110011FE8210421045101110111020A0E0A0204020A0211022080406
+3CCB:0008203C13C01200820042004A000BFC12201220E2202220222022202FFE0000
+3CCC:000027FC14441444844447FC44441444144427FCE44420402040204020400040
+3CCD:00402040104017FE808040A0492009FC13241524E12421242134212820200020
+3CCE:0040204010801110820847FC40041110111027FEE11021102210221024100810
+3CCF:00402040104017FC844444444444144417FC2040E24021402080214022300C0E
+3CD0:011021101110111087D041104310139015502510E910211221122112210E0100
+3CD1:0000200013F812A882A842A84AA80AA812A812A8E2A822A822A82FFE20000000
+3CD2:00402040104017FE80A041104208142610202040E0802108220427FE22020000
+3CD3:004020401040104087FE40804880090013FC1504E90421042104210421FC0104
+3CD4:000420041784108480BE4484428412A411142114E28422842484280420140008
+3CD5:0000210810881090800043FE48000800100011FCE00020002000200023FE0000
+3CD6:00802040104017FE808040804940094413481530E92021102108214421820100
+3CD7:000023F81108115080A0404041B0160E10402040E3F820402040204027FC0000
+3CD8:00802040104017FE80804110420817FC11242120E120212022222222241E0800
+3CD9:004020801108120487FE400248000BFC120413FCE20423FC2204220422140208
+3CDA:002820241024102083FE42204A240A24132412A8E22822102212242A24460882
+3CDB:00402140165C14448444475C4444144417FC2444E0A020A02110220824040802
+3CDC:009020901090111081FE43104D10093811381154E15421922110211021100110
+3CDD:01002108111C1270821046104A10121012FE2210E210221022102210227C0200
+3CDE:011021101110121082FE469256921A92129222FEE29222102210221022100210
+3CDF:044004403FF804400440FFFE082011102928C546038005400920311005000200
+3CE0:001024101210121080FE40104610122812242244E24222822200250028FE0000
+3CE1:040842082208200800FE8E084248522812282208E20822282210250028FE0000
+3CE2:0010207813C01040804047FE48A0091012081516E11021102110221022100410
+3CE3:00402040104413F48048405047FE104010802184E29824E028822082207E0000
+3CE4:011049102510251001108FFE4110511015982554E95422102210241028101010
+3CE5:000027FC1040104083F84040404017FC11102110EFFE21102110221022100410
+3CE6:0014401220102FFE00108290429252921FD22294E2942288228A249A24260842
+3CE7:00002FFE14801490849047904490149014902790E490249224D22F92208E0080
+3CE8:012421241248124881244124400017FE108021FCE10422882450202020C00700
+3CE9:0000407C20442E44046484544454544415FE2444E7443C442044208420940108
+3CEA:000027FC1020104080D041485244144410402000E3F822082208220823F80208
+3CEB:010001087D1005A009603118C50602000C00307820083C78200820083FF82008
+3CEC:0100210011FE1200840041FE482208241120113CE1202120212022A0247E0800
+3CED:000023F812081208820843F84040104017FC20E0E15022482444284220400040
+3CEE:000023FC1204120483FC42004A200A2213B212B4E2A822A8252425242AA20040
+3CEF:0080204017FC1000811040A04FFE104010402040E7FC20402040204020400040
+3CF0:0040202013FC1040809041084BFC080411101110E7FE21102110211022100410
+3CF1:0000278014BC152485244624452414BC14A424A4E6A42524243C242424000400
+3CF2:0020482024202020082085FE4420502012202450EC502450248824C825240202
+3CF3:00402040104017FC804040404BF80A08120813F8E0A020A021222122221E0400
+3CF4:004020281088129082A442C2448A118816782000E04027FC204020402FFE0000
+3CF5:003823C0104017FC80E0415052481C4613F02020E04027FC2040204021400080
+3CF6:00E84F08222829280548800847C8508811082108E1E82F08210A210A250A0206
+3CF7:0100210011FC12A484A441244A44089411081000E3FC220423FC220423FC0204
+3CF8:0108210817FE1108810840004890089211141318E510213221522112210E0100
+3CF9:0200420022FE22100F9082104610577C16902A90EA103210221022FE22000200
+3CFA:02404240227E22800F00827842085308121026FEEA102210221022102A500420
+3CFB:01102110111017FC811041104FFE100013F82208E20823F82208220823F80208
+3CFC:00500048FFFE00403E4022243E2800120E2A70C6030A7D90096011202518C206
+3CFD:002027201120113E814047404490141014102754E15221522192211025500220
+3CFE:02082108111017FC8040404043F8104010802FFEE1202120222022222422081E
+3CFF:0040202013FC1040809041084BFC0844104017FCE0E0215022482C4620400040
+3D00:0108210817FE11088000403C4BC00820101013FCE0082010206021802240043E
+3D01:000023F8104010408FFE41104208151613F82110E11027FC2110211022100410
+3D02:0020402020202EF804A884A844F854A814A824A8E5FE26883888208820A80090
+3D03:0040202013FE1202820243FE4220122013B222B4E2A824A82524292432A20040
+3D04:000027FE14021492848A450A4402140214F22492E49224922492249227FE0402
+3D05:010001087D1005A009603118C50602003FF82448282837D8244827C820083FF8
+3D06:000023F8100811F8800843F8400017FE14422844E3F822482248224822580040
+3D07:1088108810881088D6EA52AC52A85AA856EC52AA52AA94C81088108852A82110
+3D08:0010203813C0120083FC4220422012201FFE2000E04024442444244427FC0004
+3D09:00402090110813FC8108421044A417BE10822000E3FC20002000200027FE0000
+3D0A:044422441284101487D4411445541554155427D4E15421142204220424140808
+3D0B:0040204013F8104887FE40484BF8084012481248E2E823582248224824480848
+3D0C:02104210221022100F7E851045105510157C2944E544224422442544257C0844
+3D0D:03F04010202020440E5883F04250524815E82448E4442BF43042204021400080
+3D0E:0040204017FC10A08110420845F61000100027FCE04022482244244421400080
+3D0F:0080204017FC140481104208440413F810402040E3F820402040204027FC0000
+3D10:000040FE2F1029100950895E4F52495219522F7EE902290229022F0229140008
+3D11:0040202017FE14008504448847FE142015242524E52425FC2844288031000200
+3D12:0080204017FE1090829844944114123014002110E1102FFE2110211022100410
+3D13:000023FC1244124483FC42444A440BFC10001040E0242522250A290820F80000
+3D14:0080208011F81208841043FC480409FC100413FCE00420402124252A250A08F8
+3D15:0108210817FE1108800040384BC00840104017FCE0E021502248244428420040
+3D16:0110211017FC111081F0404043F81248124823F8E0402FFE2040204020400040
+3D17:000023FE1050105083FE42524A520BFE10001040E7FE20882190206020D80304
+3D18:000027FE140215FA840245FA4402100013FC2204E3FC220423FC220423FC0204
+3D19:0008203C17C0104080404FFE40401140165C2444E444275C2444244427FC0404
+3D1A:02082110100017FE80804184424414A811302270E4A8212822242C2220A00040
+3D1B:0008200817C81210821E44A447D41114111427D4E114210821C82E1424140022
+3D1C:0080204017FC1404840447FC4400140017FC26A4EAA42BFC2AA42AA432A4020C
+3D1D:060478440844FF441C442A44C9140A880C603118C92605400920111025080200
+3D1E:0008203C13C010448224412849000A7C12441244E27C224422442244227C0244
+3D1F:000023FE120012FC828442FC4A840AFC120012FCE208221023FE241024500820
+3D20:00008FF8401000208040577A554A156A35525552D76A504A514250825FFE0002
+3D21:003823C01040104087FC41505248144613F82208E20823F82208220823F80208
+3D22:0090909048900190917C4954495403542554497CD95449104910491049100110
+3D23:002090204BFE002091FC482449FC012025FE4822D82A48544850488849040202
+3D24:021042082200227E0F9082104210571016FC2A10EA102210221022FE22000200
+3D25:04108410445404389510557C55441544357C5544D544577C5944404440540048
+3D26:0040202017FE1402800041F84908090811F81000E3FC22042204220423FC0204
+3D27:0040208013FC120483FC420443FC120413FC2000E04020242522250A28F80000
+3D28:0044272415281500857C47104510151015FE2710E5102528252825442B440082
+3D29:012422481248112483F842084BF8080013F81248E24823F82202220221FE0000
+3D2A:0040208013F8120883F842084BF80A0813F81040E7FE20E02150224824460040
+3D2B:40002FDE225282525FF4425402582FD4241247D2CC524C5A545467D044500010
+3D2C:010822081788148887BE4488478814C814A82FA8E18822882488288822A80110
+3D2D:0080204017FC140480A041104A08080013F81208E3F8220823F8220823F80208
+3D2E:000027FC1404140487FC4420452414A815FC2504E5FC250425FC290429141108
+3D2F:002027A414A814B084A247A2449E148014BE27A2E4A224BE24A228A22ABE1122
+3D30:01102212145417D88010401247D2144E144027D2E454245827D024522552048E
+3D31:0080204017FC140480A041104248104017FC2040E44422A820A0211022080C06
+3D32:0004203E17E0143E842045FE4522153815E2251EE50029782A48324A248A0906
+3D33:04484444244024FE04509F544458545214542458E45227543C9A2092212E0240
+3D34:002024A414A8152084504488450417FE142024A4E52824502488250427FE0000
+3D35:00402028109012A482C2448A41881678100023FCE2942294229422942FFE0000
+3D36:0080208017FE1522811043FC56201A2013FC2220E22023FC2220222023FE0200
+3D37:00104F9025102510077C855447545510151025A8E7282D28214A214A21860100
+3D38:000027BC14A417BC84A447BC4404144414442444E4A424942514240424140408
+3D39:0010209214521254821040FE4010163812542292E31022102210250028FE0000
+3D3A:00208820442005FC902048A848A804A825744A22D85048504888488849040202
+3D3B:00044FC42004200407BE8484448454A417942014E8842484250421C42E140008
+3D3C:0040202017FE1402810041FE421016201A7C2244E244227C22442244227C0244
+3D3D:0008403C27C02040024881504FFE515012482C46E08020442A422A1231F00000
+3D3E:010841082FC82110011E8FD44864401417942094E11421C82F08211425240242
+3D3F:0000407E2F902220027C82444244527C1244227CE2442244227C2A0024280044
+3D40:04204220223E2F4004A08420473C555015102510E5FE2510252829282B441082
+3D41:0108210817FE1148802047FE4880090813FC1004E1502150215022522252044E
+3D42:0040202013FE1200824842484BFE0A4812481248E27822002554252A2A2A1000
+3D43:0410840844081F7E95425542552015243F284430C420452247A25CA2481E0000
+3D44:00142012101217FE801043D04A500BD4101417D4E11427F8210A228A24560822
+3D45:004020A0111012488DF6402048400BF8120813F8E20823F8220823F821100208
+3D46:000840282F28293E0928894849084F7E19002900E93E29222F222922203E0022
+3D47:01A44E2422242224027E8FA44224522412242FBCE8A428A428A42FA428BC0024
+3D48:008890884888008893DE494849480148255E4A52D95248924892495E49520200
+3D49:008890884888008893DE48884888019C25DC4AAADAAA4CC84888488848880088
+3D4A:000023F8120813F8820843F850001FFE148027BCE494279424D42F88209400A2
+3D4B:000027FC14A414A487FC40004BF80A0813F81208E3F8220823F8211022080404
+3D4C:0408841C49F01110A51045FE4910197C2944497CC944497C49444A444A7C0C44
+3D4D:0000279E1492179E8492479E44421422140A2546E542255226322402240A0404
+3D4E:079E2492179E1492879E440244F2149214F22492E4F224922492253224020406
+3D4F:0110211017FC1110804047FC4110111012A82444E0402FFE2040204020400040
+3D50:40002FFE28008A2849484BEE089228842AA04AA8CBE848884894491449241242
+3D51:0200420027BC22A404A485BC480053F8120823F8E20823F8220823F821100208
+3D52:009027FC109413FC829043FE49120BFA150E11F8E10821F8210821F820900108
+3D53:008040402FFE280203F8820843F8520813F82000EFFC2240227C254024FE0800
+3D54:0040204017FC11108248444643F8105017FC2080E3F82D0821F8210821F80108
+3D55:0080211013F8121084A447BC404010A013582C46E04822642252245221400080
+3D56:0100210017DE125286924112429E14C0111023E0E04827FC2254244829440080
+3D57:43FC22400BF80A4013F82240E3FC20042554200801087D90096011202518C206
+3D58:08100A146AD42C582A544A94A950102008100A146AD42C582A544A94A9521020
+3D59:004027FC104013F8800043F8420813F811102FFEE00023F82208220823F80208
+3D5A:01102208141411A080604198464410A013182DF6E04027FC224821502FFE0000
+3D5B:011020A017FC104083F8404047FC124811502FFEE00023F82208220823F80208
+3D5C:0010241012FE1210801048FE448214AA119222BAEE9222FE22922292228A0084
+3D5D:008080405FFE0148823046905B08020627FC4524C61445EC452445E444140408
+3D5E:00C84708212A212C0FC881084388555419142122E04020242522250A290800F8
+3D5F:028842A826A82BF0001E822445D45C14141425D4E55425482568255426140422
+3D60:004047FE24022914020887FC440457FC14202524E52425FC24202924292411FC
+3D61:03F8204017FC1444835840404358120013F82408EBC8224823E82212220201FE
+3D62:000047FC20402FFE0842835840405358100027FCE444244427FC2444244407FC
+3D63:00109F1051101F3E91225F4448101F9024905490DAA850A85EA840C445440282
+3D64:000027BC108414A4829444A4404017FC10402248E248255420A0211022080C06
+3D65:0080204017FC1484805045285554199416F02000E3F822A822A822A82FFE0000
+3D66:002021FE144012FC811042FE400016FC128422FCE28422FC2284228C250008FE
+3D67:011027FE111013F8820843F84A080BF8110013FCE4442AA4220423F420140008
+3D68:00407C2045FC44887C5043FE7C20A5FC24203C2001087D90096011202518C206
+3D69:010827FE1108100084884FFE448814F8140027FCE0402FFE215022482C460040
+3D6A:0208211017FC104083F8404047FC10001440227CE08422282C20245024880106
+3D6B:01F8201017FE10A0804047BC408411CE17382108E31827FC240427FC240407FC
+3D6C:00009DF85488149014FC1D549524555416881C0015FC55549554255427FE4C00
+3D6D:0040204413F8105087FE404051FC170411FC2104E1FC20002524249228920000
+3D6E:004027FC10A013188D1643F8411011F0104023F8E24823F8204027FC20400040
+3D6F:40002FF828088BE849084BE80A282BE82A284BE8CA084BFA4A0A53FA55562032
+3D70:0140224C12641244834C42644AA40BAC12A412A4E7FE20002110210822040404
+3D71:00044FE422842FE40ABE8AA44FE4500417D4200CEFEC2104254425242924030C
+3D72:0100420027FC2AA802A88FFE42A852A81FFE2208E3BE24882AA8213E22080C08
+3D73:00404FFE280227BC04A4829444E450A013182C46E090232020C8231020600380
+3D74:000C800A57FE140895E85D48454A05EA3D2A552CD5EC554C654A49EA48161022
+3D75:07E0225C13C4125483C8426847D41064103C27C0E144226820D0214826460040
+3D76:0110411427D221100FFE829044505FF4149427F4E49427E8248A27FA24260042
+3D77:2010110810887CBE020029141108FC3E108810887D1C13081108210821084008
+3D78:004020A01110120885F4480243B812A813B82000E7FC24A427FC24A424A4040C
+3D79:0428842844FE04289500557C5544157C3544557CD510577E5910402840440082
+3D7A:0210221017DE152888C440804BFC0A2413FC1244E3FC2120222027FE20200020
+3D7B:40502E962A928A924AD64E920A922AFE2A104EFCCA444A444A285210522826C6
+3D7C:000027FC140410808338420843B8120813F82200E7FC28042554255428280010
+3D7D:03F82248124813F88248424843F810001FBE2AAAEAAA2FBE2AAA2AAA2FBE08A2
+3D7E:0200823C5FA402248FBC42245FE4003C2FA448A4CFBC48904F9848A848AA09C6
+3D7F:0080210013F8120883F8420843F8120814102FBEE8A228A22FBE28A228A20FBE
+3D80:00004EEE2A222AAA0A668EAA4A104A281A442F92EA202AC82A322AC42A1816E0
+3D81:03909C10411E15108A7E4852425C02703F52424ED2404A5C42544A5444960122
+3D82:0088908849FC008890884BFE482001FC252449FCD92449FC4800488849040202
+3D83:0080908049FE0354915449544BFE015425544954DBFE48004954492A4A2A0000
+3D84:07BC24A417BC14A487BC448444F41514162425B4E51425B4251425F424140408
+3D85:42A0244C24A4860C44A4464C04A42FFE280243F0C020404047FC404041400080
+3D86:04104210227A2F1200148F7E40084F10103C2F64E9A4293C29242F24293C0024
+3D87:42282228227C82284F2842FE0610277C2AD44A7CD254427C4200422842440282
+3D88:0110455425B8291002A884444FFE4842104023F8E248224823F8204427FC0004
+3D89:0308BC1044BE11228432492A5E22042629205F3EC4025F02447A4A02510A2084
+3D8A:00004FBE2A082A100A3E8FA248A248BE18A22FBEEA222A222A3E2A002F940022
+3D8B:050855482DA8253E0FA8824844484ABE13082588E988237E25402920251E0200
+3D8C:00449F444AAA0AEE8E444AAA4AEE0E002A284AAACBAA4EEE5A28422842480288
+3D8D:0200422227922494093E87C84548555E17C82548E57E27C820082AA82AA80008
+3D8E:01FC495425FC240001FE80005CFC448414FC2452E4CC254824642B0030FE0000
+3D8F:001C4EE02A542A280A7C8C104AFE4A001AFC2A04EA7C2C0428FC2814294A0A38
+3D90:0040202017FE14A884FE4550477C1550157C2550E57E254028A42A8A328A0478
+3D91:021082104510089E90526FA2400800083DC85548D5485DD44894489455542222
+3D92:1F3E91225F3E11229F3E500257FA148237F25482D7F2548257FA500A5AAA1014
+3D93:02109FFE4214000A07FE140895E85D4805EA3D2A15EC554CA54A09EA08161022
+3D94:000043F822A822A803F880004FBE4AAA1AAA2FBEE0402FFE20A0211022080C06
+3D95:021043DE2528288407BC84A447BC54A417BC2404E5F4251425F4251425F4040C
+3D96:088089F84A881070138E3400B5FC55AC157415FC142055FC942013FE1154122A
+3D97:20287F78AA147F7C2A543FB206001FF010101FF010101FF001843D480930730E
+3D98:021043DE2528288407FC80A047FC54A417FC2208E3F8220823F820402FFE0040
+3D99:0284AAA456D4029EA7D451245224055E298452C4F4C451BE52A05490528E0100
+3D9A:07FE209017FE149287FE428047DE12921392211EE7D2255227DE21122FD20126
+3D9B:1080888049FE3D0012A0112C9D3455AC1534155415DC5554A7FE24884D048202
+3D9C:0002BEFA628A3EFA208231C6AAAA60823FFE2AAA2AAA7FFEAAAA2AAA32CA4104
+3D9D:004090204BFE02A492BE4BE84ABE02A826BE4AA8DABE4AA04A144B524D4A0A38
+3D9E:03F8220813F8120883F840404FFE14A417BC2110E7FC21102FFE212423180D86
+3D9F:47FC244427FC84444FFE4AAA0FBE2AAA2FBE4220C7C040844FFE404245480884
+3DA0:00009EFE54AA1EAA94FE5E10547C14103FFE4128D57C551055FE511041100610
+3DA1:00003FF8210821082108292829282948310822882248244A242A482A50068002
+3DA2:01001110111022A0044008203018C20602003FE002200420042008223022C01E
+3DA3:00003FF801000100FFFE01000100000001001110111022A0044008203018C006
+3DA4:10801080108010FC550459045284944810281010101028202440448041008600
+3DA5:100011FC1020102054205820502093FE10201020102028202420442040208020
+3DA6:100011F8100810505420581053FE902210241020102028202420442040A08040
+3DA7:10201020102011FE55225922512291221152114A118A290225024502410A8104
+3DA8:00007FFC008001000300056009183104C1020100010000002488224442448004
+3DA9:10201020102011FE55225A24502090201050105010502850249044924112820E
+3DAA:00007FFC01000300056019186104000001001110111022A0044008203018C006
+3DAB:010001007FFC0100210412C80C30F00C01021110111022A0044008203018C006
+3DAC:10201020102015FE58205020502091FC107010A810A829242524422240208020
+3DAD:1010109010901110557E5A52539290921112111212522BD224624422404A8084
+3DAE:00007FFC010001003FF8210822882448200820180100111022A004401830E00E
+3DAF:10001080131E125256525A5252529252125212D2135A2A542490449041108210
+3DB0:10881088108814885BFE508850889088108810F8108828882488448840F88088
+3DB1:102010201020102055FE58205070907010A810A811242AFA2420442040208020
+3DB2:100011FC11241124552459FC51249124112411FC11242924252445244104820C
+3DB3:01003FF00110FFFE01103FF001003FF80100FFFE00000100111022A00C60701C
+3DB4:10201020107C108455485830502090481190103E104229A42418441040608180
+3DB5:0810087813C0304050409FFE10401040104017FC100000002488224442448004
+3DB6:10201020102017FE5A42544450A090A211A4129814902888248444A240C08080
+3DB7:1080108011FC15045A0451E45124912411E41124112429E42504440440288010
+3DB8:1040104011FC14445884508451289210110813DE114A294A254A4252435A84A4
+3DB9:100011FC102014205BFE50005020902213B210B410A829282524422444A28040
+3DBA:100011FC1020102054205BFE50509088110412FA148828882488448840F88088
+3DBB:08001FF0282007C01830E10E1FF001001FF001007FFC01000100488844448444
+3DBC:10201040108815045BFE5082508091FC1220102013FE28202450448841048602
+3DBD:100011FC11041504590451FC5020902013FE122212522A8A270A4202420A8204
+3DBE:00007FFC04403FF8244824483FF800007FFC010011101120228004401830E00E
+3DBF:1020102013FE102054205BFE5202940411F8101010202BFE2420442040A08040
+3DC0:08202AA42CA849201450228841047FF0041004100410FFD00412040A04060402
+3DC1:100011F8100810D0542059FC5124912411FC1124112429FC252445244124810C
+3DC2:00007E7C48047E4442287E1048287EC401001110111022A0044008203018C006
+3DC3:010011081108229004401830EFEE08000FE008000FE00800FFFE111014E0181C
+3DC4:100011FC1124152459FC5124512491FC102013FE107028A82524422240208020
+3DC5:7F00227C3E0422283E1023A8FE44020001001110111022A0044008203018C006
+3DC6:1020104011FC110455FC590051FC910411FC102010202BFE2420442040208020
+3DC7:204020403C4045FEA84010902090C89211523D5446908428282810442084C102
+3DC8:1020102013FE105054885924522291FC112411FC112429FC24224422401E8000
+3DC9:00043F84208420843FBE20042F8420243FD422142A442A845204450488941048
+3DCA:0820082008207EFC08201C301A702A6848A48922082008200000488844448444
+3DCB:102010A210A211245450588853049022102010A410A429282450448841048202
+3DCC:100011FC100414FC580451FC500093FE1222102011FC29242524453441288020
+3DCD:1020102010501488590452FA500091FC1154115411FC2954255445544104810C
+3DCE:100011FC110411FC550459FC508091FE122211221152290225FA440240148008
+3DCF:0640387C08907E1008FE1C102A10481001001110111022A0044008203018C006
+3DD0:1040119C1104110455DC5904510491FC1020102011FC28202420442043FE8000
+3DD1:010011081108229004401830E00E3FF804403FF824483FF801003FF80100FFFE
+3DD2:11FC1124112415FC5924512451FC9020102013FE12222A2A26FA420A42028206
+3DD3:1080108010FC15545AD450B4512C924410941108104028A426AA428A44788000
+3DD4:1008103C13C014445A2451285100927C12441244127C2A4426444244427C8244
+3DD5:221012101410FF92145214547F5855905510632841287F28414841447F844102
+3DD6:00007DFC444444447C44444444947C88110014FC588450849084288444FC8084
+3DD7:00002FBC28A42FA4283C2FA228A24F9E81001110111022A0044008203018C006
+3DD8:10401088110413FE540259FC5104910411FC102013FE287024A8452442228020
+3DD9:11081088109017FE580053C45254925413D4125412542BD426544244425482C8
+3DDA:1040102013FE100055FC590451FC900013FE120211FC28202420442040A08040
+3DDB:08000BF81208320853F8904017FE10E0115012481C4610400000488844448444
+3DDC:2080204027FE2090AA98B494A114A2302440204027FE204050A0491042088C06
+3DDD:1040102013FE12025488590452229028102413FE102028502450448841048202
+3DDE:200023FE220022FCAA84B2FCA284A2FC220022FC2208221053FE4C1044508820
+3DDF:10081210117C15445844507C57409140117E11421142297E25424280447E8000
+3DE0:0110092012E00C187104091012A00C60701C10103EFC4210149008FE3010C010
+3DE1:00007EFE42807EFC42847EFC42807EFE01001110111022A0044008203018C006
+3DE2:082004407FFC01003FF80200FFFE080037F0C0801FFC0100111022A00C60701C
+3DE3:1088105013FE102055FC582053FE900010A010FC1120282027FE442040208020
+3DE4:10001078FE4810487C480086FE0082FC7C44104412285428A810242844448182
+3DE5:100015F854105820902429A844B090A815285924522290A02840440081FC0000
+3DE6:0020FF2024A43CA424A83D20242024502F50F488050406020400488844448444
+3DE7:100011FE11101520597C5144517C9144117C1110111029542552429242508420
+3DE8:1020122213FE148059F852885070938E102011FC102029FC242043FE40208020
+3DE9:000027DC25042784249C2790251247CE0000010011101120228004401830E00E
+3DEA:10A0109011FE132055FC592051FC912011FE110013FC2888249E4502420A8404
+3DEB:08007F7808483E4800863E782A483E30404880840100111022A004401830E00E
+3DEC:1088108813FE1088540059FC510491FC110411FC10202BFE2450448841048202
+3DED:210013F0151000E0775C11F0104013FC284047FE0100111022A004401830E00E
+3DEE:1090109017FE109057FC5A9453FC929413FC100011F8290825F8450841F88108
+3DEF:1020102055FC584090F810402BFE4488912412227CF8102011FC1E20F0204020
+3DF0:1040102013FE140059545124515491FC102013FE12422A9226FA420A42028206
+3DF1:1010101022107F7C01103E1022103EFE22103E2022442AFE2442000024884244
+3DF2:21C8270821082FE8A91EB7CAA54AA7CA254A27CA210A27CA511249D24E2A8444
+3DF3:3FFE224824FE2D9036FC249024FC249024FE248020402248445040A083180C06
+3DF4:3FFE21042E3822102FBC27182AB432522000208024882890214042204C18B006
+3DF5:100011FC112415AC5974512451FC902011FC102013FE280026A4425244528000
+3DF6:111017FC21102FFE6100A3F826482BF8224823F8224822580000488844448444
+3DF7:100013DE125217DE5A10525251CE9000108813FE1088288827FE448841048202
+3DF8:100011FC110415FC590451FC500091FC10A813FE10A829FC242043FE40208020
+3DF9:108813FE10881020543E582051FC910411FC110411FC282027FE442040208020
+3DFA:20203E20443EA84446844228761042287E44010211101120228004401830E00E
+3DFB:1080108011FE13545554595453FE91541154115417FE28002554452A422A8000
+3DFC:0440FFFE0440044017D01012F7DC14503452D7D2100E0100111022A00C60701C
+3DFD:1088105013FE102055FC582053FE912410A813FE100029FC2504450441FC8104
+3DFE:2040207C204023FEAA42B278A3C4A23C220023FE224023A452584DB4445289B0
+3DFF:1020102010501488590452FA5000900011DC1154115429DC2488448841548222
+3E00:102013FE100014F8588850F8500093FE120212FA128A2AFA262641F8402083FE
+3E01:10501252115414505BFE5088505093FE102011FC10202BFE24A8412446228020
+3E02:011027FC1080034870B0136810A4132010402FFE4100111022A004401830E00E
+3E03:00107F1049106B1E5D1049107F7C08447F4408440F7CF0440000488844448444
+3E04:2040202023FE2088A852B7ACA2AAA2A825AC2000210421FC510449FC41048204
+3E05:2210221023DE2528A884B000A7BCA4A427A424A427A4243455284EA044208020
+3E06:112011FC122017FE580051FC510491FC105013DE105029DC245043DE40508050
+3E07:108811DC108813DE54885954522291FC110411FC110429FC250445FC40888104
+3E08:081024483F7E64C8BF7E24483F7E24483F7E20400100111022A004401830E00E
+3E09:210827C8AAAAB12CAFE8210857D44912892200000100111022A004401830E00E
+3E0A:2108210827CE2112A924B7DEA552A55E27D2211E2392255E5940491441128122
+3E0B:203C21E03D2444A8A9FE50A82124420291FC5524552459FC9124292425FC4504
+3E0C:11FC102013FE122255AC582051AC909011FE132015FC292025FC452041FE8100
+3E0D:210821EC210A27E8AD28B5DEA728A4EA240A27EA240C27EC5A2A4BEA515687E2
+3E0E:13FC110811F8150859F8510E57F8900817FE1294139C2A94279C42D647BC8084
+3E0F:00803FFE24103F7C26382D5435322F3C2120273821202F3C248849504630B80E
+3E10:2850FE4828FE399012907CFE54907C9010FE7C901090FEFE2880440024884244
+3E11:2FEC48246BAC48246BAC4AA4FFFE88227EFC2C684AA40100111022A00C60701C
+3E12:00FC7F00020821081110102000F83F0001000100FFFE0100010001003FF80000
+3E13:00FC7F0002082108111010203FF82008200820083FF82008200820083FF82008
+3E14:00F87F00211011101220FFFE040008001FF028104FF088100FF008100FF00810
+3E15:0228077E38482AFE2A482A7E2A482A7E2A40297E2922289C28624830480E8800
+3E16:000028F824884288408884F804884888288810F8188824882488408883FE0000
+3E17:084010202850448803001CE0E01E3FF820082FE8200827C8244827C820282010
+3E18:084010202850448803001CE0E01E1FF012901FF000007FFC0100010005000200
+3E19:084010202850448803001CE0E21E1FD00220FFFE03000FF03810CFF008100FF0
+3E1A:0008848844502820105028884500840800880488445028501020285044888506
+3E1B:040025FC2444244424443C4404940488FD0024FC248424842484448444FC8484
+3E1C:04202410241025FE25023E5404880504FC0024FC242024202420442045FE8400
+3E1D:044024402440247C24443E8820A021203C202450245024482488448445048602
+3E1E:041024902490249024903EFE208020803C8024F8248824882488448844888508
+3E1F:04802484249824E024823E82207E20003CFC2484248424FC2484448444FC8484
+3E20:0890489048904A9249947C98409041987A944C9248904890491249124A128C0E
+3E21:08204920492049FC49207E20402043FE787048A848A8492449244A2248208820
+3E22:0844484449FE484448447DFE404040FE79924AFE489248FE4892489248928886
+3E23:08504A52495448504BFE7C88405043FE782049FC48204BFE48A849244E228820
+3E24:409022882288FABE028053D42208FA3E23882288729C22882288448844888888
+3E25:09F04A104FFC4A044BFC7E2443B8422279FE4A104FFC4A444BFC48D0494A8E3E
+3E26:00003FF800801080108020803FFC0080108008800680018000F0008E02800100
+3E27:00007EFC0484248424FC248444847EFC0C92149214942488448884A414C20880
+3E28:08040804488448847E844884888408840E8CF89448E408840804080408040804
+3E29:080008FC482048207E204820882009FE0E20F820482008200820082008200820
+3E2A:11041124512451247D245124912411241D24F124512411241124122412041404
+3E2B:0804080E48F048807E80488088FE08880E88F888488808880888090809080A08
+3E2C:10201020502053FE7C20502091FC11241D24F124512411341128102010201020
+3E2D:1000100051FC51247D245124912411241DFCF100510011001102110210FE1000
+3E2E:10101090509050887D085104920415FA1C88F088508810881108110812281410
+3E2F:08080888484848487E084888884808480E08F80E49F808080808080808080808
+3E30:10201010501051FE7D025204908010881C90F0A050C0108210821082107E1000
+3E31:1080108050FE51007A205120912C11741BA43124D13411281122110210FE1000
+3E32:084008404840487E7EA048A08920083C0E20F8204820083E0820082008200820
+3E33:10201020505050507C885124921210101DFCF004500810881050102010101010
+3E34:0000FFFE040008001FF02810C8100FF0010011001FF821000100FFFE01000100
+3E35:10201020502053FE7C20502091FC10001C00F1FC510411041104110411FC1104
+3E36:100011FC510451247D24512491FC11241D24F154514C118C1104110411FC1104
+3E37:080008007F7C08243E2408447F540888090011001FF821000100FFFE01000100
+3E38:1008101C51E051007D0051FE910011001D7CF144514411441144127C12441400
+3E39:1004101E51E050227D125094908010081DFEF008508810481048100810281010
+3E3A:1020082040A824A4092A723010C01700010011001FF821000100FFFE01000100
+3E3B:10201040508851047DFE5002908010FC1D20F02053FE10201050108811041202
+3E3C:1040104050FC50887D50502090D813261CF8F02050F8102013FE102010201020
+3E3D:080008FC488448847EFC4884888408FC0E84F88448FC08000848084408820902
+3E3E:100013FC5044514479445284909411081A403020D0A41282128A128A14781000
+3E3F:1020102053FE50207DFC500093FE12021C04F0F050901090109011121112120E
+3E40:1020102053FE5020782053FE9202140419F83010D02013FE1020102010A01040
+3E41:1040102053FE50007C0051FC910411041DFCF020512811241222142210A01040
+3E42:00007EFC48447E4442287E1048287EC6010011001FF821000100FFFE01000100
+3E43:044004407C7C04403C7804407C7C0440054011001FF821000100FFFE01000100
+3E44:100011FC512451FC7D2451FC908811441E42F0F8518812501020105011881606
+3E45:1080108050FC51547AD450B4912C124418943108D04010A412AA128A14781000
+3E46:100013FE522250207DFE502091FC11241DFCF12451FC102013FE102010201020
+3E47:100011FC510451FC7D0451FC908011FE1E22F1225152110211FA100210141008
+3E48:082008207E7E08C4FF281C102A2848C6010011001FF821000100FFFE01000100
+3E49:100011FE511051207D7C5144917C11441D7CF110511011541152129212501420
+3E4A:1040104053FE52A27C9051FE912013201DFCF120512011FC1120112011FE1100
+3E4B:1120113C514452A87A1056A89AC612801A8832B0D28412881232120412181260
+3E4C:1040102053FC50007D08509093FE12201EA0F2FC5320122012FC1420142019FE
+3E4D:1040102053FE50887C5053FE922212FA1E22F2FA528A128A12FA1202120A1204
+3E4E:100011FC512451FC7D2451FC904010881DF0F020504413FE1022112412221060
+3E4F:1088108853FE50887CF8502091FC11241DFCF02053FE102011FC102013FE1000
+3E50:11102110CAA814443240D27C154014FE090011001FF821000100FFFE01000100
+3E51:101417FE501053D0781053D0901013D01A5033D0D25013C8124A13CA11861242
+3E52:10501252515450507BFE5088905013FE182031FCD02013FE1050108811041602
+3E53:1020102051FC50207BFE5108939C11081988363ED00013FE109010901112120E
+3E54:100013FE500051FC7D2451FC912413FE1C00F1FC512411FC112411FC100013FE
+3E55:7DFE002000FCFE8428FC288428FC4A844CFC884811841FF82100FFFE01000100
+3E56:1020112450A851FC784053FE908811041AFA3040D1A4105811B4105213901030
+3E57:102013FE502051FC7C0053FE900211FC1C20F3FE500013FE100413BE12A4138C
+3E58:100011FC502053FE7E2251AC902011AC1C00F3FE502011FC115411541154110C
+3E59:108812AA52DC54887954522293FE12021DFC3104D1FC110411FC110411FC1104
+3E5A:108812AA52DC54887954522293FE120218F83088D0F8100011FC110411FC1104
+3E5B:200027FEA040A2EEFAAAABEAAAAE2AE83BAAECE6228825F42290206021982606
+3E5C:08200A280924092408207EFE0820082008501450125012882088210442048402
+3E5D:0004441E29F0111029104910891009FE1910291049108908090A094A51862102
+3E5E:0008441C29E011002900490089FE0910191029104910891009100A1052102410
+3E5F:00404440284013F828484848884808481FFE284048A088A00910091052082406
+3E60:00204420282013FE2820492489240924192429FC4824882008220822501E2000
+3E61:00404420282013FE28404840888809081BF028204840888809040BFC51042000
+3E62:02008A005200221E57D292521252125232525252925212521452145EA9525080
+3E63:0080888050F82108531094A0104010A033185C0690C0102010101180A0604010
+3E64:00204420282011FC2820482088200BFE182028404840888809040BFE51022000
+3E65:00404420280013FE282048208820082019FC2820482088200820082053FE2000
+3E66:00008BFC508420845084910411141208340051FC9104110411041104A1FC4104
+3E67:00204420282011FC292449248924092419242BFE482088500850088851042202
+3E68:002044202820102029FC492489240924192429FC492489240924092451FC2104
+3E69:000045FC2884108828504820885008881B26282049FC88200820082053FE2000
+3E6A:000097BC54A424A454A494A414A41FFE34A454A494A414A414A415A4A8545088
+3E6B:002044202BFE102029FC482489FC092019FE2822482A88540850088851042202
+3E6C:004088405FFE2040504097FC1444144437FC50409240114010801140A2304C0E
+3E6D:0020442029FC1124292449FC8924092419FC282048248818083208CA53062002
+3E6E:000045FE28201020284049FC89040904190429FC490489040904090451FC2104
+3E6F:009044902890111029FE4B108D10093819382954495489920910091051102110
+3E70:004044442A441148295048408FFE0890189028904890889209120912520E2400
+3E71:000045FC29041104290449FC882008201920293C492089200AA00A60543E2800
+3E72:0020442229FA102428244BFE8810082019FC288849108AFE0C10081050502020
+3E73:000047FE2840104029FC488488840BFE1800280049FC89040904090451FC2104
+3E74:000045FE2820102029FC4924892409FC1924292449FC892008A0084050B0230E
+3E75:000045FE2800109229244A4889240892180029FE482088200820082053FE2000
+3E76:0000880653B8208850889108113E1388308852889288113E11001280A47E4800
+3E77:4210241418122412521010FEFF10201028107E28AA282A282A442E4408840902
+3E78:0020444029FC1104290449FC8904090419FC28504850885008920892510E2200
+3E79:0040882053FE222052FC9224122413FE3224522492FC122012501450A4884906
+3E7A:002044222BB410A828A849248AA2084019FC2904490489FC0904090451FC2104
+3E7B:001C45E0282010202BFE48A889240A4218402BFE4888890808D0083050482184
+3E7C:0080448028FE11022A424A4A895208421BFE284248E289520A4A084250542008
+3E7D:00504448285E13E42828483288CA0F0618502848485E8BE40828083250CA2706
+3E7E:0110891053D8225454529A90111012FE3C00500093F8120812081208A3F84208
+3E7F:00204420283E102029FC490489FC090419FC292448208BFE0820082050202020
+3E80:0080448028FC11542A5448A489240A4418942908484088A40AAA0A8A54782000
+3E81:009245242A4811242892484088800BFE1A022A8A4A528A220A520A8A53FE2202
+3E82:00148812501027FE5410941015D01412341255D49554154815DA142AA8465082
+3E83:008844882BFE1088290049FC89040A0419F42914491489F40914080450282010
+3E84:004044A0291012082DF648008BC40A541A542BD44A548A540BD40A44525422C8
+3E85:0080888051FC220454089BFE1200128032FC5320922013FE14201450A8885306
+3E86:02104510287E1310292849A88944080019FC2904492489240924085050882304
+3E87:001090145FD229126910A97E2B902A906A90AB982928292829242FC4A0444082
+3E88:00204524292411FC28204BFE8800082019FC2924492489FC0820082453FE2102
+3E89:10001078FE4810487C480086FE0082FC7C4400441428FE281010282844448182
+3E8A:01044488280013FE2820482089FC082018202BFE484088240AA20A8A54882078
+3E8B:0120891052082486591093F81008100037BC508494A4129414A41084A2944108
+3E8C:011088A0500027FE50A093F810A817FE30A853F890A011B012A814A6A0A040A0
+3E8D:0040882053FE2202541491E01100110031FC5110911017FE10001090A1084204
+3E8E:002097FE542025FC542497FE142415FC342055FC952415FC152419FCA924512C
+3E8F:002045FC292413FE292449FC882009FC192429FC48408BFE088809D05070238C
+3E90:012446482924100029FC492489FC092419FC28204BFE887008A8092456222020
+3E91:0040448829FC11082A524BFE885009881E2628C04B1088640B88083050C02700
+3E92:000097BC508424A4529494A410501188362650C09310106413881030A0C04700
+3E93:002047FE282011FC28204BFE880009FC190429FC490489FC090409FC50882104
+3E94:000E8BF050442224510893F8120813FC320453FE920212AA12AA1502A4144808
+3E95:007897C05248215057FC91501248140633F85248924813F812481248A3F84208
+3E96:00089788508821106FDEA49424A427946494A794249424C827882C94A0A440C2
+3E97:000047DE2A5212522BDE480089FC092419FC292449FC88200BFE082050202020
+3E98:0090448829FE11102B104DFE8910091019FE2910491089FE09000AA452522452
+3E99:0080884057FE240251F8914817FE122833FC501093F81248124812A8A1104608
+3E9A:00109410527C201050FE9044162812FE3210527C921012FE12101210A5FE4800
+3E9B:03FC8A4053F8224053F8924013FC10043554500891101FFE11101110A2104410
+3E9C:00908BFC529423FC529493FC100013FC320052F8920013FE15201514A5484986
+3E9D:001097D0551027DE545097E8150417C4300053F892A812A812A812A8AFFE4000
+3E9E:01408A4C52642244534C926412A413AC32A452A497FE100011101108A2044404
+3E9F:000097BC508424A4529494A41120121037FC5A2093FC122013FC1220A3FE4200
+3EA0:008090405FFE29126208A5842E0E2A746A54AB542AD42A542A522D54B75C4084
+3EA1:000097FE544425986488A7DE248825DC66AAA48824202520253C2920A92057FE
+3EA2:07FC904057FE24425B5C9040175C112033FC56209BFC122013FC1220A3FE4200
+3EA3:010891EC510A27E86528A5DE272824EA640AA7EA240C27EC2A2A2BEAB15647E2
+3EA4:0148894C52AA200857FE91481368114A336A514C936C1148116A139AA0264042
+3EA5:01F08A1057FC220453FC922413B8122231FE521097FC124413FC10D0A14A463E
+3EA6:00449F445AAA2AEE6E44AAAA2AEE2E006A28AAAA2BAA2EEE3A282228A2484288
+3EA7:07BC94A457BC200057FC908013F8120833F8520893F81110120817BCA4A447BC
+3EA8:00200020FC201020102010407C4010401080108810841D04E3FE410200020000
+3EA9:00040004FE841084108410847C841084108C109410E41E84F004400400040004
+3EAA:00400040FE401040104010507C4810441044104010401E40F040404000400040
+3EAB:00080008FE081088108810887C8810881088108810881E08F008400800280010
+3EAC:000001F0FD101110111011107D9011501150111011101D12E2124212040E0800
+3EAD:000001FCFC041008101010207C2013FE1020102010201C20E020402000A00040
+3EAE:000001FCFC001000100013FE10407C40108010FC100410041C04E00440280010
+3EAF:00007FFC010001003FF801000100FFFE00000100FFFE0280044008203018C006
+3EB0:000003FEFC201020102011FC7D2411241124112411241D34E128402000200020
+3EB1:100017F82110613CA10422042414280820007FFC01003FF801200110FFFE0000
+3EB2:000001F8FC481048104810487C4811F81088108810881C88E088408803FE0000
+3EB3:00200020FE20103E102010207C2011FC1084108810481E50F020405001880606
+3EB4:00200028FE241024102011FE7C2010201020105010501E50F088408801040202
+3EB5:00800080FC8010FC1104110812407C40104010A010A011101D10E20844040802
+3EB6:00080088FE481048100810887C4810481008100E11F81E08F008400800080008
+3EB7:00200028FC24102011FC10207C70107010A810A811241D24E222402000200020
+3EB8:080009F011103190515091521112120E04007FFC01003FF801200110FFFE0000
+3EB9:00200020FC401088110413FE7C021088108813FE10881C88E108410802080408
+3EBA:000001FCFD041104110411FC11047D04110411FC110411041D04E10441FC0104
+3EBB:00200020FC2013FE102010207DFC11241124112411241D34E128402000200020
+3EBC:000003FEFC221024102010207D20113C1120112011201D20E2A04260043E0800
+3EBD:000001FEFC101010102010207C6810A41122122210201C20E020400003FE0000
+3EBE:000003FCFA042204220422F4FA9422942294229422F43A94E204420402140208
+3EBF:000001FEFD1011101110117C11447D4411441144117C11101D10E11041FE0000
+3EC0:00200020FBFE2222222223FE2222FA2223FE2020212038A0E04040A001180606
+3EC1:00000000FDFC1104110411747D5411541154115411741D04E10441FC01040000
+3EC2:01040084FC88100013FE10887C881088108817FE10881C88E108410802080408
+3EC3:044004403FF824483FF824483FF800007FFC010001003FF801200110FFFE0000
+3EC4:0008003CFDC01000100013FE7C2010201120113C11201D20E2A04260043E0800
+3EC5:00200020FC5010881104120210F87C00100013FE102010401C88E10443FE0102
+3EC6:00400080F908220427FE20022000FBFC220423FC220423FC3A04E20402140208
+3EC7:00200020FC501088110412027DFC10201020102011FC1C20E020402003FE0000
+3EC8:0008001CFDE01100110011FE7D001100117C114411441D44E144427C02440400
+3EC9:00200020F920213C2120212027FEF8002020212421243A28E410402000C00700
+3ECA:00800080FCF81108121011FC11247D24112411FC105010501C90E0924112020E
+3ECB:00200020FDFE1020102011FC7D24112411FC102010701CA8E124422200200020
+3ECC:00200020FC501088110412FA7C20102013FE102011281D24E222442200A00040
+3ECD:000001FCFD04110411FC10007C0011FC1020102013FE1C20E050408801040202
+3ECE:010001007FFC0100FD7C111011107D7C11101D10E2FE4280044008203018C006
+3ECF:000001FCFC04100410FC10047C0411FC102010A410A41D28E050408801040202
+3ED0:00400040FC88110413FE100210887D44124210F8118812501C20E05041880606
+3ED1:001C00E0FC2011FE107010A87D24122210F8101010201DFEE020402000A00040
+3ED2:000003FEFA02221A22E222222222FBFE2222227222AA3B26E222422203FE0202
+3ED3:000007E0FA5E2252225223D22252FA5423D4225422483AE8E754405400620040
+3ED4:0008003CFDE0102013FE10A810A87CA813FE10A810A813FE1C20E02041FC0000
+3ED5:000003FEFA02220223FE22102292FA92229222FE22103A92E292449204FE0802
+3ED6:00400040FBF82048204827FE2048F84823F8244422E83950E248444601400080
+3ED7:044004407C7C04403C7804407C7C044004407FFC01003FF801200110FFFE0000
+3ED8:00400020FBFE2222202021FC2124F92421FC2124212439FCE124402000200020
+3ED9:00400020FBFE2080210423FEF80221FC210421FC210439FCE104410401140108
+3EDA:000003DEFA522252225223DE2252FA52225223DE22523A52E2524252055208A6
+3EDB:000001F8FD08110811F811087D0811F8108011FC12541C94E124424400940108
+3EDC:00880088F8882088215422222442F82020202120213C3920E2A04260043E0800
+3EDD:00820082FBE22082208A23EA22AAFAAA23EA208A21CA3AAAE4A24082008A0084
+3EDE:00400020FBFE2202220223FE2200FA0023FE235225523DFEE552455209520106
+3EDF:00400040FBFE208021FC222025FEF80021FC210421FC210439FCE10401140108
+3EE0:00400020FBFE220220882104FA222028202423FE20203850E050408801040202
+3EE1:00480148FD4813FE114811487D78110011FE102013FE1C70E0A8412406220020
+3EE2:02100110F91027BE2228224823AAFAAE22BA22EA22AE3AA8E4AA44A209A2101E
+3EE3:00880088FBFE208820F8208820F8F888208823FE21003948E184410001FE0000
+3EE4:00880088FBFE2088210021FC2104FA0421F42114211439F4E114400400280010
+3EE5:00880048FC5013FE105010507DFC11541154118C11041DFCE104410401FC0104
+3EE6:01FC0124FD2411FC112411247DFC1020102013FE12221E2AE2FA420A02020206
+3EE7:01040104F9DE22442554209E2104FA24242423FE207038A8E124462200200020
+3EE8:00007EFC48447E5443287E9048287EC600007FFC01003FF801200110FFFE0000
+3EE9:011000A0F80027FE20A023F8F8A827FE20A823F820A039B0E2A84CA600A000A0
+3EEA:00A00090FDFE132015FC11207DFC112011FE110013FC1C88E09E4102020A0404
+3EEB:000001FCFD2411FC112411FC7CA810A813FE10A810A81DFCE02043FE00200020
+3EEC:01FC0020FBFE222221AC2020F9AC200021FC200023FE3880E0FC400400280010
+3EED:00400020FBFE2020204822F2F924225220F8200820203BFEE020402000200020
+3EEE:01000110FBDC225425542288F90822F42402200023FC3840E150424805440080
+3EEF:0040007CF84023FE22422278FBC4223C220822F023243AA8E5FE442008A00040
+3EF0:008803DEFC8811DC108813DE7C88100013FC100410041DFCE004400403FC0004
+3EF1:0020047CFA842148203020CE2610FA7C2210227C22103AFEE210421005FE0800
+3EF2:002001FCFD2413FE112411FC7C2011FC112411FC10401DFEE08841D00070038C
+3EF3:00880088FBFE2088204220E2FB82208A208A27EA218A39CAE2AA4482008A0084
+3EF4:000001F8FD0811F8110811F87C0013FC129413FC10001DF8E090406001980606
+3EF5:03FE0202FBFE220022FC220823FEFA10223023CE22423A84E4EE47840884018C
+3EF6:010801EEFA942042202021FC2024FBFE202421FC202039FEE02043FE00200020
+3EF7:02080208EFBE420842084FBE4AAAEAAA4AAA4BAE4208671CCAAA124802080208
+3EF8:000007BCF908252827BC231825AAF946200023F822083A08E3F84208020803F8
+3EF9:FDFC104021A27C54A5B824543D92246000007FFC01003FF801200110FFFE0000
+3EFA:3FFE21042E3822102FBC27182AB4325220002FFC208027F820A040905FFE8000
+3EFB:01080088FBC8201023DE226423D4F81423D42054209438E8E388409402940122
+3EFC:000003FEFC5013FE125213FE7C0011FC110411FC11041DFCE02043FE00200020
+3EFD:00A00090FDFE132011FC11207DFC112011FE110013DE1E52E252427202020206
+3EFE:0100FFFE104824FE799010FC22907CFC089030FEC0807FFC01003FF80120FFFE
+3EFF:000003F8FAA822A823F82100FBFC248423E422A422A43BE4E09447F400140008
+3F00:00100410FA7C201020FE20442628FAFE2210227C22103AFEE210421005FE0800
+3F01:01040088FBFE202021FC2020FBFE20542192209023FE3890E0D4438A009601A2
+3F02:0A0033B822083BB820883AB82288FFFE80027FFC01003FF801200110FFFE0000
+3F03:01240248F924200023FC22942264FA9423FC224823683A48E36A424A02460362
+3F04:01240124FAAA23AE212422AAFBAE202427FE201027D43D54E7CA454A07D60022
+3F05:00200010FBFE224422FE224423FEFA1022FE229222FE3A92E2FE420002440482
+3F06:008802AAFADC24882154222227FEFC0221F82040204039F8E050404803FE0000
+3F07:00200222FBFE209021FE231025FEF91021FE211021FE21003BDEE25202720206
+3F08:000007FCF4A424A427FC221022A8F4BE2F68223C24A82FBC3028CAA80ABE0020
+3F09:0210071038102A7C2A542A542A102A282A282948294A288628404A304D0E8900
+3F0A:1008101C10E8FEA810A854A854A854A854A87CA410A410A414A2192811340224
+3F0B:1008101C10E810A8FEA810A810A810A87CA844A444A444A444A27D2845340224
+3F0C:08081C1C70E850A850A850A858A854A854A854A450A450A458A255289D340624
+3F0D:1008101C10E8FEA810A87CA810A8FEA830A838A454A454A490A2112811341224
+3F0E:0220071038102AFE2A002A442A822A282A1029282944288428404A304D0E8900
+3F0F:04081E1CE0E822A892A854A848A810A8FCA824A444A428A410A2292845348224
+3F10:0804040E7F74415441547F5440547F54555455527F52555255505594819A0312
+3F11:1008101CFEE810A8FEA892A8D6A8BAA892A8FEA410A438A454A2932811341224
+3F12:027C0744387C2A442A7C2A002AFE2A402A7E29AA295228AA28444A304D0E8900
+3F13:08881C50700053FE505051FC585457FE545455FC505050D8595456529C500450
+3F14:0008001C7CE844A87CA844A87CA800A87CA854A454A454A456A2F92801340224
+3F15:1008921C54E8FEA882A87CA844A87CA800A87CA454A47CA454A255287D344624
+3F16:11F03A10E3E0A020A7FCA188B650A9A8AE64A9A0A248AFBEBAAAAFBE3A8A0FBE
+3F17:000001FCFE801080108010F81088108811481128112811081108114A518A2106
+3F18:100011FC10801080548054F8548854885548552855285D086508014A018A0106
+3F19:100010FC1040FE40924092789248924892A892989A88948810AA10CA108A1006
+3F1A:100008FC0840FF40004000783C48244824A824982488258846AA44CA808A0006
+3F1B:00007EFC24402440244024782448FF4824A824982488248824AA24CA448A8406
+3F1C:01001FF011101110FFFE02801C70E00E00007FFC08000FE0092010A41624181C
+3F1D:10001EF8228862A894920882307EC00000007FFC08000FE0092010A41624181C
+3F1E:00007EFC084008404A402A782C480848FFA808980888088808AA08CA088A0806
+3F1F:100010FC20407E4042404278424842487EA842984288428842AA7ECA428A0006
+3F20:100008FC08407F4041408278204820483EA820982088208826AA38CA208A0006
+3F21:080028FC28403E404840887808487F4818A81C982A882A8848AA88CA088A0806
+3F22:0000FEFC904090409040BC78A448A448A4A8A498BC88908890AA90CAFE8A0006
+3F23:0000FEFC1040104020407C784448444844A87C984488448844AA7CCA448A0006
+3F24:080008007F7C08243E2408447F54088800007FFC08000FE0092010A41624181C
+3F25:100012FC7A4014401440FF78104820487EA8909820883C8804AA04CA148A0806
+3F26:00007DF01110119011521D12E20E440000007FFC08000FE0092010A41624181C
+3F27:0000FCFC044068401040FE7892489248FEA892989288FE8892AA92CA928A8606
+3F28:080008FC14402240514088787E48024804A808987E88428842AA7ECA428A0006
+3F29:0400057C04A07F2044204438742855285558564856485448655A4D6A934A0106
+3F2A:080008FC7F40084008402A782A482A485DA888980888148814AA22CA428A8006
+3F2B:00007EFC4A404A407E404A784A487E4808A8FF9818882C882AAA4ACA888A0806
+3F2C:100010FC7C4010401040FE78444828487CA810981088FE8810AA10CA108A1006
+3F2D:1020103E7C2011FC11041D04E1FC010400007FFC08000FE0092010A41624181C
+3F2E:100010FCFE4010407C401478FE4814487CA81098FC88248844AA28CA308AC806
+3F2F:0800087CFFA0082008207F3849287F2849587F4808481C482A5A496A884A0806
+3F30:0800107C7F20492049207F38492849287F5814482448FF48045A046A044A0406
+3F31:04447C5804621C42E43E00007FFC482410107FFC08000FE0092010A41624181C
+3F32:0000FEFC10402040FE40AA78AA48AA48A2A896981088FE8810AA28CA448A8206
+3F33:100010FC52405140954008783048C0487EA842987E8842887EAA42CA7E8A4206
+3F34:00007CFC544054407C40547854487C4810A8FE9892889688BEAA82CA8A8A8406
+3F35:00003EFC22203E2022383E280048FF680858084A2F4A286A284658004FFE8000
+3F36:100010FC2840444082407C780048E248AAA8AA98EA88AA88AAAAE2CAAA8AA406
+3F37:100092FC92409240FE400078FE48104820A8FE98AA88AA88AAAAAACAAA8A8606
+3F38:1000087CFFA080A0142022384928142822584148BEC82248225A226A3E4A2206
+3F39:440044FCFF4054400840FF78404840487EA800985488548855AA56CA948A0006
+3F3A:100008FC7F4048405E404A787F484A485EA848985E88528852AA52CA5E8A9206
+3F3B:11102110CAA814443240D27C154014FE08007FFC08000FE0092010A41624181C
+3F3C:0000FEFC2840FE40AA40AA78FE4800487CA80098FE88108854AA92CA508A2006
+3F3D:100010FCFE401040BA405478BA481048BAA85498BA88108828AA24CA428A8006
+3F3E:0800047C7FA0522052207FB852A852A87FD8524852485BC8525A52EA9B4A1206
+3F3F:1000087C7F202220FF2000387F2849287F5849487F4808487F5A086A0F4AF006
+3F40:2200147CFF2014207F20553863285D2841587F480848FF48145A226A414A8006
+3F41:3FFE21042E3822102FBC27182AB4325220003FFE240027F0249048524B128C0E
+3F42:0800147C22205D2080A03E3822283E280058774811485548335A556A114A3306
+3F43:0E00F0FC92405440FE403878544882487CA8549854887C8854AA54CA7C8A4406
+3F44:240CFF7024403C40247E3C482448FF482448428800007FFC08000FE011241C9C
+3F45:0A0074FC15405240224021785D4880487EA8429842887E8842AA24CA0F8AF006
+3F46:100092FC5440FE4082407C7844487C4800A87C9854887C8854AA54CA7C8A4406
+3F47:0A803138228838382288393822887FFE4002BFF408000FE0092010A41624181C
+3F48:48F8705044203DFC20247CB890A07D7E2A007FFC08000FE0092010A41624181C
+3F49:00007E40487E7E9043087EFE48AA7EFE00007FFC08000FE0092010A41624181C
+3F4A:49005D7C6120DDA043205D3841285D28B6D89C4800487F48025A346A1C4A6306
+3F4B:210447C88812F3BC20084B92F83E0380AAAAABAA00007FFC08000FE011241C9C
+3F4C:7F00087CFFA088A06B2010386F28452855586B4810487F48495A7F6A494A7F06
+3F4D:220022FC22402240FF402278224822483EA822982288228822AA3ECA228A0006
+3F4E:22102210FF1022103EFE22923E9222102228FF28402854286248404A7E8A0106
+3F4F:204010A083184DF61000E3F8220823F800001010FFFE10101FF010101FF01010
+3F50:48884850480049FEFC5049FC48544BFE485479FC485048D849547A5248500050
+3F51:4BFE48504BFE4A52FE524BFE480049FC790449FC490449FC48207BFE48200020
+3F52:00107C10549054907CFC549055107C101010FEFC12101210221022104AFE8400
+3F53:010011001FF821005FF00100FFFE081048507E7C489088107E7C08100F10F0FE
+3F54:28102810AA506C7C2850FE901010307C4A109C102C10DAFE2900C8C0283E1000
+3F55:010001003FF821083FF821083FF800007FF8000810081FFE0002000200140008
+3F56:004000407C40544055FC544454447C4454445484548454847D04450402280410
+3F57:002000207C2054205420542054207C2054505450545054887C88450402040402
+3F58:004000207C0055FC5400540054F07C9054905490549054927C924512010E0200
+3F59:004000407C805488550457FE54027C9054905490549054907D124512020E0400
+3F5A:00003FF8210821083FF8210821083FF8000011003FF841000100FFFE01000100
+3F5B:008000807D0055FC5604540455E47D245524552455E455247C04440400280010
+3F5C:10001EF8228862A894920882307EC0003FF8210821083FF8210821083FF82008
+3F5D:7F0408441E44224454440844300CC0001FF0111011101FF0111011101FF01010
+3F5E:00003EF82288228822883EF8000000003FF8210821083FF8210821083FF82008
+3F5F:0004001E7DE054225512549454807C0855FE5408548854487C48440800280010
+3F60:002000207C2057FE5420542055247D24552456AA542054507C50448801040202
+3F61:00400080F9FCA924A924A9FCF924A944A9FCA890A910FBFE8810001000100010
+3F62:00400080FBFCA910AA48AC46FBF8AA48AA48ABF8AA48FA488BF800420042003E
+3F63:00140012F810AFFEA810A810FBD2AA52AA52AA54ABD4F80888EA071A02260042
+3F64:008000807CFE5502562254AA54727C2255FE5422547254AA7D224422000A0004
+3F65:000000FC7C48543055FE545254947D105630542055FE54707CA8452402220020
+3F66:08202AA44D28145022887FFE400280043FF8210821083FF8210821083FF82008
+3F67:00840044F848ABFEA884A884F908A94AAA52AB9CA884F9088908025203DE0042
+3F68:01080088F890ABFCA840A9F8F840ABFEA880A900A9FCFA208C20082003FE0000
+3F69:00400088F9FCA908AA52ABFEF850A988AE26A8C0AB10F8648B88003000C00700
+3F6A:01040088F800ABFEAA22AAAAFA72AA22ABFEA800A9FCF90489FC010401FC0104
+3F6B:0100FFFE104824FE799010FC22907CFC089030FEC0803FF821083FF821083FF8
+3F6C:0000FEFE00007C7C444444447C7C0000FEFE92929292FEFE92929292FEFE8282
+3F6D:000001FCF820ABFEAA22A9ACF820A9ACA800ABFEA820F9FC895401540154010C
+3F6E:0FE009200FE009200FE07C7C54547C7C54547D7C11001FF821005FF00100FFFE
+3F6F:022203FEF890A9FEAB10ADFEF910A9FEA910A9FEA900FBFE8A8A037602520276
+3F70:0000777C55145514551077105550555C55507750555055505550B55089BE1300
+3F71:008000401FFE1000900852085208120832085208923813C82208200840088008
+3F72:008000401FFE1000900057FE50801100320053F8900810082008200840508020
+3F73:008000401FFE1000900057FC5040104030405FFE904010402040204041408080
+3F74:008000401FFE10009010501057FE101030105210912010A0204020A043188C06
+3F75:008000401FFE1000904050405040104037FC504090401040204020404FFE8000
+3F76:008000401FFE1000900053F850081008300853F8920012022202220241FE8000
+3F77:008000401FFE1040904050445768117031605150925012482444284241408080
+3F78:008000401FFE10009040504053FC1244344850A090A01120212022224422881E
+3F79:008000401FFE1000901C53E05200120033F85288928812502420245048889306
+3F7A:008000401FFE100097F8510851101120313C5204928812502420245048889306
+3F7B:008000401FFE1040904057FC5040104037F85208911010A0204020A043188C06
+3F7C:008000401FFE1000900457E45024102433E45204940417E42024202441448084
+3F7D:008000401FFE10409040504057FE1040304053F8920812082208220843F88208
+3F7E:008000401FFE1000904052485248124833F85048904014442444244447FC8004
+3F7F:008000401FFE1000901C53E052901290329052909290128824C824A448D49092
+3F80:010000803FFE20002080A0806FFC208020806080BFFE2100221044084FFC8404
+3F81:008000401FFE104090505048504017FC30E05160915012482444284240408040
+3F82:008000401FFE108090805110520817FC3204500093F812082208220843F88208
+3F83:008000401FFE1080904057FC54041808320052109260138022002204420481FC
+3F84:008000401FFE10009040504057FC14443444544497FC14442444244447FC8404
+3F85:008000401FFE1040905C53E05240124033FC504490C4115422482C4040408040
+3F86:008000401FFE1040904053F85248124833F8524892481FFE2208220842288210
+3F87:010000803FFE20002000A7F86408240827F86408A40827F82408440847F88408
+3F88:008000401FFE100091085108510812FE320856489A2812282208220842288210
+3F89:008000401FFE1040904050A0511012483426502093F81008211020A040408020
+3F8A:010000803FFE20402040AFFE604027FC24446454A4E8215022484C4640408040
+3F8B:008000401FFE11109110521052FE16103A385238925412542292221042108210
+3F8C:008000401FFE10009040524053FC144030405FFE91201120212022224422981E
+3F8D:008000401FFE100090005FFE5040108037FC54A494A414A424A424A444948408
+3F8E:008000401FFE1000900057BC54A414A434A454A494E414042404240447FC8404
+3F8F:008000401FFE1000904057FC504010403FFE5000904017FC204020405FFE8000
+3F90:008000401FFE100090045FC45214121437D454549A5411942084210442148C08
+3F91:008000401FFE104090A0511052081DF63000500093F812082208220843F88208
+3F92:008000401FFE11009100511E5FD2125232525452949212922112229E44528840
+3F93:008000401FFE100093F0521053F0100037F8540897F8140827F8240844288410
+3F94:008000401FFE1000900053F85208120833F8500097FC14042404240447FC8404
+3F95:008000401FFE1080904057FC520811103FFE5040904017FC2040204040408040
+3F96:008000401FFE1000900057FC544417FC344457FC904017FC204020404FFE8000
+3F97:008000401FFE1100908057F8540817F8340857F8948214442428251046088406
+3F98:008000401FFE100097FC504053F8124833F8524893F812402140208043608C1E
+3F99:008000401FFE1010972050C0513016883FFE5100924017F82A48226842508040
+3F9A:008000401FFE1120912455E85530152235A25E1E900013F8200020004FFE8000
+3F9B:008000401FFE100093F8500851F8100833F8500097FC140423F8211040E0871C
+3F9C:008000401FFE10009040504057FC1040324852489554184220A0211046089806
+3F9D:010000803FFE20803FFCA0806FF828882FF86888AFF820803FFE408040808080
+3F9E:010000803FFE20002FFCA1206FFC292429246A1CAC042FFC280448044FFC8804
+3F9F:008000401FFE10009040527C524012403FFE5040914412482410206043809C00
+3FA0:008000401FFE10009880557C52101D103110517C93101D10211021104A7E8400
+3FA1:008000401FFE1100911E57D2511211123FF251129292145A2FD4245040108010
+3FA2:008000401FFE104090405FFE504012483248555498E2115022482C4640408040
+3FA3:00803FFE20802140A2206410280837F66080A0802FF82080249042A05FFE8000
+3FA4:008000401FFE1080904057FC540411103208540493F810402040204047FC8000
+3FA5:008000401FFE1000920053BC521412143FD45014920816882A4822144A148422
+3FA6:008000401FFE1080904057FC520811103FFE500093F812082208220843F88208
+3FA7:008000401FFE100093F8524853F8124833F8504097FC10E0215022484C468040
+3FA8:010000803FFE20802FF8A140622024103FFE6010A7D0245027D0401040508020
+3FA9:008000401FFE1000903853C050401FFE31505154975811542354254C40408040
+3FAA:008000401FFE104092485454586213803FF8520893F8120823F8220843F88208
+3FAB:008000401FFE104093FC5204520413FC320053FC9354155425FC29544144810C
+3FAC:008000401FFE1000942457A854321522361E510093FC120423FC220443FC8204
+3FAD:010000803FFE20002310AE10625422543F586690A6102B282A28524442448282
+3FAE:008000401FFE1040908053F8520813F8320853F8900017FC204023FC40408FFE
+3FAF:008000401FFE100093F8524853F8124833F8500097FE12442228229043088206
+3FB0:010000803FFE2200223CA2246FA4223C22246FA4A8BC28A42FA448C440548088
+3FB1:010000803FFE20402F50A1246A1824083BF66120A1202FFC212042244424881C
+3FB2:010000803FFE22102F90A21E6FA422243FD46414A7942488248848944AA49142
+3FB3:010000803FFE288024FCA12464203850298C6100BFFE2210272040C043308C08
+3FB4:008000401FFE1040904057FC51501248344653F8920813F8220823F842088FFE
+3FB5:008000401FFE120091085FC850081788303E5788900817882488248847888488
+3FB6:00803FFE200023F8A20863C822482FFE6802B3FC220823F8220843F842088218
+3FB7:00803FFE2000203EAFC0687C28402BFE6A42AA782AC42A3C320054F06494890C
+3FB8:008000401FFE102097FE500051F8110831F8500097FE140225FA250A45FA8406
+3FB9:010000803FFE21202128A5B065242524259C6E40A04027FC20E0415042488C46
+3FBA:010000803FFE200027FCA44067F8244027F86440A7FC20042AA44AA450148008
+3FBB:008000401FFE1010972855445582167C3510551095FE15102754249245528420
+3FBC:010000803FFE200029F8A50865F821083DF86524A5182548258445044A0091FE
+3FBD:010000803FFE20402880A5F8610821082DF86500A5FC2504250445FC4A0091FE
+3FBE:008000401FFE120891105FFE512017FC31245FFE912417FC2330252859268120
+3FBF:010000803FFE22002100AFBE68A22FA428A86FA4AA2229222AAA4CA448208020
+3FC0:010000803FFE20202E2EA42464A424A424A46EAEA424242424444644588E8100
+3FC1:008000401FFE108093F8520853F8120833F8508097FC1210244829F640408040
+3FC2:008000401FFE11109550555057DE102437D45114911417D4210821084FD48022
+3FC3:008000401FFE12A892A857FC52AA14E6380057FC944413F82248224842588040
+3FC4:010000803FFE20002FDCAA146BD42D1629206FDCA9142A942C5448084FD48022
+3FC5:010000803FFE22102410A89C7090229025FE6C10B490249C24904550463E8400
+3FC6:00801FFE1000103893C0504017FC315052489486104017FC20A223144D488186
+3FC7:008000401FFE100097BC508454A4129434A4510093FC120423FC220443FC8204
+3FC8:010000803FFE22282224A57E69482E4822FE6548A9482F7E22484448487E9040
+3FC9:00803FFE204027FCA44467FC20403FFE6404A7FC240427FC240447FC42088404
+3FCA:00803FFE20002F78A2106A502F7C26306B54B28C27F8240827F8440847F88408
+3FCB:00801FFE100013F8920853F8100037BC54A497BC10401FFE215022484C468040
+3FCC:00803FFE20802140A22064103BEC20006F78A94829482F782220455048889104
+3FCD:010000803FFE2000287CAF1471242FCC2AA86FBEAAC82F882AFE4A885088A188
+3FCE:00801FFE104017FC91505FFE111037FC540497FC140417FC240427FC41108208
+3FCF:00803FFE200027F8A0886FFE210827F86310A4A02FFC304023F840404FFE8040
+3FD0:00803FFE2210223EAF4462A822103FA8625EA2222A542B082A104A605600A3FE
+3FD1:00803FFE20002FBEA492628A2492222067FEAC2037FE242027FE442047FE8400
+3FD2:00803FFE20402FFCA04067FC20003FFE6002A7F820403FFE20084F7E49488F18
+3FD3:00803FFE204027FCA2486248255428A26318ADF6211021F02240427C454088FE
+3FD4:010000803FFE200027FCA44467FC244427FC6000AFBE2AAA2FBE4AAA4FBE88A2
+3FD5:00803FFE20002F3CA9246F3C29242F3C69E4AA242C442B642A244B644A248BEC
+3FD6:00803FFE2040207CA04067FE244225F86444A4FC24A824F824A849FC495493FE
+3FD7:00803FFE20002300BCFE64103F7C2E44757CA4442E7C2A442A7C53285244A082
+3FD8:00803FFE22082AAAA248651428A22FFE6802A3F8220823F8200047FC440487FC
+3FD9:010000803FFE200023F8A2A863F820002FBE6AAAAFBE20402FFE40A043188C06
+3FDA:00803FFE20002FFEA9126FFE2228244469FEAF48227E25482F7E4048557E9540
+3FDB:00803FFE20002FBEA514671C25542FFE6920AFFC29242FFC2A244BB85222A39E
+3FDC:00803FFE210027F8A54864A827F8221067F8BD2E27F820002FFC49244FFC8924
+3FDD:040008003FF8200820083FF8200820083FF8020004000820101020087FFC2004
+3FDE:1008103C21E07C204420443C45E044207C20443E47E0442044227C224422001E
+3FDF:1020102020407CFC44844484448444847CFC44844484448444847C8444FC0084
+3FE0:1040104422447948495048404FFE48907890489048904892491279124A0E0400
+3FE1:020004001FF010101FF010101FF00000244814500C601450644808421042603E
+3FE2:00007CFC448444FC7C8444FC44847D14020808003FF820083FF820083FF82008
+3FE3:100013F822087BF84A084BF849004BFC7C444A444AA44A044BF4780448280010
+3FE4:1040104023FC784049F848804BFC49107A084DF64910491049F07910491001F0
+3FE5:1040104023FE7AA2489049FE49104B107DFE4910491049FE4910791049FE0100
+3FE6:08007F7808483E4800863E782A483E30404884861FF010101FF010101FF01010
+3FE7:102013FE202079FC48004BFE480249FC78204BFE48004BFE48047BBE4AA4038C
+3FE8:100013FE22227ACC4A444BEE4A444AEE7B544A444A104A104A5E7A504A5005FE
+3FE9:112410A823FE7A0248F848884BFE4AAA7A724BFE48204BFE48207FFE4AA40452
+3FEA:0820082008207F7849284A2848287EA84268422852584C48444A4A8A92862102
+3FEB:208020843E9820E42684387C00801FFC1084108817F01210212020C043301C0E
+3FEC:08000800087C7F5449544A5448547E54427C424052404C4044424A42923E2000
+3FED:0C107010401040FE40927E94489048FC58A448A44CA84AA84890492889440282
+3FEE:1010101010107CFE54925494549054FC54A4FEA410A810A82890252845448282
+3FEF:010006C01830EFEE00001FF010101FF001003FFC21042FE82420424041809E7C
+3FF0:201010100010FEFE00922894449082FC04A444A428A810A82890452885440282
+3FF1:100C11F0FD0011FE1D10F2101210341001003FFC21042FE82420424041809E7C
+3FF2:10101010FE1010FE28924494FE9004FC74A454A454A874A85490052815440A82
+3FF3:082A082A08547F54492A4A2A482A7E0042FE429252924CFE44924A9292FE2082
+3FF4:10101010FF1024FE429281947E9024FC3CA424A43CA824A82E90F52805440682
+3FF5:080008FE08107F2049FE4AAA48AA7EAA42A2429652104CFE44104A2892442082
+3FF6:20101010FE1000FE44922894FE90A2FC10A4FEA420A83CA82490452855448A82
+3FF7:441024102810FEFE10927C941090FEFC20A43EA448A848A88E90792821440282
+3FF8:087C0844087C7F44497C4A0048FE7EAA42FE420052FC4C4444284A1092682186
+3FF9:10101210117C7C1054FE504453287DFE4510657C591049FE5510951022FE0400
+3FFA:7F0841087F08417E7F4A224A7F48227CFFD422544954AAD41C482A8849141822
+3FFB:00001FF0010001000100FFFE0100010001003FF82448244824482448FFFE0000
+3FFC:00003FF808200820FFFE082010202020402000003FF8244824482448FFFE0000
+3FFD:0440082010102FE8C40608000FE00020014000803FF8244824482448FFFE0000
+3FFE:020001007FFE400280043FF001000100050002003FF8244824482448FFFE0000
+3FFF:00007FFC0104110011F81100290047FE80003FF82448244824482448FFFE0000
+4000:100009F841082508092811107102110210FE00003FF8244824482448FFFE0000
+4001:0200FFFE04000FF018102FF0C8100FF00810083000003FF824482448FFFE0000
+4002:01007FFC40040400FFFE08201E4003C03C3800003FF8244824482448FFFE0000
+4003:00007FFC02000D08719002A00CC071A006981A86E1003FF824482448FFFE0000
+4004:020001007FFE42028924284849940E1077F000003FF8244824482448FFFE0000
+4005:20201020FC2009FC102038205420902013FE100000003FF824482448FFFE0000
+4006:01003FF80108FFFE01083FF801007FFC0000110826D01830E00E3FF82448FFFE
+4007:1080108011FCFE20102011FC7C20452445247DFC00003FF824482448FFFE0000
+4008:7DFC44207D2045207DFE505048905512620E00003FF8244824482448FFFE0000
+4009:00701F800200FFFE082037D8C4463FF8200827C8244827D800003FF82448FFFE
+400A:27BC14A4929444A4404011B02E4EE390206023882070038000003FF82448FFFE
+400B:210021FE2220243EF82023FE22AA225223263A52E2AA43FE00003FF82448FFFE
+400C:01003FF80108FFFE01083FF801007D7C11107D7C44447C7C44447FFC2448FFFE
+400D:1040FEF82948FE3001CE7CF844207DFC44887CF81088FEF810503FF82448FFFE
+400E:000003FE7C40444044807C80450045FC7C044404440444047C04440400280010
+400F:100010001FFC200420045FE490241FE410241FE410241FE41024000400280010
+4010:00087E084210422042447E044208421042227E424204420442087E10422000C0
+4011:000001F87C8844C844A87CA8448844507C504450442044207C50448801040202
+4012:0008003C7DE0442044207C20442047FE7C204420442044207C20442000200020
+4013:004000407C40444045F87C48444844487D4844C8444844A87CAA450A02060402
+4014:000000007DFC444444447D44454445447D444644444444847C84450402280410
+4015:000403E478244824482479E4490449047A044BE4482448247824482401440084
+4016:000000007DFC442044207C20442047FE7C204420445044507C88448801040202
+4017:0040004078404BF848487848484848487BFE484048A048A07910491002080406
+4018:000003FC789048904890789048904FFE78904890489048907910491002100410
+4019:00000100797E49124912791249D24F12791249124952499279224822004A0084
+401A:1FF010101FF010101FF010101FF000000C0070FC408440844C84709440880080
+401B:01000100790049FC4AA47CA448A4492479244A444C44488479044A0404280010
+401C:080008001FF82248444808881128221004001FF010101FF010101FF010101FF0
+401D:00100110791049124912791449D84910791049104910491279524992010E0000
+401E:001001107C90449044107D10449044907C10441E47F044107C10441000100010
+401F:0090009078904BFC489478944BFC4A907A904BFE48924892791A491402100410
+4020:00007CFC4484448444847CFC4484448444847CFC4484448444847CFC44840000
+4021:002000207C204420443E7C20442044207DFC4504450445047D04450401FC0104
+4022:00400040788048FC49207A20482048207BFE4820485048507888488801040202
+4023:00000040782048284808788848904A947AA24AA24CC2488879884A8804780000
+4024:102010203F304128A224142208203020DFF010101FF010101FF010101FF01010
+4025:0008001C7DE0450045207D20452045FE7C20442044A844A47D22462200A00040
+4026:00200020782048204BFE78204820482079FC4904490449047904490401FC0104
+4027:01100110791049104BFC79104910491079104FFE4800491079084A0804040804
+4028:0008003C79E0482048207BFE48204820782049FC490449047904490401FC0104
+4029:0080008078F849084B107CA0484048A079184A064DF849087908490801F80108
+402A:00800080793C4A004C807880497E4B087D084908490849087908490801280110
+402B:0040004078A049104A087C064BF8480078004BF84A084A087A084A0803F80208
+402C:0040004078A049104A087C064BF84840784048404BF848407840484007FE0000
+402D:002000107C1045FE44207C24444444F87C124422444445887C10442800440182
+402E:008000407BFC49004900790049F8480079504950495049507A504A520452080E
+402F:004800447BFE484048407BFC4A444A447BFC4A444A444BFC7A444A4402540208
+4030:0088788449024A2248207850488849047A0249FC490449047904490401FC0104
+4031:0080008079F849104AA0784049B04E4E79F0484049F048407FFC484000400040
+4032:0100010079FC4A004DF87908494849287BFE49084A484A287BFC480800500020
+4033:002000207BFE4820482079FC4924492479FC4820487048A879244A2200200020
+4034:000003FC780049244A487C904A48492478004BFC484048407840484007FE0000
+4035:00200040788849044BFE7882488049FC7A2048204BFE48207850488801040602
+4036:008000407BF84A084A087BF84A084A087BF84A404A444A287A104A8803060200
+4037:00880088788849C8489E788A488A4BEA788A488A490A494A7BEA4912002A0044
+4038:080C08F07E8008800EFE78880888290812081FF010101FF010101FF010101FF0
+4039:0020002078204BFE482078204924492479244AAA482048507850488801040202
+403A:108020FC6910AA9028602890230C00001FF010101FF010101FF010101FF01010
+403B:0020002079FC492449FC792449FC48007BFE4880490049FC7804480400280010
+403C:000003FC7A004A004AF87A004A004BFC7AA04AA44AA84A907A904C8804A408C2
+403D:0004000E7BB8488848887928492E4BA878A84AA84AA8493E79004A80047E0800
+403E:0000FEFC104420287E10A2283EC600001FF010101FF010101FF010101FF01010
+403F:0104010EF130912097E0F120913E9164F1A4972491249124F124912405440284
+4040:1FF010101FF010101FF010101FF0080C08F07E8008800EFE7888088829081208
+4041:004000207BFE4800480079FC49044904790449FC482048A879244A2200A00040
+4042:7EFC48447E4442287E1048287EC600001FF010101FF010101FF010101FF01010
+4043:002000207BFE4820482079FC482048207BFE484048A449A87A904C8800C60080
+4044:0020002079FC482048207BFE4888485079FC482048204BFE7820482000200020
+4045:000001FC7808481048207BFE482048A0784049FC495449547954495407FE0000
+4046:004000807BFC49104A487C464BF84A487A484BF84A484A487BF848420042003E
+4047:020001007FFE4202A96C49940E1077F000001FF010101FF010101FF010101FF0
+4048:104008403E7E228823503E20205841869FF010101FF010101FF010101FF01010
+4049:104808443E7E23C022243E282212206A41869FF210101FF010101FF010101FF0
+404A:000003F87948491048A0784049B04E0E79F8490849F8490879F8490801F80108
+404B:0048014879484BFE494879484978490079FE48204BFE487078A8492406220020
+404C:000003FE7A224BFE4A227BFE480049FC790449FC490449FC7904490401140108
+404D:00140012F01097FE9410F41095D09412F41295D495549548F5DA942A08461082
+404E:004000207BFE480049FC790449FC48007BFE4A0249FC48207820482000A00040
+404F:000003FE785048504BFE7A524A524BFE780048404FFE48887990486000D80304
+4050:008800887BFE488848A8782049FC4924792449244BFE48207850488801040202
+4051:000001F8790849F8490879F848004BFE790049FC4A544C9479244A4400A80110
+4052:000001F87908490849F878004FFE490879F8490849F84908793E4FC800080008
+4053:000000887A524A224A527A8A4A024BFE788849444A7A48887950482000D80706
+4054:001E03E078444924488879FC484048407BFE488048FC494479284A1000680186
+4055:000003FC7A044BFC4A207BFE4A104A8A7B0648004BFC4A047BFC4A0403FC0204
+4056:0020012478A848204BFE78A849244A0278404BFE488849087990486001980604
+4057:002001247924492449FC78004BFE480079FC4904490449FC7888485003FE0000
+4058:0008003C7BC048044A44792849FC4A2078204BFE482049247924492401FC0004
+4059:000001FC790449FC490479FC48204BFE7A0248404BFE48887990486000980304
+405A:000001F87908490849F878004BFC4A047BFC4A044BFC4A047BFC489001080204
+405B:002000407BFC4A244A247BFC4A244A447BFC484048A848B4793C49220222041E
+405C:000001FC7D0445FC45047DFC442045247CA8442047FE44907C9045120212040E
+405D:08202AA42CA84920145022887FFE40029FF410101FF010101FF010101FF01010
+405E:082014502288082014502288FFFE08001FF028104FF088100FF008100FF00810
+405F:0108008878904BFC484079F848404BFE7880490049FC4A207C20482003FE0000
+4060:011000A078004FFE48A07BF848A84FFE78A84BF848A049B07AA84CA600A000A0
+4061:000003DE7A524BDE4A527BDE4A024A227A224A224A524A4A7A8A4A02020A0204
+4062:02100110F11097BE9240F20093BE928AF28892A892AE92A8F4A895A8085E1080
+4063:00207BFE482049FC492479FC492449FC78224BFE48084BFE7908488800280010
+4064:004000207BFE488848507BFE4A224AFA7A224AFA4A8A4A8A7AFA4A02020A0204
+4065:000003FE7A484A484BFE7A484A204BFE7A404AFC4B444A447A7C4A0003FE0000
+4066:0040007C78404BFE4A427A784BC44A3C7A004AFC4A844AFC7A844CFC048409FE
+4067:008800887BFE488848F8782049FC492479FC482049FC48207BFE485000880306
+4068:0200011EF7D2901297D4F45497D89014F7D29092911291DAF714911005100210
+4069:0040004078F849084A1079FC4924492479FC4924492449FC78004954012A022A
+406A:02000202E23CAFA0A220EFA0AABEAFA4EAA4AFA4A224AFA4E224A24402440284
+406B:000001FC792449AC4974792449FC482079FC48204BFE48007AA44A5204520000
+406C:0104008878004BFE4A227AAA4A724A227BFE480049FC490479FC490401FC0104
+406D:002800247BFE4850488879044A024998795449104BBE49107AA84AA804440882
+406E:000007BCF108952897BCF31895AA9946F00093F892089208F3F89208020803F8
+406F:004000A0F11896E69000F3F8920893F8F00097BC908494A4F29494A402940108
+4070:000000FEF0109720927CF2449244927CF244927C93C49E44F07C902800440082
+4071:0020002079FC48204BFE79084B9C490879884E3E48004BFE789048900112020E
+4072:000003FE7A524A524BFE780049FC490479FC490449FC490479FC488801040202
+4073:008800887BFE488848247BFE4850488879044A8A48884BFE7888488801080208
+4074:00400FFEF00097FC9404F5F4951497FCF00093F8920893F8F20893F800000FFE
+4075:000001FC7954495449FC78004BFE480079FC490449FC48627894498802A400C2
+4076:01080208F7C8945097DEF46497D49214F11497D4921493C8F2489454055408A2
+4077:0A803138228838382288393822887FFE40029FF410101FF010101FF010101FF0
+4078:009003FCF29493FC9294F3FC900093FCF20092F8920093FEF520951405480986
+4079:001003C87A7E4A404A627BD44A004A3E7BC84A484E7E4A487A484BC802480008
+407A:000001FC795449FC482079FC48204BFE7888485049FC48207BFE482000200020
+407B:044404E4E8A8AAAAAEEEE4A4AAAAAEEEE242A040AFFEA0E0E150A2480C460040
+407C:01FC792449AC492449FC782049FC48207BFE49544A2A482079FC482003FE0000
+407D:01240248792448004BFC7A944A644A947BFC4A484B684A487B6A4A4A02460362
+407E:010807FE790848004BFC7A944A944BFC78284BFE4A204B247AA84A92042A08C6
+407F:7F146B125D107F7E08107F100828FFA855449FF210101FF010101FF010101FF0
+4080:011007FCF04093F89040F7FC900093D4F11297FE93509534F38C908A02960102
+4081:01F00210F7FC920493FCF22493B89222F1FE921097FC9244F3FC90D0014A063E
+4082:07BC04A4F7BC94A497BCF4A497BC9120F3FE922097FC9A20F3FC922003FE0200
+4083:003C07C0F244912897FCF4A497FC9008F78894FE978894A8F798950805A80690
+4084:03DE7A524BDE4A524BDE78A049FE4B207DFC492049FE480079FC48880070078E
+4085:044404E4EA0AAEEEA404EAEAAE0EA0E0EAAAAAEAA040A7FCE444A7FC00440FFE
+4086:00407C400440287C10840884FF041A4428242824480448048804080428281010
+4087:00007CFC0424282410240824FE241AFC28442844484448448844084429FE1000
+4088:00107C10041028FE10920892FE921A9228FE289248104814881209FE28821000
+4089:0080F8BC0884510821FE1320FD20357C3190511051FE51109128112851442182
+408A:0080F8F8090853FE25121122FDFE344030A25354509853349054109253502020
+408B:100010FCFE4810307DFE44527C94111012307C2011FE50707CA8112412221020
+408C:0020F9FC0888505023FE1000FDFC352431FC512451FC502091FC102053FE2000
+408D:01FCF90409FC510421FC1088FDFC348833FE5088512452AA907010A851242060
+408E:0528FFBE094857BE231815AAFD4637FC320453FC520453FC920413FC51082204
+408F:200021FC3C445044904410441094FE88110010FC108428842484448440FC8084
+4090:2020202021247D245124912411FCFC2010201124112429242524452441FC8004
+4091:2048204820487D48514A916C1148FD48114811481148294A256A478A41068000
+4092:202020203C2053FE9020102011FCFE00100011FC110429042504450441FC8104
+4093:200021FC21047D0451FC91041104FDFC1104110411FC2850249044924112820E
+4094:2020202021FC7C20502093FE1088FC5011FC102010202BFE2420442040208020
+4095:208020FC21047DF8500893FE1040FCA21334105810942B342452449043508020
+4096:0000FFFE020002100408040408000FF81808280848088808080808080FF80808
+4097:00400040FE401044104420483E5062606240A2C0234022443E442244003C0000
+4098:000003FCFD041144112420A83C8864886450A450242024203C50248821040602
+4099:0000007CFE441048104820503E4862486244A244224422683E50224000400040
+409A:00080088FC501020105020883D0064086488A488245024503C20245020880306
+409B:000001F8FC081050102020103DFE64226424A420242024203C20242020A00040
+409C:00200020FC2013FE102020203C2065FC6420A420242027FE3C20242020200020
+409D:00500048FC481040105E21E03C4064446444A448243024223C52248A23060002
+409E:0000FFFE040008001FF02810C8100FF001000100FFFE054009203118C1060100
+409F:080008007F7C094411441144257C42000000FFFE08001FF82808C8080FF80808
+40A0:00400040FC8010FC112022203C20642067FEA420245024503C88248821040202
+40A1:0008001CFCE01080108020803C8064FE6488A488248824883C88248821FE0000
+40A2:00400040FC7C1084118822503C2064506488A706246024103C0824C020200010
+40A3:00900090F8902290229242D47A98CA904A904A904A904A927AD24712020E0000
+40A4:00880088FC881108117E23083D0865486528A528250825083D08250821280110
+40A5:000001FCFD041104110421FC3D20652065FEA520252025103D12254A21860102
+40A6:00200020FC501088110422123C2064406588A410242024443D88241020600380
+40A7:00800080FC8011FE110222043C2064206528A524262426223C22242020A00040
+40A8:0008001CFDE01100110021003DFE65106510A530251825143D12221002100410
+40A9:000001FCFD041124112421243DFC65246524A554254C258C3D04250421FC0104
+40AA:00900090FC901292119420983C9065986694A492249024903D1225122212040E
+40AB:00800080F8FC21082290406079984E26C82049FC48204A207BFE482000200020
+40AC:00007DF01110119011521D12E20E44000000FFFE08001FF82808C8080FF80808
+40AD:00400020FC2013FE100020883D0466026488A488245024503C20245020880306
+40AE:080008007F7C08243E2408447F5408880800FFFE08001FF82808C8080FF80808
+40AF:00200010FC1011FE110021103D106510657CA510251025103D10221002FE0400
+40B0:004200E2FB82208A208A408A7BEA488AC98A49CA4AAA4A827C824882008A0084
+40B1:01040084FC88101011FC21043D04650465FCA450245024903C922512220E0400
+40B2:08207E2008FCFF24102424447E5422880100FFFE08001FF82808C8080FF80808
+40B3:00200020FCA810A810A821743E2264206420A5FC242024203C20242023FE0000
+40B4:00400020FDFE1000100020FC3C00640064FCA400240024FC3C84248420FC0084
+40B5:000001FCFC20102013FE20003C0065FC6504A524252425243D54248821040602
+40B6:00880088F88821C8209E408A788A4BEAC88A488A490A494A7BEA4912002A0044
+40B7:001C01E0FC20102013FE20203CA864AA67ACA4A824AA25AA3EA6242020200020
+40B8:00140012F81027FE201040107BD2CA524A524A544BD4480878EA471A02260042
+40B9:00200040FCFE1124129820503C6067806420A42424A424A83D30245020880306
+40BA:000001FCFD24112411FC21243D2465FC6420A7FE247024A83D24222200200020
+40BB:000000FCFC8010F8108020F83C8067FE6540A524252825103D08254421820100
+40BC:00200020F85020882144422279F84808C850482048A44A827A8A4A8A04780000
+40BD:00200020FC3E102011FC21043DFC650465FCA524242027FE3C20242020200020
+40BE:00200020F82023FE2020412479244924CAAA487048A848A879244A2204200020
+40BF:00200022FBB420A820A841247AA24840C9FC4904490449FC7904490401FC0104
+40C0:00200020FBFE202021FC40247BFE4824C9FC48404BFE488479C8483000CC0302
+40C1:000001FEFC481048104821CE3D0265026502A5CE244824483C48244821FE0000
+40C2:000001FCFD04110411FC21043D0465FC6400A51225D425183D1025522192010E
+40C3:000003FEFA02228A225243FE7A424A22CBFE4A824A824A827AFA4A02020A0204
+40C4:00400020FBFE2000200041FC79044904C90449FC482048A879244A2200A00040
+40C5:01040088FC5011FC112421243DFC65246524A5FC242024203DFE242020200020
+40C6:00840084FDFE1084108420FC3C84648464FCA484248425FE3C00244820840102
+40C7:00200040FCFC108410FC20843CFC64206420A5FE252225223D2A252420200020
+40C8:01100112FDD41118115221923D2E644065FCA504250425FC3D04250421FC0104
+40C9:000001FCFD0411FC111021FE3D10654A6586A40025FC25043DFC250421FC0104
+40CA:00900090FBFC2090200041F879084908C9F84908490849F87908490807FE0000
+40CB:004000A0F910220825F640007BC44A54CA544BD44A544A547BD44A44025402C8
+40CC:000003FEFC50105011FC21543D54655465FCA420242025FC3C20242023FE0000
+40CD:01040088F80023FE204040C27922CA54489849384A5448947912461000500020
+40CE:00000040FBFE20882104464278FC4B08C8B048D04F3E48C27B24481800600780
+40CF:000001FCFD0411FC110421FC3C20652065FEA620242025FC3C20242023FE0000
+40D0:00400020FBFE2202208841047A224828C8244BFE482048507850488801040202
+40D1:0100023CF7A424A426A445A474C2DF8054BC54A456A455A474945488049409A2
+40D2:000003FEF80021FC2104410479FC4800CBFE4A8A4A524BFE7A224A22022A0204
+40D3:00880088FBFE208821FC40887BFE4820C9FC492449FC49247BFE490401140108
+40D4:00200010FDFE1102100020FC3C84648464FCA40025FE25023D02250221FE0102
+40D5:08202AA42CA84920145022887FFE40028004FFFE08001FF82808C8080FF80808
+40D6:00400080F9FC2104210441FC7900C9FE490049FE48024AAA7AAA440200140008
+40D7:000203E2F82221EA202A47FA788A4AAAC9CA488A49CA4AA27C924882028A0104
+40D8:000003DCFA9423D4225443C87A884A94CBE24800482049FC7820482003FE0000
+40D9:00400020FBFE2250225043FE7A52CA524BFE4A004A924AD47A98449204D2088E
+40DA:04200220F23E2F4024A04420773CD5505510551055FE5510752859280B441082
+40DB:00100010FAFE2110217C4054787C4B54C97C491049FE491079104A90047E0000
+40DC:00007F7848485F4C64805F7844484A4851307F4C00007FFC08001FF868080FF8
+40DD:02080248F7482290229E4FE47114D2145FD45494591451C87F08511405140222
+40DE:08407F4022F83E4800483EC804487EAA08AA290612027FFC08001FF868080FF8
+40DF:02880288F7C82290229E4FD47024D7D4545457D4545457C874485454046404C2
+40E0:02100110F11027BE2240420073BED28A528852A852AE52A874A855A8085E1080
+40E1:000003DEF88822A823FE41887ADA4CA6C9F84908490849F87908490801F80108
+40E2:02100210F51024BE282247447210D2105F1052105AA85728722853440C440082
+40E3:000E03F0F8442224210843F87A08CBFC4A044BFE4A024AAA7AAA450204140808
+40E4:004003F8F04827FE204843F87040D554575C544457FC5444775C555405540844
+40E5:002001FCFC88105013FE20003DFC652465FCA52425FC24203DFC242023FE0000
+40E6:08407F40227E3E8801483E4804507E200850288C10007FFC08001FF868080FF8
+40E7:008079F84A884870538E492049FC6A2050F84020FFFE04000FF83808CFF80808
+40E8:000003BEF8A220A220BE43887A08CA3E4A2A4BAA48AA48BE7888408A057E0202
+40E9:005001FCFD5411FC115421FC3C0065FE6500A57C250025FE3D50255421480266
+40EA:002003FEF80023FC220442F47A944BFCC80049F8490849F8790849F8000003FE
+40EB:010001F8FA0827FE228843247BFECA004AFC4A004AFC4A007AFC448404FC0884
+40EC:00400248FA4823F8208043F87A484BF8CA484BF8484848B478BC49220222041E
+40ED:00140012F7FE241025D0441475D4D55855CA54165442582472A2528A04780000
+40EE:00100410F27C201020FE40447628D2FE5210527C521052FE7210521005FE0800
+40EF:00200040F8F8228A218C40F8798C4A8AC8F848204BFE487078A8492406220020
+40F0:00800040F7FE24022A2443BC74A4DAA8551052E854045BFA70405248044400C0
+40F1:01140112F7D2211021104FFE7290D6D2529256D2529456D4728A52CA0F160022
+40F2:010003DCFA542366224047DC7A544B48CA544CA248004BFC7A944A9407FE0000
+40F3:01240248F924200023FC42947A644A94CBFC4A484B684A487B6A4A4A02460362
+40F4:04100210F07A27122014477E7008D710503C576455A4553C75245724053C0024
+40F5:004007FEF00023FC224043F87240D3F8524053FC5004555470A853100D480186
+40F6:00400020FDFE100011FC21543DFC64206522A48C252224543CC8254422520060
+40F7:00400FFEF40027FC200047FC7404D7FC50805C9C57D45D54755C5C9615562E22
+40F8:0148014CFAAA200827FE41487B68494ACB6A494C4B6C4948796A4B9A00260042
+40F9:03DE0252FBDE225223DE42227AFA4A22CAFA4AAA4AFA4AAA7AFA4A7202AA0226
+40FA:002007FEF48827DE248845DC76AAD488545057DE545055DC74505BDE08501050
+40FB:03FE0020F7FE242221AC428077DED2925392511E57D2555277DE51120FD20126
+40FC:1020082008207E200420082808241C222A224A20882008200820082008200820
+40FD:202010201020FBFE08201020102039FC54849488104810501020105011881606
+40FE:201011101110F9120912111411D83910551095101110111211521192110E1000
+40FF:202010201020F82009FC10201020382055FE9420105010501088108811041202
+4100:209010881088F88008BC13C010803888548894901060104410A41114120C1004
+4101:204811481148F948094813FE1148394855489548117811001100110011FE1000
+4102:202010201020F82009FC112411243924552495FC112411241124112411FC1104
+4103:202010201020F9FC0924112419243524512493FE102010501050108811041202
+4104:200011FC1104F9240924112411FC392455249554114C118C1104110411FC1104
+4105:0100111009203FF802007FFC082010102FE8C0063FF801001110210845040200
+4106:2008103C11E0F820082013FE10203820542095FC110411041104110411FC1104
+4107:200011FC1104F904090411FC1000380057FE9420102011FC1020102013FE1000
+4108:200013FC1000F80009F811081108390855F89400110810881090100017FE1000
+4109:201010D81394F894089013FE10903894549490D81398109010AA10CA12861102
+410A:202010201020FBFE08201020102039FC5440942010A41282128A128A14781000
+410B:2020102013FEF85008881124122239FC552495FC112411FC10221022101E1000
+410C:400023DE2042F94A1084114A225234206800ABDE205221522094214822542422
+410D:208810881088FBFE0888108817FE380055FC9504110411FC1104110411FC1104
+410E:2020102011FCF8500888110413FE380855E89528112811E81128100810281010
+410F:2088108813FEF8880800101C19E03420502093FE102010501050108811041202
+4110:1000540054FC7C8492849284FE8400FC7C800080FE80108254829282507E2000
+4111:201C13E01220FBFE0A201292130A3A0655FC9504110411FC1104110411FC1104
+4112:202010201050F8880944122211F838085450942010A41282128A128A14781000
+4113:2020104011FCF90409FC110411FC380057FE9420102011FC1020102013FE1000
+4114:2004101E13E0F82009FC1124192435FC502093FE1222122A12FA1202120A1204
+4115:2020102213B4F8A808A8112412A2384055FC9524112411FC1124112411FC1104
+4116:404020A02110FA0815F6100023C432546A54ABD42254225423D42244225422C8
+4117:405022522252FA5213DE1202220233FE6A02AA0223DE22522252225224522802
+4118:2020101011FEF884084811FE11023A24541095FE1040107C1044108410941108
+4119:200013FE1202F80009FC110411FC390455FC9440102013FE1000108811041202
+411A:4090209027FEF89013FC129423FC32946BFCA80021F8210821F8210821F82108
+411B:202011FC1124FBFE092411FC102039FC552495FC104013FE108811D01070138C
+411C:2040102013FEF80009541124195435FC502093FE1242129212FA120A12021206
+411D:2020102013FEF82009FC10401BFE348851049242159C110411DC110411FC1104
+411E:4100211023DCFA5415541288210832F46C02A80023FC20402150224825442080
+411F:01F03E0003F03E0003FA7E0201FE0C20703C1DE2F0221C1E0000FFFE11102308
+4120:202013FE1000FBFC0A0412F412943BFC540095F8110811F8110811F8100013FE
+4121:208010F81108FBFE0944119211FE3900557C9500117C1100117C1244127C1444
+4122:4080204027FCF91010A41F58255435526B58A800220823F8220823F822082408
+4123:202013FE1020F9FC080013FE12523BFE550495FC110411FC110411FC10881104
+4124:4108210827CEF912112417DE2552355E6FD2A91E2392255E2940211421122122
+4125:47FC20402FFEF84213581040235830006EEEAAAA2EEE20002FFE224825542FFE
+4126:04000EFC780408080810FF20082018201C202A202A2048208820082008A00840
+4127:04000E0079FC08440848FF480850185E1C422A422A8248828882090209140A08
+4128:08001DFCF02010201020FC20102033FE38205420542090201020102010A01040
+4129:04200E28782408240820FF2E08F018201C202A202A2048108812080A08060802
+412A:08401C40F08010FC1104FE041004310438845444544490041004100410281010
+412B:04000E0078FC08040804FF04080418FC1C842A802A80488088820882087E0800
+412C:08201C20F0201120112CFD34116433A439245534552891221122110210FE1000
+412D:08081C3CF1E010201020FC20102033FE38205420542090201020102010201020
+412E:08201C20F020102011FCFC201020382035FE5420505090501088108811041202
+412F:04000EFC784808480848FF48084819FE1C482A482A4848488848084808880908
+4130:08001DFEF00810881088FC88110831FE38185428544890881108120810281010
+4131:08401C20F02013FE1080FC80108030FC38845484548490841104110412281410
+4132:08201C20F02011FE1122FD22112231223952554A558A910211021102110A1104
+4133:08201C20F02011201120FD20113C312039205520552091201120112017FE1000
+4134:08001CFCF08410841084FCFC10843084388454FC548490841104110412141408
+4135:00701F80010001007FFC054009203118C00601001FF011001100FFFE01000100
+4136:08901C90F09013FC1094FC9413FC3A90369053FE50929092111A111412101410
+4137:08001C00F3FE10201020FC40104038FC35845284548490841084108410FC1084
+4138:08201C20F04011FC1104FD041104310439FC5504550491041104110411FC1104
+4139:00F83F0001007FFC092011102288CC643018C1E61F000100FFFE010001000100
+413A:08201C20F3FE102011FCFC2411FC312039FE5422542A90541050108811041202
+413B:08901C90F09012921194FC98109031983A94549254909090111211121212140E
+413C:08001DFEF02010201020FDFC112431243954554C558C91041104110411FC1104
+413D:08001DFCF05010501050FDFC1154315439545554555C91841104110411FC1104
+413E:08281C24F024102013FEFC2011243124392457A8552891101212122A14461082
+413F:08201C20F1FC11241124FDFC1124312439FC542054249018103210CA13061002
+4140:08021C02F3E2110A110AFDEA112A3A2A372A52AA544A904A10821102120A1404
+4141:01007FFC40040400FFFE08201E4003C03C3801E01F0001007FFC05401930610C
+4142:08801C80F0F811081310FCA0104038A03518520655F891081108110811F81108
+4143:00007DF01110119011521D12E20E440000E01F0001007FFC05401930E10E0100
+4144:08401C40F1FC10441084FC8411283210390857DE554A914A114A1252135A14A4
+4145:08201C20F1FC10201020FC2013FE30003820542055FC90201020102013FE1000
+4146:08101C10F210113E1122FC441010389034905310512891281128114410441082
+4147:00007FFC04403FF8244824483FF8000000E01F0001007FFC05401930E10E0100
+4148:0100111009203FF802007FFC082010D02F08C1061FF005400920111061080100
+4149:08001DFEF04810481048FC481248314A394A554C544890481048104813FE1000
+414A:08401C20F3FE12001200FE0C12F032203A20563E53E0922014221422181E1000
+414B:08801C80F0F811081210FDFC11243124392455FC54509050109010921112120E
+414C:08001CFCF084108410FCFC0011FE3102390255FE5502910211FE1102110A1104
+414D:08001C06F3B810881088FD08113E3B88348852885288913E11001280147E1800
+414E:081C1DE0F020102013FEFCA81124322239F85488549090BE1102110212141408
+414F:08001DFCF104110411FCFD00111831E0393855E0553C91E011221222121E1400
+4150:08001DF8F108110811F8FD08110831F83908550855F89090109011121212140E
+4151:08081C3CF3C010441224FD28110030403BFE5488510893901060105011881604
+4152:08901C90F3FE10901090FC40102033FE39005500550091001100110011F81000
+4153:12003A00E23C27D42454F854275435546D546554A74825482048205422942122
+4154:08921C92F12412481124FC921092300039FE5522552291FE1122112211FE1102
+4155:08001DFEF102110211FEFD10111031FE39105510557E914211421242127E1442
+4156:08201C20F3FE10501088FD24122231FC392455FC552491FC10221022101E1000
+4157:081C1DE0F020102013FEFCA811243A42344053FE5088910810D0103010481184
+4158:08201C20F02013FE1020FD24112431243AAA547054A890A81124122214201020
+4159:08001DFCF104110411FCFD04110431FC3800551255D49118111011521192110E
+415A:08201D24F0A8102011FCFC4013FE3888350452FA5488908810A810921082107E
+415B:08FC1C84F08410FC1084FC8410FC300039FE5502550291FE1102110211FE1102
+415C:08081C3CF1E0102013FEFCA810A830A83BFE54A850A893FE1020102011FC1000
+415D:08401C20F02013FE1202FC9411083204380055FC542090201020102017FE1000
+415E:08001DF8F10811F81108FDF8100031FC381057FE541091101090101010501020
+415F:00401848708411FE1020FBFE108831243A425588501090621184101810601380
+4160:08001DFCF104110411FCFD04110439FC340053FE50209120113C112012A0147E
+4161:08001DFEF020104011FCFD04110431FC390455FC5504910411FC100010881104
+4162:08201C20F3FE122213FEFE2213FE300039FC550455FC910411FC110411141108
+4163:08201C40F1FC110411FCFD0411FC30003BFE5420542091FC1020102013FE1000
+4164:08081C3CF1E010201020FDFE102030A0392C5524552491AC1124112411FC1104
+4165:08001DFCF10411FC1104FDFC108031FE3A2255225552910211FA100210141008
+4166:08881C88F3FE10881088FC0011FC31243924552455FC91241124112411FC1104
+4167:08401C20F3FC10001108FC9013FE300039F85508550891F81108110811F81108
+4168:081C1DE0F020102013FEFCA81124322239FC5504550491FC1104110411FC1104
+4169:08201C20F3FE102011FCFC881050302038585586540091FE110211FE10841102
+416A:08201C20F1FC112411FCFC2013FE300039FC5504552491241124105010881304
+416B:08401C20F3FE10001000FDFC110431FC390455FC542090A81124122210A01040
+416C:09041C84F088100013FEFC00108831043A0255FC555491541154115417FE1000
+416D:08201C10F1FE10841048FDFE11023224381055FE5440907C1044108410941108
+416E:08201C20F050104810A4FDFE128430FC388454FC548090FC11441144127C1044
+416F:08201C10F1FE1110117CFD1411FE3114397C5510557C914411441244127C1444
+4170:08001DFCF124112411FCFD241154318C390455FC5440902010A4128A128A1478
+4171:08201D24F124112411FCFC0013FE300039FC5504550491FC1088105013FE1000
+4172:08401C44F1F8105013FEFC4010F831823A7E540055FC910411FC110411FC1104
+4173:08801C80F1FC12441154FDF4108431283A9055FC5244955411F4108411281210
+4174:0020182073FE102013FEFA42148C31F03820544453FE90221128122414A41040
+4175:09041C84F088100013FEFC20102039FC3420542053FE900012A4125214521000
+4176:08001DFEF100117E1100FDFE1154314839645542550491FE114412241204140C
+4177:08881C88F3FE108810A8FC50108831743A22542055FC902010A8112412A21040
+4178:08881C88F3FE10881040FC2011FC3888345053FE5020902011FC102010201020
+4179:08201DFCF12413FE1124FDFC102031FC392455FC504093FE108811D01070138C
+417A:08001DFCF05011FC1154FD5411FC300039FC540057FE902010A8112412A21040
+417B:08401C20F3FE10001154FD24115439FC342053FE5242929212FA120A12021206
+417C:08001DF8F10811F81108FDF810003BFC369453FC500091F81090106011981606
+417D:08007F7808483E4800863E782A483E30404881E41F0001007FFC05401930610C
+417E:00001BDE708812A813FEF98812DA34A639F85508510891F81108110811F81108
+417F:08881FFEF088100011FCFCA810A833FE38A854A855FC902013FE102010201020
+4180:08001DFCF12411AC1174FD2411FC382035FC502053FE900012A4125214521000
+4181:08001DFCF15411FC1020FDFC102033FE3888545055FC902013FE102010201020
+4182:10203BFEE288225023FEFA5022FC32546BFE6254A2FC225022D8255426522850
+4183:211017FC004073F8120813F812082FFE400001E01F0001007FFC05401930610C
+4184:08101DFEF00011FE1102FD7A114A39FE340054FC508490FC108410FC100011FE
+4185:0A201D3EF04210941310FD28104631FC390455FC550491FC110411FC10881104
+4186:08F81C88F08810F81000FDDC1154315439DC542057FE907010A8112412221020
+4187:1000E7FC248425E42524FDE4252435E46D0465F4A50425F42414255625562832
+4188:1000E4FE228222FE2080F8AA2E9C32AA6A8062A8A2BE22C822BE2288250828FE
+4189:10003BFCE294229423FCF910225233DC681263CEA24023D2225C23D0225222CE
+418A:00941B987092118E1280F9FC112431FC392455FC508891FC108813FE10881104
+418B:108039F8E20827FE2252FBDE2050335E695267DEA152235E215027D22152233E
+418C:0394191077BE111813AAFD46102033FE380057FC500093FC100013FC120413FC
+418D:12103910E7DE2010245EFA8227DE30106FDE6450A7DE245027DE2450245224CE
+418E:1148394CE2AA200827FEF9482368314A6B6A614CA36C2148216A239A20262042
+418F:09241CA8F3FE10A81326FDFC112431FC392455FC548893FE108817FE11041202
+4190:01001FF002007FFC082037D8C1063FF811107D7C2020FEFE5454BABA10105454
+4191:020001007FFE400288241010200800007FFC0100010001000100010005000200
+4192:020001007FFE40028824121022081FE002200A200420062009221022201E4000
+4193:020001007FFE4002882411102208044008201FF004500440044008441044603C
+4194:020001007FFE48229114210801003FF82108210821083FF82108010001000100
+4195:020001007FFE4822911401003FF0011001100110FFFE0280044008203018C006
+4196:020001007FFE48229014220802007FFC0400048008801100222044108FF80408
+4197:020001007FFE48229014200800007C8844884488448844987CE8448800080008
+4198:020001007FFE4822901420081FF0111011101FF0111011101FF0111001000100
+4199:020001007FFE4822901400007FFC01000100110011F8110011001100FFFE0000
+419A:020001007FFE4822901400003FF820082FE8200827C82448244827C820082018
+419B:020001007FFE482290140000001879E048404840487E4BC0484078444844003C
+419C:020001007FFE4822941404007FFC08001FF028104FF088100FF0081008500820
+419D:020001007FFE400288241010210802003FF824482448244824482448FFFE0000
+419E:020001007FFE482290141FF010101FF010101FF0000010F01F00100410040FFC
+419F:020001007FFE4822911422880C603018CFE600001FF01010101010101FF01010
+41A0:01007FFE4822901400003FFC210021003FF8200820083FF8210021003FFC0000
+41A1:020001007FFE4822921401001FF010101FF010101FF011081090126014181806
+41A2:020001007FFE482290141040FDF810481448184833FED04010A0111052082406
+41A3:020001007FFE4822901400003FFC20002FF820003FFE2908289048604A188C06
+41A4:01007FFE4822901402001FF010101FF010121FF410187FF001900E10F0500020
+41A5:020001007FFE482290147FFC02000D08719002A00CC071A006981886E2800100
+41A6:020001007FFE482291140910092012C0043019086914091012A004401830600C
+41A7:01007FFE482290741F8001007FFC05401930E10E04007FFC08201C4003807C78
+41A8:01007FFE482290141FF010101FF010101FF000003FF801007FFC04401830E00E
+41A9:01007FFE482290141FF010101FF010101FF010101FF002007FFC04401830E00E
+41AA:1040102095FC550458501088FD04280028F828202820282029FC4800480287FE
+41AB:01007FFE4822901408001FF82A4844480A88110822A8041001004884481287F2
+41AC:01007FFE482290140FE008203FF820083FF820083FF820083FF8082010102008
+41AD:01007FFE4822901408007F7C08107F1049107F1049FE7F100810FF9008100810
+41AE:01007FFE4822901423F8100811F8800843F8500017FC2404E3F8211020E0271C
+41AF:01007FFE4822BEFC12480C3032C800003EF812480C3032C8FFFE082007C07838
+41B0:020001007FFE482290143FF8200027F0241027F020002F7829482F7820003FFC
+41B1:020001007FFE482290142040124890B04108460410402244E44820A023182C06
+41B2:01007FFE482291143FF820802FF820883FFE20882FF824C422A8449858868180
+41B3:01007FFE4822901423FC10801144066870B01128166810A4112416A0284047FE
+41B4:01007FFE48229FD410403FF051101FF011103FF821083FF821083FFA010200FE
+41B5:020001007FFE4822901408207FFC511449247FFC00001FF010101FF010101FF0
+41B6:01007FFE4822911408801FFC30805FF810801FF810801FFC1000248822444244
+41B7:01007FFE482290141FF002207FFC04887A8001003FF8282837D8244827C82018
+41B8:020001007FFE482290947EA00444282817D02008DFF610101FF0082004407FFC
+41B9:01007FFE49229FF404407FFC00001FF011101FF011101FF001003FF80100FFFE
+41BA:01007FFE4822901400F83F0011100920FFFE09203018DFF611101FF011101FF0
+41BB:020001007FFE482290147C200420FF3E22443EA422283E282390FE2842440282
+41BC:01007FFE4822901421F8110811E8012873FC120412F4129412F412142A0847FE
+41BD:01007FFE482291FC01003FFC21042FE021082FF823002C9023605CD843469CC0
+41BE:01007FFE482290143F2024203F3E21403F5024883F0800003FF824482448FFFE
+41BF:01007FFE4822905409FC490449FC490479FC090409FCF8204BFE48A849248A22
+41C0:01007FFE482290142200FF7E22243E3C08247F24493C7F240826FF7C08040804
+41C1:01007FFE4822901420443E2844FEFF1049107F7C49107F1000FE55104A908A90
+41C2:0200010001007FFC00001010082004400000FFFE010001000100010001000100
+41C3:1000080008FC7E8400840484448444FC2484288028800E82F0824082007E0000
+41C4:1040084008407EFE00800500447C44082410282028400E80F102410200FE0000
+41C5:1050084808487E40005E05E0444044442444284828300E22F052408A03060002
+41C6:1008088808487E4800080488444844482408280E29F80E08F008400800080008
+41C7:200011FC1104FD04010409FC8920892049FE4920512051101D12E14A41860102
+41C8:200011FC1084FC880050082088D88B064820482051FC50201C20E02043FE0000
+41C9:2000100013FEFC2000200840884088FC49844A84548450841C84E08440FC0084
+41CA:202010101010FDFE010009108910891049104920512851241E44E2FE44420800
+41CB:10200820087C7E840148043044284448259E282228420EA4F018401000600180
+41CC:2020112410A4FCA8002009FC8904890449FC4904510451FC1D04E10441140108
+41CD:200011FC1104FD04010409FC882088204920493C512051201EA0E260443E0800
+41CE:204810481048FDFE0048084889FE880048FC4884508450FC1C84E08440FC0084
+41CF:2040102013FEFC0001FC090489FC880049FC4808501053FE1C20E02040A00040
+41D0:2020102011FCFC2400240BFE8824882449FC4A22517450A81D24E22240A00040
+41D1:2040108011FCFD24012409FC8924894449FC4890511053FE1C10E01040100010
+41D2:7DFC44207D2045FE7C5048525492650E020001003FF8000008200440FFFE0000
+41D3:0BFE104061FC090411FC610405FC090431FCC088030401003FF808200440FFFE
+41D4:0100FFFE20003FF800003FF820083FF80200711C57D47014545C729651D6B622
+41D5:000021FC102013FEFA2201AC082089AC88004BFE502051FC1D54E1544154010C
+41D6:104010403F7E48908508080008001FF821084108020802080408180860500020
+41D7:104010403F7E2890450880000440082010102108C2060400082010103FF81008
+41D8:104010403F7E2890450880007FFC04000FF00810082010201FC00040FFFE0000
+41D9:20403F7E4890850800007F08010801083F08200840087F08010801080A080408
+41DA:104010403F7E4890850800000840084010403050504890441044104010401040
+41DB:104010401F7E28902488450881000100110011F81100110011001100FFFE0000
+41DC:204020407EFE5110880808000FFC10042108410001000280044008203018C006
+41DD:104010403F7E2890450880400420040004FEFF000210016001840E447034000C
+41DE:104010403F7E4890850810101010FFFE101010101FF01010101010101FF01010
+41DF:104010403F7E28904508902010203E2022FC4224A42414440844108421144208
+41E0:104010403F7E28904508820001007FFC010001003FF8010001000100FFFE0000
+41E1:204020407EFE51108A0801007FFE400280043FF8010001000100010005000200
+41E2:104010403F7E2890450881000100FFFE010001001FF01010101010101FF01010
+41E3:104010403F7E489085080280044009203118C106010009201110210805000200
+41E4:20403F7E489085080000FFFE010001007FFC4104428444444824400440144008
+41E5:104010403F7E4890850800007FFC01000100110011F8110011001100FFFE0000
+41E6:104010403F7E2890450881001FF0111011101110FFFE0280044008203018C006
+41E7:104010403F7E489085080000FFFE01003FF8210822882448282820083FF82008
+41E8:20403F7E4890850808001FF0282007C01830E10E1FF0010011001FF801000100
+41E9:104010403F7E4890850801003FF821083FF821083FF8010800B001C20E32700E
+41EA:104010403F7E4890850800007FFC040008201FF0011001003FF801000100FFFE
+41EB:20403F7E4890850800003FFC2080208027F82408240827F8208020803FFE0000
+41EC:104010403F7E48908508110011003FF841000100FFFE054009203118C1060100
+41ED:20403F7E48908508020002083FD00220FFFE0100061008E03F00C808080807F8
+41EE:104010403F7E489085080810087813C0304050409FFE10401040104017FC1000
+41EF:104010403F7E2890450880007FFC10101FF010101FF01010103EFFD000100010
+41F0:104010403F7E4890850800001FC000447D88055009203118C50602003FF80000
+41F1:104010403F7E4890850800003FF8220823C824482A882108228824083FF82008
+41F2:104010403F7E4890850801003FF8010011100920FFFE0280044008203018C006
+41F3:104010403F7E28904548822003F87E0003F03E0003FCFE20014000840764781C
+41F4:104010403F7E489085080000FFFE04403FF8244824482848303820083FF82008
+41F5:104010403F7E48908508200C11F01100810049FE49101110E110221022102410
+41F6:20403F7E4890850808001FF020205FF811081FF811081FF81108210821284010
+41F7:20403F7E489085083F04210421243F24082408247FA408A410A4108422944108
+41F8:104010403F7E289045089FF0101010101FF000003FF801001FF001007FFC0000
+41F9:20403F7E4890850800003FF80408FFFE04083FF808001FF8280848088FF80808
+41FA:20403F7E4890850800007FFC00001FF0101010101FF0000008200440FFFE0000
+41FB:20403F7E489085083FF820083FF8200020702F8020F02F8020F85F824082807E
+41FC:20403F7E489085081FF010101FF000003FF8210821083FF8200220021FFE0000
+41FD:104010403F7E48909508100C11F0FD00110011FE1D10F1101110121052102410
+41FE:104010403F7E4890850801007FFC00003FF800003FF800003FF820083FF82008
+41FF:20403F7E489085080100FFFE01003FF8210821083FF8238805601918E1060100
+4200:104010403F7E489085083F842A842A942A94FFD42A942A942A942A8420942188
+4201:20403F7E4890850802800C6037D8C0063FF8248824883FF82488248824A82010
+4202:104010403F7E48908508101008207FFC082008200820FFFE0820082010202020
+4203:20403F7E4890850823FC10841084808449144A0815FCE1042104210421FC2104
+4204:104010403F7E289045089FE040445194492443C445444924551442047FFC0004
+4205:104010403F7E4890852800907FFC00803E88228822503E5000240754788C2104
+4206:20403F7E4890850800803FFC200420043FFC20A020902FFC2120421044089806
+4207:20403F7E48908508010001FC01003FF820083FF820083FF80100FFFE01000100
+4208:104010403F7E489085083EFC22A422A43EA422FC22803E80228222824A7E8400
+4209:204020407EFE51108A0801003FF80820FFFE04007FFC08201C4003800C707008
+420A:20403F7E4890850801003FF80100FFFE1010220847E40820144003801C70E00E
+420B:20403F7E4890850801047D9809603118C50602001FF010101FF010101FF01010
+420C:20403F7E48908508100009F80908410821F82908090811F87108110817FE1000
+420D:20403F7E489085080080FFFE10001FF800001FF010101FF010101FF010101FF0
+420E:20403F7E4890850812207FFC122013E010001FF80100FFFE05401930E10E0100
+420F:20403F7E4890850800007FFC00001FF010101FF000003FF821083FF821083FF8
+4210:104010403F7E48909548104013FE5880549051109152125414A8102810441082
+4211:20403F7E489085081FF010101F9010907FFC40044FE4482448244FE440144008
+4212:20403F7E489085080100FFFE01003FF8244822882FE821083FF8210821282010
+4213:104010403F7E489085081FF010101FF010101FF008001FFC2104528414541FE8
+4214:20403F7E489085087CF8440844087CF8400041F87C88405040207C5040884306
+4215:20403F7E489085081FF010101FF010101FF000007FFC110011F8290047FE8000
+4216:20403F7E489085080C10709010501010FC903050381E55F05010901010101010
+4217:20403F7E4890850809100A0817FC31105208948411F813081490106011981606
+4218:20403F7E4890850808200440FFFE1020102024487CF80810102024487EFC0204
+4219:104010403F7E4890850810001008240879FE100824887E48004854084A288A10
+421A:20403F7E48908508080010103FF800081FF0101010101FF001004884481287F2
+421B:20403F7E4890850808000F7C084408447F44552855287F105510552855444382
+421C:20403F7E489085080BF8080811F8300853F8900017FC140413F8111010E0171C
+421D:20403E7E4890BFFC010411F011002FFE40009FF010101FF010101FF010101030
+421E:20403F7E4890850800807FFC00001FF010101FF000003FF820083FF820083FF8
+421F:204020407EFE511088083F0421243F2421243F24212421243F24120421144088
+4220:20403F7E4890850800FC7F00220811103FF80200FFFE04000FF0122021C0CE3C
+4221:20403F7E4890850808001FF82A4844480A88110822A8041001004884481287F2
+4222:20403E7E4890900020087FFC00043FF820083FF80100FFFE054009203118C106
+4223:104010403F7E4890850800207F20043E044427A42428242824102F28F0444082
+4224:20403F7E4890850810881088FC8813FE3088388854F854889088108810F81088
+4225:20403F7E4890850810101F1022107FBEA4923F9224923F92249224A242AA8144
+4226:20403F7E489085082448238824483FF81010220847E40820144003801C70E00E
+4227:20403E7E489080F87F00221011201FE010201FF010101FFC20042AA44AA4800C
+4228:20403F7E4890850800007DF8450849F8510849F8452445285510494841864100
+4229:20403F7E489085080804140422245D248024112409244A2427A4F80440140008
+422A:20403F7E489085087FFC00001FF010101FF000007FFC482444445FF44104410C
+422B:20403F7E489085081020102025FC7D2409241154254C7D840104550455148108
+422C:20403F7E48908508404427FE204087FC444457FC1444E7FC2444244424540408
+422D:204020407EFE51108A0804003FF821083FF821083FF8029004A808FA308AC07E
+422E:20403F7E489085082080108010FCFD0402F44894489448F410941E04F0284010
+422F:20803EFE4910BFF801001FF010101FF010101FF010101FF01010FFFE08201010
+4230:20403F7E489085081020112410A8FC2011FC11041DFCF10451FC110451142108
+4231:104010403F7E4890850800FC7F00220811100C20307820083C7820083FF82008
+4232:20403F7E4890850810783E4822482A862300FEFC22442A44222842104A2884C6
+4233:20403F7E48909FF810081FF810081FF800007EFC224412240A1412246AD40408
+4234:20403F7E48908508102008407FFC04803FF00490FFFE04903FF00CA03498C486
+4235:20403F7E4890854808203218C4460FE000207EFC224412240A1412242A544488
+4236:104010403F7E4A9085087FFE400289241290244808203FF8C82608200FE00820
+4237:20403F7E48909508108010F8FD08129030603998560651F89108110811F81108
+4238:20403F7E4890850810041F2422147F84A4A43F9424863FBC2484248442848104
+4239:20403F7E489085087FFE48028BF4108033F85208920813F81208120813F81208
+423A:20403F7E48908508104010FC24887D50082010D827067C60001054C054308008
+423B:20403F7E48908508002878244BFE482079FC492449FC792449FC49244924990C
+423C:20403F7E50908A0801007FFE42028924284849940E1077F00100210821083FF8
+423D:20403F7E4890850808207FFC08200FE001003FF821083FF801007FFC0100FFFE
+423E:20403F7E4890850810201124FCA8102031FC390455FC910411FC110411141108
+423F:20403F7E489085087FFC40041FF010101FF010101FF00100FFFE082010102008
+4240:20403F7E4890850800803FFC222022203FFC2220222023E020004A4849249124
+4241:20403F7E489085080010FF9022283E4422923E08227C2384FE08023002080204
+4242:20403E7E48909FF011101FF011101FF0040008201FC003103FF8112025104208
+4243:20403F7E489085080440247C24A83D50042804487DFE24882448244844088418
+4244:20403F7E4890850878404BF8504067FC51104A884CF4691052A0404041B04E0E
+4245:104010403F7E4890954810407C4011F8FE48444828C87C4810AAFEAA11061202
+4246:20403F7E489085081FF010101FF010101FF010001FFC10001FFC492484940008
+4247:20403F7E4890950811047FC411241F2411241F2411247FE42924308420143FC8
+4248:20403F7E4890850824207E20243EFF4400A47E2442287E2842107E2842444682
+4249:20403F7E4890850820003E1C44E87EA8AAA83EA82AA83EA82AA42B542B744612
+424A:20803EFE551088201FF00210FFFE09203FF8D1161FF011101FF001007FFC0100
+424B:20403F7E4890850811FC1124FDFC2500257C4944297C1144297C4644827C0444
+424C:20403F7E4890850878904BFC48805144566848B049284E6868A4512246A04040
+424D:20403F7E489085087C7C44447C7C44447D7C40844A244A14525441C440144008
+424E:20403F7E48908508111009203FFC20044FE808200FE001007FFC05401930610C
+424F:20403F7E4890850810001EFC22247F44A99C3F50297C3F9029FE291045108210
+4250:20403F7E489085081020FE2010207DFC54207C2054F87C881088FE8810F81088
+4251:20403F7E4890850810003FFC4AA00AA07FFC0AA00AA07FFC0000248822444244
+4252:20803EFE491080F83F0011100920FFFE09203018DFF611101FF011101FF01010
+4253:20403F7E48908508100011FC1124FDFC312439FC542053FE90A8112412221020
+4254:20403F7E5090880800900088FBFE20483C3245CE4890A88813FE10482032C1CE
+4255:20403F7E48908508082004403FF8292825483FF800001FF010101FF010101FF0
+4256:20403F7E4890850808107F1008287F4449927F08497C7F040808FFB008080804
+4257:20403F7E4890850811F81108FDF8100013FC11081DF8F10811F8110E57F82008
+4258:20403F7E489085081040102013FEFA0214FC300039FE542050A8912412A21040
+4259:20403E7E4890BFF801007FFE41029D7401001D7000003FF80000FFFE10103FF8
+425A:20403F7E489085083FF824483FF800007FFE4002BFF408000FE0112416A4181C
+425B:20403E7E489084003FF8292825482FE8254828280100FFFE02800C603018C006
+425C:20403F7E4890850820A020907DFE9120132011FCFD2011FC2920252041FE8100
+425D:20403F7E4890951808203FF801007FFC02403C500848FFFE08507E240854198C
+425E:20403F7E4890850800283FFE20202FA420282F9048AA4FC682820900282847E4
+425F:20403E7E4890812011FC1320FDF8112015F8192031F8D10013F8111050E0271E
+4260:20403F7E4890850822204AA08ABE1FC420A46F24A0282F28291029A829443082
+4261:20803EFE4910FFFE00003FF8200827C824483FF810101FF010101FF00000FFFE
+4262:20403E7E489081007FFC11102928FFFE00003FF8200827C8244827C820083FF8
+4263:20403E7E489082001CF010101EF010101FF008001FFC20044924249424944008
+4264:20403F7E4890850849202A20FF3E2A4449A41024FE282228641018282444C282
+4265:20403F7E4890854811FE1122FD7A118A155219223152D1FE104012A4528A247A
+4266:20403E7E48908FF841402FF829480FF8E1002FFC24102BE8322423E052088FFE
+4267:20403E7E4890F784428462A454A469A414242224DD2408247F244A042F94F008
+4268:20403E7E4890900008787F48224814867F0010FC694416446D281490642818C6
+4269:20403F7E48908508100013FE1200FE7C1244327C3A0056EE52AA92EE120013FE
+426A:20403F7E489085083FF821083FF821083FF80000FEFE9292FEFE9292FEFE8282
+426B:20403E7E48908640387C08947E241C442A94490802C01D30E92E054009201310
+426C:20803EFE491080803FFE20202F2831102A0A277C294A378428784F484130874C
+426D:20803EFE49109084210810843FF82448238824483FF829482528294A25263182
+426E:20403E7E4890FC7C44447C7C44447D7C44844FE459044FC449044FC449044FEC
+426F:20403E7E4890BF7C24443F2821103F2824463FF010101FF010101FF008201010
+4270:20403E7E4890BE2022103AFE2A007F2841443E8222283E2822103E2822442682
+4271:20403F7E4890A508100003FEFA000A7C12442A7C7200AAEE2AAA22EE220023FE
+4272:20403E7E48908000F7FC124817FCFC4686EC8554F6EC155416EC144454542408
+4273:20403F7E4890850820443E2844FEFF1049107F7C49107F1000FE55104A908A90
+4274:20403F7E489085087FFC00003EF822883EF804403FF80440FFFE04901C60671C
+4275:20403F7E48909FF8149012501FF00200FFFE0AA03458CFE6155007C004A00670
+4276:20403E7E4890A4483F7E64C8BF7E24483F7E24483F7E20401FF0082007C0F83E
+4277:20403F7E489085081E7812483FFC20202E20223C3FC829282F2849905F288144
+4278:204020407EFE5110880841102788F83E53942008FBBE2008739C228843888288
+4279:20403E7E4890BFF801007FFE492284143BB82AA83BB800007FFC11102928FFFE
+427A:080008004AFC2A202C200820FE2018201C202A202A2048208820082009FE0800
+427B:1004101E95F0551059101110FD1031FE3910551055109108110A114A11861102
+427C:0804080E4AF02A802C800880FEFE18881C882A882A8848888888090809080A08
+427D:10201020952454A458A81020FDFC30203820542057FE90201020102010201020
+427E:044004447C78044004421C42E43E0000111009207FFC054009203118C1060100
+427F:1008103C95E05420592410A4FCA8302039FE5420542090201020102010A01040
+4280:10201020942054205BFE1020FC20302039FC5504550491041104110411FC1104
+4281:10201120952055FC59201220FC2033FE3890549054909090111211121212140E
+4282:1020102097FE5420582011FCFD2431243924552C547090A81124162210201020
+4283:200027FC2404AC0475F42444FC4425F475546D54AD5425542574244624462842
+4284:00007DF01110119011521D12E20E4400111009207FFC054009203118C1060100
+4285:1040104094FC55045A881050FC203040388055FC568490841084108410FC1084
+4286:04003878200820083C78200820083FF80000111009207FFC054009203118C106
+4287:1028102495FE5420582011FCFD24312439FC5524552491FC112411241124110C
+4288:1080108094FE55005AFC1084FCA430943BFE54845524911411FE100410281010
+4289:1040102095FC55045A281020FC2031FC3870546854A890A41124122210201020
+428A:100011FC9504550459FC1100FD1C3170391C5570551E91F0111011121112120E
+428B:1048114895485548594811C8FC7E30483BC855485548914811481148125C1440
+428C:10201010941055FE59001148FD4A314A396C55485548914A114A126A12461400
+428D:0C8070FC1124FD2412243844548491281010111009207FFC054009203118C106
+428E:1020112494A8542059FC1040FDFE3088390456FA5488908810A810921082107E
+428F:102010A494A4552858501088FD043024382054A854A891301050108811041202
+4290:100011FC9504550459FC1104FD0431FC3800551255D49118111011521192110E
+4291:1020112494A454A8582011FCFD04310439745554555491541174110411141108
+4292:10A01090948055FE59101310FDFC3110391055FC55109110111011FE11001100
+4293:100011FC9504550459FC1104FD0431FC380057FE54209120113C112012A0147E
+4294:2088208823FEA88870A82020F9FC212471246924ABFE20202050208821042202
+4295:20102010207CAB1471FE2114FA7C2210777C6910A9FE25102210230024FE2800
+4296:2020202023FEA820702023FEFA8A225272FA6A22AA2222FA22222222222A2204
+4297:1020104095FC550459FC1104FDFC30003BFE5420542091FC1020102013FE1000
+4298:1020102095FE552259FE1122FDFE300038FC548454FC908410FC108410941088
+4299:0000FDFE204840487DFEC44844887D080008111009207FFC054009203118C106
+429A:20102220217CA9447044207CFB402140717C6944A944217C21442280247E2000
+429B:2000245C2294A91472942454F926210077DC6914AD9425542948210825142222
+429C:102013FE942055FC592411FCFD2431FC382257FE540893FE1108108810281010
+429D:101C11E09420552458A813FEFC7030A8392456225440902412A2128A14881078
+429E:2040202023FEA888705023FEFA2222FA72226AFAAA8A228A22FA2202220A2204
+429F:2088208823FEA888708820F8F82023FE72226B32AAAA237622222222222A2224
+42A0:7DFC44207D2045FE7C5048525492650E111009207FFC054009203118C1060100
+42A1:100011F8950855F8590811F8FC0033FC3A9457FC540091F81090106011981606
+42A2:0440247C24A83D5004287DFE248844488418111009207FFC054009203118C106
+42A3:1088108895FC5488588813FEFC2031FC392455FC552491FC1000108811041202
+42A4:100013FE945057FE5A5213FEFC0031FC390455FC550491FC102013FE10201020
+42A5:202021FC2024ABFE702421FCF82022AA73AE6A22ABFE222223AE22AA22AA2422
+42A6:102013FE942055FC580013FEFE0231FC380055FC550491FC1104108813FE1000
+42A7:209027FC2094ABFC729023FEF91223FA750E69F8A90821F8210821F820902108
+42A8:0100FFFE20003FF800003FF820083FF80100755C539477D4511473965556B122
+42A9:103C13E0952454A85BFE10A8FD24320239FC5524552491FC1124112411FC1104
+42AA:1088108897FE548859FC1124FDFC312439FC542057FE9222122A12FA120A1206
+42AB:200023FC2294AA9473FC2000F890279E70906890AB9C20902090279E20902090
+42AC:0DFC712411FC1124FDFC30203BFE54A851248222111009207FFC05401930E10E
+42AD:102013FE942055FC580013FEFC0231FC382057FE540093FE100413BE12A4138C
+42AE:200023DE2042AA52714A2252F890210873FE6D10A9FE211021FE211021FE2100
+42AF:1020101095FE5528597C1128FDFE3110397C5554557C9154117C120012441482
+42B0:22102110203AAB92701423BEF8082390703C6BE4AAA422BC22A423A422BC2024
+42B1:2148214C22AAA80877FE2148FB68214A736A694CAB6C2148216A239A20262042
+42B2:0010FE0828FEFE00AA44AA28FEFE108854A838BEFEC8108838BE55089108127E
+42B3:202023FE2248ABFE724822ECFB5A224872506BDEAA5023DC225025DE24502850
+42B4:1088108894EE55545A221050FC8831743A0255DC555491DC1088108811541222
+42B5:104010402040244045F8F848104820484848FC480448004A548A548A81060200
+42B6:1020102020202520452CF934116423A44924FD34052801225522550280FE0000
+42B7:080808081008120822FE7C080818101824287E28024800885208490889280010
+42B8:100011FC200024004400FBFE104020404880FCFC040400045404540480280010
+42B9:1008103C21E024204420F820102023FE4820FC20042000205420542080200020
+42BA:100011FE204024404440F87C108420844884FD0405FC00085408540881FE0000
+42BB:104010402040247E4482F884112022204820FC50045000485488548481020200
+42BC:10101010201024904490F890109E20904890FC90049000905490549083FE0000
+42BD:10201020202025FC4424F824102420244BFEFC20045000505488548881040202
+42BE:102010202020242045FEF8201070207048A8FCA8052401245622542080200020
+42BF:102010202020242045FCF820102020204BFEFC20045000505488548881040202
+42C0:010000803FFC20043FFC2080211023E02040208827FC20444250444889440080
+42C1:10401020200025FC4400F80010F020904890FC900490009254925512810E0200
+42C2:080408441028121022287C440880100424447E44022800285210492889440082
+42C3:1008103C21E024204420F83C11E020204820FC3E07E00020542254228022001E
+42C4:100011FC210425044594F954115421244924FD54055401945504550481140108
+42C5:101010102090249044FEF890111020104810FDFE041000105410541080100010
+42C6:10401020202025FC4504F904110421FC4904FD00050001005500560082000400
+42C7:100011FC210425044504F90411FC21204920FD20052001105510550882040402
+42C8:08007F7C114432280C101228634604201FC0018006103FF80108112025104208
+42C9:1040102020202BFE4A02F404100020904890FC90048801085508550482040402
+42CA:1000100021FE24104410F81010902090489EFC90049000905490549083FE0000
+42CB:100011FC210425044504F9FC1120212049FEFD20052001105512554A81860102
+42CC:100011FE210025004500F9FC110421044904FD0405FC01005500550081FE0000
+42CD:1000100021FE24084408F9E8112821284928FD2805E801285408540880280010
+42CE:1000100021FC25044504F90411FC21044904FD0405FC01045400540083FE0000
+42CF:10801080208024FE4540F9401240207C4840FC400440007C5440544080400040
+42D0:10281024202428204BFEF220122422244A24FA280A280290AB12AA2A80460082
+42D1:100011FE202024204420F9FE112221224952FD4A058A010255025502810A0104
+42D2:100011F8200824504420F81013FE206248A4FCA0052002205420542080A00040
+42D3:1080108020F825084610FC2011FC20044804FC0405FC00045404540481FC0004
+42D4:100011FE201024104420F820106820A44922FE22042000205420540083FE0000
+42D5:081813E0304057FC904013F8020004201FC0018006103FF80108112025104208
+42D6:1020102020FC242445FEF82410FC20204820FCFC0420002055FE542080200020
+42D7:100011FE212025204520F9FC110421044904FD0405FC01205520552081FE0000
+42D8:1020102023FE28204820F1FC102020204BFEF87008A800A8A924AA2284200020
+42D9:100013FE210825084508F9F81108210849F8FD080508011E57E8540880080008
+42DA:100013DE204228424A52F14A114A204248C6F94A0A520042A842A842814A0084
+42DB:10201020212424A444A8F820102023FE4870FCA804A801245524562280200020
+42DC:100008FC3E44222822103E28224644209FC0018006103FF80108112025104208
+42DD:10401024222425084508F810104020404BFEFC88050801905460545081880604
+42DE:100011FC210425044504F9AC115421544954FD5405AC01045504550481140108
+42DF:100011F82008240845F8F9001104210448FCFC40042000A4AA8AAA8A84780000
+42E0:1028102421FE24204420F9FC1124212449FCFD24052401FC552455248124010C
+42E1:10201020205028884904F2FA102020204BFEF82009280124AA22AC2280A00040
+42E2:080C08F07E8008800EFE788808882908164808801F0002103FF8010815202210
+42E3:201020103F244044BEF8221032202A44FF7E221252104A547F52029214500820
+42E4:084008407F40087C3E840884FF04104422247C240904FF8408844904A8A81010
+42E5:100011FC2124252445FCF924112421FC4820FC2005FC00205420542083FE0000
+42E6:1080108020FE250046FCF88410A4209449FEFC840524011455FE540480280010
+42E7:100011FC2104250445FCF910111021FE4910FD10057C014455445544817C0244
+42E8:1040102021FC24004508F890100023FE4800FC0005FC01045504550481FC0104
+42E9:10001040239C2A044A04F39C120422044BFCFC9004900090549055128212040E
+42EA:2000277E450445049574E554265445549554F55405741554AE04A40484140408
+42EB:1080108020F825084610F9FC1024202449FEFC24042401FC5424542080A00040
+42EC:100013FC204028404BFEF0A0111022084C46F84008480264AA52AC5281400080
+42ED:1040102023FE28804904F3FE100221FC4904FDFC050401FC5504550481140108
+42EE:10201020205024884504FA0210F820204820FDFC0420012454A454A883FE0000
+42EF:104808443E7E23C022243E282212206A444688821F0002103FF8010815202210
+42F0:1FF010101FF010101FF010101FF01010FFFE11102248CF8602201FF009481320
+42F1:1020102020202BFE4820F124112421244AAAF87008A800A8A924AA2284200020
+42F2:100011F02110291049F0F04013F822484A48FBF80A480248ABFAA8428042003E
+42F3:1050105223DC245044D2FB4E100021FC4904FDFC050401FC5504550481140108
+42F4:100010FC2048243045FEF852109421104A30FC2005FE007054A8552482220020
+42F5:100011FC210425FC4504F9FC108021FE4A22FD220552010255FA540280140008
+42F6:100013FE2020244045FCF904110421FC4904FDFC0504010455FC540080880104
+42F7:00207E20247E18A4FF2829104A2898C6044008801F0002103FF8010815202210
+42F8:1008101C21F025104510F9FE1110217C4944FD7C0544017CA944AA44827C0444
+42F9:100013FE200029FC4904F10411FC20004BFEFA220A2203FEAA22AA2283FE0202
+42FA:108811C827082908492AF12A17AC21484B08FB880D540514A914A92481240142
+42FB:1020102023FE28204820F3FE128A22524AFAFA220A2202FAAA22AA22822A0204
+42FC:100011F82088249044FCF954112421544A88FC0005FC0154A954A95483FE0000
+42FD:21042104410447C4913EE10427C440249114F11407C41104A904A1C48E140408
+42FE:1000104023FE28884904F64210FC230848B0F8D00F3E00C2AB24A81880600780
+42FF:100011FC2124292449FCF124112421FC4800FBFE09200122A914A94881840102
+4300:10C41704212429144914F784112421144B94FB460D3C0504A904A90481040104
+4301:100013FE205028504BFEF252125223FE4800FC4007FE00885590546080D80304
+4302:100013FC220422044BFCFA0013FC22404A88FBFC0A241220ADFCA420882013FE
+4303:1082108222A229CA488AF3EA122A222A4BEAFA2A0A2A03EAAA22AA2282AA0244
+4304:11FC102021FC25244554F904112C2020483CFC2005F800885450542080D80306
+4305:1020101021FE2510457CF91411FE2114497CFD10057C0144A944AA44827C0444
+4306:1020104023FC2A244A24F3FC122422444BFCF84008A800B4A93CA9228222041E
+4307:1020102023FE28204BFEF242148C21F04820F8440BFE0022A928AA2484A40040
+4308:100011FC210429FC4904F1FC100023DE4842FA52094A00C6AB5AA842814A0084
+4309:100013FE22522A524BFEF000100023FE4820F820093C0120A920A92087FE0000
+430A:1008103C23C028044A44F12811FC22204820FBFE08200124A924A92481FC0004
+430B:1088108823FE28884820F050108821044AFAFC00040001FC5504550481FC0104
+430C:100013DE20422A52494AF2521042202049FCFD04050401FC5504550481FC0104
+430D:1088108823FE248844F8F82011FC212449FCFC2005FC002055FC542083FE0000
+430E:00407CF8554854307DCE54F854887CF8044008801F0002103FF8010815202210
+430F:1040102023FE2A424828F29412AA24CA48F8FB0008200124A924A92481FC0004
+4310:100E13F020442A244908F3FC120423FC4A04FBFC0A0403FCA890A91082120C0E
+4311:100013DC22942BD44A54F3C8128822944BE2F800082001FCA820A82083FE0000
+4312:1040102023FE22504A50FBFE125222524BFEFA000A9212D4AA98A49284D2088E
+4313:20783F48404CBE802A78FF284A107F28044408801F0002103FF8010815202210
+4314:100013FE22002A7C4A44F244127C22004AEEFAAA0AAA02AAAAEEAA0083FE0000
+4315:2040202047FE44909490E49027FC449094D8F5B805B416D4A892A89090900090
+4316:10A0109021FE2B2049FCF12011FC212049FEFD00042003FE547054A883260020
+4317:2100210043FC46A89AA8E2A827FC42A892A8F2A80FFE1000AAA8A25484540000
+4318:082049202A3E7F4849485DA86B104928454608801F0002103FF8010815202210
+4319:1088108821FC24884488FBFE102021FC4924FDFC052401FC5400548881040202
+431A:100013FE205028504BFEF252125223FE4924F8A80BFE0070A8A8A92486220020
+431B:10001E0C22F05420284410F82810FF2400FE7E1200507E5400927F1242507E20
+431C:10501252215428504BFEF088105023FE4820F9FC082003FEA8A8A92486220020
+431D:2110211047BC411093B8E5542912400093F8F00007FC1040AA48A44489420080
+431E:10201020205024884504FAFA1000200049DCFD54055401DC5488548881540222
+431F:101013C8227E2A404A62F3D41200223E4BC8FA480E7E0248AA48ABC882480008
+4320:02907FD0421E5EA242885D0855485ED4846208801F0002103FF8010815202210
+4321:109013FC22942BFC4A94F3FC100023FC4800FBFC0A0403FCA908A89087FE0000
+4322:100011FC20202BFE4A22F1AC102021AC4850F8C80B2600F8A808A8D080200010
+4323:1108110821EE2A944842F01011FE210248F8FC8804F8008054FC548480FC0084
+4324:200027FC424844449FFEE44426EC455496ECF44406EC1554AEECA44484540408
+4325:103E17C0224421284BF8F84017FC20004BF8F8080BF81008ABF8A544852A08FA
+4326:100013DE20422A52494AF252109021084BFEFD1009FE0110A9FEA91081FE0100
+4327:102013FE202029FC4800F3FE100221FC4820FBFE080003FEA804ABBE82A4038C
+4328:1088108823FE28884910F1DE125225544A88F9740A0201FCA820A92482220060
+4329:110817FE210828004BFCF294129423FC4828FBFE0A200324AAA8AA92842A08C6
+432A:13DE125223DE2A524BDEF242127A228A4B12FADA0A8A02DAAA8AAAFA820A0204
+432B:13D0129023DE2A684BC4F28413F8210849F8FD0805F8010855F854908112060E
+432C:1110109023DE28104A5EF18213DE20104BDEFA500BDE0250ABDEAA50825202CE
+432D:1088108823FE28A84890F1FE112023FC4D20F9FC092001FEA900AAA482520452
+432E:11FC102023FE2A2249ACF02011AC2000489EFBF2089E01D2AABEAC92809E0092
+432F:108813FE20882BDE4A52F3DE10A0209049FEF9200BFC0520A9FCA92081FE0100
+4330:13FC110821F8290849F8F10E17F820084FFEFA940B9C0294AB9CAAD687BC0084
+4331:40807FFC48008FF8A000EFF848084FF8A100FC9C15D45C14555C5C9695D62C22
+4332:108813FE208829F04820F3FE102021FC49ACFD7405FC002055FC542083FE0154
+4333:27FC224847FC4C4696ECE55426EC455496ECF454040817FCA840A3F8805007FC
+4334:40807FFC48008FF8A000EFF848084FF8A220FD5C17F45C9455DC5C9697F62CA2
+4335:13FE120223FE2A924A54F29212FE22AA4AFEFB220AFA02AAAAFAAA2285FA0004
+4336:101010102010241045FEF810103020304050FC50409001101C10E01040500020
+4337:102010202020242045FCF924112421244124FDFC412401241D24E12441FC0104
+4338:10201020202025FC4420F84013FE20404080FDFC400400881C50E02040100010
+4339:100013FC220422044A04FAF4129422944294FA9442F402941A04E20442140208
+433A:100013FE2088248844F8F888108820F84088FC88408E03F81C08E00840080008
+433B:100013DE204220424A52F94A114A204240C6F94A425200421842E042414A0084
+433C:110410842088241045FCF9041104210441FCFC50405000901C92E112420E0400
+433D:1008103C23C020444A24F9281100202043FEF87040A800A81924E22244200020
+433E:1020102023FE20204820FBFE128A225242FAFA22422202FA1A22E222422A0204
+433F:100013FE200021FC4904F90411FC200043FEFA22422203FE1A22E22243FE0202
+4340:10901290229C22A04AD0FA88128820804000FBF842A802A81AA8E2A84FFE0000
+4341:10881448225020FC4820F850169422384250FA98423402541A90E22045FE0800
+4342:200020FC3C20502090201020FE2011FE10205420542054205C20642004A00040
+4343:000801FC7E0022081108111008001FF821000100FFFE0100210821083FF80008
+4344:202020203C205020903E1020FE20102011FC5504550455045D04650405FC0104
+4345:202020203C50505090881124FE12101011FC5404540854885C50642004100010
+4346:204020203C2051FE91021204FE00100011FE5420542054205C20642004A00040
+4347:2004201E3CE0500090101008FEFE100210045408541054205C4064A0051E0000
+4348:200021FC3C205020912410A4FEA8102013FE5420542054205C20642004200020
+4349:200020003CFC508490841084FE84108410FC5484540054485C44648404820102
+434A:204020203C2051FE90001088FF04120210885488545054505C20645004880306
+434B:2008203C3DE0502091FE10A8FEA810A811FE54A854A855FE5C20642005FC0000
+434C:204020203CFC500090881048FE5011FE1000540054FC54845C84648404FC0084
+434D:1000FE7810487C480048FE8682007CFC20443C445028FE28101054287C440182
+434E:408843FE7888A02023FE2250FBFE225223FEAA80AAFEAA80BAFECC020AAA0004
+434F:00003FF824482448244824483FF8200820082008200820082008200820282010
+4350:00007FFC444444447FFC00003FF8010001000100FFFE01000100010001000100
+4351:00003FF822282AA824482AA8312800003FF801000100FFFE0100010001000100
+4352:00007FFC444444447FFC010001007FFC03800540092011102108C10601000100
+4353:00007FFC444444447FFC00003FFC0040104020403FFE01400640184061400080
+4354:00007FFC444444447FFC020002007FFC0400048008801100222044108FF80408
+4355:00007FFC444444447FFC000000F03F00210021003FFC208020402A243114210C
+4356:00007FFC444444447FFC08001FF020105F90109010901F901050102410040FFC
+4357:00007FFC444444447FFC020001007FFC040008201FC0008003200C103FF80008
+4358:00007FFC444444447FFC01001110092005407FFC0540092011102108C1060100
+4359:00007FFC44447FFC10003FFC40009FF012101110FFFE221021103FFC00100060
+435A:00007FFC444444447FFC01001FF010101FF010101FF011081090126014181806
+435B:00007FFC444444447FFC00003FF821082FE8210827C8244827C820083FF82008
+435C:7FFC44447FFC090008801FFC108030805FF8908010801FF8108010801FFC1000
+435D:7FFC44447FFC000001047D9809603118C50602001FF010101FF010101FF01010
+435E:7FFC40044AA444444AA400500048FFFE00403E4022243E2800120E2A70C60302
+435F:7FFC44447FFC00002448238824483FF81010220847E40820144003801C70E00E
+4360:7FFC44447FFC01000080FFFE0440139014501FF001007FFC44444FE44424400C
+4361:00007FFC44447FFC00803FFE22203FFC22243FFC284028482F7048444B448C3C
+4362:00007FFC44447FFC10003FFC4AA00AA07FFC0AA00AA07FFC0000248822444244
+4363:7FFC44447FFC00003FF801007FFE41029D7400003FF821083FF821083FF82008
+4364:00007FFC44447FFC0100FFFE02887D7025484D6690101FF010101FF010102010
+4365:00007FFC44447FFC00007FFE40005F3C44107F7E4E345552609044F84480BFFE
+4366:7FFC44447FFC100008287F24147E494855C87F7E08487F7E514855485D7E4340
+4367:10881048505050007DFC5020902010FC1C20F02051FE10201020102010201020
+4368:442024202820FDFE102010207DFC11241124FD24112411342128202040208020
+4369:444024402840FE8010FE11087E8810881088FE50105010202050208841048202
+436A:442024202820FDFE102010207C2011FC1070FCA810A811242124222240208020
+436B:442024102810FDFE110212047C8010881090FCA010C0108220822082407E8000
+436C:440025FC2820FC20112410A47CA8102013FEFC20102010202020202040208020
+436D:440024FC2884FEA4109410847C8413FE1104FF441124110421FE200440288010
+436E:445024502850FD5210D410587C50105810D4FD5210501050209220924112820E
+436F:4440244028FCFD04120811FE7D00117C1144FD441154114821422242423E8400
+4370:440025FC2904FD24112411247DFC11241124FD54114C118C2104210441FC8104
+4371:442024202850FC88110412FA7C20102013FEFC20112811242222242240A08040
+4372:88004840539CFA042204239CFA04220423FCF89020902090209041124212840E
+4373:88004BDE5042F94A2084214AFA5224202000FBDE205221522094414842548422
+4374:881C49E05020F82023FE20A8F92422422040FBFE2088210820D0403040488184
+4375:4440244028F8FD08101011FC7C24102413FEFC24102411FC2024202040A08040
+4376:442024202BFEFC2011FC11247DFC112411FCFC20107010A82124262240208020
+4377:4440244029FCFC8413FE10007DFC110411FCFC2013FE1020222023FE40208020
+4378:442824242BFEFC2011FC11247DFC112411FCFD24100813FE2088204840488018
+4379:4420244029FCFD0411FC11047DFC110411FCFC28102413FE2050208841048602
+437A:8820482051FCF92421FC2020FBFE222223FEF8202040202422A2428A44788000
+437B:88004BDE5252FBDE22102252F9CE20002088FBFE2088208823FE408841048202
+437C:88004BDE5088FAA823FE2188FADA24A621F8F908210821F82108410841F88108
+437D:88004BFE5222FACC224423EEFA4422EE2354FA4422102290229E449044908BFE
+437E:00007EEE2422242224AA24662422FF222426246A24B224222422242244AA8444
+437F:00007EFC224412241A3462C4020400007FFC010001003FF801000100FFFE0000
+4380:0014EE1222122210AAFE66902292229226926A94B29422B422CA228AAA164422
+4381:100011DC10441044FF5410CC104410447C4C44D44564444444447C4445540088
+4382:0040EE4022FC2284AB0466F42294229426F46A84B294228822822282AA7E4400
+4383:100011DC10447C44555454CC7C445444544C54D4FF6444444444444455544888
+4384:0000FDDC24442444255424CC54444844804C7CD445644444444444447D544488
+4385:100011DC20447C44455444CC444444447C4C44D44564444444447C4445540088
+4386:00007EFC224412241A3462C4030402800C603218C1061FE00020064001800040
+4387:100021DC7C444444655454CC5444FC44444C64D4556454444444444455548888
+4388:0020EE2022FC22A4AAA466FC22A422A426FC6A20B22422182212226AAB864402
+4389:000CEE0A220822FEAA8866882288228A26EA6A8AB28C228C228A228AAA964522
+438A:100010EE1E22222262AA9466082214222226416ABEB22222222222223EAA2244
+438B:080028EE28223E2248AA0866FF22002200263E6A22B2222222223E2222AA0044
+438C:0000EE7C22442244AA446644227C221026106A50B25E225022502270AA9E4500
+438D:0028EC2425FE2420B4206DFC2524252425FC6D24B52425FC25242524B524490C
+438E:0000EDFE24A024A8B4A86CE824A824A824A86CE8B4A824AA24BA25EAB4264820
+438F:080008EE1422222251AA88667E2202220426086A7EB2422242227E2242AA0044
+4390:100011DCFE4410447D5444CC7C4444447C4C54D41164FE441044104411541088
+4391:0000EEFC22042204AA7C6604220422FE26106A92B254223822542292AA504420
+4392:0048EE44225E23E0AA286612226A239626486A5EB3E0222422282212AA6A4586
+4393:0010EE1022DA2254AA5466922350222026FE6A82B28222FE22822282AAFE4482
+4394:0028EC2427FE2420B5FC6D2425FC252425FC6D24B40827FE24882448B4484818
+4395:08202AA44D28145022887FFE400280043EF8020812480A28124822880A280410
+4396:440024EE2822FE2292AAD666BA229222FE26006A7CB244227C2244227CAA4444
+4397:060078EE1022FFA222AA5D6694A21C2200267F6A41B25D2255225D2241AA4344
+4398:08007F7E0912FF92095A7F360812AA92EB9688BAFFD28892EB92AA92AA9208B6
+4399:200011DCFE4482447D5454CC98447C44C44C7CD445647C4444447C4429544488
+439A:0088EDDC248825DCB4886DDC248825FC24046CFCB40425FC24202554B54A4A3A
+439B:020002083FD00220FFFE02000C703F84C80407FC00001FF0101010101FF01010
+439C:101012107E12147E1414FE1408FE100820307E22A06422B82D223022201E0000
+439D:02203FC00280FFFE02200FC03408C3F800007EFC224412240A1412246AD40408
+439E:010001081FD001207FFC02000FF03810CFF008100FF000003FF8000800080008
+439F:100013FE10201020FC4025FC2554255425544954295411542954454481140108
+43A0:200023FE20202040FDFC25542554A5546554255435442D16250A440243FE8000
+43A1:0000FFFE020004003FF82488248824A82010010011101120228004401830E00E
+43A2:104010401080FCFE11007A0010FCFC0810103820344054809102110210FE1000
+43A3:100810481128FD28112879081108FD0811083908354855949114102210421082
+43A4:100011FC1104FD0411FC79001100FDFE1102397A354A554A927A120214141008
+43A5:100010501048FC84112478201050FC8811063AF8348854889088108810F81088
+43A6:102010A410A4FD28105078881104FC24102038A834A855309050108811041202
+43A7:1040102010FCFC00108878481050FDFE1000380034FC54849084108410FC1084
+43A8:1020102013FEFC50108879241222FDFC112439FC352455FC90221022101E1000
+43A9:109210921124FE48112478921092FC0011FE3922352255FE9122112211FE1102
+43AA:100011FC1104FDFC110479FC1000FDFE10083BFE340855089088100810281010
+43AB:105011241154FD0411FC78501088FD4410783888348855509020105010881106
+43AC:100013FE1252FE5213FE78201020FDFC1020382037FE54409088110413FE1102
+43AD:101010501250FD7C1090781010FEFF00117C39443544517C5144910012FE1400
+43AE:1040102011FCFC88105079FC1104FD2411FC392435745554915411741104110C
+43AF:1088108813FEFC8810F8782011FCFD2411FC382035FC542093FE105010881306
+43B0:1142115C13F0FD501150795E13F4FC1411D43954355455D49154115411E41004
+43B1:200023FC2294FA9423FC71102252FBDC201273CE6A40A3D2225C23D0225222CE
+43B2:0000FF0024FC24043C08241024203C20244024402E80F48244820482047E0400
+43B3:0000FF7C244424443C44247C24443C442444247C2E44F4444444048404940508
+43B4:0048FF48244824483CFC244824483C4825FE24482E48F4484448048804880508
+43B5:0040FF20242824083C08244824543D52255225602E60F44444C40544063C0400
+43B6:0020FC20482049FC79244924492479FC492449244D2479FCC924082008200820
+43B7:0020FD20492049FC79204A2048207BFE487048A84CA87924C9240A2208200820
+43B8:0000FDFE4820482078FC4844484479FE480048004CFC7884C884088408FC0884
+43B9:00F83F0011100920FFFE09203118C1063FF808200FE008200FE0083EFFE00020
+43BA:0082FC824A824BEA7C8A488A4FFA788A4BEA4AAA4EAA7AAACAA20AE2088A0884
+43BB:0000FDFC492449247974492449FC7904497449544D547974C9040A040A140C08
+43BC:0000FDF84808480879F8480848087BFE48204A224D7478A8C9240A2208A00840
+43BD:001CFDE04920492079FE4910494A7986480249FC4D047904C9FC0904090409FC
+43BE:0020FC204850488879044AFA480079FC495449544DFC7954C95409540904090C
+43BF:0008FCC84B084908792A492A4BAC794849084B884D547914C914092409240942
+43C0:0082FC824BE24882788A4BEA4AAA7AAA4BEA488A4DCA7AAACCA20882088A0884
+43C1:0040FC204BFE4A42782049FC488878504BFE48204C2079FCC820082008200820
+43C2:00A0FD2C4924492479AC4924492479FC482049FC4C887850C820085008880B06
+43C3:0000FDFE4902480078FC488448FC788448FC48204C1079FEC800084808840902
+43C4:0040FC204BFE4A8A79044BFE4840788849FC48244C2079FCC82008200BFE0800
+43C5:0080FC8849EE492A7AAA49444884797A4A0048004DFE7820C8A809240AA20840
+43C6:0050FC504BFE48507BFE4A524BFE7A524BFE48004DFC7904C9FC090409FC0904
+43C7:0000FDFC485049FC7954495449FC780049FC48004FFE7820C8A809240AA20840
+43C8:0108F9085254525474BC57085110722454BE578A580870ACD56A154A14281010
+43C9:0000FDFC490449FC790449FC4888795449DC48884D5479DCC80009A809540A54
+43CA:0110FC904BDE48107A5E49824BDE78104BDE4A504FDE7A50CBDE0A500A520ACE
+43CB:01003FF80108FFFE01083FF8054009203118C10625781348A178A5441D3C0100
+43CC:084008201010200840069FF0101010101FF0101010101FF01010101010501020
+43CD:02000400082010103FF8100800001FF010101FF010101FF01010101010501020
+43CE:00003C0024F0249024903C90249024D024B03C902490249224924512550E8A00
+43CF:00003DFC2420242024203C2027FE242024203C20242024202420442054A08840
+43D0:00203C20242025FC24243C242424242427FE3C20245024502488448855048A02
+43D1:020004000FF81210692004C003000C0071003FF8228824482108228824482018
+43D2:00083C882488248824883CFE2480248024803CFC248424842484450455048A04
+43D3:00003CFC2400240034002DFE245024502C5034502450245224524492548E8900
+43D4:00003DF82448244824483C48244825F824883C88248824882488448857FE8800
+43D5:00083C3C25E0242024203C20242027FE24203C20242024202420442055FC8800
+43D6:00043DE42424242424243DE42504250425043DE4242424242424442455448884
+43D7:00803C8024FC250026003CF82400240025F83C0824082408240A440A54068802
+43D8:00003DFE2528252825283D2825282528252A3D2A254A25462580450055FE8800
+43D9:00203C20242025FE25223E242420242024503C50245024502490449255128A0E
+43DA:00203C20242024A824A43CA22522252026243C24242824082410442054C08B00
+43DB:00403C40248024FC25043E042484244424443C14242424442584440454288810
+43DC:00007BFC4884488848887890489C488449447944492849284A104A284C449982
+43DD:00203C20242025FC24203C4027FE244024803DFC240424882450442054108810
+43DE:00203C20242027FE24203C20242025FC24703CA824A825242524462254208820
+43DF:00403C202428240824083C482454255225523D602660244424C44544563C8800
+43E0:00407820482048004BFC780048084908490878904890489048A048204BFE9800
+43E1:00003CFC2400240024003DFE2420242024A83CA4252425222622442054A08840
+43E2:00103C10241024FE24923C94249024FC24A43CA424A824A82490452855448A82
+43E3:00003CF82488248824883CF82488248824883CF8248824882488448857FE8800
+43E4:00003DFC2404240425F43C04240425F425143D1425F425142404440454288810
+43E5:00203C20242025FC25243D2425FC252425243D2427FE25042504450455148908
+43E6:00083C3C25E0242024203FFE2420242024203DFC250425042504450455FC8904
+43E7:00203C20247C248425483C302420244825903C3E244225A42418441054608980
+43E8:00403C8025F8250825083D0825F8250025003D0025FC25042504450455FC8904
+43E9:00203C202450245024883D0426FA240024003CF8248824882488448854F88888
+43EA:00003DFE2488248824883CF82488248824F83C882488249E27E8440854088808
+43EB:009078904890491049FE7B104D10493849387954495449924910491049109910
+43EC:00203C202448248425FE3C122490249024FE3D10241025FE2410441054108810
+43ED:00207920492049FC49207A2048204BFE487078A848A8492449244A2248209820
+43EE:00403C4025FC244424443C842494250824003D02248424482400444854848902
+43EF:0020782048204BFE48207820482049FC4840782048A44A824A8A4A8A4C789800
+43F0:00007BFC4844494449447A84489449084A40782048A44A824A8A4A8A4C789800
+43F1:000079FC4904490449FC7900490049FE4902797A494A494A4A7A4A024C149808
+43F2:01083C88249025FC24243C2425FC252025203DFE246224A2252A462454208820
+43F3:0104790E493049204FE07920493E496449A47F24492449244924492449449B84
+43F4:00203D2424A424A824203DFC2504250425FC3D04250425FC2504450455148908
+43F5:0090788848804BFE48A078A848B048A448A878B04924492A49324A224ADE9C00
+43F6:01103D12251425D825103D122552258E25203C2025FC24202420442057FE8800
+43F7:00003DFC250425FC25043DFC2400240025FC3C20242027FE2420442054208820
+43F8:00007BFC4840484049F8788848884BFE4800780049F849084908490849F89908
+43F9:00003DFC2504250425FC3D04250425FC25043D0425FC24502490449255128A0E
+43FA:00403C4024FC248825503C2024D8272624F83C2024F8242027FE442054208820
+43FB:1020102020204420FEFC02207C20442045FE7C2044207C48448445FE54824800
+43FC:00483C44245E25E024283C12246A259624483C5E25E0242424284412546A8986
+43FD:00403C2025FC240025083C90240027FE24003C0025FC25042504450455FC8904
+43FE:00203C2025FE242024FC3C4025FE248825243E2224F8242025FE442054208820
+43FF:104008403E7E228823503E20205841869FF010101FF010101FF0101010501020
+4400:00203C2025FC245024883D0427FE240825E83D28252825E82528440854288810
+4401:00007BFE4840488049447A2448684AB049307AA8486848A449224A2048A09840
+4402:000079F84808480849F8780848084BFE48207A22497448A849244A2248A09840
+4403:00007BFE4A024A1A4AE27A224A224BFE4A227A724AAA4B264A224A224BFE9A02
+4404:00403C40247C248425083E00242025CE25023D0225CE25022502450255FE8902
+4405:00003DFC2504250425FC3D002540257C25903D1025FE25102528452855448A82
+4406:0008783C4BC048444A247928490048204BFE787048A848A849244A224C209820
+4407:00803C8024FC255426543C942524245424883C0025FC250425FC450455FC8904
+4408:004078404BFC4840484079F8490849F8490879F8490849F8490849084FFE9800
+4409:00923C922524264825243C922492240025FE3D22252225FE2522452255FE8902
+440A:00003DFC2504250425FC3D04250425FC24003D1225D42518251045525592890E
+440B:00907890490849484A447C9249084BFC4844782048A44A824A8A4A8A4C789800
+440C:044004403FF824483FF82448FFFE10102008DFF610101FF010101FF010101030
+440D:00203C2027FE242024203DFC2400240025FC3D04250425FC2400448854508BFE
+440E:000079FC4904490449FC7904490449FC48007BFE48204920493C49204AA09C7E
+440F:00203C2027FE242025FC3C4027FE248825043EFA2488248824F84488548888F8
+4410:008871C857085108512A712A57AC51485308738855545514591451245124B142
+4411:00483D48254827FE25483D482578250025FE3C2027FE247024A8452456228820
+4412:00003C4025FE248825043E4224F8270824903C7027BE244225A4441854608B80
+4413:00003DFE2410242024FC3C84248424FC24843CFC2484248424FC444854848902
+4414:00203C1025FE250225023DFE2500250025FE3DAA26AA24FE24AA44AA54AA8886
+4415:00003CF82488248824F83C0025FE248824F83C8824F82488249E47E854088808
+4416:00007BFC4A044A044BFC7A204B244AA84A207BFE4A704AA84AA84D244A229820
+4417:00203C2024FA242424283DFE2420244024FC3D442644247C24444444547C8844
+4418:001E7BE048444924488879FC484048404BFE788048FC494449284A1048689986
+4419:008878884BFE488848F8782049FC4924492479FC48204BFE4820482048209820
+441A:00007BDE4A524A524A527BD24A524A524A527BD24A1A4A944A504AB04B109810
+441B:00203C2025FE245024883D0427FE248824F83C8824F82488249E47E854088808
+441C:002078204BFE482049FC790449FC490449FC790449FC49044BFE488849049A02
+441D:00203D2424A8242025FC3D04250425FC25043DFC2504250425FC440054888904
+441E:00007BDE484248424BDE7A104A104BDE48427A52494A494A4A5248424A949908
+441F:008878884BFE488849FC78884BFE482049FC792449FC49244BFE490449149908
+4420:00883C8827FE24A824103FFE2480248024FC3C0024A824A824A844AA552A8A06
+4421:02000100FFFE02847D78255025484D6401003FF8228824482108228824482018
+4422:0080788049FC4A44495479F4488449284A9079FC4A444D5449F4488449289A10
+4423:00003CF82488248824F83C0025FC250425FC3D0425FC250425FC445054888904
+4424:00843C44244825FE24203CFC242025FE24403C8024FE25102610441055FE8800
+4425:0090788849044A424C8879FC480448004BDE78424A52494A4A524842494A9884
+4426:00203C2024FC242024203DFE2440248425FE3C0225FC25542554455457FE8800
+4427:004078204BFC480049F8790849F848004BFC7A044AF44A944AF44A044A149A08
+4428:1000FE7810487C480048FE8682007CFC00447C4444287C2844107C2844444D82
+4429:00203D242524252425FC3C0027FE240025FC3D04250425FC2488445057FE8800
+442A:00A0789049FE4B204DFC792049FC492049FE79004BFC4888489E49024A0A9C04
+442B:012479244A244C244954794A4A924E104A107A504A5C4A504A504AB04A9E9B00
+442C:009078904FFE48904BFC7A944BFC4A944BFC780049F8490849F8490849F89908
+442D:02A872A857FC52A852AA74E6580057FC5444704053F85248524852485258B040
+442E:004078204BFC4800490878904BFE4A204AA07AFC4B204A204AFC4A204C2099FE
+442F:00003DFC252425FC25243DFC2440248825F03C20244427FE2422452456228860
+4430:0120793C49444AA84A107EA84AC64ABC4AA47ABC4AA44ABC4A244A244A249A2C
+4431:004078204BFE488848507BFE4A224AFA4A227AFA4A8A4A8A4AFA4A024A0A9A04
+4432:00007BDE48424A52494A7A524842482049FC7904490449FC4904490449FC9904
+4433:00403C4024F8250826103DFC2524252425FC3D24252425FC24004554552A8A2A
+4434:7DFC44207D2045FE7C5048525492650E1FF010101FF010101FF0101010501020
+4435:00883C8825FC248824883FFE242025FC25243DFC252425FC2400448855048A02
+4436:00007BDE48884AA84BFE79884ADA4CA649F87908490849F84908490849F89908
+4437:00007BDE4A524A524BDE780049FC492449FC792449FC48204BFE482048209820
+4438:00203DFC242427FE24243DFC242027FE24003DFC252425FC252445FC54008BFE
+4439:002079FC48244BFE482479FC48204AAA4BAE7A224BFE4A224BAE4AAA4AAA9C22
+443A:00007BFE48504BFE4A527BFE480049FC490479FC490449FC48204BFE48209820
+443B:00207BFE482049FC490479FC482049FC488878504BFE482049FC482048209820
+443C:00807BDE488A49CA488A7BD248A64840488879F048244BFE482249244AA29840
+443D:008878884BFE4888488878F848204BFE4A227B324AAA4B764A224A224A2A9A24
+443E:00003DFC255425FC24203DFC242027FE24883C5025FC242027FE442054208820
+443F:004078804BFE4A224AAA7A224BFE4A724AAA7A0248204BFE4820485048889B06
+4440:00107BC84A7E4A404A627BD44A004A3E4BC87A484E7E4A484A484BC84A489808
+4441:3AB821083AB82288393822887FFE40029FF410101FF010101FF0101010501020
+4442:01407A4C4A644A444B4C7A644AA44BAC4AA47AA44FFE4800491049084A049C04
+4443:00883DFE248825FE35022CFC240025FE2C20345025AA245C25AA444855A88810
+4444:00403CF8248824F824883CF8240025FC25243DFC252425FC240047FE54888908
+4445:00887BFE488849FC4954795449FC48004BFE7A4248F848884948483048609B80
+4446:010878904BFC484049F878804BFC494849FC7B0A4DF8490849FA4934498C9902
+4447:00427B9C4A104BDE4A947A944C204BFC4A047BFC4A044BFC4A044BFC49089A04
+4448:012479744A584ADA4BFE79544ADA4BFE48A278204BFE487048A849244A229820
+4449:E040BFFEA400A7FCA000E7FCA404A7FCA040EE4EABEAAEAAAAAEAE4A2AAA7710
+444A:0010787C4A54497C491078FE48444B7C4944797C4944497C492849444A809C7E
+444B:00207BFE480049DC495479DC48884BFE48887BFE48884BFE489449884AA498C2
+444C:03DE7A524BDE4A524BDE7A224AFA4A224AFA7AAA4AFA4AAA4AFA4A724AAA9A26
+444D:03DE7A524BDE4A524BDE7A524BDE498C4A5278404FFE48884990486048D89B04
+444E:0148794C4AAA48084FFE79484B68494A4B6A794C4B6C4948496A4B9A48269842
+444F:00887BFE48884BDE4A527BDE48A0489049FE79204BFC4D2049FC492049FE9900
+4450:00407E40484048FE48807E804310421042587E5448944892491248107E500020
+4451:00287EAA486C482848FE7E44422842FE42107E7C481048FE481048287E440082
+4452:0000FE0011FC2024282444A4FEA412A4112410247C24104410441E84F1144208
+4453:08207FFC08200FE008200FE008207FFE4002BFFC08201FF001001FF001007FFC
+4454:0020402098208BFE8820882089FCD9248924892489248934F928882000200020
+4455:060038F820083EF820083FF800003FF821083FF821083FF8210A410A41068102
+4456:002040209BFE882089FC88248BFED82489FC88208920893EF9208AA0027E0400
+4457:000041F8990889F8890889F88800DBFE890089FC8A548C94F9248A4400A80110
+4458:0108408898908BFC884089F88840DBFE8880890089FC8A20FC20882003FE0000
+4459:08001CFC708410841084FDFE108410847C8445FE4484448444847C8444940088
+445A:08001CFC708410841084FCFC108410847C8444FC4484448444847C8445140208
+445B:08041C1E71F011101110FD10111011FE7D10451045104508450A7D4A45A60112
+445C:08481D48714813FE1148FD48117811007DFE442047FE447044A87D2446220020
+445D:00003EF8228822883EF80000FFFE902210203DF84420A520192011FC20204020
+445E:3FFC24902960261038882290256022102C083FFC10103EFC4210149018FEE010
+445F:0F10F020117C8944427C0044FF7C810042FE771092105A7C2F10221042FE8200
+4460:080011FC3E04220832102A202A20FE20222032202A202A20222042204AA08440
+4461:100021F87C8844C864A854A85488FC5044506450542054204450448855048A02
+4462:100020007DFC4490649054905490FC90449064905490549244924492550E8A00
+4463:080410043F082110292025442504FF08211029222542250421084110452082C0
+4464:082010203E50225032882B442A22FE20220033FC2A042A08220842104A108420
+4465:080010FC3E44224832482A502A5CFE44224432442A682AA8229042984B248442
+4466:084010403E8022FC33042A042AF4FE94229432942AF42A94220442044A288410
+4467:1088208878884908697E5B084D08F94849284928690859084908490849289910
+4468:108020807CFE450066205520552CFD7447A46524553455284522450254FE8800
+4469:081010103E10221032FE2A102A10FE10227C32442A442A44224442444A7C8444
+446A:082010203E50225032882B042AFAFE00220032F82A882A88228842884AF88488
+446B:088410483E0022FC32482A482A48FE4823FE32482A482A48224842884A888508
+446C:085010503E50235232D42A582A50FE5822D433522A502A50229242924B12860E
+446D:100021007CBE4488640856085508FD484448648857885488448844FE54808800
+446E:100020F87C884488648854885526FE2045FE6420547054A84524462254208820
+446F:110820887C9045FC6424542455FCFD20452065FE546254A2452A462454208820
+4470:081010103E90229E32902A902BFEFE00221032922A922B14220442084A3085C0
+4471:104020207BFE4A026D04590049DEFA524A524B526C9A5894491049124A129C0E
+4472:082010203E3E222032FC2A842AFCFE8422FC32A42A202BFE222042204A208420
+4473:102020207C504488650456FA5400FDFC4554655455FC5554455445545504890C
+4474:084410443EFE224432442A7C2A44FE44227C32442A442AFE220042284A448482
+4475:100021FE7D02457A6502557A5400FCFC448464FC548454FC4484448454948888
+4476:081010103EFE2210327C2A102AFEFE00227C32442A7C2A44227C42444A548448
+4477:102020107DFE4502650255FE5500FD7E4542657E5542557E45424542554A8A44
+4478:082010103EFE228232002A7C2A00FE0022FE32102A102A54225242924A508420
+4479:104020207BFE4A2268A459284850F888490448F8688858884850482048D89B06
+447A:100023FC7A044A346BC45A444BF4FB544B544BF46A445A544BF44A944C069802
+447B:1108208878884BDE6910592049DEF94249444944695E59444A444A444CD49808
+447C:104020407CFE452264AA54FA5442FC94454864FE552256AA44FA444254948908
+447D:100021FC790449FC690459FC4800FBDE48424A52694A58C64B5A4842494A9884
+447E:10A0209079FE4B2069FC592049FCF92049FE49006BF859084890486049989E06
+447F:102020107BFE4A02688058FE4910FB204D7C49446944597C49444944497C9944
+4480:1110211079DE4AA86C4458884888F9084B7E4D08694859284908490849289910
+4481:100023DE78424A52694A5A524842F82049FC4904690459FC4904490449FC9904
+4482:109022907A9E4AA26AD45BA84894F8A44FFE4A846AA45A944A944A844C949888
+4483:101020507A50497C6890581048FEFB00497C49446944597C494449004AFE9C00
+4484:100020007BFE4A0269FC580048F8F88848F8480069FC592449FC492449FC9904
+4485:102021247CA845FC644057FE5488FD0447FE650455FC550445FC450455FC8904
+4486:110820887BE849106A9E5FD44864FBD44A544BD46A545BC84A484A544A649AC2
+4487:104020207BFE4A0269FC580048F8F88848F8480069FC592449FC492449FC9904
+4488:102021FC7C20448867FE548855FCFD0445FC650455FC550445FC448855048A02
+4489:108021007BFE4D5469545BFE4954F9544BFE490469DE5A444954489E49049A04
+448A:0440244022FC2288431040FCBEA410A420A43EFC0280028002820282147E0800
+448B:1040104010FC7C88551054FC54A454A454A4FEFC1080108028822482447E8000
+448C:0020FF20817C00447E88427C7E5442547E54107C0840FF4000422442423E8100
+448D:20401040FEFC0088451028FCFEA4A2A410A4FEFC20803C8024824482547E8800
+448E:24202420FF7C24441288FE7C245442548154247C2440FF4024422442443E8400
+448F:4440244028FCFE889310D6FCBAA492A4FEA400FC7C8044807C8244827C7E4400
+4490:2220FFA0227C7F4455887F7C0054FFD480D43E7C22403E4022423E42223E3E00
+4491:00000000000000001010081008200000FFFE0000000000000000000000000000
+4492:08200820FFFE0820082000003FF8000800480188060818086008000800500020
+4493:08200820FFFE082008200000FFFE0400040008001FF000100010001000A00040
+4494:08200820FFFE0820082000400440044004200820082010101010200840048002
+4495:08200820FFFE0820092001000100010011101108210421044102810205000200
+4496:08200820FFFE0820082000007FF0041004100410FFD00412040A040604020400
+4497:04400440FFFE0440080008001FFC200040009FE0002000C003000C0410040FFC
+4498:08200820FFFE08200820040004000FF01010282044400280010006C01830E00E
+4499:08200820FFFE08200820010001000100010001F80100010001000100FFFE0000
+449A:08200820FFFE082008200100010011101108210421144120004001800E00F000
+449B:08200820FFFE0820100010FC22044204FC040804100422044104FF0441280010
+449C:08200820FFFE08200920110011001FF8210041000100FFFE0100010001000100
+449D:08200820FFFE08200008181006600180066018186C240240018006601818E006
+449E:08200820FFFE0820092001003FFC2104410802800280048008821082207E4000
+449F:08200820FFFE082000001FF01010121011101010FFFE10102010201040508020
+44A0:08200820FFFE0820092001007FFC010001003FF801000100FFFE010001000100
+44A1:08200820FFFE082000007F08010801083F08200840087F08010801080A080408
+44A2:08200820FFFE0820082000000C0070FC4084408440844C847094408800800080
+44A3:08200820FFFE082000001FF0101010107FFC101010107FFC1010101010501020
+44A4:08200820FFFE0820082000003FF82008200820083FF82008200820083FF82008
+44A5:08200820FFFE082000007FFC010001003FF82108210821082128211001000100
+44A6:08200820FFFE082001F03E00020001007FF8006001800E003000480087FE0000
+44A7:08200820FFFE0820092001003FF8010001000100FFFE0400082010103FF81008
+44A8:04400440FFFE0440080008001FF8210041000100FFFE0280044008203018C006
+44A9:08200820FFFE0820000000F01F00010001007FFC054009203118C10601000100
+44AA:0820FFFE08200400082010103FF8000808200820FFFE08200820102020204020
+44AB:08200820FFFE08200000085008481040307C57C09040102010201014100C1004
+44AC:08200820FFFE0820082000003FF800000000FFFE010011102108410485020200
+44AD:08200820FFFE082000001FF0001000107FFC00000020FFFE0820042004A00040
+44AE:08200820FFFE082000007FFE400280040FE008200A20092009221022201E4000
+44AF:08200820FFFE082000007FFE420282041FE002200C2004200A2011222022401E
+44B0:04400440FFFE044000003FFE20002FFC2080208027F8208020802FFC20003FFE
+44B1:04400440FFFE04403FF0002000C07D040588095011202118C5060200FFFE0000
+44B2:04400440FFFE04401008101CFEE0122022202220643E15E0082214222222C01E
+44B3:08200820FFFE082000000FE008201020611C0100FFFE054009203118C1060100
+44B4:08200820FFFE0820040004007FFC08001FF028104FF088100FF0081008500820
+44B5:08200820FFFE0820100011F8FC082410242025FE442024201820182024A0C240
+44B6:08200820FFFE0820092001003FF821083FF821083FF8010800B001C20E32700E
+44B7:08200820FFFE082000F01F0001000100FFFE010001001FF0101010101FF01010
+44B8:08200820FFFE0820092002003FF82448244824482448244824482448FFFE0000
+44B9:08200820FFFE0820092001007FFC01003FF80100FFFE054009203118C1060100
+44BA:08200820FFFE0A20040008201FC0008003200C103FF801081110210845040200
+44BB:04400440FFFE04400800087C080449044904497C494049404F427942003E0000
+44BC:08200820FFFE0820044004403FF82448244824483FF82448244824483FF82008
+44BD:08200820FFFE082000003FF820082AA82AA8244824482AA82AA8200820282010
+44BE:08200820FFFE08200A200100FFFE02000500090418882850C8200A180C060800
+44BF:08200820FFFE08207FFE40029FF4101010101FF0101010101FF0101010501020
+44C0:08200820FFFE0820092001007FFC010001001FF000001FF0101010101FF01010
+44C1:08200820FFFE082001003FF801000100FFFE000000207FFC0820042004A00040
+44C2:08200820FFFE08200A200100FFFE00003FF800003FF800003FF820083FF82008
+44C3:04400440FFFE04401FF010101FF000003FF8210821083FF8200220021FFE0000
+44C4:08200820FFFE08204400280C11F02900C90019FE2910491089100A1052102410
+44C5:08200820FFFE08200820200C11F01100810049FE49101110E110221022102410
+44C6:04400440FFFE04401000100C11F0FD00110011FE1D10F1101110121052102410
+44C7:08200820FFFE082001003FF801000100FFFE0440244844448842084011402080
+44C8:04400440FFFE0440100010F8208841088A06100031F850889050102010D81706
+44C9:08200820FFFE082000007E7C2444244844507F48144424444454844814400840
+44CA:0820FFFE082000007FFC020002003FF004100810FFFE00001FF0101010101FF0
+44CB:08200820FFFE08202008103C13E082204A204BFE1220E2102212228A23062202
+44CC:08200820FFFE0820092001007FFC010001003FF80000010008844892481287F0
+44CD:04400440FFFE04401FF010101FF010101FF000003FF80100FFFE010001000100
+44CE:04400440FFFE04401080108014FC55045A045084904410442804240444288010
+44CF:08200820FFFE082000007FFC010003000D603118C1041FF0101010101FF01010
+44D0:0820FFFE082001007FFC044008203118C1063FF80100111011141FF4010400FC
+44D1:08200820FFFE0820200017FC91104110411017FE2110E1102210221024100810
+44D2:04400440FFFE044010001FF820085FC8924812481FC8124812481FC800280010
+44D3:0820FFFE0A2002007FFC02003FF80400FFFE08201FFC20204420822002A00040
+44D4:08200820FFFE082001081FD00120FFFE01001FF0082030C0CFFC008002800100
+44D5:08200820FFFE082023F01000100007FC7120112012241224141C280047FE0000
+44D6:08200820FFFE0A2001007FFE40028824121022081FF004100410081010A02040
+44D7:08200820FFFE08200440082011102208C44608201FF0011008844892481287F0
+44D8:0820FFFE0820000008401F6022505448084037FEC0001FF0101010101FF01010
+44D9:0820FFFE082000701F800100FFFE010009207924092809321922E91E01000100
+44DA:04400440FFFE0440100021F84108890811F83108510891F81108110817FE1000
+44DB:08200820FFFE082000003FF820083FF820802490249027F02080488848888FF8
+44DC:08200820FFFE08202008103C13E082204A204BFE1220E2102212228A23262212
+44DD:0820FFFE082000001FE0004001807FFC0100050002003FF824482448FFFE0000
+44DE:08200820FFFE092000803FFC200420043FFC20A020902FFC2120421044089806
+44DF:08200820FFFE082000003FF8210827C821082FE8200827C8244847C840288010
+44E0:08200820FFFE082001047D9809603118C50602001FF010101FF010101FF01010
+44E1:08200820FFFE0820282020003E7C484488440844FF4408441444227C41448000
+44E2:08200820FFFE082000003FF8210821082FE8210827C8244827C820083FF82008
+44E3:08200820FFFE0820FFFE010001007FFC41045144492455546594410441144108
+44E4:04400440FFFE044008001FF822484448088811082228041001004884481287F2
+44E5:0600010006C01830E44E3FF804401FF010101FF010101FF001007FFC01000100
+44E6:08200820FFFE0820044004403FF8244824483FF824482448FFFE082010102008
+44E7:0440FFFE044000003FF0002000C0793C4904496849107928014405000200FFFE
+44E8:08200820FFFE08207FFE400288041FF821000100FFFE0100210821083FF80008
+44E9:04400440FFFE04401020102011FEFC20102031FC388454885050902010D81306
+44EA:08200820FFFE08201FF010101FF010101FF008001FF822484488090812282410
+44EB:08200820FFFE092001003FF804400820FFFE00101F9010901F90001000500020
+44EC:08200820FFFE0820010001FC01003FF820083FF820083FF80100FFFE01000100
+44ED:08200820FFFE0820010432040C243224C9240824FFA408242A244904A8941008
+44EE:08200820FFFE08203E400240147E0888FF480A48185028504820085028881104
+44EF:0820FFFE09203FF801001FF001007FFC00001FF01210FFFE20903FFC00100060
+44F0:0820FFFE082000007FFC04403FF8244824483FF8010001003FF801000100FFFE
+44F1:0820FFFE08200440274C247024422F42F03E01007FFC054009203118C1060100
+44F2:04400440FFFE044009080890100013FC3204520493FC1090109011121212140E
+44F3:04400440FFFE0440000009F8110821F8450809F8192429284910094809860900
+44F4:0820FFFE08200000FFFE02003FF8248824A821100100FFFE028004401830E00E
+44F5:08200820FFFE082000001FF0101010101FF000007EFC4284428442847EFC4284
+44F6:04400440FFFE044008080808FF8808487F4849487F481C482A48490888280810
+44F7:08200820FFFE08A02100123C94804100437E15082108E1082108210821282110
+44F8:04400440FFFE044008007EF812202420182065FC08207E201220242018206420
+44F9:08200820FFFE092002800E603118DFE610201FE010201FE01008119014601810
+44FA:0820FFFE0820101008207FFC01003FF80100FFFE01007FFC028004401830E00E
+44FB:08200820FFFE08207FFE4002BE24002001FC7E4814C81430146A2586240243FE
+44FC:0820FFFE08201088108413FEFCA424A824B424A848B228A410AA2932452282DE
+44FD:04400440FFFE0440200010FCFE0400047C0400FC7C8000807C8044827C82447E
+44FE:08200820FFFE082020401248444420140860738020000400FFFE082007C07838
+44FF:0820FFFE082000003FE0044002807FFC444442845FF441047FFC410441047FFC
+4500:0440FFFE0440103813C0204027FC6150A248244620802FFE2110232020E02718
+4501:08200820FFFE082000007FFC04403FF824483FF801007FFC05401930E10E0100
+4502:0820FFFE0A2001007FFE420281043FF808200440FFFE01003FF8010001000100
+4503:08200820FFFE0820200011F8FD08090811F83908550895F81108110817FE1000
+4504:0820FFFE082000FC7F002208111020203FF841000100FFFE0100210821083FF8
+4505:0820FFFE082000007FFC00201F2011201F200000FFFC00201F2011201F200060
+4506:08200820FFFE0820440029FC112429FC492499FC282049FC8820082053FE2000
+4507:0820FFFE08200100210821083FF800007FFC00001FF010101FF008200440FFFE
+4508:0440FFFE04403FF801007FFC00001FF010101FF010101FF010101FF008201010
+4509:08200820FFFE08200C1C71E010201020FDFE307038A854A85124922210201020
+450A:08200820FFFE08200108FC9011FC109010907C9013FE10901C90F11041100210
+450B:04400440FFFE04401020102024207CA808A4112225227E280010542054C08300
+450C:0820FFFE082002001FF010101FF010101FF002007FFC08203118CFE601000100
+450D:08200820FFFE082000001FF811001FF011001FF011001FFC0004292444940008
+450E:08200820FFFE0820204017FC104003F87248124813F8115012481444284047FE
+450F:0820FFFE08200040224013F81440004077FC100013F8120813F8280047FE0000
+4510:04400440FFFE04402120111017FC80904064539C11202110E7FC20902064239C
+4511:04400440FFFE04400808144822285D0888C808287F0E08F82A084908A8881008
+4512:08200820FFFE0820008078404BFC5108609057FE480049F86908510841F84108
+4513:0820FFFE082020001040FE4000FE7C9001107C1001FE7C10441044107C104410
+4514:0820FFFE082001003FF80440FFFE00001FF010101FF010101FF004421842E03E
+4515:04400440FFFE0440002878244BFE482079FC492449FC792449FC49244924990C
+4516:0820FFFE0820000078404BF8504067FC51104A884CF4691052A0404041B04E0E
+4517:08200820FFFE082020881050FBFE0820102039FC5420942013FE102010201020
+4518:04400440FFFE0440200020F83C88508810F8FC88108854F854885C8875FE0400
+4519:08200820FFFE08201080288044FCB90412047C841044944450041E04E0284010
+451A:0820FFFE08203FFC20002FF820003FFC24482630240E2FF848084FF888080818
+451B:08200820FFFE082023FC204021F821083DF8210821F8250829F8300020900108
+451C:04400440FFFE04400020FC2049FC7924492479FC49244D24FBFE090409140908
+451D:0440FFFE044008442F7828422F3EF40008201FC003100C083FFC010415102208
+451E:0820FFFE0A2001007FFC020044442F88111022484FE400200100FFFE01000100
+451F:0440FFFE044000200C4070FC13081090FC6030903B3E544255A4901810601380
+4520:04400440FFFE044010201124FCA8102031FC390455FC910411FC110411141108
+4521:04400440FFFE044008001FE020207FF8A1083FF821083FF80000248822444244
+4522:0820FFFE0820145022880820145022881FF00000FFFE10001FF8000800500020
+4523:0820FFFE082003043C2404247FA416242504440C11001FF82100FFFE01000100
+4524:08200820FFFE0820000013FE20207C4045FC450445047DFC450445047DFC4504
+4525:0820FFFE082001003FF00110FFFC01103FF0092025482FE82388254829284108
+4526:04400440FFFE0440110011FC1200FDF83148392857FE5148922813FC10501020
+4527:0820FFFE082003043C2404247FA416242504440C01007FFC05401930E10E0100
+4528:0820FFFE08201050104824FE45907A9010FC2490449078FC0890109020FEC080
+4529:04400440FFFE044008200820FFBE08447FA449247F281C282A10492888440882
+452A:0820FFFE082001007FFC01002928111029280100292811102AA804401830E00E
+452B:04400440FFFE044000207C2007FE182051FC5D24512C50705CA87124C2220020
+452C:0820FFFE082000003FF821083FF821083FF804403FF80440FFFE082010102008
+452D:0820FFFE09207FFC41041490142823E800003FF821083FF821083FF821082118
+452E:08200820FFFE0820220C2270FF4022403E40227E3E482248FF48224841488088
+452F:0820FFFE082000107F10141014FE7F105510557C574461447F4441447F7C4144
+4530:0820FFFE09207FFC40043FF800001FF010101FF000003FF821083FF821083FF8
+4531:08200820FFFE082011F81108FDF8100013FC11081DF8F10811F8110E57F82008
+4532:08200820FFFE082000907EA00444282817D02008DFF610101FF0082004407FFC
+4533:04400440FFFE044010281E2432FE4A20A450185010882106C000248822444244
+4534:0440FFFE044008002A003E7C49447F4400443E2800287F1008102A2849441882
+4535:0820FFFE082000007C7C44447C7C44447D7C41045FF44384454449245124410C
+4536:0820FFFE0820000011FC1104FDFC110415FC180037FED020113C112052A0247E
+4537:0820FFFE08200000FEFE10107C7C1010FEFE010006C01A30E10E1FE000400080
+4538:0440FFFE04400120FFFE02800C603018C00610281424FEFE1020285044888106
+4539:0820FFFE0820010878904BFC48805144566848B049284E6868A4512246A04040
+453A:0440FFFE04407BFC488049F8522055FC480049F8490869F8510841F841084118
+453B:0820FFFE08201040FE4000807CFE45087E8800887C500850FE20105050882306
+453C:0820FFFE082000007EFC122452A49324264C409008502E5C28502E50F1FE0000
+453D:0820FFFE082023F8120813F8820843F8510013FC2444EAA4220423F420142008
+453E:0820FFFE082023F8220823F8FA0823F8290033FC6444AAA4220423F4A0144008
+453F:0820FFFE08200440FFFE04403FF82848303827C820083FF80020FFFE08200460
+4540:04400440FFFE044008207F20083E3E4200943E1000107F1008282A2849441882
+4541:0820FFFE082004407C7C04403C7804407C7C05400100FFFE05401930E10E0100
+4542:0820FFFE082000802110120817FC000473F8120813F810C411A812902C8847FE
+4543:0820FFFE0820004078A049104BF8550651F0490049F049006FFC5100421043F8
+4544:0820FFFE082000001FC000447D88055009203518C2061FF000003FF82448FFFE
+4545:0820FFFE08200080112C1124FDAC252425FC482029F810882850442080D80306
+4546:0440FFFE044020A021102208F5F62000678474A4AFA4A4A427A4248424942588
+4547:0820FFFE092000803FFC208021002FF828882FF829082FF84254445C9842603E
+4548:0820FFFE0820004809484BFE49487978090009FEF8204BFE487048A88B260820
+4549:0820FFFE08203FF824483FF801003FF80100FFFE04403FF80100FFFE01000100
+454A:0820FFFE0920FFFE00003FF8200827C824483FF810101FF010101FF00000FFFE
+454B:0820FFFE08201040102013FE12207EFC122413FE12241EFCE22004FC048408FC
+454C:0820FFFE082000000CA0709011FE1120FB2031FC392055FC5120912011FE1100
+454D:0820FFFE0A200100FFFE04881A70EC1808063FF824482FE8345827C820282010
+454E:08200820FFFE082001FC7C0044F844887CF8440045FC7D2445FC45247DFC4504
+454F:0440FFFE0440101008203FF801007FFC02403C500848FFFE08507E240854198C
+4550:08200820FFFE082021FC1000FCF8088810F8380055FC952411FC112411FC1104
+4551:0440FFFE0440001C11E0104425247C880820102025FC7C4800C8543054688184
+4552:0820FFFE0920FFFE01003FF800001FF010101FF00820FFFE10007EF8228846F8
+4553:0820FFFE0A2001007FFE50829EFC22885450282017D82006DFF0010011102308
+4554:0820FFFE08202100411C828014402BBE7108A7C821082948250821C82E282410
+4555:0820FFFE082011F8090809F8410823FC2A940BFC100073F81090106011981606
+4556:0820FFFE0820400C2F70211002240278E3122E7E221022542A92243050008FFE
+4557:0820FFFE0A201FF010101FF010101FF000003FF821083FF82108FFFE08201020
+4558:0440FFFE0440100013FC284045F8930809F8FD0805F8090851F8200010900108
+4559:0440FFFE044008207F280824FFFE12203FA46424BFA824183F92242A3FC62082
+455A:0820FFFE08203FFC208027F0249027F020803FFC241027F0241027F022203FFC
+455B:0440FFFE044020201020FDFC002078A800A878A801747A224850488879044A02
+455C:0820FFFE08207CF824481428244801007FFC0820145022880100FFFE01000100
+455D:0820FFFE0820001E0DE07044112410A8FDFC312439FC552453FE910411141108
+455E:0820FFFE08207C7C44447C7C44447D7C47C4444447C4444447D444A44544462C
+455F:0820FFFE082000002FEC48244BA4682C4BA46AAC4BA44824FFFE101020084004
+4560:0820FFFE082000803FFE20202F2831102A0A277C294A378428784F484130874C
+4561:0820FFFE08207C7C44447C7C44447C7C47C4444447C440044FE448244FE4400C
+4562:08200820FFFE082000887C5013FE102021FC3C4067FEA480257C26103C1025FE
+4563:0820FFFE082023F8120803F8FA080BF811002BFC7444AAA42A0423F420142008
+4564:0820FFFE08207700557C774400487F5049487F4449447F540848FFC008400840
+4565:0440FFFE0440111025484924BFFA210835582928355821083558292835582118
+4566:0820FFFE082001007FFC10001FF808200FE079384FA87AA84AB8792A4AAA9C46
+4567:0440FFFE04403E2022103AFE2A007F2841443E8222283E2822103E2822442682
+4568:0440FFFE044001243CA825FC24403DFE248825443E8A24F0242445FC54A88964
+4569:0440FFFE04401000102013FE7850128A31FC3A8A54F8508890F8112412221060
+456A:04400440FFFE044023F812A893F8404043F8104027FCE11023F8204027FC2040
+456B:0820FFFE08A0111E13D25A5E53D05A52E3CE120827E44822144003801C70E00E
+456C:0820FFFE082003FEF80009FC0924F9FC812487FEF80009FC092409FC512427FE
+456D:0440FFFE0440101010547C581090FE280044549292547C5810901C28E0444182
+456E:0440FFFE0440110011FC7E441154FEE4444429F47C4410E4FF54104410541008
+456F:0820FFFE08200000FE1C28E8FEA8AAA8FEA800A87CA800A4FEA4554A92783008
+4570:0440FFFE0440101C13E0152454A85BFE5124920211FC112429FC252445FC8104
+4571:0820FFFE082000007DFE002000FC7E8442FC42847EFC428424FC0F00F0484084
+4572:0820FFFE08A03FFE20402FFE240425F4251427FC200027FC20004FFE424884C4
+4573:0820FFFE08200000F7FC124817FCFC4686EC8554F6EC155416EC144454542408
+4574:0440FFFE044000A00C9071FE112013FCFD2031FC392055FE500092A412521452
+4575:0440FFFE0450102010FCFE8410FC10847CFC008000FE7C8044FE44027D524406
+4576:0440FFFE0440209010FEFD9002FC789000FC789000FC788049FC488878704B8E
+4577:0820FFFE092000803FFE24103F7C26382D543492212027C021104FF844A48990
+4578:0440FFFE04407F1049106BFE5D107F10087C7F0008000F7CF0440044557C5544
+4579:0440FFFE044020101048FE4044FE4590AA9010FCFE9010FC5490529092FE3080
+457A:0820FFFE0820244814507FFC082004407FFC0100FFFE22003E7C23A47E180266
+457B:0440FFFE04403F7E12241B3412A43FFC22403FF822483FF828442F7848428F3E
+457C:0820FFFE08204450FE4844FE7D901290FEFE9290FE9010FEFE90289044FE8280
+457D:0820FFFE082001FC7D5445FC44807DFC124411F45D5451F450445DF4E0140008
+457E:0820FFFE082000001E7812483FFC20202E20223C3FC829282F2849905F288144
+457F:0440FFFE04504420FEFC44847CFC1084FEFC9280FEFE1080FEFE280245528206
+4580:0820FFFE08203C782448FFFE02001FF0149012501FF0082010107C7C44447C7C
+4581:2810FEFE284400287CFE54007C7C54447C7C1044FE7C9210920ABAAA8AA4851C
+4582:0820FFFE29284FD2F03C23884812FBBE0280ABAA00F03F000100FFFE01000300
+4583:0820FFFE0A207FFC08001FF068100FF04444FEFE5454FEFE20207C7CC4C47D7C
+4584:0820FFFE08204450FE4844FE7D9010FCFE9092FCFE901090FEFE288044488224
+4585:0820FFFE08203FF801007FFE492284143BB82AA83BB800007FFC11102928FFFE
+4586:0440FFFE04400020FBFE2154F9DCA888A9FCD88889FC8888FBFE898AFEA488C2
+4587:0820FFFE2A28F3BC2508739CAD6A27C80000FFFE950A6B7055047F3824823FBC
+4588:010001F801003FFE210221F02F0420FC2000241824E027042404440443FC8000
+4589:010001F801003FFE210221F02F0420FC200023F8204020402FFE404041408080
+458A:0020043E042085FE4522293829E01122111E2900297845484548824A024A0486
+458B:0410079004103F90249027103C102490239020282F282928296449A491242042
+458C:0404078404043FD4245427143C5423D420142F14291429044944498491142008
+458D:010001F801003FFE210221F02F0420FC210021FC2210251028A0404041B0860C
+458E:00407840487C504053FC624452704BC04A444A3C6A0052F0449044924912520E
+458F:010001F801003FFE210221F02F0422FC220027F82D48334822E8449E49088218
+4590:04100E1E301020FE2092209C3EF02492248E248024B824A824A8452A452A8246
+4591:08000F00087C7F4449444E44787C4944474440444E7C4A444A02520291FE2000
+4592:010001F801003FFE210221F02F0420FC20002FF8200027F0241047F042209FFC
+4593:1010101E921092FE9292929CFEF01092108E928092B892A89EA8F32A012A0246
+4594:1020103E10207DFE1122113811E0FD22111E110021784948FD48464A024A0486
+4595:08000F0008787F4849484E7878484948477840484E484AFC4A02520291FE2000
+4596:08000F00087C7F5449544E7C78544954477C40104E104A104A12520291FE2000
+4597:01FC01003FFE210221F02F0420FC20282FFE28202BA428282BAC2A944BAC9044
+4598:10401E4010787E8853105CFC70A452A44EFC40205C505458545456929492210E
+4599:3F9024183F1421123F10247C3F8020802FFC288428F02F84287C49E04924921C
+459A:10201E4010FC7E8452845CFC708052FE4E8040FE5C0254AA54AA560294142008
+459B:08100F10087C7F1049FE4EA278444978471440FE4E104A544AB2520291FE2000
+459C:1E3C10207EFE52A25CB872E44E9C40805CB8952A23465FF010101FF010101FF0
+459D:0008007C07807900010001003FF82108210821083FF82100011001F87F042004
+459E:0808080808087F0849FE4908490849087F48482808280A080F08F10840280010
+459F:02000100FFFE100010001FF8000001001FF0111011101FF0110001087FFC2004
+45A0:100011F011107D1055105510559055507D505110111015121D12E612420E0400
+45A1:100011F810487C4854485448544855F87C885088108814881C88E48843FE0000
+45A2:1020102010207CA854A454A2552255207E245024102814081E10E22040C00300
+45A3:1008101C11F07D5055505550555055507D505148114815481D44E64442420400
+45A4:100010F83E884288A4A818941084207CC1001FF0111011101FF001087FFC2004
+45A5:1FF0022001407FFC048418886280010001001FF0111011101FF001087FFC2004
+45A6:1020102011247D245524552455FC54207C205124112415241D24E52441FC0004
+45A7:1000100010FC7C845484548454FC54847C84508410FC14841E00E20041FE0000
+45A8:1000100011FE7C2054205440544054FC7C845184128414841E84E28440FC0084
+45A9:1040102010287C0854085448545455527D525160126014441CC4E544423C0000
+45AA:088008882E9028A028C028842E84F07C01001FF0111011101FF001087FFC2004
+45AB:1010105010507C885488550456FA54207C20502011FC14201E20E22040200020
+45AC:100011FC11247D24552455FC552455247D2451FC112414201C20E42040200020
+45AD:1110091009207FFC0200FFFE08203018C1061FF0111011101FF001087FFC2004
+45AE:1020102010407DFC55045504557455547D545154115415741D04E50441140108
+45AF:01003FF80100FFFE01003FF80100FFFE000001003FF821083FF801087FFC0004
+45B0:1004101E11E07D0055065578555055507D52115415481D48E544425402620440
+45B1:100011FE11007D0055FE55105510557C7D105110111015FE1D00E50041FE0000
+45B2:1080108011FC7D04560455E4552455247DE45124112415E41D04E40440280010
+45B3:1020101011FE7D025400541C54E054207C20503E11E014201E22E222401E0000
+45B4:1050105010507D5254D45458545054587CD45152105014501E92E2924112020E
+45B5:1020102010207DFC55245524552455247DFC5124102014281C24E5FE40820000
+45B6:100013FE10407C8055445624546854B07D305228106814A41D22E62040A00040
+45B7:218420682030F8C8AB04A840ABFEA8A0F920A3FC252429243934E92840200020
+45B8:02403C500848FFFE08480E5078240854198C01003FF821083FF801087FFC0004
+45B9:208820882088FB8EA888A888A800A9FCF820A02023FE28203820E82040200020
+45BA:1080108011F821082A906C60A9982E4628402BF82A482A482BF8204427FC2004
+45BB:1020101011FE7C205448548455FE54027CA850A810A814A81EA8E2AA412A0206
+45BC:21002100211EFB92A912A912A912AFD2F912A112221A2A943FD0EA5040100010
+45BD:03083C0804487F480C4816482508442805101FF0111011101FF001087FFC2004
+45BE:1020101011FE7D02560454F8540054007DFE5050105014501E92E292410E0200
+45BF:0C8070FC1124FD241224384454849128101001003FF821083FF801087FFC0004
+45C0:2020202021FCF820A820ABFEA888A944FA42A0F821882A503820E85041880606
+45C1:1020102011FC7C505488550457FE54087DE85128112815E81D28E40840280010
+45C2:10201020103C7C2055FC5524553055E07D24511C110015701D50E5524292050E
+45C3:10481044105E7DE054285412546A55967C48505E11E014241E28E212406A0186
+45C4:1050108811547C2054D85706540854F07C80508010FC14901C90E51042100010
+45C5:100010FC10807CF8548054F8548057FE7D405124112815101D08E54441820100
+45C6:1020101011FE7D02560454F8548854887CF85080108014FC1E84E28440FC0084
+45C7:1080108010FE7D02562254AA547254227DFE5022107214AA1D22E422400A0004
+45C8:1040102013FE7C805480548054FC54007CFC508410FC14841EFCE28440FC0084
+45C9:10F8108810887CF85488548854F854007DFC5104110415FC1D04E50441FC0104
+45CA:102010A210A27D2454505488570454227C2050A410A415281C50E48841040202
+45CB:1088108813FE7C88548854F8548854887CF8502013FE14701CA8E52442220020
+45CC:100011FC11047DFC550455FC542055207DFE5220102015FC1C20E42043FE0000
+45CD:0FE010201FC00040FFFE0C1073200DC072B00C8EF3003FF821083FF801047FFE
+45CE:100013FE10507C5055FC5554555455547DFC5020102015FC1C20E42043FE0000
+45CF:1040102011FE7D2254A45528545054887D0450F8108814881E50E22040D80306
+45D0:1040FEFE21203CAC24F427A444AC54A2887E01003FF821083FF801087FFC0004
+45D1:100010FC10847CFC548454FC548454207C1051FE100014841E48E20041FE0000
+45D2:210820902000FBFCA890A890A892AC92FA94A298209028903890E89047FE0000
+45D3:2080208020FCF954AAD4A8B4A92CAA44F894A108204028A43AAAEA8A44780000
+45D4:108010BC10847D0855FE57205520557C7D90511011FE15101D28E52841440182
+45D5:01007FFC50043EF84288A2AA1492187EE1001FF0111011101FF001087FFC2004
+45D6:20A820A823FEF8A8A8A8A800ABFEAA22F820A1FC212429243934E92840200020
+45D7:2210221023DEFD28A884A800ABFCA890F890A09027FE28903890E91042100410
+45D8:1020102010FC7C20542055FE544054847DFE500211FC15541D54E55443FE0000
+45D9:01007FFE44429FF404403FF80440FFFE082011102FE8C9260FE001103FF81008
+45DA:1028102413FE7C2055FC552455FC55247DFC5124100817FE1C88E44840480018
+45DB:2120213C2144FAA8AA10AEA8AAC6AABCFAA4A2BC22A42ABC3A24EA244224022C
+45DC:204023BE2212FA92AA52AAAAAB24A840FBFEA22222222BFE3A22EA2243FE0202
+45DD:20201020FDFC092411FC392455FC9020102001003FF821083FF801087FFC0004
+45DE:00003FF80100FFFE02800C603018C00610207EFC52A47EFC10201424FEFE0202
+45DF:7F7848485F4C64805F7844484A4851307F4C01003FF821083FF801087FFC0004
+45E0:20401040FEFE21003DFE242224A044BC55608A3E01003FF821083FF801047FFE
+45E1:200023FE2020F93CA920AFFEA880A8FEF900A1FE20022AAA3AAAEC0240140008
+45E2:1010105012507D7C5490541054FE57007D7C51441144157C1D44E50042FE0400
+45E3:08200820FFFE08200FE008200FE0000010207EFC52A47EFC10201424FEFE0202
+45E4:101011FE11107D7C551455FE5514557C7D10117C15541D7CE554427C0254044C
+45E5:212421242224FC24A954A94AAA92AE10FA10A250225C2A503A50EAB0429E0300
+45E6:2020247C2284F948A830A8CEAE10AA7CFA10A27C22102AFE3A10EA1045FE0800
+45E7:1020101011FE7D10557C551455FE55147D7C111015921D54E538425402920430
+45E8:1040104010F87D08561055FC552455247DFC5124112415FC1C00E554412A022A
+45E9:200C200A2008FBFEAA08AA48AA6AAA4AFBFAA24C224C2AEC3B5AEC4A44D60822
+45EA:00803FFE222022203FFC222023E020002A48312420802FF848884FF880841FFE
+45EB:1020101011FE7D485548554855FE55487D4851EC115A15681D48E54842480048
+45EC:210013F0151000E0775C11F0104013FC284047FE01003FF821083FF801047FFE
+45ED:2020202021FCF924A9FCA820ABFEAA22FBFEA020204028243AA2EA8A44780000
+45EE:2020202023FEF820AAAAA924AAAAA820FAAAA12422AA28503850E88841040602
+45EF:20282224217EF9C8A948A87EAB48A948F97EA1482148297E3940EA80447E0000
+45F0:200021FC2124FBFEA924A9FCA800A9FCF904A1FC210429FC3904E9FC40880104
+45F1:205022522154F850ABFEA888A850ABFEF820A1FC20202BFE3850E88841040602
+45F2:2020212420A8FBFEA8A8A924AA22A904F904A1DE22442D54389EE90442040404
+45F3:201023D22054F948A88AA904AAFAAC00F9FCA104210429FC3904E88847FE0000
+45F4:2110211021DEFAA8AC44A806ABB8A888F908A3BE20882A88393EEAC0443E0000
+45F5:100013FE10007DFC552455FC552457FE7C0051FC112415FC1D24E5FC400003FE
+45F6:108813FE10887DFC550455FC550455FC7C8051FE122215521D02E5FA400A0004
+45F7:1040102011FC7C88545057FE540055FC7D0451FC110415FC1C20E694428A047A
+45F8:0100FFFE104824FE799010FC22907CFC089030FEC1803FF821083FF801047FFE
+45F9:2108209023FEF908A908AA52AB9CA908FA52A3DE204028A43AAAEA8A44780000
+45FA:00187BE0104022787A400A402BFC10002FFE400010207CF854A87CF81224FEFC
+45FB:2108210821EEFA94A842A800ABDEAA52FBD2A25223D22A1A3A94EB5042100010
+45FC:201C21E02020FBFEA820A9FCA9ACA974F9FCA02021FC28203BFEE8004154022A
+45FD:10A0209045FE792013FC25207DFC012055FE81003FF821083FF801087FFC0004
+45FE:200023FE2202FBFEAA02ABFEA908AA52FB9CA10822522BDE3800EAA442520452
+45FF:2040202023FEFA22A954A94AAA3AA800F9FCA15423FE280039FCE82040A00040
+4600:08003FF020103FF020003FF820083FF80100FFFE11207CF854A87CF81224FEFC
+4601:08287F240820FFFE12203FA46424BF2824123FAA01463FF821083FF801047FFE
+4602:2088208C23EAF888A888ABFEA948AB6AF94AA36A214C2B6C394AE96A47960022
+4603:21FC212421ACF924A9FCA820A9FCA820FBFEA154222A282039FCE82043FE0000
+4604:01081FD001207FFC02000FF03810CFF008100FF010207CF854A87CF81224FEFC
+4605:20444258FF6201427E3E42007E4C42727E42423E10207CF854A87CF81224FEFC
+4606:102013FE12227DFC542054F8542055FC7C2011FC15541DFCE44042A4028A047A
+4607:01007FFC082007C01930EFEE09200FE001103FF810207CF854A87CF81224FEFC
+4608:2FE829482BE8F95EA80AABEAAAAAABEAFAAAABEA288A2BEA3AAAEBEA4A2A1276
+4609:3FF801007FFC04401930EFEE09200FE001103FF810207CF854A87CF81224FEFC
+460A:221023DE2528F884ABFCAA94AA94ABFCF828A3FE22202B243AA8EA92442A08C6
+460B:2148214C22AAF808ABFEA948AB68A94AFB6AA14A236C294C396AEB8A40160022
+460C:3FFC24202FF825203FFC220027F02A1033F03FFC10207CF854A87CF81224FEFC
+460D:0820FFFE08201FF011101FF011107FFC41245FEC10207CF854A87CF81224FEFC
+460E:244428E82E0EFCE4AA0AAEEEA8A0AAEAF800A3F820082BF83A00EBFC40040038
+460F:0800083E10227F245524552855245524552255225522553457A8FC2000200020
+4610:0800080010787F2855285528556C556A55AA552A5528552857C8FC4800980100
+4611:0830080810007F705510551A55DA555C55585558555455545794FC1200500020
+4612:0810081010207F4455FE5528554455A2553C5544554455A85790FC2800440082
+4613:08100810101E7F225524554055105566554255425566554257C2FC42007E0042
+4614:08200810107E7F425510551C552455545508553655C0553C57A4FC24003C0024
+4615:12001100211C4FC08000100023BE6288A2882288228822A824C8248828282010
+4616:10001200221C43C085001100213E6FC8A10821082548254825C8264820282010
+4617:11001540254E47C0800017C0221E6444A784210422442FE42104254429342308
+4618:21002FE0410E47C081001FE0221E6444A784210422442FE42104254429342308
+4619:110017C0224E4FE0800017C0245E67C4A10423C4250427E4210427C425542548
+461A:02000100FFFE05000C883450C530060E040001000100FFFE0100010001000100
+461B:200011F00110FD100910111011103510591095101510111211121212120E1400
+461C:202010200020FC2009FC11241124352459249524152411341128102010201020
+461D:205010480048FC40087C13C010403440584094201420102010141014100C1004
+461E:200013F80008FC0809081108110835FE58029402140213FA1002100210141008
+461F:200011FC0024FC24082411FC11203520592095FE14221022102A102410201020
+4620:204010400040FC4009FE10401040348458A494A4152811281210142810441182
+4621:2080208820B03EC020842684387C22000100FFFE05000C883450C530060E0400
+4622:204010200020F9FE090212041000340059FE9420142010201020102010A01040
+4623:209010900090F290129222D422986A90B2902A902290229223D22E12240E2000
+4624:204010500048F8400BFC104014E038E055509150124814441842104010401040
+4625:200011FC0124FD24092411FC11243524592495FC152410201020102010201020
+4626:200011FC0104FD04090411FC11003540594495481570114011421242123E1400
+4627:202010200020FDFC0924112411243524592497FE142010501050108811041202
+4628:204010200020FBFE0800108815043A0254889088105010501020105010881306
+4629:2080108001FCFD040A0411E41124352459E49524152411E41104100410281010
+462A:204010200020FBFE0840108815043BFE549290901090109011121112120E1400
+462B:080008007F7C114421441A440C7C32000100FFFE05000C883450C530060E0400
+462C:202810240024F8200BFE102011243524592497A8152811101212122A14461082
+462D:200011FE0020FC200848108411FE34225820942015FC10201020102013FE1000
+462E:010001007FFC11101110292845440100FFFE1200111010A010401430180E1000
+462F:2020112400A4FCA8082011FC1104350459FC9504150411FC1104110411141108
+4630:2004100E03B8F08810882128212E6BA8B0A82AA822A8213E21002280247E2800
+4631:0100FFFE0820111022880C603018DFF6101010101FF004880C503530C60E0400
+4632:200011FC0004F8FC080411FC100033FE560299F8148810881050102010D81306
+4633:202010200050FC880904120210F83420582095FC1420112410A410A813FE1000
+4634:220812280228F2281FA4224422546E92B7102AA02A203228224422FC22442200
+4635:200011FC0004F80409FC100414043BFE54209222117410A81124122210A01040
+4636:200011FC0008F010122222AA22726A22B2722AAA232622A22242220223FE2002
+4637:2020112400A4FCA8082011FC11243524597495AC152411241124110411141108
+4638:2080104007FEF1201120223C22446E64B2942B48224822302220225022882306
+4639:2040102003FEF8000888108815543A225400902013FE10201020102010201020
+463A:2040102003FEF2021404200023FE6820B0202920213C212022A02260243E2800
+463B:2040102003FEF880090413FE100235FC590495FC150411FC1104110411141108
+463C:2040102003FEF2021504210021DE6A52B2522B52249A2094211021122212240E
+463D:20001040039CFA040A04139C120436045BFC949014901090109011121212140E
+463E:2040102003FEFA020C0411F81108350859F89500150011FC1104110411FC1104
+463F:200013FE0202F20213FE221022926A92B2922AFE221022922292249224FE2802
+4640:200013DE0252F252125223DE22526A52B2522BDE2252225222522252255228A6
+4641:20481044005EFDE008281012106A35965848945E15E0102410281012106A1186
+4642:209010900108F1481244249221086BFCB044282020A42282228A228A24782000
+4643:2040104003FEF88009FC122015FE300055FC990415FC110411FC110411141108
+4644:2008103C01E0F820082013FE102034A0592C9524152411AC1124112411FC1104
+4645:200013FE0050F8500BFE125216523BFE5400904017FE10881190106010D81304
+4646:201013D40058FA52098C108815043AFA5420902011FE10201050108811041202
+4647:200013FE0020FC4009FC1154115435545954952C142013FE1050108811041202
+4648:210011780108F20812FE26402A406A7CB2902A1022FE22102228222822442282
+4649:2008101C01F0FD10091011FE1110357C5944957C1544117C11441244127C1444
+464A:20A810A803FEF8A808A8100013FE3622582095FC152411241134112810201020
+464B:2040102003FEFA020C0411FC100035FC590495FC150411FC1104100013FE1000
+464C:2020102001FCF92409FC102013FE340059FC9504152411241124105010881304
+464D:200013FA000CF84A0B88112A112635225BF8952A152C112A1128122A12261422
+464E:201E13E00122FC940840108811F0342058C495FE1422102013FE105010881306
+464F:2028102403FEF82009FC112411FC352459FC9524140813FE1088104810481018
+4650:200013FE0000F9FC0904110415FC380057FE928A125213FE12221222122A1204
+4651:2080104007FEF00013F822082FFE6A08B3F828A4212823102510294821862100
+4652:2040102003FEF840088811F01020344459FE940215FC112411FC112411FC1104
+4653:200013FE0252FA520BFE1020142039FC5420902017FE10401088110413FE1102
+4654:200013FE0200FA7C0A441244167C3A0056EE92AA12AA12AA12EE120013FE1000
+4655:212411240224F4A41154214A23926D08B1082928212E212821282158214E2180
+4656:202012220222F3FE100023DE22526A52B3DE2A52225223DE22522252255A28A4
+4657:2040102003FEF888085013FE16223AFA562292FA128A128A12FA1202120A1204
+4658:201410120010F7FE1410249024D26C92B7F22C94249425C82AAA289A31A62042
+4659:200013FE0202F3FE1210225422386A54B2822A50227C2290221025FE24102810
+465A:02001FF010101FF010101FFC10001FFC0004492C0200FFFE06801C48E530060E
+465B:2040102003FEF88809241242109035F85808944414A81190128814A410C21080
+465C:2020147C0284F148103020CE26106A7CB2102A7C221022FE2210221025FE2800
+465D:0100FFFE08207E2008F8FF2814287F6A082AFF560B8204880C503530C60E0400
+465E:202017A400A8F2921114220825F46802B3F82A08220823F8220821102FFE2000
+465F:200017FC0444F5F4149427FC24046DF4B5142DF4244424F4254425FC244427FC
+4660:200017FE0400F628154827EE24926C84B6A02EA827E824882494251429243242
+4661:202011FC0124F9FC082013FE100035FC590495FC150411FC110411FC10881104
+4662:210410880000FBFE0A2212AA1272322257FE980015FC110411FC110411FC1104
+4663:200011FC0040FBFE088811041652305057DE985015DC105013DE105010501050
+4664:2000127C0144F1741054205426FE6A82B2BA2AAA22BA2282228A2284250028FE
+4665:200011FC0020FBFE0A2211AC142039AC545090C8132610F8100810D010201010
+4666:208813FE0088F9FC0954115415FC380057FE924210F810881148103010601380
+4667:201C11E00020FBFE082011FC11AC357459FC942015FC102013FE10001154122A
+4668:21FC112401FCF92409FC102013FE34A859249642142013FE10601194168810C6
+4669:208813FE0088FBFE0A0211FC14003BFE544090A2135410B81354109213501020
+466A:22882108FABE2008729CA92A2288FFFE0A203118CFE6028804501C2065180606
+466B:209413980092FD8E0A8011FC112435FC592495FC148811FC108813FE10881104
+466C:23DE125203DEFA520BDE125217DE398C5652904017FE10881190106010D81304
+466D:204017FE0492F3FC109023FC20906FFEB1082BFC250A21F82240227C254028FE
+466E:208813FE0088FBDE0A5213DE14A0389055FE912013FC152011FC112011FE1100
+466F:201417FE0490F4D4149427FA25AA6A96B1A22BF8220823F82040227C254028FE
+4670:220C110A07C8F29E155426F4245E6FD4B1142FDE2554255425D4245E25502490
+4671:23FE120203FEFA920A54129216FE3AAA56FE932212FA12AA12FA122215FA1004
+4672:00007FFC044004403FF8244824483FF801000100FFFE0280044008203018C006
+4673:00007FFC044004403FF8244824483FF801001110111022A0044008203018C006
+4674:7FFC04403FF8244824483FF80200FFFE08201FF02828C8260FE00808080807F8
+4675:00007FFC04403FF8244824483FF801003FF80100FFFE000001003FF80100FFFE
+4676:0010FE10281029FE2922FE20AA50AA50AAD2AACCAF48C24482448252FE608240
+4677:1FF010101FF010101FF010101FF004421842E03E0020FFFE0820042004A00040
+4678:00087E08420842FE7E08420842887E48424842087E0824282412240243FE8000
+4679:00007EFC2484248424FC24842484FFFC2484248424FC2450245024924492850E
+467A:100011FC1104110455FC5904510491FC1104110411FC2850245044924112820E
+467B:0800087C0B447C44487C484448447F7C09441944297C49288B28084A084A0886
+467C:00007EFC1284128422FC2A84448480FC3E84228422FC225022503E922292010E
+467D:01000100FFFE0280244818303FF8D0161FF010101FF010101FF004421842E03E
+467E:200010FC1084FE8482FC0484408440FC7C84408440FC40504C5070924092010E
+467F:100010FC10847C8410FC10841084FEFC1084388434FC5250905010921092110E
+4680:0800107C3E442244327C2A442A44FE7C224432442A7C2A282228424A4A4A8486
+4681:0800087C10447F44417C41445D44557C55445544557C5D284128414A454A4286
+4682:100010FC10847C8410FC1084FE8428FC28846C84AAFC2850285048924892990E
+4683:0800087C0F440844087C7E444244427C7A444A444A7C7A284228424A7E4A4286
+4684:00007E7C02443E44027CFFC40844097C49442A441C7C2A28C928094A284A1086
+4685:0800087C0844FF44087C2A442A442A7C5D4488441C7C2A284928884A084A0886
+4686:2200227C7F4422442A7C08443E442A7C2A442A44FF7C08281428124A224A4086
+4687:1000107C52445144957C08443044C07C7E4442447E7C42287E28424A7E4A4286
+4688:0000FF7C144414447F7C554455447F7C084408447F7C082808280F4AF04A4086
+4689:20002F7CF5442544757C2544F544297C23440844087CFFA81428224A414A8086
+468A:2200147C00447F44007C14442244417C00447F44557C5528552857CAFC4A0086
+468B:00003E7C224422443E7C00447F44417C7F4441447F7C41287F28144A224A4286
+468C:0800107C7F4441447F7C41447F44107CFFC42244497C88A87F68084A084A0886
+468D:0800FF7C08447E44087CFF4400447E7C42447E44427C7E2842287E4A244A4286
+468E:0800087C7F4410443E7C1044FFC4227C414490C4267C22283628224A3E4A2286
+468F:08004A7C2C440844FF7C2A444944887C42447744927C5A282F28224A424A8286
+4690:4000777CA5442544FD7C27445544807C7E444244427C7E284228424A7E4A4286
+4691:0000FEFCAA84AA84FEFC00847C8444FC7C8444847CFC44507C5000922892450E
+4692:1000087C7F442244FF7C00447F44497C7F4449447F7C08287F28084A0F4AF086
+4693:0000FEFC2884FE84AAFCFE8400847CFC44847C8444FC7C501050FE921092110E
+4694:200010FCFE8482847CFC548498847CFCC4847C8444FC7C5044507C922892450E
+4695:7700007C77445544777C554408447F7C54447F44557C7F2855285E4A554A9B86
+4696:0000FEFC1084FE8492FC54840084EEFCAA84EE8400FCFE505450BA921092FF0E
+4697:200820487848484890447C8454A455227C20544054407C48548455FE44828C00
+4698:12001380249C490087C01540257E67C8A548254827C8254825482548246828D0
+4699:100010FE3C002400487CBE442A442A7C3E442A442A7C3E442A004A0042FE8600
+469A:101010503C50247C4890BE102A102AFE3E282A282A283E282A4A4A4A42868700
+469B:101010503C50247C4850BE902A102AFE3E002A002A7C3E442A444A44427C8644
+469C:102010403CFE24924892BEFE2A922AA23EFE2A482A883FFE2A084A0842088608
+469D:2040202079FE480090887C88555456227C00542055FE7C205420542044208C20
+469E:2020202078204BFE90207D24552455247EAA547054A87CA85524562244208C20
+469F:100010FC3C8424FC4884BEFC2A002AFE3E082BFE2A083E882A484A0842288610
+46A0:200021FC7904490491FC7D04550455FC7C00551255D47D185510555245928D0E
+46A1:200021FC7924492491FC7D24552455FC7C20541054547D425542554A46388C00
+46A2:2048214879484BFE91487D48557855007DFE542057FE7C7054A8552446228C20
+46A3:100010FC3C84248448FCBE842A842AFC3E002BFE2A203EA02ABC4AA04360863E
+46A4:1000107C3C542454487CBE542A542A7C3E102AFE2A923E962ABE4A82428A8684
+46A5:100010EE3C22242248EEBE882A882AEE3E222AAA2A663E662AAA4A2242AA8644
+46A6:2008203C79D0491C91107D7C555455587D705554554C7D40567854A8442A8C46
+46A7:200021DC7844495490CC7D54542854447D92542054C87C3254C4541844608D80
+46A8:201221D478484A8A91047E0255DC54547C6255C0551E7DC25454544845548CA2
+46A9:201821E078404BFE90887D74565254707C0055FC55047D745554557445048D0C
+46AA:200021FC7954495491FC7C0057FE54007DFC550455FC7C625494558846A48CC2
+46AB:10207E204A7E7EC41028FF1020283EC652001FE020405FF091101FF011102130
+46AC:2020212478A84BFE90A87D24562255087DC8565E55487CA854BE550845088E08
+46AD:208823FE7888480091DC7D5455DC54887DFE569054FC7C9054FC549044FE8C80
+46AE:2000100011FCFE4400487C4800507C5E00427C424482448244827D0245140208
+46AF:100408040804FFA400247F2400247F2400247F244124412441247F0441140008
+46B0:208010801080FE8400887C9000A07CC000807C804480448444847C84447C0000
+46B1:202010201020FE2000207CA800A47CA401227D224622442044207C2044A00040
+46B2:200810081010FE2000407C8800087C1000207C444484440844107C2044C00300
+46B3:202010200020FDFE00207820002079FC00847888484848504820785049880606
+46B4:200010FC1084FE8400847CFC00847C8400847CFC4484448444847C8445140208
+46B5:200810881048FE4800087C8800487C4800087C0E45F8440844087C0844080008
+46B6:2000100011FCFE2000207C2000207DFE00207C204450445044887C8845040202
+46B7:209010900108FD0802047C0203FC7880010079F8480848084808780848500020
+46B8:202010201050FE5000887D0402027C8800887C884488448844887D0845080208
+46B9:201011100110FD120112791401D87910011079104910491249527992490E0000
+46BA:204010401040FE8000FE7D0802887C8800887C504450442044507C8845040202
+46BB:020007F0182062400980060019007FFC00003FF800003FF800003FF820083FF8
+46BC:200011F81048FE4800487C4800487DF800887C884488448844887C8847FE0000
+46BD:2008103C11E0FE2000207C3C01E07C2000207C3E47E0442044227C224422001E
+46BE:2008103C11E0FE2000207C2000207DFE00207C204420442044207C2045FC0000
+46BF:204010401040FE7C00847C8801207C2000207C504450445044887C8845040202
+46C0:2008101C01E0FD00010079FC01447944014479284928491049107A284A440482
+46C1:200010FC1084FE8400847DFE00847C8400847DFE4484448444847C8444940088
+46C2:200810680388FC880088788800887BFE0088788848884888490879084A080408
+46C3:2000100011FCFC0000007C0003FE7C9000907C904490449044927D124512020E
+46C4:42002200023CFBA402A472A404A474A40AB471285120512252227222541E0800
+46C5:200011FC1124FD2401247DFC01247D2401247DFC4524442044207C2044200020
+46C6:202010201020FE2001FC7D2401247D2401247DFC4524452445247D2445FC0104
+46C7:200010F81088FE8800887C8801067E0000007DFC4504450445047D0445FC0104
+46C8:204010401080FCFC01207E2000207C2001FE7C204450445044887C8845040202
+46C9:200011FC1104FF0401047DFC01207D2001FE7D204520451045127D4A45860102
+46CA:2000100010FCFE8400847C8400847C8400FC7C844400444844447C8444820102
+46CB:202810240024FC2001FE792001247924012479284928491849127A1A4A260442
+46CC:2040104010FCFE8401047EF400947C9400F47C844494448844827C82447E0000
+46CD:209010900090FBFC0094789403FC7A9002907BFE48924892491A79144A100410
+46CE:204010200020FBFE02027C04000078900090789048884908490879044A040402
+46CF:200010FC1084FE8400847CFC00807CA000A27CA444B844A044A27D22451E0200
+46D0:00003FF800087FC800083F8820883FA80110FFFE00003FF800003FF820083FF8
+46D1:200010400020FC280008788800907A9402A27AA24CC2488849887A8844780000
+46D2:00007DFE108010FC1E04F02801107FFC00003FF800003FF800003FF820083FF8
+46D3:0480248024FC24A02510040001007FFC00003FF800003FF800003FF820083FF8
+46D4:200013FE1020FE2000407DFC01547D5401547D544554455445547D4445140108
+46D5:2020102003FEFE2202227BFE02227A2203FE7820492048A0484078A049180606
+46D6:2020102001FCFD24012479FC0124792401FC782048244818483278CA4B060002
+46D7:00407E2049FE480048007EFC4200420042FC7E00480048FC488448847EFC0084
+46D8:20801088009CFD7001107B100510791001FE79104910491049107910497C0100
+46D9:209010900090FD1001FE7B100510793801387954495449924910791049100110
+46DA:08007EF808483E4808887EA809107FFC00003FF800003FF800003FF820083FF8
+46DB:2000100011FCFF0401047D7401547D5401547D544574450445047DFC45040000
+46DC:202010200040FDFC010479040194795401247924495449944904790449FC0104
+46DD:200011FC0024FC2401FC784400447BFE00007820482049244924792449FC0004
+46DE:200011FC1104FDFC01047DFC00007C0001FC7C20442047FE44207C2044200020
+46DF:202010200020FBFE002078200124792401247AAA482048504850788849040202
+46E0:200011FE1000FE0000FC7C8400847C8400FC7C004484444444487C0045FE0000
+46E1:201C13E00220FE2003FE7A2002907B0A020679FA490849084908790849F80108
+46E2:201C11E00020FC2003FE78A801247A22000078F8488848884888788A490A0206
+46E3:2020102001FCFD2401FC792401FC780003FE7880490049FC4804780448280010
+46E4:200010FC1084FE8400847C8400FC7C1000107C90449E449044907CD0453E0200
+46E5:218410680030FCC80304784003FE78A001207BFC4D2449244934792848200020
+46E6:200010501048FE8401247C2000507C8801067EF84488448844887C8844F80088
+46E7:201011101110FD9201547D1001FE7D1001387D544592451045107D1045FE0000
+46E8:2040102011FCFE0000887C5003FE7C2000207C2045FC442044207C2044200020
+46E9:200011FE1048FE4800487DCE01027D0201027DCE4448444844487C4845FE0000
+46EA:2040102003FEFA0200887904020279FC000479FC490049FC4804780448280010
+46EB:200010FC0080FCF8008078F800807BFE01407924492849104908794449820100
+46EC:2080108001FCFD04028478F40144784403FC78444954495449F4780448280010
+46ED:2020102001FCFC2000207BFE0088785001FC782048204BFE4820782048200020
+46EE:2088108810E8FD2C012A7EA800487CA0011E7E0044FC448444847C8444FC0084
+46EF:200011FE0102FD0201FE7910011079FE01107910497E494249427A424A7E0442
+46F0:200011FC1104FF0401FC7D0401047DFC00007D1245D4451845107D524592010E
+46F1:2020102001FCFD240124792401FC78200040782048A44A824A8A7A8A44780000
+46F2:2020104001FCFD0401FC790401FC782000207BFE4A224A224A2A7A2448200020
+46F3:2020102003FEFC5000887924022279FC012479FC492449FC48227822481E0000
+46F4:2020102001FCFC500088790403FE780801E87928492849E84928780848280010
+46F5:201C13E00044F92400A8789003FE7A02000079FC488448884850782048D80306
+46F6:2020102003FEFC2001FC782003FE7820000078204BFE487048A879244A220020
+46F7:2040102003FEFA020504790001DE7A5202527B524C9A4894491079124A12040E
+46F8:2020101001FEFD0001107910011E79100110797E4942494249427A424A7E0442
+46F9:208010FC0104FDF800087BFE004078A20334785848944B34485278904B500020
+46FA:21FC11240124FDFC0124792401FC7850008879044A8A48884888788849080208
+46FB:2008101C01F0FD10011079FE0110797C0144797C4944497C49447A44427C0444
+46FC:2040119C0104FD0401DC7904010479FC0000780049FC4820482078204BFE0000
+46FD:2008103C01E0FC2000207BFE002078A0012C7924492449AC4924792449FC0104
+46FE:2020102003FEFC2001FC782003FE7840008879F048244BFE482279244AA20040
+46FF:200013FE0000FDFC0104790401FC780003FE7A8A4A524BFE4A227A224A2A0204
+4700:400023DE014AF94A035A756A014A72D6002070205120513C5120712057FE0000
+4701:202011FC0220FBFE02007A2003FC7A2003FE7A004BE048204BFE785048880306
+4702:2020104001FCFD0401FC790401FC784003FE788849244A224DFC782048200020
+4703:20501048FEFE00907DFE00907CFE00907C9044FE7C8001003FF80100FFFE0000
+4704:200011FE0102FDFE011079540138795401827950497C499049107AFE4A100410
+4705:2020122203FEFC90008879FE03107D1001FE7910491049FE4910791049FE0100
+4706:00803FFE24103F7C26382D5434923FFC20002FF820002FF820004FF848088FF8
+4707:2040102003FEFC8801247A42009079F80008784448A849904A887CA448C20080
+4708:212412480124FC0001FC792401FC792401FC78204BFE487048A8792446220020
+4709:2020102003FEFC7000AC7B220050788801247A22492448A849247A2248A00040
+470A:2090109007FEF89003FC7A9403FC7A9403FC780049F8490849F8790849F80108
+470B:202011FC0124FDFC00207BFE000079FC010479FC490449FC490479FC48880104
+470C:1204110420082B8A4812F3BC100423884812FBBE0A820280AAAAABAA82A20000
+470D:2020102001FCFC200154788801047AFA008878F8488848F8482078A849240060
+470E:208812AA02DCFC8801547A2200007BFE02427C444BFC48444844788449140208
+470F:4020272005FEFD40057C7690057E7500057C7544557C5644547C74445444044C
+4710:00407BFC488051F84A204DFC688852F84188FFFE00003FF800003FF820083FF8
+4711:200013FE0050FDDC0104790401DC785000507BFE4840482048A47A8A4A8A0478
+4712:2040108003FEFE2202AA7A2203FE7A7202AA7A0248204BFE4850788849040602
+4713:208813FE0088FC0001487BFE01487978010079FC48204BFE487078A84B260020
+4714:202010FE0240FD7C0090797E00007B7C0144797C4944497C4944794C4A80047E
+4715:2088108803FEFC8801FC792401FC792401FC78204BFE4A224A2A7AFA4A0A0206
+4716:200013FE0050FBFE02527BFE000079FC010479FC490449FC490479FC48880104
+4717:4014201207FEF41005D0741405D4755805CA74165442582452A2728A54780000
+4718:4288228807E8FA90041E77E40454785407547554555457485548705452940122
+4719:200013FE0202FBFE02027BFE01087A52039C79084A524BDE48007AA44A520452
+471A:440022FE02AAF8AA00FE70100E54729202107254529252105210750058FE0000
+471B:208011F80210FDFC012479FC00927B0E008079F84A1049FC492479FC4892030E
+471C:2040107C0040FBFE020279FC00A87954028879FC4A8A48F8488878F8488800F8
+471D:2044128402EAFE4E02A47AEE02227BFE02447A844AEA4A4E4AA47AEE4A2203FE
+471E:4040202003FEF888005277AC02AA72A805AC7000510451FC510471FC51040204
+471F:2088108C03EAF88800887BFE01487B6A014A7B6A494C4B6C494A796A4B960022
+4720:2042139C0210FBDE02947A9404207BFC02047BFC4A044BFC4A047BFC49080204
+4721:43FC204001F8F90801F8710807FE744202A4728A547A508051F872885070038E
+4722:202013FE0222FDFC002078F8002079FC002079FC495449FC48407AA44A8A047A
+4723:0008201C11E0110001000100F1FE111011101110111015101910121002100410
+4724:011041102110211007FC0110E110211021102FFE200029103108220804040804
+4725:0000407C2F442144027C0244E4442744217C250025002AFE3200250008FE0000
+4726:0110211017FE1110020003FCF40413E4122413E4122417E41A24100400280010
+4727:000023DE114A114A035A056AF14A12D6102010201120153C1920112007FE0000
+4728:0020202011FC112401FC0020F3FE122213FE1020104014241AA2128A04780000
+4729:0110411027FC211001F00208E2EA26AC22A822AA26EA2A06300022A402520452
+472A:0040244022404A4089F8144822484148BC4824482448244A248A3C8A25060200
+472B:0000240022F84A208820142022204120BC2024202420242024203DFC24000000
+472C:0020242022204A2089FC152423244124BD2425FC2524252425243D2425FC0104
+472D:010001F801007FFE40029FF40820111022880C603018DFF6101010101FF01010
+472E:0020241022FE4A8289141450227E4150BC90241025FE241024103C1024100010
+472F:00402440227E4A82892214AA22724122BCFE2422247224AA25223C22240A0004
+4730:0020484045FC950411FC290445FC80407BFE488849244A224DFC782048200020
+4731:000049F8450895F8110829F8440083FC7A944BFC480049F84890786049980606
+4732:01244A484524940013FC2A94466482947BFC4A484B684A484B6A7A4A4A460362
+4733:00007FFC000000001FF0101010101FF008200440FFFE1000100010001FF80000
+4734:0020FE200020003E7C204420442045FC7C840088444828502E20F05041880606
+4735:0010FE10001001FE7D124514451045FC7D440144452829282F10F22842440482
+4736:0020FE20003C00447CA84410442844D67C1000FC441028902EFEF01040100010
+4737:0000FEFC0004007C7C0444FC440045FE7D0200FC444428442E28F01040680186
+4738:0000FEFE008200827CFE4480448C44B07C9C00B0449E28F02E92F112410E0200
+4739:0020FE2001FE00207C2045FC452445247DFC0020447028A82F24F22240200020
+473A:0048FE48004801FE7C48444845FE44007CFC0084448428FC2E84F08440FC0084
+473B:0000FEFC008400847CFC4484448444FC7C0001FE442028A02EBCF0A04160023E
+473C:00207E20247E18A4FF2829104A2898C600007FFC00001FF010101FF004407FFC
+473D:0020FE50008801047EFA440045E2452A7D2A01EA452A292A2FEAF122412A0164
+473E:0020FE1001FE00007C84444845FE44007CFC0084448428FC2E84F08440FC0084
+473F:00003F2024203F3E21403F5024883F0800007FFC00001FF010101FF004407FFC
+4740:0020FEDE008A00CA7CAA44D244A644007CFE0092449228FE2E92F09240FE0082
+4741:08202AA42CA84920145022887FFE40029FF400001FF010101FF008200440FFFE
+4742:7E7848487E8E420042F87E4848307ECE00007FFC00001FF010101FF004407FFC
+4743:0000FEFE008200FE7C8244FE444444AA7CEE004444AA28EE2E00F0D440AA012A
+4744:0108FA9403DE06B47BDE529453DE529473DE021097FC510860903860C1980606
+4745:0020FE200820102030204A209DFC28204C209A202A204820882008202BFE1000
+4746:08001FF822484488095012207FFC02000D1072A00CC071A006981886E2800100
+4747:000025FC2220424080A425382450249825382454249425502422440243FE8000
+4748:001CFDE01100210061FE95003900517C994435445554914811421242523E2400
+4749:044024481450FFFE800200007FFC02000D1072A00CC071A006981886E2800100
+474A:0020FC2013FE202061FC94243BFE502499FC34205520913E112012A0527E2400
+474B:0040FC2013FE2202600095FC380050009BFE3420552891241222142250A02040
+474C:0000FBDE2042414AA084154A3A525420980037DE505291521094114852542422
+474D:0000FBFE22224020A1FE142039FC512499FC352451FC902013FE102050202020
+474E:0020FD241124212461FC94003BFE5020984035FC55549154115411545154210C
+474F:0020FDFC112423FE612495FC382051FC992435FC544093FE108811D05070238C
+4750:0010FB9022FE42A0A2BE17483ABE52809ABE36A252BE9322123E122252222226
+4751:0020FDFC1088205063FE940039FC512499FC352455FC902011FC102053FE2000
+4752:03F0FD2E11E2212A61E495343BEA5032981E35E054A29134106810A453222020
+4753:0124FA4821244000A3FC16943A6452949BFC364853689248136A124A52462362
+4754:0088FBFE208843DEA25217DE38A0509099FE352053FC952011FC112051FE2100
+4755:03FCF90811F8210865F8990E37F8500897FE3A94579C9294139C12D657BC2084
+4756:1008201CD5F0095051502150D15019502950C94819482948C9440A4452422400
+4757:0C203020C22014204BFE3020C870147024A8CCA815242622C420042028201020
+4758:0C0030F8C288148848883106CA0015FC2484CC8414482450C420045028881306
+4759:0C0031FEC300150449443128C92815102510CD2815282544C584050029FE1000
+475A:100021FCD5040904510421FCD10019402944C94819702940C9420A42523E2400
+475B:10102010D41009FE51122114D11019FC2944C94419282928C9100A2852442482
+475C:10402040D488090453FE2002D08819442A42C8F819882A50C820085051882606
+475D:0C203020C3FC145048883104CBFE140825E8CD28152825E8C528040828281010
+475E:10202020D43E082051FE2122D13819E02922C91E19002978CA480A4A548A2906
+475F:1080209ED7EA088A51CA208AD3EA189228A6C8201BFE2820C850088851042602
+4760:100021FED5100920517C2144D17C1944297CC91019102954C9520A9252502420
+4761:10882088D7FE0888508820F8D0201BFE2A22CB321AAA2B76CA220A22522A2224
+4762:100021F8D50809F8510821F8D0001BFC2A94CBFC180029F8C890086051982606
+4763:1200217ED4400C7C524420FCD1401E7E2A20C8201BFE2870C8A8092452222020
+4764:0C203020C3FC142049543088C90416FA2488CCF8148824F8C42004A829241060
+4765:104021FCD50409FC510421FCD10419FC2820C92418A82924C8200BFE50202020
+4766:10402080D7FE0A52525227FED000181E2BE0C8A219222A74C8A8092456222020
+4767:00407C40448044FC7D04460444847C44444444147C2400442984240444288010
+4768:040025FC2488245024202450008C1FF010101FF010101FF010101FF008201010
+4769:00207C20445044887D04461244207C40458844107C2000442988241044608380
+476A:00007C0045FE44127C14441044907C90449E44907C90009028D02530451E8200
+476B:00807C80448044FE7D40454046407C7C444044407C40007C2840244044408040
+476C:00407C20440045FC7C20442044207C2045FC44207C2000202820242047FE8000
+476D:00807C80450045FC7E04440445E47D24452445247DE401242804240444288010
+476E:00207C10441045FE7C20442044447C8445F844107C200044288225FE44828000
+476F:00807C8044FE45007E204520452C7D7447A445247D3401282922250244FE8000
+4770:00207C20442045FC7C20442047FE7C08440845FE7C0800882848240844288010
+4771:02001FF0081010307EFC2244468C1FF010101FF010101FF010101FF008201010
+4772:00007CFC448444847CFC449044907C88448445327D0802002860241844048000
+4773:08000F7C28447F28A11016283846DFF010101FF010101FF010101FF008201010
+4774:01007FFC01001FF011101FF001007FFE50129FF410101FF010101FF008201010
+4775:00287C2445FE44207C2045FC45247D2445FC45247D2401FC292425244524810C
+4776:00407C2047FE44007C0045FC45047D0445FC44207D2801242A22242244A08040
+4777:20003E7C48440844FF44247C42001FF010101FF010101FF010101FF008201010
+4778:00887C8847FE44887CA8442047FE7C20442045FC7C8400882850242044D88306
+4779:004078204BFE4A027D04490049DE7A524A524B527C9A0094511049128A12040E
+477A:102008107EFC04482448183064CC1FF010101FF010101FF010101FF008201010
+477B:00007DFC450445047DFC451045107DFE451045107D7C014429442544457C8244
+477C:00207C2047FE44207DFC442047FE7C0045FC45047DFC010429FC250445148108
+477D:000079FE49104910797C4910491079FE490049107910017C51104A108AFE0400
+477E:3F500048FFFE08402F2028122F0AF0063FFA20083FF820083FF820083FF80820
+477F:0500397821083D7822083FF808203FF8D0161FF010101FF010101FF008201010
+4780:00807CBC448445087DFE472045207D7C459045107DFE01102928252845448182
+4781:00007BFE4A004AFC7A844AFC4A847AFC4A204BFE7A4802C852304A488A8403FE
+4782:00007DFC442044407DFC455445547D544544452C7C2003FE2850248845048202
+4783:0008700857C85210721E54A457D47114511457D47114010851C84E1484140022
+4784:2040FEFE21203CAC24F447AC54A2887E00001FF010101FF010101FF008201010
+4785:000079FE4900497E790049FE49547948496449427900017E51424A428A7E0442
+4786:00207D2444A844207DFC450445047DFC450445FC7D04010429FC240044888104
+4787:08203E2008F87F282A685D2A08563E8200001FF010101FF010101FF008201010
+4788:001E7BE0494448A879F84908490879FC4904490479FE010252AA4AAA8D0A0004
+4789:00207D2444A845FC7C4047FE44887DFC468A44F87C8800F8288824F844508088
+478A:007C78404BFE4A427A784BC44A3C7AA84B544AF87B8C02FA52884AF88A8804F8
+478B:0200713C57A4502474BC532457A4713C512457A4713C059055584968812A0346
+478C:00087C3C45E05420542057FE54205420542055FC550411042904250445FC8104
+478D:00207C2047FE442055FC542057FE540055FC550455FC110429FC250441148108
+478E:00F87C88448854F85488548854F8540055FC5504550411FC2904250445FC8104
+478F:00007DFC4524452455FC5524552455FC54205410545411422942254A42388000
+4790:00207C2047FE542055FC544057FE5488550456FA5488108828F82488448880F8
+4791:08000800087C7E1008100810FF10141014105610551095102410241054FE8800
+4792:080008FE08827E8208BA0882FF8214BA14AA56AA55AA94BA24822482548A8884
+4793:080008FE08007E5208A40928FF94144A140056FE551095102410241055FE8800
+4794:080008FE08827E8208FE0880FF8C14B0149C56B0559E94F024922512550E8A00
+4795:0800087C08107EFE08920854FF101454140056FE551094FE24AA24AA54AA8886
+4796:0850084808487E40085C09E0FE400840282028242E14280C280458004FFE8000
+4797:0808080808087E0808FE0818FE180828282828482E482888281858004FFE8000
+4798:08400840087C7E8009000800FEF80810282028402E842884287C58004FFE8000
+4799:100013FE10207C20102011FCFD241124112451245D2451345128702050208FFE
+479A:0810081008FE7E10081008FCFF040804286828102E282844288258004FFE8000
+479B:080009FE08207EA008BC08A4FEA408FC280428042E042828281058004FFE8000
+479C:0800080009FE7E1008200820FE68086428A229222E202820282058004FFE8000
+479D:0800080008FC7E2008200820FE2008FC282828242E24282029FE58004FFE8000
+479E:1050105010507DFC10541054FDFC1150115051FE5C525052505A709451108FFE
+479F:0820082008407EFC08840884FE8408FC288428842E8428FC288458004FFE8000
+47A0:080009FE08207E200840087CFEC40944284428442E44287C284458004FFE8000
+47A1:0800080008FC7E84088408FCFE84088428FC28842E0029FE280058004FFE8000
+47A2:0840084008407EFE08A00920FE3C08202820283E2E202820282058004FFE8000
+47A3:0808081C08E07E80088008FEFE90089028B028982E94291029105A004FFE8000
+47A4:1080108011007DFC12041004FDE41124112451245DE451245004702850108FFE
+47A5:0810081009FE7E20084008FCFF44087C2844287C2E442854284858004FFE8000
+47A6:08200820083C7E4408A80810FF2808442882287C2E442844287C58004FFE8000
+47A7:0808081C08E07E8008FE0880FE8008BC28A428A42EA4293C29245A004FFE8000
+47A8:0820082008FC7E20082009FEFE00082028FC28202E20282029FE58004FFE8000
+47A9:0810081008287E440882087CFF000800287C28442E44287C284458004FFE8000
+47AA:080008FE08807E8408B808A0FFBE08A428A428A42EC4288028FE58004FFE8000
+47AB:100011FC10447C4413FE1044FC4411FC108050FC5D84528450FC708450008FFE
+47AC:080C087008107EFE08380854FE920800287C28242E2E2842288A59044FFE8000
+47AD:1020104810847DFE10021048FC841142107C50845D6850105068718450008FFE
+47AE:0810081008287E4408BA0810FEFE0810285828942F122850282058004FFE8000
+47AF:080E08F008227E9208540800FF7C0808281028FE2E102810285058204FFE8000
+47B0:1020102011FC7C20102013FEFC501050115451525E5250905090713050008FFE
+47B1:0828084408927E1008280844FE82097C284428442E44287C284458004FFE8000
+47B2:101010D813947C94109013FEFC94109410D853925CAA50CA5286710250008FFE
+47B3:0820081008FC7E0008840848FEFE080028FC28842E8428FC288458004FFE8000
+47B4:11FC112411247D74112411FCFD041174115451545D7451045204721454088FFE
+47B5:100011EE10227CAA104410AAFD32120011EE50225CAA504450AA711252208FFE
+47B6:11F8110811087DF811081108FDF8108011FC52545C9451245244709451088FFE
+47B7:100011FC11047DFC11001110FD541154117C51105D5451545254747C50008FFE
+47B8:100010F810007C0011FC1020FD241222106050005DFC5104510471FC50008FFE
+47B9:0820084008FC7E8408FC0884FEFC080029FE28202EFC282029FE58004FFE8000
+47BA:081E09F009107F1009FE0910FF7E0942297E29422F7E2942297E5A004FFE8000
+47BB:11F8105010207DFC112411FCFD2411FC112450405DFC50445084712852108FFE
+47BC:0820083C08447E78080808FEFF20085228AC28582EAC284A28AA58104FFE8000
+47BD:08100810087C7E1008FE08A2FE440878281428FE2E10285428B258004FFE8000
+47BE:101E13E0123C7A2012FE12A2FAB812E4129C52805AB85328554A728650008FFE
+47BF:01007FFE44429FF404403FF80440FFFE092017D02108DFF6010011F8290047FE
+47C0:0844082808FE7E10087C0810FEFE08202820287E2E882908287E58004FFE8000
+47C1:1124124811247C0011FC1124FDFC112411FC50205DFE507050A8712452208FFE
+47C2:10FC108410FC7C8410FC1000FDFE114A11FE50005CFC5048503070CC53028FFE
+47C3:1040108811FC7D08125213FEFC50118C162251C85C3251CC503071C050008FFE
+47C4:102013FE10207DFC102013FEFC0011FC110451FC5D0451FC510471FC50888FFE
+47C5:08047F7808403E402A7E3E482A48FF4809883FF00100FFFC110011F8290047FE
+47C6:11FC112411FC7D2411FC10A8FCA813FE10A850A85DFC502053FE702050208FFE
+47C7:0894091809DE7E94095A09DEFE9409FE289028D42EAA29162A2258004FFE8000
+47C8:109411D210907DFE101011D4FD5411D4101453E85C8A51CA509673E250008FFE
+47C9:11FC115411547DFC108011FCFE4411F4115451545DF4504451F4701450088FFE
+47CA:1020103E10207DFE112211F8FD2211FE112051525DAC525A52AA744850908FFE
+47CB:1040107C10847D0813FE1144FD92117C1100517C5D00517C5244727C54008FFE
+47CC:1048104C11FA7C4813FE10A8FDFA134A15EC514C5DEA514A51F6712250008FFE
+47CD:104011FC11247D94114C1124FDFC102013FE528A5D2453FE508070FC51048FFE
+47CE:108811DC10887DDE10881154FE2211FC110451FC5D0451FC510471FC50888FFE
+47CF:1124117412587BFE115412DAFBFE1082102053FE587050A85124722250208FFE
+47D0:13FE120012227ECC124413EEFE4412EE135452105E90529E549073FE50008FFE
+47D1:1020105010887D74120211FCFD5411FC100051FC5D5451FC5154710C50008FFE
+47D2:108813FE10887BDE125213DEF8A011FE112053FC5D2051FC512071FE51008FFE
+47D3:00007C0045FE442044207C201020102010205C205020502050205C20E0A00040
+47D4:00407E404240424042407E60085008484E444844484048404E40F04000400040
+47D5:00007DF8448844C844A87CA8108810505C505050502050205C50E08801040202
+47D6:00207C204420442045247D24112411245D245124512451245D24E1FC00040000
+47D7:00047C1E45F0451045107D10111011FE11105D1051105108510A5D4AE1860102
+47D8:00807C40444047FC44007C0011F011105D105110511051125D12E212020E0400
+47D9:00007900497E49124912791211D2171251125D12515251925922E022004A0084
+47DA:00007CFC4400440044007DFE104810485C485048504850485C88E08801080208
+47DB:00207C20442047FE44207C2011FC11245D245124512451345D28E02000200020
+47DC:00207C20442045FE45227D221122112211525D4A518A510251025D02E10A0104
+47DD:00007CF84488448844887D06120011FC10845C845048505050205C50E0880306
+47DE:00207C20442044A844A47CA21122112012245C245028500850105C20E0C00300
+47DF:0200077C384420442044207C3F90241024502C5C24502650255044B0449E8500
+47E0:00287C244424442045FE7D201124112411245D285128516851945D14E02C0044
+47E1:00047C1E45F0451045107D10111011FE11105D1051105108510A5D4AE1A60112
+47E2:00807C80448044FE45027D04122010205CA850A4512451225E22E02000A00040
+47E3:00207C284424442045FC7C20107010705CA850A8512451245E22E02000200020
+47E4:00407C204428440844087C48105411525D525160526050445CC4E144023C0000
+47E5:00007DF84408445044207C1013FE10625CA450A0512052205C20E02000A00040
+47E6:00087C3C45E0442044207DFE104010405C7C50A450A851285D10E22804440082
+47E7:00007C0045FC452445247D241124112411FC5D245124512451245D24E1FC0104
+47E8:00007DFC4504450445047DFC1120112011FE5D205120511051125D4AE1860102
+47E9:00207C20442045FC44207C20102013FE5C205040504050885D04E3FE01020000
+47EA:00047C1E45E0440044207C1011FE100410085C105020504050805D40E23E0000
+47EB:0100111009207FFE40029FF4101010101FF00100110011F81100290047FE8000
+47EC:00087C1C45E0450045007D00110011FE5D105110511051105D10E11007FE0000
+47ED:00807C80448044FE45407D401240107C5C4050405040507C5C40E04000400040
+47EE:00907C944492451245107F7E1510111011105D285128512851285D44E1440182
+47EF:00087C3C45E0442044207DFE102010205C2051FC510451045D04E10401FC0104
+47F0:00407C40449C450046407C4010BE118812885C885088508850885C88E0A80090
+47F1:00207C2047FE442044207DFC112411245D24512C507050A85D24E62200200020
+47F2:00407C20442047FE44407C88110413FE10925C905090509051125D12E20E0400
+47F3:00003EEE2222222222AA3E660822086628AA2E22282228AA284458004FFE8000
+47F4:00007DFE45004500457C7D00110011FE5D505152515451485D48E24402520460
+47F5:00287C244424442045FE7C20112010B25CB4506850A851245E22E02000A00040
+47F6:00207C2044A844A844A87D741222102010205DFC5020502050205C20E3FE0000
+47F7:0104790E493049204FE07920113E11641DA457245124512451245D24E1440384
+47F8:00207C20447C44C445287C90106011805C48504851FE50485C48E08800880108
+47F9:00047C1E45E0442245127C941080100811FE5C085088504850485C08E0280010
+47FA:00007EFC4284428442FC7E84088408FC4E84488448FC48004E48F04400820102
+47FB:00207C204450448845047E0210F810205C2053FE502051245D22E22200A00040
+47FC:00087C0C44EA440A44087DFE1048104811485D6851485148514A5D6AE3860102
+47FD:00407C2045FC444044907D0813FC10045D505150515051505E50E2520452080E
+47FE:00007BDE4842494A4884794A125214201C0053DE5052515250945D48E2540422
+47FF:00007DF84408440845F87C08100813FE5C205222517450A85D24E22200A00040
+4800:00207D2444A444A844207DFC1104110411745D545154515451745D04E1140108
+4801:0040789049084BFC49087A1014A417BE50825C0053FC50005800E00007FE0000
+4802:082008207EFC08301C682AA4C92208201FF010101FF0010011F81100290047FE
+4803:00007BFE482048204BFE7A221222133252AA5EAA537652665A22E222022A0204
+4804:00507C50445045FC45547D54115411FC5D545154515453FE5C00E05000880104
+4805:00007DFE4502451A45627D22112211FA5D225132516A51A65D22E12201FE0102
+4806:00007CFC448044F844807CF8108013FE11405D245128511051085D44E1820100
+4807:00007DFE4502450245FE7D10115211525D52517E511051525D52E252027E0402
+4808:0020782049FC482448247BFE1024102451FC5E22517450A85924E22200A00040
+4809:00207C1045FE450246047CF8108810885CF85080508050FC5C84E08400FC0084
+480A:00907C904490479E44907C901090139C10905C905090539E50905C90E0900090
+480B:00407C8045FC452445247DFC112411445DFC5090511053FE5C10E01000100010
+480C:00207C2247B444A844A87D2412A210405DFC510451FC51045DFCE10401140108
+480D:00007BDE4A424A424A427BDE1200123E53D25E12521453D45A08E21402240242
+480E:00007DFE4502450245FE7D0011FE11205D4451FE511251105EFEE210041009FE
+480F:00107BD448584A52498C7888110412FA10205C2053FE502050505C88E1040202
+4810:00007DFC450445FC45047DFC110411FC5C28502453FE50505C50E08801040202
+4811:002078204BFE485048887B2611FC10201C2053FE5000502051FC5C20E02003FE
+4812:00807C9E449245D244927C9E109211D25D52515E515251525DD2E022002A0044
+4813:00887C48445047FE44507C5011FC11545D54518C510451FC5D04E10401FC0104
+4814:00007C844448440045FE7C20104411A810305C585198503450525D90E0500020
+4815:009078924AD44A984A927AD2170E10201C2053FE507050A851245E22E0200020
+4816:00207D2044BE444244847F101110112811445C8250FC508450845C84E0FC0084
+4817:00207C4045FC450445FC7D0411FC11045DFC5028502453FE5C50E08801040202
+4818:00207C4045FC450445547D241154110411FC5C00511251D451185D52E192010E
+4819:00207C1045FE448444487DFE1102122410105DFE5040507C50445C84E0940108
+481A:0080F04097FC94049110F208203C23D0A290BA90A290A288A288B4A4C4D40892
+481B:0008783C4BC048044A44792811FC12201C2053FE5020512451245D24E1FC0004
+481C:00887C8845FE448844007DFE1088108810F85C8850F85088509E5DE8E0080008
+481D:00007CF84488448844F87C0011FC11045DFC510451FC51045DFCE05000880104
+481E:0014F012901097FE9410F49024D22492A7F2BC94A494A5C8BAAAE89A11A60042
+481F:08207E2008F8FF2814287F6A082AFF5608821FF010101FF0010011F83100CFFE
+4820:14507FFC245247CE80007FFC41043FF821083FF810101FF0010011F83100CFFE
+4821:00207C3C442045FE45227D3811E4111C11005D7C5144517C51445D7CE14402FE
+4822:0820FFFE08203FF824483FF800007FFE40029FF410101FF0010011F83100CFFE
+4823:00007BDE4A524BDE4A107A5211CE10001C8853FE5088508853FE5C88E1040202
+4824:00007DDC4554455445DC7C0011FC112411FC5D2451FC502053FE5C20E0200020
+4825:0108F10895489390911EF7D425642554A554BF54A5D4A548A548B554C46404C2
+4826:00807CEE454A444A45FA7C4E10AA110010FC5C84508450FC50845C84E0FC0084
+4827:00007BFC4A044A044BFC7A2212FC122813FE5E2052FC538452FC5C84E4FC0884
+4828:00807CF8450847FE45447D9211FE11005D7C5100517C51005D7CE244027C0444
+4829:0020F13C912097FE9010F01423FE2210A3F0BA54A254A2D4BB68E44A08960322
+482A:00447A844AEA4A4E4AA47AEE122213FE12445E8452EA524E52A45EEEE22203FE
+482B:03F0792E49E2492A49E4793413EA10321C1E53E050A2513450685CA4E3220020
+482C:00A0F74E915A952A922AF21C25DA280AA1EAB92AA1EAA22CA148B068C3880008
+482D:0108F10897CE91129124F7DE2552255EA7D2B91EA392A55EA940B114C1120122
+482E:012478A849FC48404BFE790813FC152251FC5D2051FC512059FEE00202AA0004
+482F:0040F0A0911092089DF6F0002EEE2AAAAEEEB800AFFEA922AFFEB922C92A0804
+4830:00887BFE48884BDE4A527BDE10A0109011FE5D2053FC552051FC5D20E1FE0100
+4831:03FE7A024BFE4A924A547A9212FE12AA52FE5F2252FA52AA5AFAE22205FA0004
+4832:102020207C5044507C8845247E12441045FCFC040C0814882450442094100810
+4833:102020207D2445247D2445247DFC44204420FD240D2415242524452495FC0804
+4834:102020107C1044007DFE44007C0444844484FC480C4814482450441095FE0800
+4835:104420447C4444847CBE45847E8444A44494FC940C8414842484448494940888
+4836:104020407C8044FC7D2046207C20442047FEFC200C5014502488448895040A02
+4837:105020507C5045527CD444587C50445844D4FD520C5014502492449295120A0E
+4838:102020207DFC44507C8845047EFA440047FEFC400C8015FC2404440494280810
+4839:102020107C1045FE7C2044247C4444F84412FC220C4415882410442894440982
+483A:108020407C5E45027D02457A7D4A454A454AFD4A0D7A154A25024502950A0904
+483B:102020107DFE45027C4844847D0244FC4404FCFC0C8014FC2404440494280810
+483C:102020507C8845047EFA44007DE2452A452AFDEA0D2A152A25EA4522952A0964
+483D:102021247924492479FC48007BFE480049FCF904190429FC488888502BFE1000
+483E:100023DE7A524BDE7A524BDE7A024A224A22FA221A522A4A4A8A8A022A0A1204
+483F:102021FC7D2445FC7C2047FE7C0045FC4504FDFC0D0415FC250445FC94880904
+4840:101021FE7C0045FE7D02457A7D4A45FE4400FCFC0C8414FC248444FC940009FE
+4841:111020907BDE48107A5E49827BDE48104BDEFA501BDE2A504BDE8A502A5212CE
+4842:080408040844FF4408447F4449447F4449447F4C0874FF440804080408040804
+4843:104010401040FE4011FC7C4454447C4454447C841084FE841104110412281410
+4844:100010F01090FE9010907C9054907C9054907C901090FE9210921112110E1200
+4845:108210921092FE9210927C9254927C9254927C921092FE921092111211021202
+4846:101010901090FE8810887D2455247E2254207C401048FE44108411FE10821000
+4847:1000100011FCFE0010007C0057FE7C9054907C901090FE9011121112120E1400
+4848:100810881050FE2010507C8855007C0854887C881050FE501020105010881306
+4849:104010201000FDFC10007C0054F07C9054907C901090FE9210921112110E1200
+484A:1008101C11E0FD0011007DFC55447D4455447D281128FF101110122812441482
+484B:102010201020FDFE10207C2054207DFC54847C881048FE501020105011881606
+484C:104010401040FC4013FE7C4054807C9054907D201120FE481244148411FE1082
+484D:102010201020FC2011FC7C2054207C2055FE7C201050FE501088108811041202
+484E:102010101010FEFE10827C8254827CFE54827C801080FE801080110011001200
+484F:100811C81048FE4810487DC855087D0855107DD01054FE541052105E12821100
+4850:102010101010FEFE10827D0454407C4854507C601040FE4210421042103E1000
+4851:100011FC1104FD0411047DFC55207D2055FE7D201120FD101112114A11861102
+4852:1000100011FCFD2411247D2455247D2455FC7D241124FD241124112411FC1104
+4853:11001100211C47C0810017C0257E67C8A54827C821082FE82108210821282110
+4854:10201020107CFC8411487C3054207C4855907C3E1042FDA41018101010601180
+4855:100011F81010FC2010247DA854B07CA855287D241222FCA01040100011FC1000
+4856:1000100011FCFE0010507C8855247C2054207DFC1020FE201020102013FE1000
+4857:7DF0111011901D52F20E05001FF001001FF011101FF011101FF00100FFFE0100
+4858:1080108010FEFD0211027EFA54AA7CAA54FA7CAA10AAFEFA108A100210141008
+4859:1020101010FCFE8410847CFC54847C8454FC7CA210A4FE981090108810C41082
+485A:1020104011FCFD0411047DFC55047D0455FC7C501050FE5010921092110E1200
+485B:10101010FEFE10107C7C545454547C7C545454547C7C1010FEFE101010101010
+485C:1020102011FCFC2010207DFE54887D0456227C2011FCFE201020102013FE1000
+485D:2040202023FEFA022504F900A9DEFA52AA52FB52249AF894211021122212240E
+485E:1FF010101FF010101FF01010FFFE11103FF8C1061FF011101FF01110FFFE0100
+485F:1020104010FEFC9210927CFE54927CA254FE7C481088FDFE1008100810081008
+4860:10201020103EFE2010207CFC54847CFC54847CFC1084FEFC1000104810841102
+4861:1110111211D4FD1811527D92552E7C4055FC7D041104FDFC1104110411FC1104
+4862:1040102011FEFD0211027DFE55007D0055FE7DAA11AAFEFE12AA12AA14A21086
+4863:100013FE1222FC2011FE7C2055FC7D2455FC7D2411FCFC2013FE102010201020
+4864:02003FD00260FFFE1C10EFF008100FF001007FFC11101FF01110FFFE01000100
+4865:1040102013FEFE0210507C8855247C5054887D0412FAFC881088108810F81088
+4866:21F820882070F98C2000FBDEAA52F98CAA52F82023FEF87020A8212426222020
+4867:1040108011FCFD0411047DFC55007DFE55007DFE1002FEAA12AA140210141008
+4868:082004407FFC0100FFFE04001FF0E1003FFC01001FF011101FF01110FFFE0100
+4869:1020102013FEFC2011FC7D0455FC7D0455FC7D0411FCFD0413FE108811041202
+486A:1020101011FEFD0211027DFE55007DEE55227DAA1166FD22116612AA12221466
+486B:10201220117CFCA410187CE657107D7E55107D7C1110FDFE1110111012FE1400
+486C:200021F82108F9F82108F9F8A800FBFCAA94FBFC2000F9F82090206021982606
+486D:1084104811FEFE1010FC7C2055FE7C40547C7CA41124FEFC1044104411FE1000
+486E:112411241224FCA411547D4A57927D0855087D28112EFD2811281158114E1180
+486F:1020104011FCFD24117C7D8C55547D2455547DFC1040FC2412A2128A14881078
+4870:0878FF4808863E782A483E30404881043FF801001FF011101FF01110FFFE0100
+4871:200023FE2200FA7C2244FA44AA7CFA00AAEEFAAA22AAFAAA22EE220023FE2000
+4872:100013DE1252FE5213DE7C0055FC7D2455FC7D2411FCFC2013FE102010201020
+4873:214021442158FBF02150F9D0A95EF9D4A954F95423F4F8142154223424142024
+4874:102011FC1088FC5013FE7C0055FC7D2455FC7D2411FCFC2011FC102013FE1000
+4875:104412241128FC7E10107C28574A7D1C55287D4C111AFD2A1148111012FE1400
+4876:201023C8227EFA402262FBD4AA00FA3EABC8FA48267EFA48224823C822482008
+4877:108813FE1088FC2011FC7C2057FE7C4054887DFC1000FDFC1154115417FE1000
+4878:108813FE1088FDFC11547D5455FC7C2854247DFE1120FD241114114A11961122
+4879:102011FE1020FDFE11027EFC54A47CFC54A47CFC1000FDFE10A210BC1160123E
+487A:208823DE2088F9DC2088FBDEA888FBFCA804F9FC2004FBFC204022A4228A247A
+487B:204021FC2124F994214CF924A9FCF820ABFEFA8A2124FBFE208020FC2104220C
+487C:200021FC2020FBFE2222F9ACA820F9ACA800FBEE22AAFAAA22AA22AA23EE22AA
+487D:252827BE2948FFBE2318FDAAA946FBFCAA04FBFC2204FBFC220423FC21082204
+487E:210821EC210AFFEA2928FBC8A93EFFE8A948FBE82A28FB682AA82BF42AB432A2
+487F:21FC202023FEFA2221ACF820A9ACF800ABBEFAAA23BEF80023FE212422AA27FE
+4880:104010401040FEFE2080290048F87E08081008200E40F8804902090208FE0800
+4881:100010FC1084FE84208428FC48847E84088408FC0E84F8844884088409140A08
+4882:104010201020FE0021FE280048047E84088408480E48F848485008100BFE0800
+4883:00407C2045FC44887C5043FE7C20A5FC24203C2010080810066001800E70F00E
+4884:101024FE42447E2800FE7E10427C7E10082008207EFC08301C682AA4C9220820
+4885:02001C7810081E7810081FF800003FFC20002FF820003FFE288848504A308C0E
+4886:000001FE7D00457C450001FE39542948296429422B082DFE4948412882080418
+4887:200011FE7D00457C450001FE39542948296429422B082DFE4948412882080418
+4888:3FFC20002FF820003FFE286849104A888C643FF8D55613901FF00A2009200FE0
+4889:111827C8244836D8254826C837D800003FFC20002FF820003FFC24484430860E
+488A:000023F81010102000400040F7FE104010401040104011401080280047FE0000
+488B:000023FC1090109000900090F090109010901110111012101410280047FE0000
+488C:0040404020402FFE00400040E7FC244424442444245424482040204050008FFE
+488D:00802040104017FE01000100F1F8110811081108120812081450282047FE0000
+488E:000023FC1090109000900090F7FE109010901110111012101410280047FE0000
+488F:001021101090109000100210F1101110101E17F0101010101010281047FE0000
+4890:000021F81108110801F80108F10811F811081108110817FE1000280047FE0000
+4891:0008203C13E0122002200220F3FE122012101212128A13261212280047FE0000
+4892:0080204017FC100001100208F414111010A0104010A011101208280047FE0000
+4893:0040202013FE1202040401FCF020102017FE10201020102010A0284047FE0000
+4894:004020A0111012080DF60000F00013F812081208120813F81000280047FE0000
+4895:002820241024102003FE0220F224122413A812281212121A14261442288047FE
+4896:0040204013F8104807FE0048F3F8104013F81040104017FC1040284047FE0000
+4897:0120412021202FFC09240924E9242FFC2924292429242FFC200050008FFE0000
+4898:0040202013FE120204140010F3FE1010111010901090101010101050282047FE
+4899:000023FC1204120403FC0204F20413FC1204120413FC100011081204280047FE
+489A:00004FFE204027FC044407FCE44427FC2040274020C020B02108220450008FFE
+489B:000023FC12041294030C0204F2F41294129412F4120412141208280047FE0000
+489C:03F8200811F8100803F80000F7FC144413F81248124812681250284047FE0000
+489D:000027FE10901090039C0204F204139C10901090109017FE1000280047FE0000
+489E:0210421022102F7C02100630E7382AD42A52329223102210221050008FFE0000
+489F:0420422020202FBE04480488E72825282510291029283544228450008FFE0000
+48A0:00404244224424A801100208EC06211021102FFE21102210221054108FFE0000
+48A1:029042902FFC229002F00200E3F82040204027FC21502248244450408FFE0000
+48A2:004040A0211022880C4603F8E20823F8220823F8220025FC250429FC50008FFE
+48A3:002020FE134C107007A001FEF00011FC100011FC100011FC110411FC280047FE
+48A4:03904E18221422100F7E0610E7382AB42A54325022902210221050008FFE0000
+48A5:000027FC1040127802400FFEF00013F8120813F8120813F8120813F8280047FE
+48A6:0080204017FC1040009005E4F24814A411F01010104017FC10401040284047FE
+48A7:000027BC108414A4029404A4F0501188162610C0131010641388103028C047FE
+48A8:02244224242429240154024AE6922A102250225E2250225022B0229E53008FFE
+48A9:00105F902210221E0FA404C4E4943FD420082F88289428A22FC250008FFE0000
+48AA:0078478020802FFC01200210E5E8292627F8240825E8252825E8241850008FFE
+48AB:072025FE1540157C0690057EF500157C1544157C1644147C1444144C280047FE
+48AC:003C47C020442224010807FEE4022A08220823BE24882AA8213E220854088FFE
+48AD:0208411027FC204003F80040E7FC20002440227C208422282C20245054888FFE
+48AE:000047FC20402FFE08420358E0402358200027FC244427FC244427FC50008FFE
+48AF:0244444820B0230C0C420244E4A823183C06240827BE28883528223E54088FFE
+48B0:07BC208414A4129404A40120F21017FC1A2013FC122013FC122013FE2A0047FE
+48B1:004027FC104013F8000007FCF4A417FC120813F8120813F8120813F8291047FE
+48B2:07BC24A417BC14A407BC0140F3FC124017FC1A4013FE129010601398280047FE
+48B3:00003C7C24442448244824502448244824442444244425684650444080400040
+48B4:0000077C78440848084808500848FFC808440844104410682050204040408040
+48B5:00007E7C004400480048FF50104810482044204444444268FF50414000400040
+48B6:0800087C084408487F48085018481C482A442944484488680850084008400840
+48B7:00003F3E212221242924252825242124FFE22122212221342128412045208220
+48B8:00003F3E2122212421243F28212421243F2221222122213427A8F82040200020
+48B9:00007FBE4022402440247F2841244124412241227F224034402840207FA00020
+48BA:0800087C49444948494849507F48084808444944494449684F50794000400040
+48BB:00007FBE4822482448247F2841244124412241227F224834482848207FA00020
+48BC:1200123E122212247F241228122412241222FFA2002212341128212020A040A0
+48BD:044004407FFC0440FFFE10102FE8C8260FE000001FF011101FF0100410040FFC
+48BE:0800287C28443E484848085008487F4814441444144414682550264044408040
+48BF:1000083E0822FFA480A411281024FFA42222222242223434082814202220C120
+48C0:1000107C3F4421484248BFD020482F48294429442D442A6828504A404C408840
+48C1:0000F7BE10A210A494A452A852A410A431A252A294A210B410A810A052A02120
+48C2:0800087C08447F4808483E5008487F4818441C442A442A684850884008400840
+48C3:2000207C3F444848884808507F48084808442E44284428682F50F04040400040
+48C4:0800087C144422484148BE50084808487F4408442A4429684950884028401040
+48C5:00003FBE202220242F24202820243FA4282228A22D222A34292848A04C208820
+48C6:00007FBE002224A449249228492424A400227FA20822083408280BA0FC200020
+48C7:08000A7C094408487F480850084849482A4408441C442A68C950084028401040
+48C8:00007CF8448844887CF800007DFC5524552455247DFC410041004D02710240FE
+48C9:20401248444420140860738020001FF010101FF000003FF821083FF820021FFE
+48CA:0800493E29222A2408247F28412441245D225522552255345D28412045204220
+48CB:010007BE782208A444A42528202404247FA20C221622153424A8442084200420
+48CC:0800041E7FD2401243945E14521852145FD252125212521A5554595094D00250
+48CD:0800083EFFA214242224492888A47F2449227F2249227F3408280A200C200820
+48CE:248024BE49229224492424A824A400247FA248A248A27FB448A848A07FA040A0
+48CF:1500153E152225242FA465286524A524252225223FE22034252824A028A03020
+48D0:2200227C7F4422482A4808503E482A482A442A44FF4408681450124022404040
+48D1:00003FBE20222FA42AA42AA82FA42AA42AA22FA222222FB4422843A09C200820
+48D2:0800083E7F2249247F240828FFA400247F22412249224934492814202220C120
+48D3:0000FFBE00227F24412441287F240024FFA2A2A294A2FFB488A888A08AA08120
+48D4:0800497C2A4408487F48415041487F4841447F44414441687F50004022404140
+48D5:00007FBE48227F2448247F28482448247FA200A2AAA2AAB4AAA880A005200220
+48D6:00007E7848487E4848787E0048FC48A47EA402A4AAFCAA80AA8082821482087E
+48D7:0800103E7F2241247F2441287F241024FFA22222492288B47F68082008200820
+48D8:0800493E2A22FFA480A43E28222422243E2208227F22083408280F20F0204020
+48D9:0400445E44527FD200147BD44A584A547BD24A524A527BDA4A544A50AB501490
+48DA:08007F3E4922FFA449247F2808247F2449227F221022FF34212872200C20F320
+48DB:0800083EFFA21C242B24C8A814242224492288A249222A34492888A028201020
+48DC:08000F3E08227FA448A44E287924472440225F2251225F3451285F2051A0BE20
+48DD:00003FDE205220523FD422342FD822943FF222122FD2385A2FD448504FD08850
+48DE:0000F7BE94A294A4F7A422281424FFA40822492249227F340928102020204020
+48DF:0000F7BE2122A524F7A46328B5A421247FA240A240A27FB440A840A07FA040A0
+48E0:1100111E7BD21112FFF411142A9844543FB2209220923F9A209420903F902090
+48E1:4100223EFFA208247F240828FFA4152464A22422FFA224343528E2A025A068A0
+48E2:2280229E27D2FA922294729427F8F81427D274526C52A7DA2454245027D02450
+48E3:2480151E7FD240521F1411147FD855544E527FD204127FDA0414FFF02A504530
+48E4:7BC04A5E7BD24A527BD414143FD86414BF9224123FD2001A3F9410900F10F090
+48E5:0020FFA0142014227F225524552855305720612041207F22412241227F1E4100
+48E6:0020FFA0142014207F7C5524552455245724612441247F24414441447F944108
+48E7:0020FFA8142414247F20553E55E055205720612041207F20411441147F0C4104
+48E8:0010FF901410141C7F70551055105510571E61F041107F12411241127F0E4100
+48E9:0020FE20282029FCFE20AAA8AAA8AAA8AEA8C2A882F8FE2282228222FE1E8200
+48EA:0010FE10281028FEFE10AA10AAFEAA92AE92C2928292FE9A82948210FE108210
+48EB:0010FE10281028FEFE10AA10AAFCAA44AE44C2448228FE2882108228FE448282
+48EC:0048FE4428442840FE5EABE0AA40AA44AE44C2488230FE228252828AFF068202
+48ED:0010FE1428122812FE10AAFEAA10AA10AE10C2288228FE2882288244FE448282
+48EE:0028FE2428242820FEFEAA20AA20AA3CAE34C2548254FE5482888288FF148222
+48EF:0000FFBC142414247F24553C552455245724613C41247F24412441247F7E4100
+48F0:0000FFBE142014207F20553E5522552257226122413E7F20412041207F3E4100
+48F1:0020FFA01420147C7F445584557455545754615441747F54410441047F284110
+48F2:0020FE2028402848FE84AAFCAA04AA48AE48C2FE8248FE4882488288FE888308
+48F3:0000FEFC28042804FEFCAA04AA04AAF4AE94C2948294FEF482048204FE148208
+48F4:0000FE4428282892FEAAAAC6AA82AAFEAE28C2288228FE288248824AFE8A8306
+48F5:0000FEFE28482848FE78AA48AA48AA78AE48C248824EFEF882088208FE088208
+48F6:0008FE1C28702810FE10AAFEAA10AA10AE10C27C8244FE4482448244FE7C8244
+48F7:0010FE502850287CFE90AA10AA10AAFEAE10C2388238FE5482548292FE108210
+48F8:083813C0304057FC9040104013F81000FFFE04403FF82848303827C820083FF8
+48F9:0050FE5828542894FE90AA9CABF0AA94AE94C2948298FE9882948294FEAC82C4
+48FA:0000FE7C28442844FE7CAA00AAFEAA82AE82C2FE8282FE8282FE8282FE8A8284
+48FB:0010FE1028282844FE92AA08AA7CAA04AE08C210827CFE4482448244FE7C8244
+48FC:0020FE1028FE2800FE00AA7CAA44AA44AE7CC2108254FE5282928210FE508220
+48FD:20003E7C48440844FF441444227C4000FFFE04403FF82848303827C820083FF8
+48FE:0020FE1028FE2882FF04AA7CAA44AA44AE7CC2448244FE7C82448244FFFE8200
+48FF:0000FE7C28102810FEFEAA10AA10AA50AE20C2FE82AAFEAA82AA82AAFFFE8200
+4900:0044FE4429FE2844FE54AA10ABFEAA20AE40C27E82C2FF4282428242FE7E8242
+4901:0048FE4829FC2848FE78AA48AA78AA48AE48C3FE8280FEA882C48280FEFE8200
+4902:0088FE882BFE2888FE88AAF8AA88AA88AEF8C22083FEFE7082A88324FE228220
+4903:0040FE2029FE2800FE84AA48ABFEAA00AEFCC2848284FEFC82848284FEFC8284
+4904:0000FEFE28102820FEFEAAAAAAAAAABAAEAAC2AA82BAFEAA82AA82AAFEFE8282
+4905:0010FE1028282844FE82AA7CAA00AAE2AEAAC2AA82EAFEAA82AA82E2FEAA82A4
+4906:0010FED42848294AFE84AA84AB02AAF8AE20C22083FCFE2082508248FE848304
+4907:0020FE1028FE2882FE28AA44AA92AA28AE44C282827CFE0482288210FE2882C4
+4908:0044FE82297C2820FE40AA7CAA04AA28AE10C2FE82AAFEAA82AA82AAFFFE8200
+4909:0010FE0C282428AAFEB0AB24AA64AB9CAE00C2FE82AAFEAA82AA82AAFFFE8200
+490A:0044FE4428FE2844FE00AAFEAA44AA44AE7CC244827CFE44824E82F4FE048204
+490B:4408240C280AFE0829FE2808FE08AAEAAAAAAEAAC2ECFE0C822A82CAFE168222
+490C:0020FE2028502848FEA4ABFEAA84AAFCAE84C2FC8280FEFC83448344FE7C8244
+490D:0088F88823FE2088F888A8F8A820ABFEDA228B328AAAFB768A228A22FA2A8A24
+490E:00FCFE28281029FEFE52AA94AB50AA20AEFEC2AA82C6FEBA82AA82BAFE828286
+490F:0028FEEE282828EEFE28AAEEAA28AA06AEF8C21082FEFE1082FE8210FE508220
+4910:0000FBDE208822A8FBFEA988AADAACA6D9F889088908F9F889088908F9F88908
+4911:0028FE28287C2828FE28AAFEAA10AA7CAE54C27C8254FE7C82008228FE448282
+4912:0124F92422AA23AEF924AAAAABAEA924DBFE89108914F9148A8A8A4AFA168C22
+4913:0048FE4829FE2848FEFEAA82AB7CAA00AEFEC22082D2FE2C82D8822CFECA8230
+4914:42043FD88A904F9E2A945FD48224FFFE04803FF82488287830083FF820083FF8
+4915:0124F974225822DAFBFEA954AADAABFED8A288208BFEF87088A88924FA228820
+4916:01FCF90421FC2104F9FCA888A9FCA888DBFE88888924FAAA887088A8F9248860
+4917:08207F7C14C47F3822D63E3822507F7C0810FFFE04403FF8284837B820083FF8
+4918:0148F94C22AA2008FBFEA948AB68A94ADB6A894A8B6CF94C896A8B8AF8168822
+4919:00F8F90821F02010FBFEA8C4AB28A8D4DB3288D08A28FFBE8AAA8FBEFA8A8FBE
+491A:00003DFC2524252425FC3D24252425FC24203C2025FC24202420442057FE8800
+491B:10041004288424844284BC8410841084FE8C109494E4588450041E04F0044004
+491C:102010202820243C41E0B82010201020FC3E13E09420582250221C22E01E4000
+491D:10001040299E25124112B91211121112FD121112955A599451101C10E0104010
+491E:10401050284824484040B9FE10501050FC5010509490589050921D12E10E4200
+491F:1000100029FE25024302BC0010781048FE4810489448584A504A1E8AF0864100
+4920:10101010281024904290BC90109E1090FE9010909490589050901E90F1FE4000
+4921:10201020282025FC4124B92411FC1124FD24112497FE590451041D04E1144108
+4922:100011FC290425044104B9FC10401040FDFC10449444588450841D04E2284410
+4923:1008103C29E024204124B8A410A81020FDFE10209420582050201C20E0A04040
+4924:10201010281025FE4220BC24104410F8FE1210229444598850101E28F0444182
+4925:1040104028FC25044208B9FE1100117CFD4411449554594851421E42E23E4400
+4926:10A810A428A42520412EBBF015201124FD2411249528591051321D4AE1864102
+4927:1000100029FC25044104B97411541154FD5411549574590451041DFCE1044000
+4928:1004101E29E025004106B97811501150FD5211549548594851441E54E2624440
+4929:1020101029FE25024000B81C10E01020FC20103E95E0582050221C22E01E4000
+492A:100010F8288824884088B88811261220FDFE1020947058A851241E22E0204020
+492B:102011242924252441FCB82010501088FD441222942059F850081C10E0104020
+492C:201022105110491084547A5222522090F81021142E04B20862083A10E22000C0
+492D:21842068503048C88304784023FE20A0F92023FC2D24B12461343928E0200020
+492E:101010102890249E4090B89013FE1000FC1010929492591452081C10E0604380
+492F:100213E2294425484140B942114213E4FD4811409542594251441E44E2484450
+4930:108010807DFC124410481CA0E11006C81830EFEE01003FF809200540FFFE0000
+4931:10201124292425FC4000B80C11F01100FD0011FE9510591051101E10E2104410
+4932:1020102029FC24204020B82013FE1048FC48114C954A5A4A50881C88E1284210
+4933:2080204057FE492081207A3C22442664FA9423482A48B23062203A50E2880306
+4934:200021FC5008481082227AAA22722222FA7222AA2B26B2A262423A02E3FE0002
+4935:109010902890279E4090B8901090139CFC90109094905B9E50901C90E0904090
+4936:102010202BFE24504088B924122211FCFD2411FC952459FC50221C22E01E4000
+4937:200023FE52004AFC82847AFC228422FCFA2023FE2A48B2C862303A48E28403FE
+4938:208020FC510449F880087BFE204020A2FB3420582894B33460523890E3500020
+4939:104010202BFE262240A4B92810501088FD0410F89488588850501C20E0D84306
+493A:100010022BDC24904090B91011DE1354FD541154955459D451541C24E0244044
+493B:104010402BFE248041FCBA2015FE1000FDFC110495FC590451FC1D04E1144108
+493C:2040208051FC490481FC790421FC2020F83223B428A8B12861243A24E4A20040
+493D:100011FC295425544154B9FC102010A8FCA41124942058A850A41D24E0204020
+493E:101E11E0282225124094B880102011CEFD02110295CE590251021D02E1FE4102
+493F:108013DE288A25CA408ABBD210A61008FCF0102095FC582053FE1C20E0A04040
+4940:10201124292425FC4020BBFE10001020FDFC1124952459FC50201C24E3FE4102
+4941:200023FC500848D080207BFE228A2252FAFA22222A22B3FE62223A22E3FE0202
+4942:200023FE52024CFC800079FC204020A4FB3820582894B33460523890E3500020
+4943:104010402BFE26924088B9FE13101510FDFE1110951059FE51101D10E1FE4100
+4944:200023FE52004A4882487AFC22482248FBFE22002AFCB28462FC3A84E2FC0484
+4945:01007FFC01007D7C11107D7C11101CFEE10006C01830EFEE01003FF80920FFFE
+4946:0100FFFE04407C7C04403C7804407D7C06C01830EFEE01003FF811100920FFFE
+4947:1020101029FE25024102B9FE110011EEFD2211AA9566592251661EAAE2224466
+4948:2088208853FE488880247BFE20502088F904228A2888B3FE60883888E1080208
+4949:100013FE2A02244040F8B908121011FCFD24112495FC585050581C96E112420E
+494A:102013FE282025FC4020BBFE100011FCFD0411FC950459FC51041DFCE0884104
+494B:1020101029FE240042FCBC8410FC1000FEFC10089410585050201E00F1544252
+494C:020001007FFC40043C7824483C7824483D7806C01830EFEE01003FF80920FFFE
+494D:08207E2008F8FF2814287F6A082AFF56098206C01830EFEE01003FF80920FFFE
+494E:23FE220052FC4A0083FE7A9422A822C4FA0022FC2A84B2FC62843CFCE484088C
+494F:2280228E54EA494A804A724A25EA2C4AF44A256AA54A754E25683788C4080408
+4950:00207E7C14C40838FEC62A2048FCA844118C06C01830EFEE01003FF80920FFFE
+4951:102010202BFE24A840A8B97412221070FCA811469478588851501C20E0504180
+4952:7CF8048804F87C2041FC7D2405FC04282BFC16C41830EFEE01003FF80920FFFE
+4953:1088108829FE248840F8B88810F81088FDFE108895245AFA50201C20E1FE4000
+4954:200023FE5050485083FE7A52225223FEF92420A82BFEB07060A83924E6220020
+4955:2108210855484B90811E77D425642554F5542754A5D4754825483554C46404C2
+4956:108810502BFE245041FCB954118C1174FD0411FC94205BFE50501C88E1044202
+4957:2108210857C84908811E7B9220242380F80827C82908B10865943954E1240342
+4958:10881088295426224088B88811541222FDFC1104950459FC51041D04E1FC4104
+4959:2044272455284D7E85107630254A251AF52C254CA51A762A24483408C4280410
+495A:3FF820082EE82AA82EE82AA82EE82AA82FE8228824483BB8210A4FEA45469FF2
+495B:108013DE288A25CA408ABBD210A61040FC8811F094245BFE50221D24E2A24040
+495C:200023DE52524BDE82527BDE22222222FAFA22222A72B2AA63263A22E22A0204
+495D:202023FE52504BFE82527BFE229422D8FA9222CE2A00B28462983CE2E482087E
+495E:2108220827C854508FDE746427D42214F91427D42A14B3C862483C54E55408A2
+495F:2200227C52444A7C87447A7C2220237EFA9226522A6AB242627A3A02E2140608
+4960:2088208853FE48888014781223FE2210FAF422142AF4B2A862AA3AFAE2160422
+4961:2114255455544DFE855477D4245C2440F77E2510A5FE751025383554C5920910
+4962:0810FF7E08107F7C41047F2822101F28E14406C01830EFEE01003FF80920FFFE
+4963:2C7844486C4844867D7800487C301048FD8406C01830EFEE01003FF80920FFFE
+4964:11FC10202BFE262241ACB82011AC1040FCFC110496F4589450F41C8AE082407E
+4965:202023FE5088485083FE7A5023FC2254FBFE22542BFCB25062D83D54E6520850
+4966:202021FE54404AFC81107AFE200026FCFA8422FC2A84B2FC62843A8CE50008FE
+4967:2040207C50404BFE820279FC20A82154FA8821FC2A8AB0F8608838F8E08800F8
+4968:200023DE52524BDE82527BDE220222FAFA8A22FA2A02B2FA628A3AFAE2020206
+4969:228822A856A84BF0801E722425D42C14F41425D4A554754825683554C6140422
+496A:200023FE52024BFE82027BFE21082252FB9C21082A52B3DE60003AA4E2520452
+496B:2110211457D249108FFE729024502FF4F49427F4A49477E8248A37FAC4260042
+496C:108813FE2888242443FEB82011FC1124FDFC112495FC592450081DFEE0884058
+496D:14141010FEFE10105454383854549292313006C01830EFEE01003FF80920FFFE
+496E:200023FE50504BFE82527BFE200023DEFA9223D22A52B3D2629A3A94E3D00010
+496F:200023FC52944A9483FC7910225223DCF81223CE2A40B3D2625C3BD0E25202CE
+4970:2040202057FE4900810079FC20002088FBFE22AA2AAAB3FE608838AAE3FE0022
+4971:202023FE52024840819C790421DC2104F9FC21002BFEB40262AA3AAAE4140008
+4972:200827E854084DC8855E755225E42400F7E826A8A6A877E8241437F4C0240042
+4973:23FC204051F8490881F8790827FE2442FAA4228A2C7AB08061F83A88E070038E
+4974:2020222253FE489081FE7B1025FE2110F9FE211029FEB10063DE3A52E2720206
+4975:20102010577E4D1085FE754425EE2744F56425DEA50075FE2728352AC04A0086
+4976:200023FE52224ACC82447BEE224422EEFB5422442A10B210625E3A50E25005FE
+4977:244227722AA2511A8BEA722A23EA222AFBEA222A2BEAB14A67F23942E24A0444
+4978:F7FC124817FCFC4686ECF55416EC155457EC26C41830EFEE01003FF80920FFFE
+4979:208023DE508A49D280A67BD0209C2050FBFE20502AAAB3FE62523AAAE3FE0002
+497A:200023FC3810211041107910A21023FEF8302050209021102A10341020500020
+497B:100010003DFC20204020BC20102013FEFC5010501050109014921912120E0400
+497C:108010803C8020FC4154BE5410541094FC941124122410441444188411280010
+497D:204020483A44224043FE7880A08020FCF9442144214822502A20345028880306
+497E:200023FE3A022484408078FCA0802100F9FC2004200423F42804300420280010
+497F:1008101C3DE021004100BDFE11201120FD3C11241124112415241A4412540488
+4980:200027BC3884208444A47A94A2942084F98C229424A420842884308422940108
+4981:2100211E391227D241147914A7D82114F91227D22112211A2914321022100410
+4982:204020203BFC220442047BFCA20023DCFA44235422CC22442ACC3554244408CC
+4983:208820883BFE20A8402279FAA0242028FBFE204020FC21842AFC348420FC0084
+4984:102013FE3C2021FC4124BDFC112411FCFC2213FE1050109415881AA814C40082
+4985:208820503BFE202041FC7820A3FE2124F8A823FE200021FC2904310421FC0104
+4986:23DE22523BDE225243DE78A0A1FE2320FDFC212021FE200029FC30882070078E
+4987:00103E50205020483C8820A43D2422422040FE8010F820084408FE0802500020
+4988:00403E40204020403DFE20403C40204020FCFE90109021104510FE1002FE0000
+4989:00003EFE20AA20AA3CAA20AA3CAA20AA20AAFEAE10C220824482FEFE02820000
+498A:00203E202020203C3C2020203DFE20002020FE2010A820A44522FE2202A00040
+498B:00883C8820883BD0209E3BE4209427D4F91421D421544948F9484A5402D40422
+498C:00007C7C44447C7C44447C7C410441044FE44104410441045FF4400440144008
+498D:7C7C44447C7C44447C7C4004440447F4480457C4418442044414441443F4400C
+498E:7C7C44447C7C44447C7C40044FC440045FE4450445044504492450E440144008
+498F:00007C7C44447C7C44447C7C410442844464581C444444444444484450544008
+4990:00007C7C44447C7C44447C7C400440E45F0441045FE441047FFC410445144208
+4991:7C7C44447C7C44447C7C420442044FC4424442445FF442044504448448545008
+4992:7C7C44447C7C44447C7C40045FE44104420447C44C445444444447C444544008
+4993:7C7C44447C7C44447C7C4104410441F4410441044FE4482448244FE440144008
+4994:7C7C44447C7C44447C7C400440044FE448244FE448244FE440045FF44004400C
+4995:7C7C44447C7C44447C7C4004482444445FF4444444447FFC444448444844504C
+4996:7C7C44447C7C44447C7C410441045FF441044FE440044FE448244FE44824400C
+4997:7C7C44447C7C44447C7C410442044FE44AA44AA44AA44AA45FF4400440144008
+4998:7C7C44447C7C44447C7C40044FE448244FE448244FE4491448A44A444C24481C
+4999:7C7C44447C7C44447C7C410441045FF441047FFC40445FF44844444441544088
+499A:7C7C44447C7C44447C7C400440E44F0441045FF441044FE448244FE440144008
+499B:7C7C44447C7C44447C7C420447C448845FE441245FF441244FE441044304400C
+499C:7C7C44447C7C44447C7C40045FF442044FE444247FFC40044FE448244FF44008
+499D:7C7C44447C7C44447D7C41044FE441045FF442844AA44A945494448449944008
+499E:7C7C44447C7C44447C7C400449F44444504449F44444484458444BFC4804400C
+499F:7C7C44447C7C44447C7C410449244924555441044FE4410441045FF44004400C
+49A0:7C7C44447C7C44447C7C40045FF44204451459A44AC445A45A9444945A84410C
+49A1:7C7C44447C7C44447C7C41045FF4501447C4444447C4440447E4442447E4400C
+49A2:7C7C44447C7C44447C7C5084488463E45084488457F47104522457F45014400C
+49A3:7C7C44447C7C44447E7C41045FF4482444447FFC40044FE4482448244FE4400C
+49A4:7C7C44447C7C44447C7C40044EE44AA444444AA451044EE44AA444444AA4510C
+49A5:7C7C44447C7C44447C7C4004444444445EF444444EE45554644C444444544008
+49A6:7C7C44447C7C44447C7C410442844C6477DC41045FF4492445447FFC4004400C
+49A7:7C7C44447C7C44447C7C400442044CE448244EE448244FE4428444945874400C
+49A8:7C7C44447C7C44447C7C41045FF441044FE449244FE449244FE445444924410C
+49A9:7C7C44447C7C44447FFC48244FE448244FE448244FE444044FC4544443945C68
+49AA:7C7C44447C7C44447FFC48244FE448244FE444044FF459146A944FD44054402C
+49AB:7C7C44447C7C44447C7C400444445FF4444441044FE449245FF442844444482C
+49AC:7C7C44447C7C44447C7C44045EF444544E5444545EB445045FF442844444482C
+49AD:7C7C44447C7C44447C7C40E44F0441045FF44544492457D4444447C4445447C8
+49AE:7C7C44447C7C44447D7C4FE441044FE442045FF444444FE4545C67C4444447CC
+49AF:7C7C44447C7C44447C7C40047F444844527C5F9444545F54442447547C94510C
+49B0:783C48247A3C4BA47CBC4FC4554447C445444FE449244FE449244FE4411440F4
+49B1:7C7C44447C7C44447C7C41E45E2445444F8448844FC448444FE448245524656C
+49B2:7C7C44447C7C44447C7C420447C448445FF46A244C944FF448044BE44A2453EC
+49B3:7C7C44447C7C44447C7C520457746D54775455646F547C545654556466C4444C
+49B4:7C7C44447C7C44447FFC4AA44FE441044FE441045FF444444FE441045FF4410C
+49B5:7C7C44447C7C44447C7C40045FF449245FF4711C5BB455545BB455545BB4511C
+49B6:200013FC1004420447C4484450844FE441245FF441244FE44104450442144008
+49B7:200013FC10044004410449244924555441044FE4410441045FF4400440144008
+49B8:200017FC00044FE449244FE449244FE441045FF45114515457D450545034400C
+49B9:00207C2044204820482050204BFE482044204420442068205020402040204020
+49BA:00007C0045FE4820482050204820482044204420442068205020402040A04040
+49BB:00007DFC440448084810502048204BFE44204420442068205020402040A04040
+49BC:00407C4044404BF8484850484848484847FE444044A068A05110411042084406
+49BD:00007DF844084850482050104BFE482244244420442068205020402040A04040
+49BE:1040104020807C88450447FE7C02409040907C90449044907D124512020E0400
+49BF:00207C204420482049FC512449244924452445FC452468205020402040204020
+49C0:00407C40444048404BFE5040488048904490452045206A485244448441FE4082
+49C1:00807C80450049FC4A04540449E449244524452445E469245004400440284010
+49C2:00007DFC444448444844504448944888450044FC448468845084408440FC4084
+49C3:00007C0045FC4924492451244924492445FC4524452469245124412441FC4104
+49C4:00807C8044F849084B1054A0484048A04518460645F869085108410841F84108
+49C5:004078404BFC484053F8504863F852404BFC4844485468A850A0411042084406
+49C6:00907C90449048904BFC509048904890449047FE440068905088410841044204
+49C7:0040782048204BFE5040504060A050A249A44A984C906888508440A240C04080
+49C8:00007BFE48505050505061FC5154495449544954695C51844104410441FC4104
+49C9:00007DFC4524492449FC5124492449FC4420442045FC68205020402043FE4000
+49CA:00207D20452049FC4920522048204BFE4400440045FC69045104410441FC4104
+49CB:00007DFC4504490449FC5104490449FC4504450445FC6850509040924112420E
+49CC:0008783C4BC0504452246128510048404BFE4888690853904060405041884604
+49CD:00887C8445024A224820505048884904460245FC450469045104410441FC4104
+49CE:00007CFC4484488448FC500049FE4902450245FE4502690251FE4102410A4104
+49CF:00407C4044FC48884950502048D84B2644F8442044F8682053FE402040204020
+49D0:00407C2047FE480049FC510449FC480045FC440844106BFE5020402040A04040
+49D1:004078204BFE52025404600053FE482048204920693C512042A04260443E4800
+49D2:00207C2044204BFE482051244924492446AA447044A868A85124422244204020
+49D3:00007DFC452449244974512449FC490445744554455469745104420442144408
+49D4:00207C20445048884944522249F848084450442044A46A82528A428A44784000
+49D5:00147812481057FE5010601053D24A524A524A546BD4500840EA471A42264042
+49D6:00487C44445E49E048285012486A49964448445E45E0682450284012406A4186
+49D7:01007D0045FE4A004DFC510449FC490445FC448044FC69085290406041984606
+49D8:010079F84A0853F0501067FE508049444E6848B06928566840A4412246A04040
+49D9:00407A484A48524853F8604050A049104A884C86689052A84294449442804100
+49DA:00207C1045FE480048FC508448FC480045FE4502457A694A517A4102410A4104
+49DB:004078204BFC5108509063FE52024C4448204BFC688050F84088410841284210
+49DC:00207C1045FE4910497C511449FE4914457C4510457C694451444244427C4444
+49DD:00207D24452449FC482053FE4800482045FC4524452469FC5020402443FE4102
+49DE:00007DFE452049FC492051FC4920492045FE440246AA6AAA52AA420240144008
+49DF:001E7DE04422491248945080482049CE4502450245CE69025102410241FE4102
+49E0:00207BFE482051FC512461FC512449FC48224BFE680853FE4108408840284010
+49E1:00107DFE4510497C491451FE4914497C4510457C4554697C5154427C4254444C
+49E2:00007BFE4A00527C52446244527C4A004AEE4AAA6AAA52AA42EE420043FE4000
+49E3:00007DFC445049FC4954515449FC480045FC440047FE682050A8412442A24040
+49E4:00507A524954505053FE608850504BFE482049FC682053FE4050408841044602
+49E5:002078204BFE502051FC612451FC492449FC48226BFE5042402442A2428A4478
+49E6:000E7BF048445224510863F852084BFC4A044BFE6A0252AA42AA450244144808
+49E7:010478884BFE482051FC502063FE5054499248904BFE689050D4438A409641A2
+49E8:00507A524954485053FE5088605053FE482049FC48206BFE50A8412446224020
+49E9:00087B884888511057DE629452A44B944A944B946A9452C84388469440A440C2
+49EA:002078104BFE4A1052FE5254625452BA4A284A444A826A2052FE4444443848C6
+49EB:00207BFE480051FC510461FC50004BFE4A0249FC684053A440D8433440D24330
+49EC:004078204BFE520251FC6148525049FC4B0449FC690451FC410441FC40884104
+49ED:004078804BFE5222528A625253264A524AAA4BFE6840502442A2428A44884078
+49EE:00207BFE4A2251FC502060F8502049FC482049FC695451FC404042A4428A447A
+49EF:01F07A104FFC520453FC622453B84A2249FE4A106FFC524443FC40D0414A463E
+49F0:0406E438AF08A910B224AFBCCA88AA94AFBEAA8AAA88AFACC02A954A95488018
+49F1:20502048208020FEFD90269024FC2490249024FC25902690449040FE80800080
+49F2:00507C48108010FE1190129010FCFE90109010FC10901090109010FE10801080
+49F3:08500848088008FE49904E9048FC4890489048FC48904E905890E0FE00800080
+49F4:105010481080FEFE11901290FCFC0490049048FC28901090289044FE82800080
+49F5:105010481080FEFE9390129010FC2890289028FC28904A904C9088FE00800080
+49F6:090008801FFC30805FF890801FF810801FFC12000100FFFE0000082010102008
+49F7:205020483C8044FEA990129028FC4490829030FC08900090609010FE08800080
+49F8:10501048108010FEFD90129010FC10907C9044FC4490449044907CFE44800080
+49F9:010000803FFE2250224824FE24902D9036FE2490249024FE4490449084FE0480
+49FA:082808240840FF7E10C81148207E3E486248A27E2248224822483E7E22400040
+49FB:08500848148022FE4190BE9000FC00903E9022FC2290229022903EFE22800080
+49FC:1050504850807CFE5190929010FCFE90009000FC7C904490449044FE7C804480
+49FD:0628782408404A7E2AC82D48087EFF4818481C7E2A482A484848887E08400840
+49FE:10501048284044FE82907D9012FC1090FE9010FC10907C90449044FE7C804480
+49FF:242824247E40247E24C8FF48007E7E484248427E7E48424842487E7E42400040
+4A00:20501048288044FE9190129054FC38901090FEFC10903890549094FE10801080
+4A01:7E20243E1848FFA829104A28984609001FFC30805FF890801FF810801FFC1000
+4A02:0620382008A47EA819202C504A8809041FFC30805FF890801FF810801FFC1000
+4A03:00287E2442407E7E42C87F48087EFF488148107EFF4822486448187E2440C240
+4A04:082814242240497EBEC80548087EFFC814487F7E5548634841487F7E41407F40
+4A05:10281024FE40107EAAC84548827E7D4844487C7E44487C481048547E92403040
+4A06:49202A3E7F4849485DA86B10492841460A001FF831005FF091001FF011001FF8
+4A07:285024487EFEC9907EFC48907EFC48907EFE40807DFC0488285010202858C586
+4A08:20501048FE8082FE7D90569098FC7C90C4907CFC44907C9044907CFE28804480
+4A09:002877245540777E55C87748557E77482248557E1048FF482248647E1C40E340
+4A0A:08801FFC3080DFF810801FFC14283F7E64C8BF7E24483F7E10041E7C12442244
+4A0B:00003FF801007FFE41029D7401001D70000000F03F00020003F87E02020201FE
+4A0C:00003FF801007FFE41029D7401001D7000001FF000007FFC044008441044603C
+4A0D:3FF801007FFE41029D7401001D70000008203FF808200820FFFE102020204020
+4A0E:3FF801007FFE41029D7401001D7000007F1001107F1040207F2401420AFE0442
+4A0F:3FF801007FFE41029D7401001D704080208009FC12042448E04020A023182C06
+4A10:3FF801007FFE41029D7401001D70010006C01830E7CE00001FF010101FF01010
+4A11:3FF801007FFE492284140100FFFE01007FF801083FF821003FFC0284044C1830
+4A12:3FF801007FFE41029D7401001D7000007EFC224412240A14122422444A940408
+4A13:3FF801007FFE41029D7401001D7000003FF8200827C8244827C820083FF82008
+4A14:00003FF801007FFE41029D7401001D70000011100920FFFE044008423042C03E
+4A15:3FF801007FFE41029D7401001D70000011FC482020200BFE7020102010A00040
+4A16:3FF801007FFE41029D7404007FFC08001FF028104FF088100FF0081008500820
+4A17:3FF801007FFE41029D74000000FC7F00121009203FF00040FFFE010005000200
+4A18:3FF801007FFE41029D7400001FF010101FF010101FF010101FF004421842E03E
+4A19:3FF801007FFE41029D7401001D700000203813C08040484017FEE040204023FC
+4A1A:3FF801007FFE41029D7401001D7008001FF86488090836280110489487F20000
+4A1B:3FF801007FFE41029D7401001D700000100CFDF0110039FE5510921012101410
+4A1C:3FF801007FFE41029D7401001D7000003E7C22443E7C22443E7C22444A948508
+4A1D:3FF801007FFE41029D74000001003FF80100FFFE10101FF010101FF010101030
+4A1E:3FF801007FFE41029D74000001F87F0001001FF011107FFC412441F45E144008
+4A1F:3FF801007FFE41029D7401001D702000104083F8404017FC2040E3F820402FFE
+4A20:3FF801007FFE492284141FF010101FF010101FF008001FFC2104528414541FE8
+4A21:3FF801007FFE41029D7401001D7000001FE0004051944924551442047FFC0004
+4A22:3FF801007FFE41029D7408207FFC08200FE008200FE00820FFFE124014201FF8
+4A23:3FF801007FFE41029D7408207FFC08200FE001003FF821083FF80100FFFE0100
+4A24:3FF801007FFE41029D7401001D702040104007FCF44417FC144417FC280047FE
+4A25:3FF801007FFE41029D7409001FF831005FF091001FFC10003FF0082007C0F83E
+4A26:3FF801007FFE41029D7402003FF808207FFC41043FF8040007F0081010502020
+4A27:3FF801007FFE41029D7401001D7020201050FE880526441028FC2E08F0704008
+4A28:3FF801007FFE41029D740080210013F80208F3F8120013FC120413FC280047FE
+4A29:3FF801007FFE41029D7401001D7020201020FDFC092411FC392455FC90201020
+4A2A:3FF801007FFE41029D74000011FC112411FCFD2411FC10201DFCE02043FE0000
+4A2B:3FF801007FFE41029D74000001007FFC11102BA845641918E3E60E4001800E40
+4A2C:3FF801007FFE41029D7401001D702000111081104FBC1110E3B8255429122110
+4A2D:00107F100854FFB888906B7C08446B44007C7E440044FF7C104422447F540148
+4A2E:3FF801007FFE49229414FEFE10107C7C1010FEFE10103FF800081FF800083FF8
+4A2F:3FF801007FFE41029D7400207BFE482051FC612451FC492449FC687050A84124
+4A30:3FF801007FFE49228414211017FC911041F048400BF81248E3F820402FFE2040
+4A31:3FF801007FFE41029D74120027FC42088BF8120833F8510093F8151010E0171E
+4A32:00207F20083CFFC488886B7E08526B52007EFF90082C7F2A5528554A554A4386
+4A33:3FF801007FFE41029D7400003EF822883EF822883EF822883EF814502692450E
+4A34:3FF801007FFE41029D740000550836087F7E14087F4808283E2808080F287810
+4A35:3FF801007FFE4922A7FC10A017FC84A447FC520813F82208E3F8204027FC2040
+4A36:3FF801007FFE41029D7408201FF000104FE44AA449647FFC0440FC7C24444444
+4A37:3FF801007FFE41029D74000011087BCE11083B88557EBF9220943F88209421A2
+4A38:3FF801007FFE41029D7400187BE0495053F8604053F8480849F86840529444F4
+4A39:3FF801007FFE41029D74108011FC228828706B8EA9FC29AC297429FC28202154
+4A3A:3FF801007FFE49229FF404400FE000007C7C1010FEFE92925454FEFE28287C7C
+4A3B:7C7C1010FEFE92927C7C54547C7C00007C7C1010FEFE92927C7C54547C7C0000
+4A3C:104411FEFE5410487CFE1190FEFE00907CFE44907CFE44807DFE4444543849C6
+4A3D:04407C7C04403C7804407C7C044004403FF0001000103FF02000200420041FFC
+4A3E:010000803FFE2000212021202F3C212021202738212021204F3C412081200120
+4A3F:00003FF801000200FFFE08203018C44604407C7C04403C7804407C7C04400440
+4A40:04407C7C04403C7804407C7C04401FF010101FF010101FF010101FF008201010
+4A41:04407C7C04403C7804407C7C04403FF002007FF802020DFE70401C78F1C41C3C
+4A42:0020FE2010202050FE50AA88AB44BA22AA20AAF8BA08AA08AA10FE1082200020
+4A43:0010FE9010902092FE92AA94AAF4BA98AA90AA90BA90AA92AAB2FED2828E0000
+4A44:0000FE7C10442044FE54AA54AA54BA54AA54AA54BA10AA28AA28FE4A828A0106
+4A45:0010FE10101020FEFE92AA94AA90BAFCAAA4AAA4BAA8AAA8AA90FEA883440282
+4A46:0040FE401040207EFEA0AAA0AB20BA3EAA20AA20BA20AA3EAA20FE2082200020
+4A47:0010FE1010102010FE1EAA10AA10BA10AAFEAA82BA82AA82AA82FE8282FE0082
+4A48:0040FE40107E2080FF7CAA44AA64BA54ABFEAA44BAA4AA94AAFEFE0482280010
+4A49:0014FE1210FE2010FE10AAFEAA92BA92AAFEAA92BA92AAFEAA92FE9282920086
+4A4A:0020FE1010FE2082FE40AA4EAA6ABAAAAAAAAAAABB6CAA28AA4AFE4A828A0106
+4A4B:0010FE0810FE20A4FEA4AAA4AAFEBAA4AAA4AAF6BAACAAB4AAA4FEA483240024
+4A4C:0028FE241040207EFEC8AB48AA7EBA48AA48AA7EBA48AA48AA7EFE4082AA012A
+4A4D:0010FE1010FE2010FEAAAA44AA82BB7CAA44AA7CBA44AA7CAA10FE5482920030
+4A4E:0010FE1010282044FE82AA7CAA00BAEEAAAAAAAABAEEAA44AA44FEAA82AA0112
+4A4F:0024FEFE10242000FEFEAAAAAAAABAFEAA14AAFEBA90AAD2AAACFEAA82960122
+4A50:22202220FF20227E3E4008807F3C490449087F100820FFC008420842083E0800
+4A51:2200227EFF0222023E02083E7F20492049407F7E0802FF820802080208140808
+4A52:2200227EFF1022103E1008107F1049FE49107F100810FF900810081008500820
+4A53:28802880FC8028FE390212427C42548254A27D1213FAFD0A1002100210141008
+4A54:280028F8FE882888388811067E0055FC54847C841048FE501020105010881306
+4A55:28002840FD9E2912391211127D12551255127D12115AFD941110101010101010
+4A56:28202820FE2028A838A410A27D22552056247C241028FE081010102010C01300
+4A57:280028FCFE842884388410FC7C84548454847CFC1084FE841104110412141408
+4A58:22002200FF7E22083E1008107F24494449787F080810FF940822087E08220800
+4A59:28202810FE1029FE382010207C44548455F87C101020FE44108211FE10821000
+4A5A:2804281EFDF02910391011107D1055FE55107D101110FD08110A114A11A61112
+4A5B:28402820FC282808380810487C54555255527D601260FC4410C41144123C1000
+4A5C:28202820FE20282039FC11247D24552455247DFC1124FF241124112411FC1104
+4A5D:2808281CFDF02950395011507D50555055507D481148FD681154127412521400
+4A5E:28202820FE202820383E10207C20542055FC7D041104FF041104110411FC1104
+4A5F:28202820FDFE282039FC10247DFC552055FE7C22102AFC541050108811041202
+4A60:50005006FBB8508870882108F93EAB88A888FA882288F93E21002280247E2800
+4A61:28202820FC202BFE382010207D24552455247EAA1020FC501050108811041202
+4A62:5104510EF930512077E02120F93EA964A9A4FF242124F9242124212425442284
+4A63:28202820FC502888390412FA7C20542057FE7C201128FD241222142210A01040
+4A64:280028FCFE84288438FC10847C8454FC54847C8410FCFE50105010921112120E
+4A65:5004500EFBB8508870882128F92EABA8A8A8FAA822A8F93E21002280247E2800
+4A66:108020FC6910AA9028602890230C04407FFC044007C001001FF01110FFFE0100
+4A67:28402820FDFE2800380010FC7C00540054FC7C001000FCFC1084108410FC1084
+4A68:280028FCFE8028F8388010F87C8057FE55407D241128FF101108114411821100
+4A69:50405020FBFE520275042100F9DEAA52AA52FB52249AF894211021122212240E
+4A6A:28202810FDFE29023A0410F87C88548854F87C801080FCFC1084108410FC1084
+4A6B:500053FEF820502073FE2222FA22AB32AAAAFAAA2376FA6622222222222A2204
+4A6C:28202820FDFE282038FC10407DFE548855247E2210F8FC2011FE102010201020
+4A6D:28202820FDFC2850388811047FFE540855E87D281128FDE81128100810281010
+4A6E:280029F8FC08280839F810087C0857FE54207E221174FCA81124122210A01040
+4A6F:500053FCF8085010702023AEFAA2AAAAAAA4FAA423AAF83220A0204027FE2000
+4A70:280028F8FE88288838F810007DFE548854F87C8810F8FE88109E13E810081008
+4A71:504050A0F910520875F62000FBC4AA54AA54FBD42254FA5423D42244225422C8
+4A72:28402820FDFE2948394811FE7D48557855007DFC1144FD4811281210122814C6
+4A73:28402820FDFE292238A411287C50548855047CF81088FC881050102010D81306
+4A74:2880289EFC9229D23892109E7C9255D255527D5E1152FD5211D21022102A1044
+4A75:28002BFEFE2228203BFE10207DFC552455FC7D2411FCFC2013FE102010201020
+4A76:28202924FD2429FC382011FE7C00542055FC7D241124FDFC1020102413FE1102
+4A77:28202810FDFE2884384811FE7D02562454107DFE1040FC7C1044108410941108
+4A78:28882888FDFE2888380011FE7C88548854F87C8810F8FC88109E11E810081008
+4A79:280028FEFE00287C3844107C7C0054FE54827CAA1092FEFE1092109210921086
+4A7A:50905088F9045242748821FCF804A800ABDEF8422252F94A22522042214A2084
+4A7B:280029FEFD2029FC392011FC7D20552055FE7C0212AAFEAA12AA120210141008
+4A7C:28202A20FD7C28A4381810E67F10557E55107D7C1110FDFE1110111012FE1400
+4A7D:500053FEFA00527C72442244FA7CAA00AAEEFAAA22AAFAAA22EE220023FE2000
+4A7E:50405020FBFE520072482248FBFEAA48AA48FA482278FA002554252A2A2A3000
+4A7F:282029FCFC2028883BFE10887DFC550455FC7D0411FCFD0411FC108811041202
+4A80:282029FEFF0228F8388810F87C8054FC54847CFC1000FE2010541142114A1238
+4A81:28502952FCD4285039FE10887C5055FE54207CFC1020FDFE1050108811041202
+4A82:52085208FFBE520872082FBEFAAAAAAAAAAAFBAE2208FF1C2AAA324822082208
+4A83:51085088FBC8501073DE2264FBD4A814ABD4F8542094F8E82388209422942122
+4A84:28882888FDFC2888388813FE7C2055FC55247DFC1124FDFC1000108811041202
+4A85:280029FCFD54295439FC10807DFE564255F27D521152FDF2104A13FA100A1004
+4A86:285029FCFD5429FC395411FC7C0055FC54007DFC1104FDFC1088105013FE1000
+4A87:28882BFEFC8828243BFE10207DFC552455FC7D2411FCFD24100811FE10881058
+4A88:2810287CFE54297C391010FE7C00577C55447D7C1140FD7C1144117C1280147E
+4A89:51245248F924500073FC2294FA64AA94ABFCFA482368FA48236A224A22462362
+4A8A:51105090FBDE5010725E2182FBDEA810ABDEFA5023DEFA5023DE2250225222CE
+4A8B:2810287CFE54297C391010FE7C44577C55447D7C1144FD7C112811441280147E
+4A8C:51F05210FBFC560473FC2224FBB8AA22A9FEFA1027FCFA4423FC20D0214A263E
+4A8D:53DE5252FBDE525273DE2222FAFAAA22AAFAFAAA22FAFAAA22FA227222AA2226
+4A8E:522253FEF89051FE731025FEF910A9FEA910F9FE2100FBFE228A237622522276
+4A8F:101010107E1022FEFF9200927E9242AA7EAA08CA7E82088248827E82088A0884
+4A90:104010207C282408FE0800487C5445527D5211607E60104450C47D44123C1000
+4A91:102010107E1022FEFF8200847E4042447E4808507E60084248427E42083E0800
+4A92:102010107E0022FEFF1000107E1042107E7C08107E10081048107E1008FE0800
+4A93:102010207E202220FF3C00207E2042207EFC08847E84088448847E8408FC0884
+4A94:102810247DFE2420FE2001FC7D2445247DFC11247D2411FC51247D241124110C
+4A95:108010807CFE2502FE2200AA7C7244227DFE10227C7210AA51227C22100A1004
+4A96:104010407E7E2280FF7C00447E7C42447E7C08207E3C084448A87E10082808C6
+4A97:100011DC7D442544FF4401DC7D0045007DDC11147D1411D451087D0811141122
+4A98:100010FC7C842484FEFC00847C8444FC7C0011FE7C101090509C7C901150123E
+4A99:101410127DFE2410FEFE00927CFE44927CFE10927C0411FE50447C241024100C
+4A9A:100011FC7D0425FCFF0401FC7C0047DE7C4212527D4A10C6535A7C42114A1084
+4A9B:101E10F07C922454FEFE00547C9245007CFE10927C9210FE50927C9210FE1082
+4A9C:104010787C8825FEFEA400D27CFE44807CBC10807CBC108050BC7D24113C1224
+4A9D:104411FE7C542448FEFE01907CFE44907CFE10907CFE108051FE7C44103811C6
+4A9E:00003FF80100FFFE028004401830E44E04407C7C04403C7804407C7C0440FFFE
+4A9F:100011F8FE88105010207C50558C545055DC545055DC5C5011DC105013FE1000
+4AA0:1640F87C9084FE2832205250968C100004407C7C04403C7804407C7C0440FFFE
+4AA1:11201CBE704250947D9034A85C46900004407C7C04403C7804407C7C0440FFFE
+4AA2:12201D3E70425094531051287D46145035DC345055DC985011DC105013FE1000
+4AA3:1220113E1042FC94131011287C46545055DC54505DDC305051DC905013FE1000
+4AA4:281E29F02892EE5429FE2854EE92290028FE2892EE9228FE28922E92F0FE4082
+4AA5:10001EFC1044FF2881107E2800C67E2842EE7E2842EE7E2842EE7E2824FE4200
+4AA6:200010007CF8002044202820FE2000207C20442044207C20442044207DFC4400
+4AA7:202010207C2000A044AC28B4FEE401A47CA444B444A87CA244A244827C7E4400
+4AA8:204010407C4000FC44842904FE0400847C44444444447C04440444047C284410
+4AA9:202010207C20005044502888FF4402227C2044F844087C08441044107C204420
+4AAA:10007E7C124422444A7C844401003FF80820FFFE00001FF010101FF010101FF0
+4AAB:200010FE7C00005244A42928FE94004A7C0044FE44107C10441044107DFE4400
+4AAC:202010207DFE0020442029FEFF0202047CF8441044207DFE442044207CA04440
+4AAD:202010107CFE000044442828FEFE00007C7C444444447C7C444444447C7C4444
+4AAE:204010407CFE012244AA28FAFE4200947D4844FE45227EAA44FA44427C944508
+4AAF:08202AA44D28145022887FFE41029FF404407FFC00001FF010101FF010101FF0
+4AB0:2040102079FC0088485033FEFC0001FC790449FC490479FC48204A947A8A4C7A
+4AB1:000001FEFC20044005FC050405047DFC410441FC4104450459FC608841040202
+4AB2:000000FEFE10282028FC2884288428FC288428FC28842A844CFC484880840102
+4AB3:000000FE7E10122012FCFF84128412FC7E8412FC1084108420FC204840848102
+4AB4:080008FE08107F20497C08440844147C1444147C14442544267C440080280044
+4AB5:00007EFE0410242024FC248444847FFC0C8414FC1484248444FC844814840902
+4AB6:00007CFE4410442044FC7C84448444FC7C8444FC448444844EFCF04800840102
+4AB7:200020FE40107E2082FC02847A844AFC4A844AFC7A844A8402FC024814840902
+4AB8:00007EFE421042207EFC4884488448FC7E8448FC488448844AFC4A4866844302
+4AB9:00007EFE0810082010FC1484328451FC908410FC108400840EFCF04840840102
+4ABA:100010FE10107E2010FC10841084FEFC108410FC2084288444FCFE4842840102
+4ABB:100010FE20104420FEFC0284248424FC2484FEFC2484248424FC444844848502
+4ABC:100010FE9210922092FC9284FE8410FC108492FC928492849EFCF24800840102
+4ABD:00007CFE4410442044FC7C840084FEFC208440FC7C84048404FC044828841102
+4ABE:0010FF10082810287E44428242087E1042647E08421242647E08243042C08100
+4ABF:080008FE10107F20417C41446544557C4944497C55446544417C7F0041280044
+4AC0:00007EFE421042207EFC428442847EFC408448FC44844A8452FC604840840102
+4AC1:100011FE20207C4045FC45047D0445FC45047DFC4504450445FC7C8845040202
+4AC2:100010FE3E104220A47C18441044247CC8441F7C2144D2440C7C08003028C044
+4AC3:00007F7E401040205E7C404440447F7C5044517C5A445444527C910098281044
+4AC4:440024FE281000207CFC4484448444FC7C8428FC288428842AFC4C4888840102
+4AC5:100008FE7F104120497C084408447F7C0844187C1C442A44497C880008280844
+4AC6:0400053E048804107FBE44224422753E5522553E5522522252BEA680899410A2
+4AC7:0C0030FEC6101820637C0C44F044007C7E44427CFF444244FF7C42004A284444
+4AC8:0800497E491049207F7C08441444227C514488FC08447E44027C040004280844
+4AC9:0C0030FEC210142048FC3084C88414FC2484CCFC14842484C4FC044828841102
+4ACA:0000FEFE08101020347C52449144107C00447E7C42444244427C42007E284244
+4ACB:0C0070FE1010FE2038FC5484928400FC1084FCFC2484448428FC10482884C502
+4ACC:080010FE7F104920497C7F444944497C7F44147C2444FF44047C040004280444
+4ACD:140014FE1410F720147C14441444777C1444147C1444F744147C140014281444
+4ACE:0000F77E11105520227C55448944107C0044F77C11445544227C550089281044
+4ACF:2200227EFF902220227C3E442244227C3E44227C2244FF44007C140022284144
+4AD0:2200227E22102220F7FC22442244667C7744AAFCAA443244227C220022282244
+4AD1:100010FEFE10102028FC4484FE8404FC748454FC5484748454FC044814840902
+4AD2:000006FE781048207F7C48444544537C6144007C7E4442447E7C42007E284244
+4AD3:200010FE7C10002044FC24842884FEFC008400FC7C84448444FC44487C844502
+4AD4:20002F7EF5102520757C2544F544297C2344087C0844FFC4147C2200412880C4
+4AD5:200010FEFE10002044FC2884FE8482FC10847CFC5484548454FC5C4810841102
+4AD6:220022FEFF1022203E7C22443E44227C2244FF7C40445444627C40007E280044
+4AD7:0000777E51105120517C77444044407C7744417C49447544427C420045284944
+4AD8:00007CFE44107C2044FC7C8420847EFC928452FC6A8442847AFC024814840902
+4AD9:080008FE7F1008202A7C2244FFC4227C2A44087C7F441C442A7C490089280844
+4ADA:00003EFE221022203A7C2A442A447F7C41445D7C554455445D7C410045284244
+4ADB:20002F3E210841105FBEC82248224FBE5222423E5FA24222453E448048945022
+4ADC:08002A3E2A08AA90CCBEDDA2FFA2AABEAAA2DDBEFFA299A288BE8F80F0940022
+4ADD:060078FE08100820FF7C1C442A44497CBE44227C22443E44227C22003E282244
+4ADE:440024FE28100020FEFC108410847CFC108410FCFE840084AAFCAA48AA840102
+4ADF:00007CFE441044207CFC0084FE8482FCFE8482FCFE848284FEFC284844848502
+4AE0:180060FE0C1070200CFC70840084FEFC108434FC528490847CFC44487C844502
+4AE1:2200147EFF901420147C7F441544FFFC15447F7C14443644557C948014281444
+4AE2:03007C7E471044205F7C554456445C7C5544537C50445744557C5500A9A80044
+4AE3:0E00F0FE2210922044FC20844484F8FC108424FCFE841084FEFC284844848302
+4AE4:0000FF7E811000207E7C42447E44427C7E44107C0844FF44007C240042288144
+4AE5:080010FE7F104920497C7F44497C49447F7C10441A7C2CA82FC44882480287FE
+4AE6:0800083E7F080810083EFFA22022413EFFA240BE00227F22553E55005794FC22
+4AE7:100020FE7C1044207CFC44847C8410FCFE8428FC548492847CFC104810841102
+4AE8:1200123E12087A1013FE7CA210A2FCBE22A23ABE29222922293E4A805A9484A2
+4AE9:1000223E7F08421094BEF7A20822363EC92230BEC4221922623E0C003014C022
+4AEA:100010FEFE101020BAFC5484BA8410FCBA8454FCBA84108428FC244842848102
+4AEB:08007F7E4910FFA0497C7F4408447F7C49447F7C1044FF44217C72000C28F344
+4AEC:0000F7BE2108A510F7BE6322B5A2213E7FA240BE40A27FA240BE40807F9440A2
+4AED:10007CFE54107C2010FCFE8400847CFC44847CFC44847C8444FC7C4828844502
+4AEE:00007F7E01103F20017C7F440044777C2544F77C0244FFC4427C22002A280444
+4AEF:4100211E0FE4F108429E44527FF2505E5752555E55525752555E5040A14C0092
+4AF0:0020F92420A843FEF8A889248A22F9048904F9DE8A448D54F89E010452048C04
+4AF1:00007FBE08087F9054BE54A254A241BE00227FBE08227FA254BE5480549441A2
+4AF2:0280025E7FC442085E1E42925E92571E5D5242DE88520492545E51408F0C0012
+4AF3:00007F7E551055207F7C20447F44917C7D44557C55447D44117C7D0005280244
+4AF4:2200223EF7882210773EAAA22262003E7F22003EFFA20822493E4880A8941022
+4AF5:10007F3E49086510533E49227F22083EFFA2A2BE4922FFA2203E3F0041148322
+4AF6:20802A9EF5E42A8871DE6AB2A4922A9E2092041E04127FD20A1E1100208C4052
+4AF7:0000FFBE0808EB90AABEEBA20822FFBE0822EBBEAAA2EBA2083E0F80F8144022
+4AF8:00007FDE404A434A5C4A444A5F4A554A55525F52446A45445F404922801E0000
+4AF9:00007FC0407E43485C4844485F48554855485F484448457E5F404922801E0000
+4AFA:100011FC1104FD3411C4114421F42954295429F4514455545DF4851602060402
+4AFB:00007FDE405243525C52445E5F52555255525F52445E45405F404922801E0000
+4AFC:00107F1041104D7C711451147D1455FE7D10512855247D4444804042803E0000
+4AFD:00007FC6405843485C4E44585F4E5578554A5F4A444A45465F404922801E0000
+4AFE:00407C2044284C087448545455527D6256607C4454C4553C52007D004482807E
+4AFF:001E7FCA404A434A5C5244665F40555E55525F52445E45525F404922801E0000
+4B00:00487C4844884CBE752A55CA544A7C8A54AA7DF25412542A52447D004482807E
+4B01:00107F08417E4D42712051247D3855207D225122551E7D0044804042803E0000
+4B02:00287C2444204DFC7520552455247D2855287D105594552C52447D004482807E
+4B03:00107F0841004D7C710051447D2455287D28511055FE7D0044804042803E0000
+4B04:00147C1244104DFE7510551455147DD455087D0A551A552652427D004482807E
+4B05:00407C4045FC4C847484552856107D0857DE7D4A554A5652525A7DE44482807E
+4B06:00447D8444944C9477F4549455947DD456B47C945484549452887D004482807E
+4B07:440025FC290401347DC4454445F445547D5429F4294429542BF44D168A060402
+4B08:00007F4441284D00717C51447D44557C7D285128554A7D8644804042803E0000
+4B09:00207C2045FC4C20742057FE54507C5055547D525652549052907D304482807E
+4B0A:00107F1041FE4D10715451547DBA55107D28512455427D8044804042803E0000
+4B0B:00207C2044F84C2075FC548855447C7854887D505420545052887D084482807E
+4B0C:10001DFC11047D3455C4594471F455544D5441F45D44555457F4951622060402
+4B0D:00807C8044FC4D54765454A455547C8854207C145552554A52387D004482807E
+4B0E:00147C1247FE4C10741055D455547D5455CC7C0A54CA571652227D404482807E
+4B0F:00207F10417C4D44712851FE7D00557C7D445144557C7D4444804042803E0000
+4B10:00187CE044204DFC747054A855247C4057FE7C8855905470538C7D004482807E
+4B11:007C7F54417C4D54717C51007D7C55447D7C5144557C7D4444CC4042803E0000
+4B12:00207DFC45044C507488552454507C8855067CF85408545052207D50448A807E
+4B13:00207F1041FE4D44712851FE7D00557C7D44517C55447D7C44804042803E0000
+4B14:00207C5044884D0474F8540055C47D5455D47D5455D4554453547D484482807E
+4B15:00007DFC45044D3475C455447DF4555455547DF4554455547DF4491682060402
+4B16:00107F20417C4D44717C51447D7C55007D7C5110557C7D1044FC4042803E0000
+4B17:00007CF844887C9844E87CA800A8FEF840A87EF8AAA82AAA4AAA92FA2A864502
+4B18:00207DFC44004CF8748854F854007DFC55047D7455545574530C7D004482807E
+4B19:000E7F7041124D447120517C7D9055107DFE511055547D7C44804042803E0000
+4B1A:00007DFC45204DF8752055F855207DFC54047D545554540452287D104482807E
+4B1B:01FC7D2445FC4D2475FC54A854A87FFE54A87CA855FC542053FE7D2044A2807E
+4B1C:00407C2045FC4C507524555455FC7C2055FC7D4455545574530C7D004482807E
+4B1D:00287F7C41284DFE7110517C7D54557C7D54517C55007D4444824042803E0000
+4B1E:00207DFE44204CFC740055FE54027CF854207DFE540455DE53547DCC4482807E
+4B1F:00827D7A452A4DAA754A559A55427CA255F27C4A55F2555252E67DF84482807E
+4B20:00003FF801007FFE41029D7401001D7000047FE808247212120EFFD0122A221E
+4B21:02003FD00260FFFE1C10EFF008100FF000047FE808247212120EFFD0122A221E
+4B22:0800080014FC122429247E24A2243E2422243E242024284424442A8433282210
+4B23:082008201420127E29407E80A23C3E0422083E102020284024422A42323E2000
+4B24:00003FFC200420043FFC208023602C9837F6241027F0241027F4446845188604
+4B25:04200210013EFFC00022011A02860D603FF8C8260FE008200FE808D00A300C08
+4B26:080008781448124829487E86A3003EFC22443E442028282824102A2832442182
+4B27:0800080014FC120029007E00A3FE3E5022503E502050285024522A92328E2100
+4B28:10801080288025FE5202FC8244827DE244A27CA2412A512A4A1A540264144008
+4B29:00007FFC010003600D18710402800D603FF8C8260FE008200FE808D00A300C08
+4B2A:0800080014FE121029107E20A2203E6822643EA22122282024202A2032202020
+4B2B:0804081E14F0129029907E90A2903EFE22903E9020902888248A2AAA32D6208A
+4B2C:10201020282025FC5324FD2445247D2445247FFE402050504850548865044202
+4B2D:00007DFC444444447C94010802800D603FF8C8260FE008200FE808D00A300C08
+4B2E:10081048292825285328FD0845087D0845087D08414851944914542264424082
+4B2F:0810081014101210291E7E10A2103E1022FE3E822082288224822A8232FE2082
+4B30:080008FE1422122229227E22A24A3E4422803E7E2042284224422A42327E2042
+4B31:102010202820242053FEFC7044A87CA845247D24422250F84820542064204020
+4B32:08400840148012FC29047E04A2F43E9422943E9420F4289424042A0432282010
+4B33:10201020292424A452A8FC2045FC7C2044207C2043FE50204820542064204020
+4B34:10201020282025FE5220FC2044207DFC44707CA840A851244924562264204020
+4B35:10201010281025FE5220FC2444447CF844127C22404451884810542864444182
+4B36:080008FC1484128429FC7E84A2843EFC22A23EA42098289024882AA432C22080
+4B37:08200820147C128429487E30A2203E4823903E3E204229A424182A1032602180
+4B38:7F7C08041E282210542809443280CD603FF8C8260FE008200FE808D00A300C08
+4B39:100011FE282024205248FC8445FE7C2244207C2041FC50204820542067FE4000
+4B3A:110410842888240053FEFC2044207DFC44207C2043FE50204820542064204020
+4B3B:10281024283E25E05220FC3C45E07C20443E7DE0402250244818546A65864002
+4B3C:0800087C14441244297C7E00A2FE3E8222823EFE2082288224FE2A82328A2084
+4B3D:088408441448120029FC7E84A2843E8422FC3E482048284824482A8A328A2106
+4B3E:10881048285025FC5224FC2445FC7D2045207DFE40225022486A54A465204020
+4B3F:100011FC2904250453FCFD00451C7D70451C7D70411E51F0491055126512420E
+4B40:100010782A2825285128F82848787B284928792A412A512649225A806C7E4000
+4B41:100CFEF010801CFEF088110832880D603FF8C8260FE008200FE808D00A300C08
+4B42:100010F82888248852F8FC0045FC7D2445247D2441FC510049005502650240FE
+4B43:10201020285024885144FA2249F878084850782040A452824A8A5A8A6C784000
+4B44:102010202BFE242053FCFD2445FC7C2045FC7C2443FE502449FC542064A04040
+4B45:100011FC290425245324FDFC45247D2445747D54415451744904550465FC4104
+4B46:7F2048307E2842247E2049207E800D603FF8C8260FE008200FE808D00A300C08
+4B47:1080108028FC25045244FC4447FC7C4445F47C0441F4511449F4540464284010
+4B48:10101010287C271451FEF9144A7C7A104F7C791041FE55104A10530064FE4800
+4B49:1020102028FE244052FCFD1046FE7C0044FC7C8440FC508448FC548464944088
+4B4A:108810882BFE248852A8FC2045FC7D2445247D2443FE50204850548865044202
+4B4B:1100117C294426445244FE7C4A107A104AFE7A38425452544A945B126A104210
+4B4C:107CFF44107C7E44427C7F44028C0D603FF8C8260FE008200FE808D00A300C08
+4B4D:1020102029FC24205220FCF844207C2045FC7C0041FC51544954555467FE4000
+4B4E:10481148294827FE5148F9484978790049FE782043FE507048A859246E224020
+4B4F:1040102029FE25025102F9FE4900790049FE79AA41AA52FE4AAA5AAA6CA24086
+4B50:11041088280027FE5020F82049FC782048207BFE404050244AA25A8A6C884078
+4B51:10881050280025FE5250FDFC44547DFE44547DFC405050D84954565264504050
+4B52:1010102028FC248452FCFC8444FC7C8444FC7C20401050544942554A66384000
+4B53:102011242924252453FCFC0047FE7C0045FC7D04410451FC4888545067FE4000
+4B54:10101220297C25445044F87C4B407940497C79444144517C49445A806C7E4000
+4B55:100CFEF054807CFE5488FF0812880D603FF8C8260FE008200FE808D00A300C08
+4B56:1040102029FE25005148F94849FE794849487948417851004AD452AA652A4800
+4B57:1040102029FC24885050FBFE480079FC490479FC410451FC489058926912460E
+4B58:100011FC290425FC5104F9FC48207BFE480079FC410451FC482059246A224060
+4B59:100013DE288826A853FEF9884ADA7CA649F87908410851F84908590869F84108
+4B5A:102011FC2888245053FEFC0045FC7D2445FC7D2441FC502049FC542067FE4000
+4B5B:100813882888251057DEFA944AA47B944A947B94429452C84B885E9468A440C2
+4B5C:1020102029FC24205354FC8845047EFA44887CF8408850F8482054A865244060
+4B5D:10201050288825745202FDFC45247DAC45247DFC400050F8488854F8648840F8
+4B5E:100011FC295425FC5220FDFC44207FFE44887C5041FC50204BFE542064204020
+4B5F:108813FE288824005148FBFE49487978490079FC402053FE487058A86B264020
+4B60:102013FE2A88265053FEFA504AFC7A544BFE7A5442FC52504AD8555466524850
+4B61:103C13C0294424A451F8F8204BFC780049F8780841F8500849F85AC46AAA447A
+4B62:104010202BFE26225154F94A4A3A780049FC795443FE500049FC582068A04040
+4B63:104010202BFE24885052FFAC4AAA7AA84DAC7800410451FC490459FC69044204
+4B64:1010107C2A54257C5110F8FE48007B7C4944797C4140517C4944597C6A80447E
+4B65:110810902BFC244051F8F8804BFC794849FC7B0A45F8510849FA5934698C4102
+4B66:108813FE2888241252FEF8104CFE7A924AFE789241FE52924E045AFE6A44422C
+4B67:102013FE2A4827FE5248FAEC4B5A7A484A207A44427852144AFE5A106A5444B2
+4B68:122213FE289025FE5310FDFE491079FE491079FE410053FE4A8A5B766A524276
+4B69:102013FE2A4827FE5248FAEC4B5A7A484A507BDE425053DC4A5055DE64504850
+4B6A:200021FC21043DFC45044BFE800021FC212421FC212425FC282031FC202003FE
+4B6B:4084444859FE6020424042FC3E8400847CFC448444847CFC448444847CFC4484
+4B6C:4092452459246092420042FE3E1000207CFC448444FC7C8444FC44847CFC4484
+4B6D:440028FEFE10102020FC7C84448444FC7C8444FC44847C8444FC44487C844502
+4B6E:3F042018FF62220C7F7010100820FFFE02003FF820083FF820083FF820083FF8
+4B6F:042078201124FF241124392455FC90207C20452445247D24452445247DFC4404
+4B70:0420782011FCFE4010F8384057FE90887D24462244F87C2045FC44207C204420
+4B71:0420792410A4FEA8102039FC552491247D7445AC45247D24452445047D144508
+4B72:0420782011FCFE501088390457FE90087DE8452845287DE8452844087C284410
+4B73:7C4011FCFD2439FC5524FDFC24681BA2651E7FF809203FF8C8260FE008200FE0
+4B74:00001FF811001FF011001FF011001FFC0004292444940108FFFE010001000100
+4B75:00007E7848487E4848487E48486848587E580248AA48AA4AAA4A828A14860900
+4B76:00007EFE48487E4848487E48484848487E480248AA48AA48AA88828815080A08
+4B77:00087F1C48707F1048107F1C487048107F90009EAAF0AA90AA9280920512020E
+4B78:00107E8848847E8449027E02488848887E880250AA50AA20AA50828815040A02
+4B79:00007C40519E7D1251127D12511251127D120512555A55945510841014100810
+4B7A:00207E1048107EFE48007E00487848487E480248AA48AA4AAA4A828A14860900
+4B7B:00107E5048507E5048887E8849044AFA7E480248AA48AA48AA88828815280A10
+4B7C:00007F3C48007F0048007F7E482448247FA400A4AAA4AAA4AAA480A405440284
+4B7D:00087F2848287F28483E7F28484848087F8800FEAA88AA88AA88808805080208
+4B7E:00207E2848247E2448207E2048FC48207E200250AA50AA50AA88828815040A02
+4B7F:00107E1048507E50487C7E90491048107EFE0210AA28AA28AA28824414440882
+4B80:00407E4048FC7E8449047EF4489448947EF40284AA94AA88AA828282147E0800
+4B81:00207E2048407E4848847EFC480448487E4802FEAA48AA48AA48828814880908
+4B82:00287E2448247E2048FE7E204820483C7E340254AA54AA54AA88828815140822
+4B83:00107E1048107E7E48107E10481048FE7E100210AA20AA28AA4482FE14420800
+4B84:00107F0848087F7E48107F10482448247FB80088AA90AA90AAA480BE05020200
+4B85:00147E1248127E1048FE7E90489248927E920294AA94AAB4AACA828A14160822
+4B86:00007EFE48087E1048347E52489048107E000210AA10AAFEAA10821014100810
+4B87:00207E2048FC7E2449FE7E2448FC48207E2002FCAA20AA20ABFE822014200820
+4B88:00107F10481E7F2248547F08481048647F88009EAAA2AAC2AA94808805100260
+4B89:00407E40487E7E8049007E1C48E048A07EA202A4AAA8AA90AA9082A814C40882
+4B8A:00207C2051FE7C2051FC7C2451FC51207DFE0422542A54545450848815040A02
+4B8B:00027C0253E27C8A508A7CEA50AA512A7DAA056A564A544A54828482150A0A04
+4B8C:0090F890A090F910A1FEFB10A510A138F9380954A954A992A910891009103110
+4B8D:3FF821003FF021003FF021003FFC492486940108FFFE048808503A20CC180806
+4B8E:00C27C3450187C6451827C2051FE50507C9005FE56925492549A849414100810
+4B8F:00007EFE48107E10487C7E24482448FE7E000200AA7CAA44AA448244147C0844
+4B90:00007EFE48827E8248AA7EC6488248BA7EAA02AAAABAAAAAAA828282148A0884
+4B91:00047E1E48E07E12488A7E4C484048087EFE0208AA88AA48AA28820814280810
+4B92:00147E1248FE7E1048107EFE489248927EFE0292AA92AAFEAA92829214920886
+4B93:00207E20483E7E2048FC7E8448FC48847EFC02A4AA20ABFEAA20822014200820
+4B94:00047E1E48F07E1048FE7E54485448547EFE0254AA54AAFEAA10821014FE0800
+4B95:0000FBDEA042F94AA084F94AA252A420F8000BDEA852A952A89489480A543422
+4B96:007C7E4448447E7C48447E44487C48007EFE0282AA82AAFEAA82828214FE0882
+4B97:00107E9248927E9248FE7E0048FE48807EBE0288AA88AAFEAA88830815080A08
+4B98:00007E2048CE7E8248827EEE488248827EFE0228AA28AA28AA48824A148A0906
+4B99:00087E0C480A7E0849FE7E08480848EA7EAA02AAAAECAA0CAA2A82CA14160822
+4B9A:00107E10487E7E1048107EFE482448427E90023CAA44AAA4AA288210142808C6
+4B9B:0014FB94A294FAA4A2BEFAA4A364A2B4FAAC0AACAAA4AAA4AB248A240A24322C
+4B9C:00147E5448547EFE48547E54485C48407E7E0210AAFEAA10AA38825414920810
+4B9D:00007EFE48927E1048FE7E10487C48547E7C0254AA7CAA10AAFE821014100810
+4B9E:00207E2049FE7E2048FC7E4049FE48887F0402FAAA88AA88AAF88288148808F8
+4B9F:00407C2051FE7D2250A47D28505050887D0404F8548854885450842014D80B06
+4BA0:00007EFE48007E7C48447E44487C48007EFE0292AA92AAFEAA92829214FE0882
+4BA1:00407E40487E7E80487C7E44487C48447E7C0220AA3CAA44AAA88210142808C6
+4BA2:00047E1E48F07E1048107EFE481048507E960292AA92AAD6AA92829214FE0882
+4BA3:00007EFC48447E3848447EEE48AA48447EAA0210AAFEAA38AA54829214100810
+4BA4:00207E2049FE7F5248487EFE489049907EFE0290AA90AAFEAA90829014FE0880
+4BA5:00007EFE48007E7C48447E7C480048FE7E8202AAAA92AAFEAA92829214920886
+4BA6:00207E1048FE7E00487C7E44487C48007EFE0282AABAAAAAAABA8282148A0884
+4BA7:101010281044FE8211FE7C9044FC7C9044FC7C9010FEFE0212AA12AA14141008
+4BA8:00207E1048FE7EA248107EFE484448287EFE0210AA10AA7CAA10821014100810
+4BA9:00007E7C48447E7448547EFE4882487C7E44027CAA44AA7CAA44824414540848
+4BAA:00847C8450DE7D4451547EDE504450847D24042055FE547054A8852416220820
+4BAB:0020F9FCA124FBFEA124F9FCA020A1FCF92409FCA840ABFEA88889D00870338C
+4BAC:00487E4849FE7E4848007EFC488448FC7E8402FCAA20ABFEAA20825014880906
+4BAD:000E7EF048227E9248447EFE488248FE7E8202FEAA82AAFEAA288248148A0906
+4BAE:00207C2053FE7CA850A87D74522250707CA80546567854885550842014500980
+4BAF:0088F888A088FBD0A09EFBE4A094A7D4F91409D4A954A948A9488A540AD43422
+4BB0:00207E1048FE7E4448287EFE488248927EFE0292AABAAAAAAAAA82BA14820886
+4BB1:0000FA7EA110F930A04AF89AA62CA24CFA9A0A2AAA4AAA88AA288D1008FE3000
+4BB2:00287E28487C7E2848287EFE4810487C7E54027CAA54AA7CAA00822814440882
+4BB3:003CFBE0A124F8A8A3FEF8A8A124A202F9FC0924A924A9FCA924892409FC3104
+4BB4:00107ED448487F4A48847E84497A48007EFC0284AAFCAA00AA84824815FE0800
+4BB5:00207DFC50887C5053FE7C0051FC51247DFC052455FC542055FC842017FE0800
+4BB6:00507E4848FE7F9048FC7E9048FC48907EFE0280AA10AAFEAA38825414920810
+4BB7:00007EFE48AA7EAA48FE7E4048FE49227EFA02AAAAAAAAFAAA2282FA140A0804
+4BB8:0A803138228838382288393822887FFE51029FF411001FF011001FFC2A44492C
+4BB9:0020F93CA120FBFEA010F814A3FEA210FBF00A54AA54AAD4AB688C4A08963322
+4BBA:0040F820A3FEF888A052FFACA2AAA2A8FDAC0800A904A9FCA90489FC09043204
+4BBB:0020FBFEA020F9FCA000FBFEA002A1FCF8200BFEA800ABFEA8048BBE0AA4338C
+4BBC:00127E5448A87E4448927E54489848247EC20284AAEEAB24AAB4825E14440884
+4BBD:0040F820A3FEFA50A3FEFA52A3FEA200FA940AD8AA90AAD2AA8E8C000954322A
+4BBE:0110F890A3DEF810A25EF982A3DEA010FBDE0A50ABDEAA50ABDE8A500A5232CE
+4BBF:0020FBFEA24AF9FEA048F9FEA048A3FEF88409FEAA84A8FCA920893C0AA0347E
+4BC0:03FCF908A1F8F908A1F8F90EA7F8A008FFFE0A94AB9CAA94AB9C8AD60FBC3084
+4BC1:00400FFEF200A3F8F000A7F8F408A7F8F2201D5C57F4BC9495DC1C9657F62CA2
+4BC2:3FF821003FF021003FF892487EFC48907EFC48907EFEAAAA0100FFFE0920711C
+4BC3:0040F82008204BFE4A024C4448407FFE048804881D08E4D04420045028881304
+4BC4:0000F8FC08844884488448FC48207C2005FE05221D52E58A450A0502290A1104
+4BC5:0000F1FE108450FC508450FC50867BFC08040BDE3852C952089409482A541422
+4BC6:00207F20412079204920FFA080A07F2041207F2041207F2241224122451E4200
+4BC7:00207C204420742054FCFE2482247C2444247C4444447C444484448455284A10
+4BC8:00007CFC440074005400FEFE82507C5044507C5044507C5244524492548E4900
+4BC9:00407C404440747C5444FE8882A07D2044207C5044507C484488448455044A02
+4BCA:00007C0045FE74045404FEF482947C9444947C9444F47C944404440454144808
+4BCB:00507C484448744055FEFE4082407C7C44A47CA444A87D284510462854444882
+4BCC:00007CFE4482748254FEFEA082A07CA044F87CA844A87CA84528452A564A4886
+4BCD:00207C20445074505488FF2482127C1045FC7C0444087C884450442054104810
+4BCE:00207C20445074505488FF0482FA7C2044207C2045FC7C204420442054204820
+4BCF:00047C1E44F074105410FEFE82107C1044107CFE44827C824482448254FE4882
+4BD0:00107C10441074FE5492FE9282AA7CC644927C9244AA7CC644824482548A4884
+4BD1:00207C20452474A454A8FE2083FE7C5044507C5044507C5244524492548E4900
+4BD2:00207C20444E74805520FE20825E7CC445447C4444447C444444444454544848
+4BD3:00207C2044FC74205420FE2083FE7C0044207C2044FC7C204420442055FE4800
+4BD4:00207C1045FE75025400FE1C82E07C2044207C3E45E07C2044224422541E4800
+4BD5:00007C0645D874485448FE88829E7DC844487D4845487C9E44804540563E4C00
+4BD6:00207C1044FC74845484FEFC82847C8444FC7CA244A47C984490448854C44882
+4BD7:01107D12451475D85510FF1283527D8E45207C2045FC7C204420442057FE4800
+4BD8:00207C1045FE75025604FEF882007C0045FE7C5044507C5044924492550E4A00
+4BD9:00147C1244FE74105410FEFE82927C9244FE7C9244927CFE4492449254924886
+4BDA:00207C4444F874105424FEFE82027CFC44847CFC44847CFC4484448454944888
+4BDB:00407C2045FC75045480FE9C82D47D5445547D5446D87C504494449455144A0C
+4BDC:00007CFC4484748454FCFE8482847CFC44407CFE452A7E4A44924522544A4884
+4BDD:00207C2044FE744054FCFF1082FE7C0044FC7C8444FC7C8444FC448454944888
+4BDE:00007CF84488748854E8FEA882A87DFC45047D7445547D544574450455144908
+4BDF:00007C844448740055FEFE2082447DA844307C5845987C344452459054504820
+4BE0:00007CF84488748854F8FE8882887CF844007DFC45547D544554455457FE4800
+4BE1:00887C50440075FE5450FFFC82547DFE44547DFC44507CD84554465254504850
+4BE2:00803FFE24103F7C26382D5437FA220823C822482FFE2A0A23F8420842288210
+4BE3:00207DFC452475FC5420FFFE82007DFC45047DFC45047DFC450445FC54884904
+4BE4:00107C28444474BA5500FEFE82927CD644927CFE44007C7C4444447C5444487C
+4BE5:00007CFE448274FE5482FEFE82447CAA44EE7C4444AA7CEE440044D454AA492A
+4BE6:00247CFE4424740054FEFEAA82AA7CFE44147CFE44907CD244AC44AA54964922
+4BE7:01007FFC00001FF010101FF000007FFE40029FF4101017D0145017D010101030
+4BE8:0100FFFE00001FF010101FF000007FFC40044FE448244FEC0200FFFE1830E00E
+4BE9:0100FFFE00001FF010107FFC40044FE448244FEC00003FF821083FF820021FFE
+4BEA:200011FEFE1000207CFC44847C8400FCFE8482FCBA84AA84AAFCBA4882848702
+4BEB:00207C1045FE7C0044FC7C8410FCFE0001FE7D02457A7D4A117A5502930A3104
+4BEC:1000FEEE44AA7CAA00EEFE00AA7CBA54827CFE54447C7C1010FEFE1010101010
+4BED:3E0420183E6020043E182062FF0422187F6000003FF00820044003801C70E00E
+4BEE:3E0420183E6020043E182062FF0422187F6000003FE00420047C08043014C008
+4BEF:3E0420183E6020043E182062FF0422187F60010011102108416403801C00E000
+4BF0:3E0420183E6020043E182062FF0422187F60028004401C70E44E044008401040
+4BF1:3E0420183E6020043E182062FF0422187F6000007FFC01000770190CE1020100
+4BF2:3E0420183E6020043E182062FF0422187F6000003FF821083FF8200220021FFE
+4BF3:3E0420183E6020043E182062FF0422187F60044008203218C44608201FF00810
+4BF4:3F0820303EC42018FF62220C7F7000000FE01020601C1FE0082004C00780F87E
+4BF5:3E0420183E6020043E182062FF0422187F6001003FF801000820FFFE08201020
+4BF6:3F0820303EC42018FF62220C7F7000001FF010101FF010101FF01010FFFE0000
+4BF7:3E0420183E6020043E182062FF0422187F600090FFFE10887E50102420D4C70C
+4BF8:3E0420183E6020043E182062FF0422187F60410021FC0A441048E0A021182606
+4BF9:3F042018FF62220C7F7000003FF000101FF000107FFE40029FF4082007C0F83E
+4BFA:3F042018FF62220C7F7000183FE021003FFC20802C64301C1FF0101010101FF0
+4BFB:3F0820303EC42018FF62220C7F7011001FF82100FFFE00001FF010101FF01010
+4BFC:3E0420183E6020043E182062FF0422187F601400082014A46CA8155064881906
+4BFD:3F0820303EC42018FF62220C7F7001003FF80440FFFE00001FF010101FF01010
+4BFE:3F042018FF62220C7F7000003FF8210827C821082FE8200827C8444847C88018
+4BFF:3E0420183E6020043E182062FF0422187F6001003FF80820145001007FFC0100
+4C00:3F042018FF62220C7F7000001FF00100FFFE0920711C0200FFFE082007C07838
+4C01:3F042018FF62220C7F7000003FF000101FF00010FFFE111009A005401930E30E
+4C02:3F0820303EC42018FF62220C7F7000183FE0121009207FFC05401930E10E0100
+4C03:3E0420183E6020043E182062FF0422187F60082004407FFC044024481450FFFE
+4C04:3F0820303EC42018FF62220C7F7000003FF821083FF821083FF84904489287F2
+4C05:3F042018FF62220C7F7000007FFC02001FF010101FF010101FF010101FF00820
+4C06:3F042018FF62220C7F7000001FF0022001407FFC188462880100FFFE0920711C
+4C07:3F042018FF62220C7F7002001FD00220FFFE03000FF03810CFF008100FF00810
+4C08:3F042018FF62220C7F70082004407FFC01003FF80200FFFE080037F0C0801FFC
+4C09:3F042018FF62220C7F70000010783E4822482A86FF7822482A2842104A2884C6
+4C0A:3F042018FF62220C7F700110FFFE21083FF821083FF821080020FFFE08200460
+4C0B:3F042018FF62220C7F7000001FF010101FF010107FFC44043FF8082007C07838
+4C0C:3E0420183E6020043E182062FF0422187F60108821544A22113C312052A0147E
+4C0D:3F042018FF62220C7F7001007FFC09103108C6C41930E92E05C0193061080300
+4C0E:3F042018FF62220C7F7001001FF011101FF00100FFFE10101FF010101FF00820
+4C0F:3F042018FF62220C7F7008287F240820FFFE12203FA46424BF2824123FAA2046
+4C10:3F042018FF62220C7F7024203F3E21403F5024883F0800003FF824482448FFFE
+4C11:3F042018FF62220C7F7000003FF801007FFE492285147FFC02003FF824482458
+4C12:3F042018FF62220C7F7008207FFC08207FFE40029FF40600192006C038A00318
+4C13:3F042018FF62220C7F7002001FF014901250FFFE92122FE8440407E008203060
+4C14:3F042018FF62220C7F7008003E7822482A867E7822482A30464C3FF82448FFFE
+4C15:3F042018FF62220C7F7001FC01003FFE210221F02F0420FC20004FFC4914BFFE
+4C16:3F042018FF62220C7F7028503E7C4890FEFE1528264A5FF6149012501FF00820
+4C17:BEFA8822BEFA8822BEFA84028782888297C284428FE289228FE289228F1281F6
+4C18:BEFA8822BEFA8822BEFA8002BEFA924A8A2A934A82828C62B19A860280729F86
+4C19:0010FE1000107CFE44107C1000FCFE448244AA449228FE289210922892448682
+4C1A:0020FE1000107CFE44447C440044FE448244AA289228FE109210922892448682
+4C1B:0000FE0001FE7C4044407C780048FE488268AA989298FE88928A92AA92CA8686
+4C1C:0000EFEE200227C22442E7CE80088FE88828EAAE29222FE229222922A92A4864
+4C1D:0044FE2400287CFE44927CD600BAFE9282FEAA00927CFE44927C9244927C8644
+4C1E:713C17C4719C47F0725C17C45A5423C8FFFE00001FF010107FFC44445FF4410C
+4C1F:3FF80000FFFE082010103FF802081FF011101FF012101FF004A808BA3082C07E
+4C20:081010107F10497C49547F54497C49547F54107C1A102C902F904810480287FE
+4C21:080810087F284928493E7F48490849087F7E10081A082C942F924820484287FE
+4C22:102020407C8E550054207C5E54C455447C4410442A442D544F48480287FE0000
+4C23:100021FC7D04550455AC7D54555455547D5411AC2B042D144F08480287FE0000
+4C24:10201040FDFC11247D2455FC7D2455247DFC1040386854B292BE11201122121E
+4C25:00507FFC00403E4822503E2000547FFC11141FF012101FF004A808BA3082C07E
+4C26:080010087F10497E494A7F7E4952497E7F2810481A7E2C882F884808480287FE
+4C27:1020203C7C2054FE54A27CB854E4549C7C8010B82AA82D2A4F464A0287FE0000
+4C28:100021FC7D2455FC55007D7C5544557C7D44117C2A442D7C4F00480287FE0000
+4C29:102010407DFC12941494FFFC10A420A47EFCA22022443E6A226E22A03EA2231E
+4C2A:1020924054FCAA94449482FC7CA444A444FC7C204444446A7C6E44A044A24D1E
+4C2B:1010207C7C1054FE54447CEE544454EE7C0010FE2A282D2A4F46488287FE0000
+4C2C:10FC20287C1055FE54527C9055FE54AA7CC610BA2AAA2DBA4F84480287FE0000
+4C2D:0020FE4010FCFE94AA94AAFCAAA486A400FCFE201044FE6AAA6EAAA0AAA2871E
+4C2E:208843FEF820A9FCA820FBFEA854A992F89023FE209054D45B8A5E9651A28FFE
+4C2F:1100215C7D84555854C87D3E55CA56A87DEC10A82B682D5E4F80480287FE0000
+4C30:00207C4010FCFE94929454FC10A454A400FCFE201044FE6AAA6EAAA0AAA2871E
+4C31:0020FE4010FCFE94929454FC00A4EEA4AAFCEE200044FE6A546EBAA010A2FF1E
+4C32:102010203E20422084207F20492049207F20492049207F22002255224A9E8A80
+4C33:200020007CFE441088107E10521052107E10521052107E100010AA10AA500020
+4C34:20402040788048FC91007E0054F854087C10542054407C800084AA84AA7C0000
+4C35:200021FC7C04440888107E20522053FE7E20522052207E200020AA20AAA00040
+4C36:202020107C10440089FE7E40524052407E40524052407E400040AA40AA7E0000
+4C37:20202020782049FE90207C20542054FC7C20542054207DFE0020AA20AA200020
+4C38:200820487848484890447C8454A455227C20544054407C480084ABFEAA820000
+4C39:202820247C244420882E7EF0522052247E24522852287E100032AA4AAB860002
+4C3A:2004200E7C70444088407E40527E52487E48524852487E480048AA88AA880108
+4C3B:102010203E20423E84447F44494449A47F28492849107F10002855284AC48A82
+4C3C:202020207820485090507C88554456227C2054F854087C080010AA10AA200020
+4C3D:2020202078204BFE90207C2055FC55247D24552455247D340128AA20AA200020
+4C3E:2000200078FC48A490A47CA454A454A47CFC548054807C800082AA82AA7E0000
+4C3F:20402040787E488091207CA054AC54B47DE454A454B47CA800A2AA82AA7E0000
+4C40:20202020782048FC90A47CA454A454A47CA455FE54207C500050AA88AB040202
+4C41:2020202078204BFE90507C50548855247E22542055FC7C200020AA20AA200020
+4C42:201020507850489090FC7D5455D454947C94551455547DD40054AA24AA340048
+4C43:201020107C504450887C7E90531052107EFE521052287E280028AA44AA440082
+4C44:2008201C79F0495091507D50555055507D50554855487D680154AA74AA520400
+4C45:2020202078204BFE90207C20542055FC7C7054A854A87D240124AA22AA200020
+4C46:200021FC78444848908E7C82557A56147C20542057FE7C200020AA20AAA00040
+4C47:200020007CFC448488847E8452FC52847E84528452FC7E840000AA00ABFE0000
+4C48:200020FC7800480090007DFC542054207CA854A455247D220222AA20AAA00040
+4C49:200020F87888488890887CF8548854887C8854F854887C880088AA88ABFE0000
+4C4A:20202020792448A490A87C20542057FE7C7054A854A87D240124AA22AA200020
+4C4B:204820487848484891FE7C48544854487C4855FE54007C480044AA84AA820102
+4C4C:200020FE7C90449088907EBC52A452A47EA452A452BC7E900090AA90AAFE0000
+4C4D:200021FE7840484090407C78548854A87C98550855487C300010AA10ABFE0000
+4C4E:200021FE7800480090FC7C84548454FC7C84548454FC7C840000AA00ABFE0000
+4C4F:200021FE7800480090FC7C84548454847CFC540054847C440048AA00ABFE0000
+4C50:2008203C79C0480491447CA8540055F87C10542057FE7C200020AA20AAA00040
+4C51:2080208C78B048A093E07CA054BE54E87CA857A854A87CA800A8AAA8AAC80188
+4C52:2000207C7C444444887C7E0052FE52927E92529252FE7E800080AA82AA82007E
+4C53:2000200679D8484890487C88549E55C87C48554855487C9E0080AB40AA3E0400
+4C54:2088208878884910915E7D64575455547D54555455547D480148AB54AB140122
+4C55:2080208078FE490092FC7C8454A454947DFE548455247D1401FEAA04AA280010
+4C56:200020FE7C28442888287EEE52AA52AA7EAA52AA52EE7E280028AA28AA480088
+4C57:08000F7C28447F28A11016283846CFE010403FF051101FF011101FF024884244
+4C58:03043C2404247FA416242504440C0FE010403FF051101FF011101FF024884244
+4C59:20802080789C48F490947C9457F454147C94549455C87EA80088AA94AA9401A2
+4C5A:200021F87808480890F87C08540855FC7C20552454A87C7000A8AB24AAA20040
+4C5B:20142012781049FE90107C1055D255527D52555455D47C0800CAAB1AAA260042
+4C5C:20482048784849FE90487C4855FE54007CFC548454847CFC0084AA84AAFC0084
+4C5D:2020204078FE489290927CFE549254A27CFE544854887DFE0008AA08AA080008
+4C5E:2020202079FE485090887D0456FA54007C0055FE54207CA400A2AB22AA200060
+4C5F:200020FE7C82448288FE7E88528852FE7E88528852BE7EA200A2AAA2AABE0122
+4C60:20482044785E49E090287C12546A55967C48545E55E07C240028AA12AA6A0186
+4C61:2080208078FE490292227CAA547254227DFE542254727CAA0122AA22AA0A0004
+4C62:2080208078F8490892107DFC542454247DFE542454247DFC0024AA20AAA00040
+4C63:2040202079FE480090887C88555456227C00542055FE7C200020AA20AA200020
+4C64:20402040787C488491087E00542054CE7C82548254EE7C820082AA82AAFE0082
+4C65:24043FA44424FFA404243F8424942FE810403FF051101FF011101FF024884244
+4C66:20502048788048FE91907E9054FC54907C9054FC54907C900090AAFEAA800080
+4C67:2020212478A8482091FC7C4057FE54887D0456FA54887C8800A8AA92AA82007E
+4C68:2082208273E2908A208AFBEAAAAAAAAAFAAAAAEAA88AF9CA02A2AC82A88A0084
+4C69:200020FE7C8244C688AA7EFE52A252927EFE52A252A27EBA0082AA82AA8A0084
+4C6A:2010201079FE481090107CFE541054107DFE542054527CD40148AA44AA620040
+4C6B:04047FC404243FA424A43FA4150424944FE810403FF051101FF011101FF02488
+4C6C:200021FE78124890909C7C90557E56007CFC548454FC7C8400FCAA84AA940088
+4C6D:208020FE7890489090D07CBC559456947CAC54A454B47C880088AA88AAFE0080
+4C6E:2080209E73EA908A21CAF88AABEAA892F8A6A820ABFEF8200050A888A9040602
+4C6F:7E20243E1848FFA829104A2898460FE010403FF051101FF011101FF024884244
+4C70:2008203C79E0482093FE7C2055FC55247DFC552455FC7C2001FCAA20ABFE0000
+4C71:202020107CFE440088447E2852FE52827E10527C52547E540054AA5CAA100010
+4C72:2040207C788448F890087DFE544054A47D38545854947D340054AA92AB500020
+4C73:200021FE7900497C91547D54557C55547D54557C55107D10017CAA10AA1004FE
+4C74:2040205E78404860915E7D525552555E7C52545254527C5E0052AA40AA5E0040
+4C75:205020887924484090907DF8540854007DDC544455547CCC0154AA44AA5400C8
+4C76:2100209E79D2495491547DD8555455527DD25512559A7D5401D0AB50AA100010
+4C77:0F1008107F9048A04E3E79444F2451245F2475285F2855105F284028AAC40082
+4C78:20A0212C7924492491AC7D24552455FC7C2055FC54887C500020AA50AA880306
+4C79:204420247C2844FE88107E7C521052FE7E205220527C7E500090AB10AAFE0000
+4C7A:202021247924492491FC7C0057FE54007DFC550455047DFC0088AA50ABFE0000
+4C7B:2000207C7C44447488547EFE5282527C7E44527C52447E7C0044AA44AA540048
+4C7C:200021FE7902490291FE7D245524557E7D24552455FE7D520154AA48AA640442
+4C7D:202020207850484890A47DFE568454FC7C8454FC54807CFC0144AB44AA7C0044
+4C7E:202021FC79244BFE91247DFC542055FC7D2455FC54407DFE0088ABD0AA70038C
+4C7F:21002102711C97D02110FFD0AD5EAFD4FD54AFD4A914FFD40114A924A9240144
+4C80:08207E2008F8FF2814287F6A082A0FE610423FF051101FF011101FF024884244
+4C81:200423E47224922423EEFA04AAE4AA04FA0CABF4AA44FA640554AD44AA5400C8
+4C82:22102110711097BE2240FA00ABBEAA8AFA88AAA8AAAEFAA804A8ADA8A85E1080
+4C83:209221247892480090FE7C9254FE54927CFE541055FE7C380054AA92AB100010
+4C84:2208220873C8921027DEFA54AB64AAD4FFF4AA54AD54FCC807C8A854AAA40142
+4C85:2100213C712493A4213CF924A924ABBCF924A924A93CF92802A8AACAAC4A0886
+4C86:202020207C78444888907E7C525452547E7C525452547E7C0000AAAAAAAA0000
+4C87:20102210797C4910907C7C545754557C7D10553855547D920110AA90AA7E0000
+4C88:2020201079FE494891487D4855FE55487D4855EC555A7D680148AB48AA480048
+4C89:21402144715893F02150F9D0A95EA9D4F954A954ABF4F8140154AA34AC140024
+4C8A:2010239072FE92A022BEFB48AABEAA80FABEAAA2AABEFB22023EAA22AA220226
+4C8B:2088208879DC488893DE7C88555456227CFC548454847CFC0084AA84AAFC0084
+4C8C:2108210877C89108211EFB92A824AB80F808AFC8A908F9080594A954A9240342
+4C8D:112420A879FC48406BFE59084A84FCFA49104BFC6D2459FC492449FC48009954
+4C8E:200823887088911027DEFA94AAA4AB94FA94AB94AA94FAC80388AE94A8A400C2
+4C8F:2048216A78DC484890B47D2255FE55027C20542054FC7C240044AA44AA940108
+4C90:2020203E782049FE91227DFC5522557E7D54557C55547D7C0110AAFEAA2204C6
+4C91:210420887BFE482091FC7C2057FE54547D92549057FE7C9000D4AB8AAA9601A2
+4C92:210021DE724A948A23EAFAB6AAA4ABF4FABEAAA4ABE4FABE02A4AAA4AA240464
+4C93:202020207850488891047EFA540054007DDC555455547DDC0088AA88AB540222
+4C94:200023FE700091FC2124F9FCA924ABFEF800A9FCA924F9FC0124A9FCA80003FE
+4C95:2084204879FE4848914A7CCC544855FE7C0054FC54847C8400FCAA84AA8400FC
+4C96:202023FE702091FC2000FBFEA802A9FCF820ABFEA800FBFE0004ABBEAAA4038C
+4C97:21202120725692482580F970AA2EAA24FEF4AA24AAACFA740224AA34AAC4020C
+4C98:2108210879EE4A9490427C1055FE55027CF8548854F87C8000FCAA84AAFC0084
+4C99:2108210871EE92942042F800ABDEAA52FBD2AA52ABD2FA1A0294AB50AA100010
+4C9A:2088208873EE90922084FBEEAAAAAAAEFBEAA88EA9CAFAAE04A0A88CA88A0092
+4C9B:208823FE788849FC91547DFC540057FE7E0254F854887CF80088AAF8AA8800F8
+4C9C:3C3C4848FCFC54547C7C54547C7CAAAA3C3C4848FCFC54547C7C54547C7CAAAA
+4C9D:202020207C50445088887D04560254F87C88548854A87C9000821C82E07E4000
+4C9E:204020207C20440089FE7C00540454847C84544854487C4800501C10E3FE4000
+4C9F:200020407D9E451289127D1255D255127D125512555A7D9401101C10E0104010
+4CA0:202020207DFE442088FC7C4055FE54887D0456FA54887C8800F81C88E08840F8
+4CA1:208820487C5045FE88507C5055FC55547D54558C55047DFC01041D04E1FC4104
+4CA2:01243CA825FC244027FE3D08268424FA25103FFC252425FC252445FC54008BFE
+4CA3:0F1008107F9048A04E3E79444F2451245F2475285F2855105F284028BF440082
+4CA4:400044FE7A28882814FEFAAAAAAAA8AAF9AEAAC2AE82FAFE02821A82E2FE4082
+4CA5:02003FE004221822E21E1FF010101FF010101FF010001FFC10001FFC2A44452C
+4CA6:101020107F1041107F7E41107F1040107F9040287FA800A8AAA8AAC481440682
+4CA7:1040108011FC110411FCFD0411FC110011FE11001DFEE00242AA02AA0202000C
+4CA8:004000807DFC110411FC110411FC110011FE110011FE1C02E2AA42AA0202000C
+4CA9:3FFC20043FFC220027F0241027F0241027F0240027FC240047FC40048AA40AAC
+4CAA:1040108011FC110411FCFD0411FC110011FE290025FE240242AA42AA8202000C
+4CAB:0080FDF8290829F8290829F8290029FC290029FC280429542A5C480247FE8000
+4CAC:1004201E7CF044907C9044907C9040FE7E9040907E900288AA8AAAAA82C60C82
+4CAD:04200E40F0FC908490FC9084FCFC908090FE908090FE88028AAAC6AA8302000C
+4CAE:00207C4000FC008400FCFE8428FC288028FE288028FE2A024EAA4AAA8202000C
+4CAF:00207E4022FC248424FC28842EFC22802AFE248044FE4A0292AA20AA4102000C
+4CB0:0040008079FC010401FC0104FDFC210021FE210041FE50028AAAFAAA0A02000C
+4CB1:102020107F0041FE7F2041207F3C40247FA440247FA400A4AAA4AAA481540688
+4CB2:0020284024FC248442FC528490FC108020FE208048FE4402FCAA44AA0102000C
+4CB3:1020084008FCFF8400FC00843CFC248024FE248024FE250246AA44AA8102000C
+4CB4:1040108011FC150459FC510451FC910011FE110011FE280226AA42AA4202800C
+4CB5:0100111021E84F04F2001FF010101FF010101FF010001FFC10001FFC2A44452C
+4CB6:1FF00000FFFE0844323CDFF010101FF010101FF010001FFC10001FFC2A44452C
+4CB7:04001FF010101FF010101FF010001FFC10001FFC492484940108FFFE0920711C
+4CB8:1040108011FC290425FC4304A9FC290029FE290029FE28024AAA4AAA8A02000C
+4CB9:00407E8009FC090411FC150433FC510091FE110011FE00020EAAF2AA4202000C
+4CBA:4840488049FC4904FDFC490449FC490079FE490049FE48024AAA7AAA4A02000C
+4CBB:2040108001FCFD0421FC410449FC8900F1FE110021FE20024AAAFAAA0A02000C
+4CBC:1040108051FC51047DFC510491FC110011FE7D0011FE100212AA1EAAE202400C
+4CBD:00400080F9FC210421FC410479FC4900C9FE490049FE48027AAA4AAA0202000C
+4CBE:00007DFE108010FC1E04F02802101FF010101FF010101FFC10001FFC0004492C
+4CBF:00203E4022FC228422FC3E8420FC288028FE2E8028FE28024AAA4CAA8902000C
+4CC0:101020107C5044507C7C44907D1040107EFE40107E280228AA28AA4482440C82
+4CC1:105020487C4844407DFE44407C40407C7EA440A47EA80328AB10AA2882440C82
+4CC2:0020FC4024FC248444FC548488FC00807CFE448044FE440244AA7CAA4502000C
+4CC3:02001FF010101FF010101FFC10001FFC0004492C08001EF8228854980882307E
+4CC4:1420144014FC548455FC5E8454FC548054FE548054FE54025DAA76AAC502000C
+4CC5:100020007F3E41227F2241227F22403E7FA240007F940094AAA2AAA281420600
+4CC6:1040108021FC790449FC490449FC490079FE490049FE48024AAA7AAA4A02000C
+4CC7:00203C4024FC34842CFC248424FCFE8044FE648054FE44027EAA04AA2902100C
+4CC8:104020407CFC44847D0446F47C9440947EF440847E940288AA82AA82827E0C00
+4CC9:204020803DFC4504A9FC110429FC450083FE310009FE000262AA12AA0A02000C
+4CCA:2820244024FC2084FEFC208420FC3E8042FE448054FE880216AA22AA4202000C
+4CCB:2040208021FCF904A9FCA904A9FCA900F9FEA10021FE28023AAAEAAA4202000C
+4CCC:1040108021FC4904FDFC050479FC490049FE790049FE78024AAA4AAA4A02580C
+4CCD:24102420247C24447F7C2444247C2440247EFF40007E240224AA42AA4302820C
+4CCE:0040408099FC890489FC890489FCD90089FE890089FE8802FAAA8AAA0202000C
+4CCF:1040108011FC7D0411FC1104FDFC010011FE11007DFE100212AA1EAAE202400C
+4CD0:410021FC0A441048E0A0211826061FF010101FF010101FFC10001FFC0004492C
+4CD1:10201040FEFC108420FC3E8422FC6280BEFE228022FE3E0222AA22AA2302260C
+4CD2:08207F280824FFFE10207F2041247F2441247FA840287F900092AAAAAAC60182
+4CD3:102012407EFC148414FCFF8408FC108020FE7E80A0FE22022CAA30AA2102000C
+4CD4:060038F820083CF820083FF802001FF010101FF010101FFC10001FFC0004492C
+4CD5:0E20F04022FC928454FC0084FCFC088010FE168018FEF00252AA12AA5202200C
+4CD6:100021FE7CA044A87CA844E87CA840A87EA840E87EA802AAAABAABEA82260C20
+4CD7:02001FF010101FF010101FFC5244892C02403C500848FFFE08507E240854198C
+4CD8:201040D8F3949094F09093FEF0908094F89480D8FB980890A8AAA8CA8A863102
+4CD9:081008207F7C49447F7C49447F7C0040FF7E2040407E7E0202AA02AA1502080C
+4CDA:00407C8045FC7D0445FC7D0401FC01007DFE110011FEFE0212AA12AA1202100C
+4CDB:00207E4042FC42847EFC428442FC7E8010FE1080FEFE220264AA18AA2502C20C
+4CDC:1020104028FC448482FC7C8410FC1080FEFE108054FE520292AA10AA5102200C
+4CDD:202010407CFC008444FC288400FCFE8000FE00807CFE440244AA44AA7D02440C
+4CDE:081008207F7C10443E7C1044FFFC2240497E88C03E7E08027FAA08AA0902080C
+4CDF:00200E40EAFCAA84AAFCAE84EAFCAA80AAFEAE80EAFEAA020AAA12AA1302260C
+4CE0:02100F20787C0844FF7C2A442A7CFF402A7E2A40FF7E080208AA0EAA7102200C
+4CE1:2820244040FC7E84C8FC48847EFC488048FE7E8048FE480248AA7EAA4102400C
+4CE2:4840488049FCFD0449FC490479FC490079FE490049FEFC0202AA52AA4A02840C
+4CE3:08507F480840FFFE20403E502222465A82861FF010101FF010101FFC5244892C
+4CE4:10109220527C5444107CFE44927C9240BA7ED640927E920292AA82AA8B02840C
+4CE5:1020924092FCFE8410FC288444FC928008FEFC8004FE080252AA22AA1202000C
+4CE6:20201040FEFC828400FC7C8400FC7C8044FE7C8044FE7C0202AA1EAAE202400C
+4CE7:21004178F1089208F2FE9640FA40827CFA908210FAFE0A10AA28AA288A443282
+4CE8:102020407CFC44847CFC44847CFC0080FEFE108010FE7C0212AA1EAAF202400C
+4CE9:0020FE4028FC2884FEFCAA84AAFCFE8010FEFC8024FE44022AAA12AA2A02C40C
+4CEA:1020924092FC9284FEFC0084FEFC108020FEFE80AAFEAA02AAAAAAAAAB02860C
+4CEB:0A107420157C5244227C2144417CBE40087E08407F7E080214AA12AA2302400C
+4CEC:28402880FDFC290439FC11047DFC550055FE7D0011FEFC0212AA12AA1202100C
+4CED:0020EE40AAFCAA84AAFCEA84AAFCAA80EAFE8A80CAFEAE02D8AA88AA0902080C
+4CEE:00207C1045E07C2245B47CA8452456A28A401FF010101FF010101FFC5244892C
+4CEF:1C20704010FCFE8410FC7C8454FC7C8054FE7C8010FE7C0210AA1EAAF102400C
+4CF0:1008179014BC24A424BC67A4A23C22202FBE272026BE2A822AAA322A2202220C
+4CF1:00207E7C14C40838FEC62A2048FCA844128C1FF010101FF010101FFC5244892C
+4CF2:11FE1100FD7C11001DFEF1541248546422421FF010101FF010101FFC5244892C
+4CF3:1020544054FC7C8492FC9284FEFC00807CFE0080FEFE100254AA92AA5102200C
+4CF4:0020FE40AAFCAA84AAFCFE8410FC548052FE928010FE540252AA92AA1102100C
+4CF5:11041108111E7D1213DE5552555E5550BB5E1150395E554292521252154A1884
+4CF6:100E20F07C2244927C4444207C4440F87E1040247EFE0210AAFEAA2882440C82
+4CF7:11102110CAA814443240D27C154014FE0A001FF010101FF010101FFC5244892C
+4CF8:00803FFE24103F7C26382D543412210027F0241027F0241027FC40044AA4800C
+4CF9:20404020F3FE9202F00893EEF008801CFBE48154F9480954A964A942893E3200
+4CFA:08101420227C4944BEFC0444087CFFC0147E7F40557E6302412A7F2A41427F0C
+4CFB:08047F7808403E402A7E3E482A48FF480A881FF010101FF010101FFC5244892C
+4CFC:100020FE7C8044807CBC44A47CA440BC7E8040EE7EAA02AAAAEEAA8082FE0C00
+4CFD:1020924092FCFE8428FC24847EFCC88048FE7E8048FE7E0248AA48AA7F02400C
+4CFE:0A107420157C5244227C21445D7C80407E7E4240427E7E0242AA24AA0F02F00C
+4CFF:24102620357C54445F7C7444947C64402A7E4940917E0002AAAAAAAAAB02000C
+4D00:101008207F7C2244FF7C00447F7C49407F7E49407F7E08027F2A082A0F42F00C
+4D01:20201040FEFC82847CFC54847CFC54807CFE1080FEFE920292AABAAA8B02840C
+4D02:20103E20427CFF44497C49447F7C1040287ED540267ECD0215AA24AAD502080C
+4D03:102010407CFC1084FEFC4484EEFC448064FEDE8000FEFE0228AA2AAA4D02880C
+4D04:0F10F020117C8944427C0044FF7C8140427E7740927E5A022F2A222A4242820C
+4D05:08107F20087C2244FFFC22447F7C41407F7E41407F7E41027F2A222A4142808C
+4D06:2820AA406CFC2884FEFC448428FCFE8010FE7C8010FEFE0210AA28AA4502820C
+4D07:00107F20087CFFC488FC6B44087C6B40147E2A40457EBE0202AA04AA1902040C
+4D08:10202040FEFC9284D6FCBA84FEFC9280BAFED68082FE1002FEAA28AA4502820C
+4D09:0020FE40AAFCAA84FEFC0084FEFC00807CFE44807CFE2A0264AAA2AA3102200C
+4D0A:41082210FFBC08247F3C0824FFBC152064BE2420FFBE2402352AE2AA2582688C
+4D0B:200043FCF2949294F3FC9000F7FE8000FBFC8204FBFC08A2A914AB088D443182
+4D0C:104820487DFE44487CFE44827D7C40007EFE40207ED2022CAAD8AA2C82CA0C30
+4D0D:00100020777C5544557C7744557C5540777E5540557E7702002A552A88C2000C
+4D0E:00001FF011101FF011103FF82AA83EF82AA83FF810101FF010101FFC5244892C
+4D0F:22082210FFBC22243E3C41245D3CD5E0553E5520DD7E4182002A552A4A828A8C
+4D10:0808FF9084BC77242A3C77242ABCFFA0003E7F20413E7F02412A7F2A2202410C
+4D11:7F0849107F3C4924FFBCAAA4FFBCAAA0FFBE0020FFBEA2823E2A222A2782F80C
+4D12:7F080810FFBC88A46B3C08246B3C0020EFBEAAA0EFBE0002FFAA492AAA82FF8C
+4D13:0010FFA0087C084408647F544944494C4940497E49024D024A7A0802080A0804
+4D14:2020104000FCFE8400A4288444948288048044FE2802100229FA440284140008
+4D15:7F0408441E44224454440844320CDFE01420126010001FF800087F8800280010
+4D16:10201040FEFC10847CA41084FE9400887C8044FE7C0244027DFA440254144808
+4D17:00207E4042FC7E8442A47E8442947E88148012FEFF02100229FA240242148008
+4D18:03107C20477C44445F64555456445C4C5540537E50025702557A5502A98A0004
+4D19:02087910493E4BA248327AAA412247E67920693EAB82A902297A3902290A0104
+4D1A:104010201E2010FC1000FE009278C648AA48D648AA48C64A924AFE8A82860100
+4D1B:101010921E5210541010FEFE9282C682AAFED682AA82C6FE9282FE82828A0084
+4D1C:101010201EFE10921092FEFE9292C692AAFED620AA24C65A925EFE908292010E
+4D1D:1000107C1E44107C1044FE7C9200C7FEAAA0D6EEAAAAC6EA92BAFFE48224002A
+4D1E:100011DC1E44115410CCFF549250C648AAFED790AAFEC69092FEFE9082FE0080
+4D1F:00803FFE22203FFC22243FFC242027BC2422279E200023F0221042904452980E
+4D20:00803FFE22203FFC22243FFC242027BC2422279E203827C020405FFE41108E0E
+4D21:00007FFE024012480A503FFE22203FFC22243FFC284028482F7048444B448C3C
+4D22:00803FFE22203FFC22243FFC242027BC2422279E204020402FFE415042488C46
+4D23:08047F1E54F054107F92555255547F1054FE54105E10541054105C1056508020
+4D24:00803FFE22203FFC22243FFC242027BC242227DE224023FC24404BF840409FFE
+4D25:00803FFE22203FFC22243FFC242027BC2422279E24003FBC24A444A44ABC9124
+4D26:00803FFE22203FFC22243FFC242227BE20403FFE200027F8200047F8440887F8
+4D27:081C7F70541054FE7F38555455927F10542054FE5E24544454285C10562880C4
+4D28:08007F7E544854507F5C555455547F5C545454545E5C5448545C5CAA568A8118
+4D29:00803FFE22203FFC22243FFC20003FFC21402FF829482FF820005FFC44908988
+4D2A:00803FFE22203FFC22243FFC280024F824083E78220824FE2E545538445484B2
+4D2B:08007F7C541054FE7F92555455107F54542854545E8A547C54045C0856308008
+4D2C:08480844FF442A402A5E5DE088401C402A4050401E2022225412080A14066002
+4D2D:08080808FF082A082AFE5D0888181C182A2850281E4822885408080814286010
+4D2E:08100810FF102A102A925D9288921C922A9250921E922292549208FE14026000
+4D2F:08400840FF402A7E2AAA5D2A882A1C4A2A4A50921F1222225422084214946008
+4D30:08480844FF442A402A5E5DE088401C442A4450481E3022225452088A15066002
+4D31:08200810FF102AFE2A825D0488401C482A5050601E40224254420842143E6000
+4D32:08100810FF102AFE2A105D1088101C7C2A1050381E3822545454089214106010
+4D33:08200810FF102AFE2A825D0488001C282A2850281E2822285444084414446082
+4D34:08100810FF102A102A1E5D1088101C102AFE50821E8222825482088214FE6082
+4D35:10841048FE0054FC5448BA481048384855FEA2483C484448A84810882888C108
+4D36:10401040FEFC54885550BA2010D83B2654F8A2203CF84420ABFE10202820C020
+4D37:10401020FE2055FE5502BA0410F838005400A3FE3C504450A89010922912C20E
+4D38:080E08F0FF222A922A545D00887C1C082A1050101EFE22105410081014506020
+4D39:0800087CFF542A542A7C5D5488541C7C2A1050FE1E1022385454089214106010
+4D3A:08200810FF7C2A002A445D2888001CFE2A0050001E7C224454440844147C6044
+4D3B:0640387C08947E242CD44A0801007FFC11102BA845641918E3E60E4001800E40
+4D3C:10481044FE5E55E05428BA12106A39965448A25E3DE04424A8281012286AC186
+4D3D:10201040FEFE54925492BAFE109238A254FEA2483C8845FEA80810082808C008
+4D3E:10841044FE4855FE5420BAFC102039FE5440A2803CFE4510AA10141029FEC000
+4D3F:100011FEFF0254785400BAFC104038A45538A2583C944534A85210902950C020
+4D40:10101092FE54541054FEBA82108238FE5482A2FE3C824482A8FE10002844C082
+4D41:10481148FF5E556A5554BBC81050386455C4A37E3D444564A95411442954C248
+4D42:10201010FEFE54445428BAFE1082389254FEA2923CBA44AAA8AA10BA2882C086
+4D43:08280828FF7C2A282A285DFE88101C7C2A54507C1E54227C5400082814446082
+4D44:105011FCFF5455FC5554BBFC100039FC5400A3FC3D0445FCA88810502BFEC000
+4D45:08207F20083E3E4408A87F1010281E462280FFFE11C82AB40DD0764E01801E40
+4D46:10481048FEFE544854FEBA82117C380054FEA2203CD2442CA8D8102C28CAC030
+4D47:081004107FD04910493E49247FD4491459145D946B544D084908491489140922
+4D48:111023E040480BFC110033F0551010E0111012883FFE24103F7C26384D549412
+4D49:00803FFE24103F7C26382D543492214026303BEE20002FA428A44FA448A4898C
+4D4A:0088788849FC488868885BFE4820FDFC492449FC492449FC4800488849049A02
+4D4B:282028207DFE28402840FEFC10847D8456FC54847C8454FC54847C8428944488
+4D4C:282028207C2029FC2820FEA810A87CA8557456227C50545054887C8829044602
+4D4D:282028107DFE280028FCFE8410FC7C0054FC54087C1055FE54107C1028504420
+4D4E:282029247D24292429FCFE0013FE7C20544055FC7D54555455547D542954450C
+4D4F:280029DC7C44295428CCFF5410287C44559254207CC8543254C47C1828604580
+4D50:280029DC7D54295429DCFE0011FC7D2455FC55247DFC542057FE7C2028204420
+4D51:0C00700011FCFE24382454A490A428A455249024542438445444928451142208
+4D52:0C0070FC1084FE8438845484908428FC54849084548438845484928450FC2084
+4D53:0C1070101090FE9038FE549091102810541091FE541038105410921050102010
+4D54:0C20702013FEFE2039FC552491FC292455FC9020547038A85524962250202020
+4D55:0C0071FC1104FF0439FC5510911029FE55109110557C394455449344517C2244
+4D56:7E7C48047E2842107E2848FC7F0001007FFC09103288CC643938C54609203310
+4D57:0C0071FC1000FEF83888548890F8280055FC9124552439FC5524932451FC2104
+4D58:0C0070FC1084FEFC388454FC900029FE548090FE552A3A4A5492932250542088
+4D59:0C00702010FEFE4438825520907C288854509068559E382254D49208503021C0
+4D5A:0C1E71E01022FF1238945480902029CE5502910255CE39025502930251FE2102
+4D5B:0C0071EE114AFFEA392A55E49144294A55F09000541038FE5410921051FE2000
+4D5C:0C5071FC1154FFFC395455FC900029FE5500917C550039FE5550935451482266
+4D5D:00207F2049206B205D2049207F2008207F2008200F20F022002255224A9E8000
+4D5E:00047F0449046B245D2449247F2408247F2408240F24F024000455044A948008
+4D5F:0000FE7C9210D610BA109210FE1010FEFE1010101E10E0100210AA10A8108010
+4D60:0040FE409240D6FCBA849304FE041084FE4410441E44E0040204AA04A8288010
+4D61:00003FF801007FFC04401830E00E3FF8292825483FF801007FFC0100FFFE4444
+4D62:0010FE109210D67CBA109210FE1010FEFE1010381E38E0540254AA92A8108010
+4D63:0000FE0092FCD684BA849284FEFC1084FE8410841EFCE0840200AA00A9FE8000
+4D64:3FF808200820FFFE0820102020207FF8292825483FF801007FFC0100FFFE4444
+4D65:0040FE40927CD684BB0892FCFEA410A4FEA410FC1E80E0800282AA82A87E8000
+4D66:0000FE9C9248D608BA889248FE5E1008FE2810481EC8E0480248AA48A8488018
+4D67:08207F280824FFFE00207F2049246B2449247F2808287F100812FFAA0046AA82
+4D68:0048FE449240D6FEBA509254FE581052FE5410581E52E054029AAA92A92E8240
+4D69:03043C2404247FA416242504440C3FF8292825483FF801007FFC0100FFFE4444
+4D6A:0000FEFC9284D684BAFC9284FE8410FCFE0010901E92E0F40298AA92A8D2808E
+4D6B:01007FFC50043EF84288A2AA1492187EE0003FF8292825483FF80100FFFE2448
+4D6C:0010FE1092DAD654BA549292FF501020FEFE10821E82E0FE0282AA82A8FE8082
+4D6D:0020FE2092FAD624BA2893FEFE201040FEFC11441E44E07C0244AA44A87C8044
+4D6E:0000FE7C9244D67CBA44927CFE0010FEFE40107E1EAAE12A024AAA92A82A8044
+4D6F:0008FE1C92E0D620BBFE9220FEFC10A4FEFC10A41EFCE02002FCAA20A9FE8000
+4D70:0040FE7E9280D77CBA44927CFE44107CFE0010FE1E40E0FE032AAA4AA8928026
+4D71:0010FE1092FED610BA7C9200FE7C1044FE7C10281EFEE000027CAA44A87C8044
+4D72:007CFE449244D67CBA0092EEFEAA10AAFEEE10101EFEE0380254AA92A9108010
+4D73:0010FE289244D6BABB0092FEFE9210D6FE9210FE1E00E07C0244AA7CA844807C
+4D74:0000FEFE92AAD6AABAEE9228FEEE10AAFEAA10EE1EAAE0AA02EEAAA8A82A801E
+4D75:20403F7E48909FF8149012501130FFFE08203FF8D55613901FF001007FFC2448
+4D76:200021FC21547D5445DC845075DC5554555455DC7554555405DC05502852103E
+4D77:100011FC11547D5411DC1050FDDC0154115411DC7D54115411DC1D50E052403E
+4D78:7C101052FE94382854449FF212901EF002803EF822883EF822883EFA028201FE
+4D79:201C7DC8917EFDC828185FF092901EF002803EF822883EF822883EFA028201FE
+4D7A:21F8210821F8250AF5FA250A25FA2402279E20903090EF9E4492049204920892
+4D7B:1C4414441CEE55445DEE55445DEE41447744140014FEF702557E550255FE9502
+4D7C:0440247C24A83D5004287DFE248844488FF848244FE448247FFC0440FC7C2444
+4D7D:0810FF7E08107E7C42447E282418FEE601003FF80100FFFE040008201FF00810
+4D7E:081017FE3210D15010200810FF1008FE7E1000FC7E4442487E2824101E28E0C6
+4D7F:0810FF1008FC7E1000FC7E4442287E1024281EC6E10001FC01003FF820083FF8
+4D80:0810FF7E08107E7C42047E4824381E44E10006C01830E7CE00001FF010101FF0
+4D81:0810FF7E08107E7C42447E3824447E8201187D6009183FF6D0101FF010101FF0
+4D82:2020CE208220EE7C82448284FE04008492449224DA249204DA0492049328D910
+4D83:2010CE108210EE2882288244FE4400A292109210DA7C9204DA0892089310D910
+4D84:2000CEFC8210EE1082948254FE58001093FE9210DA109210DA1092109310D910
+4D85:2020CE20823CEE4482A88210FE2800449282927CDA449244DA449244937CD944
+4D86:2028CE248240EE7E82C88348FE7E00489248927EDA489248DA48927E9340D940
+4D87:2010CE1082FEEE9282FE8292FEFE0000927C9244DA7C9244DA7C92449344D94C
+4D88:2014CE1283FEEE1082FE8292FEFE009292FE9292DA0493FEDA4492249324D90C
+4D89:2020CEDE828AEECA82AA82D2FEA6000092FE9292DA9292FEDA92929293FED982
+4D8A:20007CFC44247C2444247C240024FEFC9244FE449244FE440044FE4445FE8400
+4D8B:20007CFC44447C4844487C50005CFE449244FE449268FEA80090FE9845248442
+4D8C:20407C4044FC7C8445047EF40094FE9492F4FE849294FE880082FE82447E8400
+4D8D:0040FEF8208828F84488FCF8140011FC11247DFC112411FC1C00E3FE40880108
+4D8E:10103E1022283E2822443E82007C7F0049007F7C49447F440044FFC4227C4244
+4D8F:4420287C0044FC7C1444147CFC0090FE9092FEFE329232FE5A0054FE90441084
+4D90:20107C2844447CBA45007CFE0092FED69292FEFE9200FE7C0044FE7C4444847C
+4D91:20207CF844207DFC45047CF800A8FEF892A8FEF89244FEFC0020FEB844A0857C
+4D92:0100FFFE02847D78255025484D6420083FF820083FF822083FF8244843889C68
+4D93:2040202023FEF888A852AFACAAAAAAA8ADACA800A904B9FC210421FC21042204
+4D94:102050205C2050A0FEAC28B4AAE4D7A482A4FEB4AAA8AAA2D6A29E82E27E0200
+4D95:080028002F7C2854FF54145455546B54417C7F40554055406B424F42713E0100
+4D96:081028102F102828FF28144455446BA241107F10557C55046B084F0871100110
+4D97:0800287E2F042804FF74145455546B5441547F54557455546B044F0471140108
+4D98:082028102F1028FEFF00140455446B4441247F24552855286B084F1071FE0100
+4D99:0800287E2F402840FF40147C55446B4441447F44557C55406B404F40717E0100
+4D9A:081028102F10287CFF54145455546B54417C7F54551055146B124F7E71220100
+4D9B:7F0408441E44224454440844310CC9E009007FFC04402AA83FF824482AA83FF8
+4D9C:101050505C50507CFE502890AA10D6FE8200FE00AA7CAA44D6449E44E27C0244
+4D9D:102050205C2051FCFE2028A8AAA8D6A88374FE22AA50AA50D6889E88E3040202
+4D9E:082428242F7E2824FF24143C55246B24413C7F24552455FE6B004F2471220142
+4D9F:102050205C3C5044FE482880AA20D6CC8284FE84AACCAA84D6849E84E2FC0284
+4DA0:00283FFE20202FA420282F9048AA4FC68082010011F81100FFFE04402AA83FF8
+4DA1:100250E25CA250AAFEAA28EAAAAAD6AA82EAFEAAAAAAAAA2D6E29E02E24A02A4
+4DA2:100C500A5C0850FEFE882888AAFAD68A828AFEECAAACAAACD6EA9E8AE2960322
+4DA3:101050545C545054FE7C2800AAFED600827CFE44AA44AA7CD6449E28E2FE0200
+4DA4:1000507C5C445074FE5428FEAA82D67C8244FE7CAA44AA7CD6449E44E2540248
+4DA5:1020503C5C2050FEFEA228B8AAE4D69C8280FEBCAAA4AABCD6A49EBCE2A4037E
+4DA6:102051FC5C2050FCFE2029FEAA00D6FC8284FEFCAA84AAFCD6849EFCE2480284
+4DA7:101050105C7E5010FEFE2844AAEED6448264FEDEAA00AAFED6289E28E24A0286
+4DA8:101050105C285044FE82287CAA00D6EE82AAFEAAAAEEAA44D6449EAAE2AA0312
+4DA9:102050105DFE5054FFA828ACABAAD6A883ACFE00AA84AAFCD6849EFCE2840304
+4DAA:104C51FA5C4851FEFE082868AA5AD6FA83AAFEFCAAACAAFCD6AA9EFAE2960222
+4DAB:13DE52525FDE5000FFFE2A00AAC8D64E83EAFEB2AAEAAAAAD6EA9EB4E3E4022A
+4DAC:00007C7C1010FEFE1010101008407F7C1440FF7C22043E7C22403E7C2242263E
+4DAD:140012FE12101010FF90147C14101510151016FE260024022C02540243FE8000
+4DAE:04400420FFFE0910116021844F0480FC00001FF001007FFC028004401830600C
+4DAF:208027FC240427BCF0A056BE52A257B652AA96AA50B626A222BE57A052A2867E
+4DB0:1000FF8680B8F7881408D7CE5458F6C85548D54E16F8D44857CAF40A544ACFC6
+4DB1:408047FC740497BC50A026BE52A28FB60AAA66AA10B606A282BE47A022A2067E
+4DB2:104013FE12027FDE5450575E7D5257DA55565756FC5A4752455E47D055524B3E
+4DB3:081008081400227E5D0080807F3855287F2800287F28552A7F2A554A55464380
+4DB4:08402A7C48941410212846C41830EFEE00003BB82AA87FFC44447FFC4444444C
+4DB5:1004103E2BE0463CBA2002FCFEA4AAB8FEE4029CFE80AAB8FEA8AAAAAB2A8646
+4DB6:00007FFE6D8E6DB661B67DB67D8E7FFE7FFE63CE6DBE638E6DB663CE7FFE0000
+4DB7:00007FFE6D8E6DB661B67DB67D8E7FFE7FFE63866DF663EE6DDE63DE7FFE0000
+4DB8:00007FFE6D8E6DB661B67DB67D8E7FFE7FFE63CE6DB663CE6DB663CE7FFE0000
+4DB9:00007FFE6D8E6DB661B67DB67D8E7FFE7FFE63CE6DB663C66DF663CE7FFE0000
+4DBA:00007FFE6D8E6DB661B67DB67D8E7FFE7FFE63866DB663866DB663B67FFE0000
+4DBB:00007FFE6D8E6DB661B67DB67D8E7FFE7FFE638E6DB6638E6DB6638E7FFE0000
+4DBC:00007FFE6D8E6DB661B67DB67D8E7FFE7FFE63C66DBE63BE6DBE63C67FFE0000
+4DBD:00007FFE6D8E6DB661B67DB67D8E7FFE7FFE638E6DB663B66DB6638E7FFE0000
+4DBE:00007FFE6D8E6DB661B67DB67D8E7FFE7FFE63866DBE638E6DBE63867FFE0000
+4DBF:00007FFE6D8E6DB661B67DB67D8E7FFE7FFE63866DBE638E6DBE63BE7FFE0000
+4DC0:0000000000007FFC00007FFC00007FFC00007FFC00007FFC00007FFC00000000
+4DC1:0000000000007C7C00007C7C00007C7C00007C7C00007C7C00007C7C00000000
+4DC2:0000000000007C7C00007FFC00007C7C00007C7C00007C7C00007FFC00000000
+4DC3:0000000000007FFC00007C7C00007C7C00007C7C00007FFC00007C7C00000000
+4DC4:0000000000007C7C00007FFC00007C7C00007FFC00007FFC00007FFC00000000
+4DC5:0000000000007FFC00007FFC00007FFC00007C7C00007FFC00007C7C00000000
+4DC6:0000000000007C7C00007C7C00007C7C00007C7C00007FFC00007C7C00000000
+4DC7:0000000000007C7C00007FFC00007C7C00007C7C00007C7C00007C7C00000000
+4DC8:0000000000007FFC00007FFC00007C7C00007FFC00007FFC00007FFC00000000
+4DC9:0000000000007FFC00007FFC00007FFC00007C7C00007FFC00007FFC00000000
+4DCA:0000000000007C7C00007C7C00007C7C00007FFC00007FFC00007FFC00000000
+4DCB:0000000000007FFC00007FFC00007FFC00007C7C00007C7C00007C7C00000000
+4DCC:0000000000007FFC00007FFC00007FFC00007FFC00007C7C00007FFC00000000
+4DCD:0000000000007FFC00007C7C00007FFC00007FFC00007FFC00007FFC00000000
+4DCE:0000000000007C7C00007C7C00007C7C00007FFC00007C7C00007C7C00000000
+4DCF:0000000000007C7C00007C7C00007FFC00007C7C00007C7C00007C7C00000000
+4DD0:0000000000007C7C00007FFC00007FFC00007C7C00007C7C00007FFC00000000
+4DD1:0000000000007FFC00007C7C00007C7C00007FFC00007FFC00007C7C00000000
+4DD2:0000000000007C7C00007C7C00007C7C00007C7C00007FFC00007FFC00000000
+4DD3:0000000000007FFC00007FFC00007C7C00007C7C00007C7C00007C7C00000000
+4DD4:0000000000007FFC00007C7C00007FFC00007C7C00007C7C00007FFC00000000
+4DD5:0000000000007FFC00007C7C00007C7C00007FFC00007C7C00007FFC00000000
+4DD6:0000000000007FFC00007C7C00007C7C00007C7C00007C7C00007C7C00000000
+4DD7:0000000000007C7C00007C7C00007C7C00007C7C00007C7C00007FFC00000000
+4DD8:0000000000007FFC00007FFC00007FFC00007C7C00007C7C00007FFC00000000
+4DD9:0000000000007FFC00007C7C00007C7C00007FFC00007FFC00007FFC00000000
+4DDA:0000000000007FFC00007C7C00007C7C00007C7C00007C7C00007FFC00000000
+4DDB:0000000000007C7C00007FFC00007FFC00007FFC00007FFC00007C7C00000000
+4DDC:0000000000007C7C00007FFC00007C7C00007C7C00007FFC00007C7C00000000
+4DDD:0000000000007FFC00007C7C00007FFC00007FFC00007C7C00007FFC00000000
+4DDE:0000000000007C7C00007FFC00007FFC00007FFC00007C7C00007C7C00000000
+4DDF:0000000000007C7C00007C7C00007FFC00007FFC00007FFC00007C7C00000000
+4DE0:0000000000007FFC00007FFC00007FFC00007FFC00007C7C00007C7C00000000
+4DE1:0000000000007C7C00007C7C00007FFC00007FFC00007FFC00007FFC00000000
+4DE2:0000000000007FFC00007C7C00007FFC00007C7C00007C7C00007C7C00000000
+4DE3:0000000000007C7C00007C7C00007C7C00007FFC00007C7C00007FFC00000000
+4DE4:0000000000007FFC00007FFC00007C7C00007FFC00007C7C00007FFC00000000
+4DE5:0000000000007FFC00007C7C00007FFC00007C7C00007FFC00007FFC00000000
+4DE6:0000000000007C7C00007FFC00007C7C00007FFC00007C7C00007C7C00000000
+4DE7:0000000000007C7C00007C7C00007FFC00007C7C00007FFC00007C7C00000000
+4DE8:0000000000007FFC00007C7C00007C7C00007C7C00007FFC00007FFC00000000
+4DE9:0000000000007FFC00007FFC00007C7C00007C7C00007C7C00007FFC00000000
+4DEA:0000000000007C7C00007FFC00007FFC00007FFC00007FFC00007FFC00000000
+4DEB:0000000000007FFC00007FFC00007FFC00007FFC00007FFC00007C7C00000000
+4DEC:0000000000007C7C00007FFC00007FFC00007C7C00007C7C00007C7C00000000
+4DED:0000000000007C7C00007C7C00007C7C00007FFC00007FFC00007C7C00000000
+4DEE:0000000000007C7C00007FFC00007FFC00007C7C00007FFC00007C7C00000000
+4DEF:0000000000007C7C00007FFC00007C7C00007FFC00007FFC00007C7C00000000
+4DF0:0000000000007C7C00007FFC00007FFC00007FFC00007C7C00007FFC00000000
+4DF1:0000000000007FFC00007C7C00007FFC00007FFC00007FFC00007C7C00000000
+4DF2:0000000000007C7C00007C7C00007FFC00007C7C00007C7C00007FFC00000000
+4DF3:0000000000007FFC00007C7C00007C7C00007FFC00007C7C00007C7C00000000
+4DF4:0000000000007FFC00007FFC00007C7C00007FFC00007C7C00007C7C00000000
+4DF5:0000000000007C7C00007C7C00007FFC00007C7C00007FFC00007FFC00000000
+4DF6:0000000000007C7C00007C7C00007FFC00007FFC00007C7C00007FFC00000000
+4DF7:0000000000007FFC00007C7C00007FFC00007FFC00007C7C00007C7C00000000
+4DF8:0000000000007FFC00007FFC00007C7C00007FFC00007FFC00007C7C00000000
+4DF9:0000000000007C7C00007FFC00007FFC00007C7C00007FFC00007FFC00000000
+4DFA:0000000000007FFC00007FFC00007C7C00007C7C00007FFC00007C7C00000000
+4DFB:0000000000007C7C00007FFC00007C7C00007C7C00007FFC00007FFC00000000
+4DFC:0000000000007FFC00007FFC00007C7C00007C7C00007FFC00007FFC00000000
+4DFD:0000000000007C7C00007C7C00007FFC00007FFC00007C7C00007C7C00000000
+4DFE:0000000000007C7C00007FFC00007C7C00007FFC00007C7C00007FFC00000000
+4DFF:0000000000007FFC00007C7C00007FFC00007C7C00007FFC00007C7C00000000
+4E00:0000000000000000000000000000FFFE00000000000000000000000000000000
+4E01:00007FFC01000100010001000100010001000100010001000100010005000200
+4E02:0000FFFE040004000800080010001FF000100010001000100010001000A00040
+4E03:02000200020002000200023C07C0FA0002000200020002040204020401FC0000
+4E04:01000100010001000100010001000100010001000100010001000100FFFE0000
+4E05:0000FFFE01000100010001000100010001000100010001000100010001000100
+4E06:0000FFFE02000200040004000800080010002000400080000000000000000000
+4E07:00000000FFFE04000400040007F0041004100810081010101010201040A08040
+4E08:00800080008000807FFC0080108010800880048002800100028004401830E00E
+4E09:000000007FFC00000000000000003FF800000000000000000000FFFE00000000
+4E0A:02000200020002000200020003F80200020002000200020002000200FFFE0000
+4E0B:0000FFFE02000200020002000240022002100208020802000200020002000200
+4E0C:0000FFFE08200820082008200820082008200820082010201020202040208020
+4E0D:00007FFC00800080010001000340052009101108210441048100010001000100
+4E0E:1000100010001FFC1000200020003FF8000800080008FFC80008000800500020
+4E0F:0000FFFE01000100210021FC2104210421043FFC000400040004000400280010
+4E10:0000FFFE01000100210021FC2100210021003FFC000400040004000400280010
+4E11:00003FF0021002100210021002103FF0041004100410041004100410FFFE0000
+4E12:00003FF8010801080908050802080308048804880808105020200000FFFE0000
+4E13:0100010001003FF802000200FFFE040008000FF0001000200640018000400020
+4E14:00001FF01010101010101FF01010101010101FF01010101010101010FFFE0000
+4E15:00007FFC0080010001000340052009103108C1040100010001000000FFFE0000
+4E16:02201220122012201220FFFE122012201220122013E01000100010001FFC0000
+4E17:111011101110111011101110FFFE11101110111011101110111011101FF01010
+4E18:001000781F8010001000100010001FFC104010401040104010401040FFFE0000
+4E19:0000FFFE0100010001007FFC4104410442844244442448244004400440144008
+4E1A:04400440044004404444244424481448145014600440044004400440FFFE0000
+4E1B:08200820082008200820082008201450125022882088410482020000FFFE0000
+4E1C:0200020002007FFC04000900110021003FF80100092011102108410405000200
+4E1D:0810081010201020224442847CF804080810102020407EFC00000000FFFE0000
+4E1E:00003FF00020004000807D0405880950092011102108410685000200FFFE0000
+4E1F:00007FFC0100010001003FF8010001000100FFFE02000400082010103FF81008
+4E20:04400440044004447C48045004600440044204421C42E43E44000000FFFE0000
+4E21:0000FFFE0100010001007FFC410449244924492449244FE44024400440144008
+4E22:001000F83F00010001003FF8010001000100FFFE02000400082010103FF81008
+4E23:0000FFFE0440044004407C7C4444444444447C7C044408400840104020404040
+4E24:0000FFFE0440044004407FFC4444444444444AA44A9451144204400440144008
+4E25:00007FFC024012480A5002403FFE200020002000200020002000400040008000
+4E26:1010082004407FFC0440044004404444244414481450044004400440FFFE0000
+4E27:010001007FFC01001110091009200100FFFE1200111010A010401430180E1000
+4E28:0100010001000100010001000100010001000100010001000100010001000100
+4E29:0040004010401040104010401040104010C013401C4010400040004000400040
+4E2A:0100010002800440082010102108C10601000100010001000100010001000100
+4E2B:0000201010200840048001000100010001000100010001000100010001000100
+4E2C:0100010001001100090009000100030005000900310001000100010001000100
+4E2D:01000100010001003FF8210821082108210821083FF821080100010001000100
+4E2E:00007FF00410041004107FD0041004100410FFD00412040A040A040604020400
+4E2F:0100010C017007807900010C017007807900010C017007807900010001000100
+4E30:0100010001007FFC0100010001003FF8010001000100FFFE0100010001000100
+4E31:04400440444444444444444444444C44547C644404400840084010402040C040
+4E32:010001003FF8210821083FF8010001007FFC410441047FFC4104010001000100
+4E33:044004403FF8244824483FF8044004407FFC444444447FFC4844104020404040
+4E34:08800880088049FE49404A204C20480049FC492449244924492409FC09040800
+4E35:0440244814500440FFFE0000082004403FF801000100FFFE0100010001000100
+4E36:0000000000000000000004000200010000800040004000000000000000000000
+4E37:0000000000000008200810100810042004400080000000000000000000000000
+4E38:02000200020002007FE0022012200A20042004200A20092211222022401E8000
+4E39:00001FF0101010101210111011101010FFFE1010101010102010201040508020
+4E3A:010021001100110001007FF80208020802880448044808081008200840508020
+4E3B:0200010000007FFC01000100010001003FF801000100010001000100FFFE0000
+4E3C:08200820082008207FFC08200A2009200820FFFE082008201020102020204020
+4E3D:0000FFFE000000003EF822882288228832C82AA82AA82288228822882AA82490
+4E3E:2208110811100020FFFE082011102108CFE6010001007FFC0100010001000100
+4E3F:0100010001000100010001000100010001000200020004000400080010002000
+4E40:000000000000080008001400140024004200010000C00030000E000000000000
+4E41:000000003F000100010001000100010001000080008000400020001000080006
+4E42:000000102010201010201020082008400440028001000280044008203018C006
+4E43:00003FF00410042004200440047C040408040804080410041004200440288010
+4E44:000000100010001000100220012000C0004000A0011022102400380020000000
+4E45:04000400040007E008200820104020404080008001400240042008103008C006
+4E46:0010081008101020102020407FC020800080014001400220042008103008C006
+4E47:002003F03E00020002000200020003FCFE000200020002040204020401FC0000
+4E48:01000100020002000440084010802080410002000420081010083FFC10040000
+4E49:020001102110201010201020082008400440028001000280044008203018C006
+4E4A:0000000801FC7E00000820081010101008200840000000000000000000000000
+4E4B:02000100010000007FF800100020004000800100020004001800240043FE0000
+4E4C:010002001FF01010101010101050102010001FFC000400047FE4000400280010
+4E4D:080008000FFE12001200220043F882000200020003FC02000200020002000200
+4E4E:001000F83F0001001110091009200100FFFE0100010001000100010005000200
+4E4F:001001F87E0000000200010001007FF8003000C003000C003000480087FE0000
+4E50:002000F01F0010001100210021003FFC01000920091011082104410405000200
+4E51:000801FC7F00010009040908119021A045408540092011102108410681000100
+4E52:002000F01F00100010001FF81080108010801080FFFE00000800100020004000
+4E53:002000F01F00100010001FF81080108010801080FFFE00000040002000100008
+4E54:001000F83F00010002007FFC044008203018C826082008200820102010202020
+4E55:000800FC3F8020802FF8208020803FFE208020802FF82888488848A888900080
+4E56:00701F8001000100FFFE0100092009247928093009221922E91E010001000100
+4E57:00F83F0001007FFC09200920FFFE092009207FFC0380054009203118C1060100
+4E58:00F83F0001007FFC01000924F93809223922CB9E054009203118C10601000100
+4E59:00007FF00020004000800100020004000800100010002004200420041FFC0000
+4E5A:100010001000100010001000100010001000100010001004100410040FFC0000
+4E5B:00000000FFFC0004000800100000000000000000000000000000000000000000
+4E5C:000000001000103010D017103810D0101010105010201002100210020FFE0000
+4E5D:04000400040004007FE0042004200420082008200820102210222022401E8000
+4E5E:080008001FFC1000200040009FE000200040018006000804100410040FFC0000
+4E5F:010001001100113011D017103910D1101110115011201102100210020FFE0000
+4E60:00007FF8000800080808040802080208006801880E0870082008000800500020
+4E61:020002000420082010403F800108020804101FE000400080010006001800E000
+4E62:082008200820082049204920492049204920492049204F2279220022001E0000
+4E63:084008401040104022404240FC4004400840104024404242FE424242003E0000
+4E64:0000FFFE02000240022002100208020000007FF0006001800600180420041FFC
+4E65:000801FC7E000010101008200440008000007FF0006001800600180420041FFC
+4E66:0220021002083FE00220022002200220FFFC0204020402040204022802100200
+4E67:0040044002401240084009FC7E400040004000007FF0006003801C0420041FFC
+4E68:08200820102022204120FFA000A000207F20412041204122412241227F1E4100
+4E69:08200820082008200FA00820082008207F20412041204122412241227F1E4100
+4E6A:0000FDFC052405240924092411FC112421242124412441FC400240023FFE0000
+4E6B:100010007E7C124412441244227C4A4484007FF0006001800600180420041FFC
+4E6C:00003FFC20003FF820083FF820003FFC00007FF0006001800600180420041FFC
+4E6D:0000FFFE040008001FF02810C8100FF000007FF0006001800600180420041FFC
+4E6E:0C0070FC408444845C8464944488088010807FF0006001800600180420041FFC
+4E6F:00F87F0011100920FFFE01000100050002007FF0006001800600180420041FFC
+4E70:00007FFC0004088804802480108010800100FFFE010002C0042008103008C004
+4E71:04400E40384008400840FF40084008403E4022402240224222423E42223E0000
+4E72:4080208009FC12042448E04020A023182C0600007FF0006003801C0420041FFC
+4E73:02200F20F020012091204A200020FE20042008200F20F82248220822281E1000
+4E74:080C08F07E8008800EFE788808882908120800007FF0006003801C0420041FFC
+4E75:102008207F20002022201420FFA00820082008207F20082208220822081E0800
+4E76:012001107FFC01003FF821083FF821083FF8210800003FF001C01E0420041FFC
+4E77:1020082040A824A409221228703010C0170000007FF0006003801C0420041FFC
+4E78:0800087C28442E643A54EAFE2A442AA42A942EFE2804282A201220021FFE0000
+4E79:08200820FFA008207F2041207F2041207F2049200820FFA208220822081E0800
+4E7A:061838E020803EFC22903E902090411080007FF0006001800600180420041FFC
+4E7B:10100810FF2820443E822210220842204A1084087FF0006003801C0420041FFC
+4E7C:2080104087FC4040104023F8E040204027FC20007FF0006003801C0420041FFC
+4E7D:01081FD001207FFC02000FF03810CFF008100FF000003FF001C01E0420041FFC
+4E7E:104010401080FEFE11007E0044FC7C0844107C201040FE801102110210FE1000
+4E7F:0F20F020112089204220102022207C2008201120FFA008A24A228922281E1000
+4E80:04000FE010403FF051101FF011101FF001003FF821083FF821083FFA010200FE
+4E81:08200820FFA0087E7F4041807F7C41047F0800107F200840FFC20842083E0800
+4E82:0F20F02049202220FE2014200820FF209520BD208320BD2295228922951EA300
+4E83:082049202A20FFA02A20492088A04120412077A09120552227A24122811E0100
+4E84:0820FFA008207F200020FFA080A07F2000207F2041207F22412222220F9EF000
+4E85:0010001000100010001000100010001000100010001000100010001000500020
+4E86:00007FF800100020004001800100010001000100010001000100010005000200
+4E87:0800080008000FFC100411082110410001000100010001000100010005000200
+4E88:00001FF000100220014000807FFE008200840080008000800080008002800100
+4E89:080008001FE020204040BFF8010801087FFE010801083FF80108010005000200
+4E8A:010001007FFC111009203FF801080108FFFE010801083FF80108010005000200
+4E8B:01000100FFFE01003FF821083FF801003FF80108FFFE01083FF8010005000200
+4E8C:0000000000003FF800000000000000000000000000000000FFFE000000000000
+4E8D:00003FF80000000000000000FFFE010001000100010001000100010005000200
+4E8E:00003FF80100010001000100FFFE010001000100010001000100010005000200
+4E8F:00003FF8000000000000FFFE0400040008000FF0001000100010001000A00040
+4E90:00003FF8020002000200FFFE0400040008000FF0001000100010001000A00040
+4E91:00003FF80000000000000000FFFE0200040004000840102020107FF820080008
+4E92:00007FFC0400040004000FF008100810101010201FE0002000400040FFFE0000
+4E93:00003FF8000000000000FFFE0820082008200820082010201020202040208020
+4E94:00007FFC02000200020002003FF00410041004100410081008100810FFFE0000
+4E95:08200820082008207FFC0820082008200820FFFE082008201020102020204020
+4E96:000000003FF8000000000000FFFE0000000000003FF8000000000000FFFE0000
+4E97:010001002108210821083FF80000000000003FF80000000000000000FFFE0000
+4E98:00007FFC000000001FF0101010101FF0101010101FF0101000000000FFFE0000
+4E99:00007FFC0400040004000FF008100A10111010200420022000400040FFFE0000
+4E9A:00007FFC044004400440044044442444244814481450044004400440FFFE0000
+4E9B:04400440244427482470244224422F42F03E400000001FF0000000007FFC0000
+4E9C:00007FFC0440044004403FF824482448244824483FF8044004400440FFFE0000
+4E9D:0400082010103FF80810102024487EFC020400003FF8000000000000FFFE0000
+4E9E:00007FFC0440044004403C7820082008200820083C78044004400440FFFE0000
+4E9F:00003FF0002000400180793C49044944492849107928014405000200FFFE0000
+4EA0:020001000100FFFE000000000000000000000000000000000000000000000000
+4EA1:0200010001000000FFFE1000100010001000100010001000100010001FFC0000
+4EA2:020001000100FFFE000000000FE00820082008200820082210221022201E4000
+4EA3:020001000100FFFE042004200420042004200420042008200820102020204020
+4EA4:020001000100FFFE0000101010082024482404400280010002800C403030C00E
+4EA5:0200010000007FFC02000400082010403F8801100620184060A003100C087004
+4EA6:020001000100FFFE044004402450244824484444444488440840104021404080
+4EA7:020001007FFC00000820042004403FFE20002000200020002000400040008000
+4EA8:02000100FFFE00001FF0101010101FF000003FF0006001800100010005000200
+4EA9:020001000100FFFE000000003FF82108210821083FF82108210821083FF82008
+4EAA:02000100FFFE0440145024484844094010807FE0002000200010001000080006
+4EAB:020001007FFC00001FF010101FF000001FE000400180FFFE0100010005000200
+4EAC:02000100FFFE000000001FF01010101010101FF0010011101108210445040200
+4EAD:020001007FFC00001FF010101FF000007FFE40029FF401000100010005000200
+4EAE:020001007FFC00001FF010101FF000007FFE40028FE40820082010222022C01E
+4EAF:02000100FFFE00001FF010101FF000003FF8200820083FF8200820083FF82008
+4EB0:02000100FFFE000000001FF010101FF010101FF0010011101108210445040200
+4EB1:02000100FFFE0800080013F81208320853F89208120813F81208100017FC1000
+4EB2:020001003FF8000008200440FFFE010001007FFC010009201110210845040200
+4EB3:01007FFC00001FF010101FF000007FFE400280F43F00020003F87E02020201FE
+4EB4:01007FFC00001FF010101FF000007FFE41029FF401007FFC02003FE00822701E
+4EB5:0100FFFE000008407DF808480CC8784A08AA2906130204880C503530C60E0400
+4EB6:0100FFFE00003FF8200827C824483FF800001FF010101FF010101FF00000FFFE
+4EB7:010000803FFC041002203FFE22402FF822483FFE22482FF826604A50524C8240
+4EB8:20881048FC5001FC7D2445247DFC01247D2409FC10201C20F3FE102050202020
+4EB9:0100FFFE00002FEC48246BAC48246BAC4AA4FFFE90121FF010101FF01010FFFE
+4EBA:0100010001000100010001000280028004400440082008201010200840048002
+4EBB:0800080008001000100030003000500090001000100010001000100010001000
+4EBC:01000100010001000280028004400440082010102008C00600000000FFFE0000
+4EBD:010001000100028002800440082010102008C006020001000080008000000000
+4EBE:008000800080208020802140214022202220241028083006200020003FFE0000
+4EBF:080008000BFC1008101030203040508090801100110012021202120211FE1000
+4EC0:08200820082010201020302037FE502090201020102010201020102010201020
+4EC1:08000800080013FC1000300030005000900010001000100017FE100010001000
+4EC2:084008400840104013FC30443044504490441084108410841104110412281410
+4EC3:080008000BFE1020102030203020502090201020102010201020102010A01040
+4EC4:00003FFE20002000208020802080208020802140214022204220441088081006
+4EC5:08000BFC09041104110430883088508890501050102010201050108811041602
+4EC6:0840084008401040104030503048504490441040104010401040104010401040
+4EC7:090009000900110017F0311031105110911011101110121212121412180E1000
+4EC8:0800082009201120112031203120512091201110111012101208140818041002
+4EC9:080009F0091011101110311031105110911011101110111211121212120E1400
+4ECA:0100010002800440082012102108C10600001FF0001000200020004000800100
+4ECB:0100010002800440082010102008C82608200820082008201020102020204020
+4ECC:010001000280024004200810110861040100028002800440082010102008C006
+4ECD:080008000BF810881090309030A050BC90841084110411041104120412281410
+4ECE:0820082008200820082008200820082008501450125012882088210442048402
+4ECF:08400840084010401040308030805080910011101108120817FC120410041000
+4ED0:0100010002800440082010102108C10601000100FFFE01000100010001000100
+4ED1:0100010002800440082010102008C806083008C00F0008080808080807F80000
+4ED2:0100010002800440082010102008C6060180004000000C00030000C000200000
+4ED3:010001000280044008203018C0060FE00820082008A008440804080407FC0000
+4ED4:08000BF80808101010203040304057FE90401040104010401040104011401080
+4ED5:084008400840104010403FFE304050409040104010401040104017FC10001000
+4ED6:084008400A401258126832C833485E4892481248125812421202120211FE1000
+4ED7:081008100810101013FE30103010511091101090109010501020105011881606
+4ED8:081008100810101017FE30103010501091101090109010101010101010501020
+4ED9:1040104010402040244464446444A4442444244424442444244427FC20042000
+4EDA:0100010002800440082010102108C1060100210821082108210821083FF80008
+4EDB:081008780BC01040104030403040507E97C010401040104210421042103E1000
+4EDC:08000800080013FE10203020302050209020102010201020102017FE10001000
+4EDD:0100010002800440082010102008C0061FF0010001000100010001007FFC0000
+4EDE:080008000BFC1044104432443244524494841084108411041104120414281810
+4EDF:081008780BC0104010403040304057FE90401040104010401040104010401040
+4EE0:08000BFC084010401040304030405FFE90401040104010401040104010401040
+4EE1:08800880090011FE1200340031F8500890101060108011001202120211FE1000
+4EE2:08800880090011FC120432043404590490841044104410041004100410281010
+4EE3:089008880888108010BE37C03080504090401040102010221012100A10061002
+4EE4:01000100028004400A2011102108C0061FF00010002004400280010000800080
+4EE5:0010041022102110211020102010202020202020244028503088210402020402
+4EE6:0820082008201020102031283124512492221222122214221020102010A01040
+4EE7:02000200020003F8020002000200FFFE0100010001000280044008203018C006
+4EE8:080008000BFC100010003000300051F89000100010001000100017FE10001000
+4EE9:084008400840104010403040307C504090401040104010401040104017FE1000
+4EEA:088008480A481208120831103110511090A010A01040104010A0111012081406
+4EEB:084008400880108011003110321054209020104010801108120417FE12021000
+4EEC:0900088008BC1204120432043204520492041204120412041204120412141208
+4EED:080008000BF81088108832883188508890C810A81098110E1108120814501820
+4EEE:0808083C0BC012001200320033F8528892881288125012501220145014881906
+4EEF:0840084008401148114432423242544890481048101010101020104011801600
+4EF0:080008800B3C122412243224322452249224122412B413281220102010201020
+4EF1:0840084008A010A01110328834465040900013F8100810101010102010201040
+4EF2:084008400840104017FC3444344454449444144417FC14441040104010401040
+4EF3:08200A200A2012221222322433A85230922012201220122212A21322121E1000
+4EF4:080009FC09041104110431FC31045104910411FC110411041204120414141808
+4EF5:11001100110023F8224062406440A04020402FFE204020402040204020402040
+4EF6:082008200920112011FC322032205420902017FE102010201020102010201020
+4EF7:0840084008A010A0111032083406511091101110111011101110121012101410
+4EF8:081008780FC0104010403040304057FE904010A010A011101110120814041802
+4EF9:08400840084017FC10403040304053FC9040104010401FFE1040104010401040
+4EFA:01000280044008203018C0061FF01000100010001FF01000100010001FF80000
+4EFB:081008780BC010401040304030405FFE90401040104010401040104017FC1000
+4EFC:080008000BFE1020102030203020502091FC1020102010201020102017FE1000
+4EFD:081008900890108811083104320455FA90881088108810881108110812281410
+4EFE:08000FFE08801080108030F8310851089108120813F810101010101017FE1000
+4EFF:08800840084017FE11003100310051F891081108110811081208120814501820
+4F00:082009200920111011103248324854449882108011101108120817FC12041000
+4F01:010001000280044008203118C1060100110011F81100110011001100FFFE0000
+4F02:1040104010402FFE2040604067FCA44424442444244424542448204020402040
+4F03:08000BF80808111010A0304037FE504290441040104010401040104011401080
+4F04:08000BFC08441044104433FC32405240944017FE10421042104A104410401040
+4F05:08400840084017FC1040324832485248924813F81048104010421042103E1000
+4F06:09000900090011FC12A434A430A4512491241244144410841104120414281010
+4F07:080009F0091011101110320E340053F891081110109010A0104010A013181C06
+4F08:0800088008401020112031003100550495021502150219081108110810F81000
+4F09:08800840084013FC1000300031F05110911011101110111211121212120E1400
+4F0A:08000BF808881088108837FE30885088908813F8108810801100110012001400
+4F0B:100017F81108211021106120613CA10421042288228822502420245028882306
+4F0C:08000BFE0A00120012F8328832885288928812A81290128214821482187E1000
+4F0D:08000BFC084010401040304033F8508890881088108811081108110817FE1000
+4F0E:08400840084017FE10403040304057F892081208111010A0104010A011181606
+4F0F:0840085008481048104037FE3040504090A010A010A011101110120814041802
+4F10:089008880888108010BE37C03080504490441048103010221052118A16061002
+4F11:084008400840104017FE304030E050E091501150124814441842104010401040
+4F12:0808081C09E011001100310031FE511091101110111011101110121012101410
+4F13:080008000BFE102010203040304050D091481244144410401040104010401040
+4F14:080008000BFE12021404300031F05110911011101110111212121212140E1800
+4F15:08400840084013FC10403040304057FE904010A010A011101110120814041802
+4F16:088008800880108017FE3080310051FC91441244124814501420185010881306
+4F17:0100010002800440082010102828C82608200820082014501250228841048202
+4F18:089008880888108017FE30A030A050A090A010A01120112211221222121E1400
+4F19:08400840084010401244324432485450904010A010A011101110120814041802
+4F1A:010001000280044008203018CFE6000000007FFC02000400082010103FF81008
+4F1B:08000BFC0A001208128832503250522092201250125012881308120013FE1000
+4F1C:088008800BF01090109031123112524E944010401FFE10401040104010401040
+4F1D:080008000BFC10001000300037FE50409040108010801108120417FE12021000
+4F1E:010001000280044008203018C1061110091009200100FFFE0100010001000100
+4F1F:08400840084017FE1040304033FC5040904017FE10421042104A104410401040
+4F20:08400840084013F81040308037FE5080910013F81008111010A0104010201020
+4F21:08400840084017FE108030A0312053FC90201020102017FE1020102010201020
+4F22:08000BFC0810111011103110321053FE90301050109011101210141010501020
+4F23:08000BF80A0812081248324832485248924812A812A81120112012221422181E
+4F24:08800880090011FE12003440304053FC90441044108410841104110412281410
+4F25:090009080908111011203140310057FE91401120112011101108114411821100
+4F26:0840084008A010A0111032083406511091201140118011001104110410FC1000
+4F27:0840084008A01110120834043BF2521092101210125012201204120411FC1000
+4F28:0900090009FC1204120435043884508490141024104413841104100410281010
+4F29:08800840084017FC1110311031105110911010A010A0104010A0111012081C06
+4F2A:08400A4009401140104037FC30445044908410A4109411141104120414281810
+4F2B:084008200820100013FE3202340450009000100010001000100013FE10001000
+4F2C:080009FC090411041104310431FC512491201120111011101208120814041802
+4F2D:08800840084017FE104030803108521097E0104010801108120417FE12021000
+4F2E:12001200127C22242FA464A464A4A4A824A82928251022102528294830842102
+4F2F:08400840088013FC120432043204520493FC1204120412041204120413FC1204
+4F30:084008400840104017FE30403040504093F81208120812081208120813F81208
+4F31:0840084008A010A0111032083446504091501148124812441444104011401080
+4F32:08000BFC0A041204120433FC32005240924412481270124014421442183E1000
+4F33:08480A480A481248124837FE3248524892481248127812001200120013FE1000
+4F34:08400A4409481150104037FC3040504090401FFE104010401040104010401040
+4F35:1000100017FC24A424A464A464A4A4A424A42524251C26042404240427FC2404
+4F36:0840084008A010A0111032483426502093F810081010111010A0104010201020
+4F37:104010401040204027FC64446444A444244427FC244424442444244427FC2404
+4F38:08400840084017FC14443444344457FC94441444144417FC1444104010401040
+4F39:080009F809081108110831F831085108910811F8110811081108110817FE1000
+4F3A:08000BFC0804100417F43004300453E492241224122413E41004100410141008
+4F3B:08000BF808401040124831483150504097FE1040104010401040104010401040
+4F3C:1008110810882448244864086408A40824102410241025282624244420822102
+4F3D:140014001400243C2FA464A464A4A4A424A424A424A424A428A428BC32A42100
+4F3E:08000BFC082010201040304030D0514892441444104010401040100017FE1000
+4F3F:080008000BFC1204120432043204520493FC1204100010901088110412021402
+4F40:08000BF80A0812081208320833F85200920013FC120412041204120413FC1204
+4F41:08400840088010801110320837FC5004900013F8120812081208120813F81208
+4F42:080008000BFE10201020302031205120913C1120112011201120112017FE1000
+4F43:1000100017FC2444244464446444A7FC2444244424442444244427FC24042000
+4F44:090809080908110817FE310831085108910811F8110811081108110811F81108
+4F45:08400840084013FC10403040304057FE90E01150115012481444184210401040
+4F46:080008000BFC12041204320433FC52049204120413FC12041000100017FE1000
+4F47:08400820082013FE120234043000500093FE1020102010201020102010A01040
+4F48:08400840084017FE108030A0312051FC93241524112411241134112810201020
+4F49:084008400840104013FC30403040504097FE1040108010801110120817FC1204
+4F4A:08200820082013FE12223224322053FC92841288124812501220145014881906
+4F4B:08000BFC088410841084310431145208940011FC110411041104110411FC1104
+4F4C:1120112011202522252265E46528A530252025202520252225E23E22281E2000
+4F4D:088008400840100017FC3000300852089208111011101110112010201FFE1000
+4F4E:0808083C0BE0122012203220322053FE9220121012101212120A128A13261212
+4F4F:08800840080017FC104030403040504097FC104010401040104010401FFE1000
+4F50:088008800880108017FE30803100510091FC1220122014201420182013FE1000
+4F51:084008400840104017FE30803080510093FC1504190411041104110411FC1104
+4F52:08400840084013F81248324832485248924817FE104010A010A0111012081406
+4F53:084008400840104017FC304030E050E091501150124815F41842104010401040
+4F54:084008400840107E104030403040504093FC1204120412041204120413FC1204
+4F55:0800080017FE1008200833C8524892481248124813C812481008100810281010
+4F56:1000108010402028212861086110A51425222522254229882108230824F82800
+4F57:08400820082013FE12023404310051089110112011C011021102110210FE1000
+4F58:010001000280044008203018CFE6000000007FFC010011101108210445040200
+4F59:0100010002800440082010102FE8C10601003FF8010011101108210445040200
+4F5A:104010401240224023FC62406440A0402FFE204020A020A02110220824042802
+4F5B:1120112011202FFC2124612467FCA52029202FFE21222122222A222424202820
+4F5C:09000900090011FE12803280348050F890801080108010FC1080108010801080
+4F5D:11001100120023FC2404680463E4A22422242224222423E42224200420282010
+4F5E:100013F8100020002FFE60806080AFFE21082210261021A02060209023082C04
+4F5F:0880088008F81108131034A0304050A093181C0610C010201010118010601010
+4F60:08800880088011FE110232043420502091281124122412221422102010A01040
+4F61:1040104010A020A0211062086444A84220402444244424442444244427FC2004
+4F62:08000BFE0A001200120033FC320452049204120413FC12001200120013FE1000
+4F63:100017FC14442444244467FC6444A444244427FC244424442444284428543008
+4F64:080008000FFC1100110031F0311051109190125012501210121212921312120E
+4F65:0100010002800440082010102FE8C0060210111009100920082000407FFC0000
+4F66:080008000FFE104010403080308051F893081508190811081108110811F81108
+4F67:084008400840107C10403040304057FE90401040105010481044104010401040
+4F68:0880088009FC1104120435F431145114911411F4110411281112110210FE1000
+4F69:100017FC1404240425F464446444A5F425542554255425542574244624462842
+4F6A:080008000BFC1204120432F4329452949294129412F41204120413FC12041000
+4F6B:0880088009F81208151030A0304050A093181C0613F812081208120813F81208
+4F6C:08400840084413F41048305037FE504090801184129814E018821082107E1000
+4F6D:0900090009F8131014A0304031B0564E904013FC1040144017FE104010401040
+4F6E:0840084008A011101208340633F85000900013F8120812081208120813F81208
+4F6F:0A0809080910100017FC3040304053F89040104017FE10401040104010401040
+4F70:08000BFE08201020104031FC31045104910411FC110411041104110411FC1104
+4F71:010001000280044008201010EFEE000000007FFC0100010011F811001100FFFE
+4F72:0880088008FC1104128834503020504091FC13041D0411041104110411FC1104
+4F73:084008400BFC1040104030403FFE50009040104013FC1040104010401FFE1000
+4F74:08000BFE09081108110831F83108510891F811081108111E17E8100810081008
+4F75:090408840888100013FE308830885088908817FE108810881108110812081408
+4F76:0840084008401FFE1040304037FC5000900013F8120812081208120813F81208
+4F77:08000BF80A08120813F83208320853F892441248123012201210128813061200
+4F78:081008780BC01040104037FE30405040904013F8120812081208120813F81208
+4F79:1100110013F8220824106BFE6200A2F82288228822A8229022822482247E2800
+4F7A:0840084008A011101208340633F850409040104013F810401040104017FE1000
+4F7B:089008900890149212943098309051989294149210901090111211121212140E
+4F7C:10801040104027FC200061106208A4042110211020A0204020A0211022082C06
+4F7D:102010201420227E224260846010A11021102E10222822282248224420842102
+4F7E:081009100908120814043BFA3208520893F81208120813F81208120812281210
+4F7F:104010401FFE2040204067FC6444A44427FC2040224021402080214022302C0E
+4F80:10041FC414842494249464946494AFD424942494249424942484288428943088
+4F81:10401240124023FC244068406040A7FE212021202120212022222222241E2800
+4F82:084008200BFE12001200320C32F052209220123E13E0122014221422181E1000
+4F83:100017FC14042404240467FC6000A2482248224822482248224A244A244A2806
+4F84:100017FE104020802110620867FCA0442040204027FC2040204020402FFE2000
+4F85:08400820082017FE10403084310853F090221044118816101020105011881604
+4F86:0100010001007FFC010011101110292845440380054009203118C10601000100
+4F87:1040104017FE204027FC604463FCA240244027FE204220AA20A4211022082C06
+4F88:1080108011F82210252060C06090A3202C7C2084210826902060204021802E00
+4F89:1040104017FC20A0211062086DF6A00027FC2080210023F82008200820502020
+4F8A:084008440A4411481150304037FE5090909010901090109211121112120E1400
+4F8B:1004100417C42214221463D46254A45426542554289420942104220424142808
+4F8C:01000280044009203098CFE6004000803FF800000000FFFE082010103FF80008
+4F8D:08400840084013FC1040304037FE5010901017FE101012101110111010501020
+4F8E:084008400A4811481150304037FE504090E01150115012481444184210401040
+4F8F:08400A400A4013FC14403040304057FE90E01150115012481444184210401040
+4F90:084008400880110013FC3294329452949294129412941294129412941FFE1000
+4F91:084008400FFE1080110031FC3304550499FC1104110411FC1104110411141108
+4F92:08400820082013FE12023444304053FE90881088110810D01020105010881304
+4F93:084008400BF8104817FE304833F85040904017FC104010401FFE104010401040
+4F94:084008400890110813FC30243120512091FC1220102017FE1020102010201020
+4F95:100017FC10402040208067FC64A4A4A424A424A424A424A424A4248424142408
+4F96:010002800440082037D8C00600003FF82488248824883FF82488248824A82010
+4F97:100017FC1404240425F464046404A5F425142514251425F42404240424142408
+4F98:08400820082013FE12023404303853C090401040107E17C0104010421042103E
+4F99:082808240824102017FE3020302057E0912011101110111011CA170A12061002
+4F9A:08800880090011FC1204340433E45224922413E41224122413E4100410281010
+4F9B:091009100910111013FC311031105110911017FE100011101108120814041804
+4F9C:088009000BF812081288324832485FFE92081288124812481208120814281810
+4F9D:08800840084017FE108030803140514493481530192011101108114411821100
+4F9E:090009000900111E17D232523252525292521492129211121292125E14521800
+4F9F:08400840084017FE10803080317C51089310151011FE11101110111011501120
+4FA0:08400840084017FC10403248315050409FFE10A010A011101110120814041802
+4FA1:100017FE10A020A020A067FC64A4A4A424A424A424A424A424A427FC24042000
+4FA2:08000FFC0840104013F83248324853F8924812481FFE12081208120812281210
+4FA3:100013F8120822082208620863F8A000200027FC240424042404240427FC2404
+4FA4:088008880BE8109010A037FE3080510093FC1480190011F81008100810501020
+4FA5:0880088008BC13C01050302430D4530C900017FE1090109011121112120E1400
+4FA6:08400840087E1040104033F832085248924812481248124810A0111012081404
+4FA7:100417C414442454255465546554A55425542554255421042284224424142808
+4FA8:081008780BC01040104037FE30A0511092081516111011101110121012101410
+4FA9:0840084008A011101208340631F05000900017FC104010801110120817FC1204
+4FAA:088008400FFE1208111030A0304051B0960E1110111011101110121012101410
+4FAB:088008401FFE12001200320033FC508090801FFE110812081390106011981604
+4FAC:10401040104027FC248468886140A14423482530292021102108214421822100
+4FAD:08000BF80A08120813F8322032205210920814C61420180011C0103010081000
+4FAE:0900090009FC120015F831083148512897FE11081248122813FC100810501020
+4FAF:08000BF80808100817FE3100310053F8944010401FFE104010A0111012081C06
+4FB0:08000BF80888108817FE3088308853F89100110013F815081908110811F81108
+4FB1:08000BF80A081208120833F83000500097FC1040104013F8104010401FFE1000
+4FB2:08000BFC0A00120012F83200320053FC92A012A412A812901290148814A418C2
+4FB3:084008400A4812481248355438E25040904017FC10401040104010401FFE1000
+4FB4:01000280044008203018CFE600003F04092409243F241124112417A47804200C
+4FB5:08000BF8080811F8100833F8300057FC940413F01110111010A0104011B0160E
+4FB6:080009F8090811081108310831F85040908013FC120412041204120413FC1204
+4FB7:08000BF80A08120813F83200320053FC920412F41294129414F4140418281010
+4FB8:08000FFC0800100013F8320832085208920813F810001208110811101FFE1000
+4FB9:1000100C1770211021106210627CA710211025102510227C2200250028FE3000
+4FBA:08400A480A48124813F8304030A0511092881446104013F01010102010201040
+4FBB:0A0809080910102013F832083208520893F810A010A0112011221222141E1800
+4FBC:082008200BFE1020102033FE3202540491F81010102013FE1020102010A01040
+4FBD:0BF80A480A4813F81248324833F85080908017FC108411041104120414281810
+4FBE:084008440BF41048104837FE3020504093F81110122015FE1820102010A01040
+4FBF:100017FE104027FC2444644467FCA444244427FC224021402080214022302C0E
+4FC0:0808083C0BC01044122431283100504093FE1088110813901060105011881604
+4FC1:080008F80888108812F83200320053FC9044104417FE104010A0111012081406
+4FC2:0804081E0BE01080110833F030205048918417FE102211281124122214A21040
+4FC3:08000BF80A0812081208320833F8504090401240127C12401240154018FE1000
+4FC4:102811A41724212021206FFE6120A12421A423282D2821102112212A25462282
+4FC5:085008480848104017FE304032445164916810D0115012481444104211401080
+4FC6:0840084008A01110120835F63040504097FC1040125012481444184411401080
+4FC7:08000C400ABE110812883488308850BE918812881488108810881088153E1200
+4FC8:08400A400A4013FC14403840304057FE9000100013F812081208120813F81208
+4FC9:08000FFC0880108013F83108310857FE9000100013F812081208120813F81208
+4FCA:084008400888110413FE300230885144924210F8118812501020105011881606
+4FCB:08000BF80A08120813F8300037FC54449444144417FC14001402140213FE1000
+4FCC:1048104417FE2040204067FC6444A44427FC2444244427FC2444244424542408
+4FCD:088008400BF81208120833F83208520893F81240124412281210128813061200
+4FCE:100011F811082908250845F891081108110811F8290825084508810807FE0000
+4FCF:08400A4809481150104033F83208520893F81208120813F81208120812281210
+4FD0:108411C417042114211461146FD4A11423142394255425042904210421142108
+4FD1:100017F8101021A0204067FC6444A44427FC2444244427FC2444244424542408
+4FD2:084008200BFE1202140431F83000500093FE10901090109011121112120E1400
+4FD3:08000BFC080011241248349032485124900013FC104010401040104017FE1000
+4FD4:08000BF80A08120813F83208320853F89208120813F81120112012221422181E
+4FD5:1080104017FE2402284460406040A7FC20E02150215022482444284220402040
+4FD6:100017FC1020204020D061486644A040200023F8220822082208220823F82208
+4FD7:091009080A041444104030A0311052089C0613F8120812081208120813F81208
+4FD8:0808083C0BC0100412443128300053F89010102017FE10201020102010A01040
+4FD9:1208111010E02110220860806FFEA140224027FC2A4422442254224820402040
+4FDA:100017FC1444244427FC64446444A7FC2040204027FC2040204020402FFE2000
+4FDB:0900090009F01210122037FC3A445244924413FC12A410A0112012221422181E
+4FDC:1040104017FC244427FC644467FCA0003FFE2100220023FC2004200420282010
+4FDD:08000BF80A081208120833F83040504097FC10E0115012481444184210401040
+4FDE:01000280044008203018CFE600003E0822483E4822483E48224822082A282410
+4FDF:104010801110220827FC61046100A3F8244020402FFE204020A0211022082C06
+4FE0:08400840084017FE1040324832485248955418A210A011101110120814041802
+4FE1:084008200BFE1000100031FC3000500091FC1000100011FC1104110411FC1104
+4FE2:0880088009F8131014A0304031B05E4E90801320104411881610102010C01700
+4FE3:08000BF80A08120813F83000300057FC904010401FFE104010A0111012081406
+4FE4:09080888089013FC1024302433FC5220922013FE106210A2112A122414201020
+4FE5:104010401FFE204027FC64446444A7FC2444244427FC20403FFE204020402040
+4FE6:1040104017FC204023F8608067FEA090211021FE221022902450281020502020
+4FE7:08200820082013FE10203020302051FC9040102010A41282128A128A14781000
+4FE8:08000BFC089012941198309033FE520092001200120012001200140014001800
+4FE9:10001FFE1120212021206FFC6924A92429242AA42A542C4C2884280428142808
+4FEA:10001FFE1000200027BC64A464A4A4A426B425AC24A424A424A424A424A425AC
+4FEB:08400840084017FC10403248314851509FFE10E0115011501248144418421040
+4FEC:108811C81F08210821086FD06110A3102390255425642922217E212221022100
+4FED:0840084008A010A01110320835F6500090881048124811501110102017FE1000
+4FEE:1080108011F821082A906C60A9982E2628C02B10282028C82B10206021802600
+4FEF:1040102017FE2400248864886508A57E27082548252825282908290831282110
+4FF0:100011801700211E21126FD26112A3122392235225522512291E211221002100
+4FF1:08000BF80A08120813F8320833F8520893F8120812081FFE1000111012081404
+4FF2:12101110111027D0203E62926252A452289222922112211222A224A2284A2084
+4FF3:089008900890179E109030903090539C909010901090179E1090109010901090
+4FF4:10A0109010BC27C8205060646194AE0C20A0209020BC27C82050206421942E0C
+4FF5:1040104017FC2040204063F86040A0402FFE2088215023202510294821862100
+4FF6:0900090009DC11141114311437D4501491141114158815481948111415141222
+4FF7:100017BE14AA24AA24AA67AA64AAA4AA24BE27A024A024A024A228A22AA2311E
+4FF8:084008400FFC104013F8308037FC51109248144611F0104017FC104010401040
+4FF9:08000FFE089010901090339C320452049204139C109010901090109017FE1000
+4FFA:084008800BFC11101248344633F85248924813F81248124813F810421042103E
+4FFB:0880088009F81208151030E033185C0693F81248124813F81248124813F81208
+4FFC:088008400FFE1100120837FC300453F8920813F8120813F81208120812281210
+4FFD:101010901710243E242264446790A51025102510252825282528294429443082
+4FFE:084008800BFC1224122433FC3224524493FC1090111017FE1010101010101010
+4FFF:08400840087C104013FC3244327053C09244123C120012F0149014921912120E
+5000:080009FC090011F8110031F831005FFE92801248125012201210128813061200
+5001:09000900090013DE129234923092509293F2109210921152115E122014201800
+5002:08840884090813DE110831083108510897BE1108110811081108120812081408
+5003:1110111013D8225424526A906110A2FE2C00200023F822082208220823F82208
+5004:09080890086011981644304037FE508091FC130415FC110411FC110411141108
+5005:088008400BFC10001110311032A854449000104017FE10401040104010401040
+5006:100017FC1040204027FC64446444A6642554255426EC24CC2444244424542408
+5007:1080104017FE24022A04620063BCA4A424A426A429342128222222222422281E
+5008:08400840084017FC1040324832485248955410E0115011501248144418421040
+5009:0100028004400A203118DFF610101FF010101FF010002FF8280848088FF80808
+500A:089008900908114812443492310853FC9044102010A41282128A128A14781000
+500B:100017FC1444244427FC64446444A5F425142514251425F42514240427FC2404
+500C:084008200BFE1202140431F83108510891F81100110011FC1104110411FC1104
+500D:088008400BFC100012083108311057FE9000100013FC12041204120413FC1204
+500E:08900890089013FC12943294329453FC92941294129417FE1000109011081204
+500F:1080108011F821082A906C60A9982E46285028482BFC284028A0211022082404
+5010:0840084010FC10883550542094D81706142014A414A415281450104810841302
+5011:100017BC14A424A427BC64A464A4A7BC24042404240424042404240424142408
+5012:100410041FC422142214649467D4A114211427D42114211421C42E0424142008
+5013:08400A440A44144810A0311036085044904012481248145010A0111012081C06
+5014:100017FC1404240427FC64206524A524252425FC242025242524292429FC3004
+5015:081008780BC01040104037FC324852489FFE1248124817FC1040104017FC1000
+5016:084008400FFC1040104037FE311050A097FC104010401FFE1040104010401040
+5017:100017BC14A424A424A467BC64A4A4A424A427BC24A424A424A424A42AA4314C
+5018:1040124811482150204067FC6404A40425F425142514251425F4240424142408
+5019:100013F8100828082FFE69006900ABF82C4028402FFE284028A0211022082C06
+501A:084008400BFC10A01110320837FE500893C812481248124813C8100810281010
+501B:090809080FFE1108110831F83108510891F81108110817FE1000109011081204
+501C:100017FC1444244425F464446444A7FC240425F42514251425F4240424142808
+501D:08100810FF9008107F1041107F1041107F1049100828FFA80848084408840902
+501E:088008400FFE1000100033F83208520893F81040125012481444184411401080
+501F:09100910091017FC111031103FFE500093F81208120813F81208120813F81208
+5020:09400920092013FE122036203BFC5220922013FC12201220122013FE12001200
+5021:09F80908090811F81108310831F8500093FC1204120413FC1204120413FC1204
+5022:1040104017FE204023F8604867FEA04823F820402240227C2240254024FE2800
+5023:1410121012102FA0243E644467A4A4A424A824A8249024902AA8292830442082
+5024:082008200BFE104011FC3504350455FC950415FC1504150415FC140017FE1000
+5025:08400820082013FE1202349431085204900011FC102010201020102017FE1000
+5026:10401248115027FC208061006FFEA21024082BF43212221022502224220421FC
+5027:1080104017FE2402280463F06000A00027FC2040225022482444284421402080
+5028:08000BFC0A04120413FC3220322053FE9220122012FC12841284148414FC1884
+5029:084008400FFC104013F8304037FE500093F8120813F8120813F8120812281210
+502A:080008400B9C12041204339C3204520493FC109010901090109011121212140E
+502B:1040104010A0211022086DF66000A7FC24A424A427FC24A424A424A424142408
+502C:08400840087E104013FC320433FC520493FC1244104017FE1040104010401040
+502D:08380BC00840104017FC315032485486908017FC1110121011A0106010901308
+502E:08000BF80A48124813F83248324853F8904017FC10E011501248144610401040
+502F:12081228122822282FA462446254A69227102AA02A203228224422FC22442200
+5030:1040104017FC204020406FFE6208A484288221F82208251020A0204021B02E0E
+5031:100017FC1404240427FC64046404A7FC20002420242227AC2430242225A2261E
+5032:104010401FFE2040204067FC6444A7FC244427FC24E421502248244438422040
+5033:104010401FFE204027FC644467FCA04027FC20443FFE204427FC204021402080
+5034:084008400FFE10A01150324835F650409150111017FE11101110111012101410
+5035:081008180BD41014101037FE30105090909012D012901290128A12EA17061202
+5036:08000BFC0A04120413FC320433FC5204920413FC100017FE1000110812041402
+5037:084008400FFC10A01110320835F65000900017FC104012481244144411401080
+5038:0808083C0BC01044122431283100502093FE107010A810A81124122214201020
+5039:0840084008A01110120835F63040504093F81248124813F810A0111012081406
+503A:084008400FFC104013F8304037FE500093F8120812481248124810A011101608
+503B:10001FDE14922492249467946498A49427922492249225DA2E94209020902090
+503C:084008400FFC1040104033F8320853F8920813F8120813F8120812081FFE1000
+503D:0840084008A01110120835F63040504097FC1040104013F81208120813F81208
+503E:100010FE14102420247C64446754A45424542454255426542420202820442082
+503F:088008400BFC10001108309037FE5040904017FE108811081090106011981604
+5040:1110111017FC21102150604063F8A248224822482FFE204020A0211022082406
+5041:103E17C0108424442208604067FCA444244427FC244424443FFE240424142408
+5042:09080888089017FE100033C43254525493D41254125413D412541244125412C8
+5043:08000BFE0A0012FC128432FC328452FC922013FE124812C812301248128413FE
+5044:100017FC1040208027FC64A464A4A4A42484244C20402FFE20A0211022082C06
+5045:1008103C17C020402FFE604067FCA44427FC244427FC204027FC20402FFE2000
+5046:1040104017FC204023F860806FFEA110220827FC2A0A220823F82208220823F8
+5047:100017BC14842484248467BC6400A40027BC2424242427A82410242824442482
+5048:08000BF80A0813F8120833F8310053FC9444124412A4120413F4100410281010
+5049:088008800BF8110817FE300033F8520893F8104017FC1040144017FE10401040
+504A:0804081E0BE0102011FC3124312451FC902013FE1222122A12FA1202120A1204
+504B:08000BFC0A04120413FC32003284524892FC1248124813FE1448144818881108
+504C:1108110817FE21082148604067FEA080210023FC250429042104210421FC2104
+504D:08000BF80A08120813F83208320853F8900017FE1040124012781240154018FE
+504E:08000BF80A48124813F83248324853F8900017FE124012441228129013081206
+504F:1080104017FC2404240467FC6400A40027FC26A42AA42BFC2AA42AA432A4220C
+5050:084008200BFC10001108309033FE5210922012C81210122412C8141014601980
+5051:20002FF8280848684B884888C8884BE84AA84AA84BE8488A48AA50EA57266002
+5052:08000BF80A0813F8120833F830005FFE920013FC149419241244148411281210
+5053:08000BFC0A04120413FC320033FC5240928813FC1224122015FC1420182013FE
+5054:08000BDE0A52125213DE300031FC500097FE1080110011FC1004100410281010
+5055:0A200A240BA8123012A23322325E508093FC1204120413FC1204120413FC1204
+5056:084008440BF41048105037FE3040508091F81308150811F81108110811F81108
+5057:0820082009241122122A303030C0570091FC110411FC110411FC110411FC1104
+5058:08000BF80A0812081208320833F85000900017BC14A414A414A414A417BC14A4
+5059:088008400BFC10001108309037FE5442984413FC124412441254124810401040
+505A:1210121012102FA0223E62446224AFA428A428A828A828902FA8282820442082
+505B:1008103C17C0204020406FFE6040A140265C24442444275C2444244427FC2404
+505C:1080104017FC200023F8620863F8A0002FFE280223F820402040204021402080
+505D:089008920F9C10901192368E300053FC920413FC120413FC1204120412141208
+505E:08900A900A9017FE1290329032F0520093FC104017FE10E0115012481C461040
+505F:084008800BF8120813F8320833F8500097FC1040104013F81040104017FC1000
+5060:08000BFE0850105013FE3252325253FE9000104017FE10881190106010D81304
+5061:090809080FFE110811F8310831F85108910817FE125012881304120013FC1000
+5062:13901E101210221222526FD46258A69027102AA82A2832282248224422842302
+5063:088008400FFC1000120831103FFE500093F81208120813F81208120813F81208
+5064:09080888089017FE1090309033FC52949294130C120413FC1204120413FC1204
+5065:1020102010FC2E2423FE622464FCA4202EFC222022202BFE2420262029FE3000
+5066:08000BFE08221120113C312032FE540091FC110411FC110411FC110411141108
+5067:1000108017FC211022086C8661F8A610216021A02E7E21842648203020C02F00
+5068:1120112415A82530252465A46E1CA040204027FC20E0215022482C4620402040
+5069:090009000BF8120814103BFC320453FC920413FC120413FC1000110812041402
+506A:100017FC100023F82208620863F8A00027FC2444244427FC2444244427FC2404
+506B:111011101210247C2910611062FEA6082A0822FE220822482228220822282210
+506C:1100110013FC24942B9461646254A4842128221020402124252A250A28F82000
+506D:08000FFE0840108013FC3294329452F49294129412F412941294129413FC1204
+506E:080009F80908110811F8300037FE510891F8110811F81108113E17C810081008
+506F:088008400FFE100013F832083208520893F810A4112813101510194811861100
+5070:0900093C0FD411141394311437D45124914C104017FE104010A0111012081C06
+5071:103C17E01420242027FE642065FCA504250425FC250425FC2904290431FC2104
+5072:08000BFC0A44124413FC3244324453FC9000104010241522150A190810F81000
+5073:104014441444244427FC60006FFEA040208027FC24A424A424A424A424A4240C
+5074:100217C21442245227D264526452A7D22452245227D2200222822242244A2804
+5075:1040107E1040204027FC64046404A7FC240427FC2404240427FC211022082404
+5076:100017FC1444244427FC64446444A7FC20402FFE284228522BF22912280A2804
+5077:084008A00910120815F6300033C45254925413D41254125413D41244125412C8
+5078:09C008A00910120815F6300033CA524A925413D41268125413D4124A124A12C0
+5079:0840084010FC10883550542094D8170614F814A814A814A814F810A810A810F8
+507A:091009100BD8125414523A90311052FE9C0013F81208120813F81208120813F8
+507B:0820092408A8102013FE30A831245202904017FE108811081190106011981604
+507C:08400840087E104013FC300431FC500493FC10401240127C1240154014FE1800
+507D:08400A40094017F81088309030FC5104910813FE1202142A1AAA128214141008
+507E:1040104017FC204022486FFE6208A00027FC240424442444244420B0230C2C02
+507F:08400A480950104017FE3402380451F09000100017FC10801110120817FC1204
+5080:1040108017FC2444244467FC6444A48427FC208021502164227C24422842303E
+5081:1140165C14442444275C64446444A7FC204027FC2208211020A0204021B02E0E
+5082:1004103E17E0243E242065FE6522A53825E2251E250029782A48324A248A2906
+5083:084008400FFC104013F8304037FE5080911013E0104817FC1044124815441080
+5084:104010401FFE244422A861106208AC0623F8220823F8220823F8220823F82208
+5085:085008480FFE104017FC344437FC544497FC144410081FFE1208110811281010
+5086:100017FE1420244025FC650465FCA50425FC2524242024A829242A2230A02040
+5087:090809080FFE1108100037FE310851F8910811F81108113E17C8100810081008
+5088:100017FC10A020A027FC64A464A4A7FC2040204027FC20E0215022482C462040
+5089:08000BFE0A0012FC120033FE32A8529092C81286120813FE1288144814081818
+508A:080009F80908110811F8300033FC520493FC120413FC120413FC109011081204
+508B:091009100FFC111013F8311037FC504093F8124813F8124817FE120812281210
+508C:08000BFC0A4013F8124033F83240524093FC1004155415541554140410281010
+508D:1080104017FC2208211067FE6402A884204027FC210021F82108220822282410
+508E:1040104017FC204023F8620863F8A20823F8220823F822082FFE211022082404
+508F:1040102017FE242025FC642467FEA42425FC242025FC25042504290429FC3104
+5090:1080104017FE200023F8620863F8A00027FC240425F4251425F4240424142408
+5091:1208120813BE24882AA8613E6208A448284827FC20E0215022482C4620402040
+5092:083C0FC00A4411281080311033E05040918813FC1044104017FC10A01110160E
+5093:1080104017FE2402240267FE6400A7DE24422652254A24C62B5A2842314A2084
+5094:0A080910080017FE10A037FC30A45FFE90A417FC10A011B012A81CA610A010A0
+5095:1080108017FE2522211063FC6620AA2023FC2220222023FC2220222023FE2200
+5096:0840084008A01190124837FE3A0853F8920813F8120013F81508150819F81108
+5097:088008400FFC1080110833F03060518497FE100217FC144417FC144417FC1404
+5098:01000280044008203118D116111029284544111029284544FFFE010001000100
+5099:088808880BFE1088108837FE308051FC932415FC112411FC112411241124110C
+509A:1410121012102FA0203E654464A4A8A431282528221022102528292830442082
+509B:084008200BFE120214943108326450909108120415FA11081108110811F81108
+509C:1004103E17C02244212461286200A3FC244020402FFE20402444244427FC2004
+509D:08000BF80A0813F8120833F83000500097BC108414A4129414A4108412941108
+509E:09080888089013FC104031F8304053FE9080110011FC12201420182013FE1000
+509F:092009100A081486191033F83008500097BC108414A4129414A4108412941108
+50A0:1204110411042FC4203E67846004A7A420142794248424842484278424942008
+50A1:1410120812082FBE2000608268A2A8A22492251225142114220421882E3E2400
+50A2:1080104017FC2404200063F86080A144266820B02128266820A4212226A02040
+50A3:084008400FFC104013F8308037FC511092481446124811501248144411401080
+50A4:1110111417D221102FFE62106210AFD4241429142FD4210821CA2F1A25262142
+50A5:08400A480950104017FE3402380453F89208120813F810A0112011241224141C
+50A6:080009F8090811E8112837FE340251F8910811F8110811F81108110811281110
+50A7:1080104017FE2402281463E06200A20023FC221022102FFE2000211022082404
+50A8:1020102018FA2424242861FE6020BC4024FC25442644247C25442644247C2044
+50A9:102810241740217E21C86948657EA5482248227E254825482948207E20402040
+50AA:1080111013F8221024A46FBE6042A0A023182C46219026642188263021C02E00
+50AB:100017FC144427FC244467FC6100A21027E020C823042FFE2042224825442882
+50AC:08200A220BFE1090108831FE3310551091FE1110111011FE1110111011FE1100
+50AD:102017FE142025FC242467FE6424A5FC242025FC252425FC252429FC2924312C
+50AE:08A008A00FFE10A017FC34A437FC54A497FC100013F8120813F8120813F81208
+50AF:084008800BFC124412F4331432A4524492A413FC104010241522150A190810F8
+50B0:10401444144427FC200067BC64A4A4A427BC24A424A427BC24A424A42AB43148
+50B1:11241124122424242954614A6292A6102A102250225C2250225022B0229E2300
+50B2:121012101FD022202FBE6244BFA42424242427A824A8249024A829A828443082
+50B3:10401FFE104027FC244467FC6444A7FC20422FFE20102FFE2210211021502020
+50B4:100017FC140024F82488648864F8A40025DC25542554255425DC240027FE2000
+50B5:08200BFE082011FC102033FE300051FC910411FC110411FC110411FC10881104
+50B6:10141012101027FE2410649064D2A49227F22494249425C82AAA289A31A62042
+50B7:090009FC0A0015F8110831F8310851F8900017FE110013FC14A4112412541088
+50B8:1040104017FC2040255462486554A04025542248255420A020A0211022082C06
+50B9:088008400BF8111010A037FE300053F8920813F8120813F81120112212221C1E
+50BA:090009100BDC125415543288310852F49402100013FC10401150124815441080
+50BB:084008800BFC12941264329433FC50909108128414FA11081290106011981606
+50BC:1110111017FE211021F0604063F8A24823F8204027FC20402FFE20A02110260C
+50BD:104017FC111020A02FFE600063F8A20823F8220823F820402FFE204020402040
+50BE:100011FE1010242024FC64846784A4FC248424FC2584268424FC204820842102
+50BF:100017FC1040227822406FFE6100A1FC220023FC200425542554280420282010
+50C0:12A812A817FC22A822AA64E66800A7FC2444204023F822482248224822582040
+50C1:1008103C17C02040224861506FFEA15022482C46208020442A422A1231F02000
+50C2:104013F812482FFE224863F86040A3F8224823F820802FFE211020E023182C04
+50C3:111011101FFE2110240067FC6804B7F4249427F4249427F42494249424342008
+50C4:10001FFE10A027FC24A464A467FCA00027FC20002FFE20402248244429422080
+50C5:111011101FFE211021F0604067FCA44427FC20402FFE204027FC20402FFE2000
+50C6:1020182015FE242021FC61246DFCA52425FC242025FE242024202A2031FE2000
+50C7:08000FBC088414A4129434A430505188962610C0131010641388103010C01700
+50C8:13F8120813F8220823F8600067FCA4A424A427FC200023F8211020E023182C06
+50C9:010002800440082037D8C00600003EF8228822883EF808200820145022884104
+50CA:100017FC10A027FC24A467FC6040AFFE2110220827F62A1023F02204220421FC
+50CB:084008A0091012481DF63020304053F8920813F8120813F8120813F811101208
+50CC:121012101F9022202FBE6AC46AA4AFA42AA42AA82FA822103FA8222822442282
+50CD:11C8170811082FE8211E67CA654AA7CA254A27CA210A27CA211221D22E2A2444
+50CE:100017BC14A427BC242064A4639CA000211027FC211021102FFE211022082404
+50CF:090009F00A1017FC1A24324433FC5080914416A81130166810A8112416A21040
+50D0:088808500BFE102011FC302033FE512490A817FE100011FC1104110411FC1104
+50D1:103813C0108027FE2110620865F6A91021F0200027FC240425F4251425F4240C
+50D2:1080104017FC2514220863F86088A7FE208823F8210023F82508290821F82108
+50D3:08400BF80A4813F8104037FE300053F8920813F8120813F8120813F811101208
+50D4:090808900FFE109013FC3294331C520493FC120413FC100817FE110810A81010
+50D5:10A014A412A820A027FC611060A0A7FC204023F8204027FC20A0211022082C06
+50D6:104017FC104023F8200063F86208A3F821102FFE200023F82208220823F82208
+50D7:08880AAA0ADC148811543222300053FE9242144413FC10441044108411141208
+50D8:220832482A484A90421E5FE4D0545054575455545554554857485054515450A2
+50D9:1110111017FC211021106FFE6040A7FC244427FC244427FC2000211022082404
+50DA:1040104017FC20A02514620867FCAA0A23F8220823F820402248244429442080
+50DB:1510151015102F90253E67226544A790251025102F902028252828A430442082
+50DC:102017A410A822922114620865F4A80223F82208220823F8220821102FFE2000
+50DD:17FC140417FC240025F8641067FEA4202460279C2484250829DE2F0831082318
+50DE:1004103E17C02244212863F86208A3FC220423FE240226AA2AAA2A0230142008
+50DF:124812481554275C22486554675CA2482FFE22202228222825142494242C2844
+50E0:08780FC00A48115017FC31503248540693F81248124813F81248124813F81208
+50E1:104010401FFE204027FC644467FCA44427FC20442FFE204220242522250A28F8
+50E2:103C17C010442224210867FE6402AA08220823BE24882AA8213E220824082808
+50E3:1110111017BC21102FFE611062A8A44423FA2208220823F82208220823F82208
+50E4:08000BDE0A52125213DE300031FC512491FC112411FC102013FE102010201020
+50E5:1040104017FC20402FFE611067BCA1102190263E20002FFE2120212222222C1E
+50E6:141412121F922010207E6F906890A8902F9022282B282AA83228224A2A4A2486
+50E7:09040888080013FE122232AA3272522293FE100011FC110411FC110411FC1104
+50E8:104017FC104021102FFE611063F8A20823F8220823F8220823F8211022082404
+50E9:179E1492179E2492279E640264F2A49224F2249224F224922492253224022406
+50EA:08000BFC0848103013FE305230945350902013FE1252128A1376125212721206
+50EB:08000FFE08901090139C32043204539C9090109017FE10401524150A190A10F8
+50EC:1140112013FE222026206BFC6220A22023FC2220222023FE2200252424922892
+50ED:100017BC1108252827BC631865AAA946200023F82208220823F82208220823F8
+50EE:08400BF8091010A017FC300033F8524893F8124813F8104013F8104017FE1000
+50EF:10401248115027FC215062486444A208220823BE24882AA8213E220824082808
+50F0:10101010FEFE1010FEFE929292923838545492921010111002800C603018C006
+50F1:084008200BFE1202120233FE3250524892FE139012FE129014FE149018FE1080
+50F2:100017FE10A027FC24A464A467FCA208220823BE24882AA8213E220824082808
+50F3:100017FC10A020A027FC64A464A4A7FC2248215027FC20E0215022482C462040
+50F4:100017BC14A427BC24A467BC6404A5F4251425F4251425F42514240424142408
+50F5:10001FFE100027FC244467FC6444AFFE200027FC244427FC244427FC20002FFE
+50F6:100017FC14A424A427BC60A067BCA4A424A427BC24A424A427BC24A220A2207E
+50F7:110817FE1108200024886FFE6488A4F8240027FC20402FFE215022482C462040
+50F8:1110111017BC211023B865546912A00023F8200027FC20402248244429422080
+50F9:10001FFE11202FFC29246FFC6000A7F8240827F8240827F8240827F822102408
+50FA:13F81208120823F8200067BC64A4A4A427BC20402FFE21602250244838462040
+50FB:10101008178824BE248064946788A47E2408278826BE2A882A882B8832882008
+50FC:10A010A017FC24A427FC64A467FCA00027FC200023F8220823F8211020A02FFE
+50FD:10C81708112A212C2FC861086388A55429142122204020242522250A290820F8
+50FE:083C0BC008441224110837FE344252A4928A147A108010F8110812901060179E
+50FF:1080104017FE25122BFC611067FCA11027FE2110224825F42842204027FC2000
+5100:111017FE104023FC204067FEA080272821242FFE212021A42F1A2112276E0000
+5101:1140112013FE222027FC6A2063FCA22023FE2200279E2492249224F224022406
+5102:08900BFC0A9413FC129433FC300053FC920012F8120013FE1520151415481986
+5103:10401FFE100027FC240465F46514A7FC200023F8220823F8220823F820002FFE
+5104:088008400BFC1108109037FE300053FC920413FC120413FC10401524150A18FA
+5105:10401248115027FE2402680463F8A20823F8200027FC244427FC244427FC2404
+5106:1288128817E82290241E67E46454A85427542554255427482548205422942122
+5107:08000BFC0A94129413FC300037FE500093FC120413FC10A2111413081D441182
+5108:104010A013182DF6200067FC6554A4E427FC200023F8220823F8220823F82208
+5109:1040104010A02110220865F66800A7BC24A424A427BC22102210252829443082
+510A:1110111017BC211023B865546912A00027FC2044224022782240254028FE3000
+510B:120013F8141027FE2D48762467FEA40025FC240025FC240025FC290429FC3104
+510C:121014101F9028902FBE68A46FD4A41422142FD424142788248828942A943122
+510D:082008880A5213261252328A322253FE90881144127A10881150102010D81706
+510E:111417D211102FFE21106FD06112A7D2255227D4255427C8210A2FDA21262142
+510F:108010DC128423D424486A946324AC402248215027FC20E0215022482C462040
+5110:1080104017FE24022BFC61486250A7FC220427FC2A0423FC220423FC21082204
+5111:08000BFE0A0213FE120233FE31085252939C1108125213DE100012A412521452
+5112:100017FC10402FFE284263586040A35820002FFE204027FC24A424A424A4240C
+5113:10401FFE104027FC200063F86208AFFE280227FC211023F8204027FC20402FFE
+5114:104017FC104023FC20006FFE6002A3F8204027FE200027FE200827FE24A82798
+5115:1080104017FC211020A46F586554A5522B582000220823F8220823F822082408
+5116:101017D0151027DE245067E86504A7C4200023F822A822A822A822A82FFE2000
+5117:1400157C160424A82390607C6414A7942A5022502FDC2250255024B0289E2100
+5118:08400BF8084817FE104833F8304057FE900012A4145213F812A812A81FFE1000
+5119:101014FE129222FE201061FE6000AEFE228222FE228022FE228222FE250028FE
+511A:088808880BFE108813FE325233FE500093FE124210F811081290106010C01700
+511B:1100120017FC2AA822A86FFE62A8A2A82FFE220823BE24882AA8213E22082C08
+511C:1080104017FC244422A862946474A00023F822A82FFE200027FC204021402080
+511D:1110155415B8291022A864446000A7FC2444204027FC20E0215022482C462040
+511E:100017FC124824442FFE644466ECA55426EC244426EC255426EC244424542408
+511F:0A4809500FFE140211F8310833FC520493FC120413FC120413FC110812041402
+5120:09240A480924100013FC32943264529493FC124813681248136A124A12461362
+5121:13F81248124823F82248624863F8A0002FBE2AAA2AAA2FBE2AAA2AAA2FBE28A2
+5122:1020103E102027FE242265F86422A5FE252425FC252425FC28402AA4328A247A
+5123:1040102017FE248825FC648867FEA42025FC252425FC252429FC288831042202
+5124:0BF80A080BF8120813F8311037FC51109FFE11101248155410E01150124810C0
+5125:08200BFE082011FC100033FE325253FE910411FC110411FC110411FC10881104
+5126:1080104017FC24A027FC64A467FCA400252425A8253025A4251C28002AA43452
+5127:12081FBE12082FBE2208651468A2A7FC240427FC240427FC240427FC21102208
+5128:08420B9C0A1013DE12943294342053FC920413FC120413FC120413FC11081204
+5129:10001F7C1944297C2F446944697CAF20297E29AA2F2A204A2A922922294A3104
+512A:17FC108013F8220823F862086FFEA8822548251428F4210023F8250820F02F0E
+512B:104017FE100021F8210861F86000A7FE240223F82180264421B8266821A62E60
+512C:1200123C1FA422242FBC62247FE4A03C2FA428A42FBC28902F9828A828AA29C6
+512D:1400123C1FA4202428BC65246FA4A23C22242FA4223C2B102A9832A82A2A2446
+512E:100017FE14442598248867DE6488A5DC26AA248824202520253C2920292037FE
+512F:1248115017FC20802FFE620867FCAA4223F8224023F8224023FC200425542008
+5130:11101FFE1110203C2FC064886250A7F8240827FC240427FE28022AAA32AA2004
+5131:142012201FBE2520223E7F82603EAFA028BE2FA028BE2FA028BE28A028A2299E
+5132:14101210127A2F1220146F7E6008AF10203C2F6429A4293C29242F24293C2024
+5133:09F00A100FFC120413FC322433B8522291FE121017FC124413FC10D0114A163E
+5134:104017FC100023B822A863B86110A7FC211027FC21102FFE212823102D482186
+5135:108011F812882070238E680069FCA92429AC292429FC282029FC202023FE2154
+5136:0A220BFE089011FE131035FE311051FE911011FE110013FE128A137612521276
+5137:17BE100017BC24A426B464A46040A7FE24A027FC24A427FC251229DC291231CE
+5138:100017FC14A424A427FC621062A8A4BE2F68223C24A82FBC20282AA82ABE2020
+5139:152817BE194827BE231865AA6946A3FC220423FC220423FC220423FC21082204
+513A:151815141F90253E272862686FBEAAA82FA8223E2FA822283FE8253E28A03060
+513B:1248115017FC240421F0611067FCA55424E427FC204027FC20402FFE22A42452
+513C:17BC14A417BC200027FE64006590A49E27D4256425D4255425D425682BC83054
+513D:17FC144417FC24442FFE6AAA6FBEAAAA2FBE222027C020842FFE204225482884
+513E:104017FC124823F820406FFE6AAAA3B8211027FC21102FFE212823102D482186
+513F:08400840084008400840084008400840084008400840104210422042403E8000
+5140:00000000FFFE08400840084008400840084008400840104410442044403C8000
+5141:0100010002000440082010103FF804480440044004400840084210422042C03E
+5142:0100010001007FFC01001100110021003FFE02800480048008841084207CC000
+5143:00003FF8000000000000FFFE04400440044004400840084210422042403E8000
+5144:00003FF8200820082008200820083FF80440044004400840084010422042C03E
+5145:02000100FFFE04000400082010103FF80448044004400440084408441044603C
+5146:04400440444424481450144004600C50144824444440084208421042203E4000
+5147:08202448228821082288244828283FF80440044004400440084408441044603C
+5148:0100110011001FF8210041000100FFFE044004400440084008421042203EC000
+5149:010021081108091009200100FFFE0440044004400440084208421042203EC000
+514A:04400440082011102108C206044008201FF0045004400440084408441044603C
+514B:01000100FFFE010001003FF82008200820083FF804400440084010422042C03E
+514C:04400440082010102008DFF61010101010101FF004400440044008441044603C
+514D:080008000FE0102020407FF8A108210821083FF822880480088010822082C07E
+514E:000801FC7F00010001003FF82108210821083FF8228804A0089010922082C07E
+514F:001000F81F80108010F81080108010801FFE11201120112022222222441E9800
+5150:000023F82208220823F82208220823F82208000004400440044008441044603C
+5151:10100820044000001FF01010101010101FF0145004400440084408441044603C
+5152:0000060038F8200820083CF8200820083FF8044004400440084408441044603C
+5153:00007EFE081008104890489048907EFE08100810142814282548264A448A8106
+5154:080008000FE0102020407FF8A108210821083FF8228804A0089010922082C07E
+5155:00003C7824482448244827C8200820083FF8244804400440084010422042C03E
+5156:02000100FFFE082011102208444408201FF0045004400840084010422042C03E
+5157:02000100FFFE0820101020085FF41010101010101FF00440044008441044603C
+5158:00207C200048008401FEFE02240024FC2484248424FC24842402440243FE8000
+5159:08100810FF10081008107F7E411041107F101410141014102412240243FE8000
+515A:01001110091009207FFE400280041FF0101010101FF00440044008423042C03E
+515B:0808081CFF70081008107F1041FE41107F101410141014102412240243FE8000
+515C:0100120067DC4444444447C44444444457C4601C04400440044008441044603C
+515D:08080828FF24084408427F80417C41247F24144414441494250A240243FE8000
+515E:083808E0FF20083808E07F20413C41E07F2414241424141C2402240243FE8000
+515F:0810285028503E7C4890081008107EFE1428142814281428254A264A44868100
+5160:0100121017D2F454145817D014523452D7CE100004400440044008441044603C
+5161:080008FEFF100820087C7F444144417C7F441444147C14442402240243FE8000
+5162:0820082008207EFE082008207EFC428442847EFC14501450255026924492810E
+5163:100011FEFD00117C11547D7C4554457C7D10297C29102AFE2C00480247FE8000
+5164:101011FE9528557C592811FEFD10297C2954297C29542A7C2A284C44480287FE
+5165:0400020001000100010002800280028004400440082008201010201040088006
+5166:040042004100410040804080414041404220422044104808500440007FFE0000
+5167:0400020002007FFC410441044284428444444824501440044004400440144008
+5168:0100010002800440082010102FE8C106010001001FF00100010001007FFC0000
+5169:0000FFFE0100010001007FFC4104514449244924555465944104410441144008
+516A:0600010002800C603018CFE600003E24222422483E4822903E48224822242624
+516B:0000004004400440044004400440042008200820081010101008200820044002
+516C:00800480048008400840102020104208820604000440082010203FF010100000
+516D:02000100008000800000FFFE0000000004400420081008081008200440040000
+516E:044004400820082010102008DFF6040008000FE0002000200020002001400080
+516F:201010100820084000007FF80208020802080208022802100200020002000200
+5170:101008100420044000007FFC0000000000003FF80000000000000000FFFE0000
+5171:04200420042004203FFC042004200420042004207FFE00000420081010082004
+5172:00007FFC010001003FF801000100FFFE0000044004400820082010102008C006
+5173:10100810082000003FF8010001000100FFFE010002800280044008203018C006
+5174:0408020821081110081008200040FFFE00000440042008100808100820044004
+5175:002000F01F00100010001FF81080108010801080FFFE00000840102020104008
+5176:082008207FFC082008200FE0082008200FE008200820FFFE0000082010102008
+5177:00001FF0101010101FF010101FF010101FF010101010FFFE0440082010102008
+5178:0440044004403FF82448244824483FF8244824482448FFFE0440082010102008
+5179:082004200440FFFE1020102020402448448878F008101020142822447EFC0204
+517A:0440082010102FE8C4260420082010A0604000003E442258226022423E42223E
+517B:0820044002887FFC01003FF80200FFFE04400830344EC4440440044008401040
+517C:102008407FFC048004803FF00490FFFE04903FF00CC014A02498C48604800480
+517D:082004403FF821083FF821083FF80000FFFE00001FF01010101010101FF01010
+517E:082004403FF821083FF821083FF8000008207FFC08200820FFFE082010102008
+517F:08100420FFFE08203EF808283EAA0866389200001FF000007FFC040008101FF8
+5180:04447C7804421C3EE4003FF821083FF821083FF804403FF80440FFFE10102008
+5181:440025FE29027D0255FE55247D24557E55247D2411FE1152FD54124812641442
+5182:00007FFC40044004400440044004400440044004400440044004400440144008
+5183:00007FFC4004400440045FF44004400440045FF4400440044004400440144008
+5184:00003FF8200820082008FFFE200820082008FFFE200820082008200820282010
+5185:0100010001007FFC410441044104428442444424481450144004400440144008
+5186:00007FFC410441044104410441047FFC40044004400440044004400440144008
+5187:02000200FFFE040004000FF00810181028104810881008100810081008500820
+5188:00007FFC40044004400448244444428441044284444448244004400440144008
+5189:0100010001003FF8210821083FF8210821082108FFFE20082008200820282010
+518A:00003FF824482448244824482448FFFE24482448244824482448240820282010
+518B:00007FFC40044004400447C4444444444444444447C444444004400440144008
+518C:00001E7812481248124812481248FFFE12481248124812481248128826A84110
+518D:0000FFFE010001003FF8210821083FF821082108FFFE20082008200820282010
+518E:00001FF0101010101F90109010907FFC40044004400440044004400440144008
+518F:00007FFC400444444824501467CC444444444444444447C44444400440144008
+5190:00003FF820082FE820082FE800001FF010101FF010101FF01010101010501020
+5191:010001003FF821083FF821083FF800001FF0101017D0101017D0101010501020
+5192:00003FF820082FE820082FE8200800001FF010101FF010101FF010101FF01010
+5193:082008207FFC08203FF80820FFFE01003FF821083FF82108FFFE200820282010
+5194:00003FF820082FE820082FE800007DFC4420442047FE44207C20442000A00040
+5195:7FFC40045FF440045FF404000FE010203FF8510811081FF8028004821882607E
+5196:00007FFE40028004000000000000000000000000000000000000000000000000
+5197:000000007FFE4002800400000FC00840084008400840104210422042403E8000
+5198:0100010001003FFC2104410801000280028002800480048008841084207C4000
+5199:00007FFE4002900410001FF8100020003FF800080008FFC80008000800500020
+519A:000000007FFE400281040100010021082108210821082108210821083FF80008
+519B:00007FFE4002820402003FF80400090011003FF801000100FFFE010001000100
+519C:0100010001007FFC4204820805000508089018A02840482088100A080C060800
+519D:00007FFE400280041FF0101010101FF0101010101FF0101010101010FFFE0000
+519E:00007FFE4002810411100920054001007FFC0540092011102108C10601000100
+519F:00007FFE410282041FF010101FF010101FF0000010F01F00100410040FFC0000
+51A0:00007FFE400280043E08000800FE7E08144814281408142A2412240243FE8000
+51A1:00007FFE40029FF400007FFC02000D08719002A00CC071A006981886E2800100
+51A2:00007FFE400280047FFC0200060819106AA004C01BA062980C863080C2800100
+51A3:00007FFE400280047F0022FC22443E44224422283E2822102790FA2842440282
+51A4:00007FFE400288040FE0102020405FF8110811081FF8028004A008921082607E
+51A5:00007FFE400280041FF010101FF010101FF012100100FFFE0000082010102008
+51A6:000000007FFE400280243E38002000207EF814081450142014542484240443FC
+51A7:00007FFE400280040820082008207EFC08201C301A702A6848A4892208200820
+51A8:00007FFE400280043FF800001FF010101FF000003FF821083FF821083FF82008
+51A9:00007FFE400282041CF010101EF010101FF008001FFC20044924249424944008
+51AA:FFFE84423FF804401FF010101FF010101FF002007FFC09203FF8D11611300100
+51AB:000040002000200000000800080010001000E000200020002000200020000000
+51AC:040004000FF010102820444003800C603018C006070000C000200E0001800040
+51AD:010001000100FFFE02800440082010102608C186004000000C00030000C00020
+51AE:0000400027FC204000400840084010401040E0402040204020402FFE20000000
+51AF:000047F02010201002100A100A1013FC1004E004200427F42004200420280010
+51B0:004040402040204400680770116011502150E248224824442842204021400080
+51B1:000047FE20802080008008F80908110811082208E3F820102010201027FE0000
+51B2:004040402040204007FC0444144414442444E44427FC24442040204020400040
+51B3:00804080208027F800880088108810882FFEE080214021402220241028081006
+51B4:000043FC20102110011009100A1013FE1030E050209021102210241020500020
+51B5:000047F8240824080408040817F811202120E1202120222022222422281E1000
+51B6:0040404020802110020807FC1004100023F8E208220822082208220823F80208
+51B7:0040404020A020A0011002481426102023F8E0082010211020A0204020200020
+51B8:0040424421482150004007FC104010402040EFFE204020402040204020400040
+51B9:009040882088208007FE0080110011FC2144E244224824502420285020880306
+51BA:000043FC2204220402040BFC0A20122013FEE220222022102212228A23060202
+51BB:00404040204027FE008009200920122013FCE020212821242222242220A00040
+51BC:00404240224023FC04400040104017FE2120E1202120212022222222241E0800
+51BD:000440042FC42224022403A412A414A426A4E5A4292421242204220424140808
+51BE:0040404020A021100208140613F81000200023F8E20822082208220823F80208
+51BF:0040404023F8204807FE004813F810402040E7FC204020402FFE204020400040
+51C0:0100410023F02410002017FC104410442FFE2044E04427FC2044204021400080
+51C1:004040402FFE2040004007FC1444144427FCE04020E0215022482C4620400040
+51C2:0100410021F02210022007FC1A4412442244E3FC22A420A0212022222422081E
+51C3:0040404020A02110020805F61040104027FCE040225022482444284421400080
+51C4:0040404027FC204003F8004817FE104823F8E08027FE21082390206021980604
+51C5:000047FC2444244407FC0444144415F42514E514251425F42514240427FC0404
+51C6:01404120212023FE022016201BFC1220222023FCE2202220222023FE22000200
+51C7:02084228222822280FA40244125416922710EAA02A203228224422FC22440200
+51C8:003C47C02244212800000BF80848104817FEE048204823F82048204021400080
+51C9:008040402FFE2000000003F81208120823F8E040225022482444284421400080
+51CA:0040404027FC204003F8104017FE100023F82208E3F8220823F8220822280210
+51CB:000047FC2444244405F40444144417FC2404E5F42514251425F4240424140808
+51CC:0040404023F82040004007FE111012882484E1F0231024A0204020A023100C0C
+51CD:0040404027FC204003F80A480BF8124813F8E04020E0215022482C4620400040
+51CE:0040404020A021100208040611F010402040E3F820402248214821502FFE0000
+51CF:00144012201027FE0410041015D014122412E5D42554254825DA242A28461082
+51D0:000047FC20A020A007FC04A414A414A427FCE040204027FC204020402FFE0000
+51D1:0040404027FC204003F8008017FC11102208E5F6204023F8204020A021100608
+51D2:004042482248224803F8000017FC100023F8E208220823F8211020A027FE0000
+51D3:000047FC20A020A007FC04A414A417FC2040E04027FC20E0215022482C460040
+51D4:0040404020A02190024817FE1A0813F8220823F8E20023F82508250829F80108
+51D5:000047FC2404200003F80A080BF8120813F8E080204027FC2000211022080404
+51D6:4140212003FE0A2017FCEA2023FC222023FE02000100FFFE0100010001000100
+51D7:0040444427FC2120011003FE122016202BFCE220222023FC2220222023FE0200
+51D8:04804482249C2FD004900790149E17942494E4942FD42014251428A430240044
+51D9:000047FC24A427FC004003F8104017FC2110E0A023F820402FFE204020400040
+51DA:0110411027BC211003B805541912100023F8E00027FC20402248244429420080
+51DB:00404FFE200027FC040405F4151415F42404E7FC200023F820002FFE224804C4
+51DC:00404FFE200027FC040405F4151415F42404E7FC200823F020402FFE21500E4E
+51DD:0400457C260424A80390107C141417942A502250EFDC2250255024B0289E0100
+51DE:08008BDE4A924A920BD22A5E2A502BD04A92CA924BCE50004000452444920892
+51DF:00404FFE204027FC000007FC14A417FC2208E3F8220823F8220823F821100208
+51E0:00000FE0082008200820082008200820082008201020102220222022401E8000
+51E1:00000FE00820082008200A20092008A008A008201020102220222022401E8000
+51E2:0200020004001FE01020102010201020102010201020102220222022401E8000
+51E3:02000200020002001FE0102010201020102010201020102220222022401E8000
+51E4:00003FF8200820082FC8204828482488228821082288244A284A400A40068002
+51E5:00003FFC200420043FFC2000200023E02220222022202220242244224822901E
+51E6:100010F010901E901290229022905290949414940894090C1400230040FE8000
+51E7:00003FF820082108210821082FE829282928292829A8294A210A410A41068002
+51E8:00003FF8200820082FC8200820083FE82208248828483FEA282A400A40068002
+51E9:00003FF820082108210821082FE82108238823482528252A290A510A41068002
+51EA:00003FF820082088208820882088248824E824882488248A248A5FFA40068002
+51EB:020004003FE02020242022A020403FF800081F8810A8109010822082407E8000
+51EC:00003FF8200820082FE82008200827C82448244827C8244A244A47CA44468002
+51ED:08380BC01040304057FE90401040104013F800000FE00820082010222022C01E
+51EE:00003FF8200820082FE82108220827C82448244827C8244A244A47CA44468002
+51EF:100092F092909290FE900090FE90029002907E904090409246925912610E0200
+51F0:00003FF8220827C8244827C8244827C820082FE8210827CA210A4FEA40068002
+51F1:0800490049787F480048FF4800487F48414841487F484248244A0F4AF08A4106
+51F2:00003FF8244822883FF822882FE822A83FF822A82FE8228A26CA4AAA52968282
+51F3:00907EA004442BA810102FE8C8260FE004407FFC00000FE0082008221022601E
+51F4:000043FC22400BF80A4013F82240E3FC2004255420080FE0082008221022601E
+51F5:000000000000000040044004400440044004400440044004400440047FFC0004
+51F6:000000101010082044444284410442844444482450146014400440047FFC0004
+51F7:01000100010001004FE4410441044104410441045FF44004400440047FFC0004
+51F8:00000FE008200820082008200820783C4004400440044004400440047FFC4004
+51F9:00007C7C444444444444444444444444444447C440044004400440047FFC4004
+51FA:0100010021082108210821083FF801080100010041044104410441047FFC0004
+51FB:0100010001003FF8010001000100FFFE0100010021082108210821083FF80008
+51FC:01000100010001105D244544458449444924511461144504420440047FFC0004
+51FD:00003FF00020004051944924454441044544492451144504420440047FFC0004
+51FE:00003FF00020004041845D745594555455245D5441944504420440047FFC0004
+51FF:0440244814500440FFFE0000044022882FE8210821082FE8210821083FF80008
+5200:000000003FF80208020802080208020802080408040808080808100820504020
+5201:00003FF800080008000800480088010802080408080810086008000800500020
+5202:0004000400040044004400440044004400440044004400040004000400140008
+5203:00003FF802080208020822082208220842080208040804080808080810506020
+5204:00007FF004100410241014100C100410061005900870081E1010101020A0C040
+5205:00007FE00420042004200420242824244422842208200820102010202140C080
+5206:00400440042008201010200840049FE204200420042008200820102021404080
+5207:1000100011FC104410441E44F044104410441244144418841084010402280410
+5208:000401040104212411240A240A24042404240A240A2411242104400480140008
+5209:1004100420043FA4402480243F2402240424082410242024408440843F940008
+520A:00047F0408040824082408240824FFA408240824082408240804080408140808
+520B:0004070478040824082408240824FFA408240824102410242004200440148008
+520C:0404040404040424FFA404240424042444242424242404240404040414140808
+520D:040004000FF0101020204040BFF80008000800081FF80008000800083FF80008
+520E:2004200420043FA454A494A414A424A424A448A488A410A42084408485140208
+520F:200420043F84402480243F24002400247F240124012401240144014400D40048
+5210:00043F04210421242924252425242124FFE42124212421242104410445148208
+5211:00047F8412041224122412241224FFE412241224122412242204220442148208
+5212:100414041204102413A4FC2410241124112412240C2408A414842284C1940088
+5213:00043F04000400240024FFA41224122412241224122422A42304420480140008
+5214:0804080408047F240924092409240924FFE40824082414241204210441148008
+5215:00003FF80208020804080850302000007EFC122412241224224422444A948508
+5216:00043F042104212421243F242124212421243F24212421242104410445148208
+5217:00047F84080408241F2411242124212452248A24042404240804100420144008
+5218:100408040804FFA4022442242224142414240824082414242404420482140008
+5219:00047F0441044124492449244924492449244924492414241204210440948088
+521A:00047F0441044124652455245524492449245524552465244104410445144208
+521B:0804080414041224212440A4BE242224222422242A242424208420841F940008
+521C:1202120212027F82129212927F92521252127FD21252125223422282420A8204
+521D:2000100001FCFC44084410441044344458449444144410841084110412281410
+521E:00043F042104212421243F24212421243F242124212421242784F80440140008
+521F:00047F041104112421242524422480243F2421242124212421043F0421140008
+5220:00027BC24A424A4A4A4A4A4A4A4AFFEA4A4A4A4A4A4A4A4A4A425A42854A0884
+5221:00027F824082408240927F92441244127FD24412441242124242514260CA4044
+5222:0804080414041224212448A4842404247F240124222414240804040404140008
+5223:0804080408041024122421247FA420A400243F2421242124210421043F142108
+5224:040444842484252404247FA4042404240424FFE4042408240804100420144008
+5225:00047F044104412441247F240024102410241F2411241124210421044A148408
+5226:0804080408047F24082408240824FFA408241024102422244104FF8440940008
+5227:0800080008FC7F24082408240824FFA41024102424244224FF44414400940108
+5228:100410043F0421244124BD24252425243D24212425242224208420841F940008
+5229:010407847C04042404240424FFA40C241624152424A424244404840404140408
+522A:00047F0455045524552455245524FFA455245524552455245504510445144208
+522B:00047F044104412441247F2410241024FF24112411241124210421044A148408
+522C:14041204100417247824102417A4F824112412240C2408A414842284C1940088
+522D:00047F04020404240C2412242124C0A400247F240824082408040F04F0144008
+522E:02040F04780408240824FFA40824082408247F2441244124410441047F144108
+522F:00047F84000400243F24212421243F24212421243F24212400040784F8144008
+5230:0004FF840804102422244124FFA408A4082408247F24082408040F84F8144008
+5231:2400240025F824487E482448254C254AFE4A2448244824482448448844A88510
+5232:080408047F04082408240824FFA40024082408247F24082408040F04F0144008
+5233:08040804FF84142422244124BEA40024FFA4102420247F24010401040A140408
+5234:00047F041104122423A420A44AA489240824FFA418242C242A04490488940808
+5235:0004FF84220422243E24222422243E242224222427A4FA244204020402140208
+5236:0404240424043FA444240424FFE4042404243FA424A424A42684250404140408
+5237:00023FC2204220423FD22212221222123FD252525252525293421282020A0204
+5238:0100111009203FF8020002007FFC082010102FE8C42604200820082011402080
+5239:01046204140408241424222449240824FFA408242A2429244884888428141008
+523A:08040804FF84082408247F24492449244D244A241C242A244904888408140808
+523B:100408040004FFA40824112421247E240424092412242424CC0412042114C088
+523C:1000100010FC7E24102410A410A4FEA410A41124202428244444FE4442940108
+523D:08040804140422244124BEA400240024FFA41024102422244104FF0441140008
+523E:080408040804FFA40824492429242A24FFA40824082414241204210441148008
+523F:08044904490449247F24102410243F244124A12412241424080410042014C008
+5240:08044904490449247F2400247F24012401243F242024202423042C0430140008
+5241:00043E0422042224222449A488240824FFA408241C242A244904888408140808
+5242:10040804FF840224642418242624C12422A42224222422242204420442148208
+5243:420422042404FF2409240924FF2488248824FFA418A428A44A84890408140808
+5244:00047F84000424A449249224492424A400247FA40824082408040B84FC140008
+5245:00047F84000400243F242124212421243F240024212411241204078478142008
+5246:080404043F04212421243F24212421243F242024242422242504290430142008
+5247:00047F04410441247F24412441247F24412441247F2400242204210440948088
+5248:00043F04210421243F2400247FA440A440A47FA440A440A47F84408442944108
+5249:080408042A042A242A245D2488A4082408247F240824082408040F84F8144008
+524A:0804490429042A2408247F24412441247F24412441247F244104410445144208
+524B:08080808FF48084808487F48414841487F481448140814282412240243FE8000
+524C:08040804FF84082408247F24492449247F2408241C242A244904880408140808
+524D:101008100820FFFE00003E08224822483E48224822483E48220822082A282410
+524E:02046404180416242124CA2409240824FFA418241C242A242904488488940808
+524F:4200240000FC7E24242424A424A424A4FEA42524242424242444444444948508
+5250:00047F044104412441247F2408240824FFA488A494A4A2A4C284808482948108
+5251:0804080414041224212440A4BE24002411240924492422242204078478142008
+5252:1204120412047F2412241224FFA400243F24212421243F24210421043F142108
+5253:0C80708011FCFD2432243844548491041228101000007FF80408080810506020
+5254:00043F04210421243F24212421243F2410243FA44AA492A42484488412942108
+5255:120212021202F3C21212121212127392121212121212F3D212021202120A1204
+5256:100408047F84002421241224FFE4002400243F242124212421043F0421140008
+5257:240422042F04F024142409243524CB2424242F24F0241224140409043514C308
+5258:22042204FF84222422243E24222422243E2422242224FFA40004220441148088
+5259:4200240001F87E4824482448254C254AFE4A2448244824482448448844A88510
+525A:04020402FFC204023F9224923F9204123F920492FFD204923F820402140A0804
+525B:00027FC2404251424A527FD2445244525552555255525F5240424042414A4084
+525C:080404047F8440A420243BA42AA42AA42AA45AA44BA48A241204128423144208
+525D:20043E0442047C240424FFA40824092449242A241C242A24C904090428141008
+525E:080408047F84142422244124FFE4012479244924492449247904010405140208
+525F:00047B8408842AA411242AA444A4882400247BA408A42AA411042A8444948808
+5260:10040804FF84002400247F244124412441247F2408242A244904888428141008
+5261:0804090449044A2488241424222449248824492449248A241404220441148088
+5262:0004FF84080410242824C4A40D2456242524D5240CA414A42404C40414140808
+5263:08040804140422244124BEA4082408247F24492449247F240804140422144108
+5264:10040804FF840224642418242624C12422A43E24222422243E04420442148208
+5265:00047E0402043E240224FFA40824092449242A241C242A24C904090428141008
+5266:08040804FF8414242224492488A47F2449247F2449247F2408040A040C140808
+5267:00043F84208420A43FA4242424243FA4242424243FA450A4508490841F941088
+5268:08040804FF8408247F240824FFA40824FFA4102420247F24A10421043F142108
+5269:070278020802FF822A122A92EB122A926A92A9921C122A1249028882080A0804
+526A:0820FFFE00003E0822483E4822483E482208261800007FF80408080810506020
+526B:040202023FE2248224923FF22492279220122FD22052249222824102468A9844
+526C:08044904490449247F240024FFA4082410247F24552455245504550455144308
+526D:00043F84208420A43FA420243FA4242429242FA422242FA4220443845E148808
+526E:00047F0441044124792449244924FFA480A4BEA4A2A4A2A4BE84808482948108
+526F:00027FC200023F82209220923F9200127FD2445244527FD2444244427FCA4044
+5270:03823C0204027FC215121512FFD2151215127FD20E12151224824442840A0404
+5271:08000800147E22124112BED2085208527F52499249127F1208221422224A4184
+5272:10040804FF8480A409247F2408247F240824FFA408247F24410441047F144108
+5273:22042204FF8422240824142422244124BEA4002400247F24410441047F144108
+5274:0804490449047F240024FF2400247F24412441247F24422424040F04F0144008
+5275:08040C041204292444A4BF2421243F2421243F2420243F24510451049F141108
+5276:20043F0441047E240224FFA4102428A4CD2416242524CD2414842484D4140808
+5277:080404043F8411240A243FA422242A242FA4322422242FA42204420443949C08
+5278:0804FF8408047F2449247F2449247F2408A4FFA40224FFA4420422040A140408
+5279:0004770411045524332455240C243324C4A4182462240CA4710406041814E008
+527A:082008207E7E08C4FF281C102A2848C600003FFE20002FF82208420844289810
+527B:0202222222223FEA000A3DEA252A252A3DEA252A252A3DEA2522252255AA8A44
+527C:100422047F04422494A4F7A408243624C92430A4C424192462040C043014C008
+527D:0002FFE20A027FC24A524A527FD200127FD20012FFF2041224824442942A0804
+527E:00027FC240024F82489248924F9240125DD25552555255525DC240027FEA0004
+527F:49049204490400247F2449247F2449247F240824FFA41C242A04490488140808
+5280:00047F0412040C24FFA414A42524D4240824FFA494A4A2A4DD8494849C948188
+5281:120211023FC222026212BFD2221222123FD2221222123FD2200254824A4A8A44
+5282:00027FF24002514A4A4A5F7A449A442A550A554A5F4A444A44A248A2492A9204
+5283:08047F040904FFA409247F240824FFA400247F2449247F2449047F040014FF88
+5284:420442047BC44524A8A4142422244124BEA4002400247F24410441047F144108
+5285:00047F04550455247F2420247FA490A47CA454A454A47CA41284FE8402940108
+5286:02023FF22882250A3FEA250A2FCA254A3FEA254A2FCA250A2D825542652A8504
+5287:08040F0408047FA448A47E244924472440247FA4482455244A04B7040A943608
+5288:00407C2045FC44887C5043FE7C20A5FC24203C2000007FF80408080810506020
+5289:080277C252424A42555264920A1211123F92C4523F120492250217C27C0A2004
+528A:04020B0230C2DF2200127FD255524E527FD200123F9220923F8220823F8A2084
+528B:00047F0441047F240024F7A494A4F7A408240824FFA41C242A04490488940808
+528C:020213C212027FEA010A014A3FEA210A3F0A254A254A2D4A368244A2896A3224
+528D:08040804140422244124BEA40024002477245524552477242204220455148888
+528E:0800080014FC22244124BE240024002477245524552477242244224455948908
+528F:080449042A04FFA480A43E24222422243E2400247F2449247F0449047F144108
+5290:11027FC2150212023FD26412BF9224123F9224123FD220127F8211020E0A7184
+5291:080204027FC211020A52F59255525532B592001220923F9220823F82208A4084
+5292:08000800147E22124112BE5200520052775255925512771222222222554A8884
+5293:08023F8220823F8220923F9200127FD244527FD244527FD20002FFE2110A2104
+5294:08000800147C22244124BE2400A4006477245534552C7726222422245544888C
+5295:0844738442047BE452A452A484247FA440A47FA440A47FA440847F8421144088
+5296:3E024202FF8240827F924492771244523FD24212FF9248927F821A02294AC7C4
+5297:52827BE294827BEA318A5AAA946A3FCA204A3FCA204A3FCA20423FC2108A2044
+5298:02023FF224823FEA248A2ECA35AA248A250A3DEA250A3DCA25025DE2450A8504
+5299:1F0221023E0202027FD2189265121A9266521A122492FBF2AAA2FBE228AAFBE4
+529A:7FC240427FC252424A9252525FD255525FD264525F5255525F424442BF4A0084
+529B:02000200020002007FF802080208020802080408040808080808108820504020
+529C:1020102010201020FF201120112011201120112021202122212241224A1E8400
+529D:004000400040FC4005FC04444844284410441084288424844504810402280410
+529E:02000200020002007FF002100210121812142412441208100810101020A04040
+529F:004000400040FE4011FC1044104410441044108410841E84F104410402280410
+52A0:100010001000107CFE4412441244124412441244124412442244227C4A448400
+52A1:040004000FF0182024C003000CC03230C20E1FF0021004100410081010A02040
+52A2:00200020FF20202020FC20243E24222422242224222422244244424494A80910
+52A3:0100111011082124414401800E00F10001003FF8020802080408080810506020
+52A4:022007203820202020FC20243F24242424242424242424442444448445288210
+52A5:102008200820FF2000FC00243C24242424242424242425444644448481280210
+52A6:020002003FF00410081010A06040102010207EFC12241224224422444A948508
+52A7:04200E207820082008FC7E24082408240824FF24082408440844088429281210
+52A8:004000407C40004001FC0044FE4420442044208448844484FD04450402280410
+52A9:00207C204420442044FC7C24442444247C244424442444444E44F08401280210
+52AA:10001000FEFC22844488285010202858C586020002007FF80408080810506020
+52AB:0820082008207E2008FC08240824FF241024102420244444FE44428401280210
+52AC:2020202020207E2042FC82247A244A244A244A247A244A440244028415280A10
+52AD:00207E201220122022FC2A24442480243E2422242224222422443E4422A80110
+52AE:08200820482048207EFC482488240824FF240824082414442244428481280210
+52AF:00200020FF20102010FC10243E2422246224A224222422443E44228401280210
+52B0:1020102020207E2042FC4224422442247E2442244224422442447E4442A80110
+52B1:00107FD0401040105F7E481248124F12491249124912491249125122952A2244
+52B2:00207E200420082018FC24244224812400247E240824084408440E84F1284210
+52B3:08200820FFFE082000007FFE420282043FF00210021004100410081010A02040
+52B4:22081108111000207FFE4002820402007FF80208020804080408080810506020
+52B5:0100111009203FF8020002007FFC082012102208DFF604100410081010A02040
+52B6:04200E207020402040FC7F24402440245E2452245224522452449E4492A80110
+52B7:2220122014207F2008FC08243E24082408247F24082408441044108421284210
+52B8:082008207F20082008FC0824FFA40024082408247F24082408440F44F0A84110
+52B9:102008200020FF2000FC24244224812424241424082414442244428481280210
+52BA:101010102410427EFF120912481248127F1288220822FFA20842084208940908
+52BB:00107F904010407E7F92441244125F12441244227FA2402240427FC200940108
+52BC:082008200820FF2008FC08247E24002400247E244224422442447E4442A80110
+52BD:7F84082410243F2451240A24040408043014C20802007FF80408080810506020
+52BE:102008200820FF2008FC102422247C24092412242424C82414442244C0A80110
+52BF:084008407DF808480C4819C8684A08AA2886130202007FF80408080810506020
+52C0:0820082008207F2008FC08247F24412441247F24142414242544264444A88110
+52C1:00207F20002025204AFC9224492424A400247F240824082408440F44F8A80110
+52C2:0820282028203E2048FC0824FF24002400243E242224222422443E4422A80110
+52C3:082008207F20082008FC7F24412482243C24042408240F447844088429281210
+52C4:201020103F904010BF7E211229122512FFD22112491245127F9201220A2A0444
+52C5:08200820FFA0082008FC7F24492449247F2408241C242A444944888409280A10
+52C6:102008207E20422042FC7E24422442247E244024482444444A44528461284210
+52C7:3FF0066001803FF821083FF821083FF82108220802007FF80408080810506020
+52C8:00107E1002103410087E7F12491249127F12491249127F1249124922492A4344
+52C9:202020203E20442088FC7F244924492449247F4414441494250A240243FE8000
+52CA:08200820FF20087C08247F24412441247F241444145414882502240243FE8000
+52CB:00203E20222022203EFC00247F2441244924492449244944144412842128C210
+52CC:082049202A207F2008FC1024FFA422244124BEA422242A24244420442CA83110
+52CD:10100810FF900010007E7F124112411241127F1208122A12491288A2282A1044
+52CE:082008207E20082008FCFF242224412488A408247E24082408440F44F8A84110
+52CF:102008207F20002022FC1424FFA4002400243E242224222422443E4422A80110
+52D0:00203E20042008207EFC08240824282410247F245524554455445784FD280210
+52D1:082008200820FF2008FC2A242A242A245D2488241C242A444944888409280A10
+52D2:22202220FFA022203EFC08247F24492449247F240824FFC40844088409280A10
+52D3:441044907510461054FE64924B9210127F12411241127F12411241227F2A4144
+52D4:0020FFA0082010207F7C552455245D24552455245D245524554455447F944108
+52D5:0F2078200820FFA0087C7F2449247F2449247F2408247F2408440FC4F8944108
+52D6:0020FF208120BD2081FCBD24812400247E2442247E2442247E4442447EA84310
+52D7:1FF010101FF010101FF000003E2022203EFC22243E2422242F44F04440940108
+52D8:22202220FF2022203EFC22243E2422242224FF2440245444624440847F280210
+52D9:0040FC4004FC688811500820FED813063440304053FC50449084108451142208
+52DA:52105210FF9052105E7E40127F1200127F1241124912491249121422222AC144
+52DB:00203E20222022203EFC00247F2441247F2441247F2441247F44144422A84110
+52DC:282044209220202048FCFC2404240024EE242224AA246624AA442244AAA84510
+52DD:0020792448A8482049FC78404BFE488849447A424DF848484888488849289A10
+52DE:08202AA42CA84920145022887FFE410281043FF8020802080408080810506020
+52DF:04407FFC04401FF010101FF010101FF00400FFFE10102208DFF6041008503020
+52E0:0020772011205520337C55240C243324C4A4182462240CA4714406441894E108
+52E1:0020FFA014207F2055FC55247F2400247F240024FFA408242A444944A8A81110
+52E2:10407C4011F8FE4844C892487CAA10AA1D06E20202007FF80408080810506020
+52E3:08107F1008107F10087EFF9200127F1241127F1241127F1241127F22222A4144
+52E4:22202220FFA022203EFC08247F2449247F2408247F2408447F4408840F28F210
+52E5:7CF8048804F87C2041FC7D2405FC04282BFC120402007FF80408080810506020
+52E6:49209220492000207F7C49247F2449247F240824FFA41C242A44494488940908
+52E7:202020203F20482088FC7F24142422247F24A4243F2424243F4424443FA82110
+52E8:20203E204220FF2049FC49247F2410242824D5242624CD2415442444D4A80910
+52E9:5220FFA052205E2040FC7F2400247E2442247E2442247E4442447E8425284210
+52EA:061078101010FF90227E5D1294921C1200127F1241125D1255125D22412A4344
+52EB:0F10F81049102A7EFF922A12491280927F12492249227F22494249427F944108
+52EC:081049102A107F10107EFF9222125112A2923C1209127F120812492288AA1844
+52ED:101008107F102210FF7E00127F1249127F1249127F1208127F1208220F2AF044
+52EE:08100F1008107F9048FE7E124912471240127F92481255124A12B7220AAA3644
+52EF:0820FF200020FF20817CBD24A524FF2400247E2442247E2442447E440094FF08
+52F0:100010FE7E92129222FE2A92449280FE4410FF0855285520556455AA5928B318
+52F1:22102210FF9022107F7E49127F1249127F120812FF9288928A92BEA282AA81C4
+52F2:7F200820FF2008FC7F2449247F2449247F2408447F440894FF08000024484224
+52F3:071078100810FF90087E7F126B125D127F1208127F120812FF920022552A8AC4
+52F4:08100F9008107F9048FE7E1248925F9255125F1255125F1248125522B2AA5E44
+52F5:00107F904A107F904A7E5F1255125F1255125F1244127F926492AEA2A2AA2144
+52F6:22104F90821E14A42FD46014AF9428882F88289429A202007FFC040418286010
+52F7:0810FF9000107710557E771222127F1222127F122212FF9228926522B22A2144
+52F8:2210FF902210F79094FEF792281224127F924812FF1248127F1248227FAA4044
+52F9:100010003FFC2004400480040004000400040004000400040004000400280010
+52FA:0800080010001FF8200840088008040802080108010800080008000800500020
+52FB:0800080010001FF82008400880081F880008000800083FC80008000800500020
+52FC:100010003FFC2004440484043F84048404840884089410942074400400280010
+52FD:0800080010001FF8200842088208020805080488048808481048200800500020
+52FE:0800080010001FF820084208820804080408088810483FE81028000800500020
+52FF:0800080008001FFC124422444244844404440884108421044204040408281010
+5300:080008000FFC10042004480484040204002400C403041C040804000400280010
+5301:0800080008001FF811082908450882080308048804480838100E200840500020
+5302:100010003FFC200448048844088409040E0408140814081407F4000400280010
+5303:080008000FFC1004210441049104128412441424182410041FE4000400280010
+5304:100010003FFC20044204810400043FF408040804080408040FE4000400280010
+5305:080008001FF0101020105F909090109010901F9010501020100410040FFC0000
+5306:0800080008001FFC1244224442449C440644098410C421244214040408281010
+5307:100010003FFC2204420487E40824102424440244028401040604180460280010
+5308:0800080010001FF820084088888825282228252828A820283FE8000800500020
+5309:100010003FFC20044004BFE4020412440A440A8402047FF40204020402280210
+530A:100010003FFC2004420492440A8402047FF407040A8412446224020402280010
+530B:100010003FFC200448048FC4120402047FF40204124412441FC4004400280010
+530C:100010003FFC22044504888410446FB400041FC4104410441FC4000400280010
+530D:100010001FFC22444224BFF402043FE422243FE422243FE42224222422B42048
+530E:100010001FFC24047FE48884124462341FC412441FC412441FC4022401F40008
+530F:10401040FEFC2884450482F47C940094FEF4208440947C8804820482287E1000
+5310:100010001FFC20047FE480041FC410441FC400043FE422243FE422243FF42028
+5311:100010003FFC28045EF492141E1412F41E8412847EF40A1412142A5444280010
+5312:100010001FFC28844884BFE40A8405040884174460341FC4104410441FD41048
+5313:100010003FFC4004BDE4252425243D34260425E43C2420A428442CA433282010
+5314:100010003FFC28045EF492941E9412F41E0412F47E940A9412F42A0444280010
+5315:1000100010001008103010C013001C001000100010001004100410040FFC0000
+5316:0880088008841088109030A030C05080918012801480108210821082107E1000
+5317:044004400440044404487C500460044004400440044004421C42E442443E0400
+5318:409241244248492448925040608043FE4202428A42524A224A524A8A3BFE0202
+5319:00003E4022403E4422483E500060FF40084408442F44283C280058004FFE8000
+531A:00007FFC4000400040004000400040004000400040004000400040007FFE0000
+531B:00007FFC4200420047F0441048205020404040A041104608580440007FFE0000
+531C:00007FFC40804080448044F047905C9044D044A44484440443FC40007FFE0000
+531D:00007FFC4080408040804FF8488848884888488848A84890408040807FFE0000
+531E:00007FFC400040004FF84080408040804080408040805FFC400040007FFE0000
+531F:00007FFC4000410040805FFC400043E04220422042244424481C50007FFE0000
+5320:00007FFC4000403847C04400440047FC4420442044204820482050207FFE0000
+5321:00007FFC400040004FF84080408047F04080408040804FF8400040007FFE0000
+5322:00007FFC4400440047F84928512862484448488851084250442040007FFE0000
+5323:00007FFC400040004FF8488848884FF8488848884FF84888408040807FFE0000
+5324:00007FFC400040005FFC408040804FF8408040A040905FFC400040007FFE0000
+5325:00007FFC4200441048085FFC4004441044107FFE44104410481050107FFE0000
+5326:00007FFC442044205FA0487852285FA8422843A85E2A4A2A424642807FFE0000
+5327:00007FFC408040805FFC4080449044904AA8514441204220441048107FFE0000
+5328:00007FFC4220522052205E2043FC42207E205220522052F8620042007FFE0000
+5329:00007FFC4080488848884FF840805FFC400040804FF840805FFC40007FFE0000
+532A:00007FFC424042407E7C424042405E78424042407E7C4240424042407FFE0000
+532B:00007FFC44004FFC5124624444A849104FF848084FF848084FF840007FFE0000
+532C:7FFE4080414042204C1873F640004FA448A44FA448A44FA448844A9449087FFE
+532D:00007FFC44205F2044205F7855285F2855285F28442A5F2A444644807FFE0000
+532E:00007FFC40804FF848884FF840807FFE40004FF84888496842104C087FFE0000
+532F:00007FFC40A0489045FE612057FC452049FC7920492049FE490040007FFE0000
+5330:7FFE40005F7C51445F7C40004FF848884FF848884FF840807FFE408040807FFE
+5331:7FFE40804FF848884FF840807FFE48084FF848084FF848084FF8441048087FFE
+5332:00007FFC40805FFC42204C1877F6441047F040004F7849484F7840007FFE0000
+5333:7FFE4080414042204C1873E640005F7C514451445F7C44104A28514440007FFE
+5334:7FFE48404F7C54906FF848084FF848084FF848084FF842205FFC442048207FFE
+5335:7FFE40804FF840804FF849484FF8441047F0441047F0441047F0422044107FFE
+5336:7FFE44105FFC44904FFC58806FF848804FF848804FFC4408473844087FFE0000
+5337:7FFE49484F7849484F7849484F78448047F84C8057F0648047FC44007FFE0000
+5338:00000000FFFE10001000100010001000100010001000100010001FFE00000000
+5339:00007FFC444044404440444044404440444444444844483C500040007FFE0000
+533A:00007FFC4000401044104220414040804140422044104810400040007FFE0000
+533B:00007FFC440044004FF8508040805FFC4080414042204410580840007FFE0000
+533C:00007FFC40804140422044105BEC400047F04410441047F0441040007FFE0000
+533D:7FFE40004FF848084FF848084FF841005FFE4210472040C043304C0840007FFE
+533E:00007FFC40804FF848084FF848004FFC592469244FFC4924492C40007FFE0000
+533F:00007FFC400044107FFE441041007FFE44004FF85408640847F840007FFE0000
+5340:00007FFC40004FF0481048104FF040005E78524852485E78524840007FFE0000
+5341:010001000100010001000100FFFE010001000100010001000100010001000100
+5342:00007FF004100410041004100410FFD0041004100412040A040A040604020400
+5343:001000F83F000100010001000100FFFE01000100010001000100010001000100
+5344:084008400840084008400840FFFE084008400840084008400840084008400840
+5345:101011101110111011101110FFFE111011101110111011101110211020104010
+5346:020002003FE00420042008221022211E41000100FFFE01000100010001000100
+5347:012007A03C200420042004200420FFFE04200420042008200820102020204020
+5348:0800080008001FF811002100410001000100FFFE010001000100010001000100
+5349:0100010001007FFC01000100092008200820FFFE082008201020102020204020
+534A:0100210811080910092001003FF8010001000100FFFE01000100010001000100
+534B:0100010001007FFC01000100092008200820FFFE08200820082008200FE00820
+534C:201024902490249024902490FFFE249024902490249024902490249024902010
+534D:00043F84008400840084008400843FFC2084208020802080208020FE20002000
+534E:08800888109030E0518096841084107C11000100FFFE01000100010001000100
+534F:2080208020802080FBF020902090229822942492289220902110211022502420
+5350:200021FC210021002100210021003FFC01040104010401040104FF0400040000
+5351:020004003FF8210821083FF8220822083FF808801080FFFE0080008000800080
+5352:020001007FFC0820082008201450228801000100FFFE01000100010001000100
+5353:010001FC010001001FF010101FF010101FF011100100FFFE0100010001000100
+5354:2040204023FC2084F88421142208201024102FBE24922492249228A22AAA3144
+5355:1010082004403FF8210821083FF8210821083FF801000100FFFE010001000100
+5356:010001003FF8010001007FFC04040288128008800900FFFE0240042018106008
+5357:01000100FFFE010001007FFC482444444FE4410441045FF44104410441144008
+5358:2208110811103FF8210821083FF8210821083FF801000100FFFE010001000100
+5359:22102210FF9022103E1022103E7E22102210FFD040105210611040107F900010
+535A:205020482FFE204027FCFC4427FC244427FC244420082FFE2208210821282010
+535B:210447C88812F3BC20084B92F83E0380AAAAABAA01000100FFFE010001000100
+535C:0200020002000200020002800240022002100210020002000200020002000200
+535D:084008400840084008400840F87E084008400840084008400840084008400840
+535E:0200010001000000FFFE02000200024002200210021002000200020002000200
+535F:004000407C4044404440446044504448444444447C4044400040004000400040
+5360:01000100010001FE01000100010001003FF8200820082008200820083FF82008
+5361:0200020003F8020002000200FFFE020002000240022002100208020002000200
+5362:0100010001FC010001001FF81008100810081FF8100810002000200040008000
+5363:0100010001FE010001003FF8200820083F88208820883F88200820083FF82008
+5364:0100010001FE010001003FF8200824482288210822882448282820083FF82008
+5365:0100010001FE010001003FF8200829282528224825482888214822283FF82008
+5366:0840084008407F4008400860FFD0084808447F440840084008400FC0F0400040
+5367:00207FA04820482048207F304128412441227F224820482048207FA000200020
+5368:0100010001FC01001FF010101F9010907FFC40044FE4482448244FE440144008
+5369:000003F802080208020802080208020802080208022802100200020002000200
+536A:000003F802080208020802880248024802080208022802100200020002000200
+536B:00007FF8020802080208020802080208022802100200020002000200FFFE0000
+536C:0000060078FC408440844084408440844084408440844EA87090008000800080
+536D:00000000FEFC10841084108410841084108410841E84F0A84090008000800080
+536E:007C3F80200020003FFE2000200027F024102410245024242404440443FC8000
+536F:0C0070FC44844484448444844484448444844C8474A804900880088010802080
+5370:0000060078FC4084408440847E8440844084408440844EA87090008000800080
+5371:040004000FF0101020205FFC100013F012101210125012202204220441FC8000
+5372:000000007F7C1144114421442544424480443F4421442154214821403F402140
+5373:00007E7C424442447E44424442447E444044484444544A485240604000400040
+5374:08000800087C7F44084408440844FFC41044104424444254FF48414000400040
+5375:0C0070FC4484448464A454945494448444844C8474A804900880088010802080
+5376:100010003E7C4244A444184410442444C8441F442144D2540C4808403040C040
+5377:0100111009203FF8020002007FFC082010102FE8C826082008A80848080807F8
+5378:200020003F7C4844884408447F44084408442E44284428542F48F04040400040
+5379:08000800107C7F445544554455445544554455445544555457C8FC4000400040
+537A:1FC000447D88055009203118C50602003FF800001FF010101050102410040FFC
+537B:14001200217C49440844144422444144BE4422442244225422483E4022400040
+537C:0080FC8029F82A082DFE2900297829482968295029442A442C3C480247FE8000
+537D:080010007E7C42447E4442447E440044404440447E44405440484C4070400040
+537E:00007700557C5544774400447F440044FFC420443F440154014801400A400440
+537F:080073DE42524A524A524BD24A524A524A525BD26A124A9A125412B023104210
+5380:080008007F7C1C442A44494414442244494488442A441C542A48C94028401040
+5381:0808144822285C8888487F0E08F82A08490818087FFC01040114010801000100
+5382:00003FFE20002000200020002000200020002000200020002000400040008000
+5383:040004000FF0101020205FFC1000100010001000100010002000200040008000
+5384:00003FFE2000200027F024102410241024102450242024042404440443FC8000
+5385:00003FFE2000200020002FFE2040204020402040204020402040404041408080
+5386:00003FFE20002080208020802FFC208420842104210422042204440448289010
+5387:00003FFE2000201020F827802080208020FE3F802080208220824082407E8000
+5388:00003FFE200020002FFC20802080208020803FFE208020802080408040808080
+5389:00003FFE200020002FFE2100210021F821082108210822082208440848509020
+538A:00003FFE2000200027FE201022102210241027FE20502090211042104C508020
+538B:00003FFE200020802080208020802FFC2080208020902088208840805FFE8000
+538C:00003FFE200020802090208820802FFC20802140214022202220441048089006
+538D:00003FFE2000208020802FFC21002240244027FC204020404FFE404080400040
+538E:00003FFE20002000203C27C024402440244027FE242024202412450A46468422
+538F:00003FFE20002200220023FE2480248028FC3080208020FC2080408040808080
+5390:00003FFE20002220221022002FFC22402240224824502460484248C2933E2000
+5391:00003FFE200020202FA028A228A428A828B028A028A028A22FA248A2401E8000
+5392:00003FFE20002100210023FC2240244020403FFE204024442444444447FC8004
+5393:00003FFE2040204027FC204020402FFE20002040204027FC204040404FFE8000
+5394:00003FFE2000200027FC20802110220827FC2044204027FC204040404FFE8000
+5395:00003FFE20002F8428A428A42AA42AA42AA42AA42AA422242504448448949008
+5396:00003FFE241024083FFE249024A024C8249024A424C8249228E24982567EA000
+5397:00003FFE2080204027FC2000211020A02FFE2040204027FC2040404040408040
+5398:00003FFE200027FC2444244427FC2444244427FC2040204027FC404040408FFE
+5399:00003FFE204020402FFC204027FC244427FC244427FC20402FFE404040408040
+539A:00003FFE200027F8240827F8240827F8200027F8201020202FFE404041408080
+539B:00003FFE2000200C2F70294029402940297E2948294829482F48408840888108
+539C:00003FFE2000203827C0204027FC224822482FFE224822482FFE4040404087FC
+539D:00003FFE221022102FFC221022103FFE200027F82408240847F84408840807F8
+539E:00003FFE2120212021203F3E212021202F3C212021203F3E2120412041208120
+539F:00003FFE2080210027F02410241027F02410241027F020802490488852848100
+53A0:00003FFE20002F84288428A42FA428A42FA428A428A42FA42024490448949088
+53A1:00003FFE2080210027FC240427FC240427FC2040274421682250444859468080
+53A2:00003FFE22002200227C2F442244267C27442AC42A7C324422444244427C8244
+53A3:00003FFE20A020903FFE21402630380E2FF828882FF828884FF8488880800080
+53A4:00003FFE2000230C2E70221022103FFE2210273826B42A542A52529042108210
+53A5:00003FFE2000289025102FBE222222442A902A902F9022104228442884440882
+53A6:3FFE20003FFC210027F8240827F8240827F8240827F8220047F84A0881F01E0E
+53A7:00003FFE20802FFC208027F8240827F8240827F8240827F824087FFE42108408
+53A8:00003FFE20083F8820082F08297E290829082F4820282908260843885C288810
+53A9:00003FFE20002F7E291029102F502950297E2F1028282A2829284B4A4D4A8886
+53AA:00003FFE21102FFE211021F0204027FC244427FC20402FFE204047FC40408FFE
+53AB:00003FFE221022102F90221E2FA422243FD4241427942488248848944AA49142
+53AC:3FFE200027F8240827F8240827F8222027B02D2827FE380047F8440887F80408
+53AD:00003FFE20102F9428922F9028FE2F9020102F9028902F9028A84FA848C48982
+53AE:00003FFE2900290C3FB0292029202F3E29282F28292829285FA840488A881108
+53AF:00003FFE221022103FFE27182AB4325222102210208024442452441243F08000
+53B0:00007FFE420852484A504A9E5FE4505457545554554857485048515450948022
+53B1:00003FFE204020A0211022082DF6200027BC24A424A427BC211042A844448882
+53B2:00003FFE21102FFE211023F8224823F8224823F8204027FC245445F44414840C
+53B3:1104088408883FFE20002710211E2FD424A427942494278824E85F9440A480C2
+53B4:3FFE28882F8A20082FBE28882F88289429A2200027FC244427FC444447FC8040
+53B5:3FFE20802FF828082FF844904A8881007EFE48905EBC52A45EBC48906AD49930
+53B6:0200020002000200040004000400080008401020101020107FF8200800080000
+53B7:020002000200FFFE0400040004400840088010801100221044088FFC04040004
+53B8:080808080808080808081010101010102020242424244242FEFE424202020000
+53B9:020002003FE002200220042004220822311EC10002000420081010083FFC1004
+53BA:010001000100FFFE0280044009203118C20602000420081010083FFC10040004
+53BB:0100010001003FF80100010001000100FFFE020002000400082010103FF80008
+53BC:020002000400082010103FF81108010009200910110821044104010005000200
+53BD:020002000400082010103FF80008101010101010202024244242FEFE42420000
+53BE:00007FF00410041004103F90041004107FD0041008101112208A7FCA00460002
+53BF:00001FF0101010101FF0101010101FF010101010FFFE0400082010103FF81008
+53C0:01000100FFFE01003FF8210821083FF8210821083FF80400082010103FF80008
+53C1:0200044008201FF002007FFC0820101027C8C00600000FE0000000003FF80000
+53C2:0200044008201FF002007FFC082010902308CC4601800610182000C007007800
+53C3:040008201FF0102024487EFC010006C018B0E30E0C403190062038C007007800
+53C4:040008201FF0102024487EFC010006C01830E00E0FE000001FF000007FFC0000
+53C5:040008201FF0102024487EFC010006C01830E20E02201290124822480A000400
+53C6:000E03F078440224010803FEFE42104013FE208028FC4544FD28421004680186
+53C7:00100210797C001400FE0014FB7C21922154413851544992F930490002FE0400
+53C8:00003FF01010101010200820082004400440028001000280044008203018C006
+53C9:00003FF01010121011200920082004400440028001000280044008203018C006
+53CA:00003FE008200820084008400CF80A080A080910111010A0204020A043188C06
+53CB:020002000200FFFE040004000FF00A1012101120214040808140062018186006
+53CC:00000000FDFC0484448444842888288810501050282028204450448881040202
+53CD:001000F83F00200020003FF8240824102210222021402080414042208C183006
+53CE:0400040045FC448444844484448844884C505450642044200450048805040602
+53CF:020002003FF0021002100210FFFE020002003FF010100820044003801C70E00E
+53D0:00FC3F00010001007FFE0200040007F80A080A08111020A0404080A003180C06
+53D1:01001110110822003FFC0200040007F80A080908111010A0204040A003181C06
+53D2:00003FF000201E40018006601818E00400003EF8028822881450082034D8C306
+53D3:01000100FFFE01003FF8210821083FF801003FF010100820044003801C70E00E
+53D4:080008000EFC084408440844FF440028082808284A1049108928084828841102
+53D5:00003EF8020822881450082034D0C30800003EF8028822881450082034D8C306
+53D6:0000FF8022FC22443E44224422443E442228222827A8FA104210022802440282
+53D7:000801FC7E10221011207FFE400280043FF010100820044003800C603018C006
+53D8:02000100FFFE044014502448444400003FF0082004400280010006C01830E00E
+53D9:0800080014FC22444144BE44084408287F2808282A1029104928884828841102
+53DA:00003E7C2204220422043E7C200020003EFC204420443E282010202820C42302
+53DB:1008101C95E0590011007DFC11441144FF441128112811102110222842448482
+53DC:020001007FFE4112912422C00430180CE0023FF010100820044003801C70E00E
+53DD:100010FC108410847C941088108010FCFEA410A410A824A84290FEA842C40082
+53DE:00007F00417C41247F2440245F24402840287FA84410551094A8A4A814440882
+53DF:010005003978210821083D78210821083FF801003FF00820044003801C70E00E
+53E0:1FE0044003800C407EFC22441C3862440000FFFE90121FF010101FF01010FFFE
+53E1:10001F00107CFFA480A47F242A245528A2287F28A2903E1022283E2822443E82
+53E2:24481450FFFE08207FFC01003FF80100FFFE22003EFC22443E282390FE2802C6
+53E3:000000003FF820082008200820082008200820082008200820083FF820080000
+53E4:0100010001000100FFFE0100010001001FF0101010101010101010101FF01010
+53E5:0800080010001FF8200840089F8810881088108810881F881088000800500020
+53E6:00001FF01010101010101FF0020002007FF80208040804080808100820504020
+53E7:00001FF01010101010101FF0000000007FF8040804080808080810082050C020
+53E8:000000007DFC44444444444444444444444444447C4444840084010402280410
+53E9:000000FC7C8444844484448444844484448444847C9444880080008000800080
+53EA:00001FF01010101010101010101010101FF01010000008200810100820044004
+53EB:000400047C8444844484448444844484448C44B47CC444840004000400040004
+53EC:00007FF804080408080808081050202040009FF810081008100810081FF81008
+53ED:000000207920492049204920492049204920491079104A100208040808041002
+53EE:000000007BFE4820482048204820482048204820782048200020002000A00040
+53EF:00007FFE001000101F10111011101110111011101F1011100010001000500020
+53F0:0200020004000820101020087FFC200400001FF010101010101010101FF01010
+53F1:004000407C4044424444444844504460444044C07D40444200420042003E0000
+53F2:0100010001003FF82108210821083FF82108010011000900060005801870E00E
+53F3:020002000200FFFE04000400080008001FF8280848088808080808080FF80808
+53F4:020002003FE00220042004220822301EC0001FF010101010101010101FF01010
+53F5:00007FFC40004000400047F0441044104410441047F04410400040007FFE0000
+53F6:0020002078204820482048204BFE482048204820782048200020002000200020
+53F7:00001FF01010101010101FF00000FFFE080010001FF000100010001000A00040
+53F8:00003FF8000800087FE8000800081F8810881088108810881F88108800280010
+53F9:000007F87A084A084A0849104910491048A048A07840484000A0011002080C06
+53FA:020001007880488048404840484048A048A048A0791049100208020804040802
+53FB:00400040784048404BFC48444844484448444884788448840104010402280410
+53FC:000003FC780448044804481448244844488449044A0478044804000400280010
+53FD:000001F0791049104910491049104910491049107A104A1202120412040E0800
+53FE:00003FF800600180010001000100050002001FF010101010101010101FF01010
+53FF:000000007DFC44204420442044204420442044207C2044200020002003FE0000
+5400:0008003C7DE0442044204420442047FE442044207C2044200020002000200020
+5401:000001FC782048204820482048204BFE48204820782048200020002000A00040
+5402:02000100FFFE1000100010001FF8000000001FF010101010101010101FF01010
+5403:00800080790049FE4A004C0049F8480848104860788049000202020201FE0000
+5404:040004000FF0182024C003000CC03030C00E1FF010101010101010101FF01010
+5405:000000007EFC4284428442844284428442844284428442847EFC428400000000
+5406:00200020784048404884488449084BF849104810782048400088010403FE0102
+5407:000003F8780848104820484048404FFE48404840784048400040004001400080
+5408:010001000280044008203018CFE6000000001FF010101010101010101FF01010
+5409:010001000100FFFE0100010001003FF8000000001FF01010101010101FF01010
+540A:00001FF01010101010101FF0010001003FF82108210821082128211001000100
+540B:00100010781048104BFE48104810481049104890789048100010001000500020
+540C:00003FFC200420042FF42004200427E424242424242427E42424200420142008
+540D:0200020007F00810142062400280010006001FF8E8080808080808080FF80808
+540E:001000F81F00100010001FFE10001000100017F8140824082408440887F80408
+540F:01000100FFFE010001003FF82108210821083FF811000900060005801870E00E
+5410:0040004078404840484048404FFC48404840484078404840004000400FFE0000
+5411:0200040008007FFC4004400447C4444444444444444447C44444400440144008
+5412:0008003C7BC04840484048404840487E4BC048407840484200420042003E0000
+5413:000007FE78404840484048404850484848444844784048400040004000400040
+5414:0020002078204920492C493449644BA449244934792849220122010200FE0000
+5415:00001FF010101010101010101FF0000000003FF820082008200820083FF82008
+5416:0000020279044888485048204820482048204820782048200020002000200020
+5417:000003F07810481049104910491049FC4804480478044BF40004000400280010
+5418:00800080788049FC49204A20482048204BFE4820782048200020002000200020
+5419:00400040784048404A444A444A484C50484048A078A049100110020804040802
+541A:000003F87888488848884FFE4888488848884BF8788848800100010002000400
+541B:00003FF804080408FFFE040804083FF8080008001FF81808280848088FF80808
+541C:000003F8788848884888488848884FF849084908790849080108010807FE0000
+541D:020001007FFC0820044003800C603018C0061FF010101010101010101FF01010
+541E:00003FF801000100FFFE0280044008203018DFF610101010101010101FF01010
+541F:0040004078A048A049104A884C46484048004BF8780848100010002000200040
+5420:004000507848484848404FFE4840484048A048A048A079104910020804040802
+5421:002002207A204A224A224A244BA84A304A204A207A204A2202A20322021E0000
+5422:01000080088848044812481287F0000000001FF810081008100810081FF81008
+5423:00000040F0209010909090809080928492829282F28294880088008800780000
+5424:0040004078A048A049104A084C06491049104910791049100110021002100410
+5425:000000007BFE48104810482048204868486448A479224A220420002000200020
+5426:00007FFC008001000300056009183104C10200001FF01010101010101FF01010
+5427:000003F87A484A484A484A484A484BF84A084A007A004A020202020201FE0000
+5428:0040004078404BFC48404A484A484A484A484BF87848484000420042003E0000
+5429:0010009078904888490849044A044DFA48884888488878884908010802280410
+542A:00A000A078A0492449244B284D304920496049A07920492201220122011E0100
+542B:01000100028004400A203118C1060FE0004000801FF01010101010101FF01010
+542C:0008001C79E049004900490049FE491049104910791049100110021002100410
+542D:0080004078404FFC4800480049F04910491049107910491202120212040E0800
+542E:00800080790049104A084FFC48044920492049207920492002220222041E0800
+542F:010000801FFC1004100410041FFC10001000100017FC24042404440487FC0404
+5430:00400040784048404BFE4840488048904890492079204A480244048401FE0082
+5431:0020002078204BFE48204820482049FC48844888784848500020005001880606
+5432:000403E478244824482449E4490449044A044BE4782448240024002401440084
+5433:000007E00420142017E0100010001FF001100110FFFE0280044008203018C006
+5434:00001FF0101010101FF0000000003FF801000100FFFE0280044008203018C006
+5435:004000407840494849444A424A424C4848484848781048100020004001800600
+5436:004000200020FBFE8A228A228A328A4A8A4A8A86FB068A0202020202020A0204
+5437:0040004078404BF848484848484848484FFE484078A048A00110011002080406
+5438:000007F87908491049104920493C490449044A887A884A500420045008880306
+5439:00800080788048FC490449084A404C40484048A078A049100110020804040802
+543A:000001F07910491049104A0E4C004BF849084910789048A0004000A003180C06
+543B:01000100790049FC4AA44CA448A4492449244A447C4448840104020404280010
+543C:001007D078504890491049104950499049104F107910491201120112050E0200
+543D:002000207920492049FC49204A20482048204BFE782048200020002000200020
+543E:00007FFC020002003FF0041004100810FFFE00001FF01010101010101FF01010
+543F:0100110011001FF8210041000100FFFE010001001FF01010101010101FF01010
+5440:000003FC78104910491049104A104BFE48304850789049100210041000500020
+5441:00400040788048FC49044A044884484448444814482478444984000400280010
+5442:00001FF010101010101010101FF0020004003FF820082008200820083FF82008
+5443:000003FE7A004A004AF84A884A884A884A884AA87A904A8204820482087E1000
+5444:00003FE00420047C0804101461080100FFFE010001003FF8200820083FF82008
+5445:0080004078404FFC4910491049104910491048A078A0484000A0011002080C06
+5446:00001FF01010101010101FF0010001007FFC03800540092011102108C1060100
+5447:010001047D880550092011102108C50602001FF010101010101010101FF01010
+5448:00001FF01010101010101FF0000000007FFC010001003FF801000100FFFE0000
+5449:000007E00420142017E0100010001FF000100010FFFE00000440082010102008
+544A:0100110011001FF8210041000100FFFE000000001FF01010101010101FF01010
+544B:0040004078404BFC4840484048404FFE484048A078A049100110020804040802
+544C:001001107890489048104910489048904810481E7BF048100010001000100010
+544D:0000000079FC4800480048004BFE48204820484078404888010403FE01020000
+544E:000001FC790449044904490449FC492449204920791049100208020804040802
+544F:000800687B8848884888488848884BFE48884888788848880108010802080408
+5450:0040004078404BFC4A444A444A444A444AA44A947B144A040204020402140208
+5451:001000F83F00010002007FFC044008203018C0061FF01010101010101FF01010
+5452:000003FC78404840484048404FFE484048A048A078A0492001220222041E0800
+5453:009000907BFE4890489048004BF8481048204840788049000202020201FE0000
+5454:00400040784048404FFE4840484048A048A048A0791049100288024804440802
+5455:000003FC7A004A084A884A504A504A204A204A507A504A880308020003FE0000
+5456:000003FE7A004A204A204A204AFC4A244A244A247A444A440484048409281210
+5457:000001FC79044904492449244924492449244924792448500048008401020602
+5458:00001FF0101010101FF000003FF82008210821082108210822C8043018086004
+5459:00001FF01010101010101FF0010001007FFC4104428444444824400440144008
+545A:004000407C40448044FE450846884488448844507C5044200050008801040202
+545B:0040004078A048A049104A084C0649F049104910795049200104010400FC0000
+545C:0020004079FC49044904490449144908490049FE7802480203FA000200140008
+545D:0040002079FC4904490449FC49004900497C49087910492001420282027E0400
+545E:000001FC780448044BF44804480449F449144914791449F40004000400140008
+545F:0080004078404BFE48404840488849084BF0482078404888010403FE01020000
+5460:00400040784048404FFC484048E048E0495049504A487DF44842004000400040
+5461:000003FC7A044A044A044BFC4A204A204BFE4A207A204A100212028A03060202
+5462:000003FC7A044A044A044BFC4A004A404A444A487A704A4004420442083E1000
+5463:000001F8790849484928490849084FFE4A084A887A484A0803FE000800500020
+5464:0040004078A048A049104A484C2648204BF848087810491000A0004000200020
+5465:0040004078404BF84A484A484BF84A484A484A484FFE7A084A08020802280210
+5466:002001207120522052FC54A4572451245224522474A447A400C4004400940108
+5467:0008003C7BE04A204A204A204A204BFE4A204A107A104A12020A028A03260212
+5468:00003FF8210821082FE8210821083FF8200827C82448244827C8400840288010
+5469:000001FC7800480048004BFE48204820492849247A244A220422002000A00040
+546A:000003FC7A044A044A044A044BFC4890489048907890491201120212040E0800
+546B:0020002078204820483E48204820482049FC4904490479044904010401FC0104
+546C:000000007BFC4A944A944A944A944A944A944A944A9C7B044A04020403FC0204
+546D:004802487A484A484A484FFE4A484A484A484A487A784A000200020003FE0000
+546E:0000000079FC4904490449044904490449FC4904780048900088010402020402
+546F:000001FC78204820492448A448A848204BFE4820782048200020002000200020
+5470:0440044024442758246024422F42F03E40001FF010101010101010101FF01010
+5471:0008003C7BD04A904A904A904A904A904A904A887A884AC802A404D404920800
+5472:0090009078904A904A924AD44A984A904A904A907A904A9203D20E12040E0000
+5473:0040004078404BFC4840484048404FFE48E0495079504A480444084200400040
+5474:00800080790049FC4A044C0449E449244924492479E449240004000400280010
+5475:000000007BFE4808480849E8492849284928492879E849280008000800280010
+5476:02000200E27CA224AFA4A4A4A4A4A4A8A4A8A928E510A2100528094810840102
+5477:000007FCF4449444944497FC94449444944497FCF44490400040004000400040
+5478:000003FC782048204840484048D049484A444C44784048400040000007FE0000
+5479:004000407A404A404BFC4A404C4048404FFE484078A048A00110020804040802
+547A:000001F879084908490849F848004BFE4880490079F848080008000800500020
+547B:0040004078404BF84A484A484A484BF84A484A487A484BF80248004000400040
+547C:0008003C7BE04820492448A448A848204BFE4820782048200020002000A00040
+547D:0100010002800440082037D8C00600003EF82288228822883EA8229000800080
+547E:0000000079FC49044904490449FC49044904490479FC49040000000003FE0000
+547F:00200020782049FC4820482048204BFE4820484078404888010403FE01020000
+5480:000001F879084908490849F849084908490849F8790849080108010807FE0000
+5481:01080108790849084FFE490849084908490849F8790849080108010801F80108
+5482:000003FE7A104A104A104AFE4A924A924A924A927A9A4A940210021003FE0000
+5483:0120012079204AA04AAC4EB44AE44BA44AA44AB47AA84AA202A20282027E0200
+5484:00200020792449244924492449FC4824482048207A224A220222022203FE0002
+5485:020001003FF8000008200440FFFE000000001FF010101010101010101FF01010
+5486:0080008079FC49044A044DF449144914491449F4790449280112010200FE0000
+5487:00000040782048284808488848904A944AA24AA27CC248880188028804780000
+5488:0090009078904BFC489448944BFC4A904A904BFE78924892011A011402100410
+5489:0040004078404BF84A484A484A484A484A484FFE784048A000A0011002080406
+548A:003803C07840484048404FFC484048E048E0495079504A480444084200400040
+548B:01000100790049FE4A804A804C8048F848804880788048FC0080008000800080
+548C:04000E007800087C0844FF44084418441C442A442A444844887C084408000800
+548D:002000207840488849044BFE4802480049FC4904790449040104010401FC0104
+548E:104010401E502248224454440840144023FEC0001FF01010101010101FF01010
+548F:00400020781049E0482248344BB848B048A848A8792849240224042200A00040
+5490:0088008878884908497E4B084D08494849284928790849080108010801280110
+5491:01000100793E49084FC849084908494849884F08790849080108010805280210
+5492:00007CF84488448844887CF8000000000FC0084008400840104010422042C03E
+5493:000000007BFC4900490049F04910491049904A507A504A10021202920312020E
+5494:004000407840487C4840484048404FFE48404840785048480044004000400040
+5495:00200020782048204BFE48204820482049FC4904790449040104010401FC0104
+5496:04000400F400943C9FA494A494A494A494A494A4F4A494A408A408BC12A42100
+5497:00400040784048404BFE48404880488048FE491079104A100210041001FE0000
+5498:0040004078404BFE488048A0492049FC4B244D24792449240134012800200020
+5499:00900088788848804BFE48A048A048A448A449287928493202220262049E0800
+549A:0080008078F849084B104CA0484048A04B184C0678C048200010018000600010
+549B:0040002078204BFE4A024C04480048004BFE4820782048200020002000A00040
+549C:0040002078204BFE4A024C04490049084910492079C049020102010200FE0000
+549D:0108010871085210529454A457BC510851085210742057BC000000000FFE0000
+549E:000003FC789048904890489048904FFE48904890789048900110011002100410
+549F:000003FE78204820484049FC49044904490449FC490479044904010401FC0104
+54A0:00001FF0101010101FF000007FFC10101FF010101FF01010103EFFD000100010
+54A1:000003FE79084908490849F84908490849F849087908491E07E8000800080008
+54A2:00003EF8228822883EF800003FF80000FFFE040008000FF00010001000A00040
+54A3:004000447A444948495048404FFE4890489048907890489201120112020E0400
+54A4:0040002078204BFE4A024C0448384BC048404840787E4FC0004000420042003E
+54A5:000003FE78204840488849044BFE4822482048207BFE48200020002007FE0000
+54A6:00400040F7FE904097FC904493FC9240944097FEF04290AA00A4011002080C06
+54A7:00040004EFC4A214A214A3D4A254A454A654A554E894A0940104020404140808
+54A8:4080208009FC12042448E04020A023182C0600001FF01010101010101FF01010
+54A9:01040084788848004BFE4820482049FC482048207BFE48200020002000200020
+54AA:004000407A484948495048404FFE484048E0495079504A480444084200400040
+54AB:00003E7C22442244224422443E7C2A002828282428442442248242004180807E
+54AC:00800040F04097FC900091109208940491109110F0A0904000A0011002080C06
+54AD:0020002078204BFE4820482049FC4800480049FC790449040104010401FC0104
+54AE:00200120792049FC49204A2048204BFE487048A878A849240124022200200020
+54AF:0080008078F849084B104CA0484048A049184A067DF849080108010801F80108
+54B0:0080008079FC49044A0449E44924492449E44924792449E40104000400280010
+54B1:0020004079FC49044904490449FC49044904490449FC79044904010401FC0104
+54B2:02080108791048004BFC4840484048404FFE4840784048A000A0011002080406
+54B3:00400020F02097FE90409084910893F090229044F18896100020005001880604
+54B4:0040004078404BFE4880489048904912495249547A904A280428004400840102
+54B5:002000207BFE4850488849044AFA48004BFE4840788049FC0004000400280010
+54B6:0008003C79E0482048204BFE48204820482049FC790449040104010401FC0104
+54B7:0090009078904A9249944898489049984A944C9278904890011201120212040E
+54B8:0050004800403FFE204020402F44204420442F28292829122F32494A40868102
+54B9:0040002078204BFE4A024C4448404BFE48884888790848D00020005000880304
+54BA:000003FE7800480049FC4904490449FC4904490479FC49040000000003FE0000
+54BB:009000907890491049FE4B104D10493849384954795449920110011001100110
+54BC:00001FF0101010101F90109010907FFC400440044FE4482448244FE44004400C
+54BD:000007FCF40494449444944497FC9444944494A4F49495140604040407FC0404
+54BE:0040004078444BF4484848504FFE4840488049844A987CE048820082007E0000
+54BF:0100017CF1249224922496FE9A2492249224927CF22492200220022002400280
+54C0:02000100FFFE000000001FF0101010101FF0028004440C283410C50806060400
+54C1:00001FF010101010101010101FF0000000007C7C44444444444444447C7C4444
+54C2:000007FE7890489048904BFC4A944A944A944A947A9C4B040204020403FC0204
+54C3:000003FC7A044A044AF44A044A044AF44A944A947A944AF40204020402140208
+54C4:01100110791049104BFC49104910491049104FFE780049100108020804040804
+54C5:01000100790049FE4A024A024D1248A24A4A4AAA7B1A4A0A03FA000200140008
+54C6:00800080F1F89210952090C0909093209C7C9084F10896900060004001800E00
+54C7:0020002079FC4820482048204BFE48004820482079FC48200020002003FE0000
+54C8:0040004000A0F8A089108A088C0689F4880088008BF8FA088A08020803F80208
+54C9:0840084808447F4408400840FFFE004000443E442228222A22123E2A22460082
+54CA:00400040F7FE9080910091FC9304950499FC9104F10491FC0104010401140108
+54CB:021002507250525C5F7452D4525452545254525C725053520E420442003E0000
+54CC:0008003CF7C09400941C95E09520952295249528F51095100508094409821100
+54CD:0040004078804BFC4A044A044AF44A944A944A947A944AF40204020402140208
+54CE:011001107BFC4910491048004A084A084910491078A0484000A0011002080C06
+54CF:000003F87A084A084BF84A084A084BF84A444A487A304A200210028803060200
+54D0:000003FE7A004A004BFC4A204A204AF84A204A207A204BFC0200020003FE0000
+54D1:000003FC78904890489048924C924A944A944A98789048900090009007FE0000
+54D2:001002107910491048FE48104B104928492449447942498201000280047E0000
+54D3:0080008078BC4BC04850482448D44B0C48004BFE7890489001120112020E0400
+54D4:01100112791449D8491049124952498E492048207BFE48200020002000200020
+54D5:002001247924492449FC4840484048FC49044A84784848500020004000800300
+54D6:0080008078FE49104A10481048FC4890489048907BFE48100010001000100010
+54D7:00900094791449184B104D324952490E492048207BFE48200020002000200020
+54D8:00800080793C4A004C804880497E4B084D084908790849080108010801280110
+54D9:0040004078A049104A084C0649F0480048004FFC784048800110020807FC0204
+54DA:000001F079104910491049104A4E4C404BFC484078E049500248044600400040
+54DB:00807C8844B044C444847C7C00000440082010102FE8C4260420082010A06040
+54DC:004000207BFE490448884850482048D84B064888788848880088010801080208
+54DD:00400040F04097FC948498889140914493489530F92091100108014401820100
+54DE:00400040789049084BFC48244920492049FC4A2078204FFE0020002000200020
+54DF:02200220F220943C95449F449284922494149F94F404900401840E0404280010
+54E0:00200120792049FE4A204C2048204BFE4800480079FC49040104010401FC0104
+54E1:00001FF0101010101FF000003FF820083FF820083FF820083FF8082010102008
+54E2:000003FE7820482049FC482048204BFE488848887BFE48880088010801080208
+54E3:000003FC7800480049F849084908490849F84800790848880090000007FE0000
+54E4:0110010879004FFE494849504964494849504A647A484A520462044209BE1000
+54E5:00007FFC00101F90109010901F900000FFFE00101F90109010901F9000500020
+54E6:002801A4F724912091209FFE9120912491A49328FD2891100112012A05460282
+54E7:0020002079FC4820482048204BFE48484848494C794A4A4A0088008801280210
+54E8:0020012478A448A8482049FC4904490449FC4904790449FC0104010401140108
+54E9:000007FCF444944497FC9444944497FC90409040F7FC9040004000400FFE0000
+54EA:00000FDE72525252525457D45258525452525FD27252525A0254045005500890
+54EB:000001FC79044904490449FC482048204920493C7920492002A00260043E0800
+54EC:0100010079FE4A044A044EF44A944A944A944A947AF44A940204020402140208
+54ED:00003C782448244824483C78000001100108FFFE01000280044008203018C006
+54EE:004000447BF4484848484FFE482048404BF849107A204DFE0820002000A00040
+54EF:000001FC7904490449FC4904490449FC4904490479FC4850009000920112020E
+54F0:004000207BFE4A024C24492049FC49204A2048207BFE48200020002000200020
+54F1:002000207BFE482048204BFE4A024C0449F8481078204BFE0020002000A00040
+54F2:080C08F07E8008800EFE788808882908120800001FF01010101010101FF01010
+54F3:0208021C726052405FC05240527E52C853485E4872485248024802480A880508
+54F4:008000407BF84A084A084BF84A084A084BF84A407A444A280210028803060200
+54F5:000203E27A224A2A4A2A4BEA490A490A4BEA492A792A492A0222022204AA0844
+54F6:0088008878884B8E48884888480049FC482048207BFE48200020002000200020
+54F7:0008003C7BC048444A244928490048104BFE4810791048900090001000500020
+54F8:0008003C7BC048444A244928490048404BFE488879084B900060005001880604
+54F9:0008003C7BC048044A44492848004BF8481048204FFE78204820002000A00040
+54FA:00480044F7FE9040904093FC9244924493FC9244F24493FC0244024402540208
+54FB:000001FC790449FC490449FC4800480049FC482078204BFE0020002000200020
+54FC:004000207BFE480049F84908490849F848004BFC780848300020002000A00040
+54FD:000007FEF04097FC9444944497FC9444944497FCF24091400080014002300C0E
+54FE:010400847888481049FC49044904490449FC48507850489000920112020E0400
+54FF:080008007F7C114411442544427C0000FFFE00101F90109010901F9000500020
+5500:001C01E0782048204BFE48A849244A2249F84888789048BE0102010202140408
+5501:004000207BFE4800480049FC4800480049FC4800780049FC0104010401FC0104
+5502:01100108F2049444904090A0911092089C0693F8F20892080208020803F80208
+5503:010001007BF84A084C104BFC4A444A444BFC4A447A444BFC0244044404540808
+5504:000001FC7904490449FC4904490449FC4904490449FC78004888008401020202
+5505:0040004078A049104A884C4649F04810482048407BF84A080208020803F80208
+5506:00400040788849044BFE4802488849444A4248F879884A500020005001880606
+5507:00003FFC20002FF820003FFE248824502530260E20002FF8480848088FF80808
+5508:000001F87908490849F848004BFC4A444A444A447BFC4A000202020201FE0000
+5509:00400080F110920897FC9104910093F8944090409FFEF04090A0011002080C06
+550A:0020002078204BFE482048204924492449244AAA782048500050008801040202
+550B:002000207850488849044AFA482048204BFE4820792849240222042200A00040
+550C:0004000E7BB8488848884928492E4BA848A84AA87AA8493E01000280047E0800
+550D:004000207BFE4A024C0449F8480048004BFE48907890489001120112020E0400
+550E:004200E27B82488A488A488A4FEA488A498A49CA7AAA4A8204820082008A0084
+550F:01840068783048C84B0448404BFE48A049204BFC7D2449240134012800200020
+5510:010000803FFE20802FF820883FFE20882FF820802FF82808480848088FF80808
+5511:00400040F24892489248955498E29040904097FCF0409040004000400FFE0000
+5512:00000FFEF0A090A097FC94A494A494A4951C9604F40497FC0404040407FC0404
+5513:002000207BFE482049FC4924492449FC4924492449FC78204BFE002000200020
+5514:000007FCF040904093F89088908897FE90009000F3F892080208020803F80208
+5515:0020004079FC4904490449FC4904490449FC482078204BFE0020002000200020
+5516:000003FC7890489048904BFC4A944A944A944A947BFC48900090009007FE0000
+5517:0020002079FC4820482048204BFE482048204920793C492002A00260043E0800
+5518:0000FEFC104420443E286210A2283E44228200001FF01010101010101FF01010
+5519:001008907510521255525954515851905310552879285128014801440A840502
+551A:000001FC780448FC480449FC48004BFE4A0249F8788848880050002000D80306
+551B:00400040F7FC904093F8904097FE908090F89108F31094A0004000A003180C06
+551C:010001007FFC01003FF8054009203118C10600003E442258226022423E42223E
+551D:000001FC782048204BFE4800480049FC49044924792449240154008801040602
+551E:01040124791449144FC449244914495449864F3C790449040104010405040204
+551F:010001003FF801000100FFFE040008201FF000103E442258226022423E42223E
+5520:008800887BFE488848004BFE4A024C4448404BFC784448840084010402280410
+5521:000003FE7850485048504BFE4A524A524A524AAA7AA64B0202020202020A0204
+5522:0020012478A448A8482049FC4904492449244924792449240050008801040202
+5523:0020004079FC4904490449FC4904490449FC48407840487E07C000420042003E
+5524:01000100F1F0921094209BF89248924892489248F7FE90A000A0011002080C06
+5525:001004107A284A2848444992490849084AFE4E027A044A440228021002080008
+5526:00100210791049104C544A524A524890481049147E044A0802080210022000C0
+5527:000007BC74A454A454A457A454A454A454A457A47434552804A0056006200020
+5528:000007BC74A455245524563C552454A454A454BC76A4552404240424047E0400
+5529:001C01E0782048204BFE48A849244A4248404BFE7888490800D0003000480184
+552A:00400040F7FC904093F8908097FC911092489446F1F0904007FC004000400040
+552B:0040004078A049104A084C0649F0484048404BF878404A48014801500FFE0000
+552C:00400040787C48404BFC4A444A704BC04A444A3C7A004AF0049004920912120E
+552D:008800887BFE4888488848F84888488848F8488878884BFE0000008801040202
+552E:090008800FFC10803FF850809FF810801FFC00001FF81008100810081FF81008
+552F:00A00090788049FE49104B104DFC4910491049FC79104910011001FE01000100
+5530:000207E27422542A57EA548A548A548A57EA56AA76AA5AAA0AA212E2008A0084
+5531:01F80108790849F84908490849F848004BFC4A047A044BFC0204020403FC0204
+5532:000000407B9C4A044A044B9C4A044A044BFC489078904890009001120212040E
+5533:004000207BFC4A044A044BFC4A004A284A244BFE7A204A500250048805040A02
+5534:02080108F11097FC9040904093F8904090809FFEF1209120022002220422081E
+5535:004000807BFC49104A484C464BF84A484A484BF84A487A484BF800420042003E
+5536:0088008878884BFE488848884FFE480049FC4904790449FC0104010401FC0104
+5537:004000207BFE488049044BFE480249FC490449FC790449FC0104010401140108
+5538:0040004078A049104A884C4648004BF048104820784049240522050A090800F8
+5539:0108008878084FD44A144A224A004BC84A444A447A404A500248044405440880
+553A:0090009078904BFC4A944A944A944BFC4A944A944A947FFE4800009001080204
+553B:0040004078404FFC48404A484A484A484D5448E0795049500248044408420040
+553C:008000407BFC4800490848904FFE484048404FFE788849080090006001980604
+553D:01000106F138912097A09120913E932493A49564F52499240124012401240144
+553E:00100078F3C09040904097FC9248924897FE9248F24897FC0040004007FC0000
+553F:01000100F3FC9494989491249244948491289210F0409124052A050A08F80000
+5540:000003FE7A104A104AFE4A104A104BFE4A004A107A104AFE0210041005FE0800
+5541:000007FCF444944495F49444944497FC940495F4F514951405F4040404140808
+5542:00E80F08E228A928A548A008A7C8A088A108A108E1E8AF08010A010A050A0206
+5543:00200120793C492049204FFE48004BFC4A044BFC7A044BFC0204020402140208
+5544:000003FE7840488049444A2448684AB049304AA8786848A40122022000A00040
+5545:00200020783E482049FC490449FC490449FC492448207BFE4820002000200020
+5546:020001007FFC082004403FF820082448282837D82448244827C8200820282010
+5547:020001007FFC082004403FF821082FE8210827C82448244827C8200820282010
+5548:0020002079FC482048204BFE4888485049FC482078204BFE0020002000200020
+5549:011001107110511057BC51105110533853B85554755459920110011001100110
+554A:00000EFCEA08AA08AAE8AAA8ACA8AAA8AAA8AAA8EAE8AAA80C08080808280810
+554B:0008003C7BC048444A244928490048204BFE487078A848A80124022204200020
+554C:0040002078204BFE4A024C9449084A04480049FC782048200020002007FE0000
+554D:004000207BFE480049FC490449FC480049FC480878104BFE0020002000A00040
+554E:200021FE20203E2049FC8844084409FEFE00080008FC08840884088408FC0884
+554F:00007CF844887CF844887CF8400840084FC8484848484FC84848400840284010
+5550:00800040F7FC90009110911092A8944490009040F7FE90400040004000400040
+5551:002000207BFE482049FC48244BFE482449FC48207920493E012002A0027E0400
+5552:000003FE7A024A024BFE4A104A924A924A924AFE7A104A920292049204FE0802
+5553:104008403E7E228823483E5020204058418680001FF01010101010101FF01010
+5554:104808443E7E23C022243E282212206A418680021FF01010101010101FF01010
+5555:0100010079FC4A044D0449E44A8448844FF448847AA44AA403E4000400280010
+5556:00400244F244944890A091109608904490409248F248945000A0011002080C06
+5557:0080008078F849084A104C0048404B9C4A044A047B9C4A040204020403FC0204
+5558:00800040F7FE94029A04920093BC94A494A496A4F9349128022202220422081E
+5559:04400440244427582460244224422F42F03E00003E7C2244224422443E7C2244
+555A:00001FF0101010101FF00100FFFE02003FF8200827C8244827C820083FF82008
+555B:002000207BFE482049FC48244BFE482449FC48407BFE488401C8003000CC0302
+555C:000007BC708452945108529454A45840500057BC70A452A40128029004A80846
+555D:000001807700511E51125FD2511253125392535275525512091E011201000100
+555E:000007FE7890489048904B9C4A044A044A044B9C789048900090009007FE0000
+555F:082004203F20213E214421443F4420A420283F283110511051289F2811440082
+5560:060C3870204020403F7E244824482448448881001FF01010101010101FF01010
+5561:00900090F090979E909090909090939C90909090F090979E0090009000900090
+5562:000003FE782048204BFE4A224A224B324AAA4AAA7B764A6602220222022A0204
+5563:0400040077DE5912511251125FD25112511255D27512551A05D41E1008100010
+5564:004000807BFC4A244A244BFC4A244A444BFC489079104FFE0010001000100010
+5565:0040004078A049104A084DF6484048404FFC484078404BF80208020803F80208
+5566:012001107110517E57805104514451C4512453247528512801080110057E0200
+5567:002000207BFE482049FC48204BFE480049FC4904792449240124005000880304
+5568:002000207BFE482049FC48204BFE480049FC490479FC490401FC010401140108
+5569:01100110F7D09110911091189FF4901291129110F7D09110011001D00E100410
+556A:021002107220527C5FC45244524452C4537C5E4472445244024402440A7C0444
+556B:004000447BF4484848504FFE4840488049F84B087D0849F80108010801F80108
+556C:010001007FFC010011100920FFFE00003FF8200827C8244827C820083FF82008
+556D:0210021072105FBC52105510557E57905120513C71C45F080528011001080104
+556E:00400040F27C9240924092409FFE900094449444F4A494940514040407FC0004
+556F:000003FE7A024A024BFE4A224A224AFA4A224A327A2A4BFE0202020203FE0202
+5570:000003FE7A524A524A524BFE4820484048FC49047A8848500020004001800600
+5571:002001247924492449FC480048004BFE4840488078FC49840284048400FC0084
+5572:0088008879084BDE4A524A624A424A524BCA4A4A7A424A42024203C202540008
+5573:00400248F15097FC908091009FFE921094089BF4F212921002500224020401FC
+5574:01040088785049FC4924492449FC4924492449FC7820482003FE002000200020
+5575:00100410721052FE58925494549052FC52A454A47CA854A80490052805440282
+5576:004000207BFE4A024C0448004BFE482048204920793C492002A00260043E0800
+5577:0100009E7BD24A524A544BD44A584A544BD24A127A924A5A02D4035002100010
+5578:004000407BF848484FFE48484BF848404A484A487AE84B580248024804480848
+5579:000003FC7A044A044BFC4A204A204BFE4A204A207AFC4A840284048404FC0884
+557A:000001FC790449FC490449FC48004BFE490049FE7A4A4C920122024200940108
+557B:01003FF8082004407FFE41029FF411101150112001003FF8200820083FF82008
+557C:0040002079FC4800488848504BFE4A224C2449FC492479244934012800200020
+557D:004000A079104A084DF648004BF84A084A084BF87910491007FC011002100410
+557E:008801C877085108512A512A57AC514853085388755455140914012401240142
+557F:008800887BFE488848F8488848F8488848884BFE790049480184010001FE0000
+5580:004000207BFE4A02488048F849084A90486049987E0649F80108010801F80108
+5581:01FC0124792449FC4924492449FC482048204BFE7A224A2A02FA020A02020206
+5582:000003F87A484A484BF84A484A484BF848004FFE7A404A440228029003080206
+5583:00400040F7FC9040904097FC951494A495F49444F44495F40444044404540408
+5584:082004407FFC01003FF801007FFC11100920FFFE00001FF0101010101FF01010
+5585:000001FC790449FC490449FC4904484048204BFE780049040088000007FE0000
+5586:101010101010FEFE101010107C7C000000007C7C44444444444444447C7C4444
+5587:0104010477C45104511457D45554555457D45114739455540944010401140108
+5588:022002247BA84A304AA24B224A5E48804BFC4A047A044BFC0204020403FC0204
+5589:010001787108520852FE56405A40527C5290521072FE52100228022802440282
+558A:00140012701057FE5410541055D05412541255D47554554805DA042A08461082
+558B:0048014879484BFE494849484978490049FE48207BFE487000A8012406220020
+558C:00007EFC428442847EFC00001008110811085548532891082108210841088108
+558D:009000927AD44A984A924AD24F0E482048204BFE787048A80124062200200020
+558E:000001FC7904490449E4492449244BFE4A024AFA7A8A4A8A02FA0202020A0204
+558F:01080108F7FE91089148904097FE9080910093FCF50499040104010401FC0104
+5590:0100011E77F25112521453D4525856545BD25252725253DA02540250025002D0
+5591:008000407BFC4800490848904FFE480049F84908790849F80108010801F80108
+5592:0088008879EC492A4A284D484888497E4E0049FC7904490401FC0104010401FC
+5593:000003FE785048504BFE4A524A524BFE480048404FFE78884990006000D80304
+5594:000003FC7A044A044BFC4A004BFC4A404A884BFC7A244A2005FC0420082013FE
+5595:000007FE784048804BFC4A944A944AF44A944A947AF44A940294029403FC0204
+5596:010801087108510857BE510853085388557E55227922512201220122013E0122
+5597:000003FE7A2248204BFE482049FC492449FC492479FC482003FE002000200020
+5598:00400444F444944497FC90009FFE9040908097FCF4A494A404A404A404A4040C
+5599:010001F8F20893F0901097FE90809144966890B0F128966800A4012206A00040
+559A:01000100F3F09410982097FC940494A495149444F0409FFE00A0011002080C06
+559B:003C07C07A44492848004BFC488048804FFE490079F84A880250042008D80306
+559C:01007FFC01003FF800003FF820083FF80820FFFE00003FF8200820083FF82008
+559D:000003F87A084BF84A084BF849004BFC4C444A447AA44A0403F4000400280010
+559E:008001007BDE4A524A524BD24A524A524BD248127A5A4B940210025001D00010
+559F:000003FE7A224BFE4A224BFE480049FC490449FC790449FC0104010401140108
+55A0:0008003C79E048204BFE482049FC492449FC492479FC482001FC002003FE0000
+55A1:0040004079FC48844BFE480049FC490449FC48207BFE4820022003FE00200020
+55A2:0004001E7BE0482048204FFE482048A04B2E4A227A224BAE0222022203FE0202
+55A3:0100010079FC4A044C0449E44924492479E44804002800102488224442448004
+55A4:0020004079FC490449FC490449FC48004BFE4820782049FC0020002003FE0000
+55A5:004000207BFE4A484A484BFE4A484A784A004AFC7A444A480228041004680986
+55A6:00001FF0101010101FF000007D7C454445447D7C01002108210821083FF80008
+55A7:004000207BFE4A024C0449FC480049FC490449FC790449FC0104000003FE0000
+55A8:00800040F7FE900093F8920893F8900097FE9402F9F49110011002120412080E
+55A9:01C000A079104A084DF648004BCA4A4A4A544BD47A684A5403D4024A024A02C0
+55AA:010001007FFC01003D7825483D780100FFFE1200111010A010401430180E1000
+55AB:0080009E7BEA488A49CA488A4BEA489248A648207BFE48200050008801040602
+55AC:00F83F000200FFFE04400FE03458C7C600003FF8200827C8244827C820282010
+55AD:004000207BFC4800490848904BFE4A104A204AC87A104A2402C8041004600980
+55AE:00007EFC428442847EFC00003FF821083FF821083FF80100FFFE010001000100
+55AF:002000207BFE485048A849244AFA482048A848887BFE48880088008801080208
+55B0:0040004078A049104A884C464BF84A084BF84A087BF84A440228029003080204
+55B1:000007FEF40095FC9524952495FC9524952495FCF420942005FC0820082013FE
+55B2:011001107210529E54A25F2251425212548A5FCA744250020A82094211540008
+55B3:00400040F7FC90E091509248944693F8920893F8F20893F8020800000FFE0000
+55B4:0014001277FE5410541057F05492549257D2555475545488054A0A1A08261042
+55B5:008800887BFE48884888480049FC49244924492479FC49240124012401FC0104
+55B6:2208111000207FFE400280041FF0101010101FF000003FF8200820083FF82008
+55B7:002001FC782048884BFE4888480049FC49044924792449240124005000880304
+55B8:012001107FFC01003FF821083FF821083FF8210800007C8844B044C47C84447C
+55B9:00400040F7FC90A0911092489DF69040904097FCF000904003F8004000400FFE
+55BA:0106017871105222524456F85A14522252FE5212721052540292031202500220
+55BB:004000A079104A084DF648004BC44A544A544BD47A544A5403D40244025402C8
+55BC:0080008079F84A084C104BFC480449FC48044BFC780448400124052A050A08F8
+55BD:0020012478A848204BFE48A849244A0248404FFE788849080190006001980604
+55BE:2208111000207FFE410291041FF021000100FFFE00001FF0101010101FF01010
+55BF:00001FF0101010101FF000007C7C444444447C7C01007FFC05401930E10E0100
+55C0:10001078FE4810487C480086FE0082FC00447C4400287C28441044287C444582
+55C1:0004001E7BF04A1E4A104AFE4A924A984AF24A8E7A804AB802A804AA054A0A86
+55C2:0008003C7BC048044A44492849FC4A2048204BFE782049240124012401FC0004
+55C3:004000207BFE480049FC490449FC48004BFE4A027AFA4A8A02FA0202020A0204
+55C4:07FC0080F3F8920893F8920893F8920893F89080F1F8931004A0004001B00E0E
+55C5:004000807BF84A084BF84A084BF84A084BF8485078484FFE00A0011002080C06
+55C6:00400040F0A09190924897FE9A0893F8920893F8F20093F80508050809F80108
+55C7:010001007FFC111029284544FFFE00003FF8200827C8244827C820083FF82008
+55C8:012402487A4849244BF84A084BF848004BF84A487A484BF80202020201FE0000
+55C9:002000207BFE482049FC48204BFE4840488849F078244BFE0022012402A20040
+55CA:000001FC782048204BFE480049FC490449FC490479FC490401FC008801040202
+55CB:004001FC7844489449084BDE494A494A4A9449FC790449FC010401FC0104010C
+55CC:02080108F110900097FC900091109208940493F8F2A892A802A802A80FFE0000
+55CD:0440025E7292501257D2511E55525552555257DE7152511202120222042A0844
+55CE:000001FE792049FC492049FC4920492049FE48027AAA4AAA02AA020200140008
+55CF:008800887BFE488848A84850488849244A2249FC782048A80124022200A00040
+55D0:004000207BFE4A024C2449FC482049FC48204BFE782049FC0104010401FC0104
+55D1:0020002079FC482048204BFE488049044BFE48027BFC4A940294029407FE0000
+55D2:01100110F7FC9110904090A09110920895F69000F00093F80208020803F80208
+55D3:03F00110F0E09318900097BC94A4931894A49040F7FC90E0015002480C460040
+55D4:00400040F7FC904093F8920893F8920893F89208F3F892080FFE011002080404
+55D5:000003FE7A004AFC4A004BFE4AA84A904AC84A867A084BFE0288044804080818
+55D6:0140065CF4449444975C9444944497FC904097FCF208911000A0004001B00E0E
+55D7:000001FC790449E449244BFE4A0249FC490449FC790449FC0104010401140108
+55D8:001E03E0792248944840488849F0482048C449FE7822482003FE005000880306
+55D9:004000207BFC490848904BFE4A024C4448204BFC788048F80088010801280210
+55DA:0040008079FC4904490449FC490049FE490049FE78024AAA02AA040200140008
+55DB:0108009078004BFE48A04BFC48A44FFE48A44BFC78A049B002A80CA600A000A0
+55DC:0040004479F848504BFE484048F849824A7E4C0079FC490401FC010401FC0104
+55DD:00000FFEF00093F89208920893F8900097FC9514F4A497FC0444044404540408
+55DE:0084004478484BFE488448844908494A4A524B9C788449080108025203DE0042
+55DF:0108008878904BFC484049F848404BFE4880490079FC4A200420082003FE0000
+55E0:0E40F04022789288555000207C500888110610F81E88F0885088108850F82088
+55E1:0090008879044A424C8849FC480448004BDE48427A52494A02520042014A0084
+55E2:000001F87908490849F84908490849F848004BFC7A944A940294029407FE0000
+55E3:00003E7C220422043EF400047F045574555455547F5455545574550451144308
+55E4:00200124792449FC48204BFE4800482049FC4924792449FC0020002403FE0102
+55E5:00400080F3F8920893F8920893F8908097FC9110F24894440BFA004000400040
+55E6:00400040F7FC904097FC9484991893E090409088F7FC90440250044809480080
+55E7:10007E7812482A48457882800C6037D8C0063FF8248824883FF8248824A82010
+55E8:00800880E4FEA100AAFCA484A4A4A094A3FEA484ED24A51405FE040404280010
+55E9:0020012478A8482049FC4904490449FC490449FC4904790449FC000000880104
+55EA:00400040F7FC904093F8908097FC9110926895C6F04093F800E0015806440040
+55EB:000003FC790849F8490849F8490E4FF848084FBC78A44AA40128029004A80846
+55EC:01100110F7FE9110910092FE920896089AE892A8F2A892E802A8020802280210
+55ED:01007FFC01001FF010101FF010101FF010101FF01010FFFE00903EE422843E7C
+55EE:000000FEEE28AA28AA28AAFEAAAAAEAAAAAAAAAAEAAEAAC20E820A8200FE0082
+55EF:000007FCF444944497FC944494A49514940497FCF04090240522050A090800F8
+55F0:020003FC752455245D2455FC5524552455745554755455540574050405FC0504
+55F1:00200050788849744A0248F8488848F8480C49F0782049FC002003FE00200060
+55F2:00900108F29490609198964690FC930890B090D0F73E90C20324001800600780
+55F3:000E03F078444A2449084BFE4A4248404BFE488078FC49440128021004680186
+55F4:010800907BFC4840484049F8484048404BFC48A078A848B4013C01220222041E
+55F5:01FC0808E450A420A1FCA124BD24A5FCA524A5FCE524A524052C0A0011FE0000
+55F6:000001FC792449FC492449FC48A848A84BFE48A878A849FC002003FE00200020
+55F7:01080108710857D0511E579451245FD4521453D472545248024804D404240842
+55F8:08207F20087E7E4408A4FF2810101E282244468280003FF8200820083FF82008
+55F9:0020082075FE542051FC51245DFC552455FC542075FE542004200A2011FE0000
+55FA:002002227BFE4890488849FE4B104D1049FE4910791049FE0110011001FE0100
+55FB:004000207BFE4A004A484A484BFE4A484A484A487A784A000554052A0A2A1000
+55FC:008800887BFE4888480049FC490449FC490449FC78204BFE0050008801040202
+55FD:01080108F7C89108911E97D29564954097C89108F38895480954011401240142
+55FE:04200220723E5F4054A05420573C55505510551075FE5510052809280B441082
+55FF:004000A079104A484DF6482048404BF84A084BF87A084BF8020803F801100208
+5600:00800040F7FC911090A097FC944495F4944495F4F514951405F4040404140408
+5601:00140012701057FE5410549054D2549257F25494749455C80AAA089A11A60042
+5602:0040785E48524A524A524A527A5E02407A5E4AD24B524A524852785E48520040
+5603:002007FE742055FC542457FE542455FC542055FC752455FC052409FC0924112C
+5604:010003F87A084BF84A084BF84A004BFE4A004BFE78424FFA0164065818460040
+5605:000007BE7488548857A854A854A857BE54105518749855A806AA044A00460080
+5606:01100110F7FE911091F0904093F8924893F89040F7FC90400FFE00A00110060C
+5607:00800110F3F8921094A49FBE904290A093189C46F19096640188063001C00E00
+5608:00A000A077FE50A057FC54A457FC54A457FC500073F8520803F8020803F80208
+5609:0100FFFE01003FF800001FF010101FF00820FFFE10007F7C11442144457C8244
+560A:002002227A224BFE48004BFE4A204BFC4A204BFE7A004A2005FC04200BFE0000
+560B:02080248E748A290A29EAFE4A114A214AFD4A494E914A1C80F08011405140222
+560C:00000FFEE0A0A7FCA4A4A4A4A7FCA000A7FCA000EFFEA0400248044409420080
+560D:004003F8F2489FFE924893F8904093F8924893F8F0809FFE011000E003180C04
+560E:07FC00807BF84A084BF84A084BF84A084BF84910797C4F800090006201B20E0E
+560F:100011DC11441144FD4411DC110011007DDC4514451445D445087D0845140122
+5610:000007BCF08494A4929494A490509188962690C0F31090640388003000C00700
+5611:0040007C78404BFE4A424A784BC44A3C4A084AF07B244AA805FE042008A00040
+5612:008803DE788849DC48884BDE488848004BFC4804780449FC0004000403FC0004
+5613:00000FFEE82AA826AFFEA822ABAAAAAAABAAA832E996AE2E084608820FFE0802
+5614:000003FE7A004A7C4A444A444A7C4A004AEE4AAA7AAA4AAA02EE020003FE0000
+5615:000007FCF040927892409FFE910091FC920093FCF00495540554080400280010
+5616:002003FE782049FC48204BFE480049FC490449FC790449FC010401FC00880104
+5617:111009207FFE50129FF4000020F03F0420041FFC00001FF810081FF810081FF8
+5618:0040007C78404BFE4A424A784BC44A3C4A004A507A544B5404D8045009FE0000
+5619:04100210E8FEA492A2FCA4A4ACA8A510A528A6C6E080AFFE0110032000E00718
+561A:0200027C7444597C5144527C56005AFC520853FE720852880248020802280210
+561B:00400020F7FE94909490949097FC949094D895B8F5B496D40892089010900090
+561C:004007FC7150515052E8544450E053585C46508071F8520804D0002000D00708
+561D:0204020477845494590C57C45564555457C45546757C57C405440544044408C4
+561E:0290029077D0529053BC511457D45554555457D4711457D40124012401540188
+561F:0200023EEF62A264A2A4AFE8A124A224A7A2ACA2F4A2A7B404A804A007A004A0
+5620:07FC0080F3F8920893F8920893F8920897FE94A2F89C97F00050002400D4030C
+5621:0020012478A84BFE4A0248F84888488848F84820782049FC0020002003FE0000
+5622:000007DE7542555457C85544557E57CA510A510877C85108010801C80E280410
+5623:00400444744457FC500057BC54A454A457BC54A474A457BC04A404A40AB41148
+5624:00000FBEE8A2AAAAAAAAAAAAA514A8A2A080AFFEE110A21003A0006001980E04
+5625:021002107450595C5150525056FE5A0052105250725C525002B00290030E0200
+5626:3FF820083FF8101020085FF404403FF824483FF80400FFFE08201E4003C03C38
+5627:00800040F7FE9402989490509524954A98FA9300F04094440444044407FC0004
+5628:0040004077FC50445FFE504457FC5040555454E4744457FC04E409540A4C1044
+5629:008803FE7888480049FC48A848A84BFE48A848A879FC482003FE002000200020
+562A:000003FE7A524A524BFE480049FC490449FC490479FC490401FC008801040202
+562B:0110011479D24A504A7E4D5048904AA8492849447A444C82000802A402520452
+562C:000003F8F20893F8920893F890009FFE948097BCF494979404D40F88009400A2
+562D:0104010477E85110510057C4500457C85450544277C25444028400E80F100420
+562E:008802AA7ADC4C8849544A2248004BFE4A424C447BFC48440044008401140208
+562F:004003F8F04897FE904893F890409554975C9444F7FC9444075C055405540844
+5630:024802487554575C52485554575C52485FFE52207228522805140494042C0844
+5631:000007FCF40497FC940095FC942095FC952495FCF42097FE062A06FA0A0A1206
+5632:0200023C0FA4E224A224AFBCA8A4AFA4A8A4AFBCA224E224AFA402240244028C
+5633:002001FC792449FC48204BFE480049FC490449FC790449FC010401FC00880104
+5634:00900294F2D8929292D2970E91F0921097FC9A44F3FC924403FC044404540808
+5635:0020002079FC48204BFE49084B9C490849884E3E78004BFE009000900112020E
+5636:04800482E49CAFD0A490A790A49EA794A494A494EFD4A014051408A410240044
+5637:004001FC790449FC490449FC490449FC4820492478A84924002003FE00200020
+5638:0080008079FE4B544D5449544BFE4954495449544FFE78004954012A022A0000
+5639:00400040F7FC90A09514920897FC9A0A93F89208F3F890400248044409440080
+563A:003803C0F08097FE9110920895F6991091F09000F7FC940405F4051405F4040C
+563B:004007FCF04093F8900093F8920893F891109FFEF00093F80208020803F80208
+563C:3E7C22443E7C00003FF821083FF821083FF80000FFFE00003FF820083FF82008
+563D:000003DE7A524A524BDE480049FC492449FC492479FC482003FE002000200020
+563E:000003FE78504BFE4A524BFE480049FC490449FC790449FC002003FE00200020
+563F:000007FCF444955494E4944497FC904097FC9040F0409FFE0000052404920892
+5640:000003DE7A524BDE4A104A5249CE480048884BFE7888488807FE008801040202
+5641:000007FEF0909090939C92049204939C90909090F7FE90400524050A090A00F8
+5642:01080090F7FE909093FC9294931C920493FC9204F3FC900807FE010800A80010
+5643:003C03E0792448A84BFE48A849244A0249FC4924792449FC0124012401FC0104
+5644:008003DE788A49CA488A4BD248A64840488849F078244BFE0022012402A20040
+5645:0004003EF7C09244912893F8920893FC920493FEF40296AA0AAA0A0210140008
+5646:000007BC7108552857BC531855AA5946500053F87208520803F80208020803F8
+5647:002001FC788848504BFE480049FC492449FC492479FC482001FC002003FE0000
+5648:04140212EF92A010A07EAF90A890A890AF90A228EB28AAA81228024A0A4A0486
+5649:00080788708851105FDE549454A4579454945794749454C807880C9400A400C2
+564A:000003FC784848304BFE485248944B5048204BFE7A524A8A0376025202720206
+564B:0208010877C85010579E549457A4501457945094711451C80708011405240242
+564C:02080110F00097FC9444955494E4944497FC9000F3F8920803F8020803F80208
+564D:01400120F3FE922096209BFC9220922093FC9220F22093FE0200052404920892
+564E:002003FE782049FC48004BFE4A0249FC480049FC790449FC0104008803FE0000
+564F:004000A0F11896E6900093F8920893F8900097BCF08494A4029404A402940108
+5650:00003E7C224422443E7C00003FFC010001007FFE00003E7C224422443E7C2244
+5651:0020004079FC490449FC490449FC4820492448A87924482003FE002000200020
+5652:0020012478A84BFE48A849244A224904490449DE7A444D54009E010402040404
+5653:0040007C78404BFE4A424A784BC44A3C4A004A507B544B5405DC04500BFE0000
+5654:002007A4F0A892929114920895F4980293F89208F20893F8020801100FFE0000
+5655:00F83F2009401FE010201FF010101FFC20042AA4400CBFF8200820083FF82008
+5656:00000FBEF208971C92089FBE904090A093189C46F02093F80008001000200040
+5657:00A004A4F2A890A097FC911090A097FC904093F8F04097FC00A0011002080C06
+5658:00000FFEE800AA28A948ABEEA892A884AAA0AAA8EBE8A8880894091409241242
+5659:004000A0F11092489DF690A0924892A893F89040F7FC9484052405F40414040C
+565A:000003FC78044BFC48044BFC48004BBC49244FBC78084BFE0108008800A80010
+565B:00200020793C492049204FFE480048204AAA4A227BFE4A7202AA022203FE0002
+565C:010003F0F4109FFC944497FC944497FC90009FFEF00093F8020803F8020803F8
+565D:01080108E214A294A4BCAF08A110A224A4BEAF8AE088A02C0AAA0ACA08280010
+565E:00400040F0A09110920895F6980097BC94A494A4F7BC92100210052809441082
+565F:010000803FFE224824FE2D9036FC249024FC249024FE24804FFC48048FFC0804
+5660:001004107A7C481048FE48444E284AFE4A104A7C7A104AFE0210021005FE0800
+5661:010001F87A084FFE4A884B244BFE4A004AFC4A007AFC4A0002FC048404FC0884
+5662:00800100F7FC94449554944497FC94E495549404F04097FE00A0011002080C06
+5663:000003F87AA84AA84BF849004BFC4C844BE44AA47AA44BE4009407F400140008
+5664:01100110F7BC911093B895549912900093F89000F7FC90400248044409420080
+5665:009003FC7A944BFC4A944BFC48004BFC4A004AF87A004BFE0520051405480986
+5666:0020013C79204FFE481048144BFE4A104BF04A547A544AD40368044A08960322
+5667:008800887BFE488849FC492449FC492449FC48207BFE4A22022A02FA020A0206
+5668:00003E7C224422443E7C01200110FFFE02800C603018C0063E7C224422443E7C
+5669:00007FFC01003D78254825483D7801007FFC01003D78254825483D780100FFFE
+566A:03F80208F20893F8900097BC94A494A497BC9040FFFE91600250044818460040
+566B:008000407BFC490848904FFE48004BFC4A044BFC7A044BFC00400524050A08FA
+566C:02100210F3DE95289884900097FC904092489248F248955408E200400FFE0000
+566D:0108020877C8545057DE546457D45214511457D4721453C802480454055408A2
+566E:000003FC7A944A944BFC48004FFE48004BFC4A047BFC48A2011403080D440182
+566F:003C03C070445224510857FE544252A4528A547A708050F8010802900060079E
+5670:0040002077FE50285224527E54C85748517E524874C8577E01480248047E0840
+5671:0040007C78404BFE4A424A784BC44A3C4A004BFE7A404BA4025805B4045209B0
+5672:004000A0F3189DF6900097FC955494E497FC9000F3F8920803F8020803F80208
+5673:0020003E78204BFE4A224BF84A224AFE4A844AFC7A004AFC022005FE04480986
+5674:002001FC782048884BFE488849FC490449FC490479FC490401FC008801040202
+5675:211017FE108003F8F20813F8120813F8120813F8280047FE00003FF820083FF8
+5676:008803FE788849FC490449FC490449FC488049FE7A224D52010201FA000A0004
+5677:021001107790503E54A253445F9050105790549077A854A804A807C400440082
+5678:0200023EE208BFD0A23EAAA2AAA2AABEAAA2AFBEE222A22202BE030002140022
+5679:00400248F15097FE9402980493F8920893F89000F7FC944407FC044407FC0404
+567A:0200010277DC50105450529057DE5114511457D4711455940554092405240244
+567B:00800040F7FE95129BFC911097FC911097FE9110F24895F40842004007FC0000
+567C:00100008778854BE548054945788547E5408578876BE5A880A880B8812880008
+567D:0800FF0008FE7E1000107E3042387E542492FF1000107E10421042007EFE4200
+567E:004000207BFE4A8A49444A2249FC48884BFE480079FC490401FC010401FC0104
+567F:03DE00427A52494A4A5248204BFE4888488849547A22482003FE002000200020
+5680:004000207BFE4A224954494A4A3A480049FC49547BFE480001FC002000A00040
+5681:000003DE78424A52494A4A52489049084BFE4D1079FE491001FE011001FE0100
+5682:001007D0751057DE545057E8550457C4500053F872A852A802A802A80FFE0000
+5683:040002FE7AAA48AA48FE48104E544A924A104A547A924A100210050008FE0000
+5684:008803FE78A8489049FE4B2049FC492049FC492079FE490003FC00880070038E
+5685:000007FCE040AFFEA842A358A040A358A000AFFEE040A7FC04A404A404A4040C
+5686:010807FEF108902097FE900091F8910891F89000F7FE940205FA050A05FA0406
+5687:01100110711057BC511051105FFE52A852A856EC7AAA52AA02A805A804480898
+5688:00000FFEE808ABC8AA4CABCAAA48ABDEA808ABC8EA48ABD40A540BD40A5412E2
+5689:02840284EAA4A6C4A29EAFE4A004A454A28CAFE4E104A7C4010401C40E140008
+568A:008003F8F20893F8920893F8900097FC944497FCF44497FC00000FFE01100210
+568B:004007FC704053FC500057FE500253F8504057FE700057FE000807FE04A80798
+568C:0080004077FC511050A45F58555455525B585000720853F8020803F802080408
+568D:004003F8704857FE504853F8504057FE500052A4745253F802A802A80FFE0000
+568E:004007FEF00091F8910891F8900097FE940293F8F180964401B8066801A60E60
+568F:004007FCF04097FE94029BFC924893F8924893F8F00097FC02440278054008FE
+5690:012400A87BFE4A8A48F8490C49F0490248FE480079FC490401FC010401FC0104
+5691:003C07C0F0409FFE904097FC955494E497FC9040F7FC90400FFE000005240892
+5692:0040002077FE548857DE548855DC56AA54885440748855F00420044809FC1084
+5693:0080004077FE54025A2453BC54A45AA8551052E874045BFA00400248044400C0
+5694:004007FC704057FE54025BFC524853F8524853F8710857FC02440278054008FE
+5695:010003F074105FFC544457FC544457FC5524589273F8520803F8020803F80208
+5696:008803DE788849DC48884BDE48884BFC480449FC78044BFC004002A4028A047A
+5697:03F80208F3F8920893F8911097FC91109FFE9110F248955400E00150024800C0
+5698:07FC0080E3F8A208A3F8A208AFFEA882A548A514E8F4A10003F8050800F00F0E
+5699:00200120793C49204FFE48904A944B6C4A044BFC7A944A94036C020403FC0004
+569A:00003E7C22443E7C00003FFC21003FF820083FF821003FFC00003E7C22443E7C
+569B:044404E4E8A8AAAAAEEEA4A4AAAAAEEEA242A040EFFEA0E0015002480C460040
+569C:01FC012479AC492449FC482049FC48204BFE49547A2A482001FC002003FE0000
+569D:0040002077FE548855FC548857FE542055FC552475FC552409FC088811040202
+569E:0100FFFE01007FFC00003FF820083FF81010FEFE10107C7C00007C7C44447C7C
+569F:00500190789E4BEA488A49D24A8A48A4485048887B2648A8007000A801240060
+56A0:020205E274A256AA552A566A510A528A544A5BAA710A57CA0122054201EA0E04
+56A1:05080508EFBEA508A708A208AFBEAA80AA88AF88E23EAF8802080208023E0200
+56A2:01007FFC11101FF00100FFFE94522FE844441FF004407FFC05081890EA600C18
+56A3:3EF822883EF80000FFFE01001FF01010111002C00C30700800003EF822883EF8
+56A4:002007FE748857DE548855DC56AA548C55F0542075FC542007FE082008A01040
+56A5:0110011077FC511051F0520852EA56AC52A852AA76EA5A06000002A402520452
+56A6:000007FE74445598548857DE548855DC56AA548874205520053C0920092017FE
+56A7:0040007C78404BFC4A444BF04A444AFC4AA84AF87AA84AF8020005FC05540BFE
+56A8:0210011077DE5010545E528257DE501057DE545077DE545007DE0450045204CE
+56A9:04140412E9FEAA10B2FEBC92A4FEA892B2FEBE92E20481FE2A442A242024000C
+56AA:03DE02527BDE4A524BDE4A424A7A4A8A4B124ADA7A8A4ADA028A02FA020A0204
+56AB:0400023CEFA4A024A8BCA524AFA4A23CA224AFA4E23CAB100A9812A80A2A0446
+56AC:0100013E750855D0553E55225FE2503E5122557E756255A208BE010002140C22
+56AD:0800FF7E08087E0800107E3442527E922410FF10007C7E44424442447E7C4244
+56AE:11002BDE4A5273D42A524BD27A1A12942350CA403FFC200427E4242427E4200C
+56AF:07FC0040F7FE94429B5C9040975C912093FC9620FBFC922003FC022003FE0200
+56B0:004000207BFE4A484BFE4A484AEC4B5A4A484BFE7A204A7C02C40344047C0844
+56B1:010801EC710A57E8552855DE572854EA540A57EA740C57EC0A2A0BEA115607E2
+56B2:200011DCFD5401547DDC44007DFC01247DFC092411FC1C20F3FE102050202020
+56B3:3AB821083AB82288393822887FFE400291041FF02100FFFE00001FF010101FF0
+56B4:3E7C22443E7C00003FFE20002E20223C3FA829482F2829282F1049D07F288144
+56B5:01F0021077FC520453FC522453B8522251FE521077FC524403FC00D0014A063E
+56B6:03DE02527BDE4A524BDE4A524BDE498C4A5248407FFE48880190006000D80304
+56B7:004007FCF00093B892A893B8911097FC911097FCF1109FFE012803100D480186
+56B8:00080FE8E928AB68A9AEA928AFE8A108AFE8A11EE112BFF200121552155E2012
+56B9:0408040EE788AA3EA22AA23CBFAAA226A220AABEEAA8ABBA0CAC005E00480098
+56BA:01FC095475FC5488505053FE5C4054A25534545875B45452059204500A2011FE
+56BB:00007BDE489249124BD24A527A5E03C07A5E4BD24A524A524BD2781E49920240
+56BC:003C07C07244512857FC54A457FC5008578854FE778854A80798050805A80690
+56BD:011007D0711E57A451545FD45208539454A25BFC720453FC020403FC01080204
+56BE:008803FE78884BDE4A524BDE48A0489049FE49207BFC4D2001FC012001FE0100
+56BF:010807FE712853FE522057FC5A2053FC522053FE7080531C0204039C020403FC
+56C0:02080208E27EAF88A23EAFAAAABEAFAAAABEAF8AE27EAF84027E02240214020C
+56C1:03FC010879F8490849F8490E4FF848084FFE4A947B9C4A94039C02D607BC0084
+56C2:3EF822883EF80000FFFE02001FF010101FF010101FF0082010103EF822883EF8
+56C3:04140212EFA0A53EA564AAA4A03EA224AFA4A23EEB24AAA412A4023E0A200420
+56C4:04180214EF90A53EAAA8ADE8A8BEAFA8A228AFBEEAA8AAA80BA808BE0AA00920
+56C5:0000EEFEAA82AA82EEFE00A4FEA492FEFEA492A4FEFE10A8FEAA112411321220
+56C6:008803FE788849FC492449FC49244BFE4A2A4AFA7A2649FC012401FC002203FE
+56C7:0FBE000077BC54A456B454A4504057FE54A057FC74A457FC051209DC091211CE
+56C8:010807FE71085390513C57D452B4555C5396512273FC500007FE0080010403FE
+56C9:000007FC74A454A457FC521052A854BE5F68523C74A85FBC00280AA80ABE0020
+56CA:01007FFC11101FF00100FFFE92921EF004403FF80440FFFE04880C503530C60E
+56CB:052807BE794857BE531855AA594653FC520453FC720453FC020403FC01080204
+56CC:01100FFEE510A400AF06B138AF88AA88AABEAF88EA9CAF9A0028154815480008
+56CD:10101010FEFE10107C7C00007C7C44447C7C2828FEFE00007C7C44447C7C4444
+56CE:00440E28EAFEAA92AED6AABAAAFEAE00AA7CAA44EE44A07C0A440944117C0044
+56CF:281029FEFE1028FC380010FC7C8454FC7C4811FE7C0010FCFE84288444FC8284
+56D0:010801ECE10AAFEAA928ABC8A93EAFE8A948ABE8EA28AB680AA80BF40AB412A2
+56D1:07FC040477FC552454A8552455FC555455FC564475F4555409F4084413F40008
+56D2:011007FE711057BC54A457BC54A457BC544457FC755455F4044404E405540448
+56D3:008003DE788A49D248A64BD0489C48504BFE48507AAA4BFE025202AA03FE0002
+56D4:004007FC724853F850405FFE5AAA53B8511057FC71104FFE012803100D480186
+56D5:0790051E77A8548457BE552A57BE500053F8520873F8520803F800A00124061C
+56D6:021007DEE928AFFEA912AFFEA228A444A9FEAF48E27EA5480F7E0048157E1540
+56D7:00007FFC4004400440044004400440044004400440044004400440047FFC4004
+56D8:00007FFC400440044FC44844484448444FC448044824482447E4400440144008
+56D9:00007FFC4004400440047F8440844084408440847F844084400440047FFC4004
+56DA:00007FFC4004410441044104410442844244444444244824502440047FFC4004
+56DB:000000007FFC444444444444444444444844483C5004600440047FFC40040000
+56DC:00007FFC400440044104410442044204444448245FF44814400440047FFC4004
+56DD:00007FFC400440044FE44044408441045FF4410441044104450442047FFC4004
+56DE:00003FF82008200827C82448244824482448244827C8200820083FF820080000
+56DF:0200020004007FFC40044824444442844104428444444824400440047FFC4004
+56E0:00007FFC40044104410441045FF441044284424444244814501440047FFC4004
+56E1:00007FFC4204420442047FFC444444444884468441044284444448247FFC4004
+56E2:00007FFC4004408440845FF4408441844284448448845084428441047FFC4004
+56E3:00007FFC4004408440845FF4408448844484448440844084428441047FFC4004
+56E4:00007FFC410441045FF44104492449244FE441144114411440F440047FFC4004
+56E5:00007FFC4004420441045FF44004400447C4444444444454483450047FFC4004
+56E6:00007FFC4004410441045D1445A445444924491451146504420440047FFC4004
+56E7:00007FFC40044444442448145014600447C4444444444444444444447FFC4004
+56E8:00007FFC40045FF440844104410443844544492451146114410441047FFC4004
+56E9:00007FFC400440044FE4400440045FF44204444448245FF4481440047FFC4004
+56EA:040008007FFC4004408448944514422445444884514442244C2440047FFC4004
+56EB:00007FFC4404440447F449544954525442944494491442A4444440047FFC4004
+56EC:00007FFC44444444444447C444444444444447C444444444444444447FFC4004
+56ED:00007FFC40044FE4400440045FF444844484448448944894507440047FFC4004
+56EE:00007FFC4504450449245944698449044F144914491448F4480440047FFC4004
+56EF:00007FFC400440045FF4410441044FE44104410441045FF4400440047FFC4004
+56F0:00007FFC4104410441045FF4410443844344452449145114410441047FFC4004
+56F1:040008007FFC4204420447F4481452244144408441444624580440047FFC4004
+56F2:00007FFC4444444444445FF44444444444447FFC44444444484450447FFC4004
+56F3:00007FFC40044104448442A45224484444444284410446C4583440047FFC4004
+56F4:00007FFC410441045FF441044FE441045FF4411441144154412441047FFC4004
+56F5:00007FFC41044104428444444824549C650446044424442443E440047FFC4004
+56F6:00007FFC400444444824511441044FE44104410441045FF4400440047FFC4004
+56F7:00007FFC400440E44F04410441045FF44304458449445124410440047FFC4004
+56F8:00007FFC400440045FF44104410449E44904490449045FF4400440047FFC4004
+56F9:00007FFC41044104428444444A24511C6FE4402440444284410440847FFC4004
+56FA:00007FFC410441045FF4410441044FE44824482448244FE4482440047FFC4004
+56FB:00007FFC40045FE4502450245FE451045FF4510450945454583440047FFC4004
+56FC:00007FFC42044204444448245FF440144FE4482448244FE4482440047FFC4004
+56FD:00007FFC400440045FF4410441044FE44104414441245FF4400440047FFC4004
+56FE:00007FFC4204420447E44C445284410446C4783C43044084460441847FFC4004
+56FF:00007FFC420442045FF444044FE4542467E4442447E4442444A444447FFC4004
+5700:7FFC400444444824521441045FF44404440447E44424482448A450447FFC4004
+5701:00007FFC41045FF440044FE440044FE440044FE448244FE4482440047FFC4004
+5702:00007FFC40044FE44204451459A442C444A459A4429444945A8441047FFC4004
+5703:00007FFC414441245FF441044FE449244FE449244FE44924496440047FFC4004
+5704:00007FFC40045FF442044FE444247FFC40044FE4482448244FE440047FFC4004
+5705:3FF00020064001807FFC444442845FF4410441047FFC4104410441047FFC4004
+5706:00007FFC40044FE448244FE440045FF45014511451145294444448247FFC4004
+5707:00007FFC4104428444444BA450144FE44AA44AA44FE44AA44AA448647FFC4004
+5708:00007FFC492445445FF442047FFC482457D4644C44C4442443E440047FFC4004
+5709:00007FFC410441044FE441045FF4444442844FE441045FF4410441047FFC4004
+570A:7FFC41044FE441044FE441047FFC40044FE448244FE448244FE4482448647FFC
+570B:00007FFC40A440947FFC40845E94529452A45EA4405446B4591440047FFC4004
+570C:00007FFC4104511451145FF440047FFC41045FF452945294503440047FFC4004
+570D:7FFC42044FE444245FFC40044FE448244FE441045FF4410451045FFC41047FFC
+570E:7FFC440448245FF440144FE448244FE448244FE448244FE4444448247FFC4004
+570F:00007FFC492445445FF442047FFC482457D4604C47C4442443E440047FFC4004
+5710:00007FFC40045FF4529452945FF441047FFC440447F44814505460247FFC4004
+5711:7FFC41245FF441044FE449244FE449244FE4492440445FF44844454440847FFC
+5712:00007FFC41044FE441045FF440044FE448244FE4411446A45A4442247FFC4004
+5713:7FFC40044FE448244FE440045FF450145FF450145FF450145FF4444448247FFC
+5714:7FFC41044FE441045FF4420444444FE440044FE44AA44AA45FF440047FFC4004
+5715:7FFC410441044FE441245FF441244FE441045FF448244FE448244FE440047FFC
+5716:7FFC40044FE448244FE441047FFC41045FF4501457D454545FF440047FFC4004
+5717:7FFC420444444FE441047FFC42045FF4545457D4545457D454545FF440047FFC
+5718:7FFC41045FF441044FE449244FE449244FE441145FF440445FF4484444C47FFC
+5719:00007FFC4444482457D441044FE44AA44BA44AA44BA44AA44FE440047FFC4004
+571A:7FFC41044FE449244FE441045FF448244FE448244FE448244FE4444448247FFC
+571B:7FFC40045FF452945FF441044FE441045FF4444442844FE441047FFC41047FFC
+571C:7FFC40045FF452945FF440047FFC40044FE448244FE445144CA4744446247FFC
+571D:0000FFFE800291129392A82ABBBA9012ABAAB83A8382AAAAABAA8002FFFE8002
+571E:FFFE9112A3A2B83A9392A82ABBBA8282ABAA8102BFFA854289229112FFFE8002
+571F:0100010001000100010001003FF80100010001000100010001000100FFFE0000
+5720:10801080108010801080FE80108010801080108016801884E0844084007C0000
+5721:0100010001000100010001003FF80100010001200110011001000100FFFE0000
+5722:1000100013FE10201020FE20102010201020102016201820E020402000A00040
+5723:00003FF0082004400280010006C01830E10E01001FF00100010001007FFC0000
+5724:10401040104010401040FE60105010481044104416401840E040404000400040
+5725:0100010001003FF8010001000100FFFE0440044004400440084408441044603C
+5726:12001100108010801040FC40104010A010A010A011101D10E208420804040802
+5727:00003FFE200020802080208020802FFC2080208020802080208040805FFE8000
+5728:020002000400FFFE080008401040304057FC904010401040104010401FFE1000
+5729:100011FC102010201020FC20102013FE1020102010201C20E020402000A00040
+572A:10401040108010FE1100FE0010FC10081010102010401C80E102410200FE0000
+572B:1008103C13C010401040FE401040107E13C0104016401842E0424042003E0000
+572C:200021FC200020002000FBFE20802080210021FC20043804E004400400280010
+572D:010001003FF8010001000100FFFE0000010001003FF8010001000100FFFE0000
+572E:1000100011F810081008FC08100811F81108110011001D00E102410200FE0000
+572F:100011FC110411041104FD04110411FC1100110011001D00E102410200FE0000
+5730:1020102010201120112CFD34116413A41124113411281D22E122410200FE0000
+5731:00200C2070201020102011FC1020FE201020102010201020202023FE40008000
+5732:1008103C11E010201020FC20102013FE1020102010201C20E020402000200020
+5733:11041124112411241124FD24112411241124112411241D24E124422402040404
+5734:10401040108010FC1104FD04120414841044102410241C04E004400400280010
+5735:10401040104010401040FE40107C10401040104016401840E040404007FE0000
+5736:010001007FFC0280044008203118C10601003FF80100010001000100FFFE0000
+5737:100013FE104010401040FE40105010481044104416401840E040404000400040
+5738:10201020102010201124FD24112411241124112411241D24E12441FC00040000
+5739:10401020102013FE1200FE0012001200120012001E00E2004200040004000800
+573A:200023F0202020402080F90023FC21242124212422243A44E444488401280210
+573B:1008101C11E011001100FD0011FE11101110111011101D10E110421002100410
+573C:00003FF8200820083FF8200820083FF8010001003FF8010001000100FFFE0000
+573D:11001100110011FC12A4FCA410A41124112412441C44E0844104020404280010
+573E:100017F8110811101110FD20113C1104110412881E88E2504420045008880306
+573F:10201020105010501088FD04120210881088108810881C88E088410801080208
+5740:10201020102011201120FD20113C11201120112011201D20E120412007FE0000
+5741:1004101E11F011101110FD10111011FE1110111011101D08E10A414A01860102
+5742:1008101C11E011001100FDFC114411441144112811281D10E110422802440482
+5743:1000100011FC10001000FC0013FE10901090109010901C90E1124112020E0400
+5744:200021F0211021102110FA0E240023F821082110209038A0E04040A003180C06
+5745:10201020105010501088FD4412221020100011FC10041C08E008401000100020
+5746:104010401040108010FEFD08128810881088105010501C20E050408801040202
+5747:10401040108010FC1104FE04108410441044101410241C44E184400400280010
+5748:1000100013FC12041408FC0011F011101110111011101D12E2124212040E0800
+5749:10201020102013FE1020FD2411241124112411FC10241C20E0224022001E0000
+574A:10401020102013FE1080FC80108010FC1084108410841C84E104410402280410
+574B:10101090109010881108FD04120415FA1088108810881C88E108410802280410
+574C:0440082010102FE8C4260420082010A0614001003FF8010001000100FFFE0000
+574D:100011F8110811081148FD281128110817FE110811081D08E108420802280410
+574E:10801080108010FC1104FD0812401440104010A010A01D10E110420804040802
+574F:1000100013FE10101010FC2010201068106410A41D22E2224420002000200020
+5750:01001110111011101110292825244544810001003FF8010001000100FFFE0000
+5751:10801040104013FC1000FC0011F011101110111011101D12E1124212020E0400
+5752:2080208820B03EC0208020842684387C210001003FF8010001000100FFFE0000
+5753:0820082008207FFC08200820FFFE10202020412001003FF801000100FFFE0000
+5754:010001047D880550092011102108C5060200010001003FF801000100FFFE0000
+5755:00781FA01120112011201110211021084004010001003FF801000100FFFE0000
+5756:00003FF800000000FFFE044004420842303EC10001003FF801000100FFFE0000
+5757:10401040104013FC1044FC441044104413FE104010A01CA0E110420804040802
+5758:100017FE108010801080FCF8110811081108120813F81C10E010401007FE0000
+5759:00007FFE0888088811102220111008880888010001003FF801000100FFFE0000
+575A:040025FC2504248824502420245825860400010001003FF801000100FFFE0000
+575B:1000100011FC10001000FC0013FE10201020104010401C88E10443FE01020000
+575C:200023FE220022202220FA2022FC22242224222422443A44E484448409281210
+575D:100011FC110411041124FD24112411241124112411241C50E048408401020602
+575E:1020104011FC11041104FD0411141108110011FE10021C02E3FA400200140008
+575F:10801040104017FC1110FD1011101110111010A010A01C40E0A0411002080C06
+5760:00407C404440484044A044A0551049084204450201003FF801000100FFFE0000
+5761:20202020202023FE2222FA24222023FC2284228822483A50E220445004880906
+5762:10201020112410A410A8FC2011FC10201020102013FE1C20E020402000200020
+5763:01001110092001007FFE40028104010001003FF80100010001000100FFFE0000
+5764:10201020102011FC1124FD24112411FC1124112411241DFCE124402000200020
+5765:100011F8110811081108FDF811081108110811F811081D08E108410807FE0000
+5766:1000100011FC11041104FD0411FC11041104110411FC1D04E000400003FE0000
+5767:1000100013FE10201020FC40104010FC1184128414841C84E084408400FC0084
+5768:10401020102013FE1202FC04110011081110112011C01D02E102410200FE0000
+5769:110811081108110817FEFD0811081108110811F811081D08E108410801F80108
+576A:100011FC102010201124FCA410A8102013FE102010201C20E020402000200020
+576B:1020102010201020103EFC201020102011FC110411041D04E104410401FC0104
+576C:2008203C23D022902290FA90229022902290228822883AC8E2A444D404920800
+576D:100011FC110411041104FDFC110011401144114811701D40E1424242023E0400
+576E:10201020104010401088FD0413FE1002100011FC11041D04E104410401FC0104
+576F:100013FC102010201040FE4010D011481244144416401840E040400007FE0000
+5770:100011FE110211021102FD7A114A114A114A114A117A1D4AE1024102010A0104
+5771:10201020102011FC1124FD2411241124112413FE10201C50E050408801040202
+5772:10901090109013FC1094FC9413FC1290129013FE10921C92E11A411402100410
+5773:202021202120222022FCF4A4272421242224222424A437A4E0C4404400940108
+5774:010001003FF801000100FFFE08201010210841043FF8010001000100FFFE0000
+5775:1008101C11E011001100FD00110011FE1110111011101D10E110411007FE0000
+5776:200021F8210821482128F908210827FE2208228822483A08E3FE400800500020
+5777:2000200027FE20082008FBC8224822482248224823C83A48E008400800280010
+5778:10801080110011FC1204FC0411E411241124112411E41D24E004400400280010
+5779:10401020102013FE1202FC04100010901090109010881D08E108410402040402
+577A:105010481048104013FEFC80108010FC1144114411281D28E210422804440182
+577B:1008103C13E012201220FE20122013FE1220121012101E12E20A428A03260212
+577C:1008101C11E011001100FD0011FE11101110113011181D14E112421002100410
+577D:10201020105010501088FD241212101011FC100410081C88E050402000100010
+577E:10401020102013FE1202FC041000100013FE102010201C20E020402000A00040
+577F:2088208820882108217EFB08250821482128212821083908E108410801280110
+5780:1008103C13E010201124FCA410A8102013FE102010201C20E020402000A00040
+5781:10401040108010FC1120FE201020102013FE102010501C50E088408801040202
+5782:001000F83F00010001007FFC09200920FFFE092009207FFC010001003FF80000
+5783:108010401040100013FCFC00100811081108109010901C90E0A0402007FE0000
+5784:04400420FFFE0910112011C023044D0480FC010001003FF801000100FFFE0000
+5785:109010881088108013FEFCA010A010A410A410A811281D32E1224262029E0400
+5786:20402040207E20402040FBFC22042204220423FC22043A00E200440004000800
+5787:2000200023DE22522252FA52225222522272220222023A02E20243FE02020000
+5788:089008881080309E57E0908010441034110C01003FF8010001000100FFFE0000
+5789:1080108011FC11041204FDF411141114111411F411041D28E112410200FE0000
+578A:200023FC220422042204FBFC2220222023FE222022203A10E212428A03060202
+578B:00047F84122412241224FFA4122422042214410881003FF801000100FFFE0000
+578C:200023FE2202220222FAFA02220222FA228A228A228A3AFAE2024202020A0204
+578D:10201020104011FC1104FD04110411FC1104110411FC1D04E104410401FC0104
+578E:2080208021F822082510F8A0204020A023182C0623F83A08E208420803F80208
+578F:1020102011FC102413FEFC2411FC1020102011FC10201C20E3FE402000200020
+5790:4080208009FC12042448E04020A023182C06010001003FF801000100FFFE0000
+5791:2040204020FC21082290F86020482190263E204220843B48E030402000C00700
+5792:0400082010103FF80810102024487EFC0204010001003FF801000100FFFE0000
+5793:20402020202027FE2040F884210823F0202220443988E6104020005001880604
+5794:00007FFC044004403FF8244824483FF8010001003FF8010001000100FFFE0000
+5795:007C3F8020003FFE20002FF8280828082FF8208020802FFC40804080BFFE0000
+5796:1040108011F811081108FD0811F811001100110011FC1D04E104410401FC0104
+5797:10901090109012921194FC98109011981294149210901C90E11241120212040E
+5798:10901094109211121110FF7E151011101110112811281D28E128414401440182
+5799:10201020112410A410A8FC2013FE10901090109010901C92E1124112020E0400
+579A:010001003FF8010001000100FFFE1010101010107CFC101010101E10F0FE4000
+579B:100011F0111011101110FD10124E144013FC10401CE0E1504248044600400040
+579C:100013F81088109010BCFD0411141248104017FE10401CE0E150424804460040
+579D:1040104010FC11041208FDFE1100117C1144114411541D48E1424242023E0400
+579E:2040202023FE22022000F83823C020402040207C23C03840E0424042003E0000
+579F:110410841088100013FEFC20102011FC1020102013FE1C20E020402000200020
+57A0:100011F81108110811F8FD08110811F81144114811301D20E110414801860100
+57A1:08A00890108030FC57809048105010241054118C160401003FF801000100FFFE
+57A2:1008101C11E011001100FDFE11001100117C114411441D44E144427C02440400
+57A3:100013FE1000100011FCFD04110411FC1104110411FC1D04E000400003FE0000
+57A4:200027FE204020802110FA0827FC20442040204027FC3840E04040400FFE0000
+57A5:2040204020A02110FA08240623F82000200023F822083A08E208420803F80208
+57A6:00003FF020103FF020103FF0220821902C60311C01003FF801000100FFFE0000
+57A7:20402040208023FC2204FA0422F422942294229422943AF4E204420402140208
+57A8:1040102013FE12021414FC10101013FE1010111010901C90E010401000500020
+57A9:00007FFC04402448144814500440FFFE0000010001003FF801000100FFFE0000
+57AA:110410841088100011FEFC8810881088108813FE10881C88E108410802080408
+57AB:084008407DF808480C4819C8684A08AA2886110201003FF801000100FFFE0000
+57AC:108810881088108811FEFC8810881088108813FE10001C88E084410402020402
+57AD:200023FC209020902090F892249222942294229820903890E090409007FE0000
+57AE:2040204027FC20A02110FA082DF6200027FC208021003BF8E008400800500020
+57AF:101012101110111010FEFC10131011281124114411421D82E1004280047E0000
+57B0:10201020103E10201020FDFE1000100011FE102010281C24E022402000200020
+57B1:1020112410A410A410A8FC2013FC10041004100411FC1C04E004400403FC0004
+57B2:102011241124112411FCFC0011FC1004100411FC11001D00E102410200FE0000
+57B3:20802080213C22002480F880217E23082508210821083908E108410801280110
+57B4:20402020202027FE2000F800209022542224222422543A94E204420403FC0004
+57B5:10401020102013FE1202FC44104013FE1088108811081CD0E020405000880304
+57B6:1040102011FC10001088FC5013FE10201020102011FC1C20E020402000200020
+57B7:100013F81208120813F8FE08120813F81208120813F81D20E12042220422181E
+57B8:1040102013FE12021404FDF81000100013FE109010901C90E1124112020E0400
+57B9:2100211E21122FD22114F91427D8211421122FD22112391AE214421004100810
+57BA:1008103C11C010041144FCA8100011F81010102013FE1C20E020402000A00040
+57BB:100011FC1104110411FCFD04110411FC1104110411FC1C00E088408401020202
+57BC:10F8208841088A06100031F850889050102010D8170601003FF801000100FFFE
+57BD:200C11F08100490009FE1110E11022102210251001003FF801000100FFFE0000
+57BE:100011FC110411FC1104FDFC1000100011FC10201C20E3FE4020002000200020
+57BF:2040202023FE22002200FAFE22042228221023FE3A12E2144210041004500820
+57C0:00F83F000100FFFE01000924F93809223922C91E01003FF801000100FFFE0000
+57C1:102011241124112411FCFC20105010881144122210201DF8E008401000100020
+57C2:100013FE1020102011FCFD24112411FC1124112411FC1D20E0A0404000B0030E
+57C3:204020802110220827FCF904210023F82440204027FE3840E0A0411002080C06
+57C4:210021F8230824902060F9982646204023F8204023F83840E7FC404000400040
+57C5:004078204BFE508048F84488550849284210410001003FF801000100FFFE0000
+57C6:1080108010F811081210FDFC1124112411FC112411241DFCE124422402140408
+57C7:100011F8100810D01020FDFC1124112411FC112411241DFCE12441240124010C
+57C8:104010401088110413FEFC0210881144124210F81D88E2504020005001880606
+57C9:10201020102013FE1020FC2011241124112412AA10201C50E050408801040202
+57CA:0100210821083FF8000001047D88095011202518C20601003FF801000100FFFE
+57CB:100011FC1124112411FCFD24112411FC1020102011FC1C20E020402003FE0000
+57CC:1040102011FC11041104FDFC1104110411FC112011221D14E108414401820100
+57CD:100010FC1084108410FCFC0011FE1102110211FE11021D02E1FE4102010A0104
+57CE:20282024202027FE2420FC20242427A424A424A824A83C90E692492A08461082
+57CF:2008201C277021102110FA50225C27502150255025503A7CE200450008FE1000
+57D0:100011FC100410FC1004FDFC100013FE120211F810881C88E050402000D80306
+57D1:080C08F07E8008800EFE7888088829081208010001003FF801000100FFFE0000
+57D2:1008103C13C010441224FD281100101013FE101011101C90E090401000500020
+57D3:1008103C13C011241098FC601390101013FE101011101C90E090401000500020
+57D4:2048204427FE20402040FBFC2244224423FC224422443BFCE244424402540208
+57D5:100011FC110411041104FDFC1000100013FE102010201DFCE020402003FE0000
+57D6:2108210827FE21082108F800209020922114231825103932E1524112010E0100
+57D7:101010101090109E1090FC9013FE10001010109210921D14E208401000600380
+57D8:200820082788248824FEFC88248827C824A824A824883C88E788448800280010
+57D9:200023F82208220823F8F800200027FC2404244424443C44E4B4410806041802
+57DA:200023F8220822082208FBF82040204027FC244424A43D14E614440404140408
+57DB:200027FC240424A42514FE0C240425F42514251425143DF4E514440404140408
+57DC:082008207EFC08301C682AA4C9220820092001003FF8010001000100FFFE0000
+57DD:20202020205020882144FA2221F820082050202020A43A82E28A428A04780000
+57DE:1040102013FE12021404FC0013FE102010201120113C1D20E2A04260043E0800
+57DF:20142012201027FE2010F81023D222522252225423D43808E0EA471A02260042
+57E0:1020104011FC110411FCFD0011FC110411FC10201C20E3FE4020002000200020
+57E1:200027FE209020902090FB9C220422042204239C20903890E090409007FE0000
+57E2:204022482150204023F8F88027FC2110220825F429123910E1504124010400FC
+57E3:1040102013FE10001088FC88115412221000102013FE1C20E020402000200020
+57E4:2040208023FC22242224FBFC2224224423FC20903910E7FE4010001000100010
+57E5:1020102013FE102011FCFC2013FE100011FC110411FC1D04E1FC410401140108
+57E6:2040202023FE22022504F90021DE225222522352249A3894E11041120212040E
+57E7:100011F81108110811F8FD0811F8110811F811081D08E3FE4000009001080204
+57E8:2040204020A021102208FDF6200027FC24A424A427FC3CA4E4A444A404140408
+57E9:1080108011F811081210FDFC1024102413FE102410241DFCE024402000A00040
+57EA:10401020102013FE1202FC9411081204100011FC10201C20E020402007FE0000
+57EB:2020212420A420A82020FBFE2202220222FA228A228A3A8AE2FA4202020A0204
+57EC:2040204027FC204023F8FA4823F8224823F8204020E03950E2484C4600400040
+57ED:2040204023F82048F84827FE2048204823F8244422E83950E248444601400080
+57EE:10201122112212241050FC8813041022102011241D24E2284050008801040602
+57EF:2040208027FE21102248FC4623F82248224823F822483A48E3F840420042003E
+57F0:1008103C13C010441224FD281100102013FE107010A81CA8E124422204200020
+57F1:2100210021DC2114F114211427D42014211421143588E5484948011405140222
+57F2:1020102013FE102011FCFC4013FE10881124122210F81C20E3FE402000200020
+57F3:2080208020F82108FA1024002040239C22042204239C3A04E204420403FC0204
+57F4:2040204027FC20402040FBF8220823F8220823F822083BF8E20842080FFE0000
+57F5:2008203C21E020202020FBFE2124212427FE212421243BFEE020402003FE0000
+57F6:104010407C40104011F8FE480048454892C810487C68105A108A1C8AE1064202
+57F7:104010407C4011F81048FE48444829487CC8104810A8FEA8108A110A11061202
+57F8:100011FC110411FC1104FDFC1080108011FE124A144A1C92E122424200940108
+57F9:1040102011FC10001108FC90100013FE1000100011FC1D04E104410401FC0104
+57FA:082008207FFC08200FE008200FE00820FFFE082011102108CFE6010001003FF8
+57FB:1040102013FE100011FCFD0411FC100011FC10081C10E3FE4020002000A00040
+57FC:2040204023FC20A02110FA0827FE200823C8224822483A48E3C8400800280010
+57FD:200023F8200821F82008FBF8200027FE2442284423F83A48E248424802580040
+57FE:00007F7C22443E4422283E1023A8FE440282010001003FF801000100FFFE0000
+57FF:23F8120882084BF80A401248E27022442444253C09003FF801000100FFFE0000
+5800:100013FE1202120213FEFE1012921292129212FE12101E92E292449204FE0802
+5801:100011FC1124112411FCFD24112411FC102013FE10701CA8E124422200200020
+5802:0100111009207FFE40029FF4101010101FF0010001003FF801000100FFFE0000
+5803:102008107EFE10201E3C1224122422444A94850801003FF801000100FFFE0000
+5804:20002040239C22042204FB9C2204220423FC209020903890E09041120212040E
+5805:7F7C48447F44414841287F30481048287F44008201003FF801000100FFFE0000
+5806:21402120212023FE2220FE202BFC2220222023FC22203A20E22043FE02000200
+5807:08200820FFFE08200FE001003FF821083FF801007FFC01003FF80100FFFE0000
+5808:200023FE2202228A2252FBFE2222222222AA22AA22AA3AFAE2024202020A0204
+5809:2040202023FE20802104FBFE200221FC210421FC210439FCE104410401140108
+580A:00007FFC04403C78200820083C780440FFFE010001003FF801000100FFFE0000
+580B:200023DE225222522252FBDE22522252225223DE22523A52E2524252055208A6
+580C:200027FC2444244427FCFC44244425F42514251425143DF4E514440407FC0404
+580D:2100210021F02210FA2027FC2A442244224423FC22A438B0E128422A0422081E
+580E:2020202021FC20202020FBFE20882144224220F821883A50E020405001880606
+580F:0820081009FE7E40187C2C442A8448948908080001003FF801000100FFFE0000
+5810:100013FE1210121012FEFE10121013FE1200121012101EFEE210441005FE0800
+5811:100CFEF0208048807EFE08880E88F9084A08090801003FF801000100FFFE0000
+5812:100011FC1104110411FCFD04110411FC1000111211D41D18E11041520192010E
+5813:102011241124112411FCFC0011FE1100117C111011101DFEE110421002100410
+5814:100013FE120212521088FD041020102013FE102010701CA8E124422200200020
+5815:00207BFE484048FC51844AFC488468FC5084418C01003FF801000100FFFE0000
+5816:21242248249022482124F880210027FC2404251424A43C44E4A4451407FC0404
+5817:1040102013FE12021088FD0412221028102413FE10201C50E050408801040202
+5818:204022482150204023F8F88027FC2110224824443842E3F84040004007FC0000
+5819:200027FC20A020A027FCFCA424A424A427FC20403840E7FC404000400FFE0000
+581A:100013FE1222102013FEFC2011FC112411FC112411FC1C20E3FE402000200020
+581B:200023FE200021FC2104F90421FC200023FE222222223BFEE222422203FE0202
+581C:1020102013FE102011FCFD2411AC1174112411FC10201C70E0A8412402220020
+581D:100011FC1104110411E4FD24112413FE120212FA1E8AE28A42FA0202020A0204
+581E:20902290229027FE2290FA9022F0220023FC204027FE38E0E15042480C460040
+581F:208020FC210421F82008FBFE204020A22334205820943B34E052409003500020
+5820:2100217821082208FAFE26402A40227C2290221022FE3A10E228422802440282
+5821:08000BF8120833F8504097FC115012481446114001003FF801000100FFFE0000
+5822:2100217C21442244FA44267C2A10221022FE223822543A54E294431202100210
+5823:11FC1124112411FC1124FD2411FC1020102013FE12221E2AE2FA420A02020206
+5824:100011FC1104110411FCFD04110411FC100013FE10201D20E13C412002A0047E
+5825:00407F40127E0C88FF4819482A504820A850118C01003FF801000100FFFE0000
+5826:1110111211D411181152FD92112E104011FC110411041DFCE104410401FC0104
+5827:100013FE1020104011FCFD54115411541154112C1C20E3FE4050008801040202
+5828:100011FC110411FC1104FDFC108011FE1222112211521D02E1FA400200140008
+5829:2100213C21002100F9BC25642524253C252421242124393CE1244100017E0100
+582A:1088108813FE108810F8FC8810F81088108813FE11001D48E184410001FE0000
+582B:20002088225222222252FA8A220223FE20882144227A3888E150402000D80706
+582C:204020A02110220825F6F80023C42254225423D422543A54E3D44244025402C8
+582D:1020104011FC110411FCFD0411FC100013FE102010201DFCE020402003FE0000
+582E:100013DE1252125213DEFC0011FC100013FE108011001DFCE004400400280010
+582F:010001003FF80100FFFE08203EF808200E2078FC0000FFFE044008421042603E
+5830:200023FE220022FC2284FAFC228422FC222023FE22483AC8E2304248028403FE
+5831:100010FC7C8410841094FE88448028FC7CA410A410A8FEA8109010A810C41082
+5832:7E7C42447E4442447E44484444545A486240404001003FF801000100FFFE0000
+5833:200023FC2224222423FCFA0022FC2284228422FC22843AFCE484448408FC1084
+5834:200023F8220823F82208FBF820002FFE220023FC24943924E244448401280210
+5835:2040204423F42048F85027FE2040208021F82B08350821F8C108010801F80108
+5836:2040204023FE208021FCFA2025FE200021FC210421FC3904E1FC410401140108
+5837:2080204027FC20002208F9102FFE200023F8220822083BF8E208420803F80208
+5838:20002FF828082868FB88288828882BE82AA82AA83BE8E88A48AA10EA17262002
+5839:1008103C11E0102013FEFC2011FC112411FC112411FC1C20E1FC402003FE0000
+583A:23F82248224823F82248FA4823F820A02110220825163910E110411002100410
+583B:204013F890484FFE404813F82040E3FC20402FFE2040204001003FF80100FFFE
+583C:080808087E0808FEFE0808487E2808080F28F01001003FF801000100FFFE0000
+583D:100013FE1252125213FEFC00100013FE10201020113C1D20E120412007FE0000
+583E:2040204027FC204023F8F88027FE2110220827FC3A0AE20843F80208020803F8
+583F:20142012201027FE2410FC1025D02412241225D425543D48E5DA442A08461082
+5840:200023FC2204220423FCFA002284224822FC224822483BFEE448444808881108
+5841:3FF821083FF821083FF8600C183006C01830610C01003FF801000100FFFE0000
+5842:2110211027FC2110F1102FFE2110220827F42A123210E3F04204020401FC0000
+5843:2108210827FE2148F82027FE2200220023FC200022483A48E248444A044A0846
+5844:200023FC229422942294FBFC2080204027FE208020F83888E108410802280410
+5845:208023382228222823A8FA462200227C23A4222422283BA8E610422802440282
+5846:2080204027FE2090FA942492200023F8200823F822003BFCE004400400280010
+5847:1040102013FE12021404FDFC100011FC110411FC11041DFCE104400003FE0000
+5848:00007DFC44207D2045FE7C5048525492650E01003FF8010001000100FFFE0000
+5849:204022482150224824A4F918260623F8220823F822083BF8E208420802280210
+584A:2020204023FC22242224FBFC2224224423FC204020A838B4E13C41220222041E
+584B:08202AA42CA84920145022887FFE4002810401003FF8010001000100FFFE0000
+584C:200023F8220823F82208FBF82000200027BC208424A43A94E4A4408402940108
+584D:0020792448A8482049FC78404BFE488849247A224C2049FC482048204BFE9800
+584E:1040102013FE12021050FC88112410501088110412FA1C88E088408800F80088
+584F:102011241124112411FCFC0013FE100011FC110411041DFCE088405003FE0000
+5850:1020102013FE102011FCFC2013FE1040108811F01C24E3FE4022012402A20040
+5851:2200147CFF44087C4944497C7F4408441094210841003FF801000100FFFE0000
+5852:201020102710257C2510F51025FE2708250825FE25083548E728400800280010
+5853:100013FE1202100011FCFD0411FC110411FC10401C20E3FE4000008801040202
+5854:2110211027FC21102040F8A02110220825F6200020003BF8E208420803F80208
+5855:21202110220824862910FBF82008200027BC208424A43A94E4A4408402940108
+5856:203823C0204027FC2150F954275821542354254C20E03950E248444408420040
+5857:204010A0911042084DF6104027FCE040224824442942208001003FF80100FFFE
+5858:2040202027FE242025FCFC2427FE242425FC242025FC3D04E504490409FC1104
+5859:1040102013FE100011FCFD0411FC100013FE12021EFAE28A42FA0202020A0204
+585A:200027FE2402280427FEF8802184224426A821303AF0E4A8412802240CA20040
+585B:200027FC20A020A027FCFCA424A427FC2040204027FC38E0E15042480C460040
+585C:200027FE240229F42000FBF820802144266820B03928E66840A4012206A00040
+585D:2040202023FC21082090FBFE22022444202023FC208038F8E088410801280210
+585E:020001007FFE44429FF404403FF80440FFFE082011102108DFF6010001007FFC
+585F:0820FFFE082000007FFC08401F48625014621842E03E01003FF801000100FFFE
+5860:2010242022F82288F88820F82E80228022FC228422843AFCE284450008FE0000
+5861:111811E2110210FE1000FCFC128412FC128412FC12841EFCE20043FE01080204
+5862:1040108011FC11041104FDFC110011FE110011FE1C02E2AA42AA040200140008
+5863:200013F8920842084BF8080017FCE04023F8204027FC01003FF801000100FFFE
+5864:100011F81108110811F8FC0013FC120413FC120413FC1E04E3FC409001080204
+5865:200023FE200021FC2104F90421FC200023FE228A22523BFEE2224222022A0204
+5866:7C2045FE482051FC492445FC452455FC482043FE402001003FF801000100FFFE
+5867:220821082110200027FCF80021102208240423F822A83AA8E2A842A80FFE0000
+5868:2090209023FC20902090F89027FE209021482244244A3954E14A424A01400080
+5869:2100210021FE220025F8F908210821F8200023FC22943A94E294429407FE0000
+586A:101E11E0102211121094FC80102011CE1102110211CE1D02E102410201FE0102
+586B:2040204027FC204023F8FA0823F8220823F8220823F83A08EFFE411002080404
+586C:200027FE2420244025FCFD0425FC250425FC25243C20E4A849240A2210A00040
+586D:100011F81108110811F8FD08110811F8100013FC12941E94E294429407FE0000
+586E:2084210423C4224423DEFA4423C42264225427D420C43944E244444401540088
+586F:204023BE221222922252FAAA2324204023FE222222223BFEE222422203FE0202
+5870:210011FC920045F84148112823FEE148222823FC205001203FF801000100FFFE
+5871:10007E7C42447E7C42447E7C484444445A94610801003FF801000100FFFE0000
+5872:210021FC220025F82108F9F8210821F8200027FE21003BFCE4A4412402540088
+5873:2020247C228421482030F8CE2610227C2210227C22103AFEE210421005FE0800
+5874:20202222222223FE2000FBDE2252225223DE225222523BDEE2524252055A08A4
+5875:010000803FFE22203FFC22243FFC28402F7828422F3E20802FF840807FFE8000
+5876:2040202023FE22502250FBFE2252225223FE220022923AD4E298449204D2088E
+5877:20202020203E20202020FBFE22022326228A225223263A52E28A432603FE0202
+5878:200023FE2200227C2244FA44227C220022EE22AA22AA3AAAE2EE420003FE0000
+5879:08047F7808407F40497E7F4849487F4808487F48088801003FF801000100FFFE
+587A:010000803FFE221022102FBC231826B42A52208020802FFC408040809FFE0000
+587B:1088108813FE10881000FDFC110411FC110411FC1C20E3FE4050008801040202
+587C:102013FE102011FC1124FDFC112411FC102213FE1C08E3FE4108008800280010
+587D:2040204027FC20402554FA482554204025542248255438A0E0A0411002080C06
+587E:1040FE4000407DF844487C4800C87C4808AAFEAA1106520221003FF80100FFFE
+587F:102011FC112413FE1124FDFC102011FC112411FC1C40E3FE408801D00070038C
+5880:200027FC240427FC2420FCA8247024A8250424A03CFCE52044200BFE08201020
+5881:23F8220823F8220823F8F80027FC24A424A427FC20003BF8E11040E003180C06
+5882:100013FE105011FC1154FD5411FC100011FC100013FE1C20E0A8412402A20040
+5883:2080204023F82110F8A027FE200023F8220823F822083BF8E120412202220C1E
+5884:20142012201027FE2410FC9024D2249227F224943C94E5C84AAA089A11A60042
+5885:7F7C49047F2849107F7E08127F1408100F50F02001003FF801000100FFFE0000
+5886:22A822A827FC22A8FAAA24E6280027FC2444204023F83A48E248424802580040
+5887:102011FC1088105013FEFC0011FC110411FC110411FC1C20E3FE402000200020
+5888:224822482FE8224823DEF24A23CA224A224A2FEA240A354AE632441207EA0044
+5889:202027FE242025FCF42427FE242425FC242025FC3524E5FC452409FC0924112C
+588A:08207E2008F8FF2814287F6A082AFF560882010001003FF801000100FFFE0000
+588B:2040208821FC21082252FBFE20502188262620C023103864E388403000C00700
+588C:2040202023FE22002248FA4823FE2248224822483A78E2004554052A0A2A1000
+588D:10007EFC42107E9042907EFE001040287E2840484C8A710601003FF80100FFFE
+588E:2200211E27D2201227D4FC5427D8201427D22092211239DAE714411005100210
+588F:0420247E24943D48043005C87C0825FE24882448441881003FF801000100FFFE
+5890:1088108813FE108810F8FC2011FC112411FC102013FE1C20E1FC402003FE0000
+5891:2040202023FE20882050FBFE222222FA222222FA228A3A8AE2FA4202020A0204
+5892:2040202023FE20882050FBFE2252228A230622FA228A3A8AE2FA4202020A0204
+5893:04407FFC04401FF010101FF010101FF00400FFFE10102108CFE6010001003FF8
+5894:1020122213FE10901088FDFE1310151011FE111011101DFEE110411001FE0100
+5895:200027FC20402278F2402FFE210021FC220023FC3004E5544554080400280010
+5896:204020A0211022082DF6F00023F8220823F8200027FC3444E7FC444407FC0404
+5897:21042088200023FE2222FBFE2222222223FE200021FC3904E1FC410401FC0104
+5898:2110211021102FDEF12027C0245C27C4244827C83110EFD041220122011E0100
+5899:2040204027FC20402248F95027FE200023F8220822E83AA8E2E8420803F80208
+589A:22782128246C22AA202AF94822982040204027FC20E03950E2484C4600400040
+589B:200427C42444244427DEFC0425C42404241427EC3C84E4C44AA40A8414940188
+589C:00887C5045FC484050A24B5444B8675458924350402001003FF801000100FFFE
+589D:2020202021FC202023FEF908239C21082188263E20003BFEE09040900112020E
+589E:22082110200027FC2444FD5424E4244427FC200023F83A08E3F8420803F80208
+589F:2040207C204023FE2242FA7823C4223C2200225022543B54E4D8445009FE0000
+58A0:100013DE1252125213DEFC0011FC112411FC112411FC1C20E3FE402000200020
+58A1:1088105013FE102011FCFC2013FE112410A813FE10001DFCE104410401FC0104
+58A2:202423A820922514F2082C0427BA20A827C6240037BCE08440A8009005280244
+58A3:20A024A422A820A027FCF91020A027FC204023F83840E7FC40A0011002080C06
+58A4:204023F8224823F8F84027FE200023F8220823F822083BF8E20843F801100208
+58A5:102011FC1088105013FEFC0011FC112411FC112411FC1C20E1FC402003FE0000
+58A6:103C13E0112410A813FEFCA81124120211FC112411241DFCE124412401FC0104
+58A7:203823C0208027FE2110FA0825F6291021F0200027FC3C04E5F4451405F4040C
+58A8:00003FF8292825483FF801003FF80100FFFE2448422401003FF801000100FFFE
+58A9:221021102FD0201027BEFCA427D4201427942094211439C8EF08411405140222
+58AA:08407F40007E3E8823483E4800503E5004207F500888290411003FF80100FFFE
+58AB:2108209027FE209023FCFA94231C220423FC22043BFCE00847FE010800A80010
+58AC:00403C78248828F030102BFE244025A4345829B4205221B001003FF80100FFFE
+58AD:2028202423FE22202224FBA42298249025AA284623FA3AA8E2A842A80FFE0000
+58AE:00407BFC488051F8622055FC488848F8688850F8408841003FF801000100FFFE
+58AF:104013FE188055F8522095FC108810F8108810F8108801003FF801000100FFFE
+58B0:200023FE205023FE2252FBFE200021FC210421FC210439FCE02043FE00200020
+58B1:202027A420A822922114FA0825F4280223F8220822083BF8E20841100FFE0000
+58B2:2100210023FC26A82AA8F2A827FC22A822A822A82FFE3000E2A8425404540000
+58B3:102011FC1020108813FEFC8811FC110411FC110411FC1D04E1FC408801040202
+58B4:2110211027FC21102110F7FE204027FC244427FC244437FCE000411002080404
+58B5:100011FC102013FE1222FDAC102011AC100011FC1C00E3FE4040008801FC0084
+58B6:20102410227C201020FEF844262822FE2210227C22103AFEE210421005FE0800
+58B7:108813FE1088100011FCFCA810A813FE10A810A811FC1C20E3FE402000200020
+58B8:2108210827FE21082044FBF42048205027FE208021FC3B04E5FC490401FC0104
+58B9:200027BC24A427BC24A4FFBC240425F4251425F425143DF4E514440404140408
+58BA:2080210027FC24442554FC4427FC24E4255424043840E7FE40A0011002080C06
+58BB:2040204027FC2248FA4825542FFE200023F8220822E83AA8E2E8420803F80208
+58BC:0800FF7808487F4849867F0049787F480828FF9049287F4401003FF80100FFFE
+58BD:221024102F9028902FBEF8A42FD4241422142FD424143788E48848940A941122
+58BE:0600F8FC4A8424FC3884CCFC36A2CA9412A86AC4048201003FF801000100FFFE
+58BF:200027FC24A427FC2040FBF8204027FC211020A03BF8E0404FFE004000400040
+58C0:20102008278824BEF48024942788247E2408278836BEEA884A880B8812880008
+58C1:00407C2045FC44887C5043FE7C20A5FC24203D2001003FF801000100FFFE0000
+58C2:3F7821483F4820862A783F482A483F2820104A289146200001003FF80100FFFE
+58C3:100013FE100011FC1124FDFC112413FE100011FC11241DFCE12441FC000003FE
+58C4:000027882088FABE210877D86B5CA52A29482508220801003FF801000100FFFE
+58C5:02000100FFFE104824FE799010FC22907CFC089030FEC08001003FF80100FFFE
+58C6:0A803138228838382288393822887FFE4002810401003FF801000100FFFE0000
+58C7:20402FFE200027FC2404FDF4251427FC200023F822083BF8E20843F800000FFE
+58C8:20402FFE200027FC2404FDF4251425F4240427FC20083BF0E0404FFE01500E4E
+58C9:2040207C204023FE2242FA7823C4223C220023FE22403BA4E25845B4045209B0
+58CA:2020202027FE202023FEFA52225223FE2040202027FE38A4E1A84290048800C6
+58CB:20402248215027FE2402F80423F8220823F8200027FC3C44E7FC444407FC0404
+58CC:2080204027FE2110FA08251423F8211023F8211027FC3928E3104D4801860100
+58CD:420C2FB082204FA00ABE2FA84AA8CFA842285FA84248028801003FF80100FFFE
+58CE:203C27C020402FFEF04027FC255424E427FC204037FCE0404FFE000005240892
+58CF:201027D0251027DEFC5027E8250427C4200023F822A83AA8E2A842A80FFE0000
+58D0:7FFC111021087FFCB55A292835582108355829283458201801003FF80100FFFE
+58D1:08000F00087CFFA480A47F24492494A822107F28A2443E0201003FF80100FFFE
+58D2:211027FC2110204023F8F84027FC2080211023F820003BF8E2A842A80FFE0000
+58D3:00003FFE288C2F8A28882FBE20082F8828882F94289429A2404047FC80401FFE
+58D4:204027FC204023FC2000F7FE200223F8204027FE200037FEE00847FE04A80798
+58D5:204027FE200021F8F90821F8200027FE240223F829803644E1B8466801A60E60
+58D6:100011FC102013FE1222FDAC102011AC100013FE10201DFCE15441540154010C
+58D7:204023F8204827FE2048FBF8204027FE200022A424523BF8E2A842A80FFE0000
+58D8:00001FF011101FF011101FF000003EF82AA83EF82AA83EF801003FF80100FFFE
+58D9:2040202027FE248825FCFC8827FE242025FC25243DFCE52445FC040004880904
+58DA:2040207C204023FC2244FBF0224422FC22A822F822A83AF8E20045FC05540BFE
+58DB:27BC24A427BC24A427BCFC8424F42514262425B425143DB4E51445F404140408
+58DC:11FC110411FC110413FEFC2013FE122211AC102011FC1C00E3FE4040008801FC
+58DD:202029FC252421FCF82023FE2D0425FC250425FC25043DFCE48845040BFE1000
+58DE:208020402FFE200027FCFCA427FC224821502208244438A8E11043080D460180
+58DF:08407E7C2440FF7C00047E7C42407E7C42407E7C4242463E01003FF80100FFFE
+58E0:2210211027DE2010245EFA8227DE201027DE245027DE3C50E7DE4450045204CE
+58E1:10001F7C1024FFA480A87F102A285546A2107F10A2BC3E1022103E1022FE3E00
+58E2:200027FE244425982488F7DE248825DC26AA248824203520E53C4920092017FE
+58E3:40445F444AAA4AEE4E44EAAA4AEE4E004A284AAA6BAA4EEE9A28022802480288
+58E4:204027FC200023B8F2A823B8211027FC211027FC3110EFFE412803100D480186
+58E5:27FE240025FC25AC2574FDFC242025FC242027FE3C00E554482009FC102003FE
+58E6:21102FFE211027BC24A4F7BC2140212023FE222027FC3A20E3FC422003FE0200
+58E7:27BC24A427BC200027FEFC002590249E27D4256425D43D54E5D445680BC81054
+58E8:00003EF82AA83EF82AA83EF800003EF82AA83EF82AA83EF801003FF80100FFFE
+58E9:27FC20402FFE28422358F5002FBC25242724223C2FA43AA4EFBC42241FA4024C
+58EA:244428E82E0E24E4FA0A2EEE20A02AEA200023F820083BF8E20043FC00040038
+58EB:010001000100010001000100FFFE01000100010001000100010001003FF80000
+58EC:001000F83F000100010001000100FFFE0100010001000100010001003FF80000
+58ED:01000100FFFE010001007FFC000000003FF80108010801280110010001000100
+58EE:0820082008204820282028200BFE182028204820882008200820082009FC0800
+58EF:042024202420242024203C2007FE0420FC20242024202420242045FC44008400
+58F0:01000100FFFE01007FFC00003FF8210821083FF8200020002000400040008000
+58F1:010001007FFC010001001FF000007FFE40028004101010E01F08100810080FF8
+58F2:010001007FFC010001001FF000007FFE4002844404400440044008441044203C
+58F3:010001007FFC010001001FF000007FFE400280040FE00820082010222022C01E
+58F4:01000100FFFE010001007FFC00001FF0101010101FF0000008200440FFFE0000
+58F5:010001007FFC0100010001003FF8000010101010FEFE1010101010107C7C0000
+58F6:010001007FFC010001001FF000007FFE40028444044024481448145004407FFC
+58F7:010001007FFC01001FF000007FFE444284443FF8244824483FF804400440FFFE
+58F8:010001007FFC01001FF000007FFE4002BFFC04402448144814500440FFFE0000
+58F9:010001007FFC01001FF000007FFE40029FF400001FF010101FF008200440FFFE
+58FA:010001007FFC01001FF000007FFE444284443C7820083C7804400440FFFE0000
+58FB:100013FE10221120113CFD2012FE140011FC110411FC1D04E1FC410401140108
+58FC:010001007FFC01001FF000007FFE4002BFFC04403C7820083C780440FFFE0000
+58FD:01007FFC01003FF80000FFFE00023FF00100FFFE00007FFC00107DFC44907C30
+58FE:0800087EFF40084008407E7C00447E44424442447E7C424024400F40F07E4000
+58FF:1088105013FE105011FCFF54118C1174110411FC1C0873FE2108008800A80010
+5900:01003FF801001FF001007FFC01041FF011101FF00100FFFE00083EFE22483E18
+5901:0100FFFE01003FF800007FFC44447FFC00003FF821082FE8210827C824483FF8
+5902:0400040004000FF008101010302048208440028001000280044008203018C006
+5903:00003FF00410042004200440047C04040BE4082409441084114422244C288010
+5904:1040104010401E40126022502248524494441440084008401440230040FE8000
+5905:040004000FF01820644003801C70E10E01001FF0010021003FF8010001000100
+5906:040004000FF01820644003801C70E10E1FF001001FF001007FFC010001000100
+5907:040004000FF01820644003801C70E00E1FF0111011101FF0111011101FF01010
+5908:040004000FF01820644003801C70E10E111009207FFC05400920111061080100
+5909:02000100FFFE044014502448444408000FF010102820444003800C603018C006
+590A:0400040004002FF028101010302048208440028001000280044008203018C006
+590B:0400082010103FF8000808201210220847E4082014402280010006C01830E00E
+590C:010001003FF801000100FFFE1210220847E4882214402280010006C01830E00E
+590D:100010001FFC20005FF090101FF010101FF004000FF01820644003801C70E00E
+590E:010011101110292845443FF801000100FFFE08000FF01420224041800E60701C
+590F:7FFC02001FF010101FF010101FF010101FF008001FF02820444003801C70E00E
+5910:10001FE020207FF8A30824881FF010101FF010101FF008001FF0282007C0F83E
+5911:210827C820086B9AB02C2388200853944A928BA204000FE0144003801C70E00E
+5912:0000FFFE110013DC52545BD4525C53D05A52E3CE24084FE4944203801C70E00E
+5913:17C0621C47C4444477DC444447C4745C47C4000024084FE4944203801C70E00E
+5914:0440FFFE110013DC52545BD4525C53D05A52E3CE24084FE4944203801C70E00E
+5915:020002000200020007F80408080810102410422001400080010002000C007000
+5916:10401040104010403E40226042504248A4441444084008401040204040408040
+5917:1000100010F81E8812882288228852888AA804900480088208821082207E4000
+5918:10001000107C1E4412442244224452448A440444044408540848104020404040
+5919:00003FF8200820082FE82208220827C8244828483488228A210A420A44068802
+591A:0200020007F008203840048003400C8071F802080C103220014001800E007000
+591B:00003FF0001000101FF000100010FFFE020007F008103420024001800E007000
+591C:02000100FFFE0880088010F81108314852289510111010A0104010A011181606
+591D:2020202021203D2025FC45204620A420142009FC082010201020202043FE8000
+591E:102010203F304128A224142208203020C02000003E442258226022423E42223E
+591F:20202020407C7E4482A802107A204AD04A1E4A227A644A9402080210142008C0
+5920:102010203E40427EA4821902107A284ACF4A114A327A4A4A040208023014C008
+5921:101010103E1042FEA4101810107C2800CF00117C32444A4404440844307CC044
+5922:0820FFFE08203FF824483FF800007FFE420287F408103420024001800E007000
+5923:0100FFFE10103FF800003FF824483FF800007FFE44028FF4342002C007007800
+5924:02000FF0346003801D007FFE4002BFFC01003FF821083FF821083FF810102008
+5925:00207E204A7C4A447EA84A104A207ED0081EFF2218642C942A084A10882008C0
+5926:22202220FF7C22443EA822103E2022D0221EFF2240645494620840107E2000C0
+5927:01000100010001000100FFFE010001000280028004400440082010102008C006
+5928:100010001000200020007F80008001000100FFFE01000280044008203018C006
+5929:00003FF80100010001000100FFFE01000280028004400440082010102008C006
+592A:01000100010001000100FFFE0100010002800280044004400A2011102108C006
+592B:01000100010001003FF8010001000100FFFE028004400440082010102008C006
+592C:0100010001001FF001100110011001100110FFFE02800280044008203018C006
+592D:001000F83F000100010001000100FFFE0100028002800440082010102008C006
+592E:0100010001001FF011101110111011101110FFFE02800280044008203018C006
+592F:010001007FFC0280044008203018C10601003FF8020802080408080810506020
+5930:010001007FFC0280044008203018C44604400440044004400840084010402040
+5931:01001100110011001FF8210041000100FFFE010002800280044008201010600C
+5932:010001007FFC0280044008203118C10601000100FFFE01000100010001000100
+5933:010001000100FFFE02800440082010102008CFE600000000000000007FFC0000
+5934:00800080088004802480108010800080FFFE010001400220041008083004C004
+5935:010001007FFC0280044008203018C10601000920091011082104410405000200
+5936:082008200820082008207EFE0820082008501450125012882088210442048402
+5937:01000100FFFE01003FF8010801083FF8210021003FFC0284044C08203018C006
+5938:010001007FFC0440082017D02008C0063FF8040008000FF00010001000A00040
+5939:0100010001007FFC0100111009200100FFFE010002800280044008203018C006
+593A:010001007FFC0280044008203018C0460040FFFE004010400840084001400080
+593B:010001007FFC01000280044008203018C0061FF010101010101010101FF01010
+593C:010001007FFC0280044008203018C92609200920092009201120112021204020
+593D:020002007FFC044008203018CFE6000000007FFC02000400082010103FF81008
+593E:0100010001007FFC01001110111011102928454402800280044008203018C006
+593F:010001007FFC0280044008203018DFF61110111011101FF0100410040FFC0000
+5940:00007FFC01000300056019186104000001000100FFFE0280044008203018C006
+5941:020002007FFC044008203018DFF610001220114010801140122010001FF80000
+5942:080008000FE0102020405FF09110111011101110FFFE0280044008203018C006
+5943:020002007FFC044008203018C0F63F00210021003FFC208020402A243114210C
+5944:020002007FFC044009203118DFF6111011101FF0111011101FF40104010400FC
+5945:020002007FFC044008203018C60638F82088228822882E8832A8249004800880
+5946:020002007FFC044008203018DFF6100010001FE0102010201FE0100010001FF8
+5947:010001003FF8028004400820FFFE001000101F90109010901F90001000500020
+5948:020002007FFC044008203018CFE6000000007FFC010011101108210445040200
+5949:010001007FFC01003FF80200FFFE044009203118CFE6010001003FF801000100
+594A:00800FF840805FFC40804FF840805FFC40007F0001007FFC028004401830E00E
+594B:010001007FFC0280044008203018C0061FF0111011101FF0111011101FF01010
+594C:0100010001FC010001001FF0101010101FF0010001007FFC028004401830E00E
+594D:0100111009203FF8020002007FFC082010102448C44604400840084010402040
+594E:020002007FFC044009203118CFE6010001007FFC000001003FF801000100FFFE
+594F:010001007FFC01003FF80200FFFE0440082037D8C1061FF0010002C00C303008
+5950:080008001FE020204040BFF822882448282821080100FFFE028004401830E00E
+5951:080008007F7C08243E2408247F44085409880100FFFE0280044008203018C006
+5952:020002007FFC04400A203118DFF6040008401F8001100620384001A00E107008
+5953:020002007FFC044008203218C7E618400580068039F80610192000C003003C00
+5954:020002007FFC044009203118CFE60100092008207FFC08200820102010202020
+5955:020001007FFC0440245044488944108001000100FFFE0280044008203018C006
+5956:0840484028FC09041A8828504820884009800100FFFE0280044008203018C006
+5957:010001007FFC028004400FF03418C7E6040007E00400FFFE040008101FF80008
+5958:2420242024203DFC0420FC20242024F845000100FFFE0280044008203018C006
+5959:040008201FF00210FFFE08203118DFF611101FF011101FF40104010400FC0000
+595A:00FC7F002208151008401F8003200C103FF8010801007FFC028004401830E00E
+595B:020002007FFC044008203018C0063CF824883CF8248824F83C88248801280210
+595C:044004407C7C04403C7804407C7C044005400100FFFE0280044008203018C006
+595D:020002007FFC044008203FF8D11617D011101FF0101017D0245027D040108030
+595E:020002007FFC044008203018C90608801FFC30805FF890801FF810801FFC1000
+595F:020002007FFC044008203E78D24E12481E78124812481E78124822882AA84510
+5960:08200440FFFE04403FF82848303827C820083FF801007FFC028004401830E00E
+5961:7FFC02001FF010101FF010101FF010101FF00200FFFE08203458C44608401040
+5962:020002007FFC044008203218DFD60220FFFE03000FF03810CFF008100FF00810
+5963:00003FF802007FFC04401830E00E3CF8248824F83C8824F824883C8801280210
+5964:020002007FFC044008203FF8C10602003FF8244827C8244827C824483FF82008
+5965:020004003FF82008292825482FE82548292820080100FFFE02800C603018C006
+5966:00407EFC15440838FE441AA22CFC4844A894110801007FFC028004401830E00E
+5967:02003FF8200820C82708292825482FE82548292801007FFC028004401830E00E
+5968:083E4BC42A48292008081BFE2908C8880828091001007FFC028004401830E00E
+5969:02007FFC04201818E0063FF8200027F0241027F020002F7829482F7820003FFC
+596A:02007FFC04201898E8461FF830805FF810801FF810801FFC1020FFFE08200460
+596B:020002007FFC044008203018C14625481778840847F814082778E54825482808
+596C:0440247C24A83D5004287DFE2488444885180100FFFE0280044008203018C006
+596D:01000100FFFE01007D7C11107D7C45447D7C45447D7C0280044008203018C006
+596E:02007FFC04201818E9061FF831005FF891001FFC10003FF821083FF821083FF8
+596F:02007FFC04201918E9E609007FFC00283FFE20202FA422282A90532A46469882
+5970:00003FF824483FF80000FEFEAAAAAAAAFEFE010001007FFC028004401830E00E
+5971:210447C88812F3BC20084B92F83E0380AAAAABAA01007FFC028004401830E00E
+5972:100010EEFEAA28AA44EE90007AFE1492FEFE10927CFEC4107DFE44107C104410
+5973:02000200020002000400FFFE0420082008201040184006800180066018106008
+5974:1000100011FC1084FC8424842488248824504850282010202850448881040202
+5975:1000100013FE1020FC2024202420242024204820282010202820442084A00040
+5976:1000100013F81088FC90249024A024BC24844884290411042904460482280410
+5977:1008103C11E01020FC202420242027FE24204820282010202820442084200020
+5978:100011FC10201020FE202220222023FE42202420142008201420222042208020
+5979:1020102010201120FD2C2534256427A425244934292811222922450284FE0000
+597A:10801080108010F8FD0825082510261024204820285010502888450882040402
+597B:1020102010201020FEFE22442244224442442484144808281410222842448082
+597C:1010103811E01020FE2022202220223E43E024201420082214222222421E8000
+597D:100010FC10041008FC102420242025FE24204820282010202820442084A00040
+597E:1020102010201020FD242524252425242524492429241124292445FC80040000
+597F:20402040204023FEFC88248825082490645024203450248A2502440243FE8000
+5980:00400040FC40044007FE048804887C8840884108409044505820605040880304
+5981:10401040108010FCFD0426042404250424844844284410042804440484280010
+5982:100010001000107CFE4422442244224442442444144408441444227C42448000
+5983:1000100011F81008FC082408240825F825084900290011002902450284FE0000
+5984:02000100FFFE100010001FF802000200FFFE042008201E400180066018186004
+5985:1000100011FC1020FC2024202420242024204820282010202820442083FE0000
+5986:08400840084048402BFE28880888088818882908C89008500820085008880B04
+5987:1000100011FC1004FC042404240425FC2404480428041004280445FC80040000
+5988:100013F010101010FD102510251025FC24044804280413F42804440484280010
+5989:10201020102011FEFD222624242024202450485028501050289044928512020E
+598A:1008103C11E01020FC202420242027FE24204820282010202820442085FC0000
+598B:1020102010201020FDFC24202420242027FE4820285010502888448885040202
+598C:1088108810881088FDFC24882488248827FE4888288810882888450885080208
+598D:100013FE10881088FC882488248827FE24884888288810882888448881080208
+598E:1020102010501050FC8825042602248824884888288810882888450881080208
+598F:10401020102013FEFC8824882488248824884850285010202850448881040602
+5990:1010109010901088FC882524252426222420484028481044288445FE84820000
+5991:1000100011FC1124FD2425242524252425FC4900290011002902450284FE0000
+5992:10401020102011FEFD022502250225FE25024900290011002A00460084000800
+5993:10201020102013FEFC202420242025FC24844888284810502820445081880606
+5994:10801040104013FCFC00240025F02510251049102910111229124612820E0400
+5995:1020102010201020FDFC252425242524252449FC292410202820442084200020
+5996:1008103C11E01020FC20242025FE242024204850285010502888448881040202
+5997:1020102010501050FC88254426222420240049FC280410082808441084100020
+5998:1000100010FC1000FC00240025FE24202420484028401088288445FE84820000
+5999:10201020102010A8FCA424A22522252026244824282810082810442080C00300
+599A:1000100011FE1010FC1024202420246824A449222A2210202820442084200020
+599B:01002108210821083FF801000100FFFE02000200FFFE08201C4003800C707008
+599C:10401040104013F8FC4824482448244827FE484028A010A02910451082080406
+599D:042024202420242025FE3C4404440444FC442484244824282410442844448582
+599E:100011F810481048FC482448244825F824884888288810882888448883FE0000
+599F:00001FF0101010101FF0101010101FF002000200FFFE08201C4003800C707008
+59A0:1020102010201020FDFE2522252225222552494A298A110229024502850A0104
+59A1:1008101C11E01100FD00250025FE251025104910291011102910461082100410
+59A2:1010109010901088FD082504260425FA24884888288810882908450882280410
+59A3:1010111011101112FD12251425D82510251049102910111229524592850E0000
+59A4:100011F810081050FC20241027FE242224244820282010202820442084A00040
+59A5:00FC7F00020821081110102002000200FFFE042008201E400180066018186004
+59A6:10201020102013FEFC202420242025FC24204820282013FE2820442084200020
+59A7:100011FC10001000FC0027FE24902490249048902890109229124512820E0400
+59A8:10401020102011FEFC4024402440247C24444844284410442884448481280210
+59A9:200023FC20402040F84048404FFE484088A048A030A0112029224A22841E0800
+59AA:100011FE11001104FD4425282528251025104928292811442984450085FE0000
+59AB:1020112010A010A0FC2027FE2422242224424852284A108A2882450282140408
+59AC:1000100013FE1020FC202440244024FC25844A842C8410842884448484FC0084
+59AD:2050204820482040FBFE4880488048FC89444944312811282A104A2884440182
+59AE:100011FC11041104FD0425FC25002540254449482970114029424642823E0400
+59AF:1020102010201020FDFC252425242524252449FC292411242924452485FC0104
+59B0:10801080108010FEFD4025402640247C244048402840107C2840444084400040
+59B1:100013FC10841084FC84250425142608240049FC290411042904450485FC0104
+59B2:1000100010FC1084FC84248424FC24842484488428FC10842800440085FE0000
+59B3:10801080108010FEFD0225042620242024A848A4292411222A22442080A00040
+59B4:100010F83E884288A4A818941084207CC2000200FFFE08201C4003800C707008
+59B5:10401020100013FEFC2024202420242025FC4820282010202820442083FE0000
+59B6:10201010101011FEFC2024202444248425F8481028201044288245FE84820000
+59B7:1020102011201120FDFC25202620242025FE4820285010502888448885040202
+59B8:1000100013FE1008FC0825E8252825282528492829E811282808440884280010
+59B9:10201020102011FCFC202420242027FE247048A828A811242924462284200020
+59BA:10201020102013FEFC202420242025FC247048A828A811242924462280200020
+59BB:010001007FFC01003FF80108FFFE01083FF80200FFFE08201C4003800C707008
+59BC:1040102010281008FC08244824542552255249602A60104428C44544823C0000
+59BD:10201020102011FCFD242524252425FC25244924292411FC2924442080200020
+59BE:020001003FF8000008200440FFFE020002007FFC042008401C8003800C707008
+59BF:100010007E7C1244124422444A7C844402000200FFFE08201C4003800C707008
+59C0:101C11E010201020FC2027FE24202470247048A828A811242A22442080200020
+59C1:10801080110011FCFE04240425E425242524492429E411242804440484280010
+59C2:1004101E11E01000FC20241025FE2404240848102820104028804540823E0000
+59C3:1000100013FE1020FC20242025202520253C4920292011202920452087FE0000
+59C4:100011FC11041104FD0425FC2520252025FE4920292011102912454A85860102
+59C5:10201020112410A4FCA8242025FC2420242048202BFE10202820442084200020
+59C6:100010FC108410A4FC942484248427FE250449442924110429FE440484280010
+59C7:0810081017FE3010521091101110105012200200FFFE08201C4003800C707008
+59C8:1020102010501050FC8825242612241025FC4804280810882850442084100010
+59C9:10201020102013FEFC20242025FC252425244924292411342928442084200020
+59CA:10201020102E11F0FD202520252025FE2422486228A2112A2E24442084200020
+59CB:1020102010201040FC48248425FE2482240048FC288410842884448480FC0084
+59CC:10201020102011FCFD24252425FC2524252449242BFE11042904450485140108
+59CD:100011FC11541154FD542554255427FE25544954295411542954454485140108
+59CE:10201020102011FCFD2425242524252425244BFE282010502850448881040202
+59CF:1088108810881088FDFE248824882488248848F8288810882888448884F80088
+59D0:100011F811081108FD0825F825082508250849F8290811082908450887FE0000
+59D1:1020102010201020FDFE24202420242025FC4904290411042904450485FC0104
+59D2:1008104811281128FD2825082508250825084908294811942914442284420082
+59D3:1020102011201120FDFC252026202420242049FC282010202820442083FE0000
+59D4:00701F8001000100FFFE054009203118C2060200FFFE08201C4003800C707008
+59D5:0880088828902EA028C028842E84F07C02000200FFFE08201C4003800C707008
+59D6:100011FE11001100FD0025FC250425042504490429FC11002900450085FE0000
+59D7:100011DC11541154FD542554255427FE2554495429541154295446D48224044C
+59D8:1104108410881000FDFE24882488248824884BFE288810882908450882080408
+59D9:10801088109C1170FD1027102510251025FE49102910111029104510857C0100
+59DA:2090209020902292F9944898489049988A944C9230901090291249128212040E
+59DB:100011FE11021102FD7A25022502257A254A494A294A117A29024502850A0104
+59DC:082004407FFC01003FF80100FFFE02000400FFFE082010201C4003800C707008
+59DD:20202120212021FCF9204A2048204BFE487090A850A8212431244A2248208020
+59DE:10201020102013FEFC20242025FC2400240049FC290411042904450485FC0104
+59DF:10201010101013FEFC202442248425F82410482228C413082810442880C40302
+59E0:10201020104011FEFD022502257A254A254A494A294A117A29024502850A0104
+59E1:1008103C11E01020FC2027FE24202420242049FC290411042904450485FC0104
+59E2:1020102010481084FDFE2402240024FC248448FC288410FC2884448484940088
+59E3:10401020102011FEFC0024882504260224884888285010502820445080880306
+59E4:1008101C11E01100FD0025FE25002500257C4944294411442944467C82440400
+59E5:10401040104411F4FC48245027FE2440248049842A9810E028824482847E0000
+59E6:04000400FFFE08201C4003800C70700800101010FEFE2224646418182434C2C2
+59E7:10001000FE7C2210641018102410C21010FE1010FE102210641018102410C210
+59E8:2040204027FC2040FBF848484BF84A408BFC4844305410A828A0491082080406
+59E9:1080108010FE1110FE10241024FC2490249048902BFE10102810441084100010
+59EA:100011FE10201040FC88250425FE24222420482029FE10202820442083FE0000
+59EB:100011FE11201120FD2025FC250425042504490429FC11202920452085FE0000
+59EC:100011FE11101110FD10257C2544254425444944297C11102910451085FE0000
+59ED:02001FF00410085010207EFC12242A5444880400FFFE08201C4003800C707008
+59EE:100013FE10001000FDFC2504250425FC2504490429FC11042800440083FE0000
+59EF:1040104412441148FD50244027FE2490249048902890109229124512820E0400
+59F0:1080108011FC1104FE0425E42524252425E44924292411E42904440484280010
+59F1:1020102013FE1050FC88250426FA240027FE4840288011FC2804440484280010
+59F2:20402020202023FEFA024C4448404BFE48889088510820D03020485048888304
+59F3:1040104010FC1104FE88245024202440248049FC2A8410842884448484FC0084
+59F4:00047FA410243F2451240A040C043014C2080200FFFE08201C4003800C707008
+59F5:200027FC24042404F5F45444544455F455549554555425542574544654468842
+59F6:1020102010501088FD04260225FC2400240049FC290411042904450485FC0104
+59F7:1020102011FE1040FC4024FC2484258426FC4884288410FC2884448484940088
+59F8:100011DC10881088FC882488248827DE24884888288810882888450881080208
+59F9:10401020102011FEFD022604241825E024404840287E13C0284044448444003C
+59FA:10201120112011FCFD202620242027FE2490489028901090291245128212040E
+59FB:100011FC11041124FD24252425FC252425244954294C118C2904450481FC0104
+59FC:10201020107C1084FD482430242024482590483E284211A42818441084600180
+59FD:1040104010FC1104FE0825FE2500257C254449442954114829424542853E0200
+59FE:1020102010501088FD04260225FC24202420482029FC10202820442083FE0000
+59FF:4080208009FC12042448E04020A023182C060400FFFE08201C4003800C707008
+5A00:2028202420242020FBFE48204924492489244BA8312811102A124A2A84460082
+5A01:0028002400203FFE202020203FE4222422243FA824A828902512422A45469882
+5A02:1088108810881088FDFE24882488248824884BFE280010882884450482020402
+5A03:1020102011FC1020FC20242027FE24002420482029FC10202820442083FE0000
+5A04:010011100920FFFE054009203118C0060200FFFE042008201C4003800C707008
+5A05:200023FC20902090F89048924C924A948A944A98309010902890489087FE0000
+5A06:2080208020BC23C0F850482448D44B0C88004BFE3090109029124912820E0400
+5A07:1008101C10E01020FC2025FE2450248825044A8A288810882888448884880108
+5A08:02000100FFFE0440145014482444420402007FFC042008401C8003800C707008
+5A09:1020102011FC1124FDFC252425FC240027FE4880290011FC2804440484280010
+5A0A:100011F811081108FDF82508250825F82508490829F81090289045128212040E
+5A0B:1020112410A410A8FC2025FC2504250425FC4904290411FC2904450485140108
+5A0C:100011FC11241124FDFC2524252425FC2420482029FC10202820442087FE0000
+5A0D:2028202420242020FBFE4A204A244A248BA44AA832A812902A924DAA84460882
+5A0E:080C08F07E8008800EFE78880888290812080200FFFE08201C4003800C707008
+5A0F:10901088108013FEFCA024A824B024A424A848B02924112A2932462282DE0400
+5A10:1008103C11C01004FD4424A8240025F8241048202BFE10202820442084A00040
+5A11:1020082040A824A4092A723010C0170002007FFC042008401C8003800C707008
+5A12:1080108010FE1100FEFC248424A4249425FE48842924111429FE440484280010
+5A13:200023FC22042204FBFC4A004A184AE08A384AE0323C13E02A224C22841E0800
+5A14:1020102013FE1020FC2025FC25042504250449FC28501050289244928112020E
+5A15:1020102013FE1020FC2025FC2524252425FC4820287010A82924462280200020
+5A16:100011FC11041104FD04250425FC242024204920293E1120292046A0847E0800
+5A17:2000200623B82088F8884908493E4B8888884A883288113E29004A80847E0800
+5A18:1040102011FC1104FD0425FC2504250425FC4920292211142908454485820100
+5A19:100011FE10001092FD24264825242492240049FE282010202820442083FE0000
+5A1A:11FC1124112411FCFD24252425FC244024404BFE284210822882450282140408
+5A1B:200020F820882088FAF84A004A004BFC8844484437FE104028A0491082080406
+5A1C:20002FDE22522252F25457D45258525452529FD25252225A2254545055508890
+5A1D:100013FE10101020FC6824A427222420240049FC290411042904450485FC0104
+5A1E:2008203C23C02044FA244928490048408BFE4888310813902860485081880604
+5A1F:200021F821082108F9F848004BFC4A044A0493FC5204220433FC4A044A148208
+5A20:200023FC22002200FAF84A004A004BFC8AA04AA432A812902A904C8884A408C2
+5A21:20202020202023FEF8204820482049FC8840482030A412822A8A4A8A84780000
+5A22:1020102010501088FD44262224F824082410482029FC11042904450485FC0104
+5A23:11081088109011FCFC24242425FC2520252049FE286210A2292A462484200020
+5A24:2420242024203DFC0420FC20242024F846000200FFFE08201C4003800C707008
+5A25:101010D813941094FC9027FE24902494249448D82B98109028AA44CA84860182
+5A26:1010103811C01100FD0025FC25102510251049102BFE10002890450882040402
+5A27:1104108410881010FDFC25042504250425FC48502850109028924512820E0400
+5A28:100011FC110411FCFD0425FC2400240025FC4820282013FE2820442084200020
+5A29:1080108010F81108FE1025FC25242524252449FC28501050289044928112020E
+5A2A:100013FE10401040FDFC2484248427FE2400480029FC11042904450485FC0104
+5A2B:2004200E23B82088F8884928492E4BA888A84AA832A8113E29004A80847E0800
+5A2C:2010201823D42014F8104FFE4810489088904AD0329012902A8A4AEA87060202
+5A2D:2020204020882104FBFE4882488049FC8A20482033FE10202850488881040602
+5A2E:1040102013FE1000FC0025FC2400240025FC4800280011FC2904450485FC0104
+5A2F:200020F820882088FAF84A004A004BFC8804480437FE100028A0491082080406
+5A30:21082148212822A8FAA84E884A884A884A88928852A822D432944A224A428282
+5A31:200023F822082208FBF8480048004BF88840484037FE104028A0491082080406
+5A32:200021FC21042104F90449FC482048204BFE92225252228A330A4A024A0A8204
+5A33:204220E22382208AF88A488A4BEA488A498A91CA52AA228234824882488A8084
+5A34:110010BC10041124FD24252425FC2524257449AC292411242924450485140108
+5A35:200027E0225E2252FA524BD24A524A544BD49254524822E83754485448628040
+5A36:00007F7C22443E4422283E1023A8FE4402820400FFFE08201C4003800C707008
+5A37:1008103C11E01020FDFE24A824A824A827FE48A828A813FE2820442085FC0000
+5A38:1088108813FE1088FC8824F82488248824F84888288813FE2800448885040202
+5A39:20102388208820FEF8904B904A244A244A3893885090209030A448BE4A828100
+5A3A:200023DE2042214AF884494A4A524C2088004BDE305211522894494882540422
+5A3B:1020102013FE1020FDFC252425FC252425FC4820287010A82924462280200020
+5A3C:10FC1084108410FCFC84248424FC240025FE4902290211FE2902450285FE0102
+5A3D:100011F810081008FDF82408240827FE24204A22297410A82924462280A00040
+5A3E:100011FE11101110FD7C2510251025FE250049102910117C2910461082FE0400
+5A3F:00007BFE480851E8492845E85408482842100200FFFE08201C4003800C707008
+5A40:2000277E25042504F57455545654555455549554557425542604540454148408
+5A41:01001FF01110FFFE11101FF001001FF011101FF00200FFFE08201C4003C03C38
+5A42:2020204021FC2104F9FC490449FC4820482093FE52222222322A4A2448208020
+5A43:2040202023FE2202F80049FC480048004BFE90205128212432224C2248A08040
+5A44:1040102011FC1000FD082490240027FE2400480029FC11042904450485FC0104
+5A45:1100110011FC1204FC44255424E4244427FC484428E411542A44444484140008
+5A46:202013FE922242204BFC1284E448243029CE0400FFFE08201C4003800C707008
+5A47:2008203C23C02044FA244928490048208BFE487030A810A829244A2284200020
+5A48:2020202021FC2020F8204BFE488849448A4248F8318812502820485081880606
+5A49:2040202023FE2202FD04490049DE4A528A524B52349A1094291049128212040E
+5A4A:1020102013FE1020FC2025FC2420242027FE484028A411A82A90448884C60080
+5A4B:10201020103E1020FDFE2522253825E02522491E290011782A48464A848A0906
+5A4C:2100210021DC2114F114511457D4501451149114558825482948511455148222
+5A4D:1020102011FC1050FC88250427FE240825E84928292811E82928440884280010
+5A4E:10A01090109011FEFD20252027FC2520252049FC29201120292045FE85000100
+5A4F:1080108010F81108FE1025FC25242524252449FC28501058289444928112020E
+5A50:100011FC11241124FDFC2524252425FC24204BFE287010A82924462280200020
+5A51:201C21E020202020FBFE48A849244A42484093FE5088210830D0483048488184
+5A52:102010A210A21124FC50248827042422242048A428A411282850448885040202
+5A53:04400440FC7E04407C7C0440FC7E044006400200FFFE08201C4003800C707008
+5A54:209020902090279EF890489048904B9C489090905090279E3090489048908090
+5A55:2020202023FE2020F9FC48244BFE482489FC48203120113E29204AA0827E0400
+5A56:200023FC20402040FBFE48A049104A084C4690405048226432524C5249408080
+5A57:20002040239C2204FA044B9C4A044A048BFC489030901090289049128212040E
+5A58:1020112410A81020FDFC244027FE248825044AFA2C88108828A844928482007E
+5A59:1080108010F81108FE1025FC2424242425FE4824282411FC2824442084A00040
+5A5A:201C23E0222023FEFA204A924B0A4A0649FC9104510421FC3104490449FC8104
+5A5B:1040102013FE1000FC0025FC2504250425FC4820292811242A22442280A00040
+5A5C:00007F7C48447F4441287F1048287F4400820400FFFE08201C4003800C707008
+5A5D:2040202023FE2202FC0448004BFE482088204920313C11202AA04A60843E0800
+5A5E:1020102011FC1020FC2027FE2488245025FC4820282013FE2820442084200020
+5A5F:200023FE22222222FBFE4A224A224AFA4A8A928A528A22FA328A4A024BFE8202
+5A60:1040102013FE1202FC0425F82508250825F84900290011FC2904450485FC0104
+5A61:20202020202023FEF8204924492449248AAA487030A810A829244A2284200020
+5A62:1040108011FC1124FD2425FC2524254425FC4890291013FE2810441084100010
+5A63:2050225222522252FBDE4A024A024BFE8A024A0233DE12522A52425284520802
+5A64:200023FE22222222FAFA4A224A224BFE8A024AFA328A128A2AFA4A02820A0404
+5A65:10201020103E1020FDFC250425FC250425FC4924282013FE2820442084200020
+5A66:200021FC200420FCF80449FC48004BFE4A22902051FC21243124493449288020
+5A67:1020102013FE1020FDFC242027FE240025FC490429FC110429FC450485140108
+5A68:1020102010501088FD0426FA240025FC2554495429FC1154295445548504010C
+5A69:1020112411241124FDFC240025FE2500257C4910291011FE2910461082100410
+5A6A:082008207EFC08301C682AA4C92208200A207FFC042008401C80038006703808
+5A6B:100011FC11041104FDFC2504250425FC2400491229D41118291045528592010E
+5A6C:1008103C11C01044FD2424A82490241C25E04820282013FE2820442085FC0000
+5A6D:100011FE10481048FC4825CE25022502250249CE284810482848444885FE0000
+5A6E:100011FC11041104FDFC2510251025FE25104910297C114429444544857C0244
+5A6F:0000FEFE00007C7C444464645454444446440200FFFE08201C4003800C707008
+5A70:10501050105011FCFD542554255425FC25544954295413FE2800448881040202
+5A71:00407C2005FC7C4040887DF00420044829FC10040200FFFE08201C4003C03C38
+5A72:1088108813FE1088FC8824502450249425944A98289010B228D24492848E0080
+5A73:200023FE20002000F8F848A84AAA4AFA4AAA92AA52AA22FA32024A024BFE8002
+5A74:00003EF822882AA82AA82AA81450628802007FFC042008401C80038006703808
+5A75:11041088105011FCFD24252425FC2524252449FC282010202BFE442084200020
+5A76:2040202023FE2222F82049FC4924492449FC9124512421FC3124482048208020
+5A77:1040102013FE1000FDFC250425FC240027FE4A0229FC10202820442084A00040
+5A78:100010FC108410FCFC8424FC240025FE248048FE292A124A2892452284540088
+5A79:200023FE20502050FBFE4A524A524BFE4800904057FE20883190486048D88304
+5A7A:00207E20247E18A4FF2829104A2898C602007FFC042008401C80038006703808
+5A7B:2020202023FE2020F8204BFE4A8A4A524AFA9222522222FA32224A224A2A8204
+5A7C:1088108813FE1088FCA8242027FE2440248048FC298412842884448484FC0084
+5A7D:200023DE22422242FA424BDE4A004A3E4BD29212521423D432084A144A248242
+5A7E:21C020A021102208FDF648004BCA4A4A4A5493D45268225433D44A4A4A4A82C0
+5A7F:100013FE10221120FD3C252026FE240025FC490429FC110429FC450481140108
+5A80:21FC2124212421FCF924492449FC4820482093FE5222222A32FA4A0A4A028206
+5A81:2040204021FC2084FBFE480049FC490449FC902053FE202032204BFE48208020
+5A82:2040202021FC2000F88848504BFE4A224C2491FC512421243134492848208020
+5A83:200021FC20482030FBFE4852489449108A30482033FE107028A8492486220020
+5A84:1104108813FE1020FC2025FC2420242027FE4800282013FE2820445080880306
+5A85:1088108813FE1088FCF8248824F8248824884BFE290011482984450085FE0000
+5A86:100013FE10201040FDFC2554255425542554492C282013FE2850448881040202
+5A87:1040102011FC1000FC88245027FE2420242049FC282010A82924462280A00040
+5A88:200023FE22222020FBFE482049FC492449FC912451FC202033FE482048208020
+5A89:200023FC22042204FBFC4A004BFC4A408A884BFC322412202DFC4420882013FE
+5A8A:21082088209027FEF8004BC44A544A544BD49254525423D432544A444A5482C8
+5A8B:1020102013FE1020FDFC244027FE248825044AFA2888108828F84488848800F8
+5A8C:1088108813FE1088FC88240025FC25242524492429FC11242924452485FC0104
+5A8D:1040104010F81108FE1025FC250425FC250449FC290411FC2800448881040202
+5A8E:1020102211FA1024FC2827FE2420244024FC49842A8410FC2884448484FC0084
+5A8F:1020112411241124FDFC240027FE2420244049FC29541154295445548554010C
+5A90:00007F7C444444445F7C51405F4244427FBE0200FFFE08201C4003800C707008
+5A91:2008203C21E02020FBFE482049FC492449FC912451FC202031FC48204BFE8000
+5A92:21102110211027FCF91029F0291029F048404FFE284010E011502A4E44448040
+5A93:1020104011FC1104FDFC250425FC240027FE4820282011FC2820442083FE0000
+5A94:200027FE20402080FBFC4A944A944AF44A94929452F4229432944A944BFC8204
+5A95:1020105010881104FEFA240025FC2504250449FC288810882BFE448881080208
+5A96:2110211027FC2110F95048404BF84A488A484A4837FE104028A0491082080406
+5A97:2040202023FE2202FC0449FC480049FC490491FC510421FC310448004BFE8000
+5A98:1110111211D41118FD522592252E244025FC4904290411FC2904450485FC0104
+5A99:200C200A200823FEFA084BF84A4A4A4A8BEA4AAC32AC124C2AAA4B0A82160422
+5A9A:100011FC11241124FDFC2500257C25442544497C2944117C29444644827C0444
+5A9B:203C27C022442128F8004BFC488048804FFE910051F8228832504C2048D88306
+5A9C:10201020103E1020FC2025FC250425FC250449FC290411FC2800448885040202
+5A9D:0610381008527E5408901C282A2848440A820200FFFE08201C4003800C707008
+5A9E:100011FC11041104FDFC2504250425FC24004BFE28201120293C452082A0047E
+5A9F:10481148114813FEFD4825482578250025FE48202BFE107028A8452486220020
+5AA0:1040104013FE1080FDFC262025FE240025FC490429FC110429FC450485140108
+5AA1:1020102013FE1020FDFC252425AC2574252449FC2820107028A8452482220020
+5AA2:100011FE1102117AFD02257A2502240024FC488428FC108428FC448484FC0084
+5AA3:212020A024782228F8A8492A4F2A494649A0902053FE207030A849244A228020
+5AA4:100011FC11241124FDFC2524252425FC24204810285411422942454A82380000
+5AA5:2040202021FE2102F90249FE4900490089FE49AA31AA12FE2AAA4AAA84A20086
+5AA6:200023FE222223FEFA224BFE480049FC490491FC510421FC3104490449148108
+5AA7:100010FC10841084FCF42494249425FE2502497A294A114A297A4502850A0104
+5AA8:21082088209027FEF89048904BFC4A944A94930C520423FC32044A044BFC8204
+5AA9:1080109E109213F2FC92249E249225D22552495E2952115229D24422842A0044
+5AAA:200021F821082108F9F84908490849F888004BFC329412942A944A9487FE0000
+5AAB:20402040207E2040FBFC480449FC48048BFC48403240127C2A40454084FE0800
+5AAC:2100217C21442244FA444E7C4A104A104AFE92385254225432944B124A108210
+5AAD:0BFE3020C1FC09043124C52409243050C08803040200FFFE08201C4003C03C38
+5AAE:204020A021102208FDF648004BC44A544A5493D45254225433D44A444A5482C8
+5AAF:20402240214027F8F888489048FC490489084BFE3202142A2AAA4A8284140008
+5AB0:2080208021FC2244F95449F4488449284A9091FC5244255431F4488449288210
+5AB1:2008203C23C02004FA44492849FC4A20482093FE502021243124492449FC8004
+5AB2:1020104011FC1154FD242554250425FC2400491229D41118291045528592010E
+5AB3:2020204021FC2104F9FC490449FC490489FC4840302010A42A8A4A8A84780000
+5AB4:2020202021FC2020FBFE480049FC4904490491FC5052209431884EA448C28080
+5AB5:0020792448A8482049FC78404BFE488849447A424DFC488849D0483048489984
+5AB6:2108210827FE2108F8004FFE490849F8490891F85108213E37C8480848088008
+5AB7:200023FE220022FCFA004BFE4AA84A908AC84A86320813FE2A884C4884080818
+5AB8:20202124212421FCF8204BFE4800482049FC9124512421FC302048244BFE8102
+5AB9:204023BE22122292FA524AAA4B2448404BFE9222522223FE32224A224BFE8202
+5ABA:2108254825482550F7DE502450145FD450149794549424A824C8549458149022
+5ABB:10783E4822482A86FF7822482A2842104A2884C60200FFFE08201C4003C03C38
+5ABC:100010F810A810A8FCD8248824F82400240049FC295411542954455483FE0000
+5ABD:200021FE212021FCF92049FC4920492089FE480232AA12AA2AAA4A0280140008
+5ABE:1088108813FE1088FDFC248827FE242025FC492429FC11242BFE450485140108
+5ABF:2020204023FC2224FA244BFC4A244A448BFC484030A810B4293C49228222041E
+5AC0:2040204027FC2040FBF848804FFC49108A684DC6304013F828E0495886440040
+5AC1:2040202023FE2202F80049FC484048A24B34905850942334305248904B508020
+5AC2:10A0112C11241124FDAC2524252425FC242049FC288810502820445080880306
+5AC3:1020102013FE1020FDFC250425FC250425FC490429FC11042BFE448881040202
+5AC4:100011FE11101120FD7C2544257C2544257C4910291011542952469282500420
+5AC5:21082088209023FCF84049F848404BFE4880910051FC2220342048204BFE8000
+5AC6:1040102013FE1202FC50248825242450248849042AFA10882888448884F80088
+5AC7:100013FE12021000FDFC250425FC250425FC4840282013FE2800448881040202
+5AC8:08202AA42CA84920145022887FFE400282040200FFFE08201C4003800C707008
+5AC9:2020201021FE2100F9204D204B3C495089904B1035FE111029284A2882440482
+5ACA:2020202023FE2020F9FC48204BFE4840488891F0502423FE302249244AA28040
+5ACB:200023DE20422042FBDE4A104A104BDE48429252514A214A325248424A948108
+5ACC:10881050100013FEFC5025FC245427FE245449FC285010D82954465284500050
+5ACD:101E11E010221112FC942480242025CE2502490229CE11022902450285FE0102
+5ACE:2040202023FC2108F8904BFE4A024C44482093FC508020F83088490849288210
+5ACF:2100209E23D22252FA544BD44A584A544BD292125292225A32D44B504A108010
+5AD0:200827C825482548F7FE5554555457D45214922457D4224822485254555488A0
+5AD1:7FFC03000D70710C01007FFC04403FF824483FF80400FFFE08201E4003C03C38
+5AD2:200E23F020442224F9084BFE4A4248404BFE908050FC214431284A104C688186
+5AD3:108010F811081210FDFC25242554258C25044810291211D4291845528592010E
+5AD4:2040202023FE2202FC1449E04900490049FC9110511027FE3000489049088204
+5AD5:100011FE1140117CFD90251025FE2528254449FE2820101029444542824A0038
+5AD6:100013FE105011FCFD54255425FC240025FC48002BFE102028A8452482A20040
+5AD7:200023FE2200227CFA444A444A7C4A004AEE92AA52AA22AA32EE4A004BFE8000
+5AD8:100011FC112411FCFD2425FC2440248825F04820284413FE2822452482220060
+5AD9:2420222022202F7EF4805400577C551455109550555C255029505B5050BEA100
+5ADA:200021F8210821F8F90849F848004BFC4A9493FC500021F83090486049988606
+5ADB:7F7848485F4C64805F7844484A4851307F4C0400FFFE08201C4003800C707008
+5ADC:202021FC20882050FBFE480049FC490449FC910451FC202033FE482048208020
+5ADD:1020101011FE1110FD7C251425FE2514257C4910299211542938465482920430
+5ADE:202023FE222022FCFA244BFE4A244AFC8A204AFC32A412FC2AA44CFC84A408AC
+5ADF:200023FE22482248FBFE4A484A204BFE4A4092FC53442244327C4A004BFE8000
+5AE0:08203E7E08A47F281C102A2849443FFE210021003FFE2210272040C043308C0C
+5AE1:2040202023FE2088F8504BFE4A224AFA4A2292FA528A228A32FA4A024A0A8204
+5AE2:11F87D0811F81108FDF8110829F824904112860E0200FFFE08201C4003C03C38
+5AE3:200027FC20402278FA404FFE490049FC4A0093FC500425543554480448288010
+5AE4:1088108813FE1088FCF8242025FC252425FC48202BFE102029FC442083FE0000
+5AE5:102013FE102011FCFD2425FC252425FC24224BFE280813FE2908448884280010
+5AE6:2020212420A823FEFA0248F84888488848F8902051FC21243124493449288020
+5AE7:102013FE102011FCFC2027FE240025FC250449FC290411FC290445FC84880104
+5AE8:1088108813FE1088FCF8242025FC252425FC482029FC10202BFE445080880306
+5AE9:2108210827C82110F11E57E45554555457D49114539425482948511451148122
+5AEA:200027BC208424A4FA944CA4485049884E2690C0531020643388483048C08700
+5AEB:2110211027FC2110F8004BF84A084BF88A084BF8304017FC28A0491082080406
+5AEC:2040202023FE2200FA484A484BFE4A488A484A48327812002D54452A8A2A1000
+5AED:2040207C204023FEFA424A784BC44A3C8A084AF0332412A82DFE442088A00040
+5AEE:11FC102013FE1222FDAC242025AC240025FC48002BFE108028FC440484280010
+5AEF:08207F20087E7E4408A4FF2810101E28224446828200FFFE08201C4003C03C38
+5AF0:2108210827C82108F11E57D25564554057C89108538825482954511451248142
+5AF1:1020102013FE1020FD2424A827FE240025FC4904297411542974450485FC0104
+5AF2:2040202027FE2490F490549057FC549054D895B855B426D42892589050908090
+5AF3:082049202A3E7F4849485DA86B10492841460400FFFE08201C4003800C707008
+5AF4:102013FE102011FCFD0425FC242025FC248848502BFE102029FC442084200020
+5AF5:2080208021FE2354FD5449544BFE49544954915457FE20003154492A4A2A8000
+5AF6:2090208821FE2110FB104DFE4910491089FE4910311011FE29004AA482520452
+5AF7:2020272025FE2540F57C5690557E5500557C9544557C2644247C54445444844C
+5AF8:1088105013FE1020FDFC242027FE252424A84BFE280011FC2904450485FC0104
+5AF9:1088108811FC1088FC8827FE242025FC252449FC292411FC2800448881040202
+5AFA:239C2294239C2294FB9C4A044AF44A944AF4929452F4229432944B344A04820C
+5AFB:200023DE225223DEFA524BDE4A224A224AFA9222527222AA33264A224A2A8204
+5AFC:200021FC212421ACF974492449FC482089FC482033FE10002AA44A5284520000
+5AFD:2020202023FE2050FA8A49044BFE4D0449FC910451FC202031244A224CA28040
+5AFE:2020212420A823FEF8A849244A224904890449DE32441554289E490482040404
+5AFF:202021FC202423FEF82449FC48204BFE480091FC512421FC312449FC480083FE
+5B00:2004203E27C02244F12853F8520853FC520493FE540226AA2AAA5A0250148008
+5B01:202027A420A82292F9144A084DF448028BF84A08320813F82A0841108FFE0000
+5B02:2110209423D22012FA5049904FFE48104BD29252525423D4324A4A4A4BD68022
+5B03:0BFE104061FC090411FC610405FC090431FCC0880504FFFE08201E4003C03C38
+5B04:202023FE202021FCF8004BFE4A0249FC480091FC510421FC310448884BFE8000
+5B05:108813FE10881000FDFC24A824A827FE24A848A829FC10202BFE442084200020
+5B06:204020A0211826E6F00053F8520853F8500097BC508424A4229454A452948108
+5B07:102011FC112411FCFC2027FE240025FC250449FC290411FC290445FC84880104
+5B08:2020202021FC2020FBFE49084B9C49084988963E500023FE309048904912820E
+5B09:102013FE102011FCFC0025FC250425FC24884BFE280011FC2904450485FC0104
+5B0A:0440FFFE044017D0F01217DC3452D7D2100E0400FFFE08201C4003800C707008
+5B0B:200023DE22522252FBDE480049FC492449FC912451FC202033FE482048208020
+5B0C:101811E0104013FEFC88257426522470240049FC29041174295445748504010C
+5B0D:2108254825482550F7DE501457E4501457D4911457D4210821085FD450248042
+5B0E:2200220823A824A8F93E57C85548555C554897C852BE228022825482547E8800
+5B0F:203C23E0212420A8FBFE48A849244A0249FC9124512421FC3124492449FC8104
+5B10:1020102010501088FD0426FA2400240025DC4954295411DC2888448885540222
+5B11:2040202021FC2088F8504BFE480049FC490491FC510421FC30204A944A8A847A
+5B12:1020105010881174FE0225FC252425AC252449FC280010F8288844F8848800F8
+5B13:2108220827C82450F7DE546457D45214511497D4521423C822485454555488A2
+5B14:22002208238824A8F93E57C85548557E554897C852BE228022A25492547E8800
+5B15:100011FC115411FCFC2025FC242027FE2488485029FC10202BFE442084200020
+5B16:00407C2045FC44887C5043FE7C20A5FC24203C200200FFFE08201C4003C03C38
+5B17:202023FE200023FCFA044AF44A944BFC480091F8510821F8310849F8480083FE
+5B18:20882448225020FCF82048504E944A388A504A98323412542A904A2085FE0800
+5B19:2020202023FE2124F9244AAA4FFE480049FC9104517421543174490449FC8104
+5B1A:202023FE22882250FBFE4A504AFC4A548BFE4A5432FC12502AD84D5486520850
+5B1B:200023FC22942294FBFC48004FFE48004BFC920453FC20A231144B084D448182
+5B1C:10207E20243EFF4200947E1042287E2842447E820200FFFE08201C4003C03C38
+5B1D:208023F8220823F8FA084BF84A004BFC8A004BFC304413FC28A0499486C80086
+5B1E:208823FE208821FCF8204BFE482049FC492491FC512421FC30204BFE482087FE
+5B1F:2104208823FE2020F9FC48204BFE48544992909053FE209030D44B8A489681A2
+5B20:10F81088108810F8FC0025DC2554255425DC48202BFE107028A8452482220020
+5B21:203C23C020442224F10857FE544252A4528A947A508020F8210852905060879E
+5B22:2080204027FE2110FA084D144BF849104BF8911057FC212833104D4849868100
+5B23:2040202023FE2222F954494A4A3A480049FC915453FE200031FC482048A08040
+5B24:2040202027FE2488F7DE548855DC56AA54889440548825F02420544859FC9084
+5B25:200023DE20422252F94A4A52489049084BFE951051FE211031FE491049FE8100
+5B26:204027FC204023FCF00057FE500253F8504097FE500027FE200857FE54A88798
+5B27:204023F8204827FEF8484BF848404FFE480092A4545223F832A84AA84FFE8000
+5B28:2108209023FE2108F9084A524B9C49088A524BDE304010A42AAA4A8A84780000
+5B29:2140224C22642244FB4C4A644AA44BAC8AA44AA437FE10002910490882040404
+5B2A:2040202023FE2202F9FC49484A5049FC4B0491FC510421FC310449FC48888104
+5B2B:208822AA22DC2488F9544A2248004BFE8A22482033FE107028A8492486220020
+5B2C:200021FC202023FEFA2249AC482049AC480093FE502021FC315449544954810C
+5B2D:200027FC22482444FFFE544456EC555456EC944456EC255426EC544454548408
+5B2E:3FFE28882F8A20082FBE28882F88289429A220803FFE2208271040E0431C9C02
+5B2F:20402FFE204027FCF00053F852085FFE580297FC511023F8204057FC50408FFE
+5B30:3EF822883EF822883EF822883EF8145022880400FFFE08201C4003800C707008
+5B31:420C2FB082204FA00ABE2FA84AA8CFA842285FA84248FFFE08201C4003C03C38
+5B32:0000F93EA92AA92AF93EAFAAAAAAFABE42904490FABE491249124A92ACAA1044
+5B33:108813FE10A81090FDFE272025FC252025FC492029FE11002BFC44888070038E
+5B34:0100FFFE20003FF800003FF820083FF8010079384FA87AA84AB8792A4AAA9C46
+5B35:21082110223E2222F4BE5722513E520854BE97AA502A20AA256A552E54088008
+5B36:104010F8108810F8FC8824F8240025FC252449FC292411FC280047FE84880108
+5B37:2040202027FE2488F7DE548855DC56AA54889440549025202448548455FC8884
+5B38:202023FE2202241CFBE0492448A84BFE4924920255FC212431FC492449FC8104
+5B39:220024EC24A424A4F6EC54A454A456EC54A494A45FFE20002110510852048404
+5B3A:23FE224823FE2248FA204BFE4A404AFC8B444A7C320013FE28404AA4828A047A
+5B3B:202023FE202021FCF8004BFE4A524BFE490491FC510421FC310449FC48888104
+5B3C:220225E224A226AAF52A566A510A528A544A9BAA510A27CA2122554251EA8E04
+5B3D:23FA22AA23FA2002F7FE540055FC555455FC940057FE204027FE50A051188606
+5B3E:2108210827CE2112F12457DE5552555E57D2911E5392255E2940511451128122
+5B3F:2110211027FC2110F1F0520852EA56AC52A892AA56EA2A06200052A452528452
+5B40:21FC202023FE2222F9AC482049AC4800489E93F2509E21D232BE4C92489E8092
+5B41:3FF801007FFE41029D7401001D7000003BB82AA83BB80400FFFE082007C07838
+5B42:221023DE25282084FBF84A084BF84A088BFA4A243298130628004BFC82940FFE
+5B43:204027FC200023B8FAA84BB849104FFC491097FC511027FE31284B104D488186
+5B44:23DE225223DE2252FBDE4A224AFA4A224AFA92AA52FA22AA32FA4A724AAA8226
+5B45:2148214C22AA2008F7FE51485368514A536A914C536C2148216A539A50268042
+5B46:23DE225223DE2252FBDE4A524BDE498C4A52904057FE20883190486048D88304
+5B47:2108229423DE26B4FBDE4A944BDE4A944BDE921057FC21083090486049988606
+5B48:222223FE209021FEFB104DFE491049FE491091FE510023FE328A4B764A528276
+5B49:208823FE208823DEFA524BDE48A0489049FE912053FC252031FC492049FE8100
+5B4A:202023FE224823FEFA484AEC4B5A4A488A504BDE325013DC2A504DDE84500850
+5B4B:23DE200023DE2252FB5A4A5248204BFE4A5093FE525223FE32924ADC4A9284CE
+5B4C:210447C88812F3BC20084B92F83E0380AAAAABAA0200FFFE08201C4003C03C38
+5B4D:27BC24A427BC2000F7FE54005590549E57D4956455D4255425D455685BC89054
+5B4E:23FE220223FE2292FA544A924AFE4AAA4AFE932252FA22AA32FA4A224DFA8004
+5B4F:208823FE208823DEFA524BDE4A524BDE4A2293FE52AA22FA32224A724AAA8224
+5B50:00007FF800100020004001800100FFFE01000100010001000100010005000200
+5B51:00007FF800100020004001840118016003801D00E10041000100010005000200
+5B52:00007FF80010002000400180010001FE01000100010001000100010005000200
+5B53:00007FF800100020204011800900050003000100018001400130010C05000200
+5B54:00407E4002400440084008400A400C403840C8400840084208420842283E1000
+5B55:00003FF008100820083C100417C4205440880100FFFE01000100010005000200
+5B56:00007EFC02040408081008200A200DFE3820C820082008200820082028A01040
+5B57:020001007FFE400280041FE0004000800100FFFE010001000100010005000200
+5B58:04000400FFFE0800080013F810103020504097FE104010401040104011401080
+5B59:00207E2002200420082008A80AA40CA43922C9220A2208200820082028A01040
+5B5A:00F87F0022101110112000001FE0004000800100FFFE01000100010005000200
+5B5B:010001003FF8010001007FFE400280040FE000400080FFFE0100010005000200
+5B5C:0040FC400440088010FE1108168818883088D050105010201050108851042202
+5B5D:020002083FD002200240FFFE010002003FE0104020805FFC8080008002800100
+5B5E:00001FE0004000800100FFFE0100010005000200091049084824482487E00000
+5B5F:00001FE000400180FFFE01000100050002003FF82448244824482448FFFE0000
+5B60:00003FF800087FC800083F8820883FA800103FE000800100FFFE010005000200
+5B61:00207E2002200440084808840BFE0C823800C8FC088408840884088428FC1084
+5B62:0080FC8005FC0904120415F4151419143114D1F4110411281112110250FE2000
+5B63:00701F80010001007FFC054009203118CFE600400080FFFE0100010005000200
+5B64:0008F83C0BD01290229022902A9032902290E288228822C822A424D4A4924800
+5B65:10001000FEFC2244642818102428C2C600003FE000800100FFFE010005000200
+5B66:22081108111000207FFE400280041FE000400180FFFE01000100010005000200
+5B67:0820102022FC7C24082412447F54008801003FE000800100FFFE010005000200
+5B68:00001FE000800100FFFE0100010005007A7C080810101EFEF010101050502020
+5B69:0020FC1004100BFE10201042148419F83010D02210C413081010102850C42302
+5B6A:02000100FFFE0440145014482444444400003FE000800100FFFE010005000200
+5B6B:000CFDF004200844108811F01420184431FED022102010A81124122250A02040
+5B6C:7FFC008003600D1871040100100010FCFE042208221064FE141008103450C220
+5B6D:0000FDFC0504090411FC1104150419FC3104D10411FC10001088108451022202
+5B6E:0040FC2007FE0A02100011FC1400180033FED020112811241222142250A02040
+5B6F:00007EFC48447E4442287E1048287EC600003FE000800100FFFE010005000200
+5B70:10400840FF4000407EF842487E4801487EC8044808680E5AF88A088A29061202
+5B71:3FFC20043FFC200023F020203FFE204020C02FBE210423885E7E42088A280410
+5B72:0000FDFE04480848104811CE150219023102D1CE104810481048104853FE2000
+5B73:082004407FFC12483CF0082014503EF800003FE000800100FFFE010005000200
+5B74:1FE00040FFFE010003007C7C08081EFEF010105030201FF010101FF010101FF0
+5B75:200ECEF08A22AA92AA54EE00AA7CAA08AA10AA10EEFEA8102810481048508820
+5B76:0820FFFE082012483CF0082014503EF800003FE000800100FFFE010005000200
+5B77:08203E7E08A47F281C102A2849443FFE200023F0202020402FFE404041408080
+5B78:0A803138228838382288393822887FFE4002BFE400800100FFFE010005000200
+5B79:3E1022FE3E4420287EFEA2103EFC221000003FE000800100FFFE010005000200
+5B7A:0000FDFC04200BFE122211AC142019AC3000D3FE102011FC115411545154210C
+5B7B:0020FDFC04240BFE102411FC14201BFE3000D2A4145211FC1154115457FE2000
+5B7C:52107EFE28447E28A2FE3E1020103E7C22103E1000001FE00040FFFE01000300
+5B7D:0820FFFE28207DFC44887C5041FE7C2045FC7C2000001FE00040FFFE01000300
+5B7E:03DEFA520BDE125223DE22522BDE318C2252E04027FE208821902060A0D84304
+5B7F:210447C88812F3BC20084B92F83E0380AAAAABAA00001FE00040FFFE01000300
+5B80:0200010001007FFE400280040000000000000000000000000000000000000000
+5B81:0200010001007FFE4002800400003FF801000100010001000100010005000200
+5B82:0200010001007FFE4002800400000FE0082008200820102010222022401E8000
+5B83:020001007FFE4002800408000808083009C00E00080008040804080407FC0000
+5B84:0200010001007FFE4002820402001FE0022002200420042008221022201E4000
+5B85:020001007FFE40028004002003F03E00020003FCFE0002040204020401FC0000
+5B86:020001007FFE400280043FF8000800083FF8200020003FFC0004000400280010
+5B87:020001007FFE400280043FF8010001000100FFFE010001000100010005000200
+5B88:020001007FFE4002804400400040FFFE00400040104008400840004001400080
+5B89:020001003FFC2004420802000200FFFE0420082018400640018002600C107008
+5B8A:0200010001007FFE40028104012001107FFC010002800280044008203018C006
+5B8B:020001007FFE40028104010001007FFC03800540092011102108C10601000100
+5B8C:020001007FFE400280041FF0000000007FFC044004400440084408441044603C
+5B8D:020001007FFE40028204010000800000FFFE0000044004200810100820044004
+5B8E:020001007FFE4002800400F03F0001000100FFFE01000280044008203018C006
+5B8F:020001007FFE4002820402007FFC04000480088009001100222044108FF80408
+5B90:020001007FFE40028404040007F00810081014202220014000400080FFFE0000
+5B91:020001007FFE4002882408203FF8082008200820FFFE08201020102020204020
+5B92:020001007FFE4002800400F83F00010001F83F00010001FC7F020102010200FE
+5B93:0200010001007FFE400281040090089048244842488289020E101810E7F00000
+5B94:020001007FFE4002820401007FFC0100010001003FF8010001000100FFFE0000
+5B95:020001007FFE4002800400007FFC0400040008001FF82808C80808080FF80808
+5B96:020001007FFE400280047E10021002103E10202040287E24024402FE14420800
+5B97:0200010001007FFE400280041FF0000000007FFC010011101108210445040200
+5B98:020001007FFE400280041FF0101010101FF0100010001FF8100810081FF81008
+5B99:020001007FFE4002810401003FF82108210821083FF82108210821083FF82008
+5B9A:020001007FFE4002800400003FF801000100110011F811001100290047FE8000
+5B9B:020001007FFE400290041EF812882288228852A88C90048208821082207E4000
+5B9C:020001007FFE400280041FF0101010101FF0101010101FF010101010FFFE0000
+5B9D:020001007FFE4002800400007FFC0100010001003FF8010001200110FFFE0000
+5B9E:020001007FFE4002888404800480108008800880FFFE01400220041018086004
+5B9F:020001007FFE4002810401003FF801001FF001007FFC0280044008203018C006
+5BA0:020001007FFE4002842404100410FFFE04800888089010A010C220824182867E
+5BA1:020001007FFE410281043FF8210821083FF8210821083FF82108010001000100
+5BA2:020001007FFE400288040FF010202C4003801C70E00E1FF0101010101FF01010
+5BA3:020001007FFE400280043FF800001FF010101FF010101FF010100000FFFE0000
+5BA4:020001007FFE400280043FF8040008201FF0011001003FF801000100FFFE0000
+5BA5:020001007FFE420282047FF804000FF018102FF048108FF00810081008500820
+5BA6:020001007FFE400280043FF8210021003FF02010201020103FF0210021003FFC
+5BA7:020001007FFE400280043FFC2080208027F82408240827F8208020803FFE0000
+5BA8:020001007FFE4002800404404448245024600C403460C852084A1042203E4000
+5BA9:020001007FFE410291140920054001007FFC0540092011102108C10601000100
+5BAA:020001007FFE4002810411001FF821000100FFFE04400440044008423042C03E
+5BAB:020001007FFE400280041FF0101010101FF000003FF82008200820083FF82008
+5BAC:020001007FFE4002809400883FFC208020883E88225022502A244454418C8604
+5BAD:020001007FFE400280043FF80408FFFE04083FF808001FF8280848088FF80808
+5BAE:020001007FFE400280041FF0101010101FF0020004003FF8200820083FF82008
+5BAF:020001007FFE4002810C1FD00120FFFE01001FF0082030C0CFFC008002800100
+5BB0:020001007FFE420281043FF8000008200440FFFE010001007FFC010001000100
+5BB1:020001007FFE40028884088010FE11403240547C90401040107E104010401040
+5BB2:020001007FFE400280041FF0101010101FF00100FFFE054009203118C1060100
+5BB3:020001007FFE400281043FF801001FF00100FFFE01001FF0101010101FF01010
+5BB4:020001007FFE40029FF410101FF010101FF00400FFFE08201C4003800C703008
+5BB5:020001007FFE40029114092001001FF010101FF010101FF01010101010501020
+5BB6:020001007FFE400280047FFC02000D08719002A00CC071A006981886E2800100
+5BB7:020001007FFE400280F43F00111009200100FFFE0380054009203118C1060100
+5BB8:020001007FFE400280043FF820002FF020003FFC248824504420451886060400
+5BB9:020001007FFE4002882411102288044008203018DFF61010101010101FF01010
+5BBA:020001007FFE40029FF4101010101FF00000FFFE09200920112011222122411E
+5BBB:020001007FFE4002BFF410104824244803801C70E00E0100210821083FF80008
+5BBC:020001007FFE400280243E2001FE00447E4414C814281410146A2586240243FE
+5BBD:020001007FFE400284443FF8044000001FF0101011101110129004821882E07E
+5BBE:020001007FFE400280741F80100010001FF810801080FFFE0000084010202010
+5BBF:020001007FFE400288040FFC1040308053F89208120813F81208120813F81208
+5BC0:020001007FFE4002801400F83F001110082001007FFC054009203118C1060100
+5BC1:01007FFE400281047FFC01003FF80108FFFE01083FF8110011F8290047FE8000
+5BC2:020001007FFE400288040F7C08440844FF44002808282A104910892828441082
+5BC3:020001007FFE48028FE4102020405FF8110811081FF8028004A008921082607E
+5BC4:020001007FFE420282043FF804800840FFFE00101F90109010901F9000500020
+5BC5:020001007FFE40029FF401001FF0111011101FF0111011101FF0044008201010
+5BC6:020001007FFE40028224094028884B141C10E7F001002108210821083FF80008
+5BC7:020001007FFE400280243E38002000207EF814081450142014542484240443FC
+5BC8:01007FFE4102BFFC01001FF00100FFFE00001FF010101FF010101FF010101030
+5BC9:020001007FFE490288841FFC108030805FF8908010801FF8108010801FFC1000
+5BCA:020001007FFE420283F402003FF820083FF820083FF820083FF8082010102008
+5BCB:020001007FFE4822BFFC08203FF80820FFFE10102FE8C82608A00848080807F8
+5BCC:020001007FFE4002BFFC00001FF010101FF000003FF821083FF821083FF82008
+5BCD:020001007FFE4002820409084924482487E000003FF8244824482448FFFE0000
+5BCE:020001007FFE4002840425FC24203C2005FC05247D2425542594250445148508
+5BCF:020001007FFE48028FE410403FF852481428110801007FFC028004401830E00E
+5BD0:020001007FFE40028424242025FC3C20042007FE7C6024B02528262644208420
+5BD1:020001007FFE40028BFC080811F8300853F8900017FC140413F8111010E0171C
+5BD2:020001007FFE44429FF404403FF80440FFFE082013102088C046060001800040
+5BD3:020001007FFE40029FF411101FF011101FF001003FF8210821482FE824282010
+5BD4:020001007FFE40029FF410101FF010101FF000007FFC110011F8290047FE8000
+5BD5:020001007FFE4002BFFC02003FF8244824483FF80000FFFE0100010005000200
+5BD6:020001007FFE4002A3FC100811F8800843F8500017FC2404E3F8211020E0271C
+5BD7:01007FFE420281440880292847E4180061003FF821083FF82108FFFE20082018
+5BD8:01007FFE4102BFFC01001FF010101FF010101FF010101FF01010FFFE08201010
+5BD9:020001007FFE40028004061C38E828A82CA82AA82AA82AA828A455545D748212
+5BDA:020001007FFE4002BFFC01001FF001007FFC10001FF02100FFFE010021083FF8
+5BDB:020001007FFE4822BFFC08201FF010101FF010101FF010101FF004421842E03E
+5BDC:020001007FFE41029494142823E800003FF824482448FFFE0100010005000200
+5BDD:01007FFE4002800413F8100891F8500853F8100037FC540493F8111010E0171C
+5BDE:01007FFE400284443FF804401FF010101FF010101FF002007FFC04401830E00E
+5BDF:01007FFE400290841EF822885450282017D82006DFF001001110210845040200
+5BE0:020001007FFE4102BFFC2108FFFE21083FF811101FF00400FFFE082007C07838
+5BE1:01007FFE4002BFF404001FF010101FF010101FF01010FFFE082037D8C2460CC0
+5BE2:01007FFE4002840424FC2404247C3C0404FC04007DFE250224FC2448443085CE
+5BE3:020001007FFE4042842425FC24003CF8040004F87C0024F82488248844F88488
+5BE4:020001007FFE400285FC242024F83C48044805FE7C0024FC2484248444FC8484
+5BE5:01007FFE4002BCFC24481428254806C01830E30E0C403180063038C007003800
+5BE6:01007FFE40029FF41110FFFE22103FF010101FF010101FF010101FF008201010
+5BE7:01007FFE4102949414A823E800003FF82448FFFE00003FF80100010005000200
+5BE8:01007FFE44429FF404403FF80440FFFE082011102FE8C1060920111025080200
+5BE9:01007FFE400280FC3F0011100920FFFE09203018DFF611101FF011101FF01010
+5BEA:01007FFE400280FC7F00221011201FE010201FF010101FFC20042AA44AA4800C
+5BEB:01007FFE400282041CF010101EF010101FF008001FFC20044924249424944008
+5BEC:020001007FFE4822BFFC08201FF010101FF010101FF010101FF00452184AE03E
+5BED:01007FFE4102BFFC01001FF011101FF011101FF001087FFC02044908482487E4
+5BEE:01007FFE400281047FFC044028281FF02828CFE608200FE00100111025080200
+5BEF:01007FFE490288841FFC30805FF890801FF810801FFC10003E7C224423D42008
+5BF0:01007FFE4002BFFC24483FF80000FFFE00001FF010101FF005081890EA600C1C
+5BF1:020001007FFE404289FC490449FC490479FC090409FCF8204BFE48A849248A22
+5BF2:020001007FFE4002A47C3A0422281E1020FE3E124850085E7F5014B0229E4100
+5BF3:01007FFE4082BEFC09243EA809247EA000401FF010101FF010101FF008201010
+5BF4:020001007FFE400288047F7C2244147CFF44087C7F44087C2A28492AA94A1086
+5BF5:0100FFFE88427F7C2240147CFF04007C7F40417C7F40417C7F40417C4542423E
+5BF6:01007FFE4082BEFC09203EFC08207EA400FC1FF010101FF010101FF008201010
+5BF7:01007FFE48229D7449245D7449245D7449247FFC00007FFC10101FF00820FFFE
+5BF8:0040004000400040FFFE00400040004010400840084000400040004001400080
+5BF9:0010001000107E1002FE02102410149008500850141012102210401000500020
+5BFA:0100010001003FF801000100FFFE002000207FFC082004200420002000A00040
+5BFB:00003FF8000800081FF8000800083FF800200020FFFE08200420042000A00040
+5BFC:00003FF0201020103FF0200420041FFC00200020FFFE08200420042000A00040
+5BFD:000801FC7E0002082108111010400040FFFE0040104008400840004001400080
+5BFE:2010101010100010FEFE04100410489028501050101028102410441080500020
+5BFF:020002007FFC02003FF80400FFFE082008201FFC102024204220822000A00040
+5C00:000800087F884008407E5F0851085148512851285F08510840087F8800280010
+5C01:0808080808087F08087E0808FF080048082808287F08080808080F08F0284010
+5C02:01000100FFFE01003FF821083FF821083FF80020FFFE08200420042000A00040
+5C03:012001107FFC01003FF821083FF821083FF821080020FFFE0820042004A00040
+5C04:080810083E0822083EFE22083E0822082248FE2806280A08120822084A280410
+5C05:08080808FF08080808FE7F08414841287F281408140814282412240243FE8000
+5C06:088008F809084A1028A0284008900B1018102BFEC81009100890081008500820
+5C07:0440247C24C4252824903CA004480588FC0825FE240824882448440884280410
+5C08:01007FFC01003FF821083FF821083FF80104FFFE0022FFFE0820042004A00040
+5C09:00043F84208420843FBE20042F84202420143FD422042A844A4452448A140408
+5C0A:08200440FFFE04403FF82848303827C820083FF80020FFFE0820042004A00040
+5C0B:00003FF000101FF000103FF000003E7C08447F7C0020FFFE0820042004A00040
+5C0C:08080808FF880808087E7F0800087F48412841287F08000822081788F8284010
+5C0D:1408140855083608147EFF080008224814287F2808083E0808080F0878282010
+5C0E:211017FE108003F8F20813F8120813F8120813F8280047FE0020FFFE08200460
+5C0F:0100010001000100010011101108110421042102410281020100010005000200
+5C10:01000100010009200910110811042104410001000000180024000380007E0000
+5C11:010001000100092009101108110421144110012000400080010002000C007000
+5C12:010001000280044008203118C106010009200910110821044104010005000200
+5C13:0800080008001FFC100021004100810001001110110821044102810205000200
+5C14:0800080008001FFC100421084100810001001110110821044102810205000200
+5C15:00003FF008100820083C10041004211441080920091011082104410405000200
+5C16:01000100092009101108210800000104FFFE01000280028004400830300EC004
+5C17:0200020003F8020002000200FFFE010001000920111021084104010005000200
+5C18:01000100092009101108210441040000010001003FF8010001000100FFFE0000
+5C19:010011101108210441043FF82008200827C824482448244827C8200820282010
+5C1A:010021081110092001003FF82008200827C824482448244827C8200820282010
+5C1B:0100010009200910110821044104101010101010545452529292101050502020
+5C1C:010009201110210800000100FFFE02800C603018C10609200910110825080200
+5C1D:01001110092001007FFE400280041FF0000000007FFC0400082010103FF81008
+5C1E:010001007FFC2288145008203FF8D0161FF010101FF001001110210845040200
+5C1F:00103E1022103E5422523E520090FF12080408082F102860298058004FFE8000
+5C20:22102210FF1022103E5422523E5222902210FF1440045408620840107E2000C0
+5C21:100011FC9104550459FC1104FD0429FC2800291229D429182B104D524992810E
+5C22:0400040004000400FFFE048004800480048008800880108210822082407E8000
+5C23:04400420081010082004444284420440044004400440084208421042203E4000
+5C24:0420041004100400FFFE048004800480048008800880108210822082407E8000
+5C25:20802080208021F8FD082A082888284828482808280828502822480247FE8000
+5C26:004024402240427C808425042444242424242404240424282412440243FE8000
+5C27:0200020002FC7F20014000840764381C0000FFFE04400440044008423042C03E
+5C28:0420041004100400FFFE049004A004C8049008A408C8109210E221824E7E8000
+5C29:000024FC22204220802024F8242024202420242025FC24002402440243FE8000
+5C2A:200023F820402040FC40284029F028402840284028402BF82802480247FE8000
+5C2B:000001FCFE202420242025FC242024202420242027FE24002400440243FE8000
+5C2C:2020202020502088FD042A022888288828882888290829082A0A480247FE8000
+5C2D:010001007FFC010009200820FFFE082008207FFC04400440084010422042C03E
+5C2E:200023F820882090FCBC290429142A4828402BFC28E029502A4A484247FE8000
+5C2F:2080208021F82208FDFE2900297829482968295029442A442C3E480247FE8000
+5C30:203C21E0202023FEFC2029FC292429FC292429FC282029FC28204BFE480287FE
+5C31:20401050FE48004800407DFE4450445044507C501090549092921112510E2200
+5C32:2088205023FE2050FDFC28542BFE285429FC285028D829542A52485247FE8000
+5C33:20F8208820E820A8FDFC290428F8288828F8288828F82888288848AA489287FE
+5C34:2090229022BC22D0FE882A8828002BF82AA82AA82AA82FFE2802480247FE8000
+5C35:202021FC212421FCFC202BFE290429FC290429FC290429FC28884906480287FE
+5C36:03E8FE882BCE2A502BE42A822BE0280029FC2954295429542BFE480247FE8000
+5C37:23E8228823CE2250FFE42A822BE0280029FC2954295429542BFE480247FE8000
+5C38:00001FF810081008100810081FF8100810001000100010002000200040008000
+5C39:000000003FF004100410FFFE041004103FF00410040008000800100020004000
+5C3A:00001FF810081008100810081FF8108010801080104010402020201040088006
+5C3B:00003FF8200820083FF8210021002FE0212021202220222044224422881E1000
+5C3C:00001FFC1004100410041FFC10001200120C123013C012022202220241FE8000
+5C3D:00001FF81008100810081FF81048104010202310208840068C00030000800040
+5C3E:00003FFC200420043FFC200020F02F00210021F02F00210021F85F02410280FE
+5C3F:00003FF8200820083FF82080208020882ED022E022A024A04490488892840100
+5C40:00003FF8200820083FF8200020003FFC200427E42424242447E4400480280010
+5C41:00003FF8200820083FF820002840284028442F4828502860484449448A440C3C
+5C42:00003FFC200420043FFC200020002FFC200020003FFE2100221044084FFC8404
+5C43:00003FFC200420043FFC2000200027FC240424442444244424B4410846049802
+5C44:00003FFC200420043FFC208020402FFE28023124212022102210440848049002
+5C45:00003FF8200820083FF8208020803FFE208020802FF82808480848088FF80808
+5C46:00003FFC200420043FFC2000208028842BE4288428842FF4280448044FFC8004
+5C47:00003FFC200420043FFC200027FC24442444244427FC24442444444447FC8404
+5C48:00003FF8200820083FF820802888288828882FF820803084508450849FFC0004
+5C49:00003FF8200820083FF820902490249024903FFC2490249044F04400840007FE
+5C4A:00003FF8200820083FF82080208020802FF8288828882FF8488848888FF80808
+5C4B:00003FFC200420043FFC20002FFC2100221027F8208820802FFC40804080BFFE
+5C4C:00003FFC200420043FFC200027FC2404240427FC20402FFE2842484A48448040
+5C4D:00003FFC200420043FFC200020003FFE2420242427A828B0352042224422981E
+5C4E:00003FFC200420043FFC2080249022A020803FFC21C022A02490488850868080
+5C4F:00003FF8200820083FF8241022202FF8222022203FFC22204220442084200820
+5C50:00003FFC20043FFC2020242029FE3020222025FC2C8434884450442084D80706
+5C51:00003FF8200820083FF82080249022A02FF828082FF828084FF8480888280810
+5C52:00003FFC20043FFC20002FF828002BF828002FFC2A482A5052205298A3060200
+5C53:00003FFC200420043FFC200027FC240427FC240427FC240427FC411042088404
+5C54:000002FE3C822082208220FE3E8024A024A224A424B82EA0F1224122021E0400
+5C55:3FFC200420043FFC222022203FFC222022203FFC244024442428451046088406
+5C56:00003FFC20043FFC210020802FF8241022203FFC208020804FF8408080800080
+5C57:00083F082108217E3F08204823283C2827083C0827A83C122402440243FE8000
+5C58:00003F7E210221043F082008237E3C0827083C0827883C2A2412440243FE8000
+5C59:00003FFC20043FFC20002EFC2A082AE82CA82AA82AA82AE84AA84E0888280810
+5C5A:00003FFC20043FFC20003FFE20802FFC28842CA42A9428844CA44A948884080C
+5C5B:00003FFC200420043FFC210822102F7C221022103F7E22102210441044108810
+5C5C:00003FFC200420043FFC222824A82AA823FE24A82CA834A824B8448044FE8400
+5C5D:00003FFC200420043FFC212021202F3C212021202738212021204F3C41208120
+5C5E:00003FFC20043FFC20002FF820802FF828882FF820803FFC509457F490141008
+5C5F:3FFC20043FFC200024883FFE248824F8240027FC20402FFE415042488C460040
+5C60:00003FFC20043FFC2080208827F020A03FFE208023F826085BF8420883F80208
+5C61:3FFC20043FFC249022A03FFC22A02490288821003FFC2210472040C083300C08
+5C62:3FFC20043FFC20802FF828883FFE28882FF8249027F021005FFE441083E01C1C
+5C63:3FFC20043FFC22102410289C3090229025FE2C103490249C44904550863E0400
+5C64:3FFC20043FFC221021202FFC2A9429A42FFC200027F8240847F8440887F80408
+5C65:3FFC20043FFC210029FE320021FC250429FC390429FC288049FC4A8888700B8E
+5C66:00003FFC20043FFC2000252428A831FC24A8292438402BFE4888499088700B8C
+5C67:3FFC20043FFC244825482BFE354825782D0035FE242027FE44A8452486220420
+5C68:3FFC20043FFC242029FC312423FE25242DFC34A824F8244045FE44888470058C
+5C69:3FFC20043FFC220025FC284033FE24882D74365225FC2504457445548574050C
+5C6A:3FFC20043FFC20402FFE288227FC21102BFA260C2BFA220843F84040844808C4
+5C6B:3FFC20043FFC200022FE2A202BFE2E4422BA23283EFE2A824ABA4AAA92BA2286
+5C6C:3FFC20043FFC249022A024902FF829482FFC24842FF4349447F440948FF40008
+5C6D:3FFC20043FFC220823F8220823F8211022082FBE28A22FBE48A24FBE851408A2
+5C6E:01000100210821082108210821083FF801080100010001000100010001000100
+5C6F:010001000100FFFE010021082108210821083FF8010001020102010200FE0000
+5C70:101008100820FFFE010001002108210821083FF802080400040008003000C000
+5C71:01000100010001002108210821082108210821082108210821083FF800080000
+5C72:0008007C078078000100010001002108210821082108210821083FF800080000
+5C73:060001000280044008203118C10601002108210821082108210821083FF80008
+5C74:010001002108210821083FF8020002007FF80208040804080808100820504020
+5C75:01002108210821083FF8000000003FFC20002000200020002000400040008000
+5C76:010001002108210821083FF8000000007FF8040804080808080810082050C020
+5C77:1000100013F810885490549054A054BC5484548455045D046504020402280410
+5C78:1000100011FC102054205420542054205420542054205C206420002003FE0000
+5C79:10401040108010FE5500560054FC54085410542054405C806502010200FE0000
+5C7A:1000100011F8100854085408540855F85508550055005D006502010200FE0000
+5C7B:1000100011FC104454445544554455445544564454445C846484010402280410
+5C7C:1000100013FC109054905490549054905490549054905C9265120112020E0400
+5C7D:100011FC1020102054205420542057FE5420542054205C206420002000200020
+5C7E:102010201020102055245524552455245524552455245D24652401FC00040000
+5C7F:104010401040107E54405480548054FC5404540454045DF46404000400280010
+5C80:0100010021082108210821083FF80000010041044104410441047FFC00040000
+5C81:01002108210821083FF80200020007F00810141022200140008003001C00E000
+5C82:01002108210821083FF8000000003FF00010001000103FF02000200420041FFC
+5C83:01002108210821083FF8000000003FF802081208120822080408080810506020
+5C84:100010FC10841084548454FC54845484548454FC54845C846504010402140408
+5C85:1008101C11E01100550055FC554455445544552855285D106510022802440482
+5C86:1008103C11E010205420542057FE54205420545054505C506488008801040202
+5C87:01002108210821083FF800000C0070FC4084408440844C847094408800800080
+5C88:100011FE1008108854885488550855FE5418542854485C886508020800280010
+5C89:10801080108010FC55545654545454945494552456245C446444008401280010
+5C8A:00003FF8210821083FF82000200220021FFE010001002108210821083FF80008
+5C8B:100013FC1084108854885490549C54845544554455285D286610022804440182
+5C8C:0100210821083FF800003FF0082008400CF80A08111010A0204020A043188C06
+5C8D:100011FC1088108854885488548857FE5488548854885C886488010801080208
+5C8E:101010901090108855085504560455FA5488548854885C886508010802280410
+5C8F:100011FC10001000540057FE549054905490549054905C9265120112020E0400
+5C90:10201020102013FE54205420542055FC5484548854485C506420005001880606
+5C91:0100210821083FF80100028004400A203118C1061FE000200040004000800100
+5C92:10201020105010505488554456225420540055FC54045C086408001000100020
+5C93:1008101C10E010805480548054FE54885488548854885C886508010802080408
+5C94:0440082010102FE8C4260420082010A06040010001002108210821083FF80008
+5C95:01002108210821083FF801000280044008203458C44604400440084008401040
+5C96:100011FE1100110455445528552855105510552855285D446584010001FE0000
+5C97:0100210821083FF800003FF82008204824482288210822882448280820282010
+5C98:100011FC1104110455245524552455245524555454505C90649001120212040E
+5C99:001000F83F00010002007FFC044008203018C10601002108210821083FF80008
+5C9A:0100210821083FF800001FF0101010501450129011101292244A284A40068002
+5C9B:010002001FF0101012101150102010001FFC0204222422243FE4000400280010
+5C9C:0100210821083FF800003FF82108210821083FF820002002200220021FFE0000
+5C9D:0100210821083FF8080008001FFC2400440087F00400040007F8040004000400
+5C9E:10801080108010FE554055405640547C5440544054405C7E6440004000400040
+5C9F:10201020102011FC5524552455245524552457FE54205C506450008801040202
+5CA0:100010FE10801080548054FC548454845484548454FC5C806480008000FE0000
+5CA1:00007FFC40044824442444445FF4410441044924492449244FE4400440144008
+5CA2:0100210821083FF800000000FFFE001000101F90109010901F90001000500020
+5CA3:10801080110011FC5604540455E455245524552455E45D246404000400280010
+5CA4:20402020202023FEAA02AC04A800A890A890A890A888B908C908010402040402
+5CA5:10101010101011FE55125514551055FC5544554455285D286510022802440482
+5CA6:01002108210821083FF80200010001007FFC00001010082004400000FFFE0000
+5CA7:0100210821083FF800007FF80408080810502020DFF81008100810081FF81008
+5CA8:100010F810881088548854F854885488548854F854885C886488008803FE0000
+5CA9:01002108210821083FF8000000007FFC040004000FF818082808C8080FF80808
+5CAA:0100210821083FF804403FF8044804481FF8144024403FFC0844105420484040
+5CAB:102010201020102055FC552455245524552455FC55245D246524012401FC0104
+5CAC:100011FC11241124552455FC55245524552455FC55245C206420002000200020
+5CAD:1020102010501050548855245612541055FC540454085C886450002000100010
+5CAE:10201010101011FE5502560454805488549054A054C05C8264820082007E0000
+5CAF:100011FE1010101054205420546854A45522562254205C206420000003FE0000
+5CB0:2010209020902110A97EAA52AB92A892A912A912AA52BBD2C8620022004A0084
+5CB1:089008881080309E57E0908010441034110C010021082108210821083FF80008
+5CB2:100011FC110411045504550455FC54505450545054505C9264920112020E0400
+5CB3:00701F80100010001FF8108010801080FFFE010001002108210821083FF80008
+5CB4:1008101C10E0108054805480548054FE5488548854885C886488008801FE0000
+5CB5:102010201020102055FE54205420542055FC550455045D046504010401FC0104
+5CB6:10201020104011FC550455045504550455FC550455045D046504010401FC0104
+5CB7:100011FC11041104550455FC5520552055FE552055205D106512014A01860102
+5CB8:0100210821083FF800003FFC20002FF8208020803FFE20804080408080800080
+5CB9:100013FC108410845484550455145608540055FC55045D046504010401FC0104
+5CBA:0100210821083FF8010002800C603218C1061FE0002000400C80030000800040
+5CBB:1004101E11F0111055105510551055FE5510551055105D08650A014A01A60112
+5CBC:100011FC10201020552454A454A8542057FE542054205C206420002000200020
+5CBD:0100210821083FF8020002007FFC0400090011003FF801001110210845040200
+5CBE:1020102010201020543E54205420542055FC550455045D046504010401FC0104
+5CBF:0100210821083FF8000008004BF848084808480849F848084808100813F82008
+5CC0:01002108210821083FF80000010001003FF8210821083FF8210821083FF82008
+5CC1:0100210821083FF800000C0070FC4084448444845C8464944888088010806080
+5CC2:10401040107C108455885650542054505488570654605C10640800C000200010
+5CC3:020821081110102000007FFE400281040100210821082108210821083FF80008
+5CC4:100013FC110410885450542054D85726542055FC54205C2067FE002000200020
+5CC5:1020102010401088550457FE54025488548857FE54885C886508010802080408
+5CC6:10201020105010885504560255FC5400540055FC55045D046504010401FC0104
+5CC7:0100210821083FF8010002800C603018CFE600001FF01010101010101FF01010
+5CC8:2080208020F82108AB10ACA0A840A8A0A918AA06ADF8B908C908010801F80108
+5CC9:0100210821083FF808000FF010202C4003801C70E00E1FF0101010101FF01010
+5CCA:040008003FF0201020103FF020003FF8200820083FF80100210821083FF80008
+5CCB:1080108011FC1104560455E45524552455E4552455245DE46504000400280010
+5CCC:100011FE102010405488550455FE54225420542055FE5C206420002003FE0000
+5CCD:2020202021FC2024ABFEA824A9FCA820A820A9FCA820B820CBFE002000200020
+5CCE:0100210821083FF800003FF020103FF020103FF02208211020A024402830300E
+5CCF:100013FE10201020544055FC555455545554555455545D546554014401140108
+5CD0:10201010101013FE54205442548455F85410542254C45F086410002800C40302
+5CD1:0100210821083FF801000280044008203018CFE6010001001FF0010001007FFC
+5CD2:100011FE11021102557A55025502557A554A554A554A5D7A65020102010A0104
+5CD3:1020102013FE102055FC542455FC552055FE5422542A5C546450008801040202
+5CD4:10401040104411F45448545057FE54405480558456985CE064820082007E0000
+5CD5:0100210821083FF802000100FFFE00001FF0101010101FF0101010101FF01010
+5CD6:20402020202023FEAA02AC44A840ABFEA888A888A908B8D0C820005000880304
+5CD7:1040104010FC1104560855FE5500557C5544554455545D4865420242023E0400
+5CD8:100013FE1000100055FC5504550455FC5504550455FC5D046400000003FE0000
+5CD9:10201020102011FC5420542057FE5408540855FE54085C886448000800280010
+5CDA:0100210821083FF8000002007FFC04401830E10E01001FF0010001007FFC0000
+5CDB:0100210821083FF800047F84082408241F24212451240A24040408043014C008
+5CDC:0100210821083FF801000280044008203118C10609F00900090009007FFC0000
+5CDD:0100210821083FF800003FF820082FE8200827C82448244827C8200820282010
+5CDE:0100210821083FF808001FE020205FFC900017F0141014542424240443FC8000
+5CDF:0100210821083FF8040004007FFC08001FF028104FF088100FF0081008500820
+5CE0:10201020103E1020542055FE5400540055FE542054285C246422002000200020
+5CE1:10201020102011FC5420552454A454A8542057FE54505C506488008801040202
+5CE2:2002200227E2210AA90AA9EAA92AAA2AAB2AAAAAAC4AB84AC8820102020A0404
+5CE3:1080108010BC13C05450542454D4570C540057FE54905C9065120112020E0400
+5CE4:1008103C11E01020542057FE545054885504568A54885C886488010801080208
+5CE5:1080108010F81108561055FC5424542455FE542454245DFC6424002000A00040
+5CE6:02000100FFFE044014501448244444440100010021082108210821083FF80008
+5CE7:10401020102013FE54005488550456025488548854505C506420005000880306
+5CE8:101010D813941094549057FE54905494549454D857985C9064AA00CA02860102
+5CE9:010041047FFC0000064038500848FFFE084008400E2478280812082A28C61302
+5CEA:10001050104810845524542054505488550656F854885C886488008800F80088
+5CEB:200027DE20922292AA94AA94ABD8A894A992A992AA92BA9ACC94089002900110
+5CEC:1028102413FE1020542055FC5524552455FC552455245DFC652401240124010C
+5CED:1020112410A410A8542055FC5504550455FC550455045DFC6504010401140108
+5CEE:200023F820882088AFFEA888A888ABF8A900A900ABF8BD08C908010801F80108
+5CEF:010041047FFC08001FF0282007C01830E10E1FF001001FF001007FFC01000100
+5CF0:1040104010FC10885550542054D8572654F8542054F85C2067FE002000200020
+5CF1:000045FC2824102429FC484488440BFE18002820482089240924092451FC2004
+5CF2:0100210821083FF800000608780808480848FF481C482A484948880808280810
+5CF3:0100210821083FF8000010401040247E24886488A54824502420205020882306
+5CF4:100011FC1104110455FC5504550455FC5504550455FC5C50645000920112020E
+5CF5:2040202023FE2202AC44A840ABFEA840A890A890A910B920CA24024204FE0842
+5CF6:020004001FF010101FF010101FF010001FFC10001FFC020422243FE400280010
+5CF7:0100210821083FF8020001003FF808200440FFFE010001007FFC010001000100
+5CF8:2028202420242020ABFEAA20AA24AA24ABA4AAA8AAA8BA90CA9205AA04460882
+5CF9:010002800C603018CFE601003FF801001110250802000100210821083FF80008
+5CFA:100013FE1020102055FC5524552455FC5524552455FC5D2064A0004000B0030E
+5CFB:2040204020882104ABFEA802A888A944AA42A8F8A988BA50C820005001880606
+5CFC:10201120112011FC55205620542057FE5400540055FC5D046504010401FC0104
+5CFD:10201020102013FE5420542055245524552456AA54205C506450008801040202
+5CFE:200C11F08100490009FE1110E11022102210251001002108210821083FF80008
+5CFF:100013FE1040104055FC5484548457FE5400540055FC5D046504010401FC0104
+5D00:0100210821083FF8020001001FF010101FF010101FF011081090126014181806
+5D01:0100210821083FF81080108010FC7D041248104010401CA0E0A0411002080C06
+5D02:2088208823FE2088A800ABFEAA02AC44A840ABFCA844B884C884010402280410
+5D03:20402040204027FCA840AA48A948A950AFFEA8E0A950B950CA48044408420040
+5D04:10201020105010505488550456FA54005444542455245CA86488001003FE0000
+5D05:10401040107C1084550856FE5492549254FE549254925CFE64920112010A0204
+5D06:20402020202023FEAA02AC94A908AA04A800A9FCA820B820C820002007FE0000
+5D07:0100210821083FF8020001007FFE40029FF400007FFC01001110210845040200
+5D08:020001007FFE40029FF400007FFC11102108450402000100210821083FF80008
+5D09:1020102213B410A854A8552456A2544055FC550455045DFC6504010401FC0104
+5D0A:2088208820882088ABDEA888A888A99CA9DCAAAAAAAABCC8C888008800880088
+5D0B:0100210821083FF800007FFC11101110FFFE111011107FFC0100FFFE01000100
+5D0C:100011FE1102110255FE5510551055FE55105510557E5D4265420242027E0442
+5D0D:10201020102013FE542055245524552456AA547054A85CA86524022204200020
+5D0E:1020102011FC10505488550457FE540855E8552855285DE86528000800280010
+5D0F:201C23E0222023FEAA20AA92AB0AAA06A9FCA904A904B9FCC904010401FC0104
+5D10:100011FC1104110455FC5504550455FC5400551255D45D18651001520192010E
+5D11:0100210821083FF800001FF810081FF810081FF82080208C3EF020822682387E
+5D12:0100210821083FF8020001007FFC0820145022880100FFFE0100010001000100
+5D13:200023FE22222222ABFEAA22AA22AAFAAA8AAA8AAA8ABAFACA8A020203FE0202
+5D14:010041047FFC090008801FFC108030805FF8908010801FF8108010801FFC1000
+5D15:100011FE11101110557C5510551055FE5500551055105D7C6510021002FE0400
+5D16:0100210821083FF800003FFC20802FF820803FFC200020804FF840809FFE0000
+5D17:0100210821083FF800007FFC482444445FF441044924492449244FE440144008
+5D18:1020102010501088550456FA540055FC5554555455FC5D54655401540104010C
+5D19:0100210821083FF802800C6037D8C0063FF8248824883FF82488248824A82010
+5D1A:2020202021FC2020A820ABFEA888A944AA42A8F8A988BA50C820005001880606
+5D1B:200023FE22022202ABFEAA10AA92AA92AA92AAFEAA10BA92CA92049204FE0802
+5D1C:2008203C21E02020ABFEA8A8A8A8A8A8ABFEA8A8A8A8BBFEC820002001FC0000
+5D1D:1020102013FE102055FC542057FE540055FC550455FC5D0465FC010401140108
+5D1E:2040202023FE2000A9FCA904A9FCA800A9FCA808A810BBFEC820002000A00040
+5D1F:0100210821083FF8010002800C603018CFE6010001003FF811100920FFFE0000
+5D20:1020102013FE102055FC552455FC552455FC542054705CA86124062200200020
+5D21:200021FC20082010AA22AAAAAA72AA22AA72AAAAAB26BAA2CA42020203FE0002
+5D22:101E13E011221094540055FC5424542457FE542454245DFC6424002000A00040
+5D23:010041047FFC00701F8001007FFC05401930E10E04007FFC08201C4003807C78
+5D24:21842068203020C8AB24A820ABFEA840A8FCA984AAFCB884C8FC008400940088
+5D25:1040108011FC1124552455FC5524554455FC549055105FFE6410001000100010
+5D26:2040208027FE2110AA48AC46ABF8AA48AA48ABF8AA48BA48CBF800420042003E
+5D27:0100210821083FF8101010901090FD0831483A44544250909088110813FC1104
+5D28:1020102013FE102055FC542457FE542455FC542055205D3E652002A0027E0400
+5D29:0100210821083FF800003E7C224422443E7C224422443E7C224422444A948508
+5D2A:1040102013FE100054885488555456225400542057FE5C206420002000200020
+5D2B:0100210821083FF800003FF820083FF820802490249027F02080488848888FF8
+5D2C:0100210821083FF80100FFFE01003FF821083FF821083FF803800D603118C106
+5D2D:0100210821083FF81000100CFEF0208048807EFE08880E88F888490809080A08
+5D2E:0100210821083FF800003FF8210821082FE8210827C8244827C820083FF82008
+5D2F:10201020105010885504560254F85420542055FC54205D2464A400A803FE0000
+5D30:1092109211241248552454925492540055FE552255225DFE6522012201FE0102
+5D31:0100210821083FF800003F0421243F2421243F24212421243F24120421144088
+5D32:1020104011FC110455FC550455FC540057FE542054205DFC6420002003FE0000
+5D33:204020A021102208ADF6A800ABC4AA54AA54ABD4AA54BA54CBD40244025402C8
+5D34:0100210821083FF8002800243FFE20202FA422242FA824982D12422A45468882
+5D35:100010FC108410FC548454FC540055FE548054FE552A5E4A6492012200540088
+5D36:0100210821083FF8080008087F0808FEFF08084808287F2808080F08F0284010
+5D37:10881048105013FE5450545055FC55545554558C55045DFC6504010401FC0104
+5D38:100013FE1020104055FC5504550455FC550455FC55045D0465FC000000880104
+5D39:2040202021FC2000A888A850ABFEAA22AC24A9FCA924B924C934012800200020
+5D3A:0100210821083FF820401040FEFE212020AC3CB425E424AC24A044A25482887E
+5D3B:211021102210247CA910A910AAFEAE08AA08AAFEAA08BA48CA28020802280210
+5D3C:100011FC1104110455FC5504550455FC540057FE54205D20653C012002A0047E
+5D3D:0100210821083FF800001FF0111011101FF0111011101FF001004884481287F2
+5D3E:200023FE20502050ABFEAA52AA52ABFEA800A840AFFEB888C990006000D80304
+5D3F:100011DC1154115455DC540055FC540057FE548054FC5C046404000400280010
+5D40:0100210821083FF80000084008207EFC082018201CFC2A202A20482089FE0800
+5D41:1088108813FE108854F8548854F85488548857FE55005D486584010001FE0000
+5D42:0100210821083FF8004013F8204847FE884813F8304053FC904017FE10401040
+5D43:1020101011FE10005484544855FE55085510556455085D1265640208023004C0
+5D44:2104208823FE2020A820A9FCA820A820ABFEA800A820BBFEC820005000880306
+5D45:0100210821083FF8002800243FFE20202FA420242FA8289828924FAA40468082
+5D46:0C487044104013FEFC503890549091121212110E01002108210821083FF80008
+5D47:08481C44F04013FE1050FC5010923892350E5420502091241124112411FC1004
+5D48:203C27C022442128A800ABFCA880A880AFFEA900A9F8BA88CA50042008D80306
+5D49:2040202023FE2000A9FCA904A9FCA800ABFEAA02A9FCB820C820002000A00040
+5D4A:203823C0204027FCA950A954AF58A954AB54AD4CA8E0B950CA48044408420040
+5D4B:100011FE1112111255FE5500557E55425542557E55425D7E62420242047E0842
+5D4C:0100210821083FF800202220223EFF42229422103E10221022283E2822440082
+5D4D:00407F40127E0C88FF4819482A504820A850118C01002108210821083FF80008
+5D4E:21FC2124212421FCA924A924A9FCA820A820ABFEAA22BA2ACAFA020A02020206
+5D4F:010041047FFC00002448238824483FF81010220847E40820144003801C70E00E
+5D50:0100210821083FF800001FF0101010D01710111017D0155027CA212A4FE68022
+5D51:100011FC110411FC550455FC548055FE5622552255525D0265FA000200140008
+5D52:00001FF0101010101FF000007C7C444444447D7C01002108210821083FF80008
+5D53:0100210821083FF800001FF0101010101FF000007EFC4284428442847EFC4284
+5D54:010041047FFC00001FF011101FF011101FF00000FFFE111010A014401830100E
+5D55:2000208822522222AA52AA8AAA02ABFEA888A944AA7AB888C950002000D80706
+5D56:1020102013FE107054A85524562255FC550455FC55045DFC6504000003FE0000
+5D57:0100210821083FF8004800443FFE20402F4422442A282AA83112422A44C69B02
+5D58:2088208823FE2088A800ABFEAA02AC24A820ABFEA870B8A8C8A8012402220020
+5D59:0100210821083FF800000C1070901050FC903050381E55F05010901010101010
+5D5A:0100210821083FF8104010403E7C4084BD2810201020FE501050148819041202
+5D5B:0100210821083FF802800C6037D8C0063E0822483E4822483E48220822282610
+5D5C:010041047FFC020001003FF808200440FFFE00101F90109010901F9000500020
+5D5D:2020212420A82020ABFEA8A8A924AA02A840AFFEA888B908C990006001980604
+5D5E:010002800C603018CFE601003FF80100111025080200101092929292FEFE0202
+5D5F:010041047FFC00003FFC2280224027FC2C4037F8244027F82440444047FC8400
+5D60:101E13E0112210945440548855F0542054C455FE54225C2063FE005000880306
+5D61:010041047FFC044008203218C4460FE000207EFC224412240A1412242A544488
+5D62:102010201050104854A455FE568454FC548454FC54805CFC65440144027C0044
+5D63:1020101011FE1110557C551455FE5514557C5510557C5D4465440244027C0444
+5D64:08202AA42CA84920145022887FFE40028104010021082108210821083FF80008
+5D65:2104210421DE2244AD54A89EA904AA24AC24ABFEA870B8A8C924062200200020
+5D66:102011241124112455FC540057FE540055FC550455045DFC6488005003FE0000
+5D67:204023BE22122292AA52AAAAAB24A840ABFEAA22AA22BBFECA22022203FE0202
+5D68:2040208021FC2104A904A9FCA900A9FEA900A9FEA802BAAACAAA040200140008
+5D69:010041047FFC0200FFFE00001FF010101FF000007FFC40044FE448244FE4400C
+5D6A:2040202023FC2000A9F8A908A9F8A800ABFCAA04AAF4BA94CAF4020402140208
+5D6B:20842044204823FEA884A884A908A94AAA52AB9CA884B908C908025203DE0042
+5D6C:0100210821083FF8020004003FF821083FF821083FF8029004A808FA308AC07E
+5D6D:2040202023FC2108A890ABFEAA02AC44A820ABFCA880B8F8C888010801280210
+5D6E:1020102013FE102055FC550455FC550455FC550455FC5D0463FE008801040202
+5D6F:11081088109013FC544055F8544057FE5480550055FC5E206420082003FE0000
+5D70:10881050100011FE545055FC545457FE545455FC54505CD86554025200500050
+5D71:2040202023FE2202AC94A908AA64A890A908AA04ADFAB908C908010801F80108
+5D72:1020104011FC110455FC550455FC550455FC542057FE5C7064A8012402220020
+5D73:0100210821083FF8082004407FFC01003FF80200FFFE080037F0C0801FFC0000
+5D74:2040224821502248ACA4A918AE06ABF8AA08ABF8AA08BBF8CA08020802280210
+5D75:0100210821083FF8004078404BFC48404FFE78104FFE48104A10791048500020
+5D76:200023DE20422042ABDEAA10AA10ABDEA842AA52A94AB94ACA52004202940108
+5D77:2124212422242424A954A94AAA92AE10AA10AA50AA5CBA50CA5002B0029E0300
+5D78:0100210821083FF81110211041108AA8144430405240927C1240154014FE1800
+5D79:010041047FFC00007CF8048804F87C2041FC41247D2405FC042004242BFE1002
+5D7A:200027BC208424A4AA94ACA4A850A988AE26A8C0AB10B864CB88003000C00700
+5D7B:1020101011FE1110557C551455FE5514557C551055925D546538025402920430
+5D7C:2040202023FC2000A908A890ABFEAA20AAA0AAFCAB20BA20CAFC0420042009FE
+5D7D:2154215423FE2154A954AA72AC00ABFEAA22A820A9FCB924C9240124012C0020
+5D7E:010041047FFC08201FF0102025487EFC04401930E64E1990062018C007003800
+5D7F:010041047FFC00000000FDFC104011F8110811F8110811F8110811F850902108
+5D80:11FC102013FE122255AC542055AC540055FC540057FE5C8064FC000400280010
+5D81:102011FC112413FE552455FC542055FC552455FC54405FFE648801D00070038C
+5D82:102011FC1088105057FE540055FC550455FC550455FC5C2067FE002000200020
+5D83:22002202223C2FA0AA20AFA0AABEAFA4AAA4AFA4AA24BFA4CA24024402440284
+5D84:0100210821083FF808067F7808407F40497E7F4849487F4808487F4808880908
+5D85:082008207F20087E7E4408A4FF2810101E28224446828100210821083FF80008
+5D86:2090209027FE2090ABFCAA94ABFCAA94ABFCA800A9F8B908C9F8010801F80108
+5D87:200023FE2200227CAA44AA44AA7CAA00AAEEAAAAAAAABAAACAEE020003FE0000
+5D88:0100210821083FF80440247C24A83D50042804487DFE24882448244844088418
+5D89:0100210821083FF800A0009079FE49204B204DFC492049FC7920492001FE0100
+5D8A:0100210821083FF810A01090F9FE11201B2015FC3120D1FC1120112051FE2100
+5D8B:1040108011FC110455FC550455FC550055FE550055FE5C0262AA02AA0202000C
+5D8C:010041047FFC04001FF010101FF010101FF010001FFC10001FFC492484940008
+5D8D:100013DE10421252554A56525442542055FC550455045DFC6504010401FC0104
+5D8E:0100210821083FF800003F0821083F0820FE2E0820483F2844285508A4A80C10
+5D8F:010041047FFC00007FFE40005FDC45045FC4554459DC50505FD050525FD2904E
+5D90:010041047FFC010079F04A9050606198560649F04A406BF8544043F8404047FC
+5D91:208020F8210823FEAD12A922A9FEA840A8A2AB54A898BB34C854009203500020
+5D92:21042088200023FEAA22AAAAAA72AA22ABFEA800A9FCB904C9FC010401FC0104
+5D93:103C13E0112410A855FE54A85524560255FC552455245DFC6524012401FC0104
+5D94:0100210821083FF808401440227C5C8489283E2008204A5028500E8871042202
+5D95:2090208821FE2110AB10ADFEA910A910A9FEA910A910B9FEC90002A402520452
+5D96:204020A0211826E6A800ABF8AA08ABF8A800AFBCA884BCA4C29404A402940108
+5D97:208822AA22DC2488A954AA22A800ABFEAA42AC44ABFCB844C844008401140208
+5D98:0100210821083FF81090108813FEFC48103231CE3890548853FE9048103211CE
+5D99:2020212420A823FEA8A8A924AA22A904A904A9DEAA44BD54C89E010402040404
+5D9A:010041047FFC01007FFC044028281FF02828CFE608200FE00100111025080200
+5D9B:1020102011FC102055545488550456FA548854F854885CF8642000A801240060
+5D9C:010041047FFC00003E7C081048907EFE1428244A46863FF820083FF820083FF8
+5D9D:202027A420A82292A914AA08ADF4A802ABF8AA08AA08BBF8CA0801100FFE0000
+5D9E:00407BFC488051F8622055FC488848F8688850F840884100210821083FF80008
+5D9F:2088205023FE2050A9FCA954A98CA974A904A9FCA808BBFEC908008800A80010
+5DA0:101811E0104013FE5488557456525470540055FC55045D74655401740104010C
+5DA1:010041047FFC00003FFE289025102FBE22222AD42A902F902228442844448882
+5DA2:2020202021FC2020ABFEA908AB9CA908A988AE3EA800BBFEC89000900112020E
+5DA3:010041047FFC010008801FFC30805FF810801FF810801FFC1000248822444244
+5DA4:010041047FFC01003FF80100FFFE08203EF808207EFC00007FFC04401842E03E
+5DA5:20002FFE28002A28A948ABEEA892A884AAA0AAA8ABE8B888C894091409241242
+5DA6:108010F8110813FE5544559255FE5500557C5500557C5D00657C0244027C0444
+5DA7:100011FC115411FC542055FC542057FE5488545055FC5C2067FE002000200020
+5DA8:0A803138228838382288393822887FFE4002810401002108210821083FF80008
+5DA9:105011FC115411FC555455FC540055FE5500557C55005DFE6550015401480266
+5DAA:010041047FFC24481450FFFE082004407FFC01003FF80100FFFE05401930E10E
+5DAB:2050225221542050ABFEA888A850ABFEA820A9FCA820BBFEC8A8012406220020
+5DAC:2104208823FE2020A9FCA820ABFEA854A992A890ABFEB890C8D4038A009601A2
+5DAD:0100210821083FF810407C2045FC44887C5043FE40207C2045FC44207C204420
+5DAE:1020102010501088550456FA5400540055DC555455545DDC6488008801540222
+5DAF:41047FFC00003E2822243E240020FFFE22203E2822283E1022122F2AF2464282
+5DB0:210021DE224A248AABEAAAB6AAA4ABF4AABEAAA4ABE4BABECAA402A402240464
+5DB1:108813FE108811FC550455FC550455FC548055FE56225D52650201FA000A0004
+5DB2:010041047FFC08801FFC30805FF890801FF810801FFC10003E7C224423D42008
+5DB3:21083FF800007FFC06003B0804B019C062A00C98732610207CFC10201E20F1FE
+5DB4:04003FF82008292825482FE8254829280200FFFE08203118D11611101FF00010
+5DB5:200023FC22942294ABFCA800A890AF9EA890A890AB9CB890C890079E00900090
+5DB6:010041047FFC000022204AA08ABE1FC420A46F24A0282F28291029A829443082
+5DB7:010041047FFC0000247C3A0422281E1020FE3E124850085E7F5014B0229E4100
+5DB8:208822AA22DC2488A954AA22A800ABFEAA22A820ABFEB870C8A8012406220020
+5DB9:202023FE202021FCA800ABFEA802A9FCA820ABFEA800BBFEC80403BE02A4038C
+5DBA:010041047FFC100013FC284045F8930809F8FD0805F8090851F8200010900108
+5DBB:010041047FFC08207F280824FFFE12203FA46424BFA824183F92242A3FC62082
+5DBC:2140224C22642244AB4CAA64AAA4ABACAAA4AAA4AFFEB800C910010802040404
+5DBD:0100210821083FF8001052182F945014977E1010372850289728154457442082
+5DBE:203E27C022442128ABF8A840AFFCA800ABF8A808ABF8B808CBF80544052A08FA
+5DBF:200021FC202023FEAA22A9ACA820A9ACA800ABFEA820B9FCC95401540154010C
+5DC0:010041047FFC08002A284D240820142E3F706424BF2424283F12242A3F462082
+5DC1:200023FE224823FEAA48AAFCAAA4AAFCAAA4AAFCAA20BBFEC32A057A050A0906
+5DC2:21083FF808801FFC30805FF890801FF810801FFC10003FFC24242BD4224423CC
+5DC3:41047FFC08407F7C2240147CFF04007C7F40417C7F40417C7F40417C4542423E
+5DC4:2110209023DE2010AA5EA982ABDEA810ABDEAA50ABDEBA50CBDE0250025202CE
+5DC5:21083FF808007EFE08103E20227C3E4422543E5422543E542254FF2824444282
+5DC6:208822AA22DC2488A954AA22ABFEAA02A8F8A888A8F8B800C9FC010401FC0104
+5DC7:208820CC208A23E8AAA8AADEABA8AA6AAA0AABEAAC0CBFECCA2A03EA015607E2
+5DC8:010041047FFC000029007DFC29043A4411547CE455F47C4410E4FD5410541008
+5DC9:21F0221027FC2204ABFCAA24ABB8AA22A9FEAA10AFFCBA44CBFC00D0014A063E
+5DCA:23DE225223DE2252ABDEAA52ABDEA98CAA52A840AFFEB888C990006000D80304
+5DCB:010041047FFC10007DFC44047CFC40047DFC44007DFE11225CFC50A45EACF020
+5DCC:41047FFC220811103FFC20002E20223C3FA829482F2829282F1049D07F288144
+5DCD:010041047FFC0C20704011FCFD2439FC552493FCFC24245A685E10902912C60E
+5DCE:200027FE204022EEAAAAABEAAAAEAAE8ABAAACE6AA88BDF4CA90006001980606
+5DCF:208823FE208823DEAA52ABDEA8A0A890A9FEA920ABFCBD20C9FC012001FE0100
+5DD0:010041047FFC08007F7C00443E7C22443E7C00107F6441245DFE55245D244344
+5DD1:252827BE294827BEAB18ADAAA946ABFCAA04ABFCAA04BBFCCA0403FC01080204
+5DD2:210447C88812F3BC20084B92F83E0380AAAAABAA01002108210821083FF80008
+5DD3:010041047FFC22003CFE21101F7C52445E7C52445E7C52447F7C002824444282
+5DD4:21083FF808007EFE08103E20227C3E44227C3E44227C3E44227CFF2824444282
+5DD5:2108209027FE2108ABFEAA54ABC8AA3EABC8AA5CABC8B840CBFE00880070038C
+5DD6:010041047FFC00001E7812483FFC20202E20223C3FC829282F2849905F288144
+5DD7:23DE225223DE2000ABFEAA00AAC8AA4EABEAAAB2AAEABAAACAEA02B405E4082A
+5DD8:210821EC210A2FEAA928ABC8A93EAFE8A948ABE8AA28BB68CAA80BF40AB412A2
+5DD9:211027FE204022EEAAAAABEAAAAEAAE8ABAAACE6AA88BDF4CA90006001980606
+5DDA:010041047FFC08000F9008147F9248FE7E1048905FA851285F28554455449382
+5DDB:0000000008880888088811101110222022201110111008880888088800000000
+5DDC:0000041004100820082010402080410020801040082008200410041000000000
+5DDD:1004108410841084108410841084108410841084108410842084208440048004
+5DDE:1004108410841084108454A45294529490841084108410842084208440048004
+5DDF:02000100FFFE1000100010001FF800001110111011101110211021124112800E
+5DE0:00007FFE00000888111022201110088800003FF80100010001000100FFFE0000
+5DE1:000021241124112402480248F490124812481124112411241000280047FE0000
+5DE2:088811102220111008883FF821083FF821083FF80100FFFE054009203118C106
+5DE3:22081108111000003FF821083FF821083FF80100FFFE054009203118C1060100
+5DE4:1084210810843FF82448238824483FF80000294825282948252A210A29463182
+5DE5:000000007FFC0100010001000100010001000100010001000100FFFE00000000
+5DE6:020002000200FFFE04000400040008000FF8108010802080408080803FFE0000
+5DE7:000003FEFC40104010801080110011FC100410041E04E0044004000400280010
+5DE8:00003FF82000200020003FF02010201020103FF020002000200020003FFC0000
+5DE9:000001F07D1011101110111011901150115011101D10E11242120212040E0800
+5DEA:00003FF8200020003FF0201020103FF0200020003FFC00007FF8000800080008
+5DEB:000000007FFC01000100111011101110292829284544858401000100FFFE0000
+5DEC:00007DF01110111011121D12E20E440001003FF80100FFFE028004401830600C
+5DED:00407C4013FC104410441C84E114420801003FF80100FFFE028004401830600C
+5DEE:082004407FFC010001003FF802000200FFFE0400080017F82080408080801FFC
+5DEF:00207C1005FE08201048288445FE820200A87CA810A810A810AA1D2AE1264200
+5DF0:0020FE1055FE5420A848548455FE0002FEA810A810A810A81EAAF12A41260200
+5DF1:00003FF0001000100010001000103FF02000200020002004200420041FFC0000
+5DF2:00003FF0001000100010201020103FF02000200020002004200420041FFC0000
+5DF3:00003FF0201020102010201020103FF02000200020002004200420041FFC0000
+5DF4:00003FF8210821082108210821083FF82008200020002002200220021FFE0000
+5DF5:007C3F80200020003FFE200020002FF82888288828882FF828084802480287FE
+5DF6:0000FEFC2284228442844A84848400FC7E8042804280428242827E82427E0000
+5DF7:044004403FF804400440FFFE044008201FF02828C8260FE008200808080807F8
+5DF8:00007F7C4844484448445E445244527C524052405E404842484248427F3E0000
+5DF9:1FC000447D88055009203118C50602003FF800003FF000103FF0200420041FFC
+5DFA:00007CF8448844887CF84080428442843E7C00000000FFFE0000082010102008
+5DFB:0100111009203FF802007FFC082010102FE8C02600200FE008000808080807F8
+5DFC:00003FF0211021103FF02000200420041FFC00003E442258226022423E42223E
+5DFD:00007CF844887CF8408042843E7C044004403FF804400440FFFE082010102008
+5DFE:0100010001003FF8210821082108210821082108210821282110010001000100
+5DFF:01000100FFFE0100010001003FF8210821082108210821282110010001000100
+5E00:00007FFC0100010001003FF82108210821082108210821282110010001000100
+5E01:000801FC7F00010001003FF82108210821082108210821282110010001000100
+5E02:0200010000007FFC0100010001003FF821082108210821082128211001000100
+5E03:020002000200FFFE0400090011003FF851089108110811081128111001000100
+5E04:0800080008FE7F1049104910491049104910491049104B100810081008500820
+5E05:082008204820482049FC49244924492449244924492409341128102020204020
+5E06:100011F011107D1055105510559055505550551055105D1211121212120E1400
+5E07:010001003FF80108FFFE01083FF8010001003FF8210821082128211001000100
+5E08:08000BFE48204820482049FC4924492449244924492409341128102020204020
+5E09:1010109010907C8855085504560455FA5488548854885C881108110812281410
+5E0A:1000100011FC7D24552455245524552455FC550055005D001102110210FE1000
+5E0B:00783F80208020803FFC20402822311A21061FF0111011101150112001000100
+5E0C:18180660018006603A180200FFFE048008801FF82888488888A8089000800080
+5E0D:020001003FFC200420043FFC2040204027FC2444244424444454444880400040
+5E0E:1020102010207DFE55225624542054205450545054505C50109010921112120E
+5E0F:1020102010207DFE5420542054FC5420542055FE54225C22102A102410201020
+5E10:1080108410847C88549054A0548057FE54A0549054905C88108410A210C01080
+5E11:10001000FEFC2244642818102428C34601003FF8210821082128211001000100
+5E12:08A0109030BE57C0904010241014110C01003FF8210821082128211001000100
+5E13:1020102010207DFE54205420542055FC547054A854A85D241124122210201020
+5E14:1010101010107DFE55125514551055FC5544554455285D281110122812441482
+5E15:1020102010407DFC550455045504550455FC550455045D041104110411FC1104
+5E16:1020102010207C20543E54205420542055FC550455045D041104110411FC1104
+5E17:1050104810487C4055FE54405440547C54A454A454A85D281110122810441082
+5E18:020001007FFE400288241010210801003FF82108210821082128211001000100
+5E19:1020102011207D2055FC55205620542057FE542054505C501088108811041202
+5E1A:00001FF000100FF000101FF000007FFE410281041FF011101110115011200100
+5E1B:010002001FF010101FF010101FF0010001003FF8210821082128211001000100
+5E1C:1000100011FC7D04550455045504550455FC550454005C901088110412021402
+5E1D:020001003FF80000082004407FFE410281041FF0111011101150112001000100
+5E1E:100013FE10207C20544055FC55045504550455FC55045D041104110411FC1104
+5E1F:020001007FFC0440245044488944108001003FF8210821082128211001000100
+5E20:02001CF0101010101EF0101010101FF001003FF8210821082128211001000100
+5E21:1104108410887C0055FE548854885488548857FE54885C881108110812081408
+5E22:1020102010507C885504560255FC5400540055FC55045D041104110411FC1104
+5E23:1110091009207FFC02000400FFFE11102108DFF6111011101150112001000100
+5E24:10001000FE7C224442443444087C3400C20001003FF821082108212821100100
+5E25:102020207C20442045FC45247D24412441247D244524453445287C2044200020
+5E26:092009207FFC0920092000007FFE410281041FF0111011101150112001000100
+5E27:10201020103E7C20542055FC550455245524552455245D241050104810841104
+5E28:1104108410887C1055FC55045504550455FC545054505C9010921112120E1400
+5E29:1020112410A47CA8542055FC5504550455FC550455045DFC1104110411141108
+5E2A:100011FE11007D00557C5500550055FE5550555255545D481148124412521460
+5E2B:100023FE7C204420442045FC7D24412441247D244524453445287C2044200020
+5E2C:00003FF80208FFFE04083FF808001FF82808CFF800801FFC1084109410880080
+5E2D:010000803FFE222022203FFC2220222023E020802FF82888488848A888900080
+5E2E:0800087CFF4808507E480844FF54104820404100BFF821082108212821100100
+5E2F:092009207FFC09200FE000007FFE410281041FF0111011101150112001000100
+5E30:080009FC480448FC480449FC48004BFE4A22482049FC09241124113421284020
+5E31:2040204027FCF840ABF8A880AFFEA890A910A9FEAA10BA902450281020502020
+5E32:1044104410887DDC548854885488548855DE548854885C881088108810881108
+5E33:100010FC10807CF8548054F8548057FE5540552455285D101108114411821100
+5E34:10481044105E7DE054285412546A55965448545E55E05C2410281012106A1186
+5E35:2040202023FEFA02AD04A900A9DEAA52AA52AB52AC9AB894211021122212240E
+5E36:145014507FFC1450245247CE80007FFC41041FF0111011101150112001000100
+5E37:1050104810807CFE5590569054FC5490549054FC54905C90109010FE10801080
+5E38:0100111009207FFE40029FF410101FF001003FF8210821082128211001000100
+5E39:2080204023FCF800A908A890AFFEA840A840AFFEA888B9082090206021982604
+5E3A:1088108811FC7C88548854F85488548854F8548854885DFE1000108811041202
+5E3B:2040204027FCF840ABF8A840AFFEA800ABF8AA08AA48BA48224820A021102608
+5E3C:200023FE2202FA02ABFEAA22AA22AAFAAA22AA32AA2ABBFE2202220223FE2202
+5E3D:200023FC2204FAF4AA04AAF4AA04A800A9F8A908A9F8B90821F8210821F82108
+5E3E:1020102211FA7C24542857FE5420544054FC558456845CFC1084108410FC1084
+5E3F:210021782108FA08AAFEAE40AA40AA7CAA90AA10AAFEBA102228222822442282
+5E40:10201020103E7C20542055FC550455FC550455FC55045DFC1000108811041202
+5E41:100013FE10207C4055FC5504550455FC550455FC55045D0411FC100010881104
+5E42:00007FFE40029FF410101FF010101FF00200FFFE09203FF8D116115011200100
+5E43:1040104011FC7C8457FE540055FC550455FC542057FE5C20122013FE10201020
+5E44:200023FC2204FA04ABFCAA00ABFCAA40AA88ABFCAA24BA2025FC2420282033FE
+5E45:100011FE10007CF85488548854F8540055FC552455245DFC1124112411FC1104
+5E46:100011FC11047DFC550455FC548055FE5622552255525D0211FA100210141008
+5E47:080808087E0808FEFE0808487E2808080F28F11001003FF82108212821100100
+5E48:200023FC2204FA04ABFCAA00AA84AA48AAFCAA48AA48BBFE2448244828883108
+5E49:204821482148FBFEA948A948A978A900A9FEA820ABFEB87020A8212426222020
+5E4A:100011FC10207C2057FE540055FC550455FC550455FC5D0411FC108811041202
+5E4B:10783E4822482A86FF7822482A2842104A28854601003FF82108212821100100
+5E4C:100011FC11047DFC550455FC5420552454A8542057FE5C50105010921112120E
+5E4D:101E11E010227D1254945480542055CE5502550255CE5D021102110211FE1102
+5E4E:200023FE2202F800A9FCA904A9FCA904A9FCA840A820BBFE2000208821042202
+5E4F:2040202023FEFA02A800A9FCA840A8A2AB34A858A894BB342052209023502020
+5E50:0020792448A849FC48407BFE49084A244C2279FC492449244934492848209820
+5E51:12101A902A904AA08FBE10442FA46224A2242FA82AA82A902AA82BA822442282
+5E52:1020104011FC7D24557C558C55545524555455FC54405C2412A2128A14881078
+5E53:2040208821FCF908AA52ABFEA850A988AE26A8C0AB10B8642388203020C02700
+5E54:200021F82108F9F8A908A9F8A800ABFCAA94ABFCA800B9F82090206021982606
+5E55:04407FFC04401FF010101FF010101FF00400FFFE11103FF8D116115011200100
+5E56:100013FE10507DFC5554555455FC540055FC540057FE5C2010A8112412A21040
+5E57:200023FE221AFA16ABFEAA12AAEAAAAAAAAAAAEAAA0EBA6A239A222623FE2202
+5E58:102013FE10207DFC542057FE540055FC550455FC55045DFC110411FC10881104
+5E59:1088108813FE7C88540055FC550455FC550455FC54205DFE1050108811041202
+5E5A:087CFF4808507E480844FF54104822405FF090101FF010103FF8210821180100
+5E5B:102011FC10887C5057FE540055FC550455FC550455FC5C2013FE102010201020
+5E5C:100011FC11047DFC550455FC542057FE540055FC55045DFC1020112412221060
+5E5D:200023DE2252FA52ABDEA800A9FCA924A9FCA924A9FCB82023FE202020202020
+5E5E:205022522154F850ABFEA888A850ABFEA820A9FCA820BBFE2050208821042602
+5E5F:2110209423D2F812AA50A990AFFEA810ABD2AA52AA54BBD4224A224A23D62022
+5E60:2080208021FEFB54AD54A954ABFEA954A954A954AFFEB8002154212A222A2000
+5E61:207827C02248F950ABFCA950AA48AC06ABF8AA48AA48BBF82248224823F82208
+5E62:102011FC10887C5057FE540055FC552455FC552455FC5C2011FC102013FE1000
+5E63:49202A207F3E49485DA86B2849104928404601003FF821082108212821100100
+5E64:082049202A3E7F4841A85D2855105D28424601003FF821082108212821100100
+5E65:212420A823FEFA02A8F8A888A8F8A80CA9F0A820A9FCB82023FE202020A02040
+5E66:00407C2045FC44887C5043FE7C20A5FC24203D2001003FF82108212821100100
+5E67:10F8108810887CF8540055DC5554555455DC542057FE5C7010A8112412221020
+5E68:210021F82208FFFEAA88AB24ABFEAA00AAFCAA00AAFCBA0022FC248424FC2884
+5E69:102011FC10207C8857FE548855FC550455FC550455FC5D0411FC108811041202
+5E6A:208823FE2088FBFEAA02A9FCA800ABFEA840A8A2AB54B8B82354209223502020
+5E6B:08083EFE08087F4808283E0809287FF028200FE008200FE001003FF821082118
+5E6C:202023FE2020F9FCA800ABFEA802A9FCA820ABFEA800BBFE200423BE22A4238C
+5E6D:210827FE2108F800ABFCAA94AA94ABFCA828ABFEAA20BB2422A82292242A28C6
+5E6E:2040202023FEFA44ABF4AA44AAEEAA04AAF4AAACAAE4BA1422A4247425942808
+5E6F:2108210821EEFA94A842A800ABDEAA52ABD2AA52ABD2BA1A2294235022102010
+5E70:102013FE12227DFC542054F8542055FC542055FC55545DFC104012A4128A147A
+5E71:23DE225223DEFA52ABDEAA22AAFAAA22AAFAAAAAAAFABAAA22FA227222AA2226
+5E72:00003FF801000100010001000100FFFE01000100010001000100010001000100
+5E73:00007FFC010001001110091009200100FFFE0100010001000100010001000100
+5E74:100010001FFC2080208040801FF8108010801080FFFE00800080008000800080
+5E75:00007C7C10101010101010101010FEFE10101010101010102010201040108010
+5E76:10100810082000007FFC0820082008200820FFFE082008201020102020204020
+5E77:0808080810107C7C1010101010101010FCFE1010101010102010201040108010
+5E78:010001003FF801000100FFFE082004403FF801000100FFFE0100010001000100
+5E79:102010201050FE5010887D0446FA7C2044207C2011FCFE201020102010201020
+5E7A:0200020004000810101020207FC02080010002000400082010103FF810080000
+5E7B:0800080011FC100422044204FC0404040804100424044204FE04420400280010
+5E7C:104010402040204045FC4444F84408441044108428844484FD04450402280410
+5E7D:0100010009200920514455547DF44924492455547DF44514410441047FFC0004
+5E7E:1110212045447978111025247D7C15241110FFFE1080108828522422405A8186
+5E7F:0100008000803FFC200020002000200020002000200020002000400040008000
+5E80:010000803FFE2000200022002204221822602380220022022202420241FE8000
+5E81:010000803FFE2000200020002FFE204020402040204020404040404081400080
+5E82:010000803FFE2000208020802080208020802140214022204220441088081006
+5E83:010000803FFE20002080208020802100210021002210220844084FFC84040004
+5E84:0100008000803FFC20002080208020802FFC208020802080208040805FFE8000
+5E85:010000803FFE20002100210022202220244028802100220844044FFE84020000
+5E86:010000803FFE20002080208020802FFC20802140214022204220441088081006
+5E87:010000803FFE20002420242024242428273024202420242245224622841E0000
+5E88:010000803FFE20802140222024102908308620802FF020104020402080400080
+5E89:010000803FFE204020402FFE204024442444244427FC204220424042403E8000
+5E8A:010000803FFE2000208020802FFC208021C022A022A024904888508680800080
+5E8B:010000803FFE208020803FFC208020802FF02410222021404080416086183806
+5E8C:010000803FFE200020002FFC2020242028202FFE20A021204620582080A00040
+5E8D:010000803FFE2000201C27E02400240027FE2420242024204820482090202020
+5E8E:010000803FFE2040204020A0211022082D162110211021104110421082100410
+5E8F:010000803FFE200023F8201020A020402FFE2042204420404040404081400080
+5E90:010000803FFE2100208027F824082408240827F8240824004400480088001000
+5E91:010000803FFE200020002FFC208020803FFE21402140224042424442883E1000
+5E92:010000803FFE20802080208020802FFC2080208020902088408840809FFE0000
+5E93:010000803FFE210021003FFC2200248028802FF8208020805FFE408080800080
+5E94:010000803FFE200020002104288424842448224822102210402040409FFE0000
+5E95:010000803FFE2000203C27C024402440244027FE242024202412450A46468422
+5E96:010000803FFE2200220027F8280837C82448244827C824282412440243FE8000
+5E97:010000803FFE20802080208020FC2080208027F8240824084408440887F80408
+5E98:010000803FFE2000200027FC2444244427FC2444244427FC2444404040408040
+5E99:010000803FFE2000208020802FF82888288828882FF82888488848888FF80808
+5E9A:010000803FFE200020802FF8208820883FFE208820882FF8414042208C183006
+5E9B:010000803FFE2000211021102512251425D8251025102510251245D25E12880E
+5E9C:010000803FFE200022082208240824FE2C083488244824484408440884280410
+5E9D:010000803FFE2100210023F82610292020C023303C0E20C04020430080C00020
+5E9E:010000803FFE2220221022002FFC22402240224824502460484248C2933E2000
+5E9F:010000803FFE2080249028882FFE210021FC2284228824502420485051888606
+5EA0:010000803FFE241022203FFC208020802FF8208020803FFE2080408040808080
+5EA1:010000803FFE208020403FFE20802100228426882A5032204210428883060200
+5EA2:010000803FFE200020002FFC2100221027F8208820802FFC40804080BFFE0000
+5EA3:010000803FFE212021202924252821302120233025282924222042224422881E
+5EA4:010000803FFE2000204027FC204020403FFE200020102FFC4210411081500020
+5EA5:010000803FFE20002220222024202DFE347024A824A825242622442044208420
+5EA6:010000803FFE222022203FFC2220222023E020002FF02410422041C08630380E
+5EA7:010000803FFE20802490249024902AA831C420802FF8208040804080BFFE0000
+5EA8:010000803FFE2080208827F020A03FFE20802FF02620384047FC404081400080
+5EA9:010000803FFE20802140222024103BEC208020802FF820804490488892840100
+5EAA:010000803FFE24102410247E3F102410257C26443C4424284410442894440882
+5EAB:010000803FFE20803FFC20802FF828882FF828882FF820805FFE408080800080
+5EAC:010000803FFE221022083FFE224822502264224822522264444A447288C2133E
+5EAD:010000803FFE20002E0E22F0241024102EFE221022102AFE4400460089FE1000
+5EAE:010000803FFE20002FFC21202FFC292429242A1C2C042FFC480448048FFC0804
+5EAF:010000803FFE204820442FFE204027FC244427FC244427FC2444444444548408
+5EB0:010000803FFE22082108211027FC2110211021102FFE21104110421084100810
+5EB1:010000803FFE208020802FFC20803FFE2408290433F22610492040C08730380E
+5EB2:010000803FFE204020402FFE204022482248255428E2215042484C4680400040
+5EB3:010000803FFE2080210027FC244427FC248427FC212022203FFE402040208020
+5EB4:00803FFE221022102FFC221022103FFE200027F82408240847F84408840807F8
+5EB5:010000803FFE200020802FFC2120221024882FF6349027F0249047F24082807E
+5EB6:010000803FFE2000222022203FFC22202220222023E020004A48492491240000
+5EB7:010000803FFE20802FF820883FFE20882FF8288024C422A84490488892860100
+5EB8:00803FFE20802FF820883FFE20882FF820802FF828882FF848884FF888880898
+5EB9:010000803FFE221022103FFE221023F0200027F8240827F84420441088081006
+5EBA:010000803FFE221024882924221027F8208820802FFC21C042A0449898860080
+5EBB:010000803FFE222022203FFC2220222023E020002410241044104A2891442082
+5EBC:010000803FFE280029FC28202E4029FC2904292429242B242D24485040888304
+5EBD:010000803FFE200027F8248827F8248827F820802FFC288448A44BF489140808
+5EBE:010000803FFE200022802CB8288828882EB8288828882FF8414042208C183006
+5EBF:010000803FFE211021102FFE2110200027FC2444244427FC2444444447FC8404
+5EC0:010000803FFE20402FFE2842224824B023082C0427F82208211040E043189C06
+5EC1:010000803FFE20002F84288428A42FA428A42FA428A42FA44024490488941088
+5EC2:010000803FFE20002200227C3F442244267C27442AC42AFC52446244827C0244
+5EC3:010000803FFE20402F5021242A1824083BF6212021202FFC212042244424881C
+5EC4:010000803FFE20002F78294829482F862900297C2F4428442A2849104B288D46
+5EC5:010000803FFE20802FFC20803FFE220024082FFC20002FFC49244924BFFE0000
+5EC6:010000803FFE208021002FFC28842FFC28842FFC21482154425C44468842303E
+5EC7:00803FFE2080277C2424252424A425542648208027FC244447FC444487FC0404
+5EC8:010000803FFE20002FFC208027F8240827F8240827F8220027F84A0841F09E0E
+5EC9:010000803FFE220821102FFE212027FC21243FFE212427FC2330452859268120
+5ECA:010000803FFE220021002FBE28A22FA428A82FA42A2229222AAA4CA448208020
+5ECB:010000803FFE2140265C2444275C244427FC20402FFC2208211040E043188C06
+5ECC:010000803FFE22203FFE22223FFE240027FC240027FE2002224A4926500A8004
+5ECD:010000803FFE2400221E2F922014289825143FD220122F9A489448908F900890
+5ECE:010000803FFE200029FE282028FC2E8428FC288428FC2A844CFC480080480084
+5ECF:010000803FFE24002FBC28A42FA428C22F80207E29222A222C94488847948062
+5ED0:00803FFE20002F7E291029102F502950297E2F1028282A2849284B4A8D4A0886
+5ED1:00803FFE24103FFE241027F020802FF828882FF820803FFC40804FF880803FFE
+5ED2:010000803FFE22102F90221E2FA422243FD4241427942488448848948AA41142
+5ED3:00803FFE22003FBC20242FA428A82FA820242FA4212423F45E2842208A200420
+5ED4:010000803FFE20802FF828883FFE28882FF8249027F021003FFE441043E09C1C
+5ED5:010000803FFE20102F2829442A922C7C2A082910297E2D002AFE4820484488FE
+5ED6:00803FFE20002F7C2924251429A421602618388623202C4041884E3081C00E00
+5ED7:010000803FFE22A822A82FFC22AA24E628002FFE284223F84248424882580040
+5ED8:010000803FFE208020402FFC29202FFC29242FFC2A202A244BB8522492A4231C
+5ED9:010000803FFE200027FC244427FC244427FC211027FC21102FFE400042088404
+5EDA:010000803FFE22043FC422042FBE20042FA428942F942884450443849C140808
+5EDB:00803FFE20002FF828882FF828882FF820802FF820803FFE488853E480803FFE
+5EDC:00803FFE200027FC240427FC244425F8245027FE244024F849884AF8948800F8
+5EDD:00803FFE2900290C3FB0292029202F3E29282F28292829285FA840488A881108
+5EDE:010000803FFE22002220252028BE374222942F90221032904A2843A89C440882
+5EDF:010000803FFE22002FBC22242FA428BC2FA428A42FBC22245FA4424482540288
+5EE0:00807FFE420852484A504A9E5FE4505457545554554857485048515450948022
+5EE1:010000803FFE220024002FFC355025502FFC255025503FFE40004A4889241124
+5EE2:010000803FFE20402F5021242A1824083B7621502F8C28782F48413045488284
+5EE3:010000803FFE22202FF822203FFC20802FF828882FF828884FF8422084100808
+5EE4:00803FFE20803FFC20802FF828882FF828882FF820803FFC40A45F3A91221F1E
+5EE5:00803FFE214026303BEC20002FF82AA829C82FF8200027F0441047F0841007F0
+5EE6:010000803FFE2010278824BE248027A22494243E2F882C8854BE478884880008
+5EE7:00803FFE204027FC2248224825543FFE200027FC240425F4451445F4840407FC
+5EE8:00803FFE24002F3C311422242FCC2A802FA82ABE2FC82A884ABE4A8888881188
+5EE9:00803FFE20402FFE200027FC240425F4251427FC200823F040404FFE81500E4E
+5EEA:00803FFE20402FFE200027FC240425F4251427FC200027FC40004FFE824804C4
+5EEB:00803FFE20002EEE2A222AAA2A662EAA2A102A282E542AAA4A50522492482610
+5EEC:00803FFE2040207C204027FE244225F8244424FC24A824F844A849FC895413FE
+5EED:00803FFE2010237C2E10227C2F1022FE2644277C2AC42A7C5244427C82280244
+5EEE:00803FFE20002FBE28A22FBE28A22FBE28A22FBE251428A24FFE431080E00F1C
+5EEF:010000803FFE240027222914323E2F882A882F9C2A882F88403E554895480008
+5EF0:00807FFE40207E2055FE54205DFC555455545DFC542056105C547542454A8638
+5EF1:00803FFE20002AA835242ABE2F6829682FBE20282FA82ABE4FA8482888BE07A0
+5EF2:00803FFE20002FBE2514271C25542FFE29202FFC29242FFC4A244BB89222239E
+5EF3:00807FFE40107F1052FE5E1052FE5EAA52AA7EFE42007EFE4A245E124AA4BE9C
+5EF4:00000000F80008001000100020007800080008004800300010002C0043FE8000
+5EF5:00000124F92409241248124824907A480A4809244924312410002C0043FE8000
+5EF6:0008003CF9E0082010201120213C792009200920492031FC10002C0043FE8000
+5EF7:0008003CF9E008201020102021FC782008200820482033FE10002C0043FE8000
+5EF8:00200020F82009FC11241124212479FC09240924492431FC10002C0043FE8000
+5EF9:00200020F84009FC11041104210479FC09040904490431FC11042C0043FE8000
+5EFA:00400040FBF8084817FE104823F878400BF80840484037FC10402C4043FE8000
+5EFB:000003FCFA040A0412F4129422947AF40A040A044BFC320410002C0043FE8000
+5EFC:000007FEF890089013FC129422947A940A9C0B044A0433FC12042C0043FE8000
+5EFD:000003FCFA940A9412F4129422947AF40A940A944A9433FC12042C0043FE8000
+5EFE:0000000008200820082008200820FFFE08200820082008201020102020204020
+5EFF:08100810081008100810FFFE081008100810081008100810081008100FF00810
+5F00:00007FFC08200820082008200820FFFE08200820082008201020102020204020
+5F01:02000400082010103FF80008082008200820FFFE082008201020102020204020
+5F02:00003FF0201020103FF0200420041FFC000008200820FFFE0820102020204020
+5F03:010000803FFC0200042008101FF80008042004207FFE04200420082010202020
+5F04:00007FFC010001003FF801000100FFFE000008200820FFFE0820102020204020
+5F05:0440082010102FE8C4260420082010A0604008200820FFFE0820102020204020
+5F06:010001003FF80100FFFE040008201FF0001008200820FFFE0820102020204020
+5F07:010002800C603018CFE600001FF010101FF008200820FFFE0820102020204020
+5F08:020001007FFC04402450444889441080000008200820FFFE0820102020204020
+5F09:2420242024203DFC0420FC20242024F8440008200820FFFE0820102020204020
+5F0A:082049202A3E7F4849485DA86B104928434608200820FFFE0820102020204020
+5F0B:022002100210020002FEFF0002000200020001000100008000420022001A0006
+5F0C:0048004400440040FFFE00400040004000400040002000227F92000A00060002
+5F0D:0048004400440040FFFE0040004000407E400040002000220F12F00A40060002
+5F0E:0048004400440040FFFE004000407F40004000403E2000220012078AF8064002
+5F0F:0048004400440040FFFE004000403E4008400840082008220F12780A20060002
+5F10:00483E4400440040FFFE0040004000407E400040002000220F12F00A40060002
+5F11:00144412281013FE28104410101011F0FC9010905890548894EA138A51062002
+5F12:441028141012281045FE1010141011D0FC9030903890548850EA938A10061002
+5F13:00007FF00010001000103FF02000200040007FF8000800080008000800500020
+5F14:00003FF80108010801081FF81100110021003FFC010401040114010801000100
+5F15:00087F080108010801083F082008200840087F0801080108010801080A080408
+5F16:00003FF8000800081FF8100020003FFC000400040004002800100000FFFE0000
+5F17:0440044004407FF8044804483FF8244024403FFC044408440854104820404040
+5F18:00207C200420042004207C404040404040807C880484050407FE050228021000
+5F19:00007CFE0410041004107C10401041FE40107C10041004100410041028501020
+5F1A:0820042004407FF8010801083FF8210021003FFC010401040114010801000100
+5F1B:0020F82008200920092C7934416443A441247934092809220922090250FE2000
+5F1C:00007DFC0404040404047CFC4080408041007DFC040404040404040428281010
+5F1D:00007DFC0524052405247D24412441FC41047D00050005000502050228FE1000
+5F1E:00407C400440047C04847C884120402040207C50045004500488048829041202
+5F1F:0820042004407FF8010801083FF8210021003FFC030405040914110861000100
+5F20:0100F9080908091009207940410047FE41407920092009100908094451822100
+5F21:00007CFE0480048004807CFC4084408440847C8404FC04800480048028FE1000
+5F22:00207D240524052405FC7C20402043FC41047C88048804500420045029881606
+5F23:0088F88808880908097E7B084508414841287928090809080908090851282110
+5F24:0004F81E09F0091009107910411041FE4110791009100908090A094A51A62112
+5F25:0080F880088009FE09027A0444204020412879240A240A220C22082050A02040
+5F26:0040F82008200BFE084078404088410843F078200840088809040BFC51042000
+5F27:0008F83C0BD00A900A907A904290429042907A880A880AC80AA40CD454922800
+5F28:0000FBFC088408840884790441144208440079FC090409040904090451FC2104
+5F29:08007F7C114432280C101228614600003FF000103FF020003FF8000800500020
+5F2A:00007DFC0408041004307C484084430240007DFC04200420042004202BFE1000
+5F2B:00007DFE0520052005207DFC4104410441047D0405FC05200520052029FE1000
+5F2C:00007DFE0510051005507D5C4144414441447D44055C05500510051029FE1000
+5F2D:0000FBFE09080908090879F84108410841F879080908091E0BE8080850082008
+5F2E:111009207FFC0400FFFE10102008DFF600100FF0080010001FF8000800280010
+5F2F:02000100FFFE044014502448444400003FF000103FF020003FF8000800500020
+5F30:00207D2404A404A804207DFC4104410441FC7D04050405FC0504050429141108
+5F31:00007EFC020402047EFC408040807EFC22441224060C1A3462C4020414280810
+5F32:0000F9F80908090809F8780043FC420442047BFC0A040A040BFC0A0452142208
+5F33:0000FBFC080009240A487C904248412440007BFC084008400840084057FE2000
+5F34:0040F8200BFE080009FC790441FC400041FC780808100BFE0820082050A02040
+5F35:0000F8FC088008F8088078F8408047FE41407924092809100908094451822100
+5F36:0040F8200BFE0800080079FC41044104410479FC082008A809240A2250A02040
+5F37:0020F840088809040BFE7822402043FE42227A220BFE08200824082257FE2002
+5F38:0000FBDE0A520A520A527BDE4252425242527BDE0A520A520A520A52555228A6
+5F39:0104F888085009FC0924792441FC4124412479FC082008200BFE082050202020
+5F3A:0000F9FC0904090479FC402083FE8222FA220A220BFE082008240822903F63C1
+5F3B:0000F01E17C211021102F7DE855085508550F6DE14421442144217C2A4544008
+5F3C:0000F01E17C211021202F7DE845084508450F7DE14421442144217C2A4544008
+5F3D:0048F94809480BFE094879484178410041FE78200BFE087008A8092456222020
+5F3E:0242F924080009FC0924792441FC4124412479FC082008200BFE082050202020
+5F3F:01007FFE44429FF404403FF80440FFFE08201FF02028DFE610001FF0001000E0
+5F40:1000FE7810487C480048FE8682007CFC00447C4404287C2840107C2804440D82
+5F41:0000FBFE080809E8092879E8400043FE400879E80928092809E8080850282010
+5F42:0440244814500440FFFE0000FC8004F87D20402081FCFC200450045028881104
+5F43:0000F9FC092409FC092479FC40A840A843FE78A808A809FC08200BFE50202020
+5F44:0000FBFE0A000A7C0A447A44427C420042EE7AAA0AAA0AAA0AEE0A0053FE2000
+5F45:0108F8900FFE08000BC47A5443D4425443D47A440ACC08000BFC088451142608
+5F46:49202A3E7F4849485DA86B10492841463FF000103FF020003FF8000800500020
+5F47:0020F9FC08240BFE082479FC402042AA43AE7A220BFE0A220BAE0AAA52AA2422
+5F48:0000FBDE0A520A520BDE780041FC412441FC792409FC08200BFE082050202020
+5F49:0088F88809FC088808887BFE402041FC412479FC092409FC0800088851042202
+5F4A:0000FBFE080009FC092479FC412443FE400079FC092409FC092409FC500023FE
+5F4B:0000FBFC0A940A940BFC780047FE400043FC7A040BFC08A209140B085D442182
+5F4C:0000F7FC124814441FFEF44486EC855486ECF44416EC155416EC1444A4544408
+5F4D:0040F02017FE148815FCF48887FE842085FCF52415FC152415FC1400A4884904
+5F4E:21084FD2F03C23884812FBBE0280ABAA00003FF000103FF020003FF800080070
+5F4F:03DEFA520BDE0A520BDE78A041FE432045FC792009FE080009FC08885070278E
+5F50:000000007FF800080008000800083FF800080008000800087FF8000800000000
+5F51:04000400040008000FF008101010102020203FE00040004000800080FFFE0000
+5F52:080008004BFC480448044804480449FC4804480448040804100413FC20044000
+5F53:0100210811080910092001007FF80008000800083FF80008000800087FF80008
+5F54:08000FE0082010201FC000400040FFFE010021081190056009203118C5060200
+5F55:00003FF0001000101FF000100010FFFE010021081190056009203118C5060200
+5F56:08000FF010101FE00020FFFE02000D08719002A00CC071A006981886E2800100
+5F57:1010FEFE10107C7C1010FEFE101000007FF8000800083FF8000800087FF80008
+5F58:08000FF010101FE00020FFFE0200421043D2751441184FD041126292444E0820
+5F59:08000FF010101FE000207FFE40029FF411101FF011101FF00100FFFE1110610C
+5F5A:00003FF000101FF000107FFE40029FF411101FF011101FF00100FFFE1110610C
+5F5B:3FF000101FF00010FFFE92485484FF7A3828544892980820FFFE082010202020
+5F5C:08000FF010101FE00020FFFE92485484FF7A3828544892980820FFFE08201020
+5F5D:08000FE010201FC00040FFFE92245478FE1238FE545492920820FFFE08201020
+5F5E:3FF000101FF00010FFFE92245478FE1238FE545492920820FFFE082010202020
+5F5F:0044FDFE04540448FCFE059004FEFC9000FE0890FEFE088049FE2844083819C6
+5F60:7E4403FE3E5402487EFE0190EEFE4A906EFEC09004FEFE8045FE244424380DC6
+5F61:0040008001000600180000200040018006001800001000200040018006003800
+5F62:00007F8412041208121012221202FFC412081210122212022204220842108260
+5F63:100408040808FF90222422442208221214221444080808101420230040FE8000
+5F64:00003F04210421082910252225022104FFC82110212221022104410845108260
+5F65:020001003FF8042003C004203FFC202021C02E10206021882E10406043809C00
+5F66:020001003FF8082004403FFC2000202021C02E10206021882E10406043809C00
+5F67:005000480040FFFE004000507C6045C8445044647DA800120E32F0CA43060002
+5F68:0002FFE2000400087BD04A424A424A446B485AD04A424A424A444A484A505AE0
+5F69:010007847804088844902522200204047F880C10162215022484440884100460
+5F6A:0400078404043FC8245027243C84238820102F24290429084912512290FE2000
+5F6B:00003F84248424882E9024A23F8220842E882A902AA22E822084408842908160
+5F6C:1082108210841088FBD01082308239C455A852909282148210841088109010A0
+5F6D:08000804FF84080808107F2200027F04410841107F22000222041788F8104060
+5F6E:10000804FF848088141022224902140422084110BEA22202220422083E102260
+5F6F:0000FF8414047F08551055227F0200047F080010FFA208022A044908A8901060
+5F70:100008047F0422081410FFA200027F0441087F1041227F020804FF8808100860
+5F71:00007F0441047F0841107F220802FFC400087F1041227F020804490888901860
+5F72:7BC200027BC44A486B504A4204027FC44A087FD04A427FC252445B88525099E0
+5F73:0800080010002000480008001000300050009000100010001000100010001000
+5F74:08400840108020FC490409041204348450449024102410041004100410281010
+5F75:08400840104022404A580A6812C8374852489268125012441244120411FC1000
+5F76:100017F82108411091101120213C6104A1042288228822502420245028882306
+5F77:08400820102023FE48800880108030FC50849084108410841104110412281410
+5F78:082009201120211049100A48124834445882908011101108120817FC12041000
+5F79:080009F01110211049100A0E140033F851089110109010A0104010A013181C06
+5F7A:0800080013FE2020482008201020302051FC9020102010201020102017FE1000
+5F7B:1000120022FC42249224122423A46E24A224222422A423242244204420942108
+5F7C:08200820102023FE4A220A24122033FC52849288124812501220145014881906
+5F7D:0808083C13E022204A200A20122033FE5220921012101212120A128A13261212
+5F7E:0840084010A020A049100A481426302053F890081010111010A0104010201020
+5F7F:08900890109023FC4894089413FC3290529093FE10921092111A111412101410
+5F80:08800840100027FC484008401040304057FC904010401040104010401FFE1000
+5F81:0800080013FE20204820082011203120513C9120112011201120112017FE1000
+5F82:080009F811082108490809F811083108510891F8110811081108110817FE1000
+5F83:082009201120212049FC0A2012203420502091FC102010201020102017FE1000
+5F84:08000BF8101020204860089811043602500093FC104010401040104017FE1000
+5F85:08400840104023FC4840084017FE3010501097FE101012101110111010501020
+5F86:08000FFE1090209048900BFC1294329452949294129C13041204120413FC1204
+5F87:08800880110021FC4A040C0413E43224522493E41224122413E4100410281010
+5F88:08000BF8120822084BF80A08120833F852449248123012201210128813061200
+5F89:09040884108820004BFE0820102031FC5020902013FE10201020102010201020
+5F8A:0800080013FC22044A040AF4129432945294929412F41204120413FC12041000
+5F8B:0840084013F820484FFE084813F83040504093F81040104017FC104010401040
+5F8C:08200840108821104BE00840108833FC5084908011F813081490106011981606
+5F8D:0820082011FC20204820082017FE30005020902011FC10201020102017FE1000
+5F8E:080009FC11042104490409FC1000300053FE9020102011FC1020102013FE1000
+5F8F:082008201120213C4920092017FE300050209124112412281410102010C01700
+5F90:1040104020A04110920815F620406040A7FC2040225022482444284421402080
+5F91:08000BFC100021244A480C9012483124500093FC104010401040104017FE1000
+5F92:0820082011FC20204820082013FE302050209120113C112012A01260143E1800
+5F93:080409041088209048000BFE102030205120913C1120112012A01260143E1800
+5F94:0888088813FE208848880840102033FC5008901010201040108011001280147E
+5F95:10401040204047FC9040124821486150AFFE20E0215021502248244428422040
+5F96:0840082013FE2202480009FC1000300053FE9020112811241222142210A01040
+5F97:08000BF8120823F84A080BF8100033FC501097FE101012101110101010501020
+5F98:089008901090279E489008901090339C509090901090179E1090109010901090
+5F99:082008201120213C4920092017FE300050209120113C112012A01460183E1000
+5F9A:104010402FFE404097FC1444255464E4A44427FC20E0215022482C4620402040
+5F9B:0840084013FC20A049100A0817FE300853C892481248124813C8100810281010
+5F9C:0820092410A420A848200BFE1202320252FA928A128A128A12FA1202120A1204
+5F9D:0840084017FC204048400BF8120833F8520893F8120813F8120812081FFE1000
+5F9E:088808881088208849540A221442302050209120113C112012A01260143E1800
+5F9F:100017FC2444444495F41444244467FCA40425F42514251425F4240424142808
+5FA0:08400840104027FC48400A4812483248555490E0115011501248144418421040
+5FA1:1400140027DE4912911211122FD26112A11225D22512251A25D43E1028102010
+5FA2:1040104027FE404093F8104827FE6048A3F820402240227C2240254024FE2800
+5FA3:11101110211047FC911011102FFE6000A3F82208220823F82208220823F82208
+5FA4:08100810177C211449FE0A14127C3710517C951015FE12101210150018FE1000
+5FA5:080009FC1104210449FC0904110431FC500093FE10201120113C112012A0147E
+5FA6:100017BC24844484948417BC24006400A7BC2424242427A82410242824442482
+5FA7:0840082013FE22024A020BFE1200320053FE9352155215FE1552155219521106
+5FA8:0840088013F822084BF80A0813F8300057FC9040104013F81040104017FC1000
+5FA9:0900090011FE22004DFC090411FC310451FC908010FC11081290106011981606
+5FAA:103C17E02420442097FE142025FC6504A50425FC250425FC2904290431FC2104
+5FAB:0880088013F821084FFE080013F8320853F8904017FC1040144017FE10401040
+5FAC:0840082013FC210848900BFE12023444502093FC108010F81088110811281210
+5FAD:0808083C13C020044A44092811FC3220502093FE102011241124112411FC1004
+5FAE:110815482548455097DE102420146FD4A0142794249424A824C8249428143022
+5FAF:083C0FC0124421284880091013E03040518893FC1044104017FC10A01110160E
+5FB0:08000BFE1020213C4920092017FE300057FE90201120113C1120112017FE1000
+5FB1:100017FC20A047FC94A414A427FC6000A7FC20002FFE20402248244429422080
+5FB2:100017FC240447FC942014A8247064A8A50424A024FC252024202BFE28203020
+5FB3:0820082017FE204048400BFC1294329453FC904010241522150A190810F81000
+5FB4:12101A902A904AA08FBE104420246FA4A22422282FA8221022282FA820442082
+5FB5:110815482548455097DE101427E46014A7D4211427D4210821082FD420242042
+5FB6:1108110825484390911E17D425646554A554275425D4254825482554246424C2
+5FB7:104010402FFE404097FC14A424A467FCA0002FFE204020242522250A290820F8
+5FB8:08400BF8111020A04BFC080013F8324853F8924813F8104013F8104017FE1000
+5FB9:1210111027D0421094BE1FE420546794A49427942494278824882494249425A2
+5FBA:0820082011FC20204BFE0908139C31085188963E100013FE109010901112120E
+5FBB:104010A023184DF6900017FC255464E4A7FC200023F8220823F8220823F82208
+5FBC:121014102F9048909FBE18A42FD46414A2142FD424142788248828942A943122
+5FBD:12101A902A904FA0803E1FC4242468A4AF24222824A83FD022282AA832442682
+5FBE:12101A902A904F90943E12242FD46014AF9420142F9420082F8828942F942022
+5FBF:0910089013DE20104A5E098213DE301053DE925013DE125013DE1250125212CE
+5FC0:104017FC200043B892A813B8211067FCA11027FC21102FFE212823102D482186
+5FC1:0BF80A0813F822084BF80A4813F8344457FC90801FFE1248155418E2115016C8
+5FC2:17BC14A427BC44A497BC14A427BC6120A3FE222027FC2A2023FC222023FE2200
+5FC3:0000020001000080008004000408240424042402440244128410041003F00000
+5FC4:1000100010001000180054005000500090001000100010001000100010001000
+5FC5:00000400021001100120082028482844288449024A028C120810181027F04000
+5FC6:1000100013FC1008181054205040508090801100110012021202120211FE1000
+5FC7:104010401040104019FC54445044504490441084108410841104110412281410
+5FC8:00003FF80000000000000000FFFE000001000880088848044812481287F00000
+5FC9:1000100017FC1084188454845084508490841084110411041204120414281810
+5FCA:1000100013FE1020182054205020502090201020102010201020102010A01040
+5FCB:1000100013F8100818085408500853F892081200120012021202120211FE1000
+5FCC:00003FF0001000103FF02000200420041FFC0100088848844812481287F00000
+5FCD:00003FF802081208120824080808105060200100088848844812481287F00000
+5FCE:001000F83F0001000100FFFE0100010001000000010008844892481287F00000
+5FCF:1010107813C0104018405440504057FE90401040104010401040104010401040
+5FD0:02000200020003F8020002000200FFFE00000100088848844812481287F00000
+5FD1:0000FFFE02000240022002100208020000000100088848844812481287F00000
+5FD2:0048004400440040FFFE0040084004401440554050A050A29292120A0E060002
+5FD3:100011FC1020102018205420502053FE90201020102010201020102010201020
+5FD4:10801080110011FE1A00540051F8500890101060108011001202120211FE1000
+5FD5:1040104010401840544053FE50409040104010A010A010901110110812041402
+5FD6:10101010101010101BFE54105010501091101090109010101010101010501020
+5FD7:0100010001087FFC0100010001103FF800000A102908292C6824482407E00000
+5FD8:02000100FFFE10001000100010001FF800000100088848844812481287F00000
+5FD9:10201010101010001BFE54805080508090801080108010801080108010FE1000
+5FDA:1020102010201120192C5534516453A491241134112811221122110210FE1000
+5FDB:100011F0111011101910551051905150915011101110111211121212120E1400
+5FDC:010000803FFE2000210020802240220022002A082A042A145210421081F00000
+5FDD:00003FF801000100FFFE0280044009203118C106119011482124412405000200
+5FDE:020001007FFC0820044003800C603018C0060100088848844812481287F00000
+5FDF:10401020102013FE188854885088508890881050105010201050108811041602
+5FE0:010001003FF82108210821083FF8210801000100088848844812481287F00000
+5FE1:10201020102010201BFE5622522252229222122213FE12221020102010201020
+5FE2:00007FFC020002003FF0041004100810FFFE0000010008844892481287F00000
+5FE3:100013FC1084108818885490509C508491441144112811281210122814441182
+5FE4:10801080108011FC192056205020502093FE1020102010201020102010201020
+5FE5:100010003FFC20004FF080003FF000100810041014905050514A514A8F060002
+5FE6:1040104010A018A0551052085406911011101110111011101110121012101410
+5FE7:10901088108810801BFE54A050A050A090A010A01120112211221222121E1400
+5FE8:1000100013F818005400500057FC9120112011201120112012221222141E1800
+5FE9:04400440082010102208C44608201FF000100100088848844812481287F00000
+5FEA:102011201120191055105248524894441882108011101108120817FC12041000
+5FEB:10401040104013F8184854485048504897FE104010A010A01110111012081406
+5FEC:100013F81008191054A0504057FE904210441040104010401040104011401080
+5FED:10401020102010001BFE54405040506090501048104410441040104010401040
+5FEE:10401040104017FE18405440504057F892081208111010A0104010A011181606
+5FEF:1008103C13E012201A205620522053FE9220121012101212120A128A13061202
+5FF0:1080108013F01890549051125112924E144010401FFE10401040104010401040
+5FF1:10401040104013FC1A4454485040504090A010A010A0112011221222141E1800
+5FF2:10401040104010401BFE5440504050A090A010A0111011101288124814441802
+5FF3:10201020102013FE1820552451245124912411FC1024102010221022101E1000
+5FF4:1040104010A018A05510528854469040100013F8100810101010102010201040
+5FF5:01000100028004400A203118C1060FE000400080010008844892481287F00000
+5FF6:1000100011FC18005400500053FE90201020104010401088110413FE11021000
+5FF7:10001008110810881A5256525222522292521292130A120A120213FE10021000
+5FF8:100013F81088108818885488508857F891081108110811081108110817FE1000
+5FF9:1000100013FE1020182054205020502091FC1020102010201020102017FE1000
+5FFA:10801080108010FC1904550852405440904010A010A010901110110812041402
+5FFB:1008101C11E011001900550051FE511091101110111011101110121012101410
+5FFC:10801040104017FC1800540051F05110911011101110111211121212120E1400
+5FFD:080008001FF81248224844880888110822280410010008844892481287F00000
+5FFE:1100110011FC1A00540051F85000900013F8100810081008100A100A10061002
+5FFF:0440082010102FE8C4260420082010A060400100088848844812481287F00000
+6000:1000100017FE102018205440504050D091481244144210401040104010401040
+6001:010001007FFC0100028004400A203118C0060100088848844812481287F00000
+6002:0820082008200820145012502288208841048202010008844892481287F00000
+6003:100013FC104018405440504057FE904010A010A010A0112011221222141E1800
+6004:100013FC120012081A8856505250522092201250125012881308120013FE1000
+6005:110011081108111019205540510057FE91401120112011101108114411821100
+6006:1040104010A018A055105208540691F011101110115011201104110410FC1000
+6007:100013FE120012001A0057FC520452049204120413FC12001200120013FE1000
+6008:10481248124812481A4857FE5248524892481248127812001200120013FE1000
+6009:1080108011FC11041A0455F451145114911411F4110411281112110210FE1000
+600A:100013FC108410841884550451145208940011FC110411041104110411FC1104
+600B:100013FC120412041A0457FC5220522093FE1220122012101212128A13061202
+600C:100013FC102010201840544050D0514892441444104010401040100017FE1000
+600D:10801080108018FE554051405240907C104010401040107E1040104010401040
+600E:080008000FFC1400240047F00400040007F80400010008844892481287F00000
+600F:10401040104013F81A48564852485248924817FE104010A010A0111012081406
+6010:10801080110011FC1A04540451E451249124112411E411241004100410281010
+6011:2040224421483150A840A7FCA040A04020402FFE204020402040204020402040
+6012:10001000FEFC22844488285010202858C5860000010008844892481287F00000
+6013:21002100213E211237D2AA52A252A254A254249422882108229424A428422080
+6014:1000100013FE10201820542051205120913C1120112011201120112017FE1000
+6015:10201020104011FC190455045104510491FC1104110411041104110411FC1104
+6016:10401040104013FE188054A0512051FC93241524112411241134112810201020
+6017:104010401040187E544050405040904013FC1204120412041204120413FC1204
+6018:010001007FFC010001001FF0101010101FF00100088848844812481287F00000
+6019:10201020102010201BFE54205020502091FC1104110411041104110411FC1104
+601A:100011F811081108190855F851085108910811F8110811081108110817FE1000
+601B:1000100011FC11041904550451FC51049104110411FC11041000100013FE1000
+601C:1040104010A018A0551052485426902013F810081010111010A0104010201020
+601D:00003FF8210821083FF8210821083FF820080100088848844812481287F00000
+601E:10201020102010201BFE562252225222922213FE122212221222122213FE1202
+601F:1008103C13E012201A205620522053FE9220121012101212120A128A13261212
+6020:02000400082010103FF800081FF0101010101FF0010008844892481287F00000
+6021:10201020104018405488510453FE9002100011FC110411041104110411FC1104
+6022:102010201120112019FC55205220502093FE1020105010501088108811041202
+6023:090009001FF0210001007FFC0280044008203018C10608844892481287F00000
+6024:0810081017FE3010521091101110105010200100088848844812481287F00000
+6025:08000FE0102020405FF8000800081FF8000800083FF802005104511290120FF0
+6026:100013F8104010401A4855485150504097FE1040104010401040104010401040
+6027:102010201120112019FC552052205020902011FC102010201020102013FE1000
+6028:100010F83E884288A2A8149008841084207CC000010008844892481287F00000
+6029:100011FC11041104190455FC51005140914411481170114011421242123E1400
+602A:100017F81208111018A0544050A053189C46104017FC1040104010401FFE1000
+602B:10901090109013FC1894549453FC5290929013FE10921092111A111412101410
+602C:1000100013FE12521A5256525252525292521292128E13021202120213FE1202
+602D:1000104010201028180854885090529492A212A214C210881188128814781000
+602E:2220222022203420AD7CA924AE24A2242424242429242F242144204420942108
+602F:10401040104010401BFC54405040504097FE1040108010801110120817FC1204
+6030:10401020102013FE184054405088510893F0102010401088110413FC11041000
+6031:080008001FF812482A4844880A88110822A80410010008844892481287F00000
+6032:100013FE10201020182057FE522252229252124A128A130212021202120A1204
+6033:100013FC120412041A04560453FC5090909010901090111211121212140E1800
+6034:10281024102410201BFE56205224522492241228122812901312122A10461082
+6035:10201028102410201BFE54205070507090A810A8112412221420102010201020
+6036:10201020102013FE1A225624522053FC92841288124812501220145014881906
+6037:011001080100FFFE01001110111011102110C00E010008844892481287F00000
+6038:0120011001007FFC0380054009203118C1060000010008844892481287F00000
+6039:104010402240227863C8AE48226822522242220221FE02005104511290120FF0
+603A:10401020101019E05422503453B890B010A810A8112811241224142210A01040
+603B:10100820044000001FF01010101010101FF01010010008844892481287F00000
+603C:000800087E0802FE240814480828140822284010010008844892481287F00000
+603D:10401040104013FC18405440504057FE90E01150115012481444184210401040
+603E:1000100011FC1104190455045104510491FC1104100010901088110412021402
+603F:100017F81208111018A0544051B0564E904013F81040104017FC104010401040
+6040:1040104010FC11081A90546050485190963E1042108413481030102010C01700
+6041:08380BC01040304057FC90401040104013F80100088848844812481287F00000
+6042:10801080110011FC1A04540453E45224922413E41224122413E4100410281010
+6043:1040104010401BFC5440504057FE9010101017FE101012101110111010501020
+6044:10201020102013FE1820542051FC5000900011FC110411041104110411FC1104
+6045:10401040104419F45448505053FE904010801184129814E010821082107E1000
+6046:100017FE10801080188054F85108514891281208128810501010101017FE1000
+6047:100013FE120012001BFC5620522052F892201220122013FC1200120013FE1000
+6048:10401040109011081BFC54245120512091FC1220102017FE1020102010201020
+6049:11001104113811C01902550250FE500091FC1104110411FC1104110411FC1104
+604A:2040204023FC3084A884A114A208A01024102FBE24922492249228A22AAA3144
+604B:02000100FFFE0440145014482444444400000100088848844812481287F00000
+604C:109010901090129219945498509051989294149210901090111211121212140E
+604D:10401044124419485550504057FE9090109010901090109211121112120E1400
+604E:100013FE102010401888550453FE50229020102013FE10201020102017FE1000
+604F:100010FCFE042208221064FE141008103450C220010008844892481287F00000
+6050:00007DF011101110119011501D12E212440E0800010008844892481287F00000
+6051:1040104010FC11041A0855FE5100517C914411441154114811421242123E1400
+6052:100013FE1000100019FC5504510451FC9104110411FC11041000100013FE1000
+6053:100017FE10901890549053FC5294929412941294129C13041204120413FC1204
+6054:10401020102013FE180054885104520290881088105010501020105010881306
+6055:10001000FE7C2244444434440844147C2244C000010008844892481287F00000
+6056:020004003FF8244822882108228824483FF80100088848844812481287F00000
+6057:1020102013FE10501888550452FA500093FE1040108011FC1004100410281010
+6058:109010901090191055FE53105510913811381154115411921110111011101110
+6059:082004407FFC010001003FF801000100FFFE0100088848844812481287F00000
+605A:01003FF801000100FFFE000001003FF801000100FFFE02005104511290120FF0
+605B:1000100013FC12041A0456F4529452949294129412F41204120413FC12041000
+605C:102810241024182057FE5020502097E0112011101110111011CA170A12061002
+605D:080008007F7C08243E2408247F44085408880100088848844812481287F00000
+605E:1040104017FC10401BF8544853F8524093FC1044105410A810A0111012081406
+605F:11001100110019FE56025202551298A2124A12AA131A120A13FA100210141008
+6060:10401040104013FE1880549051105110937C151011101110111011FE11001100
+6061:10081190106010981B045440504057FE90801090111011201248148419FC1084
+6062:10401040104013FE188054905090511291521154129012281428104410841102
+6063:4080208009FC12042448E04020A023182C060100088848844812481287F00000
+6064:10401040108011001BFC56945294529492941294129412941294129417FE1000
+6065:0000FF20241024103C00244024403D44254225422E42F4484448044804380400
+6066:10401040108013FC1A04560452F4529492941294129412F41204120412141208
+6067:0000FFFE020004003FF824882488248824A82010010008844892481287F00000
+6068:100013F8120812081BF85608520853F892441248123012201210128813061200
+6069:00003FF8210821082FE821082288244828283FF8010008844892481287F00000
+606A:1080108010F811081B1054A0504050A09118120615F811081108110811F81108
+606B:200027FC2404240435F4AC04A404A5F4A5142514251425F42404240424142408
+606C:1008103C11E01020182055FE50205020902011FC110411041104110411FC1104
+606D:044004403FF804400440FFFE0440082012102208C2261290124822480A000400
+606E:1040104010A011101A08540653F850409040104013F810401040104017FE1000
+606F:010002001FF010101FF010101FF010101FF01010010008844892481287F00000
+6070:1040104010A011101A08540653F85000900013F8120812081208120813F81208
+6071:10901090110811481A445492510853FC909410901090109011121112120E1400
+6072:11041084108810001BFE548850885088908817FE108810881108110812081408
+6073:00003FF020103FF020103FF0220821902C60301C010008844892481287F00000
+6074:02000100FFFE00003FF820083FF820083FF80100088848844812481287F00000
+6075:01000100FFFE01003FF821083FF821083FF80000010008844892481287F00000
+6076:00007FFC04402448144814500440FFFE00000100088848844812481287F00000
+6077:08400840104037FC50E091501150124814441842104002005104511290120FF0
+6078:2010201027903010A87EA012AFD2A21222122422252228A22FC2204220942108
+6079:100013FE122012281A24562053FE522092201250125012501488148819041202
+607A:102011241124112419FC540051FC5004900411FC110011001102110210FE1000
+607B:200427C4244424543554AD54A554A554A5542554255421042284224424142808
+607C:10401020102017FE180054005090525492241224125412941204120413FC1004
+607D:100013FE12021C44544053FC508090A0112011FC1020102017FE102010201020
+607E:1090109017FE109018905440502057FE91001100110011001100110011FC1000
+607F:3FF0066001803FF821083FF821083FF821082018010008844892481287F00000
+6080:100013FC100818D0542053FE5222922213FE1222122213FE12221222122A1204
+6081:100011F81108110819F8540053FC5204920413FC1204120413FC120412141208
+6082:12201224122813B01A20562252A2531E9040104013FC10401040104017FE1000
+6083:200027FC244424443444AFFCA444A4C4A4E42554264424442444240427FC2404
+6084:1020112410A410A8182055FC5104510491FC1104110411FC1104110411141108
+6085:10101090108811081A0455FA51085108910811F810901090109011121212140E
+6086:010002800C603018CFE601003FF8111025080200010008844892481287F00000
+6087:1040104010A011101A0855F65040504097FC1040125012481444184411401080
+6088:10101014101210101BFE54105150515497F4115411541148124A125A14261042
+6089:00F83F00111009200100FFFE092011102108C006010008844892481287F00000
+608A:080C08F07E8008800EFE78880888290812080100088848844812481287F00000
+608B:1040102017FE11081890546050605198960611F8110811081108110811F81108
+608C:11081088109013FC1824542453FC5220922013FE106210A2112A122414201020
+608D:100011FC110411FC190455FC5000500091FC1020102013FE1020102010201020
+608E:10201120112011FE1A205420502053FE9000100011FC11041104110411FC1104
+608F:10201020102013FE1820542051245124912412AA102010501050108811041202
+6090:4420282010A428A448A8992028204850885008885104220201004884481287F2
+6091:1048104413FE1840544053FC5244924413FC1244124413FC1244124412541208
+6092:100011F81108110819F8540053FC52449244124413FC12001202120211FE1000
+6093:100013F8120812081BF85608520853F89208120813F81120112012221422181E
+6094:1100110011FC1A0055F851085148912817FE11081248122813FC100810501020
+6095:2208211020E03110AA08A080AFFEA140224027FC2A4422442254224820402040
+6096:1020102013FE1820542053FE5202940411F81010102013FE1020102010A01040
+6097:1080108011F81A08541053FC52449244124413FC10A010A011221122121E1400
+6098:00003FF8240027F028803FFC2140222024103FFC010008844892481287F00000
+6099:1040102013FE100019F85508510851F8900013FC100810301020102010A01040
+609A:1020102013FE1020182055FC5124512491FC1020107010A81124122210201020
+609B:10401040108811041BFE540250885144924210F8118812501020105011881606
+609C:100011FC11041104190455FC5000500093FE1020102011FC1020102013FE1000
+609D:200027FC2444244437FCAC44A444A7FCA040204027FC2040204020402FFE2000
+609E:100010F8108810881AF85600520053FC9044104417FE104010A0111012081406
+609F:100013FE1040104019FC5484508453FE9000100011FC11041104110411FC1104
+60A0:10401040247E6488A54824502420205820862300010008844892481287F00000
+60A1:0604780408440844FF441C442A44490488140808010008844892481287F00000
+60A2:1080104013F812081A0857F85208520893F81240124412281210128813061200
+60A3:01001FF0111011101FF001003FF8210821083FF8010002005104511290120FF0
+60A4:020004003FF8220823C824482A882108228824083FF8200801004884481287F2
+60A5:02000100FFFE00003FF800003FF800003FF820083FF802005104511290120FF0
+60A6:12081108111010201BF856085208520893F810A010A0112011221222141E1800
+60A7:108411C4170411141914551457D4511493141394155415041904110411141108
+60A8:0900090011FC3204544899501148124414441140108002005104511290120FF0
+60A9:104212221124110418085400520A528A925212221252128A130A120213FE1002
+60AA:00007FFC04403FF8244824483FF80440FFFE0100088848844812481287F00000
+60AB:01007FFC01003FF800007FFE40028FE4082010222022C11E288828A4482407E0
+60AC:1FF010101FF010101FF01010FFFE082010103FF810080100288828A4482407E0
+60AD:108012FC12A412A41AA8569052A850C69020102011FC10201020102013FE1000
+60AE:200023F82208220833F8A800A000A7FCA04020402FFE204020A0211022082C06
+60AF:110010BE128212021A42562253FE5292925212221252128A130A1202120A1204
+60B0:1040102013FE1202180055FC5000500093FE1020112811241222142210A01040
+60B1:109010901090179E189054905090539C909010901090179E1090109010901090
+60B2:044004407C7C044004403C78044004407C7C0440010008844892481287F00000
+60B3:00803FFE008007F8240827F8240827F8240827F820003FFE01004884481287F2
+60B4:1080104013FC18005510511052A894441000104017FE10401040104010401040
+60B5:100010FC108018F8548050F8508097FE11401124112811101108114411821100
+60B6:00007C7C44447C7C44447C7C42044104450454245454645443C4400440144008
+60B7:1040102013FC12041A0457FC52005228922413FE122012501250148815041A02
+60B8:203823C0204027FC30E0A950A248AC46A3F02020204027FC2040204021402080
+60B9:01007FFE40029FE410201FE010001FF0101010101FF002005104511290120FF0
+60BA:1040102013FE1A02540451F85108910811F81100110011FC1104110411FC1104
+60BB:1020102013FE1020182057FE5088505093FE1020102017FE1020102010201020
+60BC:10401040107E10401BFC560453FC520493FC1244104017FE1040104010401040
+60BD:1040104017FC10401BF8544857FE504893F8108017FE11081390106011981604
+60BE:10401020102013FE1A02549451085204900011FC102010201020102017FE1000
+60BF:100013FC104010401BFE54A05110520894461040104812641252145211401080
+60C0:2040204020A03110AA08ADF6A000A7FC24A424A427FC24A424A424A424142408
+60C1:080C08F07E8018802CFE2A884888888809080100088848844812481287F00000
+60C2:1080108010F811081A1054005040539C92041204139C12041204120413FC1204
+60C3:100013FC120412041BFC5604520453FC90001220122413A81230122212A2131E
+60C4:08000F7C08440844FF4808282A30491089282844108202005104511290120FF0
+60C5:1020102013FE102051FC582057FF940011FC110411FC110411FC11041114110C
+60C6:100013FE122212221AFA5622522253FE920212FA128A128A12FA1202120A1404
+60C7:1040102013FE100019FC550451FC500091FC1008101013FE1020102010A01040
+60C8:100013F8124812481BF85648524853F8904017FC10E011501248144610401040
+60C9:10400840407E2040084013FC7204120413FC1000010008844892481287F00000
+60CA:1040102013FE1000180055FC5104510491FC1020112811241222142210A01040
+60CB:1040102013FE12021D04550051DE525292521352149A1094111011121212140E
+60CC:020001007FFE400290041EF8228824A8549008841084607C01004884481287F2
+60CD:1040104010A011101A08540651F05040904013F8104012481148115017FC1000
+60CE:08207FFC08200FE008200FE00820FFFE10102208C10609002828282447E40000
+60CF:211021102110211037BCA910A110A338A3B82554255429922110211021102110
+60D0:10141012101017FE1810541053D252529252125413D4100810EA171A12261042
+60D1:00500048FFFE00403E4022243E2800120E2A70C603020100288828A4482407E0
+60D2:0600787C08440844FF441C442A44497C88440800010008844892481287F00000
+60D3:1020112410A81BFE5440508057FE9108120415FA1908110811281112110210FE
+60D4:104012441244144818A0551056085044904012481248145010A0111012081C06
+60D5:100011FC110411FC190455FC5080508091FE124A144A10921122124210941108
+60D6:1FF010101FF010101FF008001FF82248448809081228241001004884481287F2
+60D7:2040204020A03110AA88A446A800A3F020102020204021242522250A290820F8
+60D8:100013FE1202128A1A5257FE5242522293FE12821282128212FA1202120A1204
+60D9:200027BC208422943108AA94A4A4A840A00027BC20A422A42128229024A82846
+60DA:1080108010FC11541A5454A45124524490941108104010A412AA128A14781000
+60DB:101C13E0122013FE1A205692530A520691FC1104110411FC1104110411FC1104
+60DC:10881088108813FE1888548857FE500091FC1104110411FC1104110411FC1104
+60DD:1020112410A410A8182057FE5202520292FA128A128A128A12FA1202120A1204
+60DE:201020902710243E3422AC44A790A510A5102510252825282528294429443082
+60DF:10A01090108011FE1910571055FC5110911011FC11101110111011FE11001100
+60E0:010001007FFC01003FF821083FF821083FF80104FFFE0102288828A4482407E0
+60E1:00007FFC04403C78200820083C780440FFFE0000010008844892481287F00000
+60E2:01000080088848044812481287F00000101008082220A124A4A2A4A41D1C0000
+60E3:108050807CFC515492541CA4F124124410941108010008844892481287F00000
+60E4:10101388108810FE1890579052245224923813881090109010A410BE12821100
+60E5:01000500397821083D7821083FF8028004401830E10E08844892481287F00000
+60E6:1040102013FE12001A205620523E5220922012FC128412841284148414FC1884
+60E7:100013F8120812081BF8560853F8520893F8120812081FFE1000111012081404
+60E8:20802090210833FCA840A7FEA110A2482C862310202020C42308203020C02700
+60E9:100023FE40208920113C31205120912017FE1000010008844892481287F00000
+60EA:01007FFC01001FF010101FF010101FF010101FF01010FFFE01004884481287F2
+60EB:08000FF010202C4003801C70E00E1FF011101FF011101FF001004884481287F2
+60EC:200027FE2420242035FCAC20A524A4A8A7FE2420245024482484250427FE2000
+60ED:21002102211C2FD03210AA10A51EA7D4A114211421D42F142514212421242144
+60EE:11041088105011FC1924552451FC5124912411FC1020102013FE102010201020
+60EF:11FC1124112413FE1924552451FC500091FC1104112411241124105810841302
+60F0:1040104013FE108019FC562055FE500091FC110411FC110411FC110411141108
+60F1:109211241248112418925440508053FE9202128A125212221252128A13FE1202
+60F2:100013FE122210201BFE542051FC512491FC112411FC102013FE102010201020
+60F3:080008F808887E8808F818881CF82A88488808F8010008844892481287F00000
+60F4:2040244424443444AFFCA000AFFEA040208027FC24A424A424A424A424A4240C
+60F5:10901290129017FE1A90569052F0520093FC104017FE10E0115012481C461040
+60F6:1020104011FC110419FC550451FC500093FE1020102011FC1020102013FE1000
+60F7:01007FFC01003FF80200FFFE08201FF02828CFE608200FE001004884481287F2
+60F8:110011FE120215F2191255F2511251FA900413F81010102017FE102010A01040
+60F9:08207FFC08200200FFFE08001FF02810C8100FF0010008844892481287F00000
+60FA:100011FC110411FC190455FC5020512091FE1220102011FC1020102013FE1000
+60FB:200227C22442245237D2AC52A452A7D2A452245227D2200222822242244A2804
+60FC:1040102013FE12021A0257FE5200520093FE1352155215FE1552155219521106
+60FD:100013FC120413FC1A2057FE5210528A9306100013FC120413FC120413FC1204
+60FE:10001088125212221A52568A520253FE90881144127A10881150102010D81706
+60FF:100011FC1104110419FC5504510451FC900013FE10201120113C112012A0147E
+6100:208821C827083108A92AA12AA7ACA14823082388255425142914212421242142
+6101:0E207820082408A4FEA819202C504A50888809040A020100288828A4482407E0
+6102:08107F1008107F7E41123E1204120F1278220822284A108401004884481287F2
+6103:1040102013FE1A02540451FC500091FC110411FC110411FC1104100013FE1000
+6104:100013F8124812481BF85648524853F8900017FE124012441228129013081206
+6105:2110211027FC211031F0A840A3F8A248A24823F820402FFE2040204020402040
+6106:1200213C48009400217E6208AE08220822282210210008844892481287F00000
+6107:1040104011FC10841BFE540051FC510491FC102013FE1020122013FE10201020
+6108:010002800C6037D8C0063E0822483E4822483E482208261801004884481287F2
+6109:104010A0111012081DF6540053C45254925413D41254125413D41244125412C8
+610A:100013FE100011FC1904550451FC500093FE1222122213FE1222122213FE1202
+610B:103C17C012441928540053FC5080908017FE110011F812881250142018D81306
+610C:1080108010F811081A1055FC51045154918C1124102013FE1050108811041602
+610D:00207F20413E7F4448A47F244828451053286146010008844892481287F00000
+610E:1100110011FE1A0055FC510451FC910411FC108010FC11081290106011981606
+610F:01003FF808200440FFFE00001FF010101FF010101FF002005104511290120FF0
+6110:100017FE104010801BFC5694529452F49294129412F412941294129413FC1204
+6111:100013FC108810501BFE562253FE522293FE1222104013FE1042108211141208
+6112:100013F812081BF8560853F8510093FC1444124412A4120413F4100410281010
+6113:200023F8220833F8AA08A3F8A000AFFE220023FC249429242244248421282210
+6114:2080204027FC3000AA08A110AFFEA00023F82208220823F82208220823F82208
+6115:200027BC24A424A437BCA800A3F8A000A7FC2100220023F82008200820502020
+6116:1110111017FC111019F0551051F05110911017FE120012901308120013FC1000
+6117:00407F40127E0C88FF4819482A504820A850108C010008844892481287F00000
+6118:1040102013FE1202188054F85108529090601198160611F81108110811F81108
+6119:020001007FFE48029FF4282007C01830E00E1FF010101FF001004884481287F2
+611A:1FF011101FF011101FF001003FF8210821482FE82428201001004884481287F2
+611B:007C3F80110808907FFE41029494142823E808000FF01420224041800E60701C
+611C:200027FE2420242035FCAC20A4A8A4A8A5742420245024482484250027FE2000
+611D:100013FE120012FC1A8456FC528452FC922013FE124812C812301248128413FE
+611E:100013FE102010401BFE56525252525292421226102017FE1050108811041602
+611F:002800243FFE20202FA420242FA8289828924FAA4046808201004884481287F2
+6120:100011F81108110819F85508510851F8900013FC129412941294129417FE1000
+6121:1080108010FC11541AD454B4512C524490941108104010A412AA128A14781000
+6122:100013FC124412441BFC5644524453FC9000104010241522150A190810F81000
+6123:100013FC12941A94569453FC5080904017FE108010F810881108110812281410
+6124:102011FC102010881BFE5488500051FC91041124112411241124105010881304
+6125:2110211027FC21103150A840A3F8A248A24822482FFE204020A0211022082406
+6126:1020102011FC192455FC502053FE900011FC1104112411241124105010881304
+6127:2040208027FC24443444AFFCA444A484A7FC208021502164227C24422842303E
+6128:08007F7808483E4800867F78414800303ECE0000010008844892481287F00000
+6129:100011FC102010201BFE540051FC510491FC110411FC110411FC108811041202
+612A:100011F81108110819F8540053FC520493FC120413FC120413FC109011081204
+612B:1040104017FC10401BF8544057FE5080911013E0104817FC1044124815441080
+612C:2200147CFF44087C4944497C7F44084410942108410008844892481287F00000
+612D:1040104411F810501BFE544050F85182927E140011FC110411FC110411FC1104
+612E:1008103C13C010041A44552851FC5220902013FE102011241124112411FC1004
+612F:10A0109011FE1B2055FC512051FC912011FE110013F811081090106011981606
+6130:100011FC110411FC190455FC5020512490A8102013FE1090109011121212140E
+6131:1020101011FE190055205120553C93501190131015FE11101128122812441482
+6132:100011F8110811E8192857FE540251F8910811F8110811F81108110811281110
+6133:00003E7C22443E7C22443E7C22443E7C00000100088848844812481287F00000
+6134:10201020105018C8552453FE550491FC110411FC110011FC1284128414FC1084
+6135:100013DE104210421BDE5610521053DE90421252114A114A1252104212941108
+6136:104011FC10441094190857DE514A514A929411FC110411FC110411FC1104110C
+6137:1040124812481A4857F8500057FC900013F81208120813F8111010A017FE1000
+6138:082008207F7C2A242A245D2408241C442A944808010008844892481287F00000
+6139:2040202023FE22023494A908A264A090A108220425FA21082108210821F82108
+613A:1088108813FE1088180055FC510451FC910411FC1124102013FE102010201020
+613B:000C7DF00440088811F010201C44F3FE102211245222206001004884481287F2
+613C:120C13F2120219FE540051FC550495FC150415FC150415FC140017FE11041202
+613D:1028102413FE102019FC552451FC512491FC1124100813FE1088104810481018
+613E:1100110011FC1A0055F8500053F8908812A811C817F8108A11CA16AA10861082
+613F:00003FFE208027F8240827F8240827F8225024482944208020444A424A1291F0
+6140:103C17C0124419285480511053E09040118813FC1044104017FC10A01110160E
+6141:3FF820082FF822082D2822C82DA822982D8820083FF802005104511290120FF0
+6142:200017F8911040A047FC144427FCE44427FC244424040100288828A4482407E0
+6143:2120211022083486A910A3F8A008A00027BC208424A4229424A4208422942108
+6144:200027FC20A020A037FCACA4A4A4A7FCA040204027FC20E0215022482C462040
+6145:100013F81148111018A0544051B0564E904013F81248124813F8104417FC1004
+6146:103C13C010441224192855005040539C92041204139C12041204120413FC1204
+6147:0600387820483E4822863E0022FC3E4420283E1022284A4685004884481287F2
+6148:08200440FFFE10201020244878F0102024487EFC02040100288828A4482407E0
+6149:2080204027FC20803108ABF0A060A184A7FE200227FC244427FC244427FC2404
+614A:211020A0200027FE30A0ABF8A0A8A7FEA0A823F820A021B022A82CA620A020A0
+614B:108024987EE000847E7C42007E9842E07E844284467C02005104511290120FF0
+614C:2108210827FE21483020AFFEA200A200A3FC2000224822482248244A244A2846
+614D:200023F8224822A83318AA08A3F8A000A00027FC24A424A424A424A42FFE2000
+614E:2040204027FC204033F8AA08A3F8A208A3F8220823F822082FFE211022082404
+614F:100013FE1202100019FC550451FC510491FC1040102013FE1000108811041202
+6150:3FF801007FFC00001FF010101FF010101FF010101FF0082011104884481287F2
+6151:200023FC210821F83108A9F8A10EA7F8A00827BC20A422A42128229024A82846
+6152:1050105013FE10501BFE565253FE525293FE100011FC110411FC110411FC1104
+6153:20002FFE20A027FC34A4ACA4A7FCA000A7FC20002FFE20402248244429422080
+6154:2110211027FC21103000ABF8A208A3F8A20823F8204027FC20A0211022082C06
+6155:04407FFC04401FF010101FF010101FF00400FFFE12102208CB2612902A900400
+6156:200027FE242A242637FEAC22A7AAA6AAA7AA24322596262E2446248227FE2402
+6157:08200820FFBE08447FA449247F281C282A1049288844088201004884481287F2
+6158:2080211023F8221034A4AFBEA042A0A0A3182C46219026642188263021C02E00
+6159:08047F7808407F40497E7F4849487F4808487F48088802005104511290120FF0
+615A:22002202223C2FA03220AFA0AABEAFA4AAA42FA422242FA42224224422442284
+615B:1020122213FE1090188855FE5310551091FE1110111011FE1110111011FE1100
+615C:20203FA0403EBF4429A425247FE8292845107FA8014402825104511290120FF0
+615D:3FFC24202FF825203FFC220027F02A1033F020003FFC02005104511290120FF0
+615E:102011FC108810501BFE540051FC510491FC110411FC102013FE102010201020
+615F:21C8270821082FE8311EAFCAA54AA7CAA54A27CA210A27CA211221D22E2A2444
+6160:21082108210827D0311EAF94A124AFD4A21423D422542248224824D424242842
+6161:2040204027FC20403554AA48A554A040A5542248255420A020A0211022082C06
+6162:23F8220823F83208ABF8A000A7FCA4A424A427FC200023F8211020E023182C06
+6163:100011FC112413FE192455FC500051FC910411FC110411FC110411FC10881104
+6164:08787F4808483E8600787F4841489C2815102628404602005104511290120FF0
+6165:10101450127C1290181054FE50005600927C12441244127C1244150018FE1000
+6166:0A2009207FBE08446AA41C242A28491028281046010008844892481287F00000
+6167:1010FEFE10107C7C1010FEFE10103FF800081FF800083FF801004884481287F2
+6168:200027BE2488248837A8ACA8A4A8A7BEA4102518249825A826AA244A20462080
+6169:2010241022FE3210A8FEA092A6FEA29222FE221022FE22102210251028FE2000
+616A:100013FE1200127C1A445644527C520092EE12AA12AA12AA12EE120013FE1000
+616B:1110211041108AA814443240527C9240154018FE110008844892481287F00000
+616C:1088108813FE108818F8542051FC512491FC102013FE102011FC102013FE1000
+616D:081408127F104AFE2C10FF101C282A2849448882010008844892481287F00000
+616E:010001FC01003FFE21022FF4210027F8244827F8244827F820804A44521281F0
+616F:110011FC120015F8190855F8510851F8900017FE110013FC14A4112412541088
+6170:3F0821083F7E20082F4820285FA8440895282C90010008844892481287F00000
+6171:102013FE102011FC192455FC512451FC902213FE100813FE1108108810281010
+6172:1088108813FE1088188854F8502053FE9222133212AA137612221222122A1224
+6173:200027DC251427D43454AFC8A508A514A7E22000204027FC204020402FFE2000
+6174:100013DE10421252194A56525042502091FC1104110411FC1104110411FC1104
+6175:202027FE242025FC3424AFFEA424A5FCA42025FC252425FC252429FC2924312C
+6176:00803FFE22203FFC22243FFC20003FFE20822A5431F2220027F84A0841F09E0E
+6177:2040202027FE242035FCAC24A7FEA424A5FC2420256224B429282A2630A02040
+6178:145014507FFC245247CE80007FFC41041FF011101150112001004884481287F2
+6179:10407C4011F8FE48444828C87C68109AFE8A1106120202005104511290120FF0
+617A:204023F822482FFE3248ABF8A040A3F8A24823F820802FFE211020E023182C04
+617B:10401248115013F8188057FC5110520897FC1A0A13F8120813F8120813F81208
+617C:002800243FFE2220232422242FA822282A92522A46468102288828A4482407E0
+617D:20142012201027FE3410AC90A4D2A492A7F22494249425C82AAA289A31A62042
+617E:14202220493E144222944110BE28222822443E82010008844892481287F00000
+617F:43FE222023FC0A200BFC1220E3FE212227FA2122022602005104511290120FF0
+6180:100017BC108414A41A9454A450505188962610C0131010641388103010C01700
+6181:1040108013FC12441AF4571452A4524492A413FC104010241522150A190810F8
+6182:7FFC02001FF010101FF010107FFE41029494142823E808001FF0682007C0F83E
+6183:01007FFC01003FF80200FFFE08203CF8D0161CF010101FF001004884481287F2
+6184:104027FC40408BF8120833F8520893F8120813F8120817FE01004884481287F2
+6185:7F200820FF2008FC7F2449247F2449247F2408447F440894FF08020851249FE4
+6186:1020112410A813FE1A0254F85088508890F81020102011FC1020102013FE1000
+6187:0688388809FE7E88088808F83E88228822883EF8010008844892481287F00000
+6188:1040107C104013FE1A42567853C4523C920012501254135414D8145019FE1000
+6189:1082108217F41088188057E2500253E49228122013E012221142107417881210
+618A:111017FC21102FFE6100A3F826482BF8224823F82248225801004884481287F2
+618B:082049202A3E7F4449A45D286B28491049284346010008844892481287F00000
+618C:08401440227C5C8489443E2C08144A2428C40E28701022005104511290120FF0
+618D:203823C0208027FE3110AA08A5F6A910A1F0200027FC240425F4251425F4240C
+618E:11041088100013FE1A2256AA5272522293FE100011FC110411FC110411FC1104
+618F:2100211023DC22543554AA88A108A2F4A402200023FC20402150224825442080
+6190:20402248215027FC3150AA48A444A208A20823BE24882AA8213E220824082808
+6191:43FC22400BF80A4013F82240E3FC200425542008010008844892481287F00000
+6192:104013F8124813F8184057FE500053F8920813F8120813F8120813F811101208
+6193:204020402FFE204037FCAC44A7FCA444A7FC20442FFE204220242522250A28F8
+6194:2140212023FE22203620ABFCA220A220A3FC2220222023FE2200252424922892
+6195:202027A420A822923114AA08A5F4A802A3F82208220823F8220821102FFE2000
+6196:081408127F102AFE2A105D101C282A2849448882010008844892481287F00000
+6197:082008207F3E2A442AA45D2408281C102A284846010008844892481287F00000
+6198:102013FE102019FC540051FC510491FC108817FE100011FC1104110411FC1104
+6199:01007FFC01003FF800003FF820083FF80820FFFE20083FF801004884481287F2
+619A:100013DE125212521BDE540051FC512491FC112411FC102013FE102010201020
+619B:100013FE10501BFE565253FE500091FC110411FC110411FC102013FE10201020
+619C:2020272025FE2540357CAE90A57EA500A57C2544257C2644247C24442444244C
+619D:08407F40007E3E8823483E4800503E5004207F500888290411004884481287F2
+619E:221021102FD0201037BEACA4A7D4A014A7942094211421C82F08211425142222
+619F:200027FC20A020A037FCACA4A4A4A7FCA248215027FC20E0215022482C462040
+61A0:3FFE289025102FBE22222AD42A902F90222844284444888201004884481287F2
+61A1:1210121013DE152818A4542053FE502093FE1222122A127410A8112416221020
+61A2:1020102011FC10201BFE5508539C51089188163E100013FE109010901112120E
+61A3:103C13E0112410A81BFE54A85124520291FC1124112411FC1124112411FC1104
+61A4:102011FC102010881BFE548851FC510491FC110411FC110411FC108811041202
+61A5:08202AA80820145022887FFC400402003FF804080850302001004884481287F2
+61A6:108812AA12DC148819545622500053FE9242144413FC10441044108411141208
+61A7:102011FC108810501BFE540051FC512491FC112411FC102011FC102013FE1000
+61A8:7C200420FF3E22443EA422283E282390FE28424402820100288828A4482407E0
+61A9:1C10702010FCFE8410FC7C8444FC44847CFC4400010008844892481287F00000
+61AA:279E2492279E2492379EAC02A4F2A492A4F2249224F224922492253224022406
+61AB:200027BC24A427BC34A4AFBCA484A444A5F4242424A4244424A4250424142408
+61AC:100013F812081BF8560853F8504097FE100013F8120813F810401248144410C0
+61AD:2040204027FC20A03514AA08A7FCAA0AA3F8220823F820402248244429442080
+61AE:2100210023FC36A8AAA8A2A8A7FCA2A822A822A82FFE200022A8225424542000
+61AF:200027BC2108252837BCAB18A5AAA946A00023F82208220823F82208220823F8
+61B0:100013FC104810301BFE545250945350902013FE1252128A1376125212721206
+61B1:221421122FD22010307EAF90A490A490A790212825A825682928214A254A2286
+61B2:01007FFC41043FF801001FF00100FFFE01003FF824483FF801004884481287F2
+61B3:100013FC100413FC180457FC500053BC912417BC100813FE1108108810A81010
+61B4:200027FC24A424A437BCA8A0A7BCA4A4A4A427BC24A424A427BC24A220A2207E
+61B5:00407C2045FC44887C5043FE7C20A5FC24203C20010008844892481287F00000
+61B6:1080104013FC1908549057FE500093FC120413FC120413FC10401524150A18FA
+61B7:2110211027BC3110ABB8A554A912A00027FC2044224022782240254028FE3000
+61B8:2040204020A03110AA08A5F6A800A7BC24A424A427BC22102210252829443082
+61B9:109013FC12941BFC569453FC500093FC120012F8120013FE1520151415481986
+61BA:110011F8120817FE1A88572453FE520092FC120012FC120012FC148414FC1884
+61BB:102017FE100013FE1A0256FA528A53FE900011FC110411FC110411FC100017FE
+61BC:2220FFA0223E20447FA481287D2845107D280A44048202005104511290120FF0
+61BD:21102FFE21103200ABFCA4A4ABA4A164225424942108204020242522250A28F8
+61BE:2014201227FE241035D0AC14A5D4A558A5CA24162442282422A2228A24782000
+61BF:2108220827C8245037DEAC64A7D4A214A11427D4221423C822482454255428A2
+61C0:204020A023182DF63000AFFCA554A4E4A7FC200023F8220823F8220823F82208
+61C1:200023FC22943294ABFCA000A7FEA00023FC220423FC20A2211423082D442182
+61C2:211027FE211023F83040AFFCA040A3F8A24823F8224823F8204027FC20402FFE
+61C3:2220FFA022203EFC08247F2449247F2408247F440854FF8801004884481287F2
+61C4:228822882FE8228833BEA90AA7CAA54AA7CA210A27CA210A27D2211221EA2E44
+61C5:1040107C104013FE1A42567853C4523C920013FE124013A4125815B4145219B0
+61C6:23F82208220833F8A800A7BCA4A4A4A427BC20402FFE21602250244838462040
+61C7:0600F8FC4A8424FC3884CCFC36A2CA9412A86AC4048202005104511290120FF0
+61C8:2200239E248A290A37D2AD66A540A7D4A55E256427C42544255E2544244428C4
+61C9:010000803FFE224824FE2D9034FC249024FC249024FE24804244524A920A21F8
+61CA:2080210027FC24443554AC44A7FCA4E4A554240420402FFE20A0211022082C06
+61CB:27882088FABE210877D86B5CA52A294825082208010008844892481287F00000
+61CC:200027FC24A427FC3040ABF8A040A7FCA11020A023F820402FFE204020402040
+61CD:20402FFE200027FC3404ADF4A514A5F4A40427FC200823F020402FFE21502E4E
+61CE:2040204027FC3248AA48A554AFFEA00027FC240425F4251425F4240427FC2404
+61CF:10A0109011FE132019FC552051FC512091FE110013DE12521252127212021206
+61D0:1040102013FE100019FC5554515451FC902013FE10501094118812A814C41082
+61D1:01104FFE211027FC80A047FC54A414A4E56426542484240C01004884481287F2
+61D2:221022102F9C22243248AFBEAAA2AAAAAFAA222A272A2AAA3288221422222242
+61D3:103C13C010441224190857FE544252A4928A147A108010F8110812901060179E
+61D4:20402FFE200037FCAC04A5F4A514A5F4240427FC200023F820002FFE224824C4
+61D5:00003FFE288C2F8A28882FBE20082F8828882F94289429A2408042408A1411F2
+61D6:080C147022105C1088FE3E1008104A7C28440E44707C22005104511290120FF0
+61D7:21102110211037BCA910A110AFFEA2A822A826EC2AAA22AA22A825A824482898
+61D8:42A827FC22AA84E6400057FC1444E3F822482258214008844892481287F00000
+61D9:1140124C126412441B4C566452A453AC92A412A417FE10001110110812041404
+61DA:203E27C02244212833F8A840A7FCA000A3F8200823F8200823F82544252A28FA
+61DB:20402FFE204027FC3000ABF8A208AFFEA80227FC211023F8204027FC20402FFE
+61DC:1088108813FE10881BFE565253FE500093FE124210F811081290106010C01700
+61DD:2400257C260434A8AB90A07CA414A7942A5022502FDC2250255024B0289E2100
+61DE:108813FE108813FE1A0255FC500053FE904010A2135410B81354109213501020
+61DF:140855083608147E7F0814487F2808283E0808080F28781021004884481287F2
+61E0:2080204027FC211030A4AF58A554A552AB582000220823F8220823F822082408
+61E1:2040202027FE248837DEAC88A5DCA6AAA4882440249025202448248425FC2884
+61E2:201027D0251027DE3450AFE8A504A7C4A00023F822A822A822A822A82FFE2000
+61E3:011047FC211081F0404017FC1664E55426EC2444244C02005104511290120FF0
+61E4:204027FC204033FCA800A7FEA002A3F8204027FE200027FE200827FE24A82798
+61E5:204027FC204027FE3402ABFCA248A3F8A24823F8200027FC22442278254028FE
+61E6:200027FC20402FFE3842AB58A040A358A0002FFE204027FC24A424A424A4240C
+61E7:2080204027FC244432A8AA94A474A000A3F822A82FFE200027FC204021402080
+61E8:20002FFE28082BC83A4CABCAAA48ABDEA8082BC82A482BD42A542BD42A5432E2
+61E9:2208211027FC3040ABF8A080A7FCA14823FC260A2BF8220823FA2234228C2302
+61EA:23F8220823F8220833F8A910A7FCA110AFFE21102248255420E02150224820C0
+61EB:1042139C12101BDE56945294542093FC120413FC120413FC120413FC11081204
+61EC:00803FFE22202FF822203FFC20802FF828882FF828882FF842205494924A23FA
+61ED:2040202027FE248835FCAC88A7FEA420A5FC252425FC252425FC240024882904
+61EE:27FC208023F83208ABF8A208AFFEA8822548251428F4210023F8250820F02F0E
+61EF:0A20FFA0493E7F4449A451240828FF2820103E284244868201004884481287F2
+61F0:220225E224A226AA352AAE6AA10AA28AA44A2BAA210A27CA2122254221EA2E04
+61F1:110817FE110810001BFC5694529453FC902813FE1220132412A81292142A18C6
+61F2:22204AA08ABE1FC420A46F24A0282FA822102FA822442F8201004884481287F2
+61F3:108813DE108819DC548853DE508893FC100411FC100413FC104012A4128A147A
+61F4:2114211227D23110A910A7FEA290A6D2229226D2229426D4228A22CA2F162022
+61F5:110817FE110813FC1A9457FC500057FE940211F8110811F8110811F8110811F8
+61F6:2108210827CE21123124AFDEA552A55EA7D2211E2392255E2940211421122122
+61F7:208020402FFE200037FCACA4A7FCA248A1502208244420A8211023082D462180
+61F8:3E0E22F03E2022443EF822103E2422FE7F1008542A92595001204884481287F2
+61F9:204027FC200023B832A8ABB8A110A7FCA11027FC21102FFE212823102D482186
+61FA:2448244C2AAA3008AFFEA288AEE8A28A2EEA228C2EEC228822EA2F1A24262042
+61FB:109413981092118E1A8055FC512451FC912411FC108811FC108813FE10881104
+61FC:27BC24A427BC24A437BCACA4A7BCA120A3FE222027FC2A2023FC222023FE2200
+61FD:21102FFE211027BC34A4AFBCA140A120A3FE222027FC2A2023FC222023FE2200
+61FE:13FC110811F8190855F8510E57F8900817FE1294139C1294139C12D617BC1084
+61FF:1020FF2010BE7C440050FE9083907CA800A47CC244207C1045542F42F14A4238
+6200:210447C88812F3BC20084B92F83E0380AAAAABAA010008844892481287F00000
+6201:2850FE4828FE399012907CFE54907C9010FE7C901090FEFE28804504249243F0
+6202:202027FE248827DE3488ADDCA6AAA488A45027DE245025DC24502BDE28503050
+6203:2248215027FC240431F0A910A7FCA554A4E427FC204027FC20402FFE22A42452
+6204:13DE125213DE12521BDE54A051FE532095FC112011FE100011FC10881070178E
+6205:1000FEF82820FEFC00007CF844887CF844887CF81088FEF81050020851249FE4
+6206:1040FEF82948FE3001CE7CF844207DFC44887CA810A8FE5011884884481287F2
+6207:1040FEF82948FE3001CE7CF844207DFC44887CF81088FEF81050028851249FE4
+6208:022002100210020002FEFF0002080208021001200140008003420C22701A0006
+6209:00900088008800807FFE408040804088408840904060484450A46114420C0404
+620A:0090008800803FFE208020802084204420482048203020222052408A43068C02
+620B:02400220022002FC7F0002000200023EFFC002100120014001840E447034000C
+620C:0050004800403FFE20402040204420443E442028202820122032404A40868102
+620D:0050004800403FFE204020402044304428442428242820122032404A40868102
+620E:004800440040FFFE00400840084408447F440828082810121032204A40860302
+620F:0020002800247E240220023E25E0142408240828142812102232404A00860102
+6210:0050004800403FFE2040204020443E4422442228222822122A32444A40868102
+6211:04400E50784808480840FFFE084008440A440C48183068220852088A2B061002
+6212:004800440040FFFE00401240124412447F441228122812122232224A40860302
+6213:004800440040FFFE0040004000443E4422442228222822123E32224A00860302
+6214:0240022002FC7F10016003841C64E01C0240022002FC7F10016003841C64E01C
+6215:042024282424242424203C3E05E00424FC242428242824102432444A84860502
+6216:004800440040FFFE004000403E442244224422283E2800120732784A20860302
+6217:0828082414241220212E40F0BE202224222422282A2824102112212A1F460082
+6218:1020102810241E241020103E11E010247E2442284228421042327E4A42860102
+6219:0028FF2481248120BD2E81F08120BD24A524A528A528BD108112812A85468282
+621A:0028002400203FFE222023A0222422243FE4202822282A903252422A4A468482
+621B:7FFC02001FF010101FF010101FF010101FF0024003F87E20014000840764381C
+621C:005000480040FFFE00403E4022443E4400447F2808283E1208320F4A78862302
+621D:00287E24422442207E2E42F042207E24422442287E2800102412222A41468182
+621E:7FFC02001FF010101FF010101FF010107FFE424283FC7E20014000840764381C
+621F:08200828FFA408247F20413E7FE041247F2449280828FF900832084A08860902
+6220:10400848FF44004442402440FFFE00407E44424442287E2A4212422A7E464282
+6221:22202228FF2422243E20223E3FE022242224FF28402854106232404A7E860102
+6222:3F28212421243F200020FFFE21203F2421243F28212827D0F912412A01460182
+6223:0A28742415245220222E21F04120BE24082408287F2808101412122A22464082
+6224:00107E14221224103F16557849125512A21200147F145508551A57AAFC460082
+6225:00207E2842247E2442207E3E09E048247F2488287E2808100F32F04A40860102
+6226:90A8492400247F20492E49F07F20492449247F2808280810FF92082A08460882
+6227:08280C241224292044AEBFF021203F2421243F2820283F105112512A9F461182
+6228:0028FF2402247A204A2E7AF00020FF2402247A284A284A107A12022A0A460482
+6229:0028FF2422245520F72E00F0FF2000247E24422842287E104212422A7E464282
+622A:082008287F240820FFFE142022247FA4A4243F2824283F1024123FAA20462082
+622B:10141012FE1011FE20103C1025D26552BD52255425D43C0824CA271A24262C42
+622C:00107F941212529033161278FFD200123F12211421143F08211A212A3F462182
+622D:10100814FF92809000167F7808127F1249127F1449147F08001A222A41468082
+622E:0010771411125510331655780C123312C492181462140C88711A062A1846E082
+622F:10281E2410247F20512E5CF072204E2440244A286AA85B104A128F2A78460082
+6230:0010F79494929490F79600787F1249127F1249147F140808FF9A082A08460882
+6231:08100F1408127F9048964E787912471240124A146A94AA88BB9A0A2A7F462082
+6232:08280F2408247F20492E4CF07920472440245F2840285F1051125F2A8A463F82
+6233:0020EE282224AA246620AA3E01E024247F24C8287E2848107E32484A7F864102
+6234:08207F280824FFFE00207F2049247F2449247F2822287F102212FFAA22464182
+6235:7728552477245520772E55F0772022247FA4A4283F2824103F12242A3FC62082
+6236:001000F81F0010001FF81008100810081FF81008100010002000200040008000
+6237:0200010001001FF810081008100810081FF81008100010001000200020004000
+6238:00001FF8000000001FF81008100810081FF81008100010002000200040008000
+6239:020001003FFC200420043FFC200020002FF0202020C0210042004404840403FC
+623A:08000400047C3F442144214421443F44217C204020402040204240424042803E
+623B:020001003FFC200420043FFC2080208020802FFC214021404220441088081006
+623C:0000FC7E0440044004407C7C4444444444447C7C044408400840104020404040
+623D:020001003FFC200420043FFC20002220212024202220207E5FA0402080200020
+623E:020001003FFC200420043FFC208020A020902FFC214021404220441088081006
+623F:020001003FFC200420043FFC210020803FFC2200220023F84408440888281010
+6240:0208071C38E0208020803E8022FE228822883E88208820884108410882080408
+6241:020001003FFC200420043FFC200020002FFC292429242FFC492449248924080C
+6242:020001003FFC200420043FFC2080208020FC208020802FF8480848088FF80808
+6243:020001003FFC200420043FFC200020002FFC280429E42924492449E488140808
+6244:020001003FFC200420043FFC210022002FFC280429E42924492449E488140808
+6245:010000803FFC20043FFC210023F02C2022C023403CFC23084C90406081801E00
+6246:020001003FFC200420043FFC210020802FFC2140224426284A10528883060200
+6247:020001003FFC200420043FFC200020003F7C2104292425144924514485140208
+6248:010000803FFC20043FFC200027F0241027F020002FF828884FF84802880207FE
+6249:010000803FFC20043FFC212021203F3E212021202F3C212041205F3E81200120
+624A:010000803FFC20043FFC24882490296022182C84348A2488495042208C183006
+624B:001000F83F00010001003FF8010001000100FFFE010001000100010005000200
+624C:1000100010001000F8001000140018003000D000100010001000100050002000
+624D:0080008000800080FFFE01800280028004800480088010802080408002800100
+624E:1080108010801080FE801080108012801C803080D080108410841084507C2000
+624F:1080108010801080FDF010901090149018903090D090109211121112520E2400
+6250:1040104010401040FDFC10441044144418443084D08410841104110452282410
+6251:1080108010801080FE8010A0109012881C843084D08010801080108050802080
+6252:1000102011201120FD2011201120152019203110D21012101208140854042802
+6253:1000100013FE1020FC2010201020142018203020D02010201020102050A02040
+6254:1000100013F81088FC90109010A014BC18843084D10411041104120452282410
+6255:1040104010401040FC4010801080148019003110D108120817FC120450042000
+6256:1200110010801080FC401040104014A018A030A0D11011101208120854042802
+6257:1020102010201020FC20102011FC142018203020D02010201020102053FE2000
+6258:1008103C13C01040FC4010401040147E1BC03040D040104210421042503E2000
+6259:1010101010101010FDFE10101010151019103090D09010501020105051882606
+625A:10401040108010FCFD0412041004150418843044D04410041004100450282010
+625B:1000100011FC1020FE201020102012201C203020D02010201020102053FE2000
+625C:100011FC10201020FC20102014201BFE3020D020102010201020102050A02040
+625D:100011FC10001000FC0013FE10401440188030FCD00410041004100450282010
+625E:100011FC10201020FC20102014201BFE3020D020102010201020102050202020
+625F:100013F010901090FC901090109013F018903090D0901092108A108A50862082
+6260:100017F812081288FE4811501110151018A030A0D040104010A0111052082C06
+6261:1020102010201120FD2C1134116417A419243134D12811221122110250FE2000
+6262:10401040108010FEFD00120010FC140818103020D04010801102110250FE2000
+6263:1000100011FC1104FD0411041104150419043104D1041104110411FC51042000
+6264:1000100013FC1090FC9010901090149018903090D090109211121112520E2400
+6265:102010201020103CFDE0102010201420183E33E0D020102210221022501E2000
+6266:1008103C11E01020FC201020102017FE18203020D02010201020102050202020
+6267:1040104010401040FDF8104810481448194830C8D04810A810AA110A52062402
+6268:1000100011FC1044FC4411441144154419443244D04410841084110452282410
+6269:10201010101011FEFD0011001100150019003100D10011001100120052002400
+626A:1100108010BC1204FA04120416041A043204D204120412041204120452142208
+626B:1000100013FC1004FC041004100415FC18043004D0041004100413FC50042000
+626C:100011F810101020FC40108011FE149218923092D11211221222144250942108
+626D:100011FC10441044FC441044104415FC18843084D08410841084108457FE2000
+626E:1010109010901088FD081104120415FA18883088D08810881108110852282410
+626F:1020102010201120FD201120113C152019203120D12011201120112057FE2000
+6270:1040105010481048FC4011FE1050145018503050D090109010921112510E2200
+6271:100013FC10841088FC881090109C148419443144D12811281210122854442182
+6272:1040104010A010A0FD10128814461040180033F8D00810101010102050202040
+6273:1008101C11E01100FD0011FC1144154419443128D12811101110122852442482
+6274:1020102010501050FC8811041202108818883088D08810881088110851082208
+6275:1020102010201050FC50108815041A023060D010100010C01020101050082000
+6276:1020102010201020FDFC1020102014201BFE3020D05010501088108851042202
+6277:1008103C11E01020FC20102013FE142018203050D05010501088108851042202
+6278:1010111011101110FD1011FE11001500190031F8D10811081108120852082408
+6279:1010111011101112FD12111411D8151019103110D110111211521192510E2000
+627A:1008103C13E01220FE201220122017FE1A203210D2101212120A128A53062202
+627B:10801080108010FCFD04110812401440184030A0D0A010901110110852042402
+627C:200023FE22002200FAF8228822882A883288E2A82290228224822482A87E5000
+627D:10201020102013FEFC20112411241524192431FCD024102010221022501E2000
+627E:1090108810881080FCBC13C01080148818883090D060104410A41114520C2004
+627F:1FE000400080010479280FF00920111017D0210821084FE48102010005000200
+6280:10201020102013FEFC201020102015FC18843088D04810501020105051882606
+6281:1040104010801088FD0413FE1002149018903090D090109011121112520E2400
+6282:1000100013FE1020FC2010201020142019FC3020D02010201020102057FE2000
+6283:1040102010201000FDFE10401040146018503048D04410441040104050402040
+6284:10201020102010A8FCA410A2112215201A243024D02810081010102050C02300
+6285:10801080108010FEFD0212421042148218A23112D3FA110A1002100250142008
+6286:10401020102013FEFC8810881088148818883050D05010201050108851042602
+6287:1000100011FE1102FD021102110215FA19023102D1021102110211FE51022000
+6288:100011FC11041104FD0411FC11041504190431FCD10411041204120454142808
+6289:10401040104013F8F84810481448184837FED04010A010A01110111052082406
+628A:100011FC11241124FD241124112415FC19043100D10011001102110250FE2000
+628B:1000104010201010FC901080108012841A823282D28214881088108850782000
+628C:10201020102011FEFD2212241020142018503050D0501050109010925112220E
+628D:1008106813881088FC88108814881BFE3088D088108810881108110852082408
+628E:1000100011FC1000FC00100013FE142018203040D0401088110413FE51022000
+628F:1000100011FC1000FC00100013FE109018903090D090109011121112520E2400
+6290:1020102010201020FDFE1122112215221952314AD18A110211021102510A2104
+6291:10001080133C1224FE241224122416241A243224D2B413281220102050202020
+6292:100011F810081050FC20101013FE142218243020D02010201020102050A02040
+6293:1008101C11F01150FD5011501150155019503148D14811481144124452422400
+6294:1000100013FE1020FC201040104014D019483244D44410401040104050402040
+6295:100010F810881088FC881106120015FC18843084D04810501020105050882306
+6296:1010111010901090FC101110109014901810301ED3F010101010101050102010
+6297:10801040104013FCFC00100011F0151019103110D110111211121212520E2400
+6298:1008101C11E01100FD00110011FE151019103110D11011101110121052102410
+6299:1008103C11E01020FC2011FC10201420182033FED02010201020102050A02040
+629A:100013FC10401040FC40104017FE104018A030A0D0A0112011221222541E2800
+629B:121012101210127CFA14179412941A9432A4D2A412D4128A14821482587E3000
+629C:1040104010401040FBFE1080148018FC3144D144114812501220145058882306
+629D:20802080213E2102FA42224227C228823082E1022142222227E22222A00A4004
+629E:100011FC11041104FD04110411FC152419203120D11011101208120854042802
+629F:10201020102011FCFC20104011FE1440188031FCD00410881050102050102010
+62A0:100011FE11001104FD4411281128151019103128D12811441184110051FE2000
+62A1:1040104010A010A0FD1012081406111019203140D18011001104110450FC2000
+62A2:1040104010A010A0FD101208140611F019103110D15011201104110450FC2000
+62A3:10401040108010FCFD0412041084144418443014D02410441184100450282010
+62A4:10401020102011FEFD021102110215FE19023100D10011001200120054002800
+62A5:100011FC11041104FD141108110015FC19443144D12811281110112851442182
+62A6:100013FE10201020FC2013FE122216221A52324AD28A130212021202520A2204
+62A7:1000100011FC1104FD0411041104150419FC3104D00010901088110452022402
+62A8:100011FC10201020FD2410A410A814201BFE3020D02010201020102050202020
+62A9:10201020102011FCFD24112411FC152419243124D7FE11041104110451142108
+62AA:10401040104013FEFC8010A0152019FC3324D524112411241134112850202020
+62AB:10101010101011FEFD121114111015FC19443144D12811281110122852442482
+62AC:1020102010401088FD0413FE1002140019FC3104D10411041104110451FC2104
+62AD:10401020102013FEFA021404100018F03090D0901090109011121112520E2400
+62AE:1040104010A01110FA081426104018803310D020104010881310102050C02700
+62AF:100011F811081108FD0811F811081508190831F8D10811081108110857FE2000
+62B0:10201020102011FCFD24112411241524192433FED02010501050108851042202
+62B1:1080108011FC1104FA0415F4111419143114D1F4110411281112110250FE2000
+62B2:1000100017FE1008FC0813C8124816481A483248D3C812481008100850282010
+62B3:100011FC11041104FD0411FC1100154019443148D170114011421242523E2400
+62B4:2048224822482248FA4827FE22482A483248E2482278220022002200A3FE4000
+62B5:1008103C13E01220FE201220122013FE1A203210D2101212120A128A53262212
+62B6:1020102011201120FDFC1120122010201BFE3020D05010501088108851042202
+62B7:100013FC10201020FC40104014D019483244D444104010401040100057FE2000
+62B8:1008103C13C01000FC40102013FC140818103020D040108011001280547E2000
+62B9:10201020102013FEFC201020102015FC187030A8D0A811241124122250202020
+62BA:10201020102011FCFC201020102013FE187030A8D0A811241124122250202020
+62BB:10201020102013FEFA22122216221BFE3222D222122213FE1222102050202020
+62BC:100011FC11241124FD2411FC11241524192431FCD12410201020102050202020
+62BD:1020102010201020FDFC112411241524192431FCD12411241124112451FC2104
+62BE:1020102010201020FDFE1020102014201BFE3020D04010401088110453FE2102
+62BF:100013FC12041204FE0413FC122016201BFE3220D22012101212128A53062202
+62C0:100011FC11041104FD04110411FC145018503050D050109210921112520E2400
+62C1:220022002200221EF7D22252225222523252E252225222522452245EA9525080
+62C2:10901090109013FCFC94109413FC16901A9033FED0921092111A111452102410
+62C3:10801080108010FEFD4011401240107C18403040D040107E1040104050402040
+62C4:10401020100013FEFC2010201020142019FC3020D02010201020102053FE2000
+62C5:1000100011FC1104FD04110411FC150419043104D1FC11041000100053FE2000
+62C6:1008101C11E01100FD00110011FE151019103130D11811141112121052102410
+62C7:100011F811081148FD281108110817FE1A083288D248120813FE100850502020
+62C8:104010401040107EFC4010401440184033FCD204120412041204120453FC2204
+62C9:1040102010201000FBFE1000140419043104D088108810881090101057FE2000
+62CA:1088108810881108FD7E13081508114819283128D10811081108110851282110
+62CB:221022102210227CFA1427D422942A9432A4E2A422D4228A24822482A87E5000
+62CC:10201020112410A4FCA8102011FC142018203020D3FE10201020102050202020
+62CD:10201020104011FCFD0411041104150419FC3104D10411041104110451FC2104
+62CE:1040104010A010A0FD101248142610201BF83008D010111010A0104050202020
+62CF:10001000FEFC2244642818102428C2C600201FC001003FF801007FFC01000300
+62D0:100011FC11041104FD0411FC104014401BFC3044D04410841084110452282410
+62D1:1088108810881088FDFE108810881488188830F8D08810881088108850F82088
+62D2:100011FE11001100FD0011FC1104150419043104D1FC11001100110051FE2000
+62D3:1000100013FE1020FC201040104014FC19843284D48410841084108450FC2084
+62D4:1050104810481040FBFE1080148018FC3144D144112811281210122854442182
+62D5:10201010101011FEFD02120410801488189030A0D0C0108210821082507E2000
+62D6:1080108010FE1100FE201120112C15741BA43124D13411281122110250FE2000
+62D7:2020212021202220FAFC24A4272429243224E22424A427A420C42044A0944108
+62D8:10801080110011FCFA04140411E419243124D12411E411241004100450282010
+62D9:1020102011241124FD24112415FC18243020D020122212221222122253FE2002
+62DA:1020102010401088FD0413FE10021488188833FED08810881108110852082408
+62DB:100013FC10841084FC841104111412081C0031FCD10411041104110451FC2104
+62DC:04001EFCF020102010FCFE20102010FC1020FE2011FE10202020202040208020
+62DD:100013FE10201020FDFC1020102015FC18203020D3FE10201020102050202020
+62DE:1008101C11E01100FD001100110015FE19103110D11011101110111057FE2000
+62DF:1008108810481228FA28120812081A083208D208121012981324122450422082
+62E0:220022382228FBA822A822A834A826AAEAAA22AA2126214022802260A41E4800
+62E1:10201010101011FEFD0011101110151019103120D1281124124412FE54422800
+62E2:1090108810881080FBFE10A014A018A430A4D1281128113212221262549E2800
+62E3:1040104017FC1080FC8013E0112012201BFC3020D12811241222142250A02040
+62E4:104010401040107CFC40104014401BFE3040D040105010481044104050402040
+62E5:200027FC24442444FC4427FC24442C443444E7FC2444244424442844A8545008
+62E6:1000110810881090FC0013FE10001400180031FCD00010001000100053FE2000
+62E7:10401020102013FEFA0214041000180033FED020102010201020102050A02040
+62E8:1040104812441240FBFE1080148018FC3144D144114812501220145058882306
+62E9:200027F822082110F0A0204021B0264E3040E3F82040204027FC2040A0404040
+62EA:100017FE10901090FC9013FC129416941A943294D29C13041204120453FC2204
+62EB:100011F811081108FDF81108110815F819443148D13011201110114851862100
+62EC:1008103C11E01020FC2013FE10201420182031FCD10411041104110451FC2104
+62ED:1028102410241020FBFE102014201BA03120D1101110111011CA170A52062002
+62EE:10201020102013FEFC20102011FC1400180031FCD10411041104110451FC2104
+62EF:100011FC10081010FC2213B210B414A819283124D22214A01040100057FE2000
+62F0:10801088109C1170FD1013101510111019FE3110D110111011101110517C2100
+62F1:1088108810881088FDFE108810881488188833FED00010881084110452022402
+62F2:044004407FFC0440FFFE08203018C0E61F0001003FF801007FFC010005000200
+62F3:0100111009203FF802007FFC082010F03F08C1061FE001003FF8010005000200
+62F4:1020102010501088FD04120211FC142018203020D1FC10201020102053FE2000
+62F5:10401040104013FEFC801080117815081B103510D1FE11101110111051502120
+62F6:1124112412481124FD241000108014FC19043184D24814281010102050C02300
+62F7:1040104411F41048FC5013FE1040148019FE3240D48010FC1004100450282010
+62F8:1040104010FC1108FA90106014481990363ED042108413481030102050C02700
+62F9:1040104011FC1044FC84108415281A103108D3DE114A114A114A1252535A24A4
+62FA:1020102013FE1020FC2011FC112415241924312CD07010A81124162250202020
+62FB:10401040104013FEFC8010901090151219523154D29012281428104450842102
+62FC:1104108410881000FDFE108810881488188833FED08810881108110852082408
+62FD:1020102011FC1124FD2411FC1124152419FC3020D0241018103210CA53062002
+62FE:1020102010501088FD04120211FC1400180031FCD10411041104110451FC2104
+62FF:010006C01830EFEE00001FF010101FF000201FC001003FF801007FFC01000300
+6300:1004101E11E01100FD0611781150155019523154D14811481144125452622440
+6301:10201020102011FCFC20102013FE1008180833FED00810881048100850282010
+6302:1020102011FC1020FC20102013FE100018203020D1FC10201020102053FE2000
+6303:100011FE10201040FC88110411FE142218203020D1FE10201020102053FE2000
+6304:1040104412441148FD50104017FE109018903090D090109211121112520E2400
+6305:100013F810881090FCBC110415141A483040D7FE104010E01150124854462040
+6306:100011F011101110FD101110124E14401BFC3040D0E011501248144650402040
+6307:11001104113811C0FD02110210FE140019FC3104D10411FC1104110451FC2104
+6308:08007F7C08243E2408247F44085408F83F0001003FF801007FFC010005000200
+6309:10401020102013FEFA02144410401BFE3088D088110810D01020105050882304
+630A:10401040107C1040FC4013FE100010001BFE3040D05010481044104050402040
+630B:100013FE12201220FE2013FC120416041A043204D3FC12201220122053FE2000
+630C:1080108011F81208FD1010A0144018A03318DC0613F812081208120853F82208
+630D:10401020102013FEFC0010881104120218883088D05010501020105050882306
+630E:2040204027FC20A0F11022082DF6200037FCE080210023F820082008A0504020
+630F:100011FE11021102FD7A11021102157A194A314AD14A117A11021102510A2104
+6310:10001000FE7C224442443444087C3400C2201FC001003FF801007FFC01000300
+6311:1090109010901292FD941098109015981A943492D0901090111211125212240E
+6312:200220022FC22212FA1223D222522C523652E5522892209221022202A40A4804
+6313:10401020102013FEFA02140410381BC03040D040107E17C0104010425042203E
+6314:10401020102013FEFC40104010A014A219A43298D4901088108410A250C02080
+6315:100013FE11081108FD0811F81108150819F83108D108111E17E8100850082008
+6316:1040102013FE1202FC881104120214F818103020D04010801102110250FE2000
+6317:1020102013FE1020FDFC102411FC152019FE3022D02A10541050108851042202
+6318:1020102011241122FA2A101014601B803040D04013FC10441084108451142208
+6319:2208110811100020FFFE0820101020E8DF0601003FF801007FFC010005000200
+631A:1080FBF010901990F0941154520C24E41F0001003FF801007FFC010005000200
+631B:02000100FFFE044014502448444400F03F0001003FF801007FFC010005000200
+631C:100013FC10901090FC901092149212941A943298D09010901090109057FE2000
+631D:2408220822082008F8FE2E0822482A283228E2082208222822102500A8FE4000
+631E:1010121011101110FCFE10101310152819243144D142118211001280547E2000
+631F:10201020102011FCFC20112410A414A8182033FED05010501088108851042202
+6320:1080108010BC13C0FC50102410D4130C180033FED090109011121112520E2400
+6321:1040124411441144FD48104017FC100418043004D3FC10041004100457FC2004
+6322:2010207823C02040F84027FE20A029103208E5162110211021102210A2104410
+6323:1080108011F01210F82013FC1044184437FED044104413FC1044104051402080
+6324:1080104017FE1208FD1010A0144019B0360ED110111011101110121052102410
+6325:100013FE12021444FC4013FC108014A0192031FCD020102017FE102050202020
+6326:100013FC10041004FDFC1004100417FC18083008D7FE11081088108850282010
+6327:100013DE10421042FA52114A154A184230C6D14A1252104210421042514A2084
+6328:2040208021102208F7FC2104210023F83440E0402FFE204020A02110A2084C06
+6329:1010109010881108FA0415FA110819083108D1F810901090109011125212240E
+632A:100017DE12521252FA5417D412581A543252DFD21252125A1254145055502890
+632B:2040204022482248F248255428E220403040E7FC2040204020402040AFFE4000
+632C:1020102013FE1020FC2013FE1202140419F83010D02013FE1020102050A02040
+632D:100013FE10201020FDFC1124112415FC19243124D1FC112010A0104050B0230E
+632E:11081088109013FCFC24102413FC16201A2033FED06210A2112A122454202020
+632F:100013FC12001200FEF81200120017FC1AA032A4D2A812901290148854A428C2
+6330:100011FC11041104FD0411FC100014001BFE3020D02011FC1020102053FE2000
+6331:1010121011101110FC5412521252109018103114D604120812081210522020C0
+6332:204012484444201408607380200000F03F0001003FF801007FFC010005000200
+6333:100011FE10001092FD24124811241492180031FED02010201020102053FE2000
+6334:1100110011FC1200FDF81108114815281BFE3108D248122813FC100850502020
+6335:100013FE10201020FDFC102014201BFE3088D08813FE10881088110851082208
+6336:100011FC11041104FDFC1100110015FE1902317AD14A114A127A120254142008
+6337:2100211E211227D2F914211427D829143112E7D22112211A21142210A2104410
+6338:100011FC11041104FDFC1104150419FC3104D10411FC1050105010925112220E
+6339:100011F811081108FDF8100013FC12441A443244D3FC12001202120251FE2000
+633A:2000200C27702110F9102210227C2F103110E5102510227C22002500A8FE5000
+633B:1004100E13B81088FC881128152E1BA830A8D2A812A8113E11001280547E2800
+633C:1008103C13C01044FA2411281500184033FED088110813901060105051882604
+633D:1080108011F81208FC1013FC124416441A4433FCD0A010A011221122521E2400
+633E:10201020102013FEFC20102011241524192432AAD02010501050108851042202
+633F:101C11E010201020FDFE102011FC1524192431FCD124112411FC102050202020
+6340:110011F813081490FC601198164610401BF83040D3F8104017FC104050402040
+6341:10201120112011FCFD201220102013FE18003000D1FC11041104110451FC2104
+6342:100013FE10401040FDFC1084108417FE18003000D1FC11041104110451FC2104
+6343:100011FC10441044FBFE1044144419FC3080D08011FC12841484108450FC2084
+6344:1028102410241020FDFE1020112014B218B43068D0A811241222102050A02040
+6345:200027F8201021A0F84027FC24442C4437FCE444244427FC24442444A4544408
+6346:200027FC24442444FC4427FC24442CC434E4E5542644244424442404A7FC4404
+6347:10201020102011FCFC20102013FE145018503154D15211521252109050902130
+6348:1020102010501088FD0412FA102014201BFE3020D12811241222142250A02040
+6349:100011FC11041104FD0411FC102014201920313CD120112012A01260543E2800
+634A:1008103C13C01004FA44112810001BF83010D02017FE10201020102050A02040
+634B:1008103C13C01044FA2411281500181033FED010111010901090101050502020
+634C:200427C424442454FC5427D422142A1437D4E2542254225424442444A9545088
+634D:100011FC110411FCFD0411FC1000140019FC3020D02013FE1020102050202020
+634E:1020112410A410A8FC2011FC1104150419FC3104D10411FC1104110451142108
+634F:100011FC11041104FDFC1104110415FC18203020D1FC10201020102053FE2000
+6350:100011F811081108FDF8100013FC16041A0433FCD204120413FC120452142208
+6351:100010FC10841284FEFC1284128416FC1A0033E0D02013FE1020105050882306
+6352:1020102013FE1020FC2011FC1124152419FC3020D07010A81124122250202020
+6353:200027DE20922492F494249427D820943192E1922292229A24942890A2904110
+6354:1080108011FC1104FA0815FE1122192231FED122112211FE11221222522A2404
+6355:1048104417FE1040FC4013FC124416441BFC3244D24413FC1244124452542208
+6356:1040102013FE1202FC0411F8100014001BFE3090D090109011121112520E2400
+6357:101010101090109EFC90109013FE140018103092D09211141208101050602380
+6358:1040104010881104FBFE1002148819443242D0F8118812501020105051882606
+6359:1020102013FE1020FDFC1124112415FC19243124D1FC102013FE102050202020
+635A:100011FC11241124FDFC1124112415FC18203020D1FC10201020102053FE2000
+635B:100011F811081108FD08110811F81400180033FCD20412041204120453FC2204
+635C:1020102011FC1124FD2411FC1124152419FC3020D3FC10881050102050D82306
+635D:1104108410881010FDFC11041104150419FC3050D050109010921112520E2400
+635E:1088108813FE1088FC0013FE12021444184033FCD04410841084110452282410
+635F:100010F810881088FCF8100011FC150419243124D12411241050104850842304
+6360:1008101C11E01100FD0011FE1110151019103110D7FE10001090110852042402
+6361:1040104010A010A0FD10120815F6100018883048D24811501110102057FE2000
+6362:1080108010F81108FA1015FC112419243124D12417FE10501050108851042602
+6363:2040208023F82208FA88224822182A0033FEE0822492249227F22002A0144008
+6364:200023FC22042204FBFC220022182AE03238E2E0223C23E022222422A41E4800
+6365:1040102013FE1202FD04110011DE12521A523352D49A1094111011125212240E
+6366:1020102010501088FD04120210F81420182031FCD020112410A410A853FE2000
+6367:1020102013FE1020FDFC104013FE148819243222D0F8102013FE102050202020
+6368:1020102010501088FD0412FA102014201BFE3020D02011FC1104110451FC2104
+6369:1040102013FC1204FA0413FC16001A283224D3FE122012501250148855042A02
+636A:101C13E0122013FEFE201292130A120619FC3104D10411FC1104110451FC2104
+636B:200027BC24A424A4FFBC24A424A42FBC3404E4042404240424042404A4144408
+636C:2040202027FE2400FC88248825082D7E3708E5482528252829082908B1284110
+636D:1040108013FC1224FA2413FC16241A4433FCD090111017FE1010101050102010
+636E:11FE11021102FF0211FE1310151019FF1110311051FE928212821482548228FE
+636F:200420042FC42214FA14249427D429143114E7D42114211421C42E04A4144008
+6370:100011FC11241124FDFC1124112415FC182033FED07010A81124122250202020
+6371:100013FE12101210FEFE1210121017FE1A003210D21012FE1210141055FE2800
+6372:1020112410A813FEFC40108017FE11081A0435FAD908110811281112510220FE
+6373:1008101C11E01100FDFE11101510191037FED000102012221222122253FE2002
+6374:2090209021082148FA44249221082BFC3044E02020A42282228A228AA4784000
+6375:10901090109013FCFE941294129417FC1A943294D29417FE1000109051082204
+6376:1010107813C01040F84017FC12481A4837FED248124817FC1040104057FC2000
+6377:2040204027FE2040FBF8204827FE284833F8E0402240227C22402540A4FE4800
+6378:1020102011FC1024FC2413FE1024142419FC3222D17410A81124122250A02040
+6379:1020102013FE1050FCA8112412FA142018A83088D3FE10881088108851082208
+637A:1020102013FE1050FC88110412FA1000180033FED02011241122122250A02040
+637B:1020102010501088FD44122211F8140818503020D0A41282128A128A54782000
+637C:101C11E010201020FBFE10A815241A423040D3FE1088110810D0103050482184
+637D:1040102013FE1000FC88108815541A223000D02013FE10201020102050202020
+637E:1040102013FE1202FC0411F81108150819F83100D10011FC1104110451FC2104
+637F:1020102013FE1020FDFC102413FE142419FC3040D3FE108411C8103050CC2302
+6380:201020902710243EF4222444279025103510E5102528252825282944A9445082
+6381:100010FC108010F8FC8010F8108017FE19403124D12811101108114451822100
+6382:1040102013FE1200FE201220123E12201A2032FCD28412841284148454FC2884
+6383:100011FC100410FCFC0411FC100013FE1A223020D1FC11241124113451282020
+6384:2040204020A02110F2082DF6200027FC34A4E4A427FC24A424A424A4A4144408
+6385:1020102013FE1020FDFC102013FE140019FC3104D1FC110411FC110451142108
+6386:100013FE1202128AFE5213FE122216221AAA32AAD2AA12FA12021202520A2204
+6387:200027BC20842294F908229424A428403000E7BC20A422A421282290A4A84846
+6388:101C13E010841244FD48111017FE1402180033F8D108111010A0104051B0260E
+6389:10201020103E1020FDFC110415FC190431FCD124102013FE1020102050202020
+638A:1040102011FC1000FD081090100013FE18003000D1FC11041104110451FC2104
+638B:1040102013FE1200FE1C12F0129016901AFE3290D290129012AA12CA54A62812
+638C:111009203FFC20044FE808200FE000F03F0001003FF801007FFC010005000200
+638D:100011FC11041104FDFC1104110415FC18003112D1D41118111011525192210E
+638E:1040104013FC10A0FD10120817FE10081BC83248D248124813C8100850282010
+638F:1080108010FE1102FE8210F2114214421BFA3042D152115211F2100250142008
+6390:10401040107C1084FD081200102015CE19023102D1CE11021102110251FE2102
+6391:1088108813FE1088FC8810F81088148818F83088D08813FE1000108851042202
+6392:109010901090179EF890109010901B9C3090D0901090179E1090109050902090
+6393:2100210021DC2114F914211427D428143114E1142588254829482114A5144222
+6394:00007EFC48447E4442287E1048287EC600201FC001003FF801007FFC01000300
+6395:1020102011FC1020FC2013FE108815441A4230F8D18812501020105051882606
+6396:1080104017FE1120FD20123C124416641A943348D24812301220125052882306
+6397:100017FE10901090FC90139C120416041A04339CD09010901090109057FE2000
+6398:200027FC24042404F7FC2420252425243524E5FC2420252425242924A9FC5004
+6399:103C17C012441128FC0013F81448184837FED048104813F81048104051402080
+639A:100013FE10201020FBFE122212221B3232AAD2AA1376126612221222522A2204
+639B:1088108813E81088FC88108817EC140A188A3088D3E81088108810E853882108
+639C:10001040139C1204FE04139C120416041BFC3090D0901090109011125212240E
+639D:10141012101017FEF810101017D21A523252D25413D4100810EA171A52262042
+639E:1020112211221224FC5010881304142218203124D12412281050108851042602
+639F:1040102013FE1202FC04100013FE142018203120D13C112012A01260543E2800
+63A0:1040102013FE1000FC0011FC1104150419FC3020D12811241222142250A02040
+63A1:1008103C13C01044FA2411281500182033FED07010A810A81124122254202020
+63A2:200027FC240424A4F91022082040284037FCE04020E0215022482C46A0404040
+63A3:24043FA44424FFA404243F842494258800201FC001003FF801007FFC01000300
+63A4:100013DE12521252FA5213DE12521A523252D3DE1252125212521252555228A6
+63A5:1080104013FC1000FD08109017FE1040184037FED08811081090106051982604
+63A6:100011FC110411FCFD0411FC1080148019FE324AD44A10921122124250942108
+63A7:10401020102013FEFA02149411081A043000D1FC102010201020102057FE2000
+63A8:10A01090108011FEFD10131015FC1110191031FCD1101110111011FE51002100
+63A9:1040108017FE1110FE48144613F816481A4833F8D248124813F810425042203E
+63AA:10881088108813FEF888108817FE180031FCD104110411FC1104110451FC2104
+63AB:20002FC024BC24A4F4A427A424A424A837A8E4A8249025D02EA820A8A0C44082
+63AC:1100110011FC1204FC44115414E4184433FCD04410E411541244104450142008
+63AD:200023FC20402040FBFE20A021102A083446E0402048226422522452A1404080
+63AE:1040102013FC1204FE0413FC120012FC1A8432FCD28412FC1484148458942088
+63AF:10201120113C1120F92017FE10001BFC3204D3FC120413FC1204120452142208
+63B0:10003A86E2B824882448F85E202827882288FABE2288248824882A8851288010
+63B1:00F03F0001003FF801007FFC010005047A7810107CFC1010FEFE101050502020
+63B2:100011FC110411FCFD0411FC108015FE1A023112D1EA110A10FA100250142008
+63B3:2040207C204023FEFA42227823C42A3C3240E24023FC224424842484A9144208
+63B4:200023FE22022202FBFE222222222AFA3222E232222A23FE22022202A3FE4202
+63B5:1020102010501088FD0412FA100017DE1A523252D25213DA1254101050102010
+63B6:1040102013FE1220FEFC1224122417FE1A243224D2FC12201250145054882906
+63B7:2440225E22922012FFD421142118291437F2E1122112211A22942250A4504810
+63B8:11041088105011FCFD24112411FC1524192431FCD020102013FE102050202020
+63B9:100011FC10081010F82013FE142018A03040D1FC115411541154115457FE2000
+63BA:10801090110813FCFC4017FE111012481C863310D02010C41308103050C02700
+63BB:100011FC10841088FC50102014D81B263020D1FC1124112411FC102253FE2002
+63BC:11FC1124112413FEFD24112411FC140019FC3104D12411241124105850842302
+63BD:11081090100013FCFC901090109214921A943298D09010901090109057FE2000
+63BE:210021F8220823F0F81027FE208029443668E0B02128266820A42122A6A04040
+63BF:1088108813FE1088FCA8102013FE1440188030FCD18412841084108450FC2084
+63C0:1020102013FE1020FDFC112411AC1574192431FCD020107010A8112452222020
+63C1:10201020103E1020FC2011FC110415FC190431FCD10411FC1000108851042202
+63C2:21082088209027FEF890209023FC2A943294E30C220423FC22042204A3FC4204
+63C3:11081088109017FEF80013C412541A5433D4D254125413D412541244525422C8
+63C4:204020A021102208FDF6200023C42A543254E3D42254225423D42244A25442C8
+63C5:FDFE204840487DFEC44844887D0800E81F0001003FF801007FFC010005000200
+63C6:101013D410581252FD8C1088110412FA18203020D3FE10201050108851042202
+63C7:1020102013FE1020FC2013FE128A16521AFA3222D22212FA12221222522A2204
+63C8:1100110011FE1202FC8217F2100213F2180233F2D00213F2121213F250142008
+63C9:200021FC20482030FBFE2052209429103230E02023FE207020A82124A6224020
+63CA:100013FE100011FCFD04110411FC14001BFE3222D22213FE1222122253FE2202
+63CB:100011FC11241124FDFC1124112415FC180033FED12011221114114851842102
+63CC:100011FC11241124FDFC1124152419FC3000D040102412A2128A148850782000
+63CD:2040204027FC2040FBF8208027FC29103208E5F6204023F8204020A0A1104608
+63CE:1040102013FE1202FC0411FC140019FC3104D1FC110411FC1104100053FE2000
+63CF:1088108813FE1088FC88100011FC152419243124D1FC11241124112451FC2104
+63D0:100011FC11041104FDFC1104110415FC180033FED0201120113C112052A0247E
+63D1:1040119C11041104FDDC1104110415FC18003000D1FC10201020102053FE2000
+63D2:2008203C27C02040F8402FFE20402940365CE4442444275C24442444A7FC4404
+63D3:22102110211027BEFA28224823AA2AAE32BAE2EA22AE22A824AA24A2A9A2501E
+63D4:1080108010FC1154FAD410B4152C1A443094D108104010A412AA128A54782000
+63D5:1088108813FE1088FCF8108810F81488188833FED10011481184110051FE2000
+63D6:100011F811081108FDF8100017FE150819F83108D1F81108113E17C850082008
+63D7:101C13E012201220FBFE122012FC1A843284D2FC128412FC1484148458FC2084
+63D8:1020104011FC1104FDFC110411FC14001BFE3020D02011FC1020102053FE2000
+63D9:1040102013FE1202FE0213FE120016001BFE3352D55215FE1552155259522106
+63DA:100011F8110811F8FD0811F814001BFE3100D1FC125414941124124450A82110
+63DB:1080108011F81208FC1013FE12021A52328AD222102017FE1050108851042602
+63DC:1020105010881104FEFA100015FC19043104D1FC1088108813FE108851082208
+63DD:1088108811EC112AFA2815481088197E3600D1FC1104110411FC1104510421FC
+63DE:1040102013FE1000FD04108817FE100019FC3104D10411FC1104110451FC2104
+63DF:100013FE10221120FD3C112012FE140019FC3104D1FC110411FC110451142108
+63E0:100013FE120012FCFA8412FC16841AFC3220D3FE124812C812301248528423FE
+63E1:200023FC22042204FBFC220023FC2A403288E3FC2224222025FC2420A82053FE
+63E2:1040102013FE1202FC8010F815081A903060D198160611F81108110851F82108
+63E3:2040244424442444F7FC20002FFE20403080E7FC24A424A424A424A4A4A4440C
+63E4:100013DE12521252FA5213D212521A523252D3D2121A1294125012B053102010
+63E5:1080104013FC1000FD08109017FE1442184433FCD24412441254124850402040
+63E6:1082108217F21082FC8A13EA16AA1AAA33EAD08A11CA12AA14A21082508A2084
+63E7:04047FC404243FA424A43FA41504249444281FC001003FF801007FFC01000300
+63E8:1040102013FE1000FDFC110411FC14001BFE3202D1FC10201020102050A02040
+63E9:1110111211D41118FD521192112E144019FC3104D10411FC1104110451FC2104
+63EA:208821C827082108F92A212A27AC29483308E3882554251429142124A1244142
+63EB:0620382008A47EA819202C504A8809E41F0001003FF801007FFC010005000200
+63EC:1040102013FE1202FC88110412221028182433FED02010501050108851042202
+63ED:100013F8120813F8FE0813F8110013FC1C443244D2A4120413F4100450282010
+63EE:100013FE12221020FDFE102011FC152419FC3124D1FC102013FE102050202020
+63EF:220022FE22202220FB2022BC26442A54324CE28422A4221822082208A2FE4200
+63F0:1008103C11E01020FBFE102015FC192431FCD12411FC102011FC102053FE2000
+63F1:49042A247F2441247F2441247F244104432C1FC001003FF801007FFC01000300
+63F2:10481148114813FEFD4811481178150019FE3020D3FE107010A8112456222020
+63F3:1080109E13EA108AFDCA108A13EA149218A63020D3FE10201050108851042602
+63F4:203C27C022442128F80023FC2080288037FEE10021F8228822502420A8D84306
+63F5:20102010277C2114F9FE2214227C2F10317CE51025FE221022102500A8FE4000
+63F6:20002FDE24922492F4942794249824943792E492249225DA2E942090A0904090
+63F7:101C11E010201020FDFE10A0112C1524192431ACD124112411FC112450202020
+63F8:1020102013FE1070FCA81124122211FC190431FCD10411FC1104100057FE2000
+63F9:1050105213DC1050FCD2134E100015FC190431FCD10411FC1104110451142108
+63FA:1008103C13C01004FA44112815FC18203020D3FE102011241124112451FC2004
+63FB:2014201227FE2410FC1027F024922C9237D2E55425542488254A2A1AA8265042
+63FC:100013FE10401080FDFC1284108414FC18203022D3B410A81128122454A22040
+63FD:10901290129E12A8FAC4108015FC19043124D12411241154105010905112260E
+63FE:100011F811081108FDF81108110815F8180033FCD29412941294129457FE2000
+63FF:22102210221023BEF422244427902A103210EF902228222822A82344A2444082
+6400:210021F022102420FBFC224422442BFC30A0E122261E20C020302180A0604010
+6401:2200217C25042484F4F4251426A4244434A4E71C25F42514251425F4A5144408
+6402:1020112410A81020FBFE10A811241A023040D7FE108811081190106051982604
+6403:11081088109013FCFE041204120413FC18403020D0A41282128A128A54782000
+6404:2100213C21002100F9BC256425242D3C3524E1242124213C21242100A17E4100
+6405:24842244224827FEFC02280423F82A083248E248224822A820A02122A2224C1E
+6406:1088108813FE1088FDFC108813FE142019FC3124D1FC112413FE110451142108
+6407:204020A021182686F84023F0201028A03040E7FE2088215023202510A9484186
+6408:1040102013FE1202FC5010881124145018883104D2FA10881088108850F82088
+6409:1040104013FE12A2FC9011FE15101B1035FED110111011FE1110111051FE2100
+640A:1080108011FC1244FD5411F4108415281A9031FCD244155411F4108451282210
+640B:1004101E13F0121EFE1012FE129216981AF2328ED28012B812A814AA554A2A86
+640C:200023FC22042204FBFC224822482AFC3248E24823FE22A422A82490A4C84886
+640D:100011F811081108FDF8100013FC16041BFC3204D3FC120413FC109051082204
+640E:20062F7821102120FA44227823102A24367EEA122210225422522292AA504420
+640F:1028102413FE1020FDFC112411FC152419FC3124D00813FE1088104850482018
+6410:2080204027FC2080F90823F02060298437FEE00227FC244427FC2444A7FC4404
+6411:1108110817FE1108F80017FE110819F83108D1F81108113E17C8100850082008
+6412:1040102013FC1108FC9013FE12021444182033FCD08010F81088110851282210
+6413:11081088109013FCFC4011F8104017FE18803100D1FC12201420182053FE2000
+6414:200023F821482110F8A0204021B02E4E3040E3F82248224823F82044A7FC4004
+6415:1020102011FC1020FC2013FE108015041BFE3002D3FC12941294129457FE2000
+6416:1040108011FC1248FD3010C0130011FC1A203020D3FE10201124112451FC2004
+6417:1020104011FC1104FDFC110411FC150019FE3100D1FE1042124A13FA50142008
+6418:1040104411F81050FBFE104014F81982327ED40011FC110411FC110451FC2104
+6419:100013FE120012FCFE0013FE12A816901AC83286D20813FE1288144854082818
+641A:104011FC10441094FD0813DE114A154A1A9431FCD10411FC110411FC5104210C
+641B:111010A0100017FEF8A013F810A81FFE30A8D3F810A011B012A814A650A020A0
+641C:10A0112C11241124FDAC1124112415FC182031FCD08810501020105050882306
+641D:1020104011FC1104FDFC110411FC150419FC3028D02413FE1050108851042202
+641E:1040102013FE1000FDFC110411FC14001BFE3202D2FA128A12FA1202520A2204
+641F:21002100213E27C8F90827C825482FC8357EE7C821082FE821082108A1084108
+6420:2440225E22922012F7D2211E255225523552E7DE2152211222122222A42A4844
+6421:23F0211020E02318F80027BC24A42B1834A4E04027FC20E021502248AC464040
+6422:100013FC10901294FD98109017FE180031F8D108110811F81108110851F82108
+6423:20142012201027FEFC10241027F22C923492E5B426D42488254A293AAA265042
+6424:1104108410881000FBFE1000148819043202D1FC115411541154115457FE2000
+6425:10101220117C1144FC44107C13401540197C3144D144117C11441280547E2000
+6426:200027BC20842084F7BC2420242027BC3084E4A42294229424A42084A5284210
+6427:2080204027FE2402FC0227FE24002FDE3442E652254A24C62B5A2842B14A4084
+6428:100011FC110411FCFD0411FC100014001BDE3042D252114A12521042514A2084
+6429:2208220823BEF4882AA8213E22083448E84827FC20E0215022482C46A0404040
+642A:2040202027FE2420FDFC242427FE2C2435FCE42025FC250425042904A9FC5104
+642B:08783E48228E2A007EF822482A3046CC80201FC001003FF801007FFC01000300
+642C:2100223C27A424A4F6A425A424C22F8034BCE4A426A425A424942488A49449A2
+642D:2110211027FC2110F84020A021102A0835F6E000200023F822082208A3F84208
+642E:100013FE10501050FBFE125216521BFE3020D02013FE107010A8112456222020
+642F:103C13C010441224F928110014401B9C3204D204139C12041204120453FC2204
+6430:100011FC110411E4FD2413FE120211FC190431FCD10411FC1104110451142108
+6431:100013FC12041204FBFC124012201BFC3288D25013FE122015FC142058202020
+6432:2080204027FC2404F9102208203C2BD03290E29022902288228824A4A4D44892
+6433:1040102013FE1202FC2411FC102015FC182033FED02011FC1104110451FC2104
+6434:01007FFE44429FF404403FF80440FFFE082017D02108DFF601007FF801000300
+6435:200023F8224822A8FB18220823F828003000E7FC24A424A424A424A4AFFE4000
+6436:10201020105010C8FD2413FE150411FC190431FCD10011FC1284128454FC2084
+6437:1020102013FE1020FDFC110411FC150419FC3104D1FC110413FE108851042202
+6438:1020102013FE1020FDFC104013FE1488193432E2D02011FC107010AC53222020
+6439:100013FE100011FCFD04110411FC14001BFE328AD25213FE12221222522A2204
+643A:10A0109011FE1320FDFC112011FC152019FE3100D3FC1088109E1102520A2404
+643B:010006C01830EFEE00001FF010101FF0040C78F010107CFC1010FEFE10103030
+643C:10401248115013F8F88017FC11101A2835C4D84213F8104017FC104051402080
+643D:1088108813FE1088FCA81050108815241A2231FCD02010A81124122250A02040
+643E:1040102013FE128AFD04108010FE15401A40307CD0401040107E104050402040
+643F:11003906E2B822882448F85E238820082008FBBE228822882288238842A88010
+6440:1040108011FC1104FD0411FC110015FE190031FED00212AA12AA140250142008
+6441:200027FC24442444F7FC244424A425143404E7FC204020242522250AA90840F8
+6442:100013FC110811F8FD0811F8110E17F818083008D20411081090110852042402
+6443:100011FC10201020FBFE100015FC190431FCD10411FC110411FC108851042202
+6444:100013FC110811F8FD0811F8110E17F8180837BCD0A412A41128129054A82846
+6445:2040207C204027FEF442247027C42444343CE4202410245425422942A94A5238
+6446:100013FE12521252FBFE1020142019FC3020D02017FE10401088110453FE2102
+6447:1008103C13C01004FA44112811FC1A203020D3FE102011241124112451FC2004
+6448:1040102013FE1202FC1411E01100150019FC3110D11017FE1000109051082204
+6449:1040102013FE1202FCA81124145018883346D0F8110812881050102050402380
+644A:202820242740217EF1C82948257E25483248E27E254825482948207EA0404040
+644B:2000245C22942114FA9424542126290037DCE1142594255429482108A5144222
+644C:1040102013FC1000FD08109017FE1A2032A0D2FC1320122012FC1420542029FE
+644D:1040102017FE1402FD0011FE121016201A7C3244D244127C12441244527C2244
+644E:200027BC208424A4FA9424A4205029883626E0C02310206423882030A0C04700
+644F:1020102013FE1020FDFC104013FE148819043242D59C110411DC110451FC2104
+6450:212421242224F4242954214A22923610EA102250225C2250225022B0A29E4300
+6451:200027FE242A2426F7FE242227AA26AA37AAE4322596262E24462482A7FE4402
+6452:200023FC22042204FBFC220022842A4832FCE248224823FE24482448A8885108
+6453:1020147C12841148FC3010CE16101A7C3210D27C121012FE1210121055FE2800
+6454:1040102013FE1020FC4812F21124165218F83008D02013FE1020102050202020
+6455:22A822A827FC22A8FAAA24E628002FFC3444E04023F8224822482248A2584040
+6456:1100111013DC1254FD54128811081AF43402D00013FC10401150124855442080
+6457:2108210827C82108F91E27D225642D4037C8E1082388254829542114A1244142
+6458:2080204027FC2110F8A027FC24442DF43444E5F42514251425F42404A4144408
+6459:2010241022FE2210F8FE209226FE2A9232FEE21022FE221022102510A8FE4000
+645A:1020112410A813FEFA0210F81488188830F8D020102011FC1020102053FE2000
+645B:1040102013FE1000FD541124115415FC182033FED242129212FA120A52022206
+645C:100011FC112413FEFD2411FC100015FC190431FCD10411FC110411FC50882104
+645D:1040102013FE1250FE5013FE125216521BFE3200D29212D41298149254D2288E
+645E:100013FC124413FCFE4413FC108015101BE03048D18413FE1022112852A42442
+645F:102011FC112413FEFD2411FC102015FC192431FCD04013FE108811D05070238C
+6460:1040108013FC1244FAF4131412A41A4432A4D3FC104010241522150A590820F8
+6461:200027BE24882488F7A824A824A827BE3410E518249825A826AA244AA0464080
+6462:1040107C104013FEFA42127813C41A3C3208D2F0132412A815FE142058A02040
+6463:1040107C104013FEFA42127813C41A3C3200D2FC128412FC128414FC548429FE
+6464:1020102013FE1020FAAA112412AA182032AAD12412AA10501050108851042602
+6465:110011FC120015F8F90811F8150819F83000D7FE110013FC14A4112452542088
+6466:2200220E2F74F254255428D427543054EFD424542754215421522154A55C4284
+6467:1020122213FE1090FC8811FE1310151019FE3110D11011FE1110111051FE2100
+6468:100013FE120213FEFE101254123816541A823250D27C1290121015FE54102810
+6469:00803FFE24103F7C26382D543412203827C0204027F820402FFE404041408080
+646A:20902290229E22A2FAD423A8209428A437FEE28422A4229422942284A4944888
+646B:2200227C22442744FA7C224422442F7C3244E244227C22282528254AA84A5086
+646C:1080104013F81110F8A017FE10001BF83208D3F8120813F81120112252222C1E
+646D:2040202023FE2200FA48224823FE2A483248E248227822002554252AAA2A5000
+646E:08207F20087E7E4408A4FF2810101E2822645FC281003FF801007FFC01000300
+646F:08207E2008F8FF2814287F6A082AFF5608A21FC001003FF801007FFC01000300
+6470:08203E2008F87F282A685D2A08563E8200201FC001003FF801007FFC01000300
+6471:100011F8110811F8FD0811F8100017FC1A9433FCD00011F81090106051982606
+6472:22002202223C2FA0F2202FA02ABE2FA43AA4EFA422242FA422242244A2444284
+6473:100013FE1200127CFE441244127C16001AEE32AAD2AA12AA12EE120053FE2000
+6474:11FC102013FE1222FDAC102011AC140019FC3000D3FE108010FC100450282010
+6475:20142012201027FEFC10249024D22C9237F2E494249425C82AAA289AB1A64042
+6476:102013FE102011FCFD2411FC112415FC182233FED00813FE1108108850282010
+6477:1124124811241000FDFC112411FC152419FC3020D3FE107010A8112456222020
+6478:1110111017FC1110FC0013F8120817F81A0833F8D04017FC10A0111052082406
+6479:04407FFC04401FF010101FF010101FF00400FFFE10502788C1061FF001000300
+647A:200027BC208424A4FA9424A42084284033F8E208220823F822082208A3F84208
+647B:1040108811FC1108FA5213FE145019883626D0C0131010641388103050C02700
+647C:200027DC251427D4FC5427C825082D1437E2E000204027FC20402040AFFE4000
+647D:100013FE105011FCFD54115411FC140019FC3000D3FE102010A8112452A22040
+647E:2000277C21442144F97C271024102C7C3454E7542154217C21102114AAFE4402
+647F:1020105010881346FC2011FC108814501BFE3000D1FC110411FC110451FC2104
+6480:08007F7808483E4800863E782A483E3040689FC601003FF801007FFC01000300
+6481:102013FE104810F0FC2013FE1242109019F83028D12011FC122017FE50202020
+6482:200027FC244427FCFC4427FC21002BF83510E0E023182C0623F82208A3F84208
+6483:1078FE4810487C8654787C485430FECE10201FC001003FF801007FFC01000300
+6484:20002FBE28A22AAAFAAA2AAA251428A23080EFFE2110221023A02060A1984E04
+6485:20002FFE28002A28F9482BEE289228843AA0EAA82BE8288828942914A9245242
+6486:49202A3E7F4849485DA86B104928414600201FC001003FF801007FFC01000300
+6487:2108210825482390F91E27D425642D543554E75425D4254825482554A46444C2
+6488:208822AA22DC2488F954222220002BFE3242E44423FC204420442084A1144208
+6489:08407F40227E3E8801483E4804507E200850288C10F03F0001007FFC01000300
+648A:279E2492279E2492FF9E240224F22C9234F2E49224F2249224922532A4024406
+648B:200027BC24A427BCFCA427BC24042DF43444E4E42444244425F42404A4144408
+648C:104013F8124813F8F84017FE10001BF83208D3F8120813F8120813F851102208
+648D:200027BC21082528F7BC231825AA29463000E3F82208220823F82208A20843F8
+648E:102013FE102011FCFC0013FE120215FC180031FCD10411FC1104108853FE2000
+648F:100013FC100413FCFC0413FC100017BC192437BCD00813FE1108108850A82010
+6490:112410A813FE1202FCF8108810F8140019FC3010D11011FE1050109053102030
+6491:112410A813FE1202FCF8108810F8140C19F03020D1FC102013FE102050A02040
+6492:2288228827C82290FA9E27D420242FD43454E7D4245427C824482454A46444C2
+6493:1020102011FC1020FBFE1108179C19083188D63E100013FE109010905112220E
+6494:100011FC110411FCFD0411FC14201BFE3000D1FC110411FC1020112452222060
+6495:24802482249C2FD0F4902790249E27943494E4942FD42014251428A4B0244044
+6496:2008278820882110FFDE249424A427943494E794249424C827882C94A0A440C2
+6497:1088108811FC1088FC8813FE102015FC192431FCD12411FC1000108851042202
+6498:1210121013DE1228FD4410A015101A0835F6D000100013F81208120853F82208
+6499:2108209027FE2090FBFC2294231C2A0433FCE20423FC200827FE2108A0A84010
+649A:2110211421D22250FA7E255020902AA83128E14422442482200822A4A2524452
+649B:1020112410A813FEFCA8112412221104190431DED2441554109E110452042404
+649C:202027A420A82292F914220825F4280233F8E208220823F822082110AFFE4000
+649D:2004203E27C02244F92823F822082BFC3204E3FE240226AA2AAA2A02B0144008
+649E:102011FC10881050FDFE100011FC152419FC3124D1FC102011FC102053FE2000
+649F:101C11E0104013FEFC88110412FA148818F83000D3FE120212FA128A52FA2206
+64A0:21102114211227D2F91027DE24702FD23452E7D421142FD8210A211AA1264142
+64A1:2080211023F82210FCA427BC204028A03358EC462048226422522452A1404080
+64A2:100013FE105013FEFE5213FE100015FC190431FCD10411FC102013FE50202020
+64A3:100013DE12521252FBDE100015FC192431FCD12411FC102013FE102050202020
+64A4:2208210827C82210F49E2FD4206427943494E7942494278824882494A4A445C2
+64A5:202423A820922514F2082C0427BA20A837C6E40027BC208420A82090A5284244
+64A6:1040104017FC1110FA48144613F8185037FCD08013F81D0811F8110851F82108
+64A7:21102110221C22A4F4C82F3E212A222A34AAEFBE20A020222AA22AA2A81E4000
+64A8:1090108811FE1110FB1015FE1110191031FED110111011FE110012A452522452
+64A9:2040204027FC20A0F514220827FC2A0A33F8E20823F8204022482444A9444080
+64AA:2080211023F82080F7FE224825F4284233F8E24823F8224823F82040A7FC4040
+64AB:1100110013FC16A8FAA812A817FC1AA832A8D2A81FFE100012A8125454542000
+64AC:103813C0107813C0FC7813C4103C140018C63738D1CE173811CE1738514A2186
+64AD:207827C022482150FBFC215022482C0633F8E248224823F822482248A3F84208
+64AE:200023F8220823F8FA0823F820002FFE3480E7BC2494279424D42F88A09440A2
+64AF:1088105013FE1020FDFC104013FE148019FC3284D4FC108410FC108450FC2084
+64B0:200027BC24A427BCFC2024A4239C28003110E7FC211021102FFE2110A2084404
+64B1:2020272025FE2540FD7C2690257E2D00357CE544257C2644247C2444A444444C
+64B2:1050125211541050FBFE108814501BFE3020D1FC102013FE1050108851042602
+64B3:221022102510F4BE2822274422103210EF1022102AA8272822282344AC444082
+64B4:221021102FD02010F7BE24A427D420143794E094211421C82F082114A5144222
+64B5:1088108813DE1088FBDE108811541A2233FCD080112013FC102017FE50202020
+64B6:108813FE10881000FDFC10A810A817FE18A830A8D1FC102013FE102050202020
+64B7:220022FE22102FA0F27C2244275420543054E7542554255425282724A5424082
+64B8:210023F024102FFCF44427FC244427FC3000EFFE200023F8220823F8A20843F8
+64B9:12441124112813FEFA0211F8150819F83108D1F8110811F8109010905112260E
+64BA:2080204027FC2514FA48244423F82A4833F8E04027FC244427FC2444A0404040
+64BB:20102410227C2010F8FE204426282AFE3210E27C221022FE22102210A5FE4800
+64BC:2014201227FE2410F5D0241425D4255835CAE4162442282422A2228AA4784000
+64BD:2108220827C82450F7DE246427D422143114E7D4221423C822482454A55448A2
+64BE:1000127C11441174FC54105416FE12821ABA32AAD2BA1282128A1284550028FE
+64BF:1020102010501088FD0412FA1000140019DC3154D15411DC1088108851542222
+64C0:2108210821142FD4F12227C0245C27C83448E7C8213E2FC821082108A1084108
+64C1:2040202027FE2028FA24227E24C82F48317EE24824C82F7E21482248A47E4840
+64C2:200027FC20402FFEF842235820402B583000E7FC2444244427FC2444A44447FC
+64C3:109013FC129413FCFE9413FC100017FC1A0032F8D20013FE1520151455482986
+64C4:1040107C104013FEFE4213F8124412FC1AA832F8D2A812F8122015FC5444298C
+64C5:102013FF1000FDFE1102117A114A157A190231FED00010FC108410FC508433FF
+64C6:1108110817FE1108F84413F41048185037FED08011FC130415FC190451FC2104
+64C7:100013FE125213FEFC2011FC14201BFE3088D05011FC102017FE102050202020
+64C8:1050125211541050FBFE108814501BFE3020D1FC102013FE10A8112456222020
+64C9:100013F812A812A8FBF8110013FC1C8433E4D2A412A413E4109417F450142008
+64CA:083C7F242A243E422A3CFFA449187F6600201FC001003FF801007FFC01000300
+64CB:20402248215027FEF402280423F8220833F8E00027FC244427FC2444A7FC4404
+64CC:2210221023DE2528F8C4204027FE28403248E248255428A220A02110A2084C06
+64CD:23F82208220823F8F80027BC24A42CA437BCE0402FFE216022502448B8464040
+64CE:2420FF20247E7EC482287A104A287AC604201FC001003FF801007FFC01000300
+64CF:2288228827E82290FC1E27E4245428543754E5542554274825482054A2944122
+64D0:100013FC12941294FBFC100017FE180033FCD20413FC10A2111413085D442182
+64D1:101013D412521252FBD0101017FE1A5033D2D25213D4125412EA174A50562062
+64D2:204020A021102248FDF620A022482AA833F8E04027FC2484252425F4A414440C
+64D3:200027FE24282624FD7E244824C82C7E3648E57E24482448257E2640A7FE4000
+64D4:108010F8110813FEFD44119211FE1500197C3100D17C1100117C1244527C2444
+64D5:10A0109011FE1320FDFC112011FC152019FE3100D3DE12521252127252022206
+64D6:108813FE108811FCFD0411FC110415FC188031FED2221552110211FA500A2004
+64D7:20102008278824BEF48024942788247E3408E78826BE2A882A882B88B2884008
+64D8:3E1022FE3E4420287EFEA2103EFC221000201FC001003FF801007FFC01000300
+64D9:1040108013FE1222FEAA122213FE16721AAA3202D02013FE1020105050882306
+64DA:1040107C104013FEFE42127813C4163C1A0033FED24013A4125815B4545229B0
+64DB:108813FE10881000FD4813FE11481578190031FCD02013FE107010A853262020
+64DC:2108210827CC210AF90827DE24482EC83548E7C8255427D425542554A45444E2
+64DD:200027BC24A424BCF7A424BC24A427A43024E04C23F822A822A822A8AFFE4000
+64DE:22102A9027102220FFBE224427A42AA43228EFA82490289025282228A5444882
+64DF:200027FC2248F4442FFE244426EC3554E6EC244426EC255426EC2444A4544408
+64E0:2080204027FC2110F0A42F58255425523B58E000220823F8220823F8A2084408
+64E1:20402FFE204027FCF00023F822082FFE3802E7FC211023F8204027FCA0404FFE
+64E2:200027BC208424A4FA9424A421202A1037FCEA2023FC222023FC2220A3FE4200
+64E3:204027FC204023FCF80027FE20022BF83040E7FE200027FE200827FEA4A84798
+64E4:208023F8220823F8FA0823F820002FFC3444E7FC244427FC20002FFEA1104210
+64E5:00007E40487E7E9043087EFE48AA7EFE00201FC001003FF801007FFC01000300
+64E6:2080204027FE2402FA2423BC24A42AA83510E2E824042BFA20402248A44440C0
+64E7:0A0033B822083BB820883AB82288FFFE082037D8C1061FF001007FFC01000300
+64E8:200820682F8828EEF88A2BF22AA42AC43B84EAA42A642A0A2AEA2AAAAAAA5530
+64E9:200027FC20402FFEF842235820402B583000EFFE204027FC24A424A4A4A4440C
+64EA:3FFE28882F8A20082FBE28882F88289429A227F8204027FC20405FFE404080C0
+64EB:20002FFE28082BC8FA4C2BCA2A482BDE3808EBC82A482BD42A542BD4AA5452E2
+64EC:2400257C2604F4A82390207C24143794EA5022502FDC2250255024B0A89E4100
+64ED:108813FE10A81090FDFE132011FC152019FC3120D1FE110013FC10885070238E
+64EE:2110211427D22110FFFE229024502FF43494E7F4249427E8248A27FAA4264042
+64EF:1040102013FE1202FDFC1148165019FC3304D1FC110411FC110411FC50882104
+64F0:1040102013FE1222FD54114A123A100019FC3154D3FE100011FC102050A02040
+64F1:200027BC24A427BCFCA427BC24842DF43694E4E4271C24E424A424A4A4E4440C
+64F2:2440228E2FEAF28A2FEA2AAA2C6C3BAAE82A2FEA210A2FEA228C2448A8284008
+64F3:1108110811EE1294FC42100013DE16521BD23252D3D2121A1294135052102010
+64F4:2040202027FE2488FDFC248827FE2C2035FCE52425FC252425FC2400A4884904
+64F5:202027FE248827DEF48825DC26AA248C35F0E42025FC242027FE2820A8A05040
+64F6:121013DE15281084FD08109017FE10001BD43254D3D4125413D41244525422C8
+64F7:2200227E22102FA0F27C22442744207C3044E77C25442544257C2700A5284044
+64F8:1124124811241000FBFC129416641A9433FCD24813681248136A124A52462362
+64F9:2290229027D0229EFB92212227C82D4837C8E10827C821142FD42294A4544822
+64FA:200027FC24A424A4F7FC222024A427B83022EF9E28802FA428B82FA2A8A2499E
+64FB:210827C825482FF0F55E27E4211427D43554E7D422142FC824482694A1944662
+64FC:210023F024102FFCF44427FC244427FC3524E89223F8220823F82208A3F84208
+64FD:244424E428A82AAAFEEE24A42AAA2EEE3242E0402FFE20E021502248AC464040
+64FE:27FC208023F82208F3F822082FFE28823548E51428F4210023F82508A0F04F0E
+64FF:2020201024FE2244FA2820FE20922EFE3292E2BA22AA22BA22862500A8FE4000
+6500:22882108FABE2008729CA92A2288FFFE082037D8C1061FF001007FFC01000300
+6501:2208211027FC2040FBF8208027FC294833FCE60A2BF8220823FA2234A28C4302
+6502:23F82248224823F8F248224823F820003FBEEAAA2AAA2FBE2AAA2AAAAFBE48A2
+6503:1088108813FE1088FD1011DE125215541A883174D20211FC1020112452222060
+6504:2020203E202027FEFC2225F824222DFE3524E5FC252425FC28402AA4B28A447A
+6505:108811DC108813DEFC881154122211FC190431FCD10411FC110411FC50882104
+6506:108813DE108813DEFD54122211FC142019FC3124D1FC112411FC102053FE2020
+6507:20402FFE284227FCF84023F820402FFC3040E7FC24A427FC20402524A52A48FA
+6508:102013FE125013FEFA5213FE12941AD83292D2CE120812F0122015FC54A82B26
+6509:27FC204027FE2442FB5C2040275C292033FCE6202BFC222023FC2220A3FE4200
+650A:200027FE24442598FC8827DE24882DDC36AAE48824202520253C2920A92057FE
+650B:2108210827CE2112F92427DE25522D5E37D2E11E2392255E29402114A1124122
+650C:2FFE28022BFA2AAAFBFA28022BFA280239F2E91229F228AA29922ACAA8824FFE
+650D:40807FFC48004FF8E0004FF848084FF86080DC9C57D45D54555C5C965556EE22
+650E:1040107C104013FCFE4413F0124416FC1AA832F8D2A812F8120015FC55542BFE
+650F:1110109013DE1010FA5E118217DE181033DED25013DE125013DE1250525222CE
+6510:104017FE149213FCFC9013FC109017FE19483224D5FA10A411A8129054C82086
+6511:1140126C1244136CFEA413AC12A417FE19083244D5F2104017FC104050402040
+6512:2108252827BE2948F7BE231825AA29463000E3F822082248224820B0A1084604
+6513:204027FE249223FCF89023FC20902FFE3108E3FC250A21F82240227CA54048FE
+6514:27BC24A427BC24A4FFBC244425F42C4435F4E55425F4255425F424E4A554444C
+6515:2448244C2AAAF0082FFE22882EE8328AEEEA228C2EEC228822EA2F1AA4264042
+6516:13DE125213DE1252FBDE125213DE198C3252D04017FE10881190106050D82304
+6517:204027FE24A027FCFCA427FC25142DD83512E54E25A424A827FE28A8A9245222
+6518:204027FC200023B8FAA823B821102FFC3110E7FC21102FFE21282310AD484186
+6519:11F0121017FC1204FBFC122413B81A2231FED21017FC124413FC10D0514A263E
+651A:108812AA12DC1488F954122217FE1A0230F8D08810F8100011FC110451FC2104
+651B:104017FE14921108FC80131C1204179C1A0433FCD24813681248136A52462362
+651C:122213FE109011FEFB1015FE111019FE3110D1FE110013FE128A137652522276
+651D:13FC110811F81108FDF8110E17F8180837FED294139C1294139C12D657BC2084
+651E:200027FC24A4F4A427FC221022A834BEEF68223C24A82FBC20282AA8AABE4020
+651F:204027FE24A027FCFCA427FC24002DFC3504E574252425FC257429ACA92451FC
+6520:202027FE248827DEFC8825DC26AA2C883450E7DE245025DC24502BDEA8505050
+6521:241822142F90253EFAA82DE828BE2FA83228EFBE2AA82AA82BA828BEAAA04920
+6522:252827BE294827BEFB1825AA29462BFC3204E3FC220423FC220423FCA1084204
+6523:21084FD2F03C23884812FBBE0280ABAA00201FC001003FF801007FFC01000300
+6524:251825142F90253EF72822682FBE2AA83FA8E23E2FA822283FE8253EA8A05060
+6525:221023DE25282084FBFC22A422542BFC3080E7FE22A825E4285223F8A15042C8
+6526:2FBE200027BC24A4F6B424A4204027FE34A0E7FC24A427FC251229DCA91251CE
+6527:2200221E2FC42208F79E24922792249E3792E49E279224922FDE2500A48C4892
+6528:20402FFE2A0A2434F3C02290228822A434D0E18E2E742B542AD42A52AB5A5294
+6529:2248215027FC2404F9F0211027FC2D5434E4E7FC204027FC20402FFEA2A44452
+652A:22AC244426AC2444F6AC24042FFE2A0A33F8E20823F8220823F820A0A124461C
+652B:13DE125213DE1252FBDE10A011FE1B2035FCD12011FE100011FC10885070278E
+652C:2790251E27A82484FFBE252A27BE280033F8E20823F8220823F820A0A124461C
+652D:21F0221023E02020F7FC2188265021A83664E1A022482FBE2AAA2FBEA28A4FBE
+652E:204027FC224823F8F0402FFE2AAA23B83110E7FC21102FFE21282310AD484186
+652F:0100010001007FFC0100010001003FF01010082004400280010006C01830E00E
+6530:102010201020FE2010FC1024FC24442444242844284410941908240043FE8000
+6531:202010201020FDFE00200820882089FC48844888504850501C20E05041880606
+6532:10101010FE1010FE28104410FEFC044474445444542874285410042814440982
+6533:11FC100410FCFE0411FC1000FDDE449247DE28082BFE110818A8241043FE8000
+6534:01000100010001FC0100010001003FF01010082004400280010006C01830E00E
+6535:0400040004000FFE08101010302048208440028001000280044008203018C006
+6536:084008404840488048FE49084A88488848885850685048200850088809040A02
+6537:00400040FE40208020FE210842887C8804880450045004200450048829041202
+6538:082008200820103E12443244524492A412281228121012101228104810841102
+6539:00400040FC8004FE0508050806887C8840884050405044205850608841040202
+653A:004000407C40448044FE4508468844887C884050405040204450588861040202
+653B:004000400040FE8010FE1108128810881088105010501E20F050408801040202
+653C:00407C401040108010FE11081288FE8810881050105010201050108811041202
+653D:002014201220123E214421444044BEA41228122812101210222822484A848502
+653E:204010400040FE8020FE21083E88248824882450245024204450548889040202
+653F:00200020FF20083E0844084448444EA448284828481048104F28F04800840102
+6540:1040104020407C8044FE4508468844887C8844504450442044507C8845040202
+6541:1020102010201E3E1020102010207DFC44844488444844507C20445001880606
+6542:1020102020203F3E414481443D4425A4252825283D102510012801480A840502
+6543:0020FE208220823E8244FE44904490A4FF289028901088108928A528C3448182
+6544:0040FC400440688010FE0908FE88128834883050505050209050108851042202
+6545:1040104010401080FEFE1108128810887C8844504450442044507C8845040202
+6546:08100810141E22104110BEFC004400443E4422282228221022103E2822440082
+6547:08100810FF900820083E7F44492449244D244A281C282A10492888A808440882
+6548:102008200020FF3E00442444424481A424281428081014102228424880840102
+6549:104010409440548058FE1108FE88308838885450545090201050108811041202
+654A:081008100E10081E08100810FEFC0044084408444A2849288910082828441082
+654B:204020403C404480C4FE290812882888448882507C504420445044887D044602
+654C:04200E203820083E0844FF44084408A43E2822282210221022283E4822840102
+654D:081008101410221E4110BE1008FC08447F4408442A2829284910882828441082
+654E:0240644018402480D2FE1108FE882088FE88445088500F20F850088829041202
+654F:402040207F20803E7E44424452444AA4FFA8422892108A10FF28024814840902
+6550:00207F204020403E5E44404440447FA4502851285A1054105228912898441082
+6551:1040144012401080FEFE11081088928854881050385054209250108851042202
+6552:1210121012102FA02ABE6AC46AA4AFA42AA42AA82AA82F902228222822442282
+6553:004028402440428080FE7D084688448844887C502850282028502A884D048A02
+6554:0020FF201020103E7E4422442244FFA4002800287E104210422842287E444282
+6555:08200820FFA0083E08447F44494449A47F2808281C102A104928884808840902
+6556:0820082008207F3E08443E440844FFA410281E281210121022282A4844848102
+6557:00407C40448044FE7D08450846887C88448844507C5000202850248845048202
+6558:082008201420223E4144BE44084408A47F2808282A1029104928884828841102
+6559:082008207EA0093E0A44FF4408447EA4242848288F1078100828084828841102
+655A:44402440284000807CFE4508468844887C882850285028202A504C8889040202
+655B:082008201420123E214440C4BE4400A411280928491022102228074878842102
+655C:082008201420223E514488447E4402A4142808282A10A110A128A5281C440082
+655D:0810491029102A20083E7F44492449245D246B28492849104928412845444282
+655E:0820492029202A3E08447F44414441A45D285528551055105D28412845444282
+655F:1420142014207F3E5544554455447FA4552855285510FF902428224842848102
+6560:0010F7101110551E2210551089FC10440044F744112855282210552889441082
+6561:00107E104210421E7E10421042FC7E4420447F44952825284910912825444282
+6562:00207E200220043EFF44224422443EA422283E28221022102F28F22842440282
+6563:242024207E20243E2444FF4400447EA442287E2842107E10422842284A444482
+6564:00107F104910491E7F10491049FC7F440844FF441C282A284910882808440882
+6565:0810091049104A1E8810141022FC49448844494449288A281410222841448082
+6566:10200820FF20003E7E4442447E4400A47E28042808100F10F828084828841102
+6567:081008107F1E1410221041FCFF4402447A444A284A287A104A1002280A440482
+6568:102008207F20003E22441444FF4400A400283E282210221022283E2822440082
+6569:511029102A100020FFBE80C401247E24042408280F28F8100828082828441082
+656A:0020F7201120553E22445544994400A4F7281128551022105528894810840102
+656B:082010207E20423E7E4442447E4410A40828FF2820103E10222842484A848502
+656C:22202220FFA0223E40447F44414481A47D28452845107D10452801280A440482
+656D:00207E2042207E3E42447E440044FFA440287F2895102510492891482A844502
+656E:02100F107810081E0810FF1028FC4B44494449446B28492849107F2841440082
+656F:0010FE108210FE1E8810FF1088FCA544C3440044FE288228FE108228FE448282
+6570:082049202A20083EFF442A44494488A41028FE2822104210642818283444C282
+6571:0810491049107F1E0010FF1000FC7F44414441447F28422824100F28F0444082
+6572:10100810FF10001E7E1042107EFC0044FF448144BD28A528BD10812885448282
+6573:0820492049207F3E0044FF4400447FA4412841287F10421024280F48F0844102
+6574:08200820FFBE08447FA449247F282A104928884600007FFC010011F81100FFFE
+6575:102008207F20223E14447F44414449A47F2849285D10551055285D2841444382
+6576:0210E210BFD0A220AFBECAC4AFA4AAA4AFA4A228A728CA909268822882448282
+6577:0A200920FFA0083E7F4449447F4449A47F2849281010FF9020283E2842448682
+6578:08107F104910FFA0493E7F4408247F2449247F281028FF10212872280C44F382
+6579:082008200F20083EFF448144064478A449282A28FF1018102C284A4888840902
+657A:0010FF90801E9F10911091FC9F448044BBC4AAA8AAA8AA90BB908028FFC40082
+657B:10001FE020207FF8A30824881FF010101FF010101FF008001FF8282007C0F83E
+657C:0810FF9008107F1E00107F1041FC7F442244FFC400287F28411041287F444182
+657D:061078101010FF9E22105D1094FC1C4400447F4441285D2855105D2841444382
+657E:22101410FF9008207F3E0844FFA449242A24FFA800287F10412841287F444182
+657F:061078101010FFA0223E5D4494A41C2400247F2841285D1055285D2841444382
+6580:00107F10551E55107F1020FC7F4491447D44552855287D1011107D2805440282
+6581:00207F2055207F3E08447F440844FFA4222814287F100810FFA8084808840902
+6582:082008201420223E4144BE44004400A477285528551077102228222855448882
+6583:49202A3E7F4849485DA86B10492841460000FFFE10803E9842E024841884E07C
+6584:08203E3E08447FA82A10492808443FFE20802FFC249024902AA851C446B0988E
+6585:34104B105510631E55106B10557CFFA480A47E2404280F28F810082828441082
+6586:34104B1055106320553E6B445524FFA480A47E2804280F10F828082828441082
+6587:020001000100FFFE10101010082008200440028001000280044008203018C006
+6588:020001007FFC0820044003801C70E00E0FE000400080FFFE0100010005000200
+6589:020001007FFC0820044003801C70F01E10101FF0101010101FF0101020104010
+658A:020001007FFC0820044003801C70E00E3FF808200FE008200FE0083EFFE00020
+658B:020001007FFC0820044003801C70E00E1FF0020004003FF82488248824A82010
+658C:0010201411D20012FC100BFE08104890289012D012902A902A8A4AEA87060202
+658D:01007FFC0820044003801C70E00E1FF010101FF010101FF010101FF00842F03E
+658E:020001007FFC0820044003801C70E00E17D0101017D011101590255029104010
+658F:0040202011FC0104FD0409FC0904490429FC1120112229142908494481820100
+6590:04407C7C044004403C78044004407C7C04400100FFFE0820044003801C70E00E
+6591:00000200F93E21082FC820882488FA8822BE210821083A88E2884448087E0000
+6592:0040202011FE0102FD0209FE0900490029FE11AA11AA2AFE2AAA4AAA84A20086
+6593:0200417C25040444FDF4144415F41554957455D4255425F454E455548444044C
+6594:20201020FEA0052C6924112429ACD52411247DFC55247C5010501C88E5044202
+6595:03DE225213DE0252FFDE0A220AFA4A222AFA12AA12FA2AAA2AFA4A7282AA0226
+6596:01007FFC082007C01830E7CE244837D82448FFFE90121FF010101FF01010FFFE
+6597:0040044002400240104008400840004000FE7F40004000400040004000400040
+6598:1010101010901E5012102290225052108A1E05F0041008100810101020104010
+6599:080808884A482A482C080888FE4818481C082A0E2AF848088808080808080808
+659A:1020102024487EFC224400007FFE4442824410400840007EFFC0004000400040
+659B:100810883C4824484808BE882A482A483E082A0E2AF83E082A084A0842088608
+659C:08080848142822284108BE48082808287F0E08782A0829084908880828081008
+659D:00003E7C224422443E7C00007FFE4442824410400840007EFFC0004000400040
+659E:080828484B28492849086B48492849287F0E4978080814081208210841088008
+659F:22082248FF2822283E0822483E282228220EFF7840085408620840087E080008
+65A0:22082248FFA822287F082248FFA808287F0E49787F084908FFC8410845084208
+65A1:102010201050FE8811047C1244907C5045107C90101EFEF01010101010101010
+65A2:220822487F2822282208FFC808287F28490E7F7849087F080008220841088088
+65A3:00087F48552855287F0820487FA890A87C8E54F854887C881288FE8802880108
+65A4:001000F81F001000100010001FFE104010401040104010402040204040408040
+65A5:001000F81F001000100010001FFE1040104011C0106010502048204040408040
+65A6:0200070438782040204020403F7E244824482448244824482448448844888108
+65A7:044008201850248803000CC03030C0EE1F00100010001FF81080108020804080
+65A8:0408241C24E0248024803C8004FE0488FC882488248824882508450846088408
+65A9:2008201C21E0FD004100510091FEFD10111011101D10F1105110121012101410
+65AA:2000200440787E40824002407A7E4A484A484A487A484A480248028814880908
+65AB:0008001CFCE01080108020803CFE64886488A488248824883D08250822080408
+65AC:1008101C10E0FE8010807C8054FE7C9054907C901090FE901090111011101210
+65AD:0400040455784E4044407F40447E4E48554865484448444840487F8800880108
+65AE:240024047E7824402440FF40007E7E48424842487E48424842487E8842880108
+65AF:220022047F78224022403E40227E22483E4822482248FF480448228841888108
+65B0:100008047F78004022401440FF7E084808487F4808482A484948888828881108
+65B1:100010047D7812401440FF40107E20487E48A24822483E48224822883E882308
+65B2:000077045578554077401440147E7748414841487748144814481F88F0884108
+65B3:22002202FFBC22203E2008207F3E49247F2408247F2408247F2408440F44F084
+65B4:080049022A3CFFA02A20492088BE4124412477A49124552427A4414481440184
+65B5:10006F044578554069404B40107EFFC8144877484148774814481788F8882108
+65B6:00000DFC7154415441FC40807DFC4A4449F44954495449F4484449F448148808
+65B7:0882509C5D5049D054905DDE44547FD4489450945D5449D454945DD444647FC4
+65B8:7FC2405C7FD052504A90525E5FD455545FD464545F5455545F544454BF640084
+65B9:020001000100FFFE04000400040007F004100410041008100810101020A04040
+65BA:202010200050FE50208821043E02248824882488248824884488550889080208
+65BB:208010800080FEFC210022003CF02490249024902490249244925512890E0200
+65BC:202010200020FE50205020883D04260224602410240024C04420541088080000
+65BD:2080108010FE0120FE202120212C3D7427A425242534252A2522450254FE8800
+65BE:208010800080FEFE212022203C2025FC25242524252425244534552888200020
+65BF:2080108010FE0100FE0020FC20043C08241025FE241024102410441054508820
+65C0:202010200048FE8421FE20023C20242024A824A4252425224622542088A00040
+65C1:020001003FF8082004407FFE420281043FF80400040007F00810081010502020
+65C2:2080108010FE0100FE0C20F020803C80248024FE248824882488450855088A08
+65C3:2080108010FE0100FE0020FC20843CA42494248425FE24842484450455148A08
+65C4:2080108010FE0100FE1C21E020203C3C25E02420243E27E0242044225422881E
+65C5:2080108010FE0100FE0C20F020903C902492249424882488248444A454C28880
+65C6:2080108010FE0120FE2021FE20203C2025FC2524252425242534452854208820
+65C7:2080108010FE0100FE10201020FE3C92249024FC24A424A424A8451055288A46
+65C8:2020101001FEFE20204820843DFE240224A824A824A824A844A854AA892A0206
+65C9:01107FFC01003FF821083FF821083FF821080080FFFE08000FF810082028C010
+65CA:2080108010FE0100FE0020FC20403C402478244824A82498248844AA54CA888E
+65CB:2080108010FE0100FE0021FC20243C2424A024A024BC24A024A04560553E8A00
+65CC:2080108010FE0110FE10209020FE3C902510241024FE24102410441055FE8800
+65CD:2080108010FE0120FE20205020883D242612241025FC24042488445054208810
+65CE:2080108010FE0100FE0020FC20843C8424FC248024A424A824B0452255228A1E
+65CF:2080108010FE0100FE80208020FC3CA02520242027FE24202450445054888906
+65D0:2100110011FE0200FC50205022543D58245024D825542652245044505492890E
+65D1:2020102011FC0050FC88210423FE3C0825E82528252825E82528440854288810
+65D2:2100110011FE0240FC2021FE20403C8425FE240224A824A824A844AA552A8A26
+65D3:2100110011FE0220FD2420A820203DFC250425FC250425FC2504450455148908
+65D4:40102010007CF71441FE4114727C5210577C511051FE551052105300B4FE0800
+65D5:10100810FF2820443E822210220842204A10840800007C8844B044C47C84447C
+65D6:2100110011FE0200FC2021FC20503C8827FE240825E8252825E8440854288810
+65D7:2100110011FE0200FC8821FC20883CF8248824F82488248827FE445054888904
+65D8:2110109413D20012FA50219027FE38102BD22A522A542BD42A4A4A4A4BD69822
+65D9:203C13E0112400A8FDFE20A821243E0225FC2524252425FC2524452455FC8904
+65DA:210011FE120001FEFC5021FC21543DFC240025FC240027FE242044A855248A64
+65DB:2100110011FE0200FC1C23E021243CA827FE2524260225FC252445FC552489FC
+65DC:210011FE122004FCFC0021FE21023D7A254A25FE248424FC248444FC540089FE
+65DD:208010FE11300248FCB4210221FE3DAA257225FE240024FC248444FC548488FC
+65DE:2080108010FE0100FE44202822FE3D2024542728255C252A254A452856908C7E
+65DF:2100110001FEFE002540224C3A642B4C2A642AA42BAC2AA44FFE689091080204
+65E0:00003FF002000200020002007FFC0480048004800880088010842084407C8000
+65E1:00003FF002000200420042007FFC0480048004800880088010842084407C8000
+65E2:00007DFC442044207D20452045FE7C204020483044504A5052926092410E0200
+65E3:100021FC7C2044207D2045207DFE0020402040307C50405040924C92710E0200
+65E4:00007DFC442044207520552055FEFE208220BA30AA50AA50BA9282928B0E8600
+65E5:00001FF0101010101010101010101FF01010101010101010101010101FF01010
+65E6:00001FF010101010101010101FF010101010101010101FF000000000FFFE0000
+65E7:200023FC2204220422042204220423FC2204220422042204220423FC22042000
+65E8:2000207023803C08200820081FF800001FF0101010101FF0101010101FF01010
+65E9:00001FF0101010101FF0101010101FF001000100FFFE01000100010001000100
+65EA:002000207C2044204420442047FE7C2044204420442044207C20442000200020
+65EB:000000007DFC44444444444444447C4444444444444444847C84450402280410
+65EC:080008000FFC100410042FC4484488440FC4084408440FC40844000400280010
+65ED:200020F820882088FC8824F8248824882488248824F8248A2402440243FE8000
+65EE:020002003FE0042008223022C01E00001FF0101010101FF0101010101FF01010
+65EF:00001FF0101010101FF0101010101FF0020002007FE00420042008221022601E
+65F0:000000FC7C2044204420442044207DFE44204420442044207C20442000200020
+65F1:1FF0101010101FF0101010101FF000003FF801000100FFFE0100010001000100
+65F2:00001FF0101010101FF0101010101FF001000100FFFE0280044008203018C006
+65F3:004000407C8044FC4504460444047D0444844444444444047C04440400280010
+65F4:000001FC7C2044204420442047FE7C2044204420442044207C20442000A00040
+65F5:00001FF0101010101FF0101010101FF00000010021082108210821083FF80008
+65F6:000800087C08440845FE440844087C0844884448444844087C08440800280010
+65F7:00400020782049FE490049007900490049004900490079004900020002000400
+65F8:000001F87C1044204440448045FE7C9244924492451245227E22444200940108
+65F9:01002108210821083FF80100FFFE00001FF0101010101FF0101010101FF01010
+65FA:000007FC784048404840484078404BFC4840484048407840484000400FFE0000
+65FB:1FF0101010101FF0101010101FF0020001007FFC08200440038004401830E00E
+65FC:004000207C2047FE4488448844887C8844884450445044207C50448801040602
+65FD:0020002078204BFE4820492449247924492449FC4824482078224822001E0000
+65FE:01000100FFFE010021083FF80102010200FE00003FF820083FF820083FF82008
+65FF:008000807C8045FC4520462044207C2047FE4420442044207C20442000200020
+6600:004000407C8044FC4504460444847C4444444414442444447D84440400280010
+6601:0020002078204BFE4820482049FC792449244924492449347928482000200020
+6602:3FF820083FF820083FF800000C0070FC4084408440844C847094408800800080
+6603:00001FF010101FF010101FF000003FFC20802080214021402220441048089006
+6604:0008003C7BC04A004A004A007BF84A884A884A884A507A504A20045004880906
+6605:000003FC7884488848884890489C788449444944492849287A104A2804440182
+6606:00003FF0201020103FF0201020103FF00000208020843E9820E020842684387C
+6607:00001FF010101FF010101FF000000720782008200820FFFE0820102010202020
+6608:002000107C1044FE4482448244827CFE44824480448044807C80450001000200
+6609:004000207C2047FE4480448044807CFC44844484448444847D04450402280410
+660A:00001FF010101FF010101FF0000000003FF801000100FFFE028004401830E00E
+660B:3FF801000200FFFE044008203018C0061FF0101010101FF0101010101FF01010
+660C:1FF0101010101FF0101010101FF000003FF8200820083FF8200820083FF82008
+660D:000001FC7D0445044504450445047DFC45044504450445047D0445FC01040000
+660E:000000FC7C844484448444FC7C844484448444FC7C8444840104010402140408
+660F:00783F80208020803FFC20402822301A20061FF0101010101FF0101010101FF0
+6610:001000907C9044884508450446047DFA44884488448844887D08450802280410
+6611:002000207C5044504488454446227C20440045FC440444087C08441000100020
+6612:01000100790049FC4AA44CA448A4792449244A444C44488479044A0404280010
+6613:0FF0081008100FF0081008100FF0040008001FFC224442440484088411280210
+6614:044004403FF804400440FFFE000000001FF0101010101FF0101010101FF01010
+6615:0004000E7CF044804480448044FE7C8844884488448844887C88450801080208
+6616:00100090789048884888492449247A224C4048404888488479044BFE01020000
+6617:00001FF0101010101FF0101010101FF0020001007FFC00000440082010102008
+6618:00001FF010101FF010101FF002000100FFFE040007F004100810101020A04040
+6619:00001FF010101FF010101FF000003FF800000000FFFE0400082010103FF81008
+661A:01000100FFFE01002288145008203018DFF6101010101FF0101010101FF01010
+661B:000001FE7D004500450045FC45047D044504450445FC45007D00450001FE0000
+661C:00001FF010101FF010101FF00000FFFE08001FF8224844480888110822280410
+661D:104010403E5022485444084017FE2000DFF0101010101FF0101010101FF01010
+661E:000003FE7820482048204BFE7A224A224A524A4A4A8A7B024A020202020A0204
+661F:00001FF010101FF010101FF0010011001FF8210041001FF0010001007FFC0000
+6620:00200020782049FC492449247924492449244BFE482078504850008801040202
+6621:002000107C1045FE4420442044447C8445F84410442044447C8245FE00820000
+6622:002000207D2445244524452445FC7C2044204524452445247D24452401FC0004
+6623:002000207C5044884504461244207C4045884410442044447D88441000600380
+6624:002000207C5044504488452446127C1045FC4404440844887C50442000100010
+6625:010001007FFC01003FF80200FFFE082010102FE8C82608200FE0082008200FE0
+6626:00001FF010101FF010101FF002007FFC044008203458C4460440044008401040
+6627:00200020782049FC4820482048207BFE487048A848A8492479244A2200200020
+6628:01000100790049FE4A804A804C8078F848804880488048FC7880488000800080
+6629:0040004078404FFE4840484048407BFC484048E049504A487C46484000400040
+662A:00001FF010101FF010101FF0082010103FF808280820FFFE0820102020204020
+662B:00800080790049FC4A044C0449E479244924492449E449247804480400280010
+662C:00003FF820083FF820803FFC20402C243014200C1FF010101FF010101FF01010
+662D:000003FC788448844884490449147A084C0049FC490449047904490401FC0104
+662E:00001FF010101FF010101FF0004000407DFC1044104410841C84E10442280410
+662F:1FF0101010101FF0101010101FF00000FFFE0100110011F811002900450083FE
+6630:00001FF010101FF010101FF0000000007FFC0100110011F811001100FFFE0000
+6631:1FF0101010101FF0101010101FF00200010001007FFC0000101008200440FFFE
+6632:0090009078904BFC489448947BFC4A904A904BFE48927892491A011402100410
+6633:004000407A404A404BFC4A404C4078404FFE484048A048A079104A0804040802
+6634:00001FF010101FF010101FF000000C0070FC448444845C846494488810806080
+6635:000001FC79044904490449FC49007940494449484970494079424A42023E0400
+6636:08000400027C3C44044404C4757C164416441544257C248044408430140E0800
+6637:00001FF0101010101FF0101010101FF000003FF82448244824482448FFFE0000
+6638:004000407C7C44844588465044207C5044884706446044107C0844C000200010
+6639:00400020781049E0482248347BB848B048A848A8492879244A24042200A00040
+663A:00001FF010101FF010101FF000007FFC01003FF8210822882448282820082018
+663B:00001FF010101FF010101FF000007CFC10841084108410841E94F08840800080
+663C:00001FF8100810081FF81040102020102FE848268FE008200FE000007FFC0000
+663D:00900088788848804BFE48A048A078A448A44928492849327A224A62049E0800
+663E:00001FF0101010101FF0101010101FF0044044442444144814500440FFFE0000
+663F:00200010781049FE490049107910491049104920492879244A4402FE04420800
+6640:0090009078904A9249944898489079984A944C9248904890791249120212040E
+6641:00001FF0101010101FF0101010101FF0244814500C601450644808421042603E
+6642:002000207C2045FC4420442047FE7C08440845FE440844887C48440800280010
+6643:00001FF010101FF010101FF00100111009200100FFFE0440044008421042603E
+6644:004000447A444948495048404FFE7890489048904890489279124912020E0400
+6645:000003FE7800480049FC4904490479FC4904490449FC49047800480003FE0000
+6646:002000207DFC44204420442047FE7C004420442045FC44207C20442003FE0000
+6647:002000207BFE4850488849047AFA48004BFE4840488079FC4804000400280010
+6648:004000207C2047FE4400448845047E0244884488445044507C20445000880306
+6649:00007FFC0810102024487EFC02040000FFFE00001FF010101FF010101FF01010
+664A:000003FE7840488049104A084BFC7844484048404BFC48407840484007FE0000
+664B:00007FFC0440244814500440FFFE00001FF0101010101FF0101010101FF01010
+664C:0040004078804BFC4A044A044AF47A944A944A944A944AF47A044A0402140208
+664D:000001FE7D024502457A450245027D7A454A454A454A457A7D024502010A0104
+664E:01100110791049104BFC49107910491049104FFE480079104908020804040804
+664F:00001FF010101FF010101FF001007FFC42040200FFFE08201C4003800C707008
+6650:0020001078104BFE48204842488479F84810482248C44B087810482800C40302
+6651:00001FF010101FF010101FF0020004003FF8200827C82448244827C820282010
+6652:000007FE7890489048904BFC4A947A944A944A944A9C4B047A044A0403FC0204
+6653:0080008078BC4BC04850482448D47B0C48004BFE4890489079124912020E0400
+6654:00900094791449184B104D324952790E492048204BFE48207820482000200020
+6655:1FF010101FF010101FF000007FFE42029FF4040009001FF001007FFC01000100
+6656:000003FE7A024C4448404BFC488078A0492049FC482048207BFE482000200020
+6657:0040004078A049104A884C4649F07810482048404BF84A087A084A0803F80208
+6658:000001FC7D0445FC450445FC44007C0045FC4420442047FE7C20442000200020
+6659:00400040788849044BFE4802488879444A4248F849884A507820485001880606
+665A:0080008079F84A084C104BFC4A447A444A444BFC48A048A079224922021E0400
+665B:000003F87A084A084BF84A087A084BF84A084A084BF87920492002220422181E
+665C:00001FF010101FF010101FF004407FF801083FF821003FFC0304051419086100
+665D:01003FF80108FFFE01083FF801007FFC00003FF820083FF820083FF80000FFFE
+665E:01840068783048C84B0448407BFE48A049204BFC4D2479244934012800200020
+665F:1FF010101FF010101FF000883FFC208020883E88225022502A244454418C8604
+6660:00280024782448204BFE4A207A244A244BA44AA84AA87A904A9205AA04460882
+6661:004800447BFE484048404BFC4A447A444BFC4A444A444BFC7A444A4402540208
+6662:080C08F07E8008800EFE788808882908120800001FF010101FF010101FF01010
+6663:0104010E793049204FE04920793E496449A44F24492479244924012405440284
+6664:000003FE7840484049FC488448847BFE4800480049FC49047904490401FC0104
+6665:004000207BFE4A024C0449F8780048004BFE48904890789049120112020E0400
+6666:0100010079FC4A004DF84908494879284FFE49084A484A287BFC480800500020
+6667:00200120792049FC49204A2078204BFE4800480049FC79044904010401FC0104
+6668:1FF010101FF010101FF000003FFC20002FF820003FFE2908289048604A188C06
+6669:0080008079F84A084C104BFC4A447A444A444BFC48A048A079224922021E0400
+666A:0090009078904BFC4A944A944A947BFC4A944A944A944FFE7800489001080204
+666B:00400040787E48404BFC4A044BFC7A044BFC4A4448404FFE7840484000400040
+666C:004000207BFE48004888488849547A22480048204BFE48207820482000200020
+666D:000003FE7A224A224AFA4A227A224BFE4A024AFA4A8A7A8A4AFA0202020A0404
+666E:082004407FFC044024481450FFFE00001FF0101010101FF0101010101FF01010
+666F:1FF010101FF010101FF00100FFFE00001FF0101010101FF00100210845040200
+6670:0200020CF27092409F409240927EF64897489AC89A489248F248924802480288
+6671:0020012279224A24485048887B0448224820492449247A284850008801040602
+6672:000000407B9C4A044A044B9C7A044A044BFC489048907890489001120212040E
+6673:080C08F07E8018802CFE2A884888888809081FF0101010101FF0101010101FF0
+6674:002000207BFE482049FC48204BFE780049FC490449FC490479FC490401140108
+6675:104008403E7E228823503E20205841869FF0101010101FF0101010101FF01010
+6676:0FE0082008200FE0082008200FE000007EFC428442847EFC428442847EFC4284
+6677:1FF010101FF010101FF008401F6022505448084037FEC0001FF0101010101FF0
+6678:1FF010101FF010101FF000207F20043E044427A42428242824102F28F0444082
+6679:01FC010479FC4904490449FC7800490049FE4A4A4C4A789249120222004A0184
+667A:20003E7C48440844FF441444227C40001FF0101010101FF0101010101FF01010
+667B:004000807BFC49104A484C464BF87A484A484BF84A484A487BF848420042003E
+667C:00800040F7FE94029A04920093BCF4A494A496A499349128F22292220422081E
+667D:01100110F110911097BC91109110F33893B8955495549992F110911001100110
+667E:004000207BFE4800480049FC49047904490449FC482048A879244A2200A00040
+667F:00FC00847C8444FC4484448444FC7C0045FE4502450245FE7D02450201FE0102
+6680:0090008879004A7E4C90489049107B104D7E49104910491079104910017E0100
+6681:0020002079FC482048A848887BFE488848004BFE4890789049120112020E0400
+6682:100CFEF0208048807EFE08880E88F9084A081FF8101010101FF0101010101FF0
+6683:00001FF010101FF010101FF004407C7C044004407C7C04400440FC7E04400440
+6684:004000207BFE4A024C0449FC480079FC490449FC490449FC7904480003FE0000
+6685:0100013CF100910091BC95649524F53C952491249124913CF1249100017E0100
+6686:02100110F11097BE9228924893AAF2AE92BA92EA92AE92A8F4AA94A209A2101E
+6687:000007BCF4849484948497BC9400F40097BC9424942497A8F410942804440482
+6688:1FF010101FF010107FFC41043FF801001FF011101FF011101FF00100FFFE0100
+6689:000003FE7A2248204BFE482079FC492449FC492449FC78204BFE002000200020
+668A:000003FE7C20444045FC450445047DFC450445FC450445047DFC440000880104
+668B:00207F20413E7F4448A47F2448284510532861461FF010101FF010101FF01010
+668C:001003D478584A52498C488849047AFA482048204BFE48207850488801040202
+668D:000001FC7D0445FC450445FC44807DFE46224522455245027DFA440200140008
+668E:008800887BFE488848A8482049FC7924492449244BFE48207850488801040202
+668F:004000447BF4484848504FFE4840788049F84B084D0849F87908490801F80108
+6690:0040004079FC48844BFE480049FC790449FC48204BFE48207A204BFE00200020
+6691:1FF010101FF010101FF002001FD00220FFFE03000FF03810CFF008100FF00810
+6692:000001FC790449FC490449FC7820492049FE4A20482079FC4820002003FE0000
+6693:00407F40127E0C88FF4819482A504820A850108C1FF010101FF010101FF01010
+6694:002000207BFE482048204BFE7A8A4A524AFA4A224A227AFA4A220222022A0204
+6695:002000207BFE482049FC492479AC4974492449FC4820787048A8012402220020
+6696:003C07C07A44492848004BFC788048804FFE490049F87A884A50042008D80306
+6697:008000407BFC4800490848904FFE780049F84908490849F87908490801F80108
+6698:000001F8790849F8490849F878004BFE490049FC4A547C944924024400A80110
+6699:00400040F7FC904093F8908097FCF110920895F691109110F1F09110011001F0
+669A:0008003C7BC048044A44492879FC4A2048204BFE482079244924012401FC0004
+669B:0108008878904BFC484049F848407BFE4880490049FC4A207C20482003FE0000
+669C:20201010FEFE00004444242428280EFEF00000001FF010101FF010101FF01010
+669D:000003FE7A02480049FC490449FC790449FC484048204BFE7800488801040202
+669E:0020004079FC490449FC490479FC490449FC48204BFE787048A8012402220020
+669F:002001247924492449FC48007BFE480049FC4904490479FC4888005003FE0000
+66A0:1FF010101FF010101FF00100FFFE10101FF000007FFC40044FE448244FE4400C
+66A1:0090008879044A424C8849FC780448004BDE48424A52794A4A520042014A0084
+66A2:100011F811087DF8550855F87C0057FE550055FC7E5454941124124410A81110
+66A3:0100010079FC4A004DF848007BF848884AA849C84FF8788A49CA06AA00860082
+66A4:0020004079FC490449FC490479FC48404BFE488849247A224DFC002000200020
+66A5:000001FC790449FC490449FC78204BFE4A0248404BFE78884990006000980304
+66A6:00003FFE221022103FBE27182AB432522210200027F8240827F8440847F88408
+66A7:000E03F078444A2449084BFE7A4248404BFE488048FC79444928021004680186
+66A8:7DFC44207D2045FE7C5048525492650E1FF010101FF010101FF00000FFFE0000
+66A9:010001107BDC4A544D544A8879084AF44C0248004BFC78404950024805440080
+66AA:008800887BFE4888488848F878204BFE4A224B324AAA7B764A220222022A0224
+66AB:08047F7808407F40497E7F4849487F4808487F4808881FF010101FF010101FF0
+66AC:08203E2008F87F282228496A3E2A08567E8200001FF010101FF010101FF01010
+66AD:0020004079FC490449FC490449FC7820492448A8492448207BFE482000200020
+66AE:04407FFC04401FF010101FF010101FF00400FFFE10102FE8C8260FE008200FE0
+66AF:008800887BFE4888480049FC790449FC490449FC48207BFE4850008801040202
+66B0:01240124F22494249954914A9292F6109A109250925C9250F25092B0029E0300
+66B1:000003FE7A484A484BFE4A487A204BFE4A404AFC4B447A444A7C020003FE0000
+66B2:002001FC788848504BFE480049FC790449FC490449FC48207BFE482000200020
+66B3:008803DE788849DC48884BDE788848004BFC4804480479FC4804000403FC0004
+66B4:1FF010101FF010101FF008207FFC0820FFFE08203118C9260540092015102208
+66B5:008800887BFE488848F8482079FC492449FC482049FC78204BFE005000880306
+66B6:02100110F11097BE9240920093BEF28A928892A892AE92A8F4A895A8085E1080
+66B7:002003FE782049FC492449FC792449FC48224BFE48087BFE4908008800280010
+66B8:00400040F7FC90A09514920897FCFA0A93F8920893F89040F248944409440080
+66B9:07F8440827F8240807F80240E7FC2C4037F8244027F8244027FC54008FFE0000
+66BA:000003DE7A524A524BDE480079FC492449FC492449FC78204BFE002000200020
+66BB:000001FC790449FC490449FC78204BFE480049FC490479FC4820012402220060
+66BC:49202A3E7F4849485DA86B10492841461FF0101010101FF0101010101FF01010
+66BD:0020012478A84BFE48A849244A227904490449DE4A444D54789E490402040404
+66BE:02080108F7C89010979E949497A4F01497949094911491C8F708911405240242
+66BF:002003FE782049FC480049FC790449FC48884BFE480079FC4904010401FC0104
+66C0:002003FE782049FC48004BFE7A0249FC480049FC490479FC4904008803FE0000
+66C1:10007EFC42107E9042FE7E3040507C92410E5FF070101FF010101FF00000FFFE
+66C2:0088008879FC488848884BFE782049FC492449FC492479FC4800008801040202
+66C3:00100210797C481448FE48144B7C799249544938495449927930490002FE0400
+66C4:008803FE7888480049FC48A848A87BFE48A848A849FC48207BFE482000200020
+66C5:1FF010101FF010101FF004407FFC04403FF809207FFC09203FF801007FFC0100
+66C6:3FFE2000218C2E7022103FBE27182AB43252221027F8240847F8440887F80408
+66C7:1FF010101FF010103FF801007FFE41029D7400003FF80000FFFE10103FF80008
+66C8:002001FC788848504BFE480079FC492449FC492449FC782049FC002003FE0000
+66C9:0020002079FC48204BFE49087B9C490849884E3E48007BFE489000900112020E
+66CA:009007FC78944BFC4A904BFE79124BFA4D0E49F8490879F8490801F800900108
+66CB:000003FE78504BFE4A524BFE780049FC490449FC490479FC482003FE00200020
+66CC:00F87C8844F87C8844F87C8802A801107FFC482410102FE8010001007FFC0000
+66CD:004001FC790449FC490449FC790449FC4820492448A87924482003FE00200020
+66CE:000001FC795449FC482049FC78204BFE4888485049FC78204BFE002000200020
+66CF:1FF010101FF010101FF0210027DE545297D4E458245457D29512F49A25544610
+66D0:0FE008200FE008200FE07C7C44447C7C44447D7C11001FF821005FF00100FFFE
+66D1:1FF010101FF010107FFC44447C7C44447D7C06C01930E64E01800E2000C01F00
+66D2:01080208F7C8945097DE946497D4F214911497D4921493C8F2489454055408A2
+66D3:3FF820083FF820083FF811101FF041047FFC0200FFFE09203FF8C5460BA01110
+66D4:02880288F7E89290941E97E49454F8549754955495549748F548905402940122
+66D5:010001F87A084FFE4A884B247BFE4A004AFC4A004AFC7A004AFC048404FC0884
+66D6:003C03C0F0449224910897FE9442F2A4928A947A908090F8F10892900060079E
+66D7:00500252795448504BFE488878504BFE482049FC48207BFE48A8012406220020
+66D8:000001FC78204BFE4A2249AC782049AC48004BFE482079FC495401540154010C
+66D9:000003FE7A524A524BFE482449FC78284BFE482048FC49847AFC488400FC0084
+66DA:011007FCF11097FC940493F89000F7FC9080914496A89170F6A8912606A00040
+66DB:003C07C0F0409FFE904097FC9554F4E497FC904097FC9040FFFE900005240892
+66DC:000007BCF08494A4929494A49120F21097FC9A2093FC9220F3FC922003FE0200
+66DD:03F80208F3F8920893F8911097FCF1109FFE911092489554F0E09150024800C0
+66DE:000003FE7A484BFE4A484AFC7AA44AFC4AA44AFC4A207BFE4B2A057A050A0906
+66DF:1FF010101FF010107FFC44447C7C44447FFC20002FF820003FFC24484430860E
+66E0:00400020F7FE948895FC948897FEF42095FC952495FC9524F5FC940004880904
+66E1:0FE008200FE008200FE07C7C44447C7C4444FFFE90121FF010101FF01010FFFE
+66E2:004000207BFE4A2249FC48507A8A49FC4A8A48F8488878F84820012402A20040
+66E3:01100110F7FC911091F0920892EAF6AC92A892AA96EA9A06F00092A402520452
+66E4:07FC0040F7FE94429B5C9040975CF12093FC96209BFC9220F3FC922003FE0200
+66E5:0040007C78404BFC4A444BF07A444AFC4AA84AF84AA87AF84A0005FC05540BFE
+66E6:011007FCF04093F8904097FC9000F3D4911297FE93509534F38C908A02960102
+66E7:3FF820083FF820083FF800107F1000FE3E9222923EFE00107F1455127FFE4902
+66E8:02100110F7DE9010945E928297DEF01097DE945097DE9450F7DE9450045204CE
+66E9:1FF010101FF010101FF00100FFFE22883EF804403FF80440FFFE04901C60671C
+66EA:000003FEF252925293FE91089154F25E97B4911E925497DEF0149554055E0010
+66EB:210447C88812F3BC20084B92F83E0380AAAAABAA00001FF010101FF010101FF0
+66EC:0FBE0000F7BC94A496B494A49040F7FE94A097FC94A497FCF51299DC091211CE
+66ED:02480150F7FC940491F0911097FCF55494E497FC904097FCF0409FFE02A40452
+66EE:07BC04A4F7BC900097FE94009590F49E97D4956495D49554F5D495680BC81054
+66EF:03FE02027BFE4A924A544A927AFE4AAA4AFE4B224AFA7AAA4AFA022205FA0004
+66F0:000000007FFC40044004400440047FE440044004400440047FFC400400000000
+66F1:00003FF82008200820083FF82108210821083FF8210801000100010001000100
+66F2:04400440044004407FFC44444444444444447FFC44444444444444447FFC4004
+66F3:0100010001003FF8210821083FF8210821083FF8009000A0004201A20E1AF006
+66F4:0000FFFE010001003FF8210821083FF8210821083FF811000A00060019C0E03E
+66F5:0120011001003FF8210821083FF8210821083FF8009000A0004201A20E1AF006
+66F6:080008001FF8224844480888112822101FF0101010101FF0101010101FF01010
+66F7:00001FF010101FF010101FF0080008001FFC21045284944410041F8400280010
+66F8:01003FF00110FFFE01103FF001003FF80100FFFE00001FF010101FF010101FF0
+66F9:04400440FFFE04403FF824483FF824483FF800001FF010101FF010101FF01010
+66FA:01000100FFFE01003FF821083FF821083FF800001FF010101FF010101FF01010
+66FB:1FF010101FF010101FF00000101010103EFC4210A490149008FE101020104010
+66FC:00001FF010101FF010101FF000007FFC44447FFC00003FF0082007C01830E00E
+66FD:082004403FF821083FF821083FF800001FF0101010101FF0101010101FF01010
+66FE:082004403FF82108292825483FF800001FF0101010101FF0101010101FF01010
+66FF:082008207EFC0820FEFE1450228841069FF0101010101FF0101010101FF01010
+6700:1FF010101FF010101FF00000FFFE22003EF822883E9022502F20F25042880306
+6701:3E7C081048907EFC1428244A468600001FF0101010101FF0101010101FF01010
+6702:1FF010101FF010101FF00000FFFE22203E2022FC3E2422242F24F24442540288
+6703:010002800C6037D8C0063FF8292825483FF800001FF010101FF010101FF01010
+6704:1020102013FE7C2055FC55247DAC5574552455FC7C20547010A8112412221020
+6705:100011FC11047DFC110411FC1080FDFE122211222152290245FAFC0244140008
+6706:444024402840FE7E92AAD72ABA2A924AFE4A00927D1244227C2244427C944408
+6707:1010282044FEBA920092FEFE9292D69292FEFE2800487DFE44087C0844087C08
+6708:07FC040404040404040407FC04040404040407FC040404040804080410142008
+6709:02000200FFFE040004000FF0081018102FF0481088100FF00810081008500820
+670A:0000780049FC4800480078004BFE489048907890489048904892491249129A0E
+670B:00003E7C2244224422443E7C2244224422443E7C22442244224442844A948508
+670C:00103C502450245024883C88250426FA24483C48244824482488448855288A10
+670D:00003EFC2284228422943E88228022FC22A43EA422A822A8229042A84AC48482
+670E:00203C202450245024883D242612241025FC3C04240824882450442054108810
+670F:00203C202524252425243D2425FC242024203D24252425242524452455FC8804
+6710:00803C80250025FC26043C0425E4252425243D2425E425242404440454288810
+6711:00487A484A484A484A487FFE4A484A484A487A484A784A004A004A004BFE9800
+6712:00203C20242025FC25243D242554258C25243D242554258C2504450455148908
+6713:00503C502450255224D43C582450245824D43D52265024502492449255128A0E
+6714:4200227C2444FF440844087C4944494449447F7C094410441084208441148208
+6715:00883C482450240025FC3C202420242027FE3C20245024502488448855048A02
+6716:00403C2025FC250425043DFC2504250425FC3D20252225142508454455828900
+6717:1000087C7E44424442447E7C424442447E44407C484444445A84628441140208
+6718:00407840488849044BFE7802488849444A4278F849884A504820485049889E06
+6719:0000FE7C8244AA44A644C67C8244BA44AA44AA7CAA44AA44FE84828401140208
+671A:02000100FFFE100010001FF800007CFC448444FC7C8444FC44847C8401140208
+671B:1000087CFF44207C2044267C3844209401087FFC010001003FF801000100FFFE
+671C:00403C2027FE240025FC3D0425FC240025FC3C08241027FE2420442054A08840
+671D:0800083EFFA208227F22413E7F2241227F22493E0822FFA208420842088A0904
+671E:08207FFC08200FE008200FE00820FFFE10102FE8C8260FE008200FE008200860
+671F:2200227C7F44224422443E7C224422443E44227C2244FF440484228441148208
+6720:008878884BFE488848A8782049FC4924492479244BFE48204850488849049A02
+6721:000078884A524A224A527A8A4A024BFE488879444A7A48884950482048D89B06
+6722:00007F7C48447E7C42447E7C48447F5400887FFC01003FF801000100FFFE0000
+6723:00203DFC2488245027FE3C0025FC252425FC3D2425FC242025FC442057FE8800
+6724:3E7C22443E7C22443E7C22444A9485083E7C22443E7C22443E7C22444A948508
+6725:00887AAA4ADC4C8849547A2248004BFE4A427C444BFC48444844488449149A08
+6726:00887BFE48884BFE4A0279FC48004BFE484078A24B5448B84B5448924B509820
+6727:011078904BDE48104A5E79824BDE48104BDE7A504BDE4A504BDE4A504A529ACE
+6728:01000100010001007FFC03800540054009201110210841048102010001000100
+6729:0100010001000100FFFE01000100092009101108110821044104810405000200
+672A:0100010001003FF8010001000100FFFE03800540092011102108C10601000100
+672B:010001000100FFFE0100010001007FFC03800540092011102108C10601000100
+672C:01000100010001007FFC0380054005400920111021084FE48102010001000100
+672D:0880088008800880FE80088018801C802A802A804880888408840884087C0800
+672E:0100012001100100FFFE01000920092009200920112011202120411E81000100
+672F:01000120011001107FFC03800540054009201110210841048102010001000100
+6730:010001007FFC0380054009203118C1063FF80010006003801C0420041FFC0000
+6731:0100110011001FF8210041000100FFFE03800540092011102108C10601000100
+6732:1040104010401040FC4010403040384054A054A090A011101110120814041802
+6733:1000102011201120FD2011203120392055205110911012101208140818041002
+6734:0840084008400840FE40085018481C442A442A40484088400840084008400840
+6735:00000FE00820082008201020201EC10001007FFC0380054009203118C1060100
+6736:00003FF008100820083C10041004201441080100FFFE054009203118C1060100
+6737:0800080009FC0844FE44084418441C442A442A44484488840884090409280A10
+6738:1040104010401040FDFC10443044384454445484908410841104110412281410
+6739:1080108010801080FDF0109030903890549054909090109211121112120E1400
+673A:100011F011101110FD10111031103910551055109110111211121212120E1400
+673B:0804080408840884FE84088418841C842A8C2AB448C488840804080408040804
+673C:0880088008800884FE88089018A01CC02A802A804880888408840884087C0800
+673D:100013FE10401040FC801080310039FC54045004900410041004100410281010
+673E:080008000BFE0820FE20082018201C202A202A20482088200820082008A00840
+673F:01000100FFFE010001003FF821082108210821282390054009203118C1060100
+6740:00081810066001800660181861040100FFFE0100112011102108210445040200
+6741:0880084008400820FE20082018201C502A502A50484888880888088409040A02
+6742:020002003FE0042004220822111E61000100FFFE010009201110210845040200
+6743:100013FC11041104FD0410883088388854505450902010201050108811041602
+6744:1008103C11E01020FC20102030203BFE54205420902010201020102010201020
+6745:100011FC10201020FC20102030203BFE54205420902010201020102010A01040
+6746:100011FC10201020FC20102030203BFE54205420902010201020102010201020
+6747:100011FC10001000FC0013FE30403840548054FC900410041004100410281010
+6748:100013FC11041144FD2410A83088388854505450902010201050108811041602
+6749:0804080408080810FE20084418041C082A102A224842880408080810082008C0
+674A:1104112411241124FD2411243124392455245124912411241124122412041404
+674B:100011F011101110FD10111031903950555055109110111211121212120E1400
+674C:1000100013FC1090FC90109030903890549054909090109211121112120E1400
+674D:100011FC10041008FC10102030203BFE54205420902010201020102010A01040
+674E:010001007FFC0380054009203118C1060FE000400080FFFE0100010005000200
+674F:010001007FFC0380054009203118C10600001FF010101010101010101FF01010
+6750:0808080808080808FEFE080818181C182A282A28484888880808080808280810
+6751:1010101010101010FDFE10103010381055105490909010101010101010501020
+6752:1000100011FC1044FC4411443944354452445044908410841104110412281410
+6753:10401040108010FCFD0412043004390454845444904410041004100410281010
+6754:1008103C13C01040FC4010403840347E53C050409040104210421042103E1000
+6755:0820082008200820FE2009FE18201C202A202A50485088500888088809040A02
+6756:1010101010101010FDFE10103010391055105490909010501020105011881606
+6757:02000100FFFE1000100010001FF801000100FFFE0380054009203118C1060100
+6758:00003FFC200420043FFC2000208020803FFE21C022A024902888508640808080
+6759:0848084408440840FE5E09E018401C402A402A40482088220812080A08060802
+675A:10401040108010FEFD00120030FC380854105420904010801102110210FE1000
+675B:100011FC10041004FC0410FC30803880550055FC900410041004100410281010
+675C:1020102010201020FC20102033FE382054205420902010201020102017FE1000
+675D:1020102010201120FD2C113431643BA455245534912811221122110210FE1000
+675E:1000100011F81008FC081008300839F855085500910011001102110210FE1000
+675F:01000100FFFE010001003FF82108210821083FF82388054009203118C1060100
+6760:1000100011FC1020FC2010203020382054205420902010201020102013FE1000
+6761:040004000FF01820644003801D70E10E01007FFC010009201110210845040200
+6762:010001007FFC0380054009203118C10600003FF80100010001000100FFFE0000
+6763:1020102010201020FD241124312439245524552491241124112411FC10041000
+6764:1000100013FE1080FC80108030FC388454845484910411041204120414281810
+6765:0100010001007FFC0100111009100920FFFE0380054009203118C10601000100
+6766:10801080108010F8FD08110831103A1054205020905010501088110812041402
+6767:1020101010101000FDFE10803080388054805480908010801080108010FC1000
+6768:100011F810101020FC40108031FE389254925492911211221222144210941108
+6769:100013F010101010FD101110311039FC54045404900413F41004100410281010
+676A:10201020102010A8FCA410A23122392056245424902810081010102010C01300
+676B:0810081008100890FE900890189E1C902A902A9048908890089008900BFE0800
+676C:100011FC10001000FC0013FE30903890549054909090109211121112120E1400
+676D:10801040104013FCFC00100031F03910551055109110111211121212120E1400
+676E:10201020102013FEFC20102031FC392455245524912411341128102010201020
+676F:1000100013FE1020FC201040384034D051485244944410401040104010401040
+6770:0100010001007FFC03800540092011102108C106010000002488224442448004
+6771:01000100FFFE010001003FF821083FF821083FF82388054009203118C1060100
+6772:1FF0101010101FF0101010101FF0010001007FFC0380054009203118C1060100
+6773:010001007FFC0380054009203118C1061FF0101010101FF0101010101FF01010
+6774:084008400840087CFE84088819201C202A202A50485088500888088809040A02
+6775:10801080108011FCFD2012203020382057FE5420902010201020102010201020
+6776:10201020102013FEFC20112431243924552455FC9024102010221022101E1000
+6777:100011FC11241124FD241124312439FC55045500910011001102110210FE1000
+6778:100010F810881088FC881106320039FC54845484904810501020105010881306
+6779:10A010A010A01124FD24132835303920556051A09120112211221122111E1100
+677A:1000104010201010FC90108030803A8456825282928214881088108810781000
+677B:080009F808480848FE48084818481DF82A882A8848888888088808880BFE0800
+677C:100011F810081050FC20101033FE382254245420902010201020102010A01040
+677D:1008103C11E01020FC2011FC38203420502053FE902010201020102010A01040
+677E:1010109010901088FC88112431243A225440544090881084110413FE11021000
+677F:1008101C11E01100FD0011FC3144394455445528912811101110122812441482
+6780:04400440082010102208C44608201FF001100100FFFE054009203118C1060100
+6781:100013FC10841088FC881090309C388455445544912811281210122814441182
+6782:080008FC08840884FE8408FC18841C842A842AFC488488840884088409140A08
+6783:10401040108010FCFD0412043084384454445414902410441184100410281010
+6784:10801080108010FCFD04110432443844548454A4911411F41014100410281010
+6785:100011FC10881088FC88108830883BFE54885088908810881088110811081208
+6786:1008103C11E01020FC20103C31E038205420503E93E01020102210221022101E
+6787:1010111011101112FD12111431D83910551055109110111211521192110E1000
+6788:208020843E9820E020842684387C21000100FFFE0380054009203118C1060100
+6789:1000100013FE1020FC2010203020382055FC5020902010201020102017FE1000
+678A:10001040119E1112FD1211123112391255125512915A11941110101010101010
+678B:10401020102013FEFC801080308038FC54845484908410841104110412281410
+678C:1010109010901088FD0811043A0435FA50885088908810881108110812281410
+678D:1090109011081108FA04140233FC3880550051F8900810081008100810501020
+678E:1020102010201020FDFC10203020382057FE5420905010501088108811041202
+678F:100011F811081108FD0813FE31083908550853FE910811081108110811281110
+6790:1008101C11E01100FD00110031FE391055105110911011101110121012101410
+6791:100017FE10801080FC8010F8390835085108520893F810101010101017FE1000
+6792:080009FE08080888FE88088819081DFE2A182A284848888809080A0808280810
+6793:0808088808480848FE08088818481C482A082A0E49F888080808080808080808
+6794:1020102010501050FC88114432223820540055FC900410081008101010101020
+6795:10401040104013FCFA4414483040384054A050A090A0112011221222141E1800
+6796:0808083C09E00820FE20082019FE1C202A202A50485088500888088809040A02
+6797:1020102010201020FDFE10203070387054A850A8912412221420102010201020
+6798:10201020102011FEFD221122312239225552554A918A110211021102110A1104
+6799:100011FE11001100FD78114831483948554855689150114211421142123E1400
+679A:1040104010401080FCFE11083288388854885450905010201050108811041202
+679B:1008101C11F01150FD5011503150395055505548914811481144124412421400
+679C:00001FF0111011101FF0111011101FF011100100FFFE054009203118C1060100
+679D:10201020102013FEFC201020302039FC54845488904810501020105011881606
+679E:1110111011101110FD10111031103910551052A8926812281444144418841102
+679F:1000100011FC1000FC00100033FE38205420544090401088110413FE11021000
+67A0:1040104011F81048FC88108A310A3A265420502093FE10201020102010201020
+67A1:1008106813881088FC88108830883BFE54885488908810881108110812081408
+67A2:100013FC12001208FE88125032503A2056205250925012881308120013FE1000
+67A3:01000100FFFE01003FF821082388254809203018C606018000400E0001800040
+67A4:0820082808240824FE2009FE18201C202A202A50485088500888088809040A02
+67A5:200023FE22002220FA20222022FC72246A24A224A24422442484248429283210
+67A6:10401020102011FCFD041104310439FC55045500910011001100120012001400
+67A7:100011FC11041104FD241124312439245524555490501090109011121212140E
+67A8:1080108410841088FC9010A030803BFE54A0549090901088108410A210C01080
+67A9:010001007FFC052009103108C5440440082011102108C206044008201FF00010
+67AA:1040104010A010A0FD101208340639F055105110915011201104110410FC1000
+67AB:200023F822082208FB2822A822A872486A48A2A8A2A8232A240A240A28063002
+67AC:100011F811081108FD4811283928350853FE5108910811081108120812281410
+67AD:010002001FF010101210115010201FFC010401047FF4038805401930E10E0100
+67AE:0810081008100810FE1E081018101C102AFE2A82488288820882088208FE0882
+67AF:1020102010201020FDFE10203020382055FC5504910411041104110411FC1104
+67B0:100011FC10201020FD2410A430A8382057FE5420902010201020102010201020
+67B1:0820082008200840FE48088419FE1C822A002AFC488488840884088408FC0884
+67B2:0400080010103FF800081FF0101010101FF00100FFFE054009203118C1060100
+67B3:1000100011FC1104FD0411043104390455FC5504900010901088110412021402
+67B4:100011F811081108FD0811F83000380057FC5444904410841084110412281410
+67B5:100011F811081108FD0811F830003BFE5480550091F810081008100810501020
+67B6:080008007F7C094411441144257C420001000100FFFE054009203118C1060100
+67B7:220022002200FA1E27D2225272526A52AA52A252225222522452245E29523080
+67B8:10801080108011FCFD04120431E4392455245524912411E41124100410281010
+67B9:1080108011FC1104FA0415F431143914551451F4910411281112110210FE1000
+67BA:10201020102013FEFC201020302039FC547054A890A811241124122210201020
+67BB:1048114811481148FD4813FE3148394855485548917811001100110011FE1000
+67BC:12201220FFFE1220122013E010001FF801000100FFFE054009203118C1060100
+67BD:010001007FFC01001010FFFE101010101FF00100FFFE054009203118C1060100
+67BE:10201020102013FEFC20102031243924552455FC912411241224122414241020
+67BF:10201020102013FEFC20102038A83488508857FE908810881108110812081408
+67C0:10101010101011FEFD121114311039FC55445544912811281110122812441482
+67C1:10201010101011FEFD02120430803888549054A090C0108210821082107E1000
+67C2:1080108010FE1100FA201120312C397457A45124913411281122110210FE1000
+67C3:1020102010501050FC8811243212381055FC5404900810881050102010101010
+67C4:100013FE10201020FC2013FE32223A225652524A928A130212021202120A1204
+67C5:100011FC11041104FD0411FC31003940554455489170114011421242123E1400
+67C6:1040102010201000FDFE10003004388454845448904810481050101013FE1000
+67C7:103811C010401040FC4013FC304038E054E05550915012481444184210401040
+67C8:10201020112410A4FCA8102031FC38205420542093FE10201020102010201020
+67C9:0804081E09E00800FE20081019FE1C042A082A1048208840088009400A3E0800
+67CA:10401040107C1084FD881250302038505488530690601010100810C010201010
+67CB:089008881080309E57E0908010441034110C0100FFFE054009203118C1060100
+67CC:100011FC10041004FDF41004300439F45514551491F411141004100410281010
+67CD:10201020102011FCFD24112431243924552453FE902010501050108811041202
+67CE:1088108810881108FD7E13083508394855285528910811081108110811281110
+67CF:10201020104011FCFD0411043104390455FC5504910411041104110411FC1104
+67D0:08200820FFFE082008200FE0082008200FE00100FFFE054009203118C1060100
+67D1:1088108810881088FDFE108830883888548854F8908810881088108810F81088
+67D2:20801080009C47E0208008841084607C21000100FFFE054009203118C1060100
+67D3:2080108003F04090211009121212640E29000100FFFE054009203118C1060100
+67D4:00001FF0022001407FFC04841888628001000100FFFE054009203118C1060100
+67D5:100011F810081050FC20101033FE386254A454A0912012201420102010A01040
+67D6:100013FC10841084FC84110431143A08540051FC910411041104110411FC1104
+67D7:1010109010901108FD081204340239F855085508910811081108110811F81108
+67D8:1000100013FE1020FC201040304038FC55845284948410841084108410FC1084
+67D9:100011FC11241124FD2411FC31243924552455FC912410201020102010201020
+67DA:1020102010201020FDFC112431243924552455FC912411241124112411FC1104
+67DB:10201020102011FCFD241124312439FC55245524912411FC1124102010201020
+67DC:100011FE11001100FD0011FC310439045504550491FC11001100110011FE1000
+67DD:1008101C11E01100FD00110031FE391055105530911811141112121012101410
+67DE:10801080108010FEFD4011403240387C544050409040107E1040104010401040
+67DF:10201020102011FCFD24112431FC39245524552493FE11041104110411141108
+67E0:20402020202023FEFA022404200070006BFEA020A02020202020202020A02040
+67E1:100011FC10001000FBFE10003020382257B250B490A811281124122414A21040
+67E2:1008103C13E01220FE20122032203BFE5620521092101212120A128A13261212
+67E3:1020102011201120FDFC11203220382057FE5420905010501088108811041202
+67E4:100011F811081108FD0811F831083908550855F8910811081108110817FE1000
+67E5:01000100FFFE0540092011103FF8D01610101FF0101010101FF00000FFFE0000
+67E6:0800080008FC0884FE84088418FC1C842A842A8448FC88840800080009FE0800
+67E7:1008101C11F01150FD5011503150395055505548914811681154127412521400
+67E8:10401040104013FEFC8010A0392035FC53245524912411241134112810201020
+67E9:100013FC12001240FE40127832883A9057105220925012881304120013FE1000
+67EA:1010109010901110FD7E12523392389255125112925213D210621022104A1084
+67EB:10901090109013FCFC94109433FC3A90569053FE90921092111A111412101410
+67EC:01000100FFFE010001003FF82108292825483FF82388054009203118C1060100
+67ED:1050104810481040FBFE1080308038FC55445144912811281210122814441182
+67EE:1020102011241124FD24112431FC382054205524912411241124112411FC1004
+67EF:1000100017FE1008FC0813C832483A485648524893C812481008100810281010
+67F0:010001007FFC054009203118CFE6000000007FFC010011101108210445040200
+67F1:10401020100013FEFC2010203020382055FC5420902010201020102013FE1000
+67F2:1000104010201028FC08108830903A9456A252A294C210881188128814781000
+67F3:10001080131E1252FE52125232523A52565252D2935A12541090109011101210
+67F4:0880088828902EA028C028842E84F07C01000100FFFE054009203118C1060100
+67F5:100011FC11541154FD54115431543BFE55545554915411541154114411141108
+67F6:1000100013FE1252FE52125232523A525652528E92821302120213FE12021000
+67F7:100011FC11041104FD04110431FC3850545054509050109210921112120E1400
+67F8:100011FE10101010FC201020306838A455225222902010201020100013FE1000
+67F9:10201020102E11F0FD201120312039FE5422546290A2112A1624102010201020
+67FA:100011FC11041104FD0411FC3040384055FC5444904410841084110412281410
+67FB:010001007FFC054009203118C1061FF010101FF010101FF010101010FFFE0000
+67FC:10401020102013FEFA0214043000389054905090908811081108110412041402
+67FD:100011FC10841088FC501020305038885726502091FC10201020102013FE1000
+67FE:1000100013FE1020FC20102031203920553C5520912011201120112017FE1000
+67FF:10401020100013FEFC20102031FC392455245524912411241134112810201020
+6800:101C11E011001100FDFE11003100397C554455449154114811421242123E1400
+6801:21002100211E21D2FA522252225275526892A092A11A21142210241028102010
+6802:100010FC108410A4FC94108430843BFE550455449124110411FE100410281010
+6803:1008101C11E01100FD0011FE31203920553C5524912411241124124412541488
+6804:22081108111000207FFE4002810401007FFC03800540092011102108C1060100
+6805:100011DC11541154FD54115431543BFE5554515491541154115412D41224144C
+6806:010001007FFC01003FF8210821083FF80280044008203318C0C6060001800040
+6807:100011FC10001000FC0013FE3020382055285524922412221422102010A01040
+6808:105010481040105CFDE01040305E39E054445048903010221052108A13061002
+6809:1088108813FE1088FC88100033FE3842544254429042104A1044104010401040
+680A:1090108810881080FBFE10A030A038A454A451289128113212221262149E1800
+680B:10401040104017FEF880112031203A2057FC5020912811241222142210A01040
+680C:10201020103E1020FC2011FC31043904550455FC910411001100120012001400
+680D:1020102011201120FDFC112032203820542055FC902010201020102013FE1000
+680E:1008103C13C01200FE20122032203BFE54205420912811241222142210A01040
+680F:1000110810881090FC0013FE30003800540055FC900010001000100013FE1000
+6810:10401020101011E0FC22103433B838B054A854A8912811241224142210A01040
+6811:2004200427842084F8BE2484228472A46914A114A28422842484280420142008
+6812:1080108011FC1104FE0411E43124392455E45524912411E41104100410281010
+6813:1020102010501088FD04120231FC38205420502091FC10201020102013FE1000
+6814:080008007F7C08243E2408447F54088809000100FFFE054009203118C1060100
+6815:100011FE11201120FD2011FC310439045504550491FC11201120112011FE1000
+6816:100017FE10901090FC9013FC32943A9456945294929C13041204120413FC1204
+6817:00007FFC044004403FF8244824483FF801000100FFFE054009203118C1060100
+6818:10201020107C1084FD481030302038485590543E904211A41018101010601180
+6819:2080208020FC2108FA902060219876266820A1FCA020222023FE202020202020
+681A:1088104810501000FDFC10203020382055FE5420905010501088108811041202
+681B:1040104011FC1044FC84108431283A10550853DE914A114A114A1252135A14A4
+681C:1020102013FE1020FC2011FC312439245524552C907010A81124162210201020
+681D:1008103C11E01020FC2013FE30203820542055FC910411041104110411FC1104
+681E:00007EFC08200820FEFE08201020202041200100FFFE054009203118C1060100
+681F:1104108410881000FDFE108830883888548853FE908810881108110812081408
+6820:083813C03040504097FC1040104013F800000100FFFE054009203118C1060100
+6821:10401020102011FEFC00108831043A0254885088905010501020105010881306
+6822:100013FE10201020FC4011FC31043904550455FC910411041104110411FC1104
+6823:10801088109C1170FD1013103510391055FE55109110111011101110117C1100
+6824:2020242022202220F83221B220B472A86AA8A4A8A52429242A22202020A02040
+6825:0100410021FC0A441448E0A02110260801000100FFFE054009203118C1060100
+6826:1082109210921092FC92109232DA3AB654925092909210921092111211021202
+6827:1020102011FC1124FD2411FC3124392455FC542090241018103210CA13061002
+6828:101010101210113EFD2210443810349050905310912811281128114410441082
+6829:100013DE10421042FE52114A314A384254C6514A9252104210421042114A1084
+682A:10201120112011FCFD20122030203BFE547054A890A811241124122210201020
+682B:10401040104017FEF8801080317C39085710551091FE11101110111011501120
+682C:1040104010F81108FA1011FC31243924552451FC910011001102110210FE1000
+682D:100013FE10201020FC4011FC3154395455545554915411541154114411141108
+682E:100013FE11081108FD0811F83108390855F855089108111E17E8100810081008
+682F:1040104017FE1080FD0013FC3504390455FC5504910411FC1104110411141108
+6830:10A810A410A41120FD2E13F03520392455245524912811101132114A11861102
+6831:1088108810881088FDFE108830883888548853FE900010881084110412021402
+6832:1040104411F41048FC5013FE3040388055FE5240948010FC1004100410281010
+6833:10401040104411F4FC48105033FE384054805584929814E010821082107E1000
+6834:1080108010FE1100FA0010FC308438A45494508493FE10841084110411141208
+6835:1002100217E2110AF90A11EA312A3A2A572A52AA944A104A10821102120A1404
+6836:100013FC12041244FE44124433FC3A44564452A4929413141204120413FC1204
+6837:1104108410881000FBFE1020302039FC5420502093FE10201020102010201020
+6838:10201010101013FEFC201042308439F85410542290C413081010102810C41302
+6839:100013F812081208FBF8120832083BF856445248923012201210128813061200
+683A:11001104113811C0FD02110230FE380055FC5504910411FC1104110411FC1104
+683B:1028102410241020FBFE102030203BA0552051109110111011CA170A12061002
+683C:1080108010F81108FB1014A0304038A05518520695F811081108110811F81108
+683D:084008487F4408440840FFFE004008440844FF4418282C2A2A12492A88460882
+683E:02000100FFFE0440145014482444444400000100FFFE054009203118C1060100
+683F:1090109410921112FD10137E3110391055105528912811281128114411441182
+6840:101010103EFC4210A490149008FE101020104110FFFE054009203118C1060100
+6841:10801080113C1200FC801080317E3B0855085508910811081108110811281110
+6842:1020102011FC1020FC20102033FE38005420542091FC10201020102013FE1000
+6843:1090109010901292FD941098309039985694549290901090111211121212140E
+6844:10201020112410A4FCA8102033FE3890549054909090109211121112120E1400
+6845:1040104010FC1104FE0811FE3100397C554451449154114811421242123E1400
+6846:100011FE11001100FDFE11103110397C55105510911011FE1100110011FE1000
+6847:10001000FE7C224442443444087C3400C3000100FFFE054009203118C1060100
+6848:01007FFC40040400FFFE08201E4003C03C380100FFFE054009203118C1060100
+6849:10401020102013FEFE02144430403BFE54885488910810D01020105010881304
+684A:0100111009203FF8020002007FFC082011102108DFF6030005C0193061080100
+684B:1020102013FE1020FDFC102431FC392055FE5422902A10541050108811041202
+684C:0100010001FC01001FF810081FF810081FF80100FFFE054009203118C1060100
+684D:1020102013FE1050FC88110432FA380057FE5440908011FC1004100410281010
+684E:100013FE10201040FC88110433FE38225420542093FE10201020102017FE1000
+684F:1000101E13F21092FC941094309838945492549290F2171A1214101010101010
+6850:100013FC12041204FEF4120432043AF456945294929412F41204120412141208
+6851:1FE0064001800E4000007CF82448183066CC01007FFC054009203118C1060100
+6852:010001007FFC010009200820FFFE082009200100FFFE054009203118C1060100
+6853:100013FE10001000FDFC1104310439FC5504550491FC11041000100013FE1000
+6854:10201020102013FEFC20102031FC3800540055FC910411041104110411FC1104
+6855:10001040119C1104FD041104310439DC5504550491041104110411FC11041000
+6856:1020102010401080FDFC11543154395455545554915411541154115413FE1000
+6857:100013F810881090FCBC110439143648504057FE904010E01150124814461040
+6858:1040108011F81108FD08110831F839005500550091FC11041104110411FC1104
+6859:1040104010901108FBFC10243120392055FC5220902017FE1020102010201020
+685A:1124112412481124FD241000308038FC55045184924814281010102010C01300
+685B:08200820083E0820FE2009FE18001C002BFE2A20482888240822082008200820
+685C:1040102412241108FD0810103040384057FE5488910811901060105011881604
+685D:2208220822082388FABE228824A874A86AA8A128A13E21082208220824082808
+685E:21002100211E21D2FA542254225875546892A092A112211A2214241028102010
+685F:10501048107E13C0FC40107C3BC03440507E53C090441028103210CA17061002
+6860:100011FE10481048FC4810483248394A554A554C904810481048104813FE1000
+6861:1080108010BC13C0FC50102430D43B0C540053FE9090109011121112120E1400
+6862:10201020103E1020FC2011FC3104392455245524912411241050104810841104
+6863:1020112410A410A4FCA8102033FC38045404500491FC10041004100413FC1004
+6864:1020112411241124FDFC100031FC3804540455FC910011001102110210FE1000
+6865:2010207823C02040F84027FE20A071106A08A516A11021102110221022102410
+6866:1090109411141118FB1015323152390E5520502093FE10201020102010201020
+6867:1020102010501088FD04120238F83400500053FE902010401088110413FE1102
+6868:0840484028FC09041A882850486089800100FFFE0380054009203118C1060100
+6869:10201010101011FEFD00111031103910557C5510911011101110121012FE1400
+686A:100013FC10041004FDFC100430043BFC5408500897FE11081088108810281010
+686B:2010221021102110F4542252225270906810A114A604220822082210222020C0
+686C:1020082040A824A409227228103010C007000100FFFE054009203118C1060100
+686D:100013FC12001200FEF8120032003BFC56A052A492A812901290148814A418C2
+686E:100013FE10101020FC6810A433223820540055FC910411041104110411FC1104
+686F:100011FC11041104FD0411FC3000380057FE5420902011FC1020102013FE1000
+6870:101C13E012201220FBFE122032903B0A560651FA910811081108110811F81108
+6871:100013FC10001124FA48149032483924540053FC904010401040104017FE1000
+6872:1020102013FE1020FC2013FE3A02340451F85010902013FE1020102010A01040
+6873:10401080110413FEFC22102033FE385054885124922211FC1020102010201020
+6874:1008103C11C01004FD4410A8300039F85410502093FE10201020102010A01040
+6875:2008203C23C02044FA242128210070406BFEA088A10823902060205021882604
+6876:200027F8201021A0F84027FC244474446FFCA444A44427FC2444244424542408
+6877:1080108010F81108FA1015FC3124392455FC5124912411FC1124122412141408
+6878:11841068103010C8FB04104033FE38A0552053FC952411241134112810201020
+6879:1040102011FC1104FD0411FC3104390455FC5520912211141108114411821100
+687A:100013FE10501050FC5013DE32523A525652525293DE10501090109011101210
+687B:210021F823082490F8602198264670406BF8A040A3F8204027FC204020402040
+687C:010001007FFC092011102108C284044009203118CB2605C01930610805000200
+687D:010001007FFC05401930E10E082009201550238801003FF801000100FFFE0000
+687E:100011FC10441044FBFE1044304439FC5480508091FC12841484108410FC1084
+687F:100011FC110411FCFD0411FC3000380055FC5420902013FE1020102010201020
+6880:1020102013FE1020FC2011FC3124392455FC5420907010A81124122210201020
+6881:000023F01090829452922492E110225025200100FFFE054009203118C1060100
+6882:1028102410241020FDFE1020312038B254B4546890A811241222102010A01040
+6883:2000200C27702110F9102210327C6F106110A510A510227C2200250028FE3000
+6884:100013FE10501050FDFC115431543954558C5504910411FC1104110411FC1104
+6885:1100110011FC1200FDF811083948352857FE51089248122813FC100810501020
+6886:2100211E21122FD2F114211427D871146912AFD2A112211A2214221024102810
+6887:100013FE10201020FDFC102030203BFE5488508893FE10881088110811081208
+6888:1040102013FE1000FDF81108310839F8540053FC900810301020102010A01040
+6889:1048114811481148FD4811C8307E384857C851489148114811481148125C1440
+688A:080C08F07E8008800EFE78880888290812080100FFFE054009203118C1060100
+688B:100011F811081108FDF8100033FC3A04560453FC9204120413FC120412141208
+688C:1020102010501088FD0412FA3020382057FE5420912811241222142210A01040
+688D:1020104011FC1104FD0411FC3104390455FC54409040107E17C010421042103E
+688E:1020104011FC1104FDFC110431FC38005500550C91F011001102110210FE1000
+688F:10201120112011FCFD20122030203BFE5400540091FC11041104110411FC1104
+6890:12201224122813B0FE20122232A23B1E5440504093FC10401040104017FE1000
+6891:2010289025102212F5522954215871906B10A528A9282128214821442A842502
+6892:1020102010501088FD44122230F838085410542091FC11041104110411FC1104
+6893:1040102011FC1000FC88105033FE38205420542091FC10201020102010201020
+6894:1008101C11E01100FDFE1100317C3954555455549154117C114012421242143E
+6895:100013FC10441144FD441284389435085240502090A41282128A128A14781000
+6896:080008FC08840884FEFC088418841CFC2A842A8448FC88000848084408820902
+6897:100013FE10201020FDFC1124312439FC5524552491FC112010A0104010B0130E
+6898:100011FC11041104FDFC1104310439FC5504550491FC1050105010921112120E
+6899:1020102011FC1124FD2411FC3020382057FE5222922213FE1222102010201020
+689A:1080108011F81208FC1013FC32443A44564453FC90A010A011221122121E1400
+689B:20002FDE22522252FA5427D432586A546252AFD2A252225A2254245025502890
+689C:10201020102013FEFC20102039243524512452AA902010501050108811041202
+689D:0840084010FC10883550542094D81726142015FC142014A81524122210A01040
+689E:100011F810081008FDF811003104390454FC5440902010A4128A128A14781000
+689F:04001FF010101FF010101FF010001FFC10001FFC01043FF405481930E10E0100
+68A0:100011F811081108FD08110831F83800540053FC920412041204120413FC1204
+68A1:1040102013FE1202FC0411F83800340053FE50909090109011121112120E1400
+68A2:1020112410A410A8FC2011FC3104390455FC5104910411FC1104110411141108
+68A3:1020112411241124FDFC10203050388855445222902011F81008101010101020
+68A4:1020112411241124FDFC100030883888550452FA904810481088108811281210
+68A5:020001007FFE48229214244808201FF001100100FFFE054009203118C1060100
+68A6:082008207EFC08201C702AA8C826040007F0081014202240018002000C007000
+68A7:100013FE10401040FDFC108430843BFE5400500091FC11041104110411FC1104
+68A8:03083C0804487F480C4816482508442805100100FFFE054009203118C1060100
+68A9:100011FC11241124FDFC1124312439FC5420542091FC10201020102013FE1000
+68AA:100013FC10001000FDF811083108390855F85400910810881090100017FE1000
+68AB:100011FC100410FCFC0411FC380037FE520251F8908810881050102010D81306
+68AC:1020102011FC1124FDFC112431FC380057FE5480910011FC1004100410281010
+68AD:1040104010881104FBFE100230883944564250F8918812501020105011881606
+68AE:100011FC11041104FDFC1100310039FE5502557A914A114A127A120214141008
+68AF:11081088109011FCFC24102431FC3920552051FE906210A2112A122414201020
+68B0:1010101410121010FBFE10103150395457F4515491541148124A125A14261042
+68B1:100013FE12221222FE2213FE32223A62567252AA932212221222120213FE1202
+68B2:1010109010881108FA0415FA31083908550851F890901090109011121212140E
+68B3:1040102013FC1040FC90110833FC38045550515091501150125012521452180E
+68B4:1004100E13B81088FC881128312E3BA854A852A892A8113E11001280147E1800
+68B5:082008207EFC08201C702AA8C82600000FE0082008200A20092011222022401E
+68B6:100013FC12041204FBFC120032183AE0563852E0923C13E012221422141E1800
+68B7:100010FC1E0410487E28421042287EC401000100FFFE054009203118C1060100
+68B8:208421C427042114F914211427D471146B14A394A55425042904210421142108
+68B9:1008101C11E01100FD0011FE311039105510511097FE10001090110812041402
+68BA:082008207EFC08201C702AA8C8260000FFFE0200024002200210020802000200
+68BB:22502250225025FCF4542C5435FC75506D50A5FEA4522452245A249424902510
+68BC:1020102013FE1020FDFC104033FE3848548854FE910811481228140810281010
+68BD:10201020102013FEFC201020302039FC5440542090A41282128A128A14781000
+68BE:10201020102013FEFC20112430A438A855FE547090A810A81124122214201020
+68BF:101012101110117EFC2010283748397E5508550891FE110811081288147E1000
+68C0:1040104010A010A0FD10120835F6380054885048924811501110102017FE1000
+68C1:1104108410881010FDFC11043104390455FC54509050109010921112120E1400
+68C2:100013F810081008FDF8100830083BF8544051489148125010A0111012081406
+68C3:0C8070FC1124FD24122438445484912810100100FFFE054009203118C1060100
+68C4:020001007FFC10103FF801081110FFFE11101FF001007FFC05401930E10E0100
+68C5:207823C0204027FCF84023F8204877FE6848A3F8A0E0215022482C4620402040
+68C6:1020102010501088FD0412FA300039FC5554555491FC1154115411541104110C
+68C7:1090109011081148FA44149231083BFC5444502090A41282128A128A14781000
+68C8:1020102013FE1020FDFC102033FE380055FC550491FC110411FC110411141108
+68C9:1020104011FC1104FDFC110431FC3820542053FE92221222122A122410201020
+68CA:08207FFC08200FE008200FE00820FFFE11102108DFF6030005C0193061080100
+68CB:1108110813FC1108FD0811F83108390855F85108910817FE1000109011081204
+68CC:2008203C23C02044FA242128210070206BFEA070A0A820A82124222224202020
+68CD:100011FC11041104FDFC1104310439FC5400551291D41118111011521192110E
+68CE:100013FE12021252FC8811043020382057FE5420907010A81124162210201020
+68CF:100011FC110411FCFD0411FC300039FE540853FE900811081088100810281010
+68D0:044004407C7C04403C7804407C7C044005400100FFFE054009203118C1060100
+68D1:109010901090179EF890109030903B9C549050909090179E1090109010901090
+68D2:1020102013FE1020FDFC104033FE38885524522290F8102013FE102010201020
+68D3:1080104011FC1000FD08108830903BFE5400540091FC11041104110411FC1104
+68D4:101C13E0122013FEFE201292330A3A0655FC5104910411FC1104110411FC1104
+68D5:1040102013FE1202FC0011FC3000380057FE5420912811241222142210A01040
+68D6:100010FC108010F8FC8010F830803BFE55405524912811101108114411821100
+68D7:01007FFC01003FF823880D60301001007FFC01003FF82108238805601918E106
+68D8:10201020FDFC102010207CF854A854A854A85CB81020387054A8952610201020
+68D9:1040102013FC1204FE0413FC32003A28562453FE922012501250148815041A02
+68DA:100013DE12521252FE5213DE32523A52565253DE9252125212521252155218A6
+68DB:1040102013FE1080FD0413FE300239FC550455FC910411FC1104110411141108
+68DC:21082088200827D4FA142222220073C86A44A244A24022502248244425442880
+68DD:100011FC11041124FD2411FC3124392455745554915411741104110411FC1104
+68DE:100013FE1202121AFEE2122232223BFE5622527292AA13261222122213FE1202
+68DF:1020102013FE1020FDFC112431FC392455FC5420907010A81124162210201020
+68E0:0100111009207FFE40029FF4101010101FF00100FFFE054009203118C1060100
+68E1:100013FE1202128AFE5213FE32223A2256AA52AA92AA12FA12021202120A1204
+68E2:100013FE1202128AFE5213FE32423A2257FE52829282128212FA1202120A1204
+68E3:1020102011FC1024FC2413FE3824342451FC5222917410A81124122210A01040
+68E4:10881088108813FEFC88108837FE380055FC5104910411FC1104110411FC1104
+68E5:2088248822882108F93E22882498701C68ACA2AAA14821082288228824882808
+68E6:1080108011F01210FC2013FC3044384457FE5444904413FC1044104011401080
+68E7:10481044105E11E0FC281012306A39965448545E91E0102410281012106A1186
+68E8:102008203E3E224422843E282210402881440100FFFE054009203118C1060100
+68E9:1050125212521252FBDE120232023BFE5602520293DE12521252125214521802
+68EA:1020112211221224FC5010883304382254205524912412281050108811041602
+68EB:10141012101017FEF810101033D23A525652525493D4100810EA171A12261042
+68EC:1020112410A81020FDFC104033FE3888550452FA9488108810A810921082107E
+68ED:2080204027FE2120F920223C224476646A94A348A24822302220225022882306
+68EE:010001007FFC054009203118C106082008207EFC08301C682AA4C92208200820
+68EF:1020102010501088FD44122231F838085450542090A41282128A128A14781000
+68F0:2010207823C02040F84027FC224872486FFEA248A24827FC2040204027FC2000
+68F1:1020102011FC1020FC2013FE30883944564254F8918812501020105011881606
+68F2:1020102013FE1020FDFC102433FE382455FC504093FE108411C8103010CC1302
+68F3:100013DE1042114AFC84114A3A523420500053DE905211521094114812541422
+68F4:200027BE24A224A2FCAA27A424A074BE6CAAA7AAA4AA24AA24A424A424AA29B0
+68F5:100011FC11241124FDFC1124312439FC542053FE907010A81124122210201020
+68F6:10401040104017FCF840124832483A48555450E0915011501248144418421040
+68F7:20002FC024BC24A4F4A427A424A474A86FA8A4A8A49025D02EA820A820C42082
+68F8:00007F00227C3E0422283E1023A8FE4402000100FFFE054009203118C1060100
+68F9:10201020103E1020FDFC110431FC390455FC5524902013FE1020102010201020
+68FA:1040102013FE1202FC0411F83108390855F85500910011FC1104110411FC1104
+68FB:0820FFFE08200460081037E8C22404A018400100FFFE054009203118C1060100
+68FC:082008207EFC08201C702AA8C8240440082010102FE8C4260420082010A06040
+68FD:082008207EFC08201C702AA8C92402800E603118C1061FE00020004000800100
+68FE:082008207EFC08201C702AA8C82600007FFE40028FE40820082010222022C01E
+68FF:10001040139C1204FE04139C32043A0457FC549090901090109011121212140E
+6900:1040102013FE1202FD04110031DE3A5256525352949A1094111011121212140E
+6901:1040102013FE1000FDFC110431FC380055FC5408901013FE1020102010A01040
+6902:100011F810081008FDF8100830083BFE54205222917410A81124122210A01040
+6903:10401040107C1040FBFC124432703BC05644523C920012F0149014921912120E
+6904:1080104013FC1000FD08109037FE3840544057FE908811081090106011981604
+6905:2040204023FC20A0F910220827FE70086BC8A248A248224823C8200820282010
+6906:100011FC11241124FD74112431FC390455745154915411741104120412141408
+6907:100011F811081108FDF8110831F8390855F85108910817FE1000109011081204
+6908:1100110011FC1204FC84149432A4388457FC508491C412A41494108410A81010
+6909:02000100FFFE10103EFC4210149018FEE0100110FFFE054009203118C1060100
+690A:1040102013FE1000FC88108831543A225400502093FE10201020102010201020
+690B:1040102013FE1000FC0011FC3104390455FC5420912811241222142210A01040
+690C:10401020102013FEFA02149431083A04540051FC902010201020102017FE1000
+690D:1020102013FE1020FC2011FC310439FC550455FC910411FC1104110417FE1000
+690E:10A01090109011FEFD10131035FE3910551055FE91101110111011FE11001100
+690F:100017FE10901090FC90139C32043A045604539C909010901090109017FE1000
+6910:100013FC12041204FBFC122032203BFE5620522092FC12841284148414FC1884
+6911:1040108011FC1124FD2411FC3124394455FC5490911013FE1010101010101010
+6912:2100210021DC2114F914211427D470146914A114A58825482948211425142222
+6913:100013FE10401080FD44122430683AB0553052A8906810A41122122010A01040
+6914:1092109211241248FD2410923092380055FE5522912211FE1122112211FE1102
+6915:2008208822882288FABE24482018779C6AACA2AAA2C822882288248824882988
+6916:1040102011FC1104FD0411FC3120391055FE55209120113C1124124412541488
+6917:1040102013FE1202FC04100033FE382054205520913C112012A01260143E1800
+6918:082008207EFC08201C702AA8C824020001007FF8006001800E003000480087FE
+6919:11F81108110811F8FD08110831F8380057FC5204920413FC1204120413FC1204
+691A:100013DE12521252FBDE125232523BDE560252029202120212021202120A1204
+691B:1108110817FE1108FD08100038903492511453189510113211521112110E1100
+691C:1020102010501088FD0412FA3020382055FC5524912411FC1050108811041202
+691D:100011FC7D0411241124FC5010902912460E8100FFFE054009203118C1060100
+691E:080C08F07E8018802CFE2A884888888809080100FFFE054009203118C1060100
+691F:1020102011FC1020FC2013FE3002389454505510909013FE1028104410821302
+6920:100CFEF0208048807EFE08880E88F9084A080100FFFE054009203118C1060100
+6921:1002100217E2110AFD0A124A33EA388A548A53EA908A108A10E21702120A1004
+6922:100013FE12021202FBFE122232223AFA56225232922A13FE1202120213FE1202
+6923:10901090109013FCFE94129432943BFC56945294929417FE1000109011081204
+6924:100013FE12521252FE5213FE3020384054FC5104928810501020104011801600
+6925:11001100110013DEFA9214923092389257F2509290921152115E122014201800
+6926:1020112410A81020FDFC104033FE38885544524295F810481088108811281210
+6927:1020102010501088FD0412FA30003BDE56525252925213DA1254101010101010
+6928:1040102013FE1200FE44124432843ABE578452A4929412941284128414941088
+6929:1040102013FE1220FEFC122432243BFE5624522492FC12201250145014881906
+692A:10841048100011FEFC48104830483A48554A554C904810481048104813FE1000
+692B:11041088105011FCFD24112431FC3924552455FC9020102013FE102010201020
+692C:1040102013FE1202FC0411F83108390855F85508910811F81108110817FE1000
+692D:201027902490257EFD202620257C74A46CA4A4BCA6A4253C242424242424242C
+692E:10401048108411FEFC2013FE3088392456425188901010621184101810601380
+692F:1020112411241124FDFC100033FE3820544055FC91541154115411541154110C
+6930:20002FDE24922492F4942794249874946F92A492A49225DA2E94209020902090
+6931:1100110011FE1200FDFC110431FC390455FC548090FC11081290106011981606
+6932:1040104011FC1084FBFE100031FC390455FC502093FE1020122013FE10201020
+6933:100011FC11241124FDFC1124312439FC540053FE912011221114114811841102
+6934:102011DC11141114FD1411D43126390055DC5514911411D41708110811141122
+6935:100013DE12421242FE4213DE32003A3E57D25212921413D41208121412241242
+6936:1000108812521222FE52128A32023BFE54885144927A10881150102010D81706
+6937:20142012201027FEFC10241025D074126C12A5D4A554254825DA242A28463082
+6938:22102110211027BEFA28224823AA72AE6ABAA2EAA2AE22A824AA24A229A2301E
+6939:1110111017FC1110FDF0111039F03510511057FE920012901308120013FC1000
+693A:2100217C21442244FA44267C2A1072106AFEA238A25422542294231222102210
+693B:100013FE120012FCFE8412FC32843AFC562053FE924812C812301248128413FE
+693C:1080108E11201210FCC010AE31043B1455245164912411241124110411141108
+693D:210021F8220823F0F81027FE208071446E68A0B0A128266820A4212226A02040
+693E:11081088109017FEF80013C432543A5457D45254925413D412541244125412C8
+693F:1020102013FE1020FDFC104033FE3888550452FA9088108810F81088108810F8
+6940:1004101E13E01020FDFC1124312439FC542053FE9222122A12FA1202120A1204
+6941:1040102013FE1202FC8010F831083A9054605198960611F81108110811F81108
+6942:1020102013FE1070FCA81124322239FC550451FC910411FC1104100013FE1000
+6943:100013FC12041204FBFC120033FC3A40568853FC9224122015FC1420182013FE
+6944:1040102013FE1202FE0213FE32003A0057FE5352955215FE1552155219521106
+6945:100013FE100011FCFD04110431FC380057FE5222922213FE1222122213FE1202
+6946:100013FE10501050FBFE125232523BFE5400504097FE10881190106010D81304
+6947:100011FC11041104FDE4112431243BFE560252FA928A128A12FA1202120A1204
+6948:100013FE10221120FD3C11203AFE340051FC510491FC110411FC110411141108
+6949:1088108813FE1088FCA8102033FE3840548054FC918412841084108410FC1084
+694A:100011F8110811F8FD0811F830003BFE550051FC925414941124124410A81110
+694B:1082108217F21082FC8A13EA32AA3AAA57EA508A91CA12AA14A21082108A1084
+694C:1040102013FC1000FD08109033FE3A10562052C89210122412C8141014601980
+694D:010001007FFC0380054009203118C10600007BBC4AA44AA44AA44AA47BBC4AA4
+694E:100013FE12221020FDFE102031FC392455FC552491FC102013FE102010201020
+694F:1020102013FE1050FC88132631FC3820542053FE9000102011FC1020102013FE
+6950:11FC1124112411FCFD24112431FC385054885104928A10881088108811081208
+6951:101013D410581252FD8C108831043AFA5420502093FE10201050108811041202
+6952:100011FC11241124FDFC1124312439FC54005440902412A2128A148810781000
+6953:200027FC24042434FDC4244425F475546D54A5F4A444245425F4249428063002
+6954:2100213C27D42114FB94211427D47124694CA040A7FE204020A0211022082C06
+6955:1040104013FE1080FDFC122035FE380055FC550491FC110411FC110411141108
+6956:100013DE12521252FE5213D232523A52565253D2921A1294125012B013101010
+6957:2020202020FC2E24FBFE222424FC74206EFCA220A2202BFE2420262029FE3000
+6958:00207E20247E1884FF2829104A2899440100FFFE0380054009203118C1060100
+6959:2008278820882288F93E210827D8715C6B2CA32AA54825082908210825082208
+695A:082008207EFC08201C702AA8C82400007FFC0104110011F81100290047FE8000
+695B:1088108813FE1088FCA8102033FE38205420542091FC11041104110411FC1104
+695C:2100211E211227D2F912211E211277D26C52A45EA45227D224522022202A2044
+695D:1020102013FE1020FDFC112431AC3974552455FC9020107010A8112412221020
+695E:100013FC12941294FE9413FC3080384057FE548090F810881108110812281410
+695F:1040102013FE1000FDFC110439FC340053FE520291FC10201020102010A01040
+6960:1020102013FE1020FC2013FE328A3A5256FA5222922212FA12221222122A1204
+6961:11C010A011101208FDF6100033CA3A4A565453D49268125413D4124A124A12C0
+6962:11081088109017FEF890109033FC3A945694530C920413FC1204120413FC1204
+6963:100013FC12241224FBFC120032FC3A84568452FC928412FC1284128414FC1884
+6964:1080108010FC1154FAD410B4312C3A4454945108904010A412AA128A14781000
+6965:103C17C012441128FC0013FC3080388057FE550091F812881250142018D81306
+6966:1040102013FE1202FC0411FC300039FC550455FC910411FC1104100013FE1000
+6967:2110211027FC2110F950204023F872486A48A248A7FE204020A0211022082406
+6968:10201020103E1020FC2011FC310439FC550455FC910411FC1000108811041202
+6969:210021FE21102210FAFE2292269272FE6A92A292A2FE22902250222022582286
+696A:10481148114813FEFD4811483178390055FE542093FE107010A8112416221020
+696B:100011F811081108FDF8100037FE390855F8550891F81108113E17C810081008
+696C:100011FC110411FCFD0411FC388035FE522251229152110211FA100210141008
+696D:044024481450FFFE082004407FFC01003FF80100FFFE054009203118C1060100
+696E:1020102211FA1024FC2813FE3020384054FC5184928410FC1084108410FC1084
+696F:201C23E022202220FBFE222022FC72846A84A2FCA28422FC2484248428FC2084
+6970:1020102010A0112CFD24112431AC3924552455FC912410501050108811041202
+6971:2040204027FC2040FBF8208027FC71106A08A5F6A04023F8204020A021102608
+6972:2014201227FE2410FC1027F0249274926FD2A554A5542488254A2A1A28263042
+6973:1088108813FE1088FC8810F83088388854F8542093FE107010A8112412221020
+6974:1040102011FC1000FC88105033FE3A22542455FC912411241134112810201020
+6975:100013FC10081010FC2013AE32A23AAA56A452A493AA103210A0104017FE1000
+6976:410021FC0A441048E0A0211026081FF410101FF001007FFC05401930E10E0100
+6977:1110111211D41118FD521192312E384055FC5104910411FC1104110411FC1104
+6978:208821C827082108F92A212A27AC71486B08A388A55425142914212421242142
+6979:100013F811081110FD1C12E432A43A5454A8510093FC12941294129417FE1000
+697A:100010FC10481030FDFE1052389435105230502091FE107010A8112412221020
+697B:1020104011FC1104FDFC110439FC340053FE5020902011FC1020102013FE1000
+697C:2020212420A82020FBFE20A8212472026840A7FEA08821082190206021982604
+697D:0100420427C81450044017D02448C44407C00100FFFE054009203118C1060100
+697E:1040108011FC1104FDFC110431FC3820543253B490A811281124122414A21040
+697F:101C11E010201020FBFE10A831243A2255FC5104910411FC1104110411FC1104
+6980:100010F810881088FC88108830F83888540053DE925212521252125213DE1252
+6981:1040102011FE1102FE0411FC3040388855FC5424902011FC1020102013FE1000
+6982:200027BE24882488FFA824A824A877BE6C10A518A49825A826AA244A20462080
+6983:082008207EFC08201C702AA8C82600003FF8210821083FF8210821083FF82008
+6984:10901290129E12A8FEC4108031FC39045524552491241154105010901112160E
+6985:100011F811081108FDF81108310839F8540053FC929412941294129417FE1000
+6986:104010A011101208FDF6100033C43A54565453D49254125413D41244125412C8
+6987:1040102011FC1000FC88105033FE3820542055FC902010A81124122210A01040
+6988:110010BC12841204FEF4129432943AF4560452F49294129412F4120412141208
+6989:1044112410881010FBFE108831243A2254F85020902013FE1020102010201020
+698A:120811081108103EFBAA10AA30BE392A55AA536A953E112A1108110811081108
+698B:100011FC100410FCFC0411FC3004380057DE5442904213DE1042104213DE1042
+698C:100013FA100C104AFB88112A3126392257F8512A912C112A1128122A12261422
+698D:200023FE22022202FBFE2210229272546AFEA282A2FE228222FE2482248A2884
+698E:13FE104011FC1104FDFC110431FC390455FC548090FC11081290106011981606
+698F:1104108410881000FBFE100030883904560251FC915411541154115417FE1000
+6990:100013FC12041204FBFC124832483AFC5648524893FE12A412A8149014C81886
+6991:1028102413FE1020FDFC112431FC392455FC5524900813FE1088104810481018
+6992:100013DE10421042FBDE121032103BDE54425252914A114A1252104212941108
+6993:20402028209022A4FAC2248A218876786800A3FCA29422942294229427FE2000
+6994:1100109E13D21252FE5413D432583A5457D252129292125A12D4135012101010
+6995:1040102013FE1202FC501088312438505488510492FA10881088108810F81088
+6996:08007F7808483E4800487F864100BEFC004408447E2818282C104A2888440982
+6997:100013FC10901294FD98109037FE380055F85508910811F81108110811F81108
+6998:200020FC3E8048F888887EF8148022FC40000100FFFE054009203118C1060100
+6999:1088108813FE1088FC2010503888350452FA5000900011FC1104110411FC1104
+699A:1104108410881000FBFE1020302039FC5420502093FE100012A4125214521000
+699B:1020102013FE1020FDFC10403BFE3488513452E2902011FC107010AC13221020
+699C:1040102013FC1108FC9013FE32023C44542053FC908010F81088110811281210
+699D:2000245C22942114FA942454212671006FDCA114A59425542948210825142222
+699E:100011FE11101120FD7C1144317C3944557C5510911011541152129212501420
+699F:1040102013FE1242FC2011FC3088385057FE5020902011FC1020102010201020
+69A0:100013FE12021000FDFC110431FC390455FC5440902013FE1000108811041202
+69A1:1020102013FE1020FDFC102033FE3840548855F0902413FE1022112412A21040
+69A2:1040102013FE1202FC0011FC304038A257345458909413341052109013501020
+69A3:1008103C13C01004FA44112831FC3A20542053FE902011241124112411FC1004
+69A4:2208220823BE2488FAA8213E220874486848A7FCA0E0215022482C4620402040
+69A5:100011FC110411FCFD0411FC3020392454A8502093FE1090109011121212140E
+69A6:102010201050FE5010887D0446227C2045FC7C601070FEA810A4112412201020
+69A7:100013FE12281228FEEE122832283AEE5628522892EE12281228122813FE1000
+69A8:1040102013FE128AFD04108030FE39405640507C90401040107E104010401040
+69A9:1040107C104013FEFE42127833C43A3C5640522093FE12881250142014581986
+69AA:100011FE112011FCFD2011FC3120392055FE500292AA12AA12AA120210141008
+69AB:10A0109011FE1320FDFC112031FC392055FE5500902013FE1020102010201020
+69AC:1020102011FC1020FBFE100031FC3904550451FC90521094118816A410C21080
+69AD:2084210423C42244FBDE224433C46A646254A7D4A0C421442244244421542088
+69AE:08202AA44D28145022887FFE4002810401007FFC0380054009203118C1060100
+69AF:201020102710257CFD10251025FE77086D08A5FEA50825482728200820282010
+69B0:1040104411F81050FBFE104030F83982567E540091FC110411FC110411FC1104
+69B1:2080204027FE2000FBF822082FFE72086BF8A0A4A12823102510294821862100
+69B2:200023F8224822A8FB18220823F870006800A7FCA4A424A424A424A42FFE2000
+69B3:2040202023FE2202FAEC2224224472446AEEA224A2A422A4224E2460249E2900
+69B4:104013BE12121292FE5212AA3324384057FE5222922213FE1222122213FE1202
+69B5:1108110817FE1108F80017FE310839F8550851F89108113E17C8100810081008
+69B6:1020101013FE1220FAFC122433FE3A2456FC522092FC12841284148414FC1884
+69B7:1080108017FE1522FD1013FC36203A2057FC5220922013FC1220122013FE1200
+69B8:1100113E112A112AF93E17AA312A393E55085108913E118817081208107E1000
+69B9:1004101E13F0121EFE1012FE32923A9856F2528E928012B812A814AA154A1A86
+69BA:00203D2424A8242025FC3C4027FE248825243E2225FC247024A8452456248820
+69BB:100011FC110411FCFD0411FC3800340053DE50429252114A12521042114A1084
+69BC:1020102011FC1020FC2013FE3080390457FE540293FC12941294129417FE1000
+69BD:103C17C012441128FC80111033E03840558853FC9044104017FC10A01110160E
+69BE:100011FC110411E4FD2413FE320239FC550455FC910411FC1104110411141108
+69BF:1020112411241124FDFC100033FE380055FC5504910411FC1088105013FE1000
+69C0:0100FFFE00001FF010101FF000007FFC40044FE448244FEC0100FFFE0920711C
+69C1:1040102013FE1000FDFC110431FC380057FE520292FA128A12FA1202120A1204
+69C2:20062F7821102120FA44227833106A24667EAA12A2102254225222922A502420
+69C3:10003E7822482A48FE8623782A4842304A48848401007FFC05401930E10E0100
+69C4:103C13C010441224FD28110030403B9C56045204939C12041204120413FC1204
+69C5:100013FE100011FCFD04110431FC380057FE528A925213FE12221222122A1204
+69C6:1110111017FE1110FA0013FC34043BE4562453E4922413E41224100410281010
+69C7:111811E0110210FEFC00117C3144397C5544557C9144117C110011FE10881104
+69C8:100013FE120012FCFE0013FE32A83A9056C85286920813FE1288144814081818
+69C9:1020101011FE1100F9201520333C39505590531095FE11101128122812441482
+69CA:2200147CFF44087C4944497C7F44084410942108FFFE054009203118C1060100
+69CB:1088108813FE1088FDFC108833FE382055FC552491FC112413FE110411141108
+69CC:10101220117C1144FC44107C33403940557C55449144117C11441280147E1000
+69CD:10201020105010C8FD2413FE350439FC550451FC910011FC1284128414FC1084
+69CE:11081088109013FCFC4011F830403BFE5480550091FC12201420182013FE1000
+69CF:10881050100013FEFC5011FC30543BFE545455FC905010D81154125210501050
+69D0:1020104011FC1124FD2411FC3124394455FC544090B010A4113C11221222141E
+69D1:00007CF84488448844887CF810201020FDFC307038A854A85124922210201020
+69D2:1040102013FE1040FC8811F03020384455FE540291FC112411FC112411FC1104
+69D3:100011FC10201020FBFE100031FC390455FC510491FC110411FC108811041202
+69D4:1040108013F81208FBF8120833F8388057FC5110924814441BFA104010401040
+69D5:10201020103E1020FDFC110431FC390455FC502093FE107010A8112412221020
+69D6:01007FFC01001FF000007FFE4002BFF408001FF068100FF00100FFFE0920711C
+69D7:1040104017FE1080FDF8128834F8380057FE520292FA128A12FA1202120A1204
+69D8:1104108813FE1020FDFC102033FE3820552454A8907010A81124162210A01040
+69D9:1020102013FE1020FDFC110431FC390455FC550491FC110413FE108811041202
+69DA:100013FE105013FEFE52125233FE380055FC5504912411241124105010881304
+69DB:10481148114E1150FD68114431443840540055FC915411541154115417FE1000
+69DC:10A0109011FE1320FDFC112031FC392055FE510093FC1088109E1102120A1404
+69DD:1020104011FC1104FDFC110431FC390055FE550091FE1042124A13FA10141008
+69DE:1080104017FC1110F8A017FE30003BF8564853F8924813F8124A1042103E1000
+69DF:1040102013FE1202FC1411E03100390055FC5110911017FE1000109011081204
+69E0:2020242022FA2224F82821FE2E2072406AFCA344A244227C22C42344227C2044
+69E1:11F810881070118CFC0013DE3252398C5652502093FE107010A8112416221020
+69E2:100013DE10421252FD4A12523042382055FC5504910411FC1104110411FC1104
+69E3:1040102013FE1202FC2011FC3050388857FE540891E8112811E8100810281010
+69E4:1010101012FE1110FD7C1054307C3B54557C511091FE111011101290147E1000
+69E5:108813DE108811DCFC8813DE3888340053FC5004900411FC1004100413FC1004
+69E6:202027FE242025FCFC2427FE242475FC6C20A5FCA52425FC252429FC2924312C
+69E7:08047F7808407F40497E7F4849487F4808487F48088801007FFC05401930E10E
+69E8:2200211E27D22012F7D4245427D870146FD2A092A11221DA2714211025102210
+69E9:00007DFC44207D2045FE7C5048525492650E0100FFFE054009203118C1060100
+69EA:2100223E27882488FCA827A824BE74886F88A010A4982718242824AA23CA2086
+69EB:102013FE102011FCFD2411FC312439FC542253FE900813FE1108108810281010
+69EC:2200220E2F742254F55428D4275470546FD4A454A754215421522154255C2284
+69ED:20142012201027FEFC10249024D274926FF2A494A49425C82AAA289A31A62042
+69EE:1040108811FC1108FA5213FE30503988562650C0931010641388103010C01700
+69EF:1020122213FE1090FC8811FE3B10351051FE5110911011FE1110111011FE1100
+69F0:2020247C22842148F83020CE2610727C6A10A27CA21022FE2210221025FE2800
+69F1:100011FE10481048FDFE114A314A398E550255FE910211FE10001154112A122A
+69F2:2204220427842494F90C27C4256475546FC4A546A57C27C425442544244428C4
+69F3:0440247C24A83D5004287DFE2488444885180100FFFE054009203118C1060100
+69F4:1040102013FC1204FBFC120032F83A8856F8520093FC132415FC1502190210FE
+69F5:1020102011FC1124FDFC102033FE3A2257FE50209040102412A2128A14781000
+69F6:200027FE242A2426F7FE242227AA76AA6FAAA432A596262E2446248227FE2402
+69F7:08203E2008F87F282228496A3E2A08567E820100FFFE054009203118C1060100
+69F8:2110211027D02110F93C27D4201472B46D54A11CA7D42114211421E427262242
+69F9:1020104011FC1104FDFC110431FC3820552454A89124102013FE102010201020
+69FA:2040202027FE2420FDFC242427FE74246DFCA420A56224B429282A2630A02040
+69FB:2200227C22442744FA7C22442244777C6A44A244A27C22282528254A284A3086
+69FC:11F87D0811F81108FDF8110829F824904112860E01007FFC05401930E10E0100
+69FD:1090109017FE1090FBFC129433FC3A9457FC500091F8110811F8110811F81108
+69FE:100011F8110811F8FD0811F830003BFC569453FC900011F81090106011981606
+69FF:1088108817FE1088FCF8102031FC392455FC502093FE102011FC102017FE1000
+6A00:1040102013FE1088FC5013FE32223AFA562252FA928A128A12FA1202120A1204
+6A01:1020102013FE1020FDFC104033FE388855045242959C110411DC110411FC1104
+6A02:2104220447C89452E45C47C89452F45E17C20100FFFE054009203118C1060100
+6A03:1100109E13D21252FE5213DE32523A5257D2521E9292125212D21352122A1044
+6A04:2010271025FE2510FD7C2654257C75546D7CA510A53826542492241024102410
+6A05:2124212422242424F954214A229276106A10A250A25C2250225022B0229E2300
+6A06:1040102013FE1000FD541124315439FC542053FE9242129212FA120A12021206
+6A07:2120213C214422A8FA1026A82AC672BC6AA4A2BCA2A422BC222422242224222C
+6A08:2080204023F82110F8A027FE200073F86A08A3F8A20823F82120212222222C1E
+6A09:1020102013FE1020FAAA112432AA382056AA512492AA10501050108811041602
+6A0A:24482288F93E22886458729CA92A228825480100FFFE0280044008203018C006
+6A0B:20FE240422282210F8FE20922E9272FE6A92A2FEA29222922296250028FE2000
+6A0C:100011FC112413FEFD2411FC300039FC550455FC910411FC110411FC10881104
+6A0D:102013FE102011FCFC2013FE300039FC550455FC910411FC110411FC10881104
+6A0E:1020101013FE1202F88010FE31103B20557C51449144117C11441144117C1144
+6A0F:100011FC112411FCFD2411FC3040388855F05420904413FE1022112412221060
+6A10:10201020103E1020FC2013FE32023B26568A525293261252128A132613FE1202
+6A11:22782128246C22AAF82A2148229870406840A7FCA0E0215022482C4620402040
+6A12:1040102013FE1242FC2812943AAA34CA50F85300902011241124112411FC1004
+6A13:102011FC112413FEFD2411FC302039FC552455FC904013FE108811D01070138C
+6A14:1124124811241000FDFC112431FC392455FC502093FE107010A8112416221020
+6A15:2108210827C82108F91E27D2256475406FC8A108A38825482954211421242142
+6A16:010006C01830EFEE00001FF010101FF0000013FEFC0811E8392855E890081018
+6A17:11FC102013FE1222FDAC102031AC380055FC500093FE108010FC100410281010
+6A18:1020112410A813FEFE0210F83088388854F85420902011FC1020102013FE1000
+6A19:100013FE105011FCFD54115431FC380055FC540093FE102010A8112412A21040
+6A1A:1040102013FE1250FE5013FE32523A5257FE5200929212D41298149214D2188E
+6A1B:200027BC208424A4FA9424A4205071886E26A0C0A31020642388203020C02700
+6A1C:1040102013FE1200FE48124833FE3A4856485248927812001554152A1A2A1000
+6A1D:1040107C104013FEFE42127833C43A3C560052FC928412FC128414FC148419FE
+6A1E:100013FE1200127CFE441244327C3A0056EE52AA92AA12AA12EE120013FE1000
+6A1F:102011FC10881050FBFE100031FC390455FC510491FC102013FE102010201020
+6A20:1088108813FE1088FC8810F830203BFE5622533292AA137612221222122A1224
+6A21:1110111017FC1110FC0013F832083BF8560853F8904017FC10A0111012081406
+6A22:1040108011FC1104FDFC110431FC390055FE550091FE100212AA12AA1202100C
+6A23:1104108813FE1020FDFC102033FE3820541054E0902213B410A8112416A21040
+6A24:2110211E21222254F20826942AE272886A88A2BEA28822AC222A224A22282210
+6A25:108813FE10881080FDF8128830703B8E542055FC902011FC102013FE10201020
+6A26:1210121013DE1528F884102030103BFE5420502091FC10201020102013FE1000
+6A27:2000245C22942114FA94241420A67140691CA7D4A11423942548290821142122
+6A28:200023FE220223FEFA102254223872546A82A250A27C2290221025FE24102810
+6A29:1080108011FE1220FC4013FE3890350853FE551091FE111011FE111011FE1100
+6A2A:1110111013FCFD10111017FE30403BF8564853F8924813F81000111012081404
+6A2B:200027DC251427D4FC5427C8250875146FE2A000A04027FC204020402FFE2000
+6A2C:1040108013FC1244FEF4131432A43A4456A453FC904010241522150A190810F8
+6A2D:1088108813FE1088FCF8108830F8388857FE5088912412FA1020102013FE1000
+6A2E:100013FE10501050FBFE125232523BFE54205124912412281050108811041202
+6A2F:1020102013FE1020FD2410A833FE380055FC5504917411541174110411FC1104
+6A30:100011FC102013FEFE2211AC302039AC540055FC900411FC1004100411FC1004
+6A31:20002FBE28A22AAAFAAA2AAA251478A26880AFFEA110221023A0206021982E04
+6A32:101417FE101013D0FC1013D030103BD0565053D0925013C8124A13CA11861242
+6A33:100013FC100413FCFC0413FC30003BBC552457BC900813FE1108108810A81010
+6A34:1110109413D21012FA50119037FE381057D25252925413D4124A124A13D61022
+6A35:1090108811FE1110FB1015FE3110391055FE5110911011FE110012A412521452
+6A36:100011F8110811F8FD0811F8380037FE524053DC925413D4126817C810541062
+6A37:082008207EFC18302C684AA488207F7C22443E4422283E28221027A8FA440282
+6A38:1050125211541050FBFE108830503BFE542051FC902013FE1050108811041602
+6A39:210421042FE42104F93E27C4200477E46C54A454A7C42444228420E42F142408
+6A3A:108813FE10881000FDFC10A830A83BFE54A854A891FC102013FE102010201020
+6A3B:102011FC112411FCFC2013FE300039FC550455FC910411FC110411FC10881104
+6A3C:27FC240427FC2400FDF8241027FE74206C60A79CA484250829DE2F0831082318
+6A3D:1088105013FE1050FDFC1154318C3974550455FC900813FE1108108810A81010
+6A3E:2114211221122790F97E21502FD471546954A548A5EA25562722250024FE2800
+6A3F:100013DE12521252FBDE100031FC392455FC512491FC102013FE102010201020
+6A40:1040102013FE1040FC8411FE30A838AA5526520091FC11541154115413FE1000
+6A41:1110111011DE12A8FC44110031FC3A0455F4511491F4111411F4111410281010
+6A42:1088105013FE1050FDFC1154318C3974550455FC902013FE1050108811041202
+6A43:102413A810921514FA08140433BA38A854C65380923C138410A8109012A81144
+6A44:2008278820882110FFDE249424A477946C94A794A49424C827882C9420A420C2
+6A45:1080108011FE1354FD54115433FE39545554515497FE10001154112A122A1000
+6A46:20003FFC529092907FFC12901290FFFE082008207EFC18202C704AA889240820
+6A47:103813C0107813C0FC7813C4383C340050C6573891CE173811CE1738114A1186
+6A48:1020102011FC1020FBFE1108339C39085588563E900013FE109010901112120E
+6A49:1020112410A813FEFCA8112432223904550451DE92441554109E110412041404
+6A4A:100013FE105013DEFA52125233DE385057FE5222922213FE1222122213FE1202
+6A4B:101811E0104013FEFC88117432523870540055FC91041174115411741104110C
+6A4C:13DE125213DE1252FBDE120232F23A9256F2529292F212921292133212021206
+6A4D:100013DE125213DEFE5213DE32023AFA562252729222122212FA1202120A1204
+6A4E:103C13E0112410A8FBFE10A831243A0255FC5124912411FC1124112411FC1104
+6A4F:1088105013FE1020FDFC102033FE392454A853FE900011FC1104110411FC1104
+6A50:01007FFC11101FF00100FFFE80023FF804001FF068100FF00100FFFE0920711C
+6A51:2040204027FCF8A02514220877FC6A0AABF8A20823F820402248244429442080
+6A52:100011FC102013FEFE2211AC302039AC540055FC900013FE1040108811FC1084
+6A53:203C27C02044FA24210827FE74026A08AA08A3BE24882AA8213E220824082808
+6A54:221021102FD02010F7BE24A427D470146F94A094A11421C82F08211425142222
+6A55:112410A813FE1202FCF8108830F8380055FC5410911011FE1050109013101030
+6A56:1020112410A813FEFE0210F83088388854F8502093FE107010A8112412221020
+6A57:1088108813FE1088FC0013DE32523A5257DE5252925213DE12521022102A1044
+6A58:100013FC10481030FBFE105230943B50542053FE9252128A1376125212721206
+6A59:102017A410A81292F914120835F4380257F85208920813F8120811101FFE1000
+6A5A:102011FC102413FEFC2411FC30203AAA57AE522293FE122213AE12AA12AA1422
+6A5B:20002FFE28002A28F9482BEE289278846AA0AAA8ABE828882894291429243242
+6A5C:3FFE289025103FDE22222A882F882294242228803FFE21C022A0449858868080
+6A5D:100013FE105013FEFE5213FE300039FC550455FC910411FC102013FE10201020
+6A5E:1020102013FE1020FDFC112431FC392455FC502293FE1042102412A2128A1478
+6A5F:1124112412AA13AEF92412AA33AE392457FE511091141114128A124A12161422
+6A60:102013FE104010F8FB48103033D0383C55C45048903013C410A8119016A810C6
+6A61:108010F8110813FEFD12112239FE344050A25354909813341054109213501020
+6A62:2020272025FE2540FD7C2690257E75006D7CA544A57C2644247C24442444244C
+6A63:208020402FFE2882F548251428F470006FFCA444A7FC244427FC244424542408
+6A64:01002488242443E4000024241212A0A0A4A41C1C01007FFC05401930E10E0100
+6A65:282211FC28284BFE984029FC4E8488FC288410FC01007FFC05401930E10E0100
+6A66:102011FC10881050FBFE100031FC392455FC512491FC102011FC102013FE1000
+6A67:11041088100013FEFE2212AA32723A2257FE540091FC110411FC110411FC1104
+6A68:102011FC10201088FBFE108831FC390455FC510491FC110411FC108811041202
+6A69:108812AA12DC1488F954122233FE3A02540050F890881088108A110A12061400
+6A6A:1110111411D21250FA7E155030903AA85528514492441482100812A412521452
+6A6B:1088108813FE1088FCF8100033FE382055FC552491FC112411FC108811041202
+6A6C:100013DE108812A8FBFE118832DA3CA655F85108910811F81108110811F81108
+6A6D:102013FE102011FCFD0411FC302039FC5488505093FE102011FC102010201020
+6A6E:104013BE12921252FEAA1324304039FC550455FC910411FC110411FC10881104
+6A6F:208822AA22DC2488F9542222200073FE6A42A444A3FC20442044208421142208
+6A70:104011FC110411FCFD0411FC310439FC5420552490A81124102013FE10201020
+6A71:200027FE24002404F7E4240425DE75446D44A5D4A40C2544248424E42B142008
+6A72:102013FE102011FCFC0011FC390435FC508853FE900011FC1104110411FC1104
+6A73:2010275425382510FD7C271025FE75286D24A752A5FC2514252425242B542088
+6A74:1090109212D4129AFAD2174E308839F05420504493FE10221128122414A21040
+6A75:2288228827C82290FA9E27D4202477D46C54A7D4A45427C824482454246424C2
+6A76:21102114211227D2F91027DE247077D26C52A7D4A1142FD8210A211A21262142
+6A77:2040228822EA2EAAF2AC22E822AA76AA6AE6A000A1202120212022222422281E
+6A78:10F81088108810F8FC88108830F8380057DE5252925213DE1252125213DE1252
+6A79:108010F8111013FCFD2411FC392435FC500053FE900011FC110411FC110411FC
+6A7A:100013DE125213DEFE5213DE32023AFA568A52FA928A12FA128A1202120A1204
+6A7B:200023F820482048FBF82088208877FC6800A7BCA294229427BC229422D42F3E
+6A7C:2220223C24442578F9082EFE222074D2681AAF2CA0CC201A232A2CC820282010
+6A7D:10101210117C1010FCFE1044332839FE5510557C911011FE1110111012FE1400
+6A7E:11FC1104110411FCFC0013DE32523A5257DE502093FE107010A8112416221020
+6A7F:100013FE100011FCFD2411FC31243BFE540055FC912411FC112411FC100013FE
+6A80:20402FFE200027FCFC0425F4251477FC6800A3F8A20823F8220823F820002FFE
+6A81:102013FE100011FCFD04117431543974550455FC900810F0102013FE10A81326
+6A82:109013FC129413FCFE9413FC30003BFC560052F8920013FE1520151415481986
+6A83:001E7BE4492853FC602053FE48004BFC680453FC400443FC0100FFFE0920711C
+6A84:2108220827C82450FFDE246427D472146914A7D4A21423C822482454255428A2
+6A85:1020113C112013FEFC10101433FE3A1057F05254925412D41368144A18961322
+6A86:2108210821482548F58E290822887448693EA162A5A22522292222A2247E2822
+6A87:10A0109011FE1320FDFC112031FC392055FE510093DE12521252127212021206
+6A88:100013FC12941294FBFC100037FE380057FC520493FC10A2111413081D441182
+6A89:100017E0125E13D2FE5213D23A7237DE504053FE902011FC1020102013FE1000
+6A8A:2108210821142FD4F12227C0245C77C86C48A7C8A13E2FC82108210821082108
+6A8B:108813FE108813FEFC88112432FA382055FC552491FC112411FC102013FE1020
+6A8C:200023FC22942294FBFC20002090779E6890A090A39C20902090279E20902090
+6A8D:1040102011FC1088FC5013FE300039FC550455FC910411FC10201294128A147A
+6A8E:1020105010881124FEFA10503124395455FC502093FE1242129212FA120A1206
+6A8F:1050125211541050FBFE108830503BFE542051FC902013FE10A8112416221020
+6A90:110011F8120817FEFA88132433FE3A0056FC520092FC120012FC148414FC1884
+6A91:100011FC102013FEFA2211AC302039AC540051FC9124112411FC1124112411FC
+6A92:082008207EFC18302C684AA69FF010D01710111017D0155027CA212A4FE68022
+6A93:210026DC24542454F6D42454246677C0681CA014A7D42114210821C827142222
+6A94:1020112410A813FEFE0210F83088388854F8540091FC112411FC112411FC1104
+6A95:0800FF7808487F4849867F0049787F480828FF9049287F440100FFFE0920711C
+6A96:104412241128107EFC101028334A391C5528554C911A112A1148111012FE1400
+6A97:00407C2045FC44887C5043FE7C20A5FC24203C2001007FFC05401930E10E0100
+6A98:20102008278824BEFC8024942788747E6C08A788A6BE2A882A882B8832882008
+6A99:21F8210821F8250AF5FA250A25FA74026F9EA090A0902F9E2492249224922892
+6A9A:2110211027BC2110FBB82554291270006FFCA044A24022782240254028FE3000
+6A9B:2000227C21442174F854205426FE72826ABAA2AAA2BA2282228A2284250028FE
+6A9C:204020A023182DF6F00027FC255474E46FFCA000A3F8220823F8220823F82208
+6A9D:101013D412521252FBD0101037FE3A5057D2525293D4125412EA174A10561062
+6A9E:2200239E248A290AF7D22566254077D46D5EA564A7C42544255E2544244428C4
+6A9F:100013FE105013FEFE5213FE300039FC550455FC910411FC110411FC10881104
+6AA0:2420FF20243E7E4482847A284A107A2804440100FFFE054009203118C1060100
+6AA1:100011FC115411FCFC2011FC30203BFE5488545091FC102013FE102010201020
+6AA2:1020102010501088FD0412FA3000380055DC5554915411DC1088108811541222
+6AA3:2040204027FC2248FA4825542FFE70006BF8A208A2E822A822E8220823F82208
+6AA4:10441028120011FEFD20107C30443B7C5544517C9144117C11441280147E1000
+6AA5:1104108813FE1020FDFC10203BFE34545192509093FE109010D4138A109611A2
+6AA6:20022FE222822FEAFAAA2AAA2FEA700A6BCAA00AAFEA210A25422522292A2304
+6AA7:108813FE10881100FBFC155430D43B24545450949348102010A4128A128A1478
+6AA8:1104108813FE1020FDFC102033FE38005620513E904211141610122812441082
+6AA9:102013FE100011FCFD04117431543974550455FC900011FC100013FE11241262
+6AAA:1020104010F8128AFD8C10F8318C3A8A54F8502093FE107010A8112416221020
+6AAB:2080204027FE2402FA2423BC34A46AA86510A2E8A4042BFA20402248244420C0
+6AAC:211027FC211027FCF40423F8200077FC6880A144A6A8217026A8212626A02040
+6AAD:2200227C254424C4F87C27442244727C6F52A252AA542748224823542C622040
+6AAE:204027FC204023FCF80027FE200273F86840A7FEA00027FE200827FE24A82798
+6AAF:20402FFE204027FCF80023F832086FFE6802A7FCA11023F8204027FC20402FFE
+6AB0:21082110223E2222F4BE2722213E72086CBEA7AAA02A20AA256A252E24082008
+6AB1:110811EE12941042FC88108833FE388854F8548890F8108813FE108811041202
+6AB2:13FE122213FE1222FEFA12AA32FA3AAA56FA522693FE120A13FE128A125A13FE
+6AB3:2080204027FE2402FBFC2148225077FC6A04A7FCAA0423FC220423FC21082204
+6AB4:108813FE10A81090FDFE132031FC392055FC512091FE110013FC10881070138E
+6AB5:1044128412EA124EFEA412EE32223BFE5644528492EA124E12A412EE122213FE
+6AB6:1020102013FE1050FC8813FE32003A7C5644527C920012EE12AA12EE120013FE
+6AB7:200027FC22482444FFFE244426EC75546EECA444A6EC255426EC244424542408
+6AB8:1040102013FE1222FD54114A323A380055FC515493FE100011FC102010A01040
+6AB9:24202220223E2F40F490247E272475426DFEA504A57425542974290433142008
+6ABA:204027FE200021F8F90821F8200077FE6C02A3F8A180264421B8266821A62660
+6ABB:100813E8128813EEFE2813F432823BE2540051FC915411541154115417FE1000
+6ABC:203E27C022442128FBF8204027FC70006BF8A008A3F8200823F82544252A28FA
+6ABD:100011FC102013FEFA2211AC302039AC540053FE902011FC115411541154110C
+6ABE:08202AA44D28145022887FFE4002882408207EFC08301C682AA4C92208200820
+6ABF:3FFE28942F9228902FFE20102F9028A82FA428C4298020404FFE416086581846
+6AC0:110817FE110811F8FD0811F8390837FE5108529495E2104813FC1040124814C4
+6AC1:1040102013FE1242FC2812943AAA34CA5378502091FC112411FC102213FE1002
+6AC2:200027BC208424A4F29424A4212072106FFCAA20A3FC222023FC222023FE2200
+6AC3:27FE242025FC2524FDFC242027FE75046DFCA504A5FC250425FC2488250427FE
+6AC4:101C11E0102013FEFC2011FC31AC397455FC542091FC102013FE10001154122A
+6AC5:2080204027FC2110F0A42F58255475526B58A000A20823F8220823F822082408
+6AC6:2104221427CC2544FD5427CC2546755C6FC4A104A2A422D424F02482287E2000
+6AC7:2080209E208427E8FCBE2492249277DE6E52A55EA5522492289E2940314C2252
+6AC8:202427A820922514F2E8240423FA72086BF8A110A7FC200021F021102212240E
+6AC9:200027FE24842484F7E4249E25C474046DD4A54CA5C42544288428C433142008
+6ACA:200027BC24A427BCFCA427BC248475F46E94A4E4A71C24E424A424A424E4240C
+6ACB:104011FC11241194FD4C112439FC342053FE528A912413FE108010FC1104120C
+6ACC:23FC204021F82108F9F8210827FE74426AA4A28AA47A208021F822882070238E
+6ACD:1042139C121013DEFE94129434203BFC560453FC920413FC120413FC11081204
+6ACE:2040202027FE2488FDFC248827FE74206DFCA524A5FC252425FC240024882904
+6ACF:200020FE242822FEFAAA20FE201071FE6E44A2FEA344227C2242223E250028FE
+6AD0:1FF011101FF011101FF000003EF82AA83EF82AA83EF801007FFC05401930E10E
+6AD1:23F82248224823F8FA48224823F870006FBEAAAAAAAA2FBE2AAA2AAA2FBE28A2
+6AD2:1088108813FE1088FD1011DE3A52355452885174920211FC1020112412221060
+6AD3:108011F8120815FCFD2411FC392435FC5154522A91FC110411FC110411FC1104
+6AD4:100013FE124813FEFE4812FC32A43AFC56A452FC922013FE132A157A150A1906
+6AD5:108811DC108813DEFC881154322239FC550455FC910411FC110411FC10881104
+6AD6:2020203E202027FEFC2225F8242275FE6D24A5FCA52425FC28402AA4328A247A
+6AD7:110817FE11081000FBFC129432943BFC542853FE9220132412A81292142A18C6
+6AD8:108813DE108811DCFC8813DE30883BFC540451FC900413FC104012A4128A147A
+6AD9:1088108817FE1088FBFE1200327C3A44567C520092EE12AA12AA12EE120013FE
+6ADA:100013DE125213DEFE5213DE32023AFA568A52FA920212FA128A12FA12021206
+6ADB:1108110811EE1294FC42100033DE3A5257D2525293D2121A1294135012101010
+6ADC:01007FFC11101FF00100FFFE88421F6032504C4837FEC1007FFC05401930E10E
+6ADD:102013FE102011FCFC0013FE32523BFE550455FC910411FC110411FC10881104
+6ADE:2120213C21442278FA8824FE2F2071526A1AA4ACAFCC209A202A2AC82AA82810
+6ADF:244424E428A82AAAFEEE24A42AAA7EEE6A42A040AFFE20E0215022482C462040
+6AE0:202027FE241027D4FD4A2484250277DC6C54A5E6A50025DC2844285431482094
+6AE1:2210221023DE2528F884204423F870506FFCA080A3F82D0821F8210821F82108
+6AE2:210827C825482FF0F55E27E4211477D46D54A7D4A2142FC82448269421942662
+6AE3:110817FE11081410FAFE1210307C3854567C5254927C121012FE1210151018FE
+6AE4:121013DE15281084FD08109037FE380057D4525493D4125413D41244125412C8
+6AE5:1040102013FE1244FBF4124432EE3A0456F452AC92E4121412A4147415941808
+6AE6:102013FE125013FEFE5213FE32003BFE56925348923A124012FC1548143019CE
+6AE7:24102210207A2712F814277E20087710683CA764A5A4253C25242724253C2024
+6AE8:1040107C104013FCFE4413F032443AFC56A852F892A812F8120015FC15541BFE
+6AE9:13DE125213DE1252FBDE1242327A3A8A571252DA928A12DA128A12FA120A1204
+6AEA:200027FE24442598FC8827DE248875DC6EAAA488A4202520253C2920292037FE
+6AEB:00207F2410FC28284DFE1620247C4EC4157C64440C7C01007FFC05401930E10E
+6AEC:2200213C27A42024F4BC232427A4713C6924A7A4A13C259025582968252A2246
+6AED:2F7E29102F502950FF7E2A282B287D4A6886A7F8A40827F8240827F820002FFE
+6AEE:100013FE102013AEFEAA12AA33AE382057FE502093AE12AA12AA13AE102013FE
+6AEF:2206223827882488F90827DE254875486FDCA55AA56827E820082AA82AA82008
+6AF0:208020402FFE2000F7FC24A427FC72486950A208A44420A8211023082D462180
+6AF1:52107EFE28447E28A2FE3E1020103E7C22103E1001007FFC05401930E10E0100
+6AF2:20202F3C214425BEFA2A212A2FBE72906B2AA25AA22C225C222A22482A282410
+6AF3:2210211027DE2010F45E228227DE70106FDEA450A7DE245027DE2450245224CE
+6AF4:2108210827CE2112F92427DE2552755E6FD2A11EA392255E2940211421122122
+6AF5:1088108813FE10A8FC9011FE31203BFC552051FC912011FE110012A412521452
+6AF6:102013FE122211FCFC2010F8302039FC542055FC915411FC104012A4128A147A
+6AF7:208027FC240427BCF8A026BE22A277B66AAAA6AAA0B626A222BE27A022A2267E
+6AF8:2140226C2244236CFAA423AC22A477FE6908A244A5F2204027FC204020402040
+6AF9:211027FE215023F8F84827FE204873F86D54A75CA44427FC2444275C25542954
+6AFA:200027FC20402FFEF8422358204073586800A000AEEE2AAA2AAA2AAA2EEE2AAA
+6AFB:13DE125213DE1252FBDE125233DE398C5652504097FE10881190106010D81304
+6AFC:2148214C22AAF80827FE21487368694AAB6AA14C236C2148216A239A20262042
+6AFD:00187BE0495053F8604053F8480849F86840529444F401007FFC05401930E10E
+6AFE:21822E3C20882A90F522243C27887A126A3EAF88A2082AAC2AAA2BCA2EA82090
+6AFF:108812AA12DC1488F954122233FE3A0254F8508890F8100011FC110411FC1104
+6B00:204027FC200023B8FAA823B8211077FC6910A7FCA1102FFE212823102D482186
+6B01:22882FE82AA82FE8FABE2FE830086FDC681AABE8A8282FC82AA82A482B283228
+6B02:108813FE10881412FAFE101034FE3A9256FE509291FE1292160412FE1244122C
+6B03:11F0121017FC1204FBFC122433B83A2255FE521097FC124413FC10D0114A163E
+6B04:13DE125213DE1252FBDE122232FA3A2256FA52AA92FA12AA12FA127212AA1226
+6B05:2140226C2244236CFAA423AC22A477FE6908A2F4A44223F8204027FC204020C0
+6B06:2108229423DE26B4FBDE229423DE72946BDEA210A7FC21082090206021982606
+6B07:13FC110811F81108FDF8110E37F8380857FE5294939C1294139C12D617BC1084
+6B08:122213FE109011FEFB1015FE311039FE551051FE910013FE128A137612521276
+6B09:249222942FFE2110F7FC204023F870406FFEA480A7BC2494279424C82F9420A2
+6B0A:108813FE108813DEFE5213DE30A0389055FE512093FC152011FC112011FE1100
+6B0B:13DE125213DE1252FBDE125233DE389055FE511093FE151011FE111011FE1100
+6B0C:2090209027FE2094F80A21FE250877E8694AA1EAAF2A25EA254C29EA22162462
+6B0D:210827FE212823FEFA2027FC2A2073FC6A20A3FEA080231C2204239C220423FC
+6B0E:2288F93E2288729CA92A2288FFFE80023E0822FE3E0822483E28280824283A10
+6B0F:200027FC24A424A4F7FC221022A874BE6F68A23CA4A82FBC20282AA82ABE2020
+6B10:13DE100013DE1252FB5A125230203BFE565053FE925213FE129212DC129214CE
+6B11:252827BE294827BEFB1825AA294673FC6A04A3FCA20423FC220423FC21082204
+6B12:210447C88812F3BC20084B92F83E0380AAAAABAA01007FFC05401930E10E0100
+6B13:2248215027FC2404F9F0211027FC75546CE4A7FCA04027FC20402FFE22A42452
+6B14:13DE125213DE1252FBDE10A031FE3B2055FC512091FE100011FC10881070178E
+6B15:27BC24A427BC2000F7FE24002590749E6FD4A564A5D4255425D425682BC83054
+6B16:2790251E27A82484F7BE252A27BE70006BF8A208A3F8220823F820A02124261C
+6B17:108813FE108813DEFE5213DE32523BDE562253FE92AA12FA1222127212AA1224
+6B18:13FE120213FE1292FE54129232FE3AAA56FE532292FA12AA14FA142219FA1004
+6B19:27FC244427FC2444FFFE2AAA2FBE7AAA6FBEA220A7C020842FFE204225482884
+6B1A:21F0221023E02020F7FC2188265071A86E64A1A0A2482FBE2AAA2FBE228A2FBE
+6B1B:23FE202027FE2422F9AC228027DE72926B92A11EA7D2255227DE21122FD22126
+6B1C:204027FC224823F8F0402FFE2AAA73B86910A7FCA1102FFE212823102D482186
+6B1D:2288F93E2288729CA92A22887FFC44447FFC22083EFE22483E28280824283A10
+6B1E:27FC20402FFE2842FB582040235870006EEEAAAAAEEE20002FFE224825542FFE
+6B1F:228027DE229227D2FD5E27D231126C9E67D2AD12B7DE250827CC251427D42422
+6B20:0800080008000FFC10041108211041000100028002800440082010102008C006
+6B21:00804080208020FC010409080A4014401040E0A020A021102110220824040802
+6B22:00800080FC8004FC050449082A401440104028A024A045108110020804040802
+6B23:022007203820207E204220843F10241024102410242824282448444444848102
+6B24:2020202020203F7E2042408440107E10021002101A28E2284248024414840902
+6B25:004000407C40447C4484448845207C2044204450445044507C88448801040202
+6B26:084008401440147C228452888920082000207E50025004500488088809040202
+6B27:00407E404040447C6484548849204820542054506450405040887E8801040202
+6B28:2040204040407E7C828402887B204A204A204A507A504A500288028815040A02
+6B29:00207F201120117E21422584421080103F1021102128212821283F4421440082
+6B2A:102010209220927E92429284FE10101010109210922892289E48F24400840102
+6B2B:202020203F20487E884208847F10081008102E10282828282F48F04440840102
+6B2C:102008200820FF7E0842108422107C10091012102428C82814482244C0840102
+6B2D:0020FE208220927E92429284FE1092109210AA10A628C2288248FE4482840102
+6B2E:422022202420FF7E084208844910491049107F10092810281048204440848102
+6B2F:104010401040FE7C108410887D20002000207C504450445044887C8845040202
+6B30:0820082010207F7E5542558455105510551055105528552857A8FC4400440082
+6B31:104010402840247C428480887D20002000207C504450445044887C8845040202
+6B32:142012202120497E0842148422104110BE1022102228222822483E4422840102
+6B33:082008200F20087E08427F845510551055107F10552855285528514445444282
+6B34:104008407E40427C42847E88432042207E204050485044504A88528861044202
+6B35:40404C407040447C44843C8841207C2090201050FE5010502888248845048202
+6B36:08200820FFA0087E08427F84491049107F1008101C282A284948884408840902
+6B37:422024201820247E52421084FF10201028107E10AA282A282A482E4408840902
+6B38:102010202020447EFE42028440107C1090101010FE2810281048284444848502
+6B39:082008207F20143E22224144FF5002907A104A104A107A284A2802440A440482
+6B3A:22202220FFA0227E22423E84221022103E1022102228FFA82448224442848102
+6B3B:104052405440907C288444888320102010205250545090502888248843048202
+6B3C:0020F7201120557E22425584891010100010F710112855282228554489441082
+6B3D:104010402840247C4284BC8811201020FE2010509450585050881E88F1044202
+6B3E:08200820FF20087E08427E8400107E100010FF1008284A284948894428841102
+6B3F:102010203E20227E4442808410106610421042106628422842487E4442840102
+6B40:082008207F201C7E2A42498400107E100010FF1008284A284948894428841102
+6B41:22202220FF20227E3E4222843E1022102210FF1040285428624840447E840102
+6B42:102092209220927EFE420084FE1010102010FE10AA28AA28AA28AA44AA448682
+6B43:02200F207820087E0842FF8428104B10491049106B28492849487F4441840102
+6B44:00203E202220227E3A422A842A107F1041105D10552855285D28414445444282
+6B45:0040FE402840287CFE84AA88AB20FE2010201050FE50105010881E88F1044202
+6B46:10200820FF20007E42422484FF1000107E10421042287E28424842447E844302
+6B47:00207E2042207E7E42427E8420107F1089104910552841287D2801440A440482
+6B48:102028204420827E7D420084F11095109510F51095289528F52891449544B282
+6B49:22201420FFA0147E14427F841510FF9015107F1014283628552894C414441482
+6B4A:10200820FF20007E7E4242847E100010FF108110BD28A528BD28814485448282
+6B4B:03207C204720447E5F42558456105C10551053105028572855485544A9840102
+6B4C:0020FF2002207A7E4A427A840010FF1002107A104A284A287A2802440A440482
+6B4D:102020207F20417E41427F8440107FD040107F9000A8AAA8AAA800C405440282
+6B4E:22202220FF20227E3E4208847F1049107F1008107F280828FF48144422844102
+6B4F:22202220FFA0227E3E4208847F1049107F1008107F2808287F2808440F44F082
+6B50:0020FFA080209F7E914291849F108010BB90AA90AAA8AAA8BBA88044FFC40082
+6B51:0410079004103FDE245227243C88238820882F0832482A945FD442148A140422
+6B52:20201020FE20447E2842FE8482109210FE109210BA28AA28AA28BA4482448682
+6B53:202020203F20483E88227F44145022907F10A4103F1024283F2824443F442082
+6B54:10201E2010207F3E51225C4472504E9040104A106A905B284A288F4478440082
+6B55:08207F200820223EFFA222447F5041907F1041107F1041287F28224441448082
+6B56:0820FF2008207E7E00427E8442107E102410FF1000287E28422842447E444282
+6B57:04103F9004907FDE04923FA40408554875C844487FC8445475D4555455548462
+6B58:0820292029204A7E144222844110001022102A90B72862282228524445448882
+6B59:0820142022205D3E80A23E4422503E9000107710111055283328554411443382
+6B5A:11100A107FD0041E3F9204247FC8248815087FC800083F94209420943F9420A2
+6B5B:082008201420227E4142BE840010001077105510552877282228224455448882
+6B5C:00207F205520557E7F4220847F1091107D10551055287D2811287D4405440282
+6B5D:00207F2055207F7E08427F840810FF90221014107F280828FFA8084408440882
+6B5E:00207F2041207F7E41427F842210551077102210552877280028554455440082
+6B5F:28204B204D20497E6B424D845510771055105510FFA800282228214441448082
+6B60:772055202220557EF742558422105510FF9014107F28552863285D4441447F82
+6B61:22202220FFA0227E77425584771012103F106410BF2824283F2824443F442082
+6B62:01000100010001001100110011F81100110011001100110011001100FFFE0000
+6B63:00007FFC0100010001000100110011F8110011001100110011001100FFFE0000
+6B64:0440044004402444244827502460244024402440244024422F42F042403E0000
+6B65:0100010011F8110011001100FFFE0100010011081110212040C003001C00E000
+6B66:004000503F4800480040FFFE0040044004402740242024222412278AF8064002
+6B67:0820082008200BFE48204E20482049FC4884488848484E505820E05001880606
+6B68:0100010011F8110011001100FFFE00000100110011F811001100290047FE8000
+6B69:0100010011F8110011001100FFFE0100011011081114212440C003001C00E000
+6B6A:00007FFC0100030005601918610400007FFC0100110011F811001100FFFE0000
+6B6B:080008FE0880088048804EFC488448844884488448FC4E805880E08000FE0000
+6B6C:010011F811001100FFFE010002001FF0101012101110FFFE1210211040508020
+6B6D:10201020102011FC50205C2053FE5008500851FE50085C887048C00800280010
+6B6E:0100010011F811001100FFFE00000810081048904E9C489048904E90F1FE0000
+6B6F:0100010011F811001100FFFE0000292825482FE823882548292820083FF80008
+6B70:00007EFC122452A4932422442A544488081008104E9C489048904E90F1FE0000
+6B71:1008103C11E0102053FE5C2051FC512451FC512451FC5C2071FCC02003FE0000
+6B72:008008FC088008807FFE002800243FFE20202FA422242A182A90512A46469882
+6B73:008008FC088008807FFE002800243FFE20202FA422242B182A9252AA4A468482
+6B74:3FFE221022103FBE261027382AD43292221022502040227C424042409FFE0000
+6B75:102011FE102011FC50205DFE500051FC510451FC51045DFC7104C1FC00880104
+6B76:08442F7828422F3EF0001FF011101FF011101FF001003FF821482FE824282018
+6B77:3FFE2000230C3C7024103F7E24102E3835542492208024F844804480BFFE0000
+6B78:10007DFC44047CFC40047DFC44007FFE122210205DFC512451245D34E1280020
+6B79:0000FFFE02000200040007F8080810102410422001400080010002000C007000
+6B7A:0080008000FE088008800FF8100814102210412001400080010002000C007000
+6B7B:0000FFFC1080108010841E88229022A052C08C800480088408841084207C4000
+6B7C:0008003CFDE0202020203C20442047FE64209420082008201020202040208020
+6B7D:0008001CFDE0210021003D0045FE451065109510091009101110221042108410
+6B7E:00800080FC8020FC21543E5444544494649495240A2408441044208441288010
+6B7F:00800080FCFC210421043E28441047FC65049488088808501020205041888606
+6B80:0008003CFDE0202020203C2045FE442064209450085008501088208841048202
+6B81:000000F8FC88208820883D06460045FC64849484084808501020205040888306
+6B82:000001F8FD08210821083DF845084508650895F8090809081108210847FE8000
+6B83:00200020FC2021FC21243D2445244524652497FE082008501050208841048202
+6B84:00200020FC50208821043E124420444065889410082008441188201040608380
+6B85:00200020FD20212021FC3D2046204420642095FC082008201020202043FE8000
+6B86:0020FC202020204020483C8445FE4482640094FC088408841084208440FC8084
+6B87:00800080FCFE210022F83C104420444065FC9494089409241224244440A88110
+6B88:00200020FC40208021FC3D544554455465549554095409541154215443FE8000
+6B89:0080FE8020FC210421043FF445144514A5F41914091411F41114200440148008
+6B8A:00200120FD2021FC21203E20442047FE647094A808A809241124222240208020
+6B8B:00500048FC40205C21E03C40445E47E064449448083008221052208A43068002
+6B8C:000003FCF800212422483C904A48492468009BFC084010401040204047FE8000
+6B8D:0008003CFDC0200421443CA8440045F8641094200BFE08201020202040A08040
+6B8E:00200020FC2023FE20203C2045244524652496AA082008501050208841048202
+6B8F:00280024FC24202023FE3C20452044B264B4946808A809241222202040A08040
+6B90:00200020FDFE202020203DFC4524452465FC9420087008A81124222240208020
+6B91:0020FC2023FE202020203DFC45044504650495FC08500850109220924112820E
+6B92:000000F8FC88208820F83C0045FC450465249524092409241050204840848304
+6B93:00200020FC50205020883D0446FA440064449424092408A81088201043FE8000
+6B94:00200020F9FC202420243BFE4824482469FC9A22097410A81124222240A08040
+6B95:00400020FDFC200021083C90440047FE6400940009FC09041104210441FC8104
+6B96:0020FC2023FE202020203DFC450445FC650495FC090409FC1104210447FE8000
+6B97:00400080FBFC211022483C464BF84A486A489BF80A48124813F820424042803E
+6B98:00900088FCBC23C020503C2444D4472C649094BC0BC008481050202440D4830C
+6B99:001C03E0FA2023FE22203A924B0A4A0669FC9904090411FC1104210441FC8104
+6B9A:01040088FC5021FC21243D2445FC4524652495FC0820082013FE202040208020
+6B9B:000003FCF808201020203BAE4AA24AAA6AA49AA40BAA103210A0204047FE8000
+6B9C:00480148FD4823FE21483D484578450065FE94200BFE087010A8212446228020
+6B9D:00200020FBFE202021FC38404BFE488869349AE2082011FC107020AC43228020
+6B9E:000001F8F908210821F838004BFC4A046BFC9A040BFC120413FC209041088204
+6B9F:000001F8FD08210821F83D08450845F8640097FC0A940A941294229447FE8000
+6BA0:00200040FDFC210421FC3D0445FC450465FC942808240BFE1050208841048602
+6BA1:00400020FBFE2202241439E04900490069FC9910091017FE1000209041088204
+6BA2:01540154FBFE215421543A724C004BFE6A22982009FC112411242124412C8020
+6BA3:0088FC8823FE208820F83C2045FC452465FC94200BFE082011FC202043FE8000
+6BA4:008000FEFD0022FC20843CFC448444FC640097FE088009FE12522092412A8044
+6BA5:0040FC2023FE220220003DFC442045FC652495FC092409FC1000208841048202
+6BA6:00400080FDFC210421FC3D0445FC450065FE950009FE080212AA22AA4202800C
+6BA7:02140112FBD22010203E3BD04A504A506BD099280BA813681528212A452A8246
+6BA8:002001FCFD2421FC20203FFE440045FC650495FC090409FC110421FC40888104
+6BA9:008000DCFA8423D424483A944B244C406A4899500FFC10E0115022484C468040
+6BAA:002003FEF82021FC20003BFE4A0249FC680099FC090411FC1104208843FE8000
+6BAB:000003DEFA52225223DE380049FC492469FC992409FC102013FE202040208020
+6BAC:000001FCFD5421FC20203DFC442047FE6488945009FC082013FE202040208020
+6BAD:000003FEFC0021FC21243DFC452447FE640095FC092409FC112421FC400083FE
+6BAE:00200020FC50208821043EFA4400440065DC9554095409DC1088208841548222
+6BAF:00400020FBFE220221FC39484A5049FC6B0499FC090411FC110421FC40888104
+6BB0:002003FEF82021FC20003BFE4A524BFE690499FC090411FC110421FC40888104
+6BB1:0088008CFBEA208820883BFE49484B6A694A9B6A094C136C114A216A47968022
+6BB2:0148014CFAAA200827FE39484B68494A6B6A994C0B6C1148116A239A40268042
+6BB3:00000FE00820082008201020201EC0003FF010100820044003800C603018C006
+6BB4:00007EF840884488648854864900480055FC54846488405040207E5000880306
+6BB5:060038F82088208820883C86210020003DFC208420882C50F020205020882306
+6BB6:1000087800487F480848088608007EFC08440844082808280F10F02840440182
+6BB7:0600387820483E4822483E8622003EFC20443E442228222842104A2884440182
+6BB8:080008787F48084808483E8600003EFC2A442A443E2820282010402840448182
+6BB9:00007F78484848485F486486440044FC7F4444444A285128601040287E440182
+6BBA:040044782848104828484486920010FCFE441044582854289210122850442182
+6BBB:080008787F4808483E4800867F0041FC82443C44242824282510262844448182
+6BBC:080008787F4808483E4800867F0041FCBE4400443C2824282510262844448182
+6BBD:420024781848244852481086FF0020FC3E446244BE2822283E1022282A442582
+6BBE:100010787D4812481448FF86100020FC7E44A24422283E28221022283E442382
+6BBF:00003F78214821483F4820862A002AFC3F442A442A283F2820104A2891442182
+6BC0:2000CE7882488248EE4882868200FEFC10441044FE28102810101E28F0444182
+6BC1:2000CE7882488248EE4882868200FEFC00440044FE28102810101E28F0444182
+6BC2:1000FE7810487C480048FE86820010FC7C44204450287C281010FE2810441182
+6BC3:20001078FE4800487C4844867C0000FCFE448244BA28AA28BA1082288A448582
+6BC4:10007E7810487E4852487E8652007EFC1044FF4410287E28421042287E444382
+6BC5:100008787F4822481448FF86100029FCCE4414442628CD2815102428D4440982
+6BC6:0000FFB880289F28912891469F00807CBBA4AAA4AAA8AAA8BB908028FFC40082
+6BC7:1000673841287728412841467F00087C49242A24FFA81C282A10492888440882
+6BC8:2040CE9C8A94AA94AAD4EE94AAA6AAC0AA9CAA94EE94A8D42B884888489488A2
+6BC9:7F7848485F4C64805F784A4851307F4C00007FFC1110111029284544FFFE0000
+6BCA:0878FF4808863E782A483E3040489FF40200FFFE08203FF8D0161390129013B0
+6BCB:00001FF01110111011101110FFFE21102210221022103FFC0410081010A02040
+6BCC:00001FF011101110111011101110FFFE221022102210221022103FF000100010
+6BCD:00001FF01010121011101110FFFE20102210211021103FFC0010001000A00040
+6BCE:10001FFC200020005FF0911011101110FFFE2210221022103FFC001000A00040
+6BCF:10001FFC200020005FF0901012101110FFFE2010221021103FFC001000A00040
+6BD0:01000100FFFE01003FF800001FF011101110FFFE211022103FFC041008501020
+6BD1:00103E502250325C2A7422D42254FF544254525C4A5042507F420242143E0800
+6BD2:01003FF801001FF001007FFC00001FF012101110FFFE221021103FFC00100060
+6BD3:402040107DFE80207C48448465FE5402FEA844A8A4A894A8FEAA052A29261200
+6BD4:0080208020802084208820903EA020C0208020802080208226823882207E0000
+6BD5:2080208820B03EC0208020842684387C21000100FFFE01000100010001000100
+6BD6:2080208820B03EC0208020842684387C0100009048A4484289820E101810E7F0
+6BD7:001001107D1055125512551455D87D1055105510551055127D524592010E0000
+6BD8:00003FF8210821083FF8210821083FF80000208020843E9820E020842684387C
+6BD9:410041187DE041044D0470FC0000FFFE108010883E9042E0148008843084C07C
+6BDA:1FC020807FE0A0203FE020883CF420841FFC20407FF0A2103FF005441924E0FC
+6BDB:001001F87E000200020003F03E000200020003FCFE00020002040204020401FC
+6BDC:08201C207020102010A81CA47124112212221C20F02010A2104210020FFE0000
+6BDD:08041C08703011C010041C08703011C010041C08F03011C2100210020FFE0000
+6BDE:2080208820B03EC020842084267C380000F03F0001F03F0001F87F02010200FE
+6BDF:0100111011082124414401800E00F00000F03F0001F03F0001F87F02010200FE
+6BE0:080008007F7C094411441144257C420000F03F0001F03F0001F87F02010200FE
+6BE1:08401C407040107C10401C40704011F811081D08F10811FA110A10020FFE0000
+6BE2:10003BF8E0A020A023F83AA8E2A822A822B83B08E20823F8220A200220021FFE
+6BE3:00007EFC22441224060C1A3462C4000000F03F0001F03F0001F87F02010200FE
+6BE4:281824E04220923810E02020443CFEE002222422241E24002402440243FE8000
+6BE5:11003900E1FC220424043BE4E22423E422243A24E3E42004202A201220021FFE
+6BE6:0008FF1C44E0442044207C3C44E044207C20443C44E04F22F4220422041E0400
+6BE7:10503848E0402FFC20403A48E2482F5022503A20E2282468289A210A20021FFE
+6BE8:08201CA070FC112010201DFE7050105010901C92F112120E100010020FFE0000
+6BE9:08201C20712410A410A81C2073FE102010701CA8F1241222102010020FFE0000
+6BEA:10403840E090210823FC3824E12021FC21203A20E7FE20202022202220221FFE
+6BEB:01007FFC00001FF010101FF000007FFE400281F43E0003F03E0003FA7E0201FE
+6BEC:08201C28702413FE10201D2470A8107010A81D24F22210A0104010020FFE0000
+6BED:0008FF1C00E000207E20423C42E042207E20003C42E0222224220F22F01E4000
+6BEE:1020102011241122FA2A101014601B80303CD3C0107C13C0107C17C25042203E
+6BEF:10403A44E244244820A03910E608204420403A48E248245020A22112220A1FFE
+6BF0:08401C2071FC100010881C5073FE100010F81C88F088108A10FA10020FFE0000
+6BF1:11003900E1FC220424843C94E2A427FC208439C4E2A4249420AA209220021FFE
+6BF2:0004F70E117055102210551C897010100010F71E11705510221255128912100E
+6BF3:01F03E0003F03E0003FA7E0201FE0000183071C01C7871C01C7871C41444183C
+6BF4:10903890E090279E20903890E39C209020903890E79E20902092209220021FFE
+6BF5:0808101C24E07E201020FF3C24E042208920303CC4E008223222C422381EC000
+6BF6:08401C8871FC102413FE1C88713412C210181CE0F00C103011C010020FFE0000
+6BF7:00047F0E41705D1041105D1C417000103E10221E3E7022103E1222123E12220E
+6BF8:08001DFC712411FC11241DFC7020101411521D42F248103A100210020FFE0000
+6BF9:0804140E22704110BE90001C78F04A904A907A9E4AF04A907A9248924A92590E
+6BFA:10203850E088210426FA3800E3C4225423D43A54E3D42244225622CA20021FFE
+6BFB:1008101CFEE020207E20883C7EE000207E20423C7EE042227E2242224A1E4400
+6BFC:00087E1C42E07E2042207E3C20E07F209120513C69E041227D2201220A1E0400
+6BFD:10103810E77C211422FE3A14E77C2110217C3910E6FE2210251228FE20021FFE
+6BFE:00047F0E41707F1041107F1C0070F7901090949E52F03190D69210925292210E
+6BFF:1004220E7F7042109490F79C08703610C910309EC470191062120C123012C00E
+6C00:08047F0E4970FF9049107F1C08707F1049107F1E1070FF10211272120C12F30E
+6C01:11103910E7FC211023F83A08E3F8220823F83840E7FC20A02112220A20021FFE
+6C02:08203E7E08A47F281C102A2849443FFE200020782F8020F0278040FA4F82807E
+6C03:1004080E7F702210FF10001C7F7049107F10491E7F7008107F1208120F12F00E
+6C04:7E04140E0870FF1029104A1CA87010107F10551E63705D1055125D124112430E
+6C05:082049202A3E7F4841A85D2855105D2842F63F0001F03F0001F87F02010200FE
+6C06:11083890E3FC209022943998E09027FE200039F8E10821F8210A21FA20021FFE
+6C07:11003BF0E4102BF822483BF8E24827FC20003BF8E20823F8220A23FA20021FFE
+6C08:1008FE1C00E0FE208220BA3CAAE0FE2000207C3C44E07C2244227C22001EFE00
+6C09:00047F0E41707F100010F79C94F0F7900810081EFF701C102A1249128892080E
+6C0A:10203BFEE00023FC22043AF4E29423FC210839F8E10821F8200227FE20021FFE
+6C0B:2404FF0E2470FF1081107E1C0070FF101010289ED5702E10D5122492D412080E
+6C0C:108039F8E20825FC212439FCE12421FC21543AFAE08820F8208A20FA20021FFE
+6C0D:7704550E777055107710551C777022107F90A41E3F7024103F1224123F92200E
+6C0E:3F84248E3FF024907FD0555C7FF055507FD0041E7FF048501F122A1204127FCE
+6C0F:001000F83F802080208020803FFE208020802040204020222012280A30062002
+6C10:001000F83F802080208020803FFE208020802040204020222112288A30462042
+6C11:00003FF82008200820083FF8208020803FFC20802040204024242814300C2004
+6C12:00F03F00210021003FFC2080204028243114210C0100FFFE0100010001000100
+6C13:200013FC12040204FA0443FC4220422043FE4220422042107A12028A03060202
+6C14:100010003FFC20004FF080003FF000100010001000100010000A000A00060002
+6C15:100010003FFC20004FF080003FF000100410041004100410080A080A10062002
+6C16:100010003FFC20004FF080003FF000103F101110121017D0204A204A42868102
+6C17:100010003FFC20004FF080003FF00010009030900D100210050A188A60460002
+6C18:100010003FFC20004FF080003FF000100010111011101110210A210A41068102
+6C19:100010003FFC20004FF080003FF000100410041044504450444A7FCA00460002
+6C1A:100010003FFC20004FF080003FF000102490249024902490248A448A44868082
+6C1B:20003FFC40009FF000007FF00010121021104090BF501112110A110A25064202
+6C1C:20003FFC40009FF000007FF000103F90209020903F902092208A208A3F862082
+6C1D:100010003FFC20004FF080003FF0041004107FD044504A50514A604A41464082
+6C1E:20003FFC40009FF000007FF000107FD004107FD044504A52514A604A41464082
+6C1F:20003FFC40009FF000007FF012107F9012907F9052107FD2124A134A22864202
+6C20:20003FFC40009FF000007FF0041004107FD044507FD044527FCA444A04060402
+6C21:20003FFC40009FF000007FF010101F90209051100E103192CC6A030A1C060302
+6C22:20003FFC40009FF000007FF000103FD003100CD070301FD2020A020A7FF60002
+6C23:100010003FFC20004FF080003FF00410249015107FD00E10150A248A44460402
+6C24:20003FFC40009FF000007FF000107FD0445044505F5044524A4A514A7FC64042
+6C25:20003FFC40009FF000007FF000107FD00A103F902A902A92338A208A3F862082
+6C26:20003FFC40009FF000007FF004107FD0081011103E100492190A620A0D063082
+6C27:20003FFC40009FF000007FF011100A107FD004103F900412FFEA040A04060402
+6C28:20003FFC40009FF000007FF004107FD040500810FFD01112320A0C0A1B066082
+6C29:20003FFC40009FF000007FF000107F901210125092905312520A120AFFC60002
+6C2A:20003FFC40009FF000007FF004107FD004103F9020903F920A0A124A224641C2
+6C2B:20003FFC40009FF000007FF000107FD02490491024907FD2040A040AFFE60002
+6C2C:20003FFC40009FF000007FF00010FFD01210739040904092738A120A1206FFE2
+6C2D:20003FFC40009FF000007FF004107FD004103F9024903F92248A3F8A15062482
+6C2E:20003FFC40009FF000007FF0041024900B10109060500412248A0B0A10866042
+6C2F:20003FFC40009FF000007FF000107F9000903F900090FFF2248A150A24864C42
+6C30:20003FFC40009FF000007FF004107FD004103F900410FFF2208A3F8A20862182
+6C31:20003FFC40009FF000007FF010901F9010903FF010103FD24A4A124A25460882
+6C32:20003FFC40009FF000007FF000103F9020903F9020903F92000A7FCA4A46FFE2
+6C33:20003FFC40009FF000007FF000103F9024902A903F9000127FCA4A4A4A46FFE2
+6C34:010001000100010801087D9005A0094009401120111021084106810005000200
+6C35:0000200010001000800040004800080010001000E00020002000200020000000
+6C36:00003FF000200040008401087D9005A005400940092011102108C10605000200
+6C37:0100010011000908090801907DA005400940092011102108C106010005000200
+6C38:0200010000801F00010401087D9005A005400940092011102108C10605000200
+6C39:00400040F84008440F480950116012502248244448444140408240023FFE0000
+6C3A:01000100010041082108111011200180054009201110E1084104010005000200
+6C3B:008020801080108087FC40844884088410841084E10421042104220422280410
+6C3C:010001047D880550092011102108C5060200010001000280044008203018C006
+6C3D:01000280044008203118C10601003D8405880950092011102108C10605000200
+6C3E:000023F812081208820842084A080A0812501220E20022022202220221FE0000
+6C3F:010021001100110087F041104910091011101110E110221222122412280E1000
+6C40:0000200013FE1020802040204820082010201020E02020202020202020A00040
+6C41:00402040104010408040404047FE104010402040E04020402040204020400040
+6C42:0120011001007FFC01002108111009A003400520091011086106010005000200
+6C43:0000202011201120812041204920092011201110E11022102208240828041002
+6C44:0040204010401040804040404840084010A010A0E0A021102110220824040802
+6C45:000027FE10801080810041004A000BF810081008E00820082008200820500020
+6C46:0600010002800C603118C10601003D8405880950092011102108C10605000200
+6C47:000023FE12001200820042004A000A0012001200E20022002200220023FE0000
+6C48:000027FC10041004800440144824084410841104E60420042004200420280010
+6C49:000027F812081208820841104910091010A010A0E040204020A0211022080C06
+6C4A:000027F812081288824841504910091010A010A0E040204020A0211022080C06
+6C4B:00802080110011FC820442045404190410842044E04420042004200420280010
+6C4C:0204224412441244824442444244124412442244E24422442244244424040804
+6C4D:008020801080108087F0409048900A9011901090E1502152220A220A24060802
+6C4E:000023F012101210821043105290125012502210E210221224122412280E1000
+6C4F:0040204010401040804047FE4840084010A010A0E0A021102110220824040802
+6C50:00802080108010FC810441044284144810282010E01020202040208021000600
+6C51:0010207813C01040804040404840087E17C01040E040204220422042203E0000
+6C52:004020201020100087FE41004900090011001100E10021002100210021FC0000
+6C53:000023F8100810108020404048400FFE10401040E04020402040204021400080
+6C54:00802080110011FE8200440041F8100810102060E08021002202220221FE0000
+6C55:0040204010401040844444444444144414442444E4442444244427FC20040000
+6C56:010001002108210821083FF80000010001047D880550092011102108C5060200
+6C57:0000200013FC1040804040404840084017FE1040E04020402040204020400040
+6C58:0010207813C010408040404048400FFE10401040E04020402040204020400040
+6C59:000021FC102010208020402048200BFE10201020E02020202020202020A00040
+6C5A:000023F810401040804047FE48800880110011F8E00820082008200820500020
+6C5B:000027F01110111081104110411017D011102110E1102112210A210A21060102
+6C5C:000023F812081208820842084A080BF812001200E20022022202220221FE0000
+6C5D:00802080108010808FFE41084108120812102610E1A0204020A0211022080C04
+6C5E:00003FF8010001000100FFFE0000010001047D880550092011102108C5060200
+6C5F:0000200017FC1040804040404840084010401040E040204020402FFE20000000
+6C60:0040204012401258826842C853481E4812482248E25822422202220221FE0000
+6C61:000023F810001000800047FE40801080110021F8E00820082008200820500020
+6C62:00402040104010408040404047FC104010402040E0402040204020402FFE0000
+6C63:00802080108010F88108410849100A1010201020E05020502088210822040402
+6C64:000023F0102010408080410043FC112411242124E22422442444288421280210
+6C65:00402040104017FE80404040404017FC12042208E11020A0204020A023180C06
+6C66:0008203C13E01220822042204A200BFE12201210E2102212220A228A23060202
+6C67:000027FC111011108110411049100FFE11101110E11021102110211022100410
+6C68:000023FC12041204820442044A040BFC12041204E2042204220423FC22040000
+6C69:0000200017FC140484044404440417F414042404E4042404240427FC24040000
+6C6A:000027FC1040104080404040404013FC10402040E0402040204020402FFE0000
+6C6B:011021101110111087FC41104110111011102FFEE11021102110221022100410
+6C6C:082008207FFC08200820FFFE10202020412001047D88095011202118C5060200
+6C6D:002020201020102083FE42224A220A221252124AE28A230222022202220A0204
+6C6E:0100410021FC2204020485044884408410142024E04423842104200420280010
+6C6F:0080408020802FFE008080804120512011202240E2402488248829FC20840004
+6C70:004020401040104087FE4040484008A010A010A0E11021102288224824440802
+6C71:0040205010481048804047FE4840084010A010A0E0A021102110220824040802
+6C72:000027F81108111081104120493C090411041288E28822502420245028880306
+6C73:0008203C13C01200820042004BF80A8812881288E25022502220245024880906
+6C74:008020401040100087FE4080488008C010A01090E08820882080208020800080
+6C75:0040204010A010A0811042884C460840100013F8E00820102010202020200040
+6C76:00802040104017FC8110411049100910111010A0E0A0204020A0211022080C06
+6C77:008020801080108081F841084A080D10111010A0E0A0204020A0211022080406
+6C78:00802040104017FE81004100490009F811081108E10821082208220824500820
+6C79:0000200811081088825242524A220A2212521292E30A220A220223FE20020000
+6C7A:00802080108017F8808840884888088817FE1080E14021402220241028081006
+6C7B:00802080108011FC812041204A200820102017FEE02020202020202020200020
+6C7C:002020201120112081FC422042201420102027FEE02020202020202020200020
+6C7D:0100210011FC1200840041F84800080013F81008E0082008200A200A20060002
+6C7E:001021101110120882084404580213F811082108E10821082208220824500820
+6C7F:000023F81008111080A0404047FE104210442040E04020402040204021400080
+6C80:0800087C080409280910EA082CFE2A1229144910489088900810081028501020
+6C81:0000208010401020812041004100150415022502E50229082108210820F80000
+6C82:0008203C13C012008200420043FE121012102210E21022102210241024100810
+6C83:0010207817C0104080404040404017FE104020A0E0A021102110220824040802
+6C84:0000200013FC10008000400047FE104010402080E0802108220427FE22020000
+6C85:0000200013F810008000400047FC112011202120E120212022222222241E0800
+6C86:00802040104017FC8000400049F0091011101110E110211222122212240E0800
+6C87:0080208011001110820847FC4004112011202120E120212022222222241E0800
+6C88:00402040104017FE84444848404010A010A020A0E120212022222222241E0800
+6C89:0000200013FE12028404400041F0111011102110E110211222122212240E0800
+6C8A:1020102010207E2453A894B010A8112429222A222C2028A22842480247FE8000
+6C8B:009020881088108087FE40A048A008A010A010A0E120212221222222221E0400
+6C8C:00402040104017FC804042484A480A48124813F8E048204020422042203E0000
+6C8D:000027FE10801080808040F84908090811081208E3F820102010201027FE0000
+6C8E:01202120112012248224462856301A20126022A0E220222222222222221E0200
+6C8F:0000220012FC12248224422453A41E2412242224E2A423242244204420940108
+6C90:004020401040104087FE404048E008E011501150E24824442842204020400040
+6C91:000023F8108810888088408848880BF811081108E1082108210821082FFE0000
+6C92:0080208010FC11048104422848100BFC11041088E08820502020205021880606
+6C93:010001087D1005A009603118C50602001FF0101010101FF0101010101FF01010
+6C94:000027FE104010408240427C4A440A44124413FCE00420042004200420280010
+6C95:01002100110011FC82A444A440A4112411242244E44420842104220424280010
+6C96:004020401040104087FC44444444144414442444E7FC24442040204020400040
+6C97:00003FF801000100FFFE028004401830E10E11100B2005C01930610805000200
+6C98:0020222012201222822242244BA80A3012201220E220222222A22322221E0000
+6C99:0040204010401148814442424242144810482048E01020102020204021800600
+6C9A:0040204010401040824042404A7C0A4012401240E2402240224022402FFE0000
+6C9B:0040404020402FFE0040804047FC544414442444E44424542448204020400040
+6C9C:0010221012101210821043FE4A000A00120013F8E20822082208240824080808
+6C9D:0820082008200A200A32EDB228B42CA82AA82AA8492449248A22082028A01040
+6C9E:00004FFE20402040004087FC4444544414442444E44424542448204020400040
+6C9F:01002100110011FC820444844084110411442224E7F422142004200420280010
+6CA0:0008203C17D01490849044904490149014902488E48824882484288428821000
+6CA1:000021F01110111081104210540E180013F82208E108211020A0204021B00E0E
+6CA2:000021FC110411048104410449FC092411201120E11021102208220824040802
+6CA3:00202020102013FE80204020482009FC10201020E02027FE2020202020200020
+6CA4:000023FC12001208828842504A500A2012201250E25022882308220023FE0000
+6CA5:000023FE12001220822042204AFC0A2412241224E24422442484248429281210
+6CA6:0040204010A010A0811042084406111011202140E18021002104210420FC0000
+6CA7:0040404020A02110020884044BF2421012102210E25022202204220421FC0000
+6CA8:000023F812081208832842A84AA80A48124812A8E2A8232A240A240A28061002
+6CA9:0040224011401140804047FC40441044108420A4E09421142104220424280810
+6CAA:00802040104013FC82044204420413FC12042200E20022002400240028001000
+6CAB:00402040104017FE8040404048400BFC104010E0E15022482446284020400040
+6CAC:00402040104013FC8040404048400FFE10E01150E15022482444284220400040
+6CAD:004020501048104087FC404040E010E011502150E24824442842204020400040
+6CAE:000023F812081208820843F84A080A08120813F8E2082208220822082FFE0000
+6CAF:010001087D1005A009603118C50602007FFC040008001FF82808C8080FF80808
+6CB0:0000200017FE104080404080488009F813081508E90821082108210821F80108
+6CB1:00802040104017FC840448084200121012202240E38022042204220421FC0000
+6CB2:0100210013FC120084404840427812C813482E48E248225A2242220221FE0000
+6CB3:0000200017FE1008800843C84248124812482248E3C822482008200820280010
+6CB4:0040204010A01110820844264040108013102020E04020882310202020C00700
+6CB5:00802080108011FE810242045420102011282124E22422222422202020A00040
+6CB6:000023FC10001000800040004FFE104010402248E24424442442284221400080
+6CB7:009020881088108087FE4080490009FC11441244E24824502420285020880306
+6CB8:01202120112017F88128412847F81520152027FCE12421242234222824200820
+6CB9:004020401040104087FC444444441444144427FCE44424442444244427FC0404
+6CBA:000027FC1444144484444444444417FC14442444E4442444244427FC24040000
+6CBB:0040204010801110820847FC4004100013F82208E20822082208220823F80208
+6CBC:000027FC108410848084410441141208140023FCE20422042204220423FC0204
+6CBD:004020401040104087FE40404840084013F81208E20822082208220823F80208
+6CBE:004020401040107E804040404840084013FC1204E20422042204220423FC0204
+6CBF:000021F01110111081104110420E1400100023F8E20822082208220823F80208
+6CC0:000023FC1004100487F4400448040BE412241224E22423E42004200420140008
+6CC1:000027F8140814088408440847F8112011202120E120222022222422281E1000
+6CC2:000023FC12041204820442F44A940A9412941294E2F422942204220422140208
+6CC3:01002100120013FC8404480443E4122412242224E22423E42224200420280010
+6CC4:004822481248124882484FFE4248124812482248E27822002200220023FE0000
+6CC5:000027FC140414448444444444441444144424A4E49425142604240427FC0404
+6CC6:004020401240124083FC42404440104017FE2040E0A020A02110220824040802
+6CC7:020022001200121E87D242524A520A5212521252E25222522452245E29521080
+6CC8:0080208010F81108831044A0404010A013182C06E0C020202010218020600010
+6CC9:010002001FF0101010101FF0101010101FF001047D88095011202118C5060200
+6CCA:00402040108013FC820442044A040A0413FC1204E20422042204220423FC0204
+6CCB:00402040104017FC804040404150111011102FFEE11021102210221024100810
+6CCC:0000208010401028812841084110151415222522E54229882108230824F80800
+6CCD:004020401040104087FC404048E008E011501150E24825F42842204020400040
+6CCE:01002100110011FE82804280448010F810802080E08020FC2080208020800080
+6CCF:0040204012481248824842484BF8084810401040E44424442444244427FC0004
+6CD0:0010479024902510057E86124512549214922492E692251224222422244A0484
+6CD1:0220422022202420057C89244E24422414242424E9242F242144204420940108
+6CD2:0008203C13D01290829042904A900A9012901288E28822C822A424D424920800
+6CD3:0008278810881088808847884408141014102790E09420A420A220BE25020200
+6CD4:010821081108110887FE410841081108110821F8E10821082108210821F80108
+6CD5:004020401040104087FC4040404010401FFE2040E0802100221024082FFC0404
+6CD6:00002100163C14A484A444A444A414A414A425A4E6B424A82120212022200420
+6CD7:0000200017FC14A484A444A444A414A414A42524E51C26042404240427FC0404
+6CD8:0010207817C01040844442444248104017FE2040E04020402040204021400080
+6CD9:000023F810401040824841484950084017FE1040E04020402040204020400040
+6CDA:0120212011201524852445E84530152015202520E520252225E22E22241E0000
+6CDB:00102078178010008080404047F8101010202040E08021002200250028FC0000
+6CDC:0008203C13E01220822042204A200BFE12201210E2102212220A228A23260212
+6CDD:0008203C13C01200820042004BFE0A1012101270E21022182214241024100810
+6CDE:00802040104017FC840448084000100017FC2040E04020402040204021400080
+6CDF:000027FC10401040804040404A400A7812401240E2402240224022402FFE0000
+6CE0:0040204010A010A0811042484426102013F82008E010211020A0204020200020
+6CE1:0100210011FC1204820447E44A241224122423E4E21422082202220221FE0000
+6CE2:00202020102013FE822242244A200BFC12841288E24822502220245024880906
+6CE3:008020401040100087FC40004008120812082110E1102110212020202FFE0000
+6CE4:0008210810881448844844084408140814102410E41025282624244420820102
+6CE5:000023FC12041204820443FC4A000A4012441248E270224024422442283E1000
+6CE6:000023FC1204120483FC42404A400A4013F81248E24822482488248A290A0206
+6CE7:002820241024102083FE42204A240A2412241228E22822902312222A20460082
+6CE8:00802040100017FC804040404040104013FC2040E0402040204020402FFE0000
+6CE9:004022401240124083FC444054401840104023FCE0402040204020402FFE0000
+6CEA:000023FC12041204820443FC4A040A04120413FCE20422042204220423FC0204
+6CEB:00802040104017FE804040804108121017E02040E0802108220427FE22020000
+6CEC:00402020102013FE820244044000109010902090E08821082108210422040402
+6CED:010821081108120882FE46084A08120812882248E24822082208220822280210
+6CEE:0040204012481148815040404BF8084010401040E7FC20402040204020400040
+6CEF:000023FC12041204820443FC4A200A2013FE1220E22022102212228A23060202
+6CF0:010001007FFC01003FF80200FFFE044009203118CB2605C01930610805000200
+6CF1:00402040104013F8824842484A480A48124817FEE04020A020A0211022080406
+6CF2:00402040105C13E0824042404A400BFC104410C4E14422542C48204020400040
+6CF3:00802040102013C0804440444F48115011602160E25024482844304221400080
+6CF4:010001087D1005A009603118C506020000003FF82448244824482448FFFE0000
+6CF5:0000FFFE040008001FF02810C8100FF0010001047D88095011202118C5060200
+6CF6:22081108111000207FFE40028004010001047D880550092011102108C5060200
+6CF7:012021101110110087FE41404940094811481250E2502262244224C2293E1000
+6CF8:00402040107E1040804043FC4A040A04120413FCE20422002200240024000800
+6CF9:000023F812081208820842084BF80A0812081208E20823F8200020002FFE0000
+6CFA:0008203C17C0140084404440444017FE10402040E24822442442284221400080
+6CFB:000027FE14021904810041FC49000A0013FC1004E00427F42004200420280010
+6CFC:004020481244124083FE4080488008FC11441144E14822502220245028880306
+6CFD:000027F81208111080A0404041B0164E104023F8E040204027FC204020400040
+6CFE:000027F8101010208060409841041602100023FCE04020402040204027FE0000
+6CFF:000023F81208120883F842084A080BF812441248E23022202210228823060200
+6D00:0080210013F812088288424842481FFE12082288E24822482208220824280810
+6D01:0040404020402FFE0040804047FC5000100023F8E20822082208220823F80208
+6D02:00402020102017FE8090409048900A9412921292E49220902110211022500420
+6D03:00802080108017FE810041204A200AA414A41528EA5020502088210822040402
+6D04:000027FE1402140284F244924492149214922492E4F224922402240227FE0402
+6D05:000027FC1040104083F842484A480BF812481248EFFE22082208220822280210
+6D06:000023F810101020804447644168115012502248E4442942208020002FFE0000
+6D07:000027FC140414448444444447FC1444144424A4E49425142604240427FC0404
+6D08:0100210013F8120884104BFE420012F812882288E2A8229022822482247E0800
+6D09:0008203C13C01200820043FE4A000A00120012FCE28422842484248428FC0084
+6D0A:00402040104017FE80804080497C090813101510E1FE21102110211021500120
+6D0B:020821081110100087FC4040404013F810402040E7FE20402040204020400040
+6D0C:000240022FC22212021283D24252545216522552E892209221022202240A0804
+6D0D:000027FE14201420842044F84488148814882488E4F824202420242027FE0000
+6D0E:0040208013FC1204820442044BFC0A0412041204E3FC22042204220423FC0204
+6D0F:00002FFE10401040808047FC44A414A414A424A4E4A424A424A4248424140408
+6D10:00802080113C120084804080497E0B0815081108E10821082108210821280110
+6D11:0120412821242224022086204AFC422012202250E25022502288228823040202
+6D12:00002FFE10A010A087FC44A444A414A414A424A4E51C26042404240427FC0404
+6D13:0040204017FC1040804043F84A480A4812481258E0E0215022482C4620400040
+6D14:00402040104013FC8040404047FE1010101027FEE01022102110211020500020
+6D15:001021101108120884044BFA4208120813F82208E20823F82208220822280210
+6D16:000023F81208120883F84000400017FC10402040EFFE204020A0211022080C06
+6D17:00402240124013FC84404840404017FE11202120E120212022222222241E0800
+6D18:0080208813E8109080A047FE4880090013FC1480E90021F82008200820500020
+6D19:00402240124013FC84404040404017FE10E02150E15022482444284220400040
+6D1A:0100210011F8131084A0404051B0164E104023FCE040244027FE204020400040
+6D1B:0080208011F81208851040A0404010A013182C06E3F822082208220823F80208
+6D1C:08001FF0282007C01830E00E1FF010101FF001047D88095011202118C5060200
+6D1D:00802040104017FC84044888408017FC11102110E21021A0204020A021100608
+6D1E:000027FC1404140485F44404440415F415142514E51425F42404240424140408
+6D1F:0040204017FE104087FC404443FC1240144027FEE04220AA20A4211022080C06
+6D20:004020401090110883FC40244920092011FC1220E02027FE2020202020200020
+6D21:0040204017FC1040804043F84840084017FE10E0E15021502248244428420040
+6D22:0100217C11241224822446FE4A2412241224227CE22422202220222022400280
+6D23:00402040124811488150404047FE104010E02150E15022482444284220400040
+6D24:0040204010A011108208440643F8104010402040E3F820402040204027FE0000
+6D25:0040204013F8104887FE40484BF80840104013F8E040204027FC204020400040
+6D26:000027FE10201020804043FC4A040A04120413FCE20422042204220423FC0204
+6D27:0040204017FE1080810041FC4304150419FC2104E10421FC2104210421140108
+6D28:00802040104017FC800041104208140411102110E0A0204020A0211022080C06
+6D29:00402040104017FC8444444447FC1444144427FCE02820122032204A21860E02
+6D2A:011021101110111087FC41104110111011102FFEE00021102108220824040804
+6D2B:004020401080110083FC42944A940A9412941294E2942294229422942FFE0000
+6D2C:000027F81408140887F84488448814E815282528E6A8244A244A288A29061202
+6D2D:000023FE1200120083FC42204A200AF812201220E22023FC2200220023FE0000
+6D2E:0090209010901492829440984090119812942492E0902090211221122212040E
+6D2F:080008007F7C08243E2408447F540888090001047D88095011202118C5060200
+6D30:000023FE12001200820043FC4A040A0412041204E3FC22002200220023FE0000
+6D31:000027FC1208120883F84208420813F812082208E20E23F82E08200820080008
+6D32:01042124112411248124412445B4156C19242124E12421242124222422040404
+6D33:010021001100111E87D242524252125212522492E29221122292225E24520800
+6D34:020821081110100087FC41104110111011102FFEE11021102210221024100810
+6D35:00802080110011FC8204440443E41224122423E4E224222423E4200420280010
+6D36:02002200120013FC840444044A24114414942554E634241427F4200420280010
+6D37:000027FE104010808110420847FC104410402040E7FC2040204020402FFE0000
+6D38:008020881488129082A040804FFC112011202120E120212422242224241C0800
+6D39:000027FC1000100083F84208420813F812082208E3F82208200020002FFE0000
+6D3A:0080208010FC1104828844504020104011FC2304ED0421042104210421FC0104
+6D3B:0010207813C01040804047FE40401040104023F8E20822082208220823F80208
+6D3C:0040204013F810408040404047FC100010402040E3F820402040204027FC0000
+6D3D:0040204010A011108208440643F81000100023F8E20822082208220823F80208
+6D3E:0008203C17C01400841C45E04520152215242528E51025102508294429821100
+6D3F:0040204017FC10A0811042084DF6100017FC2080E10023F82008200820500020
+6D40:005020501050105083FE42524A520A52125213FEE25222522252225223FE0202
+6D41:0080204017FE10808110420847FC100410002248E24822482248224A244A0846
+6D42:020821081110100083FC40404840084017FE1040E04020A020A0211022080406
+6D43:00402040104017FC80404248515010401FFE20A0E0A021102110220824040802
+6D44:0100210013F0121084204BFC4044104417FE2044E04423FC2044204021400080
+6D45:00A02090108010B887C0408040BC17C010882090E060204420A42114260C0004
+6D46:0840484028FC09041A8828504860898001047D880550092011102108C5060200
+6D47:0080208010BC13C08050402448D40B0C100017FEE090209021122112220E0400
+6D48:00402040107E1040804043F84A080A4812481248E248224820A0211022080404
+6D49:010021FE11101510857C45544554155415542554E5542154225C221024100810
+6D4A:00402040104017FC844444444444144417FC2444E040204820442FFE24020000
+6D4B:000427C414441454855445544554155415542554E55421042284224424140808
+6D4C:01202128112412248220463E4BE0122412242228E22822102212222A22460282
+6D4D:0040204010A011108208440641F01000100027FCE04020802110220827FC0204
+6D4E:0080204017FE1208811040A0404011B0160E2110E11021102110221022100410
+6D4F:0204410421042FE4009484944294529411142114E29422942444284430140008
+6D50:0040202013FC1000810840904BFE0A0012001200E20022002200240024000800
+6D51:000023FE12021444804043FC488008A0112011FCE020202027FE202020200020
+6D52:004044402240227C005080904E10521012FE2210E21022902310221020100010
+6D53:00402040104017FC848448884140114413482530E92021102108214421820100
+6D54:000027F81008100883F84008400817F810102010EFFE22102110211020500020
+6D55:000023F81208120883F842204A200A10120814C6E420280021C0203020080000
+6D56:0010207817801088844842504200102017FC2020E22021202120202020A00040
+6D57:005020481048104087FE40404A440964116810D0E15022482444204221400080
+6D58:000023FC1204120483FC42004A180AE0123812E0E23C23E022222422241E0800
+6D59:0208421C226022400FC08240427E52C813482E48E2482248224822482A880508
+6D5A:008020801110120887FC400441101288148421F0E31024A0204020A023100C0C
+6D5B:0040204010A011108288444641F0101010202040E3F822082208220823F80208
+6D5C:0010203813C01200820043FC4220122012202220EFFE20002120221024080804
+6D5D:01102108110017FE814841504964094811501264E24822522462244229BE1000
+6D5E:000023F8120812088208420843F8104010402240E27C22402240254028FE1000
+6D5F:0210221012101420853E4D444DA4152415282528E51025102428242824440482
+6D60:0208211010E01110820840804FFE1140124027FCEA4422442254224820400040
+6D61:0040204013FC1040804047FE5402180411F02010E0202FFE2040204021400080
+6D62:000027FC1000100083F842084A080A08120813F8E0002208210821102FFE0000
+6D63:0080204017FC1404880843F04000100017FC2120E120212022242224241C0800
+6D64:0040202013FE1202844440404BFE084010901090E11021202224224224FE0842
+6D65:000023F81208120883F8400047FC144414442444E7FC24002402240223FE0000
+6D66:004840442FFE2040004087FC4444544417FC2444E44427FC2444244424540408
+6D67:000023F812081208820843F84800080017FC1040E04023F8204020402FFE0000
+6D68:0080204017FE140288444040404017FC10E02150E15022482444284220400040
+6D69:00402240124013FC84404840404017FE10002000E3F822082208220823F80208
+6D6A:0080204013F81208820843F84A080A0813F81240E24422282210228823060200
+6D6B:000047FE240229140208840443F8504010402040E7FC20402040204020400040
+6D6C:000027FC1444144487FC4444444417FC10402040E7FC2040204020402FFE0000
+6D6D:00002FFE104017FC8444444447FC1444144427FCE24021402080214022300C0E
+6D6E:0008203C13C010048244412848000BF810101020E7FE20202020202020A00040
+6D6F:000027FC1040104083F84088408817FE10002000E3F822082208220823F80208
+6D70:008421C417041114811441144FD4111413142394E55425042904210421140108
+6D71:000023FC1200120082F842004A000BFC12A012A4E2A822902290248824A408C2
+6D72:010021F813081490806041984646104013F82040E3F8204027FC204020400040
+6D73:0088208410BE17C08032400E48000BFC120413FCE20423FC2204220422140208
+6D74:0110210812041444804040A041101208140623F8E20822082208220823F80208
+6D75:000227821484148886904582448214841FC82490E482248224842488289011A0
+6D76:0040202013FE12028424412049FC092012201020E7FE20202020202020200020
+6D77:0100210011FC120085F841084948092817FE1108E248222823FC200820500020
+6D78:000023F8100811F8800843F8400017FC140423F0E110211020A0204021B0060E
+6D79:00402040104017FE8040424842481248155428A2E0A021102110220824040802
+6D7A:010821081108113E81AA456A452A152A192A213EE12A21082108210821080108
+6D7B:000027FC140414A48514460C540415F415142514E51425F42514240424140408
+6D7C:0100210011F01210822047FC4A441244124423FCE2A420A0212022222422081E
+6D7D:0008203C13C01044822441284900084013FE1088E10823902060205021880604
+6D7E:0040204013FC10408040404047FE109012942292E49229122110221024500820
+6D7F:000023FC1204120483FC42044A040BFC12041204E3FC20002110210822040404
+6D80:000023F81208120883F84208420813F812082208E3F82120212022222422181E
+6D81:01022102110411088FD041024302138415482550E90221022104210821100160
+6D82:0040204010A01110820845F64040104017FC2040E25022482444284421400080
+6D83:000027FC14441444844447FC444414C414E42554E64424442444240427FC0404
+6D84:0040204017FC144487FC444447FC10001FFE2100E20023FC2004200420280010
+6D85:000027FC1404140487FC4404440417FC10402040E7FC2040204020402FFE0000
+6D86:0000203E1788148884884488448817BE14882488E48824882788248820080008
+6D87:000023FC100011248248449052481124100023FCE04020402040204027FE0000
+6D88:0040224811481150804043F84A080A0813F81208E20823F82208220822280210
+6D89:002020201120113C8120412047FE100010202124E12422282410202020C00700
+6D8A:000023FC10441144814442844894090812401020E0A42282228A228A24780000
+6D8B:0040202013FE1202840440504048104017FE2040E0A020A02110211022080406
+6D8C:000027F8101011A0804047FC4444144417FC2444E44427FC2444244424540408
+6D8D:0040204413F41048804847FE4020104013F82110E22025FE2820202020A00040
+6D8E:0008201C1770111081104250425C175011502550E550227C2200250028FE1000
+6D8F:0000200C1770111081104210427C171011102510E510227C2200250028FE1000
+6D90:012043A82E24222402209FFE4220522412A42328E2282E102232224A2A860402
+6D91:004040402FFE2040004087FC4444544417FC2040E0E0215022482C4620400040
+6D92:000023F81088108887FE408848880BF811001100E3F825082908210821F80108
+6D93:000021F81108110881F840004BFC0A04120413FCE204220423FC220422140208
+6D94:004022481248124883F8404048A0091012881446E04023F02010202020200040
+6D95:02102110112017F88048404847F81440144027FCE0C421442254244828400040
+6D96:012021101110120082FE460056041A8412842248E24822482250221022FE0200
+6D97:0010209010881108820445FA41081108110821F8E0902090209021122212040E
+6D98:004020801110120887FC4104410013F814402040EFFE204020A0211022080C06
+6D99:0040202013FC1204820443FC4A000A20122013FEE22022502250248825040A02
+6D9A:020821081110102083F842084A080A0813F810A0E0A0212021222222241E0800
+6D9B:0040204017FC104083F8408047FE1090111021FEE21022902450281020500020
+6D9C:0020202013FE102081FC40004BFE0A0214041090E0902090209021122112020E
+6D9D:0108210817FE1108800047FE54021884108027FCE08421042104220424280810
+6D9E:00402040104017FC804042484148115017FE20E0E15021502248244428420040
+6D9F:00202420122012FE804040504E9012FE12102210E3FE22102210251028FE0000
+6DA0:000027FC1444144485F4444444E4144415F42454E45424742444244427FC0404
+6DA1:000023F812081208820843F84040104017FC2444E4A425142614240424140408
+6DA2:000023F81208120883F84000400017FC14042444E444244424B4210826041802
+6DA3:0100210011F0121084204BF84248124812482248EFFE20A020A0211022080C06
+6DA4:0080208011F813088490406041981646104027FCE04022482244244421400080
+6DA5:008040402FFE200003F88208420853F8100023F8E01020602040204021400080
+6DA6:0200217C1504140485F444444444144415F42444E444244425F4240424140408
+6DA7:0200217C15041404840445F44514151415F42514E51425F42404240424140408
+6DA8:00404F442144214801488F50484058FE18502F50E1482148214421442A620440
+6DA9:000023FC10441244824444844094110812202020E13C21202120212027FE0000
+6DAA:0080204013FC100082084108411017FE10002000E3FC22042204220423FC0204
+6DAB:0080404027FE2402080483F84208520813F82200E20023FC2204220423FC0204
+6DAC:0040204017FC104080404FFE411010A017FC2040E0402FFE2040204020400040
+6DAD:001C23E0108412448148411057FE1402100023F8E108211020A0204021B0060E
+6DAE:000247E22422242A07EA848A448A548A17EA26AAE6AA2AAA2AA232E2208A0084
+6DAF:000027FE1420142085FC4420442017FE14002420E42025FC242028202BFE1000
+6DB0:000027BC108412948108429454A41840100027BCE0A422A42128229024A80846
+6DB1:000021FC110011F8810041F851001FFE12802248E25022202210228823060200
+6DB2:0080204017FE11208120423C4244166412942348E24822302220225022880306
+6DB3:00402020102013FE8202449441081204100021FCE02020202020202027FE0000
+6DB4:0080404027FE24020A04820043BC54A414A426A4E9342128222222222422081E
+6DB5:000023F8101010208444455444E4144414E42554E64C25442484240427FC0004
+6DB6:0010207813C01040804047FC424812481FFE2248E24827FC2040204027FC0000
+6DB7:0040204017FC104083F842484BF80A4813F81040E0E0215022482C4620400040
+6DB8:000027FC1444144487FC4444444415F415142514E51425F42514240427FC0404
+6DB9:003823C01040104087FC415042481486108027FCE110221021A0206020900308
+6DBA:000023FC1204120483FC42204A200BFE12201220E2FC22842284248424FC0884
+6DBB:0040204010A01110820845F64040104017FC2040E04023F82208220823F80208
+6DBC:0080204017FE1000800043F84A080A0813F81040E25022482444284421400080
+6DBD:001C23E0122013FE822042924B0A0A0611FC1104E10421FC2104210421FC0104
+6DBE:0040204417681150815042484544108013F82208E20823F82208220823F80208
+6DBF:00004FFE20802184024484684AB0413012A82468E8A421242222242020A00040
+6DC0:0040202013FE12028404400043FE102010202120E13C212022A02260243E0800
+6DC1:0080204013FC10008108409047FE1040104027FEE08821082090206021980604
+6DC2:000023F8120813F8820843F848000BFC101017FEE01022102110201020500020
+6DC3:00402248115017FC808041004FFE121014082BF4F212221022502224220401FC
+6DC4:0124212412481490824841244124100017FC2444E44427FC2444244427FC0404
+6DC5:0200420C227022400F408240427E564817482AC8EA4832482248224822480288
+6DC6:0210212010C013308C8840804FFE110013F82608EBF8220823F8220822280210
+6DC7:0108210817FE1108810841F84908090811F81108E10827FE2000209021080204
+6DC8:000023FE1202120283FE42104A920A92129212FEE21022922292249224FE0802
+6DC9:000023F81248124883F842484A480BF8104017FCE0E021502248244620400040
+6DCA:0100210011F81208841048204180163C14042404E7BC24042404240427FC0404
+6DCB:011021101110111087BC41104110133813B82554E55429922110211021100110
+6DCC:0040224811481150804047FC4404140415F42514E514251425F4240424140408
+6DCD:000027FC1444144485F44444444417FC140425F4E514251425F4240424140808
+6DCE:0040204017FC104083F8408047FC111012482446E1F0204027FC204020400040
+6DCF:000023FC120413FC820443FC48000BFC10401040E7FE204020A0211022080406
+6DD0:03F82208120813F88208420843F8100017FC2404E40427FC2404240427FC0404
+6DD1:0100210011DC11148114411447D4101411142114E58825482948211425140222
+6DD2:0040204017FC104083F8404847FE104813F82080E7FE21082390206021980604
+6DD3:020842082FFE2208028880404FFE4100110021F8E10821082208220824280810
+6DD4:0040204017FC1040804043F84A080BF8120813F8E20823F8220822082FFE0000
+6DD5:0040204013F81040804047FC4110120814442040E3F820402040204027FC0000
+6DD6:00402040107E104083FC42044BFC0A0413FC1244E04027FE2040204020400040
+6DD7:0100210011FC12048484449442A4108417FC2084E1C422A42494208420A80010
+6DD8:0100210011FC1204850441E44284108417F42084E2A422A423E4200420280010
+6DD9:0080404027FE2402080483F04000500017FC2040E25022482444284421400080
+6DDA:0040202013FC1204820443FC4A000A28122413FEE22022502250248825040A02
+6DDB:01042104150417D4891441144FF4111417D42554E5542554254425C421140108
+6DDC:000027BC14A414A484A447BC44A414A414A427BCE4A424A424A424A42AA4114C
+6DDD:000027BE14AA14AA84AA47AA44AA14AA14BE27A0E4A024A024A228A22AA2111E
+6DDE:02084228222822280FA482444254569217102AA0EA203228224422FC22440200
+6DDF:00902090109013FC829442944A940BFC12941294E29427FE2000209021080204
+6DE0:000027FC1444144487FC4444444417FC10002000EFFE22082208220824080808
+6DE1:004022441244144880A041104608104410402248E248245020A0211022080C06
+6DE2:00142012101017FE801040104BD20A5212521254E3D4200820EA271A22260042
+6DE3:00002040139C12048204439C4A040A0413FC1090E0902090209021122212040E
+6DE4:0210411020102FA8042884444402579014882488E48024A0249028882A881100
+6DE5:008020F81088110881F0401048100BFE10201222E17420A82124222220A00040
+6DE6:0040204010A011108208440641F01040104023F8E0402248214821502FFE0000
+6DE7:0040202013FE12028444402048280888109012A4E2C224822188228824780000
+6DE8:003C27C012441128800043F84848084817FE1048E04823F82048204021400080
+6DE9:0040204017FC104080404FFE42081484188221F8E208251020A0204021B00E0E
+6DEA:0040204010A0111082084DF6400017FC14A424A4E7FC24A424A424A424140408
+6DEB:0008203C17C01084844442484210103C17C02040E0402FFE2040204027FC0000
+6DEC:0080204017FC10008110411042A8144410002040E7FE20402040204020400040
+6DED:0080204017FC1404840447FC4440144017FE24E0E95029503248244428420040
+6DEE:01402120112013FE822046204BFC1220122023FCE2202220222023FE22000200
+6DEF:0080204017FE1100820847FC400413F8120823F8E20823F82208220822280210
+6DF0:0040204010A0111082884446400013F010102020E04021242522250A290800F8
+6DF1:000027FC140414A4811042084040104017FC2040E0E0215022482C4620400040
+6DF2:00402040107C104083FC42444A700BC01244123CE20022F0249024922912120E
+6DF3:0080204017FC100083F842084BF8080013F81010E02027FC2040204021400080
+6DF4:0100210013FC1494889441244244148411282210E0402124252A250A28F80000
+6DF5:00A024A414A414A487BC4404440417FC14042404E7BC24A424A424A428A41004
+6DF6:00402040104017FC8040424842481248155420E0E15021502248244428420040
+6DF7:000027FC1404140487FC4404440417FC10002420E42227AC2430242225A2061E
+6DF8:0040204017FC104083F8404047FE100013F82248E24823F82208220822280210
+6DF9:0040208017FE11108248444643F81248124823F8E248224823F820422042003E
+6DFA:00A0209010BC17C88050406451941E0C10A02090E0BC27C82050206421940E0C
+6DFB:000023FC1040104087FE40A04110120814462040E04822642252245221400080
+6DFC:010001087D1005A009603118C506020008100A146AD42C582A544A94A9521020
+6DFD:0108210817FE110881084020482009201120113CE1202120212021202FFE0000
+6DFE:010006C01830EFEE01003FF811100920FFFE000001087D90096011202518C206
+6DFF:0040208013F8120883F842084BF80840104017FCE44424442454244820400040
+6E00:0040204017FE10A08150424845F6104011502110E7FE21102110211022100410
+6E01:0040474421682150024884444940408010002040E74421682250244829460080
+6E02:03F82208120813F8820842084BF80880104017FCE110211020A0204021B00E0E
+6E03:0108210817FE11088148404047FE1080110023FCE50429042104210421FC0104
+6E04:009020901090179E8090409048900B9C10901090E090279E2090209020900090
+6E05:2040104017FC004083F840404FFE080013F8120813F8E20823F8220822280210
+6E06:0844448420042FD404948494449454941FF42494E49424942484288428941088
+6E07:000023F8120813F8820843F849000BFC14041224E3D4221421F4200420280010
+6E08:0040202017FE11088090406041981606110821F8E10821F82108210822080408
+6E09:002020201120113C8120412047FE100010282124E122222A2410202020C00700
+6E0A:04442444165415548564444447FC144414C424E4E55425542644284428441044
+6E0B:002020201120113C8120412047FE100010002204E10820902108220424020000
+6E0C:000023F81008100883F84008400817FE10402444E2E821502248244621400080
+6E0D:0040204017FC104083F8404047FE100013F82208E2482248224820A021100608
+6E0E:0040204013F81040804047FC4004112810A02220E12027FC2050208821040604
+6E0F:0040204013FC10A08110420857FE100813C82248E248224823C8200820280010
+6E10:01004102211C2FD002108210451E57D411142114E1D42F142514212421240144
+6E11:000023F81208120883F8404047FC1444144427FCE444244427FC20422042003E
+6E12:0040208013FC1224822443FC4A240A4413FC1090E11027FE2010201020100010
+6E13:003C27C010841444824842104840084013F81040E04027FC20A0211022080C06
+6E14:0100410023F0221004208FFC5444544417FC2444E44427FC200020002FFE0000
+6E15:04442244128417D48114411451141FF411142114E29422542444244428140008
+6E16:0080204017FC1444804043F84248124813F82248E24823F82248204020400040
+6E17:00802090110813FC804047FE411012481C862310E02020C42308203020C00700
+6E18:000023F81090106087FC40A44128122014602040E7FC20E0215022482C460040
+6E19:0100210013F01410882047FC440414A415142444E0402FFE20A0211022080C06
+6E1A:0080208817E8109080A04FFE4080110013F82608EA0823F82208220823F80208
+6E1B:00142012101017FE8410441045D01412141225D4E554254825DA242A28461082
+6E1C:000027FC1040108087FC44A444A414A41484244CE0402FFE20A0211022080C06
+6E1D:004020A01110120885F6480047C41454145427D4E454245427D4244425540488
+6E1E:0208211017FE1040808043F84A080A0813F81208E20823F82208220823F80208
+6E1F:0080204017FC100083F8420843F810001FFE2802E3F820402040204021400080
+6E20:23FC120083F84A080A0813F8E20023FC21000100FFFE054009203118C1060100
+6E21:0040202017FE1488848847FE448814F8140025FCE48424882450282028D81306
+6E22:40002FF8280888684B88488808882BE82AA84AA8CBE8488A48AA50EA57262002
+6E23:0040204017FC10E081504248444613F8120823F8E20823F8220820002FFE0000
+6E24:021082105FD00210823E5FD2505220922F124112C21243925E2242224A4A0484
+6E25:000023FC1204120483FC42004BFC0A40128813FCE224222025FC2420282013FE
+6E26:000023F81208120883C84248424817FC140425F4E514251425F4240424140408
+6E27:0080204013FC10008108409047FE1442184423FCE24422442254224820400040
+6E28:000023F81248124883F842484A480BF8100017FEE24022442228229023080206
+6E29:000023F81208120883F84208420813F8100027FCE4A424A424A424A42FFE0000
+6E2A:0008203C17C0104083F842484A480BF8104017FCE444245425F4240424140408
+6E2B:00902290129017FE8290429042F0120013FC2040E7FE20E0215022482C460040
+6E2C:000227C21442145287D24452445217D214522452E7D2200222822242244A0804
+6E2D:000027FC144417FC844447FC400013F8120823F8E20823F82208220822280210
+6E2E:0110211017FE1110800047FE4008100813C82248E24823C82248200820280010
+6E2F:0110211017FC111081104FFE4110120817F42A12E21023F02204220421FC0000
+6E30:004020A0111012088DF6400043F81208120823F8E110211027FC211022100410
+6E31:01002100113E17C8854845484548154817C82508E108214821C82E48243E0000
+6E32:0080404027FC2404080883F8400053F8120823F8E20823F82208200027FC0000
+6E33:0000277E11241124813C47244424143C14242724E126217C210421042A040404
+6E34:000023F8120813F8820843F849000BFC14441244E2A4220423F4200420280010
+6E35:020842082FFE22080208800047FC544414442444E7FC24442444244427FC0404
+6E36:0110211017FC11108150404043F8124812482248EFFE204020A0211022080406
+6E37:0080204017FC11108208440443F81208120823F8E110211021122212240E0800
+6E38:02102110111017BE8220424043BC128412882288E2BE22882488248829A81010
+6E39:0200220013FE1402888247FA400217F2100227F2E00227F2241227F220140008
+6E3A:401020102F10891049144F52095229922F104914C9044F084910402040400180
+6E3B:00402040124812448454406049800E0013F81208E3F8220823F8220823F80208
+6E3C:0208211017FE1040804043FC4840084017FE1000E04027FC20A0211022080C06
+6E3D:0128212417A4112081204FFE4020102417A424A8E4A82490279224AA20460082
+6E3E:000027FC1444104087FE40404BF80A4813F81248E3F8204027FE204020400040
+6E3F:0040204017FC10E0815042484C4613F810002000E7FC20402248244429420080
+6E40:002027A810B014A483184110420815F410402040E7FC204020A0211022080404
+6E41:02102210122812288F444282427C130012002E7CE2442244224422442A7C0444
+6E42:000027BC14A414A487BC400043F810001FFE2100E20023F82008200820500020
+6E43:010043BC2E102210023C8F904210523C12102F90E27E22102210221024100810
+6E44:000023FC1224122483FC42004AFC0A84128412FCE28422FC2484248428FC1084
+6E45:004040402FFE204007FC8444455454E4144427FCE0E0215022482C4620400040
+6E46:0080204017FC1000820841104FFE100013F82208E20823F82208220823F80208
+6E47:0080204017FC120881104FFE400013F8120823F8E20823F82208220822280210
+6E48:020842082FFE2208020883F84208520813F82040EFFE20E0215022482C460040
+6E49:0208421C2270221003108AFE4A104A101210227CE244224422442244227C0244
+6E4A:0040204017FC104083F8408047FC1110120825F6E04023F8204020A021100608
+6E4B:0080208013F8110887FE40004BF80A0813F81040E7FC2040244027FE20400040
+6E4C:0040204010A01110828844464BF80A0813F81208E3F822442228229023080204
+6E4D:004024441444144487FC40004FFE1040108027FCE4A424A424A424A424A4040C
+6E4E:000027FE1040108087FE4492449214F214922492E4F224922492249227FE0402
+6E4F:000027FE1040108083FC42044A040BFC120413FCE204220423FC200021080204
+6E50:021042102220227C0FC482444244574416FC2A44EA44324422442244227C0244
+6E51:000027FC104412408278424055FE180013F82208E3F8220823F8220822280210
+6E52:000023F81208120883F840004FFE120813F82208E3F82208227E2F8820080008
+6E53:001021101108120485FA408841081228141023F8E2A822A822A822A82FFE0000
+6E54:0208410821102FFE000087C44454545417D42454E45427D42454244425540488
+6E55:00102010177C111481FE4214427C1710117C2510E5FE22102210250028FE0000
+6E56:0100211E111217D28112411E411217D21452245EE45227D224522022202A0044
+6E57:01042104110417C4813E410447C4102411142114E7C42104210421C42E140408
+6E58:02004200227C22440F448244427C574416C42A44F27C224422442244227C0244
+6E59:0080204017FE1090829844944114123014402040E7FE204020A0211022080C06
+6E5A:00402488152815E8844844A845E8140815E82528E5E8252825EA292A292A1166
+6E5B:0108210817FE110881F8410849F80908110817FEE25022882304220023FC0000
+6E5C:000023F81208120883F842084A080BF8100017FEE040224022782240254008FE
+6E5D:0220222413A8123082A243224A5E088013FC1204E20423FC2204220423FC0204
+6E5E:0040207E1040104087FC4404440417FC140427FCE404240427FC211022080404
+6E5F:0040208013F8120883F842084BF8080017FC1040E04023F82040204027FC0000
+6E60:004024441444144487FC4100410017FE11202220E2A422A82550245028880106
+6E61:03F82248124813F8824842484BF80840104017FCE444245425F424142404040C
+6E62:000027FC100013F88208420843F8100017FC2444E44427FC2444244427FC0404
+6E63:000023FC120413FC822043FE4A100A8A13061000E3FC220423FC220423FC0204
+6E64:02102110111017BE822842484BAA0AAE12BA12EAE2AE22A824AA24A229A2101E
+6E65:0080204017FC14048110420844441050104827FEE04020A020A0211022080406
+6E66:000023F8120813F8820843F848400A4013FC1440E04023F82040204027FE0000
+6E67:000027F8111010A087FC444447FC144417FC2444E08027FC2084210422280410
+6E68:000023FC120413FC820443FC4A040BFC10501048E7FE204020A0211022080C06
+6E69:0008203C17C010408FFE404047FC144417FC2444E7FC204027FC20402FFE0000
+6E6A:010021F8120813F0801047FE40801144166820B0E128266820A4212226A00040
+6E6B:43902E102210821242524FD40258269027104AA8CA2852284248424442840302
+6E6C:0610381008527E5408901C282A444882090001047D88095011202118C5060200
+6E6D:01082088109017FE809040904BFC0A941294130CE20423FC2204220423FC0204
+6E6E:000027FC10A010A087FC44A444A414A417FC2040E04027FC204020402FFE0000
+6E6F:000023F8120813F8820843F850001FFE120023FCE49429242244248421280210
+6E70:008021F81208151080E043184C0613F810402240E3FC244023F820402FFE0000
+6E71:0040204017FC104083F8404047FC104017FC2080E10023F82D08210821F80108
+6E72:003C27C012441128800043FC4880088017FE1100E1F822882250242028D80306
+6E73:004040402FFE2040004087FC451454A415F42444E44425F42444244424540408
+6E74:01082090100013FC809040904092149212942298E09020902090209027FE0000
+6E75:0208211017FC104083F8404047FC1100110023F8E4102820204020A023180C06
+6E76:0080210013F8120883F8420843F8104010402764E16821502248244429420080
+6E77:0040204017FC104083F8408047FE1110120827FCEA0A220823F82208220803F8
+6E78:0080204017FE100083F8420843F8100017FE2402E9F42110211022122412080E
+6E79:000027FE140015FC8524452445FC1524152425FCE420242025FC2820282013FE
+6E7A:0100217C114412448244467C4A10121012FE2238E25422542294231222100210
+6E7B:0040202017FE100081F8410849F8080013FC1204E20423FC2204220423FC0204
+6E7C:0100261C14041404871C4404440417FC10002000E7FC2040204020402FFE0000
+6E7D:0248424824902FFE049082484248500017FC2444E44427FC2444244427FC0404
+6E7E:010020801FFC112085284924400017F0101027F0E40027F82008200820500020
+6E7F:000027F81408140887F84408440817F811202120E9242528233021202FFE0000
+6E80:011041102FFE2110000087FC4040504017FC2444E554255425F4240424140408
+6E81:0088208813FE1088800043FE42021424102023FEE07020A820A8212422220020
+6E82:0102210217C21112811247D24552155217D22112E392254229222102210A0104
+6E83:0040204013F8124883F840404FFE100013F82208E2482248224820A021100608
+6E84:00402444144417FC808041F84208151010E02318EC4623F820402FFE20400040
+6E85:00104F94289228900A9E8AF04A905A9E1AF02A94EA942208250A249A28261042
+6E86:42002200257C84A448245724022422282FA84228CB104A9052A842284A440482
+6E87:004022481150104087FC41504248140410802FFEE1102210232020C023300C08
+6E88:00402240114017F88088409048FC0904110813FEE202242A2AAA228224140008
+6E89:000027BE1488148887A844A844A817BE14102518E49825A826AA244A20460080
+6E8A:000027BC14841484848447BC4400140017BC2424E42427A82410242824440482
+6E8B:000023F811081110811C42E442A4125414A82100E3FC22942294229427FE0000
+6E8C:001023D410581452828C4108420415FA10902090E7FE2090211021122212040E
+6E8D:000027FC10A014A482A840A04FFE100013F82208E20823F82208220823F80208
+6E8E:02102210127C12108F90421042FE170016902A10EA7C32102210221022FE0200
+6E8F:0040202017FE142085FC442447FE142415FC2420E5FC25042504290429FC1104
+6E90:000027FE1420144085FC450445FC150415FC2524E42024A829242A2230A00040
+6E91:004022441148104083FC42044A040BFC120413FCE204220423FC200021080204
+6E92:0040204013F8104087FE40004BF80A08120813F8E0A4212823102D4821860100
+6E93:011020A0100017FE80A043F840A817FE10A823F8E0A021B022A82CA620A000A0
+6E94:020821081110100087FC404048400BF810401040E7FE2000254824A428A40000
+6E95:000047FE240229F4000083F840805144166820B0E128266820A4212226A00040
+6E96:2140112083FC524017F82A40E3F8224023FC22000100FFFE0100010001000100
+6E97:003823C0104017FC81504154475811541354254CE0E021502248244428420040
+6E98:0040204013FC104080404FFE4080111013F82008E7FC24A424A424A42FFE0000
+6E99:0040204017FC104083F8408047FC111012482446E24821502248244421400080
+6E9A:0110211017FC1110804040A049100A0815F61000E00023F82208220823F80208
+6E9B:0080204017FC140481104208483C0BD012901290E2902288228824A424D40892
+6E9C:0080277C1424152484A445544648108017FC2444E44427FC2444244427FC0404
+6E9D:0110211017FC111083FC41104FFE104013FC2244E3FC22442FFE220422140208
+6E9E:000023F81148111080A0404041B0164E104023F8E248224823F8204427FC0004
+6E9F:000027FC1404100083F842084BF80A0813F81080E04027FC2000211022080404
+6EA0:01082088109013FC804041F848400BFE10801100E1FC22202420282023FE0000
+6EA1:001020101710157C8510451045FE1708150825FEE50825482728200820280010
+6EA2:020821081110100087FC400041101208140423F8E2A822A822A822A82FFE0000
+6EA3:022042202250248805048EFA540055FC15542554E5FC2554255425542504050C
+6EA4:000023FC124013F8824043F84A400A4013FC1004E55425542554240420280010
+6EA5:005040482FFE204007FC844447FC544417FC2444E0082FFE2208210821280010
+6EA6:010825481548155087DE402440141FD410142794E49424A824C8249428141022
+6EA7:000027FC10A010A087FC44A444A417FC10402040E7FC20E0215022482C460040
+6EA8:0110211417D2111081104FFE4010111417D42114E3942548290A211A21260142
+6EA9:0080210013F81208820843F84A000BFE120013FCE00425542554280420280010
+6EAA:003C27C0124411288080411043E01040118823FCE044204027FC20A02110060E
+6EAB:400023F822480A488AA8530853F822082000C7FC44A444A444A444A44FFE0000
+6EAC:0208211017FC1040804043F84840088017FC10A0E1282134223C22222422081E
+6EAD:000027FC144417FC844447FC41101208148421F8E20825082090206021980E06
+6EAE:020024FE17101510857C45544754145414542754E554255C2510271025100010
+6EAF:0440425E2292201207D2811E45525552155227DEE152211222122222242A0844
+6EB0:004022481248124883F8400047FC100013F82208E20823F8211020A027FE0000
+6EB1:0040204017FC104083F8408047FC1110126825C6E04023F820E0215826440040
+6EB2:00402140165C14448444475C4444144417FC2040E7F8211020A0206023981C06
+6EB3:000021F81108110881F840004BFC0A0413FC1204E3FC220423FC209021080204
+6EB4:0040208013F8120883F8420843F8120813F82050E04827FE20A0211022080C06
+6EB5:000021B81628142887A844A847CE148017B82428E7A824A8249028902AA81146
+6EB6:0040202013FE1202849441084A64089011081204E5FA21082108210821F80108
+6EB7:000027FE140215FA844244C2452A146A14B2252AE46A24AA2522244227FE0402
+6EB8:0040204017FC104083F8404047FE1080111023E0E04827FC2044224825440080
+6EB9:0040204017FC10408FFE4882411013E010402088E7FC20442248244429420080
+6EBA:000027BC1084108487BC4420442017BC108424A4E294229424A4208425280210
+6EBB:000023F8120813F8820843F8400017BC108424A4E294218C26B4208422940108
+6EBC:00002FFE1210121084A44738421014A417BC2040E04027FC204020402FFE0000
+6EBD:000023FE120012FC820043FE4AA80A9012C81286E20823FE2288244824080818
+6EBE:0080210017FC1444844447FC4444148417FC20C8E1502168227C22422442083E
+6EBF:001080945F54155495585510557C1F10351055FED51055105F10511040100010
+6EC0:0080204017FC1080810843F04860098417FE1002E7FC244427FC244427FC0404
+6EC1:40102F1029288A284A444CBA0A10291029FE4910CD584A544892491248500820
+6EC2:0080404027FC221001208FFE4882504417FC2100E10021F82108220822280410
+6EC3:0120211012081486891043F84008100017BC2084E4A4229424A4208422940108
+6EC4:0040204010A01190824847FE4A0813F8120823F8E20023F82508250829F80108
+6EC5:00142012101017FE8410441047F21492149225B4E6D42488254A293A2A261042
+6EC6:00002FFE100013F88208420843F8100017FC2514E4A427FC2444244424540408
+6EC7:0040204017FC104083F8420843F8120813F82208E3F822082FFE211022080404
+6EC8:0080204017FE100083F8420843F8100017FC2404E5F4251425F4240424140408
+6EC9:000023F8120813F8820843F848400A4811501040E7FC2120212022242424081C
+6ECA:0100210011FC120085F840004BF8088812A811C8E7F8208A21CA26AA20860082
+6ECB:01082088109017FE810841084210129414A42738E1082210221024A427BC0084
+6ECC:44202420247C88444AA84A101A282AD62A104AFECA104A544892491248500820
+6ECD:00402244124413FC80404FFE4000104013FC2244E24423FC2040204427FE0202
+6ECE:08202AA42CA84920145022887FFE4002810401047D88095011202118C5060200
+6ECF:01104208251420A000E083184C0653F810402040E7FC2040224821502FFE0000
+6ED0:0208220813BE14888AA8413E42081448184827FCE0E0215022482C4620400040
+6ED1:000023F8120813C882484FFE480213F8120823F8E20823F82208220822280210
+6ED2:000027FC100813C88248424843C810001FFE2008E3C82248224823C820280010
+6ED3:0080204017FC1484804043F8411010A017FC2040E04023F82040204020400040
+6ED4:003E4FC020842444024882104100561C14042404E71C24042404240427FC0404
+6ED5:0020792448A849FC482078404BFE488849247A224D2448A849244A2248A09840
+6ED6:0080204017FE100083F842084FFE120813F820A4E12823102510294821860100
+6ED7:0210221013DE1528888440784780108010F82780E08020F82F8420842084007C
+6ED8:000047FE24022914020885F44040504017FC2000E00023F82208220823F80208
+6ED9:000027FE1450148885FE469044FC149014FC2490E49024FE2480240027FE0000
+6EDA:0080204017FC111082484484412013F010102088E15023202510294821860100
+6EDB:0004203E17C0124481244128420013FC14402040EFFE20402444244427FC0004
+6EDC:0040208013F8120883F842084BF8088017FC1110E24824442BFA204020400040
+6EDD:0080204017FC111080A047FE48000BF8124813F8E24823F8224A2042203E0000
+6EDE:0150215017FC11508150400047FE1442184423F8E24822482248225820400040
+6EDF:0420842044781F488490447C44541E542454447CC4405F4044424442443E0400
+6EE0:000023FC110811F8810841F8410E17F8100827BCE0A422A42128229024A80846
+6EE1:0108210817FE1108800047FE4090109017FE2492E492256A26462402240A0404
+6EE2:0110211017FE111080004FFE4802100017FC2040E04023F8205020482FFE0000
+6EE3:000023FE120012FC820043FE4AA80A9012C81286E20022FC2284248424FC0884
+6EE4:0040207C104017FE8442447047C41444143C2420E410245425422942294A1238
+6EE5:00902490149E149084A844A444C41080100027FCE4A424A424A424A42FFE0000
+6EE6:008040402FFE20A002A882A444A45040104027FEE0E021502248244428420040
+6EE7:4410221022108FA0403E454404A428A431284528C21042104528492850440082
+6EE8:0080204017FE1402881443E04A000A0013FC1210E2102FFE2000211022080404
+6EE9:005040482E8022FE039092904AFC5A90149024FCEA902A90329020FE20800080
+6EEA:00004FBE20882510023E81224FAA52AA122A222AE22A222A221022142A220442
+6EEB:4440244024FC88884B505A201AD82B062AF84A88CAF84A884AF8488848880898
+6EEC:0040202013FC120483FC42004AF80A8812F81200E3FC232425FC2502290200FE
+6EED:000027FC144417FC844447FC5248124817FE2248E24827FC20402FFE20400040
+6EEE:420023C222028FE44A284B920E4229C428084B92CA824A844A8A4C92547E0800
+6EEF:02A822A817FC12A882AA44E6480017FC14442040E3F822482248224822580040
+6EF0:0080204013F8111080A047FE400013F8120823F8E20823F82120212222220C1E
+6EF1:408020402FFE880250044F90001C20102F90457CC50445284910492A514220FE
+6EF2:0080211013F8121084A44FBE404210A013182C46E19026642188263021C00E00
+6EF3:0080204017FC111080A047FC44A41514160C25F4E514251425F4240424140408
+6EF4:0080204017FC111080A047FC444415F4144425F4E514251425F4240424140408
+6EF5:0080404027FE2402089480504524554A18FA2300E04024442444244427FC0004
+6EF6:01082108110817D0811E479451241FD4121423D4E2542248224824D424240842
+6EF7:00402040107E1040804047FC4404164C151424A4E64C24A42514264C27FC0404
+6EF8:0210411021102FDE0028878840085788103E2788E48824882488278824880008
+6EF9:0040207C104017FE8442447845C4143C140824F0E52424A827FE282028A01040
+6EFA:02204220243E25480DA895104528544614802040E1242522250A250A28F80000
+6EFB:0040202013FC1000810840904BFE0A2012A012FCE320222022FC2420242009FE
+6EFC:0110211017BE111083B845544912100013F02210E290225022522212240E0800
+6EFD:002027FE142015FC842447FE442415FC142025FCE52425FC252429FC2924112C
+6EFE:0080204017FC1110820845F44110111011F02088E15023202510294821860100
+6EFF:0110211017FC1110811041F0404017FC14442664E55426EC2444244424540448
+6F00:08007F7808483E4800863E782A483E304048808401087D90096011202518C206
+6F01:0100210013F0121084204FFC5444144417FC2444E44427FC2000252424920892
+6F02:00004FFE20A027FC04A484A447FC500017FC2000EFFE20402248244429420080
+6F03:008040402FFE2802120483BC422452241FA42028E2282B10329022282A440482
+6F04:00202222122213FE800043FE4A200BFC122013FEE200222025FC24202BFE0000
+6F05:024824901248100083F842484BF80A4813F81040E7FC20E0215022482C460040
+6F06:0040204017FC10E08158464440A0111012482C46E24821502248244421400080
+6F07:021042102450295C0150825046FE5A0012102250E25C225022B02290230E0200
+6F08:0100211013DC125485544288410812F414022000E3FC20402150224825440080
+6F09:0080204017FC14A084A047FC44A414A417FC2400E52425A82530292429A4111C
+6F0A:004043F822482FFE024883F8404053F8124823F8E0802FFE211020E023180C04
+6F0B:00204F3C29442AA80A108C284AC6493819102950ED7E2A90287C281028FE0800
+6F0C:011041102FFE211001F0804047FC544417FC2040EFFE204027FC20402FFE0000
+6F0D:00004FFE282A28260FFE88224BAA4AAA1BAA2832E9962E2E284628822FFE0802
+6F0E:01244124222424240954814A429256101A102250E25C2250225022B0229E0300
+6F0F:000047FE2402240207FE840047FE542017FE2622E6AA2A222AAA3222222A0204
+6F10:08207E2008F8FF2814287F6A082AFF56098201047D88095011202118C5060200
+6F11:0100423E2788248804A887A844BE548817882010E4982718242824AA23CA0086
+6F12:0000277C11441144817C47104410147C14542754E154217C211021142AFE0402
+6F13:0080204017FE100082A8424842A813F8104027FCE484252425F424142404040C
+6F14:0080204017FC1404800043F8404013F8124823F8E24823F82000211022080404
+6F15:00A020A017FE10A087FC44A447FC14A417FC2000E3F8220823F8220823F80208
+6F16:0208224817481290829E4FE4411412141FD42494E91421C82F08211425140222
+6F17:0040208013FC124482F443144AA40A4412A413FCE04020242522250A290800F8
+6F18:07FE240015FC140087FE451445481586140025FCE50425FC250429FC2904110C
+6F19:00404FFE204027FC044487FC444457FC10422FFEE0102FFE2210211021500020
+6F1A:000027FC140014F88488448844F8140015DC2554E554255425DC240027FE0000
+6F1B:00402248115017FC804040804FFE111012482446EA4821502248244421400080
+6F1C:0110211017BC111083B845544912111010402040E7FC2040204020402FFE0000
+6F1D:000027BC108414A4829444A44084104013F82208E20823F82208220823F80208
+6F1E:000E27F010441224810843FC4A040BFC120413FCE20423FC2090211022120C0E
+6F1F:0040444422482FFE080283F84208520813F82040E04027FC204020402FFE0000
+6F20:0110211017FC1110800043F84A080BF8120813F8E04027FC20A0211022080C06
+6F21:010021FC120015F8810841F8490809F8100017FEE10023FC24A4212422540088
+6F22:0110211017FE111081F040404BF80A4813F81040E7FC20402FFE20A02110060C
+6F23:0020482025FE242001FC81244DFC552415FC2420E5FE242024202A2031FE0000
+6F24:0110411027BC211003B885544912408010802FFCE1102210212020C023300C08
+6F25:008040402FFE29120248844443F8504010402FFEE000204023F8204020400FFE
+6F26:08203E3E08447FA82A10492808443FFE200020882ED022A02490488852868100
+6F27:0110411021102FDE012087C0445C57C4144827C8E1102FD021222122211E0100
+6F28:0020247C12841148803040CE4610127C1210227CE21022FE2210221025FE0800
+6F29:0420422022202F7E04808400477C551415102550E55C255029502B5030BE2100
+6F2A:0020492025FC222006508A8843FE520816E82AA8E2A822E822A822082A280410
+6F2B:03F8220813F8120883F8400047FC14A414A427FCE00023F8211020E023180C06
+6F2C:004027FC104013F8804047FE48000BF8120813F8E20823F8220823F821100208
+6F2D:0110211017FC1110804847FC40A0111012082514E11027FE2110211022100410
+6F2E:0040202017FE142085FC442447FE142415FC2420E56224B429282A2630A00040
+6F2F:000027FC144417FC844447FC4100121017E020C8E3042FFE2042224825440882
+6F30:00402444144417FC800047BC44A414A417BC24A4E4A427BC24A424A42AB41148
+6F31:0108210817C81108811E47D24564154017C82108E38825482954211421240142
+6F32:00004F3E2120213C01208F3C482048FE18502F52E1542148214821442A620440
+6F33:004027FC111010A08FFE400043F8120813F82208E3F820402FFE204020400040
+6F34:00402444144417FC8080404047FE14021BF42000E7FC20402250244829440080
+6F35:0108210812881250841E4B944124111417D42114E59425482948211425240242
+6F36:0040204013F8124883F8404047FC144417FC2040E08020482544251428F00000
+6F37:0200211E17D2101287D4445447D8101417D22092E11221DA2714211025100210
+6F38:02004202223C2FA002208FA04ABE4FA41AA42FA4E2242FA42224224422440284
+6F39:000027FC1040127882404FFE410011FC120023FCE00425542554280420280010
+6F3A:0040204017FC1040855442484554104015542248E55420A020A0211022080C06
+6F3B:000027BC108414A4829444A440501188162620C0E31020642388203020C00700
+6F3C:0040244417FC1120811043FE522016201BFC2220E22023FC2220222023FE0200
+6F3D:000027FC140417FC842044A8447014A8150424A0E4FC252024202BFE28201020
+6F3E:0208211017FC104083F8404047FC1040102021C0E0442768215022482D460080
+6F3F:0440247C24A83D5004287DFE24884448851801047D88095011202118C5060200
+6F40:000027FC14A414A487FC4000401C17E012482248E24825542554286220400040
+6F41:200024FE3810222022FC1E84008408FC0A84ECFC28842C844AFC4A48A8841102
+6F42:00402444144417FC80004208411017FC11102110E5142318211021102FFE0000
+6F43:0240444028FC3088035084204CD8570614F82488E4F8248824F8248824880498
+6F44:0108210817C81110811E47E44554155417D42114E39425482948211421140122
+6F45:0100210013FC144080804FFE4120121017FC2A20E3FC222023FC222023FE0200
+6F46:01104FFE211020000FFE8882511443E010402088E7FC20442250244829440080
+6F47:011041102FFE2110004087FC40445FFE104427FCE04025642554265428441044
+6F48:000027FC14A414A484A447FC40801144166820B0E128266820A4212226A00040
+6F49:00402444144417FC800047FC440417FC140427FCE000242427A8243225A2061E
+6F4A:421022102510849E48105710027C22242FA44224CB284AA8529042284A440482
+6F4B:42102210251084A0483E5744002424A432A44AA8C8A8411043A85C2840440082
+6F4C:0080204017FC1514820847FC4080111013F82048E04023F8204020402FFE0000
+6F4D:04508448448008FE8B905E9044FC049028905EFCC8904090469058FE40800080
+6F4E:0108210815481390811E47D44564155415542754E5D4254825482554246404C2
+6F4F:000027F81090106087FC40A4412816A0104027FCE4A4251426EC24A424E4040C
+6F50:0140212013FE122086204BFC4220122013FC2220E22023FE2200252424920892
+6F51:002423A81092151482084C0447BA10A817C62400E7BC208420A8209025280244
+6F52:010041F0221027FC0A24824443FC5080114426A8E130266820A8212426A20040
+6F53:004040402FFE204007FC844447FC544417FC2044EFFE204220242522250A08F8
+6F54:010027BC11141394811447A4414C1080111023E0E04827FC2044224825440080
+6F55:0100210013FC16A88AA842A847FC12A812A822A8EFFE200022A8225424540000
+6F56:00004FBE220827BC02088FBE400057FC14442444E7FC24002402240223FE0000
+6F57:0140212013FE16208BFC422043FC122013FE2240E0402FFE215022482C460040
+6F58:007827C01248115087FC41504248140613F82248E24823F82248224823F80208
+6F59:0004203E17C01244812843F84A080BFC120413FEE40226AA2AAA2A0230140008
+6F5A:004023F8104817FE804843F840401554175C2444E7FC2444275C255425540844
+6F5B:000027BC1108152887BC431855AA1946100023F8E208220823F82208220803F8
+6F5C:0110411027BC21100FFE811042A8544413FA2208E20823F82208220823F80208
+6F5D:004020A0111816E6800043F84A080BF8100017BCE08424A4229424A422940108
+6F5E:0010279014BC14A484C447A841101128114625C0E53C2524252425A42E3C0024
+6F5F:010026381408140887384408440817F8120027FCE80425542554280420280010
+6F60:000027BC14A417BC842044A4439C1000111027FCE11021102FFE211022080404
+6F61:021041102FD0201007BE84A447D4501417942094E11421C82F08211425140222
+6F62:0110211017FC111081104FFE404017FC144427FCE44427FC2000211022080404
+6F63:000027BC14A417BC84A447BC4484144415F42424E4A4244424A4250424140408
+6F64:000027BC14A417BC84A447BC440415F4144424E4E444244425F4240424140408
+6F65:000027FC10A010A087FC44A444A417FC12482150E7FC20E0215022482C460040
+6F66:0040204017FC10A08514420847FC1A0A13F82208E3F820402248244429440080
+6F67:02082110100017FC8444455444E4144417FC2000E3F8220823F8220823F80208
+6F68:0080210017FC14A484A44FFE4000103C17C02144E24424E8215022482C460040
+6F69:000027FC144417FC844447FC4110111017FC2110E1102FFE2000211022080404
+6F6A:020043DE251221120FD28292425E540013FC2204E20423FC2204220423FC0204
+6F6B:00402248115013F8808047FC41101288151621E0E04823FC20442248244400C0
+6F6C:000027BC14A414A487BC40004BF80A4813F81248E3F8204027FC204020400040
+6F6D:000027FC10A017FC84A447FC400013F8120823F8E20823F8204027FC20400040
+6F6E:0100411E27D22112011287DE445257D2145227DEE11221122FD22122212A0144
+6F6F:000023FC100413FC800443FC48000BBC112417BCE00823FE2108208820A80010
+6F70:004023F8124813F8804047FE48000BF8120813F8E20823F8220823F821100208
+6F71:004027FC104013F8800047FC440413F8100023F8E20823F82208211027FC0000
+6F72:01104E102254223802108F7C4244534416FC2644EA44227C2244224422540248
+6F73:000023FC1204120483FC42224AFC0A2813FE1220E2FC238422FC248424FC0884
+6F74:0020492025FA222406288BFE4220524016FC2B44E244227C224422442A7C0444
+6F75:0288228817C81290829E4FD4402417D4145427D4E45427C824482454246404C2
+6F76:000027FC1444155484E4444447FC104017FC2040E0402FFE2000252424920892
+6F77:021023DE15281084804043F8404817FE104823F8E04023FC204027FE20400040
+6F78:042084205FFC0420956855AA652600002FF84808CFF848084FF8480848280810
+6F79:0040204017FC10E08150464C40401110111027BCE11023B82554291221100110
+6F7A:07FC240417FC140085F8441047FE14201460279CE484250829DE2F0831080318
+6F7B:003823C0104017FC8150424844A4111012482C46E24821502248244421400080
+6F7C:004023F8111010A087FC40004BF80A4813F81248E3F8204023F8204027FE0000
+6F7D:0208211017FC10A084A442A84FFE100013F82208E20823F82208220823F80208
+6F7E:00402248115017FC8150424844441208120823BEE4882AA8213E220824080808
+6F7F:000027FC144415F4849447FC440415F4151425F4E44424F4254425FC244407FC
+6F80:00004FBC229426B40AD484A445AC584011082108E5A8252C252825A82E7E0000
+6F81:40402040227C824042404FFE0000220822084228CBAE4A284A284BA85E7E0000
+6F82:010825481548155087DE401447E4101417D42114E7D4210821082FD420240042
+6F83:0BFE104061FC090411FC610405FC090431FCC088010C7D90096011202518C206
+6F84:002027A410A812928114420855F4180213F82208E20823F8220821102FFE0000
+6F85:004023F8104817FE804843F8404017FE100023F8E24823F8224823F8200007FE
+6F86:0040404027FC20400FFE811047BC51101190263EE0002FFE2120212222220C1E
+6F87:0110455425B8291002A88444400057FC14842888E7F820882088210822280410
+6F88:0208210817C81210849E4FD44064179414942794E49427882488249424A405C2
+6F89:00084788208821100FDE849444A4579414942794E49424C827882C9420A400C2
+6F8A:0108209017FE109083FC42944B1C0A0413FC1204E3FC200827FE210820A80010
+6F8B:000023F8120813F8820843F8404017FE100023F8E20823F820402248244400C0
+6F8C:04804482249C2FD004908790449E579414942494EFD42014251428A430240044
+6F8D:010441042FE42104013E87C4400457E414542454E7C42444228420E42F140408
+6F8E:010441042FE82110010087C4400457C814502442E7C22444228420E82F100420
+6F8F:000023F81208120883F8400047BC14A414A427BCE04024442444244427FC0004
+6F90:000047FC20402FFE0842835840405358100027FCE0002FFE2100220827FC0204
+6F91:000027FE10A017BC84A444A447BC10A017FC2444E44427FC2444244427FC0404
+6F92:000020FE10101720827C42444244127C1244227CE3C42E44207C202820440082
+6F93:01402140127E1480897C4144427C16441A7C2220E23C224422A82210222802C6
+6F94:01082128122817BE84A844C8448814FE17802480E4BE24A224A227A224BE0022
+6F95:01102FFE1110100087FC415051501FFE11502150E7FC20402FFE204020400040
+6F96:000027BC14A417BC84A447BC4444144415F42444E4E42554264C244424540408
+6F97:000027BC14A417BC84A447BC440415F4151425F4E51425F42514240424140408
+6F98:0110211017BC111083B845544912100013F82208E20823F82208220823F80208
+6F99:00002080173C140487BC440447FC120013FC2400E7FE2002255224AA28AA0004
+6F9A:010027FC14441554844447FC44E4155410002FFEE20023FC2004200420280010
+6F9B:010043F024102FFC144487FC444457FC10002FFEE00023F8220823F8220803F8
+6F9C:0200217C1504144485F4444445F41554157425D4E55425F424E425542444044C
+6F9D:008040402FFE28820548851448F4400017FC2444E7FC244427FC244424540408
+6F9E:0040207C104017FE844245F8444415FC150825F8E40025FE24202BFE28881306
+6F9F:00404FFE200027FC040485F4451455F4140427FCE00823F020402FFE21500E4E
+6FA0:000027FC14A414A487BC40A047BC14A414A427BCE4A424A427BC24A220A2007E
+6FA1:03F84208220823F8000087BC44A454A417BC2040EFFE21602250244838460040
+6FA2:00402248115017FE8402480443F8120813F82000E7FC244427FC244427FC0404
+6FA3:0108410821142FD4012287C0445C57C8144827C8E13E2FC82108210821080108
+6FA4:000027FC14A417FC804043F8404017FC111020A0E3F820402FFE204020400040
+6FA5:4400273C291492144FA44ACC0A802FA82ABE4AC8CF884A884ABE4A8848881188
+6FA6:00004FBE20882510023E81224FA252BE1222223EE2222222223E22002A140422
+6FA7:00A020A017FC14A487FC44A447FC100017FC2000E3F8220823F8211020A00FFE
+6FA8:0210221013DE15288884400047FC104012482248E248255428E220402FFE0000
+6FA9:0A803138228838382288393822887FFE410281047D88095011202118C5060200
+6FAA:000047FC20402FFE084283584040535810A02398EC4623F02010232020C00020
+6FAB:0110211017FC111083F842484BF80A4813F81040E7FC2444245425F42414040C
+6FAC:0440227C1084112886204250488C0BF8120813F8E20823F8220823F821100208
+6FAD:0040202017FE10288224427E44C81748117E2248E4C82F7E21482248247E0840
+6FAE:004040A023182DF6000087FC455454E417FC2000E3F8220823F8220823F80208
+6FAF:008040DC228423D404488A9443244C4012482150E7FC20E0215022482C460040
+6FB0:0040204010A01110820845F6400017BC14A424A4E7BC22102210252829441082
+6FB1:40002FDC285488544FD44A940AA62FC02A9C4A94CFD448145288524864540822
+6FB2:00A024A412A810A087FC411040A017FC104023F8E04027FC215022482C460040
+6FB3:0080210017FC14448554444447FC14E415542404E0402FFE20A0211022080C06
+6FB4:000023FC1294129483FC400047FE100013FC2204E3FC20A2211423082D440182
+6FB5:0200210217DC10108450429047DE1114111427D4E11425942554292425240244
+6FB6:00404FFE200027FC040485F4451457FC100023F8E20823F8220823F820000FFE
+6FB7:03F8220813F8120883F8400047FC14A417FC2040E7FE210021F8210822280410
+6FB8:0014201217FE141085D0441445D4155815CA2416E442282422A2228A24780000
+6FB9:020043F8241027FE0D48962447FE540015FC2400E5FC240025FC290429FC1104
+6FBA:0080204013FC1108809047FE400013FC120423FCE20423FC20402524250A08FA
+6FBB:00882448125010FC802040504694123812502298E23422542290222025FE0800
+6FBC:00102008178814BE848044944788147E14082788E6BE2A882A882B8832880008
+6FBD:0040207C104013FE824242784BC40A3C120013FEE24023A4225825B4245209B0
+6FBE:00102410127C101080FE4044462812FE1210227CE21022FE2210221025FE0800
+6FBF:0110211017BC111083B845544912100013F82000E7FC20402248244429420080
+6FC0:021044102F9028900FBE88A44FD4541412142FD4E4142788248828942A941122
+6FC1:000027FC14A414A487FC420053FE14421BFA224AE3FA2052207A278A22140008
+6FC2:002027FE1508149087FC445045FC145417FE2454E5FC245024D829542A521050
+6FC3:009023FC129413FC829443FC48000BFC120012F8E20023FE2520251425480986
+6FC4:000044F8228822E800A880A84DFC450415742554E5742504251425082A0011FE
+6FC5:00404FFE280223F8000883F8400857FC144423F8E248204027F8211020E00F1E
+6FC6:004027FC104011108FFE411043F8120813F82208E3F8220823F8211022080404
+6FC7:0040204017FC1248824845544FFE100017FC2404E5F4251425F4240427FC0404
+6FC8:03D42252125213D080104FFE425013D4125423D4E25422F82F4A244A20560062
+6FC9:002840242F40297E09C88F48497E59481F48297EE94829482F48297E20400040
+6FCA:0020213C112017FE801040144BFE0A1013F01254E25422D42368244A28960322
+6FCB:0110211017BC111083B845544912100017FC2044E24022782240254028FE1000
+6FCC:1C20702211B4FCA810A87D2456A27C4055FC7D0411047DFC11041F04F1FC4104
+6FCD:01104FFE2110220003FC84A44BA4416412542494E108204020242522250A08F8
+6FCE:01F8210811F8150A85FA450A45FA1402179E2090E0902F9E2492249224920892
+6FCF:000027BE1108110887BE4108410817BE10002080E0442512252229C023040CFC
+6FD0:03FC220413FC120483FC40444BF8085017FE1040E1FC270421FC210421FC0104
+6FD1:021042102F9C222402488FBE4AA25AAA1FAA222AE72A2AAA3288221422220242
+6FD2:4200227E2A108BA04A7C4A441FD4205422544AD4CAD44B545120422844441882
+6FD3:004027FC111010A087FE44A047F814A817FE24A8E7F824A025B02AA82CA610A0
+6FD4:000027FC124814448FFE444446EC155416EC2444E6EC255426EC244424540408
+6FD5:000027FC140417FC840447FC421014A417382210E4A427BC2000254824A408A4
+6FD6:000027FC14A414A487FC404843F8105017FE2040E1F8230825F8210821F80108
+6FD7:01102FFE111013F8820843F8420813F810802FFEE24827FC2A4A224822580040
+6FD8:0080204017FC144482A842944474100013F822A8EFFE200027FC204021400080
+6FD9:0110455425B8291002A884444FFE480210402248E248245020A0211022080C06
+6FDA:0110455425B8291002A88444400057FC14442040E7FC20E0215022482C460040
+6FDB:011027FC111017FC840443F8400017FC10802144E6A8217026A8212626A00040
+6FDC:004023F8104817FE804843F8404017FE100022A4E45223F822A822A82FFE0000
+6FDD:010827FE110811F8810841F8410817FE11082294E5E2204823FC2040224804C4
+6FDE:008023F8120813F8820843F8400017FC144427FCE44427FC20002FFE21100210
+6FDF:0080204017FC111080A44F58455415521B582000E20823F8220823F822080408
+6FE0:004027FE100011F8810841F8400017FE140223F8E180264421B8266821A60E60
+6FE1:000047FC20402FFE084283584040535810002FFEE04027FC24A424A424A4040C
+6FE2:07BC208414A4129484A4404047FC1110111022A8E44420402FFE204020400040
+6FE3:4210221022289FA842444F8A08A82F9828C84FA8C20E5FB84208420842080208
+6FE4:004027FC104013FC800047FE400213F8104027FEE00027FE200827FE24A80798
+6FE5:008041F82690206001A08FFE480247FC104027FCE44427FC244427FC22080404
+6FE6:003E27C01244112883F8404047FC100013F82008E3F8200823F82544252A08FA
+6FE7:028442842AA426C4029E8FE440045454128C2FE4E10427C4210421C42E140008
+6FE8:0210212017FC1210821044A44738121014A427BCE08021482554251428F00000
+6FE9:010827FE1148122087FE4A2043FC122013FC2220E3FE220027F8211020E00F1E
+6FEA:021042102F9C22240FC8823E4FAA502A1FAA28BEEFA028A02FA228A22AA2091E
+6FEB:001027D0151017DE845047E8450417C4100023F8E2A822A822A822A82FFE0000
+6FEC:0040207C104017FE840243FC424814A4111023F8E60C2BFA220823F8220803F8
+6FED:011027FC1110104083F8404047FC1080111023F8E00023F822A822A82FFE0000
+6FEE:012821AA116C122882FE464456281AFE1210227CE21022FE2210222822440282
+6FEF:000027BC108414A4829444A44120121017FC2A20E3FC222023FC222023FE0200
+6FF0:422822242440857E49C85F48027E244829485F7EC14840485548557E50400040
+6FF1:0080404027FE24020BFC8148425057FC120427FCEA0423FC220423FC21080204
+6FF2:0200421C2F942214071480264F8048BC17142014E2142F8827082A9432240242
+6FF3:0108452827BE294807BE831845AA594613F82208E20823F82208220823F80208
+6FF4:0110455425B8291002A884444FFE484210402764E16821502248244429420080
+6FF5:002027FE140213FC822443FC4A000AFC128412FCE28422FC228424FC24480884
+6FF6:07BC24A417BC14A487BC4404443415C4144427FCE44425F4251425F424140408
+6FF7:0108799009603518C206011047FC211081F0404017FC1664E55426EC2444244C
+6FF8:01102FFE1110104081B04E4E43F8120813F82208E3F8220025FC250429FC0104
+6FF9:000027FC144417FC844447FC404017FC10402FFEE5242892204027FC20400FFE
+6FFA:00142792149E14F08794448A449617E214942492E79E20702514248A28960062
+6FFB:0010277C1554157C851046FE4500157C1544257CE544267C2444247C24280444
+6FFC:044444E428A82AAA0EEE84A44AAA4EEE12422040EFFE20E0215022482C460040
+6FFD:02084FBE22082FBE0208851448A257FC140427FCE40427FC240427FC21100208
+6FFE:0020203E102017FE842245F8442215FE152425FCE52425FC28402AA4328A047A
+6FFF:000027FE148817FE848845FC452415FC152425FCE42027FE262A2AFA2A0A1206
+7000:07FC408023F8220803F882084FFE588215482514E8F4210023F8250820F00F0E
+7001:0208211017FC104083F8408047FC114813FC260AEBF8220823FA2234228C0302
+7002:010043F024102FFC144487FC444457FC15242892E3F8220823F8220823F80208
+7003:40002F7C2944897C4F444944097C2F20297E49AACF2A404A4A924922494A1104
+7004:0210221013DE15288084400047BC14A417A424A4E7A42434252826A024200020
+7005:0110455425B8291002A884444FFE480213F82040E04023F8205020482FFE0000
+7006:00404FFE204027FC000087FC44A457FC120823F8E20823F8220823F821100208
+7007:0040202017FE148885FC448847FE142015FC2524E5FC252429FC288831040202
+7008:07BC24A4129414A48FFE484247FC104013F82248E3F8224823F8204027FC0040
+7009:00404FFE28822338020883B8420853F8120027FCE80425542554280420280010
+700A:010023DC12541366824047DC42541348125424A2E00023FC2294229427FE0000
+700B:004047FC2404283807C08248415057FC12482404EBFA224823F8224823F80208
+700C:0080204017FC14A087FC44A447FC1400152425A8E53025A4251C28002AA41452
+700D:002027FE140015FC852445FC452415FC142025FCE42027FE25242AFA282013FE
+700E:010827FE1108100083FC42944A940BFC102813FEE220232422A82292242A08C6
+700F:020225E214A216AA852A466A410A128A144A2BAAE10A27CA2122254221EA0E04
+7010:0114211217D2111081104FFE429016D2129226D2E29426D4228A22CA2F160022
+7011:03F8220813F8120883F8411047FC11101FFE2110E248255420E02150224800C0
+7012:00404FFE2248255408E2815042484DF6100027FCE40425F4251425F4240407FC
+7013:028842A826A82BF0001E822445D45C1415D42494E49425C82488249425D40422
+7014:02009FDC42140F9480145FD450660F80201C4F94C2145FD447084A8852540222
+7015:0100213E150815D0853E45224FE2103E1122257EE56225A228BE210022140C22
+7016:07FC204017FE14428B5C4040475C112013FC2620EBFC222023FC222023FE0200
+7017:00404FFE284227FC004083F8404057FC104027FCE4A427FC20402524252A08FA
+7018:0040207C104013FC824443F04A440AFC12A812F8E2A822F8220025FC25540BFE
+7019:4400223C2FA4802448BC45240FA4223C22244FA4C23C4B104A9852A84A2A0446
+701A:0410841044281F4484825F0051EE1F2231AA5F66C4225F6644AA442244AA0444
+701B:0080BFFC48000FF880004FF848080FF820805C9CD7D45D54555C5C9655562E22
+701C:00084F8820082708053E852A472A502A1FAA2DBEEAA82F882A8A2A8E2ABA0990
+701D:000027FE14441598848847DE448815DC16AA2488E4202520253C2920292017FE
+701E:022042202FB822480F90827C4F9450141FFE2894EF9428FC2F9428902A900930
+701F:011027FE115013F8804847FE404813F81554275CE44427FC2444275C25540954
+7020:0110455425B8291002A8844447FC5484111023E0E04827FC2044224825440080
+7021:00104E7E2B202ABC0AC88CBE4A004BBC1AA42ABCEAA42CBC28A428AC29400A3E
+7022:002049FC252421FC002083FE4D0445FC150425FCE50425FC248825042BFE1000
+7023:010041BC252427A804908AA8414652A017BC20A0E3B820A027BC20A02FFE0000
+7024:008040402FFE200007FC84A447FC524811502208E44420A8211023082D460180
+7025:07BC24A4129414A4804047FC400011F0111021F0E00027FC240424E424A404EC
+7026:00109F90427A04128C1452FE47080A10333C46E4CAA4523C422442244A3C0424
+7027:0210211017DE1010845E428247DE101017DE2450E7DE245027DE2450245204CE
+7028:0108210817CE1112812447DE4552155E17D2211EE392255E2940211421120122
+7029:01804E3E22083F90023E87224AA2527E1022273EE5222522257E298029141022
+702A:20207F3EAA447FA82A103F2804441FF010101FF010101FF001843D480930730E
+702B:02009FDC42140F9480145FD450660F80241C4894CF1442945FC84A8852540622
+702C:4200223E2F888210423E4FA20AA22ABE2FA2423EC72246A24ABE520042140222
+702D:0410841044281F4484825F7C55001FE235AA5FAAC4EA5FAA44AA44E244AA04A4
+702E:07FC40402FFE2842035880404358500011102FBEE11023B82554291221100110
+702F:008822AA12DC14888154422247FE140211F82108E1F8200023FC220423FC0204
+7030:40002EFE2254829242FE4E9208D628BA28D64E92C2D642BA42D642924A9A0484
+7031:40002FFE29128FFE40004FFE08802AA2288A494ACA2A488A4AAA5082514A2224
+7032:0208820845080890905E6FA4401400143DD45554D5545DC84888489455542222
+7033:011027FE1110104087FE44A047FC14A417FC2500E5FC250025FC280435540008
+7034:07BC24A417BC14A487BC44A447BC131814A42080EFFC2110232020C021B00608
+7035:0248215017FC1150864C43F8424813F8124823F8E11027FC21102FFE22080404
+7036:00404F402A7E2A800A008F7C49444944197C2F00EAEE2AAA2AAA2AAA2FEE00AA
+7037:000027BC14A4129484A443F8424813F8124823F8E11027FC21102FFE22080404
+7038:0448444C2AAA20080FFE82884EE8528A1EEA228CEEEC228822EA2F1A24260042
+7039:404020A0211082084DF640000EEE2AAA2EEE4000CFFE49224FFE4922492A0804
+703A:01F0221017FC120483FC42244BB80A2211FE1210E7FC224423FC20D0214A063E
+703B:011447D221102FFE001087D0455257D2155227D4E29427C8228A2FFA22A60442
+703C:004027FC100013B882A843B8411017FC111027FCE1102FFE212823102D480186
+703D:004027FE149213FC809043FC409017FE110823FCE50A21F82240227C254008FE
+703E:07BC24A417BC14A487BC444445F4144415F42554E5F4255425F424E42554044C
+703F:021043D0241E2FE405548FF4454857D411B22220E7C0208827FC204423500488
+7040:07FC40402FFE28420358804043585000127C2FC4E27C27442AFC3244227C0244
+7041:4FBE28A22FBE88A24FBE484209F2291229F24912C9F248464F6A49524A4A0CC6
+7042:003C27C01244112887FC44A447FC1008178824FEE78824A82798250825A80690
+7043:015023F8155417FC855447FC455417FC100027FCE00023F8220823F821100FFE
+7044:03FC210811F8110881F8410E47F8100817FE2294E39C2294239C22D627BC0084
+7045:07FC444427FC244407FC80004FBE5AAA1FBE2AAAEFBE2040204027FC20400FFE
+7046:009027FE109013E8828843CE4A500BD412A213E2E00023FC2294229427FE0000
+7047:049242942FFE211007FC804043F850401FFE2480E7BC2494279424C82F9400A2
+7048:07BC24A417BC14A487BC44A447BC112013FE2220E7FC2A2023FC222023FE0200
+7049:0A98951454900A3E9F2851685F3E00283F28553ED5285F2850A850BE4FA00020
+704A:0FBE45282FBE2308059A892647FC500013F82208E3F8200027FC249425F4044C
+704B:00404FFE29202FFC09248FFC49004BFE18022AAAE8442BF828402FFC291013F8
+704C:01104FFE211027BC04A487BC4140512013FE2220E7FC2A2023FC222023FE0200
+704D:0FBE48A22FBE28A20FBE8C424A924FDE19262D5AEFD22912292A2A462C0A0804
+704E:05089FC8555C1FC895485FFE40081FD020144FBEC8804FBE48AA452A43AA1C7E
+704F:40002FBE28888F9048BE4FA202223FEA202A4FAAC8AA4FAA42084A9452520622
+7050:0110455425B8291002A884444FFE484210A02318EDF6204027FC224821500FFE
+7051:0FBE400027BC24A406B484A4404057FE14A027FCE4A427FC251229DC291211CE
+7052:052847BE294827BE031885AA494653FC120423FCE20423FC220423FC21080204
+7053:210447C88812F3BC20084B92F83E0380AAAAABAA01087D90096011202518C206
+7054:05109FD0555C1FE495485FFE402A1FEA202A4FBEC8A04FA048A2452243A21C1E
+7055:040C820A5FC8051E92545574505E1FD422145FDED45455545754505E51501090
+7056:002027FE148817DE848845DC46AA1488145027DEE45025DC24502BDE28501050
+7057:081088FE48003EFE2A822ABAAAAA6AFE3E00287C08444A7C8E443A7C100000FE
+7058:451825142F90853E472842680FBE2AA82FA8423ECFA842285FE8453E48A01060
+7059:0248215017FC140481F0411047FC155414E427FCE04027FC20402FFE22A40452
+705A:02AC444426AC244406AC84044FFE4A0A13F82208E3F8220823F820A02124061C
+705B:4F1E29122F1E89124F1E4BBA0AAA2BBA29F24952C9F2495249F248424BFA0846
+705C:0080BFFC48000FF880004FF848080FF820005DDCD5545DD4555C5DD654962D62
+705D:40002FBE28888F9048BE4FA202223FFE20224FBEC8A24FA2423E4A8052540622
+705E:47FC20402FFE8842435845000FBC25242724423CCFA44AA44FBC42245FA4024C
+705F:07FC240417FC152484A8452445FC155415FC2644E5F4255429F4284433F40008
+7060:0790251E17A8148487BE452A47BE100013F82208E3F8220823F820A02124061C
+7061:011027FE111017BC84A447BC44A417BC144427FCE55425F4244424E425540448
+7062:004027FC124813F880404FFE4AAA13B8111027FCE1102FFE212823102D480186
+7063:444428E82E0E84E44A0A4EEE00A02AEA200047F8C00847F8440047FC40040038
+7064:444424E42A0A8EEE44044AEA0E0E20E02AAA4AEAC0404FFE415042484C460040
+7065:02001FF010101FF010101FF0092013107C7C44447C7C44447C7C92925454B2B2
+7066:00009FDE50441FC8905E5FD24892155E3DD2489ED5525DD2401E5540554C0012
+7067:42102A902F9C8AA44FC84ABE0FAA202A3FEA403ECFA048A04FA248A245221F9E
+7068:04109F9C493406089FB6401C4F8808BE2F8048BECFA2423E5FA2423E42140222
+7069:42082A882F9C8A884F884ABE0F8820103FD4403ECF8048BE4FAA48AA452A1FFE
+706A:428822E82F5E82EC475A4AE802082FFE29425494C55847F2420443E8420203E4
+706B:010001000100110811081110212021004280028004400440082010102008C006
+706C:0000000000000000000000000000000000000000000000002488224442448004
+706D:0000FFFE0100010011081108111021204280028004400440082010102008C006
+706E:010011081108229004401830E00E0440044004400440084010422042C03E0000
+706F:1000100013FE1020542058205020902010201020102028202420442040A08040
+7070:040004000400FFFE0480088008880A9012A014802140414082200210040E1804
+7071:1000100011FC1044544458445044904410441044104428842484450442288410
+7072:080408040804094449444A444C44884408440844144412442104210440148008
+7073:0800080008001FFC100422044244924412842204050404840844100460280010
+7074:1000100011FC1020542058205020902010201020102028202420442043FE8000
+7075:00003FF8000800081FF8000800083FF801001110111022A0044008203018C006
+7076:10201020102010205420582051FC902010201020102028202420442043FE8000
+7077:010011081108229004401830E00E082008200820FFFE08200820102020204020
+7078:040004000FE01040208003600C18700401001110111022A0044008203018C006
+7079:1010107813C01040544058405040907E17C010401040284224424442403E8000
+707A:1020102010201120552C5934516493A411241134112829222522450240FE8000
+707B:010001003FF8010001000100FFFE000001001110111022A0044008203018C006
+707C:10401040108010FC55045A045004910410841044104428042404440440288010
+707D:1110111022204440222011101110000001001110111022A0044008203018C006
+707E:020001007FFE400281040100110811081110212002800280044008203018C006
+707F:102010201020102055245924512491241124112411242924252445FC40048000
+7080:100011F8101014205840508051FE909210921092111229222622444240948108
+7081:00007FF80200420042007FFC0480088010842084C07C00002488224442448004
+7082:101010901090148858885124512492221440104010882884250443FE41028000
+7083:0440082010102FE8C4260420082010A06040010011101120228004401830E00E
+7084:100013F81088148858885088508897F811081108110829082508410847FE8000
+7085:00001FF0101010101FF0101010101FF00100110811102280044008203018C006
+7086:10401020102013FE548858885088908810881050105028202450448841048602
+7087:104010401040148058FE51085288908810881050105028202450448841048202
+7088:100010F81088148858885106520091FC10841084104828502420445040888306
+7089:10801040104015FC59045104510491FC11041100110029002600420044008800
+708A:104010401040127C528454885920902010201050285028502488448841048202
+708B:1000100011FE1010541058205020906810A41122122228202420442040208020
+708C:1020102010501450588851045202908810881088108828882488450841088208
+708D:1008101C11E01500590051FC5144914411441128112829102510422842448482
+708E:010011081110212002C004301808600401001110111022A0044008203018C006
+708F:10401040104014405944514451489250104010A010A028902510410842048402
+7090:10201020102011FC54205820502091FC1020102010202BFE2420442040208020
+7091:10201020102014205BFE50205070907010A810A811242A222420442040208020
+7092:10201020102010A854A458A25122912012241024102828082410442040C08300
+7093:101011101090109054105910509090901010101E13F028102410441040108010
+7094:10401040104017F8584850485048904817FE104010A028A02510411042088406
+7095:10801040104013FC5400580051F09110111011101110291225124612420E8400
+7096:10201020102011FE5420592451249124112411FC1024282024224422401E8000
+7097:08200820FFFE0820082008200FE0082001001110111022A0044008203018C006
+7098:1008101C11E015005900510051FE911011101110111029102510421042108410
+7099:020004000FF81210692004C003000C0071001110111022A0044008203018C006
+709A:002000207C20442444A444A444A87D2044204450445044507C88448801040202
+709B:010011081108229004401830E00E08800888109030E0518096841084107C1000
+709C:10401040104013FE5440584051FC9040104013FE10422842244A444440408040
+709D:1040104010A014A059105208540691F011101110115029202504450440FC8000
+709E:10401020102014005BFE50405040906010501048104428442440444040408040
+709F:1000100011FC15045904510451FC91041104110411FC29042400400043FE8000
+70A0:100011FC11241124552459FC51249124112411FC112428202420442040208020
+70A1:1000100013FE14205820502051209120113C1120112029202520412047FE8000
+70A2:102010281024102055FE58205070907010A810A811242A222420442040208020
+70A3:1000100013FE1008540859E8512891281128112811E829282408440840288010
+70A4:100013FC108410845484590451149208140011FC110429042504450441FC8104
+70A5:10901090109013FC5494589453FC9290129013FE10922892251A451442108410
+70A6:10501048104814405BFE5080508090FC11441144112829282610422844448182
+70A7:1080108010FE15005A205120512C917413A41124113429282522450240FE8000
+70A8:10201010101015FE5902520450809088109010A010C0288224824482407E8000
+70A9:1040104010A014A0591052485426902013F810081010291024A0444040208020
+70AA:10201020112415245924512451FC902010201124112429242524452441FC8004
+70AB:10201010101015FE582050205044908411F8101010202844248245FE40828000
+70AC:100011FE11001100550059FC510491041104110411FC29002500450041FE8000
+70AD:0100210821083FF808000800FFFE10801088148824902940414082200C183006
+70AE:1080108011FC15045A0455F451149114111411F4110429282512450240FE8000
+70AF:100011FE110215025902517A514A914A114A114A117A294A25024502410A8104
+70B0:080008001FF020105F90109010901F901050102410040FFC0000488844448444
+70B1:02000400082010103FF800081FF0101010101FF00100111022A004401830E00E
+70B2:102010201040108855045BFE5002900011FC1104110429042504450441FC8104
+70B3:100013FE10201420582053FE522292221252124A128A2B0226024202420A8204
+70B4:10201020102011FC5524592451249124112413FE102028502450448841048202
+70B5:10401040107C108455885A50502090501088130610602810240844C040208010
+70B6:1020102010201020543E58205020902011FC1104110429042504450441FC8104
+70B7:10401020100015FE582050205020902011FC1020102028202420402043FE8000
+70B8:11001100110015FE5A805280548090F810801080108028FC2480448040808080
+70B9:02000200020003FC020002003FF02010201020103FF000002488224442448004
+70BA:020012000A007FF0042004400FF8080810101FFC20042AA44AA4900400280010
+70BB:1000100013FE102054205840504090FC11841284148428842484448440FC8084
+70BC:1040104017FC108054805BE05120922013FC1020112829242622442240A08040
+70BD:1000100011FC1104550459045104910411FC1104100028902488450442028402
+70BE:100011FC110411045504590451FC9050105010501050289224924512420E8400
+70BF:1020104011F815085908514851289128110817FE110829082508410842288410
+70C0:1008103C13E01020552458A450A8902013FE1020102028202420442040A08040
+70C1:1008101C11E0110055205920512091FE1020102010A828A42522462240A08040
+70C2:1000110810881490580053FE50009000100011FC100028002400400043FE8000
+70C3:100011FC100810105430584850849302100011FC102028202420442043FE8000
+70C4:10401020102013FE540058885104920210881088105028502420445040888306
+70C5:102010201040148059FC51545154915411541154115429542554415443FE8000
+70C6:10801080113C120054805880517E930815081108110829082508450841288110
+70C7:10201020105014885904520251FC90201020102011FC28202420442043FE8000
+70C8:00047F84082408241F24212451240A24040408143008C0002488224442448004
+70C9:080008001FE020204040BFF820082288244828280100111022A004401830E00E
+70CA:11041084108814005BFE5020502091FC1020102013FE28202420442040208020
+70CB:08400840104037FC50E091501150124814441842104000002488224442448004
+70CC:109010901090151059FE53105510913811381154115429922510451041108110
+70CD:10201120112011FC55205A20502093FE1090109010902890251245124212840E
+70CE:00003FF808200820FFFE08201020202041201110111022A0044008203018C006
+70CF:020004001FF0101010101FF010001FFE10001FFC000409242494249440280010
+70D0:1020104011F8150859485128512893FE11081148112829282508420842288410
+70D1:10901090109014925A945098509091981294149210902890251241124212840E
+70D2:10281024102414205BFE5020502093A0112011101110291025CA470A42068002
+70D3:1020102011FC14205820502053FE90001020102011FC28202420402043FE8000
+70D4:100011FE11021102557A59025102917A114A114A114A297A25024502410A8104
+70D5:0028002400203FFE202020202FA4222422642AA832282510249248AA50468082
+70D6:084008487F4408440840FFFE00400844294429442A28482A1412122A22464082
+70D7:10201010101013FE54205842508491F81010102210C42B082410442840C48302
+70D8:108810881088108855FE588850889088108813FE100028882484450442028402
+70D9:1080108010F815085B1054A0504090A01118120615F829082508450841F88108
+70DA:102010201050108855045A0251FC9000100011FC110429042504450441FC8104
+70DB:10201020102011FC552459245124912411FC112410202828242445FE40828000
+70DC:100013FE1000140059FC5104510491FC1104110411FC29042400400043FE8000
+70DD:00001FE0004000807D040588095011202118450682001FF00000488844448444
+70DE:10881088108814885BE85088518C91CA12AA1288148828882488448840888088
+70DF:100013FE120216225A22522253FE922212221252124A2A8A2702420243FE8202
+70E0:1040104017FE1080550059FC5304950419FC1104110429FC2504450441148108
+70E1:010011081108229004401830E44E04403FF804400440FFFE0000082010102008
+70E2:1040102013FE12025400583853C090401040107C13C0284024424442403E8000
+70E3:10401040104013FE54805890509091121152115412902A282428444440848102
+70E4:1040104411F4104854505BFE5040908011FE1240148028FC2404440440288010
+70E5:100011FE11201120552059FC510491041104110411FC29202520452041FE8000
+70E6:100013FE1020104055FC59045104912411241124112429442450448841048204
+70E7:2080208020BC23C0A850B024A0D4A30C200027FE2090209051124912420E8400
+70E8:10901094111415185B1055325152910E1120102013FE28202420442040208020
+70E9:10201020105014885904520250F89000100013FE102028402488410443FE8102
+70EA:108810481050100055FC58205020902013FE1020105028502488448841048202
+70EB:23F0102080C043FC11242124E2442484292820100100111022A004401830E00E
+70EC:100011FC1104150459FC511051109108110412621410280024E0441840048000
+70ED:104010401040FDF8104810481CC83048D0AA10AA510622020000488844448444
+70EE:7F84082410243F2451240A24040408043014C10811101120228004401830E00E
+70EF:11841068103014C85B04504053FE90A0112013FC152429242534412840208020
+70F0:1008103C11C01004554458A8500091F81010102013FE28202420442040A08040
+70F1:100013FE120216525A8A5306520292FA128A128A128A2AFA268A4202420A8204
+70F2:080C08F07E8008800EFE7888088829081208010011101120228004401830E00E
+70F3:1028102413FE1020542059FC5124912411FC1124112429FC252445244124810C
+70F4:100011FE100014925924524851249092100011FE102028202420442043FE8000
+70F5:1088108813FE10885400588050FC910412041484104428442404440440288010
+70F6:1000100613B8148858885108513E9388108812881288293E25004280447E8800
+70F7:1040102013FE16025C0451F85000900013FE10901090289025124112420E8400
+70F8:1080108010FE15005AFC508450A4909413FE10841124291425FE440440288010
+70F9:0100FFFE00001FF010101FF000003FF000600180010005000200488844448444
+70FA:1040102011FC1104550459FC5104910411FC1120112229142508454441828100
+70FB:1004100E13B8148858885128512E93A810A812A812A8293E25004280447E8800
+70FC:100013FE1040148059445224506890B011301228106828A42522422040A08040
+70FD:1040104010FC10885550582050D8932610F8102010F8282027FE442040208020
+70FE:01000910092012C0043019086914091012A004401830610C1FF0010001007FFC
+70FF:100213C2124416485B5052C2524292441FE8125012422A4226444248445088E0
+7100:10001050104810845524582050509088110612F8108828882488448840F88088
+7101:0080008078FC49044A48484078B0030C0C02010011101120228004401830E00E
+7102:1040104024FE6488A55024202450208801041110111022A0044008203018C006
+7103:1020102011FC10205420582053FE90481048114C114A2A4A2488448841288210
+7104:00003FF80408FFFE04083FF808001FF8280848088FF808080000488844448444
+7105:10201120112011FC55205A20502093FE1000100011FC29042504450441FC8104
+7106:100010FC1084108454FC580051FE9102110211FE1102290225FE4502410A8104
+7107:1020112410A410A8542059FC5104910411FC1104110429FC2504450441148108
+7108:1000087C3E442244227C3E4022422042413E9110111022A0044008203018C006
+7109:00007FFC010011F811001100FFFE08000FF810001FFC00042924249440280010
+710A:100011FC110411FC550459FC5000900011FC102010202BFE2420442040208020
+710B:2420242024203DFC0420FC20242024F84400010011101120228004401830E00E
+710C:10401040108815045BFE500250889144124210F811882A502420405041888606
+710D:11081088109015FC5824502451FC9120112011FE106228A2252A422444208020
+710E:1000100C11F0FD00110011FE1D10F11011101210521024100000488844448444
+710F:00003FF0002000400180793C4944492849107928014405000200488844448444
+7110:100013FE1040104055FC5884508493FE1000100011FC29042504450441FC8104
+7111:100013FE122216225A2253FE52229262127212AA13222A222622420243FE8202
+7112:100010FC108410845484588450FC9000100011FE110229022502450241FE8102
+7113:10201020105014885944522250F890081010102011FC29042504450441FC8104
+7114:10401040107C148459085210513E912211221122113E292225224522413E8122
+7115:1080108010F815085A1055FC512491241124112413FE28502450448841048602
+7116:110010BE128216025A2252125252924212CA135612522A3226024202420A8204
+7117:100011FC1104150459FC5100510091FE1102117A114A294A267A420244148008
+7118:020002007FFC02003FF80400FFFE08201FFC20204420822002A0004024884244
+7119:1040102011FC100055085890500093FE1000100011FC29042504450441FC8104
+711A:082008207EFC08301C682AA4C922082009201110111022A0044008203018C006
+711B:7C7C44447C7C44447D7C4104410449244924494451844244422444244804500C
+711C:100011FC1104110455FC5904510491FC1000111211D42918251045524192810E
+711D:101C13E0122013FE56205A92530A920611FC1104110429FC2504450441FC8104
+711E:1040102013FE100055FC590451FC900011FC100810102BFE2420442040A08040
+711F:10881088108817FE5888508857FE900011FC1104110429FC2504450441FC8104
+7120:1040102013FE100054885888515492221000102013FE28202420442040208020
+7121:100010001FFC2AA04AA00AA07FFC0AA00AA00AA07FFC00002488224442448004
+7122:10201010101015FE5902525450889104100010FC102028202420442041FE8000
+7123:00007F0022FC3E4422443E44222822282F10F228424402820000488844448444
+7124:010000803FFE2210221025FE2C903450441044508520111022A004401830E00E
+7125:1040102013FE12025504590051DE925212521352149A2894251045124212840E
+7126:090008801FFC108030805FF8908010801FF8108010801FFC1000488844448444
+7127:10901090110815485A445492510893FC1044102010A42A82268A428A44788000
+7128:100013FC120412F456045AF4500091F8110811F8110829F82508450841288110
+7129:100013DE125216525A5253DE52529252125213DE12522A5226524252455288A6
+712A:1040102013FE120254885904520291FC100411FC110029FC2404440440288010
+712B:1088108813FE108854A8582051FC912411241154114C29842504450441148108
+712C:100011F81108150859F85108510891F8108011FC125428942524424440948108
+712D:08202AA42CA84920145022887FFE400280040FE00820082008221022201EC000
+712E:201020902710243EAC22B444A790A51025102510252825285528494449449082
+712F:10201020103E142059FC510451FC910411FC112410202BFE2420442040208020
+7130:10401040107C148459085200502091CE1102110211CE29022502450241FE8102
+7131:010011081108229004401830E00E08100A102A542C5448981410222842448082
+7132:2080204027FE2120A920B23CA244A664229423482248223052204A5042888306
+7133:10A01090108015FE5910531055FC9110111011FC11102910251045FE41008100
+7134:1040102013FE108055045BFE500291FC110411FC110429FC2504450441148108
+7135:100013FE1202168A5A5253FE5222922212AA12AA12AA2AFA26024202420A8204
+7136:102010281E24222033FE4A20A450145008881088210442020000488844448444
+7137:1040108011FC1124552459FC5124914411FC109011102BFE2410441040108010
+7138:00003E7C224422443E7C224422443E7C01001110111022A0044008203018C006
+7139:100013FE1202168A5A5253FE5242922213FE128212822A8226FA4202420A8204
+713A:100011FC110411FC550459FC5000902811C8108810882BFE2488448841088208
+713B:11F81108110815F85908510851F8900013FC120412042BFC2604420443FC8204
+713C:1020102011FC102054A8588853FE9088100013FE1090289025124512420E8400
+713D:00007CFC448444FC7C8444FC44847C84011402080100111022A004401830E00E
+713E:10201020105014885944522251F890081050102010A42A82268A428A44788000
+713F:1040102013FE16205AFC5224522493FE1224122412FC2A202650445044888906
+7140:100013FE120216025BFE521052929292129212FE12102A922692449244FE8802
+7141:1088108813FE108854F8588850F89088108813FE110029482584450041FE8000
+7142:1088108813FE108854F8582051FC9124112411FC10202BFE2420442040208020
+7143:1020102013FE105054885B2651FC9020102013FE1000282025FC4420402083FE
+7144:1008103C11E014205BFE502051FC912411FC112411FC282025FC442043FE8000
+7145:102011DC11141114551459D45126910011DC1114111429D42708450841148122
+7146:100013DE124216425A4253DE5200923E13D2121212142BD42608421442248242
+7147:100013FE1222102055FE582051FC912411FC112411FC282027FE442040208020
+7148:200027FC24042434ADC4B444A5F4A554255425F42444245455F44C9448069002
+7149:1020102013FE102055FC592451AC9174112411FC1020287024A8452442228020
+714A:1040102013FE1202540459FC500091FC110411FC110429FC2504440043FE8000
+714B:100011FC110415FC590451FC5020912011FE1220102029FC2420402043FE8000
+714C:1020104011FC150459FC510451FC900013FE1020102029FC2420402043FE8000
+714D:208821C827082108A92AB12AA7ACA14823082388255425145914492441248142
+714E:10100820FFFE00003E4822483E4822483E0822082A2824100000488844448444
+714F:100013FE100015FC5904510451FC900013FE122212222BFE2622422243FE8202
+7150:1088108813FE108854A8582051FC91241124112413FE28202450448841048202
+7151:01081FD001207FFC02000FF03810CFF008100FF00100111022A004401830E00E
+7152:2040204021FC2084ABFEB000A1FCA10421FC202023FE202052204BFE40208020
+7153:102011241124112455FC580053FE9020104011FC11542954255445544154810C
+7154:1020522054209020283C44208220102010FC5284548490842884248442FC8084
+7155:00007F7C444454445744517C51405740544244427F3E00002488224442448004
+7156:101E13E010441524588851FC5040904013FE108010FC29442528421040688186
+7157:100013FE1020104055FC5954515491541154112C10202BFE2450448841048202
+7158:20142012201027FEAC10B410A5D0A412241225D42554254855DA4C2A48469082
+7159:100013FE105014505BFE52525252925213FE102010202BFE2420402047FE8000
+715A:00007CFE448044FC7C8444FC44807CFE01001110111022A0044008203018C006
+715B:00003EF822883EF822883EF822883EF801001110111022A0044008203018C006
+715C:100011FC110415FC590451FC51049040102013FE100029042488400047FE8000
+715D:100013FC122416245BFC520052FC9284128412FC12842AFC2684428444FC8884
+715E:202020203C40447E88847F44024402287E2802100228FE440082488844448444
+715F:100013FE122213FE56225BFE500091FC110411FC110429FC2504450441148108
+7160:10481148114817FE594851485178910011FE102013FE287024A8412446228020
+7161:20102010207C2714A9FEB114A27CA210277C211021FE251052104B0044FE8800
+7162:08202AA44D28145022887FFE400280041FE0042004203FA004200414040C0404
+7163:100011FC104814305BFE5052509491101230102013FE287024A8412446228020
+7164:1088108813FE1088548858F85088908810F8102013FE287024A8452442228020
+7165:2080208020F82108AA10B5FCA104A154218C2124202023FE5050488841048602
+7166:0100790049FC4A044C0479E44924492449E44804782800102488224442448004
+7167:00007DFC44444444444444947D0844FC4484448444847CFC0000488844448444
+7168:100011FC1124112455FC5924512491FC100013FE112029222514454841848102
+7169:100013FE1020144059FC5104510491FC110411FC1104290425FC440040888104
+716A:11081088109017FE5890509053FC92941294130C12042BFC2604420443FC8204
+716B:2108209020002BFEB080A184A244A4A82130227024A8212852244C2248A08040
+716C:200023F822082BF8B208A3F8A000A7FE220023FC2494292452444C8449288210
+716D:2484490424A400247FA408241F24612412240C043014C0080000488844448444
+716E:020002083FD00220FFFE01000FF03810CFF0081008100FF00000488844448444
+716F:1110111211D4111855525992512E904011FC1104110429FC2504450441FC8104
+7170:100010F8108814885888508850F89088100013DE12522A522652425243DE8252
+7171:100011FC1104150459E45124512493FE120212FA128A2A8A26FA4202420A8204
+7172:08000BF8120833F8504097FC11501248144410400100111022A004401830E00E
+7173:1100113C112417A45924513C512493A412A412BC12A42AA427A4444440548088
+7174:100011F81108150859F85108510891F8100013FC12942A942694429447FE8000
+7175:1020102013FE1420582053FE528A925212FA122212222AFA26224222422A8204
+7176:100011FC1104150459FC5104510491FC100013FE10202920253C412042A0847E
+7177:2080204027FE2000ABF8B208A3F8A00027FE240229F4211051104A124412880E
+7178:1040102011FE1102550259FE5100910011FE11AA12AA2AFE24AA44AA40A28086
+7179:1088108813FE148859FC508853FE902011FC112411FC292427FE410441148108
+717A:200024F822882288A8F8B088AE88A2F822A22294228822A852C44A84450088FE
+717B:1020101013FE16205AFC522453FE922412FC122012FC2A842684448444FC8884
+717C:2080208021FC2A44B154A1F4A084A128229021FC2244255451F4488449288210
+717D:1020101011FE1502590251FE510091EE112211AA11662922256642AA42228466
+717E:100011FC1124152459FC51245154918C110411FC1040282024A4428A428A8478
+717F:1028102413FE102055FC592451FC912411FC112410082BFE2488444840488018
+7180:100011FC110411FC550459FC5020912410A8102013FE2890249045124212840E
+7181:104011FC1044109455085BDE514A914A129411FC110429FC250445FC4104810C
+7182:2100210021FC2A00B5F8A000A3F8A08822A821C827F8208A51CA4EAA48868082
+7183:00407EFC15440838FE441AA22CFC4844A89411080100111022A004401830E00E
+7184:1020104011FC150459FC510451FC910411FC1040102028A4268A428A44788000
+7185:100013F8124812A857185A0853F89000100017FC14A42CA424A444A44FFE8000
+7186:1020102011FC1420582053FE5080910413FE100213FC2A942694429447FE8000
+7187:1040102013FE140059FC510451FC900013FE120212FA2A8A26FA4202420A8204
+7188:00002FBC2A242A242FA428BC28A02FA02A224A224F9E80002488224442448004
+7189:100010FC1084108454FC580051FE910211FE110211FE290225FE444840848102
+718A:1080249842E07E8400847E7C42807E9842E07E844284467C0000488844448444
+718B:108024987EE000847E7C42007E9842E07E844284467C0100111022A00C60701C
+718C:100013DE125217DE5A5253DE520292221222122212522A4A268A4202420A8204
+718D:1020101011FE1102540058FC5084908410FC100011FE29022502450241FE8102
+718E:1008103C13C010045644592851FC9220102013FE102029242524452441FC8004
+718F:00F83F000100FFFE01003FF8292825483FF801003FF80100FFFE488844448444
+7190:100013FE1202100055FC590451FC910411FC104010202BFE2400448841048202
+7191:10881050100015FE585051FC505493FE105411FC105028D82554425240508050
+7192:08202AA42CA84920145022887FFE400281041110111022A0044008203018C006
+7193:2080210023F82208AA08B3F8A200A3FE220023FC200425545554480440288010
+7194:1040102013FE160258505088512490501088110412FA28882488448840F88088
+7195:100011FC102014205BFE500051FC910411FC110411FC290425FC448841048202
+7196:101E11E01022111254945880502091CE1102110211CE29022502450241FE8102
+7197:2040204020A02990B248A7FEAA08A3F8220823F8220023F855084D0849F88108
+7198:104013BE121216925A5252AA5324904013FE122212222BFE2622422243FE8202
+7199:00007F7C444444445F44517C51405F40444244427FBE00002488224442448004
+719A:100011FC112415FC592451FC50A890A813FE10A810A829FC242043FE40208020
+719B:100013FE105011FC5554595451FC900011FC100013FE282024A8452442A28040
+719C:1020104011FC1524597C518C51549124115411FC1020281025544542414A8238
+719D:1040102013FE125056505BFE5252925213FE120012922AD42698449244D2888E
+719E:100013DC129417D45A5453C85288929413E21000102029FC2420402043FE8000
+719F:1040FE4000407DF844487C4800C87C4808AAFEAA110652022000488844448444
+71A0:100013DE10421252554A5A525042902011FC1104110429FC2504450441FC8104
+71A1:204023F822482FFEAA48B3F8A040A3F8224823F820802FFE511048E043188C04
+71A2:1020147C12841548583050CE5610927C1210127C12102AFE2610421045FE8800
+71A3:1020122213FE1090548859FE5310951011FE1110111029FE2510451041FE8100
+71A4:100013DE1042114A54C6594A525290021040102011FC280025084488409083FE
+71A5:20FE240422282210A8FEB092AE92A2FE229222FE2292229252964D0048FE8000
+71A6:102011241122152A5A325060519097FE112011FC112029FC2520452041FE8100
+71A7:11102110CAA814443240D27C154014FE0800010011101120228004401830E00E
+71A8:3F0821083F7E20082F4820285FA8440895282C900100111022A004401830E00E
+71A9:1040102013FC16045BFC520052F8928812F8120013FC2B2425FC4502490280FE
+71AA:20102190261E2222AA54B208AF90A2642208271E2AA2224252144A0842108260
+71AB:1040102013FE120056485A4853FE92481248124812782A002554452A4A2A9000
+71AC:082008207F20087E7E4408A4FF2810101E282244468280002488224442448004
+71AD:1010FEFE10107C7C1010FEFE10103FF800081FF800083FF8111022A00C60701C
+71AE:200027BC208424A4AA94B4A4A050A188262620C0231020645388483040C08700
+71AF:1088108813FE108854F8582051FC912411FC102011FC282027FE445040888306
+71B0:100013FE1200167C5A445244527C920012EE12AA12AA2AAA26EE420043FE8000
+71B1:104010407C4010F8FE48444892C87C4810AA1CAAE10642020000488844448444
+71B2:400044FE7810422042FC3E84008410FC528452FC5484908428FC244844848102
+71B3:100011F8110811F8550859F8500093FC129413FC100029F82490446041988606
+71B4:20402444244427FCA800B7FCA404A7FC240427FC2000242457A84C3245A2861E
+71B5:1040102013FE1488585053FE5252928A130612FA128A2A8A26FA4202420A8204
+71B6:200023F8220823F8AA08B3F8A000AFFE248027BC2494279454D44F88409480A2
+71B7:11041088100013FE56225AAA5272922213FE100011FC290425FC450441FC8104
+71B8:200027BC21082528AFBCB318A5AAA946200023F82208220853F84A08420883F8
+71B9:01007FFC01003FF800003FF820083FF80820FFFE00003FF820083FF824884244
+71BA:102013FE102011FC540059FC510491FC108813FE100029FC2504450441FC8104
+71BB:204020A021182EE6B000A3F8A208A3F8200027BC208424A452944CA44A948108
+71BC:200027FC244427FCAC44B7FCA110A11027FC211021102FFE5000491042088404
+71BD:102011FC102417FE582451FC502092AA13AE122213FE2A2227AE42AA42AA8422
+71BE:1110109413D214125A50519057FE901013D2125212542BD4264A424A43D68022
+71BF:1088108811FC108854885BFE502091FC112411FC112429FC2400448841048202
+71C0:100013DE1252125257DE580051FC912411FC112411FC282027FE442040208020
+71C1:108813FE1088100055FC58A850A893FE10A810A811FC282027FE442040208020
+71C2:100013FE105013FE56525BFE500091FC110411FC110429FC242047FE40208020
+71C3:1110111411D216505A7E5550509092A81128114412442C82240842A442528452
+71C4:101010523E5422904428804410826610425242546698421042287E2842440082
+71C5:081008527E5408900828FF4424824210895208547E98081008280F28F8444082
+71C6:101C11E0104017FE5888510452FA948810F8100013FE2A0226FA428A42FA8206
+71C7:1088105013FE105055FC5954518C9174110411FC10082BFE2508448840A88010
+71C8:202027A420A82A92B114A208A5F4A80223F82208220823F8520849104FFE8000
+71C9:2208210827C82010AF9EB494A7A4A01427942094211421C85708491445248242
+71CA:1108211002E00C1870040010525294942828C4C401007FFC05401930E10E0100
+71CB:1090108811FE15105B1055FE5110911011FE1110111029FE250042A442528452
+71CC:102011FC102014885BFE508851FC910411FC110411FC290425FC448841048202
+71CD:22402242225C27F0AA50B3D0A25EA3D42254225427F4201452944C6448248044
+71CE:2040204027FC20A0AD14B208A7FCAA0A23F8220823F8204052484C4449448080
+71CF:100013FC104814305BFE505250949350102013FE12522A8A2776425242728206
+71D0:20402248215027FCA950B248A444A210239024BC2A902150517E4A1042108410
+71D1:102011FC108814505BFE500051FC912411FC112411FC282025FC442043FE8000
+71D2:1020102011FC14205BFE5108539C91081188163E10002BFE249044904112820E
+71D3:24482288F93E22886458729CA92A22882448010011101120228004401830E00E
+71D4:103C13E0112410A855FE58A85124920211FC1124112429FC2524452441FC8104
+71D5:0440FFFE0440044017D01012F01C17D014503452D7D2100E0000488844448444
+71D6:100013FC100413FC54045BFC500093BC112417BC10082BFE2508448840A88010
+71D7:279E2492279E2492AF9EB402A4F2A49224F2249224F2249254924D3244028406
+71D8:100013DE125217DE5A5253DE5242922212FA121212522A2226524282420A8204
+71D9:23F8120893F8420843F810002FFEE20027FC292422540588111022A00C60701C
+71DA:1010525254549090282844448282101010525254549890102828242842448082
+71DB:0000FEFE12907EFC42847EFC1290FEFE01001110111022A0044008203018C006
+71DC:2000279E2492279EAC92B79EA442A422240A25462542255256324C02440A8404
+71DD:100011FC110415FC590451FC502093FE100011FC110429FC2420452442228060
+71DE:142012203F3E24426494BF1024103F10242824283F4420820000488844448444
+71DF:08202AA44D28145022887FFE40029FF410101FF000003FF8200820083FF82008
+71E0:2080210027FC2444AD54B444A7FCA4E425542404204027FE50A0491042088C06
+71E1:100013FE125213FE542059FC502093FE1088105011FC282027FE442040208020
+71E2:0A803138228838382288393822887FFE41029114111022A0044008203018C006
+71E3:102013FE100011FC5504597451549174110411FC100828F0242047FE40A88326
+71E4:1088108813FE148859FC512451FC912411FC102013FE2A22262A42FA420A8206
+71E5:10F81088108814F8580051DC5154915411DC102013FE287024A8412442228020
+71E6:208020DC22842BD4B448AA94A324AC402248215027FC20E051504A484C468040
+71E7:104412241128147E58105028534A911C1128114C111A292A2548411042FE8400
+71E8:220821102FFE2840B7FCA040AFFEA054279221102FFE211051D44F0A49168322
+71E9:2108220827C82450AFDEB464A7D4A214211427D4221423C852484C54455488A2
+71EA:108813FE108815005BFC555450D49324105410941348282024A4428A428A8478
+71EB:102013FE1288125057FE5A5052FC925413FE125412FC2A5026D8455446528850
+71EC:210026DC24542454AED4B454A466A7C0201C201427D42114510849C847148222
+71ED:200023F822A82AA8B3F8A100A3FCA48423E422A422A423E450944FF448148008
+71EE:210827C820086B9AB02C2388200853944A928BA200003FF0082004C00780F87E
+71EF:100011FC102013FE562259AC502091AC105010C8132628F8240844D040208010
+71F0:203C23C020442224A908B7FEA442A2A4228A247A208020F851084A904060879E
+71F1:1040102011FC1488585053FE500091FC110411FC110429FC24204294428A847A
+71F2:104013FC1044109455085BDE514A92D611FC110411FC290425FC450441FC8088
+71F3:200027BE24922492ACAAB7A4A4C0A4BE24A224A227BE24A250004AA442528452
+71F4:204020A023182DF6B000A7FCA554A4E427FC200023F8220853F84A084BF88208
+71F5:10101410127C141058FE5044562892FE1210127C12102AFE2610421045FE8800
+71F6:109013FC129417FC5A9453FC500093FC120012F812002BFE2520451445488986
+71F7:102013FE100015FC5904517451549174110411FC100029FC240043FE41248262
+71F8:100011FC102013FE562259AC502091AC100013FE102029FC255445544154810C
+71F9:FEFE202050509A9A2C2C48489C9C2A2AC8C818180100111022A004401830E00E
+71FA:102013FE100014F8588850F8500093FE1202127212522A76242043FE40A88326
+71FB:101C11E0102013FE542059FC51AC917411FC102011FC282027FE44004154822A
+71FC:204023F8204827FEA848B3F8A040A7FE200022A4245223F852A84AA84FFE8000
+71FD:204027FC204023FCA800B7FEA002A3F8204027FE200027FE50084FFE44A88798
+71FE:01007FFC01003FF80000FFFE00023FF00100FFFE00107DFC44907C3024884244
+71FF:100013DE10421252554A5A525090910813FE151011FE291025FE451041FE8100
+7200:21102110211027BCA910B110AFFEA2A822A826EC2AAA22AA52A84DA844488898
+7201:100813E8128817EE5A2853F4528293E2100011FC115429542554415447FE8000
+7202:2FEC48244BA4682C4BA46AAC4BA44824FFFE810211101120228004401830E00E
+7203:108812AA12DC148859545222500093FE1222102013FE287024A8412446228020
+7204:100013FE124817FE5A4852FC52A492FC12A412FC12202BFE272A457A450A8906
+7205:11FC112411AC152459FC502051FC902013FE1154122A282025FC402043FE8000
+7206:11FC110411FC150459FC508853FE908817FE108811242AAA247040A841248060
+7207:0820FFFE082010407C4011F8FE4844C892487CAA10AA1D06E202488844448444
+7208:2020203E202027FEAC22B5F8A422A5FE252425FC252425FC58404AA4528A847A
+7209:11241248112414005BFC52945264929413FC124813682A48276A424A42468362
+720A:2080204027FC24A0AFFCB4A4A7FCA400252425A8253025A4551C48004AA49452
+720B:21C82708210827C8A93EB7CAA54AA7CA254A27CA210A27CA510A4FEA4AAA9156
+720C:2040202027FE2488ADFCB488A7FEA42025FC252425FC252455FC4C0044888904
+720D:244424E428A82AAAAEEEB4A4AAAAAEEE224220402FFE20E051504A484C468040
+720E:1040102013FE122255FC5850528A91FC128A10F8108828F82420452442A28040
+720F:200027FE24442598AC88B7DEA488A5DC26AA248824202520553C4920492097FE
+7210:1040107C104013FC56445BF0524492FC12A812F812A82AF8260045FC45548BFE
+7211:1088108813FE14A8589051FE512093FC152011FC112029FE250042A442528452
+7212:101010101EFE221054AAA8441082287CCA442A7C2C44487C1410125422924030
+7213:13DE125213DE16525BDE5242527A928A131212DA128A2ADA268A42FA420A8204
+7214:211027FC204023F8A840B7FCA000A3D4211227FE23502534538C488A42968102
+7215:210827C820086B9AB02C2388200853944A928BA20100111022A004401830E00E
+7216:2210211027DE2010AC5EB282A7DEA01027DE245027DE245057DE4C50445284CE
+7217:11FC110411FC150459FC508853FE908811FC10A813FE28A825FC442043FE8020
+7218:108010DE128213D454485AB4514A96A411FA128810F8288824FA449440A880C4
+7219:102013FE100015DC595451DC508893FE108813FE10882BFE2494418842A480C2
+721A:204020A021102208ADF6B000AEEEAAAA2EEE20002FFE29225FFE4922492A8804
+721B:13DE125213DE16525BDE522252FA922212FA12AA12FA2AAA26FA427242AA8226
+721C:249222942FFE2910B7FCA040A3F8A0402FFE248027BC249457944CC84F9480A2
+721D:101E13E0112214945BFE525253FE900413C4127E13C42A5427CC428442D48348
+721E:2040204023F82248ABF8B044A7FCA00422082FBE2AAA2FBE52084A8A4FBE8082
+721F:208823FE208823DEAA52B3DEA0A0A09021FE212023FC252051FC492041FE8100
+7220:27BC24A427BC24A4AFBCB4A4A7BCA12023FE222027FC2A2053FC4A2043FE8200
+7221:108813FE108811FC552459FC512493FE122A12FA122629FC252445FC402283FE
+7222:00803FFE24103F7C26382D54341221202F3C2120273821202F3C41205244A122
+7223:2248215027FC2404A9F0B110A7FCA55424E427FC204027FC50404FFE42A48452
+7224:211027FE211027BCACA4B7BCA4A4A7BC244427FC255425F454444CE445548448
+7225:13FE120213FE16925A54529252FE92AA12FE132212FA2AAA24FA442249FA8004
+7226:2790251E27A82484AFBEB52AA7BEA00023F8220823F8220853F848A04124861C
+7227:27FC20402FFE2842AB58B040A358A0002EEE2AAA2EEE20005FFE4A4845548FFE
+7228:2FEC48246BAC48246BAC4AA4FFFE88227EFC2C684AA4FFFE11102928C6C61830
+7229:228822E82F5E22ECAF5ABAE8A208AFFE29423494255827F252044BE8420283E4
+722A:001000F81F201220122012201220122012201210121022102208420842048002
+722B:00000008007C07807A1021101120100000000000000000000000000000000000
+722C:0E00740055FC55245524552455FC550055005502550252FE5200510090FE1000
+722D:000801FC7E10221011203FF801080108FFFE010801083FF80108010005000200
+722E:024007403A7C2A842B742A542A542A742A482942294228BE28404830480E8800
+722F:000801FC7E102210112001003FF8210821083FF821082108FFFE200820282010
+7230:000801FC7E10221011203FF8020002007FFC04000FE01420224041808660381C
+7231:000801FC7E10221011207FFE420282047FF8040007F00A10112020C043301C0E
+7232:00FC7F00121009201FF0101010101FF8100810081FFE20022AA2495251548008
+7233:00F83F2009401FE010201FF010101FFC20042AA4400C9FE00040018005000200
+7234:0004FF0E8D748B54FF548954E954A954EB548554E5548B549154FF9200920100
+7235:00FC7F00220811107FFC44447FFC00087E0842FE7E0842487E28480874284210
+7236:044008201010200840240820082004400440028001000280044008203018C006
+7237:044008201850248803000CC03030C00E1FF00210021002100250022002000200
+7238:044008201850248803000CC03030C00E1FF0111011101FF01010100410040FFC
+7239:044008201850248803000CC03230C7CE1A4001A01E7801880E90006003803C00
+723A:084010202850448803001CE0E01E00007F7822483E5022483E4423D4FE480240
+723B:00081810066001800660181860040020082004400280010002800C403030C00E
+723C:040045F829081108290845F881080508450829F8110829084508810807FE0000
+723D:010001007FFC01002928111029280100292811102AA80280044008203018C006
+723E:00007FFC21084104BFFA21083558292835582108355829283558210821282010
+723F:00100810081008100FF00010001000107FF00810081008101010101020104010
+7240:042024202420242025FE3C2004700470FCA824A8252425242622442044208420
+7241:0400240025FE240824083DE805280528FD28252825E825282408440844288410
+7242:048424442448240025FE3C20042004FCFC20242025FE24202420442044208420
+7243:04482548254827FE25483D4805780500FDFE242027FE247024A8452446228420
+7244:042024202450244824A43DFE068404FCFC8424FC248024FC25444544467C8444
+7245:102057FE542055FC542477FE142415FCF42055FC552455FC552455FC5524892C
+7246:082028202BFE292429243AAA0FFE0800F9FC2904297429542974490449FC8904
+7247:004010401040104010401FFC1000100010001FE0102010201020202020204020
+7248:0808481C49E0490049007DFC41444144794449284928491049104A284A448C82
+7249:04202420252424A424A83E2021FC20203C20242027FE24202420442044208420
+724A:040025FC2444244424443E44209420883D0024FC248424842484448444FC8484
+724B:04482444245E25E024283E12206A21963C48245E25E0242424284412446A8586
+724C:0840488049FC492449247DFC4124414479FC489049104BFE4810481048108810
+724D:0820482048FC482048207DFE4002409478504890485049FE4828484448828902
+724E:0880488048FC49544AD47CB4412C424478944908484048A44AAA4A8A4C788800
+724F:08204850488849044AFA7C0041E2412A792A49EA492A492A49EA4922492A8964
+7250:0808483C49E0482048207DFE402040A0792C4924492449AC4924492449FC8904
+7251:0840482049FE490249027DFE4100410079FE49AA4AAA4AFE4CAA48AA48A28886
+7252:0848494849484BFE49487D484178410079FE48204BFE487048A849244E228820
+7253:0820481049FE488448487DFE41024224781049FE4840487C4844488448948908
+7254:082848244BFE482049FC7D2441FC412479FC492448084BFE4888484848488818
+7255:0820484049FC4924497C7D8C41544124795449FC484048244AA24A8A4C888878
+7256:084048204BFE4A024BFE7E1443FE42107AFE4A924AFE4A924AFE4A924C928896
+7257:081049FE4910497C49147DFE4114417C7910497C4954497C49544A7C4A548C4C
+7258:08204BFE482049FC48007FFE425243FE790449FC490449FC490449FC48888904
+7259:00003FFC004000401040104020403FFE01400240044008401040604001400080
+725A:111009207FFE40029FF410101FF000007FFC104020403FFE0240044019406080
+725B:01001100110011001FF82100410001000100FFFE010001000100010001000100
+725C:08000800480048007E004800880008000E00F800480008000800080008000800
+725D:08800880488048847E88489088A008C00E80F8804880088408840884087C0800
+725E:10401040504050407DFC5044904410441C44F084508410841104110412281410
+725F:02000400082010103FF80008010011001FF821000100FFFE0100010001000100
+7260:10201020502051207D2C5134916413A41D24F134512811221122110210FE1000
+7261:08200820482048207E20482089FC08200E20F82048200820082008200BFE0800
+7262:020001007FFE40028104110011001FF8210041000100FFFE0100010001000100
+7263:1000100051FC50447C445144914411441D44F244504410841084110412281410
+7264:10201010501050007DFE5080908010801C80F080508010801080108010FC1000
+7265:10401020502053FE7C805080908010FC1C84F084508410841104110412281410
+7266:0808083C49E048207E20483C89E008200E20F83E4BE00820082208220822081E
+7267:08400840484048807EFE49088A8808880E88F850485008200850088809040A02
+7268:10801040504053FC7C00500091F011101D10F1105110111211121212120E1400
+7269:10801080508050FC7D545254905410941C94F124522410441044108411281010
+726A:08100810489048907EFE4890891008100E10F9FE481008100810081008100810
+726B:08500848484848407E5E49E0884008440E44F848483008220852088A0B060802
+726C:10201020502E51F07D205120912011FE1C22F06250A2112A1624102010201020
+726D:1000100053FC52947E945294929412941E94F294529C13041204120413FC1204
+726E:08A0109030BE57C0904010241014110C09001FF821000100FFFE010001000100
+726F:10201020502050207DFE5020902010201DFCF104510411041104110411FC1104
+7270:10201020502050207DFC5124912411241D24F1FC512411241124112411FC1104
+7271:1000100053FE50087C0851E8912811281D28F12851E811281008100810281010
+7272:10201020512051207DFC5120922010201C20F1FC502010201020102013FE1000
+7273:100010FC508450A47C945084908413FE1D04F1445124110411FE100410281010
+7274:1004101E51F051107D105110911011FE1D10F11051101108110A114A11A61112
+7275:010001003FF80280044008207FFE410289040FF0110001007FFC010001000100
+7276:0100111009203FF802007FFC082011102908CFF6110001007FFC010001000100
+7277:10201020505050887D04520291FC10201C20F02051FC10201020102013FE1000
+7278:1040102053FE52027C0451F8900810101C20F3FE502010201020102010A01040
+7279:10201020502051FC7C20502093FE10081C08F1FE500810881048100810281010
+727A:100017FE509050907C9053FC929412941E94F294529C13041204120413FC1204
+727B:10901088508051FE7CA050A890B010A41CA8F0B05124112A1132122212DE1400
+727C:100011FE500050927D245248912410921C00F1FE502010201020102013FE1000
+727D:01007FFC08201FC002007FFE48229FF4011011001FF821000100FFFE01000100
+727E:100013FE504050407DFC5084908413FE1C00F00051FC11041104110411FC1104
+727F:10201120512051FC7D205220902013FE1C00F00051FC11041104110411FC1104
+7280:00003FFC20043FFC2000288826B02808248027F8288020805FFE408080800080
+7281:03083C0804487F480C48164825084428051011001FF821000100FFFE01000100
+7282:0C8070FC1124FD241244388455289010010011001FF821000100FFFE01000100
+7283:1040102051FC50007D085090900013FE1C00F00051FC11041104110411FC1104
+7284:1020102051FC50507C88510493FE10081DE8F128512811E81128100810281010
+7285:100013FE5202528A7E5253FE922212221EAAF2AA52AA12FA12021202120A1204
+7286:1020102053FE50207C2051FC910411FC1D04F1FC510411FC1104110417FE1000
+7287:010009000FF0110001007FFC0100111051507C7C90901E10F0FE501010101010
+7288:1020112450A850207DFC504093FE10881D04F2FA5488108810A810921082107E
+7289:1040102053FE50007DFC510491FC10001DFCF008501013FE1020102010A01040
+728A:1020102051FC50207C2053FE900210941C50F110509013FE1028104410821302
+728B:100011F8510851087DF8510891F811081DF8F108510817FE1000109011081204
+728C:100013DE524252427A4253DE9200123E1BD23212D21413D41208121412241242
+728D:10101010577C51147DFE5214927C17101D7CF51055FE12101210150018FE1000
+728E:08087E0808FEFE0808487E2808080F28F11011001FF821000100FFFE01000100
+728F:1080104053FC52047E0453FC920012001FFCF354535415FC155415541944110C
+7290:10C417045124511479145784912411141B943346D53C15041104110411041104
+7291:100011FC510451FC7D0451FC910411FC1C28F02453FE10501050108811041202
+7292:1040102053FE50007DFC510491FC10001FFEF20252FA128A12FA1202120A1204
+7293:1080108051FC5244795451F4908411281A9031FCD244155411F4108411281210
+7294:1100110051FC52007DF8500093F810881AA831C8D7F8108A11CA16AA10861082
+7295:1088108853FE5088788857FE908011FC1B2435FCD12411FC112411241124110C
+7296:08202AA42CA84920145022887FFE410289041FF821000100FFFE010001000100
+7297:1040102053FE52027C2451FC902011FC1C20F3FE502011FC1104110411FC1104
+7298:010000803FFE22102F7C26382B5432922040224023FC244020405FFE40408040
+7299:1040108851FC51087A5253FE905011881E2630C0D31010641388103010C01700
+729A:3F0821083F7E20082F4820285FA8440895282C9011001FF82100FFFE01000100
+729B:08203E7E08A47F281C102A2849443FFE2480248027F8288020805FFC40808080
+729C:1108108853C850107BDE526493D410141BD43054D09410E81388109412941122
+729D:102011FC508850507DFE500091FC11241DFCF12451FC102011FC102013FE1000
+729E:101811E0504053FE7C885174925210701C00F1FC51041174115411741104110C
+729F:7CF8048804F87C2041FC7D2405FC04282BFC100411001FF82100FFFE01000100
+72A0:1104108853FE50207DFC502093FE10541D92F09053FE109010D4138A109611A2
+72A1:100013FE524853FE7E4852FC92A412FC1EA4F2FC522013FE132A157A150A1906
+72A2:102013FE502051FC7C0053FE925213FE1D04F1FC510411FC110411FC10881104
+72A3:11241248512450007BFC5294926412941BFC3248D3681248136A124A12461362
+72A4:100013FC529452947BFC5110925213DC181233CED24013D2125C13D0125212CE
+72A5:1040102053FE52507BFE525293FE12001A9432D8D29012D2128E140015541A2A
+72A6:13F8120853F852087BF8511097FC11101FFE3110D248155410E01150124810C0
+72A7:111017FC504053F8784057FC900013D4191237FED3501534138C108A12961102
+72A8:081024483F7E64C8BF7E24483F7E24483F7E204011001FF82100FFFE01000100
+72A9:7C4011FCFD2439FC5524FDFC246818A2651E11001FF821000100FFFE01000100
+72AA:211027FEA040A2EEFAAAABEAAAAE2AE83BAAECE6228825F42290206021982606
+72AB:51184B947C3ED3A87C7E53A87C3E53A87EBE43A011001FF82100FFFE01000100
+72AC:01000120011001100100FFFE010001000280028004400440082010102008C006
+72AD:0000440028001000280048008800080018002800480088000800080050002000
+72AE:01100108010801007FFE0200040007F80A080A08111020A0404080A003180C06
+72AF:0000440029F81108290849088908090819282910490089020902090250FE2000
+72B0:00804480288010802BF0489088900890189028904890889209120912520E2400
+72B1:004044402840104029F8484888480848194828C8484888A808AA090A52062402
+72B2:00104410281010102BFE48308830085018502890489089100A10081050502020
+72B3:00404440288010FC29044A048804090418842844484488040804080450282010
+72B4:000045FC282010202820482088200BFE18202820482088200820082050202020
+72B5:00804480290011FE2A004C0089F8080818102860488089000A020A0251FE2000
+72B6:084008480844484428402FFE08400840184028A0C8A00890091009080A040C02
+72B7:00204410281011FE2900490089000900190029004900890009000A0052002400
+72B8:000047F02810101029104910891009FC1804280448048BF40804080450282010
+72B9:00904488288810802BFE48A088A008A018A028A04920892209220A22521E2400
+72BA:00804440284013FC2800480089F00910191029104910891209120A12520E2400
+72BB:00204420282013FE2820482089FC092419242924492489340928082050202020
+72BC:00108FD0505020905110911011501190311057109110111211121112A50E4200
+72BD:000045FC28101110291049108A100BFE183028504850889009100A1050502020
+72BE:0040885050482048504097FE1040104030A050A090A0111011101208A4044802
+72BF:00404420282010002BFE48408840086018502848484488440840084050402040
+72C0:042024282424242424203DFE04200420FC202450245024502488448845048602
+72C1:004044402880108829044BFE88020890189028904890889009120912520E2400
+72C2:0000440029FC1020282048208820082019FC2820482088200820082053FE2000
+72C3:000045FC284410442844484488440BFC18842884488488840884088453FE2000
+72C4:00404440284010402944494489480A50184028A048A088900910090852042402
+72C5:0008443C29E010202820482088200BFE18202820482088200820082051FC2000
+72C6:002044202820102029FC492489240924192429FC492488200820082050202020
+72C7:00404440284010402BFE484088E008E0195029504A488C440842084050402040
+72C8:000045FC29041104292449248924092419242924492488500848088451022602
+72C9:000045FE2810101028204820886808A419222A22482088200820080053FE2000
+72CA:00003FF820083FF820083FF820083FF801100108FFFE0280044008203018C006
+72CB:000045FC2800100028004BFE88200820192829244A248A220C22082050A02040
+72CC:002044202920112029FC49208A200820182029FC482088200820082053FE2000
+72CD:0080448029FC11042A044DF489140914191429F4490489280912090250FE2000
+72CE:000045FC29241124292449FC89240924192429FC492488200820082050202020
+72CF:0080448028FE11002A204920892C09741BA42924493489280922090250FE2000
+72D0:0008883C53D02290529092901290129032905288928812C812A414D4A4924800
+72D1:0040444028A010A029104A488C2608201BF828084810891008A0084050202020
+72D2:00904490289013FC289448948BFC0A901A902BFE48928892091A091452102410
+72D3:00104410281011FE29124914891009FC194429444928892809100A2852442482
+72D4:000045FC29041104290449FC89000940194429484970894009420A42523E2400
+72D5:002089205120222052FC94A4172411243224522494A417A410C41044A0944108
+72D6:00404420282013FE2A024C048800089018902890488889080908090452042402
+72D7:00804480290011FC2A044C0489E409241924292449E489240804080450282010
+72D8:00284424282410202BFE4A208A240A241A242A284A288A900B120A2A50462082
+72D9:000045F829081108290849F889080908190829F8490889080908090857FE2000
+72DA:0000440029FC11042904490489FC09041904290449FC89040800080053FE2000
+72DB:00204420284011FC290449048904090419FC2904490489040904090451FC2104
+72DC:00204420282010202BFE48208820082019FC2904490489040904090451FC2104
+72DD:00804480288011FE29024A048C200820192829244A248A220C22082050A02040
+72DE:00404420282013FE2A024C04880008001BFE2820482088200820082050A02040
+72DF:000045FE2800100029FC4904890409FC1904290449FC89040800080053FE2000
+72E0:000045F82908110829F84908890809F819442948493089200910094851862100
+72E1:00404420282013FE2800488889040A0218882888485088500820085050882306
+72E2:0080448028F811082B104CA0884008A019182A064DF889080908090851F82108
+72E3:009044902890129229944898889009981A942C9248908890091209125212240E
+72E4:00204420282013FE2820482089FC0800180029FC490489040904090451FC2104
+72E5:0080448029FC11042A0449E48924092419E42924492489E40904080450282010
+72E6:00008BF852A822A852A89FFE12A812A832A85FFE92A812A812A812A8A2084218
+72E7:0008443C29E0102028204BFE88200820182029FC490489040904090451FC2104
+72E8:00284424282410202BFE48208924092419242BA8492889100A120A2A54462082
+72E9:0040882053FE220254149010101013FE301051109090109010101010A0504020
+72EA:000045FE29021102297A49028902097A194A294A494A897A09020902510A2104
+72EB:00404440284413F4284848508FFE0840188029844A988CE008820882507E2000
+72EC:00204420282011FC292449248924092419FC29244820882808240BFE51022000
+72ED:00204420282011FC2820492488A408A818202BFE485088500888088851042202
+72EE:010089FE51102510557C9554155415543554555495541154125C1210A4104810
+72EF:0040884050A021105208940611F01000300057FC9040108011101208A7FC4204
+72F0:0080448029F0121028204BFC884408441FFE284448448BFC0844084051402080
+72F1:002094285224222450209E2012FC12203220525092D0135012881088A1044202
+72F2:00008810579020905110921012D81354325456929A92131212101210A2504620
+72F3:0040884050A02110520895F61040104037FC50409250124814441844A1404080
+72F4:02208A24522823B05220922212A2131E3040504093FC104010401040A7FE4000
+72F5:00904488288013FE28A048A888B008A418A828B04924892A09320A2252DE2400
+72F6:01844468283010C82B0448408BFE08A019202BFC4D2489240934092850202020
+72F7:000045F82908110829F848008BFC0A041A042BFC4A048A040BFC0A0452142208
+72F8:000045FC2924112429FC4924892409FC1820282049FC88200820082053FE2000
+72F9:00204420282013FE282048208924092419242AAA482088500850088851042202
+72FA:004044202BFE1000280049FC8800080019FC2800480089FC0904090451FC2104
+72FB:00404440288811042BFE4802888809441A4228F849888A500820085051882606
+72FC:0040442029FC1104290449FC8904090419FC2920492289140908094451822100
+72FD:000045FC2904110429FC4904890409FC1904290449FC88000888088451022202
+72FE:0104890E5130212057E09120113E116431A457249124112411241124A5444284
+72FF:0004440E2BB8108828884928892E0BA818A82AA84AA8893E09000A80547E2800
+7300:00108A10511021105454925212521090301051149604120812081210A22040C0
+7301:008489C457042114511491141FD41114331453949554150419041104A1144108
+7302:000045FC290411FC290449FC8800080019FC282048208BFE0820082050202020
+7303:0040884050A020A05110920815F61000308850489248115011101020A7FE4000
+7304:004044202BFE1000280049FC89040904190429FC482088A809240A2250A02040
+7305:009088905090279E509090901090139C309050909090179E10901090A0904090
+7306:044004407C7C04403C7804407C7C04400440012001107FFC028004401830E00E
+7307:00204420283E102029FE4922893809E01922291E490089780A480A4A548A2906
+7308:0040448029FC1124292449FC8924094419FC289049108BFE0810081050102010
+7309:008844882BFE1088288848F88888088818F8288848888BFE0800088851042202
+730A:00009040539C22045204939C1204120433FC50909090109010901112A212440E
+730B:01100108FFFE0280044008203018C00614281224FDFE10202850245044888106
+730C:081008140812FF1208102AFE2A102A105D1088281C282A284944884408840902
+730D:00408840504027FC5040924812481248355450E09150115012481444A8424040
+730E:00884488288813FE288848888FFE080019FC2904490489FC0904090451FC2104
+730F:0040882053FC2204520493FC120012FC328452FC928412FC14841484A8944088
+7310:02088908511027FC5040904013F8104030805FFE9120112012201222A422481E
+7311:000045FC2904110429FC4904890409FC1800291249D48918091009525192210E
+7312:00107E1442127E1242107EFE00107E1042107E2842287E28424442444A844502
+7313:00008BF85248224853F89248124813F8304057FC90E0115012481446A0404040
+7314:004044202BFE1202280049FC880008001BFE2820492889240A220C2250A02040
+7315:002097205120213E5142974414901410341057549152115211921110A5504220
+7316:01F84508290811F82908490889F808001BFC2A044A048BFC0A040A0453FC2204
+7317:0040884053FC20A05110920817FE100833C852489248124813C81008A0284010
+7318:00828882528223EA548A908A17FA108A33EA52AA92AA12AA12A212E2A08A4084
+7319:003C47C02A44112828004BF8884808481FFE284848488BF80848084051402080
+731A:00A04490288011FE29104B108DFC0910191029FC49108910091009FE51002100
+731B:000045FC2808101028204BFE882008A0184029FC495489540954095457FE2000
+731C:002044202BFE102029FC48208BFE080019FC290449FC890409FC090451142108
+731D:0080884057FC20005110911012A814443000504097FE104010401040A0404040
+731E:0040884050A02110520895F61040104037FC5040904013F812081208A3F84208
+731F:0000948452442248500093F81248124833F85248924813F8124A144AA4464802
+7320:00904490289013FC2A944A948A940BFC1A942A944A948FFE0800089051082204
+7321:00008BFE52522252525293FE1020104030FC51049288105010201040A1804600
+7322:0100891E511227D25112911E111217D23452545E945217D214521022A02A4044
+7323:000044882A5212222A524A8A8A020BFE188829444A7A88880950082050D82706
+7324:001045D428581252298C488889040AFA1820282049FE88200850088851042202
+7325:00008BF85248224853F89248124813F8300057FE9240124412281290A3084206
+7326:000097FC5404243465C4A44425F425546554A5F42444245425F42494A8065002
+7327:000045FC2904110429E4492489240BFE1A022AFA4A8A8A8A0AFA0A02520A2204
+7328:003C97C052442128500093FC1080108037FE510091F8128812501420A8D84306
+7329:00008BF8520823F8520893F81040124033FC5440904013F810401040A7FE4000
+732A:0040884453F42048505097FE1040108031F85308950811F811081108A1F84108
+732B:008844882BFE10882888480089FC09241924292449FC89240924092451FC2104
+732C:000097FC544427FC544497FC100013F8320853F8920813F812081208A2284210
+732D:010089F8520823F0501097FE10801144366850B09128166810A41122A6A04040
+732E:08100814FF92081208107F7E4110551049105D1049287F284928494445444282
+732F:004094445444244457FC90001FFE1040308057FC94A414A414A414A4A4A4440C
+7330:0080449E2BEA108A29CA488A8BEA089218A628204BFE88200850088851042602
+7331:00008BF85090206057FC90A4112812203460504097FC10E011501248AC464040
+7332:000045FC290411FC290449FC888009FE1A2229224952890209FA080250142008
+7333:000097BC54842484548497BC1400140037BC5424942417A814101428A4444482
+7334:010089785108220852FE96401A40127C3290521092FE121012281228A2444282
+7335:0080884053FC2204520493FC1200120033FC5354935415FC15541554A944410C
+7336:01084488289017FE289048908BFC0A941A942B0C4A048BFC0A040A0453FC2204
+7337:221012141412FF92141014FE7F1055105510632841287F28414441447F844102
+7338:00008BFC5224222453FC920012FC1284328452FC928412FC12841284A4FC4884
+7339:0040904057FC20E051509248144613F8320853F8920813F812081000A7FE4000
+733A:0008443C2BC010042A44492889FC0A2018202BFE482089240924092451FC2004
+733B:00068F78511021205244927813101224367E5A129210125412521292A2504620
+733C:002844242BFE102029FC492489FC092419FC292448088BFE0888084850482018
+733D:000047FE2A02100029FC490489FC090419FC284048208BFE0800088851042202
+733E:00008BF8520823C852489FFE180213F8320853F8920813F812081208A2284210
+733F:0040904053F8204057FE900013F81208320853F890A4112813101D48A1864100
+7340:0140965C54442444575C9444144417FC304057FC9208111010A01040A1B0460E
+7341:00008BFC524023F8524093F81240124033FC50049554155415541404A0284010
+7342:000045FE29101120297C4944897C0944197C29104910895409520A9252502420
+7343:08104914491249127F1000FE7F1000107F1041287F28412822440F44F0844102
+7344:02109114511227D250109790103E17903010579094A814A814A817C4A0444082
+7345:020094FE57102510557C955417541454345457549554155C15101710A5104010
+7346:0020444029FC110429FC490489FC08401BFE288849248A220DFC082050202020
+7347:0208891057FC2040504093F81040108037FC50A091281134123C1222A422481E
+7348:020889085110200057FC900011101208340453F892A812A812A812A8AFFE4000
+7349:0040884057FC204053F8908017FC1110326855C6904013F810E01158A6444040
+734A:0040884050A02190524897FE1A0813F8320853F8920013F815081508A9F84108
+734B:004045FC290411FC290449FC890409FC1820292448A8892408200BFE50202020
+734C:000045F8290811F8290849F888000BFC1A942BFC480089F80890086051982606
+734D:0080884053F8211050A097FE100013F8320853F8920813F811201122A2224C1E
+734E:0440247C24A83D5004287DFE248844488418012001107FFC028004401830E00E
+734F:008844882BFE1088280049FC890409FC190429FC48208BFE0850088851042202
+7350:002045FC288810502BFE480089FC090419FC290449FC88200BFE082050202020
+7351:01008902511C27D0511097D0155E17D4355457D4911417D411141124A1244144
+7352:08207F20083E7E440884FF2820103E284244872201107FFC028004401830E00E
+7353:01089108510827D0511E979411241FD4321453D492541248124814D4A4244842
+7354:0020444029FC110429FC490489FC0820192428A8492488200BFE082050202020
+7355:002046222BFE1090288849FE8B100D1019FE2910491089FE0910091051FE2100
+7356:002045FC282010882BFE488889FC090419FC290449FC890409FC088851042202
+7357:00009FFE58002A286948ABEE289228846AA0AAA82BE8288828942914A9245242
+7358:082049202A3E7F4849485DA86B104928414440200110FFFE02800C603018C006
+7359:0108890855482390511E97D4156415543554575495D4154815481554A46444C2
+735A:0088448829FC108828884BFE882009FC192429FC492489FC0800088851042202
+735B:00A094A452A820A057FC911010A017FC304053F8904017FC10A01110A2084C06
+735C:0020452428A813FE28A849248A220904190429DE4A448D54089E090452042404
+735D:000045FC284810302BFE485288940B5018202BFE4A528A8A0B760A5252722206
+735E:002045FC288810502BFE480089FC092419FC292449FC882009FC082053FE2000
+735F:0020442029FC10202BFE49088B9C090819882E3E48008BFE089008905112220E
+7360:0040904057FC20A05514920817FC1A0A33F8520893F8104012481444A9444080
+7361:00808B1C52042204539C9204120413FC310053FE940212AA12AA1402A0144008
+7362:00388BC0508027FE5110920815F6191031F0500097FC140415F41514A5F4440C
+7363:9090491402127F1249107FFE49107F100010FFA800287F28414441447F844102
+7364:0208890857C82010579E949417A4101437945094911411C817081114A5244242
+7365:01088A0857C8245057DE946417D41214311457D4921413C812481454A55448A2
+7366:008847FE288811FC290449FC890409FC188029FE4A228D52090209FA500A2004
+7367:00008BFC5294229453FC900017FE100033FC520493FC10A211141308AD444182
+7368:000045FC2954115429FC488089FE0A4219F22952495289F2084A0BFA500A2004
+7369:0020893C512027FE5010901413FE121033F05254925412D41368144AA8964322
+736A:004088A053182DF6500097FC155414E437FC500093F8120813F81208A3F84208
+736B:0040444028A011102A084DF6880008001BB82AA84AA88BB80910091052A82444
+736C:0200939E548A290A67D2A566254027D4655EA56427C42544255E2544A44448C4
+736D:021092105F9C22246248AFBE2AA22AAA6FAAA22A272A2AAA32882214A2224242
+736E:000097FC524824446FFEA44426EC255466ECA44426EC255426EC2444A4544408
+736F:003C97C050402FFE504097FC155414E437FC504097FC10401FFE1000A5244892
+7370:0080884057FC244452A892941474100033F852A89FFE100017FC1040A1404080
+7371:004044202BFE120229FC49488A5009FC1B0429FC490489FC090409FC50882104
+7372:008847FE28A8109029FE4B2089FC092019FC292049FE89000BFC08885070238E
+7373:000045FC282013FE2A2249AC882009AC18002BFE482089FC095409545154210C
+7374:011097FC511027FC540493F8100017FC3080514496A8117016A81126A6A04040
+7375:01248A485124200053FC92941264129433FC524893681248136A124AA2464362
+7376:03FC884051F8210851F8910817FE144232A4528A947A108011F81288A070438E
+7377:0040882057FE248855FC948817FE142035FC552495FC152415FC1400A4884904
+7378:77105514771200127F1049FE7F1049107F100028FFA800287F4441447F844102
+7379:0040887C504023FC524493F0124412FC32A852F892A812F8120015FCA5544BFE
+737A:0108890857CE2112512497DE1552155E37D2511E9392155E19401114A1124122
+737B:08100F1408127F1249105EFE49107F104A105F2851285B2855445F4455849502
+737C:00009EFE5254229262FEAE9228D628BA68D6AE9222D622BA22D62292AA9A4484
+737D:004097FC500023B852A893B8111017FC311057FC91101FFE11281310AD484186
+737E:01108FFE511027BC54A497BC1140112033FE522097FC1A2013FC1220A3FE4200
+737F:000097FE504022EE62AAABEA2AAE2AE86BAAACE6228825F422902060A1984606
+7380:000097FC54A424A467FCA21022A824BE6F68A23C24A82FBC20282AA8AABE4020
+7381:07BC94A457BC200057FE94001590149E37D4556495D4155415D41568ABC85054
+7382:024097E2525C2EF06AB0AEF0201E27D46554A7D4255427D421142FE4A1244144
+7383:03DE46522BDE12522BDE48A089FE0B201DFC292049FE880009FC08885070278E
+7384:020001000100FFFE02000420082010403F8011000200042008103FF810080008
+7385:101008100810FE101054105220524290FC104814100420084408FE10422000C0
+7386:101008080808FEFE1010101020204242FCFC4848101020204444FEFE42420000
+7387:020001007FFC020044442F88111022484FE400200100FFFE0100010001000100
+7388:10400840087EFE801100101C20E042A0FCA248A410A820904490FEA842C40082
+7389:00007FFC010001000100010001003FF8010001000120011001100100FFFE0000
+738A:000000007FFC010001200110011001003FF801000100010001000100FFFE0000
+738B:00007FFC010001000100010001003FF8010001000100010001000100FFFE0000
+738C:00400040FF4008400840084008407E4008400840084008420F42F042403E0000
+738D:1000100010003FFC21004100810001003FF801000100010001000100FFFE0000
+738E:00000000FEFE1010101010107C1010101010101010101E10F010401000500020
+738F:00400040FE40104011FC10447C4410441044108410841E84F104410402280410
+7390:00000020FD201120112011207D2011201120111011101E10E208440808041002
+7391:000001F0FD1011101110111011107D1011101110111011121D12E212420E0400
+7392:00000000FDFC1020102010207C2010201020102010201C20E020402003FE0000
+7393:00400040FE8010FC110412047C0411041084104410441E04F004400400280010
+7394:01040124FD241124112411247D2411241124112411241D24E124422402040404
+7395:000001FCFC201020102010207C2013FE1020102010201C20E020402000200020
+7396:00800080FC8010F8110811087D1012101020102010501C50E088410802040402
+7397:000001FCFC201020102010207C2013FE1020102010201C20E020402000A00040
+7398:00000000FDF810081008100810087DF811081100110011001D02E10240FE0000
+7399:00800080FC8010FE1080110011007DFC10041004100413F41C04E00440280010
+739A:000001F8FC101020104010807DFE10921092109211121D22E222444200940108
+739B:000003F8FC0810081108110811087DFE10021002100213FA1C02E00240140008
+739C:00100090FC901088108811247D2412221440104010881C84E10443FE01020000
+739D:00800080FC8011FC112012207C20102013FE102010201C20E020402000200020
+739E:00200020FC20102011FC10207C20102013FE102010501C50E088408801040202
+739F:00400020FC2013FE1088108810887C8810881050105010201C50E08841040602
+73A0:00200020FC501050108811047E0210881088108810881C88E088410801080208
+73A1:000001FEFE081088108810887D0811FE1018102810481E88F108420800280010
+73A2:00100090FC9010881108110412047DFA10881088108810881D08E10842280410
+73A3:00400020FE20100013FE10407C4010601050104810441E44F040404000400040
+73A4:00200020FC2013FE1020102010207DFC10201020102013FE1C20E02040200020
+73A5:000000FCFE841084108410FC7C841084108410FC10841E84F104410402140408
+73A6:00400040FC4013F8104810487C48104817FE104010A01CA0E110411002080406
+73A7:00400040FC801088110413FE7C0210901090109010901C90E1124112020E0400
+73A8:00000000FDFC1020102010207C20102011FC102010201C20E020402003FE0000
+73A9:00000000FDFC10001000100013FE7C9010901090109010901D12E112420E0400
+73AA:00200020FC5010501088114412227C20100011FC100410081C08E01040100020
+73AB:00400040FE40108010FE11087E8810881088105010501E20F050408801040202
+73AC:000001F8FD081108114811287D28110817FE110811081D08E108420802280410
+73AD:00100110FD101112111211147DD811101110111011101D12E1524192010E0000
+73AE:00400040FC4013FE1040104011FC7C40104013FE104210421C4AE04440400040
+73AF:00000000FDFE10101010102010207C6810A41122122210201C20E02040200020
+73B0:000001FCFD0411041124112411247D2411241154105010901C90E1124212040E
+73B1:00200020FE501050108811047E0210F81088108810A81E90F0824082007E0000
+73B2:00200020FC5010501088112412127C1011FC1004100810881C50E02040100010
+73B3:00500054FC5210921090119E11F07E9010901090109010901C8AE08A40860082
+73B4:00480148FD481148114813FE7D4811481148114811781D00E100410001FE0000
+73B5:00880088FE88108813FE10887C881088108810F810881E88F088408800F80088
+73B6:000001FCFC201020112410A47CA8102013FE102010201C20E020402000200020
+73B7:00200020FC201020103E102010207C2011FC1104110411041D04E10441FC0104
+73B8:00800080FDFC1104120415F411147D14111411F4110411281D12E10240FE0000
+73B9:00400020FE2011FE102010207C44108411F8101010201E44F08241FE00820000
+73BA:080008001FFC2104410809201110250802007FFC01003FF801200110FFFE0000
+73BB:00200020F82023FE222222242220FBFC2284228822483A50E220445004880906
+73BC:00900090F8902290229222D4FA9822902290229022903A92E3D24E12040E0000
+73BD:00800080FD0011FC120414047DE411241124112411E41D24E004400400280010
+73BE:000001FCFD241124112411FC7D241124112411FC11241C20E020402000200020
+73BF:000001FCFE441044104410447C941088110010FC10841E84F084408400FC0084
+73C0:00200020FC4011FC1104110411047D0411FC1104110411041D04E10441FC0104
+73C1:00000000FBFC2100210021F02110F9102190225022503A10E21242920312020E
+73C2:00000000FDFE1008100811E811287D281128112811E811281C08E00840280010
+73C3:00200020FC2011FC1124112411FC7D241124112413FE11041D04E10441140108
+73C4:00200020FD20112011FC112012207C20102011FC102010201C20E02043FE0000
+73C5:00200020FC2011FC112411247D2411FC1124112411241DFCE124402000200020
+73C6:00200020FC401088110413FE7C02100011FC110411041D04E104410401FC0104
+73C7:000001F8FD081108110811F87D081108110811F811081D08E108410807FE0000
+73C8:02000200FA00221E27D222522252FA522252225222523A52E452445E09521080
+73C9:000001FCFD041104110411FC11207D2011FE1120112011101D12E14A41860102
+73CA:0000F7BC24A424A424A424A4F4A42FFE24A424A424A434A4E4A445A408541088
+73CB:00000080FB1E2252225222522252FA52225222D2235A3A54E090409001100210
+73CC:00000040F8202028200820882090FA9422A222A224C23888E188428804780000
+73CD:00200020FC501088110412127C2010401188101010201C44E188401000600380
+73CE:00800080FC8010FE110211047E20102010A810A411241D22E222402000A00040
+73CF:00000000FDFC10201020102010207C2011FC1020102810241C24E02043FE0000
+73D0:00200020FC2011FC1020102010207DFE10201020104010481C84E1FE40820000
+73D1:00900088FC88108013FE10A010A07CA410A410A8112811321D22E262429E0400
+73D2:00200020FDFC102413FE10247DFC1020102011FC10201C20E3FE402000200020
+73D3:00400020FC2013FE100010887D0412021088108810501C50E020405000880306
+73D4:00400040F84027FE20802080F97C21082310251021FE3910E110411001500120
+73D5:00400040FDFC1044108410847D281210110813DE114A1D4AE14A4252035A04A4
+73D6:00200020FD2410A410A8102013FE7C9010901090109010921D12E112420E0400
+73D7:00200120FD2011FC112012207C2013FE1090109010901C90E11241120212040E
+73D8:00200040FDF81108114811287D2813FE1108114811281D28E108420802280410
+73D9:00880088FC88108813FE108810887C88108817FE100010881C84E10442020402
+73DA:000001FCFD041124112411247DFC112411241154114C1D8CE104410401FC0104
+73DB:00200020FDFE1040104010FC7C84118412FC108410841CFCE084408400940088
+73DC:01040084FC88100013FE10207C2011FC1020102013FE1C20E020402000200020
+73DD:000003DEF84220422252214AF94A204220C6214A22523842E0424042014A0084
+73DE:00800080F8F82108231024A02040F8A02118220625F821083908E10801F80108
+73DF:000007F8F408240827F824882488F4E82528252826A8244A344AC88A09061202
+73E0:00200120FD2011FC112012207C2013FE107010A810A81D24E124422200200020
+73E1:0000FEFE101010107C7C10101010FEFE0100010001000280044008203018C006
+73E2:000001F8FD08110811F811087D0811F81144114811301D20E110414801860100
+73E3:00800080FDFC1104120411E47D24112411E4112411241DE4E104400400280010
+73E4:00800080FC8011FC112012207C20102017FE102011241D24E124412401FC0004
+73E5:000003FEFD081108110811F87D08110811F8110811081D1EE3E8400800080008
+73E6:00200020FC4011FE110211027D7A114A114A114A114A1D7AE1024102010A0104
+73E7:00900090F8902292219420982090F99822942492209020903912E1120212040E
+73E8:00200020FC5010881104120211FC7C00100011FC110411041D04E10441FC0104
+73E9:00800080F93C220024802080217EFB082508210821083908E108410801280110
+73EA:00200020FDFC10201020102013FE7C001020102011FC10201C20E02043FE0000
+73EB:00400020FC2013FE104010887D0413FE1092109010901C90E1124112020E0400
+73EC:00280024F824202023FE22202224FA24222423A822283A10E212442A04460882
+73ED:00800080F8BE2288228822882288FABE2288248820883908E108423E04000800
+73EE:000007FCF404240425F424442444F5F425542554255425543574C44604460842
+73EF:00400040FC4411F41048105013FE7C4010801184129810E01C82E082407E0000
+73F0:00200124FCA410A410A8102011FC7C041004100411FC10041C04E00441FC0004
+73F1:00400024FA242108210820102040F84023FE208821083990E060405001880604
+73F2:000003FEFA022444204023FC2080F8A0212021FC20203820E3FE402000200020
+73F3:02040104F9082FE8229422A42288FA8A2292212421043908E2904240043E0800
+73F4:001000D8FB942094209023FEF8902094209420D823983890E0AA40CA02860102
+73F5:000001FCFD041104110411FC7C00100013FE102010201DFCE020402003FE0000
+73F6:01080088FC9011FC1024102411FC7D20112011FE106210A21D2AE22444200020
+73F7:00100018FBD42014201027FE2010F890209022D022903A90E28A42EA07060202
+73F8:000003FEF840204021FC20842084FBFE2000200021FC3904E104410401FC0104
+73F9:00280024F824202023FE22202224FA2423A422A822A83A90E29245AA04460882
+73FA:000001FCFC44104413FE10447C4411FC1080108011FC1E84E484408400FC0084
+73FB:00800080FCFE110012FC10847CA4109413FE108411241D14E1FE400400280010
+73FC:000001FCFD04110411FC11047D0411FC1104110411FC1C00E088408401020202
+73FD:00000006FBB8208820882108213EFB88208822882288393EE1004280047E0800
+73FE:000001FCFD04110411FC110411047DFC1104110411FC10501C90E0924112020E
+73FF:000001FCFD041104110411FC7C2010201120113C11201D20E2A04260043E0800
+7400:00200020FC5010881144122210F87C081010102011FC11041D04E10441FC0104
+7401:01000100FDFE1200140011FE7C2210241120113C11201D20E12042A0047E0800
+7402:00200010FDFE1000100010FC10007C0010FC1000100010FC1C84E08440FC0084
+7403:00280024FC24102013FE102011207CB210B4106810A811241E22E02040A00040
+7404:000000FCFC84108410FC10007DFE1102110211FE11021D02E1FE4102010A0104
+7405:00400020FDFC1104110411FC11047D0411FC1120112211141D08E14441820100
+7406:000001FCFD24112411FC112411247DFC1020102011FC10201C20E02043FE0000
+7407:001C01E0FC20102013FE10A87D24122211F8108810901CBEE102410202140408
+7408:0008003CFDC01004114410A810007DF81010102013FE10201C20E02040A00040
+7409:00400020FBFC20402090210823FCF8042150215021503950E25042520452080E
+740A:000007DEF89224922494249427D8F8942192219222923A9AE494489002900110
+740B:01840068F83020C823042040FBFE20A0212023FC25243924E134412800200020
+740C:00200124FD24112411FC10207C5010881144122210201DF8E008401000100020
+740D:004200E2FB82208A208A208A27EAF88A218A21CA22AA3A82E4824082008A0084
+740E:00240224FD24117E102410247C24137E1124112411241D24E144410002FE0400
+740F:00200420FA2022FE204020502E90FAFE2210221023FE3A10E210451008FE0000
+7410:00200124FCA410A8102011FC11047D2411241124112411241C50E08841040202
+7411:00200124FCA410A8102011FC7D04110411FC110411041DFCE104410401140108
+7412:00400040FCFC1088115010207CD8132610F8102010F81C20E3FE402000200020
+7413:00400020FBFE2202240421F82000F80023FE209020903890E1124112020E0400
+7414:00400020FBFE22022404200023FEF82020202120213C3920E2A04260043E0800
+7415:00400080FDFC1124112411FC11247D4411FC1090111013FE1C10E01040100010
+7416:00480044FC5E11E0102810127C6A11961048105E11E01C24E0284012006A0186
+7417:00400020FDFE1000108810887D5412221000102013FE1C20E020402000200020
+7418:001C03E0FA2023FE22202292230AFA0621FC2104210439FCE104410401FC0104
+7419:00140012F81027FE20102010FBD222522252225423D43808E0EA471A02260042
+741A:000003FCFA04220423FC22202220FBFE2220222022FC3A84E284448404FC0884
+741B:000007FCFC0424A4211022082040F84027FC204020E03950E2484C4600400040
+741C:00400040F84027FC204022482248FA48255420E021503950E248444408420040
+741D:01FC0104FD0411FC110411047DFC1040102013FE10881C88E050402000D80706
+741E:7CFC448444FC7C8444FC44847C84011402087FFC01003FF801200110FFFE0000
+741F:00A00090FC9011FE111013107DFE1110111011FE11101D10E11041FE01000100
+7420:00500050FC5011FC1154115411547DFC11541154115413FE1C00E08841040202
+7421:01000100F9DC21142114211427D4F8142114211425883D48E948411405140222
+7422:000003FEF8402080214422242068FAB0213022A8206838A4E122422000A00040
+7423:00400020F9FC2000210820902000FBFE2000200021FC3904E104410401FC0104
+7424:00800080FDF81108121015FC7C24102413FE102410241DFCE024402000A00040
+7425:00400040F87C204023FC22442270FBC02244223C22003AF0E49044920912120E
+7426:00400040FBFC20A02110220827FEF80823C8224822483A48E3C8400800280010
+7427:00007FFC04403C7820083C780440FFFE00007FFC01003FF801200110FFFE0000
+7428:000001FCFD04110411FC110411047DFC1000111211D411181D10E1524192010E
+7429:00FC0084FC8410FC108410847CFC100011FE110211021DFEE102410201FE0102
+742A:01080108FBFC2108210821F82108F90821F8210821083BFEE000409001080204
+742B:00200020FDFC104010F8104013FE7C881124122210F810201DFCE02040200020
+742C:00400020FBFE22022504210021DEFA5222522352249A3894E11041120212040E
+742D:000001F8FC08100811F810087C0813FE1020122211741CA8E124422200A00040
+742E:00400020FBFE2202200021FC2000F80023FE202021283924E222442200A00040
+742F:00200010FDFE1102120410F87C88108810F8108010801CFCE084408400FC0084
+7430:00200122F9222224205020882304F82220202124212422283850E08801040602
+7431:000001FCFD241124117411247DFC11041174115411541D74E104420402140408
+7432:00900090F890239E209020902090FB9C209020902090239E3890E09000900090
+7433:01100110F910211027BC21102110FB3823B8255425543992E110411001100110
+7434:0000FEFE101010107C7C10101010FEFE010006C01A30E10E1FE0004000800100
+7435:0000FEFE101010107C7C10101010FEFE0000208020843E9820E020842684387C
+7436:0000FEFE101010107C7C10101010FEFE00003FF8210821083FF8200220021FFE
+7437:01080088F89023FC2040204021F8F840204027FE20A038A0E12041220222041E
+7438:00200020FC3E102011FC110411FC7D0411FC1124102013FE1C20E02040200020
+7439:0000FEFE101010107C7C10101010FEFE010001007FFC054009203118C1060100
+743A:02100110F910247C221022102010F97E21102210262022243A42E2FE02420000
+743B:00200020FC5010881104120210F87C20102011FC102011241CA4E0A843FE0000
+743C:00400020FBFE2000200021FCF904210421FC202021283924E222442200A00040
+743D:00200022FDFA1024102813FE7C20104010FC118412841CFCE084408400FC0084
+743E:03F80248FA4823F82248224823F8F8A021102208251621103910E11002100410
+743F:000003FEFA22202023FE2020F9FC212421FC212421FC3820E3FE402000200020
+7440:0004001EFBE0202021FC21242124F9FC202023FE22223A2AE2FA4202020A0204
+7441:000001FEFD02117A1102117A11027C0010FC108410FC10841CFCE08440FC0084
+7442:000001FEFD12111211FE11007D7E11421142117E11421D7EE2424242047E0842
+7443:00400040FBFC204021F8208023FCF910220825F621103910E1F04110011001F0
+7444:00400020FBFE2202240421FC2000F9FC210421FC210439FCE104400003FE0000
+7445:000001FCFD04110411FC11047D0411FC100013FE10201D20E13C412002A0047E
+7446:000001FCFD0411FC110411FC10207D2011FE1220102011FC1C20E02043FE0000
+7447:002001FEFC2010FC102011FE7C0010FC10A4109411FE1CA4E11441FE00040018
+7448:000001FCFC48103013FE10527C9411101230102013FE1C70E0A8412406220020
+7449:000001FCFD0411FC111011FE7D10114A1186100011FC1D04E1FC410401FC0104
+744A:0008000CF80A23FE2208220822E8FA0A220A22EC22AC3AA8E2EA421A02260442
+744B:00400040FDFC108413FE10007DFC110411FC102013FE1C20E22043FE00200020
+744C:000003FEFC20104011FC115411547D541154112C102013FE1C50E08841040202
+744D:00800080F8F82108221025FCF9042154218C212420203BFEE050408801040602
+744E:01100112FDD41118115211927D2E104011FC110411041DFCE104410401FC0104
+744F:00400020FBFE22022088210421FCF890211023FE20503890E110461000500020
+7450:01080088F89027FE200023C42254FA5423D4225422543BD4E2544244025402C8
+7451:008000FCFD0411F8100813FE10407CA213341058109413341C52E09043500020
+7452:000000FCFC8410FC108410FC10007DFE108010FE112A124A1C92E12240540088
+7453:00200020FBFE202021FC2124F9AC2174212421FC20203870E0A8412402220020
+7454:00400080FDFC110411FC11047DFC1020103213B410A81D28E124422404A20040
+7455:000003DEFA422242224223DE2200FA3E23D2221222143BD4E208421402240242
+7456:00800338FA28222823A822462200FA7C23A4222422283BA8E610422802440282
+7457:003C07C0FA442128200023FC2080F88027FE210021F83A88E250442008D80306
+7458:00000FDEF4922492249427942498F49427922492249225DA3E94C09000900090
+7459:00920124FA482124209220402080FBFE2202228A22523A22E252428A03FE0202
+745A:0100013CF92427E42124213C2124FBA422A422BC22A43AA4E3A4404400540088
+745B:00880088FBFE208820A8202021FCF9242124212423FE3820E050408801040202
+745C:004000A0F910220825F6200023C4FA54225423D422543A54E3D44244025402C8
+745D:00200040FDFC110411FC11047DFC100013FE102010201DFCE020402003FE0000
+745E:00200222FA22222223FE200027FEF820204023FE22523A52E252425202520206
+745F:0000FEFE101010107C7C10101010FEFE011008A0484449828E121810E7F00000
+7460:004003BEFA122292225222AA2324F84023FE222222223BFEE222422203FE0202
+7461:0100027EFB88228822BE22AA23AAFA2A222A23AA22AA3AAEE288438802880008
+7462:00400020FBFE2202249421082264F8902108220425FA3908E108410801F80108
+7463:00200124FCA8102011FC11047D0411FC110411FC11041D04E1FC400000880104
+7464:00400080FDFC1248113010C013007DFC1220102013FE10201D24E12441FC0004
+7465:000001F8FD08110811F811087D0811F8100013FC12941E94E294429407FE0000
+7466:00400080FDFC1104110411FC7D0011FE110011FE10021EAAE2AA440200140008
+7467:00200020FBFE202021FC204023FEF888213422E2202039FCE07040AC03220020
+7468:000003FCF89022942198209027FEF80021F82108210821F83908E10801F80108
+7469:08202AA44D28145022887FFE400280043FFC010001001FF80100012001107FFE
+746A:000001FEFD2011FC112011FC7D20112011FE100212AA1EAAE2AA420200140008
+746B:001E01E0FC221112109410807C2011CE1102110211CE1D02E102410201FE0102
+746C:204017FE8090490813FCE1502252244E00007FFC01003FF801200110FFFE0000
+746D:00200010FBFE222022FC222423FEFA2422FC222022FC3A84E284448404FC0884
+746E:000003FEF850205023FE22522252FBFE2020202023FE3870E0A8412406220020
+746F:0100009EFBD22252225423D42258FA5423D2221222923A5AE2D4435002100010
+7470:00200040FBFC2224222423FC2224FA4423FC204020A838B4E13C41220222041E
+7471:00200020FBFE202021FC210421FCF90421FC210421FC3904E3FE408801040202
+7472:00400040F8A02190224827FEFA0823F8220823F822003BF8E508450809F80108
+7473:00840044FC4811FE102010FC7C2011FE1040108010FE1D10E210441001FE0000
+7474:1000FE7810487C480048FE8682007CFC0044FE4410287C2810101E28F0444182
+7475:000001FCFCA41088105010207CD81326102011FC11241D24E1FC402203FE0002
+7476:0008003CFBC0200422442128F9FC2220202023FE20203924E124412401FC0004
+7477:000E03F0F8442224210823FE2242F84023FE208020FC3944E128421004680186
+7478:00400020FBFE2202241421E02100F90021FC2110211027FE3800E09001080204
+7479:00880088FBFE208820A820502088F9742222202021FC3820E0A8412402A20040
+747A:00200124FCA813FE120210F87C88108810F8102011FC1D24E124413401280020
+747B:000001FCFD2413FE112411FC7C0011FC110411FC11041DFCE10441FC00880104
+747C:002003FEFC2011FC112411FC11247DFC102213FE100813FE1D08E08840280010
+747D:01240124FA2424242954214AFA9226102A102250225C3A50E25042B0029E0300
+747E:00880088FBFE208820F8202021FCF92421FC202023FE3820E1FC402003FE0000
+747F:00007F7848485F4C64805F7844484A4851307F4C00007FFC01003FF80120FFFE
+7480:00200222FBFE2090208821FE2310FD1021FE2110211039FEE110411001FE0100
+7481:00400080FBFC224422F4231422A4FA4422A423FC20403824E522450A090800F8
+7482:00880088FBFE208820F8208820F8F88823FE208821243AFAE020402003FE0000
+7483:00400020FBFE2000215421242154F9FC202023FE22423A92E2FA420A02020206
+7484:00400020FDFC1088105013FE7C0011FC110411FC11041DFCE09040920112060E
+7485:01240248FD24100011FC11247DFC112411FC102013FE1C70E0A8412406220020
+7486:000007BCF88424A4229424A42050F988262620C023103864E388403000C00700
+7487:02100110F91027BE2240220023BEFA8A228822A822AE3AA8E4A845A8085E1080
+7488:01080108F90827D0211E2794F9242FD4221423D422543A48E24844D404240842
+7489:00100410FAFE221020FE209226FEFA9222FE221022FE3A10E210451008FE0000
+748A:00880088FBFE2088208820F82020FBFE2222233222AA3B76E2224222022A0224
+748B:002001FCFC88105013FE10007DFC110411FC110411FC1C20E3FE402000200020
+748C:00400020FBFE2202200021FC2020F9FC212421FC212439FCE000408801040202
+748D:008803FEF888200021FC20A820A8FBFE20A820A821FC3820E3FE402000200020
+748E:00000FBEF8A22AAA2AAA2AAA2514F8A220802FFE21103A10E3A0406001980E04
+748F:010001F8FA0823F020102FFE2080FC8824EA274A244C3DE8E44A464A04A60110
+7490:00100790FCBC24A424C427A82110F928214625C0253C3D24E52445A40E3C0024
+7491:00800080F9FE23542554215423FEF9542154215427FE20003954E12A022A0000
+7492:002007A4F8A822922114220825F4F80223F8220822083BF8E20841100FFE0000
+7493:008803FEFC88101C11E0102013FE7CA81124122211F810881C9EE082410A0204
+7494:01040088F80023FE222222AA2272FA2223FE200021FC3904E1FC410401FC0104
+7495:000003FCF80423FC200423FC2000FBBC212427BC20083BFEE108408800A80010
+7496:0200017EF840247C224420FCF940267E2220202023FE3870E0A8412402220020
+7497:21F8110841F821080BFE090073FC14A41154128800007FFC01003FF80120FFFE
+7498:00200124F8A823FE20A821242222F904210421DE22442554389EE10402040404
+7499:00200020FBFE2050228A2104FBFE250421FC210421FC3820E124422204A20040
+749A:000003FCF848203023FE20522094FB50202023FE22523A8AE376425202720206
+749B:004003F8F84827FE204823F8F8402554275C244427FC3C44E75C455405540844
+749C:00880088FDFC1088108813FE10207DFC112411FC112411FC1C00E08841040202
+749D:002001FCFD2411FC102013FE7C0011FC110411FC11041DFCE10441FC00880104
+749E:00500252F954205023FE20882050FBFE202021FC20203BFEE050408801040602
+749F:000001FCFD0411FC110411FC7C2013FE100011FC11041DFCE020412402220060
+74A0:003C03E0FD2410A813FE10A87D24120211FC112411241DFCE124412401FC0104
+74A1:00280424FA7E22C82148207E2648FA48227E224822483A7EE240450008FE0000
+74A2:000003FEF85023DE2252225223DEF85023FE222222223BFEE222422203FE0202
+74A3:01240124FAAA23AE212422AA23AEF92427FE211021143914E28A424A02160422
+74A4:00200020FBFE202021FC2124F9FC212421FC202223FE3842E02442A2028A0478
+74A5:02880288F7E82290241E27E42454F8542754255425543748E548405402940122
+74A6:003C03C0F8442224210827FE2442FAA4228A247A208038F8E10842900060079E
+74A7:3E1022FE3E4420287EFEA2103EFC221000007FFC01003FF801200110FFFE0000
+74A8:008000DCFA8423D424482A942324FC402248215027FC38E0E15042480C460040
+74A9:0040007CF84023FE2242227823C4FA3C220023FE22403BA4E25845B4045209B0
+74AA:01FC0104F90421FC200023DE2252FA5223DE202023FE3870E0A8412406220020
+74AB:00200124FCA813FE120210F810887C8810F8100011FC11241DFCE12441FC0104
+74AC:01080208F7C8245027DE246427D4F214211427D4221423C83248C454055408A2
+74AD:000004FEFA92227C2010207C2654FA7C2254227C221022FE3A10E51008FE0000
+74AE:002007FEF80023FE220222FA228AFBFE200021FC210439FCE10441FC000007FE
+74AF:00200050FC881174120211FC7D2411AC112411FC10001CF8E08840F8008800F8
+74B0:000003FCFA94229423FC2000FBFE200023FC220423FC38A2E11443080D440182
+74B1:000007BEF108210827BE21082108F7BE20002080204425123522C9C003040CFC
+74B2:00880448FA5020FC202020502694FA382250229822343A54E290422005FE0800
+74B3:00A000FCFD2013FE10A811247E2211FC110411FC11041DFCE10441FC00880104
+74B4:00880088FBDE208821DC22AA2488F80023FE20222120393CE12042A0047E0800
+74B5:0140024CFA642244234C226422A4FBAC22A422A427FE3800E110410802040404
+74B6:004003F8F84827FE204823F8F84027FE200022A424523BF8E2A842A80FFE0000
+74B7:014807C8F90827D0255E27E4FD5427D42554211427D43A08E3C84254055408A2
+74B8:00400020FBFE220221FC2148FA5021FC230421FC210439FCE10441FC00880104
+74B9:002003FEFC2011FC100013FE10027DFC102013FE100013FE1C04E3BE42A4038C
+74BA:2FEC48244BA4682C4BA46AAC4BA44824FFFE80027FFC01003FF801200110FFFE
+74BB:03DE0042FA52214A2252202023FEF8882088215422223820E7FE402000200020
+74BC:000803E8FA8823EE222823F42282FBE2200021FC21543954E154415407FE0000
+74BD:7FFC21087FFCB55A29283558210835582928355800007FFC01003FF80120FFFE
+74BE:00400020FBFE2088205227AC22AAFAA825AC2000210439FCE10441FC01040204
+74BF:0040007CF84027FE240223FCFA4824A4211023F8260C3BFAE20843F8020803F8
+74C0:000001FCFC2013FE122211AC7C2011AC100013FE10201DFCE15441540154010C
+74C1:008803FEFCA8109011FE13207DFC112011FC112011FE1D00E3FC40880070038E
+74C2:008803FEFC88102011FC102013FE7C40108811FC100011FC1D54E15447FE0000
+74C3:03F80248FA4823F822482248FBF820002FBE2AAA2AAA3FBEEAAA4AAA0FBE08A2
+74C4:002003FEFC2011FC100013FE7E5213FE110411FC11041DFCE10441FC00880104
+74C5:044404E4F8A82AAA2EEE24A42AAAFEEE224220402FFE20E03150C2480C460040
+74C6:0042039CFA1023DE229422942420FBFC220423FC22043BFCE20443FC01080204
+74C7:03FC0040F9F8210821F8210827FEFC4222A4228A247A3880E1F842880070038E
+74C8:00500190FC9E13EA108A11D2128A7CA410501088132610A81C70E0A841240060
+74C9:008801DCFC8813DE108811547E2211FC110411FC11041DFCE10441FC00880104
+74CA:010001F8FA0827FE22622292F9FC210421FC210421FC3880E1F842880070038E
+74CB:00200010F4FE2244222820FE2092F6FE229222BA22AA22BA3286C50008FE0000
+74CC:00400020FDFE100011FC115411FC7C201122108C112210541CC8E14442520060
+74CD:0008073EF590255E2564265E2500F5DE2552255E2552265E3452C45604A0051E
+74CE:01080108F7CE2112212427DE2552F55E27D2211E2392255E3940C11401120122
+74CF:01100090FBDE2010225E2182FBDE201023DE225023DE3A50E3DE4250025202CE
+74D0:0040007CF84023FC224423F0FA4422FC22A822F822A83AF8E20045FC05540BFE
+74D1:000007FEF4442598248827DE2488F5DC26AA248824202520353CC920092017FE
+74D2:01040514F7DE29242FFF210CF3552DA723FC220422243A24E24400B001080604
+74D3:03DE0252FBDE225223DE222222FAFA2222FA22AA22FA3AAAE2FA427202AA0226
+74D4:03DE0252FBDE225223DE225223DEF98C2252204027FE3888E190406000D80304
+74D5:F7FC124817FCFC4686ECF55416EC155456EC244400007FFC01003FF80120FFFE
+74D6:002003FEF80021DC215421DC2088FBFE208823FE208827FE3894E18806A400C2
+74D7:022203FEF89021FE231025FE2110F9FE211021FE210023FE3A8AE37602520276
+74D8:008803FEF88823DE225223DE20A0F89021FE212023FC3D20E1FC412001FE0100
+74D9:004003FCF84021F8200023FCF80421F0204023FC20083BBCE2A8439805240892
+74DA:052807BEF94827BE231825AAF94623FC220423FC22043BFCE20443FC01080204
+74DB:010801ECF10A2FEA29282BC8293EFFE829482BE82A282B683AA8CBF40AB412A2
+74DC:001000F81F2012201220122012201220122012101290225022A8432842048002
+74DD:02200720383C2A442A842A242A142A142A0429042928289028404A304D0E8900
+74DE:0210071038502A7C2A902B102AFE2A102A2829242942288228404A304D0E8900
+74DF:02400740387C2A842B742A542A542A742A482942294228BE28404A304D0E8900
+74E0:1008101CFEE828A844A882A87CA800A8FEA820A440A47CA404A2052829341224
+74E1:1008101C7CE810A810A8FEA844A828A87CA810A410A4FEA410A2112811341224
+74E2:0008FE1C28E8FEA8AAA8AAA8FEA800A87CA800A4FEA410A454A2932851342224
+74E3:409021C82708FD3E058055542548FD7E25482548755C25282508494849A89128
+74E4:1008FE1C00E8EEA8AAA8EEA844A8FEA844A8FEA444A4FEA450A2CB2865344224
+74E5:06FE38202C542AB42A5829B454545D9290307EFC52A47EFC10201424FEFE0202
+74E6:0000FFFE04000400040007E008200A20092009200820102213221C22101E0000
+74E7:0020FC202020202020203DFC2420242054204C20442044205422640243FE0000
+74E8:000001FC7C801080108010F8108810881148112811281D08E108414A018A0106
+74E9:0010FC3820E0202020203C2025FC242054204C20442044205422640243FE0000
+74EA:0004FC0E20F0208020803CFC248424C454A84C90452845445602640243FE0000
+74EB:044008203018DFE604200420082010A020407FFC08000FE0092010A41624181C
+74EC:200011FC0080FE80208020F83C88248825482528252825084508554A898A0106
+74ED:000011FC10801080FE8092F81088108829482928292829084B084D4A898A0106
+74EE:0440082010102208C44608201FF0000000007FFC08000FE0092010A41624181C
+74EF:00007EFC40404440644054784848484854A854986488408840AA7ECA008A0006
+74F0:0010FC502048208820843D0226F8244854484C88448845285612640243FE0000
+74F1:0020FC7021C0204020703DC02440247857C04C4844484448543A640243FE0000
+74F2:0020FC2021FE202021243D24252425FC54204C244424441C5402640243FE0000
+74F3:100011FC10801080FE8010F8108810887D4845284528450845087D4A458A0106
+74F4:100010FC284024404240917808480848FEA802984488288810AA08CA088A0006
+74F5:100011FC208028804480FEF8428800887D4845284528450845087D4A458A0106
+74F6:420024FC00407E402440247824482448FEA824982488248824AA44CA448A8406
+74F7:0100410021FC0A441448E0A02110260C00007FFC08000FE0092010A41624181C
+74F8:0000FDFC2020204020F83C88248824F854884C8844F844885402640243FE0000
+74F9:00007EFC424042407E4000787E48424842A87E98428842887EAA42CA4A8A4406
+74FA:00003EFC204020403C40207820483C4820A82098FE88208824AA42CAFE8A4206
+74FB:420024FC1840244052401078FF48204828A87E98AA882A882AAA2ECA088A0806
+74FC:0000FDFC2124212421FC3D24252425FC54204DFC4420442055FE640243FE0000
+74FD:0100111009207FFE40029FF410101FF000007FFC08000FE0092010A41624181C
+74FE:0C0071FC1080FE80388054F8928800881148FD28252845082908114A298AC506
+74FF:100008FC7F40004022401478FF48004800A83E982288228822AA3ECA228A0006
+7500:02000F7C78200820FFA02A382A28FFA82A582A48FFC80848085A0F6AF04A4006
+7501:220022FC4440EE404440447844484448EFA844984488448844AA44CA448A8406
+7502:1000087C7E20422042207E38422840287F58554855487F48D55A556A554A4306
+7503:0620382008A47EA819202C504A88090400007FFC08000FE0092010A41624181C
+7504:0000FEFC28402840FE40AA78AA48FE4810A81098FE88108810AA1ECAF08A4006
+7505:0000FDFE2100217C21543D7C2554257C55104D7C451046FE5402640243FE0000
+7506:082004407FFC12483CF0082014503EF800007FFC08000FE0092010A41624181C
+7507:08202AA42CA84920145022887FFE400280047FFC08000FE0092010A41624181C
+7508:080010FC7E4042407E4042787E4842487EA80898FF8818882CAA4ACA888A0806
+7509:2200147CFFA0142014207F381528FFA815587F4814483648555A94EA144A1406
+750A:08007F7C4920FFA049207F3808287F2849587F481048FF48215A726A0C4AF306
+750B:200010FCFE4044402840FE7882489248FEA89298BA88AA88AAAABACA828A8606
+750C:0000FEFC80408040BC40A478A448BC4880A8EE98AA88AA88EEAA80CAFE8A0006
+750D:0820FFFE08203FF824483FF800007FFE4002BFF408000FE0092010A41624181C
+750E:100010FCFE4010407C4054787C4854487CA81298FE880888FEAA48CA288A1806
+750F:08047F0808103E6400083E1022643E0814107F6000007FFC08000FE011241C9C
+7510:0800497C2A200820FF202A38492888284258774892485A482F5A226A424A8206
+7511:440024FC2840FE409240D678BA489248FEA800987C8844887CAA44CA7C8A4406
+7512:2000207C7FA0D52055205538FFA8552855585548FFC800486A5A556A954A0006
+7513:00407C2045FC44887C5043FE7C20A5FC24203C2000007FFC08000FE011241C9C
+7514:20003E7C4220FFA0512064B87FA840285F5840485F4840485F5A516A5F4A9106
+7515:0100FFFE104824FE799010FC22907CFC089030FEC0807FFC08000FE011241C9C
+7516:3EF822883EF822883EF822883EF8145022887FFC08000FE0092010A41624181C
+7517:08000F7C08207F2049205E3849287F284A585F4851485B48555A5F6A554A9506
+7518:08100810081008107FFE08100810081008100FF008100810081008100FF00810
+7519:005000480040FFFE004022402240FF40224022203E20221222123E0A22060002
+751A:082008207FFC082008200FE0082008200FE008200820FFFE1220141010001FF8
+751B:4404441E44F04410FE1044FE4410441044107CFE44824482448244827CFE4482
+751C:08881C887088108811FEFC88108810887C8844F84488448844887C8844F80088
+751D:08480F4808487F4849FE4E4878484948477840485E485248527A520291FE2000
+751E:0100111009207FFE40029FF410101FF000001010FFFE10101FF010101FF01010
+751F:01001100110011003FFC21004100810001003FF80100010001000100FFFE0000
+7520:002000207D20452045FC452046207C20442045FC442044207C20442003FE0000
+7521:08100810489048907EFE48908910081008107EFE0810081008100E10F1FE4000
+7522:010000803FFE022001C002203FFE2080248027FC2880308027F8408040809FFE
+7523:010000803FFE041002203FFE2080248027FC2880308027F8408040809FFE0000
+7524:00100010FF50087C105030904A109C7C28104C109A1029FE48808860281E1000
+7525:11FC1124512451FC7D24512491FC10407C4013FE104210821C82E10242140408
+7526:0010FF101050107CFE5092909210FE7C92109210FE1090FE500020005FFE8000
+7527:101050507E7E90907C7C10101EFEE0001FF010101FF010101FF0101010501020
+7528:00003FF82108210821083FF82108210821083FF8210821082108410841288010
+7529:00003FF82108210821083FF82108210821083FF82108210821284112410280FE
+752A:040008003FF82108210821083FF82108210821083FF821082108410841288010
+752B:01200110FFFE010001003FF8210821083FF8210821083FF82108210821282010
+752C:00003FF00020064001803FF8210821083FF8210821083FF82108210821282010
+752D:7FFC01000770190CE10200003FF8210821083FF8210821083FF8410841288110
+752E:08001FF822484488095012203FF8210821083FF8210821083FF8410841288110
+752F:020001007FFE41029494142823E800003FF821083FF821083FF8210821282010
+7530:00003FF8210821082108210821083FF8210821082108210821083FF820080000
+7531:01000100010001003FF821082108210821083FF821082108210821083FF82008
+7532:00003FF82108210821083FF82108210821083FF8210801000100010001000100
+7533:0100010001003FF82108210821083FF82108210821083FF82108010001000100
+7534:01000100010001003FF821082108210821083FF820082008200820083FF82008
+7535:0100010001003FF82108210821083FF82108210821083FF8210A0102010200FE
+7536:0200020004003FF821082108210821083FF821082108210821083FF820080000
+7537:3FF8210821083FF8210821083FF8000001007FFC010401040204040418146008
+7538:0800080010001FF820084008BF88248824883F88248824883F88208800500020
+7539:010001003FF821083FF821083FF80000FFFE080010001FF00010001000A00040
+753A:000000007DFE54105410541054107C1054105410541054107C10441000500020
+753B:0000FFFE000000004FE4492449244FE44924492449244FE4400440047FFC0004
+753C:00003FF8210821083FF8210821083FF800000000FFFE01000100010005000200
+753D:008200927C9254925492549254927C9254925492549254927C92451201020202
+753E:0888111022201110088800003FF82108210821083FF82108210821083FF82008
+753F:002000107C10540055FE548054807C8054805480548054807C80448000FC0000
+7540:00001FF0111011101FF0111011101FF000000000FFFE08200820082010202020
+7541:010001001FF0111011101FF0111011101FF00000FFFE08200820082010202020
+7542:008000807C8054F85508550855107E1054205420545054507C88450802040402
+7543:104010401040FE7C92849284FF0492449224FE24920410041004100410281010
+7544:0408420821101110102000403FF82108210821083FF82108210821083FF82008
+7545:100011F810107C20544054807DFC5454545454947D2454241044108411281010
+7546:100008080808FF88000800087F104910491049207F244924494249FE7F424102
+7547:004000407C8054FC5504560454847C4454445414542454447D84440400280010
+7548:0008001C7DE05500550055FC55447D4455445528552855107D10462802440482
+7549:002000207C20542055FC542054207C2057FE5420545054507C88448801040202
+754A:008800887C88548855FE548854887C8857FE5488548854887C88450801080208
+754B:004000407C40548054FE550856887C8854885450545054207C50448801040202
+754C:00001FF0111011101FF0111011101FF002800C603458C4460440084008401040
+754D:002000207C5054505488550456027C8854885488548854887C88450801080208
+754E:002000287C245424542055FE54207C2054205450545054507C88448801040202
+754F:00001FF0111011101FF0111011101FF00000FFFE111010A010401430180E1000
+7550:0000FFFE00001FF0101010101FF000003FF8210821083FF8210821083FF82008
+7551:100011FC1124112455245924512491FC1124112411242924252445FC41048000
+7552:101008100810FF90001000107F104910491049287F284928494449447F844102
+7553:010001047D88095011202118C50602003FF8210821083FF8210821083FF82008
+7554:002000207D2454A454A8542055FC7C205420542057FE54207C20442000200020
+7555:1FF0111011101FF0111011101FF000003FF8210821083FF8210821083FF82008
+7556:0008001C7DF055505550555055507D5055505548554855687D54467402520400
+7557:02000100FFFE00001FF010101FF000003FF8210821083FF8210821083FF82008
+7558:002000207C2055FC5524552455FC7D245524552457FE55047D04450401140108
+7559:060078FC4044484444445A94610800003FF8210821083FF8210821083FF82008
+755A:0200044008201FF002007FFC082010103FF8D11611101FF0111011101FF01010
+755B:002000207C5054885504561254207C4055885410542054447D88441000600380
+755C:020001007FFC040008201FC003100C083FFC00043FF821083FF821083FF82008
+755D:102008200820FFBC002400447F444988490849107F104928492849447F844102
+755E:01000100FFFE012001207D205538554855487D885510551055287D4845840102
+755F:00003FF821083FF821083FF81210220847E4882214402280010006C01830E00E
+7560:010002001FF010101FF010101FF000003FF8210821083FF8210821083FF82008
+7561:002000107C1055FE5420542454447CF854125422544455887C10442800440182
+7562:00003FF821083FF821083FF8092009207FFC092009203FF801007FFC01000100
+7563:010002800C603018CFE600001FF010101FF000003FF821083FF821083FF82008
+7564:002000207C2055FC5420542057FE7C08540855FE540854887C48440800280010
+7565:00800080F8F8A908AB10ACA0F840A8A0A918AA06ADF8F9088908010801F80108
+7566:002000207DFC54205420542057FE7C005420542055FC54207C20442003FE0000
+7567:00003FF821083FF821083FF808001FF0282007C01830E00E1FF010101FF01010
+7568:010011100920FFFE054009203118C0061FF0111011101FF0111011101FF01010
+7569:004000207C2055FE5440544054A07CA255A45698549054887C8844A400C20080
+756A:00F83F00111009200100FFFE092010103FF8D11611101FF0111011101FF01010
+756B:01003FF80108FFFE01083FF801007FFC00003FF821083FF821083FF80000FFFE
+756C:010002800C603018CFE601003FF81110250802003FF821083FF821083FF82008
+756D:002000207C505488550456FA54207C2057FE5420552855247E22442200A00040
+756E:008000807CFE550056FC548454A47C9457FE5484552455147DFE440400280010
+756F:00400040F888A904ABFEA802F888A944AA42A8F8A988FA508820005001880606
+7570:00003FF821083FF821083FF8082008207FFC08200820FFFE0000082010102008
+7571:00007FFC02803EF8228822883EF802803FF8210821083FF8210821083FF82008
+7572:010002800C6037D8C0063FF809201110250802003FF821083FF821083FF82008
+7573:00003FF821083FF821083FF80000FFFE80021FF010101FF010101FF01010FFFE
+7574:00200020FBFEA820A9FCA840FBFEA848A888A8FEA908F9488A28040800280010
+7575:01003FF80108FFFE01083FF80100FFFE00001FF051145FF451145FF440047FFC
+7576:0100111009207FFE40029FF4101010101FF000003FF821083FF821083FF82008
+7577:000003DEF842A94AA884A94AFA52AC20A800ABDEA852F9528894014802540422
+7578:002000207DFC54505488550457FE7C0855E85528552855E87D28440800280010
+7579:00400020FBFEAA02AD04A900F9DEAA52AA52AB52AC9AF894891001120212040E
+757A:00007FFC00003FF821083FF82108FFFE00003FF821083FF821083FF80000FFFE
+757B:002001247CA8542055FC544057FE7C8855245622542055FC7C20442003FE0000
+757C:000000FC7C8454FC548454FC54007DFE548054FE552A564A7C92452200540088
+757D:0008003C7DE0542057FE542055FC7D2455FC552455FC54207DFC442003FE0000
+757E:1FF0111011101FF0111011101FF00000FEFE92929292FEFE92929292FEFE8282
+757F:1110212045447978111025247D7C05240110FFFE00807C8854527C22545A7D86
+7580:0020542055FEA82055FC542403FE7C2455FC54207CA054BC54A07D60453E0200
+7581:000007BCF884ACA4AA94ACA4F850A988AE26A8C0AB10F8648B88003000C00700
+7582:00003FF821083FF821083FF8183006C018307FFE50129FF410101FF01010FFFE
+7583:002001FC7C88545057FE540055FC7D2455FC552455FC54207DFC442003FE0000
+7584:00200124F8A8ABFEA8A8A924FA22A904A904A9DEAA44FD54889E010402040404
+7585:000003FEF800A9FCA924A9FCF924ABFEA800A9FCA924F9FC892401FC000003FE
+7586:0000FBFE080009FCF92481FC8124FBFE480049FCE92449FC692489FC500023FE
+7587:002003FEF820A9FCA800ABFEF802A9FCA820ABFEA800FBFE880403BE02A4038C
+7588:0080F8BE0080709C5294729C0280FABEAAAAACAAF8BEA8AAA8AAF93E89220200
+7589:1FF011101FF011103FF82AA83EF82AA8FFFE88020FF010101FE00020FFFE0000
+758A:1FF011101FF011103FF82AA83EF82AA8FFFE90121FF010101FF01010FFFE0000
+758B:000000007FFC0104010801001100110011F81100110011002900250043FE8000
+758C:010001007FFC01003FF80108FFFE01083FF80100110011F81100290047FE8000
+758D:00007FFC0104110011F0290047FE80001FF010101FF010101FF00000FFFE0000
+758E:002000207DFE0420082011FC512451245DFC5020507050A85D247222C0200020
+758F:002000107DFE04200848108451FE50025CA850A850A850A85D2A712AC22A0406
+7590:01003FF801007FFE40029FF411101FF011101FF000007FFC010411F02900C7FE
+7591:40004DFC7008445044203DFE40247C2890A010B8FEA010A028E02520451E8200
+7592:008000401FFE1000900050005000100030005000900010002000200040008000
+7593:008000401FFE1000900057F8510811103120513C910411042204220444288810
+7594:008000401FFE1000900057FC5040104030405040904010402040204041408080
+7595:008000401FFE1000900052005208121032605380920012042204220441FC8000
+7596:008000401FFE1000900057FC5084108430845084909410882080208040808080
+7597:008000401FFE1000900057FC5008101030205040904010402040204041408080
+7598:008000401FFE10009000500057FC10403040504090401040204020404FFE8000
+7599:008000401FFE1100910053FC5400180033F850109060108021002202420281FE
+759A:008000401FFE11009100510053F01210341058209020104020A0211046089806
+759B:008000401FFE10009010501057FE101030105210911011102010201040508020
+759C:008000401FFE10009000500057FE104030405050904810442040204040408040
+759D:008000401FFE100090405040504014443444544494441444244427FC40048000
+759E:008000401FFE1000900053F85000100037FE5080910013F82008200840508020
+759F:008000401FFE1000900053FC5200120032005FFE92001200220023FC40008000
+75A0:008000401FFE1000900057FC5100110031F85108910812082208240848509020
+75A1:008000401FFE100093F0502050C0110033FC5124912412242244244448A88110
+75A2:008000401FFE100090405040524412443248545090A010A02110220844048802
+75A3:008000401FFE100090905088508017FE30A0512091201120222222224422881E
+75A4:008000401FFE1000900053F8524812483248524893F812002202220241FE8000
+75A5:008000401FFE1040904050A0511012083D165110911011102110221042108410
+75A6:008000401FFE10009040504053F810483048504897FE10A020A0211042088C06
+75A7:008000401FFE1000903C57C054401440344057FE942014202412250A46068402
+75A8:008000401FFE1000900057FC50101210341057FE90501090211022104C508020
+75A9:008000401FFE1080908057F0511011123212544E904017FE2040204040408040
+75AA:008000401FFE1020922052205222122433A852309220122222A22322421E8000
+75AB:008000401FFE100093F052105210140E380057F89208111020A0204041B08E0E
+75AC:008000401FFE100093FE52005220122032FC5224922412442244248444A88910
+75AD:008000401FFE10009110511051101110311052A8926812282444244448849102
+75AE:008000401FFE104090A05110520814063BF052109210125022202204420481FC
+75AF:008000401FFE1000900053F85208132832A85248924812A8252A240A48069002
+75B0:008000401FFE10809040500057FC10403040504093F81040204020404FFE8000
+75B1:008000401FFE1200920053FC54041BE43224522493E4121422082202420281FE
+75B2:008000401FFE1040904057FC5444144037F85508951014A0244028A049189606
+75B3:008000401FFE1000920852085FFE12083208520893F812082208220843F88208
+75B4:008000401FFE1000900057FE5008100833C85248924813C82248200840288010
+75B5:008000401FFE1000911051105512151435D8551095101510251225D25E12880E
+75B6:008000401FFE100090485248524812483FFE5248924812782200220043FE8000
+75B7:008000401FFE1000903C57C054401440344057FE942014202412250A46468422
+75B8:010000803FFE20002000A7F86408240827F86408A40827F8200040005FFE8000
+75B9:008000401FFE104090A051105208142630C05310902010C02308201040E08700
+75BA:008000401FFE1000907857805040102037FC5008903010C023002480487E9000
+75BB:008000401FFE1000900053FC520412043204520493FC12042090210842048402
+75BC:008000401FFE1100910053F85610192030C053309C0E10C02020230040C08020
+75BD:008000401FFE1000900053F85208120833F85208920813F8220822084FFE8000
+75BE:008000401FFE1200920053FC5240144030405FFE904010A020A0211042088C06
+75BF:010000803FFE21203FFCA12461242FFC29206920AFFE21222222422A44248820
+75C0:008000401FFE1200920053FC5404180433E45224922413E42224200440288010
+75C1:008000401FFE10809080508050FC1080308057F8940814082408240847F88408
+75C2:010000803FFE24002400A4006FBC24A424A464A4A4A424A428A448BC52A4A100
+75C3:008000401FFE108090405FFE50801108321057E0904010802110220847FC8204
+75C4:008000401FFE1200920053FE5500190031F85100910011FC2100210041008100
+75C5:008000401FFE1000900057FC5040104037FC544494A415142614240444148408
+75C6:008000401FFE100093FC5204520413FC3200524092441248227024424442883E
+75C7:008000401FFE100090005FFC504010403240527C92401240224022405FFE8000
+75C8:008000401FFE1000900057FC5444144437FC5444944417FC2444284448549008
+75C9:008000401FFE100097F85010502010D833045C0293F81040204020404FFE8000
+75CA:008000401FFE104090A0511052081DF63040504093F81040204020404FFE8000
+75CB:008000401FFE10009040504057FC14443444544497FC10402048207C4F828402
+75CC:008000401FFE1000900057FC540415F4340455F49514151425F4240444148408
+75CD:008000401FFE10409FFE50405FFC104437FC544097FE104220AA211442088C06
+75CE:008000401FFE108090405FFE5080110833F05020904411882610206841848602
+75CF:008000401FFE1040904057FE5080110033FC550499FC110421FC210441148108
+75D0:008000401FFE1000900057FC5404140435F45514951415F42404240447FC8404
+75D1:008000401FFE108091F852105D2010C031A0567C908411082690206040C08700
+75D2:008000401FFE111090A057FC5040104033F85040904017FC2040204040408040
+75D3:008000401FFE100097FC50805110120837FC5044904017FC204020404FFE8000
+75D4:008000401FFE1040904057FC504010403FFE501090101FFE2210211041508020
+75D5:008000401FFE100097F8540857F8140837F85484948814502420251846068400
+75D6:008000401FFE1000900053FC5090109034925292929410982090209047FE8000
+75D7:008000401FFE1200920053FE54001BF8328852489FFE1488244827FC40088030
+75D8:008000401FFE1000900057FC500013F83208520893F81000211020A04FFE8000
+75D9:008000401FFE100097FC5000524814903248500097FC1040204020404FFE8000
+75DA:010000803FFE20802088A7F060A03FFE20806FF0A620384027FC404041408080
+75DB:010000801FFE100097F850A0504017FC344457FC944417FC2444244444548448
+75DC:008000401FFE1000903853C0504017FC31505248944611F02110211042128C0E
+75DD:010000803FFE22102208BFFE6248225022646248A2522264244A447248C2933E
+75DE:008000401FFE100097FC5020504011D036485044900013F822082208420883F8
+75DF:008000401FFE104092485150504013F8320853F8920813F82208220842288210
+75E0:008000401FFE10809108520457FE110A3284548291F813082490206041988E06
+75E1:008000401FFE105090485FFE504017FC344457FC944417FC2444244444548448
+75E2:008000401FFE100090C45704511411143FD45314939415542504290441148108
+75E3:008000401FFE10009040504057FC1040304053FC900010402124252A450A88F8
+75E4:008000401FFE1040904052485248155438E25040904017FC2040204040408FFE
+75E5:008000401FFE10009210512057F814083408540897F81120212022224422981E
+75E6:008000401FFE100097FC508053F8108831085FFE900013F82208220843F88208
+75E7:008000401FFE10109210511051541452329252109114160422082210422080C0
+75E8:008000401FFE1108910857FE5108100037FE5402904017FC2084210442288C10
+75E9:008000401FFE104097FC544457FC144437FC504097F81208211020E043188C06
+75EA:008000401FFE110091F0521054201BF83248524892481FFE20A0211042088C06
+75EB:008000401FFE10009200517C5404144435F4544494E415542644244444548408
+75EC:008000401FFE100093F8520853F8120833F8510093FC14942924224444A88110
+75ED:008000401FFE100097BC54A454A417BC34A454A497BC14A424A424A44AA4914C
+75EE:008000401FFE100093FC520053F8120033F852009FFE14882450252046188406
+75EF:008000401FFE1080904057FC540413F03210521093F0120023F82208420883F8
+75F0:008000401FFE10409248525054A0111032085C449248125024A0211042088C06
+75F1:008000401FFE100090905090579E10903090539C90901090279E209040908090
+75F2:008000401FFE1110911051105FFE111035545554955415542554295641108110
+75F3:010000803FFE22102210A2107FBE221026106738AAB42A543292421042108210
+75F4:008000401FFE1200920053BC5524192431245FE49124112422A422BC44248800
+75F5:00801FFE1000103893C0504017FC315052489C4611F010202FFE204041408080
+75F6:008000401FFE10A090A057FC54A414A437FC54A494A41FFE2000211042088404
+75F7:010000803FFE20002080AFFC6120221024886FF6B49027F0249047F24082807E
+75F8:010000803FFE21002504A7C469143FF4211467D4A5542554255445C441148108
+75F9:008000401FFE100093F8524853F8124833F850009FFE11102110211042108410
+75FA:008000401FFE1080910057FC544417FC348457FC914012403FFE204040408040
+75FB:00803FFE20002038AFC068402FFC28206B1AAC0627F8240827F8440847F88408
+75FC:008000401FFE100097FC5444544417FC344455F49514151425F4240447FC8404
+75FD:008000401FFE1120911053FE522016203BFC5220922013FC2220222043FE8200
+75FE:008000401FFE1000977E55045574165435545554955415742754240444148408
+75FF:008000401FFE103897C050405FFE115032485C4690801FFE2108231040E08F1C
+7600:010000803FFE20002410A2106FA8242824446792A488248828A048905288A108
+7601:008000401FFE1000904057FC5110111032A8544490401FFE2040204040408040
+7602:008000401FFE10009FFC5120512017383408540897381120212021205FFE8000
+7603:010000803FFE20002FFCA100630824882D506260A5E029502250444859448080
+7604:010000803FFE22102FFCA21062103FFE200067F8A408240827F84408440887F8
+7605:008000401FFE1208911057FC544417FC344457FC944410402FFE204040408040
+7606:008000401FFE1090910853FC504017FE311052689D86103021C0201840608380
+7607:00803FFE200827F0A0406FFE204027FC6444A7FC244427FC204047FC40408FFE
+7608:008000401FFE110097BC51145794111437A4514C90401FFE20A0211042088C06
+7609:008000401FFE104090A053185DF61000378454A497A414A427A4248444948588
+760A:010000803FFE200022F8A20864082DFE348064F8A520242025FE445044888506
+760B:010000803FFE20002FF8A80868682B8828886BE8AAA82BE8288A50EA5726A002
+760C:008000401FFE1100910457C4511417D4355457D4911413942554294441148108
+760D:008000401FFE100093F8520853F8120833F850009FFE120027FC292442548488
+760E:008000401FFE111097FC511051F0111031F0511097FE120022902308420083FC
+760F:008000401FFE1040904453F45048105037FE508091F8130825F8290841F88108
+7610:010000803FFE20002280ACB8688828882EB86888A8882FF8214042204C18B006
+7611:010000803FFE200023F0A21063D0225022506FFCA80429E4292449E448148808
+7612:008000401FFE100097FE54425BFC104033F8524893F8124823F820404FFE8040
+7613:010000803FFE220023F0A4206FFC34A425146444A0402FFE20A0411042088C06
+7614:008000401FFE111091105FFE511010403FFE5040904017FC2404240447FC8404
+7615:008000401FFE100097BC5484548417BC3400547C97A414242428279044288446
+7616:008000401FFE1080904057FC521011203FFE500093F8120823F8220843F88208
+7617:010000803FFE20802FF8A49062A03FFE21406220AC9830862FF8408040809FFC
+7618:008000401FFE124891505FFE51501248344450809FFE11082390206041988604
+7619:008000401FFE100097FC5248511010E033185C4693F8124823F8204447FC8004
+761A:010000803FFE28902510AFBE622222442A906A90AF9022102228442844448882
+761B:008000401FFE110097BC51145394111437A4514C9100104020242522450A88F8
+761C:010000803FFE210027F8A40867F8240827F86408A7F8208020444A424A1291F0
+761D:008000401FFE100097FC54A454A417FC30405150924814442150224844448040
+761E:010000803FFE204027FCA2486248255428A26318AC4623F8204040404FFE8000
+761F:010000803FFE200027F8A40867F8240827F86000AFFC2924292449247FFE8000
+7620:008000401FFE1444924854A45110120837FC5A0A93F8120823F8220842288210
+7621:008000401FFE104091B05E4E53F8120833F8520893F8120025FC250449FC8104
+7622:010000803FFE24002F78A9486D482B863F006978A9482D482B28491049289346
+7623:010000803FFE20802100AFFC68842FFC28846FFCA1482154225C44464842B03E
+7624:008000401FFE1080977C542455A415543648508097FC144427FC244447FC8404
+7625:008000401FFE111090A057FC504013F8308057FC910013F82440284047FE8000
+7626:008000401FFE1140965C5444575C144437FC504097FC1208211020E043188C06
+7627:00803FFE208020FCA0806FFE288228F06F84A87C280029FC29004BFE490091FC
+7628:00801FFE104017FC904053F8120833F8520893F8120813F822082FFE41108208
+7629:008000401FFE1110911057FC515010A0311052E89C0613F82208220843F88208
+762A:00803FFE210027F8A40867F8240827F86408A7F8212026183A664388420881F8
+762B:010000803FFE20502048BEFE72902A902BFE6490A4902AFE2A90529040FE8080
+762C:008000401FFE1000973C5120513C1720343C5420977E1128212A212445248232
+762D:00803FFE20003FFEA1206FFC29242FFC6000A7F820002FFC2248444449428080
+762E:008000401FFE111093F8521054A417FC30A053189C4613902064239840608380
+762F:008000401FFE142092205F7E544014A0373C5550951015FE251029284B449082
+7630:00803FFE200027FCA44467FC244427FC6100A20827F020C42FFE444849449082
+7631:010000803FFE20402FFEA2486248255428A26318AC0620802A444A4A520A81F8
+7632:010000803FFE22002448A848705422A425006C10B490249C24904550463E8400
+7633:00803FFE20002F7CA924651429A421606618B88623202C4021884E3041C08E00
+7634:00803FFE204027FCA1106FFE200023F86208A3F8220823F820404FFE40408040
+7635:010000803FFE222023BCA4A46AA82510220865F6A80027FC2250444849448080
+7636:010000803FFE22202220AFA0623E2FC22A946A90AF90221027284AA852448282
+7637:010000803FFE22102210AF90623E2FA42AD46A94AF94220827084A9452248242
+7638:008000401FFE120097BC52A454A415BC384057FC94A41554244424A44514840C
+7639:010000803FFE22102520A8BC7744220422246F94A2142A84270443C45C288010
+763A:010000803FFE20002FFCA8046FFC28002FFE6820ABFE2B322AAA4B324AAA9206
+763B:010000803FFE20802FF8A8887FFE28882FF86490A7F021003FFE441043E09C1C
+763C:008000401FFE111097FC511053F8120833F8520893F810402FFE20A043188C06
+763D:00803FFE22083FFEA20863F8204027FC6444A7FC20402FFE204047FC40409FFE
+763E:00803FFE20402E78AA886B102CFC2A046AFCAA042BFC2E2028144952494A8A38
+763F:00803FFE20002FBEA8A26AAA2AAA2AAA6514A8A23FFE2208271040E0431C9C02
+7640:010000803FFE22202FF8A2207FFC20802FF86888AFF828882FF8422044108808
+7641:008000401FFE108094FC550058FC128432FC54849CFC144024FC2548443085CE
+7642:008000401FFE104097FC50A0551413F8360C5BFA920813F82040244449428080
+7643:00803FFE20202F3CA9446AA82C102A286946A9382D502A7E2890487C481088FE
+7644:008000401FFE1120911053FE56201BFC322053FC922013FE2200252444928892
+7645:008000401FFE100097FE50A057BC14A437BC50A097FC144427FC244447FC8404
+7646:010000803FFE21102554A5B8691022A824446FFEA88230842FF8410842288C10
+7647:00803FFE20002F3CA9246F3C29242F3C6804A9E4292429E4292449E449248A6C
+7648:010000803FFE20402F50A1246A1824083B766150AF8C28782F48413045488284
+7649:00803FFE20002FBEA8A26FBE200027FC6444A7FC244427FC20407FFE40408040
+764A:010000803FFE20102F28A9446A922C7C2A086910A97E2D002AFE4820484488FE
+764B:008000401FFE100097FC50A053B8120833B850A09FFE10402124252A450A88F8
+764C:008000401FFE100093F8520853F8100037BC54A497BC10402444244447FC8004
+764D:010000803FFE20802E4EA44465F4242425246EAEA444244424A446A4590E8200
+764E:008000401FFE100097BC54A457BC14A437BC540495F4151425F4251445F4840C
+764F:00801FFE100017FC94A457FC10003FFE500093F8120813F8214423284D10818C
+7650:00801FFE10A013189DF6500017FC355454E497FC100013F8220823F8420883F8
+7651:00803FFE212027F8A52867F825282FFE6800ABFC28002FFE2A444A285298A306
+7652:00803FFE204021A0A6187BF6200027A864A8A7A824A8278824A845904A5491F2
+7653:010000803FFE25102950B55067DE28243B946814AB942A942A884AC84A948C22
+7654:008000401FFE104097FC51105FFE100033F8520893F8120823F82544452A88FA
+7655:008000401FFE1040902057FE5228127E34C8577E924814C8277E2248447E8840
+7656:010000803FFE20102788A4BE648027A22494643EAF882C8834BE478844888008
+7657:00803FFE200027FCA0406FFE284223586040A358200027FC244447FC444487FC
+7658:00801FFE11101FFE911053F8124833F8524893F8104017FC245425F44414840C
+7659:010000803FFE21002E78A8086F7828082FF86888ACC82AA82CCA4AAA4CC68882
+765A:00803FFE220023F8A4106FFE352426FA6400A5FC240025FC240049FC490491FC
+765B:00803FFE20402FFEA00067FC240425F46514A7FC200823F020404FFE41508E4E
+765C:010000803FFE20002FDCA8546FD42AA22A806FDCAA942FD4280852885454A862
+765D:00803FFE20402FFEA00067FC240425F46514A7FC200027FC20004FFE424884C4
+765E:00803FFE22102F9CA22462482FBE2AA26AAAAFAA222A272A2AAA529442228242
+765F:00803FFE210027F8A6486528249827F86210A5E8380627F8254847F845488558
+7660:010000803FFE20402FFEA0A06F5E255425546B5AA20823F8220843F844088808
+7661:010000803FFE2480273CA48463942408277E6A0AA2282FAE22284558484E9080
+7662:00801FFE1208111097FC504013F830805FFE921017F81A1623F0226443188204
+7663:010000803FFE24002744A928727E2F902A906FBCAA902F90207E43905C108010
+7664:008000401FFE121093DE5528588417BC34A457A494A417A42434252846A08420
+7665:010000803FFE25102950B55067DE28243B946814AFD429142B8849084FD48822
+7666:00803FFE200027FCA55464E427FC204067FCA0402FFE24A4285247FC40408FFE
+7667:00803FFE20002FFCA8886B3029102FBC6BB8AD542912284029784940494097FC
+7668:00803FFE200027FCA0406FFE284223586220A7FE2C2037FC242047FC442087FE
+7669:010000803FFE2210221EBFA262442FBE2AA26ABEAFA2223E27224ABE52948222
+766A:00803FFE2010237CAE10627C2F1022FE6644A77C2AC42A7C3244427C42288244
+766B:00803FFE24003FBEA4086F10293E2F22692AAF2A292A2F2A292A7F94491290A2
+766C:010000803FFE24002722A914723E2F882A886F9CAA882F88203E554855488008
+766D:00803FFE20002FBEA8A26FBE28A22FBE68A2AFBE251428A22FFE431040E08F1C
+766E:00803FFE20042EF8AA546AFE2C102AFE6A04AAFC2A042EFC282049544A4A8838
+766F:00801FFE14A417BC94A457BC14A437BC512093FE122017FC2A2023FC422083FE
+7670:00803FFE20002AA8B5246ABE2F6829686FBEA0282FA82ABE2FA8482848BE87A0
+7671:00803FFE25182F94A53E672822682FBE6AA8AFA8223E2FA822285FBE452088A0
+7672:00803FFE22003FBEA2086F9028BE2FA268BEAFA228BE2FA228BE5FC0491490A2
+7673:00803FFE244427FCA4446FFE2AAA2FBE6AAAAFBE220827F020C44FFE424884C4
+7674:00803FFE24442AEAAE0E64E42AAA2EEE6000A7FC204027FC20404FFE404080C0
+7675:00803FFE244428E8AE0E64E42A0A2EEE60A0AAEA20402FFE28A24912484288A6
+7676:00887C9004A004C0448224442448085008201020101020084004800200000000
+7677:00907EA002444448283010102008DFF6010001000100FFFE0100010001000100
+7678:00907EA002444448283010102008CFE6010001007FFC010002C0042018106008
+7679:00907EA002444448283010102FE8C8260820101C2FE000200C4003800C707008
+767A:00907EA002444448283010102008DFF6044004407FFC0440084008441044603C
+767B:00803E9002A424481450082017D02008DFF6101010101FF0082004407FFC0000
+767C:00907EA00444282810103CF8C49604903D0C200041F87C0804D0042028501188
+767D:0100020004003FF820082008200820083FF8200820082008200820083FF82008
+767E:0000FFFE0100020004003FF82008200820083FF820082008200820083FF82008
+767F:0820082010203F2021202120212021203F2021202120212221223F22211E0000
+7680:020004003FF8200820083FF8200820083FF80000203823C03C04200420041FFC
+7681:020004001FF0101010101FF0101010101FF001000100FFFE0100010001000100
+7682:010002001FF0101010101FF0101010101FF00200020003FCFE000204020401FC
+7683:040008003FF8200820083FF8200820083FF8044004400440084408441044603C
+7684:1040104020407E7C42844284430442447E2442244204420442047E0442280010
+7685:1000100021FC7D2445244524452445247DFC45004500450045027D0244FE0000
+7686:208020883CB020C020842C84317C02001FF0101010101FF0101010101FF01010
+7687:020004001FF010101FF010101FF000007FFC010001003FF801000100FFFE0000
+7688:1004100E20F07C80448044FC44A444A47CA444A844A8449045107D2846440082
+7689:1090109020907A904A924AD44A984A907A904A904A904A924AD27F124A0E0000
+768A:1020102020507C5044884524461244107DFC44044408448844507C2044100010
+768B:020004001FF010101FF010101FF002007FFC044009203118CFE6010001000100
+768C:1020102020207DFE44204420442045FC7C7044A844A8452445247E2244200020
+768D:020004001FF010101FF010101FF0200020F83E882088208826A8389000800080
+768E:1040102020207BFE4800488849044A0278884888485048204850788849040602
+768F:1084104820007CFC44484448444844487DFE44484448444844487C8844880108
+7690:020004001FF010101FF010101FF021081110092011102108FFFE010001000100
+7691:1020112421247D2445FC440045FC44047C0445FC4500450045027D0244FE0000
+7692:101010D82394789448904BFE48904894789448D84B98489048AA78CA4A860102
+7693:1020112021207DFC45204620442047FE7C00440045FC450445047D0445FC0104
+7694:100011FC21047DFC450445FC440044007DFC4420442047FE44207C2044200020
+7695:00000000FEFE1020102020407EFC4284428442847EFC4284428442847EFC4284
+7696:1040102023FE7A024C0449F8480048007BFE489048904890491279124A0E0400
+7697:100011FC212479244974492449FC4904797449544954497449047A044A140408
+7698:1020102023FE7C2045FC442047FE44007DFC450445FC450445FC7D0445140108
+7699:080C08F07E8018802CFE2A8848888888090804001FF010101FF010101FF01010
+769A:102011242124792449FC48004BFE480079FC4904490449FC488878504BFE0000
+769B:020004001FF010101FF010101FF0081010207EFC428442847EFC428442847EFC
+769C:1020101021FE7C0044FC448444FC44007DFE4502457A454A457A7D02450A0104
+769D:102020207D2444A47CA844207DFE0050FE50105010507C5210521E92F08E4100
+769E:1020104021FC790449FC490449FC48407BFE488849244A224DFC782048200020
+769F:102013FE20207DFC442047FE440045FC7D0445FC450445FC45047DFC44880104
+76A0:1020122223FE7890488849FE4B104D1079FE4910491049FE4910791049FE0100
+76A1:1020104021FC7D0445FC450445FC44207D2444A84524442047FE7C2044200020
+76A2:1020102021FC78204BFE49084B9C490879884E3E48004BFE489078904912020E
+76A3:108813FE2088780049FC48A848A84BFE78A848A849FC48204BFE782048200020
+76A4:103C13E0212478A84BFE48A849244A0279FC4924492449FC4924792449FC0104
+76A5:104011FC210479FC490449FC490449FC7820492448A8492448207BFE48200020
+76A6:1088110823C87A504BDE4A644BD4491478944FF4491449C849487A544B5404A2
+76A7:103C13C020447A2449084FFE4C424AA47A8A4C7A488048F849087A904860079E
+76A8:02001FF010101FF010101FF020407EFC42847EFC42847EFC01003FF80100FFFE
+76A9:100021FC7D0445FC7D0445FC7C200124FCA8102013FE7C9010901D12E212440E
+76AA:1124117422587ADA4BFE49544ADA4BFE78A248204BFE487048A879244A220020
+76AB:1040102023FE7A504BFE4A524BFE4A007A944AD84A904AD24A8E7C004954022A
+76AC:11FC102023FE7A224DAC482049AC489079FE4B204DFC492049FC792049FE0100
+76AD:101E13E0212278944BFE4A524BFE48047BC44A7E4BC44A544BCC7A844AD40348
+76AE:0080008000803FFC2084208820802FF02410241022202140208041404630980E
+76AF:0800087C08107F1049104A1048107EFE4210421052104C1044104A1092102010
+76B0:08200820087E7F4249824A7A484A7E4A427A4242524A4C4444424A42923E2000
+76B1:201020103E1042FE84920894FE9002FC02A47EA402A802A80290FF2802440082
+76B2:0010FF10911010FEFE922094289048FC7EA408A408A80EA8F890492809440A82
+76B3:10101410121010FEFE921094109092FC54A410A438A854A89290112851442282
+76B4:10101010201044FEFE9228944490A2FC3CA444A444A8A8A81090292845448282
+76B5:241024107E1024FE2492FF9400907EFC42A442A47EA842A842907F2842440082
+76B6:10101010FE1038FE5492929410907CFC44A47CA444A87CA800901D28E1444282
+76B7:08100810FF1008FE08927E9400907EFC42A442A47EA842A824900F28F1444282
+76B8:0010FE10921010FEFE9210947C9054FC7CA454A47CA810A8FE90112811441282
+76B9:080008FE08927F1049FE4A10487C7E54427C4254527C4C1044FE4A1092102010
+76BA:40104010FE1022FEAA92FA94429094FC48A4FEA422A8AAA8FA90432894440882
+76BB:10101E1010107EFE52925C9472904EFC40A45CA454A85CA854905D2896443882
+76BC:1010FE1010107CFE0092FE9482907CFC00A47CA444A87CA8449029280F44F282
+76BD:1010FE100010FEFE8292BA94AA90FEFC00A47CA444A87CA844907D280044FE82
+76BE:1010FE1010107CFE0092FE94AA90FEFC44A47CA444A87CA844907D2828444482
+76BF:000000003FF82448244824482448244824482448244824482448FFFE00000000
+76C0:0100010001800140012001100108010001003FF82448244824482448FFFE0000
+76C1:00003FF008100820083C10041004201440083FF82448244824482448FFFE0000
+76C2:00003FF801000100FFFE010001000500020000003FF8244824482448FFFE0000
+76C3:00007FFC010003000570090C3102C10000003FF82448244824482448FFFE0000
+76C4:00007FF801083FF821003FFC01040114010800003FF8244824482448FFFE0000
+76C5:010001003FF82108210821083FF82108010001003FF8244824482448FFFE0000
+76C6:0440082010102FE8C4260420082010A0604000003FF8244824482448FFFE0000
+76C7:010001007FFC028004400A203118C00600003FF82448244824482448FFFE0000
+76C8:00003FF008100FA008BC128411042294444800003FF8244824482448FFFE0000
+76C9:00701F8001000100FFFE054009203118C0063FF82448244824482448FFFE0000
+76CA:101008200000FFFE000008201010200840043FF82448244824482448FFFE0000
+76CB:024002207FFC04000BF0112020C043301C0E00003FF8244824482448FFFE0000
+76CC:100010F83E884288A2A8149008841084207CC0003FF8244824482448FFFE0000
+76CD:010001003FF801000100FFFE040008201FF000103FF8244824482448FFFE0000
+76CE:010001001FF011101110FFFE02800C603018C0063FF8244824482448FFFE0000
+76CF:0240022003F87E0003FCFE10016003821C62E01E00003FF8244824482448FFFE
+76D0:082008207F20082808240F22F020402000003FF82448244824482448FFFE0000
+76D1:04402440247C2440249024882508040000003FF82448244824482448FFFE0000
+76D2:010002800C603018CFE600001FF010101FF000003FF8244824482448FFFE0000
+76D3:100009FC402020200BFE10207020102010A000403FF8244824482448FFFE0000
+76D4:040004007FFC08401248125024A0411082080C0600003FF8244824482448FFFE
+76D5:100009F0411025900550095071121112120E14003FF8244824482448FFFE0000
+76D6:082004407FFC010001003FF801000100FFFE000000003FF8244824482448FFFE
+76D7:4080208009FC12042448E04020A023182C0600003FF8244824482448FFFE0000
+76D8:020004001FF011101090FFFE10101210215040203FF8244824482448FFFE0000
+76D9:012001107FFC01003FF821083FF821083FF8210800003FF824482448FFFE0000
+76DA:011001087FFC0100211811A007401920E118450602003FF824482448FFFE0000
+76DB:009000883FFC208020883E48225022244A54448C81043FF824482448FFFE0000
+76DC:0080208011FC820454482040E0A023182C0600003FF8244824482448FFFE0000
+76DD:3FF000101FF00010FFFE111009A005401930E50E02003FF824482448FFFE0000
+76DE:021002FC7F4000840764781C021002FC7F4000840764781C00003FF82448FFFE
+76DF:00007CFC448444FC7C8444FC44847C84011402083FF8244824482448FFFE0000
+76E0:08000FE010201FC000407FFC0600192006C039B0068C398000003FF82448FFFE
+76E1:01003FF80108FFFE01083FF801007FFC248842443FF8244824482448FFFE0000
+76E2:00207C28542455FE7C20545054507C88010402023FF8244824482448FFFE0000
+76E3:00003F2024203F3E21403F5024883F0800003FF82448244824482448FFFE0000
+76E4:10783E4822482A86FF7822482A2842104A2884463FF8244824482448FFFE0000
+76E5:1100611C4D444544759C49844944755C420400003FF8244824482448FFFE0000
+76E6:010006C01930E7CE0080FFFE04403FF8284837B820083FF800003FF82448FFFE
+76E7:010001F801003FFC21042FE0210827F8249027F0249027F020004FF84948BFFE
+76E8:0BFE104061FC090411FC610405FC090431FCC08801043FF824482448FFFE0000
+76E9:08207F20083EFF4422A47F280828FF10082808463FF8244824482448FFFE0000
+76EA:23F8120893F8420843F810002FFEE20027FC2924225404883FF824482448FFFE
+76EB:010006C01830EFEE00001FF010107FFC04401FF014501BB010103FF82448FFFE
+76EC:00407E7C48907E1042FE7E10487C48447E7C00003FF8244824482448FFFE0000
+76ED:102022207C3E0A447FA408247F2814287F1008287F4408823FF824482448FFFE
+76EE:00003FF82008200820083FF82008200820083FF820082008200820083FF82008
+76EF:000000007BFE4820482078204820482078204820482048207820482000A00040
+76F0:000001FC7C20442044207C20442047FE7C204420442044207C20442000200020
+76F1:000001FC7C20442044207C20442047FE7C204420442044207C20442000A00040
+76F2:02000100FFFE1000100010001FF800001FF010101FF010101FF010101FF01010
+76F3:002000107C10440045FE7C80448044807C804480448044807C80448000FC0000
+76F4:010001007FFC01001FF0101010101FF010101FF010101FF010101010FFFE0000
+76F5:004000407C8044FE45007E0044FC44087C104420444044807D02450200FE0000
+76F6:000000007DFC440044007C0047FE44907C904490449044907D124512020E0400
+76F7:004000407C8044FC45047E04448444447C444414442444447D84440400280010
+76F8:080008FC08840884FE8408FC18841C842A842AFC488488840884088408FC0884
+76F9:0020002078204BFE4820792449244924792449FC4824482078224822001E0000
+76FA:0008001C7CE0448044807C8044FE44887C884488448844887D08450802080408
+76FB:00900090790849084A047C024BFC4880790049F8480848087808480800500020
+76FC:0010009078904888490879044A044DFA78884888488848887908490802280410
+76FD:002000207C2045FC44207C20442045FC7C204420442047FE7C20442000200020
+76FE:007C3F8020803FFC20802FF8280828082FF8280828082FF8480848088FF80808
+76FF:004000207C2047FE44887C88448844887C884450445044207C50448801040602
+7700:000000FC7C84448444847CFC448444847C8444FC448444847D04450402140408
+7701:010011101108212440C003000C003FF8D0081FF810081FF8100810081FF81008
+7702:0004001E7DF0451045107D10451045FE7D104510451045087D0A454A01860102
+7703:0000000079FC4800480078004BFE4820782048404840488879044BFE01020000
+7704:000003FE7C20442045207D3E452245227D2245FE440244027C02440200140008
+7705:0008001C79E04900490079FC49444944794449284928491079104A2802440482
+7706:004000207C2045FE44407C404440447C7C444444444444447C84448401280210
+7707:004000407840494849447A424A424C4878484848481048107820484001800600
+7708:0040004078404BFC4A447C484840484078A048A048A0492079224A22041E0800
+7709:00003FF8210821083FF820002FF8280828082FF828082FF8480848088FF80808
+770A:0008003C7DE0442044207C3C45E044207C20443E47E044207C2244220022001E
+770B:00F87F0001003FF80200FFFE040008001FF028104FF088100FF008100FF00810
+770C:00000FF048104FF048104FF048104FF040007FFC010011101108210445040200
+770D:000001FE7D00450445447D28452845107D104528452845447D84450001FE0000
+770E:000001FC7800480048007BFE48204820792849244A244A227C22482000A00040
+770F:002000207C2045FC45247D24452445247D2447FE442044507C50448801040202
+7710:000000007BFE48204820782049204920793C4920492049207920492007FE0000
+7711:0010009078904910497E7A524B924892791249124A524BD278624822004A0084
+7712:002000207C2045FC45247D24452445FC7D244524452445FC7D24442000200020
+7713:00280024782448204BFE7A204A244A247A244A284A284A907B124A2A00460082
+7714:00007FFC444444447FFC01000920111021084104092011102108410401000100
+7715:002000207C50448845047E12442044407D884410442044447D88441000600380
+7716:000001FC7D04450445047D0445FC44507C504450445044927C924512020E0400
+7717:008000807D0045FC46047C0445E445247D24452445E445247C04440400280010
+7718:01000100FFFE01002288145008203018DFF610101FF010101FF010101FF01010
+7719:002000207C20444044487C8445FE44827C0044FC448444847C84448400FC0084
+771A:010011001FF821005FF00100FFFE00001FF010101FF010101FF010101FF01010
+771B:002000207C2045FC44207C20442047FE7C7044A844A845247D24462200200020
+771C:002000207C2047FE44207C20442045FC7C7044A844A845247D24462200200020
+771D:0040002078204BFE4A027C04480048007BFE4820482048207820482000A00040
+771E:20703F8420041FFC00000FF848084FF848084FF848084FF840007FFE10102008
+771F:010001007FFC01001FF010101FF010101FF010101FF01010FFFE082010102008
+7720:000001FC7D04450445047DFC452045207DFE4520452045107D12454A01860102
+7721:0004001E7DF0451045107D10451045FE7D104510451045087D0A454A01A60112
+7722:10001EF8228862A894920882307EC0001FF010101FF010101FF010101FF01010
+7723:002000207D20452045FC7D20462044207DFE4420445044507C88448801040202
+7724:000001FC7D04450445047DFC450045407D444548457045407D424642023E0400
+7725:088008882E9028E028842E84F07C00001FF010101FF010101FF010101FF01010
+7726:0090009078904A904A927AD44A984A907A904A904A904A927AD24F12020E0000
+7727:000001FC7C44444444447C44449444887D0044FC448444847C84448400FC0084
+7728:0008003C7BC04800484078204BFC4808781048204840488079004A80047E0000
+7729:0040002078204BFE48407840488849087BF048204840488879044BFC01040000
+772A:000001FE7C20442044207DFE452245227D52454A458A45027D024502010A0104
+772B:002000207D2444A444A87C2045FC44207C20442047FE44207C20442000200020
+772C:00900088788848804BFE78A048A048A478A44928492849327A224A62049E0800
+772D:002000207DFC442044207C2047FE44007C20442045FC44207C20442003FE0000
+772E:000001FE7D024502457A7D024502457A7D4A454A454A457A7D024502010A0104
+772F:00200020792448A448A8782048204BFE787048A848A8492479244A2200200020
+7730:000001FE7C20444044887D0445FE44227C20442045FE44207C20442003FE0000
+7731:002000207BFE482049FC782449FC492079FE4822482A48547850488801040202
+7732:000003FE7C88448844F87C88448844F87C884488448E47F87C08440800080008
+7733:004000407CFC450446887C50442044407C8045FC468444847C84448400FC0084
+7734:0080008079FC49044A0479E44924492479E44924492449E47904480400280010
+7735:002000207C7C448445487C30442044487D90443E444245A47C18441000600180
+7736:000001FE7D00450045FE7D104510457C7D104510451045FE7D00450001FE0000
+7737:0100111009203FF802007FFC082010102FE8C8260FE008200FE008200FE00820
+7738:00400040789049084BFC78244920492079FC4A2048204FFE7820482000200020
+7739:008800487C50440045FC7C20442044207FFE4420445044507C88448801040202
+773A:0090009078904A9249947898489049987A944C9248904890791249120212040E
+773B:010400847C88440047FE7C20442045FC7C20442047FE44207C20442000200020
+773C:000003F87A084A084BF87A084A084BF87A444A484A304A207A104A8803060200
+773D:0004001E7DE0450045067D78455045507D524554454845487D44465402620440
+773E:00007FFC444444447FFC000000FC7F0011101110111029282528454481820100
+773F:00400020781049E0482278344BB848B078A848A8492849247A244C2200A00040
+7740:082004407FFC01003FF80200FFFE04000FF018102FF0C8100FF008100FF00810
+7741:0100010079F04A104C207BF8484848487BFE484848484BF87848484001400080
+7742:0208050808881248050808883FF820002FF828082FF828082FF848084FF88808
+7743:00400040788849044BFE7802488849447A4248F849884A507820485001880606
+7744:002001247CA444A844207DFC450445047DFC4504450445FC7D04450401140108
+7745:000001FC7D0445FC45047DFC440044007DFC4420442047FE7C20442000200020
+7746:004000207BFE4A024C0479F8480048007BFE48904890489079124912020E0400
+7747:0108008878904BFC482478244BFC4A207A204BFE486248A2792A4A2404200020
+7748:000001FC7D04450445047DFC440044007DFE4420442045FC7C20442003FE0000
+7749:0020002079244924492479244AAA4C727820482049FC48207820482003FE0000
+774A:000000FC7C84448444FC7C0045FE45027D0245FE450245027DFE4502010A0104
+774B:001000D87B94489448907BFE48904894789448D84B98489078AA48CA02860102
+774C:0080008079F84A084C107BFC4A444A447A444BFC48A048A079224922021E0400
+774D:000003F87A084A084BF87A084A084BF87A084A084BF8492079204A220422181E
+774E:01840068783048C84B0478404BFE48A079204BFC4D2449247934492800200020
+774F:000003FE7A224A224A227BFE4A224A627A724AAA4B224A227A224A0203FE0202
+7750:0020002078204BFE4820792448A448A87BFE487048A848A879244A2204200020
+7751:0040004078A048A049107A084DF64800788848484A4849507910482007FE0000
+7752:0020012279224A24485078884B0448227820492449244A287850488801040602
+7753:0090009078904BFC4A947A944A944BFC7A944A944A944FFE7800489001080204
+7754:002000207850488849047AFA480049FC7954495449FC4954795449540104010C
+7755:004000207BFE4A024D04790049DE4A527A524B524C9A4894791049120212040E
+7756:0020002079FC482048207BFE488849447A4248F849884A507820485001880606
+7757:000001F87908490849F87908490849F8788049FC4A544C9479244A4400940108
+7758:00003FF8244824483FF80000FFFE00001FF010101FF003040C881870EA180C06
+7759:004000207BFC4A044A047BFC4A004A287A244BFE4A204A507A504C8805040A02
+775A:000003FE7A104A104AFE7A104A104BFE7A004A104A104AFE7A104C1005FE0800
+775B:002000207BFE482049FC78204BFE480079FC490449FC490479FC490401140108
+775C:003C07C07A44492848007BF8484848487FFE484848484BF87848484001400080
+775D:0C8070FC1124FE24384454A8911000001FF010101FF010101FF010101FF01010
+775E:0020002078204BFE48207924492449247AAA487048A848A879244A2204200020
+775F:004000207BFE48004888788849544A22780048204BFE48207820482000200020
+7760:0020012478A8482049FC78404BFE488879044AFA4C88488878A848920082007E
+7761:00100078F3C090409040F7FC92489248F7FE9248924897FCF040904007FC0000
+7762:00A00090788049FE49107B104DFC4910791049FC49104910791049FE01000100
+7763:08000EFC0844FF4408282A10492808441FF210101FF010101FF010101FF01010
+7764:000001FC7924492449FC7924492449FC780048004BFE48887888488801080208
+7765:004000807BFC4A244A247BFC4A244A447BFC489049104FFE7810481000100010
+7766:0020002079FC482048207BFE488849047A22482049FC48207820482003FE0000
+7767:001C03E07A204BFE4A207A924B0A4A0679FC4904490449FC7904490401FC0104
+7768:000000407B9C4A044A047B9C4A044A047BFC489048904890789049120212040E
+7769:000001F87808480849F8780848084BFE78204A22497448A879244A2200A00040
+776A:00007FFC44447FFC01003FF80100FFFE082004403FF80100FFFE010001000100
+776B:002000207BFE482049FC78244BFE482479FC48204920493E79204AA0027E0400
+776C:0008003C7BC048444A247928490048207BFE487048A848A879244A2204200020
+776D:000001FC792449244974792449FC4904797449544954497479044A0402140408
+776E:004000A079104A084DF678004BC44A547A544BD44A544A547BD44A44025402C8
+776F:00207E20427E7EA448247F284810652843461FF010101FF010101FF010101FF0
+7770:008800887BFE488848A878204BFE4840788048FC49844A847884488400FC0084
+7771:000003DE7A424A424A427BDE4A004A3E7BD24A124A144BD47A084A1402240242
+7772:000001FC790449FC490479FC4820492079FE4A20482049FC7820482003FE0000
+7773:002000207BFE485048887B2649FC482078204BFE4800482079FC4820002003FE
+7774:000003FE7A2248204BFE782049FC492479FC492449FC48207BFE482000200020
+7775:012801247BA4492049207FFE482048247BA44AA84AA84A907B92482A00460082
+7776:004000407BFC484049F878804BFC49107A084DF64910491079F04910011001F0
+7777:00200020F0FC9E2493FEF22494FC9420FEFC922092209BFEF420962009FE1000
+7778:000003FC7A244A244BFC7A004AFC4A847A844AFC4A844AFC7A844A8404FC0884
+7779:004000447BF4484848507FFE4840488079FC4B044D0449FC7904490401FC0104
+777A:008000BC7884490849FE7B204D20497C7990491049FE49107928492801440182
+777B:004000207BFE4A024C0479FC480049FC790449FC490449FC7904480003FE0000
+777C:000001FC7904490449FC7904490449FC78004BFE48204920793C492002A0047E
+777D:001003D478584A52498C788849044AFA782048204BFE48207850488801040202
+777E:040008007FFC44447FFC01003FF80100FFFE082004403FF80100FFFE01000100
+777F:010001F801007FFE40029FF4092032900C603FF8D0161FF010101FF010101FF0
+7780:7E20243E1848FFA829104A28984600001FF010101FF010101FF010101FF01010
+7781:000003FC7A044BFC4A047BFC4A044BFC785048484FFE484078A0491002080C06
+7782:022807243C24242024FE3F2024202F3C29342F5429542F54298849884F148922
+7783:0008001C79F04910491079FE4910497C7944497C4944497C79444A44027C0444
+7784:008800887BFE48884888780049FC49247924492449FC49247924492401FC0104
+7785:008801C8F7089108912AF12A97AC9148F308938895549514F914912401240142
+7786:0020002079FC492449FC78204FFE480079FC4904492449247924485000880304
+7787:001000927A5249544910787E48104B38795449924910491079104A80047E0000
+7788:0090008879044A424C8879FC480448007BDE48424A52494A7A524842014A0084
+7789:1000FE7810487C480048FE8682007CFC00447C4444287C2844107C2844447D82
+778A:002000107BFE4A204AFC7A244BFE4A247AFC4A204AFC4A847A844C8404FC0884
+778B:002000207BFE482049FC790449FC490479FC490449FC49047BFE488801040202
+778C:0020002079FC482048207BFE488049047BFE48024BFC4A947A944A9407FE0000
+778D:0140065CF4449444975CF444944497FCF04097FC92089110F0A0904001B00E0E
+778E:004000207BFE4A024C2479FC482049FC78204BFE482049FC7904490401FC0104
+778F:7FFC44447FFC01001FF001007FFC00001FF010101FF0048808503820CB180C06
+7790:1FF810081FF810081FF810081FF800007E7E42427E7E42427E7E42427E7E4242
+7791:000003FE7A02480049FC790449FC490479FC484048204BFE7800488801040202
+7792:01080108F7FE91089000F7FE90909090F7FE94929492956AF6469402040A0404
+7793:02020122782A4FEA482A7BAA482A4BAA782A4BAA4AAA4AAA7BAA4AAA00420082
+7794:002003FE782049FC48207BFE480049FC790449FC490449FC790449FC00880104
+7795:002001FC788848504BFE780049FC490479FC490449FC48207BFE482000200020
+7796:7F7848485F4C64805F784A4851307F4C00001FF010101FF010101FF010101FF0
+7797:0040008079FC490449FC790449FC490079FE490049FE48027AAA4AAA0202000C
+7798:000003FE7A004A7C4A447A444A7C4A007AEE4AAA4AAA4AAA7AEE4A0003FE0000
+7799:008800887BFE4888480079FC490449FC790449FC48204BFE7850488801040202
+779A:004000207BFE4A02480079FC482049FC792449FC492449FC7800488801040202
+779B:01240124F22494249954F14A92929610FA109250925C9250F25092B0029E0300
+779C:002001FC79244BFE492479FC482049FC792449FC48404BFE788849D00070038C
+779D:004000207BFE480049547924495449FC78204BFE4A424A927AFA4A0A02020206
+779E:008800887BFE4888488878F848204BFE7A224B324AAA4B767A224A22022A0224
+779F:000003FE785049FC4954795449FC480079FC48004BFE482078A8492402A20040
+77A0:0020012478A84BFE4A0278F84888488878F84820482049FC7820482003FE0000
+77A1:0200027CF2449744927CF2449244977CF2449244927C9228F528954A084A1086
+77A2:0820FFFE08203FF824483FF800007FFE40029FF410101FF010101FF010101FF0
+77A3:0020002079FC492449FC78204BFE4A227BFE4820484048247AA24A8A04780000
+77A4:00007BDE4A524BDE4A527BDE4A024AFA7A224A724A224A227AFA4A02020A0204
+77A5:082049202A3E7F4849485DA86B10492843461FF010101FF010101FF010101FF0
+77A6:002003FE782049FC480079FC490449FC78884BFE480049FC7904490401FC0104
+77A7:00A0009079FE49104B107DFE4910491079FE4910491049FE79004AA402520452
+77A8:00A004A4F2A890A097FCF11090A097FCF04093F8904097FCF0A0911002080C06
+77A9:000007FCF40497FC9400F5FC942095FCF52495FC942097FEF62A96FA0A0A1206
+77AA:002007A4F0A892929114F20895F49802F3F89208920893F8F20891100FFE0000
+77AB:000003FE78504BFE4A527BFE480049FC790449FC490449FC78204BFE00200020
+77AC:003C07C0F04492249108F7FE94029A08F20893BE94889AA8F13E920804080808
+77AD:00400040F7FC90A09514F20897FC9A0AF3F8920893F89040F248944409440080
+77AE:02080108F7C89210949EFFD490649794F494979494949788F488949404A405C2
+77AF:03DE7A524BDE4A524BDE7A024AF24A927AF24A924AF24A927A924B3202020206
+77B0:00080788F08891109FDEF49494A49794F4949794949494C8F7889C9400A400C2
+77B1:008803FE7888480049FC78A848A84BFE78A848A849FC48207BFE482000200020
+77B2:000003FC784848304BFE785248944B5078204BFE4A524A8A7B764A5202720206
+77B3:002001FC788848504BFE780049FC492479FC492449FC482079FC482003FE0000
+77B4:0080008079FE4B544D5479544BFE4954795449544FFE48007954492A022A0000
+77B5:00400248F15097FC9150F24894449208F20893BE94889AA8F13E920804080808
+77B6:002001FC792449FC48207BFE480049FC790449FC490449FC790449FC00880104
+77B7:00007BDE4A524BDE4A527BDE4A024AFA7A8A4AFA4A8A4AFA7A8A4A02020A0204
+77B8:008803FE7888480049487BFE49484978790049FC48204BFE787048A803260020
+77B9:003C03C0F04492249108F7FE944292A4F28A947A908090F8F10892900060079E
+77BA:004000A0F3189DF69000F7FC955494E4F7FC900093F89208F3F8920803F80208
+77BB:010001F87A084FFE4A887B244BFE4A007AFC4A004AFC4A007AFC4C8404FC0884
+77BC:0040004078A049104A087DF6480048007BB84AA84AA84BB87910491002A80444
+77BD:0810FF7E08107E7C42447E282418FEE600001FF010101FF010101FF010101FF0
+77BE:00003EF822883EF822883EF822883EF801007FFC482410102FE8010001007FFC
+77BF:3EF822883EF822883EF822883EF808801FFC30805FF890801FF810801FFC1000
+77C0:028802A8F6A89BF0901EF22495D49C14F41495D495549548F568955406140422
+77C1:00C80708F12A912C9FC8F10893889554F914912290409024F522950A090800F8
+77C2:01FC0104790449FC48007BDE4A524A527BDE48204BFE487078A8492406220020
+77C3:004000207BFE4A224954794A4A3A480079FC49544BFE480079FC482000A00040
+77C4:001C01E078204BFE482079FC49AC497479FC482049FC48207BFE48000154022A
+77C5:000003DE78424A52494A7A52489049087BFE4D1049FE491079FE491001FE0100
+77C6:008803FE78A8489049FE7B2049FC492079FC492049FE49007BFC48880070038E
+77C7:008803FE78884BFE4A0279FC48004BFE784048A24B5448B87B54489203500020
+77C8:004001FC790449FC490479FC48204BFE7A8A49244BFE488078FC488401140208
+77C9:004000207BFE4A0249FC79484A5049FC7B0449FC490449FC790449FC00880104
+77CA:01080110F23E922294BEF722913E9208F4BE97AA902A90AAF56A952E04080008
+77CB:000003FE7A484BFE4A487AFC4AA44AFC7AA44AFC4A204BFE7B2A4D7A050A0906
+77CC:002000107BFE4A444AFE7A444BFE4A107AFE4A924AFE4A927AFE4A0002440482
+77CD:7CF844887CF844887CF809001FF831005FF091001FFC10003FF0082007C0F83E
+77CE:010001F87A084FFE4A627A9249FC490479FC490449FC488079F84A880070038E
+77CF:004001FC79244994494C792449FC48207BFE4A8A49244BFE788048FC0104020C
+77D0:01FC78204BFE4A224DAC782049AC489079FE4B204DFC492079FC492001FE0100
+77D1:0040007C78404BFC4A447BF04A444AFC7AA84AF84AA84AF87A004DFC05540BFE
+77D2:010807FE79084BFC4A947BFC48004FFE7C0249F8490849F8790849F8010801F8
+77D3:011078904BDE48104A5E79824BDE48107BDE4A504BDE4A507BDE4A50025202CE
+77D4:00887BFE48884BDE4A527BDE48A0489079FE49204BFC4D2079FC492001FE0100
+77D5:21084FD2F03C23884812FBBE0280ABAA00001FF010101FF010101FF010101FF0
+77D6:03DE78004BDE4A524B5A7A5248204BFE7A504BFE4A524BFE7A924ADC029204CE
+77D7:01003FF801000FE00820092009207FFC08207EFC08203EF822882AA82AA8FFFE
+77D8:02480150F7FC940491F0F11097FC9554F4E497FC904097FCF0409FFE02A40452
+77D9:0FBE08A2EFBEA8A2AFBEE802AB92A892EFDEAAAAABCAAAAAEB92AAD20FAA08C4
+77DA:03FE02027BFE4A924A547A924AFE4AAA7AFE4B224AFA4AAA7AFA4A2205FA0004
+77DB:00001FF000100220014000807FFE018202840480088010802080C08002800100
+77DC:00207E200250245018880944FE220A20180019FC280448088808081028101020
+77DD:00207C200450285010880924FE121A1029FC2804480848888850082028101010
+77DE:1FF0022001407FFC04841888628001003FF82448282837D82448244827C82018
+77DF:00107C9204522854101008FEFE821A8228FE2882488248FE88820882288A1084
+77E0:00487C48044829FE10480848FFFE1A0028FC2884488448FC8884088428FC1084
+77E1:03DEFA520BDE525223DE10A0FDFE372035FC512051FE500091FC10885070278E
+77E2:0800080008001FF81100210041000100FFFE010002800280044008203018C006
+77E3:02000400082010103FF8080808001FF0210001007FFC0280044008203018C006
+77E4:00407C40048004FC05207E204020402043FE7C20045004500488048829041202
+77E5:20002000207C7E444844884408440844FF44084414441444227C224442008000
+77E6:080008001FE020204040BFFC240024002FF8308020803FFC414042208410180C
+77E7:200421E43C245024902411E41104FF04110411E4102428242424442441448084
+77E8:2008203C21E07C205020902013FEFC2010201050105028502488448841048202
+77E9:200021FE3D005100910011FC1104FF041104110411FC29002500450041FE8000
+77EA:2010202020FC7C8450A490941094FDFE108410A4109428942484450441148208
+77EB:2008203C21E07C20502093FE1050FC881104128A108828882488450841088208
+77EC:2020202021247D245124912412AAFC721020102011FC28202420442043FE8000
+77ED:200021FE3C00500090FC10841084FE8410FC1000108428442448440041FE8000
+77EE:201C21E03C20502093FE10A81124FE42104013FE1088290824D0443040488184
+77EF:201821E03C4053FE908811741252FE70100011FC11042974255445744104810C
+77F0:210420883C0053FE922212AA1272FE2213FE100011FC290425FC450441FC8104
+77F1:208823FE20A87C9051FE932011FCFD2011FC112011FE290027FC44884070838E
+77F2:200023FE42527A52A3FE2110225223DCF81223CE224023D2525C4BD04A5282CE
+77F3:0000FFFE020002000400040008000FF81808280848088808080808080FF80808
+77F4:00000000FEFE1010101020103E1062106210A210221022103E10221000500020
+77F5:00040004FE041044104420443E4462446244A244224422043E04220400140008
+77F6:000001F0F9102110211041107910C91049104910491049127A124212040E0800
+77F7:000001FCFC041008101020203C2067FE6420A420242024203C20242020A00040
+77F8:000001FCFC201020102020203C2067FE6420A420242024203C20242020200020
+77F9:00000000FDFC1090109020903C9064906490A490249024923C922492210E0200
+77FA:0008003CFDE01020102020203C20643E65E0A420242024223C222422201E0000
+77FB:00400040FE8010FE110022003CF86410A4202440244024823D02250200FE0000
+77FC:00000000FDFC1020102020203C2064206420A420242024203C20242023FE0000
+77FD:00400040FC40107E108220823D4266246414A408240824103C20244020800300
+77FE:000001F0F9102110211041107990C95049504910491049127A124212040E0800
+77FF:00200010FC1010FE108020803C8064806480A480248024803C80250021000200
+7800:000001F8FC101020104020803DFE64926492A492251225223E22244220940108
+7801:000001F8FC081008108820883C8864FE6402A402240225FA3C02240220140008
+7802:00200020FC2010A810A420A23D2265206624A424242824083C10242020C00300
+7803:000000FCFC84108410A420943C94648465FEA484248424843C84250421140208
+7804:00200020FC2011FC102420243C24642465FEA420245024503C88248821040202
+7805:00200020FC201020103221B23CB464A864A8A4A8252425243E22242020A00040
+7806:00200020FC20102011FC20203C20642067FEA420245024503C88248821040202
+7807:00400020FC2013FE108820883C8864886488A450245024203C50248821040602
+7808:000001FEFD001100117821483D4865486548A568255025423D422542223E0400
+7809:010001007FFC01003FF801007FFC01007FFC040008003FF0C81008100FF00810
+780A:00400020FC0011FC100020003CF064906490A490249024923C922512210E0200
+780B:00100010FC101090109020903C9E64906490A490249024903C90249023FE0000
+780C:00000100F97E21122112411279D24F12C91249124952499279224822004A0084
+780D:00400040FC40107C108420883D2064206420A450245024503C88248821040202
+780E:00200020FC501050108821043E0264886488A488248824883C88250821080208
+780F:00100050FC501050108820883D0466FA6448A448244824483C88248821280210
+7810:000003FCF884208820884090789CC88449444944492849287A10422804440182
+7811:000003FCF8102110211041107A10CBFE48304850489049107A10441000500020
+7812:00100110FD101112111221143DD865106510A510251025123D522592210E0000
+7813:000000F8FC881088108821063E0065FC6484A484244824503C20245020880306
+7814:000001FCFC881088108820883C8867FE6488A488248824883C88250821080208
+7815:00400040FDF810481088208A3D0A66266420A42027FE24203C20242020200020
+7816:00200020FC2011FC102020403DFE64406480A5FC240424883C50242020100010
+7817:00400040FC4013FE108020A03D2065FC6420A420242027FE3C20242020200020
+7818:00200020FC2013FE102021243D2465246524A5FC242424203C222422201E0000
+7819:00000000FBFC2100210041F079104910C9904A504A504A107A124A920312020E
+781A:000001FCFD041104112421243D2465246524A554245024903C9025122212040E
+781B:00200020FC501050108821443E2264206400A5FC240424083C08241020100020
+781C:000003F8FA082208232842A87AA8CA484A484AA84AA84B2A7C0A440A08061002
+781D:00200020FC2011FC102020203C2065FE6420A420244024483C8425FE20820000
+781E:00200020FC2013FE102020203C2065FC6470A4A824A825243D24262220200020
+781F:00800080FC8010FE114021403E40647C6440A4402440247E3C40244020400040
+7820:000000F8FC881088108820F83C8864886488A4F8248824883C88248823FE0000
+7821:00000000FDFC1020102020203C20642065FCA420242824243C24242023FE0000
+7822:00000000FDFE1008100821E83D2865286528A52825E825283C08240820280010
+7823:00200010FC1011FE110222043C8064886490A4A024C024823C822482207E0000
+7824:00800080FCFE1100122021203D2C657467A4A524253425283D22250220FE0000
+7825:0004001EFDF01110111021103D1065FE6510A510251025083D0A254A21A60112
+7826:088008882E9028E028842E84F07C00007FFC040008003FF0C81008100FF00810
+7827:00200020FC201020103E20203C20642065FCA504250425043D04250421FC0104
+7828:00400020FDFC1104110421FC3D006500657CA508251025203D422682227E0400
+7829:00900090F89023FC209440947BFC4A90CA904BFE48924892791A491402100410
+782A:000000FCFC8410A4109420843C8467FE6504A544252425043DFE240420280010
+782B:00400020FC0013FE102020203C20642065FCA420242024203C20242023FE0000
+782C:00400020FC20100011FE20003C0464846484A448244824483C50241023FE0000
+782D:0004001EFDE01000102020103DFE64046408A410242024403C802540223E0000
+782E:10001000FEFC2244642818102428C2C60000FFFE08001FF82808C8080FF80808
+782F:00200020FD2010A0103221B23CB464A864A8A4A8252425243E22242020A00040
+7830:000001FCFC201020112420A43CA8642067FEA420242024203C20242020200020
+7831:00200020FC501050108821243E12641065FCA404240824883C50242020100010
+7832:00800080FDFC1104120425F43D1465146514A5F4250425283D12250220FE0000
+7833:00000000FEFE1020102020403E7C62C462C4A3442244224422443E7C22440000
+7834:00100010FC1011FE111221143D1065FC6544A544252825283D10262822440482
+7835:00200020FC20102011FE20203C70647064A8A4A8252426FA3C20242020200020
+7836:00200020FC4011FC110421043D04650465FCA504250425043D04250421FC0104
+7837:00200020FC2011FC112421243D2465FC6524A524252425FC3D24242020200020
+7838:000003FEFA102210221042FE7A924A92CA924A924A9A4A947A104A1003FE0000
+7839:01100110FBFC2110211040007A08CA084910491048A0484078A0411002080C06
+783A:000001FEFD001100110021FE3D206520653CA524252425243D24224402540488
+783B:04400420FFFC0910116021844F0480FC0000FFFE08001FF82808C8080FF80808
+783C:00200020FC501050108821043E02640065FCA420242024203C20242023FE0000
+783D:000001FCFD241124112421FC3D2465246524A5FC252425243D2425242104020C
+783E:0008001CFDE01100112021203D2065FE6420A42024A824A43D22262220A00040
+783F:00200010F81021FE2100411079104910C9104920492849247A444AFE04420800
+7840:00200020FD241124112421243DFC64206420A524252425243D24252421FC0004
+7841:000001FCFC081010103020483C8467026400A5FC242024203C20242023FE0000
+7842:00200020FC501088110422023DFC64206420A42025FC24203C20242023FE0000
+7843:00200120FD2011FC112022203C2067FE6470A4A824A825243D24262220200020
+7844:00200020FD2410A410A820203DFE64906490A490249024923D122512220E0400
+7845:00200020F9FC2020202040207BFE4800C820482049FC48207820482003FE0000
+7846:00200020FC501050108821043EFA64006400A4F8248824883C88248820F80088
+7847:00200020FC4011FC110421043D9465546524A524255425943D04250421FC0104
+7848:00200020FC2013FE102020203DFC64006400A5FC250425043D04250421FC0104
+7849:00200020FDFC102413FE202421FC7C206420A5FC2420242027FE3C2024200020
+784A:00400040FCFC1104120821FE3D00657C6544A544255425483D422542213E0200
+784B:00200010FC1013FE102020423C8465F86410A42224C427083C10242820C40302
+784C:00400040FC781088115020203C5064886506A4F8248824883C88248820F80088
+784D:000001F8FD08110811F821083D0865F86544A548253025203D10254821860100
+784E:000207E2FA42224A224A424A7A4A4FEACA4A4A4A4A4A4A4A7A424C42044A0844
+784F:000001DCFC881088108820883C8867DE6488A488248824883C88250821080208
+7850:000001FEFD021102117A21023D02657A654AA54A254A257A3D022502210A0104
+7851:01040084FC88100013FE20883C8864886488A7FE248824883D08250822080408
+7852:000003FEFC50105011FC21543D5465546554A554258C25043D04250421FC0104
+7853:00400040FC4411F41048205023FE7C406480A584269824E024823C82247E0000
+7854:00880088FC88108813FE20883C8864886488A7FE240024883C84250422020402
+7855:000003FEFC20104011FC21043D0465246524A524252425443C50248821040204
+7856:00200020FC2011FC102021243CA464A86420A7FE245024503C88248821040202
+7857:00800080F8BC23C02050402478D44B0CC8004BFE4890489079124912020E0400
+7858:00000000FDFC1104110421743D5465546554A554257425043D0425FC21040000
+7859:00200124FD24112411FC20003DFC64046404A5FC250025003D02250220FE0000
+785A:0008003CFDE01020102023FE3C5064886504A68A248824883C88250821080208
+785B:00400020F82027FE2090409078904A94CA924A924C9248907910491002500420
+785C:000001FEFC001092112422483D2464926400A5FE242024203C20242023FE0000
+785D:00200124FCA410A8102021FC3D04650465FCA504250425FC3D04250421140108
+785E:00200120FD2011FC112022203C2067FE6400A40025FC25043D04250421FC0104
+785F:0004000EFBB8208820884128792E4BA8C8A84AA84AA8493E79004A80047E0800
+7860:00400020FDFC1104110421FC3D04650465FCA520252225143D08254421820100
+7861:00400020FBFE2202244440407BFE4840C8904890491049207A244A4204FE0842
+7862:00200020FC501088110422FA3C20642067FEA420252825243E22242220A00040
+7863:00200022FDFA1024102423FE3C10642065FCA488251026FE3C10241020500020
+7864:00200020FC2013FE102020203D2465246524A6AA242024503C50248821040202
+7865:00900088FC8013FE10A020A83CB064A464A8A4B02524252A3D32222202DE0400
+7866:000003FEFC20102011FC20203C2067FE6488A48827FE24883C88250821080208
+7867:000001F8FC0810D0102021FC3D24652465FCA524252425FC3D2425242124010C
+7868:00200020FDFE102011FC21243D2465FC6524A52425FC24203DFE242020200020
+7869:080C08F07E8008800EFE7888088829081208FFFE08001FF82808C8080FF80808
+786A:001000D8FB942094209043FE78904894C89448D84B98489078AA48CA02860102
+786B:00400020FBFC2040209041087BFC4804C9504950495049507A504A520452080E
+786C:000001FEFC20102011FC21243D2465FC6524A52425FC25203CA0244020B0030E
+786D:00480048FDFE1048104820203C1065FE6480A480248024803C80248020FC0000
+786E:00400040FC7C1084110822FE3C92649264FEA492249224FE3C922512210A0204
+786F:000001F8FD08110811F821083D0865F86508A50825F824903C9021120212040E
+7870:1020082040A824A4092A723010C017000000FFFE08001FF82808C8080FF80808
+7871:000001FCFD241124112421FC3D2465646574A5AC252425243D24250421FC0104
+7872:00000050FC481084112420203C5064886506A6F8248824883C88248820F80088
+7873:00200020F9FC2020202040207BFE4848C848494C494A4A4A7888488801280210
+7874:00880088FDFE1088108820503C5064946594A698249024B23CD22492208E0080
+7875:00200020FC3E1020102021FE3D02654A652AA5122512252A3D4A250221FE0102
+7876:00200124FD24112411FC20203C5064886544A622242025F83C08241020100020
+7877:00400040F8A020A0211042087DF64800C88848484A4849507910482007FE0000
+7878:00200124FD24112411FC20003DFE6500657CA510251025FE3D10221002100410
+7879:02080228F22822282FA442447254D69257105AA05A205228724452FC02440200
+787A:000001FEFC20104010A221123C3465586498A554243424523C90251020500020
+787B:00007EFC48447E4442287E1048287EC60000FFFE08001FF82808C8080FF80808
+787C:000003DEFA522252225243DE7A524A52CA524BDE4A524A527A524A52055208A6
+787D:00400080FBFC2110224844467BF84A48CA484BF84A484A487BF848420042003E
+787E:0008003CFDE0102013FE20A83CA864A867FEA4A824A827FE3C20242021FC0000
+787F:00400020F82023FE2202449479084A04C80049FC482048207820482007FE0000
+7880:00400040FCF81108101021FC3C24642467FEA424242425FC3C24242020A00040
+7881:08207FFC08200FE008200FE00820FFFE10103FF8C4060FE0182068200FE00820
+7882:00400020FBFE2202200041FC78004800CBFE4820492849247A224C2200A00040
+7883:00200020FBFE202021FC40207BFE4800C9FC490449FC490479FC490401140108
+7884:01100110F910211027BC411079104B38CBB84D544D5449927910491001100110
+7885:000003FEFA02221A22E242227A224BFECA224A724AAA4B267A224A2203FE0202
+7886:202013FC82244BF812882450E470298C2000FFFE08001FF82808C8080FF80808
+7887:00400020FBFE2202240440007BFE4820C8204920493C49207AA04A60043E0800
+7888:001C03E0FA2023FE222042927B0A4A06C9FC4904490449FC7904490401FC0104
+7889:000001FCFD241124117421243DFC65046574A554255425743D04220402140408
+788A:00480044FC5E11E0102820123C6A65966448A45E25E024243C282412206A0186
+788B:00200124FD24112411FC20003DFE640865E8A528252825E83D28240820280010
+788C:000001F8F808200821F8400878084BFEC8204A22497448A879244A2200A00040
+788D:000001F8FD0811F8110821F83C0065FC6410A7FE241025103C90241020500020
+788E:00400020FDFE1000108820883D5466226400A42027FE24203C20242020200020
+788F:00480048FC4811FE104820483DFE640064FCA484248424FC3C84248420FC0084
+7890:00200020F9FC2020202043FE78884944CA4248F849884A507820485001880606
+7891:00400080FDFC1124112421FC3D24654465FCA490251027FE3C10241020100010
+7892:00200020FC501088110422023CF864206420A5FC242025243CA424A823FE0000
+7893:00500048FC8010FE119022903CFC64906490A4FC249024903C9024FE20800080
+7894:0008000CFCEA100A100821FE3C4864486548A568254825483D4A256A23860102
+7895:00200020FDFC10501088210423FE7C0865E8A528252825E825283C0824280010
+7896:00200020FC501088110422FA3C0065FC6554A55425FC25543D5425542104010C
+7897:00400020FBFE22022504410079DE4A52CA524B524C9A4894791049120212040E
+7898:00500050FC5011FC115421543D5465FC6554A554255427FE3C00248821040202
+7899:000003FEFA02228A225243FE7A224A22CAAA4AAA4AAA4AFA7A024A02020A0204
+789A:00400020FDFC1000110820903C0067FE6400A40025FC25043D04250421FC0104
+789B:00200020FBFE202021FC40207BFE4800C9FC4904492449247924485000880304
+789C:00800090F90823FC204047FE79104A48CC864B10482048C47B08483000C00700
+789D:000003FEFC20104011FC21543D5465546554A52C242027FE3C50248821040202
+789E:00001FF010101FF000007C7C44447C7C0000FFFE08001FF82808C8080FF80808
+789F:00900290FA9027FE229042907AF0CA004BFC48404FFE48E0795042480C460040
+78A0:00400020FBFE200021FC410479FC4800CBFE4A0249FC48207820482000A00040
+78A1:002001FEFC2010FC102021FE3C0064FC64A4A49425FE24A43D1425FE20040018
+78A2:000000FCFC84108410F420943C9465FE6502A57A254A254A3D7A2502210A0104
+78A3:000001FCFD0411FC110421FC3C8065FE6622A522255225023DFA240220140008
+78A4:00880088FBFE208820A8402079FC4924C92449244BFE48207850488801040202
+78A5:00800040FBFC2204220443FC7A00CA004BFC4B544B544DFC7D5445540944010C
+78A6:00400020FBFE2202208040F879084A90C86049984E0649F87908490801F80108
+78A7:0020FE4010FC7C8410FC1E84F0FC00007FFC040008003FF0C81008100FF00810
+78A8:000001FCFD24112411FC21243D2465FC6400A7FE252025223D14254821840102
+78A9:000003FEFC20104011FC21043D0465FC6504A5FC250425043DFC240020880104
+78AA:00880088FBFE208820F8408878F84888C8884BFE490049487984490001FE0000
+78AB:00800338FA28222823A842467A004A7CCBA44A244A284BA87E104A2802440282
+78AC:000003DEFA422242224243DE7A004A3ECBD24A124A144BD47A084A1402240242
+78AD:000001F8F90821F8210841F878004BFEC90049FC4A544C9479244A4400A80110
+78AE:000001FCFD04110411FC21043D0465FC6400A7FE242025203D3C252022A0047E
+78AF:00920124FA4821242092404078804BFECA024A8A4A524A227A524A8A03FE0202
+78B0:01080090F80023FC2090409078924C92CA944A98489048907890489007FE0000
+78B1:00140012F01027FE2410441075D0D412541255D45554554875DA542A08461082
+78B2:00400020F9FC2000208840507BFE4A22CC2449FC492449247934492800200020
+78B3:00200124F924212421FC408078804BFEC890491049524A547AA84C2808440082
+78B4:00200020FBFE207020A841247A2249FCC90449FC490449FC7904480003FE0000
+78B5:00200020FC3E1020102021FC3D0465FC6504A5FC250425FC3C00248821040202
+78B6:0080009EFBEA208A21CA408A7BEA4892C8A648204BFE48207850488801040602
+78B7:0008001CFDF01110111021FE3D10657C6544A57C2544257C3D442244027C0444
+78B8:000007FCF404243425C4444475F4D554555455F45444545475F4549408061002
+78B9:00400020FBFE2202240441FC780049FCC90449FC490449FC7904480003FE0000
+78BA:00400040FBFE22A2209041FE79104B10CDFE4910491049FE7910491001FE0100
+78BB:00200010FDFE100010FC20843CFC640065FEA502257A254A3D7A2502210A0104
+78BC:000001FEF92021FC212041FC79204920C9FE48024AAA4AAA7AAA4A0200140008
+78BD:000001FCFC20102013FE20003DFC650465FCA50425FC25043DFC248821040202
+78BE:000001FEFD02110211FE21243D24657E6524A52425FE25523D54264822640442
+78BF:000003FEFA02220223FE42107A92CA544AFE4A824AFE4A827AFE4482048A0884
+78C0:02440124F928207E2010435479544954C97C49144920492079404A80047E0000
+78C1:01080088F09027FE210841087210D29454A4573851085210721054A407BC0084
+78C2:004003BEFA122292225242AA7B244840CBFE4A224A224BFE7A224A2203FE0202
+78C3:0004001EFBF0221E221042FE7A92CA984AF24A8E4A804AB87AA844AA054A0A86
+78C4:00200010FDFE1110117C21143DFE6514657CA510257C25443D442244027C0444
+78C5:00400020FBFC2108209043FE7A024C44C8204BFC488048F87888490801280210
+78C6:000001FCFD0411E4112423FE22027DFC6504A5FC250425FC25043D0425140108
+78C7:00200040FDFC1104115421243D54650465FCA400251225D43D1825522192010E
+78C8:00200040FBFC2224222443FC7A244A44CBFC484048A848B4793C49220222041E
+78C9:03F00110F0E02318200047BC74A4D31854A4504057FC50E0715052480C460040
+78CA:7FFC040008001FF0281048108FF000007EFE102020407EFCA34422443E7C2244
+78CB:00840044FC4811FE102020FC3C2065FE6440A48024FE25103E10241021FE0000
+78CC:00200020FBFE202021FC410479FC4904C9FC490449FC49047BFE488801040202
+78CD:00400020FBFE2202242441FC782049FCC8204BFE482049FC7904490401FC0104
+78CE:001E03E0FD2210941040208821F07C2064C4A5FE2422242027FE3C5024880306
+78CF:00880050FC0013FE105021FC3C5467FE6454A5FC245024D83D54265220500050
+78D0:08783E48228E2A007EF822482A3046CC0000FFFE08001FF82808C8080FF80808
+78D1:00200124FD24112411FC20003FFE640065FCA504250425FC3C88245023FE0000
+78D2:000000FCFC84108410FC20003DFE650265FEA50225FE25023DFE244820840102
+78D3:00100220F97C21442044407C7B404940C97C49444944497C79444A80047E0000
+78D4:02080208F3BE24882AA8413E7208D448584857FC50E0515072485C4600400040
+78D5:00200020FCFC1020102021FE3C40648465FEA40225FC25543D54255423FE0000
+78D6:000001DEFC42115210CA21523C42642064FCA484248424FC3C84248420FC0084
+78D7:00280024FBFE202021FC412479FC4924C9FC492448084BFE7888484800480018
+78D8:0008003CFBC020042244412879FC4A20C8204BFE482049247924492401FC0004
+78D9:00400020FBFE208821244242789049F8C808484448A849907A884CA400C20080
+78DA:002003FEFC2011FC112421FC3D2465FC6422A7FE240827FE3D08248820280010
+78DB:08047F7808407F40497E7F4849487F4808487F4808887FFC08001FF868080FF8
+78DC:01000110FBDC22542554428879084AF4CC0248004BFC484079504A4805440080
+78DD:00880088F88823D0209E43E478944FD4C91449D44954494879484A5402D40422
+78DE:00200222FA2223FE200043DE7A524A52CBDE4A524A524BDE7A524A52055A08A4
+78DF:000007BCF88424A4229444A478504988CE2648C04B1048647B88483000C00700
+78E0:00200020F83E2020202043FE7A024B26CA8A4A524B264A527A8A4B2603FE0202
+78E1:02480248F7E8224823DE424A73CAD24A524A5FEA540A554A7632541207EA0044
+78E2:00200020FBFE202022AA41247AAA4820CAAA49244AAA48507850488801040602
+78E3:00400088F9FC2108225243FE78504988CE2648C04B1048647B88483000C00700
+78E4:000000DCFB14221423D442547BE6CA404BDC4A144BD44A547A484448055408A2
+78E5:000001FCFD2411FC112421FC3C40648865F0A420244427FE3C22252422220060
+78E6:000003FEFC5011FC115421543DFC640065FCA40027FE24203CA8252422A20040
+78E7:002003FEFC2011FC102023FE3C0065FC6504A5FC250425FC3D0425FC20880104
+78E8:00803FFE22102F7C221027382AD422102FFC2100220027F84A08520883F80208
+78E9:000C000AF80823FE220842487A6ACA4A4BFA4A4C4A4C4AEC7B5A444A04D60822
+78EA:00200222FBFE2090208841FE7B104D10C9FE4910491049FE7910491001FE0100
+78EB:01240124F22424242954414A7292D6105A105250525C5250725052B0029E0300
+78EC:08007F7808483E4800863E782A483E304048FFFE08001FF82808C8080FF80808
+78ED:03FE0200FAFC220023FE42947AA8CAC44A004AFC4A844AFC7A8444FC0484088C
+78EE:00200124FD2411FC102020503C8865746602A5FC255425543DFC25542154010C
+78EF:01240124FAAA23AE212442AA7BAE4924CFFE4910491449147A8A4A4A02160422
+78F0:00880050FBFE202021FC40207BFE4924C8A84BFE480049FC7904490401FC0104
+78F1:008802AAFADC24882154422278004BFECA424C444BFC48447844488401140208
+78F2:0200017EF840247C224440FC79404E7ECA2048204BFE487078A8492402220020
+78F3:01040088F80023FE222242AA7A724A22CBFE480049FC490479FC490401FC0104
+78F4:002007A4F0A822922114420875F4D80253F85208520853F8720851100FFE0000
+78F5:000003DEFA5223DE225243DE7A024AFACA8A4AFA4A8A4AFA7A8A4A02020A0204
+78F6:0080031CFA042204239C42047A04CBFC49004BFE4C024AAA7AAA440200140008
+78F7:00200124F8A823FE20A841247A224904C90449DE4A444D54789E490402040404
+78F8:00880050FBFE205021FC4154798C4974C90449FC48204BFE7850488801040202
+78F9:000003FEFC5013FE125223FE3C0065FC6504A5FC250425FC3C2023FE00200020
+78FA:00880088FDFC1088108823FE3C2065FC6524A5FC252425FC3C00248821040202
+78FB:003C03E0FD2410A813FE20A83D24660265FCA524252425FC3D24252421FC0104
+78FC:00A00090FDFE132011FC21203DFC652065FEA500242027FE3C7024A823260020
+78FD:00200020F9FC202023FE41087B9C4908C9884E3E48004BFE789048900112020E
+78FE:000003DEFA52225223DE400079FC4924C9FC492449FC48207BFE482000200020
+78FF:3FFE21042E3822102FBC27182AB4325220002FFC210023F826085A0843F88208
+7900:03DE0252FBDE225223DE42027AF24A92CAF24A924AF24A927A924B3202020206
+7901:00A00090F9FE2110231045FE79104910C9FE4910491049FE79004AA402520452
+7902:002003FEFC2011FC100021FC3D0465FC6488A7FE240025FC3D04250421FC0104
+7903:012400A8FBFE220220F8408878F8480CC9F0482049FC48207BFE482000A00040
+7904:001801E0FC4013FE108821743E5264706400A5FC250425743D5425742104010C
+7905:02080108F7C82010279E449477A4D01457945094511451C87708511405240242
+7906:00200020FC501088110422FA3C00640065DCA554255425DC3C88248821540222
+7907:00400080FBFE222222AA42227BFE4A72CAAA4A0248204BFE7850488801040602
+7908:00440224F928207E201040287B4A491CC928494C491A492A7948491002FE0400
+7909:01080208F7C8245027DE446477D4D214511457D4521453C872485454055408A2
+790A:0878FFC808483E862B783E482A28FF9049287F4600007FFC08001FF868080FF8
+790B:000001FCFD5411FC102021FC3C2067FE6488A45025FC24203FFE242020200020
+790C:000001FCFC2013FE122221AC3C2065AC6400A5FC252425243DFC2524212401FC
+790D:008803FEFC8811FC110421FC3D0465FC6480A5FE262225523D0225FA200A0004
+790E:00880088FBDE208821DC42AA7C884800CBFE48224920493C79204AA0047E0800
+790F:00500252F954205023FE408878504BFEC82049FC48204BFE78A8492406220020
+7910:0A803138228838382288393822887FFE4002BFF404000FF0181068100FF00810
+7911:00200124FCA813FE120220F83C88648864F8A40025FC25243DFC252421FC0104
+7912:01040088FBFE202021FC40207BFE4854C99248904BFE489078D44B8A009601A2
+7913:000003FEFC0011FC112421FC3D2467FE6400A5FC252425FC3D2425FC200003FE
+7914:001003C8FA7E2240226243D47A004A3ECBC84A484E7E4A487A484BC802480008
+7915:3E1022FE3E4420287EFEA2103EFC22100000FFFE08001FF82808C8080FF80808
+7916:0140024CFA642244234C42647AA44BACCAA44AA44FFE48007910490802040404
+7917:00400020FBFE220221FC41487A5049FCCB0449FC490449FC790449FC00880104
+7918:000003FEFA0223FE220243FE79084A52CB9C49084A524BDE78004AA402520452
+7919:020002BEFB02225421C8403E7A0A4BCACD2849284FEE49287AA84A58044E0080
+791A:008803FEF888202021FC40207BFE4840C88849FC480049FC7954495407FE0000
+791B:000803E8FA8823EE222843F47A824BE2C80049FC495449547954495407FE0000
+791C:0A0033B822083BB820883AB82288FFFE10103FF8C4060FF0181068100FF00810
+791D:000001FCFC2013FE122221AC3C2065AC6400A7FE242025FC3D5425542154010C
+791E:008803FEF88823FE220241FC78004BFEC84048A24B5448B87B54489203500020
+791F:000007C4F51427C8250847D47514D50057D450545554554875485454005401A2
+7920:01080090FBFE2108210842527B9C4908CA524BDE484048A47AAA4A8A04780000
+7921:008803FEFC88102413FE20203DFC652465FCA52425FC25243C0825FE20880058
+7922:01080090FBFC204021F840807BFC4948C9FC4B0A4DF8490879FA4934018C0102
+7923:004801FEFC48100011FE214A3D4A65FE6414A5FE251025923D4C254A21160222
+7924:00880088FBFE2088211041DE7A524D54CA8849744A0249FC7820492402220060
+7925:07DE0512F7D2245427C8451477E2D00053FC520453FC520473FC520403FC0108
+7926:00200010FBFE224422FE42447BFE4A10CAFE4A924AFE4A927AFE4A0002440482
+7927:000001FCF92421FC212441FC79044800CBFE4AAA4AAA4BFE7AAA4AAA03FE0222
+7928:00001FF011101FF011103FF82AA83EF82AA83EF800007FFC08001FF868080FF8
+7929:0042039CFA1023DE229442947C204BFCCA044BFC4A044BFC7A044BFC01080204
+792A:000001FEFD2811FE1128217C3D54657C6554A57C251025FE3D9222BA028A0484
+792B:01240174FA5822DA23FE41547ADA4BFEC8A248204BFE487078A8492402220020
+792C:22882108FABE2008729CA92A2288FFFE08203FF8C4060FF0181068100FF00810
+792D:01FC0020FBFE222225AC402079AC4890C9FE4B204DFC492079FC492001FE0100
+792E:001007C8F53E27C0251447D27522D50057D450545554554875485454005401A2
+792F:008802AAFADC2488215442227BFE4A42C88849F048244BFE7822492402A20040
+7930:000007FEF4442598248847DE7488D5DC56AA54885420542074BC54A004A00BFE
+7931:08407F7C1440FF7C22043E7C22403E7C2242263E00007FFC08001FF868080FF8
+7932:01100090FBDE2010225E41827BDE4810CBDE4A504BDE4A507BDE4A50025202CE
+7933:00400020FBFE224823FE42487AEC4B5ACA484BFE4A204A7C7AC44B44047C0844
+7934:008803FEF088241222FE401074FED29252FE509251FE5292760452FE0244022C
+7935:01FC0020FBFE222221AC402079AC4800C89E4BF2489E49D27ABE4C92009E0092
+7936:008803FEF88823DE225243DE78A04890C9FE49204BFC4D2079FC492001FE0100
+7937:009007FEF89023E8228843CE7A504BD4CAA24BE248004BFC7A944A9407FE0000
+7938:052807BEF94827BE231845AA79464BFCCA044BFC4A044BFC7A044BFC01080204
+7939:07BC04A4F7BC200027FE44007590D49E57D4556455D4555475D455680BC81054
+793A:00003FF80000000000000000FFFE010001001110110821044102810205000200
+793B:200010001000F800080010001000380054009400100010001000100010001000
+793C:208010801080F8800880108010803880548094801080108410841084107C1000
+793D:2000100013F8F8880890109010A038BC54849484110411041104120412281410
+793E:202010201020F8200820102013FE382054209420102010201020102017FE1000
+793F:204010401080F8FC090412041004390454849444104410041004100410281010
+7940:2000100011FCF90409041104110439FC55049500110011021102110210FE1000
+7941:200010FC1084FC8804880890108838885484928410C410A81090108010801080
+7942:202010201020F920092C113411643BA455249534112811221122110210FE1000
+7943:200013F01010F81009101110111039FC54049404100413F41004100410281010
+7944:202010201050F850088811041202388854889488108810881088110811081208
+7945:2008103C11E0F8200820102013FE382054209450105010501088108811041202
+7946:2000100011FCF8200820102010203BFE54209420105010501088108811041202
+7947:2004101E11F0F91009101110111039FE5510951011101108110A114A11861102
+7948:2008101C11E0F9000900110011FE391055109510111011101110121012101410
+7949:202010201020F92009201120113C392055209520112011201120112017FE1000
+794A:204010201020FBFE08801080108038FC54849484108410841104110412281410
+794B:200010F81088F88808881106120039FC54849484104810501020105010881306
+794C:202010201020F82009FC112411243924552495FC112410201020102010201020
+794D:2008103C11E0F8200820102010203BFE54209420102010201020102011FC1000
+794E:202010201020FBFE0820102019FE3420502093FE10221022102A102410201020
+794F:2000100013FEF82008201040184034FC51849284148410841084108410FC1084
+7950:202010201020F8200BFE10401040388054FC9184128410841084108410FC1084
+7951:202010201120F92009FC11201220382057FE9420105010501088108811041202
+7952:200013FC1084F8840884110411143A08540095FC110411041104110411FC1104
+7953:205010481048F8400BFE1080108038FC55449544112811281210122814441182
+7954:208810881088F908097E13081508394855289528110811081108110811281110
+7955:200010401020F8280808108810903A9456A292A214C210881188128814781000
+7956:200011F81108F908090811F811083908550895F8110811081108110817FE1000
+7957:4008203C23E0FA2012201220222033FE6A20AA1022102212220A228A23262212
+7958:00003E7C0000000000007EFE081008102A542952495288900810081028501020
+7959:202010201020F9FC0820102010203BFE547094A810A811241124122210201020
+795A:208010801080F8FE094011401240387C544094401040107E1040104010401040
+795B:202010201020F9FC0820102010203BFE5420942010401048108411FE10821000
+795C:202010201020F8200BFE10201020382055FC9504110411041104110411FC1104
+795D:200013FC1204FA040A04120413FC3890549094901090111211121212140E1800
+795E:202010201020F9FC09241124112439FC55249524112411FC1124102010201020
+795F:0100111011101FF0410441047FFC00003FF80000FFFE01001110210845040200
+7960:200011FC1004F8040BF41004100439E455249524112411E41004100410141008
+7961:088008882E9028E028842E84F07C00003FF80000FFFE01001110210845040200
+7962:208010801080F8FE090211041220382054A894A4112411221222102010A01040
+7963:2080108010FEF9000A00101C11E0392055229524112811101110114811841102
+7964:200013DE1042F8420A52114A114A384254C6914A1252104210421042114A1084
+7965:210410841088F8000BFE1020102039FC5420902013FE10201020102010201020
+7966:200011FC1104F90409FC1000100039FC5420902013FE10201050108811041202
+7967:209010901090FA9209941098189035985294949210901090111211121212140E
+7968:00007FFC04403FF8244824483FF800003FF80000FFFE01001110210845040200
+7969:202011201120F9FC0920122010203BFE547094A810A811241124122210201020
+796A:2040104010FCF9040A0811FE1100397C554495441154114811421242123E1400
+796B:202010201050F8880904120211FC3800540095FC110411041104110411FC1104
+796C:200013FE1020F8400888110413FE38225420902013FE10201020102017FE1000
+796D:108010803EFC624494484830301027C8C00600001FF001000920111025080200
+796E:202010201020FBFE0820102011FC3800540095FC110411041104110411FC1104
+796F:20201020103EF820082011FC1104392455249524112411241050104810841104
+7970:202011201120F9FC0920122010203BFE5400940011FC11041104110411FC1104
+7971:210410841088F81009FC11041104390455FC94501050109010921112120E1400
+7972:200011FC1004F8FC080411FC10003BFE560291F8108810881050102010D81306
+7973:200013FC1200FA000AF8120012003BFC56A092A412A812901290148814A418C2
+7974:201010141012F8100BFE10101150395457F4955411541148124A125A14261042
+7975:400023FE2222FA22122213FE222232626A72AAAA232222222222220223FE2202
+7976:410820882090FBFC1024102423FC32206A20ABFE206220A2212A222424202020
+7977:2020102013FEF82009FC104013FE3848548894FE110811481228140810281010
+7978:200011FC1104F904090411FC1820342053FE92221252128A130A1202120A1204
+7979:2080108010FEF9020A8210F21142384257FA94421152115211F2100210141008
+797A:2108110813FCF908090811F81108390855F89508110817FE1000109011081204
+797B:200011FC1104F924092411FC1124392455749554115411741104110411FC1104
+797C:200011FC1124F92409FC1124192435FC502093FE107010A81124122210201020
+797D:2040102013FEF8000888108811543A225400902013FE10201020102010201020
+797E:2020102011FCF820082013FE18883544524290F8118812501020105011881606
+797F:208010F81088F90809F01010181037FE50209222117410A81124122210A01040
+7980:0100FFFE00003FF8200827C8244827C820083FF800003FF80000FFFE11102308
+7981:082008207EFC08201C702AA8C82600003FF800000000FFFE0100111025084204
+7982:200011FC1124F9240974112411FC390455749554115411741104120412141408
+7983:4040204027FCF840104013F8220833F86A08ABF8220823F8220822082FFE2000
+7984:400021F82008F80811F81008200833FE6820AA22217420A82124222220A02040
+7985:210410881050F9FC0924112411FC3924552495FC1020102013FE102010201020
+7986:2040108013FCFA240A2413FC1A24364453FC9090111017FE1010101010101010
+7987:2040104413F4F848085017FE1040388055F89308150811F81108110811F81108
+7988:200013FE1222F8200BFE102011FC392455FC952411FC102013FE102010201020
+7989:208810481050FBFE0850105011FC39545554958C110411FC1104110411FC1104
+798A:4100213C27D4F9141394111427D43124694CA84027FE204020A0211022082C06
+798B:200013FE1050F85009FC11541154395455FC9420102011FC1020102013FE1000
+798C:408420442048FBFE108410842108314A6A52AB9C208421082108225223DE2042
+798D:200011FC1104F90409E4112411243BFE560292FA128A128A12FA1202120A1204
+798E:20201020103EF820082011FC110439FC550495FC110411FC1000108811041202
+798F:400023FE2000F9FC1104110421FC30006BFEAA22222223FE2222222223FE2202
+7990:203C17C01244F928080013FC1080388057FE950011F812881250142018D81306
+7991:21FC11241124F9FC0924112419FC3420502093FE1222122A12FA120A12021206
+7992:210011F81208FBF0081017FE10803944566894B01128166810A4112216A01040
+7993:200011F81108F9F8090811F810003BFE550095FC125414941124124410A81110
+7994:200011FC1104F90409FC1104190435FC500093FE10201120113C112012A0147E
+7995:2040104011FCF8840BFE100011FC390455FC902013FE1020122013FE10201020
+7996:2088108813FEF888088810F81088388854F8902013FE107010A8112412221020
+7997:200011FC1124F92409FC1124112439FC54009440102412A2128A148810781000
+7998:2040102011FCF8000888105013FE3A22542495FC112411241134112810201020
+7999:2050105213DCF85008D2134E100039FC550495FC110411FC1104110411141108
+799A:210410841088F8000BFE1020182035FC5020902013FE100012A4125214521000
+799B:2020102013FEF82009FC110411FC390455FC950411FC110413FE108811041202
+799C:08202AA44D28145022887FFE400280043FF80000FFFE01001110210845040200
+799D:200011FC1124F9FC092411FC18883544524290F8118812501020105011881606
+799E:2040102013FEF80009FC110419FC340053FE920212FA128A12FA1202120A1204
+799F:2020101011FEF910097C111411FE3914557C9510117C114411441244127C1444
+79A0:4004201E23F0FA1E121012FE229232986AF2AA8E228022B822A824AA254A2A86
+79A1:200011FE1120F9FC092011FC1120392055FE900212AA12AA12AA120210141008
+79A2:200011FC1104F9FC090411FC1800340053DE90421252114A12521042114A1084
+79A3:2028102413FEF82009FC112411FC392455FC9524100813FE1088104810481018
+79A4:200013FE1252FA520BFE100013DE38425652954A10C6135A10421042114A1084
+79A5:2088108813FEF88808F8108810F8388857FE9488112412FA1020102013FE1000
+79A6:020027DE491297D2211265DAA5142FD000003FF80000FFFE0100111025080200
+79A7:404027FC2040FBF8100013F8220833F86910AFFE200023F82208220823F82208
+79A8:4124212422AAFBAE112412AA23AE31246FFEA91021142114228A224A22162422
+79A9:400023FE2222FBFE122213FE208830886BFEA888208827FE2000208821042202
+79AA:200013DE1252FA520BDE100011FC392455FC952411FC102013FE102010201020
+79AB:200013FE1050FBFE0A5213FE100039FC550495FC110411FC102013FE10201020
+79AC:202010501088F9740A0211FC112439AC552495FC100010F8108810F8108810F8
+79AD:408824482250F8FC10201050269432386A50AA98223422542290222025FE2800
+79AE:409023FC2294FBFC129413FC200033FC6800ABFC220423FC2108209027FE2000
+79AF:409023FC2294FBFC129413FC200033FC6A00AAF8220023FE2520251425482986
+79B0:400023FE2124FA2217FE1222237632AA6B76AA22237622AA23762222222A2204
+79B1:404027FC2040FBFC100017FE200233F86840AFFE200027FE200827FE24A82798
+79B2:200013FE1248FBFE0A4812FC12A43AFC56A492FC122013FE132A157A150A1906
+79B3:202013FE1000F9DC095411DC188837FE508893FE108817FE1094118816A410C2
+79B4:404020A021100208F5F610002EEE2AAA6EEEB0002FFE29222FFE2922292A2804
+79B5:400023BE2288FB9012BE13A2203E37E2693EA92225BE2514252225002BFE3000
+79B6:452827BE2948FFBE131815AA294633FC6A04ABFC220423FC220423FC21082204
+79B7:4100255E2384F90817DE11122392355E6912A81E21522FF2211E2280244C2812
+79B8:0100010001007FFC420442044404444448245FF4481440044004400440144008
+79B9:001000F83F0001001FF0111011101FF001007FFC410441245FF448144004400C
+79BA:00003FF8210821083FF8210821083FF801007FFC410441245FE4482440144008
+79BB:02000100FFFE00001450139014501FF001007FFC420444444FE4442440144008
+79BC:010001FC01001FF01450139014501FF001007FFC420444444FE4442440144008
+79BD:010002800C603118CFE60440139014501FF001007FFC420444444FE44424400C
+79BE:001000F83F000100010001007FFC038005400540092011102108C10601000100
+79BF:00701F80010001007FFC054009203118C006044004400440044008421042603E
+79C0:00701F80010001007FFC054009203118CFE60420044004780808080810506020
+79C1:04200E20782008200820FF40084018401C402A482A84488489FE088208020800
+79C2:00F83F0001000100FFFE0540092011102008C10401000280044008203018C006
+79C3:00701F80010001007FFC054009203118C0060FC00840084008441044203C4000
+79C4:04000EFC780408080810FF20082019FE1C202A202A2048208820082008A00840
+79C5:08081C3CF3C010401040FC401040307E3BC054405040904210421042103E1000
+79C6:08001DFCF02010201020FC20102033FE38205420542090201020102010201020
+79C7:08401C40F040104011F8FC4810483048394854C8544890A810AA110A12061402
+79C8:08201C20F02010201124FD24112431243924552455249124112411FC10041000
+79C9:00F83F0001007FFC01003FF80108FFFE01083FF80380054009203118C1060100
+79CA:00701F80010001007FFC054009203118C0E61F00010001007FFC010001000100
+79CB:08401C40F04010401144FD4411483250384054A054A090901110110812041402
+79CC:103811C010401440584053FC504090E010E0115011502A482444484240408040
+79CD:08201C20F020102011FCFD2411243124392455FC552490201020102010201020
+79CE:08101C90F09010881108FD04120435FA38885488548890881108110812281410
+79CF:08081C3CF1E010201020FC3C11E038203420503E53E09020102210221022101E
+79D0:08001C00F1FC10001000FC0013FE30203820544054409088110413FE11021000
+79D1:08101D10F09010901010FD10109038903410501E53F090101010101010101010
+79D2:08201C20F02010A810A4FCA2112231203A245424542890081010102010C01300
+79D3:08201C20F02013FE1020FC20102031FC38845488544890501020105011881606
+79D4:08801C40F04013FC1000FC0011F03110391055105510911211121212120E1400
+79D5:08101D10F11011121112FD1411D83110391055105510911211521192110E1000
+79D6:08041C1EF1F011101110FD10111031FE3910551055109108110A114A11861102
+79D7:08081C3CF1E010201020FC2013FE302038205450545090501088108811041202
+79D8:08001C40F02010281008FC8810903A9436A252A254C290881188128814781000
+79D9:08201C20F020102013FEFC201020302039FC5504550491041104110411FC1104
+79DA:08201C20F12410A410A8FC2011FC38203420502053FE90201020102010201020
+79DB:08101C10F01011FE1112FD14111031FC39445544552891281110122812441482
+79DC:08001DFCF10411041104FDFC11003140394455485570914011421242123E1400
+79DD:08381DE0F02010201020FDFC10203070387054A854A891241124122210201020
+79DE:08201C20F020102011FCFD2411243124392455FC552491241124112411FC1104
+79DF:08001DF8F10811081108FDF811083108390855F8550891081108110817FE1000
+79E0:08001DFEF01010101020FC20106838A435225222502090201020100013FE1000
+79E1:08501C48F048104013FEFC80108030FC39445544552891281210122814441182
+79E2:08201C20F05010501088FD241212301039FC5404540890881050102010101010
+79E3:08201C20F02013FE1020FC20102031FC387054A854A891241124122210201020
+79E4:08001DFCF02010201124FCA410A830203BFE5420542090201020102010201020
+79E5:08201C20F0201020103EFC201020302039FC5504550491041104110411FC1104
+79E6:01007FFC01003FF80200FFFE082010D02F08C1061FF005400920111061080100
+79E7:08201C20F02011FC1124FD2411243124392457FE542090501050108811041202
+79E8:08801C80F08010FE1140FD401240307C384054405440907C1040104010401040
+79E9:08201C20F120112011FCFD201220302039FE5420545090501088108811041202
+79EA:08041C1EF1F011101110FD10111031FE3910551055109108110A114A11A61112
+79EB:08401C50F048104017FCFC4010E038E035505150524894441842104010401040
+79EC:08001DFEF10011001100FDFC110431043904550455FC91001100110011FE1000
+79ED:08201C20F02E11F01120FD20112039FE3422546250A2912A1624102010201020
+79EE:08201C20F04010401088FD0413FE3002380055FC550491041104110411FC1104
+79EF:04000E0078FC08840884FF84088418841CFC2A842A0048488844088408820902
+79F0:08801C80F08010FE1102FD041220302038A854A4512491221222102010A01040
+79F1:08001DFEF1021102117AFD021102317A394A554A554A917A11021102110A1104
+79F2:08201C20F02011FC1020FC2013FE3008380855FE540890881048100810281010
+79F3:08081C3CF1E010201020FDFE10203020382055FC550491041104110411FC1104
+79F4:08201C20F05010881104FE0211FC3000380055FC550491041104110411FC1104
+79F5:08001DFCF10411241124FD2411FC312439245554554C918C1104110411FC1104
+79F6:0100410021FC0A441448E0A02110260800E01F0001007FFC05401930E10E0100
+79F7:08001DFEF02010401088FD0411FE30223820542055FE90201020102013FE1000
+79F8:08201C20F02013FE1020FC2011FC3000380055FC550491041104110411FC1104
+79F9:00801888709C11701110FB101510311039FE55105110911011101110117C1100
+79FA:08401C20F3FE12021000FC3813C038403440507C53C0904010421042103E1000
+79FB:08201C20F07C10841148FC30102030483990543E544291A41018101010601180
+79FC:08201D20F12011FC1120FE20102033FE387054A850A891241124122210201020
+79FD:08201D24F124112411FCFC40104038FC35045284504890501020104010801300
+79FE:08201C20F02013FE1242FC4410A038A235A4529854909088108410A210C01080
+79FF:08281C24F3FE10201020FDFC1124312439FC5524552491FC112411241124110C
+7A00:09841C68F03010C81304FC4013FE38A0352053FC552491241134112810201020
+7A01:01007FFC00001FF010101FF000007FFE400280741F800100FFFE05401930E10E
+7A02:08401C20F1FC11041104FDFC1104310439FC5520552291141108114411821100
+7A03:08041C1EF1E010021122FC94100039FC3408501053FE90101010101010501020
+7A04:08401C40F088110413FEFC02108831443A4254F8518892501020105011881606
+7A05:08101C90F08811081204FDFA11083108390855F854909090109011121212140E
+7A06:08001CFCF08410841084FC8410FC3800340055FE510291021102110211FE1102
+7A07:08001DFCF12411241124FDFC11243164397455AC552491241124110411FC1104
+7A08:08001DFCF10411FC1104FDFC1000380035FC5420502093FE1020102010201020
+7A09:08001DFEF020102011FCFD24112431FC3924552455FC912010A0104010B0130E
+7A0A:09081C88F09011FC1024FC2411FC3120392055FE546290A2112A122414201020
+7A0B:00000DFCF10411041104FDFC1000380035FC5420502091FC10201020102017FE
+7A0C:08201C20F05010881104FEFA102030203BFE5420552891241222142210A01040
+7A0D:08201D24F0A410A81020FDFC1104310439FC5504550491FC1104110411141108
+7A0E:09041C84F088101011FCFD041104310439FC54505450909010921112120E1400
+7A0F:08001DFEF04810481048FDCE11023102390255CE504890481048104813FE1000
+7A10:08201C20F05010881104FEFA100031FC3954555455FC9154115411541104110C
+7A11:08201C20F1FC10201020FDFE108831043A22542051FC90201020102013FE1000
+7A12:08001DFCF10411241124FDFC1124312439745554555491741104110411FC1104
+7A13:08881C88F08813FE1088FC8817FE300039FC5504550491FC1104110411FC1104
+7A14:08201C20F05010881144FE2211F838083450542050A49282128A128A14781000
+7A15:08401C20F3FE100011FCFD0411FC380035FC5408501093FE1020102010A01040
+7A16:08801C40F1FC10001108FC88109033FE3800540055FC91041104110411FC1104
+7A17:08401C80F1FC11241124FDFC1124394435FC5490511093FE1010101010101010
+7A18:08881C88F3FE10881088FCF81088388834F85488508893FE1000108811041202
+7A19:08201C20F3FE10201020FDFC110431FC390455FC550491FC1104110417FE1000
+7A1A:08A01C90F09011FE1110FF1015FE3110391055FE55109110111011FE11001100
+7A1B:10003BFEE202221A22E2FA22222233FE6A226272A2AA23262222222223FE2202
+7A1C:10203820E1FC20202020FBFE208831446A4260F8A18822502020205021882606
+7A1D:10003BDEE25222522252FBDE225232526A5263DEA252225222522252255228A6
+7A1E:08001DFCF124112411FCFD24112431FC382057FE547090A81124122210201020
+7A1F:0100FFFE00003FF8200827C8244827C820083FF800001FF00100FFFE0920711C
+7A20:08001DFCF12411241174FD2411FC310439745554555491741104120412141408
+7A21:08401C20F3FE10001088FC88115432223800542053FE90201020102010201020
+7A22:10143812E01027FE2010F81023D232526A526254A3D4200820EA271A22262042
+7A23:2008203C7DE0442088207C2055FE54207C70546854A87CA401221C20E0204020
+7A24:08401C20F3FE10001000FDFC1104310439FC5420552891241222142210A01040
+7A25:00701F8001007FFC054009203118C006149022481FF010101FF010101FF01010
+7A26:08401C40F1FC108413FEFC0011FC390435FC502053FE9020122013FE10201020
+7A27:08801C9EF3EA108A11CAFC8A13EA389234A6502053FE90201050108811041602
+7A28:08401C20F1FE11021102FDFE1100390035FE55AA51AA92FE12AA12AA14A21086
+7A29:08001DFEF12211FE1122FDFE100030FC388454FC548490FC1084108410941088
+7A2A:09001D00F1FE120015FCFD0411FC310439FC548054FC91081290106011981606
+7A2B:08001DFEF00010FC1084FC8410FC300039FE5522552291FE1122112211FE1102
+7A2C:08001DFCF020104011FCFD54115439543544552C502093FE1050108811041202
+7A2D:09101D12F1D411181152FD92112E304039FC5504550491FC1104110411FC1104
+7A2E:08081C3CF1E0102013FEFC2011FC312439FC552455FC902011FC102013FE1000
+7A2F:08001C88F25212221252FE8A12023BFE34885144527A90881150102010D81706
+7A30:08001DFEF0121090109CFC90117E320038FC548450FC908410FC108410941088
+7A31:081E1DE0F04411241088FC2011FC3924352455FC5124912413FE110411141108
+7A32:08041C1EF1E010221112FC941080313E39225522553E912211221122113E1122
+7A33:08401CF8F108121011FCFC04100439FC3404540451FC9040102412A2128A1478
+7A34:08881C50F00011FE1050FDFC105433FE385455FC545090D81154125210501050
+7A35:08841C44F04813FE1084FC841108314A3A52579C508491081108125213DE1042
+7A36:08141C12F01013FE1014FC18139032B43A98569053B2900C10CA171A10661002
+7A37:08001DFCF12411FC1124FDFC108831443A4254F8518892501020105011881606
+7A38:08401C20F3FE10401088FDF01020304439FE540255FC912411FC112411FC1104
+7A39:08201C20F3FE102011FCFD0411FC390435FC550451FC910417FE108811041202
+7A3A:10003BFCE204220423FCFA40222033FC6A886250A3FE222025FC242028202020
+7A3B:081E1DE0F02211121094FC80102031CE3902550255CE91021102110211FE1102
+7A3C:08401C20F3FE12021000FDFC104030A23B345458509493341052109013501020
+7A3D:08501C48F3FC10A01122FE1E111031E0390454FC540091FC110411FC110411FC
+7A3E:01007FFC08200FE000007FFC48244FE440045FEC01007FFC05401930E10E0100
+7A3F:08401C20F3FE100011FCFD0411FC380037FE520252FA928A12FA1202120A1204
+7A40:1000FE7810487C480048FE8682007CFC00447C441028FE283810542892441182
+7A41:08881C88F1FE10881000FDFE1088308838F8548854F89088109E11E810081008
+7A42:08201C20F3FE102011FCFD2411FC392435FC5440502492A2128A148810781000
+7A43:08401C20F3FE12021050FC88112430503888550452FA90881088108810F81088
+7A44:11003910E3DC22542554FA88210832F46C026000A3FC20402150224825442080
+7A45:08201C10F1FE1110117CFD1411FE3914357C5510519291541138125412921430
+7A46:08201C40F1FC110411FCFD0411FC38203524563250C093181060118C103013C0
+7A47:10403888E1FC21082252FBFE205031886E2660C0A31020642388203020C02700
+7A48:010000803FFE22102F7C26382B543292203827C020402FFE215042484C468040
+7A49:08001DFEF10211FE1110FD541138395435825550517C9190111012FE12101410
+7A4A:1000E7BE2488248827A8FCA824A837BE6C106518A49825A826AA244A20462080
+7A4B:10003BDEE0422252214AFA52202830C46B126060A188203221C4201820602380
+7A4C:2008203C79E0482090207C2055FE54207C70546854A87CA40122AA20AA200020
+7A4D:08201DFEF02011FC1020FDFE100031FC390455FC550491FC110411FC10881104
+7A4E:40004CFE7010442044FC3C8400840CFC708410FCFE84108438FC544890841102
+7A4F:08081C3CF1C010441124FCA811FC300438FC540455FC904010A412AA128A1478
+7A50:1100E1F0222027F82A48FBF8224833F8684067FCA44427FC244427FE2042203E
+7A51:08201C20F3FE10201124FCA813FE300039FC5504557491541174110411FC1104
+7A52:00701F800100FFFE05401930E20E1FF010101FF010101FFC10001FFC0004492C
+7A53:10003BFEE22223FE2222FBFE208830886BFE6088A08827FE2000208821042202
+7A54:0088188871FC10881088FBFE102031FC392455FC512491FC1000108811041202
+7A55:08A01C90F1FE132011FCFD2011FC392035FE5500502093FE107010A813261020
+7A56:0124192472AA13AE1124FAAA13AE31243BFE551051149114128A124A12161422
+7A57:08201C20F3FE102011FCFD2411FC392435FC502253FE9042102412A2128A1478
+7A58:08201C20F1FC102013FEFD08139C31083988563E500093FE109010901112120E
+7A59:08501E52F154105013FEFC88105033FE382055FC502093FE1050108811041602
+7A5A:08181DE0F04013FE1088FD7412523070380055FC55049174115411741104110C
+7A5B:08901C88F1FE11101310FDFE1110391035FE5510511091FE110012A412521452
+7A5C:08201DFCF088105013FEFC0011FC312439FC552455FC902011FC102013FE1000
+7A5D:100039F8E10821F82108F9F8200037FE6A4063DCA25423D4226827C820542062
+7A5E:08801CF8F11013FC1524FDFC112431FC380057FE540091FC110411FC110411FC
+7A5F:1088E448225020FC2020F850269432386A506298A23422542290222025FE2800
+7A60:08501DFCF15411FC1154FDFC100031FE3900557C550091FE1150115411481266
+7A61:0020182073FE11241124FAAA17FE300039FC5504517491541174110411FC1104
+7A62:08201D3CF12017FE1010FC1413FE32103BF05654525492D41368144A18961322
+7A63:10803840E7FE21102208FD1423F831106BF86110A7FC212823102D4821862100
+7A64:08001DFCF02013FE1222FDAC102031AC380057FE502091FC115411541154110C
+7A65:11403A4CE2642244234CFA6422A433AC6AA462A4A7FE20002110210822042404
+7A66:08401C20F3FE120211FCFD48125039FC370455FC510491FC110411FC10881104
+7A67:10803840E7FC211020A4FF58255435526B586000A20823F8220823F822082408
+7A68:0C2071FC1124FDFC10203BFE540091FC010439FC290429FC29044DFC48888104
+7A69:103EE7C02244212823F8F84027FC30006BF86008A3F8200823F82544252A28FA
+7A6A:10003BFEE124222227FEFA22237632AA6B766222A37622AA23762222222A2204
+7A6B:00881BFE70A8109011FEFB2011FC312039FC552051FE910013FC10881070138E
+7A6C:10403820E7FE248825FCFC8827FE34206DFC6524A5FC252425FC240024882904
+7A6D:08801DF8F20815FC1124FDFC112431FC3954562A55FC910411FC110411FC1104
+7A6E:08401C20F3FE125013FEFE5213FE32003A9456D8529092D2128E140015541A2A
+7A6F:00201BFE702013AE12AAFBAE102033FE380057FE520292FA128A12FA120213FE
+7A70:1040E7FC200023B822A8FBB8211037FC691067FCA1102FFE212823102D482186
+7A71:001E1BE07122109413FEFA5213FE30043BC4567E53C4925413CC128412D41348
+7A72:13DE3800E3DE2252235AFA52202033FE6A5063FEA25223FE229222DC229224CE
+7A73:1528E7BE294827BE2318FDAA294633FC6A0463FCA20423FC220423FC21082204
+7A74:0200010001007FFE400280440440044004200820082010101010200840048002
+7A75:020001007FFE40028824101020081FE000C0030004000800100810080FF80000
+7A76:020001007FFE400288241210220802003FE002200420042008221022201E4000
+7A77:020001007FFE400288241010220802007FF00210041004100810101020A04040
+7A78:020001007FFE400288241010220804000FF0101068200440028003001C00E000
+7A79:020001007FFE482290142FF8001000101FF0100020003FF80008000800500020
+7A7A:020001007FFE400288241010200800001FF0010001000100010001007FFC0000
+7A7B:020001007FFE4002882410102FE80100010001007FFC01000100010005000200
+7A7C:020001007FFE400288241010210801007FFC0540092011102108C10601000100
+7A7D:020001007FFE48229014282808203FF8082008200820FFFE0820102010202020
+7A7E:020001007FFE48229014200800F03F0001000100FFFE0280044008203018C006
+7A7F:020001007FFE4822901400003FFC0040104020403FFE01400640184061400080
+7A80:020001007FFE482291142108FFFE01002108210821083FF8010A0102010200FE
+7A81:020001007FFE4002882411102148012001007FFC01000280044008203018C006
+7A82:020001007FFE48229014210811001FF8210041000100FFFE0100010001000100
+7A83:020001007FFE48229014200021FC2C44F0442044204424842884310422280410
+7A84:020001007FFE4822901428080FF81400240047F00400040007F8040004000400
+7A85:020001007FFE4822901420081FF0101010101FF010101FF0101010101FF01010
+7A86:020001007FFE4822901401F03E00020001007FF8006001800E003000480087FE
+7A87:020001007FFE4822901408001FF020105F90109010901F901050102410040FFC
+7A88:020001007FFE482290140840084012F822487C480848144822887E8821280210
+7A89:020001007FFE4822901420081FF0010001003FF8210822882448280820282010
+7A8A:020001007FFE4822901420781FA012201220122012101290224822A843248202
+7A8B:020001007FFE4822901421081110111011101FF001002108210821083FF80008
+7A8C:020001007FFE4822901420080C0070FC4084448444845C846494488808801080
+7A8D:020001007FFE48229014200800007DFE1040108011FC10041E04E00440280010
+7A8E:020001007FFE4822911422081FF010101210115010201FFC000400047FD40008
+7A8F:020001007FFE48229014100009FC4820202020200BFE10207020102010A01040
+7A90:020001007FFE4822901401003FF801000100FFFE000001003FF801000100FFFE
+7A91:020001007FFE48229014200808001FF821000100FFFE0100210821083FF80008
+7A92:020001007FFE4822901400007FFC040008201FF0011001003FF801000100FFFE
+7A93:020001007FFE482292142408082010103FF80008010008844892481287F00000
+7A94:020001007FFE4822921401007FFC08201010244844440280010006C01830E00E
+7A95:020001007FFE4822901404404448245024600C403460C852084A1042203E4000
+7A96:020001007FFE4822911409000FF011000100FFFE00001FF0101010101FF01010
+7A97:020001007FFE4822921404003FF8220823C824482A882108228824083FF82008
+7A98:020001007FFE482290143FF80408FFFE04083FF808001FF8280848088FF80808
+7A99:020001007FFE4822911C0FD00120FFFE01001FF0082030C0CFFC008002800100
+7A9A:020001007FFE4822909400883FFC208020883E88225022502A244454418C8604
+7A9B:020001007FFE4822901420083E2001FE00247E4414E81410146A2586240243FE
+7A9C:020001007FFE4822911401003FF821083FF801007FFC41047FFC410401000100
+7A9D:020001007FFE482290142FE8082008200FE001003FF821082288244820082018
+7A9E:020001007FFE4822941427E8082010402678180810081E78100810081FF81008
+7A9F:020001007FFE482290143FF820083FF820802490249027F02080488848888FF8
+7AA0:020001007FFE482290143FF811101FF011101FF00100FFFE054009203118C106
+7AA1:01007FFE482290143EF8020814D00820145062883EF80288145008203458C286
+7AA2:020001007FFE4822901400500048FFFE00403E4022243E2800120E2A70C60302
+7AA3:020001007FFE4822921401007FFC0820145022880100FFFE0100010001000100
+7AA4:020001007FFE482290143FF810081FF810081FF82080208C3EF020822682387E
+7AA5:020001007FFE48229014000011FC7D0411241124FD241154285024904112860E
+7AA6:020001007FFE482291142FE801007FFC048412880900FFFE0260041018086004
+7AA7:020001007FFE4822911401FC01003FF820083FF820083FF80100FFFE01000100
+7AA8:020001007FFE4A2291143FF808200440FFFE00001FF010101FF010101FF01010
+7AA9:020001007FFE482290143FF810101F9010907FFC40044FE448244FE44004400C
+7AAA:020001007FFE48229014004023F81040804047FC10002040E3F82040204027FC
+7AAB:01007FFE4822901408007F7C08243E2408447F5408880200FFFE04401830E00E
+7AAC:020001007FFE492292940C6037D8C0063E0822483E4822483E48220822282610
+7AAD:020001007FFE4822911409207FFC05401930610C0400FFFE08201E4003C03C38
+7AAE:01007FFE4822901408003F7C21043F04217C3F4021407F7C05041904E5280210
+7AAF:020001007FFE48229014244802803FF801001FF001007FFC0000248822444244
+7AB0:01007FFE4822901401F87E002208111020003FF841000100FFFE010021083FF8
+7AB1:020001007FFE4822909411F822886870ABAE282029FC282028A8292422A42040
+7AB2:020001007FFE48229014080049482A280808FF48182E2CF84A08880808080808
+7AB3:020001007FFE48229014061C38E828A82CA82AA82AA82AA828A455545D748212
+7AB4:01007FFE4822901401007FFC01001FF010101FF010101FF01010FFFE10102008
+7AB5:01007FFE482294141FF010101FF010101FF010001FFC10001FFC492484940008
+7AB6:01007FFE482291143FF82108FFFE21083FF811101FF00400FFFE082007C07838
+7AB7:01007FFE482290140040FD9E4952495279524952795249DA5D54E89008900910
+7AB8:01007FFE4822901400F83F0011100920FFFE09203118C20609002908282447E4
+7AB9:01007FFE4822901405FC242024F83C48044805FE7C0024FC2484248444FC8484
+7ABA:020001007FFE48229014000011F87D0811F81108FDF8110829F824904112860E
+7ABB:01007FFE4822911402003FF8220827E82A48218826483FF801004884481287F2
+7ABC:01007FFE48229114222011101FF011101FF011101FF001007FFC05401930E10E
+7ABD:020001007FFE4822901422203C20213E1F4220943F104810FFA8142822444182
+7ABE:01007FFE4822901408207F20083E3E4200943E1000107F1008282A2849441882
+7ABF:01007FFE4822911479F04A9050606198560649F04A406BF8544043F8404047FC
+7AC0:020001007FFE4822901401F8FD0811F8110851F85D0851F850905C90F112060E
+7AC1:01007FFE4822901401F03E0003F03E0003FA7E0201FE0C20703C1DE2F0221C1E
+7AC2:01007FFE482291147FFC044028281FF02828CFE608200FE00100111025080200
+7AC3:01007FFE492297D401007FFC11101FF011103FF821083FF821083FFA010200FE
+7AC4:01007FFE4822961438F820083CF820083FF80000294825282948252A29463182
+7AC5:01007FFE482290143E2022203E3E22443EA408247F2810281E1022282A444482
+7AC6:01007FFE4822901408003E7C22443E44227C3E0022FEFE8212822282CAFE0482
+7AC7:01007FFE492297D401003FF824483FF810101FF010101FF010101FF008201010
+7AC8:01007FFE492297D401007FFC00001FF012903EF822883EF822883EFA028201FE
+7AC9:01007FFE4822901408407E7C2440FF7C00047E7C42407E7C42407E7C4242463E
+7ACA:01007FFE482290140C40707C104055FC39241154FD0433FE3A22564A92FA1206
+7ACB:02000100010000007FFC000000101010082008200440044004800000FFFE0000
+7ACC:1000080008F07E9000900490449044902490289028900E92F0924112010E0200
+7ACD:1020082008207E200020042047FE44202420282028200E20F020402000200020
+7ACE:020001003FF8000008200440FFFE0000044004407FFC04400840084010402040
+7ACF:1008083C09E07E2000200420442047FE2420282028200E20F020402000200020
+7AD0:100008F808887E8800880506460045FC2484288428480E50F020405000880306
+7AD1:204010401040FC4003FE08408880889048904920512052481E44E48441FE0082
+7AD2:020001003FF8000008200440FFFE001000101F90109010901F90001000500020
+7AD3:1008081C08E07E200020043C44E044202420283E29E00E20F02240220022001E
+7AD4:200810681388FC880088088888888BFE48884888508850881D08E10842080408
+7AD5:201010901090FC88010809048A048DFA48884888508850881D08E10842280410
+7AD6:08004BF84A08491048A0484048B04B0C0A0001003FF8000008200440FFFE0000
+7AD7:1020082008207EA800A404A2452245202624282428280E08F010402000C00300
+7AD8:1040084008807EFE0102060244F244922492289228F20E92F002400200140008
+7AD9:1020082008207E20003E04204420442025FC290429040F04F104410401FC0104
+7ADA:204010201020FDFE01020A048800880049FE4820502050201C20E02040A00040
+7ADB:1020082008507E50008805244612441025FC280428080E88F050402000100010
+7ADC:020001003FF808200440FFFE00001FF011101FF011101FF01112010200FE0000
+7ADD:1020081008107EFE00000400448444842444284828480E10F01041FE00000000
+7ADE:020001003FF808200440FFFE00001FF0101010101FF00440044008423042C03E
+7ADF:020001003FF808200440FFFE00001FF010101FF010101FF0044008421042603E
+7AE0:020001003FF808200440FFFE00001FF010101FF010101FF00100FFFE01000100
+7AE1:100009FE08107E10002004FC44844484248428FC28840E84F084408400FC0084
+7AE2:202010401088FD0401FE0802888088FC4920482053FE50201C50E08841040202
+7AE3:204010401088FD0403FE0802888889444A4248F8518852501C20E05041880606
+7AE4:2040102013FE0202FC4400400BFE884088904890511051201A24E24204FE0842
+7AE5:020001003FF808200440FFFE00001FF011101FF011101FF001003FF80100FFFE
+7AE6:2020102013FEFC20002009FC8924892449FC4820507050A81D24E22240200020
+7AE7:1020084008F87E8800F8048844F8448A248C29F828180E28F048408803280010
+7AE8:20201020103EFC2001FC090489FC890449FC4924502053FE1C20E02040200020
+7AE9:2020101011FEFD02020408F88888888848F84888508850F81C88E08843FE0000
+7AEA:00007EFC48447E4442287E1048287EC6020001003FF8000008200440FFFE0000
+7AEB:2040104010F8FD08001009FC882488244BFE4824502451FC1C24E02040A00040
+7AEC:2004101E13E0FC2001FC0924892489FC48204BFE5222522A1EFAE202420A0204
+7AED:200011FC1104FDFC010409FC888089FE4A224922515251021DFAE00240140008
+7AEE:200013FC1204FE0403FC0A008A848A484AFC4A48524853FE1C48E44848881108
+7AEF:202011241124FD2401FC08008BFE8820484049FC515451541D54E1544154010C
+7AF0:100009FE09007F7C01540554457C45542554297C29100F10F17C4210021004FE
+7AF1:202013FE1020FDFC012409FC892489FC48224BFE500853FE1D08E08840280010
+7AF2:21041088100003FEFA2202AA0A728A228BFE480051FC510419FCE10401FC0104
+7AF3:201013D21054FD48008A09048AFA8C0049FC4904510451FC1D04E08847FE0000
+7AF4:2088105013FEFC5001FC0954898C8974490449FC500853FE1D08E08840A80010
+7AF5:200013FE100803BEFA8802A80ABE8B8888084BFE528A52521BFEE222022A0224
+7AF6:20201010FEFE44442828FEFE00007EFC428442847EFC28502A502C924912820E
+7AF7:1020FE7C44A42818FEE600107CFE44107C9044FE7C101020FE7C10C8103011CE
+7AF8:20201010FEFE44442828FEFE00007C7C44447C7C44447C7C28282A284C4A8886
+7AF9:10401040104010403EFE289049108A1008100810081008100810081008500820
+7AFA:104010401F7E289024884508800000003FF800000000000000000000FFFE0000
+7AFB:104010401F7E289024884508820002007FF80208040804080808100820504020
+7AFC:104010401F7E28902488450880000FE0082008200A200920092210222022401E
+7AFD:104010403F7E2890450880003FF801000100FFFE010001000100010005000200
+7AFE:104010401F7E2890248845088100117013901D10F11011501122110210020FFE
+7AFF:104010403F7E4890850800003FF8010001000100FFFE01000100010001000100
+7B00:104010403F7E4890850802000100FFFE0800080008000800080008000FFC0000
+7B01:104010401F7E289024884508800000003FF801000100010001000100FFFE0000
+7B02:104010403F7E28904508820002007FE002200A200420062009221022201E4000
+7B03:104010403F7E28904508BFF00010101010101FFC000400047FE4000400280010
+7B04:104010403F7E4890850800007FFC082008200820FFFE08200820102020204020
+7B05:104010403F7E28904508981006600180066018186C240240018006601818E006
+7B06:104010403F7E2890450880003FF82108210821083FF820002002200220021FFE
+7B07:104010403F7E289045088100008000007FFE0100012001100108010001000100
+7B08:104010403F7E2890450880003FE0082008400C780A081210112020C043308C0E
+7B09:104010403F7E4890950810001FF820084C088208006801881E08080800500020
+7B0A:104010403F7E28904508801000F81F2012201220122012102210220842048202
+7B0B:104010403F7E489085083FF002100210FFFE021004103FF0081010002000C000
+7B0C:104010403F7E489085083FFC0020102020203FFE012002200C203020C0A00040
+7B0D:104010403F7E4890850801003FF8210821082288244828282008200820282010
+7B0E:104010403F7E4890850800001FF0000000007FFC04400440044408441044603C
+7B0F:104010403F7E4890950810001FF8224842488488088811082208440808501020
+7B10:204020407EFE51108A0801007FFC000000000FE00820082008221022201EC000
+7B11:104010403F7E2890450880F03F0001000100FFFE01000280044008203018C006
+7B12:104010403F7E28904508828004400A203118C1061FE000200040004000800100
+7B13:104010403F7E489085082080208020883C9020A020C0208424842884307C0000
+7B14:104010403F7E4890850800F83F00010001F83F00010001FC7F020102010200FE
+7B15:104010403F7E2890450880001FF010101110111011101290149008823082C07E
+7B16:104010403F7E2890450880002410221021102110201024202830304821840602
+7B17:104010403F7E2890450888001FF02820444003801C70E30E00C00E0001800040
+7B18:104010401F7E289024884508810001FE010001003FF82008200820083FF82008
+7B19:104010403F7E28904508910011003FFC4100810001003FF8010001000100FFFE
+7B1A:20403F7E4890850800003FF8210821083FF8210821083FF82108010001000100
+7B1B:104010403F7E2890450881003FF82108210821083FF82108210821083FF82008
+7B1C:104010403F7E2890450880000100210821083FF801000100410441047FFC0004
+7B1D:104010403F7E489085083FF820082FC820482688210822882C4820083FF82008
+7B1E:104010403F7E48908508082010103FF8000800001FF01010101010101FF01010
+7B1F:104010403F7E2890450880781FA012201220122012101290224822A843248202
+7B20:104010401F7E2890248845088200010001007FFC00001010082004400000FFFE
+7B21:104010403F7E2890450880001FF0101010101FF010101FF010101010FFFE0000
+7B22:104010403F7E489085083FF8200820083FF8208020803FFC204020242C14300C
+7B23:20403F7E4890850808001FF020105F90109010901F901050102410040FFC0000
+7B24:20403F7E4890850800007FF80408080810502020DFF81008100810081FF81008
+7B25:104010403F7E2890450880003FF800087FE800081F88108810881F8810A80010
+7B26:104010403F7E489085080810081013FE30105110909010901010101010501020
+7B27:20403F7E4890850800001E78124812481248FFFE124812481248128826A84110
+7B28:104010403F7E4890850801007FFC03800540092011102FE8C106010001000100
+7B29:104010403F7E28904508885008481040307C57C09040102010201014100C1004
+7B2A:104010403F7E2890450880001FF0101010101FF0101010101FF00000FFFE0000
+7B2B:104010403F7E2890450881701F80110021003FFC0304050409043128C1100100
+7B2C:20403F7E489085083FF8010801083FF8210021003FFC030405041928E1100100
+7B2D:104010403F7E28904508828004400A203118C1061FE0002000400C8003000080
+7B2E:104010403F7E28904508880008001FFC2400440087F00400040007F804000400
+7B2F:104010403F7E28904508900011F8FE881288228824506450182018502488C306
+7B30:20403F7E4890850804403FF8044804481FF8144024403FFC0844105420484040
+7B31:104010403F7E4890950810001FF8200840089F88108810881F88000800500020
+7B32:104010403F7E28904508882010103FF8000808200820FFFE0820082010202020
+7B33:104010403F7E489085081000107C7E441244124412441244224422444A7C8444
+7B34:104010403F7E489085080000FFFE001000101F90109010901F90001000500020
+7B35:104010403F7E48908508100009F84908210825080528091071021102110210FE
+7B36:104010403F7E28904508880008001FF0210001007FFC0280044008203018C006
+7B37:104010403F7E489085080C0070FC4084448444845C8464944888088010806080
+7B38:104010403F7E2890450880003FFC2000200027F82408240827F8200020003FFE
+7B39:104010403F7E28904508822012201220FFFE1220122013E0100010001FFC0000
+7B3A:20403F7E489085080240022003F87E00020003FCFE10012000C007443834000C
+7B3B:104010403F7E2890450880007CFC10841084108410841E94F088408000800080
+7B3C:104010403F7E28904508804004207FFC04800488089008A010C223824C82807E
+7B3D:104010401F7E28902488450880003FF8244824482448244824482448FFFE0000
+7B3E:104010403F7E489085082080108017F8008870881108110812281410280047FE
+7B3F:20403F7E4890850808000FF010202C4003801C70E00E1FF0101010101FF01010
+7B40:104010403F7E2890450881003FF801000100FFFE000001003FF801000100FFFE
+7B41:104010403F7E2890454884403FF82448244824483FF82448244824483FF82008
+7B42:104010403F7E4890854820401258926843C84E480A48125AE242220221FE2000
+7B43:104010403F7E489085083FF8210821082FE8210822882448282820083FF82008
+7B44:104010403F7E4890850804404448245024600C403460C852084A1042203E4000
+7B45:104010403F7E48908508110011003FF841000100FFFE0440084010422042C03E
+7B46:104010403F7E489085083FF00110FFFE01103FF001003FF80100FFFE01000100
+7B47:104010403F7E2890450880007EFC088408880890088808840E84F0A840900080
+7B48:20403F7E4890850800F01F0001000100FFFE010001001FF0101010101FF01010
+7B49:20403F7E4890850801003FF801000100FFFE000000207FFC0820042004A00040
+7B4A:204020407EFE51108A0801007FFC08201010244844440280010006C01830E00E
+7B4B:104010403F7E489085083E20222022FC3E24222422243E24224442444A948508
+7B4C:104010403F7E289045088280044008203018CFE6010001001FF0010001007FFC
+7B4D:20403F7E4890950810001FF820085FC890481FC810481FC81048000800500020
+7B4E:104010403F7E489095081000FE7C124422442244644414440844147C2244C000
+7B4F:104010403F7E2890450888A00890108030FC57809048105010241054118C1604
+7B50:20403F7E4890850800003FFE20002FFC2080208027F8208020802FFC20003FFE
+7B51:104010403F7E4890850800007DF011101110119011501D12E2124212040E0800
+7B52:104010403F7E28904508BFF820082FE8200827C82448244827C8200820282010
+7B53:104010403F7E2890450880007EFC082008200820FEFE08200820102020204020
+7B54:104010403F7E2890450882800C603018CFE600001FF01010101010101FF01010
+7B55:20403F7E48908508100021FC4000880013FE3020502090201020102010A01040
+7B56:104010403F7E489085080100FFFE01003FF821082388255809201110610C0100
+7B57:104010403F7E489085081040104027FC6444A444244427FC2444204020402040
+7B58:104010403F7E28904508880008007EFC088408840E847884088408FC28841000
+7B59:104010403F7E4890850801007FFC01003FF80100FFFE054009203118C1060100
+7B5A:20403F7E48908508208020883EB020C42084267C39000100FFFE010001000100
+7B5B:20403F7E4890850808004BFE4820482049FC4924492449241134112820204020
+7B5C:104010403F7E289045089110092001007FF8000800083FF8000800087FF80008
+7B5D:104010403F7E2890450888001FF020205FF80108FFFE01081FF8010805000200
+7B5E:204020407EFE51108A0801003FFC2004410801007FFC054009203118C1060100
+7B5F:20403F7E4890850800F87F00221011203FE000400080FFFE0100010005000200
+7B60:104010403F7E28904508908010FC7D041204108410541C24E044418400280010
+7B61:204020407EFE51108A880440082037D8C10601003FF801001110210845040200
+7B62:104010403F7E48908508100011FCFD24112411241DFCF10011001102510220FE
+7B63:204020407EFE511088080608780808480848FF481C482A484948880808280810
+7B64:204020407EFE51108A0801001FF010101FF010101FF011081090126014181806
+7B65:104010403F7E2890450880001FF0101010101FF000003FF8200820083FF82008
+7B66:204020407EFE51108A0801003FFC20045FE800007FFC0440044008441044603C
+7B67:104010403F7E289045089FF010101FF010101FF010101FF0044008421042603E
+7B68:104010403F7E4890850802800C603118CFE6004000801FF0101010101FF01010
+7B69:104010403F7E489085083FE0044002803FF821083FF821083FF8210821282010
+7B6A:104010403F7E28904508BFFC20002FF828882FF828882FF8208020803FFE0000
+7B6B:104010403F7E2890450880003FF820083FF820083FF820083FF8082010102008
+7B6C:104010403F7E28904508809000883FFC208020883E48225022244A54448C8104
+7B6D:20403F7E4890850800003FF801001FF001007FFC00000820FFFE082010202020
+7B6E:104010403F7E4890850800007FFC01001110111011102928454485840100FFFE
+7B6F:104010403F7E489085283E20222022FC3E2422243E24222422442F44F0944108
+7B70:104010403F7E289045088880088010FE11403240547C90401040107E10401040
+7B71:104010403F7E4890850810401040247E24886488A54824502420205020882306
+7B72:104010403F7E48908508111009201FF010101FF010101FF01010101010501020
+7B73:104010403F7E4890850800387BC00840104023F8784008402BFC1000280047FE
+7B74:104010403F7E4890850801007FFC11101110292845440280044008203018C006
+7B75:20403F7E4890850800187BE00840104022787A400A402BFC1000280047FE8000
+7B76:104010403F7E4890850811001FF821000100FFFE00001FF0101010101FF01010
+7B77:104010403F7E48908508104011F818485448504853FE904010A0111012081406
+7B78:20403F7E489085081FF010101FF010101FF000003FF80100FFFE010001000100
+7B79:20403F7E4890850801007FFC02003FF80400FFFE08201FFC2420422080A00040
+7B7A:104010403F7E489085083FFE20002FFC2080208027F820A020902FFC20003FFE
+7B7B:20403F7E489085087FFC01003FF821083FF821083FF821001A00060019C0603E
+7B7C:20403F7E489085081FF0101010101FF000003FF820082108220804E01818E004
+7B7D:104010403F7E489085081FF010101FF000003FF80100FFFE028004401830E00E
+7B7E:104010403F7E2890450882800440082037D8C00602101110092008407FFC0000
+7B7F:104010403F7E289045088FE0144003801C70E10E01003FF80100111025080200
+7B80:20403F7E4890850810000BF8200827C82448244827C82448244827C820082018
+7B81:204020407EFE51108A0801003FF808200440FFFE00001FF0101010101FF01010
+7B82:104010403F7E4890850801007FFC11101110292845440380054009203118C106
+7B83:20403F7E4890850800007F0022FC3E4422443E44222822282F10F22842440282
+7B84:204020407EFE51108A0804003FF821083FF822083FF808801080FFFE00800080
+7B85:104010403F7E489085083FF821083FF821083FF80000FFFE0820082010202020
+7B86:20403F7E4890850800003FF8210822882448000020843E9820E020842684387C
+7B87:20403F7E4890850800003FF8210821082FE8210827C8244827C820083FF82008
+7B88:20403F7E4890850820801110120887FC4204500013F82208E208220823F82208
+7B89:20403F7E48908508100011F8FD08110815F8184033FCD0441084108451142208
+7B8A:104010403F7E4890952808207E50105010881F0612601210220022C04A308408
+7B8B:20403F7E48908508021002FC7F4000840764781C021002FC7F4000840764781C
+7B8C:20403F7E489085087F84100422247F24092408247F24082408240F04F0144008
+7B8D:20403F7E48908508100013FE1220FE2012FC12A41EA4F2A412B412A8522023FE
+7B8E:20403F7E4890850801F801003FFE210221F02F0420FC200027E044224822B01E
+7B8F:20403F7E4890850800FC7F00220811103FF80108FFFE01083FF8010805000200
+7B90:20403F7E4990BFF801001FF00100FFFE00001FF010101FF010101FF010101030
+7B91:20403F7E489085087FFC01003FF80108FFFE01083FF8110011F8290047FE8000
+7B92:20403F7E489085081FF000100FF000101FF000007FFE41029FF4111011501120
+7B93:20403F7E489085083FF000101FF00010FFFE111009A005401930E10E05000200
+7B94:104010403F7E48908528104009FC49042104250405FC09047104110411FC1104
+7B95:20403F7E48908508082008207FFC08200FE008200FE00820FFFE082010102008
+7B96:104010403F7E48908508082008207EFC08200C701A682AA44922882008200820
+7B97:20403E7E489080003FF820083FF820083FF820083FF80820FFFE082010202020
+7B98:20403F7E489085083FF8200820C8270821082FE823882548292821083FF82008
+7B99:20403F7E489085083EFC228422943E88228022FC3EA422A422A822904AA884C6
+7B9A:104010403F7E289045088C04122421245EA480243F242124212421043F142108
+7B9B:20403F7E48908508001C7DF00950115011501D503148D14811441254525A2468
+7B9C:20403F7E4890850801007FFE40028824101020081FF00100010001007FFC0000
+7B9D:104010403F7E4890850810881088FBFE108810881CF8F0881088108850F82088
+7B9E:20403F7E48908508111009203FF802007FFC082010102FE8C8260868080807F8
+7B9F:104010403F7E289045089FF810081FF810081FF82080208C3EF020822682387E
+7BA0:20803EFE491080F83F0001007FFC09200920FFFE092009207FFC010001003FF8
+7BA1:20403F7E4890850801007FFE40029FE410201FE010001FF0101010101FF01010
+7BA2:204020407EFE51108A0801007FFE400290041EF8228824A8549008841084607C
+7BA3:204020407EFE511088080804FFA408247F2449244B241C242A24490488140808
+7BA4:204020407EFE51108A0801007FFC08200820145022880100FFFE010001000100
+7BA5:20403F7E489085082020102013FC822442204BF80A881288E25024202450298C
+7BA6:20403F7E489085083FF801001FF001007FFC00001FF01010111002C00C307008
+7BA7:20403F7E4890850800003FFC208020802FF8249022A02FFC2140222024103FFE
+7BA8:20403F7E48908508100011FC1088FC70138E10201DFC3020D3FE102050202020
+7BA9:20403F7E489085083FF8244824483FF8020007F008103420024001800E007000
+7BAA:20403F7E48908508082004403FF821083FF821083FF80100FFFE010001000100
+7BAB:10401F7C28A045103FF80108FFFE01083FF80100254825282528292821084108
+7BAC:20403F7E4890850808207FFC08200200FFFE040008001FF02810C8100FF00810
+7BAD:20403F7E4890850810100820FFFE00003E4822483E4822483E0822082A282410
+7BAE:20403F7E50908A0801007FFE40029FF400001FF010101FF010101FF00000FFFE
+7BAF:20403F7E48908508080017FC304053F8924813F8124813F8114010C013301C0E
+7BB0:20403E7E48909FF820085FC890481FC810681FD000001FE00040FFFE01000300
+7BB1:104010403F7E28904508880008FC7E84088418FC1C842A842AFC4884888408FC
+7BB2:20403F7E489085281120092009FC422020202BFE08901090709011121112120E
+7BB3:20403F7E489085083FF820083FF8241022202FF8222022202FFC422044208820
+7BB4:104010403F7E2890452880243FFE20202FA420242FA8289828924FAA40468082
+7BB5:20403F7E489085081110216843841C00FFF010101FF010101FF010101FF01010
+7BB6:204020407EFE51108808087C7F440844087C3E442244227C22443E8422940108
+7BB7:104010403F7E4890A5481040FEFE212020AC3CB425E424AC24A044A25482887E
+7BB8:104010403F7E2890450882001FD00220FFFE03000FF03810CFF008100FF00810
+7BB9:20403F7E4890850810401440247C7884110424447E24002454044A048A280010
+7BBA:20403F7E489085087FFC01003FF80200FFFE08201FF02828CFE608200FE00820
+7BBB:20403F7E48908508004013F8204847FE884813F8304053FC904017FE10401040
+7BBC:20403F7E489085083FFC20043FFC20002FF8220024102FF820804FF84080BFFE
+7BBD:20403E7E48909FF001007FFC01001FF011101FF011101FF001003FF80100FFFE
+7BBE:20403F7E48908508080049042A247F2441247F2441247F244124410445144208
+7BBF:20403F7E489085081FF010101FF000007FFC10101FF010101FF0103EFFD00010
+7BC0:104010403F7E4890850800007E7C42447E4442447E44484444545A4862404040
+7BC1:204020407EFE51108A081FF010101FF010101FF000007FFC01003FF80100FFFE
+7BC2:20403F7E489085081FF010101FF010101FF021003FF841009FF00100FFFE0000
+7BC3:20403F7E489085083FF821083FF820002FF828082FF828084FF848088FF80808
+7BC4:20403F7E4890850808007F7C08447F4449447F4449547F480842FFC20842083E
+7BC5:20403F7E489085080100210821083FF80000FFFE02003FF82488248824A82010
+7BC6:20403E7E489088000FE010201FC00040FFFE06003B0804B019C062A00C987306
+7BC7:20403F7E4890850800803FFC20043FFC20002FFC292429242FFC49244924880C
+7BC8:20403F7E48908508080008087F0808FEFF08084808287F2808080F08F0284010
+7BC9:20403F7E489085087DF01110119011521D12E20E01007FFC054009203118C106
+7BCA:104010403F7E489085082090109013FC80904890489017FEE000209021082204
+7BCB:104010403F7E489085083FFC20802FF82080249024902AA83144222024103FFE
+7BCC:20403F7E4890850809F00810101037FC510091F81240104017FC10A01110120C
+7BCD:20403F7E489085080C20702010A410A4FCA83120382054505050908811041202
+7BCE:104010403F7E4890850800207C2044A87CA445227D22462844107C6001800600
+7BCF:104010403F7E489085282220223EFF42229422103E10221022283E2822440082
+7BD0:20403F7E48908508100013FEFE20122032FC3AA456A492A412B412A8122013FE
+7BD1:20403F7E489085081FF011101FF00100FFFE00001FF01010111002C00C307008
+7BD2:204020407EFE51108A880E603118DFE610201FE010201FE01008119014601810
+7BD3:20403F7E48908508111009207FFC05401930610C0400FFFE08201E4003C03C38
+7BD4:20803EFE49109FF010101FF000003FF820083FF820083FF820083FF808201010
+7BD5:20403F7E4890850801003FF801007FFC080010103FF800003FF824482448FFFE
+7BD6:20803EFE491080803FFC20802FF820883FFE20882FF820804FF848088FF80808
+7BD7:20803EFE491088801FFC30805FF890801FF810801FFC10003FF00C6003807C7C
+7BD8:20803EFE491090001FFC210451141FF4020814001FFC210451141FF404143808
+7BD9:20403E7E48908200FFFE00001FF010101FF000007FFC40044FE448244FE4400C
+7BDA:20403F7E489085083FFC224022403E7822402E7022403E78224022403FFC0000
+7BDB:20403F7E4890850800007EFC02047EFC40807EFC020422441A3462C414280810
+7BDC:20403F7E489085081FC000447D88055009203118C50602003FF8000024884244
+7BDD:20403F7E489085487FFC04403FF80440FFFE11101FF01110FFFE101010501020
+7BDE:20403F7E48908508200017FC140487FC440457FC104027FCE04020402FFE2000
+7BDF:20403F7E4890850808400FFC104033F8504097FE120813F8120813F812081218
+7BE0:20403F7E48908508108011F822886870ABAE282029FC282028A8292422A42040
+7BE1:20403F7E48909FF810101FF010101FF010101FF002007FFC04401A30E44E0FE0
+7BE2:20803EFE4910BFF801007FFC00001FF010101FF010101FF010101FF008201010
+7BE3:20403F7E489085083FF8082004407FFE420281043FF8040007F0081010502020
+7BE4:20403F7E4890850800001FF811001FF011001FF011001FFC0004292444940008
+7BE5:104010403F7E489085087FFC04403FF824483FF801007FFC05401930E10E0100
+7BE6:20403E7E489082003FF82448238824483FF8000020843E9820E020842684387C
+7BE7:20403F7E4890850804007FFC450408801FFC30805FF810801FF810801FFC1000
+7BE8:20403F7E48908508784048A05110620855F648404BFC68405150424845444080
+7BE9:20403E7E4890900023FE7C20442045FC7D2441247D24452445347D2844200020
+7BEA:20403F7E4890857C3F8020F820802FFC288428F02B882878480051E09224241C
+7BEB:20403F7E489085087DF0111011901D52E20E5FF001001FF001007FFC01000300
+7BEC:20403F7E4890850806C01A30E10E1FF010101FF010101FF010002FF848088FF8
+7BED:20403F7E50908A0801003FF80820FFFE00003FF821083FF821083FFA010200FE
+7BEE:20403F7E489085080480248024FC24A0251000003FF8244824482448FFFE0000
+7BEF:104010403F7E4890952810243C3E41E0BC20102E13F4FC281012106A15861802
+7BF0:20403F7E489085081000087C7F4422481450FFC800443E44225422483E402240
+7BF1:20403F7E489085080080FFFE0440139014501FF001007FFC44444FE44424400C
+7BF2:20403F7E489085081010FEFE10107C7C1010FEFE10103FF800081FF800083FF8
+7BF3:20403F7E489085083FF821083FF821083FF80920FFFE09203FF801007FFC0100
+7BF4:20403F7E4890850823FC10801144066870B01128166810A4112416A0284047FE
+7BF5:20403F7E489085081110211041108AA8144430405240927C1240154014FE1800
+7BF6:20403E7E4890FFFC010011F81100FFFE10001FF820003FFC0004492484940008
+7BF7:20403F7E4890850823F0151010E0071C704013F8104011F0104017FC284047FE
+7BF8:20803EFE491088201FF0102025487EFC04401930E64E1990062018C007003800
+7BF9:20403F7E489085081FF0149012501FF00200FFFE08203FD8C84608C0080807F8
+7BFA:104010403F7E48909528104011FC7D2411FC11441DFC7050109013FE50102010
+7BFB:20403F7E489085087FFC04403FF824483FF800003FF80000FFFE111025080200
+7BFC:20403F7E48908508120067DC444447C4444457DC60000440044008421042603E
+7BFD:20403F7E48908508140027DE4912811217D221126112A5D2251A25D42E102410
+7BFE:20403F7E489085083FF8244824483FF800903FFC208030482850242440D4830C
+7BFF:20803EFE4910FFFC01003FF821083FF821083FF801047FFC0020FFFE08200460
+7C00:20803EFE4910BFF801003FF80100FFFE10101FF010101FF010101FF008201010
+7C01:20403F7E489085081020213C4120892017FE300050209120113E112012A0147E
+7C02:20403F7E489085087FFC40A47FFC40845E9452945E64405446B459147FFC4004
+7C03:20403F7E489085280C4070FC13081090FC6030903B3E544255A4901810601380
+7C04:20803EFE4910BFF820083FF8200027F0241027F020002FF828884FF8480287FE
+7C05:20403F7E4890850800803FFC041002203FFE208024802FFC308047F840809FFE
+7C06:20403F7E50908A0801007FFE4022BE3C00207EF814081450142424D4440483FC
+7C07:20403F7E4890850820401040FEFE212020403CFC2520242025FE445054888906
+7C08:20403F7E489085083FFC20043FFC220824102F78241024103F7C441044108810
+7C09:20403F7E48908548224013F81440004077FC100013F8120813F8280047FE0000
+7C0A:20403F7E4890850808207FFC08200FE008200FE00820FFFE11102FE8C1063FF8
+7C0B:20403F7E489085081FF010101FF010101FF410881470180E3FF824482448FFFE
+7C0C:20403F7E489085080820FFA0083E7F42499449107F101C102A28492888440882
+7C0D:20403F7E489085083FF82108FFFE21083FF811101FF00400FFFE082007C07838
+7C0E:20403F7E489085081090109013FCFC9013FE10001DF8F10811F8110851F82108
+7C0F:20403F7E4890850800803FFE22203FFC22243FFC284028482F7048444B448C3C
+7C10:20403F7E4890850808207F20083E7F4249847F1049107F100828FFA808440882
+7C11:20403F7E489085087FFC00001FF01010FFFE10101FF0048808503820CB180C06
+7C12:20803EFE49109FF010101FF010101FF010101FF00200FFFE08203518CA2617F0
+7C13:20403F7E4890850800047F0849105D6049047F0841105D6255045D0845108260
+7C14:20403F7E489085087FFC00003FF81010FFFE10103FF8048808503820CB180C06
+7C15:20403F7E4890850822207F2022203EFC08247F2449247F240844FF4408940908
+7C16:20403F7E48908508040C55704E4044405F7E44484E48554844487F8800880108
+7C17:20403F7E489095080BF040902A94129275121250142001007FFC05401930E10E
+7C18:20403F7E489085083FF00110FFFC01103FF0092025482FE82388254829284108
+7C19:20803EFE4950804827FC204023F8FA4823F8224823F8224820102FFE211020B0
+7C1A:20403F7E489085087FFC444444447FFC0028FFFE08207F2449284D104A2A0846
+7C1B:20403F7E48908508220C2270FF4022403E40227E3E482248FF48224841488088
+7C1C:20403F7E4890850823F8120893F8420843F810002FFEE20027FC292422540488
+7C1D:20403F7E489085087FFC044028281FF02828CFE608200FE00100111025080200
+7C1E:20403F7E489085083EF822883EF800001FF011101FF011101FF00100FFFE0100
+7C1F:20403E7E4890FFFC04403FF824483FF810101FF010101FF00100FFFE01000100
+7C20:20403F7E489085283FF801001FF011101FF011101FF0111000003FF82448FFFE
+7C21:20403F7E489085087C7C44447C7C44447C7C40044FE448244FE448244FE4400C
+7C22:20403F7E489085083E7C22443E7C22443F7C20842FF420442244218426542008
+7C23:20803EFE49109FF011101FF001007FFC10101FF010101FF010101FF008201010
+7C24:20403E7E4890BFF824483FF800001FF010101FF010101FF010101FF008201010
+7C25:20403F7E4890850800701F800200FFFE082037D8C4463FF8200827C8244827D8
+7C26:20403F7E4890850800907EA00444282817D02008DFF610101FF0082004407FFC
+7C27:20403E7E489084403FF80440FFFE01003FF821083FF821083FF8082010102008
+7C28:20403F7E489085087CF844887CF842843E7C04403FF80440FFFE082010102008
+7C29:20403F7E4890850808202AA80820145022887FFC400402003FF8040808503020
+7C2A:20403F7E489085083E7C081048907EFE1428244A46863FF820083FF820083FF8
+7C2B:20803EFE4910BFF80108FFFE01083FF825483D7821083FF821083D7825484548
+7C2C:20403F7E48908508008078F849084A907860119812065DF8510851085DF8E108
+7C2D:20403F7E489085087FFC111029284544FFFE08203018DFF6101010101FF01010
+7C2E:20403F7E4890850808203EF808207EFC145022885FF410101FF010101FF01010
+7C2F:20403F7E489085081088108813FEFC8810F8388834F8508853FE908811041202
+7C30:20403F7E489085080820484049FC7D2441FC414479FC48A049204BFE48208820
+7C31:20403F7E48908508104808487EFC104810781E4812781248224823FE4A488484
+7C32:20403F7E4890850800203C4025FC25243DFC254425FC3C50249027FE54108810
+7C33:20403F7E4890850808107F2808443E82227C3E1022103EFE08107F1008100810
+7C34:20403F7E4890850801F801003FFE210221F02F0420FC292425285FFE42108408
+7C35:20403F7E489085081040FE7810887D5054207CD857067CF81088FE8810F81088
+7C36:20403F7E48908508200011F8FC0808F810083BFE5420953410A8112412A21040
+7C37:20403F7E48909FF820207FFEA4882BF4200027F8200027F8200047F8440887F8
+7C38:20403F7E4890850824102410FEFE24923C9024FC3CA424A4FEA8291045288246
+7C39:20403E7E4890911009203FFC20044FE808200FE000003FF821083FF821083FF8
+7C3A:20403F7E489085087FFE44429FF404403FF80440FFFE082011102FE8C1061FF0
+7C3B:20403F7E4890850821F8110811E8012873FC120412F4129412F412142A0847FE
+7C3C:20403F7E48908508211027FCF91027FC291037FEE24823F822482FFEA2084218
+7C3D:20403F7E5090890802800440183067CC00003EF8228822883EF8082014502288
+7C3E:20403F7E489085083FFC22203FFC22402FF822483FFC22482FF846604A50B24C
+7C3F:20403F7E4890854827FC104013F8824843F84A480BF81248F01027FC22102130
+7C40:20403F7E489085082080277CF4A425A436542088E7FC244427FC2444A7FC4404
+7C41:20403F7E4890850808207F3C08443E882A7C2A443E5408541C542A2848440882
+7C42:20403F7E48908508084014402AFE7F10A2103EFE22923E92289A24942A103010
+7C43:20403F7E489085083F2024203F3E21403F5024883F0800003FF824482448FFFE
+7C44:20403F7E4890BFFC208027F0249027F020803FFC241027F0241027F022203FFC
+7C45:20403F7E489085080A0033B822083A38238820883AB82288FFFE082010102008
+7C46:20803EFE491088207FFC09201FF831005FF091001FFC10003FF0082007C0F83E
+7C47:20803EFE491080803FFC00000FF008107FFE40029FF40100069839E00690398C
+7C48:20403F7E489085087F7C14207F20553855287F48086808587F4A084A0F6AF046
+7C49:20803EFE4910FFFE01003FF800001FF010107FFE48229FF401003FF80100FFFE
+7C4A:20803EFE4910BEF812480A28124808801FFC30805FF890801FF810801FFC1000
+7C4B:20403E7E489080007FFC21084104BFFA21083558292835582108355829283558
+7C4C:20803EFE4910FFFC01003FF80000FFFE00023FF00100FFFE00107DFC44907C30
+7C4D:20403F7E4890850810487CFC10487C4811FEFE0010FC388454FC948410FC1084
+7C4E:20403F7E48908508247C3A0422281E1020FE3E124850085E7F5014B0229E4100
+7C4F:20403F7E48908508208011FEFE8821FE20883CF8248824F8248845FE54888904
+7C50:20403E7E489080203D2424A825FC3C4027FE24883D2426AA247044A855248A62
+7C51:20403E7E48909FF0149012501FF00200FFFE09203FF8CA2609200FE808D00E38
+7C52:20403F7E4890850827FE20A0F7BC24A437BC20A067FCA44427FC2444A7FC4404
+7C53:20803EFE4910A03817C01248815047FC524814042BFAE24823F8224823F82208
+7C54:20403E7E489088007F204920FFBE49447FA42A243E281028FF1022281C446282
+7C55:20403F7E48908508104011BC1114FD5411AC304039FC552451FC912411FC1104
+7C56:20403E7E489084203F280424FFFE122073A4122473A812287392121A17A6F842
+7C57:20403E7E4890BFF801007FFE41029D7408801FFC30805FF890801FF810801FFC
+7C58:20403E7E489081243CA825FC24403DFE248825443E8A24F0242445FC54A88964
+7C59:20403F7E48908508100029F84408B8F810087DFE1020953450A81D24E2A24040
+7C5A:20803EFE491081F801003FFC21042FE0210827F8249027F024904FF849489FFC
+7C5B:20403F7E48908508109010882BFE4448B83211CE7C90108897FE50481C32E1CE
+7C5C:20403F7E4890850811FC1154FDFC102015FC182033FED08811FC102053FE2020
+7C5D:20403F7E489085087FFC10001FF808200FE079384FA87AA84AB8792A4AAA9C46
+7C5E:20403E7E4A90A7DE491297D2211265DAA5142FD000003FF80000FFFE11102308
+7C5F:20403F7E489095081080FEF811087EFC548454FC7C8410FC388454FC90481084
+7C60:20403F7E4890950808407E7C2440FF7C00047E7C42407E7C42407E7C4242463E
+7C61:20403F7E48908508104010A0FD1012E814061BB832A8D3B81110111052A82444
+7C62:20403F7E4890850808201420223E5D4480A47724552877282210222855448882
+7C63:20403F7E4890FD7C44447C7C44447C7C41045FF441045FF455545FF44544592C
+7C64:20403E7E4890912011282AA4FFFE122073A4122473A812287392121A17A6F842
+7C65:20803EFE491082800C6037D8C0063BB82AA83BB800003FF824883FF8248824B8
+7C66:20403F7E489085FC10202BFE4420B9FC11247DFC112495FC50201DFEE02047FE
+7C67:20403F7E489085F840802FFC28840BF0E8882BF829402AA8317022A851608FFE
+7C68:20403F7E4890850808201420223E5D4280847710551077102228222855448882
+7C69:20403E7E489087F8454824A827F80040EFFC2A1424882BF4210021F052108FFE
+7C6A:20803EFE49108882511C5DD048905DD0445E7FF451145DD448945DD444547FE4
+7C6B:20403F7E4890850828503E7C4890FEFE1528264A5FF6149012501FF008201010
+7C6C:20403F7E4890950808287F24147E494855C87F7E08487F7E514855485D7E4340
+7C6D:20403E7E4890BF7E12241B3412A43FFC22403FF822483FF828442F7848428F3E
+7C6E:20403E7E4890FFFC44447FFC10A0209045FE792013FC25207DFC012055FE8100
+7C6F:20403F7E489085087FFC10001FF808200FE07BB84AA87BA84AB87BAA492A9AC6
+7C70:20403F7E489085083EF822883EF822883FF831005FF091001FFC082007C0F83E
+7C71:20403E7E4890BFF801007FFE41029D7401001D7048907EFCC9907EFC48907EFC
+7C72:20403F7E4890850818FE24107E7C81447F7C55447F7C00447F7C55287F445582
+7C73:0100210811080910092001007FFC038005400540092011102108C10601000100
+7C74:06000100028004401830E10E1110092005407FFC0540092011102108C1060100
+7C75:081008104A102A102C100810FEFE18101C102A102A1048108810081008100810
+7C76:080008004AF02A902C900890FE9018901C902A902A90489288920912090E0A00
+7C77:0808081C4AE02A202C200820FE20183E1DE02A202A20482288220822081E0800
+7C78:100013F09490549058901090FC9033F03890549054909092108A108A10861082
+7C79:10401040944054405BFE1088FC88308838885508549090501020105010881304
+7C7A:084008404A402AFE2C800900FE7C18081C102A202A4048808902090208FE0800
+7C7B:01001110092001007FFC05400920111060080100FFFE0280044008203018C006
+7C7C:102010209420542059241124FD2431243924552455249124112411FC10041000
+7C7D:100011FC9404540858101020FC2033FE38205420542090201020102010A01040
+7C7E:1000100095FC544458441144FD44314439445644544490841084110412281410
+7C7F:080808084A082A082CFE0808FE0818081C882A482A4848088808080808280810
+7C80:10101010941054105BFE1010FC10311039105490549090501020105011881606
+7C81:0808081C4AE02A202C200820FE2019FE1C202A202A2048208820082008200820
+7C82:040004000FE01040208003600C187004111009207FFC054009203118C1060100
+7C83:101011109510551259121114FDD83110391055105510911211521192110E1000
+7C84:1008101C95E05500590011FCFD44314439445528552891101110122812441482
+7C85:10801080948054FC59541254FC54309438945524562490441044108411281010
+7C86:10201020942054A858A410A2FD2231203A245424542890081010102010C01300
+7C87:10801040944057FC58001000FDF03110391055105510911211121212120E1400
+7C88:100011F89448544858481048FC4831F838885488548890881088108813FE1000
+7C89:101010509450545058881088FD0432FA38485448544890481088108811281210
+7C8A:208020883CB020C020842C84307C0000111009207FFC054009203118C1060100
+7C8B:1040104095F854485888108AFD0A32263820542057FE90201020102010201020
+7C8C:100411E494245424582411E4FD043104390455E4542490241024102411441084
+7C8D:1008103C95E054205820103CFDE030203820543E57E09020102210221022101E
+7C8E:080008FC4A842A842C840884FEFC18A01CA02AA02A904890890809080A040C02
+7C8F:082008204A202A202C2009FEFE2018201C202A502A504850888808C809240A02
+7C90:082008104A102AFE2C820882FE8218FE1C822A802A8048808880090009000A00
+7C91:1000100095FC552459241124FD24312439FC5500550091001102110210FE1000
+7C92:082008104A102A002DFE0800FE0418841C842A482A4848488850081009FE0800
+7C93:088808884A882A882DFE0888FE8818881C882AF82A8848888888088808F80888
+7C94:080008FE4A802A802C8008FCFE8418841C842A842AFC48808880088008FE0800
+7C95:10201020944055FC59041104FD04310439FC5504550491041104110411FC1104
+7C96:10201020942055FE58201020FC2031FC387054A854A891241124122210201020
+7C97:100011F895085508590811F8FD083108390855F8550891081108110817FE1000
+7C98:1020102094205420583E1020FC20302039FC5504550491041104110411FC1104
+7C99:102010209420542059FC1124FD243124392455FC552491241124112411FC1104
+7C9A:1080108094FE55005A201120FD2C31743BA45524553491281122110210FE1000
+7C9B:010001003FF80108FFFE01083FF80100292825482FE823882548292841088108
+7C9C:0100111011101FF0410441047FFC0000111009207FFC054009203118C1060100
+7C9D:100011FE95005500590011FEFD203120393C5524552491241124124412541488
+7C9E:100013FE9450545059FC1154FD54315439545554558C91041104110411FC1104
+7C9F:7FFC044004403FF8244824483FF80000111009207FFC054009203118C1060100
+7CA0:108810889488548859FE1088FC883088388857FE540090881084110412021402
+7CA1:100011FE95025502597A1102FD02317A394A554A554A917A11021102110A1104
+7CA2:0100410021FC0A441448E0A021102608111009207FFC054009203118C1060100
+7CA3:100011DC9554555459541154FD5433FE3954555455549154115412D41224144C
+7CA4:02003FF8292825482FE82388254829283FF80000FFFE10001FF8000800500020
+7CA5:0100F93C09040D440B84793C412047E04120793C0B840D440904090451282110
+7CA6:0100111009207FFC054009203118C10610103EFC4210A290149008FE3010C010
+7CA7:10201010941055FE59001110FD103110397C5510551091101110121012FE1400
+7CA8:080009FE4A202A202C4008FCFE8418841C842AFC2A8448848884088408FC0884
+7CA9:10401040944455F458481050FDFE304038805584569890E010821082107E1000
+7CAA:0100111009207FFC054009203118C44604403FF804400440FFFE082010102008
+7CAB:100013FE94205420584011FCFD54315439545554555491541154114411141108
+7CAC:105010509450545059FC1154FD543154395455FC555491541154115411FC1104
+7CAD:082008204A502A482C840902FEFC18001C002AFC2A8448848884088408FC0884
+7CAE:1040102095FC5504590411FCFD04310439FC5520552291141108114411821100
+7CAF:100011F89508550859F81108FD0831F83908550855F89090109011121212140E
+7CB0:1008103C95C05404594410A8FC0031F83810542057FE90201020102010A01040
+7CB1:000023F0909042941292E51222502420111009207FFC054009203118C1060100
+7CB2:08000F7C28043F44612892100C683184C000111009207FFC054009203118C106
+7CB3:100011FE9420542059FC1124FD2431FC3924552455FC912010A0104010B0130E
+7CB4:100011FC9524552459FC1124FD2431FC3820542055FC90201020102013FE1000
+7CB5:04003FF820C82F2825483FF8254829283FF80000FFFE10001FF8000800500020
+7CB6:100011F89408540859F81008FC0833FE38205622557490A81124122210A01040
+7CB7:1080108094FE55025A42124AFD5230423BFE544254E29152124A104210541008
+7CB8:1088108897FE5488588810F8FC88308838F85488548893FE1000108811041202
+7CB9:1040102095FE540058881088FD5432223800542055FE90201020102010201020
+7CBA:1040108095FC5524592411FCFD24314439FC5490551093FE1010101010101010
+7CBB:100010FC948054F8588010F8FC8033FE39405524552891101108114411821100
+7CBC:080049122A120812FF242A24494888904248774892245A242F92221242128200
+7CBD:2040202023FEAA02700021FCF800200073FE6820A92821242222242220A02040
+7CBE:1020102095FE542058FC1020FDFE300038FC548454FC908410FC108410941088
+7CBF:100011FC9524552459FC1124FD2431FC382057FE547090A81124122210201020
+7CC0:1088108895FE548858881050FC50309439945698549090B210D21092108E1080
+7CC1:10401048948455FE582013FEFC8831243A425588541090621184101810601380
+7CC2:1088108897FE548858F81088FCF83088388857FE550091481184110011FE1000
+7CC3:100010FC948454FC588410FCFC0031FE388054FE552A924A1092112210541088
+7CC4:1040102095FE5502590211FEFD00310039FE55AA55AA92FE12AA12AA14A21086
+7CC5:200021FC2048A83073FE2052F894211072306820ABFE207020A8212426222020
+7CC6:100013FE9420544059FC1154FD54317439545554557491541154115411FC1104
+7CC7:108010BC9484550859FE1320FD20317C3990551055FE91101128112811441182
+7CC8:200023FE2022A920713C2120FAFE240071FC6904A9FC210421FC210421142108
+7CC9:200020882252AA227252228AFA0223FE70886944AA7A20882150202020D82706
+7CCA:1080109E949255D25892109EFC9231D23952555E5552915211D21022102A1044
+7CCB:210820882090ABFE700023C4FA54225473D46A54AA5423D422542244225422C8
+7CCC:2088208821ECA92A72282548F888217E760069FCA904210421FC2104210421FC
+7CCD:210820882090AFFE71082108FA10229474A46F38A9082210221024A427BC2084
+7CCE:100011FE9500557C59541154FD7C31543954557C55109110117C1210121014FE
+7CCF:200023FE2202AA0273FE2210FA92225472FE6A82AAFE228222FE2482248A2884
+7CD0:1028102497FE542059FC1124FDFC312439FC5524540893FE1088104810481018
+7CD1:200023DE2042A84273DE2210FA1023DE70426A52A94A214A2252204222942108
+7CD2:1088108897FE5488588813FEFC8031FC3B2455FC552491FC112411241124110C
+7CD3:1000FE7810487C480048FE8682007CFC104454443828FE281010382854449182
+7CD4:100011FC94A4548858501020FCD83326382055FC5524912411FC102213FE1002
+7CD5:11041084948854005BFE1020FC2031FC3820542057FE900012A4125214521000
+7CD6:1020101095FE5510597C1114FDFE3114397C5510557C914411441244127C1444
+7CD7:2040208023F8AA0873F82208FBF8220873F86850A84827FE20A0211022082C06
+7CD8:1040102095FE5502580010FCFC4030A23B345458549493341052109013501020
+7CD9:101010509650557C58901010FCFE3300397C55445544917C1144110012FE1400
+7CDA:1048104895FE544858001048FD48314839FE5448544893C811481148117E1240
+7CDB:1020112494A857FE5A0210F8FC88308838F85420542091FC1020102013FE1000
+7CDC:010000803FFE22102F7C26382B5432922080249022A03FFC21C042A044989886
+7CDD:2040208821FCA908725223FEF8502188762668C0AB1020642388203020C02700
+7CDE:111009207FFC054019307FFC11101FF011101FF004403FF80440FFFE08201010
+7CDF:2090209027FEA89073FC2294FBFC229473FC6800A9F8210821F8210821F82108
+7CE0:1020101095FE5510597C1114FDFE3114397C5510559291541138125412921430
+7CE1:1040102095FC5488585013FEFC0031FC390455FC550491FC109010921112160E
+7CE2:1088108897FE5488580011FCFD0431FC390455FC542093FE1050108811041202
+7CE3:200027BC2108AD2877BC2318FDAA294670006BF8AA08220823F82208220823F8
+7CE4:2288228827C8AA90729E27D4F82427D474546FD4AC5427C824482454246424C2
+7CE5:100011FE942055FE59521152FD523106380055FE542091FE1152115211521106
+7CE6:102013FE942055FC580011FCFD0431FC388857FE540091FC1104110411FC1104
+7CE7:100011FC950455FC590413FEFC0031FC392455FC552491FC102011FC102013FE
+7CE8:200023BE20A2A8A270BE2388FA08223E722A6BAAA8AA20BE2088208A257E2202
+7CE9:10201050948855745A0211FCFD2431AC392455FC540090F8108810F8108810F8
+7CEA:00407C2045FC44887C5043FE7C20A5FC24203C20111009207FFC05401930E10E
+7CEB:200023FC2294AA9473FC2000FBFE200073FC6A04ABFC20A2211423082D442182
+7CEC:200027FC24A4ACA477FC2048FBF8205077FE6840A9F8230825F8210821F82108
+7CED:202020882252AB267252228AFA2223FE70886944AA7A20882150202020D82706
+7CEE:201027D02510AFDE745027E8FD0427C470006BF8AAA822A822A822A82FFE2000
+7CEF:100011FC942057FE5A2211ACFC2031AC380057FE542091FC115411541154110C
+7CF0:23FE222223FEAA2272FA22AAFAFA22AA72FA6A26ABFE220A23FE228A225A23FE
+7CF1:52107EFE28447E28A2FE3E1020103E7C22103E10111009207FFC05401930E10E
+7CF2:200023FE2248ABFE724822FCFAA422FC72A46AFCAA2023FE232A257A250A2906
+7CF3:553C1424FFA422427F00083CFF8408286B1049287F4410100920FFFE0920711C
+7CF4:200011DC2844455490CC11545400384810FEFD9012FC389054FC949010FE1080
+7CF5:0820FFFE28207DFC44887C5041FE7C2045FC7C20111009207FFC05401930E10E
+7CF6:540055DC7C44115454CC55547C00004854FE399012FCFC9038FC549092FE1080
+7CF7:208823FE2088ABDE725223DEFA5223DE72226BFEAAAA22FA2222227222AA2224
+7CF8:02000400082010403F800100061018087FFC0104092009101108210445040200
+7CF9:080008001000120022007C000800100024007E00020000005200490089000000
+7CFA:084008401040124022407C400840104024407E400240004452444944893C0000
+7CFB:00F83F000400082010403F800100061018087FFC010409201110210845040200
+7CFC:104010402040244045FCF844104420444844FC84048400845504550482280410
+7CFD:0800080010FE121022107C100810101024107E10021000105210491089500020
+7CFE:080408041044124422447C4408441044244C7E54026400445204490489040004
+7CFF:1000100021FC24444444F844104420444844FC44044400845484550482280410
+7D00:1000100021F824084408F808100821F84908FD00050001005502550280FE0000
+7D01:100013FC210425444524F8A8108820884850FC50042000205450548881040602
+7D02:080808081008120822FE7C080808100824487E28022800085208490889280010
+7D03:10821092209224924492F892109220924892FC92049200925492551281020202
+7D04:10401040208024FC4504FA04100421044884FC44044400045404540480280010
+7D05:1000100021FC24204420F820102020204820FC20042000205420542083FE0000
+7D06:100011FC202024204420F820102023FE4820FC20042000205420542080A00040
+7D07:10401040208024FE4500FA0010FC20084810FC20044000805502550280FE0000
+7D08:104010402040244045F8F848104820484948FCC8044800A854AA550A82060402
+7D09:1000100021FC24444444F944114421444944FE44044400845484550482280410
+7D0A:020001007FFC082007C01830E20E04201FC0018006103FF80108112025104208
+7D0B:10401020202027FE4488F888108820884888FC50045000205450548881040602
+7D0C:10401050204824484440F9FE105020504850FC500490009054925512810E0200
+7D0D:10201020202025FE4522F922112221224952FD4A058A010255025502810A0104
+7D0E:10401048204424444440FBFE104020404840FCA004A000905510550882040402
+7D0F:10081088204824484408F888104820484808FC0E05F800085408540880080008
+7D10:100011F8204824484448F848104821F84888FC88048800885488548883FE0000
+7D11:1000100021FE24104410F8201020206848A4FD22062200205420542080200020
+7D12:10201020205024504488F904120220884888FC88048800885488550881080208
+7D13:100011F8200824504420F81013FE20224824FC20042000205420542080A00040
+7D14:1020102020202BFE4820F124112421244924FDFC0424002054225422801E0000
+7D15:10101110211025124512F91411D821104910FD100510011255525592810E0000
+7D16:100411E4202424244424F9E4110421044904FDE4042400245424542481440084
+7D17:10201020202024A844A4F8A2112221204A24FC24042800085410542080C00300
+7D18:10401040204028404BFEF040108020904890F92009200248AA44AC8481FE0082
+7D19:1004101E21F025104510F910111021FE4910FD1005100108550A554A81860102
+7D1A:100013FC208424884488F890109C20844944FD4405280128AA10AA2884440182
+7D1B:10101090209024884508F904120425FA4888FC88048800885508550882280410
+7D1C:1000100020FC24004400F80011FE20204820FC4004400088548455FE80820000
+7D1D:1008103C21E024204420F820102023FE4820FC20042000205420542081FC0000
+7D1E:10201020202025FE4522FA24102020204850FC5004500050549054928112020E
+7D1F:10201020205024504488F944122220204800FDFC040400085408541080100020
+7D20:01003FF801001FF00100FFFE020004201FC0018006103FF80108112025104208
+7D21:10401020202025FE4440F8401040207C4844FC44044400445484548481280210
+7D22:010001003FF8010001007FFE420284241FC0018006103FF80108112025104208
+7D23:1040104021F828484888F08A110A22264820F8200BFE0020A820A82080200020
+7D24:1004100E20F024804480F88010FE20884888FC88048800885488550881080208
+7D25:084008407F4008400E4078440844283C144008801F0002103FF8010815202210
+7D26:1000100021FC25244524F9241124212449FCFD00050001005502550280FE0000
+7D27:040025FC2488245024202450028C04201FC0018006103FF80108112025104208
+7D28:1088108820882908497EF308150821484928FD28050801085508550881280110
+7D29:102010202120252045FCF920122020204BFEFC20045000505488548881040202
+7D2A:1090109020902A904A92F2D4129822904A90FA900A900292AAD2AF12820E0000
+7D2B:088028882EF028842E84F07C020004201FC0018006103FF80108112025104208
+7D2C:102010202020242045FCF924112421244924FDFC052401245524552481FC0104
+7D2D:20082788408840889088E788240844109410F790009410A4A8A2A0BE85020200
+7D2E:042004207FA00E221522649E020004201FC0018006103FF80108112025104208
+7D2F:00003FF821083FF821083FF8020004201FC0018006103FF80108112025104208
+7D30:1000100021FC25244524F9241124212449FCFD24052401245524552481FC0104
+7D31:105010482048244047FEF880108020FC4944FD4405280128AA10AA2884440182
+7D32:10481148214825484548FBFE114821484948FD48057801005500550081FE0000
+7D33:10201020202025FC4524F924112421FC4924FD24052401FC5524542080200020
+7D34:10101010201025FE4512F914111021FC4944FD4405280128A910AA2882440482
+7D35:1040102020202BFE4A02F404100020004BFEFC20042000205420542080A00040
+7D36:10201020202025FC4420F820102023FE4820FC2004400048548455FE80820000
+7D37:10201020205024504488F9241212201049FCFC04040800885450542080100010
+7D38:10401020200025FE4420F8201020202049FCFC20042000205420542083FE0000
+7D39:100011FC204424444444F844109420884900FCFC048400845484548480FC0084
+7D3A:108810882088248847FEF888108820884888FCF8048800885488548880F80088
+7D3B:10201020202025FC4524F924112421244924FFFE042000505450548881040202
+7D3C:1090109020902BFC4894F09413FC22904A90FBFE08920092A91AA91482100410
+7D3D:10201010201025FE4502FA04108020884890FCA004C0008254825482807E0000
+7D3E:10201020205024884504FA12102020404988FC10042000445588541080600380
+7D3F:10201020204024404488F90413FE20024800FDFC050401045504550481FC0104
+7D40:10201020212425244524F92411FC20204820FD24052401245524552481FC0004
+7D41:1080108020FE25004620F920112C21744BA4FD24053401285522550280FE0000
+7D42:10401040207C28844988F250102020504888FB0608600010A808A8C080200010
+7D43:10201010201025FE4420F8201044208449F8FC1004200044548255FE80820000
+7D44:100011F8210825084508F9F8110821084908FDF805080108A908A90887FE0000
+7D45:100011FE210225024502F97A114A214A494AFD4A057A014A55025502810A0104
+7D46:10201020212424A444A8F82011FC20204820FC2007FE00205420542080200020
+7D47:10801080210029FC4A04F40411E421244924FD2405E401245404540480280010
+7D48:10201020204025FC4504F9041104210449FCFD04050401045504550481FC0104
+7D49:102010282024242045FEF8201070207048A8FCA8052402225420542080200020
+7D4A:102010202020242045FEF87010A820A84924FD24062200F85420542080200020
+7D4B:10201010201025FE4500F910111021104910FD2005280124AA44AAFE84420800
+7D4C:100011FC208424884450F820105020884B26FC2005FC00205420542083FE0000
+7D4D:10801088209C25704510FB101510211049FEFD100510011055105510817C0100
+7D4E:10401040209C25004640F84010BE21884A88FC88048800885488548880A80090
+7D4F:1020102021FC25244524F9FC1124212449FCFC2004240018543254CA83060002
+7D50:1020102020202BFE4820F02011FC20004800FDFC050401045504550481FC0104
+7D51:10201120212025FC4520FA20102023FE4870FCA804A801245524562280200020
+7D52:11041124212429244924F12415B4256C4924F92409240124A924AA2482040404
+7D53:1020102021FC24204420F82013FE20004820FC2005FC00205420542083FE0000
+7D54:100013FE202024204440F9FC110421044904FDFC050401045504550481FC0104
+7D55:100013FC204424444484F928121021FC4924FD2405FC01005502550280FE0000
+7D56:10401044224429484950F04017FE20904890FC900490009255125512820E0400
+7D57:1000100021FE25024502F97A114A214A494AFD4A057A0102550255FE81020000
+7D58:101010102210293E4922F044101020904890FB1009280128A928A94480440082
+7D59:100013FE2000240045FCF904110421FC4904FD0405FC01045400540083FE0000
+7D5A:100013FE204024404440F87C108420A44894FD04054400285408540883FE0000
+7D5B:108010F811082290206065986646A48825F02420244825FC2020212422A22040
+7D5C:08007F7C08243E2408447F540A8804201FC0018006103FF80108112025104208
+7D5D:1020102023FE24504488F90412FA20004BFEFC40048001FC5404540480280010
+7D5E:10401020202025FE4400F888110422024888FC88045000505420545080880306
+7D5F:10201020205024884504FA0211FC20204820FC2005FC00205420542083FE0000
+7D60:1020102021FE24404440F8FC108421844AFCFC84048400FC5484548480940088
+7D61:10401040207824884550F820105020884906FCF8048800885488548880F80088
+7D62:1080108021FC25044604F9E41124212449E4FD24052401E45504540480280010
+7D63:110410842088280049FEF088108820884888FBFE08880088A908A90882080408
+7D64:100013FE2050245045FCF954115421544954FD54058C01045504550481FC0104
+7D65:10901094209229124910F37E151021104910FD28052801285528554481440182
+7D66:10201020205024884504FA0211FC20004800FDFC050401045504550481FC0104
+7D67:100011FE21022502457AF9021102217A494AFD4A054A017A55025502810A0104
+7D68:10281024202428204BFEF020112421244924FBA809280110AA12AA2A84460082
+7D69:1090109020902A924994F098109021984A94FC9208900090A912A9128212040E
+7D6A:100011FC210425244524F92411FC21244924FD54054C018C5504550481FC0104
+7D6B:040008201FF0102024487EFC020004201FC0018006103FF80108112025104208
+7D6C:1008103C21E024204420FBFE102020204820FDFC050401045504550481FC0104
+7D6D:111009207FFC0200FFFE08203218C4261FC0018006103FF80108112025104208
+7D6E:08007F7C114432440C44327CC20004201FC0018006103FF80108112025104208
+7D6F:10201010201025FE4420F824104420F84812FC22044401885410542880440182
+7D70:100011FE202024404488F90411FE20224820FC2005FE00205420542083FE0000
+7D71:1040102020202BFE4840F088110423FE4892FC900490009055125512820E0400
+7D72:102010202048248845F0F8201040208849FCFC24042000A85524562280A00040
+7D73:1080108020FC29084A90F060119826264820F9FC08200220ABFEA82080200020
+7D74:11041084208828004BFEF020102021FC4820FC2007FE00205420542080200020
+7D75:10201020205028884904F20210F820004800FBFE08200040A888A90483FE0102
+7D76:1040104020F825084610F9FC112421244924FDFC050001005502550280FE0000
+7D77:1080FBF010901990F0941154520C24241FC0018006103FF80108112025104208
+7D78:100011F82108250845F8F908110821F84908FD0805F80090549055128212040E
+7D79:100010F82088248844F8F80011FC21044904FDFC0504010455FC550481140108
+7D7A:11841068203028C84B04F04013FE20A04920FBFC0D240124A934A92880200020
+7D7B:1080108020F825084610F9FC112421244924FDFC04500050549054928112020E
+7D7C:1008103C21E024964448F830104821944824FC4C059400245444558480280010
+7D7D:100010FC208424844484F88410FC20004800FDFE050201025502550281FE0102
+7D7E:10281024202428204BFEF220122422244BA4FAA80AA80290AA92ADAA84460882
+7D7F:102810242024242045FEF820112020B248B4FC6804A801245622542080A00040
+7D80:1020102023FE24204420F9FC1124212449FCFC20047000A85524562280200020
+7D81:2100211E411247D29114E11427D841149112F7D20112111AA914A21082100410
+7D82:1040102023FE24004400F9FC110421044904FDFC04500050549054928112020E
+7D83:1020112420A424A84420F9FC1104210449FCFD04050401FC5504550481140108
+7D84:1040102023FE2A024C04F1F8100020004BFEFC900490009055125512820E0400
+7D85:100011FC200424FC4404F9FC100023FE4A02FDF8048800885450542080D80306
+7D86:100013FE2020242045FCF924112421FC4924FD2405FC012054A0544080B0030E
+7D87:100013FE2050245045FCF95411542154498CFD04050401FC5504550481FC0104
+7D88:11081088209025FC4424F82411FC21204920FDFE046200A2552A562484200020
+7D89:101C11E02020242047FEF8A81124222249F8FC88049000BE5502550282140408
+7D8A:1020102020202BFE4820F020112421244924FAAA08200050A850A88881040202
+7D8B:1040102023FE2A024C44F04013FE20404890F89009100120AA24AA4284FE0842
+7D8C:10001050204824844524F820105020884906FEF8048800885488548880F80088
+7D8D:1020102023FE28204820F3FE1202240449F8FC10042003FE5420542080A00040
+7D8E:1000100623B828884888F108113E23884888FA880A88013EA900AA80847E0800
+7D8F:1008103C23C028444A24F128110020404BFEF88809080390A860A85081880604
+7D90:110410842088241045FCF9041104210449FCFC500450009054925512820E0400
+7D91:100013FE22222A224A22F3FE122222624A72FAAA0B220222AA22AA0283FE0202
+7D92:1008103C21C024044544F8A8100021F84810FC2007FE00205420542080A00040
+7D93:100011FE200028924924F248112420924800FDFE042000205420542083FE0000
+7D94:1000100CFEF02820444482F87C100024FEFE201240507C540492051228501020
+7D95:1020102020202BFE4820F020102021FC4840F82008A40282AA8AAA8A84780000
+7D96:1004100E23B828884888F128112E23A848A8FAA80AA8013EA900AA80847E0800
+7D97:100013FE22022A524A8AF306120222FA4A8AFA8A0A8A02FAAA8AAA02820A0204
+7D98:1040104020FC24884550F82010D8232648F8FC2004F8002057FE542080200020
+7D99:10101110211025924554F91011FE21104938FD54059201105510551081FE0000
+7D9A:1020102023FE282049FCF00013FE22024C04F89008900090A890A9128112020E
+7D9B:100013FC204429444944F284109421084A40F82008A40282AA8AAA8A84780000
+7D9C:1040102023FE2A024800F1FC100020004BFEF82009280124AA22AC2280A00040
+7D9D:10881088208828884BDEF0881088219C49DCFAAA0AAA04C8A888A88880880088
+7D9E:1008103C21E028204BFEF0A810A820A84BFEFCA804A803FE5420542081FC0000
+7D9F:1040102023FC2A044A04F3FC120022284A24FBFE0A200250AA50AC8885040A02
+7DA0:108010F82088290849F0F010101023FE4820FA22097400A8A924AA2280A00040
+7DA1:1040102023FE24004400F9FC110421044904FDFC042000A85524562280A00040
+7DA2:100011FC212425244574F92411FC21044974FD54055401745504560482140408
+7DA3:1020112420A8242045FCF84013FE20884904FEFA0488008854A854928082007E
+7DA4:7E7C12442A484444BE44225422483E00044008801F0002103FF8010815202210
+7DA5:100011FC2124292449FCF124112421FC4800F8000BFE0088A888A88881080208
+7DA6:08207FFC08200FE008200FE00820FFFE14502888DF0602103FF8010815202210
+7DA7:1040102023FE240045FCF90411FC200049FCFC08041003FE5420542080A00040
+7DA8:1088108823FE24884488F8F81088208848F8FC88048803FE5400548881040202
+7DA9:1040102023FE2A024D04F10011DE22524A52FB520C9A0094A910A9128212040E
+7DAA:1020102023FE242045FCF82013FE200049FCFD0405FC010455FC550481140108
+7DAB:10481044205E25E04428F812106A21964848FC5E05E0002454285412806A0186
+7DAC:101C13E020842A444948F11017FE24024800FBF809080110A8A0A84081B0060E
+7DAD:10A01090208025FE4510FB1015FC21104910FDFC05100110551055FE81000100
+7DAE:104008403E7E228823503E2020584186844008801F0002103FF8010815202210
+7DAF:1080108021FC25044684F8F4114420444BFCFC440554015455F4540480280010
+7DB0:1040102023FE2A024C04F1F81108210849F8FD00050001FC5504550481FC0104
+7DB1:100013FE22022A8A4A52F3FE122222224AAAFAAA0AAA02FAAA02AA02820A0204
+7DB2:100011FE2102218A4952F9FE1122211221FE4942F542017A55025502550A8104
+7DB3:100013DE22522A524A52F3DE125222524A52FBDE0A520252AA52AA52855208A6
+7DB4:100013DE2042294A4884F14A125224204800FBDE08520152A894A94882540422
+7DB5:1008103C23C028444A24F128110020204BFEF87008A800A8A924AA2284200020
+7DB6:100011FC2124292449FCF124112421FC4820FBFE087000A8A924AA2280200020
+7DB7:1040102021FE24004488F888115422224800FC2005FE00205420542080200020
+7DB8:10201020205024884504FAFA100021FC4954FD5405FC0154555455548104010C
+7DB9:1088108820E8252C452AFAA8104820A0491EFE0004FC00845484548480FC0084
+7DBA:1020102021FC24504488F90413FE200849E8FD28052801E85528540880280010
+7DBB:1040102023FE2A024C04F00013FE20204820F920093C0120AAA0AA60843E0800
+7DBC:1040108021FC25244524F9FC1124214449FCFC90051003FE5410541080100010
+7DBD:10201020203E242045FCF90411FC210449FCFD24042003FE5420542080200020
+7DBE:1020102021FC28204820F3FE108821444A42F8F809880250A820A85081880606
+7DBF:1020104021FC290449FCF10411FC20204820FBFE0A220222AA2AAA2480200020
+7DC0:1020102023FE242045FCF82413FE202449FCFC4007FE008455C8543080CC0302
+7DC1:1020102023FE242045FCF82413FE202449FCFC200520013EA920AAA0827E0400
+7DC2:1020112221222A244850F088130420224820F92409240228A850A88881040602
+7DC3:10881088208824884554FA22144220204820FD20053C0120AAA0AA60843E0800
+7DC4:100011FC2104250445FCF904110421FC4800FD1205D40118551055528192010E
+7DC5:20002FC044BC44A494A4E7A424A444A897A8F4A8049015D0AEA8A0A880C40082
+7DC6:100011FC210425FC4504F9FC1080208049FEFE4A044A0092A922AA4280940108
+7DC7:1092109221242A484924F0921092200049FEFD22052201FE5522552281FE0102
+7DC8:1020102021FC24204420FBFE1088205049FCFC20042003FE5420542080200020
+7DC9:100013FE202028204BFEF222122223324AAAFAAA0B760266AA22AA22822A0204
+7DCA:7EFC48447E4442287E1048287EC604201FC0018006103FF80108112025104208
+7DCB:1090109020902B9E4890F0901090239C4890F8900890039EA890A89080900090
+7DCC:101C11E0202028204BFEF0A8112422424840FBFE08880108A8D0A83080480184
+7DCD:101C13E022202BFE4A20F292130A220649FCFD04050401FC5504550481FC0104
+7DCE:1014101220102BFE4810F01013D222524A52FA540BD4000CA86AAB8A81160022
+7DCF:10901090210829484A44F492110823FC4844F82008A40282AA8AAA8A84780000
+7DD0:4000400C7EF080207C4444F864105424FEFE4412A4509454FE92051228501020
+7DD1:100011F82008280849F8F008100823FE4820FA22097400A8A924AA2280A00040
+7DD2:1020102221FA24244428FBFE1020204048FCFD84068400FC5484548480FC0084
+7DD3:1088108823FE288848A8F02011FC21244924F9240BFE0020A850A88881040202
+7DD4:1020112420A428A84820F3FE120222024AFAFA8A0A8A028AAAFAAA02820A0204
+7DD5:1040102023FE24884450F82010D823064888FCF80488008854F8550881080208
+7DD6:1020102221FA24244428FBFE1024204248FCFD84068400FC5484548480FC0084
+7DD7:11001100213C29244BA4F124113C23A44B64FD24093C0124A924A924813C0124
+7DD8:1008100C200A2BFE4A08F20812E8220A4A0AFAEC0AAC02A8AAEAAA1A82260442
+7DD9:1088108823FE248844F8F82011FC21244924FDFC042003FE5420542080200020
+7DDA:1040108021FC290449FCF10411FC20204832FBB408A80128A924AA2484A20040
+7DDB:100013FE2020244045FCF954115421544954FD2C042003FE5450548881040202
+7DDC:1000200C7CF044207C4444F87C10102410FEFE12925092549292971210501020
+7DDD:100011F82108290849F8F00017FE210849F8F90809F80108A93EAFC880080008
+7DDE:1080133822282A284BA8F2461200227C4BA4FA240A2803A8AE10AA2882440282
+7DDF:1008103C21E028204BFEF02011FC212449FCFD2405FC002055FC542083FE0000
+7DE0:1080104023FC28004908F09017FE24424844FBFC0A440244AA54AA4880400040
+7DE1:100011FC210425FC4510F9FE1110214A4986FC0005FC010455FC550481FC0104
+7DE2:1088108823FE24884488F80011FC21244924FD2405FC01245524552481FC0104
+7DE3:108010FC210429F84808F3FE104020A24B34F85808940334A852A89083500020
+7DE4:1048114821482BFE4948F1481178210049FEF8200BFE0070A8A8A92486220020
+7DE5:1100117C21442A444A44F67C1A1022104AFEFA380A540254AA94AB1282100210
+7DE6:100011FC2124252445FCF924112421FC4820FC10045401425542554A82380000
+7DE7:1088104820502BFE4850F05011FC21544954FD8C050401FC5504550481FC0104
+7DE8:1040102021FE25024502F9FE1100210049FEFDAA05AA02FEAAAAAAAA84A20086
+7DE9:101E13E0204425244488F9FC104020404BFEFC8004FC01445528561080680186
+7DEA:1100117E211025104590F95E1322252A4926FD420552010C55045504817E0100
+7DEB:1080108020FC29544AD4F0B4112C22444894F908084000A4AAAAAA8A84780000
+7DEC:100017FE204028804BFCF294129422F44A94FA940AF40294AA94AA9483FC0204
+7DED:100013FE22222BFE4A22F3FE100021FC4904FDFC050401FC5504550481140108
+7DEE:1100110021FE2A004DFCF10411FC210449FCFC8004FC01085690546081980606
+7DEF:1040104021FC28844BFEF00011FC210449FCF8200BFE0020AA20ABFE80200020
+7DF0:104010A021102A084DF6F00013C422544A54FBD40A540254ABD4AA44825402C8
+7DF1:1100117821082A084AFEF6401A40227C4A90FA100AFE0210AA28AA2882440282
+7DF2:1010101023902A904A94F3B212B222D24B90FA940A840388AA90A82080400180
+7DF3:010000803FFE22003FBC22142F9422143FA4220C24202FC041085FFC88881184
+7DF4:1020102023FE242045FCF92411AC21744924FDFC0420007054A8552482220020
+7DF5:1000108822522A224A52F28A120223FE4888F9440A7A0088A950A82080D80306
+7DF6:110011FE21102A104AFEF292169222FE4A92FA920AFE0290AA50AA2082580286
+7DF7:100013FE2222242045FEF82011FC212449FCFD2405FC002057FE542080200020
+7DF8:100013FE2050245045FCF9541154215449FCFC20042001FC5420542083FE0000
+7DF9:100011FC2104290449FCF104110421FC4800FBFE08200120A93CA92082A0047E
+7DFA:100010FC2084248444F4F894109421FE4902FD7A054A014A557A5502810A0104
+7DFB:2008200847C84210921EE4A427D441149114F7D401141108A9C8AE1484140022
+7DFC:100010F82088248844F8F888108820F84800FDFC055401545554555483FE0000
+7DFD:10201020203E24204420F9FC110421FC4904FDFC050401FC5400548881040202
+7DFE:100011FE2100257C4554F954117C21544954FD7C05100110557C5610821004FE
+7DFF:1040109021082BFC4804F00011F821084908F9F808400024AAA2AA8A84880078
+7E00:100013DE22422A424A42F3DE1200223E4BD2FA120A1403D4AA08AA1482240242
+7E01:100011FC200428FC4804F3FE104020A24B34F85808940334A852A89083500020
+7E02:10881048205025FC4504F904110421FC4820FC10045401425542554A82380000
+7E03:100013FE20222520453CF92012FE240049FCFD0405FC010455FC550481140108
+7E04:100011FC212425FC4524F9FC102021FC4924FDFC052401FC542054228022001E
+7E05:100C100A20082BFE4A08F3F8124A224A4BEAFAAC0AAC024CAAAAAB0A82160422
+7E06:2100213C4100410091BCE5642524453C9524F1240124113CA924A100817E0100
+7E07:1040102023FE2A024C04F1FC100021FC4904FDFC050401FC5504540083FE0000
+7E08:08202AA44D28145022887FFE420284241FC0018006103FF80108112025104208
+7E09:100013FC20902A944998F09017FE200049F8FD08050801F85508550881F80108
+7E0A:11041084208828004BFEF000108821044A02F9FC09540154A954A95487FE0000
+7E0B:10101220217C25444444F87C13402140497CFD440544017CA944AA80847E0000
+7E0C:124411242128247E4410FB5411542154497CFD1405200120A940AA80847E0000
+7E0D:1020101021FE24844448F9FE110222244810FDFE0440007C5444548480940108
+7E0E:100011FC210425E44524FBFE120221FC4904FDFC050401FC5504550481140108
+7E0F:08783E48228E2A007EF822482A3046CC844008801F0002103FF8010815202210
+7E10:1080108021FC2A444954F1F4108421284A90F9FC0A440554A9F4A88481280210
+7E11:10881050200025FE4450F9FC105423FE4854FDFC045000D85554565280500050
+7E12:10841044204825FE4420F8FC102021FE4840FC8004FE01105610541081FE0000
+7E13:100011FE21102520457CF944117C2144497CFD1005100154A952AA9282500420
+7E14:11F810882070298C4800F3DE1252218C4A52F8200BFE0070A8A8A92486220020
+7E15:100010F820A824A844D8F88810F820004800FDFC055401545554555483FE0000
+7E16:1040102023FE2A024C24F1FC102021FC4820FBFE082001FCA904A90481FC0104
+7E17:1040102023FE280049FCF10417FE210449FCFC5204940188568854A480C20080
+7E18:101E13E0212228944840F08811F0202048C4F9FE08220020ABFEA85080880306
+7E19:1088108821FE24884400F9FE1088208848F8FC8804F80088549E55E880080008
+7E1A:101E11E0202225124494F880102021CE4902FD0205CE01025502550281FE0102
+7E1B:1028102423FE242045FCF92411FC212449FCFD24040803FE5488544880480018
+7E1C:100010FC2084248444FCF80011FE210249FEFD0205FE010255FE544880840102
+7E1D:1020102023FE242045FCF90411FC210449FCFD0405FC010457FE548881040202
+7E1E:1040102023FC280049F8F10811F820004BFCFA040AF40294AAF4AA0482140208
+7E1F:100013FE220022FC4A00FBFE12A822904AC8FA860A0813FEAA88A44884080818
+7E20:1000FE7810487C480048FE8682007CFC2044444478281428FE10542892443182
+7E21:1040102023FE2A424820F1FC108820504BFEFC20042001FC5420542080200020
+7E22:0020792448A849FC48407BFE488849444A8A78F0482449FC482049244A229860
+7E23:00007C0C44F07C2044447CF844107C2444FEFE12105054545292931250502020
+7E24:1020102023FE242045FCF82013FE20404888FDF0042403FE5422552482A20040
+7E25:1020102023FE242045FCF84013FE20884934FEE2042001FC547054AC83220020
+7E26:108010A2211225144680F8FE110821084B28FD2E0528012855285558814E0180
+7E27:1110111E21222A544A08F6941AE222884A88FABE0A8802ACAA2AAA4A82280210
+7E28:100011FC210425FC4504F9FC1020212448A8FC2007FE0090549055128212040E
+7E29:1100111023DC2A544D54F288110822F44C02F8000BFC0040A950AA4885440080
+7E2A:100011FC212425FC4524F9FC10A820A84BFEFCA804A801FCA820ABFE80200020
+7E2B:1020147C228429484830F0CE1610227C4A10FA7C0A1002FEAA10AA1085FE0800
+7E2C:100C100A200823FE4A08FA48126A224A4BFAFA4C0A4C12ECAB5AA44A84D60822
+7E2D:1040102023FE28004954F124115421FC4820FBFE0A420292AAFAAA0A82020206
+7E2E:1020101023FE2A024880F0FE111023204D7CF9440944017CA944A944817C0144
+7E2F:1040102023FE2A024800F1FC102021FC4924FDFC052401FC5400548881040202
+7E30:11081108222824AE44A8F928137E25004908FD28052E01285558554881860100
+7E31:1124112422242C244954F14A129226104A10FA500A5C0250AA50AAB0829E0300
+7E32:100011FC212425FC4524F9FC1040208849F0FC20044403FE5422552482220060
+7E33:102013FE202025FC4524F9FC112421FC4822FDFE040801FE5508548880280010
+7E34:102013FE204820F04820FBFE1242209049F8F828092011FCAA20A7FE80200020
+7E35:100011F8210829F84908F1F8100023FC4A94FBFC080001F8A890A86081980606
+7E36:08207E2008F8FF2814287F6A082AFF560A8204200FC002103FF8010815202210
+7E37:102011FC21242BFE4924F1FC102021FC4924FDFC044003FE548855D08070038C
+7E38:1088108823FE24884400F9FC110421FC4904FDFC042003FE5450548881040202
+7E39:100013FE205025FC4554F95411FC200049FCFC0007FE002054A8552482A20040
+7E3A:1010101022FE2510457CF854107C2354497CFD1005FE0110A910AA90847E0000
+7E3B:010000803FFE22102F7C26382B543292210827F0206023842FFE404245488884
+7E3C:12101110211027BE4A40FA0013BE228A4A88FAA80AAE12A8ACA8A5A8885E1080
+7E3D:1020104021FC2524457CF98C115421244954FDFC0420001055545542814A0238
+7E3E:102013FE202025FC4420FBFE100021FC4904FDFC050401FC550455FC80880104
+7E3F:1040108821FC29084A52F3FE105021884E26F8C00B100064AB88A83080C00700
+7E40:1020122223FE28904888F1FE1310251049FEFD10051001FE5510551081FE0100
+7E41:20203F20403EBE482AA8FF284A107F28044608801F0002103FF8010815202210
+7E42:1040102023FE28204848F2F21124225248F8FC08042003FE5420542080200020
+7E43:1020122222222BFE4800F3DE125222524BDEFA520A5203DEAA52AA52855A08A4
+7E44:7F7848485F4C64805F784A4851307F4C044008801F0002103FF8010815202210
+7E45:112412482124280049FCF12411FC212449FCF8200BFE0070A8A8A92486220020
+7E46:100013DE20422A52494AF252102820C44B12F86009880032A9C4A81880600380
+7E47:00000E0CF0F02220924444F820103C2450FE1012FE501054549255125C506420
+7E48:10081388209028A448BEF38A1208223E4A2AFBAA08AA00BEA888A88A82BE0102
+7E49:11FC110421FC250445FCF90411FC20504954FCD804D80154565254908092010E
+7E4A:1088108C23EA28884888F7FE1008214A494AFD5A0B6C014CA94AA9EA87160022
+7E4B:1078FE4810487C8654787C485430FECE144008801F0002103FF8010815202210
+7E4C:1040108023FC2A944A64F29413FC20904908FA840CFA0108AA90A86081980606
+7E4D:1020102021FC242447FEF82411FC202049ACFD74052401FCA964AAB4832C0424
+7E4E:1110111421D22A504A7EF550109022A84928F9440A440482A808AAA482520452
+7E4F:100013DE22522BDE4A10F25211CE20004888FBFE08880088ABFEA88881040202
+7E50:1020102023FE282049FCF12411FC212449FCF8220BFE0042A824AAA2828A0478
+7E51:101811E020402BFE4888F174125220704800FDFC05040174555455748104010C
+7E52:1104108820002BFE4A22F2AA127222224BFEF80009FC0104A9FCA90481FC0104
+7E53:100011F8210821F84908F9F8100027FE4A40FBDC0A5413D4AA68A7C880540062
+7E54:1110109423D228124A50F19017FE20104BD2FA520A5403D4AA4AAA4A83D60022
+7E55:1088105023FE282049FCF02013FE212448A8FBFE080001FCA904A90481FC0104
+7E56:2288228847C84290929EEFD4202447D49454F7D4045417C8AC48A454846404C2
+7E57:1020112420A82BFE48A8F124122221044904F9DE0A440554A89EA90482040404
+7E58:100013FC204828304BFEF052109423504820FBFE0A52028AAB76AA5282720206
+7E59:103C13E0212428A84BFEF0A81124220249FCFD24052401FC5524552481FC0104
+7E5A:1020102021FC24204554F888110422FA4888FCF8048800F8542054A881240060
+7E5B:081008107F1E08103E7E0842FF7E22427C7E085212107F7E08102A1049101810
+7E5C:1088105023FE245045FCF954118C21744904FDFC040803FE5508548880A80010
+7E5D:13DE125223DE2A524BDEF20212F222924AF2FA920AF20292AA92AB3282020206
+7E5E:1020102021FC28204BFEF108139C21084988FE3E080003FEA890A8908112020E
+7E5F:100013DE22522A524BDEF00011FC212449FCFD2405FC002057FE542080200020
+7E60:01002488242443E4000024241212A0A0A4A41C1C04201FC002103FF809201310
+7E61:204023F8404847FE9048E3F820404554975CF44407FC1444AF5CA55485540844
+7E62:102011FC212425FC4420FBFE100021FC4904FDFC050401FC550455FC80880104
+7E63:102011FC20242BFE4824F1FC102023FE4800FDFC052401FC552455FC800003FE
+7E64:0820FFFE08201FF01490125011301FF00400FFFE12502F88C2261FF009481320
+7E65:102013FE202029FC4800F1FC110421FC4888FBFE080001FCA904A90481FC0104
+7E66:2000277C41444144917CE7102410447C9454F7540154117CA910A1148AFE0402
+7E67:100011FC20202BFE4A22F1AC102021AC4800FDFC040003FE5440548881FC0084
+7E68:10101210217C241044FEF844132821FE4910FD7C051001FE5510551082FE0400
+7E69:100011FC2154255445DCF85011DC21544954FDDC0554015455DC55508052003E
+7E6A:10201050208829744A02F1FC112421AC4924FDFC040000F8548854F8808800F8
+7E6B:0878FFC808483E862B783E482A28FF9049287F4604201FC002103FF809201310
+7E6C:1020102023FE29244924F2AA17FE200049FCFD04057401545574550481FC0104
+7E6D:0820FFFE082000007FFC4924492455FC5DAC49FC55245D3C41CC6B0441144008
+7E6E:100013FE200025FC4524F9FC112423FE4800FDFC052401FC552455FC800003FE
+7E6F:100013FC22942A944BFCF00017FE20004BFCFA040BFC00A2A914AB088D440182
+7E70:11FC1104210429FC4800F3DE125222524BDEF8200BFE0070A8A8A92486220020
+7E71:108813FE208829004BFCF55410D423244854F8940B480020A8A4AA8A828A0478
+7E72:110011DE224A2C8A4BEAF2B612A423F44ABEFAA40BE402BEAAA4AAA482240464
+7E73:2108220847C8445097DEE46427D442149114F7D4021413C8AA48A454855408A2
+7E74:3E1022FE3E4420287EFEA2103EFC2210045008801F0002103FF8010815202210
+7E75:102017FE20002BFE4A02F2FA128A23FE4800F9FC090401FCA904A9FC800007FE
+7E76:1040102021FC24884450FBFE100021FC4904FDFC050401FCA820AA94828A047A
+7E77:109013FC229423FC4A94FBFC100023FC4A00FAF80A0013FEAD20A51485480986
+7E78:10881448225028FC4820F050169422384A50FA980A340254AA90AA2085FE0800
+7E79:100011FC215425FC4420F9FC102023FE4888FC5005FC002057FE542080200020
+7E7A:1210121023D02C5E48A4F3D4105420544BC8F848085407E2A800AAA482520452
+7E7B:100011FC20202BFE4A22F1AC102021AC4800FBFE082001FCA954A9548154010C
+7E7C:1044128422EA2A4E4AA4F2EE122223FE4A44FA840AEA024EAAA4AAEE822203FE
+7E7D:1040102023FE2A0249FCF148125021FC4B04F9FC090401FCA904A9FC80880104
+7E7E:1010107C2254257C4510F8FE1000237C4944FD7C0540017C5544557C8280047E
+7E7F:100813E822882BEE4A28F3F4128223E24800F9FC09540154A954A95487FE0000
+7E80:112811AA216C2A284AFEF64416282AFE4A10FA7C0A1002FEAA10AA2882440282
+7E81:101C11E020202BFE4820F1FC11AC217449FCFC2005FC002057FE54008154022A
+7E82:20403E7E4890BFF8248822483FF80200FFFE092012502F88C2261FF009481320
+7E83:2080204047FC411090A4EF58255445529B58F000020813F8AA08A3F882080408
+7E84:108813FE208828204A3CF144103820D64B38F910097C0110A97EA910831004FE
+7E85:244424E448A84AAA9EEEE4A42AAA4EEE9242F0400FFE10E0A950A2488C460040
+7E86:11FC112421AC252445FCF82011FC20204BFEFD54062A002055FC542083FE0000
+7E87:920054FEFE10302054FC9284208444FC788410FC2484FE8410FC544892843102
+7E88:1100113E21082FD0493EF12213A2203E4822FBBE0AA202A2AABEAB8082940022
+7E89:108811DC20882BDE4888F154122221FC4904FDFC050401FC550455FC80880104
+7E8A:1020101021FE2528457CF92811FE2110497CFD54057C0154A97CAA0082440482
+7E8B:13FC104021F8290849F8F10817FE24424AA4FA8A0C7A0080A9F8AA888070038E
+7E8C:102013FE202029FC4800F3FE125223FE4904FDFC050401FC550455FC80880104
+7E8D:1FF011101FF011103FF82AA83EF82AA83EF808801F0002103FF8010815202210
+7E8E:1088108C23EA28884888F3FE1148236A494AFB6A094C036CA94AA96A87960022
+7E8F:202027FE440045FC9524E5FC252445FC9420F5FC042017FEAD24AAFA882013FE
+7E90:1200113E27C828104ABEF262142220BE4AA2FABE09220122AABEAA8084140022
+7E91:1040107C20402BFC4A44F3F0124422FC4AA8FAF80AA802F8AA00ADFC85540BFE
+7E92:13FE120022FE22924AFEFA9212FE22104AFEFA100BFE12AAAA10A2FE841009FE
+7E93:13DE125223DE2A524BDEF25213DE218C4A52F8400FFE0088A990A86080D80304
+7E94:11F0121027FC2A044BFCF22413B8222249FEFA100FFC0244ABFCA8D0814A063E
+7E95:102013FE200029DC4954F1DC108823FE4888FBFE088807FEA894A98886A400C2
+7E96:1148114C22AA28084FFEF1481368214A4B6AF94C0B6C0148A96AAB9A80260042
+7E97:122213FE209029FE4B10F5FE111021FE4910F9FE090003FEAA8AAB7682520276
+7E98:252827BE494847BE9318E5AA294643FC9204F3FC020413FCAA04A3FC81080204
+7E99:200023FE4252425293FEE1082154425E97B4F11E025417DEA814A554855E0010
+7E9A:13DE100023DE2A524B5AF252102023FE4A50FBFE0A5203FEAA92AADC829204CE
+7E9B:0100FFFE01001FF01210FFFE10901FF0001C3EE022242AF82A24FFFE2A5459B2
+7E9C:1790151E27A82C844FBEF52A17BE20004BF8FA080BF80208ABF8A8A08124061C
+7E9D:11FC112421FC29244BFEF2AA13FE22AA4BFEF88809F00064ABFEA92482220060
+7E9E:444444E44A0A4EEEA404AAEACE0E40E04AAA8AEAA040E0240522A50AA90800F8
+7E9F:10001000200024004400F800100020004000FC00400000001C00E00040000000
+7EA0:10041004208424844484F88410842084408CFCB440C400841C04E00440040004
+7EA1:100011FC202024204420F820102023FE4020FC20402000201C20E02040A00040
+7EA2:1000100021FC24204420F820102020204020FC20402000201C20E02043FE0000
+7EA3:100810082008240845FEF808100820084088FC48404800081C08E00840280010
+7EA4:1008103C21E024204420F820102023FE4020FC20402000201C20E02040200020
+7EA5:10401040208024FE4500FA0010FC20084010FC20404000801D02E10240FE0000
+7EA6:108010802080210445FEFA04140420844044FC24002400041C04E04440280010
+7EA7:100013FC208420884888F890109C20844144F944412801281A10E22844440182
+7EA8:104010402040244045F8F848104820484148FCC8404800A81CAAE10A42060402
+7EA9:10201010201025FE4500F900110021004100FD00410001001D00E20042000400
+7EAA:1000100023F820084808F008100823F84208FA00420002021A02E20241FE0000
+7EAB:1000100023FC20444844FA44124422444484F884408401041904E20444280810
+7EAC:10201020202025FE4420F82010FC20204020FDFE402200221C2AE02440200020
+7EAD:1000100021FC24004400F80013FE20204020FC40404000881D04E3FE41020000
+7EAE:10401040204020404BFEF840108020904090F920412002481A44E48441FE0082
+7EAF:10401040204023FC4840FA48124822484248FBF8404800401842E042403E0000
+7EB0:10101110211025124512F91411D821104110FD10411001121D52E192410E0000
+7EB1:10401040204021484944FA42124224484048F848401000101820E04041800600
+7EB2:100013FC220422044A94FA54122422244254FA54429403041A04E20442140208
+7EB3:10201020202020204BFEF222122222224252FA4A428A03021A02E202420A0204
+7EB4:1008103C21E024204420F820102023FE4020FC20402000201C20E02041FC0000
+7EB5:11101110211021104910F910111021104110FAA8426802281C44E44448841102
+7EB6:1040104020A020A04910FA08140621104120F940418001001904E10440FC0000
+7EB7:10101090209020884908F904120425FA4088F888408800881908E10842280410
+7EB8:1008103C23E022204A20FA20122023FE4220FA10421002121A0AE28A43060202
+7EB9:10801040204027FC4910F110111021104110F8A040A0004018A0E11042080C06
+7EBA:10401020202027FE4480F880108020FC4084FC84408400841D04E10442280410
+7EBB:104010202020240045FEF902120420004000FC00400000001C00E1FE40000000
+7EBC:100411E4202424244424F9E4110421044104FDE4402400241C24E02441440084
+7EBD:100011FC204424444444F844104421FC4084FC84408400841C84E08447FE0000
+7EBE:100011F8200824504420F81013FE20224024FC20402000201C20E02040A00040
+7EBF:105010482040245C45E0F840105E23E04044FC48403000221C52E08A43060002
+7EC0:110811082108250847FEF908110821084108FDF8410801081D08E10841F80108
+7EC1:10481248224822484A48F7FE124822484248FA48427802001A00E20043FE0000
+7EC2:10501048204820404BFEF880108020FC4144F944412801281A10E22844440182
+7EC3:1040104027FC20804880FBE01120222043FCF820412801241A22E42240A00040
+7EC4:100011F8210821084908F9F8110821084108F9F8410801081908E10847FE0000
+7EC5:10201020202025FC4524F924112421FC4124FD24412401FC1D24E02040200020
+7EC6:1000100021FC25244524F9241124212441FCFD24412401241D24E12441FC0104
+7EC7:1000100021FC25044504F9041104210441FCFD04400000901C88E10442020402
+7EC8:1080108020F821084B10FCA0104020A04318FC0640C000201810E18040600010
+7EC9:1080108020F821084A10FC2013FC20044004F80441FC00041804E00443FC0004
+7ECA:10201020212424A444A8F82011FC20204020FC2043FE00201C20E02040200020
+7ECB:10901090209023FC4894F89413FC22904290FBFE40920092191AE11442100410
+7ECC:10201020212425244524F92411FC20204020FD24412401241D24E12441FC0004
+7ECD:100013FC208420844884F904111422084400F9FC410401041904E10441FC0104
+7ECE:100013FC210420884850F82010D823264020F9FC402000201BFEE02040200020
+7ECF:100011FC200824104430F848108423024000FDFC402000201C20E02043FE0000
+7ED0:10201020204024884504FBFE1002200041FCFD04410401041D04E10441FC0104
+7ED1:2100211E211247D25114F11427D821144112F7D24112011A3114C21002100410
+7ED2:10281024202420204BFEF820112421244124FBA8412801101A12E22A44460082
+7ED3:10201020202027FE4420F82011FC20004000FDFC410401041D04E10441FC0104
+7ED4:1040104027FC20A04910FA081DF6200047FCF880410003F81808E00840500020
+7ED5:1080108020BC23C04850F82410D4230C4000FBFE409000901912E112420E0400
+7ED6:100011FE202024404488F90411FE20224020FC2041FE00201C20E02043FE0000
+7ED7:10801080213C22004C80F080117E23084508F908410801081908E10841280110
+7ED8:1040104020A021104A08F40611F020004000FBFC404000801910E20847FC0204
+7ED9:1040104020A021104A08F40613F820004000FBF8420802081A08E20843F80208
+7EDA:10801080210021FC4A04F40413E422244224FBE4422402241BE4E00440280010
+7EDB:1080108020FC21084A90F860119826264020F9FC402002201BFEE02040200020
+7EDC:1080108020F821084B10FCA0104020A04118FA0645F801081908E10841F80108
+7EDD:1080108020F821084A10F5FC112421244124F9FC410001001902E10240FE0000
+7EDE:10401020202025FE4400F888110422024088FC88405000501C20E05040880306
+7EDF:10401020202023FE4840F888110423FE4092F890409000901912E112420E0400
+7EE0:100013FE2020242045FCF924112421FC4124FD2441FC01201CA0E04040B0030E
+7EE1:1020112420A424A84420F9FC1104210441FCFD04410401FC1D04E10441140108
+7EE2:100011F82108210849F8F80013FC22044204FBFC420402041BFCE20442140208
+7EE3:103813C0204020404FFCF9501248244643F0F9104120017C1A04E20444280810
+7EE4:10001050204824844524F820105020884106FCF8408800881C88E08840F80088
+7EE5:1008103C23C020444A24F9281100204043FEF888410803901860E05041880604
+7EE6:1080108021F823084C90F060119826464040FBFC404002481A44E44441400080
+7EE7:10201220222023244AA8F22013FC22204270FAA8432402201A20E22043FE0000
+7EE8:11081088209023FC4824F82413FC22204220FBFE406200A2192AE22444200020
+7EE9:1040104027FC20404BF8F04017FE200043F8FA08424802481A48E0A041100608
+7EEA:1040104423F420484850F7FE1040208041F8FB08450801F81908E10841F80108
+7EEB:1020102021FC20204820FBFE108821444242F8F8418802501820E05041880606
+7EEC:1088108823FE248844A8F82011FC21244124FD2443FE00201C50E08841040202
+7EED:1020102021FC24204420FBFE100220944050FD10409003FE1C28E04440820302
+7EEE:1020102021FC24504488F90413FE200841E8FD28412801E81D28E00840280010
+7EEF:109010902090279E4890F8901090239C4090F8904090079E1890E09040900090
+7EF0:10401040207E20404BFCFA0413FC220443FCFA44404007FE1840E04040400040
+7EF1:1020112420A420A84820FBFE1202220242FAFA8A428A028A1AFAE202420A0204
+7EF2:100011FC2104250445FCF904110421FC4000FD1241D401181D10E1524192010E
+7EF3:100011F02110211049F0F84013F822484248FBF8424802481BFAE0424042003E
+7EF4:10A01090208025FE4510FB1015FC21104110FDFC411001101D10E1FE41000100
+7EF5:1020104021FC210449FCF10411FC20204020FBFE422202221A2AE22440200020
+7EF6:101C13E0208422444948F91017FE24024000FBF84108011018A0E04041B0060E
+7EF7:200027BC24A444A454A4F7BC24A424A444A4F7BC44A404A434A4C4A40AA4114C
+7EF8:100013FE222222224AFAFA22122223FE4202FAFA428A028A1AFAE202420A0404
+7EF9:1080108020FE25024682F8F21142204243FAFC42415201521DF2E00240140008
+7EFA:1088108821EC212A4A28F5481088217E4600F80041FC01041904E10441FC0104
+7EFB:10401248215020404BF8F88017FC21104208FDF4491201101950E124410400FC
+7EFC:1040102023FE22024800F9FC1000200043FEF820412801241A22E42240A00040
+7EFD:1040102023FE22024C04F80013FE20204020F920413C01201AA0E260443E0800
+7EFE:1040102023FE22024C04F9F81108210841F8F900410001FC1904E10441FC0104
+7EFF:100011F82008200849F8F808100823FE4020FA22417400A81924E22240A00040
+7F00:200027BC208442945108F29424A428404000F7BC40A402A43128C29004A80846
+7F01:11241124224824904A48F9241124200043FCFA44424403FC1A44E24443FC0204
+7F02:1088108823FE248844F8F82011FC21244124FDFC402003FE1C20E02040200020
+7F03:11001100213E21224FA2F122113E23A24362FD22493E01221922E122413E0122
+7F04:20142012201047FE5410F41025D024124412F5D44554054835DAC42A08461082
+7F05:100017FE204020804BFCF294129422F44294FA9442F402941A94E29443FC0204
+7F06:10901290229E22A84AC4F88011FC21044124F924412401541850E0904112060E
+7F07:100011FC2104210449FCF904110421FC4000FBFE40200120193CE12042A0047E
+7F08:20102010271045105514F752255225924710F514450807103520C04000800300
+7F09:100011F82108210849F8F00017FE210841F8F90841F80108193EE7C840080008
+7F0A:100011F82108210849F8F908110821F84000FBFC429402941A94E29447FE0000
+7F0B:1020102021FC252445FCF82013FE200041FCFD04412401241D24E05040880304
+7F0C:100011FC2124212449FCF924112421FC4000F840402402A21A8AE48840780000
+7F0D:1008103C21E020204820FBFE1124212447FEF924412403FE1820E02043FE0000
+7F0E:10801338222822284BA8FA461200227C43A4FA24422803A81E10E22842440282
+7F0F:110011FE211022104AFEF292169222FE4292FA9242FE02901A50E22042580286
+7F10:1040108021FC210449FCF90411FC20204032FBB440A801281924E22444A20040
+7F11:11001178210822084AFEF6401A40227C4290FA1042FE02101A28E22842440282
+7F12:10101220217C25444444F87C13402140417CFD444144017C1D44E280447E0000
+7F13:103C17C0224421284800FBFC1080208047FEF90041F802881A50E42048D80306
+7F14:1040102021FC24004488F85013FE22224424FDFC412401241D34E12840200020
+7F15:1020112420A820204BFEF8A8112422024040FBFE408801081990E06041980604
+7F16:1080104023FC22044A04FBFC1200220043FCFB54435405FC1D54E5544944010C
+7F17:100013FC220423FC4A20FBFE1210228A4306F80043FC02041BFCE20443FC0204
+7F18:108010FC210421F84808FBFE104020A24334F858409403341852E09043500020
+7F19:100013FC209022944998F89017FE200041F8F908410801F81908E10841F80108
+7F1A:1050104827FE20404BFCFA4413FC224443FCFA44400803FE1908E08840A80010
+7F1B:100013FE220022FC4A00FBFE12A8229042C8FA86420803FE1A88E44844080818
+7F1C:1040104027FC20404BF8FA0813F8220843F8FA0843F802081FFEE11042080404
+7F1D:1020147C228421484830F8CE1610227C4210FA7C421002FE1A10E21045FE0800
+7F1E:1040102023FE200049FCF90417FE210441FCF852409401881A88E4A440C20080
+7F1F:1040102023FE200049FCF90411FC200043FEFA0242FA028A1AFAE202420A0204
+7F20:2040202027FE440055FCF524252425FC4524F52445FC042035FCC820082013FE
+7F21:1040102023FE20004954F924115421FC4020FBFE424202921AFAE20A42020206
+7F22:11041084208820004BFEF800108821044202F9FC415401541954E15447FE0000
+7F23:10881050200025FE4450F9FC105423FE4054FDFC405000D81D54E25240500050
+7F24:1040102023FE22024C14F9E01100210041FCF910411007FE1800E09041080204
+7F25:100013FE205025FC4554F95411FC200041FCFC0043FE00201CA8E12442A20040
+7F26:100011F8210821F84908F9F8100023FC4294FBFC400001F81890E06041980606
+7F27:100011FC212425FC4524F9FC1040208841F0FC20404403FE1C22E12442220060
+7F28:20002FBE28A24AAA5AAAFAAA251428A24080F7FE4110021033A0C06001980E04
+7F29:2040202027FE44025100F1FE221026204A7CF2444244027C3244C244027C0244
+7F2A:100017BC208424A44A94F4A4105021884626F8C0431000641B88E03040C00700
+7F2B:112412482124240045FCF92411FC212441FCFC2043FE00701CA8E12446220020
+7F2C:220022FE22104FA0527CF244275420544054F754455405543528C72405420082
+7F2D:1020102023FE20504A8AF90413FE250441FCF90441FC00201924E22244A20040
+7F2E:1088105023FE202049FCF82013FE212440A8FBFE400001FC1904E10441FC0104
+7F2F:11041088200023FE4A22FAAA1272222243FEF80041FC010419FCE10441FC0104
+7F30:100013FE200025FC4524F9FC112423FE4000FDFC412401FC1D24E1FC400003FE
+7F31:101014FE229222FE4810F9FE10002EFE4282FAFE428002FE1A82E2FE450008FE
+7F32:11FC1104210421FC4800FBDE1252225243DEF82047FE007018A8E12446220020
+7F33:100013FC229422944BFCF80017FE200043FCFA0443FC00A21914E3084D440182
+7F34:2108220827C8445057DEF46427D422144114F7D4421403C83248C454055408A2
+7F35:2108252827BE494857BEF31825AA29464000F3F8420802483248C0B001080604
+7F36:0800080010001FF82100410001000100FFFE010021082108210821083FF80008
+7F37:200020003F3E482288220822FFA2082208224922492A49244F20792000200020
+7F38:200020003F7E481088100810FF10081008104910491049104F1079FE01000000
+7F39:080008001FF8210041000100FFFE01002108210821083FF80000488844448444
+7F3A:202020203C2051FC90241024FE24102413FE5420545054505C88648805040202
+7F3B:200020003DFE504090401078FE48104810685498549854885C8A64AA04CA0086
+7F3C:204020403C40507C90441088FEA0112010205450545054485C88648405040202
+7F3D:202020203C20502091FE1070FEA810A811245524562254F85C20642004200020
+7F3E:208420483C0050FC90481048FE48104811FE5448544854485C48648804880108
+7F3F:2008201C3CE05080908010FEFE80108010BC54A454A454A45CA4653C05240200
+7F40:205020503C50515290D41058FE50105810D45552565054505C9264920512020E
+7F41:400043FE7A02A28A225223FEFA22222222AAAAAAAAAAAAFABA02CA02020A0204
+7F42:3EF822882AA82AA82AA81450228849041FF821000100FFFE010021083FF80008
+7F43:08202AA44D28145022887FFE400288041FF821000100FFFE0100210821083FF8
+7F44:08007F7808483E4800863E782A483E30404890861FF02100FFFE010021083FF8
+7F45:4040407C7840A3FE22422278FBC4223C2208AAF0AB24AAA8BDFECC2008A00040
+7F46:200021FC3D2453FE912411FCFE0011FC110455FC550455FC5D0465FC04880104
+7F47:410840907BFEA09023FC2294FB1C220423FCAA04ABFCA808BBFEC90800A80010
+7F48:400043FE7850A3FE225223FEF80021FC2104A9FCA904A9FCB820CBFE00200020
+7F49:412440A87BFEA20220F82088F8F8200C21F0A820A9FCA820BBFEC82000A00040
+7F4A:08787F4808483E862B783E482A28FF9049287F4620003FF84100FFFE21083FF8
+7F4B:0100FFFE104824FE799010FC22907CFC089030FEC8803FF84100FFFE21083FF8
+7F4C:3EF822883EF822883EF822883EF81450228810001FF02100FFFE010021083FF8
+7F4D:1FF011101FF011103FF82AA83EF82AA83EF810001FF02100FFFE010021083FF8
+7F4E:41FC410479FCA10423FE2020FBFE222221ACA820A9FCA800BBFEC840008801FC
+7F4F:4040407C7840A3FC224423F0FA4422FC22A8AAF8AAA8AAF8BA00CDFC05540BFE
+7F50:408843FE7888A3DE225223DEF8A0209021FEA920ABFCAD20B9FCC92001FE0100
+7F51:00007FFC40044004421452944A54442444244A544A5452946104400440144008
+7F52:00003FF82448244824483FF80000000000000000000000000000000000000000
+7F53:00003FF820082448228821082288244820080000000000000000000000000000
+7F54:00007FFC4004482444445FF4410440845FF444044404440447E4400440144008
+7F55:00007FFE40028824101020081FF0010001000100FFFE01000100010001000100
+7F56:00003FF82448244824483FF801000280044008203018C2060100008000800000
+7F57:00003FF82448244824483FF8020004000FF0101068200440028003001C00E000
+7F58:00003FF8244824483FF8000000007FFC010003000570090C3102C10001000100
+7F59:00007FFE400288241010210801000100FFFE03800540092011102108C1060100
+7F5A:00007FFC444444447FFC0000200810880088F088108810881488180810280010
+7F5B:00007FFC444444447FFC000000781FA01220122012101290124822A843248202
+7F5C:00007FFC444444447FFC020001007FFC010001003FF8010001000100FFFE0000
+7F5D:00007FFC444444447FFC00001FF0101010101FF010101FF010101010FFFE0000
+7F5E:00007FFC44447FFC00003FF0002006400180FFFE0282048408803080C2800100
+7F5F:00007FFC444444447FFC01000100FFFE010001001FF01010101010101FF01010
+7F60:00007FFC44447FFC00003FF8200820083FF8208020803FFC204020242C14300C
+7F61:00007FFC444444447FFC000000007FFC0100110011F8110011001100FFFE0000
+7F62:00007FFC444444447FFC010001003FF801000100FFFE0400082010103FF81008
+7F63:00007FFC444444447FFC01003FF801000100FFFE000001003FF801000100FFFE
+7F64:00007FFC444444447FFC082004407FF801083FF821003FFC0304051419086100
+7F65:7FFC44447FFC00001FF010101FF000003FF820083FF820083FF8200820282010
+7F66:7FFC44447FFC000000F87F00221011203FE000400080FFFE0100010005000200
+7F67:00007FFC444444447FFC082008207EFC08201C301A702A6848A4892208200820
+7F68:3FF8244824483FF802007FFC044009203FF8D1161FF011101FF40104010400FC
+7F69:00007FFC44447FFC010001FC01003FF820083FF820083FF80100FFFE01000100
+7F6A:00007FFC444444447FFC000004407C7C044004407C7C04400440FC7E04400440
+7F6B:00007FFC444444447FFC000008207F200820FF30082808247F2408200F20F020
+7F6C:7FFC44447FFC00003EF8020814D00820145062883EF80288145008203458C286
+7F6D:00007FFC444444447FFC00500048FFFE00403E4022243E2800120E2A70C60302
+7F6E:7FFC444444447FFC0100FFFE02001FF010101FF010101FF010101FF01010FFFE
+7F6F:00007FFC44447FFC01003FF808200440FFFE00001FF010101FF010101FF01010
+7F70:7FFC444444447FFC080004047FA400243F2400243F2400243F2421043F142108
+7F71:7FFC444444447FFC0100FFFE01003FF8244822882FE821083FF8210821282010
+7F72:00003FF8244824483FF802001FD00220FFFE03000FF03810CFF008100FF00810
+7F73:7FFC444444447FFC00001FF0111011101FF0111011101FF001004884481287F2
+7F74:3FF8244824483FF8010001003FF80100FFFE040008201FF00010488844448444
+7F75:7FFC444444447FFC00001FF811001FF011001FF011001FFC0004292444940008
+7F76:7FFC444444447FFC040079FC40444844545462883FF821083FF821083FF82008
+7F77:7FFC444444447FFC1080249842E07E8400847E7C42807E9842E07E844284467C
+7F78:7FFC444444447FFC10080808FF0800FE7E0800887E4800487E0842087E284210
+7F79:00007FFC444444447FFC10A0109019FE552053FC952011FC1120112011FE1100
+7F7A:7FFC44447FFC1110222011101FF011101FF011101FF001007FFC05401930E10E
+7F7B:7FFC444444447FFC00003F0821083F0820FE2E0820483F2844285508A4A80C10
+7F7C:7FFC44447FFC00003FF821083FF821083FF80920FFFE09203FF801007FFC0100
+7F7D:7FFC444444447FFC00007FFE42004A4452A4452448A452244AA4530444949848
+7F7E:3FF8244824483FF8082004403FF8292825483FF800001FF010101FF010101FF0
+7F7F:00007FFC44447FFC01003FF80440FFFE11101FF011101FF001003FF80100FFFE
+7F80:3FF82AA824482AA80000FFFE02803EF822883EF802803FF821083FF821083FF8
+7F81:00007FFC44447FFC22007F7822083E4808487F7C49047F0408F4FF0408140808
+7F82:7FFC444444447FFC100011FC25047DFC080011FC25047DFC010455FC5504810C
+7F83:7FFC44447FFC0820FFFE08201FF010101FF01010FFFE09203FF8D11611300100
+7F84:7FFC444444447FFC1020103C24207DFC090411FC25047DFC002055FE54208020
+7F85:00007FFC444444447FFC1050148825FE7A9010FC24907EFC009054904AFE8A80
+7F86:7FFC44447FFC108024987EE000847E7C42007E9842E07E844284467C24884244
+7F87:7FFC444444447FFC2820FDFC2820385010887DFE54087DE81128FDE810081018
+7F88:00007FFC444444447FFC2800FDFE292039FC11207DFC55207DFE1002FEAA1004
+7F89:7FFC444444447FFC000021082390482473B820104BA4783E0388AAACABCA8298
+7F8A:0820042004407FFC0100010001003FF8010001000100FFFE0100010001000100
+7F8B:092009200920F93E09200920082001007FFC01000100FFFE0100010001000100
+7F8C:0820042004407FFC010001003FF802000200FFFE04800480088010822082C07E
+7F8D:020002007FFC044008203018C82604407FFC01003FF80100FFFE010001000100
+7F8E:1010081004207FFC010001003FF80100FFFE010001007FFC028004401830E00E
+7F8F:220412041408FF90082008447F0408080810FFA208420804100810102060C180
+7F90:08200820F83E082001003FF801000100FFFE04000FE01040608003401C30E00E
+7F91:082004407FFC01003FF80100FFFE040007E0082010406080014006201818E006
+7F92:441024502850FE50108810887D0412FA1048FE48104810482088208841288210
+7F93:4400240029FCFD24112411247D24112411FCFD00110011002102210240FE8000
+7F94:0820042004407FFC0100010001003FF8010001000100FFFE0000488844448444
+7F95:082004407FFC01003FF80100FFFE010000801F0001047D88095011202518C206
+7F96:440024F82888FE88108811067E0011FC1084FE84104810502020205040888306
+7F97:0820042004407FFC010001003FF802000200FFFE049004A408BC10822082C07E
+7F98:01043C842488240027FE3C20242025FC24203C2027FE24202420442054208820
+7F99:082004407FFC010001003FF801000100FFFE010011101120228004401830E00E
+7F9A:442024202850FC50108811247E12101011FCFC04100810882050202040108010
+7F9B:082004407FFC01003FF80100FFFE04407FF804483FF824403FFC084410542048
+7F9C:444024202820FDFE110212047C00100011FEFC20102010202020202040A08040
+7F9D:4404241E29F0FD10111011107D1011FE1110FD1011101108210A214A41A68112
+7F9E:082004407FFC01003FF80200FFFE04000FF011102110CFF0021002103FFE0000
+7F9F:440025FC2808FC10103010487C8413021000FDFC102010202020202043FE8000
+7FA0:442024202BFEFC2011FC10247DFC112011FEFC22102A10542050208841048202
+7FA1:082004407FFC01003FF80100FFFE4080208009FC12042448E04020A023182C06
+7FA2:441424122810FDFE101010907C92109213F2FC9410941088208A211A41268242
+7FA3:3FF80208FFFE04083FF808001FF82808CFF804407FFC01003FF80100FFFE0100
+7FA4:00827E44122812FEFF10121012107E7C201020107E1062FEA21022103E102210
+7FA5:440025FE2800FC92112412487D2410921000FDFE102010202020202043FE8000
+7FA6:4420241029FEFD02120410F87C00100011FEFC501050105020922092410E8200
+7FA7:444024402888FD0413FE10027C8811441242FCF8118812502020205041888606
+7FA8:082004407FFC01003FF80100FFFE0080208011FC820454482040E0A023182C06
+7FA9:082004407FFC01003FF80100FFFE02403C500848FFFE08480E5078240854198C
+7FAA:4440242029FCFD04110411FC7D04110411FCFD20112211142108214441828100
+7FAB:4440242029FEFD02120410507C8811041000FDFC102010202020202043FE8000
+7FAC:8808480C500AFBFE22082208FAE8220A220AFAEC22AC22A822EA421A42268442
+7FAD:884048A05110FA0825F62000FBC422542254FBD42254225423D44244425482C8
+7FAE:04407FFC01003FF80100FFFE248842443FF801001FF00100FFFE02800C60701C
+7FAF:440025FC2904FDFC110411FC7C8011FE1222FD221152110221FA200240148008
+7FB0:442025242924FD2411FC10807C8013FE1090FD101152125422A8242848448082
+7FB1:440025FE2910FD20117C11447D7C1144117CFD10111011542152229242508420
+7FB2:04407FFC01003FF80100FFFE00283E240824FFFE2A207D2490A81E12022A0C46
+7FB3:443C27E02924FCA813FE10A87D24120211FCFD24112411FC2124212441FC8104
+7FB4:082004407FFC01003FF80100FFFE454429287CFE10107C7C1010FEFE10102010
+7FB5:442025FC2820FC8813FE10887DFC110411FCFD0411FC110421FC208841048202
+7FB6:88204BFE5000FBFC220422F4FA9423FC2000F9F8210821F8210841F8400083FE
+7FB7:442024202850FC88110412FA7C00100011DCFD54115411DC2088208841548222
+7FB8:0100FFFE20003FF800003FF820083FF80440729C57D47114539C711657D6B122
+7FB9:04407FFC01003FF80100FFFE482482823FF801001FF00100FFFE02800C60701C
+7FBA:880049FC5020FBFE222221ACF82021AC2000FBFE202021FC215441544154810C
+7FBB:88204BFE5250FBFE225223FEFA0023FE2292FB48223A224022FC4548443089CE
+7FBC:3FFC20043FFC22202FF8208027F020803FFC2AA83F7C24105F7C4410BF7E0810
+7FBD:00007EFC0204020422441224122402040A14122462C422440204020414280810
+7FBE:0000EE00227C2210AA1066102210221026106A10B210221022102210AAFE4400
+7FBF:00007EFC22441224060C1A3462C40204042004207FFE04200420082010202020
+7FC0:0010EE1022102210AAFE66922292229226926AFEB292221022102210AA104410
+7FC1:0440082012102408C8261FF0001000007EFC224412240A14122422444A940408
+7FC2:0008EE2822282228AA4466442282237C26246A24B224222422442244AA944508
+7FC3:080008EE08227E2210AA1066202228224826486A90B2142222227E2222AA0044
+7FC4:0010EE10221022FEAA10661022FC224426446A44B228222822102228AA444482
+7FC5:100011DC1044FE44115410CCFC4444CC45542844284411541888240043FE8000
+7FC6:00007EFC224412241A3462C404003FC004400844113C2100FFFE010001000100
+7FC7:00007EFC224412241A3462C4022401107FFE020007F00A10112060C003301C0E
+7FC8:00007DDC5444544455547CCC54445444544C7CD4556410441044104411541088
+7FC9:100011DC1044FC44115430CC38445444524C90D411647C441044104411541088
+7FCA:200013DE1042FC420252094A894A884248C6494A525250421C42E042414A0084
+7FCB:0020EE10221022FEAA0066042244224426246A24B228222822082210AAFE4400
+7FCC:00007EFC22441224060C1A3462C4010000807FFC0000101008200440FFFE0000
+7FCD:0010EE10221022FEAA926694229022FC26A46AA4B2A822A822902328AA444482
+7FCE:100011DC28442444435490CC08440044FC4C04D4096450442044104411540088
+7FCF:00007EFC224412241A3462C4030406C01830E30E0C403180063038C007003800
+7FD0:0010EE1022502250AA7C66902310221026FE6A10B228222822282244AA444482
+7FD1:0040EE40228022FCAB04660422F4229426946A94B2F4229422042204AA284410
+7FD2:00007EFC224412241A3462C4010402001FF8100810081FF8100810081FF81008
+7FD3:100011DC1044FE44115410CC7C440044004C7CD44564444444447C4445540088
+7FD4:440025DC2844FE44115410CC7C441044104CFED4116410442044204441548088
+7FD5:010006C01830EFEE00001FF010101FF000007EFC224412240A1412246AD40408
+7FD6:100011DC28442444435480CC7C440044004C7CD44564444444447C4445540088
+7FD7:100010EE3E224222A4AA186610222422C8261F6A21B2D2220C22082230AAC044
+7FD8:200021DCFE442444295412CC2A44C6CC0154FC4428442954288A480247FE8000
+7FD9:100092EE92229222FEAA206620223E224226426AA4B214220822102220AAC044
+7FDA:7EFC224412241A3462C400007FFE42029FF4040009001FF001007FFC01000100
+7FDB:108010F811082290286069986E06ABB828882AA8299829982AA8288822A82110
+7FDC:00007EFC224412241A3462C4020401007FFC092009201550228804401830E00E
+7FDD:100008EE7F22412292AA10667F2210221426246A24B228224A225122BFAA1144
+7FDE:0020EE1022FE2200AA00667C22442244267C6A10B254225222922210AA504420
+7FDF:00007EFC224412241A3462C4020409001FFC30805FF890801FF810801FFC1000
+7FE0:00007EFC224412241A3462C4020401007FFC0820145022880100FFFE01000100
+7FE1:04407C7C04403C7804407C7C0440044000007EFC224412240A1412246AD40408
+7FE2:00007F6E492249225DAA49667F2241225D26556A55B25D2241224122452A8264
+7FE3:7EFC22441A3462C4020401003FF80820FFFE04007FFC08201C4003800C707008
+7FE4:00007CEE442244227CAA0066FE22AA22AA26AA6AFEB2AA22AA22AA22A2AA8644
+7FE5:01081FD001207FFC02000FF03810CFF008100FF000007EFC22441A3462C4060C
+7FE6:0820FFFE00003E0822483E4822483E482208261800007EFC22441A3462C4060C
+7FE7:200011DCFE44824401547CCC00447C44444C7CD445647C4400441C44E1544088
+7FE8:7EFC22441A3462C402041FF010101FF010101FF000007FFC110011F8290047FE
+7FE9:100008EE7E22422242AA7E66422240227F26556A55B27F22D522552255AA4344
+7FEA:0028EE9222AA2282AAFE6628224422A2263C6A44B24422A822102228AA444482
+7FEB:0000EE7C2200AA006600AAFE225010507E50425042507E52425242927E8E4300
+7FEC:7CF82448142824487FFC41043FF801001FF011101FF011101FF00100FFFE0100
+7FED:0040EE5C22442284AABE66902390229E26A86A88B2BE228822882294AA9444A2
+7FEE:0000FEEE00227C2244AA7C660022FE228226AA6A92B2FE229222922292AA8644
+7FEF:7CF8244814282548FFFE00001FF010101FF000007FFC40044FE448244FE4400C
+7FF0:102010201050FE8811067C0045DC7C4445547CCC1044FECC1154104411541088
+7FF1:100021DC7C4444447D5444CC7C441044FE4C28D4556492447C44104411541088
+7FF2:0000FEEE2822FE22AAAAAA66FE2200227C26006AFEB210225422922250AA2044
+7FF3:00007F7848485F4C64805F7844484A4851307F4C00007EFC22441A3462C4060C
+7FF4:0010EC1026FE2510B57C6C54247C2754257C6D10B5FE251025102690B47E4800
+7FF5:0010EE20227C2244AA7C6644227C2240267E6A40B27E220222AA22AAAB02440C
+7FF6:100021DC7C4444447D5444CC7C441044544C38D455641044FE44104411541088
+7FF7:080049EE2A220822FFAA2A66492288224226776A92B25A222F22222242AA8244
+7FF8:10007EEE10222422FEAA24667E2242227E26426A7EB242227E22242242AA8144
+7FF9:10007DDC1044FE444554EECC4444EECC0154FC4428442954288A480247FE8000
+7FFA:2000FEEE8222FE2282AAFE668222FE221026926A54B292221022FE2210AA1044
+7FFB:0E00F1DC92445444FF5438CC544482447C4C54D455647C44544454447D544488
+7FFC:7EFC22441A3462C402043FF821083FF821083FF804403FF80440FFFE08201010
+7FFD:08004E764812FF12045A05367F9244127C125536555A75125A12929225DAC8A4
+7FFE:0000FEEEAA22AA22FEAA0066FE2200227C26446A7CB22A226422A22231AA2044
+7FFF:1000FEEE10227C2200AAFE6602227C221026FE6A00B2FF220222FF22AAAAE644
+8000:100011DC9044555458CC1154FC00284828FE29902AFC28902AFC4C9048FE8080
+8001:020002083FD002200240FFFE010002000C1018E02F0048088808080807F80000
+8002:020002083FC802100220FFFE0080010002000C003000C0000000000000000000
+8003:020002083FD002200240FFFE010002000FF81200240047F08010001000A00040
+8004:02203FC00280FFFE02200FC03408C3F8000001F03E0003F03E0003FA7E0201FE
+8005:020002083FD002200240FFFE010002000FF0181028104FF0881008100FF00810
+8006:02083FD00220FFFE02000C703F84C80407FC00001FF010101FF010101FF01010
+8007:020002083FD002200240FFFE03001C00EFF810082FC8C8480FC8000800500020
+8008:02203FC00280FFFE02200FC03408C3F810003FF840089F8810881F8800500020
+8009:020002103FE00240FFFE010007F81C00E7F800081F88108810881F8800500020
+800A:020002103FE00240FFFE010006001FF0E40008201FF001001FF001007FFC0000
+800B:02203FC00280FFFE02200FC03408C3F800007FFC08201FF001001FF001007FFC
+800C:00007FFC0100010002003FF82488248824882488248824882488248820282010
+800D:0000FFFE020004003FF82488248824A822100200FFFE08201C4003800C707008
+800E:0000FFFE020004003FF824882488248824A8211001007FFC028004401830E00E
+800F:0002FFE20404040808107FC24A424A444A484A504A424A424A444848415040A0
+8010:0008FF880808080810FE7F085508550855485528552855085508550841284310
+8011:01002108210821083FF800000000FFFE020004003FF824882488248824A82010
+8012:010001007FFC010001003FF801000100FFFE0380054009203118C10601000100
+8013:1000100011FEFE1010107C101010FE1010103810341054105010901010501020
+8014:100010FC1004FC08100878101010FDFE10103810341054109010101010501020
+8015:108810881088FE8811FC7C881088FE8813FE3888348854885088910811081208
+8016:102010201020FCA810A478A21122FD2012243824342854089010102010C01300
+8017:1008101C10E0FE2010207C3C10E0FE201020383E35E05420502290221022101E
+8018:100010FC1000FE0010007C0011FEFE201020384034485484508491FE10821002
+8019:1000100011FCFD24112479241124FD2411FC3900350055009102110210FE1000
+801A:101010101010FDFE111279141110FDFC11443944352855289110122812441482
+801B:102010201020FE4010487C8411FEFE82100038FC348454845084908410FC1084
+801C:100011F81108FD081108790811F8FD00110039FC350455049104110411FC1104
+801D:100010F81088FE8810887CF81088FE88108838F8348854885088908813FE1000
+801E:110011001100FD1C13D479541154FD5411543954355455549154125C13541480
+801F:100011FE1100FF0011007DFC1104FF041104390435FC55005100910011FE1000
+8020:102010201050FC8811047A0211FCFC00100039FC350455049104110411FC1104
+8021:1008100813C8FE48125E7A4A13CAFE4A124A3BCA364A524A526A93D216121026
+8022:1088108813FEFC8810007BFE1202FC4410403BFC344454849084110412281410
+8023:102010201050FC8811047AFA1000FDFC1154395435FC5554915411541104110C
+8024:104810481048FDFE1048784811FEFC0010FC3884348454FC9084108410FC1084
+8025:1020112410A4FCA810207BFE1202FE0212FA3A8A368A528A52FA9202120A1204
+8026:11FC11241124FDFC1124792411FCFC2010203BFE3622522A52FA920A12021206
+8027:1020112410A8FC2013FE78A81124FE0210403BFE348851085190906011981604
+8028:100011FE1100FD7E110079FE1154FD4811643942350851FE5148922812081418
+8029:1088108813FEFC8811FC788813FEFC2011FC392435FC512453FE910411141108
+802A:1040102013FCFD0810907BFE1202FC4410203BFC348054F89088110811281210
+802B:102013FE1020FDFC10207BFE1000FDFC110439FC350455FC910411FC10881104
+802C:102011FC1124FFFE112479FC1020FDFC112439FC344055FE908811D01070138C
+802D:1124112412AAFFAE11247AAA13AEFD2413FE391035145114528A924A12161422
+802E:1048116A10DCFE4810B47D2211FEFF021020382034FC54245044904410941108
+802F:108813FE10A8FC9011FE7B2011FCFD2011FC392035FE550093FC10881070138E
+8030:13FC104011F8FD0811F8790817FEFC4212A43A8A347A508051F892881070138E
+8031:1040102013FEFE4813FE7A4812ECFF5A12483BFE3620527C52C49344147C1844
+8032:1040102013FEFC0011FC795411FCFC201122388C3522545490C8114412521060
+8033:00007FFC101010101FF0101010101FF010101010103E17D0F810001000100010
+8034:0020FFA0222022203E20222022203E202220222027A0FA2242220222021E0200
+8035:0000FF80227E22083E08220822083E08220822082788FA084208020802280210
+8036:0000FFBE222222243E24222822243E242222222227A2FA344228022002200220
+8037:010001007FFC0280044008203FF8C8260FE008200FE0082009F87E2000200020
+8038:0820082014502288410400007FFC10101FF010101FF01010103EFFD000100010
+8039:0020FF20242024503C50248825443E22242024F82E08F4084410041004200420
+803A:0000FF0024FC24003C00240025FE3C20242024402E40F488448405FE04820400
+803B:0010FF10241024903C902490249E3C90249024902E90F4904490049005FE0400
+803C:0000FF7C244424443C4424FE24443C44244424FE2E44F4444444044404540448
+803D:0040FC4048404BFC7A444C484840784048A048A04CA07920C9220A220C1E0800
+803E:0040FF40244024403DFE244024403C50249024902EA0F5284544064404FE0442
+803F:0020FF20242024243CA424A424A83D20242024502E50F4504488048805040602
+8040:0048FF44244424403C5E25E024403C44244424482E30F4224452048A05060402
+8041:0010FC9048904888790849044A047DFA488848884C887888C90809080A280C10
+8042:00007FFC08200FE008200FE0083EFFE000203EF8028822881450082034D8C306
+8043:0020FF20242025FC3D24252425FC3D24252425242FFEF5044504050405140508
+8044:0020FC204850488879044A1248207840498848104C207844C988081008600B80
+8045:0040FC40488048FC79204A20482078204BFE48204C507850C888088809040A02
+8046:0020FF20245024503C88252426123C1025FC24042E08F4884450042004100410
+8047:0000FF0024FE24103C10241024903C90249E24902E90F4904490049007FE0400
+8048:0010FC9048904910797E4A524B927892491249124E527BD2C8620822084A0884
+8049:0010FF10249224923C92249224FE3C10241024922E92F4924492049204FE0402
+804A:0000FC804B1E4A527A524A524A527A524A524AD24F5A7A54C890089009100A10
+804B:04800440FFFE0940118466FC00007FFC08200FE008200FE0083EFFE000200020
+804C:0000FF0024FC24843C84248424843C8424FC24842E00F4484444048404820502
+804D:0040FC2048204BFE7A024C04480078004BFE48204C207820C820082008A00840
+804E:0050FF50245025523CD4245824503C5824D425522E50F450449204920512060E
+804F:0000FDFC48204820784049FC49547954495449544D547954C954094409140908
+8050:0020FC2048204BFE7820482049FC7800480049FC4D047904C904090409FC0904
+8051:0000FDFE48884888788848F84888788848F848884C88789ECBE8080808080808
+8052:0008FF1C24E024203C2025FE24203C20242024FC2E84F4844484048404FC0484
+8053:00007DF0111011901D52F20E04007FFC08200FE008200FE0083EFFE000200020
+8054:0088FC484850480079FC4820482078204BFE48204C507850C888088809040A02
+8055:0020FD20492049FC79204A2048207BFE480048004DFC7904C904090409FC0904
+8056:00007F00227C3E4422443E4423C4FE7C024402007FFC01003FF801000100FFFE
+8057:0020FC2048204BFE782048204924792449244AAA4C207850C850088809040A02
+8058:0020FC2049FC492479FC492449FC78004BFE48804D0079FCC804080408280810
+8059:0020FC204BFE482079FC48204BFE780049FC49044DFC7904C9FC090409140908
+805A:7F00227C3E0422283E1023A8FE44020000F87F0009041188635005201918E106
+805B:0020FF4024FE24923C9224FE24923CA224FE24482E88F5FE4408040804080408
+805C:0020FF10241025FE3D02265424883D04240024FC2E20F4204420042005FE0400
+805D:0014FC12481049FE7810481049D27952495249544DD47808C8CA0B1A08260842
+805E:00007C7C44447C7C44447C7C40044FE4444447C4444447C444745FC440544048
+805F:20003E7C4844FF441444227C40007FFC08200FE008200FE0083EFFE000200020
+8060:0084FF48240024FC3C48244824483C4825FE24482E48F4484448048804880508
+8061:0090FC90490849487A444C9249087BFC484448204CA47A82CA8A0A8A0C780800
+8062:0020FF1024FE24823D04240024FE3C10241024902E9EF490449004D0053E0600
+8063:0000FF2024CE24823C8224EE24823C8224FE24282E28F4284448044A048A0506
+8064:0040FC204BFE480079FC490449FC78004BFE4A024DFC7820C820082008A00840
+8065:0004FC1E4BE0482079FC4924492479FC48204BFE4E227A2ACAFA0A020A0A0A04
+8066:0080FC8048FC49547AD448B4492C7A44489449084C4078A4CAAA0A8A0C780800
+8067:0010FDD448584A52798C488849047AFA482048204DFE7820C850088809040A02
+8068:0108FD4A4A524B9C79084A524BDE7842488848884FFE7888C888090809080A08
+8069:0020FC2049FC492479FC48204BFE780049FC49044D247924C924085008880B04
+806A:0088FC48485049FC79044904490479FC482048104C547942C942094A0A380800
+806B:0108FD4A4A524B9C79084A524BDE7842482048204FFE7820C850088809040A02
+806C:0090FC8849044A427C8849FC480478004BDE48424E52794ACA520842094A0884
+806D:0010FF2024FE24923C9224FE24923C9224FE24202E24F45A445E04900492050E
+806E:0084FC844908494A7A524B9C48847908494A4BDE4C427800C954092A0A2A0800
+806F:0108FD4A4A524B9C79084A524BDE784248904A924E927B9EC890089008900910
+8070:0020FC4049FC4924797C498C49547924495449FC4C407824CAA20A8A0C880878
+8071:08207F20087E7E4408A4FF2810101E2822447FFE88200FE0083EFFE000200020
+8072:08007F7808483E4800863E782A483E304048FFFE08200FE0083EFFE000200020
+8073:11102110CAA814443278D24015FC18007FFC08200FE008200FE0083EFFE00020
+8074:0020FC204BFE4840784049FC4954795449FC48404C247AA2CA8A0C8808780800
+8075:0020FDFC492449FC78204BFE480079FC490449FC4D0479FCC90409FC08880904
+8076:7FFC08200FE008200FE0083EFFE000207EFC24483C7824483C78264EFDF80408
+8077:0110FC944BD248127A5049904FFE78104BD24A524E547BD4CA4A0A4A0BD60822
+8078:0080FCF849084BFE7944499249FE7900497C49004D7C7900C97C0A440A7C0C44
+8079:0040FC204BFE4A227954494A4A3A780049FC49544FFE7800C9FC082008A00840
+807A:0040FC204BFE4A02791049DE4A527D544A8849744E0279FCC82009240A220860
+807B:42043FD88A904F9E2A945FD482247FFC08200FE008200FE0083EFFE000200020
+807C:002078200BFE1020FDFC4954495479FC48007BFE48405C24EAA24A8A0C880878
+807D:0020FC204BFE782049FC79544954F9FC0800FBFE284078242AA2FA8A0C880878
+807E:08403E7C1440FF7822083E782242263E00007FFC08200FE0083EFFE000200020
+807F:010001003FF80108FFFE01083FF8010001003FF801000100FFFE010001000100
+8080:010001003FF80108FFFE01083FF8010801000100010001000100010001000100
+8081:010000803FFC20043FFC20802FF820883FFE20882FF820804FFC4080BFFE0080
+8082:00200020FDFC202423FE3C2445FC4420642095FC0820082013FE202040208020
+8083:010001003FF80108FFFE01083FF8010021082548252825282928410841088108
+8084:40204C2070FC442445FE3C2440FC7C20902011FCFE20102029FE242044208020
+8085:01003FF80108FFFE01083FF8054025483D7821083FF821083D78254845488108
+8086:00203E2020FC20243DFE202420FC3C20202021FCFE20202025FE4220FE204220
+8087:08403E7E22A83E10206E41009FF00110FFFE01101FF001003FF80100FFFE0100
+8088:08243E3E22E83E12202A41469FF00110FFFE01101FF001003FF80100FFFE0100
+8089:0100010001007FFC410442844444492451044104428442444444480440144008
+808A:00003E0022FC220422083E102220222022403E4022802282228242824A7E8400
+808B:00203E202220222022FE3E222222222222223E2222422242224242824A948508
+808C:00003CF02490249024903C902490249024903C902490249224924512550E8A00
+808D:00403C402440244025F83C482448244824483C482448244A248A448A55068A00
+808E:00007FFE4002800400001FF0101010101FF0101010101FF01010101010501020
+808F:0600010002800C603118C1063FF8228824482928210822882448200820282010
+8090:00403C40248024FE25003E0024FC240824103C20244024802502450254FE8800
+8091:00403C40248024FC25043E042404250424843C44244424042404440454288810
+8092:00403C402440244025F83C482448254824C83C482468245A248A448A55068A02
+8093:02000100FFFE100010001FF800001FF010101FF010101FF01010101010501020
+8094:00203C2024202520252C3D34256427A425243D34252825222522450254FE8800
+8095:00003C0024FC242424243CA424A424A424A43D24242424442444448455288A10
+8096:010021081110092001003FF8200820083FF8200820083FF82008200820282010
+8097:00403C402440244027FE3C882488248824883D08249024502420445054888B04
+8098:00083C082408240825FE3C082408240824883C48244824082408440854288810
+8099:1FF0101010101FF000003FF8200820083FF8200820083FF82008200820282010
+809A:00203C202420242024203C2025FC242024203C20242024202420442057FE8800
+809B:00003C0025FC242024203C202420242024203C20242024202420442057FE8800
+809C:00043E042208221022203E442204220822103E2222422204220842104A2084C0
+809D:00003DFC2420242024203C20242027FE24203C20242024202420442054208820
+809E:00403C242524250425043C882488248824503C50242024202450448855048A02
+809F:00003CFC2400240024003DFE2440244024803CFC240424042404440454288810
+80A0:00003DF82410242024403C8025FE249224923C92251225222622444254948908
+80A1:00003CF82488248824883D06260025FC24843C84244824502420445054888B06
+80A2:00203C20242025FE24203C20242025FC24843C88244824502420445055888E06
+80A3:00203C202450245024883D442622242024003DFC240424082408441054108820
+80A4:00203C202420242025FC3C202420242027FE3C20245024502488448855048A02
+80A5:00003DFC2524252425243D24252425FC25043D00250025002502450254FE8800
+80A6:00103C502450245034882C88250426FA2C483448244824482488448855288A10
+80A7:00003C0025FE241024103C202420246824A43D22262224202420442054208820
+80A8:00203C20242025FC24203C20242025FC24203C20242027FE2420442054208820
+80A9:010000801FF8100810081FF8100017F8140817F8140827F82408440884280410
+80AA:00403C20242025FE24403C402440247C24443C44244424442484448455288A10
+80AB:0040784048404BFC48407A484A484A484A487BF84848484048424842483E9800
+80AC:00403C502448244824403DFE2450245024503C502490249024924512550E8A00
+80AD:00203C20242025FE25223D222522252225523D4A258A250225024502550A8904
+80AE:00403C20240025FC24003C0024F0249024903C902490249224924512550E8A00
+80AF:0100010011F811001100FFFE00001FF010101FF010101FF01010101010501020
+80B0:00203C282424242424203DFE2420242024203C50245024502488448855048A02
+80B1:00407840484048404BFE7840488048904890792049204A484A444C8449FE9882
+80B2:02000100FFFE080010103FF800081FF010101FF010101FF01010101010501020
+80B3:00803C80248024FC25543E542454249424943D24262424442444448455288810
+80B4:18180660018006603A180200FFFE04000FF818082FF848088FF8080808280810
+80B5:00043C0E24F0248024803C8024FE248824883C88248824882488450855088A08
+80B6:00103D102510251225123D1425D8251025103D102510251225524592550E8800
+80B7:00403C402440247C24843C882520242024203C50245024502488448855048A02
+80B8:00103C902490248825083D042624242224203DFE242024202420442054208820
+80B9:00483C482484248425023E0025FE244024803CFC240424042404440454288810
+80BA:00203C20242027FE24203C2025FC252425243D24252425342528442054208820
+80BB:010001F8010001003FFC200440081FF010101FF010101FF01010101010501020
+80BC:00887888488848884BFE7888488848884FFE7888488848884888490849089A08
+80BD:00203C202420242024203DFE2420242024203C5024502450248844C855248A02
+80BE:040025F824882450242024D8270604001FF010101FF010101FF0101010501020
+80BF:00203C202420242025FC3D242524252425243DFC252424202420442054208820
+80C0:00803C842484248824903CA0248027FE24A03C9024902488248444A254C08880
+80C1:00807880488048804BF0789048904A984A947C9248924890491049104A509C20
+80C2:00203C20242025FC25243D24252425FC25243D24252425FC2524442054208820
+80C3:00003FF821083FF821083FF800001FF010101FF010101FF01010101010501020
+80C4:010001003FF821083FF821083FF800001FF010101FF010101FF0101010501020
+80C5:00203C202520252025FC3D202620242025FE3C20245024502488448855048A02
+80C6:00003C0024FC248424843C8424FC248424843C8424FC24842400440055FE8800
+80C7:00503C50245025FC24543C5425FC255025503DFE24522452245A449454908910
+80C8:00503C482448244025FE3C402440247C24A43CA424A825282510462854448882
+80C9:00103C10242024FC24843C842484248424FC3C84248424842484448454FC8884
+80CA:00803C80250025FC36042C0425E425242D24352425E425242404440454288810
+80CB:00203C2024202420243E3C202420242025FC3D04250425042504450455FC8904
+80CC:048004987CE004841C84E47C40001FF010101FF010101FF01010101010501020
+80CD:0008781C49F049504950795049504950495079484948496849544A744A529C00
+80CE:00203C202420244024483C8425FE248224003CFC248424842484448454FC8884
+80CF:00203C20242E25F025203D20252025FE24223C6224A2252A2624442054208820
+80D0:00203C202524252435242D2425FC24202C203524252425242524452455FC8804
+80D1:00003C0024FC248424843C842484248424FC3C84240024482444448454828902
+80D2:00003CFC2484248424843CFC248024A024A23CA424B824A024A24522551E8A00
+80D3:00003DFC2420242025243CA424A8242027FE3C20242024202420442054208820
+80D4:088008882E9028E028842E84F07C01003FF82288244829282108228824482018
+80D5:00443C442444248424BE3D84268424A424943C94248424842484448454948888
+80D6:00203C20252424A424A83C2025FC242024203C2027FE24202420442054208820
+80D7:00203C202450248825043E122420244025883C10242024442588441054608B80
+80D8:00203C10241025FE24203C202444248425F83C1024202444248245FE54828800
+80D9:00803C80248024FE25403D402640247C24403C402440247E2440444054408840
+80DA:00007BFC482048204840784048D049484A447C4448404840484048004FFE9800
+80DB:00003DFC2524252425243DFC2524252425243DFC252424202420442054208820
+80DC:002078204920492049FC79204A204820482079FC48204820482048204BFE9800
+80DD:00043C1E25F0251025103D10251025FE25103D1025102508250A454A55A68912
+80DE:0080788049FC49044A047DF449144914491479F4490449284912490248FE9800
+80DF:00003CFC248424A424943C84248427FE25043D442524250425FE440454288810
+80E0:00203C20242025FC24203C20242027FE24203C2024402448248445FE54828800
+80E1:0800087C084408447F44087C08443E442244227C224422443E84228401140208
+80E2:00003C0025FE240824083DE82528252825283D2825E825282408440854288810
+80E3:0080788048FE49004A207920492C49744BA47924493449284922490248FE9800
+80E4:01002208244827882108224827C8200827C8244827C8244827CA444A444A84C6
+80E5:7FFC0104110011F81100290047FE80001FF010101FF010101FF0101010501020
+80E6:00203C20242025FC25243D242524252425243FFE242024502450448855048A02
+80E7:00907888488848804BFE78A048A048A448A478A84928493249224A624A9E9C00
+80E8:0040784048404FFE4880792049204A204BFC7820492849244A224C2248A09840
+80E9:00403C402440247C24403C40244027FE24403C40245024482444444054408840
+80EA:00203C20243C242024203CFC2484248424843CFC248424802480450055008A00
+80EB:000079FC480848104830784848844B02480079FC48204820482048204BFE9800
+80EC:10001000FEFC2244642818102428C2C601003FF8228824482108228824482018
+80ED:00003DFC2504252425243D2425FC252425243D54254C258C2504450455FC8904
+80EE:0080788048FC49084A90786049984E26482079FC48204A204BFE482048209820
+80EF:00203C2025FC245024883D0426FA240027FE3C40248025FC2404440454288810
+80F0:004078404FFC48404BF878484BF84A404BFC7844485448A848A049104A089C06
+80F1:004078444A444948495078404FFE48904890789048904892491249124A0E9C00
+80F2:004078204BFE48404890789049244BE448447848488849104A30484848849B04
+80F3:00403C402478248825503C202450248825063CF8248824882488448854F88888
+80F4:00007BFC4A044A044AF47A044A044AF44A947A944A944AF44A044A044A149A08
+80F5:00003DFE2420244024883D0425FE242224203C2025FE24202420442057FE8800
+80F6:0040782048204BFE4800788849044A0248887888485048504820485048889B06
+80F7:10001FFC20045454939414541FF400081FF010101FF010101FF0101010501020
+80F8:01007900490049FE4A027A024D1248A24A4A7AAA4B1A4A0A4BFA480248149808
+80F9:00003DFC2420242024403DFC2554255425543D54255425542554454455148908
+80FA:0040782048204BFE4A027C4448404BFE48887888490848D04820485048889B04
+80FB:00807880493C4A004C807880497E4B084D087908490849084908490849289910
+80FC:00843C48240024FC24483C482448244825FE3C48244824482448448854888908
+80FD:104024444248FF70014000427E42423E42007E44424842707E4042424A42443E
+80FE:082008287F240820FFFE002008247F24492455286B2849105512632A45464282
+80FF:00203C2025FC242024203C2027FE240024203C2025FC24202420442057FE8800
+8100:1FC000447D88055009203518C2063FF800001FF010101FF010101FF010101030
+8101:00503C502450255234D42C58245024582CD43552245024502492449255128A0E
+8102:01003D04253825C025023D0224FE240025FC3D04250425FC2504450455FC8904
+8103:00803C8024F8250826103DFC2524252425243DFC250025002502450254FE8800
+8104:0040784048404BFE4880789048904912495279544A904A284C28484448849902
+8105:02001FF00410085010207EFC12242A5444881FF010101FF010101FF010101030
+8106:00403C4024FC250426083DFE2500257C25443D442554254825424542553E8A00
+8107:0040784049FC48444884788449284A1049087BDE494A494A494A4A524B5A9CA4
+8108:0004781E49E049004906797849504950495279544948494849444A544A629C40
+8109:00407820481049E0482278344BB848B048A878A8492849244A244C2248A09840
+810A:2108111009201290244808203FF8C82608200FE0082008200FE0082008A00840
+810B:00001FF00410045008207EFC12442A9445081FF010101FF010101FF010101030
+810C:00803C8024FE251026103C1024FC249024903C9027FE24102410441054108810
+810D:002078204850488849047A0248F8480048007BFE48204840488849044BFE9902
+810E:000479884850482048507888492448204BFE782048A848A449224A2248A09840
+810F:00207810481049FE4900791049104910497C79104910491049104A104AFE9C00
+8110:004078204BFE490448887850482048D84B067888488848884888490849089A08
+8111:0040782048204FFE4800780048904A544A247A244A544A944A044A044BFC9804
+8112:00203C20252424A424A83C20242027FE24703CA824A825242524462254208820
+8113:0020782048204BFE4A427C4448A048A249A47A984C904888488448A248C09880
+8114:02000100FFFE04401450254841043FF822882448292821082288244820082018
+8115:00803C8024F8250826103DFC2524252425243DFC245024502490449255128A0E
+8116:002078204BFE482048207BFE4A024C0449F8781048204BFE4820482048A09840
+8117:00803C8024FC255426543CA42524264424943D0825FC25042504450455FC8904
+8118:004078204BFE4A024C0479F8480048004BFE789048904890491249124A0E9C00
+8119:00283C242424242027FE3C20252024B224B43C6824A825242622442054A08840
+811A:01007900491E4B924912791249124FD2491279124A1A4A944FD04A5048109810
+811B:00007BFC480049244A487C904A48492448007BFC48404840484048404FFE9800
+811C:00003DFE2410242024FC3C84248424FC24843C8424FC24842484448454FC8884
+811D:004078204BFE480049F87908490849F848007BFC480848304820482048A09840
+811E:00203C2024A824A824A83D742622242024203DFC242024202420442057FE8800
+811F:00043C1E25E0242225123C942480240825FE3C08248824482448440854288810
+8120:0004780E4BB8488848887928492E4BA848A87AA84AA8493E49004A804C7E9800
+8121:000078064BB8488848887908493E4B8848887A884A88493E49004A804C7E9800
+8122:00803C8024FE250026FC3C8424A4249427FE3C842524251425FE440454288810
+8123:3FFC20002FF820003FFC24482430260E2FF828082FF848084FF8880808280810
+8124:000079FE49004900497C7900490049FE495079524954494849484A444A529C60
+8125:0020782048204BFE482078204924492449247AAA482048504850488849049A02
+8126:00107814481248104BFE7810489048504848780848884AA84A9A4AAA4C669802
+8127:00403C402488250437FE2C02248825442E4234F8258826502420445055888E06
+8128:00203C2027FE242024203DFC2524252425FC3C20247024A82524462254208820
+8129:1080108011F821082A906C60A9982E0629F8290829F8290829F8210821282110
+812A:00C23C342418246425823C2025FE245024903DFE26922492249A449454108810
+812B:00107890488849084A047DFA49084908490879F848904890489049124A129C0E
+812C:0008783C4BC048044A44792848004BF8481078204FFE48204820482048A09840
+812D:000079FC49044904490479FC480048004BFE7820482049FC482048204BFE9800
+812E:0008783C4BC048444A247928490048404BFE788849084B904860485049889E04
+812F:004878444BFE484048407BFC4A444A444BFC7A444A444BFC4A444A444A549A08
+8130:00003DFE2400240024FC3C842484248424FC3C00248424442448440055FE8800
+8131:010478844888481049FC79044904490449FC785048504890489249124A0E9C00
+8132:00007BFC4A044A044BFC7A004A204A224BB27AB44AA84AA84D244D244AA29840
+8133:00427A2249244904480878004A0A4A8A4A527A224A524A8A4B0A4A024BFE9802
+8134:00003DFE2410242024683CA42522242024003CFC248424842484448454FC8884
+8135:000079FC4904490449FC7800480049FC482078204BFE48204850488849049A02
+8136:000079FC49044904490479FC482048204BFE7A224A524A8A4B0A4A024A0A9A04
+8137:004278E24B82488A488A788A4FEA488A498A79CA4AAA4A824C824882488A9884
+8138:0020782048504850488879044AFA480048447824492448A8488848104BFE9800
+8139:00003CFC248024F824803CF8248027FE25403D24252825102508454455828900
+813A:004078204BFE48004888788849544A22480078204BFE48204820482048209820
+813B:002078204BFE482049FC78244BFE482449FC78204920493E49204AA04A7E9C00
+813C:00007BFE482048204BFE7A224A224B324AAA7AAA4B764A664A224A224A2A9A04
+813D:00503C48248024FE25903E9024FC249024903CFC24902490249044FE54808880
+813E:004078804BFC4A244A247BFC4A244A444BFC789049104FFE4810481048109810
+813F:00203C2027FE242024203DFC2420242027FE3C4024A425A82690448854C68880
+8140:00203C202450248825043EFA240025FC25543D5425FC2554255445545504890C
+8141:0084788C49084FBE49087908490849084FBE79084908490849084A08AA089408
+8142:00003DFC2524252425FC3D24252425FC24203FFE247024A82524462254208820
+8143:00203D2424A8242025FC3C4027FE248825043EFA2488248824A844925482887E
+8144:00083C3C25E0242027FE3CA824A824A827FE3CA824A827FE2420442055FC8800
+8145:00203CA224A2252424503C882704242224203CA424A425282450448855048A02
+8146:00507850485049FC49547954495449FC4954795449544BFE4800488849049A02
+8147:001C79E0482048204BFE78A849244A4248407BFE4888490848D0483048489984
+8148:002078204BFE482049FC78204BFE480049FC790449FC490449FC490449149908
+8149:000078404B9C4A044A047B9C4A044A044BFC789048904890489049124A129C0E
+814A:0088788848884BFE488878884FFE480049FC7904490449FC4904490449FC9904
+814B:008078404FFE492049207A3C4A444E644A947B484A484A304A204A504A889B06
+814C:004078804BFC49104A487C464BF84A484A487BF84A484A484BF848424842983E
+814D:002078204850488849447A2249F848084850782048A44A824A8A4A8A4C789800
+814E:7EFC48447E4442287E1048287EC600001FF010101FF010101FF0101010501020
+814F:00007BDE4842494A4884794A4A524C2048007BDE48524952489449484A549C22
+8150:00803FFE2208220825FE2C883448245820802FFC29442AA4488449448A24080C
+8151:002078104BFE4A004A447A444A844ABE4B847AA44A944A944C844C8448949888
+8152:00003DFC2504250425FC3D10251025FE25103D10257C254425444544557C8A44
+8153:0090789048904F9E4890789048904B9C4890789048904F9E4890489048909890
+8154:0040782048204BFE4A027C9449084A04480079FC48204820482048204FFE9800
+8155:004078204BFE4A024D04790049DE4A524A527B524C9A4894491049124A129C0E
+8156:002078204BFE482049FC792449FC492449FC7820487048A849244E2248209820
+8157:00203C2025FC252425243DFC2524252425FC3C0027FE24882488448855088A08
+8158:00007BFE4A024A024BFE7A224A224AFA4A227A324A2A4BFE4A024A024BFE9A02
+8159:004078204BFE4A02480079FC480048004BFE7820492849244A224C2248A09840
+815A:004078204BFE4A024C0478004BFE482048207920493C49204AA04A604C3E9800
+815B:00003DFE2502250225FE3D0025FC252025443DFE2512251025FC4510561089FE
+815C:00883C8827FE248824883CF82488248824F83C2027FE247024A8452456228820
+815D:00003DFC2420244025FC3D542554255425443D2C242027FE2450448855048A02
+815E:00403C7C248424F824083DFE244024A425383C58249425342454449255508820
+815F:00403C2025FE250226043DFC2440248825FC3C24242025FC2420442057FE8800
+8160:002078204BFE482049FC78404BFE488849047AFA482049FC4820485048889B04
+8161:000079FC4904490449E4792449244BFE4A027AFA4A8A4A8A4AFA4A024A0A9A04
+8162:01FC7924492449FC4924792449FC482048207BFE4A224A2A4AFA4A0A4A029A06
+8163:0040782049FC4800488878504BFE4A224C2479FC492449244934492848209820
+8164:00203C1025FE240024843C4825FE240024FC3C84248424FC2484448454FC8884
+8165:00007BF84A084BF84A087BF848404A404BFC7C4048404BF8484048404FFE9800
+8166:009279244A4849244892784048804BFE4A027A8A4A524A224A524A8A4BFE9A02
+8167:004078A049104A084DF678004BC44A544A547BD44A544A544BD44A444A549AC8
+8168:00203D242524252425FC3C0027FE242024403DFC25542554255445545554890C
+8169:002078204BFE482048207BFE4A8A4A524AFA7A224A224AFA4A224A224A2A9A04
+816A:00007BFE4A2248204BFE782049FC492449FC792449FC48204BFE482048209820
+816B:00083C3C25E0242027FE3C2025FC252425FC3D2425FC242025FC442057FE8800
+816C:00003CFC2448243025FE3C522494251026303C2025FE247024A8452456228820
+816D:00003DDC2554255425DC3C0025FC240025FE3C8024FC24042404440454288810
+816E:000079FC4924492449FC7924492449FC4800784048244AA24A8A4C8848789800
+816F:00043C1E25F0251025103DFE2510257C25443D7C2544257C25444544557C8A44
+8170:00007BFE485048504BFE7A524A524BFE480078404FFE48884990486048D89B04
+8171:00107810487C4B1449FE79144A7C4A104F7C791049FE4D104A104B004CFE9800
+8172:00003DFC2524252425FC3D24252425FC24003FFE252025222514454855848902
+8173:00007A9E4A524A524D5279124A924A524C327BD24A5A4A544A504A504BD09A50
+8174:00203C2024A0252C25243D2425AC252425243DFC252424502450448855048A02
+8175:00007BDE4A424A424A427BDE4A004A3E4BD27A124A144BD44A084A144A249A42
+8176:00203DDC2514251425143DD42526250025DC3D14251425D42708450855148922
+8177:00003DFC240024F824883C8824F8240025FC3D24252425FC2524452455FC8904
+8178:00003CFC248424FC24843CFC240025FE24803CFE252A264A2492452254548888
+8179:00403C4024FE248025FC3E8424FC248424FC3C40247C24C42528441054688986
+817A:0040788049FC490449FC790449FC482048327BB448A8492849244A244CA29840
+817B:001878144FFE48104BD078104BF048104BE87A284AA84AA84AAA494A4A269C22
+817C:00003DFE2420244025FC3D542554257425543D54257425542554455455FC8904
+817D:00003CF82488248824F83C88248824F824003DFC255425542554455457FE8800
+817E:0248794849504FFC48407FFE49104A084DF67810491049FC48044BE448149808
+817F:00007A7C49444944487C78444F44497C4950794A49444954496249424A809C7E
+8180:004078204BFC490848907BFE4A024C4448207BFC488048F84888490849289A10
+8181:00883C50240025FE24503DFC245427FE24543DFC245024D82554465254508850
+8182:2040FEFE21003C1C24E0449454A888C61FF010101FF010101FF0101010501020
+8183:00003CF824A824A824D83C8824F8240024003DFC255425542554455457FE8800
+8184:00A03D2C2524252425AC3D24252425FC24203DFC248824502420445054888B06
+8185:00203C1025FE2510257C3D1425FE2514257C3D10257C254425444544557C8A44
+8186:002078204BFE482049FC78204BFE4840488879F048244BFE482249244AA29840
+8187:00107A20497C49444844787C4B404940497C79444944497C49444A804C7E9800
+8188:00007BFE480049FC4904790449FC48004BFE7A8A4A524BFE4A224A224A2A9A04
+8189:01043C842488240027FE3C002488250426023DFC255425542554455457FE8800
+818A:002878244BFE482049FC792449FC492449FC792448084BFE4888484848489818
+818B:08202AA44D28145022887FFE40029FF410101FF010101FF01010101010501020
+818C:00203D2424A8255424883D0426FA248824883CF82488248824F8448854888898
+818D:00203C4025FC250425543D242554250425FC3C00251225D4251845525592890E
+818E:001E7BE0492248944840788849F0482048C479FE482248204BFE485048889B06
+818F:01007FFC08200FE000007FFE48228FE400001FF010101FF010101FF010101030
+8190:2040FEFE21003C1C24E0449454A888C601003FF8228824482108228824482018
+8191:004078204BFE4A024C1479E04900490049FC791049104FFE4800489049089A04
+8192:00007BFE4A004A7C4A447A444A7C4A004AEE7AAA4AAA4AAA4AEE4A004BFE9800
+8193:010079FC4A004DF8490879F8490849F848007FFE49004BFC4CA449244A549888
+8194:004078204BFE4A504A507BFE4A524A524BFE7A004A924AD44A984A924AD29C8E
+8195:000077FE542A542657FE742257AA56AA57AA74325596562E5446548257FEB402
+8196:00207A20497C48A4481878E64B10497E4910797C491049FE491049104AFE9C00
+8197:00207A224BFE4890488879FE4B104D1049FE7910491049FE4910491049FE9900
+8198:00007BFE485049FC4954795449FC480049FC78004BFE482048A849244AA29840
+8199:00007BBE48A248A248BE7B884A084A3E4A2A7BAA48AA48BE4888488A4D7E9A02
+819A:010001FC01003FFE20022FFC28842FFC28842FFC240827F8240847F844088418
+819B:0020792448A84BFE4A0278F84888488848F87820482049FC482048204BFE9800
+819C:008878884BFE4888480079FC490449FC490479FC48204BFE4850488849049A02
+819D:002078204BFE487048AC7B224850488849247A22492448A849244A2248A09840
+819E:00203DFE242025FC25243DFC252425FC24223DFE240825FE2508448854288810
+819F:004078204BFE482048487AF249244A5248F8780848204BFE4820482048209820
+81A0:00007BDE48424A52494A7A52482848C44B1278604988483249C4481848609B80
+81A1:0020792448A849FC48407BFE488849044BFE7D0449FC490449FC490449FC9904
+81A2:002079FC49244BFE492479FC482049FC492479FC48404BFE488849D048709B8C
+81A3:004078204BFE4A8A49047BFE4840488849FC7824482049FC482048204BFE9800
+81A4:000079FC48204BFE4A2279AC482049AC480079FC480449FC4804480449FC9804
+81A5:10141010FDFE11107DD43948554A929611223FF8228824482108228824482018
+81A6:0020792448A84BFE48A879244A224904490479DE4A444D54489E49044A049C04
+81A7:00203DFC2488245037FE2C0025FC25242DFC352425FC242025FC442057FE8800
+81A8:008278824FF4488848807BE248024BE44A287A204BE04A22494248744F889A10
+81A9:00147BFE48104BD048107BD048104BD04A507BD04A504BC84A4A4BCA49869A42
+81AA:0040782049FC488848507BFE4A224C2449FC7924492C482049FC490449FC9904
+81AB:00203C2025FC242025543C88250426FA24883CF8248824F8242044A855248860
+81AC:00387BC048784BC048787BC4483C480048C67B3849CE4F3849CE4F38494A9986
+81AD:00203DFC252425FC24203FFE240025FC25043DFC250425FC250445FC54888904
+81AE:0020782049FC48204BFE79084B9C490849887E3E48004BFE4890489049129A0E
+81AF:00107BD248544948488A79044AFA4C0049FC7904490449FC490448884FFE9800
+81B0:003C7BE0492448A84BFE78A849244A0249FC7924492449FC4924492449FC9904
+81B1:011078944BD248124A5079904FFE48104BD27A524A544BD44A4A4A4A4BD69822
+81B2:00A0789049FE49104B107DFE4910491049FE7910491049FE49004AA44A529C52
+81B3:008878504BFE482049FC78204BFE492448A87BFE480049FC4904490449FC9904
+81B4:00803C8025FE275425543D5427FE255425543D5427FE24002554452A562A8800
+81B5:00883C8827FE248824203FFE2488248825543E22242027FE2420442054208820
+81B6:00007BDE4A524BDE4A527BDE4A024AFA4A227A724A224A224AFA4A024A0A9A04
+81B7:0280724E54EA55AA59AA7EEA52AC54AA55EA7F8A528A52AA54AC54E858A8B008
+81B8:002079FE4C404AFC49107AFE48004EFC4A847AFC4A844AFC4A844A8C4D0098FE
+81B9:00203DFC2420248827FE3C8825FC250425FC3D0425FC250425FC448855048A02
+81BA:00803FFE225024FC2D9036FC249024FC200027F8240827F8440847F884080418
+81BB:00207BFE48004BFC4A047AF44A944BFC480079F8490849F8490849F848009BFE
+81BC:00007A7C49444974485478544EFE4A824ABA7AAA4ABA4A824A8A4A844D0098FE
+81BD:00803CF8250827FE25443D9225FE2500257C3D00257C2500257C4544557C8A44
+81BE:00203C502488257426023DFC252425AC25243DFC240024F8248844F8548888F8
+81BF:00503DFC255425FC25543DFC240025FE25003D7C250025FE2550455455488A66
+81C0:7E7842487E4854867E7854487E3094CE62001FF010101FF010101FF010101030
+81C1:00207BFE4A884A504BFE7A504AFC4A544BFE7A544AFC4A504AD84D544E529850
+81C2:3E1022FE3E4420287EFEA2103EFC221000001FF010101FF010101FF010101030
+81C3:004078204FFE48284A247A7E4CC84F48497E7A484CC84F7E49484A484C7E9840
+81C4:0040787C48404BFE4A427A784BC44A3C4A007BFE4A404BA44A584DB44C5299B0
+81C5:00003DFC2554255425FC3C8025FE264225F23D52255225F2244A47FA540A8804
+81C6:0040782049FC488848507BFE480049FC490479FC490449FC48204A944A8A9C7A
+81C7:00A0789049FE4B2049FC792049FC492049FE79004BDE4A524A524A724A029A06
+81C8:00887BFE488849FC490479FC490449FC488079FE4A224D52490249FA480A9804
+81C9:00203C202450248825043EFA2400240025DC3D54255425DC2488448855548A22
+81CA:00F83C88248824F824003DDC2554255425DC3C2027FE247024A8452456228820
+81CB:7E7842487E4854867E7854487E3094CE63003FF8228824482108228824482018
+81CC:008878884FC848BE48887BC8481C4BD44A547A544BD44A48498848D44F149A22
+81CD:0080704057FC511050A47F58555455525B587000520853F8520853F85208B408
+81CE:03DE78424A52494A4A5278204BFE4888488879544A2248204BFE482048209820
+81CF:004078204BFE4A0249FC79484A5049FC4B0479FC490449FC490449FC48889904
+81D0:001C3DE0242027FE24203DFC25AC257425FC3C2025FC242027FE440055548A2A
+81D1:000079FC48204BFE4A2279AC482049AC48007BFE482049FC495449544954990C
+81D2:00887BFE48A8489049FE7B2049FC492049FC792049FE49004BFC488848709B8E
+81D3:0090709057FE5094500A77FE540855E8554A75EA552A55EA554C55EA5416B862
+81D4:03DE7A924BD24A544BC87A944BE2480049FC790449FC490449FC490449FC9888
+81D5:004078204BFE4A504BFE7A524BFE4A004A947AD84A904AD24A8E4C0049549A2A
+81D6:2FEC48244BA4682C4BA46AAC4BA4FFFE10103FF8D0161FF010101FF010101030
+81D7:00207BFE4A8A49FC488879FC490449FC490479FC490449FC4890489449129A0E
+81D8:01247A48492448004BFC7A944A644A944BFC7A484B684A484B6A4A4A4A469B62
+81D9:0110711057FC511051F0720852EA56AC52A872AA56EA5A06500052A45252B452
+81DA:0040787C48404BFC4A447BF04A444AFC4AA87AF84AA84AF84A004DFC49549BFE
+81DB:01FC78204BFE4A224DAC782049AC489049FE7B204DFC492049FC492049FE9900
+81DC:0108752857BE594857BE731855AA5946500073F852085248524850B05108B604
+81DD:0100FFFE20003FF800003FF820083FF8054077DC555477D4511C7FF65556B922
+81DE:03DE7A524BDE4A524BDE7A524BDE489049FE79104BFE4D1049FE491049FE9900
+81DF:0090709057FE5094500A71FE550857E8514A71EA5F2A55EA554C59EA5216B462
+81E0:210447C88812F3BC20084B92F83E0380AAAAABAA01003FF82288244821082298
+81E1:2450FF4824FE3D9008FC7E9052FC7E9024FE4280BFF822882448292822882458
+81E2:052877BE594857BE531875AA594653FC520473FC520453FC520453FC5108B204
+81E3:00003FFC2100210021003FF820082008200820083FF82100210021003FFC0000
+81E4:00007E0048FC484448447E444244422842287E2848104810482848487E840102
+81E5:00207E204820482048207E204220422042507E5048504850484848887E840102
+81E6:0000FE7E1248124812487E7E42424242424242427E7E124812481248FE7E0000
+81E7:002800245FFE502057A07520152017A4F4A454A857A85510951227AA20464082
+81E8:00407E40487E488049007E7C42444244427C7E0048EE48AA48AA48AA7EEE00AA
+81E9:0000FEFE12907EFC42847EFC1290FEFE02007FFC04401830E44E044008401040
+81EA:0100020004001FF01010101010101FF0101010101FF01010101010101FF01010
+81EB:0820082010207F20412041207F20412041207F204120412241227F22411E0000
+81EC:020004001FF010101FF010101FF010101FF00100FFFE054009203118C1060100
+81ED:020004003FF820083FF820083FF820083FF801200110FFFE028004401830E00E
+81EE:02001FF010101FF010101FF010101FF0000000FC7F0011101110292845440100
+81EF:02001FF010101FF010101FF010101FF021081110092011102108FFFE01000100
+81F0:02001FF010101FF010101FF010101FF00000FFFE08401F48625014621842E03E
+81F1:02001FF01490125011301FF001007FFE4A2291143FF8040007F0081010502020
+81F2:102020207E7C42847F0842FE7E8042BC7EA410A4FEB418A834A25322911E1200
+81F3:00007FFC02000400082010103FF80008010001003FF8010001000100FFFE0000
+81F4:0040FE401040208028FE4508FE881288108810507C50102010501E88F1044202
+81F5:0040FE401078208829504420FE501288110610F87C88108810881E88F0F84088
+81F6:0020FE20102021FE28404440FEBC1284118812887CFE108810881E88F0A84090
+81F7:084008487F4408440840FFFE00407F44104422447F28092A3E12082A0F46F082
+81F8:0000FEFE1010202028444482FEFE1212101010107CFE101010101E10F1FE4000
+81F9:0028F8242024402053FE8A20FA242A2423A4FAA822A822903A92E5AA44460882
+81FA:0100FFFE01003FF800001FF010107FFE40029FF408201FF001003FF80100FFFE
+81FB:0020F82023FE402051FC8840FBFE28882134FAE2202021FC3870E0AC43220020
+81FC:00000400387820082008200820083C78200820082008200820083FF820080000
+81FD:040004000FF01010202040408C003078200820083C782008200820083FF82008
+81FE:010005003978210821083D782108210821083FF821080280044008203018C006
+81FF:001001F83F000100FFFE01000D003178210821083D782108210821083FF82008
+8200:00FC7F0002082108111010200C003078200820083C782008200820083FF82008
+8201:060038F8200820083EF8200820083FF808200820FFFE08200820102020204020
+8202:010001007FFC01003FF80200FFFE044008203418D87610101C7010101FF01010
+8203:060038F8200820083EF8200820083FF810001FF820003FFC0004492484940008
+8204:060038F8200820083EF8200820083FF810003FFC400489242494249440280010
+8205:3E7820083C7820083FF800001FF011101FF011101FF002007FF8040818286010
+8206:1100611C47C44204751C47C4410477DC41044104FFFE00000820101020084004
+8207:0A003238238822083A38238820883AB822882288FFFE00000820101020084004
+8208:00002FEC48244BA4682C4BA44AA46AAC4BA44824FFFE00000820101020084004
+8209:0A0033B822083BB820883AB82288FFFE082011102FE8C1061FF0010001000100
+820A:0820FFFE09201FFC30805FF890801FF810801FFC02001C7810081E7810081FF8
+820B:2FEC48244BA4682C4BA46AAC4BA4FFFE80021FF010101FF010101FF01010FFFE
+820C:001000F83F0001000100FFFE0100010001001FF010101010101010101FF01010
+820D:01000280044008203018CFE6010001003FF8010001001FF0101010101FF01010
+820E:01000280044009203118CFE6010001003FF8000000001FF0101010101FF01010
+820F:04040E04784408440844FF44084408443E4C22542264224422043E0422040004
+8210:08041C1E71F011101110FD10111011FE7D10451045104508450A7D4A45860102
+8211:08201C20702011FC1124FD2411FC11247D24452447FE450445047D0445140108
+8212:100011F82808445082207C1013FE1022FE24102010207C20442044207CA04440
+8213:08001DFC710411FC1104FDFC108010807DFE464A444A449245227E4244940108
+8214:08001DFC7020102011FEFC50105010887D244622442444B244AA7D2A44A00040
+8215:08201CA270A211241050FC88130410227C2044A444A4452844507C8845040202
+8216:102810242BFE442082207DFC11241124FFFC112411247DFC452445247D24450C
+8217:102810242BFE542092207DFC11241124FDFC01247D2445FC452445247D24450C
+8218:1020101029FE450282007CF810881088FEF8108010807CFC448444847CFC4484
+8219:00F83F000100FFFE01001FF010101FF00C0C70701010FEFE10107C7C44447C7C
+821A:08801CF8710813FE1144FD9211FE11007D7C4500457C4500457C7D44457C0244
+821B:1010101010101E1012FE2210229052908A90049004FE08100810101020104010
+821C:007C3F800108108808907FFE481208101EFC221052900C9008FE101020104010
+821D:02003FF00410FFFE1110222011107FFE440288241FF001001FF021003FF80100
+821E:10003FFC4AA00AA07FFC0AA00AA07FFC101010103EFC4210149008FE3010C010
+821F:020004001FF01010121011101110FFFE10101210111011102010201040508020
+8220:080010003EFC222432242A242A24FE24222432242A242A44224442844B288610
+8221:080010003E7C221032102A102A10FE10221032102A102A10221042104AFE8400
+8222:102020207C204420652455245524FD244524652455245524452445FC54048800
+8223:104020247D244504650454885488FC8844506450542054204450448855048A02
+8224:080010003E78224832482A482A48FE68225832482A482A4A224A428A4A868500
+8225:100020007DFC4524652455245524FD2445FC6500550055004502450254FE8800
+8226:102020207C204420642055FE5420FC204420645054505450448844C855248A02
+8227:081010203E78224832482A482A48FE68225832482A482A4A224A428A4A868500
+8228:1004200E7CF04480648054FC54A4FCA444A464A854A854904510452856448882
+8229:101020907C904488648855245524FE224420644054485444448445FE54828800
+822A:104020207C0045FC6400540054F0FC90449064905490549244924512550E8A00
+822B:104020207C2045FE644054405440FC7C44446444544454444484448455288A10
+822C:080010783E48224832482A862A00FEFC224432442A282A28221042284A448582
+822D:101021107D1045126512551455D8FD10451065105510551245524592550E8800
+822E:102020107C1044FE648254825482FCFE44826480548054804480450055008A00
+822F:102020207C20442065FC55245524FD24452465FC552454204420442054208820
+8230:100021FC7D044504652455245524FD2445246554545054504490449255128A0E
+8231:102020207C504450648855045602FCF84488648854A8549044824482547E8800
+8232:082010203E50225032882B242A12FE1023FC32042A082A88225042204A108410
+8233:102020207C20442065FC55245524FD24452465FC552455244524452455FC8904
+8234:108020807C8044FE654055405640FC7C444064405440547E4440444054408840
+8235:082010103E1022FE32822A842A40FE44224832502A602A42224242424A3E8400
+8236:081010103E2022FC32842A842A84FE8422FC32842A842A84228442844AFC8484
+8237:102020107C1045FE642054205444FC8445F8641054205444448245FE54828800
+8238:100020007DFE4408640855E85528FD284528652855E855284408440854288810
+8239:080010783E48224832482A482A8EFF00220032FC2A842A84228442844AFC8484
+823A:100021FC7D244524652455FC5524FD24452465FC552454204420442054208820
+823B:102020207C3C4420642054FC5484FC84448464FC548454804480450055008A00
+823C:104820487C48444865FE54485448FC48444865FE540054484444448454828902
+823D:082010203E3C224432A82A102A28FED6221032FC2A102A9022FE42104A108410
+823E:100023FE7C50445065FC55545554FD5445546554558C55044504450455FC8904
+823F:102020207BFE4850688859044AFAF8004BFE4840688059FC4804480448289810
+8240:1008203C7DC04404654454A85400FDF84410642057FE54204420442054A08840
+8241:081010503E50227C32502A902A10FEFE220032002A7C2A44224442444A7C8444
+8242:104020407CFC44886550542054D8FF2644F8642054F8542047FE442054208820
+8243:100021FC7D24452465FC55245524FDFC4420642055FC54204420442057FE8800
+8244:102021247CA444A8642055FC5504FD0445FC6504550455FC4504450455148908
+8245:102020207C504488650456FA5420FC2047FE6420552855244622442254A08840
+8246:082010103EFC228432842AFC2A84FE8422FC32A22AA42A98229042884AC48482
+8247:100020067BB8488868885908493EFB8848884A886A88593E49004A804C7E9800
+8248:102020107DFE44206448548455FEFC0244A864A854A854A844A844AA552A8A06
+8249:100021FC7D04450465FC5500551CFD70451C6570551E55F04510451255128A0E
+824A:081010203E7C2244327C2A442A7CFE10221032FE2A922A92229242964A108410
+824B:100021FC7C084410642057FE5420FCA0444065FC555455544554455457FE8800
+824C:102020207850488869445A2249F8F8084850482068A45A824A8A4A8A4C789800
+824D:100021FC7D04450465FC55105510FDFE45106510557C554445444544557C8A44
+824E:102020407DFC450465FC550455FCFC0047FE6420542055FC4420442057FE8800
+824F:108420487DFE4420644054FC5484FC8444FC6484548454FC4484448454FC8884
+8250:105021247D54450465FC54505488FD4444786488548855504420445054888906
+8251:102020107DFE4502650255FE5500FD0045FE65AA56AA54FE44AA44AA54AA8886
+8252:100021FE7D02457A6502557A5502FC0044FC648454FC548444FC448454FC8884
+8253:104821487D4847FE654855485578FD0045FE642057FE547044A8452456228820
+8254:104020207DFE4548654855FE5548FD78450065FC554455484528451055288AC6
+8255:102020107DFE4484644855FE5502FE24441065FE5440547C4444448454948908
+8256:108420447C4845FE642054FC5420FDFE4440648054FE55104610441055FE8800
+8257:110420847C88440067FE54005488FD04460265FC555455544554455457FE8800
+8258:10A0212C7D24452465AC55245524FDFC442065FC548854504420445054888B06
+8259:102020207C50444864A455FE5684FCFC448464FC548054FC45444544567C8844
+825A:105020507DFE445065FC555455FCFD5445FC640054F8548844F8448854F88888
+825B:102021FC7D2447FE652455FC5420FDFC452465FC544057FE448845D054708B8C
+825C:115421547BFE495469545A724C00FBFE4A22482069FC592449244924492C9820
+825D:100021FC78204BFE6A2259AC4820F9AC480049FC680459FC4804480449FC9804
+825E:111021107DDE46A8644454505554FCD8445064D8555456524490449255128A0E
+825F:102021FC7C88445067FE540055FCFD2445FC652455FC542045FC442057FE8800
+8260:101023D278544948688A59044AFAFC0049FC4904690459FC490448884FFE9800
+8261:1020212478A84BFE6A0258F84888F88848F8480069FC592449FC492449FC9904
+8262:102020207BFE492469245AAA4FFEF80049FC4904697459544974490449FC9904
+8263:1040207C78404BFE6A425BF84A44FAFC4AA84AF86AA85AF84A204DFC4844998C
+8264:110420887BFE482069FC58204BFEF854499248906BFE589048D44B8A489699A2
+8265:101023D47A524A526BD058104FFEFA504BD24A526BD45A544AEA4F4A48569862
+8266:100823E87A884BEE6A285BF44A82FBE2480049FC69545954495449544FFE9800
+8267:108823FE7CA8449065FE572055FCFD2045FC652055FE550047FC448854708B8E
+8268:108823FE78884BFE6A0259FC4800FBFE484048A26B5458B84B5448924B509820
+8269:104020207BFE488868525FAC4AAAFAA84DAC4800690459FC490449FC49049A04
+826A:108021F87E0845FC652455FC5524FDFC4554662A55FC550445FC450455FC8904
+826B:1040207C78404BFC6A445BF04A44FAFC4AA84AF86AA85AF84A004DFC49549BFE
+826C:11F022107BFC4E046BFC5A244BB8FA2249FE4A106FFC5A444BFC48D0494A9A3E
+826D:110822947BDE4EB46BDE5A944BDEFA944BDE4A106FFC59084890486049989E06
+826E:00003FF0201020103FF0201020103FF022002208211020A02440282030182006
+826F:020001003FF0201020103FF0201020103FF02208211020A02040242028183006
+8270:000001F8FD08050845F84508290829F811441148293029204510454881860100
+8271:2200227CFF4422443E7C08447F44497C7F5208527F540848FF48144422624140
+8272:080008001FE020204040BFF82108210821083FF820002002200220021FFE0000
+8273:1080108010F8FD08121015FC11247D24112411FC1100FD001102110210FE1000
+8274:28202820287CFE442A882A7CFE54A854A854FF7C294029402D424A42483E8800
+8275:4240244000FC7E88251024FC24A424A4FFA424FC2480248024824482447E8400
+8276:2420FF20A57CFF44A588FF7C0054FF540054FF7C8140FF40424224421F3EE000
+8277:2A107F10AA9CFFA4AAC8FFBEAAAAFFAA002AFFBE00207F2041227F222222FF9E
+8278:10101010101092929292929292929292FEFE1212101010102010201040108010
+8279:08200820FFFE0820082000000000000000000000000000000000000000000000
+827A:08200820FFFE0820082000003FE000C00300040008001000200420041FFC0000
+827B:08200820FFFE08200A20020002007FF802080408040808080808100820504020
+827C:08200820FFFE0820082000007FFC010001000100010001000100010005000200
+827D:08200820FFFE08200820040004007FE0042004200820082010222022401E8000
+827E:04400440FFFE044000200820082004400440028001000280044008203018C006
+827F:04400440FFFE044000003FF8040804100420047C080408041004204440288010
+8280:08200820FFFE0820082000003FF8020802080208020804080408080810506020
+8281:08200820FFFE0820082000000FE00820082008200820102210222022401E8000
+8282:08200820FFFE0820082000007FF8020802080208020802500220020002000200
+8283:08200820FFFE0820082000000FE0082008200A200920092210221022201E4000
+8284:08200820FFFE08200820020002007FE002200A200420062009221022201E4000
+8285:08200820FFFE08200A200210021002FEFF00020001000100008000420032000E
+8286:08200820FFFE082000003FF0121011200820044002800100028004401830E00E
+8287:08200820FFFE08200820010001003FF821082108210821082128211001000100
+8288:09200920F93E0920092001003FF8010001000100FFFE01000100010001000100
+8289:08200820FFFE0820082000003FF8010001000100FFFE01000100010001000100
+828A:04400440FFFE0440000000F83F00010001000100FFFE01000100010001000100
+828B:08200820FFFE082000003FF8010001000100FFFE010001000100010005000200
+828C:0820FFFE082000003FF800000000FFFE040008000FF000100010001000A00040
+828D:04400440FFFE0440100010001FF8200840088808040802080208000800500020
+828E:04400440FFFE044000003FF8000800083FF8200020003FFC0004000400280010
+828F:08200820FFFE082009200100010001003FF801000100010001000100FFFE0000
+8290:08200820FFFE082008200000FFFE020002000240022002100208020002000200
+8291:08200820FFFE082000003FF00010001000103FF020002004200420041FFC0000
+8292:08200820FFFE0820082002000100FFFE0800080008000800080008000FFC0000
+8293:08200820FFFE0820082000001FE0004000800100FFFE01000100010005000200
+8294:01002108210821083FF8010011101010929292929292FEFE2212201040108010
+8295:08200820FFFE08200A20020007F808081010642002400280010006001800E000
+8296:08200820FFFE0820092001000100FFFE0100028002800440082010102008C006
+8297:08200820FFFE0A20040008101FE000C003040C083FF01020004001800E007000
+8298:08200820FFFE082008202080208020883C9020A020C0208424842884307C0000
+8299:08200820FFFE0820092001003FF801000100FFFE01000280044008203018C006
+829A:08200820FFFE082009200100FFFE01002108210821083FF8010A0102010200FE
+829B:08200820FFFE082000003FF002100210FFFE021004103FF0081010002000C000
+829C:08200820FFFE082000003FF0020002007FFC02800480048008841084207CC000
+829D:08200820FFFE08200A20010001007FF8003000C003000C003000480087FE0000
+829E:04400440FFFE044010001FFC20005FF880003FF0001000100010000A00060002
+829F:08200820FFFE082000000FE008201020601C00001FE00820044003801C70E00E
+82A0:08200820FFFE08200820020001007FFC0820082004400280010006C01830E00E
+82A1:04400440FFFE0440080008000FFC10042108410001000280044008203018C006
+82A2:08200820FFFE082000000800080013FC3000500090001000100017FE10001000
+82A3:08200820FFFE0820082000007FFC008001000300056009183104C10201000100
+82A4:04400440FFFE044000007F400240044008400F40F840484208420842283E1000
+82A5:08200820FFFE082009200280044008203458C446044004400840084010402040
+82A6:08200820FFFE0820092000803FF8200820083FF8200820002000400040008000
+82A7:08200820FFFE082000003FF0002006400180FFFE008200840080008002800100
+82A8:04400440FFFE044000003FF0082008400CF80A08111010A0204020A043188C06
+82A9:08200820FFFE08200920028004400A203118C1061FE000200040004000800100
+82AA:08200820FFFE082000783F802080208020803FFE2040204020242814300C2004
+82AB:08200820FFFE082000001FF0000000007FFC044004400440084408441044603C
+82AC:08200820FFFE082000400440082010102008DFE6042004200820102021404080
+82AD:08200820FFFE082000003FF82108210821083FF820002002200220021FFE0000
+82AE:08200820FFFE0820092001003FF8210821082288244828282008200820282010
+82AF:08200820FFFE0820082002000100008004082404240244028410041003F00000
+82B0:08200820FFFE092001007FFC010001003FF0082004400280010006C01830E00E
+82B1:08200820FFFE082000000888089010A030C050809180128214821082107E1000
+82B2:08200820FFFE0820092002800C603018C80608E00F0078080808080807F80000
+82B3:08200820FFFE08200A200100FFFE0400040007F0041008100810101020A04040
+82B4:08200820FFFE0820100010001FF8224842488488088811082208440808501020
+82B5:08200820FFFE0820092001003FF0011001100110FFFE0280044008203018C006
+82B6:08200820FFFE082010001FF8200844088408090810883FC81048000800500020
+82B7:08200820FFFE08200820010001000100110011F81100110011001100FFFE0000
+82B8:08200820FFFE0820082000003FF800000000FFFE02000400082010103FF81008
+82B9:08200820FFFE082000381FC0100010001FFC1040104010402040204040408040
+82BA:08200820FFFE0820082000F03F0001000100FFFE01000280044008203018C006
+82BB:080008001FF8220852481FC80408085030201FF8220852489FC8040808503020
+82BC:08200820FFFE0820082000F83F00010001F83F00010001FC7F020102010200FE
+82BD:08200820FFFE082000003FFC0020102020203FFE012002200C203020C0A00040
+82BE:08200820FFFE082009200100FFFE010001003FF8210821082108212821100100
+82BF:08200820FFFE0820100017F8210821106120A13C210421042204220424282810
+82C0:08200820FFFE08200A2001007FFC000000000FE00820082008221022201EC000
+82C1:08200820FFFE0820082000000820082008200820082014501250228841048202
+82C2:08200820FFFE082009200100110811081110212002800280044008203018C006
+82C3:08200820FFFE08200A200200FFFE040004000FF008101420224041808670380E
+82C4:08200820FFFE08200A2001000100FFFE02000200024002200210020002000200
+82C5:08200820FFFE0820082002044244244414440844084414442404420482140008
+82C6:08200820FFFE08200820200021FC2C44F0442044204424842884310422280410
+82C7:08200820FFFE092001007FFC010001001FF0010001007FFC0104010401140108
+82C8:08200820FFFE082000003FFC210021002FF82108210822082208440848509020
+82C9:08200820FFFE082000003FFC22402240224022442444243C280020003FFC0000
+82CA:08200820FFFE082000003FFC2000200027E02420242024A024444404440483FC
+82CB:08200820FFFE0820082000001FF010101110111011101290028004821882607E
+82CC:04400440FFFE04400800083009C00E000800FFFE0900088008400A300C0E0800
+82CD:08200820FFFE082009200280044008203018CFE60820082008A80848080807F8
+82CE:08200820FFFE08200A2001007FFE4002800400000000000000007FFC00000000
+82CF:08200820FFFE08200A2002007FF0021002142212221224124410081010A02040
+82D0:0820FFFE082000003FF8010801083FF8210021003FFC030405041928E1100100
+82D1:04400440FFFE044010001EF812882288228852A88C90048208821082207E4000
+82D2:08200820FFFE0820082001003FF8210821083FF821082108FFFE200820282010
+82D3:08200820FFFE0920028004400A203118C1061FE0002000400C80030000800040
+82D4:08200820FFFE08200400082010103FF8000800001FF01010101010101FF01010
+82D5:08200820FFFE082000007FF80408080810502020DFF81008100810081FF81008
+82D6:08200820FFFE0820092001003FF82108210821083FF82108210821083FF82008
+82D7:08200820FFFE0820082000003FF82108210821083FF82108210821083FF82008
+82D8:04400440FFFE044000003FF82008200827C824482448244827C8200820282010
+82D9:08200820FFFE08200A20010000007FFC001010100820044004800000FFFE0000
+82DA:08200820FFFE082000003FF8210821083FF8210821083FF82108410841288010
+82DB:08200820FFFE082000007FFC001000101F10111011101F101110001000500020
+82DC:08200820FFFE082000003FF8200820083FF8200820083FF8200820083FF82008
+82DD:08200820FFFE082008200000044004447C480470044004420C423442C43E0400
+82DE:04400440FFFE044008001FF020105F90109010901F901050102410040FFC0000
+82DF:04400440FFFE044010001FF8200840089F88108810881F881088000800500020
+82E0:08200820FFFE08203FF8200820083FF8208020803FFC204020242414280C3004
+82E1:08200820FFFE0820000024102210211021102010202024202850308821040602
+82E2:08200820FFFE082000001FF0101010101FF0100010001FF8100810081FF81008
+82E3:08200820FFFE082000003FF8200020003FF0201020103FF02000200020003FFC
+82E4:08200820FFFE082000007FFC00800100036005101908610401000100FFFE0000
+82E5:08200820FFFE08200A200200FFFE040008001FF028104810881008100FF00810
+82E6:08200820FFFE0820092001000100FFFE010001001FF01010101010101FF01010
+82E7:08200820FFFE08200A2001007FFE400280043FF8010001000100010005000200
+82E8:04400440FFFE04401FF8100810081FF810001200123813C02204220441FC8000
+82E9:08200820FFFE0820092002003FF82008200820083FF82008200820083FF82008
+82EA:08200820FFFE082000007FFC010001003FF82108228824482828200820282010
+82EB:08200820FFFE08200920010001FE0100010001003FF82008200820083FF82008
+82EC:08200820FFFE082000003FF8210821082108210822882448282820083FF82008
+82ED:08200820FFFE08201040104021FC24444444F844104420444884FC8445280210
+82EE:08200820FFFE0820000008200820102031245124912411241124112411FC1004
+82EF:08200820FFFE0820010001007FFC03800540092011102FE8C106010001000100
+82F0:08200820FFFE082000007E10021002103E10202040287E24024402FE14420800
+82F1:08200820FFFE0820010001001FF0111011101110FFFE0280044008203018C006
+82F2:04400440FFFE0440080008001FFC2400440087F00400040007F8040004000400
+82F3:08200820FFFE0820040008001FF02820444003801C70E30E00C00E0001800040
+82F4:08200820FFFE082000001FF0101010101FF0101010101FF010101010FFFE0000
+82F5:08200820FFFE0820010011001FF821000100FFFE01000280044008203018C006
+82F6:08200820FFFE082009200280044009203118C106010009201110210805000200
+82F7:04400440FFFE044010101010FFFE1010101010101FF01010101010101FF01010
+82F8:08200820FFFE0820001000F83F00111009200100FFFE01000100010005000200
+82F9:08200820FFFE082000007FFC01001110091009200100FFFE0100010001000100
+82FA:08200820FFFE082000001FF012101110FFFE1010221021103FFC001000A00040
+82FB:04400440FFFE044008100810101013FE30105110909010901010101010501020
+82FC:08200820FFFE0920110011003FFC4100810001003FF8010001000100FFFE0000
+82FD:08200820FFFE0820000000781FA012201220122012101290224822A843248202
+82FE:08200820FFFE0820082001000090089048244842488289020E101810E7F00000
+82FF:08200820FFFE0820092001003FF801000100FFFE0380054009203118C1060100
+8300:08200820FFFE082004403FF8044804481FF8144024403FFC0844105420484040
+8301:08200820FFFE082009202108210821083FF8010801004104410441047FFC0004
+8302:08200820FFFE0820009000883FFC2080208820882050205020244054418C8604
+8303:04400440FFFE0440100009F84908210825080528091071021102110210FE0000
+8304:08200820FFFE082000001000107C7E441244124412441244224422444A7C8444
+8305:08200820FFFE082000003FF0002006400180FFFE0282048408803080C2800100
+8306:08200820FFFE082000000C0070FC4084448444845C8464944888088010806080
+8307:04400440FFFE044002100208FFFE040004000FF008101420224041808670380E
+8308:08200820FFFE08200440044024442448275024602440244224422F42F03E4000
+8309:08200820FFFE092001000100FFFE010001007FFC0380054009203118C1060100
+830A:04400440FFFE0440001000781F80100010001FFC1040104010401040FFFE0000
+830B:08200820FFFE082008783F802080208020803FFE2040204022242914308C2084
+830C:04400440FFFE0440080008401040104037FE5040904010401040104013FC1000
+830D:04400440FC7E0440144010001FF8200840089F88108810881F88000800500020
+830E:04400440FFFE044000003FF0006001800E70700C1FF0010001000100FFFE0000
+830F:08200820FFFE08200820004004207FFC04800488089008A010C223824C82807E
+8310:04400440FFFE0440100010001FF822484A4884880A8811082288440808501020
+8311:08200820FFFE092002001FF012101110115010201FFC00047FE4000400280010
+8312:04400440FFFE044010001E7C12442248225052488C4404440854104820404040
+8313:08200820FFFE08200A2001007FFE40028004044004400820082010102008C006
+8314:08200820FFFE082000007FFE4002810401003FF80100010001000100FFFE0000
+8315:08200820FFFE082000007FFE400280041FE0042004203FA004200414040C0404
+8316:04400440FFFE044008000FF010202C4003801C70E00E1FF0101010101FF01010
+8317:08200820FFFE0820020007F808103420024001800FF81808E80808080FF80808
+8318:04400440FFFE044000003FF804080850302000007EFC1224122422444A948508
+8319:08200820FFFE082000900088FFFE0080108810887E50105010242054418C8604
+831A:08200820FFFE0820060078FC408440847E844084408440944E88708000800080
+831B:04400440FFFE044000003FF020103FF020103FF02208211020A024402830300E
+831C:04400440FFFE04400000FFFE044004403FF8244824482848303820083FF82008
+831D:08200820FFFE082000003FFC2080208027F82408240827F8208020803FFE0000
+831E:08200820FFFE082000003FFC210021003FF8200820083FF8210021003FFC0000
+831F:08200820FFFE082001003FF00110FFFE01103FF001003FF80100FFFE01000100
+8320:04400440FFFE0440000008400840104037FC50E0915011501248144418421040
+8321:08200820FFFE0A2001007FFC400480081FE000400080FFFE0100010005000200
+8322:08200820FFFE082000047F84082408241F24212451240A24040408043014C008
+8323:04400440FFFE044000001FF010101FF000003FF80100FFFE028004401830E00E
+8324:0820FFFE0820020007E01840648003200C4071F806081A10012000C007007800
+8325:08200820FFFE082001003FF801000100FFFE000001003FF801000100FFFE0000
+8326:08200820FFFE09200100FFFE01003FF8210821082128239005601918E1060100
+8327:08200820FFFE0820092001003FF82108210821083FF80100011001F87F042004
+8328:08200820FFFE08204080208020FC0904124814402040E0A020A0211022082C06
+8329:08200820FFFE082000781F80100010001FFC1000100017F82408240847F88408
+832A:08200820FFFE08200100111009100920FFFE04400440044008421042203EC000
+832B:08200820FFFE082008202040102087FE490009001100E1002100210021FC0000
+832C:08200820FFFE0A2002000400FFFE08001040304053FC90401040104017FE1000
+832D:08200820FFFE08200A2001007FFC08201010244844440280010006C01830E00E
+832E:08200820FFFE0A20020003F802000200FFFE0000010011101108210445040200
+832F:08200820FFFE0820000008500848104037FE504090A010A01110111012081406
+8330:0820FFFE092001003FF8210821083FF8210821083FF811000A00060019C0E03E
+8331:04400440FFFE0540110011003FF841000100FFFE0380054009203118C1060100
+8332:04400440FFFE04401020102020402448448878F008101020142822447EFC0204
+8333:08200820FFFE08200820200017FC90404040484008401040E04020402FFE2000
+8334:04400440FFFE044000003FF82008200827C82448244827C8200820083FF82008
+8335:04400440FFFE044000003FF8210821082FE8210822882448282820083FF82008
+8336:08200820FFFE082009200280044009203118DFF6010009201110210805000200
+8337:08200820FFFE0820000008A00890108030FC57809048105010241054118C1604
+8338:08200820FFFE082000007FFC10101FF010101FF01010103EFFD0001000100010
+8339:08200820FFFE082010001000FE7C124422442244644414440844147C2244C000
+833A:08200820FFFE0A200100FFFE0400082010103FF804480440044008441044603C
+833B:1010929292929292FEFE2010401080001010929292929292FEFE221220104010
+833C:08200820FFFE082000003FF820082FE8200827C82448244827C8200820282010
+833D:08200820FFFE082000001040104027FC6444A444244427FC2444204020402040
+833E:08200820FFFE0820082000007FFC082008200820FFFE08200820102020204020
+833F:08200820FFFE0820082000007DF011101110119011501D12E2124212040E0800
+8340:04400440FFFE144010001FF820085FC890481FC810481FC81048000800500020
+8341:08200820FFFE082000007FFC00001FF010101FF010101FF010100000FFFE0000
+8342:0820FFFE0A2002007FFC0440082037D8C0063FF808000FE00020002001400080
+8343:08200820FFFE09200280044008203018CFE6010001001FF0010001007FFC0000
+8344:08200820FFFE08200A2001007FFC040008401F8001100620384001A00E107008
+8345:08200820FFFE0820092002800C603018CFE600001FF01010101010101FF01010
+8346:12041204FFC4122400247FA4122412241224FFE4122412242204220442148208
+8347:04400440FFFE0440100021FC4000880013FE3020502090201020102010A01040
+8348:04400440FFFE0440101010103E1022FC4210A490149008FE1010201040108010
+8349:04400440FFFE044000001FF010101FF010101FF00100FFFE0100010001000100
+834A:08200820FFFE082000047F84122412241224FFE4122412242204220442148208
+834B:08200820FFFE082000007FFC010002003FF82488248824882488248824A82010
+834C:08200820FFFE0A2001007FFE400282040200FFFE042008201C4003800C707008
+834D:08200820FFFE082004404440448044FE450846885C9064504420045004880506
+834E:08200820FFFE082000007FFC040008201FF0011001003FF801000100FFFE0000
+834F:04400440FFFE04400810087813C0304050409FFE104010401040104017FC1000
+8350:08200820FFFE0A2002007FFC040009F8081018202BFE48208820082008A00840
+8351:08200820FFFE08200100FFFE01007FF801083FF821003FFC0284044C1830E00E
+8352:08200820FFFE0A200100FFFE100010001FF8000011101110111021124112810E
+8353:04400440FFFE0440101008207FFC082008200820FFFE08200820102020204020
+8354:0820FFFE0A2002003FF0041018A06040102010207EFC1224224422444A948508
+8355:08200820FFFE082000003E20222022FC3E24222422243E24224442444A948508
+8356:08200820FFFE0A2002083FD002200240FFFE0100061018E02F00C808080807F8
+8357:08200820FFFE0820009000883FFC2080208830882850245020244054418C8604
+8358:08200820FFFE0820000008204820282028200BFE082018202820C82009FC0800
+8359:08200820FFFE082020401040104007FC704010A01090110812041404280047FE
+835A:08200820FFFE0820010001003FF8010011100920FFFE0280044008203018C006
+835B:08200820FFFE0A2002FC7F20014000840764381C00007FFC044008421042603E
+835C:08200820FFFE0820208020883EB020C42084267C39000100FFFE010001000100
+835D:08200820FFFE082000047F044124492449244924492449241424220441148088
+835E:08200820FFFE082000F03F000200FFFE044008203458C4460440044008401040
+835F:08200820FFFE092002800440082037D8C00600003FF80200044008201FF00810
+8360:08200820FFFE0A2001007FFC0820044003800C603018C4460440044008401040
+8361:08200820FFFE0820000023F01020104080804BFC48A41124E244248421282210
+8362:08200820FFFE0A2001007FFE400280043FF801000100FFFE0100010005000200
+8363:08200820FFFE082000007FFE4002810401007FFC0380054009203118C1060100
+8364:0820FFFE082000007FFE420282043FF8090011001FF001000100FFFE01000100
+8365:08200820FFFE082000007FFE4002810401047D880550092011102108C5060200
+8366:08200820FFFE082000007FFE4002810411001FF821000100FFFE010001000100
+8367:08200820FFFE082000007FFE400281041110111022A00280044008203018C006
+8368:08200820FFFE08203FF000101FF000103FF00020FFFE08200420042000A00040
+8369:04400440FFFE04401FF0101010101FF010801040162021102088460681800040
+836A:04400440FFFE044000007C200420082010A810A41D24F1221222102050A02040
+836B:04400440FFFE044000007CFC4484488450FC4884448444FC5484488441144208
+836C:04400440FFFE044000007FFC04040288128008800900FFFE0240042018106008
+836D:08200820FFFE08201000100021FC4420F82010202020FC2040201C20E3FE4000
+836E:04400440FFFE044010081008200845FEF80810882048FC4840081C08E0284010
+836F:04400440FFFE04401080108020FC4504FA0410842044FC4400041C04E0284010
+8370:04400440FFFE0440102010201020FC2031FC3820542050209020102013FE1000
+8371:08200820FFFE08203FF820083FF8200020702F8020F02F8020F85F824082807E
+8372:0440FFFE044000001FF0111011101FF0111011101FF001003FF801000100FFFE
+8373:08200820FFFE082000007FFC00001FF0101010101FF0000008200440FFFE0000
+8374:04400440FFFE044010201020FDFC10201420182033FED0501050108851042202
+8375:08200820FFFE082000007FF80208120824280810310008844892481287F00000
+8376:08200820FFFE08200040004078A049104A884C4648404BF07810482000200040
+8377:04400440FFFE0440100017FE20086008A7C824482448244827C8200820282010
+8378:08200820FFFE092001003FF801007FFE40029FE400400180FFFE010005000200
+8379:08200820FFFE0820010011F811001100FFFE010009081110606001800E00F000
+837A:08200820FFFE08200820108010FC7D041204108410541C24E044418400280010
+837B:04400440FFFE04404420282010A428A448A89920282048508850088851042202
+837C:08200820FFFE092002800440082037D8C10601003FF801001110210845040200
+837D:08200820FFFE082000F87F00221011200200FFFE042008201C4003800C707008
+837E:0820FFFE08200400082010103FF804480820121067E80820144003801C70E00E
+837F:08200820FFFE0820009000883FFC208020883E88225022502A244454418C8604
+8380:08200820FFFE082000003FF820002FF020003FFC248824504420451886060400
+8381:08200820FFFE082000007FFC01001110111011102928454485840100FFFE0000
+8382:08200820FFFE08203F04210421243F24082408247FA408A410A4108422944108
+8383:0440FFFE044030100CE003000CC03230FFFE080011003FF0D110115011200100
+8384:0820FFFE082000007FFC01003FF821083FF821083FF821001A00060019C0603E
+8385:08200820FFFE082008800840104033FC50009008120811101110102017FE1000
+8386:08200820FFFE09200110FFFE01003FF821083FF821083FF82108210821282110
+8387:04400440FFFE044000203E20222022FC3E2422243E24222422442F44F0944108
+8388:08200820FFFE082021F011101110820C440053F011102110E0A0204021B02E0E
+8389:04400440FFFE044000000608780808480848FF481C482A484948880808280810
+838A:04400440FFFE044000002420242024203C2007FE0420FC202420242025FC4400
+838B:04400440FFFE04400880088010FE11403240547C90401040107E104010401040
+838C:04400440FFFE0440082004401FF01010101010101FF00440044008421042603E
+838D:04400440FFFE0440011001087FFC0100211811A007401920E118410605000200
+838E:08200820FFFE082000001020082040A824A40522092272281010106011800600
+838F:08200820FFFE082010001020FC2010A814A419223122D2281010106051802600
+8390:08200820FFFE08202040104013FC8244444810A010A0E120212022222422281E
+8391:0440FFFE044008001FF0282007C01830E10E1FF001001FF001007FFC01000100
+8392:08200820FFFE082000001FF0101010101FF000003FF82008200820083FF82008
+8393:04400440FFFE144010003FFC40009FF012101110FFFE221021103FFC00100060
+8394:04400440FFFE044000003FF8200824482828301827C82448244824483FF82008
+8395:08200820FFFE092001007FFC054009203118C1061FF01010101010101FF01010
+8396:08200820FFFE082000007FFE08881110222011103FF8010001000100FFFE0000
+8397:08200820FFFE082001007FFC01003FF821083FF821083FF80100FFFE01000100
+8398:08200820FFFE0A2001003FF8000008200440FFFE010001007FFC010001000100
+8399:08200820FFFE082000003FF80408FFFE04083FF808001FF8280848088FF80808
+839A:04400440FFFE044000187BE00840104022787A400A402BFC1000280047FE8000
+839B:04400440FFFE044000387BC00840104023F8784008402BFC1000280047FE8000
+839C:08200820FFFE0820000010401040247E24886488A54824502420205020882306
+839D:08200820FFFE082001001110111011102928454481003FF801000100FFFE0000
+839E:08200820FFFE0A2001003FFC200440081FE000007FFC0440044008441044603C
+839F:08200820FFFE09200280044009203098CFE6004000801FF0101010101FF01010
+83A0:04400440FFFE04701F8001007FFC054009203118CFC6044004F0081010506020
+83A1:04400440FFFE044000001FF0101010101FF00100110011F81100290047FE8000
+83A2:08200820FFFE0820092001007FFC11101110292845440280044008203018C006
+83A3:08200820FFFE092000807FFC080008000FF80000010008844892481287F00000
+83A4:08200820FFFE08200000FFFE04403FF824482448283830083FF820083FF82008
+83A5:08200820FFFE082044002BF81048284848489BF8284848888888088857FE2000
+83A6:08200820FFFE08200100111009201FF010101FF010101FF01010101010501020
+83A7:08200820FFFE082000001FF010101FF010101FF010101FF0044008421042603E
+83A8:08200820FFFE0A2001001FF010101FF010101FF0110410881050122014181806
+83A9:08200820FFFE082000F87F00221011203FE000400080FFFE0100010005000200
+83AA:08200820FFFE0820064038500848FFFE084008400E2478280812082A28C61302
+83AB:08200820FFFE082000001FF010101FF010101FF001007FFC028004401830E00E
+83AC:08200820FFFE0820040007E0082010403FF8510811081FF8028004821882607E
+83AD:08200820FFFE082000007E7C42447E4442447E44404450544848544062404040
+83AE:08200820FFFE082000003FF821083FF821083FF802007FFC0404080410286010
+83AF:08200820FFFE082008202040104097FE40E0415011502248E444284220402040
+83B0:04400440FFFE04401080108010FC7D041248104010401CA0E0A0411002080C06
+83B1:08200820FFFE092001003FF80100111009207FFC0380054009203118C1060100
+83B2:08200820FFFE0820208017FC1140024073FC1040104017FE1040284047FE0000
+83B3:04400440FFFE044000107C10441045FE44107D104490449044107C1044500020
+83B4:04400440FFFE04401FF0101010101FF001007FFC410442844444484440144008
+83B5:08200820FFFE092002003FF82108210821083FF8228804900888108A2082C07E
+83B6:08200820FFFE0820092002800440082037D8C00602101110092008407FFC0000
+83B7:08200820FFFE082044402850104828404FFE984028A048A08910091052082406
+83B8:04400440FFFE04404490288810882BFE48A098A028A0492089200A225222241E
+83B9:08200820FFFE082000007FFE400280043FF8010001001FF00100014001207FFC
+83BA:08200820FFFE08207FFE42029FF410101210115010201FFC000400047FD40008
+83BB:04400440FFFE044000003FE00420047C08043014C0083E44225822623E42223E
+83BC:04400440FFFE04401020102023FE44207924112421247DFC00221C22E022401E
+83BD:0820FFFE0820024002207FFC044008203018C82608207FFC0820102020204020
+83BE:0820FFFE0A2002007FFC0440092037D8C106092008207FFC0820082010202020
+83BF:04400440FFFE044008000804FFA408247F2449244B241C242A24490488140808
+83C0:08200820FFFE0A2001007FFE400290041EF82288248854A8089008841084607C
+83C1:0820FFFE09203FF801001FF00100FFFE00001FF010101FF010101FF010101030
+83C2:08200820FFFE0820104020407E7C4284430442447E244224420442047E284210
+83C3:08200820FFFE0820200013FE920042004BFC0A041204E3FC2200220023FE2000
+83C4:08200820FFFE08200100FFFE01003FF821083FF821083FF803800D603118C106
+83C5:08200820FFFE082001007FFE40029FE410201FE010001FF0101010101FF01010
+83C6:08200820FFFE08207F0022FC22443E44224422283E2822102790FA2842440282
+83C7:04400440FFFE044010101010FEFE12102210227C6444144408441444227CC044
+83C8:08200820FFFE082010401020FC2011FC140018083108D0901090102053FE2000
+83C9:08200820FFFE08203FF000101FF00010FFFE111009A005401930E10E05000200
+83CA:04400440FFFE044010001FFC220452448A8402047FF407040A84124462140208
+83CB:08200820FFFE0820004000407BF8484048404FFC48E079504A48044408420040
+83CC:0820FFFE082000003FF8200820C8270821082FE823882548292821083FF82008
+83CD:08200820FFFE09200280044009203098CFE60040028001004884481287F20000
+83CE:08200820FFFE082000001FF810081FF810081FF82080208C3EF020822682387E
+83CF:04400440FFFE0440200017FE100880084BC84A481248E3C82248200820280010
+83D0:0440244814500440FFFE082004407FFC01003FF80100FFFE028004401830E00E
+83D1:08200820FFFE08200888111022201110088800003FF821083FF821083FF82008
+83D2:08200820FFFE082000003FF820083FF820083FF80100FFFE054009203118C106
+83D3:08200820FFFE082000003FF821083FF821083FF80100FFFE054009203118C106
+83D4:08200820FFFE08203EFC228422943E88228022FC3EA422A422A822904AA884C6
+83D5:08200820FFFE092002800C6037D8C0063FF8248824883FF82488248824A82010
+83D6:04400440FFFE04401FF010101FF010101FF000003FF820083FF820083FF82008
+83D7:04400440FFFE04401020102011FCFD24112411241DFCF1241124112451FC2104
+83D8:04400440FFFE0440101010901090FD0831483A44544250909088110813FC1104
+83D9:0820FFFE082000F83F0001007FFC09200920FFFE092009207FFC010001003FF8
+83DA:08200820FFFE0820021002FC7F4000840764781C021002FC7F4000840764781C
+83DB:08200820FFFE082000007C7C44447C7C44447C7C400440044004400440144008
+83DC:08200820FFFE0820001000F83F001110082001007FFC054009203118C1060100
+83DD:08200820FFFE082010481044FDFE1040144018FC30A4D12811281210542820C6
+83DE:08200820FFFE08200C80708010FC1124FD243224384454445084910412281010
+83DF:0440FFFE044008000FE0102020405FF8110811081FF8028004A008921082607E
+83E0:04400440FFFE04402020102013FC822442204BF80A881288E25024202450298C
+83E1:04400440FFFE044000001FE040445194492443C445444924551442047FFC0004
+83E2:08200820FFFE082010801080FDFC120415F411141D14F1F4110C1102510220FE
+83E3:08200820FFFE082000007F7C484448447F44412841287F10481048287F440082
+83E4:04400440FFFE0540111009203FF802007FFC082010102FE8C8260868080807F8
+83E5:04400440FFFE04401000100C11F0FD00110031FE391055105110921012101410
+83E6:04400440FFFE0440201813E01200020073FC1220122012201420282047FE0000
+83E7:08200820FFFE092000803FFE200020782F80288028802FFC284048244A948C4C
+83E8:08200820FFFE0A2001003FF808200440FFFE04007FFC08201C4003800C707008
+83E9:08200820FFFE082001003FF808200440FFFE000000001FF0101010101FF01010
+83EA:0820FFFE0A2001007FFE400280043FF0040008001FF02810481008100FF00810
+83EB:08200820FFFE08207FFC01003FF821083FF801007FFC01003FF80100FFFE0000
+83EC:08200820FFFE082023FC10841084808449144A0815FCE1042104210421FC2104
+83ED:08200820FFFE082020801110120887FC4204500013F82208E208220823F82208
+83EE:08200820FFFE092000803FFE20802FF820883FFE20882FF8214042204C18B006
+83EF:04400440FFFE04407FFC11101110FFFE111011107FFC0100FFFE010001000100
+83F0:08200820FFFE0820001C7DF00950115011501D503148D14811441254525A2468
+83F1:08200820FFFE082001003FF80100FFFE1010220847E40820144003801C70E00E
+83F2:08200820FFFE0820082004407C7C044004407C7C04400440FC7E044004400440
+83F3:08200820FFFE0820092002800C603018CFE6010001003FF811100920FFFE0000
+83F4:08200820FFFE0A2002007FFC044009203FF8D1161FF011101FF40104010400FC
+83F5:04400440FFFE04407FFC482444445FF4410440845FF44404440447E440144008
+83F6:04400440FFFE044001007FFC01003FF80200FFFE092017D02108DFF601000100
+83F7:0820FFFE08201FF000100FF000101FF000007FFE41029FF41110115011200100
+83F8:04400440FFFE0440102008207E50105010881F0612601210220022C04A308408
+83F9:04400440FFFE0440100009F80908410821F82908090811F87108110817FE1000
+83FA:0820FFFE092000801FFC10041FFC100017F8140817F8240827F8440884280410
+83FB:04400440FFFE04400820082008207EFC08201C301A702A6848A4892208200820
+83FC:08200820FFFE082001000910092012C0043019086914091012A004401830600C
+83FD:04400440FFFE044008000F7C08440844FF44002808282A104910892828441082
+83FE:04400440FFFE04403FF801000200FFFE08203118C10609901148214805000200
+83FF:08200820FFFE08207F84100422247F24092408247F24082408240F04F0144008
+8400:08200820FFFE092001F801003FFE210221F02F0420FC200027E044224822B01E
+8401:04400440FFFE0440082008207FFC08200FE008200FE00820FFFE082010102008
+8402:04400440FFFE04400E00787C08440844FF4418441C442A444A44887C08440800
+8403:08200820FFFE0A2001007FFC08200820145022880100FFFE0100010001000100
+8404:0820FFFE082020003FFC48049FE422040204FFFC0204222422243FE400280010
+8405:0820FFFE08200100FFFE010021083FFA010200FE00003FF820083FF820083FF8
+8406:08200820FFFE0A2004003FF821083FF822083FF808801080FFFE008000800080
+8407:04400440FFFE04400FF808000FF008000FF00800FFFE111010A014401830100E
+8408:08200820FFFE082000001FF010101FF010101FF010101FF00450084A1042603E
+8409:08200820FFFE082000003EFC22A422A43EA422FC22803E80228222824A7E8400
+840A:08200820FFFE092001007FFC11101110292845440380054009203118C1060100
+840B:0820FFFE09207FFC01003FF80108FFFE01083FF80200FFFE08201C4003C07C38
+840C:08200820FFFE0820000000FC7C84448444FC7C84448444FC7C84448401140208
+840D:08200820FFFE0820200017FC904042484950084017FEE0402040204020400040
+840E:0820FFFE082000701F8001007FFC05401930E10E04007FFC08201C4003807C78
+840F:04400440FFFE044008001FE020204440B878200820083C78200820083FF82008
+8410:0820FFFE082001007FFC01003FF80108FFFE01083FF8110011F8290047FE8000
+8411:08200820FFFE092008801FFC108030805FF8908010801FF8108010801FFC1000
+8412:08200820FFFE0A2001007FFC08201210244808201FF00440044008441044603C
+8413:08200820FFFE0A2001007FFE40029FF4101010101FF010101FF010101010FFFE
+8414:04400440FFFE0440100011FCFC4410441494190832FCD0841084108450FC2084
+8415:0820FFFE0A2001007FFC0820044003801C70E82E0FE008200FE0082010202020
+8416:0820FFFE0820060038F8200820083CF8200820083FF80440044008423042C03E
+8417:08200820FFFE0A2001007FFE400280041FF0000000007FFC1110210845040200
+8418:08200820FFFE0A2002007FFC0440082037D8C0063FF801000920111025080200
+8419:04400440FFFE044010201020FDFE11223224385054505490909011121212140E
+841A:08200820FFFE0820100011FC1088FC70138E10201DFC3020D3FE102050202020
+841B:08200820FFFE08203FF820083FF820083FF820083FF80820FFFE082010202020
+841C:04400440FFFE044010201020FE3E9220922092FC92849A849484108410FC1084
+841D:0820FFFE082000003FF8244824483FF8020007F008103420024001800E007000
+841E:08200820FFFE082000003FF8210822882448000020843E9820E020842684387C
+841F:08200820FFFE08200640384009F808487E4818C81C482A68289A488A09060A02
+8420:08200820FFFE082000003E7C224422443E7C224422443E7C224422444A948508
+8421:04400440FFFE04400020104009FC49042104250405FC09047104110411FC1104
+8422:08200820FFFE08202100110013F884084BE85228122823E8E2182204220421FC
+8423:08200820FFFE0A2001007FFE400280041FF00100110011F81100290047FE8000
+8424:08200820FFFE082000007FFE410281041FF0111011101FF0010001087FFC0004
+8425:08200820FFFE08207FFE40029FF4101010101FF000003FF8200820083FF82008
+8426:08200820FFFE082000007FFE440288441F8003200C103FF80108112025104208
+8427:08200820FFFE082001003FF80108FFFE01083FF8010025482528292841088108
+8428:04400440FFFE044000207DFC4488485051FE4900450045005500490042004400
+8429:04400440FFFE04400C20702010A410A4FCA83120382054505050908811041202
+842A:08200820FFFE08200C10709010501010FC903050381E55F05010901010101010
+842B:0820FFFE082000F83F000100FFFE054009203118DFF610101FF010101FF01010
+842C:04400440FFFE04401FF011101FF011101FF001003FF8210821482FE824282010
+842D:08200820FFFE082000F03F0001001FF011101FF001007FFC412441F45E144008
+842E:08200820FFFE092002800C6037D8C0063E0822483E4822483E48220822282610
+842F:0820FFFE082004000FE010203FF850081FF810081FF810081FF8042008101008
+8430:08200820FFFE092001007FFC01003FF8292825483FF8038005601918E1060100
+8431:08200820FFFE0A2001007FFE40029FF400001FF010101FF010101FF00000FFFE
+8432:08200820FFFE082000FC7F00220811103FF80200FFFE04000FF0122021C0CE3C
+8433:08200820FFFE08200100FFFE01003FF8244822882FE821083FF8210821282010
+8434:0820FFFE08203F04210421243F2421243F24212421243F240024120421144088
+8435:04400440FFFE04401FF010101F9010907FFC40044FE4482448244FE440144008
+8436:0820FFFE082001007FFC01003FF80200FFFE08201FF02828CFE608200FE00820
+8437:04400440FFFE0440080049042A247F2441247F2441247F244124410445144208
+8438:08200820FFFE082005003978210821083D78210821083FF8028004401830E00E
+8439:08200820FFFE092000803FFC20043FFC20002FFC292429242FFC49244924880C
+843A:0820FFFE08207FFC40045FF440045FF400001FF010101FF010101FF010101FF0
+843B:08200820FFFE0A2001003FF808200440FFFE00001FF010101FF010101FF01010
+843C:0820FFFE082000003EF822883EF800003FF80000FFFE08000FF0001000A00040
+843D:08200820FFFE0820208010F811088290486049981606E1F82108210821F82108
+843E:0820FFFE082000003FE008200BF80A88112822905FF8124812481248FFFE0000
+843F:04400440FFFE0440203813C01040804047FC5040104023F8E208220823F82208
+8440:04400440FFFE0440103813C0FC40104017FC18403040D3F81208120853F82208
+8441:0440FFFE0440082004407FFC01003FF80100FFFE0200FFFE08201C4003C03C38
+8442:04400440FFFE044020203E20442088FC7F24492449247F441454248A450283FE
+8443:08200820FFFE082000807C8044FE454046407C7C44404440447E7C4044400040
+8444:08200820FFFE082000403E40227E22A03EA0233C22203E20223E22204A208420
+8445:04400440FFFE0440000011F81108290845F89108110829F82508410887FE0000
+8446:04400440FFFE044008000BF81208320853F8904017FE10E0115012481C461040
+8447:0440FFFE04401FF0022001407FFC0484188862800100FFFE05401930E10E0100
+8448:04400440FFFE144020087FFC00043FF820083FF80100FFFE054009203118C106
+8449:04400440FFFE044012207FFC122013E010001FF80100FFFE05401930E10E0100
+844A:08200820FFFE092006C01830EFEE00001FF010101FF00820FFFE082010202020
+844B:08200820FFFE082000803C8024FC25043EF4249424943CF42494240454288810
+844C:0820FFFE08200400FFFE08201E4003C03C381010FEFE2224646418182434C2C2
+844D:04400440FFFE04407FFC00001FF010101FF000003FF821083FF821083FF82008
+844E:08200820FFFE0820004013F8204847FE884813F8304053FC904017FE10401040
+844F:08200820FFFE0820204013F890484FFE404813F82040E3FC20402FFE20402040
+8450:08200820FFFE0820044008203018CFE6042018A060403FF8244824482448FFFE
+8451:04400440FFFE0440080008087F0808FEFF08084808287F2808080F08F0284010
+8452:04400440FFFE04401000100025FC7C200820102024207E20002054204BFE8A00
+8453:08200820FFFE082008202090109013FC80904890489017FEE000209021082204
+8454:0820FFFE0820000009F00810101037FC510091F81240104017FC10A01110120C
+8455:08200820FFFE08201200213C49009400247E6108A2082E082208220822282010
+8456:08200820FFFE0A2001007FFE48229114212801107FFC0280044008203018C006
+8457:0820FFFE082002083FD002200240FFFE03000C003FF0C8100FF008100FF00810
+8458:04400440FFFE044008881110FFFE1110088800003FF821083FF821083FF82008
+8459:04400440FFFE0440080008FC7E84088418FC1C842A842AFC4884888408FC0884
+845A:04400440FFFE044008207FFC08200FE008200FE00820FFFE1240142010001FF8
+845B:0820FFFE08201FF010101FF010101FF008001FFC21045284944410041FA80010
+845C:0440FFFE044008007F7C08243E2408447F5408880100FFFE02800C603018C006
+845D:04400440FFFE044000207F202A2054FC2A2400247E24082408440E44F0944108
+845E:0820FFFE082000007DFC048804887CF8408840887CF80488049E05E828081008
+845F:08200820FFFE092002001FF010101FF010101FF000007FFC01003FF80100FFFE
+8460:04400440FFFE04400BF8080811F8300853F8900017FC140413F8111010E0171C
+8461:04400440FFFE24403FFC42247FF482043FE422243FE422243FE4222422A4204C
+8462:08200820FFFE092001007FFC04800A603118C0063FF8244824482448FFFE0000
+8463:0820FFFE08201FF001007FFC01001FF011101FF011101FF001003FF80100FFFE
+8464:04400440FFFE04401008100824087DFE0808108824487E48000854084A288A10
+8465:04400440FFFE044010100820FFFE00003E4822483E4822483E0822082A282410
+8466:0820FFFE082002003FF00410FFFE00001FF010101FF001001FF021003FF80100
+8467:04400440FFFE044008107F1008107F7E41123E1204120F1278220822284A1084
+8468:04400440FFFE04401FF011101FF011101FF00000FFFE111010A014401830100E
+8469:04400440FFFE0440100021FC7D244524452445247DFC4500450045027D0244FE
+846A:04400440FFFE044010041F0422247FA4A4A43FA424A43FA424A4248442948108
+846B:04400440FFFE04400800087C7F440844087C3E442244227C22443E8422940108
+846C:0820FFFE0820FFFE10803E9842E024841884E07C08200820FFFE082010202020
+846D:0820FFFE082000007CF8440844087CF8400041F87C88405040207C5040884306
+846E:0820FFFE0820060038F8208820883D06220021F83C8820882C50F02020D82706
+846F:08200820FFFE082010401440247C7884110424447E24002454044A048A280010
+8470:04400440FFFE044009100A0817FC31105208948411F813081490106011981606
+8471:04400440FFFE044008001FF82A4844480A88110822A8041001004884481287F2
+8472:0820FFFE0A2004001FF010101FF010101FF001047D88095011202118C5060200
+8473:04400440FFFE0440002800243FFE20202FA422242FA824982D12422A45468882
+8474:04400440FFFE0440002800243FFE20202FA420242FA8289828924FAA40468082
+8475:0820FFFE082000907EA00444282810102FE8C10601007FFC010002C00C307008
+8476:0820FFFE09207FFC00001FF010101FF000007FFE40029FF40100010005000200
+8477:0820FFFE08207FFC41043FF801001FF011101FF011101FF00100FFFE01000100
+8478:0820FFFE082000003FF8210821083FF8210821083FF802005104511290120FF0
+8479:08200820FFFE082020401040FEFE212020AC3CB425E424AC24A044A25482887E
+847A:0820FFFE08201FF010101FF000007FFC10101FF010101FF0103EFFD000100010
+847B:04400440FFFE044000001FF0101010D01710111017D0155027CA212A4FE68022
+847C:08200820FFFE08202448238824483FF81010220847E40820144003801C70E00E
+847D:08200820FFFE08207FFC04403FF824483FF80400FFFE08201C4003800C703008
+847E:08200820FFFE082010001EF8228862A894920882307EC10008844892481287F0
+847F:08200820FFFE08203FF821083FF820002FF828082FF828084FF848088FF80808
+8480:04400440FFFE04401FF010101FF010101FF000003FF8244824482448FFFE0000
+8481:08200820FFFE08202050104817FC00C00160F150124814441040280047FE0000
+8482:0820FFFE0A2001003FF8082004407FFE410281041FF011101150112001000100
+8483:0440FFFE044008000FE010201FC00040FFFE06003B0804B019C062A00C987306
+8484:08200820FFFE08207FFE400280043E0800087EFE14481428140A242A241243FE
+8485:0440FFFE04401080088043F0289011127212140E1100FFFE05401930E10E0100
+8486:0820FFFE082000007DF0111011901D52F20E0400FFFE08201C4003800C707008
+8487:04400440FFFE044800243FFE20202FA428A42AA82AA82A902A92452A49469082
+8488:04400440FFFE044020883C9020E42C84307C04001FF010101FF010101FF01010
+8489:0820FFFE082001001FF011101FF00100FFFE00001FF01010111002C00C307008
+848A:04400440FFFE04400880109830E057849084107C00007C8844B044C47C84447C
+848B:08200820FFFE0820008008F849102AA0285008901BFE29104890889008100830
+848C:04400440FFFE0440111009207FFC05401930610C0400FFFE08201E4003C03C38
+848D:0820FFFE0820240014007FE0042008200FF8080810081FFE2002255249548008
+848E:04400440FFFE0440201C13E0920E42F04A900A901292E2942288248824A428C2
+848F:08200820FFFE08207FFE4002BFF404803FF82488287830083FF820083FF82008
+8490:08200820FFFE0A2004003FF821083FF821083FF8029002A804B8088A3082C07E
+8491:0820FFFE08200600387820483E4822863F0022FC3E4420443E2822104A2884C6
+8492:0440FFFE0440100023FE7C20442045FC7D2441247D24452445347D2844200020
+8493:04400440FFFE04401020102025FE7C200924112425247DFC002254225422801E
+8494:08200820FFFE0820004078404BFC48404FFE78104FFE48104A10791048500020
+8495:04400440FFFE04401FF01110129014501FF000003FF8244824482448FFFE0000
+8496:0820FFFE09207FFC01001FF010101FF010101FF010101FF01010FFFE08201010
+8497:08200820FFFE08A0204013F8920843F84A080BF81242E2442228229023082206
+8498:0440FFFE044008007F7C114432440C7C3220DFC001003FF801007FFC01000300
+8499:0820FFFE08207FFE40028FE400007FFC06003B0804B019C062A00C9872860100
+849A:0820FFFE082000007FFC00001FF010101FF000007FFC482444445FF44104410C
+849B:04400440FFFE0440202020203DFC50241024FC2411FE542054505C5074880506
+849C:08200820FFFE082000007C7C00000000FEFE1010101054545252929250502020
+849D:0440FFFE044000003FFC2080210027F0241027F0241027F0408044908A881104
+849E:08200820FFFE082021401120120082FC46005A8812482248E250220022FC2200
+849F:08200820FFFE08202080108010FCFD0402F44894489448F410941E04F0284010
+84A0:0820FFFE082002003FF820083FF820083FF820083FF8010008844892481287F0
+84A1:0820FFFE082001003FF8082004407FFE420281043FF8040007F0081010502020
+84A2:08200820FFFE0820784048A05110620855F648404BFC68405150424845444080
+84A3:08200820FFFE0820104020A041108A0815F6304053FC90401150124815441080
+84A4:08200820FFFE0820204010A0911042084DF6104027FCE0402248244429422080
+84A5:08200820FFFE0820040079FC40444844545462883FF821083FF821083FF82008
+84A6:0440FFFE044008801FFC30805FF890801FF810801FFC10003FF00C6003807C7C
+84A7:04400440FFFE0440002800243FFE222023A422242FA8289828924FAA40468082
+84A8:0440FFFE044013F8104023F820406FFEA00023F8220823F8220823F822082218
+84A9:08200820FFFE08200C0071F811081108FDF83108390855F85108910817FE1000
+84AA:0820FFFE092001107FFC01003FF821083FF821083FF821080020FFFE08200460
+84AB:0440FFFE0440082004407FFC01003FF80200FFFE080017F8208040809FFC0000
+84AC:08200820FFFE08207FFE44028FE410203FF8510811081FF802800492188AE07E
+84AD:0820FFFE082010001FFC210451141FF4020814001FFC210451141FF404143808
+84AE:08200820FFFE082004007FFC450408801FFC30805FF810801FF810801FFC1000
+84AF:11021102FFE2110A000A7BCA4A4A4A4A7BCA4A4A4A4A7BCA4A424A42AB4A1484
+84B0:08200820FFFE082010783E4822482A862300FEFC22442A44222842104A2884C6
+84B1:04400440FFFE044010281024FDFE102015FC192431FCD12411FC11245124210C
+84B2:08200820FFFE0828404427FE204087FC444457FC1444E7FC2444244424540408
+84B3:04400440FFFE04401020102025FC7D2409241154254C7D840104550455148108
+84B4:08200820FFFE08204100227CFFC40844497C494449447F7C1144204440948108
+84B5:0440FFFE044000387FC02208151008401F8001201FF002107FFC04401830E00E
+84B6:04400440FFFE04401010109024887D040A0211F824487C480088548855288210
+84B7:0820FFFE08201FF010101FF000003FF820083FF820083FF820083FF808201010
+84B8:08200820FFFE08201FC000447D88055009203118C50602003FF8000024884244
+84B9:0820FFFE082010100820FFFE04403FF80448FFFE04483FF80C603458C4460440
+84BA:0820FFFE092000801FFC1000920053F8544010403FFE504090A0211022084C06
+84BB:08200820FFFE082000007EFC02047EFC40807EFC020422441A3462C414280810
+84BC:08200820FFFE092006C01A30E10E1FF010101FF010101FF010002FF848088FF8
+84BD:0820FFFE082000003FF821082FE82288244828283FF8010008844892481287F0
+84BE:08200820FFFE08202040124811500040F7FC10E01150124814441040280047FE
+84BF:0820FFFE08200200FFFE00001FF010101FF000007FFC40044FE448244FE4400C
+84C0:04400440FFFE0440000C7DF00440088811F010201C44F3FE1022112452222060
+84C1:0820FFFE082001007FFC01003FF80200FFFE082017D02108DFF6054009201110
+84C2:08200820FFFE08207FFE40029FF410101FF010101FF00100FFFE082010102008
+84C3:0820FFFE08200500397821083D7821083FF801003FF00820044003801C70E00E
+84C4:0820FFFE08200100FFFE08201FC003100C083FFC00043FF821083FF821083FF8
+84C5:04400440FFFE0440202017FE1080810843FC500411502150E15022522252244E
+84C6:0820FFFE092000803FFC222022203FFC222023E020802FF8488848A888900080
+84C7:0820FFFE08201FF010101F9010907FFE40029FF410101FF010101FF010101030
+84C8:08200820FFFE082004003F7C21443F4821503F48284424442A54324820400040
+84C9:08200820FFFE0A2001007FFE400289241290244808203FF8C82608200FE00820
+84CA:0820FFFE0820044008203218C4460FE000207EFC224412240A1412242A544488
+84CB:0820FFFE082001003FF801007FFC080010103FF800003FF824482448FFFE0000
+84CC:0440FFFE04401110111029287FFC0100FFFE08001FF02820444003801C70E00E
+84CD:0820FFFE0A203FC00280FFFE02200FC03408C3F800001FF010101FF010101FF0
+84CE:0820FFFE092000803FFC20802FF820883FFE20882FF820804FF848088FF80808
+84CF:08200820FFFE08200000061C38E828A82CA82AA82AA82AA828A455545D748212
+84D0:0820FFFE08203FFC20002FF820003FFC24482430260E20205FFC442082A00040
+84D1:0820FFFE082001007FFC00001FF01010FFFE10101FF0048808503820CB180C06
+84D2:04400440FFFE044008007F7C08107F1049107F1049FE7F100810FF9008100810
+84D3:08200820FFFE08A0104017FC20006208A1102FFE200023F82208220823F82208
+84D4:04400440FFFE0440082004407FFC010001003FF801000100FFFE248822444244
+84D5:04400440FFFE04401020102011FCFC20102033FE3800542051FC9020102013FE
+84D6:0820FFFE082002003FF82448238824483FF8000020843E9820E020842684387C
+84D7:08200820FFFE0820104023F84040884017FC3040524092781240154018FE1000
+84D8:0820FFFE0A2001007FFC08201210244848241FF00510088818502920CA180C06
+84D9:08200820FFFE092000803FFE2080249024902AA831C420802FF8408040809FFE
+84DA:08200820FFFE0820108011FC228828706B8EA8202848299028642988203021C0
+84DB:04400440FFFE044008200820FFBE08447FA449244B281C282A10492888440882
+84DC:08200820FFFE08207F7C140414047F04557C574061407F40414241427F3E4100
+84DD:08200820FFFE08200480248024FC24A0251000003FF8244824482448FFFE0000
+84DE:08200820FFFE082000FC7F00220811100C20307820083C78200820083FF82008
+84DF:04400440FFFE044010041F0422247FA4A4A43FA424A43FA40004078478142008
+84E0:08200820FFFE09200080FFFE0440139014501FF001007FFC44444FE44424400C
+84E1:08200820FFFE082023F8100811F8800843F8500017FC2404E3F8211020E0271C
+84E2:04400440FFFE144008003E7C22443E44227C3E442244287C24442A4432942108
+84E3:0820FFFE082000007DFC0420284011FCFD041524112411241124105050882304
+84E4:08200820FFFE0820404023F820400FFE1110128824F4E11022A0204021B02E0E
+84E5:08200820FFFE082000007FFE410282840C603018DFF601003FF8111009207FFC
+84E6:0440FFFE04401FF010101FF01010FFFE10102FC8C04608400FF800087FA80010
+84E7:08200820FFFE0820108011F822886870ABAE282029FC282028A8292422A42040
+84E8:0440FFFE0440108011FC228828706B8EA80029FC290429FC290429FC2104210C
+84E9:0820FFFE082000807CF805082A901060FD981606304053F89048108851502620
+84EA:08200820FFFE082047F8211020A007FCE44427FC244427FC2444245454088FFE
+84EB:0820FFFE082023FC10801144066870B01128166810A4112416A0284047FE0000
+84EC:0820FFFE0820010023F0151010E0071C704013F8104011F0104017FC284047FE
+84ED:0820FFFE092000803FFC20803FFC222024902FF8349427F0249047F24082807E
+84EE:0820FFFE0820004027FC104013F8024873F8124813F8104017FC284047FE0000
+84EF:04400440FFFE04401110211041108AA8144430405240927C1240154014FE1800
+84F0:04400440FFFE04401020213C4120892017FE300050209120113E112012A0147E
+84F1:08200820FFFE08202108109093FC40904890089017FEE0902090211021100210
+84F2:0820FFFE082000003FF8200027F0241027F020002F7829482F7820003FFC0000
+84F3:0440FFFE044008207FFC08200FE001003FF821083FF801007FFC0100FFFE0000
+84F4:0820FFFE09207FFC01003FF821083FF821083FF801047FFC0020FFFE08200460
+84F5:04400440FFFE0440102013FE1020FDFC102413FE1C24F1FC1020113C512022FE
+84F6:04400440FFFE044000A0009079FE49204B204DFC492049FC7920492001FE0100
+84F7:04400440FFFE044010A01090F9FE11201B2015FC3120D1FC1120112051FE2100
+84F8:0440FFFE04407FFC04403FF824483FF824483FF800001FF010101FF010101FF0
+84F9:04400440FFFE0440140027DE4912811217D221126112A5D2251A25D42E102410
+84FA:08200820FFFE0820104010407C4010F8FE48444892C87C4810AA1CAAE1064202
+84FB:08200820FFFE0820104010407C4011F8FE48444828C87C4810AAFEAA11061202
+84FC:0820FFFE08203CF824481428254806C01830E30E0C403180063038C007003800
+84FD:0820FFFE08203FF821083FF821083FF80920FFFE09203FF801007FFC01000100
+84FE:08200820FFFE092001FC01003FF829282448228829282288244829283FF82008
+84FF:0820FFFE082001007FFE48028BF4108033F85208920813F81208120813F81208
+8500:04400440FFFE04401000087C7F4422481450FFC800443E44225422483E402240
+8501:0820FFFE09203FF80440FFFE00001FF010101FF010101FF00100FFFE01000100
+8502:0820FFFE08201FF011101FF011101FF0040008201FC003103FF8112025104208
+8503:08200820FFFE08207CF8048804F87C2041FC41247D2405FC042004242BFE1002
+8504:08200820FFFE08207C7C44447C7C44447C7C40044FE4482448244FE440144008
+8505:0820FFFE08207C7C44447C7C44447C7C41044FF442444644418442444C24400C
+8506:08200820FFFE0820204013F8104087FE4110528814F42110E2A0204021B02E0E
+8507:08200820FFFE082000007DFC44207D20452045FE7C50505048925492610E4200
+8508:0820FFFE082000007FFC04403FF824483FF800003FF80000FFFE111025080200
+8509:0820FFFE08200100FFFE101020085FF4101010101FF0048808503820CB180C06
+850A:04400440FFFE044011FC110415FC550459FC500091FC10202BFE242044208020
+850B:08200820FFFE0820220013BE921242125FD210142214EA88324822142A242442
+850C:0820FFFE082000000820FFA0083E7F42499449107F101C102A28492888440882
+850D:08200820FFFE092000803FFE22203FFC22243FFC284028482F7048444B448C3C
+850E:04400440FFFE244010F8FC8800887906020079F8008878884850482078D84B06
+850F:0820FFFE0A2001007FFC082004407FFC4444482457D4644C444447C440144008
+8510:0820FFFE0A2001007FFC082004407FFC41045FF441044FE448244FE44004400C
+8511:0820FFFE082000003FF8244824483FF800903FFC208030482850242440D4830C
+8512:0820FFFE082000003FF80208FFFE04083FF808001FF82808CFF8000024444222
+8513:0820FFFE08201FF010101FF010107FFC44447FFC00003FF0082007C01830E00E
+8514:0820FFFE28203FFC4004BFE400041FC410441FC400043FE422243FE422243FEC
+8515:0820FFFE0820145014507FFC245247CE80007FFC41041FF01110115011200100
+8516:0820FFFE092001F801003FFC21042FE0210827F8241027F0241047F044109FFC
+8517:08200820FFFE092000803FFC222022203FFC2220222023E020004A4849249124
+8518:0440FFFE044008201FF0102025487EFC04401930E64E1990062018C007003800
+8519:08200820FFFE082020401040FEFE210020003DFE2422242024BC44A055608A3E
+851A:08200820FFFE082000003F0821083F0820FE2E0820483F2844285508A4A80C10
+851B:08200820FFFE082010041F2422147F84A4A43F9424863FBC2484248442848104
+851C:04400440FFFE0440082008207F3E08443EA40824FF2810281E1022284A448482
+851D:04400440FFFE04400020792448A848207BFE487078A848A849247A2248200020
+851E:0820FFFE082001003FF82108FFFE21083FF811101FF00400FFFE082007C07838
+851F:08200820FFFE082020401040FEFE212020403CFC2520242025FE445054888906
+8520:08200820FFFE0820104010FC24887D50082010D827067C60001054C054308008
+8521:0440FFFE044010801EF822885450282017D82006DFF001001110210845040200
+8522:0440FFFE0440202013FC82244BF812882450E470298C2400FFFE082007C07838
+8523:08200820FFFE08200440247C24A83D50042804487DFE24882448244844088418
+8524:0820FFFE0A2001007FFE42028924284849940E1077F00100210821083FF80008
+8525:08200820FFFE092002003FF8220827E82A48218826483FF801004884481287F2
+8526:0820FFFE082004001FF010101FF010101FF010001FFC10001FFC492484940008
+8527:0820FFFE08201010FEFE10107C7C1010FEFE10103FF800081FF800083FF80008
+8528:0820FFFE08207FFC45445FF442047FFC482457D4644C44C4442443E440047FFC
+8529:0820FFFE0A2001007FFE4002BFFC01003FF821083FF821083FF8101020084004
+852A:04400440FFFE044008067F7808407F40497E7F4849487F4808487F4808880908
+852B:0820FFFE08207FFC010011F81100FFFE10001FF820003FFC0004492484940008
+852C:0820FFFE082000107DFE0420184851FE50025CA850A850A85D2A712AC22A0406
+852D:0820FFFE0820004078A04910524865F4502048404BF8680057FC4080411043F8
+852E:04400440FFFE04407FFC40A47FFC40845E9452945E64405446B459147FFC4004
+852F:04400440FFFE044000207BFE482051FC612451FC492449FC687050A841244622
+8530:0820FFFE09203FF820083FF8200027F0241027F020002FF828884FF8480287FE
+8531:0820FFFE082022001478084814482A8609007EFC08442A4449288910282810C6
+8532:0820FFFE0A2001007FFE400280443E40007C7E88155014201452248A43FE8000
+8533:0440FFFE044023F8104013F8804047FE500013F82208E3F8220823F822082218
+8534:08200820FFFE092000803FFC242024203F7C24202E702D6834A4452244208420
+8535:04400440FFFE044800243FFE20202FA42A242FA828A82F902A124FAA40468082
+8536:0820FFFE09207FFC01003FF80100FFFE10101FF010101FF010101FF008201010
+8537:0820FFFE082001003FF811100920FFFE00003FF8200827C8244827C820083FF8
+8538:08200820FFFE0920120067DC444447C4444457DC60000440044008421042603E
+8539:04400440FFFE044008200820143E22445DA48024112809284A1027A8F8444082
+853A:0820FFFE0820200017FC050444844FF459046FE449044FE449044FF448144008
+853B:0820FFFE0A2001007FFE400280243E3800207EF81408145014242454248443FC
+853C:0820FFFE082043F8220823F80208E3F8210023FC244422A42A0433F420140008
+853D:04400440FFFE0440082049202A3E7F4449A449245D286B284910412845444282
+853E:0820FFFE08200640387C08947E241C442A9449080100FFFE054009203118C106
+853F:0820FFFE082000F87F00221011201FE010201FF010101FFC20042AA44AA4800C
+8540:0440FFFE044010101010FEFE1010FEFE92929292969638385454929210101010
+8541:0820FFFE08203FF000101FF000103FF000003E7C08447F7C0020FFFE08200460
+8542:0440FFFE044000203D2424A825FC3C4027FE24883D2426FA2448444854A88910
+8543:0820FFFE082000F83F0011100920FFFE09203018DFF611101FF011101FF01010
+8544:0820FFFE08207C7C44447C7C44447C7C410440844AA44A144A5451C440144008
+8545:08200820FFFE082023F8124893F842484BF8084017FCE444245425F42414040C
+8546:04400440FFFE044800243FFE20202FA428A42FA828A82F9028924FAA45468882
+8547:0820FFFE08203EF822883EF800001FF011101FF011101FF00100FFFE01000100
+8548:0820FFFE08207FFC04403FF824483FF810101FF010101FF00100FFFE01000100
+8549:08200820FFFE092008801FFC30805FF810801FF810801FFC1000248822444244
+854A:08200820FFFE0820082001002488242443E4000024241212A0A0A4A41C1C0000
+854B:0820FFFE0820010011F811001100FFFE081008104E9C489048904E90F1FE0000
+854C:04400440FFFE04401FF010101FF010101FF000007EFC42847EFC42847EFC4284
+854D:0440FFFE044020A01110120885F64000578414A427A4E4A427A4248424942588
+854E:0820FFFE082000701F800200FFFE082037D8C4463FF8200827C8244827C82018
+854F:08200820FFFE0820004453F42048505097FE108031FC530495FC190451FC2104
+8550:0440FFFE04407FFC1110292845441110292845447FFC0100FFFE010001000100
+8551:0820FFFE08207C7C44447C7C44447C7C400447C4444447C4444447C4445448C8
+8552:0820FFFE08203FF824483FF800001FF010101FF010101FF010101FF008201010
+8553:0820FFFE08203FF801007FFE41029D7401001D7000003FF80000FFFE10103FF8
+8554:0440FFFE0440100010FC7C841094FE88448028FC7CA410A4FEA8109010A810C6
+8555:08200820FFFE0820228814500BFE145025FC4D54158C250445FC850429FC1104
+8556:0820FFFE082023FC120043F82A080BF8720013FC1100FFFE05401930E10E0100
+8557:08200820FFFE0820008078F849084A907860119812065DF8510851085DF8E108
+8558:0820FFFE082001003FF80100FFFE08203EF808207EFC00007FFC04401842E03E
+8559:0820FFFE09203FF801001FF011101FF011101FF001087FFC02044908482487E4
+855A:0820FFFE08201FF010107FFC44447C7C00003FF80000FFFE10001FF800080070
+855B:08200820FFFE08200C88705011FC1024FDFC312039FE546250AA912412201020
+855C:08200820FFFE082004407C7C04403C7804407C7C0440020009084924482487E0
+855D:04400440FFFE0440108010F825087E1009FC112425247DFC01005502550280FE
+855E:0820FFFE08201FF010101FF01010FFFE22003EFC22443E4422282F10F22842C6
+855F:0820FFFE08A03E900464282810103EF8C2961E90110C20F03E90026014900908
+8560:0440FFFE044008007F7C114432440C44367CC8801F0002103FF8010815202210
+8561:0440FFFE05407FFC0920FFFE08203FF820083FF820083FF820083FF808201010
+8562:0820FFFE09201FF011101FF00100FFFE10101FF010101FF010101FF008201010
+8563:0820FFFE082000FC7F00220811107FFE400290243DF84420A92011FC2020C020
+8564:0820FFFE08200010FF50107C29904E10967C2510CD1014FE2440C430140E0800
+8565:0820FFFE082000507E4804FE2490259044FE7E900C9014FE2490449094FE0880
+8566:0820FFFE082000000BFE102021FC490411FC210445FC090411FC2000C0880104
+8567:0820FFFE0820020013FC240043F88A0813F8320853F8910013F8151010E0171C
+8568:0820FFFE082000003FFE289025102FBE22222AD42A902F902228442844448882
+8569:08200820FFFE082023F8120893F8420843F810002FFEE20027FC292422540488
+856A:04400440FFFE044010003FFC4AA00AA07FFC0AA00AA07FFC0000248822444244
+856B:0820FFFE09201FF004407FFC00001FF011101FF011101FF001003FF80100FFFE
+856C:04400440FFFE04401020102024407C8809F0102024487DFC002054A855248060
+856D:0820FFFE09203FF80108FFFE01083FF825483D7821083FF821083D7825484548
+856E:0820FFFE082002001CF010101EF010101FF008001FFC20044924249424944008
+856F:0820FFFE0820010079F04A9050606198560649F04A406BF8544043F8404047FC
+8570:04400440FFFE044023F8120893F842084BF8080017FCE524252425242FFE0000
+8571:04400440FFFE04400C20712410A81020FDFC310439FC550451FC910411141108
+8572:0820FFFE0820220C14707F4049407F40497E7F480848FF480848088808880908
+8573:08200820FFFE08207C7C44447C7C44447C7C40044FE448244FE448244FE4400C
+8574:04400440FFFE044021F8210845F88908F1F8200043FCFA9402941A94E7FE4000
+8575:0440FFFE0440204020A021583A264DF8490849F8A90811F81144212841508188
+8576:0820FFFE08203FF801007FFE41029D7401001D7006C01930EFEE004006800100
+8577:0820FFFE082000007DFE042028FC1084FEFC128414FC108410FC100050482084
+8578:0820FFFE0820000047BC248427BC0400E7BC240427A82410242854448FFE0000
+8579:0820FFFE0A200100FFFE10A0209045FE7B2011FC25207DFC0920112021FEC100
+857A:0440FFFE04403E2822243E240020FFFE22203E2822283E1022122F2AF2464282
+857B:08200820FFFE082000483E4820483CFC20483C482048FEFE20004448FE844302
+857C:0440FFFE044000203EFC20243DFE20243CFC2020FEFC102025FE7E2022200020
+857D:0820FFFE082002401FF812481FF812483FFC20002FF820003FFE24484530860E
+857E:0820FFFE08203FF801007FFE41029D7401001D7000003FF821083FF821083FF8
+857F:0440FFFE0440101E13E0152254945BFC504097FE108011FC2A48243044488186
+8580:08200820FFFE082023F81248924842A84BF8080017FCE4A424A424A42FFE0000
+8581:0820FFFE082004003FF8292825482FE8254828280100FFFE02800C603018C006
+8582:0820FFFE082010003E2022203E3E22443EA408247F2810281E1022282A444482
+8583:0440FFFE0440202017FE100081F8410851F8100027FEE40225FA250A25FA2406
+8584:0820FFFE0820004827FC104013F8824843F84A480BF81248F01027FC22102130
+8585:0820FFFE082023FE2200FAFC4A004BFE4AA4929852C6220853FE4A8884480818
+8586:0820FFFE082000F87F00221011207FFC4204292847E408001FF0282007C0F83E
+8587:04400440FFFE044022204AA08ABE1FC420A46F24A0282F28291029A829443082
+8588:0820FFFE092002800C6037D8C0063FF829283FF800001FF010101FF010101FF0
+8589:0820FFFE092011F81100FFFE00243FFE20202FA422242A182A90512A46469882
+858A:04400440FFFE044010041F0422247FA4A4A43FA424A43FA400042A8445540008
+858B:0820FFFE492021FC0A44F0B0230E3FF010101FF010101FF010101FF008201010
+858C:08200820FFFE0820210027DE545297D4E458245457D29512F49A255446108410
+858D:0440FFFE04407F102A107F1012100C107F904A905E9040905E924A9244924B8E
+858E:0820FFFE08207FFC44447FFC00007FFE4922911431FC5F1090A0104411A4161C
+858F:0820FFFE082001003FF80820FFFE00001FF010101FF010101FF04904489287F2
+8590:04400440FFFE04400C2071FC102013FEFC8831443A7A54885150902010D81706
+8591:0820FFFE08207FFC00003FF821083FF82108FFFE00003FF821083FF82108FFFE
+8592:0440FFFE044008000F7828087F28A110162838C4D11009207FFC05401930610C
+8593:0820FFFE082023F8100813F8800847FC544413F82248E04027F8211020E02F1E
+8594:0820FFFE09207FFC111029284544FFFE00003FF8200827C8244827C820083FF8
+8595:0820FFFE082001003FFC22203FFC22402FF822483FFC22482FF846604A50B24C
+8596:08200820FFFE082021F8110811E8012873FC120412F4129412F412142A0847FE
+8597:0820FFFE08207FFC41044FE441045FF440044FE448244FE446944A6452147FFC
+8598:0820FFFE0820004023F8104017FC0110F7FC104013F8104017FC1040284047FE
+8599:04400440FFFE044020A020907DFE9120132011FCFD2011FC2920252041FE8100
+859A:0820FFFE082000FC7E8410FC10843CFC240047FEA48019FE0A521092212A4044
+859B:08200820FFFE082010407C2045FC44887C5043FE40207C2045FC44207C204420
+859C:0820FFFE082000403E2022FC22883E5021FE20203E2052FC52209E2012200020
+859D:0820FFFE08201FF020207FFEA4882BF4200027F8200027F8200047F8440887F8
+859E:0820FFFE082000407EA0119812463DF8250845F8A50819F80944112821904108
+859F:08200820FFFE092002800440183067CC00003EF8228822883EF8082014502288
+85A0:08200820FFFE082013FC104015F8550859F8510891F8110829F8249045088204
+85A1:0820FFFE08201FF010101FF010105FF450145FF440047C7C0440FC7C24444444
+85A2:04400440FFFE044020FC3C244444BE8C2A503E7C2A903E102AFE2A1042108610
+85A3:0440FFFE04400810FF1008FE7E1000107EFE42427E44422824100E28F0444182
+85A4:0820FFFE082000507E5011DC10503C5025DC6450945009DC0850105023FE4000
+85A5:0820FFFE08203FF824483FF808001FFC2204DFC412441FC402243FE410280010
+85A6:0820FFFE09203FFC24403FF824483FF8240027FC28002FFC20044AA451548008
+85A7:0820FFFE09207FFC00001FF010107FFE4002BFF408401F48625014621842E03E
+85A8:0820FFFE08207FFC44447FFC00007FFE4002BFF408401F48625014621842E03E
+85A9:0440FFFE0440002079FC4888505063FE52204AA04AFC6B2052FC4420442049FE
+85AA:0820FFFE0820100008047F7822401440FF7E08487F4808482A484988A8881108
+85AB:0820FFFE08203FF80100FFFE11101FF011101FF001003FF80100FFFE24884244
+85AC:0820FFFE0920020047C4244817D0244847C40100FFFE054009203118C1060100
+85AD:0440FFFE044000200C4071FC112411FCFD4431FC3850549051FE901010101010
+85AE:0440FFFE0440000049202A20FF3E2A4449A41024FE282228641018282444C282
+85AF:0820FFFE08203FF824483FF802001FD00220FFFE03000FF03810CFF008100FF0
+85B0:0820FFFE08203FF80100FFFE01003FF829283FF801003FF80100FFFE24484224
+85B1:08200820FFFE0820140855083608147E7F0814487F2808283E0808080F287810
+85B2:0820FFFE09207FFE40029FF4092011C006001FF868080FF808080FF804100808
+85B3:0820FFFE0820004023F8104017FC000073F8120813F810C411A812902C8847FE
+85B4:0820FFFE09207FFC4204A92847E400003FF82448FFFE00007FFC010005000200
+85B5:0820FFFE09207FFC01003FF80000FFFE00023FF00100FFFE00107DFC44907C30
+85B6:0440FFFE0440080031FCCB242D2431FCC924152425FCCC2015FC2420D4200BFE
+85B7:0820FFFE08203FF801007FFE41029D7401001D7000007FFC02003FF824482458
+85B8:0820FFFE0820200017FC10A087FC44A457FC100027FCE0002FFE2040224824C4
+85B9:0820FFFE0920FFFE01003FF800001FF010107FFE48229FF401003FF80100FFFE
+85BA:0820FFFE08200100FFFE02887D7025484D6690101FF010101FF0101020104010
+85BB:0820FFFE082022481490124883F8424853F8124823F8E0402FFE215022482444
+85BC:0820FFFE09203FFC24403FF824483FF828402F7828442F3C20804FF840809FFC
+85BD:0820FFFE082000007F7C14207F20553855287F48086808587F4A084A0F6AF046
+85BE:0820FFFE08207FFC111021087FFCB55A29283558210835582928355820082018
+85BF:08200820FFFE0820247C3A0422281E1020FE3E124850085E7F5014B0229E4100
+85C0:0440FFFE044008202AA44D28145022887FFE410291141120228004401830E00E
+85C1:0820FFFE082001007FFC08200FE000007FFC48244FEC01007FFC05401930E10E
+85C2:0820FFFE08207F00227C3E0422283E1023A8FE4403F87F04118863700D18F106
+85C3:0440FFFE044008207F2000203E3E22423E8400107F1041105D2855285D444382
+85C4:0440FFFE044008207FFC08200FE00820FFFE14502F8841241FF0011009201310
+85C5:0820FFFE08207FFC44447FFC0800FF8400247F2400247F2400247F0441147F08
+85C6:0820FFFE0A2001007FFE4442BFFC0440FFFE082031D8CF0601007FFC01000300
+85C7:04400440FFFE04400A0033B822083A38238820883AB82288FFFE082010102008
+85C8:0440FFFE04400020F7A490A89292F114920895F4F84293F89040F0A091100608
+85C9:08200820FFFE082010487CFC10487C4811FEFE0010FC388454FC948410FC1084
+85CA:0440FFFE044000200DFE7102110211FEFD0031FE39AA56AA52FE94AA10A21086
+85CB:0820FFFE08203EF812480A28124808801FFC30805FF890801FF810801FFC1000
+85CC:0820FFFE0A2001007FFC42442B904C2837E0C1001FF011101FF001087FFC2004
+85CD:0820FFFE082000003F2024203F3E21403F5024883F0800003FF824482448FFFE
+85CE:0820FFFE09203FF80108FFFE01083FF801007FFC248842443FF824482448FFFE
+85CF:0440FFFE044800241FFE502057A0752417A4F4A857A85510951227AA20464082
+85D0:0820FFFE082008103020CAFC2C843084C8FC14842484CCFC1448244AD48A0906
+85D1:0440FFFE14401FE020207FF8A30824881FF011101FF008001FF0282007C0F83E
+85D2:08200820FFFE08200DFC710411FC1104FDFC308039FE56225552910211FA1006
+85D3:08200820FFFE082020443E2844FEFF1049107F7C49107F1000FE0F10F0104010
+85D4:0820FFFE0A207FFC4104BFF8044028281FF02828CFE608200FE0010015102208
+85D5:0820FFFE0820100011FC7D2411FC7D2411FCFC2013FE3A22562A92FA120A1206
+85D6:0820FFFE08203F7C24443F2821103F2824463FF010101FF010101FF008201010
+85D7:0440FFFE044042102F9022100F9E0AA2EA882F88220827142A94322252428FFE
+85D8:0820FFFE092001F801003FFC21042FE0210827F8249027F0249047F44A4A93FA
+85D9:0440FFFE0440100008787F48224814867F0010FC694416446D281490642818C6
+85DA:0820FFFE09207FFC01003FF824483FF810101FF010101FF010101FF008201010
+85DB:0820FFFE0A2001007FFE42029CF410101EF010101FF008001FFC20040AA412AC
+85DC:0820FFFE08200640387C08947E241C442A94490802C01D30E92E054009201310
+85DD:0820FFFE08203E2008F87F282A285D6A082A3E5600823FF80000FFFE10103FF8
+85DE:0820FFFE082000007FFC08001FF02810CFF000007EFE20407EFCA3443E7C2244
+85DF:04400440FFFE04403FF821083FF821083FF80000FEFE9292FEFE9292FEFE8282
+85E0:0820FFFE092002001FF010101FF010101FF020407EFC42847EFC42847EFC4284
+85E1:0820FFFE08A0404027FC211000A007FCE44427FC244425F4251425F4540C8FFE
+85E2:04400440FFFE044022204AA08ABE1FC420A46F24A0282FA822102FA822442F82
+85E3:0820FFFE08207FFC44447FFC24987EE000847E7C42007E9842E07E844284467C
+85E4:0440FFFE044000203D2424A825FC3C4027FE24883D2426AA247044A855248A62
+85E5:04400440FFFE044021104BA472B823904AA47BBC0100FFFE05401930E10E0100
+85E6:0820FFFE08A03FFE24103F7C26382D5434122FF8208027F820805FFE40808180
+85E7:04400440FFFE0440103C13C025447CA809FC104027FE7C8000F85548563080CE
+85E8:08200820FFFE09203FFC24403FF824483FF828402F7828442F3C40004A489124
+85E9:0820FFFE0820203817C01248815047FC524814042BFAE24823F8224823F82208
+85EA:0440FFFE044008007F204920FFBE49447FA42A243E281028FF1022281C446282
+85EB:0820FFFE0820000027FC10A017FC84A447FC520813F82208E3F8204027FC2040
+85EC:0820FFFE08207DFC452449FC482053FE490445FC450455FC490441FC40884104
+85ED:0820FFFE09207FFE5022A8143EF822083E0822F83E8022FCFE0412042228CE10
+85EE:0440FFFE044010A0109011FEFD2013FC312039FC552051FE900012A412521452
+85EF:0820FFFE08203F0821083F7E20082F4820285FA8440895282C900100489487F2
+85F0:0820FFFE08207784428462A454A469A414242224DD2408247F244A042F94F008
+85F1:08200820FFFE092000803FFC2100AFF868882FF86888AFF8215042F84C8AB07E
+85F2:04400440FFFE0440100013FE1200FE7C1244327C3A0056EE52AA92EE120013FE
+85F3:0440FFFE05407FFC08200FE000007FFC48244FEC00003FF80100FFFE0920711C
+85F4:04400440FFFE144010F824887CF8088810F824007DFC01545554555483FE0000
+85F5:0820FFFE08200BF8120833F8504097FE115012480100FFFE06801C48E530060E
+85F6:0820FFFE08203FFE21042E3822102FBC27182AB432522040247C444044409FFE
+85F7:04400440FFFE044020201022FDFC00287BFE004079FC068478FC488478FC4884
+85F8:04400440FFFE04400022FCFA2024602895FE344058FC948435FC568490FC2084
+85F9:04400440FFFE0440200011FCFD0401FC790401FC788001FE7A224D5279FA4806
+85FA:0820FFFE08207C7C44447C7C44447D7C44844FE459044FC449044FC449044FEC
+85FB:0820FFFE082023F8120813F8800047BC54A417BC2040EFFE215022482C462040
+85FC:0820FFFE09207FFC41043FF801001FF001007FFC24483FF801004884489287F2
+85FD:04400440FFFE044008007F7C2244147CFF44087C7F44087C2A28492AA94A1086
+85FE:04400440FFFE14401080FEF811087EFC548454FC7C8410FC388454FC90481084
+85FF:0820FFFE08203FF801007FFE41029D7408801FFC30805FF890801FF810801FFC
+8600:08200820FFFE082011FC1154FDFC102015FC182033FED08811FC102053FE2020
+8601:0820FFFE08207FFC01003D7825483D7801007FFC01003D7825483D780100FFFE
+8602:0820FFFE09202488242443E424281214A0A0A4A41C1C0100FFFE05401930E10E
+8603:0820FFFE092011F81100FFFE08102E5C28502E50F0FE01007FFC05401930E10E
+8604:0820FFFE0820770C5570774000407F7E49487F4849487F480848FF8808880908
+8605:0820FFFE0820220047DC888017C0257E67C8A54827C821082FE8210822A82450
+8606:0820FFFE092001F801003FFC21042FE0210827F8249027F024904FF849489FFC
+8607:04400440FFFE0440200C3E704410FF1049FE7F1049387F34005455528A900010
+8608:0820FFFE0820060038FE08107F7C1C442A7C49441C7C1444157C262824444082
+8609:0820FFFE08203FF82448FFFE901213F020102FFC6804A7F02210212020C02738
+860A:0440FFFE0440100010F824A87CA808D810F824007DFC01545554555483FE0000
+860B:04400440FFFE044009FE28202EFC2884FEFC088428FC2A8444FC08003048C084
+860C:0820FFFE0A2027DE491297D2211265DAA5142FD000003FF80000FFFE11102308
+860D:0820FFFE08A03F1004107FD0043E7FD255527FD204127FD20412FFE22AAA4544
+860E:0820FFFE08203FF801007FFE41029D7400003EF822A83EA822F83E844284867C
+860F:0820FFFE0820400049FE742044FC3C8400FC7C8400FCFE8410FC5400D2482084
+8610:04400440FFFE0440203C13C0FD4400A879FC00407BFE008078F849487A3048CE
+8611:0820FFFE08A03FFE22102FBC231826B42A5220003FFC44004FF8940827F80408
+8612:0820FFFE08A01CF0F11012F810A8FCF810A831FC392455FC552491FC1022101E
+8613:08200820FFFE08200C8070F811081210FDFC312439FC552451FC90001154122A
+8614:0440FFFE0440480075FE44203CFC00840CFC708410FCFE8410FC380054489084
+8615:0440FFFE04402020247C4AA4F81810E626104AFEFA10027CAA10AAFE051008FE
+8616:0440FFFE044020207DFC44887C5041FE7C2045FC7C2001007FFC05401930E10E
+8617:0820FFFE082000407C2045FC7C5043FE7C20A5FC3C2001007FFC05401930E10E
+8618:0820FFFE082001007FFC00003EF822883EF804403FF80440FFFE04901C60671C
+8619:0820FFFE08207F7848485E8664785F484A307F4C00007EFC22441A3462C4060C
+861A:08200820FFFE082020443E2844FEFF1049107F7C49107F1000FE55104A908A90
+861B:0820FFFE0820241024FEFF2024443CFE24023C7C2444FF7C5444627C40447E4C
+861C:04400440FFFE044029007DFC29043A4411547CE455F47C4410E4FD5410541008
+861D:04400440FFFE044008201420223E5D4280847710551077102228222855448882
+861E:04400440FFFE044008201420223E5D4480A47724552877282210222855448882
+861F:0440FFFE044001FC7CA845FC482051FC480445FC440455FC484042A4428A447A
+8620:0820FFFE0820104057FC524855547FFE100017FCF40455F4551455F4940417FC
+8621:0820FFFE08203EF822883EF822883EF822883EF814502288FFFE082007C07838
+8622:0440FFFE0440100008407E7C2440FF7C00047E7C42407E7C42407E7C4242463E
+8623:04400440FFFE044022207F10227EFF9008107F10497C7F1049107F1022FE4100
+8624:0440FFFE0440103C27C07A4449284BF84A087BFC4A044BFE7A024CAA04AA0906
+8625:0820FFFE092002800C6037D8C0063BB82AA83BB800003FF824883FF8248824B8
+8626:04400440FFFE04403FF801007FFE41029D7401001D7000003BB82AA83BB82AA8
+8627:0820FFFE08A000F840802FFC28840BF0E8882BF829402AA8317022A851608FFE
+8628:0820FFFE0820070CF87051102A2420783E104824FF7E081249544F5271920030
+8629:0820FFFE28203F20403EBE482AA8FF284A107F2808461F8002103FF811102308
+862A:0820FFFE09203FFC24403FF824483FF828402F7828442F3C44905FFC82A01C9C
+862B:08200820FFFE082027D01510179E84A047A8554417C42000E7F8252825282FFE
+862C:0440FFFE044010007DFC44047CFC40047DFC44007DFE11225CFC50A45EACF020
+862D:0820FFFE08207C7C44447C7C44447C7C41045FF441045FF455545FF44544592C
+862E:0820FFFE08203FF824483FF800003FFE22042A942514289422544A8445148888
+862F:0820FFFE082021F8110841F821080BFE090073FC14A4115412883FF82448FFFE
+8630:04400440FFFE044021FC210449FCF90413FE22524BFEF80001FCA888A870038E
+8631:0440FFFE0440100093FE5420FEFC388454FC928400FC1484FEFC280044488084
+8632:0440FFFE04401FF011101FF011103FF82AA83EF82AA83EF801003FF80100FFFE
+8633:08200820FFFE082022107F7C2210FF90087E7F0049107F10497C7F10227E4100
+8634:0820FFFE08201D7049245D7449245D7449247FFC00007FFC10101FF00820FFFE
+8635:0820FFFE08200094FDD2481249507BFE481049D4795449D44F48F9CA09560822
+8636:0440FFFE04400C20704011FCFD2439FC552493FCFC24245A685E10902912C60E
+8637:0440FFFE0440FFFE110013DE5A5253DE52505BD2E40E0FE0544483821C70E00E
+8638:0820FFFE08200050FE4810FE11907CFC549054FC6C9044FE7C8045547D2A462A
+8639:0820FFFE08A0104017FC10005BF856A853F892441158124410A8119016A810C6
+863A:0440FFFE0440100008287F24147E494855C87F7E08487F7E514855485D7E4340
+863B:0820FFFE08207F3C2A243E422A3CFFA449187F6608401F8002103FF811102308
+863C:0820FFFE08A03FFE24103F7C26382D54341221203F3E21202F3C41205F3E8120
+863D:0820FFFE08201FF011101FF011103FF82AA83EF82AA83EF801007FFC0920711C
+863E:0820FFFE08A0204027FC200023F8FAA823F822442118224438A8E19046A800C6
+863F:0820FFFE08207FFC44447FFC10A0209045FE792013FC25207DFC012055FE8100
+8640:0820FFFE0920FFFE02887D7025484D6682807EFC02803EF802807EFC0280FFFE
+8641:0440FFFE0440FFFE110013DE5A5253DE52505BD2E64E0FE0544483821C70E00E
+8642:0820FFFE08203FF801007FFE41029D7400403EFC23483E3009CE2E7828487E78
+8643:0820FFFE08202294129215508FFE42905EF412942EF4E2942EE8228A22F62F22
+8644:0820FFFE08A021F822882070FBAEA8F8A850FBFE22A02AFC3B20CA78042009FE
+8645:0820FFFE082001243CA825FC24403FFE248825FC3EA224F824A044FC54048AAC
+8646:0820FFFE08201FF011101FF011107FFC4AA47EFC4AA47EFC20087FFC11102308
+8647:0820FFFE08A87BFE08880BDE7A5243DE40A079FE09200BFC0D2009FC512021FE
+8648:0820FFFE082000007BDE489249124BD27A5E03C07A5E4BD24A524BD2799E4A52
+8649:0820FFFE08207F10007C3E44227C3E44007C7F40557E49407F7E490249AA4306
+864A:0820FFFE082021084FD2F03C23884812FBBE0280ABAA01007FFC05401930E10E
+864B:0820FFFE082077DC444477DC4444FFFE92921C7010101FF008201FF0642C0860
+864C:0820FFFE49202A3E7F4849485DA86B1049285FF612903EF822883EF8228A3DFE
+864D:0100010001F8010001003FFC200421082100211821E02F002104410440FC8000
+864E:010001F801003FFC210421602F88210820F8200023E02220222044244824901C
+864F:010001F801003FFC210421602F88210820F821002FF821082108420844509820
+8650:010001F801003FFC210421602F88210820F8200027F824003FFE440047F88000
+8651:010001F801003FFC210421602F88210820F82000208020442A424A12521081F0
+8652:0008007C3F80208020F820802FFE288228F02F84287C28004BE052229422281E
+8653:2020203E202021FEF922293829E02922291E29002B782D484948424A824A0486
+8654:010001F801003FFE210221F02F0420FC210020802FF822202140408043608C1C
+8655:010001F801003FFE210221F02F0420FC2400243827A828AA352A42464580987E
+8656:010001F801003FFE210221F02F0420FC201027E0224821502FFE404041408080
+8657:010001F801003FFE210221F02F0420FC2000201C27E0240027FE442044209FFE
+8658:010001F801003FFE210221F02F0420FC200027F8240827F8240847F84408BFFE
+8659:010001F801003FFC210421602F88210820F8210020882A242A445380460899F8
+865A:010001F801003FFC210421602F88210820F8224032482A482A5042405FFC8000
+865B:010001F801003FFE210221F02F0420FC2120292429242F3C212041205FFE8000
+865C:010001F801003FFC21042FE0210827F8249027F0249027F041005FF884080818
+865D:08200F2008207F7E496A4EAA782A492A474A40924E224A544A0A520291FE2000
+865E:010001F801003FFC21042FE0210827F8241027F020002FF820805FFC42209C1C
+865F:0020783E482049FE4922793801E0FD22211E41007978094809480A4A524A2486
+8660:2010101E0010FEFE0092289C44F08292048E448028B810A828A8452A852A0246
+8661:010001F801003FFE210221F02F0420FC200021202924252821205FFE42108408
+8662:04101E1EE01022FE9292549C40F00492FF8E048044B824A824A8052A152A0A46
+8663:08100C1EEA100AFE0892FE9C28F02892B88EA880AAB8AAA8B6A8C32A812A0246
+8664:10101E1E10107EFE52925C9C70F052924E8E40805CB854A854A8972A952A2246
+8665:10281E24102E7EF052285C12702A52D64E28402E5CF0542454285612942A20C6
+8666:2810241E2E10F0FE2892129C2AF0D692288E2E80F0B824A828A812AA2B2AC646
+8667:08000FBC08007FC048404F3E7890479052205FBE72025F8252025F8252149F88
+8668:08020F8208047FC848504F0278824784400848907DE248825DC46AA8489088A0
+8669:1020923E522055FE11227D3845E07D22451E7D00117859485548964A524A2486
+866A:2120213C39642318FA66AABEB2AAE6BEAAAA9ABE8288BABEAA88AE7E2A0042AA
+866B:0100010001003FF821082108210821083FF8210801000110010801FC7E040000
+866C:0840084008407F4049404940494049407F40484008400A440F44F144403C0000
+866D:0800080008FE7F2249224922492249227F22482208220A420F42F18241140208
+866E:1000100010F07C9054905490549054907C905090109014921C92E512410E0200
+866F:0804080408447F4449444944494449447F44484C08740A440F04F10440040004
+8670:0800080008FE7F1049104910491049107F10481008100A100F10F11040500020
+8671:00007FF0009003D07C1004103F902490249024903F900412048A07CA78462002
+8672:0820082008207F2049204930492849247F22482208200A200F20F12040200020
+8673:0820082008207F7C49444984490449447F24481408140A040F04F10440280010
+8674:1008101C10E07C20542054205420543E7DE05020102014221E22E222401E0000
+8675:1020102010207D20552C5534556457A47D245134112815221D22E50240FE0000
+8676:100011FC10207C2054205420542057FE7C205020102014201E20E22040A00040
+8677:0800087C08107F1049104910491049FE7F10481008100A100F10F11040100010
+8678:100011FC10047C0854105420542057FE7C205020102014201E20E22040A00040
+8679:1000100011FC7C2054205420542054207C205020102014201E20E22043FE0000
+867A:00200020FE2025FC25242524252425FC24202420242825FC2404440243FE8000
+867B:1020101010107C0055FE5480548054807C805080108014801E80E28040FC0000
+867C:1040104010807CFE5500560054FC54087C105020104014801D02E50240FE0000
+867D:00001FF0101010101FF0010001003FF8210821083FF80120011001F87F042004
+867E:100013FE10407C4054405440545054487C445044104014401E40E24040400040
+867F:0000FFFE040007F00810101020A041403FF8210821083FF8010001087FFC2004
+8680:2020202020203DFC45244924A124212421FC212420202028282433FE21020000
+8681:1040102411247D0455045488548854887C505050102014201C50E48841040602
+8682:100011F810087C0854885488548854FE7C025002100215FA1C02E40240140008
+8683:040008401F8003080C103FE000C0070079001FF0111011101FF001087FFC2004
+8684:1040102010207DFE544054405440547C7C445044104414441E84E28441280210
+8685:100011FE11007D0055785548554855487D485168115015421D42E542423E0400
+8686:1000100011FC7D2455245524552455247DFC5100110015001D02E50240FE0000
+8687:100010FC10847C845484548454FC54A07CA050A0109014901D08E50842040402
+8688:100011FC10887C8854885488548857FE7C885088108814881C88E50841080208
+8689:020001007FFC0820044003801C70E10E1FF0111011101FF0110001087FFC2004
+868A:1040102010207DFE54885488548854887C885050105014201E20E25040880106
+868B:1020102010207DFE55225522552255227D52514A118A15021D02E502410A0104
+868C:1020102010207DFC54205420542055FC7C205020102017FE1C20E42040200020
+868D:1010111011107D125512551455D855107D105110111015121D52E592410E0000
+868E:1000100010FC7C8454845484548454847CFC5084108414841E84E28440FC0084
+868F:100010FC10847C84548454FC548454847C8450FC108414841E84E28441140208
+8690:1040104010807CFC55045604548454447C445014102414441D84E40440280010
+8691:1020102010207DFE54205420542055FC7C845088104814501E20E25041880606
+8692:100010FC10847C8454A45494549454847DFE5084108414841C84E50441140208
+8693:100411E410247C24542455E4550455047D0451E4102414241C24E42441440084
+8694:1004101E11F07D1055105510551055FE7D105110111015081D0AE54A41860102
+8695:00003FF801000200FFFE044008203118DFF6111011101FF0110001087FFC2004
+8696:1000100011FC7C005400540057FE54907C905090109014901D12E512420E0400
+8697:1020102010207DFC54245424542454247DFE5020105014501E88E28841040202
+8698:1048104410447C4057FE5450545054507C505050109014921C92E512410E0200
+8699:1020102010507C5054885544562254207C0051FC100414081E08E21040100020
+869A:1008101C10E07C805480548054FE54887C885088108814881D08E50842080408
+869B:1020102010207C2055FC5524552455247D2451FC112414201E20E22040200020
+869C:100011FE10087C8854885488550855FE7C185028104814881D08E60840280010
+869D:1008103C11E07C205420543C55E054207C20503E13E014201E22E2224022001E
+869E:1020102010207C2055FE5420547054707CA850A8112415241E22E42040200020
+869F:1000100011FC7C2054205420542054207DFC5020102014201C20E42043FE0000
+86A0:044008203018DFE60420042008A0104021001FF0111011101FF001087FFC2004
+86A1:1010109010907C8855085504560455FA7C885088108814881D08E50842280410
+86A2:1040102010007DFC5400540054F054907C905090109014921C92E512410E0200
+86A3:1008104810487C485444548454A455227C205040104014481C84E5FE40820000
+86A4:00003FF012100920044003801C70E10E1FF0111011101FF0110001087FFC2004
+86A5:1010108810847C8455025602548854887C885050105014201E50E28841040202
+86A6:100010FC10847C84548455FE548454847C8451FE108414841E84E28440940088
+86A7:1020102010507C5054885504560254887C885088108814881C88E50841080208
+86A8:1020102010207C2055FC5420542054207DFE5020105014501E88E28841040202
+86A9:0100210821083FF80100FFFE000001003FF8210821083FF8010001087FFC2004
+86AA:1010111010907C9054105510549054907C10501E13F014101E10E21040100010
+86AB:1040104010FC7C84550456F4549454947CF45084109414881E82E282407E0000
+86AC:100011FC11047D0455245524552455247D245154105014901C90E5124212040E
+86AD:100011FC11047D04550455FC550055407D445148117015401D42E642423E0400
+86AE:1050105410527C925490559E55F056907C905090109014901E8AE28A40860082
+86AF:1004100E10F07C8054805480548054FE7C885088108814881C88E48843FE0000
+86B0:1020102010207C2055FC5524552455247D2451FC112415241D24E52441FC0104
+86B1:1080108010807CFE554055405640547C7C4050401040147E1E40E24040400040
+86B2:100011FC10207C20552454A454A854207FFE5020102014201E20E22040200020
+86B3:1004101E11F07D1055105510551055FE7D105110111015081D0AE54A41A60112
+86B4:201020902090F910A97EAA52AB92A892F912A11222522BD23862E822404A0084
+86B5:1000100013FE7C08540855E8552855287D28512811E815281C08E40840280010
+86B6:1088108810887C8855FE5488548854887C8850F8108814881E88E28840F80088
+86B7:100010FE10807C80548054FC548454847C84508410FC14801E80E28040FE0000
+86B8:1008101C11E07D005500550055FE55107D105130111815141D12E61042100410
+86B9:1044104410447C8454BE5584568454A47C945094108414841E84E28440940088
+86BA:1020102010207DFC5524552455FC55247D24512417FE15041D04E50441140108
+86BB:042004207FA00E20152224A2441E01001FF0111011101FF0110001087FFC2004
+86BC:1080108010807DFC5504560455E455247D245124112415E41D24E40440280010
+86BD:100011FE10107C1054205420546854A47D225222102014201C20E40043FE0000
+86BE:1010101010107DFE55125514551055FC7D445144112815281D10E62842440482
+86BF:1020101010107DFE54205420544454847DF85010102014441C82E5FE40820000
+86C0:1040102010007DFE54205420542054207DFC5020102014201C20E42043FE0000
+86C1:100011FC10447C4454445444549454887D0050FC108414841E84E28440FC0084
+86C2:1050104810487C4055FE54405440547C7CA450A410A815281D10E62840440082
+86C3:100011FE10207C20542055FE552255227D52514A118A15021D02E502410A0104
+86C4:1020102010207C2055FE5420542054207DFC5104110415041D04E50441FC0104
+86C5:1020102010207C20543E5420542054207DFC5104110415041D04E50441FC0104
+86C6:100010FC10847C84548454FC548454847C8450FC108414841C84E48443FE0000
+86C7:1020101010107DFE55025604548054887C9050A010C014821E82E282407E0000
+86C8:1020102011207D2055FC5520562054207DFE5020105014501E88E28841040202
+86C9:1020102010507C5054885524561254107DFC5004100814881E50E22040100010
+86CA:010001003FF8210821083FF8010001087FFC00043FF8244824482448FFFE0000
+86CB:7FFC0104110011F81100290047FE81001FF0111011101FF0110001087FFC2004
+86CC:1008101C11F07D5055505550555055507D505148114815681D54E67442520400
+86CD:2208111000207FFE4002810401003FF8210821083FF80120011001F87F042004
+86CE:100011FE11007D00550055FE552055207D3C5124112415241D24E64442540488
+86CF:100011FC10847C8854505420545054887F26502011FC14201C20E42043FE0000
+86D0:1050105010507C5055FC5554555455547D5451FC115415541D54E55441FC0104
+86D1:1020102010487C8455FE5412549054907CFE5110101017FE1C10E41040100010
+86D2:1040104010787C8855505420545054887D0650F8108814881E88E28840F80088
+86D3:082008287F240820FFFE002008247F24492449287F28481009120FAAF0464082
+86D4:1000100011FE7D025502557A554A554A7D4A514A117A15021D02E5FE41020000
+86D5:1020102011FE7C40544054FC548455847EFC5084108414FC1E84E28440940088
+86D6:1090108810807DFE54A054A854B054A47CA850B01124152A1D32E62242DE0400
+86D7:040008003FF020103FF020003FF820083FF801003FF821083FF801087FFC0004
+86D8:1104108410887C0057FE5420542055FC7C20502013FE14201E20E22040200020
+86D9:1020102011FC7C205420542057FE54007C20502011FC14201C20E42043FE0000
+86DA:2002200223E2F90AA90AA9EAA92AAA2AFB2AA2AA244A284A3882E902420A0404
+86DB:1020112011207DFC55205620542057FE7C7050A810A815241D24E62240200020
+86DC:2100217C2124FA24AA24AEFEAA24AA24FA24A27C22242A203A20EA2042400280
+86DD:100011F811087D0855F85508550855F87D445148113015201D10E54841860100
+86DE:1008103C11E07C20542057FE542054207C2051FC110415041D04E50441FC0104
+86DF:1040102010207DFE54005488550456027C885088105014501C20E45040880306
+86E0:2040204021FCF844A884A884A928AA10F908A3DE214A294A394AEA52435A04A4
+86E1:100013DE10427C425652554A554A54427CC6514A125214421C42E442414A0084
+86E2:1104108410887C0055FE5488548854887C8853FE108814881D08E50842080408
+86E3:1020102010207DFE5420542054FC54007C0050FC108414841E84E28440FC0084
+86E4:1020102010507C505488550456FA54007C0050F8108814881E88E28840F80088
+86E5:10201020107C7C8455485430542054487D90503E104215A41E18E21040600180
+86E6:1020102013FE7C2055FC542455FC55207DFE5022102A14541E50E28841040202
+86E7:100011FC11047D04550455AC555455547D54515411AC15041D04E50441140108
+86E8:100011FE10207C20544054FC548454847C8450FC108414841E84E28440FC0084
+86E9:00007DF01110119011521D12E20E45001FF0111011101FF0110001087FFC2004
+86EA:080008007F7C08243E2408447F54088809001FF0111011101FF001087FFC2004
+86EB:1040104010FC7D04560855FE5500557C7D445144115415481D42E542413E0200
+86EC:044004407FFC04400440FFFE082010102108DFF6111011101FF001087FFC2004
+86ED:100011FE10207C405488550455FE54227C20502011FE14201C20E42043FE0000
+86EE:02000100FFFE044014502448444401001FF0111011101FF0110001087FFC2004
+86EF:1040104010447DF45448545057FE54407C805184129814E01C82E482407E0000
+86F0:10801080FBF010901990F0941154520C25041FF0111011101FF001087FFC2004
+86F1:1020102010207DFC5420552454A454A87C2053FE105014501E88E28841040202
+86F2:2080208020BCFBC0A850A824A8D4AB0CF800A3FE209028903912E912420E0400
+86F3:208020BE2088FA88AABEAAAAAAAAAAAAFAAAA2AA22AA28AA392EE90842080408
+86F4:1040102013FE7C8854505420545054887D065088108814881C88E50841080208
+86F5:100011FE10007C9255245648552454927C0051FE102014201C20E42043FE0000
+86F6:1004101E11E07C2255125494548054087DFE5008108814481E48E20840280010
+86F7:1028102410247C2055FE5420552054B27CB4506810A815241E22E42040A00040
+86F8:1020112410A47CA8542055FC550455047DFC5104110415FC1D04E50441140108
+86F9:100011F810087CD0542055FC552455247DFC5124112415FC1D24E5244124010C
+86FA:1020102010207DFC542054A854A854A87D745222105014501E88E28841040202
+86FB:1010109010887D08560455FA550855087D0851F8109014901C90E5124212040E
+86FC:1020102011FE7C2055FC5524552455FC7D24512411FC14201DFEE42040200020
+86FD:100010FC10847C8454FC5484548454FC7C84508410FC14001E48E24440820102
+86FE:201020D82394F894A890ABFEA890A894F894A0D82398289038AAE8CA42860102
+86FF:1020102010507C885544562254F854087C10502011FC15041D04E50441FC0104
+8700:00003FF8244824483FF810001FFC22045FC4924412441FC4022403F47C142008
+8701:2100210021FEFA00AC00A9FEA822A824F920A13C212029203920EAA0447E0800
+8702:1040104010FC7C885550542054D857267CF8502010F814201FFEE42040200020
+8703:3FFC20002FF820003FFC24482430260E20802FF8288848884FF880841FFE0802
+8704:100011FE11007D00557C5500550055FE7D505152115415481D48E64442520460
+8705:1028102413FE7C20542055FC552455247DFC5124112415FC1D24E5244124010C
+8706:100011FC11047D0455FC5504550455FC7D04510411FC14501C50E4924112020E
+8707:080C08F07E8008800EFE788808882908120801003FF821083FF801087FFC0004
+8708:100011FC11047D0455FC5400540055FC7C20502013FE14201C50E48841040202
+8709:1008103C11C07C04554454A8540055F87C10502013FE14201E20E22040A00040
+870A:208421C42704F914A914A914AFD4A914FB14A39425542D043904E90441140108
+870B:1040102011FC7D04550455FC550455047DFC5120112215141D08E54441820100
+870C:1110111211147DD8551055125552558E7D20502011FC14201C20E42043FE0000
+870D:1020102010507C885504560254F854207C2053FE102015241D22E62240A00040
+870E:1000107C10447C44547C540054FE54827C8250FE108214821EFEE282408A0084
+870F:101C11E010207C2057FE54A8552456227DF85088109014BE1D02E50242140408
+8710:1088108810887DC8549E548A548A57EA7C8A508A110A154A1FEAE512402A0044
+8711:00187BE0104022787A400A402BFC10002FFE41003FF821083FF801087FFC0004
+8712:2004200E23B8F888A888A928A92EABA8F8A8A2A822A8293E3900EA80447E0800
+8713:2000200623B8F888A888A908A93EAB88F888A2882288293E3900EA80447E0800
+8714:1080108010FE7D02550256FA54AA54AA7CFA50AA10AA14FA1E8AE20240140008
+8715:1104108410887C1055FC5504550455047DFC5050105014901C92E512420E0400
+8716:100011FE114A7D4A554A557A554A554A7D4A517A114A154A1D4AE5FE41020000
+8717:200021FC2104F904A904A9FCA820A820FBFEA22222522A8A3B0AEA02420A0204
+8718:210021002100FBDEAA92AC92A892A892FBF2A09220922952395EEA2044200800
+8719:210421142114F914AFD2A922A92AAB48FB88A550251029143922E97E41220100
+871A:044004407C7C04403C7804407C7C044001001FF0111011101FF001087FFC2004
+871B:100011FC11047D0455FC5510551055FE7D105110117C15441D44E544417C0244
+871C:020001007FFE42028924284849940E1077F001003FF821083FF801087FFC0004
+871D:08207FFC08200FE008200FE00820FFFE10102108DFF611101FF001087FFC0004
+871E:1088108811FC7C88548854F8548854887CF85088108815FE1C00E48841040202
+871F:1020101011FE7C40548455FE540254FC7C8450FC108414FC1E84E28440940088
+8720:200023FE2202FA1AAAE2AA22AA22ABFEFA22A27222AA2B263A22EA2243FE0202
+8721:1048104810487DFE5448544855FE54007CFC5084108414FC1E84E28440FC0084
+8722:100011FC10087C10542057FE542054A07C4051FC115415541D54E55443FE0000
+8723:1088104810507DFC5420542055FC54207C2053FE105014501C90E4924112020E
+8724:080C08F07E8018802CFE2A884888888809081FF0111011101FF001087FFC2004
+8725:210021062138F920AFA0A920A93EAB24FBA4A564252429243924E92441240144
+8726:1020102010507C88550456FA540055FC7D54515411FC15541D54E5544104010C
+8727:2040202023FCFA04AA04ABFCAA00AA28FA24A3FE22202A503A50EC8845040A02
+8728:1020102013FE7C2055FC542457FE54247DFC50201120153E1D20E6A0427E0400
+8729:100011FC11247D245574552455FC55047D745154115415741D04E60442140408
+872A:1080108010FE7D02568254F2554254427FFA5042115215521DF2E40240140008
+872B:100011FC11047D0455FC5504550455FC7C00511211D415181D10E5524192010E
+872C:200021FC2008F810AA22AAAAAA72AA22FA72A2AA23262AA23A42EA0243FE0002
+872D:10401040107C7C8455085600542055CE7D02510211CE15021D02E50241FE0102
+872E:201420122010FBFEA810A810ABD2AA52FA52A25423D4280C386AEB8A41160022
+872F:1020102011FE7C2054FC544055FE54887D24522210F814201DFEE42040200020
+8730:00003EFC22A43EA422FC3E80228222824A7E85003FF821083FF801087FFC0004
+8731:1040108011FC7D24552455FC552455447DFC5090111017FE1C10E41040100010
+8732:101C11E010207C2057FE54A8552456427C4053FE108815081CD0E43040480184
+8733:1020101011FE7C0054FC548454FC54007CFC5008101015FE1E10E21040500020
+8734:100010FC10847C8454FC5484548454FC7C4050FE112A144A1C92E522404A0084
+8735:1050115411547D5455DC5504550455FC7D04510411DC15541D54E55442540404
+8736:1040102011FE7C0054885488555456227C00502013FE14201E20E22040200020
+8737:1020112410A87C2055FC544057FE54887D0452FA148814881CA8E4924082007E
+8738:00007EFC48447E4442287E1048287EC601001FF0111011101FF001087FFC2004
+8739:1088108813FE7C8854A8542055FC55247D245154114C15841D04E50441140108
+873A:20002040239CFA04AA04AB9CAA04AA04FBFCA090209028903890E9124212040E
+873B:1020102013FE7C2055FC542057FE54007DFC510411FC15041DFCE50441140108
+873C:10A0109010807DFE5510571055FC55107D1051FC111015101D10E5FE41000100
+873D:200023FE2020F820ABFEAA22AA22AB32FAAAA2AA23762A663A22EA22422A0204
+873E:100011FC11247D2455FC5524552455FC7C2053FE107014A81D24E62240200020
+873F:2040202023FEFA02AD04A900A9DEAA52FA52A352249A28943910E9124212040E
+8740:1020102013FE7C2055FC552455FC55247DFC5020107014A81D24E62240200020
+8741:00007FFC04403C7820083C780440FFFE01001FF0111011101FF001087FFC2004
+8742:2080228622B8FAA0ABE0AA3EAA2AAA2AFBAAA2AA22A42AA43AA4ECCA448A0892
+8743:100013DE10427D4A5484554A565254207C0053DE105215521C94E54842540422
+8744:200023FE2202FA8AAA52ABFEAA42AA22FBFEA28222822A823AFAEA02420A0204
+8745:3EF8082008207EFC08201450228841049FF2111011101FF0110001087FFC2004
+8746:10A810A813AE7CA854A8542055FC54207C20502013FE14201E20E22040200020
+8747:200021F02110F910A9F0A840ABF8AA48FA48A3F822482A483BFAE8424042003E
+8748:200023FE2202FA02ABFEAA22AA22AAFAFA22A232222A2BFE3A02EA0243FE0202
+8749:1104108810507DFC5524552455FC55247D2451FC102014201DFEE42040200020
+874A:2040202023FEFA02AC04A800ABFEA820F820A120213C29203AA0EA60443E0800
+874B:200024842244FA48A800ABF8AA48AA48FBF8A24822482BF83A4AEC4A44460802
+874C:20C427042124F914A914AF84A924A914FB94A346253C2D043904E90441040104
+874D:200023DE2252FA52AA52ABD2AA52AA52FA52A3D2221A2A943A50EAB043100010
+874E:100011FC11047DFC550455FC548055FE7E225122115215021DFAE40240140008
+874F:2040202023FEF800A9FCA904A9FCA800FBFEA20221FC28203820E82040A00040
+8750:100011FE11027D7A5502557A550254007CFC508410FC14841EFCE28440FC0084
+8751:100013FE10227D20553C552056FE54007DFC510411FC15041DFCE50441140108
+8752:100013FE10207C4055FC5554555455747D545154117415541D54E55441FC0104
+8753:204020A02110FA08ADF6A800ABC4AA54FA54A3D422542A543BD4EA44425402C8
+8754:1110111211D47D1855525592552E54407DFC5104110415FC1D04E50441FC0104
+8755:10201020282025FC5324FD2445247D2445FC7D2440205028482455FE64824000
+8756:1040102013FE7E02540455FC540055FC7D0451FC110415FC1D04E40043FE0000
+8757:2020204021FCF904A9FCA904A9FCA800FBFEA020202029FC3820E82043FE0000
+8758:100011FE11007D7C5544557C5544557C7D1051FE112415641D18E524414201FE
+8759:1020101011FE7D02550255FE550055007DFE51AA12AA14FE1CAAE4AA40AA0086
+875A:100010FC10487C3055FE5452549455107E30502011FE14701CA8E52442220020
+875B:200C200A2008FBFEAA08ABF8AA4AAA4AFBEAA2AC22AC2A4C3AAAEB0A42160422
+875C:1040104010F87D08561055FC550455FC7D0451FC110415FC1C00E48841040202
+875D:1040107C10847CF8540855FE544054A47D385058109415341C54E49241500020
+875E:100011FC11247D2455FC5500557C55447D44517C1144157C1D44E644427C0444
+875F:100011FE11227DFE552255FE540054FC7C8450FC108414FC1E84E28440940088
+8760:100011FE10007CFC5484548454FC54007DFE5122112215FE1D22E52241FE0102
+8761:100013FE10207C4055FC5554555455547D54512C102015FE1C50E48841040202
+8762:100013FE10207C4055FC5504550455FC7D0451FC110415041DFCE40040880104
+8763:210820882088FBDEA910A920A9DEA942F944A144215E29443A44EA4444D40808
+8764:1088104810507DFE5450545055FC55547D54518C110415FC1D04E50441FC0104
+8765:00207E20247E18A4FF2829104A2898C601001FF0111011101FF001087FFC2004
+8766:200023DE2242FA42AA42ABDEAA00AA3EFBD2A21222142BD43A08EA1442240242
+8767:1088108813FE7C8854A8542055FC55247D24512413FE14201E50E28841040202
+8768:00003FF0021002107FEA0206020208207EFC4AA44AA47EFC08200A24FEFE0202
+8769:1008103C11E07C2057FE542055FC55247DFC512411FC14201DFCE42043FE0000
+876A:100010FC10847CFC548454FC540055FE7C8050FE112A164A1C92E52240540088
+876B:1020102211FA7C24542857FE542054407CFC5184128414FC1E84E28440FC0084
+876C:200020882252FA22AA52AA8AAA02ABFEF888A144227A28883950E82040D80706
+876D:100011FC11047D0455FC5504550455FC7C0053FE102015201D3CE52042A0047E
+876E:1040104010FE7C8055FC568454FC54847CFC5040107C14C41D28E41040680186
+876F:101E13E010447D24548855FC544054407DFE508010FC15441D28E61040680186
+8770:1020102013FE7C505488572655FC54207C2053FE100014201DFCE420402003FE
+8771:02000100FFFE100010001FF8000008207EFC4AA44AA47EFC08200A24FEFE0202
+8772:2082208227F2F882A88AABEAAAAAAAAAFBEAA08A21CA2AAA3CA2E882408A0084
+8773:102011FE10207CFC542055FE540054FC7CA4509411FE14A41D14E5FE40040018
+8774:2100213C2124FBA4A924A93CA924ABA4FAA4A2BC22A42AA43BA4E84440540088
+8775:0620382008A47EA819202C504A88090401001FF0111011101FF001087FFC2004
+8776:204821482148FBFEA948A948A978A900F9FEA02023FE287038A8E92446220020
+8777:1020101011FE7D005544552855FE55107D5451541154157C1D14E52042400080
+8778:100010FC10847C8454F45494549455FE7D02517A114A154A1D7AE502410A0104
+8779:100010F810887C8854F85488548854F87C0051FC115415541D54E55443FE0000
+877A:2004201E23E0F820A9FCA924A924A9FCF820A3FE22222A2A3AFAEA02420A0204
+877B:2020202023FEF820A820ABFEAA8AAA52FAFAA22222222AFA3A22EA22422A0204
+877C:2020212420A8F820ABFEA8A8A924AA02F840A7FE208829083990E86041980604
+877D:1020102013FE7C2055FC544057FE54887D0452FA108814881CF8E488408800F8
+877E:2088208823FEF888A800ABFEAA02AC24F820A3FE207028A838A8E92442220020
+877F:100011FC11247DFC552455FC542055FC7D2451FC112415FC1C20E4224022001E
+8780:088049F82A90286008901FFE2A10C950092001003FF821083FF801087FFC0004
+8781:1000127C11447D44547C54445744557C7D50514A114415541D62E5424280047E
+8782:2100209E23D2FA52AA54ABD4AA58AA54FBD2A21222922A5A3AD4EB5042100010
+8783:2040202023FCF908A890ABFEAA02AC44F820A3FC208028F83888E90841280210
+8784:2100227E2388FA88AABEAAAAABAAAA2AFA2AA3AA22AA2AAE3A88EB8842880008
+8785:2020204021FCF904A9FCA904A9FCA904F9FCA040202028A43A8AEA8A44780000
+8786:208420442048FBFEA884A884A908A94AFA52A39C208429083908EA5243DE0042
+8787:101E13E011227C945440548855F054207CC451FE102214201FFEE45040880306
+8788:100011FE11107D20557C5544557C55447D7C5110111015541F52E29242500420
+8789:209020882104FA42AC88A9FCA804A800FBDEA0422252294A3A52E842414A0084
+878A:1088105010007DFE545055FC545457FE7C5451FC105014D81D54E65240500050
+878B:10A0112C11247D2455AC5524552455FC7C2051FC108814501E20E25040880306
+878C:10783E4822482A86FF7822482A2842104A2885463FF821083FF801087FFC0004
+878D:0020FE2000207CFC44A47CA400A4FEA482FCAAA49220FE28922492FE92428600
+878E:200023FE2000F9FCA904A904A9FCA800FBFEA28A22522BFE3A22EA22422A0204
+878F:2020201021FEF900A920AD20AB3CA950F990A31025FE29103928EA2842440482
+8790:2040208021FCF904A904A9FCA900A9FEF900A1FE20022AAA3AAAEC0240140008
+8791:1020104011FC7D0455FC550455FC55047DFC5028102415FE1C50E48841040202
+8792:102010201050FE8811267C2045FC7D2445247D2411FCFE201028103C13C41104
+8793:2040204027FCF840ABF8A880AFFCA910FA68A5C620402BF838E0E95846440040
+8794:2004201E23F0FA1EAA10AAFEAA92AA98FAF2A28E22802AB83AA8ECAA454A0A86
+8795:1020104011FC7D0455545524555455047DFC5000111215D41D18E5524192010E
+8796:100010FC10847CF4549455FE550254FC7C8450FC108414FC1E84E28440940088
+8797:1020101011FE7D10557C551455FE55147D7C5110117C15441D44E644427C0444
+8798:1020112411247D2455FC540057FE54007DFC5104110415FC1C88E45043FE0000
+8799:010001007FFC038005401930E10E08207EFC4AA44AA47EFC08200A24FEFE0202
+879A:20444258FF6201427E3E42007E4C42727E42423E01003FF821083FF801047FFE
+879B:2040202023FEFA02AC24A9FCA820A9FCF820A3FE202029FC3904E90441FC0104
+879C:08007F7808483E4800867F78414800303ECE01003FF821083FF801087FFC0004
+879D:2020204023FCFA24AA24ABFCAA24AA44FBFCA04020A828B4393CE9224222041E
+879E:200021FE2120F9FCA920A9FCA920A920F9FEA00222AA2AAA3AAAEA0240140008
+879F:200023FE2202F800A9FCA904A9FCA904F9FCA04020202BFE3800E88841040202
+87A0:210420842088F800ABFEA800A888A904FA02A1FC215429543954E95447FE0000
+87A1:020001007FFC082007C01830E00E08207EFC4AA44AA47EFC08200A24FEFE0202
+87A2:08202AA44D28145022887FFE410281041FF0111011101FF0010001087FFC0004
+87A3:00203D2424A8242025FC3C4027FE24A825243EFA24A824A824F8442455FC8804
+87A4:20201020FE2005FC6924112429FCD52411247DFC55247C5010501C88E5044202
+87A5:1020102010507C4854A455FE568454FC7C8450FC108014FC1D44E544427C0044
+87A6:1020102013FE7C2055FC542057FE54407C8851F0102417FE1C22E52442A20040
+87A7:1040104411F87C5057FE544054F855827E7E540011FC15041DFCE50441FC0104
+87A8:1048104811FE7C48540055FE544854487DFE514A114A15B61D22E502410A0104
+87A9:2110211E2122FA54AA08AE94AAE2AA88FA88A2BE22882AAC3A2AEA4A42280210
+87AA:2040202023FEF888A850ABFEAA52AA8AFB06A2FA228A2A8A3AFAEA02420A0204
+87AB:08207F20083EFF4414A85610A5284C4681001FF0111011101FF001087FFC2004
+87AC:2090209027FEF890ABFCAA94ABFCAA94FBFCA00021F8290839F8E90841F80108
+87AD:2040202023FEF800A954A924A954A9FCF820A3FE22422A923AFAEA0A42020206
+87AE:2154215423FEF954A954AA72AC00ABFEFA22A02021FC29243924E924412C0020
+87AF:08207F20087E7E4408A4FF2810101E282244468281003FF821083FF801047FFE
+87B0:2040202023FEFA50AA50ABFEAA52AA52FBFEA20022922AD43A98EC9244D2088E
+87B1:3F0821083F7E20082F4820285FA8440895282C9001003FF821083FF801047FFE
+87B2:2040202023FEFA8AA904ABFEA840A888F9FCA024202029FC3820E82043FE0000
+87B3:2020212420A8FBFEAA02A8F8A888A888F8F8A020202029FC3820E82043FE0000
+87B4:00207BFE482051FC612451FC492449FC687050A841243FFA21083FF801047FFE
+87B5:100013FE10507DFC5554555455FC54007DFC500013FE14201CA8E52442A20040
+87B6:00003FFC20003FF820083FF820003FFC10207EFC52A47EFC10201424FEFE0202
+87B7:00803FFE22002FF828882FF829082FF822203FFC20A02FF848884FF880843FFE
+87B8:14202220493E144222944110BE28222822443E8201003FF821083FF801047FFE
+87B9:20802080208EFBE8A888ABE8AAAEABEAFAAAA3EA208A2BEA388AE892409200A2
+87BA:100011FC11247DFC552455FC544054887DF05020104417FE1C22E52442220060
+87BB:202021FC2124FBFEA924A9FCA820A9FCF924A1FC20402BFE3888E9D04070038C
+87BC:1088108813FE7C8854F8542055FC55247DFC502013FE14201DFCE42043FE0000
+87BD:08001FF0282007C01830E18E0C40030010A07EFC52A47EFC10201424FEFE0202
+87BE:1040102013FE7E02540055FC542055FC7D2451FC112415FC1C00E48841040202
+87BF:0440247C24A83D5004287DFE24884448841801003FF821083FF801087FFC0004
+87C0:2040202023FEF820A848AAF2A924AA52F8F8A00820202BFE3820E82040200020
+87C1:3FF820083FF821003FFC20802C64301C10207EFC52A47EFC10201424FEFE0202
+87C2:104011FC11047DFC550455FC550055FE7D0051FE102215FA1C76E4A843260020
+87C3:200021F82108F9F8A908A9F8A800ABFCFA94A3FC200029F83890E86041980606
+87C4:08207E2008F8FF2814287F6A082AFF56088201003FF821083FF801087FFC0004
+87C5:1040102011FE7D005548554855FE55487D48114815781D00E6D442AA052A0800
+87C6:1088108813FE7C88540055FC550455FC7D0451FC102017FE1C50E48841040202
+87C7:04407FFC04401FF010101FF010101FF00400FFFE11103FF8D1161FF001087FFC
+87C8:200023FE221AFA16ABFEAA12AAEAAAAAFAAAA2EA220E2A6A3B9AEA2643FE0202
+87C9:200023DE2042FA52A94AAA52A828A8C4FB12A0602188283239C4E81840600380
+87CA:1FF0022001407FFC048418886280010010207EFC52A47EFC10201424FEFE0202
+87CB:201C21E02020F924A8A8ABFEA870A8A8F924A222204028243AA2EA8A44880078
+87CC:1020104011FC7D24557C558C555455247D5451FC102014101D54E542414A0238
+87CD:2062238A208AFFEAA88AA9CAAAA2AC8AF8A4A02023FE287038A8E92442220020
+87CE:2088208823FEF888A888A8F8A820ABFEFA22A33222AA2B763A22EA22422A0224
+87CF:2088208823FEF888A820ABFCA824AFFEF824A3FC20202AB43AACEB2C42240424
+87D0:2020212420A8FBFEAA02A8F8A888A888F8F8A02021FC29243924E93441280020
+87D1:102011FC10887C5057FE540055FC55047DFC510411FC14201FFEE42040200020
+87D2:2088208823FEF888A824ABFEA850A888F904A28A20882BFE3888E88841080208
+87D3:208020F82108FBFEAD12A922A9FEA840F8A2A35420982B343854E89243500020
+87D4:200021FC2124F9ACA974A924A9FCA820F9FCA02023FE28003AA4EA5244520000
+87D5:2090229422D8FA92AAD2AF0EA9F0AA10FFFCAA4423FC2A443BFCEC4444540808
+87D6:214021442158FBF0A950A9D0A95EA9D4F954A15423F428143954EA3444140024
+87D7:01007FFC11101FF00100FFFE91121FF041047FFC01003FF821083FF801047FFE
+87D8:10541092119E7EF0548A5486540254FC7C8450FC108414FC1E84E2FC40480084
+87D9:2110209423D2F812AA50A990AFFEA810FBD2A25222542BD43A4AEA4A43D60022
+87DA:08047F0808103E6400083E1022643E0814107F6001003FF821083FF801047FFE
+87DB:2082208227F4F888A880ABE2A802ABE4FA28A22023E02A223942E87447880210
+87DC:101811E010407FFE54885574565254707C0051FC110415741D54E5744104010C
+87DD:2200217E2040FC7CAA44A8FCA940AE7EFA20A02023FE287038A8E92442220020
+87DE:082049202A3E7F4849485DA86B10492841461FF0111011101FF001087FFC2004
+87DF:1020102011FC7C2055545488550456FA7C8850F8108814F81E20E2A841240060
+87E0:203C23E02124F8A8ABFEA8A8A924AA02F9FCA124212429FC3924E92441FC0104
+87E1:200E23F02044FA24A908ABF8AA08ABFCFA04A3FE22022AAA3AAAED0244140808
+87E2:102013FE10207DFC540055FC550455FC7C8853FE100015FC1D04E50441FC0104
+87E3:2124212422AAFBAEA924AAAAABAEA924FBFEA110211429143A8AEA4A42160422
+87E4:200023DE2252FBDEAA10AA52A9CEA800F888A3FE208828883BFEE88841040202
+87E5:1088108811FC7C88548857FE542055FC7D2451FC112415FC1C00E48841040202
+87E6:102011FC10207C8857FE548855FC55047DFC510411FC15041DFCE48841040202
+87E7:208822AA22DCFC88A954AA22A800ABFEFA42A44423FC28443844E88441140208
+87E8:3FFE289025103FDE22222A882F8822942422284027FC244427FC40444FFE8002
+87E9:20002FFE2800FA28A948ABEEA892A884FAA0AAA82BE828883894E91449241242
+87EA:2020202023FEF820A9FCA924A9FCA924F9FCA02223FE28423824EAA2428A0478
+87EB:200023FE2050FBFEAA52ABFEA800A9FCF904A1FC210429FC3820EBFE40200020
+87EC:200023DE2252FA52ABDEA800A9FCA924F9FCA12421FC28203BFEE82040200020
+87ED:1090108811FE7D10571055FE551055107DFE111015101DFEE50042A402520452
+87EE:1088105013FE7C2055FC542057FE55247CA853FE100015FC1D04E50441FC0104
+87EF:2020202021FCF820ABFEA908AB9CA908F988A63E20002BFE3890E8904112020E
+87F0:202021FC2024FBFEA824A9FCA820AAAAFBAEA22223FE2A223BAEEAAA42AA0422
+87F1:2080208021FEFB54AD54A954ABFEA954F954A15427FE28003954E92A422A0000
+87F2:010001003FF821083FF801087FFC000410207EFC52A47EFC10201424FEFE0202
+87F3:100011FC10047CFC540455FC540055DC7C9453DC100817FE1D08E48840A80010
+87F4:240CFF7024403C40247E3C482448FF482448428801003FF821083FF801047FFE
+87F5:200023FE2200FA04ABF4AA04AAEEAAA4FAA4A2EC22042AA43A44EA7445940008
+87F6:200027E0225EFBD2AA52ABD2AA72AFDEF840A3FE202029FC3820E82043FE0000
+87F7:2020212420A8FBFEAA02A8F8A888A888F8F8A00021FC292439FCE92441FC0104
+87F8:7FFC06003B0804B019C062A00C98728611207EFC52A47EFC10201424FEFE0202
+87F9:20003EFC4424BE542A983E502AFC3E102AFE2A1045103FF821083FF801047FFE
+87FA:101011FE10007DFE5502557A554A55FE7C0050FC108414FC1E84E2FC400001FE
+87FB:2104208823FEF820A9FCA820ABFEA854F992A09023FE289038D4EB8A409601A2
+87FC:2420FF20247E7EC482287A104A287AC605001FF0111011101FF001087FFC2004
+87FD:10101210117C7C1054FE5444572855FE7D10517C111015FE1D10E51042FE0400
+87FE:108010F811087FFE5544559255FE55007D7C5100117C15001D7CE544417C0244
+87FF:0878FFC808483E862B783E482A28FF9049287F4601003FF821083FF801047FFE
+8800:1220113E10427C9457105528544655FC7D0451FC110415FC1D04E5FC40880104
+8801:11002BDE4A5273D42A524BD27A1A12942350C24001003FF821083FF801047FFE
+8802:108813FE10887C00554857FE554855787D0051FC102017FE1C70E4A843260020
+8803:0100FFFE20003FF800003FF820083FF80000711C57D4755457DC715657D6B062
+8804:202020502088F924AEFAA850A924A954F9FCA02023FE2A423A92EAFA420A0206
+8805:100011FC11547D5455DC545055DC55547D5451DC115415541DDCE5504052003E
+8806:0820FFFE08201FF011101FF011107FFC41245FEC01003FF821083FF801047FFE
+8807:2088208823FEF888A9FCA924A9FCA924F9FCA02023FE2A223A2AEAFA420A0206
+8808:00107C1445FE7C9044947DD4448A7C8A291645223FF821083FF801087FFC0004
+8809:100011FC11547D5455FC540057FE54007DFC510411FC14621C94E58842A400C2
+880A:202023FE2288FA50ABFEAA50AAFCAA54FBFEA25422FC2A503AD8ED5446520850
+880B:100011FC11547D5455FC548055FC56447DF45154115415F41C44E5F440140008
+880C:100011FC11547DFC542055FC542057FE7C88505011FC14201FFEE42040200020
+880D:200823C82248FBCEAA4AABD2A904ABE4FCA4A2A423642A2A3BEAE82A414A0090
+880E:108813FE10887C2057FE5450548857267CF85020108815FE1C88E48841080208
+880F:210021DE224AFC8AABEAAAB6AAA4ABF4FABEA2A423E42ABE3AA4EAA442240464
+8810:2040202023FEF888A852AFACAAAAAAA8FDACA000210429FC3904E9FC41040204
+8811:208822AA22DCFC88A954AA22A800ABFEFA22A02023FE287038A8E92446220020
+8812:7FFC21087FFCB55A29283558210835582928355801003FF821083FF801047FFE
+8813:208823FE2088FBFEAA02A9FCA800ABFEF840A0A2235428B83B54E89243500020
+8814:202023FE2000F9FCA904A9FCA800ABFEFA02A1FC20402BA438D8EB3440D20330
+8815:200021FC2020FBFEAA22A9ACA820A9ACF800A3FE202029FC3954E9544154010C
+8816:108813FE10A87C9055FE572055FC55207DFC512011FE15001FFCE4884070038E
+8817:200023DE2042FA52A94AAA52A890A908FBFEA51021FE291039FEE91041FE0100
+8818:2110211423F2F910AFFEAA90AA50AFF4FA94A3F422942BE83A8AEBFA42260042
+8819:2040202023FEFA02A9FCA948AA50A9FCFB04A1FC210429FC3904E9FC40880104
+881A:08207FFC08200200FFFE08001FF02810C8100FF010207CF854A87CF81224FEFC
+881B:104811FE10487C0055FE554A554A55FE7C1451FE111015921D4CE54A41160222
+881C:22882108FABE2008729CA92A2288FFFE08203018C1063FF821083FF801047FFE
+881D:200021FC2124F9FCA924A9FCA904A800FBFEA2AA22AA2BFE3AAAEAAA43FE0222
+881E:20403F7E4890BF7C21443F4421443F5424483A4001003FF821083FF801047FFE
+881F:212422482124F800ABFCAA94AA64AA94FBFCA24823682A483B6AEA4A42460362
+8820:00007FFC02003FF8244827C8244827C824483FF810207CF854A87CF81224FEFC
+8821:0FE010201FC00040FFFE0C1073200DC072B00C8EF3207CF854A87CF81224FEFC
+8822:01007FFC01003FF80200FFFE08203FF8C8260FE010207CF854A87CF81224FEFC
+8823:100011FE11287DFE5528557C5554557C7D54117C15101DFEE59242BA028A0484
+8824:08200440FFFE04403FF82848303827C820083FF810207CF854A87CF81224FEFC
+8825:52107EFE28447E28A2FE3E1020103E7C22103E1001003FF821083FF801047FFE
+8826:2040207C2040FBFCAA44ABF0AA44AAFCFAA8A2F822A82AF83A00EDFC45540BFE
+8827:01007FFC01001FF000007FFE48029FF42810CFF010207CF854A87CF81224FEFC
+8828:208823FE20A8F9FCA824ABFEA824A9FCFAAAA3AE22222BFE3A22EBAE42AA04AA
+8829:22102110203AFB92A814ABBEA808AB90F83CA3E422A42ABC3AA4EBA442BC0024
+882A:08407F7C1440FF7C22043E7C22403E7C2242263E01003FF821083FF801047FFE
+882B:0704782425241E2464241A24652419046514020810207CF854A87CF81224FEFC
+882C:2110209023DEF810AA5EA982ABDEA810FBDEA25023DE2A503BDEEA50425202CE
+882D:210013F0151000E0775C11F0104013FC284047FE10207CF854A87CF81224FEFC
+882E:23EE228A22EAFB50ABEEAA4AAAA4ABEAF800A3DE20422A52394AEA52414A0084
+882F:00807FFE42004FF848884FF849084FF842807FFC44905F7C55545F7C4492BFFE
+8830:102013FE10007DDC555455DC548857FE7C8853FE108817FE1C94E58842A400C2
+8831:01001FF011101FF001087FFC10207CF854A87CF81224FEFC00003FF82448FFFE
+8832:440024FE28AA00AAFEFE004028FE452282FA00AAFEAAAAFAAA22AAFAAF0AF804
+8833:23DE225223DEFA52ABDEAA52ABDEA98CFA52A04027FE28883990E86040D80304
+8834:108813FE10887DFC555455FC542255FC7C2853FE104015FC1E84E4FC408400FC
+8835:222223FE2090F9FEAB10ADFEA910A9FEF910A1FE21002BFE3A8AEB7642520276
+8836:3E7C48907EFC142A66C63FF820083FF820083FF810207CF854A87CF81224FEFC
+8837:23DE225223DEFA52ABDEAA52ABDEA890F9FEA11023FE2D1039FEE91041FE0100
+8838:208823FE2088FBDEAA52ABDEA8A0A890F9FEA12023FC2D2039FCE92041FE0100
+8839:01007FFC11101FF00100FFFE88021FF068100FF010207CF854A87CF81224FEFC
+883A:7CF81020FDFC28504488BFF620103FF020103FF010207CF854A87CF81224FEFC
+883B:210447C88812F3BC20084B92F83E0380AAAAABAA01003FF821083FF801047FFE
+883C:23DE225223DEFA52ABDEA8A0A9FEAB20FDFCA12021FE280039FCE8884070078E
+883D:08282A244D2E087014243F246428BF12242A3F4610207CF854A87CF81224FEFC
+883E:23FE220223FEFA92AA54AA92AAFEAAAAFAFEA32222FA2AAA3AFAEA2245FA0004
+883F:249079E414547DFC0004FFFC249479E41454FFFC10207CF854A87CF81224FEFC
+8840:0100010002003FF82448244824482448244824482448244824482448FFFE0000
+8841:02000100FFFE1000100010001FF8010002003FF82448244824482448FFFE0000
+8842:08000800107E7F125512555255525552555255925512552257A2FC4200940108
+8843:0800080010FE7F10551055205530555855545592551255105790FC1000100010
+8844:080008FC10247F2455245524552455FC554455445544554457C4FC4401FE0000
+8845:0810081010947F545558551055FC55105510551055FE55105790FC1000100010
+8846:040008003FF824482448FFFE000000F87F0009041188635005201918E1060100
+8847:0804080E10707F405546555855545554555655545554555457D2FC9200980110
+8848:0800087E10247F24553C55245524553C552455245526557C5784FC0400040004
+8849:08200820103C7F4455A85510552855445582557C5544554457C4FC44007C0044
+884A:102410FE2024FE00AAFEAAAAAAAAAAFEAA14AAFEAA90AAD2AFACF8AA00960122
+884B:01003FF80108FFFE01083FF801007D7C11107D7C44447C7C45447FFC2448FFFE
+884C:080009FC100020004800080013FE302050209020102010201020102010A01040
+884D:10001200211C410080001400223E6288A0882108270821082108210821282010
+884E:1000100027DC410081001100213E6108AFE82108210821082108210821282110
+884F:100010002F9C400080001FC0253E6508A5082508254829882908300820282010
+8850:1000100027DC44008400178024BE6488A48827882408240827C8200820282010
+8851:11001100229C42408420190020BE6008AFC82048208825082208210821282010
+8852:12001100201C4FC08200140024BE6888AF0821082208220824882F8820A82010
+8853:11001180215C4140810017C0213E6308A3882348254825082908210821282110
+8854:12001200239C4200840017802A3E6208AF882208220822082288230822282010
+8855:20002FE0482E48208BA01820283E6BA4AAA42AA42AA42BA42824282428B42848
+8856:14801480249C44809FE0148024BE6488A4882FE8200824882448284830082018
+8857:1100110027DC4100810017C0203E6108A10827C82108210821C82E0824282010
+8858:1400140027EE4900910011002FDE6104A10425C42504250425C43E0428142008
+8859:10001FC0221C42008F80148024BE6FC8A0082008278824882488248827A82490
+885A:140014E024AE4EA084A014E024BE6EA4AAA42AE42AA42AA42EA4212421342268
+885B:120012002FCE44409FE010002FDE6844AFC421042FC4210429042FE421142108
+885C:144012802FEE4100820017C0245E6444A7C42444244427C42444244427D42448
+885D:108011C0271C410087C0110027FE6548A7C8254827C8210827C821082FE82010
+885E:110017C0224E4FE0800017C0245E67C4A0042FE421042FE42924292429742108
+885F:154015402A8E4540854010002FDE6104A7C4244427C4244427C4244427D42448
+8860:110011002FEE410087C0144027DE6444A7C4244427C424442FE4228424542828
+8861:120013C0244E488087C01540255E67C4A544254427C421042FE4210422942448
+8862:2EE02AA04EEE4AA08EE01AA02EFE6444AFF4348427E4248427E4248427F42408
+8863:020001000100FFFE0200020005000508089018A02840482088100A080C060800
+8864:200010000000FC00080010001000340058009400140010001000100010001000
+8865:1040084000407E400240046008501A482C444A440A4008400840084008400840
+8866:200011FC0020F8200820102014203BFE54209020102010201020102010201020
+8867:200011FC0020F8200820102014203BFE54209020102010201020102010A01040
+8868:010001007FFC010001003FF801000100FFFE0500088818502820C9180A060C00
+8869:200013FC0104F944092410A81088348858509450142010201050108811041602
+886A:202010200020F920092C1134116437A459249534152811221122110210FE1000
+886B:1004080400087E100220044408041A082C104A220A42080408080810082008C0
+886C:201010100010FC1009FE10101010341059109490149010101010101010501020
+886D:202010200020FC2009FC1020102034205BFE9420145010501088108811041202
+886E:02000100FFFE000008201210244848241FF0029004440C283410C50806060400
+886F:201010900090FC8809081104120435FA58889488148810881108110812281410
+8870:02000100FFFE00001FF01010FFFE10101FF0028004440C283410C50806060400
+8871:200013FC0084F88808881090109C348459449544152811281210122814441182
+8872:202010200020FDFE09221122112235225952954A158A110211021102110A1104
+8873:201010900090F8880888112415243A225440904010881084110413FE11021000
+8874:202010200020FDFE09221224102034205850945014501050109010921112120E
+8875:2000100001FCFD04090411041104350459FC9504150411041104110411FC1104
+8876:202010200020FC2009FC112411243524592495FC152410201020102010201020
+8877:02000100FFFE01003FF8210821083FF80100028004440C283410C50806060400
+8878:2040104000A0F8A0091012081406311055109910151011101110121012101410
+8879:2004101E01F0FD1009101110111035FE5910951015101108110A114A11861102
+887A:02000100FFFE00007FFC20403FFE02400D407080030804900C603518C6060400
+887B:200010FC0084FC84088411FE10843484588495FE148410841084108410941088
+887C:202010200020FBFE08201020102035FC58849488144810501020105011881606
+887D:2008103C01E0FC2008201020102035FE58209420142010201020102011FC1000
+887E:01000280044009203098CFE6004002800100FFFE05000C883450C530060E0400
+887F:202010200050FC500888114412223420580095FC140410081008101010101020
+8880:204010400080FCFC090412041084344458449414142410441184100410281010
+8881:010001003FF80100FFFE00001FF0101010101FF0050408883850CA200C180806
+8882:202010200020F9FC082410241424382455FE9020105010501088108811041202
+8883:200021FC2C44F04420842484291432080100FFFE05000C883450C530060E0400
+8884:2008103C01E0FC200820102011FE342058209450145010501088108811041202
+8885:04001FE0142012A010401FFC000402140108FFFE05000C883450C530060E0400
+8886:202010200020FDFE0820102010FC3420582095FE14221022102A102410201020
+8887:200010FC0084FC8408A410941094348459FE9484148410841084110411141208
+8888:080008007F7C094411441144257C42000100FFFE05000C883450C530060E0400
+8889:202010100010F9FE0902120410803488589094A014C0108210821082107E1000
+888A:202010200050F850088811241212301055FC9804140810881050102010101010
+888B:08A0109030BE57C0904010241014120C0100FFFE05000C883450C530060E0400
+888C:0100FFFE08001FF020105F9010D01FA010040FFC030004880C503530C60E0400
+888D:2080108001FCF9040A0415F411143514591495F4150411281112110210FE1000
+888E:202011200120F22012FC24A427246924B2242A2424A427A420C4204420942108
+888F:204010400040FC400BFE10401080348058FE9510151012101210141011FE1000
+8890:200010400020F8280808108814903A9456A292A214C210881188128814781000
+8891:200013FC0084F8840884110415143A08540091FC110411041104110411FC1104
+8892:2000100001FCFD040904110411FC35045904950415FC11041000100013FE1000
+8893:200011F80108FD08090811F811083508590895F8150811081108110817FE1000
+8894:2000100003FEF808080811E8112835285928952815E811281008100810281010
+8895:204010200020FBFE0A0214041000349058909490148811081108110412041402
+8896:202010200020FC2009FC112411243524592495FC152411241124112411FC1104
+8897:202010200050FC88090412121020344059889410142010441188101010601380
+8898:2080108000FEFD000A201120112C35745BA49524153411281122110210FE1000
+8899:202010200040FDFC090411041104350459FC9504150411041104110411FC1104
+889A:205010480048FC400BFE1080108034FC59449544152811281210122814441182
+889B:2004101E01F0FD1009101110111035FE5910951015101108110A114A11A61112
+889C:202010200020FDFE08201020102035FC587094A814A811241124122210201020
+889D:208810880088F908097E13081508314855289928150811081108110811281110
+889E:02000100FFFE0820101020085FF4101010101FF004440C283410C50806060400
+889F:202010200120F92009FC11201220302055FE9820145010501088108811041202
+88A0:02000100FFFE11001FF822007FFC048008603298C4440C283410C50806060400
+88A1:202010200020F9FC0924112415FC39245524912413FE11041104110411141108
+88A2:202010200124F8A408A8102015FC38205420902013FE10201020102010201020
+88A3:204811480148F948094813FE1148354859489548157811001100110011FE1000
+88A4:0100FFFE00001FF0022001407FFC048418886280030004880C503530C60E0400
+88A5:2000100003FEF82008201040144038FC55849284148410841084108410FC1084
+88A6:202010200124FD240924112411FC342058209524152411241124112411FC1004
+88A7:208010800100F9FC0A04140411E435245924952415E411241004100410281010
+88A8:204010200020FBFE08401040108835085BF0942014401088110413FC11041000
+88A9:202010200020FC20083E10201020342059FC9504150411041104110411FC1104
+88AA:202010200020F9FC0820102014203BFE5420904010401088110413FE11021000
+88AB:201010100010F9FE09121114151039FC55449144112811281110122812441482
+88AC:02000100FFFE080010103FF800081FF0101010101FF0048808503820CB180C06
+88AD:04400420FFFE0910116021844F0482FC0100FFFE05000C883450C530060E0400
+88AE:208010800080F9FE090012001420302055289924162412221422102010A01040
+88AF:204010480244FA400BFE1080148038FC55449144114812501220145018881306
+88B0:1FF012101110FFFE121021103FFC001002A00140FFFE04880C503420C5180606
+88B1:209010940092F9120910137E1510311055109928152811281128114411441182
+88B2:0100FFFE02000FE034C00700388003F81D3001C03F0004880C503530C60E0400
+88B3:20201020007CFC8409481030102034485990943E144211A41018101010601180
+88B4:2020102003FEFC500888110412FA34005BFE9440148011FC1004100410281010
+88B5:20801088009CF970091013101510311055FE99101510111011101110117C1100
+88B6:2080108000FCF9080A90106011983626582095FC1420122013FE102010201020
+88B7:202010200050F8880904120211FC3400580095FC150411041104110411FC1104
+88B8:204010400040FBFE08801080117835085B10951015FE11101110111011501120
+88B9:200013FE0020FC20084011FC11043504590495FC150411041104110411FC1104
+88BA:202010200020FBFE0820102011FC3400580095FC150411041104110411FC1104
+88BB:200013FE0020FC20084011FC1154355459549554155411541154114411141108
+88BC:2080108000F8F9080B1014A0104034A05918960615F811081108110811F81108
+88BD:410021002100011EF7D2125222526A52B2522C92229221122292225E24522800
+88BE:202011200120F9FC09201220102033FE547098A814A811241124122210201020
+88BF:2020102001FCF8200820102013FE30005420982015FC10201020102013FE1000
+88C0:200011FE0102F9220922112211FE352259229552154A118A1102110211FE1102
+88C1:084008487F4408440840FFFE10400844FF4410442928662AA212292A30462082
+88C2:00047F8408241F24212452240C243004C20C0100FFFE04880C503420C5180606
+88C3:20401040007CFC40084013FE100034005BFE9440145010481044104010401040
+88C4:20401040009CF9000A40104010BE35885A889488148810881088108810A81090
+88C5:082048202BFE082018202820C9FC0A000100FFFE05000C883450C530060E0400
+88C6:2020112400A4FCA408A8102013FC34045804940415FC10041004100413FC1004
+88C7:202010200040F88009FC11541154355459549554155411541154115413FE1000
+88C8:200013FE0202FC44084013FC108034A0592095FC1420102013FE102010201020
+88C9:200011F80108F90809F81108110835F859449548153011201110114811861100
+88CA:04001FF010101FF010101FF010001FFC10001FFC01043FEC04801C486530060E
+88CB:200013FC0000FC0009F811081108350859F89400150810881090100017FE1000
+88CC:202010200020FBFE0820102011243524592496AA142010501050108811041202
+88CD:200013FE0222FA220A2213FE16223A62567292AA132212221222120213FE1202
+88CE:200011FC0104F904090411FC1000340059FE9420142011FC1020102013FE1000
+88CF:0100FFFE00001FF011101FF011101FF001001FF001007FFC04880C503530C60E
+88D0:200010FC0084FC8408FC100011FE3502590295FE1502110211FE1102110A1104
+88D1:2040108001F8F90809F8110815FA390A550C93F8101810281048118816281010
+88D2:02000100FFFE0400387820083C7820083FF8028004440C283410C50806060400
+88D3:201010140012F8100BFE10101550395457F4915411541148124A125A14261042
+88D4:02000100FFFE048808503A20CC1808063FF82448282837D8244827C820282010
+88D5:200010500048FC840924102010503488590694F8148810881088108810F81088
+88D6:200011FE0100FD00097C1100110035FE59509552155411481148124412521460
+88D7:2040102003FCF8400890110813FC30045550995015501150125012521452180E
+88D8:012001107FFC111009A00540193062080100FFFE05000C883450C530060E0400
+88D9:200011FC0044F8440BFE1044104435FC5880948015FC12841484108410FC1084
+88DA:080C08F07E8008800EFE78880888290812080100FFFE04880C503420C5180606
+88DB:0100FFFE00001FF010101FF000003FF821083FF820021FFE04881850EB300C0E
+88DC:2028102403FEF820082011FC1124352459FC9524152411FC112411241124110C
+88DD:242024203C2005FCFC20242024F846000100FFFE05000C883450C530060E0400
+88DE:210410840088FC1009FC11041104350459FC94501450109010921112120E1400
+88DF:1020082040A824A409227228103010C007000100FFFE04880C503420C5180606
+88E0:3FF80208FFFE04083FF808001FF82808CFF80100FFFE04880C503420C5180606
+88E1:200011FC0124FD2409FC1124112435FC5820942015FC10201020102013FE1000
+88E2:201012100110F97E082010281748357E5908950815FE110811081288147E1000
+88E3:202010200050F8880904120211FC340058449424112410A81088101013FE1000
+88E4:2010100801FEFD10091011FE112035285948957E1508110811FE120812081408
+88E5:210010BE0282F202120222FA228A6A8AB2FA2A8A228A22FA22022202220A2204
+88E6:0100FFFE000019F8609040607BFC40A441287A60030004880C503530C60E0400
+88E7:202010A200A2F9240850108813043022542098A414A411281050108811041202
+88E8:2040108003FCFA240A2413FC16243A4457FC9090111017FE1010101010101010
+88E9:200011FC0104FD0409FC1104110435FC5800951215D41118111011521192110E
+88EA:2080108000FEFD020A8210F2114234425BFA94421552115211F2100210141008
+88EB:205012520252F25213DE220222026BFEB2022A0223DE22522252225224522802
+88EC:2020102001FCFC20082013FE108835445A4294F8158812501020105011881606
+88ED:20201020003EFC2009FE1122113835E05922951E150011781248124A148A1906
+88EE:20FC10840084FCFC0884108410FC340059FE9502150211FE1102110211FE1102
+88EF:200011FC0124FD240974112411FC350459749554155411741104120412141408
+88F0:200017BC0084F2941108229424A46840B0002FBC20A422A42128229024A82846
+88F1:2020102003FEF820082011FC102034205BFE944014A411A81290148810C61080
+88F2:200013FE0020F02013FE222222226B32B2AA2AAA2376226622222222222A2204
+88F3:0100111009207FFE40029FF410101FF00100FFFE05000C883450C530060E0400
+88F4:044004407C7C04403C7804407C7C06400100FFFE05000C883450C530060E0400
+88F5:02000100FFFE04407C7C04403C7804407C7C0440030804900C603518C6060400
+88F6:209010900090F79E1090209020906B9CB09028902090279E2090209020902090
+88F7:2020112400A8F82009FC104017FE3888550492FA1488108810A810921082107E
+88F8:200011FC0124F92409FC1124152439FC542093FE107010A81124122210201020
+88F9:0100FFFE00001FF011101FF011101FF00100FFFE131065880C503530C60E0400
+88FA:2020102003FEF85008881124122231FC552499FC152411FC10221022101E1000
+88FB:08000E7C08047F4408282A1049281A440100FFFE05000C883450C530060E0400
+88FC:200011F80108F90809F81108150839F8548091FC125414941124124410941108
+88FD:24043FA44424FFA404243F842494258802000100FFFE04880C503420C5180606
+88FE:200013FC0204F20413FC222022206BFEB2202A2022FC22842284248424FC2884
+88FF:2020102001FCFC500888110413FE340859E89528152811E81128100810281010
+8900:2088108803FEFC88088810F81088348858F89488148813FE1000108811041202
+8901:00001FF011101FF011101FF00100FFFE09201110630804900C603518C6060400
+8902:2110111007D0F110111021182FF46812B112291027D02110211021D02E102410
+8903:20201120013CFD20092013FE100035FC590495FC150411FC1104110411141108
+8904:2020102003FEF82009FC102413FE342459FC944017FE108411C8103010CC1302
+8905:2040102001FCF8000888105013FE3222542499FC152411241134112810201020
+8906:200011FC0104FD0409FC1104110435FC580097FE14201120113C112012A0147E
+8907:2100110001FEFA000DFC110411FC350459FC948014FC11081290106011981606
+8908:2008103C01E0F8200BFE102011FC352459FC952415FC102011FC102013FE1000
+8909:2100113C07D4F1141394211427D46924B14C284027FE204020A0211022082C06
+890A:2080104003FCF204120423FC22006A00B3FC2B54235425FC255425542944210C
+890B:204811480148FBFE094811481578390055FE902013FE107010A8112416221020
+890C:200013FE0222F8200BFE102011FC352459FC952415FC102013FE102010201020
+890D:202011240124FD2409FC100013FE3420584095FC15541154115411541154110C
+890E:02000100FFFE00180CE0302021FC3CA821243C20030804900C603518C6060400
+890F:0100FFFE00200C2031FC21243DFC212421243DFC030004880C503530C60E0400
+8910:200013F80208F3F8120823F821006BFCB4442A4422A4220423F4200420282010
+8911:201E13E00044FD24088811FC104034405BFE948014FC11441128121010681186
+8912:0100FFFE08000BF8120833F8504097FE11501248030004880C503530C60E0400
+8913:2100117C0144F2441244267C2A106A10B2FE2A38225422542294231222102210
+8914:200013FE0000F9FC0904110415FC380057FE9222122213FE1222122213FE1202
+8915:204010A00110F20815F6200023C46A54B2542BD42254225423D42244225422C8
+8916:208010FC0104FDF8080813FE104034A25B349458149413341052109013501020
+8917:200013FE0200FAFC0A8412FC16843AFC562093FE124812C812301248128413FE
+8918:2040104001FCF8840BFE100015FC390455FC902013FE1020122013FE10201020
+8919:2050105203DCF85008D2134E100035FC590495FC150411FC1104110411141108
+891A:2020102201FAF824082813FE1420384054FC9184128410FC1084108410FC1084
+891B:2020112400A8F02013FE20A821246A02B0402BFE208821082190206021982604
+891C:008079F84A087DE8492879E8491449049AFC0100FFFE04880C503420C5180606
+891D:224211240000FDFC0924112411FC3524592495FC1420102013FE102010201020
+891E:200011F80108F90809F81108150839F8540093FC129412941294129417FE1000
+891F:200011FC0104F9FC090411FC14003BDE54429252114A10C6135A1042114A1084
+8920:2088108803FEFC8809FC108813FE342059FC952415FC112413FE110411141108
+8921:2088108803FEF888082010501488390456FA9000100011FC1104110411FC1104
+8922:0100FFFE02001FF011101FF012101FF004A808BA3382C4FE0C503530C60E0400
+8923:2040102003FEFA0208501088152438505488910412FA10881088108810F81088
+8924:2020102001FCF8200BFE100011FC3504590495FC14521094118816A410C21080
+8925:200013FE0200F2FC120023FE22A86A90B2C82A86220823FE2288244824082818
+8926:211012120454F7D81010201227D26C4EB4402FD22454245827D024522552248E
+8927:7E1024523C5424903C282744FC8206000100FFFE05000C883450C530060E0400
+8928:210810880090FBFC084011F814403BFE5480910011FC12201420182013FE1000
+8929:10003E7822482A48FE8623782A4842304A4886840100FFFE06801C48E530060E
+892A:2000127C0144F944087C10441744357C5950954A15441154116211421280147E
+892B:2004101E03F0F21E121022FE22926A98B2F22A8E228022B822A824AA254A2A86
+892C:21F810880070F18C100023DE2252698CB252282023FE207020A8212426222020
+892D:0100FFFE00003FFC21003FF821003FFE29224496030004880C503530C60E0400
+892E:08202AA44D28145022887FFE400282040100FFFE05000C883450C530060E0400
+892F:2040102007FEF488148827FE24886CF8B4202DFC252425242934292830202020
+8930:01007FFE44429FF404403FF80440FFFE0A2011102FE8C28E04501C2065180606
+8931:02000100FFFE00003FF824483FF8111009201110230804900C603518C6060400
+8932:2020101001FEFD10097C1110117C3554597C9554157C111011FE121012101410
+8933:2010101002FEF910097C1054147C3B54557C911011FE111011101290147E1000
+8934:20481148014EF9500968114411443440580095FC155411541154115417FE1000
+8935:2040102003FEF80009541124155439FC542093FE1242129212FA120A12021206
+8936:200013DE0042FA52094A12521042342059FC9504150411FC1104110411FC1104
+8937:221012100450F95C1150225026FE6A00B2102A50225C225022B02290230E2200
+8938:202011FC0124FBFE092411FC142039FC552491FC104013FE108811D01070138C
+8939:2110111007D0F110113C27D420146AB4B554291C27D42114211421E427262242
+893A:08207E2008F8FF2814287F6A082AFF560A820100FFFE04880C503420C5180606
+893B:0100FFFE08203E2008F87F282A685D2A08563E82030004880C503530C60E0400
+893C:400023FE205003FEF25213FE20206FFEB088290423FA250821F82102210220FE
+893D:3F0821083F7E20082F4820285FA8440895282E900100FFFE06801C48E530060E
+893E:200013FE0050FDFC0954115411FC340059FC940017FE102010A8112412A21040
+893F:2090109007FEF8900BFC129413FC36945BFC940015F8110811F8110811F81108
+8940:202013FE0020FDFC082013FE100035FC590495FC150411FC110411FC10881104
+8941:200013BE00A2F0A210BE238822086A3EB22A2BAA20AA20BE2088208A257E2202
+8942:2040108801FCF9080A5213FE14503988562690C0131010641388103010C01700
+8943:0100FFFE00000CF8308820F83C2021FC20A83D24030004880C503530C60E0400
+8944:0100FFFE00003EF822883EF804407FFC04403FF80440FFFE04441C28E5180606
+8945:200011FC0124FDFC092411FC10A834A85BFE94A814A811FC102013FE10201020
+8946:205012520154F8500BFE108814503BFE542091FC102013FE1050108811041602
+8947:200013DE0252FBDE0A5213DE16023AFA568A92FA128A12FA128A1202120A1204
+8948:200013DE0252FBDE0A10125211CE3400588897FE1488108817FE108811041202
+8949:279E1492079EF492179E240224F26C92B4F22C9224F224922492253224022406
+894A:200013F80208F3F8120823F820006FFEB4802FBC2494279424D42F88209420A2
+894B:420822080FBEE20822082FBE4AAA5AAAEAAA5BAE4208471C4AAA524842084208
+894C:200013DE0252FA520BDE100011FC352459FC952415FC102013FE102010201020
+894D:20A0109001FEFB2009FC112011FC352059FE9500142013FE107010A813261020
+894E:203C13E00124F8A80BFE10A81124360259FC9524152411FC1124112411FC1104
+894F:202413A80092F5141208240423BA68A8B0C62B80223C238420A8209022A82144
+8950:208010F80108FBFE0D12112215FE384054A29354109813341054109213501020
+8951:200011FC0004FCFC080411FC100035DC589497DC140813FE1108108810A81010
+8952:210811080548F390111E27D425646D54B5542F5425D4254825482554246424C2
+8953:2020102001FCF8200BFE1108139C35085988963E140013FE109010901112120E
+8954:2088108803FEF888088810F814203BFE5622933212AA137612221222122A1224
+8955:210010BE0282F22212FA222222FA6AAAB2BA2AEA22AA22FA227222AA22222226
+8956:2080110007FCF4441554244427FC6CE4B5542C0420402FFE20A0211022082C06
+8957:200011FC0154F9FC082011FC14203BFE5488905011FC102013FE102010201020
+8958:202010500088FD740A0211FC112435AC592495FC140010F8108810F8108810F8
+8959:20F810880088FCF8080011DC1154355459DC942015FE107010A8112412221020
+895A:204412240128FC7E08101028134A351C5928954C151A112A1148111012FE1400
+895B:209013FC0294FBFC0A9413FC14003BFC560092F8120013FE1520151415481986
+895C:208010F80108FBFE0944119211FE3500597C9500157C1100117C1244127C1444
+895D:202010200050FC88090412FA1000340059DC9554155411DC1088108811541222
+895E:00407C2045FC44887C5043FE7C20A5FC24203E200100FFFE06801C48E530060E
+895F:2110111007BCF11013B8255429126800B3F8280027FC20402248244429422080
+8960:2020112400A8FBFE0A0210F81088348858F8940015FC112411FC112411FC1104
+8961:200013F802A8F2A813F8210023FC6C84B3E42AA422A423E4209427F420142008
+8962:202013FE0000FBFC0A0412F4129437FC580095F8150811F8110811F8100013FE
+8963:204010F80088FCF8088810F8100035FC592495FC152411FC100013FE10881108
+8964:200813E80288FBEE0A2813F416823BE2540091FC115411541154115417FE1000
+8965:212811AA016CF22812FE264426286AFEB2102A7C221022FE2210222822442282
+8966:200011FC0020FBFE0A2211AC142039AC540093FE102011FC115411541154110C
+8967:200017FC0248F4441FFE244426EC6D54B6EC2C4426EC255426EC244424542408
+8968:214411440554F364115E27E420046A34B14C2BE4208423E4208420E427142008
+8969:202013FE0020FDFC080013FE125237FE590495FC150411FC110411FC10881104
+896A:210817FE0108F00013FC229422946BFCB0282BFE2220232422A82292242A28C6
+896B:2020102007FEF02013AE212423AE6AAAB3AE2AAA23AE20502050208821042602
+896C:200013FC0294F29413FC211022526BDCB0122BCE224023D2225C23D0225222CE
+896D:2100113E0108F7D0113E212223A2683EB0222BBE22A222A222BE238022942022
+896E:21FC110401FCFD0409FC108811FC34885BFE9488152412AA107010A811241060
+896F:4200213C27A40024F4BC132427A4693CB1242FA4213C259025582968252A2246
+8970:2108110807CEF112112427DE25526D5EB7D2291E2392255E2940211421122122
+8971:2210111007DEF010145E228227DE6810B7DE2C5027DE245027DE2450245224CE
+8972:08407F7C1440FF7C22043E7C22403E7C2242263E0100FFFE06801C48E530060E
+8973:4148214C22AA0008F7FE11482368694AB36A294C236C2148216A239A20262042
+8974:27BC14A407BCF4A417BC244425F46C44B5F42D5425F4255425F424E42554244C
+8975:23FC110801F8F10811F8210E27F86808B7FE2A94239C2294239C22D627BC2084
+8976:411427D221100FFEF01017D025526FD2B5522FD4229427C8228A2FFA22A62442
+8977:2140126C0244F36C12A423AC22A46FFEB1082AF4244223F8204027FC204020C0
+8978:252817BE0948F7BE131825AA29466BFCB2042BFC220423FC220423FC21082204
+8979:27BE100007BCF4A416B424A420406FFEB4A02FFC24A427FC251229DC291231CE
+897A:211017FE0110F00017FE254A254A6EFEB7EA2D6A267E27CA244E257225422406
+897B:22A8124807BEF2A8175C2AAA22886FFEB2182DE4284223F8204027FC204020C0
+897C:210817FE0108F390113C27D422B46D5CB396292223FC200027FE2080210423FE
+897D:211017FE0110F7BC14A427BC24A46FBCB4442FFC255425F4244424E425542448
+897E:0000FFFE0440044004407FFC444444444444444447C444444004400440044004
+897F:0000FFFE0440044004403FF8244824482448244828383008200820083FF82008
+8980:00007FFC044004403FF8244824483FF800000000000000000000000000000000
+8981:00007FFC044004403FF8244824483FF802007FFC042008401C80038006703808
+8982:FFFE04403FF824483FF8000001F03E0001007FF80060018006001800E7FE0000
+8983:FFFE04403FF824483FF800001FF010101FF010101FF00100FFFE010001000100
+8984:00007FFC04403FF8244824483FF80850104837FE504090A010A0111012081406
+8985:0040FE402840287EFEAAAB2AAA2AFE4A104AFE9225124422282210422894C408
+8986:FFFE04403FF824483FF8120027FC42088BF8120833F8510093F8151010E0171E
+8987:FFFE04403FF824483FF822007F7C22443E44087C7F4449447F7C0844FF540888
+8988:FFFE04403FF824483FF810207E20523E4A447EA41028FF2820103E2842448682
+8989:FFFE04403FF824483FF828207DFC2850388813FE7C0855E87D2811E8FE081018
+898A:FFFE04403FF824483FF82800FDFE292039FC11207DFC55207DFE1002FEAA1004
+898B:00001FF0101010101FF0101010101FF0101010101FF00440044008423042C03E
+898C:000001F8FD08050805F84908290811F81108290825F844908090011202120C0E
+898D:010009201110210841041FF010101FF010101FF010101FF0044008421042603E
+898E:00007E7C420442087E10421042FE7E10421042107E1024502422240243FE8000
+898F:100010FC10847C8410FC10841084FEFC1084108410FC2850245044928092010E
+8990:00007E88425042207E50428842007E88425042207E5024882402240243FE8000
+8991:080048FC4884488448FC7E84408440FC40847C8444FC4450445044924492850E
+8992:04000EFC7084108410FC1C84708410FC10841E84F0FC1050145018921092010E
+8993:000801FC7E102210112000001FF010101FF010101FF010101FF004421842E03E
+8994:00007FFC010003600D1871041FF010101FF010101FF010101FF004421842E03E
+8995:1000087C0A440244127C134454C454FC54449844197C112831284F4A804A0086
+8996:200011FC1104F90409FC1104110439FC5504950411FC1050109010921112120E
+8997:00007F7C014401447D7C014401447D7C454445447D7C45280128014A0A4A0486
+8998:100010FC10841E8410FC1084108410FC7E84428442FC425042507E924292010E
+8999:200020FC20847E8442FC4484908410FC5484548452FC5250925010925092210E
+899A:2208111000207FFE40029FF410101FF010101FF010101FF0044008421042603E
+899B:0200077C38442044237C2C44284428FC2D442A442A7C29282928494A4C4A8886
+899C:280028FC28842884AAFC6C84288428FC6C84AA8428FC28502A504C924892810E
+899D:00007CFC10841084FEFC1084108400FC1084528452FC9450285024924492810E
+899E:00007CFC448444847CFC448444847CFC448444847CFC28502A502C924892810E
+899F:0800087C0844FF44087C084408447E7C104408442A7CA128A128A54A1C4A0086
+89A0:00007E7C12441244FF7C124412447E7C204420447E7C6228A228224A3E4A2286
+89A1:0000007C7F440844087C2A442A442A7C5D444944887C08280F28F04A404A0086
+89A2:100052FC5484908428FC4484828410FC1084528454FC9050285024924292810E
+89A3:0C0070FC1084FE8438FC5484928400FC1084FC8424FC4450285010922892C50E
+89A4:10001EFC10847E8452FC5C84708452FC4E8440845CFC5450545096929492210E
+89A5:1400147C14447F44557C554455447F7C55445544557CFFA82428224A424A8086
+89A6:1000287C444482447D7C0044F144957C9544F544957C9528F528914A954AB286
+89A7:3F2024203F3E21403F5024883FF810101FF010101FF010101FF004421842E03E
+89A8:0000777C55445544777C00447F44007CFFC420443F7C01280128014A0A4A0486
+89A9:1000107C7D441244147CFF441044207C7E44A244227C3E282228224A3E4A2286
+89AA:1000087C7F440044227C1444FF44087C08447F44087C2A28492888CA284A1086
+89AB:1000087C7F440044227C14447F44517C08447F44107C1E281228224A2A4A4486
+89AC:0800497C49447F44007CFF4400447F7C414441447F7C422824280F4AF04A4086
+89AD:0000FF7C814400447E7C42447E44427C7E441044087CFF280028244A424A8186
+89AE:08202AA44D28145022887FFE40029FF410101FF010101FF010101FF00842F03E
+89AF:2200227CFFC422447F7C2244FFC4087C7F4449447F7C4928FFE8414A454A4286
+89B0:10001E7C10447F44517C5C4472444E7C40445E44527C5E2852285E4A524ABF86
+89B1:08047F7808403E402A7E3E482A48FF4808881FF010101FF010101FF00442783E
+89B2:2200227CFFC422443E7C08447F44497C7F4408447F7C08287F28084A0F4AF086
+89B3:2000207C3F444844887C7F441444227C7F44A4443F7C24283F28244A3F4A2086
+89B4:0A00747C15445244227C21445D44807C7E444244427C7E284228244A0F4AF086
+89B5:E700A57CE744A544E77C8144BD44A57CBD44A544BD7CA528A528CD4A814A8386
+89B6:0F00F07C49442244FE7C14440844FF7C9544BD44837CBD289528894A954AA386
+89B7:10001E7C10447F44517C5C4472444E7C40444A446AFC5B284A288F4A784A0086
+89B8:0000777C55447744557C774441445D7C55445D44557C5D285528414A454A4286
+89B9:0144F9548B548DF8F80E89128AEAFE0A8A0A8AEAFAAA52A452B456AA5B0A9210
+89BA:3AB821083AB82288393822887FFE50129FF410101FF010101FF004421842E03E
+89BB:08000F7C08447F44497C4C447944477C40445F44407C5F2851285F4A8A4A3F86
+89BC:0000FF7C52449144FFFC9144DB44B57CDB449144DB7CB528DB28914A954A8286
+89BD:7E40487E7E9043087EFE48AA7FFE10101FF010101FF010101FF004421842E03E
+89BE:1000087C7F444144867C784449442A7CFF442A44417CBE282A283E4A2A4A3E86
+89BF:1000FEFC10847C8400FCFE84AA84FEFC44847C8444FC7C5044507C922892450E
+89C0:2200227CFFC42244777C55447744127C3F446444BF7C24283F28244A3F4A2086
+89C1:00001FF01010101011101110111011101110129012900480048008823082C07E
+89C2:000001FC0104FD0405240524492429241124115428502490449081120212040E
+89C3:00003E7C220422082A102A102AFE2A102A102A10081014501422240243FE8000
+89C4:100011FC11047D04112411241124FF241124115410502890249045128212040E
+89C5:01F87E0012100910092000001FF010101110111011101290028004821882607E
+89C6:200011FC1104F90409241124112439245524955410501090109011121212140E
+89C7:100011FC11041F0411241124112411247D2445544450449044907D124612040E
+89C8:04402440247C2490250804001FF010101110111011101290028004841884607C
+89C9:2208111000207FFE400280041FF010101110111011101290028004841884607C
+89CA:0800497C494449447F5400547F54015401543F542010202823282C4A308A0106
+89CB:0000007C7F44084408542A542A542A545D544954881008280F28F04A408A0106
+89CC:0800087C7E4408440854FF5401542A54185448542810FF281428224A414A8186
+89CD:1400147C14447F445554555455547F54555455545510FFA82428224A428A8106
+89CE:1000287C444482447D540054F15495549554F55495109528F528914A954AB286
+89CF:2400247CFF4424447E542454FF5408547E544A547E104A28FF28424A4A4A4486
+89D0:2200227CFFC422443E5408547F5449547F5408547F1008287F28084A0F4AF086
+89D1:10001E7C10447F4451545C5472544E5440544A546A905B284A288F4A784A0086
+89D2:080008001FE020204040BFF8210821083FF8210821083FF82108410841288010
+89D3:100410041F2421244224BFA424A424A43FA424AC24B43FA42484448442848104
+89D4:101010101F102110427EBF92249224923F92249224923F92249244A242AA8144
+89D5:1080108050F851087E1055FC912411241DFCF124512411FC1124122412141408
+89D6:20202020782049FC90247C24542454247DFE542054507C505488548845048E02
+89D7:1004101E3CF024904890BE902A902AFE3E902A902A903E882A8A4AAA42C68682
+89D8:101010103C1024104854BE522A522A903E102A142A043E082A084A10422086C0
+89D9:100010FC3C4424484848BE502A5C2A443E442A442A683EA82A904A9843248642
+89DA:2008201C79F0495091507D50555055507D50554855487D685554567446528C00
+89DB:100010003CFC24844884BE842AFC2A843E842A842AFC3E842A004A0043FE8600
+89DC:088028882EF028842E84F07C08000FC010803FF851081FF811081FF811082118
+89DD:1004101E3CF024904890BE902A902AFE3E902A902A903E882A8A4AAA42D6868A
+89DE:104010403C7E2480497CBE082A102A203EFE2A4A2A4A3E922B124A2242548688
+89DF:101010103C7C24104810BE102AFE2A003E102A102A7C3E102A104A1042FE8600
+89E0:111009207FFC0200FFFE08203818CFC610803FF851081FF811081FF811082118
+89E1:104010403C7824884950BE202A502A883F062AF82A883E882A884A8842F88688
+89E2:08007F7C08243E2408447F5408880FC010803FF851081FF811081FF811082118
+89E3:100010FC3C2424244854BE882A102A503E7C2A902A103EFE2A104A1042108610
+89E4:2040204078FC490492087DFE5500557C7D44554455547D4855425542453E8E00
+89E5:20202020792448A490A87C2055FE54907C90549054907C9255125512460E8C00
+89E6:20202020782049FC91247D24552455247DFC552454207C28542457FE45028C00
+89E7:108810483C50240049FCBE202A202AFC3E202A202BFE3E202A204A2042208620
+89E8:200021FC7820482093FE7C00542054227FB254B454A87D285524562444A28C40
+89E9:202820247824482093FE7C20552054B27CB4546854A87D245622542044A08C40
+89EA:104010203CFC24004888BE502BFE2A203E202A202AFC3E202A204A2042208620
+89EB:2020202079FE482090207DFC552455247DFC542054707CA85524562244208C20
+89EC:20002040799C490491047DDC550455047DFC545054507C505490549245128E0E
+89ED:2020202079FC485090887D0457FE54087DE8552855287DE85528540844288C10
+89EE:100010FC3C042404487CBE042A042AFE3E102A922A543E382A544A9242508620
+89EF:21042088785049FC91247D2455FC55247D2455FC54207C2057FE542044208C20
+89F0:102010203CFA24244828BFFE2A202A403EFC2B442A443E7C2A444A44427C8644
+89F1:00283FFE20202FA420282F9048AA4FC690823FF851081FF811081FF811082118
+89F2:208820507BFE482091FC7C2057FE54007CA054FC55207C2057FE542044208C20
+89F3:0800FFB808287F280028FFC6A0803E7C4224FF2449287F2849107F2849448B82
+89F4:1040107E3C80257C4844BE7C2A442A7C3E002AFE2A403EFE2B2A4A4A42928626
+89F5:2048204879FC484890487DFE542055FC7D2455FC55247DFC5400544844848D02
+89F6:200021DC7954495491DC7C0055FC55247DFC552455FC7C2057FE542044208C20
+89F7:0A803138228839382288FFFE88020FC010803FF851081FF811081FF811082118
+89F8:200021FC7954495491FC7C8055FC56447DF4555455547DF4544455F444148C08
+89F9:105010483CFE259048FCBE902AFC2A903EFE2A002AEE3EAA2AAA4ABA42828686
+89FA:48F8705044203DFC20247CB890A07D7E2A004FF010202FF848880FF808881098
+89FB:212421747A584ADA93FE7D5456DA57FE7CA2542057FE7C7054A8552446228C20
+89FC:208020F879084BFE91227D5254FC54847CFC548454FC7C4054FC554444388CEE
+89FD:2010211279FE484890FE7D9056FE54907CFE549054FE7C8055DE555245728D06
+89FE:208820887BFE488890F87D04557457567D54555457747D0654005554452A8E2A
+89FF:222223FE789049FE93107DFE551055FE7D1055FE54007DFE554A55F645528D76
+8A00:02000100FFFE000000003FF8000000003FF8000000003FF8200820083FF82008
+8A01:200010001000FE0000007C0000007C0000007C004400440044007C0044000000
+8A02:2000100011FEFE2000207C2000207C2000207C204420442044207C2044A00040
+8A03:204010401040FE4000407C5000487C4400447C404440444044407C4044400040
+8A04:2040202023FC2000FDF8240025F8240025F82508250825FA250A440243FE8000
+8A05:204010401040FE4001F87C4800487C4800487C484448444A448A7C8A45060200
+8A06:200410041084FE8400847C8400847C84008C7C9444E4448444047C0444040004
+8A07:100010001FFC20044204BFE400041FC400041FC400041FC410441FC410540008
+8A08:202010201020FE2000207C2003FE7C2000207C204420442044207C2044200020
+8A09:200011F00110FD100110791001907950015079104910491249127A124A0E0400
+8A0A:200013F00090FC900090789000907BF00090789048904892488A788A48860082
+8A0B:204010401040FEFC00847D0400047D0400847C444444440444047C0444280010
+8A0C:2000100010FCFE2000207C2000207C2000207C204420442044207C2045FE0000
+8A0D:200011F81088FEC800A87CA800887C5000507C504420442044507C8845040202
+8A0E:201010101010FE1001FE7C1000107C1001107C904490441044107C1044500020
+8A0F:200010FC1020FE2000207C2000207DFE00207C204420442044207C2044A00040
+8A10:200010FC1020FE2000207C2000207DFE00207C204420442044207C2044200020
+8A11:202010201020FEA000AC7CB400E47DA400A47CB444A844A244A27C82447E0000
+8A12:2000100010FCFE2400247CA400A47CA400A47D244424444444447C8445280210
+8A13:210411240124FD240124792401247924012479244924492449247A244A040404
+8A14:0100210821083FF802000100FFFE00003FF800003FF800003FF820083FF82008
+8A15:202010201020FE2001247D2401247D2401247D244524452445247DFC44040000
+8A16:204010401080FEFE01007E0000FC7C0800107C204440448045027D0244FE0000
+8A17:2008103C11E0FE2000207C2000207C3E01E07C204420442244227C22441E0000
+8A18:2000100010FCFE0400047C0400047CFC00847C804480448044827C82447E0000
+8A19:204010401040FDF800487C4800487D4800C87C4844A844A8448A7D0A45060202
+8A1A:200017FC020441045FF440044FE440044FE440044FE4482448244FE44824400C
+8A1B:20A010A000A0FD2401247B2805307920016079A04920492249227922491E0100
+8A1C:201010501050FE5000887C8801047EFA00487C484448444844887C8845280210
+8A1D:200011FC1010FE9000907C9001107DFE00307C504450449045107E1044500020
+8A1E:2008103C11E0FE2000207C2003FE7C2000207C504450445044887C8845040202
+8A1F:200810481048FE4800447C8400A47D2200207C404440444844847DFE44820000
+8A20:200411E40024FC24002479E401047904010479E4482448244824782449440084
+8A21:202010201050FE5000887D4402227C2000007DFC4404440844087C1044100020
+8A22:2004100E10F0FE8000807C8000FE7C8800887C884488448844887D0845080208
+8A23:202010201020FDFC00247C2400247C2403FE7C204450445044887C8845040202
+8A24:200810881050FE2000507C8801007C0800887C884450445044207C5044880306
+8A25:202010200020FC2003FE7A2202227A2202527A4A4A8A4B024A027A024A0A0204
+8A26:202010200020FDFE01227A24002078200050785048504850489078924912020E
+8A27:204010501048FE4800407DFE00507C5000507C504490449044927D12450E0200
+8A28:201010101010FE9000907C90009E7C9000907C904490449044907C9045FE0000
+8A29:200010080108FC8802527A5202227A2202527A924B0A4A0A4A027BFE48020000
+8A2A:204010201020FDFE00407C4000407C7C00447C444444444444847C8445280210
+8A2B:200010400020FC100090788000807A8402827A824A824C884888788848780000
+8A2C:202010201020FEA800A47CA201227D2002247C244428440844107C2044C00300
+8A2D:200010F81088FE8800887D0602007DFC00847C844448445044207C5044880306
+8A2E:200011FC0088FC880088788800887BFE00887888488848884888790849080208
+8A2F:200013FC0084FC8800887890009C788401447944492849284A107A2844440182
+8A30:202010200020FBFE0020792401247924012479FC4824482048227822481E0000
+8A31:208010800080FDFC01207A200020782003FE7820482048204820782048200020
+8A32:202010200020FC2001FC792401247924012479FC492448204820782048200020
+8A33:200011FC0104FD040104790401FC792401207920491049104A087A0844040802
+8A34:2008101C01E0FD000100790001FE7910011079304918491449127A104A100410
+8A35:2000100003FCFE9402947A9402947A9402947A944A9C4B044A047A044BFC0204
+8A36:2000100003FEFC08000879E8012879280128792849E849284808780848280010
+8A37:202010200020FDFC01247924012479FC01247924492449FC4924782048200020
+8A38:201C10E01020FE2000207DFE00207C7000707CA844A8452446227C2044200020
+8A39:202010281024FC2003FE7C2000707C7000A87CA84524462244207C2044200020
+8A3A:202010200050FC8801047A120020784001887810482048444988781048600380
+8A3B:204010200000FDFE002078200020782001FC782048204820482078204BFE0000
+8A3C:2000100003FEFC200020782001207920013C7920492049204920792047FE0000
+8A3D:208010800100FDFC02047C0401E479240124792449E449244804780448280010
+8A3E:088028882EF028842E84F07C01007FFC00003FF800003FF800003FF820083FF8
+8A3F:209010900090FA9002927AD402987A9002907A904A904A924AD27F124A0E0000
+8A40:202010201020FE20003E7C2000207C2001FC7D044504450445047D0445FC0104
+8A41:202010200020FC2003FE78200020782001FC7904490449044904790449FC0104
+8A42:208810880088FD08017E7B080508794801287928490849084908790849280110
+8A43:202010101010FDFE00207C2000447C8401F87C104420444444827DFE44820000
+8A44:202010200120FD2001FC79200220782003FE7820485048504888788849040202
+8A45:202010201050FE5000887D2402127C1001FC7C044408448844507C2044100010
+8A46:2004101E11F0FF1001107D1001107DFE01107D1045104508450A7D4A45A60112
+8A47:202010200020FDFC012479240124792401247BFE482048504850788849040202
+8A48:00003FF8244824483FF80100FFFE00003FF800003FF800003FF820083FF82008
+8A49:41002100013EF91207D27252025272540254749452885108529474A458420080
+8A4A:202010201124FEA400A87C2001FC7C2000207C2047FE442044207C2044200020
+8A4B:200011FC0104FD040104790401FC78500050785048504892489279124A0E0400
+8A4C:208810881088FE8801FE7C8800887C8800887CF84488448844887C8844F80088
+8A4D:204811480148FD4801487BFE0148794801487948497849004900790049FE0000
+8A4E:200010FE1080FE8000807CFC00847C8400847C8444FC448044807C8044FE0000
+8A4F:201010900090FD10017E7A5203927892011279124A524BD248627822484A0084
+8A50:208010801080FCFE01407D4002407C7C00407C404440447E44407C4044400040
+8A51:202010101010FEFE00827D0400407C4800507C604440444244427C42443E0000
+8A52:202010201020FE4000487C8401FE7C8200007CFC4484448444847C8444FC0084
+8A53:202010201020FDFC00207C2000207DFE00207C204440444844847DFE44820000
+8A54:200011FC1044FE4400447C4400947C8801007CFC4484448444847C8444FC0084
+8A55:200011FC1020FE2001247CA400A87C2003FE7C204420442044207C2044200020
+8A56:201010100010FDFE01127914011079FC014479444928492849107A284A440482
+8A57:200011FE1102FF0201027D7A014A7D4A014A7D4A457A454A45027D02450A0104
+8A58:202010200124FD240124792401FC782000207924492449244924792449FC0004
+8A59:205010480048FC4003FE7880008078FC01447944492849284A107A2844440182
+8A5A:2000100010FCFE8400847C8400FC7C8400847C8444FC448444007C0045FE0000
+8A5B:200010F81088FE8800887CF800887C8800887CF84488448844887C8845FE0000
+8A5C:202011240124FD2401FC782000207BFC01047888488848504820785049880606
+8A5D:204010200020FDFE01027A040000780001FE7820482048204820782048A00040
+8A5E:200011FC1004FE0401F47C0400047DF401147D1445F4451444047C0444280010
+8A5F:04800440FFFE0940118466FC01007FFC00003FF800003FF800003FF820083FF8
+8A60:204010200010FDE00022783403B878B000A878A8492849244A247C2248A00040
+8A61:200013DE0042FC420252794A014A784200C6794A4A52484248427842494A0084
+8A62:2080108001FCFD04020479E40124792401E47924492449E44904780448280010
+8A63:208010841098FEE000827C82007E7C0000FC7C84448444FC44847C8444FC0084
+8A64:201011101110FF2801447D0001FE7C0000A87CA844A844A844A87CAA452A0206
+8A65:202010201050FE5000887D0402FA7C0000007CF84488448844887C8844F80088
+8A66:201010140012FC1003FE7810001079D0009078904890488848EA7B8A48060002
+8A67:108010803EFC62449448483031102FE8C0061FF000001FF000001FF010101FF0
+8A68:204010200020FDFE0000788801047A0200887888485048504820785048880306
+8A69:202010200020FDFC0020782003FE7808000879FE480848884848780848280010
+8A6A:200011F80108FD0801F87908010879F801447948493049204910794849860100
+8A6B:2040102003FEFA020000783803C078400040787C4BC0484048427842483E0000
+8A6C:2008101C01E0FD00010079FE01007900017C79444944494449447A7C4A440400
+8A6D:2040104000FCFD04020879FE0100797C014479444954494849427A424A3E0400
+8A6E:202010200050FC8801047A0201FC78200020782049FC4820482078204BFE0000
+8A6F:202010200040FDFC01047904010479FC0104790449FC49044904790449FC0104
+8A70:202010200020FBFE0020782001FC7800000079FC490449044904790449FC0104
+8A71:2008103C11E0FE2000207DFE00207C2000207DFC4504450445047D0445FC0104
+8A72:202010101010FDFE00207C2400447CF800127C224444458844107C2844440182
+8A73:210410840088FC0003FE7820002079FC002078204BFE48204820782048200020
+8A74:2020102011FEFE4000407CFC00847D8402FC7C84448444FC44847C8444940088
+8A75:202011200120FDFC01207A2000207BFE0090789048904890491279124A12040E
+8A76:208210920092FC920092789202DA7AB604927892489248924892791249020202
+8A77:200011FE1102FF02017A7D0201027D7A014A7D4A454A457A45027D02450A0104
+8A78:202010200124FCA400A8782000207BFE007078A848A8492449247A2248200020
+8A79:08000FF010203FFE6508A8843FFE200027F8200027F8200027F8440847F88408
+8A7A:20201020107EFE8201447C2800107C2000407CFE4542444244427C42447E0042
+8A7B:2080108000F8FD0803107CA0004078A001187A064DF849084908790849F80108
+8A7C:204010400040FDFE0080789000907912015279544A904A284C28784448840102
+8A7D:200011DC0088FC880088788800887BDE00887888488848884888790849080208
+8A7E:210011000100FDFE02027A02051278A2024A7AAA4B1A4A0A4BFA780248140008
+8A7F:2020102001FCFC200020782003FE78000020782049FC4820482078204BFE0000
+8A80:200013FE1088FE8800F87C8800887CF800887C88448E47F844087C0844080008
+8A81:210410840088FC0001FE78880088788800887BFE48884888490879084A080408
+8A82:205010501050FD5200D47C5800507C5800D47D524650445044927C924512020E
+8A83:20201020107CFE8401487C3000207C4801907C3E444245A444187C1044600180
+8A84:2020102003FEFC20002079FC0020782003FE787048A848A849247A2244200020
+8A85:202011200120FDFC01207A2000207BFE007078A848A8492449247A2248200020
+8A86:200013FE0200FE0003FC7A2002207AF802207A204A204BFC4A007A004BFE0000
+8A87:2020102003FEFC500088790402FA780003FE7840488049FC4804780448280010
+8A88:200011FE0020FC400088790401FE78220020782049FE4820482078204BFE0000
+8A89:2208110811100020FFFE082011102FE8C0061FF000001FF000001FF010101FF0
+8A8A:1110091009207FFC0200FFFE09203FF8C0061FF000001FF000001FF010101FF0
+8A8B:200011F80008FC0801F879000104790400FC7840482048A44A8A7A8A44780000
+8A8C:202010200020FBFE00207820002079FC0040782048A44A824A8A7A8A4C780000
+8A8D:200013FC0044FD4401447A84009479080240782048A44A824A8A7A8A44780000
+8A8E:2020102003FEFC20002079FC0124792401FC7820487048A849247A2248200020
+8A8F:2020101010FCFE8400847CFC00847C8400FC7CA244A4449844907C8844C40082
+8A90:201010D80394FC9400907BFE00907894009478D84B98489048AA78CA4A860102
+8A91:4000244002BEF90802887488008870BE018872885488508850887088553E0200
+8A92:202010400088FD0403FE7882008079FC022078204BFE48204850788849040602
+8A93:080C7EF008800EFE78880A8819087FFC00003FF800003FF800003FF820083FF8
+8A94:2000100603B8FC8800887908013E7B8800887A884A88493E49007A80447E0800
+8A95:2004100E03B8FC8800887928012E7BA800A87AA84AA8493E49007A80447E0800
+8A96:2020102003FEFC2000207BFE02027C0401F8781048204BFE4820782048A00040
+8A97:204210E20382FC8A008A788A03EA788A018A79CA4AAA4A824C827882488A0084
+8A98:201C11E00020FC2003FE78A801247A2201F87888489048BE490279024A140408
+8A99:200011FE0000FC9201247A4801247892000079FE48204820482078204BFE0000
+8A9A:2020112410A4FEA800207DFC01047D0401FC7D04450445FC45047D0445140108
+8A9B:200011FC0004FCFC000479FC00007BFE020279F8488848884850782048D80306
+8A9C:204010400088FD0403FE780200887944024278F849884A504820785049880606
+8A9D:202010201050FE8801447E2200F87C0800107C2045FC450445047D0445FC0104
+8A9E:200013FC0040FC4001F8788800887BFE0000780049F849084908790849F80108
+8A9F:2020102211FAFE2400247DFE00107C2001FC7C88451046FE44107C1044500020
+8AA0:202810240024FC2003FE7A2002247A2403A47AA84AA84A904A927DAA44460882
+8AA1:201010140012FC1003FE78100150795407F47954495449484A4A7A5A44260042
+8AA2:200011F80108FD0801F87908010879F80108790849F84890489079124A12040E
+8AA3:200011FC0020FC20012479240124792402AA7AAA4CB24820482078204BFE0000
+8AA4:200011FC0104FD0401FC7800000079FC002078204BFE48204850788849040202
+8AA5:202011200120FDFC01207A2000207BFE0000780049FC49044904790449FC0104
+8AA6:200011F81008FED000207DFC01247D2401FC7D24452445FC45247D244524010C
+8AA7:2028102411FEFE2000207DFC01247D2401FC7D24452445FC45247D244524010C
+8AA8:2080108010FEFD0002FC7C8400A47C9403FE7C844524451445FE7C0444280010
+8AA9:202010101010FEFE00007C7C00007C7C00007C7C4444444444447C7C44440000
+8AAA:201010900088FD0802047DFA01087908010879F848904890489079124A12040E
+8AAB:200011FE0100FD00017C7900010079FE015079524954494849487A444A520460
+8AAC:210410840088FC1001FC79040104790401FC785048504890489279124A0E0400
+8AAD:2020102003FEFC2001FC780003FE7A020404789048904890489079124912020E
+8AAE:2088108813FEFC8800887C5000507C9401947E98449044B244D27C92448E0080
+8AAF:20FC10841084FEFC00847C8400FC7C0001FE7D02450245FE45027D0245FE0102
+8AB0:20A010900080FDFE01107B1005FC7910011079FC49104910491079FE49000100
+8AB1:2020102003FEFC2001FC782403FE782401FC78204920493E49207AA04A7E0400
+8AB2:200011FC0124FD2401FC7924012479FC00207BFE487048A849247A2248200020
+8AB3:400023FE0202FA0203FE721002927292029272FE521052925292749254FE0802
+8AB4:2040102003FEFA02000079FC0000780003FE7820492849244A227C2248A00040
+8AB5:218410680030FCC80324782003FE784000FC79844AFC488448FC788448940088
+8AB6:2040102003FEFC000088788801547A22000078204BFE48204820782048200020
+8AB7:200013FE0202FE8A02527BFE02427A2203FE7A824A824A824AFA7A024A0A0204
+8AB8:201013880088FCFE00907B9002247A2402387B884890489048A478BE4A820100
+8AB9:205010500050FBDE00507850005079DC00507850485048504BDE785048500050
+8ABA:202010200020FBFE002079240124792402AA787048A848A849247A224C200020
+8ABB:2020102203B4FCA800A8792402A2784001FC7904490449FC4904790449FC0104
+8ABC:2020101001FEFD02020478F80088788800F87888488848F8488878884BFE0000
+8ABD:20001040039CFA0402047B9C02047A0403FC789048904890489079124A12040E
+8ABE:7C7C44447C7C44447C7C41045FF440044FE440044FE440044FE448244FE4400C
+8ABF:200011FC0124FD240174792401FC7904017479544954497449047A044A140408
+8AC0:2040108001FCFD24012479FC0124794401FC789049104BFE4810781048100010
+8AC1:200013DE0042FD4A0084794A02527C2000007BDE48524952489479484A540422
+8AC2:20401040007CFC8401087A00002079CE0102790249CE49024902790249FE0102
+8AC3:208810880088FC8803DE78880088799C01DC7AAA4AAA4CC84888788848880088
+8AC4:2040102003FEFC0001FC790401FC780001FC780848104BFE4820782048A00040
+8AC5:08207FFC08200FE008200FE00820FFFE11103FF8C0061FF000001FF010101FF0
+8AC6:2088108813FEFC8800887CF800887C8800F87C88448847FE44007C8845040202
+8AC7:202010A200A2FD240050788803047822002078A448A449284850788849040202
+8AC8:2008103C01E0FC2003FE78A800A878A803FE78A848A84BFE4820782049FC0000
+8AC9:201C11E00020FC2003FE78A801247A4200407BFE4888490848D0783048480184
+8ACA:2080108000FEFD0202427A4A0152784203FE784248E249524A4A784248540008
+8ACB:2020102003FEFC2001FC782003FE780001FC790449FC490449FC790449140108
+8ACC:2020102013FEFC2001FC7D2401FC7D2401FC7C20447044A845247E2244200020
+8ACD:2080108001F8FD0802107DFC0024782403FE7824482449FC4824782048A00040
+8ACE:204810481048FDFE00487C4801FE7C0000FC7C84448444FC44847C8444FC0084
+8ACF:200017E0025EFA5202527BD202527A5403D47A544A484AE84F54785448620040
+8AD0:17F8240867F8A2A024A4289C01007FFC00003FF800003FF800003FF820083FF8
+8AD1:200013FE0040FC8001447A2400687AB001307AA8486848A449227A2048A00040
+8AD2:2040102003FEFC00000079FC01047904010479FC482048A849247A2248A00040
+8AD3:20481044105EFDE000287C12006A7D9600487C5E45E0442444287C12446A0186
+8AD4:4100210001DCF9140114711407D4701401147114558855485948711455140222
+8AD5:20201020003EFC2001FE7922013879E00122791E490049784A487A4A448A0906
+8AD6:202010200050FC8801047AFA000079FC0154795449FC4954495479544904010C
+8AD7:202010200050FC8801447A2201F878080050782048A44A824A8A7A8A44780000
+8AD8:2020102003FEFC20002079FC0020782003FE784048A449A84A907C8848C60080
+8AD9:201C13E00220FBFE02207A92030A7A0601FC7904490449FC4904790449FC0104
+8ADA:2020101010FEFE8201047C0000FE7C1000107C90449E449044907CD0453E0200
+8ADB:2020102000A0FD2C0124792401AC7924012479FC492448504850788849040202
+8ADC:204811480148FBFE014879480178790001FE78204BFE487048A879244E220020
+8ADD:200013FE0022FD20013C792002FE7C0001FC790449FC490449FC790449140108
+8ADE:2040102001FEFD02010279FE0100790001FE79AA49AA4AFE4AAA7AAA44A20086
+8ADF:200011FC0104FD0401FC7904010479FC00007BFE48204920493C79204AA0047E
+8AE0:2040102003FEFA02040479FC000079FC010479FC490449FC490478004BFE0000
+8AE1:2088110402FAFC40008078F800087850002079FC49544954495479544BFE0000
+8AE2:200013FE0222FC2003FE782001FC792401FC792449FC48204BFE782048200020
+8AE3:200010FC1084FE8400F47C9400947DFE01027D7A454A454A457A7D02450A0104
+8AE4:200013DE0252FE5203DE780001FC780003FE7880490049FC4804780448280010
+8AE5:2008103C01E0FC2003FE782001FC792401FC792449FC482049FC78204BFE0000
+8AE6:2040102001FCFC000088785003FE7A22042479FC492449244934792848200020
+8AE7:2110111201D4FD1801527992012E784001FC7904490449FC4904790449FC0104
+8AE8:200013FE0000FDFC0104790401FC780003FE7A224A224BFE4A227A224BFE0202
+8AE9:208410480000FDFE0048784800487A48014A794C48484848484878484BFE0000
+8AEA:2040102003FEFC0001FC790401FC780003FE7A0249FC48204820782048A00040
+8AEB:2020102003FEFC2001FC792401AC7974012479FC4820487048A879244A220020
+8AEC:0C28702411FEFE503852548E91007FFC00003FF800003FF800003FF820083FF8
+8AED:204010A00110FA0805F6780003C47A5402547BD44A544A544BD47A444A5402C8
+8AEE:2020112000BEFC4200847B10011079280144788248FC48844884788448FC0084
+8AEF:202011240124FD2401FC780003FE7820004079FC49544954495479544954010C
+8AF0:200011FC0124FD2401FC7924012479FC0000784048244AA24A8A7C8848780000
+8AF1:2040104001FCFC8403FE780001FC790401FC78204BFE48204A207BFE48200020
+8AF2:200013FE0050FC5001FC79540154795401FC7820482049FC482078204BFE0000
+8AF3:2020101011FEFE0000847C4801FE7C0000FC7C84448444FC44847C8444FC0084
+8AF4:2008100C000AFBFE02087A0802E87A0A020A7AEC4AAC4AA84AEA7A1A4A260442
+8AF5:2020102003FEFC2000207BFE028A7A5202FA7A224A224AFA4A227A224A2A0204
+8AF6:2088108803FEFC8800F8788800F8788800887BFE490049484984790049FE0000
+8AF7:400027FC0404FC3405C4744405F47554055475F45444545455F4749458061002
+8AF8:2020102201FAFC2400287BFE0020784000FC79844A8448FC4884788448FC0084
+8AF9:200011F80108FDF8010879F800007BFE010079FC4A544C9449247A4448A80110
+8AFA:2020101001FEFC000084784801FE7908011079644908491249647A084A3004C0
+8AFB:2020104001FCFD0401FC790401FC780003FE7820482049FC482078204BFE0000
+8AFC:201E13E00044FD24008879FC0040784003FE788048FC494449287A1048680186
+8AFD:2088108803FEFC8800F8782001FC7924012479FC48204BFE4820782048200020
+8AFE:2088108803FEFC8800A8782003FE7840008078FC49844A844884788448FC0084
+8AFF:200010F81088FE8800F87C0001FE7C8800F87C8844F84488449E7DE844080008
+8B00:2088108803FEFC88008878F80088788800F878204BFE487048A879244A220020
+8B01:200011FC1104FDFC01047DFC00807DFE02227D224552450245FA7C0244140008
+8B02:200013FE0222FBFE02227BFE000079FC010479FC490449FC4904790449140108
+8B03:200011FC0104FDFC010479FC0020792001FE7A20482049FC482078204BFE0000
+8B04:024879504BF848804FFC79104A484FFC48027BF848004BF848004BF84A089BF8
+8B05:2040104010FEFD2200AA7CFA00427C9401487CFE452246AA44FA7C4244940108
+8B06:2020101001FEFD02010279FE010079EE012279AA4966492249667AAA4A220466
+8B07:01007FFE44429FF404403FF80440FFFE09201FF02008DFF600001FF010101FF0
+8B08:1FF010101FF010101FF008207FFC0820FFFE0A203118DFF600000FE008200FE0
+8B09:2020104003FCFE2402247BFC02247A4403FC784048A848B4493C79224A22041E
+8B0A:2088108803FEFCA800107BFE0080788000FC780048A848A848A878AA492A0206
+8B0B:4208220803BEF4880AA8713E02087448084877FC50E0515052487C4650400040
+8B0C:200013FE0008FDE8012879E800007BFE000879E84928492849E8780848280010
+8B0D:08202AA44D28145022887FFE4102BFF400001FF000001FF000001FF010101FF0
+8B0E:201010940254FD580110787E00107B30013879544994491049107A804C7E0000
+8B0F:20A0112C1124FD2401AC7D2401247DFC00207DFC4488445044207C5044880306
+8B10:404020280090FAA402C2748A01887678000073FC529452945294729457FE0000
+8B11:201E13E00122FC940040788801F0782000C479FE482248204BFE785048880306
+8B12:202010200050FC4800A479FE028478FC008478FC488048FC494479444A7C0044
+8B13:2020102003FEFC2001FC790401FC790401FC790449FC49044BFE788849040202
+8B14:4040207C0040FBFE0242727803C07244023C720052FC528053FE7480548008FC
+8B15:4004201E03F0FA1E021072FE0292729802F2728E528052B852A874AA554A0A86
+8B16:200011FC0124FDFC012479FC00887944024278F849884A504820785049880606
+8B17:2040102003FCFD0800907BFE02027C4400207BFC488048F84888790849280210
+8B18:200013FC0204FA0403FC7A4002207BFC02887A504BFE4A204DFC7C2048200020
+8B19:208810500000FDFE005079FC00547BFE005479FC485048D849547A5248500050
+8B1A:210410840088FC0003FE780000887904020279FC495449544954795447FE0000
+8B1B:2088108803FEFC8801FC788803FE782001FC792449FC49244BFE790449140108
+8B1C:200011FE0110FD20017C7944017C7944017C79104910495449527A924A500420
+8B1D:4084210403C4FA4403DE724403C47264025477D450C451445244744451540088
+8B1E:2040102003FEFC0001FC790401FC780003FE7A024AFA4A8A4AFA7A024A0A0204
+8B1F:203C13C00044FA240128790000407B9C02047A044B9C4A044A047A044BFC0204
+8B20:2040108001FCFA48013078C0030079FC022078204BFE48204924792449FC0004
+8B21:2008103C03C0F8040244792801FC7A2000207BFE482049244924792449FC0004
+8B22:20A0109001FEFB2001FC792001FC792001FE79004BF849084890786049980606
+8B23:21FC102003FEFE2201AC782001AC780001FC78004BFE488048FC780448280010
+8B24:200013FE0050FDFC0154795401FC780001FC78004BFE482048A879244AA20040
+8B25:2020104001FCFD24017C798C01547924015479FC4820481049547942494A0238
+8B26:0878FF4808863E782A483E304148FFFC00003FF800003FF800003FF820083FF8
+8B27:2040102003FEFC0001547924015479FC00207BFE4A424A924AFA7A0A4A020206
+8B28:2088108803FEFC88000079FC010479FC010479FC48204BFE4850788849040202
+8B29:04407FFC04401FF010101FF010101FF00400FFFE11102FE8C0060FE008200FE0
+8B2A:2040102003FEFC8800507BFE02527A8A03067AFA4A8A4A8A4AFA7A024A0A0204
+8B2B:2040102003FEFC8800507BFE02227AFA02227AFA4A8A4A8A4AFA7A024A0A0204
+8B2C:200013DE0042FA52014A7A52002878C4031278604988483249C4781848600380
+8B2D:2108109007FEF80003C47A5403D47A5403D47A444ACC48004BFC788449140608
+8B2E:202013FE0020FDFC00207BFE000079FC010479FC490449FC490479FC48880104
+8B2F:2020103C0020FDFE0122793801E4791C0100797C4944497C4944797C494402FE
+8B30:2010101002FEFD10017C7854007C7B54017C791049FE491049107A90447E0000
+8B31:202011FC0124FBFE012479FC002079FC012479FC48404BFE488879D04870038C
+8B32:2040108801FCFD0802527BFE00507988062678C04B1048644B88783048C00700
+8B33:200013FE0200FE7C02447A44027C7A0002EE7AAA4AAA4AAA4AEE7A004BFE0000
+8B34:200011FC0124FBFE012479FC000079FC010479FC490449FC490479FC48880104
+8B35:200013DE0042FA52014A7A520042782001FC7904490449FC4904790449FC0104
+8B36:2040102001FEFD000148794801FE794801487948497849004AD47AAA452A0800
+8B37:08207E20087EFEC410281E10222846C68100FFFE00003FF800003FF820083FF8
+8B38:410821080108F7D0011E779401247FD4021473D452545248524874D454240842
+8B39:2088108803FEFC8800F8782001FC792401FC78204BFE482049FC78204BFE0000
+8B3A:08207E2008F8FF2814287F6A082AFF560982FFFE00003FF800003FF820083FF8
+8B3B:40102190061EFA22025472080F9072640208771E5AA252425214720852100260
+8B3C:2040107C0040FDFC0144797801C4793C01047978499449584AFE7A1044500020
+8B3D:7CF804887CF840207DFC052415FC0A22FFFE00003FF800001FF010101FF01010
+8B3E:200011F80108FDF8010879F800007BFC02947BFC480049F84890786049980606
+8B3F:4100211E07D2F912011277DE045277D2045277DE511251125FD27122512A0144
+8B40:200813880088F91007DE7A9402A47B9402947B944A944AC84B887E9448A400C2
+8B41:208813FE0088FC0001FC78A800A87BFE00A878A849FC48204BFE782048200020
+8B42:200013DE0252FE5203DE780001FC792401FC792449FC48204BFE782048200020
+8B43:4040207C0040FBFE0242727803C4723C020072505254535454D8745059FE0000
+8B44:210410880000FBFE02227AAA02727A2203FE780049FC490449FC790449FC0104
+8B45:400027DE014AFB5A056A725202D674200084708452D45296529472D4573E0000
+8B46:202013FE0020FDFC000079FC010479FC00887BFE480049FC4904790449FC0104
+8B47:2020102003FEFC8801247A2201FC782803FE784049FC4E8448FC788448FC0084
+8B48:4208210807C8F810079E749407A4701407947094511451C85708711455240242
+8B49:202017A400A8FA9201147A0805F4780203F87A084A084BF84A0879104FFE0000
+8B4A:2020102001FCFC2003FE7908039C790801887E3E48004BFE489078904912020E
+8B4B:239C1294039CFE94039C7A0402F47A9402F47A944AF44A944A947B344A04020C
+8B4C:400E23F00044FA24010873F8020873FC020473FE520252AA52AA750254140808
+8B4D:00803FFE229025FE2E9034FE249024FE24402FFE200027FC400047FC840407FC
+8B4E:200013FC0048FC3003FE785200947B5000207BFE4A524A8A4B767A524A720206
+8B4F:2124112402AAFBAE01247AAA03AE792407FE7910491449144A8A7A4A4A160422
+8B50:2088105003FEFC5001FC7954018C7974010479FC48084BFE4908788848A80010
+8B51:201811E00040FBFE0088797402527870000079FC49044974495479744904010C
+8B52:203C13E00124FCA803FE78A801247A0201FC7924492449FC4924792449FC0104
+8B53:2020102003FEFC2001FC792401FC792401FC78224BFE484248247AA24A8A0478
+8B54:200013DE0252FBDE02107A5201CE780000887BFE488848884BFE788849040202
+8B55:2080108001FEFB540554795403FE7954015479544FFE48004954792A4A2A0000
+8B56:200013DE0088FAA803FE798802DA7CA601F87908490849F84908790849F80108
+8B57:2210121003DEFA28054478A001107A0805F6780048004BF84A087A084BF80208
+8B58:2110109403D2F8120250799007FE781003D27A524A544BD44A4A7A4A4BD60022
+8B59:2090108801FEFD1003107DFE0110791001FE7910491049FE49007AA44A520452
+8B5A:200013FE0050FBFE02527BFE000079FC010479FC490449FC48207BFE48200020
+8B5B:2088108803DEF88807FE788801547A2201FC7904490449FC4904790449FC0104
+8B5C:2108109003FCF8900294799800907BFE000079F84908490849F87908490801F8
+8B5D:400027FC04A4FCA407BC70A007BC74A404A477BC54A454A457BC74A250A2007E
+8B5E:200011FC0154FD5401FC780003FE780001FC790449FC4862489479884AA400C2
+8B5F:20F810880088FCF8000079DC0154795401DC78204BFE487048A879244A220020
+8B60:202017FE0000FBFE02027AFA028A7BFE000079FC490449FC490479FC480007FE
+8B61:2020112400A8FBFE020278F80088788800F8780049FC492449FC792449FC0104
+8B62:204412240128FC7E00107828034A791C0128794C491A492A494879104AFE0400
+8B63:202010200050FC8801047AFA0000780001DC7954495449DC4888788849540222
+8B64:4108220807C8F45007DE746407D47214011477D4521453C852487454555408A2
+8B65:10207E204A7E7EC41028FF1020283EC64300FFFE00003FF800003FF820083FF8
+8B66:2420FF20247E7EC482287A104A287AC60500FFFE00003FF800003FF820083FF8
+8B67:402023FE0288FA5003FE725002FC725403FE725452FC525052D8755456520850
+8B68:409023FC0294FBFC029473FC000073FC020072F8520053FE5520751455480986
+8B69:2040102001FCFC8800507BFE000079FC010479FC490449FC48207A944A8A047A
+8B6A:208813FE0088FDFC010479FC010479FC008079FE4A224D52490279FA480A0004
+8B6B:208010F80108FBFE0144799201FE7900017C7900497C4900497C7A444A7C0444
+8B6C:3E1022FE3E4420287EFEA2103EFC22100100FFFE00003FF800003FF820083FF8
+8B6D:410026DC0454FC5406D47454046677C0001C701457D45114510871C857140222
+8B6E:202010501088FD7402027DFC01247DAC01247DFC440044F844887CF8448800F8
+8B6F:200011FC0154FDFC002079FC00207BFE0088785049FC48204BFE782048200020
+8B70:2104108803FEFC2001FC782003FE7854019278904BFE489048D47B8A489601A2
+8B71:08207FFC01003FF80100FFFE11107D7C01007D7C01007D7C01007D7C45447D7C
+8B72:4080204007FEF9100208751403F8711003F8711057FC512853107D4851860100
+8B73:200011FC0020FBFE022279AC002079AC00007BFE482049FC495479544954010C
+8B74:2010107C0254FD7C011078FE00007B7C0144797C4940497C4944797C4A80047E
+8B75:414421440554FB64015E77E400047234014C77E4508453E4508470E457140008
+8B76:0100FFFE00003FF800003FF820083FF80810FEFE00007CFC00007CFC44847CFC
+8B77:208813FE00A8FC9001FE7B2001FC792001FC792049FE49004BFC78884870038E
+8B78:202013FE0020FDFC00007BFE000279FC00207BFE48004BFE48047BBE4AA4038C
+8B79:202013FE0000FDFC010479FC00007BFE020279FC48404BA448D87B3448D20330
+8B7A:220012BE0302FA5401C8783E020A7BCA052879284FEE49284AA87A584C4E0080
+8B7B:3EF822883EF822883EF822883EF814502288FFFE00003FF800003FF820083FF8
+8B7C:7E40487E7E9043087EFE48AA7EFE02000100FFFE00003FF800003FF820083FF8
+8B7D:0A0033B822083BB820883AB82288FFFE11103FF840049FF200001FF010101FF0
+8B7E:208813FE0000FDE2012A79EA012A79EA0122796648004BDE4A52794A4A5200C6
+8B7F:208813DE0088FDDC00887BDE00887BFC000479FC48044BFC48407AA44A8A047A
+8B80:202013FE0020FDFC00007BFE02527BFE010479FC490449FC490479FC48880104
+8B81:4020201004FEFA44022870FE009276FE029272BA52AA52BA5286750058FE0000
+8B82:210011F80208FFFE02627A9201FC790401FC790449FC488049F87A884870038E
+8B83:208811DC0088FBDE00887954022279FC010479FC490449FC490479FC48880104
+8B84:83F842480248E3F80248E24803F8E0000FBEEAAAAAAAAFBEAAAAEAAAAFBE08A2
+8B85:202013FE0202FC1C03E0792400A87BFE01247A024DFC492449FC792449FC0104
+8B86:22004F9C94802FDE6108AFC8250827D80100FFFE00003FF800003FF820083FF8
+8B87:23DE125203DEFE5203DE7A42027A7A8A03127ADA4A8A4ADA4A8A7AFA4A0A0204
+8B88:400027FE0444FD98048875FE048875DC06AA748854205520553C752055200BFE
+8B89:2010107C0254FD7C011078FE00447B7C0144797C4944497C492879444A80047E
+8B8A:210447C88812F3BC20084B92F83E0380AAAAABAA08001FF8282007C01830E00E
+8B8B:08407F7C1440FF7C22043E7C22403E7C2342FFFE00003FF800003FF820083FF8
+8B8C:4110211007FCF91001F0720802EA76AC02A872AA56EA5A06500072A452520452
+8B8D:200013FE0020FBAE02AA7AAA03AE782003FE78204BAE4AAA4AAA7BAE482003FE
+8B8E:3218291440207BBED06853A8783E53A850287BBE52A852A852A87BBE42A04020
+8B8F:22004F9C94802FDE6208AFC82A482AD80100FFFE00003FF800003FF820083FF8
+8B90:48907EFCC9907EFC48907EFC48907EFC0100FFFE00003FF800003FF820083FF8
+8B91:804040A00110E2080DF6E0000EEEEAAA0EEEE000AFFEA922AFFEE922A92A0804
+8B92:21F0121007FCFA0403FC7A2403B87A2201FE7A104FFC4A444BFC78D0494A063E
+8B93:202013FE0000FDDC015479DC00887BFE00887BFE48884BFE489479884AA400C2
+8B94:400E2770052AFD14053E7608057E7500057E7502553E5602547E741454AA04BA
+8B95:23DE125203DEFE5203DE7A2202FA7A2202FA7AAA4AFA4AAA4AFA7A724AAA0226
+8B96:2148114C02AAFC0803FE79480368794A036A794A4B6C494C496A7B8A48160022
+8B97:222213FE0090F9FE03107DFE011079FE011079FE49004BFE4A8A7B764A520276
+8B98:43FC210801F8F90801F8710E07F8700807FE7294539C5294539C72D657BC0084
+8B99:208813FE0088FBDE02527BDE00A0789001FE79204BFC4D2049FC792049FE0100
+8B9A:452827BE0948F7BE031875AA094673FC020473FC520453FC520473FC51080204
+8B9B:410827FE0108FB90013C77D402B4755C0396712253FC500057FE7080510403FE
+8B9C:4248215007FCF40401F0711007FC755404E477FC504057FC50407FFE52A40452
+8B9D:23DE125203DEFC0003FE7A0002C87A4E03EA7AB24AEA4AAA4AEA7AB445E4082A
+8B9E:810841EC010AEFEA0928EBC8093EEFE80948EBE8AA28AB68AAA8EBF4AAB412A2
+8B9F:81084FE40100E7CE0000EFEE0AA0EFEE0440E7CEA44AA7CAA44AE7CEA28A0440
+8BA0:000020001000100000000000F000100010001000100010001400180010000000
+8BA1:004020401040104000400040F7FE104010401040104010401440184010400040
+8BA2:0000200013FE102000200020F020102010201020102010201420182010A00040
+8BA3:0080208010801080008000A0F090108810841084108010801480188010800080
+8BA4:004020401040104000400040F040104010A010A010A015101910120804040802
+8BA5:000021F01110111001100110F1101110111011101110151219121212020E0400
+8BA6:0000200013FC104000400040F040104017FE1040104010401440184010400040
+8BA7:0000200013FE102000200020F020102010201020102014201820102007FE0000
+8BA8:001020101010101003FE0010F010101011101090109010101410181010500020
+8BA9:004020401040104000400040F07C10401040104010401440184010400FFE0000
+8BAA:002020201020102001240124F12411241124112411241124152419FC10040000
+8BAB:00802080110011FE02000400F1F8100810101060108015001A02120201FE0000
+8BAC:0010207813C0104000400040F040107E17C010401040144218421042003E0000
+8BAD:010421241124112401240124F124112411241124112415241924122402040404
+8BAE:008020481248120802080110F110111010A010A01040144018A0111002080C06
+8BAF:000027F01110111001100110F11017D01110111011101112150A190A11060102
+8BB0:0000200011F8100800080008F00811F811081100110011001502190210FE0000
+8BB1:0000200013FC104400440244F244124414841084108415041904120404280810
+8BB2:011021101110111007FC0110F11011101FFE1110111015101910121002100410
+8BB3:00402040104017FE00400040F3FC1040104017FE10421042144A184410400040
+8BB4:000023FC1200120802880250F2501220122012501250128817081A0013FE0000
+8BB5:000023FE12001200020003FCF20412041204120413FC120016001A0013FE0000
+8BB6:000023FC1010111001100110F21013FE10301050109015101A10141000500020
+8BB7:002020201020102003FE0222F22212221252124A128A130216021A02120A0204
+8BB8:00802080108011FC01200220F020102013FE1020102010201420182010200020
+8BB9:00A020A010A0112401240328F5301120116011A01120112215221922111E0100
+8BBA:0040204010A010A001100208F406111011201140118011001504190410FC0000
+8BBB:000020081108108802520252F222122212521292130A160A1A0213FE00020000
+8BBC:002021201120111001100248F248144418821080111015081A0817FC02040000
+8BBD:000043F822082208032802A8E2A82248224822A822A82B2A340A240A08061002
+8BBE:000021F0111011100110020EF40013F811081110109014A0184010A003180C06
+8BBF:00802040104017FE01000100F10011F811081108110815081A08120804500820
+8BC0:00402040104013FC00440044F044104417FE104010A014A01910120804040802
+8BC1:0000200013FE102000200020F1201120113C1120112015201920112007FE0000
+8BC2:002020201020102003FE0020F020102011FC1104110411041504190411FC0104
+8BC3:0000200017FE1008000803C8F24812481248124813C812481408180810280010
+8BC4:000023F81040104002480148F150104017FE1040104014401840104000400040
+8BC5:000021F811081108010801F8F1081108110811F8110815081908110807FE0000
+8BC6:0000200011FC110401040104F104110411FC1104100014901888110402020402
+8BC7:000023FC12041204020402F4F29412941294129412F416941A04120402140208
+8BC8:01002100110011FE02800280F48010F810801080108014FC1880108000800080
+8BC9:0008201C11E0110001000100F1FE111011101130111815141912121002100410
+8BCA:0040404020A0211002080426E040208023102020204028883310202000C00700
+8BCB:0008203C13E0122002200220F22013FE1220121012101212160A1A8A13260212
+8BCC:0080208010F8110802100420F3FC10041004100411FC10041404180413FC0004
+8BCD:000023FC1004100407F40004F00413E412241224122413E41404180410140008
+8BCE:002020201124112401240124F1FC102010201124112411241524192411FC0004
+8BCF:000023FC1084108400840104F1141208140011FC110411041504190411FC0104
+8BD0:00202020102013FE02220224F22013FC12841288124816501A20145004880906
+8BD1:000023FC1104108800500020F0D81326102011FC102014201BFE102000200020
+8BD2:0020202010401088010403FEF002100011FC1104110411041504190411FC0104
+8BD3:000023FE1200120003FC0220F22012F812201220122013FC16001A0013FE0000
+8BD4:0040404027FC2040004003F8E040204027FE20E0215029503248244408420040
+8BD5:002820241024102007FE0020F02017E0112011101110151019CA170A02060002
+8BD6:0020202011FC102000200020F3FE10001020102011FC10201420182013FE0000
+8BD7:00402040104013FC00400040F7FE1010101017FE101012101510191010500020
+8BD8:00202020102017FE00200020F3FE1000100011FC110411041504190411FC0104
+8BD9:00802080108017FE01000120F22012A414A415281A5010501488190812040402
+8BDA:00284024202027FE04200420E42427A424A424A824A82C903692292A08461082
+8BDB:00202120112011FC01200220F02013FE107010A810A815241924122200200020
+8BDC:00202120112011FC01200220F02013FE1090109010901090151219121212040E
+8BDD:0008203C11E01020002003FEF0201020102011FC110411041504190411FC0104
+8BDE:0008401C2F70211002100450EF5C21502950295025502A7C33002480087E1000
+8BDF:0008403C23C02200020003FEE2002200220022FC22842A843484248408FC0084
+8BE0:0040204010A0111002080406F3F810401040104013F810401440184017FE0000
+8BE1:0100410023F8220804100BFEE20022F82288228822A822902A823482247E0800
+8BE2:0200420023FC240404040BE4E224222423E42224222423E42A24300420140008
+8BE3:01002104113811C001020102F0FE100011FC1104110415FC1904110401FC0104
+8BE4:0080208011F01210002003FCF044104417FE1044104413FC1444184011400080
+8BE5:008040402FFE208001100110E22427E42048208821102A203450208803040C04
+8BE6:020821081110100007FC0040F04013F81040104017FE10401440184010400040
+8BE7:00402020102013FE02020404F03813C010401040107E17C0144018421042003E
+8BE8:000023FE12021444004003FCF08010A0112011FC102014201BFE102000200020
+8BE9:000047BC2084208404A40294E2942084218C229424A420842884308422940108
+8BEA:0040404027FC204003F80080E7FE2090211021FE22102A903450281000500020
+8BEB:0014401220102FFE00100290E29222922FD2229422942A88328A249A04260842
+8BEC:000047FC2040204002480248E248255424D2286220402840304020400FFE0000
+8BED:000047FC2040204003F80088E08827FE2000200023F822082A08320823F80208
+8BEE:0020212410A410A8002001FCF104110411FC1104110411FC1504190411140108
+8BEF:000043F82208220803F80000E7FC204020402FFE204020A028A0311022080406
+8BF0:00202120112011FE02200420F02013FE1000100011FC11041504190411FC0104
+8BF1:001C47E0204020400FFE0150E2482C4623F021102120217C2A04320424280810
+8BF2:0100210011FC120005F80108F148112817FE11081248122817FC180810500020
+8BF3:0000444022BE210802880488E08820BE218822882488208828883088253E0200
+8BF4:020821081110102003F80208F208120813F810A010A0152019221222041E0800
+8BF5:000047F8201021A0004007FCE444244427FC2444244427FC2C44344424540408
+8BF6:004040802110220807FC0104E10023F8244020402FFE204028A0311022080C06
+8BF7:0040404027FC204003F80040E7FE200023F8220823F822082BF8320822280210
+8BF8:0040404423F42048005007FEE040208021F82308250821F82908310821F80108
+8BF9:00004FC024BC24A404A407A4E4A424A827A824A8249025D02EA830A820C40082
+8BFA:0108410827FE210801480040E7FE2080210023FC250429042904310421FC0104
+8BFB:0020202011FC1020002003FEF002109410501110109013FE1428184410820302
+8BFC:00004FFE2080218402440468EAB0213022A8246828A421242A22342020A00040
+8BFD:009020901090179E00900090F090139C109010901090179E1890109000900090
+8BFE:000043F82248224803F80248E24823F8204027FC20E029503248244600400040
+8BFF:003843C02040204007FC0150E2482486208027FC21102A1031A0206000900308
+8C00:00404140265C24440444075CE444244427FC244420A020A02910320824040802
+8C01:01404120212023FE02200620EBFC2220222023FC222022202A2033FE22000200
+8C02:0040404020A0211002880446E80023F020102020204029243522250A090800F8
+8C03:000047FC2444244405F40444E44427FC240425F425142D1435F4240404140808
+8C04:0080408020F8210802100400E040239C22042204239C22042A04320423FC0204
+8C05:0040202013FE1000000001FCF1041104110411FC102014A81924122200A00040
+8C06:0080204017FC100003F80208F3F8100013F81010102017FC1840104001400080
+8C07:0080404027FC200001100110E2A824442000204027FE20402840304020400040
+8C08:004022441244144800A00110F6081044104012481248145018A0111002080C06
+8C09:0040202013FE1222002001FCF124112411FC1124112415FC1924102000200020
+8C0A:0040202013FE1202040401F8F108110811F81108110815F81908110807FE0000
+8C0B:020842082FFE2208020803F8E208220823F820402FFE20E0295032482C460040
+8C0C:0110411027FC211001F00110E1F02110211027FE220022902B08320023FC0000
+8C0D:00904290229027FE02900290E2F0220023FC204027FE20E0295032482C460040
+8C0E:0108410827FE2148002007FEE200220023FC2000224822482A48344A244A0846
+8C0F:004040402FFE204007FC0444E55424E4244427FC20E029503248244600400040
+8C10:0220222413A8123002A20322F25E108013FC1204120413FC16041A0413FC0204
+8C11:0040207C104013FE02420278F3C01244123C120012FC16801BFE1480048008FC
+8C12:000043F8220823F8020803F8E10023FC2444224422A422042BF4300420280010
+8C13:000047FC244427FC044407FCE00023F8220823F8220823F82A08320822280210
+8C14:000047BC24A424A407BC0000E3F820002FFE2100220023F82808300820500020
+8C15:004020A01110120805F60000F3C41254125413D41254125417D41A44125402C8
+8C16:003C47C022442128000003FCE080208027FE210021F82A883250242008D80306
+8C17:010021F01210142003FC0244F24413FC10A01122161E10C01430198010600010
+8C18:00402240117C108401080620F22012501288110611F811081508190811F80108
+8C19:0080404027FC200002080110EFFE200023F82208220823F82A08320823F80208
+8C1A:0040202013FC100001080090F3FE1210122012C8121016241AC8141004600980
+8C1B:0040202011FC100000880050F3FE1222142411FC112411241534192810200020
+8C1C:0010409224522254021000FEE010263822542292231022102A10350028FE0000
+8C1D:0080404027FC2404040407FCE400240027FC26A42AA42BFC3AA42AA412A4020C
+8C1E:000023FE10221120013C0120F2FE140011FC110411FC150419FC110401140108
+8C1F:0110411027FC2110000003F8E20823F8220823F8204027FC28A0311022080C06
+8C20:004042482150204007FE0402E80423F82208220823F820A0292031242224041C
+8C21:000047FC244427FC044407FCE1102208248421F8220825083090206001980E06
+8C22:010842082788248807BE0488E78824C824A82FA821882A883488288802A80110
+8C23:0008203C13C0100402440128F1FC1220102013FE102011241524192411FC0004
+8C24:0040202013FC1108009003FEF2021444102013FC108010F81488190811280210
+8C25:020841082110200007FC0000E1102208240423F822A822A82AA832A82FFE0000
+8C26:02084110200027FE00A007FCE0A42FFE20A427FC20A029B032A82CA600A000A0
+8C27:00404028209022A402C2048AE1882678200023FC229422942A94329427FE0000
+8C28:011041102FFE211001F00040E7FC244427FC20402FFE20402FFC30402FFE0000
+8C29:03F8420823F8220803F80000E7FC24A424A427FC200023F8291030E023180C06
+8C2A:0080404027FC211000A007FCE44425F4244425F4251425142DF4340424140408
+8C2B:0108209017FE100003C40254F3D4125413D4124412CC14001BFC108401140608
+8C2C:000047BC208424A4029404A4E0502188262620C0231020642B88303020C00700
+8C2D:000023FE105013FE025203FEF00011FC110411FC110415FC182013FE00200020
+8C2E:000047BC2108252807BC0318E5AA2946200023F8220822082BF83208220803F8
+8C2F:0140412023FE222006200BFCE220222023FC222022202BFE3200252404920892
+8C30:0200417C2504244405F40444E5F42554257425D4255425F42CE435542444044C
+8C31:0208411027FC20A004A402A8EFFE200023F82208220823F82A08320823F80208
+8C32:000047F82090206007FC00A4E12826A0204027FC24A425142EEC34A424E4040C
+8C33:0108410827CC210A010807DEE44826C8254827C8255427D42D543554245404E2
+8C34:001044FE229222FE001001FEE0002EFE228222FE228022FE2A8232FE250008FE
+8C35:020043F8241027FE0D481624E7FE240025FC240025FC2C0035FC290409FC1104
+8C36:0448444C2AAA20080FFE0288EEE8228A2EEA228C2EEC2A8832EA2F1A04260042
+8C37:08200810110821044280044008203018C0061FF010101010101010101FF01010
+8C38:08881C84F102122210201050FC881104120211FC110411042104210441FC8104
+8C39:004048404440944013FE2840448080907890492049204A484A447C8449FE0082
+8C3A:000024FC22084A4888481448228841FEBC1824282428244824883D0824280010
+8C3B:000025F822484A48884815F822484148BC4825F824482448248A3C8A250A0206
+8C3C:0048244822484A4889FE144822484148BC4825FE2400244824443C8424820102
+8C3D:002048204450948811442A2244F880087810482049FC49044904790449FC0104
+8C3E:0040482045FE95021204285044888104780049FC48204820482078204BFE0000
+8C3F:0E00F05022489284452420204450F888110624F8FE881088FE88288844F88288
+8C40:001E4BE0452294941040288845F0802078C449FE482248204BFE785048880306
+8C41:20001050FE48828411247C2010507C881104FEFA10887C88448844887CF84488
+8C42:000024EE22224AAA886614AA22104128BC442592242024C824323CC4241800E0
+8C43:000853884888891027DE32944AA487947A944B944A944AC84B887E9448A400C2
+8C44:00204BFE442095FC10002BFE465283FE790449FC490449FC490479FC48880104
+8C45:011050904BDE8810225E31824BDE84107BDE4A504BDE4A504BDE7A504A5202CE
+8C46:00007FFC000000001FF010101010101010101FF00000101008200440FFFE0000
+8C47:0000FE0001FC00207C204420442044207C200020442028202E20F02043FE0000
+8C48:0100210821083FF800007FFC00001FF0101010101FF0000008200440FFFE0000
+8C49:0020FE20002001FE7C204420442045FC7C840088444828502E20F05041880606
+8C4A:04403FF824483FF824483FF800007FFC00001FF010101FF008200440FFFE0000
+8C4B:108010803EFC62449448483030102FE8C0061FF010101FF008200440FFFE0000
+8C4C:0040FC2003FE02027D04490049DE4A527A5203528C9A489451101912E212040E
+8C4D:0020FE4000FE00927C9244FE449244A27CFE0048448829FE2E08F00840080008
+8C4E:7EFC48447E4442287E1048287E4400827FFC00001FF010101FF008200440FFFE
+8C4F:0088FE50000001FE7C5045FC445447FE7C5401FC445028D82F54F25240500050
+8C50:08201D7049245D7449245D7449247FFC00007FFC00001FF010101FF004407FFC
+8C51:2844FE28AA00FEFCAA14FE1400FCFE9000907CFE44327C32445A28541E90E110
+8C52:2A227F14AABEFF8AAA8AFFBEAAA8FFA8003EFF9A001A7F2A412E7F482208FF88
+8C53:2A107F10AA90FFBCAA90FFA8AAA8FFA40054FF82007C7F5441547F542254FFFE
+8C54:2A087F08AA9CFF88AA88FFBEAA88FF900014FFBE00007F3E412A7F2A222AFFFE
+8C55:00007FFC020006000908119062A004C008C011A06290048808863080C2800100
+8C56:00007FFC020006000908119062A014C008C015A06290048808863080C2800100
+8C57:0000FDFE2820284028A22B34285828942B34285228922B102850482247FE8000
+8C58:0020FC20102023FE6020952439245124992435FC5424902010221022501E2000
+8C59:020001003FF808200440FFFE02000D08719002A00CC071A006981886E2800100
+8C5A:00007BFE4840488049447A24486848B049307A28486848A449224A2048A09840
+8C5B:0000FCF810882088608895063A0051FC98843484544890501020105050882306
+8C5C:0000FDFE1048204860489448384853FE98483448544890481088108851082208
+8C5D:0000FDFC1124212461249524392451FC99043500550091001102110250FE2000
+8C5E:0040FE40088010FC31044A049CF428944C949A942AF448948804080428281010
+8C5F:0040FC2011FC2104610495FC39005100997C35085510912011421282527E2400
+8C60:0000FEF80888108830884AF89C8828884C889AF82A884888888808882BFE1000
+8C61:08001FE020207FF8A10822083FF80600191062A00CC071A006901888E2860100
+8C62:111009207FFC0400FFFE10102FC8C606191062A00CC071B006881884E2800100
+8C63:0000FDDC1088208860889488388853DE98883488548890881088110851082208
+8C64:0000FDF81108210861F89508390851F899443548553091201110114851862100
+8C65:0020FE10081011FE30204A249C4428F84C129A222A4449888810082828441182
+8C66:010001F801003FFE210221F02F0420FC20002FF823002C9023605CD843469CC0
+8C67:0028FC2413FE2020602095FC3924512499FC3524552491FC112411245124210C
+8C68:00C2FC34101820646182942039FE5050989035FE56929092109A109450102010
+8C69:0000FDFE1020204060A295123834505898983514543490521090111050502020
+8C6A:01007FFC00001FF010101FF000007FFE40029FF40600192006C039B0068C3980
+8C6B:0080F8F8090853FE25121122FDFE244028A223542098233420542092A3504020
+8C6C:0020FE2008FA102430284BFE9C2028404CFC9B442A44487C88440844287C1044
+8C6D:0000FDDC11442144614495DC3900510099DC3514551491D41108110851142122
+8C6E:0020FDFC1020208863FE9488380051FC99043524552491241124105050882304
+8C6F:000EFEF00822109230444A209C4428F84C109A242AFE481088FE082828441082
+8C70:1000FE7810487C480048FE8682007CFC0044FE44202854282810DC282A44D982
+8C71:0000FCF81088208860F89488388850F8980035FC555491541154115453FE2000
+8C72:0000FDFE11102120617C9544397C5144997C3510551091541152129252502420
+8C73:010041047DF4492451446BAC4D3459646DB44B2C596469A4596441047FFC0004
+8C74:0020FE1008FE104430284AFE9C8228924CFE9A922ABA48AA88AA08BA28821086
+8C75:0124F924222444A4A154154A3B92550899083528512E912811281158514E2180
+8C76:0020FDFC1020208863FE948839FC510499FC350455FC910411FC108851042202
+8C77:0020FBFE202041FCA00017FE3A0251FC980035FC510491FC1104108853FE2000
+8C78:00E007007A0C113008C00780784000A003300C507090011006101810E0A00040
+8C79:0C403040C28014FC49043204C80415042484CC4414442404C404040428281010
+8C7A:0C103010C210141049FE3010C83014302450CC5014902510C410041028501020
+8C7B:0C0030FCC220142048203020C82015FE2420CC2014202420C420042028201020
+8C7C:0C103110C310151249123114C9D815102510CD1015102512C5520592290E1000
+8C7D:0C203020C22015FE49223122C92215222552CD4A158A2502C5020502290A1104
+8C7E:0C0031FEC210141048203020C86814A42522CE2214202420C42004002BFE1000
+8C7F:0C803080C28015FC49043204C9E415242524CD24152425E4C524040428281010
+8C80:0C203020C324152449243124C9FC14202420CD2415242524C524052429FC1004
+8C81:10402020D4200BFE52022404D00018902890C89018882908C908090452042402
+8C82:0C0031FCC244144448443044C89414882500CCFC14842484C484048428FC1084
+8C83:0C203020C24015FC49043104C904150425FCCD0415042504C504050429FC1104
+8C84:0C203020C3FC14244BFE3024C9FC14202420CDFC14202420C7FE042028201020
+8C85:10902090D490091051FE2310D51019382938C95419542992C910091051102110
+8C86:0C0031FEC200140048FC3084C88414FC2484CC8414FC2484C400040029FE1000
+8C87:0C0031F8C308150849F83108C90815F82544CD4815302520C510054829861100
+8C88:0C103020C2FC148448A43094C89415FE2484CCA414942494C484050429141208
+8C89:10802080D4F80908531024A0D04018A02918CA061DF82908C908090851F82108
+8C8A:0C0030FEC2201420484030FCC88414842484CCFC14842484C484048428FC1084
+8C8B:0C0031FCC30415FC490431FCC800140025FCCC20142027FEC420042028201020
+8C8C:0C203040C3FC1504490431FCC904150425FCCC5014502450C4920492290E1200
+8C8D:0C0031FCC324152449FC3124C92415FC2420CC2015FC2420C42004202BFE1000
+8C8E:10002040D79C0A045204239CD2041A042BFCC89018902890C89009125212240E
+8C8F:10402080D5FC0924512421FCD124194429FCC89019102BFEC810081050102010
+8C90:104020A0D5100A0855F62000D3C41A542A54CBD41A542A54CBD40A44525422C8
+8C91:100023DED6420A42524223DED2001A3E2BD2CA121A142BD4CA080A1452242242
+8C92:0C203124C324152449FC3000CBFE14202440CDFC15542554C55405542954110C
+8C93:0C883088C3FE148848883000C9FC15242524CD2415FC2524C524052429FC1104
+8C94:0C203040C3FC150449543124C954150425FCCC00151225D4C51805522992110E
+8C95:101E23E0D522089450402088D1F0182028C4C9FE18222820CBFE085050882306
+8C96:11042084D488080053FE2000D08819042A02C9FC19542954C954095457FE2000
+8C97:102021FCD5240BFE512421FCD02019FC2924C9FC18402BFEC88809D05070238C
+8C98:0C883088C3FE1488480031FCC90415FC2504CDFC142025FEC450048829041202
+8C99:100023FED6000A7C52442244D27C1A002AEECAAA1AAA2AAACAEE0A0053FE2000
+8C9A:100023DED6520A5253DE2000D1FC192429FCC92419FC2820CBFE082050202020
+8C9B:108823FED4880BDE525223DED0A0189029FEC9201BFC2D20C9FC092051FE2100
+8C9C:13DE2252D7DE0A5253DE20A0D1FE1B202DFCC92019FE2800C9FC08885070278E
+8C9D:00003FF8200820083FF8200820083FF8200820083FF800000820101020084004
+8C9E:010001FC010001003FF8200820083FF820083FF8200820083FF8082010102008
+8C9F:0800101020087FFC200400003FF820083FF820083FF820083FF8082010102008
+8CA0:080008001FE020204040BFF820083FF820083FF820083FF80000046018186004
+8CA1:00107C10441044107DFE441044307C30445044507C9001102810241044508020
+8CA2:00003FF801000100FFFE00003FF820083FF820083FF820083FF8082010102008
+8CA3:04200210013EFFC00022001A3FF620103FF020103FF020103FF0084010202010
+8CA4:0020782048204920792C493449647BA449244934792801225122490288FE0000
+8CA5:00407C20440045FC7C00440044F07C90449044907C90009228922512450E8200
+8CA6:00007C0045FC44007C00440047FE7C90449044907C900090289225124512820E
+8CA7:044008203018CFE6042018A060401FF010101FF010101FF010101FF008201010
+8CA8:0880109830E057849084107C00001FF010101FF010101FF010101FF008201010
+8CA9:0008781C49E04900790049FC49447944494449287928011051104A288A440482
+8CAA:010002800C603118CFE6004000801FF010101FF010101FF010101FF008201010
+8CAB:00001FF01110FFFE11101FF000001FF010101FF010101FF010101FF008201010
+8CAC:01003FF801001FF00100FFFE00001FF010101FF010101FF010101FF008201010
+8CAD:0008007C3F80208020803FFE208027F8240827F8240827F8240847F842108408
+8CAE:00203F2800240020FFFE00207FA040A07FA040907F9040907F8A120A21064082
+8CAF:00407C20442045FE7D02460444007C0045FE44207C2000202820242044A08040
+8CB0:12207FFC122013E010001FF800001FF010101FF010101FF010101FF008201010
+8CB1:00107810481049FE79124914491079FC494449447928012851104A288A440482
+8CB2:088028882EF028842E84F07C00001FF010101FF010101FF010101FF008201010
+8CB3:0024FFFE00203FA000207FA000203FA020A03F9020903F90208A3F8A11062082
+8CB4:01001FF011101FF00100FFFE00001FF010101FF010101FF010101FF008201010
+8CB5:040008201FF00210FFFE08203018DFF610101FF010101FF010101FF008201010
+8CB6:00047C1E45E044007C20441045FE7C04440844107C20004028802540463E8000
+8CB7:00007FFC444444447FFC00003FF820083FF820083FF820083FF8082010102008
+8CB8:08901088307ED7C01022101A00061FF010101FF010101FF010101FF008201010
+8CB9:00107C10449044907CFE449045107C10441044FE7C1000102810241045FE8000
+8CBA:00007DFC450445047D04450445FC7C50445044507C50005028922492450E8200
+8CBB:04407FF804483FF824403FFC08441FF4301C5FF010101FF010101FF008201010
+8CBC:00207C20442044207C3E442044207C2045FC45047D0401042904250445FC8104
+8CBD:00207C20442044407C48448445FE7C82440044FC7C8400842884248444FC8084
+8CBE:00047C1E45F045107D10451045107DFE451045107D100108290A254A45A68112
+8CBF:060078FC4044484444445A9461081FF010101FF010101FF010101FF008201010
+8CC0:100010007E7C124422442A7C44009FF010101FF010101FF010101FF008201010
+8CC1:01003FF801000820FFFE082000001FF010101FF010101FF010101FF008201010
+8CC2:0080788048F849087B104CA0484078A049184A067DF801085108490889F80108
+8CC3:081813E0304057FC904013F800001FF010101FF010101FF010101FF008201010
+8CC4:00207C2045FE44407C4044FC44847D8446FC44847C8400FC2884248444948088
+8CC5:00207C10441045FE7C20442444447CF8441244227C4401882810242844448182
+8CC6:00827C42444444007CFE444444447C44444445FE7C4400442884248445048204
+8CC7:410021FC0A441048E0A0211826061FF010101FF010101FF010101FF008201010
+8CC8:00007FFC04403FF824483FF800001FF010101FF010101FF010101FF008201010
+8CC9:00207C20444044807DFC455445547D54455445547D5401542954255447FE8000
+8CCA:00147C12441045FE7C10449044927C9247F244947C940088288A251A45268242
+8CCB:00407C20442045FE7C00448845047E02448844887C5000502820245044888306
+8CCC:0100FFFE08401F90062038D007087FF410101FF010101FF010101FF008201010
+8CCD:00207810481049FE7900491049107910497C49107910011051104A108AFE0400
+8CCE:00287C24443E45E07C20443C45E07C20443E45E07C2200242818246A45868002
+8CCF:00007CFC448444847CFC448444847CFC448444847CFC00002848244444828102
+8CD0:00407840488849047BFE4802488879444A4248F8798802505020485089880606
+8CD1:000079FE49004900797C4900490079FE495049527954014851484A448A520460
+8CD2:00207C20445044887D0446FA44007C0047FE44207D2801242A22242244A08040
+8CD3:01007FFE4002BFFC0910316003803FF8E0083FF820083FF820083FF808201010
+8CD4:01007FFE4002BFFC21083FF820002FF828082FF828082FF828084FF844108808
+8CD5:00287C24442444207DFE442045207CB244B444687CA801242A22242044A08040
+8CD6:00207C20445044887D0446FA44207C2047FE44207D2801242A22242244A08040
+8CD7:0020782049FC4924792449FC482078204BFE4A227A2203FE5222482088200020
+8CD8:00207810481049FE7900491049107910497C49107914011251124A108AFE0400
+8CD9:00007CFE449244927CBA449244FE7C8244BA44AA7CAA00BA28822502450A8204
+8CDA:01007FFC092015502388054009203FF8D0161FF010101FF010101FF008201010
+8CDB:082008207EFC0820FEFE145022885FF690101FF010101FF010101FF008201010
+8CDC:00007CFC448444847CFC448444847CFC444044FE7D2A024A28922522444A8084
+8CDD:00007BFE4A024A5278884904482078204BFE4820787000A851244E2288200020
+8CDE:111009207FFE40029FF410103FF820083FF820083FF820083FF8082010102008
+8CDF:00507C50445045FC7D54455445547DFC455445547D5403FE2800248845048202
+8CE0:00407C2045FC44007D08449044007DFE440044007DFC01042904250445FC8104
+8CE1:00803FFE20802FF820883FFE21082FF824102FF8341627F0441047F082200410
+8CE2:00007EFC48447E4442287E1048287FF610101FF010101FF010101FF008201010
+8CE3:0100FFFE01003FF800007FFC44447FFC10101FF010101FF010101FF008201010
+8CE4:00487C44445E45E07C284412446A7D964448445E7DE0002428282412446A8186
+8CE5:00407C2045FE44007C88448845547E22440044207DFE00202820242044208020
+8CE6:00087C0C44EA440A7C0845FE44487C48454845687D480148294A256A47868102
+8CE7:00207CA244A245247C50448847047C22442044A47CA401282850248845048202
+8CE8:01007FFC40041FF000007FFC1110250842041FF010101FF010101FF008201010
+8CE9:004078204BFE4A02780049FC480078004BFE48207928012452224C2288A00040
+8CEA:060C387020403F7E2448244844889FF010101FF010101FF010101FF008201010
+8CEB:01007FFC0920092015507FFE40029FF410101FF010101FF010101FF008201010
+8CEC:00007CFC448044F87C8044F844807FFE454045247D2801102908254445828100
+8CED:00207C2245FA44247C2847FE44207C4044FC45847E8400FC2884248444FC8084
+8CEE:01003FF80108FFFE01083FF801007FFC24885FF410101FF010101FF008201010
+8CEF:010079FE4A024DF2791249F2491279FA48044BF87810002057FE482088A00040
+8CF0:00207C2047FE44207DFC444047FE7C88450446FA7C88008828F82488448880F8
+8CF1:00007BFE4A2248207BFE482049FC792449FC492479FC002053FE482088200020
+8CF2:13F8120823F86040A7FC215022481FF010101FF010101FF010101FF008201010
+8CF3:012879244BA4492079204FFE482078244BA44AA87AA802905392482A88460082
+8CF4:10201020FE7810881110FEFC928492FCFE8410FC388454FC9200104810841102
+8CF5:00007DFE4502457A7D02457A45027C0044FC44847CFC008428FC248444FC8084
+8CF6:00207C20445044487CA445FE46847CFC448444FC7C8000FC29442544467C8044
+8CF7:01007FFC01003D7825483D7801007FFE50129FF410101FF010101FF008201010
+8CF8:00203D2424A825FC24403FFE248825FC268A3CF8248824F8248844F854508888
+8CF9:01047884488848007BFE4800488879044A0249FC79540154515449548FFE0000
+8CFA:011078A048004BFC78A04BF848A87BFE48A84BF878A001B052A84CA688A000A0
+8CFB:00287C2447FE44207DFC452445FC7D2445FC45247C0803FE2888244844488018
+8CFC:008878884BFE488879FC48884BFE782049FC492479FC012453FE490489140108
+8CFD:01007FFE44429FF404403FF80440FFFE08201FF02828CFE608200FE004400820
+8CFE:00207DFE482048FC48205DFE540054FC54845CFC488448FC48847EFC00480084
+8CFF:00007BDE48424A52794A4A52482878C44B1248607988003251C4481888600380
+8D00:7F7848485F4C64805F784A4851307F4C00001FF010101FF010101FF008201010
+8D01:7E2042207E20423E7E4442447E4424A442287E2842107E1042287E4824844302
+8D02:0040788849FC49087A524BFE485079884E2648C07B1000645388483088C00700
+8D03:0020782049FC492479FC48204BFE7A224BFE48207840002452A24A8A8C780000
+8D04:08207E2008F8FF2814287F6A082AFF5608821FF010101FF010101FF008201010
+8D05:08207F20087E7E4408A4FF2810101E2822445FF290101FF010101FF008201010
+8D06:002878244BFE4850788849044A027998495449107BBE011052A84AA88C440882
+8D07:41D42010FBFE109052C8228A57E680021FF010101FF010101FF010101FF00820
+8D08:0104788848004BFE7A224AAA4A727A224BFE480079FC010451FC490489FC0104
+8D09:00007BFE48504BFE7A524BFE480079FC490449FC790401FC50204BFE88200020
+8D0A:28503E7C4890FEFE1528264A44861FF010101FF010101FF010101FF008201010
+8D0B:3FFE225024882DFE369024FC249024FE200027FC240427FC440447FC82080404
+8D0C:00507A52495448507BFE488848507BFE482049FC782003FE5050488889040602
+8D0D:008078F849084BFE7944499249FE7900497C4900797C0100517C4A448A7C0444
+8D0E:008878884BFE488879FC492449FC792449FC48207BFE0222522A4AFA8A0A0206
+8D0F:0100FFFE20003FF800003FF820083FF8000077DC545477D4545C77D65296B462
+8D10:002079FC48244BFE782449FC48207BFE48004AA47C5201FC515449548FFE0000
+8D11:1000FEFC44202820FEFE00007CFC44847CFC44847CFC1084FEFC104810841102
+8D12:7E2051FC7D2445FC7C24514A7EF800003FF820083FF820083FF820083FF80820
+8D13:000C700A51FE550875E85548574A71EA512A5FEC754C054C55EA4A0A82160422
+8D14:3FF820083FF820083FF820083FF8082010107EFC42847EFC42847EFC24484284
+8D15:2010CEFE8A10AA7CAA00EEFEAAAAAAFEAA44AA7CEE44A87C2844487C48288844
+8D16:00207BFE482049FC78004BFE4A527BFE490449FC790401FC510449FC88880104
+8D17:3FFE224025F82D0835F8250825FE26AA240627F8240827F8440847F882100408
+8D18:012478A84BFE4A0278F8488849FC790449FC490479FC010451FC480088880104
+8D19:0E1C08107EFC4A945CB84A945CB8952A22461FF010101FF010101FF008201010
+8D1A:011078904BDE48107A5E49824BDE78104BDE4A507BDE025053DE4A508A5202CE
+8D1B:1040FE7C44C82830FECE00787C2045FC7C8844F87C8810F8FE8810F810501088
+8D1C:0090709057FE5094700A51FE550877E8514A51EA7F2A05EA554C49EA82160462
+8D1D:00001FF010101010101011101110111011101110121002800440082010102008
+8D1E:0100010001FC010001003FF820082108210821082208220804C008303008C004
+8D1F:040004000FE0102020405FF010101110111011101110121002C0042018106008
+8D20:02000400082010103FF8000800001FF01010111011101110121004C018306008
+8D21:00003FF8010001007FFC000000001FF01010111011101110121004C018306008
+8D22:00107C104410541055FE54105430543054505450549011102810241044508020
+8D23:010001007FFC01003FF80100FFFE00001FF0101011101110111002600C187004
+8D24:040025F824882450242024D8270604001FF0101011101110111002600C187004
+8D25:00407C404440548054FE55085688548854885450545010202850248845048202
+8D26:00807C8444845488549054A0548055FE54A054A054901090288824A444C28080
+8D27:08800880109830E057849084107C00001FF0101011101110111002600C187004
+8D28:007C3FC0204020403FFE2040204027FC240424442444244424B4410846049802
+8D29:00047C0E44F04480548054FC54A454A454A454A854A810902910252842448082
+8D2A:01000280044009203098CFE6004000801FF0101011101110111002600C187004
+8D2B:044008203018DFE60420042008A010403FF0101011101110111002600C187004
+8D2C:00087C3C45C044005420541055FC5404540854105420104028802540423E8000
+8D2D:00807C80448054FC5504550456445444548454A4551411F42814240444288010
+8D2E:00407C204420540055FE5502560454005400540054001000280025FE44008000
+8D2F:1FF011101110FFFE111011101FF000001FF0101011101110111002600C187004
+8D30:00280024FFFE00203FA000207FA000203FA0209024902490248A0A0A11066082
+8D31:00507C484440445C55E05440545E57E054445448543010222852248A43068002
+8D32:01003FF801000820FFFE082000001FF01010111011101110121004C018306008
+8D33:12201220FFFE122013E010001FF800001FF0101011101110111002600C187004
+8D34:00207C2044205420543E54205420542055FC5504550411042904250445FC8104
+8D35:01001FF0111011101FF00100FFFE00001FF0101011101110111002600C187004
+8D36:00007DFC450445045504550455FC5450545054505450109228922512420E8400
+8D37:08901088307ED7C01022101A00061FF01010111011101110121004C018306008
+8D38:060078FC4044484444445A94610800001FF0101011101110111002600C187004
+8D39:04407FF804483FF824403FFC0844105420085FF010101110111002C00C303008
+8D3A:100010007E7C124422442A7C44009FF01010111011101110121004C018306008
+8D3B:00207C20442054405448548455FE5482540054FC548410842884248444FC8084
+8D3C:00147C12441045FE541054905492549257F2549454941088288A251A41268242
+8D3D:10801080FBF010901990F0941154520C24041FF010101110111002C00C303008
+8D3E:00007FFC04403FF8244824483FF800001FF0101011101110111002600C187004
+8D3F:00207C2045FE5440544054FC5484558456FC5484548410FC2884248444948088
+8D40:088008882E9028E028842E84F07C00001FF0101011101110111002600C187004
+8D41:083813C03040504097FC1040104013F800001FF010101110111002C00C303008
+8D42:00407C40447854885550542054505488550654F8548810882888248844F88088
+8D43:00207C10441045FE5500551055105510557C5510551011102910261042FE8400
+8D44:0100410021FC0A441448E0A02110260C1FF0101011101110111002600C187004
+8D45:00207C10441047FE54205442548455F85410542254C413082810242840C48302
+8D46:00007CFC4484548454FC54905490548854845532550812002860241844048000
+8D47:00287C244424542055FE5420552054B254B4546854A811242A22242044A08040
+8D48:00007DFE45004500557C5500550055FE55505552555411482948264442528460
+8D49:010001007FFC11100920FFFE054009203018DFF610101110111002C00C303008
+8D4A:00207C2044505488550456FA5400540057FE5420552811242A22242244A08040
+8D4B:00087C0C44EA440A540855FE544854485548556855481148294A256A43868102
+8D4C:004000407C4445FC4448545057FE544054F85588568854F82888248844F88088
+8D4D:01007FFC0920092015507FFE400280041FF0101011101110111002600C187004
+8D4E:00207C2045FC4420542057FE5402549454505510549013FE2828244440828302
+8D4F:111009203FFC20044FE808200FE000001FF0101011101110111002600C187004
+8D50:00007CFC4484548454FC5484548454FC544054FE552A124A28922522444A8084
+8D51:1FF010101110111002C00C30700800003EF822882AA82AA82AA8145022884104
+8D52:00007DFC452445245574552455FC550455745554555411742904260442148408
+8D53:00803FFE20802FF820883FFE21082FF824102FF8341624904490416082100C08
+8D54:00407C2045FC540055085490540057FE5400540055FC11042904250445FC8104
+8D55:00207CA244A245245450548857045422542054A454A411282850248841048202
+8D56:10801080FEF8110812107DFC5504552455247D24112439245450908811041202
+8D57:00007DFE4502457A5502557A5502540054FC548454FC108428FC248440FC8084
+8D58:08207F20087E7E4408A4FF2810101E28224446829FF01010111002C00C307008
+8D59:00287C2447FE542055FC552455FC552455FC5524540813FE2888244844488018
+8D5A:00887C50440055FE545055FC545457FE545455FC545010D82954265244508050
+8D5B:01007FFE44429FF404403FF80440FFFE08201FF02928C92609200AA004401820
+8D5C:00207DFE482048FC48205DFE540055FC55045D244924492449247E5000880304
+8D5D:3FFE225024FE2D9036FC249024FC249024FE200027FC2444444440B0830C1C02
+8D5E:081028503E7C48907EFE14282548468A81061FF010101110111002C00C303008
+8D5F:41D42010FBFE109052C8228A57E680021FF0101011101110111002600C187004
+8D60:00887C48445055FC552455AC5574552455FC540054F8108828F8248844F88088
+8D61:00807CF8450847FE5544559255FE5500557C5500557C1100297C2644427C8444
+8D62:0100FFFE20003FF800003FF820083FF8000077DC54547554555C75565296B462
+8D63:1040FE7844D02920FE5801867CF844207DFC44007CF81088FEA810A810501188
+8D64:0100010001003FF801000100FFFE044004402448244444428842084011402080
+8D65:0810081008107E10083E0822FF44149014105610551095282428242454448882
+8D66:0820082008207E40087E0884FF44144414445628552895102410242854448882
+8D67:080008FC08847E8408940888FF8014FC14A456A455A894A8249024A854C48882
+8D68:0810081008107EFE08920892FF92149214FE5692551095142412241E54F28800
+8D69:0820082008787E480890087CFF5414541454567C5540954024422442543E8800
+8D6A:08100810081E7E10081008FEFF82149214925692559294922428242454428882
+8D6B:0820082008207EF808200820FEFE1450145056D8555494522450249054908930
+8D6C:08200820083E7E20082008FCFF8414FC148456FC558494FC2400244854848902
+8D6D:0820082408F47E28082808FEFF101420147C56C45544957C24442444547C8844
+8D6E:100011DC11447D44114411DCFF00290029DC6D14AB1429D42908490849149922
+8D6F:1020101011FE7D10117C1114FDFE2914297C6D10AB7C294429444A444A7C9C44
+8D70:0100010001003FF801000100FFFE01000100110011F811001100290047FE8000
+8D71:010001003FF8010001000100FFFE00002010102000C003000C00130020FE4000
+8D72:0820082008207E2008FC0824FF240824282428442E442894290858004FFE8000
+8D73:0804080408447E4408440844FF44084C285428642E042804280458004FFE8000
+8D74:0420042004203F20043004287FA404240420242027A02420242054004FFE8000
+8D75:0800080408847E4408280828FE100810282828282E442884280058004FFE8000
+8D76:080008FC08207E2008200820FE2009FE282028202E202820282058204FFE8000
+8D77:0800080008F87E0808080808FEF80888288028802E842884287C58004FFE8000
+8D78:0810081008107E1008920892FE920892289228922E9228FE280258004FFE8000
+8D79:0820082008407EFE09020842FE220822280A28322EC22802281458084FFE8000
+8D7A:0820082008507E5008880944FE2208F8280828102E102820282058004FFE8000
+8D7B:0810081008107E5408520852FE900812280428082E102860298058004FFE8000
+8D7C:0420042004203F3E044204047F9004100410242827A42442248254004FFE8000
+8D7D:0820082008207EFC08240824FE2409FE282028502E482884290458004FFE8000
+8D7E:0800080C08707E400840087EFF480848284828482E882888290858004FFE8000
+8D7F:1004101E11F07D1011101110FDFE1110111051105D10514A5186710250008FFE
+8D80:0810081008167EF808900890FEFE0812283228522E962910281058104FFE8000
+8D81:0820082008507E5008880924FE420890282028442E882810282058404FFE8000
+8D82:0840084008407EFE08820924FE2008A828A429222E2228A0284058004FFE8000
+8D83:082008A008A07EFC08A00920FE2009FE282028502E482884290458004FFE8000
+8D84:080008F808887E8808F80888FF8808F8288828882E8829FE280058004FFE8000
+8D85:080009FC08447E4408440894FF0808FC288428842E8428FC280058004FFE8000
+8D86:0800081C08F07E90089008FEFE900890289028AA2ECA28A6281258004FFE8000
+8D87:0820081008107EFE08040844FF440828282828282E1028FE280058004FFE8000
+8D88:0820082008207E3E08200820FF2008FC288428842E8428FC288458004FFE8000
+8D89:0810081008927E92089208FEFF100892289228922E9228FE280258004FFE8000
+8D8A:1028102410207DFC11201124FD241128112851105D94512C704450004FFE8000
+8D8B:0840084008787E88091008FCFE04080428FC28042E0429FC280058004FFE8000
+8D8C:0810081008107EFE0810087CFF00087C284428442E44287C284458004FFE8000
+8D8D:10201020107C7C8813501024FCC8131E102250E45C1850105060738050008FFE
+8D8E:0810085008507EFC09100810FEFE0830283828542E942910281058004FFE8000
+8D8F:081C08E008207E2009FE0820FE2008FC288428842E8428FC288458004FFE8000
+8D90:080009DC08447E44095408CCFE4408CC295428442E44285428C858004FFE8000
+8D91:1020122011207D3E10421084FC901090131051105D2851245142708250008FFE
+8D92:0810085008507E50095408D8FE5008D8295428522E922892290E5A004FFE8000
+8D93:100010F810887C8810881088FD26122011FE50205C7050A85124722250208FFE
+8D94:100213F210827C8A108A11EAFD2A112A12AA504A5C4A5082510A720450008FFE
+8D95:0800087C08447E7C0844087CFF00087C281028102EFE2810281058104FFE8000
+8D96:0810081008547E54085408BAFF100810287C28102E1028FE280058004FFE8000
+8D97:080008F808887E88088808F8FE2008A028BC28A02EA029602A3C58004FFE8000
+8D98:080008FE08827EFE0880088CFEF0089C28F0289E2EF02912290E5A004FFE8000
+8D99:0810089208547E1008FE0882FEFE088228FE28822E82288A288458004FFE8000
+8D9A:0820082009FE7E20082009FCFF24092429FC28702EA829242A2258204FFE8000
+8D9B:0820082008507E8809040AFAFE20082029FC28202EA828702BFE58004FFE8000
+8D9C:0880088009FE7E2208AA0872FE2209FE282228722EAA2922282A58044FFE8000
+8D9D:1020102010507C8811441222FDF81008105050205CA4528A528A747850008FFE
+8D9E:0848084808FC7E48084809FEFE0008FC288428FC2E8428FC288458004FFE8000
+8D9F:1020112410A47CA811FC1104FD041174115451545D745104710C50004FFE8000
+8DA0:10201020103E7C2011FC1104FDFC110411FC51245C2053FE5020702050208FFE
+8DA1:0850084808807EFE09900A90FEFC0890289028FC2E90289028FE58804FFE8000
+8DA2:11F8100810F87C0813FE1020FC24112410A850705CA85324502470A050408FFE
+8DA3:100013E0115E7D4211D2114AFD4A11C4114451645DCA534A705250404FFE8000
+8DA4:0820081008FE7E82080008FEFF20084028FC29442E44287C284458004FFE8000
+8DA5:1088105013FE7C50105011FCFD54118C110451FC5D04510451FC710450008FFE
+8DA6:1220113E10427C9413101128FC46100011FC51045D04510451FC710450008FFE
+8DA7:080008FC08847EFC088408FCFE0009FE2810289C2E902890297E5A004FFE8000
+8DA8:108011FC12447D5411F41084FD18108011FC52445D5451F45084711850008FFE
+8DA9:100011FC11247DFC112411FCFC88108811FC50885C8853FE5088710450008FFE
+8DAA:1088108811FC7C88108813FEFC2011FC112451FC5D2451FC5000708851048FFE
+8DAB:103C13C010407BFE10901108FAF4149213FC52045AF4529452F4720C50008FFE
+8DAC:0810087C08107EFE084408EEFE4408EE280028FE2E28282A284658804FFE8000
+8DAD:10A0109011FE7D2013FC1120FDFC1120112051FE5C0052A45252745250008FFE
+8DAE:0800087C08447E7C080008EEFEAA08EE281028FE2E382854289258104FFE8000
+8DAF:080009EE08AA7E6608AA0850FEFE099028FC28902EFC289028FE58804FFE8000
+8DB0:100013FE11247A2217FE1376FAAA1376122253765AAA53765222720650008FFE
+8DB1:1108152817BE794817BE1318FDAA194613F852085A48524850A0711052088FFE
+8DB2:152817BE19487FBE131815AAF94613FC120453FC5A0453FC520473FC51088FFE
+8DB3:00001FF010101010101010101FF001000100110011F811002900250043FE8000
+8DB4:00007C204520452045207D20112011205D205110511052105E08E40808041002
+8DB5:00407C40444044FC44847D04100411045C845044504450045C04E00400280010
+8DB6:00007DFC4420442044207C20102013FE5C205020502050205C20E02000A00040
+8DB7:00407C40448044FE45007E0010FC10085C105020504050805D02E10200FE0000
+8DB8:0000FFFE040007F0081010A0604000001FF010101FF0010011F81100290047FE
+8DB9:00207C20442045FC44247C24102410245DFE5020505050505C88E08801040202
+8DBA:00207C204420442045FC7C20102010205DFE5020505050505C88E08801040202
+8DBB:00207C204450445044887D44122210205C0051FC500450085C08E01000100020
+8DBC:00007DFE4448444844487C48104813FE5C485048504850485C88E08801080208
+8DBD:00407C20442047FE44807C80108010FC5C845084508450845D04E10402280410
+8DBE:00207C204420452045207D20113C11205D205120512051205D20E12007FE0000
+8DBF:00007BFC4884488848887890109C108451445D44512851285A10E22804440182
+8DC0:00007CFC4484448444847CFC108410845C8450FC508450845D04E10402140408
+8DC1:00007DFC4524452445247D24112411FC11045D005100510051025D02E0FE0000
+8DC2:00207C20442045FE44207C20102011FC5C845088504850505C20E05001880606
+8DC3:00087C3C45E0442044207C2013FE10205C205050505050505C88E08801040202
+8DC4:00207C204450445044887D04120210F85C88508850A850905C82E082007E0000
+8DC5:00087C1C45E0450045007D0011FE11105D105130511851145D12E21002100410
+8DC6:00207C204440444044887D0413FE100210005DFC5104510451045D04E1FC0104
+8DC7:00487D484548454845487FFE114811485D485148517851005D00E10001FE0000
+8DC8:00207C204450448845047E121020104011885C105020504451885C10E0600380
+8DC9:00207C204450445044887D24121210105DFC5004500850885C50E02000100010
+8DCA:00207C20442045FC44207C20102013FE5C7050A850A851245D24E22200200020
+8DCB:00507C484448444047FE7C80108010FC5D445144512851285E10E22804440182
+8DCC:00207C204520452045FC7D201220102011FE5C205050505050885C88E1040202
+8DCD:00207C204420442047FE7C201020102011FC5D045104510451045D04E1FC0104
+8DCE:00207C10441045FE45027E04108010885C9050A050C050825C82E082007E0000
+8DCF:010079004900491C4BD479541154115451545D54515451545954E25C03540480
+8DD0:00487C4844484548454A7D6C114811485D4851485148514A5D6AE38A01060000
+8DD1:00807C8045FC450446047DF4111411145D1451F4510451285D12E10200FE0000
+8DD2:00007C0045FE440844087DE81128112811285D2851E8512850085C08E0280010
+8DD3:00407C20440047FE44207C20102010205DFC5020502050205C20E02003FE0000
+8DD4:00807C80450045FC46047C0411E411245D24512451E451245C04E00400280010
+8DD5:00207C2044204420443E7C201020102011FC5D045104510451045D04E1FC0104
+8DD6:00007C0045FE442044207C40104010FC10845D845284508450845C84E0FC0084
+8DD7:0088788848884908497E7B081508114851285D28510851085908E10801280110
+8DD8:00207C20452444A444A87C2011FC10205C20502053FE50205C20E02000200020
+8DD9:00007DF84508450845087DF8110811085D0851F8510851085D08E10807FE0000
+8DDA:00007DDC4554455445547D54115413FE5D545154515451545D54E2D40224044C
+8DDB:00107C10441045FE45127D14111011FC5D445144512851285D10E22802440482
+8DDC:00007DFC4504450445047DFC110011405D445148517051405D42E242023E0400
+8DDD:00007DFE4500450045007DFC110411045D04510451FC51005D00E10001FE0000
+8DDE:00087C1C45E0450045207D20112011FE5C20502050A850A45D22E22200A00040
+8DDF:00007DF84508450845F87D08110811F85D445148513051205D10E14801860100
+8DE0:00207C2047FE442045FC7C2411FC112011FE5C22502A505450505C88E1040202
+8DE1:00407C20442047FE44907C90109012945E925292549250905D10E11002500420
+8DE2:00207C20447C448445487C30102010485D90503E504251A45C18E01000600180
+8DE3:00207920492049FC49207A20102013FE50905C90509050905912E1120212040E
+8DE4:00407C20442045FE44007C881104120210885C885050505050205C50E0880306
+8DE5:00007DFC44444448445E7C82108A11245C2053FE502050705CA8E12402220020
+8DE6:00207D20452045FC45207E20102013FE5C7050A850A851245D24E22200200020
+8DE7:00207C204450448845047E0211FC10205C20502051FC50205C20E02003FE0000
+8DE8:002078204BFE48504888790416FA100053FE5C40508051FC5804E00400280010
+8DE9:00207C2045FC452445247DFC112411245DFC5020502450185C32E0CA03060002
+8DEA:00407C4044FC450446087DFE1100117C5D445144515451485D42E242023E0400
+8DEB:00007DF01110119011521D12E20E44001FF010101FF0010011F81100290047FE
+8DEC:00207C2045FC442044207C2013FE10005C20502051FC50205C20E02003FE0000
+8DED:0080788048FC49084A9078601198162610205DFC5020522053FE5C20E0200020
+8DEE:00007DFE4420444044887D0411FE10225C20502051FE50205C20E02003FE0000
+8DEF:00407C404478448845507C201050108811065CF85088508850885C88E0F80088
+8DF0:01047C844488440045FE7C88108810885C8853FE508850885D08E10802080408
+8DF1:00207C20442045FC44207C2013FE100810085DFE5008508850485C08E0280010
+8DF2:00207C204450448845047E0211FC100010005DFC5104510451045D04E1FC0104
+8DF3:00507C504450455244D47C581050105810D45D525050505050925C92E112020E
+8DF4:00007BFE48504850485079FC115411541D545154515C518451045D04E1FC0104
+8DF5:00507C484440445C45E07C40105E11E05C445048503050225C52E08A03060002
+8DF6:00107A104910491048FE78101310112851245D44514251825900E280047E0000
+8DF7:00807C8044BC47C044507C2410D4130C5C0053FE509050905D12E112020E0400
+8DF8:01107D12451445D845107D121152118E11205C2053FE502050205C20E0200020
+8DF9:00007A0C497049104810781010FE171051105D10511051105910E280047E0000
+8DFA:00007CF84488448844887C88112612205DFE5020507050A85D24E22200200020
+8DFB:00407C2045FE448844507C201050108811065C885088508850885D08E1080208
+8DFC:00007DFC4504450445FC7D00110011FE5D02517A514A514A5E7AE20204140008
+8DFD:00007DF84408440845F87D00110411045CFC5040502050A45E8AE28A04780000
+8DFE:1040104024FE6488A5502420245020881FF410101FF0010011F81100290047FE
+8DFF:00207C2045FC442044207C2013FE10205C205120513C51205EA0E260043E0800
+8E00:00007DFC4504450445047DFC102010205D20513C512051205EA0E260043E0800
+8E01:00007DFE4400449245247E481124109210005DFE5020502050205C20E3FE0000
+8E02:00007BFE49204928492879E81128112851285DE85128512A593AE3EA00260020
+8E03:00207D2444A444A844207DFC110411045DFC5104510451FC5D04E10401140108
+8E04:00107C104490449E44907C9013FE10005C105092509251145E08E01000600380
+8E05:080C08F07E8008800EFE78880888290812081FF010101FF0010011F83100CFFE
+8E06:00407C404488450447FE7C021088114412425CF85188525050205C50E1880606
+8E07:00807C8044FE450046FC7C8410A410945DFE5084512451145DFEE00400280010
+8E08:00207C2047FE442044207DFC112411245DFC5020507050A85D24E22200200020
+8E09:00407C2045FC450445047DFC1104110411FC5D205122511451085D44E1820100
+8E0A:00007DF8440844D044207DFC112411245DFC5124512451FC5D24E1240124010C
+8E0B:0100F100911E93929112F112211227D2A112B912A21AA294A7D0B250C0100010
+8E0C:00207C2047FE442045FC7C4013FE10485C8850FE510851485E28E40800280010
+8E0D:00207C2245FA442444247DFE1010102011FC5C88511052FE54105C10E0500020
+8E0E:00007DFE4410442044687CA41122102010005CFC5084508450845C84E0FC0084
+8E0F:002078224BB448A848A8792412A2104051FC5D04510451FC5904E10401FC0104
+8E10:00487C44445E45E044287C12106A119610485C5E51E0502450285C12E06A0186
+8E11:00887C8847FE448844887CF8108810885CF85088508853FE5C00E08801040202
+8E12:001C7DE04420442047FE7CA8112412425C4053FE508851085CD0E03000480184
+8E13:00A07C90449045FE45207D2013FC112011205DFC5120512051205DFEE1000100
+8E14:00207C20443E442045FC7D0411FC11045DFC5124502053FE5C20E02000200020
+8E15:00207C2047FE442045FC7C2413FE10245DFC50205120513E5D20E2A0027E0400
+8E16:00487C48444845FE44487C4811FE100010FC5C84508450FC50845C84E0FC0084
+8E17:00207C204450448845447E2211F810085C50502050A452825E8AE28A04780000
+8E18:01007D0045FC460444447D5410E4104413FC5C4450E4515452445C44E0140008
+8E19:00007BE0495C495449D47954115411D451545D54516853C85848E05400540062
+8E1A:00207C204450448845047EFA100011FC11545D5451FC515451545D54E104010C
+8E1B:00207C2045FC442044207DFE108811045E22502051FC50205C20E02003FE0000
+8E1C:0020782049FC482048207BFE1088114412425CF85188525050205C50E1880606
+8E1D:00007DFC4524452445FC7D24112411FC10205DFE507050A851245E22E0200020
+8E1E:00007DFE4502450245FE7D10111011FE5D105110517E51425D42E242027E0442
+8E1F:0100790049004BDE4A927C921092109253F25C9250925152595EE22004200800
+8E20:004078204BFE4A024D04790011DE12521E525352549A509451105D12E212040E
+8E21:00207D2444A8442045FC7C4013FE10885D0452FA548850885CA8E0920082007E
+8E22:00007CFC4484448444FC7C84108410FC5C4050FE512A524A5C92E122004A0084
+8E23:00407C2045FC440045087C90100013FE10005C0051FC510451045D04E1FC0104
+8E24:00407C2045FE440044887C881154122210005C2053FE502050205C20E0200020
+8E25:00407C2045FC440044887C5013FE10405C4053FE508851885C50E03000C80304
+8E26:00207C2045FC445044887D0413FE10085DE85128512851E85D28E00800280010
+8E27:00807C80449C44F444947C9413F4101410945C9451C852A850885C94E09401A2
+8E28:008878884888488849547A221442102050205D20513C51205AA0E260043E0800
+8E29:00087C3C45C0444445247CA8108010205DFE507050A850A85D24E22204200020
+8E2A:004078204BFE4A024C0479F81000100053FE5C20512851245A22E42200A00040
+8E2B:01087C90440045FC44907C901092129211945D985090509050905C90E3FE0000
+8E2C:001C7DE04510451045FE7D101110117C5D445154515451545D54E22802440482
+8E2D:00807C8044F8450846107DFC102410245DFE5024502451FC5C24E02000A00040
+8E2E:00207C1045FE450045207D20113C11205D20517C514451445D44E244027C0444
+8E2F:0440F25E9292901297D4F11421182114A7F2B912A112A11ABA94E25004500810
+8E30:00207C504488450446FA7C0011E2112A5D2A51EA512A512A5DEAE122012A0164
+8E31:00407C2045FE454845487DFE114811785D0051FC514451485D28E210022804C6
+8E32:00087C1C45F0451045107DFE1110117C5D44517C5144517C5D44E244027C0444
+8E33:00207C2047FE442045FC7C4013FE10885D0452FA508850885CF8E088008800F8
+8E34:00007DFC4448443045FC7D2411FC11245DFC5124504051FC5C44E08401140208
+8E35:00087C3C45E0442047FE7C2011FC11245DFC512451FC50205DFCE02003FE0000
+8E36:00007DFC4504450445FC7D04110411FC5C0053FE502051205D3CE12002A0047E
+8E37:00207C2245FA442444287FFE1020104010FC5D84528450FC50845C84E0FC0084
+8E38:00887C8847FE448844F87C8810F810885C8853FE510051485D84E10001FE0000
+8E39:00207D244524452445FC7C0013FE10205C4051FC515451545D54E1540154010C
+8E3A:001078104F7C491449FE7A14127C1710517C5D1055FE52105A10E50008FE0000
+8E3B:00007CFC4484448444F47C94109411FE5D02517A514A514A5D7AE102010A0104
+8E3C:00007CFC448444FC44847CFC100011FE5C8050FE512A524A5C92E12200540088
+8E3D:00047C1E47E0442045FC7D24112411FC5C2053FE5222522A5EFAE202020A0204
+8E3E:00007DFE440044FC44847C8410FC100011FE5D22512251FE51225D22E1FE0102
+8E3F:000878C84B084908492A792A13AC11481D0853885554511451145D24E1240142
+8E40:00487D48454847FE45487D48117811005DFE502053FE50705CA8E12406220020
+8E41:00407C2045FE450245027DFE110011005DFE51AA51AA52FE5EAAE2AA04A20086
+8E42:00007DFC4448443047FE7C52109411105E30502053FE50705CA8E12406220020
+8E43:00887C8847FE448844A87C2013FE104010805CFC5184528450845C84E0FC0084
+8E44:00407C2045FC440044887C5013FE12225C2451FC512451245D34E12800200020
+8E45:00207C2047FE447044A87D24122211FC5D0451FC510451FC5D04E00003FE0000
+8E46:00007A7C49444944487C78441744117C11505D4A5144515451625D42E280047E
+8E47:01007FFE44429FF404403FF80440FFFE08201FF02828CFE6010009F0150023FC
+8E48:001E7DE04422451244947C80102011CE11025D0251CE510251025D02E1FE0102
+8E49:00847C44444845FE44207CFC102011FE5C40508050FE51105E10E41001FE0000
+8E4A:001E7BE0492248944840788811F0102050C45DFE502250205BFEE05000880306
+8E4B:00007DFC450445FC45047DFC1000100013DE5C425252514A52525C42E14A0084
+8E4C:00207C204450444844A47DFE128410FC5C8450FC508050FC5D44E144027C0044
+8E4D:00007BFC4A044A044BFC7A48124812FC12485E4853FE52A452A85C90E4C80886
+8E4E:00207C2047FE442045FC7D0411FC110411FC5D0451FC510453FE5C88E1040202
+8E4F:0004781E4BF04A1E4A107AFE1292129852F25E8E528052B85AA8E4AA054A0A86
+8E50:00207D2444A8455444887D0412FA148810885CF85088508850F85C88E0880098
+8E51:00007DFE448444FC44847CFC108613FC5C0453DE505251525C94E14802540422
+8E52:00487C4845FE444844007DFE104810485DFE514A514A51B65D22E102010A0104
+8E53:00407DBC4514459445547DA4114C100011FC5D24512451FC51245D24E1FC0104
+8E54:08047F7808403E402A7E3E482A48FF4808881FF010101FF0010011F83100CFFE
+8E55:00007DFC452445FC45247DFC10A810A85DFE50A850A851FC5C20E3FE00200020
+8E56:00207C2047FE442045FC7C4013FE10885D045242559C51045DDCE10401FC0104
+8E57:004078204BFE4A504A507BFE1252125253FE5E00529252D45A98E49204D2088E
+8E58:00007BDE48424A52494A7A52102810C453125C605188503259C4E01800600380
+8E59:00243FFE222023A422243FA82B10529A46269FF210101FF0010011F83100CFFE
+8E5A:0020792448A84BFE4A0278F8108810881CF85020502051FC50205C20E3FE0000
+8E5B:02A8F2A897FC92A892AAF4E6280027FCA444B840A3F8A248A248B248C2580040
+8E5C:002078104BFE4A02488078FE111013201D7C51445144517C51445D44E17C0144
+8E5D:010879084A284CAE48A87928137E15001D085128512E512851585D48E1860100
+8E5E:000078FE48104A204A7C7A4413C4127C52445E7C52C453445A7CE02800440082
+8E5F:00207BFE482049FC48207BFE100011FC1D0451FC510451FC51045DFCE0880104
+8E60:004078204BFE4A004A487A4813FE124852485E48527852005D54E52A0A2A1000
+8E61:00487D48455E456A45547DC81050106413C45D7E5144516451545D44E2540448
+8E62:004078204BFE488848507BFE122212FA52225EFA528A528A5AFAE202020A0204
+8E63:00887C8847FE448844887CF8102013FE5E22533252AA53765E22E222022A0224
+8E64:012479244A244CA44954794A1392150811085D28512E512851285D58E14E0180
+8E65:00107C1046FE4510457C7C54107C13545D7C511051FE51105D10E290047E0000
+8E66:00207A224A224BFE48007BDE1252125253DE5E52525253DE5A52E252055A08A4
+8E67:009078904FFE48904BFC7A9413FC129453FC5C0051F8510859F8E10801F80108
+8E68:0110791449D24A504A7E7D50109012A851285D44524454825808E2A402520452
+8E69:49202A3E7F4849485DA86B10492841461FF010101FF0010011F81100290047FE
+8E6A:002079FC492449FC48207BFE100011FC11045DFC510451FC51045DFCE0880104
+8E6B:000079FC484848304BFE7852109413501C2053FE5252528A53765E52E2720206
+8E6C:00107BD248544948488A790412FA140051FC5D04510451FC5904E08807FE0000
+8E6D:0104788848004BFE4A227AAA1272122253FE5C0051FC510459FCE10401FC0104
+8E6E:00007DFC445045FC45547DFC102013FE5C48508451FA52885CF8E0840084007C
+8E6F:003C7DE0452444A845FE7CA8112412025DFC5124512451FC5D24E12401FC0104
+8E70:00007BFE4A004A044BF47A0412EE12A452A45EEC520452A45A44E27405940008
+8E71:00207DFC4488445047FE7C0011FC11245DFC512451FC50205DFCE02003FE0000
+8E72:008878504BFE485049FC7954118C117451045DFC500853FE5908E08800A80010
+8E73:00247BA848924D144A087C0413BA10A81CC65380523C538450A85C90E2A80144
+8E74:0214F1129FD29010907EF79024902490A790B928A5A8A568A928B14AC54A0286
+8E75:08287F2400FE3E2022503E504952988E00001FF010101FF0010011F83100CFFE
+8E76:0000F7FE940096289548F7EE24922484A6A0BEA8A7E8A488BC94E51409241242
+8E77:3FFE289025103FDE22222A882F88229424222BF8220823F82040427C454088FE
+8E78:0020792448A84BFE48A879241222110411045DDE52445554509E5D04E2040404
+8E79:00207C504488457446027CF8108810F810005DDC5044515450CC5D54E04400CC
+8E7A:0020782049FC48204BFE7908139C11081D88563E500053FE50905C90E112020E
+8E7B:00187DE0444047FE44887D741252107010005DFC5104517451545D74E104010C
+8E7C:00507A52495448504BFE7888105013FE50205DFC502053FE5850E08801040602
+8E7D:00207C2045FC442045547C88110412FA10885CF8508850F850205CA8E1240060
+8E7E:010878884BC848104BDE7A6413D4101413D45C54509450E853885C94E2940122
+8E7F:004078204BFE4A8A49247A2211FC112451FC5C2053FE52225BFEE22200200020
+8E80:00007DFC452447FE45247DFC100011FC5D0451FC510451FC5D04E1FC00880104
+8E81:00F87C88448844F844007DDC115411545DDC502053FE50705CA8E12402220020
+8E82:00107A10497C481048FE7844132811FE11105D7C511051FE51105D10E2FE0400
+8E83:001078084BC84A7E4A407A5413C8127E52085FC8537E55485D48E5C809480008
+8E84:3E1022FE3E4420287EFEA2103EFC221000001FF010101FF0010011F83100CFFE
+8E85:00007DFC4554455445FC7C8011FC124411F45D54515451F450445DF4E0140008
+8E86:0040787C48404BFE4A427A7813C4123C1E0053FE524053A452585DB4E45209B0
+8E87:008878884BFE48A8482279FA1024102853FE5C4050FC51845AFCE48400FC0084
+8E88:008879084BC84A504BDE7A6413D4111450945FF4511451C85948E254035404A2
+8E89:0820FFFE08201FF011101FF011107FFC41245FFC10101FF0010011F83100CFFE
+8E8A:00207BFE482049FC48007BFE100211FC1C2053FE500053FE50045FBEE2A4038C
+8E8B:0080F04097FC911090A4FF5825542552AB58B800A208A3F8BA08E3F802080408
+8E8C:008079004BFE4D5449547BFE1154115413FE5D0451DE524451545C9EE1040204
+8E8D:00007BDE48424A52494A7A521090110813FE5D1051FE511051FE5D10E1FE0100
+8E8E:0000F7FC924894449FFEF44426EC2554A6ECBC44A6ECA554A6ECB444C4540408
+8E8F:00487DFE4448450044BE7C821152117E11D25D7E5152517E51525D7EE1420106
+8E90:01247A48492448004BFC7A941264129413FC5E4853685248536A5E4AE2460362
+8E91:0440F28E9FEA928A9FEAFAAA2C6C2BAAA82ABFEAA10AAFEAA28CB448C8280008
+8E92:012479744A584ADA4BFE795412DA13FE10A25C2053FE507050A85D24E2220020
+8E93:00427B9C4A104BDE4A947A94142013FC52045FFC520453FC5A04E3FC01080204
+8E94:0020F7FE940095FC9524F5FC252425FCA420BDFCA420A7FEBD24EAFA082013FE
+8E95:004078204BFE4A444BF47A4412EE120452F45EAC52E452145AA4E47405940808
+8E96:01107A124BAA493A4A927BBA108A13FE1D12521253AA513A52925FBAE08A03FE
+8E97:22004F9C94802FDE6108AFC8250827D801001FF010101FF0010011F83100CFFE
+8E98:011078904BDE48104A5E798213DE101013DE5E5053DE525053DE5E50E25202CE
+8E99:03DE7A524BDE4A524BDE7A22129212FA1FA252FA52A252FA52A25EFAE2820206
+8E9A:0000F0FE942892FE92AAF0FE201021FEA644BAFEA344A27CBA42E23E050008FE
+8E9B:22004F9C94802FDE6208AFC82A482AD800001FF010101FF0010011F83100CFFE
+8E9C:0108F52897BE994897BEF31825AA2946A000BBF8A208A248BA48E0B001080604
+8E9D:03DE7A524BDE4A524BDE7A2212FA122252FA5EAA52FA52AA5AFAE27202AA0226
+8E9E:0248F2E8930896EA9A1CF2E8220822E8A5B4B8E2A000A3F8B910E0E003180C06
+8E9F:00207BFE480049DC495479DC108813FE1C8853FE508853FE50945D88E2A400C2
+8EA0:0820FFFE28207DFC44887DFE40207DFC44207FF010101FF0010011F83100CFFE
+8EA1:03FCF10891F8910891F8F10E27F82008A7FEBA94A39CA294A39CB2D6C7BC0084
+8EA2:079EF492979E949297FEF51225F22512A5F2BC02A7BAA6AAA59AB6AAC59A0406
+8EA3:03DE7A524BDE4A524BDE7A5213DE109011FE5D1053FE551051FE5D10E1FE0100
+8EA4:0108F7FE910890009114F7BE21142794B17EAF80A13EA3A2B57EC922013E0122
+8EA5:0040F7FE949291089080F31C2204239CA204BBFCA248A368A248B36AC2460362
+8EA6:0528F7BE994897BE9318F5AA294623FCA204BBFCA204A3FCBA04E3FC01080204
+8EA7:03DE78004BDE4A524B5A7A52102013FE1E5053FE525253FE52925EDCE29204CE
+8EA8:0110F7FE904092EE92AAFBEA2AAE2AE8ABAABCE6A288A5F4A290B060C1980606
+8EA9:03DE7A524BDE4A524BDE78A011FE132015FC5D2051FE500051FC5C88E070078E
+8EAA:00887BFE48884BDE4A527BDE125213DE124A5EFE539252FE52925EFEE2820206
+8EAB:020004001FF010101FF010101FF2101410187FF00050009003101C10E0500020
+8EAC:080010FC3E0422043E04227C3E4022402280FEFC06040A04120422044A280410
+8EAD:102020207C2045FE7D2246247C2044204450FC500C5014502490449295120A0E
+8EAE:101020507C5044507C8844887D0446FA4448FC480C4814482488448895280A10
+8EAF:100021FE7D0045047D4445287D2845104510FD280D2815442584450095FE0800
+8EB0:102020207C2044207DFE44707CA844A84524FD240E2214F82420442094200820
+8EB1:100021FC7C4444487C5E44827C8A45244420FDFE0C20147024A8452496220820
+8EB2:100020F87C8844887C8844887D26462045FEFC200C7014A82524462294200820
+8EB3:0800107C3E4422443E4422443E7C22002200FEFE06820A82128222824AFE0482
+8EB4:082010103EFC22843E8422FC3E84228422FCFEA206A40A98129022884AC40482
+8EB5:100021FC7C2444A47CA445247C54444844A0FC100C5415422542454A96380800
+8EB6:100021FC7D2445247DFC45247D2445FC4420FDFE0C7014A82524462294200820
+8EB7:101C21E07C2044207FFE44A87D2446424440FFFE0C88150824D0443094480984
+8EB8:102020207DFC44507C8845047FFE440845E8FD280D2815E82528440894280810
+8EB9:108020807CFE45027E2244AA7C72442245FEFC220C7214AA25224422940A0804
+8EBA:102021247CA444A87C2045FC7D0445044574FD540D5415542574450495140908
+8EBB:104020207DFE45027E0444507C8845044400FDFC0C2014202420442097FE0800
+8EBC:100020FC7C8044F87C8044F87C8047FE4540FD240D2815102508454495820900
+8EBD:100023FE7A004AFC7A844AFC7A844AFC4A20FBFE1A482AC84A308A482A8413FE
+8EBE:108420487DFE44207C2044FC7C20442045FEFC000C2015FE2420445094880B06
+8EBF:1020201079FE4910797C491479FE4914497CF9101992295449388A542A921430
+8EC0:100023FE7A004A7C7A444A447A7C4A004AEEFAAA1AAA2AAA4AEE8A002BFE1000
+8EC1:102021FC7D2447FE7D2445FC7C2045FC4524FDFC0C4017FE248845D094700B8C
+8EC2:1048216A7CDC44487CB445227DFE45024420FC200CFC14242444444494940908
+8EC3:100021DC7D5445547DDC44007DFC452445FCFD240DFC142027FE442094200820
+8EC4:111020947BD248127A5049907FFE48104BD2FA521A542BD44A4A8A4A2BD61022
+8EC5:100023FE7A004A587A544ABE7BA84AE84ABEFAA81AA82ABE4AA88AA82ABE14A0
+8EC6:105021FC7D5445FC7D5445FC7C0045FC4400FDFC0D0415FC2488445097FE0800
+8EC7:102023FE782049FC78004BFE780249FC4820FBFE18002BFE48048BBE2AA4138C
+8EC8:104020207BFE4A547A7E4AA87BBC4AA84ABCFAA81ABE2AA04A548B422D4A1238
+8EC9:102023FE7A1249DC78A849DC78AA4BFE4800F9FC190429FC490489FC28881104
+8ECA:010001007FFC01003FF8210821083FF8210821083FF80100FFFE010001000100
+8ECB:08200820FFA008207F20492049207F20492049207F200822FFA20822081E0800
+8ECC:108010801080FC8013F07C9054907C9054907C901090FE9211121112120E1400
+8ECD:00007FFE410281043FF801001FF011101FF011101FF00100FFFE010001000100
+8ECE:01007FFC01003FF821083FF821083FF80100FFFE01003FF8200820083FF82008
+8ECF:1000100013FCFC9010907C9054907C9054907C901090FE9211121112120E1400
+8ED0:100011F01090FE9010907C9054907DF054907C901090FE92108A108A10861082
+8ED1:102010201020FE2010207DFE54207C2054207C501050FE501088108811041202
+8ED2:0800087C0810FF1008107F1049107F7E49107F100810FF100810081008100810
+8ED3:1000100010F0FE9010907C9054907CD054B07C901090FE9210921112110E1200
+8ED4:1000100011FCFE2410247CA454A47CA455247C241024FE441044108411141208
+8ED5:102010201020FC2011247D2455247D2455247D241124FF24112411FC10041000
+8ED6:1000100011FCFE2010207C2054207C2055FC7C201020FE201020102013FE1000
+8ED7:100010F81088FE8810887D0656007DFC54847C841048FE501020105010881306
+8ED8:102010201020FDFE10207D2455247D2455247DFC1024FE2010221022101E1000
+8ED9:102010201020FE3E10207C2054207DFC54847C881048FE501020105011881606
+8EDA:102010201020FE2010207DFE54207C2054207C501050FE50108810C811241202
+8EDB:100011FE1100FD0011787D4855487D4855487D681150FD4211421142123E1400
+8EDC:102010201020FDFE11227D2255227D2255527D4A118AFF0211021102110A1104
+8EDD:1004101E10F0FE9010907C9054907CFE54907C901090FE88108A10AA10C61082
+8EDE:1008101C10E0FE2010207C3C54E07C2054207C3E11E0FE20102410241024101C
+8EDF:104010401040FE7C10847C8855207C2054207C501050FE501088108811041202
+8EE0:1008103C11E0FE2010207C2054207DFE54207C201020FE201020102011FC1000
+8EE1:102010201050FE5010887D4456227C2054007DFC1004FE081008101010101020
+8EE2:1000100010FCFE0010007C0055FE7C2054207C401040FE88108411FE10821000
+8EE3:01007FFC01003FF821083FF821083FF80100FFFE0100600C183006C01830600C
+8EE4:1008103C13E0FC2011247CA454A87C2057FE7C201020FE201020102010A01040
+8EE5:104010401040FEFC10847D0454F47C9454947C941094FEF41094100410281010
+8EE6:100011FC1104FD0411047D0455FC7C5054507C501050FE9210921112120E1400
+8EE7:1004101E10F0FE9010907C9054907CFE54907C901090FE88108A10AA10D6108A
+8EE8:102010201050FE5010887D2456127C1055FC7C041008FE881050102010101010
+8EE9:102010201020FE4010487C8455FE7C8254007CFC1084FE841084108410FC1084
+8EEA:201020902090F910217EFA52AB92F892A912F9122252FBD220622022204A2084
+8EEB:102010201050FE8811047E1254207C4055887C101020FE441188101010601380
+8EEC:040008201FF00210FFFE09203FF8C1061FF011101FF011101FF00100FFFE0100
+8EED:100010FE1080FE8010FE7C9054907CBC54907C901090FEFE1080108010FE1000
+8EEE:102010201020FDFC11247D2455247D2455247FFE1020FE501050108811041202
+8EEF:100011FC1020FC2011247CA454A87C2057FE7C201020FE201020102010201020
+8EF0:04447C5804621C42E43E01007FFC01001FF011101FF011101FF00100FFFE0100
+8EF1:1008101C11F0FD5011507D5055507D5055507D481148FD681154127412521400
+8EF2:102010201020FE2011FE7C2054207C2054FC7C841084FE841084108410FC1084
+8EF3:1040104010FCFE8411047EF454947C9454F47C841094FE8810821082107E1000
+8EF4:104010201000FDFE10207C2054207C2055FC7C201020FE201020102013FE1000
+8EF5:104410441044FE8410BE7D8456847CA454947C941084FE841084108410941088
+8EF6:1040102011FCFD0411047DFC55007D00557C7D081110FD2011421282127E1400
+8EF7:105010481048FC4013FE7C8054807CFC55447D441128FD281210122814441182
+8EF8:102010201020FE2011FC7D2455247D2455247DFC1124FF241124112411FC1104
+8EF9:1000100011FCFF0411047D0455047D0455FC7D041000FE901088110412021402
+8EFA:100011FC1044FE4410447C4454947C8855007CFC1084FE841084108410FC1084
+8EFB:1000100013FEFC0810087DE855287D2855287D2811E8FD281008100810281010
+8EFC:102010201120FD2011FC7D2056207C2055FE7C201050FE501088108811041202
+8EFD:100011FC1084FE8810507C2054507C8857267C2011FCFE201020102013FE1000
+8EFE:101010141012FC1013FE7C1054107DD054907C901090FC8810EA138A10061002
+8EFF:108410481000FEFC10487C4854487C4855FE7C481048FE481048108810881108
+8F00:100013FE1020FE2010407DFC55547D5455547D541154FF541154114411141108
+8F01:104810481048FE4811FE7C4854487C4854487DFE1000FE481044108410821102
+8F02:08207FFC0820FFFE101021085FF481021FF011101FF011101FF00100FFFE0100
+8F03:104010201020FDFE10007C8855047E0254887C881050FE501020105010881306
+8F04:102010201124FEA410A87C2057FE7C9054907C901090FE9211121112120E1400
+8F05:104010401078FE8811507C2054507C8855067CF81088FE881088108810F81088
+8F06:102010101010FDFE10207C2454447CF854127C221044FD881010102810441182
+8F07:102010201050FE8811047E0255FC7C2054207C2011FCFE201020102013FE1000
+8F08:1010102010FCFE8410A47C9454947DFE54847CA41094FE941084110411141208
+8F09:08207F280824FFFE0820FFA008247F2449247F2849287F100812FFAA08460882
+8F0A:100011FE1020FE4010887D0455FE7C2254207C2011FEFE201020102013FE1000
+8F0B:010041047FFC0200FFFE09203FF8C1061FF011101FF011101FF00100FFFE0100
+8F0C:200023FE2020F8202020FBFEAA22FA22AAAAFAAA22AAFAFA22022202220A2204
+8F0D:100010501048FE8411247C2054507C8855067EF81088FE881088108810F81088
+8F0E:101010921052FE5410107CFE54827C8254FE7C821082FEFE10821082108A1084
+8F0F:100013FE1050FC5011FC7D5455547D54558C7D041104FDFC1104110411FC1104
+8F10:1020101011FEFD0212047CF854007C0055FE7C501050FE5010921092110E1200
+8F11:100010FC1024FE2411FE7C2454247CFC54407C4010FCFEC411441044107C1044
+8F12:100013FE1120FD2811287DE855287D2855287DE81128FD2A113A13EA10261020
+8F13:1080108010F8FD0812107DFC55247D2455247DFC1050FE50109010921112120E
+8F14:1028102413FEFC2010207DFC55247D2455FC7D241124FDFC112411241124110C
+8F15:100011FE1000FE9211247E4855247C9254007DFE1020FE201020102013FE1000
+8F16:100010FE1092FE9210BA7C9254FE7C8254BA7CAA10AAFEBA10821102110A1204
+8F17:10001040119CFF0411047DDC55047D0455FC7C501050FE50109010921112120E
+8F18:1020102010FCFC2010207DFE54487C8455227C781088FD48105010201050118C
+8F19:100013E0115CFD5411547DD455547D5455D47D541148FD6813C8105410541062
+8F1A:10481044105EFDE010287C12546A7D9654487C5E11E0FE2410281012106A1186
+8F1B:200023FE2020F82023FEFA22AA22FB32AAAAFAAA2376FA6622222222222A2204
+8F1C:109210921124FE4811247C9254927C0055FE7D221122FDFE1122112211FE1102
+8F1D:100013FE922254205BFE1020FDFC292429FC292429FC28202BFE4C2048208020
+8F1E:200023FE2202FA8A2252FBFEAA42FA22ABFEFA822282FA8222FA2202220A2204
+8F1F:200023DE2042F94A2084F94AAA52FC20A800FBDE2052F9522094214822542422
+8F20:100011FC1124FD2411FC7D2455247DFC54207DFE1070FEA81124122210201020
+8F21:10401040107CFC8411087E0054207DCE55027D0211CEFD021102110211FE1102
+8F22:1020102011FCFC5010887D0457FE7C0855E87D281128FDE81128100810281010
+8F23:100011DC1154FD5411547DDC55547D5455547DDC1154FD54115412D41224144C
+8F24:1020102011FEFE2010FC7C2055FE7C0054FC7C8410FCFE8410FC108410941088
+8F25:100011FC1104FD0411FC7D0455047DFC54007D1211D4FD18111011521192110E
+8F26:08203EF808207EFC145023885FF401001FF011101FF011101FF00100FFFE0100
+8F27:104410441088FDDC10887C8854887C8855DE7C881088FE881088108810881108
+8F28:1020101011FEFD0210007CF854887C8854F87C801080FEFC1084108410FC1084
+8F29:04407C7C04403C7804407C7C05403FF801001FF011101FF01110FFFE01000100
+8F2A:102010201050FE8811047EFA54007DFC55547D5411FCFF54115411541104110C
+8F2B:104810481048FDCE10487C4854487DCE54487C481048FDCE1048104810481048
+8F2C:1040102013FEFC0010007DFC55047D0455047DFC1020FEA81124122210A01040
+8F2D:100013FE1020FC4011FC7D5455547D5455547D2C1020FDFE1050108811041202
+8F2E:100010FC1048FE3011FE7C5254947D1056307C2011FEFE7010A8112412221020
+8F2F:100010F81088FE8810F87C0055FE7C8854F87C8810F8FE88109E13E810081008
+8F30:100010FC1084FEFC10847CFC54007DFE54807CFE112AFE4A1092112210541088
+8F31:2008200C200AFBFE2208FA08AAE8FA0AAA0AFAEC22ACFAA822EA221A22262442
+8F32:102011241124FD2411FC7C0057FE7C2054407DFC1154FF54115411541154110C
+8F33:1020102013FEFC2011FC7C4057FE7C8855047EFA1020FDFC1020105010881304
+8F34:1008101C11F0FD1011107DFE55107D7C55447D7C1144FD7C11441244127C1444
+8F35:100010FC1084FEFC10847CFC54407CFE55127C9210AAFE8210FA100210141008
+8F36:108810481050FDFE10507C5055FC7D5455547D8C1104FDFC1104110411FC1104
+8F37:1080108010FEFD0212427DFA54027DF254027DF21002FDF2111211F210141008
+8F38:204020A02110FA0825F6F800ABC4FA54AA54FBD42254FA5423D42244225422C8
+8F39:1040104010FEFE8011FC7E8454FC7C8454FC7C40107CFEC41128101010681186
+8F3A:1052105210A4FDFE10A47C5254527C0054FE7C921092FEFE1092109210FE1082
+8F3B:100010FE1000FE7C10447C44547C7C0054FE7C921092FEFE1092109210FE1082
+8F3C:100010F81088FE8810F87C8854887CF854007DFC1154FF541154115413FE1000
+8F3D:104010481084FDFE10207FFE54887D0457FE7D241124FDFC1124112411FC1104
+8F3E:200023FC2204FA0423FCFA48AA48FAFCAA48FA4823FEFAA422A8249024C82886
+8F3F:010017C0611C47C4454477DC454447C4711C47C44104FFFE0000101020084004
+8F40:100010F810A8FEA810D87C8854F87C0054007DFC1154FF541154115413FE1000
+8F41:101E11E01022FD1210947C8054207DCE55027D0211CEFF021102110211FE1102
+8F42:0800FFB808287F280028FFC688807F7C08247F2449287F284910FFA808440882
+8F43:1020102013FEFC2011FC7C4057FE7C8855347EE21020FDFC107010AC13221020
+8F44:2040202023FEFA022424F9FCA820F9FCA820FBFE2020F9FC2104210421FC2104
+8F45:1020102011FCFC2013FE7C0055FC7D0455047DFC1052FC94118816A410C21080
+8F46:2040202023FEFA502250FBFEAA52FA52ABFEFA002292FAD42298249224D2288E
+8F47:200023DE2042FA52214AFA52A828F8C4AB12F8602188F83221C4201820602380
+8F48:112412481124FC0011FC7D2455FC7D2455FC7C2013FEFC7010A8112416221020
+8F49:102013FE1020FDFC11247DFC55247DFC54227DFE1008FDFE1108108810281010
+8F4A:108813DE1088FDDC10887FDE54887C0057FC7C041004FDFC1004100413FC1004
+8F4B:1010101012FEFD10117C7C54547C7F54557C7D1011FEFD1011101290147E1000
+8F4C:100011FC1020FFFE12227DAC54207DAC54007DFC1004FDFC1004100411FC1004
+8F4D:2108208823E8F910229EFFD4A864FBD4AA54FBD42254FBC822482254226422C2
+8F4E:201C21E02040FBFE2088F904AAFAFC88A8F8F80023FEFA0222FA228A22FA2206
+8F4F:23FE220223FEFA0022FCFA08ABFEFA10AA30FBCE2242FA8424EE27842884218C
+8F50:1050115210D4FC5011FE7C8854507DFE54207CFC1020FDFE1050108811041202
+8F51:1020102011FCFC2011547C8855047EFA54887CF81088FEF8102010A811241060
+8F52:102011FC1020FC8813FE7C8855FC7D0455FC7D0411FCFD0411FC108811041202
+8F53:103C13E01124FCA813FE7CA855247E0255FC7D241124FDFC1124112411FC1104
+8F54:2020212420A8FBFE20A8F924AA22F904A904F9DE2244FD54209E210422042404
+8F55:108813FE1088FDFC11047DFC55047DFC54807DFE1222FD52110211FA100A1004
+8F56:2020202023FEF9242124FAAAAFFEF800A9FCF9042174F9542174210421FC2104
+8F57:2014201223FEFA1022F0FA14AAF4FAB8AAEAFA162442F82422A2228A24782000
+8F58:100011FC1154FD5411FC7C0057FE7C0055FC7D0411FCFC621094118812A410C2
+8F59:1104108813FEFC2011FC7C2057FE7C5455927C9013FEFC9010D4138A109611A2
+8F5A:08007F3C2A243E422A3CFFA449187F6601007FFC11101FF01110FFFE01000100
+8F5B:214421442554FB64215EFBE4A804FA34A94CFBE42084FBE4208420E427142008
+8F5C:200021FC2020FBFE2222F9ACA820F9ACA800FBFE2020F9FC215421542154210C
+8F5D:1A3823883A38238838B82288FFFE11103FF8C1061FF011101FF01110FFFE0100
+8F5E:200823E82288FBEE2228FBF4AA82FBE2A800F9FC2154F9542154215427FE2000
+8F5F:01003FF801001FF011101FF01110FFFE01001110FEFE54547C7C5454FEFE1010
+8F60:200021FC2124F9FC2124F9FCA904F800ABFEFAAA22AAFBFE22AA22AA23FE2222
+8F61:210427C4410897D2E55C47C89552F7DE0100AFEAA92A01003FF820083FF82008
+8F62:212421742258FADA23FEF954AADAFBFEA8A2F82023FEF87020A8212422222020
+8F63:200023FE2222FACC2244FBEEAA44FAEEAB54FA442210FA90229E249024902BFE
+8F64:2040207C2040FBFC2244FBF0AA44FAFCAAA8FAF822A8FAF8220025FC25542BFE
+8F65:208823FE2088FBDE2252FBDEAA52FBDEAA4AFAFE2392FAFE229222FE22822206
+8F66:0200020002007FFC04000900110021003FF801000100FFFE0100010001000100
+8F67:104010401040FE402040284048407E40084008400E40F84248420842083E0800
+8F68:208020802080FC8043F050909090FC90109010901C90F09251121112120E1400
+8F69:1000100010FEFE102010281048107E1009FE08100E10F8104810081008100810
+8F6A:102010201020FE20202029FE48207E20082008500E50F8504888088809040A02
+8F6B:1000100010FCFE24202428A448A47EA408A409240E24F8444844088409280A10
+8F6C:202020202020FDFC4020504093FEFC40108011FC1C04F0885050102010101010
+8F6D:200021FE2100FD00417851489148FD48114811681D50F14251421142123E1400
+8F6E:2040204020A0FCA0411052089406FD10112011401D80F1005104110410FC1000
+8F6F:104010401040FE7C2084288849207E20082008500E50F8504888088809040A02
+8F70:020002007FFC080011003FF80100FFFE010001003EF80288145008203458C286
+8F71:102010201020FE2021FE282048207E2008FC08840E84F8844884088408FC0884
+8F72:2000200021FEFC08400851E89128FD28112811281DE8F1285008100810281010
+8F73:20202020203EFC20402051FC9104FD04110411FC1D04F1005100120012001400
+8F74:202020202020FC2041FC51249124FD24112411FC1D24F1245124112411FC1104
+8F75:2000200021FCFD04410451049104FD0411FC11041C00F0905088110412021402
+8F76:202020202120FD2041FC51209220FC2013FE10201C50F0505088108811041202
+8F77:2008203C23E0FC20412450A490A8FC2013FE10201C20F0205020102010A01040
+8F78:202020202050FC88410452129020FC40118810101C20F0445188101010601380
+8F79:2008201C21E0FD00412051209120FDFE102010201CA8F0A45122122210A01040
+8F7A:100011FC1044FE442044284448947E88090008FC0E84F8844884088408FC0884
+8F7B:200021FC2008FC10403050489084FF02100011FC1C20F0205020102013FE1000
+8F7C:201020142012FC1041FE50109010FDD0109010901C90F08850EA138A10061002
+8F7D:082008287F240820FFFE10201024FF24202448287F2808100F12F82A08460882
+8F7E:100010FE1010FE202044288248FE7E12081008100EFEF8104810081009FE0800
+8F7F:2008203C21E0FC20402053FE9050FC881104128A1C88F0885088110811081208
+8F80:2010202020FCFC8440A450949094FDFE108410A41C94F0945084110411141208
+8F81:202020202050FC884104520291FCFC20102010201DFCF0205020102013FE1000
+8F82:104010401078FE882150282048507E88090608F80E88F8884888088808F80888
+8F83:204020202020FDFE400050889104FE02108810881C50F0505020105010881306
+8F84:200023FE2120FD28412851E89128FD28112811E81D28F12A513A13EA10261020
+8F85:2028202423FEFC20402051FC9124FD2411FC11241D24F1FC512411241124110C
+8F86:200023FE2050FC50405053FE9252FE52125212AA1EA6F30252021202120A1204
+8F87:082008207EFC0820FEFE145022884206BFF8050009001FF00100FFFE01000100
+8F88:04407C7C04403C7804407C7C064002003FF8050009001FF00100FFFE01000100
+8F89:100013FE92025444584013FCFC8028A0292029FC282028202BFE4C2048208020
+8F8A:200021FC2104FD0441FC51049104FDFC100011121DD4F118511011521192110E
+8F8B:200023FE2202FA8A425253FE9242FE2213FE12821E82F28252FA1202120A1204
+8F8C:2040202023FEFC00400051FC9104FD0411FC10201D28F1245222142210A01040
+8F8D:200023DE2042FD4A4084514A9252FC20100013DE1C52F1525094114812541422
+8F8E:209220922124FA48412450929092FC0011FE11221D22F1FE5122112211FE1102
+8F8F:2020202023FEFC2041FC504093FEFC88110412FA1C20F1FC5020105010881304
+8F90:200021FE2000FCFC4084508490FCFC0011FE11221D22F1FE5122112211FE1102
+8F91:200021F82108FD0841F8500097FEFD0811F811081DF8F108513E17C810081008
+8F92:100010F81088FE8820F8288848887EF8080009FC0F54F954495409540BFE0800
+8F93:204020A02110FA0825F6400053C49254FA5413D41A54F25453D41244125412C8
+8F94:2208220847D08A22F53C27C84110F93E07C0193EE1003FF8200820083FF82008
+8F95:2020202021FCFC2043FE500091FCFD04110411FC1C52F094518816A410C21080
+8F96:2040202023FEFE02442451FC9020FDFC102013FE1C20F1FC5104110411FC1104
+8F97:200023FC2204FA0443FC52489248FEFC124812481FFEF2A452A8149014C81886
+8F98:2040202023FEFA50425053FE9252FE5213FE12001E92F2D45298149214D2188E
+8F99:2208210827C8FA10249E4FD450649794FC9417941C94F7885488149414A415C2
+8F9A:2020212420A8FBFE20A8412452229104F90411DE1A44F554509E110412041404
+8F9B:020001003FF8000008200440FFFE0100010001007FFC01000100010001000100
+8F9C:01007FFC01001FF010101FF001003FF808200440FFFE01003FF8010001000100
+8F9D:10401020202029FC4400FE88425001FE7C20442045FC442044207C2044200020
+8F9E:00201E10F01011FF1000FE441024102811FF7C10441045FF441044107C104410
+8F9F:00407C20442045FC44007C88405041FE7C206420A5FCA42024203C2024200020
+8FA0:02001FF010101FF010101FF010101FF001003FF80820FFFE01003FF801000100
+8FA1:204010201020FDFC000044882850FDFE10201020FDFC10202020202040208020
+8FA2:10401020FE2011FC1000FE88925093FEFE20102039FC54209220102010201020
+8FA3:2020102011FCFC20002045FC2924FD2411FC1020FC7010A82124222240208020
+8FA4:04201E10E01022FE92005444FE2882FE00107C10047C68101010281044108210
+8FA5:08204A1052107EFE24004844BE2822FE22103E10207C3E10221022103E102210
+8FA6:421022082208FA3E078052942288FABE22882288729C2288248844884A889108
+8FA7:401020082788FABE028052942288FABE22882288729C2288248844884A889108
+8FA8:2010108810887CBE00802A941288FEBE128810887C9C11081108220824084008
+8FA9:2010120811087D3E00002B141108FD3E110811087D1C11481188210820084008
+8FAA:08204F10481048FEFF00084410287EFE42107E10407C7F1041107F1041100010
+8FAB:2010108810887D3E01402BD41088FCBE110813C87C1C100810C8230820084008
+8FAC:401022082108F93E000057D42088FCBE22882108711C22882288448848088008
+8FAD:0F20F010491022FEFE0014440828FFFE9510BD10837CBD10951089109510A310
+8FAE:411021082288FABE078051142108FABE27C82148711C25882548494845088208
+8FAF:421021082008FBBE000053942008FBBE20082388729C22882288438842888008
+8FB0:00003FFC200020002FF8200020003FFC24802488245024204410450886060400
+8FB1:00003FFC20002FF820003FFE288848504A308C0E0020FFFE0820042004A00040
+8FB2:04403FF824483FF824483FF800003FFC20002FF820003FFE288848504A308C0E
+8FB3:082008207EFC08201C702AA8C8243FFC20002FF820003FFE288848504A308C0E
+8FB4:0000EEFEAA80AA80EEBC0080FE8092FEFEA092B2FEB410A8FEA8112411321220
+8FB5:003803C07C00003803C03C0C007007807800010011F811001100290047FE8000
+8FB6:000020001000100000000000F000100010001000100010001000280047FE0000
+8FB7:0000200010001000000007FCF000100010001000100010001000280047FE0000
+8FB8:0000200017F8110801100120F13C110411041204120414281810280047FE0000
+8FB9:00402040104013FC00440044F044108410841104110412281410280047FE0000
+8FBA:0000200017F8108800880088F088108810881108110812281410280047FE0000
+8FBB:0040204010401040004007FEF040104010401040104010401040280047FE0000
+8FBC:0200210010801040004000A0F0A0111011101208140418021000280047FE0000
+8FBD:000023F81010102000400040F040104010401040104011401080280047FE0000
+8FBE:004020401040104007FE0040F04010A010901108120414041000280047FE0000
+8FBF:004020401040144404440444F44414441444144417FC10041000280047FE0000
+8FC0:000021FC1020102000200020F3FE102010201020102010201020280047FE0000
+8FC1:0010207813C0104000400040F7FE104010401040104010401040280047FE0000
+8FC2:000023F81040104000400040F7FC104010401040104010401140288047FE0000
+8FC3:000023F81000100007FE0080F10011F810081008100810501020280047FE0000
+8FC4:0100210011FE1200040001F8F010106010801104110410FC1000280047FE0000
+8FC5:00004FE02220222002200220EFA02220222422142214220C220450008FFE0000
+8FC6:004020401040125802E80748F248126812541244120411FC1000280047FE0000
+8FC7:00102010101017FE00100010F210111011101010101010501020280047FE0000
+8FC8:0000200017FE1080008000FCF084108410841104110412281410280047FE0000
+8FC9:000021FC11041104010401FCF104110011001100110012001400280047FE0000
+8FCA:00004FFE2040204007FC0444E44424442444245424482040204050008FFE0000
+8FCB:000027FC1040104000400040F3F8104010401040104017FC1000280047FE0000
+8FCC:000021FC1104110401FC0104F10411FC11041104110412141408280047FE0000
+8FCD:0040204017FC104002480248F24813F8104410441044103C1000280047FE0000
+8FCE:00002080133C122402240224F2241224122412B4132812201020282047FE0000
+8FCF:004020401040104007FE0040F04010A010901108124414241020280047FE0000
+8FD0:000023F810001000000007FCF04010801110120817FC12041000280047FE0000
+8FD1:0008201C11E01100010001FEF110111011101110121012101410280047FE0000
+8FD2:00802040104017FE00000000F1F011101110111012121212140E280047FE0000
+8FD3:000023FC1010111001100210F3FE103010501090111016501020280047FE0000
+8FD4:0008203C13C01200020003FCF204128812501220125014881504280047FE0000
+8FD5:00802080108011FC01200220F020102017FE1020102010201020282047FE0000
+8FD6:005020481048104007FE0040F04010A010901108120414041000280047FE0000
+8FD7:000023FC1040104000400040F7FE104010A01090110812041404280047FE0000
+8FD8:000023FC1020102000400040F0D0114812441444104010401040280047FE0000
+8FD9:00802040104017FC00100210F12010A0104010A0111012081408280047FE0000
+8FDA:00402040104017FC04440444F444144417FC1444104010401040280047FE0000
+8FDB:00902090109013FC00900090F09017FE10901090111011101210280047FE0000
+8FDC:000023F810001000000007FCF120112011201120112412241224141C280047FE
+8FDD:008040802FFC2080008007F8E08020802FFC208420842094208850808FFE0000
+8FDE:0040204017FE108000A00120F3FC10201020102017FE10201020282047FE0000
+8FDF:000021F811081108010801F8F108112011101208120414041000280047FE0000
+8FE0:004020401040107E00400040F3FC120412041204120413FC1204280047FE0000
+8FE1:000023FC1204120403FC0200F2801284129812E012821282147E280047FE0000
+8FE2:000023FC1084108400840114F20811FC11041104110411FC1000280047FE0000
+8FE3:004822481248124807FE0248F248124812781200120013FE1000280047FE0000
+8FE4:0200220013FC144004400A58F2E81748126812501244120411FC280047FE0000
+8FE5:000023FC1204120402F40294F294129412F41294120412141208280047FE0000
+8FE6:04004400243C2FA404A404A4E4A424A424A428A428BC32A4210050008FFE0000
+8FE7:0040204017FC1444044407FCF444144417FC1444104010401040280047FE0000
+8FE8:008020801110120807FC0204F00013F812081208120813F81208280047FE0000
+8FE9:00802080110011FE02020424F020112811241222142210A01040280047FE0000
+8FEA:00404040204027FC04440444E44427FC24442444244427FC200050008FFE0000
+8FEB:00402040108013F802080208F20813F812081208120813F81208280047FE0000
+8FEC:00802040100017FC00400040F04013F81040104010401FFE1000280047FE0000
+8FED:00402240124013FC02400440F04017FE104010A0109011081208280047FE0000
+8FEE:01002100110013FE02800480F0F81080108010FC108010801080280047FE0000
+8FEF:01102110111011D002580254F252155218901090111012101410280047FE0000
+8FF0:004020501048104007FC00C0F0E0115011481244144410401040280047FE0000
+8FF1:0080404027FC240408080200E210226023802204220421FC200050008FFE0000
+8FF2:00402040104013FC00400040F7FE104010801110120817FC1204280047FE0000
+8FF3:000023F81010102000500188F60413F810401040104017FC1000280047FE0000
+8FF4:000023FC1204120402F40294F29412F41204120413FC12041000280047FE0000
+8FF5:000023FC120412F402040204F2F41294129412F4120412141208280047FE0000
+8FF6:0040204017FE1080010003FCF50419FC110411FC110411141108280047FE0000
+8FF7:0040224811481150004007FCF04010E011501248144410401040280047FE0000
+8FF8:02082110100017FC01100110F11017FE11101110121012101410280047FE0000
+8FF9:00402020102017FE00900090F294129214921110111012501420280047FE0000
+8FFA:00004FFE20A020A007FC04A4E4A424A4251C2604240427FC240450008FFE0000
+8FFB:0040208011F81610012000C0F120167C10841348103010C01700280047FE0000
+8FFC:00402040104017FC00400040F3F81000100013F81208120813F81208280047FE
+8FFD:0020204013FC1204020403FCF200120013FE1202120213FE1202280047FE0000
+8FFE:000427E411041114011403D4F2541254155410941094110412141408280047FE
+8FFF:0100210011FC1204040403E4F224122413E41224122413E410041028281047FE
+9000:03F82208120813F802080208F3F8124412281210128813041204280047FE0000
+9001:020241043088101003FE0020F020102017FF10201050108811042A02440183FF
+9002:007823C01040104007FE0040F04013F812081208120813F81208280047FE0000
+9003:00A020A014A412A801B000A0F1B012A814A4112011241224141C280047FE0000
+9004:0080208010FC110802900060F1981626102011FC1020122013FE1020282047FE
+9005:003C23C01200120003FE0200F20012FC12841484148418FC1084280047FE0000
+9006:0208410821102FFE00400040E4442444244427FC20842100220054008FFE0000
+9007:021042502250225C0F7402D4E2542254225C23502E422442203E50008FFE0000
+9008:0040208013FC1204020402F4F2941294129412F4120412141208280047FE0000
+9009:00402240124013F804400040F7FC11201120112012241224141C280047FE0000
+900A:00104F9020902110021002D8E354225426922A92231222102A50242050008FFE
+900B:004840442FFE204007FC0444E7FC244427FC244424442454240850008FFE0000
+900C:00402040107C1040004003FCF20413F4121413F4120413FC1204280047FE0000
+900D:0040224811481150004003F8F208120813F81208120813F8120812282A1047FE
+900E:000027FE1090109003FC0294F294130C120413FC1204120413FC1204280047FE
+900F:003823C0104017FC01500248F44613F01110113C110412141408280047FE0000
+9010:000023FC1040108001440668F0B01128166810A41124162010A0284047FE0000
+9011:00402050104817FC00400248F15010E011501248144411401080280047FE0000
+9012:011020A013F81048004803F8F240124013FC10C4114412541448284047FE0000
+9013:003C47E0242025FC042007FEE420242025FC2524252429342928302050008FFE
+9014:004020A01110120805F60040F04017FC10401248124414441140288047FE0000
+9015:000027FC1000124804900248F00017FC1040104010401FFE1000280047FE0000
+9016:09104510221026520A520254E29026282A24324422422A82250050008FFE0000
+9017:000027FC1000100003F80208F20813F810001208111017FC1000280047FE0000
+9018:00802100120817FC01040100F3F81440104017FE104010A011102A0847FE0000
+9019:0080204017FC100003F80000F3F8100013F81208120813F81208280047FE0000
+901A:000047F8201021A0004007FCE444244427FC2444244427FC2444245454088FFE
+901B:00004880257C22100D100110E17C23102D10211021102A7E240050008FFE0000
+901C:00004FF82080208007F00110E1102FFC200027F82408240827F850008FFE0000
+901D:0208421C226022400FC0027EE2C823482E48224822482A48248851008FFE0000
+901E:03F822081208120803F80000F7FC1040104013F81040104017FC280047FE0000
+901F:0040204017FC104003F80248F24813F810E01150124814441040280047FE0000
+9020:0040224013F81440004007FCF000100013F81208120813F81208280047FE0000
+9021:00802110120817FC00040110F208150411F812081590106011902E0847FE0000
+9022:010021F81308149000600198F606104013F8104013F8104017FC1040284047FE
+9023:004040402FFE204007FC0444E7FC244427FC20402FFE2040204050408FFE0000
+9024:001022101110145402520092F0101114160412081210122010C0280047FE0000
+9025:000023FC1294129402F40294F29412F412941294129413FC1204280047FE0000
+9026:00004FFE2000200007BC04A4E4A426B425AC24A424A424A425AC50008FFE0000
+9027:01102248144410A001100208F40613F812081208120813F81208280047FE0000
+9028:0040204017FC104001500150F2E8144410E01150124814441040280047FE0000
+9029:0000208017FC111002480C46F3F810401150111017FE111012101410281047FE
+902A:0110211017FC111001100FFEF00013F8120813F8120813F81208280047FE0000
+902B:000047BC2084252802100528E84027BC2084252822102528284450008FFE0000
+902C:00842084110817BC01080108F108110817BE11081108110811082A0847FE0000
+902D:0080204017FC140403F00210F21013F0120013F81208120813F8280047FE0000
+902E:0040204013F8104807FE0048F3F8144412481150124814441140288047FE0000
+902F:000047F8200823F800080FFEE040244422E8215022482444214050808FFE0000
+9030:02204220223E2F400280027CE30422082E7E2208220822082A28241050008FFE
+9031:000047FC2444244405F40444E7FC240425F4251425F42404280C50008FFE0000
+9032:0140212013FE122006200BFCF220122013FC1220122013FE1200280047FE0000
+9033:0080204017FE1100020807FCF00413F8120813F8120813F8120812282A1047FE
+9034:00402040107E104003F80208F3F8120813F810401FFE10401040284047FE0000
+9035:0040204013F81040004007FCF1101248144413F81040104017FC1000280047FE
+9036:003823C0104017FC01500248F44410801FFE11081390106011981604280047FE
+9037:000023F8120813F8020803F8F10013FC14941924124414A811102A0047FE0000
+9038:0100410021F0221004200FFCE444244427FC20A02130212A2222241E50008FFE
+9039:0040204013F81040004007FCF11010A013F81040104017FC10401040284047FE
+903A:0040204013F8104007FE0080F11013E0104411A81690108810C4280047FE0000
+903B:000047FC24A424A407FC0080E1F82208251020A0204021802E0050008FFE0000
+903C:000027FC100013F8020803F8F00017FC144417FC144417FC1404280047FE0000
+903D:0108210817FE1108004007FEF080110013FC1504190411FC1104280047FE0000
+903E:004040A0211022080DF60000E78424A427A424A427A424842494258850008FFE
+903F:01F8210811F8110801F80000F7FE110013FC14A4112412541088280047FE0000
+9040:008027FC110013F804400BFCF00013F8120813F8120813F8120812282A1047FE
+9041:001E23E01220122003FE0220F2FC128412FC128412FC148414FC280047FE0000
+9042:0110209010A017FC00800144F66810B01128166810A4112416A0284047FE0000
+9043:0040202013FC100001080090F3FE122012C81210122412C812101460298047FE
+9044:004044442444244407FC0000EFFE208027FC24A424A424A424A4240C50008FFE
+9045:00004FFC280428040FFC0910E8A02FFC28402BF8284037FC204050408FFE0000
+9046:0080204017FC111000A007FCF444104013F812481248126812501040284047FE
+9047:000023F8124813F8024803F8F04017FC14441454147415941404140C280047FE
+9048:000043F8220823F8020803F8E0002FFC204022782240254028FE50008FFE0000
+9049:00402040107C104003F80208F3F8120813F8120813F810A011102A0847FE0000
+904A:042042202FBE2440043C0784E488248824FE24882488288829A850108FFE0000
+904B:000027FC144413F8004003F8F24813F8124813F8104017FC1040284047FE0000
+904C:000027BC14A417BC000003F8F00017FE110011F8100810081050282047FE0000
+904D:0080204013FC1204020403FCF20013FC1354155415FC19541144110C280047FE
+904E:01F8210811E81128012803FCF20412F4129412F4120412141208280047FE0000
+904F:000023F8120813F8020803F8F10013FC14441AA4120413F41014280847FE0000
+9050:000047BC2484248407BC0400E40027BC2404240427A82410242854448FFE0000
+9051:0040208013F8120803F80208F3F8100017FC104013F8104017FC280047FE0000
+9052:020841102FFE20A007FC04A4E4A42524261C240427FC240427FC50008FFE0000
+9053:02082110100017FC008003F8F20813F8120813F8120813F81208280047FE0000
+9054:0040204013F8104007FC0110F0A017FC104013F8104017FC1040284047FE0000
+9055:008023F8110817FE000003F8F20813F8104017FC1040144017FE1040284047FE
+9056:004040402FFE204007FC0514E4A425F4244425F424442454244850008FFE0000
+9057:004023F8124813F800400FFEF00013F812081248124810A011102A0847FE0000
+9058:011027FC111013F8011007FCF04013F8124813F8124817FE120812282A1047FE
+9059:004020FC1324109800E00700F1F81240104017FC1040124413FC280047FE0000
+905A:00402140165C1444075C0444F7FC104017FC10081190106011981604280047FE
+905B:0080477C2424252404A40554E648208027FC244427FC244427FC50008FFE0000
+905C:00064FB82090212002440278E3102E24227E221222542A92245050208FFE0000
+905D:000027FC14A414A407FC0040F150124814441150124814441040280047FE0000
+905E:001E47E0243C242005FE0522E53825E2251E250029782A48328A250650008FFE
+905F:000023FC1204120403FC0240F22013FC1288125013FE122015FC1420282047FE
+9060:0040204013F8104007FC0000F3F8120813F810C411A8129014881084280047FE
+9061:0440225E1292101207D2011EF5521552155217DE115212121222142A284447FE
+9062:000023F8120813F8020803F8F00017BC108414A4129414A412941108280047FE
+9063:004023F8124813F8004007FEF00013F8120813F8120013F8120813F8280047FE
+9064:000023FC124013F8024003F8F24013FC10041554155415541428281047FE0000
+9065:003C23C010041244012801FCF220102013FE102011241124112411FC280047FE
+9066:03FC224417FE124403FC0000F3FC120413FC120413FC120413FC11082A0447FE
+9067:004047FC21102FFE000003F8E20823F8220823F820402FFE204050408FFE0000
+9068:021042102F90221E07A40244EF9424142788248824942AA2294250008FFE0000
+9069:0080404027FC211000A007FCE44427FC244425F4251425F42404240C50008FFE
+906A:0080211013F8121004A407FCF0A013181C4613901064139810601380280047FE
+906B:021042102F90223E0FA40AC4EAA42F94220827082A943224224450008FFE0000
+906C:022042202FA0223C0FC40A90EA902F90221027282AA83244228450008FFE0000
+906D:00A02FFE10A017FC04A407FCF4A417FC100013F8120813F8120813F8280047FE
+906E:0040402027FE240004880488E7FE2488248824F828002AA43252245250008FFE
+906F:0000477E25102530074A059AE52C274C259A252A254A25A82B1050008FFE0000
+9070:02A822A817FC12AA04E60800F7FC1444104013F8124812481258284047FE0000
+9071:004043F822482FFE024803F8E04023F8224823F820802FFE211020E053188FFE
+9072:07FC440427FC242004A80470E4A8250424A024FC252024202BFE282050208FFE
+9073:0110211017FC111000400248F2481554104013F81040104017FC280047FE0000
+9074:00402248115017FC01500248F4441210139014BC1A901150117E12102A1047FE
+9075:01104FFE20A027FC04A4051CE60427FC240427FC20102FFE211020B050008FFE
+9076:0040204013F8104007FC0210F73812101F7C100017FC11201224141C280047FE
+9077:07FC20A017FC14A407FC0080F7FE120815F4191211F0110410FC280047FE0000
+9078:0F3C49242F3C28A2079E0110E7FC211021102FFE21102208240450008FFE0000
+9079:000023F81090106007FC0124F6A8104017FC14A4151416EC14A414EC280047FE
+907A:004023F8124813F8004007FEF00013F8120813F8120813F8120813F8291047FE
+907B:000027BC14A414A407BC0110F0A017FC10401248124813F810401080290047FE
+907C:004040402FFC20A0051403F8E60C2BFA220823F8204022482444294450808FFE
+907D:0040407C204027FE044205F8E44427FC24C0272228D42B183074239250208FFE
+907E:0210421023DE2528088407FCE04022482248255428E220402FFE50008FFE0000
+907F:0010478824BE248004A20794E43E28082F8834BE24882788248850008FFE0000
+9080:020044102F9028900F9E08A4EFC422143FD424082788289432A2214250008FFE
+9081:01104FFE211023F8024803F8E24823F8204027FC245425F42414240C50008FFE
+9082:04004F3C291432140F940AA8EAA82FBC2AC82A882FBE2A882A88318850088FFE
+9083:008040402FFE2A12140C0120E7FC20802144266821B0266821A426A450408FFE
+9084:000047FC24A427FC00000FFEE00023F8220823F8214423282D9051088FFE0000
+9085:002027FE100013FC020402F4F29413FC110811F8110811F8100017FE280047FE
+9086:002423A810921514020805F4F00213F8120813F81208111017FC280047FE0000
+9087:07FC424824442FFE044406ECE55426EC244426EC255426EC2444240C50008FFE
+9088:011042202D7C25C402440D7CE3442544297C23282528292A254652808FFE0000
+9089:008047FC240427FC040407FCE40427FC20402FFE291223F8251421F050008FFE
+908A:008047F8254824A807F80040EFFC2A1424882BF4210021F02210243050008FFE
+908B:02484490224827F8052804C8E52827F8249026D0249026D4248C26C450008FFE
+908C:0190461E222A2F8A031206AAEA4420A023182C46225021602250254850808FFE
+908D:010043F0251020E0071C03F8E24823F8224823F820082FFE2248215052488FFE
+908E:04004F8C35702A2004441A78EF9020242F7E20102F5429922F3050008FFE0000
+908F:00004FFE29122FFE02280424E97E2FC8227E25482F7E21482AFE2A4050008FFE
+9090:0FBE40002FBE2CB20AAA0040EFFE29202FFC29242FFC2A282BB22A1E53808FFE
+9091:00001FF0101010101FF000003FF82108210821083FF82008200220021FFE0000
+9092:0000FF7C08440848084808500848084808440844084408680850284010400040
+9093:00007E7C02440248424824501448084808441444144422684250804000400040
+9094:00007F7C01440148014801503F48214820442044204421682650384020400040
+9095:088811102220111008881FF010101FF000003FF8210821083FF8200220021FFE
+9096:0800083E0822082449244928492449244922492249224F347928002000200020
+9097:00007F7C08440848084808500848FFC808440844084408680850084008400840
+9098:00007F7C08440848084808500848FFC808440844084408680850084028401040
+9099:1000083E08220024FFA4202820242024202220222022203420283F2000200020
+909A:1000107C10441048FE4822502248224842442444144408681450224042408040
+909B:0000007C7F44084808480850084808480844084408440F68F050404000400040
+909C:1000107C10441F482148215051488A480A440444044408681050204040408040
+909D:0800043E04223FA4202420282024202420222022202220342028402040208020
+909E:0800087C08447F48084808500848FFC808441444124422682150414080400040
+909F:1000087C0844FF48004800503C48244824442444244425684650444080400040
+90A0:0000147C12441248214821504048BE481244124412441268225022404A408440
+90A1:1000083E0822FFA4102410281F24112411221122112211342128252042208020
+90A2:00007FBE12221224122412281224FFE412221222122212342228222042208220
+90A3:00007E7C1244124812487E50124812487E4412441244226822504A4084400040
+90A4:0200077C38442048204820503FC8244824442444244424682450444044408440
+90A5:0800087C08447F48494808500848144814441444144425682650444080400040
+90A6:0800087C0844FF48084808507E4808480844FF44084410681050204040408040
+90A7:00003F3E002200240024FFA81224122412221222122222B42328422080200020
+90A8:0800083E0822FFA4082449284924492449227F220822083409280A200C200820
+90A9:0800087C0844094849484A504C48884808440844144412682150214040408040
+90AA:00007FBE022222242224222842247FE406220A2212222234422882200A200420
+90AB:100010F81088FC8810F810007DFC11241124FF2411FC110021002102410280FE
+90AC:1000203E7E22422442244A28442440247F22012201221D34E12841200A200420
+90AD:1000103E20223F24412481283D242524252225223D222534012801200A200420
+90AE:0800087C08447F4849484950494849487F4449444944496849507F4041400040
+90AF:2200223E22222224FFA42228222422243E2222222222223422283E2022200020
+90B0:0800083E102222244124FFA800A400247F22412241224134412841207F204120
+90B1:0000033E3C222024202420283FA42224222222222222223427A8F82040200020
+90B2:1000083E0A2202241224132854A454A4542298221922113431284F2080200020
+90B3:0000FF7C08440848104814503248514890441044104400680E50F04040400040
+90B4:00007FBE0822082408247FA848A448A454A252A262A240B440A840A042A04120
+90B5:00007F3E1122112421242528422480243F2221222122213421283F2021200020
+90B6:1200123E122212241224F3A812241224122212221222323452A8932012200020
+90B7:0000FF7C204420483C482450244834484C444C44444445685550654043400040
+90B8:010007BE7C2244244424442844247FA4442244224422423442A852A069A044A0
+90B9:2000207C3E44424884480850FE48024802447E44024402680250FE4002400040
+90BA:1400143E142214A494A455285524562414221422142217B4F828402000200020
+90BB:0800087C14441248214848D0844804487F440144224414680850044004400040
+90BC:00007FBE402240247FA4442844245F24442244227FA2403440287FA000200020
+90BD:0800087C7F44084808480850FFC80048084408447F44086808500F40F0404040
+90BE:0800487C48447F48484888500848FFC818441C442A4429684950884008400840
+90BF:0800083E08227F2408240828FFA4022402227FA202222234122802200A200420
+90C0:0800083EFFA2142422244128BEA40024FFA2102220227F34012801200A200420
+90C1:0800083EFF22102410243F2821246124BF22212221223F342128212025202220
+90C2:1000083E0022FFA40824112821247E240422092212222434CC2812202120C0A0
+90C3:0800087C144422484148BED0004800483E4422442244226822503E4022400040
+90C4:0100323E0C22122469240828FFA410242422242248228A3411283F2011200020
+90C5:0000FFBE0822102422244128FFA408A4082208227F22083408280FA0F8204020
+90C6:0800083E0822FFA4082408287F24002400227F224122413441287F2041200020
+90C7:2000203E7F22412481247928492449247922492249227934412801200A200420
+90C8:0200073E7822402440247FA8402440245F2251225122513451289F2091200020
+90C9:0000773E22222224222422282224F7A422222222222222342228422042208220
+90CA:1000087C0044FF48004824504248814824441444084414682250424080400040
+90CB:0800083E10227F24412441287F24412441227F224122413441287F2041200020
+90CC:100010F810887C8810F81000FDFC0124112411247DFC110011001D02E10240FE
+90CD:0800103E3F222124292425282524FF2421222922252225342128412045208220
+90CE:0800043E3F22212421243F28212421243F222022242222342528292030202020
+90CF:0800083E0822FFA40824492829242A24FFA20822082214341228212041208020
+90D0:0800083E142222244124BEA800240024FFA21022102222344128FF2041200020
+90D1:2200123E14227F24082408280824FFA408220822142212342128412080200020
+90D2:000020F810887C8844F844007DFC452445247D2441FC510049005502650240FE
+90D3:00007FBE48A208247FA41028142424247FA20422042207B4FC28442004200420
+90D4:008001DE771211121114251425D8751415125512551227DA201450108FF00010
+90D5:0400053E04A204247FA4442844247524552255225522523452A8A6A089A010A0
+90D6:00007FBE002200243F242128212421243F22002221221134122807A078202020
+90D7:30800D3E0622192460A408287FE4142424227FA2A4A224B426A8252004200420
+90D8:00003E3E22222224222422283E24002400227F2241224134412841207F204120
+90D9:0A00093EFFA2082408247F28492449247F22492249227F344928492049204320
+90DA:0000FFBE082208247F2411281124FFE4002200227F224134412841207F204120
+90DB:02000F3EF022012491244A280024FE24042208220F22F8344828082028201020
+90DC:0800483E48227F24482488280824FFA4002200227F224134412841207F204120
+90DD:0800083E7F22082408240828FFA412241222532252A292B4222822204A208420
+90DE:1000087C7E44424842487E50424842487E4451444A4444684450524062404040
+90DF:0800083E0822FFA408242A282A242A245D2288A2082214341228212041208020
+90E0:00007FBE082208247F24492849247F24492249227F220834682818202620C120
+90E1:00007F3E11221124FFE4112811247F24202220227F22A134212821203F202120
+90E2:00007F7C4144414841487F5000487F48084408447F44086808500F40F0404040
+90E3:0800087C7F44084808487F50414882483C44044408440F687850084028401040
+90E4:1400127C214449480848145022484148BE4422442244226822503E4022400040
+90E5:00007E7C424442487E48425042487E48424442447E4400682450224041408140
+90E6:00007FDE001200127BD44A544A584A546B525AD24A524A5A4A544A504A505AD0
+90E7:00003E3E222222243E2400287F2441244922492249224934142812202120C120
+90E8:1000083E7FA2002421241228FFE4002400223F222122213421283F2021200020
+90E9:61001A3E0C223224C9240828FFA410243F226122BF2221343F28212025202220
+90EA:0800083EFFA208247F240928FFA409247F221022FF22213472280C203320C0A0
+90EB:1000203E7F22492449247F28492451247F2224224422FFB40428042004200420
+90EC:0800083EFFA208247F240828FFA400247F2241227F2241347F28412045204220
+90ED:1000087CFF4400487E4842507E4800487E44044408440F68F850084028401040
+90EE:00003FBE24A224A42EA424A83FA420A42EA22AA22AA22EB420A840A042A08120
+90EF:0800093E49224A2488241428222449248822492249228A3414282220412080A0
+90F0:0000FC1E48124BD278544A5449587954489248925C92E95A49540A5008100810
+90F1:2100113E122200247FA41228122412241222FFA2122212341228122022204220
+90F2:0800087C0844FF4808482A502A482A485D4488441C442A684950884008400840
+90F3:1000677C414441487748415041487F4814441444144414682550264044408040
+90F4:1100111E111211127BD41114111833143B9255525512991A1114111011101110
+90F5:02000F3E78220824FFA42A282A24FFA42A222A22FFA2083408280F20F0204020
+90F6:200010F87C88008844F8280001FCFF24012401247DFC4500450045027D0244FE
+90F7:200023DE22524A524BD4F254125823D44A12FA920A5212DA1354221040108010
+90F8:4100223E14227F24492449287F24492449227F2208220834FFA8082008200820
+90F9:00007E7C42447E4842487E5042487E4814441244FF4410682850244042408040
+90FA:212422483D244400A8F8108820F8C80011FC3D24452485FC290011042104C0FC
+90FB:3F00A13EBF22A124BF24A128BF248024FFA20022492249349228922049204920
+90FC:1000103E7F222124FFE400287F2441247F220822FFA208348828FFE008200820
+90FD:080008BE7EA209240A24FFE8082410243F226122A1223F34212821203F202120
+90FE:00007FDE40125F9250945F9450985F9444127FD24912591A4614491050907FD0
+90FF:00007F7C494449487F4840505F48514851445F4451445F68515051409F401140
+9100:2200223EFFA222242A240828FFA4102420223F226122A134212821203F202120
+9101:140014BEF722142434A4D3A800247F2441227F2241227F344128412045204220
+9102:0000773E55225524772400287F240024FFA220223F220134012801200A200420
+9103:0800143E22224124BEA4002878A44AA44AA27AA24AA24AB47AA848A04AA05920
+9104:0000FF7C144414487F48555055487F48084408447F44086808500F40F0404040
+9105:010007BEF82208247F24492849247F240822FFA288A28AB4BEA880A082A08120
+9106:0000FFBE88A20824FFA408287F2449247F2249227F220834FFA8082008200820
+9107:1000179E109220922FF46414A41827D4291221122FF2211A2294225024502810
+9108:0A00747C15445248224821504148BE48084408447F4408681450124022404040
+9109:2100209E23D24A524A54F3D4125822544BD2FA120A92125A12D4235042108010
+910A:200027FE22524A524BD4F254125823D44A52FA520A7217DA1054205040508050
+910B:28004B7C494449486B48495049487F4808447F44014432680C50124061400040
+910C:0800043E7FA244245F2445287FA445245F2244225F225134512851205F209120
+910D:0000FFBE80A200247F2441287F2441247F2210220822FFB400282220412080A0
+910E:0800103E7F2241247F2441287F2441247F22102208222934A2A8A2A01E200020
+910F:00007FBE40225F2440247FA855245224592250A242227FB452284A2082200620
+9110:1000083EFFA2102422247C28082411247FA200A27F2249347F2849207F204120
+9111:00007FBE122252A433241228FFE400243F22212221223F34212821203F202120
+9112:1000103E3FA248A42AA43EA810A4252452223FA248A2AAB43EA810A025204220
+9113:0800103E7F2241247F2441287F2441247F220A220922FFB40828142022204120
+9114:1000203E7F22412441247F2840247FE440227FA200A2AAB4AAA800A005200220
+9115:2080211E23D24A524A54F3D4125822544BD2F8120A52139A1214225041D08010
+9116:00003F3E212221243F2400287FA440A47FA240A27FA240B47FA81220212040A0
+9117:1000087CFF4400487E4842507E480048FF448144BD44A568BD50814085408240
+9118:02003FDE22122F9222943FD422982F9422122F922A922F9A4A944F908A900990
+9119:1F00113E11221F2404247FE804243FA420A22EA22AA22EB420A83FA020A00020
+911A:2200223EFFA222247F2441287F2441247F220822FFA208341428222041208120
+911B:4900927C494400487F4849507F4849487F440844FFC41C682A50494088400840
+911C:0800043E7FA2522452247FA852A452A47FA2522252225BB4522852A09B201220
+911D:0000773E11225524332455280C243324C4A2182262220CB4712806201820E020
+911E:2200227CFFC422483E4808507F4849487F4408447F4408687F5008400F40F040
+911F:0800FFBE08227F2449247F2849247F2408A2FFA20222FFB4422822200A200420
+9120:7F00083EFFA288A46B2408286B2400247F220022FFA220343F2801200A200420
+9121:10007F3E41227F2441247F2840247FA440227FA208A27EB41DA82A20C9200820
+9122:00007FBE042227242424FFA820243FA440227FA200A2AAB4AAA800A005200220
+9123:08007F3E22221424FFA400287F2441247F2241227F220834FFA8082008200820
+9124:7E00427C7E4442487E480050FF48A548FF4400447E4402683450084014406240
+9125:1000203E7F2241247F2441287F2440247FA240227FA200B4AAA8AAA080A00320
+9126:2000203E7FA2D52455245528FFA4552455225522FFA200346A28552095200020
+9127:0500723E12A2512421245EA880A43F24212221223F222134122807A078202020
+9128:49202A3E7F4449A85D106B2849461FF010101FF000003FF821083FF820021FFE
+9129:00007F3E01223F2401247F28002477242522F7220222FFB4422822202A200420
+912A:1200FF9E12927F9252147FD422587F54A1D23F1221123F1A21143F1012102110
+912B:4100223E0022FFA488A4AAA89CA488A4FFA200227F2241347F2841207F204120
+912C:03C07C1E289215123F14211421183F94209220923FD2205A55545550A1500090
+912D:2200147CFF4414487F48555063485D4841447F440844FF681450224041408040
+912E:1000EFBEA4A294A4AAA4C92810247F2441227F2241227F3441287F2022204120
+912F:2200143EFFA208247F240828FFA449242A22FFA200227F34412841207F204120
+9130:0800493E2A22FFA42A24492888A44124412277A29122553427A8412081200120
+9131:0F00F83E49222A24FFA42A28492480A47F22492249227F34492849207F204120
+9132:0000F7BE94A294A4F7A400287F2449247F2249227F220834FFA8082008200820
+9133:00007F3E55225524772414287724552455227722552255347728542014A00FA0
+9134:1400557C36441448FF48225014487F4808447F440844FF681C502A4049400840
+9135:00007F3E41227F240024F7A894A4F7A408220822FFA21C342A28492088A00820
+9136:04000B1E30D2DF3200147FD455584E547FD200123F92209A3F9420903F902090
+9137:12007FBE52A27FA452A47FA800247FA400227FA240A27FB4212812200FA0F020
+9138:2200FFBE22227F24552455287F240024FFA290A23E22223452280C201820E020
+9139:FC004BBE78A24AA479244D28FAA40CA407A2F82228A24D341A282920C8A00820
+913A:0800043E7FA24A245F244A287FA444245F2255225F2255345F288020912020A0
+913B:2200F7BE2222F7A4552488A87F2408247F2249227F2249347F280820FFA00820
+913C:2200773E2222F7A42224552888A47F2441227F2241227F3441287F2022204120
+913D:04007FDE40125F9254945F9454985F9444125F9244127FDA5494AF5084103FD0
+913E:7F80083E3F2221243F2421287FA448A4252252A20E2210343F2851200E207120
+913F:2200FFBE222277245524772800247F2449227F2249227F340828FFA008200820
+9140:2200221EFF9222123E1441145D58D59455125552DD5240DA001454904A508A50
+9141:3E00421EFF9240927F944494771844543FD24212FF92489A7F941A102950C7D0
+9142:1080529E7BD29492FBF431945AD8949400123F922092249A24940B1010906050
+9143:00007FCE040AFFEA842A358A040C358A000A000AEEEAAAAAAAACAAA8EEE8AAA8
+9144:11007FDE11127BD24A547BD4141812143FD224127F92A41A3F9424103FD02010
+9145:44407FDE12123FD26214BFD422183FD422123FD220127FDA51546ED04A504ED0
+9146:2A007F3EAAA2FFA4AAA4FFA8AAA4FFA40022FFA200227F3441287F202220FFA0
+9147:52807BDE9492FBF231945AD494983F9420923F9220923F9A20943F9011102090
+9148:7BC0001E7BD24A526B544A5404187FD44A127FD24A527FDA52545B90525099D0
+9149:0000FFFE044004407FFC444444444844503C600440047FFC400440047FFC4004
+914A:0000FF80147E14107F105510551055105710611041107F10411041107F504120
+914B:101008100820FFFE044004407FFC44444844503C60047FFC400440047FFC4004
+914C:0020FE202820287CFE44AA84AA04AA44AE24C2148214FE0482048204FE288210
+914D:0000FE0028F82808FE08AA08AA08AAF8AE88C2808280FE8082828282FE7E8200
+914E:0008FE0828082808FEFEAA08AA08AA08AE48C2288228FE0882088208FE288210
+914F:0020FE20282028A0FEACAAB4AAE4ABA4AEA4C2B482A8FEA282A28282FE7E8200
+9150:0000FE7C28102810FE10AA10AA10AAFEAE10C2108210FE1082108210FE108210
+9151:0000FEFC28202820FE20AA20AA20ABFEAE20C2208220FE2082208220FEA08240
+9152:00004FFE20A020A007FC84A444A454A4151C2604E40427FC2404240427FC0404
+9153:010002800C603118CFE600400080FFFE04803FF82488287830083FF820083FF8
+9154:0040FE4029F82848FE88AA8AAB0AAA26AE20C22083FEFE2082208220FE208220
+9155:0008FE1C28F02810FE10AA1CAAF0AA10AE10C21E82F0FE1082128212FE12820E
+9156:0010FE1028102810FEFEAA92AA92AA10AE28C2288228FE288248824AFE8A8306
+9157:0000FE4428442828FEAAAAAAAA92AA92AEAAC2AA82A6FEC682828282FEFE8202
+9158:0000FE7828482848FE48AA86AB00AAFCAE44C2448228FE2882108228FE448382
+9159:0008FE8828482848FE08AA88AA48AA48AE08C20E82F8FE0882088208FE088208
+915A:0008FE2828282828FE44AA44AA82AB7CAE24C2248224FE2482448244FE948308
+915B:0000FEFC28002800FE00AAFEAA50AA50AE50C2508250FE5282528292FE8E8300
+915C:0020FE20282028FCFE20AA20AA20ABFEAE20C2508250FE4882888284FF048202
+915D:0000FE00287C2800FE00AA00AAFEAA10AE10C2208220FE44824282FEFE428200
+915E:0020FE2028202820FE20ABFEAA20AA20AE20C2508250FE50828882C8FF248202
+915F:0010FF90141014107F1E551055105510577C614441447F44414441447F7C4144
+9160:0000FE0028FE2804FE04AAF4AA94AA94AE94C29482F4FE9482048204FE148208
+9161:0020FE10281028FEFE82AA84AA40AA44AE48C2508260FE4282428242FE3E8200
+9162:0040FE402840287EFEA0AAA0AB20AA3CAE20C2208220FE3E82208220FE208220
+9163:0044FE4428442844FEFEAA44AA44AA44AE44C27C8244FE4482448244FE7C8244
+9164:0010FE1028102810FEFEAA10AA10AA10AE7CC2448244FE4482448244FE7C8244
+9165:0004FE1E28F02810FE10AA10AAFEAA10AE38C2348254FE5282908210FE108210
+9166:0020FE2828A428A0FEFEAA40AA40AA7CAEA4C2A482A8FEA882908328FE448282
+9167:0020FE1028FE2882FF0CAA08AA08AAFEAE08C2488228FE2882088208FE288210
+9168:082008287F240820FFFE0020FFA414247F245528632841107F12412A7F464182
+9169:0020FE20287E2882FF44AA28AA10AA20AE40C2FE8342FE4282428242FE7E8242
+916A:0020FE20283C2844FEA8AA10AA28AA44AE82C27C8244FE4482448244FE7C8244
+916B:0010FE1028282828FE44AA82AA7CAA10AE10C210827CFE1082108210FEFE8200
+916C:0004FE4428542854FE54AA54AADCAB74AE54C2548254FE5482548254FE848304
+916D:0020FE2028FE2820FE40AA7CAA44AAC4AF7CC2448244FE7C82448244FE44824C
+916E:0000FEFE28822882FEBAAA82AA82AABAAEAAC2AA82AAFEBA82828282FE8A8284
+916F:0080FE82288C28F0FE82AA82AA7EAA00AEFCC2848284FEFC82848284FEFC8284
+9170:0010FE502850287CFE90AA10AA10AAFEAE28C2288228FE28824A824AFE868300
+9171:0840488029FC1A482830C9C00800FFFE04803FF82488287830083FF820083FF8
+9172:0000FE7C28442844FE44AA7CAA00AA00AEFEC2108210FE7C82108210FEFE8200
+9173:0020FE4428F82810FE24AAFEAA02AAFCAE84C2FC8284FEFC82848284FE948288
+9174:0010FE1028282828FE44AABAAA10AA10AEFEC2108258FE5482928312FE508220
+9175:0020FE2229FA2824FE24ABFEAA10AA20AFFCC2888310FEFE82108210FE508220
+9176:0040FE40287E2880FF7CAA44AA64AA54AEFEC24482A4FE9482FE8204FE288210
+9177:0010FE502850287CFE50AA90AA10AAFEAE00C200827CFE4482448244FE7C8244
+9178:0010FE1028202844FEFEAA28AA44AAA2AE3CC2448244FEA882108228FE448282
+9179:0004FE1E28E02822FE92AA54AA40AA08AFFEC2088288FE4882488208FE288210
+917A:0014FE1228FE2810FE10AAFEAA92AA92AEFEC2928292FEFE82928292FE928286
+917B:000EFEF028222892FE54AA00AA7CAA08AE10C21082FEFE1082108210FE508220
+917C:0020FE1029FE2820FE48AA84ABFEAA02AEA8C2A882A8FEA882A882AAFF2A8206
+917D:0000FEFE282828AAFE6CAA28AAFEAA80AE80C2808280FE8082808300FF008200
+917E:0000FBFE20002000FBDEAA52AA52AA52DB5A8AD68A52FA528A528A52FA528AD6
+917F:0020FE1028FC2884FE84AAFCAA84AA84AEFCC2A282A4FE9882908288FEC48282
+9180:0050FE48288028FEFF90AA90AAFCAA90AE90C2FC8290FE90829082FEFE808280
+9181:0000FEFC28042804FE7CAA04AA04AAFEAE10C2928254FE3882548292FE508220
+9182:0048FE4828482848FEFEAA48AA48AAECAEDCC35A8248FE4882488248FE488248
+9183:0020FE2029FE2850FEA8AB26AAF8AAA8AEA8C2F882A8FEA882F882AAFE22821E
+9184:0040FE4028FE2882FF42AA7AAAA2AA22AFFEC22282AAFEAA82FA8202FE148208
+9185:0020FE1028FC2800FE84AA48AA00AAFEAE00C20082FCFE8482848284FEFC8284
+9186:0028FE24282E28F0FE28AA12AA2AAAD6AE28C22E82F0FE2482288212FE2A82C6
+9187:0020FE1028FE2800FE7CAA44AA7CAA00AE7CC2088210FEFE82108210FE508220
+9188:0020FEA228A22924FE50AA88AB04AA22AE20C2A482A4FF2882508288FF048202
+9189:0040FE2029FE2800FE88AA88AB54AA22AE00C22083FEFE2082208220FE208220
+918A:0000FEEE282228AAFE44AAAAAB12AA00AEEEC22A82AAFE4A824482A4FF2A8210
+918B:0048FE48284829FEFE48AA48ABFEAA00AEFCC2848284FEFC82848284FEFC8284
+918C:0000FEFC28842884FEFCAA84AA84AAFCAE00C2908292FEF482988292FED2828E
+918D:0000FE7C2844287CFE44AA7CAA00ABFEAE10C210825EFE50825082B0FE9E8300
+918E:0008F80C200A23FEFA08AA08AAE8AA0ADA0A8AEC8AACFAA88AEA8A1AFA268C42
+918F:0020FE2028FA2824FE28ABFEAA20AA40AEFCC3448244FE7C82448244FE7C8244
+9190:0100F93C212427E4F924A93CA924ABA4DAA48ABC8AA4FAA48BA48844F8548888
+9191:0000FEFC28142850FE5CAA50AA7EAA80AE7CC244827CFE44827C8244FE44824C
+9192:0000FE7C2844287CFE44AA7CAA10AA50AE7CC2908210FE7C82108210FEFE8200
+9193:0010FE1028FE2892FE92AA28AA28AA4AAE86C30082FEFEAA82AA82AAFEAA83FE
+9194:0620382008A47EA819202C504A880904FFFE04403FF82848303827C820083FF8
+9195:0020FE1029FE2800FE7CAA44AA7CAA00AEFEC2828282FEFE82828282FEFE8282
+9196:0000FE7C28442844FE7CAA44AA44AA7CAE00C2FE82AAFEAA82AA82AAFFFE8200
+9197:0008FEEC282828AAFE44AA44AA84AB7AAE28C22882FEFE288228824AFE4A8286
+9198:0010FE10287E2810FE10AAFEAA20AA42AEFEC20082FEFEAA82AA82AAFFFE8200
+9199:0050FE9628922892FED6AA92AA92AAFEAE10C2FC8244FE4482288210FE2882C6
+919A:0008FE4A292A28ACFE88AA3EAA08AB98AE9CC2AA82CAFE8882888340FE3E8200
+919B:0044FE4428FE2844FE10AA28AA44AA82AE7CC2108210FE7C82108210FEFE8200
+919C:0010FE2028FE2892FE92AAFEAA92AA92AEFEC2208224FE5A825E8290FE92830E
+919D:0044FE24282828FEFE10AA7CAA10AAFEAE20C220827CFE5082908310FEFE8200
+919E:0000FE7C28542854FE6CAA44AA7CAA00AE00C2FE82AAFEAA82AA82AAFFFE8200
+919F:08202AA44D28145022887FFE4002BFF404803FF82488287830083FF820083FF8
+91A0:0010FE10287C2854FE54AAFEAA28AA44AE82C30082FEFEAA82AA82AAFFFE8200
+91A1:0040FE2029FE2902FE50AA88AB44AA40AEFEC320823CFE20823E8220FE208220
+91A2:0020F82023FC2040F880A9F8AA88AC88D8F8880089FCF95489548954FBFE8800
+91A3:0020FE1028FE2890FEBCAA94AAFEAA94AEBCC29082BCFEA482A482A4FEBC8324
+91A4:083E4BC42A4829281BFE2908C8A80810FFFE04403FF82848303827C820083FF8
+91A5:0000FEFE282828FEFEAAAAAAAAFEAA00AE7CC20082FEFE1082548292FE508220
+91A6:0010FE20284428FEFE44AAAAAAEEAA10AE28C25482AAFE5082248248FE108260
+91A7:0000FBFE2200227CFA44AA44AA7CAA00DAEE8AAA8AAAFAAA8AEE8A00FBFE8800
+91A8:0020FE1028FE2828FE92AAAAAA82AAFEAE10C2FE82A2FEAA82BA8282FE8A8284
+91A9:0028FE2828FE2828FEFEAAAAAAFEAAAAAEFEC200827CFE44827C8244FE7C8244
+91AA:0000FEEE282228AAFE66AAAAAA10AA28AE44C3928220FEC8823282C4FE1882E0
+91AB:7F7848485E8664785F484A307F480084FFFE04403FF82848303827C820083FF8
+91AC:0440247C3CA805507C2825FE44888058FFFE04403FF82848303827C820083FF8
+91AD:0028FEAA286C2828FEFEAA44AA28AAFEAE10C27C8210FEFE82108228FE448282
+91AE:0028FE242840287EFEC8AB48AA7EAA48AE48C27E8248FE48827E8240FEAA832A
+91AF:0040F82023FE2040F884A9FEA8A8A8AAD9268A0089FCF95489548954FBFE8800
+91B0:0000FEFE282828FEFEAAAAFEAA00AA7CAE44C27C8244FE7C821082FEFE108210
+91B1:0024FBA820922514FA08AC04ABBAA8A8D8C68B808A3CFB8488A88890FAA88944
+91B2:0028FEFE28AA28FEFEAAAAFEAA00AAFEAE80C2BE8280FEFE82A882AAFEA48332
+91B3:0000FEFE28AA28FEFE10AAFEAA10ABFEAE44C22882FEFE1083FE8210FE108210
+91B4:0028FEFE28AA28FEFEAAAAFEAA00AAFEAE00C2FE8282FEFE82448228FEFE8200
+91B5:0040F87C204023FEFA42AA78ABC4AA3CDA008BFE8A40FBA48A588DB4FC5289B0
+91B6:0010FE1028282844FE82AA7CAA00AAEEAEAAC2AA82EEFE44824482AAFEAA8312
+91B7:0010FEFE28442828FEFEAA00AA7CAA44AE7CC244827CFE2082948342FE44823C
+91B8:0020FE1029FE2848FE84AB4AAAFCAA48AEFCC24883FEFE5482C88354FE628240
+91B9:0000FE7C281028FEFE92AA54AA10AA54AE00C2FE8210FEFE82AA82AAFEAA8286
+91BA:001CF9E0202023FEF820A9FCA9ACA974D9FC882089FCF8208BFE8800F9548A2A
+91BB:0020FBFE202021FCF800ABFEA802A9FCD8208BFE8800FBFE88048BBEFAA48B8C
+91BC:0110F91027FC2110F9F0AA08AAEAAEACDAA88AAA8EEAFA0688008AA4FA528C52
+91BD:0000F9FC202023FEFA22A9ACA820A9ACD8008BEE8AAAFAAA8AAA8AAAFBEE8AAA
+91BE:0040F82023FE2248FBFEAA48AAECAB5ADA488B248AA8FBFE8A708AA8FD268820
+91BF:0020FBFE224823FEFA48AAECAB5AAA48DA208A448A78FA148AFE8A10FA548CB2
+91C0:0010FEFE280028EEFEAAAAEEAA44AAFEAE44C2FE8244FEFE825082CAFF648242
+91C1:2FEC48246BAC48246BAC4AA4FFFE92921D7010101FF004401830EFEE04201860
+91C2:001EFBE021222094FBFEAA52ABFEA804DBC48A7E8BC4FA548BCC8A84FAD48B48
+91C3:03DEF80023DE2252FB5AAA52A820ABFEDA508BFE8A52FBFE8A928ADCFA928CCE
+91C4:0020FBFE224823FEFA48AAECAB5AAA48DA508BDE8A50FBDC8A508BDEFA508C50
+91C5:03DEFA5223DE2000FBFEAA00AAC8AA4EDBEA8AB28AEAFAAA8AEA8AB4FDE4882A
+91C6:001000F83F00010011100910092001007FFC03800540092011102108C1060100
+91C7:001000F83F00020011100910082001007FFC03800540092011102108C1060100
+91C8:0C00F1FC1104550439041104FDFC112031203920552051109110110812041402
+91C9:0C20F0201020542039FC1124FD241124312439FC552451249124112411FC1104
+91CA:0C00F3FC1104548838501020FCD81326302039FC5420502093FE102010201020
+91CB:0C00F1FC115455FC382011FCFC2013FE3088385055FC502093FE102010201020
+91CC:00003FF8210821083FF8210821083FF8010001003FF8010001000100FFFE0000
+91CD:001000F83F000100FFFE01001FF011101FF011101FF001003FF80100FFFE0000
+91CE:00007F7C490449287F104908497E7F12081408107F10081008100F10F0504020
+91CF:00001FF010101FF01010FFFE00001FF011101FF011101FF001001FF001007FFC
+91D0:08203E7E08A47F281C102A2849443FFE20002FF828882FF828884FF840809FFC
+91D1:0100010002800440082010102FE8C10601003FF80100111009100920FFFE0000
+91D2:10001000280024004200BC0010001000FE0010009400580050001E00F0004000
+91D3:10801080288024804280BC8010801080FE8010809480588450841E84F07C4000
+91D4:1000100028FE24044208BC1010201020FE4010409480588250821E82F07E4000
+91D5:100011FC280424084210BC2010201020FE2010209420582050201E20F0A04040
+91D6:1000100029FC24444244BC4410441044FE4410449444588450841F04F2284410
+91D7:10041004280424444244BC4410441044FE4410449444580450041E04F0144008
+91D8:100010002BFE24204220BC2010201020FE2010209420582050201E20F0A04040
+91D9:10401040284024404240BC5010481044FE4410409440584050401E40F0404040
+91DA:108010802880248043F0B89010901090FC9010909490589251121D12E20E4400
+91DB:102010202820242042FCBC2410241024FE2410449444584450841E84F1284210
+91DC:044008201850248803000CC03030C00E1FF0010001003FF80100111009207FFC
+91DD:10201020282024204220BC2013FE1020FE2010209420582050201E20F0204020
+91DE:10801040284024204220BC2010201050FE5010509448588850881E84F1044202
+91DF:10001010289024904090B89010901090FC9010909508590851081E04E2044402
+91E0:100010F0289024904290BC9010901090FE9010909490589250921F12F10E4200
+91E1:0820101021084284044008203018CFE6010001003FF8010011100920FFFE0000
+91E2:1000100029FC24444248BC481050105EFE4210429482588250821F02F1144208
+91E3:104010402840247C4284BC8411041044FE2410249404580450041E04F0284010
+91E4:08040804140822104120BE44080408087F10082249422A0408080F10F02040C0
+91E5:10201020282024204020B8A810A410A4FD2211229622582050201C20E0A04040
+91E6:1000100028FC24844284BC8410841084FE8410849484588450841EFCF0844000
+91E7:11041124292425244124B92411241124FD2411249524592451241E24E2044404
+91E8:100010FC280424084210BC20102011FEFE2010209420582050201E20F0A04040
+91E9:100011F0291025104110B91011901150FD5011109510591251121E12E20E4400
+91EA:100010FC282024204220BC20102011FEFE2010209420582050201E20F0A04040
+91EB:100010FC280024004200BDFE10401040FE8010FC9404580450041E04F0284010
+91EC:100010FC282024204220BC20102011FEFE2010209420582050201E20F0204020
+91ED:1000100028FC24204220BC2010201020FE2010209420582050201E20F1FE4000
+91EE:101010102810241043FEBC1010301030FE5010509490591050101E10F0504020
+91EF:104010202820240043FEBC8010801080FE8010809480588050801E80F0FC4000
+91F0:1000100029FC24244024B8A410A410A4FD2410249424584450441C84E1144208
+91F1:10201020282024204220BDFE10201020FE2010509450585050881E88F1044202
+91F2:1000100028FC24844284BC84108410FCFE8410809480588250821E82F07E4000
+91F3:10401040288024FE4100BA0010FC1008FC1010209440588051021D02E0FE4000
+91F4:1050104828482440425EBDE010401040FE4010409420582250121E0AF0064002
+91F5:100011F8288824C842A8BCA810881050FE5010509420582050501E88F1044202
+91F6:1020102028202520412CB934116413A4FD2411349528592251221D02E0FE4000
+91F7:10201020282024204020B82011FC1020FC2010209420582050201C20E3FE4000
+91F8:104010402840247C4244BC8410C41124FE1810089410581050201E40F0804100
+91F9:104010402840244043FEB88810881088FC8811089490585050201C50E0884304
+91FA:1008103C29E024204020B820102013FEFC2010209420582050201C20E0204020
+91FB:104010402840244041F8B84810481048FD4810C8944858A850AA1D0AE2064402
+91FC:1000100029FC24444044B94410C41044FC641054944C588650841D04E2284410
+91FD:1008101C29F025504150B95011501150FD5011489548594851441E44E2424400
+91FE:100011FE280824884088B888110811FEFC1810289448588851081E08E0284010
+91FF:1004100E28F024804280BC8010FE1088FE8810889488588850881F08F1084208
+9200:1000100029FC25244124B92411241124FDFC11009500590051021D02E0FE4000
+9201:10401020282025FE4240BC401040107CFE4410449444584450841E84F1284210
+9202:10201020282025FE4122BA2410201020FC5010509450585050901C92E112420E
+9203:100010FC284824484248BC48104811FEFE4810489448584850481E48F0884108
+9204:10081088284824484208BC8810481048FE08100E95F8580850081E08F0084008
+9205:100010FC288424844284BCFC10841084FE8410FC9484588450841E84F1144208
+9206:10081048284824484044B88410A41122FC2010409440584850841DFEE0824000
+9207:102010202820242041FCB82010201020FDFE10209450585050881C88E1044202
+9208:1000100029FE24104210BC2010201068FE6410A29522582050201E20F0204020
+9209:10201020282025FE4122B92211221122FD52114A958A590251021D02E10A4104
+920A:10001040282024104050B84010401144FD42114295425A4450441C44E03C4000
+920B:10A010A028A025244124BB2815301120FD6011A09520592251221D22E11E4100
+920C:10201020282025FC4024B82410241024FDFE10209450585050881C88E1044202
+920D:10201020282025FE4020B92411241124FD2411FC9424582050221C22E01E4000
+920E:10801080288024FC4104B90412441044FC8410A4951459F450141C04E0284010
+920F:100411E4282424244024B9E411041104FD0411E49424582450241C24E1444084
+9210:10201020285024504088B94412221020FC0011FC9404580850081C10E0104020
+9211:1008101C29E025004100B9FC11441144FD4411289528591051101E28E2444482
+9212:100013FC288424884088B890109C1084FD4411449528592852101E28E4444182
+9213:1008103C29E024204020B820102013FEFC2010209420582050201C20E1FC4000
+9214:10201020282024A842A4BCA211221120FE2410249428580850101E20F0C04300
+9215:100011F8284824484048B848104811F8FC8810889488588850881C88E3FE4000
+9216:10101090289024884108B904120415FAFC8810889488588851081D08E2284410
+9217:10401040288024884104BBFE10021090FC9010909490589051121D12E20E4400
+9218:10201020282025FE4020B820102011FCFC8410889448585050201C50E1884606
+9219:102010202820243E4220BC20102011FCFE8410889448585050201E50F1884606
+921A:10101110291025124112B91411D81110FD1011109510591251521D92E10E4000
+921B:1048104428442440425EBDE010401044FE4410489430582250521E8AF1064002
+921C:104010402840244043FEB84010801090FC90112095205A4852441C84E1FE4082
+921D:101010102890249042FEBC9011101010FE1011FE9410581050101E10F0104010
+921E:10401040288024FC4104BA0410841044FC4410149424584451841C04E0284010
+921F:100011FC282424244224BDFC11201120FF2011FE94225822502A1E24F0204020
+9220:100010F8288824884288BD06120011FCFE8410849448585050201E50F0884306
+9221:102010202820242041FCB92411241124FD2411FC9524582050201C20E0204020
+9222:102010202820242041FEB82010701070FCA810A89524592452221C20E0204020
+9223:100010FE281024104290BC9E10901090FE9010FE9402580250021E02F0144008
+9224:1000100028FC24844284BC8410841084FEFC10849484588450841E84F0FC4084
+9225:102010202820242442A4BCA410A81120FE2010509450585050881E88F1044202
+9226:10201020282024204220BDFE10201020FE2010509450585050881EC8F1244202
+9227:10401020280025FC4000B80010F01090FC9010909490589250921D12E10E4200
+9228:1000100029FC24004000B80013FE1090FC9010909490589051121D12E20E4400
+9229:10201010281024FE4282BC82108210FEFE8210809480588050801F00F1004200
+922A:100011FE290025004178B94811481148FD4811689550594251421D42E23E4400
+922B:10401020282025FE4288BC8810881088FE5010509420582050501E88F1044202
+922C:100010FC288424844284BC8410FC1090FE9010909490588850881E84F1044202
+922D:088008882E9028E028842E84F17C06C01830EFEE01003FF809200540FFFE0000
+922E:100011FC290425044104B9FC11001140FD4411489570594051421E42E23E4400
+922F:10201020292425244124B92411FC1020FC2011249524592451241D24E1FC4004
+9230:10401020280025FE4020B82011FC1124FD2411249524592451341D28E0204020
+9231:100011FC290425044104B9FC11201120FDFE11209520591051121D4AE1864102
+9232:1008101C29F025504150B95011501150FD5011489548596851541E74E2524400
+9233:100010002BFE24084008B9E811281128FD28112895E8592850081C08E0284010
+9234:10201020285024504088B92412121010FDFC10049408588850501C20E0104010
+9235:100011FE282024204020B9FE11221122FD52114A958A590251021D02E10A4104
+9236:10201020282024404248BC8411FE1082FE0010FC9484588450841E84F0FC4084
+9237:102010202820242043FEB82010201020FDFC11049504590451041D04E1FC4104
+9238:105010482848244043FEBC401040107CFEA410A494A8592851101E28F0444082
+9239:10101010281025FE4112B914111011FCFD4411449528592851101E28E2444482
+923A:1000100029FC24204020B82010201020FDFC10209428582450241C20E3FE4000
+923B:100010FC288424844284BC8410FC1080FE8010FE9482588250821E82F0FE4082
+923C:10801080288024FE4340BD401240107CFE4010409440587E50401E40F0404040
+923D:10201020282025FE4040B850109010FEFD92129294925892509A1C94E0104010
+923E:102010202820242041FCB92411241124FD2411FC9524592451241D24E1FC4104
+923F:1000100029FC25244124B92411241124FDFC11249524592451241D24E1FC4104
+9240:100011FC292425244124B9FC11241124FD2411FC9524582050201C20E0204020
+9241:10201020285024884104BA1210201040FD8810109420584451881C10E0604380
+9242:10201020282025FC4124B924112411FCFD241020952058C050401CA0E1184206
+9243:10401040288024FC4120BA2010201020FDFE10209450585050881C88E1044202
+9244:102010202920252041FCB92012201020FDFE10209450585050881C88E1044202
+9245:100010FE288024804280BCFC10841084FE84108494FC588050801E80F0FE4000
+9246:1020102028202420403EB82010201020FDFC11049504590451041D04E1FC4104
+9247:1080108028FE250042207D20912C11747BA411249534592851221D02E0FE4000
+9248:10201010281025FE4102BA0410801088FC9010A094C0588250821C82E07E4000
+9249:10201010281025FE4020B82010441084FDF810109420584450821DFEE0824000
+924A:100011FC284424444044B84410941088FD0010FC9484588450841C84E0FC4084
+924B:1080108029FC25044204BDF411141114FD1411F49504592851121D02E0FE4000
+924C:101C11E0282024204020BBFE10201070FC7010A894A8592452221C20E0204020
+924D:10401020282824084008B84810541152FD5211609660584450C41D44E23C4000
+924E:102010202920252041FCB92012201020FC2011FC9420582050201C20E3FE4000
+924F:100010F8288824884088B8F810881088FC8810F89488588850881C88E3FE4000
+9250:100010002BFE24204020B840104010FCFD8412849484588450841C84E0FC4084
+9251:10101010282024FC4284BC8410841084FEFC10849484588450841E84F0FC4084
+9252:10401020280025FE4020B82010201020FDFC10209420582050201C20E3FE4000
+9253:10801080288024FE4120BA20102011FCFD2411249524592451341D28E0204020
+9254:100011FE291025104110B97C11541154FD5411549554595C51101D10E1FE4000
+9255:100010FE2880248042BCBCA410A410A4FEA410A494BC58A450801E80F0FE4000
+9256:10401040287C24844188BA5010201050FC8813069460581050081CC0E0204010
+9257:108810882888248843FEBC8810881088FE8810F89488588850881E88F0F84088
+9258:10501050285025FC4054B85411FC1150FD5011FE94525852505A1C94E0904110
+9259:1000100029FC25044104B90411041104FDFC11049400589050881D04E2024402
+925A:20002080531E4A5282527A5222522252FA5222D22B5AB25460903890E1100210
+925B:100010F8288824884088B88811061200FC0010FC9484588450841C84E0FC4084
+925C:1088108828882508417EBB0815081148FD2811289508590851081D08E1284110
+925D:102010102810240041FEB80010041084FC8410489448584850501C10E1FE4000
+925E:202820245024482083FE7A2022242224FA2422282A28B29063123A2AE0460082
+925F:100010FE281024104220BC2010681064FEA211229420582050201E00F1FE4000
+9260:10201020282025FC4124B92411241124FD2413FE9420585050501C88E1044202
+9261:10201020292424A440A8B82011FC1020FC20102097FE582050201C20E0204020
+9262:102010202820242043FEB82010701070FCA810A895245AFA54201C20E0204020
+9263:10201020282025FC4020B820102013FEFC2010209440584850841DFEE0824000
+9264:10801080290025FC4204BC0411E41124FD24112495E4592450041C04E0284010
+9265:102010282824242041FCB82010701070FCA810A89524592452221C20E0204020
+9266:1000100029FE24104010B81010901090FC9E10909490589050901C90E3FE4000
+9267:100010FC288424A44094B884108413FEFD0411449524590451FE1C04E0284010
+9268:10801080288024FE4102B90412201020FCA810A49524592252221C20E0A04040
+9269:10201020285024504088B90412221020FCA810A49524592252221C20E0A04040
+926A:102410A428A424A442A4BDFE10A410A4FEA410A494BC588050801E80F0FE4000
+926B:110011002900251C43D4B95411541154FD5411549554595451541E5CE3544480
+926C:100011FC290425044104B9FC11041104FD0411FC9504590451041D04E1FC4104
+926D:1000100028FC24844284BC8410FC1084FE84108494FC588450001E00F1FE4000
+926E:10201020282025FC4124B924112411FCFD241124952459FC51241C20E0204020
+926F:10081048292825284128B90811081108FD0811089548599451141C22E0424082
+9270:100011FC2804240443F4B804100411E4FD241124952459E450041C04E0144008
+9271:10201010281025FE4100B91011101110FD1011209528592452441EFEE4424800
+9272:102010202820243C4220BC20102011FEFE2010209428582450221E20F0204020
+9273:10901090289024904090BB9210941098FC9010909490599252921C92E08E4080
+9274:04402440247C24902488250802800C603018CFE601003FF8092005407FFC0000
+9275:10201020282025FC4124B92411241124FDFC11249420582850241DFEE0824000
+9276:100213E22942254A414AB94A114A13EAFD4A114A954A594A51421E42E24A4444
+9277:104810482848244841FEB84810481048FC4811FE9400584850441C84E0824102
+9278:10401020282025FE4000B88811041202FC8810889450585050201C50E0884306
+9279:10201020287C24844148B83010201048FD90103E944259A450181C10E0604180
+927A:100013FE2888248840F8B888108810F8FC881088948E5BF850081C08E0084008
+927B:10401040287824884150B82010501088FD0610F89488588850881C88E0F84088
+927C:110410842888240041FEB88810881088FC8813FE9488588851081D08E2084408
+927D:201020145012481083FE7810201021D0F89020902890B08860EA3B8AE0060002
+927E:102010202848248441FEB81210901090FCFE1110941059FE50101C10E0104010
+927F:10201020285024884104BA0211FC1000FC0011FC9504590451041D04E1FC4104
+9280:100011F82908250841F8B908110811F8FD4411489530592051101D48E1864100
+9281:10401040288024FE4102BA0211F21112FD1211F29512591251F21C02E0144008
+9282:10821092289224924092B89212DA12B6FC9210929492589250921D12E1024202
+9283:10401020282025FE4040B888110411FEFC9210909490589051121D12E20E4400
+9284:10201020284025FC4104B90411741154FD5411549554597451041D04E1144108
+9285:100011FC290425044174B90411041174FD5411549554597451041D04E1144108
+9286:100013FE282024204040B9FC11041104FD0411FC9504590451041D04E1FC4104
+9287:1020102029FE24204020B8FC10201020FDFE107094A858A851241E22E4204020
+9288:1020102029FC24204020B82013FE1000FC20102095FC582050201C20E3FE4000
+9289:1020102029FC242443FEB82411FC1020FC2011FC9420582053FE1C20E0204020
+928A:202820245024482083FE7A2022242224FA2423A82A28B21062123C2AE4460882
+928B:10801088289C25704110BB1015101110FDFE11109510591051101D10E17C4100
+928C:10201020282025FE4040B84010BC1084FD88128894FE588850881C88E0A84090
+928D:100011FE282024404088B90411FE1022FC20102095FE582050201C20E3FE4000
+928E:00007DF01110119011521D12E20E450006C01830EFEE01003FF811100920FFFE
+928F:100011DC295425544154B954115413FEFD5411549554595451541ED4E224444C
+9290:00047F8408241F24212452240C243104C6CC1830EFEE01003FF811100920FFFE
+9291:10201120292025FC4120BA20102013FEFC9010909490589051121D12E212440E
+9292:100011DC288824884088B888108813DEFC8810889488588850881D08E1084208
+9293:10201020285024884104BA0211FC1020FC20102095FC582050201C20E3FE4000
+9294:100013FE281024204068B8A413221020FC00102094205BFE50201C20E0204020
+9295:102010202BFE242041FCB82411FC1120FDFE1022942A585450501C88E1044202
+9296:10201120292025FC4120BA20102013FEFC7010A894A8592451241E22E0204020
+9297:1008101C29E025004100B9FE11001100FD7C11449544594451441E7CE2444400
+9298:1040104028FC25044288B85010201040FC8011FC9684588450841C84E0FC4084
+9299:2020202053FE48508088790422FA2000FBFE20402880B1FC60043804E0280010
+929A:105010502850255242D4BC5810501058FED411529450585050921E92F112420E
+929B:1008103C29E024204020BBFE10201020FC2011FC9504590451041D04E1FC4104
+929C:11001100229C424084201BC0213E6108AFC8210829482588250821C82E282410
+929D:109010902890251041FEBB1015101138FD3811549554599251101D10E1104110
+929E:10001FF820085FC890481FC810481FE8011006C01830EFEE01003FF80920FFFE
+929F:101010922892249242FEBC0010101010FEFE10929492589A50941E10F0104010
+92A0:10401040284425F44048B85013FE1040FC801184969858E050821C82E07E4000
+92A1:10201020282027FE4020B82011FC1000FC0011FC9504590451041D04E1FC4104
+92A2:200021FC5000480083FE780020202022FBB220B428A8B12861243A24E4A20040
+92A3:210021005100491E87D27A5222522252FA5224922A92B11262923A5EE4520800
+92A4:10201020292424A440A8B820102013FEFC7010A894A8592451241E22E0204020
+92A5:10401020282025FE4040B84010A010A2FDA412989490588850881CA4E0C24080
+92A6:100011FE290225224122B92211FE1122FD221152954A598A51021D02E1FE4102
+92A7:104010442A4425484150B84017FE1090FC9010909490589251121D12E20E4400
+92A8:10401020282027FE4202BC44104013FEFC881088950858D050201C50E0884304
+92A9:1008103C29E024204020B9FC10201020FC2013FE9420584050881D04E3FE4102
+92AA:1020102029FE24404240BCFC10841184FEFC1084948458FC50841E84F0944088
+92AB:1080108028F825084210BDFC11241124FD2411FC9500590051021D02E0FE4000
+92AC:1040104429F424484050BBFE10401080FDFE1240948058FC50041C04E0284010
+92AD:10281024283E25E04220BC3C11E01020FE3E11E09422582450181E6AF1864002
+92AE:02000100FFFE0440145024484444010006C01830EFEE01003FF811100920FFFE
+92AF:102010202848248841F0B82010401088FDFC1024942058A851241E22E0A04040
+92B0:1088108829FE24884088B80011041104FC8810889450582050501C88E1044202
+92B1:100010F82888248840F8B820102011FCFD2411249524592451341D28E0204020
+92B2:100011FC290425FC4104B9FC10001000FDFC102094205BFE50201C20E0204020
+92B3:10101090288825084204BDFA11081108FD0811F89490589050901D12E212440E
+92B4:080C08F07E8008800EFE78880888290816C81830EFEE01003FF811100920FFFE
+92B5:1020104028F8248840F8B88810F8108AFC8C13F89418582850481C88E3284010
+92B6:102810242824242043FEB820112010B2FCB4106894A8592452221C20E0A04040
+92B7:10101092285224544210BCFE10821082FEFE1082948258FE50821E82F08A4084
+92B8:100013FE292025284128B9E811281128FD2811E89528592A513A1FEAE0264020
+92B9:101C11E02820242043FEB8A811241222FDF81088949058BE51021D02E2144408
+92BA:242024203DFC0420FC2024F8450006C01830EFEE01003FF809200540FFFE0000
+92BB:11081088289025FC4024B82411FC1120FD2011FE946258A2512A1E24E4204020
+92BC:1020102028A824A840A8B97412221020FC2011FC9420582050201C20E3FE4000
+92BD:101C13E02A20262043FEBA201290130AFE0611FA9508590851081D08E1F84108
+92BE:200021FC5020482083FE780020202022FBB220B428A8B12861243A24E4A20040
+92BF:100011F8280824D04020B9FC11241124FDFC1124952459FC51241D24E124410C
+92C0:100011FE2800240042FCBC8410841084FEFC10009484584450481E00F1FE4000
+92C1:100010FC288424844284BC8410FC1000FE0011FE9502590251021F02F1FE4102
+92C2:1080108028FE250042FCB88410A41094FDFE10849524591451FE1C04E0284010
+92C3:1040102029FC25044104B9FC11041104FDFC11209522591451081D44E1824100
+92C4:100013FE282024A44128B85010881104FC0010FC9484588850501C20E0D84706
+92C5:1040102029FC24004088B85013FE1020FC20102095FC582050201C20E0204020
+92C6:108010FC7D04104410341CC4E11406C81830EFEE01003FF809200540FFFE0000
+92C7:100011FC2904250441FCB904110411FCFD04110495FC580050881C84E1024202
+92C8:101C09E0402024200BFE70501088110406C01830EFEE01003FF811100920FFFE
+92C9:102010202BFE24204020B9FC11241124FDFC1020947058A851241E22E0204020
+92CA:10881084290226224020B85010881104FE0210FC9484588450841C84E0FC4084
+92CB:2004200E53B8488880887928212E23A8F8A822A82AA8B13E61003A80E47E0800
+92CC:2000200653B8488880887908213E2388F88822882A88B13E61003A80E47E0800
+92CD:2020202053FE482080207BFE22022404F9F820102820B3FE60203820E0A00040
+92CE:1020101029FE25024204B8F810001000FDFE10509450585050921C92E10E4200
+92CF:10201020282025FC4020B8A810A810A8FD7412229450585050881C88E1044202
+92D0:1040102029FE25024244B84011FE1040FC501090949058A051241D42E27E4422
+92D1:104010402888250443FEB80210881144FE4210F895885A5050201C50E1884606
+92D2:1040104028FC24884150B82010D81326FCF8102094F8582053FE1C20E0204020
+92D3:204220E25382488A808A788A23EA208AF98A21CA2AAAB28264823882E08A0084
+92D4:1080108028F825084210B9FC11241124FD2411FC9450585050901C92E112420E
+92D5:2020202050204BFE80207820202021FCF840202028A4B282628A3A8AE4780000
+92D6:1004101E29E024224112B89410801020FDFE1044948459C850301C28E0C44302
+92D7:100010F82888248840F8B80011FC1104FD0411FC9504590451FC1D04E1144108
+92D8:100011FC2904250441FCB800100011FCFC20102097FE582050501C88E1044202
+92D9:100011FE2820242042FCBC44104411FEFE00100094FC588450841E84F0FC4084
+92DA:1040104024FE6488A55024202450218806C41830EFEE01003FF811100920FFFE
+92DB:2020202051FC4924812479FC20202020FBFE22222A22B3FE62223820E0200020
+92DC:100011FC290425044104B90411FC1020FC201120953E592051201EA0E47E4800
+92DD:1004101E29E024224112B89410801008FDFE10089488584850481C08E0284010
+92DE:100011FE280024924124BA4811241092FC0011FE9420582050201C20E3FE4000
+92DF:100011FC280424FC4004B9FC100013FEFE0211F89488588850501C20E0D84306
+92E0:100011FE29002500417CB900110011FEFD5011529554594851481E44E2524460
+92E1:10201020285024884144BA2210F81008FC10102095FC590451041D04E1FC4104
+92E2:1008103C29C024044144B8A8100011F8FC10102097FE582050201C20E0A04040
+92E3:200027DE50924C9284947C9427D82094F99221922A92B29A64943890E2900110
+92E4:2008200853C84A48825E7A4A23CA224AFA4A23CA2A4AB24A626A3BD2E6120026
+92E5:100011FC290425044104B9FC10001000FDFE1020942059FC50201C20E3FE4000
+92E6:100011FC2904250441FCB900110011FEFD02117A954A594A527A1E02E4144008
+92E7:100011F82908250841F8B908110811F8FD08110895F8589050901D12E212440E
+92E8:201020D85394489480907BFE20902094F89420D82B98B09060AA38CAE2860102
+92E9:1048104829FE24484248BC20101011FEFE8010809480588050801E80F0FC4000
+92EA:102810242BFE24204020B9FC11241124FDFC1124952459FC51241D24E124410C
+92EB:03043C0404247FA40E2415246484050C06C01830EFEE01003FF811100920FFFE
+92EC:101C11E0FD0011FC1D04F1681210312806C41830EFEE01003FF811100920FFFE
+92ED:110410842888241041FCB90411041104FDFC10509450589050921D12E20E4400
+92EE:202820245024482083FE7A2022242224FBA422A82AA8B29062923DAAE4460882
+92EF:10201120292025FC4120BA20102013FEFC00100095FC590451041D04E1FC4104
+92F0:100011FC2924252441FCB924112411FCFC20102095FC582050201C20E3FE4000
+92F1:201020145012481083FE781020902050F84820082888B2A8629A3AAAE4660002
+92F2:1010103829C025004100B9FC11101110FD10111097FE580050901D08E2044402
+92F3:102010202BFE242041FCB84013FE1048FC8810FE9508594852281C08E0284010
+92F4:102010202BFE24204020B9FC11041104FD0411FC9450585050921C92E112420E
+92F5:101C11E02820242043FEB8A811241222FC0010F89488588850881C8AE10A4206
+92F6:1020101029FE24204248BC8411FE1002FEA810A894A858A850A81EAAF12A4206
+92F7:200027E0525E4A5282527BD222522254FBD422542A48B2E867543854E0620040
+92F8:100011FC2904250441FCB910111011FEFD101110957C594451441D44E17C4244
+92F9:100010FC288024F84080B8F8108013FEFD4011249528591051081D44E1824100
+92FA:2040202053FE4A028504790021DE2252FA5223522C9AB09461103912E212040E
+92FB:7E7C48047E4442287E1048287EC4010006C01830EFEE01003FF811100920FFFE
+92FC:200023FE52024A8A82527BFE22222222FAAA22AA2AAAB2FA62023A02E20A0204
+92FD:10201020283E242041FCB90411FC1104FDFC112494205BFE50201C20E0204020
+92FE:1040104028FE24824142B87A10A21022FDFE102294AA58AA50FA1C02E0144008
+92FF:1020112428A424A84020B9FC11041104FD7411549554595451741D04E1144108
+9300:10201020285024884104BAFA100011FCFD54115495FC595451541D54E104410C
+9301:100011FC2924252441FCB924112411FCFC2011FE947058A851241E22E0204020
+9302:1020102029FC24204020BBFE10881144FE4210F895885A5050201C50E1884606
+9303:102009FE4122252009FC110472681410112806C41830EFEE01003FF80920FFFE
+9304:108010F82888250841F0B810101013FEFC201222957458A851241E22E0A04040
+9305:0640387C08947E241C442A94490806C01830EFEE01003FF809200540FFFE0000
+9306:102010202BFE242041FCB82013FE1000FDFC110495FC590451FC1D04E1144108
+9307:1080104029FC24004108B888109013FEFC00100095FC590451041D04E1FC4104
+9308:1020112428A8242041FCB84013FE1088FD0412FA9488588850A81C92E082407E
+9309:101C13E02A2027FE4220BA92130A1206FDFC1104950459FC51041D04E1FC4104
+930A:1040102029FE24004088B88811541222FC00102095FE582050201C20E0204020
+930B:200023DE52524A5282527BDE22522252FA5223DE2A52B25262523A52E55208A6
+930C:102011242924252441FCB80011FE1100FD7C1110951059FE51101E10E2104410
+930D:1040108029FC25244124B9FC11241144FDFC109095105BFE50101C10E0104010
+930E:10401040287C24844108BA00102011CEFD02110295CE590251021D02E1FE4102
+930F:100013FE285024504050B9DC11041104FD0411DC9450585050501C50E3FE4000
+9310:10A01090288025FE4110BB1015FC1110FD1011FC9510591051101DFEE1004100
+9311:2040202053FC4A0482047BFC22002228FA2423FE2A20B25062503C88E5040A02
+9312:2000277E55044D048574755426542554F5542554A574755426043404C4140408
+9313:10881048285025FC4020B82011FC1020FC2013FE9450585050901C92E112420E
+9314:102010222BB424A840A8B92412A21040FDFC1104950459FC51041D04E1FC4104
+9315:100011FC2904250441FCB904110411FCFC00111295D4591851101D52E192410E
+9316:08000E7C08047F4408282A104928194406C01830EFEE01003FF811100920FFFE
+9317:101C11E02820242043FEB8A811241242FC4013FE9488590850D01C30E0484184
+9318:2008203C51E0482083FE78A820A820A8FBFE20A828A8B3FE60203820E1FC0000
+9319:10921092292426484124B89210921000FDFE1122952259FE51221D22E1FE4102
+931A:1080108028F825084210B9FC10241024FDFE1024942459FC50241C20E0A04040
+931B:102010202BFE245040A8B92412FA1020FCA8108897FE588850881C88E1084208
+931C:202020205050488881447A2221F82008F850202028A4B282628A3A8AE4780000
+931D:2040202053FE4A02800079FC20002000FBFE20202928B12462223C22E0A00040
+931E:104010202BFE240041FCB90411FC1000FDFC100894105BFE50201C20E0A04040
+931F:102010A228A225244050B88813041022FC2010A494A4592850501C88E1044202
+9320:2040202053FE4A028404780023FE2020F8202120293CB12062A03A60E43E0800
+9321:1020102029FC24504088B90413FE1008FDE81128952859E851281C08E0284010
+9322:10481044285E25E04228BC12106A1196FE48105E95E0582450281E12F06A4186
+9323:200023DE5042494A8084794A22522420F80023DE2852B15260943948E2540422
+9324:108810882BFE24884288BCF810881088FEF8108894885BFE50001E88F1044202
+9325:104010202BFE24804104BBFE100211FCFD0411FC950459FC51041D04E1144108
+9326:1020104028FC248440FCB88410FC1020FC2011FE95225922512A1D24E0204020
+9327:1020101029FE25024204BCF810881088FEF81080948058FC50841E84F0FC4084
+9328:108810882BFE24884088B80011FC1124FD24112495FC592451241D24E1FC4104
+9329:10F81088288824F84088B88810F81000FDFC1104950459FC51041D04E1FC4104
+932A:10501050285025FC4154B954115411FCFD54115495545BFE50001C50E0884104
+932B:100010FC2884248440FCB884108410FCFC4010FE952A5A4A50921D22E04A4084
+932C:102010202BFE242041FCB92411FC1124FDFC1020947058A851241E22E0204020
+932D:100011FC292425244174B92411FC1104FD7411549554597451041E04E2144408
+932E:100011FC290425244124B9FC11241124FD7411549554597451041D04E1FC4104
+932F:10481048284825FE4248BC4811FE1000FEFC1084948458FC50841E84F0FC4084
+9330:10201020282025FE4020B87010A810A8FD2412229420580051541D2AE22A4000
+9331:010002800C603018DFF601003FF8111009207FFC00007EFE08103E7C08107EFE
+9332:100011F82808240841F8B808100813FEFC201222957458A851241E22E0A04040
+9333:100011FC280824104020BBFE102010A0FC4011FC9554595451541D54E3FE4000
+9334:1020102029FC24204020BBFE10881104FE22102095FC582050201C20E3FE4000
+9335:108810882BFE24884088B85010501094FD941298949058B250D21C92E08E4080
+9336:2020202053FE4820802079FC20202020FBFE204028A4B1A862903C88E0C60080
+9337:20882088208857E8888873E822A823E8FAA823E82888B7E8608A388AE08A0086
+9338:2020202050204BFE8020792421242124FAAA207028A8B0A861243A22E4200020
+9339:10201120293C25204120BBFE100011FCFD0411FC950459FC51041D04E1144108
+933A:110811082BFE25084148B82013FE1080FC8010F89488588850881D08E1284210
+933B:2010201451D2481280107BFE20102090F89022D02A90B290628A3AEAE7060202
+933C:2020202053FE48508088790422FA2000F80023FE2820B12461223A22E0A00040
+933D:100013FE282024A44128B85010881144FC4010FC95845A8850501C20E0D84706
+933E:1004FF7828407F7E08480F48F888090806C01830EFEE01003FF811100920FFFE
+933F:10201020283E242041FEB922113811E0FD22111E9500597852481E4AE48A4906
+9340:100011FC290425FC4104B9FC100011FEFC0813FE9408590850881C08E0284010
+9341:2010209057104C3E8422744427902510F5102510A528752825283944C9441082
+9342:10201020285024884104BA0210F81020FC2011FC9420592450A41CA8E3FE4000
+9343:2080208050FC4954825478A421242244F89421082840B0A462AA3A8AE4780000
+9344:104010202BFE24004000B9FC11041104FDFC10209528592452221C22E0A04040
+9345:221021102110547C8A1072102010217EF91022102E20B22462423AFEE2420000
+9346:200023DE52524A5283DE7A52225223DEFA0222022A02B20262023A02E20A0204
+9347:1110111229D425184152B992112E1040FDFC1104950459FC51041D04E1FC4104
+9348:108810882BFE248840A8B82011FC1124FD24112497FE582050501C88E1044202
+9349:100011FC2904250441FCB904110411FCFC0013FE94205920513C1D20E2A0447E
+934A:102010202BFE242041FCB92411AC1174FD2411FC9420587050A81D24E2224020
+934B:100010F82888248840E8B8A810A811FCFD0411749554595451741D04E1144108
+934C:0020112049FC22200BFE10907092110E16C01830EFEE01003FF811100920FFFE
+934D:2040202053FE4A4882487BFE22482278FA0022FC2A44B24862283C10E4680986
+934E:1008101C29F025104110B9FE1110117CFD44117C9544597C51441E44E27C4444
+934F:1020102028FC244441FEB80010FC1084FCFC102095FE582051201DFEE0204020
+9350:2000208852524A2282527A8A220223FEF88821442A7AB08861503820E0D80706
+9351:1040104028FE248041FCBA8410FC1084FCFC1040947C58C451281C10E0684186
+9352:100010FC2848243041FEB85210941110FE30102095FE587050A81D24E2224020
+9353:100010F82888248840F8B80013FE1088FCF8108894F85888509E1DE8E0084008
+9354:200023DE52524A5283DE780021FC2000FBFE20802900B1FC60043804E0280010
+9355:100013FE2A22242043FEB82011FC1124FDFC112495FC582053FE1C20E0204020
+9356:108810882BFE248840F8B88810F81088FC8813FE9500594851841D00E1FE4000
+9357:1040102029FC24004088B85013FE1222FC2411FC9524592451341D28E0204020
+9358:200223C252424A5283D27A52225223D2FA5222522BD2B00261823942E24A0404
+9359:1090089043FC2090089017FE7090110816C41830EFEE01003FF811100920FFFE
+935A:100010FC288424FC4084B8FC100011FEFC8010FE952A5A4A50921D22E0544088
+935B:2080233852284A2883A87A462200227CFBA422242A28B3A866103A28E2440282
+935C:200023DE52424A4282427BDE2200223EFBD222122A14B3D462083A14E2240242
+935D:11FC1124292425FC4124B92411FC1020FC2013FE96225A2A52FA1E0AE2024206
+935E:10201020283E24204020B9FC110411FCFD0411FC950459FC50001C88E1044202
+935F:100011FC290425FC4104B9FC10201120FDFE1220942059FC50201C20E3FE4000
+9360:1020104028FC248440FCB88410FC1000FDFE1020942058FC50201C20E1FE4000
+9361:100011FC2924252441FCB924112411FCFC0013FE9520592251141D48E1844102
+9362:100010FE2800247C4244BC44107C1000FEFE1092949258FE50921E92F0FE4082
+9363:1048104829FE24484200BDFC10441044FE94110896FC588450841E84F0FC4084
+9364:1008103C29E024204020BBFE102010A0FD2C1124952459AC51241D24E1FC4104
+9365:1080109E2BEA248A41CAB88A13EA1092FCA6102097FE582050501C88E1044602
+9366:22102110211057BE8A28724823AA22AEFABA22EA2AAEB2A864AA3CA2E9A2101E
+9367:1080108028FE25024242B9FA100211F2FC0211F2940259F251121DF2E0144008
+9368:101011D428582652418CB888110412FAFC20102095FE582050501C88E1044202
+9369:108810882BFE248840A8B82013FE1040FC8010FC95845A8450841C84E0FC4084
+936A:00207E20247E1884FF2829104A28994406C01830EFEE01003FF811100920FFFE
+936B:0620382008A47EA819202C504A88090406C01830EFEE01003FF811100920FFFE
+936C:208821C857084908812A712A27AC2148F3082388A554751429143124C1240142
+936D:108010BC2884250841FEBB201520117CFD90111095FE591051281D28E1444182
+936E:204020A051104A0885F6780023C42254FA5423D42A54B25463D43A44E25402C8
+936F:2080208050FC495482D478B4212C2244F89421082840B0A462AA3A8AE4780000
+9370:101E13E0284425244088B9FC10401040FDFE108094FC594451281E10E0684186
+9371:2048214851484BFE8148794821782100F9FE20202BFEB07060A83924E6220020
+9372:100011FC290425FC4110B9FE1110114AFD86100095FC590451FC1D04E1FC4104
+9373:3F2024203F3E21403F5024883F08010006C01830EFEE01003FF811100920FFFE
+9374:102011242924252441FCB80013FE1020FC4011FC9554595451541D54E154410C
+9375:20102010577C491481FE7214227C2710F17C2510A5FE721022103500C8FE0000
+9376:100011FC2924252441FCB924112411FCFC2010109454594251421D4AE2384000
+9377:102010202BFE24504088BB2611FC1020FC2013FE9400582051FC1C20E02043FE
+9378:1080109E289225D24092B89E109211D2FD52115E9552595251D21C22E02A4044
+9379:104010202BFE26024404B9FC100011FCFD0411FC950459FC51041C00E3FE4000
+937A:1020102229FA24244028BBFE10201040FCFC1184968458FC50841C84E0FC4084
+937B:100011FC290425FC4104B9FC108011FEFE2211229552590251FA1C02E0144008
+937C:2008200C500A4BFE82087A0822E8220AFA0A22EC2AACB2A862EA3A1AE2260442
+937D:1040102029FE25024102B9FE11001100FDFE11AA96AA5AFE54AA1CAAE0A24086
+937E:1008103C29E0242043FEB82011FC1124FDFC112495FC582051FC1C20E3FE4000
+937F:1052105228A425FE42A4BC5210521000FEFE1092949258FE50921E92F0FE4082
+9380:1090109E28A225544108BB5415621140FD4411589542594451181D02E10C4130
+9381:20002FDE54924C928494779424982494F7922492A49275DA2E943090C0900090
+9382:110410882BFE24204020B9FC10201020FDFE100094205BFE50201C50E0884306
+9383:2008241C52E04A80888C74B024A822AAF2AC24A8ACA874A824A43524C5320220
+9384:104010202BFE240041FCB90411041104FDFC10529494598852881CA4E0C24080
+9385:11FC1124292425FC4124B92411FC1050FC881104968A588850881C88E1084208
+9386:2108208850904BFE80007BC422542254FBD422542A54B3D462543A44E25402C8
+9387:100011FC2924252441FCB900117C1144FD44117C9544597C51441E44E27C4444
+9388:10841044284825FE4020B8FC102011FEFC40108094FE591052101C10E1FE4000
+9389:100011FC290425FC4104B9FC100013DEFC421252954A58C6535A1C42E14A4084
+938A:1020101029FE24844048B9FE11021224FC1011FE9440587C50441C84E0944108
+938B:2040202053FE4A02842479FC202021FCF82023FE2820B1FC61043904E1FC0104
+938C:10881050280025FE4050B9FC105413FEFC5411FC945058D851541E52E0504050
+938D:2020202053FE482083FE7A42248C21F0F82020442BFEB02261283A24E4A40040
+938E:2100210051FC4A0085F8780023F82088FAA821C82BF8B08A61CA3AAAE0860082
+938F:204017FE8090490813FCE1502252244E010006C01830EFEE01003FF80920FFFE
+9390:1008103C2BC024044244B92811FC1220FC2013FE9420592451241D24E1FC4004
+9391:1020102028FC24204020B9FE10401084FDFE100295FC595451541D54E3FE4000
+9392:100011FE2900257E4100B9FE11541148FD641142950459FE51441E24E204440C
+9393:2090208851044A42848879FC20042000FBDE20422A52B14A62523842E14A0084
+9394:104010202BFE26024050B88811241050FC88110496FA588850881C88E0F84088
+9395:1020101029FE2510417CB91411FE1114FD7C1110957C594451441E44E27C4444
+9396:1020112428A8242041FCB904110411FCFD0411FC9504590451FC1C00E0884104
+9397:102010202850244840A4B9FE128410FCFC8410FC948058FC51441D44E27C4044
+9398:200023FE500049FC8104790421FC2000FBFE228A2A52B3FE62223A22E22A0204
+9399:2440225E5292481287D2791E25522552FD5227DE2952B11262123A22E42A0844
+939A:10101220297C25444044B87C13401140FD7C11449544597C51441E80E47E4000
+939B:102810242BFE242041FCB92411FC1124FDFC112494085BFE50881C48E0484018
+939C:10003E782A482248FE862B7842484A30854806C41830EFEE01003FF80920FFFE
+939D:108810882BFE24884020B85010881104FEFA1000940059FC51041D04E1FC4104
+939E:1020104029FC25044154B92411541104FDFC1000951259D451181D52E192410E
+939F:21F820885070498C80007BDE2252218CFA5220202BFEB07060A83924E6220020
+93A0:200023FE52524A5283FE7800200023FEF8202020293CB12061203920E7FE0000
+93A1:2084204450484BFE808478842108214AFA52239C2884B10861083A52E3DE0042
+93A2:1040108029FC25044104B9FC110011FEFD0011FE94025AAA52AA1C02E0144008
+93A3:08202AA44D28145022887FFE410286C41830EFEE01003FF809200540FFFE0000
+93A4:100011FC290425FC4104B9FC10201124FCA8102097FE589050901D12E212440E
+93A5:108011F822886870AB8E282029FC28A8216406C01830EFEE01003FF80920FFFE
+93A6:204023BE52124A9282527AAA23242040FBFE22222A22B3FE62223A22E3FE0202
+93A7:102011242924252441FCB80013FE1000FDFC1104950459FC50881C50E3FE4000
+93A8:10A0109029FE272041FCB92011FC1120FDFE110094205BFE50201C20E0204020
+93A9:2000245C529449148294745421262100F7DC2114A594755429483108C5140222
+93AA:10A0112C2924252441ACB924112411FCFC2011FC9488585050201C50E0884306
+93AB:1020104029FC25044154B92411541104FC881144967A588851501C20E0D84706
+93AC:1020101029FE240040FCB88410FC1000FDFE1102957A594A517A1D02E10A4104
+93AD:111811E0290224FE4000B97C1144117CFD44117C9544597C51001DFEE0884104
+93AE:102010202BFE242041FCB90411FC1104FDFC110495FC590453FE1C88E1044202
+93AF:2100209E53D24A5282547BD422582254FBD222122A92B25A62D43B50E2100010
+93B0:10881050280025FC4000B85010881104FC0011FC9554595451541D54E3FE4000
+93B1:1020102029FC242043FEB80011FC1104FD0411FC9452589451881EA4E0C24080
+93B2:1020112428A8242043FEBA02100011FCFD04110495FC585050501C92E112420E
+93B3:1020104029FC250441FCB90411FC1104FDFC102095FE587050A81D24E2224020
+93B4:1020104029FC250441FCB90411FC1104FDFC1040942058A4528A1E8AE4784000
+93B5:2040202053FE4A02800079FC204020A2FB3420582894B33460523890E3500020
+93B6:100013FE280825E84128B9E8100013FEFC0811E89528592851E81C08E0284010
+93B7:200021FE512049FC812079FC21202120F9FE20022AAAB2AA62AA3A02E0140008
+93B8:20A0209051FE4B2085FC792021FC2120F9FE21002BFCB088609E3902E20A0404
+93B9:102210122914248040BEB808100811BEFC8810889494589250A21D40E23E4000
+93BA:22002100513C482487A478A4213C2124FBA42564293CB12461243924E17E0100
+93BB:109211242A4825244092B80011FC1104FDFC110495FC590451FC1C88E1044202
+93BC:1020103C282025FE4122B93811E2111EFD0411789510597C51101EFEE2104430
+93BD:2020222253FE488081F87A882070238EF82021FC2820B1FC60203BFEE0200020
+93BE:100010F82888248840F8B888108810F8FC0011FC9554595451541D54E3FE4000
+93BF:10201050288825744202B8F8108810F8FC0C11F0942059FC50201DFEE0204060
+93C0:20202020503E482080207BFE22022326FA8A22522B26B252628A3B26E3FE0202
+93C1:112412482924240041FCB92411FC1124FDFC102097FE587050A81D24E6224020
+93C2:200023FE52004A7C82447A44227C2200FAEE22AA2AAAB2AA62EE3A00E3FE0000
+93C3:2220212051204FBE82407A2023BC22D0FA9022902AFEB29064A83DA8E8441082
+93C4:102013FE282025FC4124B9FC112411FCFC2213FE94085BFE51081C88E0284010
+93C5:2120213C214452A88A1076A82AC622BCFAA422BC2AA4B2BC62243A24E224022C
+93C6:100011FC292427FE4124B9FC100011FCFD0411FC950459FC51041DFCE0884104
+93C7:22102110211057BE8A40720023BE228AFA8822A82AAEB2A864A83DA8E85E1080
+93C8:2010201052FE4910817C7854207C2354F97C211029FEB11061103A90E47E0000
+93C9:2108210857C84908811E77D225642540F7C82108A388754829543114C1240142
+93CA:08207F20083E7E440884FF2820103E28434486C21830EFEE01003FF80920FFFE
+93CB:2088208853FE4888808878F8202023FEFA2223322AAAB37662223A22E22A0224
+93CC:108810882BFE24884000B9FC110411FCFD0411FC94205BFE50501C88E1044202
+93CD:100011FC292425FC4124B9FC10401088FDF0102094445BFE50221D24E2224060
+93CE:200021FC512449FC812479FC20A820A8FBFE20A828A8B1FC60203BFEE0200020
+93CF:208823DE508849DC80887BDE20882000FBFC20042804B1FC60043804E3FC0004
+93D0:200023DE50424A52814A7A52202820C4FB1220602988B03261C43818E0600380
+93D1:104010202BFE24884050BBFE122212FAFE2212FA968A5A8A52FA1E02E20A4204
+93D2:2040208851FC490882527BFE20502188FE2620C02B10B06463883830E0C00700
+93D3:1020104029FC2524417CB98C11541124FD5411FC9420581051541D42E14A4238
+93D4:104010202BFE26024000B9FC102011FCFD2411FC952459FC50001C88E1044202
+93D5:2040202053FE4A5082507BFE22522252FBFE22002A92B2D462983C92E4D2088E
+93D6:00803FFE22203FFC22243FFC242027BC246227BE23182DF6204047FC42488FFE
+93D7:200023DC52944BD482547BC822882294FBE220002820B1FC60203820E3FE0000
+93D8:20882288529E4AAA82947B88209020A4F88427BE2A84B2A462943A84E4940088
+93D9:102012222BFE24904088B9FE13101510FDFE1110951059FE51101D10E1FE4100
+93DA:200C200A50084BFE82087A48226A224AFBFA224C2A4CB2EC635A3C4AE4D60822
+93DB:1020112428A827FE4202B8F810881088FCF8102095FC592451241D34E1284020
+93DC:1020112428A827FE4202B8F810881088FCF81020942059FC50201C20E3FE4000
+93DD:100011F8290825F84108B9F8100013FCFE9413FC940059F850901C60E1984606
+93DE:101011FE2910257C4114B9FE1114117CFD10117C9554597C51541E7CE254444C
+93DF:1020101029FE24004084B84811FE1110FD50117E95905910517E1E10E21044FE
+93E0:2020247C52844948803078CE2610227CFA10227C2A10B2FE62103A10E5FE0800
+93E1:1040102029FC24884050BBFE100011FCFD0411FC950459FC50901C92E112460E
+93E2:100013FE285025FC4154B95411FC1000FDFC100097FE582050A81D24E2A24040
+93E3:1040102029FE25004148B94811FE1148FD4811489578590052D41EAAE52A4800
+93E4:102011FC292427FE4124B9FC102011FCFD2411FC94405BFE50881DD0E070438C
+93E5:102010102BFE26024080B8FE11101320FD7C11449544597C51441D44E17C4144
+93E6:112411242A2424A441547D4A9392150879081128952E592851281D58E14E4180
+93E7:08007F7808483E4800863E782A483E30414886C41830EFEE01003FF80920FFFE
+93E8:08047F7808403E402A7E3E482A48FF48098806C01830EFEE01003FF80920FFFE
+93E9:21002102511C4FD0811077D0255E27D4F55427D4A11477D421143124C1240144
+93EA:2090209057FE489083FC7A9423FC2294FBFC200029F8B10861F83908E1F80108
+93EB:2062238A208A57EA888A71CA22A2248AF8A420202BFEB07060A83924E2220020
+93EC:2040207C50404BFE82427A7823C4223CFA0822F02B24B2A865FE3C20E8A00040
+93ED:201C21E05020492480A87BFE207020A8F92422222840B02462A23A8AE4880078
+93EE:1020101029FE2510417CB91411FE1114FD7C11109592595451381E54E2924430
+93EF:2020202053FE482082AA792422AA2020FAAA21242AAAB05060503888E1040602
+93F0:2020222252224BFE80007BDE22522252FBDE22522A52B3DE62523A52E55A08A4
+93F1:102011FC2888245043FEB80011FC1104FDFC110495FC582053FE1C20E0204020
+93F2:202023FE504848F080207BFE22422090F9F820282920B1FC62203BFEE0200020
+93F3:2104208850004BFE82227AAA22722222FBFE200029FCB10461FC3904E1FC0104
+93F4:2010279054BC4CA484C477A821102128F14625C0A53C7524252435A4CE3C0024
+93F5:108813FE2888240041FCB8A810A813FEFCA810A895FC582053FE1C20E0204020
+93F6:10A0109029FE272041FCB92011FC1120FDFE110094205BFE50701CA8E3264020
+93F7:105012522954245043FEB888105013FEFC2011FC94205BFE50501C88E1044602
+93F8:2020202053FE482081FC792421FC2124F9FC20222BFEB04260243AA2E28A0478
+93F9:200023BE50A248A280BE7B882208223EFA2A23AA28AAB0BE6088388AE57E0202
+93FA:202423A8209255148A08740423BA20A8F8C623802A3CB38460A83890E2A80144
+93FB:2020212450A84BFE80A8792422222104F90421DE2A44B554609E3904E2040404
+93FC:2210221053DE4D2880A4782023FE2020FBFE22222A2AB27460A83924E6220020
+93FD:204023F850484FFE804873F820402554F75C2444A7FC7444275C3554C5540844
+93FE:2288228857C84A90829E77D4202427D4F45427D4A45477C824483454C46404C2
+93FF:2020212450A84BFE820278F820882088F8F820202BFEB07060A83924E2220020
+9400:102011FC292425FC4020BBFE100011FCFD0411FC950459FC51041DFCE0884104
+9401:22402242525C4FF082507BD0225E23D4FA5422542FF4B01462943C64E8240044
+9402:200023FE50504BDE82527A5223DE2050FBFE22222A22B3FE62223A22E3FE0202
+9403:2020202051FC482083FE7908239C2108F988263E2800B3FE60903890E112020E
+9404:1088108829FC24884088BBFE102011FCFD2411FC952459FC50001C88E1044202
+9405:49202A3E7F4849485DA86B104928414406C01830EFEE01003FF811100920FFFE
+9406:010878904BFC504049A4445855B4485241B046C01830EFEE01003FF80920FFFE
+9407:103C13E0292424A843FEB8A811241202FDFC1124952459FC51241D24E1FC4104
+9408:101811E0284027FE4088B97412521070FC0011FC9504597451541D74E104410C
+9409:100013DE2A5227DE4210BA5211CE1000FC8813FE9488588853FE1C88E1044202
+940A:2000277C55444D7C8544757C260025FEF540257EA5AA752A264A3492C42A0444
+940B:2000227C5144497C84447A7C220021FEF940227E2EAAB32A624A3A92E22A0044
+940C:208020F851084BFE8512792221FE2040F8A223542898B33460543892E3500020
+940D:11F81050282027FC40A4B92812A01040FDFC1154958C597451541D74E104410C
+940E:1090108829FE25104310BDFE11101110FDFE1110951059FE51001EA4E2524452
+940F:108810502BFE245041FCB954118C1174FD0411FC94085BFE51081C88E0A84010
+9410:1020102029FC24204154B888110412FAFC8810F8948858F850201CA8E1244060
+9411:208820885108493E82487B88209C2100FA4023DC2814B05462B43A94E21C0014
+9412:208822AA22DC548889547222200023FEFA4224442BFCB04460443884E1140208
+9413:2108208853C8481083DE7A6423D42014FBD420542894B0E863883894E2940122
+9414:200023FE50504BFE82527BFE200021FCF90421FC2904B1FC60203BFEE0200020
+9415:200023DE50884AA883FE798822DA24A6F9F821082908B1F861083908E1F80108
+9416:2124212452AA4BAE81247AAA23AE2124FBFE21102914B114628A3A4AE2160422
+9417:23DE225253DE4A5283DE7A0222F22292FAF222922AF2B29262923B32E2020206
+9418:102011FC2888245043FEB80011FC1124FDFC112495FC582051FC1C20E3FE4000
+9419:101010D42848254A4284BC84117A1000FEFC108494FC580050841E48F1FE4000
+941A:100013FE285025DC4104B90411DC1050FC5013FE9440582050A41E8AE28A4478
+941B:100011FC290425FC4104B9FC102013FEFC0011FC950459FC50201D24E2224060
+941C:08207F20223E3E4400843E2804107E2809442EC21830EFEE01003FF80920FFFE
+941D:200027FE54004E28854877EE24922484F6A026A8A7E8748824943514C9241242
+941E:100011FC280424FC4004B9FC100011DCFC9413DC94085BFE51081C88E0A84010
+941F:108810882BDE248847FEB88811541222FDFC1104950459FC51041D04E1FC4104
+9420:2108209053FC489082947998209027FEF80021F82908B10861F83908E10801F8
+9421:2094209253F2489087FE701023D22252F25223D4A454728C20EA370AC0160022
+9422:22882108FABE2008729CA92A2288210806C01830EFEE01003FF811100920FFFE
+9423:112410A82BFE260240F8B88810F8100CFDF0102095FC582053FE1C20E0A04040
+9424:21F8210851F84D0A85FA750A25FA2402F79E2090A0907F9E24923492C4920892
+9425:108810502BFE242041FCB82013FE1124FCA813FE940059FC51041D04E1FC4104
+9426:200023DE52524BDE82527BDE220222FAFA5222522BFEB25262523A92E20A0204
+9427:200023DE52524BDE82527BDE220222FAFA8A22FA2A8AB2FA628A3A02E20A0204
+9428:109017FC289427FC4290BBFE111213FAFD0E11F8950859F851081DF8E0904108
+9429:104412242928247E4010B828134A111CFD28114C951A592A51481D10E2FE4400
+942A:1020103E282025FE4122B9FC1122117EFD54117C9554597C51101EFEE22244C6
+942B:20A0209051FE4B2081FC792021FC2120F9FE21002BDEB25262523A72E2020206
+942C:2020213C51204BFE8010781423FE2210FBF022542A54B2D463683C4AE8960322
+942D:2040208053FE4A2282AA7A2223FE2272FAAA22022820B3FE60503888E1040602
+942E:202023FE52884A5083FE7A5022FC2254FBFE22542AFCB25062D83D54E6520850
+942F:108810882BFE24A840227DFA902410287BFE104094FC598452FC1C84E0FC4084
+9430:10F81088288824F84000B9DC11541154FDDC102095FE587050A81D24E2224020
+9431:10201020285024884104BAFA10001000FDDC1154955459DC50881C88E1544222
+9432:100011FC2954255441FCB88011FC1244FDF41154955459F450441DF4E0144008
+9433:100011FC282027FE4222B9AC102011ACFC0011FC9524592451FC1D24E12441FC
+9434:201023C8527E4A4082627BD42200223EFBC822482E7EB24862483BC8E2480008
+9435:208C23EA50884BFE80087BE8222A23EAF80A23EC288CB3EC608A38EAE3960022
+9436:100011FC2954255441FCB80013FE1000FDFC110495FC586250941D88E2A440C2
+9437:108813FE288824004148BBFE11481178FD0011FC94205BFE50701CA8E3264020
+9438:100011FC295425FC4020B9FC102013FEFC88105095FC582053FE1C20E0204020
+9439:2000227C514449748054785426FE2282FABA22AA2ABAB282628A3A84E50008FE
+943A:1020112428A827FE4202B8F810881088FCF8100095FC592451FC1D24E1FC4104
+943B:2040207C50404BFE82427A7823C4223CFA0023FE2A40B3A462583DB4E45209B0
+943C:102011FC2820248843FEB88811FC1104FDFC110495FC590451FC1C88E1044202
+943D:10101210297C241040FEB844132811FEFD10117C951059FE51101D10E2FE4400
+943E:3E1022FE3E4420287EFEA2103EFC231006C01830EFEE01003FF811100920FFFE
+943F:1040102029FC24884050BBFE100011FCFD0411FC950459FC50201E94E28A447A
+9440:100E11F028A2245441FEB92210141152FD4A12389440587C50841D48E03041CE
+9441:2020208852524B2682527A8A222223FEF88821442A7AB08861503820E0D80706
+9442:101C11E0282027FE4020B9FC11AC1174FDFC102095FC582053FE1C00E154422A
+9443:100011DC2844255440CCB95410001048FCFE119096FC589050FC1C90E0FE4080
+9444:202023FE502049FC80007BFE200221FCF82023FE2800B3FE60043BBEE2A4038C
+9445:208822AA22DC548889547222200023FEFA2220202BFEB07060A83924E6220020
+9446:2144214455544B64814E7BE42004222CF94423E42884B3E4608438E4E7140008
+9447:2040202053FE4888805277AC22AA22A8F5AC2000A10471FC210431FCC1040204
+9448:200027FC224854448FFE744426EC2554FEEC24442EECB55466EC3C44E4540408
+9449:108813FE2888242041FCB82013FE1040FC8811FC940059FC51541D54E7FE4000
+944A:108813FE28A8249041FEBB2011FC1120FDFC112095FE590053FC1C88E070438E
+944B:1000FEFE10547CA854547C7C5410FEFE110006C01830EFEE01003FF80920FFFE
+944C:2040202053FE4A0281FC7948225021FCFB0421FC2904B1FC610439FCE0880104
+944D:3EF822883EF822883EF822883EF81450238806C01830EFEE01003FF80920FFFE
+944E:23FE222052FC4AA482FC7A2023FE2284FAFC22842AFCB28462FC3A48E28403FE
+944F:104010202BFE26224154B94A123A1000FDFC115497FE580051FC1C20E0A04040
+9450:100011FC282027FE4222B9AC102011ACFC0013FE942059FC51541D54E154410C
+9451:200823E852884BEE82287BF4228223E2F80021FC2954B15461543954E7FE0000
+9452:7E40487E7E9043087EFE48AA7EFE010006C01830EFEE01003FF811100920FFFE
+9453:1010107C2A54257C4110B8FE1000137CFD44117C9540597C51441D7CE280447E
+9454:2040202053FE4A02851479DE22522554FA8821742A02B1FC60203924E2220060
+9455:2042239C52104BDE82947A94242023FCFA0423FC2A04B3FC62043BFCE1080204
+9456:210827FE5108480083FC7A94229423FCF82823FE2A20B32462A83A92E42A08C6
+9457:10501190289E27EA408AB9D2128A10A4FC501088972658A850701CA8E1244060
+9458:23F8224852484BF88248724823F82000FFBE2AAAAAAA7FBE2AAA3AAACFBE08A2
+9459:2394211027BE51188BAA7546221823E0FA0421FC2800B3F862083BF8E20803F8
+945A:108811DC288825DE4088B954122211FCFD0411FC950459FC51041DFCE0884104
+945B:1020101029FE2528417CB92811FE1110FD7C1154957C5954517C1E00E2444482
+945C:112410A82BFE260240F8B88811FC1104FDFC110495FC590451FC1C00E0884104
+945D:208823FE50884820823C7944203820D6FB382110297CB110617E3910E31004FE
+945E:212422485124480083FC7A9422642294FBFC22482B68B248636A3A4AE2460362
+945F:102013FE282025FC4000BBFE125213FEFD0411FC950459FC51041DFCE0884104
+9460:244424E458A84AAA8EEE74A42AAA2EEEF2422040AFFE70E021503248CC460040
+9461:20202120513C492087FE78902294236CFA0423FC2A94B294636C3A04E3FC0004
+9462:2020203C50204BFE82227AF8222422FCFAA422FC2AA4B2FC64203D54E94A023A
+9463:2040202053FE4A5083FE7A5223FE2200FA9422D82A90B2D2628E3C00E5540A2A
+9464:11FC110429FC250441FC7C8891FC10887BFE108895245AAA50701CA8E1244060
+9465:108011F82A0825FC4124B9FC112411FCFD54122A95FC590451FC1D04E1FC4104
+9466:27DE251227D254548FC8751427E22000FBFC22042BFCB20463FC3A04E3FC0108
+9467:102013FE2A8A25FC4088B9FC110411FCFD0411FC950459FC50901C94E112420E
+9468:2110209053DE4810825E798223DE2010FBDE22502BDEB25063DE3A50E25202CE
+9469:200023FE50204BAE82AA7AAA23AE2020FBFE20202BAEB2AA62AA3BAEE02003FE
+946A:2040207C50404BFC82447BF0224422FCFAA822F82AA8B2F862003DFCE5540BFE
+946B:010006C01830EFEE01001FF009203FF8101028287C7C92927C7C10105454FEFE
+946C:13D012902BDE266843C4BA8413F81108FDF8110895F8590851F81C90E112460E
+946D:23DE225253DE4A5283DE7A2222FA2222FAFA22AA2AFAB2AA62FA3A72E2AA0226
+946E:208823FE208854128AFE701024FE2292FAFE209229FEB29266043AFEE244022C
+946F:2148214C52AA480883FE79482368214AFB6A214A2B6CB14C616A3B8AE0160022
+9470:10201050288825744202B9FC115411FCFC0011FC9554595451FC1D54E154410C
+9471:21F0221057FC4A0483FC7A2423B82222F9FE22102FFCB24463FC38D0E14A063E
+9472:102013FE280025DC4154B9DC108813FEFC8813FE94885BFE50941D88E2A440C2
+9473:204027FE54924BFC80907BFC209027FEF90823FC2D0AB1F862403A7CE54008FE
+9474:222223FE209051FE8B1075FE211021FEF91021FE2900B3FE628A3B76E2520276
+9475:208823FE50884BDE82527BDE20A02090F9FE21202BFCB52061FC3920E1FE0100
+9476:2090209057FE4894800A71FE250827E8F14A21EAAF2A75EA254C39EAC2160462
+9477:23FC210851F8490881F8790E27F82008FFFE22942B9CB294639C3AD6E7BC0084
+9478:27FC244457FC4C4487FC70002FBE2AAAFFBE2AAAAFBE7040204037FCC0400FFE
+9479:204027FE5492490880807B1C2204239CFA0423FC2A48B36862483B6AE2460362
+947A:23DE225253DE4A5283DE7A5223DE2090F9FE21102BFEB51061FE3910E1FE0100
+947B:22A8224857BE4AA8875C7AAA22882FFEF21825E4A84273F8204037FCC04000C0
+947C:200023FE52524A5283FE71082154225EF7B4211EA25477DE20143554C55E0010
+947D:252827BE294857BE8B1875AA294623FCFA0423FC2A04B3FC62043BFCE1080204
+947E:21084FD2F03C23884812FBBE0280ABAA010006C01830EFEE01003FF80920FFFE
+947F:55781448FF4822867F7808486B2849107F2806C41830EFEE01003FF80920FFFE
+9480:210821EC510A4FEA89287BC8293E2FE8F9482BE8AA287B682AA83BF4CAB412A2
+9481:23DE225253DE4A5283DE78A021FE2320FDFC212029FEB00061FC3888E070078E
+9482:2248215057FC4C0481F0711027FC2554F4E427FCA04077FC20403FFEC2A40452
+9483:23FE220253FE4A9282547A9222FE22AAFAFE23222AFAB2AA62FA3A22E5FA0004
+9484:208823FE50884BDE82527BDE225223DEFA2223FE2AAAB2FA62223A72E2AA0224
+9485:100010001E00200020007C0090001000FE001000100012001400180010000000
+9486:108010801E80208020807C8090801080FE8010801080128414841884107C0000
+9487:100010003DFC20084010BC2010401040FC801080110011041504190410FC0000
+9488:102010201E20202020207C2093FE1020FE201020102012201420182010200020
+9489:100010003DFE20204020BC2010201020FC201020102010201420182010A00040
+948A:100410041E04204420447C4490441044FE441044104412041404180410140008
+948B:104010401E40204020407C6090501048FE441044104012401440184010400040
+948C:100011FC1E04200820107C2090201020FE201020102012201420182010A00040
+948D:102010203C2020204020BC2011FC1020FC201020102010201420182013FE0000
+948E:1008103C3DE020204020BC20102013FEFC201020102010201420182010200020
+948F:110411243D2421244124BD2411241124FD2411241124112415241A2412040404
+9490:100810081E10202020407C8890081010FE201044108412081410182010C00300
+9491:100013FC3C8420884088BC90109C1084FD4411441128112816101A2814440182
+9492:100011F03D1021104110BD1011901150FD5011101110111215121A12120E0400
+9493:104010403C8020FC4104BE0410041104FC841044104410041404180410280010
+9494:108010403C5E21024102BD0211021102FD0211021102110215021902110A0104
+9495:104010403C40204043FEBC8810881088FC881108109010501420185010880304
+9496:100011F83C1020204040BC8011FC1054FC541094112410241444188411280010
+9497:100013FC3D0421444124BCA810881088FC501050102010201450188811040602
+9498:100011FC3C8820884088BC88108813FEFC881088108810881488190811080208
+9499:100013FE3C2020204120BD3E11201120FD2011FE100210021402180210140008
+949A:100010003DFE20104010BC2010201068FCA41122122210201420182010200020
+949B:102010201E20202020207DFE90201020FE20105010501250148818C811240202
+949C:100011FE3D0021004100BDFC11041104FD04110411FC11001500190011FE0000
+949D:20402040384027FC40407A48A2482248FA4823F82048204028423042203E0000
+949E:102010203C2020A840A4BCA211221120FE241024102810081410182010C00300
+949F:102010203C20202041FCBD2411241124FD2411FC112410201420182010200020
+94A0:102010203C2021FE4122BD2211221122FD52114A118A110215021902110A0104
+94A1:100011FC3D0421044124BD2411241124FD241124112410501448188411020602
+94A2:100011FC3D0421044194BD5411541124FD241154115411941504190411140108
+94A3:1008101C3DE021004100BDFC11441144FD4411281128111015101A2812440482
+94A4:102010203C5020504088BD4412221020FC0011FC100410081408181010100020
+94A5:100010FC3C8420844084BCFC10841084FC8410FC108410841504190412140408
+94A6:104010403C40207C4084BC8811201020FC201050105010501488188811040202
+94A7:104010403C8020FC4104BE0410841044FC441014102410441584180410280010
+94A8:102010403CFC20844084BC8410941088FC8010FE1002100215FA180210140008
+94A9:108010803C8020FC4104BD0412441044FC8410A4111411F41414180410280010
+94AA:104010203C0021FC4000BC0010F01090FC9010901090109214921912110E0200
+94AB:104010203C2023FE4080BC80108010FCFC841084108410841504190412280410
+94AC:102010201E20202420A47CA490A81120FE201050105012501488188811040202
+94AD:101011103C9020904010BD1010901090FC10101E13F010101410181010100010
+94AE:100011F83C4820484048BC48104811F8FC881088108810881488188813FE0000
+94AF:100011FC3D2421244124BD24112411FCFD041100110011001502190210FE0000
+94B0:100010003DFC20204020BC2010201020FDFC1020102810241424182013FE0000
+94B1:105010483C40205C41E0BC40105E11E0FC441048103010221452188A13060002
+94B2:100010003DFE20104010BC1010901090FC9E1090109010901490189013FE0000
+94B3:108810883C88208843FEBC8810881088FC8810F8108810881488188810F80088
+94B4:102010203C20202043FEBC2010201020FDFC1104110411041504190411FC0104
+94B5:102010203C20202041FEBC7010A810A8FD241124122210F81420182010200020
+94B6:100010003DFE20084008BDE811281128FD28112811E811281408180810280010
+94B7:100011FE3D002100417CBD4411441144FD441144117C11441500190011FE0000
+94B8:20402040384023FE408078A0A12021FCFB242524212421242934312820200020
+94B9:105010483C48204043FEBC80108010FCFD4411441128112816101A2814440182
+94BA:202820243824202043FE7A20A2242224FA242228222822902B12322A20460082
+94BB:102010203C202020403EBC2010201020FDFC1104110411041504190411FC0104
+94BC:100011FC3D0421044104BDFC11041104FD0411FC110411041504190411FC0104
+94BD:100010003DFC21044104BD0411FC1104FD04110411FC11041400180013FE0000
+94BE:100011FC3D2421244124BDFC11241124FD2411FC112410201420182010200020
+94BF:100010003DFC21244124BD2411241124FDFC1124112411241524192411FC0104
+94C0:102010203C20202041FCBD2411241124FD2411FC112411241524192411FC0104
+94C1:102010203D20212041FCBD2012201020FDFE1020105010501488188811040202
+94C2:102010203C4021FC4104BD0411041104FDFC1104110411041504190411FC0104
+94C3:2040204038A020A041107A48A4262020FBF820082010211028A0304020200020
+94C4:2008203C3BC0220042207A20A22023FEF8202020212821242A22342220A00040
+94C5:100010F83C8820884088BC8811061200FC0011FC110411041504190411FC0104
+94C6:200020803B1E225242527A52A2522252FA5222D2235A22542890309021100210
+94C7:108010803DFC21044204BDF411141114FD1411F4110411281512190210FE0000
+94C8:104010203C0023FE4020BC2011FC1124FD241124112411241534192810200020
+94C9:102010103C1021FE4020BC2010441084FDF8101010201044148219FE10820000
+94CA:102010103C1021FE4102BE0410801088FC9010A010C0108214821882107E0000
+94CB:104010203C2820084008BC4810541152FD5211601260104414C41944123C0000
+94CC:100011FC3D0421044104BDFC11001140FD4411481170114015421A42123E0400
+94CD:101010103C1021FE4112BD14111011FCFD4411441128112815101A2812440482
+94CE:100013FC3D0420884050BC2010D81326FC2011FC1020102017FE182010200020
+94CF:200427C43A84229442947A94A29427D4FA942294229422942A84348424940888
+94D0:104010443DF420484050BDFE10401080FDFE1240148010FC1404180410280010
+94D1:104010403C4421F44048BC5013FE1040FC801184129810E014821882107E0000
+94D2:100011FE3C8820884088BCF810881088FCF810881088109E15E8180810080008
+94D3:104810483DFE20484048BC20101011FEFC801080108010801480188010FC0000
+94D4:200023FC3890209040907892A4922294FA942298209020902890309027FE0000
+94D5:102010203DFE20404040BCFC10841184FEFC1084108410FC1484188410940088
+94D6:202820243824202043FE7A20A2242224FBA422A822A822902A9235AA24460882
+94D7:102010203C2021FC4020BD2410A410A8FC2013FE105010501488188811040202
+94D8:200027DE3892449244947C94A7D82094F992219222922A9A3494289002900110
+94D9:2080208038BC23C040507824A0D4230CF80023FE2090209029123112220E0400
+94DA:100011FE3C2020404088BD0411FE1022FC20102011FE10201420182013FE0000
+94DB:102011243CA420A440A8BC2013FC1004FC04100411FC10041404180413FC0004
+94DC:200023FC3A04220442F47A04A20422F4FA942294229422F42A04320422140208
+94DD:100010FC3C8420844084BC8410FC1000FC0011FE110211021502190211FE0102
+94DE:200021FC3904210441FC7820A02023FEFA222222222222222A2A322420200020
+94DF:200023FE3A02222242227A22A3FE2222FA222252224A228A2B02320223FE0202
+94E0:102011243D24212441FCBC0011FC1004FC0411FC110011001502190210FE0000
+94E1:200223E23A22222A42AA7AAAA2AA22AAFAAA22AA22AA208229423122220A0404
+94E2:20202120392021FC41207A20A02023FEF87020A820A821242924322220200020
+94E3:102011203D2021FC4120BE20102013FEFC90109010901090151219121212040E
+94E4:200020063BB8208840887908A13E2388F88822882288213E29003280247E0800
+94E5:1008103C3DE020204020BDFC10201020FC2013FE102010401488190413FE0102
+94E6:1008103C3DE020204020BDFE10201020FC2011FC110411041504190411FC0104
+94E7:109010943D1421184310BD321152110EFD20102013FE10201420182010200020
+94E8:2040204038A0211042087C06A3F82040F840204023F820402840304027FE0000
+94E9:100411883C5020204050BC8811241020FFFE102010A810A415221A2210A00040
+94EA:2040204038A0211042087C06A3F82000F80023F8220822082A08320823F80208
+94EB:105010503C50215240D4BC5810501058FCD4115212501050149218921112020E
+94EC:104010403C7820884150BC2010501088FD0610F8108810881488188810F80088
+94ED:104010403CFC21044288BC5010201040FC8011FC128410841484188410FC0084
+94EE:2080208039F8220840107BFCA0242024FBFE2024202423FC2824302020A00040
+94EF:108010803CF821084210BDFC11241124FD2411FC110011001502190210FE0000
+94F0:104010203C2021FE4000BC8811041202FC881088105010501420185010880306
+94F1:104010203C2023FE4040BC4010A010A2FDA4129814901088148418A210C00080
+94F2:204020203BFC200041087890A3FE2200FA002200220022002A00340024000800
+94F3:104010203C2023FE4040BC88110413FEFC9210901090109015121912120E0400
+94F4:2200217C3904240842107A20A07E212AF92A222A264A22522A923322224A0084
+94F5:20402020382023FE42027C44A04023FEF8882088210820D02820305020880304
+94F6:100011F83D08210841F8BD08110811F8FD441148113011201510194811860100
+94F7:210021003900211E47D27A52A2522252FA522492229221122A92325E24520800
+94F8:102010203DFC202040FCBC2011FE1048FC4810FE1088114815281A0810280010
+94F9:208820883BFE208840007BFEA2022444F84023FC204420842884310422280410
+94FA:204820443BFE204040407BFCA2442244FBFC2244224423FC2A44324422540208
+94FB:100013FE3C40204041FCBC84108413FEFC00100011FC11041504190411FC0104
+94FC:20202020382023FE40207924A0A420A8FBFE207020A820A82924322224200020
+94FD:201020143812201043FE7810A0902050F8482008208822A82A9A32AA24660002
+94FE:201022103910217E40207828A748217EF908210821FE210829083288247E0000
+94FF:208022FC3AA422A442A87A90A2A820C6F820202021FC20202820302023FE0000
+9500:102011243CA420A84020BDFC11041104FDFC1104110411FC1504190411140108
+9501:102011243CA420A84020BDFC11041124FD241124112411241450188811040202
+9502:100011FC3D24212441FCBD24112411FCFC20102011FC10201420182013FE0000
+9503:100011FC3D0421044104BDFC10001000FDFE1020102011FC1420182013FE0000
+9504:200820083BC82248425E7A4AA3CA224AFA4A23CA224A224A2A6A33D226120026
+9505:200021FC39042104410479FCA0202020FBFE22222252228A2B0A3202220A0204
+9506:20202120392021FC41207A20A02023FEF800200021FC21042904310421FC0104
+9507:201020D83B94209440907BFEA0902094F89420D82398209028AA30CA22860102
+9508:101C11E03C20202043FEBCA811241222FDF81088109010BE1502190212140408
+9509:102010203D2421244124BD2412AA1472FC20102011FC10201420182013FE0000
+950A:1004101E3DE020224112BC9410801008FDFE1008108810481448180810280010
+950B:104010403CFC20884150BC2010D81326FCF8102010F8102017FE182010200020
+950C:104010203DFC20004088BC5013FE1020FC20102011FC10201420182010200020
+950D:204020203BFC204040907908A3FC2004F9502150215021502A5032522452080E
+950E:210020BE3A82220242FA7A52A2522252FBFE2252225222922B123202220A0204
+950F:210020BE3A82220242027AFAA28A228AFAFA228A228A22FA2A023202220A0204
+9510:220821083910402043F87A08A2082208FBF820A020A0292031242224041C0800
+9511:21082088389023FC40247824A3FC2220FA2023FE206220A2292A322424200020
+9512:104010203DFC21044104BDFC11041104FDFC1120112211141508194411820100
+9513:100011FC3C0420FC4004BDFC100013FEFE0211F8108810881450182010D80306
+9514:200023F83A08420843F87A00A20023FCFA0422F422942A9434F4240408280010
+9515:2000277E3D04250445747D54A6542554FD542554257425542E04340424140408
+9516:202020203BFE202041FC7820A3FE2000F9FC210421FC210429FC310421140108
+9517:2020202239FA202440287BFEA0202040F8FC2184228420FC2884308420FC0084
+9518:208820883BFE208840A87820A3FE2040F88020FC218422842884308420FC0084
+9519:21102110391027FC41107910AFFE2000FBF82208220823F82A08320823F80208
+951A:208820883BFE208840887800A1FC2124F924212421FC21242924312421FC0104
+951B:202020203BFE205040A87924A2FA2020F8A8208823FE20882888308821080208
+951C:102010203DFC20504088BD0413FE1008FDE81128112811E81528180810280010
+951D:100011FC3D0421FC4104BDFC100011FEFC0813FE100811081488180810280010
+951E:100011FC3D24212441FCBD24112411FCFC2013FE107010A815241A2210200020
+951F:100011FC3D04210441FCBD04110411FCFC00111211D41118151019521192010E
+9520:10FC10843C8420FC4084BC8410FC1000FDFE1102110211FE1502190211FE0102
+9521:100011F83D08210841F8BD08110811F8FC8011FC1254109415241A4410940108
+9522:100011FC3D0421244124BDFC11241124FD741154115411741504190411FC0104
+9523:200023FE3A52225242527BFEA0202040F8FC2104228820502820304021800600
+9524:2008203C39E0202040207BFEA1242124FBFE2124212423FE2820302023FE0000
+9525:105010483C8020FE4190BE9010FC1090FC9010FC10901090149018FE10800080
+9526:102010403DFC210441FCBD0411FC1020FC2013FE12221222162A1A2410200020
+9527:101C11E03D10211041FEBD101110117CFD4411541154115415541A2812440482
+9528:201020503B90221E42127A24A3C82288FA882288228822942A94349424940822
+9529:102011243CA8202041FCBC4013FE1088FD0412FA1488108814A818921082007E
+952A:2080208038FC2154425478A4A1242244F8942108204020A42AAA328A24780000
+952B:104010203DFC20004108BC90100013FEFC00100011FC11041504190411FC0104
+952C:204022443A44244840A07910A6082044F84022482248245028A0311022080C06
+952D:204020203BFE220244047800A3FE2020F8202120213C21202AA03260243E0800
+952E:201020103B7C211441FE7A14A27C2710F97C251025FE22102A10350028FE0000
+952F:200023FC3A04220443FC7A20A22023FEFA20222022FC22842A84348424FC0884
+9530:200021FC3808201040207BFEA02020A0F84021FC215421542954315427FE0000
+9531:109210923D2422484124BC9210921000FDFE1122112211FE1522192211FE0102
+9532:2100213C3BD4211443947914A7D42124F94C204027FE204028A0311022080C06
+9533:208820883BFE208840A87820A1FC2124F924212427FE20202850308821040202
+9534:111011123DD421184152BD92112E1040FDFC1104110411FC1504190411FC0104
+9535:109010903C9E22A241D4BC88109410A4FDFE128414A410941494188410940088
+9536:200021FC3924212441FC7924A12421FCF8002040202422A22A8A348820780000
+9537:200023DE3A52225243DE7800A1FC2000FBFE2080210021FC2804300420280010
+9538:1008103C3DE020204020BDFE102010A0FD2C1124112411AC1524192411FC0104
+9539:200820C83B082108412A792AA3AC2148F9082388255421142914312421240142
+953A:1008103C3DE0202043FEBC2011FC1124FDFC112411FC102015FC182013FE0000
+953B:208023383A28222843A87A46A200227CFBA42224222823A82E10322822440282
+953C:10A0112C3D24212441ACBD24112411FCFC2011FC108810501420185010880306
+953D:102010403CFC208440FCBC8410FC1000FDFE1020102010FC1420182011FE0000
+953E:101E13E03C4421244088BDFC10401040FDFE108010FC114415281A1010680186
+953F:204020203BFE200041FC7904A1042104F9FC2052209421882A8834A420C20080
+9540:204020203BFE224842487BFEA2482278FA0022FC224422482A28341024680986
+9541:210420883BFE2020402079FCA0202020FBFE2000202023FE2820305020880306
+9542:102011243CA8202043FEBCA811241202FC4013FE108811081590186011980604
+9543:20842044384823FE40847884A108214AFA52239C208421082908325223DE0042
+9544:209027FC389423FC42907BFEA1122216FDFC2104212421242924305020880304
+9545:200023FC3A24422443FC7A00A2FC2284FA8422FC22842AFC3484248408FC1084
+9546:208820883BFE2088400079FCA10421FCF90421FC202023FE2850308821040202
+9547:202020203BFE402041FC7904A1FC2104F9FC210421FC290437FE208801040202
+9548:202820243BFE202041FC7924A1FC2124F9FC2124200823FE2888304820480018
+9549:200023FE380021FC41047904A1FC2000FBFE228A225223FE2A223222222A0204
+954A:200023FC390821F8410879F8A10E27F8F80827BC20A422A42928329024A80846
+954B:2020212438A8202043FE7A02A00021FCF904210421FC2050285030922112020E
+954C:20A0209039FE232045FC7920A1FC2120F9FE210023FC2088289E3102220A0404
+954D:204020803BF8220843F87A08A3F82208FBF8204027FE20E02950324824460040
+954E:102010503C8821744202BCF8108810F8FC0C11F0102011FC14201BFE10200060
+954F:204023BE3A12229242527AAAA3242040FBFE2222222223FE2A22322223FE0202
+9550:204020203BFE200041FC7904A1FC2000FBFE220222FA228A2AFA3202220A0204
+9551:204020203BFC210840907BFEA2022444F82023FC208020F82888310821280210
+9552:210420843888200043FE7800A0882104FA0221FC215421542954315427FE0000
+9553:204020203BFE2202400079FCA04020A2FB342058209423342852309023500020
+9554:204020203BFE2202441479E0A1002100F9FC2110211027FE2800309021080204
+9555:204020203BFE220240507888A1242050F888210422FA20882888308820F80088
+9556:100013FE3C5021FC4154BD5411FC1000FDFC100013FE102014A8192412A20040
+9557:2020212438A823FE420278F8A0882088F8F82020202021FC2820302023FE0000
+9558:200021F8390821F8410879F8A00023FCFA9423FC200021F82890306021980606
+9559:100011FC3D2421FC4124BDFC10401088FDF01020104413FE1422192412220060
+955A:202022223A2223FE40007BDEA2522252FBDE2252225223DE2A523252255A08A4
+955B:202027FE3C2025FC442477FEA42425FCFC2025FC252425FC2D2439FC2924112C
+955C:208020403BF8211040A077FEA00023F8FA0823F8220823F82920312222220C1E
+955D:204020203BFE208840507BFEA22222FAFA2222FA228A228A2AFA3202220A0204
+955E:22202120392047BE42407A20A3BC22D0FA90229022FE2A9034A825A808441082
+955F:22102110391047BE42407A00A3BE228AFA8822A822AE2AA834A825A8085E1080
+9560:200023DE38422252414A7A52A02820C4FB1220602188203229C4301820600380
+9561:200023FE385023FE42527BFEA00021FCF90421FC210421FC282033FE20200020
+9562:20002FFE38004A2849487BEEA8922884FAA02AA82BE828883894291409241242
+9563:202020203BFE2050428A7904A3FE2504F9FC210421FC20202924322224A20040
+9564:20A024A43AA820A047FC7910A0A027FCF84023F8204027FC28A0311022080C06
+9565:208020F8391023FC452479FCA12421FCF80023FE200021FC290431FC210401FC
+9566:210820883BC8201043DE7A64A3D42014FBD42054209420E82B88309422940122
+9567:2200217C3D04244445F47C44A5F42554FD7425D4255425F42CE435542444044C
+9568:210820903BFC209042947998A09027FEF80021F82108210829F83108210801F8
+9569:204020203BFE228A41247A22A1FC2124F9FC202023FE22222BFE322220200020
+956A:200023BE38A220A240BE7B88A208223EFA2A23AA20AA20BE2888308A257E0202
+956B:202027A438A8229241147A08A5F42802FBF82208220823F82A0831102FFE0000
+956C:208823FE38A8209041FE7B20A1FC2120F9FC212021FE21002BFC30882070038E
+956D:100011FC3C2023FE4222BDAC102011ACFC0011FC1124112415FC1924112401FC
+956E:200023FC3A94229443FC7800A7FE2000FBFC220423FC20A2291433082D440182
+956F:200023F83AA822A843F87900A3FC2484FBE422A422A423E4289437F420140008
+9570:202023FE3A88225043FE7A50A2FC2254FBFE225422FC22502AD8355426520850
+9571:2040202039FC208840507BFEA00021FCF90421FC210421FC28203294228A047A
+9572:2080204037FE44024A2473BCA4A42AA8F51022E8240423F828403248244400C0
+9573:204020203BFE225043FE7A52A3FE2200FA9422D8229022D22A8E340025540A2A
+9574:212422483924200043FC7A94A2642294FBFC2248236822482B6A324A22460362
+9575:21F022103BFC260443FC7A24A3B82222F9FE221027FC22442BFC30D0214A063E
+9576:204027FC380023B842A87BB8A11027FCF91027FC211027FE2928331025480186
+9577:00000FF808000FF008000FF00800FFFE1200111010A010401220141818061000
+9578:00000FF8080008000FF0080008000FF008000800FFFE0400082010103FF81008
+9579:00403E40204020783C8820883C8821102010FE10102820284448FE4402840102
+957A:00083E3C21E020203C2020203DFE20202020FE50105020504488FE8803040202
+957B:00203E2020A020A03CFC20A03D20202021FEFE20103020504448FE8803040202
+957C:00003EFE208220FE3C8820AA3CAA20AA20BEFE8810AA20AA44AAFEAA02BE0102
+957D:00203E2021FC20203D5420883D0422FA2088FEF8108820F84420FEA803240060
+957E:00003BFE21243A2227FE3A22237622AAFB76222223764AAAFB764A22022A0204
+957F:0800081008200840088009000800FFFE0A0009000880084009200A180C060800
+9580:00003E7C224422443E7C224422443E7C20042004200420042004200420142008
+9581:00007CF844887CF844887CF84008408840884108410842084408480840284010
+9582:00007C7C44447C7C44447C7C4004400440045FF4400440044004400440144008
+9583:00007C7C44447C7C44447C7C4004410441044104428442444424480440144008
+9584:0010771055105510771055105510771041104128412841284128414445444282
+9585:00007C7C44447C7C44447C7C40045FF441044104410441044104450442144008
+9586:00007C7C44447C7C44447C7C40045FF440044FE440045FF44004400440144008
+9587:00007C7C44447C7C44447C7C40045FF442044284424442244204420442144008
+9588:00007C7C44447C7C44447C7C40044FE4410441045FF441044104410441144008
+9589:00007C7C44447C7C44447C7C408440844FF44184428444844884428441144008
+958A:00007C7C44447C7C44447C7C4104410449244924492449244FE4400440144008
+958B:00007CF844887CF844887CF840084FC8448844885FE844884488488850A84010
+958C:7C7C44447C7C44447C7C420441045FF4400447C444444444485450344004400C
+958D:00007C7C44447C7C44447C7C420441047FFC440447E444244824514460944008
+958E:7C7C44447C7C44447C7C410441045FF44204448444844904522467F44214400C
+958F:00007C7C44447C7C44447C7C40045FF441044FE4410441045FF4400440144008
+9590:7C7C44447C7C44447C7C400441C45E0443C45E0443E45E04422441E440144008
+9591:7C7C44447C7C44447D7C410441045FF441044384454449245114410441144008
+9592:7C7C44447C7C44447C7C400447E4442447E4442447E4442448A4504440144008
+9593:00007CF844887CF844887CF840084FC848484FC848484FC84848400840284010
+9594:7C7C44447C7C44447C7C420441045FF440444444428441044284444448544008
+9595:00007C7C44447C7C44447C7C40044FE4408448844FF442844484588441944008
+9596:7C7C44447C7C44447C7C410441045D1445A44544492449145114650442144008
+9597:00007C7C44447C7C44447C7C4084448442844884448440F45F84408440944088
+9598:7C7C44447C7C44447C7C40044FE449244FE449244FE449244104410440144008
+9599:00007C7C44447C7C44447C7C420441045FF441044FE4492449A4494441144108
+959A:00007C7C44447C7C44447C7C420441044FE44444424442845FF4400440144008
+959B:7C7C44447C7C44447C7C40045FF44104492445445FF441044104410441144008
+959C:00007CF844887CF844887CF840085FE840484F4849484F484048414840A84010
+959D:7C7C44447C7C44447D7C4104428444444A24511C6FE440244044428441144088
+959E:7C7C44447C7C44447C7C440448245FF4445444445FF444444444444448544008
+959F:00007C7C44447C7C44447C7C4204414444845524561464544C4473C440144008
+95A0:00007C7C44447C7C44447C7C40045FF441044FE4410441445FF4400440144008
+95A1:7C7C44447C7C44447E7C41045FF4420444444F8441244644588443444C344008
+95A2:7C7C44447C7C44447C7C4004444442844FE441045FF44104428444444824400C
+95A3:7C7C44447C7C44447C7C420447E44824544443844C64701C47C44444445447C8
+95A4:7C7C44447C7C44447C7C4104428444445BB4400447C44444444447C444544008
+95A5:7C7C44447C7C44447C7C40044544492459F46F244944488449544A344814400C
+95A6:00007C7C44447C7C44447D7C4284444458344444444444444AA4511440144008
+95A7:7C7C44447C7C44447C7C400444445FF4444444447FFC4004444444244824400C
+95A8:7C7C44447C7C44447C7C41044FE441045FF441044FE441045FF4400440144008
+95A9:7C7C44447C7C44447C7C410441044FE4492449244FE441145FF440144004400C
+95AA:7C7C44447C7C44447C7C40045FF442844FE44AA44AA44CE448244FE44824400C
+95AB:7C7C44447C7C44447C7C40045FF4511451145FF453945554593451145FF4400C
+95AC:7C7C44447C7C44447E7C41044FE448244FE448244FE4491448A44A444C24481C
+95AD:7C7C44447C7C44447C7C40044FE448244FE440045FF450145FF4400440144008
+95AE:7C7C44447C7C44447C7C40345DC4444448445DF44444544449F4560461F4400C
+95AF:00007C7C44447C7C44447C7C5084488462A452944C8470245044518456144008
+95B0:7C7C44447C7C44447C7C400442044CE4482448244EE4482448244FE44004400C
+95B1:7C7C44447C7C44447C7C444448245FF4682C48244FE44284428444944874500C
+95B2:7C7C44447C7C44447C7C444442844FE448244FE442844284449458744004400C
+95B3:7C7C44447C7C44447D7C41045FF441044FE449244FE449244FE441045FF4410C
+95B4:7C7C44447C7C44447C7C40044FE448244FE448244FE448244FE444444824400C
+95B5:7C7C44447C7C44447C7C450444844FF459046FE449044FE449044FF44804400C
+95B6:7C7C44447C7C44447FFC48244FE448244FE440045FF450145FF450145FF44008
+95B7:08008BDE525223DE52528BDE22022222FA222222B252AA4A2A8A2202A20A4204
+95B8:7C7C44447C7C44447C7C40045FF442844EE4482448244EE4428442845FF4400C
+95B9:7C7C44447C7C44447D7C42045FF449245FF4692C4FE449244FE4411440F4400C
+95BA:7C7C44447C7C44447C7C40044FE448244FE448244FE441045FF4444443845C6C
+95BB:7C7C44447C7C44447E7C420447E4482452444CE4482448244EE4482448244FEC
+95BC:7C7C44447C7C44447C7C480444445E4448A44F144A4C4A244A8452446624400C
+95BD:7C7C44447C7C44447C7C40645F8451045FE4509458744FE448244FE448244FEC
+95BE:7C7C44447C7C44447C7C408440A45FF440844EA44AA44EA4405446B45914420C
+95BF:7C7C44447C7C44447C7C40E45F2449445FF4501447C440444684410442844C4C
+95C0:7C7C44447C7C44447C7C44445FF444447FFC482457D4644C47C4442443E4400C
+95C1:7C7C44447C7C44447C7C40044EE44AA44EE44AA44EE44824482448244864400C
+95C2:7C7C44447C7C44447C7C492445445FF442047FFC482457D4644C44C4442443EC
+95C3:7C7C44447C7C44447C7C4FE448244FE448244FE448244FE441445FF44284444C
+95C4:7C7C44447C7C44447C7C40045FF442844FE44AA44FE442045FF4444443845C6C
+95C5:7C7C44447C7C44447FFC48244FE448244FE4420443F442045FE4444443845C6C
+95C6:7C7C44447C7C44447C7C400447C4444447C440044EE44AA44AA44EE440144008
+95C7:7C7C44447C7C44447E7C41044FE4444442845FF440044FE448244FE448244FEC
+95C8:7C7C44447C7C44447C7C42044FC444445FF448244FE441044FE451045FF44108
+95C9:7C7C44447C7C44447C7C40045FF442845FF452945FF441044FE441045FF4400C
+95CA:7C7C44447C7C44447C7C4004483445C4404453FC484441F4451449F450144008
+95CB:7C7C44447C7C44447C7C40944EA4424C5454482457D4410C4FE442844444582C
+95CC:7C7C44447C7C44447C7C41045FF441045FF4555453945FF4454449245114410C
+95CD:7C7C44447C7C44447C7C41144FE441445FF442044FE4742447E4442447E4400C
+95CE:7C7C44447C7C44447D7C42044FE448244FE448244FE441145DA445444924531C
+95CF:FC7E8442FC7E8442FC7E8002BFE2A022AFA2A222AFA2AAAAAFAAA25ADFCA8046
+95D0:7C7C44447C7C44447D7C4FE441044FE448244FE448244FE448247FFC4444482C
+95D1:7C7C44447D7C46447FFC48244FE448244FE448244FE441045FF445444924410C
+95D2:7C7C44447C7C44447C7C47C4444447C4444447C440044EE44AA446644AA4466C
+95D3:7C7C44447C7C44447D7C49244FE440045FF440044FE448244FE444445FF4400C
+95D4:7C7C44447C7C44447C7C41044FE441045FF444444FE440044FE44AA45FF4400C
+95D5:7C7C44447C7C44447C7C51444A445F744494552455445F44444448A449145208
+95D6:7C7C44447C7C44447C7C40044FF449044FE449044FE449044FF440145554402C
+95D7:7C7C44447C7C44447C7C4844484452945CE4484452945EF440044AA45154400C
+95D8:00007C7C44447C7C44447C7C40245E2440F45E2452A45E6452244F2478B45048
+95D9:7C7C44447C7C44447C7C480444445E7C52945E9451545E246A544E8C4004400C
+95DA:7C7C44447C7C44447C7C480449E45D2449E449247DE4492449E454C45154623C
+95DB:7C7C44447C7C44447C7C492445445FF4501447C4444447C441044FE441045FEC
+95DC:7C7C44447C7C44447C7C484452945CE44A545EF4428452945EF4428444944888
+95DD:7C7C44447C7C44447C7C40245F24517C5F9451145F5451245F244A545194400C
+95DE:7C7C44447C7C44447C7C40045C44447C7F5452945E1452545E2453A47E544298
+95DF:7C7C44447C7C44447D7C46C4583447C4444447C440044EE44AA446644AA4466C
+95E0:7C7C44447C7C44447D7C4FE449244FE441047FFC48244FE448244FE44444482C
+95E1:7C7C44447C7C44447EFC4AA44EE440044FE449244FE449244FE441045FF44108
+95E2:7C7C44447C7C44447C7C40845E4453F45EA450445EF46A444AE44E444A544008
+95E3:7C7C44447C7C44447C7C492445445FF4501447C444444FE449244FE449244FEC
+95E4:7C7C44447C7C44447FFC4AA44FE440045FF440044FC448444FC445244CC4562C
+95E5:7C7C44447C7C44447C7C50844BE4408447F459444BE448844FF44884488457EC
+95E6:7C7C44447C7C44447C7C42844FE44AA44FE44AA45FF4444447C4444442844FEC
+95E7:7C7C44447C7C44447C7C408463E4508447F4722453E45154532455146FF4400C
+95E8:200013FC10044004400440044004400440044004400440044004400440144008
+95E9:200017FC000440044004400440045FF440044004400440044004400440144008
+95EA:200017FC00044004410441044104410442844244442448244004400440144008
+95EB:200017FC000440045FF44004400440044FE44004400440045FF4400440144008
+95EC:200017FC000440044FE44104410441045FF44104410441044104410440144008
+95ED:200017FC0004408440845FF44084418442844484488450844284410440144008
+95EE:200017FC00044004400447C44444444444444444444447C44444400440144008
+95EF:200013FC100440045F844084488448844FE4402440245FA44024414440944008
+95F0:200013FC1004400440045FF4410441044FE44104410441045FF4400440144008
+95F1:200017FC010441045FF4410441044FE4410441045FF44114411441544124400C
+95F2:200017FC00044104410441045FF4410443844544492451144104410440144008
+95F3:200017FC0204420442045FF444044484488449045144522467F4421440144008
+95F4:200013FC1004400447C444444444444447C444444444444447C4400440144008
+95F5:200017FC0004420441045FF44044444442844104428444444844400440144008
+95F6:200017FC0004420441045FF44004400447C44444444444544834500440144008
+95F7:200017FC00044204410441044404542454146454444443C44004400440144008
+95F8:200017FC000440044FE4492449244FE4492449244FE449244104410441144008
+95F9:200017FC0004420441045FF4410441044FE44924492449A44944410441144008
+95FA:200017FC000441044FE4410441045FF4400441044FE4410441045FF44004400C
+95FB:200017FC000440045FF4444447C4444447C4444444745FC44044404440544008
+95FC:200017FC00044844444445F440445C4444A4449445144A0451F4400440144008
+95FD:200017FC0004410441044FE44924492449244FE44904412441F45E144804400C
+95FE:200017FC0004400447C44444444447C440044FE4482448244FE4400440144008
+95FF:200017FC0104492449244FE440044FE4402440244FE44804481447F44004400C
+9600:200017FC000445444524490459F46F044924492448C4489449544A3448144008
+9601:200017FC0204420447E44C445284410442844C6477DC4444444447C440144008
+9602:200017FC0004420441045FF4420444444F8441244644588443444C244004400C
+9603:200017FC000440045FF4511451145FF4511453945554593451145FF44004400C
+9604:200017FC0004440447C4488451046FE449244FE449244FE44114411440F4400C
+9605:200017FC00044444428440044FE4482448244FE4428442844484489450744008
+9606:200017FC020441044FE448244FE448244FE4491448A44A444C2448144004400C
+9607:200017FC010441144FE441445FF442044FE4742447E4442447E4442440144008
+9608:200017FC008440A440945FF440844EA44AA44EA440C4465458B441144204400C
+9609:200017FC000442045FF444444924711C4FE449244FE449244FE4411440F44008
+960A:200017FC00044FE448244FE448244FE440045FF450145FF450145FF44004400C
+960B:200017FC000442044CE448244EE448244FE4428442844494449448745004400C
+960C:200017FC000440E45F044A2445445FF4501447C440444684410442844444482C
+960D:200017FC000440645F8451045FF450845C5450344FE448244FE448244FE4482C
+960E:200017FC0204420447E4482452444CE4482448244EE4482448244FE440144008
+960F:200017FC0004484444445EA448A449144E0C4A444A244A044A8452445624600C
+9610:200017FC0004444442844FE449244FE449244FE441045FF44104410440144008
+9611:200017FC010441045FF441045FF45114555453945FF44544492451244104410C
+9612:200017FC00044FE448244FE448244FE448244FE441445FF4410442844444482C
+9613:200017FC01044FE449244FE441047FFC40044FE448244924492442844444482C
+9614:200017FC0004483445C46444504451F44444484479F44914491449F44004400C
+9615:200017FC000440845E9442A44A4C4454482457D4610C4FE4410442844444582C
+9616:200013FC11044FE441045FF4420444444FE440044FE44AA44AA45FF440144008
+9617:200017FC01045FF441044FE448244FE448244FE448244FE448247FFC4444482C
+9618:200017FC00044FE448244FE448244FE440045EF4421452944A5452944A54442C
+9619:200017FC000451444A445F744494552455445F44444448A44914520440144008
+961A:200017FC00045C44447C7F5452945E1452545E2453A47E544294430440144008
+961B:200017FC00045FF452945FF440047FFC40044FE448244FE445144CA47444462C
+961C:020004003FF020103FF020003FF8200820083FF801000100FFFE010001000100
+961D:00007C0044004800480050004800480044004400440068005000400040004000
+961E:00407C40444048404BFC50444844484444444484448468845104410442284410
+961F:00407C4044404840484050404840484044A044A044A069105110420844044802
+9620:00007DF04490489048905090489049F04490449044906892508A408A40864082
+9621:00087C3C45E048204820502048204BFE44204420442068205020402040204020
+9622:00007C0047FC48904890509048904890449044904490689251124112420E4400
+9623:00407C40448048FE4900520048FC480844104420444068805102410240FE4000
+9624:00207C2044204920492C513449644BA445244534452869225122410240FE4000
+9625:0040784048405044506867705160495049504A486A4854444842404041404080
+9626:00407C40444048404944514449484A50444044A044A068905110410842044402
+9627:00107D104490489048105110489048904410441E45F068105010401040104010
+9628:00007DFE450049004978514849484948454845684550694251424142423E4400
+9629:00087C68478848884888508848884BFE44884488448868885108410842084408
+962A:00087C1C45E04900490051FC4944494445444528452869105110422842444482
+962B:00007C0045FE4810481050204820486844A44522462268205020402040204020
+962C:00807C4044404BFC4800500049F04910451045104510691251124212420E4400
+962D:00407C4044804888490453FE48024890449044904490689051124112420E4400
+962E:00007DFC44004800480053FE48904890449044904490689251124112420E4400
+962F:00207C204420492049205120493C492045204520452069205120412047FE4000
+9630:00107D10451049124912511449D84910451045104510691251524192410E4000
+9631:00887C88448848884BFE508848884888448847FE448868885088410841084208
+9632:00407C2044204BFE48805080488048FC44844484448468845104410442284410
+9633:00007C0045FC4904490451044904490445FC4504450469045104410441FC4104
+9634:00007DFC45044904490451FC49044904450445FC450469045204420444144808
+9635:00407C4044404BFE488050A0492049FC4420442044206BFE5020402040204020
+9636:00207C2044504850488851044A02488844884488448868885088410841084208
+9637:00007C0045FE48204820502049204920453C4520452069205120412047FE4000
+9638:00407C2045FC4904490451FC49004900457C45084510692051424282427E4400
+9639:00207C20442049FC4820502048204BFE4420444044406888510443FE41024000
+963A:00047C1E45F0491049105110491049FE4510451045106908510A414A41A64112
+963B:00007DF845084908490851F849084908450845F8450869085108410847FE4000
+963C:00807C80448048FE494051404A40487C444044404440687E5040404040404040
+963D:00207C2044204820483E50204820482045FC4504450469045104410441FC4104
+963E:00207C2044504850488851244A12481045FC4404440868885050402040104010
+963F:00007DFE4408480849E85128492849284528452845E869285008400840284010
+9640:00407C20442049FE49025204490049084510452045C069045104410440FC4000
+9641:00807C8044FE49004A205120492C497447A44524453469285122410240FE4000
+9642:00207820482053FE5222622452204BFC4A844A886A4852504220445044884906
+9643:00007DFE44204820482051FE492249224552454A458A690251024102410A4104
+9644:00887C8844884908497E53084D08494845284528450869085108410841284110
+9645:000079FC48005000500063FE50204820492849246A2452224422402040A04040
+9646:00207C20442049FC4820502048204BFE44204420452469245124412441FC4004
+9647:00907C88448848804BFE50A048A048A444A445284528693252224262449E4800
+9648:00407840484057FE5080612051204A204BFC4820692851244222442240A04040
+9649:00007DFC440848104830504848844B02440045FC442068205020402043FE4000
+964A:00207C20447C488449485030482048484590443E444269A45018401040604180
+964B:00007BFE4820502052FC62A452A44AA44AD44A846A8452944288420043FE4000
+964C:00007DFE44204820484051FC49044904450445FC450469045104410441FC4104
+964D:00807C8044FC49084A90506049984E26442045FC44206A2053FE402040204020
+964E:00207D20452049FC4920522048204BFE447044A844A869245124422240204020
+964F:00207C2045FE4840484050FC4884498446FC4484448468FC5084408440944088
+9650:00007BF84A08520853F8620852084BF84A444A486A3052204210428843064200
+9651:00007DFE44204820484051FE49524952455245524552695251524142410A4104
+9652:00407C4044FC49044A0851FE4900497C454445444554694851424242423E4400
+9653:002078204BFE48505088510462FA50004BFE4840488069FC5004400440284010
+9654:00407820482057FE5040608451084BF048224844698856104020405041884604
+9655:00407840484057FC50406248515048404FFE48A068A051104110420844044802
+9656:00407C40448849044BFE500248884944464244F845886A505020405041884606
+9657:00207D2444A448A8482051FC4904490445FC4504450469FC5104410441144108
+9658:00007BFC48005124524864905248492448004BFC684050404040404047FE4000
+9659:00007DFE45004900497C5100490049FE45504552455469485148424442524460
+965A:001078184BD45014501067FE5010489048904AD06A905290428A42EA47064202
+965B:02207A244A2853B05220622252A24B1E484048406BFC50404040404047FE4000
+965C:00207C2044204BFE4820502049244924452446AA442068505050408841044202
+965D:00407840484057FE5040645052484A484D5448A268A051104110420844044802
+965E:00287DC8448848884BFE5088488849084628442045FC68205020402043FE4000
+965F:002078204920513C5120612057FE480048204924692452284410402040C04700
+9660:00287C2445FE4820482051FC4924492445FC4524452469FC512441244124410C
+9661:00207C2045FC4820482050204BFE482044204520453C692052A04260443E4800
+9662:004078204BFE5202540461F8500048004BFE48906890509041124112420E4400
+9663:00207C2045FE482049FC5124492449FC4524452445FC682053FE402040204020
+9664:00007840484050A05110620855F6484048404BFC684051504248444441444080
+9665:00407C40447C488449085210493E492245224522453E692251224122413E4122
+9666:00207C2047FE482049FC50404BFE4848448844FE450869485228440840284010
+9667:00007DFC4504490449FC5104490449FC4420442045FC68205020402043FE4000
+9668:00007CF84488488848F8500049FC490445244524452469245050404840844304
+9669:0040784048A050A05110620855F64800488848486A4851504110402047FE4000
+966A:00407C2045FC48004908509048004BFE4400440045FC69045104410441FC4104
+966B:00907C9044904B9E4890509048904B9C4490449044906B9E5090409040904090
+966C:00007FE04A5E5252525263D252524A544BD44A546A4852E84754405440624040
+966D:00207C2045FC4850488851044BFE480845E84528452869E85128400840284010
+966E:00A07C90448049FE491053104DFC4910451045FC45106910511041FE41004100
+966F:00207C2044504888490452FA480049FC4554455445FC6954515441544104410C
+9670:00207C20445048884944522249F84808441045FC44006BFE5040408841FC4084
+9671:00807C8044FE49024A42524A4952484247FE444244E26952524A404240544008
+9672:0008783C49E05020502063FE512449244FFE4924692453FE4020402043FE4000
+9673:004078404FFC504053F8624853F84A484BF8484068E0515042484C4640404040
+9674:004078804BFC5224522463FC52244A444BFC4890691057FE4010401040104010
+9675:0020782049FC5020502063FE508849444A4248F8698852504020405041884606
+9676:0100790049FC5204550461E4528448844FF448846AA452A443E4400440284010
+9677:0080788048F851085210640050404B9C4A044A046B9C52044204420443FC4204
+9678:00207C2045FC4820482053FE488849044622442045FC68205020402043FE4000
+9679:00287DC8448848884BFE508848884908460045FC4504690451FC4104410441FC
+967A:00207C2044504888490452FA4820482045FC4524452469FC5050408841044202
+967B:00007BFE4850505053FE625252524A524BFE4820682053FE4020402047FE4000
+967C:00207C2245FA4824482853FE4820484044FC4584468468FC5084408440FC4084
+967D:00007CFC448448FC488450FC480049FE448044FE452A6A4A5092412240544088
+967E:00007BFE4820504051FC6154515449544954492C682053FE4050408841044202
+967F:00007DFE4510491049FC51104954495445BA4510452869245142418041FE4000
+9680:00087C3C45E048204BFE502049FC492445FC452445FC682051FC402043FE4000
+9681:00007BFE4A0052FC528462FC52844AFC4A204BFE6A4852C842304248428443FE
+9682:00207C50448849044AFE508048F8488044F8448047FE68405088410443FE4002
+9683:004078A04910520855F6600053C44A544A544BD46A54525443D44244425442C8
+9684:00007DFC4504490449FC5104490449FC440047FE44206920513C412042A0447E
+9685:01FC7924492449FC5124512461FC502048204BFE4A226A2A52FA420A42024206
+9686:008079F84A08551050E063185C064BF848404A406BFC544043F840404FFE4000
+9687:000C780A48084BFE520853F8624A524A4BEA4AAC4AAC6A4C52AA430A42164422
+9688:00007BF84A484A4853F85248624853F848004FFE4A406A445228429043084206
+9689:00407D9C4504490449DC5104490449FC4400440045FC68205020402043FE4000
+968A:01047888480053FE504060C251224A54489849386A5450944112461040504020
+968B:004078404BFE508051FC622055FE480049FC490469FC510441FC410441144108
+968C:00407C2045FE4800488450484BFE480044FC4484448468FC5084408440FC4084
+968D:00207C4045FC490449FC510449FC480047FE4420442069FC5020402043FE4000
+968E:01107D1245D4491849525192492E484045FC4504450469FC5104410441FC4104
+968F:0010781049FE5420524060FC514448444E7C4A446A7C524442544248450048FE
+9690:0080788049F84A08541053FC600451FC48044BFC480468405124452A450A48F8
+9691:00207D244524492449FC50004BFE480045FC4504450469FC5088405043FE4000
+9692:00887C50440049FE485051FC48544BFE445445FC445068D85154425240504050
+9693:00207C2045FE484048FC51104AFE4800442045FE444068FC5110421041FE4000
+9694:00007BFE480051FC5104610451FC48004BFE4A8A6A5253FE42224222422A4204
+9695:00007CFC4484488448FC500049FE490245FE450245FE690251FE404840844102
+9696:00407C8045FC4904490451FC490049FE450045FE44026AAA52AA440240144008
+9697:002078404BFC4A24522453FC622452444BFC484048A868B4513C41224222441E
+9698:020879084910480057FC5000611052084C044BF84AA86AA852A842A84FFE4000
+9699:00207CA845244A22480051FC490449FC450445FC442068A85124422240A04040
+969A:00207D2444A84BFE4A0250F84888488844F84420442069FC5020402043FE4000
+969B:010079104BDC52545554628851084AF44C0248006BFC50404150424845444080
+969C:00207DFC448848504BFE500049FC490445FC450445FC682053FE402040204020
+969D:00407C8045FC490449FC510449FC490045FE450045FE680252AA42AA4202400C
+969E:01087908490857D0511E679451244FD44A144BD46A545248424844D444244842
+969F:01247A484924500051FC612451FC492449FC48206BFE507040A8412446224020
+96A0:00087C3C45C04844492450A849FC480444FC440445FC684050A442AA428A4478
+96A1:004078204BFC50005108609053FE4A204AA04AFC6B20522042FC4420442049FE
+96A2:00207C2045FC48204BFE51084B9C49084588463E44006BFE509040904112420E
+96A3:0020792448A853FE50A8612452224904490449DE6A445554409E410442044404
+96A4:00207DFC452449FC482053FE480049FC450445FC450469FC510441FC40884104
+96A5:00107BD248545148508A610452FA4C0049FC4904690451FC4104408847FE4000
+96A6:00107BC84A7E5240526263D452004A3E4BC84A486E7E5248424843C842484008
+96A7:00887C484A5050FC5020605056944A384A504A986A3452544290422045FE4800
+96A8:002079FE4C404AFC511052FE600056FC4A844AFC4A846AFC5284428C450048FE
+96A9:004078804BFE522252AA622253FE4A724AAA4A02682053FE4050408841044602
+96AA:00207C2044504888490452FA4800480045DC4554455469DC5088408841544222
+96AB:00207DFC442048884BFE508849FC490445FC450445FC690451FC408841044202
+96AC:00007BFE49244A2257FE5222637652AA4B764A224B766AAA53764222422A4204
+96AD:000079FC48204BFE522251AC602051AC48004BFE482069FC515441544154410C
+96AE:004078204BFE4888505257AC62AA52A84DAC4800490469FC510441FC41044204
+96AF:00207BFE482049FC500053FE600251FC48204BFE48006BFE500443BE42A4438C
+96B0:00007BFE4A024BFE520253FE610852524B9C49084A526BDE500042A442524452
+96B1:003E7FC04A44492853F8504067FC50004BF848084BF8680853F84544452A48FA
+96B2:00207CA845244A2A483050C04BFE492045FC452045FC692051FE400242AA4004
+96B3:00407BFC488051F84A204DFC688850F8418846C01930E10E1190214845240200
+96B4:011078904BDE4810525E518263DE50104BDE4A504BDE6A5053DE4250425242CE
+96B5:0108F1EC910AA7E8A528C5DEA72894EA940A97EAD40CA7EC8A2A8BEA915687E2
+96B6:010001003FF801080108FFFE010801083FF821081190056009203118C5060200
+96B7:10201020FCFC102411FE7C2400FC7C200124FCA8107054A85324922210A03040
+96B8:10201020FEFC382455FE922410FC7C200124FEA8107054A85324922250A02040
+96B9:0900088008801FFC108030805FF8908010801FF81080108010801FFC10001000
+96BA:020002007FFC450408801FFC308050809FF8108010801FF8108010801FFC1000
+96BB:090008801FFC30805FF890801FF810801FFC10003FF00820044003801C70E00E
+96BC:090008801FFC30805FF890801FF810801FFC11000100FFFE0100010001000100
+96BD:090008801FFC30805FF890801FF810801FFC10003FE00420047C08043014C008
+96BE:00A00090FC8005FE05104B102DFC2910111011FC29102510451081FE01000100
+96BF:28502448248020FE3D90E29020FC2090209020FC20902090149014FE0C800480
+96C0:010011101108212440C003000C803040DFFC10801FF810801FF810801FFC1000
+96C1:00003FFE20002250224824FE24902D9036FE2490249024FE2490449044FE8480
+96C2:08500848148014FE2390529088FC089000907EFC02900490049008FE08800080
+96C3:00507E48248024FE2590269024FCFF90249024FC24902490249024FE44808480
+96C4:0850084808807EFE1190129020FC2890489048FC9090149022907EFE22800080
+96C5:00507E48048024FE2590269044FC7F900C9014FC14902490449084FE14800880
+96C6:090008801FFC30805FF890801FF810801FFC1100FFFE054009203118C1060100
+96C7:010000803FFC20043FFC2280224027FC2C4037F8244027F84440444087FC0400
+96C8:0440FC7E0440010008801FFC108030805FF8908010801FF8108010801FFC1000
+96C9:20A0209020807DFE5110931015FCFD10111011FC11102910251045FE41008100
+96CA:2050204820807EFE439082907AFC4A904A904AFC4A907A904A9002FE14800880
+96CB:090008801FFC30805FF890801FF810801FFC10003E7C2244224423C420142008
+96CC:14501448148054FE55905E9054FC5490549054FC549054905D9076FEC4800080
+96CD:02000100FFFE1050104824FE45907A9010FC2490449078FC0890109020FEC080
+96CE:00507C48448044FE45907E9044FC44907C9044FC449044904E90F0FE00800080
+96CF:205020483E8042FE85900A90FEFC029002907EFC029002900290FEFE02800080
+96D0:010001F801003FFE210221F02F0422FC224027FE2C4037FC244047FC444087FE
+96D1:20502048F88028FE29902A9046FC90901090FEFC10903490529092FE50802080
+96D2:205020483C8044FEC5902A9010FC2890449082FC7C904490449044FE7C804480
+96D3:10501048288044FE83907E9010FC1090FE9010FC54905290929010FE50802080
+96D4:1428122420403F7E64C8A5483F7E244824483F7E2448244824483F7E20402040
+96D5:00287F244940497E5DC849487F7E41485D48557E55485D484148417E45408240
+96D6:00507C48448044FE7D90129010FCFE90929092FCFE901090149012FEFE800280
+96D7:10401040107EFE8011507C4844FE7D9046907CFC1090FEFC1090109010FE1080
+96D8:00443DFE2454244834FE2D9024FE2490FEFE249024FE248025FE244444388DC6
+96D9:081024483F7E64C8BF7E24483F7E24483F7E20401FF00820044003801C70E00E
+96DA:0820FFFE08203EF822883EF8090008801FFC30805FF890801FF810801FFC1000
+96DB:202820247F40917E55C87D48217E4A48A4487F7E914855487D48217E4A408440
+96DC:10500848FE8000FE259026905AFC91901090FEFC10905490929012FE50802080
+96DD:492892244940007E7CC845487C7E0048FE48927E9248FE488148817E7F400040
+96DE:0E50F048228092FE4590229044FCF890109024FCFE901090FE9028FE44808280
+96DF:010042047FFC08803440CFFC18802FF848800FFE08003FFC24242BD4224423CC
+96E0:30182A1441207D3ED06853287D3E512851287D3E5128516851A87D3E40204020
+96E1:0028EE242240AA7E66C8AB48187E66488948307EC4481948E2480C7E3040C040
+96E2:102808247F40147E49C85548417E7F4808487F7E514855485D48417E45404240
+96E3:22282224FF40227E3EC809487F7E49487F48087E7F480848FF48147E22404140
+96E4:3AB821083AB82288393822887FFE48829FFC30805FF890801FF810801FFC1000
+96E5:08801FFC30805FF890801FF810801FFC24483F7E64C8BF7E24483F7E24483F7E
+96E6:318C294A22107BDE56B4D2947BDE529452947BDE5294529452947BDE42104210
+96E7:08801FFC3080DFF810801FFC14283F7E64C8BF7E24483F7E0100FFFE0920711C
+96E8:0000FFFE0100010001007FFC4104410449444524410449444524410441144008
+96E9:3FF801007FFE41029D7401001D7000003FF80000FFFE04000FF0001000A00040
+96EA:3FF801007FFE41029D7401001D7000003FF8000800081FF8000800083FF80008
+96EB:00003FF801007FFE41029D7401001D700000FFFE020002400220021002000200
+96EC:00003FF801007FFE41029D7401001D70000001007FFC038005601918E1060100
+96ED:3FF801007FFE41029D7401001D7000003FE008400CF81210112020C043309C0E
+96EE:00003FF801007FFE41029D7401001D70000001F03E0003F03E0003FA7E0201FE
+96EF:3FF801007FFE41029D7401001D70020001007FFC08200440038004401830E00E
+96F0:3FF801007FFE41029D7401001D70044008203018DFE604200420082010A02040
+96F1:3FF801007FFE41029D7401001D70020001007FFC040007F00410081010A06040
+96F2:3FF801007FFE41029D7401001D7000003FF800000000FFFE082010103FF80008
+96F3:3FF801007FFE41029D7401001D7000003FFC200021002FF82108420844509820
+96F4:00003FF801007FFE41029D7401001D70020001003FF8000008200440FFFE0000
+96F5:3FF801007FFE41029D7401001D70000001001FF011101110FFFE02801C70E00E
+96F6:3FF801007FFE41029D7401001D7002800C603218C1061FE00020064001800040
+96F7:00003FF801007FFE41029D7401001D7000003FF8210821083FF8210821083FF8
+96F8:00003FF801007FFE41029D7401001D70000008207FFC08200FE008200FE00820
+96F9:3FF801007FFE41029D7401001D7008001FF020105F9010901FD0102010040FFC
+96FA:3FF801007FFE41029D7401001D7000001FF0022001407FFC0484188862800100
+96FB:3FF801007FFE41029D7401001D7000003FF821083FF821083FF80102010200FE
+96FC:3FF801007FFE41029D7401001D7000007FFC040008001FF82808C8080FF80808
+96FD:3FF801007FFE41029D7401001D70000000F87F0011100920FFFE010005000200
+96FE:3FF801007FFE41029D7401001D7004000FE0144003801C70E20E0FE004201860
+96FF:3FF801007FFE41029D7401001D700000244814500C601450644808421042603E
+9700:00003FF801007FFE41029D7401001D700000FFFE02003FF82488248824A82010
+9701:3FF801007FFE41029D7401001D7000807FFC082007C01830E44E044008401040
+9702:00003FF801007FFE41029D7401001D702040104087FE50E02150E24824442842
+9703:3FF801007FFE41029D7401001D70204013FC824454A810A0E1222222241E2800
+9704:3FF801007FFE41029D7401001D70111009203FF820083FF820083FF820082018
+9705:3FF801007FFE41029D74000001007FFC00003FF800003FF800003FF820083FF8
+9706:3FF801007FFE41029D7401001D7000087C3C09E010203DFC44202BFE10006FFE
+9707:3FF801007FFE41029D7401001D7000003FFC20002FF820003FFC24484430860E
+9708:00003FF801007FFE41029D7401001D70204017FC40402BF80A48724812581040
+9709:3FF801007FFE41029D7401001D7010001FFC20005FF01210FFFE20903FFC0030
+970A:3FF801007FFE41029D7401001D7000001FF000007FFC044024481450FFFE0000
+970B:3FF801007FFE41029D7402001FF002107FFC02101FF004007FFC082007C07838
+970C:3FF801007FFE41029D7400003FF8210827C821082FE8200827C8444847C88018
+970D:3FF801007FFE41029D7401001D7008801FFC30805FF890801FF810801FFC1000
+970E:3FF801007FFE41029D7401001D7002003FF808207FFC0200FFFE082007C07838
+970F:00003FF801007FFE41029D7401001D7004407C7C04403C7804407C7C04400440
+9710:3FF801007FFE41029D7401001D70000027881088878854102790E0A422BE2102
+9711:3FF801007FFE41029D7401001D7020001040807C48400BF81208E20823F82208
+9712:00107F100810FFA888A86B4408A26B1000107E7C0004FF04100822087F100110
+9713:3FF801007FFE41029D7401001D70060038F820083CF820083FF808421042E03E
+9714:3FF801007FFE41029D7401001D702080104087FC4040104023F8E040204027FC
+9715:00107F10087EFF9088906B5408546B5400547F7C0014FF90101222127F12210E
+9716:3FF801007FFE41029D7401001D70082008207EFC08301C682AA4C92208200820
+9717:3FF801007FFE41029D7401001D70204010A00158462629F0081070A010401020
+9718:3FF801007FFE41029D7401001D70200013FC020442F42A040AF4729412F4120C
+9719:3FF801007FFE41029D7401001D700820FFFE09201FF01110FFFE02801C70E00E
+971A:00003FF801007FFE41029D7401001D7000207E20247E18A4FF2829104A2898C6
+971B:3FF801007FFE41029D7401001D7000007BDE08427BDE42107BDE0842294A1084
+971C:3FF801007FFE41029D7401001D70000008FC7E8418FC2C844AFC888408FC0884
+971D:00003FF801007FFE41029D7401001D7000007BBC4AA44AA44AA44AA47BBC4AA4
+971E:3FF801007FFE41029D7401001D7000003EF822083EF820003EF820483E3020CC
+971F:3FF801007FFE41029D7401001D701090089043FC2090089017FE709011081204
+9720:3FF801007FFE41029D7401001D7020201050FC8849444A2210F81E08F0104020
+9721:3FF801007FFE41029D7401001D7000203C1024E03C2225B43CA8252426A24C40
+9722:3FF801007FFE41029D7401001D70000C7DF045087D7045447D68455055488A66
+9723:3FF801007FFE492284140FE008203FF820083FF820083FF820083FF808201010
+9724:3FF801007FFE41029D74040079FC40444844545462883FF821083FF821083FF8
+9725:3FF801007FFE41029D7400007FFE40029FF406003B0804B019C062A00C987306
+9726:3FF801007FFE41029D7401001D7022042208F7B022047708AAB2224422182260
+9727:3FF801007FFE41029D74000000407EFC15440838FE441AA22CFC4844A8941108
+9728:3FF801007FFE41029D7400003F0821083F7E20082F4820285F88440895282C90
+9729:3FF801007FFE41029D740000087C7F4422483E5000483E4404647F5808401840
+972A:3FF801007FFE41029D7401001D70203C17C08244412817FC2040EFFE204027FC
+972B:3FF801007FFE41029D7400007EFC22441A3462C404001FF010101FF010101FF0
+972C:3FF801007FFE492284143FF821083FF821083FF804403FF80440FFFE08201010
+972D:3FF801007FFE4922841423F8120803F8720813F8110013FC14441AA413F4000C
+972E:3FF801007FFE49228414211017FC911041F0411011F02110E7FC2250228823FC
+972F:3FF801007FFE41029D74000000907EA004442BA810102FE8C8260FE004407FFC
+9730:3FF801007FFE41029D74000012203F20123E7F4400A43F2421283F1021282346
+9731:3FF801007FFE49229FF402207FFC04887A8001003FF8282837D8244827C82018
+9732:3FF801007FFE41029D7401001D7000407CF845487C3011CE5C0050F85C88E0F8
+9733:3FF801007FFE41029D74008079F84A884870538E492049FC6A2050F8402043FE
+9734:00207C2010FCFE2493FE542410FC542001247CA80070FEA821244822FCA00440
+9735:3FF801007FFE41029D7400003E2822243E240020FFFE22243E282392FE2A0246
+9736:3FF801007FFE41029D74008047FC21100FFE884257FC1100E1F8220822282410
+9737:3FF801007FFE4922841401F8790849F849084BFE79004BFC4CA449247A544888
+9738:3FF801007FFE41029D7422007F7C22443E44087C7F4449447F7C0844FF540888
+9739:3FF801007FFE41029D7401001D7000107EFE42447E2840FE7E10627CBE102210
+973A:3FF801007FFE41029D7401001D702010455097DE20246FD4A014278824D428A2
+973B:3FF801007FFE41029D7404403FF824483FF824487FFC10101FF00820FFFE0000
+973C:00807C8010FCFF0092F8540011F8544801687CC801F8FE4A20EA495AFC460442
+973D:3FF801007FFE49228514FFFE02887D7025484D6690101FF010101FF010102010
+973E:3FF801007FFE41029D743000CBFC2D2431FCC92415FC64200DFC3420C5FE1800
+973F:3FF801007FFE41029D7400807DF8068828701088FD0634F8508890F8508820F8
+9740:3FF801007FFE41029D7408207FFC08207FFE40029FF40600192006C038A00318
+9741:3FF801007FFE492284143FF821083FF821083FF80000FEFE9292FEFE9292FEFE
+9742:3FF801007FFE492284147FFE40005F3C44107F7E4E345552609044F84480BFFE
+9743:3FF801007FFE41029D7401001D70081024483F7E64C8BF7E24483F7E24483F7E
+9744:3FF801007FFE4922A41411FCFD0401FC790401FC788001FE7A224D5279FA4806
+9745:00287CFE102AFEFE92A854FE104A54FE00827CFE0082FEFE208248FEFC440482
+9746:00107E10117CFE1492FE5414137C559201547D380154FF9221304900FEFE0400
+9747:3FF801007FFE41029D74000008407F7C1440FF7C22043E7C22403E7C2242263E
+9748:3FF801007FFE41029D7401001D7000003BB82AA83BB800007FFC11102928FFFE
+9749:000E7DF010A2FE5493FE552210145552014A7E380040FE7C20844948FC3004CE
+974A:3FF801007FFE41029D74000049245D7449247FFC00003FF808200FE004407FFC
+974B:3FF801007FFE41029D74200017FE840047DC148827FEE5CC26AA293C292013FE
+974C:3FF801007FFE492285147FFC40843CF809283CB009287FF011101FF008201010
+974D:3FF801007FFE41029D74284024FC7E8448FCFE8448FE7E8048FE48027EAA4004
+974E:3FF801007FFE41029D74084014FC22845CFC88843EFE08804AFE28020EAA7004
+974F:3FF801007FFE41029D7410407EFC528428FC3E8468FEBE8028FE3E0228AA3E04
+9750:3FF801007FFE49229FF411101FF000007C7C1010FEFE929254547C7C54547C7C
+9751:010001007FFC01003FF80100FFFE00001FF0111011101FF01010101010501020
+9752:010001007FFC01003FF80100FFFE00001FF010101FF010101FF0101010501020
+9753:100010FCFE8410847CA410A4FEA400A47CA444A47C5044507C5044925492490E
+9754:10401040FE7E10807D00107CFE0000007CF844087C0844087C0A440A54064802
+9755:00200020FDFE102010FC102051FE5C0050FC508450FC50845CFCF08400940088
+9756:2020102013FEFC2001FC08208BFE880049FC490451FC51041DFCE10441140108
+9757:10201020FD2410A47CA81020FDFE00507C5044507C5044507C924492550E4A00
+9758:10401040FCFC10887D1010FCFEA400A47CA444FC7C8044807C824482447E4C00
+9759:10401040FE7810887C1011FCFE2400247DFE44247C2445FC7C24442054A04840
+975A:100011FCFF0411047DFC1104FF0401FC7D0445047DFC44507C90449255124A0E
+975B:10201010FEFE10827D041000FEFE00107C1044907C9E44907C9044D0553E4A00
+975C:101E11E0FE92104C7C0010FCFE2400247DFE44247C2444FC7C24442054A04840
+975D:10801080FCFC11007EF81000FDF800487D6844C87DF8444A7CEA475A54464842
+975E:044004400440FC7E0440044004407C7C0440044004400440FC7E044004400440
+975F:044004407C7C04403C7804407C7C044000F03F0001F03F0001F87F02010200FE
+9760:11001FF02100FFFE00001FF010101FF004407C7C04403C7804407C7C04400440
+9761:00803FFE24103F7C26382D543412212021203F3E21202F3C21205F3E41208120
+9762:0000FFFE0200020004003FF82448244827C82448244827C8244824483FF82008
+9763:0000FFFE0200020004003FF82008200827C82448244827C8200820083FF82008
+9764:0040FE4010FC2084FF04AAF4AA94BA94AAF4AA84BA94AA88AA82FE82827E0000
+9765:3FFC20903FFC21402630380C27F020802FF82A282BE82A284BE84A288FF80808
+9766:0000FEFC10842084FEFCAA84AA84BAFCAA84AA84BAFCAA50AA50FE528292010E
+9767:0010FEFE109220FEFE10ABFEAA00BAFEAA82AAFEBA82AAFEAA82FEFE82440082
+9768:3FFE28882F8A20082FBE28882F88289429A23FFE20802FFC292449E449248FFC
+9769:082008207FFC082008200FE001003FF8210821083FF80100FFFE010001000100
+976A:22002200FF7E22083E0808087F08490849087F080808FF880808080808280810
+976B:280029F8FE8828C838A810A87C88545054507C501020FE201050108811041202
+976C:2200227CFF1022103E1008107F1049FE49107F100810FF900810081008100810
+976D:22002200FF7E22123E1208527F52495249527F920812FFA20822084208940908
+976E:22202220FF20227E3E4208827F02498249427F220822FF820802080208140808
+976F:22102210FF1022103E10087C7F10491049107F100810FF90081008FE08000800
+9770:28002800FDFC2890389010907C90549054907C901090FC9210921092110E1200
+9771:28002800FDFC2844384411447CC4544454647C54104CFC861084110412281410
+9772:28202820FE202850385010887D44562254207CF81008FE081010101010201020
+9773:2204220EFF7022403E4008407F7E494849487F480848FFC80848088808880908
+9774:28502850FE502892389211947E98549054B07CD01090FE9010921092108E1080
+9775:280029F8FE482848384810487C4855F854887C881088FE881088108813FE1000
+9776:280029FCFD242924392411247D2455FC55047D001100FD001102110210FE1000
+9777:280429E4FE242824382411E47D04550455047DE41024FE241024102411441084
+9778:28002BFCFC842888388810907C9C548455447D441128FD281210122814441182
+9779:28202820FE2029FE392211227D22552255527D4A118AFF0211021102110A1104
+977A:28202820FC202BFE382010207C2055FC54707CA810A8FD241124122210201020
+977B:280028F8FE882888388810F87C88548854887CF81088FE881088108813FE1000
+977C:28002800FEFC2884388410847CFC548454847C8410FCFE841000100011FE1000
+977D:28202820FD2428A438A810207DFC542054207C2013FEFC201020102010201020
+977E:282828A8FEA828A838A813FE7CA854A854A87CA810B8FE801080108010FE1000
+977F:50105090F8905110717E2252FB92A892A912F9122252FBD220622022204A2084
+9780:280029FCFE442844384410447C94548855007CFC1084FE841084108410FC1084
+9781:28102810FE1029FE391211147D1055FC55447D441128FF281110122812441482
+9782:2808283CFDE02820382010207DFE542054707C6810A8FCA41122102010201020
+9783:280829C8FE482848384811C87D08550855107DD01054FE541052105E12821100
+9784:28402840FEFC2884390412F47C94549454F47C841094FE8810821082107E1000
+9785:28202820FE2029FC392411247D24552455247FFE1020FE501050108811041202
+9786:280029FEFC202820382011FE7D22552255527D4A118AFD0211021102110A1104
+9787:280029FCFD042924392411247DFC552455247D54114CFD8C1104110411FC1104
+9788:28202820FE502848388411027CFC540054007CFC1084FE841084108410FC1084
+9789:28502850FE50295238D410587C50545854D47D521050FE50109210921112120E
+978A:28202820FC202BFE382010207DFC540054007DFC1104FD041104110411FC1104
+978B:28202820FEFC2820382010207DFE540054207C2010FCFE201020102011FE1000
+978C:01007FFC44043FF8082007C0783804407FFC044007C001001FF01110FFFE0100
+978D:28402820FC202BFE3A0214447C4057FE54887C881108FCD01020105010881304
+978E:280028FCFE84288438FC10847C8454FC54A27CA41098FE90108810A410C21080
+978F:7CF8108810CA1D2AF20608207FFC08200FE001003FF821083FF80100FFFE0100
+9790:28202820FE3E2820382011FE7C00540055FE7C201028FE241022102010201020
+9791:28102910FC902890387E10107D90549054987CA810A4FCC410801140123E1000
+9792:2808281CFEE02820382011FE7C50548855047E8A1088FE881088108810881108
+9793:280028FCFE842884388410FC7C00540055FE7C201020FEFC1020102011FE1000
+9794:28802880FCF829083A1011FC7D24552455247DFC1050FC50109010921112120E
+9795:280029FEFC20282039FC11247D2455FC55247D2411FCFD2010A0104010B0130E
+9796:2804281EFDE02822391210947C80542055FE7C441084FDC81030102810C41302
+9797:108011F8128820702B8E68886BFEA88828F8282029FC292429FC202023FE2020
+9798:28102892FE522854381010FE7C82548254FE7C821082FEFE10821082108A1084
+9799:280028F8FE88288838F810007DFC550455047DFC1104FF0411FC110411141108
+979A:28202810FE1029FE390212547C88550454007CFC1020FE201020102011FE1000
+979B:28202810FEFC2800388810507C0055FE54007C0010FCFE841084108410FC1084
+979C:28202822FDB428A838A811247EA2544055FC7D041104FDFC1104110411FC1104
+979D:28202924FCA428A8382011FC7D04550455747D541154FD541174110411141108
+979E:28202840FCFE2892389210FE7C9254A254FE7C481088FDFE1008100810081008
+979F:28202810FDFE280038FC10847CFC540054FC7C081010FDFE1010101010501020
+97A0:28802880FEFE29023A2210AA7C72542255FE7C221072FEAA11221022100A1004
+97A1:28902888FC8828BE3BC010827CA254E254927D921294FC941084108812BE1100
+97A2:28482948FD482BFE394811487D78550055FE7C2013FEFC7010A8112416221020
+97A3:280029FCFC4828303BFE10527C94551056307C2013FEFC7010A8112416221020
+97A4:08087F0808FEFF0808487F2808080F28F01004407FFC04401FF01110FFFE0100
+97A5:28202830FE482884397A10007CFC548454847CFC1048FE4811FE104810881108
+97A6:500850C8FB085108712A212AFBACA948A908FB882554F9142114212421242142
+97A7:28882848FC502BFE385010507DFC555455547D8C1104FDFC1104110411FC1104
+97A8:280029FCFD0429FC390411FC7C8055FE56227D221152FD0211FA100210141008
+97A9:50825082FAA251CA708A23EAFA2AAA2AABEAFA2A222AFBEA2222222222AA2244
+97AA:7E20243E1848FFA829104A28984604407FFC044007C001001FF01110FFFE0100
+97AB:28802880FCFE29023A4211FA7C0255F254027DF21002FDF2111211F210141008
+97AC:50105010F87C571471FE2114FA7CAA10AF7CF91021FEFD102210230024FE2800
+97AD:288028FEFE90297C395413547D7C555455547D7C1190FF501120113011481186
+97AE:280028FCFE84288438FC10847C8454FC54007DFE1020FEA010BC10A01160123E
+97AF:28482848FDFE2848382011FE7C40544054BC7D841288FCBE1088108810A81090
+97B0:280028F8FE88288838F810887C8854F854007DFC1154FF541154115413FE1000
+97B1:281E28E0FE222892385410407C2054CE54827C8210EEFE821082108210FE1082
+97B2:50885088FBFE508871FC2088FBFEA820A9FCF92421FCF92423FE210421142108
+97B3:28882888FDFE2888382010507C88550456FA7C001000FDFC1104110411FC1104
+97B4:50885088FBFE5088708827FEF880A9FCAB24FDFC2124F9FC212421242124210C
+97B5:281E2BE0FD222894384010887DF0542054C47DFE1022FC2013FE105010881306
+97B6:08783E48228E2A007EF822482A3046CC7FFC044007C001001FF01110FFFE0100
+97B7:7FFC08200FE000003FF824482FE82108211804407FFC04401FF01110FFFE0100
+97B8:280029FCFD2429FC392411FC7CA854A857FE7CA810A8FDFC102013FE10201020
+97B9:5100509EFBD2501273D42254FBD8A814ABD2F8522092F8DA2394209022902110
+97BA:28202924FCA82BFE3A0210F87C88548854F87C201020FDFC1020102013FE1000
+97BB:282029FCFD242BFE392411FC7C2055FC55247DFC1040FDFE108811D01070138C
+97BC:282029FCFD2429FC382013FE7C0055FC55047DFC1104FDFC110411FC10881104
+97BD:281829E0FC402BFE388811747E52547054007DFC1104FD74115411741104110C
+97BE:28882BFEFC88280039FC10A87CA857FE54A87CA811FCFC2013FE102010201020
+97BF:51245124FAAA53AE712422AAFBAEA924AFFEF9102114F914228A224A22162422
+97C0:50405020FBFE525073FE2252FBFEAA80AAFEFA8022FEFA02255625562A022006
+97C1:28002BFEFC0029FC392411FC7D2457FE54007DFC1124FDFC112411FC100013FE
+97C2:288028F8FD082BFE394411927DFE5500557C7D00117CFD00117C1244127C1444
+97C3:28102A10FD7C281038FE10447F2855FE55107D7C1110FDFE1110111012FE1400
+97C4:28882BFEFCA8289039FE13207DFC552055FC7D2011FEFD0013FC10881070138E
+97C5:280029FCFD0429FC390411FC7C88555455DC7C881154FDDC100011A811541254
+97C6:500050FEFC2852FE72AA20FEF810A9FEAE44FAFE2344FA7C2242223E250028FE
+97C7:28202BFEFC2029FC380013FE7E5257FE55047DFC1104FDFC110411FC10881104
+97C8:284829FEFC48280039FE114A7D4A55FE54147DFE1110FD92114C114A11161222
+97C9:508853FEF888502073FE2250FBFEAA52ABFEFA8022FEFA8022FE24022AAA2004
+97CA:508853FEF88853DE725223DEFA52ABDEAA22FBFE22AAFAFA2222227222AA2224
+97CB:020002003FF00410FFFE00001FF010101FF001003FF8010021003FFC01000100
+97CC:100010007EFE2212FF1200527E5242527E9208127E12082248227E42088A0904
+97CD:102810247E242220FF7E00207E20423C7E3408547E54085448887E8809140822
+97CE:101010107E1022FEFF1000107E10427C7E1008387E38085448547E9208100810
+97CF:111009207FFC0400FFFE12102FE8C4263FF810101FF001001FF021003FF80100
+97D0:102010207C502450FE8801047EFA44007C0010F87C88108850887C8810F81088
+97D1:102011FC944455FE580011FCFD0429FC282029FC2820292029FC4820482287FE
+97D2:101010927E522254FF1000FE7E8242827EFE08827E8208FE48827E82088A0884
+97D3:1020102010FCFE4411FE7C0044FC7C8444FC7C1010FCFE10109010FE10101010
+97D4:1000107C7E402278FF4000787E4043FE7EA008A47E98089048887EA408C20880
+97D5:102010107EFE2200FF7C00447E7C42007E7C08087E1008FE48107E1008500820
+97D6:100010FC7C482430FEFE00527C9445507C2010107DFE103850547C9211101010
+97D7:100011FE7D022420FEFC00207DFC45247DFC11247DFC102053FE7C2010201020
+97D8:101410547E5422FEFF5400547E5C42407E7E08107EFE081048387E5408920810
+97D9:00103E7C22243EFE22003E7C0044FF7C0810083C2F50287E281058104FFE8000
+97DA:108810887DFE2488FEF800207DFC45247D2411FC7C2013FE50207C2010201020
+97DB:104410447DFE2444FE4401FE7C4044FE7D9212FE7C9210FE50927C9210921086
+97DC:101E11E07C222512FE9400807C2045CE7D0211027DCE110251027D0211FE1102
+97DD:104810487DFE2448FEFC00487DFE44107CFC10947CFC109451FE7C8410941088
+97DE:100010F87C882488FEF800887C8844F87C0011FC7D54115451547D5413FE1000
+97DF:101010207E7C2244FF7C00447E7C42107EFE08287E540892487C7E1008100810
+97E0:100010FE7E9222FEFF9200FE7E5442547EFE08547E5408FE48107EFE08100810
+97E1:104410FE7E442200FFFE00547E5442FE7E5408547EFE081048FE7E1008100810
+97E2:101010107DFE2410FEFC00947CFC44947CFC10127DFE102250147D52114A1238
+97E3:100011FC7D542554FFFC00807DFC46447DF411547D5411F450447DF410141008
+97E4:104811FE7C482400FFFE014A7D4A45FE7C1411FE7D101192514C7D4A11161222
+97E5:101010FE7E10227CFF0000FE7EAA42FE7E44087C7E44087C48447E7C08280844
+97E6:0100010001007FFE010001003FF8010001007FFC010401040104012801100100
+97E7:2000200021FCFC24202420A4F8A420A42124FC24242424443444288421142208
+97E8:205020482048FC4021FE2040F840207C20A4FCA424A8252835102A2820442082
+97E9:102010201020FEFE10207C2044FC7C2044207DFE1022FE22102A102410201020
+97EA:00203E2022FC3E2022203EF80020FF2008FC08242F242834282858204FFE8000
+97EB:200020F82088FC8820F82088F88820F82000FDFC255425543554295423FE2000
+97EC:201E21E02022FD1220942080F82021CE2102FD0225CE25023502290221FE2102
+97ED:044004407C7C0440044004407C7C0440044004407C7C044004400440FFFE0000
+97EE:08200820FFFE0820082004407C7C044004407C7C044004407C7C04400440FFFE
+97EF:082008287F240820FFFE0020122473A4122473A812287390121217AAF8464082
+97F0:08000F7C28447F28A110162838C6C2807EFC02803EF802807EFC0280FFFE0000
+97F1:112011282AA444640020FFFE122073A4122473A812287390121217AAF8464082
+97F2:0100FFFE02847D78255025484D6402807EFC02803EF802807EFC0280FFFE0000
+97F3:020001003FF8000008200440FFFE00001FF0101010101FF0101010101FF01010
+97F4:200013FE7C200020442029FCFF2401247D24452445247D34452844207C204420
+97F5:204010407C8000FC45042A04FE8400447C44441444247C44458444047C284410
+97F6:200011FC7C44004444442844FE9400887D0044FC44847C84448444847CFC4484
+97F7:201010107C92009244922892FEFE00107C10449244927C92449244927CFE4402
+97F8:204010407CFC008845502820FED803267CF8442044F87C2047FE44207C204420
+97F9:202010407CFC008444FC2884FEFC00007DFE442044207CFC442044207DFE4400
+97FA:208810887DFC008844A82820FEF800A87CA844A844A87DFC442044507C884504
+97FB:2000107C7C440044447C2800FEFE00827CFE448244FE7C8244FE44287C444482
+97FC:20201220797C00A4481830E6FB10017E7910497C491079FE491049107AFE4C00
+97FD:1020281044FE92007C440828FEFE2800FE7CAA44CE44827CFE448244FE7C8244
+97FE:08007F7808483E4800863E782A483E30414EBFFC0440FFFE10101FF010101FF0
+97FF:110023DE7A5213D42A527BDA1294235001003FF80440FFFE10101FF010101FF0
+9800:204411FE7C54004844FE2990FEFE00907CFE449044FE7C8045FE44447C3845C6
+9801:00007FFE020004001FF8100810081FF810081FF8100810081FF8081010082004
+9802:000001FEFE20104011FC1104110411FC110411FC1104110411FC108851042202
+9803:000021FE2020204021FC3D04210421FC210425FC2904310421FC008801040202
+9804:200020FE20102020FCFC2484248424FC248424FC2584268444FC404880840102
+9805:000001FE0020FC4011FC1104110411FC110411FC11041D04E1FC408801040202
+9806:040045FE5420544055FC5504550455FC550455FC5504550455FC548885040602
+9807:00007CFE1010102010FC10841084FEFC108410FC1084108410FC104810841102
+9808:080009FE1020204041FC8904090411FC210445FC8504090411FC208841048202
+9809:080009FE0810082048FC4E84488448FC488448FC48844E8458FCE04800840102
+980A:000001FE7C20104011FC11047D0411FC110411FC11041D04E1FC408801040202
+980B:00007EFE401040205EFC5284528452FC5A8454FC5084528454FC584850848102
+980C:000028FE2410242042FC5284908410FC208420FC48844484FCFC444800840102
+980D:100011FE1020FE4011FC1104FD0405FC050449FC2904110429FC448881040202
+980E:08001DFE6020404041FC41047F0449FC490449FC4904490449FC488889040A02
+980F:100008FE0810FF2000FC00843C8424FC248424FC2484258446FC444880840102
+9810:00007CFE0410282010FC0884FE8412FC148410FC1084108410FC104850842102
+9811:00007CFE0010002000FCFE84288428FC288428FC28842A844CFC484880840102
+9812:000028FE2410242042FC428480847CFC248424FC2484248444FC444894840902
+9813:100011FE1020FE4011FC5504550455FC55047DFC1104110415FC188811040202
+9814:100011FE10207C4055FC5504550455FC7D0455FC5504550455FC7C8845040202
+9815:100010FE10101E2010FC1084108410FC7E8442FC4284428442FC7E4842840102
+9816:100011FE9420584011FC7D04110411FCFF0411FC1104110421FC208841048202
+9817:080008FE08107F20497C4A4448447F7C4144527C4A4444444A7C910021280044
+9818:100011FE2820244043FC9104090401FCFD0405FC0904510421FC108811040202
+9819:000001FEFC20104011FC110451045DFC510451FC510451045DFCF08801040202
+981A:00007CFE0410682010FC2884448492FC10847CFC108410841EFCF04840840102
+981B:100010FE1010FE2010FC7C841084FEFC308438FC5484548490FC104810841102
+981C:100011FE2820244043FC81047D0401FC01047DFC4504450445FC7C8845040202
+981D:200010FE0010FE2000FC2884448482FC048444FC2884108428FC444884840102
+981E:100008FE7E10422094FC10841084FEFC248424FC4884288410FC284844848102
+981F:200020FE3C104420C4FC2884108428FC448482FC7C84448444FC44487C844502
+9820:1000107E3F102120427CBFC420442F7C2944297C2D442A44287C4A004C288844
+9821:100010FE1010FE2010FC10847C8400FC00847CFC4484448444FC7C4844840102
+9822:08001DFE7020104011FCFD04110411FC7D0445FC4504450445FC7C8845040202
+9823:00007EFE4810482048FC7E84428442FC7E8448FC4884488448FC7E4800840102
+9824:00007DFE4820484049FC5D04550455FC55045DFC4904490449FC7E8801040202
+9825:40005F7E54105420547C5F445144517C51445F7C54445444547C54005F284044
+9826:100008FE0810FF2008FC108422847CFC098412FC2484C88414FC2248C0840102
+9827:080011FE7C20444045FC45047D0441FC41047DFC4504450445FC7C8845040202
+9828:0000EEFE22102220AAFC6684228422FC26846AFCB284228422FC2248AA844502
+9829:420024FE00107E2024FC2484248424FCFF8424FC2484248424FC444844848502
+982A:080008FE4A102A202CFC0884FE8418FC1C842AFC2A84488488FC084808840902
+982B:280028FE28102820AAFC6C84288428FC6C84AAFC288428842AFC4C4848848102
+982C:080008FE08107E2008FC4A842A842CFC0884FEFC0884148412FC224840848102
+982D:0000FEFE002000407CFC4484448444FC7C8400FC448428842EFCF00040480084
+982E:0800097EEA102C204A7C4944A844107C2444247CFF442444247C440044288444
+982F:100010FE3E10622094FC48843084C0FC248424FCFF84248424FC444844848502
+9830:080008FE0810FFA0087C2A442A442A7C5D4488FC08441444127C210041288044
+9831:04001EFEE010222092FC5484408404FCFF8404FC4484248424FC044814840902
+9832:000001BE76081210123E222227A2723E1222523E522227A2203E50008F940022
+9833:100010FE10107C2010FC1084FE8428FC28846CFCAA84288428FC484848849902
+9834:40004CFE7010422042FC3E8400847CFC0084FEFC1084548452FC924850842102
+9835:00007EFE12101220FF7C124412447E7C2044207C7E446244A27C22003E282244
+9836:080028FE28103E2048FC0884FF8400FC00843EFC2284228422FC3E4822840102
+9837:080008FE1410222051FC88847E8402FC048408FC7E84428442FC7E4842840102
+9838:0000FEFE54105420A8FC5484548400FCFE8410FC108410841EFCF04840840102
+9839:0C0070FE1010FE2010FC3884548492FC008428FC288428842AFC4C4848848102
+983A:0C0070FE1010FE2010FC3884548492FC7C8424FC28842E8422FC42484A848502
+983B:080008FE28102E2028FC2884FF8400FC08842AFC2A844C8484FC08483084C102
+983C:100010FEFE10102010FCFE84928492FCFE8410FC3884548492FC104810841102
+983D:0C0070FE1010FE2010FC3884548492FC008438FC288428842AFC4C4848848102
+983E:0BFE104061FC090411FC610405FC090431FCC088090428802E9828E22E82F07E
+983F:060018FE62100C20737C0C44F444147C55445E7C54445544557C5D00F3280044
+9840:140012FE20103F20647CA4443F44247C24443F7C24442444247C3F0020282044
+9841:1000087E7F104120827C00447F44087C0844287C2E442844287C58004F288044
+9842:100010FE1010FE2010FC5484548454FCBA8410FC3884548492FC104810841102
+9843:100052FE5410902028FC4484828410FC108452FC5484908428FC244842848102
+9844:00007F7E02100420497C6B445D44497C5D446B7C49446944517C470079280044
+9845:100008FE7E10422042FC7E8440845EFC52845EFC52845E8452FC524892841702
+9846:00007F7E491049207F7C494449447F7C0844FF7C1C442A44497C880008280844
+9847:100008FE00107F20007C22442244557C88C4087CFF440844087C080008280844
+9848:40004CFE7010422042FC3E84208444FC788410FC2484FE8410FC544892843102
+9849:100010FE2810242042FCBC84108410FCFE8410FC9484588450FC1E48F0844102
+984A:100020FE7E1042207EFC40847E8442FC7E8410FC1084FE8410FC104810841102
+984B:00007F7E491049207F7C494449447F7C0844047C154450C450FC52808E280044
+984C:00003EFE22103E20227C3E44007CFF44087C08442F7C2828284458824FFE8000
+984D:200010FEFE10822020FC3C844484A8FC108428FC4484FE8444FC44487C844502
+984E:0000EEFEAA10AA20EEFC00847C8400FCFE8420FC40847C8404FC044828841102
+984F:100008FE7F1022201CFC22847F8444FC488472FC4484488471FC42488C847102
+9850:0000FEFE92101020FEFC10847C8454FC7C8454FC7C841084FEFC104810841102
+9851:020002BE02087F90423E42225E2242BE42A25EBE56A255225D7E414042D48462
+9852:00007CFE541054207CFC548454847CFC1084FEFC92849684BEFC82488A848502
+9853:100092FE92109220FEFC0084FE8410FC2084FEFCAA84AA84AAFCAA48AA848702
+9854:100008FE7F102220147C7F444444487C5244447C48445144427C440088283044
+9855:00007CFE441044207CFC448444847CFC288428FCAA846C8428FC2E48F0844102
+9856:0800107E7F104120557C49445544417C7F44087C054454C450FC92000E280044
+9857:0800497E49107F20007CFF4400447F7C4144417C7F444244247C0F00F0284044
+9858:00007F7E441048205F7C51445F44517C5F44447C56445544657C450094280844
+9859:00007EFE22101C20227C77445544227C5544087C7F441C442A7C490088280844
+985A:4600787E40903FA0007C5F4451445F7C51445F7C51445F44407C7F8022284144
+985B:100010FEFE1010207CFC44847C8444FC7C8444FC7C844484FEFC284844848302
+985C:2200223EFF8822107F3E2222FFA2083E7F22493E7F224922FFBE410045144222
+985D:00007CFE4410742054FCFE8482847CFC44847CFC44847C8444FC444854844902
+985E:100092FE5410FE2030FC5484928400FC148412FCFE84108428FC244844848102
+985F:0000777E11105520337C55440C44337CC4C4187C62440CC4717C06001828E044
+9860:0000FEFE2810FE20AAFCAA84FE8400FC7C8400FCFE84108454FC924850842102
+9861:100008FE7F102220147CFF441044297CCE44147C2644CD44157C2400D4280844
+9862:2200223EFF882210223E3E220822FFBE88A2CCBEAAA2DDA288BE88808A948922
+9863:0200029E02047FC8421E4A124E124A9E7E924A9E4A925D126B5E49405ACC8452
+9864:100010FE7C101020FEFC4484EE8444FC6484DEFC0084FE8428FC2A484C848902
+9865:00007CFE44107C2044FC7C841084FEFC00847CFC44847C8410FC544892843102
+9866:280024FE7E10C82048FC7E84488448FC7E8448FC48847E8440FCAA48AA840102
+9867:100008FE7F104120417C7F445444527C7F44547C5F4454445F7C54009F281044
+9868:FEFE10207EFC42847EFC42847EFC42847EFC244842840000FFFE082010202020
+9869:080008FE14102220417CBE440044007C7744557C55447744227C220055288844
+986A:040027BE2408FFD0023E02A27FE2423E7E224ABE4AA25AA26D3E894012D46462
+986B:1000FEFE0010FE2082FCBA84AA84FEFC00847CFC44847C8444FC7C480084FF02
+986C:00007F3E0808FF9088BE6B2208226B3E0022FFBE08227F22553E550055144322
+986D:2200FFBE22087F10553E55227F22003EFFA290BE3E222222523E0C001814E022
+986E:1000087EFF9080A07F7C524494447F7CC1447F7C41447F44417C7F0022284144
+986F:0000FEFE8210FE2082FCFE844484AAFCEE8444FCAA84EE8400FCAA48AA840102
+9870:087E2E10287EFF422A7E4C42327EC4243FFA21083FF822083FF80880FFFE0080
+9871:08000FBE08087F9048BE7E2248A25FBE55225F3E55225F22403EBF802A947FE2
+9872:29004A7E14106220097C2A445444227C4844FF7C00447F44417C5D0055287F44
+9873:7F80213E3F0821103F3E21E2FF22013EFFE252BE73A252A273BE5AC0F79410A2
+9874:2200227EFF902220777C55447744127C3F44647CBF4424443F7C24003F282044
+9875:00007FFC020004001FF010101110111011101110111012900240042018106008
+9876:000001FEFE20104011FC11041124112411241124112411441050508821040202
+9877:000021FE2020204021FC3D042124212421242524292431442050008801040202
+9878:000079FE1020104011FC11041124FD2411241124112411441050108811041202
+9879:000001FE0020FC4011FC1104112411241124112411241D44E050408801040202
+987A:040045FE5420544055FC55045524552455245524552455445450548885040602
+987B:080009FE1020204041FC89040924112421244524852409441050208841048202
+987C:000001FE7C20104011FC11047D2411241124112411241D44E050408801040202
+987D:00007CFE0020004000FCFE84289428942894289428942AA44C30484880840302
+987E:00007EFE402040405EFC5284529452945A945494509452A45430584850848302
+987F:100011FE1020FE4011FC55045524552455247D24112411441450188811040202
+9880:08001CFE6020404040FC40847E94489448944894489448A44830484888840B02
+9881:000029FE2820244045FC450481247D2425242524252425442450448855048A02
+9882:000028FE2420244042FC52849094109420942094489444A4FC30444800840302
+9883:100008FE0820FF4000FC00843C94249424942494249425A44630444880840302
+9884:0000F9FE0820504021FC1104FD242524292421242124214420502088A1044202
+9885:100010FE1E20104010FC7C844494449444947C94449440A44030404880840302
+9886:100011FE2820244043FC910409240124FD240524092451442050108811040202
+9887:080008FE08107F20497C4A4448547F54415452544A5444544A28912421420082
+9888:00007EFE04100820187C24444254815400547E540854085408280E24F0424082
+9889:100010FE1020FE4010FC10847C94009400947C94449444A444307C4844840302
+988A:080008FE08207E4008FC4A842A942C940894FE94089414A41230224840848302
+988B:0000037EEC102420247C44444F54E4542454A454A4544F544020A0281F440082
+988C:100010FE2820244042FC80847C94009400947C94449444A444307C4844840302
+988D:200024FE3820224022FC1E84009408940A94EC9428942CA44A304A48A8841302
+988E:400044FE7820424042FC3E840094109452945294549490A42830244844848302
+988F:100008FE0820FF4008FC108422947C94099412942494C8A414302248C0840302
+9890:00007DFE4820484049FC5D045524552455245D244924494448507E8801040202
+9891:100011FE50205C4051FC5104FF2401241124552455245544845008883104C202
+9892:080009FEEA102C204A7C4944A854105424542454FF5424542428442444428482
+9893:0C0071FE1020FE4011FC39045524932401243924292429442A504C8849048202
+9894:080008FE14102220517C88447E540254045408547E54425442287E2442420082
+9895:40004CFE7020424042FC3E8400947C940094FE94109454A45230924850842302
+9896:40004DFE7020444045FC3D0401240D2471241124FF2411443850548891041202
+9897:00007F7E491049207F7C494449547F540854FF541C542A544920882808440882
+9898:00003EFE22103E20227C3E440054FF54085408542F282844288258004FFE8000
+9899:00003EFE2A102A203E7C2A442A543E5408547F5449544B545F28412445424282
+989A:0000EEFEAA10AA20EE7C0044FE540054FF5440547E5402540228022414420882
+989B:0800497E491049207F7C0044FFD4085410547F54555455545520552855444382
+989C:100008FE7F102220147C7F444454485452544454485451544228442488423082
+989D:100008FE7F104120107C1E44225454540854145422547F54A22822243E422282
+989E:00007F7E22103E20227C3E4423D4FE540254F754115455542220552889441082
+989F:240024FEFF102420007CFF4424542454FF54A554A554DB549128812485428282
+98A0:080008FE7F1008203E7C22443E5422543E5422543E5422547F28142422424182
+98A1:00007EFE22101C20227C774455542254555408547F541C542A28492488420882
+98A2:00007F7E41107F20417C7F440854FFD400547F5441547F540820492888C41882
+98A3:920054FEFE103020547C924420544454785410542454FE541028542492423082
+98A4:0800FF7E0010FF20817CBD44A554FF5400547E5442547E5442207E280044FE82
+98A5:00007F7E0810FFA088FC6B4408546B540054FFD408547F545520552855444382
+98A6:08002EFE2820FF7C2A544C543228C4443FF821083FF822083FF80880FFFE0080
+98A7:2200227EFF902220777C5544775412543F546454BF5424543F2024283F442082
+98A8:00003FF8200820E82F0821082FE8292829282FE82908214A21EA5E2A48068002
+98A9:00027FC2404443485C5244425F44554855505F42444445485F504922801E0000
+98AA:00007FFC01000160011001001FF010D01710111017D0155027CA212A4FE68022
+98AB:00087FC84048435C5C4844485F7E554855485F54445245625F404922801E0000
+98AC:00007FDE404443545C5444645F7E5544554C5F54446445545F484922801E0000
+98AD:00087FC84048434E5C4844485F48555C55545F544454455C5F544922801E0000
+98AE:00407F40417C4D84717451547D5455747D48514255427D3E44804042803E0000
+98AF:80004FF848080868EB880888A888ABE8AAA8AAA84BE8388AC8AA10EA17262002
+98B0:00087FCA4048437E5C4844505F5E5552556A5F44444A45525F404922801E0000
+98B1:00087FC8404843525C5E44425F40555E55525F52445E45525F404922801E0000
+98B2:00027DF244824C8A748A55EA552A7D2A56AA7C4A544A5482530A7D044482807E
+98B3:00047FD8404843485C7E44485F48555C55545F544454455C5F404922801E0000
+98B4:00207F20413E4D407180517E7D1255507D5C515055507DBE44804042803E0000
+98B5:00107F5441384D10717C51447D7C55447D7C514455447D4C44804042803E0000
+98B6:00007F7C41444D7C7144517C7D44557C7D4451FE55007D2844C44042803E0000
+98B7:00107F5241944D28714451847D1055127D5451A855247D4444804042803E0000
+98B8:00007F7C41544D7C7154517C7D0055247D12516055A47D1C44804042803E0000
+98B9:00107F7C41244DFE7100517C7D44557C7D10513C55507D7E44904052803E0000
+98BA:007C7F44417C4D44717C51007DFE55407D7E51AA55527D2A44844042803E0000
+98BB:0E00F1FC2304933445C421443DF451541154FFF41144555455F45D1662060402
+98BC:00A07D2C45244DAC752455FC54207DFC54047CC85430544853847D004482807E
+98BD:100055FC550455347DC401447DF401547D5445F47D44455429F41D16E2064402
+98BE:00007DF844A84C887450542054D87F2654F87CA854F8542453FC7D044482807E
+98BF:00007DFC51047D3451C47D4451F451547D5405F45544555455F4851616060C02
+98C0:00407DBC45144D5475A4552C54407DFC55247DFC552455FC52007D004482807E
+98C1:0000FDFC2504B5346DC4B54425F411547D5445F445447D5445F445167E064402
+98C2:00007DDC44444D5474CC555454207C5054A87D5454A0544852907D2044C2807E
+98C3:00007DFC44504DFC755455FC54007CF854007DFC54A8552452607D004482807E
+98C4:0000FEF82888FE98AAE8AAA8FEF800A87CF800A8FEA810BA54CA928A51062202
+98C5:00007DFE44504DDC755455DC54507DFC55247DFC552455FC52007D004482807E
+98C6:140011FCFF04293445C4834425F437542554FFF4254455544BF4891612060402
+98C7:00287C2045FC4C507488550454487C6C54487DFE544854A852947D1244A2807E
+98C8:00207CA444A44D287450548855047C8856AA7DDC5488555452227D004482807E
+98C9:00207C2045FC4D54748855FC568A7CF854887CF854A8552452607D004482807E
+98CA:08002AF82C88489814E822A841F824A82DF8B6A864A824BA54CA4A8A91060202
+98CB:00007DDE44844DCE748455DE54207C1854487CD45562544853B87D004482807E
+98CC:4400FEF844880098EEE8AAA8EEF824A87EF8C8A87EA848BA7ECA488A7F064202
+98CD:1FF010D01710111017D0155027CA212A4FE680227CF854A87CF854AA7DFE8202
+98CE:00003FF02010201028502450229022902110211022902292244A484A40068002
+98CF:00007DF84410442044C04DFC6C545494552454446C8445284410420241FE8000
+98D0:00103F10211E21102510357C294429442944297C3544250020824062401E8000
+98D1:00407C4044FC450446F44C946CF454845494548A6C82447E4400420241FE8000
+98D2:200013F81208FE0803280AA88AA88A484A484AA852A8532A1C0AE40A48061002
+98D3:00007CF8448844F844884CF86C8854F8548855FC6C0044504488420241FE8000
+98D4:00007DFC452445FC45244DFC6C205414555255426E4844384400420241FE8000
+98D5:00A07D2C452445AC45244DFC6C2055FC540454C86C3044484584420241FE8000
+98D6:0E00F0F822889288448820983CD850A810A8FEA810D8548A548A5D0A65060202
+98D7:00407DBC4514455445A44D2C6C4055FC552455FC6D2445FC4400420241FE8000
+98D8:0000FEF82888FE88AA88AA98FED800A87CA800A8FED8108A548A930A51062202
+98D9:000014F81088FE882888449882D824A836A824A8FFD8248A548A4B0A89061202
+98DA:00207CA444A4452844504C886D04548856AA55DC6C8845544622420241FE8000
+98DB:00007FE000240A28722412201212120AFFC6124812501248224022244214820C
+98DC:08001DFAF00C544A3988FEAA34A652A281F87CAA54AC54AA7CA854AA54A67D22
+98DD:00047FE808247212120EFFD0122A221EFDF82448D5AA56ACFDFA54A855AA9326
+98DE:0000FFC000400044004800500060005000480044002000200012000A00060002
+98DF:0100028004400A203118DFF610101FF010101FF0100811901060121014081804
+98E0:080008001400120029007E00A2003E0022003E002000280024002A0032002000
+98E1:0040404020A0211002880C460BF8120813F8E20823F822442228229023080204
+98E2:080008781448124829487E48A2483E4822483E482048284A244A2A8A32862100
+98E3:0800080014FE121029107E10A2103E1022103E102010281024102A1032502020
+98E4:082008201420122029207E20A2203E2022503E502050285024482A8832842102
+98E5:0808081C14E0122029207E20A2203E3E22E03E202020282224222A22321E2000
+98E6:0800087C1410121029107E10A2103EFE22103E102010281024102A1032102010
+98E7:2020202020503C4824A445FA4688A4F8148808F808A21094108820A440C48080
+98E8:102010201050244824A479FA0A8810F824887CF804A20894088810A420C44080
+98E9:10201020282025FC5220FCA844A87CA844A87CA840F8502248225422641E4000
+98EA:08000808141C127029107E10A2103E1022FE3E102010281024102A10327C2000
+98EB:1008103C29E024205220FC2045FE7C2044207C50405050504888548865044202
+98EC:0100111009203FF802007FFC082011102FE8C8260FE008200FE808D00A300C08
+98ED:10401040284024FE5280FD2044207DFC44247C24404450444844548464A84110
+98EE:082008201420127E28424484BE1022103E1022103E2820283E4820443E842102
+98EF:1004100E28F024805280FCFC44A47CA444A47CA840A850904910552866444082
+98F0:082008101410120029FE7E20A2203E3022283E282024282424202A2032202020
+98F1:00200020FC50208821443E2245FC450465FC950409FC09221114214841848102
+98F2:104010402840247C5284FC8845207C2044207C50405050504888548865044202
+98F3:10201010280024FE5210FC1044107C1044FE7C10401050104810541065FE4000
+98F4:10201020282024405248FC8445FE7C8244007CFC408450844884548464FC4084
+98F5:084008401440127E29A07EA0A3203E3C22203E202020283E24202A2032202020
+98F6:10401020282824085208FC4844547D5245527D604260504448C45544663C4000
+98F7:0800087C1444124429447E7CA2443E4422443E7C2044284424442A4432FE2000
+98F8:00207C204450444844A47DFA0288FEF8208840F87CA20494048804A428C41080
+98F9:100010802B1E26525252FA524A527A524A527AD2435A52544890589069104210
+98FA:088028882EF028842E84F17C02800D603FF8C8260FE008200FE808D00A300C08
+98FB:10201020285024885304FE1244207C4045887C10402050444988541064604380
+98FC:080008FE1402120229FA7E02A2023EFA228A3E8A20FA288A24022A0232142008
+98FD:0840084014FC128429047EF4A2943E9422F43E842094288824822A82327E2000
+98FE:10801080288024FE5320FE2044207DFC45247D24412451244934552864204020
+98FF:081008101492129229927E92A2FE3E1022103E922092289224922A9232FE2002
+9900:1088108829FE24885288FC0045047D0444887C88405050204850548865044202
+9901:10401044284E24B85288FD8846887C8844FE7C88408850884888548864BE4080
+9902:1008103C29E024205220FDFE44207C2044207DFC410451044904550465FC4104
+9903:10401020282025FE5200FC8845047E0244887C88405050504820545064884306
+9904:081008101428122829447E82A27C3E0022003E7C2044284424442A44327C2044
+9905:08840848140012FC29487E48A2483E4823FE3E482048284824482A8832882108
+9906:105010502850255252D4FC5844507C5844D47D5240505050489254926512420E
+9907:080008FE1482128229BA7E82A2823EBA22AA3EAA20AA28BA24822A82328A2084
+9908:410021FC0A441440E0B0210822842D603FF8C8260FE008200FE808D00A300C08
+9909:08100810142012FE29827E82A2BA3EAA22AA3EAA20AA28BA24822A82328A2084
+990A:082004407FFC01003FF80400FFFE11102FE8C8260FE008200FE808D00A300C08
+990B:111009207FFC0400FFFE111022C8CD363FE8C8240FE008200FE808D00A300C08
+990C:080008FE1444124429447E7CA2443E44227C3E442044284E24F42A0432042004
+990D:00003FFE21083FFC2410288833642C9837F6241027F0241027F4446845188604
+990E:084008401478128829507E20A2503E8823063EF82088288824882A8832F82088
+990F:10401020282025FE5240FC4044A07CA245A47E9844905088488854A464C24080
+9910:08000F7828087F28A11017283AC4CD603FF8C8260FE008200FE808D00A300C08
+9911:1020102029FE24205220FDFE45027E0444F87C10402051FE4820542064A04040
+9912:1004101E29E024225312FC9444807C2045FE7C44408451C84830542864C44302
+9913:101010D82B9424945090FBFE48907894489478D84398509048AA58CA6A864102
+9914:102810242BFE24205220FDFC45247D2445FC7D24412451FC492455246524410C
+9915:081008101420124429FE7E28A2443EA2223C3E44204428A824102A2832442082
+9916:100011FE2800240052FCFC8444847C8444FC7C00408450444848540065FE4000
+9917:102010202BFE24205220FDFC45247D2445FC7C20407050A84924562264204020
+9918:081008101428122829447EBAA2103E1022FE3E102058285424922B1232502020
+9919:10C21034281824645382FC2045FE7C5044907DFE42925092489A549464104010
+991A:11841068283024C85324FC2047FE7C4044FC7D8442FC508448FC548464944088
+991B:100011FC2904250453FCFD0445047DFC44007D1241D45118491055526592410E
+991C:100011FC2924252453FCFD2445247DFC44207DFE407050A84924562264204020
+991D:1084108429FE248452A4FC1045FE7C4044407C7C404450444844548464944108
+991E:10481044285E25E05228FC12446A7D9644487C5E41E0502448285412646A4186
+991F:100013DE2842254A5084F94A4A527C2048007BDE40525152489459486A544422
+9920:10441044288825DC5288FC8844887C8845DE7C88408850884888548864884108
+9921:10401040287C24845308FE0044207DCE45027D0241CE51024902550265FE4102
+9922:08200810147C120029447E24A2283EFE22003E00207C284424442A44327C2044
+9923:102010202BFE24505288FD2446227DFC45247DFC412451FC48225422641E4000
+9924:102010A228A225245250FC8847047C2244207CA440A451284850548865044202
+9925:04407C7C04403C7804407D7C06C00D603FF8C8260FE008200FE808D00A300C08
+9926:100010FC288024F85280FCF844807FFE45407D24412851104908554465824100
+9927:103810E0282025FC5270FCA845247C2044407DFE404850884850542064504188
+9928:0820081014FE128229047E7CA2443E44227C3E402040287E24422A42327E2042
+9929:082008201450128829267E10A3FE3E2022443EF82012286425882A1832642182
+992A:100013FE2820244053FCFD5445547D5445547D2C402053FE4850548865044202
+992B:100013FE2A22242053FEFC2045FC7D2445FC7D2441FC50204BFE542064204020
+992C:1080109E289225D25292FC9E44927DD245527D5E4152515249D25422642A4044
+992D:1020104028FC248452FCFC8444FC7C0045FE7C20402050FC4820542065FE4000
+992E:7F2010501E882346549009241048619006601FF8E8160FF008100FF408680C1C
+992F:1040107C288424F85208FDFE44407CA445387C58409451344854549265504020
+9930:1080108E2920261054C0F8AE49047B144D247964412451244924590469144108
+9931:108010BC2884250851FEFB204D20797C4990791041FE51104928592869444182
+9932:080008FC148412FC29847EFCA2403EFE23123E9220AA288224FA2A0232142008
+9933:0800087C1444127C29447E7CA2003EFE22403E7E20AA292A244A2A92322A2044
+9934:102010202BFE245050A8F9244AFA782048A8788843FE50884888588869084208
+9935:100010FC28A424A452FCFCA444A47CFC44007DFE40905094488854A864C44082
+9936:100010FC288424F45294FDFE45027CFC44847CFC408450FC4884548464944088
+9937:0810081014FE123829547E92A2003E7C22443E7C2044287C24442A0032FE2000
+9938:102210122914248052BEFC0844087DBE44887C884094509248A25540663E4000
+9939:0820081014FE129029BC7E94A2FE3E9422BC3E9020BC28A424A42AA432BC2124
+993A:102810242BFE242053FCFD2445FC7D2445FC7D24400853FE4888544864484018
+993B:084408241428120029FE7E10A2103E7C22103E1020FE280024AA2AAA32AA2000
+993C:1080108028FC250052F8FC0045F87C4845687CC841F8504A48EA555A64464042
+993D:1020104029FC25245324FDFC45247D4445FC7C4040B050A4493C55226622441E
+993E:104013BE2A1226925252FAAA4B2478404BFE7A22422253FE4A225A226BFE4202
+993F:10A0112C2924252453ACFD2445247DFC44207DFC408850504820545064884306
+9940:101E11E0282225125294FC8044207DCE45027D0241CE51024902550265FE4102
+9941:1020102028FC24205220FDFE44407C8445FE7C0241FC51544954555467FE4000
+9942:100010F82888248852F8FC8844887CF844007DFC415451544954555467FE4000
+9943:108810882BFE24885200FDFC45047DFC45047DFC402053FE4850548865044202
+9944:1020112428A827FE5202FCF844887C8844F87C20402051FC4820542067FE4000
+9945:087C0844147C1244297C7E00A2FE3EAA22FE3E0020FC284424282A1032682186
+9946:100011FC292425FC5324FDFC44A87CA847FE7CA840A851FC482057FE64204020
+9947:100013FE2A00267C5244FA444A7C7A004AEE7AAA42AA52AA4AEE5A006BFE4000
+9948:1084104829FE241052FCFC2045FE7C40447C7CA4412450FC4844544465FE4000
+9949:108810882BFE248852F8FC2045FC7D2445FC7C2043FE502049FC542067FE4000
+994A:114811482BE82550515EFBE448147BD44A547BD4425453C84A485A546A5442E2
+994B:102011FC292425FC5220FFFE44007DFC45047DFC410451FC490455FC64884104
+994C:100013DE2A5227DE5210FA5249CE780048887BFE408850884BFE588869044202
+994D:108810502BFE242051FCF8204BFE792448A87BFE400051FC4904590469FC4104
+994E:102013FE282025FC5200FDFC45047DFC44887FFE400051FC4904550465FC4104
+994F:3C20043EFF4422A83E1023287E44038006601FF8E8160FF008100FF408680C1C
+9950:102013FE282025FC5000FBFE4A0279FC480079FC410451FC490458886BFE4000
+9951:112411242AAA27AE5124FAAA4BAE79244FFE7910411451144A8A5A4A6A164422
+9952:1020102029FC242053FEF9084B9C790849887E3E400053FE489058906912420E
+9953:1020112428A827FE5202FCF844887C8844F87C2043FE507048A8552466224020
+9954:0100FFFE10A025FE7B2015FC792011FEE6601FF8E8160FF008100FF408680C1C
+9955:7C1C4410FEFE20927CF8049428BC11AA06661FF8E8160FF008100FF408680C1C
+9956:1020113C292027FE5010F8144BFE7A104BF07A54425452D44B68544A68964322
+9957:110023DE7A5213D42A527BDA129423D006601FF8E8160FF008100FF408680C1C
+9958:101011FE280025FE5302FD7A454A7DFE44007CFC408450FC488454FC640041FE
+9959:102011FC2820248853FEFC8845FC7D0445FC7D0441FC510449FC548865044202
+995A:108813FE2888242053FCFC2047FE7C4044887DFC400051FC4954555467FE4000
+995B:108813FE288827FE5202F9FC48007BFE484078A2435450B84B5458926B504020
+995C:3FFE28882F8A20082FBE28882F8828D429A223F826162BF0221043F44268831C
+995D:104010202BFE264853FEFA484AEC7B5A4A487BFE4220527C4AC45344647C4844
+995E:11F012102BFC260453FCFA244BB87A2249FE7A1047FC52444BFC58D0694A423E
+995F:102013FE280025DC5154F9DC48887BFE48887BFE408853FE489459886AA440C2
+9960:100013FE2A52265253FEF90849547A5E4FB4791E425457DE48145554655E4010
+9961:152817BE294827BE5318FDAA49467BFC4A047BFC420453FC4A045BFC69084204
+9962:104017FC2A4827F85040FFFE4AAA7BB849107BFC411057FE492853106D484186
+9963:2000200020003E00440048008000100010001000100012001400180010000000
+9964:2000200020FE3E10441048108010101010101010101012101410181010500020
+9965:200021F021103D1045104910A1102110211021102110211229123212220E0400
+9966:2010207823C03C40444048408040207E27C020402040244228423042203E0000
+9967:200021F820103C2044404880A1FE209220922092211221222A22344220940108
+9968:2040204020403BFC4840524882482248224823F82048204028423042203E0000
+9969:2080208020FC3D00460048F88000200021F8200820082408280A300A20060002
+996A:2008203C21E03C2044204820802023FE20202020202024202820302021FC0000
+996B:2008203C21E03C204420482083FE202020202050205024502888308821040202
+996C:20802080210039FE4A005440804023FC20442044208420842904310422280410
+996D:2008201C21E03D00450049FCA144214421442128212821102910322822440482
+996E:2040204020403E7C448448888120102010201050105012501488188811040202
+996F:2050204820403C5C45E04840A05E23E020442048203020222852308A23060002
+9970:2080208020803CFE45204A20802021FC21242124212425242934312820200020
+9971:2080208021FC39044A0455F481142114211421F4210421282912310220FE0000
+9972:200023FC20043C0447F44804A00423E422242224222423E42804300420140008
+9973:2020202021243D244524492481FC202020202124212425242924312421FC0004
+9974:2020202020403C8845044BFE8002200021FC2104210425042904310421FC0104
+9975:200023FE21083D08450849F8A108210821F821082108211E2BE8300820080008
+9976:2080208020BC3BC04850502480D4230C200027FE2090209029123112220E0400
+9977:2040204020803BFC4A04520482F4229422942294229422F42A04320422140208
+9978:2020202020503C8845044A0281FC2000200021FC210425042904310421FC0104
+9979:2080208020F839084B1054A0804020A02118220625F821082908310821F80108
+997A:2040202020203DFE44004888A104220220882088205020502820305020880306
+997B:2040202020203BFE4840504080A020A221A4229824902088288430A220C00080
+997C:21042084208838004BFE508880882088208827FE208820882908310822080408
+997D:2020202023FE3C2044204BFEA202240421F82010202023FE2820302020A00040
+997E:200023FC20003C0045F849088108210821F82000210824882890300027FE0000
+997F:201020D823943C9444904BFEA0902094209420D82398209028AA30CA22860102
+9980:2020202020503C8845044AFAA020202023FE2020212821242A22342220A00040
+9981:2008203C23C038444A2451288100204023FE2088210823902860305021880604
+9982:2040204020883D0447FE4802A0882144224220F8218822502820305021880606
+9983:200021FC21243D2445FC4924812421FC202023FE207024A82924322220200020
+9984:200021FC21043D0445FC4904A10421FC2000211221D42118291031522192010E
+9985:2080208020F839084A1054008040239C22042204239C22042A04320423FC0204
+9986:2040202023FE3A024C0451F88108210821F82100210021FC2904310421FC0104
+9987:2040204027FC38E049505248844623F8220823F8220823F82A08300027FE0000
+9988:2020202021FC3D2445FC482083FE200021FC2104212425242924305020880304
+9989:200021FC21043DE445244BFE820221FC210421FC210425FC2904310421140108
+998A:20A0232E22223E2247AE4A22A22223FE202023FE210420882850302020D80706
+998B:210021F022103C204BFC5244824423FC20A02122261E20C02830318020600010
+998C:2020202021FC3C2044204BFEA080210423FE200223FC22942A94329427FE0000
+998D:2110211027FC3910480053F8820823F8220823F8204023FC28A0311022080406
+998E:2028202423FE3C2045FC4924A1FC212421FC2124200823FE2888304820480018
+998F:204023BE22123A924A5252AA8324204023FE2222222223FE2A22322223FE0202
+9990:2208211027FC38404BF8508087FC210023F82488288823F82908310827FE0000
+9991:2088208823FE3C8844F84820A1FC212421FC202023FE202029FC302023FE0000
+9992:23F8220823F83A084BF8500087FC24A424A427FC200023F8291030E023180C06
+9993:2288228827C83A904A9E57D4802427D4245427D4245427C82C483454246404C2
+9994:200023DE22523BDE4A10525281CE2000208823FE208820882BFE308821040202
+9995:204027FC22483BF848405FFE8AAA23B8211027FC21102FFE292833102D480186
+9996:10100820FFFE020004003FF8200820083FF8200820083FF8200820083FF82008
+9997:211020A0200023FCFC8025F8250825F8250825F8250825FA250A440243FE8000
+9998:441424122810FDFE101020107DD2455245527D5445D47C0844CA471A7C264442
+9999:00701F8001000100FFFE054009203118DFF6101010101FF0101010101FF01010
+999A:041078501050FE5010883888550492FA7C48444844487C48448844887D284610
+999B:045078481048FE4011FE38405440907C7CA444A444A87D28451046287C444482
+999C:040078FC1084FE84108438FC548090A07CA444A844B07CA044A245227D1E4600
+999D:044078201028FE0810083848545491527D52456046607C4444C445447E3C4400
+999E:0420782011FEFE20102039FE550292047CF8441044207DFE442044207CA04440
+999F:0408783C11C0FE04114438A8540091F87C10442047FE7C20442044207CA04440
+99A0:042078201050FE8811443A2254F890087C10442045FC7D04450445047DFC4504
+99A1:044878481048FDCE10483848544891CE7C48444844487DCE444844487C484448
+99A2:04487844105EFDE010283812546A91967C48445E45E07C24442844127C6A4586
+99A3:0420782011FEFE5010A8392654F890A87CA844F844A87CA844F844AA7C22441E
+99A4:040079FC1104FDFC110439FC548091FE7E22452245527D0245FA44027C144408
+99A5:0440784010FEFE8011FC3A8454FC90847CFC4440447C7CC4452844107C684586
+99A6:048878501000FDFE105039FC545493FE7C5445FC44507CD8455446527C504450
+99A7:040078F81088FE8810F83888548890F87C0045FC45547D54455445547FFE4400
+99A8:0878FF4808863E782A483E3040489FE401007FFC09203FF8C8260FE008200FE0
+99A9:042079FC1020FC8813FE388855FC91047DFC450445FC7D0445FC44887D044602
+99AA:0420781011FEFF0210FC38A8553090FC7D8444FC44847CFC448444FC7C484484
+99AB:1FE001007FFC09203FF8C8260FE008247FF81010FEFE545492927C7C44447C7C
+99AC:00003FF821003FF021003FF0210021003FF80008124849284928800800500020
+99AD:00007F00487C7F2448247F24482448287FA800A8AA90AA90AAA880A805440282
+99AE:000043FC224023F802400BF80A40124013FCE004255425542554240420280010
+99AF:00007F7C48107F1048107F104810487E7F900090AA90AA90AA90809005100210
+99B0:00107F1048107F3C48247F44480448247F940094AA84AA84AA84808405280210
+99B1:00107F1048107F10487E7F10481048107F9000A8AAA8AAA8AAA880C405440282
+99B2:00087F1C48707F1048107F104810481E7FF00090AA90AA92AA928092050E0200
+99B3:00207E2048207EA048AC7EB448E449A47EA402B4AAA8AAA2AAA28282147E0800
+99B4:00027F22482A7F2A482A7F2A482A482A7FAA00AAAAAAAAAAAAAA80AA05420282
+99B5:3FF821003FF021003FF021003FFC4924849408280820FFFE0820102020204020
+99B6:00107E1048107EFE48107E1048FC48447E440244AA28AA28AA10822814440882
+99B7:00087F0848087F3E48087F08483E482A7FAA00AAAAAAAAAAAAAE808805080208
+99B8:00007F0C48307F2048207F20483E48247FA400A4AAA4AAA4AAA480A405440284
+99B9:00007F3E48227F2248227F224822483E7FA200A2AAA2AAA2AAA280BE05220200
+99BA:00007EFC48447E4848487E50485C48447E440244AA68AAA8AA90829815240842
+99BB:00107F1048207F2848447F7C480448287FA800A8AAA8AAA8AAAA80CA05460280
+99BC:00207E1048107EFE48447E44484448447E440228AA28AA10AA10822814440882
+99BD:3FF821003FF021003FF021003FFC4924849401083FF8210821083FF801000100
+99BE:00107E1048107E1048FE7E92489248107E280228AA28AA28AA48824A148A0906
+99BF:00107F0848007F3E48227F224822483E7FA200A0AAA0AAA0AAA080A005400280
+99C0:00487E4448447E4049FE7E50485048507E500250AA50AA52AA528292148E0900
+99C1:00027F2248147F0848147F22484248007FA200A2AA94AA94AA88809405240242
+99C2:400049FC5120612045FC45203DFC1120112011FEFC0212AA12AA120210141008
+99C3:00107F1048107F10487C7F14481448147F9400FEAA90AA90AAA880A805440282
+99C4:00207E2048207E2048FE7E20482048307E500250AA48AA48AAC882A415240A02
+99C5:00007E7C48447E4448447E44487C48547E500250AA48AA48AA48828414840902
+99C6:00007DFE51007D0451447D28512851107D100528552855445584850015FE0800
+99C7:00107F1048107F20483E7F4448A448247FA800A8AA90AA90AAA880A805440282
+99C8:00087E1C48607E4048407E404840487E7E480248AA48AA48AA48824815FE0800
+99C9:00007EFE48827E8248827EBA48AA48AA7EAA02AAAABAAAAAAA828282148A0884
+99CA:00107E1048107EFE48927E94489048FC7EA402A4AAA8AAA8AA90832815440A82
+99CB:00007F7E48127F1248127F22482A48447F8000BEAAA2AAA2AAA280A2053E0222
+99CC:10003EF84288A2AA1492187EE0001FF011001FF011001FF011001FFC2A44492C
+99CD:00007F7C48107F1048547F34483848107FFE0090AA90AA90AA90809005100210
+99CE:00087F0848087F08483E7F2A482A482A7FAA00BEAAAAAAAAAAAA80AA053E0222
+99CF:00007F3E48207F2048207F3E482248227FA200A2AABEAAA0AAA080A0053E0200
+99D0:00107F0848007F3E48087F08480848087FBE0088AA88AA88AA888088057E0200
+99D1:08007F7C114432280C10122861461FF011001FF011001FF011001FFC2A44492C
+99D2:00207F2048207F7E48427F82483A482A7FAA00AAAABAAAAAAA82808205140208
+99D3:00007F3E48087F0848087F18481C482A7FAA00CAAA88AA88AA888080053E0200
+99D4:00007F3C48247F2448247F3C482448247FA400BCAAA4AAA4AAA480A4057E0200
+99D5:100010007E7C124422442A7C44009FF011001FF011001FF011001FFC2A44492C
+99D6:00107F1048287F2848447F92480848007FBC0084AA88AAA8AA90808805040200
+99D7:00107F1048287F2848447F92482048407F880090AAA0AA84AA88809005200240
+99D8:00087F0848107F1048247F7E482248007FBC00A4AAA4AAA4AAA480A4053C0224
+99D9:00487E4848487E8848FE7E88498848887EC802A8AAA8AA88AA88828814A80890
+99DA:00207C2050207DFC51247D24512451247D2407FE542054505450848815040A02
+99DB:00087F0848087F3E482A7F2A482A482A7FBE0088AAC8AAA8AA90809805240242
+99DC:00107E0848087E0248227E24482448A87EAC02B2AB32AA20AA6282A2151E0800
+99DD:00107F0848087F7E48427F42482048247FA800B0AAA0AAA2AAA280A2051E0200
+99DE:00407C40507E7C8051207CA050AC50B47DE404A454B454A854A28482147E0800
+99DF:00007E0048FE7EAA48AA7EAA48AA48AA7EAA02AAAAAEAAC2AA82828214FE0882
+99E0:00007E2048CE7EAA48AA7EAA48AA48AA7EAA02AAAAEAAAACAA28824814480888
+99E1:00003EF822883EF800001FF811001FF011001FF011001FFC0004292444940008
+99E2:00847E4848007EFC48487E48484848487FFE0248AA48AA48AA48828814880908
+99E3:00507E5048507F5248D47E58485048587ED40352AA50AA50AA92829215120A0E
+99E4:00007F7E48107F1048247F22487E480A7F880088AABEAA88AA888088057E0200
+99E5:00147E1248127E1048FE7E10485248527E5202F4AA54AA54AA8A828A15160822
+99E6:111009207FFC0200FFFE08203018DFF611001FF011001FF011001FFC2A44492C
+99E7:00007EFE48827E8248BA7E82488248BA7EAA02AAAAAAAABAAA828282148A0884
+99E8:00107F1048107F3E48227F42483A482A7FAA00BAAAAAAAAAAABA808205140208
+99E9:00087F0848147F1448227F40483E48087F880088AABEAA88AA888088057E0200
+99EA:00107E5048507E7C48907E10481048FE7E280228AA28AA28AA4A824A14860900
+99EB:00207E2049247EA448A87E2049FE48507E500250AA50AA52AA528292148E0900
+99EC:00007F7E48247F2448247F3C482448247FBC00A4AAA4AAAEAAF4808405040204
+99ED:00207C1050107DFE50207C24504450F87C120422544455885410842814440982
+99EE:00207E1048107EFE48007E44488249007E440244AA28AA28AA10822814440982
+99EF:00107E5048507E7C48907E10481048FE7E100238AA38AA54AA54829214100810
+99F0:00007EFE48827E9248927E9248FE48927E9202AAAAA6AAC6AA82828214FE0882
+99F1:00407E4048787E8849507E20485048887F0602F8AA88AA88AA88828814F80888
+99F2:00827C9250927C9250927C9252DA52B67C920492549254925492851215020A02
+99F3:0004F80EA3B8F888A088F928A12EA3A8F8A80AA8AAA8A93EA9008A800C7E3800
+99F4:0010F814A012F810A3FEF810A150A154FFF40954A954A948AA4A8A5A0C263042
+99F5:00007EFE48287E2848287EEE48AA48AA7EAA02AAAAEEAA28AA28822814480888
+99F6:00007EFC48847E8448FC7E8048FE48827EBA02AAAAAAAABAAA82828214940908
+99F7:00107E1048FE7E1048107EFE489248927EFE0210AA38AA54AA92831014100810
+99F8:00007EFC48047E7C48047EFC480049FE7F0202FCAA44AA44AA28821014680986
+99F9:00487E4448407EFE48507E54485848527E540258AA52AA54AA9A8292152E0A40
+99FA:00207E1048FC7E8448847EFC488448847EFC02A2AAA4AA98AA90828814C40882
+99FB:00007F3E48227F3E48227F3E480048007FBE0088AA88AAFEAA88808805080208
+99FC:00107E1048287E2848447EBA481048107EFE0210AA58AA54AA92831214500820
+99FD:00007F3E48227F22483E7F00483E48227FA200BEAAA2AABEAAA280A2052A0224
+99FE:00847E4448487E0048FC7E84488448847EFC0248AA48AA48AA48828A148A0906
+99FF:00107E1048207E4448FE7E28484448A27E3C0244AA44AAA8AA10822814440882
+9A00:0010F8D8A394F894A090FBFEA090A094F89408D8AB98A890A8AA88CA0A863102
+9A01:00107E1048FC7E9448FC7E9448FC48007FFE0240AA80AAFCAA04820414280810
+9A02:00207F1048107F7C48007F28481048FE7F900090AAFCAA90AA90809005100210
+9A03:00107E2048447E8248FE7E004840487E7E900210AAFEAA10AA28824414820900
+9A04:00007EFC48047E04487C7E04480448FE7E100292AA54AA38AA54829214500820
+9A05:00507E4848807EFE49907E9048FC48907E9002FCAA90AA90AA9082FE14800880
+9A06:00007EFE48927E9248BA7E9248FE48827EBA02AAAAAAAABAAA828282148A0904
+9A07:0020F820A050F888A104FAFAA020A020FBFE0820A820A9FCA904890409FC3104
+9A08:00227E2248447EEE48447E44484448447EEE0244AA44AA44AA44824414440884
+9A09:00007EFC48847E8448FC7E84488448FC7E000290AA92AAF4AA98829214D2088E
+9A0A:00407E4048FE7E8249427E7A48A248227EFA0222AAAAAAAAAAFA820214140808
+9A0B:00107E1048107EFE48107E54485448547EBA0210AA38AA54AA92821014100810
+9A0C:00207E1048FE7E8248007E7C480048007EFE0210AA10AA54AA52829214500820
+9A0D:00007E7C48547E54487C7E544854487C7E1002FEAA10AA38AA54829214100810
+9A0E:00207E2049FC7E2048507E8849FE48087EE802A8AAA8AAE8AAA8820814280810
+9A0F:00247F24487E7F2448247F3C482448247FBC00A4AAA4AAFEAA8080A405220242
+9A10:0020F820A050F888A144FA22A1F8A008F8500820A8A4AA82AA8A8A8A0C783000
+9A11:00287E2848287EEE48287E28482848EE7E280228AA28AAEEAA28822814280828
+9A12:00007EFC48447E2848107E68499648107EFE0292AA92AAFEAA10821415FE0882
+9A13:00107E2848447E82487C7E10481048FE7E920292AAFEAA10AA28822814440882
+9A14:00007EFC48847EFC48847EFC484048FE7F120292AAAAAA82AAFA820214140808
+9A15:00007EFE48287E2848FE7EAA48AA48FE7E1003FEAA24AA44AA68821814640982
+9A16:7E20243E1848FFA829104A2898461FF011001FF011001FF011001FFC2A44492C
+9A17:1000087C7E50427C42507E7C425040507F7C550455547F54D554558455144308
+9A18:00407E40487E7EAA496A7E5A489649227E4A0284AA20AA94AB428244143C0800
+9A19:00407C2051FE7D0251027DFE510051007DFE05AA56AA56FE54AA84AA14A20886
+9A1A:00847C4450487DFE50007DE2512A512A7DEA052A552A55EA552A8522152A0964
+9A1B:00007DFA500C7C4A51887CAA50A650A27DF804AA54AC54AA54A8852A15260A22
+9A1C:00107E20487C7E44487C7E44487C48007EFE0210AA10AA7CAA10821014FE0800
+9A1D:0010F810A03CFB94A0FEF894A13CA110FBBC0890A8FEAA90A91089800A7E3400
+9A1E:00107E1048FE7E1048FC7E1048FE48107EFE0220AA40AAFCAB448244147C0844
+9A1F:00207C5050887D0452FA7C0051E2512A7D2A05EA552A552A55EA8522152A0964
+9A20:00007EFC48847E8448FC7E84488448FC7E0003FEAA20AAA0AABC82A015600A3E
+9A21:00107E2048FE7E8248FE7E8248FE48107E1202D4AA58AA54AA94829215500820
+9A22:00007DDC51447D4451447DDC510051007DDC0514551455D45508850815140922
+9A23:00287E9248AA7E8248FE7E28484448A27E3C0244AA44AAA8AA10822814440882
+9A24:00107ED448487F4A48847E84490248F87E200220ABFCAA20AA50824814840904
+9A25:00007CFC50487C3051FE7C52509451107E30042055FE547054A8852416220820
+9A26:00007DFC51247D2451FC7D24512451FC7C200410545455425542854A16380800
+9A27:00007E7C48447E4448747E54485448FE7E8202BAAAAAAAAAAABA8282148A0884
+9A28:02427D2450007DFC51247D2451FC51247D2405FC5420542057FE842014200820
+9A29:00107E2048FE7E9248927EFE489248927EFE0220AA24AA5AAA5E82901492090E
+9A2A:00507E9648927E9248D67E92489248FE7E1002FCAA44AA44AA288210142808C6
+9A2B:01007FFE44429FF404403FF80440FFFE09201FF02908CFE609000FF800081558
+9A2C:001CF9E0A020FBFEA0A8F8AAA3ACA0AAF9AA0AA6A870A8A8A9248A220C203020
+9A2D:0020793C492053FE48A46B285070438000003FF821003FF821003FFE29224496
+9A2E:00207EDE488A7ECA48AA7ED248A648007EFE0292AA92AAFEAA92829214FE0882
+9A2F:00207E1048FE7E0048447E2848FE48A27E1002FEAA20AA3CAA24824414540888
+9A30:012478A849FC48404BFE79084BFC4D2249FC792049FC492049FE48024AAA9804
+9A31:000E7EF048227E9248447E20484448F87E100224AAFEAA10AAFE822814440882
+9A32:00887C8853FE7C8850007DFC510451FC7D0405FC5524542057FE842014200820
+9A33:00007EFE48907EFC48907EFC489048907EFE0202AAAAAAAAAAAA828214140808
+9A34:00007E7C48447E7C48447E7C481048FE7E820220AAFEAA44AA68821014280844
+9A35:00007EFE48887E9048BE7EA248BE48A27EBE0288AAACAAAAAACA828A15280A10
+9A36:00407E4048FE7F2248AA7EFA484248947F4802FEAB22AAAAAAFA824214940908
+9A37:00007DFC50A47C8850507C2050D853267C2005FC5524552455FC842217FE0802
+9A38:00207C1051FE7D0251027DFE510051EE7D2205AA55665522556686AA16220C66
+9A39:00887C8853FE7C8850F87C2051FC51247DFC042055FC542055FC842017FE0800
+9A3A:08207E2008F8FF2814287F6A082AFF5608823FF821003FF821003FFE29224496
+9A3B:00107E1048FE7E1048BA7E5448BA48107EBA0254AABAAA10AA28822814440882
+9A3C:00207E1048FE7EA848A87EFE48AA48AA7EFE0280AACAAAECAB48824A146A0846
+9A3D:00007DDE50427D5250CA7D52504250207CFC0484548454FC5484848414FC0884
+9A3E:00007DFC51247DFC51247DFC504050887DF00420544457FE5422852416220860
+9A3F:00107EFE48447E2848FE7E00487C48447E7C0244AA7CAA10AAFE821014100810
+9A40:0820FFFE08201FF010101FF01010FFFE08203FF8D1061FF011001FFC2A44452C
+9A41:08207F20087E7E4408A4FF2810101E2822447FFAA1003FF821003FFE29224496
+9A42:00107E2048447EFE48447EAA48EE48107E280254AAAAAA50AA24824814100860
+9A43:00007EFE48287EFE48AA7EAA48FE48007E7C0200AAFEAA10AA54829214500820
+9A44:00207C4051FC7D24517C7D8C515451247D5405FC5420541055548542154A0A38
+9A45:0000FBFEA200FA7CA244FA44A27CA200FAEE0AAAAAAAAAAAAAEE8A000BFE3000
+9A46:00007EFE48927EFE48927EFE485448547EFE0254AA54AAFEAA1082FE14100810
+9A47:08203E2008F87F282A685D2A08563E8200003FF821003FF821003FFE29224496
+9A48:00FC7E2848107FFE48527E94495048207EFE02AAAAC6AABAAAAA82BA14820886
+9A49:00207C3C50207DFE51227D3851E4511C7D00052855AA556C5528862814FE0800
+9A4A:00447EFE48447E0048FE7E54485448FE7E540254AAFEAA10AAFE821014100810
+9A4B:0024FBA8A092FD14A208FC04A3BAA0A8F8C60B80AA3CAB84A8A888900AA83144
+9A4C:0020F9FCA024FBFEA024F9FCA020A2AAFBAE0A22ABFEAA22ABAE8AAA0AAA3422
+9A4D:0020F820A1FCF820A3FEF908A39CA108F9880E3EA800ABFEA89088900912320E
+9A4E:0020F924A0A8FBFEA0A8F924A222A104F90409DEAA44AD54A89E89040A043404
+9A4F:03FEFA02A3FEFA00A2FCFA08A3FEA210FA300BCEAA42AA84ACEE8F840884318C
+9A50:0108F888A3C8F810A3DEFA64A3D4A014FBD40854A894A8E8AB8888940A943122
+9A51:00007EFE48287EEE48AA7EAA48EE48287EFE0292AA92AAFEAA92829214FE0882
+9A52:00007EEE48AA7EAA48EE7E0048FE48927EFE0292AAFEAA10ABFE821014100810
+9A53:00447E2448287EFE48927ED648BA48927EFE0200AA7CAA44AA7C8244147C0844
+9A54:00007EFE48287EFE48AA7EFE4800487C7E44027CAA44AA7CAA1082FE14100810
+9A55:0018F9E0A040FBFEA088F974A252A070F80009FCA904A974A95489740904310C
+9A56:008CFBEAA088FBFEA008FBE8A22AA3EAF80A0BECA88CABECA88A88EA0B963022
+9A57:00207C2050507C8851047EFA500050007DDC0554555455DC5488848815540A22
+9A58:0100FFFE20003FF800003FF820083FF8000077DC551477D4551C77D65056B562
+9A59:00107EFE48007EFE48827EBA48AA48FE7E00027CAA44AA7CAA44827C140008FE
+9A5A:2420FF20247E7EC482287A104A287AC604003FF821003FF821003FFE29224496
+9A5B:00007DFC51547DFC50207DFC502053FE7C88045055FC542057FE842014200820
+9A5C:00507D5250D47C5051FE7C88505051FE7C2004FC542055FE54A8852416220820
+9A5D:00107EFE48107E7C48007EFE4882487C7E20027CAAC4AB7CAA1082FE14540992
+9A5E:0040F820A3FEFA02A1FCF948A250A1FCFB0409FCA904A9FCA90489FC08883104
+9A5F:03F07D2E51E27D2A51E47D3453EA50327C1E07E054A25534546884A417220820
+9A60:0110F910A7FCF910A1F0FA08A2EAA6ACFAA80AAAAEEAAA06A8008AA40A523452
+9A61:10407E7C2440FF7C42047E7C42407E7842423FFE21003FF821003FFE29224496
+9A62:0040F87CA040FBFCA244FBF0A244A2FCFAA80AF8AAA8AAF8AA008DFC095433FE
+9A63:01247CA851FC7C4053FE7D0853FC55227DFC052055FC552055FE840216AA0804
+9A64:00107EFE48007EEE48AA7EEE484448FE7E4402FEAA44AAFEAA5082CA15640842
+9A65:0094FB98A092F98EA280F9FCA124A1FCF92409FCA888A9FCA8888BFE08883104
+9A66:01FCF820A3FEFA22A1ACF820A1ACA000F89E0BF2A89EA9D2AABE8C92089E3092
+9A67:0290FA90A7D0FABEA3CAF92EA7DAA54AFD7E0FCAA91EAFEAA90A8902090A3104
+9A68:0222FBFEA090F9FEA310FDFEA110A1FEF91009FEA900ABFEAA8A8B760A523276
+9A69:0088FBFEA088FBDEA252FBDEA0A0A090F9FE0920ABFCAD20A9FC892009FE3100
+9A6A:03DEF800A3DEFA52A35AFA52A020A3FEFA500BFEAA52ABFEAA928ADC0A9234CE
+9A6B:7FF842007FF042007FFC5244892C7E7E48487E7E48487E7E48487E7E02029696
+9A6C:00007FE0002000201020102010201FFC000400040004FFE40004000400280010
+9A6D:00007C0005FC24842484248424883E88025002501A20E2204250028815040A02
+9A6E:00207C2004202420242025FE24203E20022002501A50E2504288028815040A02
+9A6F:0104F924092449244924492449247D24052405241D24E524452406242A041404
+9A70:0020F82008204920492C493449647FA4052405341D28E5224522050228FE1000
+9A71:0000F9FE090049044944492849287D10051005281D28E5444584050029FE1000
+9A72:00007CFC048424842484248424843EFC028402841A84E2844284028414FC0884
+9A73:0008F888085048204850488849007C08048804881C50E4504420045028881306
+9A74:0040F820082048FC4884488448847CFC048404801C80E4804480050029001200
+9A75:0000F8F808884888488848F848887C88048804F81C88E488448804882BFE1000
+9A76:0020F820082049FC4924492449247D2405FC04201CA0E4604460049029081206
+9A77:0000F9FC095449544954495449547D540594058C1D04E504450405FC29041000
+9A78:0088F88808884908497E4B084D087D48052805281D08E5084508050829281110
+9A79:0080F880090049FC4A044C0449E47D24052405241DE4E5244404040428281010
+9A7A:0080F88008F849084A104C204BFC7C04040404041DFCE404440404042BFC1004
+9A7B:0040F82008004BFE4820482048207C2005FC04201C20E420442004202BFE1000
+9A7C:0020F810081049FE49024A0448807C88049004A01CC0E48244820482287E1000
+9A7D:08007F7C114432280C10122861461FE00020082008200FFC00047FC400140008
+9A7E:080008007F7C11441144257C42001FE00020082008200FFC00047FC400140008
+9A7F:0000FBFC090448884850482048D87F26042005FC1C20E42047FE042028201020
+9A80:0020F8200840488849044BFE48027C0005FC05041D04E5044504050429FC1104
+9A81:0080F88008BC4BC04850482448D47F0C040007FE1C90E490451205122A0E1400
+9A82:00007CF8448844887CF800003FE00020082008200FFC00047FE4000400280010
+9A83:0000F9FC090449244924492449FC7D24052405541D4CE58C4504050429FC1104
+9A84:0008F83C09E0482048204BFE48507C880504068A1C88E4884488050829081208
+9A85:0090F894091449184B104D3249527D0E052004201FFEE4204420042028201020
+9A86:0080F88008F849084B104CA048407CA0051806061DF8E5084508050829F81108
+9A87:0020F810081049FE4820482448447CF8041204221C44E5884410042828441182
+9A88:0084F8440848480049FE484848487C48044807FE1C48E4484448044828881108
+9A89:3FF0001010101FFC00047FE400280010FCFC040444447E7E0202F2F20A0A0404
+9A8A:0000F3FE1000500053DE525252527A520B5A0AD63A52CA520A520A522A5212D6
+9A8B:0020F82009FC492449FC492449FC7C0007FE04801D00E5FC4404040428281010
+9A8C:0020F82008504850488849044AFA7C00044404241D24E4A8448804102BFE1000
+9A8D:0040F82009FC4800488848504BFE7C20042004201DFCE4204420042028201020
+9A8E:0000F8FC0804487C480448FC48007DFE050204FC1C44E4444428041028681186
+9A8F:0040F840088849044BFE480248887D44064204F81D88E6504420045029881606
+9A90:0088F8880BFE4888488848F848887C8804F804881C88E7FE4400048828841104
+9A91:0020F82009FC4850488849044BFE7C0805E805281D28E5E84528040828281010
+9A92:0000F9FC0924492449FC492449247DFC042007FE1C70E4A84524062228201020
+9A93:0050F848088048FE49904A9048FC7C90049004FC1C90E490449004FE28801080
+9A94:0040F8200BFE4A024C0448F848007C0005FE04201CA8E4A44522062228A01040
+9A95:0020F82009FC48244BFE482449FC7C20052405241D74E5AC452405242A241424
+9A96:0040F848088449FE48204BFE48887D24064205881C10E4624584041828601380
+9A97:0040F82009FE4902490249FE49007D0005FE05AA1EAAE6FE44AA04AA28A21086
+9A98:0020793C492053FE48A46B28507043801FE0002008200FFC00047FC400140008
+9A99:0010FBD408584A52498C488849047EFA042004201DFEE4204450048829041202
+9A9A:0000F9FC08A448884850482048D87F26042005FC1D24E52445FC04222BFE1002
+9A9B:7E20243E1848FFA829104A28984600001FE0002008200FFC00047FC400140008
+9A9C:08207F20087E7E4408A4FF2810101E2822445FE2802008200FFC00047FD40008
+9A9D:0040F9BC09144994495449A4494C7C0005FC05241D24E5FC4524052429FC1104
+9A9E:01007FFE44429FF404403FF80440FFFE08201FD02048C8460FF800087FA80010
+9A9F:0020F81009FE4902490249FE49007DEE052205AA1D66E522456606AA2A221466
+9AA0:0000FBFE085049FC4954495449FC7C0005FC04001FFEE42044A805242AA21040
+9AA1:0000F9FC092449FC492449FC48407C8805F004201C44E7FE442205242A221060
+9AA2:0020F84009FC4924497C498C49547D24055405FC1C20E41045540542294A1238
+9AA3:03FEF20213FE520052FC520853FE7A100A300BCE3A42CA840CEE0F842884118C
+9AA4:07E0F25C13C4525453C8526857D47864083C0FC03944CA6808D009482E461040
+9AA5:0094FB980892498E4A8049FC49247DFC052405FC1C88E5FC448807FE28881104
+9AA6:01FCF8200BFE4A2249AC482049AC7C00049E07F21C9EE5D246BE0492289E1092
+9AA7:0020F3FE100051DC515451DC50887BFE08880BFE3888CBFE089409882AA410C2
+9AA8:1FF010101F90109010907FFE40029FF410101FF010101FF01010101010501020
+9AA9:00407C404440744055F8FE4882487C4844487C4844487C4A448A448A55064A00
+9AAA:00007C0044F074905490FE9082907CD044B07C9044907C9244924512550E4A00
+9AAB:00407C40444075F85448FE4882487D4844C87C4844A87CA8448A450A55064A02
+9AAC:00007CFC442074205420FE2082207DFE44207C2044207C204420442054A04840
+9AAD:00007CFC442074205420FE2082207DFE44207C2044207C204420442054204820
+9AAE:3F1021143D12251225107F9640B8BF1021103F1021103F10210A210A25062202
+9AAF:00407C20440075FC5400FE0082F07C9044907C9044907C9244924512550E4A00
+9AB0:00007CF8448874885488FF0682007DFC44847C8444487C504420445054884B06
+9AB1:00207C20442074505450FE8883067C4844487C4844487C484448448854884908
+9AB2:00407C4044FC74845504FEF482947C9444F47C8444947C8844824482547E4800
+9AB3:00107C10441074FE5492FE9482907CFC44A47CA444A87CA84490452855444A82
+9AB4:00087C284428742854A8FEAA82BC7CA844A87CA844A87CA844AA44BA54EA4986
+9AB5:00207C204420742055FEFE7082A87CA845247D2446227CF84420442054204820
+9AB6:00047C1E44F074905490FE9082907CFE44907C9044907C88448A44AA54D6488A
+9AB7:00207C204420742055FEFE2082207C2044FC7C8444847C844484448454FC4884
+9AB8:00207C10441075FE5420FE2482447CF844127C2244447D884410442854444982
+9AB9:00207C10441074FE5400FE4482827D0044447C4444287C284410442854444882
+9ABA:00087C1C44E074805480FEFE82807C8044BC7CA444A47CA444A4453C55244A00
+9ABB:00207C2045FC74505488FF0482FA7C0047FE7C4044807DFC4404440454284810
+9ABC:00407C40447874885550FE2082507C8845067CF844887C884488448854F84888
+9ABD:00047C1E45E074225512FE9482807C2045FE7C4444847DC84430442854C44B02
+9ABE:00007DFE4420742055FCFF2483247DFC45247D2445FC7D2044A0444054B04B0E
+9ABF:00847C48440074FC5448FE4882487C4845FE7C4844487C484448448854884908
+9AC0:00207C4044FE74925492FEFE82927CA244FE7C4844887DFE4408440854084808
+9AC1:00007CF844A874A854F8FEA882A87CF844207DFC44207C7044A8452654204820
+9AC2:00407C2045FC75045440FE7882887D5044207CD847067CF84488448854F84888
+9AC3:00FC7CA444A474FC54A4FEA482FC7C2044207DFE45227D2A45FA450A55024906
+9AC4:00087C0844FE751054A0FE7E82A27C2245BE7CA244BE7CA244AA44A455404A3E
+9AC5:00207D2444A8742055FEFE6882A47D0244207DFE44487C8844D04430544C4982
+9AC6:00147C1245FE741054FEFE9282FE7C9244FE7C9244047DFE444444245424480C
+9AC7:00207C1045FE740054FCFE8482FC7C0045FE7D02457A7D4A457A4502550A4904
+9AC8:00207C1044FE74005444FE2882FE7CA244107CFE44207C3C4424444454544888
+9AC9:00207C2045FE75525448FEFE82907D9044FE7C9044907CFE4490449054FE4880
+9ACA:00847C44444875FE5420FEFC82207DFE44407C8044FE7D104610441055FE4800
+9ACB:00207C1045FE75025448FEFC82487C0044FC7C8444A47CA444A4445054924B0E
+9ACC:00407C2045FE75025418FEE082807CFC44907C9044907DFE4400448855044A02
+9ACD:00207C1045FE75485548FF4883FE7D4845487DEC455A7D684548454856484848
+9ACE:00007CEE442274AA5466FEAA82107C2844447D9244207CC8443244C4541848E0
+9ACF:00207DFC452477FE5524FFFC82207DFC45247DFC44407DFE448845D054704B8C
+9AD0:00207C2044FC742055FEFE8883DC7C8844C87DBC44007DFE445044505494490C
+9AD1:00007CFE44AA74AA54FEFE4082FE7D2244FA7CAA44AA7CFA442244FA540A4804
+9AD2:00487DFE4448740055FEFE8882EA7D2C44CA7C8645487DFE4448444854884908
+9AD3:00107C7E452074BC54C8FEBE82007DBC44A47CBC44A47CBC44A444AC55404A3E
+9AD4:00507DFC455475FC5554FFFC82007DFC44007DFC45047DFC4488445057FE4800
+9AD5:00207C1045FE750254FCFEA883307CFC45847CFC44847CFC448444FC54484884
+9AD6:00207DFE454A74FC5448FEFC82847CFC44847CFC44847CFC445044545492490E
+9AD7:00207C3E442075FE5522FFF883227D7E45547D7C45547D7C450046FE54AA49FE
+9AD8:02000100FFFE00000FE0082008200FE000007FFC40044FE4482448244FE4400C
+9AD9:020001007FFC10101FF010101FF010107FFC40044FE4482448244FE44004400C
+9ADA:20201010FE1001FE7C0044007C780048FE488248BA48AA4AAA4ABA8A82868700
+9ADB:200010FCFE8400847CFC44A07CA000A0FEF882A8BAA8AAA8AAA8BAAA834A8686
+9ADC:2000107EFE42007E7C42447E7C000014FE648224BA24AAFEAA24BA2482448684
+9ADD:2048116AFEDC00487CB445227DFE0102FE208220BAFCAA24AA44BA4482948708
+9ADE:207C1044FE44007C7C0044EE7CAA00AAFEEE8210BAFEAA38AA54BA9283108610
+9ADF:3F04200420083E10202020443E0420082010FF22104224044208FF10412000C0
+9AE0:3E0420183E6020043E182062FF0422187F6000000FE00820082010222022C01E
+9AE1:3E0420183E6020043E182062FF0422187F6000007FFC0440044008423042C03E
+9AE2:3E0420183E6020043E182062FF0422187F60013011D01F107152112210020FFE
+9AE3:3E0420183E6020043E182062FF0422187F6002007FFC040007F0081010A06040
+9AE4:3E0420183E6020043E182062FF0422187F6001007FFC0380054009203118C106
+9AE5:3F0820303EC42018FF62220C7F7000000FF008107FFE08107FFE081008500820
+9AE6:3E0420183E6020043E182062FF0422187F6001F03E0003F03E0003FA7E0201FE
+9AE7:3E0420183E6020043E182062FF0422187F6001007FFC4104028004821882E07E
+9AE8:3E0420183E6020043E182062FF0422187F6000003FF80000FFFE04401842E03E
+9AE9:3F0820303EC42018FF62220C7F700000FFFE010021FC21043FFC000400280010
+9AEA:3E0420183E6020043E182062FF0422187F600100FFFE04000FF0122061C00E3C
+9AEB:3E0420183E6020043E182062FF0422187F6000007FF8080810303FF8D0081FF8
+9AEC:3E0420183E6020043E182062FF0422187F6000007FFC03000D70710C0100FFFE
+9AED:3E0420183E6020043E182062FF0422187F60088008882E9028E028842E84F07C
+9AEE:3E0420183E6020043E182062FF0422187F600110FFFE04000FF0122061C00E3C
+9AEF:3F0820303EC42018FF62220C7F7001003FF821083FF82108FFFE200820282010
+9AF0:3E0420183E6020043E182062FF0422187F6000001220FFFE122013E010001FFC
+9AF1:3F0820303EC42018FF62220C7F7008001FF020105F9010901FD0102010040FFC
+9AF2:3E0420183E6020043E182062FF0422187F6000803FFC208427F0222041C09E3C
+9AF3:3E0420183E6020043E182062FF0422187F6000003FE00440FFFC04841888E180
+9AF4:3F0820303EC42018FF62220C7F7004407FF804483FF824403FFC084410542048
+9AF5:3E0420183E6020043E182062FF0422187F600000FFFE02003FF8248824A82010
+9AF6:3F0820303EC42018FF62220C7F7000003FF808200FE008200FE0083EFFE00020
+9AF7:3E0420183E6020043E182062FF0422187F6004403FF824483FF824483FF82008
+9AF8:3E0420183E6020043E182062FF0422187F6004403FF80440FFFE082010102008
+9AF9:3E0420183E6020043E182062FF0422187F600840104037FCD0E013581C461040
+9AFA:3F0820303EC42018FF62220C7F70000000F83F000100FFFE01001FF010101FF0
+9AFB:3F0820303EC42018FF62220C7F700100FFFE01003FF800003FF820083FF82008
+9AFC:3F042018FF62220C7F7008001FF0282007C01830E10E1FF001007FFC01000100
+9AFD:3E0420183E6020043E182062FF0422187F6011101110292845443FF80100FFFE
+9AFE:3F0820303EC42018FF62220C7F70111009203FF820083FF820083FF820082018
+9AFF:3E0420183E6020043E182062FF0422187F60102048A825240A227028103017C0
+9B00:3F042018FF62220C7F70082004407FF801083FF821003FFC0304051419086100
+9B01:3E0420183E6020043E182062FF0422187F6000083E4808487F481C482A084918
+9B02:3F0820303EC42018FF62220C7F7000201FC010001FF810801080FFFE10202010
+9B03:3F0820303EC42018FF62220C7F7001007FFC40041FF000007FFC111025084204
+9B04:3F0820303EC42018FF62220C7F7000001FF010101FF010101FFC644408943308
+9B05:3F0820303EC42018FF62220C7F7000003E7C22443E7C22443E7C22444A948508
+9B06:3E0420183E6020043E182062FF0422187F6010101088FD443242589095F81008
+9B07:3F042018FF62220C7F7008001FF020205FF80108FFFE01081FF8010805000200
+9B08:3F042018FF62220C7F70111009207FFC0400FFFE10102FE8C82608A0084807F8
+9B09:3F0820303EC42018FF62220C7F700440238824483FF814102FE8144003807C78
+9B0A:3F042018FF62220C7F7001007FFC01003FF80200FFFE08201FF02828CFE60820
+9B0B:3F042018FF62220C7F7010100820FFFE00003E0822483E4822483E4822082618
+9B0C:3F042018FF62220C7F7004007FFC08801FFC28104FF088100FF0081008500820
+9B0D:3E0420183E6020043E182062FF0422187F60107CFF44107C7E44427C7E44428C
+9B0E:3F0820303EC42018FF62220C7F7004047FC404243FA424A43FA4150424944408
+9B0F:3E0420183E6020043E182062FF0422187F6000007C101052FE94382854449282
+9B10:3F042018FF62220C7F7001081FD001207FFC06201C4463FC00001FF811081FF8
+9B11:3F042018FF62220C7F7008407FFC04803FF00490FFFE04903FF00CA03498C486
+9B12:3F042018FF62220C7F7001007FFC01001FF0101011101110FFFE082010102008
+9B13:3F042018FF62220C7F70020001007FFE40229FC410001FF81080FFFE10202010
+9B14:3F042018FF62220C7F70210013F0151000E0775C11F0104013FC284047FE0000
+9B15:3F042018FF62220C7F700820FFFE08201FF010101FF01010FFFE08203018C006
+9B16:3F042018FF62220C7F7008201FF0102025487EFC044018B0E30E0C6003801C00
+9B17:3F042018FF62220C7F7008207FFC08200FE001007FFC5144492455546184410C
+9B18:3F042018FF62220C7F7000001FF010101FF010107FFC44447FFC082007C0F83E
+9B19:3F042018FF62220C7F7008207FFC511449247FFC00001FF010101FF010101FF0
+9B1A:3F042018FF62220C7F7000000BFE104061FC090411FC610405FC090431FCC088
+9B1B:3F042018FF62220C7F7002003FF82448238824483FF829482528294A25263182
+9B1C:3F042018FF62220C7F7000007C7C44447C7C47C47C7C47C4444447C4444448CC
+9B1D:3F042018FF62220C7F7C44447C7C44447C7C40044FE448244FE448244FE4400C
+9B1E:3F042018FF62220C7F7002401FF812481FF812483FFC20003FFC28884A708C0E
+9B1F:3F0820303EC42018FF62220C7F7001003FF82448FFFE10101FF00C883470C60E
+9B20:3F0820303EC42018FF62220C7F7002800C603FF8D55613901FF00A2009200FE0
+9B21:3F042018FF62220C7F7001007FFC4204A92847E400003FF82448FFFE01000300
+9B22:3F042018FF62220C7F7001007FFE40029FF4092011C00FF818886FF804100808
+9B23:3F042018FF62220C7F701084210810843FF82448238824483FF8294A25263182
+9B24:3F042018FF62220C7F700100FFFE22883EF804403FF80440FFFE04901C60671C
+9B25:00005E7A44225E7A44225E7A40024002400240024002400240024002400A4004
+9B26:00005E7A44225E7A44225E7A4082448242824882448240F25F824082408A4084
+9B27:00005E7A44225E7A44225E7A420241025FF241024FE2492249A24942410A4104
+9B28:00005E7A44225E7A44225E7A4002444244424FE2444244425FF24442482A4004
+9B29:00005E7A44225E7A44225E7A42024CE248224EE248224FE242824492587A4004
+9B2A:BEFA8822BEFA8822BEFA8002BF1280129EFE921292929E5292128F12B8529026
+9B2B:BEFA8822BEFA8822BEFA80029C42847ABF5292929E1292529E2293A2FE528296
+9B2C:BEFA8822BEFA8822BEFA8806B3BAAAA2BBA28A3EBBAAA0AABBAA8A2A8BAABC46
+9B2D:BEFA8822BEFA8822BEFA8006BBBAAAA2BBA28A3EBBAAA0AABBAA8A2A8BAABC46
+9B2E:BEFA8822BEFA8822BEFA8102BFF2A012BCF28482B4F29492FCF29482B49283F6
+9B2F:09202448228829282288244829283FF81000103811C01E04100410040FFC0000
+9B30:2288F93E2288729CA92A228800007FFE4A12A4A42AC83F9010241F4810101F20
+9B31:2208F3BC2508739CAD6A27C800007FFE4A12A4A42AC83F9010241F4810101F20
+9B32:0000FFFE00001FF0101010101FF000007FFC482444445FF44104410441144008
+9B33:01FC01003FFE210221F02F0420FC20003FFE220823F820002FFE29124BFA8842
+9B34:0014FE1200FE7C1044107CFE0092FE9282FEAA929292FEFE9292929292928686
+9B35:3E7C48907EFC142A66C60400FFFE00001FF010101FF000007FFC44444FE4410C
+9B36:10F87CA810A8FE52288E4500FFFE00001FF010101FF000007FFC44444FE4410C
+9B37:0028FE9200AA7C8244FE7C280044FEA2823CAA449244FEA89210922892448682
+9B38:0020FEDE008A7CCA44AA7CD200A6FE0082FEAA929292FEFE9292929292FE8682
+9B39:08F83E8808F87E8808F81452228E4100FFFE10101FF000007FFC44444FE4410C
+9B3A:0040FE7E00807D7C44447C7C0044FE7C8200AAFE9240FEFE932A924A92928626
+9B3B:711C1544711C47D0739C1544310C0000FFFE10101FF000007FFC44444FE4410C
+9B3C:020004003FF8210821083FF8220822083FF8051009200948117C2102410280FE
+9B3D:080410047F08491049247F04490849107F2210021A042C882F904820480287FE
+9B3E:081010107F7E491049107F10497C49047F4410281A102CA82FC44884480287FE
+9B3F:0808101C7F60494049407F7E494849487F4810481A482C882F884800480287FE
+9B40:081010107F28492849447F82492849287F2810281A282CA82FA84848480287FE
+9B41:080810487F28492849087F48492849287F0E10F81A082C882F884808480287FE
+9B42:002000407DFC0124012401FCFF24212421FC2040486844B2FCBE45200122021E
+9B43:102820247C2055FE54207C20547C54447C5410882A942D244F40480287FE0000
+9B44:1020104021FC7D24452445FC45247D2445FC4440446844B27CBE45200122021E
+9B45:081010107F10497C49107F1049FE49107F3810541A922C902F904810480287FE
+9B46:101420127C1054FE54907C94549454887C8A10DA2AA62D424F00480287FE0000
+9B47:3FFC20903FFC21402630388C21002FF828882FF828882FF8415042FA8C8A307E
+9B48:081010547F384910497C7F444944497C7F4410441A7C2CC42FC4484C480287FE
+9B49:100021FC7C50545055FC7D54555455547DAC11042B042D144F08480287FE0000
+9B4A:101020147C1257FE54107DD4555455D47C1810CA2B162D224F40480287FE0000
+9B4B:082810247F40497E49C87F48497E49487F48107E1A482CC82FFE4840480287FE
+9B4C:082410247F7E492449247F3C4924493C7F2410241A7E2C802FA84844480287FE
+9B4D:100021FC7D04558C55547DFC554455247DFC11442B742D044F0C480287FE0000
+9B4E:23FE4020F820ABFEAA22FB32AAAAAB76FA66222256225A2A5E0450024FFE8000
+9B4F:0C20704011FCFF24392455FC9324012411FCFC40246844B228BE11202922C61E
+9B50:108820507DFE545055FC7C5457FE54547DFC10502AD82D544F52485287FE0000
+9B51:104020207DFC545055247D5455FC54207DFC11442B542D744F0C480287FE0000
+9B52:100021FC7C5055FC55547DFC540054F87C0011FC2AA82D244F60480287FE0000
+9B53:11FC21247DFC552455FC7CA855FC54A87CA811FC2A202DFC4F20482287FE0000
+9B54:00803FFE24103F7C26382D5435122FF828882FF828882FF8215042F84C8AB07E
+9B55:109421187DDE5494555A7DDE549455FE7C9010D42AAA2D164F20480287FE0000
+9B56:1020203E7C2055FE55227D3C55E2551E7D2811AA2A6C2D284F7C480287FE0000
+9B57:1020FE4010FC7C940094FEFC02A47CA410FCFE200044FF6A026EFFA0AAA2E71E
+9B58:3FFE28882F8A20082FBE28882F88289429A227F8248827F8248847F842528C3E
+9B59:42043FD88A904F9E2A945FD482241FF011101FF012101FF004A808BA3082C07E
+9B5A:040004000FE0102020407FF8A10821083FF8210821083FF80000488844448444
+9B5B:200020007CFE442288227E22522252227E22522252227E420042AA82AA940108
+9B5C:202020207C20442088207E20522052207E50525052507E500048AA88AA840102
+9B5D:100410043E04422484247F24492449247F24492449247F24000455044A948A88
+9B5E:208020407C20442088107E10521052287E28522852287E480044AA44AA840102
+9B5F:200020007C7C441088107E10521052107E10521052107E100010AA10AAFE0000
+9B60:2008203C79E0482090207C205420543E7DE0542054207C220022AA22AA1E0000
+9B61:204020407C40447C88847E84530452447E24522452047E040004AA04AA280010
+9B62:200020007CFC440488047E04520452FC7E84528052807E800082AA82AA7E0000
+9B63:200021F87C08445088207E1053FE52227E24522052207E200020AA20AAA00040
+9B64:205020507850489290927D94569854907CB054D054907C900092AA92AA8E0080
+9B65:200020FC7C44444888487E50525C52447E44524452687EA80090AA98AB240042
+9B66:201020107C10441088547E52525252907E10521452047E080008AA10AA2000C0
+9B67:202020107C1044FE88007E00527852487E48524852487E4A004AAA8AAA860100
+9B68:202020207C2045FC88207EA852A852A87EA852A852F87E220022AA22AA1E0000
+9B69:204020407C40447E88AA7F2A522A524A7E4A529253127E220022AA42AA940008
+9B6A:201020107C10442888287E44528252487E48524852487E480048AA88AA880108
+9B6B:201020107C10441088FE7E92529252107E28522852287E280048AA4AAA8A0106
+9B6C:2008201C79E0490091007DFC554455447D44552855287D100110AA28AA440482
+9B6D:200020FC7C00440088007EFE525052507E50525052507E520052AA92AA8E0100
+9B6E:201020907C90449288927E9452F452987E90529052907E9200B2AAD2AA8E0000
+9B6F:08001FE020207FF8A1083FF821083FF8444482221FF010101FF010101FF01010
+9B70:204020207C2045FE88887E88528852887E88525052507E200020AA50AA880106
+9B71:200021FE7C20442088207E3C524452447E44528452FC7E080008AA08ABFE0000
+9B72:202020107C10447E88427E425242527E7E42524052407E400040AA80AA800100
+9B73:200023FE7820482090207DFC552455247D24552455247D340128AA20AA200020
+9B74:202020107C1045FE88407E405240527C7E44524452447E440044AA44AAA80110
+9B75:200820287C28442888447E445282537C7E24522452247E240044AA44AA940108
+9B76:201020107C1044FE88927E92529252AA7EAA52CA52827E820082AA82AA8A0084
+9B77:204820447844484091FE7C50545054507C50545054507C520052AA92AA8E0100
+9B78:201020907890489090907CFE548054807C8054F854887C880088AA88AA880108
+9B79:2008201C7CE0442088207E3C52E052207E20523E53E07E200022AA22AA22001E
+9B7A:200020007DFE440488047EF4529452947E94529452F47E940004AA04AA140008
+9B7B:200021FC7924492491247DFC552455247D2455FC55247C200020AA20AA200020
+9B7C:20202020782049FC90207C20542055FE7C20542054407C480084ABFEAA820000
+9B7D:204420447C44444488FE7E44524452447E44527C52447E440044AA44AA7C0044
+9B7E:200021FE7C10441088207E20526852A47F22522252207E200020AA00ABFE0000
+9B7F:202020207850485090887D24561254107DFC540454087C880050AA20AA100010
+9B80:202020107C1044FE88827E84524052447E48525052607E420042AA42AA3E0000
+9B81:205020487848484091FE7C405440547C7CA454A454A87D280110AA28AA440082
+9B82:200020FE7C82449288927E92529252927E9252AA52A67EC60082AA82AAFE0082
+9B83:200021FC7C20442089247EA452A852207FFE522052207E200020AA20AA200020
+9B84:20502050785049FC90547C5455FC55507D5055FE54527C52005AAA94AA900110
+9B85:201020087C08440288227E24522452A87EAC52B253327E200062AAA2AB1E0000
+9B86:088028882EF028842E84F07C08000FE010403FF051101FF011101FF024884244
+9B87:20202020782049FC90207C20542057FE7C7054A854A87D240124AA22AA200020
+9B88:204020407C4044FC88847F0452F452947E94529452947EF40094AA04AA280010
+9B89:200021FC7C44444488447E44529452887F0052FC52847E840084AA84AAFC0084
+9B8A:201020107C2044FE88827E82528252827EFE528252827E820082AA82AAFE0082
+9B8B:201020107C10441088FE7E92529252927E9252FE52927E920092AA92AAFE0082
+9B8C:201020087C0844FE88107E10522052427EFC524852107E200044AAFEAA420000
+9B8D:20102010781049FE91127D14551055FC7D44554455287D280110AA28AA440482
+9B8E:201020107C104410881E7E10521052107EFE528252827E820082AA82AAFE0082
+9B8F:202020207920492091FC7D20562054207C2055FC54207C200020AA20ABFE0000
+9B90:202020207C20444088487E8453FE52827E0052FC52847E840084AA84AAFC0084
+9B91:204020407CFC448489047EF4529452947EF4528452947E880082AA82AA7E0000
+9B92:204420447844488490BE7D84568454A47C94549454847C840084AA84AA940088
+9B93:204020407C40447E88A07EA05320523C7E20522052207E3E0020AA20AA200020
+9B94:200020FE7C80448088807EFC528452847E84528452FC7E800080AA80AAFE0000
+9B95:201020107C10441088FE7E10521052107E7C524452447E440044AA44AA7C0044
+9B96:200020007DFE441088107E205220527C7E4452C453447E440044AA44AA7C0044
+9B97:20402040787C488491887E50542054507C88570654607C100008AAC0AA200010
+9B98:205020547852489290907D9655F856907C90549054907C90008AAA8AAA860082
+9B99:200020EE7C22442288AA7E66522252227E26526A52B27E220022AA22AAAA0044
+9B9A:201020107C1044FE88107E10527C52007E00527C52447E440044AA44AA7C0044
+9B9B:202020207820483C90207C2055FE54007C20542054A87CA40122AA22AAA00040
+9B9C:2008201C79E0490091007DFE550055007D7C554455447D440144AA7CAA440400
+9B9D:111009207FFC0200FFFE08203418CFE610403FF051101FF011101FF024884244
+9B9E:200020FE7C10441088207EFE52AA52AA7EAA52AA52AA7EAA00AAAAA2AA8A0084
+9B9F:2040202078204BFE92027C44544057FE7C88548855087CD00020AA50AA880304
+9BA0:2040204078FC490492087DFE5500557C7D44554455547D480142AA42AA3E0400
+9BA1:205020507850495290D47C58545054587CD4555254507C500092AA92AB12020E
+9BA2:20202120792049FC91207E20542057FE7C7054A854A87D240124AA22AA200020
+9BA3:20002040799E491291127D1255D255127D125512555A7D940110AA10AA100010
+9BA4:7F8408241F24212456241804E4140FE810403FF051101FF011101FF024884244
+9BA5:204020407C78448889507E20525052887F0652F852887E880088AA88AAF80088
+9BA6:200020FE7C82448288BA7E82528252BA7EAA52AA52AA7EBA0082AA82AA8A0084
+9BA7:202020207BFE482091FC7C2455FC55207DFE5422542A7C540050AA88AB040202
+9BA8:20802084789848E090827C82547E54007CFC548454847CFC0084AA84AAFC0084
+9BA9:208420487C0044FC88487E48524852487FFE524852487E480048AA88AA880108
+9BAA:2020202079FE484090407CFC548455847EFC548454847CFC0084AA84AA940088
+9BAB:20402020782049FC90007C88550456027C88548854507C500020AA50AA880104
+9BAC:201020107CFE442888447E82527C52007EFE522052407E7C0004AA04AA280010
+9BAD:201020107C7C441088107E1052FE52007E105210527C7E100010AA10AAFE0000
+9BAE:208420447848480091FE7C20542054FC7C20542055FE7C200020AA20AA200020
+9BAF:202020207850485090887D0456FA54007C0054F854887C880088AA88AAF80088
+9BB0:200020007CFE448288827EBA52AA52AA7EAA52AA52BA7E820082AAFEAA820000
+9BB1:20402040784449F490487C5057FE54407C80558456987CE00082AA82AA7E0000
+9BB2:205020547852489290907DBE569054907C9054A854A87CA800A8AAA4AAA400C2
+9BB3:2040204479F4484890507DFE544054807DFE564054807CFC0004AA04AA280010
+9BB4:204820487848488890FE7D885688549C7C9C54AA54AA7CC80088AA88AA880088
+9BB5:208420447C48440088FC7E84528452847EFC524852487E480048AA8AAA8A0106
+9BB6:200020FC7C24442489FE7E24522452FC7E40524052FC7EC40144AA44AA7C0044
+9BB7:20882048785049FC90247C2455FC55207D2055FE54227C22006AAAA4AB200020
+9BB8:2080208078F8490892107DFC552455247D2455FC54507C500090AA92AB12020E
+9BB9:201020927C52445488107EFE528252827EFE528252827EFE0082AA82AA8A0084
+9BBA:04407FFC01003FF80400FFFE14002FE0D0403FF051101FF011101FF024884244
+9BBB:201020107C20444488FE7E28524452A27E3C524452447EA80010AA28AA440082
+9BBC:200020FC7804487C90047CFC540055FE7D0254FC54447C440028AA10AA680186
+9BBD:201020107C28442888447EBA521052107EFE521052587E540092AB12AA500020
+9BBE:2004201E79E0482291127C94548054207DFE544454847DC80030AA28AAC40302
+9BBF:200023FE7920492891287DE8552855287D2855E855287D2A013AABEAAA260020
+9BC0:200C21F07820484490887DF0542054447DFE542254207CA80124AA22AAA00040
+9BC1:200021FE7820482091FC7D24552455FC7D24552455FC7D2000A0AA40AAB0030E
+9BC2:200021FE7C28442888FE7EAA52AA52AA7EC6528252827EFE0082AA82AAFE0082
+9BC3:200021FE7820482090FC7C44544455FE7C00540054FC7C840084AA84AAFC0084
+9BC4:202820247824482091FE7C20552054B27CB4546854A87D240222AA20AAA00040
+9BC5:2004200E7BB8488890887D28552E57A87CA856A856A87D3E0100AA80AA7E0000
+9BC6:201420127CFE441088107EFE529252927EFE529252927EFE0092AA92AA920086
+9BC7:2020201079FE490292047CF8540054007DFE545054507C500092AA92AB0E0200
+9BC8:108011F8128820702B8E688068F8A9102BFC2D2429FC292429FC20002154222A
+9BC9:200021FC7924492491FC7D24552455FC7C20542055FC7C200020AA20ABFE0000
+9BCA:20401248444420140860738028000FE010403FF051101FF011101FF024884244
+9BCB:2008210878884808912C7CAA54AA54487C48548A558A7C840084AA88AA900060
+9BCC:201020507C50447C88507E90521052FE7E005200527C7E440044AA44AA7C0044
+9BCD:2020201079FE482090487C8455FE54027CA854A854A87CA800A8AAAAAB2A0206
+9BCE:201020147812481091FC7D10551055D47D54555455547D48014AAA9AAA260442
+9BCF:2002203278C2484A904A7C4A55FA544A7CCA54EA555A7D420242AA42AA4A0044
+9BD0:201020107C7C441088107E1052FE52107E105250525C7E500070AA90AA8E0100
+9BD1:20C220347818486491827C2055FE54507C9055FE56927C92009AAA94AA100010
+9BD2:200020FC7C04446888107EFE529252927EFE529252927EFE0092AA92AA920086
+9BD3:2020204078F8488890F87C8854F8548A7C8C55F854187C280048AA88AB280010
+9BD4:200020927C92452489247E92529252007EFE529252927EFE0092AA92AAFE0082
+9BD5:2088208879FC488890887CF8548854887CF8548854887DFE0000AA50AA880104
+9BD6:2020202079FE482090FC7C2055FE54007CFC548454FC7C8400FCAA84AA940088
+9BD7:04407FFC01003FF80400FFFE14102FE8D0463FF051101FF011101FF024884244
+9BD8:201C21E07820482093FE7CA8552456427C4057FE54887D0800D0AA30AA480184
+9BD9:2020201079FE480090FC7C8454FC54007CFC540854107DFE0010AA10AA500020
+9BDA:201C20E0782049FE90707CA8552456227CF8541054207DFE0020AA20AAA00040
+9BDB:200020FE7C92449288BA7E9252FE52827EBA52AA52AA7EBA0082AA82AA8A0104
+9BDC:202020107CFE440088447E2853FE52207E2053FE52447EC40028AA18AA640182
+9BDD:200020FE7C82449288927EFE529252927EBA52AA52AA7EBA0082AA82AAFE0082
+9BDE:200020FC7804487C90047CFC540055FE7D22542054FC7CA400A4AAB4AAA80020
+9BDF:201020107CFE441088107EFE529252FE7E9252FE52107E380054AA92AA100010
+9BE0:201020107C1044FE88107E54525452547EBA521052387E540092AA10AA100010
+9BE1:2050205078504BDE90507C50545055DC7C50545054507C5003DEAA50AA500050
+9BE2:200020207CCE448288827EEE528252827EFE522852287E280048AA4AAA8A0106
+9BE3:200020FC7C84448488FC7E84528452FC7E4052FE532A7E4A0092AB22AA4A0084
+9BE4:200020FC7884488490FC7C84548454FC7C00549054927CF40098AA92AAD2008E
+9BE5:2020202078FC482090207DFE544854847D22542054FC7C200020AA20ABFE0000
+9BE6:2088208878E8492C912A7EA8544854A07D1E560054FC7C840084AA84AAFC0084
+9BE7:207C20447C44447C88447E44527C52007EFE528252827EFE0082AA82AAFE0082
+9BE8:204020207DFE440088007EF8528852887E8852F852207EA80124AA22AAA00040
+9BE9:201020107C28444488827F7C520052FE7EAA52AA52FE7EAA00AAAAAAAA820086
+9BEA:2020202078FC482090207DFE544854847D22547854887D480050AA20AA50018C
+9BEB:200023E0795C495491547DD4555455547DD4555455487D6803C8AA54AA540062
+9BEC:0640387C08947E241C442A9448080FE010403FF051101FF011101FF024884244
+9BED:200020FC7C08441088FE7E10521052507E2052FE52AA7EAA00AAAAAAABFE0000
+9BEE:202020107CFE448288007E7C520052007EFE521052107E540052AA92AA500020
+9BEF:20822082728293EA248AF88AAFFAA88AFBEAAAAAAAAAFAAA02A2AAE2A88A0084
+9BF0:201020107C28444488A27F1052FC52047E08522052107E0400A2AAA2AAAA0118
+9BF1:201020107C1E441088FE7E92529852F07E92528E52807EB800A8AAAAAB4A0286
+9BF2:2088204878084BF491147D22550055E87D24552455207D300128AA24AAA40440
+9BF3:2040202073FE9200221CFAF0AA90AA90FAFEAA90AA90FA9002AAAACAACA60812
+9BF4:200021FC7804483491C47C44544455F47D54555455F47C440054AA76AB960002
+9BF5:20402048788449FE90207DFE548855247E42558854107C2200C4AA18AA600180
+9BF6:200020FE7C92441088FE7E10527C52547E7C5254527C7E1000FEAA10AA100010
+9BF7:2000207C7C44447C88447E7C520053FE7E105210525E7E500050AAB0AA9E0100
+9BF8:2040205C7C44448488BE7E905390529E7EA8528852BE7E880088AA94AA9400A2
+9BF9:200021FC790449FC91047DFC542055207DFE562054207DFC0020AA20ABFE0000
+9BFA:2020202479F4482890287DFE542054407CFC558456847CFC0084AA84AAFC0084
+9BFB:2082208273E29082208AFBEAAAAAAAAAFBEAA88AA9CAFAAA04A2A882A88A0084
+9BFC:202820927CAA448288FE7E28524452A27E3C524452447EA80010AA28AA440082
+9BFD:200020EE7CAA44AA88AA7EEA52AA52AA7EEA528A52CA7EAE00D8AA88AA080008
+9BFE:2040207E784848BE90AA7DAA56BE54AA7CAA54BE54C87CA80090AA98AAA400C2
+9BFF:2020201079FE490291027DFE550055007DFE55AA56AA7CFE00AAAAAAAAAA0086
+9C00:201E23E07844492490887DFC544054407DFE548054FC7D440128AA10AA680186
+9C01:201020207CFE448288FE7E8252FE52107E1252D452587E540094AA92AB500020
+9C02:200221E27922492A91EA7D2A552A55EA7D2A552A55EA7C0200C2AAA2AB2A0204
+9C03:200020FC78A448A490FC7CA454A454FC7C0055FE54907C940088AAA8AAC40082
+9C04:200C200A700893FE2208FBF8AA4AAA4AFBEAAAACAAACFA4C02AAAB0AAA160422
+9C05:2000207C7C544454887C7E545254527C7E1052FE52927E9600BEAA82AA8A0084
+9C06:2020202079FE482090FC7C4055FE54887D0456FA54887C8800F8AA88AA8800F8
+9C07:200020FC7848483091FE7C52549455107E30542055FE7C7000A8AB24AA220020
+9C08:201420547C5444FE88547E54525C52407E7E521052FE7E100038AA54AA920010
+9C09:201020207C7C4444887C7E44527C52007EFE521052107E7C0010AA10AAFE0000
+9C0A:202020207BFE482091FC7D2455AC55747D2455FC54207C7000A8AB24AA220020
+9C0B:200021FE7900497E91427D7E5542557E7D1055FE55247D640118AB24AB4201FE
+9C0C:204420247C2844FE88287E2852FE52AA7EAA52C652827EFE0082AA82AAFE0082
+9C0D:200820687988488890AA7CAC55E854A87C8855C856A87C880094AA94AA9400A2
+9C0E:20102010783C4B9490FE7C94553C55107FBC549054FE7E900190AAC0AABE0100
+9C0F:200020FE7C00447C88447E44527C52007EFE529252927EFE0092AA92AAFE0082
+9C10:200021DC7954495491DC7C0055FC54007DFE548054FC7C040004AA04AA280010
+9C11:200020FC788448FC90847CFC540055FE7C8054FE552A7E4A0092AB22AA540088
+9C12:204020407CFE448089FC7E8452FC52847EFC5240527C7EC40128AA10AA680186
+9C13:200021FC7924492491FC7D24552455FC7C20541054547D420142AB4AAA380000
+9C14:2008200C700A93FE2208FA08AAE8AA0AFA0AAAECAAACFAA802EAAA1AAA260442
+9C15:200021DC7944494491447DDC550055007DDC551455147DD40108AB08AB140122
+9C16:2020202079FE484090FE7D1056FE54007CFE548254FE7C8200FEAA82AA8A0084
+9C17:2080209E78924BF290927C9E549255D27D52555E55527D5201D2AA22AA2A0044
+9C18:2040202079FE490292047DFC544054887DFC542454207DFC0020AA20ABFE0000
+9C19:2084208479FE488490A47C2055FE54407C8054FC55847E840084AA84AAFC0084
+9C1A:2020201079FE490292047CFC540054FC7C8454FC54847CFC0084AA00AAFE0000
+9C1B:200020F87888488890F87C88548854F87C0055FC55547D540154AB54ABFE0000
+9C1C:20882050780049FE90507DFC545457FE7C5455FC54507CD80154AA52AA500050
+9C1D:202020107CFE4400887C7E44527C52007EFE528252BA7EAA00BAAA82AA8A0084
+9C1E:202020407CFC448488847EFC528052FE7E8052FE52027EAA00AAAA02AA140008
+9C1F:202020107CFE440088447E2852FE52A27E1052FE52207E3C0024AA44AA540088
+9C20:200021FC78A4488890507C2054D857267C2055FC55247D2401FCAA22ABFE0002
+9C21:202020DE7C8A44CA88AA7ED252A652007EFE529252927EFE0092AA92AAFE0082
+9C22:200020FE789048FC90907CFC549054907CFE540254AA7CAA00AAAA82AA140008
+9C23:2008200879C8497E91487D48557E55C47D44557E55447D6401D4AA04AA140008
+9C24:2100227E7388928822BEFAAAABAAAA2AFA2AABAAAAAAFAAE0288AB88AA880008
+9C25:200020FE7CAA44AA88AA7EFE521052547E52529252107E540052AA92AA100010
+9C26:2084204478484BFE90847C845508554A7E52579C54847D080108AA52ABDE0042
+9C27:012478A849FC48404BFE79084A844CFA49107BFC4D2449FC492449FC48009954
+9C28:200021F8790849F891087DF8540054007DDC544455547CCC0154AA44AA5400C8
+9C29:2004201E79E0480291227C9454FE55107C1055FE54107C920092AA92AAFE0002
+9C2A:201020107C7E441088107EFE522052427EFE520052FE7EAA00AAAAAAABFE0000
+9C2B:2040202079FE490290507C88552454507C88550456FA7C880088AA88AAF80088
+9C2C:2020203C782049FE91227D3855E4551C7D20551055FE7D440128AA10AA2804C6
+9C2D:2020202478F4482891FE7C20547854C27D3E560054FC7C8400FCAA84AAFC0084
+9C2E:200020F878A848A890D87C8854F854007C0055FC55547D540154AB54ABFE0000
+9C2F:200021DC7844484491DC7D10551055DC7C44555454CC7CCC0154AA44AA5400C8
+9C30:220821087908483E93AA7CAA54BE552A7DAA576A553E7D2A0108AB08AB080108
+9C31:201020107AFE4910917C7C54547C57547D7C551055FE7D100110AA90AA7E0000
+9C32:08207E20087EFEC410281E102A284FE690403FF051101FF011101FF024884244
+9C33:2148214873E8914821DEF88AABEAAAAAFAAAABEAA88AFBEA0092A892A8AA00C4
+9C34:11101550255047D0903E17A422546394A49427D42D5427C8254827D420142AA2
+9C35:20203F20403EBE482AA8FF284A107FE810463FF051101FF011101FF024884244
+9C36:2080208879EE492A92AA7D445484557A7E00540055FE7C2000A8AB24AAA20040
+9C37:2110211E712292542208FE94AAE2AA88FA88AABEAA88FAAC022AAA4AAA280210
+9C38:200023FE7200927C2244FA44AA7CAA00FAEEAAAAAAAAFAAA02EEAA00ABFE0000
+9C39:200021EE794A49EA912A7DE45544554A7DF0540054107CFE0010AA10ABFE0000
+9C3A:201020207C4444FE88447EAA52EE52107E28525452AA7E500024AA48AA100060
+9C3B:207C20447C7C4444887C7E0052FE52AA7EFE520052FC7E440028AA10AA680186
+9C3C:200021DE7842495290CA7D52544254207CFC548454847CFC0084AA84AAFC0084
+9C3D:2050205079FE485091FC7D5455FC55547DFC540054F87C8800F8AA88AAF80088
+9C3E:200023FE785049FC91547D5455FC54007DFC540057FE7C2000A8AB24AAA20040
+9C3F:201021FE781048FC90107DFE540054FC7C8454FC54847CFC0084AAFCAA480084
+9C40:7DFC44207D2045FE7C50485254926FEE10403FF051101FF011101FF024884244
+9C41:2000213E78884890902A7C4A571C552C7D4A551A552A7D480128AA90AA7E0000
+9C42:20482148795E496A91547DC8545054647FC4557E55447D640154AB44AA540448
+9C43:2084204879FE481090FC7C2055FE54407C7C54A455247CFC0044AA44ABFE0000
+9C44:202023FE782049FC91247DFC552455FC7C2255FE54087DFE0108AA88AA280010
+9C45:201021FE7910497C91147DFE5514557C7D10557C55547D7C0154AA7CAA54044C
+9C46:201020FE7C44442888FE7E00527C52447E7C5244527C7E1000FEAA10AA100010
+9C47:2020201079FE4910917C7D1455FE55147D7C551055927D540138AA54AA920430
+9C48:200021FC78204BFE92227DAC542055AC7C0055FC54047DFC0004AA04ABFC0004
+9C49:49202A3E7F4849485DA86B1049284FE610403FF051101FF011101FF024884244
+9C4A:20FC2028781049FE90527C94555054207CFE54AA54C67CBA00AAAABAAA820086
+9C4B:2020203C782049FE91227D3855E4551C7D00552855AA7D6C0128AA28AAFE0000
+9C4C:208020F0791049FC93247D2455FC54407CA4555854987D340054AA92AB500020
+9C4D:201221D478484A8A91047E0255DC54547C6255C0551E7DC20054AA48AB5400A2
+9C4E:201821E078404BFE90887D74565254707C0055FC55047D740154AB74AB04010C
+9C4F:200020FE7C2844FE88AA7EFE5200527C7E44527C52447E7C0010AAFEAA100010
+9C50:202021FC702493FE2024F9FCA820AAAAFBAEAA22ABFEFA2203AEAAAAAAAA0422
+9C51:2048204878FC484890487DFE542054FC7CA454FC54A47CFC0000AA48AA840102
+9C52:2088205079FE485091FC7D54559C55047DFC550455FC7C0801FEAA88AA480018
+9C53:200021DC7954495491DC7C0055FC55247DFC552455FC7C2003FEAA20AA200020
+9C54:2044202879FE481090FE7C1055FE54927C5455FE54007CFE0082AA82AAFE0082
+9C55:201C21E078A4486891FE7CA8552456027CFC54A454A47CFC00A4AAA4AAFC0084
+9C56:200023FE7200931422A4FBF6AA4AAA42FB50AB54ABF4FA44024AAA8AAC920920
+9C57:201020927854481091FE7C54549255107C8454EE55247CB4005EAA44AA840104
+9C58:200021FE780249FE90027DFE540055DE7C9257DE54047DFE0084AA44AA540008
+9C59:2020202078FC482091FE7C8855DC54887CC855BC54007DFE0050AA50AA94010C
+9C5A:201020107CFE4410887C7E00527C52447E7C522852FE7E00007CAA44AA7C0044
+9C5B:204420247C2844FE88927ED652BA52927EFE5200527C7E44007CAA44AA7C0044
+9C5C:2280224E74EA95AA29AAFEEAAAACACAAFDEAAF8AAA8AFAAA04ACACE8A8A80008
+9C5D:202021FC7820488893FE7C8855FC55047DFC550455FC7D0401FCAA88AB040202
+9C5E:200021FC7954495491FC7C0057FE54007DFC550455FC7C620094AB88AAA400C2
+9C5F:0A803138228839382288FFFE88020FE010403FF051101FF011101FF024884244
+9C60:202020507888497492027DFC552455AC7D2455FC54007CF80088AAF8AA8800F8
+9C61:2008200C738A92FE2288FBA8AAA8AAAAFBFAAAAAAAACFBAC002AAAAAAC560022
+9C62:20F82088788848F890007DDC555455547DDC542057FE7C7000A8AB24AA220020
+9C63:201021FE780049FE91027D7A554A55FE7C0054FC54847CFC0084AAFCAA0001FE
+9C64:2014201273FE921022F0FA14AAF4AAB8FAEAAA16AC42F82402A2AA8AAC780000
+9C65:2020213879204BFE90107C1455FE55107DF0555455547DD40168AA4AAA960122
+9C66:200021FC7954495491DC7C5055DC55547D5455DC55547D5401DCAB50AA52003E
+9C67:205021FC795449FC91547DFC540055FC7C0055FC55047DFC0088AA50ABFE0000
+9C68:212420A87BFE4A8A90F87D0C55F055027CFE540055FC7D0401FCAB04ABFC0104
+9C69:200021FC78204BFE92227DAC542055AC7C0055FC55247D2401FCAB24AB2401FC
+9C6A:21FC210479FC490491FC7C2255FC54287FFE544055FC7E8400FCAA84AAFC0084
+9C6B:200E21F078A2485491FE7D22541455527D4A563854407C7C0084AB48AA3001CE
+9C6C:200021FC78204BFE92227DAC542055AC7C0057FE54207DFC0154AB54AB54010C
+9C6D:2040202073FE90882052FFACAAAAAAA8FDACA800A904F9FC0104A9FCA9040204
+9C6E:20A0212C7934492491AC7D34555455DC7D54555457FE7C000048AA44AA820102
+9C6F:204421FE7854484890FE7D9054FE54907CFE549054FE7C8001FEAA44AA3801C6
+9C70:200023FE7A524A5293FE7C2455FC54287FFE542054FC7D8402FCAA84AAFC0084
+9C71:200021FE792849FE91287D7C5554557C7D54557C55107DFE0192AABAAA8A0484
+9C72:212422487124900023FCFA94AA64AA94FBFCAA48AB68FA48036AAA4AAA460362
+9C73:21242174725892DA23FEF954AADAABFEF8A2A820ABFEF87000A8A924AA220020
+9C74:204421FE7C44440088FE7EAA52AA52FE7E1452FE52907ED200ACAAAAAA960122
+9C75:2110211071DE92A82454F812ABFEAA10FAF4AA14AAF4FAA802AAAAFAAA160422
+9C76:208823FE782049FC90407FFE548855247EFA548854F87C8800FAAA94AAA800C4
+9C77:200023FE702093AE22AAFAAAABAEA820FBFEA820ABAEFAAA02AAABAEA82003FE
+9C78:2020203E782049FE91227DF85522557E7D54557C55547D7C0100AAFEAAAA05FE
+9C79:208823FE7888480091DC7D5455DC54887DFE569054FC7C9000FCAA90AAFE0080
+9C7A:20EE20007CEE44AA88EE7EAA521052FE7EA852FE52AA7EFE00AAAABCAAAA0136
+9C7B:0FE010403FF051101FF011101FF024A85E3424507EFC2A543E7C2A54BE7C95AA
+9C7C:040004000FE0102020407FF8A10821083FF8210821083FF800000000FFFE0000
+9C7D:200020007DFC444488447C44544454447C44544454447C8400841D04E1284210
+9C7E:100010001EF8220824087E08AA082AF83E882A802A803E8000820E82707E2000
+9C7F:204020507C48444888407DFE545054507C50545054907C9000921D12E10E4200
+9C80:202020207C2045FE88207D24552455247D2455FC54247C2000221C22E01E4000
+9C81:08001FE020207FF8A1083FF821083FF80000FFFE00001FF010101FF010101FF0
+9C82:102010101E1023FE24407E40AA402A7C3E442A442A443E4400840E8471282210
+9C83:200020007DFC452489247D24552455247DFC550055007D0001021D02E0FE4000
+9C84:200020007DFE440888087DE8552855287D28552855E87D2800081C08E0284010
+9C85:205020487C48444089FE7C405440547C7CA454A454A87D2801101E28E0444082
+9C86:200020007DFC442088207D2454A454A87C2057FE54207C2000201C20E0204020
+9C87:101010101E102210241E7E10AA102A103EFC2A842A843E8400840E8470FC2084
+9C88:101010101E1E221024107EFEAA822A823E822AFE2A823E8000800F0071002200
+9C89:202020207C20442089FC7D24552455247D2455FC55247D2401241D24E1FC4104
+9C8A:104010401E40227E24A07EA0AB202A3E3E202A202A203E3E00200E2070202020
+9C8B:204420447C44448488BE7D84568454A47C94549454847C8400841C84E0944088
+9C8C:101010101E2022FC24847E84AA842A843EFC2A842A843E8400840E8470FC2084
+9C8D:204020407CFC448489047EF4549454947CF4548454947C8800821C82E07E4000
+9C8E:2208111000207FFC440484080FC010403FF051101FF011101FF00000FFFE0000
+9C8F:201020107C1045FE89127D14551055FC7D44554455287D2801101E28E2444482
+9C90:102010201E20224024487E84ABFE2A823E002AFC2A843E8400840E8470FC2084
+9C91:202020207DFC442088207C2057FE54007C20542055FC7C2000201C20E3FE4000
+9C92:202020207C2047FE88207C2055FC54007C0055FC55047D0401041D04E1FC4104
+9C93:204020447DF4444888507DFE544054807DFE564054807CFC00041C04E0284010
+9C94:202020207DFE444088407CFC548455847EFC548454847CFC00841C84E0944088
+9C95:200021FE7C20442088407DFC555455547D54555455547D5401541D54E104410C
+9C96:200021FC7D04450489747D04550455747D54555455547D7401041D04E1144108
+9C97:400243E27A228A2A12AAFAAAAAAAAAAAFAAAAAAAAAAAF88201421922E20A4404
+9C98:2008201C7DE0450089007DFE550055007D7C554455447D4401441E7CE2444400
+9C99:202020207C50448889047E0254F854007C0057FE54207C4000881D04E3FE4102
+9C9A:204020207DFE448888507C20545054887D06548854887C8800881D08E1084208
+9C9B:204020207C2045FE88007C88550456027C88548854507C5000201C50E0884306
+9C9C:108210441E2822FE24107E10AA102A7C3E102A102A103EFE00100E1070102010
+9C9D:04407FFC01003FF80400FFFE14002FC0D0403FF051101FF011101FF00000FFFE
+9C9E:111009207FFC0200FFFE08203418CFC610403FF051101FF011101FF00000FFFE
+9C9F:200021FC7C04440488FC7C04540455FC7C08540855FE7C8800481C48E0084018
+9CA0:200021FE7C20442089FC7D24552455FC7D24552455FC7D2000A01C40E0B0430E
+9CA1:400043FE7800880013DEFA52AA52AA52FB5AAAD6AA52FA5202521A52E25242D6
+9CA2:401042107910897E1020F828AF48A97EF908A908A9FEF90801081A88E47E4000
+9CA3:2040217E7D52455289547D48555454627C10541054FE7C1000101C10E1FE4000
+9CA4:200021FC7D24452489FC7D24552455FC7C20542055FC7C2000201C20E3FE4000
+9CA5:400440047BC48A44127EFA44AA44ABE4FA54AA54AA44FA4403C41A44E0144008
+9CA6:204020407CF8448889507C2054D857267C2055FC54207D2801241E24E0A04040
+9CA7:200C21F07C20444488887DF0542054447DFE542254207CA801241E22E0A04040
+9CA8:20401248444420140860738028000FC010403FF051101FF011101FF00000FFFE
+9CA9:202020107DFE45028A047CF8540054007DFE545054507C5000921C92E10E4200
+9CAA:100010FC1E24222425FE7E24AA242AFC3E402A402AFC3EC401440E44707C2044
+9CAB:400043DE7A528A521252FBD2AA52AA52FA52ABD2AA1AFA9402501AB0E3104010
+9CAC:200021F87C0844D088207DFC552455247DFC552455247DFC01241D24E124410C
+9CAD:202020207DFE442088FC7C2055FE54007CFC548454FC7C8400FC1C84E0944088
+9CAE:202020207CFC442088207DFE544854847D22547854887D4800501C20E050418C
+9CAF:208820887DFC448888887CF8548854887CF8548854887DFE00001C88E1044202
+9CB0:200023E07D5C455489547DD4555455547DD4555455487D6803C81C54E0544062
+9CB1:205020507C5047DE88507C50545055DC7C50545054507C5003DE1C50E0504050
+9CB2:200021FC7D04450489FC7D04550455FC7C00551255D47D1801101D52E192410E
+9CB3:20FC20847C8444FC88847C8454FC54007DFE550255027DFE01021D02E1FE4102
+9CB4:200021FC7D04452489247DFC552455247D74555455547D7401041D04E1FC4104
+9CB5:200020407D9C450489047DDC550455047DFC545054507C5000901C92E112420E
+9CB6:40204020785088881144FA22A9F8A808F850A820A8A4FA82028A1A8AE4784000
+9CB7:200021FC7D24452489747D2455FC55047D74555455547D7401041E04E2144408
+9CB8:204020207DFE440088007CF8548854887C8854F854207CA801241E22E0A04040
+9CB9:204020487C8445FE88207FFE548855247E42558854107C6201841C18E0604380
+9CBA:200021FC7C04443489C47C44544455F47D54555455F47C4400541C76E1964002
+9CBB:209220927D24464889247C92549254007DFE552255227DFE01221D22E1FE4102
+9CBC:202021FC7C2044888BFE7C88540055FC7D04552455247D2401241C50E0884304
+9CBD:4048414879488BFE1148F948A978A900F9FEA820ABFEF87000A81924E6224020
+9CBE:100010FE1E00227C24447E44AA7C2A003EFE2A922A923EFE00920E9270FE2082
+9CBF:202021247CA8442089FE7D02540054F87C00540055FE7C2000401C88E1FC4084
+9CC0:100010FC1E84228424FC7E84AA842AFC3E002BFE2A203EA000BC0EA07160223E
+9CC1:200020F87C88448888F87C88548854F87C0055FC55547D5401541D54E3FE4000
+9CC2:200021FC7D24452489FC7D24552455FC7C0057FE55207D2201141D48E1844102
+9CC3:200021FC7D24452489FC7D24552455FC7C20541054547D4201421D4AE2384000
+9CC4:200021DC7D54455489DC7C0055FC54007DFE548054FC7C0400041C04E0284010
+9CC5:400840C87B088908112AF92AABACA948F908AB88AD54F91401141924E1244142
+9CC6:204020407CFE448089FC7E8454FC54847CFC5440547C7CC401281C10E0684186
+9CC7:202020407DFC450489FC7D0455FC54007FFE542054207DFC00201C20E3FE4000
+9CC8:204020807DFC450489FC7D0455FC54207C3257B454A87D2801241E24E4A24040
+9CC9:209020907C9E46A289D47C88549454A47DFE568454A47C9400941C84E0944088
+9CCA:202020107DFE450289027DFE550055007DFE55AA56AA7CFE00AA1CAAE0AA4086
+9CCB:200021FC7CA4448888507C2054D857267C2055FC55247D2401FC1C22E3FE4002
+9CCC:08207E20087EFEC410281E1022284FC690403FF051101FF011101FF00000FFFE
+9CCD:204020447DF844508BFE7C4054F855827E7E540055FC7D0401FC1D04E1FC4104
+9CCE:200020FC7C8444FC88847CFC540054007DDC544455547CCC01541C44E1544088
+9CCF:200021FC7D54455489547DFC542054A87CA4552454207CA800A41D24E0204020
+9CD0:2004201E7DE0440289227C9454FE55107C1055FE54107C9200921C92E0FE4002
+9CD1:202020107DFE448488487DFE550256247C1055FE54407C7C00441C84E0944108
+9CD2:208820507C0045FE88507DFC545457FE7C5455FC54507CD801541E52E0504050
+9CD3:414841487BE8894811DEF88AABEAAAAAFAAAABEAA88AFBEA00921892E0AA40C4
+9CD4:200023FE7C5045FC89547D5455FC54007DFC540057FE7C2000A81D24E2A24040
+9CD5:200021FC7C2047FE8A227DAC542055AC7C0055FC54047DFC00041C04E1FC4004
+9CD6:49202A3E7F4849485DA86B1049284FC610403FF051101FF011101FF00000FFFE
+9CD7:400041F8790889F81108F9F8A800ABFCFA94ABFCA800F9F800901860E1984606
+9CD8:20203F20407EBEA82A28FF104A287FC610403FF051101FF011101FF00000FFFE
+9CD9:201021FE7D10457C89147DFE5514557C7D10557C55547D7C01541E7CE254444C
+9CDA:400443E47A248A2413EEFA04AAE4AA04FA0CABF4AA44FA6405541D44EA5440C8
+9CDB:200021DE7C42455288CA7D52544254207CFC548454847CFC00841C84E0FC4084
+9CDC:400043FE7A008B1412A4FBF6AA4AAA42FB50AB54ABF4FA44024A1A8AE4924920
+9CDD:408840507BFE882011FCF820ABFEA924F8A8ABFEA800F9FC01041904E1FC4104
+9CDE:4020412478A88BFE10A8F924AA22A904F904A9DEAA44FD54009E1904E2044404
+9CDF:208820507DFE445089FC7D54559C55047DFC550455FC7C0801FE1C88E0484018
+9CE0:208823FE7CA8449089FE7F2055FC55207DFC552055FE7D0003FC1C88E070438E
+9CE1:401440127BFE8A1012F0FA14AAF4AAB8FAEAAA16AC42F82402A21A8AE4784000
+9CE2:205021FC7D5445FC89547DFC540055FC7C0055FC55047DFC00881C50E3FE4000
+9CE3:201021FE7C0045FE89027D7A554A55FE7C0054FC54847CFC00841CFCE00041FE
+9CE4:210821087DEE469488427C1055FE55027CF8548854F87C8000FC1C84E0FC4084
+9CE5:020004001FF010101FF010101FF010001FFC10001FFC09242494249440280010
+9CE6:100020007F3E41027F0441047F0840087F9040107FA000A2AAA2AAA2811E0600
+9CE7:08003FE020203FE020203FE020003FF820003FF8524889281FD810422042C03E
+9CE8:101020107F1041107F7E41127F1240127F9240127F920092AAA2AAA2814A0684
+9CE9:2040208021FC2104F9FC290429FC290029FE29002BFE2C024AAA42AA8202000C
+9CEA:2040208021FC210421FC290425FC250025FE210021FE200222AA22AA2202200C
+9CEB:00003FFE2100220027F0241027F0241027F0240027FC240027FC40044AA48AAC
+9CEC:04001FF010101FF010101FF010001FFC10001FFC00040F94088808821082607E
+9CED:00400080F9FC290429FC290429FC290029FE290029FE28024AAA4AAA9A02000C
+9CEE:0040008001FCFD0405FC050449FC290011FE110029FE240246AA82AA0202000C
+9CEF:00007FF844085FC850485FC850485FC850085FE850085FEA402AAAAAAAA60042
+9CF0:0040008081FC410421FC210411FC110029FE290025FE240242AA42AA8202000C
+9CF1:00407C8011FC110411FC110411FCFF0011FE110011FE100212AA12AA1202100C
+9CF2:004000803DFC250425FC25043DFC250021FE210021FE200222AA42AA4202800C
+9CF3:3FF820082FE822082FE828282FE828282FE828082FF828082FFA401A55568032
+9CF4:0040008079FC490449FC490449FC490049FE490049FE78024AAA02AA0202000C
+9CF5:0040F88049FC490449FC490449FCF90049FE490049FE48024AAA4AAA4602420C
+9CF6:04200210013EFFC002221FFA10161FF010101FF010001FFC10001FFC2A44452C
+9CF7:1040108011FCFF0411FC1104FDFC050005FE490029FE10022AAA46AA8202000C
+9CF8:01007FFC40047FFC42005FF050105FF050105FF050005FFC50005FFCAA44452C
+9CF9:1040108029FC290445FCA50411FC110001FEFD0005FE08020AAA12AA1202000C
+9CFA:1040108011FC7D0411FC110411FCFD0011FE110011FE280226AA42AA8202000C
+9CFB:0020284024FC248442FC428480FC7C8024FE248024FE240244AA44AA9502080C
+9CFC:0040208011FC0104FDFC090409FC490029FE110011FE28022AAA4AAA8202000C
+9CFD:00407C8029FC290429FC290429FCFF0029FE290029FE28022AAA2AAA4A02880C
+9CFE:0040FE8011FC11047DFC550455FC550055FE550055FE5C0212AA12AA1202100C
+9CFF:004000807DFC110411FC11047DFC110011FE110011FE1C02E2AA42AA0202000C
+9D00:0040FC8011FC110421FC310469FC6500A5FE210021FE200222AA22AA2202200C
+9D01:00400C8071FC110411FC1104FDFC110011FE110029FE280242AA42AA8202000C
+9D02:2040208021FCF90429FC290429FC2900FDFE210021FE200232AA4AAA4A02800C
+9D03:101020107F1041107F7C41147F1440147F94407E7F900090AAA8AAA881440682
+9D04:00200040FEFCA884A8FCA884A8FCA880AAFEAA80A6FEC00282AAFAAA0202000C
+9D05:0040788049FC490469FC590449FCFD0049FE490049FE48024AAA4AAA4A02980C
+9D06:1040108011FC7D0455FC910411FC290029FE290029FE2C024AAA42AA8202000C
+9D07:4040488051FC610445FC45043DFC110011FE1100FDFE100212AA12AA1202100C
+9D08:00007FFE444045FC490449FC590469FC490049FE490049FE48024AAA8AAA0804
+9D09:0040FC8009FC490449FC490489FCFF0019FE190029FE28024AAA8AAA2A02100C
+9D0A:00400080FDFC110411FC110451FC5D0051FE510051FE50025EAAF2AA0202000C
+9D0B:2020104000FCFE8420FC20843CFC248024FE248024FE240244AA54AA8902000C
+9D0C:00003FF801007FFC04401830E20E1FF010101FF010101FFC10001FFC0004492C
+9D0D:020001007FFC082007C01830E20E1FF010101FF010101FFC10001FFC0004492C
+9D0E:0040FC8081FC8904C9FCA90491FC9100A9FEA900C9FE800282AAFEAA0202000C
+9D0F:105020547C5244927C90459E7DF042907E9040907E900290AA8AAA8A82860C82
+9D10:10007E7812482678C2001FF010101FF010101FF010001FFC10001FFC2A44452C
+9D11:08007E7812480C3032CEDFF010101FF010101FF010001FFC10001FFC2A44452C
+9D12:1040108029FC250443FC910409FC0100FDFE050009FE500222AA12AA1202000C
+9D13:2020104014FC048424FC2484AAFCAA80A8FE308032FE220222AA5EAA8102000C
+9D14:08401C80E1FC010421FC1104FDFC050009FE090011FE200242AAA2AA1E02000C
+9D15:101020087F08417E7F4241427F2040247FA840307FA000A2AAA2AAA2811E0600
+9D16:00207E4042FC42847EFC488448FC48807EFE488048FE48024AAA4AAA6702420C
+9D17:2040108011FCFD0401FC090489FC890049FE490051FE50021EAAE2AA4202000C
+9D18:1040108021FC4904FDFC050429FC290029FEFD0029FE28022AAA4AAA4A02880C
+9D19:2040208021FC7D0451FC910411FC1100FDFE110011FE280226AA42AA8202000C
+9D1A:100020007DFE44047C0444F47C9440947E9440947EF40294AA04AA0482140C08
+9D1B:20F83E88449AA882127E3FF0D0101FF010101FF010001FFC10001FFC2A44452C
+9D1C:08442F7828422F3EF2001FF010101FF010101FF010001FFC10001FFC2A44452C
+9D1D:2020204020FC7E8442FC82847AFC4A804AFE4A807AFE4A0202AA02AA1502080C
+9D1E:0040788049FC490449FC790401FCFD0021FE410079FE08020AAA0AAA5202200C
+9D1F:04400E80F1FC910491FC9104FDFC910091FE910091FE88028AAAC6AA9202080C
+9D20:004000807DFC450445FC7D0445FC45007DFE010001FE1C02E2AA42AA0202000C
+9D21:0040788049FC490449FC790449FC490079FE490049FE48024EAAF2AA0202000C
+9D22:04082410243C44245FBC94A4E4BC24A044BE44A094BEF48218AA08AA1282210C
+9D23:1020104010FC1084FEFC108410FC10807CFE448044FE440244AA7CAA4502000C
+9D24:102020207F3C41447F6841A87F1040287FC440827FA00090AA88AAA081100608
+9D25:102020107C1044FE7C8245047C0040287E2840287E280228AA44AA4482440C82
+9D26:01001FF01110FFFE02801C70E20E1FF010101FF010101FFC10001FFC0004492C
+9D27:2020104010FCFE8482FC848400FC788048FE488048FE4A024EAA4AAA8202000C
+9D28:00407C8055FC550455FC7D0455FC550055FE7D0055FE100212AA12AA1202100C
+9D29:1040108051FC51047DFC910411FC1100FDFE110011FE280226AA42AA8202000C
+9D2A:2020104010FCFE8482FC828428FC288024FE248044FE400242AA82AA0202000C
+9D2B:00400080F9FCA904A9FCA904A9FCF900A9FEA900A9FEA802FAAA8AAA0202000C
+9D2C:2208111000207FFE42029FF410101FF010101FF010001FFC10001FFC2A44452C
+9D2D:1040208079FC490449FC490479FC410041FE790049FE48024AAA7AAA4A02000C
+9D2E:10201040FEFC288444FC82847CFC0080FEFE208040FE7C0204AA04AA2902100C
+9D2F:0020FE4010FC108420FCFE84AAFCAA80AAFEAA80AAFEAA02AAAAA2AA8B02840C
+9D30:08201C4070FC108410FCFC8410FC10807CFE448044FE440244AA7CAA4502000C
+9D31:28402880FDFC290429FC010405FC450029FE290011FE10022AAA2AAA4A02800C
+9D32:80208840B0FCC08484FC84847CFC0080F8FE888088FEF8028AAA8AAAFA02880C
+9D33:102008407EFC428494FC108410FCFE8024FE248048FE280212AA2AAA4602800C
+9D34:10101020277C4044907C10442FFC6240A27E2240227E220222AA22AA2B02240C
+9D35:2820284028FC2884AAFC6C8428FC28806CFEAA8028FE28022AAA4CAA4902800C
+9D36:1020104010FCFE8410FC10847CFC008000FE7C8044FE440244AA7CAA4502000C
+9D37:7F0408441E44224454440844320CDFF010101FF010101FFC10001FFC0004492C
+9D38:1040508051FC7D0491FC110411FCFF0031FE390055FE540292AA12AA1202100C
+9D39:4440248029FCFF0411FC11047DFC110011FEFF0011FE100222AA22AA4202800C
+9D3A:10201040FEFC10847CFC14847CFC50807EFE128012FE160228AA24AA4502800C
+9D3B:0020804040FC1F8484FC448444FC048024FE4480C4FE47025CAA48AA4102000C
+9D3C:101020107F3C41247F4441287F1040287FC640007FBC00A4AAA4AAA4813C0624
+9D3D:1000FE7C22441C7CE2001FF010101FF010101FF010001FFC10001FFC2A44452C
+9D3E:1040108021FC4904FDFC450411FC51007DFE910011FEFC0212AA12AA1202100C
+9D3F:2040208051FC490485FC0104F9FC010001FEF90089FE88028AAAFAAA8A02000C
+9D40:081813E0304057FC904013F802001FF010101FF010101FFC10001FFC0004492C
+9D41:2040108001FCFD0401FC290445FC830009FE490029FE10022AAA4AAA8202000C
+9D42:12081210123C22242FBC6224A63C27202ABE2AA0323E2202222A222A2202220C
+9D43:1040208079FC490469FC590449FCF90049FE490069FE58024AAA4AAA4A02980C
+9D44:0040FE8021FC290445FCFD0415FC110011FE7D0011FE10021EAAE2AA4202000C
+9D45:2040208039FC490449FCA90411FC290045FE850079FE48024AAA4AAA7A02480C
+9D46:11001200279C44808780148027BE6408A7C8240827C820482548254828682190
+9D47:202020403EFC288448FC08843CFC288028FE2880FEFE08020AAA0AAA0A02080C
+9D48:0040FC8049FC490479FC490449FC790049FE49004DFE7802CAAA0AAA0A02080C
+9D49:02000100FFFE04401450244842041FF010101FF010101FFC10001FFC0004492C
+9D4A:10201040FEFC108410FC548454FC5480BAFE118010FE280228AA44AA8502000C
+9D4B:00107E20027C02447E7C4044417C41403F7E1040087E2902A2AAA2AA1F02000C
+9D4C:101020107C2844287C4444BA7C1040107EFE40107E580254AA92AB1282500C20
+9D4D:20201040FEFC828400FC7C8400FC0080FEFE288028FE280228AA4AAA4D02800C
+9D4E:04201E40E0FC228492FC548448FC1080FCFE248044FE280210AA28AA4502800C
+9D4F:1020144010FCFE8410FC7C8454FC54807CFE548054FE7C0254AA54AA55024C0C
+9D50:002000407CFC108410FC548454FC5480BAFE108010FE1C02E2AA42AA0202000C
+9D51:0040F88089FC8904F9FC0104F9FC890089FEF90089FE8802FAAA8AAA8A02980C
+9D52:0040488045FC950411FC290445FC810079FE490049FE48024AAA7AAA4A02000C
+9D53:10201040FEFC108410FCFE8482FC048078FE088010FE1E02F0AA10AA5102200C
+9D54:101020107C2044447CFE44287C4440A27E3C40447E4402A8AA10AA2882440C82
+9D55:1020104020FC4484FEFC288444FCA2803CFE448044FEA80212AA2AAA4602800C
+9D56:004000807DFC450445FC7D0445FC45007DFE410051FE480256AA62AA4202000C
+9D57:42102420187C2444527C1044FF7C2040287E7E40AA7E2A022AAA2EAA0902080C
+9D58:00107E20127C1244FF7C1244127C7E40207E20407E7E6202A2AA22AA3F02220C
+9D59:0040788049FC490479FC490449FC790049FE490079FE000252AA4AAA8A02000C
+9D5A:0C20704010FCFE8410FC388454FC928000FE388028FE28022AAA4CAA4902800C
+9D5B:0020FE4054FC5484A8FC548454FC0080FEFE108010FE10021EAAF2AA4202000C
+9D5C:4420244028FCFC8414FC1484FCFC908090FEFE8032FE320252AA96AA1102100C
+9D5D:04103620E57C2544247CFFC4247C2540257E3640E67E24022AAA32AAA1C2408C
+9D5E:02403C500848FFFE08480E50782408541A8C1FF010101FF010101FFC5244892C
+9D5F:280011FC682014F82420D5FC0A001FF010101FF010101FFC10001FFC0004492C
+9D60:1020504050FC7C8490FC1084FEFC008000FE7C8044FE440244AA7CAA4502000C
+9D61:04100620757C0544047CFF44047C1440147E5C40547E5402552A5D2AE342410C
+9D62:1040208079FC490479FC490479FC490049FEF90019FE28024AAA8AAA2A02100C
+9D63:10201040FEFC108410FC7C8454FC548054FE7C8010FE380256AA92AA1202100C
+9D64:202020403CFC448448FCBE842AFC2A803EFE2A802AFE3E022AAA2AAA2B02440C
+9D65:49042A247F240824FFA4080C02001FF010101FF010101FFC10001FFC0004492C
+9D66:100020FC7C0444047C7C44047C0440FE7E1040927E540238AA54AA9282500C20
+9D67:4440288001FC7D0429FC290429FC2900FDFE290029FE28022AAA4AAA4A02880C
+9D68:1020104028FC248442FCB88410FC1080FEFE108010FE7C0244AA44AA7D02440C
+9D69:0008779054BC54A454BC75A4543C57A054BE74A056BE5502552A56AA5482B40C
+9D6A:10201040FEFC288454FC92847CFC54807CFE54807CFE100216AA1AAA1202000C
+9D6B:102010401EFC10847CFC44847CFC44807CFE548010FEFE0212AA12AA1202100C
+9D6C:00107720557C5544557C7744557C5540557E7740557E5502552AB52A8942130C
+9D6D:1020104028FC248442FCBC8410FC1080FEFE108094FE580252AA1EAAF202400C
+9D6E:102010403EFC228444FC808410FC668042FE428066FE420242AA7EAA4302000C
+9D6F:104020807DFC550455FC7D0455FC55007DFE210051FEFC0212AA12AA1202100C
+9D70:00107F20497C49445D7C49447F7C41405D7E5540557E5D02412A412A4542820C
+9D71:102010407CFC108410FCFE8400FC448092FE10807CFE100212AA1EAAE202400C
+9D72:2820284028FCFC8428FC2884FEFC00807CFE448044FE7C0244AA44AA7D02440C
+9D73:102008407EFC428442FC7E8440FC5E8052FE5E8052FE5E0252AA52AA9302160C
+9D74:402040407EFC828422FCAA8472FC2280FEFE228072FEAA0222AA22AA0B02040C
+9D75:202020403CFC448488FC7E8452FC52807EFE10802CFE2A0228AA4AAA4B02860C
+9D76:0020FE4028FC288428FCEE8482FC828082FEEE8028FE28022EAAF0AA4102000C
+9D77:10100820FF7C8144407C7744557C5540557EB540977E1402242A252A4642840C
+9D78:10201040FEFC108428FC4484FEFC048074FE548054FE740254AA04AA1502080C
+9D79:0640387C08947E241C442A944A081FF010101FF010101FFC10001FFC0004492C
+9D7A:20201040FEFC288428FC4E8452FCDA8056FE628054FE4C0248AA54AA6502400C
+9D7B:105020487C8044FE7D9046907CFC40907E9040FC7E900290AA90AAFE82800C80
+9D7C:20201040FEFC828428FC448482FC00807CFE108010FE10021EAAF2AA4202000C
+9D7D:0010F720117C5544227C5544897C1040007EF740117E5502222A552A8942100C
+9D7E:0020FC4084FC8484FCFC848484FCFC8000FE8880EEFE880288AAAAAACD02880C
+9D7F:100020FE7C8244FE7C8244FE7C0040147EE440447E4403FEAA44AA4482840D04
+9D80:102420247F7E41247F24413C7F2440247FBC40247FA400FEAA80AAA481220642
+9D81:20201040FEFC008400FC7C8444FC44807CFE108054FE520292AA10AA5102200C
+9D82:2020CE4082FC8284EEFC828482FCFE8028FE288028FE28024AAA4CAA8902000C
+9D83:100020207CCE44827C8244EE7C8240827EFE40287E280228AA48AA4A828A0D06
+9D84:10201040FEFC10847CFC1084FEFC00807CFE44807CFE44027CAA44AA5502480C
+9D85:0040548055FCA904A9FC550455FC0100F9FEA900A9FEF802AAAAAAAAFA02880C
+9D86:1040108011FC7D0411FC550455FC5500BBFE110039FE540292AA12AA1202100C
+9D87:10201040FEFC10847CFC54847CFC54807CFE108038FE540292AA12AA1202100C
+9D88:10201040FEFC10847CFC1484FEFC14807CFE1080FCFE240244AA28AA3102C80C
+9D89:20201040FEFC00847CFC44847CFC00807CFE048008FE1E02F2AA12AA5202200C
+9D8A:101008207F7C48445E7C4A444A7C7F404A7E4A405E7E4802542A922A2242400C
+9D8B:00207E4042FC42847EFC488448FC7E8048FE48805CFE540254AA54AA5D02940C
+9D8C:00107F20417C41447F7C4444557C5540557E5F40447E5502552A572A9D42000C
+9D8D:00207C4044FC7C8444FC44847CFC20807EFEAA802AFE4A0292AA22AA4B02040C
+9D8E:20201040FEFC828400FC7C8400FC0080FEFE108010FE540252AA92AA5102200C
+9D8F:0E20F04022FC928444FC108410FC7C8010FE1080FCFE10022AAA26AA4202800C
+9D90:08208C404AFC48843EFC0884C8FC5C806AFE488048FE48024AAA62AA9A02000C
+9D91:2AA42CA84920145022885FF410101FF010101FF010001FFC10001FFC2A44452C
+9D92:22082210FA3C222427BCFAA4AABCAAA0FABE22A072BEAA822AAA24AA2482298C
+9D93:50405080F9FC510451FC0104F9FCA900A9FEA900F9FEA802AAAAAAAAFA02880C
+9D94:00107E20247C18447F7C29444A7CA840107E0840FF7E1C022A2A492A8842080C
+9D95:2040108079FC010449FC3104FDFC010079FE490049FE78024AAA4AAA7A02480C
+9D96:0610381008527E5408901C282A2848440A821FF010101FF010101FFC5244892C
+9D97:00407CFC44847CFC44847CFC0080FEFE108010FE5E0252AA52AAB0049FFE0000
+9D98:20102720257C7544257C2744257C7540557E5740557E5502752A492A0942130C
+9D99:20201040FEFC008444FC2884FEFC828010FE7C8054FE540254AA5CAA1102100C
+9D9A:0020EE40AAFCAA84EEFC008478FC0080FCFE208040FE78020AAA0AAA2A02100C
+9D9B:48204A406CFC48844AFC6A8456FC20807EFE428042FE7E0242AA42AA7F02420C
+9D9C:4420FE4044FC00847CFC048428FC1080FEFE328054FE900212AA12AA5202200C
+9D9D:0020FE4000FC7C8444FC44847CFC0080FEFE928092FEFE0292AA92AAFF02820C
+9D9E:021007203C7C2444247C3F44247C2F40297E2F40297E2F02292A492A4F42890C
+9D9F:20201040FEFC828428FC448492FC148012FEFE8010FE10022AAA26AA4202800C
+9DA0:0010FFA0807CBF44A17CBF44A17CBF40887EFFC0927EB2028CAA92AAA102FF8C
+9DA1:00207C4044FC7C8444FC7C8420FC7E8092FE52806AFE42027AAA02AA1502080C
+9DA2:0E20F04022FC928454FC48847CFC1080FEFE20803EFE420254AA88AA1502620C
+9DA3:101008207E7C4244427C7E44427C40407F7E5540557E7F02D52A552A5542430C
+9DA4:0020FE4092FC1084FEFC10847CFC54807CFE54807CFE1002FEAA12AA1202100C
+9DA5:00107F20497C49447F7C40445F7C5140517E5F40517E5F02512A512A9F42110C
+9DA6:107CFF44107C7E44427C7E44028C1FF010101FF010101FFC10001FFC0004492C
+9DA7:221022207F7C22442A7C08443E7C2A402A7E2A40FF7E0802142A122A2242400C
+9DA8:20203C4044FC788408FCFE8420FC52809CFE2C804AFE98022AAA4AAAAA02100C
+9DA9:00207E20247E18A4FF2829104A2898C602001FF010101FF010101FFC5244892C
+9DAA:00207E4042FC7E8442FC7E8442FC7E8014FE1280FEFE10022AAA26AA4202800C
+9DAB:10201040FEFC1084FEFC9284D6FCBA8092FEFE8010FE380254AA92AA1102100C
+9DAC:08100C20127C294444FCBF44217C3F40217E3F40207E3F02512A512A9F42110C
+9DAD:20204410F9FE1040247CFE840084551482081FF010101FF010101FFC5244892C
+9DAE:20201040FEFC00847CFC44847CFC0080FEFE8280BAFEAA02BAAA82AA8B02840C
+9DAF:08202AA44D28145022887FFE42029FF410101FF010101FFC10001FFC0004492C
+9DB0:00207C4044FC44847CFC0084FEFC8280FEFE8280FEFE8202FEAA28AA4502840C
+9DB1:01007FFE44429FF404403FF80440FFFE0A201FF02828CFE608200FF800081558
+9DB2:2820444092FC208448FCFC8404FC0080EEFE2280AAFE6602AAAA22AAAB02440C
+9DB3:2100427EF3889288F2BE92AAF3AA822AFA2A83AAFAAA0AAEAA88AB888A883008
+9DB4:081008207F7C5544127C3F44647CA4403F7E2440247E3F0224AA24AA3F02200C
+9DB5:201020207F7C9144557C7D44217C4A40A47E7F40917E55027D2A212A4A42840C
+9DB6:101008207F7C48445E7C4A447F7C4A405E7E48405E7E520252AA52AA5F02920C
+9DB7:20201040FEFC828410FC7C8410FC7C8010FEFE8010FE7C0244AA44AA7D02440C
+9DB8:0020EE4022FC2284EEFC888488FCEE8022FEAA8066FE6602AAAA22AAAB02440C
+9DB9:2020DE408AFCCA84AAFCD284A6FC0080FEFE928092FEFE0292AA92AAFF02820C
+9DBA:1020924054FCAA8444FC82847CFC448044FE7C8044FE44027CAA44AA45024C0C
+9DBB:00207C4044FC748454FCFE8482FC7C8044FE7C8044FE7C0244AA44AA5502480C
+9DBC:22101420007C7FC4147C7F44157CFFC0157E7F40147E3602552A94AA1442140C
+9DBD:282024407EFCC8847EFC48847EFC48807EFE508010FEFE0212AA12AA1202100C
+9DBE:108010FE1140FEFC10847CFC44847CFC44807CFE1080FEFE100212AA12AA1004
+9DBF:082004407FFC12483CF0082014503EF802001FF010101FF010101FFC5244892C
+9DC0:21081110123CFFE4213C2124423C52A094BEE720213E4202422A94AAF782108C
+9DC1:22101420007C7F44007C1444227C4140007E7F40557E5502552A57AAFC42000C
+9DC2:0E20F04022FC928444FC20843CFC508010FEFE8010FE540254AA5CAA6502000C
+9DC3:00107E20427C7E44427C7E44087CFF40817E1040FF7E220264AA18AA2502C20C
+9DC4:0E20F04022FC928444FC208444FCF88010FE2480FEFE1002FEAA28AA4502820C
+9DC5:0020FE4028FC2884FEFCAA84AAFCFE8010FE1080FEFE380254AA92AA1102100C
+9DC6:4610782040FC3FC4007C5F44517C5F40517E5F40517E5F02402A7FAA2242410C
+9DC7:1000FE7810487C480048FE8692007CFC44447C4444287E2840107F280144AB82
+9DC8:2004401EF3F0921EF21092FEF2928298FAF2828EFA800AB8AAA8ACAA8D4A3A86
+9DC9:03107C20477C44445F7C5544567C5C40557E5340507E5702552A552AA9C2000C
+9DCA:0020FE4000FC7C8444FC7C8400FCFE8082FEAA8092FEFE0292AA92AA9302860C
+9DCB:22082210FFBC22242A3C1424223C5D2088BE08207F3E08022A2A492AA882100C
+9DCC:100020FE7C9044FC7C9044FC7C9040907EFE40027EAA02AAAAAAAA8282140C08
+9DCD:104020807DFC45047DFC45047DFC45007DFE1100FDFE10023AAA56AA9202100C
+9DCE:102020407CFC44847CFC44847CFC1080FEFE288054FE92027CAA10AA1102100C
+9DCF:10201040FEFC10847CFC44847CFC44807CFE44807CFE4402FEAA28AA4502820C
+9DD0:00107E20427C7E44427C7E44007C7F40407E5E40407E7F02552A522A5942910C
+9DD1:44104420777CAA44117C2044107CFF40007E0440447E240228AA0EAAF102400C
+9DD2:10201040FEFC10847CFC54847CFC54807CFE1280FEFE0802FEAA48AA2902180C
+9DD3:101008207F7C4044527C52447F7C5240527E5E40407E5502552A552A8042000C
+9DD4:08207F20087E7E4408A4FF2810101E2822445FF290101FF010101FFC5244892C
+9DD5:009079FE4B204DFC492049FC792001FE02001FF010101FF010101FFC5244892C
+9DD6:7F7848485F4C64805F784A4851307F4C02001FF010101FF010101FFC5244892C
+9DD7:0020FE4080FC8084BCFCA484A4FCBC8080FEEE80AAFEAA02EEAA80AAFF02000C
+9DD8:0820FFA0083E7F4449A87F102A28494682001FF010101FF010101FFC5244892C
+9DD9:08207E2008F8FF2814287F6A082AFF560A821FF010101FF010101FFC5244892C
+9DDA:0020EE4022FCAA8466FCAA8410FC288044FE928020FEC80232AAC4AA1902E00C
+9DDB:02083FD0223C2FA422BC3FE422BC2FA0223E2FA02ABE2F824AAA4FAA8A82098C
+9DDC:08107F20497CFFC4497C7F44087C7F40497E7F40107EFF02212A722A0C42F30C
+9DDD:0020FE4092FCFE8492FCFE8454FC5480FEFE548054FEFE0210AAFEAA1102100C
+9DDE:10201040FEFC1084BAFC5484BAFC1080BAFE5480BAFE10022AAA26AA4202800C
+9DDF:208010FCFD4020F83D2024FC445055888A041FF010101FF010101FFC5244892C
+9DE0:2040208079FC490491FC7D0455FC55007DFE550055FE7C0202AAAAAAAA02000C
+9DE1:200820107FBCD524553C5524FFBC5520553E5520FFBE00026A2A552A9502000C
+9DE2:3FFE289025103FDE22222A882F88229425222FF0241027F0241047FC40048AAC
+9DE3:0020FE4028FCFE84AAFCFE8400FC7C8044FE7C8044FE7C0210AAFEAA1102100C
+9DE4:0020EE40AAFCAA84EEFC00847CFC54807CFE54807CFE1002FEAA12AA1202100C
+9DE5:1020244878F014287EFC002054A8556402001FF010101FF010101FFC5244892C
+9DE6:282024407EFCC88448FC7E8448FC48807EFE488048FE7E0240AAAAAAAB02000C
+9DE7:1020FE4010FC7C8400FCFE8482FC7C8000FE7C8044FE7C0244AA28AA0F02F00C
+9DE8:44204440FEFC448400FCFE8454FC5480FEFE548054FEFE0210AAFEAA1102100C
+9DE9:49202A3E7F4849485DA86B104928414602001FF010101FF010101FFC5244892C
+9DEA:00003EF822883EF822883EF822887FFE42029FF410101FF010101FFC5244892C
+9DEB:08087F10093CFFA4093C7F24083CAAA0EBBE88A0FFBE8882EBAAAAAAAA82088C
+9DEC:282028407CFC288428FCFE8410FC7C8054FE7C8054FE7C0200AA28AA4502820C
+9DED:0E20F04092FC5484FEFC388454FC82807CFE548054FE7C0254AA54AA7D02440C
+9DEE:06107820107CFFC4227C5D4494FC1C40007E7F40417E5D02552A5D2A4142430C
+9DEF:081008207F7C0844557C2244417CBEC0227E3E40227E3E0208AA2AAA4902180C
+9DF0:0440FFFE044017D2F01C17D03452D7CE02001FF010101FF010101FFC5244892C
+9DF1:2020FE4082FCFE8482FCFE8482FCFE8010FE928054FE920210AAFEAA1102100C
+9DF2:08287F2400FE3E2022503E504952988E02001FF010101FF010101FFC5244892C
+9DF3:EE20AA40EEFCAA84EEFC8284BAFCAA80BAFEAA80BAFEAA02AAAADAAA8302860C
+9DF4:0020EE40AAFCEE84AAFCEE8492FC9280FEFE9280BAFED60292AA92AA8B02840C
+9DF5:00107F20417C41447F7C48445D7C4A407F7E48405E7E72025EAA52AA5F02920C
+9DF6:0020FE40AAFCAA84FEFC00847CFC44807CFE44807CFE44027CAA00AA2902440C
+9DF7:22101420FF7C14447F7C5544637C5D40417E7F40047EFF0244AA24AA25020C0C
+9DF8:7E101420087CFF44297C4A44A87C10407F7E5540637E5D02552A5D2A4142430C
+9DF9:00803FFE225024FC2D9036FC249024FC210027F0241027F0441047FC80040AAC
+9DFA:00403EFC23483E3009CE2E7828487E7802001FF010101FF010101FFC5244892C
+9DFB:21084088F3C89010F3DE9264F3D48014FBD48054F89408E8AB88A8948A943122
+9DFC:0020EE40AAFCEE84AAFCEE8482FCBA80AAFEBA80AAFEBA02AAAA82AA8B02840C
+9DFD:0A803138228838382288393822887FFE42029FF410101FF010101FFC5244892C
+9DFE:1020FE4044FC2884FEFC00847CFC44807CFE44807CFE10020AAAA9AAA5021C0C
+9DFF:3E1022FE3E4420287EFEA2103EFC221002001FF010101FF010101FFC5244892C
+9E00:00107F20557C55447F7C20447F7C91407D7E5540557E7D02112A7D2A0542020C
+9E01:0100FFFE20003FF800003FF820083FF80200779C54947794549C77D65056B562
+9E02:0310BC2044FC1144847C49445E7C0440297E5F40C47E5F0244AA4AAA5102208C
+9E03:21044088F3FE9020F1FC9020F3FE8054F9928090FBFE0890A8D4AB8A889631A2
+9E04:10207E204A7E7EC41028FF1020283EC642001FF010101FF010101FFC5244892C
+9E05:00107F20557C7F44087C7F44087CFFC0227E14407F7E0802FFAA08AA0902080C
+9E06:08100F20087C7F44497C7C44497C5F40527E5E40407E5E02482A7F2A5242A10C
+9E07:1020FE4000FCFE8482FCBA84AAFCFE8000FE7C8044FE7C0244AA7CAA0102FE0C
+9E08:14105520367C1444FF7C2244147C7F40087E7F40087EFF021CAA2AAA4902080C
+9E09:11FC1104FDFC310459FC948011FE125202AA1FF410101FF010101FFC5244892C
+9E0A:02087910493C4BA4483C7AA4413C47E0793E6920ABBEA902292A392A2902010C
+9E0B:0810FF20917C4A44A57C1C44007C7F40557EFFC0007E7F0208AA08AA2902100C
+9E0C:104421FE7C5444487CFE45907CFE40907EFE40907EFE0280ABFEAA4482380DC6
+9E0D:0008FF90493C88A4FFFC88A4DDBCAAA0DDBE88A0DDBEAA82DDAA88AA8A82810C
+9E0E:3EF822883EF822883EF822883EF8145022881FF010101FF010101FFC5244892C
+9E0F:2410FF20247CFF44817C7E44007CFF40107E28C0D57E2E02D5AA24AAD502080C
+9E10:0010EE20227CAA44667CAA44007C24407F7EC8407E7E48027EAA48AA7F02400C
+9E11:510C278A500897BE30085788949457A422021FF010101FF010101FFC5244892C
+9E12:1A3823883A38238838B82288FFFE10102208DFF610101FF010101FFC5244892C
+9E13:00087F10493C7F24493C7F24413C0020FFBEAAA0AABEFF82AAAAAAAAFF82888C
+9E14:21FC4104F9FC8904F9FC8888F9FC8088FDFE8088FD2406AA547054A885241860
+9E15:08080F90083C7FA448BC7E2448BC5FA0553E5F20553E5F02402ABFAA2A827FCC
+9E16:7F080810FFBC88A46B3C08246B3C24207FBEC8207F3E48027F2A482A7F82400C
+9E17:08403E7C1440FF7822083E782242263E02001FF010101FF010101FFC5244892C
+9E18:FE201040FEFC928454FC108454FC00802EFEFA802EFE7A02AEAA2AAA2F022A0C
+9E19:1020284044FCBA8400FCFE84AAFCFE8000FEFE80AAFEAA02FEAAAAAAAB02860C
+9E1A:00107720557C7744557C7744557C7740227E5540107EFF0222AA64AA1D02E30C
+9E1B:4420FE4044FC0084EEFCAA84EEFC24807EFEC8807EFE48027EAA48AA7F02400C
+9E1C:77105520777C5544777C5544777C22407FFEA4403F7E24023F2A242A3FC2200C
+9E1D:77100020777C5544777C5544087C7F40547E7F40557E7F02552A5E2A55429B0C
+9E1E:21084FD2F03C23884812FBBE0280ABAA02001FF010101FF010101FFC5244892C
+9E1F:010002001FF01010121011101150102010001FFC000400047FE4000400280010
+9E20:2020204020FC2084FCA4248424942488248024FE2502260245FA400280140008
+9E21:0020004000FCFC8404A4048448942888108010FE2802240245FA800200140008
+9E22:04200410023EFFC00080004202321FEE1420126010001FF800087F8800280010
+9E23:0020004079FC4904494449244924490C490049FE7802480203FA000200140008
+9E24:002000403EFC228422A422843E942288208020FE2002200221FA400240148008
+9E25:00207E4040FC448464A4548448944888548054FE6402400241FA7E0200140008
+9E26:00207E4004FC248424A4248444947F880C8014FE1402240245FA840214140808
+9E27:08100820147C124421644054BE44224C2240227E2A022402217A21021F0A0004
+9E28:4020484050FC608444A444843C941088108010FEFE02100211FA100210141008
+9E29:08100820087C7F44496408540844144C1440147E14022502267A4402800A0004
+9E2A:1020104010FC1084FEA41084109410887C8044FE4402440245FA7C0244140008
+9E2B:10101020107CFF44206428544844484C7E40087E2C022A02497A8902280A1004
+9E2C:102010401EFC108410A47C844494448844807CFE4402400241FA400280140008
+9E2D:0020FE4092FC928492A4FE84929492889280FEFE9202100211FA100210141008
+9E2E:00207E4042FC428442A47E840094FF88208040FE7E02020203FA020214140808
+9E2F:01001FF011101110FFFE02801C70E20E04001FE0122011601FFC00047FD40008
+9E30:1020104028FC248442A4918408940888FE8002FE4402280211FA080208140008
+9E31:011007A07C7C44444464445444447F4C4440447E4402420242FA5282698A4484
+9E32:2020204040FC7E8482A402847A944A884A804AFE7A024A0203FA020214140808
+9E33:10003EF84288A2AA1492187EE2001FE01420126010001FF800087F8800280010
+9E34:2208111000207FFE410282041FF010101210115010201FFC000400047FD40008
+9E35:102020107C1044FE548245045440484840507E6002400242FA420242143E0800
+9E36:1020244878F010207EFC0000FFFE020004001FE0122011601FFC00047FD40008
+9E37:10801080FBF010901990F0941154520C24041FE0122011601FFC00047FD40008
+9E38:00107F20087C084410647F545544554C5540557E55025502557A5102450A4204
+9E39:04200E4038FC088408A4FF84089408883E8022FE2202220223FA3E0222140008
+9E3A:12081210123E22222FB2622AA62227262AA02ABE32022202227A2202220A2204
+9E3B:10101020277C4044906410542FC4624CA240227E22022202227A22022A0A2404
+9E3C:082010403EFC228432A42A842A94FE88228032FE2A022A0223FA42024A148408
+9E3D:1020104028FC248442A480847C94008800807CFE4402440245FA7C0244140008
+9E3E:02000100FFFE04401450244842041FE01420126010001FF800087F8800280010
+9E3F:00108020407C1F44846444544444044C2440447EC40247025C7A4802400A0004
+9E40:001000207F7C084408642A542A442A4C5D40497E880208020F7AF002400A0004
+9E41:10201040FEFC108410A4FE8482940488788008FE10021E02F1FA100250142008
+9E42:0008FF90003E0022F7B294AA94A294A6D6A0B5BE9482948294FA9482948AB584
+9E43:00103E20227C22443E6400547F44414C41407F7E410241027F7A4102450A4204
+9E44:08104820487C7F44886408540844FF4C0040007E7E024202427A42027E0A4204
+9E45:04103620E57C25442464FFD42444254C2540367EE60224022AFA3282A18A4084
+9E46:2820244042FC928410A42884449482887C8044FE4402440245FA7C0244140008
+9E47:40102F20017C4944496449547F44494C5D406B7E49024902497A4102450A4204
+9E48:4420244028FCFC8414A41484FC9490889080FEFE3202320253FA960210141008
+9E49:04100620757C05440464FF540444144C14405C7E54025402557A5D02E30A4104
+9E4A:24102420247CFF4424642454FFC4004C7E40427E42027E02427A42027E0A4204
+9E4B:22082210FFBE22222232002A7F2249264920493E7F024902497A49027F0A4104
+9E4C:08080810FFBE14222232492A88A27F2649207F3E49027F02087A0A020C0A0804
+9E4D:00107E20427C42447E64425442447E4C0040447E77024402447A5502660A4404
+9E4E:101020207F7C494449647F544944514C7F40247E4402FF82047A0402040A0404
+9E4F:00107720557C5544556477545544554C5540777E55025502557AB502890A1304
+9E50:102010403EFC228444A4808410946688428042FE6602420243FA7E0242140008
+9E51:10100820FF7C00447E6442547E44004C7E40047E08020F02F87A0802280A1004
+9E52:101008207F7C48445E644A544A447F4C4A404A7E5E024802547A9202220A4004
+9E53:10100820FF7C8144406477545544554C5540B57E97021402247A2502460A8404
+9E54:081008207F7C0944FFE409547F44084C4940497E5D026B02497A4902890A0904
+9E55:2008279024BEFCA224B227AA24A274A654A057BE5482548274FA08820A8A1104
+9E56:00107E20427C7E4442647E5420447F4C8940497E550241027D7A01020A0A0404
+9E57:00107720557C5544776400547F44004CFFC0207E3F020102017A01020A0A0404
+9E58:00207C4044FC748454A4FE9482947C8C44807CFE44027C0245FA440254144808
+9E59:0620382008A47EA819202C504A881FE41420126010001FF800087F8800280010
+9E5A:21081110123EFFE22132212A422252A694A0E73E21024202427A9482F78A1084
+9E5B:00107F20497C49447F6440545F44514C51405F7E51025F02517A51029F0A1104
+9E5C:00207E20247E18A4FF2829104A289AC604001FE0122011601FFC00047FD40008
+9E5D:0020FE4000FC7C8444A47C840094FE888280AAFE9202FE0293FA920292148608
+9E5E:0E20F04022FC928444A420843C9450881080FEFE1002540255FA5C0264140008
+9E5F:2820444092FC208448A4FC8404940088EE8022FEAA026602ABFA2202AA144408
+9E60:2020DE408AFCCA84AAA4D284A6940088FE8092FE9202FE0293FA9202FE148208
+9E61:1020924054FCAA8444A482847C94448844807CFE440244027DFA440244144C08
+9E62:22101420007C7F44006414542244414C00407F7E55025502557A5782FC0A0004
+9E63:22101420007C7FC414647F541544FFCC15407F7E14023602557A9482140A1404
+9E64:081008207F7C554412643F546444A44C3F40247E24023F02247A24023F0A2004
+9E65:7F7848485F4C64805F784A4851307F4C04001FE0122011601FFC00047FD40008
+9E66:00107720557C5544556455542244554C0840FF7E12022202347A0C02320AC104
+9E67:101008207F7C4044526452547F44524C52405E7E40025502557A5502800A0004
+9E68:00107720117C5544336455540C44334CC4C0187E62020C82717A0602180AE004
+9E69:081008207F7C0844556422544144BECC22403E7E22023E02087A2A02490A1804
+9E6A:282024407EFCC88448A47E84489448887E8048FE48027E0241FAAA02AA140008
+9E6B:08287F2400FE3E2022503E5049529A8E04001FE0122011601FFC00047FD40008
+9E6C:7E101420087CFF4429644A54A844104C7F40557E63025D02557A5D02410A4304
+9E6D:00403EFC23483E3009CE2E7828487E7804001FE0122011601FFC00047FD40008
+9E6E:0020FE40AAFCAA84FEA40084FE9400887C8044FE7C022A0265FAA20231142008
+9E6F:1020FE4000FCFE8482A4BA84AA94FE8800807CFE44027C0245FA7C020014FE08
+9E70:00803FFE225024FC2D9036FC249024FC210027F02490242047FC40049FD40008
+9E71:104421FE7C54444864FE559044FE4C9040FE7C9004FE0480F5FE0444143809C6
+9E72:2410FF20247CFF4481647E540044FF4C104028FED5022E02D57A2482D40A0804
+9E73:2208FF90223EF7A294B2F7AA282224267FA0483EFF0248027F7A48027F8A4004
+9E74:7F1008207F7C49442A6408542A44004C2740FD7E27027502AF7A2502270A2504
+9E75:0100010001FE010001003FF8200829282448228829282288244829283FF82008
+9E76:102010201E2010501050FE889344C622AA20D6F8AA08C6089210FE1082200020
+9E77:102010201E5010501088FF249212C610ABFCD604AA08C6889250FE2082100010
+9E78:101010281E441082107CFE109210C6FEAA92D692AAFEC6109228FE2882440082
+9E79:100C100A1E0810FE1088FE8892FAC68AAA8AD6ECAAACC6AC92EAFE8A82960122
+9E7A:104410241E2810FE1010FE7C9210C6FEAA20D620AA7CC6509290FF1082FE0000
+9E7B:108810501E0011FE1050FEFC9254C7FEAA54D6FCAA50C6D89354FE5282500050
+9E7C:101010101E2810441082FE7C9200C6EEAAAAD6AAAAEEC6449244FEAA82AA0112
+9E7D:0100F9FEA220A43EF8208BFE8AAAFA52A326A252A2AAFBFE00003FF82448FFFE
+9E7E:208420443C4821FE2020FCFC842095FED440A480D4FE95108610FC1085FE0000
+9E7F:010000803FFE222022203FFC222422243FFC284028442F58486048448B440C3C
+9E80:010000803FFE22203FFC22243FFC28402F7828422F3E200028784F82480287FE
+9E81:010002000FF0706003801D00E0803FFC22403FF822483FF828442F7848428F3E
+9E82:010000803FFE22203FFC22243FFC28402F7828422F3E200023F042104412980E
+9E83:010000803FFE22203FFC22243FFC28442F4828742B442C3C40004A4889241124
+9E84:044008203018DFF60410095010A03FFC22403FF822483FF828442F7848428F3E
+9E85:00803FFE22203FFC22243FFC242227BE24002FF830082FC828684FD0480287FE
+9E86:00803FFE22203FFC22243FFC242227BE200027F8240827F8240847F84408BFFE
+9E87:00803FFE22203FFC22243FFC242027BC2422279E200823F020404FFE41508E4E
+9E88:00803FFE22203FFC22243FFC242027BC2422279E20802FFE204047FC40409FFE
+9E89:00007C7C10101010FEFE111010903FFC22403FF822483FF828442F7848428F3E
+9E8A:111009207FFC05401930610C00803FFC22403FF822483FF828442F7848428F3E
+9E8B:00803FFE22203FFC22243FFC242027BC2422279E224821502FFE415042488C46
+9E8C:00803FFE22203FFC22243FFC200027F0241027F020002FF820805FFC42209C1C
+9E8D:00803FFE22203FFC22243FFC242227BE20403FFE220024082FFC44944892908E
+9E8E:00803FFE22203FFC22243FFC242227BE20002FFC28002BFC28004FFE4A28939E
+9E8F:00803FFE22203FFC22243FFC20002FFC21043FFE21042FFC220047FC4A0493FC
+9E90:00803FFE22203FFC22243FFC242227BE20402FFE211020E02F1E43F8420883F8
+9E91:00803FFE22203FFC22243FFC242227BE21002E7828082F7828084FF842229C1E
+9E92:08447F4455FE54447F44557C55447F44547C54445E4455FE54005C2856448082
+9E93:082008207EFC1C702AA8C92608A03FFC22403FF822483FF828442F7848428F3E
+9E94:00803FFE22203FFC22243FFC222027B02D2832242DFE300027F84408440887F8
+9E95:00803FFE22203FFC22243FFC20002FFC28242BC428842FF42AA44C944FFC8804
+9E96:00803FFE22203FFC22243FFC20803FFE20002FF828082FF82080488852848100
+9E97:3F7E00003E7C224432642B5400803FFC22403FF822483FF828442F7848428F3E
+9E98:00803FFE22203FFC22243FFC20102FE020803FFC24902FF8341647F0441087F0
+9E99:00803FFE22203FFC22243FFC200020282FFE28202BA428282BAC4A944BAC9044
+9E9A:00803FFE22203FFC22243FFC20002F7C29042F7C28002F7C28444F28483088CE
+9E9B:00803FFE22203FFC22243FFC20002F7E21242F3C28242F3C2126417C45048204
+9E9C:00803FFE22203FFC22243FFC20002FFE211027FC251427FC20404FFE4150864C
+9E9D:00803FFE22203FFC22243FFC242027BC24222F9E29082F7E29485F2845089B18
+9E9E:00803FFE22203FFC22243FFC204027FC21102FFE220823F822084FFE40408040
+9E9F:08107F54543854FE7F10553855567F90548454EE5EA454B4555E5C4456848104
+9EA0:00803FFE22203FFC22243FFC28882FF828883FFE20002FF828884FF84888BFFE
+9EA1:00803FFE22203FFC22243FFC20402FFE20A02F5E255425542B5A440847F88808
+9EA2:00803FFE22203FFC22243FFC200027FC20402FFE2842235820004EEE4AAA8EEE
+9EA3:13DEFE52ABDEA800FFFEAA00AAC8FE4EABEAAAB2BEEAAAAAAAEABAB4ADE4002A
+9EA4:00803FFE22203FFC22243FFC4810FF7E54487F7E554A7F7E52645B7652A49B36
+9EA5:01007FFC092009201550238805401930E20E07E008203440028003000C807040
+9EA6:010001007FFC010001003FF801000100FFFE08001FF02820444003801C70E00E
+9EA7:08200820FF402A7E2A805D00887C1C042A0850101E20224054420842143E6000
+9EA8:08100810FF102A102A545D5288521C902A1050141E04220854080810142060C0
+9EA9:10201020FE20542055FCBA201020382055FEA2203C504450A88810882904C202
+9EAA:100011FEFE20542054A0BABC10A438A454A4A2FC3C044404A80410042828C010
+9EAB:080008FEFF102A102A505D5E88501C502A50507E1E0222025402080214146008
+9EAC:10101010FE1054FE5492BA94109038FC54A4A2A43CA844A8A89011282944C282
+9EAD:10401040FEFC54845504BAF41094389454F4A2843C944488A8821082287EC000
+9EAE:08100810FF102A7E2A105D1088101CFE2A1050101E202228544408FE14426000
+9EAF:10501050FE50545055FCBB54115439545554A3FC3D544554A954115429FCC104
+9EB0:10201020FE48548455FEBA121090389054FEA3103C1045FEA81010102810C010
+9EB1:10141012FEFE54105410BAFE1092389254FEA2923C9244FEA89210922892C086
+9EB2:080008FCFF842A842AFC5D8488841CFC2A8450841EFC2250545008521492610E
+9EB3:08100810FF102AFE2A105D5488541C542ABA50101E3822545492081014106010
+9EB4:10801080FEFE55025622BAAA1072382255FEA2223C7244AAA9221022280AC004
+9EB5:080008FEFF102A202AFE5DAA88AA1CBA2AAA50AA1EBA22AA54AA08AA14FE6082
+9EB6:10201010FEFE54285492BAAA108238FE5410A2FE3CA244AAA8BA1082288AC084
+9EB7:10A811FCFEAA57FE56AABBFE12AA3BFE5400A3FE3C0045FCA90411FC2888C3FE
+9EB8:10201020FE2010207DFC1020FE2020203DFE44204850A8501088288841048202
+9EB9:10801080FEFE11027E2210AAFE7220223DFE44224872A8AA11222822400A8004
+9EBA:100011FEFE2010407DFC1154FF5421743D5445544974A9541154295441FC8104
+9EBB:010000803FFE2210221022103FBE2210261027382AB42A545292421082100210
+9EBC:010000803FFE221022102FBC231826B42A522100221027E040C043088FFC0004
+9EBD:010000803FFE221022102FBC231826B42A522100224024804910420887FC0004
+9EBE:010000803FFE22102F7C26382B54329220782F8020F82F8020FC5F824082807E
+9EBF:00803FFE24103F7C26382D543412200027F8240827F820002FFC480448048FFC
+9EC0:010000803FFE22102F7C26382B5432923F80297C2F2429242F2849905F288146
+9EC1:00803FFE24103F7C26382D5434122FE020803FFC24902FF8341647F0441087F0
+9EC2:00803FFE24103F7C26382D5434922FF822A02FFC22202FF828884FF844108808
+9EC3:08207FFC08200FE00000FFFE01001FF0111011101FF0111011101FF008201010
+9EC4:044004403FF804400440FFFE01001FF011101FF011101FF0000008201010600C
+9EC5:221022107F1022282228FFC408447FA249107F10497C7F040008220821104110
+9EC6:221022107F10221022FEFF9208927F1049287F2849287F280048224A218A4106
+9EC7:221022107F102210221EFF9008107F10497C7F4449447F4400442244217C4144
+9EC8:222022107F0022FE2210FF9008107F10497C7F1049107F100010221021FE4100
+9EC9:110808907FFE44429FF404407FFC01001FF011101FF011101FF0044008201010
+9ECA:282028207CF828202820FE2011FC7C00542054207CF8542054207C2029FC4400
+9ECB:1088108895FC5488588813FEFC2029FC292429FC292429FC288849044A0287FE
+9ECC:0A803138228839382288FFFE84423FF80440FFFE11101FF011101FF008201010
+9ECD:00F83F0001007FFC092011102288C44409203118CB2605C01930610805000200
+9ECE:0640387C08947E241C442A94490802800C603118C92605400920111025080200
+9ECF:0C2070201020FE20383E54209020282055FC9104550439045504930451FC2104
+9ED0:0C40702011FCFE5039245554910429FC542091FC554439545574930451142108
+9ED1:00003FF82108292825483FF8010001003FF801000100FFFE0000488844448444
+9ED2:00003FF821083FF821083FF801003FF801000100FFFE00002488224442448004
+9ED3:00287F2449246B205D2E49F07F2008207F2008200FA0F0100012550A4A868002
+9ED4:0020FE209220D650BA509288FF441222FE2010F81E08E0080210AA10A8208020
+9ED5:0010FE109210D610BAFE9292FE921010FE2810281E28E0280248AA4AA88A8106
+9ED6:0000FEFE9210D610BA909290FE9010FEFE1010101E28E0280248AA4AA88A8106
+9ED7:0020FE209220D7FCBA2092A8FEA810A8FEA810A81EF8E0220222AA22A81E8000
+9ED8:0020FE289224D624BA2093FEFE201020FE2010501E50E0500288AA88A9048202
+9ED9:00107F1449127F10497E7F1008287F2808440F44F08200002488224442448004
+9EDA:0044FE449244D644BAFE9244FE441044FE44107C1E44E0440244AA44A87C8044
+9EDB:08901088307ED7C01022101A00063FF8292825483FF801007FFC0100FFFE4444
+9EDC:0010FE109292D692BA929292FEFE1010FE1010921E92E0920292AA92A8FE8002
+9EDD:0010FE509250D690BAFC9354FFD41094FE9411141F54E1D40254AA24A8348048
+9EDE:0010FE109210D610BA1E9210FE101010FEFE10821E82E0820282AA82A8FE8082
+9EDF:0020FE20927CD684BB489230FE201048FE90103E1E42E0A40218AA10A82080C0
+9EE0:0020FE209220D7FEBA209220FEFC1000FE0010FC1E84E0840284AA84A8FC8084
+9EE1:3FFC20903FFC21402630380C2FF82AA829C82FF820802FF840805FFC8A481124
+9EE2:0010FE109220D644BAFE9228FE4410A2FE3C10441E44E0A80210AA28A8448082
+9EE3:0040FE40927ED680BB7C9244FE641054FEFE10441EA4E09402FEAA04A8288010
+9EE4:0020FE2093FED650BAA89326FEF810A8FEA810F81EA8E0A802F8AAAAA822801E
+9EE5:0020FE1092FED600BA00927CFE441044FE7C10101E54E0520292AA10A8508020
+9EE6:0020FE1092FED682BA40924EFE6A10AAFEAA10AA1F6CE028024AAA4AA88A8106
+9EE7:0640387C08947E241C442A9448083FF8292825483FF801007FFC0100FFFE4444
+9EE8:111009207FFE40029FF410103FF8292825483FF801003FF80100FFFE24484224
+9EE9:0010FE1092FCD610BA1093FEFE021054FE3010901E50E1FE0228AA44A8828102
+9EEA:0020FE289244D6FEBA2093FEFE881114FE2210481E10E02202C4AA18A8608180
+9EEB:0000FEFE9228D628BAFE92AAFEAA10AAFEFE10101E10E0FE0210AA10A9FE8000
+9EEC:000CFE0A9208D6FEBA889288FEFA108AFE8A10EC1EACE0AC02EAAA8AA8968122
+9EED:0020FE309248D684BB7A9200FEFC1084FE8410FC1E48E04803FEAA48A8888108
+9EEE:0048FE4893FCD648BA789248FE781048FE4811FE1E80E0A802C4AA80A8FE8000
+9EEF:0020FE1092FED600BA449228FEFE1000FE7C10441E44E07C0244AA44A87C8044
+9EF0:0010FE1092FED610BA7C9244FE7C1044FE7C10441E7CE04402FEAA28A8448082
+9EF1:012478A849FC48404BFE79084BFC4DAE497479FC482049FC48204BFE49549A2A
+9EF2:0010FE209244D6FEBA4492AAFEEE1010FE2810541EAAE0500224AA48A8108060
+9EF3:7F7848485E8664785F484A307F4C00003FF8292825483FF80100FFFE24484224
+9EF4:11101550255047D0903E17A420546FD4A9542DD42B542FC821082FD420142AA2
+9EF5:0040FE7C9284D7FEBAA292C8FEFE1080FEBE10801EBEE08002BEAAA2A8BE8122
+9EF6:3FFE28882F8A20082FBE28882F88289429A220002FFE29522FFE40405FFE8924
+9EF7:0010FEFE9210D67CBA0092FEFEAA10FEFE44107C1E44E07C0244AA7CA8288044
+9EF8:0040F87CA840ABFCFA44ABF0FA4422FCFAA822F83AA8E2F80A00A5FCA5540BFE
+9EF9:0440244814500440FFFE0100111009203FF82108254825282928210821282110
+9EFA:1408552836281428FF4449442A827F7C492449245D246B244944494449944B08
+9EFB:1428552436241420FF7E49202A207F3C493449545D546B544988498849144B22
+9EFC:14145512367E1410FF10497E2A527F52497E49525D526B7E4952495249524B46
+9EFD:00003FF8228822883EF802803EF8228822883EF8228822883EF8228A028201FE
+9EFE:1FF0101010101FF001003FF8210821083FF8210821083FF8210A0102010200FE
+9EFF:1FF00000FFFE0844303CDFF012901EF002803EF822883EF822883EFA028201FE
+9F00:01003FF80100FFFE10103FF852941EF002803EF822883EF822883EFA028201FE
+9F01:01003FF80100FFFE04201FF000001FF012903EF822883EF822883EF8028201FE
+9F02:00001FF010101FF01010FFFE00001FF012903EF822883EF822883EF8028201FE
+9F03:01003FF80100FFFE01003FF80100FFFE12903EF822883EF822883EF8028201FE
+9F04:09000FF011007FFC05401930E10E1FF012903EF822883EF822883EF8028201FE
+9F05:20003F7C4844FFC4147C224441001FF012903EF822883EF822883EF8028201FE
+9F06:0000FDFC8554015479DC485079DC4954795421DC1154FD5401DC51504852883E
+9F07:08207E20087EFEC410281E1022285FF692903EF822883EF822883EF8028201FE
+9F08:49202A3E7F4849485DA86B1049285FF612903EF822883EF822883EF8028201FE
+9F09:00003EF822883FF811101FF01110FFFE12903EF822883EF822883EF8028201FE
+9F0A:00107E7C42287EFE40107E7CA2103FF012903EF822883EF822883EF8028201FE
+9F0B:1FF00000FFFE0844303CDFF010101FF001003FF821083FF821083FFA010200FE
+9F0C:00001FF010101FF01010FFFE00001FF010103FF821083FF821083FFA010200FE
+9F0D:00003EF822883FF811101FF01110FFFE01003FF821083FF821083FFA010200FE
+9F0E:0FE008200FE048244FE448244FE440047C7C04400440FC7C2444244444448444
+9F0F:7FFE40028FE408200FE008204FE448244FE440047C7C0440FC7C244444448444
+9F10:7FF81008101E2FE2482A8FE408204FE448244FE440047C7C0440FC7C24444444
+9F11:010001FC01001FF010101FF010105FF450145FF440047C7C0440FC7C24444444
+9F12:00807FFC048019806FE008200FE048244FE448244FE47C7C0440FC7C2444C444
+9F13:08100810FF1008FE08107E1000FC7E44424442447E28422824100F28F0444082
+9F14:08100810FF10081E08107E1000FC7E44424442447E28422824100F28F0444082
+9F15:0810FF7E08107E7C42047E4824381E44E8001FF0282007C01830E18E0C400300
+9F16:01007FFC0920FFFE08200810FF1008FE7E1000FC7E4442487E2824101E28E0C6
+9F17:249014A024940884707C0810FF1008FE7E1000FC7E4442487E2824101E28E0C6
+9F18:0810FF7E08107E7C42447E282418FEE624483C7820083FF820083C7824484448
+9F19:0810FF7E08107F7C41447F2822101F28FFF611101FF012101FF004407FFC0040
+9F1A:0810FF7E08107E7C42047E4824381E44EFF008000FF00800FFFE111014E0181C
+9F1B:0810FF7E08107E7C42447E3824447EA222385424082037FEC0001FF010101FF0
+9F1C:0810FF7E08107E7C42447E3824447FF2092007C0F93E1FF011101FF001087FFC
+9F1D:24A414A487BC440417FC24044FBC90A40810FF7E08107E7C42447E282418FEE6
+9F1E:0810FF7E08107E7C42447E282418FEE611107FFE48228FE401001FF001007FFC
+9F1F:0810FF7E08107E7C42447E3824D47EA204442BA810102FE8C8260FE004407FFC
+9F20:0400387820083C78200820083FF800002948252821082948252A210A29463182
+9F21:22081108111000003FF8210821083FF8210821083FF82108210A410A41068002
+9F22:2008CE288228EE2882448244FE82017C92249224DA249224DA4492449394D908
+9F23:2010CE148212EE12821082FEFE10001092109228DA289228DA2892449344D982
+9F24:2020CE108210EEFE82448244FE44004492449228DA289210DA1092289344D982
+9F25:2028CE248224EE2082FE8220FE20003C92349254DA549254DA8892889314D922
+9F26:2000CEFC8224EE2482248224FE5400489280927CDA449244DA449244937CD944
+9F27:2020CE108210EEFE82828284FE40004492489250DA609242DA429242933ED900
+9F28:2020CE20823EEE4282C48328FE10002892449382DA309208DA0492609310D908
+9F29:2040CE408240EEFC82848304FEF4009492949294DA9492F4DA9492049328D910
+9F2A:2010CE108250EE50827C8250FE9000109210927CDA109210DA10921093FED900
+9F2B:2000CE0082FEEE1082108220FE20007C924492C4DB449244DA449244937CD944
+9F2C:2010CE108210EE1082FE8292FE920092929292FEDA929292DA92929293FED982
+9F2D:2010CE108210EE7C82108210FEFE0008920892FEDA089248DA2892089328D910
+9F2E:2000CC0685D8EC4884488488FC9E01C8A848F948A948F89EA880A940FA3EA400
+9F2F:2000CEFE8210EE10827C8224FE2400FE92009200DA7C9244DA449244937CD944
+9F30:2000CE7C8244EE44827C8244FE44007C92449244DA7C9200DA2892249342D982
+9F31:2010CE1082FEEE10827C8210FEFE0000927C9244DA7C9244DA7C92449354D948
+9F32:2000CEFE8292EE1082FE8210FE7C0054927C9254DA7C9210DAFE92109310D910
+9F33:2000CEFE8282EEFE828282FEFE8200FE92149212DAFE9210DA2892289344D982
+9F34:2000CDFE8500ED7E8542857EFD42017EA910F9FEA924F964A918A924FB42A5FE
+9F35:2020CE1082FEEE8282448292FE14001292FE9210DA289228DA2892449344D982
+9F36:2008CC3C85D0ED1C8510857CFD540158A970F954A94CF940AA78A8A8FA2AA446
+9F37:200ECEF08222EE9282448220FE4400F892109224DAFE9210DAFE92289344D982
+9F38:2088CC508400EDFE845085FCFC5403FEA854F9FCA850F8D8A954AA52FA50A450
+9F39:2000CE7C8244EE7C8244827CFE1000FE92829210DAFE9224DA6892109328D944
+9F3A:2000CDFC8524EDFC852485FCFD040000ABFEFAAAAAAAFBFEAAAAAAAAFBFEA622
+9F3B:02001FF010101FF010101FF000003FF821083FF821083FF80000FFFE08201020
+9F3C:10043E0422443E4422443E4400447F4449447F4C49747F440004FF8422044204
+9F3D:10203E2022203E2022F83E2800287F2849287F2849287F2A002AFFCA22464280
+9F3E:10003E00227C3E1022103E1000107F1049FE7F1049107F100010FF9022104210
+9F3F:10003E00227C3E2822283E2800287F2849287F2849287F2A002AFFAA22464280
+9F40:10003E7C22203E2022203E3800287F2849587F4849487F48005AFFEA224A4206
+9F41:10403E4022403EFC22843F0400747F5449547F5449747F540004FF8422284210
+9F42:20207C2044FC7C2445FE7C2400FCFE209324FEA89270FEA80124FE2244A08440
+9F43:20007CFC44847CFC44847CFC0040FEFE9312FE9292AAFE8200FAFE0244148408
+9F44:10103E1022FE3E3822543E9200007F7C49447F7C49447F7C0044FF8022FE4200
+9F45:20207C4044FC7C8444FC7C8400FCFE8492FCFE289224FEFE0020FE5044888506
+9F46:20927D2444927C00447C7C44007CFE0092FEFE929292FEFE0080FE824482847E
+9F47:20207C3C44207CFE44A27CB800E4FE9C9280FEBC92A4FEBC00A4FEBC44A4857E
+9F48:20287CFE44AA7CFE44AA7CFE0000FEFE9280FEBE9280FEFE00A8FEAA44A48532
+9F49:2020FBFE8924F9FC8820FBFE0356F9DCA888FBFEA888FBFE0094F98852A490C2
+9F4A:020001007FFC0440028C7D702550255045488D6610101FF010101FF010102010
+9F4B:0100FFFE02847D78255025484D6420083FF820083FF821082548252849288108
+9F4C:0100FFFE02847D78255025484D6420083FF820083FF820082528294842888C48
+9F4D:0100FFFE02847D78255025484D6420083FF820083FF840083FF824482448FFFE
+9F4E:0100FFFE02847D78255025484D6420083FF820082FE828282FE828284FE88448
+9F4F:0100FFFE02887D7025484D66A0083FF822882EE822882EE822884EE842888FE8
+9F50:020001007FFC0820044003800C603018C8260820082008200820102010202020
+9F51:020001007FFC0820044003801C70E28E2EE822882EE822882EE822885FF88008
+9F52:0100110011F811001100FFFE044024482AA831183FF824482AA831183FF80008
+9F53:082028202F202820FF20142055206B2041207F20552055226B224F22711E0100
+9F54:082028202F202820FF22142455286B3041207F6055A055226B224F22711E0100
+9F55:082028202F20287EFF401480553C6B0441087F10552055406B424F42713E0100
+9F56:100050FC5C085048FE482848AA88D6FE8218FE28AA28AA48D6889F08E2280210
+9F57:0800280C2F702840FF401440557E6B4841487F48554855486B484F4871480188
+9F58:081028102F102828FF28144455AA6B2841287F28552855286B284F4871480188
+9F59:104050405CFC5084FF042AF4AA94D69482F4FE84AA94AA88D6829E82E27E0200
+9F5A:082028202F20283EFF50145055906B1E41107F105510551E6B104F1071100110
+9F5B:102850A85CA850A8FEA829FEAAA8D6A882A8FEA8AAB8AA80D6809E80E2FE0200
+9F5C:100850285C285028FEA828AAAABCD6A882A8FEA8AAA8AAA8D6AA9EBAE2EA0386
+9F5D:102050205C205040FE482884ABFED6828200FEFCAA84AA84D6849E84E2FC0284
+9F5E:080028002F7C2844FF44144455446B44417C7F44550055286B244F4471420182
+9F5F:0800287C2F442844FF44147C55446B4441447F7C554455446B444F4471FE0100
+9F60:080028FC2F242824FF24142455546B4841807F7C554455446B444F44717C0144
+9F61:081028102F102828FF281454558A6B08417C7F04550855286B104F1071080108
+9F62:081028102E1028282828FF54008A49086B7C49047F085D286B104F1079080008
+9F63:082028202F20287CFF44148455746B5441547F54557455546B044F0471280110
+9F64:111009207FFC0400FFFE111029E8C9067FFC04402AA83FF824482AA83FF80008
+9F65:102050205CFC50A4FEA428FCAAA4D6A482FCFE20AA24AA18D6129E6AE3860202
+9F66:0800087C2F442844FF7C144455446B7C41507F52555455486B5441667F420000
+9F67:08007F7C08243E2408447F5409E809007FFC04402AA83FF824482AA83FF80008
+9F68:080028202F4C2844FF44144455446B6C41447F44554455446B444F7C71440100
+9F69:102050105C1050FEFE002844AA82D7008244FE44AA28AA28D6109E28E2440282
+9F6A:0800287C2F442844FF441444557C6B1041107F50555E55506B504F70719E0100
+9F6B:100050FE5C925092FE9228FEAA92D6B282BAFED6AA92AA92D6929E82E2FE0282
+9F6C:080028FC2F102810FF7C142455246BFE41007F00557C55446B444F44717C0144
+9F6D:100050325CCC5088FE8828E8AAAED6AA82AAFEEAAA8AAA8AD68A9E8AE3120222
+9F6E:102050205DFC5020FE502888ABFED60882E8FEA8AAA8AAE8D6A89E08E2280210
+9F6F:100050205CCE5082FE8228EEAA82D68282FEFE28AA28AA28D6489E4AE28A0306
+9F70:104850485C4851FEFE482848ABFED60082FCFE84AA84AAFCD6849E84E2FC0284
+9F71:100051F05CAE50AAFEEA28AAAAAAD6EA82AAFEAAAAB4ABE4D6249E2AE22A0230
+9F72:100E51F05C1050FEFE922892AAFED61082FEFE92AA9AAA96D6FE9E82E28A0284
+9F73:100050FE5C925010FEFE2810AA7CD654827CFE54AA7CAA10D6FE9E10E2100210
+9F74:102050105CFE5044FE2828FEAA88D69082A4FE88AA90AAA2D6849E88E3100260
+9F75:1000507C5C545054FE7C2854AA54D67C8210FEFEAA92AA96D6BE9E82E28A0284
+9F76:100050EE5CAA50AAFEEE2800AA7CD60082FEFE20AA40AA7CD6049E04E2280210
+9F77:100050FE5C825082FEFE2880AABED6908294FEBEAA8AAA88D6BE9E88E308027E
+9F78:104450285C0050FEFE002828AA44D6828200FEFEAAAAAAAAD6AA9EAAE3FE0200
+9F79:082004407FFC0100FFFE04001FF8E0801FFC010009F009007FFC24482AA83FF8
+9F7A:104050405CFE5122FEAA28FAAA42D6948348FEFEAB22AAAAD6FA9E42E2940308
+9F7B:101050105CFE5010FE7C2844AA7CD644827CFE44AA7CAA44D6FE9E28E2440282
+9F7C:108850885DFE5088FEDC29AAAA88D60083FEFE22AAA0AABCD6A09F60E23E0200
+9F7D:104450445DEE5044FEEE2954AA44D600827CFE00AAFEAA10D6549E92E2500220
+9F7E:0F1408127F10497E7E1049287F2852449EFA04807FFE04402AA431143FFC0004
+9F7F:0100010011F8110011001100FFFE00002108210822882448282820083FF80008
+9F80:0820082028202F2228222824FF2800304920496055A0632241224722791E0100
+9F81:0820082028202F7E28402880FF3C0004490849105520634041424742793E0100
+9F82:0800080C28702F4028402840FF7E004849484948554863484148474879480188
+9F83:0800087C28442F442844287CFF4400444944497C554463444144474479FE0100
+9F84:1020102050505E5050885124FE12001093FC9204AA08C68882508E20F2100210
+9F85:10401040507C5E84508451F4FE940094929492F4AA84C6A882928E82F27E0200
+9F86:080008FE28222F2228222822FF4A00444980497E5542634241424742797E0142
+9F87:1008102850285E2850A850AAFEBC00A892A892A8AAA8C6A882AA8EBAF2EA0386
+9F88:100010FC50845E8450FC5084FE8400FC92A292A4AA98C69082888EA4F2C20280
+9F89:100011FC50205E2050FC5044FE4401FE92009200AAFCC68482848E84F2FC0284
+9F8A:0800087C28442F4428442844FF7C001049104950555E635041504770799E0100
+9F8B:100E11F050105EFE50925092FEFE001092FE9292AA9AC69682FE8E82F28A0284
+9F8C:100010FE50825E8250FE5080FEFE009092A492FEAA92C69082FC8E90F31002FE
+9F8D:104008407E7E2440187EFF02007E7E40427E7E40427E7E40427E42404A42443E
+9F8E:00003FFE22202FBC2520223C3F84203C2FA028BC2FA028BC2FA048BC48A2899E
+9F8F:08407F7C1440FF7C22043E7C22403E782242263E08200820FFFE082010202020
+9F90:00807FFE42205FBC4920463C7F84403C5FA050BC5FA050BC5FA050BC52A2911E
+9F91:08407F7C1440FF7C22043E7C22403E782242263E00003FF80200FFFE0860701C
+9F92:08407F7C1440FF7C22043E7C22403E7C2242263E00003FF80000FFFE11102308
+9F93:21102090FBDE2010425E79824BDEC8107BDE4A504BDE7A504BDE4A504A525ACE
+9F94:08407F7C1440FF7C22043E7C22403E782242263E04403FF80440FFFE08201010
+9F95:010006C01830EFEE00001FF010101FF008403E7C1440FF7822083E782242263E
+9F96:88884E4EF8F8A8A84E4EF2F20E0EE8E8AEAEA8A8EEEEA8A8EEEEA8A8AAAAA6A6
+9F97:3FF801007FFE492284143BB82AA83BB808403E7C1440FF7822083E782242263E
+9F98:08403E7C1440FF7822083E782242487EE8E8AEAEF8F80E0EE2E2AEAEE8E8AEAE
+9F99:0420041004100400FFFE048004880488049008A008C0108211822282447E8000
+9F9A:042004107FFC092009C4170420FCC44004403FF804400440FFFE082010102008
+9F9B:010006C01830EFEE00001FF010101FF004400420FFFE0910116021844F0480FC
+9F9C:04003FF820083EF802807A800AFCFE940AD47AA402A47AD40A94FEFC0A8279FE
+9F9D:1080E7FC240427BC20A0FEBE22A237B66AAA66AAA0B626A222BE27A022A2267E
+9F9E:49202A3E7F485DA86B10456E3FF820083EF802807AF80AD8FEA80AD87A8A01FE
+9F9F:040004000FE0102020407FF8A10821083FF8210821083FF821080102010200FE
+9FA0:010002800C603018DFF600003BB82AA83BB800003FF824883FF8248824A82010
+9FA1:08100810141022105D3E80A27F4455907F1000107F1055287F28552455444382
+9FA2:0808081C14F022105D1080907F7C55107F3800347F5455547F92551055104310
+9FA3:080008FC140422045D7C80847F0455FE7F1000927F5455387F54559255504320
+9FA4:0848084A146C22485D4A80EA7F5655207F7E00427F42557E7F425542557E4342
+9FA5:0800087E140822105D7C80C47F44557C7F44007C7F4455447F7C552855444382
+9FA6:112410A410A813FE16025AFA508890F8102011FC112429242524452C40208020
+9FA7:01FC010479FC490449FC484479F848504FFF48804BFC7D0449FC010401FC0104
+9FA8:00003FFC228024402FFC3440244027F8244027F82440244027FC24003FFC0000
+9FA9:04200420FFFF0420240CFF7024403C40087F7E484A487E480848FF8808880908
+9FAA:0820082008207E2008200820FF20085008500E502848288828845B02480087FF
+9FAB:10101010FF1010287E445282537C7E10521052107EFE1010FF10101010101010
+9FAC:100013FE1A02268A22527FFE924212227FFE128216825A8232FA1E02E20A0204
+9FAD:7DFE51227DFE512251227DFE504850487EFC0248564853FE8200024814840902
+9FAE:7FDE514A7CC6514A52527CFC50A450FC7EA402FC564852FE824803FE14840902
+9FAF:10281024282025FE4120B920112411247D28111815105910312A1E2AF2464482
+9FB0:0000000000000100010001000100010011F011001100110011002D00430080FC
+9FB1:00007FFC4004402448244424424441444084414442244414581440047FFC4004
+9FB2:1020101029FE251041FEBD10117C11547D7C1154157C591031FE1E10E2104410
+9FB3:101010107EFC10101010FEFE2448529410107E7C1010101010101E10E1FE0000
+9FB4:00000000000000007FFC00080010032000C00020001000000000000000000000
+9FB5:00F87F0001003FF80100FFFE0200040008003000C00000000000000000000000
+9FB6:010001007FFC01003FF80100FFFE000000000000000000000000000000000000
+9FB7:082008207FFC08200820FFFE0000000000000000000000000000000000000000
+9FB8:01001110092001007FFE40048008000000000000000000000000000000000000
+9FB9:1110092001003FFC010002007FFE082010102008C00600000000000000000000
+9FBA:10001000FE0010007C00440044007C0044007C0054001000FE00100010001000
+9FBB:208827E84812F3DC20084BD2F83E03C0AA52ABD2000000000000000000000000
+9FBC:0040207C204027FE240223FCFA642492210823FC250A21F83908C1F8010801F8
+9FBD:1080108010FC1108561055FC5524992411FC1124112429FC24004554412A822A
+9FBE:08400840087E7F424AA248AA48727EFE4222627254AA4D2288229402220A4004
+9FBF:08200820FFFE0820044008400BF81040304057FC904013F81040104017FE1000
+9FC0:0420FFFE04207F7850485E8665784A487F3000C8FFFE04403FF824482BA83FF8
+9FC1:209010900090FC9003FC78900090789000907BFE48004800489079084A040404
+9FC2:10201040FEFC10847CFC54847CFC548054FE7C8054FE1002FEAA10AE1152100C
+9FC3:00400040F7FC90409250F148914892D4F460904090A090A0F110920804040802
+9FC4:10000BF840882288098850C82108222825100100FFFE05400920111C61080100
+9FC5:21FC102003FEFA2209AC1020118C382054509188162611F8100810D010201010
+9FC6:404020400040FBFE0880108020F830886948A150215022202220245028882104
+9FC7:088008F81110122035FC5044904417FE1044104413FC10441040104011401080
+9FC8:080009FC11042104490409FC1124312051209110111011101208120814041802
+9FC9:08000BFE104020404840084013F8304850489088108810881088108817FE1000
+9FCA:08200820FFFE082008204000202090204120293C11201120E1202120212027FE
+9FCB:204017FE0040FBFC08001BF816083BF855109FFE100013F81208120813F81208
+9FCC:008040402FFE2000800043F84A080BF8120813F8E04022482244244229420080
+9FCD:00007FFE73866DBE718E7DBE73BE7FFE7FFE718E6FB66FB66FB6718E7FFE0000
+9FCE:00007FFE73866DBE718E7DBE73BE7FFE7FFE71866FBE6F8E6FBE71867FFE0000
+9FCF:00007FFE73866DBE718E7DBE73BE7FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+9FD0:00007FFE73866DBE718E7DBE73BE7FFE7FFE63CE6DB66DB66DB663CE7FFE0000
+9FD1:00007FFE73866DBE718E7DBE73BE7FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000
+9FD2:00007FFE73866DBE718E7DBE73BE7FFE7FFE63866DF66D866DBE63867FFE0000
+9FD3:00007FFE73866DBE718E7DBE73BE7FFE7FFE638E6DF66DC66DF6638E7FFE0000
+9FD4:00007FFE73866DBE718E7DBE73BE7FFE7FFE63B66DB66D866DF663F67FFE0000
+9FD5:00007FFE73866DBE718E7DBE73BE7FFE7FFE63866DBE6D866DF663867FFE0000
+9FD6:00007FFE73866DBE718E7DBE73BE7FFE7FFE63CE6DBE6D8E6DB663CE7FFE0000
+9FD7:00007FFE73866DBE718E7DBE73BE7FFE7FFE63866DF66DEE6DDE63DE7FFE0000
+9FD8:00007FFE73866DBE718E7DBE73BE7FFE7FFE63CE6DB66DCE6DB663CE7FFE0000
+9FD9:00007FFE73866DBE718E7DBE73BE7FFE7FFE63CE6DB66DC66DF663CE7FFE0000
+9FDA:00007FFE73866DBE718E7DBE73BE7FFE7FFE63866DB66D866DB663B67FFE0000
+9FDB:00007FFE73866DBE718E7DBE73BE7FFE7FFE638E6DB66D8E6DB6638E7FFE0000
+9FDC:00007FFE73866DBE718E7DBE73BE7FFE7FFE63C66DBE6DBE6DBE63C67FFE0000
+9FDD:00007FFE73866DBE718E7DBE73BE7FFE7FFE638E6DB66DB66DB6638E7FFE0000
+9FDE:00007FFE73866DBE718E7DBE73BE7FFE7FFE63866DBE6D8E6DBE63867FFE0000
+9FDF:00007FFE73866DBE718E7DBE73BE7FFE7FFE63866DBE6D8E6DBE63BE7FFE0000
+9FE0:00007FFE73866DBE718E7DBE73BE7FFE7FFE61CE6FB663B66FB661CE7FFE0000
+9FE1:00007FFE73866DBE718E7DBE73BE7FFE7FFE61EE6FCE63EE6FEE61C67FFE0000
+9FE2:00007FFE73866DBE718E7DBE73BE7FFE7FFE61866FF663866FBE61867FFE0000
+9FE3:00007FFE73866DBE718E7DBE73BE7FFE7FFE618E6FF663C66FF6618E7FFE0000
+9FE4:00007FFE73866DBE718E7DBE73BE7FFE7FFE61B66FB663866FF661F67FFE0000
+9FE5:00007FFE73866DBE718E7DBE73BE7FFE7FFE61866FBE63866FF661867FFE0000
+9FE6:00007FFE73866DBE718E7DBE73BE7FFE7FFE61CE6FBE638E6FB661CE7FFE0000
+9FE7:00007FFE73866DBE718E7DBE73BE7FFE7FFE61866FF663EE6FDE61DE7FFE0000
+9FE8:00007FFE73866DBE718E7DBE73BE7FFE7FFE61CE6FB663CE6FB661CE7FFE0000
+9FE9:00007FFE73866DBE718E7DBE73BE7FFE7FFE61CE6FB663C66FF661CE7FFE0000
+9FEA:00007FFE73866DBE718E7DBE73BE7FFE7FFE61866FB663866FB661B67FFE0000
+9FEB:00007FFE73866DBE718E7DBE73BE7FFE7FFE618E6FB6638E6FB6618E7FFE0000
+9FEC:00007FFE73866DBE718E7DBE73BE7FFE7FFE61C66FBE63BE6FBE61C67FFE0000
+9FED:00007FFE73866DBE718E7DBE73BE7FFE7FFE618E6FB663B66FB6618E7FFE0000
+9FEE:00007FFE73866DBE718E7DBE73BE7FFE7FFE61866FBE638E6FBE61867FFE0000
+9FEF:00007FFE73866DBE718E7DBE73BE7FFE7FFE61866FBE638E6FBE61BE7FFE0000
+9FF0:00007FFE73866DBE718E7DBE73BE7FFE7FFE61CE6FB663B66FB66FCE7FFE0000
+9FF1:00007FFE73866DBE718E7DBE73BE7FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000
+9FF2:00007FFE73866DBE718E7DBE73BE7FFE7FFE61866FF663866FBE6F867FFE0000
+9FF3:00007FFE73866DBE718E7DBE73BE7FFE7FFE618E6FF663C66FF66F8E7FFE0000
+9FF4:00007FFE73866DBE718E7DBE73BE7FFE7FFE61B66FB663866FF66FF67FFE0000
+9FF5:00007FFE73866DBE718E7DBE73BE7FFE7FFE61866FBE63866FF66F867FFE0000
+9FF6:00007FFE73866DBE718E7DBE73BE7FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+9FF7:00007FFE73866DBE718E7DBE73BE7FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+9FF8:00007FFE73866DBE718E7DBE73BE7FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+9FF9:00007FFE73866DBE718E7DBE73BE7FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+9FFA:00007FFE73866DBE718E7DBE73BE7FFE7FFE61866FB663866FB66FB67FFE0000
+9FFB:00007FFE73866DBE718E7DBE73BE7FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+9FFC:00007FFE73866DBE718E7DBE73BE7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+9FFD:00007FFE73866DBE718E7DBE73BE7FFE7FFE618E6FB663B66FB66F8E7FFE0000
+9FFE:00007FFE73866DBE718E7DBE73BE7FFE7FFE61866FBE638E6FBE6F867FFE0000
+9FFF:00007FFE73866DBE718E7DBE73BE7FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+A000:000000000000000010101FF010101010101010107C101010082007C000000000
+A001:000003800440000010101FF010107C10121012107C101010082007C000000000
+A002:000000000000000010101FF010107C10121012107C101010082007C000000000
+A003:000000000000000000600050004800403BC004400A400A4004403BC000000000
+A004:0000000000000000139014500C6007C0044004400E4004400440038000000000
+A005:0000038004400000018001600100038004400440038001000D00030000000000
+A006:0000000000000000018001600100038004400440038001000D00030000000000
+A007:0000000000000000071008F009900A800A800A800A80099008F0071000000000
+A008:000000000000000000080008018831680D180300010001000100010000000000
+A009:000003800440000001A0016001200D2003200120012001200D20032000000000
+A00A:000000000000000001A0016001200D2003200120012001200D20032000000000
+A00B:0000000000300040034002C002401A3006000200020002001A00060000000000
+A00C:0000038004400000101011101110111010101FF0101011101110111000000000
+A00D:0000000000000000101011101110111010101FF0101011101110111000000000
+A00E:00000000000004200A500A50042004200420042004200420042003C000000000
+A00F:00000000000000000FE0111011100FE001000700080007000800070000000000
+A010:00000380044000000C700A880988088808A808A808A848882888187000000000
+A011:00000000000000000C700A880988088808A808A808A848882888187000000000
+A012:00000000000000000C700A880988088808880888088848882888187000000000
+A013:000003800440000000603858044008401FC0084004403840034000C000000000
+A014:000000000000000000603858044008401FC0084004403840034000C000000000
+A015:00000000000000001110111011100EE000000000044004400440044000000000
+A016:0000000000000000038004400440055004E004E0055004400440038000000000
+A017:000003800440000010F011001200120012001FF012001200110010F000000000
+A018:000000000000000010F011001200120012001FF012001200110010F000000000
+A019:0000000000000000062005A00460040004F0050007F0050004F0040000000000
+A01A:00000000000000001C18222022402240224023F82240224022201C1800000000
+A01B:000003800440000007D00820105010901110111012101410082007C000000000
+A01C:000000000000000007D00820105010901110111012101410082007C000000000
+A01D:00000000000000000700089008880888089008E0089008880888071000000000
+A01E:0000000000000000082008200FE0082008200380044004400440038000000000
+A01F:0000038004400000082008200FE00820082000001110111011100EE000000000
+A020:0000000000000000082008200FE00820082000001110111011100EE000000000
+A021:0000000000000000082008200FE0082008200000000004400820101000000000
+A022:000003800440000003E0041009D00090009001D000100E100990086000000000
+A023:000000000000000003E0041009D00090009001D000100E100990086000000000
+A024:00000000000000000FE0010001000100010001000100010001000FE000000000
+A025:000000000000000000F01700090014801070148009001700010000F000000000
+A026:000003800440000007C0082008200BA0092009200BA00820082007C000000000
+A027:000000000000000007C0082008200BA0092009200BA00820082007C000000000
+A028:00000000000000001FF0010001001FF0000000001FF0010001001FF000000000
+A029:00000380044000000EE01110111001000100000011101110082007C000000000
+A02A:00000000000000000EE01110111001000100000011101110082007C000000000
+A02B:00000000000000000FE0010009200540038003800540092001000FE000000000
+A02C:00000000000000000FE01010101010100FE00100012001200100010000000000
+A02D:0000038004400000010001000100010001200120012001200D20030000000000
+A02E:0000000000000000010001000100010001200120012001200D20030000000000
+A02F:000000000000000001E0020004E0050005000500050004E0020001E000000000
+A030:00000380044000000860088008800BE008800BE0088008800880070000000000
+A031:00000000000000000860088008800BE008800BE0088008800880070000000000
+A032:0000000000000000030002C00200039002500220022002501B90060000000000
+A033:0000038004400000018001600100016001800160011001600D80036000000000
+A034:0000000000000000018001600100016001800160011001600D80036000000000
+A035:00000000000000000CC00AA00990088008801C800880088022801C8000000000
+A036:00000380044000000030002800241FE022204AA042204AA022201FE000000000
+A037:00000000000000000030002800241FE022204AA042204AA022201FE000000000
+A038:00000000000000000060005000480FC010403FC020403FC010400FC000000000
+A039:000003800440000001C002201220122012E017201A200220022001C000000000
+A03A:000000000000000001C002201220122012E017201A200220022001C000000000
+A03B:00000000000000000000110011000A500A5004500A500A501100110000000000
+A03C:00000380044000000E0011001100115011501F501150115011000E0000000000
+A03D:00000000000000000E0011001100115011501F501150115011000E0000000000
+A03E:000000000000000007C0082011101110082007C00100111011100EE000000000
+A03F:0000000000000000000010101010101010101FF0101010101010101000000000
+A040:00000380044000001110111011101FF01110111011101110092007C000000000
+A041:00000000000000001110111011101FF01110111011101110092007C000000000
+A042:0000000000000000088008900890089008F00890089008900880070000000000
+A043:000003800440000007F008000FF0080007F000800AA00AA00AA0008000000000
+A044:000000000000000007F008000FF0080007F000800AA00AA00AA0008000000000
+A045:000000000000000007F009100FF0091007F0001008100810042003C000000000
+A046:0000000000000000070008A0089008901CA008C01CA008900890072000000000
+A047:00000380044000000920092009200540038000000FE0000000000FE000000000
+A048:00000000000000000920092009200540038000000FE0000000000FE000000000
+A049:000000000000000007F008000FF0080007F0008007F0008007F0008000000000
+A04A:0000000000000000062005A004600400040004000400046005A0062000000000
+A04B:00000380044000000FE0102010200FE0102010200FE0102010200FE000000000
+A04C:000000000000000007F00810081007F00810081007F00810081007F000000000
+A04D:00000000000000C000B0078008800A800A800880078000800680018000000000
+A04E:00000380044000000E0011001150155015F015501150110011000E0000000000
+A04F:00000000000000000E0011001150155015F015501150110011000E0000000000
+A050:000000000000000000C000A00090078008801080108010800880078000000000
+A051:0000038004400000000030182828244822A8212822A824482828301800000000
+A052:0000000000000000000030182828244822A8212822A824482828301800000000
+A053:00000000000000000CC00AA0099008801CA008A008A008A022801C8000000000
+A054:000003800440000008C008A00890008007800890109010900880078000000000
+A055:000000000000000008C008A00890008007800890109010900880078000000000
+A056:00000000000000000380044007C0044007C004400380111011100EE000000000
+A057:0000038004400000010011100920054003800380054009201110010000000000
+A058:0000000000000000010011100920054003800380054009201110010000000000
+A059:000000000000000037D80820145012901290129012901450082037D800000000
+A05A:000000000000000007C008200820082007C011100EE000000100010001000000
+A05B:00000380044000000000007800800D180B200978092009186880187800000000
+A05C:0000000000000000003C0040008C069005BC0490048C0440343C0C0000000000
+A05D:0000000000000000181804200240024002400FF0024002400420181800000000
+A05E:00000000000000000000300C0FF00420024003C0024004200FF0300C00000000
+A05F:000003800440000000000406020A47122AA212422AA24712020A040600000000
+A060:000000000000000000000406020A47122AA212422AA24712020A040600000000
+A061:00000000000000001110111011100EE0000000000FE0000000001FF000000000
+A062:00000380044000000CA00AA009A000200FA000200FA0002001A0006000000000
+A063:00000000000000000CA00AA009A000200FA000200FA0002001A0006000000000
+A064:0000000000000000038014501450145004400440145014501450038000000000
+A065:0000000000000000008000800790089010901090089007900080008000000000
+A066:000003800440000001000920054003800540092001000FE001000FE000000000
+A067:000000000000000001000920054003800540092001000FE001000FE000000000
+A068:00000000000000000EE01110010007C00820111011100100082007C000000000
+A069:00000380044000000640054034D02C10231020D0203007800000078000000000
+A06A:0000000000000000032002A01A68160811881068101803C0000003C000000000
+A06B:0000000000000000314029442548235000603F4000400240014000C000000000
+A06C:0000000000000000304C08500850304C034002C0320C0A100A10320C00000000
+A06D:00000380044000000010019001500D300B000920092029201900010000000000
+A06E:0000000000000000000800C800A8069805800490049014900C80008000000000
+A06F:000000000000000000C018B01688118000900090189016801180100000000000
+A070:0000038004400000002000201820162011A0106001C0022002A002A000000000
+A071:0000000000000000002000201820162011A0106001C0022002A002A000000000
+A072:0000000000000000066005D0044005400540044007C0044015400CC000000000
+A073:0000038004400000019001700110010001000100010011001D00130000000000
+A074:0000000000000000019001700110010001000100010011001D00130000000000
+A075:0000000000000000018001600D00030001000100018001600D00030000000000
+A076:000000000000000003000AC00A300A0002A002A00BE00AA00AA0020000000000
+A077:000003800440000007C009200FE0092007C0010001400150011000E000000000
+A078:000000000000000007C009200FE0092007C0010001400150011000E000000000
+A079:00000000000000001860165011C81040104011F0104011F01040104000000000
+A07A:00000700088000001FC00220021002001FC0020002001FC00200020000000000
+A07B:00000000000000001FC00220021002001FC0020002001FC00200020000000000
+A07C:0000000000000000010001000FE001000100010001000FE00100010000000000
+A07D:00000000000000000E0011141114208420FC20842094249424801B0000000000
+A07E:00000380044000000000044004401FF00280010002801FF00440044000000000
+A07F:00000000000000000000044004401FF00280010002801FF00440044000000000
+A080:0000000000001010145014501290129011101290129014501450101000000000
+A081:0000000000000000038802680E18124022402240224002180268038800000000
+A082:038004400000111011100EE000000100010007C00100010010100FE000000000
+A083:000000000000111011100EE000000100010007C00100010010100FE000000000
+A084:00000000000000001110111011100EE0000001000100111010100FE000000000
+A085:000000000000000003D005300910090009F0090009000910052003C000000000
+A086:000003800440000009C00A2002200E20122012200E2002200A2009C000000000
+A087:000000000000000009C00A2002200E20122012200E2002200A2009C000000000
+A088:0000000000000000010007C009201110115011501110092007C0010000000000
+A089:00000380044000003838454445444444444447C4444444444544393800000000
+A08A:00000000000000003838454445444444444447C4444444444544393800000000
+A08B:0000000000000770088009A00AA00A800BE00A800AA009A00880077000000000
+A08C:000003800440000011501150111011501F50111011501150092007C000000000
+A08D:000000000000000011501150111011501F50111011501150092007C000000000
+A08E:00000000000000006360145813461440634000400C400B4008C0080000000000
+A08F:000003800440000031182928254823883FF82388254829283118010000000000
+A090:000000000000010031182928254823883FF82388254829283118010000000000
+A091:0000000000000000018001600100092009200920092001000D00030000000000
+A092:00000380044000001110092007C001001FF0010007C009201110111000000000
+A093:00000000000011101110092007C001001FF0010007C009201110111000000000
+A094:000000000000000007C00920111012901290129013901450082007C000000000
+A095:0000038004400000155015501110092007C001000100110011000E0000000000
+A096:0000000000000000155015501110092007C001000100110011000E0000000000
+A097:0000000000000000001001900150013001000920092009200100010000000000
+A098:00000000000000000600058004000400058004200710048034480C4800000000
+A099:0000038004400000001030102C10231020D02038204400440044003800000000
+A09A:0000000000000000001030102C10231020D02038204400440044003800000000
+A09B:000000000000000000C030B0088C048004803F80048004800880308000000000
+A09C:00000380044000000240024012480A50046000400C400B4008C0080000000000
+A09D:00000000000000000240024012480A50046000400C400B4008C0080000000000
+A09E:000000000000000009800960091809000180016031182D002300200000000000
+A09F:000000000000000000600050004807C00840124015401240084007C000000000
+A0A0:000003800440000001801160111801000F8811482520250011000F0000000000
+A0A1:000000000000000001801160111801000F8811482520250011000F0000000000
+A0A2:000000000000000003C004200400020001800040012002A0092007C000000000
+A0A3:0000000000000FE008200440028002A0012002A00280044008200FE000000000
+A0A4:00000380044000000020092009200020092009200020062001A0006000000000
+A0A5:00000000000000000020092009200020092009200020062001A0006000000000
+A0A6:000000000000000007C00920155015501110111015501550092007C000000000
+A0A7:0000038004400000111011101010082007C00000082008200820082000000000
+A0A8:0000000000000000111011101010082007C00000082008200820082000000000
+A0A9:000003800440000001000100012009200920090001C001200D10031000000000
+A0AA:000000000000000001000100012009200920090001C001200D10031000000000
+A0AB:00000000000008500850001008500850001008500850031002D0023000000000
+A0AC:000003800440000007C009200FE0092007C001000540155011100EE000000000
+A0AD:000000000000000007C009200FE0092007C001000540155011100EE000000000
+A0AE:000000000000000007C0082016D01290111017D010101390082007C000000000
+A0AF:0000038004400000031002D002300200023002C0030012C00A30060000000000
+A0B0:0000000000000000031002D002300200023002C0030012C00A30060000000000
+A0B1:00000000000000C800A8009800800FF800800FF8008018800680018000000000
+A0B2:000003800440000007C00820145022882128212822881450082007C000000000
+A0B3:000000000000000007C00820145022882128212822881450082007C000000000
+A0B4:0000000000000000000800C800A8109810801090009018900680018000000000
+A0B5:00000000000000001860175012C81240124012401FC012401240124000000000
+A0B6:0000038004400000038004400440044004401FF0044004400440038000000000
+A0B7:0000000000000000038004400440044004401FF0044004400440038000000000
+A0B8:00000000000000001110111011100EE00000010007C0010007C0010000000000
+A0B9:000000000000121011101090121011101090121011101090082007C000000000
+A0BA:000003800440000000C006B0058004C004B014800CC000B00680018000000000
+A0BB:000000000000000000C006B0058004C004B014800CC000B00680018000000000
+A0BC:00000000000000000638054404C404541F5404541F54044434440C3800000000
+A0BD:000000000000000000C000A00090008007800880128012800880078000000000
+A0BE:000003800440000001800160011801C0012001C0010007C00920092000000000
+A0BF:000000000000000001800160011801C0012001C0010007C00920092000000000
+A0C0:000000000000000003C00420081000100010001000100E100990086000000000
+A0C1:000003800440000001000118012401240FE40124012431180D00030000000000
+A0C2:000000000000000001000118012401240FE40124012431180D00030000000000
+A0C3:0000000000000000009000880A880A900AE00090008818880690018000000000
+A0C4:0000038004400000042004200420042007E004200420242014200C2000000000
+A0C5:0000000000000000021002100210021003F00210021012100A10061000000000
+A0C6:00000000000000000388045003E0004001F0024801F018400640018000000000
+A0C7:00000380044000000080008008F008800880008000F018800680018000000000
+A0C8:00000000000000000080008008F008800880008000F018800680018000000000
+A0C9:00000000000000000C200B2008E008000F700880094008800F70080000000000
+A0CA:0000038004400000101010101010082007C00000082008200820082000000000
+A0CB:0000000000000000101010101010082007C00000082008200820082000000000
+A0CC:0000000000000000020002200220022002000FF0020002200220022000000000
+A0CD:00000000000000000380044004401EF008201EF008200920092006C000000000
+A0CE:000003800440000000C000B00480078004800080008000800680018000000000
+A0CF:0000000000000000018000B00480078004800080008000800680018000000000
+A0D0:000000000000000000C000B008800F800880008000800E800980080000000000
+A0D1:00000000000009200AB00AAC092008200FE0082009200AA06AA0192000000000
+A0D2:000003800440000018081608118810681018014009480948041003E000000000
+A0D3:000000000000000018081608118810681018014009480948041003E000000000
+A0D4:00000000000000001808160811881068101802200AA80888041003E000000000
+A0D5:0000038004400000012000A018E0052002200220052018E000A0012000000000
+A0D6:0000000000000000009000500C7002900110011002900C700050009000000000
+A0D7:0000000000000000092005200720090011F01100092007200520090000000000
+A0D8:0000000000000000030012C01230120002200220122012001200020000000000
+A0D9:00000380044000000820282828282828183008200FE008200820082000000000
+A0DA:00000000000000000820282828282828183008200FE008200820082000000000
+A0DB:0000000000000000000002400240181016601180166018100240024000000000
+A0DC:0000038004400000000801883968051823002300050039000100010000000000
+A0DD:0000000000000000000801883968051823002300050039000100010000000000
+A0DE:0000000000000000009000A000C0009000A000C0188016801180100000000000
+A0DF:0000038004400000111011101510092017C0010031002D002300200000000000
+A0E0:0000000000000000111011101510092017C0010031002D002300200000000000
+A0E1:000000000000000010101010082007C00100012031402D802300200000000000
+A0E2:000000000000000011101110082007C001001900150013001000000000000000
+A0E3:0000038004400000001800200040064005C004400440044034200C1800000000
+A0E4:0000000000000000001800200040064005C004400440044034200C1800000000
+A0E5:00000000000000001C1013901170010001C009200920092001C0010000000000
+A0E6:000000000000000011101110111011100110012001C031000D00030000000000
+A0E7:000003800440000009200540139013900540092001000FE001000FE000000000
+A0E8:000000000000000009200540139013900540092001000FE001000FE000000000
+A0E9:00000000000000003FF80100010009C00920092009C0010001003FF800000000
+A0EA:000000000000000007C0082010101FF0101010101FF01010082007C000000000
+A0EB:0000038004400000101010101390145008201450139010101010101000000000
+A0EC:0000000000000000101010101390145008201450139010101010101000000000
+A0ED:0000000000000000030002C0020032380EC803080EC832381A00060000000000
+A0EE:0000000000000000024002401A48164813C81268125802400240018000000000
+A0EF:000003800440000000800C88129012A012C00C80008018800680018000000000
+A0F0:000000000000000000800C88129012A012C00C80008018800680018000000000
+A0F1:000000000000002401A41F74212C212011000F001100210021001F0000000000
+A0F2:000003800440000001E000100C10102011C010200C100010001001E000000000
+A0F3:000000000000000001E000100C10102011C010200C100010001001E000000000
+A0F4:0000000000000000003000280224142008A015202220052008A0004000000000
+A0F5:0380044000001C700380044008203E2008203E200820044003801C7000000000
+A0F6:0000000000001C700380044008203E2008203E200820044003801C7000000000
+A0F7:000000000000008000400FE00820044002800100028004400920111000000000
+A0F8:000003800440000000200020002001E002201F2004201F20022001E000000000
+A0F9:000000000000000000200020002001E002201F2004201F20022001E000000000
+A0FA:000000000000018001402128210811104FE441044FE411102108210800000000
+A0FB:000003800440000010101010082007C000000820082009200100010000000000
+A0FC:000000000000000010101010082007C000000820082009200100010000000000
+A0FD:000000000000000001802148210811100FE401040FE411102508230800000000
+A0FE:000003800440000011101110092007C01110111001001FF001001FF000000000
+A0FF:000000000000000011101110092007C01110111001001FF001001FF000000000
+A100:0000000000000000008832842A84268800F0008832842A842688008000000000
+A101:000003800440000000C004A0029012800C800080188016801180100000000000
+A102:000000000000000000C004A0029012800C800080188016801180100000000000
+A103:000000000100020001000080111011100EE00440054005400440038000000000
+A104:0000038004400000001C0020004C065005D004500450044C34200C1C00000000
+A105:0000000000000000001C0020004C065005D004500450044C34200C1C00000000
+A106:00000000000000000420042072424E4241824272424E04200420042000000000
+A107:0000000000000000110011201120112011001FF81100112011200E2000000000
+A108:0000000003800440000010180828044812881108128804480828101800000000
+A109:0000000000000000000010180828044812881108128804480828101800000000
+A10A:00000000000000000000080C04141A2415441084514432240414080C00000000
+A10B:0000038004400000002000A000A008A00EA009A00020062001A0006000000000
+A10C:0000000000000000002000A000A008A00EA009A00020062001A0006000000000
+A10D:00000000000000000100010007C009200920082008200820082007C000000000
+A10E:000003800440000001800160011801001FF0010031002D002300200000000000
+A10F:000000000000000001800160011801001FF0010031002D002300200000000000
+A110:000000000000000001800160011801001FF00100010031000D00030000000000
+A111:03800440000001C00130010007C0054003800380054007C00100190007000000
+A112:0000000001C00130010007C0054003800380054007C001001900070000000000
+A113:000000000000000018081608118810E81098008003E004900888088800000000
+A114:0000000000000000041008900910071009100890041000100190007000000000
+A115:00000380044000001E20212021C01E8000F0088008F008800088007000000000
+A116:00000000000000001E20212021C01E8000F0088008F008800088007000000000
+A117:00000000000000000FE01010101010100FE0010001F00100010000F000000000
+A118:000003800440000001800160011801001FF00100050005000500010000000000
+A119:000000000000000001800160011801001FF00100050005000500010000000000
+A11A:000000000FE0000001800160011801001FF00100010031000D00030000000000
+A11B:00000380044000000080008027F02080208027F0008018800680018000000000
+A11C:00000000000000000040004013F81040104013F800400C40034000C000000000
+A11D:00000000000000000008018801680118010001001FF001000100010000000000
+A11E:000003800440000008C004B024801880008007F0008000800680018000000000
+A11F:000000000000000008C004B024801880008007F0008000800680018000000000
+A120:00000000000000000850085007900010079008500850031000D0003000000000
+A121:00000000000000000FE0001003900410041004100410039000100FE000000000
+A122:00000380044000000820082000001FE0001000101FE000000840084000000000
+A123:00000000000000000820082000001FE0001000101FE000000840084000000000
+A124:0000000000000FE0001000100F9000100F9000100F90001000100FE000000000
+A125:0000000000000000711C092009201010600C1010092009200920701C00000000
+A126:03800440000000100FF000100FF000100FF00010031002D00230020000000000
+A127:00000000000000100FF000100FF000100FF00010031002D00230020000000000
+A128:000000000000000008040AC40AB4088C0A800A8008804A802A80188000000000
+A129:0000000000000000018001600100018001600100018001600D00030000000000
+A12A:000003800440000001801160111811800160011831802D602318200000000000
+A12B:000000000000000001801160111811800160011831802D602318200000000000
+A12C:00000000000000003C78410441043C78410441043C78410441043C7800000000
+A12D:000003800440000012480A88070807080A8812480F8802080788007800000000
+A12E:000000000000000012480A88070807080A8812480F8802080788007800000000
+A12F:0000000000000000030002C00230030002C0023002000F801240124000000000
+A130:00000000000000000E00117011801100112011201100118011700E0000000000
+A131:000003800440000007C00820101010101010101010101010082007C000000000
+A132:000000000000000007C00820101010101010101010101010082007C000000000
+A133:000000000000000007F008080808080807F000401650155014D0040000000000
+A134:000003800440000001800D600B000928092829F8192801280D00030000000000
+A135:000000000000000001800D600B000928092829F8192801280D00030000000000
+A136:000000000000000018081608118810E810980080049004900490008000000000
+A137:000003800440000010C008B00480108008800480008000800680018000000000
+A138:000000000000000010C008B00480108008800480008000800680018000000000
+A139:000000000000000018881688118810E8109800800FF8008000800FF800000000
+A13A:0000038004400000210821083FF82108210801000FE0010001000FE000000000
+A13B:0000000000000000210821083FF82108210801000FE0010001000FE000000000
+A13C:0000000000000000010021083FF82108010007C0092011101110111000000000
+A13D:00000000000000001FF0010007C0092009200920092007C001001FF000000000
+A13E:0380044000001FF00100311C0D6403840D64311C01001FF001001FF000000000
+A13F:0000000000001FF00100311C0D6403840D64311C01001FF001001FF000000000
+A140:000000000FE001000FE001003908270821C8213801000FE001000FE000000000
+A141:00000380044000000FE001000380054009200920092009200540038000000000
+A142:00000000000000000FE001000380054009200920092009200540038000000000
+A143:00000000000000000FE001000FE0082004400280010002800440082000000000
+A144:000000000000000001800140012001000100092007C000000920092000000000
+A145:0000038004400000111011101FF011101110092007C000000920092000000000
+A146:0000000000000000111011101FF011101110092007C000000920092000000000
+A147:000000000000031002D002300F800200020010400F8000001240124000000000
+A148:00000380044000000EE0010002800440054005400440028001000EE000000000
+A149:00000000000000000EE0010002800440054005400440028001000EE000000000
+A14A:000000000000000008600FD02848184003C0044008400840044003C000000000
+A14B:0000000000001FC0104008800510051003F005100510088010401FC000000000
+A14C:0000038004400000111011101110092007C00100110011001100010000000000
+A14D:0000000000000000111011101110092007C00100110011001100010000000000
+A14E:00000000000000000F8010801088088807F808881088108010800F8000000000
+A14F:000003800440000011101110111011101110111011101110092007C000000000
+A150:000000000000000011101110111011101110111011101110092007C000000000
+A151:0000000000000000008000801808160811881068101800000490049000000000
+A152:0000038004400000002008200FE008200020002008200E2009A0006000000000
+A153:0000000000000000002008200FE008200020002008200E2009A0006000000000
+A154:000000000000000003800440044009200920082008200920092006C000000000
+A155:000003800440000001800160210817D0111017D0210801000D00030000000000
+A156:000000000000000001800160210817D0111017D0210801000D00030000000000
+A157:00000000000000000C60125013C812400C4000400C400B4008C0080000000000
+A158:00000380044000000C60125012480C4000401FF80040074004C0040000000000
+A159:00000000000000000C60125012480C4000401FF80040074004C0040000000000
+A15A:0000000000000000188824A824A824A818A800F000A018A006A0018000000000
+A15B:0000000000000000004007F008400FF0084007F000400E4009C0080000000000
+A15C:0380044000000400099012501250125011900810031002D00230020000000000
+A15D:0000000000000400099012501250125011900810031002D00230020000000000
+A15E:0000000004000800101014501450111011100810031002D00230020000000000
+A15F:0000038004400000183024282424242019E0022004200420022001E000000000
+A160:0000000000000000183024282424242019E0022004200420022001E000000000
+A161:00000000000000000660095829402940264010400FC00040034000C000000000
+A162:00000000000000000000088008800520052003E0052005200880088000000000
+A163:00000380044000000120012001200120012001C00100111011100FE000000000
+A164:00000000000000000120012001200120012001C00100111011100FE000000000
+A165:00000000000000000FE01010101010100FE001001FF001001FF0010000000000
+A166:00000380044000000FE01010101010100FE001001F2001201F20010000000000
+A167:00000000000000000FE01010101010100FE001001F2001201F20010000000000
+A168:0000000000000000098011601118090001001FF001001FF00100010000000000
+A169:0000038004400000018001600118010001001FF001001FF00100010000000000
+A16A:0000000000000000018001600118010001001FF001001FF00100010000000000
+A16B:0000000000000000018001402128210811100FE001000FE01110210821080000
+A16C:000000000000000001800140012001001FF001000FE010102108210800000000
+A16D:000003800440000011101110092007C001001900150013401040018000000000
+A16E:000000000000000011101110092007C001001900150013401040018000000000
+A16F:000000000000046025582546044064401C4000400C400B4008C0080000000000
+A170:00000000000000000010031002D0023002001FC802081FC80200020000000000
+A171:000003800440000000080188016801180D000B80296019180100010000000000
+A172:000000000000000000080188016801180D000B80296019180100010000000000
+A173:00000000000000000FE008200440038004400820018001400500030000000000
+A174:000003800440000003800540054035482F4825E8255805400540038000000000
+A175:000000000000000003800540054035482F4825E8255805400540038000000000
+A176:0000000000000000223055285524222008201420142009A00160010000000000
+A177:000003800440000000C022B0228C088008800080188016801180100000000000
+A178:000000000000000000C022B0228C088008800080188016801180100000000000
+A179:03800440000001800540030000000EE00100028001000EE00000018005400300
+A17A:000001800540030000000EE00100028001000EE0000001800540030000000000
+A17B:0000000000000000000020C412A8118808100FF0081010C812A8218400000000
+A17C:00000000000003600458334640403340044003401840164011C0100000000000
+A17D:0000000000000000006000500048004023C8244808400840244823C800000000
+A17E:000003800440000000900A900A900A9000F00E90009004900290019000000000
+A17F:000000000000000000900A900A900A9000F00E90009004900290019000000000
+A180:000000000000000000C000A00090008007A008C0118012800C80078000000000
+A181:000003800440000000E0011001100710059015500D300110011000E000000000
+A182:000000000000000000E0011001100710059015500D300110011000E000000000
+A183:00000000000000000600058004000798046005C00640078034000C0000000000
+A184:0380044000000660055014C80C600050004001F00C400B4008C0080000000000
+A185:0000000000000660055014C80C600050004001F00C400B4008C0080000000000
+A186:000000000000000001800160011817C0110017C001000D000B00080000000000
+A187:00000380044000001D8003600118010003001D00010031000D00030000000000
+A188:00000000000000001D8003600118010003001D00010031000D00030000000000
+A189:000000000000000008E00910091009500950095009500910091008E000000000
+A18A:00000000000000000700089008900FF0089008900FF008900890070000000000
+A18B:0380044000003E60415808463E40084041403E4000400E4009C0080000000000
+A18C:0000000000003E60415808463E40084041403E4000400E4009C0080000000000
+A18D:000000000000000024C018B0008C248018800080188016801180100000000000
+A18E:0000038004400000018001600D00030001000D00030001000D00030000000000
+A18F:0000000000000000018001600D00030001000D00030001000D00030000000000
+A190:000000000000000031800D60031831000D00030031002D002300200000000000
+A191:000000000000000000C000B000800A800A800A80008000800680018000000000
+A192:03800440000012C00CB0008012800C80008012800C8000801C80038000000000
+A193:00000000000012C00CB0008012800C80008012800C8000801C80038000000000
+A194:000000000000000000600A580A400A40004011400E400040034000C000000000
+A195:000003800440000000C014B01480148000E01C90009000900680018000000000
+A196:000000000000000000C014B01480148000E01C90009000900680018000000000
+A197:000000000410041003E018881688118810E81098008003E00490049000000000
+A198:0380044000000820082007C001100FF0110011000FF0010007C0082008200000
+A199:000000000820082007C001100FF0110011000FF0010007C00820082000000000
+A19A:000000000000000017D0082017D0101010101010082007C010100FE000000000
+A19B:038004400000038004400440038031102D10231021D021300380054005400000
+A19C:0000000001C00220022001C018881688118810E8109801C002A002A000000000
+A19D:0000000000000000089007100010031002D00230020007000A800A8000000000
+A19E:000000000000000007000880088008800B900AD00AB008800880070000000000
+A19F:0000038004400000008007900890108010901090108008900790008000000000
+A1A0:0000000000000000008007900890108010901090108008900790008000000000
+A1A1:000000000000000007800840102000A800A800A800701C20132010C000000000
+A1A2:0380044000000EE001000280044004400FE0044005400540028001000EE00000
+A1A3:000000000EE001000280044004400FE0044005400540028001000EE000000000
+A1A4:000000000000000027C828281010183017D0101011101110082007C000000000
+A1A5:000003800440000001000124012401F801200124012431F80D20032000000000
+A1A6:000000000000000001000124012401F801200124012431F80D20032000000000
+A1A7:000000000000000027C828281010183017D0101010101010082007C000000000
+A1A8:03800440000007C0082010101E1011D0103011D01E101010082007C000000000
+A1A9:00000000000007C0082010101E1011D0103011D01E101010082007C000000000
+A1AA:000000000000000007C008201010101010101FF010101010082007C000000000
+A1AB:00000000000001800160011801001FF001001FF001001D001300100000000000
+A1AC:000003800440000004F00900090004800070048009000900090004F000000000
+A1AD:000000000000000004F00900090004800070048009000900090004F000000000
+A1AE:00000000000000000FE0101010100FE00100090008E00100090008E000000000
+A1AF:000003800440000007C00820101010101010101010101450082017D020080000
+A1B0:000000000000000007C00820101010101010101010101450082017D020080000
+A1B1:00000000000000000110011000E00040034002C0020007000880088000000000
+A1B2:0000038004400000111011101110092007C00100390027002100210000000000
+A1B3:0000000000000000088808880888049003E000801C8013801080108000000000
+A1B4:000000000000000001C0022006300528042004200420042014A00C6000000000
+A1B5:000003800440000002C01AB0168C538032800280188016801180100000000000
+A1B6:000000000000000002C01AB0168C538032800280188016801180100000000000
+A1B7:0000000000000000001001900170010031482D4823C821780140010000000000
+A1B8:000003800440000000400440044004400440044000400C40034000C000000000
+A1B9:000000000000000000400440044004400440044000400C40034000C000000000
+A1BA:000000000000000007C009201110111011101FF011101110092007C000000000
+A1BB:00000000000000000020022002200AA008A008A00020062001A0006000000000
+A1BC:00000380044000000040044004400440004004400A400A400640098000000000
+A1BD:00000000000000000040044004400440004004400A400A400640098000000000
+A1BE:00000000000000000020062009200920092006200020062001A0006000000000
+A1BF:0000000000000000102010281028102010281FE8102010281028102000000000
+A1C0:00000380044000000C200A2009200820082008200820092008A0086000000000
+A1C1:00000000000000000C200A2009200820082008200820092008A0086000000000
+A1C2:00000000000000C000B0188C23E0188023E0188000800E800980080000000000
+A1C3:000005500550001003D00430081008000800080008000810042003C000000000
+A1C4:000003800440000001800160011803800540054013901110092007C000000000
+A1C5:000000000000000001800160011803800540054013901110092007C000000000
+A1C6:0000000000000000044004400FE01450244824480FE014502448238800000000
+A1C7:0000000000000000145015501110082007C001000FE001000900060000000000
+A1C8:000003800440000001800160010007C00920092007C001000D00030000000000
+A1C9:000000000000000001800160010007C00920092007C001000D00030000000000
+A1CA:000000000000000003800540054009200FE009200FE00920092006C000000000
+A1CB:0000038004400000042009200920082004200020062005A00460040000000000
+A1CC:0000000000000000042009200920082004200020062005A00460040000000000
+A1CD:00000000000000001808170810E81018010001000000111011100EE000000000
+A1CE:000000000000000007C00820129012901010101011101110082007C000000000
+A1CF:00000380044000001110111011100EE004400440054005400440038000000000
+A1D0:00000000000000001110111011100EE004400440054005400440038000000000
+A1D1:000000000000100408081C10222049404880494022201C100808100400000000
+A1D2:0000038004402008111009200440028001000280044009201110200800000000
+A1D3:0000000000002008111009200440028001000280044009201110200800000000
+A1D4:000000000000000010841084088807F000800C800B8008806A801A8000000000
+A1D5:000003800440000018081608118810E81098008000800000041003E000000000
+A1D6:000000000000000018081608118810E81098008000800000041003E000000000
+A1D7:000000000000000018081608118810E810980080008006800580040000000000
+A1D8:000003C00420000003C00420040004000200018000400020042003C000000000
+A1D9:000000000000000003C00420040004000200018000400020042003C000000000
+A1DA:00000000000000000F0010802048004800480078004838482648218000000000
+A1DB:000007C00820000003C00420081001100110011000100E100990086000000000
+A1DC:000000000000000003C00420081001100110011000100E100990086000000000
+A1DD:00000000000000000008018801680118010007C02108210810100FE000000000
+A1DE:000000000000000007C0092011101110010007C011101110092007C000000000
+A1DF:0000038004400000145014501390082007C00100010001000900060000000000
+A1E0:0000000000000000145014501390082007C00100010001000900060000000000
+A1E1:000000000000000001880168011801001FF001002548254810100FE000000000
+A1E2:000000000000000014501390082007C00000000007C008201390145000000000
+A1E3:000003800440000010101010082007C00000000007C008201010101000000000
+A1E4:000000000000000010101010082007C00000000007C008201010101000000000
+A1E5:00000000000007C008201010145013901010139014501010082007C000000000
+A1E6:00000000000000000000406020A0112C0A3004300A30113020AC406000000000
+A1E7:00000380044000000000406C20B011300A2C04200A2C113020B0406C00000000
+A1E8:00000000000000000000406C20B011300A2C04200A2C113020B0406C00000000
+A1E9:00000000000007C008201290129010101FF0101011101110082007C000000000
+A1EA:000000000000000044444444444444443BB811101550155011100EE000000000
+A1EB:000003800440000031000D08011031200D400180010031000D00030000000000
+A1EC:000000000000000031000D08011031200D400180010031000D00030000000000
+A1ED:0000000000000000000008200820082000001FF0000001000100010000000000
+A1EE:00000000000000000180016001180100011001F031102D002300200000000000
+A1EF:0000038004400000018001600100090009000900010001000D00030000000000
+A1F0:0000000000000000018001600100090009000900010001000D00030000000000
+A1F1:000000000000000001800960091809000100010031002D002300200000000000
+A1F2:00000000000000E0191005500350031003F0031003500550191000E000000000
+A1F3:0000038004400000101010101FF010101010101010101010082007C000000000
+A1F4:0000000000000000101010101FF010101010101010101010082007C000000000
+A1F5:000000000000000007C008201010145017D0145014501390082007C000000000
+A1F6:0000038004400000101010101FF010101010101010101450082017D020080000
+A1F7:0000000000000000101010101FF010101010101010101450082017D020080000
+A1F8:0000000000000000040005E0040005E0040005E0040004600580060000000000
+A1F9:000003800440000001C00220022004101F100410041004900490036000000000
+A1FA:000000000000000001C00220022004100F100410041004900490036000000000
+A1FB:0000000000001FF01010092005400280010002800540092010101FF000000000
+A1FC:0000038004400000000801880168011831002D08238821682118010000000000
+A1FD:0000000000000000000801880168011831002D08238821682118010000000000
+A1FE:0000000000000000010031182928254823882388254829283118010000000000
+A1FF:0000000000000000038002601218124012401E40124012181260038000000000
+A200:0000000003800440000010180828044802881FF8028804480828101800000000
+A201:0000000000000000000010180828044802881FF8028804480828101800000000
+A202:00000000000000000180096009180900011001F031102D002300200000000000
+A203:000003800440000000601158114011400440047004480048034800C000000000
+A204:000000000000000000601158114011400440047004480048034800C000000000
+A205:0000000001800160010003800540038001000D00030007C00820082000000000
+A206:0000000000000000031002D01E300200020003C002001E000200020000000000
+A207:038004400000180006C000B018800680008018E0069000900690018000000000
+A208:000000000000180006C000B018800680008018E0069000900690018000000000
+A209:000000000000030002C0023002000FF01200120012000FF00200020000000000
+A20A:0000000000000000044004401390111011100EE0044004400440038000000000
+A20B:0000038004400000082008200820082000000000010001000100010000000000
+A20C:0000000000000000082008200820082000000000010001000100010000000000
+A20D:0000000000000000101010101010082007C00000111011101110111000000000
+A20E:0000000000000000111011101110092007C0010001001FF00100010000000000
+A20F:000003800440000000101A5016501250135012D00010031000D0003000000000
+A210:00000000000002101A5016501250135012D002100010031000D0003000000000
+A211:000000000000000003E004900490008000800080188016801180100000000000
+A212:03800440000000400640054004401F40044014400C400040034000C000000000
+A213:0000000000000020032002A002200FA002200A200620002001A0006000000000
+A214:00000000000007C008201010101010100C601010111011100D60010000000000
+A215:0000038004400000002008A005200520052008A00020062001A0006000000000
+A216:0000000000000000002008A005200520052008A00020062001A0006000000000
+A217:00000380044000000F6010D01648094016401040164009401640004000000000
+A218:00000000000000000F6010D01648094016401040164009401640004000000000
+A219:00000000000000000400040004001C0816081188106810380020002000000000
+A21A:0000000000000000020802080208020803F8020802081A081608100800000000
+A21B:03800440000007E00810080007E00010081007E0008007F0008007F000800000
+A21C:00000000000007E00810080007E00010081007E0008007F0008007F000800000
+A21D:000000000000000021382140218021800180014031382D002300200000000000
+A21E:000000000000000008400840084000400C40034000C001E00210021000000000
+A21F:00000380044000001830244804400440044004400FE014502448238800000000
+A220:00000000000000001830244804400440044004400FE014502448238800000000
+A221:000000000FE010101110111010100FE001001FF001001FF00500030000000000
+A222:00000000000000000180016031082D0823882168211801000D00030000000000
+A223:000003800440000000200020002000200020082008200E2009A0086000000000
+A224:000000000000000000200020002000200020082008200E2009A0086000000000
+A225:00000000000000000840084008400840004000400C400B4008C0080000000000
+A226:00000000000000000AC00AB000801F8000800A800A8000800680018000000000
+A227:0000038004400000111011101010101011101110101010101110111000000000
+A228:0000000000000000111011101010101011101110101010101110111000000000
+A229:000000000000000019602558244027C02440254025401840034000C000000000
+A22A:0000000000000000000809881568151815000F00050009001100010000000000
+A22B:038004400000183006D0011006D018300000183006D0011006D0183000000000
+A22C:000000000000183006D0011006D018300000183006D0011006D0183000000000
+A22D:0000000000000000183006D0011006D01830010001001FF00100010000000000
+A22E:0380044000000FE01010101010100FE000000FE01010101010100FE000000000
+A22F:0000000000000FE01010101010100FE000000FE01010101010100FE000000000
+A230:000003800440000006183D944472441024101C102410441044103C1000000000
+A231:000000000000000006183D944472441024101C102410441044103C1000000000
+A232:000000000000000003E00410041007F00410051006100C10141003E000000000
+A233:0000038004400000186016581040104010401FC0124012401240124000000000
+A234:0000000000000000186016581040104010401FC0124012401240124000000000
+A235:0000000000000000010C01100120012001E0012031202D10230C200000000000
+A236:0380044001000FE0111011100FE0210821080FE0111011100FE0010000000000
+A237:0000000001000FE0111011100FE0210821080FE0111011100FE0010000000000
+A238:0000000000000000000007C008200820082007C0010007C00920092000000000
+A239:0000000000000000000007C009200FE0092007C0010007C00920092000000000
+A23A:03800440000003E004100410041003E00080038002000F801240124000000000
+A23B:00000000000003E004100410041003E00080038002000F801240124000000000
+A23C:000000000000000000780080038004401E380440038000800080007800000000
+A23D:0380044000000070008000900790088012701200127008800790009000800070
+A23E:0000007000800090079008801270120012700880079000900080007000000000
+A23F:00000000000000000FB8104020A020A020B820A020A020A010400FB800000000
+A240:000000000000000008202AA81AB0193018301AB01AB02928082007C000000000
+A241:0000000003800440000006E0010002C002000FE0020002C0010006E000000000
+A242:0000000000000000000006E0010002C002000FE0020002C0010006E000000000
+A243:00000000000000000410041003E0008007F0008007F0108010800F0000000000
+A244:00000380044000001410141014101590169014901090109008A007C000000000
+A245:00000000000000001410141014101590169014901090109008A007C000000000
+A246:000000000000000000000E1009900870000000000E1009900870000000000000
+A247:0380044000000100311829282448228821082288244829283118010000000000
+A248:0000000000000100311829282448228821082288244829283118010000000000
+A249:0000000000001FF0004007C008400840084007C008400840084007C000000000
+A24A:0000000000000000004009400940094000400F4000400C40034000C000000000
+A24B:0000038004400000003000400090039002F00280028002401A30060000000000
+A24C:0000000000000000003000400090039002F00280028002401A30060000000000
+A24D:0000000000000000070008A008A0088008F0088008A008A00880070000000000
+A24E:000000000000000010C020B0248C22801180008007E008800880070000000000
+A24F:000003800440000010C020B0248C228011800080008018800680018000000000
+A250:000000000000000010C020B0248C228011800080008018800680018000000000
+A251:000000000000000012C022B0248C228011800280028018800680018000000000
+A252:00000000000000002288228822881C7000000820082008200440038000000000
+A253:000003800440000001E00200040004000400040004000400020001E000000000
+A254:000000000000000001E00200040004000400040004000400020001E000000000
+A255:00000000000000001110111011100EE000000380044004400440038000000000
+A256:00000000000000000FC0002007A00820072000A00F20002000200FC000000000
+A257:0000038004400000018001600900050003000100010001000D00030000000000
+A258:0000000000000000018001600900050003000100010001000D00030000000000
+A259:0000000000000000000030182828244822882108228824482828301800000000
+A25A:0380044000000920092007C00FE01110111011100FE007C00920092000000000
+A25B:0000000000000920092007C00FE01110111011100FE007C00920092000000000
+A25C:0000000000000000018031602D1823002100010031002D002300210000000000
+A25D:00000380044000000180056005180500014009400540131011100FE000000000
+A25E:00000000000000000180056005180500014009400540131011100FE000000000
+A25F:000000000000000001800160110811087D3E1108110801000D00030000000000
+A260:0000000000000000202020203828262821A820702020202010400F8000000000
+A261:000003800440000018881688118810E810980080008006800580040000000000
+A262:000000000000000018881688118810E810980080008006800580040000000000
+A263:0000000000000000008008E008903E8808880888009018E00680018000000000
+A264:00000000000000000FE0101024482288010001002288244810100FE000000000
+A265:0380044000000380044005400540044007C00440028001000280044000000000
+A266:0000000000000380044005400540044007C00440028001000280044000000000
+A267:00000000000000001C70028001000100010001000100010002801C7000000000
+A268:0000038004400000038004400440044007C0082009200920082007C000000000
+A269:0000000000000000038004400440044007C0082009200920082007C000000000
+A26A:00000000000000000088029002A002C012E00C900090189006E0018000000000
+A26B:00000380044000000020022002200FA0022002200020062001A0006000000000
+A26C:00000000000000000020022002200FA0022002200020062001A0006000000000
+A26D:00000000000000000E00110011001F2011501FD011501F2011000E0000000000
+A26E:0000000000000000098011601118090007000900110011000900010000000000
+A26F:0000038004400000118011600918070009001100110001000D00030000000000
+A270:0000000000000000118011600918070009001100110001000D00030000000000
+A271:00000000000000000050035002D002700240024002000F801240124000000000
+A272:000003800440000001C002A003E002A031C02C8023C002200490049000000000
+A273:000000000000000000E0015001F0015018E0164011E001100248024800000000
+A274:000000000000000000E001100110011018E0164011E001100248024800000000
+A275:0000000000000000098015601518090001001FF001001FF00100010000000000
+A276:000003800440000001801960051813002B002B00130005001900010000000000
+A277:000000000000000001801960051813002B002B00130005001900010000000000
+A278:000000000000000001001FE00910151009101FE0010007C00920092000000000
+A279:00000000000000000F00103810400880078008801040103810000F0000000000
+A27A:000003800440000007C00820139014501450145014501390082007C000000000
+A27B:000000000000000007C00820139014501450145014501390082007C000000000
+A27C:0000000000000000000020201040089005280228052808901040202000000000
+A27D:00000380044000000C300B2808E4082008201C202A202A202A20082000000000
+A27E:00000000000000000C300B2808E4082008201C202A202A202A20082000000000
+A27F:0000000000000000038004400E4004400E400440038004400920092000000000
+A280:0000000000000000022002200E240BA42A741A2C02A002A0022001C000000000
+A281:000003800440000018081608118810681018000007E00000000007E000000000
+A282:000000000000000018081608118810681018000007E00000000007E000000000
+A283:0000000000000000180816081188106810180000042004200420042000000000
+A284:00000380044000000E70018001800250025002500180058002400D3000000000
+A285:00000000000000000E70018001800250025002500180058002400D3000000000
+A286:00000000000001C001300F8001400F4001400F80010003800540054000000000
+A287:00000380044000000710089008A007C0008003E000800BE00880070000000000
+A288:00000000000000000710089008A007C0008003E000800BE00880070000000000
+A289:0000000000000000000004400440028002A001200AA006800640054000000000
+A28A:038004400000180006C000B01888068000801880068003E00490049000000000
+A28B:00000000180006C000B018880680008018800680008003E00490049000000000
+A28C:0000000000000000018001600118014001401D10139011700100010000000000
+A28D:00000000000011101110092007C00100150015001F0015001500010000000000
+A28E:00000380044000000440044004401390111011100EE004400AA00AA000000000
+A28F:00000000000000000440044004401390111011100EE004400AA00AA000000000
+A290:000000000000000003D00430081009000900090009000810042003C000000000
+A291:00000380044000001440144014401FF814401440144001F0004001F000000000
+A292:00000000000000001440144014401FF814401440144001F0004001F000000000
+A293:000000000000000001801560151815001FE01500150001000100010000000000
+A294:000000000000000801881D6803180B000B7003801DA001A00180017000000000
+A295:0000038004400000007807800880107814801480107808800780007800000000
+A296:0000000000000000007807800880107814801480107808800780007800000000
+A297:00000000000000000440044004401390111011100EE0000000000EE000000000
+A298:00000380044000000380044004400E40044004400E4004400440038000000000
+A299:00000000000000000380044004400E40044004400E4004400440038000000000
+A29A:0000000000000000010001180124013C012401FC012431180D00030000000000
+A29B:000000000000000001000280044008200FE001000280044008200FE000000000
+A29C:00000380044000000804087408AC09200A200C200A20692058A0406000000000
+A29D:00000000000000000804087408AC09200A200C200A20692058A0406000000000
+A29E:00000000000000000FE0101010100FE0101010100FE0101010100FE000000000
+A29F:0000038004400000018001600118010017D01110111017D00100010000000000
+A2A0:0000000000000000018001600118010017D01110111017D00100010000000000
+A2A1:00000000000000400C400B4008C008000BE00A20094008800940022000000000
+A2A2:0000000000000000070008A008A008C0088008A008A008C00880070000000000
+A2A3:00000000038004400000064001C0064001C00000064001C0064001C000000000
+A2A4:00000000000000000000064001C0064001C00000064001C0064001C000000000
+A2A5:000000000000000007C00820111011100000000007C008201110111000000000
+A2A6:0000000003800440000060305054489405180210051408941058203000000000
+A2A7:0000000000000000000060305054489405180210051408941058203000000000
+A2A8:0000000000000248015000E001500248034012C00A8007000A80124000000000
+A2A9:000000000380044000000440044002800280010002800A800840074000000000
+A2AA:000000000000000000000440044002800280010002800A800840074000000000
+A2AB:000000000000000000F00900090000F00900090000F00900090000F000000000
+A2AC:000003800440000003C0240C2410022021E022200410240C240003C000000000
+A2AD:000000000000000003C0240C2410022021E022200410240C240003C000000000
+A2AE:00000000000000001860165011C8104012401240124010401040104000000000
+A2AF:0000038004400000030002C002300200020002001FC002000200020000000000
+A2B0:0000000000000000030002C002300200020002001FC002000200020000000000
+A2B1:0000000000000FE00820044002800280010002800280044008200FE000000000
+A2B2:0000000000001E0811CC103A1188114811081108110815085308300000000000
+A2B3:0000038004400000038004400450045004500460044004400440038000000000
+A2B4:0000000000000000038004400450045004500460044004400440038000000000
+A2B5:0000000000000000030002C00230020002000F8010401FC010400F8000000000
+A2B6:000000000000000007C00820109016901190109016901190082007C000000000
+A2B7:000003800440000007C00820101011901150111015101310082007C000000000
+A2B8:000000000000000007C00820101011901150111015101310082007C000000000
+A2B9:000000000000000007800840132802A802280A3006201C20132010C000000000
+A2BA:03800440000001C00130010001C0012007C00900070001001900070000000000
+A2BB:00000000000001C00130010001C0012007C00900070001001900070000000000
+A2BC:00000000000000000C6002800100028002800440044009200920092000000000
+A2BD:000000000000000002200220022802280F282AE81A380228022801C000000000
+A2BE:000003800440000001C00220022802280F282AE81A380228022801C000000000
+A2BF:000000000000000001C00220022802280F282AE81A380228022801C000000000
+A2C0:0000000000000000071008900890089008901FF0089008900890071000000000
+A2C1:000003800440000007C00820139010501390105013901010082007C000000000
+A2C2:000000000000000007C00820139010501390105013901010082007C000000000
+A2C3:00000000000000001110111011100EE0000004401550155011100EE000000000
+A2C4:000000000000000011C42224222412240E3C122422242224122401C400000000
+A2C5:00000000038004400000406020A011244A24443C4A24112420A0406000000000
+A2C6:00000000000000000000406020A011244A24443C4A24112420A0406000000000
+A2C7:000000000000000010C013B01080088007800080188016801180100000000000
+A2C8:0000038004400000070008900890089008F00890089008900880070000000000
+A2C9:0000000000000000070008900890089008F00890089008900880070000000000
+A2CA:000000000000000008200420022001200CA00A60090008800840082000000000
+A2CB:0000000003800440000004400440028002A0012002A002800440044000000000
+A2CC:0000000000000000000004400440028002A0012002A002800440044000000000
+A2CD:0000000000000000018001600100010001000100010001000D00030000000000
+A2CE:0000038004400000183006C0010006C018300100010007C00100010000000000
+A2CF:0000000000000000183006C0010006C018300100010007C00100010000000000
+A2D0:000000000000000018081608158814681458044007C004400440044000000000
+A2D1:0000038004401000086024501048084003C0044008400840044003C000000000
+A2D2:0000000000001000086024501048084003C0044008400840044003C000000000
+A2D3:00000000000000000020062005A0046004000520052004000520052000000000
+A2D4:0000000000000FE0010011400920051011400920051011400920051000000000
+A2D5:000003800440000007C00820101017D001000100054005400540010000000000
+A2D6:000000000000000007C00820101017D001000100054005400540010000000000
+A2D7:0000000000000000180816081188106811180100010004400440044000000000
+A2D8:00000000000000001FC00200020012680AA807380AA8126802001FC000000000
+A2D9:00000000038004400000110011000A500A5004000A500A501100110000000000
+A2DA:00000000000000000000110011000A500A5004000A500A501100110000000000
+A2DB:00000000000000000000110011000A500A5004000A700A001100110000000000
+A2DC:038004400010031002D002300F8002000F800200070008800880070000000000
+A2DD:000000000010031002D002300F8002000F800200070008800880070000000000
+A2DE:00000000000000000100010007C011101110092007C004400820082000000000
+A2DF:000003800440000007C008200FE008200FE0082007C00100011000E000000000
+A2E0:000000000000000007C008200FE008200FE0082007C00100011000E000000000
+A2E1:00000000000000000F00114011400F40114011000F000110011000E000000000
+A2E2:0000038004400000030002C002300200070008800880070010400F8000000000
+A2E3:0000000000000000030002C002300200070008800880070010400F8000000000
+A2E4:000000000180016001000F28112811F811280F28010001000D00030000000000
+A2E5:0000038004400000060005800460040004A004A007E004A004A0040000000000
+A2E6:0000000000000000060005800460040004A004A007E004A004A0040000000000
+A2E7:0000000000000000000004400820101004400820101004400820101000000000
+A2E8:0380044000000010031002D0023002000A6006A0032006A00A60020000000000
+A2E9:0000000000000010031002D0023002000A6006A0032006A00A60020000000000
+A2EA:000000000000000001E0022004200420022001E0006009A00E20082000000000
+A2EB:000003800440000003800440044004400FC01440144014401440044000000000
+A2EC:000000000000000001C002200220022007E00A200A200A200A20022000000000
+A2ED:000000000000000007F0008001C0013001000120012001200D00030000000000
+A2EE:0000000003800440000004400440044000000FE0000004400440044000000000
+A2EF:0000000000000000000004400440044000000FE0000004400440044000000000
+A2F0:0000000000000000012009100910092001C00120091009100920010000000000
+A2F1:000003800440000011201510151011201FC011201510151011200E0000000000
+A2F2:000000000000000011201510151011201FC011201510151011200E0000000000
+A2F3:0000000000000000112011101110112011C011201110111011200E0000000000
+A2F4:0000000000000000010007C00100000001800160010001000D00030000000000
+A2F5:000003800440010007C00100000001800160010007C001000D00030000000000
+A2F6:000000000000010007C00100000001800160010007C001000D00030000000000
+A2F7:0000000000000000098011601118090007480948110011480948010000000000
+A2F8:0000038004400000044004400380111013900D6001000D6003800D6000000000
+A2F9:0000000000000000044004400380111013900D6001000D6003800D6000000000
+A2FA:00000380044000000010031002D0023002000F801240124012400F8000000000
+A2FB:00000000000000000010031002D0023002000F801240124012400F8000000000
+A2FC:0000038004400000008003E00080060005800460040004400440040000000000
+A2FD:0000000000000000008003E00080060005800460040004400440040000000000
+A2FE:0000038004400000010007C00100111011100EE00000010007C0010000000000
+A2FF:0000000000000000010007C00100111011100EE00000010007C0010000000000
+A300:00000000010007C041044C64345804400380010007C0010007C0010000000000
+A301:0000038004400000101010101FF011101110111011101110092007C000000000
+A302:0000000000000000101010101FF011101110111011101110092007C000000000
+A303:0000000000000000000009F012101210091000F009101210121009F000000000
+A304:000003800440000002400280030003C00220022003C003000280024000000000
+A305:000000000000000002400280030003C00220022003C003000280024000000000
+A306:000000000000000007C0082014501FF0145014501FF01450082007C000000000
+A307:000003800440000010101450145014501010111011101110082007C000000000
+A308:000000000000000010101450145014501010111011101110082007C000000000
+A309:000000000000000000880088008800880C8810F8208824882288118800000000
+A30A:000003800440000007C008201FF010101FF0082007C008201110111000000000
+A30B:000000000000000007C008201FF010101FF0082007C008201110111000000000
+A30C:0000000000000000030012C01230120002000200120012001200020000000000
+A30D:000003800440000004440444024801F018402040404048404640218000000000
+A30E:000000000000000004440444024801F018402040404048404640218000000000
+A30F:000000000000000011101110092007C001000100078009400640004000000000
+A310:000000000000000000B808C008C008B8088000B800C018C006B8018000000000
+A311:00000380044000000080089008F0089008800080009018F00690018000000000
+A312:00000000000000000080089008F0089008800080009018F00690018000000000
+A313:00000F901050001003D00430081008000800080008000810042003C000000000
+A314:0000038004400000060005800460040005200520052005200400040000000000
+A315:0000000000000000060005800460040005200520052005200400040000000000
+A316:00000000000000000C000B0008C008000A200940088009400A20080000000000
+A317:00000000000003C004200500048002000180004002200120042003C000000000
+A318:0000038004400000118009600500110009400520011001400D20031000000000
+A319:0000000000000000118009600500110009400520011001400D20031000000000
+A31A:00000000000007C008200A800A80080007C0002002A002A0082007C000000000
+A31B:000003800440000008C008A00090078008800880078000800880088000000000
+A31C:000000000000000008C008A00090078008800880078000800880088000000000
+A31D:0000000000000000004010501050135002C00200121012101210020000000000
+A31E:0000000000000820082007C00000111011100EE0000007C00820082000000000
+A31F:0000038004400000024002400240020003E00200024002401A40060000000000
+A320:0000000000000000012001200120010001F00100012001200D20030000000000
+A321:000000000000000003C00420081008103E10081008100810042003C000000000
+A322:00000380044000000100092009201D20090009F0010001200D20032000000000
+A323:00000000000000000100092009201D20090009F0010001200D20032000000000
+A324:00000000000000001010101010101010082007C00000010007C0010000000000
+A325:00000380044000001010101010101010082007C00100110011000E0000000000
+A326:00000000000000001010101010101010082007C00100110011000E0000000000
+A327:0000000000000000008007F00080008007F00080188016801180100000000000
+A328:0000038004400000101010101010082007C00000010001000100010000000000
+A329:0000000000000000101010101010082007C00000010001000100010000000000
+A32A:0000000000000000000811881F6811180100011011101F101110010000000000
+A32B:00000380044000000020062005A0046004000440044005F00440044000000000
+A32C:00000000000000000020062005A0046004000440044005F00440044000000000
+A32D:0000000000000000001003101ED002300200022002201EF80220022000000000
+A32E:000003800440000018081608118811681518054001400540051000E000000000
+A32F:000000000000000018081608118811681518054001400540051000E000000000
+A330:000000000000000018081608118810E81098008002A002A0008007F000000000
+A331:00000000000000001110111013900D60010005401550155011100EE000000000
+A332:00000380044000000FE0101010100FE0210821080FE0101010100FE000000000
+A333:00000000000000000FE0101010100FE0210821080FE0101010100FE000000000
+A334:0000000000000FE0101010100FE001001FF001000FE0101010100FE000000000
+A335:0000000000000000000811881F681118110011001F0011000100010000000000
+A336:000003800440000007C00820101010101FF0111011101110092007C000000000
+A337:000000000000000007C00820101010101FF0111011101110092007C000000000
+A338:00000000000000001860165011C0104012401540154015401240104000000000
+A339:00000380044000000180016001000100010001C0012001200D20030000000000
+A33A:00000000000000000180016001000100010001C0012001200D20030000000000
+A33B:000000000000000007C00820119011501110119015501350082007C000000000
+A33C:000000000000000000401FF800400440047800400C400B4008C0080000000000
+A33D:00000380044000001C60135010C002400FC002400C400B4008C0080000000000
+A33E:00000000000000001C60135010C002400FC002400C400B4008C0080000000000
+A33F:000000000000049003E00080049003E01880168013E014100490049000000000
+A340:0000000000000000112015101510112015C01520111015101510112000000000
+A341:00000380044000000180016007D8090009C0090037C02D002300200000000000
+A342:00000000000000000180016007D8090009C0090037C02D002300200000000000
+A343:00000000000000000F001088224802400FC80248024038482648218000000000
+A344:0380044000000EE0111011101110010001000FE0000009200920092000000000
+A345:0000000000000EE0111011101110010001000FE0000009200920092000000000
+A346:0000000000700E8011A011A01180157015001570118011A011A00E8000700000
+A347:03800440010001000440044018101610111010D0103004400540010000000000
+A348:00000000010001000440044018101610111010D0103004400540010000000000
+A349:000000000000000003883A680618120012001200120006183A68038800000000
+A34A:00000380044000000580056025181900010001003FF801000100010000000000
+A34B:00000000000000000580056025181900010001003FF801000100010000000000
+A34C:000000000000000007E008200820082007E0002001200920082007C000000000
+A34D:000000000000000005800560251819000100010007C009201110111000000000
+A34E:00000380044000001860165011C010401240124010401FC01040104000000000
+A34F:00000000000000001860165011C010401240124010401FC01040104000000000
+A350:000000000000000001000540044002801E90111012F002800440054001000000
+A351:00000000000000000008018801680118010005402548210811100FE000000000
+A352:00000380044000000100010001000100054005402548210811100FE000000000
+A353:00000000000000000100010001000100054005402548210811100FE000000000
+A354:000000000000000015501550155011101550155015501110092007C000000000
+A355:00000000000000000638054404C40444044404440444245414540C3800100000
+A356:000003800440000001900F6811281128091007000900110011000F0000000000
+A357:000000000000000001900F6811281128091007000900110011000F0000000000
+A358:000000000000000000000100028002800100000004400AA00AA0044000000000
+A359:0000038004400000031002E81A28062802101A00060002001A00060000000000
+A35A:0000000000000000031002E81A28062802101A00060002001A00060000000000
+A35B:00000000000007C00820080007C00020082007C000000FE000000FE000000000
+A35C:000003800440000011101110092007C00110011007C009201110111000000000
+A35D:000000000000000011101110092007C00110011007C009201110111000000000
+A35E:0000000000000E100990087000000E100990087000000E100990087000000000
+A35F:0000038004400000038002601218120013E01200120012180260038000000000
+A360:0000000000000000038002601218120013E01200120012180260038000000000
+A361:00000000000000000180016001000FE009200540038003800540092000000000
+A362:000003800440000001800160010007C0092007C0010007C00920092000000000
+A363:000000000000000001800160010007C0092007C0010007C00920092000000000
+A364:0000000000000100038005400440054003800100038005400920092000000000
+A365:000000000000000030C02CA8239820882480248020803F802080208000000000
+A366:00000380044000000C300A280820282018A00C600A20082028A0186000000000
+A367:00000000000000000C300A280820282018A00C600A20082028A0186000000000
+A368:000000000000000000002230125008900510021C051008901250223000000000
+A369:000000000000000018181514111210101FF01010111091105050303000000000
+A36A:03800440000018081608118810E81098008018881688118810E8109800000000
+A36B:00000000000018081608118810E81098008018881688118810E8109800000000
+A36C:00000000000000000C300B2C082008200FE008200820082069A0186000000000
+A36D:00000000000000001FF011100920054013901110139005400920111000000000
+A36E:00000380044000001FF011100920054003801FF0028004400920111000000000
+A36F:00000000000000001FF011100920054003801FF0028004400920111000000000
+A370:00000000000000001FF01110092005403B8827C822B804400920111000000000
+A371:00000380044000000E001128112815F8152815F81528112811000E0000000000
+A372:00000000000000000E001128112815F8152815F81528112811000E0000000000
+A373:0000000000000000072008A008800AF00A800A800AF0088008A0072000000000
+A374:00000380044000000C040B34082C082008203E200820082C6834180400000000
+A375:00000000000000000C040B34082C082008203E200820082C6834180400000000
+A376:000000001C1001C805A8059801800E8000800FF8008018800680018000000000
+A377:000003800440000018081608118810E81098008001C00220022001C000000000
+A378:000000000000000018081608118810E81098008001C00220022001C000000000
+A379:000000000000000005500550011007D00110055004500C100390007000000000
+A37A:0380044000001C0803880B680B1803001D0001001FF001001FF0010000000000
+A37B:0000000000001C0803880B680B1803001D0001001FF001001FF0010000000000
+A37C:0000038004400000033012E812243A2012201220022002201A20062000000000
+A37D:0000000000000000033012E812243A2012201220022002201A20062000000000
+A37E:0000038004400000010001200920150015F01500092001200D00030000000000
+A37F:0000000000000000010001200920150015F01500092001200D00030000000000
+A380:0000000000000000014811481130110011F80100013031480D48030000000000
+A381:00000380044000000380044007C008200FE0082008200920092006C000000000
+A382:00000000000000000380044007C008200FE0082008200920092006C000000000
+A383:00000000000007C008201010045004500110011000100E100990086000000000
+A384:0000000000000000000801880168011801003FF8010011007D00110000000000
+A385:00000380044000000FC00020002000200FE000200020002000200FC000000000
+A386:00000000000000000FC00020002000200FE000200020002000200FC000000000
+A387:000000000000000018081608118810E81098008003E008800880070000000000
+A388:0000000000000000181014101210101011101110101010901050103000000000
+A389:0000038004400000082014501450145008200540028002800280010000000000
+A38A:0000000000000000082014501450145008200540028002800280010000000000
+A38B:000000000000000036D808201450145014503FF814501450082036D800000000
+A38C:0000038004400000018000400620082009200920082006200040018000000000
+A38D:0000000000000000018000400620082009200920082006200040018000000000
+A38E:0000000000000000008000A800A800A800F800A818A816A81180100000000000
+A38F:00000380044000000040004000400040004000500C500B5008D0080000000000
+A390:00000000000000000040004000400040004000500C500B5008D0080000000000
+A391:000000000000000000C007A00890088004A003A004A008800880078000000000
+A392:0000038004400000080809881D6809180900010007C009201110111000000000
+A393:0000000000000000080809881D6809180900010007C009201110111000000000
+A394:00000000000007C008201110111010101FF0101011101110082007C000000000
+A395:000003800440000003801450145004400FE00440145014500440038000000000
+A396:000000000000000003801450145004400FE00440145014500440038000000000
+A397:0000000000000000024002500260024002400240024006400A40024000000000
+A398:000003800440000003C004200910011007D0011001100E100990086000000000
+A399:000000000000000003C004200910011007D0011001100E100990086000000000
+A39A:000000000220022003E006300A3001D00010001000100E100990086000000000
+A39B:0000000000000000000801880168011801001FF0010009200920010000000000
+A39C:000003800440000004040434042C0420042007E0042034202C20202000000000
+A39D:000000000000000004040434042C0420042007E0042034202C20202000000000
+A39E:000000000000000000C000A00090008007B008C010F010C008B0078000000000
+A39F:0000000000000000070008800BA00AE0088008800BA00AE00880070000000000
+A3A0:000003800440100028C02FB0288C10800080108028802F802880108000000000
+A3A1:000000000000100028C02FB0288C10800080108028802F802880108000000000
+A3A2:000000000000082008200440139011107D7C111011100D000B00080000000000
+A3A3:00000380044000000FE01010101010100FE001000100110011000E0000000000
+A3A4:00000000000000000FE01010101010100FE001000100110011000E0000000000
+A3A5:000000000000000009300550039003900550093001000D000B00080000000000
+A3A6:00000380044000000810081008100FF008100A100C1018102810081000000000
+A3A7:00000000000000000810081008100FF008100A100C1018102810081000000000
+A3A8:00000000000000000080088008800F80088008800080008000800FF800000000
+A3A9:0000038004400000030002C00200020003E00210024802A81AA0064000000000
+A3AA:0000000000000000030002C00200020003E00210024802A81AA0064000000000
+A3AB:0000000000000000000010180828044802880108028804480828101800000000
+A3AC:0000038004400000018001602918290029003F00290029002900010000000000
+A3AD:0000000000000000018001602918290029003F00290029002900010000000000
+A3AE:0000000000000000093009280FE40920092009200FE049202920192000000000
+A3AF:00000380044000000FE001000FE0010009200540038003800540092000000000
+A3B0:00000000000000000FE001000FE0010009200540038003800540092000000000
+A3B1:000000000000000018081608118810E81098008002A001C001C002A000000000
+A3B2:000000000000000009C01130110009200720092011201100093001C000000000
+A3B3:0380044000000540054004401390111011100EE0054005400440038000000000
+A3B4:0000000000000540054004401390111011100EE0054005400440038000000000
+A3B5:00000000000000000000190C251422241D4400841D4422242514190C00000000
+A3B6:0000000000000000008002A002A002A01880168011C012200490049000000000
+A3B7:000003800440100011801F601118114001401950171011D01130010000000000
+A3B8:000000000000100011801F601118114001401950171011D01130010000000000
+A3B9:0000000000001C0003800B600B1803401D4001401910171011D0113000000000
+A3BA:0000000000000000010009200540038009200540038009200540038000000000
+A3BB:0000038004400000012801280128012801280128013031E00D20032000000000
+A3BC:0000000000000000012801280128012801280128013031E00D20032000000000
+A3BD:000000000000000007E008100810081007E00080068009000680008000000000
+A3BE:000003800440000007900860086007A00020002007A008600860079000000000
+A3BF:000000000000000007900860086007A00020002007A008600860079000000000
+A3C0:0000000000000000022002201A28162813A81268123802200220022000000000
+A3C1:000003800440000003E004000400020001E0020004000400040003E000000000
+A3C2:000000000000000003E004000400020001E0020004000400040003E000000000
+A3C3:0000000000000490049002A001C0008000801880168011801000100000000000
+A3C4:000003800440100011E012000400140017E0140004001400120011E000000000
+A3C5:000000000000080008F0090002000A000BF00A0002000A00090008F000000000
+A3C6:000000000000018001600118010007C00920111017D011101110010000000000
+A3C7:00000380044000000E0011481148113011F811301148114811000E0000000000
+A3C8:00000000000000000E0011481148113011F811301148114811000E0000000000
+A3C9:00000000000000000760088009800A800A800A800A8009800880076000000000
+A3CA:00000380044000000C200A20082009200AA00AA00920082008A0086000000000
+A3CB:00000000000000000C200A20082009200AA00AA00920082008A0086000000000
+A3CC:000000000000000010001210112010C01FF010C0112012101000100000000000
+A3CD:0000000000000440028001002288145008201450228801000280044000000000
+A3CE:00000380044000000700088009C00AA00AA00AA00AA009C00880070000000000
+A3CF:00000000000000000700088009C00AA00AA00AA00AA009C00880070000000000
+A3D0:000000000000000000000440044012902AA829282AA812900440044000000000
+A3D1:0000038004400000038004400440038009300550039003900550093000000000
+A3D2:0000000000000000038004400440038009300550039003900550093000000000
+A3D3:000000000000000001E00210021012D00B5006500B5012D0021001E000000000
+A3D4:000000000920054003800380054009200540054001000FE001000FE000000000
+A3D5:000003800440000007C031102D10231021D02130010005400540010000000000
+A3D6:000000000000000003E018881688118810E81098008002A002A0008000000000
+A3D7:00000000000000001E00010009300550039003900550093001001E0000000000
+A3D8:0000038004400000092005400380038005400920010005400540010000000000
+A3D9:0000000000000000092005400380038005400920010005400540010000000000
+A3DA:000000000000000002480248015000E0034002C007000A801240124000000000
+A3DB:0000038004400000062005A004600400052007F00520052007F0052000000000
+A3DC:0000000000000000062005A004600400052007F00520052007F0052000000000
+A3DD:000000000000000000300028262415200CA03FA00620052004A0006000000000
+A3DE:0000038004400000007818800480027802800280027804801880007800000000
+A3DF:0000000000000000007818800480027802800280027804801880007800000000
+A3E0:000000000000000007C0082001000D200B2009A009600100082007C000000000
+A3E1:00000380044000000100010031102C10231020D0203001000100010000000000
+A3E2:0000000000000000008000801888160811881068101800800080008000000000
+A3E3:000000001FF8002000A000A0062005A0046004000480048004001FF800000000
+A3E4:000000000000073004E8042435A00C60042035A00C60042035A00C6000000000
+A3E5:000003800440000008040934092C08200FE00820092069205820402000000000
+A3E6:000000000000000008040934092C08200FE00820092069205820402000000000
+A3E7:00000000000000000EF0010002800FE0028002800FE0028001000EF000000000
+A3E8:00000000101017D0082017D0101011101110101017D0082017D0101000000000
+A3E9:0000038004400000044004401390111011100EE0000001000100010000000000
+A3EA:0000000000000000044004401390111011100EE0000001000100010000000000
+A3EB:00000000000000000F801058136012C0124012401A40166010580F8000000000
+A3EC:00000000000000001110111011100EE000000100010007C00100010000000000
+A3ED:00000380044000001110111011100EE000000100010009000900060000000000
+A3EE:00000000000000001110111011100EE000000100010009000900060000000000
+A3EF:000000000000044004400380111011100EE000000100110011000E0000000000
+A3F0:00000000000007C0082011901150111017D0111015101310082007C000000000
+A3F1:000003800440000001E00200044004A004A004A004A00440020001E000000000
+A3F2:000000000000000001E00200044004A004A004A004A00440020001E000000000
+A3F3:000000000000000003D0043009100A800A800A800A800910042003C000000000
+A3F4:000003800440000010101190115011101110111015101310082007C000000000
+A3F5:000000000000000010101190115011101110111015101310082007C000000000
+A3F6:00000000000000000180016009181100110017C0110011000900010000000000
+A3F7:00000380044000000380026002000A000A000A000A000A000260038000000000
+A3F8:00000000000000000380026002000A000A000A000A000A000260038000000000
+A3F9:0000000000000E0009C00800088008800BE008800880080009C00E0000000000
+A3FA:0000038004400000000801880968111811001700110011000900010000000000
+A3FB:0000000000000000000801880968111811001700110011000900010000000000
+A3FC:0000000000000000003000280024102023E024201CA024A0242013E000000000
+A3FD:000000000380044000000440044002800AA009200AA002800440044000000000
+A3FE:000000000000000000000440044002800AA009200AA002800440044000000000
+A3FF:000000000000000007C00820101010101110111010101010082007C000000000
+A400:000000000000000000003F8020A411240A1807F80A18112420A43F8000000000
+A401:00000380044000000400048804880450042007F80420245014880C8800000000
+A402:00000000000000000400048804880450042007F80420245014880C8800000000
+A403:000000000000000000001100114811480A3007F80A3011481148110000000000
+A404:000000000000000003F00410041003F0001003F000100BF0081007E000000000
+A405:000003800440000010101010101011F010101F101010101011F0101000000000
+A406:000000000000000010101010101011F010101F101010101011F0101000000000
+A407:00000000000000001010101011F010101F10101011F01010082007C000000000
+A408:0000000000000000010011001100111001100110111011001100010000000000
+A409:00000380044000000E00190015001120115017D01150152019000E0000000000
+A40A:00000000000000000E00190015001120115017D01150152019000E0000000000
+A40B:000000000000000007C00920111010101010101012901450082007C000000000
+A40C:00000000000000000700088008F0088008F0088008F008800880070000000000
+A40D:000003800440000007C00820101010101010101010101110092007C000000000
+A40E:000000000000000007C00820101010101010101010101110092007C000000000
+A40F:000000000000000000100810101010900E90109010100B1000D0003000000000
+A410:000003800440000007C008201010101010101010101012900AA007C000000000
+A411:000000000000000007C008201010101010101010101012900AA007C000000000
+A412:0000000000000000010011180928054803880388054809281118010000000000
+A413:0000038004400000082008200440038001000D000B0008000800080000000000
+A414:0000000000000000082008200440038001000D000B0008000800080000000000
+A415:00000000000009200AA009200440038001000D000B0008000800080000000000
+A416:0380044000001830145013901390155019300100092005400380054009200000
+A417:0000000018301450139013901550193001000920054003800540092000000000
+A418:0000000000000000082008200440038009200920038004400820082000000000
+A419:0000038004400000044004401FF004400440044004401FF00440044000000000
+A41A:0000000000000000044004401FF004400440044004401FF00440044000000000
+A41B:000000000000180004C01FA00490188000800F801080108010800F8000000000
+A41C:00000000000000000820082004400380010005400540110011000E0000000000
+A41D:0000038004400000183024480440044003800FE0010001000900060000000000
+A41E:0000000000000000183024480440044003800FE0010001000900060000000000
+A41F:0000000000000000092009200440038001000920092009200100010000000000
+A420:0380044000001830044012901290129004401830038004400920092000000000
+A421:0000000000001830044012901290129004401830038004400920092000000000
+A422:000000000000000002080208011008E01400140008E001100208020800000000
+A423:00000000000000000C040AC409B41C8C2A802A8008801C802A802A8000000000
+A424:000003800440000018C016B0118C10807C8010807C8010801080108000000000
+A425:000000000000000018C016B0118C10807C8010807C8010801080108000000000
+A426:0000000000001830044002800280028004401830038004400820082000000000
+A427:00000000000000000FE01010101010100FE0010007000800082007C000000000
+A428:038004400000001007F008800FF0088007F0010001C002A00490049000000000
+A429:000000000000001007F008800FF0088007F0008001C002A00490049000000000
+A42A:0000000000000000000007C0082009200920044009200920082007C000000000
+A42B:0000038004400000008007F00880088007F0008001C002A00490049000000000
+A42C:0000000000000000008007F00880088007F0008001C002A00490049000000000
+A42D:00000000000000003808260821C82538050001403948270821C8203800000000
+A42E:00000380044000000EE00440044004400380010007C001000900060000000000
+A42F:00000000000000000EE00440044004400380010007C001000900060000000000
+A430:000000000AC00AA00F900A800A8000800A800A800F800A800A80008000000000
+A431:00000000000000000FF01080108010800FF00080008008800880070000000000
+A432:000003800440000011101110092007C0010001000100110011000E0000000000
+A433:000000000000000011101110092007C0010001000100110011000E0000000000
+A434:0000000000000000202020203FF82024202420382020202010400F8000000000
+A435:00000000000000001110111011100EE0000009200920092000000FE000000000
+A436:03800440000003800440054005401E50155014F0054005400440038000000000
+A437:00000000000003800440054005401E50155014F0054005400440038000000000
+A438:00000000000007C00820082007C001000FE001000540155010100FE000000000
+A439:0000038004400000066005D00440044007C004400000111011100EE000000000
+A43A:0000000000000000066005D00440044007C004400000111011100EE000000000
+A43B:0000000000000000000060305054489445104214451448905054603400000000
+A43C:000000000380044000006030505448924512421C451248925054603000000000
+A43D:000000000000000000006030505448924512421C451248925054603000000000
+A43E:00000000000000000EE00100028002800EA00BA00AE0028001000EE000000000
+A43F:03800440000001E0020004400440040007E0040004400440020001E000000000
+A440:00000000000001E0020004400440040007E0040004400440020001E000000000
+A441:000000000000000003C00400082008100F90081008200800040003C000000000
+A442:000003800440000000600058004003F8184020404C404B4008C0080000000000
+A443:00000000000000000030002C002001FC0C201020262025A00460040000000000
+A444:00000000000000000F2010D010501020080006000100008010800F0000000000
+A445:038004400000049002A001C001C002A004900080188016801180100000000000
+A446:000000000000049002A001C001C002A004900080188016801180100000000000
+A447:0000000000000000082008200180014001200100010009000500030000000000
+A448:03800440000002C01AA0069002801A8006800080188016801180100000000000
+A449:00000000000002C01AA0069002801A8006800080188016801180100000000000
+A44A:000000000000111011100FE001000FE01110111001000D000B00080000000000
+A44B:000003800440000001800160011801001FF001001FF001001FF0010000000000
+A44C:000000000000000001800160011801001FF001001FF001001FF0010000000000
+A44D:00000000000000000C000B0008C0080008400840084008400800080000000000
+A44E:0000000000000000600612480A50099008100FF0081009901248624600000000
+A44F:0000038004400000088608880890081008100FF0081049902A481A4600000000
+A450:0000000000000000088608880890081008100FF0081049902A481A4600000000
+A451:0000000000000000610C11100920082008200FE0082009201110610C00000000
+A452:03800440000003800440092009200440038000000FF00060018006000FF00000
+A453:0000000003800440092009200440038000000FF00060018006000FF000000000
+A454:00000000082028282448238810100FE0210821083FF821082108010000000000
+A455:0000000000000000311809200540054005400540054005400920311800000000
+A456:00000380044000000D200BA0096001000D200BA0096001001900070000000000
+A457:00000180016001000D200BA0096001000D200BA0096001001900070000000000
+A458:000000000000000003800440044008200820082008200920092006C000000000
+A459:000000000000000007C00820111011101FF0111011101010082007C000000000
+A45A:0000038004400000088008800E8009C008B00880089008900890088000000000
+A45B:0000000000000000088008800E8009C008B00880089008900890088000000000
+A45C:0000000000000000008007F008800880088007F0008000900090009000000000
+A45D:00000000000000001110111011100EE000000440028001000280044000000000
+A45E:00000000038004400000110811080A080A0804680A580A401140114000000000
+A45F:00000000000000000000110811080A080A0804680A580A401140114000000000
+A460:00000000000006200920062000200620092006200020062001A0006000000000
+A461:00000000000000001110111011100EE004400540038001000900060000000000
+A462:00000380044000001110111011100EE004400440044015401540088000000000
+A463:00000000000000001110111011100EE004400440044015401540088000000000
+A464:000000000000000000002208220814681458084014E0144022E0224000000000
+A465:00000380044000000920092004400380044008200FE008200440038000000000
+A466:00000000000000000920092004400380044008200FE008200440038000000000
+A467:000000000000111011100EE0000004400380000014501390082007C000000000
+A468:00000380044000000660055004C804400E40154015400E400440044000000000
+A469:00000000000000000660055004C804400E40154015400E400440044000000000
+A46A:00000000000000001860165811C6104096405A4032405A409640104000000000
+A46B:000000000000000004400440038001000D200BA00960010001000FE000000000
+A46C:00000380044000000100010031102D10231021D0213001000100010000000000
+A46D:00000000000000000080008018881688118810E8109800800080008000000000
+A46E:00000000000000000220022001C018881688118810E810980080008000000000
+A46F:0000038004400000111011101110092007C031102D10231021D0213000000000
+A470:0000000000000000088808880888049003E018881688118810E8109800000000
+A471:0000000000000000000800C800A8009800801F8024803F8024801F8000000000
+A472:000003800440000028F029083A04280428040004000403840264021800000000
+A473:000000000000000028F029083A04280428040004000403840264021800000000
+A474:0000000000000180016001000920054003800540092001000D00030000000000
+A475:0000000000000000000400640054004C0FC038E01540154038E007C000000000
+A476:00000380044000000010031002D0023002001FC002001FC00200020000000000
+A477:00000000000000000010031002D0023002001FC002001FC00200020000000000
+A478:000001C00130010007C00920155013901550092007C001001900070000000000
+A479:000000000000000012C012B00C8000C00CB0128012C000B00680018000000000
+A47A:00000380044000000CC012B012801E80128012E00C9000900690018000000000
+A47B:00000000000000000CC012B012801E80128012E00C9000900690018000000000
+A47C:00000000000002000FA0022000200FA0106010001F00102010400F8000000000
+A47D:00000000000000000CC012B012800080128012800C8000800680018000000000
+A47E:000003800440000003D00430081008000F80080008000810042003C000000000
+A47F:000000000000000003D00430081008000F80080008000810042003C000000000
+A480:000000000000000008200820044003800120014001800110011000E000000000
+A481:000000000180016001000D200BA00960010007C001000D000B00080000000000
+A482:0380044000001110111017D011101110082007C00100111011100EE000000000
+A483:0000000000001110111017D011101110082007C00100111011100EE000000000
+A484:00000000000000000020092009200FE0092009200020062001A0006000000000
+A485:0380044000000180016001000D200BA00960010007C001000D00030000000000
+A486:0000000000000180016001000D200BA00960010007C001000D00030000000000
+A487:000000000000092009200440038000000FE00000038004400920092000000000
+A488:00000380044000000040004003C0044008400840044003C00040004000000000
+A489:00000000000000000040004003C0044008400840044003C00040004000000000
+A48A:000000000000000000F00700090010801070108009000700010000F000000000
+A48B:038004400000393805400540393801001FF00100393805400540393800000000
+A48C:000000000000393805400540393801001FF00100393805400540393800000000
+A48D:00007FFE61B66DB661866DF66DF67FFE7FFE738E6DB673B66DB6738E7FFE0000
+A48E:00007FFE61B66DB661866DF66DF67FFE7FFE73866DBE738E6DBE73867FFE0000
+A48F:00007FFE61B66DB661866DF66DF67FFE7FFE73866DBE738E6DBE73BE7FFE0000
+A490:0000000000000000010001000100010001000100010001000100010000000000
+A491:000000000000000000400040004000400040004000400C40034000C000000000
+A492:0000000000000000040004000400040004000400040004600580060000000000
+A493:0000000000000000060005800460040004000400040004000400040000000000
+A494:0000000000000000018001600100010001000100010001000D00030000000000
+A495:00000000000000000020062005A0046004000400040004000400040000000000
+A496:00000000000000000040004000400040004000400C400B4008C0080000000000
+A497:000000000000000001800160011801000100010031002D002300200000000000
+A498:000000000000000000C800A80098008000800080008018800680018000000000
+A499:0000000000000000180816081188106810180000000000000000000000000000
+A49A:000000000000000003C00420040004000200018000400020042003C000000000
+A49B:0000000000000000004000400040034002C00200020002000200020000000000
+A49C:000000000000000003C00420081000100010001000100E100990086000000000
+A49D:000000000000000003D00430081008000800080008000810042003C000000000
+A49E:00000000000000000E2009A008600800080008000800086009A00E2000000000
+A49F:000000000000000001E00200040004000400040004000400020001E000000000
+A4A0:00000000000000000FC0002000200020002000200020002000200FC000000000
+A4A1:0000000000000000082008200440038000000000000000000000000000000000
+A4A2:0000000000000000000000000000000000000000038004400820082000000000
+A4A3:0000000000000000180806080188006800180000000000000000000000000000
+A4A4:000000000000000010101010101010101010101010101010082007C000000000
+A4A5:0000000000000000086008800880088008800880088008800880070000000000
+A4A6:0000000000000000183024480440044004400440044004400440038000000000
+A4A7:000000000000000003800440044008200820082008200920092006C000000000
+A4A8:000000000000000007C00820101010101010101010101010082007C000000000
+A4A9:0000000000000000038004400440044004400440044004400440038000000000
+A4AA:00000000000000000FE01010101010100FE00000000000000000000000000000
+A4AB:000000000000000001000280044008200FE00000000000000000000000000000
+A4AC:000000000000000000C000A00090008007800880108010800880078000000000
+A4AD:000000000000000000C000A00090008007C008A0109010800880078000000000
+A4AE:0000000000000000000800C800A8009807800880108010800880078000000000
+A4AF:0000000000000000002000200020002001E0022004200420022001E000000000
+A4B0:000000000000000003C004000400020001C0020004000400040003C000000000
+A4B1:0000000000000000078000400040008007000080004000400040078000000000
+A4B2:000000000000000003E00400040003E00400040003E00400040003E000000000
+A4B3:00000000000000001110111011100EE000000000000000000000000000000000
+A4B4:0000000000000000444444444C64345804400440038000000000000000000000
+A4B5:00000000000000001C7008200820044003800000000000000000000000000000
+A4B6:00000000000000004444444444443BB800000000000000000000000000000000
+A4B7:0000000000000000183024480440044003800000000000000000000000000000
+A4B8:00000000000000000710089008A007C000800080008000800C80030000000000
+A4B9:00000000000000000E20112011400F800100010001000120012000C000000000
+A4BA:000000000000000007900860086007A00020002007A008600860079000000000
+A4BB:000000000000000000200020002000200020022005200520032004C000000000
+A4BC:0000000000000000000004400440028002800100028002800440044000000000
+A4BD:00000000000000000C6002800100028002800440044008200820082000000000
+A4BE:0000000000000FE00820044002800280010002800280044008200FE000000000
+A4BF:0000000000000000000030182828244822882108228824482828301800000000
+A4C0:0000000000000000000010180828044802880108028804480828101800000000
+A4C1:0000000000000000000030182828244802880108028804480828101800000000
+A4C2:00000000000000000000190C251422241D4400841D4422242514190C00000000
+A4C3:0000000000000FE0082004400440028002800100028002800440044000000000
+A4C4:00000000000000000FE001000100010001000100010001000100010000000000
+A4C5:00000000000000001FC002200210020002000200020002000200020000000000
+A4C6:0000000000000000000004400440044000000000000000000000000000000000
+A4C7:00007FFE61B66DB661866DF66DF67FFE7FFE71866FF66FEE6FDE71DE7FFE0000
+A4C8:00007FFE61B66DB661866DF66DF67FFE7FFE71CE6FB66FCE6FB671CE7FFE0000
+A4C9:00007FFE61B66DB661866DF66DF67FFE7FFE71CE6FB66FC66FF671CE7FFE0000
+A4CA:00007FFE61B66DB661866DF66DF67FFE7FFE71866FB66F866FB671B67FFE0000
+A4CB:00007FFE61B66DB661866DF66DF67FFE7FFE718E6FB66F8E6FB6718E7FFE0000
+A4CC:00007FFE61B66DB661866DF66DF67FFE7FFE71C66FBE6FBE6FBE71C67FFE0000
+A4CD:00007FFE61B66DB661866DF66DF67FFE7FFE718E6FB66FB66FB6718E7FFE0000
+A4CE:00007FFE61B66DB661866DF66DF67FFE7FFE71866FBE6F8E6FBE71867FFE0000
+A4CF:00007FFE61B66DB661866DF66DF67FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+A4D0:000000007C4242427C424242427C0000
+A4D1:000000007C4242427C40404040400000
+A4D2:0000000202023A4642424242463A0000
+A4D3:00000000784442424242424244780000
+A4D4:000000007F0808080808080808080000
+A4D5:000000000808080808080808087F0000
+A4D6:000000003C424240404E4242463A0000
+A4D7:00000000424448506060504844420000
+A4D8:000000004222120A06060A1222420000
+A4D9:00000000040404040404044444380000
+A4DA:000000003C42424040404042423C0000
+A4DB:000000003C42420202020242423C0000
+A4DC:000000007E02020408102040407E0000
+A4DD:000000007E4040407C40404040400000
+A4DE:0000000002020202023E0202027E0000
+A4DF:00000000424266665A5A424242420000
+A4E0:0000000042626252524A4A4646420000
+A4E1:000000004040404040404040407E0000
+A4E2:000000003C424240300C0242423C0000
+A4E3:000000007C4242427C48444442420000
+A4E4:0000000042422222123E4242423E0000
+A4E5:00000000080814142222224141410000
+A4E6:00000000414141222222141408080000
+A4E7:00000000424242427E42424242420000
+A4E8:000000005C62424272020242423C0000
+A4E9:00000000384444404040404040400000
+A4EA:00000000424242425A5A666642420000
+A4EB:00000000424224241818242442420000
+A4EC:00000000414122221408080808080000
+A4ED:000000003E424242423E4242423E0000
+A4EE:0000000018242442427E424242420000
+A4EF:00000000424242427E42422424180000
+A4F0:000000007E4040407C404040407E0000
+A4F1:000000007E0202023E020202027E0000
+A4F2:00000000080808080808080808080000
+A4F3:000000003C42424242424242423C0000
+A4F4:000000004242424242424242423C0000
+A4F5:000000003C4242424242424242420000
+A4F6:000000007E0202020202020202020000
+A4F7:000000001E22424242424242221E0000
+A4F8:00000000000000000000000018180000
+A4F9:00000000000000000000000018080810
+A4FA:00000000000000000000000066660000
+A4FB:00000000000000000000000066620204
+A4FC:00000000000018180000001808081000
+A4FD:00000000000018180000001818000000
+A4FE:00000000000000000070000006060000
+A4FF:000000000000007E0000007E00000000
+A500:0000000000000FE00100010001001930254825481930010001000FE000000000
+A501:0000000000000FE001000FE0010019302548193001000FE001000FE000000000
+A502:000000000000242024401A800100010002000200022001480090016000000000
+A503:0000000000003E0008000800046003A0012001E000200020002000F800000000
+A504:0000000000003E0008003E00046003A0012001E0002000F8002000F800000000
+A505:0000000000003838444447C44544393801000380044004400440038000000000
+A506:0000000000000380044004400440139001003938454447C44444383800000000
+A507:00000000000004200860086004A003200020002000200020002000F800000000
+A508:00000000000004200860086004A003200020002000A80020002000F800000000
+A509:0000000000001FF0010001000540010001000100010001000100010000000000
+A50A:0000000000001FF0010001000540010001000FE0010001000100010000000000
+A50B:0000000000001FF0010001000100010001000100010001000100010000000000
+A50C:000000000000038004400440044003800100010001000100010007C000000000
+A50D:0000000000000380044004400440038001000100010007C0010007C000000000
+A50E:000000000000124012400DC00040004000400078004000400040007800000000
+A50F:000000000000124012400DF80040004000400078004000400040007800000000
+A510:00000000000049004900370001000150015403A8050009000900060000000000
+A511:00000000000049004900372001000150015403A8050009200900060000000000
+A512:000000000000124012400DC00040004000480078004800400040004000000000
+A513:000000000000124012400DC0004000480078004800400040071008E000000000
+A514:00000000000006180A2812482288020802080208020802080208020800000000
+A515:0000000000001F800080008000800080008007F8088808880888070800000000
+A516:0000000000000920092009200920092009200920092009200920092000000000
+A517:00000000000009200920092009200920092009200920092000000FE000000000
+A518:0000000000001010101010100000010001000100000010101010101000000000
+A519:00000000000010101FF010100000010001000100000010101FF0101000000000
+A51A:000000000000000000001C703EF83EF83EF83EF83EF81C70482437D800000000
+A51B:000000000000000000001C70228822882288228822881450482437D800000000
+A51C:00000000000000002000204020003FE020083FE0200020402000000000000000
+A51D:000000000000000020002000204020003FE82000204020002000000000000000
+A51E:000000000000A00AA00AA00AA44AAAAAAAAAAAAAA44AFBBEA00AA00A00000000
+A51F:0000000000002008200820082C68329821082288228822882108200800000000
+A520:000000000000042004200420042004203FFC0420042004200420042000000000
+A521:000000000000062009600A6004A0032000200020002000200020007800000000
+A522:0000000000000810142822440990024002400240024002400240018000000000
+A523:000000000000082000001C70228822882288228822881450482437D800000000
+A524:000000000000124012400DC0004000480078004800400040004001F000000000
+A525:000000000000124012400DC000500044007C004400500040004001F000000000
+A526:000000000000124012400DC00040044407FC044400400040004001F000000000
+A527:000000000000000003800440004001800240024001800200022001C000000000
+A528:000000000000124012400DC00040124012400DC0007000C80548023001000000
+A529:000000000000124012400DC00040124012400DC0007000CA0532020C01000000
+A52A:0000000000000E000F800FE00F800E000C000E000F800FE00F800E0000000000
+A52B:000000000000308C49523E3C0410041004100410041004100808100400000000
+A52C:0000000000000E001100110011100A100FF00A101110110011000E0000000000
+A52D:0000000000000E001100110011500A100FF00A101150110011000E0000000000
+A52E:00000000000003800D6011101390244824482388145018300C60038000000000
+A52F:0000000000003FF801000100054001000FE00100054001000100010000000000
+A530:000000000000010001000100054001003FF80100054001000100010000000000
+A531:0000000000001110111011101EE01000100010001110111011100EE000000000
+A532:00000000000000C00100111011101EE01000111011100EE00080030000000000
+A533:000000000000121012200DC00080008001100100012401040088007000000000
+A534:000000000000121012200DC00088008001100100012401040088007000000000
+A535:00000000000008000800080009E00A500C900860080008000800080000000000
+A536:00000000000008000A00080009E00A500C9008600A0008000800080000000000
+A537:00000000000000000000018003C007E007E003C0018000000000000000000000
+A538:00000000000000000000018003C007E007E003C001800000071008E000000000
+A539:00000000000000000000018003C007E017E803C0018000000000000000000000
+A53A:00000000000001000200010044A245223BDC0100008001000200010000000000
+A53B:0000000000001C0022002200222814281FE814282228220022001C0000000000
+A53C:0000000000001C002200220022A814281FE8142822A8220022001C0000000000
+A53D:0000000000000060018006000180186024101860018006000180006000000000
+A53E:0000000000000060018006000180186024141860018006000180006000000000
+A53F:00000000000003E004000FC008000800080009800A400C400440038000000000
+A540:00000000000000000000000004404C6433980000000000000000000000000000
+A541:0000000000000000000004400000000004404C64339800000000000000000000
+A542:00000000000000000100000004404C6433980000000001000000000000000000
+A543:00000000000001000200040004000800080009C00A200C20042003C000000000
+A544:00000000000001000200040004000800080009C00A200CA0042003C000000000
+A545:000000000000248024801B80008000A8008801F8028804A80480030000000000
+A546:0000000000000738084010801080210021002100108010800840073800000000
+A547:00000000000007E0001007E00400043005D00610001003F0040003F000000000
+A548:00000000000000800080008000800080008007F8088808880888070800000000
+A549:0000000000000380044004400440038001000540010005400100010000000000
+A54A:00000000000000000380044004400440044004402288210812900C6000000000
+A54B:00000000000000000380044004400444044004402288210812900C6400000000
+A54C:000000000000442244224E7235AC042004200420042004200420042000000000
+A54D:00000000000000000100444444444EE437D80440044005400440044000000000
+A54E:000000000000121012200DC00080008001000100010401040088007000000000
+A54F:000000000000248024801B8000800080008000B000C8008000B000C800000000
+A550:000000000000222022201DE00020002000A80020002000200020002000000000
+A551:000000000000380E44104220424032400FF0024C024204420822701C00000000
+A552:0000000000003FE020202020203C202422242024203C202020203FE000000000
+A553:00000000000000003FF02088208824B0208020803FF000080008003000000000
+A554:00000000000001000100028002800440044008200820101010101FF000000000
+A555:0000000003800C6018301450228821082288145018300C600380000000000000
+A556:00000000000001000100028012900440044008200820101010101FF000000000
+A557:0000000000000FC008200810081008200FC008200810081008200FC000000000
+A558:00000000000003C00420082001C001000100010001C00820042003C000000000
+A559:00000000000010F011081208107010401FC0104010701208110810F000000000
+A55A:0000000000001110111013900D60010001000100010001000100010000000000
+A55B:00000000000017D0111013900D6001000100010001000100010007C000000000
+A55C:0000000000000008010800081108110812980C68000801080008000800000000
+A55D:00000000000000140214001422142214253418D4001402140014001400000000
+A55E:0000000000000A000A000A000BF00A000A000BF00A000A000A000A0000000000
+A55F:0000000000000A000A000A000BF00A000A000BF00A000200071008E000000000
+A560:0000000000000030000800083FF02220222022202220222022203FE000000000
+A561:0000000000000030008800083FF02220222422202220222022203FE000000000
+A562:0000000000000EE01110111011100FE003800440044004400380000000000000
+A563:0000000000000EE01110111011100FE003800440044014500380000000000000
+A564:000000000000000000000EE0111011100FE0111011100EE00000000000000000
+A565:000000000000010000000EE0111011104FE4111011100EE00000010000000000
+A566:000000000000003001C006401880010007001930014801880088007000000000
+A567:0000000000001FF0038003800540054009200920111011102108210800000000
+A568:0000000000000EE0111011101FF0038005400540092009201110111000000000
+A569:000000000000121012200DC00080488049003700010401040088007000000000
+A56A:00000000000004000800086004A0032000200020002000200020002000000000
+A56B:0000000000000E00110011000100010002000C3810443FC40044003800000000
+A56C:0000000000001FF022882288228822881FF022882288228822881FF000000000
+A56D:000000000000442244224E7235AC042004200420442244224A52318C00000000
+A56E:0000000000003018482444443FF8044004400440044008200820101000000000
+A56F:0000000000000FE00100010001000100010001000100010001000FE000000000
+A570:000000000000444044403BC000400040007C0044004400440044007C00000000
+A571:00000000000010001F8010800080008800F8008800800080008001C000000000
+A572:00000000000010001F80108000A0008800F8008800A00080008001C000000000
+A573:00000000000010001F801080008008880FF8088800800080008001C000000000
+A574:0000000000001C0008000800080008080FF8008800800080008001C000000000
+A575:0000000000001C0008000800082008080FF8008800A00080008001C000000000
+A576:0000000000000390045008300810040003800040002008200C400B8000000000
+A577:0000000000000390045009300810040003800040002009200C400B8000000000
+A578:0000000000000000006001900610186010001200106011901610186000000000
+A579:000000000000000000000000381C7C3E7FFE7C3C381C00000000000000000000
+A57A:0000000000000100028002800440044008200440044002800280010000000000
+A57B:0000000000000100028002800440044028280440044002800280010000000000
+A57C:000000000000002000200FE0082008200820082008200FE00020002000000000
+A57D:0000000000002108210823881D70010001000FE0010001000100010000000000
+A57E:0000000000002108210823881D70010001000FE001000FE00100010000000000
+A57F:00000000000000E011000200020002001200020002000200110000E000000000
+A580:00000000000000E011000200020002001220020002000200110000E000000000
+A581:000000000000442244224E7235AC0420042004200420042004200E7000000000
+A582:000000000000442244224E7235AC0420042004A00420042004200E7000000000
+A583:000000000000248024801B80009800A800C80188028004800480030000000000
+A584:000000000000248024981BA800C8018802800480048003001C40238000000000
+A585:0000000000000FE001004104410441047FFC41044104410401000FE000000000
+A586:000000000000248024801B800080008000F001A802A804900480030000000000
+A587:000000000000222022202220222022203FE0002000200020002000F800000000
+A588:000000000000222022202220222022203FE00020002000A8002000F800000000
+A589:0000000000000380044004400440028001000280044004400440038000000000
+A58A:0000000000000380044014500440028001000280044014500440038000000000
+A58B:0000000000000100010001000920010001000100092001000100010000000000
+A58C:0000000000000100010001000100010009200100010001000100010000000000
+A58D:0000000000001040104010401040104012481040104010401040104000000000
+A58E:0000000000000400040004000480040004000400048004000400040000000000
+A58F:0000000000003018482444443FF80440044004400440082008201FF000000000
+A590:0000000000003018482444443FF8044004400440082008281FF8000800000000
+A591:0000000000003F800080008007F8008800880088008800880008000800000000
+A592:00000000000000000000010038387C7C7FFC7C7C383801000000000000000000
+A593:0000000000004900490037200100017801840324050809000900060000000000
+A594:0000000000000FE00100010009200100010001000920010001000FE000000000
+A595:0000000000002108210823881D700100010005F4001000100010001000000000
+A596:0000000000004210421047103AE0020002000BE8002000F8002000F800000000
+A597:0000000000004210421047103AE00200020003E000200020002000F800000000
+A598:00000000000003800C6010101390244824482288911292924C64339800000000
+A599:0000000000002108210823881D700100010001F0001000100010001000000000
+A59A:0000000000004210421047103AE00200020003E0002000F8002000F800000000
+A59B:0000000000000420042004203FFC0420042004203FFC04200420042000000000
+A59C:0000000000003838444444444444383800000380044004400440038000000000
+A59D:0000000000000E001100110011000A0007F00A081108111011000E0000000000
+A59E:0000000000000E001100110011400A0007F00A081148111011000E0000000000
+A59F:000000000000100029082B881D700100010001000100010001000FE000000000
+A5A0:000000000000100029082B881D700100010001000540010001000FE000000000
+A5A1:000000000000101029282BA81D700100010001000100010001000FE000000000
+A5A2:0000000000000060008001003938454447C445443938010002000C0000000000
+A5A3:000000000000001800200040385C446247E246623A5C024004801B0000000000
+A5A4:000000000000070008800880088007000240020003E002000240020000000000
+A5A5:0000000000000E001100110011000E0004A0042007E0042004A0040000000000
+A5A6:0000000000001130115011501190119011101310131015101510191000000000
+A5A7:0000000000001130115011501190119051141310131015101510191000000000
+A5A8:000000000000000000001000100010001FF01008100810080030000000000000
+A5A9:0000000000001000100010001FF010081008100800300000071008E000000000
+A5AA:000000000000000000001000120010001FF01008120810080030000000000000
+A5AB:000000000000000000001000100010001FF01008100810480070004000000000
+A5AC:0000000000000C30145004100410041000000080008000800080008000000000
+A5AD:0000000000000C30145004100410041000000080008002A00080008000000000
+A5AE:0000000000000C3014500410041004100000008000800080008003E000000000
+A5AF:0000000000000C30145004100410041000000080008002A0008003E000000000
+A5B0:000000000000000000001100150011001FF01108150811080030000000000000
+A5B1:000000000000000000001100110011001FF01108110811080030000000000000
+A5B2:000000000000000000001500150015001FF01508150815080030000000000000
+A5B3:000000000000000000001400150014001FF01408150814080030000000000000
+A5B4:00000000000003800C6010101010200821082008101010100C60038000000000
+A5B5:000000000000038004400540044003800100010005400100010007C000000000
+A5B6:000000000000038004400540044003800100010001000100010007C000000000
+A5B7:00000000000004000860086004A0032004200420042004200420042000000000
+A5B8:0000000000001FF0111011101110111011F011101110111011101FF000000000
+A5B9:0000000000000820082008200920082008200920082008200440038000000000
+A5BA:000000000000111011101EE01000111011101EE01000111011100EE000000000
+A5BB:0000000000003838044002800280028022900280028002800440383800000000
+A5BC:0000000000003938044002800280028002800280028002800440393800000000
+A5BD:00000000000022301DD022301DD022301DD00010001000100010007C00000000
+A5BE:0000000000007C7C044004400440044007C004400440044004407C7C00000000
+A5BF:000000000000111011100EE00000111011100EE00000111011100EE000000000
+A5C0:00000000000022301DD022301DD022301DD000100010007C0010007C00000000
+A5C1:000000000000000000000000381C442247E246623A5C024004801B0000000000
+A5C2:00000000000000D8012002403A5C466247E246623A5C024004801B0000000000
+A5C3:0000000000000030004800880110020007000F801FC00F800700020000000000
+A5C4:0000000000000030004800880110124007000F801FC00F800700020000000000
+A5C5:000000000000221022301DD00010221022301DD0001000100010007C00000000
+A5C6:000000000000221022301DD00010221022301DD0001000540010007C00000000
+A5C7:0000000000000FE002800280044004400820482430181FF00820044000000000
+A5C8:00000000000007C0000007C001000280044028285FF428281450082000000000
+A5C9:000000000000000003C004200FF0042003C004200420042003C0000000000000
+A5CA:000000000000000003C004200FF0042003C004200FF0042003C0000000000000
+A5CB:0000000000001FF010001000100010001FF010001000100010001FF000000000
+A5CC:000000000000124012400DC000480050006000C0014002400240018000000000
+A5CD:0000000000001FF010001080100010001FF010001080100010001FF000000000
+A5CE:000000000000124012400DC000480050006004C8014002400240018000000000
+A5CF:000000000000000003C004200400040003C004200420042003C0000000000000
+A5D0:00000000000003C004200400040003C00420042003C00000071008E000000000
+A5D1:0000000000000C6012902108228802800280010001000100010007C000000000
+A5D2:0000000000000C6012902108228802800280010001000540010007C000000000
+A5D3:00000000000000E001300230020002E0033002300200020002000F8000000000
+A5D4:00000000000000E001300230020002E00B3402300200020002000F8000000000
+A5D5:00000000000000E001300230020002E00330023002000F8002000F8000000000
+A5D6:00000000000000E001300230020002E00B34023002000F8002000F8000000000
+A5D7:00000000000003E00210021003E00210021003E002000A8002000F8000000000
+A5D8:00000000000007F00508050805F00508050805F00500050005001FC000000000
+A5D9:00000000000007F00508050805F00508050805F00500154005001FC000000000
+A5DA:000000000000000003E004100490041003E004100490041003E0000000000000
+A5DB:00000000000001E006100860080009C00E2008C0080008F00B080C3000000000
+A5DC:00000000000000000000044040044444644C5BB4400444200000000000000000
+A5DD:0000000000000000010000000380044008200820082004400380101000000000
+A5DE:0000000000001FF00000038004400820082008200440038000001FF000000000
+A5DF:00000000000003D00450087008500400038000400A200A200E400B8000000000
+A5E0:0000000000003870448842840204020407F808101020204059B266CC00000000
+A5E1:000000000000044004A004A004A004C807500C20145014501450082000000000
+A5E2:000000000000000000020002309248924C924B6E300200020002000000000000
+A5E3:0000000000003E100808083408C00B000C000B0008C0083408083E1000000000
+A5E4:000000000000084014A014A014A008C8155026200A500A500A50042000000000
+A5E5:000000000000084014A014A014A048CA155026200A500A500A50042000000000
+A5E6:0000000000000C6012902108228802800280010001000120012000C000000000
+A5E7:0000000000000C6012902108228802800280010001000128013000C000000000
+A5E8:00000000000000C003000C00030000C0002000C003000C00030000C000000000
+A5E9:00000000000000C003000C00030000C0082400C003000C00030000C000000000
+A5EA:00000000000010E011001200120012001200120012001200110010E000000000
+A5EB:0000000000001070148011001100110011001100110011001480107000000000
+A5EC:000000000000000000000000381C442247E24422381C00000000000000000000
+A5ED:000000000000000000000000381C442247E24422381C00000240000000000000
+A5EE:0000000000000000000001003838444447C44444383801000000000000000000
+A5EF:000000000000000C0014002470444C8443844264441C48005000600000000000
+A5F0:000000000000000C0114002470444C8443844264441C48005100600000000000
+A5F1:00000000000000F0030804300800080008000800080008F00B080C3000000000
+A5F2:00000000000000F0030806300A000A000A000A000A000AF00B080C3000000000
+A5F3:000000000000038004400440428441047FFC4104428404400440038000000000
+A5F4:000000000000038004400440529441047FFC4104529404400440038000000000
+A5F5:000000000000000003C014281FF8142803C014281FF8142803C0000000000000
+A5F6:000000000000000003C044227FFE442213C844227FFE442203C0000000000000
+A5F7:0000000000001010101010101010101000000100010001000100010000000000
+A5F8:000000000000101010101010101001000100010001000000071008E000000000
+A5F9:0000000000001010101010101010101000000100010009200100010000000000
+A5FA:0000000000000100010001001110101010101010111001000100010000000000
+A5FB:0000000000000100010001000100454445443BB8010001000100010000000000
+A5FC:0000000000000100010001000100454445443BB8010011100100010000000000
+A5FD:0000000000000100010011100100454445443BB8010011100100010000000000
+A5FE:00000000000007C0010011100100454405443BB801001110010007C000000000
+A5FF:0000000000000F00108020800700040007F804000700208010800F0000000000
+A600:0000000000000F00108020800720040007E804000720208010800F0000000000
+A601:0000000000000F00108020800728040807F804080728208010800F0000000000
+A602:0000000000000F00108020880708040807F804080708208810800F0000000000
+A603:0000000000002108210813900D6001000100010001000100010007C000000000
+A604:0000000000002108210813900D6001000100010005400100010007C000000000
+A605:0000000000002108210813900D60010001000540010007C0010007C000000000
+A606:0000000000002108210813900D6001000100010007C00100010007C000000000
+A607:0000000000002108210813900D60010001000100010009200FE0082000000000
+A608:0000000000001248124812481248124812481248124812481248124800000000
+A609:0000000000001EF00100028002800280028002800280028001001EF000000000
+A60A:0000000000002108210813900D600100010001F0015001F0015001F000000000
+A60B:000000000000121012200DC00080008001000138014401440088007000000000
+A60C:0000000000000000000000003FFC0000000000003FFC00000000000000000000
+A60D:0000000000000000000000000000000001000100028002800440044000000000
+A60E:000000000000000000000420024001800FF00180024004200000000000000000
+A60F:0000000000000000000000000000000000003A884694438452C422B800000000
+A610:00000000000001C002200410641064161C1E04100410041002D601CE00000000
+A611:000000000000111011100EE004400440044004400440155015500EE000000000
+A612:000000000000060C183060C01830060C01FE060C183060C01830060C00000000
+A613:00000000000003C004200400040004000380040004000400042003C000000000
+A614:000000000000222022601DA00020002000E40138002000200020002000000000
+A615:0000000000000014071408940894089445144214251418FC0014001400000000
+A616:0000000000000FE00820092008200820092008200820092008200FE000000000
+A617:0000000000000218022802480288020802080208220812080A08060800000000
+A618:00000000000003700D983118010001700198011801000100010007C000000000
+A619:0000000000000FE001000100010001F0010801080130010001000FE000000000
+A61A:0000000000001110000019982220222022202220222019980000111000000000
+A61B:000000000000121012200DC0008000800100010001FC01040088007000000000
+A61C:0000000000003FF8210811101110092009200540054003800380010000000000
+A61D:0000000000000FF008900C900B600800080008000800080008003E0000000000
+A61E:000000000000442044603BA000240020003E0020002400200020002000000000
+A61F:0000000000001C00220022001C6008900510031004E004000200018000000000
+A620:000000000000111011100EE0000007C00820101010101010082007C000000000
+A621:0000000000000080008000800080008000800080008000800080008000000000
+A622:0000000000000380044004400380010005400100054001000164019800000000
+A623:0000000000003800440047804440384003800040004003800200020000000000
+A624:0000000000000C000A00090008000900090009000FE001200120012000000000
+A625:0000000000000C000A00090008000800080009C00A200C100C10082000000000
+A626:00000000000001C002001F8004000400040004C005200620022001C000000000
+A627:0000000000000CC01340004000400040004000E001100110011000E000000000
+A628:00000000000004200000000004200420042003C004200420042003C000000000
+A629:0000000000000070008800880C701220114011800E4000400080030000000000
+A62A:0000000000003018482444443FF8044004400440044048242828101000000000
+A62B:000000000000038004400440044003800100010001000110011000E000000000
+A62C:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE61C67DBE61BE6FBE61C67FFE0000
+A62D:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE618E7DB661B66FB6618E7FFE0000
+A62E:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE61867DBE618E6FBE61867FFE0000
+A62F:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE61867DBE618E6FBE61BE7FFE0000
+A630:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE63CE7DB671B67DB663CE7FFE0000
+A631:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE63EE7DCE71EE7DEE63C67FFE0000
+A632:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE63867DF671867DBE63867FFE0000
+A633:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE638E7DF671C67DF6638E7FFE0000
+A634:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE63B67DB671867DF663F67FFE0000
+A635:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE63867DBE71867DF663867FFE0000
+A636:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE63CE7DBE718E7DB663CE7FFE0000
+A637:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE63867DF671EE7DDE63DE7FFE0000
+A638:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE63CE7DB671CE7DB663CE7FFE0000
+A639:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE63CE7DB671C67DF663CE7FFE0000
+A63A:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE63867DB671867DB663B67FFE0000
+A63B:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE638E7DB6718E7DB6638E7FFE0000
+A63C:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE63C67DBE71BE7DBE63C67FFE0000
+A63D:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE638E7DB671B67DB6638E7FFE0000
+A63E:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE63867DBE718E7DBE63867FFE0000
+A63F:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE63867DBE718E7DBE63BE7FFE0000
+A640:000000007E02020408102040407E3A44
+A641:0000000000007E0204081020407E3A44
+A642:000000007E020204087C2040407E3A44
+A643:0000000000007E02047E1020407E3A44
+A644:000000003C4242020C304042423C0000
+A645:0000000000003C42020C3040423C0000
+A646:00000000202020202020202024180000
+A647:00000000000020202020202024180000
+A648:00000000103810103844828282820000
+A649:00000000000010381038444444440000
+A64A:000000000000424224183C4A524A423C
+A64B:00000000020244442810282828100000
+A64C:00000000000000003C78428442844004400440044004410442843C7800000000
+A64D:00000000000000000000000030184004400440044004410442843C7800000000
+A64E:00000000205050101E111111111E0000
+A64F:0000000000002050501E1111111E0000
+A650:000000000000000000003C102410241004100790045004500450045007900000
+A651:0000000000000000000000003C10241024100790045004500450079000000000
+A652:00000000507E52505C525252525C0000
+A653:000000000000507E52505C52525C0000
+A654:00000000324A4A4A4E4A4A4A4A320000
+A655:000000000000324A4A4E4A4A4A320000
+A656:000000008894A2A2FEA2A2A2A2A20000
+A657:0000000000004C42424E7252524E0000
+A658:000000001824244242427E42427E0000
+A659:000000000000182442427E42427E0000
+A65A:000000003E222214081C227F49490000
+A65B:0000000000003E22143E417F49490000
+A65C:000000008894A2A2FEA2A2A2A2BE0000
+A65D:000000000000444A51517F51515F0000
+A65E:0000000000000100038005400540092009202910111001000100010000000000
+A65F:0000000000081C2A2AA9490808080000
+A660:00000000000000001080108010801080108010801080108010803FC020002000
+A661:00000000000000000000000000000000088008800880088008801FC010000000
+A662:000000000000000003FC048404840480088008800880108010803FC020402040
+A663:00000000000000000000000007F80488088808801080108010801FC010400000
+A664:00000000000000000FFC08840884088008800880088010801080208000000000
+A665:0000000000000000000000000FF8088808880880088010801080208000000000
+A666:000000000000000021FC2104330433002D002D00210021002100210000000000
+A667:00000000000000000000000021F8330833082D002D0021002100210000000000
+A668:000000003C4242425A5A4242423C0000
+A669:0000000000003C42425A5A42423C0000
+A66A:000000007C82828282AA8282827C0000
+A66B:0000000000003E4141415541413E0000
+A66C:00000000000000001E782184218421842DB42DB42184218421841E7800000000
+A66D:0000000000000000000000001E78218421842DB42DB4218421841E7800000000
+A66E:0E70118815A811880E7039CE463156B5463139CE0E70118815A811880E700000
+A66F:007E4200000000000000000000000000
+A670:0000028001002AA8101028280000A0144008A014000000002828129029280280
+A671:007E420000000000000000000000427E
+A672:0100010007C0010001000000F01E00000000F01E00000000F01E054005400540
+A673:1028EE824482EE281000000000000000
+A674:001C2238221C00000000000000000000
+A675:0022262A322200000000000000000000
+A676:00140008080800000000000000000000
+A677:00221408102000000000000000000000
+A678:0030101C121C00000000000000000000
+A679:004242724A7200000000000000000000
+A67A:00202038243800000000000000000000
+A67B:00545454280000000000000000000000
+A67C:0000423C000000000000000000000000
+A67D:000A0A06020000000000000000000000
+A67E:0000423C000000000000000000000000
+A67F:000A0A06020000000000000000000000
+A680:001010101E1212122222224242FF8181
+A681:0000000010101E1222224242427F4100
+A682:000000003C424240201008040242423C
+A683:00000000182424201010080804242418
+A684:00000000000000003C404246024802503FE004600250024842443C4200000000
+A685:0000000000000000000000003C46424802503FE00450024842443C4200000000
+A686:0000000092929292926E020202020000
+A687:000000000000929292926E0202020000
+A688:000000001C1414142424244649FA8186
+A689:0000000000001C1424244446497A4106
+A68A:00000000FE1010101619111111110502
+A68B:000000000000FE101016191111110502
+A68C:00000000FE10101010101010120C0000
+A68D:000000000000FE1010101010120C0000
+A68E:0000000042424242424242427E39413E
+A68F:0000000000004242424242427E39413E
+A690:000000007F0808080808080808384030
+A691:0000000000007F080808080808384030
+A692:00000000000000003F90249004100410041007F0001000100010001000000000
+A693:0000000000000000000000001FC812480208020803F800080008000800000000
+A694:00000000304840405864424242420000
+A695:00000000000030484040586444440000
+A696:000000009292929292929292FE39413E
+A697:000000000000929292929292FE39413E
+A698:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE73CE6DB671CE7DB673CE7FFE0000
+A699:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE73CE6DB671C67DF673CE7FFE0000
+A69A:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE73866DB671867DB673B67FFE0000
+A69B:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE738E6DB6718E7DB6738E7FFE0000
+A69C:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE73C66DBE71BE7DBE73C67FFE0000
+A69D:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE738E6DB671B67DB6738E7FFE0000
+A69E:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE73866DBE718E7DBE73867FFE0000
+A69F:004C507C504C00000000000000000000
+A6A0:00000000080C0A080808084848300000
+A6A1:000000004246464A4A52526262420000
+A6A2:0000007C007C00384482828244380000
+A6A3:00000000043448485250202040400000
+A6A4:000000000020000020242262528C0000
+A6A5:00000000404040404048407C00080000
+A6A6:000000000020007C02027C0020000000
+A6A7:000000007C0408081010303048460000
+A6A8:000000007E0204040408080808040000
+A6A9:00000000408C92A2A284780000100000
+A6AA:000000001C2222A47820242024200000
+A6AB:00000000103054901050102020200000
+A6AC:00000000401C22222A2A242020200000
+A6AD:0000000002020202027E2212227E0000
+A6AE:00000000405040780404784050400000
+A6AF:00000000001860004860504840400000
+A6B0:00000000704C424C7040404040400000
+A6B1:00000000404040407C40404040400000
+A6B2:00000000928244442828101010100000
+A6B3:000000004444444444444440407E0000
+A6B4:000000008888888A888E505220200000
+A6B5:00000000828282443810101010100000
+A6B6:00000000484848484A48484A48784800
+A6B7:0000000002002C3464A6202820200000
+A6B8:00000000304080988442320204180000
+A6B9:00000000201008041210101010100000
+A6BA:00000000601218244444241810600000
+A6BB:000000004000007848484E4040400000
+A6BC:000000000010C0300C020C30C0100000
+A6BD:00000002040818240202024244380000
+A6BE:00000000505050507C14141414140000
+A6BF:00000000182442422272020204040000
+A6C0:00000000182442427E02020204040000
+A6C1:00000000182442424202020204040000
+A6C2:00000000405E405E4040404040400000
+A6C3:00000000000202020204545428280000
+A6C4:00000000465A62625A46404040400000
+A6C5:0000000008084A485868484840400000
+A6C6:0000000002020202027A0606067A0000
+A6C7:00000002040810204220100804020000
+A6C8:00000000384492925410101010100000
+A6C9:000000007C04080810102020407C0000
+A6CA:0000000010101010242A22524C800000
+A6CB:000000003E1828480808080808080000
+A6CC:00000000100038441804443800100000
+A6CD:0000000070080404083020F820200000
+A6CE:00000000102828284444444482820000
+A6CF:00000000380082C6AAAA920010100000
+A6D0:000000003E4040403E00080808080000
+A6D1:00000000320804040404080810600000
+A6D2:00000000384402020204042810080000
+A6D3:000000001C2222A47820242424240000
+A6D4:00000000101210103854929292920000
+A6D5:00000000605048444040444850600000
+A6D6:00000000404040407848484848440000
+A6D7:00000000385492929280808080800000
+A6D8:00000000C2A29286864A4A5252220000
+A6D9:0000000018284A0C1828480808080000
+A6DA:000000004040404040404840407E0000
+A6DB:000000007E4242424242424242420000
+A6DC:00000000100018244454542404040000
+A6DD:000000003048888A4838080808100000
+A6DE:000000007E0202027E40404040400000
+A6DF:00000000828244444444282828100000
+A6E0:000000003028242224283060A0200000
+A6E1:00000000006294888A7400007E000000
+A6E2:000000201008102020404040221C0000
+A6E3:00000000407C44040404040404040000
+A6E4:000000046211090A0808101020C00000
+A6E5:000000000E1070504E40404040400000
+A6E6:000000003E0808780402020204080000
+A6E7:00000000380808780402020204080000
+A6E8:000000007050501010101010107C0000
+A6E9:00000000080808780402020204080000
+A6EA:00000000182848083C02020204080000
+A6EB:00000000700804040830202020200000
+A6EC:000000001018141210101010107C0000
+A6ED:00000000700804044830282420200000
+A6EE:000000001E1212121212121212720000
+A6EF:000000003844422204182042423C0000
+A6F0:00102844000000000000000000000000
+A6F1:003E0000000000000000000000000000
+A6F2:00000000200008040402020244380000
+A6F3:00000000040408081010242040400000
+A6F4:00000000222222224455448888880000
+A6F5:00000000000000003E08101020200000
+A6F6:0000000000000000F424484A90900000
+A6F7:00000000101010109254381000100000
+A6F8:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+A6F9:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+A6FA:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE61866FB663866FB66FB67FFE0000
+A6FB:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+A6FC:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+A6FD:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE618E6FB663B66FB66F8E7FFE0000
+A6FE:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE61866FBE638E6FBE6F867FFE0000
+A6FF:00007FFE61CE6DBE618E6DB66DCE7FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+A700:0000000000000000001C20201C000000
+A701:0000000000000000001C20201C003C00
+A702:000000001C20201C0000000000000000
+A703:000000001C20201C003C000000000000
+A704:00000000380404380000000000000000
+A705:0000000038040438003C000000000000
+A706:00000000000000000038040438000000
+A707:00000000000000000038040438003C00
+A708:00000000501010101010101010100000
+A709:00000000101050101010101010100000
+A70A:00000000101010105010101010100000
+A70B:00000000101010101010105010100000
+A70C:00000000101010101010101010500000
+A70D:00000000141010101010101010100000
+A70E:00000000101014101010101010100000
+A70F:00000000101010101410101010100000
+A710:00000000101010101010101410100000
+A711:00000000101010101010101010140000
+A712:000000001E1010101010101010100000
+A713:0000000010101E101010101010100000
+A714:00000000101010101E10101010100000
+A715:00000000101010101010101E10100000
+A716:000000001010101010101010101E0000
+A717:00000000101050101000000000000000
+A718:00000000001204081000000000000000
+A719:00000000000010007C00000000000000
+A71A:00000000000004047C00000000000000
+A71B:0000000010387C101010000000000000
+A71C:000000001010107C3810000000000000
+A71D:00000000101010100010000000000000
+A71E:00000000100010101010000000000000
+A71F:00000000000000001000101010100000
+A720:007E5050000000000000000000000000
+A721:00000000000000000000000050507E00
+A722:00007078040438000070780404380000
+A723:00000030380404180030380404180000
+A724:000000003C7E604040404040403E0000
+A725:00000000000000387C604040403C0000
+A726:00000000424242427E4242424242120C
+A727:0000004040405C62424242424242120C
+A728:0000000000003F8004000400040007F8041004200440047004080008010800F0
+A729:0000000000000000080008003FFC080808100820083808040804060400840078
+A72A:000000003C424850304C4040423C0000
+A72B:000000001C22202018202020221C0000
+A72C:00000000040C1424447C040424180000
+A72D:000000000000040C14247C0404042418
+A72E:000000000818284888FE08084B310102
+A72F:00000000000008182848FE080B094932
+A730:0000000000007C404078404040400000
+A731:0000000000003C4240300C02423C0000
+A732:00000000000000000C3012481248218421843FFC218421842184218400000000
+A733:0000000000000000000000001E78218401041F7C21842184238C1D7400000000
+A734:00000000000000000C7812841284218421843F84218421842184217800000000
+A735:0000000000000000000000001E78218401841F842184218423841D7800000000
+A736:00000000000000000C8412841284218421843F84218421842184217800000000
+A737:0000000000000000000000001E84218401841F8421842184238C1D7400000000
+A738:00000000000000000E0812081208211021103F1020A020A02040204000000000
+A739:0000000000000000000000001E08210801081F902190219022601C6000000000
+A73A:00000000000000000E0812081208211021103FF820A020A02040204000000000
+A73B:0000000000000000000000001E08210801081FFC2190219022601C6000000000
+A73C:00000000000000000E0812081208211021103F1020A020A02040204004800300
+A73D:0000000000000000000000001E08210801081F902190219022601C60012000C0
+A73E:000000003C4242021A1A0242423C0000
+A73F:0000000000003C42021A1A02423C0000
+A740:0000000042E448506060504844420000
+A741:0000000040F044485060504844420000
+A742:00000000424448506060544854420000
+A743:00000000404044485060544854420000
+A744:0000000042E448506060544854420000
+A745:0000000040F044485060544854420000
+A746:000000004040404040202020203E0000
+A747:000000001808080808040404041F0000
+A748:0000000040F0404040404040407E0000
+A749:0000000018081C0808080808083E0000
+A74A:000000003C424242FF424242423C0000
+A74B:0000000000003C4242FF4242423C0000
+A74C:0000000275898E888888888888700000
+A74D:00000000000275898E88888888700000
+A74E:00000000000000001E78218421842184218421842184218421841E7800000000
+A74F:0000000000000000000000001E782184218421842184218421841E7800000000
+A750:000000007C4242427C404040F0400000
+A751:0000000000005C6242424242625CF040
+A752:000000001E1111117E90909050100000
+A753:00000000000016191111111179969050
+A754:000000004EA929291E08080808080000
+A755:0000000000004AAD292929291D0A0808
+A756:000000003C4242424242425A643D0205
+A757:0000000000003A4642424242463A0702
+A758:00000000000000000F00108010901088108810881090169019200F4000800140
+A759:0000000000000000000000000E901188108810881090109011A00EC001800280
+A75A:000000003C4242020408080404020000
+A75B:0000000000003C4202021C1008040000
+A75C:00000000788404040810224284FE0408
+A75D:000000000000384404081222447E0408
+A75E:00000000494949323222545488880000
+A75F:0000000000004A4A5234646498980000
+A760:00000000424242425A5A66664242020C
+A761:00000000000041494949494949370106
+A762:0000003C4040403E0408101C0202423C
+A763:00000000003040403C08102038044438
+A764:000040F0407844424244784040400000
+A765:0000002078203C222222242830202020
+A766:000000404078444242447840F0400000
+A767:0000000020203C222222242830207820
+A768:00000000444444484850506040400000
+A769:00000000000022222424283020200000
+A76A:00000000384404041804040404380000
+A76B:00000000000038440404180404040438
+A76C:0000000C1212127C1010101050200000
+A76D:0000000C1212127C1010101010105020
+A76E:00000000182442424A32020204380000
+A76F:000000000000182442424A3202020438
+A770:00001824424A32020438000000000000
+A771:0000000000000100010001001D002300210021082108211023241DF800400080
+A772:00000000000000001800080008000800080008100810082008483FF000800100
+A773:000000000000000000000000760049004900490849084910492449F800400080
+A774:0000000000000000000000005C0062004200421042104220424843F000800100
+A775:00000000002000200040009017E0190012001000100010001000100000000000
+A776:0000000000000000000000007C00420042007C1050104820444843F000800100
+A777:0000000000200020104010907FE01100120010001000100010000C0000000000
+A778:0000000038444444381C224202FC0000
+A779:0000F81C2442424242424242423C0000
+A77A:000040300804023E42424242423C0000
+A77B:000000005C6240407840404040400000
+A77C:00000000000058644040704040404040
+A77D:0000007E040810100838444444380000
+A77E:0000001C2222221C10080810207E0000
+A77F:0000000000003844444438201010207E
+A780:000000007E0202020202020202020000
+A781:000000003E08080808080808080C0000
+A782:000000005C6242424242414040400000
+A783:00000000000058644444424040404040
+A784:000000005C6040404040404040404040
+A785:0000000000005C604040404040404040
+A786:00000000FE20408080808080423C0000
+A787:000000000000FE2040808080423C0000
+A788:00000000000000000000000000182442
+A789:00000000000018180000001818000000
+A78A:00000000000000003C00003C00000000
+A78B:00000000080808080808080000000000
+A78C:00000000080808080800000000000000
+A78D:00000000424242427E02020202020000
+A78E:00000000180808285A4C380808060000
+A78F:00007FFE61866DF661EE6DDE6DDE7FFE7FFE73866DBE738E6DBE73BE7FFE0000
+A790:0000000044646454544C4C4444470101
+A791:00000000000058644444444444470101
+A792:000000001C22222070202022221C0000
+A793:0000000000001C2220702020221C0000
+A794:00007FFE61866DF661EE6DDE6DDE7FFE7FFE73B66DB671867DF673F67FFE0000
+A795:00007FFE61866DF661EE6DDE6DDE7FFE7FFE73866DBE71867DF673867FFE0000
+A796:00007FFE61866DF661EE6DDE6DDE7FFE7FFE73CE6DBE718E7DB673CE7FFE0000
+A797:00007FFE61866DF661EE6DDE6DDE7FFE7FFE73866DF671EE7DDE73DE7FFE0000
+A798:00007FFE61866DF661EE6DDE6DDE7FFE7FFE73CE6DB671CE7DB673CE7FFE0000
+A799:00007FFE61866DF661EE6DDE6DDE7FFE7FFE73CE6DB671C67DF673CE7FFE0000
+A79A:00007FFE61866DF661EE6DDE6DDE7FFE7FFE73866DB671867DB673B67FFE0000
+A79B:00007FFE61866DF661EE6DDE6DDE7FFE7FFE738E6DB6718E7DB6738E7FFE0000
+A79C:00007FFE61866DF661EE6DDE6DDE7FFE7FFE73C66DBE71BE7DBE73C67FFE0000
+A79D:00007FFE61866DF661EE6DDE6DDE7FFE7FFE738E6DB671B67DB6738E7FFE0000
+A79E:00007FFE61866DF661EE6DDE6DDE7FFE7FFE73866DBE718E7DBE73867FFE0000
+A79F:00007FFE61866DF661EE6DDE6DDE7FFE7FFE73866DBE718E7DBE73BE7FFE0000
+A7A0:000000003D424648506642C2463A0000
+A7A1:0000000000023A477CC438203C42423C
+A7A2:000000004244485062645868C4420000
+A7A3:000000004040444850605678C4420000
+A7A4:00000000426263565A6ACA4646420000
+A7A5:0000000000005C634E72C24242420000
+A7A6:000000007C475AE27C48444442420000
+A7A7:0000000000005C6242506040C0400000
+A7A8:000000003C42404C30CC0242423C0000
+A7A9:0000000000001E2026186601211E0000
+A7AA:0000000062A2A2223E22222222220000
+A7AB:00007FFE61866DF661EE6DDE6DDE7FFE7FFE618E6DB6618E6DB66D8E7FFE0000
+A7AC:00007FFE61866DF661EE6DDE6DDE7FFE7FFE61C66DBE61BE6DBE6DC67FFE0000
+A7AD:00007FFE61866DF661EE6DDE6DDE7FFE7FFE618E6DB661B66DB66D8E7FFE0000
+A7AE:00007FFE61866DF661EE6DDE6DDE7FFE7FFE61866DBE618E6DBE6D867FFE0000
+A7AF:00007FFE61866DF661EE6DDE6DDE7FFE7FFE61866DBE618E6DBE6DBE7FFE0000
+A7B0:00007FFE61866DF661EE6DDE6DDE7FFE7FFE63CE6DB663B66DB663CE7FFE0000
+A7B1:00007FFE61866DF661EE6DDE6DDE7FFE7FFE63EE6DCE63EE6DEE63C67FFE0000
+A7B2:00007FFE61866DF661EE6DDE6DDE7FFE7FFE63866DF663866DBE63867FFE0000
+A7B3:00007FFE61866DF661EE6DDE6DDE7FFE7FFE638E6DF663C66DF6638E7FFE0000
+A7B4:00007FFE61866DF661EE6DDE6DDE7FFE7FFE63B66DB663866DF663F67FFE0000
+A7B5:00007FFE61866DF661EE6DDE6DDE7FFE7FFE63866DBE63866DF663867FFE0000
+A7B6:00007FFE61866DF661EE6DDE6DDE7FFE7FFE63CE6DBE638E6DB663CE7FFE0000
+A7B7:00007FFE61866DF661EE6DDE6DDE7FFE7FFE63866DF663EE6DDE63DE7FFE0000
+A7B8:00007FFE61866DF661EE6DDE6DDE7FFE7FFE63CE6DB663CE6DB663CE7FFE0000
+A7B9:00007FFE61866DF661EE6DDE6DDE7FFE7FFE63CE6DB663C66DF663CE7FFE0000
+A7BA:00007FFE61866DF661EE6DDE6DDE7FFE7FFE63866DB663866DB663B67FFE0000
+A7BB:00007FFE61866DF661EE6DDE6DDE7FFE7FFE638E6DB6638E6DB6638E7FFE0000
+A7BC:00007FFE61866DF661EE6DDE6DDE7FFE7FFE63C66DBE63BE6DBE63C67FFE0000
+A7BD:00007FFE61866DF661EE6DDE6DDE7FFE7FFE638E6DB663B66DB6638E7FFE0000
+A7BE:00007FFE61866DF661EE6DDE6DDE7FFE7FFE63866DBE638E6DBE63867FFE0000
+A7BF:00007FFE61866DF661EE6DDE6DDE7FFE7FFE63866DBE638E6DBE63BE7FFE0000
+A7C0:00007FFE61866DF661EE6DDE6DDE7FFE7FFE71CE6FB66FB66FB671CE7FFE0000
+A7C1:00007FFE61866DF661EE6DDE6DDE7FFE7FFE71EE6FCE6FEE6FEE71C67FFE0000
+A7C2:00007FFE61866DF661EE6DDE6DDE7FFE7FFE71866FF66F866FBE71867FFE0000
+A7C3:00007FFE61866DF661EE6DDE6DDE7FFE7FFE718E6FF66FC66FF6718E7FFE0000
+A7C4:00007FFE61866DF661EE6DDE6DDE7FFE7FFE71B66FB66F866FF671F67FFE0000
+A7C5:00007FFE61866DF661EE6DDE6DDE7FFE7FFE71866FBE6F866FF671867FFE0000
+A7C6:00007FFE61866DF661EE6DDE6DDE7FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000
+A7C7:00007FFE61866DF661EE6DDE6DDE7FFE7FFE71866FF66FEE6FDE71DE7FFE0000
+A7C8:00007FFE61866DF661EE6DDE6DDE7FFE7FFE71CE6FB66FCE6FB671CE7FFE0000
+A7C9:00007FFE61866DF661EE6DDE6DDE7FFE7FFE71CE6FB66FC66FF671CE7FFE0000
+A7CA:00007FFE61866DF661EE6DDE6DDE7FFE7FFE71866FB66F866FB671B67FFE0000
+A7CB:00007FFE61866DF661EE6DDE6DDE7FFE7FFE718E6FB66F8E6FB6718E7FFE0000
+A7CC:00007FFE61866DF661EE6DDE6DDE7FFE7FFE71C66FBE6FBE6FBE71C67FFE0000
+A7CD:00007FFE61866DF661EE6DDE6DDE7FFE7FFE718E6FB66FB66FB6718E7FFE0000
+A7CE:00007FFE61866DF661EE6DDE6DDE7FFE7FFE71866FBE6F8E6FBE71867FFE0000
+A7CF:00007FFE61866DF661EE6DDE6DDE7FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+A7D0:00007FFE61866DF661EE6DDE6DDE7FFE7FFE63CE6DB66DB66DB663CE7FFE0000
+A7D1:00007FFE61866DF661EE6DDE6DDE7FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000
+A7D2:00007FFE61866DF661EE6DDE6DDE7FFE7FFE63866DF66D866DBE63867FFE0000
+A7D3:00007FFE61866DF661EE6DDE6DDE7FFE7FFE638E6DF66DC66DF6638E7FFE0000
+A7D4:00007FFE61866DF661EE6DDE6DDE7FFE7FFE63B66DB66D866DF663F67FFE0000
+A7D5:00007FFE61866DF661EE6DDE6DDE7FFE7FFE63866DBE6D866DF663867FFE0000
+A7D6:00007FFE61866DF661EE6DDE6DDE7FFE7FFE63CE6DBE6D8E6DB663CE7FFE0000
+A7D7:00007FFE61866DF661EE6DDE6DDE7FFE7FFE63866DF66DEE6DDE63DE7FFE0000
+A7D8:00007FFE61866DF661EE6DDE6DDE7FFE7FFE63CE6DB66DCE6DB663CE7FFE0000
+A7D9:00007FFE61866DF661EE6DDE6DDE7FFE7FFE63CE6DB66DC66DF663CE7FFE0000
+A7DA:00007FFE61866DF661EE6DDE6DDE7FFE7FFE63866DB66D866DB663B67FFE0000
+A7DB:00007FFE61866DF661EE6DDE6DDE7FFE7FFE638E6DB66D8E6DB6638E7FFE0000
+A7DC:00007FFE61866DF661EE6DDE6DDE7FFE7FFE63C66DBE6DBE6DBE63C67FFE0000
+A7DD:00007FFE61866DF661EE6DDE6DDE7FFE7FFE638E6DB66DB66DB6638E7FFE0000
+A7DE:00007FFE61866DF661EE6DDE6DDE7FFE7FFE63866DBE6D8E6DBE63867FFE0000
+A7DF:00007FFE61866DF661EE6DDE6DDE7FFE7FFE63866DBE6D8E6DBE63BE7FFE0000
+A7E0:00007FFE61866DF661EE6DDE6DDE7FFE7FFE61CE6FB663B66FB661CE7FFE0000
+A7E1:00007FFE61866DF661EE6DDE6DDE7FFE7FFE61EE6FCE63EE6FEE61C67FFE0000
+A7E2:00007FFE61866DF661EE6DDE6DDE7FFE7FFE61866FF663866FBE61867FFE0000
+A7E3:00007FFE61866DF661EE6DDE6DDE7FFE7FFE618E6FF663C66FF6618E7FFE0000
+A7E4:00007FFE61866DF661EE6DDE6DDE7FFE7FFE61B66FB663866FF661F67FFE0000
+A7E5:00007FFE61866DF661EE6DDE6DDE7FFE7FFE61866FBE63866FF661867FFE0000
+A7E6:00007FFE61866DF661EE6DDE6DDE7FFE7FFE61CE6FBE638E6FB661CE7FFE0000
+A7E7:00007FFE61866DF661EE6DDE6DDE7FFE7FFE61866FF663EE6FDE61DE7FFE0000
+A7E8:00007FFE61866DF661EE6DDE6DDE7FFE7FFE61CE6FB663CE6FB661CE7FFE0000
+A7E9:00007FFE61866DF661EE6DDE6DDE7FFE7FFE61CE6FB663C66FF661CE7FFE0000
+A7EA:00007FFE61866DF661EE6DDE6DDE7FFE7FFE61866FB663866FB661B67FFE0000
+A7EB:00007FFE61866DF661EE6DDE6DDE7FFE7FFE618E6FB6638E6FB6618E7FFE0000
+A7EC:00007FFE61866DF661EE6DDE6DDE7FFE7FFE61C66FBE63BE6FBE61C67FFE0000
+A7ED:00007FFE61866DF661EE6DDE6DDE7FFE7FFE618E6FB663B66FB6618E7FFE0000
+A7EE:00007FFE61866DF661EE6DDE6DDE7FFE7FFE61866FBE638E6FBE61867FFE0000
+A7EF:00007FFE61866DF661EE6DDE6DDE7FFE7FFE61866FBE638E6FBE61BE7FFE0000
+A7F0:00007FFE61866DF661EE6DDE6DDE7FFE7FFE61CE6FB663B66FB66FCE7FFE0000
+A7F1:00007FFE61866DF661EE6DDE6DDE7FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000
+A7F2:00007FFE61866DF661EE6DDE6DDE7FFE7FFE61866FF663866FBE6F867FFE0000
+A7F3:00007FFE61866DF661EE6DDE6DDE7FFE7FFE618E6FF663C66FF66F8E7FFE0000
+A7F4:00007FFE61866DF661EE6DDE6DDE7FFE7FFE61B66FB663866FF66FF67FFE0000
+A7F5:00007FFE61866DF661EE6DDE6DDE7FFE7FFE61866FBE63866FF66F867FFE0000
+A7F6:00007FFE61866DF661EE6DDE6DDE7FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+A7F7:00007FFE61866DF661EE6DDE6DDE7FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+A7F8:0000000044FE447C4444440000000000
+A7F9:0036494F483700000000000000000000
+A7FA:000000000000006B2A2A2A2A2A7F0000
+A7FB:000000007E0202023E02020202020000
+A7FC:000000003E4242423E02020202020000
+A7FD:00000000424242425A5A666642420000
+A7FE:00003E080808080808080808083E0000
+A7FF:000000000000000010411041104128A228A228A2451445148208820800000000
+A800:000000000000FFFF003000500090011002100410081010106008000000000000
+A801:000000000000FFFF040005000680048001000600010000800040000000000000
+A802:0480024001200000000000000000000000000000000000000000000000000000
+A803:000000000000FFFF080011E02210241020E02110201010200FC0000000000000
+A804:0E0001000080FFFF10801080108011001E001000100010000800000000000000
+A805:000000000000FFFF0040034004C00840084004C0034018401840000000000000
+A806:004000A001100000000000000000000000000000000000000000000000000000
+A807:000000000000FFFF226022A023202E2032200220022002200110000000000000
+A808:000000000000FFFF26602AA03320222000200020002000200010000000000000
+A809:000000000000FFFF0840084004400C4014401440084000400020000000000000
+A80A:000000000000FFFF00C003400440034000C003400440034000E0000000000000
+A80B:0030004800300000000000000000000000000000000000000000000000000000
+A80C:000000000000FFFF004000C00140024004400840064001C00020000000000000
+A80D:000000000000FFFF100011801280148019E00290046008000800000000000000
+A80E:000000000000FFFF0820102021E0212011200E20002000200010000000000000
+A80F:000000000000FFFF200026002A28322802480248029002900320000000000000
+A810:000000000000FFFF0700088008400480010002400420082007C0000000000000
+A811:000000000000FFFF080008000B000C800880088009000A000C00000000000000
+A812:000000000000FFFF010001000960119011101010102008400780000000000000
+A813:000000000000FFFF0800080009800A400A400880088009000600000000000000
+A814:000000000000FFFF0040004018C01F4008400840084010402020000000000000
+A815:000000000000FFFF0020026006A02B2012200020002000200010000000000000
+A816:000000000000FFFF100011801280148018800080008000400030000000000000
+A817:000000000000FFFF2010203013500D9001100010001000100008000000000000
+A818:000000000000FFFF006000A00120022005200520052002200010000000000000
+A819:000000000000FFFF206020A02120222024202820302020200010000000000000
+A81A:000000000000FFFF40C041704248445048605050604840400020000000000000
+A81B:000000000000FFFF00400040074008C008C00740004000400020000000000000
+A81C:000000000000FFFF01E0022004201E2025200220002000200010000000000000
+A81D:000000000000FFFF406020A011200A2004200A200A2004200010000000000000
+A81E:000000000000FFFF006000A0012012200C200020002000200010000000000000
+A81F:000000000000FFFF006000A0012012200C2000A0012002200190FFFF00000000
+A820:000000000000FFFF010001000160019001100010002000400780000000000000
+A821:000000000000FFFF00100E301150119002100510009000900008000000000000
+A822:000000000000FFFF206020A021202220242028A0312022200190000000000000
+A823:000000000000000F000200020002000200020002000200020001000000000000
+A824:000C00120002000F000200020002000200020002000200020001000000000000
+A825:000000000000FFFF000000000000000000000000000000080008001001E00000
+A826:0200010000800000000000000000000000000000000000000000000000000000
+A827:000800040002000F000200020002000200020002000200020001000000000000
+A828:00000000000030484830000000000000
+A829:00000000304848300030484830000000
+A82A:0000000000000000301848244824301800000180024002400180000000000000
+A82B:00000000000000000C60129012900C6000000C60129012900C60000000000000
+A82C:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE61C67DBE61BE6FBE61C67FFE0000
+A82D:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE618E7DB661B66FB6618E7FFE0000
+A82E:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE61867DBE618E6FBE61867FFE0000
+A82F:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE61867DBE618E6FBE61BE7FFE0000
+A830:0000000000000080008000800080008000800080008000800080000000000000
+A831:0000000000000120012001200120012001200120012001200120012000000000
+A832:0000000000000920092009200920092009200920092009200920092000000000
+A833:00000000000000000000000000000000007003801C0000000000000000000000
+A834:000000000000000000000000007003801C000000007003801C00000000000000
+A835:0000000000000000007003801C00007003801C00007003801C00000000000000
+A836:00000000000001C002200220022001C000000000000000000000000000000000
+A837:0000000000000000004000800100020004000E001100110011000E0000000000
+A838:000000000000001000100010001000100010001000100010002001C000000000
+A839:00000000000000700080008000800040004000400040004001800E0000000000
+A83A:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE63867DB671867DB663B67FFE0000
+A83B:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE638E7DB6718E7DB6638E7FFE0000
+A83C:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE63C67DBE71BE7DBE63C67FFE0000
+A83D:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE638E7DB671B67DB6638E7FFE0000
+A83E:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE63867DBE718E7DBE63867FFE0000
+A83F:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE63867DBE718E7DBE63BE7FFE0000
+A840:00001FF80248024802481E480248024802480008000800080008000800080008
+A841:00001FF01080108017F814081408140814081408158816481028001800080000
+A842:00001FF8010801081FE81028102810281028102817A818680008000800080008
+A843:00001FF800080008000800081FF8100010001000100010001FE0001000080008
+A844:00001FF800080008000800081FF8100810081008100810081FC8002800180018
+A845:00001FF8010001001FF811081108110811081788184800280018000800000000
+A846:00001FF810001000100010001FC0103010081000100017801860001000080008
+A847:00001FF810081008103810C81308120811081088100810080008000800080008
+A848:00001FF811001100110011001100110011601190111011200040002000100010
+A849:00001FF8010802080C0810081FF80108020804080E0811880068001800080008
+A84A:00001FF8040004000400040008000B801C601010001000080008000800080008
+A84B:00001FF8000800080008000807080888084807A8001800080008000800080008
+A84C:00001FC8004800480048004800481FC8100810081008100817C8182800180018
+A84D:00001FF8004800480048004800481FC8100810081008100817C8182800180018
+A84E:00001FF800481048184817C810081008100810081008100817C8182800180018
+A84F:00001C0802080208020801080108010807C80928091806080008000800080008
+A850:00001FF801081108138814481078104808880708000800080008000800080008
+A851:00001FF800081008118810681058105808880708000800080008000800080008
+A852:00001FF80408040804081F880088008800880088008800881FF8000800080008
+A853:00001FE011001100110017C0128012801440144017C010001000100010001000
+A854:00001FE010201020102010201340148013401020102000200020002000200020
+A855:00001FF810001000100010001FC0103010081000100017801860001000080008
+A856:00001FF81008100810081008100811F811001100110011001100117011881000
+A857:00001108110811081108110811081108110812880C4800480028002800180018
+A858:00001FF8010001000100010007C0082010101010000800080008000800080008
+A859:00001FE010201020102010201020102013E01200120012001200120012F01308
+A85A:00001FF81008100810081008100810081F080108010801080D08130801080008
+A85B:00000FE804480448028802880108010802880C8810480C480228012801180018
+A85C:00001FF802000200040008001860069001900090002000200010000800000000
+A85D:0000106808E809480A4809480948094809480948062800280028001800180018
+A85E:00001FF800080008000800080008000800080008078808480828062800180018
+A85F:00001FF801000100010003E0141014081448138810080810042003C000000000
+A860:00001FF80008000800081FF81808060801080088008800080008000800080008
+A861:00001FF801800180024002400420042008100810100810081008000000000000
+A862:00001FF810881088110811081208160811881048102810281018001800080008
+A863:00001FF8104810881108120813F8104810881108138810481028101810081008
+A864:00001FF8010001000200046018900488028801080108003800C8030800C80038
+A865:00001FF811081108108810881048106811881208140814081808180010001000
+A866:00001FC010301008100010001000100010001000100017801860001000080008
+A867:000000080018002800C803080C0810080C08030800C800280018000800000000
+A868:0000000010081008181016601180100810081008081006600180000000000000
+A869:00001FF800880088008800880088008806880988088804880200040008000800
+A86A:00001FF810801040103010081FF8108010401020107011881600180010001000
+A86B:00001FF80020002000200020001001D006380808080010001000100010001000
+A86C:00001FF8100010001000100010E01110121015E0180010001000100010001000
+A86D:00001108110811081108110811081108110811881F4800480028002800180018
+A86E:00001FF81008100810081008100811F811001100110011001100117011881000
+A86F:00001FF801000100020004601890048802880108010800080008000800080008
+A870:00001FF801000100020004601890049002A001100108003800C8030800C80038
+A871:0000000800080008000800081C08030800880048004800280028001800180008
+A872:00000000000000001FF801000100010001000100010000000000000000000000
+A873:0000000001000380038007C007C0038000001010082007C00380000000000000
+A874:000013F812081208120812081208120813C81008100810081008100810081FF8
+A875:000017BC14A414A414A414A414A414A416B41084108410841084108410841FFC
+A876:00000000000000001FF800000000000000000000000000000000000000000000
+A877:00000000000000001FF80000000000001FF80000000000000000000000000000
+A878:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE61CE7DB67BCE77B677CE7FFE0000
+A879:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE61CE7DB67BC677F677CE7FFE0000
+A87A:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE61867DB67B8677B677B67FFE0000
+A87B:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE618E7DB67B8E77B6778E7FFE0000
+A87C:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE61C67DBE7BBE77BE77C67FFE0000
+A87D:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE618E7DB67BB677B6778E7FFE0000
+A87E:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE61867DBE7B8E77BE77867FFE0000
+A87F:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE61867DBE7B8E77BE77BE7FFE0000
+A880:000000000000000000000004000A000A00040000000000000000000000000000
+A881:00000000000000000004000A000A000400000004000A000A0004000000000000
+A882:000000000000000036004900490002007C008000808081007E00000000000000
+A883:000000000000000036004900490002007C008100808081407E00000000000000
+A884:000000000000000063009480A400820061008100810082007C00000000000000
+A885:000000000000000063009480A700820061008100810082007C00000000000000
+A886:0000000000000000CF00308029004C0092008200820084007800000000000000
+A887:0000000000000000CE00310028804C8092808280828084807880000000000000
+A888:00000000000000004C8092809280628004807880808081007E00000000000000
+A889:00000000000000004C0092009200620004007900808081407E00000000000000
+A88A:000000000000000077008880888080808080BE80848088804700000000000000
+A88B:000000000000000077008880888080808080BE80848088804700060021001E00
+A88C:00000000000000003F00408080009300948094808F0044003800000000000000
+A88D:00000000000000003F0040808080A480AA80AA809C8048803080000000000000
+A88E:00000000000000003F0040808000A900AA80AA80970042003C00000000000000
+A88F:00000000000000003F0040809E00A10091008600990041003E00000000000000
+A890:00000000000000003F0040809C80A280928084809A8042803C80000000000000
+A891:00000000000000003F0040809000A9008A80B2808F8049803180000000000000
+A892:0000000000000000270058805080288008800880088008800880000000000000
+A893:000000000000000084404AA027C02440484049209220922061C0000000000000
+A894:0000000000000000670088808880888088808880888088807300000000000000
+A895:000000000000000062009500A500820065008500888088807300000000000000
+A896:00000000000000007F0080808080B8804480B880808080804300000000000000
+A897:00000000000000006100928050801080F8804100810082007C00000000000000
+A898:000000000000000063009480A280808070808100810082007C00000000000000
+A899:00000000000000007700888088808080A080D080908094806300000000000000
+A89A:0000000000000000770088809480A280A2809480888094804900000000000000
+A89B:00000000000000003C0042008900950095008F80910092004C00000000000000
+A89C:0000000000000000FF8040003800060071008880908081007E00000000000000
+A89D:00000000000000003E0041008080808080808080808041003E00000000000000
+A89E:00000000000000007F8001002200470088808080808041003E00000000000000
+A89F:0000000000000000020085004480258052804080408021001E00000000000000
+A8A0:00000000000000003E0041008C8092809280BA80828044803900000000000000
+A8A1:00000000000000003E0041008080808080808080808040803080000000000000
+A8A2:0000000000000000330048801080210042003400080014000800000000000000
+A8A3:0000000000000000780084008400480010006200810083007C80000000000000
+A8A4:000000000000000063009480A080808060808080808081007E00000000000000
+A8A5:00000000000000003D004280830082008200A200520052002200000000000000
+A8A6:00000000000000004300A0801080110021002200420044003800000000000000
+A8A7:0000000000000000180025804380420084009480888041003E00000000000000
+A8A8:0000000000000000B600B900610002007C008100808080807F00000000000000
+A8A9:00000000000000004D8092409240904090409040904090406180000000000000
+A8AA:00000000000000006C80928092804480188060808080B8804700000000000000
+A8AB:00000000000000004300A0805080110021002200420044003800000000000000
+A8AC:0000000000000000F780140012002200210041004080F880C700000000000000
+A8AD:0000000000000000770088808880808080808080808080806300000000000000
+A8AE:0000000000000000E30080804100220014000800140014000800000000000000
+A8AF:00000000000000003900448084809480A8809480848084806300000000000000
+A8B0:000000000000000061009280D280A10082808280848044803900000000000000
+A8B1:00000000000000004880B5009900910088808880848084808300000000000000
+A8B2:0000000000000000FF00100020007100A8809080808041003E00000000000000
+A8B3:00000000000000006B0094809480808080808080808081006600000000000000
+A8B4:00000000000000000012001200120012000E0002000200020002000000000000
+A8B5:0000000000000000002E0012001400040008000800100010000C000000000000
+A8B6:003C004200240000000000000000000000000000000000000000000000000000
+A8B7:00700088000800080008000800080008000800080008000A0004000000000000
+A8B8:00000000000000000044002A003A003400100028002800280010000000000000
+A8B9:000000000000000800500034003A003400100028002800280010000000000000
+A8BA:0000000000000000001C002A00240020001C000200020022001C000000000000
+A8BB:0000000000000000001C002A00240020001C000200020022001C0040003C0002
+A8BC:000000000000000000DC0122012201220126012A012A012A00A4000000000000
+A8BD:000000000000000000DC0122012201220126012A012A012A00A4020001F00008
+A8BE:0000000000000000000C001200120016000A0002000200040008000000000000
+A8BF:0000000000000000003E0022001400040008000800120012000C000000000000
+A8C0:0000000000000000001800240026001A00020002000A0016000C000000000000
+A8C1:0000000000000000003E002200120004003800080008000A0004000000000000
+A8C2:0000000000000000007E0046002A000A0072000A000A000A0004000000000000
+A8C3:000000000000000000E4009A001A001C001800180038005A0024000000000000
+A8C4:0000000000000000000000000000000000000000000000000000002000100008
+A8C5:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE71866FBE6F866FF671867FFE0000
+A8C6:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000
+A8C7:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE71866FF66FEE6FDE71DE7FFE0000
+A8C8:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE71CE6FB66FCE6FB671CE7FFE0000
+A8C9:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE71CE6FB66FC66FF671CE7FFE0000
+A8CA:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE71866FB66F866FB671B67FFE0000
+A8CB:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE718E6FB66F8E6FB6718E7FFE0000
+A8CC:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE71C66FBE6FBE6FBE71C67FFE0000
+A8CD:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE718E6FB66FB66FB6718E7FFE0000
+A8CE:0000000000000000008000800080008000800080008000800080000000000000
+A8CF:0000000000000000024002400240024002400240024002400240000000000000
+A8D0:000000000000000003C0042008100810081008100810042003C0000000000000
+A8D1:000000000000000001C00220022001C000400080008000800060000000000000
+A8D2:000000000000000007C008200020022001C00100008000400030000000000000
+A8D3:0000000000000000038004400040018000400040084008400780000000000000
+A8D4:00000000000000000140022002200140008001400220022001C0000000000000
+A8D5:0000000000000000062008200840087007880088010801080110000000000000
+A8D6:000000000000000003C004200400030002000400040002400180000000000000
+A8D7:0000000000000000024004A004A0046004200220024001400080000000000000
+A8D8:0000000000000000010002800240044004200620052005200240000000000000
+A8D9:00000000000000000800040004000440088009400820042003C0000000000000
+A8DA:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE63866DB66D866DB663B67FFE0000
+A8DB:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE638E6DB66D8E6DB6638E7FFE0000
+A8DC:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE63C66DBE6DBE6DBE63C67FFE0000
+A8DD:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE638E6DB66DB66DB6638E7FFE0000
+A8DE:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE63866DBE6D8E6DBE63867FFE0000
+A8DF:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE63866DBE6D8E6DBE63BE7FFE0000
+A8E0:0000018002400240018000000000000000000000000000000000000000000000
+A8E1:0180024001800300008000400000000000000000000000000000000000000000
+A8E2:0180024000800100008000400000000000000000000000000000000000000000
+A8E3:0180004001800040018000400020000000000000000000000000000000000000
+A8E4:0000044002800100028001000000000000000000000000000000000000000000
+A8E5:01000100012000E0002000100010000800080000000000000000000000000000
+A8E6:00C0010000C0010000E000200010000000000000000000000000000000000000
+A8E7:044004A00460022001C000000000000000000000000000000000000000000000
+A8E8:004000800100012000C000000000000000000000000000000000000000000000
+A8E9:00C0012000C00040002000200000000000000000000000000000000000000000
+A8EA:1CE002400C4023C01C4000000000000000000000000000000000000000000000
+A8EB:07E0004004800240018000000000000000000000000000000000000000000000
+A8EC:0FF00080038004E0039000900000000000000000000000000000000000000000
+A8ED:07E0004003C00440004000400040000000000000000000000000000000000000
+A8EE:0FC0048004800380008000800000000000000000000000000000000000000000
+A8EF:07E0008001800100008000400000000000000000000000000000000000000000
+A8F0:030004000FE004C0054004C00440000000000000000000000000000000000000
+A8F1:007000800040012000C000000000000000000000000000000000000000000000
+A8F2:000000000000000008900410031000E000000000000000000000000000000000
+A8F3:000000000000000008900410031000E0000000E0001000080008000800000000
+A8F4:00000000000000000450031000E000000450031000E000000060001000080008
+A8F5:000000000000000008900410031000E0000000E0001000100060001000080000
+A8F6:000000000000000008900410031000E0000000E0001000E0001000E000400020
+A8F7:000000000000000008900410031000E0000000E0010000800240018000000000
+A8F8:00000000000000000718082408240714080C08040808041003E0000000000000
+A8F9:00000000000000000038004400040004070408040808041003E0000000000000
+A8FA:0000000002200140008000000000000000000000000000000000000000000000
+A8FB:000000000000FFFF000000000000000000000000000000000000000000000000
+A8FC:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+A8FD:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE618E6FB663B66FB66F8E7FFE0000
+A8FE:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE61866FBE638E6FBE6F867FFE0000
+A8FF:00007FFE61CE6DB661CE6DB66DCE7FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+A900:00000000000000001FF820042004200420042004200420041FF8000000000000
+A901:00000000000000003FFC000400041FFC20042000203C20441FF8000000000000
+A902:0000000000000000101010100820082004400440028002800100000000000000
+A903:00000000000000000FF8081008200040008001180228044807F0000000000000
+A904:0000000000000000107011901610181010101010001000100060000000000000
+A905:00000000000000001FF810001000100010001000100010001C00000000000000
+A906:0000000000000000101810681188160818081038104810481030000000000000
+A907:0000000000000000003800081008100810081008100810080FF0000000000000
+A908:0000000000000000100010001000100010001000100810081FF8000000000000
+A909:00000000000000001C0010001000100410041004100410040FF8000000000000
+A90A:00000000000000003C780488050806080C081408240824083808000000000000
+A90B:00000000000000001FF82004200420043FFC0004000420041FF8000000000000
+A90C:000000000000000011F01210141018101FF01010101010101010000000000000
+A90D:00000000000000001FF820042004200020002000200420041FF8000000000000
+A90E:00000000000000000FF0100810080B0804880B08100820083E08000000000000
+A90F:00000000000000001FF800080008038802480228022802180C08000000000000
+A910:0000000000000000106011901610182010401020101010701000000000000000
+A911:00000000000000001FF820040004000420043FF8200020041FF8000000000000
+A912:00000000000000000C000B0008C0083009800A400CC009400880000000000000
+A913:0000000000000000000800080008103810081008100810080FF0000000000000
+A914:00000000000000000FF010080F0000F0180810081FF010000F80000000000000
+A915:00000000000000001FF820042018206021802600380420041FF8000000000000
+A916:00000000000000000FC010201020100013E01420182010201010000000000000
+A917:0000000000000000200820082008210822882448282830181FF0000000000000
+A918:00000000000000000FF8001000200040008001180228044807F0000000000000
+A919:000000000000000008F009100A100C1008100870089008900860000000000000
+A91A:000000000000000008F009100A100C1008100810081008100810001000100060
+A91B:000000000000000020F021082108210821082108210821081E08000000000000
+A91C:000000000000000020F021082108210821081E08000820081FF0000000000000
+A91D:00000000000000001000100010001C0810081008100810080FF0000000000000
+A91E:00000000000000001FF820042000200020041FFC000420041FF8000000000000
+A91F:00000000000000000E1012101410183010501F90001000100060000000000000
+A920:0000000000000000600C583446C4410400040004400440043FF8000000000000
+A921:00000000000000000FF010081008000818081608118810681018000000000000
+A922:00000000000000001FF82004200420001E002000200420041FF8000000000000
+A923:000000000000000010081008100810081018102810C813081C08000000000000
+A924:00000000000000001FF8200C20340044018402040C0430041FF8000000000000
+A925:00000000000000001FF82004300C2C3423C42004200420041FF8000000000000
+A926:00040000000000000000000000000000
+A927:0C00030000C00000000000000000000000000000000000000000000000000000
+A928:010006C018300000000000000000000000000000000000000000000000000000
+A929:104010400F800000000000000000000000000000000000000000000000000000
+A92A:124010400F800000000000000000000000000000000000000000000000000000
+A92B:00000000000000000000000000000400
+A92C:0000000000000000000000000000000000000000000000000000080010200FC0
+A92D:0000000000000000000000000000000000000000000000000000090010200FC0
+A92E:000000000000000000000000000003C00C301008000000000000000000000000
+A92F:0000000000000000008000800080008000800080008000800080000000000000
+A930:0000000000000000010002800240052004800800080010001000000000000000
+A931:0000000000000000010002800240042004000800080010001000000000000000
+A932:000000000000000004440A880A881110111022A022A044404440000000000000
+A933:0000000000000000010002800240062005400880080010001000000000000000
+A934:00000000000000000180024002200610054008A0080010001000000000000000
+A935:0000000000000000030C05140514092409241144114421842184000000000000
+A936:0000000000000000001000100020002000400840048002800100000000000000
+A937:0000000000000000001000200040008001000200040008001000000000000000
+A938:000000000000000004400440028002800100210812900AA00440000000000000
+A939:0000000000000000008001400120029002480620051008A00840000000000000
+A93A:000000000000000004200A500948148412802100200040004000000000000000
+A93B:000000000000000004440AA80AA8111010002000200040004000000000000000
+A93C:00000000000000000210052804E4084008401080108021002100000000000000
+A93D:00000000000000000210052804E4084008401080188025002300000000000000
+A93E:0000000000000000018802880290049004A008A008C010C01080000000000000
+A93F:00000000000000004004400420082008101011100AA00AA00440000000000000
+A940:00000000000000000210052004E0084008401080108021002100000000000000
+A941:0000000000000000004000A0009001080100220012000C000400000000000000
+A942:00000000000000000108021002100420042008400C4012801180000000000000
+A943:0000000000000080014002200220041004900948094812241224000000000000
+A944:00000000000000000D4415441484148815481548262826282410000000000000
+A945:000000000000000004440AA80AA811101100220032004C004400000000000000
+A946:0000000000000000011002A002A0044006000A00090011001000000000000000
+A947:0000000000000000000000000000000000008000000000000000000000000000
+A948:0000000000000000000000000000000000000000000000000000800000000000
+A949:0000000000000000000000000000800080008000800000000000000000000000
+A94A:0008001400220000000000000000000000000000000000000000000000000000
+A94B:0000000000000000000000000000800080008000800000000000000080000000
+A94C:0000000000000000000000000000000000000000000000000000800080006000
+A94D:0000000000000000000000000000000000000000000000000000A000A000A000
+A94E:0000000000000000000000000000000000000000000000000000000A000A000A
+A94F:0002000400000000000000000000000000000000000000000000000000000000
+A950:0012002400000000000000000000000000000000000000000000000000000000
+A951:0022001400080000000000000000000000000000000000000000000000000000
+A952:0000000000000000000000000000000000000000000000000000000200000002
+A953:0004000A00040000000000000000000000000000000000000000000000000000
+A954:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61B66FB661867DF661F67FFE0000
+A955:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61866FBE61867DF661867FFE0000
+A956:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61CE6FBE618E7DB661CE7FFE0000
+A957:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61866FF661EE7DDE61DE7FFE0000
+A958:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61CE6FB661CE7DB661CE7FFE0000
+A959:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61CE6FB661C67DF661CE7FFE0000
+A95A:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61866FB661867DB661B67FFE0000
+A95B:00007FFE61CE6DB661C66DF66DCE7FFE7FFE618E6FB6618E7DB6618E7FFE0000
+A95C:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61C66FBE61BE7DBE61C67FFE0000
+A95D:00007FFE61CE6DB661C66DF66DCE7FFE7FFE618E6FB661B67DB6618E7FFE0000
+A95E:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61866FBE618E7DBE61867FFE0000
+A95F:0000000000000000008009300940058012700E4801A002900C90010000000000
+A960:00003E7C2044204420443E7C0000000000000000000000000000000000000000
+A961:00003E442044207C20443E7C0000000000000000000000000000000000000000
+A962:00003E102010201020283E440000000000000000000000000000000000000000
+A963:00003E7C2008201020283E440000000000000000000000000000000000000000
+A964:00007CF804087C0840087C080000000000000000000000000000000000000000
+A965:00003DDC04443C4420443C440000000000000000000000000000000000000000
+A966:00003E7C02403E4020403E7C0000000000000000000000000000000000000000
+A967:00003DDC05103D1021103DDC0000000000000000000000000000000000000000
+A968:00003E7C02443E4420443E7C0000000000000000000000000000000000000000
+A969:00003E4402443E7C20443E7C0000000000000000000000000000000000000000
+A96A:00003D5405543DDC21543DDC0000000000000000000000000000000000000000
+A96B:00443E7C02443E7C20383E440038000000000000000000000000000000000000
+A96C:00003E1002103E1020283E440000000000000000000000000000000000000000
+A96D:00003E7C02083E1020283E440000000000000000000000000000000000000000
+A96E:00003E7C02043E7C20043E040000000000000000000000000000000000000000
+A96F:00003E7C2204220422043E040000000000000000000000000000000000000000
+A970:00003E7C2240224022403E7C0000000000000000000000000000000000000000
+A971:00003E102210221022283E440000000000000000000000000000000000000000
+A972:0000293C2920393C2AA03C7C0000000000000000000000000000000000000000
+A973:0000227C22043E7C22043E040000000000000000000000000000000000000000
+A974:0000223022FC3E3022483E300000000000000000000000000000000000000000
+A975:000008920892089E1552223E0000000000000000000000000000000000000000
+A976:00000E3E1102113E11200E3E0000000000000000000000000000000000000000
+A977:00001C3022FC223022481C300000000000000000000000000000000000000000
+A978:00003FEC047F088C1552222C0000000000000000000000000000000000000000
+A979:00003E7C20403E7C20403E7C0000000000000000000000000000000000000000
+A97A:00003E3014FC143014483E300000000000000000000000000000000000000000
+A97B:00000C103F100C1012280C440000000000000000000000000000000000000000
+A97C:00003EFC00000C3012480C300000000000000000000000000000000000000000
+A97D:00007FFE61CE6DB661C66DF66DCE7FFE7FFE618E7DB67BB677B6778E7FFE0000
+A97E:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61867DBE7B8E77BE77867FFE0000
+A97F:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61867DBE7B8E77BE77BE7FFE0000
+A980:11880A5007E00000000000000000000000000000000000000000000000000000
+A981:0240038000000000000000000000000000000000000000000000000000000000
+A982:0040008001000200000000000000000000000000000000000000000000000000
+A983:0000000000000000000600090009000500020006000100010001000100010002
+A984:0000000000000000300040008000B03C88A4B0FE882489A47264000000000000
+A985:000000000000000038D845244524440444044404450424842784018002600010
+A986:0000000000000000228855545554505450545054545452545E74060009800040
+A987:0000000000000000228855545554505450545054545458545B74040002000C00
+A988:000000000000000038D845244524440444044404450424842788003000460078
+A989:000000000000000030C049204920492049204920492049204E2004000F000080
+A98A:000000000000000031B04A484A4848084A08491C4F2800480788080809880670
+A98B:000000000000000031B04A484A4848084A0C491A4F2A004C078A080A098C0670
+A98C:000000000000000000000000000007800A401180100010700F88000000000000
+A98D:000003000400038000400180000007800A401180100010700F88000000000000
+A98E:000000000000000039C0492090909090909090904F2000400380043809C00E00
+A98F:00000000000000002388545454545454545454545E5455545574020000000000
+A990:00000000000000002388545454545454545454545E5455545574060009800040
+A991:00000000000000002384544854505450545054505E5055505560020000000000
+A992:000000000000000031104AA84AA84AA84AA82AA80AA80AA80EE8000000000000
+A993:0000000000000000231855145514551455145514555455545CA0000000000000
+A994:000000000000000038D8452445244404440444044484244427C4000000000000
+A995:0000000000000000387044484448444844484E485548554848C8000000000000
+A996:000000000000000010002200452049524A55529654A5552A2210000000000000
+A997:000000000000000038784484451C45E045C04530450824882780000000000000
+A998:000000000000000038784484451C45E045C04530450824882780018002600010
+A999:000800140014000E31454AA54AA648244A2449244F2400440784080808C80730
+A99A:0000000000008000457EAADAAADAA0DAA8DAA4DABCDA00000000000000000000
+A99B:000000000000000031B04A484A484808480848084B084C884708084008400780
+A99C:000000000000000031B04A484A4848084808480849884A484F88000000000000
+A99D:000000000000000038F048909050905090509050925092504D90000000000000
+A99E:0000000000000000398048409040904090409040924092404D80000000000000
+A99F:0000000000000000224855B455B455B455B435B415B415B41DB4000000000000
+A9A0:000000000000000027CC543454345434533450B450B450B45F34000000000000
+A9A1:000000000000000038F048909050905090509250955091504F90010001400080
+A9A2:000000000000000039E04A109210921092109210939096504990000000000000
+A9A3:000000000000000038F048909050905090509050925092504D90000000000000
+A9A4:000000000000000039E04A109210921092109F10929092905110000000000000
+A9A5:0000000000000000387044484448444844484448444844482388000000000000
+A9A6:0000000000000000386048909090905090209030924892484D90000000000000
+A9A7:0000000000000000629C95549554905490549054945492545F64000000000000
+A9A8:00000000000000003C782448244804404F4074E00258014400C0000000000000
+A9A9:00000000000000003F18482448244824472448244824482427C4000000000000
+A9AA:000000000000000039CE494A494A494A494A494A494A494A2E32000000000000
+A9AB:00000000000000003C78228412840284048408841C8402840184000000000000
+A9AC:000C0012000E000264929B6A9B6A9B6A5B6A1B6A1B6A1B6A1B6E000000000000
+A9AD:000000000000000039DC4A549254925492549254925492544E64000000000000
+A9AE:00000000000000001CF024884848484848484848484848482788000000000000
+A9AF:0000000000000000233054C854C854C855C836C817FC14CA1CC8000000000000
+A9B0:00000000000000003878484890489148924893FC904A90484F88000000000000
+A9B1:00000000000000003C3C44248424842484248E249524952448C4000000000000
+A9B2:000000000000000039FC49649164916491649164916491644E64000000000000
+A9B3:0000024001802424181800000000000000000000000000000000000000000000
+A9B4:0000000000000000000600090009000100020002000400050007000000000000
+A9B5:0000000000000000000000040004000200020001000900060000000000000000
+A9B6:01E0021004100410047003900000000000000000000000000000000000000000
+A9B7:01E00210053004D0047003900000000000000000000000000000000000000000
+A9B8:000000000000000000000000000000050005000500050005000500050019003E
+A9B9:000000000000000000000004000F00140014000E00050005000500050019003E
+A9BA:00000000000000004800B400B400B400B400B400B400B4003400040004000300
+A9BB:1800200010000800300000004800B400B400B400B400B4003400040004000300
+A9BC:0780084008200610000000000000000000000000000000000000000000000000
+A9BD:0000000000000000000000000000000100060002000100010001003200340058
+A9BE:000E000A000A000A000A000A000A000A000A002A002A00CA030A040A04CA0331
+A9BF:180020004000800080008000800080008000800080048008401C2002180207FC
+A9C0:000E000A000A000A000A000A000A000A000A000A000A030A048A040A04CA0331
+A9C1:00000006060A04080408020861E04004206A1F8400100612042203C2000A000C
+A9C2:00003000500043C044204860080021F856042002078610401020102050606000
+A9C3:2800D586C586C586D586F58601861D8621862F86A5E6999F818781C741D73EA9
+A9C4:6800D586C586C586D586F58681869D86A186AF86A5E6999F818781C741D73EA9
+A9C5:30004006E806D586C586F58681869D86A186AF86A5E6999F818781C741D73EA9
+A9C6:0000000000000000000001C0022002200220022001C000000000000000000000
+A9C7:0000000000000000000000000240038000000000024003800000000000000000
+A9C8:00000000000000001800040002000100008000800040034000C0000000000000
+A9C9:0000000000000000330008800440022001100110008806E80198000000000000
+A9CA:00000000000000000600010001000100010001000100010001000100010000C0
+A9CB:0000000000000000198004400440044004400440044004400440044004400330
+A9CC:0000001000200140010000C006000100010001000100010001000100010000C0
+A9CD:0000018000400040004000400040004000400040003001800040014002000400
+A9CE:00007FFE61CE6DB661C66DF66DCE7FFE7FFE71866FBE6F8E6FBE71867FFE0000
+A9CF:0000000000000000000000000820072002C00200010001000100000000000000
+A9D0:0000000000000000000001C0022002200220022001C000000000000000000000
+A9D1:000000000000000031104AA84AA84AA84AA82AA80AA80AA80EE8000000000000
+A9D2:000000000000000031B04A484A4848084A08491C4F2800480788080809880670
+A9D3:00000000000000002367549554955015541552255E4500850F05100511850E79
+A9D4:000000000000000000C00100020002C0022002C00220022001C0000000000000
+A9D5:00000000000000000380044008200B2008A00B2008A008A00720002000200018
+A9D6:000000000000000000000000000007800A401180100010700F88000000000000
+A9D7:000000000000000039DC4A549254925492549254925492544E64000000000000
+A9D8:0000000000000000386048909090905090209030924892484D90000000000000
+A9D9:000000000000000039CE494A494A494A494A494A494A494A2E32000000000000
+A9DA:00007FFE61CE6DB661C66DF66DCE7FFE7FFE63866DB66D866DB663B67FFE0000
+A9DB:00007FFE61CE6DB661C66DF66DCE7FFE7FFE638E6DB66D8E6DB6638E7FFE0000
+A9DC:00007FFE61CE6DB661C66DF66DCE7FFE7FFE63C66DBE6DBE6DBE63C67FFE0000
+A9DD:00007FFE61CE6DB661C66DF66DCE7FFE7FFE638E6DB66DB66DB6638E7FFE0000
+A9DE:000000000000000000800140022002200220022001C000000000000000000000
+A9DF:00000000000000001C7022882288228822882288228822882388000000000000
+A9E0:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61CE6FB663B66FB661CE7FFE0000
+A9E1:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61EE6FCE63EE6FEE61C67FFE0000
+A9E2:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61866FF663866FBE61867FFE0000
+A9E3:00007FFE61CE6DB661C66DF66DCE7FFE7FFE618E6FF663C66FF6618E7FFE0000
+A9E4:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61B66FB663866FF661F67FFE0000
+A9E5:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61866FBE63866FF661867FFE0000
+A9E6:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61CE6FBE638E6FB661CE7FFE0000
+A9E7:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61866FF663EE6FDE61DE7FFE0000
+A9E8:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61CE6FB663CE6FB661CE7FFE0000
+A9E9:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61CE6FB663C66FF661CE7FFE0000
+A9EA:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61866FB663866FB661B67FFE0000
+A9EB:00007FFE61CE6DB661C66DF66DCE7FFE7FFE618E6FB6638E6FB6618E7FFE0000
+A9EC:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61C66FBE63BE6FBE61C67FFE0000
+A9ED:00007FFE61CE6DB661C66DF66DCE7FFE7FFE618E6FB663B66FB6618E7FFE0000
+A9EE:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61866FBE638E6FBE61867FFE0000
+A9EF:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61866FBE638E6FBE61BE7FFE0000
+A9F0:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61CE6FB663B66FB66FCE7FFE0000
+A9F1:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000
+A9F2:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61866FF663866FBE6F867FFE0000
+A9F3:00007FFE61CE6DB661C66DF66DCE7FFE7FFE618E6FF663C66FF66F8E7FFE0000
+A9F4:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61B66FB663866FF66FF67FFE0000
+A9F5:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61866FBE63866FF66F867FFE0000
+A9F6:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+A9F7:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+A9F8:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+A9F9:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+A9FA:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61866FB663866FB66FB67FFE0000
+A9FB:00007FFE61CE6DB661C66DF66DCE7FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+A9FC:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+A9FD:00007FFE61CE6DB661C66DF66DCE7FFE7FFE618E6FB663B66FB66F8E7FFE0000
+A9FE:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61866FBE638E6FBE6F867FFE0000
+A9FF:00007FFE61CE6DB661C66DF66DCE7FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+AA00:00000000000000000E0611C9222929323480188013C004A00300000000000000
+AA01:00000000000000000CC013201020282050400780082008500790000000000000
+AA02:0000000000000000038004400820082004400180020002400180000000000000
+AA03:00380044004400480E20111011080928025804300420024001E0000000000000
+AA04:00000000000000000E70118818081408083000C00110011000E0000000000000
+AA05:00000000000000000380044008201C200AC0042000F0012800C0000000000000
+AA06:00000000000000000EE011101110102008000800080008001000000000000000
+AA07:00000000000000001B0C24922452206411C01280148015002200000000000000
+AA08:000000000000000007700888108810101000100011000A800700000000000000
+AA09:0000000000000000186C24922492148404800880090006000200000000000000
+AA0A:00000000000000001C2822502230161001100120014003800400000000000000
+AA0B:00000000000000001C2822502230161001100120014003800430044804900300
+AA0C:00000000000000001C3022482248114001800F00120012000C00000000000000
+AA0D:00000000000000001886254925491544064C1C94248828901060000000000000
+AA0E:000000000000000038D8452445242C8802800280028007000800000000000000
+AA0F:0000000000000000031804A404A404A8052013902B5027301CE0000000000000
+AA10:00000000000000001986264940314022406040A02920152028C0000000000000
+AA11:00000000000000001986264940314022406040A02920152028C4004A00480030
+AA12:00000000000000001986264940314022406040A02920152029C4024A01480230
+AA13:0000000000000000077008880888101010001600190009000600000000000000
+AA14:00000000000000000E0C111211120928025804300420024001C0000000000000
+AA15:00000000000000001C7022882288165001400140014003800400000000000000
+AA16:00000000000000000C70128812880A5002400440048003000100000000000000
+AA17:00000000000000001C0C22122212110801080F08129012600C40000000000000
+AA18:00000000000000001C0C22122212110801080F08129012600C48009400900060
+AA19:00000000000000001C0C22122212110801080F08129012600C0008C009200600
+AA1A:0000000000000000077008880888040004002400540048003000000000000000
+AA1B:00000000000000001C1822242224162801200120014003800400000000000000
+AA1C:00000000000000000E0C1112111209080A284A58AA30911060E0000000000000
+AA1D:0000000000000000183024482448085010401040104008400780000000000000
+AA1E:0000000000000000306C48924892108020802080208010800F00000000000000
+AA1F:0000000000000000306C4892489228840A80110012800C800400000000000000
+AA20:0000000000000000183824442444144805400880094006400248009400900060
+AA21:0000000000000000183824442444144805400880095006200250005000200000
+AA22:0000000000000000306C48924892248404400240024002800700000000000000
+AA23:000000000000000000F001080108009000800680098009000600000000000000
+AA24:0000000000000000073808C4080410041008101012000D000600000000000000
+AA25:00000000000000001838244424441448044008D0092006500250002000000000
+AA26:00000000000000000C1C12222A22522402200440048003000100000000000000
+AA27:0000000000000000073808C408040408020012002A0024001800000000000000
+AA28:00000000000000000770088808980428021412002A0024001800000000000000
+AA29:0038004400480020001800040004000000000000000000000000000000000000
+AA2A:001C00220041004D003200040000000000000000000000000000000000000000
+AA2B:001C002200490041004D00320004000000000000000000000000000000000000
+AA2C:00380045008E009A006400080000000000000000000000000000000000000000
+AA2D:00000000000000000000000000000000000000000000000000000002001C0020
+AA2E:00000011000E0000000000000000000000000000000000000000000000000000
+AA2F:0000000000000000000000006000900090008000A0005000A000000000000000
+AA30:0000000000000000000000006000900090008000A00050002000080070008000
+AA31:0002001C00200024001800100020000000000000000000000000000000000000
+AA32:0000000000000000000000000000000000000000000000000000000C00040008
+AA33:0000000000000000000000000000000600090009000800040032000A0012003C
+AA34:5800A8008800100020004000800080008000800080008000800082004A003400
+AA35:000000000000000000000000000000000000000000000000000000040008000C
+AA36:0000000000000000000000000000000000000008000500020005000500050002
+AA37:00007FFE61866DB661866DB66DB67FFE7FFE63867DF671EE7DDE63DE7FFE0000
+AA38:00007FFE61866DB661866DB66DB67FFE7FFE63CE7DB671CE7DB663CE7FFE0000
+AA39:00007FFE61866DB661866DB66DB67FFE7FFE63CE7DB671C67DF663CE7FFE0000
+AA3A:00007FFE61866DB661866DB66DB67FFE7FFE63867DB671867DB663B67FFE0000
+AA3B:00007FFE61866DB661866DB66DB67FFE7FFE638E7DB6718E7DB6638E7FFE0000
+AA3C:00007FFE61866DB661866DB66DB67FFE7FFE63C67DBE71BE7DBE63C67FFE0000
+AA3D:00007FFE61866DB661866DB66DB67FFE7FFE638E7DB671B67DB6638E7FFE0000
+AA3E:00007FFE61866DB661866DB66DB67FFE7FFE63867DBE718E7DBE63867FFE0000
+AA3F:00007FFE61866DB661866DB66DB67FFE7FFE63867DBE718E7DBE63BE7FFE0000
+AA40:00000000000000000EE011101110101008100820082008401080000000000000
+AA41:00000000000000000EE01110111020102010202020202C401C80000000000000
+AA42:00000000000000001C2022502250163001180124014403880410000000000000
+AA43:0004000800300000000000000000000000000000000000000000000000000000
+AA44:00000000000000001C3822442244114401840F08120812100C20000000000000
+AA45:0000000000000000077008880888100810081610191009200640000000000000
+AA46:0000000000000000381C44224422221202121E14252424C81890000000000000
+AA47:00000000000000000770088808880408020812102A1024201840000000000000
+AA48:0000000000000000306C48924892248204420244024402880710000000000000
+AA49:000000000000000000F801040104008400840688098809100620000000000000
+AA4A:00000000000000000E701188100820082008201024102A201C40000000000000
+AA4B:00000000000000001C7812842A84524402440448048803100120000000000000
+AA4C:0000002000000000000000000000000000000000000000000000000000000000
+AA4D:0000000000000000000000000006000900050001000200040004000000000000
+AA4E:00007FFE61866DB661866DB66DB67FFE7FFE6D866DBE618E7DBE7D867FFE0000
+AA4F:00007FFE61866DB661866DB66DB67FFE7FFE6D866DBE618E7DBE7DBE7FFE0000
+AA50:000000000000000003C0042008100810081008100810042003C0000000000000
+AA51:00000000000000000FE0101010103C200CC00100010001000100000000000000
+AA52:000203840478080013B824442444280429042A88270810100FE0000000000000
+AA53:00000000000000000E7011881008200820102024244A2A4A1C30000000000000
+AA54:0000000000000000000406080908109020507C20220022001C00000000000000
+AA55:00000000000000000F0010801080090002800040034004800340000000000000
+AA56:000000000000000000F001080108009000800680098009000600000000000000
+AA57:000000000000000000F801040104008400840688098809100660008800940060
+AA58:00000000000000001C3822442244114401840F08120812100C60008800940060
+AA59:0000000000000000183824442444084410841088108809100660008800940060
+AA5A:00007FFE61866DB661866DB66DB67FFE7FFE61866FB661867DB661B67FFE0000
+AA5B:00007FFE61866DB661866DB66DB67FFE7FFE618E6FB6618E7DB6618E7FFE0000
+AA5C:0000000000000000000001C00220041024101310082007C00000000000000000
+AA5D:0000000000000000008000800080008000800080008000800080000000000000
+AA5E:0000000000000000024002400240024002400240024000400040000000000000
+AA5F:0000000000000000049004900490049004900090009000100010000000000000
+AA60:000000000000000000003DE04210810881388148425024200000000000000000
+AA61:000000000000000000001EF02108408440844084218892706000000000000000
+AA62:0000000000000000000081C0802080109010A810A42043C00000000000000000
+AA63:000000000000000000001EF02108408441844284228891706000000000000000
+AA64:000000000000000000002478428481028102810242843C780000000000000000
+AA65:000000003878408481028102810243043D380100010001000100010007000000
+AA66:000000000000000000003DE0421081089908990842103C200000000000000000
+AA67:000000000000000000003C78428481029902990242843C780000000000000000
+AA68:000000000000000000003DE0421081089938994842503C200000000000000000
+AA69:000000000000000000003C784284810299C2992242943C780000000000000000
+AA6A:000000000000000000003C784284810281C2812242943C780000000000000000
+AA6B:00000000000000002000478048403820142012200A4004800000000000000000
+AA6C:000000000000000000000F804890850885088508489030600000000000000000
+AA6D:0000000004000AF00B0806040204020402080210020002000200220022001C00
+AA6E:000000000000000000001E182104408270824882284410380000000000000000
+AA6F:0000000000000000000063C05420481048104810442043C00000000000000000
+AA70:000007C00820000007C008200000000000000000000000000000000000000000
+AA71:000000000000000000003DE04210A10891089108521024200000000000000000
+AA72:000000000000000000001EF02108408440842084C088B1706000000000000000
+AA73:0000000000000000000080C0C020A01090108810842083C00000000000000000
+AA74:00180024002013102288228812880F080208020802080608090806F000000000
+AA75:0018002400201D9022482128112872480088008800880188024801B000000000
+AA76:0000000C0012001031C84A2404140414042404440444044424C4452438D80000
+AA77:000001800240020001801C00220021001100710002000200050004A004400700
+AA78:000000000000209C11220E200020402020201020102010402040474008C01040
+AA79:0000000000000000000007800840082004201C200040004000800080008000E0
+AA7A:00400040FFC080008E189104A082A08290C48CB88080808080808080FF800000
+AA7B:0000000000000000000000000000000000000000000C0012001C001000080004
+AA7C:00007FFE61866DB661866DB66DB67FFE7FFE61C67DBE7BBE77BE77C67FFE0000
+AA7D:00007FFE61866DB661866DB66DB67FFE7FFE618E7DB67BB677B6778E7FFE0000
+AA7E:00007FFE61866DB661866DB66DB67FFE7FFE61867DBE7B8E77BE77867FFE0000
+AA7F:00007FFE61866DB661866DB66DB67FFE7FFE61867DBE7B8E77BE77BE7FFE0000
+AA80:00000000000000001830085008900890091009100A100C100000000000000000
+AA81:000000000000000003E00410082808480888090806101E200000000000000000
+AA82:0000000000000E04110820882088208820882088110809F00008000800880070
+AA83:000000000000661C222222422242224222422242224C1D82000200020022001C
+AA84:0000000000000E0811102090209020907110291C293210CC0000000000000000
+AA85:00000000000008F00508020802080208000800080030000800080208010800F0
+AA86:000000000000038004400820082008201C200A200A2004200020002004400380
+AA87:000000000000038004400820082008200820046003A000200020002004400380
+AA88:00060008000EDB094C86488848884888488849EA4A95310A0000000000000000
+AA89:02000400080013C0142014101010101010100810042003C00000000000000000
+AA8A:000000300048008000801880248004800480048004E003D00060000000000000
+AA8B:0000000000000210052804F0042004200420042004200820002000200012000C
+AA8C:0000003C0042008000803060488008800880088008C0092006C0000000000000
+AA8D:0000003C00420080008030604880088008800880088008800700008000800300
+AA8E:0000000000003008081004200240018001802240142008180000000000000000
+AA8F:0007000800100E1011102090209020907110291C293210CC0000000000000000
+AA90:00000000000066D823242224222422242224222422241C240004000400840078
+AA91:0000000000000770088810881008780814080C080008000800080008010800F0
+AA92:000000000000000003E00410080808080808080804101E200000000000000000
+AA93:00000000000060E021102210221022102210239026501990001000100012000C
+AA94:0000000000000770088810881008780814080C10000000000000000000000000
+AA95:0000000000003040484008400840084008400840084807B00000000000000000
+AA96:0000000000000E00110020802080208070802880288010800080008800880070
+AA97:0000000000000C1004100410041004100410043004500390001000100012000C
+AA98:000200040008DB084C88488848884888488849EA4A95310A0000000000000000
+AA99:000000000000000018202440048004800480048004E003D00060000000000000
+AA9A:0000002000400080008018802480048004800480048003000000000000000000
+AA9B:000400080008000832481248124812481248124812480DB00000000000000000
+AA9C:0018002400403040084008400840084008400840048003000000000000000000
+AA9D:000800100010001031101110111011101110111011100EE00000000000000000
+AA9E:0000003C004200800080606014801A801080108010C011200EC0000000000000
+AA9F:000400080008010862882288228822882288228822881C700008000800300000
+AAA0:0000042004401B80308008800900090009000960089007600000000000000000
+AAA1:0000001C00220020632025202520292029203138316420980000000000000000
+AAA2:0000000000016D822644244424442444244224E22552188C0000000000000000
+AAA3:0000000000043808441004100410041004080E08150808F00000000000000000
+AAA4:020C02120DA03820442004200420042004200420024001800000000000000000
+AAA5:020802100DA03820442004200420042004200420024001800000000000000000
+AAA6:0000000000002300148008400840084008400840102420180000000000000000
+AAA7:0000000000002300148008400840084008400858103420380010000800000000
+AAA8:000000000000CDC046204420442044204420442044203820002000200012000C
+AAA9:0000000000000780084008400090012000C000800D0002000000000000000000
+AAAA:000000000000DB704C884884488448844884488448A430980000000000000000
+AAAB:00000000000003C0042004100010001000100810042003C00000000000000000
+AAAC:000000000000CCC055204E104410441044104422442438180000000000000000
+AAAD:00000000000030E0111012081208120814081408144808300000000000000000
+AAAE:00000000000003C0042004100250019000100410042003C00000000000000000
+AAAF:000003C004200410021001F800140414042403C4000400040004000400880070
+AAB0:0000042008400880070000000000000000000000000000000000000000000000
+AAB1:0000000000000780044000400040004000400040004000400000000000000000
+AAB2:00000100010006C0000000000000000000000000000000000000000000000000
+AAB3:080014E017100800100008000000000000000000000000000000000000000000
+AAB4:0000000000000000000000000000000000000000000C0012000E0022001C0000
+AAB5:000000000000042008401080108010801080108010800C600000000000000000
+AAB6:000001E002100400040004000400040004000400040003000000000000000000
+AAB7:0010002000400280010000000000000000000000000000000000000000000000
+AAB8:001000A0004002A0010000000000000000000000000000000000000000000000
+AAB9:0000000000000080010002000200020002000200020001800000000000000000
+AABA:0000000000E0010002000200010000C0010001C002A004400000000000000000
+AABB:00000600090008800880049003E0008000800080008003000000000000000000
+AABC:00000000000001C00220040004000400020001C0008001000200020004000600
+AABD:0000002000400080009031E04A8008800880088008C0092006C0000000000000
+AABE:038802700E2009C0388027000000000000000000000000000000000000000000
+AABF:0040004000400080008000800000000000000000000000000000000000000000
+AAC0:0000000000000180024004400440048007000420044003800000000000000000
+AAC1:0000003006400980030004000000000000000000000000000000000000000000
+AAC2:0000000000000780044000400040004000400040004000400040008001000200
+AAC3:00007FFE61866DB661866DB66DB67FFE7FFE718E6FF66FC66FF6718E7FFE0000
+AAC4:00007FFE61866DB661866DB66DB67FFE7FFE71B66FB66F866FF671F67FFE0000
+AAC5:00007FFE61866DB661866DB66DB67FFE7FFE71866FBE6F866FF671867FFE0000
+AAC6:00007FFE61866DB661866DB66DB67FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000
+AAC7:00007FFE61866DB661866DB66DB67FFE7FFE71866FF66FEE6FDE71DE7FFE0000
+AAC8:00007FFE61866DB661866DB66DB67FFE7FFE71CE6FB66FCE6FB671CE7FFE0000
+AAC9:00007FFE61866DB661866DB66DB67FFE7FFE71CE6FB66FC66FF671CE7FFE0000
+AACA:00007FFE61866DB661866DB66DB67FFE7FFE71866FB66F866FB671B67FFE0000
+AACB:00007FFE61866DB661866DB66DB67FFE7FFE718E6FB66F8E6FB6718E7FFE0000
+AACC:00007FFE61866DB661866DB66DB67FFE7FFE71C66FBE6FBE6FBE71C67FFE0000
+AACD:00007FFE61866DB661866DB66DB67FFE7FFE718E6FB66FB66FB6718E7FFE0000
+AACE:00007FFE61866DB661866DB66DB67FFE7FFE71866FBE6F8E6FBE71867FFE0000
+AACF:00007FFE61866DB661866DB66DB67FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+AAD0:00007FFE61866DB661866DB66DB67FFE7FFE63CE6DB66DB66DB663CE7FFE0000
+AAD1:00007FFE61866DB661866DB66DB67FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000
+AAD2:00007FFE61866DB661866DB66DB67FFE7FFE63866DF66D866DBE63867FFE0000
+AAD3:00007FFE61866DB661866DB66DB67FFE7FFE638E6DF66DC66DF6638E7FFE0000
+AAD4:00007FFE61866DB661866DB66DB67FFE7FFE63B66DB66D866DF663F67FFE0000
+AAD5:00007FFE61866DB661866DB66DB67FFE7FFE63866DBE6D866DF663867FFE0000
+AAD6:00007FFE61866DB661866DB66DB67FFE7FFE63CE6DBE6D8E6DB663CE7FFE0000
+AAD7:00007FFE61866DB661866DB66DB67FFE7FFE63866DF66DEE6DDE63DE7FFE0000
+AAD8:00007FFE61866DB661866DB66DB67FFE7FFE63CE6DB66DCE6DB663CE7FFE0000
+AAD9:00007FFE61866DB661866DB66DB67FFE7FFE63CE6DB66DC66DF663CE7FFE0000
+AADA:00007FFE61866DB661866DB66DB67FFE7FFE63866DB66D866DB663B67FFE0000
+AADB:0007000800100E12110C208420B823C87D08291C292A10CC0000000000000000
+AADC:0007000800100E12110C2084208820887108291C292A10CC0000000000000000
+AADD:02000400080008000B8004400A20092008E01C500A480A480430000000000000
+AADE:1F7C21844508105001020A0405545AAC4AA44AA464980000145041043EF80000
+AADF:0000007000800100012000C00040008000801FE0209007E0088011C00EA000C0
+AAE0:000000000000000001C002200410081008100010001013900C70000000000000
+AAE1:00000000000000001FF008000800080008100810082004400380000000000000
+AAE2:00000000000000001CE0249017A0102010200840084008403030000000000000
+AAE3:000000000000000001900190016002000200020034004C004C00000000000000
+AAE4:0000000000000000070C089210A2204250A28912850A48923062000000000000
+AAE5:00000000000000001FF00100010001000FE009200FE009200FE0000000000000
+AAE6:00000000000000000700088018C0252042104010202020201040000000000000
+AAE7:0000000000000000183024482288210822882448282824482388000000000000
+AAE8:00000000000000003FF0100013F0101010201040104010801080000000000000
+AAE9:00000000000000007FFC22881450082014502288228814500820000000000000
+AAEA:000000000000000007C00820082008200FE00820082008200FE0000000000000
+AAEB:0000600090007C00200020002000200020002000200020002000000000000000
+AAEC:0000000000000000000000000000000000000000000000000490049003600000
+AAED:008000400020006000A000400000000000000000000000000000000000000000
+AAEE:0000600090007000200020003800200020002000200020002000000000000000
+AAEF:0000000C0012001C000800080038000800080008000800080008000000000000
+AAF0:0000000000000000008000800080008000800080008000800080000000000000
+AAF1:000000000000000010100C600380000003800C60101000000000000000000000
+AAF2:00000080022001C0000001C002200020004001800200022001C0000000000000
+AAF3:000000000000000007C008200820044002800100028004400820000000000000
+AAF4:0000000000000000038000400020002000400080010000800060000000000000
+AAF5:000000000000000000000004000A000A00040004000400000000000000000000
+AAF6:0000000000000000000000000000000000000000000000000000008001C00080
+AAF7:00007FFE61866DB661866DB66DB67FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+AAF8:00007FFE61866DB661866DB66DB67FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+AAF9:00007FFE61866DB661866DB66DB67FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+AAFA:00007FFE61866DB661866DB66DB67FFE7FFE61866FB663866FB66FB67FFE0000
+AAFB:00007FFE61866DB661866DB66DB67FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+AAFC:00007FFE61866DB661866DB66DB67FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+AAFD:00007FFE61866DB661866DB66DB67FFE7FFE618E6FB663B66FB66F8E7FFE0000
+AAFE:00007FFE61866DB661866DB66DB67FFE7FFE61866FBE638E6FBE6F867FFE0000
+AAFF:00007FFE61866DB661866DB66DB67FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+AB00:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73CE6DB66DB66DB673CE7FFE0000
+AB01:000000000600060007000F8018C018C01FC01FFC18CC18C018C018C000000000
+AB02:000000000600060007000F8018C018C01FC01FC018C018C018CC18FC00000000
+AB03:000000000180018001C003E00630063007F007F0063000300030003000000000
+AB04:000000000600060007000F8018C018C01FC01FC018C018F818CC18F800000000
+AB05:000000000300038001C003E00630063007F007F0063006300630063000000000
+AB06:000000000180018001C003E00630063007F007F0063006000600060000000000
+AB07:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73866DF66DEE6DDE73DE7FFE0000
+AB08:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73CE6DB66DCE6DB673CE7FFE0000
+AB09:0600060007000F8018801F8018800D0006001FC030C030FC018C018000000000
+AB0A:0600060007000F8018801F8018800D0006001FC030C030C0019801F800000000
+AB0B:03000300038007C00C400FC00C40068003000FF00C300C300030003000000000
+AB0C:0600060007000F8018801F8018800D0006000600060003F03F9830F000000000
+AB0D:0600060007000F8018801FF818980D0006000600060003003FF0303000000000
+AB0E:0300038007C00C400FC00C400680030007F00C30180018001800180000000000
+AB0F:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73866DBE6D8E6DBE73BE7FFE0000
+AB10:00007FFE618E6DB6618E6DB66D8E7FFE7FFE7BCE73B67BB67BB671CE7FFE0000
+AB11:60307FF0401018C018C018C018C01FC01FC018FC18CC18CC18C018C000000000
+AB12:60307FF0401018C018C018C018C01FC01FC018C018C018C018CC18FC00000000
+AB13:30183FF820080C600C600C600C600FE00FE00C600C6000600060006000000000
+AB14:60307FF0401018C018C018C018C01FC01FC018C018C018F818CC18F800000000
+AB15:30183FF8200800001C3036303630063007F007F0063006300630063000000000
+AB16:30183FF820080C600C600C600C600FE00FE00C600C600C000C000C0000000000
+AB17:00007FFE618E6DB6618E6DB66D8E7FFE7FFE7B8673F67BEE7BDE71DE7FFE0000
+AB18:00007FFE618E6DB6618E6DB66D8E7FFE7FFE7BCE73B67BCE7BB671CE7FFE0000
+AB19:00007FFE618E6DB6618E6DB66D8E7FFE7FFE7BCE73B67BC67BF671CE7FFE0000
+AB1A:00007FFE618E6DB6618E6DB66D8E7FFE7FFE7B8673B67B867BB671B67FFE0000
+AB1B:00007FFE618E6DB6618E6DB66D8E7FFE7FFE7B8E73B67B8E7BB6718E7FFE0000
+AB1C:00007FFE618E6DB6618E6DB66D8E7FFE7FFE7BC673BE7BBE7BBE71C67FFE0000
+AB1D:00007FFE618E6DB6618E6DB66D8E7FFE7FFE7B8E73B67BB67BB6718E7FFE0000
+AB1E:00007FFE618E6DB6618E6DB66D8E7FFE7FFE7B8673BE7B8E7BBE71867FFE0000
+AB1F:00007FFE618E6DB6618E6DB66D8E7FFE7FFE7B8673BE7B8E7BBE71BE7FFE0000
+AB20:60307FF0401000001F803FC06260C230C230C230F338DAB6CAB2FBBE00000000
+AB21:60307FF0401000001F803FC06260C230C23FC233F338DAB4CAB2FBBE00000000
+AB22:60307FF0401000001F803FC06260C230C230C230F330DAB0CAB3FBBF00000000
+AB23:30183FF820080FE01FF031186118799865587DD8001800340032003E00000000
+AB24:60307FF0401000001F803FC06260C23FC239C237F330DABCCAB2FBBE00000000
+AB25:60307FF040101FC07FE0C630E6389724F33C030003800340032003E000000000
+AB26:30183FF820080FE01FF01A183218231862946252739C680064007C0000000000
+AB27:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61867DF661EE6FDE61DE7FFE0000
+AB28:000018181FF81008018003C00660066003C007E00E700C300C300C3000000000
+AB29:000060607FE0402006000F00198019800F001F8039C030FC30CC30C000000000
+AB2A:000060607FE0402006000F00198019800F001F8039C030C030CC30FC00000000
+AB2B:30303FF02010030007800CC00CC007800FC01CC018E018600060006000000000
+AB2C:000030603FE02020030007800CC00CC007800FC01CE01878186C187800000000
+AB2D:000030603FE0202006000F0019F819980F001F8039C030C030C030C000000000
+AB2E:30603FE02020030007800CC00CC007800FC01CE0186018601800180000000000
+AB2F:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61867DBE618E6FBE61BE7FFE0000
+AB30:00007FFE618E6DB6618E6DB66D8E7FFE7FFE63CE7DB671B67DB663CE7FFE0000
+AB31:00007FFE618E6DB6618E6DB66D8E7FFE7FFE63EE7DCE71EE7DEE63C67FFE0000
+AB32:00007FFE618E6DB6618E6DB66D8E7FFE7FFE63867DF671867DBE63867FFE0000
+AB33:00007FFE618E6DB6618E6DB66D8E7FFE7FFE638E7DF671C67DF6638E7FFE0000
+AB34:00007FFE618E6DB6618E6DB66D8E7FFE7FFE63B67DB671867DF663F67FFE0000
+AB35:00007FFE618E6DB6618E6DB66D8E7FFE7FFE63867DBE71867DF663867FFE0000
+AB36:00007FFE618E6DB6618E6DB66D8E7FFE7FFE63CE7DBE718E7DB663CE7FFE0000
+AB37:00007FFE618E6DB6618E6DB66D8E7FFE7FFE63867DF671EE7DDE63DE7FFE0000
+AB38:00007FFE618E6DB6618E6DB66D8E7FFE7FFE63CE7DB671CE7DB663CE7FFE0000
+AB39:00007FFE618E6DB6618E6DB66D8E7FFE7FFE63CE7DB671C67DF663CE7FFE0000
+AB3A:00007FFE618E6DB6618E6DB66D8E7FFE7FFE63867DB671867DB663B67FFE0000
+AB3B:00007FFE618E6DB6618E6DB66D8E7FFE7FFE638E7DB6718E7DB6638E7FFE0000
+AB3C:00007FFE618E6DB6618E6DB66D8E7FFE7FFE63C67DBE71BE7DBE63C67FFE0000
+AB3D:00007FFE618E6DB6618E6DB66D8E7FFE7FFE638E7DB671B67DB6638E7FFE0000
+AB3E:00007FFE618E6DB6618E6DB66D8E7FFE7FFE63867DBE718E7DBE63867FFE0000
+AB3F:00007FFE618E6DB6618E6DB66D8E7FFE7FFE63867DBE718E7DBE63BE7FFE0000
+AB40:00007FFE618E6DB6618E6DB66D8E7FFE7FFE6DCE6DB661B67DB67DCE7FFE0000
+AB41:00007FFE618E6DB6618E6DB66D8E7FFE7FFE6DEE6DCE61EE7DEE7DC67FFE0000
+AB42:00007FFE618E6DB6618E6DB66D8E7FFE7FFE6D866DF661867DBE7D867FFE0000
+AB43:00007FFE618E6DB6618E6DB66D8E7FFE7FFE6D8E6DF661C67DF67D8E7FFE0000
+AB44:00007FFE618E6DB6618E6DB66D8E7FFE7FFE6DB66DB661867DF67DF67FFE0000
+AB45:00007FFE618E6DB6618E6DB66D8E7FFE7FFE6D866DBE61867DF67D867FFE0000
+AB46:00007FFE618E6DB6618E6DB66D8E7FFE7FFE6DCE6DBE618E7DB67DCE7FFE0000
+AB47:00007FFE618E6DB6618E6DB66D8E7FFE7FFE6D866DF661EE7DDE7DDE7FFE0000
+AB48:00007FFE618E6DB6618E6DB66D8E7FFE7FFE6DCE6DB661CE7DB67DCE7FFE0000
+AB49:00007FFE618E6DB6618E6DB66D8E7FFE7FFE6DCE6DB661C67DF67DCE7FFE0000
+AB4A:00007FFE618E6DB6618E6DB66D8E7FFE7FFE6D866DB661867DB67DB67FFE0000
+AB4B:00007FFE618E6DB6618E6DB66D8E7FFE7FFE6D8E6DB6618E7DB67D8E7FFE0000
+AB4C:00007FFE618E6DB6618E6DB66D8E7FFE7FFE6DC66DBE61BE7DBE7DC67FFE0000
+AB4D:00007FFE618E6DB6618E6DB66D8E7FFE7FFE6D8E6DB661B67DB67D8E7FFE0000
+AB4E:00007FFE618E6DB6618E6DB66D8E7FFE7FFE6D866DBE618E7DBE7D867FFE0000
+AB4F:00007FFE618E6DB6618E6DB66D8E7FFE7FFE6D866DBE618E7DBE7DBE7FFE0000
+AB50:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61CE6FB661B67DB661CE7FFE0000
+AB51:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61EE6FCE61EE7DEE61C67FFE0000
+AB52:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61866FF661867DBE61867FFE0000
+AB53:00007FFE618E6DB6618E6DB66D8E7FFE7FFE618E6FF661C67DF6618E7FFE0000
+AB54:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61B66FB661867DF661F67FFE0000
+AB55:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61866FBE61867DF661867FFE0000
+AB56:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61CE6FBE618E7DB661CE7FFE0000
+AB57:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61866FF661EE7DDE61DE7FFE0000
+AB58:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61CE6FB661CE7DB661CE7FFE0000
+AB59:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61CE6FB661C67DF661CE7FFE0000
+AB5A:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61866FB661867DB661B67FFE0000
+AB5B:00007FFE618E6DB6618E6DB66D8E7FFE7FFE618E6FB6618E7DB6618E7FFE0000
+AB5C:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61C66FBE61BE7DBE61C67FFE0000
+AB5D:00007FFE618E6DB6618E6DB66D8E7FFE7FFE618E6FB661B67DB6618E7FFE0000
+AB5E:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61866FBE618E7DBE61867FFE0000
+AB5F:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61866FBE618E7DBE61BE7FFE0000
+AB60:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73CE6FB663B66DB673CE7FFE0000
+AB61:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73EE6FCE63EE6DEE73C67FFE0000
+AB62:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73866FF663866DBE73867FFE0000
+AB63:00007FFE618E6DB6618E6DB66D8E7FFE7FFE738E6FF663C66DF6738E7FFE0000
+AB64:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73B66FB663866DF673F67FFE0000
+AB65:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73866FBE63866DF673867FFE0000
+AB66:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73CE6FBE638E6DB673CE7FFE0000
+AB67:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73866FF663EE6DDE73DE7FFE0000
+AB68:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73CE6FB663CE6DB673CE7FFE0000
+AB69:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73CE6FB663C66DF673CE7FFE0000
+AB6A:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73866FB663866DB673B67FFE0000
+AB6B:00007FFE618E6DB6618E6DB66D8E7FFE7FFE738E6FB6638E6DB6738E7FFE0000
+AB6C:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73C66FBE63BE6DBE73C67FFE0000
+AB6D:00007FFE618E6DB6618E6DB66D8E7FFE7FFE738E6FB663B66DB6738E7FFE0000
+AB6E:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73866FBE638E6DBE73867FFE0000
+AB6F:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73866FBE638E6DBE73BE7FFE0000
+AB70:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61CE7DB67BB677B677CE7FFE0000
+AB71:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61EE7DCE7BEE77EE77C67FFE0000
+AB72:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61867DF67B8677BE77867FFE0000
+AB73:00007FFE618E6DB6618E6DB66D8E7FFE7FFE618E7DF67BC677F6778E7FFE0000
+AB74:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61B67DB67B8677F677F67FFE0000
+AB75:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61867DBE7B8677F677867FFE0000
+AB76:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61CE7DBE7B8E77B677CE7FFE0000
+AB77:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61867DF67BEE77DE77DE7FFE0000
+AB78:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61CE7DB67BCE77B677CE7FFE0000
+AB79:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61CE7DB67BC677F677CE7FFE0000
+AB7A:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61867DB67B8677B677B67FFE0000
+AB7B:00007FFE618E6DB6618E6DB66D8E7FFE7FFE618E7DB67B8E77B6778E7FFE0000
+AB7C:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61C67DBE7BBE77BE77C67FFE0000
+AB7D:00007FFE618E6DB6618E6DB66D8E7FFE7FFE618E7DB67BB677B6778E7FFE0000
+AB7E:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61867DBE7B8E77BE77867FFE0000
+AB7F:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61867DBE7B8E77BE77BE7FFE0000
+AB80:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73CE6DB673B66DB673CE7FFE0000
+AB81:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73EE6DCE73EE6DEE73C67FFE0000
+AB82:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73866DF673866DBE73867FFE0000
+AB83:00007FFE618E6DB6618E6DB66D8E7FFE7FFE738E6DF673C66DF6738E7FFE0000
+AB84:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73B66DB673866DF673F67FFE0000
+AB85:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73866DBE73866DF673867FFE0000
+AB86:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73CE6DBE738E6DB673CE7FFE0000
+AB87:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73866DF673EE6DDE73DE7FFE0000
+AB88:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73CE6DB673CE6DB673CE7FFE0000
+AB89:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73CE6DB673C66DF673CE7FFE0000
+AB8A:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73866DB673866DB673B67FFE0000
+AB8B:00007FFE618E6DB6618E6DB66D8E7FFE7FFE738E6DB6738E6DB6738E7FFE0000
+AB8C:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73C66DBE73BE6DBE73C67FFE0000
+AB8D:00007FFE618E6DB6618E6DB66D8E7FFE7FFE738E6DB673B66DB6738E7FFE0000
+AB8E:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73866DBE738E6DBE73867FFE0000
+AB8F:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73866DBE738E6DBE73BE7FFE0000
+AB90:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73CE6DB671B67DB673CE7FFE0000
+AB91:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73EE6DCE71EE7DEE73C67FFE0000
+AB92:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73866DF671867DBE73867FFE0000
+AB93:00007FFE618E6DB6618E6DB66D8E7FFE7FFE738E6DF671C67DF6738E7FFE0000
+AB94:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73B66DB671867DF673F67FFE0000
+AB95:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73866DBE71867DF673867FFE0000
+AB96:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73CE6DBE718E7DB673CE7FFE0000
+AB97:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73866DF671EE7DDE73DE7FFE0000
+AB98:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73CE6DB671CE7DB673CE7FFE0000
+AB99:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73CE6DB671C67DF673CE7FFE0000
+AB9A:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73866DB671867DB673B67FFE0000
+AB9B:00007FFE618E6DB6618E6DB66D8E7FFE7FFE738E6DB6718E7DB6738E7FFE0000
+AB9C:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73C66DBE71BE7DBE73C67FFE0000
+AB9D:00007FFE618E6DB6618E6DB66D8E7FFE7FFE738E6DB671B67DB6738E7FFE0000
+AB9E:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73866DBE718E7DBE73867FFE0000
+AB9F:00007FFE618E6DB6618E6DB66D8E7FFE7FFE73866DBE718E7DBE73BE7FFE0000
+ABA0:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61CE6DB661B66DB66DCE7FFE0000
+ABA1:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61EE6DCE61EE6DEE6DC67FFE0000
+ABA2:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61866DF661866DBE6D867FFE0000
+ABA3:00007FFE618E6DB6618E6DB66D8E7FFE7FFE618E6DF661C66DF66D8E7FFE0000
+ABA4:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61B66DB661866DF66DF67FFE0000
+ABA5:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61866DBE61866DF66D867FFE0000
+ABA6:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61CE6DBE618E6DB66DCE7FFE0000
+ABA7:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61866DF661EE6DDE6DDE7FFE0000
+ABA8:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61CE6DB661CE6DB66DCE7FFE0000
+ABA9:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61CE6DB661C66DF66DCE7FFE0000
+ABAA:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61866DB661866DB66DB67FFE0000
+ABAB:00007FFE618E6DB6618E6DB66D8E7FFE7FFE618E6DB6618E6DB66D8E7FFE0000
+ABAC:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61C66DBE61BE6DBE6DC67FFE0000
+ABAD:00007FFE618E6DB6618E6DB66D8E7FFE7FFE618E6DB661B66DB66D8E7FFE0000
+ABAE:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61866DBE618E6DBE6D867FFE0000
+ABAF:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61866DBE618E6DBE6DBE7FFE0000
+ABB0:00007FFE618E6DB6618E6DB66D8E7FFE7FFE63CE6DB663B66DB663CE7FFE0000
+ABB1:00007FFE618E6DB6618E6DB66D8E7FFE7FFE63EE6DCE63EE6DEE63C67FFE0000
+ABB2:00007FFE618E6DB6618E6DB66D8E7FFE7FFE63866DF663866DBE63867FFE0000
+ABB3:00007FFE618E6DB6618E6DB66D8E7FFE7FFE638E6DF663C66DF6638E7FFE0000
+ABB4:00007FFE618E6DB6618E6DB66D8E7FFE7FFE63B66DB663866DF663F67FFE0000
+ABB5:00007FFE618E6DB6618E6DB66D8E7FFE7FFE63866DBE63866DF663867FFE0000
+ABB6:00007FFE618E6DB6618E6DB66D8E7FFE7FFE63CE6DBE638E6DB663CE7FFE0000
+ABB7:00007FFE618E6DB6618E6DB66D8E7FFE7FFE63866DF663EE6DDE63DE7FFE0000
+ABB8:00007FFE618E6DB6618E6DB66D8E7FFE7FFE63CE6DB663CE6DB663CE7FFE0000
+ABB9:00007FFE618E6DB6618E6DB66D8E7FFE7FFE63CE6DB663C66DF663CE7FFE0000
+ABBA:00007FFE618E6DB6618E6DB66D8E7FFE7FFE63866DB663866DB663B67FFE0000
+ABBB:00007FFE618E6DB6618E6DB66D8E7FFE7FFE638E6DB6638E6DB6638E7FFE0000
+ABBC:00007FFE618E6DB6618E6DB66D8E7FFE7FFE63C66DBE63BE6DBE63C67FFE0000
+ABBD:00007FFE618E6DB6618E6DB66D8E7FFE7FFE638E6DB663B66DB6638E7FFE0000
+ABBE:00007FFE618E6DB6618E6DB66D8E7FFE7FFE63866DBE638E6DBE63867FFE0000
+ABBF:00007FFE618E6DB6618E6DB66D8E7FFE7FFE63866DBE638E6DBE63BE7FFE0000
+ABC0:00000000000000007FF824B024D02590269024902C9034903FF0000000000000
+ABC1:0000000000000000063009481084100410040808080804100220000000000000
+ABC2:00000000000000001FF80020002007A008601000100008400780000000000000
+ABC3:00000000000000007FF82400240024003FE024C02500251024E0000000000000
+ABC4:00000000000000007FF844882490249014A014A014A054A86498000000000000
+ABC5:00000000000000001FFC041008100820104010080810042003C0000000000000
+ABC6:00000000000000003FF020101020102008400FC0084028503030000000000000
+ABC7:00000000008001001FF011080890086004000400240024001800000000000000
+ABC8:00000000000000001FF8100008C0052006280410040004001800000000000000
+ABC9:000000000000000007F004900490049064909490149024907FF0000000000000
+ABCA:00000000000000001FFC00800080008008881084108409480630000000000000
+ABCB:00000000000000003FF8200810101010092008A0086008203018000000000000
+ABCC:00000000000000007FFF0808100413640D580240042008241018000000000000
+ABCD:00000000000000007FFC000001800240042008200920112060C0000000000000
+ABCE:00000000000000003FFC10001070089007E00010088815481230000000000000
+ABCF:00000000000000001FF8100008000600058004600410051018E0000000000000
+ABD0:00000000000000001FF01000102010401F801000101010201FC0000000000000
+ABD1:00000000000000003FF8124012401240124012400A480A5007E0000000000000
+ABD2:00000000000000001FF009200924092409180900090009000900000000000000
+ABD3:00000000000000000FF800100020004000800100020004300FC0004000300000
+ABD4:00000000000000000E70118810881F8010801080108010801F80000000000000
+ABD5:00000000000000000FE004400280010002800440082004400380000000000000
+ABD6:00000000000000001FF0001000E0030004000820082004400380000000000000
+ABD7:00000000000000000FFC04480288011002900450083004480384000000000000
+ABD8:00000000000000001FF004000400040004001FC0248024901860000000000000
+ABD9:00000000000000001FFC0040004000400840104010C009400640000000000000
+ABDA:00000000000000001FF00220022012200C200020002000200020000000000000
+ABDB:00000000000000003FF812481248124012401240124012401FC0000000000000
+ABDC:00000000000000000FF80010001000100010071000D000300010000000000000
+ABDD:00000000000000003FF8108010801FE010801080108010801080000000000000
+ABDE:00000000000000003FF821081110111009200920092029283118000000000000
+ABDF:00000000000000003FF8049009201200122011C00808081007E0000000000000
+ABE0:000000000000000020402080210022003F800240024002400180000000000000
+ABE1:00000000000000001FF009200920092009200920092009200FE0000000000000
+ABE2:00000000000000001FF01000080007C0042004100910092010C0000000000000
+ABE3:00180004001C0024002400180000000000000000000000000000000000000000
+ABE4:000000060009003E000800080008000800080008000800080008000000000000
+ABE5:0040002000100000000000000000000000000000000000000000000000000000
+ABE6:0000000000000000000000000006000900090006000000000000000000000000
+ABE7:00020015000E0004000C00000000000000000000000000000000000000000000
+ABE8:0000000000000000000000000000000000000000000000000360049004100220
+ABE9:000200250015000E000400000000000000000000000000000000000000000000
+ABEA:0002000500050003000100020004000000000000000000000000000000000000
+ABEB:0000000000000000044004400440044004400440044004400440000000000000
+ABEC:0000000000000000000000000000000000000000000000060006000000000000
+ABED:000000000000000000000000000000000000000000000000000000007FFE0000
+ABEE:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61866FBE638E6FBE61867FFE0000
+ABEF:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61866FBE638E6FBE61BE7FFE0000
+ABF0:0000000003000CC01020102020102010102010200CC003000000000000000000
+ABF1:000000000000000003800440082008C004000300008004400380000000000000
+ABF2:000000000000000003800440082008C004000360049004500390000000000000
+ABF3:000000000000000003800440082008CC0412036A04A804A80310000000000000
+ABF4:00000000000000000380044000800300040008C0082004400380000000000000
+ABF5:00000000000000000FC010202210251015000E00040004000400000000000000
+ABF6:00000000000000000FC010202210252015000E00048005000600040000000000
+ABF7:00000000000000000C3011480950012003D00508088809100620000000000000
+ABF8:00000000000000000FC010202210252015000E00040014000C00040000000000
+ABF9:00000000000000000FC010202210252015000E0004001F802400180000000000
+ABFA:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61866FB663866FB66FB67FFE0000
+ABFB:00007FFE618E6DB6618E6DB66D8E7FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+ABFC:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+ABFD:00007FFE618E6DB6618E6DB66D8E7FFE7FFE618E6FB663B66FB66F8E7FFE0000
+ABFE:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61866FBE638E6FBE6F867FFE0000
+ABFF:00007FFE618E6DB6618E6DB66D8E7FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+AC00:00000000001000101F9000900090009E01100110021004101810001000100000
+AC01:000000083E0802080208040E080830080008000007F800080008000800080000
+AC02:000000083E0802080208040E080830080008000000003EF80208020802080000
+AC03:000000083E0802080208040E080830080008000000001F080108011401620000
+AC04:000000083E0802080208040E080830080008000808000800080008000FF80000
+AC05:000000083E0802080208040E0808300800080000000010F8101010301ECC0000
+AC06:000000083E0802080208040E08083008000800000808087F081C08220F9C0000
+AC07:000000083E0802080208040E080830080008000003F802000200020003F80000
+AC08:000000083E0802080208040E080830080008000007F8000807F8040007F80000
+AC09:000000083E0802080208040E08083008000800003EF802083E0820083E080000
+AC0A:000000083E0802080208040E08083008000800003EF802883E8820883EF80000
+AC0B:000000083E0802080208040E08083008000800003E8802883EF820883EF80000
+AC0C:000000083E0802080208040E08083008000800001F0801081F0810141F620000
+AC0D:000000083E0802080208040E08083008000800003EF802803EF820803EF80000
+AC0E:000000083E0802080208040E08083008000800003EFC02483E4820483EFC0000
+AC0F:000000083E0802080208040E08083008000800001F08017F1F1C10221F1C0000
+AC10:000000083E0802080208040E080830080008000003F802080208020803F80000
+AC11:000000083E0802080208040E08083008000800000208020803F8020803F80000
+AC12:000000083E0802080208040E0808300800080000110811081F0811141F620000
+AC13:000000083E0802080208040E0808300800080000001000100010006801840000
+AC14:000000083E0802080208040E08083008000800000048004800A8011406620000
+AC15:000000083E0802080208040E0808300800080000000003F00408040803F00000
+AC16:000000083E0802080208040E080830080008000003F80020002000D003080000
+AC17:000000083E0802080208040E0808300800080000004003F8004000A003180000
+AC18:000000083E0802080208040E080830080008000003F8000803F8000800080000
+AC19:000000083E0802080208040E080830080008000003F8020003F8020003F80000
+AC1A:000000083E0802080208040E080830080008000000000FF8022002200FF80000
+AC1B:000000083E0802080208040E080830080008000000800FF803E0041003E00000
+AC1C:00000000001200121F9200920092009E01120112021204121812001200120000
+AC1D:000000283E28022802280438082830280028000007F800080008000800080000
+AC1E:000000283E28022802280438082830280028000000003EF80208020802080000
+AC1F:000000283E28022802280438082830280028000000003E100210022802C40000
+AC20:000000283E28022802280438082830280028002808000800080008000FF80000
+AC21:000000283E280228022804380828302800280000000020F8201020303ECC0000
+AC22:000000283E280228022804380828302800280000202021FC207020883E700000
+AC23:000000283E28022802280438082830280028000003F802000200020003F80000
+AC24:000000283E28022802280438082830280028000007F8000807F8040007F80000
+AC25:000000283E2802280228043808283028002800003EF802083E0820083E080000
+AC26:000000283E2802280228043808283028002800003EF802883E8820883EF80000
+AC27:000000283E2802280228043808283028002800003E8802883EF820883EF80000
+AC28:000000283E2802280228043808283028002800001F0801081F0810141F620000
+AC29:000000283E2802280228043808283028002800003EF802803EF820803EF80000
+AC2A:000000283E2802280228043808283028002800003EFC02483E4820483EFC0000
+AC2B:000000283E2802280228043808283028002800003E1002FE3E3820443E380000
+AC2C:000000283E28022802280438082830280028000003F802080208020803F80000
+AC2D:000000283E2802280228043808283028002800000208020803F8020803F80000
+AC2E:000000283E280228022804380828302800280000110811081F0811141F620000
+AC2F:000000283E280228022804380828302800280000000800080008003400C20000
+AC30:000000283E2802280228043808283028002800000048004800A8011406620000
+AC31:000000283E280228022804380828302800280000000001F00208020801F00000
+AC32:000000283E28022802280438082830280028000003F80020002000D003080000
+AC33:000000283E280228022804380828302800280000004003F8004000A003180000
+AC34:000000283E28022802280438082830280028000003F8000803F8000800080000
+AC35:000000283E28022802280438082830280028000003F8020003F8020003F80000
+AC36:000000283E28022802280438082830280028000000000FF8022002200FF80000
+AC37:000000283E28022802280438082830280028000000800FF803E0041003E00000
+AC38:00000000001000101F900090009E00900110011E021004101810001000100000
+AC39:000000083E080208020E0408080E30080008000007F800080008000800080000
+AC3A:000000083E080208020E0408080E30080008000000003EF80208020802080000
+AC3B:000000083E080208020E0408080E30080008000000001F080108011401620000
+AC3C:000000083E080208020E0408080E30080008000008000800080008000FF80000
+AC3D:000000083E080208020E0408080E300800080000000010F8101010301ECC0000
+AC3E:000000083E080208020E0408080E3008000800000808087F081C08220F9C0000
+AC3F:000000083E080208020E0408080E30080008000003F802000200020003F80000
+AC40:000000083E080208020E0408080E30080008000007F8000807F8040007F80000
+AC41:000000083E080208020E0408080E3008000800003EF802083E0820083E080000
+AC42:000000083E080208020E0408080E3008000800003EF802883E8820883EF80000
+AC43:000000083E080208020E0408080E3008000800003E8802883EF820883EF80000
+AC44:000000083E080208020E0408080E3008000800001F0801081F0810141F620000
+AC45:000000083E080208020E0408080E3008000800003EF802803EF820803EF80000
+AC46:000000083E080208020E0408080E3008000800003EFC02483E4820483EFC0000
+AC47:000000083E080208020E0408080E3008000800001F08017F1F1C10221F1C0000
+AC48:000000083E080208020E0408080E30080008000003F802080208020803F80000
+AC49:000000083E080208020E0408080E3008000800000208020803F8020803F80000
+AC4A:000000083E080208020E0408080E300800080000110811081F0811141F620000
+AC4B:000000083E080208020E0408080E300800080000001000100010006801840000
+AC4C:000000083E080208020E0408080E3008000800000048004800A8011406620000
+AC4D:000000083E080208020E0408080E300800080000000003F00408040803F00000
+AC4E:000000083E080208020E0408080E30080008000003F80020002000D003080000
+AC4F:000000083E080208020E0408080E300800080000004003F8004000A003180000
+AC50:000000083E080208020E0408080E30080008000003F8000803F8000800080000
+AC51:000000083E080208020E0408080E30080008000003F8020003F8020003F80000
+AC52:000000083E080208020E0408080E30080008000000000FF8022002200FF80000
+AC53:000000083E080208020E0408080E30080008000000800FF803E0041003E00000
+AC54:00000000001200121F920092009E00920112011E021204121812001200120000
+AC55:000000283E28022802380428083830280028000007F800080008000800080000
+AC56:000000283E28022802380428083830280028000000003EF80208020802080000
+AC57:000000283E28022802380428083830280028000000003E100210022802C40000
+AC58:000000283E28022802380428083830280028002808000800080008000FF80000
+AC59:000000283E280228023804280838302800280000000020F8201020303ECC0000
+AC5A:000000283E280228023804280838302800280000202021FC207020883E700000
+AC5B:000000283E28022802380428083830280028000003F802000200020003F80000
+AC5C:000000283E28022802380428083830280028000007F8000807F8040007F80000
+AC5D:000000283E2802280238042808383028002800003EF802083E0820083E080000
+AC5E:000000283E2802280238042808383028002800003EF802883E8820883EF80000
+AC5F:000000283E2802280238042808383028002800003E8802883EF820883EF80000
+AC60:000000283E2802280238042808383028002800001F0801081F0810141F620000
+AC61:000000283E2802280238042808383028002800003EF802803EF820803EF80000
+AC62:000000283E2802280238042808383028002800003EFC02483E4820483EFC0000
+AC63:000000283E2802280238042808383028002800003E1002FE3E3820443E380000
+AC64:000000283E28022802380428083830280028000003F802080208020803F80000
+AC65:000000283E2802280238042808383028002800000208020803F8020803F80000
+AC66:000000283E280228023804280838302800280000110811081F0811141F620000
+AC67:000000283E280228023804280838302800280000000800080008003400C20000
+AC68:000000283E2802280238042808383028002800000048004800A8011406620000
+AC69:000000283E280228023804280838302800280000000001F00208020801F00000
+AC6A:000000283E28022802380428083830280028000003F80020002000D003080000
+AC6B:000000283E280228023804280838302800280000004003F8004000A003180000
+AC6C:000000283E28022802380428083830280028000003F8000803F8000800080000
+AC6D:000000283E28022802380428083830280028000003F8020003F8020003F80000
+AC6E:000000283E28022802380428083830280028000000000FF8022002200FF80000
+AC6F:000000283E28022802380428083830280028000000800FF803E0041003E00000
+AC70:00000000000200021F8200820082009E01020102020204021802000200020000
+AC71:000000083E080208020804380808300800080000000007F80008000800080000
+AC72:000000083E08020802080438080830080008000000003EF80208020802080000
+AC73:000000083E08020802080438080830080008000000001F080108011401620000
+AC74:000000083E08020802080438080830080008000000001000100010001FF80000
+AC75:000000083E080208020804380808300800080000000020F8201020303ECC0000
+AC76:000000083E080208020804380808300800080000202021FC207020883E700000
+AC77:000000083E08020802080438080830080008000003F802000200020003F80000
+AC78:000000083E08020802080438080830080008000007F8000807F8040007F80000
+AC79:000000083E0802080208043808083008000800003EF802083E0820083E080000
+AC7A:000000083E0802080208043808083008000800003EF802883E8820883EF80000
+AC7B:000000083E0802080208043808083008000800003E8802883EF820883EF80000
+AC7C:000000083E0802080208043808083008000800000F8800880F8808140FA20000
+AC7D:000000083E0802080208043808083008000800003EF802803EF820803EF80000
+AC7E:000000083E0802080208043808083008000800003EFC02483E4820483EFC0000
+AC7F:000000083E0802080208043808083008000800003E1002FE3E3820443E380000
+AC80:000000083E08020802080438080830080008000003F802080208020803F80000
+AC81:000000083E0802080208043808083008000800000208020803F8020803F80000
+AC82:000000083E080208020804380808300800080000210821083F0821143F620000
+AC83:000000083E080208020804380808300800080000001000100010006801840000
+AC84:000000083E0802080208043808083008000800000048004800A8011406620000
+AC85:000000083E080208020804380808300800080000000003F00408040803F00000
+AC86:000000083E08020802080438080830080008000003F80020002000D003080000
+AC87:000000083E080208020804380808300800080000004003F8004000A003180000
+AC88:000000083E08020802080438080830080008000003F8000803F8000800080000
+AC89:000000083E08020802080438080830080008000003F8020003F8020003F80000
+AC8A:000000083E08020802080438080830080008000000000FF8022002200FF80000
+AC8B:000000083E08020802080438080830080008000000800FF803E0041003E00000
+AC8C:00000000000A000A1F8A008A008A00BA010A010A020A040A180A000A000A0000
+AC8D:000000283E280228022804E8082830280028000007F800080008000800080000
+AC8E:000000283E280228022804E8082830280028000000003EF80208020802080000
+AC8F:000000283E280228022804E8082830280028000000003E100210022802C40000
+AC90:000000283E280228022804E8082830280028000008000800080008000FF80000
+AC91:000000283E280228022804E80828302800280000000020F8201020303ECC0000
+AC92:000000283E280228022804E80828302800280000202021FC207020883E700000
+AC93:000000283E280228022804E8082830280028000003F802000200020003F80000
+AC94:000000283E280228022804E8082830280028000007F8000807F8040007F80000
+AC95:000000283E280228022804E808283028002800003EF802083E0820083E080000
+AC96:000000283E280228022804E808283028002800003EF802883E8820883EF80000
+AC97:000000283E280228022804E808283028002800003E8802883EF820883EF80000
+AC98:000000283E280228022804E808283028002800001F0801081F0810141F620000
+AC99:000000283E280228022804E808283028002800003EF802803EF820803EF80000
+AC9A:000000283E280228022804E808283028002800003EFC02483E4820483EFC0000
+AC9B:000000283E280228022804E808283028002800003E1002FE3E3820443E380000
+AC9C:000000283E280228022804E8082830280028000003F802080208020803F80000
+AC9D:000000283E280228022804E808283028002800000208020803F8020803F80000
+AC9E:000000283E280228022804E80828302800280000110811081F0811141F620000
+AC9F:000000283E280228022804E80828302800280000000800080008003400C20000
+ACA0:000000283E280228022804E808283028002800000048004800A8011406620000
+ACA1:000000283E280228022804E80828302800280000000001F00208020801F00000
+ACA2:000000283E280228022804E8082830280028000003F80020002000D003080000
+ACA3:000000283E280228022804E80828302800280000004003F8004000A003180000
+ACA4:000000283E280228022804E8082830280028000003F8000803F8000800080000
+ACA5:000000283E280228022804E8082830280028000003F8020003F8020003F80000
+ACA6:000000283E280228022804E8082830280028000000000FF8022002200FF80000
+ACA7:000000283E280228022804E8082830280028000000800FF803E0041003E00000
+ACA8:00000000000200021F820082009E00820102011E020204021802000200020000
+ACA9:000000083E080208023804080838300800080000000007F80008000800080000
+ACAA:000000083E08020802380408083830080008000000003EF80208020802080000
+ACAB:000000083E08020802380408083830080008000000001F080108011401620000
+ACAC:000000083E08020802380408083830080008000800001000100010001FF80000
+ACAD:000000083E080208023804080838300800080000000020F8201020303ECC0000
+ACAE:000000083E080208023804080838300800080000202021FC207020883E700000
+ACAF:000000083E08020802380408083830080008000003F802000200020003F80000
+ACB0:000000083E08020802380408083830080008000007F8000807F8040007F80000
+ACB1:000000083E0802080238040808383008000800003EF802083E0820083E080000
+ACB2:000000083E0802080238040808383008000800003EF802883E8820883EF80000
+ACB3:000000083E0802080238040808383008000800003E8802883EF820883EF80000
+ACB4:000000083E0802080238040808383008000800000F8800880F8808140FA20000
+ACB5:000000083E0802080238040808383008000800003EF802803EF820803EF80000
+ACB6:000000083E0802080238040808383008000800003EFC02483E4820483EFC0000
+ACB7:000000083E0802080238040808383008000800003E1002FE3E3820443E380000
+ACB8:000000083E08020802380408083830080008000003F802080208020803F80000
+ACB9:000000083E0802080238040808383008000800000208020803F8020803F80000
+ACBA:000000083E080208023804080838300800080000210821083F0821143F620000
+ACBB:000000083E080208023804080838300800080000001000100010006801840000
+ACBC:000000083E0802080238040808383008000800000048004800A8011406620000
+ACBD:000000083E080208023804080838300800080000000003F00408040803F00000
+ACBE:000000083E08020802380408083830080008000003F80020002000D003080000
+ACBF:000000083E080208023804080838300800080000004003F8004000A003180000
+ACC0:000000083E08020802380408083830080008000003F8000803F8000800080000
+ACC1:000000083E08020802380408083830080008000003F8020003F8020003F80000
+ACC2:000000083E08020802380408083830080008000000000FF8022002200FF80000
+ACC3:000000083E08020802380408083830080008000000800FF803E0041003E00000
+ACC4:00000000000A000A1F8A008A00BA008A010A013A020A040A180A000A000A0000
+ACC5:000000283E28022802E8042808E830280028000007F800080008000800080000
+ACC6:000000283E28022802E8042808E830280028000000003EF80208020802080000
+ACC7:000000283E28022802E8042808E830280028000000003E100210022802C40000
+ACC8:000000283E28022802E8042808E830280028002808000800080008000FF80000
+ACC9:000000283E28022802E8042808E8302800280000000020F8201020303ECC0000
+ACCA:000000283E28022802E8042808E8302800280000202021FC207020883E700000
+ACCB:000000283E28022802E8042808E830280028000003F802000200020003F80000
+ACCC:000000283E28022802E8042808E830280028000007F8000807F8040007F80000
+ACCD:000000283E28022802E8042808E83028002800003EF802083E0820083E080000
+ACCE:000000283E28022802E8042808E83028002800003EF802883E8820883EF80000
+ACCF:000000283E28022802E8042808E83028002800003E8802883EF820883EF80000
+ACD0:000000283E28022802E8042808E83028002800001F0801081F0810141F620000
+ACD1:000000283E28022802E8042808E83028002800003EF802803EF820803EF80000
+ACD2:000000283E28022802E8042808E83028002800003EFC02483E4820483EFC0000
+ACD3:000000283E28022802E8042808E83028002800003E1002FE3E3820443E380000
+ACD4:000000283E28022802E8042808E830280028000003F802080208020803F80000
+ACD5:000000283E28022802E8042808E83028002800000208020803F8020803F80000
+ACD6:000000283E28022802E8042808E8302800280000110811081F0811141F620000
+ACD7:000000283E28022802E8042808E8302800280000000800080008003400C20000
+ACD8:000000283E28022802E8042808E83028002800000048004800A8011406620000
+ACD9:000000283E28022802E8042808E8302800280000000001F00208020801F00000
+ACDA:000000283E28022802E8042808E830280028000003F80020002000D003080000
+ACDB:000000283E28022802E8042808E8302800280000004003F8004000A003180000
+ACDC:000000283E28022802E8042808E830280028000003F8000803F8000800080000
+ACDD:000000283E28022802E8042808E830280028000003F8020003F8020003F80000
+ACDE:000000283E28022802E8042808E830280028000000000FF8022002200FF80000
+ACDF:000000283E28022802E8042808E830280028000000800FF803E0041003E00000
+ACE0:00000000000000003FF0001000100010001002100200020002007FFC00000000
+ACE1:000000001FF0001000100010011001007FFC00001FF000100010001000100000
+ACE2:000000001FF0001000100010011001007FFC000000003EF80208020802080000
+ACE3:000000001FF0001000100010011001007FFC000000001E100210022802C40000
+ACE4:000000001FF0001000100010011001007FFC000000001000100010001FF00000
+ACE5:000000001FF0001000100010011001007FFC0000000020F8201020303ECC0000
+ACE6:000000001FF0001000100010011001007FFC0000202021FC207020883E700000
+ACE7:000000001FF0001000100010011001007FFC00001FF01000100010001FF00000
+ACE8:000000001FF0001000100010011001007FFC00001FF000101FF010001FF00000
+ACE9:000000001FF0001000100010011001007FFC00003EF802083E0820083E080000
+ACEA:000000001FF0001000100010011001007FFC00003EF802883E8820883EF80000
+ACEB:000000001FF0001000100010011001007FFC00003E8802883EF820883EF80000
+ACEC:000000001FF0001000100010011001007FFC00003E1002103E1020283EC40000
+ACED:000000001FF0001000100010011001007FFC00003EF802803EF820803EF80000
+ACEE:000000001FF0001000100010011001007FFC00003EFC02483E4820483EFC0000
+ACEF:000000001FF0001000100010011001007FFC00003E2003FC3E7020883E700000
+ACF0:000000001FF0001000100010011001007FFC00001FF01010101010101FF00000
+ACF1:000000001FF0001000100010011001007FFC0000101010101FF010101FF00000
+ACF2:000000001FF0001000100010011001007FFC0000222022203E2022503E880000
+ACF3:000000001FF0001000100010011001007FFC000000000100010002800C400000
+ACF4:000000001FF0001000100010011001007FFC00000000024002400DA033100000
+ACF5:000000001FF0001000100010011001007FFC0000000007C00820082007C00000
+ACF6:000000001FF0001000100010011001007FFC0000000007E00080014006200000
+ACF7:000000001FF0001000100010011001007FFC0000008007E00080014006200000
+ACF8:000000001FF0001000100010011001007FFC00001FF000101FF0001000100000
+ACF9:000000001FF0001000100010011001007FFC00001FF010001FF010001FF00000
+ACFA:000000001FF0001000100010011001007FFC000000001FF0044004401FF00000
+ACFB:000000001FF0001000100010011001007FFC000001001FF007C0082007C00000
+ACFC:00000000001000103FD000500050005E0450041004107FD00010001000100000
+ACFD:000000081F880088008E0088048804087FE8000007F800080008000800080000
+ACFE:000000081F880088008E0088048804087FE8000000003EF80208020802080000
+ACFF:000000081F880088008E0088048804087FE8000000001F080108011401620000
+AD00:000000081F880088008E0088048804087FE8000008000800080008000FF80000
+AD01:000000081F880088008E0088048804087FE80000000010F8101010301ECC0000
+AD02:000000081F880088008E0088048804087FE800000808087F081C08220F9C0000
+AD03:000000081F880088008E0088048804087FE8000003F802000200020003F80000
+AD04:000000081F880088008E0088048804087FE8000007F8000807F8040007F80000
+AD05:000000081F880088008E0088048804087FE800003EF802083E0820083E080000
+AD06:000000081F880088008E0088048804087FE800003EF802883E8820883EF80000
+AD07:000000081F880088008E0088048804087FE800003E8802883EF820883EF80000
+AD08:000000081F880088008E0088048804087FE800001F0801081F0810141F620000
+AD09:000000081F880088008E0088048804087FE800003EF802803EF820803EF80000
+AD0A:000000081F880088008E0088048804087FE800003EFC02483E4820483EFC0000
+AD0B:000000081F880088008E0088048804087FE800001F08017F1F1C10221F1C0000
+AD0C:000000081F880088008E0088048804087FE8000003F802080208020803F80000
+AD0D:000000081F880088008E0088048804087FE800000208020803F8020803F80000
+AD0E:000000081F880088008E0088048804087FE80000110811081F0811141F620000
+AD0F:000000081F880088008E0088048804087FE80000001000100010006801840000
+AD10:000000081F880088008E0088048804087FE800000048004800A8011406620000
+AD11:000000081F880088008E0088048804087FE80000000003F00408040803F00000
+AD12:000000081F880088008E0088048804087FE8000003F80020002000D003080000
+AD13:000000081F880088008E0088048804087FE80000004003F8004000A003180000
+AD14:000000081F880088008E0088048804087FE8000003F8000803F8000800080000
+AD15:000000081F880088008E0088048804087FE8000003F8020003F8020003F80000
+AD16:000000081F880088008E0088048804087FE8000000000FF8022002200FF80000
+AD17:000000081F880088008E0088048804087FE8000000800FF803E0041003E00000
+AD18:00000000001200123FD200520052005E0452041204127FD20012001200120000
+AD19:000000281FA800A800B800A804A804287FA8000007F800080008000800080000
+AD1A:000000281FA800A800B800A804A804287FA8000000003EF80208020802080000
+AD1B:000000281FA800A800B800A804A804287FA8000000001F080108011401620000
+AD1C:000000281FA800A800B800A804A804287FA8000008000800080008000FF80000
+AD1D:000000281FA800A800B800A804A804287FA80000000010F8101010301ECC0000
+AD1E:000000281FA800A800B800A804A804287FA800000808087F081C08220F9C0000
+AD1F:000000281FA800A800B800A804A804287FA8000003F802000200020003F80000
+AD20:000000281FA800A800B800A804A804287FA8000007F8000807F8040007F80000
+AD21:000000281FA800A800B800A804A804287FA800003EF802083E0820083E080000
+AD22:000000281FA800A800B800A804A804287FA800003EF802883E8820883EF80000
+AD23:000000281FA800A800B800A804A804287FA800003E8802883EF820883EF80000
+AD24:000000281FA800A800B800A804A804287FA800001F0801081F0810141F620000
+AD25:000000281FA800A800B800A804A804287FA800003EF802803EF820803EF80000
+AD26:000000281FA800A800B800A804A804287FA800003EFC02483E4820483EFC0000
+AD27:000000281FA800A800B800A804A804287FA800001F08017F1F1C10221F1C0000
+AD28:000000281FA800A800B800A804A804287FA8000003F802080208020803F80000
+AD29:000000281FA800A800B800A804A804287FA800000208020803F8020803F80000
+AD2A:000000281FA800A800B800A804A804287FA80000110811081F0811141F620000
+AD2B:000000281FA800A800B800A804A804287FA80000001000100010006801840000
+AD2C:000000281FA800A800B800A804A804287FA800000048004800A8011406620000
+AD2D:000000281FA800A800B800A804A804287FA80000000003F00408040803F00000
+AD2E:000000281FA800A800B800A804A804287FA8000003F80020002000D003080000
+AD2F:000000281FA800A800B800A804A804287FA80000004003F8004000A003180000
+AD30:000000281FA800A800B800A804A804287FA8000003F8000803F8000800080000
+AD31:000000281FA800A800B800A804A804287FA8000003F8020003F8020003F80000
+AD32:000000281FA800A800B800A804A804287FA8000000000FF8022002200FF80000
+AD33:000000281FA800A800B800A804A804287FA8000000800FF803E0041003E00000
+AD34:00000000000400043FC40044004400440444040404047FF40004000400040000
+AD35:000000081F88008800880088048804087FE8000007F800080008000800080000
+AD36:000000081F88008800880088048804087FE8000000003EF80208020802080000
+AD37:000000081F88008800880088048804087FE8000000001F080108011401620000
+AD38:000000081F88008800880088048804087FE8000008000800080008000FF80000
+AD39:000000081F88008800880088048804087FE80000000010F8101010301ECC0000
+AD3A:000000081F88008800880088048804087FE800000808087F081C08220F9C0000
+AD3B:000000081F88008800880088048804087FE8000003F802000200020003F80000
+AD3C:000000081F88008800880088048804087FE8000007F8000807F8040007F80000
+AD3D:000000081F88008800880088048804087FE800003EF802083E0820083E080000
+AD3E:000000081F88008800880088048804087FE800003EF802883E8820883EF80000
+AD3F:000000081F88008800880088048804087FE800003E8802883EF820883EF80000
+AD40:000000081F88008800880088048804087FE800001F0801081F0810141F620000
+AD41:000000081F88008800880088048804087FE800003EF802803EF820803EF80000
+AD42:000000081F88008800880088048804087FE800003EFC02483E4820483EFC0000
+AD43:000000081F88008800880088048804087FE800001F08017F1F1C10221F1C0000
+AD44:000000081F88008800880088048804087FE8000003F802080208020803F80000
+AD45:000000081F88008800880088048804087FE800000208020803F8020803F80000
+AD46:000000081F88008800880088048804087FE80000110811081F0811141F620000
+AD47:000000081F88008800880088048804087FE80000001000100010006801840000
+AD48:000000081F88008800880088048804087FE800000048004800A8011406620000
+AD49:000000081F88008800880088048804087FE80000000003F00408040803F00000
+AD4A:000000081F88008800880088048804087FE8000003F80020002000D003080000
+AD4B:000000081F88008800880088048804087FE80000004003F8004000A003180000
+AD4C:000000081F88008800880088048804087FE8000003F8000803F8000800080000
+AD4D:000000081F88008800880088048804087FE8000003F8020003F8020003F80000
+AD4E:000000081F88008800880088048804087FE8000000000FF8022002200FF80000
+AD4F:000000081F88008800880088048804087FE8000000800FF803E0041003E00000
+AD50:00000000000000003FF0001000100010001008900880088008807FFC00000000
+AD51:000000001FF0001000100010049004807FFC00001FF000100010001000100000
+AD52:000000001FF0001000100010049004807FFC000000003EF80208020802080000
+AD53:000000001FF0001000100010049004807FFC000000001E100210022802C40000
+AD54:000000001FF0001000100010049004807FFC000000001000100010001FF00000
+AD55:000000001FF0001000100010049004807FFC0000000020F8201020303ECC0000
+AD56:000000001FF0001000100010049004807FFC0000202021FC207020883E700000
+AD57:000000001FF0001000100010049004807FFC00001FF01000100010001FF00000
+AD58:000000001FF0001000100010049004807FFC00001FF000101FF010001FF00000
+AD59:000000001FF0001000100010049004807FFC00003EF802083E0820083E080000
+AD5A:000000001FF0001000100010049004807FFC00003EF802883E8820883EF80000
+AD5B:000000001FF0001000100010049004807FFC00003E8802883EF820883EF80000
+AD5C:000000001FF0001000100010049004807FFC00003E1002103E1020283EC40000
+AD5D:000000001FF0001000100010049004807FFC00003EF802803EF820803EF80000
+AD5E:000000001FF0001000100010049004807FFC00003EFC02483E4820483EFC0000
+AD5F:000000001FF0001000100010049004807FFC00003E2003FC3E7020883E700000
+AD60:000000001FF0001000100010049004807FFC00001FF01010101010101FF00000
+AD61:000000001FF0001000100010049004807FFC0000101010101FF010101FF00000
+AD62:000000001FF0001000100010049004807FFC0000222022203E2022503E880000
+AD63:000000001FF0001000100010049004807FFC000000000100010002800C400000
+AD64:000000001FF0001000100010049004807FFC00000000024002400DA033100000
+AD65:000000001FF0001000100010049004807FFC0000000007C00820082007C00000
+AD66:000000001FF0001000100010049004807FFC0000000007E00080014006200000
+AD67:000000001FF0001000100010049004807FFC0000008007E00080014006200000
+AD68:000000001FF0001000100010049004807FFC00001FF000101FF0001000100000
+AD69:000000001FF0001000100010049004807FFC00001FF010001FF010001FF00000
+AD6A:000000001FF0001000100010049004807FFC000000001FF0044004401FF00000
+AD6B:000000001FF0001000100010049004807FFC000001001FF007C0082007C00000
+AD6C:0000000000003FE00020002000200020002000003FF801000100010001000000
+AD6D:000000001FF000100010001000007FFC010001001FF000100010001000100000
+AD6E:000000001FF000100010001000007FFC0100010000003EF80208020802080000
+AD6F:000000001FF000100010001000007FFC0100010000001E100210022802C40000
+AD70:000000001FF0001000100010000000007FFC010001001100100010001FF00000
+AD71:000000001FF000100010001000007FFC01000100000020F8201020303ECC0000
+AD72:000000001FF000100010001000007FFC01000100202021FC207020883E700000
+AD73:000000001FF000100010001000007FFC010001001FF01000100010001FF00000
+AD74:000000001FF000100010001000007FFC010001001FF000101FF010001FF00000
+AD75:000000001FF000100010001000007FFC010001003EF802083E0820083E080000
+AD76:000000001FF000100010001000007FFC010001003EF802883E8820883EF80000
+AD77:000000001FF000100010001000007FFC010001003E8802883EF820883EF80000
+AD78:000000001FF000100010001000007FFC010001003E1002103E1020283EC40000
+AD79:000000001FF000100010001000007FFC010001003EF802803EF820803EF80000
+AD7A:000000001FF000100010001000007FFC010001003EFC02483E4820483EFC0000
+AD7B:000000001FF000100010001000007FFC010001003E2003FC3E7020883E700000
+AD7C:000000001FF000100010001000007FFC010001001FF01010101010101FF00000
+AD7D:000000001FF000100010001000007FFC01000100101010101FF010101FF00000
+AD7E:000000001FF000100010001000007FFC01000100222022203E2022503E880000
+AD7F:000000001FF000100010001000007FFC0100010000000100010002800C400000
+AD80:000000001FF000100010001000007FFC010001000000024002400DA033100000
+AD81:000000001FF000100010001000007FFC01000100000007C00820082007C00000
+AD82:000000001FF000100010001000007FFC01000100000007E00080014006200000
+AD83:000000001FF000100010001000007FFC01000100008007E00080014006200000
+AD84:000000001FF000100010001000007FFC010001001FF000101FF0001000100000
+AD85:000000001FF000100010001000007FFC010001001FF010001FF010001FF00000
+AD86:000000001FF000100010001000007FFC0100010000001FF0044004401FF00000
+AD87:000000001FF000100010001000007FFC0100010001001FF007C0082007C00000
+AD88:00000008000800083FE8002800280028002800087FE8040804F8040804080000
+AD89:000800083F080108010801087FE8027802080000000007F80008000800080000
+AD8A:000800083F080108010801087FE802780208000000003EF80208020802080000
+AD8B:000800083F080108010801087FE802780208000000001F080108011401620000
+AD8C:000800083F0801080108010800087FE80278020802081000100010001FF80000
+AD8D:000800083F080108010801087FE8027802080000000020F8201020303ECC0000
+AD8E:000800083F080108010801087FE8027802080000202021FC207020883E700000
+AD8F:000800083F080108010801087FE802780208000003F802000200020003F80000
+AD90:000800083F080108010801087FE802780208000007F8000807F8040007F80000
+AD91:000800083F080108010801087FE80278020800003EF802083E0820083E080000
+AD92:000800083F080108010801087FE80278020800003EF802883E8820883EF80000
+AD93:000800083F080108010801087FE80278020800003E8802883EF820883EF80000
+AD94:000800083F080108010801087FE80278020800000F8800880F8808140FA20000
+AD95:000800083F080108010801087FE80278020800003EF802803EF820803EF80000
+AD96:000800083F080108010801087FE80278020800003EFC02483E4820483EFC0000
+AD97:000800083F080108010801087FE80278020800003E1002FE3E3820443E380000
+AD98:000800083F080108010801087FE802780208000003F802080208020803F80000
+AD99:000800083F080108010801087FE80278020800000208020803F8020803F80000
+AD9A:000800083F080108010801087FE8027802080000210821083F0821143F620000
+AD9B:000800083F080108010801087FE8027802080000001000100010006801840000
+AD9C:000800083F080108010801087FE80278020800000048004800A8011406620000
+AD9D:000800083F080108010801087FE8027802080000000003F00408040803F00000
+AD9E:000800083F080108010801087FE802780208000003F80020002000D003080000
+AD9F:000800083F080108010801087FE8027802080000004003F8004000A003180000
+ADA0:000800083F080108010801087FE802780208000003F8000803F8000800080000
+ADA1:000800083F080108010801087FE802780208000003F8020003F8020003F80000
+ADA2:000800083F080108010801087FE802780208000000000FF8022002200FF80000
+ADA3:000800083F080108010801087FE802780208000000800FF803E0041003E00000
+ADA4:0000000A000A000A3FEA002A002A002A002A000A7FEA040A047A040A040A0000
+ADA5:002800283F280128012801287FA805E804280000000007F80008000800080000
+ADA6:002800283F280128012801287FA805E80428000000003EF80208020802080000
+ADA7:002800283F280128012801287FA805E80428000000001F080108011401620000
+ADA8:002800283F2801280128012800287FA8042805E804281428100010001FF80000
+ADA9:002800283F280128012801287FA805E804280000000020F8201020303ECC0000
+ADAA:002800283F280128012801287FA805E804280000202021FC207020883E700000
+ADAB:002800283F280128012801287FA805E80428000003F802000200020003F80000
+ADAC:002800283F280128012801287FA805E80428000007F8000807F8040007F80000
+ADAD:002800283F280128012801287FA805E8042800003EF802083E0820083E080000
+ADAE:002800283F280128012801287FA805E8042800003EF802883E8820883EF80000
+ADAF:002800283F280128012801287FA805E8042800003E8802883EF820883EF80000
+ADB0:002800283F280128012801287FA805E8042800000F8800880F8808140FA20000
+ADB1:002800283F280128012801287FA805E8042800003EF802803EF820803EF80000
+ADB2:002800283F280128012801287FA805E8042800003EFC02483E4820483EFC0000
+ADB3:002800283F280128012801287FA805E8042800003E1002FE3E3820443E380000
+ADB4:002800283F280128012801287FA805E80428000003F802080208020803F80000
+ADB5:002800283F280128012801287FA805E8042800000208020803F8020803F80000
+ADB6:002800283F280128012801287FA805E804280000210821083F0821143F620000
+ADB7:002800283F280128012801287FA805E804280000001000100010006801840000
+ADB8:002800283F280128012801287FA805E8042800000048004800A8011406620000
+ADB9:002800283F280128012801287FA805E804280000000003F00408040803F00000
+ADBA:002800283F280128012801287FA805E80428000003F80020002000D003080000
+ADBB:002800283F280128012801287FA805E804280000004003F8004000A003180000
+ADBC:002800283F280128012801287FA805E80428000003F8000803F8000800080000
+ADBD:002800283F280128012801287FA805E80428000003F8020003F8020003F80000
+ADBE:002800283F280128012801287FA805E80428000000000FF8022002200FF80000
+ADBF:002800283F280128012801287FA805E80428000000800FF803E0041003E00000
+ADC0:00000008000800083FE8002800280028002800087FE804080408040804080000
+ADC1:000800083F080108010801087FE8020802000000000007F80008000800080000
+ADC2:000800083F080108010801087FE802080200000000003EF80208020802080000
+ADC3:000800083F080108010801087FE802080200000000001F080108011401620000
+ADC4:000800083F0801080108010800087FE80208020802081008100010001FF80000
+ADC5:000800083F080108010801087FE8020802000000000020F8201020303ECC0000
+ADC6:000800083F080108010801087FE8020802000000202021FC207020883E700000
+ADC7:000800083F080108010801087FE802080200000003F802000200020003F80000
+ADC8:000800083F080108010801087FE802080200000007F8000807F8040007F80000
+ADC9:000800083F080108010801087FE80208020000003EF802083E0820083E080000
+ADCA:000800083F080108010801087FE80208020000003EF802883E8820883EF80000
+ADCB:000800083F080108010801087FE80208020000003E8802883EF820883EF80000
+ADCC:000800083F080108010801087FE80208020000000F8800880F8808140FA20000
+ADCD:000800083F080108010801087FE80208020000003EF802803EF820803EF80000
+ADCE:000800083F080108010801087FE80208020000003EFC02483E4820483EFC0000
+ADCF:000800083F080108010801087FE80208020000003E1002FE3E3820443E380000
+ADD0:000800083F080108010801087FE802080200000003F802080208020803F80000
+ADD1:000800083F080108010801087FE80208020000000208020803F8020803F80000
+ADD2:000800083F080108010801087FE8020802000000210821083F0821143F620000
+ADD3:000800083F080108010801087FE8020802000000001000100010006801840000
+ADD4:000800083F080108010801087FE80208020000000048004800A8011406620000
+ADD5:000800083F080108010801087FE8020802000000000003F00408040803F00000
+ADD6:000800083F080108010801087FE802080200000003F80020002000D003080000
+ADD7:000800083F080108010801087FE8020802000000004003F8004000A003180000
+ADD8:000800083F080108010801087FE802080200000003F8000803F8000800080000
+ADD9:000800083F080108010801087FE802080200000003F8020003F8020003F80000
+ADDA:000800083F080108010801087FE802080200000000000FF8022002200FF80000
+ADDB:000800083F080108010801087FE802080200000000800FF803E0041003E00000
+ADDC:0000000000003FE00020002000200020002000007FFC04400440044004400000
+ADDD:000000001FF000100010001000007FFC044004401FF000100010001000100000
+ADDE:000000001FF000100010001000007FFC0440044000003EF80208020802080000
+ADDF:000000001FF000100010001000007FFC0440044000001E100210022802C40000
+ADE0:000000001FF0001000100010000000007FFC044004401440100010001FF00000
+ADE1:000000001FF000100010001000007FFC04400440000020F8201020303ECC0000
+ADE2:000000001FF000100010001000007FFC04400440202021FC207020883E700000
+ADE3:000000001FF000100010001000007FFC044004401FF01000100010001FF00000
+ADE4:000000001FF000100010001000007FFC044004401FF000101FF010001FF00000
+ADE5:000000001FF000100010001000007FFC044004403EF802083E0820083E080000
+ADE6:000000001FF000100010001000007FFC044004403EF802883E8820883EF80000
+ADE7:000000001FF000100010001000007FFC044004403E8802883EF820883EF80000
+ADE8:000000001FF000100010001000007FFC044004403E1002103E1020283EC40000
+ADE9:000000001FF000100010001000007FFC044004403EF802803EF820803EF80000
+ADEA:000000001FF000100010001000007FFC044004403EFC02483E4820483EFC0000
+ADEB:000000001FF000100010001000007FFC044004403E2003FC3E7020883E700000
+ADEC:000000001FF000100010001000007FFC044004401FF01010101010101FF00000
+ADED:000000001FF000100010001000007FFC04400440101010101FF010101FF00000
+ADEE:000000001FF000100010001000007FFC04400440222022203E2022503E880000
+ADEF:000000001FF000100010001000007FFC0440044000000100010002800C400000
+ADF0:000000001FF000100010001000007FFC044004400000024002400DA033100000
+ADF1:000000001FF000100010001000007FFC04400440000007C00820082007C00000
+ADF2:000000001FF000100010001000007FFC04400440000007E00080014006200000
+ADF3:000000001FF000100010001000007FFC04400440008007E00080014006200000
+ADF4:000000001FF000100010001000007FFC044004401FF000101FF0001000100000
+ADF5:000000001FF000100010001000007FFC044004401FF010001FF010001FF00000
+ADF6:000000001FF000100010001000007FFC0440044000001FF0044004401FF00000
+ADF7:000000001FF000100010001000007FFC0440044001001FF007C0082007C00000
+ADF8:00000000000000003FF00010001000100010001000007FFC0000000000000000
+ADF9:000000001FF0001000100010001000007FFC00001FF000100010001000100000
+ADFA:000000001FF0001000100010001000007FFC000000003EF80208020802080000
+ADFB:000000001FF0001000100010001000007FFC000000001E100210022802C40000
+ADFC:000000001FF0001000100010001000007FFC000000001000100010001FF00000
+ADFD:000000001FF0001000100010001000007FFC0000000020F8201020303ECC0000
+ADFE:000000001FF0001000100010001000007FFC0000202021FC207020883E700000
+ADFF:000000001FF0001000100010001000007FFC00001FF01000100010001FF00000
+AE00:000000001FF0001000100010001000007FFC00001FF000101FF010001FF00000
+AE01:000000001FF0001000100010001000007FFC00003EF802083E0820083E080000
+AE02:000000001FF0001000100010001000007FFC00003EF802883E8820883EF80000
+AE03:000000001FF0001000100010001000007FFC00003E8802883EF820883EF80000
+AE04:000000001FF0001000100010001000007FFC00003E1002103E1020283EC40000
+AE05:000000001FF0001000100010001000007FFC00003EF802803EF820803EF80000
+AE06:000000001FF0001000100010001000007FFC00003EFC02483E4820483EFC0000
+AE07:000000001FF0001000100010001000007FFC00003E2003FC3E7020883E700000
+AE08:000000001FF0001000100010001000007FFC00001FF01010101010101FF00000
+AE09:000000001FF0001000100010001000007FFC0000101010101FF010101FF00000
+AE0A:000000001FF0001000100010001000007FFC0000222022203E2022503E880000
+AE0B:000000001FF0001000100010001000007FFC000000000100010002800C400000
+AE0C:000000001FF0001000100010001000007FFC00000000024002400DA033100000
+AE0D:000000001FF0001000100010001000007FFC0000000007C00820082007C00000
+AE0E:000000001FF0001000100010001000007FFC0000000007E00080014006200000
+AE0F:000000001FF0001000100010001000007FFC0000008007E00080014006200000
+AE10:000000001FF0001000100010001000007FFC00001FF000101FF0001000100000
+AE11:000000001FF0001000100010001000007FFC00001FF010001FF010001FF00000
+AE12:000000001FF0001000100010001000007FFC000000001FF0044004401FF00000
+AE13:000000001FF0001000100010001000007FFC000001001FF007C0082007C00000
+AE14:00000000000800083FC80048004800480048000800087FE80008000800080000
+AE15:000000081F88008800880088008800087FE8000007F800080008000800080000
+AE16:000000081F88008800880088008800087FE8000000003EF80208020802080000
+AE17:000000081F88008800880088008800087FE8000000001F080108011401620000
+AE18:000000081F88008800880088008800087FE8000008000800080008000FF80000
+AE19:000000081F88008800880088008800087FE80000000010F8101010301ECC0000
+AE1A:000000081F88008800880088008800087FE800000808087F081C08220F9C0000
+AE1B:000000081F88008800880088008800087FE8000003F802000200020003F80000
+AE1C:000000081F88008800880088008800087FE8000007F8000807F8040007F80000
+AE1D:000000081F88008800880088008800087FE800003EF802083E0820083E080000
+AE1E:000000081F88008800880088008800087FE800003EF802883E8820883EF80000
+AE1F:000000081F88008800880088008800087FE800003E8802883EF820883EF80000
+AE20:000000081F88008800880088008800087FE800001F0801081F0810141F620000
+AE21:000000081F88008800880088008800087FE800003EF802803EF820803EF80000
+AE22:000000081F88008800880088008800087FE800003EFC02483E4820483EFC0000
+AE23:000000081F88008800880088008800087FE800001F08017F1F1C10221F1C0000
+AE24:000000081F88008800880088008800087FE8000003F802080208020803F80000
+AE25:000000081F88008800880088008800087FE800000208020803F8020803F80000
+AE26:000000081F88008800880088008800087FE80000110811081F0811141F620000
+AE27:000000081F88008800880088008800087FE80000001000100010006801840000
+AE28:000000081F88008800880088008800087FE800000048004800A8011406620000
+AE29:000000081F88008800880088008800087FE80000000003F00408040803F00000
+AE2A:000000081F88008800880088008800087FE8000003F80020002000D003080000
+AE2B:000000081F88008800880088008800087FE80000004003F8004000A003180000
+AE2C:000000081F88008800880088008800087FE8000003F8000803F8000800080000
+AE2D:000000081F88008800880088008800087FE8000003F8020003F8020003F80000
+AE2E:000000081F88008800880088008800087FE8000000000FF8022002200FF80000
+AE2F:000000081F88008800880088008800087FE8000000800FF803E0041003E00000
+AE30:00000000000800081F8800880088008801080108020804081808000800080000
+AE31:000000083E080208020804080808300800080000000007F80008000800080000
+AE32:000000083E08020802080408080830080008000000003EF80208020802080000
+AE33:000000083E08020802080408080830080008000000001F080108011401620000
+AE34:000000083E08020802080408080830080008000800001000100010001FF80000
+AE35:000000083E080208020804080808300800080000000020F8201020303ECC0000
+AE36:000000083E080208020804080808300800080000202021FC207020883E700000
+AE37:000000083E08020802080408080830080008000003F802000200020003F80000
+AE38:000000083E08020802080408080830080008000007F8000807F8040007F80000
+AE39:000000083E0802080208040808083008000800003EF802083E0820083E080000
+AE3A:000000083E0802080208040808083008000800003EF802883E8820883EF80000
+AE3B:000000083E0802080208040808083008000800003E8802883EF820883EF80000
+AE3C:000000083E0802080208040808083008000800000F8800880F8808140FA20000
+AE3D:000000083E0802080208040808083008000800003EF802803EF820803EF80000
+AE3E:000000083E0802080208040808083008000800003EFC02483E4820483EFC0000
+AE3F:000000083E0802080208040808083008000800003E1002FE3E3820443E380000
+AE40:000000083E08020802080408080830080008000003F802080208020803F80000
+AE41:000000083E0802080208040808083008000800000208020803F8020803F80000
+AE42:000000083E080208020804080808300800080000210821083F0821143F620000
+AE43:000000083E080208020804080808300800080000001000100010006801840000
+AE44:000000083E0802080208040808083008000800000048004800A8011406620000
+AE45:000000083E080208020804080808300800080000000003F00408040803F00000
+AE46:000000083E08020802080408080830080008000003F80020002000D003080000
+AE47:000000083E080208020804080808300800080000004003F8004000A003180000
+AE48:000000083E08020802080408080830080008000003F8000803F8000800080000
+AE49:000000083E08020802080408080830080008000003F8020003F8020003F80000
+AE4A:000000083E08020802080408080830080008000000000FF8022002200FF80000
+AE4B:000000083E08020802080408080830080008000000800FF803E0041003E00000
+AE4C:00000000001000107B9008900890089E11101110221044100810001000100000
+AE4D:00000008F78810881088108E2108C6080008000007F800080008000800080000
+AE4E:00000008F78810881088108E2108C6080008000000003EF80208020802080000
+AE4F:00000008F78810881088108E2108C6080008000000001F080108011401620000
+AE50:00000008F78810881088108E2108C6080008000808000800080008000FF80000
+AE51:00000008F78810881088108E2108C60800080000000010F8101010301ECC0000
+AE52:00000008F78810881088108E2108C608000800000808087F081C08220F9C0000
+AE53:00000008F78810881088108E2108C6080008000003F802000200020003F80000
+AE54:00000008F78810881088108E2108C6080008000007F8000807F8040007F80000
+AE55:00000008F78810881088108E2108C608000800003EF802083E0820083E080000
+AE56:00000008F78810881088108E2108C608000800003EF802883E8820883EF80000
+AE57:00000008F78810881088108E2108C608000800003E8802883EF820883EF80000
+AE58:00000008F78810881088108E2108C608000800001F0801081F0810141F620000
+AE59:00000008F78810881088108E2108C608000800003EF802803EF820803EF80000
+AE5A:00000008F78810881088108E2108C608000800003EFC02483E4820483EFC0000
+AE5B:00000008F78810881088108E2108C608000800001F08017F1F1C10221F1C0000
+AE5C:00000008F78810881088108E2108C6080008000003F802080208020803F80000
+AE5D:00000008F78810881088108E2108C608000800000208020803F8020803F80000
+AE5E:00000008F78810881088108E2108C60800080000110811081F0811141F620000
+AE5F:00000008F78810881088108E2108C60800080000001000100010006801840000
+AE60:00000008F78810881088108E2108C608000800000048004800A8011406620000
+AE61:00000008F78810881088108E2108C60800080000000003F00408040803F00000
+AE62:00000008F78810881088108E2108C6080008000003F80020002000D003080000
+AE63:00000008F78810881088108E2108C60800080000004003F8004000A003180000
+AE64:00000008F78810881088108E2108C6080008000003F8000803F8000800080000
+AE65:00000008F78810881088108E2108C6080008000003F8020003F8020003F80000
+AE66:00000008F78810881088108E2108C6080008000000000FF8022002200FF80000
+AE67:00000008F78810881088108E2108C6080008000000800FF803E0041003E00000
+AE68:00000000001200127B9208920892089E11121112221244120812001200120000
+AE69:00000028F7A810A810A810B82128C6280028000007F800080008000800080000
+AE6A:00000028F7A810A810A810B82128C6280028000000003EF80208020802080000
+AE6B:00000028F7A810A810A810B82128C6280028000000003E100210022802C40000
+AE6C:00000028F7A810A810A810B82128C6280028002808000800080008000FF80000
+AE6D:00000028F7A810A810A810B82128C62800280000000020F8201020303ECC0000
+AE6E:00000028F7A810A810A810B82128C62800280000202021FC207020883E700000
+AE6F:00000028F7A810A810A810B82128C6280028000003F802000200020003F80000
+AE70:00000028F7A810A810A810B82128C6280028000007F8000807F8040007F80000
+AE71:00000028F7A810A810A810B82128C628002800003EF802083E0820083E080000
+AE72:00000028F7A810A810A810B82128C628002800003EF802883E8820883EF80000
+AE73:00000028F7A810A810A810B82128C628002800003E8802883EF820883EF80000
+AE74:00000028F7A810A810A810B82128C628002800001F0801081F0810141F620000
+AE75:00000028F7A810A810A810B82128C628002800003EF802803EF820803EF80000
+AE76:00000028F7A810A810A810B82128C628002800003EFC02483E4820483EFC0000
+AE77:00000028F7A810A810A810B82128C628002800003E1002FE3E3820443E380000
+AE78:00000028F7A810A810A810B82128C6280028000003F802080208020803F80000
+AE79:00000028F7A810A810A810B82128C628002800000208020803F8020803F80000
+AE7A:00000028F7A810A810A810B82128C62800280000110811081F0811141F620000
+AE7B:00000028F7A810A810A810B82128C62800280000000800080008003400C20000
+AE7C:00000028F7A810A810A810B82128C628002800000048004800A8011406620000
+AE7D:00000028F7A810A810A810B82128C62800280000000001F00208020801F00000
+AE7E:00000028F7A810A810A810B82128C6280028000003F80020002000D003080000
+AE7F:00000028F7A810A810A810B82128C62800280000004003F8004000A003180000
+AE80:00000028F7A810A810A810B82128C6280028000003F8000803F8000800080000
+AE81:00000028F7A810A810A810B82128C6280028000003F8020003F8020003F80000
+AE82:00000028F7A810A810A810B82128C6280028000000000FF8022002200FF80000
+AE83:00000028F7A810A810A810B82128C6280028000000800FF803E0041003E00000
+AE84:00000000001000107B900890089E08901110111E221044100810001000100000
+AE85:00000008F7881088108E1088210EC6080008000007F800080008000800080000
+AE86:00000008F7881088108E1088210EC6080008000000003EF80208020802080000
+AE87:00000008F7881088108E1088210EC6080008000000001F080108011401620000
+AE88:00000008F7881088108E1088210EC6080008000008000800080008000FF80000
+AE89:00000008F7881088108E1088210EC60800080000000010F8101010301ECC0000
+AE8A:00000008F7881088108E1088210EC608000800000808087F081C08220F9C0000
+AE8B:00000008F7881088108E1088210EC6080008000003F802000200020003F80000
+AE8C:00000008F7881088108E1088210EC6080008000007F8000807F8040007F80000
+AE8D:00000008F7881088108E1088210EC608000800003EF802083E0820083E080000
+AE8E:00000008F7881088108E1088210EC608000800003EF802883E8820883EF80000
+AE8F:00000008F7881088108E1088210EC608000800003E8802883EF820883EF80000
+AE90:00000008F7881088108E1088210EC608000800001F0801081F0810141F620000
+AE91:00000008F7881088108E1088210EC608000800003EF802803EF820803EF80000
+AE92:00000008F7881088108E1088210EC608000800003EFC02483E4820483EFC0000
+AE93:00000008F7881088108E1088210EC608000800001F08017F1F1C10221F1C0000
+AE94:00000008F7881088108E1088210EC6080008000003F802080208020803F80000
+AE95:00000008F7881088108E1088210EC608000800000208020803F8020803F80000
+AE96:00000008F7881088108E1088210EC60800080000110811081F0811141F620000
+AE97:00000008F7881088108E1088210EC60800080000001000100010006801840000
+AE98:00000008F7881088108E1088210EC608000800000048004800A8011406620000
+AE99:00000008F7881088108E1088210EC60800080000000003F00408040803F00000
+AE9A:00000008F7881088108E1088210EC6080008000003F80020002000D003080000
+AE9B:00000008F7881088108E1088210EC60800080000004003F8004000A003180000
+AE9C:00000008F7881088108E1088210EC6080008000003F8000803F8000800080000
+AE9D:00000008F7881088108E1088210EC6080008000003F8020003F8020003F80000
+AE9E:00000008F7881088108E1088210EC6080008000000000FF8022002200FF80000
+AE9F:00000008F7881088108E1088210EC6080008000000800FF803E0041003E00000
+AEA0:00000000001200127B920892089E08921112111E221244120812001200120000
+AEA1:00000028F7A810A810B810A82138C6280028000007F800080008000800080000
+AEA2:00000028F7A810A810B810A82138C6280028000000003EF80208020802080000
+AEA3:00000028F7A810A810B810A82138C6280028000000003E100210022802C40000
+AEA4:00000028F7A810A810B810A82138C6280028002808000800080008000FF80000
+AEA5:00000028F7A810A810B810A82138C62800280000000020F8201020303ECC0000
+AEA6:00000028F7A810A810B810A82138C62800280000202021FC207020883E700000
+AEA7:00000028F7A810A810B810A82138C6280028000003F802000200020003F80000
+AEA8:00000028F7A810A810B810A82138C6280028000007F8000807F8040007F80000
+AEA9:00000028F7A810A810B810A82138C628002800003EF802083E0820083E080000
+AEAA:00000028F7A810A810B810A82138C628002800003EF802883E8820883EF80000
+AEAB:00000028F7A810A810B810A82138C628002800003E8802883EF820883EF80000
+AEAC:00000028F7A810A810B810A82138C628002800001F0801081F0810141F620000
+AEAD:00000028F7A810A810B810A82138C628002800003EF802803EF820803EF80000
+AEAE:00000028F7A810A810B810A82138C628002800003EFC02483E4820483EFC0000
+AEAF:00000028F7A810A810B810A82138C628002800003E1002FE3E3820443E380000
+AEB0:00000028F7A810A810B810A82138C6280028000003F802080208020803F80000
+AEB1:00000028F7A810A810B810A82138C628002800000208020803F8020803F80000
+AEB2:00000028F7A810A810B810A82138C62800280000110811081F0811141F620000
+AEB3:00000028F7A810A810B810A82138C62800280000000800080008003400C20000
+AEB4:00000028F7A810A810B810A82138C628002800000048004800A8011406620000
+AEB5:00000028F7A810A810B810A82138C62800280000000001F00208020801F00000
+AEB6:00000028F7A810A810B810A82138C6280028000003F80020002000D003080000
+AEB7:00000028F7A810A810B810A82138C62800280000004003F8004000A003180000
+AEB8:00000028F7A810A810B810A82138C6280028000003F8000803F8000800080000
+AEB9:00000028F7A810A810B810A82138C6280028000003F8020003F8020003F80000
+AEBA:00000028F7A810A810B810A82138C6280028000000000FF8022002200FF80000
+AEBB:00000028F7A810A810B810A82138C6280028000000800FF803E0041003E00000
+AEBC:00000000000200027B8208820882089E11021102220244020802000200020000
+AEBD:00000008F7881088108810B82108C60800080000000007F80008000800080000
+AEBE:00000008F7881088108810B82108C6080008000000003EF80208020802080000
+AEBF:00000008F7881088108810B82108C6080008000000001F080108011401620000
+AEC0:00000008F7881088108810B82108C6080008000000001000100010001FF80000
+AEC1:00000008F7881088108810B82108C60800080000000020F8201020303ECC0000
+AEC2:00000008F7881088108810B82108C60800080000202021FC207020883E700000
+AEC3:00000008F7881088108810B82108C6080008000003F802000200020003F80000
+AEC4:00000008F7881088108810B82108C6080008000007F8000807F8040007F80000
+AEC5:00000008F7881088108810B82108C608000800003EF802083E0820083E080000
+AEC6:00000008F7881088108810B82108C608000800003EF802883E8820883EF80000
+AEC7:00000008F7881088108810B82108C608000800003E8802883EF820883EF80000
+AEC8:00000008F7881088108810B82108C608000800000F8800880F8808140FA20000
+AEC9:00000008F7881088108810B82108C608000800003EF802803EF820803EF80000
+AECA:00000008F7881088108810B82108C608000800003EFC02483E4820483EFC0000
+AECB:00000008F7881088108810B82108C608000800003E1002FE3E3820443E380000
+AECC:00000008F7881088108810B82108C6080008000003F802080208020803F80000
+AECD:00000008F7881088108810B82108C608000800000208020803F8020803F80000
+AECE:00000008F7881088108810B82108C60800080000210821083F0821143F620000
+AECF:00000008F7881088108810B82108C60800080000001000100010006801840000
+AED0:00000008F7881088108810B82108C608000800000048004800A8011406620000
+AED1:00000008F7881088108810B82108C60800080000000003F00408040803F00000
+AED2:00000008F7881088108810B82108C6080008000003F80020002000D003080000
+AED3:00000008F7881088108810B82108C60800080000004003F8004000A003180000
+AED4:00000008F7881088108810B82108C6080008000003F8000803F8000800080000
+AED5:00000008F7881088108810B82108C6080008000003F8020003F8020003F80000
+AED6:00000008F7881088108810B82108C6080008000000000FF8022002200FF80000
+AED7:00000008F7881088108810B82108C6080008000000800FF803E0041003E00000
+AED8:00000000000A000A7B8A088A088A08BA110A110A220A440A080A000A000A0000
+AED9:00000028F7A810A810A810E82128C6280028000007F800080008000800080000
+AEDA:00000028F7A810A810A810E82128C6280028000000003EF80208020802080000
+AEDB:00000028F7A810A810A810E82128C6280028000000003E100210022802C40000
+AEDC:00000028F7A810A810A810E82128C6280028000008000800080008000FF80000
+AEDD:00000028F7A810A810A810E82128C62800280000000020F8201020303ECC0000
+AEDE:00000028F7A810A810A810E82128C62800280000202021FC207020883E700000
+AEDF:00000028F7A810A810A810E82128C6280028000003F802000200020003F80000
+AEE0:00000028F7A810A810A810E82128C6280028000007F8000807F8040007F80000
+AEE1:00000028F7A810A810A810E82128C628002800003EF802083E0820083E080000
+AEE2:00000028F7A810A810A810E82128C628002800003EF802883E8820883EF80000
+AEE3:00000028F7A810A810A810E82128C628002800003E8802883EF820883EF80000
+AEE4:00000028F7A810A810A810E82128C628002800001F0801081F0810141F620000
+AEE5:00000028F7A810A810A810E82128C628002800003EF802803EF820803EF80000
+AEE6:00000028F7A810A810A810E82128C628002800003EFC02483E4820483EFC0000
+AEE7:00000028F7A810A810A810E82128C628002800003E1002FE3E3820443E380000
+AEE8:00000028F7A810A810A810E82128C6280028000003F802080208020803F80000
+AEE9:00000028F7A810A810A810E82128C628002800000208020803F8020803F80000
+AEEA:00000028F7A810A810A810E82128C62800280000110811081F0811141F620000
+AEEB:00000028F7A810A810A810E82128C62800280000000800080008003400C20000
+AEEC:00000028F7A810A810A810E82128C628002800000048004800A8011406620000
+AEED:00000028F7A810A810A810E82128C62800280000000001F00208020801F00000
+AEEE:00000028F7A810A810A810E82128C6280028000003F80020002000D003080000
+AEEF:00000028F7A810A810A810E82128C62800280000004003F8004000A003180000
+AEF0:00000028F7A810A810A810E82128C6280028000003F8000803F8000800080000
+AEF1:00000028F7A810A810A810E82128C6280028000003F8020003F8020003F80000
+AEF2:00000028F7A810A810A810E82128C6280028000000000FF8022002200FF80000
+AEF3:00000028F7A810A810A810E82128C6280028000000800FF803E0041003E00000
+AEF4:00000000000200027B820882089E08821102111E220244020802000200020000
+AEF5:00000008F788108810B810882138C60800080000000007F80008000800080000
+AEF6:00000008F788108810B810882138C6080008000000003EF80208020802080000
+AEF7:00000008F788108810B810882138C6080008000000001F080108011401620000
+AEF8:00000008F788108810B810882138C6080008000800001000100010001FF80000
+AEF9:00000008F788108810B810882138C60800080000000020F8201020303ECC0000
+AEFA:00000008F788108810B810882138C60800080000202021FC207020883E700000
+AEFB:00000008F788108810B810882138C6080008000003F802000200020003F80000
+AEFC:00000008F788108810B810882138C6080008000007F8000807F8040007F80000
+AEFD:00000008F788108810B810882138C608000800003EF802083E0820083E080000
+AEFE:00000008F788108810B810882138C608000800003EF802883E8820883EF80000
+AEFF:00000008F788108810B810882138C608000800003E8802883EF820883EF80000
+AF00:00000008F788108810B810882138C608000800000F8800880F8808140FA20000
+AF01:00000008F788108810B810882138C608000800003EF802803EF820803EF80000
+AF02:00000008F788108810B810882138C608000800003EFC02483E4820483EFC0000
+AF03:00000008F788108810B810882138C608000800003E1002FE3E3820443E380000
+AF04:00000008F788108810B810882138C6080008000003F802080208020803F80000
+AF05:00000008F788108810B810882138C608000800000208020803F8020803F80000
+AF06:00000008F788108810B810882138C60800080000210821083F0821143F620000
+AF07:00000008F788108810B810882138C60800080000001000100010006801840000
+AF08:00000008F788108810B810882138C608000800000048004800A8011406620000
+AF09:00000008F788108810B810882138C60800080000000003F00408040803F00000
+AF0A:00000008F788108810B810882138C6080008000003F80020002000D003080000
+AF0B:00000008F788108810B810882138C60800080000004003F8004000A003180000
+AF0C:00000008F788108810B810882138C6080008000003F8000803F8000800080000
+AF0D:00000008F788108810B810882138C6080008000003F8020003F8020003F80000
+AF0E:00000008F788108810B810882138C6080008000000000FF8022002200FF80000
+AF0F:00000008F788108810B810882138C6080008000000800FF803E0041003E00000
+AF10:00000000000A000A7B8A088A08BA088A110A113A220A440A080A000A000A0000
+AF11:00000028F7A810A810E810A821E8C6280028000007F800080008000800080000
+AF12:00000028F7A810A810E810A821E8C6280028000000003EF80208020802080000
+AF13:00000028F7A810A810E810A821E8C6280028000000003E100210022802C40000
+AF14:00000028F7A810A810E810A821E8C6280028002808000800080008000FF80000
+AF15:00000028F7A810A810E810A821E8C62800280000000020F8201020303ECC0000
+AF16:00000028F7A810A810E810A821E8C62800280000202021FC207020883E700000
+AF17:00000028F7A810A810E810A821E8C6280028000003F802000200020003F80000
+AF18:00000028F7A810A810E810A821E8C6280028000007F8000807F8040007F80000
+AF19:00000028F7A810A810E810A821E8C628002800003EF802083E0820083E080000
+AF1A:00000028F7A810A810E810A821E8C628002800003EF802883E8820883EF80000
+AF1B:00000028F7A810A810E810A821E8C628002800003E8802883EF820883EF80000
+AF1C:00000028F7A810A810E810A821E8C628002800001F0801081F0810141F620000
+AF1D:00000028F7A810A810E810A821E8C628002800003EF802803EF820803EF80000
+AF1E:00000028F7A810A810E810A821E8C628002800003EFC02483E4820483EFC0000
+AF1F:00000028F7A810A810E810A821E8C628002800003E1002FE3E3820443E380000
+AF20:00000028F7A810A810E810A821E8C6280028000003F802080208020803F80000
+AF21:00000028F7A810A810E810A821E8C628002800000208020803F8020803F80000
+AF22:00000028F7A810A810E810A821E8C62800280000110811081F0811141F620000
+AF23:00000028F7A810A810E810A821E8C62800280000000800080008003400C20000
+AF24:00000028F7A810A810E810A821E8C628002800000048004800A8011406620000
+AF25:00000028F7A810A810E810A821E8C62800280000000001F00208020801F00000
+AF26:00000028F7A810A810E810A821E8C6280028000003F80020002000D003080000
+AF27:00000028F7A810A810E810A821E8C62800280000004003F8004000A003180000
+AF28:00000028F7A810A810E810A821E8C6280028000003F8000803F8000800080000
+AF29:00000028F7A810A810E810A821E8C6280028000003F8020003F8020003F80000
+AF2A:00000028F7A810A810E810A821E8C6280028000000000FF8022002200FF80000
+AF2B:00000028F7A810A810E810A821E8C6280028000000800FF803E0041003E00000
+AF2C:00000000000000003EF8020802080208020800000100010001007FFC00000000
+AF2D:000000003EF8020802080208010001007FFC00001FF000100010001000100000
+AF2E:000000003EF8020802080208010001007FFC000000003EF80208020802080000
+AF2F:000000003EF8020802080208010001007FFC000000001E100210022802C40000
+AF30:000000003EF8020802080208010001007FFC000000001000100010001FF00000
+AF31:000000003EF8020802080208010001007FFC0000000020F8201020303ECC0000
+AF32:000000003EF8020802080208010001007FFC0000202021FC207020883E700000
+AF33:000000003EF8020802080208010001007FFC00001FF01000100010001FF00000
+AF34:000000003EF8020802080208010001007FFC00001FF000101FF010001FF00000
+AF35:000000003EF8020802080208010001007FFC00003EF802083E0820083E080000
+AF36:000000003EF8020802080208010001007FFC00003EF802883E8820883EF80000
+AF37:000000003EF8020802080208010001007FFC00003E8802883EF820883EF80000
+AF38:000000003EF8020802080208010001007FFC00003E1002103E1020283EC40000
+AF39:000000003EF8020802080208010001007FFC00003EF802803EF820803EF80000
+AF3A:000000003EF8020802080208010001007FFC00003EFC02483E4820483EFC0000
+AF3B:000000003EF8020802080208010001007FFC00003E2003FC3E7020883E700000
+AF3C:000000003EF8020802080208010001007FFC00001FF01010101010101FF00000
+AF3D:000000003EF8020802080208010001007FFC0000101010101FF010101FF00000
+AF3E:000000003EF8020802080208010001007FFC0000222022203E2022503E880000
+AF3F:000000003EF8020802080208010001007FFC000000000100010002800C400000
+AF40:000000003EF8020802080208010001007FFC00000000024002400DA033100000
+AF41:000000003EF8020802080208010001007FFC0000000007C00820082007C00000
+AF42:000000003EF8020802080208010001007FFC0000000007E00080014006200000
+AF43:000000003EF8020802080208010001007FFC0000008007E00080014006200000
+AF44:000000003EF8020802080208010001007FFC00001FF000101FF0001000100000
+AF45:000000003EF8020802080208010001007FFC00001FF010001FF010001FF00000
+AF46:000000003EF8020802080208010001007FFC000000001FF0044004401FF00000
+AF47:000000003EF8020802080208010001007FFC000001001FF007C0082007C00000
+AF48:00000010001000107BD008500850085E08500010041004107FD0001000100000
+AF49:00000008F7881088108E1088148804087FE8000007F800080008000800080000
+AF4A:00000008F7881088108E1088148804087FE8000000003EF80208020802080000
+AF4B:00000008F7881088108E1088148804087FE8000000001F080108011401620000
+AF4C:00000008F7881088108E1088148804087FE8000008000800080008000FF80000
+AF4D:00000008F7881088108E1088148804087FE80000000010F8101010301ECC0000
+AF4E:00000008F7881088108E1088148804087FE800000808087F081C08220F9C0000
+AF4F:00000008F7881088108E1088148804087FE8000003F802000200020003F80000
+AF50:00000008F7881088108E1088148804087FE8000007F8000807F8040007F80000
+AF51:00000008F7881088108E1088148804087FE800003EF802083E0820083E080000
+AF52:00000008F7881088108E1088148804087FE800003EF802883E8820883EF80000
+AF53:00000008F7881088108E1088148804087FE800003E8802883EF820883EF80000
+AF54:00000008F7881088108E1088148804087FE800001F0801081F0810141F620000
+AF55:00000008F7881088108E1088148804087FE800003EF802803EF820803EF80000
+AF56:00000008F7881088108E1088148804087FE800003EFC02483E4820483EFC0000
+AF57:00000008F7881088108E1088148804087FE800001F08017F1F1C10221F1C0000
+AF58:00000008F7881088108E1088148804087FE8000003F802080208020803F80000
+AF59:00000008F7881088108E1088148804087FE800000208020803F8020803F80000
+AF5A:00000008F7881088108E1088148804087FE80000110811081F0811141F620000
+AF5B:00000008F7881088108E1088148804087FE80000001000100010006801840000
+AF5C:00000008F7881088108E1088148804087FE800000048004800A8011406620000
+AF5D:00000008F7881088108E1088148804087FE80000000003F00408040803F00000
+AF5E:00000008F7881088108E1088148804087FE8000003F80020002000D003080000
+AF5F:00000008F7881088108E1088148804087FE80000004003F8004000A003180000
+AF60:00000008F7881088108E1088148804087FE8000003F8000803F8000800080000
+AF61:00000008F7881088108E1088148804087FE8000003F8020003F8020003F80000
+AF62:00000008F7881088108E1088148804087FE8000000000FF8022002200FF80000
+AF63:00000008F7881088108E1088148804087FE8000000800FF803E0041003E00000
+AF64:00000012001200127BD208520852085E08520012041204127FD2001200120000
+AF65:00000028F7A810A810B810A814A804287FA8000007F800080008000800080000
+AF66:00000028F7A810A810B810A814A804287FA8000000003EF80208020802080000
+AF67:00000028F7A810A810B810A814A804287FA8000000001F080108011401620000
+AF68:00000028F7A810A810B810A814A804287FA8000008000800080008000FF80000
+AF69:00000028F7A810A810B810A814A804287FA80000000010F8101010301ECC0000
+AF6A:00000028F7A810A810B810A814A804287FA800000808087F081C08220F9C0000
+AF6B:00000028F7A810A810B810A814A804287FA8000003F802000200020003F80000
+AF6C:00000028F7A810A810B810A814A804287FA8000007F8000807F8040007F80000
+AF6D:00000028F7A810A810B810A814A804287FA800003EF802083E0820083E080000
+AF6E:00000028F7A810A810B810A814A804287FA800003EF802883E8820883EF80000
+AF6F:00000028F7A810A810B810A814A804287FA800003E8802883EF820883EF80000
+AF70:00000028F7A810A810B810A814A804287FA800001F0801081F0810141F620000
+AF71:00000028F7A810A810B810A814A804287FA800003EF802803EF820803EF80000
+AF72:00000028F7A810A810B810A814A804287FA800003EFC02483E4820483EFC0000
+AF73:00000028F7A810A810B810A814A804287FA800001F08017F1F1C10221F1C0000
+AF74:00000028F7A810A810B810A814A804287FA8000003F802080208020803F80000
+AF75:00000028F7A810A810B810A814A804287FA800000208020803F8020803F80000
+AF76:00000028F7A810A810B810A814A804287FA80000110811081F0811141F620000
+AF77:00000028F7A810A810B810A814A804287FA80000001000100010006801840000
+AF78:00000028F7A810A810B810A814A804287FA800000048004800A8011406620000
+AF79:00000028F7A810A810B810A814A804287FA80000000003F00408040803F00000
+AF7A:00000028F7A810A810B810A814A804287FA8000003F80020002000D003080000
+AF7B:00000028F7A810A810B810A814A804287FA80000004003F8004000A003180000
+AF7C:00000028F7A810A810B810A814A804287FA8000003F8000803F8000800080000
+AF7D:00000028F7A810A810B810A814A804287FA8000003F8020003F8020003F80000
+AF7E:00000028F7A810A810B810A814A804287FA8000000000FF8022002200FF80000
+AF7F:00000028F7A810A810B810A814A804287FA8000000800FF803E0041003E00000
+AF80:00000008000800087BC808480848084808480008040804087FE8000800080000
+AF81:00000008F788108810881088148804087FE8000007F800080008000800080000
+AF82:00000008F788108810881088148804087FE8000000003EF80208020802080000
+AF83:00000008F788108810881088148804087FE8000000001F080108011401620000
+AF84:00000008F788108810881088148804087FE8000008000800080008000FF80000
+AF85:00000008F788108810881088148804087FE80000000010F8101010301ECC0000
+AF86:00000008F788108810881088148804087FE800000808087F081C08220F9C0000
+AF87:00000008F788108810881088148804087FE8000003F802000200020003F80000
+AF88:00000008F788108810881088148804087FE8000007F8000807F8040007F80000
+AF89:00000008F788108810881088148804087FE800003EF802083E0820083E080000
+AF8A:00000008F788108810881088148804087FE800003EF802883E8820883EF80000
+AF8B:00000008F788108810881088148804087FE800003E8802883EF820883EF80000
+AF8C:00000008F788108810881088148804087FE800001F0801081F0810141F620000
+AF8D:00000008F788108810881088148804087FE800003EF802803EF820803EF80000
+AF8E:00000008F788108810881088148804087FE800003EFC02483E4820483EFC0000
+AF8F:00000008F788108810881088148804087FE800001F08017F1F1C10221F1C0000
+AF90:00000008F788108810881088148804087FE8000003F802080208020803F80000
+AF91:00000008F788108810881088148804087FE800000208020803F8020803F80000
+AF92:00000008F788108810881088148804087FE80000110811081F0811141F620000
+AF93:00000008F788108810881088148804087FE80000001000100010006801840000
+AF94:00000008F788108810881088148804087FE800000048004800A8011406620000
+AF95:00000008F788108810881088148804087FE80000000003F00408040803F00000
+AF96:00000008F788108810881088148804087FE8000003F80020002000D003080000
+AF97:00000008F788108810881088148804087FE80000004003F8004000A003180000
+AF98:00000008F788108810881088148804087FE8000003F8000803F8000800080000
+AF99:00000008F788108810881088148804087FE8000003F8020003F8020003F80000
+AF9A:00000008F788108810881088148804087FE8000000000FF8022002200FF80000
+AF9B:00000008F788108810881088148804087FE8000000800FF803E0041003E00000
+AF9C:00000000000000003EF8020802080208020804400440044004407FFC00000000
+AF9D:000000003EF8020802080208044004407FFC00001FF000100010001000100000
+AF9E:000000003EF8020802080208044004407FFC000000003EF80208020802080000
+AF9F:000000003EF8020802080208044004407FFC000000001E100210022802C40000
+AFA0:000000003EF8020802080208044004407FFC000000001000100010001FF00000
+AFA1:000000003EF8020802080208044004407FFC0000000020F8201020303ECC0000
+AFA2:000000003EF8020802080208044004407FFC0000202021FC207020883E700000
+AFA3:000000003EF8020802080208044004407FFC00001FF01000100010001FF00000
+AFA4:000000003EF8020802080208044004407FFC00001FF000101FF010001FF00000
+AFA5:000000003EF8020802080208044004407FFC00003EF802083E0820083E080000
+AFA6:000000003EF8020802080208044004407FFC00003EF802883E8820883EF80000
+AFA7:000000003EF8020802080208044004407FFC00003E8802883EF820883EF80000
+AFA8:000000003EF8020802080208044004407FFC00003E1002103E1020283EC40000
+AFA9:000000003EF8020802080208044004407FFC00003EF802803EF820803EF80000
+AFAA:000000003EF8020802080208044004407FFC00003EFC02483E4820483EFC0000
+AFAB:000000003EF8020802080208044004407FFC00003E2003FC3E7020883E700000
+AFAC:000000003EF8020802080208044004407FFC00001FF01010101010101FF00000
+AFAD:000000003EF8020802080208044004407FFC0000101010101FF010101FF00000
+AFAE:000000003EF8020802080208044004407FFC0000222022203E2022503E880000
+AFAF:000000003EF8020802080208044004407FFC000000000100010002800C400000
+AFB0:000000003EF8020802080208044004407FFC00000000024002400DA033100000
+AFB1:000000003EF8020802080208044004407FFC0000000007C00820082007C00000
+AFB2:000000003EF8020802080208044004407FFC0000000007E00080014006200000
+AFB3:000000003EF8020802080208044004407FFC0000008007E00080014006200000
+AFB4:000000003EF8020802080208044004407FFC00001FF000101FF0001000100000
+AFB5:000000003EF8020802080208044004407FFC00001FF010001FF010001FF00000
+AFB6:000000003EF8020802080208044004407FFC000000001FF0044004401FF00000
+AFB7:000000003EF8020802080208044004407FFC000001001FF007C0082007C00000
+AFB8:00000000000000007DF0041004100410041000003FF801000100010001000000
+AFB9:000000003EF802080208020800007FFC010001001FF000100010001000100000
+AFBA:000000003EF802080208020800007FFC0100010000003EF80208020802080000
+AFBB:000000003EF802080208020800007FFC0100010000001E100210022802C40000
+AFBC:000000003EF8020802080208000000007FFC010001001100100010001FF00000
+AFBD:000000003EF802080208020800007FFC01000100000020F8201020303ECC0000
+AFBE:000000003EF802080208020800007FFC01000100202021FC207020883E700000
+AFBF:000000003EF802080208020800007FFC010001001FF01000100010001FF00000
+AFC0:000000003EF802080208020800007FFC010001001FF000101FF010001FF00000
+AFC1:000000003EF802080208020800007FFC010001003EF802083E0820083E080000
+AFC2:000000003EF802080208020800007FFC010001003EF802883E8820883EF80000
+AFC3:000000003EF802080208020800007FFC010001003E8802883EF820883EF80000
+AFC4:000000003EF802080208020800007FFC010001003E1002103E1020283EC40000
+AFC5:000000003EF802080208020800007FFC010001003EF802803EF820803EF80000
+AFC6:000000003EF802080208020800007FFC010001003EFC02483E4820483EFC0000
+AFC7:000000003EF802080208020800007FFC010001003E2003FC3E7020883E700000
+AFC8:000000003EF802080208020800007FFC010001001FF01010101010101FF00000
+AFC9:000000003EF802080208020800007FFC01000100101010101FF010101FF00000
+AFCA:000000003EF802080208020800007FFC01000100222022203E2022503E880000
+AFCB:000000003EF802080208020800007FFC0100010000000100010002800C400000
+AFCC:000000003EF802080208020800007FFC010001000000024002400DA033100000
+AFCD:000000003EF802080208020800007FFC01000100000007C00820082007C00000
+AFCE:000000003EF802080208020800007FFC01000100000007E00080014006200000
+AFCF:000000003EF802080208020800007FFC01000100008007E00080014006200000
+AFD0:000000003EF802080208020800007FFC010001001FF000101FF0001000100000
+AFD1:000000003EF802080208020800007FFC010001001FF010001FF010001FF00000
+AFD2:000000003EF802080208020800007FFC0100010000001FF0044004401FF00000
+AFD3:000000003EF802080208020800007FFC0100010001001FF007C0082007C00000
+AFD4:00000008000800087BC8084808480848000800087FE8040804F8040804080000
+AFD5:00080008F7881088108810887FE8027802080000000007F80008000800080000
+AFD6:00080008F7881088108810887FE802780208000000003EF80208020802080000
+AFD7:00080008F7881088108810887FE802780208000000001F080108011401620000
+AFD8:00080008F78810881088108800087FE80278020802081000100010001FF80000
+AFD9:00080008F7881088108810887FE8027802080000000020F8201020303ECC0000
+AFDA:00080008F7881088108810887FE8027802080000202021FC207020883E700000
+AFDB:00080008F7881088108810887FE802780208000003F802000200020003F80000
+AFDC:00080008F7881088108810887FE802780208000007F8000807F8040007F80000
+AFDD:00080008F7881088108810887FE80278020800003EF802083E0820083E080000
+AFDE:00080008F7881088108810887FE80278020800003EF802883E8820883EF80000
+AFDF:00080008F7881088108810887FE80278020800003E8802883EF820883EF80000
+AFE0:00080008F7881088108810887FE80278020800000F8800880F8808140FA20000
+AFE1:00080008F7881088108810887FE80278020800003EF802803EF820803EF80000
+AFE2:00080008F7881088108810887FE80278020800003EFC02483E4820483EFC0000
+AFE3:00080008F7881088108810887FE80278020800003E1002FE3E3820443E380000
+AFE4:00080008F7881088108810887FE802780208000003F802080208020803F80000
+AFE5:00080008F7881088108810887FE80278020800000208020803F8020803F80000
+AFE6:00080008F7881088108810887FE8027802080000210821083F0821143F620000
+AFE7:00080008F7881088108810887FE8027802080000001000100010006801840000
+AFE8:00080008F7881088108810887FE80278020800000048004800A8011406620000
+AFE9:00080008F7881088108810887FE8027802080000000003F00408040803F00000
+AFEA:00080008F7881088108810887FE802780208000003F80020002000D003080000
+AFEB:00080008F7881088108810887FE8027802080000004003F8004000A003180000
+AFEC:00080008F7881088108810887FE802780208000003F8000803F8000800080000
+AFED:00080008F7881088108810887FE802780208000003F8020003F8020003F80000
+AFEE:00080008F7881088108810887FE802780208000000000FF8022002200FF80000
+AFEF:00080008F7881088108810887FE802780208000000800FF803E0041003E00000
+AFF0:0000000A000A000A7BCA084A084A084A000A000A7FEA040A047A040A040A0000
+AFF1:00280028F7A810A810A810A87FA805E804280000000007F80008000800080000
+AFF2:00280028F7A810A810A810A87FA805E80428000000003EF80208020802080000
+AFF3:00280028F7A810A810A810A87FA805E80428000000001F080108011401620000
+AFF4:00280028F7A810A810A810A800287FA8042805E804281428100010001FF80000
+AFF5:00280028F7A810A810A810A87FA805E804280000000020F8201020303ECC0000
+AFF6:00280028F7A810A810A810A87FA805E804280000202021FC207020883E700000
+AFF7:00280028F7A810A810A810A87FA805E80428000003F802000200020003F80000
+AFF8:00280028F7A810A810A810A87FA805E80428000007F8000807F8040007F80000
+AFF9:00280028F7A810A810A810A87FA805E8042800003EF802083E0820083E080000
+AFFA:00280028F7A810A810A810A87FA805E8042800003EF802883E8820883EF80000
+AFFB:00280028F7A810A810A810A87FA805E8042800003E8802883EF820883EF80000
+AFFC:00280028F7A810A810A810A87FA805E8042800000F8800880F8808140FA20000
+AFFD:00280028F7A810A810A810A87FA805E8042800003EF802803EF820803EF80000
+AFFE:00280028F7A810A810A810A87FA805E8042800003EFC02483E4820483EFC0000
+AFFF:00280028F7A810A810A810A87FA805E8042800003E1002FE3E3820443E380000
+B000:00280028F7A810A810A810A87FA805E80428000003F802080208020803F80000
+B001:00280028F7A810A810A810A87FA805E8042800000208020803F8020803F80000
+B002:00280028F7A810A810A810A87FA805E804280000210821083F0821143F620000
+B003:00280028F7A810A810A810A87FA805E804280000001000100010006801840000
+B004:00280028F7A810A810A810A87FA805E8042800000048004800A8011406620000
+B005:00280028F7A810A810A810A87FA805E804280000000003F00408040803F00000
+B006:00280028F7A810A810A810A87FA805E80428000003F80020002000D003080000
+B007:00280028F7A810A810A810A87FA805E804280000004003F8004000A003180000
+B008:00280028F7A810A810A810A87FA805E80428000003F8000803F8000800080000
+B009:00280028F7A810A810A810A87FA805E80428000003F8020003F8020003F80000
+B00A:00280028F7A810A810A810A87FA805E80428000000000FF8022002200FF80000
+B00B:00280028F7A810A810A810A87FA805E80428000000800FF803E0041003E00000
+B00C:00000008000800087BC8084808480848000800087FE804080408040804080000
+B00D:00080008F7881088108810887FE8020802000000000007F80008000800080000
+B00E:00080008F7881088108810887FE802080200000000003EF80208020802080000
+B00F:00080008F7881088108810887FE802080200000000001F080108011401620000
+B010:00080008F78810881088108800087FE80208020802081008100010001FF80000
+B011:00080008F7881088108810887FE8020802000000000020F8201020303ECC0000
+B012:00080008F7881088108810887FE8020802000000202021FC207020883E700000
+B013:00080008F7881088108810887FE802080200000003F802000200020003F80000
+B014:00080008F7881088108810887FE802080200000007F8000807F8040007F80000
+B015:00080008F7881088108810887FE80208020000003EF802083E0820083E080000
+B016:00080008F7881088108810887FE80208020000003EF802883E8820883EF80000
+B017:00080008F7881088108810887FE80208020000003E8802883EF820883EF80000
+B018:00080008F7881088108810887FE80208020000000F8800880F8808140FA20000
+B019:00080008F7881088108810887FE80208020000003EF802803EF820803EF80000
+B01A:00080008F7881088108810887FE80208020000003EFC02483E4820483EFC0000
+B01B:00080008F7881088108810887FE80208020000003E1002FE3E3820443E380000
+B01C:00080008F7881088108810887FE802080200000003F802080208020803F80000
+B01D:00080008F7881088108810887FE80208020000000208020803F8020803F80000
+B01E:00080008F7881088108810887FE8020802000000210821083F0821143F620000
+B01F:00080008F7881088108810887FE8020802000000001000100010006801840000
+B020:00080008F7881088108810887FE80208020000000048004800A8011406620000
+B021:00080008F7881088108810887FE8020802000000000003F00408040803F00000
+B022:00080008F7881088108810887FE802080200000003F80020002000D003080000
+B023:00080008F7881088108810887FE8020802000000004003F8004000A003180000
+B024:00080008F7881088108810887FE802080200000003F8000803F8000800080000
+B025:00080008F7881088108810887FE802080200000003F8020003F8020003F80000
+B026:00080008F7881088108810887FE802080200000000000FF8022002200FF80000
+B027:00080008F7881088108810887FE802080200000000800FF803E0041003E00000
+B028:00000000000000007DF0041004100410041000007FFC04400440044004400000
+B029:000000003EF802080208020800007FFC044004401FF000100010001000100000
+B02A:000000003EF802080208020800007FFC0440044000003EF80208020802080000
+B02B:000000003EF802080208020800007FFC0440044000001E100210022802C40000
+B02C:000000003EF8020802080208000000007FFC044004401440100010001FF00000
+B02D:000000003EF802080208020800007FFC04400440000020F8201020303ECC0000
+B02E:000000003EF802080208020800007FFC04400440202021FC207020883E700000
+B02F:000000003EF802080208020800007FFC044004401FF01000100010001FF00000
+B030:000000003EF802080208020800007FFC044004401FF000101FF010001FF00000
+B031:000000003EF802080208020800007FFC044004403EF802083E0820083E080000
+B032:000000003EF802080208020800007FFC044004403EF802883E8820883EF80000
+B033:000000003EF802080208020800007FFC044004403E8802883EF820883EF80000
+B034:000000003EF802080208020800007FFC044004403E1002103E1020283EC40000
+B035:000000003EF802080208020800007FFC044004403EF802803EF820803EF80000
+B036:000000003EF802080208020800007FFC044004403EFC02483E4820483EFC0000
+B037:000000003EF802080208020800007FFC044004403E2003FC3E7020883E700000
+B038:000000003EF802080208020800007FFC044004401FF01010101010101FF00000
+B039:000000003EF802080208020800007FFC04400440101010101FF010101FF00000
+B03A:000000003EF802080208020800007FFC04400440222022203E2022503E880000
+B03B:000000003EF802080208020800007FFC0440044000000100010002800C400000
+B03C:000000003EF802080208020800007FFC044004400000024002400DA033100000
+B03D:000000003EF802080208020800007FFC04400440000007C00820082007C00000
+B03E:000000003EF802080208020800007FFC04400440000007E00080014006200000
+B03F:000000003EF802080208020800007FFC04400440008007E00080014006200000
+B040:000000003EF802080208020800007FFC044004401FF000101FF0001000100000
+B041:000000003EF802080208020800007FFC044004401FF010001FF010001FF00000
+B042:000000003EF802080208020800007FFC0440044000001FF0044004401FF00000
+B043:000000003EF802080208020800007FFC0440044001001FF007C0082007C00000
+B044:00000000000000003EF80208020802080208000000007FFC0000000000000000
+B045:000000003EF8020802080208000000007FFC00001FF000100010001000100000
+B046:000000003EF8020802080208000000007FFC000000003EF80208020802080000
+B047:000000003EF8020802080208000000007FFC000000001E100210022802C40000
+B048:000000003EF8020802080208000000007FFC000000001000100010001FF00000
+B049:000000003EF8020802080208000000007FFC0000000020F8201020303ECC0000
+B04A:000000003EF8020802080208000000007FFC0000202021FC207020883E700000
+B04B:000000003EF8020802080208000000007FFC00001FF01000100010001FF00000
+B04C:000000003EF8020802080208000000007FFC00001FF000101FF010001FF00000
+B04D:000000003EF8020802080208000000007FFC00003EF802083E0820083E080000
+B04E:000000003EF8020802080208000000007FFC00003EF802883E8820883EF80000
+B04F:000000003EF8020802080208000000007FFC00003E8802883EF820883EF80000
+B050:000000003EF8020802080208000000007FFC00003E1002103E1020283EC40000
+B051:000000003EF8020802080208000000007FFC00003EF802803EF820803EF80000
+B052:000000003EF8020802080208000000007FFC00003EFC02483E4820483EFC0000
+B053:000000003EF8020802080208000000007FFC00003E2003FC3E7020883E700000
+B054:000000003EF8020802080208000000007FFC00001FF01010101010101FF00000
+B055:000000003EF8020802080208000000007FFC0000101010101FF010101FF00000
+B056:000000003EF8020802080208000000007FFC0000222022203E2022503E880000
+B057:000000003EF8020802080208000000007FFC000000000100010002800C400000
+B058:000000003EF8020802080208000000007FFC00000000024002400DA033100000
+B059:000000003EF8020802080208000000007FFC0000000007C00820082007C00000
+B05A:000000003EF8020802080208000000007FFC0000000007E00080014006200000
+B05B:000000003EF8020802080208000000007FFC0000008007E00080014006200000
+B05C:000000003EF8020802080208000000007FFC00001FF000101FF0001000100000
+B05D:000000003EF8020802080208000000007FFC00001FF010001FF010001FF00000
+B05E:000000003EF8020802080208000000007FFC000000001FF0044004401FF00000
+B05F:000000003EF8020802080208000000007FFC000001001FF007C0082007C00000
+B060:00000008000800087BC80848084808480848000800087FE80008000800080000
+B061:00000008F788108810881088108800087FE8000007F800080008000800080000
+B062:00000008F788108810881088108800087FE8000000003EF80208020802080000
+B063:00000008F788108810881088108800087FE8000000001F080108011401620000
+B064:00000008F788108810881088108800087FE8000008000800080008000FF80000
+B065:00000008F788108810881088108800087FE80000000010F8101010301ECC0000
+B066:00000008F788108810881088108800087FE800000808087F081C08220F9C0000
+B067:00000008F788108810881088108800087FE8000003F802000200020003F80000
+B068:00000008F788108810881088108800087FE8000007F8000807F8040007F80000
+B069:00000008F788108810881088108800087FE800003EF802083E0820083E080000
+B06A:00000008F788108810881088108800087FE800003EF802883E8820883EF80000
+B06B:00000008F788108810881088108800087FE800003E8802883EF820883EF80000
+B06C:00000008F788108810881088108800087FE800001F0801081F0810141F620000
+B06D:00000008F788108810881088108800087FE800003EF802803EF820803EF80000
+B06E:00000008F788108810881088108800087FE800003EFC02483E4820483EFC0000
+B06F:00000008F788108810881088108800087FE800001F08017F1F1C10221F1C0000
+B070:00000008F788108810881088108800087FE8000003F802080208020803F80000
+B071:00000008F788108810881088108800087FE800000208020803F8020803F80000
+B072:00000008F788108810881088108800087FE80000110811081F0811141F620000
+B073:00000008F788108810881088108800087FE80000001000100010006801840000
+B074:00000008F788108810881088108800087FE800000048004800A8011406620000
+B075:00000008F788108810881088108800087FE80000000003F00408040803F00000
+B076:00000008F788108810881088108800087FE8000003F80020002000D003080000
+B077:00000008F788108810881088108800087FE80000004003F8004000A003180000
+B078:00000008F788108810881088108800087FE8000003F8000803F8000800080000
+B079:00000008F788108810881088108800087FE8000003F8020003F8020003F80000
+B07A:00000008F788108810881088108800087FE8000000000FF8022002200FF80000
+B07B:00000008F788108810881088108800087FE8000000800FF803E0041003E00000
+B07C:00000000000800087B8808880888088811081108220844080808000800080000
+B07D:00000008F7881088108810882108C60800080000000007F80008000800080000
+B07E:00000008F7881088108810882108C6080008000000003EF80208020802080000
+B07F:00000008F7881088108810882108C6080008000000001F080108011401620000
+B080:00000008F7881088108810882108C6080008000800001000100010001FF80000
+B081:00000008F7881088108810882108C60800080000000020F8201020303ECC0000
+B082:00000008F7881088108810882108C60800080000202021FC207020883E700000
+B083:00000008F7881088108810882108C6080008000003F802000200020003F80000
+B084:00000008F7881088108810882108C6080008000007F8000807F8040007F80000
+B085:00000008F7881088108810882108C608000800003EF802083E0820083E080000
+B086:00000008F7881088108810882108C608000800003EF802883E8820883EF80000
+B087:00000008F7881088108810882108C608000800003E8802883EF820883EF80000
+B088:00000008F7881088108810882108C608000800000F8800880F8808140FA20000
+B089:00000008F7881088108810882108C608000800003EF802803EF820803EF80000
+B08A:00000008F7881088108810882108C608000800003EFC02483E4820483EFC0000
+B08B:00000008F7881088108810882108C608000800003E1002FE3E3820443E380000
+B08C:00000008F7881088108810882108C6080008000003F802080208020803F80000
+B08D:00000008F7881088108810882108C608000800000208020803F8020803F80000
+B08E:00000008F7881088108810882108C60800080000210821083F0821143F620000
+B08F:00000008F7881088108810882108C60800080000001000100010006801840000
+B090:00000008F7881088108810882108C608000800000048004800A8011406620000
+B091:00000008F7881088108810882108C60800080000000003F00408040803F00000
+B092:00000008F7881088108810882108C6080008000003F80020002000D003080000
+B093:00000008F7881088108810882108C60800080000004003F8004000A003180000
+B094:00000008F7881088108810882108C6080008000003F8000803F8000800080000
+B095:00000008F7881088108810882108C6080008000003F8020003F8020003F80000
+B096:00000008F7881088108810882108C6080008000000000FF8022002200FF80000
+B097:00000008F7881088108810882108C6080008000000800FF803E0041003E00000
+B098:0000000000100010001040104010401E4010401040107F900010001000100000
+B099:00000008000800084008400E400840087E08000007F800080008000800080000
+B09A:00000008000800084008400E400840087E08000000003EF80208020802080000
+B09B:00000008000800084008400E400840087E08000000001F080108011401620000
+B09C:00000008000800084008400E400840087E08000808000800080008000FF80000
+B09D:00000008000800084008400E400840087E080000000010F8101010301ECC0000
+B09E:00000008000800084008400E400840087E0800000808087F081C08220F9C0000
+B09F:00000008000800084008400E400840087E08000003F802000200020003F80000
+B0A0:00000008000800084008400E400840087E08000007F8000807F8040007F80000
+B0A1:00000008000800084008400E400840087E0800003EF802083E0820083E080000
+B0A2:00000008000800084008400E400840087E0800003EF802883E8820883EF80000
+B0A3:00000008000800084008400E400840087E0800003E8802883EF820883EF80000
+B0A4:00000008000800084008400E400840087E0800001F0801081F0810141F620000
+B0A5:00000008000800084008400E400840087E0800003EF802803EF820803EF80000
+B0A6:00000008000800084008400E400840087E0800003EFC02483E4820483EFC0000
+B0A7:00000008000800084008400E400840087E0800001F08017F1F1C10221F1C0000
+B0A8:00000008000800084008400E400840087E08000003F802080208020803F80000
+B0A9:00000008000800084008400E400840087E0800000208020803F8020803F80000
+B0AA:00000008000800084008400E400840087E080000110811081F0811141F620000
+B0AB:00000008000800084008400E400840087E080000001000100010006801840000
+B0AC:00000008000800084008400E400840087E0800000048004800A8011406620000
+B0AD:00000008000800084008400E400840087E080000000003F00408040803F00000
+B0AE:00000008000800084008400E400840087E08000003F80020002000D003080000
+B0AF:00000008000800084008400E400840087E080000004003F8004000A003180000
+B0B0:00000008000800084008400E400840087E08000003F8000803F8000800080000
+B0B1:00000008000800084008400E400840087E08000003F8020003F8020003F80000
+B0B2:00000008000800084008400E400840087E08000000000FF8022002200FF80000
+B0B3:00000008000800084008400E400840087E08000000800FF803E0041003E00000
+B0B4:0000000000120012001240124012401E4012401240127F920012001200120000
+B0B5:000000280028002840284038402840287E28000007F800080008000800080000
+B0B6:000000280028002840284038402840287E28000000003EF80208020802080000
+B0B7:000000280028002840284038402840287E28000000003E100210022802C40000
+B0B8:000000280028002840284038402840287E28002808000800080008000FF80000
+B0B9:000000280028002840284038402840287E280000000020F8201020303ECC0000
+B0BA:000000280028002840284038402840287E280000202021FC207020883E700000
+B0BB:000000280028002840284038402840287E28000003F802000200020003F80000
+B0BC:000000280028002840284038402840287E28000007F8000807F8040007F80000
+B0BD:000000280028002840284038402840287E2800003EF802083E0820083E080000
+B0BE:000000280028002840284038402840287E2800003EF802883E8820883EF80000
+B0BF:000000280028002840284038402840287E2800003E8802883EF820883EF80000
+B0C0:000000280028002840284038402840287E2800001F0801081F0810141F620000
+B0C1:000000280028002840284038402840287E2800003EF802803EF820803EF80000
+B0C2:000000280028002840284038402840287E2800003EFC02483E4820483EFC0000
+B0C3:000000280028002840284038402840287E2800003E1002FE3E3820443E380000
+B0C4:000000280028002840284038402840287E28000003F802080208020803F80000
+B0C5:000000280028002840284038402840287E2800000208020803F8020803F80000
+B0C6:000000280028002840284038402840287E280000110811081F0811141F620000
+B0C7:000000280028002840284038402840287E280000000800080008003400C20000
+B0C8:000000280028002840284038402840287E2800000048004800A8011406620000
+B0C9:000000280028002840284038402840287E280000000001F00208020801F00000
+B0CA:000000280028002840284038402840287E28000003F80020002000D003080000
+B0CB:000000280028002840284038402840287E280000004003F8004000A003180000
+B0CC:000000280028002840284038402840287E28000003F8000803F8000800080000
+B0CD:000000280028002840284038402840287E28000003F8020003F8020003F80000
+B0CE:000000280028002840284038402840287E28000000000FF8022002200FF80000
+B0CF:000000280028002840284038402840287E28000000800FF803E0041003E00000
+B0D0:000000000010001000104010401E40104010401E40107F900010001000100000
+B0D1:0000000800080008400E4008400E40087E08000007F800080008000800080000
+B0D2:0000000800080008400E4008400E40087E08000000003EF80208020802080000
+B0D3:0000000800080008400E4008400E40087E08000000001F080108011401620000
+B0D4:0000000800080008400E4008400E40087E08000008000800080008000FF80000
+B0D5:0000000800080008400E4008400E40087E080000000010F8101010301ECC0000
+B0D6:0000000800080008400E4008400E40087E0800000808087F081C08220F9C0000
+B0D7:0000000800080008400E4008400E40087E08000003F802000200020003F80000
+B0D8:0000000800080008400E4008400E40087E08000007F8000807F8040007F80000
+B0D9:0000000800080008400E4008400E40087E0800003EF802083E0820083E080000
+B0DA:0000000800080008400E4008400E40087E0800003EF802883E8820883EF80000
+B0DB:0000000800080008400E4008400E40087E0800003E8802883EF820883EF80000
+B0DC:0000000800080008400E4008400E40087E0800001F0801081F0810141F620000
+B0DD:0000000800080008400E4008400E40087E0800003EF802803EF820803EF80000
+B0DE:0000000800080008400E4008400E40087E0800003EFC02483E4820483EFC0000
+B0DF:0000000800080008400E4008400E40087E0800001F08017F1F1C10221F1C0000
+B0E0:0000000800080008400E4008400E40087E08000003F802080208020803F80000
+B0E1:0000000800080008400E4008400E40087E0800000208020803F8020803F80000
+B0E2:0000000800080008400E4008400E40087E080000110811081F0811141F620000
+B0E3:0000000800080008400E4008400E40087E080000001000100010006801840000
+B0E4:0000000800080008400E4008400E40087E0800000048004800A8011406620000
+B0E5:0000000800080008400E4008400E40087E080000000003F00408040803F00000
+B0E6:0000000800080008400E4008400E40087E08000003F80020002000D003080000
+B0E7:0000000800080008400E4008400E40087E080000004003F8004000A003180000
+B0E8:0000000800080008400E4008400E40087E08000003F8000803F8000800080000
+B0E9:0000000800080008400E4008400E40087E08000003F8020003F8020003F80000
+B0EA:0000000800080008400E4008400E40087E08000000000FF8022002200FF80000
+B0EB:0000000800080008400E4008400E40087E08000000800FF803E0041003E00000
+B0EC:000000000012001200124012401E40124012401E40127F920012001200120000
+B0ED:000000280028002840384028403840287E28000007F800080008000800080000
+B0EE:000000280028002840384028403840287E28000000003EF80208020802080000
+B0EF:000000280028002840384028403840287E28000000003E100210022802C40000
+B0F0:000000280028002840384028403840287E28002808000800080008000FF80000
+B0F1:000000280028002840384028403840287E280000000020F8201020303ECC0000
+B0F2:000000280028002840384028403840287E280000202021FC207020883E700000
+B0F3:000000280028002840384028403840287E28000003F802000200020003F80000
+B0F4:000000280028002840384028403840287E28000007F8000807F8040007F80000
+B0F5:000000280028002840384028403840287E2800003EF802083E0820083E080000
+B0F6:000000280028002840384028403840287E2800003EF802883E8820883EF80000
+B0F7:000000280028002840384028403840287E2800003E8802883EF820883EF80000
+B0F8:000000280028002840384028403840287E2800001F0801081F0810141F620000
+B0F9:000000280028002840384028403840287E2800003EF802803EF820803EF80000
+B0FA:000000280028002840384028403840287E2800003EFC02483E4820483EFC0000
+B0FB:000000280028002840384028403840287E2800003E1002FE3E3820443E380000
+B0FC:000000280028002840384028403840287E28000003F802080208020803F80000
+B0FD:000000280028002840384028403840287E2800000208020803F8020803F80000
+B0FE:000000280028002840384028403840287E280000110811081F0811141F620000
+B0FF:000000280028002840384028403840287E280000000800080008003400C20000
+B100:000000280028002840384028403840287E2800000048004800A8011406620000
+B101:000000280028002840384028403840287E280000000001F00208020801F00000
+B102:000000280028002840384028403840287E28000003F80020002000D003080000
+B103:000000280028002840384028403840287E280000004003F8004000A003180000
+B104:000000280028002840384028403840287E28000003F8000803F8000800080000
+B105:000000280028002840384028403840287E28000003F8020003F8020003F80000
+B106:000000280028002840384028403840287E28000000000FF8022002200FF80000
+B107:000000280028002840384028403840287E28000000800FF803E0041003E00000
+B108:0000000000020002000240024002401E4002400240027F820002000200020000
+B109:000000080008000840084038400840087E080000000007F80008000800080000
+B10A:000000080008000840084038400840087E08000000003EF80208020802080000
+B10B:000000080008000840084038400840087E08000000001F080108011401620000
+B10C:000000080008000840084038400840087E08000000001000100010001FF80000
+B10D:000000080008000840084038400840087E080000000020F8201020303ECC0000
+B10E:000000080008000840084038400840087E080000202021FC207020883E700000
+B10F:000000080008000840084038400840087E08000003F802000200020003F80000
+B110:000000080008000840084038400840087E08000007F8000807F8040007F80000
+B111:000000080008000840084038400840087E0800003EF802083E0820083E080000
+B112:000000080008000840084038400840087E0800003EF802883E8820883EF80000
+B113:000000080008000840084038400840087E0800003E8802883EF820883EF80000
+B114:000000080008000840084038400840087E0800000F8800880F8808140FA20000
+B115:000000080008000840084038400840087E0800003EF802803EF820803EF80000
+B116:000000080008000840084038400840087E0800003EFC02483E4820483EFC0000
+B117:000000080008000840084038400840087E0800003E1002FE3E3820443E380000
+B118:000000080008000840084038400840087E08000003F802080208020803F80000
+B119:000000080008000840084038400840087E0800000208020803F8020803F80000
+B11A:000000080008000840084038400840087E080000210821083F0821143F620000
+B11B:000000080008000840084038400840087E080000001000100010006801840000
+B11C:000000080008000840084038400840087E0800000048004800A8011406620000
+B11D:000000080008000840084038400840087E080000000003F00408040803F00000
+B11E:000000080008000840084038400840087E08000003F80020002000D003080000
+B11F:000000080008000840084038400840087E080000004003F8004000A003180000
+B120:000000080008000840084038400840087E08000003F8000803F8000800080000
+B121:000000080008000840084038400840087E08000003F8020003F8020003F80000
+B122:000000080008000840084038400840087E08000000000FF8022002200FF80000
+B123:000000080008000840084038400840087E08000000800FF803E0041003E00000
+B124:00000000000A000A000A400A400A403A400A400A400A7F8A000A000A000A0000
+B125:0000002800280028402840E8402840287E28000007F800080008000800080000
+B126:0000002800280028402840E8402840287E28000000003EF80208020802080000
+B127:0000002800280028402840E8402840287E28000000003E100210022802C40000
+B128:0000002800280028402840E8402840287E28000008000800080008000FF80000
+B129:0000002800280028402840E8402840287E280000000020F8201020303ECC0000
+B12A:0000002800280028402840E8402840287E280000202021FC207020883E700000
+B12B:0000002800280028402840E8402840287E28000003F802000200020003F80000
+B12C:0000002800280028402840E8402840287E28000007F8000807F8040007F80000
+B12D:0000002800280028402840E8402840287E2800003EF802083E0820083E080000
+B12E:0000002800280028402840E8402840287E2800003EF802883E8820883EF80000
+B12F:0000002800280028402840E8402840287E2800003E8802883EF820883EF80000
+B130:0000002800280028402840E8402840287E2800001F0801081F0810141F620000
+B131:0000002800280028402840E8402840287E2800003EF802803EF820803EF80000
+B132:0000002800280028402840E8402840287E2800003EFC02483E4820483EFC0000
+B133:0000002800280028402840E8402840287E2800003E1002FE3E3820443E380000
+B134:0000002800280028402840E8402840287E28000003F802080208020803F80000
+B135:0000002800280028402840E8402840287E2800000208020803F8020803F80000
+B136:0000002800280028402840E8402840287E280000110811081F0811141F620000
+B137:0000002800280028402840E8402840287E280000000800080008003400C20000
+B138:0000002800280028402840E8402840287E2800000048004800A8011406620000
+B139:0000002800280028402840E8402840287E280000000001F00208020801F00000
+B13A:0000002800280028402840E8402840287E28000003F80020002000D003080000
+B13B:0000002800280028402840E8402840287E280000004003F8004000A003180000
+B13C:0000002800280028402840E8402840287E28000003F8000803F8000800080000
+B13D:0000002800280028402840E8402840287E28000003F8020003F8020003F80000
+B13E:0000002800280028402840E8402840287E28000000000FF8022002200FF80000
+B13F:0000002800280028402840E8402840287E28000000800FF803E0041003E00000
+B140:000000000002000200024002401E40024002401E40027F820002000200020000
+B141:000000080008000840384008403840087E080000000007F80008000800080000
+B142:000000080008000840384008403840087E08000000003EF80208020802080000
+B143:000000080008000840384008403840087E08000000001F080108011401620000
+B144:000000080008000840384008403840087E08000800001000100010001FF80000
+B145:000000080008000840384008403840087E080000000020F8201020303ECC0000
+B146:000000080008000840384008403840087E080000202021FC207020883E700000
+B147:000000080008000840384008403840087E08000003F802000200020003F80000
+B148:000000080008000840384008403840087E08000007F8000807F8040007F80000
+B149:000000080008000840384008403840087E0800003EF802083E0820083E080000
+B14A:000000080008000840384008403840087E0800003EF802883E8820883EF80000
+B14B:000000080008000840384008403840087E0800003E8802883EF820883EF80000
+B14C:000000080008000840384008403840087E0800000F8800880F8808140FA20000
+B14D:000000080008000840384008403840087E0800003EF802803EF820803EF80000
+B14E:000000080008000840384008403840087E0800003EFC02483E4820483EFC0000
+B14F:000000080008000840384008403840087E0800003E1002FE3E3820443E380000
+B150:000000080008000840384008403840087E08000003F802080208020803F80000
+B151:000000080008000840384008403840087E0800000208020803F8020803F80000
+B152:000000080008000840384008403840087E080000210821083F0821143F620000
+B153:000000080008000840384008403840087E080000001000100010006801840000
+B154:000000080008000840384008403840087E0800000048004800A8011406620000
+B155:000000080008000840384008403840087E080000000003F00408040803F00000
+B156:000000080008000840384008403840087E08000003F80020002000D003080000
+B157:000000080008000840384008403840087E080000004003F8004000A003180000
+B158:000000080008000840384008403840087E08000003F8000803F8000800080000
+B159:000000080008000840384008403840087E08000003F8020003F8020003F80000
+B15A:000000080008000840384008403840087E08000000000FF8022002200FF80000
+B15B:000000080008000840384008403840087E08000000800FF803E0041003E00000
+B15C:00000000000A000A000A400A403A400A400A403A400A7F8A000A000A000A0000
+B15D:000000280028002840E8402840E840287E28000007F800080008000800080000
+B15E:000000280028002840E8402840E840287E28000000003EF80208020802080000
+B15F:000000280028002840E8402840E840287E28000000003E100210022802C40000
+B160:000000280028002840E8402840E840287E28002808000800080008000FF80000
+B161:000000280028002840E8402840E840287E280000000020F8201020303ECC0000
+B162:000000280028002840E8402840E840287E280000202021FC207020883E700000
+B163:000000280028002840E8402840E840287E28000003F802000200020003F80000
+B164:000000280028002840E8402840E840287E28000007F8000807F8040007F80000
+B165:000000280028002840E8402840E840287E2800003EF802083E0820083E080000
+B166:000000280028002840E8402840E840287E2800003EF802883E8820883EF80000
+B167:000000280028002840E8402840E840287E2800003E8802883EF820883EF80000
+B168:000000280028002840E8402840E840287E2800001F0801081F0810141F620000
+B169:000000280028002840E8402840E840287E2800003EF802803EF820803EF80000
+B16A:000000280028002840E8402840E840287E2800003EFC02483E4820483EFC0000
+B16B:000000280028002840E8402840E840287E2800003E1002FE3E3820443E380000
+B16C:000000280028002840E8402840E840287E28000003F802080208020803F80000
+B16D:000000280028002840E8402840E840287E2800000208020803F8020803F80000
+B16E:000000280028002840E8402840E840287E280000110811081F0811141F620000
+B16F:000000280028002840E8402840E840287E280000000800080008003400C20000
+B170:000000280028002840E8402840E840287E2800000048004800A8011406620000
+B171:000000280028002840E8402840E840287E280000000001F00208020801F00000
+B172:000000280028002840E8402840E840287E28000003F80020002000D003080000
+B173:000000280028002840E8402840E840287E280000004003F8004000A003180000
+B174:000000280028002840E8402840E840287E28000003F8000803F8000800080000
+B175:000000280028002840E8402840E840287E28000003F8020003F8020003F80000
+B176:000000280028002840E8402840E840287E28000000000FF8022002200FF80000
+B177:000000280028002840E8402840E840287E28000000800FF803E0041003E00000
+B178:00000000200020002000200020003FF8000000000100010001007FFC00000000
+B179:000000001000100010001FF0010001007FFC00001FF000100010001000100000
+B17A:000000001000100010001FF0010001007FFC000000003EF80208020802080000
+B17B:000000001000100010001FF0010001007FFC000000001E100210022802C40000
+B17C:000000001000100010001FF0010001007FFC000000001000100010001FF00000
+B17D:000000001000100010001FF0010001007FFC0000000020F8201020303ECC0000
+B17E:000000001000100010001FF0010001007FFC0000202021FC207020883E700000
+B17F:000000001000100010001FF0010001007FFC00001FF01000100010001FF00000
+B180:000000001000100010001FF0010001007FFC00001FF000101FF010001FF00000
+B181:000000001000100010001FF0010001007FFC00003EF802083E0820083E080000
+B182:000000001000100010001FF0010001007FFC00003EF802883E8820883EF80000
+B183:000000001000100010001FF0010001007FFC00003E8802883EF820883EF80000
+B184:000000001000100010001FF0010001007FFC00003E1002103E1020283EC40000
+B185:000000001000100010001FF0010001007FFC00003EF802803EF820803EF80000
+B186:000000001000100010001FF0010001007FFC00003EFC02483E4820483EFC0000
+B187:000000001000100010001FF0010001007FFC00003E2003FC3E7020883E700000
+B188:000000001000100010001FF0010001007FFC00001FF01010101010101FF00000
+B189:000000001000100010001FF0010001007FFC0000101010101FF010101FF00000
+B18A:000000001000100010001FF0010001007FFC0000222022203E2022503E880000
+B18B:000000001000100010001FF0010001007FFC000000000100010002800C400000
+B18C:000000001000100010001FF0010001007FFC00000000024002400DA033100000
+B18D:000000001000100010001FF0010001007FFC0000000007C00820082007C00000
+B18E:000000001000100010001FF0010001007FFC0000000007E00080014006200000
+B18F:000000001000100010001FF0010001007FFC0000008007E00080014006200000
+B190:000000001000100010001FF0010001007FFC00001FF000101FF0001000100000
+B191:000000001000100010001FF0010001007FFC00001FF010001FF010001FF00000
+B192:000000001000100010001FF0010001007FFC000000001FF0044004401FF00000
+B193:000000001000100010001FF0010001007FFC000001001FF007C0082007C00000
+B194:0000001000104010401040104010401E7F900010041004107FD0001000100000
+B195:0000000820082008200E20083F8804087FE8000007F800080008000800080000
+B196:0000000820082008200E20083F8804087FE8000000003EF80208020802080000
+B197:0000000820082008200E20083F8804087FE8000000001F080108011401620000
+B198:0000000820082008200E20083F8804087FE8000008000800080008000FF80000
+B199:0000000820082008200E20083F8804087FE80000000010F8101010301ECC0000
+B19A:0000000820082008200E20083F8804087FE800000808087F081C08220F9C0000
+B19B:0000000820082008200E20083F8804087FE8000003F802000200020003F80000
+B19C:0000000820082008200E20083F8804087FE8000007F8000807F8040007F80000
+B19D:0000000820082008200E20083F8804087FE800003EF802083E0820083E080000
+B19E:0000000820082008200E20083F8804087FE800003EF802883E8820883EF80000
+B19F:0000000820082008200E20083F8804087FE800003E8802883EF820883EF80000
+B1A0:0000000820082008200E20083F8804087FE800001F0801081F0810141F620000
+B1A1:0000000820082008200E20083F8804087FE800003EF802803EF820803EF80000
+B1A2:0000000820082008200E20083F8804087FE800003EFC02483E4820483EFC0000
+B1A3:0000000820082008200E20083F8804087FE800001F08017F1F1C10221F1C0000
+B1A4:0000000820082008200E20083F8804087FE8000003F802080208020803F80000
+B1A5:0000000820082008200E20083F8804087FE800000208020803F8020803F80000
+B1A6:0000000820082008200E20083F8804087FE80000110811081F0811141F620000
+B1A7:0000000820082008200E20083F8804087FE80000001000100010006801840000
+B1A8:0000000820082008200E20083F8804087FE800000048004800A8011406620000
+B1A9:0000000820082008200E20083F8804087FE80000000003F00408040803F00000
+B1AA:0000000820082008200E20083F8804087FE8000003F80020002000D003080000
+B1AB:0000000820082008200E20083F8804087FE80000004003F8004000A003180000
+B1AC:0000000820082008200E20083F8804087FE8000003F8000803F8000800080000
+B1AD:0000000820082008200E20083F8804087FE8000003F8020003F8020003F80000
+B1AE:0000000820082008200E20083F8804087FE8000000000FF8022002200FF80000
+B1AF:0000000820082008200E20083F8804087FE8000000800FF803E0041003E00000
+B1B0:0000001200124012401240124012401E7F920012041204127FD2001200120000
+B1B1:0000002820282028203820283FA804287FA8000007F800080008000800080000
+B1B2:0000002820282028203820283FA804287FA8000000003EF80208020802080000
+B1B3:0000002820282028203820283FA804287FA8000000001F080108011401620000
+B1B4:0000002820282028203820283FA804287FA8000008000800080008000FF80000
+B1B5:0000002820282028203820283FA804287FA80000000010F8101010301ECC0000
+B1B6:0000002820282028203820283FA804287FA800000808087F081C08220F9C0000
+B1B7:0000002820282028203820283FA804287FA8000003F802000200020003F80000
+B1B8:0000002820282028203820283FA804287FA8000007F8000807F8040007F80000
+B1B9:0000002820282028203820283FA804287FA800003EF802083E0820083E080000
+B1BA:0000002820282028203820283FA804287FA800003EF802883E8820883EF80000
+B1BB:0000002820282028203820283FA804287FA800003E8802883EF820883EF80000
+B1BC:0000002820282028203820283FA804287FA800001F0801081F0810141F620000
+B1BD:0000002820282028203820283FA804287FA800003EF802803EF820803EF80000
+B1BE:0000002820282028203820283FA804287FA800003EFC02483E4820483EFC0000
+B1BF:0000002820282028203820283FA804287FA800001F08017F1F1C10221F1C0000
+B1C0:0000002820282028203820283FA804287FA8000003F802080208020803F80000
+B1C1:0000002820282028203820283FA804287FA800000208020803F8020803F80000
+B1C2:0000002820282028203820283FA804287FA80000110811081F0811141F620000
+B1C3:0000002820282028203820283FA804287FA80000001000100010006801840000
+B1C4:0000002820282028203820283FA804287FA800000048004800A8011406620000
+B1C5:0000002820282028203820283FA804287FA80000000003F00408040803F00000
+B1C6:0000002820282028203820283FA804287FA8000003F80020002000D003080000
+B1C7:0000002820282028203820283FA804287FA80000004003F8004000A003180000
+B1C8:0000002820282028203820283FA804287FA8000003F8000803F8000800080000
+B1C9:0000002820282028203820283FA804287FA8000003F8020003F8020003F80000
+B1CA:0000002820282028203820283FA804287FA8000000000FF8022002200FF80000
+B1CB:0000002820282028203820283FA804287FA8000000800FF803E0041003E00000
+B1CC:000000080008400840084008400840087F880008040804087FE8000800080000
+B1CD:0000000820082008200820083F8804087FE8000007F800080008000800080000
+B1CE:0000000820082008200820083F8804087FE8000000003EF80208020802080000
+B1CF:0000000820082008200820083F8804087FE8000000001F080108011401620000
+B1D0:0000000820082008200820083F8804087FE8000008000800080008000FF80000
+B1D1:0000000820082008200820083F8804087FE80000000010F8101010301ECC0000
+B1D2:0000000820082008200820083F8804087FE800000808087F081C08220F9C0000
+B1D3:0000000820082008200820083F8804087FE8000003F802000200020003F80000
+B1D4:0000000820082008200820083F8804087FE8000007F8000807F8040007F80000
+B1D5:0000000820082008200820083F8804087FE800003EF802083E0820083E080000
+B1D6:0000000820082008200820083F8804087FE800003EF802883E8820883EF80000
+B1D7:0000000820082008200820083F8804087FE800003E8802883EF820883EF80000
+B1D8:0000000820082008200820083F8804087FE800001F0801081F0810141F620000
+B1D9:0000000820082008200820083F8804087FE800003EF802803EF820803EF80000
+B1DA:0000000820082008200820083F8804087FE800003EFC02483E4820483EFC0000
+B1DB:0000000820082008200820083F8804087FE800001F08017F1F1C10221F1C0000
+B1DC:0000000820082008200820083F8804087FE8000003F802080208020803F80000
+B1DD:0000000820082008200820083F8804087FE800000208020803F8020803F80000
+B1DE:0000000820082008200820083F8804087FE80000110811081F0811141F620000
+B1DF:0000000820082008200820083F8804087FE80000001000100010006801840000
+B1E0:0000000820082008200820083F8804087FE800000048004800A8011406620000
+B1E1:0000000820082008200820083F8804087FE80000000003F00408040803F00000
+B1E2:0000000820082008200820083F8804087FE8000003F80020002000D003080000
+B1E3:0000000820082008200820083F8804087FE80000004003F8004000A003180000
+B1E4:0000000820082008200820083F8804087FE8000003F8000803F8000800080000
+B1E5:0000000820082008200820083F8804087FE8000003F8020003F8020003F80000
+B1E6:0000000820082008200820083F8804087FE8000000000FF8022002200FF80000
+B1E7:0000000820082008200820083F8804087FE8000000800FF803E0041003E00000
+B1E8:00000000200020002000200020003FF8000004400440044004407FFC00000000
+B1E9:000000001000100010001FF0044004407FFC00001FF000100010001000100000
+B1EA:000000001000100010001FF0044004407FFC000000003EF80208020802080000
+B1EB:000000001000100010001FF0044004407FFC000000001E100210022802C40000
+B1EC:000000001000100010001FF0044004407FFC000000001000100010001FF00000
+B1ED:000000001000100010001FF0044004407FFC0000000020F8201020303ECC0000
+B1EE:000000001000100010001FF0044004407FFC0000202021FC207020883E700000
+B1EF:000000001000100010001FF0044004407FFC00001FF01000100010001FF00000
+B1F0:000000001000100010001FF0044004407FFC00001FF000101FF010001FF00000
+B1F1:000000001000100010001FF0044004407FFC00003EF802083E0820083E080000
+B1F2:000000001000100010001FF0044004407FFC00003EF802883E8820883EF80000
+B1F3:000000001000100010001FF0044004407FFC00003E8802883EF820883EF80000
+B1F4:000000001000100010001FF0044004407FFC00003E1002103E1020283EC40000
+B1F5:000000001000100010001FF0044004407FFC00003EF802803EF820803EF80000
+B1F6:000000001000100010001FF0044004407FFC00003EFC02483E4820483EFC0000
+B1F7:000000001000100010001FF0044004407FFC00003E2003FC3E7020883E700000
+B1F8:000000001000100010001FF0044004407FFC00001FF01010101010101FF00000
+B1F9:000000001000100010001FF0044004407FFC0000101010101FF010101FF00000
+B1FA:000000001000100010001FF0044004407FFC0000222022203E2022503E880000
+B1FB:000000001000100010001FF0044004407FFC000000000100010002800C400000
+B1FC:000000001000100010001FF0044004407FFC00000000024002400DA033100000
+B1FD:000000001000100010001FF0044004407FFC0000000007C00820082007C00000
+B1FE:000000001000100010001FF0044004407FFC0000000007E00080014006200000
+B1FF:000000001000100010001FF0044004407FFC0000008007E00080014006200000
+B200:000000001000100010001FF0044004407FFC00001FF000101FF0001000100000
+B201:000000001000100010001FF0044004407FFC00001FF010001FF010001FF00000
+B202:000000001000100010001FF0044004407FFC000000001FF0044004401FF00000
+B203:000000001000100010001FF0044004407FFC000001001FF007C0082007C00000
+B204:00000000200020002000200020003FF8000000003FF801000100010001000000
+B205:000000001000100010001FF000007FFC010001001FF000100010001000100000
+B206:000000001000100010001FF000007FFC0100010000003EF80208020802080000
+B207:000000001000100010001FF000007FFC0100010000001E100210022802C40000
+B208:000000001000100010001FF0000000007FFC010001001100100010001FF00000
+B209:000000001000100010001FF000007FFC01000100000020F8201020303ECC0000
+B20A:000000001000100010001FF000007FFC01000100202021FC207020883E700000
+B20B:000000001000100010001FF000007FFC010001001FF01000100010001FF00000
+B20C:000000001000100010001FF000007FFC010001001FF000101FF010001FF00000
+B20D:000000001000100010001FF000007FFC010001003EF802083E0820083E080000
+B20E:000000001000100010001FF000007FFC010001003EF802883E8820883EF80000
+B20F:000000001000100010001FF000007FFC010001003E8802883EF820883EF80000
+B210:000000001000100010001FF000007FFC010001003E1002103E1020283EC40000
+B211:000000001000100010001FF000007FFC010001003EF802803EF820803EF80000
+B212:000000001000100010001FF000007FFC010001003EFC02483E4820483EFC0000
+B213:000000001000100010001FF000007FFC010001003E2003FC3E7020883E700000
+B214:000000001000100010001FF000007FFC010001001FF01010101010101FF00000
+B215:000000001000100010001FF000007FFC01000100101010101FF010101FF00000
+B216:000000001000100010001FF000007FFC01000100222022203E2022503E880000
+B217:000000001000100010001FF000007FFC0100010000000100010002800C400000
+B218:000000001000100010001FF000007FFC010001000000024002400DA033100000
+B219:000000001000100010001FF000007FFC01000100000007C00820082007C00000
+B21A:000000001000100010001FF000007FFC01000100000007E00080014006200000
+B21B:000000001000100010001FF000007FFC01000100008007E00080014006200000
+B21C:000000001000100010001FF000007FFC010001001FF000101FF0001000100000
+B21D:000000001000100010001FF000007FFC010001001FF010001FF010001FF00000
+B21E:000000001000100010001FF000007FFC0100010000001FF0044004401FF00000
+B21F:000000001000100010001FF000007FFC0100010001001FF007C0082007C00000
+B220:00000008000840084008400840087F88000800087FE8040804F8040804080000
+B221:00082008200820083F8800087FE8027802080000000007F80008000800080000
+B222:00082008200820083F8800087FE802780208000000003EF80208020802080000
+B223:00082008200820083F8800087FE802780208000000001F080108011401620000
+B224:00082008200820083F88000800087FE80278020802081000100010001FF80000
+B225:00082008200820083F8800087FE8027802080000000020F8201020303ECC0000
+B226:00082008200820083F8800087FE8027802080000202021FC207020883E700000
+B227:00082008200820083F8800087FE802780208000003F802000200020003F80000
+B228:00082008200820083F8800087FE802780208000007F8000807F8040007F80000
+B229:00082008200820083F8800087FE80278020800003EF802083E0820083E080000
+B22A:00082008200820083F8800087FE80278020800003EF802883E8820883EF80000
+B22B:00082008200820083F8800087FE80278020800003E8802883EF820883EF80000
+B22C:00082008200820083F8800087FE80278020800000F8800880F8808140FA20000
+B22D:00082008200820083F8800087FE80278020800003EF802803EF820803EF80000
+B22E:00082008200820083F8800087FE80278020800003EFC02483E4820483EFC0000
+B22F:00082008200820083F8800087FE80278020800003E1002FE3E3820443E380000
+B230:00082008200820083F8800087FE802780208000003F802080208020803F80000
+B231:00082008200820083F8800087FE80278020800000208020803F8020803F80000
+B232:00082008200820083F8800087FE8027802080000210821083F0821143F620000
+B233:00082008200820083F8800087FE8027802080000001000100010006801840000
+B234:00082008200820083F8800087FE80278020800000048004800A8011406620000
+B235:00082008200820083F8800087FE8027802080000000003F00408040803F00000
+B236:00082008200820083F8800087FE802780208000003F80020002000D003080000
+B237:00082008200820083F8800087FE8027802080000004003F8004000A003180000
+B238:00082008200820083F8800087FE802780208000003F8000803F8000800080000
+B239:00082008200820083F8800087FE802780208000003F8020003F8020003F80000
+B23A:00082008200820083F8800087FE802780208000000000FF8022002200FF80000
+B23B:00082008200820083F8800087FE802780208000000800FF803E0041003E00000
+B23C:0000000A000A400A400A400A400A7F8A000A000A7FEA040A047A040A040A0000
+B23D:00282028202820283FA800287FA805E804280000000007F80008000800080000
+B23E:00282028202820283FA800287FA805E80428000000003EF80208020802080000
+B23F:00282028202820283FA800287FA805E80428000000001F080108011401620000
+B240:00282028202820283FA8002800287FA8042805E804281428100010001FF80000
+B241:00282028202820283FA800287FA805E804280000000020F8201020303ECC0000
+B242:00282028202820283FA800287FA805E804280000202021FC207020883E700000
+B243:00282028202820283FA800287FA805E80428000003F802000200020003F80000
+B244:00282028202820283FA800287FA805E80428000007F8000807F8040007F80000
+B245:00282028202820283FA800287FA805E8042800003EF802083E0820083E080000
+B246:00282028202820283FA800287FA805E8042800003EF802883E8820883EF80000
+B247:00282028202820283FA800287FA805E8042800003E8802883EF820883EF80000
+B248:00282028202820283FA800287FA805E8042800000F8800880F8808140FA20000
+B249:00282028202820283FA800287FA805E8042800003EF802803EF820803EF80000
+B24A:00282028202820283FA800287FA805E8042800003EFC02483E4820483EFC0000
+B24B:00282028202820283FA800287FA805E8042800003E1002FE3E3820443E380000
+B24C:00282028202820283FA800287FA805E80428000003F802080208020803F80000
+B24D:00282028202820283FA800287FA805E8042800000208020803F8020803F80000
+B24E:00282028202820283FA800287FA805E804280000210821083F0821143F620000
+B24F:00282028202820283FA800287FA805E804280000001000100010006801840000
+B250:00282028202820283FA800287FA805E8042800000048004800A8011406620000
+B251:00282028202820283FA800287FA805E804280000000003F00408040803F00000
+B252:00282028202820283FA800287FA805E80428000003F80020002000D003080000
+B253:00282028202820283FA800287FA805E804280000004003F8004000A003180000
+B254:00282028202820283FA800287FA805E80428000003F8000803F8000800080000
+B255:00282028202820283FA800287FA805E80428000003F8020003F8020003F80000
+B256:00282028202820283FA800287FA805E80428000000000FF8022002200FF80000
+B257:00282028202820283FA800287FA805E80428000000800FF803E0041003E00000
+B258:00000008000840084008400840087F88000800087FE804080408040804080000
+B259:00082008200820083F8800087FE8020802000000000007F80008000800080000
+B25A:00082008200820083F8800087FE802080200000000003EF80208020802080000
+B25B:00082008200820083F8800087FE802080200000000001F080108011401620000
+B25C:00082008200820083F88000800087FE80208020802081008100010001FF80000
+B25D:00082008200820083F8800087FE8020802000000000020F8201020303ECC0000
+B25E:00082008200820083F8800087FE8020802000000202021FC207020883E700000
+B25F:00082008200820083F8800087FE802080200000003F802000200020003F80000
+B260:00082008200820083F8800087FE802080200000007F8000807F8040007F80000
+B261:00082008200820083F8800087FE80208020000003EF802083E0820083E080000
+B262:00082008200820083F8800087FE80208020000003EF802883E8820883EF80000
+B263:00082008200820083F8800087FE80208020000003E8802883EF820883EF80000
+B264:00082008200820083F8800087FE80208020000000F8800880F8808140FA20000
+B265:00082008200820083F8800087FE80208020000003EF802803EF820803EF80000
+B266:00082008200820083F8800087FE80208020000003EFC02483E4820483EFC0000
+B267:00082008200820083F8800087FE80208020000003E1002FE3E3820443E380000
+B268:00082008200820083F8800087FE802080200000003F802080208020803F80000
+B269:00082008200820083F8800087FE80208020000000208020803F8020803F80000
+B26A:00082008200820083F8800087FE8020802000000210821083F0821143F620000
+B26B:00082008200820083F8800087FE8020802000000001000100010006801840000
+B26C:00082008200820083F8800087FE80208020000000048004800A8011406620000
+B26D:00082008200820083F8800087FE8020802000000000003F00408040803F00000
+B26E:00082008200820083F8800087FE802080200000003F80020002000D003080000
+B26F:00082008200820083F8800087FE8020802000000004003F8004000A003180000
+B270:00082008200820083F8800087FE802080200000003F8000803F8000800080000
+B271:00082008200820083F8800087FE802080200000003F8020003F8020003F80000
+B272:00082008200820083F8800087FE802080200000000000FF8022002200FF80000
+B273:00082008200820083F8800087FE802080200000000800FF803E0041003E00000
+B274:00000000200020002000200020003FF8000000007FFC04400440044004400000
+B275:000000001000100010001FF000007FFC044004401FF000100010001000100000
+B276:000000001000100010001FF000007FFC0440044000003EF80208020802080000
+B277:000000001000100010001FF000007FFC0440044000001E100210022802C40000
+B278:000000001000100010001FF0000000007FFC044004401440100010001FF00000
+B279:000000001000100010001FF000007FFC04400440000020F8201020303ECC0000
+B27A:000000001000100010001FF000007FFC04400440202021FC207020883E700000
+B27B:000000001000100010001FF000007FFC044004401FF01000100010001FF00000
+B27C:000000001000100010001FF000007FFC044004401FF000101FF010001FF00000
+B27D:000000001000100010001FF000007FFC044004403EF802083E0820083E080000
+B27E:000000001000100010001FF000007FFC044004403EF802883E8820883EF80000
+B27F:000000001000100010001FF000007FFC044004403E8802883EF820883EF80000
+B280:000000001000100010001FF000007FFC044004403E1002103E1020283EC40000
+B281:000000001000100010001FF000007FFC044004403EF802803EF820803EF80000
+B282:000000001000100010001FF000007FFC044004403EFC02483E4820483EFC0000
+B283:000000001000100010001FF000007FFC044004403E2003FC3E7020883E700000
+B284:000000001000100010001FF000007FFC044004401FF01010101010101FF00000
+B285:000000001000100010001FF000007FFC04400440101010101FF010101FF00000
+B286:000000001000100010001FF000007FFC04400440222022203E2022503E880000
+B287:000000001000100010001FF000007FFC0440044000000100010002800C400000
+B288:000000001000100010001FF000007FFC044004400000024002400DA033100000
+B289:000000001000100010001FF000007FFC04400440000007C00820082007C00000
+B28A:000000001000100010001FF000007FFC04400440000007E00080014006200000
+B28B:000000001000100010001FF000007FFC04400440008007E00080014006200000
+B28C:000000001000100010001FF000007FFC044004401FF000101FF0001000100000
+B28D:000000001000100010001FF000007FFC044004401FF010001FF010001FF00000
+B28E:000000001000100010001FF000007FFC0440044000001FF0044004401FF00000
+B28F:000000001000100010001FF000007FFC0440044001001FF007C0082007C00000
+B290:00000000200020002000200020003FF80000000000007FFC0000000000000000
+B291:000000001000100010001FF0000000007FFC00001FF000100010001000100000
+B292:000000001000100010001FF0000000007FFC000000003EF80208020802080000
+B293:000000001000100010001FF0000000007FFC000000001E100210022802C40000
+B294:000000001000100010001FF0000000007FFC000000001000100010001FF00000
+B295:000000001000100010001FF0000000007FFC0000000020F8201020303ECC0000
+B296:000000001000100010001FF0000000007FFC0000202021FC207020883E700000
+B297:000000001000100010001FF0000000007FFC00001FF01000100010001FF00000
+B298:000000001000100010001FF0000000007FFC00001FF000101FF010001FF00000
+B299:000000001000100010001FF0000000007FFC00003EF802083E0820083E080000
+B29A:000000001000100010001FF0000000007FFC00003EF802883E8820883EF80000
+B29B:000000001000100010001FF0000000007FFC00003E8802883EF820883EF80000
+B29C:000000001000100010001FF0000000007FFC00003E1002103E1020283EC40000
+B29D:000000001000100010001FF0000000007FFC00003EF802803EF820803EF80000
+B29E:000000001000100010001FF0000000007FFC00003EFC02483E4820483EFC0000
+B29F:000000001000100010001FF0000000007FFC00003E2003FC3E7020883E700000
+B2A0:000000001000100010001FF0000000007FFC00001FF01010101010101FF00000
+B2A1:000000001000100010001FF0000000007FFC0000101010101FF010101FF00000
+B2A2:000000001000100010001FF0000000007FFC0000222022203E2022503E880000
+B2A3:000000001000100010001FF0000000007FFC000000000100010002800C400000
+B2A4:000000001000100010001FF0000000007FFC00000000024002400DA033100000
+B2A5:000000001000100010001FF0000000007FFC0000000007C00820082007C00000
+B2A6:000000001000100010001FF0000000007FFC0000000007E00080014006200000
+B2A7:000000001000100010001FF0000000007FFC0000008007E00080014006200000
+B2A8:000000001000100010001FF0000000007FFC00001FF000101FF0001000100000
+B2A9:000000001000100010001FF0000000007FFC00001FF010001FF010001FF00000
+B2AA:000000001000100010001FF0000000007FFC000000001FF0044004401FF00000
+B2AB:000000001000100010001FF0000000007FFC000001001FF007C0082007C00000
+B2AC:000000080008400840084008400840087F88000800087FE80008000800080000
+B2AD:0000000820082008200820083F8800087FE8000007F800080008000800080000
+B2AE:0000000820082008200820083F8800087FE8000000003EF80208020802080000
+B2AF:0000000820082008200820083F8800087FE8000000001F080108011401620000
+B2B0:0000000820082008200820083F8800087FE8000008000800080008000FF80000
+B2B1:0000000820082008200820083F8800087FE80000000010F8101010301ECC0000
+B2B2:0000000820082008200820083F8800087FE800000808087F081C08220F9C0000
+B2B3:0000000820082008200820083F8800087FE8000003F802000200020003F80000
+B2B4:0000000820082008200820083F8800087FE8000007F8000807F8040007F80000
+B2B5:0000000820082008200820083F8800087FE800003EF802083E0820083E080000
+B2B6:0000000820082008200820083F8800087FE800003EF802883E8820883EF80000
+B2B7:0000000820082008200820083F8800087FE800003E8802883EF820883EF80000
+B2B8:0000000820082008200820083F8800087FE800001F0801081F0810141F620000
+B2B9:0000000820082008200820083F8800087FE800003EF802803EF820803EF80000
+B2BA:0000000820082008200820083F8800087FE800003EFC02483E4820483EFC0000
+B2BB:0000000820082008200820083F8800087FE800001F08017F1F1C10221F1C0000
+B2BC:0000000820082008200820083F8800087FE8000003F802080208020803F80000
+B2BD:0000000820082008200820083F8800087FE800000208020803F8020803F80000
+B2BE:0000000820082008200820083F8800087FE80000110811081F0811141F620000
+B2BF:0000000820082008200820083F8800087FE80000001000100010006801840000
+B2C0:0000000820082008200820083F8800087FE800000048004800A8011406620000
+B2C1:0000000820082008200820083F8800087FE80000000003F00408040803F00000
+B2C2:0000000820082008200820083F8800087FE8000003F80020002000D003080000
+B2C3:0000000820082008200820083F8800087FE80000004003F8004000A003180000
+B2C4:0000000820082008200820083F8800087FE8000003F8000803F8000800080000
+B2C5:0000000820082008200820083F8800087FE8000003F8020003F8020003F80000
+B2C6:0000000820082008200820083F8800087FE8000000000FF8022002200FF80000
+B2C7:0000000820082008200820083F8800087FE8000000800FF803E0041003E00000
+B2C8:000000000008000800084008400840084008400840087F880008000800080000
+B2C9:000000080008000840084008400840087E080000000007F80008000800080000
+B2CA:000000080008000840084008400840087E08000000003EF80208020802080000
+B2CB:000000080008000840084008400840087E08000000001F080108011401620000
+B2CC:000000080008000840084008400840087E08000800001000100010001FF80000
+B2CD:000000080008000840084008400840087E080000000020F8201020303ECC0000
+B2CE:000000080008000840084008400840087E080000202021FC207020883E700000
+B2CF:000000080008000840084008400840087E08000003F802000200020003F80000
+B2D0:000000080008000840084008400840087E08000007F8000807F8040007F80000
+B2D1:000000080008000840084008400840087E0800003EF802083E0820083E080000
+B2D2:000000080008000840084008400840087E0800003EF802883E8820883EF80000
+B2D3:000000080008000840084008400840087E0800003E8802883EF820883EF80000
+B2D4:000000080008000840084008400840087E0800000F8800880F8808140FA20000
+B2D5:000000080008000840084008400840087E0800003EF802803EF820803EF80000
+B2D6:000000080008000840084008400840087E0800003EFC02483E4820483EFC0000
+B2D7:000000080008000840084008400840087E0800003E1002FE3E3820443E380000
+B2D8:000000080008000840084008400840087E08000003F802080208020803F80000
+B2D9:000000080008000840084008400840087E0800000208020803F8020803F80000
+B2DA:000000080008000840084008400840087E080000210821083F0821143F620000
+B2DB:000000080008000840084008400840087E080000001000100010006801840000
+B2DC:000000080008000840084008400840087E0800000048004800A8011406620000
+B2DD:000000080008000840084008400840087E080000000003F00408040803F00000
+B2DE:000000080008000840084008400840087E08000003F80020002000D003080000
+B2DF:000000080008000840084008400840087E080000004003F8004000A003180000
+B2E0:000000080008000840084008400840087E08000003F8000803F8000800080000
+B2E1:000000080008000840084008400840087E08000003F8020003F8020003F80000
+B2E2:000000080008000840084008400840087E08000000000FF8022002200FF80000
+B2E3:000000080008000840084008400840087E08000000800FF803E0041003E00000
+B2E4:00000000001000107F9040104010401E401040107F9000100010001000100000
+B2E5:0000000800087E084008400E40087E080008000007F800080008000800080000
+B2E6:0000000800087E084008400E40087E080008000000003EF80208020802080000
+B2E7:0000000800087E084008400E40087E080008000000001F080108011401620000
+B2E8:0000000800087E084008400E40087E080008000808000800080008000FF80000
+B2E9:0000000800087E084008400E40087E0800080000000010F8101010301ECC0000
+B2EA:0000000800087E084008400E40087E08000800000808087F081C08220F9C0000
+B2EB:0000000800087E084008400E40087E080008000003F802000200020003F80000
+B2EC:0000000800087E084008400E40087E080008000007F8000807F8040007F80000
+B2ED:0000000800087E084008400E40087E08000800003EF802083E0820083E080000
+B2EE:0000000800087E084008400E40087E08000800003EF802883E8820883EF80000
+B2EF:0000000800087E084008400E40087E08000800003E8802883EF820883EF80000
+B2F0:0000000800087E084008400E40087E08000800001F0801081F0810141F620000
+B2F1:0000000800087E084008400E40087E08000800003EF802803EF820803EF80000
+B2F2:0000000800087E084008400E40087E08000800003EFC02483E4820483EFC0000
+B2F3:0000000800087E084008400E40087E08000800001F08017F1F1C10221F1C0000
+B2F4:0000000800087E084008400E40087E080008000003F802080208020803F80000
+B2F5:0000000800087E084008400E40087E08000800000208020803F8020803F80000
+B2F6:0000000800087E084008400E40087E0800080000110811081F0811141F620000
+B2F7:0000000800087E084008400E40087E0800080000001000100010006801840000
+B2F8:0000000800087E084008400E40087E08000800000048004800A8011406620000
+B2F9:0000000800087E084008400E40087E0800080000000003F00408040803F00000
+B2FA:0000000800087E084008400E40087E080008000003F80020002000D003080000
+B2FB:0000000800087E084008400E40087E0800080000004003F8004000A003180000
+B2FC:0000000800087E084008400E40087E080008000003F8000803F8000800080000
+B2FD:0000000800087E084008400E40087E080008000003F8020003F8020003F80000
+B2FE:0000000800087E084008400E40087E080008000000000FF8022002200FF80000
+B2FF:0000000800087E084008400E40087E080008000000800FF803E0041003E00000
+B300:00000000001200127F9240124012401E401240127F9200120012001200120000
+B301:0000002800287E284028403840287E280028000007F800080008000800080000
+B302:0000002800287E284028403840287E280028000000003EF80208020802080000
+B303:0000002800287E284028403840287E280028000000003E100210022802C40000
+B304:0000002800287E284028403840287E280028002808000800080008000FF80000
+B305:0000002800287E284028403840287E2800280000000020F8201020303ECC0000
+B306:0000002800287E284028403840287E2800280000202021FC207020883E700000
+B307:0000002800287E284028403840287E280028000003F802000200020003F80000
+B308:0000002800287E284028403840287E280028000007F8000807F8040007F80000
+B309:0000002800287E284028403840287E28002800003EF802083E0820083E080000
+B30A:0000002800287E284028403840287E28002800003EF802883E8820883EF80000
+B30B:0000002800287E284028403840287E28002800003E8802883EF820883EF80000
+B30C:0000002800287E284028403840287E28002800001F0801081F0810141F620000
+B30D:0000002800287E284028403840287E28002800003EF802803EF820803EF80000
+B30E:0000002800287E284028403840287E28002800003EFC02483E4820483EFC0000
+B30F:0000002800287E284028403840287E28002800003E1002FE3E3820443E380000
+B310:0000002800287E284028403840287E280028000003F802080208020803F80000
+B311:0000002800287E284028403840287E28002800000208020803F8020803F80000
+B312:0000002800287E284028403840287E2800280000110811081F0811141F620000
+B313:0000002800287E284028403840287E2800280000000800080008003400C20000
+B314:0000002800287E284028403840287E28002800000048004800A8011406620000
+B315:0000002800287E284028403840287E2800280000000001F00208020801F00000
+B316:0000002800287E284028403840287E280028000003F80020002000D003080000
+B317:0000002800287E284028403840287E2800280000004003F8004000A003180000
+B318:0000002800287E284028403840287E280028000003F8000803F8000800080000
+B319:0000002800287E284028403840287E280028000003F8020003F8020003F80000
+B31A:0000002800287E284028403840287E280028000000000FF8022002200FF80000
+B31B:0000002800287E284028403840287E280028000000800FF803E0041003E00000
+B31C:00000000001000107F904010401E40104010401E7F9000100010001000100000
+B31D:0000000800087E08400E4008400E7E080008000007F800080008000800080000
+B31E:0000000800087E08400E4008400E7E080008000000003EF80208020802080000
+B31F:0000000800087E08400E4008400E7E080008000000001F080108011401620000
+B320:0000000800087E08400E4008400E7E080008000008000800080008000FF80000
+B321:0000000800087E08400E4008400E7E0800080000000010F8101010301ECC0000
+B322:0000000800087E08400E4008400E7E08000800000808087F081C08220F9C0000
+B323:0000000800087E08400E4008400E7E080008000003F802000200020003F80000
+B324:0000000800087E08400E4008400E7E080008000007F8000807F8040007F80000
+B325:0000000800087E08400E4008400E7E08000800003EF802083E0820083E080000
+B326:0000000800087E08400E4008400E7E08000800003EF802883E8820883EF80000
+B327:0000000800087E08400E4008400E7E08000800003E8802883EF820883EF80000
+B328:0000000800087E08400E4008400E7E08000800001F0801081F0810141F620000
+B329:0000000800087E08400E4008400E7E08000800003EF802803EF820803EF80000
+B32A:0000000800087E08400E4008400E7E08000800003EFC02483E4820483EFC0000
+B32B:0000000800087E08400E4008400E7E08000800001F08017F1F1C10221F1C0000
+B32C:0000000800087E08400E4008400E7E080008000003F802080208020803F80000
+B32D:0000000800087E08400E4008400E7E08000800000208020803F8020803F80000
+B32E:0000000800087E08400E4008400E7E0800080000110811081F0811141F620000
+B32F:0000000800087E08400E4008400E7E0800080000001000100010006801840000
+B330:0000000800087E08400E4008400E7E08000800000048004800A8011406620000
+B331:0000000800087E08400E4008400E7E0800080000000003F00408040803F00000
+B332:0000000800087E08400E4008400E7E080008000003F80020002000D003080000
+B333:0000000800087E08400E4008400E7E0800080000004003F8004000A003180000
+B334:0000000800087E08400E4008400E7E080008000003F8000803F8000800080000
+B335:0000000800087E08400E4008400E7E080008000003F8020003F8020003F80000
+B336:0000000800087E08400E4008400E7E080008000000000FF8022002200FF80000
+B337:0000000800087E08400E4008400E7E080008000000800FF803E0041003E00000
+B338:00000000001200127F924012401E40124012401E7F9200120012001200120000
+B339:0000002800287E284038402840387E280028000007F800080008000800080000
+B33A:0000002800287E284038402840387E280028000000003EF80208020802080000
+B33B:0000002800287E284038402840387E280028000000003E100210022802C40000
+B33C:0000002800287E284038402840387E280028002808000800080008000FF80000
+B33D:0000002800287E284038402840387E2800280000000020F8201020303ECC0000
+B33E:0000002800287E284038402840387E2800280000202021FC207020883E700000
+B33F:0000002800287E284038402840387E280028000003F802000200020003F80000
+B340:0000002800287E284038402840387E280028000007F8000807F8040007F80000
+B341:0000002800287E284038402840387E28002800003EF802083E0820083E080000
+B342:0000002800287E284038402840387E28002800003EF802883E8820883EF80000
+B343:0000002800287E284038402840387E28002800003E8802883EF820883EF80000
+B344:0000002800287E284038402840387E28002800001F0801081F0810141F620000
+B345:0000002800287E284038402840387E28002800003EF802803EF820803EF80000
+B346:0000002800287E284038402840387E28002800003EFC02483E4820483EFC0000
+B347:0000002800287E284038402840387E28002800003E1002FE3E3820443E380000
+B348:0000002800287E284038402840387E280028000003F802080208020803F80000
+B349:0000002800287E284038402840387E28002800000208020803F8020803F80000
+B34A:0000002800287E284038402840387E2800280000110811081F0811141F620000
+B34B:0000002800287E284038402840387E2800280000000800080008003400C20000
+B34C:0000002800287E284038402840387E28002800000048004800A8011406620000
+B34D:0000002800287E284038402840387E2800280000000001F00208020801F00000
+B34E:0000002800287E284038402840387E280028000003F80020002000D003080000
+B34F:0000002800287E284038402840387E2800280000004003F8004000A003180000
+B350:0000002800287E284038402840387E280028000003F8000803F8000800080000
+B351:0000002800287E284038402840387E280028000003F8020003F8020003F80000
+B352:0000002800287E284038402840387E280028000000000FF8022002200FF80000
+B353:0000002800287E284038402840387E280028000000800FF803E0041003E00000
+B354:00000000000200027F8240024002401E400240027F8200020002000200020000
+B355:0000000800087E084008403840087E0800080000000007F80008000800080000
+B356:0000000800087E084008403840087E080008000000003EF80208020802080000
+B357:0000000800087E084008403840087E080008000000001F080108011401620000
+B358:0000000800087E084008403840087E080008000000001000100010001FF80000
+B359:0000000800087E084008403840087E0800080000000020F8201020303ECC0000
+B35A:0000000800087E084008403840087E0800080000202021FC207020883E700000
+B35B:0000000800087E084008403840087E080008000003F802000200020003F80000
+B35C:0000000800087E084008403840087E080008000007F8000807F8040007F80000
+B35D:0000000800087E084008403840087E08000800003EF802083E0820083E080000
+B35E:0000000800087E084008403840087E08000800003EF802883E8820883EF80000
+B35F:0000000800087E084008403840087E08000800003E8802883EF820883EF80000
+B360:0000000800087E084008403840087E08000800000F8800880F8808140FA20000
+B361:0000000800087E084008403840087E08000800003EF802803EF820803EF80000
+B362:0000000800087E084008403840087E08000800003EFC02483E4820483EFC0000
+B363:0000000800087E084008403840087E08000800003E1002FE3E3820443E380000
+B364:0000000800087E084008403840087E080008000003F802080208020803F80000
+B365:0000000800087E084008403840087E08000800000208020803F8020803F80000
+B366:0000000800087E084008403840087E0800080000210821083F0821143F620000
+B367:0000000800087E084008403840087E0800080000001000100010006801840000
+B368:0000000800087E084008403840087E08000800000048004800A8011406620000
+B369:0000000800087E084008403840087E0800080000000003F00408040803F00000
+B36A:0000000800087E084008403840087E080008000003F80020002000D003080000
+B36B:0000000800087E084008403840087E0800080000004003F8004000A003180000
+B36C:0000000800087E084008403840087E080008000003F8000803F8000800080000
+B36D:0000000800087E084008403840087E080008000003F8020003F8020003F80000
+B36E:0000000800087E084008403840087E080008000000000FF8022002200FF80000
+B36F:0000000800087E084008403840087E080008000000800FF803E0041003E00000
+B370:00000000000A000A7F8A400A400A403A400A400A7F8A000A000A000A000A0000
+B371:0000002800287E28402840E840287E280028000007F800080008000800080000
+B372:0000002800287E28402840E840287E280028000000003EF80208020802080000
+B373:0000002800287E28402840E840287E280028000000003E100210022802C40000
+B374:0000002800287E28402840E840287E280028000008000800080008000FF80000
+B375:0000002800287E28402840E840287E2800280000000020F8201020303ECC0000
+B376:0000002800287E28402840E840287E2800280000202021FC207020883E700000
+B377:0000002800287E28402840E840287E280028000003F802000200020003F80000
+B378:0000002800287E28402840E840287E280028000007F8000807F8040007F80000
+B379:0000002800287E28402840E840287E28002800003EF802083E0820083E080000
+B37A:0000002800287E28402840E840287E28002800003EF802883E8820883EF80000
+B37B:0000002800287E28402840E840287E28002800003E8802883EF820883EF80000
+B37C:0000002800287E28402840E840287E28002800001F0801081F0810141F620000
+B37D:0000002800287E28402840E840287E28002800003EF802803EF820803EF80000
+B37E:0000002800287E28402840E840287E28002800003EFC02483E4820483EFC0000
+B37F:0000002800287E28402840E840287E28002800003E1002FE3E3820443E380000
+B380:0000002800287E28402840E840287E280028000003F802080208020803F80000
+B381:0000002800287E28402840E840287E28002800000208020803F8020803F80000
+B382:0000002800287E28402840E840287E2800280000110811081F0811141F620000
+B383:0000002800287E28402840E840287E2800280000000800080008003400C20000
+B384:0000002800287E28402840E840287E28002800000048004800A8011406620000
+B385:0000002800287E28402840E840287E2800280000000001F00208020801F00000
+B386:0000002800287E28402840E840287E280028000003F80020002000D003080000
+B387:0000002800287E28402840E840287E2800280000004003F8004000A003180000
+B388:0000002800287E28402840E840287E280028000003F8000803F8000800080000
+B389:0000002800287E28402840E840287E280028000003F8020003F8020003F80000
+B38A:0000002800287E28402840E840287E280028000000000FF8022002200FF80000
+B38B:0000002800287E28402840E840287E280028000000800FF803E0041003E00000
+B38C:00000000000200027F824002401E40024002401E7F8200020002000200020000
+B38D:0000000800087E084038400840387E0800080000000007F80008000800080000
+B38E:0000000800087E084038400840387E080008000000003EF80208020802080000
+B38F:0000000800087E084038400840387E080008000000001F080108011401620000
+B390:0000000800087E084038400840387E080008000800001000100010001FF80000
+B391:0000000800087E084038400840387E0800080000000020F8201020303ECC0000
+B392:0000000800087E084038400840387E0800080000202021FC207020883E700000
+B393:0000000800087E084038400840387E080008000003F802000200020003F80000
+B394:0000000800087E084038400840387E080008000007F8000807F8040007F80000
+B395:0000000800087E084038400840387E08000800003EF802083E0820083E080000
+B396:0000000800087E084038400840387E08000800003EF802883E8820883EF80000
+B397:0000000800087E084038400840387E08000800003E8802883EF820883EF80000
+B398:0000000800087E084038400840387E08000800000F8800880F8808140FA20000
+B399:0000000800087E084038400840387E08000800003EF802803EF820803EF80000
+B39A:0000000800087E084038400840387E08000800003EFC02483E4820483EFC0000
+B39B:0000000800087E084038400840387E08000800003E1002FE3E3820443E380000
+B39C:0000000800087E084038400840387E080008000003F802080208020803F80000
+B39D:0000000800087E084038400840387E08000800000208020803F8020803F80000
+B39E:0000000800087E084038400840387E0800080000210821083F0821143F620000
+B39F:0000000800087E084038400840387E0800080000001000100010006801840000
+B3A0:0000000800087E084038400840387E08000800000048004800A8011406620000
+B3A1:0000000800087E084038400840387E0800080000000003F00408040803F00000
+B3A2:0000000800087E084038400840387E080008000003F80020002000D003080000
+B3A3:0000000800087E084038400840387E0800080000004003F8004000A003180000
+B3A4:0000000800087E084038400840387E080008000003F8000803F8000800080000
+B3A5:0000000800087E084038400840387E080008000003F8020003F8020003F80000
+B3A6:0000000800087E084038400840387E080008000000000FF8022002200FF80000
+B3A7:0000000800087E084038400840387E080008000000800FF803E0041003E00000
+B3A8:00000000000A000A7F8A400A403A400A400A403A7F8A000A000A000A000A0000
+B3A9:0000002800287E2840E8402840E87E280028000007F800080008000800080000
+B3AA:0000002800287E2840E8402840E87E280028000000003EF80208020802080000
+B3AB:0000002800287E2840E8402840E87E280028000000003E100210022802C40000
+B3AC:0000002800287E2840E8402840E87E280028002808000800080008000FF80000
+B3AD:0000002800287E2840E8402840E87E2800280000000020F8201020303ECC0000
+B3AE:0000002800287E2840E8402840E87E2800280000202021FC207020883E700000
+B3AF:0000002800287E2840E8402840E87E280028000003F802000200020003F80000
+B3B0:0000002800287E2840E8402840E87E280028000007F8000807F8040007F80000
+B3B1:0000002800287E2840E8402840E87E28002800003EF802083E0820083E080000
+B3B2:0000002800287E2840E8402840E87E28002800003EF802883E8820883EF80000
+B3B3:0000002800287E2840E8402840E87E28002800003E8802883EF820883EF80000
+B3B4:0000002800287E2840E8402840E87E28002800001F0801081F0810141F620000
+B3B5:0000002800287E2840E8402840E87E28002800003EF802803EF820803EF80000
+B3B6:0000002800287E2840E8402840E87E28002800003EFC02483E4820483EFC0000
+B3B7:0000002800287E2840E8402840E87E28002800003E1002FE3E3820443E380000
+B3B8:0000002800287E2840E8402840E87E280028000003F802080208020803F80000
+B3B9:0000002800287E2840E8402840E87E28002800000208020803F8020803F80000
+B3BA:0000002800287E2840E8402840E87E2800280000110811081F0811141F620000
+B3BB:0000002800287E2840E8402840E87E2800280000000800080008003400C20000
+B3BC:0000002800287E2840E8402840E87E28002800000048004800A8011406620000
+B3BD:0000002800287E2840E8402840E87E2800280000000001F00208020801F00000
+B3BE:0000002800287E2840E8402840E87E280028000003F80020002000D003080000
+B3BF:0000002800287E2840E8402840E87E2800280000004003F8004000A003180000
+B3C0:0000002800287E2840E8402840E87E280028000003F8000803F8000800080000
+B3C1:0000002800287E2840E8402840E87E280028000003F8020003F8020003F80000
+B3C2:0000002800287E2840E8402840E87E280028000000000FF8022002200FF80000
+B3C3:0000002800287E2840E8402840E87E280028000000800FF803E0041003E00000
+B3C4:000000003FF820002000200020003FF8000000000100010001007FFC00000000
+B3C5:000000001FF0100010001FF0010001007FFC00001FF000100010001000100000
+B3C6:000000001FF0100010001FF0010001007FFC000000003EF80208020802080000
+B3C7:000000001FF0100010001FF0010001007FFC000000001E100210022802C40000
+B3C8:000000001FF0100010001FF0010001007FFC000000001000100010001FF00000
+B3C9:000000001FF0100010001FF0010001007FFC0000000020F8201020303ECC0000
+B3CA:000000001FF0100010001FF0010001007FFC0000202021FC207020883E700000
+B3CB:000000001FF0100010001FF0010001007FFC00001FF01000100010001FF00000
+B3CC:000000001FF0100010001FF0010001007FFC00001FF000101FF010001FF00000
+B3CD:000000001FF0100010001FF0010001007FFC00003EF802083E0820083E080000
+B3CE:000000001FF0100010001FF0010001007FFC00003EF802883E8820883EF80000
+B3CF:000000001FF0100010001FF0010001007FFC00003E8802883EF820883EF80000
+B3D0:000000001FF0100010001FF0010001007FFC00003E1002103E1020283EC40000
+B3D1:000000001FF0100010001FF0010001007FFC00003EF802803EF820803EF80000
+B3D2:000000001FF0100010001FF0010001007FFC00003EFC02483E4820483EFC0000
+B3D3:000000001FF0100010001FF0010001007FFC00003E2003FC3E7020883E700000
+B3D4:000000001FF0100010001FF0010001007FFC00001FF01010101010101FF00000
+B3D5:000000001FF0100010001FF0010001007FFC0000101010101FF010101FF00000
+B3D6:000000001FF0100010001FF0010001007FFC0000222022203E2022503E880000
+B3D7:000000001FF0100010001FF0010001007FFC000000000100010002800C400000
+B3D8:000000001FF0100010001FF0010001007FFC00000000024002400DA033100000
+B3D9:000000001FF0100010001FF0010001007FFC0000000007C00820082007C00000
+B3DA:000000001FF0100010001FF0010001007FFC0000000007E00080014006200000
+B3DB:000000001FF0100010001FF0010001007FFC0000008007E00080014006200000
+B3DC:000000001FF0100010001FF0010001007FFC00001FF000101FF0001000100000
+B3DD:000000001FF0100010001FF0010001007FFC00001FF010001FF010001FF00000
+B3DE:000000001FF0100010001FF0010001007FFC000000001FF0044004401FF00000
+B3DF:000000001FF0100010001FF0010001007FFC000001001FF007C0082007C00000
+B3E0:0000001000107F904010401040107F9E00100010041004107FD0001000100000
+B3E1:000000083F882008200E3F88040804087FE8000007F800080008000800080000
+B3E2:000000083F882008200E3F88040804087FE8000000003EF80208020802080000
+B3E3:000000083F882008200E3F88040804087FE8000000001F080108011401620000
+B3E4:000000083F882008200E3F88040804087FE8000008000800080008000FF80000
+B3E5:000000083F882008200E3F88040804087FE80000000010F8101010301ECC0000
+B3E6:000000083F882008200E3F88040804087FE800000808087F081C08220F9C0000
+B3E7:000000083F882008200E3F88040804087FE8000003F802000200020003F80000
+B3E8:000000083F882008200E3F88040804087FE8000007F8000807F8040007F80000
+B3E9:000000083F882008200E3F88040804087FE800003EF802083E0820083E080000
+B3EA:000000083F882008200E3F88040804087FE800003EF802883E8820883EF80000
+B3EB:000000083F882008200E3F88040804087FE800003E8802883EF820883EF80000
+B3EC:000000083F882008200E3F88040804087FE800001F0801081F0810141F620000
+B3ED:000000083F882008200E3F88040804087FE800003EF802803EF820803EF80000
+B3EE:000000083F882008200E3F88040804087FE800003EFC02483E4820483EFC0000
+B3EF:000000083F882008200E3F88040804087FE800001F08017F1F1C10221F1C0000
+B3F0:000000083F882008200E3F88040804087FE8000003F802080208020803F80000
+B3F1:000000083F882008200E3F88040804087FE800000208020803F8020803F80000
+B3F2:000000083F882008200E3F88040804087FE80000110811081F0811141F620000
+B3F3:000000083F882008200E3F88040804087FE80000001000100010006801840000
+B3F4:000000083F882008200E3F88040804087FE800000048004800A8011406620000
+B3F5:000000083F882008200E3F88040804087FE80000000003F00408040803F00000
+B3F6:000000083F882008200E3F88040804087FE8000003F80020002000D003080000
+B3F7:000000083F882008200E3F88040804087FE80000004003F8004000A003180000
+B3F8:000000083F882008200E3F88040804087FE8000003F8000803F8000800080000
+B3F9:000000083F882008200E3F88040804087FE8000003F8020003F8020003F80000
+B3FA:000000083F882008200E3F88040804087FE8000000000FF8022002200FF80000
+B3FB:000000083F882008200E3F88040804087FE8000000800FF803E0041003E00000
+B3FC:0000001200127F924012401240127F9E00120012041204127FD2001200120000
+B3FD:000000283FA8202820383FA8042804287FA8000007F800080008000800080000
+B3FE:000000283FA8202820383FA8042804287FA8000000003EF80208020802080000
+B3FF:000000283FA8202820383FA8042804287FA8000000001F080108011401620000
+B400:000000283FA8202820383FA8042804287FA8000008000800080008000FF80000
+B401:000000283FA8202820383FA8042804287FA80000000010F8101010301ECC0000
+B402:000000283FA8202820383FA8042804287FA800000808087F081C08220F9C0000
+B403:000000283FA8202820383FA8042804287FA8000003F802000200020003F80000
+B404:000000283FA8202820383FA8042804287FA8000007F8000807F8040007F80000
+B405:000000283FA8202820383FA8042804287FA800003EF802083E0820083E080000
+B406:000000283FA8202820383FA8042804287FA800003EF802883E8820883EF80000
+B407:000000283FA8202820383FA8042804287FA800003E8802883EF820883EF80000
+B408:000000283FA8202820383FA8042804287FA800001F0801081F0810141F620000
+B409:000000283FA8202820383FA8042804287FA800003EF802803EF820803EF80000
+B40A:000000283FA8202820383FA8042804287FA800003EFC02483E4820483EFC0000
+B40B:000000283FA8202820383FA8042804287FA800001F08017F1F1C10221F1C0000
+B40C:000000283FA8202820383FA8042804287FA8000003F802080208020803F80000
+B40D:000000283FA8202820383FA8042804287FA800000208020803F8020803F80000
+B40E:000000283FA8202820383FA8042804287FA80000110811081F0811141F620000
+B40F:000000283FA8202820383FA8042804287FA80000001000100010006801840000
+B410:000000283FA8202820383FA8042804287FA800000048004800A8011406620000
+B411:000000283FA8202820383FA8042804287FA80000000003F00408040803F00000
+B412:000000283FA8202820383FA8042804287FA8000003F80020002000D003080000
+B413:000000283FA8202820383FA8042804287FA80000004003F8004000A003180000
+B414:000000283FA8202820383FA8042804287FA8000003F8000803F8000800080000
+B415:000000283FA8202820383FA8042804287FA8000003F8020003F8020003F80000
+B416:000000283FA8202820383FA8042804287FA8000000000FF8022002200FF80000
+B417:000000283FA8202820383FA8042804287FA8000000800FF803E0041003E00000
+B418:0000000800087F884008400840087F8800080008040804087FE8000800080000
+B419:000000083F88200820083F88040804087FE8000007F800080008000800080000
+B41A:000000083F88200820083F88040804087FE8000000003EF80208020802080000
+B41B:000000083F88200820083F88040804087FE8000000001F080108011401620000
+B41C:000000083F88200820083F88040804087FE8000008000800080008000FF80000
+B41D:000000083F88200820083F88040804087FE80000000010F8101010301ECC0000
+B41E:000000083F88200820083F88040804087FE800000808087F081C08220F9C0000
+B41F:000000083F88200820083F88040804087FE8000003F802000200020003F80000
+B420:000000083F88200820083F88040804087FE8000007F8000807F8040007F80000
+B421:000000083F88200820083F88040804087FE800003EF802083E0820083E080000
+B422:000000083F88200820083F88040804087FE800003EF802883E8820883EF80000
+B423:000000083F88200820083F88040804087FE800003E8802883EF820883EF80000
+B424:000000083F88200820083F88040804087FE800001F0801081F0810141F620000
+B425:000000083F88200820083F88040804087FE800003EF802803EF820803EF80000
+B426:000000083F88200820083F88040804087FE800003EFC02483E4820483EFC0000
+B427:000000083F88200820083F88040804087FE800001F08017F1F1C10221F1C0000
+B428:000000083F88200820083F88040804087FE8000003F802080208020803F80000
+B429:000000083F88200820083F88040804087FE800000208020803F8020803F80000
+B42A:000000083F88200820083F88040804087FE80000110811081F0811141F620000
+B42B:000000083F88200820083F88040804087FE80000001000100010006801840000
+B42C:000000083F88200820083F88040804087FE800000048004800A8011406620000
+B42D:000000083F88200820083F88040804087FE80000000003F00408040803F00000
+B42E:000000083F88200820083F88040804087FE8000003F80020002000D003080000
+B42F:000000083F88200820083F88040804087FE80000004003F8004000A003180000
+B430:000000083F88200820083F88040804087FE8000003F8000803F8000800080000
+B431:000000083F88200820083F88040804087FE8000003F8020003F8020003F80000
+B432:000000083F88200820083F88040804087FE8000000000FF8022002200FF80000
+B433:000000083F88200820083F88040804087FE8000000800FF803E0041003E00000
+B434:000000003FF820002000200020003FF8000004400440044004407FFC00000000
+B435:000000001FF0100010001FF0044004407FFC00001FF000100010001000100000
+B436:000000001FF0100010001FF0044004407FFC000000003EF80208020802080000
+B437:000000001FF0100010001FF0044004407FFC000000001E100210022802C40000
+B438:000000001FF0100010001FF0044004407FFC000000001000100010001FF00000
+B439:000000001FF0100010001FF0044004407FFC0000000020F8201020303ECC0000
+B43A:000000001FF0100010001FF0044004407FFC0000202021FC207020883E700000
+B43B:000000001FF0100010001FF0044004407FFC00001FF01000100010001FF00000
+B43C:000000001FF0100010001FF0044004407FFC00001FF000101FF010001FF00000
+B43D:000000001FF0100010001FF0044004407FFC00003EF802083E0820083E080000
+B43E:000000001FF0100010001FF0044004407FFC00003EF802883E8820883EF80000
+B43F:000000001FF0100010001FF0044004407FFC00003E8802883EF820883EF80000
+B440:000000001FF0100010001FF0044004407FFC00003E1002103E1020283EC40000
+B441:000000001FF0100010001FF0044004407FFC00003EF802803EF820803EF80000
+B442:000000001FF0100010001FF0044004407FFC00003EFC02483E4820483EFC0000
+B443:000000001FF0100010001FF0044004407FFC00003E2003FC3E7020883E700000
+B444:000000001FF0100010001FF0044004407FFC00001FF01010101010101FF00000
+B445:000000001FF0100010001FF0044004407FFC0000101010101FF010101FF00000
+B446:000000001FF0100010001FF0044004407FFC0000222022203E2022503E880000
+B447:000000001FF0100010001FF0044004407FFC000000000100010002800C400000
+B448:000000001FF0100010001FF0044004407FFC00000000024002400DA033100000
+B449:000000001FF0100010001FF0044004407FFC0000000007C00820082007C00000
+B44A:000000001FF0100010001FF0044004407FFC0000000007E00080014006200000
+B44B:000000001FF0100010001FF0044004407FFC0000008007E00080014006200000
+B44C:000000001FF0100010001FF0044004407FFC00001FF000101FF0001000100000
+B44D:000000001FF0100010001FF0044004407FFC00001FF010001FF010001FF00000
+B44E:000000001FF0100010001FF0044004407FFC000000001FF0044004401FF00000
+B44F:000000001FF0100010001FF0044004407FFC000001001FF007C0082007C00000
+B450:000000003FF820002000200020003FF8000000003FF801000100010001000000
+B451:000000001FF0100010001FF000007FFC010001001FF000100010001000100000
+B452:000000001FF0100010001FF000007FFC0100010000003EF80208020802080000
+B453:000000001FF0100010001FF000007FFC0100010000001E100210022802C40000
+B454:000000001FF0100010001FF0000000007FFC010001001100100010001FF00000
+B455:000000001FF0100010001FF000007FFC01000100000020F8201020303ECC0000
+B456:000000001FF0100010001FF000007FFC01000100202021FC207020883E700000
+B457:000000001FF0100010001FF000007FFC010001001FF01000100010001FF00000
+B458:000000001FF0100010001FF000007FFC010001001FF000101FF010001FF00000
+B459:000000001FF0100010001FF000007FFC010001003EF802083E0820083E080000
+B45A:000000001FF0100010001FF000007FFC010001003EF802883E8820883EF80000
+B45B:000000001FF0100010001FF000007FFC010001003E8802883EF820883EF80000
+B45C:000000001FF0100010001FF000007FFC010001003E1002103E1020283EC40000
+B45D:000000001FF0100010001FF000007FFC010001003EF802803EF820803EF80000
+B45E:000000001FF0100010001FF000007FFC010001003EFC02483E4820483EFC0000
+B45F:000000001FF0100010001FF000007FFC010001003E2003FC3E7020883E700000
+B460:000000001FF0100010001FF000007FFC010001001FF01010101010101FF00000
+B461:000000001FF0100010001FF000007FFC01000100101010101FF010101FF00000
+B462:000000001FF0100010001FF000007FFC01000100222022203E2022503E880000
+B463:000000001FF0100010001FF000007FFC0100010000000100010002800C400000
+B464:000000001FF0100010001FF000007FFC010001000000024002400DA033100000
+B465:000000001FF0100010001FF000007FFC01000100000007C00820082007C00000
+B466:000000001FF0100010001FF000007FFC01000100000007E00080014006200000
+B467:000000001FF0100010001FF000007FFC01000100008007E00080014006200000
+B468:000000001FF0100010001FF000007FFC010001001FF000101FF0001000100000
+B469:000000001FF0100010001FF000007FFC010001001FF010001FF010001FF00000
+B46A:000000001FF0100010001FF000007FFC0100010000001FF0044004401FF00000
+B46B:000000001FF0100010001FF000007FFC0100010001001FF007C0082007C00000
+B46C:0000000800087FC84008400840087FC8000800087FE8040804F8040804080000
+B46D:00083F88200820083F8800087FE8027802080000000007F80008000800080000
+B46E:00083F88200820083F8800087FE802780208000000003EF80208020802080000
+B46F:00083F88200820083F8800087FE802780208000000001F080108011401620000
+B470:00083F88200820083F88000800087FE80278020802081000100010001FF80000
+B471:00083F88200820083F8800087FE8027802080000000020F8201020303ECC0000
+B472:00083F88200820083F8800087FE8027802080000202021FC207020883E700000
+B473:00083F88200820083F8800087FE802780208000003F802000200020003F80000
+B474:00083F88200820083F8800087FE802780208000007F8000807F8040007F80000
+B475:00083F88200820083F8800087FE80278020800003EF802083E0820083E080000
+B476:00083F88200820083F8800087FE80278020800003EF802883E8820883EF80000
+B477:00083F88200820083F8800087FE80278020800003E8802883EF820883EF80000
+B478:00083F88200820083F8800087FE80278020800000F8800880F8808140FA20000
+B479:00083F88200820083F8800087FE80278020800003EF802803EF820803EF80000
+B47A:00083F88200820083F8800087FE80278020800003EFC02483E4820483EFC0000
+B47B:00083F88200820083F8800087FE80278020800003E1002FE3E3820443E380000
+B47C:00083F88200820083F8800087FE802780208000003F802080208020803F80000
+B47D:00083F88200820083F8800087FE80278020800000208020803F8020803F80000
+B47E:00083F88200820083F8800087FE8027802080000210821083F0821143F620000
+B47F:00083F88200820083F8800087FE8027802080000001000100010006801840000
+B480:00083F88200820083F8800087FE80278020800000048004800A8011406620000
+B481:00083F88200820083F8800087FE8027802080000000003F00408040803F00000
+B482:00083F88200820083F8800087FE802780208000003F80020002000D003080000
+B483:00083F88200820083F8800087FE8027802080000004003F8004000A003180000
+B484:00083F88200820083F8800087FE802780208000003F8000803F8000800080000
+B485:00083F88200820083F8800087FE802780208000003F8020003F8020003F80000
+B486:00083F88200820083F8800087FE802780208000000000FF8022002200FF80000
+B487:00083F88200820083F8800087FE802780208000000800FF803E0041003E00000
+B488:0000000A000A7FCA400A400A400A7FCA000A000A7FEA040A047A040A040A0000
+B489:00283FA8202820283FA800287FA805E804280000000007F80008000800080000
+B48A:00283FA8202820283FA800287FA805E80428000000003EF80208020802080000
+B48B:00283FA8202820283FA800287FA805E80428000000001F080108011401620000
+B48C:00283FA8202820283FA8002800287FA8042805E804281428100010001FF80000
+B48D:00283FA8202820283FA800287FA805E804280000000020F8201020303ECC0000
+B48E:00283FA8202820283FA800287FA805E804280000202021FC207020883E700000
+B48F:00283FA8202820283FA800287FA805E80428000003F802000200020003F80000
+B490:00283FA8202820283FA800287FA805E80428000007F8000807F8040007F80000
+B491:00283FA8202820283FA800287FA805E8042800003EF802083E0820083E080000
+B492:00283FA8202820283FA800287FA805E8042800003EF802883E8820883EF80000
+B493:00283FA8202820283FA800287FA805E8042800003E8802883EF820883EF80000
+B494:00283FA8202820283FA800287FA805E8042800000F8800880F8808140FA20000
+B495:00283FA8202820283FA800287FA805E8042800003EF802803EF820803EF80000
+B496:00283FA8202820283FA800287FA805E8042800003EFC02483E4820483EFC0000
+B497:00283FA8202820283FA800287FA805E8042800003E1002FE3E3820443E380000
+B498:00283FA8202820283FA800287FA805E80428000003F802080208020803F80000
+B499:00283FA8202820283FA800287FA805E8042800000208020803F8020803F80000
+B49A:00283FA8202820283FA800287FA805E804280000210821083F0821143F620000
+B49B:00283FA8202820283FA800287FA805E804280000001000100010006801840000
+B49C:00283FA8202820283FA800287FA805E8042800000048004800A8011406620000
+B49D:00283FA8202820283FA800287FA805E804280000000003F00408040803F00000
+B49E:00283FA8202820283FA800287FA805E80428000003F80020002000D003080000
+B49F:00283FA8202820283FA800287FA805E804280000004003F8004000A003180000
+B4A0:00283FA8202820283FA800287FA805E80428000003F8000803F8000800080000
+B4A1:00283FA8202820283FA800287FA805E80428000003F8020003F8020003F80000
+B4A2:00283FA8202820283FA800287FA805E80428000000000FF8022002200FF80000
+B4A3:00283FA8202820283FA800287FA805E80428000000800FF803E0041003E00000
+B4A4:0000000800087FC84008400840087FC8000800087FE804080408040804080000
+B4A5:00083F88200820083F8800087FE8020802000000000007F80008000800080000
+B4A6:00083F88200820083F8800087FE802080200000000003EF80208020802080000
+B4A7:00083F88200820083F8800087FE802080200000000001F080108011401620000
+B4A8:00083F88200820083F88000800087FE80208020802081008100010001FF80000
+B4A9:00083F88200820083F8800087FE8020802000000000020F8201020303ECC0000
+B4AA:00083F88200820083F8800087FE8020802000000202021FC207020883E700000
+B4AB:00083F88200820083F8800087FE802080200000003F802000200020003F80000
+B4AC:00083F88200820083F8800087FE802080200000007F8000807F8040007F80000
+B4AD:00083F88200820083F8800087FE80208020000003EF802083E0820083E080000
+B4AE:00083F88200820083F8800087FE80208020000003EF802883E8820883EF80000
+B4AF:00083F88200820083F8800087FE80208020000003E8802883EF820883EF80000
+B4B0:00083F88200820083F8800087FE80208020000000F8800880F8808140FA20000
+B4B1:00083F88200820083F8800087FE80208020000003EF802803EF820803EF80000
+B4B2:00083F88200820083F8800087FE80208020000003EFC02483E4820483EFC0000
+B4B3:00083F88200820083F8800087FE80208020000003E1002FE3E3820443E380000
+B4B4:00083F88200820083F8800087FE802080200000003F802080208020803F80000
+B4B5:00083F88200820083F8800087FE80208020000000208020803F8020803F80000
+B4B6:00083F88200820083F8800087FE8020802000000210821083F0821143F620000
+B4B7:00083F88200820083F8800087FE8020802000000001000100010006801840000
+B4B8:00083F88200820083F8800087FE80208020000000048004800A8011406620000
+B4B9:00083F88200820083F8800087FE8020802000000000003F00408040803F00000
+B4BA:00083F88200820083F8800087FE802080200000003F80020002000D003080000
+B4BB:00083F88200820083F8800087FE8020802000000004003F8004000A003180000
+B4BC:00083F88200820083F8800087FE802080200000003F8000803F8000800080000
+B4BD:00083F88200820083F8800087FE802080200000003F8020003F8020003F80000
+B4BE:00083F88200820083F8800087FE802080200000000000FF8022002200FF80000
+B4BF:00083F88200820083F8800087FE802080200000000800FF803E0041003E00000
+B4C0:000000003FF820002000200020003FF8000000007FFC04400440044004400000
+B4C1:000000001FF0100010001FF000007FFC044004401FF000100010001000100000
+B4C2:000000001FF0100010001FF000007FFC0440044000003EF80208020802080000
+B4C3:000000001FF0100010001FF000007FFC0440044000001E100210022802C40000
+B4C4:000000001FF0100010001FF0000000007FFC044004401440100010001FF00000
+B4C5:000000001FF0100010001FF000007FFC04400440000020F8201020303ECC0000
+B4C6:000000001FF0100010001FF000007FFC04400440202021FC207020883E700000
+B4C7:000000001FF0100010001FF000007FFC044004401FF01000100010001FF00000
+B4C8:000000001FF0100010001FF000007FFC044004401FF000101FF010001FF00000
+B4C9:000000001FF0100010001FF000007FFC044004403EF802083E0820083E080000
+B4CA:000000001FF0100010001FF000007FFC044004403EF802883E8820883EF80000
+B4CB:000000001FF0100010001FF000007FFC044004403E8802883EF820883EF80000
+B4CC:000000001FF0100010001FF000007FFC044004403E1002103E1020283EC40000
+B4CD:000000001FF0100010001FF000007FFC044004403EF802803EF820803EF80000
+B4CE:000000001FF0100010001FF000007FFC044004403EFC02483E4820483EFC0000
+B4CF:000000001FF0100010001FF000007FFC044004403E2003FC3E7020883E700000
+B4D0:000000001FF0100010001FF000007FFC044004401FF01010101010101FF00000
+B4D1:000000001FF0100010001FF000007FFC04400440101010101FF010101FF00000
+B4D2:000000001FF0100010001FF000007FFC04400440222022203E2022503E880000
+B4D3:000000001FF0100010001FF000007FFC0440044000000100010002800C400000
+B4D4:000000001FF0100010001FF000007FFC044004400000024002400DA033100000
+B4D5:000000001FF0100010001FF000007FFC04400440000007C00820082007C00000
+B4D6:000000001FF0100010001FF000007FFC04400440000007E00080014006200000
+B4D7:000000001FF0100010001FF000007FFC04400440008007E00080014006200000
+B4D8:000000001FF0100010001FF000007FFC044004401FF000101FF0001000100000
+B4D9:000000001FF0100010001FF000007FFC044004401FF010001FF010001FF00000
+B4DA:000000001FF0100010001FF000007FFC0440044000001FF0044004401FF00000
+B4DB:000000001FF0100010001FF000007FFC0440044001001FF007C0082007C00000
+B4DC:000000003FF820002000200020003FF80000000000007FFC0000000000000000
+B4DD:000000001FF0100010001FF0000000007FFC00001FF000100010001000100000
+B4DE:000000001FF0100010001FF0000000007FFC000000003EF80208020802080000
+B4DF:000000001FF0100010001FF0000000007FFC000000001E100210022802C40000
+B4E0:000000001FF0100010001FF0000000007FFC000000001000100010001FF00000
+B4E1:000000001FF0100010001FF0000000007FFC0000000020F8201020303ECC0000
+B4E2:000000001FF0100010001FF0000000007FFC0000202021FC207020883E700000
+B4E3:000000001FF0100010001FF0000000007FFC00001FF01000100010001FF00000
+B4E4:000000001FF0100010001FF0000000007FFC00001FF000101FF010001FF00000
+B4E5:000000001FF0100010001FF0000000007FFC00003EF802083E0820083E080000
+B4E6:000000001FF0100010001FF0000000007FFC00003EF802883E8820883EF80000
+B4E7:000000001FF0100010001FF0000000007FFC00003E8802883EF820883EF80000
+B4E8:000000001FF0100010001FF0000000007FFC00003E1002103E1020283EC40000
+B4E9:000000001FF0100010001FF0000000007FFC00003EF802803EF820803EF80000
+B4EA:000000001FF0100010001FF0000000007FFC00003EFC02483E4820483EFC0000
+B4EB:000000001FF0100010001FF0000000007FFC00003E2003FC3E7020883E700000
+B4EC:000000001FF0100010001FF0000000007FFC00001FF01010101010101FF00000
+B4ED:000000001FF0100010001FF0000000007FFC0000101010101FF010101FF00000
+B4EE:000000001FF0100010001FF0000000007FFC0000222022203E2022503E880000
+B4EF:000000001FF0100010001FF0000000007FFC000000000100010002800C400000
+B4F0:000000001FF0100010001FF0000000007FFC00000000024002400DA033100000
+B4F1:000000001FF0100010001FF0000000007FFC0000000007C00820082007C00000
+B4F2:000000001FF0100010001FF0000000007FFC0000000007E00080014006200000
+B4F3:000000001FF0100010001FF0000000007FFC0000008007E00080014006200000
+B4F4:000000001FF0100010001FF0000000007FFC00001FF000101FF0001000100000
+B4F5:000000001FF0100010001FF0000000007FFC00001FF010001FF010001FF00000
+B4F6:000000001FF0100010001FF0000000007FFC000000001FF0044004401FF00000
+B4F7:000000001FF0100010001FF0000000007FFC000001001FF007C0082007C00000
+B4F8:0000000800087F884008400840087F880008000800087FE80008000800080000
+B4F9:000000083F88200820083F88000800087FE8000007F800080008000800080000
+B4FA:000000083F88200820083F88000800087FE8000000003EF80208020802080000
+B4FB:000000083F88200820083F88000800087FE8000000001F080108011401620000
+B4FC:000000083F88200820083F88000800087FE8000008000800080008000FF80000
+B4FD:000000083F88200820083F88000800087FE80000000010F8101010301ECC0000
+B4FE:000000083F88200820083F88000800087FE800000808087F081C08220F9C0000
+B4FF:000000083F88200820083F88000800087FE8000003F802000200020003F80000
+B500:000000083F88200820083F88000800087FE8000007F8000807F8040007F80000
+B501:000000083F88200820083F88000800087FE800003EF802083E0820083E080000
+B502:000000083F88200820083F88000800087FE800003EF802883E8820883EF80000
+B503:000000083F88200820083F88000800087FE800003E8802883EF820883EF80000
+B504:000000083F88200820083F88000800087FE800001F0801081F0810141F620000
+B505:000000083F88200820083F88000800087FE800003EF802803EF820803EF80000
+B506:000000083F88200820083F88000800087FE800003EFC02483E4820483EFC0000
+B507:000000083F88200820083F88000800087FE800001F08017F1F1C10221F1C0000
+B508:000000083F88200820083F88000800087FE8000003F802080208020803F80000
+B509:000000083F88200820083F88000800087FE800000208020803F8020803F80000
+B50A:000000083F88200820083F88000800087FE80000110811081F0811141F620000
+B50B:000000083F88200820083F88000800087FE80000001000100010006801840000
+B50C:000000083F88200820083F88000800087FE800000048004800A8011406620000
+B50D:000000083F88200820083F88000800087FE80000000003F00408040803F00000
+B50E:000000083F88200820083F88000800087FE8000003F80020002000D003080000
+B50F:000000083F88200820083F88000800087FE80000004003F8004000A003180000
+B510:000000083F88200820083F88000800087FE8000003F8000803F8000800080000
+B511:000000083F88200820083F88000800087FE8000003F8020003F8020003F80000
+B512:000000083F88200820083F88000800087FE8000000000FF8022002200FF80000
+B513:000000083F88200820083F88000800087FE8000000800FF803E0041003E00000
+B514:00000000000800087F88400840084008400840087F8800080008000800080000
+B515:0000000800087E084008400840087E0800080000000007F80008000800080000
+B516:0000000800087E084008400840087E080008000000003EF80208020802080000
+B517:0000000800087E084008400840087E080008000000001F080108011401620000
+B518:0000000800087E084008400840087E080008000800001000100010001FF80000
+B519:0000000800087E084008400840087E0800080000000020F8201020303ECC0000
+B51A:0000000800087E084008400840087E0800080000202021FC207020883E700000
+B51B:0000000800087E084008400840087E080008000003F802000200020003F80000
+B51C:0000000800087E084008400840087E080008000007F8000807F8040007F80000
+B51D:0000000800087E084008400840087E08000800003EF802083E0820083E080000
+B51E:0000000800087E084008400840087E08000800003EF802883E8820883EF80000
+B51F:0000000800087E084008400840087E08000800003E8802883EF820883EF80000
+B520:0000000800087E084008400840087E08000800000F8800880F8808140FA20000
+B521:0000000800087E084008400840087E08000800003EF802803EF820803EF80000
+B522:0000000800087E084008400840087E08000800003EFC02483E4820483EFC0000
+B523:0000000800087E084008400840087E08000800003E1002FE3E3820443E380000
+B524:0000000800087E084008400840087E080008000003F802080208020803F80000
+B525:0000000800087E084008400840087E08000800000208020803F8020803F80000
+B526:0000000800087E084008400840087E0800080000210821083F0821143F620000
+B527:0000000800087E084008400840087E0800080000001000100010006801840000
+B528:0000000800087E084008400840087E08000800000048004800A8011406620000
+B529:0000000800087E084008400840087E0800080000000003F00408040803F00000
+B52A:0000000800087E084008400840087E080008000003F80020002000D003080000
+B52B:0000000800087E084008400840087E0800080000004003F8004000A003180000
+B52C:0000000800087E084008400840087E080008000003F8000803F8000800080000
+B52D:0000000800087E084008400840087E080008000003F8020003F8020003F80000
+B52E:0000000800087E084008400840087E080008000000000FF8022002200FF80000
+B52F:0000000800087E084008400840087E080008000000800FF803E0041003E00000
+B530:00000000001000107BD042104210421E421042107BD000100010001000100000
+B531:00000008000877084408440E440877080008000007F800080008000800080000
+B532:00000008000877084408440E440877080008000000003EF80208020802080000
+B533:00000008000877084408440E440877080008000000001F080108011401620000
+B534:00000008000877084408440E440877080008000808000800080008000FF80000
+B535:00000008000877084408440E4408770800080000000010F8101010301ECC0000
+B536:00000008000877084408440E44087708000800000808087F081C08220F9C0000
+B537:00000008000877084408440E440877080008000003F802000200020003F80000
+B538:00000008000877084408440E440877080008000007F8000807F8040007F80000
+B539:00000008000877084408440E44087708000800003EF802083E0820083E080000
+B53A:00000008000877084408440E44087708000800003EF802883E8820883EF80000
+B53B:00000008000877084408440E44087708000800003E8802883EF820883EF80000
+B53C:00000008000877084408440E44087708000800001F0801081F0810141F620000
+B53D:00000008000877084408440E44087708000800003EF802803EF820803EF80000
+B53E:00000008000877084408440E44087708000800003EFC02483E4820483EFC0000
+B53F:00000008000877084408440E44087708000800001F08017F1F1C10221F1C0000
+B540:00000008000877084408440E440877080008000003F802080208020803F80000
+B541:00000008000877084408440E44087708000800000208020803F8020803F80000
+B542:00000008000877084408440E4408770800080000110811081F0811141F620000
+B543:00000008000877084408440E4408770800080000001000100010006801840000
+B544:00000008000877084408440E44087708000800000048004800A8011406620000
+B545:00000008000877084408440E4408770800080000000003F00408040803F00000
+B546:00000008000877084408440E440877080008000003F80020002000D003080000
+B547:00000008000877084408440E4408770800080000004003F8004000A003180000
+B548:00000008000877084408440E440877080008000003F8000803F8000800080000
+B549:00000008000877084408440E440877080008000003F8020003F8020003F80000
+B54A:00000008000877084408440E440877080008000000000FF8022002200FF80000
+B54B:00000008000877084408440E440877080008000000800FF803E0041003E00000
+B54C:00000000001200127BD242124212421E421242127BD200120012001200120000
+B54D:000000280028772844284438442877280028000007F800080008000800080000
+B54E:000000280028772844284438442877280028000000003EF80208020802080000
+B54F:000000280028772844284438442877280028000000003E100210022802C40000
+B550:000000280028772844284438442877280028002808000800080008000FF80000
+B551:0000002800287728442844384428772800280000000020F8201020303ECC0000
+B552:0000002800287728442844384428772800280000202021FC207020883E700000
+B553:000000280028772844284438442877280028000003F802000200020003F80000
+B554:000000280028772844284438442877280028000007F8000807F8040007F80000
+B555:00000028002877284428443844287728002800003EF802083E0820083E080000
+B556:00000028002877284428443844287728002800003EF802883E8820883EF80000
+B557:00000028002877284428443844287728002800003E8802883EF820883EF80000
+B558:00000028002877284428443844287728002800001F0801081F0810141F620000
+B559:00000028002877284428443844287728002800003EF802803EF820803EF80000
+B55A:00000028002877284428443844287728002800003EFC02483E4820483EFC0000
+B55B:00000028002877284428443844287728002800003E1002FE3E3820443E380000
+B55C:000000280028772844284438442877280028000003F802080208020803F80000
+B55D:00000028002877284428443844287728002800000208020803F8020803F80000
+B55E:0000002800287728442844384428772800280000110811081F0811141F620000
+B55F:0000002800287728442844384428772800280000000800080008003400C20000
+B560:00000028002877284428443844287728002800000048004800A8011406620000
+B561:0000002800287728442844384428772800280000000001F00208020801F00000
+B562:000000280028772844284438442877280028000003F80020002000D003080000
+B563:0000002800287728442844384428772800280000004003F8004000A003180000
+B564:000000280028772844284438442877280028000003F8000803F8000800080000
+B565:000000280028772844284438442877280028000003F8020003F8020003F80000
+B566:000000280028772844284438442877280028000000000FF8022002200FF80000
+B567:000000280028772844284438442877280028000000800FF803E0041003E00000
+B568:00000000001000107BD04210421E42104210421E7BD000100010001000100000
+B569:0000000800087708440E4408440E77080008000007F800080008000800080000
+B56A:0000000800087708440E4408440E77080008000000003EF80208020802080000
+B56B:0000000800087708440E4408440E77080008000000001F080108011401620000
+B56C:0000000800087708440E4408440E77080008000008000800080008000FF80000
+B56D:0000000800087708440E4408440E770800080000000010F8101010301ECC0000
+B56E:0000000800087708440E4408440E7708000800000808087F081C08220F9C0000
+B56F:0000000800087708440E4408440E77080008000003F802000200020003F80000
+B570:0000000800087708440E4408440E77080008000007F8000807F8040007F80000
+B571:0000000800087708440E4408440E7708000800003EF802083E0820083E080000
+B572:0000000800087708440E4408440E7708000800003EF802883E8820883EF80000
+B573:0000000800087708440E4408440E7708000800003E8802883EF820883EF80000
+B574:0000000800087708440E4408440E7708000800001F0801081F0810141F620000
+B575:0000000800087708440E4408440E7708000800003EF802803EF820803EF80000
+B576:0000000800087708440E4408440E7708000800003EFC02483E4820483EFC0000
+B577:0000000800087708440E4408440E7708000800001F08017F1F1C10221F1C0000
+B578:0000000800087708440E4408440E77080008000003F802080208020803F80000
+B579:0000000800087708440E4408440E7708000800000208020803F8020803F80000
+B57A:0000000800087708440E4408440E770800080000110811081F0811141F620000
+B57B:0000000800087708440E4408440E770800080000001000100010006801840000
+B57C:0000000800087708440E4408440E7708000800000048004800A8011406620000
+B57D:0000000800087708440E4408440E770800080000000003F00408040803F00000
+B57E:0000000800087708440E4408440E77080008000003F80020002000D003080000
+B57F:0000000800087708440E4408440E770800080000004003F8004000A003180000
+B580:0000000800087708440E4408440E77080008000003F8000803F8000800080000
+B581:0000000800087708440E4408440E77080008000003F8020003F8020003F80000
+B582:0000000800087708440E4408440E77080008000000000FF8022002200FF80000
+B583:0000000800087708440E4408440E77080008000000800FF803E0041003E00000
+B584:00000000001200127BD24212421E42124212421E7BD200120012001200120000
+B585:000000280028772844384428443877280028000007F800080008000800080000
+B586:000000280028772844384428443877280028000000003EF80208020802080000
+B587:000000280028772844384428443877280028000000003E100210022802C40000
+B588:000000280028772844384428443877280028002808000800080008000FF80000
+B589:0000002800287728443844284438772800280000000020F8201020303ECC0000
+B58A:0000002800287728443844284438772800280000202021FC207020883E700000
+B58B:000000280028772844384428443877280028000003F802000200020003F80000
+B58C:000000280028772844384428443877280028000007F8000807F8040007F80000
+B58D:00000028002877284438442844387728002800003EF802083E0820083E080000
+B58E:00000028002877284438442844387728002800003EF802883E8820883EF80000
+B58F:00000028002877284438442844387728002800003E8802883EF820883EF80000
+B590:00000028002877284438442844387728002800001F0801081F0810141F620000
+B591:00000028002877284438442844387728002800003EF802803EF820803EF80000
+B592:00000028002877284438442844387728002800003EFC02483E4820483EFC0000
+B593:00000028002877284438442844387728002800003E1002FE3E3820443E380000
+B594:000000280028772844384428443877280028000003F802080208020803F80000
+B595:00000028002877284438442844387728002800000208020803F8020803F80000
+B596:0000002800287728443844284438772800280000110811081F0811141F620000
+B597:0000002800287728443844284438772800280000000800080008003400C20000
+B598:00000028002877284438442844387728002800000048004800A8011406620000
+B599:0000002800287728443844284438772800280000000001F00208020801F00000
+B59A:000000280028772844384428443877280028000003F80020002000D003080000
+B59B:0000002800287728443844284438772800280000004003F8004000A003180000
+B59C:000000280028772844384428443877280028000003F8000803F8000800080000
+B59D:000000280028772844384428443877280028000003F8020003F8020003F80000
+B59E:000000280028772844384428443877280028000000000FF8022002200FF80000
+B59F:000000280028772844384428443877280028000000800FF803E0041003E00000
+B5A0:00000000000200027BC242024202421E420242027BC200020002000200020000
+B5A1:0000000800087708440844384408770800080000000007F80008000800080000
+B5A2:000000080008770844084438440877080008000000003EF80208020802080000
+B5A3:000000080008770844084438440877080008000000001F080108011401620000
+B5A4:000000080008770844084438440877080008000000001000100010001FF80000
+B5A5:0000000800087708440844384408770800080000000020F8201020303ECC0000
+B5A6:0000000800087708440844384408770800080000202021FC207020883E700000
+B5A7:000000080008770844084438440877080008000003F802000200020003F80000
+B5A8:000000080008770844084438440877080008000007F8000807F8040007F80000
+B5A9:00000008000877084408443844087708000800003EF802083E0820083E080000
+B5AA:00000008000877084408443844087708000800003EF802883E8820883EF80000
+B5AB:00000008000877084408443844087708000800003E8802883EF820883EF80000
+B5AC:00000008000877084408443844087708000800000F8800880F8808140FA20000
+B5AD:00000008000877084408443844087708000800003EF802803EF820803EF80000
+B5AE:00000008000877084408443844087708000800003EFC02483E4820483EFC0000
+B5AF:00000008000877084408443844087708000800003E1002FE3E3820443E380000
+B5B0:000000080008770844084438440877080008000003F802080208020803F80000
+B5B1:00000008000877084408443844087708000800000208020803F8020803F80000
+B5B2:0000000800087708440844384408770800080000210821083F0821143F620000
+B5B3:0000000800087708440844384408770800080000001000100010006801840000
+B5B4:00000008000877084408443844087708000800000048004800A8011406620000
+B5B5:0000000800087708440844384408770800080000000003F00408040803F00000
+B5B6:000000080008770844084438440877080008000003F80020002000D003080000
+B5B7:0000000800087708440844384408770800080000004003F8004000A003180000
+B5B8:000000080008770844084438440877080008000003F8000803F8000800080000
+B5B9:000000080008770844084438440877080008000003F8020003F8020003F80000
+B5BA:000000080008770844084438440877080008000000000FF8022002200FF80000
+B5BB:000000080008770844084438440877080008000000800FF803E0041003E00000
+B5BC:00000000000A000A7BCA420A420A423A420A420A7BCA000A000A000A000A0000
+B5BD:0000002800287728442844E8442877280028000007F800080008000800080000
+B5BE:0000002800287728442844E8442877280028000000003EF80208020802080000
+B5BF:0000002800287728442844E8442877280028000000003E100210022802C40000
+B5C0:0000002800287728442844E8442877280028000008000800080008000FF80000
+B5C1:0000002800287728442844E84428772800280000000020F8201020303ECC0000
+B5C2:0000002800287728442844E84428772800280000202021FC207020883E700000
+B5C3:0000002800287728442844E8442877280028000003F802000200020003F80000
+B5C4:0000002800287728442844E8442877280028000007F8000807F8040007F80000
+B5C5:0000002800287728442844E844287728002800003EF802083E0820083E080000
+B5C6:0000002800287728442844E844287728002800003EF802883E8820883EF80000
+B5C7:0000002800287728442844E844287728002800003E8802883EF820883EF80000
+B5C8:0000002800287728442844E844287728002800001F0801081F0810141F620000
+B5C9:0000002800287728442844E844287728002800003EF802803EF820803EF80000
+B5CA:0000002800287728442844E844287728002800003EFC02483E4820483EFC0000
+B5CB:0000002800287728442844E844287728002800003E1002FE3E3820443E380000
+B5CC:0000002800287728442844E8442877280028000003F802080208020803F80000
+B5CD:0000002800287728442844E844287728002800000208020803F8020803F80000
+B5CE:0000002800287728442844E84428772800280000110811081F0811141F620000
+B5CF:0000002800287728442844E84428772800280000000800080008003400C20000
+B5D0:0000002800287728442844E844287728002800000048004800A8011406620000
+B5D1:0000002800287728442844E84428772800280000000001F00208020801F00000
+B5D2:0000002800287728442844E8442877280028000003F80020002000D003080000
+B5D3:0000002800287728442844E84428772800280000004003F8004000A003180000
+B5D4:0000002800287728442844E8442877280028000003F8000803F8000800080000
+B5D5:0000002800287728442844E8442877280028000003F8020003F8020003F80000
+B5D6:0000002800287728442844E8442877280028000000000FF8022002200FF80000
+B5D7:0000002800287728442844E8442877280028000000800FF803E0041003E00000
+B5D8:00000000000200027BC24202421E42024202421E7BC200020002000200020000
+B5D9:0000000800087708443844084438770800080000000007F80008000800080000
+B5DA:000000080008770844384408443877080008000000003EF80208020802080000
+B5DB:000000080008770844384408443877080008000000001F080108011401620000
+B5DC:000000080008770844384408443877080008000800001000100010001FF80000
+B5DD:0000000800087708443844084438770800080000000020F8201020303ECC0000
+B5DE:0000000800087708443844084438770800080000202021FC207020883E700000
+B5DF:000000080008770844384408443877080008000003F802000200020003F80000
+B5E0:000000080008770844384408443877080008000007F8000807F8040007F80000
+B5E1:00000008000877084438440844387708000800003EF802083E0820083E080000
+B5E2:00000008000877084438440844387708000800003EF802883E8820883EF80000
+B5E3:00000008000877084438440844387708000800003E8802883EF820883EF80000
+B5E4:00000008000877084438440844387708000800000F8800880F8808140FA20000
+B5E5:00000008000877084438440844387708000800003EF802803EF820803EF80000
+B5E6:00000008000877084438440844387708000800003EFC02483E4820483EFC0000
+B5E7:00000008000877084438440844387708000800003E1002FE3E3820443E380000
+B5E8:000000080008770844384408443877080008000003F802080208020803F80000
+B5E9:00000008000877084438440844387708000800000208020803F8020803F80000
+B5EA:0000000800087708443844084438770800080000210821083F0821143F620000
+B5EB:0000000800087708443844084438770800080000001000100010006801840000
+B5EC:00000008000877084438440844387708000800000048004800A8011406620000
+B5ED:0000000800087708443844084438770800080000000003F00408040803F00000
+B5EE:000000080008770844384408443877080008000003F80020002000D003080000
+B5EF:0000000800087708443844084438770800080000004003F8004000A003180000
+B5F0:000000080008770844384408443877080008000003F8000803F8000800080000
+B5F1:000000080008770844384408443877080008000003F8020003F8020003F80000
+B5F2:000000080008770844384408443877080008000000000FF8022002200FF80000
+B5F3:000000080008770844384408443877080008000000800FF803E0041003E00000
+B5F4:00000000000A000A7BCA420A423A420A420A423A7BCA000A000A000A000A0000
+B5F5:000000280028772844E8442844E877280028000007F800080008000800080000
+B5F6:000000280028772844E8442844E877280028000000003EF80208020802080000
+B5F7:000000280028772844E8442844E877280028000000003E100210022802C40000
+B5F8:000000280028772844E8442844E877280028002808000800080008000FF80000
+B5F9:000000280028772844E8442844E8772800280000000020F8201020303ECC0000
+B5FA:000000280028772844E8442844E8772800280000202021FC207020883E700000
+B5FB:000000280028772844E8442844E877280028000003F802000200020003F80000
+B5FC:000000280028772844E8442844E877280028000007F8000807F8040007F80000
+B5FD:000000280028772844E8442844E87728002800003EF802083E0820083E080000
+B5FE:000000280028772844E8442844E87728002800003EF802883E8820883EF80000
+B5FF:000000280028772844E8442844E87728002800003E8802883EF820883EF80000
+B600:000000280028772844E8442844E87728002800001F0801081F0810141F620000
+B601:000000280028772844E8442844E87728002800003EF802803EF820803EF80000
+B602:000000280028772844E8442844E87728002800003EFC02483E4820483EFC0000
+B603:000000280028772844E8442844E87728002800003E1002FE3E3820443E380000
+B604:000000280028772844E8442844E877280028000003F802080208020803F80000
+B605:000000280028772844E8442844E87728002800000208020803F8020803F80000
+B606:000000280028772844E8442844E8772800280000110811081F0811141F620000
+B607:000000280028772844E8442844E8772800280000000800080008003400C20000
+B608:000000280028772844E8442844E87728002800000048004800A8011406620000
+B609:000000280028772844E8442844E8772800280000000001F00208020801F00000
+B60A:000000280028772844E8442844E877280028000003F80020002000D003080000
+B60B:000000280028772844E8442844E8772800280000004003F8004000A003180000
+B60C:000000280028772844E8442844E877280028000003F8000803F8000800080000
+B60D:000000280028772844E8442844E877280028000003F8020003F8020003F80000
+B60E:000000280028772844E8442844E877280028000000000FF8022002200FF80000
+B60F:000000280028772844E8442844E877280028000000800FF803E0041003E00000
+B610:000000003EF820802080208020803EF8000000000100010001007FFC00000000
+B611:000000001EF0108010801EF0010001007FFC00001FF000100010001000100000
+B612:000000001EF0108010801EF0010001007FFC000000003EF80208020802080000
+B613:000000001EF0108010801EF0010001007FFC000000001E100210022802C40000
+B614:000000001EF0108010801EF0010001007FFC000000001000100010001FF00000
+B615:000000001EF0108010801EF0010001007FFC0000000020F8201020303ECC0000
+B616:000000001EF0108010801EF0010001007FFC0000202021FC207020883E700000
+B617:000000001EF0108010801EF0010001007FFC00001FF01000100010001FF00000
+B618:000000001EF0108010801EF0010001007FFC00001FF000101FF010001FF00000
+B619:000000001EF0108010801EF0010001007FFC00003EF802083E0820083E080000
+B61A:000000001EF0108010801EF0010001007FFC00003EF802883E8820883EF80000
+B61B:000000001EF0108010801EF0010001007FFC00003E8802883EF820883EF80000
+B61C:000000001EF0108010801EF0010001007FFC00003E1002103E1020283EC40000
+B61D:000000001EF0108010801EF0010001007FFC00003EF802803EF820803EF80000
+B61E:000000001EF0108010801EF0010001007FFC00003EFC02483E4820483EFC0000
+B61F:000000001EF0108010801EF0010001007FFC00003E2003FC3E7020883E700000
+B620:000000001EF0108010801EF0010001007FFC00001FF01010101010101FF00000
+B621:000000001EF0108010801EF0010001007FFC0000101010101FF010101FF00000
+B622:000000001EF0108010801EF0010001007FFC0000222022203E2022503E880000
+B623:000000001EF0108010801EF0010001007FFC000000000100010002800C400000
+B624:000000001EF0108010801EF0010001007FFC00000000024002400DA033100000
+B625:000000001EF0108010801EF0010001007FFC0000000007C00820082007C00000
+B626:000000001EF0108010801EF0010001007FFC0000000007E00080014006200000
+B627:000000001EF0108010801EF0010001007FFC0000008007E00080014006200000
+B628:000000001EF0108010801EF0010001007FFC00001FF000101FF0001000100000
+B629:000000001EF0108010801EF0010001007FFC00001FF010001FF010001FF00000
+B62A:000000001EF0108010801EF0010001007FFC000000001FF0044004401FF00000
+B62B:000000001EF0108010801EF0010001007FFC000001001FF007C0082007C00000
+B62C:0000001000107BD0421042104210421E7BD00010041004107FD0001000100000
+B62D:000000083B882208220E3B88040804087FE8000007F800080008000800080000
+B62E:000000083B882208220E3B88040804087FE8000000003EF80208020802080000
+B62F:000000083B882208220E3B88040804087FE8000000001F080108011401620000
+B630:000000083B882208220E3B88040804087FE8000008000800080008000FF80000
+B631:000000083B882208220E3B88040804087FE80000000010F8101010301ECC0000
+B632:000000083B882208220E3B88040804087FE800000808087F081C08220F9C0000
+B633:000000083B882208220E3B88040804087FE8000003F802000200020003F80000
+B634:000000083B882208220E3B88040804087FE8000007F8000807F8040007F80000
+B635:000000083B882208220E3B88040804087FE800003EF802083E0820083E080000
+B636:000000083B882208220E3B88040804087FE800003EF802883E8820883EF80000
+B637:000000083B882208220E3B88040804087FE800003E8802883EF820883EF80000
+B638:000000083B882208220E3B88040804087FE800001F0801081F0810141F620000
+B639:000000083B882208220E3B88040804087FE800003EF802803EF820803EF80000
+B63A:000000083B882208220E3B88040804087FE800003EFC02483E4820483EFC0000
+B63B:000000083B882208220E3B88040804087FE800001F08017F1F1C10221F1C0000
+B63C:000000083B882208220E3B88040804087FE8000003F802080208020803F80000
+B63D:000000083B882208220E3B88040804087FE800000208020803F8020803F80000
+B63E:000000083B882208220E3B88040804087FE80000110811081F0811141F620000
+B63F:000000083B882208220E3B88040804087FE80000001000100010006801840000
+B640:000000083B882208220E3B88040804087FE800000048004800A8011406620000
+B641:000000083B882208220E3B88040804087FE80000000003F00408040803F00000
+B642:000000083B882208220E3B88040804087FE8000003F80020002000D003080000
+B643:000000083B882208220E3B88040804087FE80000004003F8004000A003180000
+B644:000000083B882208220E3B88040804087FE8000003F8000803F8000800080000
+B645:000000083B882208220E3B88040804087FE8000003F8020003F8020003F80000
+B646:000000083B882208220E3B88040804087FE8000000000FF8022002200FF80000
+B647:000000083B882208220E3B88040804087FE8000000800FF803E0041003E00000
+B648:0000001200127BD2421242124212421E7BD20012041204127FD2001200120000
+B649:000000283BA8222822383BA8042804287FA8000007F800080008000800080000
+B64A:000000283BA8222822383BA8042804287FA8000000003EF80208020802080000
+B64B:000000283BA8222822383BA8042804287FA8000000001F080108011401620000
+B64C:000000283BA8222822383BA8042804287FA8000008000800080008000FF80000
+B64D:000000283BA8222822383BA8042804287FA80000000010F8101010301ECC0000
+B64E:000000283BA8222822383BA8042804287FA800000808087F081C08220F9C0000
+B64F:000000283BA8222822383BA8042804287FA8000003F802000200020003F80000
+B650:000000283BA8222822383BA8042804287FA8000007F8000807F8040007F80000
+B651:000000283BA8222822383BA8042804287FA800003EF802083E0820083E080000
+B652:000000283BA8222822383BA8042804287FA800003EF802883E8820883EF80000
+B653:000000283BA8222822383BA8042804287FA800003E8802883EF820883EF80000
+B654:000000283BA8222822383BA8042804287FA800001F0801081F0810141F620000
+B655:000000283BA8222822383BA8042804287FA800003EF802803EF820803EF80000
+B656:000000283BA8222822383BA8042804287FA800003EFC02483E4820483EFC0000
+B657:000000283BA8222822383BA8042804287FA800001F08017F1F1C10221F1C0000
+B658:000000283BA8222822383BA8042804287FA8000003F802080208020803F80000
+B659:000000283BA8222822383BA8042804287FA800000208020803F8020803F80000
+B65A:000000283BA8222822383BA8042804287FA80000110811081F0811141F620000
+B65B:000000283BA8222822383BA8042804287FA80000001000100010006801840000
+B65C:000000283BA8222822383BA8042804287FA800000048004800A8011406620000
+B65D:000000283BA8222822383BA8042804287FA80000000003F00408040803F00000
+B65E:000000283BA8222822383BA8042804287FA8000003F80020002000D003080000
+B65F:000000283BA8222822383BA8042804287FA80000004003F8004000A003180000
+B660:000000283BA8222822383BA8042804287FA8000003F8000803F8000800080000
+B661:000000283BA8222822383BA8042804287FA8000003F8020003F8020003F80000
+B662:000000283BA8222822383BA8042804287FA8000000000FF8022002200FF80000
+B663:000000283BA8222822383BA8042804287FA8000000800FF803E0041003E00000
+B664:0000000800087BC842084208420842087BC80008040804087FE8000800080000
+B665:000000083B88220822083B88040804087FE8000007F800080008000800080000
+B666:000000083B88220822083B88040804087FE8000000003EF80208020802080000
+B667:000000083B88220822083B88040804087FE8000000001F080108011401620000
+B668:000000083B88220822083B88040804087FE8000008000800080008000FF80000
+B669:000000083B88220822083B88040804087FE80000000010F8101010301ECC0000
+B66A:000000083B88220822083B88040804087FE800000808087F081C08220F9C0000
+B66B:000000083B88220822083B88040804087FE8000003F802000200020003F80000
+B66C:000000083B88220822083B88040804087FE8000007F8000807F8040007F80000
+B66D:000000083B88220822083B88040804087FE800003EF802083E0820083E080000
+B66E:000000083B88220822083B88040804087FE800003EF802883E8820883EF80000
+B66F:000000083B88220822083B88040804087FE800003E8802883EF820883EF80000
+B670:000000083B88220822083B88040804087FE800001F0801081F0810141F620000
+B671:000000083B88220822083B88040804087FE800003EF802803EF820803EF80000
+B672:000000083B88220822083B88040804087FE800003EFC02483E4820483EFC0000
+B673:000000083B88220822083B88040804087FE800001F08017F1F1C10221F1C0000
+B674:000000083B88220822083B88040804087FE8000003F802080208020803F80000
+B675:000000083B88220822083B88040804087FE800000208020803F8020803F80000
+B676:000000083B88220822083B88040804087FE80000110811081F0811141F620000
+B677:000000083B88220822083B88040804087FE80000001000100010006801840000
+B678:000000083B88220822083B88040804087FE800000048004800A8011406620000
+B679:000000083B88220822083B88040804087FE80000000003F00408040803F00000
+B67A:000000083B88220822083B88040804087FE8000003F80020002000D003080000
+B67B:000000083B88220822083B88040804087FE80000004003F8004000A003180000
+B67C:000000083B88220822083B88040804087FE8000003F8000803F8000800080000
+B67D:000000083B88220822083B88040804087FE8000003F8020003F8020003F80000
+B67E:000000083B88220822083B88040804087FE8000000000FF8022002200FF80000
+B67F:000000083B88220822083B88040804087FE8000000800FF803E0041003E00000
+B680:000000003EF820802080208020803EF8000004400440044004407FFC00000000
+B681:000000001EF0108010801EF0044004407FFC00001FF000100010001000100000
+B682:000000001EF0108010801EF0044004407FFC000000003EF80208020802080000
+B683:000000001EF0108010801EF0044004407FFC000000001E100210022802C40000
+B684:000000001EF0108010801EF0044004407FFC000000001000100010001FF00000
+B685:000000001EF0108010801EF0044004407FFC0000000020F8201020303ECC0000
+B686:000000001EF0108010801EF0044004407FFC0000202021FC207020883E700000
+B687:000000001EF0108010801EF0044004407FFC00001FF01000100010001FF00000
+B688:000000001EF0108010801EF0044004407FFC00001FF000101FF010001FF00000
+B689:000000001EF0108010801EF0044004407FFC00003EF802083E0820083E080000
+B68A:000000001EF0108010801EF0044004407FFC00003EF802883E8820883EF80000
+B68B:000000001EF0108010801EF0044004407FFC00003E8802883EF820883EF80000
+B68C:000000001EF0108010801EF0044004407FFC00003E1002103E1020283EC40000
+B68D:000000001EF0108010801EF0044004407FFC00003EF802803EF820803EF80000
+B68E:000000001EF0108010801EF0044004407FFC00003EFC02483E4820483EFC0000
+B68F:000000001EF0108010801EF0044004407FFC00003E2003FC3E7020883E700000
+B690:000000001EF0108010801EF0044004407FFC00001FF01010101010101FF00000
+B691:000000001EF0108010801EF0044004407FFC0000101010101FF010101FF00000
+B692:000000001EF0108010801EF0044004407FFC0000222022203E2022503E880000
+B693:000000001EF0108010801EF0044004407FFC000000000100010002800C400000
+B694:000000001EF0108010801EF0044004407FFC00000000024002400DA033100000
+B695:000000001EF0108010801EF0044004407FFC0000000007C00820082007C00000
+B696:000000001EF0108010801EF0044004407FFC0000000007E00080014006200000
+B697:000000001EF0108010801EF0044004407FFC0000008007E00080014006200000
+B698:000000001EF0108010801EF0044004407FFC00001FF000101FF0001000100000
+B699:000000001EF0108010801EF0044004407FFC00001FF010001FF010001FF00000
+B69A:000000001EF0108010801EF0044004407FFC000000001FF0044004401FF00000
+B69B:000000001EF0108010801EF0044004407FFC000001001FF007C0082007C00000
+B69C:000000003EF820802080208020803EF8000000003FF801000100010001000000
+B69D:000000001EF0108010801EF000007FFC010001001FF000100010001000100000
+B69E:000000001EF0108010801EF000007FFC0100010000003EF80208020802080000
+B69F:000000001EF0108010801EF000007FFC0100010000001E100210022802C40000
+B6A0:000000001EF0108010801EF0000000007FFC010001001100100010001FF00000
+B6A1:000000001EF0108010801EF000007FFC01000100000020F8201020303ECC0000
+B6A2:000000001EF0108010801EF000007FFC01000100202021FC207020883E700000
+B6A3:000000001EF0108010801EF000007FFC010001001FF01000100010001FF00000
+B6A4:000000001EF0108010801EF000007FFC010001001FF000101FF010001FF00000
+B6A5:000000001EF0108010801EF000007FFC010001003EF802083E0820083E080000
+B6A6:000000001EF0108010801EF000007FFC010001003EF802883E8820883EF80000
+B6A7:000000001EF0108010801EF000007FFC010001003E8802883EF820883EF80000
+B6A8:000000001EF0108010801EF000007FFC010001003E1002103E1020283EC40000
+B6A9:000000001EF0108010801EF000007FFC010001003EF802803EF820803EF80000
+B6AA:000000001EF0108010801EF000007FFC010001003EFC02483E4820483EFC0000
+B6AB:000000001EF0108010801EF000007FFC010001003E2003FC3E7020883E700000
+B6AC:000000001EF0108010801EF000007FFC010001001FF01010101010101FF00000
+B6AD:000000001EF0108010801EF000007FFC01000100101010101FF010101FF00000
+B6AE:000000001EF0108010801EF000007FFC01000100222022203E2022503E880000
+B6AF:000000001EF0108010801EF000007FFC0100010000000100010002800C400000
+B6B0:000000001EF0108010801EF000007FFC010001000000024002400DA033100000
+B6B1:000000001EF0108010801EF000007FFC01000100000007C00820082007C00000
+B6B2:000000001EF0108010801EF000007FFC01000100000007E00080014006200000
+B6B3:000000001EF0108010801EF000007FFC01000100008007E00080014006200000
+B6B4:000000001EF0108010801EF000007FFC010001001FF000101FF0001000100000
+B6B5:000000001EF0108010801EF000007FFC010001001FF010001FF010001FF00000
+B6B6:000000001EF0108010801EF000007FFC0100010000001FF0044004401FF00000
+B6B7:000000001EF0108010801EF000007FFC0100010001001FF007C0082007C00000
+B6B8:000000087BC842084208420842087BC8000800087FE8040804F8040804080000
+B6B9:0008770844084408770800087FE8027802080000000007F80008000800080000
+B6BA:0008770844084408770800087FE802780208000000003EF80208020802080000
+B6BB:0008770844084408770800087FE802780208000000001F080108011401620000
+B6BC:00087708440844087708000800087FE80278020802081000100010001FF80000
+B6BD:0008770844084408770800087FE8027802080000000020F8201020303ECC0000
+B6BE:0008770844084408770800087FE8027802080000202021FC207020883E700000
+B6BF:0008770844084408770800087FE802780208000003F802000200020003F80000
+B6C0:0008770844084408770800087FE802780208000007F8000807F8040007F80000
+B6C1:0008770844084408770800087FE80278020800003EF802083E0820083E080000
+B6C2:0008770844084408770800087FE80278020800003EF802883E8820883EF80000
+B6C3:0008770844084408770800087FE80278020800003E8802883EF820883EF80000
+B6C4:0008770844084408770800087FE80278020800000F8800880F8808140FA20000
+B6C5:0008770844084408770800087FE80278020800003EF802803EF820803EF80000
+B6C6:0008770844084408770800087FE80278020800003EFC02483E4820483EFC0000
+B6C7:0008770844084408770800087FE80278020800003E1002FE3E3820443E380000
+B6C8:0008770844084408770800087FE802780208000003F802080208020803F80000
+B6C9:0008770844084408770800087FE80278020800000208020803F8020803F80000
+B6CA:0008770844084408770800087FE8027802080000210821083F0821143F620000
+B6CB:0008770844084408770800087FE8027802080000001000100010006801840000
+B6CC:0008770844084408770800087FE80278020800000048004800A8011406620000
+B6CD:0008770844084408770800087FE8027802080000000003F00408040803F00000
+B6CE:0008770844084408770800087FE802780208000003F80020002000D003080000
+B6CF:0008770844084408770800087FE8027802080000004003F8004000A003180000
+B6D0:0008770844084408770800087FE802780208000003F8000803F8000800080000
+B6D1:0008770844084408770800087FE802780208000003F8020003F8020003F80000
+B6D2:0008770844084408770800087FE802780208000000000FF8022002200FF80000
+B6D3:0008770844084408770800087FE802780208000000800FF803E0041003E00000
+B6D4:0000000A7BCA420A420A420A420A7BCA000A000A7FEA040A047A040A040A0000
+B6D5:0028772844284428772800287FA805E804280000000007F80008000800080000
+B6D6:0028772844284428772800287FA805E80428000000003EF80208020802080000
+B6D7:0028772844284428772800287FA805E80428000000001F080108011401620000
+B6D8:00287728442844287728002800287FA8042805E804281428100010001FF80000
+B6D9:0028772844284428772800287FA805E804280000000020F8201020303ECC0000
+B6DA:0028772844284428772800287FA805E804280000202021FC207020883E700000
+B6DB:0028772844284428772800287FA805E80428000003F802000200020003F80000
+B6DC:0028772844284428772800287FA805E80428000007F8000807F8040007F80000
+B6DD:0028772844284428772800287FA805E8042800003EF802083E0820083E080000
+B6DE:0028772844284428772800287FA805E8042800003EF802883E8820883EF80000
+B6DF:0028772844284428772800287FA805E8042800003E8802883EF820883EF80000
+B6E0:0028772844284428772800287FA805E8042800000F8800880F8808140FA20000
+B6E1:0028772844284428772800287FA805E8042800003EF802803EF820803EF80000
+B6E2:0028772844284428772800287FA805E8042800003EFC02483E4820483EFC0000
+B6E3:0028772844284428772800287FA805E8042800003E1002FE3E3820443E380000
+B6E4:0028772844284428772800287FA805E80428000003F802080208020803F80000
+B6E5:0028772844284428772800287FA805E8042800000208020803F8020803F80000
+B6E6:0028772844284428772800287FA805E804280000210821083F0821143F620000
+B6E7:0028772844284428772800287FA805E804280000001000100010006801840000
+B6E8:0028772844284428772800287FA805E8042800000048004800A8011406620000
+B6E9:0028772844284428772800287FA805E804280000000003F00408040803F00000
+B6EA:0028772844284428772800287FA805E80428000003F80020002000D003080000
+B6EB:0028772844284428772800287FA805E804280000004003F8004000A003180000
+B6EC:0028772844284428772800287FA805E80428000003F8000803F8000800080000
+B6ED:0028772844284428772800287FA805E80428000003F8020003F8020003F80000
+B6EE:0028772844284428772800287FA805E80428000000000FF8022002200FF80000
+B6EF:0028772844284428772800287FA805E80428000000800FF803E0041003E00000
+B6F0:000000087BC842084208420842087BC8000800087FE804080408040804080000
+B6F1:0008770844084408770800087FE8020802000000000007F80008000800080000
+B6F2:0008770844084408770800087FE802080200000000003EF80208020802080000
+B6F3:0008770844084408770800087FE802080200000000001F080108011401620000
+B6F4:00087708440844087708000800087FE80208020802081008100010001FF80000
+B6F5:0008770844084408770800087FE8020802000000000020F8201020303ECC0000
+B6F6:0008770844084408770800087FE8020802000000202021FC207020883E700000
+B6F7:0008770844084408770800087FE802080200000003F802000200020003F80000
+B6F8:0008770844084408770800087FE802080200000007F8000807F8040007F80000
+B6F9:0008770844084408770800087FE80208020000003EF802083E0820083E080000
+B6FA:0008770844084408770800087FE80208020000003EF802883E8820883EF80000
+B6FB:0008770844084408770800087FE80208020000003E8802883EF820883EF80000
+B6FC:0008770844084408770800087FE80208020000000F8800880F8808140FA20000
+B6FD:0008770844084408770800087FE80208020000003EF802803EF820803EF80000
+B6FE:0008770844084408770800087FE80208020000003EFC02483E4820483EFC0000
+B6FF:0008770844084408770800087FE80208020000003E1002FE3E3820443E380000
+B700:0008770844084408770800087FE802080200000003F802080208020803F80000
+B701:0008770844084408770800087FE80208020000000208020803F8020803F80000
+B702:0008770844084408770800087FE8020802000000210821083F0821143F620000
+B703:0008770844084408770800087FE8020802000000001000100010006801840000
+B704:0008770844084408770800087FE80208020000000048004800A8011406620000
+B705:0008770844084408770800087FE8020802000000000003F00408040803F00000
+B706:0008770844084408770800087FE802080200000003F80020002000D003080000
+B707:0008770844084408770800087FE8020802000000004003F8004000A003180000
+B708:0008770844084408770800087FE802080200000003F8000803F8000800080000
+B709:0008770844084408770800087FE802080200000003F8020003F8020003F80000
+B70A:0008770844084408770800087FE802080200000000000FF8022002200FF80000
+B70B:0008770844084408770800087FE802080200000000800FF803E0041003E00000
+B70C:000000003EF820802080208020803EF8000000007FFC04400440044004400000
+B70D:000000001EF0108010801EF000007FFC044004401FF000100010001000100000
+B70E:000000001EF0108010801EF000007FFC0440044000003EF80208020802080000
+B70F:000000001EF0108010801EF000007FFC0440044000001E100210022802C40000
+B710:000000001EF0108010801EF0000000007FFC044004401440100010001FF00000
+B711:000000001EF0108010801EF000007FFC04400440000020F8201020303ECC0000
+B712:000000001EF0108010801EF000007FFC04400440202021FC207020883E700000
+B713:000000001EF0108010801EF000007FFC044004401FF01000100010001FF00000
+B714:000000001EF0108010801EF000007FFC044004401FF000101FF010001FF00000
+B715:000000001EF0108010801EF000007FFC044004403EF802083E0820083E080000
+B716:000000001EF0108010801EF000007FFC044004403EF802883E8820883EF80000
+B717:000000001EF0108010801EF000007FFC044004403E8802883EF820883EF80000
+B718:000000001EF0108010801EF000007FFC044004403E1002103E1020283EC40000
+B719:000000001EF0108010801EF000007FFC044004403EF802803EF820803EF80000
+B71A:000000001EF0108010801EF000007FFC044004403EFC02483E4820483EFC0000
+B71B:000000001EF0108010801EF000007FFC044004403E2003FC3E7020883E700000
+B71C:000000001EF0108010801EF000007FFC044004401FF01010101010101FF00000
+B71D:000000001EF0108010801EF000007FFC04400440101010101FF010101FF00000
+B71E:000000001EF0108010801EF000007FFC04400440222022203E2022503E880000
+B71F:000000001EF0108010801EF000007FFC0440044000000100010002800C400000
+B720:000000001EF0108010801EF000007FFC044004400000024002400DA033100000
+B721:000000001EF0108010801EF000007FFC04400440000007C00820082007C00000
+B722:000000001EF0108010801EF000007FFC04400440000007E00080014006200000
+B723:000000001EF0108010801EF000007FFC04400440008007E00080014006200000
+B724:000000001EF0108010801EF000007FFC044004401FF000101FF0001000100000
+B725:000000001EF0108010801EF000007FFC044004401FF010001FF010001FF00000
+B726:000000001EF0108010801EF000007FFC0440044000001FF0044004401FF00000
+B727:000000001EF0108010801EF000007FFC0440044001001FF007C0082007C00000
+B728:000000003EF820802080208020803EF80000000000007FFC0000000000000000
+B729:000000001EF0108010801EF0000000007FFC00001FF000100010001000100000
+B72A:000000001EF0108010801EF0000000007FFC000000003EF80208020802080000
+B72B:000000001EF0108010801EF0000000007FFC000000001E100210022802C40000
+B72C:000000001EF0108010801EF0000000007FFC000000001000100010001FF00000
+B72D:000000001EF0108010801EF0000000007FFC0000000020F8201020303ECC0000
+B72E:000000001EF0108010801EF0000000007FFC0000202021FC207020883E700000
+B72F:000000001EF0108010801EF0000000007FFC00001FF01000100010001FF00000
+B730:000000001EF0108010801EF0000000007FFC00001FF000101FF010001FF00000
+B731:000000001EF0108010801EF0000000007FFC00003EF802083E0820083E080000
+B732:000000001EF0108010801EF0000000007FFC00003EF802883E8820883EF80000
+B733:000000001EF0108010801EF0000000007FFC00003E8802883EF820883EF80000
+B734:000000001EF0108010801EF0000000007FFC00003E1002103E1020283EC40000
+B735:000000001EF0108010801EF0000000007FFC00003EF802803EF820803EF80000
+B736:000000001EF0108010801EF0000000007FFC00003EFC02483E4820483EFC0000
+B737:000000001EF0108010801EF0000000007FFC00003E2003FC3E7020883E700000
+B738:000000001EF0108010801EF0000000007FFC00001FF01010101010101FF00000
+B739:000000001EF0108010801EF0000000007FFC0000101010101FF010101FF00000
+B73A:000000001EF0108010801EF0000000007FFC0000222022203E2022503E880000
+B73B:000000001EF0108010801EF0000000007FFC000000000100010002800C400000
+B73C:000000001EF0108010801EF0000000007FFC00000000024002400DA033100000
+B73D:000000001EF0108010801EF0000000007FFC0000000007C00820082007C00000
+B73E:000000001EF0108010801EF0000000007FFC0000000007E00080014006200000
+B73F:000000001EF0108010801EF0000000007FFC0000008007E00080014006200000
+B740:000000001EF0108010801EF0000000007FFC00001FF000101FF0001000100000
+B741:000000001EF0108010801EF0000000007FFC00001FF010001FF010001FF00000
+B742:000000001EF0108010801EF0000000007FFC000000001FF0044004401FF00000
+B743:000000001EF0108010801EF0000000007FFC000001001FF007C0082007C00000
+B744:0000000800087BC842084208420842087BC8000800087FE80008000800080000
+B745:000000083B88220822083B88000800087FE8000007F800080008000800080000
+B746:000000083B88220822083B88000800087FE8000000003EF80208020802080000
+B747:000000083B88220822083B88000800087FE8000000001F080108011401620000
+B748:000000083B88220822083B88000800087FE8000008000800080008000FF80000
+B749:000000083B88220822083B88000800087FE80000000010F8101010301ECC0000
+B74A:000000083B88220822083B88000800087FE800000808087F081C08220F9C0000
+B74B:000000083B88220822083B88000800087FE8000003F802000200020003F80000
+B74C:000000083B88220822083B88000800087FE8000007F8000807F8040007F80000
+B74D:000000083B88220822083B88000800087FE800003EF802083E0820083E080000
+B74E:000000083B88220822083B88000800087FE800003EF802883E8820883EF80000
+B74F:000000083B88220822083B88000800087FE800003E8802883EF820883EF80000
+B750:000000083B88220822083B88000800087FE800001F0801081F0810141F620000
+B751:000000083B88220822083B88000800087FE800003EF802803EF820803EF80000
+B752:000000083B88220822083B88000800087FE800003EFC02483E4820483EFC0000
+B753:000000083B88220822083B88000800087FE800001F08017F1F1C10221F1C0000
+B754:000000083B88220822083B88000800087FE8000003F802080208020803F80000
+B755:000000083B88220822083B88000800087FE800000208020803F8020803F80000
+B756:000000083B88220822083B88000800087FE80000110811081F0811141F620000
+B757:000000083B88220822083B88000800087FE80000001000100010006801840000
+B758:000000083B88220822083B88000800087FE800000048004800A8011406620000
+B759:000000083B88220822083B88000800087FE80000000003F00408040803F00000
+B75A:000000083B88220822083B88000800087FE8000003F80020002000D003080000
+B75B:000000083B88220822083B88000800087FE80000004003F8004000A003180000
+B75C:000000083B88220822083B88000800087FE8000003F8000803F8000800080000
+B75D:000000083B88220822083B88000800087FE8000003F8020003F8020003F80000
+B75E:000000083B88220822083B88000800087FE8000000000FF8022002200FF80000
+B75F:000000083B88220822083B88000800087FE8000000800FF803E0041003E00000
+B760:00000000000800087BC8420842084208420842087BC800080008000800080000
+B761:0000000800087708440844084408770800080000000007F80008000800080000
+B762:000000080008770844084408440877080008000000003EF80208020802080000
+B763:000000080008770844084408440877080008000000001F080108011401620000
+B764:000000080008770844084408440877080008000800001000100010001FF80000
+B765:0000000800087708440844084408770800080000000020F8201020303ECC0000
+B766:0000000800087708440844084408770800080000202021FC207020883E700000
+B767:000000080008770844084408440877080008000003F802000200020003F80000
+B768:000000080008770844084408440877080008000007F8000807F8040007F80000
+B769:00000008000877084408440844087708000800003EF802083E0820083E080000
+B76A:00000008000877084408440844087708000800003EF802883E8820883EF80000
+B76B:00000008000877084408440844087708000800003E8802883EF820883EF80000
+B76C:00000008000877084408440844087708000800000F8800880F8808140FA20000
+B76D:00000008000877084408440844087708000800003EF802803EF820803EF80000
+B76E:00000008000877084408440844087708000800003EFC02483E4820483EFC0000
+B76F:00000008000877084408440844087708000800003E1002FE3E3820443E380000
+B770:000000080008770844084408440877080008000003F802080208020803F80000
+B771:00000008000877084408440844087708000800000208020803F8020803F80000
+B772:0000000800087708440844084408770800080000210821083F0821143F620000
+B773:0000000800087708440844084408770800080000001000100010006801840000
+B774:00000008000877084408440844087708000800000048004800A8011406620000
+B775:0000000800087708440844084408770800080000000003F00408040803F00000
+B776:000000080008770844084408440877080008000003F80020002000D003080000
+B777:0000000800087708440844084408770800080000004003F8004000A003180000
+B778:000000080008770844084408440877080008000003F8000803F8000800080000
+B779:000000080008770844084408440877080008000003F8020003F8020003F80000
+B77A:000000080008770844084408440877080008000000000FF8022002200FF80000
+B77B:000000080008770844084408440877080008000000800FF803E0041003E00000
+B77C:00000000001000103F90009000903F9E2010201020103F900010001000100000
+B77D:0000000800083F0801083F0E20083F080008000007F800080008000800080000
+B77E:0000000800083F0801083F0E20083F080008000000003EF80208020802080000
+B77F:0000000800083F0801083F0E20083F080008000000001F080108011401620000
+B780:0000000800083F0801083F0E20083F080008000808000800080008000FF80000
+B781:0000000800083F0801083F0E20083F0800080000000010F8101010301ECC0000
+B782:0000000800083F0801083F0E20083F08000800000808087F081C08220F9C0000
+B783:0000000800083F0801083F0E20083F080008000003F802000200020003F80000
+B784:0000000800083F0801083F0E20083F080008000007F8000807F8040007F80000
+B785:0000000800083F0801083F0E20083F08000800003EF802083E0820083E080000
+B786:0000000800083F0801083F0E20083F08000800003EF802883E8820883EF80000
+B787:0000000800083F0801083F0E20083F08000800003E8802883EF820883EF80000
+B788:0000000800083F0801083F0E20083F08000800001F0801081F0810141F620000
+B789:0000000800083F0801083F0E20083F08000800003EF802803EF820803EF80000
+B78A:0000000800083F0801083F0E20083F08000800003EFC02483E4820483EFC0000
+B78B:0000000800083F0801083F0E20083F08000800001F08017F1F1C10221F1C0000
+B78C:0000000800083F0801083F0E20083F080008000003F802080208020803F80000
+B78D:0000000800083F0801083F0E20083F08000800000208020803F8020803F80000
+B78E:0000000800083F0801083F0E20083F0800080000110811081F0811141F620000
+B78F:0000000800083F0801083F0E20083F0800080000001000100010006801840000
+B790:0000000800083F0801083F0E20083F08000800000048004800A8011406620000
+B791:0000000800083F0801083F0E20083F0800080000000003F00408040803F00000
+B792:0000000800083F0801083F0E20083F080008000003F80020002000D003080000
+B793:0000000800083F0801083F0E20083F0800080000004003F8004000A003180000
+B794:0000000800083F0801083F0E20083F080008000003F8000803F8000800080000
+B795:0000000800083F0801083F0E20083F080008000003F8020003F8020003F80000
+B796:0000000800083F0801083F0E20083F080008000000000FF8022002200FF80000
+B797:0000000800083F0801083F0E20083F080008000000800FF803E0041003E00000
+B798:00000000001200123F92009200923F9E2012201220123F920012001200120000
+B799:0000002800283F2801283F3820283F280028000007F800080008000800080000
+B79A:0000002800283F2801283F3820283F280028000000003EF80208020802080000
+B79B:0000002800283F2801283F3820283F280028000000003E100210022802C40000
+B79C:0000002800283F2801283F3820283F280028002808000800080008000FF80000
+B79D:0000002800283F2801283F3820283F2800280000000020F8201020303ECC0000
+B79E:0000002800283F2801283F3820283F2800280000202021FC207020883E700000
+B79F:0000002800283F2801283F3820283F280028000003F802000200020003F80000
+B7A0:0000002800283F2801283F3820283F280028000007F8000807F8040007F80000
+B7A1:0000002800283F2801283F3820283F28002800003EF802083E0820083E080000
+B7A2:0000002800283F2801283F3820283F28002800003EF802883E8820883EF80000
+B7A3:0000002800283F2801283F3820283F28002800003E8802883EF820883EF80000
+B7A4:0000002800283F2801283F3820283F28002800001F0801081F0810141F620000
+B7A5:0000002800283F2801283F3820283F28002800003EF802803EF820803EF80000
+B7A6:0000002800283F2801283F3820283F28002800003EFC02483E4820483EFC0000
+B7A7:0000002800283F2801283F3820283F28002800003E1002FE3E3820443E380000
+B7A8:0000002800283F2801283F3820283F280028000003F802080208020803F80000
+B7A9:0000002800283F2801283F3820283F28002800000208020803F8020803F80000
+B7AA:0000002800283F2801283F3820283F2800280000110811081F0811141F620000
+B7AB:0000002800283F2801283F3820283F2800280000000800080008003400C20000
+B7AC:0000002800283F2801283F3820283F28002800000048004800A8011406620000
+B7AD:0000002800283F2801283F3820283F2800280000000001F00208020801F00000
+B7AE:0000002800283F2801283F3820283F280028000003F80020002000D003080000
+B7AF:0000002800283F2801283F3820283F2800280000004003F8004000A003180000
+B7B0:0000002800283F2801283F3820283F280028000003F8000803F8000800080000
+B7B1:0000002800283F2801283F3820283F280028000003F8020003F8020003F80000
+B7B2:0000002800283F2801283F3820283F280028000000000FF8022002200FF80000
+B7B3:0000002800283F2801283F3820283F280028000000800FF803E0041003E00000
+B7B4:00000000001000103F900090009E3F902010201E20103F900010001000100000
+B7B5:0000000800083F08010E3F08200E3F080008000007F800080008000800080000
+B7B6:0000000800083F08010E3F08200E3F080008000000003EF80208020802080000
+B7B7:0000000800083F08010E3F08200E3F080008000000001F080108011401620000
+B7B8:0000000800083F08010E3F08200E3F080008000008000800080008000FF80000
+B7B9:0000000800083F08010E3F08200E3F0800080000000010F8101010301ECC0000
+B7BA:0000000800083F08010E3F08200E3F08000800000808087F081C08220F9C0000
+B7BB:0000000800083F08010E3F08200E3F080008000003F802000200020003F80000
+B7BC:0000000800083F08010E3F08200E3F080008000007F8000807F8040007F80000
+B7BD:0000000800083F08010E3F08200E3F08000800003EF802083E0820083E080000
+B7BE:0000000800083F08010E3F08200E3F08000800003EF802883E8820883EF80000
+B7BF:0000000800083F08010E3F08200E3F08000800003E8802883EF820883EF80000
+B7C0:0000000800083F08010E3F08200E3F08000800001F0801081F0810141F620000
+B7C1:0000000800083F08010E3F08200E3F08000800003EF802803EF820803EF80000
+B7C2:0000000800083F08010E3F08200E3F08000800003EFC02483E4820483EFC0000
+B7C3:0000000800083F08010E3F08200E3F08000800001F08017F1F1C10221F1C0000
+B7C4:0000000800083F08010E3F08200E3F080008000003F802080208020803F80000
+B7C5:0000000800083F08010E3F08200E3F08000800000208020803F8020803F80000
+B7C6:0000000800083F08010E3F08200E3F0800080000110811081F0811141F620000
+B7C7:0000000800083F08010E3F08200E3F0800080000001000100010006801840000
+B7C8:0000000800083F08010E3F08200E3F08000800000048004800A8011406620000
+B7C9:0000000800083F08010E3F08200E3F0800080000000003F00408040803F00000
+B7CA:0000000800083F08010E3F08200E3F080008000003F80020002000D003080000
+B7CB:0000000800083F08010E3F08200E3F0800080000004003F8004000A003180000
+B7CC:0000000800083F08010E3F08200E3F080008000003F8000803F8000800080000
+B7CD:0000000800083F08010E3F08200E3F080008000003F8020003F8020003F80000
+B7CE:0000000800083F08010E3F08200E3F080008000000000FF8022002200FF80000
+B7CF:0000000800083F08010E3F08200E3F080008000000800FF803E0041003E00000
+B7D0:00000000001200123F920092009E3F922012201E20123F920012001200120000
+B7D1:0000002800283F2801383F2820383F280028000007F800080008000800080000
+B7D2:0000002800283F2801383F2820383F280028000000003EF80208020802080000
+B7D3:0000002800283F2801383F2820383F280028000000003E100210022802C40000
+B7D4:0000002800283F2801383F2820383F280028002808000800080008000FF80000
+B7D5:0000002800283F2801383F2820383F2800280000000020F8201020303ECC0000
+B7D6:0000002800283F2801383F2820383F2800280000202021FC207020883E700000
+B7D7:0000002800283F2801383F2820383F280028000003F802000200020003F80000
+B7D8:0000002800283F2801383F2820383F280028000007F8000807F8040007F80000
+B7D9:0000002800283F2801383F2820383F28002800003EF802083E0820083E080000
+B7DA:0000002800283F2801383F2820383F28002800003EF802883E8820883EF80000
+B7DB:0000002800283F2801383F2820383F28002800003E8802883EF820883EF80000
+B7DC:0000002800283F2801383F2820383F28002800001F0801081F0810141F620000
+B7DD:0000002800283F2801383F2820383F28002800003EF802803EF820803EF80000
+B7DE:0000002800283F2801383F2820383F28002800003EFC02483E4820483EFC0000
+B7DF:0000002800283F2801383F2820383F28002800003E1002FE3E3820443E380000
+B7E0:0000002800283F2801383F2820383F280028000003F802080208020803F80000
+B7E1:0000002800283F2801383F2820383F28002800000208020803F8020803F80000
+B7E2:0000002800283F2801383F2820383F2800280000110811081F0811141F620000
+B7E3:0000002800283F2801383F2820383F2800280000000800080008003400C20000
+B7E4:0000002800283F2801383F2820383F28002800000048004800A8011406620000
+B7E5:0000002800283F2801383F2820383F2800280000000001F00208020801F00000
+B7E6:0000002800283F2801383F2820383F280028000003F80020002000D003080000
+B7E7:0000002800283F2801383F2820383F2800280000004003F8004000A003180000
+B7E8:0000002800283F2801383F2820383F280028000003F8000803F8000800080000
+B7E9:0000002800283F2801383F2820383F280028000003F8020003F8020003F80000
+B7EA:0000002800283F2801383F2820383F280028000000000FF8022002200FF80000
+B7EB:0000002800283F2801383F2820383F280028000000800FF803E0041003E00000
+B7EC:00000000000200023F82008200823F9E2002200220023F820002000200020000
+B7ED:0000000800083F0801083F3820083F0800080000000007F80008000800080000
+B7EE:0000000800083F0801083F3820083F080008000000003EF80208020802080000
+B7EF:0000000800083F0801083F3820083F080008000000001F080108011401620000
+B7F0:0000000800083F0801083F3820083F080008000000001000100010001FF80000
+B7F1:0000000800083F0801083F3820083F0800080000000020F8201020303ECC0000
+B7F2:0000000800083F0801083F3820083F0800080000202021FC207020883E700000
+B7F3:0000000800083F0801083F3820083F080008000003F802000200020003F80000
+B7F4:0000000800083F0801083F3820083F080008000007F8000807F8040007F80000
+B7F5:0000000800083F0801083F3820083F08000800003EF802083E0820083E080000
+B7F6:0000000800083F0801083F3820083F08000800003EF802883E8820883EF80000
+B7F7:0000000800083F0801083F3820083F08000800003E8802883EF820883EF80000
+B7F8:0000000800083F0801083F3820083F08000800000F8800880F8808140FA20000
+B7F9:0000000800083F0801083F3820083F08000800003EF802803EF820803EF80000
+B7FA:0000000800083F0801083F3820083F08000800003EFC02483E4820483EFC0000
+B7FB:0000000800083F0801083F3820083F08000800003E1002FE3E3820443E380000
+B7FC:0000000800083F0801083F3820083F080008000003F802080208020803F80000
+B7FD:0000000800083F0801083F3820083F08000800000208020803F8020803F80000
+B7FE:0000000800083F0801083F3820083F0800080000210821083F0821143F620000
+B7FF:0000000800083F0801083F3820083F0800080000001000100010006801840000
+B800:0000000800083F0801083F3820083F08000800000048004800A8011406620000
+B801:0000000800083F0801083F3820083F0800080000000003F00408040803F00000
+B802:0000000800083F0801083F3820083F080008000003F80020002000D003080000
+B803:0000000800083F0801083F3820083F0800080000004003F8004000A003180000
+B804:0000000800083F0801083F3820083F080008000003F8000803F8000800080000
+B805:0000000800083F0801083F3820083F080008000003F8020003F8020003F80000
+B806:0000000800083F0801083F3820083F080008000000000FF8022002200FF80000
+B807:0000000800083F0801083F3820083F080008000000800FF803E0041003E00000
+B808:00000000000A000A3F8A008A008A3FBA200A200A200A3F8A000A000A000A0000
+B809:0000002800283F2801283FE820283F280028000007F800080008000800080000
+B80A:0000002800283F2801283FE820283F280028000000003EF80208020802080000
+B80B:0000002800283F2801283FE820283F280028000000003E100210022802C40000
+B80C:0000002800283F2801283FE820283F280028000008000800080008000FF80000
+B80D:0000002800283F2801283FE820283F2800280000000020F8201020303ECC0000
+B80E:0000002800283F2801283FE820283F2800280000202021FC207020883E700000
+B80F:0000002800283F2801283FE820283F280028000003F802000200020003F80000
+B810:0000002800283F2801283FE820283F280028000007F8000807F8040007F80000
+B811:0000002800283F2801283FE820283F28002800003EF802083E0820083E080000
+B812:0000002800283F2801283FE820283F28002800003EF802883E8820883EF80000
+B813:0000002800283F2801283FE820283F28002800003E8802883EF820883EF80000
+B814:0000002800283F2801283FE820283F28002800001F0801081F0810141F620000
+B815:0000002800283F2801283FE820283F28002800003EF802803EF820803EF80000
+B816:0000002800283F2801283FE820283F28002800003EFC02483E4820483EFC0000
+B817:0000002800283F2801283FE820283F28002800003E1002FE3E3820443E380000
+B818:0000002800283F2801283FE820283F280028000003F802080208020803F80000
+B819:0000002800283F2801283FE820283F28002800000208020803F8020803F80000
+B81A:0000002800283F2801283FE820283F2800280000110811081F0811141F620000
+B81B:0000002800283F2801283FE820283F2800280000000800080008003400C20000
+B81C:0000002800283F2801283FE820283F28002800000048004800A8011406620000
+B81D:0000002800283F2801283FE820283F2800280000000001F00208020801F00000
+B81E:0000002800283F2801283FE820283F280028000003F80020002000D003080000
+B81F:0000002800283F2801283FE820283F2800280000004003F8004000A003180000
+B820:0000002800283F2801283FE820283F280028000003F8000803F8000800080000
+B821:0000002800283F2801283FE820283F280028000003F8020003F8020003F80000
+B822:0000002800283F2801283FE820283F280028000000000FF8022002200FF80000
+B823:0000002800283F2801283FE820283F280028000000800FF803E0041003E00000
+B824:00000000000200023F820082009E3F822002201E20023F820002000200020000
+B825:0000000800083F0801383F0820383F0800080000000007F80008000800080000
+B826:0000000800083F0801383F0820383F080008000000003EF80208020802080000
+B827:0000000800083F0801383F0820383F080008000000001F080108011401620000
+B828:0000000800083F0801383F0820383F080008000800001000100010001FF80000
+B829:0000000800083F0801383F0820383F0800080000000020F8201020303ECC0000
+B82A:0000000800083F0801383F0820383F0800080000202021FC207020883E700000
+B82B:0000000800083F0801383F0820383F080008000003F802000200020003F80000
+B82C:0000000800083F0801383F0820383F080008000007F8000807F8040007F80000
+B82D:0000000800083F0801383F0820383F08000800003EF802083E0820083E080000
+B82E:0000000800083F0801383F0820383F08000800003EF802883E8820883EF80000
+B82F:0000000800083F0801383F0820383F08000800003E8802883EF820883EF80000
+B830:0000000800083F0801383F0820383F08000800000F8800880F8808140FA20000
+B831:0000000800083F0801383F0820383F08000800003EF802803EF820803EF80000
+B832:0000000800083F0801383F0820383F08000800003EFC02483E4820483EFC0000
+B833:0000000800083F0801383F0820383F08000800003E1002FE3E3820443E380000
+B834:0000000800083F0801383F0820383F080008000003F802080208020803F80000
+B835:0000000800083F0801383F0820383F08000800000208020803F8020803F80000
+B836:0000000800083F0801383F0820383F0800080000210821083F0821143F620000
+B837:0000000800083F0801383F0820383F0800080000001000100010006801840000
+B838:0000000800083F0801383F0820383F08000800000048004800A8011406620000
+B839:0000000800083F0801383F0820383F0800080000000003F00408040803F00000
+B83A:0000000800083F0801383F0820383F080008000003F80020002000D003080000
+B83B:0000000800083F0801383F0820383F0800080000004003F8004000A003180000
+B83C:0000000800083F0801383F0820383F080008000003F8000803F8000800080000
+B83D:0000000800083F0801383F0820383F080008000003F8020003F8020003F80000
+B83E:0000000800083F0801383F0820383F080008000000000FF8022002200FF80000
+B83F:0000000800083F0801383F0820383F080008000000800FF803E0041003E00000
+B840:00000000000A000A3F8A008A00BA3F8A200A203A200A3F8A000A000A000A0000
+B841:0000002800283F2801E83F2820E83F280028000007F800080008000800080000
+B842:0000002800283F2801E83F2820E83F280028000000003EF80208020802080000
+B843:0000002800283F2801E83F2820E83F280028000000003E100210022802C40000
+B844:0000002800283F2801E83F2820E83F280028002808000800080008000FF80000
+B845:0000002800283F2801E83F2820E83F2800280000000020F8201020303ECC0000
+B846:0000002800283F2801E83F2820E83F2800280000202021FC207020883E700000
+B847:0000002800283F2801E83F2820E83F280028000003F802000200020003F80000
+B848:0000002800283F2801E83F2820E83F280028000007F8000807F8040007F80000
+B849:0000002800283F2801E83F2820E83F28002800003EF802083E0820083E080000
+B84A:0000002800283F2801E83F2820E83F28002800003EF802883E8820883EF80000
+B84B:0000002800283F2801E83F2820E83F28002800003E8802883EF820883EF80000
+B84C:0000002800283F2801E83F2820E83F28002800001F0801081F0810141F620000
+B84D:0000002800283F2801E83F2820E83F28002800003EF802803EF820803EF80000
+B84E:0000002800283F2801E83F2820E83F28002800003EFC02483E4820483EFC0000
+B84F:0000002800283F2801E83F2820E83F28002800003E1002FE3E3820443E380000
+B850:0000002800283F2801E83F2820E83F280028000003F802080208020803F80000
+B851:0000002800283F2801E83F2820E83F28002800000208020803F8020803F80000
+B852:0000002800283F2801E83F2820E83F2800280000110811081F0811141F620000
+B853:0000002800283F2801E83F2820E83F2800280000000800080008003400C20000
+B854:0000002800283F2801E83F2820E83F28002800000048004800A8011406620000
+B855:0000002800283F2801E83F2820E83F2800280000000001F00208020801F00000
+B856:0000002800283F2801E83F2820E83F280028000003F80020002000D003080000
+B857:0000002800283F2801E83F2820E83F2800280000004003F8004000A003180000
+B858:0000002800283F2801E83F2820E83F280028000003F8000803F8000800080000
+B859:0000002800283F2801E83F2820E83F280028000003F8020003F8020003F80000
+B85A:0000002800283F2801E83F2820E83F280028000000000FF8022002200FF80000
+B85B:0000002800283F2801E83F2820E83F280028000000800FF803E0041003E00000
+B85C:000000001FF0001000101FF0100010001FF000000100010001007FFC00000000
+B85D:00001FF000101FF010001FF0010001007FFC00001FF000100010001000100000
+B85E:00001FF000101FF010001FF0010001007FFC000000003EF80208020802080000
+B85F:00001FF000101FF010001FF0010001007FFC000000001E100210022802C40000
+B860:00001FF000101FF010001FF0010001007FFC000000001000100010001FF00000
+B861:00001FF000101FF010001FF0010001007FFC0000000020F8201020303ECC0000
+B862:00001FF000101FF010001FF0010001007FFC0000202021FC207020883E700000
+B863:00001FF000101FF010001FF0010001007FFC00001FF01000100010001FF00000
+B864:00001FF000101FF010001FF0010001007FFC00001FF000101FF010001FF00000
+B865:00001FF000101FF010001FF0010001007FFC00003EF802083E0820083E080000
+B866:00001FF000101FF010001FF0010001007FFC00003EF802883E8820883EF80000
+B867:00001FF000101FF010001FF0010001007FFC00003E8802883EF820883EF80000
+B868:00001FF000101FF010001FF0010001007FFC00003E1002103E1020283EC40000
+B869:00001FF000101FF010001FF0010001007FFC00003EF802803EF820803EF80000
+B86A:00001FF000101FF010001FF0010001007FFC00003EFC02483E4820483EFC0000
+B86B:00001FF000101FF010001FF0010001007FFC00003E2003FC3E7020883E700000
+B86C:00001FF000101FF010001FF0010001007FFC00001FF01010101010101FF00000
+B86D:00001FF000101FF010001FF0010001007FFC0000101010101FF010101FF00000
+B86E:00001FF000101FF010001FF0010001007FFC0000222022203E2022503E880000
+B86F:00001FF000101FF010001FF0010001007FFC000000000100010002800C400000
+B870:00001FF000101FF010001FF0010001007FFC00000000024002400DA033100000
+B871:00001FF000101FF010001FF0010001007FFC0000000007C00820082007C00000
+B872:00001FF000101FF010001FF0010001007FFC0000000007E00080014006200000
+B873:00001FF000101FF010001FF0010001007FFC0000008007E00080014006200000
+B874:00001FF000101FF010001FF0010001007FFC00001FF000101FF0001000100000
+B875:00001FF000101FF010001FF0010001007FFC00001FF010001FF010001FF00000
+B876:00001FF000101FF010001FF0010001007FFC000000001FF0044004401FF00000
+B877:00001FF000101FF010001FF0010001007FFC000001001FF007C0082007C00000
+B878:0000001000103F90009000903F90201E20103F90041004107FD0001000100000
+B879:000000083F8800883F8E20083F8804087FE8000007F800080008000800080000
+B87A:000000083F8800883F8E20083F8804087FE8000000003EF80208020802080000
+B87B:000000083F8800883F8E20083F8804087FE8000000001F080108011401620000
+B87C:000000083F8800883F8E20083F8804087FE8000008000800080008000FF80000
+B87D:000000083F8800883F8E20083F8804087FE80000000010F8101010301ECC0000
+B87E:000000083F8800883F8E20083F8804087FE800000808087F081C08220F9C0000
+B87F:000000083F8800883F8E20083F8804087FE8000003F802000200020003F80000
+B880:000000083F8800883F8E20083F8804087FE8000007F8000807F8040007F80000
+B881:000000083F8800883F8E20083F8804087FE800003EF802083E0820083E080000
+B882:000000083F8800883F8E20083F8804087FE800003EF802883E8820883EF80000
+B883:000000083F8800883F8E20083F8804087FE800003E8802883EF820883EF80000
+B884:000000083F8800883F8E20083F8804087FE800001F0801081F0810141F620000
+B885:000000083F8800883F8E20083F8804087FE800003EF802803EF820803EF80000
+B886:000000083F8800883F8E20083F8804087FE800003EFC02483E4820483EFC0000
+B887:000000083F8800883F8E20083F8804087FE800001F08017F1F1C10221F1C0000
+B888:000000083F8800883F8E20083F8804087FE8000003F802080208020803F80000
+B889:000000083F8800883F8E20083F8804087FE800000208020803F8020803F80000
+B88A:000000083F8800883F8E20083F8804087FE80000110811081F0811141F620000
+B88B:000000083F8800883F8E20083F8804087FE80000001000100010006801840000
+B88C:000000083F8800883F8E20083F8804087FE800000048004800A8011406620000
+B88D:000000083F8800883F8E20083F8804087FE80000000003F00408040803F00000
+B88E:000000083F8800883F8E20083F8804087FE8000003F80020002000D003080000
+B88F:000000083F8800883F8E20083F8804087FE80000004003F8004000A003180000
+B890:000000083F8800883F8E20083F8804087FE8000003F8000803F8000800080000
+B891:000000083F8800883F8E20083F8804087FE8000003F8020003F8020003F80000
+B892:000000083F8800883F8E20083F8804087FE8000000000FF8022002200FF80000
+B893:000000083F8800883F8E20083F8804087FE8000000800FF803E0041003E00000
+B894:0000001200123F92009200923F92201E20123F92041204127FD2001200120000
+B895:000000283FA800A83FB820283FA804287FA8000007F800080008000800080000
+B896:000000283FA800A83FB820283FA804287FA8000000003EF80208020802080000
+B897:000000283FA800A83FB820283FA804287FA8000000001F080108011401620000
+B898:000000283FA800A83FB820283FA804287FA8000008000800080008000FF80000
+B899:000000283FA800A83FB820283FA804287FA80000000010F8101010301ECC0000
+B89A:000000283FA800A83FB820283FA804287FA800000808087F081C08220F9C0000
+B89B:000000283FA800A83FB820283FA804287FA8000003F802000200020003F80000
+B89C:000000283FA800A83FB820283FA804287FA8000007F8000807F8040007F80000
+B89D:000000283FA800A83FB820283FA804287FA800003EF802083E0820083E080000
+B89E:000000283FA800A83FB820283FA804287FA800003EF802883E8820883EF80000
+B89F:000000283FA800A83FB820283FA804287FA800003E8802883EF820883EF80000
+B8A0:000000283FA800A83FB820283FA804287FA800001F0801081F0810141F620000
+B8A1:000000283FA800A83FB820283FA804287FA800003EF802803EF820803EF80000
+B8A2:000000283FA800A83FB820283FA804287FA800003EFC02483E4820483EFC0000
+B8A3:000000283FA800A83FB820283FA804287FA800001F08017F1F1C10221F1C0000
+B8A4:000000283FA800A83FB820283FA804287FA8000003F802080208020803F80000
+B8A5:000000283FA800A83FB820283FA804287FA800000208020803F8020803F80000
+B8A6:000000283FA800A83FB820283FA804287FA80000110811081F0811141F620000
+B8A7:000000283FA800A83FB820283FA804287FA80000001000100010006801840000
+B8A8:000000283FA800A83FB820283FA804287FA800000048004800A8011406620000
+B8A9:000000283FA800A83FB820283FA804287FA80000000003F00408040803F00000
+B8AA:000000283FA800A83FB820283FA804287FA8000003F80020002000D003080000
+B8AB:000000283FA800A83FB820283FA804287FA80000004003F8004000A003180000
+B8AC:000000283FA800A83FB820283FA804287FA8000003F8000803F8000800080000
+B8AD:000000283FA800A83FB820283FA804287FA8000003F8020003F8020003F80000
+B8AE:000000283FA800A83FB820283FA804287FA8000000000FF8022002200FF80000
+B8AF:000000283FA800A83FB820283FA804287FA8000000800FF803E0041003E00000
+B8B0:0000000800083F88008800883F88200820083F88040804087FE8000800080000
+B8B1:000000083F8800883F8820083F8804087FE8000007F800080008000800080000
+B8B2:000000083F8800883F8820083F8804087FE8000000003EF80208020802080000
+B8B3:000000083F8800883F8820083F8804087FE8000000001F080108011401620000
+B8B4:000000083F8800883F8820083F8804087FE8000008000800080008000FF80000
+B8B5:000000083F8800883F8820083F8804087FE80000000010F8101010301ECC0000
+B8B6:000000083F8800883F8820083F8804087FE800000808087F081C08220F9C0000
+B8B7:000000083F8800883F8820083F8804087FE8000003F802000200020003F80000
+B8B8:000000083F8800883F8820083F8804087FE8000007F8000807F8040007F80000
+B8B9:000000083F8800883F8820083F8804087FE800003EF802083E0820083E080000
+B8BA:000000083F8800883F8820083F8804087FE800003EF802883E8820883EF80000
+B8BB:000000083F8800883F8820083F8804087FE800003E8802883EF820883EF80000
+B8BC:000000083F8800883F8820083F8804087FE800001F0801081F0810141F620000
+B8BD:000000083F8800883F8820083F8804087FE800003EF802803EF820803EF80000
+B8BE:000000083F8800883F8820083F8804087FE800003EFC02483E4820483EFC0000
+B8BF:000000083F8800883F8820083F8804087FE800001F08017F1F1C10221F1C0000
+B8C0:000000083F8800883F8820083F8804087FE8000003F802080208020803F80000
+B8C1:000000083F8800883F8820083F8804087FE800000208020803F8020803F80000
+B8C2:000000083F8800883F8820083F8804087FE80000110811081F0811141F620000
+B8C3:000000083F8800883F8820083F8804087FE80000001000100010006801840000
+B8C4:000000083F8800883F8820083F8804087FE800000048004800A8011406620000
+B8C5:000000083F8800883F8820083F8804087FE80000000003F00408040803F00000
+B8C6:000000083F8800883F8820083F8804087FE8000003F80020002000D003080000
+B8C7:000000083F8800883F8820083F8804087FE80000004003F8004000A003180000
+B8C8:000000083F8800883F8820083F8804087FE8000003F8000803F8000800080000
+B8C9:000000083F8800883F8820083F8804087FE8000003F8020003F8020003F80000
+B8CA:000000083F8800883F8820083F8804087FE8000000000FF8022002200FF80000
+B8CB:000000083F8800883F8820083F8804087FE8000000800FF803E0041003E00000
+B8CC:000000001FF0001000101FF0100010001FF004400440044004407FFC00000000
+B8CD:00001FF000101FF010001FF0044004407FFC00001FF000100010001000100000
+B8CE:00001FF000101FF010001FF0044004407FFC000000003EF80208020802080000
+B8CF:00001FF000101FF010001FF0044004407FFC000000001E100210022802C40000
+B8D0:00001FF000101FF010001FF0044004407FFC000000001000100010001FF00000
+B8D1:00001FF000101FF010001FF0044004407FFC0000000020F8201020303ECC0000
+B8D2:00001FF000101FF010001FF0044004407FFC0000202021FC207020883E700000
+B8D3:00001FF000101FF010001FF0044004407FFC00001FF01000100010001FF00000
+B8D4:00001FF000101FF010001FF0044004407FFC00001FF000101FF010001FF00000
+B8D5:00001FF000101FF010001FF0044004407FFC00003EF802083E0820083E080000
+B8D6:00001FF000101FF010001FF0044004407FFC00003EF802883E8820883EF80000
+B8D7:00001FF000101FF010001FF0044004407FFC00003E8802883EF820883EF80000
+B8D8:00001FF000101FF010001FF0044004407FFC00003E1002103E1020283EC40000
+B8D9:00001FF000101FF010001FF0044004407FFC00003EF802803EF820803EF80000
+B8DA:00001FF000101FF010001FF0044004407FFC00003EFC02483E4820483EFC0000
+B8DB:00001FF000101FF010001FF0044004407FFC00003E2003FC3E7020883E700000
+B8DC:00001FF000101FF010001FF0044004407FFC00001FF01010101010101FF00000
+B8DD:00001FF000101FF010001FF0044004407FFC0000101010101FF010101FF00000
+B8DE:00001FF000101FF010001FF0044004407FFC0000222022203E2022503E880000
+B8DF:00001FF000101FF010001FF0044004407FFC000000000100010002800C400000
+B8E0:00001FF000101FF010001FF0044004407FFC00000000024002400DA033100000
+B8E1:00001FF000101FF010001FF0044004407FFC0000000007C00820082007C00000
+B8E2:00001FF000101FF010001FF0044004407FFC0000000007E00080014006200000
+B8E3:00001FF000101FF010001FF0044004407FFC0000008007E00080014006200000
+B8E4:00001FF000101FF010001FF0044004407FFC00001FF000101FF0001000100000
+B8E5:00001FF000101FF010001FF0044004407FFC00001FF010001FF010001FF00000
+B8E6:00001FF000101FF010001FF0044004407FFC000000001FF0044004401FF00000
+B8E7:00001FF000101FF010001FF0044004407FFC000001001FF007C0082007C00000
+B8E8:000000001FF0001000101FF0100010001FF000003FF801000100010001000000
+B8E9:00001FF000101FF010001FF000007FFC010001001FF000100010001000100000
+B8EA:00001FF000101FF010001FF000007FFC0100010000003EF80208020802080000
+B8EB:00001FF000101FF010001FF000007FFC0100010000001E100210022802C40000
+B8EC:00001FF000101FF010001FF0000000007FFC010001001100100010001FF00000
+B8ED:00001FF000101FF010001FF000007FFC01000100000020F8201020303ECC0000
+B8EE:00001FF000101FF010001FF000007FFC01000100202021FC207020883E700000
+B8EF:00001FF000101FF010001FF000007FFC010001001FF01000100010001FF00000
+B8F0:00001FF000101FF010001FF000007FFC010001001FF000101FF010001FF00000
+B8F1:00001FF000101FF010001FF000007FFC010001003EF802083E0820083E080000
+B8F2:00001FF000101FF010001FF000007FFC010001003EF802883E8820883EF80000
+B8F3:00001FF000101FF010001FF000007FFC010001003E8802883EF820883EF80000
+B8F4:00001FF000101FF010001FF000007FFC010001003E1002103E1020283EC40000
+B8F5:00001FF000101FF010001FF000007FFC010001003EF802803EF820803EF80000
+B8F6:00001FF000101FF010001FF000007FFC010001003EFC02483E4820483EFC0000
+B8F7:00001FF000101FF010001FF000007FFC010001003E2003FC3E7020883E700000
+B8F8:00001FF000101FF010001FF000007FFC010001001FF01010101010101FF00000
+B8F9:00001FF000101FF010001FF000007FFC01000100101010101FF010101FF00000
+B8FA:00001FF000101FF010001FF000007FFC01000100222022203E2022503E880000
+B8FB:00001FF000101FF010001FF000007FFC0100010000000100010002800C400000
+B8FC:00001FF000101FF010001FF000007FFC010001000000024002400DA033100000
+B8FD:00001FF000101FF010001FF000007FFC01000100000007C00820082007C00000
+B8FE:00001FF000101FF010001FF000007FFC01000100000007E00080014006200000
+B8FF:00001FF000101FF010001FF000007FFC01000100008007E00080014006200000
+B900:00001FF000101FF010001FF000007FFC010001001FF000101FF0001000100000
+B901:00001FF000101FF010001FF000007FFC010001001FF010001FF010001FF00000
+B902:00001FF000101FF010001FF000007FFC0100010000001FF0044004401FF00000
+B903:00001FF000101FF010001FF000007FFC0100010001001FF007C0082007C00000
+B904:000000083FC8004800483FC8200820083FC800087FE8040804F8040804080000
+B905:7F8800887F8840087F8800087FE8027802080000000007F80008000800080000
+B906:7F8800887F8840087F8800087FE802780208000000003EF80208020802080000
+B907:7F8800887F8840087F8800087FE802780208000000001F080108011401620000
+B908:7F8800887F8840087F88000800087FE80278020802081000100010001FF80000
+B909:7F8800887F8840087F8800087FE8027802080000000020F8201020303ECC0000
+B90A:7F8800887F8840087F8800087FE8027802080000202021FC207020883E700000
+B90B:7F8800887F8840087F8800087FE802780208000003F802000200020003F80000
+B90C:7F8800887F8840087F8800087FE802780208000007F8000807F8040007F80000
+B90D:7F8800887F8840087F8800087FE80278020800003EF802083E0820083E080000
+B90E:7F8800887F8840087F8800087FE80278020800003EF802883E8820883EF80000
+B90F:7F8800887F8840087F8800087FE80278020800003E8802883EF820883EF80000
+B910:7F8800887F8840087F8800087FE80278020800000F8800880F8808140FA20000
+B911:7F8800887F8840087F8800087FE80278020800003EF802803EF820803EF80000
+B912:7F8800887F8840087F8800087FE80278020800003EFC02483E4820483EFC0000
+B913:7F8800887F8840087F8800087FE80278020800003E1002FE3E3820443E380000
+B914:7F8800887F8840087F8800087FE802780208000003F802080208020803F80000
+B915:7F8800887F8840087F8800087FE80278020800000208020803F8020803F80000
+B916:7F8800887F8840087F8800087FE8027802080000210821083F0821143F620000
+B917:7F8800887F8840087F8800087FE8027802080000001000100010006801840000
+B918:7F8800887F8840087F8800087FE80278020800000048004800A8011406620000
+B919:7F8800887F8840087F8800087FE8027802080000000003F00408040803F00000
+B91A:7F8800887F8840087F8800087FE802780208000003F80020002000D003080000
+B91B:7F8800887F8840087F8800087FE8027802080000004003F8004000A003180000
+B91C:7F8800887F8840087F8800087FE802780208000003F8000803F8000800080000
+B91D:7F8800887F8840087F8800087FE802780208000003F8020003F8020003F80000
+B91E:7F8800887F8840087F8800087FE802780208000000000FF8022002200FF80000
+B91F:7F8800887F8840087F8800087FE802780208000000800FF803E0041003E00000
+B920:0000000A3FCA004A004A3FCA200A200A3FCA000A7FEA040A047A040A040A0000
+B921:7FA800A87FA840287FA800287FA805E804280000000007F80008000800080000
+B922:7FA800A87FA840287FA800287FA805E80428000000003EF80208020802080000
+B923:7FA800A87FA840287FA800287FA805E80428000000001F080108011401620000
+B924:7FA800A87FA840287FA8002800287FA8042805E804281428100010001FF80000
+B925:7FA800A87FA840287FA800287FA805E804280000000020F8201020303ECC0000
+B926:7FA800A87FA840287FA800287FA805E804280000202021FC207020883E700000
+B927:7FA800A87FA840287FA800287FA805E80428000003F802000200020003F80000
+B928:7FA800A87FA840287FA800287FA805E80428000007F8000807F8040007F80000
+B929:7FA800A87FA840287FA800287FA805E8042800003EF802083E0820083E080000
+B92A:7FA800A87FA840287FA800287FA805E8042800003EF802883E8820883EF80000
+B92B:7FA800A87FA840287FA800287FA805E8042800003E8802883EF820883EF80000
+B92C:7FA800A87FA840287FA800287FA805E8042800000F8800880F8808140FA20000
+B92D:7FA800A87FA840287FA800287FA805E8042800003EF802803EF820803EF80000
+B92E:7FA800A87FA840287FA800287FA805E8042800003EFC02483E4820483EFC0000
+B92F:7FA800A87FA840287FA800287FA805E8042800003E1002FE3E3820443E380000
+B930:7FA800A87FA840287FA800287FA805E80428000003F802080208020803F80000
+B931:7FA800A87FA840287FA800287FA805E8042800000208020803F8020803F80000
+B932:7FA800A87FA840287FA800287FA805E804280000210821083F0821143F620000
+B933:7FA800A87FA840287FA800287FA805E804280000001000100010006801840000
+B934:7FA800A87FA840287FA800287FA805E8042800000048004800A8011406620000
+B935:7FA800A87FA840287FA800287FA805E804280000000003F00408040803F00000
+B936:7FA800A87FA840287FA800287FA805E80428000003F80020002000D003080000
+B937:7FA800A87FA840287FA800287FA805E804280000004003F8004000A003180000
+B938:7FA800A87FA840287FA800287FA805E80428000003F8000803F8000800080000
+B939:7FA800A87FA840287FA800287FA805E80428000003F8020003F8020003F80000
+B93A:7FA800A87FA840287FA800287FA805E80428000000000FF8022002200FF80000
+B93B:7FA800A87FA840287FA800287FA805E80428000000800FF803E0041003E00000
+B93C:000000083FC8004800483FC8200820083FC800087FE804080408040804080000
+B93D:7F8800887F8840087F8800087FE8020802000000000007F80008000800080000
+B93E:7F8800887F8840087F8800087FE802080200000000003EF80208020802080000
+B93F:7F8800887F8840087F8800087FE802080200000000001F080108011401620000
+B940:7F8800887F8840087F88000800087FE80208020802081008100010001FF80000
+B941:7F8800887F8840087F8800087FE8020802000000000020F8201020303ECC0000
+B942:7F8800887F8840087F8800087FE8020802000000202021FC207020883E700000
+B943:7F8800887F8840087F8800087FE802080200000003F802000200020003F80000
+B944:7F8800887F8840087F8800087FE802080200000007F8000807F8040007F80000
+B945:7F8800887F8840087F8800087FE80208020000003EF802083E0820083E080000
+B946:7F8800887F8840087F8800087FE80208020000003EF802883E8820883EF80000
+B947:7F8800887F8840087F8800087FE80208020000003E8802883EF820883EF80000
+B948:7F8800887F8840087F8800087FE80208020000000F8800880F8808140FA20000
+B949:7F8800887F8840087F8800087FE80208020000003EF802803EF820803EF80000
+B94A:7F8800887F8840087F8800087FE80208020000003EFC02483E4820483EFC0000
+B94B:7F8800887F8840087F8800087FE80208020000003E1002FE3E3820443E380000
+B94C:7F8800887F8840087F8800087FE802080200000003F802080208020803F80000
+B94D:7F8800887F8840087F8800087FE80208020000000208020803F8020803F80000
+B94E:7F8800887F8840087F8800087FE8020802000000210821083F0821143F620000
+B94F:7F8800887F8840087F8800087FE8020802000000001000100010006801840000
+B950:7F8800887F8840087F8800087FE80208020000000048004800A8011406620000
+B951:7F8800887F8840087F8800087FE8020802000000000003F00408040803F00000
+B952:7F8800887F8840087F8800087FE802080200000003F80020002000D003080000
+B953:7F8800887F8840087F8800087FE8020802000000004003F8004000A003180000
+B954:7F8800887F8840087F8800087FE802080200000003F8000803F8000800080000
+B955:7F8800887F8840087F8800087FE802080200000003F8020003F8020003F80000
+B956:7F8800887F8840087F8800087FE802080200000000000FF8022002200FF80000
+B957:7F8800887F8840087F8800087FE802080200000000800FF803E0041003E00000
+B958:000000001FF0001000101FF0100010001FF000007FFC04400440044004400000
+B959:00001FF000101FF010001FF000007FFC044004401FF000100010001000100000
+B95A:00001FF000101FF010001FF000007FFC0440044000003EF80208020802080000
+B95B:00001FF000101FF010001FF000007FFC0440044000001E100210022802C40000
+B95C:00001FF000101FF010001FF0000000007FFC044004401440100010001FF00000
+B95D:00001FF000101FF010001FF000007FFC04400440000020F8201020303ECC0000
+B95E:00001FF000101FF010001FF000007FFC04400440202021FC207020883E700000
+B95F:00001FF000101FF010001FF000007FFC044004401FF01000100010001FF00000
+B960:00001FF000101FF010001FF000007FFC044004401FF000101FF010001FF00000
+B961:00001FF000101FF010001FF000007FFC044004403EF802083E0820083E080000
+B962:00001FF000101FF010001FF000007FFC044004403EF802883E8820883EF80000
+B963:00001FF000101FF010001FF000007FFC044004403E8802883EF820883EF80000
+B964:00001FF000101FF010001FF000007FFC044004403E1002103E1020283EC40000
+B965:00001FF000101FF010001FF000007FFC044004403EF802803EF820803EF80000
+B966:00001FF000101FF010001FF000007FFC044004403EFC02483E4820483EFC0000
+B967:00001FF000101FF010001FF000007FFC044004403E2003FC3E7020883E700000
+B968:00001FF000101FF010001FF000007FFC044004401FF01010101010101FF00000
+B969:00001FF000101FF010001FF000007FFC04400440101010101FF010101FF00000
+B96A:00001FF000101FF010001FF000007FFC04400440222022203E2022503E880000
+B96B:00001FF000101FF010001FF000007FFC0440044000000100010002800C400000
+B96C:00001FF000101FF010001FF000007FFC044004400000024002400DA033100000
+B96D:00001FF000101FF010001FF000007FFC04400440000007C00820082007C00000
+B96E:00001FF000101FF010001FF000007FFC04400440000007E00080014006200000
+B96F:00001FF000101FF010001FF000007FFC04400440008007E00080014006200000
+B970:00001FF000101FF010001FF000007FFC044004401FF000101FF0001000100000
+B971:00001FF000101FF010001FF000007FFC044004401FF010001FF010001FF00000
+B972:00001FF000101FF010001FF000007FFC0440044000001FF0044004401FF00000
+B973:00001FF000101FF010001FF000007FFC0440044001001FF007C0082007C00000
+B974:000000001FF0001000101FF0100010001FF0000000007FFC0000000000000000
+B975:00001FF000101FF010001FF0000000007FFC00001FF000100010001000100000
+B976:00001FF000101FF010001FF0000000007FFC000000003EF80208020802080000
+B977:00001FF000101FF010001FF0000000007FFC000000001E100210022802C40000
+B978:00001FF000101FF010001FF0000000007FFC000000001000100010001FF00000
+B979:00001FF000101FF010001FF0000000007FFC0000000020F8201020303ECC0000
+B97A:00001FF000101FF010001FF0000000007FFC0000202021FC207020883E700000
+B97B:00001FF000101FF010001FF0000000007FFC00001FF01000100010001FF00000
+B97C:00001FF000101FF010001FF0000000007FFC00001FF000101FF010001FF00000
+B97D:00001FF000101FF010001FF0000000007FFC00003EF802083E0820083E080000
+B97E:00001FF000101FF010001FF0000000007FFC00003EF802883E8820883EF80000
+B97F:00001FF000101FF010001FF0000000007FFC00003E8802883EF820883EF80000
+B980:00001FF000101FF010001FF0000000007FFC00003E1002103E1020283EC40000
+B981:00001FF000101FF010001FF0000000007FFC00003EF802803EF820803EF80000
+B982:00001FF000101FF010001FF0000000007FFC00003EFC02483E4820483EFC0000
+B983:00001FF000101FF010001FF0000000007FFC00003E2003FC3E7020883E700000
+B984:00001FF000101FF010001FF0000000007FFC00001FF01010101010101FF00000
+B985:00001FF000101FF010001FF0000000007FFC0000101010101FF010101FF00000
+B986:00001FF000101FF010001FF0000000007FFC0000222022203E2022503E880000
+B987:00001FF000101FF010001FF0000000007FFC000000000100010002800C400000
+B988:00001FF000101FF010001FF0000000007FFC00000000024002400DA033100000
+B989:00001FF000101FF010001FF0000000007FFC0000000007C00820082007C00000
+B98A:00001FF000101FF010001FF0000000007FFC0000000007E00080014006200000
+B98B:00001FF000101FF010001FF0000000007FFC0000008007E00080014006200000
+B98C:00001FF000101FF010001FF0000000007FFC00001FF000101FF0001000100000
+B98D:00001FF000101FF010001FF0000000007FFC00001FF010001FF010001FF00000
+B98E:00001FF000101FF010001FF0000000007FFC000000001FF0044004401FF00000
+B98F:00001FF000101FF010001FF0000000007FFC000001001FF007C0082007C00000
+B990:0000000800083F88008800883F88200820083F8800087FE80008000800080000
+B991:000000083F8800883F8820083F8800087FE8000007F800080008000800080000
+B992:000000083F8800883F8820083F8800087FE8000000003EF80208020802080000
+B993:000000083F8800883F8820083F8800087FE8000000001F080108011401620000
+B994:000000083F8800883F8820083F8800087FE8000008000800080008000FF80000
+B995:000000083F8800883F8820083F8800087FE80000000010F8101010301ECC0000
+B996:000000083F8800883F8820083F8800087FE800000808087F081C08220F9C0000
+B997:000000083F8800883F8820083F8800087FE8000003F802000200020003F80000
+B998:000000083F8800883F8820083F8800087FE8000007F8000807F8040007F80000
+B999:000000083F8800883F8820083F8800087FE800003EF802083E0820083E080000
+B99A:000000083F8800883F8820083F8800087FE800003EF802883E8820883EF80000
+B99B:000000083F8800883F8820083F8800087FE800003E8802883EF820883EF80000
+B99C:000000083F8800883F8820083F8800087FE800001F0801081F0810141F620000
+B99D:000000083F8800883F8820083F8800087FE800003EF802803EF820803EF80000
+B99E:000000083F8800883F8820083F8800087FE800003EFC02483E4820483EFC0000
+B99F:000000083F8800883F8820083F8800087FE800001F08017F1F1C10221F1C0000
+B9A0:000000083F8800883F8820083F8800087FE8000003F802080208020803F80000
+B9A1:000000083F8800883F8820083F8800087FE800000208020803F8020803F80000
+B9A2:000000083F8800883F8820083F8800087FE80000110811081F0811141F620000
+B9A3:000000083F8800883F8820083F8800087FE80000001000100010006801840000
+B9A4:000000083F8800883F8820083F8800087FE800000048004800A8011406620000
+B9A5:000000083F8800883F8820083F8800087FE80000000003F00408040803F00000
+B9A6:000000083F8800883F8820083F8800087FE8000003F80020002000D003080000
+B9A7:000000083F8800883F8820083F8800087FE80000004003F8004000A003180000
+B9A8:000000083F8800883F8820083F8800087FE8000003F8000803F8000800080000
+B9A9:000000083F8800883F8820083F8800087FE8000003F8020003F8020003F80000
+B9AA:000000083F8800883F8820083F8800087FE8000000000FF8022002200FF80000
+B9AB:000000083F8800883F8820083F8800087FE8000000800FF803E0041003E00000
+B9AC:00000000000800083F88008800883F882008200820083F880008000800080000
+B9AD:0000000800083F0801083F0820083F0800080000000007F80008000800080000
+B9AE:0000000800083F0801083F0820083F080008000000003EF80208020802080000
+B9AF:0000000800083F0801083F0820083F080008000000001F080108011401620000
+B9B0:0000000800083F0801083F0820083F080008000800001000100010001FF80000
+B9B1:0000000800083F0801083F0820083F0800080000000020F8201020303ECC0000
+B9B2:0000000800083F0801083F0820083F0800080000202021FC207020883E700000
+B9B3:0000000800083F0801083F0820083F080008000003F802000200020003F80000
+B9B4:0000000800083F0801083F0820083F080008000007F8000807F8040007F80000
+B9B5:0000000800083F0801083F0820083F08000800003EF802083E0820083E080000
+B9B6:0000000800083F0801083F0820083F08000800003EF802883E8820883EF80000
+B9B7:0000000800083F0801083F0820083F08000800003E8802883EF820883EF80000
+B9B8:0000000800083F0801083F0820083F08000800000F8800880F8808140FA20000
+B9B9:0000000800083F0801083F0820083F08000800003EF802803EF820803EF80000
+B9BA:0000000800083F0801083F0820083F08000800003EFC02483E4820483EFC0000
+B9BB:0000000800083F0801083F0820083F08000800003E1002FE3E3820443E380000
+B9BC:0000000800083F0801083F0820083F080008000003F802080208020803F80000
+B9BD:0000000800083F0801083F0820083F08000800000208020803F8020803F80000
+B9BE:0000000800083F0801083F0820083F0800080000210821083F0821143F620000
+B9BF:0000000800083F0801083F0820083F0800080000001000100010006801840000
+B9C0:0000000800083F0801083F0820083F08000800000048004800A8011406620000
+B9C1:0000000800083F0801083F0820083F0800080000000003F00408040803F00000
+B9C2:0000000800083F0801083F0820083F080008000003F80020002000D003080000
+B9C3:0000000800083F0801083F0820083F0800080000004003F8004000A003180000
+B9C4:0000000800083F0801083F0820083F080008000003F8000803F8000800080000
+B9C5:0000000800083F0801083F0820083F080008000003F8020003F8020003F80000
+B9C6:0000000800083F0801083F0820083F080008000000000FF8022002200FF80000
+B9C7:0000000800083F0801083F0820083F080008000000800FF803E0041003E00000
+B9C8:00000000001000107F9040904090409E4090409040907F900010001000100000
+B9C9:000000087E0842084208420E42087E080008000007F800080008000800080000
+B9CA:000000087E0842084208420E42087E080008000000003EF80208020802080000
+B9CB:000000087E0842084208420E42087E080008000000001F080108011401620000
+B9CC:000000087E0842084208420E42087E080008000808000800080008000FF80000
+B9CD:000000087E0842084208420E42087E0800080000000010F8101010301ECC0000
+B9CE:000000087E0842084208420E42087E08000800000808087F081C08220F9C0000
+B9CF:000000087E0842084208420E42087E080008000003F802000200020003F80000
+B9D0:000000087E0842084208420E42087E080008000007F8000807F8040007F80000
+B9D1:000000087E0842084208420E42087E08000800003EF802083E0820083E080000
+B9D2:000000087E0842084208420E42087E08000800003EF802883E8820883EF80000
+B9D3:000000087E0842084208420E42087E08000800003E8802883EF820883EF80000
+B9D4:000000087E0842084208420E42087E08000800001F0801081F0810141F620000
+B9D5:000000087E0842084208420E42087E08000800003EF802803EF820803EF80000
+B9D6:000000087E0842084208420E42087E08000800003EFC02483E4820483EFC0000
+B9D7:000000087E0842084208420E42087E08000800001F08017F1F1C10221F1C0000
+B9D8:000000087E0842084208420E42087E080008000003F802080208020803F80000
+B9D9:000000087E0842084208420E42087E08000800000208020803F8020803F80000
+B9DA:000000087E0842084208420E42087E0800080000110811081F0811141F620000
+B9DB:000000087E0842084208420E42087E0800080000001000100010006801840000
+B9DC:000000087E0842084208420E42087E08000800000048004800A8011406620000
+B9DD:000000087E0842084208420E42087E0800080000000003F00408040803F00000
+B9DE:000000087E0842084208420E42087E080008000003F80020002000D003080000
+B9DF:000000087E0842084208420E42087E0800080000004003F8004000A003180000
+B9E0:000000087E0842084208420E42087E080008000003F8000803F8000800080000
+B9E1:000000087E0842084208420E42087E080008000003F8020003F8020003F80000
+B9E2:000000087E0842084208420E42087E080008000000000FF8022002200FF80000
+B9E3:000000087E0842084208420E42087E080008000000800FF803E0041003E00000
+B9E4:00000000001200127F9240924092409E4092409240927F920012001200120000
+B9E5:000000287E2842284228423842287E280028000007F800080008000800080000
+B9E6:000000287E2842284228423842287E280028000000003EF80208020802080000
+B9E7:000000287E2842284228423842287E280028000000003E100210022802C40000
+B9E8:000000287E2842284228423842287E280028002808000800080008000FF80000
+B9E9:000000287E2842284228423842287E2800280000000020F8201020303ECC0000
+B9EA:000000287E2842284228423842287E2800280000202021FC207020883E700000
+B9EB:000000287E2842284228423842287E280028000003F802000200020003F80000
+B9EC:000000287E2842284228423842287E280028000007F8000807F8040007F80000
+B9ED:000000287E2842284228423842287E28002800003EF802083E0820083E080000
+B9EE:000000287E2842284228423842287E28002800003EF802883E8820883EF80000
+B9EF:000000287E2842284228423842287E28002800003E8802883EF820883EF80000
+B9F0:000000287E2842284228423842287E28002800001F0801081F0810141F620000
+B9F1:000000287E2842284228423842287E28002800003EF802803EF820803EF80000
+B9F2:000000287E2842284228423842287E28002800003EFC02483E4820483EFC0000
+B9F3:000000287E2842284228423842287E28002800003E1002FE3E3820443E380000
+B9F4:000000287E2842284228423842287E280028000003F802080208020803F80000
+B9F5:000000287E2842284228423842287E28002800000208020803F8020803F80000
+B9F6:000000287E2842284228423842287E2800280000110811081F0811141F620000
+B9F7:000000287E2842284228423842287E2800280000000800080008003400C20000
+B9F8:000000287E2842284228423842287E28002800000048004800A8011406620000
+B9F9:000000287E2842284228423842287E2800280000000001F00208020801F00000
+B9FA:000000287E2842284228423842287E280028000003F80020002000D003080000
+B9FB:000000287E2842284228423842287E2800280000004003F8004000A003180000
+B9FC:000000287E2842284228423842287E280028000003F8000803F8000800080000
+B9FD:000000287E2842284228423842287E280028000003F8020003F8020003F80000
+B9FE:000000287E2842284228423842287E280028000000000FF8022002200FF80000
+B9FF:000000287E2842284228423842287E280028000000800FF803E0041003E00000
+BA00:00000000001000107F904090409E40904090409E40907F900010001000100000
+BA01:000000087E084208420E4208420E7E080008000007F800080008000800080000
+BA02:000000087E084208420E4208420E7E080008000000003EF80208020802080000
+BA03:000000087E084208420E4208420E7E080008000000001F080108011401620000
+BA04:000000087E084208420E4208420E7E080008000008000800080008000FF80000
+BA05:000000087E084208420E4208420E7E0800080000000010F8101010301ECC0000
+BA06:000000087E084208420E4208420E7E08000800000808087F081C08220F9C0000
+BA07:000000087E084208420E4208420E7E080008000003F802000200020003F80000
+BA08:000000087E084208420E4208420E7E080008000007F8000807F8040007F80000
+BA09:000000087E084208420E4208420E7E08000800003EF802083E0820083E080000
+BA0A:000000087E084208420E4208420E7E08000800003EF802883E8820883EF80000
+BA0B:000000087E084208420E4208420E7E08000800003E8802883EF820883EF80000
+BA0C:000000087E084208420E4208420E7E08000800001F0801081F0810141F620000
+BA0D:000000087E084208420E4208420E7E08000800003EF802803EF820803EF80000
+BA0E:000000087E084208420E4208420E7E08000800003EFC02483E4820483EFC0000
+BA0F:000000087E084208420E4208420E7E08000800001F08017F1F1C10221F1C0000
+BA10:000000087E084208420E4208420E7E080008000003F802080208020803F80000
+BA11:000000087E084208420E4208420E7E08000800000208020803F8020803F80000
+BA12:000000087E084208420E4208420E7E0800080000110811081F0811141F620000
+BA13:000000087E084208420E4208420E7E0800080000001000100010006801840000
+BA14:000000087E084208420E4208420E7E08000800000048004800A8011406620000
+BA15:000000087E084208420E4208420E7E0800080000000003F00408040803F00000
+BA16:000000087E084208420E4208420E7E080008000003F80020002000D003080000
+BA17:000000087E084208420E4208420E7E0800080000004003F8004000A003180000
+BA18:000000087E084208420E4208420E7E080008000003F8000803F8000800080000
+BA19:000000087E084208420E4208420E7E080008000003F8020003F8020003F80000
+BA1A:000000087E084208420E4208420E7E080008000000000FF8022002200FF80000
+BA1B:000000087E084208420E4208420E7E080008000000800FF803E0041003E00000
+BA1C:00000000001200127F924092409E40924092409E40927F920012001200120000
+BA1D:000000287E2842284238422842387E280028000007F800080008000800080000
+BA1E:000000287E2842284238422842387E280028000000003EF80208020802080000
+BA1F:000000287E2842284238422842387E280028000000003E100210022802C40000
+BA20:000000287E2842284238422842387E280028002808000800080008000FF80000
+BA21:000000287E2842284238422842387E2800280000000020F8201020303ECC0000
+BA22:000000287E2842284238422842387E2800280000202021FC207020883E700000
+BA23:000000287E2842284238422842387E280028000003F802000200020003F80000
+BA24:000000287E2842284238422842387E280028000007F8000807F8040007F80000
+BA25:000000287E2842284238422842387E28002800003EF802083E0820083E080000
+BA26:000000287E2842284238422842387E28002800003EF802883E8820883EF80000
+BA27:000000287E2842284238422842387E28002800003E8802883EF820883EF80000
+BA28:000000287E2842284238422842387E28002800001F0801081F0810141F620000
+BA29:000000287E2842284238422842387E28002800003EF802803EF820803EF80000
+BA2A:000000287E2842284238422842387E28002800003EFC02483E4820483EFC0000
+BA2B:000000287E2842284238422842387E28002800003E1002FE3E3820443E380000
+BA2C:000000287E2842284238422842387E280028000003F802080208020803F80000
+BA2D:000000287E2842284238422842387E28002800000208020803F8020803F80000
+BA2E:000000287E2842284238422842387E2800280000110811081F0811141F620000
+BA2F:000000287E2842284238422842387E2800280000000800080008003400C20000
+BA30:000000287E2842284238422842387E28002800000048004800A8011406620000
+BA31:000000287E2842284238422842387E2800280000000001F00208020801F00000
+BA32:000000287E2842284238422842387E280028000003F80020002000D003080000
+BA33:000000287E2842284238422842387E2800280000004003F8004000A003180000
+BA34:000000287E2842284238422842387E280028000003F8000803F8000800080000
+BA35:000000287E2842284238422842387E280028000003F8020003F8020003F80000
+BA36:000000287E2842284238422842387E280028000000000FF8022002200FF80000
+BA37:000000287E2842284238422842387E280028000000800FF803E0041003E00000
+BA38:00000000000200027F8240824082409E4082408240827F820002000200020000
+BA39:000000087E0842084208423842087E0800080000000007F80008000800080000
+BA3A:000000087E0842084208423842087E080008000000003EF80208020802080000
+BA3B:000000087E0842084208423842087E080008000000001F080108011401620000
+BA3C:000000087E0842084208423842087E080008000000001000100010001FF80000
+BA3D:000000087E0842084208423842087E0800080000000020F8201020303ECC0000
+BA3E:000000087E0842084208423842087E0800080000202021FC207020883E700000
+BA3F:000000087E0842084208423842087E080008000003F802000200020003F80000
+BA40:000000087E0842084208423842087E080008000007F8000807F8040007F80000
+BA41:000000087E0842084208423842087E08000800003EF802083E0820083E080000
+BA42:000000087E0842084208423842087E08000800003EF802883E8820883EF80000
+BA43:000000087E0842084208423842087E08000800003E8802883EF820883EF80000
+BA44:000000087E0842084208423842087E08000800000F8800880F8808140FA20000
+BA45:000000087E0842084208423842087E08000800003EF802803EF820803EF80000
+BA46:000000087E0842084208423842087E08000800003EFC02483E4820483EFC0000
+BA47:000000087E0842084208423842087E08000800003E1002FE3E3820443E380000
+BA48:000000087E0842084208423842087E080008000003F802080208020803F80000
+BA49:000000087E0842084208423842087E08000800000208020803F8020803F80000
+BA4A:000000087E0842084208423842087E0800080000210821083F0821143F620000
+BA4B:000000087E0842084208423842087E0800080000001000100010006801840000
+BA4C:000000087E0842084208423842087E08000800000048004800A8011406620000
+BA4D:000000087E0842084208423842087E0800080000000003F00408040803F00000
+BA4E:000000087E0842084208423842087E080008000003F80020002000D003080000
+BA4F:000000087E0842084208423842087E0800080000004003F8004000A003180000
+BA50:000000087E0842084208423842087E080008000003F8000803F8000800080000
+BA51:000000087E0842084208423842087E080008000003F8020003F8020003F80000
+BA52:000000087E0842084208423842087E080008000000000FF8022002200FF80000
+BA53:000000087E0842084208423842087E080008000000800FF803E0041003E00000
+BA54:00000000000A000A7F8A408A408A40BA408A408A408A7F8A000A000A000A0000
+BA55:000000287E284228422842E842287E280028000007F800080008000800080000
+BA56:000000287E284228422842E842287E280028000000003EF80208020802080000
+BA57:000000287E284228422842E842287E280028000000003E100210022802C40000
+BA58:000000287E284228422842E842287E280028000008000800080008000FF80000
+BA59:000000287E284228422842E842287E2800280000000020F8201020303ECC0000
+BA5A:000000287E284228422842E842287E2800280000202021FC207020883E700000
+BA5B:000000287E284228422842E842287E280028000003F802000200020003F80000
+BA5C:000000287E284228422842E842287E280028000007F8000807F8040007F80000
+BA5D:000000287E284228422842E842287E28002800003EF802083E0820083E080000
+BA5E:000000287E284228422842E842287E28002800003EF802883E8820883EF80000
+BA5F:000000287E284228422842E842287E28002800003E8802883EF820883EF80000
+BA60:000000287E284228422842E842287E28002800001F0801081F0810141F620000
+BA61:000000287E284228422842E842287E28002800003EF802803EF820803EF80000
+BA62:000000287E284228422842E842287E28002800003EFC02483E4820483EFC0000
+BA63:000000287E284228422842E842287E28002800003E1002FE3E3820443E380000
+BA64:000000287E284228422842E842287E280028000003F802080208020803F80000
+BA65:000000287E284228422842E842287E28002800000208020803F8020803F80000
+BA66:000000287E284228422842E842287E2800280000110811081F0811141F620000
+BA67:000000287E284228422842E842287E2800280000000800080008003400C20000
+BA68:000000287E284228422842E842287E28002800000048004800A8011406620000
+BA69:000000287E284228422842E842287E2800280000000001F00208020801F00000
+BA6A:000000287E284228422842E842287E280028000003F80020002000D003080000
+BA6B:000000287E284228422842E842287E2800280000004003F8004000A003180000
+BA6C:000000287E284228422842E842287E280028000003F8000803F8000800080000
+BA6D:000000287E284228422842E842287E280028000003F8020003F8020003F80000
+BA6E:000000287E284228422842E842287E280028000000000FF8022002200FF80000
+BA6F:000000287E284228422842E842287E280028000000800FF803E0041003E00000
+BA70:00000000000200027F824082409E40824082409E40827F820002000200020000
+BA71:000000087E0842084238420842387E0800080000000007F80008000800080000
+BA72:000000087E0842084238420842387E080008000000003EF80208020802080000
+BA73:000000087E0842084238420842387E080008000000001F080108011401620000
+BA74:000000087E0842084238420842387E080008000800001000100010001FF80000
+BA75:000000087E0842084238420842387E0800080000000020F8201020303ECC0000
+BA76:000000087E0842084238420842387E0800080000202021FC207020883E700000
+BA77:000000087E0842084238420842387E080008000003F802000200020003F80000
+BA78:000000087E0842084238420842387E080008000007F8000807F8040007F80000
+BA79:000000087E0842084238420842387E08000800003EF802083E0820083E080000
+BA7A:000000087E0842084238420842387E08000800003EF802883E8820883EF80000
+BA7B:000000087E0842084238420842387E08000800003E8802883EF820883EF80000
+BA7C:000000087E0842084238420842387E08000800000F8800880F8808140FA20000
+BA7D:000000087E0842084238420842387E08000800003EF802803EF820803EF80000
+BA7E:000000087E0842084238420842387E08000800003EFC02483E4820483EFC0000
+BA7F:000000087E0842084238420842387E08000800003E1002FE3E3820443E380000
+BA80:000000087E0842084238420842387E080008000003F802080208020803F80000
+BA81:000000087E0842084238420842387E08000800000208020803F8020803F80000
+BA82:000000087E0842084238420842387E0800080000210821083F0821143F620000
+BA83:000000087E0842084238420842387E0800080000001000100010006801840000
+BA84:000000087E0842084238420842387E08000800000048004800A8011406620000
+BA85:000000087E0842084238420842387E0800080000000003F00408040803F00000
+BA86:000000087E0842084238420842387E080008000003F80020002000D003080000
+BA87:000000087E0842084238420842387E0800080000004003F8004000A003180000
+BA88:000000087E0842084238420842387E080008000003F8000803F8000800080000
+BA89:000000087E0842084238420842387E080008000003F8020003F8020003F80000
+BA8A:000000087E0842084238420842387E080008000000000FF8022002200FF80000
+BA8B:000000087E0842084238420842387E080008000000800FF803E0041003E00000
+BA8C:00000000000A000A7F8A408A40BA408A408A40BA408A7F8A000A000A000A0000
+BA8D:000000287E28422842E8422842E87E280028000007F800080008000800080000
+BA8E:000000287E28422842E8422842E87E280028000000003EF80208020802080000
+BA8F:000000287E28422842E8422842E87E280028000000003E100210022802C40000
+BA90:000000287E28422842E8422842E87E280028002808000800080008000FF80000
+BA91:000000287E28422842E8422842E87E2800280000000020F8201020303ECC0000
+BA92:000000287E28422842E8422842E87E2800280000202021FC207020883E700000
+BA93:000000287E28422842E8422842E87E280028000003F802000200020003F80000
+BA94:000000287E28422842E8422842E87E280028000007F8000807F8040007F80000
+BA95:000000287E28422842E8422842E87E28002800003EF802083E0820083E080000
+BA96:000000287E28422842E8422842E87E28002800003EF802883E8820883EF80000
+BA97:000000287E28422842E8422842E87E28002800003E8802883EF820883EF80000
+BA98:000000287E28422842E8422842E87E28002800001F0801081F0810141F620000
+BA99:000000287E28422842E8422842E87E28002800003EF802803EF820803EF80000
+BA9A:000000287E28422842E8422842E87E28002800003EFC02483E4820483EFC0000
+BA9B:000000287E28422842E8422842E87E28002800003E1002FE3E3820443E380000
+BA9C:000000287E28422842E8422842E87E280028000003F802080208020803F80000
+BA9D:000000287E28422842E8422842E87E28002800000208020803F8020803F80000
+BA9E:000000287E28422842E8422842E87E2800280000110811081F0811141F620000
+BA9F:000000287E28422842E8422842E87E2800280000000800080008003400C20000
+BAA0:000000287E28422842E8422842E87E28002800000048004800A8011406620000
+BAA1:000000287E28422842E8422842E87E2800280000000001F00208020801F00000
+BAA2:000000287E28422842E8422842E87E280028000003F80020002000D003080000
+BAA3:000000287E28422842E8422842E87E2800280000004003F8004000A003180000
+BAA4:000000287E28422842E8422842E87E280028000003F8000803F8000800080000
+BAA5:000000287E28422842E8422842E87E280028000003F8020003F8020003F80000
+BAA6:000000287E28422842E8422842E87E280028000000000FF8022002200FF80000
+BAA7:000000287E28422842E8422842E87E280028000000800FF803E0041003E00000
+BAA8:000000003FF820082008200820083FF8000000000100010001007FFC00000000
+BAA9:00001FF01010101010101FF0010001007FFC00001FF000100010001000100000
+BAAA:00001FF01010101010101FF0010001007FFC000000003EF80208020802080000
+BAAB:00001FF01010101010101FF0010001007FFC000000001E100210022802C40000
+BAAC:00001FF01010101010101FF0010001007FFC000000001000100010001FF00000
+BAAD:00001FF01010101010101FF0010001007FFC0000000020F8201020303ECC0000
+BAAE:00001FF01010101010101FF0010001007FFC0000202021FC207020883E700000
+BAAF:00001FF01010101010101FF0010001007FFC00001FF01000100010001FF00000
+BAB0:00001FF01010101010101FF0010001007FFC00001FF000101FF010001FF00000
+BAB1:00001FF01010101010101FF0010001007FFC00003EF802083E0820083E080000
+BAB2:00001FF01010101010101FF0010001007FFC00003EF802883E8820883EF80000
+BAB3:00001FF01010101010101FF0010001007FFC00003E8802883EF820883EF80000
+BAB4:00001FF01010101010101FF0010001007FFC00003E1002103E1020283EC40000
+BAB5:00001FF01010101010101FF0010001007FFC00003EF802803EF820803EF80000
+BAB6:00001FF01010101010101FF0010001007FFC00003EFC02483E4820483EFC0000
+BAB7:00001FF01010101010101FF0010001007FFC00003E2003FC3E7020883E700000
+BAB8:00001FF01010101010101FF0010001007FFC00001FF01010101010101FF00000
+BAB9:00001FF01010101010101FF0010001007FFC0000101010101FF010101FF00000
+BABA:00001FF01010101010101FF0010001007FFC0000222022203E2022503E880000
+BABB:00001FF01010101010101FF0010001007FFC000000000100010002800C400000
+BABC:00001FF01010101010101FF0010001007FFC00000000024002400DA033100000
+BABD:00001FF01010101010101FF0010001007FFC0000000007C00820082007C00000
+BABE:00001FF01010101010101FF0010001007FFC0000000007E00080014006200000
+BABF:00001FF01010101010101FF0010001007FFC0000008007E00080014006200000
+BAC0:00001FF01010101010101FF0010001007FFC00001FF000101FF0001000100000
+BAC1:00001FF01010101010101FF0010001007FFC00001FF010001FF010001FF00000
+BAC2:00001FF01010101010101FF0010001007FFC000000001FF0044004401FF00000
+BAC3:00001FF01010101010101FF0010001007FFC000001001FF007C0082007C00000
+BAC4:0000001000103F90209020902090209E20903F90041004107FD0001000100000
+BAC5:000000083F882088208E20883F8804087FE8000007F800080008000800080000
+BAC6:000000083F882088208E20883F8804087FE8000000003EF80208020802080000
+BAC7:000000083F882088208E20883F8804087FE8000000001F080108011401620000
+BAC8:000000083F882088208E20883F8804087FE8000008000800080008000FF80000
+BAC9:000000083F882088208E20883F8804087FE80000000010F8101010301ECC0000
+BACA:000000083F882088208E20883F8804087FE800000808087F081C08220F9C0000
+BACB:000000083F882088208E20883F8804087FE8000003F802000200020003F80000
+BACC:000000083F882088208E20883F8804087FE8000007F8000807F8040007F80000
+BACD:000000083F882088208E20883F8804087FE800003EF802083E0820083E080000
+BACE:000000083F882088208E20883F8804087FE800003EF802883E8820883EF80000
+BACF:000000083F882088208E20883F8804087FE800003E8802883EF820883EF80000
+BAD0:000000083F882088208E20883F8804087FE800001F0801081F0810141F620000
+BAD1:000000083F882088208E20883F8804087FE800003EF802803EF820803EF80000
+BAD2:000000083F882088208E20883F8804087FE800003EFC02483E4820483EFC0000
+BAD3:000000083F882088208E20883F8804087FE800001F08017F1F1C10221F1C0000
+BAD4:000000083F882088208E20883F8804087FE8000003F802080208020803F80000
+BAD5:000000083F882088208E20883F8804087FE800000208020803F8020803F80000
+BAD6:000000083F882088208E20883F8804087FE80000110811081F0811141F620000
+BAD7:000000083F882088208E20883F8804087FE80000001000100010006801840000
+BAD8:000000083F882088208E20883F8804087FE800000048004800A8011406620000
+BAD9:000000083F882088208E20883F8804087FE80000000003F00408040803F00000
+BADA:000000083F882088208E20883F8804087FE8000003F80020002000D003080000
+BADB:000000083F882088208E20883F8804087FE80000004003F8004000A003180000
+BADC:000000083F882088208E20883F8804087FE8000003F8000803F8000800080000
+BADD:000000083F882088208E20883F8804087FE8000003F8020003F8020003F80000
+BADE:000000083F882088208E20883F8804087FE8000000000FF8022002200FF80000
+BADF:000000083F882088208E20883F8804087FE8000000800FF803E0041003E00000
+BAE0:0000001200123F92209220922092209E20923F92041204127FD2001200120000
+BAE1:000000283FA820A820B820A83FA804287FA8000007F800080008000800080000
+BAE2:000000283FA820A820B820A83FA804287FA8000000003EF80208020802080000
+BAE3:000000283FA820A820B820A83FA804287FA8000000001F080108011401620000
+BAE4:000000283FA820A820B820A83FA804287FA8000008000800080008000FF80000
+BAE5:000000283FA820A820B820A83FA804287FA80000000010F8101010301ECC0000
+BAE6:000000283FA820A820B820A83FA804287FA800000808087F081C08220F9C0000
+BAE7:000000283FA820A820B820A83FA804287FA8000003F802000200020003F80000
+BAE8:000000283FA820A820B820A83FA804287FA8000007F8000807F8040007F80000
+BAE9:000000283FA820A820B820A83FA804287FA800003EF802083E0820083E080000
+BAEA:000000283FA820A820B820A83FA804287FA800003EF802883E8820883EF80000
+BAEB:000000283FA820A820B820A83FA804287FA800003E8802883EF820883EF80000
+BAEC:000000283FA820A820B820A83FA804287FA800001F0801081F0810141F620000
+BAED:000000283FA820A820B820A83FA804287FA800003EF802803EF820803EF80000
+BAEE:000000283FA820A820B820A83FA804287FA800003EFC02483E4820483EFC0000
+BAEF:000000283FA820A820B820A83FA804287FA800001F08017F1F1C10221F1C0000
+BAF0:000000283FA820A820B820A83FA804287FA8000003F802080208020803F80000
+BAF1:000000283FA820A820B820A83FA804287FA800000208020803F8020803F80000
+BAF2:000000283FA820A820B820A83FA804287FA80000110811081F0811141F620000
+BAF3:000000283FA820A820B820A83FA804287FA80000001000100010006801840000
+BAF4:000000283FA820A820B820A83FA804287FA800000048004800A8011406620000
+BAF5:000000283FA820A820B820A83FA804287FA80000000003F00408040803F00000
+BAF6:000000283FA820A820B820A83FA804287FA8000003F80020002000D003080000
+BAF7:000000283FA820A820B820A83FA804287FA80000004003F8004000A003180000
+BAF8:000000283FA820A820B820A83FA804287FA8000003F8000803F8000800080000
+BAF9:000000283FA820A820B820A83FA804287FA8000003F8020003F8020003F80000
+BAFA:000000283FA820A820B820A83FA804287FA8000000000FF8022002200FF80000
+BAFB:000000283FA820A820B820A83FA804287FA8000000800FF803E0041003E00000
+BAFC:0000000800083F88208820882088208820883F88040804087FE8000800080000
+BAFD:000000083F882088208820883F8804087FE8000007F800080008000800080000
+BAFE:000000083F882088208820883F8804087FE8000000003EF80208020802080000
+BAFF:000000083F882088208820883F8804087FE8000000001F080108011401620000
+BB00:000000083F882088208820883F8804087FE8000008000800080008000FF80000
+BB01:000000083F882088208820883F8804087FE80000000010F8101010301ECC0000
+BB02:000000083F882088208820883F8804087FE800000808087F081C08220F9C0000
+BB03:000000083F882088208820883F8804087FE8000003F802000200020003F80000
+BB04:000000083F882088208820883F8804087FE8000007F8000807F8040007F80000
+BB05:000000083F882088208820883F8804087FE800003EF802083E0820083E080000
+BB06:000000083F882088208820883F8804087FE800003EF802883E8820883EF80000
+BB07:000000083F882088208820883F8804087FE800003E8802883EF820883EF80000
+BB08:000000083F882088208820883F8804087FE800001F0801081F0810141F620000
+BB09:000000083F882088208820883F8804087FE800003EF802803EF820803EF80000
+BB0A:000000083F882088208820883F8804087FE800003EFC02483E4820483EFC0000
+BB0B:000000083F882088208820883F8804087FE800001F08017F1F1C10221F1C0000
+BB0C:000000083F882088208820883F8804087FE8000003F802080208020803F80000
+BB0D:000000083F882088208820883F8804087FE800000208020803F8020803F80000
+BB0E:000000083F882088208820883F8804087FE80000110811081F0811141F620000
+BB0F:000000083F882088208820883F8804087FE80000001000100010006801840000
+BB10:000000083F882088208820883F8804087FE800000048004800A8011406620000
+BB11:000000083F882088208820883F8804087FE80000000003F00408040803F00000
+BB12:000000083F882088208820883F8804087FE8000003F80020002000D003080000
+BB13:000000083F882088208820883F8804087FE80000004003F8004000A003180000
+BB14:000000083F882088208820883F8804087FE8000003F8000803F8000800080000
+BB15:000000083F882088208820883F8804087FE8000003F8020003F8020003F80000
+BB16:000000083F882088208820883F8804087FE8000000000FF8022002200FF80000
+BB17:000000083F882088208820883F8804087FE8000000800FF803E0041003E00000
+BB18:000000003FF820082008200820083FF8000004400440044004407FFC00000000
+BB19:00001FF01010101010101FF0044004407FFC00001FF000100010001000100000
+BB1A:00001FF01010101010101FF0044004407FFC000000003EF80208020802080000
+BB1B:00001FF01010101010101FF0044004407FFC000000001E100210022802C40000
+BB1C:00001FF01010101010101FF0044004407FFC000000001000100010001FF00000
+BB1D:00001FF01010101010101FF0044004407FFC0000000020F8201020303ECC0000
+BB1E:00001FF01010101010101FF0044004407FFC0000202021FC207020883E700000
+BB1F:00001FF01010101010101FF0044004407FFC00001FF01000100010001FF00000
+BB20:00001FF01010101010101FF0044004407FFC00001FF000101FF010001FF00000
+BB21:00001FF01010101010101FF0044004407FFC00003EF802083E0820083E080000
+BB22:00001FF01010101010101FF0044004407FFC00003EF802883E8820883EF80000
+BB23:00001FF01010101010101FF0044004407FFC00003E8802883EF820883EF80000
+BB24:00001FF01010101010101FF0044004407FFC00003E1002103E1020283EC40000
+BB25:00001FF01010101010101FF0044004407FFC00003EF802803EF820803EF80000
+BB26:00001FF01010101010101FF0044004407FFC00003EFC02483E4820483EFC0000
+BB27:00001FF01010101010101FF0044004407FFC00003E2003FC3E7020883E700000
+BB28:00001FF01010101010101FF0044004407FFC00001FF01010101010101FF00000
+BB29:00001FF01010101010101FF0044004407FFC0000101010101FF010101FF00000
+BB2A:00001FF01010101010101FF0044004407FFC0000222022203E2022503E880000
+BB2B:00001FF01010101010101FF0044004407FFC000000000100010002800C400000
+BB2C:00001FF01010101010101FF0044004407FFC00000000024002400DA033100000
+BB2D:00001FF01010101010101FF0044004407FFC0000000007C00820082007C00000
+BB2E:00001FF01010101010101FF0044004407FFC0000000007E00080014006200000
+BB2F:00001FF01010101010101FF0044004407FFC0000008007E00080014006200000
+BB30:00001FF01010101010101FF0044004407FFC00001FF000101FF0001000100000
+BB31:00001FF01010101010101FF0044004407FFC00001FF010001FF010001FF00000
+BB32:00001FF01010101010101FF0044004407FFC000000001FF0044004401FF00000
+BB33:00001FF01010101010101FF0044004407FFC000001001FF007C0082007C00000
+BB34:000000003FF8200820082008200820083FF800003FF801000100010001000000
+BB35:00001FF01010101010101FF000007FFC010001001FF000100010001000100000
+BB36:00001FF01010101010101FF000007FFC0100010000003EF80208020802080000
+BB37:00001FF01010101010101FF000007FFC0100010000001E100210022802C40000
+BB38:00001FF01010101010101FF0000000007FFC010001001100100010001FF00000
+BB39:00001FF01010101010101FF000007FFC01000100000020F8201020303ECC0000
+BB3A:00001FF01010101010101FF000007FFC01000100202021FC207020883E700000
+BB3B:00001FF01010101010101FF000007FFC010001001FF01000100010001FF00000
+BB3C:00001FF01010101010101FF000007FFC010001001FF000101FF010001FF00000
+BB3D:00001FF01010101010101FF000007FFC010001003EF802083E0820083E080000
+BB3E:00001FF01010101010101FF000007FFC010001003EF802883E8820883EF80000
+BB3F:00001FF01010101010101FF000007FFC010001003E8802883EF820883EF80000
+BB40:00001FF01010101010101FF000007FFC010001003E1002103E1020283EC40000
+BB41:00001FF01010101010101FF000007FFC010001003EF802803EF820803EF80000
+BB42:00001FF01010101010101FF000007FFC010001003EFC02483E4820483EFC0000
+BB43:00001FF01010101010101FF000007FFC010001003E2003FC3E7020883E700000
+BB44:00001FF01010101010101FF000007FFC010001001FF01010101010101FF00000
+BB45:00001FF01010101010101FF000007FFC01000100101010101FF010101FF00000
+BB46:00001FF01010101010101FF000007FFC01000100222022203E2022503E880000
+BB47:00001FF01010101010101FF000007FFC0100010000000100010002800C400000
+BB48:00001FF01010101010101FF000007FFC010001000000024002400DA033100000
+BB49:00001FF01010101010101FF000007FFC01000100000007C00820082007C00000
+BB4A:00001FF01010101010101FF000007FFC01000100000007E00080014006200000
+BB4B:00001FF01010101010101FF000007FFC01000100008007E00080014006200000
+BB4C:00001FF01010101010101FF000007FFC010001001FF000101FF0001000100000
+BB4D:00001FF01010101010101FF000007FFC010001001FF010001FF010001FF00000
+BB4E:00001FF01010101010101FF000007FFC0100010000001FF0044004401FF00000
+BB4F:00001FF01010101010101FF000007FFC0100010001001FF007C0082007C00000
+BB50:000000083FC8204820482048204820483FC800087FE8040804F8040804080000
+BB51:00083F88208820883F8800087FE8027802080000000007F80008000800080000
+BB52:00083F88208820883F8800087FE802780208000000003EF80208020802080000
+BB53:00083F88208820883F8800087FE802780208000000001F080108011401620000
+BB54:00083F88208820883F88000800087FE80278020802081000100010001FF80000
+BB55:00083F88208820883F8800087FE8027802080000000020F8201020303ECC0000
+BB56:00083F88208820883F8800087FE8027802080000202021FC207020883E700000
+BB57:00083F88208820883F8800087FE802780208000003F802000200020003F80000
+BB58:00083F88208820883F8800087FE802780208000007F8000807F8040007F80000
+BB59:00083F88208820883F8800087FE80278020800003EF802083E0820083E080000
+BB5A:00083F88208820883F8800087FE80278020800003EF802883E8820883EF80000
+BB5B:00083F88208820883F8800087FE80278020800003E8802883EF820883EF80000
+BB5C:00083F88208820883F8800087FE80278020800000F8800880F8808140FA20000
+BB5D:00083F88208820883F8800087FE80278020800003EF802803EF820803EF80000
+BB5E:00083F88208820883F8800087FE80278020800003EFC02483E4820483EFC0000
+BB5F:00083F88208820883F8800087FE80278020800003E1002FE3E3820443E380000
+BB60:00083F88208820883F8800087FE802780208000003F802080208020803F80000
+BB61:00083F88208820883F8800087FE80278020800000208020803F8020803F80000
+BB62:00083F88208820883F8800087FE8027802080000210821083F0821143F620000
+BB63:00083F88208820883F8800087FE8027802080000001000100010006801840000
+BB64:00083F88208820883F8800087FE80278020800000048004800A8011406620000
+BB65:00083F88208820883F8800087FE8027802080000000003F00408040803F00000
+BB66:00083F88208820883F8800087FE802780208000003F80020002000D003080000
+BB67:00083F88208820883F8800087FE8027802080000004003F8004000A003180000
+BB68:00083F88208820883F8800087FE802780208000003F8000803F8000800080000
+BB69:00083F88208820883F8800087FE802780208000003F8020003F8020003F80000
+BB6A:00083F88208820883F8800087FE802780208000000000FF8022002200FF80000
+BB6B:00083F88208820883F8800087FE802780208000000800FF803E0041003E00000
+BB6C:0000000A3FCA204A204A204A204A204A3FCA000A7FEA040A047A040A040A0000
+BB6D:00283FA820A820A83FA800287FA805E804280000000007F80008000800080000
+BB6E:00283FA820A820A83FA800287FA805E80428000000003EF80208020802080000
+BB6F:00283FA820A820A83FA800287FA805E80428000000001F080108011401620000
+BB70:00283FA820A820A83FA8002800287FA8042805E804281428100010001FF80000
+BB71:00283FA820A820A83FA800287FA805E804280000000020F8201020303ECC0000
+BB72:00283FA820A820A83FA800287FA805E804280000202021FC207020883E700000
+BB73:00283FA820A820A83FA800287FA805E80428000003F802000200020003F80000
+BB74:00283FA820A820A83FA800287FA805E80428000007F8000807F8040007F80000
+BB75:00283FA820A820A83FA800287FA805E8042800003EF802083E0820083E080000
+BB76:00283FA820A820A83FA800287FA805E8042800003EF802883E8820883EF80000
+BB77:00283FA820A820A83FA800287FA805E8042800003E8802883EF820883EF80000
+BB78:00283FA820A820A83FA800287FA805E8042800000F8800880F8808140FA20000
+BB79:00283FA820A820A83FA800287FA805E8042800003EF802803EF820803EF80000
+BB7A:00283FA820A820A83FA800287FA805E8042800003EFC02483E4820483EFC0000
+BB7B:00283FA820A820A83FA800287FA805E8042800003E1002FE3E3820443E380000
+BB7C:00283FA820A820A83FA800287FA805E80428000003F802080208020803F80000
+BB7D:00283FA820A820A83FA800287FA805E8042800000208020803F8020803F80000
+BB7E:00283FA820A820A83FA800287FA805E804280000210821083F0821143F620000
+BB7F:00283FA820A820A83FA800287FA805E804280000001000100010006801840000
+BB80:00283FA820A820A83FA800287FA805E8042800000048004800A8011406620000
+BB81:00283FA820A820A83FA800287FA805E804280000000003F00408040803F00000
+BB82:00283FA820A820A83FA800287FA805E80428000003F80020002000D003080000
+BB83:00283FA820A820A83FA800287FA805E804280000004003F8004000A003180000
+BB84:00283FA820A820A83FA800287FA805E80428000003F8000803F8000800080000
+BB85:00283FA820A820A83FA800287FA805E80428000003F8020003F8020003F80000
+BB86:00283FA820A820A83FA800287FA805E80428000000000FF8022002200FF80000
+BB87:00283FA820A820A83FA800287FA805E80428000000800FF803E0041003E00000
+BB88:000000083FC8204820482048204820483FC800087FE804080408040804080000
+BB89:00083F88208820883F8800087FE8020802000000000007F80008000800080000
+BB8A:00083F88208820883F8800087FE802080200000000003EF80208020802080000
+BB8B:00083F88208820883F8800087FE802080200000000001F080108011401620000
+BB8C:00083F88208820883F88000800087FE80208020802081008100010001FF80000
+BB8D:00083F88208820883F8800087FE8020802000000000020F8201020303ECC0000
+BB8E:00083F88208820883F8800087FE8020802000000202021FC207020883E700000
+BB8F:00083F88208820883F8800087FE802080200000003F802000200020003F80000
+BB90:00083F88208820883F8800087FE802080200000007F8000807F8040007F80000
+BB91:00083F88208820883F8800087FE80208020000003EF802083E0820083E080000
+BB92:00083F88208820883F8800087FE80208020000003EF802883E8820883EF80000
+BB93:00083F88208820883F8800087FE80208020000003E8802883EF820883EF80000
+BB94:00083F88208820883F8800087FE80208020000000F8800880F8808140FA20000
+BB95:00083F88208820883F8800087FE80208020000003EF802803EF820803EF80000
+BB96:00083F88208820883F8800087FE80208020000003EFC02483E4820483EFC0000
+BB97:00083F88208820883F8800087FE80208020000003E1002FE3E3820443E380000
+BB98:00083F88208820883F8800087FE802080200000003F802080208020803F80000
+BB99:00083F88208820883F8800087FE80208020000000208020803F8020803F80000
+BB9A:00083F88208820883F8800087FE8020802000000210821083F0821143F620000
+BB9B:00083F88208820883F8800087FE8020802000000001000100010006801840000
+BB9C:00083F88208820883F8800087FE80208020000000048004800A8011406620000
+BB9D:00083F88208820883F8800087FE8020802000000000003F00408040803F00000
+BB9E:00083F88208820883F8800087FE802080200000003F80020002000D003080000
+BB9F:00083F88208820883F8800087FE8020802000000004003F8004000A003180000
+BBA0:00083F88208820883F8800087FE802080200000003F8000803F8000800080000
+BBA1:00083F88208820883F8800087FE802080200000003F8020003F8020003F80000
+BBA2:00083F88208820883F8800087FE802080200000000000FF8022002200FF80000
+BBA3:00083F88208820883F8800087FE802080200000000800FF803E0041003E00000
+BBA4:000000003FF8200820082008200820083FF800007FFC04400440044004400000
+BBA5:00001FF01010101010101FF000007FFC044004401FF000100010001000100000
+BBA6:00001FF01010101010101FF000007FFC0440044000003EF80208020802080000
+BBA7:00001FF01010101010101FF000007FFC0440044000001E100210022802C40000
+BBA8:00001FF01010101010101FF0000000007FFC044004401440100010001FF00000
+BBA9:00001FF01010101010101FF000007FFC04400440000020F8201020303ECC0000
+BBAA:00001FF01010101010101FF000007FFC04400440202021FC207020883E700000
+BBAB:00001FF01010101010101FF000007FFC044004401FF01000100010001FF00000
+BBAC:00001FF01010101010101FF000007FFC044004401FF000101FF010001FF00000
+BBAD:00001FF01010101010101FF000007FFC044004403EF802083E0820083E080000
+BBAE:00001FF01010101010101FF000007FFC044004403EF802883E8820883EF80000
+BBAF:00001FF01010101010101FF000007FFC044004403E8802883EF820883EF80000
+BBB0:00001FF01010101010101FF000007FFC044004403E1002103E1020283EC40000
+BBB1:00001FF01010101010101FF000007FFC044004403EF802803EF820803EF80000
+BBB2:00001FF01010101010101FF000007FFC044004403EFC02483E4820483EFC0000
+BBB3:00001FF01010101010101FF000007FFC044004403E2003FC3E7020883E700000
+BBB4:00001FF01010101010101FF000007FFC044004401FF01010101010101FF00000
+BBB5:00001FF01010101010101FF000007FFC04400440101010101FF010101FF00000
+BBB6:00001FF01010101010101FF000007FFC04400440222022203E2022503E880000
+BBB7:00001FF01010101010101FF000007FFC0440044000000100010002800C400000
+BBB8:00001FF01010101010101FF000007FFC044004400000024002400DA033100000
+BBB9:00001FF01010101010101FF000007FFC04400440000007C00820082007C00000
+BBBA:00001FF01010101010101FF000007FFC04400440000007E00080014006200000
+BBBB:00001FF01010101010101FF000007FFC04400440008007E00080014006200000
+BBBC:00001FF01010101010101FF000007FFC044004401FF000101FF0001000100000
+BBBD:00001FF01010101010101FF000007FFC044004401FF010001FF010001FF00000
+BBBE:00001FF01010101010101FF000007FFC0440044000001FF0044004401FF00000
+BBBF:00001FF01010101010101FF000007FFC0440044001001FF007C0082007C00000
+BBC0:000000003FF820082008200820083FF80000000000007FFC0000000000000000
+BBC1:00001FF01010101010101FF0000000007FFC00001FF000100010001000100000
+BBC2:00001FF01010101010101FF0000000007FFC000000003EF80208020802080000
+BBC3:00001FF01010101010101FF0000000007FFC000000001E100210022802C40000
+BBC4:00001FF01010101010101FF0000000007FFC000000001000100010001FF00000
+BBC5:00001FF01010101010101FF0000000007FFC0000000020F8201020303ECC0000
+BBC6:00001FF01010101010101FF0000000007FFC0000202021FC207020883E700000
+BBC7:00001FF01010101010101FF0000000007FFC00001FF01000100010001FF00000
+BBC8:00001FF01010101010101FF0000000007FFC00001FF000101FF010001FF00000
+BBC9:00001FF01010101010101FF0000000007FFC00003EF802083E0820083E080000
+BBCA:00001FF01010101010101FF0000000007FFC00003EF802883E8820883EF80000
+BBCB:00001FF01010101010101FF0000000007FFC00003E8802883EF820883EF80000
+BBCC:00001FF01010101010101FF0000000007FFC00003E1002103E1020283EC40000
+BBCD:00001FF01010101010101FF0000000007FFC00003EF802803EF820803EF80000
+BBCE:00001FF01010101010101FF0000000007FFC00003EFC02483E4820483EFC0000
+BBCF:00001FF01010101010101FF0000000007FFC00003E2003FC3E7020883E700000
+BBD0:00001FF01010101010101FF0000000007FFC00001FF01010101010101FF00000
+BBD1:00001FF01010101010101FF0000000007FFC0000101010101FF010101FF00000
+BBD2:00001FF01010101010101FF0000000007FFC0000222022203E2022503E880000
+BBD3:00001FF01010101010101FF0000000007FFC000000000100010002800C400000
+BBD4:00001FF01010101010101FF0000000007FFC00000000024002400DA033100000
+BBD5:00001FF01010101010101FF0000000007FFC0000000007C00820082007C00000
+BBD6:00001FF01010101010101FF0000000007FFC0000000007E00080014006200000
+BBD7:00001FF01010101010101FF0000000007FFC0000008007E00080014006200000
+BBD8:00001FF01010101010101FF0000000007FFC00001FF000101FF0001000100000
+BBD9:00001FF01010101010101FF0000000007FFC00001FF010001FF010001FF00000
+BBDA:00001FF01010101010101FF0000000007FFC000000001FF0044004401FF00000
+BBDB:00001FF01010101010101FF0000000007FFC000001001FF007C0082007C00000
+BBDC:0000000800083F88208820882088208820883F8800087FE80008000800080000
+BBDD:000000083F882088208820883F8800087FE8000007F800080008000800080000
+BBDE:000000083F882088208820883F8800087FE8000000003EF80208020802080000
+BBDF:000000083F882088208820883F8800087FE8000000001F080108011401620000
+BBE0:000000083F882088208820883F8800087FE8000008000800080008000FF80000
+BBE1:000000083F882088208820883F8800087FE80000000010F8101010301ECC0000
+BBE2:000000083F882088208820883F8800087FE800000808087F081C08220F9C0000
+BBE3:000000083F882088208820883F8800087FE8000003F802000200020003F80000
+BBE4:000000083F882088208820883F8800087FE8000007F8000807F8040007F80000
+BBE5:000000083F882088208820883F8800087FE800003EF802083E0820083E080000
+BBE6:000000083F882088208820883F8800087FE800003EF802883E8820883EF80000
+BBE7:000000083F882088208820883F8800087FE800003E8802883EF820883EF80000
+BBE8:000000083F882088208820883F8800087FE800001F0801081F0810141F620000
+BBE9:000000083F882088208820883F8800087FE800003EF802803EF820803EF80000
+BBEA:000000083F882088208820883F8800087FE800003EFC02483E4820483EFC0000
+BBEB:000000083F882088208820883F8800087FE800001F08017F1F1C10221F1C0000
+BBEC:000000083F882088208820883F8800087FE8000003F802080208020803F80000
+BBED:000000083F882088208820883F8800087FE800000208020803F8020803F80000
+BBEE:000000083F882088208820883F8800087FE80000110811081F0811141F620000
+BBEF:000000083F882088208820883F8800087FE80000001000100010006801840000
+BBF0:000000083F882088208820883F8800087FE800000048004800A8011406620000
+BBF1:000000083F882088208820883F8800087FE80000000003F00408040803F00000
+BBF2:000000083F882088208820883F8800087FE8000003F80020002000D003080000
+BBF3:000000083F882088208820883F8800087FE80000004003F8004000A003180000
+BBF4:000000083F882088208820883F8800087FE8000003F8000803F8000800080000
+BBF5:000000083F882088208820883F8800087FE8000003F8020003F8020003F80000
+BBF6:000000083F882088208820883F8800087FE8000000000FF8022002200FF80000
+BBF7:000000083F882088208820883F8800087FE8000000800FF803E0041003E00000
+BBF8:00000000000800087F884088408840884088408840887F880008000800080000
+BBF9:000000087E0842084208420842087E0800080000000007F80008000800080000
+BBFA:000000087E0842084208420842087E080008000000003EF80208020802080000
+BBFB:000000087E0842084208420842087E080008000000001F080108011401620000
+BBFC:000000087E0842084208420842087E080008000800001000100010001FF80000
+BBFD:000000087E0842084208420842087E0800080000000020F8201020303ECC0000
+BBFE:000000087E0842084208420842087E0800080000202021FC207020883E700000
+BBFF:000000087E0842084208420842087E080008000003F802000200020003F80000
+BC00:000000087E0842084208420842087E080008000007F8000807F8040007F80000
+BC01:000000087E0842084208420842087E08000800003EF802083E0820083E080000
+BC02:000000087E0842084208420842087E08000800003EF802883E8820883EF80000
+BC03:000000087E0842084208420842087E08000800003E8802883EF820883EF80000
+BC04:000000087E0842084208420842087E08000800000F8800880F8808140FA20000
+BC05:000000087E0842084208420842087E08000800003EF802803EF820803EF80000
+BC06:000000087E0842084208420842087E08000800003EFC02483E4820483EFC0000
+BC07:000000087E0842084208420842087E08000800003E1002FE3E3820443E380000
+BC08:000000087E0842084208420842087E080008000003F802080208020803F80000
+BC09:000000087E0842084208420842087E08000800000208020803F8020803F80000
+BC0A:000000087E0842084208420842087E0800080000210821083F0821143F620000
+BC0B:000000087E0842084208420842087E0800080000001000100010006801840000
+BC0C:000000087E0842084208420842087E08000800000048004800A8011406620000
+BC0D:000000087E0842084208420842087E0800080000000003F00408040803F00000
+BC0E:000000087E0842084208420842087E080008000003F80020002000D003080000
+BC0F:000000087E0842084208420842087E0800080000004003F8004000A003180000
+BC10:000000087E0842084208420842087E080008000003F8000803F8000800080000
+BC11:000000087E0842084208420842087E080008000003F8020003F8020003F80000
+BC12:000000087E0842084208420842087E080008000000000FF8022002200FF80000
+BC13:000000087E0842084208420842087E080008000000800FF803E0041003E00000
+BC14:00000000001000102090209020903F9E2090209020903F900010001000100000
+BC15:000000080008420842087E0E42087E080008000007F800080008000800080000
+BC16:000000080008420842087E0E42087E080008000000003EF80208020802080000
+BC17:000000080008420842087E0E42087E080008000000001F080108011401620000
+BC18:000000080008420842087E0E42087E080008000808000800080008000FF80000
+BC19:000000080008420842087E0E42087E0800080000000010F8101010301ECC0000
+BC1A:000000080008420842087E0E42087E08000800000808087F081C08220F9C0000
+BC1B:000000080008420842087E0E42087E080008000003F802000200020003F80000
+BC1C:000000080008420842087E0E42087E080008000007F8000807F8040007F80000
+BC1D:000000080008420842087E0E42087E08000800003EF802083E0820083E080000
+BC1E:000000080008420842087E0E42087E08000800003EF802883E8820883EF80000
+BC1F:000000080008420842087E0E42087E08000800003E8802883EF820883EF80000
+BC20:000000080008420842087E0E42087E08000800001F0801081F0810141F620000
+BC21:000000080008420842087E0E42087E08000800003EF802803EF820803EF80000
+BC22:000000080008420842087E0E42087E08000800003EFC02483E4820483EFC0000
+BC23:000000080008420842087E0E42087E08000800001F08017F1F1C10221F1C0000
+BC24:000000080008420842087E0E42087E080008000003F802080208020803F80000
+BC25:000000080008420842087E0E42087E08000800000208020803F8020803F80000
+BC26:000000080008420842087E0E42087E0800080000110811081F0811141F620000
+BC27:000000080008420842087E0E42087E0800080000001000100010006801840000
+BC28:000000080008420842087E0E42087E08000800000048004800A8011406620000
+BC29:000000080008420842087E0E42087E0800080000000003F00408040803F00000
+BC2A:000000080008420842087E0E42087E080008000003F80020002000D003080000
+BC2B:000000080008420842087E0E42087E0800080000004003F8004000A003180000
+BC2C:000000080008420842087E0E42087E080008000003F8000803F8000800080000
+BC2D:000000080008420842087E0E42087E080008000003F8020003F8020003F80000
+BC2E:000000080008420842087E0E42087E080008000000000FF8022002200FF80000
+BC2F:000000080008420842087E0E42087E080008000000800FF803E0041003E00000
+BC30:00000000001200122092209220923F9E2092209220923F920012001200120000
+BC31:000000280028422842287E3842287E280028000007F800080008000800080000
+BC32:000000280028422842287E3842287E280028000000003EF80208020802080000
+BC33:000000280028422842287E3842287E280028000000003E100210022802C40000
+BC34:000000280028422842287E3842287E280028002808000800080008000FF80000
+BC35:000000280028422842287E3842287E2800280000000020F8201020303ECC0000
+BC36:000000280028422842287E3842287E2800280000202021FC207020883E700000
+BC37:000000280028422842287E3842287E280028000003F802000200020003F80000
+BC38:000000280028422842287E3842287E280028000007F8000807F8040007F80000
+BC39:000000280028422842287E3842287E28002800003EF802083E0820083E080000
+BC3A:000000280028422842287E3842287E28002800003EF802883E8820883EF80000
+BC3B:000000280028422842287E3842287E28002800003E8802883EF820883EF80000
+BC3C:000000280028422842287E3842287E28002800001F0801081F0810141F620000
+BC3D:000000280028422842287E3842287E28002800003EF802803EF820803EF80000
+BC3E:000000280028422842287E3842287E28002800003EFC02483E4820483EFC0000
+BC3F:000000280028422842287E3842287E28002800003E1002FE3E3820443E380000
+BC40:000000280028422842287E3842287E280028000003F802080208020803F80000
+BC41:000000280028422842287E3842287E28002800000208020803F8020803F80000
+BC42:000000280028422842287E3842287E2800280000110811081F0811141F620000
+BC43:000000280028422842287E3842287E2800280000000800080008003400C20000
+BC44:000000280028422842287E3842287E28002800000048004800A8011406620000
+BC45:000000280028422842287E3842287E2800280000000001F00208020801F00000
+BC46:000000280028422842287E3842287E280028000003F80020002000D003080000
+BC47:000000280028422842287E3842287E2800280000004003F8004000A003180000
+BC48:000000280028422842287E3842287E280028000003F8000803F8000800080000
+BC49:000000280028422842287E3842287E280028000003F8020003F8020003F80000
+BC4A:000000280028422842287E3842287E280028000000000FF8022002200FF80000
+BC4B:000000280028422842287E3842287E280028000000800FF803E0041003E00000
+BC4C:000000000010001020902090209E3F902090209E20903F900010001000100000
+BC4D:0000000800084208420E7E08420E7E080008000007F800080008000800080000
+BC4E:0000000800084208420E7E08420E7E080008000000003EF80208020802080000
+BC4F:0000000800084208420E7E08420E7E080008000000001F080108011401620000
+BC50:0000000800084208420E7E08420E7E080008000008000800080008000FF80000
+BC51:0000000800084208420E7E08420E7E0800080000000010F8101010301ECC0000
+BC52:0000000800084208420E7E08420E7E08000800000808087F081C08220F9C0000
+BC53:0000000800084208420E7E08420E7E080008000003F802000200020003F80000
+BC54:0000000800084208420E7E08420E7E080008000007F8000807F8040007F80000
+BC55:0000000800084208420E7E08420E7E08000800003EF802083E0820083E080000
+BC56:0000000800084208420E7E08420E7E08000800003EF802883E8820883EF80000
+BC57:0000000800084208420E7E08420E7E08000800003E8802883EF820883EF80000
+BC58:0000000800084208420E7E08420E7E08000800001F0801081F0810141F620000
+BC59:0000000800084208420E7E08420E7E08000800003EF802803EF820803EF80000
+BC5A:0000000800084208420E7E08420E7E08000800003EFC02483E4820483EFC0000
+BC5B:0000000800084208420E7E08420E7E08000800001F08017F1F1C10221F1C0000
+BC5C:0000000800084208420E7E08420E7E080008000003F802080208020803F80000
+BC5D:0000000800084208420E7E08420E7E08000800000208020803F8020803F80000
+BC5E:0000000800084208420E7E08420E7E0800080000110811081F0811141F620000
+BC5F:0000000800084208420E7E08420E7E0800080000001000100010006801840000
+BC60:0000000800084208420E7E08420E7E08000800000048004800A8011406620000
+BC61:0000000800084208420E7E08420E7E0800080000000003F00408040803F00000
+BC62:0000000800084208420E7E08420E7E080008000003F80020002000D003080000
+BC63:0000000800084208420E7E08420E7E0800080000004003F8004000A003180000
+BC64:0000000800084208420E7E08420E7E080008000003F8000803F8000800080000
+BC65:0000000800084208420E7E08420E7E080008000003F8020003F8020003F80000
+BC66:0000000800084208420E7E08420E7E080008000000000FF8022002200FF80000
+BC67:0000000800084208420E7E08420E7E080008000000800FF803E0041003E00000
+BC68:000000000012001220922092209E3F922092209E20923F920012001200120000
+BC69:000000280028422842387E2842387E280028000007F800080008000800080000
+BC6A:000000280028422842387E2842387E280028000000003EF80208020802080000
+BC6B:000000280028422842387E2842387E280028000000003E100210022802C40000
+BC6C:000000280028422842387E2842387E280028002808000800080008000FF80000
+BC6D:000000280028422842387E2842387E2800280000000020F8201020303ECC0000
+BC6E:000000280028422842387E2842387E2800280000202021FC207020883E700000
+BC6F:000000280028422842387E2842387E280028000003F802000200020003F80000
+BC70:000000280028422842387E2842387E280028000007F8000807F8040007F80000
+BC71:000000280028422842387E2842387E28002800003EF802083E0820083E080000
+BC72:000000280028422842387E2842387E28002800003EF802883E8820883EF80000
+BC73:000000280028422842387E2842387E28002800003E8802883EF820883EF80000
+BC74:000000280028422842387E2842387E28002800001F0801081F0810141F620000
+BC75:000000280028422842387E2842387E28002800003EF802803EF820803EF80000
+BC76:000000280028422842387E2842387E28002800003EFC02483E4820483EFC0000
+BC77:000000280028422842387E2842387E28002800003E1002FE3E3820443E380000
+BC78:000000280028422842387E2842387E280028000003F802080208020803F80000
+BC79:000000280028422842387E2842387E28002800000208020803F8020803F80000
+BC7A:000000280028422842387E2842387E2800280000110811081F0811141F620000
+BC7B:000000280028422842387E2842387E2800280000000800080008003400C20000
+BC7C:000000280028422842387E2842387E28002800000048004800A8011406620000
+BC7D:000000280028422842387E2842387E2800280000000001F00208020801F00000
+BC7E:000000280028422842387E2842387E280028000003F80020002000D003080000
+BC7F:000000280028422842387E2842387E2800280000004003F8004000A003180000
+BC80:000000280028422842387E2842387E280028000003F8000803F8000800080000
+BC81:000000280028422842387E2842387E280028000003F8020003F8020003F80000
+BC82:000000280028422842387E2842387E280028000000000FF8022002200FF80000
+BC83:000000280028422842387E2842387E280028000000800FF803E0041003E00000
+BC84:00000000000200022082208220823F9E2082208220823F820002000200020000
+BC85:000000080008420842087E3842087E0800080000000007F80008000800080000
+BC86:000000080008420842087E3842087E080008000000003EF80208020802080000
+BC87:000000080008420842087E3842087E080008000000001F080108011401620000
+BC88:000000080008420842087E3842087E080008000000001000100010001FF80000
+BC89:000000080008420842087E3842087E0800080000000020F8201020303ECC0000
+BC8A:000000080008420842087E3842087E0800080000202021FC207020883E700000
+BC8B:000000080008420842087E3842087E080008000003F802000200020003F80000
+BC8C:000000080008420842087E3842087E080008000007F8000807F8040007F80000
+BC8D:000000080008420842087E3842087E08000800003EF802083E0820083E080000
+BC8E:000000080008420842087E3842087E08000800003EF802883E8820883EF80000
+BC8F:000000080008420842087E3842087E08000800003E8802883EF820883EF80000
+BC90:000000080008420842087E3842087E08000800000F8800880F8808140FA20000
+BC91:000000080008420842087E3842087E08000800003EF802803EF820803EF80000
+BC92:000000080008420842087E3842087E08000800003EFC02483E4820483EFC0000
+BC93:000000080008420842087E3842087E08000800003E1002FE3E3820443E380000
+BC94:000000080008420842087E3842087E080008000003F802080208020803F80000
+BC95:000000080008420842087E3842087E08000800000208020803F8020803F80000
+BC96:000000080008420842087E3842087E0800080000210821083F0821143F620000
+BC97:000000080008420842087E3842087E0800080000001000100010006801840000
+BC98:000000080008420842087E3842087E08000800000048004800A8011406620000
+BC99:000000080008420842087E3842087E0800080000000003F00408040803F00000
+BC9A:000000080008420842087E3842087E080008000003F80020002000D003080000
+BC9B:000000080008420842087E3842087E0800080000004003F8004000A003180000
+BC9C:000000080008420842087E3842087E080008000003F8000803F8000800080000
+BC9D:000000080008420842087E3842087E080008000003F8020003F8020003F80000
+BC9E:000000080008420842087E3842087E080008000000000FF8022002200FF80000
+BC9F:000000080008420842087E3842087E080008000000800FF803E0041003E00000
+BCA0:00000000000A000A208A208A208A3FBA208A208A208A3F8A000A000A000A0000
+BCA1:000000280028422842287EE842287E280028000007F800080008000800080000
+BCA2:000000280028422842287EE842287E280028000000003EF80208020802080000
+BCA3:000000280028422842287EE842287E280028000000003E100210022802C40000
+BCA4:000000280028422842287EE842287E280028000008000800080008000FF80000
+BCA5:000000280028422842287EE842287E2800280000000020F8201020303ECC0000
+BCA6:000000280028422842287EE842287E2800280000202021FC207020883E700000
+BCA7:000000280028422842287EE842287E280028000003F802000200020003F80000
+BCA8:000000280028422842287EE842287E280028000007F8000807F8040007F80000
+BCA9:000000280028422842287EE842287E28002800003EF802083E0820083E080000
+BCAA:000000280028422842287EE842287E28002800003EF802883E8820883EF80000
+BCAB:000000280028422842287EE842287E28002800003E8802883EF820883EF80000
+BCAC:000000280028422842287EE842287E28002800001F0801081F0810141F620000
+BCAD:000000280028422842287EE842287E28002800003EF802803EF820803EF80000
+BCAE:000000280028422842287EE842287E28002800003EFC02483E4820483EFC0000
+BCAF:000000280028422842287EE842287E28002800003E1002FE3E3820443E380000
+BCB0:000000280028422842287EE842287E280028000003F802080208020803F80000
+BCB1:000000280028422842287EE842287E28002800000208020803F8020803F80000
+BCB2:000000280028422842287EE842287E2800280000110811081F0811141F620000
+BCB3:000000280028422842287EE842287E2800280000000800080008003400C20000
+BCB4:000000280028422842287EE842287E28002800000048004800A8011406620000
+BCB5:000000280028422842287EE842287E2800280000000001F00208020801F00000
+BCB6:000000280028422842287EE842287E280028000003F80020002000D003080000
+BCB7:000000280028422842287EE842287E2800280000004003F8004000A003180000
+BCB8:000000280028422842287EE842287E280028000003F8000803F8000800080000
+BCB9:000000280028422842287EE842287E280028000003F8020003F8020003F80000
+BCBA:000000280028422842287EE842287E280028000000000FF8022002200FF80000
+BCBB:000000280028422842287EE842287E280028000000800FF803E0041003E00000
+BCBC:000000000002000220822082209E3F822082209E20823F820002000200020000
+BCBD:000000080008420842387E0842387E0800080000000007F80008000800080000
+BCBE:000000080008420842387E0842387E080008000000003EF80208020802080000
+BCBF:000000080008420842387E0842387E080008000000001F080108011401620000
+BCC0:000000080008420842387E0842387E080008000800001000100010001FF80000
+BCC1:000000080008420842387E0842387E0800080000000020F8201020303ECC0000
+BCC2:000000080008420842387E0842387E0800080000202021FC207020883E700000
+BCC3:000000080008420842387E0842387E080008000003F802000200020003F80000
+BCC4:000000080008420842387E0842387E080008000007F8000807F8040007F80000
+BCC5:000000080008420842387E0842387E08000800003EF802083E0820083E080000
+BCC6:000000080008420842387E0842387E08000800003EF802883E8820883EF80000
+BCC7:000000080008420842387E0842387E08000800003E8802883EF820883EF80000
+BCC8:000000080008420842387E0842387E08000800000F8800880F8808140FA20000
+BCC9:000000080008420842387E0842387E08000800003EF802803EF820803EF80000
+BCCA:000000080008420842387E0842387E08000800003EFC02483E4820483EFC0000
+BCCB:000000080008420842387E0842387E08000800003E1002FE3E3820443E380000
+BCCC:000000080008420842387E0842387E080008000003F802080208020803F80000
+BCCD:000000080008420842387E0842387E08000800000208020803F8020803F80000
+BCCE:000000080008420842387E0842387E0800080000210821083F0821143F620000
+BCCF:000000080008420842387E0842387E0800080000001000100010006801840000
+BCD0:000000080008420842387E0842387E08000800000048004800A8011406620000
+BCD1:000000080008420842387E0842387E0800080000000003F00408040803F00000
+BCD2:000000080008420842387E0842387E080008000003F80020002000D003080000
+BCD3:000000080008420842387E0842387E0800080000004003F8004000A003180000
+BCD4:000000080008420842387E0842387E080008000003F8000803F8000800080000
+BCD5:000000080008420842387E0842387E080008000003F8020003F8020003F80000
+BCD6:000000080008420842387E0842387E080008000000000FF8022002200FF80000
+BCD7:000000080008420842387E0842387E080008000000800FF803E0041003E00000
+BCD8:00000000000A000A208A208A20BA3F8A208A20BA208A3F8A000A000A000A0000
+BCD9:000000280028422842E87E2842E87E280028000007F800080008000800080000
+BCDA:000000280028422842E87E2842E87E280028000000003EF80208020802080000
+BCDB:000000280028422842E87E2842E87E280028000000003E100210022802C40000
+BCDC:000000280028422842E87E2842E87E280028002808000800080008000FF80000
+BCDD:000000280028422842E87E2842E87E2800280000000020F8201020303ECC0000
+BCDE:000000280028422842E87E2842E87E2800280000202021FC207020883E700000
+BCDF:000000280028422842E87E2842E87E280028000003F802000200020003F80000
+BCE0:000000280028422842E87E2842E87E280028000007F8000807F8040007F80000
+BCE1:000000280028422842E87E2842E87E28002800003EF802083E0820083E080000
+BCE2:000000280028422842E87E2842E87E28002800003EF802883E8820883EF80000
+BCE3:000000280028422842E87E2842E87E28002800003E8802883EF820883EF80000
+BCE4:000000280028422842E87E2842E87E28002800001F0801081F0810141F620000
+BCE5:000000280028422842E87E2842E87E28002800003EF802803EF820803EF80000
+BCE6:000000280028422842E87E2842E87E28002800003EFC02483E4820483EFC0000
+BCE7:000000280028422842E87E2842E87E28002800003E1002FE3E3820443E380000
+BCE8:000000280028422842E87E2842E87E280028000003F802080208020803F80000
+BCE9:000000280028422842E87E2842E87E28002800000208020803F8020803F80000
+BCEA:000000280028422842E87E2842E87E2800280000110811081F0811141F620000
+BCEB:000000280028422842E87E2842E87E2800280000000800080008003400C20000
+BCEC:000000280028422842E87E2842E87E28002800000048004800A8011406620000
+BCED:000000280028422842E87E2842E87E2800280000000001F00208020801F00000
+BCEE:000000280028422842E87E2842E87E280028000003F80020002000D003080000
+BCEF:000000280028422842E87E2842E87E2800280000004003F8004000A003180000
+BCF0:000000280028422842E87E2842E87E280028000003F8000803F8000800080000
+BCF1:000000280028422842E87E2842E87E280028000003F8020003F8020003F80000
+BCF2:000000280028422842E87E2842E87E280028000000000FF8022002200FF80000
+BCF3:000000280028422842E87E2842E87E280028000000800FF803E0041003E00000
+BCF4:000000001010101010101FF0101010101FF000000100010001007FFC00000000
+BCF5:0000101010101FF010101FF0010001007FFC00001FF000100010001000100000
+BCF6:0000101010101FF010101FF0010001007FFC000000003EF80208020802080000
+BCF7:0000101010101FF010101FF0010001007FFC000000001E100210022802C40000
+BCF8:0000101010101FF010101FF0010001007FFC000000001000100010001FF00000
+BCF9:0000101010101FF010101FF0010001007FFC0000000020F8201020303ECC0000
+BCFA:0000101010101FF010101FF0010001007FFC0000202021FC207020883E700000
+BCFB:0000101010101FF010101FF0010001007FFC00001FF01000100010001FF00000
+BCFC:0000101010101FF010101FF0010001007FFC00001FF000101FF010001FF00000
+BCFD:0000101010101FF010101FF0010001007FFC00003EF802083E0820083E080000
+BCFE:0000101010101FF010101FF0010001007FFC00003EF802883E8820883EF80000
+BCFF:0000101010101FF010101FF0010001007FFC00003E8802883EF820883EF80000
+BD00:0000101010101FF010101FF0010001007FFC00003E1002103E1020283EC40000
+BD01:0000101010101FF010101FF0010001007FFC00003EF802803EF820803EF80000
+BD02:0000101010101FF010101FF0010001007FFC00003EFC02483E4820483EFC0000
+BD03:0000101010101FF010101FF0010001007FFC00003E2003FC3E7020883E700000
+BD04:0000101010101FF010101FF0010001007FFC00001FF01010101010101FF00000
+BD05:0000101010101FF010101FF0010001007FFC0000101010101FF010101FF00000
+BD06:0000101010101FF010101FF0010001007FFC0000222022203E2022503E880000
+BD07:0000101010101FF010101FF0010001007FFC000000000100010002800C400000
+BD08:0000101010101FF010101FF0010001007FFC00000000024002400DA033100000
+BD09:0000101010101FF010101FF0010001007FFC0000000007C00820082007C00000
+BD0A:0000101010101FF010101FF0010001007FFC0000000007E00080014006200000
+BD0B:0000101010101FF010101FF0010001007FFC0000008007E00080014006200000
+BD0C:0000101010101FF010101FF0010001007FFC00001FF000101FF0001000100000
+BD0D:0000101010101FF010101FF0010001007FFC00001FF010001FF010001FF00000
+BD0E:0000101010101FF010101FF0010001007FFC000000001FF0044004401FF00000
+BD0F:0000101010101FF010101FF0010001007FFC000001001FF007C0082007C00000
+BD10:0000001000102090209020903F90209E20903F90041004107FD0001000100000
+BD11:00000008208820883F8E20883F8804087FE8000007F800080008000800080000
+BD12:00000008208820883F8E20883F8804087FE8000000003EF80208020802080000
+BD13:00000008208820883F8E20883F8804087FE8000000001F080108011401620000
+BD14:00000008208820883F8E20883F8804087FE8000008000800080008000FF80000
+BD15:00000008208820883F8E20883F8804087FE80000000010F8101010301ECC0000
+BD16:00000008208820883F8E20883F8804087FE800000808087F081C08220F9C0000
+BD17:00000008208820883F8E20883F8804087FE8000003F802000200020003F80000
+BD18:00000008208820883F8E20883F8804087FE8000007F8000807F8040007F80000
+BD19:00000008208820883F8E20883F8804087FE800003EF802083E0820083E080000
+BD1A:00000008208820883F8E20883F8804087FE800003EF802883E8820883EF80000
+BD1B:00000008208820883F8E20883F8804087FE800003E8802883EF820883EF80000
+BD1C:00000008208820883F8E20883F8804087FE800001F0801081F0810141F620000
+BD1D:00000008208820883F8E20883F8804087FE800003EF802803EF820803EF80000
+BD1E:00000008208820883F8E20883F8804087FE800003EFC02483E4820483EFC0000
+BD1F:00000008208820883F8E20883F8804087FE800001F08017F1F1C10221F1C0000
+BD20:00000008208820883F8E20883F8804087FE8000003F802080208020803F80000
+BD21:00000008208820883F8E20883F8804087FE800000208020803F8020803F80000
+BD22:00000008208820883F8E20883F8804087FE80000110811081F0811141F620000
+BD23:00000008208820883F8E20883F8804087FE80000001000100010006801840000
+BD24:00000008208820883F8E20883F8804087FE800000048004800A8011406620000
+BD25:00000008208820883F8E20883F8804087FE80000000003F00408040803F00000
+BD26:00000008208820883F8E20883F8804087FE8000003F80020002000D003080000
+BD27:00000008208820883F8E20883F8804087FE80000004003F8004000A003180000
+BD28:00000008208820883F8E20883F8804087FE8000003F8000803F8000800080000
+BD29:00000008208820883F8E20883F8804087FE8000003F8020003F8020003F80000
+BD2A:00000008208820883F8E20883F8804087FE8000000000FF8022002200FF80000
+BD2B:00000008208820883F8E20883F8804087FE8000000800FF803E0041003E00000
+BD2C:0000001200122092209220923F92209E20923F92041204127FD2001200120000
+BD2D:0000002820A820A83FB820A83FA804287FA8000007F800080008000800080000
+BD2E:0000002820A820A83FB820A83FA804287FA8000000003EF80208020802080000
+BD2F:0000002820A820A83FB820A83FA804287FA8000000001F080108011401620000
+BD30:0000002820A820A83FB820A83FA804287FA8000008000800080008000FF80000
+BD31:0000002820A820A83FB820A83FA804287FA80000000010F8101010301ECC0000
+BD32:0000002820A820A83FB820A83FA804287FA800000808087F081C08220F9C0000
+BD33:0000002820A820A83FB820A83FA804287FA8000003F802000200020003F80000
+BD34:0000002820A820A83FB820A83FA804287FA8000007F8000807F8040007F80000
+BD35:0000002820A820A83FB820A83FA804287FA800003EF802083E0820083E080000
+BD36:0000002820A820A83FB820A83FA804287FA800003EF802883E8820883EF80000
+BD37:0000002820A820A83FB820A83FA804287FA800003E8802883EF820883EF80000
+BD38:0000002820A820A83FB820A83FA804287FA800001F0801081F0810141F620000
+BD39:0000002820A820A83FB820A83FA804287FA800003EF802803EF820803EF80000
+BD3A:0000002820A820A83FB820A83FA804287FA800003EFC02483E4820483EFC0000
+BD3B:0000002820A820A83FB820A83FA804287FA800001F08017F1F1C10221F1C0000
+BD3C:0000002820A820A83FB820A83FA804287FA8000003F802080208020803F80000
+BD3D:0000002820A820A83FB820A83FA804287FA800000208020803F8020803F80000
+BD3E:0000002820A820A83FB820A83FA804287FA80000110811081F0811141F620000
+BD3F:0000002820A820A83FB820A83FA804287FA80000001000100010006801840000
+BD40:0000002820A820A83FB820A83FA804287FA800000048004800A8011406620000
+BD41:0000002820A820A83FB820A83FA804287FA80000000003F00408040803F00000
+BD42:0000002820A820A83FB820A83FA804287FA8000003F80020002000D003080000
+BD43:0000002820A820A83FB820A83FA804287FA80000004003F8004000A003180000
+BD44:0000002820A820A83FB820A83FA804287FA8000003F8000803F8000800080000
+BD45:0000002820A820A83FB820A83FA804287FA8000003F8020003F8020003F80000
+BD46:0000002820A820A83FB820A83FA804287FA8000000000FF8022002200FF80000
+BD47:0000002820A820A83FB820A83FA804287FA8000000800FF803E0041003E00000
+BD48:0000000800082088208820883F88208820883F88040804087FE8000800080000
+BD49:00000008208820883F8820883F8804087FE8000007F800080008000800080000
+BD4A:00000008208820883F8820883F8804087FE8000000003EF80208020802080000
+BD4B:00000008208820883F8820883F8804087FE8000000001F080108011401620000
+BD4C:00000008208820883F8820883F8804087FE8000008000800080008000FF80000
+BD4D:00000008208820883F8820883F8804087FE80000000010F8101010301ECC0000
+BD4E:00000008208820883F8820883F8804087FE800000808087F081C08220F9C0000
+BD4F:00000008208820883F8820883F8804087FE8000003F802000200020003F80000
+BD50:00000008208820883F8820883F8804087FE8000007F8000807F8040007F80000
+BD51:00000008208820883F8820883F8804087FE800003EF802083E0820083E080000
+BD52:00000008208820883F8820883F8804087FE800003EF802883E8820883EF80000
+BD53:00000008208820883F8820883F8804087FE800003E8802883EF820883EF80000
+BD54:00000008208820883F8820883F8804087FE800001F0801081F0810141F620000
+BD55:00000008208820883F8820883F8804087FE800003EF802803EF820803EF80000
+BD56:00000008208820883F8820883F8804087FE800003EFC02483E4820483EFC0000
+BD57:00000008208820883F8820883F8804087FE800001F08017F1F1C10221F1C0000
+BD58:00000008208820883F8820883F8804087FE8000003F802080208020803F80000
+BD59:00000008208820883F8820883F8804087FE800000208020803F8020803F80000
+BD5A:00000008208820883F8820883F8804087FE80000110811081F0811141F620000
+BD5B:00000008208820883F8820883F8804087FE80000001000100010006801840000
+BD5C:00000008208820883F8820883F8804087FE800000048004800A8011406620000
+BD5D:00000008208820883F8820883F8804087FE80000000003F00408040803F00000
+BD5E:00000008208820883F8820883F8804087FE8000003F80020002000D003080000
+BD5F:00000008208820883F8820883F8804087FE80000004003F8004000A003180000
+BD60:00000008208820883F8820883F8804087FE8000003F8000803F8000800080000
+BD61:00000008208820883F8820883F8804087FE8000003F8020003F8020003F80000
+BD62:00000008208820883F8820883F8804087FE8000000000FF8022002200FF80000
+BD63:00000008208820883F8820883F8804087FE8000000800FF803E0041003E00000
+BD64:000000001010101010101FF0101010101FF004400440044004407FFC00000000
+BD65:0000101010101FF010101FF0044004407FFC00001FF000100010001000100000
+BD66:0000101010101FF010101FF0044004407FFC000000003EF80208020802080000
+BD67:0000101010101FF010101FF0044004407FFC000000001E100210022802C40000
+BD68:0000101010101FF010101FF0044004407FFC000000001000100010001FF00000
+BD69:0000101010101FF010101FF0044004407FFC0000000020F8201020303ECC0000
+BD6A:0000101010101FF010101FF0044004407FFC0000202021FC207020883E700000
+BD6B:0000101010101FF010101FF0044004407FFC00001FF01000100010001FF00000
+BD6C:0000101010101FF010101FF0044004407FFC00001FF000101FF010001FF00000
+BD6D:0000101010101FF010101FF0044004407FFC00003EF802083E0820083E080000
+BD6E:0000101010101FF010101FF0044004407FFC00003EF802883E8820883EF80000
+BD6F:0000101010101FF010101FF0044004407FFC00003E8802883EF820883EF80000
+BD70:0000101010101FF010101FF0044004407FFC00003E1002103E1020283EC40000
+BD71:0000101010101FF010101FF0044004407FFC00003EF802803EF820803EF80000
+BD72:0000101010101FF010101FF0044004407FFC00003EFC02483E4820483EFC0000
+BD73:0000101010101FF010101FF0044004407FFC00003E2003FC3E7020883E700000
+BD74:0000101010101FF010101FF0044004407FFC00001FF01010101010101FF00000
+BD75:0000101010101FF010101FF0044004407FFC0000101010101FF010101FF00000
+BD76:0000101010101FF010101FF0044004407FFC0000222022203E2022503E880000
+BD77:0000101010101FF010101FF0044004407FFC000000000100010002800C400000
+BD78:0000101010101FF010101FF0044004407FFC00000000024002400DA033100000
+BD79:0000101010101FF010101FF0044004407FFC0000000007C00820082007C00000
+BD7A:0000101010101FF010101FF0044004407FFC0000000007E00080014006200000
+BD7B:0000101010101FF010101FF0044004407FFC0000008007E00080014006200000
+BD7C:0000101010101FF010101FF0044004407FFC00001FF000101FF0001000100000
+BD7D:0000101010101FF010101FF0044004407FFC00001FF010001FF010001FF00000
+BD7E:0000101010101FF010101FF0044004407FFC000000001FF0044004401FF00000
+BD7F:0000101010101FF010101FF0044004407FFC000001001FF007C0082007C00000
+BD80:000000001010101010101FF0101010101FF000003FF801000100010001000000
+BD81:0000101010101FF010101FF000007FFC010001001FF000100010001000100000
+BD82:0000101010101FF010101FF000007FFC0100010000003EF80208020802080000
+BD83:0000101010101FF010101FF000007FFC0100010000001E100210022802C40000
+BD84:0000101010101FF010101FF0000000007FFC010001001100100010001FF00000
+BD85:0000101010101FF010101FF000007FFC01000100000020F8201020303ECC0000
+BD86:0000101010101FF010101FF000007FFC01000100202021FC207020883E700000
+BD87:0000101010101FF010101FF000007FFC010001001FF01000100010001FF00000
+BD88:0000101010101FF010101FF000007FFC010001001FF000101FF010001FF00000
+BD89:0000101010101FF010101FF000007FFC010001003EF802083E0820083E080000
+BD8A:0000101010101FF010101FF000007FFC010001003EF802883E8820883EF80000
+BD8B:0000101010101FF010101FF000007FFC010001003E8802883EF820883EF80000
+BD8C:0000101010101FF010101FF000007FFC010001003E1002103E1020283EC40000
+BD8D:0000101010101FF010101FF000007FFC010001003EF802803EF820803EF80000
+BD8E:0000101010101FF010101FF000007FFC010001003EFC02483E4820483EFC0000
+BD8F:0000101010101FF010101FF000007FFC010001003E2003FC3E7020883E700000
+BD90:0000101010101FF010101FF000007FFC010001001FF01010101010101FF00000
+BD91:0000101010101FF010101FF000007FFC01000100101010101FF010101FF00000
+BD92:0000101010101FF010101FF000007FFC01000100222022203E2022503E880000
+BD93:0000101010101FF010101FF000007FFC0100010000000100010002800C400000
+BD94:0000101010101FF010101FF000007FFC010001000000024002400DA033100000
+BD95:0000101010101FF010101FF000007FFC01000100000007C00820082007C00000
+BD96:0000101010101FF010101FF000007FFC01000100000007E00080014006200000
+BD97:0000101010101FF010101FF000007FFC01000100008007E00080014006200000
+BD98:0000101010101FF010101FF000007FFC010001001FF000101FF0001000100000
+BD99:0000101010101FF010101FF000007FFC010001001FF010001FF010001FF00000
+BD9A:0000101010101FF010101FF000007FFC0100010000001FF0044004401FF00000
+BD9B:0000101010101FF010101FF000007FFC0100010001001FF007C0082007C00000
+BD9C:000000082088208820883F88208820883F8800087FE8040804F8040804080000
+BD9D:208820883F8820883F8800087FE8027802080000000007F80008000800080000
+BD9E:208820883F8820883F8800087FE802780208000000003EF80208020802080000
+BD9F:208820883F8820883F8800087FE802780208000000001F080108011401620000
+BDA0:208820883F8820883F88000800087FE80278020802081000100010001FF80000
+BDA1:208820883F8820883F8800087FE8027802080000000020F8201020303ECC0000
+BDA2:208820883F8820883F8800087FE8027802080000202021FC207020883E700000
+BDA3:208820883F8820883F8800087FE802780208000003F802000200020003F80000
+BDA4:208820883F8820883F8800087FE802780208000007F8000807F8040007F80000
+BDA5:208820883F8820883F8800087FE80278020800003EF802083E0820083E080000
+BDA6:208820883F8820883F8800087FE80278020800003EF802883E8820883EF80000
+BDA7:208820883F8820883F8800087FE80278020800003E8802883EF820883EF80000
+BDA8:208820883F8820883F8800087FE80278020800000F8800880F8808140FA20000
+BDA9:208820883F8820883F8800087FE80278020800003EF802803EF820803EF80000
+BDAA:208820883F8820883F8800087FE80278020800003EFC02483E4820483EFC0000
+BDAB:208820883F8820883F8800087FE80278020800003E1002FE3E3820443E380000
+BDAC:208820883F8820883F8800087FE802780208000003F802080208020803F80000
+BDAD:208820883F8820883F8800087FE80278020800000208020803F8020803F80000
+BDAE:208820883F8820883F8800087FE8027802080000210821083F0821143F620000
+BDAF:208820883F8820883F8800087FE8027802080000001000100010006801840000
+BDB0:208820883F8820883F8800087FE80278020800000048004800A8011406620000
+BDB1:208820883F8820883F8800087FE8027802080000000003F00408040803F00000
+BDB2:208820883F8820883F8800087FE802780208000003F80020002000D003080000
+BDB3:208820883F8820883F8800087FE8027802080000004003F8004000A003180000
+BDB4:208820883F8820883F8800087FE802780208000003F8000803F8000800080000
+BDB5:208820883F8820883F8800087FE802780208000003F8020003F8020003F80000
+BDB6:208820883F8820883F8800087FE802780208000000000FF8022002200FF80000
+BDB7:208820883F8820883F8800087FE802780208000000800FF803E0041003E00000
+BDB8:0000000A208A208A208A3F8A208A208A3F8A000A7FEA040A047A040A040A0000
+BDB9:20A820A83FA820A83FA800287FA805E804280000000007F80008000800080000
+BDBA:20A820A83FA820A83FA800287FA805E80428000000003EF80208020802080000
+BDBB:20A820A83FA820A83FA800287FA805E80428000000001F080108011401620000
+BDBC:20A820A83FA820A83FA8002800287FA8042805E804281428100010001FF80000
+BDBD:20A820A83FA820A83FA800287FA805E804280000000020F8201020303ECC0000
+BDBE:20A820A83FA820A83FA800287FA805E804280000202021FC207020883E700000
+BDBF:20A820A83FA820A83FA800287FA805E80428000003F802000200020003F80000
+BDC0:20A820A83FA820A83FA800287FA805E80428000007F8000807F8040007F80000
+BDC1:20A820A83FA820A83FA800287FA805E8042800003EF802083E0820083E080000
+BDC2:20A820A83FA820A83FA800287FA805E8042800003EF802883E8820883EF80000
+BDC3:20A820A83FA820A83FA800287FA805E8042800003E8802883EF820883EF80000
+BDC4:20A820A83FA820A83FA800287FA805E8042800000F8800880F8808140FA20000
+BDC5:20A820A83FA820A83FA800287FA805E8042800003EF802803EF820803EF80000
+BDC6:20A820A83FA820A83FA800287FA805E8042800003EFC02483E4820483EFC0000
+BDC7:20A820A83FA820A83FA800287FA805E8042800003E1002FE3E3820443E380000
+BDC8:20A820A83FA820A83FA800287FA805E80428000003F802080208020803F80000
+BDC9:20A820A83FA820A83FA800287FA805E8042800000208020803F8020803F80000
+BDCA:20A820A83FA820A83FA800287FA805E804280000210821083F0821143F620000
+BDCB:20A820A83FA820A83FA800287FA805E804280000001000100010006801840000
+BDCC:20A820A83FA820A83FA800287FA805E8042800000048004800A8011406620000
+BDCD:20A820A83FA820A83FA800287FA805E804280000000003F00408040803F00000
+BDCE:20A820A83FA820A83FA800287FA805E80428000003F80020002000D003080000
+BDCF:20A820A83FA820A83FA800287FA805E804280000004003F8004000A003180000
+BDD0:20A820A83FA820A83FA800287FA805E80428000003F8000803F8000800080000
+BDD1:20A820A83FA820A83FA800287FA805E80428000003F8020003F8020003F80000
+BDD2:20A820A83FA820A83FA800287FA805E80428000000000FF8022002200FF80000
+BDD3:20A820A83FA820A83FA800287FA805E80428000000800FF803E0041003E00000
+BDD4:000000082088208820883F88208820883F8800087FE804080408040804080000
+BDD5:208820883F8820883F8800087FE8020802000000000007F80008000800080000
+BDD6:208820883F8820883F8800087FE802080200000000003EF80208020802080000
+BDD7:208820883F8820883F8800087FE802080200000000001F080108011401620000
+BDD8:208820883F8820883F88000800087FE80208020802081008100010001FF80000
+BDD9:208820883F8820883F8800087FE8020802000000000020F8201020303ECC0000
+BDDA:208820883F8820883F8800087FE8020802000000202021FC207020883E700000
+BDDB:208820883F8820883F8800087FE802080200000003F802000200020003F80000
+BDDC:208820883F8820883F8800087FE802080200000007F8000807F8040007F80000
+BDDD:208820883F8820883F8800087FE80208020000003EF802083E0820083E080000
+BDDE:208820883F8820883F8800087FE80208020000003EF802883E8820883EF80000
+BDDF:208820883F8820883F8800087FE80208020000003E8802883EF820883EF80000
+BDE0:208820883F8820883F8800087FE80208020000000F8800880F8808140FA20000
+BDE1:208820883F8820883F8800087FE80208020000003EF802803EF820803EF80000
+BDE2:208820883F8820883F8800087FE80208020000003EFC02483E4820483EFC0000
+BDE3:208820883F8820883F8800087FE80208020000003E1002FE3E3820443E380000
+BDE4:208820883F8820883F8800087FE802080200000003F802080208020803F80000
+BDE5:208820883F8820883F8800087FE80208020000000208020803F8020803F80000
+BDE6:208820883F8820883F8800087FE8020802000000210821083F0821143F620000
+BDE7:208820883F8820883F8800087FE8020802000000001000100010006801840000
+BDE8:208820883F8820883F8800087FE80208020000000048004800A8011406620000
+BDE9:208820883F8820883F8800087FE8020802000000000003F00408040803F00000
+BDEA:208820883F8820883F8800087FE802080200000003F80020002000D003080000
+BDEB:208820883F8820883F8800087FE8020802000000004003F8004000A003180000
+BDEC:208820883F8820883F8800087FE802080200000003F8000803F8000800080000
+BDED:208820883F8820883F8800087FE802080200000003F8020003F8020003F80000
+BDEE:208820883F8820883F8800087FE802080200000000000FF8022002200FF80000
+BDEF:208820883F8820883F8800087FE802080200000000800FF803E0041003E00000
+BDF0:000000001010101010101FF0101010101FF000007FFC04400440044004400000
+BDF1:0000101010101FF010101FF000007FFC044004401FF000100010001000100000
+BDF2:0000101010101FF010101FF000007FFC0440044000003EF80208020802080000
+BDF3:0000101010101FF010101FF000007FFC0440044000001E100210022802C40000
+BDF4:0000101010101FF010101FF0000000007FFC044004401440100010001FF00000
+BDF5:0000101010101FF010101FF000007FFC04400440000020F8201020303ECC0000
+BDF6:0000101010101FF010101FF000007FFC04400440202021FC207020883E700000
+BDF7:0000101010101FF010101FF000007FFC044004401FF01000100010001FF00000
+BDF8:0000101010101FF010101FF000007FFC044004401FF000101FF010001FF00000
+BDF9:0000101010101FF010101FF000007FFC044004403EF802083E0820083E080000
+BDFA:0000101010101FF010101FF000007FFC044004403EF802883E8820883EF80000
+BDFB:0000101010101FF010101FF000007FFC044004403E8802883EF820883EF80000
+BDFC:0000101010101FF010101FF000007FFC044004403E1002103E1020283EC40000
+BDFD:0000101010101FF010101FF000007FFC044004403EF802803EF820803EF80000
+BDFE:0000101010101FF010101FF000007FFC044004403EFC02483E4820483EFC0000
+BDFF:0000101010101FF010101FF000007FFC044004403E2003FC3E7020883E700000
+BE00:0000101010101FF010101FF000007FFC044004401FF01010101010101FF00000
+BE01:0000101010101FF010101FF000007FFC04400440101010101FF010101FF00000
+BE02:0000101010101FF010101FF000007FFC04400440222022203E2022503E880000
+BE03:0000101010101FF010101FF000007FFC0440044000000100010002800C400000
+BE04:0000101010101FF010101FF000007FFC044004400000024002400DA033100000
+BE05:0000101010101FF010101FF000007FFC04400440000007C00820082007C00000
+BE06:0000101010101FF010101FF000007FFC04400440000007E00080014006200000
+BE07:0000101010101FF010101FF000007FFC04400440008007E00080014006200000
+BE08:0000101010101FF010101FF000007FFC044004401FF000101FF0001000100000
+BE09:0000101010101FF010101FF000007FFC044004401FF010001FF010001FF00000
+BE0A:0000101010101FF010101FF000007FFC0440044000001FF0044004401FF00000
+BE0B:0000101010101FF010101FF000007FFC0440044001001FF007C0082007C00000
+BE0C:000000001010101010101FF0101010101FF0000000007FFC0000000000000000
+BE0D:0000101010101FF010101FF0000000007FFC00001FF000100010001000100000
+BE0E:0000101010101FF010101FF0000000007FFC000000003EF80208020802080000
+BE0F:0000101010101FF010101FF0000000007FFC000000001E100210022802C40000
+BE10:0000101010101FF010101FF0000000007FFC000000001000100010001FF00000
+BE11:0000101010101FF010101FF0000000007FFC0000000020F8201020303ECC0000
+BE12:0000101010101FF010101FF0000000007FFC0000202021FC207020883E700000
+BE13:0000101010101FF010101FF0000000007FFC00001FF01000100010001FF00000
+BE14:0000101010101FF010101FF0000000007FFC00001FF000101FF010001FF00000
+BE15:0000101010101FF010101FF0000000007FFC00003EF802083E0820083E080000
+BE16:0000101010101FF010101FF0000000007FFC00003EF802883E8820883EF80000
+BE17:0000101010101FF010101FF0000000007FFC00003E8802883EF820883EF80000
+BE18:0000101010101FF010101FF0000000007FFC00003E1002103E1020283EC40000
+BE19:0000101010101FF010101FF0000000007FFC00003EF802803EF820803EF80000
+BE1A:0000101010101FF010101FF0000000007FFC00003EFC02483E4820483EFC0000
+BE1B:0000101010101FF010101FF0000000007FFC00003E2003FC3E7020883E700000
+BE1C:0000101010101FF010101FF0000000007FFC00001FF01010101010101FF00000
+BE1D:0000101010101FF010101FF0000000007FFC0000101010101FF010101FF00000
+BE1E:0000101010101FF010101FF0000000007FFC0000222022203E2022503E880000
+BE1F:0000101010101FF010101FF0000000007FFC000000000100010002800C400000
+BE20:0000101010101FF010101FF0000000007FFC00000000024002400DA033100000
+BE21:0000101010101FF010101FF0000000007FFC0000000007C00820082007C00000
+BE22:0000101010101FF010101FF0000000007FFC0000000007E00080014006200000
+BE23:0000101010101FF010101FF0000000007FFC0000008007E00080014006200000
+BE24:0000101010101FF010101FF0000000007FFC00001FF000101FF0001000100000
+BE25:0000101010101FF010101FF0000000007FFC00001FF010001FF010001FF00000
+BE26:0000101010101FF010101FF0000000007FFC000000001FF0044004401FF00000
+BE27:0000101010101FF010101FF0000000007FFC000001001FF007C0082007C00000
+BE28:0000000800082088208820883F88208820883F8800087FE80008000800080000
+BE29:00000008208820883F8820883F8800087FE8000007F800080008000800080000
+BE2A:00000008208820883F8820883F8800087FE8000000003EF80208020802080000
+BE2B:00000008208820883F8820883F8800087FE8000000001F080108011401620000
+BE2C:00000008208820883F8820883F8800087FE8000008000800080008000FF80000
+BE2D:00000008208820883F8820883F8800087FE80000000010F8101010301ECC0000
+BE2E:00000008208820883F8820883F8800087FE800000808087F081C08220F9C0000
+BE2F:00000008208820883F8820883F8800087FE8000003F802000200020003F80000
+BE30:00000008208820883F8820883F8800087FE8000007F8000807F8040007F80000
+BE31:00000008208820883F8820883F8800087FE800003EF802083E0820083E080000
+BE32:00000008208820883F8820883F8800087FE800003EF802883E8820883EF80000
+BE33:00000008208820883F8820883F8800087FE800003E8802883EF820883EF80000
+BE34:00000008208820883F8820883F8800087FE800001F0801081F0810141F620000
+BE35:00000008208820883F8820883F8800087FE800003EF802803EF820803EF80000
+BE36:00000008208820883F8820883F8800087FE800003EFC02483E4820483EFC0000
+BE37:00000008208820883F8820883F8800087FE800001F08017F1F1C10221F1C0000
+BE38:00000008208820883F8820883F8800087FE8000003F802080208020803F80000
+BE39:00000008208820883F8820883F8800087FE800000208020803F8020803F80000
+BE3A:00000008208820883F8820883F8800087FE80000110811081F0811141F620000
+BE3B:00000008208820883F8820883F8800087FE80000001000100010006801840000
+BE3C:00000008208820883F8820883F8800087FE800000048004800A8011406620000
+BE3D:00000008208820883F8820883F8800087FE80000000003F00408040803F00000
+BE3E:00000008208820883F8820883F8800087FE8000003F80020002000D003080000
+BE3F:00000008208820883F8820883F8800087FE80000004003F8004000A003180000
+BE40:00000008208820883F8820883F8800087FE8000003F8000803F8000800080000
+BE41:00000008208820883F8820883F8800087FE8000003F8020003F8020003F80000
+BE42:00000008208820883F8820883F8800087FE8000000000FF8022002200FF80000
+BE43:00000008208820883F8820883F8800087FE8000000800FF803E0041003E00000
+BE44:00000000000800082088208820883F882088208820883F880008000800080000
+BE45:000000080008420842087E0842087E0800080000000007F80008000800080000
+BE46:000000080008420842087E0842087E080008000000003EF80208020802080000
+BE47:000000080008420842087E0842087E080008000000001F080108011401620000
+BE48:000000080008420842087E0842087E080008000800001000100010001FF80000
+BE49:000000080008420842087E0842087E0800080000000020F8201020303ECC0000
+BE4A:000000080008420842087E0842087E0800080000202021FC207020883E700000
+BE4B:000000080008420842087E0842087E080008000003F802000200020003F80000
+BE4C:000000080008420842087E0842087E080008000007F8000807F8040007F80000
+BE4D:000000080008420842087E0842087E08000800003EF802083E0820083E080000
+BE4E:000000080008420842087E0842087E08000800003EF802883E8820883EF80000
+BE4F:000000080008420842087E0842087E08000800003E8802883EF820883EF80000
+BE50:000000080008420842087E0842087E08000800000F8800880F8808140FA20000
+BE51:000000080008420842087E0842087E08000800003EF802803EF820803EF80000
+BE52:000000080008420842087E0842087E08000800003EFC02483E4820483EFC0000
+BE53:000000080008420842087E0842087E08000800003E1002FE3E3820443E380000
+BE54:000000080008420842087E0842087E080008000003F802080208020803F80000
+BE55:000000080008420842087E0842087E08000800000208020803F8020803F80000
+BE56:000000080008420842087E0842087E0800080000210821083F0821143F620000
+BE57:000000080008420842087E0842087E0800080000001000100010006801840000
+BE58:000000080008420842087E0842087E08000800000048004800A8011406620000
+BE59:000000080008420842087E0842087E0800080000000003F00408040803F00000
+BE5A:000000080008420842087E0842087E080008000003F80020002000D003080000
+BE5B:000000080008420842087E0842087E0800080000004003F8004000A003180000
+BE5C:000000080008420842087E0842087E080008000003F8000803F8000800080000
+BE5D:000000080008420842087E0842087E080008000003F8020003F8020003F80000
+BE5E:000000080008420842087E0842087E080008000000000FF8022002200FF80000
+BE5F:000000080008420842087E0842087E080008000000800FF803E0041003E00000
+BE60:00000000001000102490249024903F9E249024903F9000100010001000100000
+BE61:000000084908490849087F0E49087F080008000007F800080008000800080000
+BE62:000000084908490849087F0E49087F080008000000003EF80208020802080000
+BE63:000000084908490849087F0E49087F080008000000001F080108011401620000
+BE64:000000084908490849087F0E49087F080008000808000800080008000FF80000
+BE65:000000084908490849087F0E49087F0800080000000010F8101010301ECC0000
+BE66:000000084908490849087F0E49087F08000800000808087F081C08220F9C0000
+BE67:000000084908490849087F0E49087F080008000003F802000200020003F80000
+BE68:000000084908490849087F0E49087F080008000007F8000807F8040007F80000
+BE69:000000084908490849087F0E49087F08000800003EF802083E0820083E080000
+BE6A:000000084908490849087F0E49087F08000800003EF802883E8820883EF80000
+BE6B:000000084908490849087F0E49087F08000800003E8802883EF820883EF80000
+BE6C:000000084908490849087F0E49087F08000800001F0801081F0810141F620000
+BE6D:000000084908490849087F0E49087F08000800003EF802803EF820803EF80000
+BE6E:000000084908490849087F0E49087F08000800003EFC02483E4820483EFC0000
+BE6F:000000084908490849087F0E49087F08000800001F08017F1F1C10221F1C0000
+BE70:000000084908490849087F0E49087F080008000003F802080208020803F80000
+BE71:000000084908490849087F0E49087F08000800000208020803F8020803F80000
+BE72:000000084908490849087F0E49087F0800080000110811081F0811141F620000
+BE73:000000084908490849087F0E49087F0800080000001000100010006801840000
+BE74:000000084908490849087F0E49087F08000800000048004800A8011406620000
+BE75:000000084908490849087F0E49087F0800080000000003F00408040803F00000
+BE76:000000084908490849087F0E49087F080008000003F80020002000D003080000
+BE77:000000084908490849087F0E49087F0800080000004003F8004000A003180000
+BE78:000000084908490849087F0E49087F080008000003F8000803F8000800080000
+BE79:000000084908490849087F0E49087F080008000003F8020003F8020003F80000
+BE7A:000000084908490849087F0E49087F080008000000000FF8022002200FF80000
+BE7B:000000084908490849087F0E49087F080008000000800FF803E0041003E00000
+BE7C:00000000001200122492249224923F9E249224923F9200120012001200120000
+BE7D:000000284928492849287F3849287F280028000007F800080008000800080000
+BE7E:000000284928492849287F3849287F280028000000003EF80208020802080000
+BE7F:000000284928492849287F3849287F280028000000003E100210022802C40000
+BE80:000000284928492849287F3849287F280028002808000800080008000FF80000
+BE81:000000284928492849287F3849287F2800280000000020F8201020303ECC0000
+BE82:000000284928492849287F3849287F2800280000202021FC207020883E700000
+BE83:000000284928492849287F3849287F280028000003F802000200020003F80000
+BE84:000000284928492849287F3849287F280028000007F8000807F8040007F80000
+BE85:000000284928492849287F3849287F28002800003EF802083E0820083E080000
+BE86:000000284928492849287F3849287F28002800003EF802883E8820883EF80000
+BE87:000000284928492849287F3849287F28002800003E8802883EF820883EF80000
+BE88:000000284928492849287F3849287F28002800001F0801081F0810141F620000
+BE89:000000284928492849287F3849287F28002800003EF802803EF820803EF80000
+BE8A:000000284928492849287F3849287F28002800003EFC02483E4820483EFC0000
+BE8B:000000284928492849287F3849287F28002800003E1002FE3E3820443E380000
+BE8C:000000284928492849287F3849287F280028000003F802080208020803F80000
+BE8D:000000284928492849287F3849287F28002800000208020803F8020803F80000
+BE8E:000000284928492849287F3849287F2800280000110811081F0811141F620000
+BE8F:000000284928492849287F3849287F2800280000000800080008003400C20000
+BE90:000000284928492849287F3849287F28002800000048004800A8011406620000
+BE91:000000284928492849287F3849287F2800280000000001F00208020801F00000
+BE92:000000284928492849287F3849287F280028000003F80020002000D003080000
+BE93:000000284928492849287F3849287F2800280000004003F8004000A003180000
+BE94:000000284928492849287F3849287F280028000003F8000803F8000800080000
+BE95:000000284928492849287F3849287F280028000003F8020003F8020003F80000
+BE96:000000284928492849287F3849287F280028000000000FF8022002200FF80000
+BE97:000000284928492849287F3849287F280028000000800FF803E0041003E00000
+BE98:000000000010001024902490249E3F902490249E3F9000100010001000100000
+BE99:0000000849084908490E7F08490E7F080008000007F800080008000800080000
+BE9A:0000000849084908490E7F08490E7F080008000000003EF80208020802080000
+BE9B:0000000849084908490E7F08490E7F080008000000001F080108011401620000
+BE9C:0000000849084908490E7F08490E7F080008000008000800080008000FF80000
+BE9D:0000000849084908490E7F08490E7F0800080000000010F8101010301ECC0000
+BE9E:0000000849084908490E7F08490E7F08000800000808087F081C08220F9C0000
+BE9F:0000000849084908490E7F08490E7F080008000003F802000200020003F80000
+BEA0:0000000849084908490E7F08490E7F080008000007F8000807F8040007F80000
+BEA1:0000000849084908490E7F08490E7F08000800003EF802083E0820083E080000
+BEA2:0000000849084908490E7F08490E7F08000800003EF802883E8820883EF80000
+BEA3:0000000849084908490E7F08490E7F08000800003E8802883EF820883EF80000
+BEA4:0000000849084908490E7F08490E7F08000800001F0801081F0810141F620000
+BEA5:0000000849084908490E7F08490E7F08000800003EF802803EF820803EF80000
+BEA6:0000000849084908490E7F08490E7F08000800003EFC02483E4820483EFC0000
+BEA7:0000000849084908490E7F08490E7F08000800001F08017F1F1C10221F1C0000
+BEA8:0000000849084908490E7F08490E7F080008000003F802080208020803F80000
+BEA9:0000000849084908490E7F08490E7F08000800000208020803F8020803F80000
+BEAA:0000000849084908490E7F08490E7F0800080000110811081F0811141F620000
+BEAB:0000000849084908490E7F08490E7F0800080000001000100010006801840000
+BEAC:0000000849084908490E7F08490E7F08000800000048004800A8011406620000
+BEAD:0000000849084908490E7F08490E7F0800080000000003F00408040803F00000
+BEAE:0000000849084908490E7F08490E7F080008000003F80020002000D003080000
+BEAF:0000000849084908490E7F08490E7F0800080000004003F8004000A003180000
+BEB0:0000000849084908490E7F08490E7F080008000003F8000803F8000800080000
+BEB1:0000000849084908490E7F08490E7F080008000003F8020003F8020003F80000
+BEB2:0000000849084908490E7F08490E7F080008000000000FF8022002200FF80000
+BEB3:0000000849084908490E7F08490E7F080008000000800FF803E0041003E00000
+BEB4:000000000012001224922492249E3F922492249E3F9200120012001200120000
+BEB5:000000284928492849387F2849387F280028000007F800080008000800080000
+BEB6:000000284928492849387F2849387F280028000000003EF80208020802080000
+BEB7:000000284928492849387F2849387F280028000000003E100210022802C40000
+BEB8:000000284928492849387F2849387F280028002808000800080008000FF80000
+BEB9:000000284928492849387F2849387F2800280000000020F8201020303ECC0000
+BEBA:000000284928492849387F2849387F2800280000202021FC207020883E700000
+BEBB:000000284928492849387F2849387F280028000003F802000200020003F80000
+BEBC:000000284928492849387F2849387F280028000007F8000807F8040007F80000
+BEBD:000000284928492849387F2849387F28002800003EF802083E0820083E080000
+BEBE:000000284928492849387F2849387F28002800003EF802883E8820883EF80000
+BEBF:000000284928492849387F2849387F28002800003E8802883EF820883EF80000
+BEC0:000000284928492849387F2849387F28002800001F0801081F0810141F620000
+BEC1:000000284928492849387F2849387F28002800003EF802803EF820803EF80000
+BEC2:000000284928492849387F2849387F28002800003EFC02483E4820483EFC0000
+BEC3:000000284928492849387F2849387F28002800003E1002FE3E3820443E380000
+BEC4:000000284928492849387F2849387F280028000003F802080208020803F80000
+BEC5:000000284928492849387F2849387F28002800000208020803F8020803F80000
+BEC6:000000284928492849387F2849387F2800280000110811081F0811141F620000
+BEC7:000000284928492849387F2849387F2800280000000800080008003400C20000
+BEC8:000000284928492849387F2849387F28002800000048004800A8011406620000
+BEC9:000000284928492849387F2849387F2800280000000001F00208020801F00000
+BECA:000000284928492849387F2849387F280028000003F80020002000D003080000
+BECB:000000284928492849387F2849387F2800280000004003F8004000A003180000
+BECC:000000284928492849387F2849387F280028000003F8000803F8000800080000
+BECD:000000284928492849387F2849387F280028000003F8020003F8020003F80000
+BECE:000000284928492849387F2849387F280028000000000FF8022002200FF80000
+BECF:000000284928492849387F2849387F280028000000800FF803E0041003E00000
+BED0:00000000000200022482248224823F9E248224823F8200020002000200020000
+BED1:000000084908490849087F3849087F0800080000000007F80008000800080000
+BED2:000000084908490849087F3849087F080008000000003EF80208020802080000
+BED3:000000084908490849087F3849087F080008000000001F080108011401620000
+BED4:000000084908490849087F3849087F080008000000001000100010001FF80000
+BED5:000000084908490849087F3849087F0800080000000020F8201020303ECC0000
+BED6:000000084908490849087F3849087F0800080000202021FC207020883E700000
+BED7:000000084908490849087F3849087F080008000003F802000200020003F80000
+BED8:000000084908490849087F3849087F080008000007F8000807F8040007F80000
+BED9:000000084908490849087F3849087F08000800003EF802083E0820083E080000
+BEDA:000000084908490849087F3849087F08000800003EF802883E8820883EF80000
+BEDB:000000084908490849087F3849087F08000800003E8802883EF820883EF80000
+BEDC:000000084908490849087F3849087F08000800000F8800880F8808140FA20000
+BEDD:000000084908490849087F3849087F08000800003EF802803EF820803EF80000
+BEDE:000000084908490849087F3849087F08000800003EFC02483E4820483EFC0000
+BEDF:000000084908490849087F3849087F08000800003E1002FE3E3820443E380000
+BEE0:000000084908490849087F3849087F080008000003F802080208020803F80000
+BEE1:000000084908490849087F3849087F08000800000208020803F8020803F80000
+BEE2:000000084908490849087F3849087F0800080000210821083F0821143F620000
+BEE3:000000084908490849087F3849087F0800080000001000100010006801840000
+BEE4:000000084908490849087F3849087F08000800000048004800A8011406620000
+BEE5:000000084908490849087F3849087F0800080000000003F00408040803F00000
+BEE6:000000084908490849087F3849087F080008000003F80020002000D003080000
+BEE7:000000084908490849087F3849087F0800080000004003F8004000A003180000
+BEE8:000000084908490849087F3849087F080008000003F8000803F8000800080000
+BEE9:000000084908490849087F3849087F080008000003F8020003F8020003F80000
+BEEA:000000084908490849087F3849087F080008000000000FF8022002200FF80000
+BEEB:000000084908490849087F3849087F080008000000800FF803E0041003E00000
+BEEC:00000000000A000A248A248A248A3FBA248A248A3F8A000A000A000A000A0000
+BEED:000000284928492849287FE849287F280028000007F800080008000800080000
+BEEE:000000284928492849287FE849287F280028000000003EF80208020802080000
+BEEF:000000284928492849287FE849287F280028000000003E100210022802C40000
+BEF0:000000284928492849287FE849287F280028000008000800080008000FF80000
+BEF1:000000284928492849287FE849287F2800280000000020F8201020303ECC0000
+BEF2:000000284928492849287FE849287F2800280000202021FC207020883E700000
+BEF3:000000284928492849287FE849287F280028000003F802000200020003F80000
+BEF4:000000284928492849287FE849287F280028000007F8000807F8040007F80000
+BEF5:000000284928492849287FE849287F28002800003EF802083E0820083E080000
+BEF6:000000284928492849287FE849287F28002800003EF802883E8820883EF80000
+BEF7:000000284928492849287FE849287F28002800003E8802883EF820883EF80000
+BEF8:000000284928492849287FE849287F28002800001F0801081F0810141F620000
+BEF9:000000284928492849287FE849287F28002800003EF802803EF820803EF80000
+BEFA:000000284928492849287FE849287F28002800003EFC02483E4820483EFC0000
+BEFB:000000284928492849287FE849287F28002800003E1002FE3E3820443E380000
+BEFC:000000284928492849287FE849287F280028000003F802080208020803F80000
+BEFD:000000284928492849287FE849287F28002800000208020803F8020803F80000
+BEFE:000000284928492849287FE849287F2800280000110811081F0811141F620000
+BEFF:000000284928492849287FE849287F2800280000000800080008003400C20000
+BF00:000000284928492849287FE849287F28002800000048004800A8011406620000
+BF01:000000284928492849287FE849287F2800280000000001F00208020801F00000
+BF02:000000284928492849287FE849287F280028000003F80020002000D003080000
+BF03:000000284928492849287FE849287F2800280000004003F8004000A003180000
+BF04:000000284928492849287FE849287F280028000003F8000803F8000800080000
+BF05:000000284928492849287FE849287F280028000003F8020003F8020003F80000
+BF06:000000284928492849287FE849287F280028000000000FF8022002200FF80000
+BF07:000000284928492849287FE849287F280028000000800FF803E0041003E00000
+BF08:000000000002000224822482249E3F822482249E3F8200020002000200020000
+BF09:000000084908490849387F0849387F0800080000000007F80008000800080000
+BF0A:000000084908490849387F0849387F080008000000003EF80208020802080000
+BF0B:000000084908490849387F0849387F080008000000001F080108011401620000
+BF0C:000000084908490849387F0849387F080008000800001000100010001FF80000
+BF0D:000000084908490849387F0849387F0800080000000020F8201020303ECC0000
+BF0E:000000084908490849387F0849387F0800080000202021FC207020883E700000
+BF0F:000000084908490849387F0849387F080008000003F802000200020003F80000
+BF10:000000084908490849387F0849387F080008000007F8000807F8040007F80000
+BF11:000000084908490849387F0849387F08000800003EF802083E0820083E080000
+BF12:000000084908490849387F0849387F08000800003EF802883E8820883EF80000
+BF13:000000084908490849387F0849387F08000800003E8802883EF820883EF80000
+BF14:000000084908490849387F0849387F08000800000F8800880F8808140FA20000
+BF15:000000084908490849387F0849387F08000800003EF802803EF820803EF80000
+BF16:000000084908490849387F0849387F08000800003EFC02483E4820483EFC0000
+BF17:000000084908490849387F0849387F08000800003E1002FE3E3820443E380000
+BF18:000000084908490849387F0849387F080008000003F802080208020803F80000
+BF19:000000084908490849387F0849387F08000800000208020803F8020803F80000
+BF1A:000000084908490849387F0849387F0800080000210821083F0821143F620000
+BF1B:000000084908490849387F0849387F0800080000001000100010006801840000
+BF1C:000000084908490849387F0849387F08000800000048004800A8011406620000
+BF1D:000000084908490849387F0849387F0800080000000003F00408040803F00000
+BF1E:000000084908490849387F0849387F080008000003F80020002000D003080000
+BF1F:000000084908490849387F0849387F0800080000004003F8004000A003180000
+BF20:000000084908490849387F0849387F080008000003F8000803F8000800080000
+BF21:000000084908490849387F0849387F080008000003F8020003F8020003F80000
+BF22:000000084908490849387F0849387F080008000000000FF8022002200FF80000
+BF23:000000084908490849387F0849387F080008000000800FF803E0041003E00000
+BF24:00000000000A000A248A248A24BA3F8A248A24BA3F8A000A000A000A000A0000
+BF25:000000284928492849E87F2849E87F280028000007F800080008000800080000
+BF26:000000284928492849E87F2849E87F280028000000003EF80208020802080000
+BF27:000000284928492849E87F2849E87F280028000000003E100210022802C40000
+BF28:000000284928492849E87F2849E87F280028002808000800080008000FF80000
+BF29:000000284928492849E87F2849E87F2800280000000020F8201020303ECC0000
+BF2A:000000284928492849E87F2849E87F2800280000202021FC207020883E700000
+BF2B:000000284928492849E87F2849E87F280028000003F802000200020003F80000
+BF2C:000000284928492849E87F2849E87F280028000007F8000807F8040007F80000
+BF2D:000000284928492849E87F2849E87F28002800003EF802083E0820083E080000
+BF2E:000000284928492849E87F2849E87F28002800003EF802883E8820883EF80000
+BF2F:000000284928492849E87F2849E87F28002800003E8802883EF820883EF80000
+BF30:000000284928492849E87F2849E87F28002800001F0801081F0810141F620000
+BF31:000000284928492849E87F2849E87F28002800003EF802803EF820803EF80000
+BF32:000000284928492849E87F2849E87F28002800003EFC02483E4820483EFC0000
+BF33:000000284928492849E87F2849E87F28002800003E1002FE3E3820443E380000
+BF34:000000284928492849E87F2849E87F280028000003F802080208020803F80000
+BF35:000000284928492849E87F2849E87F28002800000208020803F8020803F80000
+BF36:000000284928492849E87F2849E87F2800280000110811081F0811141F620000
+BF37:000000284928492849E87F2849E87F2800280000000800080008003400C20000
+BF38:000000284928492849E87F2849E87F28002800000048004800A8011406620000
+BF39:000000284928492849E87F2849E87F2800280000000001F00208020801F00000
+BF3A:000000284928492849E87F2849E87F280028000003F80020002000D003080000
+BF3B:000000284928492849E87F2849E87F2800280000004003F8004000A003180000
+BF3C:000000284928492849E87F2849E87F280028000003F8000803F8000800080000
+BF3D:000000284928492849E87F2849E87F280028000003F8020003F8020003F80000
+BF3E:000000284928492849E87F2849E87F280028000000000FF8022002200FF80000
+BF3F:000000284928492849E87F2849E87F280028000000800FF803E0041003E00000
+BF40:000000002108210821083FF8210821083FF800000100010001007FFC00000000
+BF41:0000210821083FF821083FF8010001007FFC00001FF000100010001000100000
+BF42:0000210821083FF821083FF8010001007FFC000000003EF80208020802080000
+BF43:0000210821083FF821083FF8010001007FFC000000001E100210022802C40000
+BF44:0000210821083FF821083FF8010001007FFC000000001000100010001FF00000
+BF45:0000210821083FF821083FF8010001007FFC0000000020F8201020303ECC0000
+BF46:0000210821083FF821083FF8010001007FFC0000202021FC207020883E700000
+BF47:0000210821083FF821083FF8010001007FFC00001FF01000100010001FF00000
+BF48:0000210821083FF821083FF8010001007FFC00001FF000101FF010001FF00000
+BF49:0000210821083FF821083FF8010001007FFC00003EF802083E0820083E080000
+BF4A:0000210821083FF821083FF8010001007FFC00003EF802883E8820883EF80000
+BF4B:0000210821083FF821083FF8010001007FFC00003E8802883EF820883EF80000
+BF4C:0000210821083FF821083FF8010001007FFC00003E1002103E1020283EC40000
+BF4D:0000210821083FF821083FF8010001007FFC00003EF802803EF820803EF80000
+BF4E:0000210821083FF821083FF8010001007FFC00003EFC02483E4820483EFC0000
+BF4F:0000210821083FF821083FF8010001007FFC00003E2003FC3E7020883E700000
+BF50:0000210821083FF821083FF8010001007FFC00001FF01010101010101FF00000
+BF51:0000210821083FF821083FF8010001007FFC0000101010101FF010101FF00000
+BF52:0000210821083FF821083FF8010001007FFC0000222022203E2022503E880000
+BF53:0000210821083FF821083FF8010001007FFC000000000100010002800C400000
+BF54:0000210821083FF821083FF8010001007FFC00000000024002400DA033100000
+BF55:0000210821083FF821083FF8010001007FFC0000000007C00820082007C00000
+BF56:0000210821083FF821083FF8010001007FFC0000000007E00080014006200000
+BF57:0000210821083FF821083FF8010001007FFC0000008007E00080014006200000
+BF58:0000210821083FF821083FF8010001007FFC00001FF000101FF0001000100000
+BF59:0000210821083FF821083FF8010001007FFC00001FF010001FF010001FF00000
+BF5A:0000210821083FF821083FF8010001007FFC000000001FF0044004401FF00000
+BF5B:0000210821083FF821083FF8010001007FFC000001001FF007C0082007C00000
+BF5C:0000001000104450445044507FD0445E44507FD0041004107FD0001000100000
+BF5D:0000248824883F88248E3F88040804087FE8000007F800080008000800080000
+BF5E:0000248824883F88248E3F88040804087FE8000000003EF80208020802080000
+BF5F:0000248824883F88248E3F88040804087FE8000000001F080108011401620000
+BF60:0000248824883F88248E3F88040804087FE8000008000800080008000FF80000
+BF61:0000248824883F88248E3F88040804087FE80000000010F8101010301ECC0000
+BF62:0000248824883F88248E3F88040804087FE800000808087F081C08220F9C0000
+BF63:0000248824883F88248E3F88040804087FE8000003F802000200020003F80000
+BF64:0000248824883F88248E3F88040804087FE8000007F8000807F8040007F80000
+BF65:0000248824883F88248E3F88040804087FE800003EF802083E0820083E080000
+BF66:0000248824883F88248E3F88040804087FE800003EF802883E8820883EF80000
+BF67:0000248824883F88248E3F88040804087FE800003E8802883EF820883EF80000
+BF68:0000248824883F88248E3F88040804087FE800001F0801081F0810141F620000
+BF69:0000248824883F88248E3F88040804087FE800003EF802803EF820803EF80000
+BF6A:0000248824883F88248E3F88040804087FE800003EFC02483E4820483EFC0000
+BF6B:0000248824883F88248E3F88040804087FE800001F08017F1F1C10221F1C0000
+BF6C:0000248824883F88248E3F88040804087FE8000003F802080208020803F80000
+BF6D:0000248824883F88248E3F88040804087FE800000208020803F8020803F80000
+BF6E:0000248824883F88248E3F88040804087FE80000110811081F0811141F620000
+BF6F:0000248824883F88248E3F88040804087FE80000001000100010006801840000
+BF70:0000248824883F88248E3F88040804087FE800000048004800A8011406620000
+BF71:0000248824883F88248E3F88040804087FE80000000003F00408040803F00000
+BF72:0000248824883F88248E3F88040804087FE8000003F80020002000D003080000
+BF73:0000248824883F88248E3F88040804087FE80000004003F8004000A003180000
+BF74:0000248824883F88248E3F88040804087FE8000003F8000803F8000800080000
+BF75:0000248824883F88248E3F88040804087FE8000003F8020003F8020003F80000
+BF76:0000248824883F88248E3F88040804087FE8000000000FF8022002200FF80000
+BF77:0000248824883F88248E3F88040804087FE8000000800FF803E0041003E00000
+BF78:0000001200124452445244527FD2445E44527FD2041204127FD2001200120000
+BF79:000024A824A83FA824B83FA8042804287FA8000007F800080008000800080000
+BF7A:000024A824A83FA824B83FA8042804287FA8000000003EF80208020802080000
+BF7B:000024A824A83FA824B83FA8042804287FA8000000001F080108011401620000
+BF7C:000024A824A83FA824B83FA8042804287FA8000008000800080008000FF80000
+BF7D:000024A824A83FA824B83FA8042804287FA80000000010F8101010301ECC0000
+BF7E:000024A824A83FA824B83FA8042804287FA800000808087F081C08220F9C0000
+BF7F:000024A824A83FA824B83FA8042804287FA8000003F802000200020003F80000
+BF80:000024A824A83FA824B83FA8042804287FA8000007F8000807F8040007F80000
+BF81:000024A824A83FA824B83FA8042804287FA800003EF802083E0820083E080000
+BF82:000024A824A83FA824B83FA8042804287FA800003EF802883E8820883EF80000
+BF83:000024A824A83FA824B83FA8042804287FA800003E8802883EF820883EF80000
+BF84:000024A824A83FA824B83FA8042804287FA800001F0801081F0810141F620000
+BF85:000024A824A83FA824B83FA8042804287FA800003EF802803EF820803EF80000
+BF86:000024A824A83FA824B83FA8042804287FA800003EFC02483E4820483EFC0000
+BF87:000024A824A83FA824B83FA8042804287FA800001F08017F1F1C10221F1C0000
+BF88:000024A824A83FA824B83FA8042804287FA8000003F802080208020803F80000
+BF89:000024A824A83FA824B83FA8042804287FA800000208020803F8020803F80000
+BF8A:000024A824A83FA824B83FA8042804287FA80000110811081F0811141F620000
+BF8B:000024A824A83FA824B83FA8042804287FA80000001000100010006801840000
+BF8C:000024A824A83FA824B83FA8042804287FA800000048004800A8011406620000
+BF8D:000024A824A83FA824B83FA8042804287FA80000000003F00408040803F00000
+BF8E:000024A824A83FA824B83FA8042804287FA8000003F80020002000D003080000
+BF8F:000024A824A83FA824B83FA8042804287FA80000004003F8004000A003180000
+BF90:000024A824A83FA824B83FA8042804287FA8000003F8000803F8000800080000
+BF91:000024A824A83FA824B83FA8042804287FA8000003F8020003F8020003F80000
+BF92:000024A824A83FA824B83FA8042804287FA8000000000FF8022002200FF80000
+BF93:000024A824A83FA824B83FA8042804287FA8000000800FF803E0041003E00000
+BF94:0000000800084448444844487FC8444844487FC8040804087FE8000800080000
+BF95:0000248824883F8824883F88040804087FE8000007F800080008000800080000
+BF96:0000248824883F8824883F88040804087FE8000000003EF80208020802080000
+BF97:0000248824883F8824883F88040804087FE8000000001F080108011401620000
+BF98:0000248824883F8824883F88040804087FE8000008000800080008000FF80000
+BF99:0000248824883F8824883F88040804087FE80000000010F8101010301ECC0000
+BF9A:0000248824883F8824883F88040804087FE800000808087F081C08220F9C0000
+BF9B:0000248824883F8824883F88040804087FE8000003F802000200020003F80000
+BF9C:0000248824883F8824883F88040804087FE8000007F8000807F8040007F80000
+BF9D:0000248824883F8824883F88040804087FE800003EF802083E0820083E080000
+BF9E:0000248824883F8824883F88040804087FE800003EF802883E8820883EF80000
+BF9F:0000248824883F8824883F88040804087FE800003E8802883EF820883EF80000
+BFA0:0000248824883F8824883F88040804087FE800001F0801081F0810141F620000
+BFA1:0000248824883F8824883F88040804087FE800003EF802803EF820803EF80000
+BFA2:0000248824883F8824883F88040804087FE800003EFC02483E4820483EFC0000
+BFA3:0000248824883F8824883F88040804087FE800001F08017F1F1C10221F1C0000
+BFA4:0000248824883F8824883F88040804087FE8000003F802080208020803F80000
+BFA5:0000248824883F8824883F88040804087FE800000208020803F8020803F80000
+BFA6:0000248824883F8824883F88040804087FE80000110811081F0811141F620000
+BFA7:0000248824883F8824883F88040804087FE80000001000100010006801840000
+BFA8:0000248824883F8824883F88040804087FE800000048004800A8011406620000
+BFA9:0000248824883F8824883F88040804087FE80000000003F00408040803F00000
+BFAA:0000248824883F8824883F88040804087FE8000003F80020002000D003080000
+BFAB:0000248824883F8824883F88040804087FE80000004003F8004000A003180000
+BFAC:0000248824883F8824883F88040804087FE8000003F8000803F8000800080000
+BFAD:0000248824883F8824883F88040804087FE8000003F8020003F8020003F80000
+BFAE:0000248824883F8824883F88040804087FE8000000000FF8022002200FF80000
+BFAF:0000248824883F8824883F88040804087FE8000000800FF803E0041003E00000
+BFB0:000000002108210821083FF8210821083FF804400440044004407FFC00000000
+BFB1:0000210821083FF821083FF8044004407FFC00001FF000100010001000100000
+BFB2:0000210821083FF821083FF8044004407FFC000000003EF80208020802080000
+BFB3:0000210821083FF821083FF8044004407FFC000000001E100210022802C40000
+BFB4:0000210821083FF821083FF8044004407FFC000000001000100010001FF00000
+BFB5:0000210821083FF821083FF8044004407FFC0000000020F8201020303ECC0000
+BFB6:0000210821083FF821083FF8044004407FFC0000202021FC207020883E700000
+BFB7:0000210821083FF821083FF8044004407FFC00001FF01000100010001FF00000
+BFB8:0000210821083FF821083FF8044004407FFC00001FF000101FF010001FF00000
+BFB9:0000210821083FF821083FF8044004407FFC00003EF802083E0820083E080000
+BFBA:0000210821083FF821083FF8044004407FFC00003EF802883E8820883EF80000
+BFBB:0000210821083FF821083FF8044004407FFC00003E8802883EF820883EF80000
+BFBC:0000210821083FF821083FF8044004407FFC00003E1002103E1020283EC40000
+BFBD:0000210821083FF821083FF8044004407FFC00003EF802803EF820803EF80000
+BFBE:0000210821083FF821083FF8044004407FFC00003EFC02483E4820483EFC0000
+BFBF:0000210821083FF821083FF8044004407FFC00003E2003FC3E7020883E700000
+BFC0:0000210821083FF821083FF8044004407FFC00001FF01010101010101FF00000
+BFC1:0000210821083FF821083FF8044004407FFC0000101010101FF010101FF00000
+BFC2:0000210821083FF821083FF8044004407FFC0000222022203E2022503E880000
+BFC3:0000210821083FF821083FF8044004407FFC000000000100010002800C400000
+BFC4:0000210821083FF821083FF8044004407FFC00000000024002400DA033100000
+BFC5:0000210821083FF821083FF8044004407FFC0000000007C00820082007C00000
+BFC6:0000210821083FF821083FF8044004407FFC0000000007E00080014006200000
+BFC7:0000210821083FF821083FF8044004407FFC0000008007E00080014006200000
+BFC8:0000210821083FF821083FF8044004407FFC00001FF000101FF0001000100000
+BFC9:0000210821083FF821083FF8044004407FFC00001FF010001FF010001FF00000
+BFCA:0000210821083FF821083FF8044004407FFC000000001FF0044004401FF00000
+BFCB:0000210821083FF821083FF8044004407FFC000001001FF007C0082007C00000
+BFCC:000000002108210821083FF8210821083FF800003FF801000100010001000000
+BFCD:0000210821083FF821083FF800007FFC010001001FF000100010001000100000
+BFCE:0000210821083FF821083FF800007FFC0100010000003EF80208020802080000
+BFCF:0000210821083FF821083FF800007FFC0100010000001E100210022802C40000
+BFD0:0000210821083FF821083FF8000000007FFC010001001100100010001FF00000
+BFD1:0000210821083FF821083FF800007FFC01000100000020F8201020303ECC0000
+BFD2:0000210821083FF821083FF800007FFC01000100202021FC207020883E700000
+BFD3:0000210821083FF821083FF800007FFC010001001FF01000100010001FF00000
+BFD4:0000210821083FF821083FF800007FFC010001001FF000101FF010001FF00000
+BFD5:0000210821083FF821083FF800007FFC010001003EF802083E0820083E080000
+BFD6:0000210821083FF821083FF800007FFC010001003EF802883E8820883EF80000
+BFD7:0000210821083FF821083FF800007FFC010001003E8802883EF820883EF80000
+BFD8:0000210821083FF821083FF800007FFC010001003E1002103E1020283EC40000
+BFD9:0000210821083FF821083FF800007FFC010001003EF802803EF820803EF80000
+BFDA:0000210821083FF821083FF800007FFC010001003EFC02483E4820483EFC0000
+BFDB:0000210821083FF821083FF800007FFC010001003E2003FC3E7020883E700000
+BFDC:0000210821083FF821083FF800007FFC010001001FF01010101010101FF00000
+BFDD:0000210821083FF821083FF800007FFC01000100101010101FF010101FF00000
+BFDE:0000210821083FF821083FF800007FFC01000100222022203E2022503E880000
+BFDF:0000210821083FF821083FF800007FFC0100010000000100010002800C400000
+BFE0:0000210821083FF821083FF800007FFC010001000000024002400DA033100000
+BFE1:0000210821083FF821083FF800007FFC01000100000007C00820082007C00000
+BFE2:0000210821083FF821083FF800007FFC01000100000007E00080014006200000
+BFE3:0000210821083FF821083FF800007FFC01000100008007E00080014006200000
+BFE4:0000210821083FF821083FF800007FFC010001001FF000101FF0001000100000
+BFE5:0000210821083FF821083FF800007FFC010001001FF010001FF010001FF00000
+BFE6:0000210821083FF821083FF800007FFC0100010000001FF0044004401FF00000
+BFE7:0000210821083FF821083FF800007FFC0100010001001FF007C0082007C00000
+BFE8:000000084448444844487FC8444844487FC800087FE8040804F8040804080000
+BFE9:248824883F8824883F8800087FE8027802080000000007F80008000800080000
+BFEA:248824883F8824883F8800087FE802780208000000003EF80208020802080000
+BFEB:248824883F8824883F8800087FE802780208000000001F080108011401620000
+BFEC:248824883F8824883F88000800087FE80278020802081000100010001FF80000
+BFED:248824883F8824883F8800087FE8027802080000000020F8201020303ECC0000
+BFEE:248824883F8824883F8800087FE8027802080000202021FC207020883E700000
+BFEF:248824883F8824883F8800087FE802780208000003F802000200020003F80000
+BFF0:248824883F8824883F8800087FE802780208000007F8000807F8040007F80000
+BFF1:248824883F8824883F8800087FE80278020800003EF802083E0820083E080000
+BFF2:248824883F8824883F8800087FE80278020800003EF802883E8820883EF80000
+BFF3:248824883F8824883F8800087FE80278020800003E8802883EF820883EF80000
+BFF4:248824883F8824883F8800087FE80278020800000F8800880F8808140FA20000
+BFF5:248824883F8824883F8800087FE80278020800003EF802803EF820803EF80000
+BFF6:248824883F8824883F8800087FE80278020800003EFC02483E4820483EFC0000
+BFF7:248824883F8824883F8800087FE80278020800003E1002FE3E3820443E380000
+BFF8:248824883F8824883F8800087FE802780208000003F802080208020803F80000
+BFF9:248824883F8824883F8800087FE80278020800000208020803F8020803F80000
+BFFA:248824883F8824883F8800087FE8027802080000210821083F0821143F620000
+BFFB:248824883F8824883F8800087FE8027802080000001000100010006801840000
+BFFC:248824883F8824883F8800087FE80278020800000048004800A8011406620000
+BFFD:248824883F8824883F8800087FE8027802080000000003F00408040803F00000
+BFFE:248824883F8824883F8800087FE802780208000003F80020002000D003080000
+BFFF:248824883F8824883F8800087FE8027802080000004003F8004000A003180000
+C000:248824883F8824883F8800087FE802780208000003F8000803F8000800080000
+C001:248824883F8824883F8800087FE802780208000003F8020003F8020003F80000
+C002:248824883F8824883F8800087FE802780208000000000FF8022002200FF80000
+C003:248824883F8824883F8800087FE802780208000000800FF803E0041003E00000
+C004:0000000A444A444A444A7FCA444A444A7FCA000A7FEA040A047A040A040A0000
+C005:24A824A83FA824A83FA800287FA805E804280000000007F80008000800080000
+C006:24A824A83FA824A83FA800287FA805E80428000000003EF80208020802080000
+C007:24A824A83FA824A83FA800287FA805E80428000000001F080108011401620000
+C008:24A824A83FA824A83FA8002800287FA8042805E804281428100010001FF80000
+C009:24A824A83FA824A83FA800287FA805E804280000000020F8201020303ECC0000
+C00A:24A824A83FA824A83FA800287FA805E804280000202021FC207020883E700000
+C00B:24A824A83FA824A83FA800287FA805E80428000003F802000200020003F80000
+C00C:24A824A83FA824A83FA800287FA805E80428000007F8000807F8040007F80000
+C00D:24A824A83FA824A83FA800287FA805E8042800003EF802083E0820083E080000
+C00E:24A824A83FA824A83FA800287FA805E8042800003EF802883E8820883EF80000
+C00F:24A824A83FA824A83FA800287FA805E8042800003E8802883EF820883EF80000
+C010:24A824A83FA824A83FA800287FA805E8042800000F8800880F8808140FA20000
+C011:24A824A83FA824A83FA800287FA805E8042800003EF802803EF820803EF80000
+C012:24A824A83FA824A83FA800287FA805E8042800003EFC02483E4820483EFC0000
+C013:24A824A83FA824A83FA800287FA805E8042800003E1002FE3E3820443E380000
+C014:24A824A83FA824A83FA800287FA805E80428000003F802080208020803F80000
+C015:24A824A83FA824A83FA800287FA805E8042800000208020803F8020803F80000
+C016:24A824A83FA824A83FA800287FA805E804280000210821083F0821143F620000
+C017:24A824A83FA824A83FA800287FA805E804280000001000100010006801840000
+C018:24A824A83FA824A83FA800287FA805E8042800000048004800A8011406620000
+C019:24A824A83FA824A83FA800287FA805E804280000000003F00408040803F00000
+C01A:24A824A83FA824A83FA800287FA805E80428000003F80020002000D003080000
+C01B:24A824A83FA824A83FA800287FA805E804280000004003F8004000A003180000
+C01C:24A824A83FA824A83FA800287FA805E80428000003F8000803F8000800080000
+C01D:24A824A83FA824A83FA800287FA805E80428000003F8020003F8020003F80000
+C01E:24A824A83FA824A83FA800287FA805E80428000000000FF8022002200FF80000
+C01F:24A824A83FA824A83FA800287FA805E80428000000800FF803E0041003E00000
+C020:000000084448444844487FC8444844487FC800087FE804080408040804080000
+C021:248824883F8824883F8800087FE8020802000000000007F80008000800080000
+C022:248824883F8824883F8800087FE802080200000000003EF80208020802080000
+C023:248824883F8824883F8800087FE802080200000000001F080108011401620000
+C024:248824883F8824883F88000800087FE80208020802081008100010001FF80000
+C025:248824883F8824883F8800087FE8020802000000000020F8201020303ECC0000
+C026:248824883F8824883F8800087FE8020802000000202021FC207020883E700000
+C027:248824883F8824883F8800087FE802080200000003F802000200020003F80000
+C028:248824883F8824883F8800087FE802080200000007F8000807F8040007F80000
+C029:248824883F8824883F8800087FE80208020000003EF802083E0820083E080000
+C02A:248824883F8824883F8800087FE80208020000003EF802883E8820883EF80000
+C02B:248824883F8824883F8800087FE80208020000003E8802883EF820883EF80000
+C02C:248824883F8824883F8800087FE80208020000000F8800880F8808140FA20000
+C02D:248824883F8824883F8800087FE80208020000003EF802803EF820803EF80000
+C02E:248824883F8824883F8800087FE80208020000003EFC02483E4820483EFC0000
+C02F:248824883F8824883F8800087FE80208020000003E1002FE3E3820443E380000
+C030:248824883F8824883F8800087FE802080200000003F802080208020803F80000
+C031:248824883F8824883F8800087FE80208020000000208020803F8020803F80000
+C032:248824883F8824883F8800087FE8020802000000210821083F0821143F620000
+C033:248824883F8824883F8800087FE8020802000000001000100010006801840000
+C034:248824883F8824883F8800087FE80208020000000048004800A8011406620000
+C035:248824883F8824883F8800087FE8020802000000000003F00408040803F00000
+C036:248824883F8824883F8800087FE802080200000003F80020002000D003080000
+C037:248824883F8824883F8800087FE8020802000000004003F8004000A003180000
+C038:248824883F8824883F8800087FE802080200000003F8000803F8000800080000
+C039:248824883F8824883F8800087FE802080200000003F8020003F8020003F80000
+C03A:248824883F8824883F8800087FE802080200000000000FF8022002200FF80000
+C03B:248824883F8824883F8800087FE802080200000000800FF803E0041003E00000
+C03C:000000002108210821083FF8210821083FF800007FFC04400440044004400000
+C03D:0000210821083FF821083FF800007FFC044004401FF000100010001000100000
+C03E:0000210821083FF821083FF800007FFC0440044000003EF80208020802080000
+C03F:0000210821083FF821083FF800007FFC0440044000001E100210022802C40000
+C040:0000210821083FF821083FF8000000007FFC044004401440100010001FF00000
+C041:0000210821083FF821083FF800007FFC04400440000020F8201020303ECC0000
+C042:0000210821083FF821083FF800007FFC04400440202021FC207020883E700000
+C043:0000210821083FF821083FF800007FFC044004401FF01000100010001FF00000
+C044:0000210821083FF821083FF800007FFC044004401FF000101FF010001FF00000
+C045:0000210821083FF821083FF800007FFC044004403EF802083E0820083E080000
+C046:0000210821083FF821083FF800007FFC044004403EF802883E8820883EF80000
+C047:0000210821083FF821083FF800007FFC044004403E8802883EF820883EF80000
+C048:0000210821083FF821083FF800007FFC044004403E1002103E1020283EC40000
+C049:0000210821083FF821083FF800007FFC044004403EF802803EF820803EF80000
+C04A:0000210821083FF821083FF800007FFC044004403EFC02483E4820483EFC0000
+C04B:0000210821083FF821083FF800007FFC044004403E2003FC3E7020883E700000
+C04C:0000210821083FF821083FF800007FFC044004401FF01010101010101FF00000
+C04D:0000210821083FF821083FF800007FFC04400440101010101FF010101FF00000
+C04E:0000210821083FF821083FF800007FFC04400440222022203E2022503E880000
+C04F:0000210821083FF821083FF800007FFC0440044000000100010002800C400000
+C050:0000210821083FF821083FF800007FFC044004400000024002400DA033100000
+C051:0000210821083FF821083FF800007FFC04400440000007C00820082007C00000
+C052:0000210821083FF821083FF800007FFC04400440000007E00080014006200000
+C053:0000210821083FF821083FF800007FFC04400440008007E00080014006200000
+C054:0000210821083FF821083FF800007FFC044004401FF000101FF0001000100000
+C055:0000210821083FF821083FF800007FFC044004401FF010001FF010001FF00000
+C056:0000210821083FF821083FF800007FFC0440044000001FF0044004401FF00000
+C057:0000210821083FF821083FF800007FFC0440044001001FF007C0082007C00000
+C058:000000002108210821083FF8210821083FF8000000007FFC0000000000000000
+C059:0000210821083FF821083FF8000000007FFC00001FF000100010001000100000
+C05A:0000210821083FF821083FF8000000007FFC000000003EF80208020802080000
+C05B:0000210821083FF821083FF8000000007FFC000000001E100210022802C40000
+C05C:0000210821083FF821083FF8000000007FFC000000001000100010001FF00000
+C05D:0000210821083FF821083FF8000000007FFC0000000020F8201020303ECC0000
+C05E:0000210821083FF821083FF8000000007FFC0000202021FC207020883E700000
+C05F:0000210821083FF821083FF8000000007FFC00001FF01000100010001FF00000
+C060:0000210821083FF821083FF8000000007FFC00001FF000101FF010001FF00000
+C061:0000210821083FF821083FF8000000007FFC00003EF802083E0820083E080000
+C062:0000210821083FF821083FF8000000007FFC00003EF802883E8820883EF80000
+C063:0000210821083FF821083FF8000000007FFC00003E8802883EF820883EF80000
+C064:0000210821083FF821083FF8000000007FFC00003E1002103E1020283EC40000
+C065:0000210821083FF821083FF8000000007FFC00003EF802803EF820803EF80000
+C066:0000210821083FF821083FF8000000007FFC00003EFC02483E4820483EFC0000
+C067:0000210821083FF821083FF8000000007FFC00003E2003FC3E7020883E700000
+C068:0000210821083FF821083FF8000000007FFC00001FF01010101010101FF00000
+C069:0000210821083FF821083FF8000000007FFC0000101010101FF010101FF00000
+C06A:0000210821083FF821083FF8000000007FFC0000222022203E2022503E880000
+C06B:0000210821083FF821083FF8000000007FFC000000000100010002800C400000
+C06C:0000210821083FF821083FF8000000007FFC00000000024002400DA033100000
+C06D:0000210821083FF821083FF8000000007FFC0000000007C00820082007C00000
+C06E:0000210821083FF821083FF8000000007FFC0000000007E00080014006200000
+C06F:0000210821083FF821083FF8000000007FFC0000008007E00080014006200000
+C070:0000210821083FF821083FF8000000007FFC00001FF000101FF0001000100000
+C071:0000210821083FF821083FF8000000007FFC00001FF010001FF010001FF00000
+C072:0000210821083FF821083FF8000000007FFC000000001FF0044004401FF00000
+C073:0000210821083FF821083FF8000000007FFC000001001FF007C0082007C00000
+C074:0000000800084448444844487FC8444844487FC800087FE80008000800080000
+C075:0000248824883F8824883F88000800087FE8000007F800080008000800080000
+C076:0000248824883F8824883F88000800087FE8000000003EF80208020802080000
+C077:0000248824883F8824883F88000800087FE8000000001F080108011401620000
+C078:0000248824883F8824883F88000800087FE8000008000800080008000FF80000
+C079:0000248824883F8824883F88000800087FE80000000010F8101010301ECC0000
+C07A:0000248824883F8824883F88000800087FE800000808087F081C08220F9C0000
+C07B:0000248824883F8824883F88000800087FE8000003F802000200020003F80000
+C07C:0000248824883F8824883F88000800087FE8000007F8000807F8040007F80000
+C07D:0000248824883F8824883F88000800087FE800003EF802083E0820083E080000
+C07E:0000248824883F8824883F88000800087FE800003EF802883E8820883EF80000
+C07F:0000248824883F8824883F88000800087FE800003E8802883EF820883EF80000
+C080:0000248824883F8824883F88000800087FE800001F0801081F0810141F620000
+C081:0000248824883F8824883F88000800087FE800003EF802803EF820803EF80000
+C082:0000248824883F8824883F88000800087FE800003EFC02483E4820483EFC0000
+C083:0000248824883F8824883F88000800087FE800001F08017F1F1C10221F1C0000
+C084:0000248824883F8824883F88000800087FE8000003F802080208020803F80000
+C085:0000248824883F8824883F88000800087FE800000208020803F8020803F80000
+C086:0000248824883F8824883F88000800087FE80000110811081F0811141F620000
+C087:0000248824883F8824883F88000800087FE80000001000100010006801840000
+C088:0000248824883F8824883F88000800087FE800000048004800A8011406620000
+C089:0000248824883F8824883F88000800087FE80000000003F00408040803F00000
+C08A:0000248824883F8824883F88000800087FE8000003F80020002000D003080000
+C08B:0000248824883F8824883F88000800087FE80000004003F8004000A003180000
+C08C:0000248824883F8824883F88000800087FE8000003F8000803F8000800080000
+C08D:0000248824883F8824883F88000800087FE8000003F8020003F8020003F80000
+C08E:0000248824883F8824883F88000800087FE8000000000FF8022002200FF80000
+C08F:0000248824883F8824883F88000800087FE8000000800FF803E0041003E00000
+C090:00000000000800082488248824883F88248824883F8800080008000800080000
+C091:000000084908490849087F0849087F0800080000000007F80008000800080000
+C092:000000084908490849087F0849087F080008000000003EF80208020802080000
+C093:000000084908490849087F0849087F080008000000001F080108011401620000
+C094:000000084908490849087F0849087F080008000800001000100010001FF80000
+C095:000000084908490849087F0849087F0800080000000020F8201020303ECC0000
+C096:000000084908490849087F0849087F0800080000202021FC207020883E700000
+C097:000000084908490849087F0849087F080008000003F802000200020003F80000
+C098:000000084908490849087F0849087F080008000007F8000807F8040007F80000
+C099:000000084908490849087F0849087F08000800003EF802083E0820083E080000
+C09A:000000084908490849087F0849087F08000800003EF802883E8820883EF80000
+C09B:000000084908490849087F0849087F08000800003E8802883EF820883EF80000
+C09C:000000084908490849087F0849087F08000800000F8800880F8808140FA20000
+C09D:000000084908490849087F0849087F08000800003EF802803EF820803EF80000
+C09E:000000084908490849087F0849087F08000800003EFC02483E4820483EFC0000
+C09F:000000084908490849087F0849087F08000800003E1002FE3E3820443E380000
+C0A0:000000084908490849087F0849087F080008000003F802080208020803F80000
+C0A1:000000084908490849087F0849087F08000800000208020803F8020803F80000
+C0A2:000000084908490849087F0849087F0800080000210821083F0821143F620000
+C0A3:000000084908490849087F0849087F0800080000001000100010006801840000
+C0A4:000000084908490849087F0849087F08000800000048004800A8011406620000
+C0A5:000000084908490849087F0849087F0800080000000003F00408040803F00000
+C0A6:000000084908490849087F0849087F080008000003F80020002000D003080000
+C0A7:000000084908490849087F0849087F0800080000004003F8004000A003180000
+C0A8:000000084908490849087F0849087F080008000003F8000803F8000800080000
+C0A9:000000084908490849087F0849087F080008000003F8020003F8020003F80000
+C0AA:000000084908490849087F0849087F080008000000000FF8022002200FF80000
+C0AB:000000084908490849087F0849087F080008000000800FF803E0041003E00000
+C0AC:0000000000100010021002100410041E0A101110609000100010001000100000
+C0AD:000000080008040804080C0E120861080008000007F800080008000800080000
+C0AE:000000080008040804080C0E120861080008000000003EF80208020802080000
+C0AF:000000080008040804080C0E120861080008000000001F080108011401620000
+C0B0:000000080008040804080C0E120861080008000808000800080008000FF80000
+C0B1:000000080008040804080C0E1208610800080000000010F8101010301ECC0000
+C0B2:000000080008040804080C0E12086108000800000808087F081C08220F9C0000
+C0B3:000000080008040804080C0E120861080008000003F802000200020003F80000
+C0B4:000000080008040804080C0E120861080008000007F8000807F8040007F80000
+C0B5:000000080008040804080C0E12086108000800003EF802083E0820083E080000
+C0B6:000000080008040804080C0E12086108000800003EF802883E8820883EF80000
+C0B7:000000080008040804080C0E12086108000800003E8802883EF820883EF80000
+C0B8:000000080008040804080C0E12086108000800001F0801081F0810141F620000
+C0B9:000000080008040804080C0E12086108000800003EF802803EF820803EF80000
+C0BA:000000080008040804080C0E12086108000800003EFC02483E4820483EFC0000
+C0BB:000000080008040804080C0E12086108000800001F08017F1F1C10221F1C0000
+C0BC:000000080008040804080C0E120861080008000003F802080208020803F80000
+C0BD:000000080008040804080C0E12086108000800000208020803F8020803F80000
+C0BE:000000080008040804080C0E1208610800080000110811081F0811141F620000
+C0BF:000000080008040804080C0E1208610800080000001000100010006801840000
+C0C0:000000080008040804080C0E12086108000800000048004800A8011406620000
+C0C1:000000080008040804080C0E1208610800080000000003F00408040803F00000
+C0C2:000000080008040804080C0E120861080008000003F80020002000D003080000
+C0C3:000000080008040804080C0E1208610800080000004003F8004000A003180000
+C0C4:000000080008040804080C0E120861080008000003F8000803F8000800080000
+C0C5:000000080008040804080C0E120861080008000003F8020003F8020003F80000
+C0C6:000000080008040804080C0E120861080008000000000FF8022002200FF80000
+C0C7:000000080008040804080C0E120861080008000000800FF803E0041003E00000
+C0C8:0000000000120012021202120412041E0A121112609200120012001200120000
+C0C9:000000280028042804280C38122861280028000007F800080008000800080000
+C0CA:000000280028042804280C38122861280028000000003EF80208020802080000
+C0CB:000000280028042804280C38122861280028000000003E100210022802C40000
+C0CC:000000280028042804280C38122861280028002808000800080008000FF80000
+C0CD:000000280028042804280C381228612800280000000020F8201020303ECC0000
+C0CE:000000280028042804280C381228612800280000202021FC207020883E700000
+C0CF:000000280028042804280C38122861280028000003F802000200020003F80000
+C0D0:000000280028042804280C38122861280028000007F8000807F8040007F80000
+C0D1:000000280028042804280C3812286128002800003EF802083E0820083E080000
+C0D2:000000280028042804280C3812286128002800003EF802883E8820883EF80000
+C0D3:000000280028042804280C3812286128002800003E8802883EF820883EF80000
+C0D4:000000280028042804280C3812286128002800001F0801081F0810141F620000
+C0D5:000000280028042804280C3812286128002800003EF802803EF820803EF80000
+C0D6:000000280028042804280C3812286128002800003EFC02483E4820483EFC0000
+C0D7:000000280028042804280C3812286128002800003E1002FE3E3820443E380000
+C0D8:000000280028042804280C38122861280028000003F802080208020803F80000
+C0D9:000000280028042804280C3812286128002800000208020803F8020803F80000
+C0DA:000000280028042804280C381228612800280000110811081F0811141F620000
+C0DB:000000280028042804280C381228612800280000000800080008003400C20000
+C0DC:000000280028042804280C3812286128002800000048004800A8011406620000
+C0DD:000000280028042804280C381228612800280000000001F00208020801F00000
+C0DE:000000280028042804280C38122861280028000003F80020002000D003080000
+C0DF:000000280028042804280C381228612800280000004003F8004000A003180000
+C0E0:000000280028042804280C38122861280028000003F8000803F8000800080000
+C0E1:000000280028042804280C38122861280028000003F8020003F8020003F80000
+C0E2:000000280028042804280C38122861280028000000000FF8022002200FF80000
+C0E3:000000280028042804280C38122861280028000000800FF803E0041003E00000
+C0E4:000000000010001002100210041E04100A10111E609000100010001000100000
+C0E5:0000000800080408040E0C08120E61080008000007F800080008000800080000
+C0E6:0000000800080408040E0C08120E61080008000000003EF80208020802080000
+C0E7:0000000800080408040E0C08120E61080008000000001F080108011401620000
+C0E8:0000000800080408040E0C08120E61080008000008000800080008000FF80000
+C0E9:0000000800080408040E0C08120E610800080000000010F8101010301ECC0000
+C0EA:0000000800080408040E0C08120E6108000800000808087F081C08220F9C0000
+C0EB:0000000800080408040E0C08120E61080008000003F802000200020003F80000
+C0EC:0000000800080408040E0C08120E61080008000007F8000807F8040007F80000
+C0ED:0000000800080408040E0C08120E6108000800003EF802083E0820083E080000
+C0EE:0000000800080408040E0C08120E6108000800003EF802883E8820883EF80000
+C0EF:0000000800080408040E0C08120E6108000800003E8802883EF820883EF80000
+C0F0:0000000800080408040E0C08120E6108000800001F0801081F0810141F620000
+C0F1:0000000800080408040E0C08120E6108000800003EF802803EF820803EF80000
+C0F2:0000000800080408040E0C08120E6108000800003EFC02483E4820483EFC0000
+C0F3:0000000800080408040E0C08120E6108000800001F08017F1F1C10221F1C0000
+C0F4:0000000800080408040E0C08120E61080008000003F802080208020803F80000
+C0F5:0000000800080408040E0C08120E6108000800000208020803F8020803F80000
+C0F6:0000000800080408040E0C08120E610800080000110811081F0811141F620000
+C0F7:0000000800080408040E0C08120E610800080000001000100010006801840000
+C0F8:0000000800080408040E0C08120E6108000800000048004800A8011406620000
+C0F9:0000000800080408040E0C08120E610800080000000003F00408040803F00000
+C0FA:0000000800080408040E0C08120E61080008000003F80020002000D003080000
+C0FB:0000000800080408040E0C08120E610800080000004003F8004000A003180000
+C0FC:0000000800080408040E0C08120E61080008000003F8000803F8000800080000
+C0FD:0000000800080408040E0C08120E61080008000003F8020003F8020003F80000
+C0FE:0000000800080408040E0C08120E61080008000000000FF8022002200FF80000
+C0FF:0000000800080408040E0C08120E61080008000000800FF803E0041003E00000
+C100:000000000012001202120212041E04120A12111E609200120012001200120000
+C101:000000280028042804380C28123861280028000007F800080008000800080000
+C102:000000280028042804380C28123861280028000000003EF80208020802080000
+C103:000000280028042804380C28123861280028000000003E100210022802C40000
+C104:000000280028042804380C28123861280028002808000800080008000FF80000
+C105:000000280028042804380C281238612800280000000020F8201020303ECC0000
+C106:000000280028042804380C281238612800280000202021FC207020883E700000
+C107:000000280028042804380C28123861280028000003F802000200020003F80000
+C108:000000280028042804380C28123861280028000007F8000807F8040007F80000
+C109:000000280028042804380C2812386128002800003EF802083E0820083E080000
+C10A:000000280028042804380C2812386128002800003EF802883E8820883EF80000
+C10B:000000280028042804380C2812386128002800003E8802883EF820883EF80000
+C10C:000000280028042804380C2812386128002800001F0801081F0810141F620000
+C10D:000000280028042804380C2812386128002800003EF802803EF820803EF80000
+C10E:000000280028042804380C2812386128002800003EFC02483E4820483EFC0000
+C10F:000000280028042804380C2812386128002800003E1002FE3E3820443E380000
+C110:000000280028042804380C28123861280028000003F802080208020803F80000
+C111:000000280028042804380C2812386128002800000208020803F8020803F80000
+C112:000000280028042804380C281238612800280000110811081F0811141F620000
+C113:000000280028042804380C281238612800280000000800080008003400C20000
+C114:000000280028042804380C2812386128002800000048004800A8011406620000
+C115:000000280028042804380C281238612800280000000001F00208020801F00000
+C116:000000280028042804380C28123861280028000003F80020002000D003080000
+C117:000000280028042804380C281238612800280000004003F8004000A003180000
+C118:000000280028042804380C28123861280028000003F8000803F8000800080000
+C119:000000280028042804380C28123861280028000003F8020003F8020003F80000
+C11A:000000280028042804380C28123861280028000000000FF8022002200FF80000
+C11B:000000280028042804380C28123861280028000000800FF803E0041003E00000
+C11C:0000000000020002020202020402041E0A021102608200020002000200020000
+C11D:000000080008040804080C381208610800080000000007F80008000800080000
+C11E:000000080008040804080C38120861080008000000003EF80208020802080000
+C11F:000000080008040804080C38120861080008000000001F080108011401620000
+C120:000000080008040804080C38120861080008000000001000100010001FF80000
+C121:000000080008040804080C381208610800080000000020F8201020303ECC0000
+C122:000000080008040804080C381208610800080000202021FC207020883E700000
+C123:000000080008040804080C38120861080008000003F802000200020003F80000
+C124:000000080008040804080C38120861080008000007F8000807F8040007F80000
+C125:000000080008040804080C3812086108000800003EF802083E0820083E080000
+C126:000000080008040804080C3812086108000800003EF802883E8820883EF80000
+C127:000000080008040804080C3812086108000800003E8802883EF820883EF80000
+C128:000000080008040804080C3812086108000800000F8800880F8808140FA20000
+C129:000000080008040804080C3812086108000800003EF802803EF820803EF80000
+C12A:000000080008040804080C3812086108000800003EFC02483E4820483EFC0000
+C12B:000000080008040804080C3812086108000800003E1002FE3E3820443E380000
+C12C:000000080008040804080C38120861080008000003F802080208020803F80000
+C12D:000000080008040804080C3812086108000800000208020803F8020803F80000
+C12E:000000080008040804080C381208610800080000210821083F0821143F620000
+C12F:000000080008040804080C381208610800080000001000100010006801840000
+C130:000000080008040804080C3812086108000800000048004800A8011406620000
+C131:000000080008040804080C381208610800080000000003F00408040803F00000
+C132:000000080008040804080C38120861080008000003F80020002000D003080000
+C133:000000080008040804080C381208610800080000004003F8004000A003180000
+C134:000000080008040804080C38120861080008000003F8000803F8000800080000
+C135:000000080008040804080C38120861080008000003F8020003F8020003F80000
+C136:000000080008040804080C38120861080008000000000FF8022002200FF80000
+C137:000000080008040804080C38120861080008000000800FF803E0041003E00000
+C138:00000000000A000A020A020A040A043A0A0A110A608A000A000A000A000A0000
+C139:000000280028042804280CE8122861280028000007F800080008000800080000
+C13A:000000280028042804280CE8122861280028000000003EF80208020802080000
+C13B:000000280028042804280CE8122861280028000000003E100210022802C40000
+C13C:000000280028042804280CE8122861280028000008000800080008000FF80000
+C13D:000000280028042804280CE81228612800280000000020F8201020303ECC0000
+C13E:000000280028042804280CE81228612800280000202021FC207020883E700000
+C13F:000000280028042804280CE8122861280028000003F802000200020003F80000
+C140:000000280028042804280CE8122861280028000007F8000807F8040007F80000
+C141:000000280028042804280CE812286128002800003EF802083E0820083E080000
+C142:000000280028042804280CE812286128002800003EF802883E8820883EF80000
+C143:000000280028042804280CE812286128002800003E8802883EF820883EF80000
+C144:000000280028042804280CE812286128002800001F0801081F0810141F620000
+C145:000000280028042804280CE812286128002800003EF802803EF820803EF80000
+C146:000000280028042804280CE812286128002800003EFC02483E4820483EFC0000
+C147:000000280028042804280CE812286128002800003E1002FE3E3820443E380000
+C148:000000280028042804280CE8122861280028000003F802080208020803F80000
+C149:000000280028042804280CE812286128002800000208020803F8020803F80000
+C14A:000000280028042804280CE81228612800280000110811081F0811141F620000
+C14B:000000280028042804280CE81228612800280000000800080008003400C20000
+C14C:000000280028042804280CE812286128002800000048004800A8011406620000
+C14D:000000280028042804280CE81228612800280000000001F00208020801F00000
+C14E:000000280028042804280CE8122861280028000003F80020002000D003080000
+C14F:000000280028042804280CE81228612800280000004003F8004000A003180000
+C150:000000280028042804280CE8122861280028000003F8000803F8000800080000
+C151:000000280028042804280CE8122861280028000003F8020003F8020003F80000
+C152:000000280028042804280CE8122861280028000000000FF8022002200FF80000
+C153:000000280028042804280CE8122861280028000000800FF803E0041003E00000
+C154:000000000002000202020202041E04020A02111E608200020002000200020000
+C155:000000080008040804380C081238610800080000000007F80008000800080000
+C156:000000080008040804380C08123861080008000000003EF80208020802080000
+C157:000000080008040804380C08123861080008000000001F080108011401620000
+C158:000000080008040804380C08123861080008000800001000100010001FF80000
+C159:000000080008040804380C081238610800080000000020F8201020303ECC0000
+C15A:000000080008040804380C081238610800080000202021FC207020883E700000
+C15B:000000080008040804380C08123861080008000003F802000200020003F80000
+C15C:000000080008040804380C08123861080008000007F8000807F8040007F80000
+C15D:000000080008040804380C0812386108000800003EF802083E0820083E080000
+C15E:000000080008040804380C0812386108000800003EF802883E8820883EF80000
+C15F:000000080008040804380C0812386108000800003E8802883EF820883EF80000
+C160:000000080008040804380C0812386108000800000F8800880F8808140FA20000
+C161:000000080008040804380C0812386108000800003EF802803EF820803EF80000
+C162:000000080008040804380C0812386108000800003EFC02483E4820483EFC0000
+C163:000000080008040804380C0812386108000800003E1002FE3E3820443E380000
+C164:000000080008040804380C08123861080008000003F802080208020803F80000
+C165:000000080008040804380C0812386108000800000208020803F8020803F80000
+C166:000000080008040804380C081238610800080000210821083F0821143F620000
+C167:000000080008040804380C081238610800080000001000100010006801840000
+C168:000000080008040804380C0812386108000800000048004800A8011406620000
+C169:000000080008040804380C081238610800080000000003F00408040803F00000
+C16A:000000080008040804380C08123861080008000003F80020002000D003080000
+C16B:000000080008040804380C081238610800080000004003F8004000A003180000
+C16C:000000080008040804380C08123861080008000003F8000803F8000800080000
+C16D:000000080008040804380C08123861080008000003F8020003F8020003F80000
+C16E:000000080008040804380C08123861080008000000000FF8022002200FF80000
+C16F:000000080008040804380C08123861080008000000800FF803E0041003E00000
+C170:00000000000A000A020A020A043A040A0A0A113A608A000A000A000A000A0000
+C171:000000280028042804E80C2812E861280028000007F800080008000800080000
+C172:000000280028042804E80C2812E861280028000000003EF80208020802080000
+C173:000000280028042804E80C2812E861280028000000003E100210022802C40000
+C174:000000280028042804E80C2812E861280028002808000800080008000FF80000
+C175:000000280028042804E80C2812E8612800280000000020F8201020303ECC0000
+C176:000000280028042804E80C2812E8612800280000202021FC207020883E700000
+C177:000000280028042804E80C2812E861280028000003F802000200020003F80000
+C178:000000280028042804E80C2812E861280028000007F8000807F8040007F80000
+C179:000000280028042804E80C2812E86128002800003EF802083E0820083E080000
+C17A:000000280028042804E80C2812E86128002800003EF802883E8820883EF80000
+C17B:000000280028042804E80C2812E86128002800003E8802883EF820883EF80000
+C17C:000000280028042804E80C2812E86128002800001F0801081F0810141F620000
+C17D:000000280028042804E80C2812E86128002800003EF802803EF820803EF80000
+C17E:000000280028042804E80C2812E86128002800003EFC02483E4820483EFC0000
+C17F:000000280028042804E80C2812E86128002800003E1002FE3E3820443E380000
+C180:000000280028042804E80C2812E861280028000003F802080208020803F80000
+C181:000000280028042804E80C2812E86128002800000208020803F8020803F80000
+C182:000000280028042804E80C2812E8612800280000110811081F0811141F620000
+C183:000000280028042804E80C2812E8612800280000000800080008003400C20000
+C184:000000280028042804E80C2812E86128002800000048004800A8011406620000
+C185:000000280028042804E80C2812E8612800280000000001F00208020801F00000
+C186:000000280028042804E80C2812E861280028000003F80020002000D003080000
+C187:000000280028042804E80C2812E8612800280000004003F8004000A003180000
+C188:000000280028042804E80C2812E861280028000003F8000803F8000800080000
+C189:000000280028042804E80C2812E861280028000003F8020003F8020003F80000
+C18A:000000280028042804E80C2812E861280028000000000FF8022002200FF80000
+C18B:000000280028042804E80C2812E861280028000000800FF803E0041003E00000
+C18C:00000000008000800100010002800440182000000100010001007FFC00000000
+C18D:000000800080018002400C20010001007FFC00001FF000100010001000100000
+C18E:000000800080018002400C20010001007FFC000000003EF80208020802080000
+C18F:000000800080018002400C20010001007FFC000000001E100210022802C40000
+C190:000000800080018002400C20010001007FFC000000001000100010001FF00000
+C191:000000800080018002400C20010001007FFC0000000020F8201020303ECC0000
+C192:000000800080018002400C20010001007FFC0000202021FC207020883E700000
+C193:000000800080018002400C20010001007FFC00001FF01000100010001FF00000
+C194:000000800080018002400C20010001007FFC00001FF000101FF010001FF00000
+C195:000000800080018002400C20010001007FFC00003EF802083E0820083E080000
+C196:000000800080018002400C20010001007FFC00003EF802883E8820883EF80000
+C197:000000800080018002400C20010001007FFC00003E8802883EF820883EF80000
+C198:000000800080018002400C20010001007FFC00003E1002103E1020283EC40000
+C199:000000800080018002400C20010001007FFC00003EF802803EF820803EF80000
+C19A:000000800080018002400C20010001007FFC00003EFC02483E4820483EFC0000
+C19B:000000800080018002400C20010001007FFC00003E2003FC3E7020883E700000
+C19C:000000800080018002400C20010001007FFC00001FF01010101010101FF00000
+C19D:000000800080018002400C20010001007FFC0000101010101FF010101FF00000
+C19E:000000800080018002400C20010001007FFC0000222022203E2022503E880000
+C19F:000000800080018002400C20010001007FFC000000000100010002800C400000
+C1A0:000000800080018002400C20010001007FFC00000000024002400DA033100000
+C1A1:000000800080018002400C20010001007FFC0000000007C00820082007C00000
+C1A2:000000800080018002400C20010001007FFC0000000007E00080014006200000
+C1A3:000000800080018002400C20010001007FFC0000008007E00080014006200000
+C1A4:000000800080018002400C20010001007FFC00001FF000101FF0001000100000
+C1A5:000000800080018002400C20010001007FFC00001FF010001FF010001FF00000
+C1A6:000000800080018002400C20010001007FFC000000001FF0044004401FF00000
+C1A7:000000800080018002400C20010001007FFC000001001FF007C0082007C00000
+C1A8:00000010001002100210041004100A1E11106090041004107FD0001000100000
+C1A9:0000020802080608090E3088040804087FE8000007F800080008000800080000
+C1AA:0000020802080608090E3088040804087FE8000000003EF80208020802080000
+C1AB:0000020802080608090E3088040804087FE8000000001F080108011401620000
+C1AC:0000020802080608090E3088040804087FE8000008000800080008000FF80000
+C1AD:0000020802080608090E3088040804087FE80000000010F8101010301ECC0000
+C1AE:0000020802080608090E3088040804087FE800000808087F081C08220F9C0000
+C1AF:0000020802080608090E3088040804087FE8000003F802000200020003F80000
+C1B0:0000020802080608090E3088040804087FE8000007F8000807F8040007F80000
+C1B1:0000020802080608090E3088040804087FE800003EF802083E0820083E080000
+C1B2:0000020802080608090E3088040804087FE800003EF802883E8820883EF80000
+C1B3:0000020802080608090E3088040804087FE800003E8802883EF820883EF80000
+C1B4:0000020802080608090E3088040804087FE800001F0801081F0810141F620000
+C1B5:0000020802080608090E3088040804087FE800003EF802803EF820803EF80000
+C1B6:0000020802080608090E3088040804087FE800003EFC02483E4820483EFC0000
+C1B7:0000020802080608090E3088040804087FE800001F08017F1F1C10221F1C0000
+C1B8:0000020802080608090E3088040804087FE8000003F802080208020803F80000
+C1B9:0000020802080608090E3088040804087FE800000208020803F8020803F80000
+C1BA:0000020802080608090E3088040804087FE80000110811081F0811141F620000
+C1BB:0000020802080608090E3088040804087FE80000001000100010006801840000
+C1BC:0000020802080608090E3088040804087FE800000048004800A8011406620000
+C1BD:0000020802080608090E3088040804087FE80000000003F00408040803F00000
+C1BE:0000020802080608090E3088040804087FE8000003F80020002000D003080000
+C1BF:0000020802080608090E3088040804087FE80000004003F8004000A003180000
+C1C0:0000020802080608090E3088040804087FE8000003F8000803F8000800080000
+C1C1:0000020802080608090E3088040804087FE8000003F8020003F8020003F80000
+C1C2:0000020802080608090E3088040804087FE8000000000FF8022002200FF80000
+C1C3:0000020802080608090E3088040804087FE8000000800FF803E0041003E00000
+C1C4:00000012001202120212041204120A1E11126092041204127FD2001200120000
+C1C5:0000022802280628093830A8042804287FA8000007F800080008000800080000
+C1C6:0000022802280628093830A8042804287FA8000000003EF80208020802080000
+C1C7:0000022802280628093830A8042804287FA8000000001F080108011401620000
+C1C8:0000022802280628093830A8042804287FA8000008000800080008000FF80000
+C1C9:0000022802280628093830A8042804287FA80000000010F8101010301ECC0000
+C1CA:0000022802280628093830A8042804287FA800000808087F081C08220F9C0000
+C1CB:0000022802280628093830A8042804287FA8000003F802000200020003F80000
+C1CC:0000022802280628093830A8042804287FA8000007F8000807F8040007F80000
+C1CD:0000022802280628093830A8042804287FA800003EF802083E0820083E080000
+C1CE:0000022802280628093830A8042804287FA800003EF802883E8820883EF80000
+C1CF:0000022802280628093830A8042804287FA800003E8802883EF820883EF80000
+C1D0:0000022802280628093830A8042804287FA800001F0801081F0810141F620000
+C1D1:0000022802280628093830A8042804287FA800003EF802803EF820803EF80000
+C1D2:0000022802280628093830A8042804287FA800003EFC02483E4820483EFC0000
+C1D3:0000022802280628093830A8042804287FA800001F08017F1F1C10221F1C0000
+C1D4:0000022802280628093830A8042804287FA8000003F802080208020803F80000
+C1D5:0000022802280628093830A8042804287FA800000208020803F8020803F80000
+C1D6:0000022802280628093830A8042804287FA80000110811081F0811141F620000
+C1D7:0000022802280628093830A8042804287FA80000001000100010006801840000
+C1D8:0000022802280628093830A8042804287FA800000048004800A8011406620000
+C1D9:0000022802280628093830A8042804287FA80000000003F00408040803F00000
+C1DA:0000022802280628093830A8042804287FA8000003F80020002000D003080000
+C1DB:0000022802280628093830A8042804287FA80000004003F8004000A003180000
+C1DC:0000022802280628093830A8042804287FA8000003F8000803F8000800080000
+C1DD:0000022802280628093830A8042804287FA8000003F8020003F8020003F80000
+C1DE:0000022802280628093830A8042804287FA8000000000FF8022002200FF80000
+C1DF:0000022802280628093830A8042804287FA8000000800FF803E0041003E00000
+C1E0:00000008000802080208040804080A0811086088040804087FE8000800080000
+C1E1:000002080208060809083088040804087FE8000007F800080008000800080000
+C1E2:000002080208060809083088040804087FE8000000003EF80208020802080000
+C1E3:000002080208060809083088040804087FE8000000001F080108011401620000
+C1E4:000002080208060809083088040804087FE8000008000800080008000FF80000
+C1E5:000002080208060809083088040804087FE80000000010F8101010301ECC0000
+C1E6:000002080208060809083088040804087FE800000808087F081C08220F9C0000
+C1E7:000002080208060809083088040804087FE8000003F802000200020003F80000
+C1E8:000002080208060809083088040804087FE8000007F8000807F8040007F80000
+C1E9:000002080208060809083088040804087FE800003EF802083E0820083E080000
+C1EA:000002080208060809083088040804087FE800003EF802883E8820883EF80000
+C1EB:000002080208060809083088040804087FE800003E8802883EF820883EF80000
+C1EC:000002080208060809083088040804087FE800001F0801081F0810141F620000
+C1ED:000002080208060809083088040804087FE800003EF802803EF820803EF80000
+C1EE:000002080208060809083088040804087FE800003EFC02483E4820483EFC0000
+C1EF:000002080208060809083088040804087FE800001F08017F1F1C10221F1C0000
+C1F0:000002080208060809083088040804087FE8000003F802080208020803F80000
+C1F1:000002080208060809083088040804087FE800000208020803F8020803F80000
+C1F2:000002080208060809083088040804087FE80000110811081F0811141F620000
+C1F3:000002080208060809083088040804087FE80000001000100010006801840000
+C1F4:000002080208060809083088040804087FE800000048004800A8011406620000
+C1F5:000002080208060809083088040804087FE80000000003F00408040803F00000
+C1F6:000002080208060809083088040804087FE8000003F80020002000D003080000
+C1F7:000002080208060809083088040804087FE80000004003F8004000A003180000
+C1F8:000002080208060809083088040804087FE8000003F8000803F8000800080000
+C1F9:000002080208060809083088040804087FE8000003F8020003F8020003F80000
+C1FA:000002080208060809083088040804087FE8000000000FF8022002200FF80000
+C1FB:000002080208060809083088040804087FE8000000800FF803E0041003E00000
+C1FC:00000000008000800100010002800440182004400440044004407FFC00000000
+C1FD:000000800080018002400C20044004407FFC00001FF000100010001000100000
+C1FE:000000800080018002400C20044004407FFC000000003EF80208020802080000
+C1FF:000000800080018002400C20044004407FFC000000001E100210022802C40000
+C200:000000800080018002400C20044004407FFC000000001000100010001FF00000
+C201:000000800080018002400C20044004407FFC0000000020F8201020303ECC0000
+C202:000000800080018002400C20044004407FFC0000202021FC207020883E700000
+C203:000000800080018002400C20044004407FFC00001FF01000100010001FF00000
+C204:000000800080018002400C20044004407FFC00001FF000101FF010001FF00000
+C205:000000800080018002400C20044004407FFC00003EF802083E0820083E080000
+C206:000000800080018002400C20044004407FFC00003EF802883E8820883EF80000
+C207:000000800080018002400C20044004407FFC00003E8802883EF820883EF80000
+C208:000000800080018002400C20044004407FFC00003E1002103E1020283EC40000
+C209:000000800080018002400C20044004407FFC00003EF802803EF820803EF80000
+C20A:000000800080018002400C20044004407FFC00003EFC02483E4820483EFC0000
+C20B:000000800080018002400C20044004407FFC00003E2003FC3E7020883E700000
+C20C:000000800080018002400C20044004407FFC00001FF01010101010101FF00000
+C20D:000000800080018002400C20044004407FFC0000101010101FF010101FF00000
+C20E:000000800080018002400C20044004407FFC0000222022203E2022503E880000
+C20F:000000800080018002400C20044004407FFC000000000100010002800C400000
+C210:000000800080018002400C20044004407FFC00000000024002400DA033100000
+C211:000000800080018002400C20044004407FFC0000000007C00820082007C00000
+C212:000000800080018002400C20044004407FFC0000000007E00080014006200000
+C213:000000800080018002400C20044004407FFC0000008007E00080014006200000
+C214:000000800080018002400C20044004407FFC00001FF000101FF0001000100000
+C215:000000800080018002400C20044004407FFC00001FF010001FF010001FF00000
+C216:000000800080018002400C20044004407FFC000000001FF0044004401FF00000
+C217:000000800080018002400C20044004407FFC000001001FF007C0082007C00000
+C218:00000000008000800100010002800440182000003FF801000100010001000000
+C219:000000800080018002400C2000007FFC010001001FF000100010001000100000
+C21A:000000800080018002400C2000007FFC0100010000003EF80208020802080000
+C21B:000000800080018002400C2000007FFC0100010000001E100210022802C40000
+C21C:000000800080018002400C20000000007FFC010001001100100010001FF00000
+C21D:000000800080018002400C2000007FFC01000100000020F8201020303ECC0000
+C21E:000000800080018002400C2000007FFC01000100202021FC207020883E700000
+C21F:000000800080018002400C2000007FFC010001001FF01000100010001FF00000
+C220:000000800080018002400C2000007FFC010001001FF000101FF010001FF00000
+C221:000000800080018002400C2000007FFC010001003EF802083E0820083E080000
+C222:000000800080018002400C2000007FFC010001003EF802883E8820883EF80000
+C223:000000800080018002400C2000007FFC010001003E8802883EF820883EF80000
+C224:000000800080018002400C2000007FFC010001003E1002103E1020283EC40000
+C225:000000800080018002400C2000007FFC010001003EF802803EF820803EF80000
+C226:000000800080018002400C2000007FFC010001003EFC02483E4820483EFC0000
+C227:000000800080018002400C2000007FFC010001003E2003FC3E7020883E700000
+C228:000000800080018002400C2000007FFC010001001FF01010101010101FF00000
+C229:000000800080018002400C2000007FFC01000100101010101FF010101FF00000
+C22A:000000800080018002400C2000007FFC01000100222022203E2022503E880000
+C22B:000000800080018002400C2000007FFC0100010000000100010002800C400000
+C22C:000000800080018002400C2000007FFC010001000000024002400DA033100000
+C22D:000000800080018002400C2000007FFC01000100000007C00820082007C00000
+C22E:000000800080018002400C2000007FFC01000100000007E00080014006200000
+C22F:000000800080018002400C2000007FFC01000100008007E00080014006200000
+C230:000000800080018002400C2000007FFC010001001FF000101FF0001000100000
+C231:000000800080018002400C2000007FFC010001001FF010001FF010001FF00000
+C232:000000800080018002400C2000007FFC0100010000001FF0044004401FF00000
+C233:000000800080018002400C2000007FFC0100010001001FF007C0082007C00000
+C234:0000000802080208040804080A081108608800087FE8040804F8040804080000
+C235:0208020806080908308800087FE8027802080000000007F80008000800080000
+C236:0208020806080908308800087FE802780208000000003EF80208020802080000
+C237:0208020806080908308800087FE802780208000000001F080108011401620000
+C238:02080208060809083088000800087FE80278020802081000100010001FF80000
+C239:0208020806080908308800087FE8027802080000000020F8201020303ECC0000
+C23A:0208020806080908308800087FE8027802080000202021FC207020883E700000
+C23B:0208020806080908308800087FE802780208000003F802000200020003F80000
+C23C:0208020806080908308800087FE802780208000007F8000807F8040007F80000
+C23D:0208020806080908308800087FE80278020800003EF802083E0820083E080000
+C23E:0208020806080908308800087FE80278020800003EF802883E8820883EF80000
+C23F:0208020806080908308800087FE80278020800003E8802883EF820883EF80000
+C240:0208020806080908308800087FE80278020800000F8800880F8808140FA20000
+C241:0208020806080908308800087FE80278020800003EF802803EF820803EF80000
+C242:0208020806080908308800087FE80278020800003EFC02483E4820483EFC0000
+C243:0208020806080908308800087FE80278020800003E1002FE3E3820443E380000
+C244:0208020806080908308800087FE802780208000003F802080208020803F80000
+C245:0208020806080908308800087FE80278020800000208020803F8020803F80000
+C246:0208020806080908308800087FE8027802080000210821083F0821143F620000
+C247:0208020806080908308800087FE8027802080000001000100010006801840000
+C248:0208020806080908308800087FE80278020800000048004800A8011406620000
+C249:0208020806080908308800087FE8027802080000000003F00408040803F00000
+C24A:0208020806080908308800087FE802780208000003F80020002000D003080000
+C24B:0208020806080908308800087FE8027802080000004003F8004000A003180000
+C24C:0208020806080908308800087FE802780208000003F8000803F8000800080000
+C24D:0208020806080908308800087FE802780208000003F8020003F8020003F80000
+C24E:0208020806080908308800087FE802780208000000000FF8022002200FF80000
+C24F:0208020806080908308800087FE802780208000000800FF803E0041003E00000
+C250:0000000A020A020A040A040A0A0A110A608A000A7FEA040A047A040A040A0000
+C251:022802280628092830A800287FA805E804280000000007F80008000800080000
+C252:022802280628092830A800287FA805E80428000000003EF80208020802080000
+C253:022802280628092830A800287FA805E80428000000001F080108011401620000
+C254:022802280628092830A8002800287FA8042805E804281428100010001FF80000
+C255:022802280628092830A800287FA805E804280000000020F8201020303ECC0000
+C256:022802280628092830A800287FA805E804280000202021FC207020883E700000
+C257:022802280628092830A800287FA805E80428000003F802000200020003F80000
+C258:022802280628092830A800287FA805E80428000007F8000807F8040007F80000
+C259:022802280628092830A800287FA805E8042800003EF802083E0820083E080000
+C25A:022802280628092830A800287FA805E8042800003EF802883E8820883EF80000
+C25B:022802280628092830A800287FA805E8042800003E8802883EF820883EF80000
+C25C:022802280628092830A800287FA805E8042800000F8800880F8808140FA20000
+C25D:022802280628092830A800287FA805E8042800003EF802803EF820803EF80000
+C25E:022802280628092830A800287FA805E8042800003EFC02483E4820483EFC0000
+C25F:022802280628092830A800287FA805E8042800003E1002FE3E3820443E380000
+C260:022802280628092830A800287FA805E80428000003F802080208020803F80000
+C261:022802280628092830A800287FA805E8042800000208020803F8020803F80000
+C262:022802280628092830A800287FA805E804280000210821083F0821143F620000
+C263:022802280628092830A800287FA805E804280000001000100010006801840000
+C264:022802280628092830A800287FA805E8042800000048004800A8011406620000
+C265:022802280628092830A800287FA805E804280000000003F00408040803F00000
+C266:022802280628092830A800287FA805E80428000003F80020002000D003080000
+C267:022802280628092830A800287FA805E804280000004003F8004000A003180000
+C268:022802280628092830A800287FA805E80428000003F8000803F8000800080000
+C269:022802280628092830A800287FA805E80428000003F8020003F8020003F80000
+C26A:022802280628092830A800287FA805E80428000000000FF8022002200FF80000
+C26B:022802280628092830A800287FA805E80428000000800FF803E0041003E00000
+C26C:0000000802080208040804080A081108608800087FE804080408040804080000
+C26D:0208020806080908308800087FE8020802000000000007F80008000800080000
+C26E:0208020806080908308800087FE802080200000000003EF80208020802080000
+C26F:0208020806080908308800087FE802080200000000001F080108011401620000
+C270:02080208060809083088000800087FE80208020802081008100010001FF80000
+C271:0208020806080908308800087FE8020802000000000020F8201020303ECC0000
+C272:0208020806080908308800087FE8020802000000202021FC207020883E700000
+C273:0208020806080908308800087FE802080200000003F802000200020003F80000
+C274:0208020806080908308800087FE802080200000007F8000807F8040007F80000
+C275:0208020806080908308800087FE80208020000003EF802083E0820083E080000
+C276:0208020806080908308800087FE80208020000003EF802883E8820883EF80000
+C277:0208020806080908308800087FE80208020000003E8802883EF820883EF80000
+C278:0208020806080908308800087FE80208020000000F8800880F8808140FA20000
+C279:0208020806080908308800087FE80208020000003EF802803EF820803EF80000
+C27A:0208020806080908308800087FE80208020000003EFC02483E4820483EFC0000
+C27B:0208020806080908308800087FE80208020000003E1002FE3E3820443E380000
+C27C:0208020806080908308800087FE802080200000003F802080208020803F80000
+C27D:0208020806080908308800087FE80208020000000208020803F8020803F80000
+C27E:0208020806080908308800087FE8020802000000210821083F0821143F620000
+C27F:0208020806080908308800087FE8020802000000001000100010006801840000
+C280:0208020806080908308800087FE80208020000000048004800A8011406620000
+C281:0208020806080908308800087FE8020802000000000003F00408040803F00000
+C282:0208020806080908308800087FE802080200000003F80020002000D003080000
+C283:0208020806080908308800087FE8020802000000004003F8004000A003180000
+C284:0208020806080908308800087FE802080200000003F8000803F8000800080000
+C285:0208020806080908308800087FE802080200000003F8020003F8020003F80000
+C286:0208020806080908308800087FE802080200000000000FF8022002200FF80000
+C287:0208020806080908308800087FE802080200000000800FF803E0041003E00000
+C288:00000000008000800100010002800440182000007FFC04400440044004400000
+C289:000000800080018002400C2000007FFC044004401FF000100010001000100000
+C28A:000000800080018002400C2000007FFC0440044000003EF80208020802080000
+C28B:000000800080018002400C2000007FFC0440044000001E100210022802C40000
+C28C:000000800080018002400C20000000007FFC044004401440100010001FF00000
+C28D:000000800080018002400C2000007FFC04400440000020F8201020303ECC0000
+C28E:000000800080018002400C2000007FFC04400440202021FC207020883E700000
+C28F:000000800080018002400C2000007FFC044004401FF01000100010001FF00000
+C290:000000800080018002400C2000007FFC044004401FF000101FF010001FF00000
+C291:000000800080018002400C2000007FFC044004403EF802083E0820083E080000
+C292:000000800080018002400C2000007FFC044004403EF802883E8820883EF80000
+C293:000000800080018002400C2000007FFC044004403E8802883EF820883EF80000
+C294:000000800080018002400C2000007FFC044004403E1002103E1020283EC40000
+C295:000000800080018002400C2000007FFC044004403EF802803EF820803EF80000
+C296:000000800080018002400C2000007FFC044004403EFC02483E4820483EFC0000
+C297:000000800080018002400C2000007FFC044004403E2003FC3E7020883E700000
+C298:000000800080018002400C2000007FFC044004401FF01010101010101FF00000
+C299:000000800080018002400C2000007FFC04400440101010101FF010101FF00000
+C29A:000000800080018002400C2000007FFC04400440222022203E2022503E880000
+C29B:000000800080018002400C2000007FFC0440044000000100010002800C400000
+C29C:000000800080018002400C2000007FFC044004400000024002400DA033100000
+C29D:000000800080018002400C2000007FFC04400440000007C00820082007C00000
+C29E:000000800080018002400C2000007FFC04400440000007E00080014006200000
+C29F:000000800080018002400C2000007FFC04400440008007E00080014006200000
+C2A0:000000800080018002400C2000007FFC044004401FF000101FF0001000100000
+C2A1:000000800080018002400C2000007FFC044004401FF010001FF010001FF00000
+C2A2:000000800080018002400C2000007FFC0440044000001FF0044004401FF00000
+C2A3:000000800080018002400C2000007FFC0440044001001FF007C0082007C00000
+C2A4:000000000080008001000100028004401820000000007FFC0000000000000000
+C2A5:000000800080018002400C20000000007FFC00001FF000100010001000100000
+C2A6:000000800080018002400C20000000007FFC000000003EF80208020802080000
+C2A7:000000800080018002400C20000000007FFC000000001E100210022802C40000
+C2A8:000000800080018002400C20000000007FFC000000001000100010001FF00000
+C2A9:000000800080018002400C20000000007FFC0000000020F8201020303ECC0000
+C2AA:000000800080018002400C20000000007FFC0000202021FC207020883E700000
+C2AB:000000800080018002400C20000000007FFC00001FF01000100010001FF00000
+C2AC:000000800080018002400C20000000007FFC00001FF000101FF010001FF00000
+C2AD:000000800080018002400C20000000007FFC00003EF802083E0820083E080000
+C2AE:000000800080018002400C20000000007FFC00003EF802883E8820883EF80000
+C2AF:000000800080018002400C20000000007FFC00003E8802883EF820883EF80000
+C2B0:000000800080018002400C20000000007FFC00003E1002103E1020283EC40000
+C2B1:000000800080018002400C20000000007FFC00003EF802803EF820803EF80000
+C2B2:000000800080018002400C20000000007FFC00003EFC02483E4820483EFC0000
+C2B3:000000800080018002400C20000000007FFC00003E2003FC3E7020883E700000
+C2B4:000000800080018002400C20000000007FFC00001FF01010101010101FF00000
+C2B5:000000800080018002400C20000000007FFC0000101010101FF010101FF00000
+C2B6:000000800080018002400C20000000007FFC0000222022203E2022503E880000
+C2B7:000000800080018002400C20000000007FFC000000000100010002800C400000
+C2B8:000000800080018002400C20000000007FFC00000000024002400DA033100000
+C2B9:000000800080018002400C20000000007FFC0000000007C00820082007C00000
+C2BA:000000800080018002400C20000000007FFC0000000007E00080014006200000
+C2BB:000000800080018002400C20000000007FFC0000008007E00080014006200000
+C2BC:000000800080018002400C20000000007FFC00001FF000101FF0001000100000
+C2BD:000000800080018002400C20000000007FFC00001FF010001FF010001FF00000
+C2BE:000000800080018002400C20000000007FFC000000001FF0044004401FF00000
+C2BF:000000800080018002400C20000000007FFC000001001FF007C0082007C00000
+C2C0:00000008000802080208040804080A081108608800087FE80008000800080000
+C2C1:000002080208060809083088000800087FE8000007F800080008000800080000
+C2C2:000002080208060809083088000800087FE8000000003EF80208020802080000
+C2C3:000002080208060809083088000800087FE8000000001F080108011401620000
+C2C4:000002080208060809083088000800087FE8000008000800080008000FF80000
+C2C5:000002080208060809083088000800087FE80000000010F8101010301ECC0000
+C2C6:000002080208060809083088000800087FE800000808087F081C08220F9C0000
+C2C7:000002080208060809083088000800087FE8000003F802000200020003F80000
+C2C8:000002080208060809083088000800087FE8000007F8000807F8040007F80000
+C2C9:000002080208060809083088000800087FE800003EF802083E0820083E080000
+C2CA:000002080208060809083088000800087FE800003EF802883E8820883EF80000
+C2CB:000002080208060809083088000800087FE800003E8802883EF820883EF80000
+C2CC:000002080208060809083088000800087FE800001F0801081F0810141F620000
+C2CD:000002080208060809083088000800087FE800003EF802803EF820803EF80000
+C2CE:000002080208060809083088000800087FE800003EFC02483E4820483EFC0000
+C2CF:000002080208060809083088000800087FE800001F08017F1F1C10221F1C0000
+C2D0:000002080208060809083088000800087FE8000003F802080208020803F80000
+C2D1:000002080208060809083088000800087FE800000208020803F8020803F80000
+C2D2:000002080208060809083088000800087FE80000110811081F0811141F620000
+C2D3:000002080208060809083088000800087FE80000001000100010006801840000
+C2D4:000002080208060809083088000800087FE800000048004800A8011406620000
+C2D5:000002080208060809083088000800087FE80000000003F00408040803F00000
+C2D6:000002080208060809083088000800087FE8000003F80020002000D003080000
+C2D7:000002080208060809083088000800087FE80000004003F8004000A003180000
+C2D8:000002080208060809083088000800087FE8000003F8000803F8000800080000
+C2D9:000002080208060809083088000800087FE8000003F8020003F8020003F80000
+C2DA:000002080208060809083088000800087FE8000000000FF8022002200FF80000
+C2DB:000002080208060809083088000800087FE8000000800FF803E0041003E00000
+C2DC:000000000008000802080208040804080A081108608800080008000800080000
+C2DD:000000080008040804080C081208610800080000000007F80008000800080000
+C2DE:000000080008040804080C08120861080008000000003EF80208020802080000
+C2DF:000000080008040804080C08120861080008000000001F080108011401620000
+C2E0:000000080008040804080C08120861080008000800001000100010001FF80000
+C2E1:000000080008040804080C081208610800080000000020F8201020303ECC0000
+C2E2:000000080008040804080C081208610800080000202021FC207020883E700000
+C2E3:000000080008040804080C08120861080008000003F802000200020003F80000
+C2E4:000000080008040804080C08120861080008000007F8000807F8040007F80000
+C2E5:000000080008040804080C0812086108000800003EF802083E0820083E080000
+C2E6:000000080008040804080C0812086108000800003EF802883E8820883EF80000
+C2E7:000000080008040804080C0812086108000800003E8802883EF820883EF80000
+C2E8:000000080008040804080C0812086108000800000F8800880F8808140FA20000
+C2E9:000000080008040804080C0812086108000800003EF802803EF820803EF80000
+C2EA:000000080008040804080C0812086108000800003EFC02483E4820483EFC0000
+C2EB:000000080008040804080C0812086108000800003E1002FE3E3820443E380000
+C2EC:000000080008040804080C08120861080008000003F802080208020803F80000
+C2ED:000000080008040804080C0812086108000800000208020803F8020803F80000
+C2EE:000000080008040804080C081208610800080000210821083F0821143F620000
+C2EF:000000080008040804080C081208610800080000001000100010006801840000
+C2F0:000000080008040804080C0812086108000800000048004800A8011406620000
+C2F1:000000080008040804080C081208610800080000000003F00408040803F00000
+C2F2:000000080008040804080C08120861080008000003F80020002000D003080000
+C2F3:000000080008040804080C081208610800080000004003F8004000A003180000
+C2F4:000000080008040804080C08120861080008000003F8000803F8000800080000
+C2F5:000000080008040804080C08120861080008000003F8020003F8020003F80000
+C2F6:000000080008040804080C08120861080008000000000FF8022002200FF80000
+C2F7:000000080008040804080C08120861080008000000800FF803E0041003E00000
+C2F8:0000000000100010089008900890191E15102290CC5000100010001000100000
+C2F9:00000008000812081208340E2A0849080008000007F800080008000800080000
+C2FA:00000008000812081208340E2A0849080008000000003EF80208020802080000
+C2FB:00000008000812081208340E2A0849080008000000001F080108011401620000
+C2FC:00000008000812081208340E2A0849080008000808000800080008000FF80000
+C2FD:00000008000812081208340E2A08490800080000000010F8101010301ECC0000
+C2FE:00000008000812081208340E2A084908000800000808087F081C08220F9C0000
+C2FF:00000008000812081208340E2A0849080008000003F802000200020003F80000
+C300:00000008000812081208340E2A0849080008000007F8000807F8040007F80000
+C301:00000008000812081208340E2A084908000800003EF802083E0820083E080000
+C302:00000008000812081208340E2A084908000800003EF802883E8820883EF80000
+C303:00000008000812081208340E2A084908000800003E8802883EF820883EF80000
+C304:00000008000812081208340E2A084908000800001F0801081F0810141F620000
+C305:00000008000812081208340E2A084908000800003EF802803EF820803EF80000
+C306:00000008000812081208340E2A084908000800003EFC02483E4820483EFC0000
+C307:00000008000812081208340E2A084908000800001F08017F1F1C10221F1C0000
+C308:00000008000812081208340E2A0849080008000003F802080208020803F80000
+C309:00000008000812081208340E2A084908000800000208020803F8020803F80000
+C30A:00000008000812081208340E2A08490800080000110811081F0811141F620000
+C30B:00000008000812081208340E2A08490800080000001000100010006801840000
+C30C:00000008000812081208340E2A084908000800000048004800A8011406620000
+C30D:00000008000812081208340E2A08490800080000000003F00408040803F00000
+C30E:00000008000812081208340E2A0849080008000003F80020002000D003080000
+C30F:00000008000812081208340E2A08490800080000004003F8004000A003180000
+C310:00000008000812081208340E2A0849080008000003F8000803F8000800080000
+C311:00000008000812081208340E2A0849080008000003F8020003F8020003F80000
+C312:00000008000812081208340E2A0849080008000000000FF8022002200FF80000
+C313:00000008000812081208340E2A0849080008000000800FF803E0041003E00000
+C314:0000000000120012089208920892191E15122292CC5200120012001200120000
+C315:0000002800281228122834382A2849280028000007F800080008000800080000
+C316:0000002800281228122834382A2849280028000000003EF80208020802080000
+C317:0000002800281228122834382A2849280028000000003E100210022802C40000
+C318:0000002800281228122834382A2849280028002808000800080008000FF80000
+C319:0000002800281228122834382A28492800280000000020F8201020303ECC0000
+C31A:0000002800281228122834382A28492800280000202021FC207020883E700000
+C31B:0000002800281228122834382A2849280028000003F802000200020003F80000
+C31C:0000002800281228122834382A2849280028000007F8000807F8040007F80000
+C31D:0000002800281228122834382A284928002800003EF802083E0820083E080000
+C31E:0000002800281228122834382A284928002800003EF802883E8820883EF80000
+C31F:0000002800281228122834382A284928002800003E8802883EF820883EF80000
+C320:0000002800281228122834382A284928002800001F0801081F0810141F620000
+C321:0000002800281228122834382A284928002800003EF802803EF820803EF80000
+C322:0000002800281228122834382A284928002800003EFC02483E4820483EFC0000
+C323:0000002800281228122834382A284928002800003E1002FE3E3820443E380000
+C324:0000002800281228122834382A2849280028000003F802080208020803F80000
+C325:0000002800281228122834382A284928002800000208020803F8020803F80000
+C326:0000002800281228122834382A28492800280000110811081F0811141F620000
+C327:0000002800281228122834382A28492800280000000800080008003400C20000
+C328:0000002800281228122834382A284928002800000048004800A8011406620000
+C329:0000002800281228122834382A28492800280000000001F00208020801F00000
+C32A:0000002800281228122834382A2849280028000003F80020002000D003080000
+C32B:0000002800281228122834382A28492800280000004003F8004000A003180000
+C32C:0000002800281228122834382A2849280028000003F8000803F8000800080000
+C32D:0000002800281228122834382A2849280028000003F8020003F8020003F80000
+C32E:0000002800281228122834382A2849280028000000000FF8022002200FF80000
+C32F:0000002800281228122834382A2849280028000000800FF803E0041003E00000
+C330:000000000010001008900890089E19101510229ECC5000100010001000100000
+C331:0000000800081208120E34082A0E49080008000007F800080008000800080000
+C332:0000000800081208120E34082A0E49080008000000003EF80208020802080000
+C333:0000000800081208120E34082A0E49080008000000001F080108011401620000
+C334:0000000800081208120E34082A0E49080008000008000800080008000FF80000
+C335:0000000800081208120E34082A0E490800080000000010F8101010301ECC0000
+C336:0000000800081208120E34082A0E4908000800000808087F081C08220F9C0000
+C337:0000000800081208120E34082A0E49080008000003F802000200020003F80000
+C338:0000000800081208120E34082A0E49080008000007F8000807F8040007F80000
+C339:0000000800081208120E34082A0E4908000800003EF802083E0820083E080000
+C33A:0000000800081208120E34082A0E4908000800003EF802883E8820883EF80000
+C33B:0000000800081208120E34082A0E4908000800003E8802883EF820883EF80000
+C33C:0000000800081208120E34082A0E4908000800001F0801081F0810141F620000
+C33D:0000000800081208120E34082A0E4908000800003EF802803EF820803EF80000
+C33E:0000000800081208120E34082A0E4908000800003EFC02483E4820483EFC0000
+C33F:0000000800081208120E34082A0E4908000800001F08017F1F1C10221F1C0000
+C340:0000000800081208120E34082A0E49080008000003F802080208020803F80000
+C341:0000000800081208120E34082A0E4908000800000208020803F8020803F80000
+C342:0000000800081208120E34082A0E490800080000110811081F0811141F620000
+C343:0000000800081208120E34082A0E490800080000001000100010006801840000
+C344:0000000800081208120E34082A0E4908000800000048004800A8011406620000
+C345:0000000800081208120E34082A0E490800080000000003F00408040803F00000
+C346:0000000800081208120E34082A0E49080008000003F80020002000D003080000
+C347:0000000800081208120E34082A0E490800080000004003F8004000A003180000
+C348:0000000800081208120E34082A0E49080008000003F8000803F8000800080000
+C349:0000000800081208120E34082A0E49080008000003F8020003F8020003F80000
+C34A:0000000800081208120E34082A0E49080008000000000FF8022002200FF80000
+C34B:0000000800081208120E34082A0E49080008000000800FF803E0041003E00000
+C34C:000000000012001208920892089E19121512229ECC5200120012001200120000
+C34D:0000002800281228123834282A3849280028000007F800080008000800080000
+C34E:0000002800281228123834282A3849280028000000003EF80208020802080000
+C34F:0000002800281228123834282A3849280028000000003E100210022802C40000
+C350:0000002800281228123834282A3849280028002808000800080008000FF80000
+C351:0000002800281228123834282A38492800280000000020F8201020303ECC0000
+C352:0000002800281228123834282A38492800280000202021FC207020883E700000
+C353:0000002800281228123834282A3849280028000003F802000200020003F80000
+C354:0000002800281228123834282A3849280028000007F8000807F8040007F80000
+C355:0000002800281228123834282A384928002800003EF802083E0820083E080000
+C356:0000002800281228123834282A384928002800003EF802883E8820883EF80000
+C357:0000002800281228123834282A384928002800003E8802883EF820883EF80000
+C358:0000002800281228123834282A384928002800001F0801081F0810141F620000
+C359:0000002800281228123834282A384928002800003EF802803EF820803EF80000
+C35A:0000002800281228123834282A384928002800003EFC02483E4820483EFC0000
+C35B:0000002800281228123834282A384928002800003E1002FE3E3820443E380000
+C35C:0000002800281228123834282A3849280028000003F802080208020803F80000
+C35D:0000002800281228123834282A384928002800000208020803F8020803F80000
+C35E:0000002800281228123834282A38492800280000110811081F0811141F620000
+C35F:0000002800281228123834282A38492800280000000800080008003400C20000
+C360:0000002800281228123834282A384928002800000048004800A8011406620000
+C361:0000002800281228123834282A38492800280000000001F00208020801F00000
+C362:0000002800281228123834282A3849280028000003F80020002000D003080000
+C363:0000002800281228123834282A38492800280000004003F8004000A003180000
+C364:0000002800281228123834282A3849280028000003F8000803F8000800080000
+C365:0000002800281228123834282A3849280028000003F8020003F8020003F80000
+C366:0000002800281228123834282A3849280028000000000FF8022002200FF80000
+C367:0000002800281228123834282A3849280028000000800FF803E0041003E00000
+C368:0000000000020002088208820882191E15022282CC4200020002000200020000
+C369:0000000800081208120834382A08490800080000000007F80008000800080000
+C36A:0000000800081208120834382A0849080008000000003EF80208020802080000
+C36B:0000000800081208120834382A0849080008000000001F080108011401620000
+C36C:0000000800081208120834382A0849080008000000001000100010001FF80000
+C36D:0000000800081208120834382A08490800080000000020F8201020303ECC0000
+C36E:0000000800081208120834382A08490800080000202021FC207020883E700000
+C36F:0000000800081208120834382A0849080008000003F802000200020003F80000
+C370:0000000800081208120834382A0849080008000007F8000807F8040007F80000
+C371:0000000800081208120834382A084908000800003EF802083E0820083E080000
+C372:0000000800081208120834382A084908000800003EF802883E8820883EF80000
+C373:0000000800081208120834382A084908000800003E8802883EF820883EF80000
+C374:0000000800081208120834382A084908000800000F8800880F8808140FA20000
+C375:0000000800081208120834382A084908000800003EF802803EF820803EF80000
+C376:0000000800081208120834382A084908000800003EFC02483E4820483EFC0000
+C377:0000000800081208120834382A084908000800003E1002FE3E3820443E380000
+C378:0000000800081208120834382A0849080008000003F802080208020803F80000
+C379:0000000800081208120834382A084908000800000208020803F8020803F80000
+C37A:0000000800081208120834382A08490800080000210821083F0821143F620000
+C37B:0000000800081208120834382A08490800080000001000100010006801840000
+C37C:0000000800081208120834382A084908000800000048004800A8011406620000
+C37D:0000000800081208120834382A08490800080000000003F00408040803F00000
+C37E:0000000800081208120834382A0849080008000003F80020002000D003080000
+C37F:0000000800081208120834382A08490800080000004003F8004000A003180000
+C380:0000000800081208120834382A0849080008000003F8000803F8000800080000
+C381:0000000800081208120834382A0849080008000003F8020003F8020003F80000
+C382:0000000800081208120834382A0849080008000000000FF8022002200FF80000
+C383:0000000800081208120834382A0849080008000000800FF803E0041003E00000
+C384:00000000000A000A088A088A088A193A150A228ACC4A000A000A000A000A0000
+C385:0000002800281228122834E82A2849280028000007F800080008000800080000
+C386:0000002800281228122834E82A2849280028000000003EF80208020802080000
+C387:0000002800281228122834E82A2849280028000000003E100210022802C40000
+C388:0000002800281228122834E82A2849280028000008000800080008000FF80000
+C389:0000002800281228122834E82A28492800280000000020F8201020303ECC0000
+C38A:0000002800281228122834E82A28492800280000202021FC207020883E700000
+C38B:0000002800281228122834E82A2849280028000003F802000200020003F80000
+C38C:0000002800281228122834E82A2849280028000007F8000807F8040007F80000
+C38D:0000002800281228122834E82A284928002800003EF802083E0820083E080000
+C38E:0000002800281228122834E82A284928002800003EF802883E8820883EF80000
+C38F:0000002800281228122834E82A284928002800003E8802883EF820883EF80000
+C390:0000002800281228122834E82A284928002800001F0801081F0810141F620000
+C391:0000002800281228122834E82A284928002800003EF802803EF820803EF80000
+C392:0000002800281228122834E82A284928002800003EFC02483E4820483EFC0000
+C393:0000002800281228122834E82A284928002800003E1002FE3E3820443E380000
+C394:0000002800281228122834E82A2849280028000003F802080208020803F80000
+C395:0000002800281228122834E82A284928002800000208020803F8020803F80000
+C396:0000002800281228122834E82A28492800280000110811081F0811141F620000
+C397:0000002800281228122834E82A28492800280000000800080008003400C20000
+C398:0000002800281228122834E82A284928002800000048004800A8011406620000
+C399:0000002800281228122834E82A28492800280000000001F00208020801F00000
+C39A:0000002800281228122834E82A2849280028000003F80020002000D003080000
+C39B:0000002800281228122834E82A28492800280000004003F8004000A003180000
+C39C:0000002800281228122834E82A2849280028000003F8000803F8000800080000
+C39D:0000002800281228122834E82A2849280028000003F8020003F8020003F80000
+C39E:0000002800281228122834E82A2849280028000000000FF8022002200FF80000
+C39F:0000002800281228122834E82A2849280028000000800FF803E0041003E00000
+C3A0:000000000002000208820882089E19021502229ECC4200020002000200020000
+C3A1:0000000800081208123834082A38490800080000000007F80008000800080000
+C3A2:0000000800081208123834082A3849080008000000003EF80208020802080000
+C3A3:0000000800081208123834082A3849080008000000001F080108011401620000
+C3A4:0000000800081208123834082A3849080008000800001000100010001FF80000
+C3A5:0000000800081208123834082A38490800080000000020F8201020303ECC0000
+C3A6:0000000800081208123834082A38490800080000202021FC207020883E700000
+C3A7:0000000800081208123834082A3849080008000003F802000200020003F80000
+C3A8:0000000800081208123834082A3849080008000007F8000807F8040007F80000
+C3A9:0000000800081208123834082A384908000800003EF802083E0820083E080000
+C3AA:0000000800081208123834082A384908000800003EF802883E8820883EF80000
+C3AB:0000000800081208123834082A384908000800003E8802883EF820883EF80000
+C3AC:0000000800081208123834082A384908000800000F8800880F8808140FA20000
+C3AD:0000000800081208123834082A384908000800003EF802803EF820803EF80000
+C3AE:0000000800081208123834082A384908000800003EFC02483E4820483EFC0000
+C3AF:0000000800081208123834082A384908000800003E1002FE3E3820443E380000
+C3B0:0000000800081208123834082A3849080008000003F802080208020803F80000
+C3B1:0000000800081208123834082A384908000800000208020803F8020803F80000
+C3B2:0000000800081208123834082A38490800080000210821083F0821143F620000
+C3B3:0000000800081208123834082A38490800080000001000100010006801840000
+C3B4:0000000800081208123834082A384908000800000048004800A8011406620000
+C3B5:0000000800081208123834082A38490800080000000003F00408040803F00000
+C3B6:0000000800081208123834082A3849080008000003F80020002000D003080000
+C3B7:0000000800081208123834082A38490800080000004003F8004000A003180000
+C3B8:0000000800081208123834082A3849080008000003F8000803F8000800080000
+C3B9:0000000800081208123834082A3849080008000003F8020003F8020003F80000
+C3BA:0000000800081208123834082A3849080008000000000FF8022002200FF80000
+C3BB:0000000800081208123834082A3849080008000000800FF803E0041003E00000
+C3BC:00000000000A000A088A088A08BA190A150A22BACC4A000A000A000A000A0000
+C3BD:000000280028122812E834282AE849280028000007F800080008000800080000
+C3BE:000000280028122812E834282AE849280028000000003EF80208020802080000
+C3BF:000000280028122812E834282AE849280028000000003E100210022802C40000
+C3C0:000000280028122812E834282AE849280028002808000800080008000FF80000
+C3C1:000000280028122812E834282AE8492800280000000020F8201020303ECC0000
+C3C2:000000280028122812E834282AE8492800280000202021FC207020883E700000
+C3C3:000000280028122812E834282AE849280028000003F802000200020003F80000
+C3C4:000000280028122812E834282AE849280028000007F8000807F8040007F80000
+C3C5:000000280028122812E834282AE84928002800003EF802083E0820083E080000
+C3C6:000000280028122812E834282AE84928002800003EF802883E8820883EF80000
+C3C7:000000280028122812E834282AE84928002800003E8802883EF820883EF80000
+C3C8:000000280028122812E834282AE84928002800001F0801081F0810141F620000
+C3C9:000000280028122812E834282AE84928002800003EF802803EF820803EF80000
+C3CA:000000280028122812E834282AE84928002800003EFC02483E4820483EFC0000
+C3CB:000000280028122812E834282AE84928002800003E1002FE3E3820443E380000
+C3CC:000000280028122812E834282AE849280028000003F802080208020803F80000
+C3CD:000000280028122812E834282AE84928002800000208020803F8020803F80000
+C3CE:000000280028122812E834282AE8492800280000110811081F0811141F620000
+C3CF:000000280028122812E834282AE8492800280000000800080008003400C20000
+C3D0:000000280028122812E834282AE84928002800000048004800A8011406620000
+C3D1:000000280028122812E834282AE8492800280000000001F00208020801F00000
+C3D2:000000280028122812E834282AE849280028000003F80020002000D003080000
+C3D3:000000280028122812E834282AE8492800280000004003F8004000A003180000
+C3D4:000000280028122812E834282AE849280028000003F8000803F8000800080000
+C3D5:000000280028122812E834282AE849280028000003F8020003F8020003F80000
+C3D6:000000280028122812E834282AE849280028000000000FF8022002200FF80000
+C3D7:000000280028122812E834282AE849280028000000800FF803E0041003E00000
+C3D8:0000000000000220022002200640054008A033100100010001007FFC00000000
+C3D9:000000000220022004400AA0111001007FFC00001FF000100010001000100000
+C3DA:000000000220022004400AA0111001007FFC000000003EF80208020802080000
+C3DB:000000000220022004400AA0111001007FFC000000001E100210022802C40000
+C3DC:000000000220022004400AA0111001007FFC000000001000100010001FF00000
+C3DD:000000000220022004400AA0111001007FFC0000000020F8201020303ECC0000
+C3DE:000000000220022004400AA0111001007FFC0000202021FC207020883E700000
+C3DF:000000000220022004400AA0111001007FFC00001FF01000100010001FF00000
+C3E0:000000000220022004400AA0111001007FFC00001FF000101FF010001FF00000
+C3E1:000000000220022004400AA0111001007FFC00003EF802083E0820083E080000
+C3E2:000000000220022004400AA0111001007FFC00003EF802883E8820883EF80000
+C3E3:000000000220022004400AA0111001007FFC00003E8802883EF820883EF80000
+C3E4:000000000220022004400AA0111001007FFC00003E1002103E1020283EC40000
+C3E5:000000000220022004400AA0111001007FFC00003EF802803EF820803EF80000
+C3E6:000000000220022004400AA0111001007FFC00003EFC02483E4820483EFC0000
+C3E7:000000000220022004400AA0111001007FFC00003E2003FC3E7020883E700000
+C3E8:000000000220022004400AA0111001007FFC00001FF01010101010101FF00000
+C3E9:000000000220022004400AA0111001007FFC0000101010101FF010101FF00000
+C3EA:000000000220022004400AA0111001007FFC0000222022203E2022503E880000
+C3EB:000000000220022004400AA0111001007FFC000000000100010002800C400000
+C3EC:000000000220022004400AA0111001007FFC00000000024002400DA033100000
+C3ED:000000000220022004400AA0111001007FFC0000000007C00820082007C00000
+C3EE:000000000220022004400AA0111001007FFC0000000007E00080014006200000
+C3EF:000000000220022004400AA0111001007FFC0000008007E00080014006200000
+C3F0:000000000220022004400AA0111001007FFC00001FF000101FF0001000100000
+C3F1:000000000220022004400AA0111001007FFC00001FF010001FF010001FF00000
+C3F2:000000000220022004400AA0111001007FFC000000001FF0044004401FF00000
+C3F3:000000000220022004400AA0111001007FFC000001001FF007C0082007C00000
+C3F4:0000001000100890089008901910151E2290CC50041004107FD0001000100000
+C3F5:00000888088811082A8E4448040804087FE8000007F800080008000800080000
+C3F6:00000888088811082A8E4448040804087FE8000000003EF80208020802080000
+C3F7:00000888088811082A8E4448040804087FE8000000001F080108011401620000
+C3F8:00000888088811082A8E4448040804087FE8000008000800080008000FF80000
+C3F9:00000888088811082A8E4448040804087FE80000000010F8101010301ECC0000
+C3FA:00000888088811082A8E4448040804087FE800000808087F081C08220F9C0000
+C3FB:00000888088811082A8E4448040804087FE8000003F802000200020003F80000
+C3FC:00000888088811082A8E4448040804087FE8000007F8000807F8040007F80000
+C3FD:00000888088811082A8E4448040804087FE800003EF802083E0820083E080000
+C3FE:00000888088811082A8E4448040804087FE800003EF802883E8820883EF80000
+C3FF:00000888088811082A8E4448040804087FE800003E8802883EF820883EF80000
+C400:00000888088811082A8E4448040804087FE800001F0801081F0810141F620000
+C401:00000888088811082A8E4448040804087FE800003EF802803EF820803EF80000
+C402:00000888088811082A8E4448040804087FE800003EFC02483E4820483EFC0000
+C403:00000888088811082A8E4448040804087FE800001F08017F1F1C10221F1C0000
+C404:00000888088811082A8E4448040804087FE8000003F802080208020803F80000
+C405:00000888088811082A8E4448040804087FE800000208020803F8020803F80000
+C406:00000888088811082A8E4448040804087FE80000110811081F0811141F620000
+C407:00000888088811082A8E4448040804087FE80000001000100010006801840000
+C408:00000888088811082A8E4448040804087FE800000048004800A8011406620000
+C409:00000888088811082A8E4448040804087FE80000000003F00408040803F00000
+C40A:00000888088811082A8E4448040804087FE8000003F80020002000D003080000
+C40B:00000888088811082A8E4448040804087FE80000004003F8004000A003180000
+C40C:00000888088811082A8E4448040804087FE8000003F8000803F8000800080000
+C40D:00000888088811082A8E4448040804087FE8000003F8020003F8020003F80000
+C40E:00000888088811082A8E4448040804087FE8000000000FF8022002200FF80000
+C40F:00000888088811082A8E4448040804087FE8000000800FF803E0041003E00000
+C410:0000001200120892089208921912151E2292CC52041204127FD2001200120000
+C411:000008A808A811282AB84468042804287FA8000007F800080008000800080000
+C412:000008A808A811282AB84468042804287FA8000000003EF80208020802080000
+C413:000008A808A811282AB84468042804287FA8000000001F080108011401620000
+C414:000008A808A811282AB84468042804287FA8000008000800080008000FF80000
+C415:000008A808A811282AB84468042804287FA80000000010F8101010301ECC0000
+C416:000008A808A811282AB84468042804287FA800000808087F081C08220F9C0000
+C417:000008A808A811282AB84468042804287FA8000003F802000200020003F80000
+C418:000008A808A811282AB84468042804287FA8000007F8000807F8040007F80000
+C419:000008A808A811282AB84468042804287FA800003EF802083E0820083E080000
+C41A:000008A808A811282AB84468042804287FA800003EF802883E8820883EF80000
+C41B:000008A808A811282AB84468042804287FA800003E8802883EF820883EF80000
+C41C:000008A808A811282AB84468042804287FA800001F0801081F0810141F620000
+C41D:000008A808A811282AB84468042804287FA800003EF802803EF820803EF80000
+C41E:000008A808A811282AB84468042804287FA800003EFC02483E4820483EFC0000
+C41F:000008A808A811282AB84468042804287FA800001F08017F1F1C10221F1C0000
+C420:000008A808A811282AB84468042804287FA8000003F802080208020803F80000
+C421:000008A808A811282AB84468042804287FA800000208020803F8020803F80000
+C422:000008A808A811282AB84468042804287FA80000110811081F0811141F620000
+C423:000008A808A811282AB84468042804287FA80000001000100010006801840000
+C424:000008A808A811282AB84468042804287FA800000048004800A8011406620000
+C425:000008A808A811282AB84468042804287FA80000000003F00408040803F00000
+C426:000008A808A811282AB84468042804287FA8000003F80020002000D003080000
+C427:000008A808A811282AB84468042804287FA80000004003F8004000A003180000
+C428:000008A808A811282AB84468042804287FA8000003F8000803F8000800080000
+C429:000008A808A811282AB84468042804287FA8000003F8020003F8020003F80000
+C42A:000008A808A811282AB84468042804287FA8000000000FF8022002200FF80000
+C42B:000008A808A811282AB84468042804287FA8000000800FF803E0041003E00000
+C42C:000000080008088808880888190815082288CC48040804087FE8000800080000
+C42D:00000888088811082A884448040804087FE8000007F800080008000800080000
+C42E:00000888088811082A884448040804087FE8000000003EF80208020802080000
+C42F:00000888088811082A884448040804087FE8000000001F080108011401620000
+C430:00000888088811082A884448040804087FE8000008000800080008000FF80000
+C431:00000888088811082A884448040804087FE80000000010F8101010301ECC0000
+C432:00000888088811082A884448040804087FE800000808087F081C08220F9C0000
+C433:00000888088811082A884448040804087FE8000003F802000200020003F80000
+C434:00000888088811082A884448040804087FE8000007F8000807F8040007F80000
+C435:00000888088811082A884448040804087FE800003EF802083E0820083E080000
+C436:00000888088811082A884448040804087FE800003EF802883E8820883EF80000
+C437:00000888088811082A884448040804087FE800003E8802883EF820883EF80000
+C438:00000888088811082A884448040804087FE800001F0801081F0810141F620000
+C439:00000888088811082A884448040804087FE800003EF802803EF820803EF80000
+C43A:00000888088811082A884448040804087FE800003EFC02483E4820483EFC0000
+C43B:00000888088811082A884448040804087FE800001F08017F1F1C10221F1C0000
+C43C:00000888088811082A884448040804087FE8000003F802080208020803F80000
+C43D:00000888088811082A884448040804087FE800000208020803F8020803F80000
+C43E:00000888088811082A884448040804087FE80000110811081F0811141F620000
+C43F:00000888088811082A884448040804087FE80000001000100010006801840000
+C440:00000888088811082A884448040804087FE800000048004800A8011406620000
+C441:00000888088811082A884448040804087FE80000000003F00408040803F00000
+C442:00000888088811082A884448040804087FE8000003F80020002000D003080000
+C443:00000888088811082A884448040804087FE80000004003F8004000A003180000
+C444:00000888088811082A884448040804087FE8000003F8000803F8000800080000
+C445:00000888088811082A884448040804087FE8000003F8020003F8020003F80000
+C446:00000888088811082A884448040804087FE8000000000FF8022002200FF80000
+C447:00000888088811082A884448040804087FE8000000800FF803E0041003E00000
+C448:0000000000000220022002200640054008A037500440044004407FFC00000000
+C449:000000000220022004400AA0155004407FFC00001FF000100010001000100000
+C44A:000000000220022004400AA0155004407FFC000000003EF80208020802080000
+C44B:000000000220022004400AA0155004407FFC000000001E100210022802C40000
+C44C:000000000220022004400AA0155004407FFC000000001000100010001FF00000
+C44D:000000000220022004400AA0155004407FFC0000000020F8201020303ECC0000
+C44E:000000000220022004400AA0155004407FFC0000202021FC207020883E700000
+C44F:000000000220022004400AA0155004407FFC00001FF01000100010001FF00000
+C450:000000000220022004400AA0155004407FFC00001FF000101FF010001FF00000
+C451:000000000220022004400AA0155004407FFC00003EF802083E0820083E080000
+C452:000000000220022004400AA0155004407FFC00003EF802883E8820883EF80000
+C453:000000000220022004400AA0155004407FFC00003E8802883EF820883EF80000
+C454:000000000220022004400AA0155004407FFC00003E1002103E1020283EC40000
+C455:000000000220022004400AA0155004407FFC00003EF802803EF820803EF80000
+C456:000000000220022004400AA0155004407FFC00003EFC02483E4820483EFC0000
+C457:000000000220022004400AA0155004407FFC00003E2003FC3E7020883E700000
+C458:000000000220022004400AA0155004407FFC00001FF01010101010101FF00000
+C459:000000000220022004400AA0155004407FFC0000101010101FF010101FF00000
+C45A:000000000220022004400AA0155004407FFC0000222022203E2022503E880000
+C45B:000000000220022004400AA0155004407FFC000000000100010002800C400000
+C45C:000000000220022004400AA0155004407FFC00000000024002400DA033100000
+C45D:000000000220022004400AA0155004407FFC0000000007C00820082007C00000
+C45E:000000000220022004400AA0155004407FFC0000000007E00080014006200000
+C45F:000000000220022004400AA0155004407FFC0000008007E00080014006200000
+C460:000000000220022004400AA0155004407FFC00001FF000101FF0001000100000
+C461:000000000220022004400AA0155004407FFC00001FF010001FF010001FF00000
+C462:000000000220022004400AA0155004407FFC000000001FF0044004401FF00000
+C463:000000000220022004400AA0155004407FFC000001001FF007C0082007C00000
+C464:000000000220022002200640054008A0331000003FF801000100010001000000
+C465:000000000220022004400AA011107FFC010001001FF000100010001000100000
+C466:000000000220022004400AA011107FFC0100010000003EF80208020802080000
+C467:000000000220022004400AA011107FFC0100010000001E100210022802C40000
+C468:000000000220022004400AA0111000007FFC010001001100100010001FF00000
+C469:000000000220022004400AA011107FFC01000100000020F8201020303ECC0000
+C46A:000000000220022004400AA011107FFC01000100202021FC207020883E700000
+C46B:000000000220022004400AA011107FFC010001001FF01000100010001FF00000
+C46C:000000000220022004400AA011107FFC010001001FF000101FF010001FF00000
+C46D:000000000220022004400AA011107FFC010001003EF802083E0820083E080000
+C46E:000000000220022004400AA011107FFC010001003EF802883E8820883EF80000
+C46F:000000000220022004400AA011107FFC010001003E8802883EF820883EF80000
+C470:000000000220022004400AA011107FFC010001003E1002103E1020283EC40000
+C471:000000000220022004400AA011107FFC010001003EF802803EF820803EF80000
+C472:000000000220022004400AA011107FFC010001003EFC02483E4820483EFC0000
+C473:000000000220022004400AA011107FFC010001003E2003FC3E7020883E700000
+C474:000000000220022004400AA011107FFC010001001FF01010101010101FF00000
+C475:000000000220022004400AA011107FFC01000100101010101FF010101FF00000
+C476:000000000220022004400AA011107FFC01000100222022203E2022503E880000
+C477:000000000220022004400AA011107FFC0100010000000100010002800C400000
+C478:000000000220022004400AA011107FFC010001000000024002400DA033100000
+C479:000000000220022004400AA011107FFC01000100000007C00820082007C00000
+C47A:000000000220022004400AA011107FFC01000100000007E00080014006200000
+C47B:000000000220022004400AA011107FFC01000100008007E00080014006200000
+C47C:000000000220022004400AA011107FFC010001001FF000101FF0001000100000
+C47D:000000000220022004400AA011107FFC010001001FF010001FF010001FF00000
+C47E:000000000220022004400AA011107FFC0100010000001FF0044004401FF00000
+C47F:000000000220022004400AA011107FFC0100010001001FF007C0082007C00000
+C480:00000008088808880888190815082288CC4800087FE8040804F8040804080000
+C481:00080888088811082A8844487FE8027802080000000007F80008000800080000
+C482:00080888088811082A8844487FE802780208000000003EF80208020802080000
+C483:00080888088811082A8844487FE802780208000000001F080108011401620000
+C484:00080888088811082A88444800087FE80278020802081000100010001FF80000
+C485:00080888088811082A8844487FE8027802080000000020F8201020303ECC0000
+C486:00080888088811082A8844487FE8027802080000202021FC207020883E700000
+C487:00080888088811082A8844487FE802780208000003F802000200020003F80000
+C488:00080888088811082A8844487FE802780208000007F8000807F8040007F80000
+C489:00080888088811082A8844487FE80278020800003EF802083E0820083E080000
+C48A:00080888088811082A8844487FE80278020800003EF802883E8820883EF80000
+C48B:00080888088811082A8844487FE80278020800003E8802883EF820883EF80000
+C48C:00080888088811082A8844487FE80278020800000F8800880F8808140FA20000
+C48D:00080888088811082A8844487FE80278020800003EF802803EF820803EF80000
+C48E:00080888088811082A8844487FE80278020800003EFC02483E4820483EFC0000
+C48F:00080888088811082A8844487FE80278020800003E1002FE3E3820443E380000
+C490:00080888088811082A8844487FE802780208000003F802080208020803F80000
+C491:00080888088811082A8844487FE80278020800000208020803F8020803F80000
+C492:00080888088811082A8844487FE8027802080000210821083F0821143F620000
+C493:00080888088811082A8844487FE8027802080000001000100010006801840000
+C494:00080888088811082A8844487FE80278020800000048004800A8011406620000
+C495:00080888088811082A8844487FE8027802080000000003F00408040803F00000
+C496:00080888088811082A8844487FE802780208000003F80020002000D003080000
+C497:00080888088811082A8844487FE8027802080000004003F8004000A003180000
+C498:00080888088811082A8844487FE802780208000003F8000803F8000800080000
+C499:00080888088811082A8844487FE802780208000003F8020003F8020003F80000
+C49A:00080888088811082A8844487FE802780208000000000FF8022002200FF80000
+C49B:00080888088811082A8844487FE802780208000000800FF803E0041003E00000
+C49C:0000000A088A088A088A190A150A228ACC4A000A7FEA040A047A040A040A0000
+C49D:002808A808A811282AA844687FA805E804280000000007F80008000800080000
+C49E:002808A808A811282AA844687FA805E80428000000003EF80208020802080000
+C49F:002808A808A811282AA844687FA805E80428000000001F080108011401620000
+C4A0:002808A808A811282AA8446800287FA8042805E804281428100010001FF80000
+C4A1:002808A808A811282AA844687FA805E804280000000020F8201020303ECC0000
+C4A2:002808A808A811282AA844687FA805E804280000202021FC207020883E700000
+C4A3:002808A808A811282AA844687FA805E80428000003F802000200020003F80000
+C4A4:002808A808A811282AA844687FA805E80428000007F8000807F8040007F80000
+C4A5:002808A808A811282AA844687FA805E8042800003EF802083E0820083E080000
+C4A6:002808A808A811282AA844687FA805E8042800003EF802883E8820883EF80000
+C4A7:002808A808A811282AA844687FA805E8042800003E8802883EF820883EF80000
+C4A8:002808A808A811282AA844687FA805E8042800000F8800880F8808140FA20000
+C4A9:002808A808A811282AA844687FA805E8042800003EF802803EF820803EF80000
+C4AA:002808A808A811282AA844687FA805E8042800003EFC02483E4820483EFC0000
+C4AB:002808A808A811282AA844687FA805E8042800003E1002FE3E3820443E380000
+C4AC:002808A808A811282AA844687FA805E80428000003F802080208020803F80000
+C4AD:002808A808A811282AA844687FA805E8042800000208020803F8020803F80000
+C4AE:002808A808A811282AA844687FA805E804280000210821083F0821143F620000
+C4AF:002808A808A811282AA844687FA805E804280000001000100010006801840000
+C4B0:002808A808A811282AA844687FA805E8042800000048004800A8011406620000
+C4B1:002808A808A811282AA844687FA805E804280000000003F00408040803F00000
+C4B2:002808A808A811282AA844687FA805E80428000003F80020002000D003080000
+C4B3:002808A808A811282AA844687FA805E804280000004003F8004000A003180000
+C4B4:002808A808A811282AA844687FA805E80428000003F8000803F8000800080000
+C4B5:002808A808A811282AA844687FA805E80428000003F8020003F8020003F80000
+C4B6:002808A808A811282AA844687FA805E80428000000000FF8022002200FF80000
+C4B7:002808A808A811282AA844687FA805E80428000000800FF803E0041003E00000
+C4B8:00000008088808880888190815082288CC4800087FE804080408040804080000
+C4B9:00080888088811082A8844487FE8020802000000000007F80008000800080000
+C4BA:00080888088811082A8844487FE802080200000000003EF80208020802080000
+C4BB:00080888088811082A8844487FE802080200000000001F080108011401620000
+C4BC:00080888088811082A88444800087FE80208020802081008100010001FF80000
+C4BD:00080888088811082A8844487FE8020802000000000020F8201020303ECC0000
+C4BE:00080888088811082A8844487FE8020802000000202021FC207020883E700000
+C4BF:00080888088811082A8844487FE802080200000003F802000200020003F80000
+C4C0:00080888088811082A8844487FE802080200000007F8000807F8040007F80000
+C4C1:00080888088811082A8844487FE80208020000003EF802083E0820083E080000
+C4C2:00080888088811082A8844487FE80208020000003EF802883E8820883EF80000
+C4C3:00080888088811082A8844487FE80208020000003E8802883EF820883EF80000
+C4C4:00080888088811082A8844487FE80208020000000F8800880F8808140FA20000
+C4C5:00080888088811082A8844487FE80208020000003EF802803EF820803EF80000
+C4C6:00080888088811082A8844487FE80208020000003EFC02483E4820483EFC0000
+C4C7:00080888088811082A8844487FE80208020000003E1002FE3E3820443E380000
+C4C8:00080888088811082A8844487FE802080200000003F802080208020803F80000
+C4C9:00080888088811082A8844487FE80208020000000208020803F8020803F80000
+C4CA:00080888088811082A8844487FE8020802000000210821083F0821143F620000
+C4CB:00080888088811082A8844487FE8020802000000001000100010006801840000
+C4CC:00080888088811082A8844487FE80208020000000048004800A8011406620000
+C4CD:00080888088811082A8844487FE8020802000000000003F00408040803F00000
+C4CE:00080888088811082A8844487FE802080200000003F80020002000D003080000
+C4CF:00080888088811082A8844487FE8020802000000004003F8004000A003180000
+C4D0:00080888088811082A8844487FE802080200000003F8000803F8000800080000
+C4D1:00080888088811082A8844487FE802080200000003F8020003F8020003F80000
+C4D2:00080888088811082A8844487FE802080200000000000FF8022002200FF80000
+C4D3:00080888088811082A8844487FE802080200000000800FF803E0041003E00000
+C4D4:000000000220022002200640054008A0331000007FFC04400440044004400000
+C4D5:000000000220022004400AA011107FFC044004401FF000100010001000100000
+C4D6:000000000220022004400AA011107FFC0440044000003EF80208020802080000
+C4D7:000000000220022004400AA011107FFC0440044000001E100210022802C40000
+C4D8:000000000220022004400AA0111000007FFC044004401440100010001FF00000
+C4D9:000000000220022004400AA011107FFC04400440000020F8201020303ECC0000
+C4DA:000000000220022004400AA011107FFC04400440202021FC207020883E700000
+C4DB:000000000220022004400AA011107FFC044004401FF01000100010001FF00000
+C4DC:000000000220022004400AA011107FFC044004401FF000101FF010001FF00000
+C4DD:000000000220022004400AA011107FFC044004403EF802083E0820083E080000
+C4DE:000000000220022004400AA011107FFC044004403EF802883E8820883EF80000
+C4DF:000000000220022004400AA011107FFC044004403E8802883EF820883EF80000
+C4E0:000000000220022004400AA011107FFC044004403E1002103E1020283EC40000
+C4E1:000000000220022004400AA011107FFC044004403EF802803EF820803EF80000
+C4E2:000000000220022004400AA011107FFC044004403EFC02483E4820483EFC0000
+C4E3:000000000220022004400AA011107FFC044004403E2003FC3E7020883E700000
+C4E4:000000000220022004400AA011107FFC044004401FF01010101010101FF00000
+C4E5:000000000220022004400AA011107FFC04400440101010101FF010101FF00000
+C4E6:000000000220022004400AA011107FFC04400440222022203E2022503E880000
+C4E7:000000000220022004400AA011107FFC0440044000000100010002800C400000
+C4E8:000000000220022004400AA011107FFC044004400000024002400DA033100000
+C4E9:000000000220022004400AA011107FFC04400440000007C00820082007C00000
+C4EA:000000000220022004400AA011107FFC04400440000007E00080014006200000
+C4EB:000000000220022004400AA011107FFC04400440008007E00080014006200000
+C4EC:000000000220022004400AA011107FFC044004401FF000101FF0001000100000
+C4ED:000000000220022004400AA011107FFC044004401FF010001FF010001FF00000
+C4EE:000000000220022004400AA011107FFC0440044000001FF0044004401FF00000
+C4EF:000000000220022004400AA011107FFC0440044001001FF007C0082007C00000
+C4F0:0000000000000220022002200640054008A0331000007FFC0000000000000000
+C4F1:000000000220022004400AA0111000007FFC00001FF000100010001000100000
+C4F2:000000000220022004400AA0111000007FFC000000003EF80208020802080000
+C4F3:000000000220022004400AA0111000007FFC000000001E100210022802C40000
+C4F4:000000000220022004400AA0111000007FFC000000001000100010001FF00000
+C4F5:000000000220022004400AA0111000007FFC0000000020F8201020303ECC0000
+C4F6:000000000220022004400AA0111000007FFC0000202021FC207020883E700000
+C4F7:000000000220022004400AA0111000007FFC00001FF01000100010001FF00000
+C4F8:000000000220022004400AA0111000007FFC00001FF000101FF010001FF00000
+C4F9:000000000220022004400AA0111000007FFC00003EF802083E0820083E080000
+C4FA:000000000220022004400AA0111000007FFC00003EF802883E8820883EF80000
+C4FB:000000000220022004400AA0111000007FFC00003E8802883EF820883EF80000
+C4FC:000000000220022004400AA0111000007FFC00003E1002103E1020283EC40000
+C4FD:000000000220022004400AA0111000007FFC00003EF802803EF820803EF80000
+C4FE:000000000220022004400AA0111000007FFC00003EFC02483E4820483EFC0000
+C4FF:000000000220022004400AA0111000007FFC00003E2003FC3E7020883E700000
+C500:000000000220022004400AA0111000007FFC00001FF01010101010101FF00000
+C501:000000000220022004400AA0111000007FFC0000101010101FF010101FF00000
+C502:000000000220022004400AA0111000007FFC0000222022203E2022503E880000
+C503:000000000220022004400AA0111000007FFC000000000100010002800C400000
+C504:000000000220022004400AA0111000007FFC00000000024002400DA033100000
+C505:000000000220022004400AA0111000007FFC0000000007C00820082007C00000
+C506:000000000220022004400AA0111000007FFC0000000007E00080014006200000
+C507:000000000220022004400AA0111000007FFC0000008007E00080014006200000
+C508:000000000220022004400AA0111000007FFC00001FF000101FF0001000100000
+C509:000000000220022004400AA0111000007FFC00001FF010001FF010001FF00000
+C50A:000000000220022004400AA0111000007FFC000000001FF0044004401FF00000
+C50B:000000000220022004400AA0111000007FFC000001001FF007C0082007C00000
+C50C:000000080008088808880888190815082288CC4800087FE80008000800080000
+C50D:00000888088811082A884448000800087FE8000007F800080008000800080000
+C50E:00000888088811082A884448000800087FE8000000003EF80208020802080000
+C50F:00000888088811082A884448000800087FE8000000001F080108011401620000
+C510:00000888088811082A884448000800087FE8000008000800080008000FF80000
+C511:00000888088811082A884448000800087FE80000000010F8101010301ECC0000
+C512:00000888088811082A884448000800087FE800000808087F081C08220F9C0000
+C513:00000888088811082A884448000800087FE8000003F802000200020003F80000
+C514:00000888088811082A884448000800087FE8000007F8000807F8040007F80000
+C515:00000888088811082A884448000800087FE800003EF802083E0820083E080000
+C516:00000888088811082A884448000800087FE800003EF802883E8820883EF80000
+C517:00000888088811082A884448000800087FE800003E8802883EF820883EF80000
+C518:00000888088811082A884448000800087FE800001F0801081F0810141F620000
+C519:00000888088811082A884448000800087FE800003EF802803EF820803EF80000
+C51A:00000888088811082A884448000800087FE800003EFC02483E4820483EFC0000
+C51B:00000888088811082A884448000800087FE800001F08017F1F1C10221F1C0000
+C51C:00000888088811082A884448000800087FE8000003F802080208020803F80000
+C51D:00000888088811082A884448000800087FE800000208020803F8020803F80000
+C51E:00000888088811082A884448000800087FE80000110811081F0811141F620000
+C51F:00000888088811082A884448000800087FE80000001000100010006801840000
+C520:00000888088811082A884448000800087FE800000048004800A8011406620000
+C521:00000888088811082A884448000800087FE80000000003F00408040803F00000
+C522:00000888088811082A884448000800087FE8000003F80020002000D003080000
+C523:00000888088811082A884448000800087FE80000004003F8004000A003180000
+C524:00000888088811082A884448000800087FE8000003F8000803F8000800080000
+C525:00000888088811082A884448000800087FE8000003F8020003F8020003F80000
+C526:00000888088811082A884448000800087FE8000000000FF8022002200FF80000
+C527:00000888088811082A884448000800087FE8000000800FF803E0041003E00000
+C528:0000000000080008088808880888190815082288CC4800080008000800080000
+C529:0000000800081208120834082A08490800080000000007F80008000800080000
+C52A:0000000800081208120834082A0849080008000000003EF80208020802080000
+C52B:0000000800081208120834082A0849080008000000001F080108011401620000
+C52C:0000000800081208120834082A0849080008000800001000100010001FF80000
+C52D:0000000800081208120834082A08490800080000000020F8201020303ECC0000
+C52E:0000000800081208120834082A08490800080000202021FC207020883E700000
+C52F:0000000800081208120834082A0849080008000003F802000200020003F80000
+C530:0000000800081208120834082A0849080008000007F8000807F8040007F80000
+C531:0000000800081208120834082A084908000800003EF802083E0820083E080000
+C532:0000000800081208120834082A084908000800003EF802883E8820883EF80000
+C533:0000000800081208120834082A084908000800003E8802883EF820883EF80000
+C534:0000000800081208120834082A084908000800000F8800880F8808140FA20000
+C535:0000000800081208120834082A084908000800003EF802803EF820803EF80000
+C536:0000000800081208120834082A084908000800003EFC02483E4820483EFC0000
+C537:0000000800081208120834082A084908000800003E1002FE3E3820443E380000
+C538:0000000800081208120834082A0849080008000003F802080208020803F80000
+C539:0000000800081208120834082A084908000800000208020803F8020803F80000
+C53A:0000000800081208120834082A08490800080000210821083F0821143F620000
+C53B:0000000800081208120834082A08490800080000001000100010006801840000
+C53C:0000000800081208120834082A084908000800000048004800A8011406620000
+C53D:0000000800081208120834082A08490800080000000003F00408040803F00000
+C53E:0000000800081208120834082A0849080008000003F80020002000D003080000
+C53F:0000000800081208120834082A08490800080000004003F8004000A003180000
+C540:0000000800081208120834082A0849080008000003F8000803F8000800080000
+C541:0000000800081208120834082A0849080008000003F8020003F8020003F80000
+C542:0000000800081208120834082A0849080008000000000FF8022002200FF80000
+C543:0000000800081208120834082A0849080008000000800FF803E0041003E00000
+C544:00000000001000101E1021104090409E409021101E1000100010001000100000
+C545:000000081E0821082108210E21081E080008000007F800080008000800080000
+C546:000000081E0821082108210E21081E080008000000003EF80208020802080000
+C547:000000081E0821082108210E21081E080008000000001F080108011401620000
+C548:000000081E0821082108210E21081E080008000808000800080008000FF80000
+C549:000000081E0821082108210E21081E0800080000000010F8101010301ECC0000
+C54A:000000081E0821082108210E21081E08000800000808087F081C08220F9C0000
+C54B:000000081E0821082108210E21081E080008000003F802000200020003F80000
+C54C:000000081E0821082108210E21081E080008000007F8000807F8040007F80000
+C54D:000000081E0821082108210E21081E08000800003EF802083E0820083E080000
+C54E:000000081E0821082108210E21081E08000800003EF802883E8820883EF80000
+C54F:000000081E0821082108210E21081E08000800003E8802883EF820883EF80000
+C550:000000081E0821082108210E21081E08000800001F0801081F0810141F620000
+C551:000000081E0821082108210E21081E08000800003EF802803EF820803EF80000
+C552:000000081E0821082108210E21081E08000800003EFC02483E4820483EFC0000
+C553:000000081E0821082108210E21081E08000800001F08017F1F1C10221F1C0000
+C554:000000081E0821082108210E21081E080008000003F802080208020803F80000
+C555:000000081E0821082108210E21081E08000800000208020803F8020803F80000
+C556:000000081E0821082108210E21081E0800080000110811081F0811141F620000
+C557:000000081E0821082108210E21081E0800080000001000100010006801840000
+C558:000000081E0821082108210E21081E08000800000048004800A8011406620000
+C559:000000081E0821082108210E21081E0800080000000003F00408040803F00000
+C55A:000000081E0821082108210E21081E080008000003F80020002000D003080000
+C55B:000000081E0821082108210E21081E0800080000004003F8004000A003180000
+C55C:000000081E0821082108210E21081E080008000003F8000803F8000800080000
+C55D:000000081E0821082108210E21081E080008000003F8020003F8020003F80000
+C55E:000000081E0821082108210E21081E080008000000000FF8022002200FF80000
+C55F:000000081E0821082108210E21081E080008000000800FF803E0041003E00000
+C560:00000000001200121E1221124092409E409221121E1200120012001200120000
+C561:000000281E2821282128213821281E280028000007F800080008000800080000
+C562:000000281E2821282128213821281E280028000000003EF80208020802080000
+C563:000000281E2821282128213821281E280028000000003E100210022802C40000
+C564:000000281E2821282128213821281E280028002808000800080008000FF80000
+C565:000000281E2821282128213821281E2800280000000020F8201020303ECC0000
+C566:000000281E2821282128213821281E2800280000202021FC207020883E700000
+C567:000000281E2821282128213821281E280028000003F802000200020003F80000
+C568:000000281E2821282128213821281E280028000007F8000807F8040007F80000
+C569:000000281E2821282128213821281E28002800003EF802083E0820083E080000
+C56A:000000281E2821282128213821281E28002800003EF802883E8820883EF80000
+C56B:000000281E2821282128213821281E28002800003E8802883EF820883EF80000
+C56C:000000281E2821282128213821281E28002800001F0801081F0810141F620000
+C56D:000000281E2821282128213821281E28002800003EF802803EF820803EF80000
+C56E:000000281E2821282128213821281E28002800003EFC02483E4820483EFC0000
+C56F:000000281E2821282128213821281E28002800003E1002FE3E3820443E380000
+C570:000000281E2821282128213821281E280028000003F802080208020803F80000
+C571:000000281E2821282128213821281E28002800000208020803F8020803F80000
+C572:000000281E2821282128213821281E2800280000110811081F0811141F620000
+C573:000000281E2821282128213821281E2800280000000800080008003400C20000
+C574:000000281E2821282128213821281E28002800000048004800A8011406620000
+C575:000000281E2821282128213821281E2800280000000001F00208020801F00000
+C576:000000281E2821282128213821281E280028000003F80020002000D003080000
+C577:000000281E2821282128213821281E2800280000004003F8004000A003180000
+C578:000000281E2821282128213821281E280028000003F8000803F8000800080000
+C579:000000281E2821282128213821281E280028000003F8020003F8020003F80000
+C57A:000000281E2821282128213821281E280028000000000FF8022002200FF80000
+C57B:000000281E2821282128213821281E280028000000800FF803E0041003E00000
+C57C:00000000001000101E102110409E40904090211E1E1000100010001000100000
+C57D:000000081E082108210E2108210E1E080008000007F800080008000800080000
+C57E:000000081E082108210E2108210E1E080008000000003EF80208020802080000
+C57F:000000081E082108210E2108210E1E080008000000001F080108011401620000
+C580:000000081E082108210E2108210E1E080008000008000800080008000FF80000
+C581:000000081E082108210E2108210E1E0800080000000010F8101010301ECC0000
+C582:000000081E082108210E2108210E1E08000800000808087F081C08220F9C0000
+C583:000000081E082108210E2108210E1E080008000003F802000200020003F80000
+C584:000000081E082108210E2108210E1E080008000007F8000807F8040007F80000
+C585:000000081E082108210E2108210E1E08000800003EF802083E0820083E080000
+C586:000000081E082108210E2108210E1E08000800003EF802883E8820883EF80000
+C587:000000081E082108210E2108210E1E08000800003E8802883EF820883EF80000
+C588:000000081E082108210E2108210E1E08000800001F0801081F0810141F620000
+C589:000000081E082108210E2108210E1E08000800003EF802803EF820803EF80000
+C58A:000000081E082108210E2108210E1E08000800003EFC02483E4820483EFC0000
+C58B:000000081E082108210E2108210E1E08000800001F08017F1F1C10221F1C0000
+C58C:000000081E082108210E2108210E1E080008000003F802080208020803F80000
+C58D:000000081E082108210E2108210E1E08000800000208020803F8020803F80000
+C58E:000000081E082108210E2108210E1E0800080000110811081F0811141F620000
+C58F:000000081E082108210E2108210E1E0800080000001000100010006801840000
+C590:000000081E082108210E2108210E1E08000800000048004800A8011406620000
+C591:000000081E082108210E2108210E1E0800080000000003F00408040803F00000
+C592:000000081E082108210E2108210E1E080008000003F80020002000D003080000
+C593:000000081E082108210E2108210E1E0800080000004003F8004000A003180000
+C594:000000081E082108210E2108210E1E080008000003F8000803F8000800080000
+C595:000000081E082108210E2108210E1E080008000003F8020003F8020003F80000
+C596:000000081E082108210E2108210E1E080008000000000FF8022002200FF80000
+C597:000000081E082108210E2108210E1E080008000000800FF803E0041003E00000
+C598:00000000001200121E122112409E40924092211E1E1200120012001200120000
+C599:000000281E2821282138212821381E280028000007F800080008000800080000
+C59A:000000281E2821282138212821381E280028000000003EF80208020802080000
+C59B:000000281E2821282138212821381E280028000000003E100210022802C40000
+C59C:000000281E2821282138212821381E280028002808000800080008000FF80000
+C59D:000000281E2821282138212821381E2800280000000020F8201020303ECC0000
+C59E:000000281E2821282138212821381E2800280000202021FC207020883E700000
+C59F:000000281E2821282138212821381E280028000003F802000200020003F80000
+C5A0:000000281E2821282138212821381E280028000007F8000807F8040007F80000
+C5A1:000000281E2821282138212821381E28002800003EF802083E0820083E080000
+C5A2:000000281E2821282138212821381E28002800003EF802883E8820883EF80000
+C5A3:000000281E2821282138212821381E28002800003E8802883EF820883EF80000
+C5A4:000000281E2821282138212821381E28002800001F0801081F0810141F620000
+C5A5:000000281E2821282138212821381E28002800003EF802803EF820803EF80000
+C5A6:000000281E2821282138212821381E28002800003EFC02483E4820483EFC0000
+C5A7:000000281E2821282138212821381E28002800003E1002FE3E3820443E380000
+C5A8:000000281E2821282138212821381E280028000003F802080208020803F80000
+C5A9:000000281E2821282138212821381E28002800000208020803F8020803F80000
+C5AA:000000281E2821282138212821381E2800280000110811081F0811141F620000
+C5AB:000000281E2821282138212821381E2800280000000800080008003400C20000
+C5AC:000000281E2821282138212821381E28002800000048004800A8011406620000
+C5AD:000000281E2821282138212821381E2800280000000001F00208020801F00000
+C5AE:000000281E2821282138212821381E280028000003F80020002000D003080000
+C5AF:000000281E2821282138212821381E2800280000004003F8004000A003180000
+C5B0:000000281E2821282138212821381E280028000003F8000803F8000800080000
+C5B1:000000281E2821282138212821381E280028000003F8020003F8020003F80000
+C5B2:000000281E2821282138212821381E280028000000000FF8022002200FF80000
+C5B3:000000281E2821282138212821381E280028000000800FF803E0041003E00000
+C5B4:00000000000200021E0221024082409E408221021E0200020002000200020000
+C5B5:000000081E0821082108213821081E0800080000000007F80008000800080000
+C5B6:000000081E0821082108213821081E080008000000003EF80208020802080000
+C5B7:000000081E0821082108213821081E080008000000001F080108011401620000
+C5B8:000000081E0821082108213821081E080008000000001000100010001FF80000
+C5B9:000000081E0821082108213821081E0800080000000020F8201020303ECC0000
+C5BA:000000081E0821082108213821081E0800080000202021FC207020883E700000
+C5BB:000000081E0821082108213821081E080008000003F802000200020003F80000
+C5BC:000000081E0821082108213821081E080008000007F8000807F8040007F80000
+C5BD:000000081E0821082108213821081E08000800003EF802083E0820083E080000
+C5BE:000000081E0821082108213821081E08000800003EF802883E8820883EF80000
+C5BF:000000081E0821082108213821081E08000800003E8802883EF820883EF80000
+C5C0:000000081E0821082108213821081E08000800000F8800880F8808140FA20000
+C5C1:000000081E0821082108213821081E08000800003EF802803EF820803EF80000
+C5C2:000000081E0821082108213821081E08000800003EFC02483E4820483EFC0000
+C5C3:000000081E0821082108213821081E08000800003E1002FE3E3820443E380000
+C5C4:000000081E0821082108213821081E080008000003F802080208020803F80000
+C5C5:000000081E0821082108213821081E08000800000208020803F8020803F80000
+C5C6:000000081E0821082108213821081E0800080000210821083F0821143F620000
+C5C7:000000081E0821082108213821081E0800080000001000100010006801840000
+C5C8:000000081E0821082108213821081E08000800000048004800A8011406620000
+C5C9:000000081E0821082108213821081E0800080000000003F00408040803F00000
+C5CA:000000081E0821082108213821081E080008000003F80020002000D003080000
+C5CB:000000081E0821082108213821081E0800080000004003F8004000A003180000
+C5CC:000000081E0821082108213821081E080008000003F8000803F8000800080000
+C5CD:000000081E0821082108213821081E080008000003F8020003F8020003F80000
+C5CE:000000081E0821082108213821081E080008000000000FF8022002200FF80000
+C5CF:000000081E0821082108213821081E080008000000800FF803E0041003E00000
+C5D0:00000000000A000A1E0A210A408A40BA408A210A1E0A000A000A000A000A0000
+C5D1:000000281E282128212821E821281E280028000007F800080008000800080000
+C5D2:000000281E282128212821E821281E280028000000003EF80208020802080000
+C5D3:000000281E282128212821E821281E280028000000003E100210022802C40000
+C5D4:000000281E282128212821E821281E280028000008000800080008000FF80000
+C5D5:000000281E282128212821E821281E2800280000000020F8201020303ECC0000
+C5D6:000000281E282128212821E821281E2800280000202021FC207020883E700000
+C5D7:000000281E282128212821E821281E280028000003F802000200020003F80000
+C5D8:000000281E282128212821E821281E280028000007F8000807F8040007F80000
+C5D9:000000281E282128212821E821281E28002800003EF802083E0820083E080000
+C5DA:000000281E282128212821E821281E28002800003EF802883E8820883EF80000
+C5DB:000000281E282128212821E821281E28002800003E8802883EF820883EF80000
+C5DC:000000281E282128212821E821281E28002800001F0801081F0810141F620000
+C5DD:000000281E282128212821E821281E28002800003EF802803EF820803EF80000
+C5DE:000000281E282128212821E821281E28002800003EFC02483E4820483EFC0000
+C5DF:000000281E282128212821E821281E28002800003E1002FE3E3820443E380000
+C5E0:000000281E282128212821E821281E280028000003F802080208020803F80000
+C5E1:000000281E282128212821E821281E28002800000208020803F8020803F80000
+C5E2:000000281E282128212821E821281E2800280000110811081F0811141F620000
+C5E3:000000281E282128212821E821281E2800280000000800080008003400C20000
+C5E4:000000281E282128212821E821281E28002800000048004800A8011406620000
+C5E5:000000281E282128212821E821281E2800280000000001F00208020801F00000
+C5E6:000000281E282128212821E821281E280028000003F80020002000D003080000
+C5E7:000000281E282128212821E821281E2800280000004003F8004000A003180000
+C5E8:000000281E282128212821E821281E280028000003F8000803F8000800080000
+C5E9:000000281E282128212821E821281E280028000003F8020003F8020003F80000
+C5EA:000000281E282128212821E821281E280028000000000FF8022002200FF80000
+C5EB:000000281E282128212821E821281E280028000000800FF803E0041003E00000
+C5EC:00000000000200021E022102409E40824082211E1E0200020002000200020000
+C5ED:000000081E0821082138210821381E0800080000000007F80008000800080000
+C5EE:000000081E0821082138210821381E080008000000003EF80208020802080000
+C5EF:000000081E0821082138210821381E080008000000001F080108011401620000
+C5F0:000000081E0821082138210821381E080008000800001000100010001FF80000
+C5F1:000000081E0821082138210821381E0800080000000020F8201020303ECC0000
+C5F2:000000081E0821082138210821381E0800080000202021FC207020883E700000
+C5F3:000000081E0821082138210821381E080008000003F802000200020003F80000
+C5F4:000000081E0821082138210821381E080008000007F8000807F8040007F80000
+C5F5:000000081E0821082138210821381E08000800003EF802083E0820083E080000
+C5F6:000000081E0821082138210821381E08000800003EF802883E8820883EF80000
+C5F7:000000081E0821082138210821381E08000800003E8802883EF820883EF80000
+C5F8:000000081E0821082138210821381E08000800000F8800880F8808140FA20000
+C5F9:000000081E0821082138210821381E08000800003EF802803EF820803EF80000
+C5FA:000000081E0821082138210821381E08000800003EFC02483E4820483EFC0000
+C5FB:000000081E0821082138210821381E08000800003E1002FE3E3820443E380000
+C5FC:000000081E0821082138210821381E080008000003F802080208020803F80000
+C5FD:000000081E0821082138210821381E08000800000208020803F8020803F80000
+C5FE:000000081E0821082138210821381E0800080000210821083F0821143F620000
+C5FF:000000081E0821082138210821381E0800080000001000100010006801840000
+C600:000000081E0821082138210821381E08000800000048004800A8011406620000
+C601:000000081E0821082138210821381E0800080000000003F00408040803F00000
+C602:000000081E0821082138210821381E080008000003F80020002000D003080000
+C603:000000081E0821082138210821381E0800080000004003F8004000A003180000
+C604:000000081E0821082138210821381E080008000003F8000803F8000800080000
+C605:000000081E0821082138210821381E080008000003F8020003F8020003F80000
+C606:000000081E0821082138210821381E080008000000000FF8022002200FF80000
+C607:000000081E0821082138210821381E080008000000800FF803E0041003E00000
+C608:00000000000A000A1E0A210A40BA408A408A213A1E0A000A000A000A000A0000
+C609:000000281E28212821E8212821E81E280028000007F800080008000800080000
+C60A:000000281E28212821E8212821E81E280028000000003EF80208020802080000
+C60B:000000281E28212821E8212821E81E280028000000003E100210022802C40000
+C60C:000000281E28212821E8212821E81E280028002808000800080008000FF80000
+C60D:000000281E28212821E8212821E81E2800280000000020F8201020303ECC0000
+C60E:000000281E28212821E8212821E81E2800280000202021FC207020883E700000
+C60F:000000281E28212821E8212821E81E280028000003F802000200020003F80000
+C610:000000281E28212821E8212821E81E280028000007F8000807F8040007F80000
+C611:000000281E28212821E8212821E81E28002800003EF802083E0820083E080000
+C612:000000281E28212821E8212821E81E28002800003EF802883E8820883EF80000
+C613:000000281E28212821E8212821E81E28002800003E8802883EF820883EF80000
+C614:000000281E28212821E8212821E81E28002800001F0801081F0810141F620000
+C615:000000281E28212821E8212821E81E28002800003EF802803EF820803EF80000
+C616:000000281E28212821E8212821E81E28002800003EFC02483E4820483EFC0000
+C617:000000281E28212821E8212821E81E28002800003E1002FE3E3820443E380000
+C618:000000281E28212821E8212821E81E280028000003F802080208020803F80000
+C619:000000281E28212821E8212821E81E28002800000208020803F8020803F80000
+C61A:000000281E28212821E8212821E81E2800280000110811081F0811141F620000
+C61B:000000281E28212821E8212821E81E2800280000000800080008003400C20000
+C61C:000000281E28212821E8212821E81E28002800000048004800A8011406620000
+C61D:000000281E28212821E8212821E81E2800280000000001F00208020801F00000
+C61E:000000281E28212821E8212821E81E280028000003F80020002000D003080000
+C61F:000000281E28212821E8212821E81E2800280000004003F8004000A003180000
+C620:000000281E28212821E8212821E81E280028000003F8000803F8000800080000
+C621:000000281E28212821E8212821E81E280028000003F8020003F8020003F80000
+C622:000000281E28212821E8212821E81E280028000000000FF8022002200FF80000
+C623:000000281E28212821E8212821E81E280028000000800FF803E0041003E00000
+C624:000007C00820101010101010082007C0000000000100010001007FFC00000000
+C625:000007C008200820082007C0010001007FFC00001FF000100010001000100000
+C626:000007C008200820082007C0010001007FFC000000003EF80208020802080000
+C627:000007C008200820082007C0010001007FFC000000001E100210022802C40000
+C628:000007C008200820082007C0010001007FFC000000001000100010001FF00000
+C629:000007C008200820082007C0010001007FFC0000000020F8201020303ECC0000
+C62A:000007C008200820082007C0010001007FFC0000202021FC207020883E700000
+C62B:000007C008200820082007C0010001007FFC00001FF01000100010001FF00000
+C62C:000007C008200820082007C0010001007FFC00001FF000101FF010001FF00000
+C62D:000007C008200820082007C0010001007FFC00003EF802083E0820083E080000
+C62E:000007C008200820082007C0010001007FFC00003EF802883E8820883EF80000
+C62F:000007C008200820082007C0010001007FFC00003E8802883EF820883EF80000
+C630:000007C008200820082007C0010001007FFC00003E1002103E1020283EC40000
+C631:000007C008200820082007C0010001007FFC00003EF802803EF820803EF80000
+C632:000007C008200820082007C0010001007FFC00003EFC02483E4820483EFC0000
+C633:000007C008200820082007C0010001007FFC00003E2003FC3E7020883E700000
+C634:000007C008200820082007C0010001007FFC00001FF01010101010101FF00000
+C635:000007C008200820082007C0010001007FFC0000101010101FF010101FF00000
+C636:000007C008200820082007C0010001007FFC0000222022203E2022503E880000
+C637:000007C008200820082007C0010001007FFC000000000100010002800C400000
+C638:000007C008200820082007C0010001007FFC00000000024002400DA033100000
+C639:000007C008200820082007C0010001007FFC0000000007C00820082007C00000
+C63A:000007C008200820082007C0010001007FFC0000000007E00080014006200000
+C63B:000007C008200820082007C0010001007FFC0000008007E00080014006200000
+C63C:000007C008200820082007C0010001007FFC00001FF000101FF0001000100000
+C63D:000007C008200820082007C0010001007FFC00001FF010001FF010001FF00000
+C63E:000007C008200820082007C0010001007FFC000000001FF0044004401FF00000
+C63F:000007C008200820082007C0010001007FFC000001001FF007C0082007C00000
+C640:0000001000101F10209040504050405E20901F10041004107FD0001000100000
+C641:000000081F082088208E20881F0804087FE8000007F800080008000800080000
+C642:000000081F082088208E20881F0804087FE8000000003EF80208020802080000
+C643:000000081F082088208E20881F0804087FE8000000001F080108011401620000
+C644:000000081F082088208E20881F0804087FE8000008000800080008000FF80000
+C645:000000081F082088208E20881F0804087FE80000000010F8101010301ECC0000
+C646:000000081F082088208E20881F0804087FE800000808087F081C08220F9C0000
+C647:000000081F082088208E20881F0804087FE8000003F802000200020003F80000
+C648:000000081F082088208E20881F0804087FE8000007F8000807F8040007F80000
+C649:000000081F082088208E20881F0804087FE800003EF802083E0820083E080000
+C64A:000000081F082088208E20881F0804087FE800003EF802883E8820883EF80000
+C64B:000000081F082088208E20881F0804087FE800003E8802883EF820883EF80000
+C64C:000000081F082088208E20881F0804087FE800001F0801081F0810141F620000
+C64D:000000081F082088208E20881F0804087FE800003EF802803EF820803EF80000
+C64E:000000081F082088208E20881F0804087FE800003EFC02483E4820483EFC0000
+C64F:000000081F082088208E20881F0804087FE800001F08017F1F1C10221F1C0000
+C650:000000081F082088208E20881F0804087FE8000003F802080208020803F80000
+C651:000000081F082088208E20881F0804087FE800000208020803F8020803F80000
+C652:000000081F082088208E20881F0804087FE80000110811081F0811141F620000
+C653:000000081F082088208E20881F0804087FE80000001000100010006801840000
+C654:000000081F082088208E20881F0804087FE800000048004800A8011406620000
+C655:000000081F082088208E20881F0804087FE80000000003F00408040803F00000
+C656:000000081F082088208E20881F0804087FE8000003F80020002000D003080000
+C657:000000081F082088208E20881F0804087FE80000004003F8004000A003180000
+C658:000000081F082088208E20881F0804087FE8000003F8000803F8000800080000
+C659:000000081F082088208E20881F0804087FE8000003F8020003F8020003F80000
+C65A:000000081F082088208E20881F0804087FE8000000000FF8022002200FF80000
+C65B:000000081F082088208E20881F0804087FE8000000800FF803E0041003E00000
+C65C:0000001200121F12209240524052405E20921F12041204127FD2001200120000
+C65D:000000281F2820A820B820A81F2804287FA8000007F800080008000800080000
+C65E:000000281F2820A820B820A81F2804287FA8000000003EF80208020802080000
+C65F:000000281F2820A820B820A81F2804287FA8000000001F080108011401620000
+C660:000000281F2820A820B820A81F2804287FA8000008000800080008000FF80000
+C661:000000281F2820A820B820A81F2804287FA80000000010F8101010301ECC0000
+C662:000000281F2820A820B820A81F2804287FA800000808087F081C08220F9C0000
+C663:000000281F2820A820B820A81F2804287FA8000003F802000200020003F80000
+C664:000000281F2820A820B820A81F2804287FA8000007F8000807F8040007F80000
+C665:000000281F2820A820B820A81F2804287FA800003EF802083E0820083E080000
+C666:000000281F2820A820B820A81F2804287FA800003EF802883E8820883EF80000
+C667:000000281F2820A820B820A81F2804287FA800003E8802883EF820883EF80000
+C668:000000281F2820A820B820A81F2804287FA800001F0801081F0810141F620000
+C669:000000281F2820A820B820A81F2804287FA800003EF802803EF820803EF80000
+C66A:000000281F2820A820B820A81F2804287FA800003EFC02483E4820483EFC0000
+C66B:000000281F2820A820B820A81F2804287FA800001F08017F1F1C10221F1C0000
+C66C:000000281F2820A820B820A81F2804287FA8000003F802080208020803F80000
+C66D:000000281F2820A820B820A81F2804287FA800000208020803F8020803F80000
+C66E:000000281F2820A820B820A81F2804287FA80000110811081F0811141F620000
+C66F:000000281F2820A820B820A81F2804287FA80000001000100010006801840000
+C670:000000281F2820A820B820A81F2804287FA800000048004800A8011406620000
+C671:000000281F2820A820B820A81F2804287FA80000000003F00408040803F00000
+C672:000000281F2820A820B820A81F2804287FA8000003F80020002000D003080000
+C673:000000281F2820A820B820A81F2804287FA80000004003F8004000A003180000
+C674:000000281F2820A820B820A81F2804287FA8000003F8000803F8000800080000
+C675:000000281F2820A820B820A81F2804287FA8000003F8020003F8020003F80000
+C676:000000281F2820A820B820A81F2804287FA8000000000FF8022002200FF80000
+C677:000000281F2820A820B820A81F2804287FA8000000800FF803E0041003E00000
+C678:0000000800081F08208840484048404820881F08040804087FE8000800080000
+C679:000000081F082088208820881F0804087FE8000007F800080008000800080000
+C67A:000000081F082088208820881F0804087FE8000000003EF80208020802080000
+C67B:000000081F082088208820881F0804087FE8000000001F080108011401620000
+C67C:000000081F082088208820881F0804087FE8000008000800080008000FF80000
+C67D:000000081F082088208820881F0804087FE80000000010F8101010301ECC0000
+C67E:000000081F082088208820881F0804087FE800000808087F081C08220F9C0000
+C67F:000000081F082088208820881F0804087FE8000003F802000200020003F80000
+C680:000000081F082088208820881F0804087FE8000007F8000807F8040007F80000
+C681:000000081F082088208820881F0804087FE800003EF802083E0820083E080000
+C682:000000081F082088208820881F0804087FE800003EF802883E8820883EF80000
+C683:000000081F082088208820881F0804087FE800003E8802883EF820883EF80000
+C684:000000081F082088208820881F0804087FE800001F0801081F0810141F620000
+C685:000000081F082088208820881F0804087FE800003EF802803EF820803EF80000
+C686:000000081F082088208820881F0804087FE800003EFC02483E4820483EFC0000
+C687:000000081F082088208820881F0804087FE800001F08017F1F1C10221F1C0000
+C688:000000081F082088208820881F0804087FE8000003F802080208020803F80000
+C689:000000081F082088208820881F0804087FE800000208020803F8020803F80000
+C68A:000000081F082088208820881F0804087FE80000110811081F0811141F620000
+C68B:000000081F082088208820881F0804087FE80000001000100010006801840000
+C68C:000000081F082088208820881F0804087FE800000048004800A8011406620000
+C68D:000000081F082088208820881F0804087FE80000000003F00408040803F00000
+C68E:000000081F082088208820881F0804087FE8000003F80020002000D003080000
+C68F:000000081F082088208820881F0804087FE80000004003F8004000A003180000
+C690:000000081F082088208820881F0804087FE8000003F8000803F8000800080000
+C691:000000081F082088208820881F0804087FE8000003F8020003F8020003F80000
+C692:000000081F082088208820881F0804087FE8000000000FF8022002200FF80000
+C693:000000081F082088208820881F0804087FE8000000800FF803E0041003E00000
+C694:000007C00820101010101010082007C0000004400440044004407FFC00000000
+C695:000007C008200820082007C0044004407FFC00001FF000100010001000100000
+C696:000007C008200820082007C0044004407FFC000000003EF80208020802080000
+C697:000007C008200820082007C0044004407FFC000000001E100210022802C40000
+C698:000007C008200820082007C0044004407FFC000000001000100010001FF00000
+C699:000007C008200820082007C0044004407FFC0000000020F8201020303ECC0000
+C69A:000007C008200820082007C0044004407FFC0000202021FC207020883E700000
+C69B:000007C008200820082007C0044004407FFC00001FF01000100010001FF00000
+C69C:000007C008200820082007C0044004407FFC00001FF000101FF010001FF00000
+C69D:000007C008200820082007C0044004407FFC00003EF802083E0820083E080000
+C69E:000007C008200820082007C0044004407FFC00003EF802883E8820883EF80000
+C69F:000007C008200820082007C0044004407FFC00003E8802883EF820883EF80000
+C6A0:000007C008200820082007C0044004407FFC00003E1002103E1020283EC40000
+C6A1:000007C008200820082007C0044004407FFC00003EF802803EF820803EF80000
+C6A2:000007C008200820082007C0044004407FFC00003EFC02483E4820483EFC0000
+C6A3:000007C008200820082007C0044004407FFC00003E2003FC3E7020883E700000
+C6A4:000007C008200820082007C0044004407FFC00001FF01010101010101FF00000
+C6A5:000007C008200820082007C0044004407FFC0000101010101FF010101FF00000
+C6A6:000007C008200820082007C0044004407FFC0000222022203E2022503E880000
+C6A7:000007C008200820082007C0044004407FFC000000000100010002800C400000
+C6A8:000007C008200820082007C0044004407FFC00000000024002400DA033100000
+C6A9:000007C008200820082007C0044004407FFC0000000007C00820082007C00000
+C6AA:000007C008200820082007C0044004407FFC0000000007E00080014006200000
+C6AB:000007C008200820082007C0044004407FFC0000008007E00080014006200000
+C6AC:000007C008200820082007C0044004407FFC00001FF000101FF0001000100000
+C6AD:000007C008200820082007C0044004407FFC00001FF010001FF010001FF00000
+C6AE:000007C008200820082007C0044004407FFC000000001FF0044004401FF00000
+C6AF:000007C008200820082007C0044004407FFC000001001FF007C0082007C00000
+C6B0:0000000007C00820101010101010082007C000003FF801000100010001000000
+C6B1:000007C008200820082007C000007FFC010001001FF000100010001000100000
+C6B2:000007C008200820082007C000007FFC0100010000003EF80208020802080000
+C6B3:000007C008200820082007C000007FFC0100010000001E100210022802C40000
+C6B4:000007C008200820082007C0000000007FFC010001001100100010001FF00000
+C6B5:000007C008200820082007C000007FFC01000100000020F8201020303ECC0000
+C6B6:000007C008200820082007C000007FFC01000100202021FC207020883E700000
+C6B7:000007C008200820082007C000007FFC010001001FF01000100010001FF00000
+C6B8:000007C008200820082007C000007FFC010001001FF000101FF010001FF00000
+C6B9:000007C008200820082007C000007FFC010001003EF802083E0820083E080000
+C6BA:000007C008200820082007C000007FFC010001003EF802883E8820883EF80000
+C6BB:000007C008200820082007C000007FFC010001003E8802883EF820883EF80000
+C6BC:000007C008200820082007C000007FFC010001003E1002103E1020283EC40000
+C6BD:000007C008200820082007C000007FFC010001003EF802803EF820803EF80000
+C6BE:000007C008200820082007C000007FFC010001003EFC02483E4820483EFC0000
+C6BF:000007C008200820082007C000007FFC010001003E2003FC3E7020883E700000
+C6C0:000007C008200820082007C000007FFC010001001FF01010101010101FF00000
+C6C1:000007C008200820082007C000007FFC01000100101010101FF010101FF00000
+C6C2:000007C008200820082007C000007FFC01000100222022203E2022503E880000
+C6C3:000007C008200820082007C000007FFC0100010000000100010002800C400000
+C6C4:000007C008200820082007C000007FFC010001000000024002400DA033100000
+C6C5:000007C008200820082007C000007FFC01000100000007C00820082007C00000
+C6C6:000007C008200820082007C000007FFC01000100000007E00080014006200000
+C6C7:000007C008200820082007C000007FFC01000100008007E00080014006200000
+C6C8:000007C008200820082007C000007FFC010001001FF000101FF0001000100000
+C6C9:000007C008200820082007C000007FFC010001001FF010001FF010001FF00000
+C6CA:000007C008200820082007C000007FFC0100010000001FF0044004401FF00000
+C6CB:000007C008200820082007C000007FFC0100010001001FF007C0082007C00000
+C6CC:000000081F08208840484048404820881F0800087FE8040804F8040804080000
+C6CD:1F082088208820881F0800087FE8027802080000000007F80008000800080000
+C6CE:1F082088208820881F0800087FE802780208000000003EF80208020802080000
+C6CF:1F082088208820881F0800087FE802780208000000001F080108011401620000
+C6D0:1F082088208820881F08000800087FE80278020802081000100010001FF80000
+C6D1:1F082088208820881F0800087FE8027802080000000020F8201020303ECC0000
+C6D2:1F082088208820881F0800087FE8027802080000202021FC207020883E700000
+C6D3:1F082088208820881F0800087FE802780208000003F802000200020003F80000
+C6D4:1F082088208820881F0800087FE802780208000007F8000807F8040007F80000
+C6D5:1F082088208820881F0800087FE80278020800003EF802083E0820083E080000
+C6D6:1F082088208820881F0800087FE80278020800003EF802883E8820883EF80000
+C6D7:1F082088208820881F0800087FE80278020800003E8802883EF820883EF80000
+C6D8:1F082088208820881F0800087FE80278020800000F8800880F8808140FA20000
+C6D9:1F082088208820881F0800087FE80278020800003EF802803EF820803EF80000
+C6DA:1F082088208820881F0800087FE80278020800003EFC02483E4820483EFC0000
+C6DB:1F082088208820881F0800087FE80278020800003E1002FE3E3820443E380000
+C6DC:1F082088208820881F0800087FE802780208000003F802080208020803F80000
+C6DD:1F082088208820881F0800087FE80278020800000208020803F8020803F80000
+C6DE:1F082088208820881F0800087FE8027802080000210821083F0821143F620000
+C6DF:1F082088208820881F0800087FE8027802080000001000100010006801840000
+C6E0:1F082088208820881F0800087FE80278020800000048004800A8011406620000
+C6E1:1F082088208820881F0800087FE8027802080000000003F00408040803F00000
+C6E2:1F082088208820881F0800087FE802780208000003F80020002000D003080000
+C6E3:1F082088208820881F0800087FE8027802080000004003F8004000A003180000
+C6E4:1F082088208820881F0800087FE802780208000003F8000803F8000800080000
+C6E5:1F082088208820881F0800087FE802780208000003F8020003F8020003F80000
+C6E6:1F082088208820881F0800087FE802780208000000000FF8022002200FF80000
+C6E7:1F082088208820881F0800087FE802780208000000800FF803E0041003E00000
+C6E8:0000000A1F0A208A404A404A404A208A1F0A000A7FEA040A047A040A040A0000
+C6E9:1F2820A820A820A81F2800287FA805E804280000000007F80008000800080000
+C6EA:1F2820A820A820A81F2800287FA805E80428000000003EF80208020802080000
+C6EB:1F2820A820A820A81F2800287FA805E80428000000001F080108011401620000
+C6EC:1F2820A820A820A81F28002800287FA8042805E804281428100010001FF80000
+C6ED:1F2820A820A820A81F2800287FA805E804280000000020F8201020303ECC0000
+C6EE:1F2820A820A820A81F2800287FA805E804280000202021FC207020883E700000
+C6EF:1F2820A820A820A81F2800287FA805E80428000003F802000200020003F80000
+C6F0:1F2820A820A820A81F2800287FA805E80428000007F8000807F8040007F80000
+C6F1:1F2820A820A820A81F2800287FA805E8042800003EF802083E0820083E080000
+C6F2:1F2820A820A820A81F2800287FA805E8042800003EF802883E8820883EF80000
+C6F3:1F2820A820A820A81F2800287FA805E8042800003E8802883EF820883EF80000
+C6F4:1F2820A820A820A81F2800287FA805E8042800000F8800880F8808140FA20000
+C6F5:1F2820A820A820A81F2800287FA805E8042800003EF802803EF820803EF80000
+C6F6:1F2820A820A820A81F2800287FA805E8042800003EFC02483E4820483EFC0000
+C6F7:1F2820A820A820A81F2800287FA805E8042800003E1002FE3E3820443E380000
+C6F8:1F2820A820A820A81F2800287FA805E80428000003F802080208020803F80000
+C6F9:1F2820A820A820A81F2800287FA805E8042800000208020803F8020803F80000
+C6FA:1F2820A820A820A81F2800287FA805E804280000210821083F0821143F620000
+C6FB:1F2820A820A820A81F2800287FA805E804280000001000100010006801840000
+C6FC:1F2820A820A820A81F2800287FA805E8042800000048004800A8011406620000
+C6FD:1F2820A820A820A81F2800287FA805E804280000000003F00408040803F00000
+C6FE:1F2820A820A820A81F2800287FA805E80428000003F80020002000D003080000
+C6FF:1F2820A820A820A81F2800287FA805E804280000004003F8004000A003180000
+C700:1F2820A820A820A81F2800287FA805E80428000003F8000803F8000800080000
+C701:1F2820A820A820A81F2800287FA805E80428000003F8020003F8020003F80000
+C702:1F2820A820A820A81F2800287FA805E80428000000000FF8022002200FF80000
+C703:1F2820A820A820A81F2800287FA805E80428000000800FF803E0041003E00000
+C704:000000081F08208840484048404820881F0800087FE804080408040804080000
+C705:1F082088208820881F0800087FE8020802000000000007F80008000800080000
+C706:1F082088208820881F0800087FE802080200000000003EF80208020802080000
+C707:1F082088208820881F0800087FE802080200000000001F080108011401620000
+C708:1F082088208820881F08000800087FE80208020802081008100010001FF80000
+C709:1F082088208820881F0800087FE8020802000000000020F8201020303ECC0000
+C70A:1F082088208820881F0800087FE8020802000000202021FC207020883E700000
+C70B:1F082088208820881F0800087FE802080200000003F802000200020003F80000
+C70C:1F082088208820881F0800087FE802080200000007F8000807F8040007F80000
+C70D:1F082088208820881F0800087FE80208020000003EF802083E0820083E080000
+C70E:1F082088208820881F0800087FE80208020000003EF802883E8820883EF80000
+C70F:1F082088208820881F0800087FE80208020000003E8802883EF820883EF80000
+C710:1F082088208820881F0800087FE80208020000000F8800880F8808140FA20000
+C711:1F082088208820881F0800087FE80208020000003EF802803EF820803EF80000
+C712:1F082088208820881F0800087FE80208020000003EFC02483E4820483EFC0000
+C713:1F082088208820881F0800087FE80208020000003E1002FE3E3820443E380000
+C714:1F082088208820881F0800087FE802080200000003F802080208020803F80000
+C715:1F082088208820881F0800087FE80208020000000208020803F8020803F80000
+C716:1F082088208820881F0800087FE8020802000000210821083F0821143F620000
+C717:1F082088208820881F0800087FE8020802000000001000100010006801840000
+C718:1F082088208820881F0800087FE80208020000000048004800A8011406620000
+C719:1F082088208820881F0800087FE8020802000000000003F00408040803F00000
+C71A:1F082088208820881F0800087FE802080200000003F80020002000D003080000
+C71B:1F082088208820881F0800087FE8020802000000004003F8004000A003180000
+C71C:1F082088208820881F0800087FE802080200000003F8000803F8000800080000
+C71D:1F082088208820881F0800087FE802080200000003F8020003F8020003F80000
+C71E:1F082088208820881F0800087FE802080200000000000FF8022002200FF80000
+C71F:1F082088208820881F0800087FE802080200000000800FF803E0041003E00000
+C720:0000000007C00820101010101010082007C000007FFC04400440044004400000
+C721:000007C008200820082007C000007FFC044004401FF000100010001000100000
+C722:000007C008200820082007C000007FFC0440044000003EF80208020802080000
+C723:000007C008200820082007C000007FFC0440044000001E100210022802C40000
+C724:000007C008200820082007C0000000007FFC044004401440100010001FF00000
+C725:000007C008200820082007C000007FFC04400440000020F8201020303ECC0000
+C726:000007C008200820082007C000007FFC04400440202021FC207020883E700000
+C727:000007C008200820082007C000007FFC044004401FF01000100010001FF00000
+C728:000007C008200820082007C000007FFC044004401FF000101FF010001FF00000
+C729:000007C008200820082007C000007FFC044004403EF802083E0820083E080000
+C72A:000007C008200820082007C000007FFC044004403EF802883E8820883EF80000
+C72B:000007C008200820082007C000007FFC044004403E8802883EF820883EF80000
+C72C:000007C008200820082007C000007FFC044004403E1002103E1020283EC40000
+C72D:000007C008200820082007C000007FFC044004403EF802803EF820803EF80000
+C72E:000007C008200820082007C000007FFC044004403EFC02483E4820483EFC0000
+C72F:000007C008200820082007C000007FFC044004403E2003FC3E7020883E700000
+C730:000007C008200820082007C000007FFC044004401FF01010101010101FF00000
+C731:000007C008200820082007C000007FFC04400440101010101FF010101FF00000
+C732:000007C008200820082007C000007FFC04400440222022203E2022503E880000
+C733:000007C008200820082007C000007FFC0440044000000100010002800C400000
+C734:000007C008200820082007C000007FFC044004400000024002400DA033100000
+C735:000007C008200820082007C000007FFC04400440000007C00820082007C00000
+C736:000007C008200820082007C000007FFC04400440000007E00080014006200000
+C737:000007C008200820082007C000007FFC04400440008007E00080014006200000
+C738:000007C008200820082007C000007FFC044004401FF000101FF0001000100000
+C739:000007C008200820082007C000007FFC044004401FF010001FF010001FF00000
+C73A:000007C008200820082007C000007FFC0440044000001FF0044004401FF00000
+C73B:000007C008200820082007C000007FFC0440044001001FF007C0082007C00000
+C73C:000007C00820101010101010082007C00000000000007FFC0000000000000000
+C73D:000007C008200820082007C0000000007FFC00001FF000100010001000100000
+C73E:000007C008200820082007C0000000007FFC000000003EF80208020802080000
+C73F:000007C008200820082007C0000000007FFC000000001E100210022802C40000
+C740:000007C008200820082007C0000000007FFC000000001000100010001FF00000
+C741:000007C008200820082007C0000000007FFC0000000020F8201020303ECC0000
+C742:000007C008200820082007C0000000007FFC0000202021FC207020883E700000
+C743:000007C008200820082007C0000000007FFC00001FF01000100010001FF00000
+C744:000007C008200820082007C0000000007FFC00001FF000101FF010001FF00000
+C745:000007C008200820082007C0000000007FFC00003EF802083E0820083E080000
+C746:000007C008200820082007C0000000007FFC00003EF802883E8820883EF80000
+C747:000007C008200820082007C0000000007FFC00003E8802883EF820883EF80000
+C748:000007C008200820082007C0000000007FFC00003E1002103E1020283EC40000
+C749:000007C008200820082007C0000000007FFC00003EF802803EF820803EF80000
+C74A:000007C008200820082007C0000000007FFC00003EFC02483E4820483EFC0000
+C74B:000007C008200820082007C0000000007FFC00003E2003FC3E7020883E700000
+C74C:000007C008200820082007C0000000007FFC00001FF01010101010101FF00000
+C74D:000007C008200820082007C0000000007FFC0000101010101FF010101FF00000
+C74E:000007C008200820082007C0000000007FFC0000222022203E2022503E880000
+C74F:000007C008200820082007C0000000007FFC000000000100010002800C400000
+C750:000007C008200820082007C0000000007FFC00000000024002400DA033100000
+C751:000007C008200820082007C0000000007FFC0000000007C00820082007C00000
+C752:000007C008200820082007C0000000007FFC0000000007E00080014006200000
+C753:000007C008200820082007C0000000007FFC0000008007E00080014006200000
+C754:000007C008200820082007C0000000007FFC00001FF000101FF0001000100000
+C755:000007C008200820082007C0000000007FFC00001FF010001FF010001FF00000
+C756:000007C008200820082007C0000000007FFC000000001FF0044004401FF00000
+C757:000007C008200820082007C0000000007FFC000001001FF007C0082007C00000
+C758:0000000800081F08208840484048404820881F0800087FE80008000800080000
+C759:000000081F082088208820881F0800087FE8000007F800080008000800080000
+C75A:000000081F082088208820881F0800087FE8000000003EF80208020802080000
+C75B:000000081F082088208820881F0800087FE8000000001F080108011401620000
+C75C:000000081F082088208820881F0800087FE8000008000800080008000FF80000
+C75D:000000081F082088208820881F0800087FE80000000010F8101010301ECC0000
+C75E:000000081F082088208820881F0800087FE800000808087F081C08220F9C0000
+C75F:000000081F082088208820881F0800087FE8000003F802000200020003F80000
+C760:000000081F082088208820881F0800087FE8000007F8000807F8040007F80000
+C761:000000081F082088208820881F0800087FE800003EF802083E0820083E080000
+C762:000000081F082088208820881F0800087FE800003EF802883E8820883EF80000
+C763:000000081F082088208820881F0800087FE800003E8802883EF820883EF80000
+C764:000000081F082088208820881F0800087FE800001F0801081F0810141F620000
+C765:000000081F082088208820881F0800087FE800003EF802803EF820803EF80000
+C766:000000081F082088208820881F0800087FE800003EFC02483E4820483EFC0000
+C767:000000081F082088208820881F0800087FE800001F08017F1F1C10221F1C0000
+C768:000000081F082088208820881F0800087FE8000003F802080208020803F80000
+C769:000000081F082088208820881F0800087FE800000208020803F8020803F80000
+C76A:000000081F082088208820881F0800087FE80000110811081F0811141F620000
+C76B:000000081F082088208820881F0800087FE80000001000100010006801840000
+C76C:000000081F082088208820881F0800087FE800000048004800A8011406620000
+C76D:000000081F082088208820881F0800087FE80000000003F00408040803F00000
+C76E:000000081F082088208820881F0800087FE8000003F80020002000D003080000
+C76F:000000081F082088208820881F0800087FE80000004003F8004000A003180000
+C770:000000081F082088208820881F0800087FE8000003F8000803F8000800080000
+C771:000000081F082088208820881F0800087FE8000003F8020003F8020003F80000
+C772:000000081F082088208820881F0800087FE8000000000FF8022002200FF80000
+C773:000000081F082088208820881F0800087FE8000000800FF803E0041003E00000
+C774:00000000000800081E08210840884088408821081E0800080008000800080000
+C775:000000081E0821082108210821081E0800080000000007F80008000800080000
+C776:000000081E0821082108210821081E080008000000003EF80208020802080000
+C777:000000081E0821082108210821081E080008000000001F080108011401620000
+C778:000000081E0821082108210821081E080008000800001000100010001FF80000
+C779:000000081E0821082108210821081E0800080000000020F8201020303ECC0000
+C77A:000000081E0821082108210821081E0800080000202021FC207020883E700000
+C77B:000000081E0821082108210821081E080008000003F802000200020003F80000
+C77C:000000081E0821082108210821081E080008000007F8000807F8040007F80000
+C77D:000000081E0821082108210821081E08000800003EF802083E0820083E080000
+C77E:000000081E0821082108210821081E08000800003EF802883E8820883EF80000
+C77F:000000081E0821082108210821081E08000800003E8802883EF820883EF80000
+C780:000000081E0821082108210821081E08000800000F8800880F8808140FA20000
+C781:000000081E0821082108210821081E08000800003EF802803EF820803EF80000
+C782:000000081E0821082108210821081E08000800003EFC02483E4820483EFC0000
+C783:000000081E0821082108210821081E08000800003E1002FE3E3820443E380000
+C784:000000081E0821082108210821081E080008000003F802080208020803F80000
+C785:000000081E0821082108210821081E08000800000208020803F8020803F80000
+C786:000000081E0821082108210821081E0800080000210821083F0821143F620000
+C787:000000081E0821082108210821081E0800080000001000100010006801840000
+C788:000000081E0821082108210821081E08000800000048004800A8011406620000
+C789:000000081E0821082108210821081E0800080000000003F00408040803F00000
+C78A:000000081E0821082108210821081E080008000003F80020002000D003080000
+C78B:000000081E0821082108210821081E0800080000004003F8004000A003180000
+C78C:000000081E0821082108210821081E080008000003F8000803F8000800080000
+C78D:000000081E0821082108210821081E080008000003F8020003F8020003F80000
+C78E:000000081E0821082108210821081E080008000000000FF8022002200FF80000
+C78F:000000081E0821082108210821081E080008000000800FF803E0041003E00000
+C790:00000000001000103F9001100110021E06100910309000100010001000100000
+C791:0000000800087E080408040E1A0861080008000007F800080008000800080000
+C792:0000000800087E080408040E1A0861080008000000003EF80208020802080000
+C793:0000000800087E080408040E1A0861080008000000001F080108011401620000
+C794:0000000800087E080408040E1A0861080008000808000800080008000FF80000
+C795:0000000800087E080408040E1A08610800080000000010F8101010301ECC0000
+C796:0000000800087E080408040E1A086108000800000808087F081C08220F9C0000
+C797:0000000800087E080408040E1A0861080008000003F802000200020003F80000
+C798:0000000800087E080408040E1A0861080008000007F8000807F8040007F80000
+C799:0000000800087E080408040E1A086108000800003EF802083E0820083E080000
+C79A:0000000800087E080408040E1A086108000800003EF802883E8820883EF80000
+C79B:0000000800087E080408040E1A086108000800003E8802883EF820883EF80000
+C79C:0000000800087E080408040E1A086108000800001F0801081F0810141F620000
+C79D:0000000800087E080408040E1A086108000800003EF802803EF820803EF80000
+C79E:0000000800087E080408040E1A086108000800003EFC02483E4820483EFC0000
+C79F:0000000800087E080408040E1A086108000800001F08017F1F1C10221F1C0000
+C7A0:0000000800087E080408040E1A0861080008000003F802080208020803F80000
+C7A1:0000000800087E080408040E1A086108000800000208020803F8020803F80000
+C7A2:0000000800087E080408040E1A08610800080000110811081F0811141F620000
+C7A3:0000000800087E080408040E1A08610800080000001000100010006801840000
+C7A4:0000000800087E080408040E1A086108000800000048004800A8011406620000
+C7A5:0000000800087E080408040E1A08610800080000000003F00408040803F00000
+C7A6:0000000800087E080408040E1A0861080008000003F80020002000D003080000
+C7A7:0000000800087E080408040E1A08610800080000004003F8004000A003180000
+C7A8:0000000800087E080408040E1A0861080008000003F8000803F8000800080000
+C7A9:0000000800087E080408040E1A0861080008000003F8020003F8020003F80000
+C7AA:0000000800087E080408040E1A0861080008000000000FF8022002200FF80000
+C7AB:0000000800087E080408040E1A0861080008000000800FF803E0041003E00000
+C7AC:00000000001200123F9201120112021E06120912309200120012001200120000
+C7AD:0000002800287E28042804381A2861280028000007F800080008000800080000
+C7AE:0000002800287E28042804381A2861280028000000003EF80208020802080000
+C7AF:0000002800287E28042804381A2861280028000000003E100210022802C40000
+C7B0:0000002800287E28042804381A2861280028002808000800080008000FF80000
+C7B1:0000002800287E28042804381A28612800280000000020F8201020303ECC0000
+C7B2:0000002800287E28042804381A28612800280000202021FC207020883E700000
+C7B3:0000002800287E28042804381A2861280028000003F802000200020003F80000
+C7B4:0000002800287E28042804381A2861280028000007F8000807F8040007F80000
+C7B5:0000002800287E28042804381A286128002800003EF802083E0820083E080000
+C7B6:0000002800287E28042804381A286128002800003EF802883E8820883EF80000
+C7B7:0000002800287E28042804381A286128002800003E8802883EF820883EF80000
+C7B8:0000002800287E28042804381A286128002800001F0801081F0810141F620000
+C7B9:0000002800287E28042804381A286128002800003EF802803EF820803EF80000
+C7BA:0000002800287E28042804381A286128002800003EFC02483E4820483EFC0000
+C7BB:0000002800287E28042804381A286128002800003E1002FE3E3820443E380000
+C7BC:0000002800287E28042804381A2861280028000003F802080208020803F80000
+C7BD:0000002800287E28042804381A286128002800000208020803F8020803F80000
+C7BE:0000002800287E28042804381A28612800280000110811081F0811141F620000
+C7BF:0000002800287E28042804381A28612800280000000800080008003400C20000
+C7C0:0000002800287E28042804381A286128002800000048004800A8011406620000
+C7C1:0000002800287E28042804381A28612800280000000001F00208020801F00000
+C7C2:0000002800287E28042804381A2861280028000003F80020002000D003080000
+C7C3:0000002800287E28042804381A28612800280000004003F8004000A003180000
+C7C4:0000002800287E28042804381A2861280028000003F8000803F8000800080000
+C7C5:0000002800287E28042804381A2861280028000003F8020003F8020003F80000
+C7C6:0000002800287E28042804381A2861280028000000000FF8022002200FF80000
+C7C7:0000002800287E28042804381A2861280028000000800FF803E0041003E00000
+C7C8:00000000001000103F900110011E02100610091E309000100010001000100000
+C7C9:0000000800087E08040E04081A0E61080008000007F800080008000800080000
+C7CA:0000000800087E08040E04081A0E61080008000000003EF80208020802080000
+C7CB:0000000800087E08040E04081A0E61080008000000001F080108011401620000
+C7CC:0000000800087E08040E04081A0E61080008000008000800080008000FF80000
+C7CD:0000000800087E08040E04081A0E610800080000000010F8101010301ECC0000
+C7CE:0000000800087E08040E04081A0E6108000800000808087F081C08220F9C0000
+C7CF:0000000800087E08040E04081A0E61080008000003F802000200020003F80000
+C7D0:0000000800087E08040E04081A0E61080008000007F8000807F8040007F80000
+C7D1:0000000800087E08040E04081A0E6108000800003EF802083E0820083E080000
+C7D2:0000000800087E08040E04081A0E6108000800003EF802883E8820883EF80000
+C7D3:0000000800087E08040E04081A0E6108000800003E8802883EF820883EF80000
+C7D4:0000000800087E08040E04081A0E6108000800001F0801081F0810141F620000
+C7D5:0000000800087E08040E04081A0E6108000800003EF802803EF820803EF80000
+C7D6:0000000800087E08040E04081A0E6108000800003EFC02483E4820483EFC0000
+C7D7:0000000800087E08040E04081A0E6108000800001F08017F1F1C10221F1C0000
+C7D8:0000000800087E08040E04081A0E61080008000003F802080208020803F80000
+C7D9:0000000800087E08040E04081A0E6108000800000208020803F8020803F80000
+C7DA:0000000800087E08040E04081A0E610800080000110811081F0811141F620000
+C7DB:0000000800087E08040E04081A0E610800080000001000100010006801840000
+C7DC:0000000800087E08040E04081A0E6108000800000048004800A8011406620000
+C7DD:0000000800087E08040E04081A0E610800080000000003F00408040803F00000
+C7DE:0000000800087E08040E04081A0E61080008000003F80020002000D003080000
+C7DF:0000000800087E08040E04081A0E610800080000004003F8004000A003180000
+C7E0:0000000800087E08040E04081A0E61080008000003F8000803F8000800080000
+C7E1:0000000800087E08040E04081A0E61080008000003F8020003F8020003F80000
+C7E2:0000000800087E08040E04081A0E61080008000000000FF8022002200FF80000
+C7E3:0000000800087E08040E04081A0E61080008000000800FF803E0041003E00000
+C7E4:00000000001200123F920112011E02120612091E309200120012001200120000
+C7E5:0000002800287E28043804281A3861280028000007F800080008000800080000
+C7E6:0000002800287E28043804281A3861280028000000003EF80208020802080000
+C7E7:0000002800287E28043804281A3861280028000000003E100210022802C40000
+C7E8:0000002800287E28043804281A3861280028002808000800080008000FF80000
+C7E9:0000002800287E28043804281A38612800280000000020F8201020303ECC0000
+C7EA:0000002800287E28043804281A38612800280000202021FC207020883E700000
+C7EB:0000002800287E28043804281A3861280028000003F802000200020003F80000
+C7EC:0000002800287E28043804281A3861280028000007F8000807F8040007F80000
+C7ED:0000002800287E28043804281A386128002800003EF802083E0820083E080000
+C7EE:0000002800287E28043804281A386128002800003EF802883E8820883EF80000
+C7EF:0000002800287E28043804281A386128002800003E8802883EF820883EF80000
+C7F0:0000002800287E28043804281A386128002800001F0801081F0810141F620000
+C7F1:0000002800287E28043804281A386128002800003EF802803EF820803EF80000
+C7F2:0000002800287E28043804281A386128002800003EFC02483E4820483EFC0000
+C7F3:0000002800287E28043804281A386128002800003E1002FE3E3820443E380000
+C7F4:0000002800287E28043804281A3861280028000003F802080208020803F80000
+C7F5:0000002800287E28043804281A386128002800000208020803F8020803F80000
+C7F6:0000002800287E28043804281A38612800280000110811081F0811141F620000
+C7F7:0000002800287E28043804281A38612800280000000800080008003400C20000
+C7F8:0000002800287E28043804281A386128002800000048004800A8011406620000
+C7F9:0000002800287E28043804281A38612800280000000001F00208020801F00000
+C7FA:0000002800287E28043804281A3861280028000003F80020002000D003080000
+C7FB:0000002800287E28043804281A38612800280000004003F8004000A003180000
+C7FC:0000002800287E28043804281A3861280028000003F8000803F8000800080000
+C7FD:0000002800287E28043804281A3861280028000003F8020003F8020003F80000
+C7FE:0000002800287E28043804281A3861280028000000000FF8022002200FF80000
+C7FF:0000002800287E28043804281A3861280028000000800FF803E0041003E00000
+C800:00000000000200023F8201020102021E06020902308200020002000200020000
+C801:0000000800087E08040804381A08610800080000000007F80008000800080000
+C802:0000000800087E08040804381A0861080008000000003EF80208020802080000
+C803:0000000800087E08040804381A0861080008000000001F080108011401620000
+C804:0000000800087E08040804381A0861080008000000001000100010001FF80000
+C805:0000000800087E08040804381A08610800080000000020F8201020303ECC0000
+C806:0000000800087E08040804381A08610800080000202021FC207020883E700000
+C807:0000000800087E08040804381A0861080008000003F802000200020003F80000
+C808:0000000800087E08040804381A0861080008000007F8000807F8040007F80000
+C809:0000000800087E08040804381A086108000800003EF802083E0820083E080000
+C80A:0000000800087E08040804381A086108000800003EF802883E8820883EF80000
+C80B:0000000800087E08040804381A086108000800003E8802883EF820883EF80000
+C80C:0000000800087E08040804381A086108000800000F8800880F8808140FA20000
+C80D:0000000800087E08040804381A086108000800003EF802803EF820803EF80000
+C80E:0000000800087E08040804381A086108000800003EFC02483E4820483EFC0000
+C80F:0000000800087E08040804381A086108000800003E1002FE3E3820443E380000
+C810:0000000800087E08040804381A0861080008000003F802080208020803F80000
+C811:0000000800087E08040804381A086108000800000208020803F8020803F80000
+C812:0000000800087E08040804381A08610800080000210821083F0821143F620000
+C813:0000000800087E08040804381A08610800080000001000100010006801840000
+C814:0000000800087E08040804381A086108000800000048004800A8011406620000
+C815:0000000800087E08040804381A08610800080000000003F00408040803F00000
+C816:0000000800087E08040804381A0861080008000003F80020002000D003080000
+C817:0000000800087E08040804381A08610800080000004003F8004000A003180000
+C818:0000000800087E08040804381A0861080008000003F8000803F8000800080000
+C819:0000000800087E08040804381A0861080008000003F8020003F8020003F80000
+C81A:0000000800087E08040804381A0861080008000000000FF8022002200FF80000
+C81B:0000000800087E08040804381A0861080008000000800FF803E0041003E00000
+C81C:00000000000A000A3F8A010A010A023A060A090A308A000A000A000A000A0000
+C81D:0000002800287E28042804E81A2861280028000007F800080008000800080000
+C81E:0000002800287E28042804E81A2861280028000000003EF80208020802080000
+C81F:0000002800287E28042804E81A2861280028000000003E100210022802C40000
+C820:0000002800287E28042804E81A2861280028000008000800080008000FF80000
+C821:0000002800287E28042804E81A28612800280000000020F8201020303ECC0000
+C822:0000002800287E28042804E81A28612800280000202021FC207020883E700000
+C823:0000002800287E28042804E81A2861280028000003F802000200020003F80000
+C824:0000002800287E28042804E81A2861280028000007F8000807F8040007F80000
+C825:0000002800287E28042804E81A286128002800003EF802083E0820083E080000
+C826:0000002800287E28042804E81A286128002800003EF802883E8820883EF80000
+C827:0000002800287E28042804E81A286128002800003E8802883EF820883EF80000
+C828:0000002800287E28042804E81A286128002800001F0801081F0810141F620000
+C829:0000002800287E28042804E81A286128002800003EF802803EF820803EF80000
+C82A:0000002800287E28042804E81A286128002800003EFC02483E4820483EFC0000
+C82B:0000002800287E28042804E81A286128002800003E1002FE3E3820443E380000
+C82C:0000002800287E28042804E81A2861280028000003F802080208020803F80000
+C82D:0000002800287E28042804E81A286128002800000208020803F8020803F80000
+C82E:0000002800287E28042804E81A28612800280000110811081F0811141F620000
+C82F:0000002800287E28042804E81A28612800280000000800080008003400C20000
+C830:0000002800287E28042804E81A286128002800000048004800A8011406620000
+C831:0000002800287E28042804E81A28612800280000000001F00208020801F00000
+C832:0000002800287E28042804E81A2861280028000003F80020002000D003080000
+C833:0000002800287E28042804E81A28612800280000004003F8004000A003180000
+C834:0000002800287E28042804E81A2861280028000003F8000803F8000800080000
+C835:0000002800287E28042804E81A2861280028000003F8020003F8020003F80000
+C836:0000002800287E28042804E81A2861280028000000000FF8022002200FF80000
+C837:0000002800287E28042804E81A2861280028000000800FF803E0041003E00000
+C838:00000000000200023F820102011E02020602091E308200020002000200020000
+C839:0000000800087E08043804081A38610800080000000007F80008000800080000
+C83A:0000000800087E08043804081A3861080008000000003EF80208020802080000
+C83B:0000000800087E08043804081A3861080008000000001F080108011401620000
+C83C:0000000800087E08043804081A3861080008000800001000100010001FF80000
+C83D:0000000800087E08043804081A38610800080000000020F8201020303ECC0000
+C83E:0000000800087E08043804081A38610800080000202021FC207020883E700000
+C83F:0000000800087E08043804081A3861080008000003F802000200020003F80000
+C840:0000000800087E08043804081A3861080008000007F8000807F8040007F80000
+C841:0000000800087E08043804081A386108000800003EF802083E0820083E080000
+C842:0000000800087E08043804081A386108000800003EF802883E8820883EF80000
+C843:0000000800087E08043804081A386108000800003E8802883EF820883EF80000
+C844:0000000800087E08043804081A386108000800000F8800880F8808140FA20000
+C845:0000000800087E08043804081A386108000800003EF802803EF820803EF80000
+C846:0000000800087E08043804081A386108000800003EFC02483E4820483EFC0000
+C847:0000000800087E08043804081A386108000800003E1002FE3E3820443E380000
+C848:0000000800087E08043804081A3861080008000003F802080208020803F80000
+C849:0000000800087E08043804081A386108000800000208020803F8020803F80000
+C84A:0000000800087E08043804081A38610800080000210821083F0821143F620000
+C84B:0000000800087E08043804081A38610800080000001000100010006801840000
+C84C:0000000800087E08043804081A386108000800000048004800A8011406620000
+C84D:0000000800087E08043804081A38610800080000000003F00408040803F00000
+C84E:0000000800087E08043804081A3861080008000003F80020002000D003080000
+C84F:0000000800087E08043804081A38610800080000004003F8004000A003180000
+C850:0000000800087E08043804081A3861080008000003F8000803F8000800080000
+C851:0000000800087E08043804081A3861080008000003F8020003F8020003F80000
+C852:0000000800087E08043804081A3861080008000000000FF8022002200FF80000
+C853:0000000800087E08043804081A3861080008000000800FF803E0041003E00000
+C854:00000000000A000A3F8A010A013A020A060A093A308A000A000A000A000A0000
+C855:0000002800287E2804E804281AE861280028000007F800080008000800080000
+C856:0000002800287E2804E804281AE861280028000000003EF80208020802080000
+C857:0000002800287E2804E804281AE861280028000000003E100210022802C40000
+C858:0000002800287E2804E804281AE861280028002808000800080008000FF80000
+C859:0000002800287E2804E804281AE8612800280000000020F8201020303ECC0000
+C85A:0000002800287E2804E804281AE8612800280000202021FC207020883E700000
+C85B:0000002800287E2804E804281AE861280028000003F802000200020003F80000
+C85C:0000002800287E2804E804281AE861280028000007F8000807F8040007F80000
+C85D:0000002800287E2804E804281AE86128002800003EF802083E0820083E080000
+C85E:0000002800287E2804E804281AE86128002800003EF802883E8820883EF80000
+C85F:0000002800287E2804E804281AE86128002800003E8802883EF820883EF80000
+C860:0000002800287E2804E804281AE86128002800001F0801081F0810141F620000
+C861:0000002800287E2804E804281AE86128002800003EF802803EF820803EF80000
+C862:0000002800287E2804E804281AE86128002800003EFC02483E4820483EFC0000
+C863:0000002800287E2804E804281AE86128002800003E1002FE3E3820443E380000
+C864:0000002800287E2804E804281AE861280028000003F802080208020803F80000
+C865:0000002800287E2804E804281AE86128002800000208020803F8020803F80000
+C866:0000002800287E2804E804281AE8612800280000110811081F0811141F620000
+C867:0000002800287E2804E804281AE8612800280000000800080008003400C20000
+C868:0000002800287E2804E804281AE86128002800000048004800A8011406620000
+C869:0000002800287E2804E804281AE8612800280000000001F00208020801F00000
+C86A:0000002800287E2804E804281AE861280028000003F80020002000D003080000
+C86B:0000002800287E2804E804281AE8612800280000004003F8004000A003180000
+C86C:0000002800287E2804E804281AE861280028000003F8000803F8000800080000
+C86D:0000002800287E2804E804281AE861280028000003F8020003F8020003F80000
+C86E:0000002800287E2804E804281AE861280028000000000FF8022002200FF80000
+C86F:0000002800287E2804E804281AE861280028000000800FF803E0041003E00000
+C870:000000000FE0004000400080018002400C2000000100010001007FFC00000000
+C871:00000FC0008003400C200000010001007FFC00001FF000100010001000100000
+C872:00000FC0008003400C200000010001007FFC000000003EF80208020802080000
+C873:00000FC0008003400C200000010001007FFC000000001E100210022802C40000
+C874:00000FC0008003400C200000010001007FFC000000001000100010001FF00000
+C875:00000FC0008003400C200000010001007FFC0000000020F8201020303ECC0000
+C876:00000FC0008003400C200000010001007FFC0000202021FC207020883E700000
+C877:00000FC0008003400C200000010001007FFC00001FF01000100010001FF00000
+C878:00000FC0008003400C200000010001007FFC00001FF000101FF010001FF00000
+C879:00000FC0008003400C200000010001007FFC00003EF802083E0820083E080000
+C87A:00000FC0008003400C200000010001007FFC00003EF802883E8820883EF80000
+C87B:00000FC0008003400C200000010001007FFC00003E8802883EF820883EF80000
+C87C:00000FC0008003400C200000010001007FFC00003E1002103E1020283EC40000
+C87D:00000FC0008003400C200000010001007FFC00003EF802803EF820803EF80000
+C87E:00000FC0008003400C200000010001007FFC00003EFC02483E4820483EFC0000
+C87F:00000FC0008003400C200000010001007FFC00003E2003FC3E7020883E700000
+C880:00000FC0008003400C200000010001007FFC00001FF01010101010101FF00000
+C881:00000FC0008003400C200000010001007FFC0000101010101FF010101FF00000
+C882:00000FC0008003400C200000010001007FFC0000222022203E2022503E880000
+C883:00000FC0008003400C200000010001007FFC000000000100010002800C400000
+C884:00000FC0008003400C200000010001007FFC00000000024002400DA033100000
+C885:00000FC0008003400C200000010001007FFC0000000007C00820082007C00000
+C886:00000FC0008003400C200000010001007FFC0000000007E00080014006200000
+C887:00000FC0008003400C200000010001007FFC0000008007E00080014006200000
+C888:00000FC0008003400C200000010001007FFC00001FF000101FF0001000100000
+C889:00000FC0008003400C200000010001007FFC00001FF010001FF010001FF00000
+C88A:00000FC0008003400C200000010001007FFC000000001FF0044004401FF00000
+C88B:00000FC0008003400C200000010001007FFC000001001FF007C0082007C00000
+C88C:0000001000103F90011001100210061E09103090041004107FD0001000100000
+C88D:000000083F0802080D0E3088040804087FE8000007F800080008000800080000
+C88E:000000083F0802080D0E3088040804087FE8000000003EF80208020802080000
+C88F:000000083F0802080D0E3088040804087FE8000000001F080108011401620000
+C890:000000083F0802080D0E3088040804087FE8000008000800080008000FF80000
+C891:000000083F0802080D0E3088040804087FE80000000010F8101010301ECC0000
+C892:000000083F0802080D0E3088040804087FE800000808087F081C08220F9C0000
+C893:000000083F0802080D0E3088040804087FE8000003F802000200020003F80000
+C894:000000083F0802080D0E3088040804087FE8000007F8000807F8040007F80000
+C895:000000083F0802080D0E3088040804087FE800003EF802083E0820083E080000
+C896:000000083F0802080D0E3088040804087FE800003EF802883E8820883EF80000
+C897:000000083F0802080D0E3088040804087FE800003E8802883EF820883EF80000
+C898:000000083F0802080D0E3088040804087FE800001F0801081F0810141F620000
+C899:000000083F0802080D0E3088040804087FE800003EF802803EF820803EF80000
+C89A:000000083F0802080D0E3088040804087FE800003EFC02483E4820483EFC0000
+C89B:000000083F0802080D0E3088040804087FE800001F08017F1F1C10221F1C0000
+C89C:000000083F0802080D0E3088040804087FE8000003F802080208020803F80000
+C89D:000000083F0802080D0E3088040804087FE800000208020803F8020803F80000
+C89E:000000083F0802080D0E3088040804087FE80000110811081F0811141F620000
+C89F:000000083F0802080D0E3088040804087FE80000001000100010006801840000
+C8A0:000000083F0802080D0E3088040804087FE800000048004800A8011406620000
+C8A1:000000083F0802080D0E3088040804087FE80000000003F00408040803F00000
+C8A2:000000083F0802080D0E3088040804087FE8000003F80020002000D003080000
+C8A3:000000083F0802080D0E3088040804087FE80000004003F8004000A003180000
+C8A4:000000083F0802080D0E3088040804087FE8000003F8000803F8000800080000
+C8A5:000000083F0802080D0E3088040804087FE8000003F8020003F8020003F80000
+C8A6:000000083F0802080D0E3088040804087FE8000000000FF8022002200FF80000
+C8A7:000000083F0802080D0E3088040804087FE8000000800FF803E0041003E00000
+C8A8:0000001200123F92011201120212061E09123092041204127FD2001200120000
+C8A9:000000283F2802280D3830A8042804287FA8000007F800080008000800080000
+C8AA:000000283F2802280D3830A8042804287FA8000000003EF80208020802080000
+C8AB:000000283F2802280D3830A8042804287FA8000000001F080108011401620000
+C8AC:000000283F2802280D3830A8042804287FA8000008000800080008000FF80000
+C8AD:000000283F2802280D3830A8042804287FA80000000010F8101010301ECC0000
+C8AE:000000283F2802280D3830A8042804287FA800000808087F081C08220F9C0000
+C8AF:000000283F2802280D3830A8042804287FA8000003F802000200020003F80000
+C8B0:000000283F2802280D3830A8042804287FA8000007F8000807F8040007F80000
+C8B1:000000283F2802280D3830A8042804287FA800003EF802083E0820083E080000
+C8B2:000000283F2802280D3830A8042804287FA800003EF802883E8820883EF80000
+C8B3:000000283F2802280D3830A8042804287FA800003E8802883EF820883EF80000
+C8B4:000000283F2802280D3830A8042804287FA800001F0801081F0810141F620000
+C8B5:000000283F2802280D3830A8042804287FA800003EF802803EF820803EF80000
+C8B6:000000283F2802280D3830A8042804287FA800003EFC02483E4820483EFC0000
+C8B7:000000283F2802280D3830A8042804287FA800001F08017F1F1C10221F1C0000
+C8B8:000000283F2802280D3830A8042804287FA8000003F802080208020803F80000
+C8B9:000000283F2802280D3830A8042804287FA800000208020803F8020803F80000
+C8BA:000000283F2802280D3830A8042804287FA80000110811081F0811141F620000
+C8BB:000000283F2802280D3830A8042804287FA80000001000100010006801840000
+C8BC:000000283F2802280D3830A8042804287FA800000048004800A8011406620000
+C8BD:000000283F2802280D3830A8042804287FA80000000003F00408040803F00000
+C8BE:000000283F2802280D3830A8042804287FA8000003F80020002000D003080000
+C8BF:000000283F2802280D3830A8042804287FA80000004003F8004000A003180000
+C8C0:000000283F2802280D3830A8042804287FA8000003F8000803F8000800080000
+C8C1:000000283F2802280D3830A8042804287FA8000003F8020003F8020003F80000
+C8C2:000000283F2802280D3830A8042804287FA8000000000FF8022002200FF80000
+C8C3:000000283F2802280D3830A8042804287FA8000000800FF803E0041003E00000
+C8C4:0000000800083F88010801080208060809083088040804087FE8000800080000
+C8C5:000000083F0802080D083088040804087FE8000007F800080008000800080000
+C8C6:000000083F0802080D083088040804087FE8000000003EF80208020802080000
+C8C7:000000083F0802080D083088040804087FE8000000001F080108011401620000
+C8C8:000000083F0802080D083088040804087FE8000008000800080008000FF80000
+C8C9:000000083F0802080D083088040804087FE80000000010F8101010301ECC0000
+C8CA:000000083F0802080D083088040804087FE800000808087F081C08220F9C0000
+C8CB:000000083F0802080D083088040804087FE8000003F802000200020003F80000
+C8CC:000000083F0802080D083088040804087FE8000007F8000807F8040007F80000
+C8CD:000000083F0802080D083088040804087FE800003EF802083E0820083E080000
+C8CE:000000083F0802080D083088040804087FE800003EF802883E8820883EF80000
+C8CF:000000083F0802080D083088040804087FE800003E8802883EF820883EF80000
+C8D0:000000083F0802080D083088040804087FE800001F0801081F0810141F620000
+C8D1:000000083F0802080D083088040804087FE800003EF802803EF820803EF80000
+C8D2:000000083F0802080D083088040804087FE800003EFC02483E4820483EFC0000
+C8D3:000000083F0802080D083088040804087FE800001F08017F1F1C10221F1C0000
+C8D4:000000083F0802080D083088040804087FE8000003F802080208020803F80000
+C8D5:000000083F0802080D083088040804087FE800000208020803F8020803F80000
+C8D6:000000083F0802080D083088040804087FE80000110811081F0811141F620000
+C8D7:000000083F0802080D083088040804087FE80000001000100010006801840000
+C8D8:000000083F0802080D083088040804087FE800000048004800A8011406620000
+C8D9:000000083F0802080D083088040804087FE80000000003F00408040803F00000
+C8DA:000000083F0802080D083088040804087FE8000003F80020002000D003080000
+C8DB:000000083F0802080D083088040804087FE80000004003F8004000A003180000
+C8DC:000000083F0802080D083088040804087FE8000003F8000803F8000800080000
+C8DD:000000083F0802080D083088040804087FE8000003F8020003F8020003F80000
+C8DE:000000083F0802080D083088040804087FE8000000000FF8022002200FF80000
+C8DF:000000083F0802080D083088040804087FE8000000800FF803E0041003E00000
+C8E0:000000000FE0004000400080018002400C2004400440044004407FFC00000000
+C8E1:00000FC0008003400C200000044004407FFC00001FF000100010001000100000
+C8E2:00000FC0008003400C200000044004407FFC000000003EF80208020802080000
+C8E3:00000FC0008003400C200000044004407FFC000000001E100210022802C40000
+C8E4:00000FC0008003400C200000044004407FFC000000001000100010001FF00000
+C8E5:00000FC0008003400C200000044004407FFC0000000020F8201020303ECC0000
+C8E6:00000FC0008003400C200000044004407FFC0000202021FC207020883E700000
+C8E7:00000FC0008003400C200000044004407FFC00001FF01000100010001FF00000
+C8E8:00000FC0008003400C200000044004407FFC00001FF000101FF010001FF00000
+C8E9:00000FC0008003400C200000044004407FFC00003EF802083E0820083E080000
+C8EA:00000FC0008003400C200000044004407FFC00003EF802883E8820883EF80000
+C8EB:00000FC0008003400C200000044004407FFC00003E8802883EF820883EF80000
+C8EC:00000FC0008003400C200000044004407FFC00003E1002103E1020283EC40000
+C8ED:00000FC0008003400C200000044004407FFC00003EF802803EF820803EF80000
+C8EE:00000FC0008003400C200000044004407FFC00003EFC02483E4820483EFC0000
+C8EF:00000FC0008003400C200000044004407FFC00003E2003FC3E7020883E700000
+C8F0:00000FC0008003400C200000044004407FFC00001FF01010101010101FF00000
+C8F1:00000FC0008003400C200000044004407FFC0000101010101FF010101FF00000
+C8F2:00000FC0008003400C200000044004407FFC0000222022203E2022503E880000
+C8F3:00000FC0008003400C200000044004407FFC000000000100010002800C400000
+C8F4:00000FC0008003400C200000044004407FFC00000000024002400DA033100000
+C8F5:00000FC0008003400C200000044004407FFC0000000007C00820082007C00000
+C8F6:00000FC0008003400C200000044004407FFC0000000007E00080014006200000
+C8F7:00000FC0008003400C200000044004407FFC0000008007E00080014006200000
+C8F8:00000FC0008003400C200000044004407FFC00001FF000101FF0001000100000
+C8F9:00000FC0008003400C200000044004407FFC00001FF010001FF010001FF00000
+C8FA:00000FC0008003400C200000044004407FFC000000001FF0044004401FF00000
+C8FB:00000FC0008003400C200000044004407FFC000001001FF007C0082007C00000
+C8FC:000000000FE0004000400080018002400C2000003FF801000100010001000000
+C8FD:00000FC00080008003400C2000007FFC010001001FF000100010001000100000
+C8FE:00000FC00080008003400C2000007FFC0100010000003EF80208020802080000
+C8FF:00000FC00080008003400C2000007FFC0100010000001E100210022802C40000
+C900:00000FC00080008003400C20000000007FFC010001001100100010001FF00000
+C901:00000FC00080008003400C2000007FFC01000100000020F8201020303ECC0000
+C902:00000FC00080008003400C2000007FFC01000100202021FC207020883E700000
+C903:00000FC00080008003400C2000007FFC010001001FF01000100010001FF00000
+C904:00000FC00080008003400C2000007FFC010001001FF000101FF010001FF00000
+C905:00000FC00080008003400C2000007FFC010001003EF802083E0820083E080000
+C906:00000FC00080008003400C2000007FFC010001003EF802883E8820883EF80000
+C907:00000FC00080008003400C2000007FFC010001003E8802883EF820883EF80000
+C908:00000FC00080008003400C2000007FFC010001003E1002103E1020283EC40000
+C909:00000FC00080008003400C2000007FFC010001003EF802803EF820803EF80000
+C90A:00000FC00080008003400C2000007FFC010001003EFC02483E4820483EFC0000
+C90B:00000FC00080008003400C2000007FFC010001003E2003FC3E7020883E700000
+C90C:00000FC00080008003400C2000007FFC010001001FF01010101010101FF00000
+C90D:00000FC00080008003400C2000007FFC01000100101010101FF010101FF00000
+C90E:00000FC00080008003400C2000007FFC01000100222022203E2022503E880000
+C90F:00000FC00080008003400C2000007FFC0100010000000100010002800C400000
+C910:00000FC00080008003400C2000007FFC010001000000024002400DA033100000
+C911:00000FC00080008003400C2000007FFC01000100000007C00820082007C00000
+C912:00000FC00080008003400C2000007FFC01000100000007E00080014006200000
+C913:00000FC00080008003400C2000007FFC01000100008007E00080014006200000
+C914:00000FC00080008003400C2000007FFC010001001FF000101FF0001000100000
+C915:00000FC00080008003400C2000007FFC010001001FF010001FF010001FF00000
+C916:00000FC00080008003400C2000007FFC0100010000001FF0044004401FF00000
+C917:00000FC00080008003400C2000007FFC0100010001001FF007C0082007C00000
+C918:000000083F8801080108020806080908308800087FE8040804F8040804080000
+C919:3F08020802080D08308800087FE8027802080000000007F80008000800080000
+C91A:3F08020802080D08308800087FE802780208000000003EF80208020802080000
+C91B:3F08020802080D08308800087FE802780208000000001F080108011401620000
+C91C:3F08020802080D083088000800087FE80278020802081000100010001FF80000
+C91D:3F08020802080D08308800087FE8027802080000000020F8201020303ECC0000
+C91E:3F08020802080D08308800087FE8027802080000202021FC207020883E700000
+C91F:3F08020802080D08308800087FE802780208000003F802000200020003F80000
+C920:3F08020802080D08308800087FE802780208000007F8000807F8040007F80000
+C921:3F08020802080D08308800087FE80278020800003EF802083E0820083E080000
+C922:3F08020802080D08308800087FE80278020800003EF802883E8820883EF80000
+C923:3F08020802080D08308800087FE80278020800003E8802883EF820883EF80000
+C924:3F08020802080D08308800087FE80278020800000F8800880F8808140FA20000
+C925:3F08020802080D08308800087FE80278020800003EF802803EF820803EF80000
+C926:3F08020802080D08308800087FE80278020800003EFC02483E4820483EFC0000
+C927:3F08020802080D08308800087FE80278020800003E1002FE3E3820443E380000
+C928:3F08020802080D08308800087FE802780208000003F802080208020803F80000
+C929:3F08020802080D08308800087FE80278020800000208020803F8020803F80000
+C92A:3F08020802080D08308800087FE8027802080000210821083F0821143F620000
+C92B:3F08020802080D08308800087FE8027802080000001000100010006801840000
+C92C:3F08020802080D08308800087FE80278020800000048004800A8011406620000
+C92D:3F08020802080D08308800087FE8027802080000000003F00408040803F00000
+C92E:3F08020802080D08308800087FE802780208000003F80020002000D003080000
+C92F:3F08020802080D08308800087FE8027802080000004003F8004000A003180000
+C930:3F08020802080D08308800087FE802780208000003F8000803F8000800080000
+C931:3F08020802080D08308800087FE802780208000003F8020003F8020003F80000
+C932:3F08020802080D08308800087FE802780208000000000FF8022002200FF80000
+C933:3F08020802080D08308800087FE802780208000000800FF803E0041003E00000
+C934:0000000A3F8A010A010A020A060A090A308A000A7FEA040A047A040A040A0000
+C935:3F28022802280D2830A800287FA805E804280000000007F80008000800080000
+C936:3F28022802280D2830A800287FA805E80428000000003EF80208020802080000
+C937:3F28022802280D2830A800287FA805E80428000000001F080108011401620000
+C938:3F28022802280D2830A8002800287FA8042805E804281428100010001FF80000
+C939:3F28022802280D2830A800287FA805E804280000000020F8201020303ECC0000
+C93A:3F28022802280D2830A800287FA805E804280000202021FC207020883E700000
+C93B:3F28022802280D2830A800287FA805E80428000003F802000200020003F80000
+C93C:3F28022802280D2830A800287FA805E80428000007F8000807F8040007F80000
+C93D:3F28022802280D2830A800287FA805E8042800003EF802083E0820083E080000
+C93E:3F28022802280D2830A800287FA805E8042800003EF802883E8820883EF80000
+C93F:3F28022802280D2830A800287FA805E8042800003E8802883EF820883EF80000
+C940:3F28022802280D2830A800287FA805E8042800000F8800880F8808140FA20000
+C941:3F28022802280D2830A800287FA805E8042800003EF802803EF820803EF80000
+C942:3F28022802280D2830A800287FA805E8042800003EFC02483E4820483EFC0000
+C943:3F28022802280D2830A800287FA805E8042800003E1002FE3E3820443E380000
+C944:3F28022802280D2830A800287FA805E80428000003F802080208020803F80000
+C945:3F28022802280D2830A800287FA805E8042800000208020803F8020803F80000
+C946:3F28022802280D2830A800287FA805E804280000210821083F0821143F620000
+C947:3F28022802280D2830A800287FA805E804280000001000100010006801840000
+C948:3F28022802280D2830A800287FA805E8042800000048004800A8011406620000
+C949:3F28022802280D2830A800287FA805E804280000000003F00408040803F00000
+C94A:3F28022802280D2830A800287FA805E80428000003F80020002000D003080000
+C94B:3F28022802280D2830A800287FA805E804280000004003F8004000A003180000
+C94C:3F28022802280D2830A800287FA805E80428000003F8000803F8000800080000
+C94D:3F28022802280D2830A800287FA805E80428000003F8020003F8020003F80000
+C94E:3F28022802280D2830A800287FA805E80428000000000FF8022002200FF80000
+C94F:3F28022802280D2830A800287FA805E80428000000800FF803E0041003E00000
+C950:000000083F8801080108020806080908308800087FE804080408040804080000
+C951:3F08020802080D08308800087FE8020802000000000007F80008000800080000
+C952:3F08020802080D08308800087FE802080200000000003EF80208020802080000
+C953:3F08020802080D08308800087FE802080200000000001F080108011401620000
+C954:3F08020802080D083088000800087FE80208020802081008100010001FF80000
+C955:3F08020802080D08308800087FE8020802000000000020F8201020303ECC0000
+C956:3F08020802080D08308800087FE8020802000000202021FC207020883E700000
+C957:3F08020802080D08308800087FE802080200000003F802000200020003F80000
+C958:3F08020802080D08308800087FE802080200000007F8000807F8040007F80000
+C959:3F08020802080D08308800087FE80208020000003EF802083E0820083E080000
+C95A:3F08020802080D08308800087FE80208020000003EF802883E8820883EF80000
+C95B:3F08020802080D08308800087FE80208020000003E8802883EF820883EF80000
+C95C:3F08020802080D08308800087FE80208020000000F8800880F8808140FA20000
+C95D:3F08020802080D08308800087FE80208020000003EF802803EF820803EF80000
+C95E:3F08020802080D08308800087FE80208020000003EFC02483E4820483EFC0000
+C95F:3F08020802080D08308800087FE80208020000003E1002FE3E3820443E380000
+C960:3F08020802080D08308800087FE802080200000003F802080208020803F80000
+C961:3F08020802080D08308800087FE80208020000000208020803F8020803F80000
+C962:3F08020802080D08308800087FE8020802000000210821083F0821143F620000
+C963:3F08020802080D08308800087FE8020802000000001000100010006801840000
+C964:3F08020802080D08308800087FE80208020000000048004800A8011406620000
+C965:3F08020802080D08308800087FE8020802000000000003F00408040803F00000
+C966:3F08020802080D08308800087FE802080200000003F80020002000D003080000
+C967:3F08020802080D08308800087FE8020802000000004003F8004000A003180000
+C968:3F08020802080D08308800087FE802080200000003F8000803F8000800080000
+C969:3F08020802080D08308800087FE802080200000003F8020003F8020003F80000
+C96A:3F08020802080D08308800087FE802080200000000000FF8022002200FF80000
+C96B:3F08020802080D08308800087FE802080200000000800FF803E0041003E00000
+C96C:000000000FE0004000400080018002400C2000007FFC04400440044004400000
+C96D:00000FC00080008003400C2000007FFC044004401FF000100010001000100000
+C96E:00000FC00080008003400C2000007FFC0440044000003EF80208020802080000
+C96F:00000FC00080008003400C2000007FFC0440044000001E100210022802C40000
+C970:00000FC00080008003400C20000000007FFC044004401440100010001FF00000
+C971:00000FC00080008003400C2000007FFC04400440000020F8201020303ECC0000
+C972:00000FC00080008003400C2000007FFC04400440202021FC207020883E700000
+C973:00000FC00080008003400C2000007FFC044004401FF01000100010001FF00000
+C974:00000FC00080008003400C2000007FFC044004401FF000101FF010001FF00000
+C975:00000FC00080008003400C2000007FFC044004403EF802083E0820083E080000
+C976:00000FC00080008003400C2000007FFC044004403EF802883E8820883EF80000
+C977:00000FC00080008003400C2000007FFC044004403E8802883EF820883EF80000
+C978:00000FC00080008003400C2000007FFC044004403E1002103E1020283EC40000
+C979:00000FC00080008003400C2000007FFC044004403EF802803EF820803EF80000
+C97A:00000FC00080008003400C2000007FFC044004403EFC02483E4820483EFC0000
+C97B:00000FC00080008003400C2000007FFC044004403E2003FC3E7020883E700000
+C97C:00000FC00080008003400C2000007FFC044004401FF01010101010101FF00000
+C97D:00000FC00080008003400C2000007FFC04400440101010101FF010101FF00000
+C97E:00000FC00080008003400C2000007FFC04400440222022203E2022503E880000
+C97F:00000FC00080008003400C2000007FFC0440044000000100010002800C400000
+C980:00000FC00080008003400C2000007FFC044004400000024002400DA033100000
+C981:00000FC00080008003400C2000007FFC04400440000007C00820082007C00000
+C982:00000FC00080008003400C2000007FFC04400440000007E00080014006200000
+C983:00000FC00080008003400C2000007FFC04400440008007E00080014006200000
+C984:00000FC00080008003400C2000007FFC044004401FF000101FF0001000100000
+C985:00000FC00080008003400C2000007FFC044004401FF010001FF010001FF00000
+C986:00000FC00080008003400C2000007FFC0440044000001FF0044004401FF00000
+C987:00000FC00080008003400C2000007FFC0440044001001FF007C0082007C00000
+C988:000000000FE0004000400080018002400C20000000007FFC0000000000000000
+C989:00000FC0008003400C200000000000007FFC00001FF000100010001000100000
+C98A:00000FC0008003400C200000000000007FFC000000003EF80208020802080000
+C98B:00000FC0008003400C200000000000007FFC000000001E100210022802C40000
+C98C:00000FC0008003400C200000000000007FFC000000001000100010001FF00000
+C98D:00000FC0008003400C200000000000007FFC0000000020F8201020303ECC0000
+C98E:00000FC0008003400C200000000000007FFC0000202021FC207020883E700000
+C98F:00000FC0008003400C200000000000007FFC00001FF01000100010001FF00000
+C990:00000FC0008003400C200000000000007FFC00001FF000101FF010001FF00000
+C991:00000FC0008003400C200000000000007FFC00003EF802083E0820083E080000
+C992:00000FC0008003400C200000000000007FFC00003EF802883E8820883EF80000
+C993:00000FC0008003400C200000000000007FFC00003E8802883EF820883EF80000
+C994:00000FC0008003400C200000000000007FFC00003E1002103E1020283EC40000
+C995:00000FC0008003400C200000000000007FFC00003EF802803EF820803EF80000
+C996:00000FC0008003400C200000000000007FFC00003EFC02483E4820483EFC0000
+C997:00000FC0008003400C200000000000007FFC00003E2003FC3E7020883E700000
+C998:00000FC0008003400C200000000000007FFC00001FF01010101010101FF00000
+C999:00000FC0008003400C200000000000007FFC0000101010101FF010101FF00000
+C99A:00000FC0008003400C200000000000007FFC0000222022203E2022503E880000
+C99B:00000FC0008003400C200000000000007FFC000000000100010002800C400000
+C99C:00000FC0008003400C200000000000007FFC00000000024002400DA033100000
+C99D:00000FC0008003400C200000000000007FFC0000000007C00820082007C00000
+C99E:00000FC0008003400C200000000000007FFC0000000007E00080014006200000
+C99F:00000FC0008003400C200000000000007FFC0000008007E00080014006200000
+C9A0:00000FC0008003400C200000000000007FFC00001FF000101FF0001000100000
+C9A1:00000FC0008003400C200000000000007FFC00001FF010001FF010001FF00000
+C9A2:00000FC0008003400C200000000000007FFC000000001FF0044004401FF00000
+C9A3:00000FC0008003400C200000000000007FFC000001001FF007C0082007C00000
+C9A4:0000000800083F8801080108020806080908308800087FE80008000800080000
+C9A5:000000083F0802080D083088000800087FE8000007F800080008000800080000
+C9A6:000000083F0802080D083088000800087FE8000000003EF80208020802080000
+C9A7:000000083F0802080D083088000800087FE8000000001F080108011401620000
+C9A8:000000083F0802080D083088000800087FE8000008000800080008000FF80000
+C9A9:000000083F0802080D083088000800087FE80000000010F8101010301ECC0000
+C9AA:000000083F0802080D083088000800087FE800000808087F081C08220F9C0000
+C9AB:000000083F0802080D083088000800087FE8000003F802000200020003F80000
+C9AC:000000083F0802080D083088000800087FE8000007F8000807F8040007F80000
+C9AD:000000083F0802080D083088000800087FE800003EF802083E0820083E080000
+C9AE:000000083F0802080D083088000800087FE800003EF802883E8820883EF80000
+C9AF:000000083F0802080D083088000800087FE800003E8802883EF820883EF80000
+C9B0:000000083F0802080D083088000800087FE800001F0801081F0810141F620000
+C9B1:000000083F0802080D083088000800087FE800003EF802803EF820803EF80000
+C9B2:000000083F0802080D083088000800087FE800003EFC02483E4820483EFC0000
+C9B3:000000083F0802080D083088000800087FE800001F08017F1F1C10221F1C0000
+C9B4:000000083F0802080D083088000800087FE8000003F802080208020803F80000
+C9B5:000000083F0802080D083088000800087FE800000208020803F8020803F80000
+C9B6:000000083F0802080D083088000800087FE80000110811081F0811141F620000
+C9B7:000000083F0802080D083088000800087FE80000001000100010006801840000
+C9B8:000000083F0802080D083088000800087FE800000048004800A8011406620000
+C9B9:000000083F0802080D083088000800087FE80000000003F00408040803F00000
+C9BA:000000083F0802080D083088000800087FE8000003F80020002000D003080000
+C9BB:000000083F0802080D083088000800087FE80000004003F8004000A003180000
+C9BC:000000083F0802080D083088000800087FE8000003F8000803F8000800080000
+C9BD:000000083F0802080D083088000800087FE8000003F8020003F8020003F80000
+C9BE:000000083F0802080D083088000800087FE8000000000FF8022002200FF80000
+C9BF:000000083F0802080D083088000800087FE8000000800FF803E0041003E00000
+C9C0:00000000000800083F8801080108020806080908308800080008000800080000
+C9C1:0000000800087E08040804081A08610800080000000007F80008000800080000
+C9C2:0000000800087E08040804081A0861080008000000003EF80208020802080000
+C9C3:0000000800087E08040804081A0861080008000000001F080108011401620000
+C9C4:0000000800087E08040804081A0861080008000800001000100010001FF80000
+C9C5:0000000800087E08040804081A08610800080000000020F8201020303ECC0000
+C9C6:0000000800087E08040804081A08610800080000202021FC207020883E700000
+C9C7:0000000800087E08040804081A0861080008000003F802000200020003F80000
+C9C8:0000000800087E08040804081A0861080008000007F8000807F8040007F80000
+C9C9:0000000800087E08040804081A086108000800003EF802083E0820083E080000
+C9CA:0000000800087E08040804081A086108000800003EF802883E8820883EF80000
+C9CB:0000000800087E08040804081A086108000800003E8802883EF820883EF80000
+C9CC:0000000800087E08040804081A086108000800000F8800880F8808140FA20000
+C9CD:0000000800087E08040804081A086108000800003EF802803EF820803EF80000
+C9CE:0000000800087E08040804081A086108000800003EFC02483E4820483EFC0000
+C9CF:0000000800087E08040804081A086108000800003E1002FE3E3820443E380000
+C9D0:0000000800087E08040804081A0861080008000003F802080208020803F80000
+C9D1:0000000800087E08040804081A086108000800000208020803F8020803F80000
+C9D2:0000000800087E08040804081A08610800080000210821083F0821143F620000
+C9D3:0000000800087E08040804081A08610800080000001000100010006801840000
+C9D4:0000000800087E08040804081A086108000800000048004800A8011406620000
+C9D5:0000000800087E08040804081A08610800080000000003F00408040803F00000
+C9D6:0000000800087E08040804081A0861080008000003F80020002000D003080000
+C9D7:0000000800087E08040804081A08610800080000004003F8004000A003180000
+C9D8:0000000800087E08040804081A0861080008000003F8000803F8000800080000
+C9D9:0000000800087E08040804081A0861080008000003F8020003F8020003F80000
+C9DA:0000000800087E08040804081A0861080008000000000FF8022002200FF80000
+C9DB:0000000800087E08040804081A0861080008000000800FF803E0041003E00000
+C9DC:00000000001000107B9008900890191E15102290CC5000100010001000100000
+C9DD:00000008000877082208220E550888880008000007F800080008000800080000
+C9DE:00000008000877082208220E550888880008000000003EF80208020802080000
+C9DF:00000008000877082208220E550888880008000000001F080108011401620000
+C9E0:00000008000877082208220E550888880008000808000800080008000FF80000
+C9E1:00000008000877082208220E5508888800080000000010F8101010301ECC0000
+C9E2:00000008000877082208220E55088888000800000808087F081C08220F9C0000
+C9E3:00000008000877082208220E550888880008000003F802000200020003F80000
+C9E4:00000008000877082208220E550888880008000007F8000807F8040007F80000
+C9E5:00000008000877082208220E55088888000800003EF802083E0820083E080000
+C9E6:00000008000877082208220E55088888000800003EF802883E8820883EF80000
+C9E7:00000008000877082208220E55088888000800003E8802883EF820883EF80000
+C9E8:00000008000877082208220E55088888000800001F0801081F0810141F620000
+C9E9:00000008000877082208220E55088888000800003EF802803EF820803EF80000
+C9EA:00000008000877082208220E55088888000800003EFC02483E4820483EFC0000
+C9EB:00000008000877082208220E55088888000800001F08017F1F1C10221F1C0000
+C9EC:00000008000877082208220E550888880008000003F802080208020803F80000
+C9ED:00000008000877082208220E55088888000800000208020803F8020803F80000
+C9EE:00000008000877082208220E5508888800080000110811081F0811141F620000
+C9EF:00000008000877082208220E5508888800080000001000100010006801840000
+C9F0:00000008000877082208220E55088888000800000048004800A8011406620000
+C9F1:00000008000877082208220E5508888800080000000003F00408040803F00000
+C9F2:00000008000877082208220E550888880008000003F80020002000D003080000
+C9F3:00000008000877082208220E5508888800080000004003F8004000A003180000
+C9F4:00000008000877082208220E550888880008000003F8000803F8000800080000
+C9F5:00000008000877082208220E550888880008000003F8020003F8020003F80000
+C9F6:00000008000877082208220E550888880008000000000FF8022002200FF80000
+C9F7:00000008000877082208220E550888880008000000800FF803E0041003E00000
+C9F8:00000000001200127B9208920892191E15122292CC5200120012001200120000
+C9F9:000000280028772822282238552888A80028000007F800080008000800080000
+C9FA:000000280028772822282238552888A80028000000003EF80208020802080000
+C9FB:000000280028772822282238552888A80028000000003E100210022802C40000
+C9FC:000000280028772822282238552888A80028002808000800080008000FF80000
+C9FD:000000280028772822282238552888A800280000000020F8201020303ECC0000
+C9FE:000000280028772822282238552888A800280000202021FC207020883E700000
+C9FF:000000280028772822282238552888A80028000003F802000200020003F80000
+CA00:000000280028772822282238552888A80028000007F8000807F8040007F80000
+CA01:000000280028772822282238552888A8002800003EF802083E0820083E080000
+CA02:000000280028772822282238552888A8002800003EF802883E8820883EF80000
+CA03:000000280028772822282238552888A8002800003E8802883EF820883EF80000
+CA04:000000280028772822282238552888A8002800001F0801081F0810141F620000
+CA05:000000280028772822282238552888A8002800003EF802803EF820803EF80000
+CA06:000000280028772822282238552888A8002800003EFC02483E4820483EFC0000
+CA07:000000280028772822282238552888A8002800003E1002FE3E3820443E380000
+CA08:000000280028772822282238552888A80028000003F802080208020803F80000
+CA09:000000280028772822282238552888A8002800000208020803F8020803F80000
+CA0A:000000280028772822282238552888A800280000110811081F0811141F620000
+CA0B:000000280028772822282238552888A800280000000800080008003400C20000
+CA0C:000000280028772822282238552888A8002800000048004800A8011406620000
+CA0D:000000280028772822282238552888A800280000000001F00208020801F00000
+CA0E:000000280028772822282238552888A80028000003F80020002000D003080000
+CA0F:000000280028772822282238552888A800280000004003F8004000A003180000
+CA10:000000280028772822282238552888A80028000003F8000803F8000800080000
+CA11:000000280028772822282238552888A80028000003F8020003F8020003F80000
+CA12:000000280028772822282238552888A80028000000000FF8022002200FF80000
+CA13:000000280028772822282238552888A80028000000800FF803E0041003E00000
+CA14:00000000001000107B900890089E19101510229ECC5000100010001000100000
+CA15:0000000800087708220E2208550E88880008000007F800080008000800080000
+CA16:0000000800087708220E2208550E88880008000000003EF80208020802080000
+CA17:0000000800087708220E2208550E88880008000000001F080108011401620000
+CA18:0000000800087708220E2208550E88880008000008000800080008000FF80000
+CA19:0000000800087708220E2208550E888800080000000010F8101010301ECC0000
+CA1A:0000000800087708220E2208550E8888000800000808087F081C08220F9C0000
+CA1B:0000000800087708220E2208550E88880008000003F802000200020003F80000
+CA1C:0000000800087708220E2208550E88880008000007F8000807F8040007F80000
+CA1D:0000000800087708220E2208550E8888000800003EF802083E0820083E080000
+CA1E:0000000800087708220E2208550E8888000800003EF802883E8820883EF80000
+CA1F:0000000800087708220E2208550E8888000800003E8802883EF820883EF80000
+CA20:0000000800087708220E2208550E8888000800001F0801081F0810141F620000
+CA21:0000000800087708220E2208550E8888000800003EF802803EF820803EF80000
+CA22:0000000800087708220E2208550E8888000800003EFC02483E4820483EFC0000
+CA23:0000000800087708220E2208550E8888000800001F08017F1F1C10221F1C0000
+CA24:0000000800087708220E2208550E88880008000003F802080208020803F80000
+CA25:0000000800087708220E2208550E8888000800000208020803F8020803F80000
+CA26:0000000800087708220E2208550E888800080000110811081F0811141F620000
+CA27:0000000800087708220E2208550E888800080000001000100010006801840000
+CA28:0000000800087708220E2208550E8888000800000048004800A8011406620000
+CA29:0000000800087708220E2208550E888800080000000003F00408040803F00000
+CA2A:0000000800087708220E2208550E88880008000003F80020002000D003080000
+CA2B:0000000800087708220E2208550E888800080000004003F8004000A003180000
+CA2C:0000000800087708220E2208550E88880008000003F8000803F8000800080000
+CA2D:0000000800087708220E2208550E88880008000003F8020003F8020003F80000
+CA2E:0000000800087708220E2208550E88880008000000000FF8022002200FF80000
+CA2F:0000000800087708220E2208550E88880008000000800FF803E0041003E00000
+CA30:00000000001200127B920892089E19121512229ECC5200120012001200120000
+CA31:000000280028772822382228553888A80028000007F800080008000800080000
+CA32:000000280028772822382228553888A80028000000003EF80208020802080000
+CA33:000000280028772822382228553888A80028000000003E100210022802C40000
+CA34:000000280028772822382228553888A80028002808000800080008000FF80000
+CA35:000000280028772822382228553888A800280000000020F8201020303ECC0000
+CA36:000000280028772822382228553888A800280000202021FC207020883E700000
+CA37:000000280028772822382228553888A80028000003F802000200020003F80000
+CA38:000000280028772822382228553888A80028000007F8000807F8040007F80000
+CA39:000000280028772822382228553888A8002800003EF802083E0820083E080000
+CA3A:000000280028772822382228553888A8002800003EF802883E8820883EF80000
+CA3B:000000280028772822382228553888A8002800003E8802883EF820883EF80000
+CA3C:000000280028772822382228553888A8002800001F0801081F0810141F620000
+CA3D:000000280028772822382228553888A8002800003EF802803EF820803EF80000
+CA3E:000000280028772822382228553888A8002800003EFC02483E4820483EFC0000
+CA3F:000000280028772822382228553888A8002800003E1002FE3E3820443E380000
+CA40:000000280028772822382228553888A80028000003F802080208020803F80000
+CA41:000000280028772822382228553888A8002800000208020803F8020803F80000
+CA42:000000280028772822382228553888A800280000110811081F0811141F620000
+CA43:000000280028772822382228553888A800280000000800080008003400C20000
+CA44:000000280028772822382228553888A8002800000048004800A8011406620000
+CA45:000000280028772822382228553888A800280000000001F00208020801F00000
+CA46:000000280028772822382228553888A80028000003F80020002000D003080000
+CA47:000000280028772822382228553888A800280000004003F8004000A003180000
+CA48:000000280028772822382228553888A80028000003F8000803F8000800080000
+CA49:000000280028772822382228553888A80028000003F8020003F8020003F80000
+CA4A:000000280028772822382228553888A80028000000000FF8022002200FF80000
+CA4B:000000280028772822382228553888A80028000000800FF803E0041003E00000
+CA4C:00000000000200027B8208820882191E15022282CC4200020002000200020000
+CA4D:0000000800087708220822385508888800080000000007F80008000800080000
+CA4E:000000080008770822082238550888880008000000003EF80208020802080000
+CA4F:000000080008770822082238550888880008000000001F080108011401620000
+CA50:000000080008770822082238550888880008000000001000100010001FF80000
+CA51:0000000800087708220822385508888800080000000020F8201020303ECC0000
+CA52:0000000800087708220822385508888800080000202021FC207020883E700000
+CA53:000000080008770822082238550888880008000003F802000200020003F80000
+CA54:000000080008770822082238550888880008000007F8000807F8040007F80000
+CA55:00000008000877082208223855088888000800003EF802083E0820083E080000
+CA56:00000008000877082208223855088888000800003EF802883E8820883EF80000
+CA57:00000008000877082208223855088888000800003E8802883EF820883EF80000
+CA58:00000008000877082208223855088888000800000F8800880F8808140FA20000
+CA59:00000008000877082208223855088888000800003EF802803EF820803EF80000
+CA5A:00000008000877082208223855088888000800003EFC02483E4820483EFC0000
+CA5B:00000008000877082208223855088888000800003E1002FE3E3820443E380000
+CA5C:000000080008770822082238550888880008000003F802080208020803F80000
+CA5D:00000008000877082208223855088888000800000208020803F8020803F80000
+CA5E:0000000800087708220822385508888800080000210821083F0821143F620000
+CA5F:0000000800087708220822385508888800080000001000100010006801840000
+CA60:00000008000877082208223855088888000800000048004800A8011406620000
+CA61:0000000800087708220822385508888800080000000003F00408040803F00000
+CA62:000000080008770822082238550888880008000003F80020002000D003080000
+CA63:0000000800087708220822385508888800080000004003F8004000A003180000
+CA64:000000080008770822082238550888880008000003F8000803F8000800080000
+CA65:000000080008770822082238550888880008000003F8020003F8020003F80000
+CA66:000000080008770822082238550888880008000000000FF8022002200FF80000
+CA67:000000080008770822082238550888880008000000800FF803E0041003E00000
+CA68:00000000000A000A7B8A088A088A193A150A228ACC4A000A000A000A000A0000
+CA69:0000002800287728222822E8552888A80028000007F800080008000800080000
+CA6A:0000002800287728222822E8552888A80028000000003EF80208020802080000
+CA6B:0000002800287728222822E8552888A80028000000003E100210022802C40000
+CA6C:0000002800287728222822E8552888A80028000008000800080008000FF80000
+CA6D:0000002800287728222822E8552888A800280000000020F8201020303ECC0000
+CA6E:0000002800287728222822E8552888A800280000202021FC207020883E700000
+CA6F:0000002800287728222822E8552888A80028000003F802000200020003F80000
+CA70:0000002800287728222822E8552888A80028000007F8000807F8040007F80000
+CA71:0000002800287728222822E8552888A8002800003EF802083E0820083E080000
+CA72:0000002800287728222822E8552888A8002800003EF802883E8820883EF80000
+CA73:0000002800287728222822E8552888A8002800003E8802883EF820883EF80000
+CA74:0000002800287728222822E8552888A8002800001F0801081F0810141F620000
+CA75:0000002800287728222822E8552888A8002800003EF802803EF820803EF80000
+CA76:0000002800287728222822E8552888A8002800003EFC02483E4820483EFC0000
+CA77:0000002800287728222822E8552888A8002800003E1002FE3E3820443E380000
+CA78:0000002800287728222822E8552888A80028000003F802080208020803F80000
+CA79:0000002800287728222822E8552888A8002800000208020803F8020803F80000
+CA7A:0000002800287728222822E8552888A800280000110811081F0811141F620000
+CA7B:0000002800287728222822E8552888A800280000000800080008003400C20000
+CA7C:0000002800287728222822E8552888A8002800000048004800A8011406620000
+CA7D:0000002800287728222822E8552888A800280000000001F00208020801F00000
+CA7E:0000002800287728222822E8552888A80028000003F80020002000D003080000
+CA7F:0000002800287728222822E8552888A800280000004003F8004000A003180000
+CA80:0000002800287728222822E8552888A80028000003F8000803F8000800080000
+CA81:0000002800287728222822E8552888A80028000003F8020003F8020003F80000
+CA82:0000002800287728222822E8552888A80028000000000FF8022002200FF80000
+CA83:0000002800287728222822E8552888A80028000000800FF803E0041003E00000
+CA84:00000000000200027B820882089E19021502229ECC4200020002000200020000
+CA85:0000000800087708223822085538888800080000000007F80008000800080000
+CA86:000000080008770822382208553888880008000000003EF80208020802080000
+CA87:000000080008770822382208553888880008000000001F080108011401620000
+CA88:000000080008770822382208553888880008000800001000100010001FF80000
+CA89:0000000800087708223822085538888800080000000020F8201020303ECC0000
+CA8A:0000000800087708223822085538888800080000202021FC207020883E700000
+CA8B:000000080008770822382208553888880008000003F802000200020003F80000
+CA8C:000000080008770822382208553888880008000007F8000807F8040007F80000
+CA8D:00000008000877082238220855388888000800003EF802083E0820083E080000
+CA8E:00000008000877082238220855388888000800003EF802883E8820883EF80000
+CA8F:00000008000877082238220855388888000800003E8802883EF820883EF80000
+CA90:00000008000877082238220855388888000800000F8800880F8808140FA20000
+CA91:00000008000877082238220855388888000800003EF802803EF820803EF80000
+CA92:00000008000877082238220855388888000800003EFC02483E4820483EFC0000
+CA93:00000008000877082238220855388888000800003E1002FE3E3820443E380000
+CA94:000000080008770822382208553888880008000003F802080208020803F80000
+CA95:00000008000877082238220855388888000800000208020803F8020803F80000
+CA96:0000000800087708223822085538888800080000210821083F0821143F620000
+CA97:0000000800087708223822085538888800080000001000100010006801840000
+CA98:00000008000877082238220855388888000800000048004800A8011406620000
+CA99:0000000800087708223822085538888800080000000003F00408040803F00000
+CA9A:000000080008770822382208553888880008000003F80020002000D003080000
+CA9B:0000000800087708223822085538888800080000004003F8004000A003180000
+CA9C:000000080008770822382208553888880008000003F8000803F8000800080000
+CA9D:000000080008770822382208553888880008000003F8020003F8020003F80000
+CA9E:000000080008770822382208553888880008000000000FF8022002200FF80000
+CA9F:000000080008770822382208553888880008000000800FF803E0041003E00000
+CAA0:00000000000A000A7B8A088A08BA190A150A22BACC4A000A000A000A000A0000
+CAA1:000000280028772822E8222855E888A80028000007F800080008000800080000
+CAA2:000000280028772822E8222855E888A80028000000003EF80208020802080000
+CAA3:000000280028772822E8222855E888A80028000000003E100210022802C40000
+CAA4:000000280028772822E8222855E888A80028002808000800080008000FF80000
+CAA5:000000280028772822E8222855E888A800280000000020F8201020303ECC0000
+CAA6:000000280028772822E8222855E888A800280000202021FC207020883E700000
+CAA7:000000280028772822E8222855E888A80028000003F802000200020003F80000
+CAA8:000000280028772822E8222855E888A80028000007F8000807F8040007F80000
+CAA9:000000280028772822E8222855E888A8002800003EF802083E0820083E080000
+CAAA:000000280028772822E8222855E888A8002800003EF802883E8820883EF80000
+CAAB:000000280028772822E8222855E888A8002800003E8802883EF820883EF80000
+CAAC:000000280028772822E8222855E888A8002800001F0801081F0810141F620000
+CAAD:000000280028772822E8222855E888A8002800003EF802803EF820803EF80000
+CAAE:000000280028772822E8222855E888A8002800003EFC02483E4820483EFC0000
+CAAF:000000280028772822E8222855E888A8002800003E1002FE3E3820443E380000
+CAB0:000000280028772822E8222855E888A80028000003F802080208020803F80000
+CAB1:000000280028772822E8222855E888A8002800000208020803F8020803F80000
+CAB2:000000280028772822E8222855E888A800280000110811081F0811141F620000
+CAB3:000000280028772822E8222855E888A800280000000800080008003400C20000
+CAB4:000000280028772822E8222855E888A8002800000048004800A8011406620000
+CAB5:000000280028772822E8222855E888A800280000000001F00208020801F00000
+CAB6:000000280028772822E8222855E888A80028000003F80020002000D003080000
+CAB7:000000280028772822E8222855E888A800280000004003F8004000A003180000
+CAB8:000000280028772822E8222855E888A80028000003F8000803F8000800080000
+CAB9:000000280028772822E8222855E888A80028000003F8020003F8020003F80000
+CABA:000000280028772822E8222855E888A80028000000000FF8022002200FF80000
+CABB:000000280028772822E8222855E888A80028000000800FF803E0041003E00000
+CABC:0000000000001EE0022002200640054008A033100100010001007FFC00000000
+CABD:00003DE00440088015402220010001007FFC00001FF000100010001000100000
+CABE:00003DE00440088015402220010001007FFC000000003EF80208020802080000
+CABF:00003DE00440088015402220010001007FFC000000001E100210022802C40000
+CAC0:00003DE00440088015402220010001007FFC000000001000100010001FF00000
+CAC1:00003DE00440088015402220010001007FFC0000000020F8201020303ECC0000
+CAC2:00003DE00440088015402220010001007FFC0000202021FC207020883E700000
+CAC3:00003DE00440088015402220010001007FFC00001FF01000100010001FF00000
+CAC4:00003DE00440088015402220010001007FFC00001FF000101FF010001FF00000
+CAC5:00003DE00440088015402220010001007FFC00003EF802083E0820083E080000
+CAC6:00003DE00440088015402220010001007FFC00003EF802883E8820883EF80000
+CAC7:00003DE00440088015402220010001007FFC00003E8802883EF820883EF80000
+CAC8:00003DE00440088015402220010001007FFC00003E1002103E1020283EC40000
+CAC9:00003DE00440088015402220010001007FFC00003EF802803EF820803EF80000
+CACA:00003DE00440088015402220010001007FFC00003EFC02483E4820483EFC0000
+CACB:00003DE00440088015402220010001007FFC00003E2003FC3E7020883E700000
+CACC:00003DE00440088015402220010001007FFC00001FF01010101010101FF00000
+CACD:00003DE00440088015402220010001007FFC0000101010101FF010101FF00000
+CACE:00003DE00440088015402220010001007FFC0000222022203E2022503E880000
+CACF:00003DE00440088015402220010001007FFC000000000100010002800C400000
+CAD0:00003DE00440088015402220010001007FFC00000000024002400DA033100000
+CAD1:00003DE00440088015402220010001007FFC0000000007C00820082007C00000
+CAD2:00003DE00440088015402220010001007FFC0000000007E00080014006200000
+CAD3:00003DE00440088015402220010001007FFC0000008007E00080014006200000
+CAD4:00003DE00440088015402220010001007FFC00001FF000101FF0001000100000
+CAD5:00003DE00440088015402220010001007FFC00001FF010001FF010001FF00000
+CAD6:00003DE00440088015402220010001007FFC000000001FF0044004401FF00000
+CAD7:00003DE00440088015402220010001007FFC000001001FF007C0082007C00000
+CAD8:0000001000107B90089008901910151E2290CC50041004107FD0001000100000
+CAD9:00007BC8088811082A8E4448040804087FE8000007F800080008000800080000
+CADA:00007BC8088811082A8E4448040804087FE8000000003EF80208020802080000
+CADB:00007BC8088811082A8E4448040804087FE8000000001F080108011401620000
+CADC:00007BC8088811082A8E4448040804087FE8000008000800080008000FF80000
+CADD:00007BC8088811082A8E4448040804087FE80000000010F8101010301ECC0000
+CADE:00007BC8088811082A8E4448040804087FE800000808087F081C08220F9C0000
+CADF:00007BC8088811082A8E4448040804087FE8000003F802000200020003F80000
+CAE0:00007BC8088811082A8E4448040804087FE8000007F8000807F8040007F80000
+CAE1:00007BC8088811082A8E4448040804087FE800003EF802083E0820083E080000
+CAE2:00007BC8088811082A8E4448040804087FE800003EF802883E8820883EF80000
+CAE3:00007BC8088811082A8E4448040804087FE800003E8802883EF820883EF80000
+CAE4:00007BC8088811082A8E4448040804087FE800001F0801081F0810141F620000
+CAE5:00007BC8088811082A8E4448040804087FE800003EF802803EF820803EF80000
+CAE6:00007BC8088811082A8E4448040804087FE800003EFC02483E4820483EFC0000
+CAE7:00007BC8088811082A8E4448040804087FE800001F08017F1F1C10221F1C0000
+CAE8:00007BC8088811082A8E4448040804087FE8000003F802080208020803F80000
+CAE9:00007BC8088811082A8E4448040804087FE800000208020803F8020803F80000
+CAEA:00007BC8088811082A8E4448040804087FE80000110811081F0811141F620000
+CAEB:00007BC8088811082A8E4448040804087FE80000001000100010006801840000
+CAEC:00007BC8088811082A8E4448040804087FE800000048004800A8011406620000
+CAED:00007BC8088811082A8E4448040804087FE80000000003F00408040803F00000
+CAEE:00007BC8088811082A8E4448040804087FE8000003F80020002000D003080000
+CAEF:00007BC8088811082A8E4448040804087FE80000004003F8004000A003180000
+CAF0:00007BC8088811082A8E4448040804087FE8000003F8000803F8000800080000
+CAF1:00007BC8088811082A8E4448040804087FE8000003F8020003F8020003F80000
+CAF2:00007BC8088811082A8E4448040804087FE8000000000FF8022002200FF80000
+CAF3:00007BC8088811082A8E4448040804087FE8000000800FF803E0041003E00000
+CAF4:0000001200127B92089208921912151E2292CC52041204127FD2001200120000
+CAF5:00007BE808A811282AB84468042804287FA8000007F800080008000800080000
+CAF6:00007BE808A811282AB84468042804287FA8000000003EF80208020802080000
+CAF7:00007BE808A811282AB84468042804287FA8000000001F080108011401620000
+CAF8:00007BE808A811282AB84468042804287FA8000008000800080008000FF80000
+CAF9:00007BE808A811282AB84468042804287FA80000000010F8101010301ECC0000
+CAFA:00007BE808A811282AB84468042804287FA800000808087F081C08220F9C0000
+CAFB:00007BE808A811282AB84468042804287FA8000003F802000200020003F80000
+CAFC:00007BE808A811282AB84468042804287FA8000007F8000807F8040007F80000
+CAFD:00007BE808A811282AB84468042804287FA800003EF802083E0820083E080000
+CAFE:00007BE808A811282AB84468042804287FA800003EF802883E8820883EF80000
+CAFF:00007BE808A811282AB84468042804287FA800003E8802883EF820883EF80000
+CB00:00007BE808A811282AB84468042804287FA800001F0801081F0810141F620000
+CB01:00007BE808A811282AB84468042804287FA800003EF802803EF820803EF80000
+CB02:00007BE808A811282AB84468042804287FA800003EFC02483E4820483EFC0000
+CB03:00007BE808A811282AB84468042804287FA800001F08017F1F1C10221F1C0000
+CB04:00007BE808A811282AB84468042804287FA8000003F802080208020803F80000
+CB05:00007BE808A811282AB84468042804287FA800000208020803F8020803F80000
+CB06:00007BE808A811282AB84468042804287FA80000110811081F0811141F620000
+CB07:00007BE808A811282AB84468042804287FA80000001000100010006801840000
+CB08:00007BE808A811282AB84468042804287FA800000048004800A8011406620000
+CB09:00007BE808A811282AB84468042804287FA80000000003F00408040803F00000
+CB0A:00007BE808A811282AB84468042804287FA8000003F80020002000D003080000
+CB0B:00007BE808A811282AB84468042804287FA80000004003F8004000A003180000
+CB0C:00007BE808A811282AB84468042804287FA8000003F8000803F8000800080000
+CB0D:00007BE808A811282AB84468042804287FA8000003F8020003F8020003F80000
+CB0E:00007BE808A811282AB84468042804287FA8000000000FF8022002200FF80000
+CB0F:00007BE808A811282AB84468042804287FA8000000800FF803E0041003E00000
+CB10:0000000800087B8808880888190815082288CC48040804087FE8000800080000
+CB11:00007BC8088811082A884448040804087FE8000007F800080008000800080000
+CB12:00007BC8088811082A884448040804087FE8000000003EF80208020802080000
+CB13:00007BC8088811082A884448040804087FE8000000001F080108011401620000
+CB14:00007BC8088811082A884448040804087FE8000008000800080008000FF80000
+CB15:00007BC8088811082A884448040804087FE80000000010F8101010301ECC0000
+CB16:00007BC8088811082A884448040804087FE800000808087F081C08220F9C0000
+CB17:00007BC8088811082A884448040804087FE8000003F802000200020003F80000
+CB18:00007BC8088811082A884448040804087FE8000007F8000807F8040007F80000
+CB19:00007BC8088811082A884448040804087FE800003EF802083E0820083E080000
+CB1A:00007BC8088811082A884448040804087FE800003EF802883E8820883EF80000
+CB1B:00007BC8088811082A884448040804087FE800003E8802883EF820883EF80000
+CB1C:00007BC8088811082A884448040804087FE800001F0801081F0810141F620000
+CB1D:00007BC8088811082A884448040804087FE800003EF802803EF820803EF80000
+CB1E:00007BC8088811082A884448040804087FE800003EFC02483E4820483EFC0000
+CB1F:00007BC8088811082A884448040804087FE800001F08017F1F1C10221F1C0000
+CB20:00007BC8088811082A884448040804087FE8000003F802080208020803F80000
+CB21:00007BC8088811082A884448040804087FE800000208020803F8020803F80000
+CB22:00007BC8088811082A884448040804087FE80000110811081F0811141F620000
+CB23:00007BC8088811082A884448040804087FE80000001000100010006801840000
+CB24:00007BC8088811082A884448040804087FE800000048004800A8011406620000
+CB25:00007BC8088811082A884448040804087FE80000000003F00408040803F00000
+CB26:00007BC8088811082A884448040804087FE8000003F80020002000D003080000
+CB27:00007BC8088811082A884448040804087FE80000004003F8004000A003180000
+CB28:00007BC8088811082A884448040804087FE8000003F8000803F8000800080000
+CB29:00007BC8088811082A884448040804087FE8000003F8020003F8020003F80000
+CB2A:00007BC8088811082A884448040804087FE8000000000FF8022002200FF80000
+CB2B:00007BC8088811082A884448040804087FE8000000800FF803E0041003E00000
+CB2C:0000000000001EE0022002200640054008A037500440044004407FFC00000000
+CB2D:00003DE00440088015402220044004407FFC00001FF000100010001000100000
+CB2E:00003DE00440088015402220044004407FFC000000003EF80208020802080000
+CB2F:00003DE00440088015402220044004407FFC000000001E100210022802C40000
+CB30:00003DE00440088015402220044004407FFC000000001000100010001FF00000
+CB31:00003DE00440088015402220044004407FFC0000000020F8201020303ECC0000
+CB32:00003DE00440088015402220044004407FFC0000202021FC207020883E700000
+CB33:00003DE00440088015402220044004407FFC00001FF01000100010001FF00000
+CB34:00003DE00440088015402220044004407FFC00001FF000101FF010001FF00000
+CB35:00003DE00440088015402220044004407FFC00003EF802083E0820083E080000
+CB36:00003DE00440088015402220044004407FFC00003EF802883E8820883EF80000
+CB37:00003DE00440088015402220044004407FFC00003E8802883EF820883EF80000
+CB38:00003DE00440088015402220044004407FFC00003E1002103E1020283EC40000
+CB39:00003DE00440088015402220044004407FFC00003EF802803EF820803EF80000
+CB3A:00003DE00440088015402220044004407FFC00003EFC02483E4820483EFC0000
+CB3B:00003DE00440088015402220044004407FFC00003E2003FC3E7020883E700000
+CB3C:00003DE00440088015402220044004407FFC00001FF01010101010101FF00000
+CB3D:00003DE00440088015402220044004407FFC0000101010101FF010101FF00000
+CB3E:00003DE00440088015402220044004407FFC0000222022203E2022503E880000
+CB3F:00003DE00440088015402220044004407FFC000000000100010002800C400000
+CB40:00003DE00440088015402220044004407FFC00000000024002400DA033100000
+CB41:00003DE00440088015402220044004407FFC0000000007C00820082007C00000
+CB42:00003DE00440088015402220044004407FFC0000000007E00080014006200000
+CB43:00003DE00440088015402220044004407FFC0000008007E00080014006200000
+CB44:00003DE00440088015402220044004407FFC00001FF000101FF0001000100000
+CB45:00003DE00440088015402220044004407FFC00001FF010001FF010001FF00000
+CB46:00003DE00440088015402220044004407FFC000000001FF0044004401FF00000
+CB47:00003DE00440088015402220044004407FFC000001001FF007C0082007C00000
+CB48:000000001EE0022002200640054008A0331000003FF801000100010001000000
+CB49:00003DE0044008801540222000007FFC010001001FF000100010001000100000
+CB4A:00003DE0044008801540222000007FFC0100010000003EF80208020802080000
+CB4B:00003DE0044008801540222000007FFC0100010000001E100210022802C40000
+CB4C:00003DE00440088015402220000000007FFC010001001100100010001FF00000
+CB4D:00003DE0044008801540222000007FFC01000100000020F8201020303ECC0000
+CB4E:00003DE0044008801540222000007FFC01000100202021FC207020883E700000
+CB4F:00003DE0044008801540222000007FFC010001001FF01000100010001FF00000
+CB50:00003DE0044008801540222000007FFC010001001FF000101FF010001FF00000
+CB51:00003DE0044008801540222000007FFC010001003EF802083E0820083E080000
+CB52:00003DE0044008801540222000007FFC010001003EF802883E8820883EF80000
+CB53:00003DE0044008801540222000007FFC010001003E8802883EF820883EF80000
+CB54:00003DE0044008801540222000007FFC010001003E1002103E1020283EC40000
+CB55:00003DE0044008801540222000007FFC010001003EF802803EF820803EF80000
+CB56:00003DE0044008801540222000007FFC010001003EFC02483E4820483EFC0000
+CB57:00003DE0044008801540222000007FFC010001003E2003FC3E7020883E700000
+CB58:00003DE0044008801540222000007FFC010001001FF01010101010101FF00000
+CB59:00003DE0044008801540222000007FFC01000100101010101FF010101FF00000
+CB5A:00003DE0044008801540222000007FFC01000100222022203E2022503E880000
+CB5B:00003DE0044008801540222000007FFC0100010000000100010002800C400000
+CB5C:00003DE0044008801540222000007FFC010001000000024002400DA033100000
+CB5D:00003DE0044008801540222000007FFC01000100000007C00820082007C00000
+CB5E:00003DE0044008801540222000007FFC01000100000007E00080014006200000
+CB5F:00003DE0044008801540222000007FFC01000100008007E00080014006200000
+CB60:00003DE0044008801540222000007FFC010001001FF000101FF0001000100000
+CB61:00003DE0044008801540222000007FFC010001001FF010001FF010001FF00000
+CB62:00003DE0044008801540222000007FFC0100010000001FF0044004401FF00000
+CB63:00003DE0044008801540222000007FFC0100010001001FF007C0082007C00000
+CB64:000000087B8808880888190815082288CC4800087FE8040804F8040804080000
+CB65:7BC8088811082A88444800087FE8027802080000000007F80008000800080000
+CB66:7BC8088811082A88444800087FE802780208000000003EF80208020802080000
+CB67:7BC8088811082A88444800087FE802780208000000001F080108011401620000
+CB68:7BC8088811082A884448000800087FE80278020802081000100010001FF80000
+CB69:7BC8088811082A88444800087FE8027802080000000020F8201020303ECC0000
+CB6A:7BC8088811082A88444800087FE8027802080000202021FC207020883E700000
+CB6B:7BC8088811082A88444800087FE802780208000003F802000200020003F80000
+CB6C:7BC8088811082A88444800087FE802780208000007F8000807F8040007F80000
+CB6D:7BC8088811082A88444800087FE80278020800003EF802083E0820083E080000
+CB6E:7BC8088811082A88444800087FE80278020800003EF802883E8820883EF80000
+CB6F:7BC8088811082A88444800087FE80278020800003E8802883EF820883EF80000
+CB70:7BC8088811082A88444800087FE80278020800000F8800880F8808140FA20000
+CB71:7BC8088811082A88444800087FE80278020800003EF802803EF820803EF80000
+CB72:7BC8088811082A88444800087FE80278020800003EFC02483E4820483EFC0000
+CB73:7BC8088811082A88444800087FE80278020800003E1002FE3E3820443E380000
+CB74:7BC8088811082A88444800087FE802780208000003F802080208020803F80000
+CB75:7BC8088811082A88444800087FE80278020800000208020803F8020803F80000
+CB76:7BC8088811082A88444800087FE8027802080000210821083F0821143F620000
+CB77:7BC8088811082A88444800087FE8027802080000001000100010006801840000
+CB78:7BC8088811082A88444800087FE80278020800000048004800A8011406620000
+CB79:7BC8088811082A88444800087FE8027802080000000003F00408040803F00000
+CB7A:7BC8088811082A88444800087FE802780208000003F80020002000D003080000
+CB7B:7BC8088811082A88444800087FE8027802080000004003F8004000A003180000
+CB7C:7BC8088811082A88444800087FE802780208000003F8000803F8000800080000
+CB7D:7BC8088811082A88444800087FE802780208000003F8020003F8020003F80000
+CB7E:7BC8088811082A88444800087FE802780208000000000FF8022002200FF80000
+CB7F:7BC8088811082A88444800087FE802780208000000800FF803E0041003E00000
+CB80:0000000A7B8A088A088A190A150A228ACC4A000A7FEA040A047A040A040A0000
+CB81:7BE808A811282AA8446800287FA805E804280000000007F80008000800080000
+CB82:7BE808A811282AA8446800287FA805E80428000000003EF80208020802080000
+CB83:7BE808A811282AA8446800287FA805E80428000000001F080108011401620000
+CB84:7BE808A811282AA84468002800287FA8042805E804281428100010001FF80000
+CB85:7BE808A811282AA8446800287FA805E804280000000020F8201020303ECC0000
+CB86:7BE808A811282AA8446800287FA805E804280000202021FC207020883E700000
+CB87:7BE808A811282AA8446800287FA805E80428000003F802000200020003F80000
+CB88:7BE808A811282AA8446800287FA805E80428000007F8000807F8040007F80000
+CB89:7BE808A811282AA8446800287FA805E8042800003EF802083E0820083E080000
+CB8A:7BE808A811282AA8446800287FA805E8042800003EF802883E8820883EF80000
+CB8B:7BE808A811282AA8446800287FA805E8042800003E8802883EF820883EF80000
+CB8C:7BE808A811282AA8446800287FA805E8042800000F8800880F8808140FA20000
+CB8D:7BE808A811282AA8446800287FA805E8042800003EF802803EF820803EF80000
+CB8E:7BE808A811282AA8446800287FA805E8042800003EFC02483E4820483EFC0000
+CB8F:7BE808A811282AA8446800287FA805E8042800003E1002FE3E3820443E380000
+CB90:7BE808A811282AA8446800287FA805E80428000003F802080208020803F80000
+CB91:7BE808A811282AA8446800287FA805E8042800000208020803F8020803F80000
+CB92:7BE808A811282AA8446800287FA805E804280000210821083F0821143F620000
+CB93:7BE808A811282AA8446800287FA805E804280000001000100010006801840000
+CB94:7BE808A811282AA8446800287FA805E8042800000048004800A8011406620000
+CB95:7BE808A811282AA8446800287FA805E804280000000003F00408040803F00000
+CB96:7BE808A811282AA8446800287FA805E80428000003F80020002000D003080000
+CB97:7BE808A811282AA8446800287FA805E804280000004003F8004000A003180000
+CB98:7BE808A811282AA8446800287FA805E80428000003F8000803F8000800080000
+CB99:7BE808A811282AA8446800287FA805E80428000003F8020003F8020003F80000
+CB9A:7BE808A811282AA8446800287FA805E80428000000000FF8022002200FF80000
+CB9B:7BE808A811282AA8446800287FA805E80428000000800FF803E0041003E00000
+CB9C:000000087B8808880888190815082288CC4800087FE804080408040804080000
+CB9D:7BC8088811082A88444800087FE8020802000000000007F80008000800080000
+CB9E:7BC8088811082A88444800087FE802080200000000003EF80208020802080000
+CB9F:7BC8088811082A88444800087FE802080200000000001F080108011401620000
+CBA0:7BC8088811082A884448000800087FE80208020802081008100010001FF80000
+CBA1:7BC8088811082A88444800087FE8020802000000000020F8201020303ECC0000
+CBA2:7BC8088811082A88444800087FE8020802000000202021FC207020883E700000
+CBA3:7BC8088811082A88444800087FE802080200000003F802000200020003F80000
+CBA4:7BC8088811082A88444800087FE802080200000007F8000807F8040007F80000
+CBA5:7BC8088811082A88444800087FE80208020000003EF802083E0820083E080000
+CBA6:7BC8088811082A88444800087FE80208020000003EF802883E8820883EF80000
+CBA7:7BC8088811082A88444800087FE80208020000003E8802883EF820883EF80000
+CBA8:7BC8088811082A88444800087FE80208020000000F8800880F8808140FA20000
+CBA9:7BC8088811082A88444800087FE80208020000003EF802803EF820803EF80000
+CBAA:7BC8088811082A88444800087FE80208020000003EFC02483E4820483EFC0000
+CBAB:7BC8088811082A88444800087FE80208020000003E1002FE3E3820443E380000
+CBAC:7BC8088811082A88444800087FE802080200000003F802080208020803F80000
+CBAD:7BC8088811082A88444800087FE80208020000000208020803F8020803F80000
+CBAE:7BC8088811082A88444800087FE8020802000000210821083F0821143F620000
+CBAF:7BC8088811082A88444800087FE8020802000000001000100010006801840000
+CBB0:7BC8088811082A88444800087FE80208020000000048004800A8011406620000
+CBB1:7BC8088811082A88444800087FE8020802000000000003F00408040803F00000
+CBB2:7BC8088811082A88444800087FE802080200000003F80020002000D003080000
+CBB3:7BC8088811082A88444800087FE8020802000000004003F8004000A003180000
+CBB4:7BC8088811082A88444800087FE802080200000003F8000803F8000800080000
+CBB5:7BC8088811082A88444800087FE802080200000003F8020003F8020003F80000
+CBB6:7BC8088811082A88444800087FE802080200000000000FF8022002200FF80000
+CBB7:7BC8088811082A88444800087FE802080200000000800FF803E0041003E00000
+CBB8:000000001EE0022002200640054008A0331000007FFC04400440044004400000
+CBB9:00003DE0044008801540222000007FFC044004401FF000100010001000100000
+CBBA:00003DE0044008801540222000007FFC0440044000003EF80208020802080000
+CBBB:00003DE0044008801540222000007FFC0440044000001E100210022802C40000
+CBBC:00003DE00440088015402220000000007FFC044004401440100010001FF00000
+CBBD:00003DE0044008801540222000007FFC04400440000020F8201020303ECC0000
+CBBE:00003DE0044008801540222000007FFC04400440202021FC207020883E700000
+CBBF:00003DE0044008801540222000007FFC044004401FF01000100010001FF00000
+CBC0:00003DE0044008801540222000007FFC044004401FF000101FF010001FF00000
+CBC1:00003DE0044008801540222000007FFC044004403EF802083E0820083E080000
+CBC2:00003DE0044008801540222000007FFC044004403EF802883E8820883EF80000
+CBC3:00003DE0044008801540222000007FFC044004403E8802883EF820883EF80000
+CBC4:00003DE0044008801540222000007FFC044004403E1002103E1020283EC40000
+CBC5:00003DE0044008801540222000007FFC044004403EF802803EF820803EF80000
+CBC6:00003DE0044008801540222000007FFC044004403EFC02483E4820483EFC0000
+CBC7:00003DE0044008801540222000007FFC044004403E2003FC3E7020883E700000
+CBC8:00003DE0044008801540222000007FFC044004401FF01010101010101FF00000
+CBC9:00003DE0044008801540222000007FFC04400440101010101FF010101FF00000
+CBCA:00003DE0044008801540222000007FFC04400440222022203E2022503E880000
+CBCB:00003DE0044008801540222000007FFC0440044000000100010002800C400000
+CBCC:00003DE0044008801540222000007FFC044004400000024002400DA033100000
+CBCD:00003DE0044008801540222000007FFC04400440000007C00820082007C00000
+CBCE:00003DE0044008801540222000007FFC04400440000007E00080014006200000
+CBCF:00003DE0044008801540222000007FFC04400440008007E00080014006200000
+CBD0:00003DE0044008801540222000007FFC044004401FF000101FF0001000100000
+CBD1:00003DE0044008801540222000007FFC044004401FF010001FF010001FF00000
+CBD2:00003DE0044008801540222000007FFC0440044000001FF0044004401FF00000
+CBD3:00003DE0044008801540222000007FFC0440044001001FF007C0082007C00000
+CBD4:0000000000001EE0022002200640054008A0331000007FFC0000000000000000
+CBD5:00003DE00440088015402220000000007FFC00001FF000100010001000100000
+CBD6:00003DE00440088015402220000000007FFC000000003EF80208020802080000
+CBD7:00003DE00440088015402220000000007FFC000000001E100210022802C40000
+CBD8:00003DE00440088015402220000000007FFC000000001000100010001FF00000
+CBD9:00003DE00440088015402220000000007FFC0000000020F8201020303ECC0000
+CBDA:00003DE00440088015402220000000007FFC0000202021FC207020883E700000
+CBDB:00003DE00440088015402220000000007FFC00001FF01000100010001FF00000
+CBDC:00003DE00440088015402220000000007FFC00001FF000101FF010001FF00000
+CBDD:00003DE00440088015402220000000007FFC00003EF802083E0820083E080000
+CBDE:00003DE00440088015402220000000007FFC00003EF802883E8820883EF80000
+CBDF:00003DE00440088015402220000000007FFC00003E8802883EF820883EF80000
+CBE0:00003DE00440088015402220000000007FFC00003E1002103E1020283EC40000
+CBE1:00003DE00440088015402220000000007FFC00003EF802803EF820803EF80000
+CBE2:00003DE00440088015402220000000007FFC00003EFC02483E4820483EFC0000
+CBE3:00003DE00440088015402220000000007FFC00003E2003FC3E7020883E700000
+CBE4:00003DE00440088015402220000000007FFC00001FF01010101010101FF00000
+CBE5:00003DE00440088015402220000000007FFC0000101010101FF010101FF00000
+CBE6:00003DE00440088015402220000000007FFC0000222022203E2022503E880000
+CBE7:00003DE00440088015402220000000007FFC000000000100010002800C400000
+CBE8:00003DE00440088015402220000000007FFC00000000024002400DA033100000
+CBE9:00003DE00440088015402220000000007FFC0000000007C00820082007C00000
+CBEA:00003DE00440088015402220000000007FFC0000000007E00080014006200000
+CBEB:00003DE00440088015402220000000007FFC0000008007E00080014006200000
+CBEC:00003DE00440088015402220000000007FFC00001FF000101FF0001000100000
+CBED:00003DE00440088015402220000000007FFC00001FF010001FF010001FF00000
+CBEE:00003DE00440088015402220000000007FFC000000001FF0044004401FF00000
+CBEF:00003DE00440088015402220000000007FFC000001001FF007C0082007C00000
+CBF0:0000000800087B8808880888190815082288CC4800087FE80008000800080000
+CBF1:00007BC8088811082A884448000800087FE8000007F800080008000800080000
+CBF2:00007BC8088811082A884448000800087FE8000000003EF80208020802080000
+CBF3:00007BC8088811082A884448000800087FE8000000001F080108011401620000
+CBF4:00007BC8088811082A884448000800087FE8000008000800080008000FF80000
+CBF5:00007BC8088811082A884448000800087FE80000000010F8101010301ECC0000
+CBF6:00007BC8088811082A884448000800087FE800000808087F081C08220F9C0000
+CBF7:00007BC8088811082A884448000800087FE8000003F802000200020003F80000
+CBF8:00007BC8088811082A884448000800087FE8000007F8000807F8040007F80000
+CBF9:00007BC8088811082A884448000800087FE800003EF802083E0820083E080000
+CBFA:00007BC8088811082A884448000800087FE800003EF802883E8820883EF80000
+CBFB:00007BC8088811082A884448000800087FE800003E8802883EF820883EF80000
+CBFC:00007BC8088811082A884448000800087FE800001F0801081F0810141F620000
+CBFD:00007BC8088811082A884448000800087FE800003EF802803EF820803EF80000
+CBFE:00007BC8088811082A884448000800087FE800003EFC02483E4820483EFC0000
+CBFF:00007BC8088811082A884448000800087FE800001F08017F1F1C10221F1C0000
+CC00:00007BC8088811082A884448000800087FE8000003F802080208020803F80000
+CC01:00007BC8088811082A884448000800087FE800000208020803F8020803F80000
+CC02:00007BC8088811082A884448000800087FE80000110811081F0811141F620000
+CC03:00007BC8088811082A884448000800087FE80000001000100010006801840000
+CC04:00007BC8088811082A884448000800087FE800000048004800A8011406620000
+CC05:00007BC8088811082A884448000800087FE80000000003F00408040803F00000
+CC06:00007BC8088811082A884448000800087FE8000003F80020002000D003080000
+CC07:00007BC8088811082A884448000800087FE80000004003F8004000A003180000
+CC08:00007BC8088811082A884448000800087FE8000003F8000803F8000800080000
+CC09:00007BC8088811082A884448000800087FE8000003F8020003F8020003F80000
+CC0A:00007BC8088811082A884448000800087FE8000000000FF8022002200FF80000
+CC0B:00007BC8088811082A884448000800087FE8000000800FF803E0041003E00000
+CC0C:00000000000800087B8808880888190815082288CC4800080008000800080000
+CC0D:0000000800087708220822085508888800080000000007F80008000800080000
+CC0E:000000080008770822082208550888880008000000003EF80208020802080000
+CC0F:000000080008770822082208550888880008000000001F080108011401620000
+CC10:000000080008770822082208550888880008000800001000100010001FF80000
+CC11:0000000800087708220822085508888800080000000020F8201020303ECC0000
+CC12:0000000800087708220822085508888800080000202021FC207020883E700000
+CC13:000000080008770822082208550888880008000003F802000200020003F80000
+CC14:000000080008770822082208550888880008000007F8000807F8040007F80000
+CC15:00000008000877082208220855088888000800003EF802083E0820083E080000
+CC16:00000008000877082208220855088888000800003EF802883E8820883EF80000
+CC17:00000008000877082208220855088888000800003E8802883EF820883EF80000
+CC18:00000008000877082208220855088888000800000F8800880F8808140FA20000
+CC19:00000008000877082208220855088888000800003EF802803EF820803EF80000
+CC1A:00000008000877082208220855088888000800003EFC02483E4820483EFC0000
+CC1B:00000008000877082208220855088888000800003E1002FE3E3820443E380000
+CC1C:000000080008770822082208550888880008000003F802080208020803F80000
+CC1D:00000008000877082208220855088888000800000208020803F8020803F80000
+CC1E:0000000800087708220822085508888800080000210821083F0821143F620000
+CC1F:0000000800087708220822085508888800080000001000100010006801840000
+CC20:00000008000877082208220855088888000800000048004800A8011406620000
+CC21:0000000800087708220822085508888800080000000003F00408040803F00000
+CC22:000000080008770822082208550888880008000003F80020002000D003080000
+CC23:0000000800087708220822085508888800080000004003F8004000A003180000
+CC24:000000080008770822082208550888880008000003F8000803F8000800080000
+CC25:000000080008770822082208550888880008000003F8020003F8020003F80000
+CC26:000000080008770822082208550888880008000000000FF8022002200FF80000
+CC27:000000080008770822082208550888880008000000800FF803E0041003E00000
+CC28:000000000010041004103F900110021E06100910309000100010001000100000
+CC29:00000008000808087E08080E140862080008000007F800080008000800080000
+CC2A:00000008000808087E08080E140862080008000000003EF80208020802080000
+CC2B:00000008000808087E08080E140862080008000000001F080108011401620000
+CC2C:00000008000808087E08080E140862080008000808000800080008000FF80000
+CC2D:00000008000808087E08080E1408620800080000000010F8101010301ECC0000
+CC2E:00000008000808087E08080E14086208000800000808087F081C08220F9C0000
+CC2F:00000008000808087E08080E140862080008000003F802000200020003F80000
+CC30:00000008000808087E08080E140862080008000007F8000807F8040007F80000
+CC31:00000008000808087E08080E14086208000800003EF802083E0820083E080000
+CC32:00000008000808087E08080E14086208000800003EF802883E8820883EF80000
+CC33:00000008000808087E08080E14086208000800003E8802883EF820883EF80000
+CC34:00000008000808087E08080E14086208000800001F0801081F0810141F620000
+CC35:00000008000808087E08080E14086208000800003EF802803EF820803EF80000
+CC36:00000008000808087E08080E14086208000800003EFC02483E4820483EFC0000
+CC37:00000008000808087E08080E14086208000800001F08017F1F1C10221F1C0000
+CC38:00000008000808087E08080E140862080008000003F802080208020803F80000
+CC39:00000008000808087E08080E14086208000800000208020803F8020803F80000
+CC3A:00000008000808087E08080E1408620800080000110811081F0811141F620000
+CC3B:00000008000808087E08080E1408620800080000001000100010006801840000
+CC3C:00000008000808087E08080E14086208000800000048004800A8011406620000
+CC3D:00000008000808087E08080E1408620800080000000003F00408040803F00000
+CC3E:00000008000808087E08080E140862080008000003F80020002000D003080000
+CC3F:00000008000808087E08080E1408620800080000004003F8004000A003180000
+CC40:00000008000808087E08080E140862080008000003F8000803F8000800080000
+CC41:00000008000808087E08080E140862080008000003F8020003F8020003F80000
+CC42:00000008000808087E08080E140862080008000000000FF8022002200FF80000
+CC43:00000008000808087E08080E140862080008000000800FF803E0041003E00000
+CC44:000000000012041204123F920112021E06120912309200120012001200120000
+CC45:00000028002808287E280838142862280028000007F800080008000800080000
+CC46:00000028002808287E280838142862280028000000003EF80208020802080000
+CC47:00000028002808287E280838142862280028000000003E100210022802C40000
+CC48:00000028002808287E280838142862280028002808000800080008000FF80000
+CC49:00000028002808287E2808381428622800280000000020F8201020303ECC0000
+CC4A:00000028002808287E2808381428622800280000202021FC207020883E700000
+CC4B:00000028002808287E280838142862280028000003F802000200020003F80000
+CC4C:00000028002808287E280838142862280028000007F8000807F8040007F80000
+CC4D:00000028002808287E28083814286228002800003EF802083E0820083E080000
+CC4E:00000028002808287E28083814286228002800003EF802883E8820883EF80000
+CC4F:00000028002808287E28083814286228002800003E8802883EF820883EF80000
+CC50:00000028002808287E28083814286228002800001F0801081F0810141F620000
+CC51:00000028002808287E28083814286228002800003EF802803EF820803EF80000
+CC52:00000028002808287E28083814286228002800003EFC02483E4820483EFC0000
+CC53:00000028002808287E28083814286228002800003E1002FE3E3820443E380000
+CC54:00000028002808287E280838142862280028000003F802080208020803F80000
+CC55:00000028002808287E28083814286228002800000208020803F8020803F80000
+CC56:00000028002808287E2808381428622800280000110811081F0811141F620000
+CC57:00000028002808287E2808381428622800280000000800080008003400C20000
+CC58:00000028002808287E28083814286228002800000048004800A8011406620000
+CC59:00000028002808287E2808381428622800280000000001F00208020801F00000
+CC5A:00000028002808287E280838142862280028000003F80020002000D003080000
+CC5B:00000028002808287E2808381428622800280000004003F8004000A003180000
+CC5C:00000028002808287E280838142862280028000003F8000803F8000800080000
+CC5D:00000028002808287E280838142862280028000003F8020003F8020003F80000
+CC5E:00000028002808287E280838142862280028000000000FF8022002200FF80000
+CC5F:00000028002808287E280838142862280028000000800FF803E0041003E00000
+CC60:000000000010041004103F90011E02100610091E309000100010001000100000
+CC61:00000008000808087E0E0808140E62080008000007F800080008000800080000
+CC62:00000008000808087E0E0808140E62080008000000003EF80208020802080000
+CC63:00000008000808087E0E0808140E62080008000000001F080108011401620000
+CC64:00000008000808087E0E0808140E62080008000008000800080008000FF80000
+CC65:00000008000808087E0E0808140E620800080000000010F8101010301ECC0000
+CC66:00000008000808087E0E0808140E6208000800000808087F081C08220F9C0000
+CC67:00000008000808087E0E0808140E62080008000003F802000200020003F80000
+CC68:00000008000808087E0E0808140E62080008000007F8000807F8040007F80000
+CC69:00000008000808087E0E0808140E6208000800003EF802083E0820083E080000
+CC6A:00000008000808087E0E0808140E6208000800003EF802883E8820883EF80000
+CC6B:00000008000808087E0E0808140E6208000800003E8802883EF820883EF80000
+CC6C:00000008000808087E0E0808140E6208000800001F0801081F0810141F620000
+CC6D:00000008000808087E0E0808140E6208000800003EF802803EF820803EF80000
+CC6E:00000008000808087E0E0808140E6208000800003EFC02483E4820483EFC0000
+CC6F:00000008000808087E0E0808140E6208000800001F08017F1F1C10221F1C0000
+CC70:00000008000808087E0E0808140E62080008000003F802080208020803F80000
+CC71:00000008000808087E0E0808140E6208000800000208020803F8020803F80000
+CC72:00000008000808087E0E0808140E620800080000110811081F0811141F620000
+CC73:00000008000808087E0E0808140E620800080000001000100010006801840000
+CC74:00000008000808087E0E0808140E6208000800000048004800A8011406620000
+CC75:00000008000808087E0E0808140E620800080000000003F00408040803F00000
+CC76:00000008000808087E0E0808140E62080008000003F80020002000D003080000
+CC77:00000008000808087E0E0808140E620800080000004003F8004000A003180000
+CC78:00000008000808087E0E0808140E62080008000003F8000803F8000800080000
+CC79:00000008000808087E0E0808140E62080008000003F8020003F8020003F80000
+CC7A:00000008000808087E0E0808140E62080008000000000FF8022002200FF80000
+CC7B:00000008000808087E0E0808140E62080008000000800FF803E0041003E00000
+CC7C:000000000012041204123F92011E02120612091E309200120012001200120000
+CC7D:00000028002808287E380828143862280028000007F800080008000800080000
+CC7E:00000028002808287E380828143862280028000000003EF80208020802080000
+CC7F:00000028002808287E380828143862280028000000003E100210022802C40000
+CC80:00000028002808287E380828143862280028002808000800080008000FF80000
+CC81:00000028002808287E3808281438622800280000000020F8201020303ECC0000
+CC82:00000028002808287E3808281438622800280000202021FC207020883E700000
+CC83:00000028002808287E380828143862280028000003F802000200020003F80000
+CC84:00000028002808287E380828143862280028000007F8000807F8040007F80000
+CC85:00000028002808287E38082814386228002800003EF802083E0820083E080000
+CC86:00000028002808287E38082814386228002800003EF802883E8820883EF80000
+CC87:00000028002808287E38082814386228002800003E8802883EF820883EF80000
+CC88:00000028002808287E38082814386228002800001F0801081F0810141F620000
+CC89:00000028002808287E38082814386228002800003EF802803EF820803EF80000
+CC8A:00000028002808287E38082814386228002800003EFC02483E4820483EFC0000
+CC8B:00000028002808287E38082814386228002800003E1002FE3E3820443E380000
+CC8C:00000028002808287E380828143862280028000003F802080208020803F80000
+CC8D:00000028002808287E38082814386228002800000208020803F8020803F80000
+CC8E:00000028002808287E3808281438622800280000110811081F0811141F620000
+CC8F:00000028002808287E3808281438622800280000000800080008003400C20000
+CC90:00000028002808287E38082814386228002800000048004800A8011406620000
+CC91:00000028002808287E3808281438622800280000000001F00208020801F00000
+CC92:00000028002808287E380828143862280028000003F80020002000D003080000
+CC93:00000028002808287E3808281438622800280000004003F8004000A003180000
+CC94:00000028002808287E380828143862280028000003F8000803F8000800080000
+CC95:00000028002808287E380828143862280028000003F8020003F8020003F80000
+CC96:00000028002808287E380828143862280028000000000FF8022002200FF80000
+CC97:00000028002808287E380828143862280028000000800FF803E0041003E00000
+CC98:000000000002040204023F820102021E06020902308200020002000200020000
+CC99:00000008000808087E0808381408620800080000000007F80008000800080000
+CC9A:00000008000808087E080838140862080008000000003EF80208020802080000
+CC9B:00000008000808087E080838140862080008000000001F080108011401620000
+CC9C:00000008000808087E080838140862080008000000001000100010001FF80000
+CC9D:00000008000808087E0808381408620800080000000020F8201020303ECC0000
+CC9E:00000008000808087E0808381408620800080000202021FC207020883E700000
+CC9F:00000008000808087E080838140862080008000003F802000200020003F80000
+CCA0:00000008000808087E080838140862080008000007F8000807F8040007F80000
+CCA1:00000008000808087E08083814086208000800003EF802083E0820083E080000
+CCA2:00000008000808087E08083814086208000800003EF802883E8820883EF80000
+CCA3:00000008000808087E08083814086208000800003E8802883EF820883EF80000
+CCA4:00000008000808087E08083814086208000800000F8800880F8808140FA20000
+CCA5:00000008000808087E08083814086208000800003EF802803EF820803EF80000
+CCA6:00000008000808087E08083814086208000800003EFC02483E4820483EFC0000
+CCA7:00000008000808087E08083814086208000800003E1002FE3E3820443E380000
+CCA8:00000008000808087E080838140862080008000003F802080208020803F80000
+CCA9:00000008000808087E08083814086208000800000208020803F8020803F80000
+CCAA:00000008000808087E0808381408620800080000210821083F0821143F620000
+CCAB:00000008000808087E0808381408620800080000001000100010006801840000
+CCAC:00000008000808087E08083814086208000800000048004800A8011406620000
+CCAD:00000008000808087E0808381408620800080000000003F00408040803F00000
+CCAE:00000008000808087E080838140862080008000003F80020002000D003080000
+CCAF:00000008000808087E0808381408620800080000004003F8004000A003180000
+CCB0:00000008000808087E080838140862080008000003F8000803F8000800080000
+CCB1:00000008000808087E080838140862080008000003F8020003F8020003F80000
+CCB2:00000008000808087E080838140862080008000000000FF8022002200FF80000
+CCB3:00000008000808087E080838140862080008000000800FF803E0041003E00000
+CCB4:00000000000A040A040A3F8A010A023A060A090A308A000A000A000A000A0000
+CCB5:00000028002808287E2808E8142862280028000007F800080008000800080000
+CCB6:00000028002808287E2808E8142862280028000000003EF80208020802080000
+CCB7:00000028002808287E2808E8142862280028000000003E100210022802C40000
+CCB8:00000028002808287E2808E8142862280028000008000800080008000FF80000
+CCB9:00000028002808287E2808E81428622800280000000020F8201020303ECC0000
+CCBA:00000028002808287E2808E81428622800280000202021FC207020883E700000
+CCBB:00000028002808287E2808E8142862280028000003F802000200020003F80000
+CCBC:00000028002808287E2808E8142862280028000007F8000807F8040007F80000
+CCBD:00000028002808287E2808E814286228002800003EF802083E0820083E080000
+CCBE:00000028002808287E2808E814286228002800003EF802883E8820883EF80000
+CCBF:00000028002808287E2808E814286228002800003E8802883EF820883EF80000
+CCC0:00000028002808287E2808E814286228002800001F0801081F0810141F620000
+CCC1:00000028002808287E2808E814286228002800003EF802803EF820803EF80000
+CCC2:00000028002808287E2808E814286228002800003EFC02483E4820483EFC0000
+CCC3:00000028002808287E2808E814286228002800003E1002FE3E3820443E380000
+CCC4:00000028002808287E2808E8142862280028000003F802080208020803F80000
+CCC5:00000028002808287E2808E814286228002800000208020803F8020803F80000
+CCC6:00000028002808287E2808E81428622800280000110811081F0811141F620000
+CCC7:00000028002808287E2808E81428622800280000000800080008003400C20000
+CCC8:00000028002808287E2808E814286228002800000048004800A8011406620000
+CCC9:00000028002808287E2808E81428622800280000000001F00208020801F00000
+CCCA:00000028002808287E2808E8142862280028000003F80020002000D003080000
+CCCB:00000028002808287E2808E81428622800280000004003F8004000A003180000
+CCCC:00000028002808287E2808E8142862280028000003F8000803F8000800080000
+CCCD:00000028002808287E2808E8142862280028000003F8020003F8020003F80000
+CCCE:00000028002808287E2808E8142862280028000000000FF8022002200FF80000
+CCCF:00000028002808287E2808E8142862280028000000800FF803E0041003E00000
+CCD0:000000000002040204023F82011E02020602091E308200020002000200020000
+CCD1:00000008000808087E3808081438620800080000000007F80008000800080000
+CCD2:00000008000808087E380808143862080008000000003EF80208020802080000
+CCD3:00000008000808087E380808143862080008000000001F080108011401620000
+CCD4:00000008000808087E380808143862080008000800001000100010001FF80000
+CCD5:00000008000808087E3808081438620800080000000020F8201020303ECC0000
+CCD6:00000008000808087E3808081438620800080000202021FC207020883E700000
+CCD7:00000008000808087E380808143862080008000003F802000200020003F80000
+CCD8:00000008000808087E380808143862080008000007F8000807F8040007F80000
+CCD9:00000008000808087E38080814386208000800003EF802083E0820083E080000
+CCDA:00000008000808087E38080814386208000800003EF802883E8820883EF80000
+CCDB:00000008000808087E38080814386208000800003E8802883EF820883EF80000
+CCDC:00000008000808087E38080814386208000800000F8800880F8808140FA20000
+CCDD:00000008000808087E38080814386208000800003EF802803EF820803EF80000
+CCDE:00000008000808087E38080814386208000800003EFC02483E4820483EFC0000
+CCDF:00000008000808087E38080814386208000800003E1002FE3E3820443E380000
+CCE0:00000008000808087E380808143862080008000003F802080208020803F80000
+CCE1:00000008000808087E38080814386208000800000208020803F8020803F80000
+CCE2:00000008000808087E3808081438620800080000210821083F0821143F620000
+CCE3:00000008000808087E3808081438620800080000001000100010006801840000
+CCE4:00000008000808087E38080814386208000800000048004800A8011406620000
+CCE5:00000008000808087E3808081438620800080000000003F00408040803F00000
+CCE6:00000008000808087E380808143862080008000003F80020002000D003080000
+CCE7:00000008000808087E3808081438620800080000004003F8004000A003180000
+CCE8:00000008000808087E380808143862080008000003F8000803F8000800080000
+CCE9:00000008000808087E380808143862080008000003F8020003F8020003F80000
+CCEA:00000008000808087E380808143862080008000000000FF8022002200FF80000
+CCEB:00000008000808087E380808143862080008000000800FF803E0041003E00000
+CCEC:00000000000A040A040A3F8A013A020A060A093A308A000A000A000A000A0000
+CCED:00000028002808287EE8082814E862280028000007F800080008000800080000
+CCEE:00000028002808287EE8082814E862280028000000003EF80208020802080000
+CCEF:00000028002808287EE8082814E862280028000000003E100210022802C40000
+CCF0:00000028002808287EE8082814E862280028002808000800080008000FF80000
+CCF1:00000028002808287EE8082814E8622800280000000020F8201020303ECC0000
+CCF2:00000028002808287EE8082814E8622800280000202021FC207020883E700000
+CCF3:00000028002808287EE8082814E862280028000003F802000200020003F80000
+CCF4:00000028002808287EE8082814E862280028000007F8000807F8040007F80000
+CCF5:00000028002808287EE8082814E86228002800003EF802083E0820083E080000
+CCF6:00000028002808287EE8082814E86228002800003EF802883E8820883EF80000
+CCF7:00000028002808287EE8082814E86228002800003E8802883EF820883EF80000
+CCF8:00000028002808287EE8082814E86228002800001F0801081F0810141F620000
+CCF9:00000028002808287EE8082814E86228002800003EF802803EF820803EF80000
+CCFA:00000028002808287EE8082814E86228002800003EFC02483E4820483EFC0000
+CCFB:00000028002808287EE8082814E86228002800003E1002FE3E3820443E380000
+CCFC:00000028002808287EE8082814E862280028000003F802080208020803F80000
+CCFD:00000028002808287EE8082814E86228002800000208020803F8020803F80000
+CCFE:00000028002808287EE8082814E8622800280000110811081F0811141F620000
+CCFF:00000028002808287EE8082814E8622800280000000800080008003400C20000
+CD00:00000028002808287EE8082814E86228002800000048004800A8011406620000
+CD01:00000028002808287EE8082814E8622800280000000001F00208020801F00000
+CD02:00000028002808287EE8082814E862280028000003F80020002000D003080000
+CD03:00000028002808287EE8082814E8622800280000004003F8004000A003180000
+CD04:00000028002808287EE8082814E862280028000003F8000803F8000800080000
+CD05:00000028002808287EE8082814E862280028000003F8020003F8020003F80000
+CD06:00000028002808287EE8082814E862280028000000000FF8022002200FF80000
+CD07:00000028002808287EE8082814E862280028000000800FF803E0041003E00000
+CD08:0000010001000FE000400080018002400C2000000100010001007FFC00000000
+CD09:000001000FC0010002800C40010001007FFC00001FF000100010001000100000
+CD0A:000001000FC0010002800C40010001007FFC000000003EF80208020802080000
+CD0B:000001000FC0010002800C40010001007FFC000000001E100210022802C40000
+CD0C:000001000FC0010002800C40010001007FFC000000001000100010001FF00000
+CD0D:000001000FC0010002800C40010001007FFC0000000020F8201020303ECC0000
+CD0E:000001000FC0010002800C40010001007FFC0000202021FC207020883E700000
+CD0F:000001000FC0010002800C40010001007FFC00001FF01000100010001FF00000
+CD10:000001000FC0010002800C40010001007FFC00001FF000101FF010001FF00000
+CD11:000001000FC0010002800C40010001007FFC00003EF802083E0820083E080000
+CD12:000001000FC0010002800C40010001007FFC00003EF802883E8820883EF80000
+CD13:000001000FC0010002800C40010001007FFC00003E8802883EF820883EF80000
+CD14:000001000FC0010002800C40010001007FFC00003E1002103E1020283EC40000
+CD15:000001000FC0010002800C40010001007FFC00003EF802803EF820803EF80000
+CD16:000001000FC0010002800C40010001007FFC00003EFC02483E4820483EFC0000
+CD17:000001000FC0010002800C40010001007FFC00003E2003FC3E7020883E700000
+CD18:000001000FC0010002800C40010001007FFC00001FF01010101010101FF00000
+CD19:000001000FC0010002800C40010001007FFC0000101010101FF010101FF00000
+CD1A:000001000FC0010002800C40010001007FFC0000222022203E2022503E880000
+CD1B:000001000FC0010002800C40010001007FFC000000000100010002800C400000
+CD1C:000001000FC0010002800C40010001007FFC00000000024002400DA033100000
+CD1D:000001000FC0010002800C40010001007FFC0000000007C00820082007C00000
+CD1E:000001000FC0010002800C40010001007FFC0000000007E00080014006200000
+CD1F:000001000FC0010002800C40010001007FFC0000008007E00080014006200000
+CD20:000001000FC0010002800C40010001007FFC00001FF000101FF0001000100000
+CD21:000001000FC0010002800C40010001007FFC00001FF010001FF010001FF00000
+CD22:000001000FC0010002800C40010001007FFC000000001FF0044004401FF00000
+CD23:000001000FC0010002800C40010001007FFC000001001FF007C0082007C00000
+CD24:00000010041004103F9001100210061E09103090041004107FD0001000100000
+CD25:000002081F880208050E1888040804087FE8000007F800080008000800080000
+CD26:000002081F880208050E1888040804087FE8000000003EF80208020802080000
+CD27:000002081F880208050E1888040804087FE8000000001F080108011401620000
+CD28:000002081F880208050E1888040804087FE8000008000800080008000FF80000
+CD29:000002081F880208050E1888040804087FE80000000010F8101010301ECC0000
+CD2A:000002081F880208050E1888040804087FE800000808087F081C08220F9C0000
+CD2B:000002081F880208050E1888040804087FE8000003F802000200020003F80000
+CD2C:000002081F880208050E1888040804087FE8000007F8000807F8040007F80000
+CD2D:000002081F880208050E1888040804087FE800003EF802083E0820083E080000
+CD2E:000002081F880208050E1888040804087FE800003EF802883E8820883EF80000
+CD2F:000002081F880208050E1888040804087FE800003E8802883EF820883EF80000
+CD30:000002081F880208050E1888040804087FE800001F0801081F0810141F620000
+CD31:000002081F880208050E1888040804087FE800003EF802803EF820803EF80000
+CD32:000002081F880208050E1888040804087FE800003EFC02483E4820483EFC0000
+CD33:000002081F880208050E1888040804087FE800001F08017F1F1C10221F1C0000
+CD34:000002081F880208050E1888040804087FE8000003F802080208020803F80000
+CD35:000002081F880208050E1888040804087FE800000208020803F8020803F80000
+CD36:000002081F880208050E1888040804087FE80000110811081F0811141F620000
+CD37:000002081F880208050E1888040804087FE80000001000100010006801840000
+CD38:000002081F880208050E1888040804087FE800000048004800A8011406620000
+CD39:000002081F880208050E1888040804087FE80000000003F00408040803F00000
+CD3A:000002081F880208050E1888040804087FE8000003F80020002000D003080000
+CD3B:000002081F880208050E1888040804087FE80000004003F8004000A003180000
+CD3C:000002081F880208050E1888040804087FE8000003F8000803F8000800080000
+CD3D:000002081F880208050E1888040804087FE8000003F8020003F8020003F80000
+CD3E:000002081F880208050E1888040804087FE8000000000FF8022002200FF80000
+CD3F:000002081F880208050E1888040804087FE8000000800FF803E0041003E00000
+CD40:00000012041204123F9201120212061E09123092041204127FD2001200120000
+CD41:000002281FA80228053818A8042804287FA8000007F800080008000800080000
+CD42:000002281FA80228053818A8042804287FA8000000003EF80208020802080000
+CD43:000002281FA80228053818A8042804287FA8000000001F080108011401620000
+CD44:000002281FA80228053818A8042804287FA8000008000800080008000FF80000
+CD45:000002281FA80228053818A8042804287FA80000000010F8101010301ECC0000
+CD46:000002281FA80228053818A8042804287FA800000808087F081C08220F9C0000
+CD47:000002281FA80228053818A8042804287FA8000003F802000200020003F80000
+CD48:000002281FA80228053818A8042804287FA8000007F8000807F8040007F80000
+CD49:000002281FA80228053818A8042804287FA800003EF802083E0820083E080000
+CD4A:000002281FA80228053818A8042804287FA800003EF802883E8820883EF80000
+CD4B:000002281FA80228053818A8042804287FA800003E8802883EF820883EF80000
+CD4C:000002281FA80228053818A8042804287FA800001F0801081F0810141F620000
+CD4D:000002281FA80228053818A8042804287FA800003EF802803EF820803EF80000
+CD4E:000002281FA80228053818A8042804287FA800003EFC02483E4820483EFC0000
+CD4F:000002281FA80228053818A8042804287FA800001F08017F1F1C10221F1C0000
+CD50:000002281FA80228053818A8042804287FA8000003F802080208020803F80000
+CD51:000002281FA80228053818A8042804287FA800000208020803F8020803F80000
+CD52:000002281FA80228053818A8042804287FA80000110811081F0811141F620000
+CD53:000002281FA80228053818A8042804287FA80000001000100010006801840000
+CD54:000002281FA80228053818A8042804287FA800000048004800A8011406620000
+CD55:000002281FA80228053818A8042804287FA80000000003F00408040803F00000
+CD56:000002281FA80228053818A8042804287FA8000003F80020002000D003080000
+CD57:000002281FA80228053818A8042804287FA80000004003F8004000A003180000
+CD58:000002281FA80228053818A8042804287FA8000003F8000803F8000800080000
+CD59:000002281FA80228053818A8042804287FA8000003F8020003F8020003F80000
+CD5A:000002281FA80228053818A8042804287FA8000000000FF8022002200FF80000
+CD5B:000002281FA80228053818A8042804287FA8000000800FF803E0041003E00000
+CD5C:00000008040804083F8801080208060809083088040804087FE8000800080000
+CD5D:000002081F88020805081888040804087FE8000007F800080008000800080000
+CD5E:000002081F88020805081888040804087FE8000000003EF80208020802080000
+CD5F:000002081F88020805081888040804087FE8000000001F080108011401620000
+CD60:000002081F88020805081888040804087FE8000008000800080008000FF80000
+CD61:000002081F88020805081888040804087FE80000000010F8101010301ECC0000
+CD62:000002081F88020805081888040804087FE800000808087F081C08220F9C0000
+CD63:000002081F88020805081888040804087FE8000003F802000200020003F80000
+CD64:000002081F88020805081888040804087FE8000007F8000807F8040007F80000
+CD65:000002081F88020805081888040804087FE800003EF802083E0820083E080000
+CD66:000002081F88020805081888040804087FE800003EF802883E8820883EF80000
+CD67:000002081F88020805081888040804087FE800003E8802883EF820883EF80000
+CD68:000002081F88020805081888040804087FE800001F0801081F0810141F620000
+CD69:000002081F88020805081888040804087FE800003EF802803EF820803EF80000
+CD6A:000002081F88020805081888040804087FE800003EFC02483E4820483EFC0000
+CD6B:000002081F88020805081888040804087FE800001F08017F1F1C10221F1C0000
+CD6C:000002081F88020805081888040804087FE8000003F802080208020803F80000
+CD6D:000002081F88020805081888040804087FE800000208020803F8020803F80000
+CD6E:000002081F88020805081888040804087FE80000110811081F0811141F620000
+CD6F:000002081F88020805081888040804087FE80000001000100010006801840000
+CD70:000002081F88020805081888040804087FE800000048004800A8011406620000
+CD71:000002081F88020805081888040804087FE80000000003F00408040803F00000
+CD72:000002081F88020805081888040804087FE8000003F80020002000D003080000
+CD73:000002081F88020805081888040804087FE80000004003F8004000A003180000
+CD74:000002081F88020805081888040804087FE8000003F8000803F8000800080000
+CD75:000002081F88020805081888040804087FE8000003F8020003F8020003F80000
+CD76:000002081F88020805081888040804087FE8000000000FF8022002200FF80000
+CD77:000002081F88020805081888040804087FE8000000800FF803E0041003E00000
+CD78:0000010001000FE000400080018002400C2004400440044004407FFC00000000
+CD79:000001000FC0010002800C40044004407FFC00001FF000100010001000100000
+CD7A:000001000FC0010002800C40044004407FFC000000003EF80208020802080000
+CD7B:000001000FC0010002800C40044004407FFC000000001E100210022802C40000
+CD7C:000001000FC0010002800C40044004407FFC000000001000100010001FF00000
+CD7D:000001000FC0010002800C40044004407FFC0000000020F8201020303ECC0000
+CD7E:000001000FC0010002800C40044004407FFC0000202021FC207020883E700000
+CD7F:000001000FC0010002800C40044004407FFC00001FF01000100010001FF00000
+CD80:000001000FC0010002800C40044004407FFC00001FF000101FF010001FF00000
+CD81:000001000FC0010002800C40044004407FFC00003EF802083E0820083E080000
+CD82:000001000FC0010002800C40044004407FFC00003EF802883E8820883EF80000
+CD83:000001000FC0010002800C40044004407FFC00003E8802883EF820883EF80000
+CD84:000001000FC0010002800C40044004407FFC00003E1002103E1020283EC40000
+CD85:000001000FC0010002800C40044004407FFC00003EF802803EF820803EF80000
+CD86:000001000FC0010002800C40044004407FFC00003EFC02483E4820483EFC0000
+CD87:000001000FC0010002800C40044004407FFC00003E2003FC3E7020883E700000
+CD88:000001000FC0010002800C40044004407FFC00001FF01010101010101FF00000
+CD89:000001000FC0010002800C40044004407FFC0000101010101FF010101FF00000
+CD8A:000001000FC0010002800C40044004407FFC0000222022203E2022503E880000
+CD8B:000001000FC0010002800C40044004407FFC000000000100010002800C400000
+CD8C:000001000FC0010002800C40044004407FFC00000000024002400DA033100000
+CD8D:000001000FC0010002800C40044004407FFC0000000007C00820082007C00000
+CD8E:000001000FC0010002800C40044004407FFC0000000007E00080014006200000
+CD8F:000001000FC0010002800C40044004407FFC0000008007E00080014006200000
+CD90:000001000FC0010002800C40044004407FFC00001FF000101FF0001000100000
+CD91:000001000FC0010002800C40044004407FFC00001FF010001FF010001FF00000
+CD92:000001000FC0010002800C40044004407FFC000000001FF0044004401FF00000
+CD93:000001000FC0010002800C40044004407FFC000001001FF007C0082007C00000
+CD94:00000080008007F00020004000C00120061000003FF801000100010001000000
+CD95:000001000FC0010002800C4000007FFC010001001FF000100010001000100000
+CD96:000001000FC0010002800C4000007FFC0100010000003EF80208020802080000
+CD97:000001000FC0010002800C4000007FFC0100010000001E100210022802C40000
+CD98:000001000FC0010002800C40000000007FFC010001001100100010001FF00000
+CD99:000001000FC0010002800C4000007FFC01000100000020F8201020303ECC0000
+CD9A:000001000FC0010002800C4000007FFC01000100202021FC207020883E700000
+CD9B:000001000FC0010002800C4000007FFC010001001FF01000100010001FF00000
+CD9C:000001000FC0010002800C4000007FFC010001001FF000101FF010001FF00000
+CD9D:000001000FC0010002800C4000007FFC010001003EF802083E0820083E080000
+CD9E:000001000FC0010002800C4000007FFC010001003EF802883E8820883EF80000
+CD9F:000001000FC0010002800C4000007FFC010001003E8802883EF820883EF80000
+CDA0:000001000FC0010002800C4000007FFC010001003E1002103E1020283EC40000
+CDA1:000001000FC0010002800C4000007FFC010001003EF802803EF820803EF80000
+CDA2:000001000FC0010002800C4000007FFC010001003EFC02483E4820483EFC0000
+CDA3:000001000FC0010002800C4000007FFC010001003E2003FC3E7020883E700000
+CDA4:000001000FC0010002800C4000007FFC010001001FF01010101010101FF00000
+CDA5:000001000FC0010002800C4000007FFC01000100101010101FF010101FF00000
+CDA6:000001000FC0010002800C4000007FFC01000100222022203E2022503E880000
+CDA7:000001000FC0010002800C4000007FFC0100010000000100010002800C400000
+CDA8:000001000FC0010002800C4000007FFC010001000000024002400DA033100000
+CDA9:000001000FC0010002800C4000007FFC01000100000007C00820082007C00000
+CDAA:000001000FC0010002800C4000007FFC01000100000007E00080014006200000
+CDAB:000001000FC0010002800C4000007FFC01000100008007E00080014006200000
+CDAC:000001000FC0010002800C4000007FFC010001001FF000101FF0001000100000
+CDAD:000001000FC0010002800C4000007FFC010001001FF010001FF010001FF00000
+CDAE:000001000FC0010002800C4000007FFC0100010000001FF0044004401FF00000
+CDAF:000001000FC0010002800C4000007FFC0100010001001FF007C0082007C00000
+CDB0:0000040804083F880108020806080908308800087FE8040804F8040804080000
+CDB1:04083F0804080A08310800087FE8027802080000000007F80008000800080000
+CDB2:04083F0804080A08310800087FE802780208000000003EF80208020802080000
+CDB3:04083F0804080A08310800087FE802780208000000001F080108011401620000
+CDB4:04083F0804080A083108000800087FE80278020802081000100010001FF80000
+CDB5:04083F0804080A08310800087FE8027802080000000020F8201020303ECC0000
+CDB6:04083F0804080A08310800087FE8027802080000202021FC207020883E700000
+CDB7:04083F0804080A08310800087FE802780208000003F802000200020003F80000
+CDB8:04083F0804080A08310800087FE802780208000007F8000807F8040007F80000
+CDB9:04083F0804080A08310800087FE80278020800003EF802083E0820083E080000
+CDBA:04083F0804080A08310800087FE80278020800003EF802883E8820883EF80000
+CDBB:04083F0804080A08310800087FE80278020800003E8802883EF820883EF80000
+CDBC:04083F0804080A08310800087FE80278020800000F8800880F8808140FA20000
+CDBD:04083F0804080A08310800087FE80278020800003EF802803EF820803EF80000
+CDBE:04083F0804080A08310800087FE80278020800003EFC02483E4820483EFC0000
+CDBF:04083F0804080A08310800087FE80278020800003E1002FE3E3820443E380000
+CDC0:04083F0804080A08310800087FE802780208000003F802080208020803F80000
+CDC1:04083F0804080A08310800087FE80278020800000208020803F8020803F80000
+CDC2:04083F0804080A08310800087FE8027802080000210821083F0821143F620000
+CDC3:04083F0804080A08310800087FE8027802080000001000100010006801840000
+CDC4:04083F0804080A08310800087FE80278020800000048004800A8011406620000
+CDC5:04083F0804080A08310800087FE8027802080000000003F00408040803F00000
+CDC6:04083F0804080A08310800087FE802780208000003F80020002000D003080000
+CDC7:04083F0804080A08310800087FE8027802080000004003F8004000A003180000
+CDC8:04083F0804080A08310800087FE802780208000003F8000803F8000800080000
+CDC9:04083F0804080A08310800087FE802780208000003F8020003F8020003F80000
+CDCA:04083F0804080A08310800087FE802780208000000000FF8022002200FF80000
+CDCB:04083F0804080A08310800087FE802780208000000800FF803E0041003E00000
+CDCC:0000040A040A3F8A010A020A060A090A308A000A7FEA040A047A040A040A0000
+CDCD:04283F2804280A28312800287FA805E804280000000007F80008000800080000
+CDCE:04283F2804280A28312800287FA805E80428000000003EF80208020802080000
+CDCF:04283F2804280A28312800287FA805E80428000000001F080108011401620000
+CDD0:04283F2804280A283128002800287FA8042805E804281428100010001FF80000
+CDD1:04283F2804280A28312800287FA805E804280000000020F8201020303ECC0000
+CDD2:04283F2804280A28312800287FA805E804280000202021FC207020883E700000
+CDD3:04283F2804280A28312800287FA805E80428000003F802000200020003F80000
+CDD4:04283F2804280A28312800287FA805E80428000007F8000807F8040007F80000
+CDD5:04283F2804280A28312800287FA805E8042800003EF802083E0820083E080000
+CDD6:04283F2804280A28312800287FA805E8042800003EF802883E8820883EF80000
+CDD7:04283F2804280A28312800287FA805E8042800003E8802883EF820883EF80000
+CDD8:04283F2804280A28312800287FA805E8042800000F8800880F8808140FA20000
+CDD9:04283F2804280A28312800287FA805E8042800003EF802803EF820803EF80000
+CDDA:04283F2804280A28312800287FA805E8042800003EFC02483E4820483EFC0000
+CDDB:04283F2804280A28312800287FA805E8042800003E1002FE3E3820443E380000
+CDDC:04283F2804280A28312800287FA805E80428000003F802080208020803F80000
+CDDD:04283F2804280A28312800287FA805E8042800000208020803F8020803F80000
+CDDE:04283F2804280A28312800287FA805E804280000210821083F0821143F620000
+CDDF:04283F2804280A28312800287FA805E804280000001000100010006801840000
+CDE0:04283F2804280A28312800287FA805E8042800000048004800A8011406620000
+CDE1:04283F2804280A28312800287FA805E804280000000003F00408040803F00000
+CDE2:04283F2804280A28312800287FA805E80428000003F80020002000D003080000
+CDE3:04283F2804280A28312800287FA805E804280000004003F8004000A003180000
+CDE4:04283F2804280A28312800287FA805E80428000003F8000803F8000800080000
+CDE5:04283F2804280A28312800287FA805E80428000003F8020003F8020003F80000
+CDE6:04283F2804280A28312800287FA805E80428000000000FF8022002200FF80000
+CDE7:04283F2804280A28312800287FA805E80428000000800FF803E0041003E00000
+CDE8:0000040804083F880108020806080908308800087FE804080408040804080000
+CDE9:04083F0804080A08310800087FE8020802000000000007F80008000800080000
+CDEA:04083F0804080A08310800087FE802080200000000003EF80208020802080000
+CDEB:04083F0804080A08310800087FE802080200000000001F080108011401620000
+CDEC:04083F0804080A083108000800087FE80208020802081008100010001FF80000
+CDED:04083F0804080A08310800087FE8020802000000000020F8201020303ECC0000
+CDEE:04083F0804080A08310800087FE8020802000000202021FC207020883E700000
+CDEF:04083F0804080A08310800087FE802080200000003F802000200020003F80000
+CDF0:04083F0804080A08310800087FE802080200000007F8000807F8040007F80000
+CDF1:04083F0804080A08310800087FE80208020000003EF802083E0820083E080000
+CDF2:04083F0804080A08310800087FE80208020000003EF802883E8820883EF80000
+CDF3:04083F0804080A08310800087FE80208020000003E8802883EF820883EF80000
+CDF4:04083F0804080A08310800087FE80208020000000F8800880F8808140FA20000
+CDF5:04083F0804080A08310800087FE80208020000003EF802803EF820803EF80000
+CDF6:04083F0804080A08310800087FE80208020000003EFC02483E4820483EFC0000
+CDF7:04083F0804080A08310800087FE80208020000003E1002FE3E3820443E380000
+CDF8:04083F0804080A08310800087FE802080200000003F802080208020803F80000
+CDF9:04083F0804080A08310800087FE80208020000000208020803F8020803F80000
+CDFA:04083F0804080A08310800087FE8020802000000210821083F0821143F620000
+CDFB:04083F0804080A08310800087FE8020802000000001000100010006801840000
+CDFC:04083F0804080A08310800087FE80208020000000048004800A8011406620000
+CDFD:04083F0804080A08310800087FE8020802000000000003F00408040803F00000
+CDFE:04083F0804080A08310800087FE802080200000003F80020002000D003080000
+CDFF:04083F0804080A08310800087FE8020802000000004003F8004000A003180000
+CE00:04083F0804080A08310800087FE802080200000003F8000803F8000800080000
+CE01:04083F0804080A08310800087FE802080200000003F8020003F8020003F80000
+CE02:04083F0804080A08310800087FE802080200000000000FF8022002200FF80000
+CE03:04083F0804080A08310800087FE802080200000000800FF803E0041003E00000
+CE04:00000080008007F00020004000C00120061000007FFC04400440044004400000
+CE05:000001000FC0010002800C4000007FFC044004401FF000100010001000100000
+CE06:000001000FC0010002800C4000007FFC0440044000003EF80208020802080000
+CE07:000001000FC0010002800C4000007FFC0440044000001E100210022802C40000
+CE08:000001000FC0010002800C40000000007FFC044004401440100010001FF00000
+CE09:000001000FC0010002800C4000007FFC04400440000020F8201020303ECC0000
+CE0A:000001000FC0010002800C4000007FFC04400440202021FC207020883E700000
+CE0B:000001000FC0010002800C4000007FFC044004401FF01000100010001FF00000
+CE0C:000001000FC0010002800C4000007FFC044004401FF000101FF010001FF00000
+CE0D:000001000FC0010002800C4000007FFC044004403EF802083E0820083E080000
+CE0E:000001000FC0010002800C4000007FFC044004403EF802883E8820883EF80000
+CE0F:000001000FC0010002800C4000007FFC044004403E8802883EF820883EF80000
+CE10:000001000FC0010002800C4000007FFC044004403E1002103E1020283EC40000
+CE11:000001000FC0010002800C4000007FFC044004403EF802803EF820803EF80000
+CE12:000001000FC0010002800C4000007FFC044004403EFC02483E4820483EFC0000
+CE13:000001000FC0010002800C4000007FFC044004403E2003FC3E7020883E700000
+CE14:000001000FC0010002800C4000007FFC044004401FF01010101010101FF00000
+CE15:000001000FC0010002800C4000007FFC04400440101010101FF010101FF00000
+CE16:000001000FC0010002800C4000007FFC04400440222022203E2022503E880000
+CE17:000001000FC0010002800C4000007FFC0440044000000100010002800C400000
+CE18:000001000FC0010002800C4000007FFC044004400000024002400DA033100000
+CE19:000001000FC0010002800C4000007FFC04400440000007C00820082007C00000
+CE1A:000001000FC0010002800C4000007FFC04400440000007E00080014006200000
+CE1B:000001000FC0010002800C4000007FFC04400440008007E00080014006200000
+CE1C:000001000FC0010002800C4000007FFC044004401FF000101FF0001000100000
+CE1D:000001000FC0010002800C4000007FFC044004401FF010001FF010001FF00000
+CE1E:000001000FC0010002800C4000007FFC0440044000001FF0044004401FF00000
+CE1F:000001000FC0010002800C4000007FFC0440044001001FF007C0082007C00000
+CE20:0000010001000FE000400080018002400C20000000007FFC0000000000000000
+CE21:000001000FC0010002800C40000000007FFC00001FF000100010001000100000
+CE22:000001000FC0010002800C40000000007FFC000000003EF80208020802080000
+CE23:000001000FC0010002800C40000000007FFC000000001E100210022802C40000
+CE24:000001000FC0010002800C40000000007FFC000000001000100010001FF00000
+CE25:000001000FC0010002800C40000000007FFC0000000020F8201020303ECC0000
+CE26:000001000FC0010002800C40000000007FFC0000202021FC207020883E700000
+CE27:000001000FC0010002800C40000000007FFC00001FF01000100010001FF00000
+CE28:000001000FC0010002800C40000000007FFC00001FF000101FF010001FF00000
+CE29:000001000FC0010002800C40000000007FFC00003EF802083E0820083E080000
+CE2A:000001000FC0010002800C40000000007FFC00003EF802883E8820883EF80000
+CE2B:000001000FC0010002800C40000000007FFC00003E8802883EF820883EF80000
+CE2C:000001000FC0010002800C40000000007FFC00003E1002103E1020283EC40000
+CE2D:000001000FC0010002800C40000000007FFC00003EF802803EF820803EF80000
+CE2E:000001000FC0010002800C40000000007FFC00003EFC02483E4820483EFC0000
+CE2F:000001000FC0010002800C40000000007FFC00003E2003FC3E7020883E700000
+CE30:000001000FC0010002800C40000000007FFC00001FF01010101010101FF00000
+CE31:000001000FC0010002800C40000000007FFC0000101010101FF010101FF00000
+CE32:000001000FC0010002800C40000000007FFC0000222022203E2022503E880000
+CE33:000001000FC0010002800C40000000007FFC000000000100010002800C400000
+CE34:000001000FC0010002800C40000000007FFC00000000024002400DA033100000
+CE35:000001000FC0010002800C40000000007FFC0000000007C00820082007C00000
+CE36:000001000FC0010002800C40000000007FFC0000000007E00080014006200000
+CE37:000001000FC0010002800C40000000007FFC0000008007E00080014006200000
+CE38:000001000FC0010002800C40000000007FFC00001FF000101FF0001000100000
+CE39:000001000FC0010002800C40000000007FFC00001FF010001FF010001FF00000
+CE3A:000001000FC0010002800C40000000007FFC000000001FF0044004401FF00000
+CE3B:000001000FC0010002800C40000000007FFC000001001FF007C0082007C00000
+CE3C:00000008040804083F880108020806080908308800087FE80008000800080000
+CE3D:000002081F88020805081888000800087FE8000007F800080008000800080000
+CE3E:000002081F88020805081888000800087FE8000000003EF80208020802080000
+CE3F:000002081F88020805081888000800087FE8000000001F080108011401620000
+CE40:000002081F88020805081888000800087FE8000008000800080008000FF80000
+CE41:000002081F88020805081888000800087FE80000000010F8101010301ECC0000
+CE42:000002081F88020805081888000800087FE800000808087F081C08220F9C0000
+CE43:000002081F88020805081888000800087FE8000003F802000200020003F80000
+CE44:000002081F88020805081888000800087FE8000007F8000807F8040007F80000
+CE45:000002081F88020805081888000800087FE800003EF802083E0820083E080000
+CE46:000002081F88020805081888000800087FE800003EF802883E8820883EF80000
+CE47:000002081F88020805081888000800087FE800003E8802883EF820883EF80000
+CE48:000002081F88020805081888000800087FE800001F0801081F0810141F620000
+CE49:000002081F88020805081888000800087FE800003EF802803EF820803EF80000
+CE4A:000002081F88020805081888000800087FE800003EFC02483E4820483EFC0000
+CE4B:000002081F88020805081888000800087FE800001F08017F1F1C10221F1C0000
+CE4C:000002081F88020805081888000800087FE8000003F802080208020803F80000
+CE4D:000002081F88020805081888000800087FE800000208020803F8020803F80000
+CE4E:000002081F88020805081888000800087FE80000110811081F0811141F620000
+CE4F:000002081F88020805081888000800087FE80000001000100010006801840000
+CE50:000002081F88020805081888000800087FE800000048004800A8011406620000
+CE51:000002081F88020805081888000800087FE80000000003F00408040803F00000
+CE52:000002081F88020805081888000800087FE8000003F80020002000D003080000
+CE53:000002081F88020805081888000800087FE80000004003F8004000A003180000
+CE54:000002081F88020805081888000800087FE8000003F8000803F8000800080000
+CE55:000002081F88020805081888000800087FE8000003F8020003F8020003F80000
+CE56:000002081F88020805081888000800087FE8000000000FF8022002200FF80000
+CE57:000002081F88020805081888000800087FE8000000800FF803E0041003E00000
+CE58:000000000008040804083F880108020806080908308800080008000800080000
+CE59:00000008000808087E0808081408620800080000000007F80008000800080000
+CE5A:00000008000808087E080808140862080008000000003EF80208020802080000
+CE5B:00000008000808087E080808140862080008000000001F080108011401620000
+CE5C:00000008000808087E080808140862080008000800001000100010001FF80000
+CE5D:00000008000808087E0808081408620800080000000020F8201020303ECC0000
+CE5E:00000008000808087E0808081408620800080000202021FC207020883E700000
+CE5F:00000008000808087E080808140862080008000003F802000200020003F80000
+CE60:00000008000808087E080808140862080008000007F8000807F8040007F80000
+CE61:00000008000808087E08080814086208000800003EF802083E0820083E080000
+CE62:00000008000808087E08080814086208000800003EF802883E8820883EF80000
+CE63:00000008000808087E08080814086208000800003E8802883EF820883EF80000
+CE64:00000008000808087E08080814086208000800000F8800880F8808140FA20000
+CE65:00000008000808087E08080814086208000800003EF802803EF820803EF80000
+CE66:00000008000808087E08080814086208000800003EFC02483E4820483EFC0000
+CE67:00000008000808087E08080814086208000800003E1002FE3E3820443E380000
+CE68:00000008000808087E080808140862080008000003F802080208020803F80000
+CE69:00000008000808087E08080814086208000800000208020803F8020803F80000
+CE6A:00000008000808087E0808081408620800080000210821083F0821143F620000
+CE6B:00000008000808087E0808081408620800080000001000100010006801840000
+CE6C:00000008000808087E08080814086208000800000048004800A8011406620000
+CE6D:00000008000808087E0808081408620800080000000003F00408040803F00000
+CE6E:00000008000808087E080808140862080008000003F80020002000D003080000
+CE6F:00000008000808087E0808081408620800080000004003F8004000A003180000
+CE70:00000008000808087E080808140862080008000003F8000803F8000800080000
+CE71:00000008000808087E080808140862080008000003F8020003F8020003F80000
+CE72:00000008000808087E080808140862080008000000000FF8022002200FF80000
+CE73:00000008000808087E080808140862080008000000800FF803E0041003E00000
+CE74:00000000001000101F9000900090009E1F100110021004101810001000100000
+CE75:000000087E08020802087E0E040818086008000007F800080008000800080000
+CE76:000000087E08020802087E0E040818086008000000003EF80208020802080000
+CE77:000000087E08020802087E0E040818086008000000001F080108011401620000
+CE78:000000087E08020802087E0E040818086008000808000800080008000FF80000
+CE79:000000087E08020802087E0E0408180860080000000010F8101010301ECC0000
+CE7A:000000087E08020802087E0E04081808600800000808087F081C08220F9C0000
+CE7B:000000087E08020802087E0E040818086008000003F802000200020003F80000
+CE7C:000000087E08020802087E0E040818086008000007F8000807F8040007F80000
+CE7D:000000087E08020802087E0E04081808600800003EF802083E0820083E080000
+CE7E:000000087E08020802087E0E04081808600800003EF802883E8820883EF80000
+CE7F:000000087E08020802087E0E04081808600800003E8802883EF820883EF80000
+CE80:000000087E08020802087E0E04081808600800001F0801081F0810141F620000
+CE81:000000087E08020802087E0E04081808600800003EF802803EF820803EF80000
+CE82:000000087E08020802087E0E04081808600800003EFC02483E4820483EFC0000
+CE83:000000087E08020802087E0E04081808600800001F08017F1F1C10221F1C0000
+CE84:000000087E08020802087E0E040818086008000003F802080208020803F80000
+CE85:000000087E08020802087E0E04081808600800000208020803F8020803F80000
+CE86:000000087E08020802087E0E0408180860080000110811081F0811141F620000
+CE87:000000087E08020802087E0E0408180860080000001000100010006801840000
+CE88:000000087E08020802087E0E04081808600800000048004800A8011406620000
+CE89:000000087E08020802087E0E0408180860080000000003F00408040803F00000
+CE8A:000000087E08020802087E0E040818086008000003F80020002000D003080000
+CE8B:000000087E08020802087E0E0408180860080000004003F8004000A003180000
+CE8C:000000087E08020802087E0E040818086008000003F8000803F8000800080000
+CE8D:000000087E08020802087E0E040818086008000003F8020003F8020003F80000
+CE8E:000000087E08020802087E0E040818086008000000000FF8022002200FF80000
+CE8F:000000087E08020802087E0E040818086008000000800FF803E0041003E00000
+CE90:00000000001200121F9200920092009E1F120112021204121812001200120000
+CE91:000000287E28022802287E38042818286028000007F800080008000800080000
+CE92:000000287E28022802287E38042818286028000000003EF80208020802080000
+CE93:000000287E28022802287E38042818286028000000003E100210022802C40000
+CE94:000000287E28022802287E38042818286028002808000800080008000FF80000
+CE95:000000287E28022802287E380428182860280000000020F8201020303ECC0000
+CE96:000000287E28022802287E380428182860280000202021FC207020883E700000
+CE97:000000287E28022802287E38042818286028000003F802000200020003F80000
+CE98:000000287E28022802287E38042818286028000007F8000807F8040007F80000
+CE99:000000287E28022802287E3804281828602800003EF802083E0820083E080000
+CE9A:000000287E28022802287E3804281828602800003EF802883E8820883EF80000
+CE9B:000000287E28022802287E3804281828602800003E8802883EF820883EF80000
+CE9C:000000287E28022802287E3804281828602800001F0801081F0810141F620000
+CE9D:000000287E28022802287E3804281828602800003EF802803EF820803EF80000
+CE9E:000000287E28022802287E3804281828602800003EFC02483E4820483EFC0000
+CE9F:000000287E28022802287E3804281828602800003E1002FE3E3820443E380000
+CEA0:000000287E28022802287E38042818286028000003F802080208020803F80000
+CEA1:000000287E28022802287E3804281828602800000208020803F8020803F80000
+CEA2:000000287E28022802287E380428182860280000110811081F0811141F620000
+CEA3:000000287E28022802287E380428182860280000000800080008003400C20000
+CEA4:000000287E28022802287E3804281828602800000048004800A8011406620000
+CEA5:000000287E28022802287E380428182860280000000001F00208020801F00000
+CEA6:000000287E28022802287E38042818286028000003F80020002000D003080000
+CEA7:000000287E28022802287E380428182860280000004003F8004000A003180000
+CEA8:000000287E28022802287E38042818286028000003F8000803F8000800080000
+CEA9:000000287E28022802287E38042818286028000003F8020003F8020003F80000
+CEAA:000000287E28022802287E38042818286028000000000FF8022002200FF80000
+CEAB:000000287E28022802287E38042818286028000000800FF803E0041003E00000
+CEAC:00000000001000101F900090009E00901F10011E021004101810001000100000
+CEAD:000000087E080208020E7E08040E18086008000007F800080008000800080000
+CEAE:000000087E080208020E7E08040E18086008000000003EF80208020802080000
+CEAF:000000087E080208020E7E08040E18086008000000001F080108011401620000
+CEB0:000000087E080208020E7E08040E18086008000008000800080008000FF80000
+CEB1:000000087E080208020E7E08040E180860080000000010F8101010301ECC0000
+CEB2:000000087E080208020E7E08040E1808600800000808087F081C08220F9C0000
+CEB3:000000087E080208020E7E08040E18086008000003F802000200020003F80000
+CEB4:000000087E080208020E7E08040E18086008000007F8000807F8040007F80000
+CEB5:000000087E080208020E7E08040E1808600800003EF802083E0820083E080000
+CEB6:000000087E080208020E7E08040E1808600800003EF802883E8820883EF80000
+CEB7:000000087E080208020E7E08040E1808600800003E8802883EF820883EF80000
+CEB8:000000087E080208020E7E08040E1808600800001F0801081F0810141F620000
+CEB9:000000087E080208020E7E08040E1808600800003EF802803EF820803EF80000
+CEBA:000000087E080208020E7E08040E1808600800003EFC02483E4820483EFC0000
+CEBB:000000087E080208020E7E08040E1808600800001F08017F1F1C10221F1C0000
+CEBC:000000087E080208020E7E08040E18086008000003F802080208020803F80000
+CEBD:000000087E080208020E7E08040E1808600800000208020803F8020803F80000
+CEBE:000000087E080208020E7E08040E180860080000110811081F0811141F620000
+CEBF:000000087E080208020E7E08040E180860080000001000100010006801840000
+CEC0:000000087E080208020E7E08040E1808600800000048004800A8011406620000
+CEC1:000000087E080208020E7E08040E180860080000000003F00408040803F00000
+CEC2:000000087E080208020E7E08040E18086008000003F80020002000D003080000
+CEC3:000000087E080208020E7E08040E180860080000004003F8004000A003180000
+CEC4:000000087E080208020E7E08040E18086008000003F8000803F8000800080000
+CEC5:000000087E080208020E7E08040E18086008000003F8020003F8020003F80000
+CEC6:000000087E080208020E7E08040E18086008000000000FF8022002200FF80000
+CEC7:000000087E080208020E7E08040E18086008000000800FF803E0041003E00000
+CEC8:00000000001200121F920092009E00921F12011E021204121812001200120000
+CEC9:000000287E28022802387E28043818286028000007F800080008000800080000
+CECA:000000287E28022802387E28043818286028000000003EF80208020802080000
+CECB:000000287E28022802387E28043818286028000000003E100210022802C40000
+CECC:000000287E28022802387E28043818286028002808000800080008000FF80000
+CECD:000000287E28022802387E280438182860280000000020F8201020303ECC0000
+CECE:000000287E28022802387E280438182860280000202021FC207020883E700000
+CECF:000000287E28022802387E28043818286028000003F802000200020003F80000
+CED0:000000287E28022802387E28043818286028000007F8000807F8040007F80000
+CED1:000000287E28022802387E2804381828602800003EF802083E0820083E080000
+CED2:000000287E28022802387E2804381828602800003EF802883E8820883EF80000
+CED3:000000287E28022802387E2804381828602800003E8802883EF820883EF80000
+CED4:000000287E28022802387E2804381828602800001F0801081F0810141F620000
+CED5:000000287E28022802387E2804381828602800003EF802803EF820803EF80000
+CED6:000000287E28022802387E2804381828602800003EFC02483E4820483EFC0000
+CED7:000000287E28022802387E2804381828602800003E1002FE3E3820443E380000
+CED8:000000287E28022802387E28043818286028000003F802080208020803F80000
+CED9:000000287E28022802387E2804381828602800000208020803F8020803F80000
+CEDA:000000287E28022802387E280438182860280000110811081F0811141F620000
+CEDB:000000287E28022802387E280438182860280000000800080008003400C20000
+CEDC:000000287E28022802387E2804381828602800000048004800A8011406620000
+CEDD:000000287E28022802387E280438182860280000000001F00208020801F00000
+CEDE:000000287E28022802387E28043818286028000003F80020002000D003080000
+CEDF:000000287E28022802387E280438182860280000004003F8004000A003180000
+CEE0:000000287E28022802387E28043818286028000003F8000803F8000800080000
+CEE1:000000287E28022802387E28043818286028000003F8020003F8020003F80000
+CEE2:000000287E28022802387E28043818286028000000000FF8022002200FF80000
+CEE3:000000287E28022802387E28043818286028000000800FF803E0041003E00000
+CEE4:00000000000200021F8200820082009E1F020102020204021802000200020000
+CEE5:000000087E08020802087E380408180860080000000007F80008000800080000
+CEE6:000000087E08020802087E38040818086008000000003EF80208020802080000
+CEE7:000000087E08020802087E38040818086008000000001F080108011401620000
+CEE8:000000087E08020802087E38040818086008000000001000100010001FF80000
+CEE9:000000087E08020802087E380408180860080000000020F8201020303ECC0000
+CEEA:000000087E08020802087E380408180860080000202021FC207020883E700000
+CEEB:000000087E08020802087E38040818086008000003F802000200020003F80000
+CEEC:000000087E08020802087E38040818086008000007F8000807F8040007F80000
+CEED:000000087E08020802087E3804081808600800003EF802083E0820083E080000
+CEEE:000000087E08020802087E3804081808600800003EF802883E8820883EF80000
+CEEF:000000087E08020802087E3804081808600800003E8802883EF820883EF80000
+CEF0:000000087E08020802087E3804081808600800000F8800880F8808140FA20000
+CEF1:000000087E08020802087E3804081808600800003EF802803EF820803EF80000
+CEF2:000000087E08020802087E3804081808600800003EFC02483E4820483EFC0000
+CEF3:000000087E08020802087E3804081808600800003E1002FE3E3820443E380000
+CEF4:000000087E08020802087E38040818086008000003F802080208020803F80000
+CEF5:000000087E08020802087E3804081808600800000208020803F8020803F80000
+CEF6:000000087E08020802087E380408180860080000210821083F0821143F620000
+CEF7:000000087E08020802087E380408180860080000001000100010006801840000
+CEF8:000000087E08020802087E3804081808600800000048004800A8011406620000
+CEF9:000000087E08020802087E380408180860080000000003F00408040803F00000
+CEFA:000000087E08020802087E38040818086008000003F80020002000D003080000
+CEFB:000000087E08020802087E380408180860080000004003F8004000A003180000
+CEFC:000000087E08020802087E38040818086008000003F8000803F8000800080000
+CEFD:000000087E08020802087E38040818086008000003F8020003F8020003F80000
+CEFE:000000087E08020802087E38040818086008000000000FF8022002200FF80000
+CEFF:000000087E08020802087E38040818086008000000800FF803E0041003E00000
+CF00:00000000000A000A1F8A008A008A00BA1F0A010A020A040A180A000A000A0000
+CF01:000000287E28022802287EE8042818286028000007F800080008000800080000
+CF02:000000287E28022802287EE8042818286028000000003EF80208020802080000
+CF03:000000287E28022802287EE8042818286028000000003E100210022802C40000
+CF04:000000287E28022802287EE8042818286028000008000800080008000FF80000
+CF05:000000287E28022802287EE80428182860280000000020F8201020303ECC0000
+CF06:000000287E28022802287EE80428182860280000202021FC207020883E700000
+CF07:000000287E28022802287EE8042818286028000003F802000200020003F80000
+CF08:000000287E28022802287EE8042818286028000007F8000807F8040007F80000
+CF09:000000287E28022802287EE804281828602800003EF802083E0820083E080000
+CF0A:000000287E28022802287EE804281828602800003EF802883E8820883EF80000
+CF0B:000000287E28022802287EE804281828602800003E8802883EF820883EF80000
+CF0C:000000287E28022802287EE804281828602800001F0801081F0810141F620000
+CF0D:000000287E28022802287EE804281828602800003EF802803EF820803EF80000
+CF0E:000000287E28022802287EE804281828602800003EFC02483E4820483EFC0000
+CF0F:000000287E28022802287EE804281828602800003E1002FE3E3820443E380000
+CF10:000000287E28022802287EE8042818286028000003F802080208020803F80000
+CF11:000000287E28022802287EE804281828602800000208020803F8020803F80000
+CF12:000000287E28022802287EE80428182860280000110811081F0811141F620000
+CF13:000000287E28022802287EE80428182860280000000800080008003400C20000
+CF14:000000287E28022802287EE804281828602800000048004800A8011406620000
+CF15:000000287E28022802287EE80428182860280000000001F00208020801F00000
+CF16:000000287E28022802287EE8042818286028000003F80020002000D003080000
+CF17:000000287E28022802287EE80428182860280000004003F8004000A003180000
+CF18:000000287E28022802287EE8042818286028000003F8000803F8000800080000
+CF19:000000287E28022802287EE8042818286028000003F8020003F8020003F80000
+CF1A:000000287E28022802287EE8042818286028000000000FF8022002200FF80000
+CF1B:000000287E28022802287EE8042818286028000000800FF803E0041003E00000
+CF1C:00000000000200021F820082009E00821F02011E020204021802000200020000
+CF1D:000000087E08020802387E080438180860080000000007F80008000800080000
+CF1E:000000087E08020802387E08043818086008000000003EF80208020802080000
+CF1F:000000087E08020802387E08043818086008000000001F080108011401620000
+CF20:000000087E08020802387E08043818086008000800001000100010001FF80000
+CF21:000000087E08020802387E080438180860080000000020F8201020303ECC0000
+CF22:000000087E08020802387E080438180860080000202021FC207020883E700000
+CF23:000000087E08020802387E08043818086008000003F802000200020003F80000
+CF24:000000087E08020802387E08043818086008000007F8000807F8040007F80000
+CF25:000000087E08020802387E0804381808600800003EF802083E0820083E080000
+CF26:000000087E08020802387E0804381808600800003EF802883E8820883EF80000
+CF27:000000087E08020802387E0804381808600800003E8802883EF820883EF80000
+CF28:000000087E08020802387E0804381808600800000F8800880F8808140FA20000
+CF29:000000087E08020802387E0804381808600800003EF802803EF820803EF80000
+CF2A:000000087E08020802387E0804381808600800003EFC02483E4820483EFC0000
+CF2B:000000087E08020802387E0804381808600800003E1002FE3E3820443E380000
+CF2C:000000087E08020802387E08043818086008000003F802080208020803F80000
+CF2D:000000087E08020802387E0804381808600800000208020803F8020803F80000
+CF2E:000000087E08020802387E080438180860080000210821083F0821143F620000
+CF2F:000000087E08020802387E080438180860080000001000100010006801840000
+CF30:000000087E08020802387E0804381808600800000048004800A8011406620000
+CF31:000000087E08020802387E080438180860080000000003F00408040803F00000
+CF32:000000087E08020802387E08043818086008000003F80020002000D003080000
+CF33:000000087E08020802387E080438180860080000004003F8004000A003180000
+CF34:000000087E08020802387E08043818086008000003F8000803F8000800080000
+CF35:000000087E08020802387E08043818086008000003F8020003F8020003F80000
+CF36:000000087E08020802387E08043818086008000000000FF8022002200FF80000
+CF37:000000087E08020802387E08043818086008000000800FF803E0041003E00000
+CF38:00000000000A000A1F8A008A00BA008A1F0A013A020A040A180A000A000A0000
+CF39:000000287E28022802E87E2804E818286028000007F800080008000800080000
+CF3A:000000287E28022802E87E2804E818286028000000003EF80208020802080000
+CF3B:000000287E28022802E87E2804E818286028000000003E100210022802C40000
+CF3C:000000287E28022802E87E2804E818286028002808000800080008000FF80000
+CF3D:000000287E28022802E87E2804E8182860280000000020F8201020303ECC0000
+CF3E:000000287E28022802E87E2804E8182860280000202021FC207020883E700000
+CF3F:000000287E28022802E87E2804E818286028000003F802000200020003F80000
+CF40:000000287E28022802E87E2804E818286028000007F8000807F8040007F80000
+CF41:000000287E28022802E87E2804E81828602800003EF802083E0820083E080000
+CF42:000000287E28022802E87E2804E81828602800003EF802883E8820883EF80000
+CF43:000000287E28022802E87E2804E81828602800003E8802883EF820883EF80000
+CF44:000000287E28022802E87E2804E81828602800001F0801081F0810141F620000
+CF45:000000287E28022802E87E2804E81828602800003EF802803EF820803EF80000
+CF46:000000287E28022802E87E2804E81828602800003EFC02483E4820483EFC0000
+CF47:000000287E28022802E87E2804E81828602800003E1002FE3E3820443E380000
+CF48:000000287E28022802E87E2804E818286028000003F802080208020803F80000
+CF49:000000287E28022802E87E2804E81828602800000208020803F8020803F80000
+CF4A:000000287E28022802E87E2804E8182860280000110811081F0811141F620000
+CF4B:000000287E28022802E87E2804E8182860280000000800080008003400C20000
+CF4C:000000287E28022802E87E2804E81828602800000048004800A8011406620000
+CF4D:000000287E28022802E87E2804E8182860280000000001F00208020801F00000
+CF4E:000000287E28022802E87E2804E818286028000003F80020002000D003080000
+CF4F:000000287E28022802E87E2804E8182860280000004003F8004000A003180000
+CF50:000000287E28022802E87E2804E818286028000003F8000803F8000800080000
+CF51:000000287E28022802E87E2804E818286028000003F8020003F8020003F80000
+CF52:000000287E28022802E87E2804E818286028000000000FF8022002200FF80000
+CF53:000000287E28022802E87E2804E818286028000000800FF803E0041003E00000
+CF54:00000000000000003FF8000800083FF8000802080208020002007FFC00000000
+CF55:000000001FF000101FF00010011001007FFC00001FF000100010001000100000
+CF56:000000001FF000101FF00010011001007FFC000000003EF80208020802080000
+CF57:000000001FF000101FF00010011001007FFC000000001E100210022802C40000
+CF58:000000001FF000101FF00010011001007FFC000000001000100010001FF00000
+CF59:000000001FF000101FF00010011001007FFC0000000020F8201020303ECC0000
+CF5A:000000001FF000101FF00010011001007FFC0000202021FC207020883E700000
+CF5B:000000001FF000101FF00010011001007FFC00001FF01000100010001FF00000
+CF5C:000000001FF000101FF00010011001007FFC00001FF000101FF010001FF00000
+CF5D:000000001FF000101FF00010011001007FFC00003EF802083E0820083E080000
+CF5E:000000001FF000101FF00010011001007FFC00003EF802883E8820883EF80000
+CF5F:000000001FF000101FF00010011001007FFC00003E8802883EF820883EF80000
+CF60:000000001FF000101FF00010011001007FFC00003E1002103E1020283EC40000
+CF61:000000001FF000101FF00010011001007FFC00003EF802803EF820803EF80000
+CF62:000000001FF000101FF00010011001007FFC00003EFC02483E4820483EFC0000
+CF63:000000001FF000101FF00010011001007FFC00003E2003FC3E7020883E700000
+CF64:000000001FF000101FF00010011001007FFC00001FF01010101010101FF00000
+CF65:000000001FF000101FF00010011001007FFC0000101010101FF010101FF00000
+CF66:000000001FF000101FF00010011001007FFC0000222022203E2022503E880000
+CF67:000000001FF000101FF00010011001007FFC000000000100010002800C400000
+CF68:000000001FF000101FF00010011001007FFC00000000024002400DA033100000
+CF69:000000001FF000101FF00010011001007FFC0000000007C00820082007C00000
+CF6A:000000001FF000101FF00010011001007FFC0000000007E00080014006200000
+CF6B:000000001FF000101FF00010011001007FFC0000008007E00080014006200000
+CF6C:000000001FF000101FF00010011001007FFC00001FF000101FF0001000100000
+CF6D:000000001FF000101FF00010011001007FFC00001FF010001FF010001FF00000
+CF6E:000000001FF000101FF00010011001007FFC000000001FF0044004401FF00000
+CF6F:000000001FF000101FF00010011001007FFC000001001FF007C0082007C00000
+CF70:00000000001000103FD0005000503FDE0450045004107FD00010001000100000
+CF71:000000083F8800883F8E0088048804087FE8000007F800080008000800080000
+CF72:000000083F8800883F8E0088048804087FE8000000003EF80208020802080000
+CF73:000000083F8800883F8E0088048804087FE8000000001F080108011401620000
+CF74:000000083F8800883F8E0088048804087FE8000008000800080008000FF80000
+CF75:000000083F8800883F8E0088048804087FE80000000010F8101010301ECC0000
+CF76:000000083F8800883F8E0088048804087FE800000808087F081C08220F9C0000
+CF77:000000083F8800883F8E0088048804087FE8000003F802000200020003F80000
+CF78:000000083F8800883F8E0088048804087FE8000007F8000807F8040007F80000
+CF79:000000083F8800883F8E0088048804087FE800003EF802083E0820083E080000
+CF7A:000000083F8800883F8E0088048804087FE800003EF802883E8820883EF80000
+CF7B:000000083F8800883F8E0088048804087FE800003E8802883EF820883EF80000
+CF7C:000000083F8800883F8E0088048804087FE800001F0801081F0810141F620000
+CF7D:000000083F8800883F8E0088048804087FE800003EF802803EF820803EF80000
+CF7E:000000083F8800883F8E0088048804087FE800003EFC02483E4820483EFC0000
+CF7F:000000083F8800883F8E0088048804087FE800001F08017F1F1C10221F1C0000
+CF80:000000083F8800883F8E0088048804087FE8000003F802080208020803F80000
+CF81:000000083F8800883F8E0088048804087FE800000208020803F8020803F80000
+CF82:000000083F8800883F8E0088048804087FE80000110811081F0811141F620000
+CF83:000000083F8800883F8E0088048804087FE80000001000100010006801840000
+CF84:000000083F8800883F8E0088048804087FE800000048004800A8011406620000
+CF85:000000083F8800883F8E0088048804087FE80000000003F00408040803F00000
+CF86:000000083F8800883F8E0088048804087FE8000003F80020002000D003080000
+CF87:000000083F8800883F8E0088048804087FE80000004003F8004000A003180000
+CF88:000000083F8800883F8E0088048804087FE8000003F8000803F8000800080000
+CF89:000000083F8800883F8E0088048804087FE8000003F8020003F8020003F80000
+CF8A:000000083F8800883F8E0088048804087FE8000000000FF8022002200FF80000
+CF8B:000000083F8800883F8E0088048804087FE8000000800FF803E0041003E00000
+CF8C:00000000001200123FD2005200523FDE0452045204127FD20012001200120000
+CF8D:000000283FA800A83FB800A804A804287FA8000007F800080008000800080000
+CF8E:000000283FA800A83FB800A804A804287FA8000000003EF80208020802080000
+CF8F:000000283FA800A83FB800A804A804287FA8000000001F080108011401620000
+CF90:000000283FA800A83FB800A804A804287FA8000008000800080008000FF80000
+CF91:000000283FA800A83FB800A804A804287FA80000000010F8101010301ECC0000
+CF92:000000283FA800A83FB800A804A804287FA800000808087F081C08220F9C0000
+CF93:000000283FA800A83FB800A804A804287FA8000003F802000200020003F80000
+CF94:000000283FA800A83FB800A804A804287FA8000007F8000807F8040007F80000
+CF95:000000283FA800A83FB800A804A804287FA800003EF802083E0820083E080000
+CF96:000000283FA800A83FB800A804A804287FA800003EF802883E8820883EF80000
+CF97:000000283FA800A83FB800A804A804287FA800003E8802883EF820883EF80000
+CF98:000000283FA800A83FB800A804A804287FA800001F0801081F0810141F620000
+CF99:000000283FA800A83FB800A804A804287FA800003EF802803EF820803EF80000
+CF9A:000000283FA800A83FB800A804A804287FA800003EFC02483E4820483EFC0000
+CF9B:000000283FA800A83FB800A804A804287FA800001F08017F1F1C10221F1C0000
+CF9C:000000283FA800A83FB800A804A804287FA8000003F802080208020803F80000
+CF9D:000000283FA800A83FB800A804A804287FA800000208020803F8020803F80000
+CF9E:000000283FA800A83FB800A804A804287FA80000110811081F0811141F620000
+CF9F:000000283FA800A83FB800A804A804287FA80000001000100010006801840000
+CFA0:000000283FA800A83FB800A804A804287FA800000048004800A8011406620000
+CFA1:000000283FA800A83FB800A804A804287FA80000000003F00408040803F00000
+CFA2:000000283FA800A83FB800A804A804287FA8000003F80020002000D003080000
+CFA3:000000283FA800A83FB800A804A804287FA80000004003F8004000A003180000
+CFA4:000000283FA800A83FB800A804A804287FA8000003F8000803F8000800080000
+CFA5:000000283FA800A83FB800A804A804287FA8000003F8020003F8020003F80000
+CFA6:000000283FA800A83FB800A804A804287FA8000000000FF8022002200FF80000
+CFA7:000000283FA800A83FB800A804A804287FA8000000800FF803E0041003E00000
+CFA8:00000000000400043FC4004400443FC40444044404047FF40004000400040000
+CFA9:000000083F8800883F880088048804087FE8000007F800080008000800080000
+CFAA:000000083F8800883F880088048804087FE8000000003EF80208020802080000
+CFAB:000000083F8800883F880088048804087FE8000000001F080108011401620000
+CFAC:000000083F8800883F880088048804087FE8000008000800080008000FF80000
+CFAD:000000083F8800883F880088048804087FE80000000010F8101010301ECC0000
+CFAE:000000083F8800883F880088048804087FE800000808087F081C08220F9C0000
+CFAF:000000083F8800883F880088048804087FE8000003F802000200020003F80000
+CFB0:000000083F8800883F880088048804087FE8000007F8000807F8040007F80000
+CFB1:000000083F8800883F880088048804087FE800003EF802083E0820083E080000
+CFB2:000000083F8800883F880088048804087FE800003EF802883E8820883EF80000
+CFB3:000000083F8800883F880088048804087FE800003E8802883EF820883EF80000
+CFB4:000000083F8800883F880088048804087FE800001F0801081F0810141F620000
+CFB5:000000083F8800883F880088048804087FE800003EF802803EF820803EF80000
+CFB6:000000083F8800883F880088048804087FE800003EFC02483E4820483EFC0000
+CFB7:000000083F8800883F880088048804087FE800001F08017F1F1C10221F1C0000
+CFB8:000000083F8800883F880088048804087FE8000003F802080208020803F80000
+CFB9:000000083F8800883F880088048804087FE800000208020803F8020803F80000
+CFBA:000000083F8800883F880088048804087FE80000110811081F0811141F620000
+CFBB:000000083F8800883F880088048804087FE80000001000100010006801840000
+CFBC:000000083F8800883F880088048804087FE800000048004800A8011406620000
+CFBD:000000083F8800883F880088048804087FE80000000003F00408040803F00000
+CFBE:000000083F8800883F880088048804087FE8000003F80020002000D003080000
+CFBF:000000083F8800883F880088048804087FE80000004003F8004000A003180000
+CFC0:000000083F8800883F880088048804087FE8000003F8000803F8000800080000
+CFC1:000000083F8800883F880088048804087FE8000003F8020003F8020003F80000
+CFC2:000000083F8800883F880088048804087FE8000000000FF8022002200FF80000
+CFC3:000000083F8800883F880088048804087FE8000000800FF803E0041003E00000
+CFC4:00000000000000003FF8000800083FF8000808880888088008807FFC00000000
+CFC5:000000001FF000101FF00010049004807FFC00001FF000100010001000100000
+CFC6:000000001FF000101FF00010049004807FFC000000003EF80208020802080000
+CFC7:000000001FF000101FF00010049004807FFC000000001E100210022802C40000
+CFC8:000000001FF000101FF00010049004807FFC000000001000100010001FF00000
+CFC9:000000001FF000101FF00010049004807FFC0000000020F8201020303ECC0000
+CFCA:000000001FF000101FF00010049004807FFC0000202021FC207020883E700000
+CFCB:000000001FF000101FF00010049004807FFC00001FF01000100010001FF00000
+CFCC:000000001FF000101FF00010049004807FFC00001FF000101FF010001FF00000
+CFCD:000000001FF000101FF00010049004807FFC00003EF802083E0820083E080000
+CFCE:000000001FF000101FF00010049004807FFC00003EF802883E8820883EF80000
+CFCF:000000001FF000101FF00010049004807FFC00003E8802883EF820883EF80000
+CFD0:000000001FF000101FF00010049004807FFC00003E1002103E1020283EC40000
+CFD1:000000001FF000101FF00010049004807FFC00003EF802803EF820803EF80000
+CFD2:000000001FF000101FF00010049004807FFC00003EFC02483E4820483EFC0000
+CFD3:000000001FF000101FF00010049004807FFC00003E2003FC3E7020883E700000
+CFD4:000000001FF000101FF00010049004807FFC00001FF01010101010101FF00000
+CFD5:000000001FF000101FF00010049004807FFC0000101010101FF010101FF00000
+CFD6:000000001FF000101FF00010049004807FFC0000222022203E2022503E880000
+CFD7:000000001FF000101FF00010049004807FFC000000000100010002800C400000
+CFD8:000000001FF000101FF00010049004807FFC00000000024002400DA033100000
+CFD9:000000001FF000101FF00010049004807FFC0000000007C00820082007C00000
+CFDA:000000001FF000101FF00010049004807FFC0000000007E00080014006200000
+CFDB:000000001FF000101FF00010049004807FFC0000008007E00080014006200000
+CFDC:000000001FF000101FF00010049004807FFC00001FF000101FF0001000100000
+CFDD:000000001FF000101FF00010049004807FFC00001FF010001FF010001FF00000
+CFDE:000000001FF000101FF00010049004807FFC000000001FF0044004401FF00000
+CFDF:000000001FF000101FF00010049004807FFC000001001FF007C0082007C00000
+CFE0:0000000000003FF8000800083FF80008000800003FF801000100010001000000
+CFE1:000000001FF000101FF0001000107FFC010001001FF000100010001000100000
+CFE2:000000001FF000101FF0001000107FFC0100010000003EF80208020802080000
+CFE3:000000001FF000101FF0001000107FFC0100010000001E100210022802C40000
+CFE4:000000001FF000101FF00010001000007FFC010001001100100010001FF00000
+CFE5:000000001FF000101FF0001000107FFC01000100000020F8201020303ECC0000
+CFE6:000000001FF000101FF0001000107FFC01000100202021FC207020883E700000
+CFE7:000000001FF000101FF0001000107FFC010001001FF01000100010001FF00000
+CFE8:000000001FF000101FF0001000107FFC010001001FF000101FF010001FF00000
+CFE9:000000001FF000101FF0001000107FFC010001003EF802083E0820083E080000
+CFEA:000000001FF000101FF0001000107FFC010001003EF802883E8820883EF80000
+CFEB:000000001FF000101FF0001000107FFC010001003E8802883EF820883EF80000
+CFEC:000000001FF000101FF0001000107FFC010001003E1002103E1020283EC40000
+CFED:000000001FF000101FF0001000107FFC010001003EF802803EF820803EF80000
+CFEE:000000001FF000101FF0001000107FFC010001003EFC02483E4820483EFC0000
+CFEF:000000001FF000101FF0001000107FFC010001003E2003FC3E7020883E700000
+CFF0:000000001FF000101FF0001000107FFC010001001FF01010101010101FF00000
+CFF1:000000001FF000101FF0001000107FFC01000100101010101FF010101FF00000
+CFF2:000000001FF000101FF0001000107FFC01000100222022203E2022503E880000
+CFF3:000000001FF000101FF0001000107FFC0100010000000100010002800C400000
+CFF4:000000001FF000101FF0001000107FFC010001000000024002400DA033100000
+CFF5:000000001FF000101FF0001000107FFC01000100000007C00820082007C00000
+CFF6:000000001FF000101FF0001000107FFC01000100000007E00080014006200000
+CFF7:000000001FF000101FF0001000107FFC01000100008007E00080014006200000
+CFF8:000000001FF000101FF0001000107FFC010001001FF000101FF0001000100000
+CFF9:000000001FF000101FF0001000107FFC010001001FF010001FF010001FF00000
+CFFA:000000001FF000101FF0001000107FFC0100010000001FF0044004401FF00000
+CFFB:000000001FF000101FF0001000107FFC0100010001001FF007C0082007C00000
+CFFC:0000000800083FC8004800483FC80048004800087FE8040804F8040804080000
+CFFD:00083F8800883F88008800887FE8027802080000000007F80008000800080000
+CFFE:00083F8800883F88008800887FE802780208000000003EF80208020802080000
+CFFF:00083F8800883F88008800887FE802780208000000001F080108011401620000
+D000:00083F8800883F880088008800087FE80278020802081000100010001FF80000
+D001:00083F8800883F88008800887FE8027802080000000020F8201020303ECC0000
+D002:00083F8800883F88008800887FE8027802080000202021FC207020883E700000
+D003:00083F8800883F88008800887FE802780208000003F802000200020003F80000
+D004:00083F8800883F88008800887FE802780208000007F8000807F8040007F80000
+D005:00083F8800883F88008800887FE80278020800003EF802083E0820083E080000
+D006:00083F8800883F88008800887FE80278020800003EF802883E8820883EF80000
+D007:00083F8800883F88008800887FE80278020800003E8802883EF820883EF80000
+D008:00083F8800883F88008800887FE80278020800000F8800880F8808140FA20000
+D009:00083F8800883F88008800887FE80278020800003EF802803EF820803EF80000
+D00A:00083F8800883F88008800887FE80278020800003EFC02483E4820483EFC0000
+D00B:00083F8800883F88008800887FE80278020800003E1002FE3E3820443E380000
+D00C:00083F8800883F88008800887FE802780208000003F802080208020803F80000
+D00D:00083F8800883F88008800887FE80278020800000208020803F8020803F80000
+D00E:00083F8800883F88008800887FE8027802080000210821083F0821143F620000
+D00F:00083F8800883F88008800887FE8027802080000001000100010006801840000
+D010:00083F8800883F88008800887FE80278020800000048004800A8011406620000
+D011:00083F8800883F88008800887FE8027802080000000003F00408040803F00000
+D012:00083F8800883F88008800887FE802780208000003F80020002000D003080000
+D013:00083F8800883F88008800887FE8027802080000004003F8004000A003180000
+D014:00083F8800883F88008800887FE802780208000003F8000803F8000800080000
+D015:00083F8800883F88008800887FE802780208000003F8020003F8020003F80000
+D016:00083F8800883F88008800887FE802780208000000000FF8022002200FF80000
+D017:00083F8800883F88008800887FE802780208000000800FF803E0041003E00000
+D018:0000000A000A3FCA004A004A3FCA004A004A000A7FEA040A047A040A040A0000
+D019:00283FA800A83FA800A800A87FA805E804280000000007F80008000800080000
+D01A:00283FA800A83FA800A800A87FA805E80428000000003EF80208020802080000
+D01B:00283FA800A83FA800A800A87FA805E80428000000001F080108011401620000
+D01C:00283FA800A83FA800A800A800287FA8042805E804281428100010001FF80000
+D01D:00283FA800A83FA800A800A87FA805E804280000000020F8201020303ECC0000
+D01E:00283FA800A83FA800A800A87FA805E804280000202021FC207020883E700000
+D01F:00283FA800A83FA800A800A87FA805E80428000003F802000200020003F80000
+D020:00283FA800A83FA800A800A87FA805E80428000007F8000807F8040007F80000
+D021:00283FA800A83FA800A800A87FA805E8042800003EF802083E0820083E080000
+D022:00283FA800A83FA800A800A87FA805E8042800003EF802883E8820883EF80000
+D023:00283FA800A83FA800A800A87FA805E8042800003E8802883EF820883EF80000
+D024:00283FA800A83FA800A800A87FA805E8042800000F8800880F8808140FA20000
+D025:00283FA800A83FA800A800A87FA805E8042800003EF802803EF820803EF80000
+D026:00283FA800A83FA800A800A87FA805E8042800003EFC02483E4820483EFC0000
+D027:00283FA800A83FA800A800A87FA805E8042800003E1002FE3E3820443E380000
+D028:00283FA800A83FA800A800A87FA805E80428000003F802080208020803F80000
+D029:00283FA800A83FA800A800A87FA805E8042800000208020803F8020803F80000
+D02A:00283FA800A83FA800A800A87FA805E804280000210821083F0821143F620000
+D02B:00283FA800A83FA800A800A87FA805E804280000001000100010006801840000
+D02C:00283FA800A83FA800A800A87FA805E8042800000048004800A8011406620000
+D02D:00283FA800A83FA800A800A87FA805E804280000000003F00408040803F00000
+D02E:00283FA800A83FA800A800A87FA805E80428000003F80020002000D003080000
+D02F:00283FA800A83FA800A800A87FA805E804280000004003F8004000A003180000
+D030:00283FA800A83FA800A800A87FA805E80428000003F8000803F8000800080000
+D031:00283FA800A83FA800A800A87FA805E80428000003F8020003F8020003F80000
+D032:00283FA800A83FA800A800A87FA805E80428000000000FF8022002200FF80000
+D033:00283FA800A83FA800A800A87FA805E80428000000800FF803E0041003E00000
+D034:0000000800083FC8004800483FC80048004800087FE804080408040804080000
+D035:00083F8800883F88008800887FE8020802000000000007F80008000800080000
+D036:00083F8800883F88008800887FE802080200000000003EF80208020802080000
+D037:00083F8800883F88008800887FE802080200000000001F080108011401620000
+D038:00083F8800883F880088008800087FE80208020802081008100010001FF80000
+D039:00083F8800883F88008800887FE8020802000000000020F8201020303ECC0000
+D03A:00083F8800883F88008800887FE8020802000000202021FC207020883E700000
+D03B:00083F8800883F88008800887FE802080200000003F802000200020003F80000
+D03C:00083F8800883F88008800887FE802080200000007F8000807F8040007F80000
+D03D:00083F8800883F88008800887FE80208020000003EF802083E0820083E080000
+D03E:00083F8800883F88008800887FE80208020000003EF802883E8820883EF80000
+D03F:00083F8800883F88008800887FE80208020000003E8802883EF820883EF80000
+D040:00083F8800883F88008800887FE80208020000000F8800880F8808140FA20000
+D041:00083F8800883F88008800887FE80208020000003EF802803EF820803EF80000
+D042:00083F8800883F88008800887FE80208020000003EFC02483E4820483EFC0000
+D043:00083F8800883F88008800887FE80208020000003E1002FE3E3820443E380000
+D044:00083F8800883F88008800887FE802080200000003F802080208020803F80000
+D045:00083F8800883F88008800887FE80208020000000208020803F8020803F80000
+D046:00083F8800883F88008800887FE8020802000000210821083F0821143F620000
+D047:00083F8800883F88008800887FE8020802000000001000100010006801840000
+D048:00083F8800883F88008800887FE80208020000000048004800A8011406620000
+D049:00083F8800883F88008800887FE8020802000000000003F00408040803F00000
+D04A:00083F8800883F88008800887FE802080200000003F80020002000D003080000
+D04B:00083F8800883F88008800887FE8020802000000004003F8004000A003180000
+D04C:00083F8800883F88008800887FE802080200000003F8000803F8000800080000
+D04D:00083F8800883F88008800887FE802080200000003F8020003F8020003F80000
+D04E:00083F8800883F88008800887FE802080200000000000FF8022002200FF80000
+D04F:00083F8800883F88008800887FE802080200000000800FF803E0041003E00000
+D050:0000000000003FF8000800083FF80008000800007FFC04400440044004400000
+D051:000000001FF000101FF0001000107FFC044004401FF000100010001000100000
+D052:000000001FF000101FF0001000107FFC0440044000003EF80208020802080000
+D053:000000001FF000101FF0001000107FFC0440044000001E100210022802C40000
+D054:000000001FF000101FF00010001000007FFC044004401440100010001FF00000
+D055:000000001FF000101FF0001000107FFC04400440000020F8201020303ECC0000
+D056:000000001FF000101FF0001000107FFC04400440202021FC207020883E700000
+D057:000000001FF000101FF0001000107FFC044004401FF01000100010001FF00000
+D058:000000001FF000101FF0001000107FFC044004401FF000101FF010001FF00000
+D059:000000001FF000101FF0001000107FFC044004403EF802083E0820083E080000
+D05A:000000001FF000101FF0001000107FFC044004403EF802883E8820883EF80000
+D05B:000000001FF000101FF0001000107FFC044004403E8802883EF820883EF80000
+D05C:000000001FF000101FF0001000107FFC044004403E1002103E1020283EC40000
+D05D:000000001FF000101FF0001000107FFC044004403EF802803EF820803EF80000
+D05E:000000001FF000101FF0001000107FFC044004403EFC02483E4820483EFC0000
+D05F:000000001FF000101FF0001000107FFC044004403E2003FC3E7020883E700000
+D060:000000001FF000101FF0001000107FFC044004401FF01010101010101FF00000
+D061:000000001FF000101FF0001000107FFC04400440101010101FF010101FF00000
+D062:000000001FF000101FF0001000107FFC04400440222022203E2022503E880000
+D063:000000001FF000101FF0001000107FFC0440044000000100010002800C400000
+D064:000000001FF000101FF0001000107FFC044004400000024002400DA033100000
+D065:000000001FF000101FF0001000107FFC04400440000007C00820082007C00000
+D066:000000001FF000101FF0001000107FFC04400440000007E00080014006200000
+D067:000000001FF000101FF0001000107FFC04400440008007E00080014006200000
+D068:000000001FF000101FF0001000107FFC044004401FF000101FF0001000100000
+D069:000000001FF000101FF0001000107FFC044004401FF010001FF010001FF00000
+D06A:000000001FF000101FF0001000107FFC0440044000001FF0044004401FF00000
+D06B:000000001FF000101FF0001000107FFC0440044001001FF007C0082007C00000
+D06C:00000000000000003FF8000800083FF80008000800087FFC0000000000000000
+D06D:000000001FF000101FF00010001000007FFC00001FF000100010001000100000
+D06E:000000001FF000101FF00010001000007FFC000000003EF80208020802080000
+D06F:000000001FF000101FF00010001000007FFC000000001E100210022802C40000
+D070:000000001FF000101FF00010001000007FFC000000001000100010001FF00000
+D071:000000001FF000101FF00010001000007FFC0000000020F8201020303ECC0000
+D072:000000001FF000101FF00010001000007FFC0000202021FC207020883E700000
+D073:000000001FF000101FF00010001000007FFC00001FF01000100010001FF00000
+D074:000000001FF000101FF00010001000007FFC00001FF000101FF010001FF00000
+D075:000000001FF000101FF00010001000007FFC00003EF802083E0820083E080000
+D076:000000001FF000101FF00010001000007FFC00003EF802883E8820883EF80000
+D077:000000001FF000101FF00010001000007FFC00003E8802883EF820883EF80000
+D078:000000001FF000101FF00010001000007FFC00003E1002103E1020283EC40000
+D079:000000001FF000101FF00010001000007FFC00003EF802803EF820803EF80000
+D07A:000000001FF000101FF00010001000007FFC00003EFC02483E4820483EFC0000
+D07B:000000001FF000101FF00010001000007FFC00003E2003FC3E7020883E700000
+D07C:000000001FF000101FF00010001000007FFC00001FF01010101010101FF00000
+D07D:000000001FF000101FF00010001000007FFC0000101010101FF010101FF00000
+D07E:000000001FF000101FF00010001000007FFC0000222022203E2022503E880000
+D07F:000000001FF000101FF00010001000007FFC000000000100010002800C400000
+D080:000000001FF000101FF00010001000007FFC00000000024002400DA033100000
+D081:000000001FF000101FF00010001000007FFC0000000007C00820082007C00000
+D082:000000001FF000101FF00010001000007FFC0000000007E00080014006200000
+D083:000000001FF000101FF00010001000007FFC0000008007E00080014006200000
+D084:000000001FF000101FF00010001000007FFC00001FF000101FF0001000100000
+D085:000000001FF000101FF00010001000007FFC00001FF010001FF010001FF00000
+D086:000000001FF000101FF00010001000007FFC000000001FF0044004401FF00000
+D087:000000001FF000101FF00010001000007FFC000001001FF007C0082007C00000
+D088:00000000000800083FC8004800483FC80048004800087FE80008000800080000
+D089:000000083F8800883F880088008800087FE8000007F800080008000800080000
+D08A:000000083F8800883F880088008800087FE8000000003EF80208020802080000
+D08B:000000083F8800883F880088008800087FE8000000001F080108011401620000
+D08C:000000083F8800883F880088008800087FE8000008000800080008000FF80000
+D08D:000000083F8800883F880088008800087FE80000000010F8101010301ECC0000
+D08E:000000083F8800883F880088008800087FE800000808087F081C08220F9C0000
+D08F:000000083F8800883F880088008800087FE8000003F802000200020003F80000
+D090:000000083F8800883F880088008800087FE8000007F8000807F8040007F80000
+D091:000000083F8800883F880088008800087FE800003EF802083E0820083E080000
+D092:000000083F8800883F880088008800087FE800003EF802883E8820883EF80000
+D093:000000083F8800883F880088008800087FE800003E8802883EF820883EF80000
+D094:000000083F8800883F880088008800087FE800001F0801081F0810141F620000
+D095:000000083F8800883F880088008800087FE800003EF802803EF820803EF80000
+D096:000000083F8800883F880088008800087FE800003EFC02483E4820483EFC0000
+D097:000000083F8800883F880088008800087FE800001F08017F1F1C10221F1C0000
+D098:000000083F8800883F880088008800087FE8000003F802080208020803F80000
+D099:000000083F8800883F880088008800087FE800000208020803F8020803F80000
+D09A:000000083F8800883F880088008800087FE80000110811081F0811141F620000
+D09B:000000083F8800883F880088008800087FE80000001000100010006801840000
+D09C:000000083F8800883F880088008800087FE800000048004800A8011406620000
+D09D:000000083F8800883F880088008800087FE80000000003F00408040803F00000
+D09E:000000083F8800883F880088008800087FE8000003F80020002000D003080000
+D09F:000000083F8800883F880088008800087FE80000004003F8004000A003180000
+D0A0:000000083F8800883F880088008800087FE8000003F8000803F8000800080000
+D0A1:000000083F8800883F880088008800087FE8000003F8020003F8020003F80000
+D0A2:000000083F8800883F880088008800087FE8000000000FF8022002200FF80000
+D0A3:000000083F8800883F880088008800087FE8000000800FF803E0041003E00000
+D0A4:00000000000800081F880088008800881F080108020804081808000800080000
+D0A5:000000087E08020802087E080408180860080000000007F80008000800080000
+D0A6:000000087E08020802087E08040818086008000000003EF80208020802080000
+D0A7:000000087E08020802087E08040818086008000000001F080108011401620000
+D0A8:000000087E08020802087E08040818086008000800001000100010001FF80000
+D0A9:000000087E08020802087E080408180860080000000020F8201020303ECC0000
+D0AA:000000087E08020802087E080408180860080000202021FC207020883E700000
+D0AB:000000087E08020802087E08040818086008000003F802000200020003F80000
+D0AC:000000087E08020802087E08040818086008000007F8000807F8040007F80000
+D0AD:000000087E08020802087E0804081808600800003EF802083E0820083E080000
+D0AE:000000087E08020802087E0804081808600800003EF802883E8820883EF80000
+D0AF:000000087E08020802087E0804081808600800003E8802883EF820883EF80000
+D0B0:000000087E08020802087E0804081808600800000F8800880F8808140FA20000
+D0B1:000000087E08020802087E0804081808600800003EF802803EF820803EF80000
+D0B2:000000087E08020802087E0804081808600800003EFC02483E4820483EFC0000
+D0B3:000000087E08020802087E0804081808600800003E1002FE3E3820443E380000
+D0B4:000000087E08020802087E08040818086008000003F802080208020803F80000
+D0B5:000000087E08020802087E0804081808600800000208020803F8020803F80000
+D0B6:000000087E08020802087E080408180860080000210821083F0821143F620000
+D0B7:000000087E08020802087E080408180860080000001000100010006801840000
+D0B8:000000087E08020802087E0804081808600800000048004800A8011406620000
+D0B9:000000087E08020802087E080408180860080000000003F00408040803F00000
+D0BA:000000087E08020802087E08040818086008000003F80020002000D003080000
+D0BB:000000087E08020802087E080408180860080000004003F8004000A003180000
+D0BC:000000087E08020802087E08040818086008000003F8000803F8000800080000
+D0BD:000000087E08020802087E08040818086008000003F8020003F8020003F80000
+D0BE:000000087E08020802087E08040818086008000000000FF8022002200FF80000
+D0BF:000000087E08020802087E08040818086008000000800FF803E0041003E00000
+D0C0:00000000001000103F90201020103F9E201020103F9000100010001000100000
+D0C1:0000000800087E0840087E0E40087E080008000007F800080008000800080000
+D0C2:0000000800087E0840087E0E40087E080008000000003EF80208020802080000
+D0C3:0000000800087E0840087E0E40087E080008000000001F080108011401620000
+D0C4:0000000800087E0840087E0E40087E080008000808000800080008000FF80000
+D0C5:0000000800087E0840087E0E40087E0800080000000010F8101010301ECC0000
+D0C6:0000000800087E0840087E0E40087E08000800000808087F081C08220F9C0000
+D0C7:0000000800087E0840087E0E40087E080008000003F802000200020003F80000
+D0C8:0000000800087E0840087E0E40087E080008000007F8000807F8040007F80000
+D0C9:0000000800087E0840087E0E40087E08000800003EF802083E0820083E080000
+D0CA:0000000800087E0840087E0E40087E08000800003EF802883E8820883EF80000
+D0CB:0000000800087E0840087E0E40087E08000800003E8802883EF820883EF80000
+D0CC:0000000800087E0840087E0E40087E08000800001F0801081F0810141F620000
+D0CD:0000000800087E0840087E0E40087E08000800003EF802803EF820803EF80000
+D0CE:0000000800087E0840087E0E40087E08000800003EFC02483E4820483EFC0000
+D0CF:0000000800087E0840087E0E40087E08000800001F08017F1F1C10221F1C0000
+D0D0:0000000800087E0840087E0E40087E080008000003F802080208020803F80000
+D0D1:0000000800087E0840087E0E40087E08000800000208020803F8020803F80000
+D0D2:0000000800087E0840087E0E40087E0800080000110811081F0811141F620000
+D0D3:0000000800087E0840087E0E40087E0800080000001000100010006801840000
+D0D4:0000000800087E0840087E0E40087E08000800000048004800A8011406620000
+D0D5:0000000800087E0840087E0E40087E0800080000000003F00408040803F00000
+D0D6:0000000800087E0840087E0E40087E080008000003F80020002000D003080000
+D0D7:0000000800087E0840087E0E40087E0800080000004003F8004000A003180000
+D0D8:0000000800087E0840087E0E40087E080008000003F8000803F8000800080000
+D0D9:0000000800087E0840087E0E40087E080008000003F8020003F8020003F80000
+D0DA:0000000800087E0840087E0E40087E080008000000000FF8022002200FF80000
+D0DB:0000000800087E0840087E0E40087E080008000000800FF803E0041003E00000
+D0DC:00000000001200123F92201220123F9E201220123F9200120012001200120000
+D0DD:0000002800287E2840287E3840287E280028000007F800080008000800080000
+D0DE:0000002800287E2840287E3840287E280028000000003EF80208020802080000
+D0DF:0000002800287E2840287E3840287E280028000000003E100210022802C40000
+D0E0:0000002800287E2840287E3840287E280028002808000800080008000FF80000
+D0E1:0000002800287E2840287E3840287E2800280000000020F8201020303ECC0000
+D0E2:0000002800287E2840287E3840287E2800280000202021FC207020883E700000
+D0E3:0000002800287E2840287E3840287E280028000003F802000200020003F80000
+D0E4:0000002800287E2840287E3840287E280028000007F8000807F8040007F80000
+D0E5:0000002800287E2840287E3840287E28002800003EF802083E0820083E080000
+D0E6:0000002800287E2840287E3840287E28002800003EF802883E8820883EF80000
+D0E7:0000002800287E2840287E3840287E28002800003E8802883EF820883EF80000
+D0E8:0000002800287E2840287E3840287E28002800001F0801081F0810141F620000
+D0E9:0000002800287E2840287E3840287E28002800003EF802803EF820803EF80000
+D0EA:0000002800287E2840287E3840287E28002800003EFC02483E4820483EFC0000
+D0EB:0000002800287E2840287E3840287E28002800003E1002FE3E3820443E380000
+D0EC:0000002800287E2840287E3840287E280028000003F802080208020803F80000
+D0ED:0000002800287E2840287E3840287E28002800000208020803F8020803F80000
+D0EE:0000002800287E2840287E3840287E2800280000110811081F0811141F620000
+D0EF:0000002800287E2840287E3840287E2800280000000800080008003400C20000
+D0F0:0000002800287E2840287E3840287E28002800000048004800A8011406620000
+D0F1:0000002800287E2840287E3840287E2800280000000001F00208020801F00000
+D0F2:0000002800287E2840287E3840287E280028000003F80020002000D003080000
+D0F3:0000002800287E2840287E3840287E2800280000004003F8004000A003180000
+D0F4:0000002800287E2840287E3840287E280028000003F8000803F8000800080000
+D0F5:0000002800287E2840287E3840287E280028000003F8020003F8020003F80000
+D0F6:0000002800287E2840287E3840287E280028000000000FF8022002200FF80000
+D0F7:0000002800287E2840287E3840287E280028000000800FF803E0041003E00000
+D0F8:00000000001000103F902010201E3F902010201E3F9000100010001000100000
+D0F9:0000000800087E08400E7E08400E7E080008000007F800080008000800080000
+D0FA:0000000800087E08400E7E08400E7E080008000000003EF80208020802080000
+D0FB:0000000800087E08400E7E08400E7E080008000000001F080108011401620000
+D0FC:0000000800087E08400E7E08400E7E080008000008000800080008000FF80000
+D0FD:0000000800087E08400E7E08400E7E0800080000000010F8101010301ECC0000
+D0FE:0000000800087E08400E7E08400E7E08000800000808087F081C08220F9C0000
+D0FF:0000000800087E08400E7E08400E7E080008000003F802000200020003F80000
+D100:0000000800087E08400E7E08400E7E080008000007F8000807F8040007F80000
+D101:0000000800087E08400E7E08400E7E08000800003EF802083E0820083E080000
+D102:0000000800087E08400E7E08400E7E08000800003EF802883E8820883EF80000
+D103:0000000800087E08400E7E08400E7E08000800003E8802883EF820883EF80000
+D104:0000000800087E08400E7E08400E7E08000800001F0801081F0810141F620000
+D105:0000000800087E08400E7E08400E7E08000800003EF802803EF820803EF80000
+D106:0000000800087E08400E7E08400E7E08000800003EFC02483E4820483EFC0000
+D107:0000000800087E08400E7E08400E7E08000800001F08017F1F1C10221F1C0000
+D108:0000000800087E08400E7E08400E7E080008000003F802080208020803F80000
+D109:0000000800087E08400E7E08400E7E08000800000208020803F8020803F80000
+D10A:0000000800087E08400E7E08400E7E0800080000110811081F0811141F620000
+D10B:0000000800087E08400E7E08400E7E0800080000001000100010006801840000
+D10C:0000000800087E08400E7E08400E7E08000800000048004800A8011406620000
+D10D:0000000800087E08400E7E08400E7E0800080000000003F00408040803F00000
+D10E:0000000800087E08400E7E08400E7E080008000003F80020002000D003080000
+D10F:0000000800087E08400E7E08400E7E0800080000004003F8004000A003180000
+D110:0000000800087E08400E7E08400E7E080008000003F8000803F8000800080000
+D111:0000000800087E08400E7E08400E7E080008000003F8020003F8020003F80000
+D112:0000000800087E08400E7E08400E7E080008000000000FF8022002200FF80000
+D113:0000000800087E08400E7E08400E7E080008000000800FF803E0041003E00000
+D114:00000000001200123F922012201E3F922012201E3F9200120012001200120000
+D115:0000002800287E2840387E2840387E280028000007F800080008000800080000
+D116:0000002800287E2840387E2840387E280028000000003EF80208020802080000
+D117:0000002800287E2840387E2840387E280028000000003E100210022802C40000
+D118:0000002800287E2840387E2840387E280028002808000800080008000FF80000
+D119:0000002800287E2840387E2840387E2800280000000020F8201020303ECC0000
+D11A:0000002800287E2840387E2840387E2800280000202021FC207020883E700000
+D11B:0000002800287E2840387E2840387E280028000003F802000200020003F80000
+D11C:0000002800287E2840387E2840387E280028000007F8000807F8040007F80000
+D11D:0000002800287E2840387E2840387E28002800003EF802083E0820083E080000
+D11E:0000002800287E2840387E2840387E28002800003EF802883E8820883EF80000
+D11F:0000002800287E2840387E2840387E28002800003E8802883EF820883EF80000
+D120:0000002800287E2840387E2840387E28002800001F0801081F0810141F620000
+D121:0000002800287E2840387E2840387E28002800003EF802803EF820803EF80000
+D122:0000002800287E2840387E2840387E28002800003EFC02483E4820483EFC0000
+D123:0000002800287E2840387E2840387E28002800003E1002FE3E3820443E380000
+D124:0000002800287E2840387E2840387E280028000003F802080208020803F80000
+D125:0000002800287E2840387E2840387E28002800000208020803F8020803F80000
+D126:0000002800287E2840387E2840387E2800280000110811081F0811141F620000
+D127:0000002800287E2840387E2840387E2800280000000800080008003400C20000
+D128:0000002800287E2840387E2840387E28002800000048004800A8011406620000
+D129:0000002800287E2840387E2840387E2800280000000001F00208020801F00000
+D12A:0000002800287E2840387E2840387E280028000003F80020002000D003080000
+D12B:0000002800287E2840387E2840387E2800280000004003F8004000A003180000
+D12C:0000002800287E2840387E2840387E280028000003F8000803F8000800080000
+D12D:0000002800287E2840387E2840387E280028000003F8020003F8020003F80000
+D12E:0000002800287E2840387E2840387E280028000000000FF8022002200FF80000
+D12F:0000002800287E2840387E2840387E280028000000800FF803E0041003E00000
+D130:00000000000200023F82200220023F9E200220023F8200020002000200020000
+D131:0000000800087E0840087E3840087E0800080000000007F80008000800080000
+D132:0000000800087E0840087E3840087E080008000000003EF80208020802080000
+D133:0000000800087E0840087E3840087E080008000000001F080108011401620000
+D134:0000000800087E0840087E3840087E080008000000001000100010001FF80000
+D135:0000000800087E0840087E3840087E0800080000000020F8201020303ECC0000
+D136:0000000800087E0840087E3840087E0800080000202021FC207020883E700000
+D137:0000000800087E0840087E3840087E080008000003F802000200020003F80000
+D138:0000000800087E0840087E3840087E080008000007F8000807F8040007F80000
+D139:0000000800087E0840087E3840087E08000800003EF802083E0820083E080000
+D13A:0000000800087E0840087E3840087E08000800003EF802883E8820883EF80000
+D13B:0000000800087E0840087E3840087E08000800003E8802883EF820883EF80000
+D13C:0000000800087E0840087E3840087E08000800000F8800880F8808140FA20000
+D13D:0000000800087E0840087E3840087E08000800003EF802803EF820803EF80000
+D13E:0000000800087E0840087E3840087E08000800003EFC02483E4820483EFC0000
+D13F:0000000800087E0840087E3840087E08000800003E1002FE3E3820443E380000
+D140:0000000800087E0840087E3840087E080008000003F802080208020803F80000
+D141:0000000800087E0840087E3840087E08000800000208020803F8020803F80000
+D142:0000000800087E0840087E3840087E0800080000210821083F0821143F620000
+D143:0000000800087E0840087E3840087E0800080000001000100010006801840000
+D144:0000000800087E0840087E3840087E08000800000048004800A8011406620000
+D145:0000000800087E0840087E3840087E0800080000000003F00408040803F00000
+D146:0000000800087E0840087E3840087E080008000003F80020002000D003080000
+D147:0000000800087E0840087E3840087E0800080000004003F8004000A003180000
+D148:0000000800087E0840087E3840087E080008000003F8000803F8000800080000
+D149:0000000800087E0840087E3840087E080008000003F8020003F8020003F80000
+D14A:0000000800087E0840087E3840087E080008000000000FF8022002200FF80000
+D14B:0000000800087E0840087E3840087E080008000000800FF803E0041003E00000
+D14C:00000000000A000A3F8A200A200A3FBA200A200A3F8A000A000A000A000A0000
+D14D:0000002800287E2840287EE840287E280028000007F800080008000800080000
+D14E:0000002800287E2840287EE840287E280028000000003EF80208020802080000
+D14F:0000002800287E2840287EE840287E280028000000003E100210022802C40000
+D150:0000002800287E2840287EE840287E280028000008000800080008000FF80000
+D151:0000002800287E2840287EE840287E2800280000000020F8201020303ECC0000
+D152:0000002800287E2840287EE840287E2800280000202021FC207020883E700000
+D153:0000002800287E2840287EE840287E280028000003F802000200020003F80000
+D154:0000002800287E2840287EE840287E280028000007F8000807F8040007F80000
+D155:0000002800287E2840287EE840287E28002800003EF802083E0820083E080000
+D156:0000002800287E2840287EE840287E28002800003EF802883E8820883EF80000
+D157:0000002800287E2840287EE840287E28002800003E8802883EF820883EF80000
+D158:0000002800287E2840287EE840287E28002800001F0801081F0810141F620000
+D159:0000002800287E2840287EE840287E28002800003EF802803EF820803EF80000
+D15A:0000002800287E2840287EE840287E28002800003EFC02483E4820483EFC0000
+D15B:0000002800287E2840287EE840287E28002800003E1002FE3E3820443E380000
+D15C:0000002800287E2840287EE840287E280028000003F802080208020803F80000
+D15D:0000002800287E2840287EE840287E28002800000208020803F8020803F80000
+D15E:0000002800287E2840287EE840287E2800280000110811081F0811141F620000
+D15F:0000002800287E2840287EE840287E2800280000000800080008003400C20000
+D160:0000002800287E2840287EE840287E28002800000048004800A8011406620000
+D161:0000002800287E2840287EE840287E2800280000000001F00208020801F00000
+D162:0000002800287E2840287EE840287E280028000003F80020002000D003080000
+D163:0000002800287E2840287EE840287E2800280000004003F8004000A003180000
+D164:0000002800287E2840287EE840287E280028000003F8000803F8000800080000
+D165:0000002800287E2840287EE840287E280028000003F8020003F8020003F80000
+D166:0000002800287E2840287EE840287E280028000000000FF8022002200FF80000
+D167:0000002800287E2840287EE840287E280028000000800FF803E0041003E00000
+D168:00000000000200023F822002201E3F822002201E3F8200020002000200020000
+D169:0000000800087E0840387E0840387E0800080000000007F80008000800080000
+D16A:0000000800087E0840387E0840387E080008000000003EF80208020802080000
+D16B:0000000800087E0840387E0840387E080008000000001F080108011401620000
+D16C:0000000800087E0840387E0840387E080008000800001000100010001FF80000
+D16D:0000000800087E0840387E0840387E0800080000000020F8201020303ECC0000
+D16E:0000000800087E0840387E0840387E0800080000202021FC207020883E700000
+D16F:0000000800087E0840387E0840387E080008000003F802000200020003F80000
+D170:0000000800087E0840387E0840387E080008000007F8000807F8040007F80000
+D171:0000000800087E0840387E0840387E08000800003EF802083E0820083E080000
+D172:0000000800087E0840387E0840387E08000800003EF802883E8820883EF80000
+D173:0000000800087E0840387E0840387E08000800003E8802883EF820883EF80000
+D174:0000000800087E0840387E0840387E08000800000F8800880F8808140FA20000
+D175:0000000800087E0840387E0840387E08000800003EF802803EF820803EF80000
+D176:0000000800087E0840387E0840387E08000800003EFC02483E4820483EFC0000
+D177:0000000800087E0840387E0840387E08000800003E1002FE3E3820443E380000
+D178:0000000800087E0840387E0840387E080008000003F802080208020803F80000
+D179:0000000800087E0840387E0840387E08000800000208020803F8020803F80000
+D17A:0000000800087E0840387E0840387E0800080000210821083F0821143F620000
+D17B:0000000800087E0840387E0840387E0800080000001000100010006801840000
+D17C:0000000800087E0840387E0840387E08000800000048004800A8011406620000
+D17D:0000000800087E0840387E0840387E0800080000000003F00408040803F00000
+D17E:0000000800087E0840387E0840387E080008000003F80020002000D003080000
+D17F:0000000800087E0840387E0840387E0800080000004003F8004000A003180000
+D180:0000000800087E0840387E0840387E080008000003F8000803F8000800080000
+D181:0000000800087E0840387E0840387E080008000003F8020003F8020003F80000
+D182:0000000800087E0840387E0840387E080008000000000FF8022002200FF80000
+D183:0000000800087E0840387E0840387E080008000000800FF803E0041003E00000
+D184:00000000000A000A3F8A200A203A3F8A200A203A3F8A000A000A000A000A0000
+D185:0000002800287E2840E87E2840E87E280028000007F800080008000800080000
+D186:0000002800287E2840E87E2840E87E280028000000003EF80208020802080000
+D187:0000002800287E2840E87E2840E87E280028000000003E100210022802C40000
+D188:0000002800287E2840E87E2840E87E280028002808000800080008000FF80000
+D189:0000002800287E2840E87E2840E87E2800280000000020F8201020303ECC0000
+D18A:0000002800287E2840E87E2840E87E2800280000202021FC207020883E700000
+D18B:0000002800287E2840E87E2840E87E280028000003F802000200020003F80000
+D18C:0000002800287E2840E87E2840E87E280028000007F8000807F8040007F80000
+D18D:0000002800287E2840E87E2840E87E28002800003EF802083E0820083E080000
+D18E:0000002800287E2840E87E2840E87E28002800003EF802883E8820883EF80000
+D18F:0000002800287E2840E87E2840E87E28002800003E8802883EF820883EF80000
+D190:0000002800287E2840E87E2840E87E28002800001F0801081F0810141F620000
+D191:0000002800287E2840E87E2840E87E28002800003EF802803EF820803EF80000
+D192:0000002800287E2840E87E2840E87E28002800003EFC02483E4820483EFC0000
+D193:0000002800287E2840E87E2840E87E28002800003E1002FE3E3820443E380000
+D194:0000002800287E2840E87E2840E87E280028000003F802080208020803F80000
+D195:0000002800287E2840E87E2840E87E28002800000208020803F8020803F80000
+D196:0000002800287E2840E87E2840E87E2800280000110811081F0811141F620000
+D197:0000002800287E2840E87E2840E87E2800280000000800080008003400C20000
+D198:0000002800287E2840E87E2840E87E28002800000048004800A8011406620000
+D199:0000002800287E2840E87E2840E87E2800280000000001F00208020801F00000
+D19A:0000002800287E2840E87E2840E87E280028000003F80020002000D003080000
+D19B:0000002800287E2840E87E2840E87E2800280000004003F8004000A003180000
+D19C:0000002800287E2840E87E2840E87E280028000003F8000803F8000800080000
+D19D:0000002800287E2840E87E2840E87E280028000003F8020003F8020003F80000
+D19E:0000002800287E2840E87E2840E87E280028000000000FF8022002200FF80000
+D19F:0000002800287E2840E87E2840E87E280028000000800FF803E0041003E00000
+D1A0:00003FF8200020003FF8200020003FF8000000000100010001007FFC00000000
+D1A1:00001FF010001FF010001FF0010001007FFC00001FF000100010001000100000
+D1A2:00001FF010001FF010001FF0010001007FFC000000003EF80208020802080000
+D1A3:00001FF010001FF010001FF0010001007FFC000000001E100210022802C40000
+D1A4:00001FF010001FF010001FF0010001007FFC000000001000100010001FF00000
+D1A5:00001FF010001FF010001FF0010001007FFC0000000020F8201020303ECC0000
+D1A6:00001FF010001FF010001FF0010001007FFC0000202021FC207020883E700000
+D1A7:00001FF010001FF010001FF0010001007FFC00001FF01000100010001FF00000
+D1A8:00001FF010001FF010001FF0010001007FFC00001FF000101FF010001FF00000
+D1A9:00001FF010001FF010001FF0010001007FFC00003EF802083E0820083E080000
+D1AA:00001FF010001FF010001FF0010001007FFC00003EF802883E8820883EF80000
+D1AB:00001FF010001FF010001FF0010001007FFC00003E8802883EF820883EF80000
+D1AC:00001FF010001FF010001FF0010001007FFC00003E1002103E1020283EC40000
+D1AD:00001FF010001FF010001FF0010001007FFC00003EF802803EF820803EF80000
+D1AE:00001FF010001FF010001FF0010001007FFC00003EFC02483E4820483EFC0000
+D1AF:00001FF010001FF010001FF0010001007FFC00003E2003FC3E7020883E700000
+D1B0:00001FF010001FF010001FF0010001007FFC00001FF01010101010101FF00000
+D1B1:00001FF010001FF010001FF0010001007FFC0000101010101FF010101FF00000
+D1B2:00001FF010001FF010001FF0010001007FFC0000222022203E2022503E880000
+D1B3:00001FF010001FF010001FF0010001007FFC000000000100010002800C400000
+D1B4:00001FF010001FF010001FF0010001007FFC00000000024002400DA033100000
+D1B5:00001FF010001FF010001FF0010001007FFC0000000007C00820082007C00000
+D1B6:00001FF010001FF010001FF0010001007FFC0000000007E00080014006200000
+D1B7:00001FF010001FF010001FF0010001007FFC0000008007E00080014006200000
+D1B8:00001FF010001FF010001FF0010001007FFC00001FF000101FF0001000100000
+D1B9:00001FF010001FF010001FF0010001007FFC00001FF010001FF010001FF00000
+D1BA:00001FF010001FF010001FF0010001007FFC000000001FF0044004401FF00000
+D1BB:00001FF010001FF010001FF0010001007FFC000001001FF007C0082007C00000
+D1BC:000000103FD0201020103FD02010201E3FD00010041004107FD0001000100000
+D1BD:000000087F0840087F0E40087F0804087FE8000007F800080008000800080000
+D1BE:000000087F0840087F0E40087F0804087FE8000000003EF80208020802080000
+D1BF:000000087F0840087F0E40087F0804087FE8000000001F080108011401620000
+D1C0:000000087F0840087F0E40087F0804087FE8000008000800080008000FF80000
+D1C1:000000087F0840087F0E40087F0804087FE80000000010F8101010301ECC0000
+D1C2:000000087F0840087F0E40087F0804087FE800000808087F081C08220F9C0000
+D1C3:000000087F0840087F0E40087F0804087FE8000003F802000200020003F80000
+D1C4:000000087F0840087F0E40087F0804087FE8000007F8000807F8040007F80000
+D1C5:000000087F0840087F0E40087F0804087FE800003EF802083E0820083E080000
+D1C6:000000087F0840087F0E40087F0804087FE800003EF802883E8820883EF80000
+D1C7:000000087F0840087F0E40087F0804087FE800003E8802883EF820883EF80000
+D1C8:000000087F0840087F0E40087F0804087FE800001F0801081F0810141F620000
+D1C9:000000087F0840087F0E40087F0804087FE800003EF802803EF820803EF80000
+D1CA:000000087F0840087F0E40087F0804087FE800003EFC02483E4820483EFC0000
+D1CB:000000087F0840087F0E40087F0804087FE800001F08017F1F1C10221F1C0000
+D1CC:000000087F0840087F0E40087F0804087FE8000003F802080208020803F80000
+D1CD:000000087F0840087F0E40087F0804087FE800000208020803F8020803F80000
+D1CE:000000087F0840087F0E40087F0804087FE80000110811081F0811141F620000
+D1CF:000000087F0840087F0E40087F0804087FE80000001000100010006801840000
+D1D0:000000087F0840087F0E40087F0804087FE800000048004800A8011406620000
+D1D1:000000087F0840087F0E40087F0804087FE80000000003F00408040803F00000
+D1D2:000000087F0840087F0E40087F0804087FE8000003F80020002000D003080000
+D1D3:000000087F0840087F0E40087F0804087FE80000004003F8004000A003180000
+D1D4:000000087F0840087F0E40087F0804087FE8000003F8000803F8000800080000
+D1D5:000000087F0840087F0E40087F0804087FE8000003F8020003F8020003F80000
+D1D6:000000087F0840087F0E40087F0804087FE8000000000FF8022002200FF80000
+D1D7:000000087F0840087F0E40087F0804087FE8000000800FF803E0041003E00000
+D1D8:000000123FD2201220123FD22012201E3FD20012041204127FD2001200120000
+D1D9:000000287F2840287F3840287F2804287FA8000007F800080008000800080000
+D1DA:000000287F2840287F3840287F2804287FA8000000003EF80208020802080000
+D1DB:000000287F2840287F3840287F2804287FA8000000001F080108011401620000
+D1DC:000000287F2840287F3840287F2804287FA8000008000800080008000FF80000
+D1DD:000000287F2840287F3840287F2804287FA80000000010F8101010301ECC0000
+D1DE:000000287F2840287F3840287F2804287FA800000808087F081C08220F9C0000
+D1DF:000000287F2840287F3840287F2804287FA8000003F802000200020003F80000
+D1E0:000000287F2840287F3840287F2804287FA8000007F8000807F8040007F80000
+D1E1:000000287F2840287F3840287F2804287FA800003EF802083E0820083E080000
+D1E2:000000287F2840287F3840287F2804287FA800003EF802883E8820883EF80000
+D1E3:000000287F2840287F3840287F2804287FA800003E8802883EF820883EF80000
+D1E4:000000287F2840287F3840287F2804287FA800001F0801081F0810141F620000
+D1E5:000000287F2840287F3840287F2804287FA800003EF802803EF820803EF80000
+D1E6:000000287F2840287F3840287F2804287FA800003EFC02483E4820483EFC0000
+D1E7:000000287F2840287F3840287F2804287FA800001F08017F1F1C10221F1C0000
+D1E8:000000287F2840287F3840287F2804287FA8000003F802080208020803F80000
+D1E9:000000287F2840287F3840287F2804287FA800000208020803F8020803F80000
+D1EA:000000287F2840287F3840287F2804287FA80000110811081F0811141F620000
+D1EB:000000287F2840287F3840287F2804287FA80000001000100010006801840000
+D1EC:000000287F2840287F3840287F2804287FA800000048004800A8011406620000
+D1ED:000000287F2840287F3840287F2804287FA80000000003F00408040803F00000
+D1EE:000000287F2840287F3840287F2804287FA8000003F80020002000D003080000
+D1EF:000000287F2840287F3840287F2804287FA80000004003F8004000A003180000
+D1F0:000000287F2840287F3840287F2804287FA8000003F8000803F8000800080000
+D1F1:000000287F2840287F3840287F2804287FA8000003F8020003F8020003F80000
+D1F2:000000287F2840287F3840287F2804287FA8000000000FF8022002200FF80000
+D1F3:000000287F2840287F3840287F2804287FA8000000800FF803E0041003E00000
+D1F4:000000083FC8200820083FC8200820083FC80008040804087FE8000800080000
+D1F5:000000087F0840087F0840087F0804087FE8000007F800080008000800080000
+D1F6:000000087F0840087F0840087F0804087FE8000000003EF80208020802080000
+D1F7:000000087F0840087F0840087F0804087FE8000000001F080108011401620000
+D1F8:000000087F0840087F0840087F0804087FE8000008000800080008000FF80000
+D1F9:000000087F0840087F0840087F0804087FE80000000010F8101010301ECC0000
+D1FA:000000087F0840087F0840087F0804087FE800000808087F081C08220F9C0000
+D1FB:000000087F0840087F0840087F0804087FE8000003F802000200020003F80000
+D1FC:000000087F0840087F0840087F0804087FE8000007F8000807F8040007F80000
+D1FD:000000087F0840087F0840087F0804087FE800003EF802083E0820083E080000
+D1FE:000000087F0840087F0840087F0804087FE800003EF802883E8820883EF80000
+D1FF:000000087F0840087F0840087F0804087FE800003E8802883EF820883EF80000
+D200:000000087F0840087F0840087F0804087FE800001F0801081F0810141F620000
+D201:000000087F0840087F0840087F0804087FE800003EF802803EF820803EF80000
+D202:000000087F0840087F0840087F0804087FE800003EFC02483E4820483EFC0000
+D203:000000087F0840087F0840087F0804087FE800001F08017F1F1C10221F1C0000
+D204:000000087F0840087F0840087F0804087FE8000003F802080208020803F80000
+D205:000000087F0840087F0840087F0804087FE800000208020803F8020803F80000
+D206:000000087F0840087F0840087F0804087FE80000110811081F0811141F620000
+D207:000000087F0840087F0840087F0804087FE80000001000100010006801840000
+D208:000000087F0840087F0840087F0804087FE800000048004800A8011406620000
+D209:000000087F0840087F0840087F0804087FE80000000003F00408040803F00000
+D20A:000000087F0840087F0840087F0804087FE8000003F80020002000D003080000
+D20B:000000087F0840087F0840087F0804087FE80000004003F8004000A003180000
+D20C:000000087F0840087F0840087F0804087FE8000003F8000803F8000800080000
+D20D:000000087F0840087F0840087F0804087FE8000003F8020003F8020003F80000
+D20E:000000087F0840087F0840087F0804087FE8000000000FF8022002200FF80000
+D20F:000000087F0840087F0840087F0804087FE8000000800FF803E0041003E00000
+D210:00003FF8200020003FF8200020003FF8000004400440044004407FFC00000000
+D211:00001FF010001FF010001FF0044004407FFC00001FF000100010001000100000
+D212:00001FF010001FF010001FF0044004407FFC000000003EF80208020802080000
+D213:00001FF010001FF010001FF0044004407FFC000000001E100210022802C40000
+D214:00001FF010001FF010001FF0044004407FFC000000001000100010001FF00000
+D215:00001FF010001FF010001FF0044004407FFC0000000020F8201020303ECC0000
+D216:00001FF010001FF010001FF0044004407FFC0000202021FC207020883E700000
+D217:00001FF010001FF010001FF0044004407FFC00001FF01000100010001FF00000
+D218:00001FF010001FF010001FF0044004407FFC00001FF000101FF010001FF00000
+D219:00001FF010001FF010001FF0044004407FFC00003EF802083E0820083E080000
+D21A:00001FF010001FF010001FF0044004407FFC00003EF802883E8820883EF80000
+D21B:00001FF010001FF010001FF0044004407FFC00003E8802883EF820883EF80000
+D21C:00001FF010001FF010001FF0044004407FFC00003E1002103E1020283EC40000
+D21D:00001FF010001FF010001FF0044004407FFC00003EF802803EF820803EF80000
+D21E:00001FF010001FF010001FF0044004407FFC00003EFC02483E4820483EFC0000
+D21F:00001FF010001FF010001FF0044004407FFC00003E2003FC3E7020883E700000
+D220:00001FF010001FF010001FF0044004407FFC00001FF01010101010101FF00000
+D221:00001FF010001FF010001FF0044004407FFC0000101010101FF010101FF00000
+D222:00001FF010001FF010001FF0044004407FFC0000222022203E2022503E880000
+D223:00001FF010001FF010001FF0044004407FFC000000000100010002800C400000
+D224:00001FF010001FF010001FF0044004407FFC00000000024002400DA033100000
+D225:00001FF010001FF010001FF0044004407FFC0000000007C00820082007C00000
+D226:00001FF010001FF010001FF0044004407FFC0000000007E00080014006200000
+D227:00001FF010001FF010001FF0044004407FFC0000008007E00080014006200000
+D228:00001FF010001FF010001FF0044004407FFC00001FF000101FF0001000100000
+D229:00001FF010001FF010001FF0044004407FFC00001FF010001FF010001FF00000
+D22A:00001FF010001FF010001FF0044004407FFC000000001FF0044004401FF00000
+D22B:00001FF010001FF010001FF0044004407FFC000001001FF007C0082007C00000
+D22C:000000003FF8200020003FF8200020003FF800003FF801000100010001000000
+D22D:00001FF010001FF010001FF000007FFC010001001FF000100010001000100000
+D22E:00001FF010001FF010001FF000007FFC0100010000003EF80208020802080000
+D22F:00001FF010001FF010001FF000007FFC0100010000001E100210022802C40000
+D230:00001FF010001FF010001FF0000000007FFC010001001100100010001FF00000
+D231:00001FF010001FF010001FF000007FFC01000100000020F8201020303ECC0000
+D232:00001FF010001FF010001FF000007FFC01000100202021FC207020883E700000
+D233:00001FF010001FF010001FF000007FFC010001001FF01000100010001FF00000
+D234:00001FF010001FF010001FF000007FFC010001001FF000101FF010001FF00000
+D235:00001FF010001FF010001FF000007FFC010001003EF802083E0820083E080000
+D236:00001FF010001FF010001FF000007FFC010001003EF802883E8820883EF80000
+D237:00001FF010001FF010001FF000007FFC010001003E8802883EF820883EF80000
+D238:00001FF010001FF010001FF000007FFC010001003E1002103E1020283EC40000
+D239:00001FF010001FF010001FF000007FFC010001003EF802803EF820803EF80000
+D23A:00001FF010001FF010001FF000007FFC010001003EFC02483E4820483EFC0000
+D23B:00001FF010001FF010001FF000007FFC010001003E2003FC3E7020883E700000
+D23C:00001FF010001FF010001FF000007FFC010001001FF01010101010101FF00000
+D23D:00001FF010001FF010001FF000007FFC01000100101010101FF010101FF00000
+D23E:00001FF010001FF010001FF000007FFC01000100222022203E2022503E880000
+D23F:00001FF010001FF010001FF000007FFC0100010000000100010002800C400000
+D240:00001FF010001FF010001FF000007FFC010001000000024002400DA033100000
+D241:00001FF010001FF010001FF000007FFC01000100000007C00820082007C00000
+D242:00001FF010001FF010001FF000007FFC01000100000007E00080014006200000
+D243:00001FF010001FF010001FF000007FFC01000100008007E00080014006200000
+D244:00001FF010001FF010001FF000007FFC010001001FF000101FF0001000100000
+D245:00001FF010001FF010001FF000007FFC010001001FF010001FF010001FF00000
+D246:00001FF010001FF010001FF000007FFC0100010000001FF0044004401FF00000
+D247:00001FF010001FF010001FF000007FFC0100010001001FF007C0082007C00000
+D248:000000083FC8200820083FC8200820083FC800087FE8040804F8040804080000
+D249:7F8840087F8840087F8800087FE8027802080000000007F80008000800080000
+D24A:7F8840087F8840087F8800087FE802780208000000003EF80208020802080000
+D24B:7F8840087F8840087F8800087FE802780208000000001F080108011401620000
+D24C:7F8840087F8840087F88000800087FE80278020802081000100010001FF80000
+D24D:7F8840087F8840087F8800087FE8027802080000000020F8201020303ECC0000
+D24E:7F8840087F8840087F8800087FE8027802080000202021FC207020883E700000
+D24F:7F8840087F8840087F8800087FE802780208000003F802000200020003F80000
+D250:7F8840087F8840087F8800087FE802780208000007F8000807F8040007F80000
+D251:7F8840087F8840087F8800087FE80278020800003EF802083E0820083E080000
+D252:7F8840087F8840087F8800087FE80278020800003EF802883E8820883EF80000
+D253:7F8840087F8840087F8800087FE80278020800003E8802883EF820883EF80000
+D254:7F8840087F8840087F8800087FE80278020800000F8800880F8808140FA20000
+D255:7F8840087F8840087F8800087FE80278020800003EF802803EF820803EF80000
+D256:7F8840087F8840087F8800087FE80278020800003EFC02483E4820483EFC0000
+D257:7F8840087F8840087F8800087FE80278020800003E1002FE3E3820443E380000
+D258:7F8840087F8840087F8800087FE802780208000003F802080208020803F80000
+D259:7F8840087F8840087F8800087FE80278020800000208020803F8020803F80000
+D25A:7F8840087F8840087F8800087FE8027802080000210821083F0821143F620000
+D25B:7F8840087F8840087F8800087FE8027802080000001000100010006801840000
+D25C:7F8840087F8840087F8800087FE80278020800000048004800A8011406620000
+D25D:7F8840087F8840087F8800087FE8027802080000000003F00408040803F00000
+D25E:7F8840087F8840087F8800087FE802780208000003F80020002000D003080000
+D25F:7F8840087F8840087F8800087FE8027802080000004003F8004000A003180000
+D260:7F8840087F8840087F8800087FE802780208000003F8000803F8000800080000
+D261:7F8840087F8840087F8800087FE802780208000003F8020003F8020003F80000
+D262:7F8840087F8840087F8800087FE802780208000000000FF8022002200FF80000
+D263:7F8840087F8840087F8800087FE802780208000000800FF803E0041003E00000
+D264:0000000A3FCA200A200A3FCA200A200A3FCA000A7FEA040A047A040A040A0000
+D265:7FA840287FA840287FA800287FA805E804280000000007F80008000800080000
+D266:7FA840287FA840287FA800287FA805E80428000000003EF80208020802080000
+D267:7FA840287FA840287FA800287FA805E80428000000001F080108011401620000
+D268:7FA840287FA840287FA8002800287FA8042805E804281428100010001FF80000
+D269:7FA840287FA840287FA800287FA805E804280000000020F8201020303ECC0000
+D26A:7FA840287FA840287FA800287FA805E804280000202021FC207020883E700000
+D26B:7FA840287FA840287FA800287FA805E80428000003F802000200020003F80000
+D26C:7FA840287FA840287FA800287FA805E80428000007F8000807F8040007F80000
+D26D:7FA840287FA840287FA800287FA805E8042800003EF802083E0820083E080000
+D26E:7FA840287FA840287FA800287FA805E8042800003EF802883E8820883EF80000
+D26F:7FA840287FA840287FA800287FA805E8042800003E8802883EF820883EF80000
+D270:7FA840287FA840287FA800287FA805E8042800000F8800880F8808140FA20000
+D271:7FA840287FA840287FA800287FA805E8042800003EF802803EF820803EF80000
+D272:7FA840287FA840287FA800287FA805E8042800003EFC02483E4820483EFC0000
+D273:7FA840287FA840287FA800287FA805E8042800003E1002FE3E3820443E380000
+D274:7FA840287FA840287FA800287FA805E80428000003F802080208020803F80000
+D275:7FA840287FA840287FA800287FA805E8042800000208020803F8020803F80000
+D276:7FA840287FA840287FA800287FA805E804280000210821083F0821143F620000
+D277:7FA840287FA840287FA800287FA805E804280000001000100010006801840000
+D278:7FA840287FA840287FA800287FA805E8042800000048004800A8011406620000
+D279:7FA840287FA840287FA800287FA805E804280000000003F00408040803F00000
+D27A:7FA840287FA840287FA800287FA805E80428000003F80020002000D003080000
+D27B:7FA840287FA840287FA800287FA805E804280000004003F8004000A003180000
+D27C:7FA840287FA840287FA800287FA805E80428000003F8000803F8000800080000
+D27D:7FA840287FA840287FA800287FA805E80428000003F8020003F8020003F80000
+D27E:7FA840287FA840287FA800287FA805E80428000000000FF8022002200FF80000
+D27F:7FA840287FA840287FA800287FA805E80428000000800FF803E0041003E00000
+D280:000000083FC8200820083FC8200820083FC800087FE804080408040804080000
+D281:7F8840087F8840087F8800087FE8020802000000000007F80008000800080000
+D282:7F8840087F8840087F8800087FE802080200000000003EF80208020802080000
+D283:7F8840087F8840087F8800087FE802080200000000001F080108011401620000
+D284:7F8840087F8840087F88000800087FE80208020802081008100010001FF80000
+D285:7F8840087F8840087F8800087FE8020802000000000020F8201020303ECC0000
+D286:7F8840087F8840087F8800087FE8020802000000202021FC207020883E700000
+D287:7F8840087F8840087F8800087FE802080200000003F802000200020003F80000
+D288:7F8840087F8840087F8800087FE802080200000007F8000807F8040007F80000
+D289:7F8840087F8840087F8800087FE80208020000003EF802083E0820083E080000
+D28A:7F8840087F8840087F8800087FE80208020000003EF802883E8820883EF80000
+D28B:7F8840087F8840087F8800087FE80208020000003E8802883EF820883EF80000
+D28C:7F8840087F8840087F8800087FE80208020000000F8800880F8808140FA20000
+D28D:7F8840087F8840087F8800087FE80208020000003EF802803EF820803EF80000
+D28E:7F8840087F8840087F8800087FE80208020000003EFC02483E4820483EFC0000
+D28F:7F8840087F8840087F8800087FE80208020000003E1002FE3E3820443E380000
+D290:7F8840087F8840087F8800087FE802080200000003F802080208020803F80000
+D291:7F8840087F8840087F8800087FE80208020000000208020803F8020803F80000
+D292:7F8840087F8840087F8800087FE8020802000000210821083F0821143F620000
+D293:7F8840087F8840087F8800087FE8020802000000001000100010006801840000
+D294:7F8840087F8840087F8800087FE80208020000000048004800A8011406620000
+D295:7F8840087F8840087F8800087FE8020802000000000003F00408040803F00000
+D296:7F8840087F8840087F8800087FE802080200000003F80020002000D003080000
+D297:7F8840087F8840087F8800087FE8020802000000004003F8004000A003180000
+D298:7F8840087F8840087F8800087FE802080200000003F8000803F8000800080000
+D299:7F8840087F8840087F8800087FE802080200000003F8020003F8020003F80000
+D29A:7F8840087F8840087F8800087FE802080200000000000FF8022002200FF80000
+D29B:7F8840087F8840087F8800087FE802080200000000800FF803E0041003E00000
+D29C:000000003FF8200020003FF8200020003FF800007FFC04400440044004400000
+D29D:00001FF010001FF010001FF000007FFC044004401FF000100010001000100000
+D29E:00001FF010001FF010001FF000007FFC0440044000003EF80208020802080000
+D29F:00001FF010001FF010001FF000007FFC0440044000001E100210022802C40000
+D2A0:00001FF010001FF010001FF0000000007FFC044004401440100010001FF00000
+D2A1:00001FF010001FF010001FF000007FFC04400440000020F8201020303ECC0000
+D2A2:00001FF010001FF010001FF000007FFC04400440202021FC207020883E700000
+D2A3:00001FF010001FF010001FF000007FFC044004401FF01000100010001FF00000
+D2A4:00001FF010001FF010001FF000007FFC044004401FF000101FF010001FF00000
+D2A5:00001FF010001FF010001FF000007FFC044004403EF802083E0820083E080000
+D2A6:00001FF010001FF010001FF000007FFC044004403EF802883E8820883EF80000
+D2A7:00001FF010001FF010001FF000007FFC044004403E8802883EF820883EF80000
+D2A8:00001FF010001FF010001FF000007FFC044004403E1002103E1020283EC40000
+D2A9:00001FF010001FF010001FF000007FFC044004403EF802803EF820803EF80000
+D2AA:00001FF010001FF010001FF000007FFC044004403EFC02483E4820483EFC0000
+D2AB:00001FF010001FF010001FF000007FFC044004403E2003FC3E7020883E700000
+D2AC:00001FF010001FF010001FF000007FFC044004401FF01010101010101FF00000
+D2AD:00001FF010001FF010001FF000007FFC04400440101010101FF010101FF00000
+D2AE:00001FF010001FF010001FF000007FFC04400440222022203E2022503E880000
+D2AF:00001FF010001FF010001FF000007FFC0440044000000100010002800C400000
+D2B0:00001FF010001FF010001FF000007FFC044004400000024002400DA033100000
+D2B1:00001FF010001FF010001FF000007FFC04400440000007C00820082007C00000
+D2B2:00001FF010001FF010001FF000007FFC04400440000007E00080014006200000
+D2B3:00001FF010001FF010001FF000007FFC04400440008007E00080014006200000
+D2B4:00001FF010001FF010001FF000007FFC044004401FF000101FF0001000100000
+D2B5:00001FF010001FF010001FF000007FFC044004401FF010001FF010001FF00000
+D2B6:00001FF010001FF010001FF000007FFC0440044000001FF0044004401FF00000
+D2B7:00001FF010001FF010001FF000007FFC0440044001001FF007C0082007C00000
+D2B8:00003FF8200020003FF8200020003FF80000000000007FFC0000000000000000
+D2B9:00001FF010001FF010001FF0000000007FFC00001FF000100010001000100000
+D2BA:00001FF010001FF010001FF0000000007FFC000000003EF80208020802080000
+D2BB:00001FF010001FF010001FF0000000007FFC000000001E100210022802C40000
+D2BC:00001FF010001FF010001FF0000000007FFC000000001000100010001FF00000
+D2BD:00001FF010001FF010001FF0000000007FFC0000000020F8201020303ECC0000
+D2BE:00001FF010001FF010001FF0000000007FFC0000202021FC207020883E700000
+D2BF:00001FF010001FF010001FF0000000007FFC00001FF01000100010001FF00000
+D2C0:00001FF010001FF010001FF0000000007FFC00001FF000101FF010001FF00000
+D2C1:00001FF010001FF010001FF0000000007FFC00003EF802083E0820083E080000
+D2C2:00001FF010001FF010001FF0000000007FFC00003EF802883E8820883EF80000
+D2C3:00001FF010001FF010001FF0000000007FFC00003E8802883EF820883EF80000
+D2C4:00001FF010001FF010001FF0000000007FFC00003E1002103E1020283EC40000
+D2C5:00001FF010001FF010001FF0000000007FFC00003EF802803EF820803EF80000
+D2C6:00001FF010001FF010001FF0000000007FFC00003EFC02483E4820483EFC0000
+D2C7:00001FF010001FF010001FF0000000007FFC00003E2003FC3E7020883E700000
+D2C8:00001FF010001FF010001FF0000000007FFC00001FF01010101010101FF00000
+D2C9:00001FF010001FF010001FF0000000007FFC0000101010101FF010101FF00000
+D2CA:00001FF010001FF010001FF0000000007FFC0000222022203E2022503E880000
+D2CB:00001FF010001FF010001FF0000000007FFC000000000100010002800C400000
+D2CC:00001FF010001FF010001FF0000000007FFC00000000024002400DA033100000
+D2CD:00001FF010001FF010001FF0000000007FFC0000000007C00820082007C00000
+D2CE:00001FF010001FF010001FF0000000007FFC0000000007E00080014006200000
+D2CF:00001FF010001FF010001FF0000000007FFC0000008007E00080014006200000
+D2D0:00001FF010001FF010001FF0000000007FFC00001FF000101FF0001000100000
+D2D1:00001FF010001FF010001FF0000000007FFC00001FF010001FF010001FF00000
+D2D2:00001FF010001FF010001FF0000000007FFC000000001FF0044004401FF00000
+D2D3:00001FF010001FF010001FF0000000007FFC000001001FF007C0082007C00000
+D2D4:000000083FC8200820083FC8200820083FC8000800087FE80008000800080000
+D2D5:000000087F0840087F0840087F0800087FE8000007F800080008000800080000
+D2D6:000000087F0840087F0840087F0800087FE8000000003EF80208020802080000
+D2D7:000000087F0840087F0840087F0800087FE8000000001F080108011401620000
+D2D8:000000087F0840087F0840087F0800087FE8000008000800080008000FF80000
+D2D9:000000087F0840087F0840087F0800087FE80000000010F8101010301ECC0000
+D2DA:000000087F0840087F0840087F0800087FE800000808087F081C08220F9C0000
+D2DB:000000087F0840087F0840087F0800087FE8000003F802000200020003F80000
+D2DC:000000087F0840087F0840087F0800087FE8000007F8000807F8040007F80000
+D2DD:000000087F0840087F0840087F0800087FE800003EF802083E0820083E080000
+D2DE:000000087F0840087F0840087F0800087FE800003EF802883E8820883EF80000
+D2DF:000000087F0840087F0840087F0800087FE800003E8802883EF820883EF80000
+D2E0:000000087F0840087F0840087F0800087FE800001F0801081F0810141F620000
+D2E1:000000087F0840087F0840087F0800087FE800003EF802803EF820803EF80000
+D2E2:000000087F0840087F0840087F0800087FE800003EFC02483E4820483EFC0000
+D2E3:000000087F0840087F0840087F0800087FE800001F08017F1F1C10221F1C0000
+D2E4:000000087F0840087F0840087F0800087FE8000003F802080208020803F80000
+D2E5:000000087F0840087F0840087F0800087FE800000208020803F8020803F80000
+D2E6:000000087F0840087F0840087F0800087FE80000110811081F0811141F620000
+D2E7:000000087F0840087F0840087F0800087FE80000001000100010006801840000
+D2E8:000000087F0840087F0840087F0800087FE800000048004800A8011406620000
+D2E9:000000087F0840087F0840087F0800087FE80000000003F00408040803F00000
+D2EA:000000087F0840087F0840087F0800087FE8000003F80020002000D003080000
+D2EB:000000087F0840087F0840087F0800087FE80000004003F8004000A003180000
+D2EC:000000087F0840087F0840087F0800087FE8000003F8000803F8000800080000
+D2ED:000000087F0840087F0840087F0800087FE8000003F8020003F8020003F80000
+D2EE:000000087F0840087F0840087F0800087FE8000000000FF8022002200FF80000
+D2EF:000000087F0840087F0840087F0800087FE8000000800FF803E0041003E00000
+D2F0:00000000000800083F88200820083F88200820083F8800080008000800080000
+D2F1:0000000800087E0840087E0840087E0800080000000007F80008000800080000
+D2F2:0000000800087E0840087E0840087E080008000000003EF80208020802080000
+D2F3:0000000800087E0840087E0840087E080008000000001F080108011401620000
+D2F4:0000000800087E0840087E0840087E080008000800001000100010001FF80000
+D2F5:0000000800087E0840087E0840087E0800080000000020F8201020303ECC0000
+D2F6:0000000800087E0840087E0840087E0800080000202021FC207020883E700000
+D2F7:0000000800087E0840087E0840087E080008000003F802000200020003F80000
+D2F8:0000000800087E0840087E0840087E080008000007F8000807F8040007F80000
+D2F9:0000000800087E0840087E0840087E08000800003EF802083E0820083E080000
+D2FA:0000000800087E0840087E0840087E08000800003EF802883E8820883EF80000
+D2FB:0000000800087E0840087E0840087E08000800003E8802883EF820883EF80000
+D2FC:0000000800087E0840087E0840087E08000800000F8800880F8808140FA20000
+D2FD:0000000800087E0840087E0840087E08000800003EF802803EF820803EF80000
+D2FE:0000000800087E0840087E0840087E08000800003EFC02483E4820483EFC0000
+D2FF:0000000800087E0840087E0840087E08000800003E1002FE3E3820443E380000
+D300:0000000800087E0840087E0840087E080008000003F802080208020803F80000
+D301:0000000800087E0840087E0840087E08000800000208020803F8020803F80000
+D302:0000000800087E0840087E0840087E0800080000210821083F0821143F620000
+D303:0000000800087E0840087E0840087E0800080000001000100010006801840000
+D304:0000000800087E0840087E0840087E08000800000048004800A8011406620000
+D305:0000000800087E0840087E0840087E0800080000000003F00408040803F00000
+D306:0000000800087E0840087E0840087E080008000003F80020002000D003080000
+D307:0000000800087E0840087E0840087E0800080000004003F8004000A003180000
+D308:0000000800087E0840087E0840087E080008000003F8000803F8000800080000
+D309:0000000800087E0840087E0840087E080008000003F8020003F8020003F80000
+D30A:0000000800087E0840087E0840087E080008000000000FF8022002200FF80000
+D30B:0000000800087E0840087E0840087E080008000000800FF803E0041003E00000
+D30C:00000000001000107FD011101110111E111011107FD000100010001000100000
+D30D:0000000800087F881208120E12087F880008000007F800080008000800080000
+D30E:0000000800087F881208120E12087F880008000000003EF80208020802080000
+D30F:0000000800087F881208120E12087F880008000000001F080108011401620000
+D310:0000000800087F881208120E12087F880008000808000800080008000FF80000
+D311:0000000800087F881208120E12087F8800080000000010F8101010301ECC0000
+D312:0000000800087F881208120E12087F88000800000808087F081C08220F9C0000
+D313:0000000800087F881208120E12087F880008000003F802000200020003F80000
+D314:0000000800087F881208120E12087F880008000007F8000807F8040007F80000
+D315:0000000800087F881208120E12087F88000800003EF802083E0820083E080000
+D316:0000000800087F881208120E12087F88000800003EF802883E8820883EF80000
+D317:0000000800087F881208120E12087F88000800003E8802883EF820883EF80000
+D318:0000000800087F881208120E12087F88000800001F0801081F0810141F620000
+D319:0000000800087F881208120E12087F88000800003EF802803EF820803EF80000
+D31A:0000000800087F881208120E12087F88000800003EFC02483E4820483EFC0000
+D31B:0000000800087F881208120E12087F88000800001F08017F1F1C10221F1C0000
+D31C:0000000800087F881208120E12087F880008000003F802080208020803F80000
+D31D:0000000800087F881208120E12087F88000800000208020803F8020803F80000
+D31E:0000000800087F881208120E12087F8800080000110811081F0811141F620000
+D31F:0000000800087F881208120E12087F8800080000001000100010006801840000
+D320:0000000800087F881208120E12087F88000800000048004800A8011406620000
+D321:0000000800087F881208120E12087F8800080000000003F00408040803F00000
+D322:0000000800087F881208120E12087F880008000003F80020002000D003080000
+D323:0000000800087F881208120E12087F8800080000004003F8004000A003180000
+D324:0000000800087F881208120E12087F880008000003F8000803F8000800080000
+D325:0000000800087F881208120E12087F880008000003F8020003F8020003F80000
+D326:0000000800087F881208120E12087F880008000000000FF8022002200FF80000
+D327:0000000800087F881208120E12087F880008000000800FF803E0041003E00000
+D328:00000000001200127FD211121112111E111211127FD200120012001200120000
+D329:0000002800287FA81228123812287FA80028000007F800080008000800080000
+D32A:0000002800287FA81228123812287FA80028000000003EF80208020802080000
+D32B:0000002800287FA81228123812287FA80028000000003E100210022802C40000
+D32C:0000002800287FA81228123812287FA80028002808000800080008000FF80000
+D32D:0000002800287FA81228123812287FA800280000000020F8201020303ECC0000
+D32E:0000002800287FA81228123812287FA800280000202021FC207020883E700000
+D32F:0000002800287FA81228123812287FA80028000003F802000200020003F80000
+D330:0000002800287FA81228123812287FA80028000007F8000807F8040007F80000
+D331:0000002800287FA81228123812287FA8002800003EF802083E0820083E080000
+D332:0000002800287FA81228123812287FA8002800003EF802883E8820883EF80000
+D333:0000002800287FA81228123812287FA8002800003E8802883EF820883EF80000
+D334:0000002800287FA81228123812287FA8002800001F0801081F0810141F620000
+D335:0000002800287FA81228123812287FA8002800003EF802803EF820803EF80000
+D336:0000002800287FA81228123812287FA8002800003EFC02483E4820483EFC0000
+D337:0000002800287FA81228123812287FA8002800003E1002FE3E3820443E380000
+D338:0000002800287FA81228123812287FA80028000003F802080208020803F80000
+D339:0000002800287FA81228123812287FA8002800000208020803F8020803F80000
+D33A:0000002800287FA81228123812287FA800280000110811081F0811141F620000
+D33B:0000002800287FA81228123812287FA800280000000800080008003400C20000
+D33C:0000002800287FA81228123812287FA8002800000048004800A8011406620000
+D33D:0000002800287FA81228123812287FA800280000000001F00208020801F00000
+D33E:0000002800287FA81228123812287FA80028000003F80020002000D003080000
+D33F:0000002800287FA81228123812287FA800280000004003F8004000A003180000
+D340:0000002800287FA81228123812287FA80028000003F8000803F8000800080000
+D341:0000002800287FA81228123812287FA80028000003F8020003F8020003F80000
+D342:0000002800287FA81228123812287FA80028000000000FF8022002200FF80000
+D343:0000002800287FA81228123812287FA80028000000800FF803E0041003E00000
+D344:00000000001000107FD01110111E11101110111E7FD000100010001000100000
+D345:0000000800087F88120E1208120E7F880008000007F800080008000800080000
+D346:0000000800087F88120E1208120E7F880008000000003EF80208020802080000
+D347:0000000800087F88120E1208120E7F880008000000001F080108011401620000
+D348:0000000800087F88120E1208120E7F880008000008000800080008000FF80000
+D349:0000000800087F88120E1208120E7F8800080000000010F8101010301ECC0000
+D34A:0000000800087F88120E1208120E7F88000800000808087F081C08220F9C0000
+D34B:0000000800087F88120E1208120E7F880008000003F802000200020003F80000
+D34C:0000000800087F88120E1208120E7F880008000007F8000807F8040007F80000
+D34D:0000000800087F88120E1208120E7F88000800003EF802083E0820083E080000
+D34E:0000000800087F88120E1208120E7F88000800003EF802883E8820883EF80000
+D34F:0000000800087F88120E1208120E7F88000800003E8802883EF820883EF80000
+D350:0000000800087F88120E1208120E7F88000800001F0801081F0810141F620000
+D351:0000000800087F88120E1208120E7F88000800003EF802803EF820803EF80000
+D352:0000000800087F88120E1208120E7F88000800003EFC02483E4820483EFC0000
+D353:0000000800087F88120E1208120E7F88000800001F08017F1F1C10221F1C0000
+D354:0000000800087F88120E1208120E7F880008000003F802080208020803F80000
+D355:0000000800087F88120E1208120E7F88000800000208020803F8020803F80000
+D356:0000000800087F88120E1208120E7F8800080000110811081F0811141F620000
+D357:0000000800087F88120E1208120E7F8800080000001000100010006801840000
+D358:0000000800087F88120E1208120E7F88000800000048004800A8011406620000
+D359:0000000800087F88120E1208120E7F8800080000000003F00408040803F00000
+D35A:0000000800087F88120E1208120E7F880008000003F80020002000D003080000
+D35B:0000000800087F88120E1208120E7F8800080000004003F8004000A003180000
+D35C:0000000800087F88120E1208120E7F880008000003F8000803F8000800080000
+D35D:0000000800087F88120E1208120E7F880008000003F8020003F8020003F80000
+D35E:0000000800087F88120E1208120E7F880008000000000FF8022002200FF80000
+D35F:0000000800087F88120E1208120E7F880008000000800FF803E0041003E00000
+D360:00000000001200127FD21112111E11121112111E7FD200120012001200120000
+D361:0000002800287FA81238122812387FA80028000007F800080008000800080000
+D362:0000002800287FA81238122812387FA80028000000003EF80208020802080000
+D363:0000002800287FA81238122812387FA80028000000003E100210022802C40000
+D364:0000002800287FA81238122812387FA80028002808000800080008000FF80000
+D365:0000002800287FA81238122812387FA800280000000020F8201020303ECC0000
+D366:0000002800287FA81238122812387FA800280000202021FC207020883E700000
+D367:0000002800287FA81238122812387FA80028000003F802000200020003F80000
+D368:0000002800287FA81238122812387FA80028000007F8000807F8040007F80000
+D369:0000002800287FA81238122812387FA8002800003EF802083E0820083E080000
+D36A:0000002800287FA81238122812387FA8002800003EF802883E8820883EF80000
+D36B:0000002800287FA81238122812387FA8002800003E8802883EF820883EF80000
+D36C:0000002800287FA81238122812387FA8002800001F0801081F0810141F620000
+D36D:0000002800287FA81238122812387FA8002800003EF802803EF820803EF80000
+D36E:0000002800287FA81238122812387FA8002800003EFC02483E4820483EFC0000
+D36F:0000002800287FA81238122812387FA8002800003E1002FE3E3820443E380000
+D370:0000002800287FA81238122812387FA80028000003F802080208020803F80000
+D371:0000002800287FA81238122812387FA8002800000208020803F8020803F80000
+D372:0000002800287FA81238122812387FA800280000110811081F0811141F620000
+D373:0000002800287FA81238122812387FA800280000000800080008003400C20000
+D374:0000002800287FA81238122812387FA8002800000048004800A8011406620000
+D375:0000002800287FA81238122812387FA800280000000001F00208020801F00000
+D376:0000002800287FA81238122812387FA80028000003F80020002000D003080000
+D377:0000002800287FA81238122812387FA800280000004003F8004000A003180000
+D378:0000002800287FA81238122812387FA80028000003F8000803F8000800080000
+D379:0000002800287FA81238122812387FA80028000003F8020003F8020003F80000
+D37A:0000002800287FA81238122812387FA80028000000000FF8022002200FF80000
+D37B:0000002800287FA81238122812387FA80028000000800FF803E0041003E00000
+D37C:00000000000200027FC211021102111E110211027FC200020002000200020000
+D37D:0000000800087F881208123812087F8800080000000007F80008000800080000
+D37E:0000000800087F881208123812087F880008000000003EF80208020802080000
+D37F:0000000800087F881208123812087F880008000000001F080108011401620000
+D380:0000000800087F881208123812087F880008000000001000100010001FF80000
+D381:0000000800087F881208123812087F8800080000000020F8201020303ECC0000
+D382:0000000800087F881208123812087F8800080000202021FC207020883E700000
+D383:0000000800087F881208123812087F880008000003F802000200020003F80000
+D384:0000000800087F881208123812087F880008000007F8000807F8040007F80000
+D385:0000000800087F881208123812087F88000800003EF802083E0820083E080000
+D386:0000000800087F881208123812087F88000800003EF802883E8820883EF80000
+D387:0000000800087F881208123812087F88000800003E8802883EF820883EF80000
+D388:0000000800087F881208123812087F88000800000F8800880F8808140FA20000
+D389:0000000800087F881208123812087F88000800003EF802803EF820803EF80000
+D38A:0000000800087F881208123812087F88000800003EFC02483E4820483EFC0000
+D38B:0000000800087F881208123812087F88000800003E1002FE3E3820443E380000
+D38C:0000000800087F881208123812087F880008000003F802080208020803F80000
+D38D:0000000800087F881208123812087F88000800000208020803F8020803F80000
+D38E:0000000800087F881208123812087F8800080000210821083F0821143F620000
+D38F:0000000800087F881208123812087F8800080000001000100010006801840000
+D390:0000000800087F881208123812087F88000800000048004800A8011406620000
+D391:0000000800087F881208123812087F8800080000000003F00408040803F00000
+D392:0000000800087F881208123812087F880008000003F80020002000D003080000
+D393:0000000800087F881208123812087F8800080000004003F8004000A003180000
+D394:0000000800087F881208123812087F880008000003F8000803F8000800080000
+D395:0000000800087F881208123812087F880008000003F8020003F8020003F80000
+D396:0000000800087F881208123812087F880008000000000FF8022002200FF80000
+D397:0000000800087F881208123812087F880008000000800FF803E0041003E00000
+D398:00000000000A000A7FCA110A110A113A110A110A7FCA000A000A000A000A0000
+D399:0000002800287FA8122812E812287FA80028000007F800080008000800080000
+D39A:0000002800287FA8122812E812287FA80028000000003EF80208020802080000
+D39B:0000002800287FA8122812E812287FA80028000000003E100210022802C40000
+D39C:0000002800287FA8122812E812287FA80028000008000800080008000FF80000
+D39D:0000002800287FA8122812E812287FA800280000000020F8201020303ECC0000
+D39E:0000002800287FA8122812E812287FA800280000202021FC207020883E700000
+D39F:0000002800287FA8122812E812287FA80028000003F802000200020003F80000
+D3A0:0000002800287FA8122812E812287FA80028000007F8000807F8040007F80000
+D3A1:0000002800287FA8122812E812287FA8002800003EF802083E0820083E080000
+D3A2:0000002800287FA8122812E812287FA8002800003EF802883E8820883EF80000
+D3A3:0000002800287FA8122812E812287FA8002800003E8802883EF820883EF80000
+D3A4:0000002800287FA8122812E812287FA8002800001F0801081F0810141F620000
+D3A5:0000002800287FA8122812E812287FA8002800003EF802803EF820803EF80000
+D3A6:0000002800287FA8122812E812287FA8002800003EFC02483E4820483EFC0000
+D3A7:0000002800287FA8122812E812287FA8002800003E1002FE3E3820443E380000
+D3A8:0000002800287FA8122812E812287FA80028000003F802080208020803F80000
+D3A9:0000002800287FA8122812E812287FA8002800000208020803F8020803F80000
+D3AA:0000002800287FA8122812E812287FA800280000110811081F0811141F620000
+D3AB:0000002800287FA8122812E812287FA800280000000800080008003400C20000
+D3AC:0000002800287FA8122812E812287FA8002800000048004800A8011406620000
+D3AD:0000002800287FA8122812E812287FA800280000000001F00208020801F00000
+D3AE:0000002800287FA8122812E812287FA80028000003F80020002000D003080000
+D3AF:0000002800287FA8122812E812287FA800280000004003F8004000A003180000
+D3B0:0000002800287FA8122812E812287FA80028000003F8000803F8000800080000
+D3B1:0000002800287FA8122812E812287FA80028000003F8020003F8020003F80000
+D3B2:0000002800287FA8122812E812287FA80028000000000FF8022002200FF80000
+D3B3:0000002800287FA8122812E812287FA80028000000800FF803E0041003E00000
+D3B4:00000000000200027FC21102111E11021102111E7FC200020002000200020000
+D3B5:0000000800087F881238120812387F8800080000000007F80008000800080000
+D3B6:0000000800087F881238120812387F880008000000003EF80208020802080000
+D3B7:0000000800087F881238120812387F880008000000001F080108011401620000
+D3B8:0000000800087F881238120812387F880008000800001000100010001FF80000
+D3B9:0000000800087F881238120812387F8800080000000020F8201020303ECC0000
+D3BA:0000000800087F881238120812387F8800080000202021FC207020883E700000
+D3BB:0000000800087F881238120812387F880008000003F802000200020003F80000
+D3BC:0000000800087F881238120812387F880008000007F8000807F8040007F80000
+D3BD:0000000800087F881238120812387F88000800003EF802083E0820083E080000
+D3BE:0000000800087F881238120812387F88000800003EF802883E8820883EF80000
+D3BF:0000000800087F881238120812387F88000800003E8802883EF820883EF80000
+D3C0:0000000800087F881238120812387F88000800000F8800880F8808140FA20000
+D3C1:0000000800087F881238120812387F88000800003EF802803EF820803EF80000
+D3C2:0000000800087F881238120812387F88000800003EFC02483E4820483EFC0000
+D3C3:0000000800087F881238120812387F88000800003E1002FE3E3820443E380000
+D3C4:0000000800087F881238120812387F880008000003F802080208020803F80000
+D3C5:0000000800087F881238120812387F88000800000208020803F8020803F80000
+D3C6:0000000800087F881238120812387F8800080000210821083F0821143F620000
+D3C7:0000000800087F881238120812387F8800080000001000100010006801840000
+D3C8:0000000800087F881238120812387F88000800000048004800A8011406620000
+D3C9:0000000800087F881238120812387F8800080000000003F00408040803F00000
+D3CA:0000000800087F881238120812387F880008000003F80020002000D003080000
+D3CB:0000000800087F881238120812387F8800080000004003F8004000A003180000
+D3CC:0000000800087F881238120812387F880008000003F8000803F8000800080000
+D3CD:0000000800087F881238120812387F880008000003F8020003F8020003F80000
+D3CE:0000000800087F881238120812387F880008000000000FF8022002200FF80000
+D3CF:0000000800087F881238120812387F880008000000800FF803E0041003E00000
+D3D0:00000000000A000A7FCA110A113A110A110A113A7FCA000A000A000A000A0000
+D3D1:0000002800287FA812E8122812E87FA80028000007F800080008000800080000
+D3D2:0000002800287FA812E8122812E87FA80028000000003EF80208020802080000
+D3D3:0000002800287FA812E8122812E87FA80028000000003E100210022802C40000
+D3D4:0000002800287FA812E8122812E87FA80028002808000800080008000FF80000
+D3D5:0000002800287FA812E8122812E87FA800280000000020F8201020303ECC0000
+D3D6:0000002800287FA812E8122812E87FA800280000202021FC207020883E700000
+D3D7:0000002800287FA812E8122812E87FA80028000003F802000200020003F80000
+D3D8:0000002800287FA812E8122812E87FA80028000007F8000807F8040007F80000
+D3D9:0000002800287FA812E8122812E87FA8002800003EF802083E0820083E080000
+D3DA:0000002800287FA812E8122812E87FA8002800003EF802883E8820883EF80000
+D3DB:0000002800287FA812E8122812E87FA8002800003E8802883EF820883EF80000
+D3DC:0000002800287FA812E8122812E87FA8002800001F0801081F0810141F620000
+D3DD:0000002800287FA812E8122812E87FA8002800003EF802803EF820803EF80000
+D3DE:0000002800287FA812E8122812E87FA8002800003EFC02483E4820483EFC0000
+D3DF:0000002800287FA812E8122812E87FA8002800003E1002FE3E3820443E380000
+D3E0:0000002800287FA812E8122812E87FA80028000003F802080208020803F80000
+D3E1:0000002800287FA812E8122812E87FA8002800000208020803F8020803F80000
+D3E2:0000002800287FA812E8122812E87FA800280000110811081F0811141F620000
+D3E3:0000002800287FA812E8122812E87FA800280000000800080008003400C20000
+D3E4:0000002800287FA812E8122812E87FA8002800000048004800A8011406620000
+D3E5:0000002800287FA812E8122812E87FA800280000000001F00208020801F00000
+D3E6:0000002800287FA812E8122812E87FA80028000003F80020002000D003080000
+D3E7:0000002800287FA812E8122812E87FA800280000004003F8004000A003180000
+D3E8:0000002800287FA812E8122812E87FA80028000003F8000803F8000800080000
+D3E9:0000002800287FA812E8122812E87FA80028000003F8020003F8020003F80000
+D3EA:0000002800287FA812E8122812E87FA80028000000000FF8022002200FF80000
+D3EB:0000002800287FA812E8122812E87FA80028000000800FF803E0041003E00000
+D3EC:000000003FF808200820082008203FF8000000000100010001007FFC00000000
+D3ED:00001FF00440044004401FF0010001007FFC00001FF000100010001000100000
+D3EE:00001FF00440044004401FF0010001007FFC000000003EF80208020802080000
+D3EF:00001FF00440044004401FF0010001007FFC000000001E100210022802C40000
+D3F0:00001FF00440044004401FF0010001007FFC000000001000100010001FF00000
+D3F1:00001FF00440044004401FF0010001007FFC0000000020F8201020303ECC0000
+D3F2:00001FF00440044004401FF0010001007FFC0000202021FC207020883E700000
+D3F3:00001FF00440044004401FF0010001007FFC00001FF01000100010001FF00000
+D3F4:00001FF00440044004401FF0010001007FFC00001FF000101FF010001FF00000
+D3F5:00001FF00440044004401FF0010001007FFC00003EF802083E0820083E080000
+D3F6:00001FF00440044004401FF0010001007FFC00003EF802883E8820883EF80000
+D3F7:00001FF00440044004401FF0010001007FFC00003E8802883EF820883EF80000
+D3F8:00001FF00440044004401FF0010001007FFC00003E1002103E1020283EC40000
+D3F9:00001FF00440044004401FF0010001007FFC00003EF802803EF820803EF80000
+D3FA:00001FF00440044004401FF0010001007FFC00003EFC02483E4820483EFC0000
+D3FB:00001FF00440044004401FF0010001007FFC00003E2003FC3E7020883E700000
+D3FC:00001FF00440044004401FF0010001007FFC00001FF01010101010101FF00000
+D3FD:00001FF00440044004401FF0010001007FFC0000101010101FF010101FF00000
+D3FE:00001FF00440044004401FF0010001007FFC0000222022203E2022503E880000
+D3FF:00001FF00440044004401FF0010001007FFC000000000100010002800C400000
+D400:00001FF00440044004401FF0010001007FFC00000000024002400DA033100000
+D401:00001FF00440044004401FF0010001007FFC0000000007C00820082007C00000
+D402:00001FF00440044004401FF0010001007FFC0000000007E00080014006200000
+D403:00001FF00440044004401FF0010001007FFC0000008007E00080014006200000
+D404:00001FF00440044004401FF0010001007FFC00001FF000101FF0001000100000
+D405:00001FF00440044004401FF0010001007FFC00001FF010001FF010001FF00000
+D406:00001FF00440044004401FF0010001007FFC000000001FF0044004401FF00000
+D407:00001FF00440044004401FF0010001007FFC000001001FF007C0082007C00000
+D408:00000010001000107FD011101110111E11107FD0041004107FD0001000100000
+D409:000000083F881108110E3F88040804087FE8000007F800080008000800080000
+D40A:000000083F881108110E3F88040804087FE8000000003EF80208020802080000
+D40B:000000083F881108110E3F88040804087FE8000000001F080108011401620000
+D40C:000000083F881108110E3F88040804087FE8000008000800080008000FF80000
+D40D:000000083F881108110E3F88040804087FE80000000010F8101010301ECC0000
+D40E:000000083F881108110E3F88040804087FE800000808087F081C08220F9C0000
+D40F:000000083F881108110E3F88040804087FE8000003F802000200020003F80000
+D410:000000083F881108110E3F88040804087FE8000007F8000807F8040007F80000
+D411:000000083F881108110E3F88040804087FE800003EF802083E0820083E080000
+D412:000000083F881108110E3F88040804087FE800003EF802883E8820883EF80000
+D413:000000083F881108110E3F88040804087FE800003E8802883EF820883EF80000
+D414:000000083F881108110E3F88040804087FE800001F0801081F0810141F620000
+D415:000000083F881108110E3F88040804087FE800003EF802803EF820803EF80000
+D416:000000083F881108110E3F88040804087FE800003EFC02483E4820483EFC0000
+D417:000000083F881108110E3F88040804087FE800001F08017F1F1C10221F1C0000
+D418:000000083F881108110E3F88040804087FE8000003F802080208020803F80000
+D419:000000083F881108110E3F88040804087FE800000208020803F8020803F80000
+D41A:000000083F881108110E3F88040804087FE80000110811081F0811141F620000
+D41B:000000083F881108110E3F88040804087FE80000001000100010006801840000
+D41C:000000083F881108110E3F88040804087FE800000048004800A8011406620000
+D41D:000000083F881108110E3F88040804087FE80000000003F00408040803F00000
+D41E:000000083F881108110E3F88040804087FE8000003F80020002000D003080000
+D41F:000000083F881108110E3F88040804087FE80000004003F8004000A003180000
+D420:000000083F881108110E3F88040804087FE8000003F8000803F8000800080000
+D421:000000083F881108110E3F88040804087FE8000003F8020003F8020003F80000
+D422:000000083F881108110E3F88040804087FE8000000000FF8022002200FF80000
+D423:000000083F881108110E3F88040804087FE8000000800FF803E0041003E00000
+D424:00000012001200127FD211121112111E11127FD2041204127FD2001200120000
+D425:000000283FA8112811383FA8042804287FA8000007F800080008000800080000
+D426:000000283FA8112811383FA8042804287FA8000000003EF80208020802080000
+D427:000000283FA8112811383FA8042804287FA8000000001F080108011401620000
+D428:000000283FA8112811383FA8042804287FA8000008000800080008000FF80000
+D429:000000283FA8112811383FA8042804287FA80000000010F8101010301ECC0000
+D42A:000000283FA8112811383FA8042804287FA800000808087F081C08220F9C0000
+D42B:000000283FA8112811383FA8042804287FA8000003F802000200020003F80000
+D42C:000000283FA8112811383FA8042804287FA8000007F8000807F8040007F80000
+D42D:000000283FA8112811383FA8042804287FA800003EF802083E0820083E080000
+D42E:000000283FA8112811383FA8042804287FA800003EF802883E8820883EF80000
+D42F:000000283FA8112811383FA8042804287FA800003E8802883EF820883EF80000
+D430:000000283FA8112811383FA8042804287FA800001F0801081F0810141F620000
+D431:000000283FA8112811383FA8042804287FA800003EF802803EF820803EF80000
+D432:000000283FA8112811383FA8042804287FA800003EFC02483E4820483EFC0000
+D433:000000283FA8112811383FA8042804287FA800001F08017F1F1C10221F1C0000
+D434:000000283FA8112811383FA8042804287FA8000003F802080208020803F80000
+D435:000000283FA8112811383FA8042804287FA800000208020803F8020803F80000
+D436:000000283FA8112811383FA8042804287FA80000110811081F0811141F620000
+D437:000000283FA8112811383FA8042804287FA80000001000100010006801840000
+D438:000000283FA8112811383FA8042804287FA800000048004800A8011406620000
+D439:000000283FA8112811383FA8042804287FA80000000003F00408040803F00000
+D43A:000000283FA8112811383FA8042804287FA8000003F80020002000D003080000
+D43B:000000283FA8112811383FA8042804287FA80000004003F8004000A003180000
+D43C:000000283FA8112811383FA8042804287FA8000003F8000803F8000800080000
+D43D:000000283FA8112811383FA8042804287FA8000003F8020003F8020003F80000
+D43E:000000283FA8112811383FA8042804287FA8000000000FF8022002200FF80000
+D43F:000000283FA8112811383FA8042804287FA8000000800FF803E0041003E00000
+D440:00000008000800087FC811081108110811087FC8040804087FE8000800080000
+D441:000000083F88110811083F88040804087FE8000007F800080008000800080000
+D442:000000083F88110811083F88040804087FE8000000003EF80208020802080000
+D443:000000083F88110811083F88040804087FE8000000001F080108011401620000
+D444:000000083F88110811083F88040804087FE8000008000800080008000FF80000
+D445:000000083F88110811083F88040804087FE80000000010F8101010301ECC0000
+D446:000000083F88110811083F88040804087FE800000808087F081C08220F9C0000
+D447:000000083F88110811083F88040804087FE8000003F802000200020003F80000
+D448:000000083F88110811083F88040804087FE8000007F8000807F8040007F80000
+D449:000000083F88110811083F88040804087FE800003EF802083E0820083E080000
+D44A:000000083F88110811083F88040804087FE800003EF802883E8820883EF80000
+D44B:000000083F88110811083F88040804087FE800003E8802883EF820883EF80000
+D44C:000000083F88110811083F88040804087FE800001F0801081F0810141F620000
+D44D:000000083F88110811083F88040804087FE800003EF802803EF820803EF80000
+D44E:000000083F88110811083F88040804087FE800003EFC02483E4820483EFC0000
+D44F:000000083F88110811083F88040804087FE800001F08017F1F1C10221F1C0000
+D450:000000083F88110811083F88040804087FE8000003F802080208020803F80000
+D451:000000083F88110811083F88040804087FE800000208020803F8020803F80000
+D452:000000083F88110811083F88040804087FE80000110811081F0811141F620000
+D453:000000083F88110811083F88040804087FE80000001000100010006801840000
+D454:000000083F88110811083F88040804087FE800000048004800A8011406620000
+D455:000000083F88110811083F88040804087FE80000000003F00408040803F00000
+D456:000000083F88110811083F88040804087FE8000003F80020002000D003080000
+D457:000000083F88110811083F88040804087FE80000004003F8004000A003180000
+D458:000000083F88110811083F88040804087FE8000003F8000803F8000800080000
+D459:000000083F88110811083F88040804087FE8000003F8020003F8020003F80000
+D45A:000000083F88110811083F88040804087FE8000000000FF8022002200FF80000
+D45B:000000083F88110811083F88040804087FE8000000800FF803E0041003E00000
+D45C:000000003FF808200820082008203FF8000004400440044004407FFC00000000
+D45D:00001FF00440044004401FF0044004407FFC00001FF000100010001000100000
+D45E:00001FF00440044004401FF0044004407FFC000000003EF80208020802080000
+D45F:00001FF00440044004401FF0044004407FFC000000001E100210022802C40000
+D460:00001FF00440044004401FF0044004407FFC000000001000100010001FF00000
+D461:00001FF00440044004401FF0044004407FFC0000000020F8201020303ECC0000
+D462:00001FF00440044004401FF0044004407FFC0000202021FC207020883E700000
+D463:00001FF00440044004401FF0044004407FFC00001FF01000100010001FF00000
+D464:00001FF00440044004401FF0044004407FFC00001FF000101FF010001FF00000
+D465:00001FF00440044004401FF0044004407FFC00003EF802083E0820083E080000
+D466:00001FF00440044004401FF0044004407FFC00003EF802883E8820883EF80000
+D467:00001FF00440044004401FF0044004407FFC00003E8802883EF820883EF80000
+D468:00001FF00440044004401FF0044004407FFC00003E1002103E1020283EC40000
+D469:00001FF00440044004401FF0044004407FFC00003EF802803EF820803EF80000
+D46A:00001FF00440044004401FF0044004407FFC00003EFC02483E4820483EFC0000
+D46B:00001FF00440044004401FF0044004407FFC00003E2003FC3E7020883E700000
+D46C:00001FF00440044004401FF0044004407FFC00001FF01010101010101FF00000
+D46D:00001FF00440044004401FF0044004407FFC0000101010101FF010101FF00000
+D46E:00001FF00440044004401FF0044004407FFC0000222022203E2022503E880000
+D46F:00001FF00440044004401FF0044004407FFC000000000100010002800C400000
+D470:00001FF00440044004401FF0044004407FFC00000000024002400DA033100000
+D471:00001FF00440044004401FF0044004407FFC0000000007C00820082007C00000
+D472:00001FF00440044004401FF0044004407FFC0000000007E00080014006200000
+D473:00001FF00440044004401FF0044004407FFC0000008007E00080014006200000
+D474:00001FF00440044004401FF0044004407FFC00001FF000101FF0001000100000
+D475:00001FF00440044004401FF0044004407FFC00001FF010001FF010001FF00000
+D476:00001FF00440044004401FF0044004407FFC000000001FF0044004401FF00000
+D477:00001FF00440044004401FF0044004407FFC000001001FF007C0082007C00000
+D478:000000003FF808200820082008203FF8000000003FF801000100010001000000
+D479:00001FF00440044004401FF000007FFC010001001FF000100010001000100000
+D47A:00001FF00440044004401FF000007FFC0100010000003EF80208020802080000
+D47B:00001FF00440044004401FF000007FFC0100010000001E100210022802C40000
+D47C:00001FF00440044004401FF0000000007FFC010001001100100010001FF00000
+D47D:00001FF00440044004401FF000007FFC01000100000020F8201020303ECC0000
+D47E:00001FF00440044004401FF000007FFC01000100202021FC207020883E700000
+D47F:00001FF00440044004401FF000007FFC010001001FF01000100010001FF00000
+D480:00001FF00440044004401FF000007FFC010001001FF000101FF010001FF00000
+D481:00001FF00440044004401FF000007FFC010001003EF802083E0820083E080000
+D482:00001FF00440044004401FF000007FFC010001003EF802883E8820883EF80000
+D483:00001FF00440044004401FF000007FFC010001003E8802883EF820883EF80000
+D484:00001FF00440044004401FF000007FFC010001003E1002103E1020283EC40000
+D485:00001FF00440044004401FF000007FFC010001003EF802803EF820803EF80000
+D486:00001FF00440044004401FF000007FFC010001003EFC02483E4820483EFC0000
+D487:00001FF00440044004401FF000007FFC010001003E2003FC3E7020883E700000
+D488:00001FF00440044004401FF000007FFC010001001FF01010101010101FF00000
+D489:00001FF00440044004401FF000007FFC01000100101010101FF010101FF00000
+D48A:00001FF00440044004401FF000007FFC01000100222022203E2022503E880000
+D48B:00001FF00440044004401FF000007FFC0100010000000100010002800C400000
+D48C:00001FF00440044004401FF000007FFC010001000000024002400DA033100000
+D48D:00001FF00440044004401FF000007FFC01000100000007C00820082007C00000
+D48E:00001FF00440044004401FF000007FFC01000100000007E00080014006200000
+D48F:00001FF00440044004401FF000007FFC01000100008007E00080014006200000
+D490:00001FF00440044004401FF000007FFC010001001FF000101FF0001000100000
+D491:00001FF00440044004401FF000007FFC010001001FF010001FF010001FF00000
+D492:00001FF00440044004401FF000007FFC0100010000001FF0044004401FF00000
+D493:00001FF00440044004401FF000007FFC0100010001001FF007C0082007C00000
+D494:0000000800087FC811081108110811087FC800087FE8040804F8040804080000
+D495:00083F88110811083F8800087FE8027802080000000007F80008000800080000
+D496:00083F88110811083F8800087FE802780208000000003EF80208020802080000
+D497:00083F88110811083F8800087FE802780208000000001F080108011401620000
+D498:00083F88110811083F88000800087FE80278020802081000100010001FF80000
+D499:00083F88110811083F8800087FE8027802080000000020F8201020303ECC0000
+D49A:00083F88110811083F8800087FE8027802080000202021FC207020883E700000
+D49B:00083F88110811083F8800087FE802780208000003F802000200020003F80000
+D49C:00083F88110811083F8800087FE802780208000007F8000807F8040007F80000
+D49D:00083F88110811083F8800087FE80278020800003EF802083E0820083E080000
+D49E:00083F88110811083F8800087FE80278020800003EF802883E8820883EF80000
+D49F:00083F88110811083F8800087FE80278020800003E8802883EF820883EF80000
+D4A0:00083F88110811083F8800087FE80278020800000F8800880F8808140FA20000
+D4A1:00083F88110811083F8800087FE80278020800003EF802803EF820803EF80000
+D4A2:00083F88110811083F8800087FE80278020800003EFC02483E4820483EFC0000
+D4A3:00083F88110811083F8800087FE80278020800003E1002FE3E3820443E380000
+D4A4:00083F88110811083F8800087FE802780208000003F802080208020803F80000
+D4A5:00083F88110811083F8800087FE80278020800000208020803F8020803F80000
+D4A6:00083F88110811083F8800087FE8027802080000210821083F0821143F620000
+D4A7:00083F88110811083F8800087FE8027802080000001000100010006801840000
+D4A8:00083F88110811083F8800087FE80278020800000048004800A8011406620000
+D4A9:00083F88110811083F8800087FE8027802080000000003F00408040803F00000
+D4AA:00083F88110811083F8800087FE802780208000003F80020002000D003080000
+D4AB:00083F88110811083F8800087FE8027802080000004003F8004000A003180000
+D4AC:00083F88110811083F8800087FE802780208000003F8000803F8000800080000
+D4AD:00083F88110811083F8800087FE802780208000003F8020003F8020003F80000
+D4AE:00083F88110811083F8800087FE802780208000000000FF8022002200FF80000
+D4AF:00083F88110811083F8800087FE802780208000000800FF803E0041003E00000
+D4B0:0000000A000A7FCA110A110A110A110A7FCA000A7FEA040A047A040A040A0000
+D4B1:00283FA8112811283FA800287FA805E804280000000007F80008000800080000
+D4B2:00283FA8112811283FA800287FA805E80428000000003EF80208020802080000
+D4B3:00283FA8112811283FA800287FA805E80428000000001F080108011401620000
+D4B4:00283FA8112811283FA8002800287FA8042805E804281428100010001FF80000
+D4B5:00283FA8112811283FA800287FA805E804280000000020F8201020303ECC0000
+D4B6:00283FA8112811283FA800287FA805E804280000202021FC207020883E700000
+D4B7:00283FA8112811283FA800287FA805E80428000003F802000200020003F80000
+D4B8:00283FA8112811283FA800287FA805E80428000007F8000807F8040007F80000
+D4B9:00283FA8112811283FA800287FA805E8042800003EF802083E0820083E080000
+D4BA:00283FA8112811283FA800287FA805E8042800003EF802883E8820883EF80000
+D4BB:00283FA8112811283FA800287FA805E8042800003E8802883EF820883EF80000
+D4BC:00283FA8112811283FA800287FA805E8042800000F8800880F8808140FA20000
+D4BD:00283FA8112811283FA800287FA805E8042800003EF802803EF820803EF80000
+D4BE:00283FA8112811283FA800287FA805E8042800003EFC02483E4820483EFC0000
+D4BF:00283FA8112811283FA800287FA805E8042800003E1002FE3E3820443E380000
+D4C0:00283FA8112811283FA800287FA805E80428000003F802080208020803F80000
+D4C1:00283FA8112811283FA800287FA805E8042800000208020803F8020803F80000
+D4C2:00283FA8112811283FA800287FA805E804280000210821083F0821143F620000
+D4C3:00283FA8112811283FA800287FA805E804280000001000100010006801840000
+D4C4:00283FA8112811283FA800287FA805E8042800000048004800A8011406620000
+D4C5:00283FA8112811283FA800287FA805E804280000000003F00408040803F00000
+D4C6:00283FA8112811283FA800287FA805E80428000003F80020002000D003080000
+D4C7:00283FA8112811283FA800287FA805E804280000004003F8004000A003180000
+D4C8:00283FA8112811283FA800287FA805E80428000003F8000803F8000800080000
+D4C9:00283FA8112811283FA800287FA805E80428000003F8020003F8020003F80000
+D4CA:00283FA8112811283FA800287FA805E80428000000000FF8022002200FF80000
+D4CB:00283FA8112811283FA800287FA805E80428000000800FF803E0041003E00000
+D4CC:0000000800087FC811081108110811087FC800087FE804080408040804080000
+D4CD:00083F88110811083F8800087FE8020802000000000007F80008000800080000
+D4CE:00083F88110811083F8800087FE802080200000000003EF80208020802080000
+D4CF:00083F88110811083F8800087FE802080200000000001F080108011401620000
+D4D0:00083F88110811083F88000800087FE80208020802081008100010001FF80000
+D4D1:00083F88110811083F8800087FE8020802000000000020F8201020303ECC0000
+D4D2:00083F88110811083F8800087FE8020802000000202021FC207020883E700000
+D4D3:00083F88110811083F8800087FE802080200000003F802000200020003F80000
+D4D4:00083F88110811083F8800087FE802080200000007F8000807F8040007F80000
+D4D5:00083F88110811083F8800087FE80208020000003EF802083E0820083E080000
+D4D6:00083F88110811083F8800087FE80208020000003EF802883E8820883EF80000
+D4D7:00083F88110811083F8800087FE80208020000003E8802883EF820883EF80000
+D4D8:00083F88110811083F8800087FE80208020000000F8800880F8808140FA20000
+D4D9:00083F88110811083F8800087FE80208020000003EF802803EF820803EF80000
+D4DA:00083F88110811083F8800087FE80208020000003EFC02483E4820483EFC0000
+D4DB:00083F88110811083F8800087FE80208020000003E1002FE3E3820443E380000
+D4DC:00083F88110811083F8800087FE802080200000003F802080208020803F80000
+D4DD:00083F88110811083F8800087FE80208020000000208020803F8020803F80000
+D4DE:00083F88110811083F8800087FE8020802000000210821083F0821143F620000
+D4DF:00083F88110811083F8800087FE8020802000000001000100010006801840000
+D4E0:00083F88110811083F8800087FE80208020000000048004800A8011406620000
+D4E1:00083F88110811083F8800087FE8020802000000000003F00408040803F00000
+D4E2:00083F88110811083F8800087FE802080200000003F80020002000D003080000
+D4E3:00083F88110811083F8800087FE8020802000000004003F8004000A003180000
+D4E4:00083F88110811083F8800087FE802080200000003F8000803F8000800080000
+D4E5:00083F88110811083F8800087FE802080200000003F8020003F8020003F80000
+D4E6:00083F88110811083F8800087FE802080200000000000FF8022002200FF80000
+D4E7:00083F88110811083F8800087FE802080200000000800FF803E0041003E00000
+D4E8:000000003FF808200820082008203FF8000000007FFC04400440044004400000
+D4E9:00001FF00440044004401FF000007FFC044004401FF000100010001000100000
+D4EA:00001FF00440044004401FF000007FFC0440044000003EF80208020802080000
+D4EB:00001FF00440044004401FF000007FFC0440044000001E100210022802C40000
+D4EC:00001FF00440044004401FF0000000007FFC044004401440100010001FF00000
+D4ED:00001FF00440044004401FF000007FFC04400440000020F8201020303ECC0000
+D4EE:00001FF00440044004401FF000007FFC04400440202021FC207020883E700000
+D4EF:00001FF00440044004401FF000007FFC044004401FF01000100010001FF00000
+D4F0:00001FF00440044004401FF000007FFC044004401FF000101FF010001FF00000
+D4F1:00001FF00440044004401FF000007FFC044004403EF802083E0820083E080000
+D4F2:00001FF00440044004401FF000007FFC044004403EF802883E8820883EF80000
+D4F3:00001FF00440044004401FF000007FFC044004403E8802883EF820883EF80000
+D4F4:00001FF00440044004401FF000007FFC044004403E1002103E1020283EC40000
+D4F5:00001FF00440044004401FF000007FFC044004403EF802803EF820803EF80000
+D4F6:00001FF00440044004401FF000007FFC044004403EFC02483E4820483EFC0000
+D4F7:00001FF00440044004401FF000007FFC044004403E2003FC3E7020883E700000
+D4F8:00001FF00440044004401FF000007FFC044004401FF01010101010101FF00000
+D4F9:00001FF00440044004401FF000007FFC04400440101010101FF010101FF00000
+D4FA:00001FF00440044004401FF000007FFC04400440222022203E2022503E880000
+D4FB:00001FF00440044004401FF000007FFC0440044000000100010002800C400000
+D4FC:00001FF00440044004401FF000007FFC044004400000024002400DA033100000
+D4FD:00001FF00440044004401FF000007FFC04400440000007C00820082007C00000
+D4FE:00001FF00440044004401FF000007FFC04400440000007E00080014006200000
+D4FF:00001FF00440044004401FF000007FFC04400440008007E00080014006200000
+D500:00001FF00440044004401FF000007FFC044004401FF000101FF0001000100000
+D501:00001FF00440044004401FF000007FFC044004401FF010001FF010001FF00000
+D502:00001FF00440044004401FF000007FFC0440044000001FF0044004401FF00000
+D503:00001FF00440044004401FF000007FFC0440044001001FF007C0082007C00000
+D504:000000003FF808200820082008203FF80000000000007FFC0000000000000000
+D505:00001FF00440044004401FF0000000007FFC00001FF000100010001000100000
+D506:00001FF00440044004401FF0000000007FFC000000003EF80208020802080000
+D507:00001FF00440044004401FF0000000007FFC000000001E100210022802C40000
+D508:00001FF00440044004401FF0000000007FFC000000001000100010001FF00000
+D509:00001FF00440044004401FF0000000007FFC0000000020F8201020303ECC0000
+D50A:00001FF00440044004401FF0000000007FFC0000202021FC207020883E700000
+D50B:00001FF00440044004401FF0000000007FFC00001FF01000100010001FF00000
+D50C:00001FF00440044004401FF0000000007FFC00001FF000101FF010001FF00000
+D50D:00001FF00440044004401FF0000000007FFC00003EF802083E0820083E080000
+D50E:00001FF00440044004401FF0000000007FFC00003EF802883E8820883EF80000
+D50F:00001FF00440044004401FF0000000007FFC00003E8802883EF820883EF80000
+D510:00001FF00440044004401FF0000000007FFC00003E1002103E1020283EC40000
+D511:00001FF00440044004401FF0000000007FFC00003EF802803EF820803EF80000
+D512:00001FF00440044004401FF0000000007FFC00003EFC02483E4820483EFC0000
+D513:00001FF00440044004401FF0000000007FFC00003E2003FC3E7020883E700000
+D514:00001FF00440044004401FF0000000007FFC00001FF01010101010101FF00000
+D515:00001FF00440044004401FF0000000007FFC0000101010101FF010101FF00000
+D516:00001FF00440044004401FF0000000007FFC0000222022203E2022503E880000
+D517:00001FF00440044004401FF0000000007FFC000000000100010002800C400000
+D518:00001FF00440044004401FF0000000007FFC00000000024002400DA033100000
+D519:00001FF00440044004401FF0000000007FFC0000000007C00820082007C00000
+D51A:00001FF00440044004401FF0000000007FFC0000000007E00080014006200000
+D51B:00001FF00440044004401FF0000000007FFC0000008007E00080014006200000
+D51C:00001FF00440044004401FF0000000007FFC00001FF000101FF0001000100000
+D51D:00001FF00440044004401FF0000000007FFC00001FF010001FF010001FF00000
+D51E:00001FF00440044004401FF0000000007FFC000000001FF0044004401FF00000
+D51F:00001FF00440044004401FF0000000007FFC000001001FF007C0082007C00000
+D520:00000008000800087FC811081108110811087FC800087FE80008000800080000
+D521:000000083F88110811083F88000800087FE8000007F800080008000800080000
+D522:000000083F88110811083F88000800087FE8000000003EF80208020802080000
+D523:000000083F88110811083F88000800087FE8000000001F080108011401620000
+D524:000000083F88110811083F88000800087FE8000008000800080008000FF80000
+D525:000000083F88110811083F88000800087FE80000000010F8101010301ECC0000
+D526:000000083F88110811083F88000800087FE800000808087F081C08220F9C0000
+D527:000000083F88110811083F88000800087FE8000003F802000200020003F80000
+D528:000000083F88110811083F88000800087FE8000007F8000807F8040007F80000
+D529:000000083F88110811083F88000800087FE800003EF802083E0820083E080000
+D52A:000000083F88110811083F88000800087FE800003EF802883E8820883EF80000
+D52B:000000083F88110811083F88000800087FE800003E8802883EF820883EF80000
+D52C:000000083F88110811083F88000800087FE800001F0801081F0810141F620000
+D52D:000000083F88110811083F88000800087FE800003EF802803EF820803EF80000
+D52E:000000083F88110811083F88000800087FE800003EFC02483E4820483EFC0000
+D52F:000000083F88110811083F88000800087FE800001F08017F1F1C10221F1C0000
+D530:000000083F88110811083F88000800087FE8000003F802080208020803F80000
+D531:000000083F88110811083F88000800087FE800000208020803F8020803F80000
+D532:000000083F88110811083F88000800087FE80000110811081F0811141F620000
+D533:000000083F88110811083F88000800087FE80000001000100010006801840000
+D534:000000083F88110811083F88000800087FE800000048004800A8011406620000
+D535:000000083F88110811083F88000800087FE80000000003F00408040803F00000
+D536:000000083F88110811083F88000800087FE8000003F80020002000D003080000
+D537:000000083F88110811083F88000800087FE80000004003F8004000A003180000
+D538:000000083F88110811083F88000800087FE8000003F8000803F8000800080000
+D539:000000083F88110811083F88000800087FE8000003F8020003F8020003F80000
+D53A:000000083F88110811083F88000800087FE8000000000FF8022002200FF80000
+D53B:000000083F88110811083F88000800087FE8000000800FF803E0041003E00000
+D53C:00000000000800087FC8110811081108110811087FC800080008000800080000
+D53D:0000000800087F881208120812087F8800080000000007F80008000800080000
+D53E:0000000800087F881208120812087F880008000000003EF80208020802080000
+D53F:0000000800087F881208120812087F880008000000001F080108011401620000
+D540:0000000800087F881208120812087F880008000800001000100010001FF80000
+D541:0000000800087F881208120812087F8800080000000020F8201020303ECC0000
+D542:0000000800087F881208120812087F8800080000202021FC207020883E700000
+D543:0000000800087F881208120812087F880008000003F802000200020003F80000
+D544:0000000800087F881208120812087F880008000007F8000807F8040007F80000
+D545:0000000800087F881208120812087F88000800003EF802083E0820083E080000
+D546:0000000800087F881208120812087F88000800003EF802883E8820883EF80000
+D547:0000000800087F881208120812087F88000800003E8802883EF820883EF80000
+D548:0000000800087F881208120812087F88000800000F8800880F8808140FA20000
+D549:0000000800087F881208120812087F88000800003EF802803EF820803EF80000
+D54A:0000000800087F881208120812087F88000800003EFC02483E4820483EFC0000
+D54B:0000000800087F881208120812087F88000800003E1002FE3E3820443E380000
+D54C:0000000800087F881208120812087F880008000003F802080208020803F80000
+D54D:0000000800087F881208120812087F88000800000208020803F8020803F80000
+D54E:0000000800087F881208120812087F8800080000210821083F0821143F620000
+D54F:0000000800087F881208120812087F8800080000001000100010006801840000
+D550:0000000800087F881208120812087F88000800000048004800A8011406620000
+D551:0000000800087F881208120812087F8800080000000003F00408040803F00000
+D552:0000000800087F881208120812087F880008000003F80020002000D003080000
+D553:0000000800087F881208120812087F8800080000004003F8004000A003180000
+D554:0000000800087F881208120812087F880008000003F8000803F8000800080000
+D555:0000000800087F881208120812087F880008000003F8020003F8020003F80000
+D556:0000000800087F881208120812087F880008000000000FF8022002200FF80000
+D557:0000000800087F881208120812087F880008000000800FF803E0041003E00000
+D558:00000000041004103F900E101110209E2090209011100E100010001000100000
+D559:000008087F081C082208220E22081C080008000007F800080008000800080000
+D55A:000008087F081C082208220E22081C080008000000003EF80208020802080000
+D55B:000008087F081C082208220E22081C080008000000001F080108011401620000
+D55C:000008087F081C082208220E22081C080008000808000800080008000FF80000
+D55D:000008087F081C082208220E22081C0800080000000010F8101010301ECC0000
+D55E:000008087F081C082208220E22081C08000800000808087F081C08220F9C0000
+D55F:000008087F081C082208220E22081C080008000003F802000200020003F80000
+D560:000008087F081C082208220E22081C080008000007F8000807F8040007F80000
+D561:000008087F081C082208220E22081C08000800003EF802083E0820083E080000
+D562:000008087F081C082208220E22081C08000800003EF802883E8820883EF80000
+D563:000008087F081C082208220E22081C08000800003E8802883EF820883EF80000
+D564:000008087F081C082208220E22081C08000800001F0801081F0810141F620000
+D565:000008087F081C082208220E22081C08000800003EF802803EF820803EF80000
+D566:000008087F081C082208220E22081C08000800003EFC02483E4820483EFC0000
+D567:000008087F081C082208220E22081C08000800001F08017F1F1C10221F1C0000
+D568:000008087F081C082208220E22081C080008000003F802080208020803F80000
+D569:000008087F081C082208220E22081C08000800000208020803F8020803F80000
+D56A:000008087F081C082208220E22081C0800080000110811081F0811141F620000
+D56B:000008087F081C082208220E22081C0800080000001000100010006801840000
+D56C:000008087F081C082208220E22081C08000800000048004800A8011406620000
+D56D:000008087F081C082208220E22081C0800080000000003F00408040803F00000
+D56E:000008087F081C082208220E22081C080008000003F80020002000D003080000
+D56F:000008087F081C082208220E22081C0800080000004003F8004000A003180000
+D570:000008087F081C082208220E22081C080008000003F8000803F8000800080000
+D571:000008087F081C082208220E22081C080008000003F8020003F8020003F80000
+D572:000008087F081C082208220E22081C080008000000000FF8022002200FF80000
+D573:000008087F081C082208220E22081C080008000000800FF803E0041003E00000
+D574:00000000041204123F920E121112209E2092209211120E120012001200120000
+D575:000008287F281C282228223822281C280028000007F800080008000800080000
+D576:000008287F281C282228223822281C280028000000003EF80208020802080000
+D577:000008287F281C282228223822281C280028000000003E100210022802C40000
+D578:000008287F281C282228223822281C280028002808000800080008000FF80000
+D579:000008287F281C282228223822281C2800280000000020F8201020303ECC0000
+D57A:000008287F281C282228223822281C2800280000202021FC207020883E700000
+D57B:000008287F281C282228223822281C280028000003F802000200020003F80000
+D57C:000008287F281C282228223822281C280028000007F8000807F8040007F80000
+D57D:000008287F281C282228223822281C28002800003EF802083E0820083E080000
+D57E:000008287F281C282228223822281C28002800003EF802883E8820883EF80000
+D57F:000008287F281C282228223822281C28002800003E8802883EF820883EF80000
+D580:000008287F281C282228223822281C28002800001F0801081F0810141F620000
+D581:000008287F281C282228223822281C28002800003EF802803EF820803EF80000
+D582:000008287F281C282228223822281C28002800003EFC02483E4820483EFC0000
+D583:000008287F281C282228223822281C28002800003E1002FE3E3820443E380000
+D584:000008287F281C282228223822281C280028000003F802080208020803F80000
+D585:000008287F281C282228223822281C28002800000208020803F8020803F80000
+D586:000008287F281C282228223822281C2800280000110811081F0811141F620000
+D587:000008287F281C282228223822281C2800280000000800080008003400C20000
+D588:000008287F281C282228223822281C28002800000048004800A8011406620000
+D589:000008287F281C282228223822281C2800280000000001F00208020801F00000
+D58A:000008287F281C282228223822281C280028000003F80020002000D003080000
+D58B:000008287F281C282228223822281C2800280000004003F8004000A003180000
+D58C:000008287F281C282228223822281C280028000003F8000803F8000800080000
+D58D:000008287F281C282228223822281C280028000003F8020003F8020003F80000
+D58E:000008287F281C282228223822281C280028000000000FF8022002200FF80000
+D58F:000008287F281C282228223822281C280028000000800FF803E0041003E00000
+D590:00000000041004103F900E10111E20902090209E11100E100010001000100000
+D591:000008087F081C08220E2208220E1C080008000007F800080008000800080000
+D592:000008087F081C08220E2208220E1C080008000000003EF80208020802080000
+D593:000008087F081C08220E2208220E1C080008000000001F080108011401620000
+D594:000008087F081C08220E2208220E1C080008000008000800080008000FF80000
+D595:000008087F081C08220E2208220E1C0800080000000010F8101010301ECC0000
+D596:000008087F081C08220E2208220E1C08000800000808087F081C08220F9C0000
+D597:000008087F081C08220E2208220E1C080008000003F802000200020003F80000
+D598:000008087F081C08220E2208220E1C080008000007F8000807F8040007F80000
+D599:000008087F081C08220E2208220E1C08000800003EF802083E0820083E080000
+D59A:000008087F081C08220E2208220E1C08000800003EF802883E8820883EF80000
+D59B:000008087F081C08220E2208220E1C08000800003E8802883EF820883EF80000
+D59C:000008087F081C08220E2208220E1C08000800001F0801081F0810141F620000
+D59D:000008087F081C08220E2208220E1C08000800003EF802803EF820803EF80000
+D59E:000008087F081C08220E2208220E1C08000800003EFC02483E4820483EFC0000
+D59F:000008087F081C08220E2208220E1C08000800001F08017F1F1C10221F1C0000
+D5A0:000008087F081C08220E2208220E1C080008000003F802080208020803F80000
+D5A1:000008087F081C08220E2208220E1C08000800000208020803F8020803F80000
+D5A2:000008087F081C08220E2208220E1C0800080000110811081F0811141F620000
+D5A3:000008087F081C08220E2208220E1C0800080000001000100010006801840000
+D5A4:000008087F081C08220E2208220E1C08000800000048004800A8011406620000
+D5A5:000008087F081C08220E2208220E1C0800080000000003F00408040803F00000
+D5A6:000008087F081C08220E2208220E1C080008000003F80020002000D003080000
+D5A7:000008087F081C08220E2208220E1C0800080000004003F8004000A003180000
+D5A8:000008087F081C08220E2208220E1C080008000003F8000803F8000800080000
+D5A9:000008087F081C08220E2208220E1C080008000003F8020003F8020003F80000
+D5AA:000008087F081C08220E2208220E1C080008000000000FF8022002200FF80000
+D5AB:000008087F081C08220E2208220E1C080008000000800FF803E0041003E00000
+D5AC:00000000041204123F920E12111E20922092209E11120E120012001200120000
+D5AD:000008287F281C282238222822381C280028000007F800080008000800080000
+D5AE:000008287F281C282238222822381C280028000000003EF80208020802080000
+D5AF:000008287F281C282238222822381C280028000000003E100210022802C40000
+D5B0:000008287F281C282238222822381C280028002808000800080008000FF80000
+D5B1:000008287F281C282238222822381C2800280000000020F8201020303ECC0000
+D5B2:000008287F281C282238222822381C2800280000202021FC207020883E700000
+D5B3:000008287F281C282238222822381C280028000003F802000200020003F80000
+D5B4:000008287F281C282238222822381C280028000007F8000807F8040007F80000
+D5B5:000008287F281C282238222822381C28002800003EF802083E0820083E080000
+D5B6:000008287F281C282238222822381C28002800003EF802883E8820883EF80000
+D5B7:000008287F281C282238222822381C28002800003E8802883EF820883EF80000
+D5B8:000008287F281C282238222822381C28002800001F0801081F0810141F620000
+D5B9:000008287F281C282238222822381C28002800003EF802803EF820803EF80000
+D5BA:000008287F281C282238222822381C28002800003EFC02483E4820483EFC0000
+D5BB:000008287F281C282238222822381C28002800003E1002FE3E3820443E380000
+D5BC:000008287F281C282238222822381C280028000003F802080208020803F80000
+D5BD:000008287F281C282238222822381C28002800000208020803F8020803F80000
+D5BE:000008287F281C282238222822381C2800280000110811081F0811141F620000
+D5BF:000008287F281C282238222822381C2800280000000800080008003400C20000
+D5C0:000008287F281C282238222822381C28002800000048004800A8011406620000
+D5C1:000008287F281C282238222822381C2800280000000001F00208020801F00000
+D5C2:000008287F281C282238222822381C280028000003F80020002000D003080000
+D5C3:000008287F281C282238222822381C2800280000004003F8004000A003180000
+D5C4:000008287F281C282238222822381C280028000003F8000803F8000800080000
+D5C5:000008287F281C282238222822381C280028000003F8020003F8020003F80000
+D5C6:000008287F281C282238222822381C280028000000000FF8022002200FF80000
+D5C7:000008287F281C282238222822381C280028000000800FF803E0041003E00000
+D5C8:00000000040204023F820E021102209E2082208211020E020002000200020000
+D5C9:000008087F081C082208223822081C0800080000000007F80008000800080000
+D5CA:000008087F081C082208223822081C080008000000003EF80208020802080000
+D5CB:000008087F081C082208223822081C080008000000001F080108011401620000
+D5CC:000008087F081C082208223822081C080008000000001000100010001FF80000
+D5CD:000008087F081C082208223822081C0800080000000020F8201020303ECC0000
+D5CE:000008087F081C082208223822081C0800080000202021FC207020883E700000
+D5CF:000008087F081C082208223822081C080008000003F802000200020003F80000
+D5D0:000008087F081C082208223822081C080008000007F8000807F8040007F80000
+D5D1:000008087F081C082208223822081C08000800003EF802083E0820083E080000
+D5D2:000008087F081C082208223822081C08000800003EF802883E8820883EF80000
+D5D3:000008087F081C082208223822081C08000800003E8802883EF820883EF80000
+D5D4:000008087F081C082208223822081C08000800000F8800880F8808140FA20000
+D5D5:000008087F081C082208223822081C08000800003EF802803EF820803EF80000
+D5D6:000008087F081C082208223822081C08000800003EFC02483E4820483EFC0000
+D5D7:000008087F081C082208223822081C08000800003E1002FE3E3820443E380000
+D5D8:000008087F081C082208223822081C080008000003F802080208020803F80000
+D5D9:000008087F081C082208223822081C08000800000208020803F8020803F80000
+D5DA:000008087F081C082208223822081C0800080000210821083F0821143F620000
+D5DB:000008087F081C082208223822081C0800080000001000100010006801840000
+D5DC:000008087F081C082208223822081C08000800000048004800A8011406620000
+D5DD:000008087F081C082208223822081C0800080000000003F00408040803F00000
+D5DE:000008087F081C082208223822081C080008000003F80020002000D003080000
+D5DF:000008087F081C082208223822081C0800080000004003F8004000A003180000
+D5E0:000008087F081C082208223822081C080008000003F8000803F8000800080000
+D5E1:000008087F081C082208223822081C080008000003F8020003F8020003F80000
+D5E2:000008087F081C082208223822081C080008000000000FF8022002200FF80000
+D5E3:000008087F081C082208223822081C080008000000800FF803E0041003E00000
+D5E4:00000000040A040A3F8A0E0A110A20BA208A208A110A0E0A000A000A000A0000
+D5E5:000008287F281C28222822E822281C280028000007F800080008000800080000
+D5E6:000008287F281C28222822E822281C280028000000003EF80208020802080000
+D5E7:000008287F281C28222822E822281C280028000000003E100210022802C40000
+D5E8:000008287F281C28222822E822281C280028000008000800080008000FF80000
+D5E9:000008287F281C28222822E822281C2800280000000020F8201020303ECC0000
+D5EA:000008287F281C28222822E822281C2800280000202021FC207020883E700000
+D5EB:000008287F281C28222822E822281C280028000003F802000200020003F80000
+D5EC:000008287F281C28222822E822281C280028000007F8000807F8040007F80000
+D5ED:000008287F281C28222822E822281C28002800003EF802083E0820083E080000
+D5EE:000008287F281C28222822E822281C28002800003EF802883E8820883EF80000
+D5EF:000008287F281C28222822E822281C28002800003E8802883EF820883EF80000
+D5F0:000008287F281C28222822E822281C28002800001F0801081F0810141F620000
+D5F1:000008287F281C28222822E822281C28002800003EF802803EF820803EF80000
+D5F2:000008287F281C28222822E822281C28002800003EFC02483E4820483EFC0000
+D5F3:000008287F281C28222822E822281C28002800003E1002FE3E3820443E380000
+D5F4:000008287F281C28222822E822281C280028000003F802080208020803F80000
+D5F5:000008287F281C28222822E822281C28002800000208020803F8020803F80000
+D5F6:000008287F281C28222822E822281C2800280000110811081F0811141F620000
+D5F7:000008287F281C28222822E822281C2800280000000800080008003400C20000
+D5F8:000008287F281C28222822E822281C28002800000048004800A8011406620000
+D5F9:000008287F281C28222822E822281C2800280000000001F00208020801F00000
+D5FA:000008287F281C28222822E822281C280028000003F80020002000D003080000
+D5FB:000008287F281C28222822E822281C2800280000004003F8004000A003180000
+D5FC:000008287F281C28222822E822281C280028000003F8000803F8000800080000
+D5FD:000008287F281C28222822E822281C280028000003F8020003F8020003F80000
+D5FE:000008287F281C28222822E822281C280028000000000FF8022002200FF80000
+D5FF:000008287F281C28222822E822281C280028000000800FF803E0041003E00000
+D600:00000000040204023F820E02111E20822082209E11020E020002000200020000
+D601:000008087F081C082238220822381C0800080000000007F80008000800080000
+D602:000008087F081C082238220822381C080008000000003EF80208020802080000
+D603:000008087F081C082238220822381C080008000000001F080108011401620000
+D604:000008087F081C082238220822381C080008000800001000100010001FF80000
+D605:000008087F081C082238220822381C0800080000000020F8201020303ECC0000
+D606:000008087F081C082238220822381C0800080000202021FC207020883E700000
+D607:000008087F081C082238220822381C080008000003F802000200020003F80000
+D608:000008087F081C082238220822381C080008000007F8000807F8040007F80000
+D609:000008087F081C082238220822381C08000800003EF802083E0820083E080000
+D60A:000008087F081C082238220822381C08000800003EF802883E8820883EF80000
+D60B:000008087F081C082238220822381C08000800003E8802883EF820883EF80000
+D60C:000008087F081C082238220822381C08000800000F8800880F8808140FA20000
+D60D:000008087F081C082238220822381C08000800003EF802803EF820803EF80000
+D60E:000008087F081C082238220822381C08000800003EFC02483E4820483EFC0000
+D60F:000008087F081C082238220822381C08000800003E1002FE3E3820443E380000
+D610:000008087F081C082238220822381C080008000003F802080208020803F80000
+D611:000008087F081C082238220822381C08000800000208020803F8020803F80000
+D612:000008087F081C082238220822381C0800080000210821083F0821143F620000
+D613:000008087F081C082238220822381C0800080000001000100010006801840000
+D614:000008087F081C082238220822381C08000800000048004800A8011406620000
+D615:000008087F081C082238220822381C0800080000000003F00408040803F00000
+D616:000008087F081C082238220822381C080008000003F80020002000D003080000
+D617:000008087F081C082238220822381C0800080000004003F8004000A003180000
+D618:000008087F081C082238220822381C080008000003F8000803F8000800080000
+D619:000008087F081C082238220822381C080008000003F8020003F8020003F80000
+D61A:000008087F081C082238220822381C080008000000000FF8022002200FF80000
+D61B:000008087F081C082238220822381C080008000000800FF803E0041003E00000
+D61C:00000000040A040A3F8A0E0A113A208A208A20BA110A0E0A000A000A000A0000
+D61D:000008287F281C2822E8222822E81C280028000007F800080008000800080000
+D61E:000008287F281C2822E8222822E81C280028000000003EF80208020802080000
+D61F:000008287F281C2822E8222822E81C280028000000003E100210022802C40000
+D620:000008287F281C2822E8222822E81C280028002808000800080008000FF80000
+D621:000008287F281C2822E8222822E81C2800280000000020F8201020303ECC0000
+D622:000008287F281C2822E8222822E81C2800280000202021FC207020883E700000
+D623:000008287F281C2822E8222822E81C280028000003F802000200020003F80000
+D624:000008287F281C2822E8222822E81C280028000007F8000807F8040007F80000
+D625:000008287F281C2822E8222822E81C28002800003EF802083E0820083E080000
+D626:000008287F281C2822E8222822E81C28002800003EF802883E8820883EF80000
+D627:000008287F281C2822E8222822E81C28002800003E8802883EF820883EF80000
+D628:000008287F281C2822E8222822E81C28002800001F0801081F0810141F620000
+D629:000008287F281C2822E8222822E81C28002800003EF802803EF820803EF80000
+D62A:000008287F281C2822E8222822E81C28002800003EFC02483E4820483EFC0000
+D62B:000008287F281C2822E8222822E81C28002800003E1002FE3E3820443E380000
+D62C:000008287F281C2822E8222822E81C280028000003F802080208020803F80000
+D62D:000008287F281C2822E8222822E81C28002800000208020803F8020803F80000
+D62E:000008287F281C2822E8222822E81C2800280000110811081F0811141F620000
+D62F:000008287F281C2822E8222822E81C2800280000000800080008003400C20000
+D630:000008287F281C2822E8222822E81C28002800000048004800A8011406620000
+D631:000008287F281C2822E8222822E81C2800280000000001F00208020801F00000
+D632:000008287F281C2822E8222822E81C280028000003F80020002000D003080000
+D633:000008287F281C2822E8222822E81C2800280000004003F8004000A003180000
+D634:000008287F281C2822E8222822E81C280028000003F8000803F8000800080000
+D635:000008287F281C2822E8222822E81C280028000003F8020003F8020003F80000
+D636:000008287F281C2822E8222822E81C280028000000000FF8022002200FF80000
+D637:000008287F281C2822E8222822E81C280028000000800FF803E0041003E00000
+D638:0000010001000FE0000007C00820082007C000000100010001007FFC00000000
+D639:01000FE007C00820082007C0010001007FFC00001FF000100010001000100000
+D63A:01000FE007C00820082007C0010001007FFC000000003EF80208020802080000
+D63B:01000FE007C00820082007C0010001007FFC000000001E100210022802C40000
+D63C:01000FE007C00820082007C0010001007FFC000000001000100010001FF00000
+D63D:01000FE007C00820082007C0010001007FFC0000000020F8201020303ECC0000
+D63E:01000FE007C00820082007C0010001007FFC0000202021FC207020883E700000
+D63F:01000FE007C00820082007C0010001007FFC00001FF01000100010001FF00000
+D640:01000FE007C00820082007C0010001007FFC00001FF000101FF010001FF00000
+D641:01000FE007C00820082007C0010001007FFC00003EF802083E0820083E080000
+D642:01000FE007C00820082007C0010001007FFC00003EF802883E8820883EF80000
+D643:01000FE007C00820082007C0010001007FFC00003E8802883EF820883EF80000
+D644:01000FE007C00820082007C0010001007FFC00003E1002103E1020283EC40000
+D645:01000FE007C00820082007C0010001007FFC00003EF802803EF820803EF80000
+D646:01000FE007C00820082007C0010001007FFC00003EFC02483E4820483EFC0000
+D647:01000FE007C00820082007C0010001007FFC00003E2003FC3E7020883E700000
+D648:01000FE007C00820082007C0010001007FFC00001FF01010101010101FF00000
+D649:01000FE007C00820082007C0010001007FFC0000101010101FF010101FF00000
+D64A:01000FE007C00820082007C0010001007FFC0000222022203E2022503E880000
+D64B:01000FE007C00820082007C0010001007FFC000000000100010002800C400000
+D64C:01000FE007C00820082007C0010001007FFC00000000024002400DA033100000
+D64D:01000FE007C00820082007C0010001007FFC0000000007C00820082007C00000
+D64E:01000FE007C00820082007C0010001007FFC0000000007E00080014006200000
+D64F:01000FE007C00820082007C0010001007FFC0000008007E00080014006200000
+D650:01000FE007C00820082007C0010001007FFC00001FF000101FF0001000100000
+D651:01000FE007C00820082007C0010001007FFC00001FF010001FF010001FF00000
+D652:01000FE007C00820082007C0010001007FFC000000001FF0044004401FF00000
+D653:01000FE007C00820082007C0010001007FFC000001001FF007C0082007C00000
+D654:00000010041004103F9000101F10209E20901F10041004107FD0001000100000
+D655:000004083F880E08110E11080E0804087FE8000007F800080008000800080000
+D656:000004083F880E08110E11080E0804087FE8000000003EF80208020802080000
+D657:000004083F880E08110E11080E0804087FE8000000001F080108011401620000
+D658:000004083F880E08110E11080E0804087FE8000008000800080008000FF80000
+D659:000004083F880E08110E11080E0804087FE80000000010F8101010301ECC0000
+D65A:000004083F880E08110E11080E0804087FE800000808087F081C08220F9C0000
+D65B:000004083F880E08110E11080E0804087FE8000003F802000200020003F80000
+D65C:000004083F880E08110E11080E0804087FE8000007F8000807F8040007F80000
+D65D:000004083F880E08110E11080E0804087FE800003EF802083E0820083E080000
+D65E:000004083F880E08110E11080E0804087FE800003EF802883E8820883EF80000
+D65F:000004083F880E08110E11080E0804087FE800003E8802883EF820883EF80000
+D660:000004083F880E08110E11080E0804087FE800001F0801081F0810141F620000
+D661:000004083F880E08110E11080E0804087FE800003EF802803EF820803EF80000
+D662:000004083F880E08110E11080E0804087FE800003EFC02483E4820483EFC0000
+D663:000004083F880E08110E11080E0804087FE800001F08017F1F1C10221F1C0000
+D664:000004083F880E08110E11080E0804087FE8000003F802080208020803F80000
+D665:000004083F880E08110E11080E0804087FE800000208020803F8020803F80000
+D666:000004083F880E08110E11080E0804087FE80000110811081F0811141F620000
+D667:000004083F880E08110E11080E0804087FE80000001000100010006801840000
+D668:000004083F880E08110E11080E0804087FE800000048004800A8011406620000
+D669:000004083F880E08110E11080E0804087FE80000000003F00408040803F00000
+D66A:000004083F880E08110E11080E0804087FE8000003F80020002000D003080000
+D66B:000004083F880E08110E11080E0804087FE80000004003F8004000A003180000
+D66C:000004083F880E08110E11080E0804087FE8000003F8000803F8000800080000
+D66D:000004083F880E08110E11080E0804087FE8000003F8020003F8020003F80000
+D66E:000004083F880E08110E11080E0804087FE8000000000FF8022002200FF80000
+D66F:000004083F880E08110E11080E0804087FE8000000800FF803E0041003E00000
+D670:00000012041204123F9200121F12209E20921F12041204127FD2001200120000
+D671:000004283FA80E28113811280E2804287FA8000007F800080008000800080000
+D672:000004283FA80E28113811280E2804287FA8000000003EF80208020802080000
+D673:000004283FA80E28113811280E2804287FA8000000001F080108011401620000
+D674:000004283FA80E28113811280E2804287FA8000008000800080008000FF80000
+D675:000004283FA80E28113811280E2804287FA80000000010F8101010301ECC0000
+D676:000004283FA80E28113811280E2804287FA800000808087F081C08220F9C0000
+D677:000004283FA80E28113811280E2804287FA8000003F802000200020003F80000
+D678:000004283FA80E28113811280E2804287FA8000007F8000807F8040007F80000
+D679:000004283FA80E28113811280E2804287FA800003EF802083E0820083E080000
+D67A:000004283FA80E28113811280E2804287FA800003EF802883E8820883EF80000
+D67B:000004283FA80E28113811280E2804287FA800003E8802883EF820883EF80000
+D67C:000004283FA80E28113811280E2804287FA800001F0801081F0810141F620000
+D67D:000004283FA80E28113811280E2804287FA800003EF802803EF820803EF80000
+D67E:000004283FA80E28113811280E2804287FA800003EFC02483E4820483EFC0000
+D67F:000004283FA80E28113811280E2804287FA800001F08017F1F1C10221F1C0000
+D680:000004283FA80E28113811280E2804287FA8000003F802080208020803F80000
+D681:000004283FA80E28113811280E2804287FA800000208020803F8020803F80000
+D682:000004283FA80E28113811280E2804287FA80000110811081F0811141F620000
+D683:000004283FA80E28113811280E2804287FA80000001000100010006801840000
+D684:000004283FA80E28113811280E2804287FA800000048004800A8011406620000
+D685:000004283FA80E28113811280E2804287FA80000000003F00408040803F00000
+D686:000004283FA80E28113811280E2804287FA8000003F80020002000D003080000
+D687:000004283FA80E28113811280E2804287FA80000004003F8004000A003180000
+D688:000004283FA80E28113811280E2804287FA8000003F8000803F8000800080000
+D689:000004283FA80E28113811280E2804287FA8000003F8020003F8020003F80000
+D68A:000004283FA80E28113811280E2804287FA8000000000FF8022002200FF80000
+D68B:000004283FA80E28113811280E2804287FA8000000800FF803E0041003E00000
+D68C:00000008040804083F8800081F08208820881F08040804087FE8000800080000
+D68D:000004083F880E08110811080E0804087FE8000007F800080008000800080000
+D68E:000004083F880E08110811080E0804087FE8000000003EF80208020802080000
+D68F:000004083F880E08110811080E0804087FE8000000001F080108011401620000
+D690:000004083F880E08110811080E0804087FE8000008000800080008000FF80000
+D691:000004083F880E08110811080E0804087FE80000000010F8101010301ECC0000
+D692:000004083F880E08110811080E0804087FE800000808087F081C08220F9C0000
+D693:000004083F880E08110811080E0804087FE8000003F802000200020003F80000
+D694:000004083F880E08110811080E0804087FE8000007F8000807F8040007F80000
+D695:000004083F880E08110811080E0804087FE800003EF802083E0820083E080000
+D696:000004083F880E08110811080E0804087FE800003EF802883E8820883EF80000
+D697:000004083F880E08110811080E0804087FE800003E8802883EF820883EF80000
+D698:000004083F880E08110811080E0804087FE800001F0801081F0810141F620000
+D699:000004083F880E08110811080E0804087FE800003EF802803EF820803EF80000
+D69A:000004083F880E08110811080E0804087FE800003EFC02483E4820483EFC0000
+D69B:000004083F880E08110811080E0804087FE800001F08017F1F1C10221F1C0000
+D69C:000004083F880E08110811080E0804087FE8000003F802080208020803F80000
+D69D:000004083F880E08110811080E0804087FE800000208020803F8020803F80000
+D69E:000004083F880E08110811080E0804087FE80000110811081F0811141F620000
+D69F:000004083F880E08110811080E0804087FE80000001000100010006801840000
+D6A0:000004083F880E08110811080E0804087FE800000048004800A8011406620000
+D6A1:000004083F880E08110811080E0804087FE80000000003F00408040803F00000
+D6A2:000004083F880E08110811080E0804087FE8000003F80020002000D003080000
+D6A3:000004083F880E08110811080E0804087FE80000004003F8004000A003180000
+D6A4:000004083F880E08110811080E0804087FE8000003F8000803F8000800080000
+D6A5:000004083F880E08110811080E0804087FE8000003F8020003F8020003F80000
+D6A6:000004083F880E08110811080E0804087FE8000000000FF8022002200FF80000
+D6A7:000004083F880E08110811080E0804087FE8000000800FF803E0041003E00000
+D6A8:0000010001000FE0000007C00820082007C004400440044004407FFC00000000
+D6A9:01000FE007C00820082007C0044004407FFC00001FF000100010001000100000
+D6AA:01000FE007C00820082007C0044004407FFC000000003EF80208020802080000
+D6AB:01000FE007C00820082007C0044004407FFC000000001E100210022802C40000
+D6AC:01000FE007C00820082007C0044004407FFC000000001000100010001FF00000
+D6AD:01000FE007C00820082007C0044004407FFC0000000020F8201020303ECC0000
+D6AE:01000FE007C00820082007C0044004407FFC0000202021FC207020883E700000
+D6AF:01000FE007C00820082007C0044004407FFC00001FF01000100010001FF00000
+D6B0:01000FE007C00820082007C0044004407FFC00001FF000101FF010001FF00000
+D6B1:01000FE007C00820082007C0044004407FFC00003EF802083E0820083E080000
+D6B2:01000FE007C00820082007C0044004407FFC00003EF802883E8820883EF80000
+D6B3:01000FE007C00820082007C0044004407FFC00003E8802883EF820883EF80000
+D6B4:01000FE007C00820082007C0044004407FFC00003E1002103E1020283EC40000
+D6B5:01000FE007C00820082007C0044004407FFC00003EF802803EF820803EF80000
+D6B6:01000FE007C00820082007C0044004407FFC00003EFC02483E4820483EFC0000
+D6B7:01000FE007C00820082007C0044004407FFC00003E2003FC3E7020883E700000
+D6B8:01000FE007C00820082007C0044004407FFC00001FF01010101010101FF00000
+D6B9:01000FE007C00820082007C0044004407FFC0000101010101FF010101FF00000
+D6BA:01000FE007C00820082007C0044004407FFC0000222022203E2022503E880000
+D6BB:01000FE007C00820082007C0044004407FFC000000000100010002800C400000
+D6BC:01000FE007C00820082007C0044004407FFC00000000024002400DA033100000
+D6BD:01000FE007C00820082007C0044004407FFC0000000007C00820082007C00000
+D6BE:01000FE007C00820082007C0044004407FFC0000000007E00080014006200000
+D6BF:01000FE007C00820082007C0044004407FFC0000008007E00080014006200000
+D6C0:01000FE007C00820082007C0044004407FFC00001FF000101FF0001000100000
+D6C1:01000FE007C00820082007C0044004407FFC00001FF010001FF010001FF00000
+D6C2:01000FE007C00820082007C0044004407FFC000000001FF0044004401FF00000
+D6C3:01000FE007C00820082007C0044004407FFC000001001FF007C0082007C00000
+D6C4:0000010001000FE0000007C00820082007C000003FF801000100010001000000
+D6C5:01000FE007C00820082007C000007FFC010001001FF000100010001000100000
+D6C6:01000FE007C00820082007C000007FFC0100010000003EF80208020802080000
+D6C7:01000FE007C00820082007C000007FFC0100010000001E100210022802C40000
+D6C8:01000FE007C00820082007C0000000007FFC010001001100100010001FF00000
+D6C9:01000FE007C00820082007C000007FFC01000100000020F8201020303ECC0000
+D6CA:01000FE007C00820082007C000007FFC01000100202021FC207020883E700000
+D6CB:01000FE007C00820082007C000007FFC010001001FF01000100010001FF00000
+D6CC:01000FE007C00820082007C000007FFC010001001FF000101FF010001FF00000
+D6CD:01000FE007C00820082007C000007FFC010001003EF802083E0820083E080000
+D6CE:01000FE007C00820082007C000007FFC010001003EF802883E8820883EF80000
+D6CF:01000FE007C00820082007C000007FFC010001003E8802883EF820883EF80000
+D6D0:01000FE007C00820082007C000007FFC010001003E1002103E1020283EC40000
+D6D1:01000FE007C00820082007C000007FFC010001003EF802803EF820803EF80000
+D6D2:01000FE007C00820082007C000007FFC010001003EFC02483E4820483EFC0000
+D6D3:01000FE007C00820082007C000007FFC010001003E2003FC3E7020883E700000
+D6D4:01000FE007C00820082007C000007FFC010001001FF01010101010101FF00000
+D6D5:01000FE007C00820082007C000007FFC01000100101010101FF010101FF00000
+D6D6:01000FE007C00820082007C000007FFC01000100222022203E2022503E880000
+D6D7:01000FE007C00820082007C000007FFC0100010000000100010002800C400000
+D6D8:01000FE007C00820082007C000007FFC010001000000024002400DA033100000
+D6D9:01000FE007C00820082007C000007FFC01000100000007C00820082007C00000
+D6DA:01000FE007C00820082007C000007FFC01000100000007E00080014006200000
+D6DB:01000FE007C00820082007C000007FFC01000100008007E00080014006200000
+D6DC:01000FE007C00820082007C000007FFC010001001FF000101FF0001000100000
+D6DD:01000FE007C00820082007C000007FFC010001001FF010001FF010001FF00000
+D6DE:01000FE007C00820082007C000007FFC0100010000001FF0044004401FF00000
+D6DF:01000FE007C00820082007C000007FFC0100010001001FF007C0082007C00000
+D6E0:0000040804083F8800081F08208820881F0800087FE8040804F8040804080000
+D6E1:04083F880E0811080E0800087FE8027802080000000007F80008000800080000
+D6E2:04083F880E0811080E0800087FE802780208000000003EF80208020802080000
+D6E3:04083F880E0811080E0800087FE802780208000000001F080108011401620000
+D6E4:04083F880E0811080E08000800087FE80278020802081000100010001FF80000
+D6E5:04083F880E0811080E0800087FE8027802080000000020F8201020303ECC0000
+D6E6:04083F880E0811080E0800087FE8027802080000202021FC207020883E700000
+D6E7:04083F880E0811080E0800087FE802780208000003F802000200020003F80000
+D6E8:04083F880E0811080E0800087FE802780208000007F8000807F8040007F80000
+D6E9:04083F880E0811080E0800087FE80278020800003EF802083E0820083E080000
+D6EA:04083F880E0811080E0800087FE80278020800003EF802883E8820883EF80000
+D6EB:04083F880E0811080E0800087FE80278020800003E8802883EF820883EF80000
+D6EC:04083F880E0811080E0800087FE80278020800000F8800880F8808140FA20000
+D6ED:04083F880E0811080E0800087FE80278020800003EF802803EF820803EF80000
+D6EE:04083F880E0811080E0800087FE80278020800003EFC02483E4820483EFC0000
+D6EF:04083F880E0811080E0800087FE80278020800003E1002FE3E3820443E380000
+D6F0:04083F880E0811080E0800087FE802780208000003F802080208020803F80000
+D6F1:04083F880E0811080E0800087FE80278020800000208020803F8020803F80000
+D6F2:04083F880E0811080E0800087FE8027802080000210821083F0821143F620000
+D6F3:04083F880E0811080E0800087FE8027802080000001000100010006801840000
+D6F4:04083F880E0811080E0800087FE80278020800000048004800A8011406620000
+D6F5:04083F880E0811080E0800087FE8027802080000000003F00408040803F00000
+D6F6:04083F880E0811080E0800087FE802780208000003F80020002000D003080000
+D6F7:04083F880E0811080E0800087FE8027802080000004003F8004000A003180000
+D6F8:04083F880E0811080E0800087FE802780208000003F8000803F8000800080000
+D6F9:04083F880E0811080E0800087FE802780208000003F8020003F8020003F80000
+D6FA:04083F880E0811080E0800087FE802780208000000000FF8022002200FF80000
+D6FB:04083F880E0811080E0800087FE802780208000000800FF803E0041003E00000
+D6FC:0000040A040A3F8A000A1F0A208A208A1F0A000A7FEA040A047A040A040A0000
+D6FD:04283FA80E2811280E2800287FA805E804280000000007F80008000800080000
+D6FE:04283FA80E2811280E2800287FA805E80428000000003EF80208020802080000
+D6FF:04283FA80E2811280E2800287FA805E80428000000001F080108011401620000
+D700:04283FA80E2811280E28002800287FA8042805E804281428100010001FF80000
+D701:04283FA80E2811280E2800287FA805E804280000000020F8201020303ECC0000
+D702:04283FA80E2811280E2800287FA805E804280000202021FC207020883E700000
+D703:04283FA80E2811280E2800287FA805E80428000003F802000200020003F80000
+D704:04283FA80E2811280E2800287FA805E80428000007F8000807F8040007F80000
+D705:04283FA80E2811280E2800287FA805E8042800003EF802083E0820083E080000
+D706:04283FA80E2811280E2800287FA805E8042800003EF802883E8820883EF80000
+D707:04283FA80E2811280E2800287FA805E8042800003E8802883EF820883EF80000
+D708:04283FA80E2811280E2800287FA805E8042800000F8800880F8808140FA20000
+D709:04283FA80E2811280E2800287FA805E8042800003EF802803EF820803EF80000
+D70A:04283FA80E2811280E2800287FA805E8042800003EFC02483E4820483EFC0000
+D70B:04283FA80E2811280E2800287FA805E8042800003E1002FE3E3820443E380000
+D70C:04283FA80E2811280E2800287FA805E80428000003F802080208020803F80000
+D70D:04283FA80E2811280E2800287FA805E8042800000208020803F8020803F80000
+D70E:04283FA80E2811280E2800287FA805E804280000210821083F0821143F620000
+D70F:04283FA80E2811280E2800287FA805E804280000001000100010006801840000
+D710:04283FA80E2811280E2800287FA805E8042800000048004800A8011406620000
+D711:04283FA80E2811280E2800287FA805E804280000000003F00408040803F00000
+D712:04283FA80E2811280E2800287FA805E80428000003F80020002000D003080000
+D713:04283FA80E2811280E2800287FA805E804280000004003F8004000A003180000
+D714:04283FA80E2811280E2800287FA805E80428000003F8000803F8000800080000
+D715:04283FA80E2811280E2800287FA805E80428000003F8020003F8020003F80000
+D716:04283FA80E2811280E2800287FA805E80428000000000FF8022002200FF80000
+D717:04283FA80E2811280E2800287FA805E80428000000800FF803E0041003E00000
+D718:0000040804083F8800081F08208820881F0800087FE804080408040804080000
+D719:04083F880E0811080E0800087FE8020802000000000007F80008000800080000
+D71A:04083F880E0811080E0800087FE802080200000000003EF80208020802080000
+D71B:04083F880E0811080E0800087FE802080200000000001F080108011401620000
+D71C:04083F880E0811080E08000800087FE80208020802081008100010001FF80000
+D71D:04083F880E0811080E0800087FE8020802000000000020F8201020303ECC0000
+D71E:04083F880E0811080E0800087FE8020802000000202021FC207020883E700000
+D71F:04083F880E0811080E0800087FE802080200000003F802000200020003F80000
+D720:04083F880E0811080E0800087FE802080200000007F8000807F8040007F80000
+D721:04083F880E0811080E0800087FE80208020000003EF802083E0820083E080000
+D722:04083F880E0811080E0800087FE80208020000003EF802883E8820883EF80000
+D723:04083F880E0811080E0800087FE80208020000003E8802883EF820883EF80000
+D724:04083F880E0811080E0800087FE80208020000000F8800880F8808140FA20000
+D725:04083F880E0811080E0800087FE80208020000003EF802803EF820803EF80000
+D726:04083F880E0811080E0800087FE80208020000003EFC02483E4820483EFC0000
+D727:04083F880E0811080E0800087FE80208020000003E1002FE3E3820443E380000
+D728:04083F880E0811080E0800087FE802080200000003F802080208020803F80000
+D729:04083F880E0811080E0800087FE80208020000000208020803F8020803F80000
+D72A:04083F880E0811080E0800087FE8020802000000210821083F0821143F620000
+D72B:04083F880E0811080E0800087FE8020802000000001000100010006801840000
+D72C:04083F880E0811080E0800087FE80208020000000048004800A8011406620000
+D72D:04083F880E0811080E0800087FE8020802000000000003F00408040803F00000
+D72E:04083F880E0811080E0800087FE802080200000003F80020002000D003080000
+D72F:04083F880E0811080E0800087FE8020802000000004003F8004000A003180000
+D730:04083F880E0811080E0800087FE802080200000003F8000803F8000800080000
+D731:04083F880E0811080E0800087FE802080200000003F8020003F8020003F80000
+D732:04083F880E0811080E0800087FE802080200000000000FF8022002200FF80000
+D733:04083F880E0811080E0800087FE802080200000000800FF803E0041003E00000
+D734:0000010001000FE0000007C00820082007C000007FFC04400440044004400000
+D735:01000FE007C00820082007C000007FFC044004401FF000100010001000100000
+D736:01000FE007C00820082007C000007FFC0440044000003EF80208020802080000
+D737:01000FE007C00820082007C000007FFC0440044000001E100210022802C40000
+D738:01000FE007C00820082007C0000000007FFC044004401440100010001FF00000
+D739:01000FE007C00820082007C000007FFC04400440000020F8201020303ECC0000
+D73A:01000FE007C00820082007C000007FFC04400440202021FC207020883E700000
+D73B:01000FE007C00820082007C000007FFC044004401FF01000100010001FF00000
+D73C:01000FE007C00820082007C000007FFC044004401FF000101FF010001FF00000
+D73D:01000FE007C00820082007C000007FFC044004403EF802083E0820083E080000
+D73E:01000FE007C00820082007C000007FFC044004403EF802883E8820883EF80000
+D73F:01000FE007C00820082007C000007FFC044004403E8802883EF820883EF80000
+D740:01000FE007C00820082007C000007FFC044004403E1002103E1020283EC40000
+D741:01000FE007C00820082007C000007FFC044004403EF802803EF820803EF80000
+D742:01000FE007C00820082007C000007FFC044004403EFC02483E4820483EFC0000
+D743:01000FE007C00820082007C000007FFC044004403E2003FC3E7020883E700000
+D744:01000FE007C00820082007C000007FFC044004401FF01010101010101FF00000
+D745:01000FE007C00820082007C000007FFC04400440101010101FF010101FF00000
+D746:01000FE007C00820082007C000007FFC04400440222022203E2022503E880000
+D747:01000FE007C00820082007C000007FFC0440044000000100010002800C400000
+D748:01000FE007C00820082007C000007FFC044004400000024002400DA033100000
+D749:01000FE007C00820082007C000007FFC04400440000007C00820082007C00000
+D74A:01000FE007C00820082007C000007FFC04400440000007E00080014006200000
+D74B:01000FE007C00820082007C000007FFC04400440008007E00080014006200000
+D74C:01000FE007C00820082007C000007FFC044004401FF000101FF0001000100000
+D74D:01000FE007C00820082007C000007FFC044004401FF010001FF010001FF00000
+D74E:01000FE007C00820082007C000007FFC0440044000001FF0044004401FF00000
+D74F:01000FE007C00820082007C000007FFC0440044001001FF007C0082007C00000
+D750:0000010001000FE0000007C00820082007C0000000007FFC0000000000000000
+D751:01000FE007C00820082007C0000000007FFC00001FF000100010001000100000
+D752:01000FE007C00820082007C0000000007FFC000000003EF80208020802080000
+D753:01000FE007C00820082007C0000000007FFC000000001E100210022802C40000
+D754:01000FE007C00820082007C0000000007FFC000000001000100010001FF00000
+D755:01000FE007C00820082007C0000000007FFC0000000020F8201020303ECC0000
+D756:01000FE007C00820082007C0000000007FFC0000202021FC207020883E700000
+D757:01000FE007C00820082007C0000000007FFC00001FF01000100010001FF00000
+D758:01000FE007C00820082007C0000000007FFC00001FF000101FF010001FF00000
+D759:01000FE007C00820082007C0000000007FFC00003EF802083E0820083E080000
+D75A:01000FE007C00820082007C0000000007FFC00003EF802883E8820883EF80000
+D75B:01000FE007C00820082007C0000000007FFC00003E8802883EF820883EF80000
+D75C:01000FE007C00820082007C0000000007FFC00003E1002103E1020283EC40000
+D75D:01000FE007C00820082007C0000000007FFC00003EF802803EF820803EF80000
+D75E:01000FE007C00820082007C0000000007FFC00003EFC02483E4820483EFC0000
+D75F:01000FE007C00820082007C0000000007FFC00003E2003FC3E7020883E700000
+D760:01000FE007C00820082007C0000000007FFC00001FF01010101010101FF00000
+D761:01000FE007C00820082007C0000000007FFC0000101010101FF010101FF00000
+D762:01000FE007C00820082007C0000000007FFC0000222022203E2022503E880000
+D763:01000FE007C00820082007C0000000007FFC000000000100010002800C400000
+D764:01000FE007C00820082007C0000000007FFC00000000024002400DA033100000
+D765:01000FE007C00820082007C0000000007FFC0000000007C00820082007C00000
+D766:01000FE007C00820082007C0000000007FFC0000000007E00080014006200000
+D767:01000FE007C00820082007C0000000007FFC0000008007E00080014006200000
+D768:01000FE007C00820082007C0000000007FFC00001FF000101FF0001000100000
+D769:01000FE007C00820082007C0000000007FFC00001FF010001FF010001FF00000
+D76A:01000FE007C00820082007C0000000007FFC000000001FF0044004401FF00000
+D76B:01000FE007C00820082007C0000000007FFC000001001FF007C0082007C00000
+D76C:00000008040804083F8800081F08208820881F0800087FE80008000800080000
+D76D:000004083F880E08110811080E0800087FE8000007F800080008000800080000
+D76E:000004083F880E08110811080E0800087FE8000000003EF80208020802080000
+D76F:000004083F880E08110811080E0800087FE8000000001F080108011401620000
+D770:000004083F880E08110811080E0800087FE8000008000800080008000FF80000
+D771:000004083F880E08110811080E0800087FE80000000010F8101010301ECC0000
+D772:000004083F880E08110811080E0800087FE800000808087F081C08220F9C0000
+D773:000004083F880E08110811080E0800087FE8000003F802000200020003F80000
+D774:000004083F880E08110811080E0800087FE8000007F8000807F8040007F80000
+D775:000004083F880E08110811080E0800087FE800003EF802083E0820083E080000
+D776:000004083F880E08110811080E0800087FE800003EF802883E8820883EF80000
+D777:000004083F880E08110811080E0800087FE800003E8802883EF820883EF80000
+D778:000004083F880E08110811080E0800087FE800001F0801081F0810141F620000
+D779:000004083F880E08110811080E0800087FE800003EF802803EF820803EF80000
+D77A:000004083F880E08110811080E0800087FE800003EFC02483E4820483EFC0000
+D77B:000004083F880E08110811080E0800087FE800001F08017F1F1C10221F1C0000
+D77C:000004083F880E08110811080E0800087FE8000003F802080208020803F80000
+D77D:000004083F880E08110811080E0800087FE800000208020803F8020803F80000
+D77E:000004083F880E08110811080E0800087FE80000110811081F0811141F620000
+D77F:000004083F880E08110811080E0800087FE80000001000100010006801840000
+D780:000004083F880E08110811080E0800087FE800000048004800A8011406620000
+D781:000004083F880E08110811080E0800087FE80000000003F00408040803F00000
+D782:000004083F880E08110811080E0800087FE8000003F80020002000D003080000
+D783:000004083F880E08110811080E0800087FE80000004003F8004000A003180000
+D784:000004083F880E08110811080E0800087FE8000003F8000803F8000800080000
+D785:000004083F880E08110811080E0800087FE8000003F8020003F8020003F80000
+D786:000004083F880E08110811080E0800087FE8000000000FF8022002200FF80000
+D787:000004083F880E08110811080E0800087FE8000000800FF803E0041003E00000
+D788:00000000040804083F880E08110820882088208811080E080008000800080000
+D789:000008087F081C082208220822081C0800080000000007F80008000800080000
+D78A:000008087F081C082208220822081C080008000000003EF80208020802080000
+D78B:000008087F081C082208220822081C080008000000001F080108011401620000
+D78C:000008087F081C082208220822081C080008000800001000100010001FF80000
+D78D:000008087F081C082208220822081C0800080000000020F8201020303ECC0000
+D78E:000008087F081C082208220822081C0800080000202021FC207020883E700000
+D78F:000008087F081C082208220822081C080008000003F802000200020003F80000
+D790:000008087F081C082208220822081C080008000007F8000807F8040007F80000
+D791:000008087F081C082208220822081C08000800003EF802083E0820083E080000
+D792:000008087F081C082208220822081C08000800003EF802883E8820883EF80000
+D793:000008087F081C082208220822081C08000800003E8802883EF820883EF80000
+D794:000008087F081C082208220822081C08000800000F8800880F8808140FA20000
+D795:000008087F081C082208220822081C08000800003EF802803EF820803EF80000
+D796:000008087F081C082208220822081C08000800003EFC02483E4820483EFC0000
+D797:000008087F081C082208220822081C08000800003E1002FE3E3820443E380000
+D798:000008087F081C082208220822081C080008000003F802080208020803F80000
+D799:000008087F081C082208220822081C08000800000208020803F8020803F80000
+D79A:000008087F081C082208220822081C0800080000210821083F0821143F620000
+D79B:000008087F081C082208220822081C0800080000001000100010006801840000
+D79C:000008087F081C082208220822081C08000800000048004800A8011406620000
+D79D:000008087F081C082208220822081C0800080000000003F00408040803F00000
+D79E:000008087F081C082208220822081C080008000003F80020002000D003080000
+D79F:000008087F081C082208220822081C0800080000004003F8004000A003180000
+D7A0:000008087F081C082208220822081C080008000003F8000803F8000800080000
+D7A1:000008087F081C082208220822081C080008000003F8020003F8020003F80000
+D7A2:000008087F081C082208220822081C080008000000000FF8022002200FF80000
+D7A3:000008087F081C082208220822081C080008000000800FF803E0041003E00000
+D7A4:00007FFE63866DF66DEE6DDE63DE7FFE7FFE61B66DB661866DF66DF67FFE0000
+D7A5:00007FFE63866DF66DEE6DDE63DE7FFE7FFE61866DBE61866DF66D867FFE0000
+D7A6:00007FFE63866DF66DEE6DDE63DE7FFE7FFE61CE6DBE618E6DB66DCE7FFE0000
+D7A7:00007FFE63866DF66DEE6DDE63DE7FFE7FFE61866DF661EE6DDE6DDE7FFE0000
+D7A8:00007FFE63866DF66DEE6DDE63DE7FFE7FFE61CE6DB661CE6DB66DCE7FFE0000
+D7A9:00007FFE63866DF66DEE6DDE63DE7FFE7FFE61CE6DB661C66DF66DCE7FFE0000
+D7AA:00007FFE63866DF66DEE6DDE63DE7FFE7FFE61866DB661866DB66DB67FFE0000
+D7AB:00007FFE63866DF66DEE6DDE63DE7FFE7FFE618E6DB6618E6DB66D8E7FFE0000
+D7AC:00007FFE63866DF66DEE6DDE63DE7FFE7FFE61C66DBE61BE6DBE6DC67FFE0000
+D7AD:00007FFE63866DF66DEE6DDE63DE7FFE7FFE618E6DB661B66DB66D8E7FFE0000
+D7AE:00007FFE63866DF66DEE6DDE63DE7FFE7FFE61866DBE618E6DBE6D867FFE0000
+D7AF:00007FFE63866DF66DEE6DDE63DE7FFE7FFE61866DBE618E6DBE6DBE7FFE0000
+D7B0:0040003000100010001003F00110001003F0011000100C1004D0071078100000
+D7B1:00000000000000000000000000000000030001001FF001003FF8000003000100
+D7B2:004000300010001000100010001000100010001001900C9C04F0071078100000
+D7B3:0048003600120012001200120012001200120012031E191209F20F1278020000
+D7B4:00080006000200020002000200020002001E00020302193209C20F0278020000
+D7B5:0008000600020002000200020002000200023FF20202021E0202021E00020000
+D7B6:0010008C006400240024002400240024002400247FE404240424042400040000
+D7B7:00480036001200120012001200120012001E00127FF211121112111200020000
+D7B8:00000000000000000000000000000000000000003FF808200BA000803FFC0000
+D7B9:00800060002000200020002000200020003C00200020002000E0072078200000
+D7BA:00080006000200020002000200020002001E00020002000200E2070278020000
+D7BB:00480036001200120012001200120012007200120012001200D2071278020000
+D7BC:00000000000000000000000000000000000000003FF80000038000803FFC0000
+D7BD:00000040013000D000500050005C00500050005C005000500E1002003FFC0000
+D7BE:0090046C03240124013C01240124013C01240124012401240024000400000000
+D7BF:011000CC00440044005C00440044005C00440044004400440044000400000000
+D7C0:0410034C01340114011401740114011401740114011401140114001400040000
+D7C1:000000200018000800080008000800080008070801003FF80000070001000100
+D7C2:00000020001800080008000800080008000839C808403FF80000000000000000
+D7C3:000000200018000800080008000800080008000800003FF80840084000000000
+D7C4:0048003600120012001200120012001200120012001200120012001200020000
+D7C5:00800060002000200020002000200020003C0020302038200820002000200000
+D7C6:0010008C00640024002400240024002401E40024302438240824002400040000
+D7C7:00007FFE63866DF66DEE6DDE63DE7FFE7FFE71866FF66FEE6FDE71DE7FFE0000
+D7C8:00007FFE63866DF66DEE6DDE63DE7FFE7FFE71CE6FB66FCE6FB671CE7FFE0000
+D7C9:00007FFE63866DF66DEE6DDE63DE7FFE7FFE71CE6FB66FC66FF671CE7FFE0000
+D7CA:00007FFE63866DF66DEE6DDE63DE7FFE7FFE71866FB66F866FB671B67FFE0000
+D7CB:0000000000000000000000000000000060FE2002200220FE2080268038FE0000
+D7CC:000000000000000000000078C00043FE402040304C4871840000000000000000
+D7CD:000000000000000000000000000000000000FDF8208020802080268018780000
+D7CE:00000000000000000000000000000000FFB62212221E22122212265E19920000
+D7CF:00000000000000000000000000000000FD98208820F82088208826F818880000
+D7D0:0000000000000000000000000000000000007C38200820082018262438C20000
+D7D1:00000000000000000000000000000000000078EE2022202220622492390A0000
+D7D2:0000000000000000000000000000000000007C7E200820082018262438C20000
+D7D3:00000000000000000000000000000000003C7C00207E20082018262438C20000
+D7D4:00000000000000000000000000000000000000007EFC1040107C13400C3C0000
+D7D5:00000000000000000000000000000000000000003DDC04443C4420443C440000
+D7D6:0000000000000000000000000000001C3DC0047E04483C5C206220623C5C0000
+D7D7:00000000000000000000000000000000000000007BDC08447BDC42047BC40000
+D7D8:0000000000000000000000000000001C7BC00A7E0A487A5C426243E27A1C0000
+D7D9:000000000000000000000000000004807A5E0A480BC87A48424843C87A4E0000
+D7DA:0000000000000000000000000000049E7A440A420BD27A4A424243C47A5E0000
+D7DB:000000000000000000000000000000083C08041C04223C22202220223C1C0000
+D7DC:0000000000000000000000000000000EF780101F1304F48E84918491F30E0000
+D7DD:000000000000000000001FF800081FF810001FF8000003E00410041003E00000
+D7DE:0000000000000000000000000000000000007DC044404440444044407C3E4000
+D7DF:0000000000000000000000000000000000007B30491049104910491078CC4000
+D7E0:00000000000000000000000000000000000000003E7C2244224422443E7C2040
+D7E1:0000000000000000000000000000000000000480F4889784948C9492F7A18000
+D7E2:00000000000000000000000000000000000000003EFC2220223022483E842000
+D7E3:000000000000000000000000000000004400227C22203E20222022203E3C0000
+D7E4:0000000000000000000000000000000049DE244424523DCA250225043DDE0000
+D7E5:000000000000000000000000000000004400227C22443E44224422443E7C0040
+D7E6:000000000000000000000000000000004488224422443E7C224422443E7C0000
+D7E7:000000000000000000000000000000009000485E4848788849484A287A2E0000
+D7E8:000000000000000000000000000000004400220022FC3E20223022483E840000
+D7E9:000000000000000000000000000000004478220022FC3E20223022483E840000
+D7EA:0000000000000000000000000000000000000800047C04440C441244617C0040
+D7EB:00000000000000000000000000000044007C0844047C04000C38124461380000
+D7EC:000000000000000000000000000000000000123C0904090419042684CC440000
+D7ED:000000000000000000000000000000000000123E0910091019102690CC5E0000
+D7EE:00000000000000000000000000000000000010200810082818442482C2FE0000
+D7EF:000000000000000000000000000000000000000010FC082018302448C2840000
+D7F0:000000000000000000000000000000000078100008FC082018302448C2840000
+D7F1:000000000000000000000000000000000000100008FC0840187C2440C23C0000
+D7F2:000000000000000000000000000000380000107C0810083818442444C2380000
+D7F3:0000000000000000000000000000000001102088108828F844888288FEF80000
+D7F4:0000000000000000000000000210010801F8210811F8287044888270FE000000
+D7F5:000000000000000000000000000000000800087C1C442244224422441C7C0040
+D7F6:000000000000000000000000000000380800087C1C102238224422441C380000
+D7F7:00000000000000000000000000000000000000003F4404440C7C1244217C0040
+D7F8:000000000000000000000000000000000000000001297D2911EF292945EF0108
+D7F9:00000000000000000000000000000000000000007EFC08201830244842840000
+D7FA:000000000000000000000000000000007800104048202820086010907B080000
+D7FB:0000000000000000000000000000000078FC10404840287C08401040783C0000
+D7FC:00007FFE63866DF66DEE6DDE63DE7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+D7FD:00007FFE63866DF66DEE6DDE63DE7FFE7FFE618E6FB663B66FB66F8E7FFE0000
+D7FE:00007FFE63866DF66DEE6DDE63DE7FFE7FFE61866FBE638E6FBE6F867FFE0000
+D7FF:00007FFE63866DF66DEE6DDE63DE7FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+E000:00007FFE61CE6FB663B66FB661CE7FFE7FFE73CE6DB66DB66DB673CE7FFE0000
+E001:00007FFE61CE6FB663B66FB661CE7FFE7FFE73EE6DCE6DEE6DEE73C67FFE0000
+E002:00007FFE61CE6FB663B66FB661CE7FFE7FFE73866DF66D866DBE73867FFE0000
+E003:00007FFE61CE6FB663B66FB661CE7FFE7FFE738E6DF66DC66DF6738E7FFE0000
+E004:00007FFE61CE6FB663B66FB661CE7FFE7FFE73B66DB66D866DF673F67FFE0000
+E005:00007FFE61CE6FB663B66FB661CE7FFE7FFE73866DBE6D866DF673867FFE0000
+E006:00007FFE61CE6FB663B66FB661CE7FFE7FFE73CE6DBE6D8E6DB673CE7FFE0000
+E007:00007FFE61CE6FB663B66FB661CE7FFE7FFE73866DF66DEE6DDE73DE7FFE0000
+E008:00007FFE61CE6FB663B66FB661CE7FFE7FFE73CE6DB66DCE6DB673CE7FFE0000
+E009:00007FFE61CE6FB663B66FB661CE7FFE7FFE73CE6DB66DC66DF673CE7FFE0000
+E00A:00007FFE61CE6FB663B66FB661CE7FFE7FFE73866DB66D866DB673B67FFE0000
+E00B:00007FFE61CE6FB663B66FB661CE7FFE7FFE738E6DB66D8E6DB6738E7FFE0000
+E00C:00007FFE61CE6FB663B66FB661CE7FFE7FFE73C66DBE6DBE6DBE73C67FFE0000
+E00D:00007FFE61CE6FB663B66FB661CE7FFE7FFE738E6DB66DB66DB6738E7FFE0000
+E00E:00007FFE61CE6FB663B66FB661CE7FFE7FFE73866DBE6D8E6DBE73867FFE0000
+E00F:00007FFE61CE6FB663B66FB661CE7FFE7FFE73866DBE6D8E6DBE73BE7FFE0000
+E010:00007FFE61CE6FB663B66FB661CE7FFE7FFE7BCE73B67BB67BB671CE7FFE0000
+E011:00007FFE61CE6FB663B66FB661CE7FFE7FFE7BEE73CE7BEE7BEE71C67FFE0000
+E012:00007FFE61CE6FB663B66FB661CE7FFE7FFE7B8673F67B867BBE71867FFE0000
+E013:00007FFE61CE6FB663B66FB661CE7FFE7FFE7B8E73F67BC67BF6718E7FFE0000
+E014:00007FFE61CE6FB663B66FB661CE7FFE7FFE7BB673B67B867BF671F67FFE0000
+E015:00007FFE61CE6FB663B66FB661CE7FFE7FFE7B8673BE7B867BF671867FFE0000
+E016:00007FFE61CE6FB663B66FB661CE7FFE7FFE7BCE73BE7B8E7BB671CE7FFE0000
+E017:00007FFE61CE6FB663B66FB661CE7FFE7FFE7B8673F67BEE7BDE71DE7FFE0000
+E018:00007FFE61CE6FB663B66FB661CE7FFE7FFE7BCE73B67BCE7BB671CE7FFE0000
+E019:00007FFE61CE6FB663B66FB661CE7FFE7FFE7BCE73B67BC67BF671CE7FFE0000
+E01A:00007FFE61CE6FB663B66FB661CE7FFE7FFE7B8673B67B867BB671B67FFE0000
+E01B:00007FFE61CE6FB663B66FB661CE7FFE7FFE7B8E73B67B8E7BB6718E7FFE0000
+E01C:00007FFE61CE6FB663B66FB661CE7FFE7FFE7BC673BE7BBE7BBE71C67FFE0000
+E01D:00007FFE61CE6FB663B66FB661CE7FFE7FFE7B8E73B67BB67BB6718E7FFE0000
+E01E:00007FFE61CE6FB663B66FB661CE7FFE7FFE7B8673BE7B8E7BBE71867FFE0000
+E01F:00007FFE61CE6FB663B66FB661CE7FFE7FFE7B8673BE7B8E7BBE71BE7FFE0000
+E020:00007FFE61CE6FB663B66FB661CE7FFE7FFE61CE7DB661B66FB661CE7FFE0000
+E021:00007FFE61CE6FB663B66FB661CE7FFE7FFE61EE7DCE61EE6FEE61C67FFE0000
+E022:00007FFE61CE6FB663B66FB661CE7FFE7FFE61867DF661866FBE61867FFE0000
+E023:00007FFE61CE6FB663B66FB661CE7FFE7FFE618E7DF661C66FF6618E7FFE0000
+E024:00007FFE61CE6FB663B66FB661CE7FFE7FFE61B67DB661866FF661F67FFE0000
+E025:00007FFE61CE6FB663B66FB661CE7FFE7FFE61867DBE61866FF661867FFE0000
+E026:00007FFE61CE6FB663B66FB661CE7FFE7FFE61CE7DBE618E6FB661CE7FFE0000
+E027:00007FFE61CE6FB663B66FB661CE7FFE7FFE61867DF661EE6FDE61DE7FFE0000
+E028:00007FFE61CE6FB663B66FB661CE7FFE7FFE61CE7DB661CE6FB661CE7FFE0000
+E029:00007FFE61CE6FB663B66FB661CE7FFE7FFE61CE7DB661C66FF661CE7FFE0000
+E02A:00007FFE61CE6FB663B66FB661CE7FFE7FFE61867DB661866FB661B67FFE0000
+E02B:00007FFE61CE6FB663B66FB661CE7FFE7FFE618E7DB6618E6FB6618E7FFE0000
+E02C:00007FFE61CE6FB663B66FB661CE7FFE7FFE61C67DBE61BE6FBE61C67FFE0000
+E02D:00007FFE61CE6FB663B66FB661CE7FFE7FFE618E7DB661B66FB6618E7FFE0000
+E02E:00007FFE61CE6FB663B66FB661CE7FFE7FFE61867DBE618E6FBE61867FFE0000
+E02F:00007FFE61CE6FB663B66FB661CE7FFE7FFE61867DBE618E6FBE61BE7FFE0000
+E030:00007FFE61CE6FB663B66FB661CE7FFE7FFE63CE7DB671B67DB663CE7FFE0000
+E031:00007FFE61CE6FB663B66FB661CE7FFE7FFE63EE7DCE71EE7DEE63C67FFE0000
+E032:00007FFE61CE6FB663B66FB661CE7FFE7FFE63867DF671867DBE63867FFE0000
+E033:00007FFE61CE6FB663B66FB661CE7FFE7FFE638E7DF671C67DF6638E7FFE0000
+E034:00007FFE61CE6FB663B66FB661CE7FFE7FFE63B67DB671867DF663F67FFE0000
+E035:00007FFE61CE6FB663B66FB661CE7FFE7FFE63867DBE71867DF663867FFE0000
+E036:00007FFE61CE6FB663B66FB661CE7FFE7FFE63CE7DBE718E7DB663CE7FFE0000
+E037:00007FFE61CE6FB663B66FB661CE7FFE7FFE63867DF671EE7DDE63DE7FFE0000
+E038:00007FFE61CE6FB663B66FB661CE7FFE7FFE63CE7DB671CE7DB663CE7FFE0000
+E039:00007FFE61CE6FB663B66FB661CE7FFE7FFE63CE7DB671C67DF663CE7FFE0000
+E03A:00007FFE61CE6FB663B66FB661CE7FFE7FFE63867DB671867DB663B67FFE0000
+E03B:00007FFE61CE6FB663B66FB661CE7FFE7FFE638E7DB6718E7DB6638E7FFE0000
+E03C:00007FFE61CE6FB663B66FB661CE7FFE7FFE63C67DBE71BE7DBE63C67FFE0000
+E03D:00007FFE61CE6FB663B66FB661CE7FFE7FFE638E7DB671B67DB6638E7FFE0000
+E03E:00007FFE61CE6FB663B66FB661CE7FFE7FFE63867DBE718E7DBE63867FFE0000
+E03F:00007FFE61CE6FB663B66FB661CE7FFE7FFE63867DBE718E7DBE63BE7FFE0000
+E040:00007FFE61CE6FB663B66FB661CE7FFE7FFE6DCE6DB661B67DB67DCE7FFE0000
+E041:00007FFE61CE6FB663B66FB661CE7FFE7FFE6DEE6DCE61EE7DEE7DC67FFE0000
+E042:00007FFE61CE6FB663B66FB661CE7FFE7FFE6D866DF661867DBE7D867FFE0000
+E043:00007FFE61CE6FB663B66FB661CE7FFE7FFE6D8E6DF661C67DF67D8E7FFE0000
+E044:00007FFE61CE6FB663B66FB661CE7FFE7FFE6DB66DB661867DF67DF67FFE0000
+E045:00007FFE61CE6FB663B66FB661CE7FFE7FFE6D866DBE61867DF67D867FFE0000
+E046:00007FFE61CE6FB663B66FB661CE7FFE7FFE6DCE6DBE618E7DB67DCE7FFE0000
+E047:00007FFE61CE6FB663B66FB661CE7FFE7FFE6D866DF661EE7DDE7DDE7FFE0000
+E048:00007FFE61CE6FB663B66FB661CE7FFE7FFE6DCE6DB661CE7DB67DCE7FFE0000
+E049:00007FFE61CE6FB663B66FB661CE7FFE7FFE6DCE6DB661C67DF67DCE7FFE0000
+E04A:00007FFE61CE6FB663B66FB661CE7FFE7FFE6D866DB661867DB67DB67FFE0000
+E04B:00007FFE61CE6FB663B66FB661CE7FFE7FFE6D8E6DB6618E7DB67D8E7FFE0000
+E04C:00007FFE61CE6FB663B66FB661CE7FFE7FFE6DC66DBE61BE7DBE7DC67FFE0000
+E04D:00007FFE61CE6FB663B66FB661CE7FFE7FFE6D8E6DB661B67DB67D8E7FFE0000
+E04E:00007FFE61CE6FB663B66FB661CE7FFE7FFE6D866DBE618E7DBE7D867FFE0000
+E04F:00007FFE61CE6FB663B66FB661CE7FFE7FFE6D866DBE618E7DBE7DBE7FFE0000
+E050:00007FFE61CE6FB663B66FB661CE7FFE7FFE61CE6FB661B67DB661CE7FFE0000
+E051:00007FFE61CE6FB663B66FB661CE7FFE7FFE61EE6FCE61EE7DEE61C67FFE0000
+E052:00007FFE61CE6FB663B66FB661CE7FFE7FFE61866FF661867DBE61867FFE0000
+E053:00007FFE61CE6FB663B66FB661CE7FFE7FFE618E6FF661C67DF6618E7FFE0000
+E054:00007FFE61CE6FB663B66FB661CE7FFE7FFE61B66FB661867DF661F67FFE0000
+E055:00007FFE61CE6FB663B66FB661CE7FFE7FFE61866FBE61867DF661867FFE0000
+E056:00007FFE61CE6FB663B66FB661CE7FFE7FFE61CE6FBE618E7DB661CE7FFE0000
+E057:00007FFE61CE6FB663B66FB661CE7FFE7FFE61866FF661EE7DDE61DE7FFE0000
+E058:00007FFE61CE6FB663B66FB661CE7FFE7FFE61CE6FB661CE7DB661CE7FFE0000
+E059:00007FFE61CE6FB663B66FB661CE7FFE7FFE61CE6FB661C67DF661CE7FFE0000
+E05A:00007FFE61CE6FB663B66FB661CE7FFE7FFE61866FB661867DB661B67FFE0000
+E05B:00007FFE61CE6FB663B66FB661CE7FFE7FFE618E6FB6618E7DB6618E7FFE0000
+E05C:00007FFE61CE6FB663B66FB661CE7FFE7FFE61C66FBE61BE7DBE61C67FFE0000
+E05D:00007FFE61CE6FB663B66FB661CE7FFE7FFE618E6FB661B67DB6618E7FFE0000
+E05E:00007FFE61CE6FB663B66FB661CE7FFE7FFE61866FBE618E7DBE61867FFE0000
+E05F:00007FFE61CE6FB663B66FB661CE7FFE7FFE61866FBE618E7DBE61BE7FFE0000
+E060:00007FFE61CE6FB663B66FB661CE7FFE7FFE73CE6FB663B66DB673CE7FFE0000
+E061:00007FFE61CE6FB663B66FB661CE7FFE7FFE73EE6FCE63EE6DEE73C67FFE0000
+E062:00007FFE61CE6FB663B66FB661CE7FFE7FFE73866FF663866DBE73867FFE0000
+E063:00007FFE61CE6FB663B66FB661CE7FFE7FFE738E6FF663C66DF6738E7FFE0000
+E064:00007FFE61CE6FB663B66FB661CE7FFE7FFE73B66FB663866DF673F67FFE0000
+E065:00007FFE61CE6FB663B66FB661CE7FFE7FFE73866FBE63866DF673867FFE0000
+E066:00007FFE61CE6FB663B66FB661CE7FFE7FFE73CE6FBE638E6DB673CE7FFE0000
+E067:00007FFE61CE6FB663B66FB661CE7FFE7FFE73866FF663EE6DDE73DE7FFE0000
+E068:00007FFE61CE6FB663B66FB661CE7FFE7FFE73CE6FB663CE6DB673CE7FFE0000
+E069:00007FFE61CE6FB663B66FB661CE7FFE7FFE73CE6FB663C66DF673CE7FFE0000
+E06A:00007FFE61CE6FB663B66FB661CE7FFE7FFE73866FB663866DB673B67FFE0000
+E06B:00007FFE61CE6FB663B66FB661CE7FFE7FFE738E6FB6638E6DB6738E7FFE0000
+E06C:00007FFE61CE6FB663B66FB661CE7FFE7FFE73C66FBE63BE6DBE73C67FFE0000
+E06D:00007FFE61CE6FB663B66FB661CE7FFE7FFE738E6FB663B66DB6738E7FFE0000
+E06E:00007FFE61CE6FB663B66FB661CE7FFE7FFE73866FBE638E6DBE73867FFE0000
+E06F:00007FFE61CE6FB663B66FB661CE7FFE7FFE73866FBE638E6DBE73BE7FFE0000
+E070:00007FFE61CE6FB663B66FB661CE7FFE7FFE61CE7DB67BB677B677CE7FFE0000
+E071:00007FFE61CE6FB663B66FB661CE7FFE7FFE61EE7DCE7BEE77EE77C67FFE0000
+E072:00007FFE61CE6FB663B66FB661CE7FFE7FFE61867DF67B8677BE77867FFE0000
+E073:00007FFE61CE6FB663B66FB661CE7FFE7FFE618E7DF67BC677F6778E7FFE0000
+E074:00007FFE61CE6FB663B66FB661CE7FFE7FFE61B67DB67B8677F677F67FFE0000
+E075:00007FFE61CE6FB663B66FB661CE7FFE7FFE61867DBE7B8677F677867FFE0000
+E076:00007FFE61CE6FB663B66FB661CE7FFE7FFE61CE7DBE7B8E77B677CE7FFE0000
+E077:00007FFE61CE6FB663B66FB661CE7FFE7FFE61867DF67BEE77DE77DE7FFE0000
+E078:00007FFE61CE6FB663B66FB661CE7FFE7FFE61CE7DB67BCE77B677CE7FFE0000
+E079:00007FFE61CE6FB663B66FB661CE7FFE7FFE61CE7DB67BC677F677CE7FFE0000
+E07A:00007FFE61CE6FB663B66FB661CE7FFE7FFE61867DB67B8677B677B67FFE0000
+E07B:00007FFE61CE6FB663B66FB661CE7FFE7FFE618E7DB67B8E77B6778E7FFE0000
+E07C:00007FFE61CE6FB663B66FB661CE7FFE7FFE61C67DBE7BBE77BE77C67FFE0000
+E07D:00007FFE61CE6FB663B66FB661CE7FFE7FFE618E7DB67BB677B6778E7FFE0000
+E07E:00007FFE61CE6FB663B66FB661CE7FFE7FFE61867DBE7B8E77BE77867FFE0000
+E07F:00007FFE61CE6FB663B66FB661CE7FFE7FFE61867DBE7B8E77BE77BE7FFE0000
+E080:00007FFE61CE6FB663B66FB661CE7FFE7FFE73CE6DB673B66DB673CE7FFE0000
+E081:00007FFE61CE6FB663B66FB661CE7FFE7FFE73EE6DCE73EE6DEE73C67FFE0000
+E082:00007FFE61CE6FB663B66FB661CE7FFE7FFE73866DF673866DBE73867FFE0000
+E083:00007FFE61CE6FB663B66FB661CE7FFE7FFE738E6DF673C66DF6738E7FFE0000
+E084:00007FFE61CE6FB663B66FB661CE7FFE7FFE73B66DB673866DF673F67FFE0000
+E085:00007FFE61CE6FB663B66FB661CE7FFE7FFE73866DBE73866DF673867FFE0000
+E086:00007FFE61CE6FB663B66FB661CE7FFE7FFE73CE6DBE738E6DB673CE7FFE0000
+E087:00007FFE61CE6FB663B66FB661CE7FFE7FFE73866DF673EE6DDE73DE7FFE0000
+E088:00007FFE61CE6FB663B66FB661CE7FFE7FFE73CE6DB673CE6DB673CE7FFE0000
+E089:00007FFE61CE6FB663B66FB661CE7FFE7FFE73CE6DB673C66DF673CE7FFE0000
+E08A:00007FFE61CE6FB663B66FB661CE7FFE7FFE73866DB673866DB673B67FFE0000
+E08B:00007FFE61CE6FB663B66FB661CE7FFE7FFE738E6DB6738E6DB6738E7FFE0000
+E08C:00007FFE61CE6FB663B66FB661CE7FFE7FFE73C66DBE73BE6DBE73C67FFE0000
+E08D:00007FFE61CE6FB663B66FB661CE7FFE7FFE738E6DB673B66DB6738E7FFE0000
+E08E:00007FFE61CE6FB663B66FB661CE7FFE7FFE73866DBE738E6DBE73867FFE0000
+E08F:00007FFE61CE6FB663B66FB661CE7FFE7FFE73866DBE738E6DBE73BE7FFE0000
+E090:00007FFE61CE6FB663B66FB661CE7FFE7FFE73CE6DB671B67DB673CE7FFE0000
+E091:00007FFE61CE6FB663B66FB661CE7FFE7FFE73EE6DCE71EE7DEE73C67FFE0000
+E092:00007FFE61CE6FB663B66FB661CE7FFE7FFE73866DF671867DBE73867FFE0000
+E093:00007FFE61CE6FB663B66FB661CE7FFE7FFE738E6DF671C67DF6738E7FFE0000
+E094:00007FFE61CE6FB663B66FB661CE7FFE7FFE73B66DB671867DF673F67FFE0000
+E095:00007FFE61CE6FB663B66FB661CE7FFE7FFE73866DBE71867DF673867FFE0000
+E096:00007FFE61CE6FB663B66FB661CE7FFE7FFE73CE6DBE718E7DB673CE7FFE0000
+E097:00007FFE61CE6FB663B66FB661CE7FFE7FFE73866DF671EE7DDE73DE7FFE0000
+E098:00007FFE61CE6FB663B66FB661CE7FFE7FFE73CE6DB671CE7DB673CE7FFE0000
+E099:00007FFE61CE6FB663B66FB661CE7FFE7FFE73CE6DB671C67DF673CE7FFE0000
+E09A:00007FFE61CE6FB663B66FB661CE7FFE7FFE73866DB671867DB673B67FFE0000
+E09B:00007FFE61CE6FB663B66FB661CE7FFE7FFE738E6DB6718E7DB6738E7FFE0000
+E09C:00007FFE61CE6FB663B66FB661CE7FFE7FFE73C66DBE71BE7DBE73C67FFE0000
+E09D:00007FFE61CE6FB663B66FB661CE7FFE7FFE738E6DB671B67DB6738E7FFE0000
+E09E:00007FFE61CE6FB663B66FB661CE7FFE7FFE73866DBE718E7DBE73867FFE0000
+E09F:00007FFE61CE6FB663B66FB661CE7FFE7FFE73866DBE718E7DBE73BE7FFE0000
+E0A0:00007FFE61CE6FB663B66FB661CE7FFE7FFE61CE6DB661B66DB66DCE7FFE0000
+E0A1:00007FFE61CE6FB663B66FB661CE7FFE7FFE61EE6DCE61EE6DEE6DC67FFE0000
+E0A2:00007FFE61CE6FB663B66FB661CE7FFE7FFE61866DF661866DBE6D867FFE0000
+E0A3:00007FFE61CE6FB663B66FB661CE7FFE7FFE618E6DF661C66DF66D8E7FFE0000
+E0A4:00007FFE61CE6FB663B66FB661CE7FFE7FFE61B66DB661866DF66DF67FFE0000
+E0A5:00007FFE61CE6FB663B66FB661CE7FFE7FFE61866DBE61866DF66D867FFE0000
+E0A6:00007FFE61CE6FB663B66FB661CE7FFE7FFE61CE6DBE618E6DB66DCE7FFE0000
+E0A7:00007FFE61CE6FB663B66FB661CE7FFE7FFE61866DF661EE6DDE6DDE7FFE0000
+E0A8:00007FFE61CE6FB663B66FB661CE7FFE7FFE61CE6DB661CE6DB66DCE7FFE0000
+E0A9:00007FFE61CE6FB663B66FB661CE7FFE7FFE61CE6DB661C66DF66DCE7FFE0000
+E0AA:00007FFE61CE6FB663B66FB661CE7FFE7FFE61866DB661866DB66DB67FFE0000
+E0AB:00007FFE61CE6FB663B66FB661CE7FFE7FFE618E6DB6618E6DB66D8E7FFE0000
+E0AC:00007FFE61CE6FB663B66FB661CE7FFE7FFE61C66DBE61BE6DBE6DC67FFE0000
+E0AD:00007FFE61CE6FB663B66FB661CE7FFE7FFE618E6DB661B66DB66D8E7FFE0000
+E0AE:00007FFE61CE6FB663B66FB661CE7FFE7FFE61866DBE618E6DBE6D867FFE0000
+E0AF:00007FFE61CE6FB663B66FB661CE7FFE7FFE61866DBE618E6DBE6DBE7FFE0000
+E0B0:00007FFE61CE6FB663B66FB661CE7FFE7FFE63CE6DB663B66DB663CE7FFE0000
+E0B1:00007FFE61CE6FB663B66FB661CE7FFE7FFE63EE6DCE63EE6DEE63C67FFE0000
+E0B2:00007FFE61CE6FB663B66FB661CE7FFE7FFE63866DF663866DBE63867FFE0000
+E0B3:00007FFE61CE6FB663B66FB661CE7FFE7FFE638E6DF663C66DF6638E7FFE0000
+E0B4:00007FFE61CE6FB663B66FB661CE7FFE7FFE63B66DB663866DF663F67FFE0000
+E0B5:00007FFE61CE6FB663B66FB661CE7FFE7FFE63866DBE63866DF663867FFE0000
+E0B6:00007FFE61CE6FB663B66FB661CE7FFE7FFE63CE6DBE638E6DB663CE7FFE0000
+E0B7:00007FFE61CE6FB663B66FB661CE7FFE7FFE63866DF663EE6DDE63DE7FFE0000
+E0B8:00007FFE61CE6FB663B66FB661CE7FFE7FFE63CE6DB663CE6DB663CE7FFE0000
+E0B9:00007FFE61CE6FB663B66FB661CE7FFE7FFE63CE6DB663C66DF663CE7FFE0000
+E0BA:00007FFE61CE6FB663B66FB661CE7FFE7FFE63866DB663866DB663B67FFE0000
+E0BB:00007FFE61CE6FB663B66FB661CE7FFE7FFE638E6DB6638E6DB6638E7FFE0000
+E0BC:00007FFE61CE6FB663B66FB661CE7FFE7FFE63C66DBE63BE6DBE63C67FFE0000
+E0BD:00007FFE61CE6FB663B66FB661CE7FFE7FFE638E6DB663B66DB6638E7FFE0000
+E0BE:00007FFE61CE6FB663B66FB661CE7FFE7FFE63866DBE638E6DBE63867FFE0000
+E0BF:00007FFE61CE6FB663B66FB661CE7FFE7FFE63866DBE638E6DBE63BE7FFE0000
+E0C0:00007FFE61CE6FB663B66FB661CE7FFE7FFE71CE6FB66FB66FB671CE7FFE0000
+E0C1:00007FFE61CE6FB663B66FB661CE7FFE7FFE71EE6FCE6FEE6FEE71C67FFE0000
+E0C2:00007FFE61CE6FB663B66FB661CE7FFE7FFE71866FF66F866FBE71867FFE0000
+E0C3:00007FFE61CE6FB663B66FB661CE7FFE7FFE718E6FF66FC66FF6718E7FFE0000
+E0C4:00007FFE61CE6FB663B66FB661CE7FFE7FFE71B66FB66F866FF671F67FFE0000
+E0C5:00007FFE61CE6FB663B66FB661CE7FFE7FFE71866FBE6F866FF671867FFE0000
+E0C6:00007FFE61CE6FB663B66FB661CE7FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000
+E0C7:00007FFE61CE6FB663B66FB661CE7FFE7FFE71866FF66FEE6FDE71DE7FFE0000
+E0C8:00007FFE61CE6FB663B66FB661CE7FFE7FFE71CE6FB66FCE6FB671CE7FFE0000
+E0C9:00007FFE61CE6FB663B66FB661CE7FFE7FFE71CE6FB66FC66FF671CE7FFE0000
+E0CA:00007FFE61CE6FB663B66FB661CE7FFE7FFE71866FB66F866FB671B67FFE0000
+E0CB:00007FFE61CE6FB663B66FB661CE7FFE7FFE718E6FB66F8E6FB6718E7FFE0000
+E0CC:00007FFE61CE6FB663B66FB661CE7FFE7FFE71C66FBE6FBE6FBE71C67FFE0000
+E0CD:00007FFE61CE6FB663B66FB661CE7FFE7FFE718E6FB66FB66FB6718E7FFE0000
+E0CE:00007FFE61CE6FB663B66FB661CE7FFE7FFE71866FBE6F8E6FBE71867FFE0000
+E0CF:00007FFE61CE6FB663B66FB661CE7FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+E0D0:00007FFE61CE6FB663B66FB661CE7FFE7FFE63CE6DB66DB66DB663CE7FFE0000
+E0D1:00007FFE61CE6FB663B66FB661CE7FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000
+E0D2:00007FFE61CE6FB663B66FB661CE7FFE7FFE63866DF66D866DBE63867FFE0000
+E0D3:00007FFE61CE6FB663B66FB661CE7FFE7FFE638E6DF66DC66DF6638E7FFE0000
+E0D4:00007FFE61CE6FB663B66FB661CE7FFE7FFE63B66DB66D866DF663F67FFE0000
+E0D5:00007FFE61CE6FB663B66FB661CE7FFE7FFE63866DBE6D866DF663867FFE0000
+E0D6:00007FFE61CE6FB663B66FB661CE7FFE7FFE63CE6DBE6D8E6DB663CE7FFE0000
+E0D7:00007FFE61CE6FB663B66FB661CE7FFE7FFE63866DF66DEE6DDE63DE7FFE0000
+E0D8:00007FFE61CE6FB663B66FB661CE7FFE7FFE63CE6DB66DCE6DB663CE7FFE0000
+E0D9:00007FFE61CE6FB663B66FB661CE7FFE7FFE63CE6DB66DC66DF663CE7FFE0000
+E0DA:00007FFE61CE6FB663B66FB661CE7FFE7FFE63866DB66D866DB663B67FFE0000
+E0DB:00007FFE61CE6FB663B66FB661CE7FFE7FFE638E6DB66D8E6DB6638E7FFE0000
+E0DC:00007FFE61CE6FB663B66FB661CE7FFE7FFE63C66DBE6DBE6DBE63C67FFE0000
+E0DD:00007FFE61CE6FB663B66FB661CE7FFE7FFE638E6DB66DB66DB6638E7FFE0000
+E0DE:00007FFE61CE6FB663B66FB661CE7FFE7FFE63866DBE6D8E6DBE63867FFE0000
+E0DF:00007FFE61CE6FB663B66FB661CE7FFE7FFE63866DBE6D8E6DBE63BE7FFE0000
+E0E0:00007FFE61CE6FB663B66FB661CE7FFE7FFE61CE6FB663B66FB661CE7FFE0000
+E0E1:00007FFE61CE6FB663B66FB661CE7FFE7FFE61EE6FCE63EE6FEE61C67FFE0000
+E0E2:00007FFE61CE6FB663B66FB661CE7FFE7FFE61866FF663866FBE61867FFE0000
+E0E3:00007FFE61CE6FB663B66FB661CE7FFE7FFE618E6FF663C66FF6618E7FFE0000
+E0E4:00007FFE61CE6FB663B66FB661CE7FFE7FFE61B66FB663866FF661F67FFE0000
+E0E5:00007FFE61CE6FB663B66FB661CE7FFE7FFE61866FBE63866FF661867FFE0000
+E0E6:00007FFE61CE6FB663B66FB661CE7FFE7FFE61CE6FBE638E6FB661CE7FFE0000
+E0E7:00007FFE61CE6FB663B66FB661CE7FFE7FFE61866FF663EE6FDE61DE7FFE0000
+E0E8:00007FFE61CE6FB663B66FB661CE7FFE7FFE61CE6FB663CE6FB661CE7FFE0000
+E0E9:00007FFE61CE6FB663B66FB661CE7FFE7FFE61CE6FB663C66FF661CE7FFE0000
+E0EA:00007FFE61CE6FB663B66FB661CE7FFE7FFE61866FB663866FB661B67FFE0000
+E0EB:00007FFE61CE6FB663B66FB661CE7FFE7FFE618E6FB6638E6FB6618E7FFE0000
+E0EC:00007FFE61CE6FB663B66FB661CE7FFE7FFE61C66FBE63BE6FBE61C67FFE0000
+E0ED:00007FFE61CE6FB663B66FB661CE7FFE7FFE618E6FB663B66FB6618E7FFE0000
+E0EE:00007FFE61CE6FB663B66FB661CE7FFE7FFE61866FBE638E6FBE61867FFE0000
+E0EF:00007FFE61CE6FB663B66FB661CE7FFE7FFE61866FBE638E6FBE61BE7FFE0000
+E0F0:00007FFE61CE6FB663B66FB661CE7FFE7FFE61CE6FB663B66FB66FCE7FFE0000
+E0F1:00007FFE61CE6FB663B66FB661CE7FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000
+E0F2:00007FFE61CE6FB663B66FB661CE7FFE7FFE61866FF663866FBE6F867FFE0000
+E0F3:00007FFE61CE6FB663B66FB661CE7FFE7FFE618E6FF663C66FF66F8E7FFE0000
+E0F4:00007FFE61CE6FB663B66FB661CE7FFE7FFE61B66FB663866FF66FF67FFE0000
+E0F5:00007FFE61CE6FB663B66FB661CE7FFE7FFE61866FBE63866FF66F867FFE0000
+E0F6:00007FFE61CE6FB663B66FB661CE7FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+E0F7:00007FFE61CE6FB663B66FB661CE7FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+E0F8:00007FFE61CE6FB663B66FB661CE7FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+E0F9:00007FFE61CE6FB663B66FB661CE7FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+E0FA:00007FFE61CE6FB663B66FB661CE7FFE7FFE61866FB663866FB66FB67FFE0000
+E0FB:00007FFE61CE6FB663B66FB661CE7FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+E0FC:00007FFE61CE6FB663B66FB661CE7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+E0FD:00007FFE61CE6FB663B66FB661CE7FFE7FFE618E6FB663B66FB66F8E7FFE0000
+E0FE:00007FFE61CE6FB663B66FB661CE7FFE7FFE61866FBE638E6FBE6F867FFE0000
+E0FF:00007FFE61CE6FB663B66FB661CE7FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+E100:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73CE6DB66DB66DB673CE7FFE0000
+E101:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73EE6DCE6DEE6DEE73C67FFE0000
+E102:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73866DF66D866DBE73867FFE0000
+E103:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE738E6DF66DC66DF6738E7FFE0000
+E104:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73B66DB66D866DF673F67FFE0000
+E105:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73866DBE6D866DF673867FFE0000
+E106:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73CE6DBE6D8E6DB673CE7FFE0000
+E107:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73866DF66DEE6DDE73DE7FFE0000
+E108:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73CE6DB66DCE6DB673CE7FFE0000
+E109:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73CE6DB66DC66DF673CE7FFE0000
+E10A:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73866DB66D866DB673B67FFE0000
+E10B:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE738E6DB66D8E6DB6738E7FFE0000
+E10C:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73C66DBE6DBE6DBE73C67FFE0000
+E10D:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE738E6DB66DB66DB6738E7FFE0000
+E10E:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73866DBE6D8E6DBE73867FFE0000
+E10F:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73866DBE6D8E6DBE73BE7FFE0000
+E110:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE7BCE73B67BB67BB671CE7FFE0000
+E111:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE7BEE73CE7BEE7BEE71C67FFE0000
+E112:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE7B8673F67B867BBE71867FFE0000
+E113:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE7B8E73F67BC67BF6718E7FFE0000
+E114:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE7BB673B67B867BF671F67FFE0000
+E115:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE7B8673BE7B867BF671867FFE0000
+E116:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE7BCE73BE7B8E7BB671CE7FFE0000
+E117:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE7B8673F67BEE7BDE71DE7FFE0000
+E118:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE7BCE73B67BCE7BB671CE7FFE0000
+E119:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE7BCE73B67BC67BF671CE7FFE0000
+E11A:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE7B8673B67B867BB671B67FFE0000
+E11B:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE7B8E73B67B8E7BB6718E7FFE0000
+E11C:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE7BC673BE7BBE7BBE71C67FFE0000
+E11D:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE7B8E73B67BB67BB6718E7FFE0000
+E11E:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE7B8673BE7B8E7BBE71867FFE0000
+E11F:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE7B8673BE7B8E7BBE71BE7FFE0000
+E120:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61CE7DB661B66FB661CE7FFE0000
+E121:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61EE7DCE61EE6FEE61C67FFE0000
+E122:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61867DF661866FBE61867FFE0000
+E123:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE618E7DF661C66FF6618E7FFE0000
+E124:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61B67DB661866FF661F67FFE0000
+E125:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61867DBE61866FF661867FFE0000
+E126:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61CE7DBE618E6FB661CE7FFE0000
+E127:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61867DF661EE6FDE61DE7FFE0000
+E128:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61CE7DB661CE6FB661CE7FFE0000
+E129:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61CE7DB661C66FF661CE7FFE0000
+E12A:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61867DB661866FB661B67FFE0000
+E12B:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE618E7DB6618E6FB6618E7FFE0000
+E12C:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61C67DBE61BE6FBE61C67FFE0000
+E12D:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE618E7DB661B66FB6618E7FFE0000
+E12E:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61867DBE618E6FBE61867FFE0000
+E12F:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61867DBE618E6FBE61BE7FFE0000
+E130:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE63CE7DB671B67DB663CE7FFE0000
+E131:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE63EE7DCE71EE7DEE63C67FFE0000
+E132:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE63867DF671867DBE63867FFE0000
+E133:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE638E7DF671C67DF6638E7FFE0000
+E134:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE63B67DB671867DF663F67FFE0000
+E135:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE63867DBE71867DF663867FFE0000
+E136:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE63CE7DBE718E7DB663CE7FFE0000
+E137:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE63867DF671EE7DDE63DE7FFE0000
+E138:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE63CE7DB671CE7DB663CE7FFE0000
+E139:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE63CE7DB671C67DF663CE7FFE0000
+E13A:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE63867DB671867DB663B67FFE0000
+E13B:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE638E7DB6718E7DB6638E7FFE0000
+E13C:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE63C67DBE71BE7DBE63C67FFE0000
+E13D:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE638E7DB671B67DB6638E7FFE0000
+E13E:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE63867DBE718E7DBE63867FFE0000
+E13F:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE63867DBE718E7DBE63BE7FFE0000
+E140:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE6DCE6DB661B67DB67DCE7FFE0000
+E141:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE6DEE6DCE61EE7DEE7DC67FFE0000
+E142:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE6D866DF661867DBE7D867FFE0000
+E143:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE6D8E6DF661C67DF67D8E7FFE0000
+E144:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE6DB66DB661867DF67DF67FFE0000
+E145:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE6D866DBE61867DF67D867FFE0000
+E146:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE6DCE6DBE618E7DB67DCE7FFE0000
+E147:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE6D866DF661EE7DDE7DDE7FFE0000
+E148:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE6DCE6DB661CE7DB67DCE7FFE0000
+E149:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE6DCE6DB661C67DF67DCE7FFE0000
+E14A:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE6D866DB661867DB67DB67FFE0000
+E14B:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE6D8E6DB6618E7DB67D8E7FFE0000
+E14C:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE6DC66DBE61BE7DBE7DC67FFE0000
+E14D:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE6D8E6DB661B67DB67D8E7FFE0000
+E14E:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE6D866DBE618E7DBE7D867FFE0000
+E14F:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE6D866DBE618E7DBE7DBE7FFE0000
+E150:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61CE6FB661B67DB661CE7FFE0000
+E151:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61EE6FCE61EE7DEE61C67FFE0000
+E152:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61866FF661867DBE61867FFE0000
+E153:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE618E6FF661C67DF6618E7FFE0000
+E154:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61B66FB661867DF661F67FFE0000
+E155:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61866FBE61867DF661867FFE0000
+E156:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61CE6FBE618E7DB661CE7FFE0000
+E157:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61866FF661EE7DDE61DE7FFE0000
+E158:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61CE6FB661CE7DB661CE7FFE0000
+E159:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61CE6FB661C67DF661CE7FFE0000
+E15A:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61866FB661867DB661B67FFE0000
+E15B:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE618E6FB6618E7DB6618E7FFE0000
+E15C:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61C66FBE61BE7DBE61C67FFE0000
+E15D:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE618E6FB661B67DB6618E7FFE0000
+E15E:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61866FBE618E7DBE61867FFE0000
+E15F:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61866FBE618E7DBE61BE7FFE0000
+E160:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73CE6FB663B66DB673CE7FFE0000
+E161:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73EE6FCE63EE6DEE73C67FFE0000
+E162:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73866FF663866DBE73867FFE0000
+E163:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE738E6FF663C66DF6738E7FFE0000
+E164:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73B66FB663866DF673F67FFE0000
+E165:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73866FBE63866DF673867FFE0000
+E166:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73CE6FBE638E6DB673CE7FFE0000
+E167:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73866FF663EE6DDE73DE7FFE0000
+E168:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73CE6FB663CE6DB673CE7FFE0000
+E169:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73CE6FB663C66DF673CE7FFE0000
+E16A:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73866FB663866DB673B67FFE0000
+E16B:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE738E6FB6638E6DB6738E7FFE0000
+E16C:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73C66FBE63BE6DBE73C67FFE0000
+E16D:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE738E6FB663B66DB6738E7FFE0000
+E16E:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73866FBE638E6DBE73867FFE0000
+E16F:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73866FBE638E6DBE73BE7FFE0000
+E170:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61CE7DB67BB677B677CE7FFE0000
+E171:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61EE7DCE7BEE77EE77C67FFE0000
+E172:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61867DF67B8677BE77867FFE0000
+E173:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE618E7DF67BC677F6778E7FFE0000
+E174:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61B67DB67B8677F677F67FFE0000
+E175:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61867DBE7B8677F677867FFE0000
+E176:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61CE7DBE7B8E77B677CE7FFE0000
+E177:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61867DF67BEE77DE77DE7FFE0000
+E178:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61CE7DB67BCE77B677CE7FFE0000
+E179:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61CE7DB67BC677F677CE7FFE0000
+E17A:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61867DB67B8677B677B67FFE0000
+E17B:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE618E7DB67B8E77B6778E7FFE0000
+E17C:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61C67DBE7BBE77BE77C67FFE0000
+E17D:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE618E7DB67BB677B6778E7FFE0000
+E17E:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61867DBE7B8E77BE77867FFE0000
+E17F:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61867DBE7B8E77BE77BE7FFE0000
+E180:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73CE6DB673B66DB673CE7FFE0000
+E181:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73EE6DCE73EE6DEE73C67FFE0000
+E182:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73866DF673866DBE73867FFE0000
+E183:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE738E6DF673C66DF6738E7FFE0000
+E184:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73B66DB673866DF673F67FFE0000
+E185:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73866DBE73866DF673867FFE0000
+E186:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73CE6DBE738E6DB673CE7FFE0000
+E187:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73866DF673EE6DDE73DE7FFE0000
+E188:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73CE6DB673CE6DB673CE7FFE0000
+E189:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73CE6DB673C66DF673CE7FFE0000
+E18A:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73866DB673866DB673B67FFE0000
+E18B:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE738E6DB6738E6DB6738E7FFE0000
+E18C:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73C66DBE73BE6DBE73C67FFE0000
+E18D:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE738E6DB673B66DB6738E7FFE0000
+E18E:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73866DBE738E6DBE73867FFE0000
+E18F:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73866DBE738E6DBE73BE7FFE0000
+E190:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73CE6DB671B67DB673CE7FFE0000
+E191:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73EE6DCE71EE7DEE73C67FFE0000
+E192:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73866DF671867DBE73867FFE0000
+E193:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE738E6DF671C67DF6738E7FFE0000
+E194:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73B66DB671867DF673F67FFE0000
+E195:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73866DBE71867DF673867FFE0000
+E196:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73CE6DBE718E7DB673CE7FFE0000
+E197:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73866DF671EE7DDE73DE7FFE0000
+E198:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73CE6DB671CE7DB673CE7FFE0000
+E199:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73CE6DB671C67DF673CE7FFE0000
+E19A:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73866DB671867DB673B67FFE0000
+E19B:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE738E6DB6718E7DB6738E7FFE0000
+E19C:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73C66DBE71BE7DBE73C67FFE0000
+E19D:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE738E6DB671B67DB6738E7FFE0000
+E19E:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73866DBE718E7DBE73867FFE0000
+E19F:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE73866DBE718E7DBE73BE7FFE0000
+E1A0:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61CE6DB661B66DB66DCE7FFE0000
+E1A1:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61EE6DCE61EE6DEE6DC67FFE0000
+E1A2:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61866DF661866DBE6D867FFE0000
+E1A3:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE618E6DF661C66DF66D8E7FFE0000
+E1A4:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61B66DB661866DF66DF67FFE0000
+E1A5:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61866DBE61866DF66D867FFE0000
+E1A6:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61CE6DBE618E6DB66DCE7FFE0000
+E1A7:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61866DF661EE6DDE6DDE7FFE0000
+E1A8:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61CE6DB661CE6DB66DCE7FFE0000
+E1A9:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61CE6DB661C66DF66DCE7FFE0000
+E1AA:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61866DB661866DB66DB67FFE0000
+E1AB:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE618E6DB6618E6DB66D8E7FFE0000
+E1AC:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61C66DBE61BE6DBE6DC67FFE0000
+E1AD:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE618E6DB661B66DB66D8E7FFE0000
+E1AE:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61866DBE618E6DBE6D867FFE0000
+E1AF:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61866DBE618E6DBE6DBE7FFE0000
+E1B0:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE63CE6DB663B66DB663CE7FFE0000
+E1B1:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE63EE6DCE63EE6DEE63C67FFE0000
+E1B2:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE63866DF663866DBE63867FFE0000
+E1B3:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE638E6DF663C66DF6638E7FFE0000
+E1B4:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE63B66DB663866DF663F67FFE0000
+E1B5:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE63866DBE63866DF663867FFE0000
+E1B6:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE63CE6DBE638E6DB663CE7FFE0000
+E1B7:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE63866DF663EE6DDE63DE7FFE0000
+E1B8:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE63CE6DB663CE6DB663CE7FFE0000
+E1B9:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE63CE6DB663C66DF663CE7FFE0000
+E1BA:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE63866DB663866DB663B67FFE0000
+E1BB:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE638E6DB6638E6DB6638E7FFE0000
+E1BC:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE63C66DBE63BE6DBE63C67FFE0000
+E1BD:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE638E6DB663B66DB6638E7FFE0000
+E1BE:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE63866DBE638E6DBE63867FFE0000
+E1BF:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE63866DBE638E6DBE63BE7FFE0000
+E1C0:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE71CE6FB66FB66FB671CE7FFE0000
+E1C1:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE71EE6FCE6FEE6FEE71C67FFE0000
+E1C2:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE71866FF66F866FBE71867FFE0000
+E1C3:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE718E6FF66FC66FF6718E7FFE0000
+E1C4:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE71B66FB66F866FF671F67FFE0000
+E1C5:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE71866FBE6F866FF671867FFE0000
+E1C6:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000
+E1C7:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE71866FF66FEE6FDE71DE7FFE0000
+E1C8:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE71CE6FB66FCE6FB671CE7FFE0000
+E1C9:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE71CE6FB66FC66FF671CE7FFE0000
+E1CA:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE71866FB66F866FB671B67FFE0000
+E1CB:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE718E6FB66F8E6FB6718E7FFE0000
+E1CC:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE71C66FBE6FBE6FBE71C67FFE0000
+E1CD:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE718E6FB66FB66FB6718E7FFE0000
+E1CE:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE71866FBE6F8E6FBE71867FFE0000
+E1CF:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+E1D0:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE63CE6DB66DB66DB663CE7FFE0000
+E1D1:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000
+E1D2:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE63866DF66D866DBE63867FFE0000
+E1D3:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE638E6DF66DC66DF6638E7FFE0000
+E1D4:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE63B66DB66D866DF663F67FFE0000
+E1D5:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE63866DBE6D866DF663867FFE0000
+E1D6:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE63CE6DBE6D8E6DB663CE7FFE0000
+E1D7:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE63866DF66DEE6DDE63DE7FFE0000
+E1D8:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE63CE6DB66DCE6DB663CE7FFE0000
+E1D9:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE63CE6DB66DC66DF663CE7FFE0000
+E1DA:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE63866DB66D866DB663B67FFE0000
+E1DB:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE638E6DB66D8E6DB6638E7FFE0000
+E1DC:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE63C66DBE6DBE6DBE63C67FFE0000
+E1DD:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE638E6DB66DB66DB6638E7FFE0000
+E1DE:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE63866DBE6D8E6DBE63867FFE0000
+E1DF:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE63866DBE6D8E6DBE63BE7FFE0000
+E1E0:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61CE6FB663B66FB661CE7FFE0000
+E1E1:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61EE6FCE63EE6FEE61C67FFE0000
+E1E2:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61866FF663866FBE61867FFE0000
+E1E3:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE618E6FF663C66FF6618E7FFE0000
+E1E4:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61B66FB663866FF661F67FFE0000
+E1E5:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61866FBE63866FF661867FFE0000
+E1E6:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61CE6FBE638E6FB661CE7FFE0000
+E1E7:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61866FF663EE6FDE61DE7FFE0000
+E1E8:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61CE6FB663CE6FB661CE7FFE0000
+E1E9:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61CE6FB663C66FF661CE7FFE0000
+E1EA:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61866FB663866FB661B67FFE0000
+E1EB:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE618E6FB6638E6FB6618E7FFE0000
+E1EC:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61C66FBE63BE6FBE61C67FFE0000
+E1ED:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE618E6FB663B66FB6618E7FFE0000
+E1EE:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61866FBE638E6FBE61867FFE0000
+E1EF:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61866FBE638E6FBE61BE7FFE0000
+E1F0:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61CE6FB663B66FB66FCE7FFE0000
+E1F1:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000
+E1F2:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61866FF663866FBE6F867FFE0000
+E1F3:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE618E6FF663C66FF66F8E7FFE0000
+E1F4:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61B66FB663866FF66FF67FFE0000
+E1F5:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61866FBE63866FF66F867FFE0000
+E1F6:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+E1F7:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+E1F8:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+E1F9:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+E1FA:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61866FB663866FB66FB67FFE0000
+E1FB:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+E1FC:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+E1FD:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE618E6FB663B66FB66F8E7FFE0000
+E1FE:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61866FBE638E6FBE6F867FFE0000
+E1FF:00007FFE61EE6FCE63EE6FEE61C67FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+E200:00007FFE61866FF663866FBE61867FFE7FFE73CE6DB66DB66DB673CE7FFE0000
+E201:00007FFE61866FF663866FBE61867FFE7FFE73EE6DCE6DEE6DEE73C67FFE0000
+E202:00007FFE61866FF663866FBE61867FFE7FFE73866DF66D866DBE73867FFE0000
+E203:00007FFE61866FF663866FBE61867FFE7FFE738E6DF66DC66DF6738E7FFE0000
+E204:00007FFE61866FF663866FBE61867FFE7FFE73B66DB66D866DF673F67FFE0000
+E205:00007FFE61866FF663866FBE61867FFE7FFE73866DBE6D866DF673867FFE0000
+E206:00007FFE61866FF663866FBE61867FFE7FFE73CE6DBE6D8E6DB673CE7FFE0000
+E207:00007FFE61866FF663866FBE61867FFE7FFE73866DF66DEE6DDE73DE7FFE0000
+E208:00007FFE61866FF663866FBE61867FFE7FFE73CE6DB66DCE6DB673CE7FFE0000
+E209:00007FFE61866FF663866FBE61867FFE7FFE73CE6DB66DC66DF673CE7FFE0000
+E20A:00007FFE61866FF663866FBE61867FFE7FFE73866DB66D866DB673B67FFE0000
+E20B:00007FFE61866FF663866FBE61867FFE7FFE738E6DB66D8E6DB6738E7FFE0000
+E20C:00007FFE61866FF663866FBE61867FFE7FFE73C66DBE6DBE6DBE73C67FFE0000
+E20D:00007FFE61866FF663866FBE61867FFE7FFE738E6DB66DB66DB6738E7FFE0000
+E20E:00007FFE61866FF663866FBE61867FFE7FFE73866DBE6D8E6DBE73867FFE0000
+E20F:00007FFE61866FF663866FBE61867FFE7FFE73866DBE6D8E6DBE73BE7FFE0000
+E210:00007FFE61866FF663866FBE61867FFE7FFE7BCE73B67BB67BB671CE7FFE0000
+E211:00007FFE61866FF663866FBE61867FFE7FFE7BEE73CE7BEE7BEE71C67FFE0000
+E212:00007FFE61866FF663866FBE61867FFE7FFE7B8673F67B867BBE71867FFE0000
+E213:00007FFE61866FF663866FBE61867FFE7FFE7B8E73F67BC67BF6718E7FFE0000
+E214:00007FFE61866FF663866FBE61867FFE7FFE7BB673B67B867BF671F67FFE0000
+E215:00007FFE61866FF663866FBE61867FFE7FFE7B8673BE7B867BF671867FFE0000
+E216:00007FFE61866FF663866FBE61867FFE7FFE7BCE73BE7B8E7BB671CE7FFE0000
+E217:00007FFE61866FF663866FBE61867FFE7FFE7B8673F67BEE7BDE71DE7FFE0000
+E218:00007FFE61866FF663866FBE61867FFE7FFE7BCE73B67BCE7BB671CE7FFE0000
+E219:00007FFE61866FF663866FBE61867FFE7FFE7BCE73B67BC67BF671CE7FFE0000
+E21A:00007FFE61866FF663866FBE61867FFE7FFE7B8673B67B867BB671B67FFE0000
+E21B:00007FFE61866FF663866FBE61867FFE7FFE7B8E73B67B8E7BB6718E7FFE0000
+E21C:00007FFE61866FF663866FBE61867FFE7FFE7BC673BE7BBE7BBE71C67FFE0000
+E21D:00007FFE61866FF663866FBE61867FFE7FFE7B8E73B67BB67BB6718E7FFE0000
+E21E:00007FFE61866FF663866FBE61867FFE7FFE7B8673BE7B8E7BBE71867FFE0000
+E21F:00007FFE61866FF663866FBE61867FFE7FFE7B8673BE7B8E7BBE71BE7FFE0000
+E220:00007FFE61866FF663866FBE61867FFE7FFE61CE7DB661B66FB661CE7FFE0000
+E221:00007FFE61866FF663866FBE61867FFE7FFE61EE7DCE61EE6FEE61C67FFE0000
+E222:00007FFE61866FF663866FBE61867FFE7FFE61867DF661866FBE61867FFE0000
+E223:00007FFE61866FF663866FBE61867FFE7FFE618E7DF661C66FF6618E7FFE0000
+E224:00007FFE61866FF663866FBE61867FFE7FFE61B67DB661866FF661F67FFE0000
+E225:00007FFE61866FF663866FBE61867FFE7FFE61867DBE61866FF661867FFE0000
+E226:00007FFE61866FF663866FBE61867FFE7FFE61CE7DBE618E6FB661CE7FFE0000
+E227:00007FFE61866FF663866FBE61867FFE7FFE61867DF661EE6FDE61DE7FFE0000
+E228:00007FFE61866FF663866FBE61867FFE7FFE61CE7DB661CE6FB661CE7FFE0000
+E229:00007FFE61866FF663866FBE61867FFE7FFE61CE7DB661C66FF661CE7FFE0000
+E22A:00007FFE61866FF663866FBE61867FFE7FFE61867DB661866FB661B67FFE0000
+E22B:00007FFE61866FF663866FBE61867FFE7FFE618E7DB6618E6FB6618E7FFE0000
+E22C:00007FFE61866FF663866FBE61867FFE7FFE61C67DBE61BE6FBE61C67FFE0000
+E22D:00007FFE61866FF663866FBE61867FFE7FFE618E7DB661B66FB6618E7FFE0000
+E22E:00007FFE61866FF663866FBE61867FFE7FFE61867DBE618E6FBE61867FFE0000
+E22F:00007FFE61866FF663866FBE61867FFE7FFE61867DBE618E6FBE61BE7FFE0000
+E230:00007FFE61866FF663866FBE61867FFE7FFE63CE7DB671B67DB663CE7FFE0000
+E231:00007FFE61866FF663866FBE61867FFE7FFE63EE7DCE71EE7DEE63C67FFE0000
+E232:00007FFE61866FF663866FBE61867FFE7FFE63867DF671867DBE63867FFE0000
+E233:00007FFE61866FF663866FBE61867FFE7FFE638E7DF671C67DF6638E7FFE0000
+E234:00007FFE61866FF663866FBE61867FFE7FFE63B67DB671867DF663F67FFE0000
+E235:00007FFE61866FF663866FBE61867FFE7FFE63867DBE71867DF663867FFE0000
+E236:00007FFE61866FF663866FBE61867FFE7FFE63CE7DBE718E7DB663CE7FFE0000
+E237:00007FFE61866FF663866FBE61867FFE7FFE63867DF671EE7DDE63DE7FFE0000
+E238:00007FFE61866FF663866FBE61867FFE7FFE63CE7DB671CE7DB663CE7FFE0000
+E239:00007FFE61866FF663866FBE61867FFE7FFE63CE7DB671C67DF663CE7FFE0000
+E23A:00007FFE61866FF663866FBE61867FFE7FFE63867DB671867DB663B67FFE0000
+E23B:00007FFE61866FF663866FBE61867FFE7FFE638E7DB6718E7DB6638E7FFE0000
+E23C:00007FFE61866FF663866FBE61867FFE7FFE63C67DBE71BE7DBE63C67FFE0000
+E23D:00007FFE61866FF663866FBE61867FFE7FFE638E7DB671B67DB6638E7FFE0000
+E23E:00007FFE61866FF663866FBE61867FFE7FFE63867DBE718E7DBE63867FFE0000
+E23F:00007FFE61866FF663866FBE61867FFE7FFE63867DBE718E7DBE63BE7FFE0000
+E240:00007FFE61866FF663866FBE61867FFE7FFE6DCE6DB661B67DB67DCE7FFE0000
+E241:00007FFE61866FF663866FBE61867FFE7FFE6DEE6DCE61EE7DEE7DC67FFE0000
+E242:00007FFE61866FF663866FBE61867FFE7FFE6D866DF661867DBE7D867FFE0000
+E243:00007FFE61866FF663866FBE61867FFE7FFE6D8E6DF661C67DF67D8E7FFE0000
+E244:00007FFE61866FF663866FBE61867FFE7FFE6DB66DB661867DF67DF67FFE0000
+E245:00007FFE61866FF663866FBE61867FFE7FFE6D866DBE61867DF67D867FFE0000
+E246:00007FFE61866FF663866FBE61867FFE7FFE6DCE6DBE618E7DB67DCE7FFE0000
+E247:00007FFE61866FF663866FBE61867FFE7FFE6D866DF661EE7DDE7DDE7FFE0000
+E248:00007FFE61866FF663866FBE61867FFE7FFE6DCE6DB661CE7DB67DCE7FFE0000
+E249:00007FFE61866FF663866FBE61867FFE7FFE6DCE6DB661C67DF67DCE7FFE0000
+E24A:00007FFE61866FF663866FBE61867FFE7FFE6D866DB661867DB67DB67FFE0000
+E24B:00007FFE61866FF663866FBE61867FFE7FFE6D8E6DB6618E7DB67D8E7FFE0000
+E24C:00007FFE61866FF663866FBE61867FFE7FFE6DC66DBE61BE7DBE7DC67FFE0000
+E24D:00007FFE61866FF663866FBE61867FFE7FFE6D8E6DB661B67DB67D8E7FFE0000
+E24E:00007FFE61866FF663866FBE61867FFE7FFE6D866DBE618E7DBE7D867FFE0000
+E24F:00007FFE61866FF663866FBE61867FFE7FFE6D866DBE618E7DBE7DBE7FFE0000
+E250:00007FFE61866FF663866FBE61867FFE7FFE61CE6FB661B67DB661CE7FFE0000
+E251:00007FFE61866FF663866FBE61867FFE7FFE61EE6FCE61EE7DEE61C67FFE0000
+E252:00007FFE61866FF663866FBE61867FFE7FFE61866FF661867DBE61867FFE0000
+E253:00007FFE61866FF663866FBE61867FFE7FFE618E6FF661C67DF6618E7FFE0000
+E254:00007FFE61866FF663866FBE61867FFE7FFE61B66FB661867DF661F67FFE0000
+E255:00007FFE61866FF663866FBE61867FFE7FFE61866FBE61867DF661867FFE0000
+E256:00007FFE61866FF663866FBE61867FFE7FFE61CE6FBE618E7DB661CE7FFE0000
+E257:00007FFE61866FF663866FBE61867FFE7FFE61866FF661EE7DDE61DE7FFE0000
+E258:00007FFE61866FF663866FBE61867FFE7FFE61CE6FB661CE7DB661CE7FFE0000
+E259:00007FFE61866FF663866FBE61867FFE7FFE61CE6FB661C67DF661CE7FFE0000
+E25A:00007FFE61866FF663866FBE61867FFE7FFE61866FB661867DB661B67FFE0000
+E25B:00007FFE61866FF663866FBE61867FFE7FFE618E6FB6618E7DB6618E7FFE0000
+E25C:00007FFE61866FF663866FBE61867FFE7FFE61C66FBE61BE7DBE61C67FFE0000
+E25D:00007FFE61866FF663866FBE61867FFE7FFE618E6FB661B67DB6618E7FFE0000
+E25E:00007FFE61866FF663866FBE61867FFE7FFE61866FBE618E7DBE61867FFE0000
+E25F:00007FFE61866FF663866FBE61867FFE7FFE61866FBE618E7DBE61BE7FFE0000
+E260:00007FFE61866FF663866FBE61867FFE7FFE73CE6FB663B66DB673CE7FFE0000
+E261:00007FFE61866FF663866FBE61867FFE7FFE73EE6FCE63EE6DEE73C67FFE0000
+E262:00007FFE61866FF663866FBE61867FFE7FFE73866FF663866DBE73867FFE0000
+E263:00007FFE61866FF663866FBE61867FFE7FFE738E6FF663C66DF6738E7FFE0000
+E264:00007FFE61866FF663866FBE61867FFE7FFE73B66FB663866DF673F67FFE0000
+E265:00007FFE61866FF663866FBE61867FFE7FFE73866FBE63866DF673867FFE0000
+E266:00007FFE61866FF663866FBE61867FFE7FFE73CE6FBE638E6DB673CE7FFE0000
+E267:00007FFE61866FF663866FBE61867FFE7FFE73866FF663EE6DDE73DE7FFE0000
+E268:00007FFE61866FF663866FBE61867FFE7FFE73CE6FB663CE6DB673CE7FFE0000
+E269:00007FFE61866FF663866FBE61867FFE7FFE73CE6FB663C66DF673CE7FFE0000
+E26A:00007FFE61866FF663866FBE61867FFE7FFE73866FB663866DB673B67FFE0000
+E26B:00007FFE61866FF663866FBE61867FFE7FFE738E6FB6638E6DB6738E7FFE0000
+E26C:00007FFE61866FF663866FBE61867FFE7FFE73C66FBE63BE6DBE73C67FFE0000
+E26D:00007FFE61866FF663866FBE61867FFE7FFE738E6FB663B66DB6738E7FFE0000
+E26E:00007FFE61866FF663866FBE61867FFE7FFE73866FBE638E6DBE73867FFE0000
+E26F:00007FFE61866FF663866FBE61867FFE7FFE73866FBE638E6DBE73BE7FFE0000
+E270:00007FFE61866FF663866FBE61867FFE7FFE61CE7DB67BB677B677CE7FFE0000
+E271:00007FFE61866FF663866FBE61867FFE7FFE61EE7DCE7BEE77EE77C67FFE0000
+E272:00007FFE61866FF663866FBE61867FFE7FFE61867DF67B8677BE77867FFE0000
+E273:00007FFE61866FF663866FBE61867FFE7FFE618E7DF67BC677F6778E7FFE0000
+E274:00007FFE61866FF663866FBE61867FFE7FFE61B67DB67B8677F677F67FFE0000
+E275:00007FFE61866FF663866FBE61867FFE7FFE61867DBE7B8677F677867FFE0000
+E276:00007FFE61866FF663866FBE61867FFE7FFE61CE7DBE7B8E77B677CE7FFE0000
+E277:00007FFE61866FF663866FBE61867FFE7FFE61867DF67BEE77DE77DE7FFE0000
+E278:00007FFE61866FF663866FBE61867FFE7FFE61CE7DB67BCE77B677CE7FFE0000
+E279:00007FFE61866FF663866FBE61867FFE7FFE61CE7DB67BC677F677CE7FFE0000
+E27A:00007FFE61866FF663866FBE61867FFE7FFE61867DB67B8677B677B67FFE0000
+E27B:00007FFE61866FF663866FBE61867FFE7FFE618E7DB67B8E77B6778E7FFE0000
+E27C:00007FFE61866FF663866FBE61867FFE7FFE61C67DBE7BBE77BE77C67FFE0000
+E27D:00007FFE61866FF663866FBE61867FFE7FFE618E7DB67BB677B6778E7FFE0000
+E27E:00007FFE61866FF663866FBE61867FFE7FFE61867DBE7B8E77BE77867FFE0000
+E27F:00007FFE61866FF663866FBE61867FFE7FFE61867DBE7B8E77BE77BE7FFE0000
+E280:00007FFE61866FF663866FBE61867FFE7FFE73CE6DB673B66DB673CE7FFE0000
+E281:00007FFE61866FF663866FBE61867FFE7FFE73EE6DCE73EE6DEE73C67FFE0000
+E282:00007FFE61866FF663866FBE61867FFE7FFE73866DF673866DBE73867FFE0000
+E283:00007FFE61866FF663866FBE61867FFE7FFE738E6DF673C66DF6738E7FFE0000
+E284:00007FFE61866FF663866FBE61867FFE7FFE73B66DB673866DF673F67FFE0000
+E285:00007FFE61866FF663866FBE61867FFE7FFE73866DBE73866DF673867FFE0000
+E286:00007FFE61866FF663866FBE61867FFE7FFE73CE6DBE738E6DB673CE7FFE0000
+E287:00007FFE61866FF663866FBE61867FFE7FFE73866DF673EE6DDE73DE7FFE0000
+E288:00007FFE61866FF663866FBE61867FFE7FFE73CE6DB673CE6DB673CE7FFE0000
+E289:00007FFE61866FF663866FBE61867FFE7FFE73CE6DB673C66DF673CE7FFE0000
+E28A:00007FFE61866FF663866FBE61867FFE7FFE73866DB673866DB673B67FFE0000
+E28B:00007FFE61866FF663866FBE61867FFE7FFE738E6DB6738E6DB6738E7FFE0000
+E28C:00007FFE61866FF663866FBE61867FFE7FFE73C66DBE73BE6DBE73C67FFE0000
+E28D:00007FFE61866FF663866FBE61867FFE7FFE738E6DB673B66DB6738E7FFE0000
+E28E:00007FFE61866FF663866FBE61867FFE7FFE73866DBE738E6DBE73867FFE0000
+E28F:00007FFE61866FF663866FBE61867FFE7FFE73866DBE738E6DBE73BE7FFE0000
+E290:00007FFE61866FF663866FBE61867FFE7FFE73CE6DB671B67DB673CE7FFE0000
+E291:00007FFE61866FF663866FBE61867FFE7FFE73EE6DCE71EE7DEE73C67FFE0000
+E292:00007FFE61866FF663866FBE61867FFE7FFE73866DF671867DBE73867FFE0000
+E293:00007FFE61866FF663866FBE61867FFE7FFE738E6DF671C67DF6738E7FFE0000
+E294:00007FFE61866FF663866FBE61867FFE7FFE73B66DB671867DF673F67FFE0000
+E295:00007FFE61866FF663866FBE61867FFE7FFE73866DBE71867DF673867FFE0000
+E296:00007FFE61866FF663866FBE61867FFE7FFE73CE6DBE718E7DB673CE7FFE0000
+E297:00007FFE61866FF663866FBE61867FFE7FFE73866DF671EE7DDE73DE7FFE0000
+E298:00007FFE61866FF663866FBE61867FFE7FFE73CE6DB671CE7DB673CE7FFE0000
+E299:00007FFE61866FF663866FBE61867FFE7FFE73CE6DB671C67DF673CE7FFE0000
+E29A:00007FFE61866FF663866FBE61867FFE7FFE73866DB671867DB673B67FFE0000
+E29B:00007FFE61866FF663866FBE61867FFE7FFE738E6DB6718E7DB6738E7FFE0000
+E29C:00007FFE61866FF663866FBE61867FFE7FFE73C66DBE71BE7DBE73C67FFE0000
+E29D:00007FFE61866FF663866FBE61867FFE7FFE738E6DB671B67DB6738E7FFE0000
+E29E:00007FFE61866FF663866FBE61867FFE7FFE73866DBE718E7DBE73867FFE0000
+E29F:00007FFE61866FF663866FBE61867FFE7FFE73866DBE718E7DBE73BE7FFE0000
+E2A0:00007FFE61866FF663866FBE61867FFE7FFE61CE6DB661B66DB66DCE7FFE0000
+E2A1:00007FFE61866FF663866FBE61867FFE7FFE61EE6DCE61EE6DEE6DC67FFE0000
+E2A2:00007FFE61866FF663866FBE61867FFE7FFE61866DF661866DBE6D867FFE0000
+E2A3:00007FFE61866FF663866FBE61867FFE7FFE618E6DF661C66DF66D8E7FFE0000
+E2A4:00007FFE61866FF663866FBE61867FFE7FFE61B66DB661866DF66DF67FFE0000
+E2A5:00007FFE61866FF663866FBE61867FFE7FFE61866DBE61866DF66D867FFE0000
+E2A6:00007FFE61866FF663866FBE61867FFE7FFE61CE6DBE618E6DB66DCE7FFE0000
+E2A7:00007FFE61866FF663866FBE61867FFE7FFE61866DF661EE6DDE6DDE7FFE0000
+E2A8:00007FFE61866FF663866FBE61867FFE7FFE61CE6DB661CE6DB66DCE7FFE0000
+E2A9:00007FFE61866FF663866FBE61867FFE7FFE61CE6DB661C66DF66DCE7FFE0000
+E2AA:00007FFE61866FF663866FBE61867FFE7FFE61866DB661866DB66DB67FFE0000
+E2AB:00007FFE61866FF663866FBE61867FFE7FFE618E6DB6618E6DB66D8E7FFE0000
+E2AC:00007FFE61866FF663866FBE61867FFE7FFE61C66DBE61BE6DBE6DC67FFE0000
+E2AD:00007FFE61866FF663866FBE61867FFE7FFE618E6DB661B66DB66D8E7FFE0000
+E2AE:00007FFE61866FF663866FBE61867FFE7FFE61866DBE618E6DBE6D867FFE0000
+E2AF:00007FFE61866FF663866FBE61867FFE7FFE61866DBE618E6DBE6DBE7FFE0000
+E2B0:00007FFE61866FF663866FBE61867FFE7FFE63CE6DB663B66DB663CE7FFE0000
+E2B1:00007FFE61866FF663866FBE61867FFE7FFE63EE6DCE63EE6DEE63C67FFE0000
+E2B2:00007FFE61866FF663866FBE61867FFE7FFE63866DF663866DBE63867FFE0000
+E2B3:00007FFE61866FF663866FBE61867FFE7FFE638E6DF663C66DF6638E7FFE0000
+E2B4:00007FFE61866FF663866FBE61867FFE7FFE63B66DB663866DF663F67FFE0000
+E2B5:00007FFE61866FF663866FBE61867FFE7FFE63866DBE63866DF663867FFE0000
+E2B6:00007FFE61866FF663866FBE61867FFE7FFE63CE6DBE638E6DB663CE7FFE0000
+E2B7:00007FFE61866FF663866FBE61867FFE7FFE63866DF663EE6DDE63DE7FFE0000
+E2B8:00007FFE61866FF663866FBE61867FFE7FFE63CE6DB663CE6DB663CE7FFE0000
+E2B9:00007FFE61866FF663866FBE61867FFE7FFE63CE6DB663C66DF663CE7FFE0000
+E2BA:00007FFE61866FF663866FBE61867FFE7FFE63866DB663866DB663B67FFE0000
+E2BB:00007FFE61866FF663866FBE61867FFE7FFE638E6DB6638E6DB6638E7FFE0000
+E2BC:00007FFE61866FF663866FBE61867FFE7FFE63C66DBE63BE6DBE63C67FFE0000
+E2BD:00007FFE61866FF663866FBE61867FFE7FFE638E6DB663B66DB6638E7FFE0000
+E2BE:00007FFE61866FF663866FBE61867FFE7FFE63866DBE638E6DBE63867FFE0000
+E2BF:00007FFE61866FF663866FBE61867FFE7FFE63866DBE638E6DBE63BE7FFE0000
+E2C0:00007FFE61866FF663866FBE61867FFE7FFE71CE6FB66FB66FB671CE7FFE0000
+E2C1:00007FFE61866FF663866FBE61867FFE7FFE71EE6FCE6FEE6FEE71C67FFE0000
+E2C2:00007FFE61866FF663866FBE61867FFE7FFE71866FF66F866FBE71867FFE0000
+E2C3:00007FFE61866FF663866FBE61867FFE7FFE718E6FF66FC66FF6718E7FFE0000
+E2C4:00007FFE61866FF663866FBE61867FFE7FFE71B66FB66F866FF671F67FFE0000
+E2C5:00007FFE61866FF663866FBE61867FFE7FFE71866FBE6F866FF671867FFE0000
+E2C6:00007FFE61866FF663866FBE61867FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000
+E2C7:00007FFE61866FF663866FBE61867FFE7FFE71866FF66FEE6FDE71DE7FFE0000
+E2C8:00007FFE61866FF663866FBE61867FFE7FFE71CE6FB66FCE6FB671CE7FFE0000
+E2C9:00007FFE61866FF663866FBE61867FFE7FFE71CE6FB66FC66FF671CE7FFE0000
+E2CA:00007FFE61866FF663866FBE61867FFE7FFE71866FB66F866FB671B67FFE0000
+E2CB:00007FFE61866FF663866FBE61867FFE7FFE718E6FB66F8E6FB6718E7FFE0000
+E2CC:00007FFE61866FF663866FBE61867FFE7FFE71C66FBE6FBE6FBE71C67FFE0000
+E2CD:00007FFE61866FF663866FBE61867FFE7FFE718E6FB66FB66FB6718E7FFE0000
+E2CE:00007FFE61866FF663866FBE61867FFE7FFE71866FBE6F8E6FBE71867FFE0000
+E2CF:00007FFE61866FF663866FBE61867FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+E2D0:00007FFE61866FF663866FBE61867FFE7FFE63CE6DB66DB66DB663CE7FFE0000
+E2D1:00007FFE61866FF663866FBE61867FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000
+E2D2:00007FFE61866FF663866FBE61867FFE7FFE63866DF66D866DBE63867FFE0000
+E2D3:00007FFE61866FF663866FBE61867FFE7FFE638E6DF66DC66DF6638E7FFE0000
+E2D4:00007FFE61866FF663866FBE61867FFE7FFE63B66DB66D866DF663F67FFE0000
+E2D5:00007FFE61866FF663866FBE61867FFE7FFE63866DBE6D866DF663867FFE0000
+E2D6:00007FFE61866FF663866FBE61867FFE7FFE63CE6DBE6D8E6DB663CE7FFE0000
+E2D7:00007FFE61866FF663866FBE61867FFE7FFE63866DF66DEE6DDE63DE7FFE0000
+E2D8:00007FFE61866FF663866FBE61867FFE7FFE63CE6DB66DCE6DB663CE7FFE0000
+E2D9:00007FFE61866FF663866FBE61867FFE7FFE63CE6DB66DC66DF663CE7FFE0000
+E2DA:00007FFE61866FF663866FBE61867FFE7FFE63866DB66D866DB663B67FFE0000
+E2DB:00007FFE61866FF663866FBE61867FFE7FFE638E6DB66D8E6DB6638E7FFE0000
+E2DC:00007FFE61866FF663866FBE61867FFE7FFE63C66DBE6DBE6DBE63C67FFE0000
+E2DD:00007FFE61866FF663866FBE61867FFE7FFE638E6DB66DB66DB6638E7FFE0000
+E2DE:00007FFE61866FF663866FBE61867FFE7FFE63866DBE6D8E6DBE63867FFE0000
+E2DF:00007FFE61866FF663866FBE61867FFE7FFE63866DBE6D8E6DBE63BE7FFE0000
+E2E0:00007FFE61866FF663866FBE61867FFE7FFE61CE6FB663B66FB661CE7FFE0000
+E2E1:00007FFE61866FF663866FBE61867FFE7FFE61EE6FCE63EE6FEE61C67FFE0000
+E2E2:00007FFE61866FF663866FBE61867FFE7FFE61866FF663866FBE61867FFE0000
+E2E3:00007FFE61866FF663866FBE61867FFE7FFE618E6FF663C66FF6618E7FFE0000
+E2E4:00007FFE61866FF663866FBE61867FFE7FFE61B66FB663866FF661F67FFE0000
+E2E5:00007FFE61866FF663866FBE61867FFE7FFE61866FBE63866FF661867FFE0000
+E2E6:00007FFE61866FF663866FBE61867FFE7FFE61CE6FBE638E6FB661CE7FFE0000
+E2E7:00007FFE61866FF663866FBE61867FFE7FFE61866FF663EE6FDE61DE7FFE0000
+E2E8:00007FFE61866FF663866FBE61867FFE7FFE61CE6FB663CE6FB661CE7FFE0000
+E2E9:00007FFE61866FF663866FBE61867FFE7FFE61CE6FB663C66FF661CE7FFE0000
+E2EA:00007FFE61866FF663866FBE61867FFE7FFE61866FB663866FB661B67FFE0000
+E2EB:00007FFE61866FF663866FBE61867FFE7FFE618E6FB6638E6FB6618E7FFE0000
+E2EC:00007FFE61866FF663866FBE61867FFE7FFE61C66FBE63BE6FBE61C67FFE0000
+E2ED:00007FFE61866FF663866FBE61867FFE7FFE618E6FB663B66FB6618E7FFE0000
+E2EE:00007FFE61866FF663866FBE61867FFE7FFE61866FBE638E6FBE61867FFE0000
+E2EF:00007FFE61866FF663866FBE61867FFE7FFE61866FBE638E6FBE61BE7FFE0000
+E2F0:00007FFE61866FF663866FBE61867FFE7FFE61CE6FB663B66FB66FCE7FFE0000
+E2F1:00007FFE61866FF663866FBE61867FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000
+E2F2:00007FFE61866FF663866FBE61867FFE7FFE61866FF663866FBE6F867FFE0000
+E2F3:00007FFE61866FF663866FBE61867FFE7FFE618E6FF663C66FF66F8E7FFE0000
+E2F4:00007FFE61866FF663866FBE61867FFE7FFE61B66FB663866FF66FF67FFE0000
+E2F5:00007FFE61866FF663866FBE61867FFE7FFE61866FBE63866FF66F867FFE0000
+E2F6:00007FFE61866FF663866FBE61867FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+E2F7:00007FFE61866FF663866FBE61867FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+E2F8:00007FFE61866FF663866FBE61867FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+E2F9:00007FFE61866FF663866FBE61867FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+E2FA:00007FFE61866FF663866FBE61867FFE7FFE61866FB663866FB66FB67FFE0000
+E2FB:00007FFE61866FF663866FBE61867FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+E2FC:00007FFE61866FF663866FBE61867FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+E2FD:00007FFE61866FF663866FBE61867FFE7FFE618E6FB663B66FB66F8E7FFE0000
+E2FE:00007FFE61866FF663866FBE61867FFE7FFE61866FBE638E6FBE6F867FFE0000
+E2FF:00007FFE61866FF663866FBE61867FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+E300:00007FFE618E6FF663C66FF6618E7FFE7FFE73CE6DB66DB66DB673CE7FFE0000
+E301:00007FFE618E6FF663C66FF6618E7FFE7FFE73EE6DCE6DEE6DEE73C67FFE0000
+E302:00007FFE618E6FF663C66FF6618E7FFE7FFE73866DF66D866DBE73867FFE0000
+E303:00007FFE618E6FF663C66FF6618E7FFE7FFE738E6DF66DC66DF6738E7FFE0000
+E304:00007FFE618E6FF663C66FF6618E7FFE7FFE73B66DB66D866DF673F67FFE0000
+E305:00007FFE618E6FF663C66FF6618E7FFE7FFE73866DBE6D866DF673867FFE0000
+E306:00007FFE618E6FF663C66FF6618E7FFE7FFE73CE6DBE6D8E6DB673CE7FFE0000
+E307:00007FFE618E6FF663C66FF6618E7FFE7FFE73866DF66DEE6DDE73DE7FFE0000
+E308:00007FFE618E6FF663C66FF6618E7FFE7FFE73CE6DB66DCE6DB673CE7FFE0000
+E309:00007FFE618E6FF663C66FF6618E7FFE7FFE73CE6DB66DC66DF673CE7FFE0000
+E30A:00007FFE618E6FF663C66FF6618E7FFE7FFE73866DB66D866DB673B67FFE0000
+E30B:00007FFE618E6FF663C66FF6618E7FFE7FFE738E6DB66D8E6DB6738E7FFE0000
+E30C:00007FFE618E6FF663C66FF6618E7FFE7FFE73C66DBE6DBE6DBE73C67FFE0000
+E30D:00007FFE618E6FF663C66FF6618E7FFE7FFE738E6DB66DB66DB6738E7FFE0000
+E30E:00007FFE618E6FF663C66FF6618E7FFE7FFE73866DBE6D8E6DBE73867FFE0000
+E30F:00007FFE618E6FF663C66FF6618E7FFE7FFE73866DBE6D8E6DBE73BE7FFE0000
+E310:00007FFE618E6FF663C66FF6618E7FFE7FFE7BCE73B67BB67BB671CE7FFE0000
+E311:00007FFE618E6FF663C66FF6618E7FFE7FFE7BEE73CE7BEE7BEE71C67FFE0000
+E312:00007FFE618E6FF663C66FF6618E7FFE7FFE7B8673F67B867BBE71867FFE0000
+E313:00007FFE618E6FF663C66FF6618E7FFE7FFE7B8E73F67BC67BF6718E7FFE0000
+E314:00007FFE618E6FF663C66FF6618E7FFE7FFE7BB673B67B867BF671F67FFE0000
+E315:00007FFE618E6FF663C66FF6618E7FFE7FFE7B8673BE7B867BF671867FFE0000
+E316:00007FFE618E6FF663C66FF6618E7FFE7FFE7BCE73BE7B8E7BB671CE7FFE0000
+E317:00007FFE618E6FF663C66FF6618E7FFE7FFE7B8673F67BEE7BDE71DE7FFE0000
+E318:00007FFE618E6FF663C66FF6618E7FFE7FFE7BCE73B67BCE7BB671CE7FFE0000
+E319:00007FFE618E6FF663C66FF6618E7FFE7FFE7BCE73B67BC67BF671CE7FFE0000
+E31A:00007FFE618E6FF663C66FF6618E7FFE7FFE7B8673B67B867BB671B67FFE0000
+E31B:00007FFE618E6FF663C66FF6618E7FFE7FFE7B8E73B67B8E7BB6718E7FFE0000
+E31C:00007FFE618E6FF663C66FF6618E7FFE7FFE7BC673BE7BBE7BBE71C67FFE0000
+E31D:00007FFE618E6FF663C66FF6618E7FFE7FFE7B8E73B67BB67BB6718E7FFE0000
+E31E:00007FFE618E6FF663C66FF6618E7FFE7FFE7B8673BE7B8E7BBE71867FFE0000
+E31F:00007FFE618E6FF663C66FF6618E7FFE7FFE7B8673BE7B8E7BBE71BE7FFE0000
+E320:00007FFE618E6FF663C66FF6618E7FFE7FFE61CE7DB661B66FB661CE7FFE0000
+E321:00007FFE618E6FF663C66FF6618E7FFE7FFE61EE7DCE61EE6FEE61C67FFE0000
+E322:00007FFE618E6FF663C66FF6618E7FFE7FFE61867DF661866FBE61867FFE0000
+E323:00007FFE618E6FF663C66FF6618E7FFE7FFE618E7DF661C66FF6618E7FFE0000
+E324:00007FFE618E6FF663C66FF6618E7FFE7FFE61B67DB661866FF661F67FFE0000
+E325:00007FFE618E6FF663C66FF6618E7FFE7FFE61867DBE61866FF661867FFE0000
+E326:00007FFE618E6FF663C66FF6618E7FFE7FFE61CE7DBE618E6FB661CE7FFE0000
+E327:00007FFE618E6FF663C66FF6618E7FFE7FFE61867DF661EE6FDE61DE7FFE0000
+E328:00007FFE618E6FF663C66FF6618E7FFE7FFE61CE7DB661CE6FB661CE7FFE0000
+E329:00007FFE618E6FF663C66FF6618E7FFE7FFE61CE7DB661C66FF661CE7FFE0000
+E32A:00007FFE618E6FF663C66FF6618E7FFE7FFE61867DB661866FB661B67FFE0000
+E32B:00007FFE618E6FF663C66FF6618E7FFE7FFE618E7DB6618E6FB6618E7FFE0000
+E32C:00007FFE618E6FF663C66FF6618E7FFE7FFE61C67DBE61BE6FBE61C67FFE0000
+E32D:00007FFE618E6FF663C66FF6618E7FFE7FFE618E7DB661B66FB6618E7FFE0000
+E32E:00007FFE618E6FF663C66FF6618E7FFE7FFE61867DBE618E6FBE61867FFE0000
+E32F:00007FFE618E6FF663C66FF6618E7FFE7FFE61867DBE618E6FBE61BE7FFE0000
+E330:00007FFE618E6FF663C66FF6618E7FFE7FFE63CE7DB671B67DB663CE7FFE0000
+E331:00007FFE618E6FF663C66FF6618E7FFE7FFE63EE7DCE71EE7DEE63C67FFE0000
+E332:00007FFE618E6FF663C66FF6618E7FFE7FFE63867DF671867DBE63867FFE0000
+E333:00007FFE618E6FF663C66FF6618E7FFE7FFE638E7DF671C67DF6638E7FFE0000
+E334:00007FFE618E6FF663C66FF6618E7FFE7FFE63B67DB671867DF663F67FFE0000
+E335:00007FFE618E6FF663C66FF6618E7FFE7FFE63867DBE71867DF663867FFE0000
+E336:00007FFE618E6FF663C66FF6618E7FFE7FFE63CE7DBE718E7DB663CE7FFE0000
+E337:00007FFE618E6FF663C66FF6618E7FFE7FFE63867DF671EE7DDE63DE7FFE0000
+E338:00007FFE618E6FF663C66FF6618E7FFE7FFE63CE7DB671CE7DB663CE7FFE0000
+E339:00007FFE618E6FF663C66FF6618E7FFE7FFE63CE7DB671C67DF663CE7FFE0000
+E33A:00007FFE618E6FF663C66FF6618E7FFE7FFE63867DB671867DB663B67FFE0000
+E33B:00007FFE618E6FF663C66FF6618E7FFE7FFE638E7DB6718E7DB6638E7FFE0000
+E33C:00007FFE618E6FF663C66FF6618E7FFE7FFE63C67DBE71BE7DBE63C67FFE0000
+E33D:00007FFE618E6FF663C66FF6618E7FFE7FFE638E7DB671B67DB6638E7FFE0000
+E33E:00007FFE618E6FF663C66FF6618E7FFE7FFE63867DBE718E7DBE63867FFE0000
+E33F:00007FFE618E6FF663C66FF6618E7FFE7FFE63867DBE718E7DBE63BE7FFE0000
+E340:00007FFE618E6FF663C66FF6618E7FFE7FFE6DCE6DB661B67DB67DCE7FFE0000
+E341:00007FFE618E6FF663C66FF6618E7FFE7FFE6DEE6DCE61EE7DEE7DC67FFE0000
+E342:00007FFE618E6FF663C66FF6618E7FFE7FFE6D866DF661867DBE7D867FFE0000
+E343:00007FFE618E6FF663C66FF6618E7FFE7FFE6D8E6DF661C67DF67D8E7FFE0000
+E344:00007FFE618E6FF663C66FF6618E7FFE7FFE6DB66DB661867DF67DF67FFE0000
+E345:00007FFE618E6FF663C66FF6618E7FFE7FFE6D866DBE61867DF67D867FFE0000
+E346:00007FFE618E6FF663C66FF6618E7FFE7FFE6DCE6DBE618E7DB67DCE7FFE0000
+E347:00007FFE618E6FF663C66FF6618E7FFE7FFE6D866DF661EE7DDE7DDE7FFE0000
+E348:00007FFE618E6FF663C66FF6618E7FFE7FFE6DCE6DB661CE7DB67DCE7FFE0000
+E349:00007FFE618E6FF663C66FF6618E7FFE7FFE6DCE6DB661C67DF67DCE7FFE0000
+E34A:00007FFE618E6FF663C66FF6618E7FFE7FFE6D866DB661867DB67DB67FFE0000
+E34B:00007FFE618E6FF663C66FF6618E7FFE7FFE6D8E6DB6618E7DB67D8E7FFE0000
+E34C:00007FFE618E6FF663C66FF6618E7FFE7FFE6DC66DBE61BE7DBE7DC67FFE0000
+E34D:00007FFE618E6FF663C66FF6618E7FFE7FFE6D8E6DB661B67DB67D8E7FFE0000
+E34E:00007FFE618E6FF663C66FF6618E7FFE7FFE6D866DBE618E7DBE7D867FFE0000
+E34F:00007FFE618E6FF663C66FF6618E7FFE7FFE6D866DBE618E7DBE7DBE7FFE0000
+E350:00007FFE618E6FF663C66FF6618E7FFE7FFE61CE6FB661B67DB661CE7FFE0000
+E351:00007FFE618E6FF663C66FF6618E7FFE7FFE61EE6FCE61EE7DEE61C67FFE0000
+E352:00007FFE618E6FF663C66FF6618E7FFE7FFE61866FF661867DBE61867FFE0000
+E353:00007FFE618E6FF663C66FF6618E7FFE7FFE618E6FF661C67DF6618E7FFE0000
+E354:00007FFE618E6FF663C66FF6618E7FFE7FFE61B66FB661867DF661F67FFE0000
+E355:00007FFE618E6FF663C66FF6618E7FFE7FFE61866FBE61867DF661867FFE0000
+E356:00007FFE618E6FF663C66FF6618E7FFE7FFE61CE6FBE618E7DB661CE7FFE0000
+E357:00007FFE618E6FF663C66FF6618E7FFE7FFE61866FF661EE7DDE61DE7FFE0000
+E358:00007FFE618E6FF663C66FF6618E7FFE7FFE61CE6FB661CE7DB661CE7FFE0000
+E359:00007FFE618E6FF663C66FF6618E7FFE7FFE61CE6FB661C67DF661CE7FFE0000
+E35A:00007FFE618E6FF663C66FF6618E7FFE7FFE61866FB661867DB661B67FFE0000
+E35B:00007FFE618E6FF663C66FF6618E7FFE7FFE618E6FB6618E7DB6618E7FFE0000
+E35C:00007FFE618E6FF663C66FF6618E7FFE7FFE61C66FBE61BE7DBE61C67FFE0000
+E35D:00007FFE618E6FF663C66FF6618E7FFE7FFE618E6FB661B67DB6618E7FFE0000
+E35E:00007FFE618E6FF663C66FF6618E7FFE7FFE61866FBE618E7DBE61867FFE0000
+E35F:00007FFE618E6FF663C66FF6618E7FFE7FFE61866FBE618E7DBE61BE7FFE0000
+E360:00007FFE618E6FF663C66FF6618E7FFE7FFE73CE6FB663B66DB673CE7FFE0000
+E361:00007FFE618E6FF663C66FF6618E7FFE7FFE73EE6FCE63EE6DEE73C67FFE0000
+E362:00007FFE618E6FF663C66FF6618E7FFE7FFE73866FF663866DBE73867FFE0000
+E363:00007FFE618E6FF663C66FF6618E7FFE7FFE738E6FF663C66DF6738E7FFE0000
+E364:00007FFE618E6FF663C66FF6618E7FFE7FFE73B66FB663866DF673F67FFE0000
+E365:00007FFE618E6FF663C66FF6618E7FFE7FFE73866FBE63866DF673867FFE0000
+E366:00007FFE618E6FF663C66FF6618E7FFE7FFE73CE6FBE638E6DB673CE7FFE0000
+E367:00007FFE618E6FF663C66FF6618E7FFE7FFE73866FF663EE6DDE73DE7FFE0000
+E368:00007FFE618E6FF663C66FF6618E7FFE7FFE73CE6FB663CE6DB673CE7FFE0000
+E369:00007FFE618E6FF663C66FF6618E7FFE7FFE73CE6FB663C66DF673CE7FFE0000
+E36A:00007FFE618E6FF663C66FF6618E7FFE7FFE73866FB663866DB673B67FFE0000
+E36B:00007FFE618E6FF663C66FF6618E7FFE7FFE738E6FB6638E6DB6738E7FFE0000
+E36C:00007FFE618E6FF663C66FF6618E7FFE7FFE73C66FBE63BE6DBE73C67FFE0000
+E36D:00007FFE618E6FF663C66FF6618E7FFE7FFE738E6FB663B66DB6738E7FFE0000
+E36E:00007FFE618E6FF663C66FF6618E7FFE7FFE73866FBE638E6DBE73867FFE0000
+E36F:00007FFE618E6FF663C66FF6618E7FFE7FFE73866FBE638E6DBE73BE7FFE0000
+E370:00007FFE618E6FF663C66FF6618E7FFE7FFE61CE7DB67BB677B677CE7FFE0000
+E371:00007FFE618E6FF663C66FF6618E7FFE7FFE61EE7DCE7BEE77EE77C67FFE0000
+E372:00007FFE618E6FF663C66FF6618E7FFE7FFE61867DF67B8677BE77867FFE0000
+E373:00007FFE618E6FF663C66FF6618E7FFE7FFE618E7DF67BC677F6778E7FFE0000
+E374:00007FFE618E6FF663C66FF6618E7FFE7FFE61B67DB67B8677F677F67FFE0000
+E375:00007FFE618E6FF663C66FF6618E7FFE7FFE61867DBE7B8677F677867FFE0000
+E376:00007FFE618E6FF663C66FF6618E7FFE7FFE61CE7DBE7B8E77B677CE7FFE0000
+E377:00007FFE618E6FF663C66FF6618E7FFE7FFE61867DF67BEE77DE77DE7FFE0000
+E378:00007FFE618E6FF663C66FF6618E7FFE7FFE61CE7DB67BCE77B677CE7FFE0000
+E379:00007FFE618E6FF663C66FF6618E7FFE7FFE61CE7DB67BC677F677CE7FFE0000
+E37A:00007FFE618E6FF663C66FF6618E7FFE7FFE61867DB67B8677B677B67FFE0000
+E37B:00007FFE618E6FF663C66FF6618E7FFE7FFE618E7DB67B8E77B6778E7FFE0000
+E37C:00007FFE618E6FF663C66FF6618E7FFE7FFE61C67DBE7BBE77BE77C67FFE0000
+E37D:00007FFE618E6FF663C66FF6618E7FFE7FFE618E7DB67BB677B6778E7FFE0000
+E37E:00007FFE618E6FF663C66FF6618E7FFE7FFE61867DBE7B8E77BE77867FFE0000
+E37F:00007FFE618E6FF663C66FF6618E7FFE7FFE61867DBE7B8E77BE77BE7FFE0000
+E380:00007FFE618E6FF663C66FF6618E7FFE7FFE73CE6DB673B66DB673CE7FFE0000
+E381:00007FFE618E6FF663C66FF6618E7FFE7FFE73EE6DCE73EE6DEE73C67FFE0000
+E382:00007FFE618E6FF663C66FF6618E7FFE7FFE73866DF673866DBE73867FFE0000
+E383:00007FFE618E6FF663C66FF6618E7FFE7FFE738E6DF673C66DF6738E7FFE0000
+E384:00007FFE618E6FF663C66FF6618E7FFE7FFE73B66DB673866DF673F67FFE0000
+E385:00007FFE618E6FF663C66FF6618E7FFE7FFE73866DBE73866DF673867FFE0000
+E386:00007FFE618E6FF663C66FF6618E7FFE7FFE73CE6DBE738E6DB673CE7FFE0000
+E387:00007FFE618E6FF663C66FF6618E7FFE7FFE73866DF673EE6DDE73DE7FFE0000
+E388:00007FFE618E6FF663C66FF6618E7FFE7FFE73CE6DB673CE6DB673CE7FFE0000
+E389:00007FFE618E6FF663C66FF6618E7FFE7FFE73CE6DB673C66DF673CE7FFE0000
+E38A:00007FFE618E6FF663C66FF6618E7FFE7FFE73866DB673866DB673B67FFE0000
+E38B:00007FFE618E6FF663C66FF6618E7FFE7FFE738E6DB6738E6DB6738E7FFE0000
+E38C:00007FFE618E6FF663C66FF6618E7FFE7FFE73C66DBE73BE6DBE73C67FFE0000
+E38D:00007FFE618E6FF663C66FF6618E7FFE7FFE738E6DB673B66DB6738E7FFE0000
+E38E:00007FFE618E6FF663C66FF6618E7FFE7FFE73866DBE738E6DBE73867FFE0000
+E38F:00007FFE618E6FF663C66FF6618E7FFE7FFE73866DBE738E6DBE73BE7FFE0000
+E390:00007FFE618E6FF663C66FF6618E7FFE7FFE73CE6DB671B67DB673CE7FFE0000
+E391:00007FFE618E6FF663C66FF6618E7FFE7FFE73EE6DCE71EE7DEE73C67FFE0000
+E392:00007FFE618E6FF663C66FF6618E7FFE7FFE73866DF671867DBE73867FFE0000
+E393:00007FFE618E6FF663C66FF6618E7FFE7FFE738E6DF671C67DF6738E7FFE0000
+E394:00007FFE618E6FF663C66FF6618E7FFE7FFE73B66DB671867DF673F67FFE0000
+E395:00007FFE618E6FF663C66FF6618E7FFE7FFE73866DBE71867DF673867FFE0000
+E396:00007FFE618E6FF663C66FF6618E7FFE7FFE73CE6DBE718E7DB673CE7FFE0000
+E397:00007FFE618E6FF663C66FF6618E7FFE7FFE73866DF671EE7DDE73DE7FFE0000
+E398:00007FFE618E6FF663C66FF6618E7FFE7FFE73CE6DB671CE7DB673CE7FFE0000
+E399:00007FFE618E6FF663C66FF6618E7FFE7FFE73CE6DB671C67DF673CE7FFE0000
+E39A:00007FFE618E6FF663C66FF6618E7FFE7FFE73866DB671867DB673B67FFE0000
+E39B:00007FFE618E6FF663C66FF6618E7FFE7FFE738E6DB6718E7DB6738E7FFE0000
+E39C:00007FFE618E6FF663C66FF6618E7FFE7FFE73C66DBE71BE7DBE73C67FFE0000
+E39D:00007FFE618E6FF663C66FF6618E7FFE7FFE738E6DB671B67DB6738E7FFE0000
+E39E:00007FFE618E6FF663C66FF6618E7FFE7FFE73866DBE718E7DBE73867FFE0000
+E39F:00007FFE618E6FF663C66FF6618E7FFE7FFE73866DBE718E7DBE73BE7FFE0000
+E3A0:00007FFE618E6FF663C66FF6618E7FFE7FFE61CE6DB661B66DB66DCE7FFE0000
+E3A1:00007FFE618E6FF663C66FF6618E7FFE7FFE61EE6DCE61EE6DEE6DC67FFE0000
+E3A2:00007FFE618E6FF663C66FF6618E7FFE7FFE61866DF661866DBE6D867FFE0000
+E3A3:00007FFE618E6FF663C66FF6618E7FFE7FFE618E6DF661C66DF66D8E7FFE0000
+E3A4:00007FFE618E6FF663C66FF6618E7FFE7FFE61B66DB661866DF66DF67FFE0000
+E3A5:00007FFE618E6FF663C66FF6618E7FFE7FFE61866DBE61866DF66D867FFE0000
+E3A6:00007FFE618E6FF663C66FF6618E7FFE7FFE61CE6DBE618E6DB66DCE7FFE0000
+E3A7:00007FFE618E6FF663C66FF6618E7FFE7FFE61866DF661EE6DDE6DDE7FFE0000
+E3A8:00007FFE618E6FF663C66FF6618E7FFE7FFE61CE6DB661CE6DB66DCE7FFE0000
+E3A9:00007FFE618E6FF663C66FF6618E7FFE7FFE61CE6DB661C66DF66DCE7FFE0000
+E3AA:00007FFE618E6FF663C66FF6618E7FFE7FFE61866DB661866DB66DB67FFE0000
+E3AB:00007FFE618E6FF663C66FF6618E7FFE7FFE618E6DB6618E6DB66D8E7FFE0000
+E3AC:00007FFE618E6FF663C66FF6618E7FFE7FFE61C66DBE61BE6DBE6DC67FFE0000
+E3AD:00007FFE618E6FF663C66FF6618E7FFE7FFE618E6DB661B66DB66D8E7FFE0000
+E3AE:00007FFE618E6FF663C66FF6618E7FFE7FFE61866DBE618E6DBE6D867FFE0000
+E3AF:00007FFE618E6FF663C66FF6618E7FFE7FFE61866DBE618E6DBE6DBE7FFE0000
+E3B0:00007FFE618E6FF663C66FF6618E7FFE7FFE63CE6DB663B66DB663CE7FFE0000
+E3B1:00007FFE618E6FF663C66FF6618E7FFE7FFE63EE6DCE63EE6DEE63C67FFE0000
+E3B2:00007FFE618E6FF663C66FF6618E7FFE7FFE63866DF663866DBE63867FFE0000
+E3B3:00007FFE618E6FF663C66FF6618E7FFE7FFE638E6DF663C66DF6638E7FFE0000
+E3B4:00007FFE618E6FF663C66FF6618E7FFE7FFE63B66DB663866DF663F67FFE0000
+E3B5:00007FFE618E6FF663C66FF6618E7FFE7FFE63866DBE63866DF663867FFE0000
+E3B6:00007FFE618E6FF663C66FF6618E7FFE7FFE63CE6DBE638E6DB663CE7FFE0000
+E3B7:00007FFE618E6FF663C66FF6618E7FFE7FFE63866DF663EE6DDE63DE7FFE0000
+E3B8:00007FFE618E6FF663C66FF6618E7FFE7FFE63CE6DB663CE6DB663CE7FFE0000
+E3B9:00007FFE618E6FF663C66FF6618E7FFE7FFE63CE6DB663C66DF663CE7FFE0000
+E3BA:00007FFE618E6FF663C66FF6618E7FFE7FFE63866DB663866DB663B67FFE0000
+E3BB:00007FFE618E6FF663C66FF6618E7FFE7FFE638E6DB6638E6DB6638E7FFE0000
+E3BC:00007FFE618E6FF663C66FF6618E7FFE7FFE63C66DBE63BE6DBE63C67FFE0000
+E3BD:00007FFE618E6FF663C66FF6618E7FFE7FFE638E6DB663B66DB6638E7FFE0000
+E3BE:00007FFE618E6FF663C66FF6618E7FFE7FFE63866DBE638E6DBE63867FFE0000
+E3BF:00007FFE618E6FF663C66FF6618E7FFE7FFE63866DBE638E6DBE63BE7FFE0000
+E3C0:00007FFE618E6FF663C66FF6618E7FFE7FFE71CE6FB66FB66FB671CE7FFE0000
+E3C1:00007FFE618E6FF663C66FF6618E7FFE7FFE71EE6FCE6FEE6FEE71C67FFE0000
+E3C2:00007FFE618E6FF663C66FF6618E7FFE7FFE71866FF66F866FBE71867FFE0000
+E3C3:00007FFE618E6FF663C66FF6618E7FFE7FFE718E6FF66FC66FF6718E7FFE0000
+E3C4:00007FFE618E6FF663C66FF6618E7FFE7FFE71B66FB66F866FF671F67FFE0000
+E3C5:00007FFE618E6FF663C66FF6618E7FFE7FFE71866FBE6F866FF671867FFE0000
+E3C6:00007FFE618E6FF663C66FF6618E7FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000
+E3C7:00007FFE618E6FF663C66FF6618E7FFE7FFE71866FF66FEE6FDE71DE7FFE0000
+E3C8:00007FFE618E6FF663C66FF6618E7FFE7FFE71CE6FB66FCE6FB671CE7FFE0000
+E3C9:00007FFE618E6FF663C66FF6618E7FFE7FFE71CE6FB66FC66FF671CE7FFE0000
+E3CA:00007FFE618E6FF663C66FF6618E7FFE7FFE71866FB66F866FB671B67FFE0000
+E3CB:00007FFE618E6FF663C66FF6618E7FFE7FFE718E6FB66F8E6FB6718E7FFE0000
+E3CC:00007FFE618E6FF663C66FF6618E7FFE7FFE71C66FBE6FBE6FBE71C67FFE0000
+E3CD:00007FFE618E6FF663C66FF6618E7FFE7FFE718E6FB66FB66FB6718E7FFE0000
+E3CE:00007FFE618E6FF663C66FF6618E7FFE7FFE71866FBE6F8E6FBE71867FFE0000
+E3CF:00007FFE618E6FF663C66FF6618E7FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+E3D0:00007FFE618E6FF663C66FF6618E7FFE7FFE63CE6DB66DB66DB663CE7FFE0000
+E3D1:00007FFE618E6FF663C66FF6618E7FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000
+E3D2:00007FFE618E6FF663C66FF6618E7FFE7FFE63866DF66D866DBE63867FFE0000
+E3D3:00007FFE618E6FF663C66FF6618E7FFE7FFE638E6DF66DC66DF6638E7FFE0000
+E3D4:00007FFE618E6FF663C66FF6618E7FFE7FFE63B66DB66D866DF663F67FFE0000
+E3D5:00007FFE618E6FF663C66FF6618E7FFE7FFE63866DBE6D866DF663867FFE0000
+E3D6:00007FFE618E6FF663C66FF6618E7FFE7FFE63CE6DBE6D8E6DB663CE7FFE0000
+E3D7:00007FFE618E6FF663C66FF6618E7FFE7FFE63866DF66DEE6DDE63DE7FFE0000
+E3D8:00007FFE618E6FF663C66FF6618E7FFE7FFE63CE6DB66DCE6DB663CE7FFE0000
+E3D9:00007FFE618E6FF663C66FF6618E7FFE7FFE63CE6DB66DC66DF663CE7FFE0000
+E3DA:00007FFE618E6FF663C66FF6618E7FFE7FFE63866DB66D866DB663B67FFE0000
+E3DB:00007FFE618E6FF663C66FF6618E7FFE7FFE638E6DB66D8E6DB6638E7FFE0000
+E3DC:00007FFE618E6FF663C66FF6618E7FFE7FFE63C66DBE6DBE6DBE63C67FFE0000
+E3DD:00007FFE618E6FF663C66FF6618E7FFE7FFE638E6DB66DB66DB6638E7FFE0000
+E3DE:00007FFE618E6FF663C66FF6618E7FFE7FFE63866DBE6D8E6DBE63867FFE0000
+E3DF:00007FFE618E6FF663C66FF6618E7FFE7FFE63866DBE6D8E6DBE63BE7FFE0000
+E3E0:00007FFE618E6FF663C66FF6618E7FFE7FFE61CE6FB663B66FB661CE7FFE0000
+E3E1:00007FFE618E6FF663C66FF6618E7FFE7FFE61EE6FCE63EE6FEE61C67FFE0000
+E3E2:00007FFE618E6FF663C66FF6618E7FFE7FFE61866FF663866FBE61867FFE0000
+E3E3:00007FFE618E6FF663C66FF6618E7FFE7FFE618E6FF663C66FF6618E7FFE0000
+E3E4:00007FFE618E6FF663C66FF6618E7FFE7FFE61B66FB663866FF661F67FFE0000
+E3E5:00007FFE618E6FF663C66FF6618E7FFE7FFE61866FBE63866FF661867FFE0000
+E3E6:00007FFE618E6FF663C66FF6618E7FFE7FFE61CE6FBE638E6FB661CE7FFE0000
+E3E7:00007FFE618E6FF663C66FF6618E7FFE7FFE61866FF663EE6FDE61DE7FFE0000
+E3E8:00007FFE618E6FF663C66FF6618E7FFE7FFE61CE6FB663CE6FB661CE7FFE0000
+E3E9:00007FFE618E6FF663C66FF6618E7FFE7FFE61CE6FB663C66FF661CE7FFE0000
+E3EA:00007FFE618E6FF663C66FF6618E7FFE7FFE61866FB663866FB661B67FFE0000
+E3EB:00007FFE618E6FF663C66FF6618E7FFE7FFE618E6FB6638E6FB6618E7FFE0000
+E3EC:00007FFE618E6FF663C66FF6618E7FFE7FFE61C66FBE63BE6FBE61C67FFE0000
+E3ED:00007FFE618E6FF663C66FF6618E7FFE7FFE618E6FB663B66FB6618E7FFE0000
+E3EE:00007FFE618E6FF663C66FF6618E7FFE7FFE61866FBE638E6FBE61867FFE0000
+E3EF:00007FFE618E6FF663C66FF6618E7FFE7FFE61866FBE638E6FBE61BE7FFE0000
+E3F0:00007FFE618E6FF663C66FF6618E7FFE7FFE61CE6FB663B66FB66FCE7FFE0000
+E3F1:00007FFE618E6FF663C66FF6618E7FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000
+E3F2:00007FFE618E6FF663C66FF6618E7FFE7FFE61866FF663866FBE6F867FFE0000
+E3F3:00007FFE618E6FF663C66FF6618E7FFE7FFE618E6FF663C66FF66F8E7FFE0000
+E3F4:00007FFE618E6FF663C66FF6618E7FFE7FFE61B66FB663866FF66FF67FFE0000
+E3F5:00007FFE618E6FF663C66FF6618E7FFE7FFE61866FBE63866FF66F867FFE0000
+E3F6:00007FFE618E6FF663C66FF6618E7FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+E3F7:00007FFE618E6FF663C66FF6618E7FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+E3F8:00007FFE618E6FF663C66FF6618E7FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+E3F9:00007FFE618E6FF663C66FF6618E7FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+E3FA:00007FFE618E6FF663C66FF6618E7FFE7FFE61866FB663866FB66FB67FFE0000
+E3FB:00007FFE618E6FF663C66FF6618E7FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+E3FC:00007FFE618E6FF663C66FF6618E7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+E3FD:00007FFE618E6FF663C66FF6618E7FFE7FFE618E6FB663B66FB66F8E7FFE0000
+E3FE:00007FFE618E6FF663C66FF6618E7FFE7FFE61866FBE638E6FBE6F867FFE0000
+E3FF:00007FFE618E6FF663C66FF6618E7FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+E400:00007FFE61B66FB663866FF661F67FFE7FFE73CE6DB66DB66DB673CE7FFE0000
+E401:00007FFE61B66FB663866FF661F67FFE7FFE73EE6DCE6DEE6DEE73C67FFE0000
+E402:00007FFE61B66FB663866FF661F67FFE7FFE73866DF66D866DBE73867FFE0000
+E403:00007FFE61B66FB663866FF661F67FFE7FFE738E6DF66DC66DF6738E7FFE0000
+E404:00007FFE61B66FB663866FF661F67FFE7FFE73B66DB66D866DF673F67FFE0000
+E405:00007FFE61B66FB663866FF661F67FFE7FFE73866DBE6D866DF673867FFE0000
+E406:00007FFE61B66FB663866FF661F67FFE7FFE73CE6DBE6D8E6DB673CE7FFE0000
+E407:00007FFE61B66FB663866FF661F67FFE7FFE73866DF66DEE6DDE73DE7FFE0000
+E408:00007FFE61B66FB663866FF661F67FFE7FFE73CE6DB66DCE6DB673CE7FFE0000
+E409:00007FFE61B66FB663866FF661F67FFE7FFE73CE6DB66DC66DF673CE7FFE0000
+E40A:00007FFE61B66FB663866FF661F67FFE7FFE73866DB66D866DB673B67FFE0000
+E40B:00007FFE61B66FB663866FF661F67FFE7FFE738E6DB66D8E6DB6738E7FFE0000
+E40C:00007FFE61B66FB663866FF661F67FFE7FFE73C66DBE6DBE6DBE73C67FFE0000
+E40D:00007FFE61B66FB663866FF661F67FFE7FFE738E6DB66DB66DB6738E7FFE0000
+E40E:00007FFE61B66FB663866FF661F67FFE7FFE73866DBE6D8E6DBE73867FFE0000
+E40F:00007FFE61B66FB663866FF661F67FFE7FFE73866DBE6D8E6DBE73BE7FFE0000
+E410:00007FFE61B66FB663866FF661F67FFE7FFE7BCE73B67BB67BB671CE7FFE0000
+E411:00007FFE61B66FB663866FF661F67FFE7FFE7BEE73CE7BEE7BEE71C67FFE0000
+E412:00007FFE61B66FB663866FF661F67FFE7FFE7B8673F67B867BBE71867FFE0000
+E413:00007FFE61B66FB663866FF661F67FFE7FFE7B8E73F67BC67BF6718E7FFE0000
+E414:00007FFE61B66FB663866FF661F67FFE7FFE7BB673B67B867BF671F67FFE0000
+E415:00007FFE61B66FB663866FF661F67FFE7FFE7B8673BE7B867BF671867FFE0000
+E416:00007FFE61B66FB663866FF661F67FFE7FFE7BCE73BE7B8E7BB671CE7FFE0000
+E417:00007FFE61B66FB663866FF661F67FFE7FFE7B8673F67BEE7BDE71DE7FFE0000
+E418:00007FFE61B66FB663866FF661F67FFE7FFE7BCE73B67BCE7BB671CE7FFE0000
+E419:00007FFE61B66FB663866FF661F67FFE7FFE7BCE73B67BC67BF671CE7FFE0000
+E41A:00007FFE61B66FB663866FF661F67FFE7FFE7B8673B67B867BB671B67FFE0000
+E41B:00007FFE61B66FB663866FF661F67FFE7FFE7B8E73B67B8E7BB6718E7FFE0000
+E41C:00007FFE61B66FB663866FF661F67FFE7FFE7BC673BE7BBE7BBE71C67FFE0000
+E41D:00007FFE61B66FB663866FF661F67FFE7FFE7B8E73B67BB67BB6718E7FFE0000
+E41E:00007FFE61B66FB663866FF661F67FFE7FFE7B8673BE7B8E7BBE71867FFE0000
+E41F:00007FFE61B66FB663866FF661F67FFE7FFE7B8673BE7B8E7BBE71BE7FFE0000
+E420:00007FFE61B66FB663866FF661F67FFE7FFE61CE7DB661B66FB661CE7FFE0000
+E421:00007FFE61B66FB663866FF661F67FFE7FFE61EE7DCE61EE6FEE61C67FFE0000
+E422:00007FFE61B66FB663866FF661F67FFE7FFE61867DF661866FBE61867FFE0000
+E423:00007FFE61B66FB663866FF661F67FFE7FFE618E7DF661C66FF6618E7FFE0000
+E424:00007FFE61B66FB663866FF661F67FFE7FFE61B67DB661866FF661F67FFE0000
+E425:00007FFE61B66FB663866FF661F67FFE7FFE61867DBE61866FF661867FFE0000
+E426:00007FFE61B66FB663866FF661F67FFE7FFE61CE7DBE618E6FB661CE7FFE0000
+E427:00007FFE61B66FB663866FF661F67FFE7FFE61867DF661EE6FDE61DE7FFE0000
+E428:00007FFE61B66FB663866FF661F67FFE7FFE61CE7DB661CE6FB661CE7FFE0000
+E429:00007FFE61B66FB663866FF661F67FFE7FFE61CE7DB661C66FF661CE7FFE0000
+E42A:00007FFE61B66FB663866FF661F67FFE7FFE61867DB661866FB661B67FFE0000
+E42B:00007FFE61B66FB663866FF661F67FFE7FFE618E7DB6618E6FB6618E7FFE0000
+E42C:00007FFE61B66FB663866FF661F67FFE7FFE61C67DBE61BE6FBE61C67FFE0000
+E42D:00007FFE61B66FB663866FF661F67FFE7FFE618E7DB661B66FB6618E7FFE0000
+E42E:00007FFE61B66FB663866FF661F67FFE7FFE61867DBE618E6FBE61867FFE0000
+E42F:00007FFE61B66FB663866FF661F67FFE7FFE61867DBE618E6FBE61BE7FFE0000
+E430:00007FFE61B66FB663866FF661F67FFE7FFE63CE7DB671B67DB663CE7FFE0000
+E431:00007FFE61B66FB663866FF661F67FFE7FFE63EE7DCE71EE7DEE63C67FFE0000
+E432:00007FFE61B66FB663866FF661F67FFE7FFE63867DF671867DBE63867FFE0000
+E433:00007FFE61B66FB663866FF661F67FFE7FFE638E7DF671C67DF6638E7FFE0000
+E434:00007FFE61B66FB663866FF661F67FFE7FFE63B67DB671867DF663F67FFE0000
+E435:00007FFE61B66FB663866FF661F67FFE7FFE63867DBE71867DF663867FFE0000
+E436:00007FFE61B66FB663866FF661F67FFE7FFE63CE7DBE718E7DB663CE7FFE0000
+E437:00007FFE61B66FB663866FF661F67FFE7FFE63867DF671EE7DDE63DE7FFE0000
+E438:00007FFE61B66FB663866FF661F67FFE7FFE63CE7DB671CE7DB663CE7FFE0000
+E439:00007FFE61B66FB663866FF661F67FFE7FFE63CE7DB671C67DF663CE7FFE0000
+E43A:00007FFE61B66FB663866FF661F67FFE7FFE63867DB671867DB663B67FFE0000
+E43B:00007FFE61B66FB663866FF661F67FFE7FFE638E7DB6718E7DB6638E7FFE0000
+E43C:00007FFE61B66FB663866FF661F67FFE7FFE63C67DBE71BE7DBE63C67FFE0000
+E43D:00007FFE61B66FB663866FF661F67FFE7FFE638E7DB671B67DB6638E7FFE0000
+E43E:00007FFE61B66FB663866FF661F67FFE7FFE63867DBE718E7DBE63867FFE0000
+E43F:00007FFE61B66FB663866FF661F67FFE7FFE63867DBE718E7DBE63BE7FFE0000
+E440:00007FFE61B66FB663866FF661F67FFE7FFE6DCE6DB661B67DB67DCE7FFE0000
+E441:00007FFE61B66FB663866FF661F67FFE7FFE6DEE6DCE61EE7DEE7DC67FFE0000
+E442:00007FFE61B66FB663866FF661F67FFE7FFE6D866DF661867DBE7D867FFE0000
+E443:00007FFE61B66FB663866FF661F67FFE7FFE6D8E6DF661C67DF67D8E7FFE0000
+E444:00007FFE61B66FB663866FF661F67FFE7FFE6DB66DB661867DF67DF67FFE0000
+E445:00007FFE61B66FB663866FF661F67FFE7FFE6D866DBE61867DF67D867FFE0000
+E446:00007FFE61B66FB663866FF661F67FFE7FFE6DCE6DBE618E7DB67DCE7FFE0000
+E447:00007FFE61B66FB663866FF661F67FFE7FFE6D866DF661EE7DDE7DDE7FFE0000
+E448:00007FFE61B66FB663866FF661F67FFE7FFE6DCE6DB661CE7DB67DCE7FFE0000
+E449:00007FFE61B66FB663866FF661F67FFE7FFE6DCE6DB661C67DF67DCE7FFE0000
+E44A:00007FFE61B66FB663866FF661F67FFE7FFE6D866DB661867DB67DB67FFE0000
+E44B:00007FFE61B66FB663866FF661F67FFE7FFE6D8E6DB6618E7DB67D8E7FFE0000
+E44C:00007FFE61B66FB663866FF661F67FFE7FFE6DC66DBE61BE7DBE7DC67FFE0000
+E44D:00007FFE61B66FB663866FF661F67FFE7FFE6D8E6DB661B67DB67D8E7FFE0000
+E44E:00007FFE61B66FB663866FF661F67FFE7FFE6D866DBE618E7DBE7D867FFE0000
+E44F:00007FFE61B66FB663866FF661F67FFE7FFE6D866DBE618E7DBE7DBE7FFE0000
+E450:00007FFE61B66FB663866FF661F67FFE7FFE61CE6FB661B67DB661CE7FFE0000
+E451:00007FFE61B66FB663866FF661F67FFE7FFE61EE6FCE61EE7DEE61C67FFE0000
+E452:00007FFE61B66FB663866FF661F67FFE7FFE61866FF661867DBE61867FFE0000
+E453:00007FFE61B66FB663866FF661F67FFE7FFE618E6FF661C67DF6618E7FFE0000
+E454:00007FFE61B66FB663866FF661F67FFE7FFE61B66FB661867DF661F67FFE0000
+E455:00007FFE61B66FB663866FF661F67FFE7FFE61866FBE61867DF661867FFE0000
+E456:00007FFE61B66FB663866FF661F67FFE7FFE61CE6FBE618E7DB661CE7FFE0000
+E457:00007FFE61B66FB663866FF661F67FFE7FFE61866FF661EE7DDE61DE7FFE0000
+E458:00007FFE61B66FB663866FF661F67FFE7FFE61CE6FB661CE7DB661CE7FFE0000
+E459:00007FFE61B66FB663866FF661F67FFE7FFE61CE6FB661C67DF661CE7FFE0000
+E45A:00007FFE61B66FB663866FF661F67FFE7FFE61866FB661867DB661B67FFE0000
+E45B:00007FFE61B66FB663866FF661F67FFE7FFE618E6FB6618E7DB6618E7FFE0000
+E45C:00007FFE61B66FB663866FF661F67FFE7FFE61C66FBE61BE7DBE61C67FFE0000
+E45D:00007FFE61B66FB663866FF661F67FFE7FFE618E6FB661B67DB6618E7FFE0000
+E45E:00007FFE61B66FB663866FF661F67FFE7FFE61866FBE618E7DBE61867FFE0000
+E45F:00007FFE61B66FB663866FF661F67FFE7FFE61866FBE618E7DBE61BE7FFE0000
+E460:00007FFE61B66FB663866FF661F67FFE7FFE73CE6FB663B66DB673CE7FFE0000
+E461:00007FFE61B66FB663866FF661F67FFE7FFE73EE6FCE63EE6DEE73C67FFE0000
+E462:00007FFE61B66FB663866FF661F67FFE7FFE73866FF663866DBE73867FFE0000
+E463:00007FFE61B66FB663866FF661F67FFE7FFE738E6FF663C66DF6738E7FFE0000
+E464:00007FFE61B66FB663866FF661F67FFE7FFE73B66FB663866DF673F67FFE0000
+E465:00007FFE61B66FB663866FF661F67FFE7FFE73866FBE63866DF673867FFE0000
+E466:00007FFE61B66FB663866FF661F67FFE7FFE73CE6FBE638E6DB673CE7FFE0000
+E467:00007FFE61B66FB663866FF661F67FFE7FFE73866FF663EE6DDE73DE7FFE0000
+E468:00007FFE61B66FB663866FF661F67FFE7FFE73CE6FB663CE6DB673CE7FFE0000
+E469:00007FFE61B66FB663866FF661F67FFE7FFE73CE6FB663C66DF673CE7FFE0000
+E46A:00007FFE61B66FB663866FF661F67FFE7FFE73866FB663866DB673B67FFE0000
+E46B:00007FFE61B66FB663866FF661F67FFE7FFE738E6FB6638E6DB6738E7FFE0000
+E46C:00007FFE61B66FB663866FF661F67FFE7FFE73C66FBE63BE6DBE73C67FFE0000
+E46D:00007FFE61B66FB663866FF661F67FFE7FFE738E6FB663B66DB6738E7FFE0000
+E46E:00007FFE61B66FB663866FF661F67FFE7FFE73866FBE638E6DBE73867FFE0000
+E46F:00007FFE61B66FB663866FF661F67FFE7FFE73866FBE638E6DBE73BE7FFE0000
+E470:00007FFE61B66FB663866FF661F67FFE7FFE61CE7DB67BB677B677CE7FFE0000
+E471:00007FFE61B66FB663866FF661F67FFE7FFE61EE7DCE7BEE77EE77C67FFE0000
+E472:00007FFE61B66FB663866FF661F67FFE7FFE61867DF67B8677BE77867FFE0000
+E473:00007FFE61B66FB663866FF661F67FFE7FFE618E7DF67BC677F6778E7FFE0000
+E474:00007FFE61B66FB663866FF661F67FFE7FFE61B67DB67B8677F677F67FFE0000
+E475:00007FFE61B66FB663866FF661F67FFE7FFE61867DBE7B8677F677867FFE0000
+E476:00007FFE61B66FB663866FF661F67FFE7FFE61CE7DBE7B8E77B677CE7FFE0000
+E477:00007FFE61B66FB663866FF661F67FFE7FFE61867DF67BEE77DE77DE7FFE0000
+E478:00007FFE61B66FB663866FF661F67FFE7FFE61CE7DB67BCE77B677CE7FFE0000
+E479:00007FFE61B66FB663866FF661F67FFE7FFE61CE7DB67BC677F677CE7FFE0000
+E47A:00007FFE61B66FB663866FF661F67FFE7FFE61867DB67B8677B677B67FFE0000
+E47B:00007FFE61B66FB663866FF661F67FFE7FFE618E7DB67B8E77B6778E7FFE0000
+E47C:00007FFE61B66FB663866FF661F67FFE7FFE61C67DBE7BBE77BE77C67FFE0000
+E47D:00007FFE61B66FB663866FF661F67FFE7FFE618E7DB67BB677B6778E7FFE0000
+E47E:00007FFE61B66FB663866FF661F67FFE7FFE61867DBE7B8E77BE77867FFE0000
+E47F:00007FFE61B66FB663866FF661F67FFE7FFE61867DBE7B8E77BE77BE7FFE0000
+E480:00007FFE61B66FB663866FF661F67FFE7FFE73CE6DB673B66DB673CE7FFE0000
+E481:00007FFE61B66FB663866FF661F67FFE7FFE73EE6DCE73EE6DEE73C67FFE0000
+E482:00007FFE61B66FB663866FF661F67FFE7FFE73866DF673866DBE73867FFE0000
+E483:00007FFE61B66FB663866FF661F67FFE7FFE738E6DF673C66DF6738E7FFE0000
+E484:00007FFE61B66FB663866FF661F67FFE7FFE73B66DB673866DF673F67FFE0000
+E485:00007FFE61B66FB663866FF661F67FFE7FFE73866DBE73866DF673867FFE0000
+E486:00007FFE61B66FB663866FF661F67FFE7FFE73CE6DBE738E6DB673CE7FFE0000
+E487:00007FFE61B66FB663866FF661F67FFE7FFE73866DF673EE6DDE73DE7FFE0000
+E488:00007FFE61B66FB663866FF661F67FFE7FFE73CE6DB673CE6DB673CE7FFE0000
+E489:00007FFE61B66FB663866FF661F67FFE7FFE73CE6DB673C66DF673CE7FFE0000
+E48A:00007FFE61B66FB663866FF661F67FFE7FFE73866DB673866DB673B67FFE0000
+E48B:00007FFE61B66FB663866FF661F67FFE7FFE738E6DB6738E6DB6738E7FFE0000
+E48C:00007FFE61B66FB663866FF661F67FFE7FFE73C66DBE73BE6DBE73C67FFE0000
+E48D:00007FFE61B66FB663866FF661F67FFE7FFE738E6DB673B66DB6738E7FFE0000
+E48E:00007FFE61B66FB663866FF661F67FFE7FFE73866DBE738E6DBE73867FFE0000
+E48F:00007FFE61B66FB663866FF661F67FFE7FFE73866DBE738E6DBE73BE7FFE0000
+E490:00007FFE61B66FB663866FF661F67FFE7FFE73CE6DB671B67DB673CE7FFE0000
+E491:00007FFE61B66FB663866FF661F67FFE7FFE73EE6DCE71EE7DEE73C67FFE0000
+E492:00007FFE61B66FB663866FF661F67FFE7FFE73866DF671867DBE73867FFE0000
+E493:00007FFE61B66FB663866FF661F67FFE7FFE738E6DF671C67DF6738E7FFE0000
+E494:00007FFE61B66FB663866FF661F67FFE7FFE73B66DB671867DF673F67FFE0000
+E495:00007FFE61B66FB663866FF661F67FFE7FFE73866DBE71867DF673867FFE0000
+E496:00007FFE61B66FB663866FF661F67FFE7FFE73CE6DBE718E7DB673CE7FFE0000
+E497:00007FFE61B66FB663866FF661F67FFE7FFE73866DF671EE7DDE73DE7FFE0000
+E498:00007FFE61B66FB663866FF661F67FFE7FFE73CE6DB671CE7DB673CE7FFE0000
+E499:00007FFE61B66FB663866FF661F67FFE7FFE73CE6DB671C67DF673CE7FFE0000
+E49A:00007FFE61B66FB663866FF661F67FFE7FFE73866DB671867DB673B67FFE0000
+E49B:00007FFE61B66FB663866FF661F67FFE7FFE738E6DB6718E7DB6738E7FFE0000
+E49C:00007FFE61B66FB663866FF661F67FFE7FFE73C66DBE71BE7DBE73C67FFE0000
+E49D:00007FFE61B66FB663866FF661F67FFE7FFE738E6DB671B67DB6738E7FFE0000
+E49E:00007FFE61B66FB663866FF661F67FFE7FFE73866DBE718E7DBE73867FFE0000
+E49F:00007FFE61B66FB663866FF661F67FFE7FFE73866DBE718E7DBE73BE7FFE0000
+E4A0:00007FFE61B66FB663866FF661F67FFE7FFE61CE6DB661B66DB66DCE7FFE0000
+E4A1:00007FFE61B66FB663866FF661F67FFE7FFE61EE6DCE61EE6DEE6DC67FFE0000
+E4A2:00007FFE61B66FB663866FF661F67FFE7FFE61866DF661866DBE6D867FFE0000
+E4A3:00007FFE61B66FB663866FF661F67FFE7FFE618E6DF661C66DF66D8E7FFE0000
+E4A4:00007FFE61B66FB663866FF661F67FFE7FFE61B66DB661866DF66DF67FFE0000
+E4A5:00007FFE61B66FB663866FF661F67FFE7FFE61866DBE61866DF66D867FFE0000
+E4A6:00007FFE61B66FB663866FF661F67FFE7FFE61CE6DBE618E6DB66DCE7FFE0000
+E4A7:00007FFE61B66FB663866FF661F67FFE7FFE61866DF661EE6DDE6DDE7FFE0000
+E4A8:00007FFE61B66FB663866FF661F67FFE7FFE61CE6DB661CE6DB66DCE7FFE0000
+E4A9:00007FFE61B66FB663866FF661F67FFE7FFE61CE6DB661C66DF66DCE7FFE0000
+E4AA:00007FFE61B66FB663866FF661F67FFE7FFE61866DB661866DB66DB67FFE0000
+E4AB:00007FFE61B66FB663866FF661F67FFE7FFE618E6DB6618E6DB66D8E7FFE0000
+E4AC:00007FFE61B66FB663866FF661F67FFE7FFE61C66DBE61BE6DBE6DC67FFE0000
+E4AD:00007FFE61B66FB663866FF661F67FFE7FFE618E6DB661B66DB66D8E7FFE0000
+E4AE:00007FFE61B66FB663866FF661F67FFE7FFE61866DBE618E6DBE6D867FFE0000
+E4AF:00007FFE61B66FB663866FF661F67FFE7FFE61866DBE618E6DBE6DBE7FFE0000
+E4B0:00007FFE61B66FB663866FF661F67FFE7FFE63CE6DB663B66DB663CE7FFE0000
+E4B1:00007FFE61B66FB663866FF661F67FFE7FFE63EE6DCE63EE6DEE63C67FFE0000
+E4B2:00007FFE61B66FB663866FF661F67FFE7FFE63866DF663866DBE63867FFE0000
+E4B3:00007FFE61B66FB663866FF661F67FFE7FFE638E6DF663C66DF6638E7FFE0000
+E4B4:00007FFE61B66FB663866FF661F67FFE7FFE63B66DB663866DF663F67FFE0000
+E4B5:00007FFE61B66FB663866FF661F67FFE7FFE63866DBE63866DF663867FFE0000
+E4B6:00007FFE61B66FB663866FF661F67FFE7FFE63CE6DBE638E6DB663CE7FFE0000
+E4B7:00007FFE61B66FB663866FF661F67FFE7FFE63866DF663EE6DDE63DE7FFE0000
+E4B8:00007FFE61B66FB663866FF661F67FFE7FFE63CE6DB663CE6DB663CE7FFE0000
+E4B9:00007FFE61B66FB663866FF661F67FFE7FFE63CE6DB663C66DF663CE7FFE0000
+E4BA:00007FFE61B66FB663866FF661F67FFE7FFE63866DB663866DB663B67FFE0000
+E4BB:00007FFE61B66FB663866FF661F67FFE7FFE638E6DB6638E6DB6638E7FFE0000
+E4BC:00007FFE61B66FB663866FF661F67FFE7FFE63C66DBE63BE6DBE63C67FFE0000
+E4BD:00007FFE61B66FB663866FF661F67FFE7FFE638E6DB663B66DB6638E7FFE0000
+E4BE:00007FFE61B66FB663866FF661F67FFE7FFE63866DBE638E6DBE63867FFE0000
+E4BF:00007FFE61B66FB663866FF661F67FFE7FFE63866DBE638E6DBE63BE7FFE0000
+E4C0:00007FFE61B66FB663866FF661F67FFE7FFE71CE6FB66FB66FB671CE7FFE0000
+E4C1:00007FFE61B66FB663866FF661F67FFE7FFE71EE6FCE6FEE6FEE71C67FFE0000
+E4C2:00007FFE61B66FB663866FF661F67FFE7FFE71866FF66F866FBE71867FFE0000
+E4C3:00007FFE61B66FB663866FF661F67FFE7FFE718E6FF66FC66FF6718E7FFE0000
+E4C4:00007FFE61B66FB663866FF661F67FFE7FFE71B66FB66F866FF671F67FFE0000
+E4C5:00007FFE61B66FB663866FF661F67FFE7FFE71866FBE6F866FF671867FFE0000
+E4C6:00007FFE61B66FB663866FF661F67FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000
+E4C7:00007FFE61B66FB663866FF661F67FFE7FFE71866FF66FEE6FDE71DE7FFE0000
+E4C8:00007FFE61B66FB663866FF661F67FFE7FFE71CE6FB66FCE6FB671CE7FFE0000
+E4C9:00007FFE61B66FB663866FF661F67FFE7FFE71CE6FB66FC66FF671CE7FFE0000
+E4CA:00007FFE61B66FB663866FF661F67FFE7FFE71866FB66F866FB671B67FFE0000
+E4CB:00007FFE61B66FB663866FF661F67FFE7FFE718E6FB66F8E6FB6718E7FFE0000
+E4CC:00007FFE61B66FB663866FF661F67FFE7FFE71C66FBE6FBE6FBE71C67FFE0000
+E4CD:00007FFE61B66FB663866FF661F67FFE7FFE718E6FB66FB66FB6718E7FFE0000
+E4CE:00007FFE61B66FB663866FF661F67FFE7FFE71866FBE6F8E6FBE71867FFE0000
+E4CF:00007FFE61B66FB663866FF661F67FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+E4D0:00007FFE61B66FB663866FF661F67FFE7FFE63CE6DB66DB66DB663CE7FFE0000
+E4D1:00007FFE61B66FB663866FF661F67FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000
+E4D2:00007FFE61B66FB663866FF661F67FFE7FFE63866DF66D866DBE63867FFE0000
+E4D3:00007FFE61B66FB663866FF661F67FFE7FFE638E6DF66DC66DF6638E7FFE0000
+E4D4:00007FFE61B66FB663866FF661F67FFE7FFE63B66DB66D866DF663F67FFE0000
+E4D5:00007FFE61B66FB663866FF661F67FFE7FFE63866DBE6D866DF663867FFE0000
+E4D6:00007FFE61B66FB663866FF661F67FFE7FFE63CE6DBE6D8E6DB663CE7FFE0000
+E4D7:00007FFE61B66FB663866FF661F67FFE7FFE63866DF66DEE6DDE63DE7FFE0000
+E4D8:00007FFE61B66FB663866FF661F67FFE7FFE63CE6DB66DCE6DB663CE7FFE0000
+E4D9:00007FFE61B66FB663866FF661F67FFE7FFE63CE6DB66DC66DF663CE7FFE0000
+E4DA:00007FFE61B66FB663866FF661F67FFE7FFE63866DB66D866DB663B67FFE0000
+E4DB:00007FFE61B66FB663866FF661F67FFE7FFE638E6DB66D8E6DB6638E7FFE0000
+E4DC:00007FFE61B66FB663866FF661F67FFE7FFE63C66DBE6DBE6DBE63C67FFE0000
+E4DD:00007FFE61B66FB663866FF661F67FFE7FFE638E6DB66DB66DB6638E7FFE0000
+E4DE:00007FFE61B66FB663866FF661F67FFE7FFE63866DBE6D8E6DBE63867FFE0000
+E4DF:00007FFE61B66FB663866FF661F67FFE7FFE63866DBE6D8E6DBE63BE7FFE0000
+E4E0:00007FFE61B66FB663866FF661F67FFE7FFE61CE6FB663B66FB661CE7FFE0000
+E4E1:00007FFE61B66FB663866FF661F67FFE7FFE61EE6FCE63EE6FEE61C67FFE0000
+E4E2:00007FFE61B66FB663866FF661F67FFE7FFE61866FF663866FBE61867FFE0000
+E4E3:00007FFE61B66FB663866FF661F67FFE7FFE618E6FF663C66FF6618E7FFE0000
+E4E4:00007FFE61B66FB663866FF661F67FFE7FFE61B66FB663866FF661F67FFE0000
+E4E5:00007FFE61B66FB663866FF661F67FFE7FFE61866FBE63866FF661867FFE0000
+E4E6:00007FFE61B66FB663866FF661F67FFE7FFE61CE6FBE638E6FB661CE7FFE0000
+E4E7:00007FFE61B66FB663866FF661F67FFE7FFE61866FF663EE6FDE61DE7FFE0000
+E4E8:00007FFE61B66FB663866FF661F67FFE7FFE61CE6FB663CE6FB661CE7FFE0000
+E4E9:00007FFE61B66FB663866FF661F67FFE7FFE61CE6FB663C66FF661CE7FFE0000
+E4EA:00007FFE61B66FB663866FF661F67FFE7FFE61866FB663866FB661B67FFE0000
+E4EB:00007FFE61B66FB663866FF661F67FFE7FFE618E6FB6638E6FB6618E7FFE0000
+E4EC:00007FFE61B66FB663866FF661F67FFE7FFE61C66FBE63BE6FBE61C67FFE0000
+E4ED:00007FFE61B66FB663866FF661F67FFE7FFE618E6FB663B66FB6618E7FFE0000
+E4EE:00007FFE61B66FB663866FF661F67FFE7FFE61866FBE638E6FBE61867FFE0000
+E4EF:00007FFE61B66FB663866FF661F67FFE7FFE61866FBE638E6FBE61BE7FFE0000
+E4F0:00007FFE61B66FB663866FF661F67FFE7FFE61CE6FB663B66FB66FCE7FFE0000
+E4F1:00007FFE61B66FB663866FF661F67FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000
+E4F2:00007FFE61B66FB663866FF661F67FFE7FFE61866FF663866FBE6F867FFE0000
+E4F3:00007FFE61B66FB663866FF661F67FFE7FFE618E6FF663C66FF66F8E7FFE0000
+E4F4:00007FFE61B66FB663866FF661F67FFE7FFE61B66FB663866FF66FF67FFE0000
+E4F5:00007FFE61B66FB663866FF661F67FFE7FFE61866FBE63866FF66F867FFE0000
+E4F6:00007FFE61B66FB663866FF661F67FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+E4F7:00007FFE61B66FB663866FF661F67FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+E4F8:00007FFE61B66FB663866FF661F67FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+E4F9:00007FFE61B66FB663866FF661F67FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+E4FA:00007FFE61B66FB663866FF661F67FFE7FFE61866FB663866FB66FB67FFE0000
+E4FB:00007FFE61B66FB663866FF661F67FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+E4FC:00007FFE61B66FB663866FF661F67FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+E4FD:00007FFE61B66FB663866FF661F67FFE7FFE618E6FB663B66FB66F8E7FFE0000
+E4FE:00007FFE61B66FB663866FF661F67FFE7FFE61866FBE638E6FBE6F867FFE0000
+E4FF:00007FFE61B66FB663866FF661F67FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+E500:00007FFE61866FBE63866FF661867FFE7FFE73CE6DB66DB66DB673CE7FFE0000
+E501:00007FFE61866FBE63866FF661867FFE7FFE73EE6DCE6DEE6DEE73C67FFE0000
+E502:00007FFE61866FBE63866FF661867FFE7FFE73866DF66D866DBE73867FFE0000
+E503:00007FFE61866FBE63866FF661867FFE7FFE738E6DF66DC66DF6738E7FFE0000
+E504:00007FFE61866FBE63866FF661867FFE7FFE73B66DB66D866DF673F67FFE0000
+E505:00007FFE61866FBE63866FF661867FFE7FFE73866DBE6D866DF673867FFE0000
+E506:00007FFE61866FBE63866FF661867FFE7FFE73CE6DBE6D8E6DB673CE7FFE0000
+E507:00007FFE61866FBE63866FF661867FFE7FFE73866DF66DEE6DDE73DE7FFE0000
+E508:00007FFE61866FBE63866FF661867FFE7FFE73CE6DB66DCE6DB673CE7FFE0000
+E509:00007FFE61866FBE63866FF661867FFE7FFE73CE6DB66DC66DF673CE7FFE0000
+E50A:00007FFE61866FBE63866FF661867FFE7FFE73866DB66D866DB673B67FFE0000
+E50B:00007FFE61866FBE63866FF661867FFE7FFE738E6DB66D8E6DB6738E7FFE0000
+E50C:00007FFE61866FBE63866FF661867FFE7FFE73C66DBE6DBE6DBE73C67FFE0000
+E50D:00007FFE61866FBE63866FF661867FFE7FFE738E6DB66DB66DB6738E7FFE0000
+E50E:00007FFE61866FBE63866FF661867FFE7FFE73866DBE6D8E6DBE73867FFE0000
+E50F:00007FFE61866FBE63866FF661867FFE7FFE73866DBE6D8E6DBE73BE7FFE0000
+E510:00007FFE61866FBE63866FF661867FFE7FFE7BCE73B67BB67BB671CE7FFE0000
+E511:00007FFE61866FBE63866FF661867FFE7FFE7BEE73CE7BEE7BEE71C67FFE0000
+E512:00007FFE61866FBE63866FF661867FFE7FFE7B8673F67B867BBE71867FFE0000
+E513:00007FFE61866FBE63866FF661867FFE7FFE7B8E73F67BC67BF6718E7FFE0000
+E514:00007FFE61866FBE63866FF661867FFE7FFE7BB673B67B867BF671F67FFE0000
+E515:00007FFE61866FBE63866FF661867FFE7FFE7B8673BE7B867BF671867FFE0000
+E516:00007FFE61866FBE63866FF661867FFE7FFE7BCE73BE7B8E7BB671CE7FFE0000
+E517:00007FFE61866FBE63866FF661867FFE7FFE7B8673F67BEE7BDE71DE7FFE0000
+E518:00007FFE61866FBE63866FF661867FFE7FFE7BCE73B67BCE7BB671CE7FFE0000
+E519:00007FFE61866FBE63866FF661867FFE7FFE7BCE73B67BC67BF671CE7FFE0000
+E51A:00007FFE61866FBE63866FF661867FFE7FFE7B8673B67B867BB671B67FFE0000
+E51B:00007FFE61866FBE63866FF661867FFE7FFE7B8E73B67B8E7BB6718E7FFE0000
+E51C:00007FFE61866FBE63866FF661867FFE7FFE7BC673BE7BBE7BBE71C67FFE0000
+E51D:00007FFE61866FBE63866FF661867FFE7FFE7B8E73B67BB67BB6718E7FFE0000
+E51E:00007FFE61866FBE63866FF661867FFE7FFE7B8673BE7B8E7BBE71867FFE0000
+E51F:00007FFE61866FBE63866FF661867FFE7FFE7B8673BE7B8E7BBE71BE7FFE0000
+E520:00007FFE61866FBE63866FF661867FFE7FFE61CE7DB661B66FB661CE7FFE0000
+E521:00007FFE61866FBE63866FF661867FFE7FFE61EE7DCE61EE6FEE61C67FFE0000
+E522:00007FFE61866FBE63866FF661867FFE7FFE61867DF661866FBE61867FFE0000
+E523:00007FFE61866FBE63866FF661867FFE7FFE618E7DF661C66FF6618E7FFE0000
+E524:00007FFE61866FBE63866FF661867FFE7FFE61B67DB661866FF661F67FFE0000
+E525:00007FFE61866FBE63866FF661867FFE7FFE61867DBE61866FF661867FFE0000
+E526:00007FFE61866FBE63866FF661867FFE7FFE61CE7DBE618E6FB661CE7FFE0000
+E527:00007FFE61866FBE63866FF661867FFE7FFE61867DF661EE6FDE61DE7FFE0000
+E528:00007FFE61866FBE63866FF661867FFE7FFE61CE7DB661CE6FB661CE7FFE0000
+E529:00007FFE61866FBE63866FF661867FFE7FFE61CE7DB661C66FF661CE7FFE0000
+E52A:00007FFE61866FBE63866FF661867FFE7FFE61867DB661866FB661B67FFE0000
+E52B:00007FFE61866FBE63866FF661867FFE7FFE618E7DB6618E6FB6618E7FFE0000
+E52C:00007FFE61866FBE63866FF661867FFE7FFE61C67DBE61BE6FBE61C67FFE0000
+E52D:00007FFE61866FBE63866FF661867FFE7FFE618E7DB661B66FB6618E7FFE0000
+E52E:00007FFE61866FBE63866FF661867FFE7FFE61867DBE618E6FBE61867FFE0000
+E52F:00007FFE61866FBE63866FF661867FFE7FFE61867DBE618E6FBE61BE7FFE0000
+E530:00007FFE61866FBE63866FF661867FFE7FFE63CE7DB671B67DB663CE7FFE0000
+E531:00007FFE61866FBE63866FF661867FFE7FFE63EE7DCE71EE7DEE63C67FFE0000
+E532:00007FFE61866FBE63866FF661867FFE7FFE63867DF671867DBE63867FFE0000
+E533:00007FFE61866FBE63866FF661867FFE7FFE638E7DF671C67DF6638E7FFE0000
+E534:00007FFE61866FBE63866FF661867FFE7FFE63B67DB671867DF663F67FFE0000
+E535:00007FFE61866FBE63866FF661867FFE7FFE63867DBE71867DF663867FFE0000
+E536:00007FFE61866FBE63866FF661867FFE7FFE63CE7DBE718E7DB663CE7FFE0000
+E537:00007FFE61866FBE63866FF661867FFE7FFE63867DF671EE7DDE63DE7FFE0000
+E538:00007FFE61866FBE63866FF661867FFE7FFE63CE7DB671CE7DB663CE7FFE0000
+E539:00007FFE61866FBE63866FF661867FFE7FFE63CE7DB671C67DF663CE7FFE0000
+E53A:00007FFE61866FBE63866FF661867FFE7FFE63867DB671867DB663B67FFE0000
+E53B:00007FFE61866FBE63866FF661867FFE7FFE638E7DB6718E7DB6638E7FFE0000
+E53C:00007FFE61866FBE63866FF661867FFE7FFE63C67DBE71BE7DBE63C67FFE0000
+E53D:00007FFE61866FBE63866FF661867FFE7FFE638E7DB671B67DB6638E7FFE0000
+E53E:00007FFE61866FBE63866FF661867FFE7FFE63867DBE718E7DBE63867FFE0000
+E53F:00007FFE61866FBE63866FF661867FFE7FFE63867DBE718E7DBE63BE7FFE0000
+E540:00007FFE61866FBE63866FF661867FFE7FFE6DCE6DB661B67DB67DCE7FFE0000
+E541:00007FFE61866FBE63866FF661867FFE7FFE6DEE6DCE61EE7DEE7DC67FFE0000
+E542:00007FFE61866FBE63866FF661867FFE7FFE6D866DF661867DBE7D867FFE0000
+E543:00007FFE61866FBE63866FF661867FFE7FFE6D8E6DF661C67DF67D8E7FFE0000
+E544:00007FFE61866FBE63866FF661867FFE7FFE6DB66DB661867DF67DF67FFE0000
+E545:00007FFE61866FBE63866FF661867FFE7FFE6D866DBE61867DF67D867FFE0000
+E546:00007FFE61866FBE63866FF661867FFE7FFE6DCE6DBE618E7DB67DCE7FFE0000
+E547:00007FFE61866FBE63866FF661867FFE7FFE6D866DF661EE7DDE7DDE7FFE0000
+E548:00007FFE61866FBE63866FF661867FFE7FFE6DCE6DB661CE7DB67DCE7FFE0000
+E549:00007FFE61866FBE63866FF661867FFE7FFE6DCE6DB661C67DF67DCE7FFE0000
+E54A:00007FFE61866FBE63866FF661867FFE7FFE6D866DB661867DB67DB67FFE0000
+E54B:00007FFE61866FBE63866FF661867FFE7FFE6D8E6DB6618E7DB67D8E7FFE0000
+E54C:00007FFE61866FBE63866FF661867FFE7FFE6DC66DBE61BE7DBE7DC67FFE0000
+E54D:00007FFE61866FBE63866FF661867FFE7FFE6D8E6DB661B67DB67D8E7FFE0000
+E54E:00007FFE61866FBE63866FF661867FFE7FFE6D866DBE618E7DBE7D867FFE0000
+E54F:00007FFE61866FBE63866FF661867FFE7FFE6D866DBE618E7DBE7DBE7FFE0000
+E550:00007FFE61866FBE63866FF661867FFE7FFE61CE6FB661B67DB661CE7FFE0000
+E551:00007FFE61866FBE63866FF661867FFE7FFE61EE6FCE61EE7DEE61C67FFE0000
+E552:00007FFE61866FBE63866FF661867FFE7FFE61866FF661867DBE61867FFE0000
+E553:00007FFE61866FBE63866FF661867FFE7FFE618E6FF661C67DF6618E7FFE0000
+E554:00007FFE61866FBE63866FF661867FFE7FFE61B66FB661867DF661F67FFE0000
+E555:00007FFE61866FBE63866FF661867FFE7FFE61866FBE61867DF661867FFE0000
+E556:00007FFE61866FBE63866FF661867FFE7FFE61CE6FBE618E7DB661CE7FFE0000
+E557:00007FFE61866FBE63866FF661867FFE7FFE61866FF661EE7DDE61DE7FFE0000
+E558:00007FFE61866FBE63866FF661867FFE7FFE61CE6FB661CE7DB661CE7FFE0000
+E559:00007FFE61866FBE63866FF661867FFE7FFE61CE6FB661C67DF661CE7FFE0000
+E55A:00007FFE61866FBE63866FF661867FFE7FFE61866FB661867DB661B67FFE0000
+E55B:00007FFE61866FBE63866FF661867FFE7FFE618E6FB6618E7DB6618E7FFE0000
+E55C:00007FFE61866FBE63866FF661867FFE7FFE61C66FBE61BE7DBE61C67FFE0000
+E55D:00007FFE61866FBE63866FF661867FFE7FFE618E6FB661B67DB6618E7FFE0000
+E55E:00007FFE61866FBE63866FF661867FFE7FFE61866FBE618E7DBE61867FFE0000
+E55F:00007FFE61866FBE63866FF661867FFE7FFE61866FBE618E7DBE61BE7FFE0000
+E560:00007FFE61866FBE63866FF661867FFE7FFE73CE6FB663B66DB673CE7FFE0000
+E561:00007FFE61866FBE63866FF661867FFE7FFE73EE6FCE63EE6DEE73C67FFE0000
+E562:00007FFE61866FBE63866FF661867FFE7FFE73866FF663866DBE73867FFE0000
+E563:00007FFE61866FBE63866FF661867FFE7FFE738E6FF663C66DF6738E7FFE0000
+E564:00007FFE61866FBE63866FF661867FFE7FFE73B66FB663866DF673F67FFE0000
+E565:00007FFE61866FBE63866FF661867FFE7FFE73866FBE63866DF673867FFE0000
+E566:00007FFE61866FBE63866FF661867FFE7FFE73CE6FBE638E6DB673CE7FFE0000
+E567:00007FFE61866FBE63866FF661867FFE7FFE73866FF663EE6DDE73DE7FFE0000
+E568:00007FFE61866FBE63866FF661867FFE7FFE73CE6FB663CE6DB673CE7FFE0000
+E569:00007FFE61866FBE63866FF661867FFE7FFE73CE6FB663C66DF673CE7FFE0000
+E56A:00007FFE61866FBE63866FF661867FFE7FFE73866FB663866DB673B67FFE0000
+E56B:00007FFE61866FBE63866FF661867FFE7FFE738E6FB6638E6DB6738E7FFE0000
+E56C:00007FFE61866FBE63866FF661867FFE7FFE73C66FBE63BE6DBE73C67FFE0000
+E56D:00007FFE61866FBE63866FF661867FFE7FFE738E6FB663B66DB6738E7FFE0000
+E56E:00007FFE61866FBE63866FF661867FFE7FFE73866FBE638E6DBE73867FFE0000
+E56F:00007FFE61866FBE63866FF661867FFE7FFE73866FBE638E6DBE73BE7FFE0000
+E570:00007FFE61866FBE63866FF661867FFE7FFE61CE7DB67BB677B677CE7FFE0000
+E571:00007FFE61866FBE63866FF661867FFE7FFE61EE7DCE7BEE77EE77C67FFE0000
+E572:00007FFE61866FBE63866FF661867FFE7FFE61867DF67B8677BE77867FFE0000
+E573:00007FFE61866FBE63866FF661867FFE7FFE618E7DF67BC677F6778E7FFE0000
+E574:00007FFE61866FBE63866FF661867FFE7FFE61B67DB67B8677F677F67FFE0000
+E575:00007FFE61866FBE63866FF661867FFE7FFE61867DBE7B8677F677867FFE0000
+E576:00007FFE61866FBE63866FF661867FFE7FFE61CE7DBE7B8E77B677CE7FFE0000
+E577:00007FFE61866FBE63866FF661867FFE7FFE61867DF67BEE77DE77DE7FFE0000
+E578:00007FFE61866FBE63866FF661867FFE7FFE61CE7DB67BCE77B677CE7FFE0000
+E579:00007FFE61866FBE63866FF661867FFE7FFE61CE7DB67BC677F677CE7FFE0000
+E57A:00007FFE61866FBE63866FF661867FFE7FFE61867DB67B8677B677B67FFE0000
+E57B:00007FFE61866FBE63866FF661867FFE7FFE618E7DB67B8E77B6778E7FFE0000
+E57C:00007FFE61866FBE63866FF661867FFE7FFE61C67DBE7BBE77BE77C67FFE0000
+E57D:00007FFE61866FBE63866FF661867FFE7FFE618E7DB67BB677B6778E7FFE0000
+E57E:00007FFE61866FBE63866FF661867FFE7FFE61867DBE7B8E77BE77867FFE0000
+E57F:00007FFE61866FBE63866FF661867FFE7FFE61867DBE7B8E77BE77BE7FFE0000
+E580:00007FFE61866FBE63866FF661867FFE7FFE73CE6DB673B66DB673CE7FFE0000
+E581:00007FFE61866FBE63866FF661867FFE7FFE73EE6DCE73EE6DEE73C67FFE0000
+E582:00007FFE61866FBE63866FF661867FFE7FFE73866DF673866DBE73867FFE0000
+E583:00007FFE61866FBE63866FF661867FFE7FFE738E6DF673C66DF6738E7FFE0000
+E584:00007FFE61866FBE63866FF661867FFE7FFE73B66DB673866DF673F67FFE0000
+E585:00007FFE61866FBE63866FF661867FFE7FFE73866DBE73866DF673867FFE0000
+E586:00007FFE61866FBE63866FF661867FFE7FFE73CE6DBE738E6DB673CE7FFE0000
+E587:00007FFE61866FBE63866FF661867FFE7FFE73866DF673EE6DDE73DE7FFE0000
+E588:00007FFE61866FBE63866FF661867FFE7FFE73CE6DB673CE6DB673CE7FFE0000
+E589:00007FFE61866FBE63866FF661867FFE7FFE73CE6DB673C66DF673CE7FFE0000
+E58A:00007FFE61866FBE63866FF661867FFE7FFE73866DB673866DB673B67FFE0000
+E58B:00007FFE61866FBE63866FF661867FFE7FFE738E6DB6738E6DB6738E7FFE0000
+E58C:00007FFE61866FBE63866FF661867FFE7FFE73C66DBE73BE6DBE73C67FFE0000
+E58D:00007FFE61866FBE63866FF661867FFE7FFE738E6DB673B66DB6738E7FFE0000
+E58E:00007FFE61866FBE63866FF661867FFE7FFE73866DBE738E6DBE73867FFE0000
+E58F:00007FFE61866FBE63866FF661867FFE7FFE73866DBE738E6DBE73BE7FFE0000
+E590:00007FFE61866FBE63866FF661867FFE7FFE73CE6DB671B67DB673CE7FFE0000
+E591:00007FFE61866FBE63866FF661867FFE7FFE73EE6DCE71EE7DEE73C67FFE0000
+E592:00007FFE61866FBE63866FF661867FFE7FFE73866DF671867DBE73867FFE0000
+E593:00007FFE61866FBE63866FF661867FFE7FFE738E6DF671C67DF6738E7FFE0000
+E594:00007FFE61866FBE63866FF661867FFE7FFE73B66DB671867DF673F67FFE0000
+E595:00007FFE61866FBE63866FF661867FFE7FFE73866DBE71867DF673867FFE0000
+E596:00007FFE61866FBE63866FF661867FFE7FFE73CE6DBE718E7DB673CE7FFE0000
+E597:00007FFE61866FBE63866FF661867FFE7FFE73866DF671EE7DDE73DE7FFE0000
+E598:00007FFE61866FBE63866FF661867FFE7FFE73CE6DB671CE7DB673CE7FFE0000
+E599:00007FFE61866FBE63866FF661867FFE7FFE73CE6DB671C67DF673CE7FFE0000
+E59A:00007FFE61866FBE63866FF661867FFE7FFE73866DB671867DB673B67FFE0000
+E59B:00007FFE61866FBE63866FF661867FFE7FFE738E6DB6718E7DB6738E7FFE0000
+E59C:00007FFE61866FBE63866FF661867FFE7FFE73C66DBE71BE7DBE73C67FFE0000
+E59D:00007FFE61866FBE63866FF661867FFE7FFE738E6DB671B67DB6738E7FFE0000
+E59E:00007FFE61866FBE63866FF661867FFE7FFE73866DBE718E7DBE73867FFE0000
+E59F:00007FFE61866FBE63866FF661867FFE7FFE73866DBE718E7DBE73BE7FFE0000
+E5A0:00007FFE61866FBE63866FF661867FFE7FFE61CE6DB661B66DB66DCE7FFE0000
+E5A1:00007FFE61866FBE63866FF661867FFE7FFE61EE6DCE61EE6DEE6DC67FFE0000
+E5A2:00007FFE61866FBE63866FF661867FFE7FFE61866DF661866DBE6D867FFE0000
+E5A3:00007FFE61866FBE63866FF661867FFE7FFE618E6DF661C66DF66D8E7FFE0000
+E5A4:00007FFE61866FBE63866FF661867FFE7FFE61B66DB661866DF66DF67FFE0000
+E5A5:00007FFE61866FBE63866FF661867FFE7FFE61866DBE61866DF66D867FFE0000
+E5A6:00007FFE61866FBE63866FF661867FFE7FFE61CE6DBE618E6DB66DCE7FFE0000
+E5A7:00007FFE61866FBE63866FF661867FFE7FFE61866DF661EE6DDE6DDE7FFE0000
+E5A8:00007FFE61866FBE63866FF661867FFE7FFE61CE6DB661CE6DB66DCE7FFE0000
+E5A9:00007FFE61866FBE63866FF661867FFE7FFE61CE6DB661C66DF66DCE7FFE0000
+E5AA:00007FFE61866FBE63866FF661867FFE7FFE61866DB661866DB66DB67FFE0000
+E5AB:00007FFE61866FBE63866FF661867FFE7FFE618E6DB6618E6DB66D8E7FFE0000
+E5AC:00007FFE61866FBE63866FF661867FFE7FFE61C66DBE61BE6DBE6DC67FFE0000
+E5AD:00007FFE61866FBE63866FF661867FFE7FFE618E6DB661B66DB66D8E7FFE0000
+E5AE:00007FFE61866FBE63866FF661867FFE7FFE61866DBE618E6DBE6D867FFE0000
+E5AF:00007FFE61866FBE63866FF661867FFE7FFE61866DBE618E6DBE6DBE7FFE0000
+E5B0:00007FFE61866FBE63866FF661867FFE7FFE63CE6DB663B66DB663CE7FFE0000
+E5B1:00007FFE61866FBE63866FF661867FFE7FFE63EE6DCE63EE6DEE63C67FFE0000
+E5B2:00007FFE61866FBE63866FF661867FFE7FFE63866DF663866DBE63867FFE0000
+E5B3:00007FFE61866FBE63866FF661867FFE7FFE638E6DF663C66DF6638E7FFE0000
+E5B4:00007FFE61866FBE63866FF661867FFE7FFE63B66DB663866DF663F67FFE0000
+E5B5:00007FFE61866FBE63866FF661867FFE7FFE63866DBE63866DF663867FFE0000
+E5B6:00007FFE61866FBE63866FF661867FFE7FFE63CE6DBE638E6DB663CE7FFE0000
+E5B7:00007FFE61866FBE63866FF661867FFE7FFE63866DF663EE6DDE63DE7FFE0000
+E5B8:00007FFE61866FBE63866FF661867FFE7FFE63CE6DB663CE6DB663CE7FFE0000
+E5B9:00007FFE61866FBE63866FF661867FFE7FFE63CE6DB663C66DF663CE7FFE0000
+E5BA:00007FFE61866FBE63866FF661867FFE7FFE63866DB663866DB663B67FFE0000
+E5BB:00007FFE61866FBE63866FF661867FFE7FFE638E6DB6638E6DB6638E7FFE0000
+E5BC:00007FFE61866FBE63866FF661867FFE7FFE63C66DBE63BE6DBE63C67FFE0000
+E5BD:00007FFE61866FBE63866FF661867FFE7FFE638E6DB663B66DB6638E7FFE0000
+E5BE:00007FFE61866FBE63866FF661867FFE7FFE63866DBE638E6DBE63867FFE0000
+E5BF:00007FFE61866FBE63866FF661867FFE7FFE63866DBE638E6DBE63BE7FFE0000
+E5C0:00007FFE61866FBE63866FF661867FFE7FFE71CE6FB66FB66FB671CE7FFE0000
+E5C1:00007FFE61866FBE63866FF661867FFE7FFE71EE6FCE6FEE6FEE71C67FFE0000
+E5C2:00007FFE61866FBE63866FF661867FFE7FFE71866FF66F866FBE71867FFE0000
+E5C3:00007FFE61866FBE63866FF661867FFE7FFE718E6FF66FC66FF6718E7FFE0000
+E5C4:00007FFE61866FBE63866FF661867FFE7FFE71B66FB66F866FF671F67FFE0000
+E5C5:00007FFE61866FBE63866FF661867FFE7FFE71866FBE6F866FF671867FFE0000
+E5C6:00007FFE61866FBE63866FF661867FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000
+E5C7:00007FFE61866FBE63866FF661867FFE7FFE71866FF66FEE6FDE71DE7FFE0000
+E5C8:00007FFE61866FBE63866FF661867FFE7FFE71CE6FB66FCE6FB671CE7FFE0000
+E5C9:00007FFE61866FBE63866FF661867FFE7FFE71CE6FB66FC66FF671CE7FFE0000
+E5CA:00007FFE61866FBE63866FF661867FFE7FFE71866FB66F866FB671B67FFE0000
+E5CB:00007FFE61866FBE63866FF661867FFE7FFE718E6FB66F8E6FB6718E7FFE0000
+E5CC:00007FFE61866FBE63866FF661867FFE7FFE71C66FBE6FBE6FBE71C67FFE0000
+E5CD:00007FFE61866FBE63866FF661867FFE7FFE718E6FB66FB66FB6718E7FFE0000
+E5CE:00007FFE61866FBE63866FF661867FFE7FFE71866FBE6F8E6FBE71867FFE0000
+E5CF:00007FFE61866FBE63866FF661867FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+E5D0:00007FFE61866FBE63866FF661867FFE7FFE63CE6DB66DB66DB663CE7FFE0000
+E5D1:00007FFE61866FBE63866FF661867FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000
+E5D2:00007FFE61866FBE63866FF661867FFE7FFE63866DF66D866DBE63867FFE0000
+E5D3:00007FFE61866FBE63866FF661867FFE7FFE638E6DF66DC66DF6638E7FFE0000
+E5D4:00007FFE61866FBE63866FF661867FFE7FFE63B66DB66D866DF663F67FFE0000
+E5D5:00007FFE61866FBE63866FF661867FFE7FFE63866DBE6D866DF663867FFE0000
+E5D6:00007FFE61866FBE63866FF661867FFE7FFE63CE6DBE6D8E6DB663CE7FFE0000
+E5D7:00007FFE61866FBE63866FF661867FFE7FFE63866DF66DEE6DDE63DE7FFE0000
+E5D8:00007FFE61866FBE63866FF661867FFE7FFE63CE6DB66DCE6DB663CE7FFE0000
+E5D9:00007FFE61866FBE63866FF661867FFE7FFE63CE6DB66DC66DF663CE7FFE0000
+E5DA:00007FFE61866FBE63866FF661867FFE7FFE63866DB66D866DB663B67FFE0000
+E5DB:00007FFE61866FBE63866FF661867FFE7FFE638E6DB66D8E6DB6638E7FFE0000
+E5DC:00007FFE61866FBE63866FF661867FFE7FFE63C66DBE6DBE6DBE63C67FFE0000
+E5DD:00007FFE61866FBE63866FF661867FFE7FFE638E6DB66DB66DB6638E7FFE0000
+E5DE:00007FFE61866FBE63866FF661867FFE7FFE63866DBE6D8E6DBE63867FFE0000
+E5DF:00007FFE61866FBE63866FF661867FFE7FFE63866DBE6D8E6DBE63BE7FFE0000
+E5E0:00007FFE61866FBE63866FF661867FFE7FFE61CE6FB663B66FB661CE7FFE0000
+E5E1:00007FFE61866FBE63866FF661867FFE7FFE61EE6FCE63EE6FEE61C67FFE0000
+E5E2:00007FFE61866FBE63866FF661867FFE7FFE61866FF663866FBE61867FFE0000
+E5E3:00007FFE61866FBE63866FF661867FFE7FFE618E6FF663C66FF6618E7FFE0000
+E5E4:00007FFE61866FBE63866FF661867FFE7FFE61B66FB663866FF661F67FFE0000
+E5E5:00007FFE61866FBE63866FF661867FFE7FFE61866FBE63866FF661867FFE0000
+E5E6:00007FFE61866FBE63866FF661867FFE7FFE61CE6FBE638E6FB661CE7FFE0000
+E5E7:00007FFE61866FBE63866FF661867FFE7FFE61866FF663EE6FDE61DE7FFE0000
+E5E8:00007FFE61866FBE63866FF661867FFE7FFE61CE6FB663CE6FB661CE7FFE0000
+E5E9:00007FFE61866FBE63866FF661867FFE7FFE61CE6FB663C66FF661CE7FFE0000
+E5EA:00007FFE61866FBE63866FF661867FFE7FFE61866FB663866FB661B67FFE0000
+E5EB:00007FFE61866FBE63866FF661867FFE7FFE618E6FB6638E6FB6618E7FFE0000
+E5EC:00007FFE61866FBE63866FF661867FFE7FFE61C66FBE63BE6FBE61C67FFE0000
+E5ED:00007FFE61866FBE63866FF661867FFE7FFE618E6FB663B66FB6618E7FFE0000
+E5EE:00007FFE61866FBE63866FF661867FFE7FFE61866FBE638E6FBE61867FFE0000
+E5EF:00007FFE61866FBE63866FF661867FFE7FFE61866FBE638E6FBE61BE7FFE0000
+E5F0:00007FFE61866FBE63866FF661867FFE7FFE61CE6FB663B66FB66FCE7FFE0000
+E5F1:00007FFE61866FBE63866FF661867FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000
+E5F2:00007FFE61866FBE63866FF661867FFE7FFE61866FF663866FBE6F867FFE0000
+E5F3:00007FFE61866FBE63866FF661867FFE7FFE618E6FF663C66FF66F8E7FFE0000
+E5F4:00007FFE61866FBE63866FF661867FFE7FFE61B66FB663866FF66FF67FFE0000
+E5F5:00007FFE61866FBE63866FF661867FFE7FFE61866FBE63866FF66F867FFE0000
+E5F6:00007FFE61866FBE63866FF661867FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+E5F7:00007FFE61866FBE63866FF661867FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+E5F8:00007FFE61866FBE63866FF661867FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+E5F9:00007FFE61866FBE63866FF661867FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+E5FA:00007FFE61866FBE63866FF661867FFE7FFE61866FB663866FB66FB67FFE0000
+E5FB:00007FFE61866FBE63866FF661867FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+E5FC:00007FFE61866FBE63866FF661867FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+E5FD:00007FFE61866FBE63866FF661867FFE7FFE618E6FB663B66FB66F8E7FFE0000
+E5FE:00007FFE61866FBE63866FF661867FFE7FFE61866FBE638E6FBE6F867FFE0000
+E5FF:00007FFE61866FBE63866FF661867FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+E600:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73CE6DB66DB66DB673CE7FFE0000
+E601:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73EE6DCE6DEE6DEE73C67FFE0000
+E602:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73866DF66D866DBE73867FFE0000
+E603:00007FFE61CE6FBE638E6FB661CE7FFE7FFE738E6DF66DC66DF6738E7FFE0000
+E604:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73B66DB66D866DF673F67FFE0000
+E605:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73866DBE6D866DF673867FFE0000
+E606:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73CE6DBE6D8E6DB673CE7FFE0000
+E607:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73866DF66DEE6DDE73DE7FFE0000
+E608:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73CE6DB66DCE6DB673CE7FFE0000
+E609:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73CE6DB66DC66DF673CE7FFE0000
+E60A:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73866DB66D866DB673B67FFE0000
+E60B:00007FFE61CE6FBE638E6FB661CE7FFE7FFE738E6DB66D8E6DB6738E7FFE0000
+E60C:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73C66DBE6DBE6DBE73C67FFE0000
+E60D:00007FFE61CE6FBE638E6FB661CE7FFE7FFE738E6DB66DB66DB6738E7FFE0000
+E60E:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73866DBE6D8E6DBE73867FFE0000
+E60F:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73866DBE6D8E6DBE73BE7FFE0000
+E610:00007FFE61CE6FBE638E6FB661CE7FFE7FFE7BCE73B67BB67BB671CE7FFE0000
+E611:00007FFE61CE6FBE638E6FB661CE7FFE7FFE7BEE73CE7BEE7BEE71C67FFE0000
+E612:00007FFE61CE6FBE638E6FB661CE7FFE7FFE7B8673F67B867BBE71867FFE0000
+E613:00007FFE61CE6FBE638E6FB661CE7FFE7FFE7B8E73F67BC67BF6718E7FFE0000
+E614:00007FFE61CE6FBE638E6FB661CE7FFE7FFE7BB673B67B867BF671F67FFE0000
+E615:00007FFE61CE6FBE638E6FB661CE7FFE7FFE7B8673BE7B867BF671867FFE0000
+E616:00007FFE61CE6FBE638E6FB661CE7FFE7FFE7BCE73BE7B8E7BB671CE7FFE0000
+E617:00007FFE61CE6FBE638E6FB661CE7FFE7FFE7B8673F67BEE7BDE71DE7FFE0000
+E618:00007FFE61CE6FBE638E6FB661CE7FFE7FFE7BCE73B67BCE7BB671CE7FFE0000
+E619:00007FFE61CE6FBE638E6FB661CE7FFE7FFE7BCE73B67BC67BF671CE7FFE0000
+E61A:00007FFE61CE6FBE638E6FB661CE7FFE7FFE7B8673B67B867BB671B67FFE0000
+E61B:00007FFE61CE6FBE638E6FB661CE7FFE7FFE7B8E73B67B8E7BB6718E7FFE0000
+E61C:00007FFE61CE6FBE638E6FB661CE7FFE7FFE7BC673BE7BBE7BBE71C67FFE0000
+E61D:00007FFE61CE6FBE638E6FB661CE7FFE7FFE7B8E73B67BB67BB6718E7FFE0000
+E61E:00007FFE61CE6FBE638E6FB661CE7FFE7FFE7B8673BE7B8E7BBE71867FFE0000
+E61F:00007FFE61CE6FBE638E6FB661CE7FFE7FFE7B8673BE7B8E7BBE71BE7FFE0000
+E620:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61CE7DB661B66FB661CE7FFE0000
+E621:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61EE7DCE61EE6FEE61C67FFE0000
+E622:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61867DF661866FBE61867FFE0000
+E623:00007FFE61CE6FBE638E6FB661CE7FFE7FFE618E7DF661C66FF6618E7FFE0000
+E624:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61B67DB661866FF661F67FFE0000
+E625:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61867DBE61866FF661867FFE0000
+E626:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61CE7DBE618E6FB661CE7FFE0000
+E627:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61867DF661EE6FDE61DE7FFE0000
+E628:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61CE7DB661CE6FB661CE7FFE0000
+E629:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61CE7DB661C66FF661CE7FFE0000
+E62A:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61867DB661866FB661B67FFE0000
+E62B:00007FFE61CE6FBE638E6FB661CE7FFE7FFE618E7DB6618E6FB6618E7FFE0000
+E62C:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61C67DBE61BE6FBE61C67FFE0000
+E62D:00007FFE61CE6FBE638E6FB661CE7FFE7FFE618E7DB661B66FB6618E7FFE0000
+E62E:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61867DBE618E6FBE61867FFE0000
+E62F:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61867DBE618E6FBE61BE7FFE0000
+E630:00007FFE61CE6FBE638E6FB661CE7FFE7FFE63CE7DB671B67DB663CE7FFE0000
+E631:00007FFE61CE6FBE638E6FB661CE7FFE7FFE63EE7DCE71EE7DEE63C67FFE0000
+E632:00007FFE61CE6FBE638E6FB661CE7FFE7FFE63867DF671867DBE63867FFE0000
+E633:00007FFE61CE6FBE638E6FB661CE7FFE7FFE638E7DF671C67DF6638E7FFE0000
+E634:00007FFE61CE6FBE638E6FB661CE7FFE7FFE63B67DB671867DF663F67FFE0000
+E635:00007FFE61CE6FBE638E6FB661CE7FFE7FFE63867DBE71867DF663867FFE0000
+E636:00007FFE61CE6FBE638E6FB661CE7FFE7FFE63CE7DBE718E7DB663CE7FFE0000
+E637:00007FFE61CE6FBE638E6FB661CE7FFE7FFE63867DF671EE7DDE63DE7FFE0000
+E638:00007FFE61CE6FBE638E6FB661CE7FFE7FFE63CE7DB671CE7DB663CE7FFE0000
+E639:00007FFE61CE6FBE638E6FB661CE7FFE7FFE63CE7DB671C67DF663CE7FFE0000
+E63A:00007FFE61CE6FBE638E6FB661CE7FFE7FFE63867DB671867DB663B67FFE0000
+E63B:00007FFE61CE6FBE638E6FB661CE7FFE7FFE638E7DB6718E7DB6638E7FFE0000
+E63C:00007FFE61CE6FBE638E6FB661CE7FFE7FFE63C67DBE71BE7DBE63C67FFE0000
+E63D:00007FFE61CE6FBE638E6FB661CE7FFE7FFE638E7DB671B67DB6638E7FFE0000
+E63E:00007FFE61CE6FBE638E6FB661CE7FFE7FFE63867DBE718E7DBE63867FFE0000
+E63F:00007FFE61CE6FBE638E6FB661CE7FFE7FFE63867DBE718E7DBE63BE7FFE0000
+E640:00007FFE61CE6FBE638E6FB661CE7FFE7FFE6DCE6DB661B67DB67DCE7FFE0000
+E641:00007FFE61CE6FBE638E6FB661CE7FFE7FFE6DEE6DCE61EE7DEE7DC67FFE0000
+E642:00007FFE61CE6FBE638E6FB661CE7FFE7FFE6D866DF661867DBE7D867FFE0000
+E643:00007FFE61CE6FBE638E6FB661CE7FFE7FFE6D8E6DF661C67DF67D8E7FFE0000
+E644:00007FFE61CE6FBE638E6FB661CE7FFE7FFE6DB66DB661867DF67DF67FFE0000
+E645:00007FFE61CE6FBE638E6FB661CE7FFE7FFE6D866DBE61867DF67D867FFE0000
+E646:00007FFE61CE6FBE638E6FB661CE7FFE7FFE6DCE6DBE618E7DB67DCE7FFE0000
+E647:00007FFE61CE6FBE638E6FB661CE7FFE7FFE6D866DF661EE7DDE7DDE7FFE0000
+E648:00007FFE61CE6FBE638E6FB661CE7FFE7FFE6DCE6DB661CE7DB67DCE7FFE0000
+E649:00007FFE61CE6FBE638E6FB661CE7FFE7FFE6DCE6DB661C67DF67DCE7FFE0000
+E64A:00007FFE61CE6FBE638E6FB661CE7FFE7FFE6D866DB661867DB67DB67FFE0000
+E64B:00007FFE61CE6FBE638E6FB661CE7FFE7FFE6D8E6DB6618E7DB67D8E7FFE0000
+E64C:00007FFE61CE6FBE638E6FB661CE7FFE7FFE6DC66DBE61BE7DBE7DC67FFE0000
+E64D:00007FFE61CE6FBE638E6FB661CE7FFE7FFE6D8E6DB661B67DB67D8E7FFE0000
+E64E:00007FFE61CE6FBE638E6FB661CE7FFE7FFE6D866DBE618E7DBE7D867FFE0000
+E64F:00007FFE61CE6FBE638E6FB661CE7FFE7FFE6D866DBE618E7DBE7DBE7FFE0000
+E650:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61CE6FB661B67DB661CE7FFE0000
+E651:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61EE6FCE61EE7DEE61C67FFE0000
+E652:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61866FF661867DBE61867FFE0000
+E653:00007FFE61CE6FBE638E6FB661CE7FFE7FFE618E6FF661C67DF6618E7FFE0000
+E654:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61B66FB661867DF661F67FFE0000
+E655:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61866FBE61867DF661867FFE0000
+E656:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61CE6FBE618E7DB661CE7FFE0000
+E657:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61866FF661EE7DDE61DE7FFE0000
+E658:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61CE6FB661CE7DB661CE7FFE0000
+E659:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61CE6FB661C67DF661CE7FFE0000
+E65A:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61866FB661867DB661B67FFE0000
+E65B:00007FFE61CE6FBE638E6FB661CE7FFE7FFE618E6FB6618E7DB6618E7FFE0000
+E65C:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61C66FBE61BE7DBE61C67FFE0000
+E65D:00007FFE61CE6FBE638E6FB661CE7FFE7FFE618E6FB661B67DB6618E7FFE0000
+E65E:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61866FBE618E7DBE61867FFE0000
+E65F:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61866FBE618E7DBE61BE7FFE0000
+E660:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73CE6FB663B66DB673CE7FFE0000
+E661:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73EE6FCE63EE6DEE73C67FFE0000
+E662:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73866FF663866DBE73867FFE0000
+E663:00007FFE61CE6FBE638E6FB661CE7FFE7FFE738E6FF663C66DF6738E7FFE0000
+E664:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73B66FB663866DF673F67FFE0000
+E665:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73866FBE63866DF673867FFE0000
+E666:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73CE6FBE638E6DB673CE7FFE0000
+E667:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73866FF663EE6DDE73DE7FFE0000
+E668:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73CE6FB663CE6DB673CE7FFE0000
+E669:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73CE6FB663C66DF673CE7FFE0000
+E66A:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73866FB663866DB673B67FFE0000
+E66B:00007FFE61CE6FBE638E6FB661CE7FFE7FFE738E6FB6638E6DB6738E7FFE0000
+E66C:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73C66FBE63BE6DBE73C67FFE0000
+E66D:00007FFE61CE6FBE638E6FB661CE7FFE7FFE738E6FB663B66DB6738E7FFE0000
+E66E:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73866FBE638E6DBE73867FFE0000
+E66F:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73866FBE638E6DBE73BE7FFE0000
+E670:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61CE7DB67BB677B677CE7FFE0000
+E671:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61EE7DCE7BEE77EE77C67FFE0000
+E672:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61867DF67B8677BE77867FFE0000
+E673:00007FFE61CE6FBE638E6FB661CE7FFE7FFE618E7DF67BC677F6778E7FFE0000
+E674:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61B67DB67B8677F677F67FFE0000
+E675:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61867DBE7B8677F677867FFE0000
+E676:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61CE7DBE7B8E77B677CE7FFE0000
+E677:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61867DF67BEE77DE77DE7FFE0000
+E678:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61CE7DB67BCE77B677CE7FFE0000
+E679:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61CE7DB67BC677F677CE7FFE0000
+E67A:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61867DB67B8677B677B67FFE0000
+E67B:00007FFE61CE6FBE638E6FB661CE7FFE7FFE618E7DB67B8E77B6778E7FFE0000
+E67C:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61C67DBE7BBE77BE77C67FFE0000
+E67D:00007FFE61CE6FBE638E6FB661CE7FFE7FFE618E7DB67BB677B6778E7FFE0000
+E67E:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61867DBE7B8E77BE77867FFE0000
+E67F:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61867DBE7B8E77BE77BE7FFE0000
+E680:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73CE6DB673B66DB673CE7FFE0000
+E681:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73EE6DCE73EE6DEE73C67FFE0000
+E682:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73866DF673866DBE73867FFE0000
+E683:00007FFE61CE6FBE638E6FB661CE7FFE7FFE738E6DF673C66DF6738E7FFE0000
+E684:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73B66DB673866DF673F67FFE0000
+E685:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73866DBE73866DF673867FFE0000
+E686:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73CE6DBE738E6DB673CE7FFE0000
+E687:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73866DF673EE6DDE73DE7FFE0000
+E688:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73CE6DB673CE6DB673CE7FFE0000
+E689:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73CE6DB673C66DF673CE7FFE0000
+E68A:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73866DB673866DB673B67FFE0000
+E68B:00007FFE61CE6FBE638E6FB661CE7FFE7FFE738E6DB6738E6DB6738E7FFE0000
+E68C:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73C66DBE73BE6DBE73C67FFE0000
+E68D:00007FFE61CE6FBE638E6FB661CE7FFE7FFE738E6DB673B66DB6738E7FFE0000
+E68E:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73866DBE738E6DBE73867FFE0000
+E68F:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73866DBE738E6DBE73BE7FFE0000
+E690:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73CE6DB671B67DB673CE7FFE0000
+E691:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73EE6DCE71EE7DEE73C67FFE0000
+E692:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73866DF671867DBE73867FFE0000
+E693:00007FFE61CE6FBE638E6FB661CE7FFE7FFE738E6DF671C67DF6738E7FFE0000
+E694:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73B66DB671867DF673F67FFE0000
+E695:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73866DBE71867DF673867FFE0000
+E696:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73CE6DBE718E7DB673CE7FFE0000
+E697:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73866DF671EE7DDE73DE7FFE0000
+E698:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73CE6DB671CE7DB673CE7FFE0000
+E699:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73CE6DB671C67DF673CE7FFE0000
+E69A:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73866DB671867DB673B67FFE0000
+E69B:00007FFE61CE6FBE638E6FB661CE7FFE7FFE738E6DB6718E7DB6738E7FFE0000
+E69C:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73C66DBE71BE7DBE73C67FFE0000
+E69D:00007FFE61CE6FBE638E6FB661CE7FFE7FFE738E6DB671B67DB6738E7FFE0000
+E69E:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73866DBE718E7DBE73867FFE0000
+E69F:00007FFE61CE6FBE638E6FB661CE7FFE7FFE73866DBE718E7DBE73BE7FFE0000
+E6A0:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61CE6DB661B66DB66DCE7FFE0000
+E6A1:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61EE6DCE61EE6DEE6DC67FFE0000
+E6A2:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61866DF661866DBE6D867FFE0000
+E6A3:00007FFE61CE6FBE638E6FB661CE7FFE7FFE618E6DF661C66DF66D8E7FFE0000
+E6A4:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61B66DB661866DF66DF67FFE0000
+E6A5:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61866DBE61866DF66D867FFE0000
+E6A6:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61CE6DBE618E6DB66DCE7FFE0000
+E6A7:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61866DF661EE6DDE6DDE7FFE0000
+E6A8:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61CE6DB661CE6DB66DCE7FFE0000
+E6A9:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61CE6DB661C66DF66DCE7FFE0000
+E6AA:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61866DB661866DB66DB67FFE0000
+E6AB:00007FFE61CE6FBE638E6FB661CE7FFE7FFE618E6DB6618E6DB66D8E7FFE0000
+E6AC:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61C66DBE61BE6DBE6DC67FFE0000
+E6AD:00007FFE61CE6FBE638E6FB661CE7FFE7FFE618E6DB661B66DB66D8E7FFE0000
+E6AE:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61866DBE618E6DBE6D867FFE0000
+E6AF:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61866DBE618E6DBE6DBE7FFE0000
+E6B0:00007FFE61CE6FBE638E6FB661CE7FFE7FFE63CE6DB663B66DB663CE7FFE0000
+E6B1:00007FFE61CE6FBE638E6FB661CE7FFE7FFE63EE6DCE63EE6DEE63C67FFE0000
+E6B2:00007FFE61CE6FBE638E6FB661CE7FFE7FFE63866DF663866DBE63867FFE0000
+E6B3:00007FFE61CE6FBE638E6FB661CE7FFE7FFE638E6DF663C66DF6638E7FFE0000
+E6B4:00007FFE61CE6FBE638E6FB661CE7FFE7FFE63B66DB663866DF663F67FFE0000
+E6B5:00007FFE61CE6FBE638E6FB661CE7FFE7FFE63866DBE63866DF663867FFE0000
+E6B6:00007FFE61CE6FBE638E6FB661CE7FFE7FFE63CE6DBE638E6DB663CE7FFE0000
+E6B7:00007FFE61CE6FBE638E6FB661CE7FFE7FFE63866DF663EE6DDE63DE7FFE0000
+E6B8:00007FFE61CE6FBE638E6FB661CE7FFE7FFE63CE6DB663CE6DB663CE7FFE0000
+E6B9:00007FFE61CE6FBE638E6FB661CE7FFE7FFE63CE6DB663C66DF663CE7FFE0000
+E6BA:00007FFE61CE6FBE638E6FB661CE7FFE7FFE63866DB663866DB663B67FFE0000
+E6BB:00007FFE61CE6FBE638E6FB661CE7FFE7FFE638E6DB6638E6DB6638E7FFE0000
+E6BC:00007FFE61CE6FBE638E6FB661CE7FFE7FFE63C66DBE63BE6DBE63C67FFE0000
+E6BD:00007FFE61CE6FBE638E6FB661CE7FFE7FFE638E6DB663B66DB6638E7FFE0000
+E6BE:00007FFE61CE6FBE638E6FB661CE7FFE7FFE63866DBE638E6DBE63867FFE0000
+E6BF:00007FFE61CE6FBE638E6FB661CE7FFE7FFE63866DBE638E6DBE63BE7FFE0000
+E6C0:00007FFE61CE6FBE638E6FB661CE7FFE7FFE71CE6FB66FB66FB671CE7FFE0000
+E6C1:00007FFE61CE6FBE638E6FB661CE7FFE7FFE71EE6FCE6FEE6FEE71C67FFE0000
+E6C2:00007FFE61CE6FBE638E6FB661CE7FFE7FFE71866FF66F866FBE71867FFE0000
+E6C3:00007FFE61CE6FBE638E6FB661CE7FFE7FFE718E6FF66FC66FF6718E7FFE0000
+E6C4:00007FFE61CE6FBE638E6FB661CE7FFE7FFE71B66FB66F866FF671F67FFE0000
+E6C5:00007FFE61CE6FBE638E6FB661CE7FFE7FFE71866FBE6F866FF671867FFE0000
+E6C6:00007FFE61CE6FBE638E6FB661CE7FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000
+E6C7:00007FFE61CE6FBE638E6FB661CE7FFE7FFE71866FF66FEE6FDE71DE7FFE0000
+E6C8:00007FFE61CE6FBE638E6FB661CE7FFE7FFE71CE6FB66FCE6FB671CE7FFE0000
+E6C9:00007FFE61CE6FBE638E6FB661CE7FFE7FFE71CE6FB66FC66FF671CE7FFE0000
+E6CA:00007FFE61CE6FBE638E6FB661CE7FFE7FFE71866FB66F866FB671B67FFE0000
+E6CB:00007FFE61CE6FBE638E6FB661CE7FFE7FFE718E6FB66F8E6FB6718E7FFE0000
+E6CC:00007FFE61CE6FBE638E6FB661CE7FFE7FFE71C66FBE6FBE6FBE71C67FFE0000
+E6CD:00007FFE61CE6FBE638E6FB661CE7FFE7FFE718E6FB66FB66FB6718E7FFE0000
+E6CE:00007FFE61CE6FBE638E6FB661CE7FFE7FFE71866FBE6F8E6FBE71867FFE0000
+E6CF:00007FFE61CE6FBE638E6FB661CE7FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+E6D0:00007FFE61CE6FBE638E6FB661CE7FFE7FFE63CE6DB66DB66DB663CE7FFE0000
+E6D1:00007FFE61CE6FBE638E6FB661CE7FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000
+E6D2:00007FFE61CE6FBE638E6FB661CE7FFE7FFE63866DF66D866DBE63867FFE0000
+E6D3:00007FFE61CE6FBE638E6FB661CE7FFE7FFE638E6DF66DC66DF6638E7FFE0000
+E6D4:00007FFE61CE6FBE638E6FB661CE7FFE7FFE63B66DB66D866DF663F67FFE0000
+E6D5:00007FFE61CE6FBE638E6FB661CE7FFE7FFE63866DBE6D866DF663867FFE0000
+E6D6:00007FFE61CE6FBE638E6FB661CE7FFE7FFE63CE6DBE6D8E6DB663CE7FFE0000
+E6D7:00007FFE61CE6FBE638E6FB661CE7FFE7FFE63866DF66DEE6DDE63DE7FFE0000
+E6D8:00007FFE61CE6FBE638E6FB661CE7FFE7FFE63CE6DB66DCE6DB663CE7FFE0000
+E6D9:00007FFE61CE6FBE638E6FB661CE7FFE7FFE63CE6DB66DC66DF663CE7FFE0000
+E6DA:00007FFE61CE6FBE638E6FB661CE7FFE7FFE63866DB66D866DB663B67FFE0000
+E6DB:00007FFE61CE6FBE638E6FB661CE7FFE7FFE638E6DB66D8E6DB6638E7FFE0000
+E6DC:00007FFE61CE6FBE638E6FB661CE7FFE7FFE63C66DBE6DBE6DBE63C67FFE0000
+E6DD:00007FFE61CE6FBE638E6FB661CE7FFE7FFE638E6DB66DB66DB6638E7FFE0000
+E6DE:00007FFE61CE6FBE638E6FB661CE7FFE7FFE63866DBE6D8E6DBE63867FFE0000
+E6DF:00007FFE61CE6FBE638E6FB661CE7FFE7FFE63866DBE6D8E6DBE63BE7FFE0000
+E6E0:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61CE6FB663B66FB661CE7FFE0000
+E6E1:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61EE6FCE63EE6FEE61C67FFE0000
+E6E2:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61866FF663866FBE61867FFE0000
+E6E3:00007FFE61CE6FBE638E6FB661CE7FFE7FFE618E6FF663C66FF6618E7FFE0000
+E6E4:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61B66FB663866FF661F67FFE0000
+E6E5:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61866FBE63866FF661867FFE0000
+E6E6:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61CE6FBE638E6FB661CE7FFE0000
+E6E7:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61866FF663EE6FDE61DE7FFE0000
+E6E8:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61CE6FB663CE6FB661CE7FFE0000
+E6E9:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61CE6FB663C66FF661CE7FFE0000
+E6EA:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61866FB663866FB661B67FFE0000
+E6EB:00007FFE61CE6FBE638E6FB661CE7FFE7FFE618E6FB6638E6FB6618E7FFE0000
+E6EC:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61C66FBE63BE6FBE61C67FFE0000
+E6ED:00007FFE61CE6FBE638E6FB661CE7FFE7FFE618E6FB663B66FB6618E7FFE0000
+E6EE:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61866FBE638E6FBE61867FFE0000
+E6EF:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61866FBE638E6FBE61BE7FFE0000
+E6F0:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61CE6FB663B66FB66FCE7FFE0000
+E6F1:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000
+E6F2:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61866FF663866FBE6F867FFE0000
+E6F3:00007FFE61CE6FBE638E6FB661CE7FFE7FFE618E6FF663C66FF66F8E7FFE0000
+E6F4:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61B66FB663866FF66FF67FFE0000
+E6F5:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61866FBE63866FF66F867FFE0000
+E6F6:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+E6F7:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+E6F8:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+E6F9:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+E6FA:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61866FB663866FB66FB67FFE0000
+E6FB:00007FFE61CE6FBE638E6FB661CE7FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+E6FC:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+E6FD:00007FFE61CE6FBE638E6FB661CE7FFE7FFE618E6FB663B66FB66F8E7FFE0000
+E6FE:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61866FBE638E6FBE6F867FFE0000
+E6FF:00007FFE61CE6FBE638E6FB661CE7FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+E700:00007FFE61866FF663EE6FDE61DE7FFE7FFE73CE6DB66DB66DB673CE7FFE0000
+E701:00007FFE61866FF663EE6FDE61DE7FFE7FFE73EE6DCE6DEE6DEE73C67FFE0000
+E702:00007FFE61866FF663EE6FDE61DE7FFE7FFE73866DF66D866DBE73867FFE0000
+E703:00007FFE61866FF663EE6FDE61DE7FFE7FFE738E6DF66DC66DF6738E7FFE0000
+E704:00007FFE61866FF663EE6FDE61DE7FFE7FFE73B66DB66D866DF673F67FFE0000
+E705:00007FFE61866FF663EE6FDE61DE7FFE7FFE73866DBE6D866DF673867FFE0000
+E706:00007FFE61866FF663EE6FDE61DE7FFE7FFE73CE6DBE6D8E6DB673CE7FFE0000
+E707:00007FFE61866FF663EE6FDE61DE7FFE7FFE73866DF66DEE6DDE73DE7FFE0000
+E708:00007FFE61866FF663EE6FDE61DE7FFE7FFE73CE6DB66DCE6DB673CE7FFE0000
+E709:00007FFE61866FF663EE6FDE61DE7FFE7FFE73CE6DB66DC66DF673CE7FFE0000
+E70A:00007FFE61866FF663EE6FDE61DE7FFE7FFE73866DB66D866DB673B67FFE0000
+E70B:00007FFE61866FF663EE6FDE61DE7FFE7FFE738E6DB66D8E6DB6738E7FFE0000
+E70C:00007FFE61866FF663EE6FDE61DE7FFE7FFE73C66DBE6DBE6DBE73C67FFE0000
+E70D:00007FFE61866FF663EE6FDE61DE7FFE7FFE738E6DB66DB66DB6738E7FFE0000
+E70E:00007FFE61866FF663EE6FDE61DE7FFE7FFE73866DBE6D8E6DBE73867FFE0000
+E70F:00007FFE61866FF663EE6FDE61DE7FFE7FFE73866DBE6D8E6DBE73BE7FFE0000
+E710:00007FFE61866FF663EE6FDE61DE7FFE7FFE7BCE73B67BB67BB671CE7FFE0000
+E711:00007FFE61866FF663EE6FDE61DE7FFE7FFE7BEE73CE7BEE7BEE71C67FFE0000
+E712:00007FFE61866FF663EE6FDE61DE7FFE7FFE7B8673F67B867BBE71867FFE0000
+E713:00007FFE61866FF663EE6FDE61DE7FFE7FFE7B8E73F67BC67BF6718E7FFE0000
+E714:00007FFE61866FF663EE6FDE61DE7FFE7FFE7BB673B67B867BF671F67FFE0000
+E715:00007FFE61866FF663EE6FDE61DE7FFE7FFE7B8673BE7B867BF671867FFE0000
+E716:00007FFE61866FF663EE6FDE61DE7FFE7FFE7BCE73BE7B8E7BB671CE7FFE0000
+E717:00007FFE61866FF663EE6FDE61DE7FFE7FFE7B8673F67BEE7BDE71DE7FFE0000
+E718:00007FFE61866FF663EE6FDE61DE7FFE7FFE7BCE73B67BCE7BB671CE7FFE0000
+E719:00007FFE61866FF663EE6FDE61DE7FFE7FFE7BCE73B67BC67BF671CE7FFE0000
+E71A:00007FFE61866FF663EE6FDE61DE7FFE7FFE7B8673B67B867BB671B67FFE0000
+E71B:00007FFE61866FF663EE6FDE61DE7FFE7FFE7B8E73B67B8E7BB6718E7FFE0000
+E71C:00007FFE61866FF663EE6FDE61DE7FFE7FFE7BC673BE7BBE7BBE71C67FFE0000
+E71D:00007FFE61866FF663EE6FDE61DE7FFE7FFE7B8E73B67BB67BB6718E7FFE0000
+E71E:00007FFE61866FF663EE6FDE61DE7FFE7FFE7B8673BE7B8E7BBE71867FFE0000
+E71F:00007FFE61866FF663EE6FDE61DE7FFE7FFE7B8673BE7B8E7BBE71BE7FFE0000
+E720:00007FFE61866FF663EE6FDE61DE7FFE7FFE61CE7DB661B66FB661CE7FFE0000
+E721:00007FFE61866FF663EE6FDE61DE7FFE7FFE61EE7DCE61EE6FEE61C67FFE0000
+E722:00007FFE61866FF663EE6FDE61DE7FFE7FFE61867DF661866FBE61867FFE0000
+E723:00007FFE61866FF663EE6FDE61DE7FFE7FFE618E7DF661C66FF6618E7FFE0000
+E724:00007FFE61866FF663EE6FDE61DE7FFE7FFE61B67DB661866FF661F67FFE0000
+E725:00007FFE61866FF663EE6FDE61DE7FFE7FFE61867DBE61866FF661867FFE0000
+E726:00007FFE61866FF663EE6FDE61DE7FFE7FFE61CE7DBE618E6FB661CE7FFE0000
+E727:00007FFE61866FF663EE6FDE61DE7FFE7FFE61867DF661EE6FDE61DE7FFE0000
+E728:00007FFE61866FF663EE6FDE61DE7FFE7FFE61CE7DB661CE6FB661CE7FFE0000
+E729:00007FFE61866FF663EE6FDE61DE7FFE7FFE61CE7DB661C66FF661CE7FFE0000
+E72A:00007FFE61866FF663EE6FDE61DE7FFE7FFE61867DB661866FB661B67FFE0000
+E72B:00007FFE61866FF663EE6FDE61DE7FFE7FFE618E7DB6618E6FB6618E7FFE0000
+E72C:00007FFE61866FF663EE6FDE61DE7FFE7FFE61C67DBE61BE6FBE61C67FFE0000
+E72D:00007FFE61866FF663EE6FDE61DE7FFE7FFE618E7DB661B66FB6618E7FFE0000
+E72E:00007FFE61866FF663EE6FDE61DE7FFE7FFE61867DBE618E6FBE61867FFE0000
+E72F:00007FFE61866FF663EE6FDE61DE7FFE7FFE61867DBE618E6FBE61BE7FFE0000
+E730:00007FFE61866FF663EE6FDE61DE7FFE7FFE63CE7DB671B67DB663CE7FFE0000
+E731:00007FFE61866FF663EE6FDE61DE7FFE7FFE63EE7DCE71EE7DEE63C67FFE0000
+E732:00007FFE61866FF663EE6FDE61DE7FFE7FFE63867DF671867DBE63867FFE0000
+E733:00007FFE61866FF663EE6FDE61DE7FFE7FFE638E7DF671C67DF6638E7FFE0000
+E734:00007FFE61866FF663EE6FDE61DE7FFE7FFE63B67DB671867DF663F67FFE0000
+E735:00007FFE61866FF663EE6FDE61DE7FFE7FFE63867DBE71867DF663867FFE0000
+E736:00007FFE61866FF663EE6FDE61DE7FFE7FFE63CE7DBE718E7DB663CE7FFE0000
+E737:00007FFE61866FF663EE6FDE61DE7FFE7FFE63867DF671EE7DDE63DE7FFE0000
+E738:00007FFE61866FF663EE6FDE61DE7FFE7FFE63CE7DB671CE7DB663CE7FFE0000
+E739:00007FFE61866FF663EE6FDE61DE7FFE7FFE63CE7DB671C67DF663CE7FFE0000
+E73A:00007FFE61866FF663EE6FDE61DE7FFE7FFE63867DB671867DB663B67FFE0000
+E73B:00007FFE61866FF663EE6FDE61DE7FFE7FFE638E7DB6718E7DB6638E7FFE0000
+E73C:00007FFE61866FF663EE6FDE61DE7FFE7FFE63C67DBE71BE7DBE63C67FFE0000
+E73D:00007FFE61866FF663EE6FDE61DE7FFE7FFE638E7DB671B67DB6638E7FFE0000
+E73E:00007FFE61866FF663EE6FDE61DE7FFE7FFE63867DBE718E7DBE63867FFE0000
+E73F:00007FFE61866FF663EE6FDE61DE7FFE7FFE63867DBE718E7DBE63BE7FFE0000
+E740:00007FFE61866FF663EE6FDE61DE7FFE7FFE6DCE6DB661B67DB67DCE7FFE0000
+E741:00007FFE61866FF663EE6FDE61DE7FFE7FFE6DEE6DCE61EE7DEE7DC67FFE0000
+E742:00007FFE61866FF663EE6FDE61DE7FFE7FFE6D866DF661867DBE7D867FFE0000
+E743:00007FFE61866FF663EE6FDE61DE7FFE7FFE6D8E6DF661C67DF67D8E7FFE0000
+E744:00007FFE61866FF663EE6FDE61DE7FFE7FFE6DB66DB661867DF67DF67FFE0000
+E745:00007FFE61866FF663EE6FDE61DE7FFE7FFE6D866DBE61867DF67D867FFE0000
+E746:00007FFE61866FF663EE6FDE61DE7FFE7FFE6DCE6DBE618E7DB67DCE7FFE0000
+E747:00007FFE61866FF663EE6FDE61DE7FFE7FFE6D866DF661EE7DDE7DDE7FFE0000
+E748:00007FFE61866FF663EE6FDE61DE7FFE7FFE6DCE6DB661CE7DB67DCE7FFE0000
+E749:00007FFE61866FF663EE6FDE61DE7FFE7FFE6DCE6DB661C67DF67DCE7FFE0000
+E74A:00007FFE61866FF663EE6FDE61DE7FFE7FFE6D866DB661867DB67DB67FFE0000
+E74B:00007FFE61866FF663EE6FDE61DE7FFE7FFE6D8E6DB6618E7DB67D8E7FFE0000
+E74C:00007FFE61866FF663EE6FDE61DE7FFE7FFE6DC66DBE61BE7DBE7DC67FFE0000
+E74D:00007FFE61866FF663EE6FDE61DE7FFE7FFE6D8E6DB661B67DB67D8E7FFE0000
+E74E:00007FFE61866FF663EE6FDE61DE7FFE7FFE6D866DBE618E7DBE7D867FFE0000
+E74F:00007FFE61866FF663EE6FDE61DE7FFE7FFE6D866DBE618E7DBE7DBE7FFE0000
+E750:00007FFE61866FF663EE6FDE61DE7FFE7FFE61CE6FB661B67DB661CE7FFE0000
+E751:00007FFE61866FF663EE6FDE61DE7FFE7FFE61EE6FCE61EE7DEE61C67FFE0000
+E752:00007FFE61866FF663EE6FDE61DE7FFE7FFE61866FF661867DBE61867FFE0000
+E753:00007FFE61866FF663EE6FDE61DE7FFE7FFE618E6FF661C67DF6618E7FFE0000
+E754:00007FFE61866FF663EE6FDE61DE7FFE7FFE61B66FB661867DF661F67FFE0000
+E755:00007FFE61866FF663EE6FDE61DE7FFE7FFE61866FBE61867DF661867FFE0000
+E756:00007FFE61866FF663EE6FDE61DE7FFE7FFE61CE6FBE618E7DB661CE7FFE0000
+E757:00007FFE61866FF663EE6FDE61DE7FFE7FFE61866FF661EE7DDE61DE7FFE0000
+E758:00007FFE61866FF663EE6FDE61DE7FFE7FFE61CE6FB661CE7DB661CE7FFE0000
+E759:00007FFE61866FF663EE6FDE61DE7FFE7FFE61CE6FB661C67DF661CE7FFE0000
+E75A:00007FFE61866FF663EE6FDE61DE7FFE7FFE61866FB661867DB661B67FFE0000
+E75B:00007FFE61866FF663EE6FDE61DE7FFE7FFE618E6FB6618E7DB6618E7FFE0000
+E75C:00007FFE61866FF663EE6FDE61DE7FFE7FFE61C66FBE61BE7DBE61C67FFE0000
+E75D:00007FFE61866FF663EE6FDE61DE7FFE7FFE618E6FB661B67DB6618E7FFE0000
+E75E:00007FFE61866FF663EE6FDE61DE7FFE7FFE61866FBE618E7DBE61867FFE0000
+E75F:00007FFE61866FF663EE6FDE61DE7FFE7FFE61866FBE618E7DBE61BE7FFE0000
+E760:00007FFE61866FF663EE6FDE61DE7FFE7FFE73CE6FB663B66DB673CE7FFE0000
+E761:00007FFE61866FF663EE6FDE61DE7FFE7FFE73EE6FCE63EE6DEE73C67FFE0000
+E762:00007FFE61866FF663EE6FDE61DE7FFE7FFE73866FF663866DBE73867FFE0000
+E763:00007FFE61866FF663EE6FDE61DE7FFE7FFE738E6FF663C66DF6738E7FFE0000
+E764:00007FFE61866FF663EE6FDE61DE7FFE7FFE73B66FB663866DF673F67FFE0000
+E765:00007FFE61866FF663EE6FDE61DE7FFE7FFE73866FBE63866DF673867FFE0000
+E766:00007FFE61866FF663EE6FDE61DE7FFE7FFE73CE6FBE638E6DB673CE7FFE0000
+E767:00007FFE61866FF663EE6FDE61DE7FFE7FFE73866FF663EE6DDE73DE7FFE0000
+E768:00007FFE61866FF663EE6FDE61DE7FFE7FFE73CE6FB663CE6DB673CE7FFE0000
+E769:00007FFE61866FF663EE6FDE61DE7FFE7FFE73CE6FB663C66DF673CE7FFE0000
+E76A:00007FFE61866FF663EE6FDE61DE7FFE7FFE73866FB663866DB673B67FFE0000
+E76B:00007FFE61866FF663EE6FDE61DE7FFE7FFE738E6FB6638E6DB6738E7FFE0000
+E76C:00007FFE61866FF663EE6FDE61DE7FFE7FFE73C66FBE63BE6DBE73C67FFE0000
+E76D:00007FFE61866FF663EE6FDE61DE7FFE7FFE738E6FB663B66DB6738E7FFE0000
+E76E:00007FFE61866FF663EE6FDE61DE7FFE7FFE73866FBE638E6DBE73867FFE0000
+E76F:00007FFE61866FF663EE6FDE61DE7FFE7FFE73866FBE638E6DBE73BE7FFE0000
+E770:00007FFE61866FF663EE6FDE61DE7FFE7FFE61CE7DB67BB677B677CE7FFE0000
+E771:00007FFE61866FF663EE6FDE61DE7FFE7FFE61EE7DCE7BEE77EE77C67FFE0000
+E772:00007FFE61866FF663EE6FDE61DE7FFE7FFE61867DF67B8677BE77867FFE0000
+E773:00007FFE61866FF663EE6FDE61DE7FFE7FFE618E7DF67BC677F6778E7FFE0000
+E774:00007FFE61866FF663EE6FDE61DE7FFE7FFE61B67DB67B8677F677F67FFE0000
+E775:00007FFE61866FF663EE6FDE61DE7FFE7FFE61867DBE7B8677F677867FFE0000
+E776:00007FFE61866FF663EE6FDE61DE7FFE7FFE61CE7DBE7B8E77B677CE7FFE0000
+E777:00007FFE61866FF663EE6FDE61DE7FFE7FFE61867DF67BEE77DE77DE7FFE0000
+E778:00007FFE61866FF663EE6FDE61DE7FFE7FFE61CE7DB67BCE77B677CE7FFE0000
+E779:00007FFE61866FF663EE6FDE61DE7FFE7FFE61CE7DB67BC677F677CE7FFE0000
+E77A:00007FFE61866FF663EE6FDE61DE7FFE7FFE61867DB67B8677B677B67FFE0000
+E77B:00007FFE61866FF663EE6FDE61DE7FFE7FFE618E7DB67B8E77B6778E7FFE0000
+E77C:00007FFE61866FF663EE6FDE61DE7FFE7FFE61C67DBE7BBE77BE77C67FFE0000
+E77D:00007FFE61866FF663EE6FDE61DE7FFE7FFE618E7DB67BB677B6778E7FFE0000
+E77E:00007FFE61866FF663EE6FDE61DE7FFE7FFE61867DBE7B8E77BE77867FFE0000
+E77F:00007FFE61866FF663EE6FDE61DE7FFE7FFE61867DBE7B8E77BE77BE7FFE0000
+E780:00007FFE61866FF663EE6FDE61DE7FFE7FFE73CE6DB673B66DB673CE7FFE0000
+E781:00007FFE61866FF663EE6FDE61DE7FFE7FFE73EE6DCE73EE6DEE73C67FFE0000
+E782:00007FFE61866FF663EE6FDE61DE7FFE7FFE73866DF673866DBE73867FFE0000
+E783:00007FFE61866FF663EE6FDE61DE7FFE7FFE738E6DF673C66DF6738E7FFE0000
+E784:00007FFE61866FF663EE6FDE61DE7FFE7FFE73B66DB673866DF673F67FFE0000
+E785:00007FFE61866FF663EE6FDE61DE7FFE7FFE73866DBE73866DF673867FFE0000
+E786:00007FFE61866FF663EE6FDE61DE7FFE7FFE73CE6DBE738E6DB673CE7FFE0000
+E787:00007FFE61866FF663EE6FDE61DE7FFE7FFE73866DF673EE6DDE73DE7FFE0000
+E788:00007FFE61866FF663EE6FDE61DE7FFE7FFE73CE6DB673CE6DB673CE7FFE0000
+E789:00007FFE61866FF663EE6FDE61DE7FFE7FFE73CE6DB673C66DF673CE7FFE0000
+E78A:00007FFE61866FF663EE6FDE61DE7FFE7FFE73866DB673866DB673B67FFE0000
+E78B:00007FFE61866FF663EE6FDE61DE7FFE7FFE738E6DB6738E6DB6738E7FFE0000
+E78C:00007FFE61866FF663EE6FDE61DE7FFE7FFE73C66DBE73BE6DBE73C67FFE0000
+E78D:00007FFE61866FF663EE6FDE61DE7FFE7FFE738E6DB673B66DB6738E7FFE0000
+E78E:00007FFE61866FF663EE6FDE61DE7FFE7FFE73866DBE738E6DBE73867FFE0000
+E78F:00007FFE61866FF663EE6FDE61DE7FFE7FFE73866DBE738E6DBE73BE7FFE0000
+E790:00007FFE61866FF663EE6FDE61DE7FFE7FFE73CE6DB671B67DB673CE7FFE0000
+E791:00007FFE61866FF663EE6FDE61DE7FFE7FFE73EE6DCE71EE7DEE73C67FFE0000
+E792:00007FFE61866FF663EE6FDE61DE7FFE7FFE73866DF671867DBE73867FFE0000
+E793:00007FFE61866FF663EE6FDE61DE7FFE7FFE738E6DF671C67DF6738E7FFE0000
+E794:00007FFE61866FF663EE6FDE61DE7FFE7FFE73B66DB671867DF673F67FFE0000
+E795:00007FFE61866FF663EE6FDE61DE7FFE7FFE73866DBE71867DF673867FFE0000
+E796:00007FFE61866FF663EE6FDE61DE7FFE7FFE73CE6DBE718E7DB673CE7FFE0000
+E797:00007FFE61866FF663EE6FDE61DE7FFE7FFE73866DF671EE7DDE73DE7FFE0000
+E798:00007FFE61866FF663EE6FDE61DE7FFE7FFE73CE6DB671CE7DB673CE7FFE0000
+E799:00007FFE61866FF663EE6FDE61DE7FFE7FFE73CE6DB671C67DF673CE7FFE0000
+E79A:00007FFE61866FF663EE6FDE61DE7FFE7FFE73866DB671867DB673B67FFE0000
+E79B:00007FFE61866FF663EE6FDE61DE7FFE7FFE738E6DB6718E7DB6738E7FFE0000
+E79C:00007FFE61866FF663EE6FDE61DE7FFE7FFE73C66DBE71BE7DBE73C67FFE0000
+E79D:00007FFE61866FF663EE6FDE61DE7FFE7FFE738E6DB671B67DB6738E7FFE0000
+E79E:00007FFE61866FF663EE6FDE61DE7FFE7FFE73866DBE718E7DBE73867FFE0000
+E79F:00007FFE61866FF663EE6FDE61DE7FFE7FFE73866DBE718E7DBE73BE7FFE0000
+E7A0:00007FFE61866FF663EE6FDE61DE7FFE7FFE61CE6DB661B66DB66DCE7FFE0000
+E7A1:00007FFE61866FF663EE6FDE61DE7FFE7FFE61EE6DCE61EE6DEE6DC67FFE0000
+E7A2:00007FFE61866FF663EE6FDE61DE7FFE7FFE61866DF661866DBE6D867FFE0000
+E7A3:00007FFE61866FF663EE6FDE61DE7FFE7FFE618E6DF661C66DF66D8E7FFE0000
+E7A4:00007FFE61866FF663EE6FDE61DE7FFE7FFE61B66DB661866DF66DF67FFE0000
+E7A5:00007FFE61866FF663EE6FDE61DE7FFE7FFE61866DBE61866DF66D867FFE0000
+E7A6:00007FFE61866FF663EE6FDE61DE7FFE7FFE61CE6DBE618E6DB66DCE7FFE0000
+E7A7:00007FFE61866FF663EE6FDE61DE7FFE7FFE61866DF661EE6DDE6DDE7FFE0000
+E7A8:00007FFE61866FF663EE6FDE61DE7FFE7FFE61CE6DB661CE6DB66DCE7FFE0000
+E7A9:00007FFE61866FF663EE6FDE61DE7FFE7FFE61CE6DB661C66DF66DCE7FFE0000
+E7AA:00007FFE61866FF663EE6FDE61DE7FFE7FFE61866DB661866DB66DB67FFE0000
+E7AB:00007FFE61866FF663EE6FDE61DE7FFE7FFE618E6DB6618E6DB66D8E7FFE0000
+E7AC:00007FFE61866FF663EE6FDE61DE7FFE7FFE61C66DBE61BE6DBE6DC67FFE0000
+E7AD:00007FFE61866FF663EE6FDE61DE7FFE7FFE618E6DB661B66DB66D8E7FFE0000
+E7AE:00007FFE61866FF663EE6FDE61DE7FFE7FFE61866DBE618E6DBE6D867FFE0000
+E7AF:00007FFE61866FF663EE6FDE61DE7FFE7FFE61866DBE618E6DBE6DBE7FFE0000
+E7B0:00007FFE61866FF663EE6FDE61DE7FFE7FFE63CE6DB663B66DB663CE7FFE0000
+E7B1:00007FFE61866FF663EE6FDE61DE7FFE7FFE63EE6DCE63EE6DEE63C67FFE0000
+E7B2:00007FFE61866FF663EE6FDE61DE7FFE7FFE63866DF663866DBE63867FFE0000
+E7B3:00007FFE61866FF663EE6FDE61DE7FFE7FFE638E6DF663C66DF6638E7FFE0000
+E7B4:00007FFE61866FF663EE6FDE61DE7FFE7FFE63B66DB663866DF663F67FFE0000
+E7B5:00007FFE61866FF663EE6FDE61DE7FFE7FFE63866DBE63866DF663867FFE0000
+E7B6:00007FFE61866FF663EE6FDE61DE7FFE7FFE63CE6DBE638E6DB663CE7FFE0000
+E7B7:00007FFE61866FF663EE6FDE61DE7FFE7FFE63866DF663EE6DDE63DE7FFE0000
+E7B8:00007FFE61866FF663EE6FDE61DE7FFE7FFE63CE6DB663CE6DB663CE7FFE0000
+E7B9:00007FFE61866FF663EE6FDE61DE7FFE7FFE63CE6DB663C66DF663CE7FFE0000
+E7BA:00007FFE61866FF663EE6FDE61DE7FFE7FFE63866DB663866DB663B67FFE0000
+E7BB:00007FFE61866FF663EE6FDE61DE7FFE7FFE638E6DB6638E6DB6638E7FFE0000
+E7BC:00007FFE61866FF663EE6FDE61DE7FFE7FFE63C66DBE63BE6DBE63C67FFE0000
+E7BD:00007FFE61866FF663EE6FDE61DE7FFE7FFE638E6DB663B66DB6638E7FFE0000
+E7BE:00007FFE61866FF663EE6FDE61DE7FFE7FFE63866DBE638E6DBE63867FFE0000
+E7BF:00007FFE61866FF663EE6FDE61DE7FFE7FFE63866DBE638E6DBE63BE7FFE0000
+E7C0:00007FFE61866FF663EE6FDE61DE7FFE7FFE71CE6FB66FB66FB671CE7FFE0000
+E7C1:00007FFE61866FF663EE6FDE61DE7FFE7FFE71EE6FCE6FEE6FEE71C67FFE0000
+E7C2:00007FFE61866FF663EE6FDE61DE7FFE7FFE71866FF66F866FBE71867FFE0000
+E7C3:00007FFE61866FF663EE6FDE61DE7FFE7FFE718E6FF66FC66FF6718E7FFE0000
+E7C4:00007FFE61866FF663EE6FDE61DE7FFE7FFE71B66FB66F866FF671F67FFE0000
+E7C5:00007FFE61866FF663EE6FDE61DE7FFE7FFE71866FBE6F866FF671867FFE0000
+E7C6:00007FFE61866FF663EE6FDE61DE7FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000
+E7C7:00007FFE61866FF663EE6FDE61DE7FFE7FFE71866FF66FEE6FDE71DE7FFE0000
+E7C8:00007FFE61866FF663EE6FDE61DE7FFE7FFE71CE6FB66FCE6FB671CE7FFE0000
+E7C9:00007FFE61866FF663EE6FDE61DE7FFE7FFE71CE6FB66FC66FF671CE7FFE0000
+E7CA:00007FFE61866FF663EE6FDE61DE7FFE7FFE71866FB66F866FB671B67FFE0000
+E7CB:00007FFE61866FF663EE6FDE61DE7FFE7FFE718E6FB66F8E6FB6718E7FFE0000
+E7CC:00007FFE61866FF663EE6FDE61DE7FFE7FFE71C66FBE6FBE6FBE71C67FFE0000
+E7CD:00007FFE61866FF663EE6FDE61DE7FFE7FFE718E6FB66FB66FB6718E7FFE0000
+E7CE:00007FFE61866FF663EE6FDE61DE7FFE7FFE71866FBE6F8E6FBE71867FFE0000
+E7CF:00007FFE61866FF663EE6FDE61DE7FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+E7D0:00007FFE61866FF663EE6FDE61DE7FFE7FFE63CE6DB66DB66DB663CE7FFE0000
+E7D1:00007FFE61866FF663EE6FDE61DE7FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000
+E7D2:00007FFE61866FF663EE6FDE61DE7FFE7FFE63866DF66D866DBE63867FFE0000
+E7D3:00007FFE61866FF663EE6FDE61DE7FFE7FFE638E6DF66DC66DF6638E7FFE0000
+E7D4:00007FFE61866FF663EE6FDE61DE7FFE7FFE63B66DB66D866DF663F67FFE0000
+E7D5:00007FFE61866FF663EE6FDE61DE7FFE7FFE63866DBE6D866DF663867FFE0000
+E7D6:00007FFE61866FF663EE6FDE61DE7FFE7FFE63CE6DBE6D8E6DB663CE7FFE0000
+E7D7:00007FFE61866FF663EE6FDE61DE7FFE7FFE63866DF66DEE6DDE63DE7FFE0000
+E7D8:00007FFE61866FF663EE6FDE61DE7FFE7FFE63CE6DB66DCE6DB663CE7FFE0000
+E7D9:00007FFE61866FF663EE6FDE61DE7FFE7FFE63CE6DB66DC66DF663CE7FFE0000
+E7DA:00007FFE61866FF663EE6FDE61DE7FFE7FFE63866DB66D866DB663B67FFE0000
+E7DB:00007FFE61866FF663EE6FDE61DE7FFE7FFE638E6DB66D8E6DB6638E7FFE0000
+E7DC:00007FFE61866FF663EE6FDE61DE7FFE7FFE63C66DBE6DBE6DBE63C67FFE0000
+E7DD:00007FFE61866FF663EE6FDE61DE7FFE7FFE638E6DB66DB66DB6638E7FFE0000
+E7DE:00007FFE61866FF663EE6FDE61DE7FFE7FFE63866DBE6D8E6DBE63867FFE0000
+E7DF:00007FFE61866FF663EE6FDE61DE7FFE7FFE63866DBE6D8E6DBE63BE7FFE0000
+E7E0:00007FFE61866FF663EE6FDE61DE7FFE7FFE61CE6FB663B66FB661CE7FFE0000
+E7E1:00007FFE61866FF663EE6FDE61DE7FFE7FFE61EE6FCE63EE6FEE61C67FFE0000
+E7E2:00007FFE61866FF663EE6FDE61DE7FFE7FFE61866FF663866FBE61867FFE0000
+E7E3:00007FFE61866FF663EE6FDE61DE7FFE7FFE618E6FF663C66FF6618E7FFE0000
+E7E4:00007FFE61866FF663EE6FDE61DE7FFE7FFE61B66FB663866FF661F67FFE0000
+E7E5:00007FFE61866FF663EE6FDE61DE7FFE7FFE61866FBE63866FF661867FFE0000
+E7E6:00007FFE61866FF663EE6FDE61DE7FFE7FFE61CE6FBE638E6FB661CE7FFE0000
+E7E7:00007FFE61866FF663EE6FDE61DE7FFE7FFE61866FF663EE6FDE61DE7FFE0000
+E7E8:00007FFE61866FF663EE6FDE61DE7FFE7FFE61CE6FB663CE6FB661CE7FFE0000
+E7E9:00007FFE61866FF663EE6FDE61DE7FFE7FFE61CE6FB663C66FF661CE7FFE0000
+E7EA:00007FFE61866FF663EE6FDE61DE7FFE7FFE61866FB663866FB661B67FFE0000
+E7EB:00007FFE61866FF663EE6FDE61DE7FFE7FFE618E6FB6638E6FB6618E7FFE0000
+E7EC:00007FFE61866FF663EE6FDE61DE7FFE7FFE61C66FBE63BE6FBE61C67FFE0000
+E7ED:00007FFE61866FF663EE6FDE61DE7FFE7FFE618E6FB663B66FB6618E7FFE0000
+E7EE:00007FFE61866FF663EE6FDE61DE7FFE7FFE61866FBE638E6FBE61867FFE0000
+E7EF:00007FFE61866FF663EE6FDE61DE7FFE7FFE61866FBE638E6FBE61BE7FFE0000
+E7F0:00007FFE61866FF663EE6FDE61DE7FFE7FFE61CE6FB663B66FB66FCE7FFE0000
+E7F1:00007FFE61866FF663EE6FDE61DE7FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000
+E7F2:00007FFE61866FF663EE6FDE61DE7FFE7FFE61866FF663866FBE6F867FFE0000
+E7F3:00007FFE61866FF663EE6FDE61DE7FFE7FFE618E6FF663C66FF66F8E7FFE0000
+E7F4:00007FFE61866FF663EE6FDE61DE7FFE7FFE61B66FB663866FF66FF67FFE0000
+E7F5:00007FFE61866FF663EE6FDE61DE7FFE7FFE61866FBE63866FF66F867FFE0000
+E7F6:00007FFE61866FF663EE6FDE61DE7FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+E7F7:00007FFE61866FF663EE6FDE61DE7FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+E7F8:00007FFE61866FF663EE6FDE61DE7FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+E7F9:00007FFE61866FF663EE6FDE61DE7FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+E7FA:00007FFE61866FF663EE6FDE61DE7FFE7FFE61866FB663866FB66FB67FFE0000
+E7FB:00007FFE61866FF663EE6FDE61DE7FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+E7FC:00007FFE61866FF663EE6FDE61DE7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+E7FD:00007FFE61866FF663EE6FDE61DE7FFE7FFE618E6FB663B66FB66F8E7FFE0000
+E7FE:00007FFE61866FF663EE6FDE61DE7FFE7FFE61866FBE638E6FBE6F867FFE0000
+E7FF:00007FFE61866FF663EE6FDE61DE7FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+E800:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73CE6DB66DB66DB673CE7FFE0000
+E801:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73EE6DCE6DEE6DEE73C67FFE0000
+E802:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73866DF66D866DBE73867FFE0000
+E803:00007FFE61CE6FB663CE6FB661CE7FFE7FFE738E6DF66DC66DF6738E7FFE0000
+E804:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73B66DB66D866DF673F67FFE0000
+E805:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73866DBE6D866DF673867FFE0000
+E806:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73CE6DBE6D8E6DB673CE7FFE0000
+E807:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73866DF66DEE6DDE73DE7FFE0000
+E808:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73CE6DB66DCE6DB673CE7FFE0000
+E809:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73CE6DB66DC66DF673CE7FFE0000
+E80A:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73866DB66D866DB673B67FFE0000
+E80B:00007FFE61CE6FB663CE6FB661CE7FFE7FFE738E6DB66D8E6DB6738E7FFE0000
+E80C:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73C66DBE6DBE6DBE73C67FFE0000
+E80D:00007FFE61CE6FB663CE6FB661CE7FFE7FFE738E6DB66DB66DB6738E7FFE0000
+E80E:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73866DBE6D8E6DBE73867FFE0000
+E80F:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73866DBE6D8E6DBE73BE7FFE0000
+E810:00007FFE61CE6FB663CE6FB661CE7FFE7FFE7BCE73B67BB67BB671CE7FFE0000
+E811:00007FFE61CE6FB663CE6FB661CE7FFE7FFE7BEE73CE7BEE7BEE71C67FFE0000
+E812:00007FFE61CE6FB663CE6FB661CE7FFE7FFE7B8673F67B867BBE71867FFE0000
+E813:00007FFE61CE6FB663CE6FB661CE7FFE7FFE7B8E73F67BC67BF6718E7FFE0000
+E814:00007FFE61CE6FB663CE6FB661CE7FFE7FFE7BB673B67B867BF671F67FFE0000
+E815:00007FFE61CE6FB663CE6FB661CE7FFE7FFE7B8673BE7B867BF671867FFE0000
+E816:00007FFE61CE6FB663CE6FB661CE7FFE7FFE7BCE73BE7B8E7BB671CE7FFE0000
+E817:00007FFE61CE6FB663CE6FB661CE7FFE7FFE7B8673F67BEE7BDE71DE7FFE0000
+E818:00007FFE61CE6FB663CE6FB661CE7FFE7FFE7BCE73B67BCE7BB671CE7FFE0000
+E819:00007FFE61CE6FB663CE6FB661CE7FFE7FFE7BCE73B67BC67BF671CE7FFE0000
+E81A:00007FFE61CE6FB663CE6FB661CE7FFE7FFE7B8673B67B867BB671B67FFE0000
+E81B:00007FFE61CE6FB663CE6FB661CE7FFE7FFE7B8E73B67B8E7BB6718E7FFE0000
+E81C:00007FFE61CE6FB663CE6FB661CE7FFE7FFE7BC673BE7BBE7BBE71C67FFE0000
+E81D:00007FFE61CE6FB663CE6FB661CE7FFE7FFE7B8E73B67BB67BB6718E7FFE0000
+E81E:00007FFE61CE6FB663CE6FB661CE7FFE7FFE7B8673BE7B8E7BBE71867FFE0000
+E81F:00007FFE61CE6FB663CE6FB661CE7FFE7FFE7B8673BE7B8E7BBE71BE7FFE0000
+E820:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61CE7DB661B66FB661CE7FFE0000
+E821:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61EE7DCE61EE6FEE61C67FFE0000
+E822:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61867DF661866FBE61867FFE0000
+E823:00007FFE61CE6FB663CE6FB661CE7FFE7FFE618E7DF661C66FF6618E7FFE0000
+E824:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61B67DB661866FF661F67FFE0000
+E825:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61867DBE61866FF661867FFE0000
+E826:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61CE7DBE618E6FB661CE7FFE0000
+E827:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61867DF661EE6FDE61DE7FFE0000
+E828:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61CE7DB661CE6FB661CE7FFE0000
+E829:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61CE7DB661C66FF661CE7FFE0000
+E82A:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61867DB661866FB661B67FFE0000
+E82B:00007FFE61CE6FB663CE6FB661CE7FFE7FFE618E7DB6618E6FB6618E7FFE0000
+E82C:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61C67DBE61BE6FBE61C67FFE0000
+E82D:00007FFE61CE6FB663CE6FB661CE7FFE7FFE618E7DB661B66FB6618E7FFE0000
+E82E:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61867DBE618E6FBE61867FFE0000
+E82F:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61867DBE618E6FBE61BE7FFE0000
+E830:00007FFE61CE6FB663CE6FB661CE7FFE7FFE63CE7DB671B67DB663CE7FFE0000
+E831:00007FFE61CE6FB663CE6FB661CE7FFE7FFE63EE7DCE71EE7DEE63C67FFE0000
+E832:00007FFE61CE6FB663CE6FB661CE7FFE7FFE63867DF671867DBE63867FFE0000
+E833:00007FFE61CE6FB663CE6FB661CE7FFE7FFE638E7DF671C67DF6638E7FFE0000
+E834:00007FFE61CE6FB663CE6FB661CE7FFE7FFE63B67DB671867DF663F67FFE0000
+E835:00007FFE61CE6FB663CE6FB661CE7FFE7FFE63867DBE71867DF663867FFE0000
+E836:00007FFE61CE6FB663CE6FB661CE7FFE7FFE63CE7DBE718E7DB663CE7FFE0000
+E837:00007FFE61CE6FB663CE6FB661CE7FFE7FFE63867DF671EE7DDE63DE7FFE0000
+E838:00007FFE61CE6FB663CE6FB661CE7FFE7FFE63CE7DB671CE7DB663CE7FFE0000
+E839:00007FFE61CE6FB663CE6FB661CE7FFE7FFE63CE7DB671C67DF663CE7FFE0000
+E83A:00007FFE61CE6FB663CE6FB661CE7FFE7FFE63867DB671867DB663B67FFE0000
+E83B:00007FFE61CE6FB663CE6FB661CE7FFE7FFE638E7DB6718E7DB6638E7FFE0000
+E83C:00007FFE61CE6FB663CE6FB661CE7FFE7FFE63C67DBE71BE7DBE63C67FFE0000
+E83D:00007FFE61CE6FB663CE6FB661CE7FFE7FFE638E7DB671B67DB6638E7FFE0000
+E83E:00007FFE61CE6FB663CE6FB661CE7FFE7FFE63867DBE718E7DBE63867FFE0000
+E83F:00007FFE61CE6FB663CE6FB661CE7FFE7FFE63867DBE718E7DBE63BE7FFE0000
+E840:00007FFE61CE6FB663CE6FB661CE7FFE7FFE6DCE6DB661B67DB67DCE7FFE0000
+E841:00007FFE61CE6FB663CE6FB661CE7FFE7FFE6DEE6DCE61EE7DEE7DC67FFE0000
+E842:00007FFE61CE6FB663CE6FB661CE7FFE7FFE6D866DF661867DBE7D867FFE0000
+E843:00007FFE61CE6FB663CE6FB661CE7FFE7FFE6D8E6DF661C67DF67D8E7FFE0000
+E844:00007FFE61CE6FB663CE6FB661CE7FFE7FFE6DB66DB661867DF67DF67FFE0000
+E845:00007FFE61CE6FB663CE6FB661CE7FFE7FFE6D866DBE61867DF67D867FFE0000
+E846:00007FFE61CE6FB663CE6FB661CE7FFE7FFE6DCE6DBE618E7DB67DCE7FFE0000
+E847:00007FFE61CE6FB663CE6FB661CE7FFE7FFE6D866DF661EE7DDE7DDE7FFE0000
+E848:00007FFE61CE6FB663CE6FB661CE7FFE7FFE6DCE6DB661CE7DB67DCE7FFE0000
+E849:00007FFE61CE6FB663CE6FB661CE7FFE7FFE6DCE6DB661C67DF67DCE7FFE0000
+E84A:00007FFE61CE6FB663CE6FB661CE7FFE7FFE6D866DB661867DB67DB67FFE0000
+E84B:00007FFE61CE6FB663CE6FB661CE7FFE7FFE6D8E6DB6618E7DB67D8E7FFE0000
+E84C:00007FFE61CE6FB663CE6FB661CE7FFE7FFE6DC66DBE61BE7DBE7DC67FFE0000
+E84D:00007FFE61CE6FB663CE6FB661CE7FFE7FFE6D8E6DB661B67DB67D8E7FFE0000
+E84E:00007FFE61CE6FB663CE6FB661CE7FFE7FFE6D866DBE618E7DBE7D867FFE0000
+E84F:00007FFE61CE6FB663CE6FB661CE7FFE7FFE6D866DBE618E7DBE7DBE7FFE0000
+E850:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61CE6FB661B67DB661CE7FFE0000
+E851:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61EE6FCE61EE7DEE61C67FFE0000
+E852:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61866FF661867DBE61867FFE0000
+E853:00007FFE61CE6FB663CE6FB661CE7FFE7FFE618E6FF661C67DF6618E7FFE0000
+E854:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61B66FB661867DF661F67FFE0000
+E855:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61866FBE61867DF661867FFE0000
+E856:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61CE6FBE618E7DB661CE7FFE0000
+E857:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61866FF661EE7DDE61DE7FFE0000
+E858:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61CE6FB661CE7DB661CE7FFE0000
+E859:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61CE6FB661C67DF661CE7FFE0000
+E85A:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61866FB661867DB661B67FFE0000
+E85B:00007FFE61CE6FB663CE6FB661CE7FFE7FFE618E6FB6618E7DB6618E7FFE0000
+E85C:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61C66FBE61BE7DBE61C67FFE0000
+E85D:00007FFE61CE6FB663CE6FB661CE7FFE7FFE618E6FB661B67DB6618E7FFE0000
+E85E:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61866FBE618E7DBE61867FFE0000
+E85F:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61866FBE618E7DBE61BE7FFE0000
+E860:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73CE6FB663B66DB673CE7FFE0000
+E861:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73EE6FCE63EE6DEE73C67FFE0000
+E862:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73866FF663866DBE73867FFE0000
+E863:00007FFE61CE6FB663CE6FB661CE7FFE7FFE738E6FF663C66DF6738E7FFE0000
+E864:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73B66FB663866DF673F67FFE0000
+E865:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73866FBE63866DF673867FFE0000
+E866:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73CE6FBE638E6DB673CE7FFE0000
+E867:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73866FF663EE6DDE73DE7FFE0000
+E868:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73CE6FB663CE6DB673CE7FFE0000
+E869:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73CE6FB663C66DF673CE7FFE0000
+E86A:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73866FB663866DB673B67FFE0000
+E86B:00007FFE61CE6FB663CE6FB661CE7FFE7FFE738E6FB6638E6DB6738E7FFE0000
+E86C:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73C66FBE63BE6DBE73C67FFE0000
+E86D:00007FFE61CE6FB663CE6FB661CE7FFE7FFE738E6FB663B66DB6738E7FFE0000
+E86E:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73866FBE638E6DBE73867FFE0000
+E86F:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73866FBE638E6DBE73BE7FFE0000
+E870:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61CE7DB67BB677B677CE7FFE0000
+E871:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61EE7DCE7BEE77EE77C67FFE0000
+E872:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61867DF67B8677BE77867FFE0000
+E873:00007FFE61CE6FB663CE6FB661CE7FFE7FFE618E7DF67BC677F6778E7FFE0000
+E874:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61B67DB67B8677F677F67FFE0000
+E875:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61867DBE7B8677F677867FFE0000
+E876:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61CE7DBE7B8E77B677CE7FFE0000
+E877:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61867DF67BEE77DE77DE7FFE0000
+E878:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61CE7DB67BCE77B677CE7FFE0000
+E879:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61CE7DB67BC677F677CE7FFE0000
+E87A:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61867DB67B8677B677B67FFE0000
+E87B:00007FFE61CE6FB663CE6FB661CE7FFE7FFE618E7DB67B8E77B6778E7FFE0000
+E87C:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61C67DBE7BBE77BE77C67FFE0000
+E87D:00007FFE61CE6FB663CE6FB661CE7FFE7FFE618E7DB67BB677B6778E7FFE0000
+E87E:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61867DBE7B8E77BE77867FFE0000
+E87F:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61867DBE7B8E77BE77BE7FFE0000
+E880:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73CE6DB673B66DB673CE7FFE0000
+E881:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73EE6DCE73EE6DEE73C67FFE0000
+E882:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73866DF673866DBE73867FFE0000
+E883:00007FFE61CE6FB663CE6FB661CE7FFE7FFE738E6DF673C66DF6738E7FFE0000
+E884:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73B66DB673866DF673F67FFE0000
+E885:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73866DBE73866DF673867FFE0000
+E886:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73CE6DBE738E6DB673CE7FFE0000
+E887:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73866DF673EE6DDE73DE7FFE0000
+E888:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73CE6DB673CE6DB673CE7FFE0000
+E889:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73CE6DB673C66DF673CE7FFE0000
+E88A:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73866DB673866DB673B67FFE0000
+E88B:00007FFE61CE6FB663CE6FB661CE7FFE7FFE738E6DB6738E6DB6738E7FFE0000
+E88C:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73C66DBE73BE6DBE73C67FFE0000
+E88D:00007FFE61CE6FB663CE6FB661CE7FFE7FFE738E6DB673B66DB6738E7FFE0000
+E88E:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73866DBE738E6DBE73867FFE0000
+E88F:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73866DBE738E6DBE73BE7FFE0000
+E890:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73CE6DB671B67DB673CE7FFE0000
+E891:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73EE6DCE71EE7DEE73C67FFE0000
+E892:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73866DF671867DBE73867FFE0000
+E893:00007FFE61CE6FB663CE6FB661CE7FFE7FFE738E6DF671C67DF6738E7FFE0000
+E894:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73B66DB671867DF673F67FFE0000
+E895:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73866DBE71867DF673867FFE0000
+E896:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73CE6DBE718E7DB673CE7FFE0000
+E897:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73866DF671EE7DDE73DE7FFE0000
+E898:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73CE6DB671CE7DB673CE7FFE0000
+E899:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73CE6DB671C67DF673CE7FFE0000
+E89A:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73866DB671867DB673B67FFE0000
+E89B:00007FFE61CE6FB663CE6FB661CE7FFE7FFE738E6DB6718E7DB6738E7FFE0000
+E89C:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73C66DBE71BE7DBE73C67FFE0000
+E89D:00007FFE61CE6FB663CE6FB661CE7FFE7FFE738E6DB671B67DB6738E7FFE0000
+E89E:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73866DBE718E7DBE73867FFE0000
+E89F:00007FFE61CE6FB663CE6FB661CE7FFE7FFE73866DBE718E7DBE73BE7FFE0000
+E8A0:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61CE6DB661B66DB66DCE7FFE0000
+E8A1:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61EE6DCE61EE6DEE6DC67FFE0000
+E8A2:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61866DF661866DBE6D867FFE0000
+E8A3:00007FFE61CE6FB663CE6FB661CE7FFE7FFE618E6DF661C66DF66D8E7FFE0000
+E8A4:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61B66DB661866DF66DF67FFE0000
+E8A5:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61866DBE61866DF66D867FFE0000
+E8A6:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61CE6DBE618E6DB66DCE7FFE0000
+E8A7:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61866DF661EE6DDE6DDE7FFE0000
+E8A8:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61CE6DB661CE6DB66DCE7FFE0000
+E8A9:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61CE6DB661C66DF66DCE7FFE0000
+E8AA:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61866DB661866DB66DB67FFE0000
+E8AB:00007FFE61CE6FB663CE6FB661CE7FFE7FFE618E6DB6618E6DB66D8E7FFE0000
+E8AC:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61C66DBE61BE6DBE6DC67FFE0000
+E8AD:00007FFE61CE6FB663CE6FB661CE7FFE7FFE618E6DB661B66DB66D8E7FFE0000
+E8AE:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61866DBE618E6DBE6D867FFE0000
+E8AF:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61866DBE618E6DBE6DBE7FFE0000
+E8B0:00007FFE61CE6FB663CE6FB661CE7FFE7FFE63CE6DB663B66DB663CE7FFE0000
+E8B1:00007FFE61CE6FB663CE6FB661CE7FFE7FFE63EE6DCE63EE6DEE63C67FFE0000
+E8B2:00007FFE61CE6FB663CE6FB661CE7FFE7FFE63866DF663866DBE63867FFE0000
+E8B3:00007FFE61CE6FB663CE6FB661CE7FFE7FFE638E6DF663C66DF6638E7FFE0000
+E8B4:00007FFE61CE6FB663CE6FB661CE7FFE7FFE63B66DB663866DF663F67FFE0000
+E8B5:00007FFE61CE6FB663CE6FB661CE7FFE7FFE63866DBE63866DF663867FFE0000
+E8B6:00007FFE61CE6FB663CE6FB661CE7FFE7FFE63CE6DBE638E6DB663CE7FFE0000
+E8B7:00007FFE61CE6FB663CE6FB661CE7FFE7FFE63866DF663EE6DDE63DE7FFE0000
+E8B8:00007FFE61CE6FB663CE6FB661CE7FFE7FFE63CE6DB663CE6DB663CE7FFE0000
+E8B9:00007FFE61CE6FB663CE6FB661CE7FFE7FFE63CE6DB663C66DF663CE7FFE0000
+E8BA:00007FFE61CE6FB663CE6FB661CE7FFE7FFE63866DB663866DB663B67FFE0000
+E8BB:00007FFE61CE6FB663CE6FB661CE7FFE7FFE638E6DB6638E6DB6638E7FFE0000
+E8BC:00007FFE61CE6FB663CE6FB661CE7FFE7FFE63C66DBE63BE6DBE63C67FFE0000
+E8BD:00007FFE61CE6FB663CE6FB661CE7FFE7FFE638E6DB663B66DB6638E7FFE0000
+E8BE:00007FFE61CE6FB663CE6FB661CE7FFE7FFE63866DBE638E6DBE63867FFE0000
+E8BF:00007FFE61CE6FB663CE6FB661CE7FFE7FFE63866DBE638E6DBE63BE7FFE0000
+E8C0:00007FFE61CE6FB663CE6FB661CE7FFE7FFE71CE6FB66FB66FB671CE7FFE0000
+E8C1:00007FFE61CE6FB663CE6FB661CE7FFE7FFE71EE6FCE6FEE6FEE71C67FFE0000
+E8C2:00007FFE61CE6FB663CE6FB661CE7FFE7FFE71866FF66F866FBE71867FFE0000
+E8C3:00007FFE61CE6FB663CE6FB661CE7FFE7FFE718E6FF66FC66FF6718E7FFE0000
+E8C4:00007FFE61CE6FB663CE6FB661CE7FFE7FFE71B66FB66F866FF671F67FFE0000
+E8C5:00007FFE61CE6FB663CE6FB661CE7FFE7FFE71866FBE6F866FF671867FFE0000
+E8C6:00007FFE61CE6FB663CE6FB661CE7FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000
+E8C7:00007FFE61CE6FB663CE6FB661CE7FFE7FFE71866FF66FEE6FDE71DE7FFE0000
+E8C8:00007FFE61CE6FB663CE6FB661CE7FFE7FFE71CE6FB66FCE6FB671CE7FFE0000
+E8C9:00007FFE61CE6FB663CE6FB661CE7FFE7FFE71CE6FB66FC66FF671CE7FFE0000
+E8CA:00007FFE61CE6FB663CE6FB661CE7FFE7FFE71866FB66F866FB671B67FFE0000
+E8CB:00007FFE61CE6FB663CE6FB661CE7FFE7FFE718E6FB66F8E6FB6718E7FFE0000
+E8CC:00007FFE61CE6FB663CE6FB661CE7FFE7FFE71C66FBE6FBE6FBE71C67FFE0000
+E8CD:00007FFE61CE6FB663CE6FB661CE7FFE7FFE718E6FB66FB66FB6718E7FFE0000
+E8CE:00007FFE61CE6FB663CE6FB661CE7FFE7FFE71866FBE6F8E6FBE71867FFE0000
+E8CF:00007FFE61CE6FB663CE6FB661CE7FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+E8D0:00007FFE61CE6FB663CE6FB661CE7FFE7FFE63CE6DB66DB66DB663CE7FFE0000
+E8D1:00007FFE61CE6FB663CE6FB661CE7FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000
+E8D2:00007FFE61CE6FB663CE6FB661CE7FFE7FFE63866DF66D866DBE63867FFE0000
+E8D3:00007FFE61CE6FB663CE6FB661CE7FFE7FFE638E6DF66DC66DF6638E7FFE0000
+E8D4:00007FFE61CE6FB663CE6FB661CE7FFE7FFE63B66DB66D866DF663F67FFE0000
+E8D5:00007FFE61CE6FB663CE6FB661CE7FFE7FFE63866DBE6D866DF663867FFE0000
+E8D6:00007FFE61CE6FB663CE6FB661CE7FFE7FFE63CE6DBE6D8E6DB663CE7FFE0000
+E8D7:00007FFE61CE6FB663CE6FB661CE7FFE7FFE63866DF66DEE6DDE63DE7FFE0000
+E8D8:00007FFE61CE6FB663CE6FB661CE7FFE7FFE63CE6DB66DCE6DB663CE7FFE0000
+E8D9:00007FFE61CE6FB663CE6FB661CE7FFE7FFE63CE6DB66DC66DF663CE7FFE0000
+E8DA:00007FFE61CE6FB663CE6FB661CE7FFE7FFE63866DB66D866DB663B67FFE0000
+E8DB:00007FFE61CE6FB663CE6FB661CE7FFE7FFE638E6DB66D8E6DB6638E7FFE0000
+E8DC:00007FFE61CE6FB663CE6FB661CE7FFE7FFE63C66DBE6DBE6DBE63C67FFE0000
+E8DD:00007FFE61CE6FB663CE6FB661CE7FFE7FFE638E6DB66DB66DB6638E7FFE0000
+E8DE:00007FFE61CE6FB663CE6FB661CE7FFE7FFE63866DBE6D8E6DBE63867FFE0000
+E8DF:00007FFE61CE6FB663CE6FB661CE7FFE7FFE63866DBE6D8E6DBE63BE7FFE0000
+E8E0:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61CE6FB663B66FB661CE7FFE0000
+E8E1:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61EE6FCE63EE6FEE61C67FFE0000
+E8E2:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61866FF663866FBE61867FFE0000
+E8E3:00007FFE61CE6FB663CE6FB661CE7FFE7FFE618E6FF663C66FF6618E7FFE0000
+E8E4:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61B66FB663866FF661F67FFE0000
+E8E5:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61866FBE63866FF661867FFE0000
+E8E6:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61CE6FBE638E6FB661CE7FFE0000
+E8E7:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61866FF663EE6FDE61DE7FFE0000
+E8E8:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61CE6FB663CE6FB661CE7FFE0000
+E8E9:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61CE6FB663C66FF661CE7FFE0000
+E8EA:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61866FB663866FB661B67FFE0000
+E8EB:00007FFE61CE6FB663CE6FB661CE7FFE7FFE618E6FB6638E6FB6618E7FFE0000
+E8EC:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61C66FBE63BE6FBE61C67FFE0000
+E8ED:00007FFE61CE6FB663CE6FB661CE7FFE7FFE618E6FB663B66FB6618E7FFE0000
+E8EE:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61866FBE638E6FBE61867FFE0000
+E8EF:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61866FBE638E6FBE61BE7FFE0000
+E8F0:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61CE6FB663B66FB66FCE7FFE0000
+E8F1:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000
+E8F2:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61866FF663866FBE6F867FFE0000
+E8F3:00007FFE61CE6FB663CE6FB661CE7FFE7FFE618E6FF663C66FF66F8E7FFE0000
+E8F4:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61B66FB663866FF66FF67FFE0000
+E8F5:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61866FBE63866FF66F867FFE0000
+E8F6:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+E8F7:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+E8F8:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+E8F9:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+E8FA:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61866FB663866FB66FB67FFE0000
+E8FB:00007FFE61CE6FB663CE6FB661CE7FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+E8FC:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+E8FD:00007FFE61CE6FB663CE6FB661CE7FFE7FFE618E6FB663B66FB66F8E7FFE0000
+E8FE:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61866FBE638E6FBE6F867FFE0000
+E8FF:00007FFE61CE6FB663CE6FB661CE7FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+E900:00007FFE61CE6FB663C66FF661CE7FFE7FFE73CE6DB66DB66DB673CE7FFE0000
+E901:00007FFE61CE6FB663C66FF661CE7FFE7FFE73EE6DCE6DEE6DEE73C67FFE0000
+E902:00007FFE61CE6FB663C66FF661CE7FFE7FFE73866DF66D866DBE73867FFE0000
+E903:00007FFE61CE6FB663C66FF661CE7FFE7FFE738E6DF66DC66DF6738E7FFE0000
+E904:00007FFE61CE6FB663C66FF661CE7FFE7FFE73B66DB66D866DF673F67FFE0000
+E905:00007FFE61CE6FB663C66FF661CE7FFE7FFE73866DBE6D866DF673867FFE0000
+E906:00007FFE61CE6FB663C66FF661CE7FFE7FFE73CE6DBE6D8E6DB673CE7FFE0000
+E907:00007FFE61CE6FB663C66FF661CE7FFE7FFE73866DF66DEE6DDE73DE7FFE0000
+E908:00007FFE61CE6FB663C66FF661CE7FFE7FFE73CE6DB66DCE6DB673CE7FFE0000
+E909:00007FFE61CE6FB663C66FF661CE7FFE7FFE73CE6DB66DC66DF673CE7FFE0000
+E90A:00007FFE61CE6FB663C66FF661CE7FFE7FFE73866DB66D866DB673B67FFE0000
+E90B:00007FFE61CE6FB663C66FF661CE7FFE7FFE738E6DB66D8E6DB6738E7FFE0000
+E90C:00007FFE61CE6FB663C66FF661CE7FFE7FFE73C66DBE6DBE6DBE73C67FFE0000
+E90D:00007FFE61CE6FB663C66FF661CE7FFE7FFE738E6DB66DB66DB6738E7FFE0000
+E90E:00007FFE61CE6FB663C66FF661CE7FFE7FFE73866DBE6D8E6DBE73867FFE0000
+E90F:00007FFE61CE6FB663C66FF661CE7FFE7FFE73866DBE6D8E6DBE73BE7FFE0000
+E910:00007FFE61CE6FB663C66FF661CE7FFE7FFE7BCE73B67BB67BB671CE7FFE0000
+E911:00007FFE61CE6FB663C66FF661CE7FFE7FFE7BEE73CE7BEE7BEE71C67FFE0000
+E912:00007FFE61CE6FB663C66FF661CE7FFE7FFE7B8673F67B867BBE71867FFE0000
+E913:00007FFE61CE6FB663C66FF661CE7FFE7FFE7B8E73F67BC67BF6718E7FFE0000
+E914:00007FFE61CE6FB663C66FF661CE7FFE7FFE7BB673B67B867BF671F67FFE0000
+E915:00007FFE61CE6FB663C66FF661CE7FFE7FFE7B8673BE7B867BF671867FFE0000
+E916:00007FFE61CE6FB663C66FF661CE7FFE7FFE7BCE73BE7B8E7BB671CE7FFE0000
+E917:00007FFE61CE6FB663C66FF661CE7FFE7FFE7B8673F67BEE7BDE71DE7FFE0000
+E918:00007FFE61CE6FB663C66FF661CE7FFE7FFE7BCE73B67BCE7BB671CE7FFE0000
+E919:00007FFE61CE6FB663C66FF661CE7FFE7FFE7BCE73B67BC67BF671CE7FFE0000
+E91A:00007FFE61CE6FB663C66FF661CE7FFE7FFE7B8673B67B867BB671B67FFE0000
+E91B:00007FFE61CE6FB663C66FF661CE7FFE7FFE7B8E73B67B8E7BB6718E7FFE0000
+E91C:00007FFE61CE6FB663C66FF661CE7FFE7FFE7BC673BE7BBE7BBE71C67FFE0000
+E91D:00007FFE61CE6FB663C66FF661CE7FFE7FFE7B8E73B67BB67BB6718E7FFE0000
+E91E:00007FFE61CE6FB663C66FF661CE7FFE7FFE7B8673BE7B8E7BBE71867FFE0000
+E91F:00007FFE61CE6FB663C66FF661CE7FFE7FFE7B8673BE7B8E7BBE71BE7FFE0000
+E920:00007FFE61CE6FB663C66FF661CE7FFE7FFE61CE7DB661B66FB661CE7FFE0000
+E921:00007FFE61CE6FB663C66FF661CE7FFE7FFE61EE7DCE61EE6FEE61C67FFE0000
+E922:00007FFE61CE6FB663C66FF661CE7FFE7FFE61867DF661866FBE61867FFE0000
+E923:00007FFE61CE6FB663C66FF661CE7FFE7FFE618E7DF661C66FF6618E7FFE0000
+E924:00007FFE61CE6FB663C66FF661CE7FFE7FFE61B67DB661866FF661F67FFE0000
+E925:00007FFE61CE6FB663C66FF661CE7FFE7FFE61867DBE61866FF661867FFE0000
+E926:00007FFE61CE6FB663C66FF661CE7FFE7FFE61CE7DBE618E6FB661CE7FFE0000
+E927:00007FFE61CE6FB663C66FF661CE7FFE7FFE61867DF661EE6FDE61DE7FFE0000
+E928:00007FFE61CE6FB663C66FF661CE7FFE7FFE61CE7DB661CE6FB661CE7FFE0000
+E929:00007FFE61CE6FB663C66FF661CE7FFE7FFE61CE7DB661C66FF661CE7FFE0000
+E92A:00007FFE61CE6FB663C66FF661CE7FFE7FFE61867DB661866FB661B67FFE0000
+E92B:00007FFE61CE6FB663C66FF661CE7FFE7FFE618E7DB6618E6FB6618E7FFE0000
+E92C:00007FFE61CE6FB663C66FF661CE7FFE7FFE61C67DBE61BE6FBE61C67FFE0000
+E92D:00007FFE61CE6FB663C66FF661CE7FFE7FFE618E7DB661B66FB6618E7FFE0000
+E92E:00007FFE61CE6FB663C66FF661CE7FFE7FFE61867DBE618E6FBE61867FFE0000
+E92F:00007FFE61CE6FB663C66FF661CE7FFE7FFE61867DBE618E6FBE61BE7FFE0000
+E930:00007FFE61CE6FB663C66FF661CE7FFE7FFE63CE7DB671B67DB663CE7FFE0000
+E931:00007FFE61CE6FB663C66FF661CE7FFE7FFE63EE7DCE71EE7DEE63C67FFE0000
+E932:00007FFE61CE6FB663C66FF661CE7FFE7FFE63867DF671867DBE63867FFE0000
+E933:00007FFE61CE6FB663C66FF661CE7FFE7FFE638E7DF671C67DF6638E7FFE0000
+E934:00007FFE61CE6FB663C66FF661CE7FFE7FFE63B67DB671867DF663F67FFE0000
+E935:00007FFE61CE6FB663C66FF661CE7FFE7FFE63867DBE71867DF663867FFE0000
+E936:00007FFE61CE6FB663C66FF661CE7FFE7FFE63CE7DBE718E7DB663CE7FFE0000
+E937:00007FFE61CE6FB663C66FF661CE7FFE7FFE63867DF671EE7DDE63DE7FFE0000
+E938:00007FFE61CE6FB663C66FF661CE7FFE7FFE63CE7DB671CE7DB663CE7FFE0000
+E939:00007FFE61CE6FB663C66FF661CE7FFE7FFE63CE7DB671C67DF663CE7FFE0000
+E93A:00007FFE61CE6FB663C66FF661CE7FFE7FFE63867DB671867DB663B67FFE0000
+E93B:00007FFE61CE6FB663C66FF661CE7FFE7FFE638E7DB6718E7DB6638E7FFE0000
+E93C:00007FFE61CE6FB663C66FF661CE7FFE7FFE63C67DBE71BE7DBE63C67FFE0000
+E93D:00007FFE61CE6FB663C66FF661CE7FFE7FFE638E7DB671B67DB6638E7FFE0000
+E93E:00007FFE61CE6FB663C66FF661CE7FFE7FFE63867DBE718E7DBE63867FFE0000
+E93F:00007FFE61CE6FB663C66FF661CE7FFE7FFE63867DBE718E7DBE63BE7FFE0000
+E940:00007FFE61CE6FB663C66FF661CE7FFE7FFE6DCE6DB661B67DB67DCE7FFE0000
+E941:00007FFE61CE6FB663C66FF661CE7FFE7FFE6DEE6DCE61EE7DEE7DC67FFE0000
+E942:00007FFE61CE6FB663C66FF661CE7FFE7FFE6D866DF661867DBE7D867FFE0000
+E943:00007FFE61CE6FB663C66FF661CE7FFE7FFE6D8E6DF661C67DF67D8E7FFE0000
+E944:00007FFE61CE6FB663C66FF661CE7FFE7FFE6DB66DB661867DF67DF67FFE0000
+E945:00007FFE61CE6FB663C66FF661CE7FFE7FFE6D866DBE61867DF67D867FFE0000
+E946:00007FFE61CE6FB663C66FF661CE7FFE7FFE6DCE6DBE618E7DB67DCE7FFE0000
+E947:00007FFE61CE6FB663C66FF661CE7FFE7FFE6D866DF661EE7DDE7DDE7FFE0000
+E948:00007FFE61CE6FB663C66FF661CE7FFE7FFE6DCE6DB661CE7DB67DCE7FFE0000
+E949:00007FFE61CE6FB663C66FF661CE7FFE7FFE6DCE6DB661C67DF67DCE7FFE0000
+E94A:00007FFE61CE6FB663C66FF661CE7FFE7FFE6D866DB661867DB67DB67FFE0000
+E94B:00007FFE61CE6FB663C66FF661CE7FFE7FFE6D8E6DB6618E7DB67D8E7FFE0000
+E94C:00007FFE61CE6FB663C66FF661CE7FFE7FFE6DC66DBE61BE7DBE7DC67FFE0000
+E94D:00007FFE61CE6FB663C66FF661CE7FFE7FFE6D8E6DB661B67DB67D8E7FFE0000
+E94E:00007FFE61CE6FB663C66FF661CE7FFE7FFE6D866DBE618E7DBE7D867FFE0000
+E94F:00007FFE61CE6FB663C66FF661CE7FFE7FFE6D866DBE618E7DBE7DBE7FFE0000
+E950:00007FFE61CE6FB663C66FF661CE7FFE7FFE61CE6FB661B67DB661CE7FFE0000
+E951:00007FFE61CE6FB663C66FF661CE7FFE7FFE61EE6FCE61EE7DEE61C67FFE0000
+E952:00007FFE61CE6FB663C66FF661CE7FFE7FFE61866FF661867DBE61867FFE0000
+E953:00007FFE61CE6FB663C66FF661CE7FFE7FFE618E6FF661C67DF6618E7FFE0000
+E954:00007FFE61CE6FB663C66FF661CE7FFE7FFE61B66FB661867DF661F67FFE0000
+E955:00007FFE61CE6FB663C66FF661CE7FFE7FFE61866FBE61867DF661867FFE0000
+E956:00007FFE61CE6FB663C66FF661CE7FFE7FFE61CE6FBE618E7DB661CE7FFE0000
+E957:00007FFE61CE6FB663C66FF661CE7FFE7FFE61866FF661EE7DDE61DE7FFE0000
+E958:00007FFE61CE6FB663C66FF661CE7FFE7FFE61CE6FB661CE7DB661CE7FFE0000
+E959:00007FFE61CE6FB663C66FF661CE7FFE7FFE61CE6FB661C67DF661CE7FFE0000
+E95A:00007FFE61CE6FB663C66FF661CE7FFE7FFE61866FB661867DB661B67FFE0000
+E95B:00007FFE61CE6FB663C66FF661CE7FFE7FFE618E6FB6618E7DB6618E7FFE0000
+E95C:00007FFE61CE6FB663C66FF661CE7FFE7FFE61C66FBE61BE7DBE61C67FFE0000
+E95D:00007FFE61CE6FB663C66FF661CE7FFE7FFE618E6FB661B67DB6618E7FFE0000
+E95E:00007FFE61CE6FB663C66FF661CE7FFE7FFE61866FBE618E7DBE61867FFE0000
+E95F:00007FFE61CE6FB663C66FF661CE7FFE7FFE61866FBE618E7DBE61BE7FFE0000
+E960:00007FFE61CE6FB663C66FF661CE7FFE7FFE73CE6FB663B66DB673CE7FFE0000
+E961:00007FFE61CE6FB663C66FF661CE7FFE7FFE73EE6FCE63EE6DEE73C67FFE0000
+E962:00007FFE61CE6FB663C66FF661CE7FFE7FFE73866FF663866DBE73867FFE0000
+E963:00007FFE61CE6FB663C66FF661CE7FFE7FFE738E6FF663C66DF6738E7FFE0000
+E964:00007FFE61CE6FB663C66FF661CE7FFE7FFE73B66FB663866DF673F67FFE0000
+E965:00007FFE61CE6FB663C66FF661CE7FFE7FFE73866FBE63866DF673867FFE0000
+E966:00007FFE61CE6FB663C66FF661CE7FFE7FFE73CE6FBE638E6DB673CE7FFE0000
+E967:00007FFE61CE6FB663C66FF661CE7FFE7FFE73866FF663EE6DDE73DE7FFE0000
+E968:00007FFE61CE6FB663C66FF661CE7FFE7FFE73CE6FB663CE6DB673CE7FFE0000
+E969:00007FFE61CE6FB663C66FF661CE7FFE7FFE73CE6FB663C66DF673CE7FFE0000
+E96A:00007FFE61CE6FB663C66FF661CE7FFE7FFE73866FB663866DB673B67FFE0000
+E96B:00007FFE61CE6FB663C66FF661CE7FFE7FFE738E6FB6638E6DB6738E7FFE0000
+E96C:00007FFE61CE6FB663C66FF661CE7FFE7FFE73C66FBE63BE6DBE73C67FFE0000
+E96D:00007FFE61CE6FB663C66FF661CE7FFE7FFE738E6FB663B66DB6738E7FFE0000
+E96E:00007FFE61CE6FB663C66FF661CE7FFE7FFE73866FBE638E6DBE73867FFE0000
+E96F:00007FFE61CE6FB663C66FF661CE7FFE7FFE73866FBE638E6DBE73BE7FFE0000
+E970:00007FFE61CE6FB663C66FF661CE7FFE7FFE61CE7DB67BB677B677CE7FFE0000
+E971:00007FFE61CE6FB663C66FF661CE7FFE7FFE61EE7DCE7BEE77EE77C67FFE0000
+E972:00007FFE61CE6FB663C66FF661CE7FFE7FFE61867DF67B8677BE77867FFE0000
+E973:00007FFE61CE6FB663C66FF661CE7FFE7FFE618E7DF67BC677F6778E7FFE0000
+E974:00007FFE61CE6FB663C66FF661CE7FFE7FFE61B67DB67B8677F677F67FFE0000
+E975:00007FFE61CE6FB663C66FF661CE7FFE7FFE61867DBE7B8677F677867FFE0000
+E976:00007FFE61CE6FB663C66FF661CE7FFE7FFE61CE7DBE7B8E77B677CE7FFE0000
+E977:00007FFE61CE6FB663C66FF661CE7FFE7FFE61867DF67BEE77DE77DE7FFE0000
+E978:00007FFE61CE6FB663C66FF661CE7FFE7FFE61CE7DB67BCE77B677CE7FFE0000
+E979:00007FFE61CE6FB663C66FF661CE7FFE7FFE61CE7DB67BC677F677CE7FFE0000
+E97A:00007FFE61CE6FB663C66FF661CE7FFE7FFE61867DB67B8677B677B67FFE0000
+E97B:00007FFE61CE6FB663C66FF661CE7FFE7FFE618E7DB67B8E77B6778E7FFE0000
+E97C:00007FFE61CE6FB663C66FF661CE7FFE7FFE61C67DBE7BBE77BE77C67FFE0000
+E97D:00007FFE61CE6FB663C66FF661CE7FFE7FFE618E7DB67BB677B6778E7FFE0000
+E97E:00007FFE61CE6FB663C66FF661CE7FFE7FFE61867DBE7B8E77BE77867FFE0000
+E97F:00007FFE61CE6FB663C66FF661CE7FFE7FFE61867DBE7B8E77BE77BE7FFE0000
+E980:00007FFE61CE6FB663C66FF661CE7FFE7FFE73CE6DB673B66DB673CE7FFE0000
+E981:00007FFE61CE6FB663C66FF661CE7FFE7FFE73EE6DCE73EE6DEE73C67FFE0000
+E982:00007FFE61CE6FB663C66FF661CE7FFE7FFE73866DF673866DBE73867FFE0000
+E983:00007FFE61CE6FB663C66FF661CE7FFE7FFE738E6DF673C66DF6738E7FFE0000
+E984:00007FFE61CE6FB663C66FF661CE7FFE7FFE73B66DB673866DF673F67FFE0000
+E985:00007FFE61CE6FB663C66FF661CE7FFE7FFE73866DBE73866DF673867FFE0000
+E986:00007FFE61CE6FB663C66FF661CE7FFE7FFE73CE6DBE738E6DB673CE7FFE0000
+E987:00007FFE61CE6FB663C66FF661CE7FFE7FFE73866DF673EE6DDE73DE7FFE0000
+E988:00007FFE61CE6FB663C66FF661CE7FFE7FFE73CE6DB673CE6DB673CE7FFE0000
+E989:00007FFE61CE6FB663C66FF661CE7FFE7FFE73CE6DB673C66DF673CE7FFE0000
+E98A:00007FFE61CE6FB663C66FF661CE7FFE7FFE73866DB673866DB673B67FFE0000
+E98B:00007FFE61CE6FB663C66FF661CE7FFE7FFE738E6DB6738E6DB6738E7FFE0000
+E98C:00007FFE61CE6FB663C66FF661CE7FFE7FFE73C66DBE73BE6DBE73C67FFE0000
+E98D:00007FFE61CE6FB663C66FF661CE7FFE7FFE738E6DB673B66DB6738E7FFE0000
+E98E:00007FFE61CE6FB663C66FF661CE7FFE7FFE73866DBE738E6DBE73867FFE0000
+E98F:00007FFE61CE6FB663C66FF661CE7FFE7FFE73866DBE738E6DBE73BE7FFE0000
+E990:00007FFE61CE6FB663C66FF661CE7FFE7FFE73CE6DB671B67DB673CE7FFE0000
+E991:00007FFE61CE6FB663C66FF661CE7FFE7FFE73EE6DCE71EE7DEE73C67FFE0000
+E992:00007FFE61CE6FB663C66FF661CE7FFE7FFE73866DF671867DBE73867FFE0000
+E993:00007FFE61CE6FB663C66FF661CE7FFE7FFE738E6DF671C67DF6738E7FFE0000
+E994:00007FFE61CE6FB663C66FF661CE7FFE7FFE73B66DB671867DF673F67FFE0000
+E995:00007FFE61CE6FB663C66FF661CE7FFE7FFE73866DBE71867DF673867FFE0000
+E996:00007FFE61CE6FB663C66FF661CE7FFE7FFE73CE6DBE718E7DB673CE7FFE0000
+E997:00007FFE61CE6FB663C66FF661CE7FFE7FFE73866DF671EE7DDE73DE7FFE0000
+E998:00007FFE61CE6FB663C66FF661CE7FFE7FFE73CE6DB671CE7DB673CE7FFE0000
+E999:00007FFE61CE6FB663C66FF661CE7FFE7FFE73CE6DB671C67DF673CE7FFE0000
+E99A:00007FFE61CE6FB663C66FF661CE7FFE7FFE73866DB671867DB673B67FFE0000
+E99B:00007FFE61CE6FB663C66FF661CE7FFE7FFE738E6DB6718E7DB6738E7FFE0000
+E99C:00007FFE61CE6FB663C66FF661CE7FFE7FFE73C66DBE71BE7DBE73C67FFE0000
+E99D:00007FFE61CE6FB663C66FF661CE7FFE7FFE738E6DB671B67DB6738E7FFE0000
+E99E:00007FFE61CE6FB663C66FF661CE7FFE7FFE73866DBE718E7DBE73867FFE0000
+E99F:00007FFE61CE6FB663C66FF661CE7FFE7FFE73866DBE718E7DBE73BE7FFE0000
+E9A0:00007FFE61CE6FB663C66FF661CE7FFE7FFE61CE6DB661B66DB66DCE7FFE0000
+E9A1:00007FFE61CE6FB663C66FF661CE7FFE7FFE61EE6DCE61EE6DEE6DC67FFE0000
+E9A2:00007FFE61CE6FB663C66FF661CE7FFE7FFE61866DF661866DBE6D867FFE0000
+E9A3:00007FFE61CE6FB663C66FF661CE7FFE7FFE618E6DF661C66DF66D8E7FFE0000
+E9A4:00007FFE61CE6FB663C66FF661CE7FFE7FFE61B66DB661866DF66DF67FFE0000
+E9A5:00007FFE61CE6FB663C66FF661CE7FFE7FFE61866DBE61866DF66D867FFE0000
+E9A6:00007FFE61CE6FB663C66FF661CE7FFE7FFE61CE6DBE618E6DB66DCE7FFE0000
+E9A7:00007FFE61CE6FB663C66FF661CE7FFE7FFE61866DF661EE6DDE6DDE7FFE0000
+E9A8:00007FFE61CE6FB663C66FF661CE7FFE7FFE61CE6DB661CE6DB66DCE7FFE0000
+E9A9:00007FFE61CE6FB663C66FF661CE7FFE7FFE61CE6DB661C66DF66DCE7FFE0000
+E9AA:00007FFE61CE6FB663C66FF661CE7FFE7FFE61866DB661866DB66DB67FFE0000
+E9AB:00007FFE61CE6FB663C66FF661CE7FFE7FFE618E6DB6618E6DB66D8E7FFE0000
+E9AC:00007FFE61CE6FB663C66FF661CE7FFE7FFE61C66DBE61BE6DBE6DC67FFE0000
+E9AD:00007FFE61CE6FB663C66FF661CE7FFE7FFE618E6DB661B66DB66D8E7FFE0000
+E9AE:00007FFE61CE6FB663C66FF661CE7FFE7FFE61866DBE618E6DBE6D867FFE0000
+E9AF:00007FFE61CE6FB663C66FF661CE7FFE7FFE61866DBE618E6DBE6DBE7FFE0000
+E9B0:00007FFE61CE6FB663C66FF661CE7FFE7FFE63CE6DB663B66DB663CE7FFE0000
+E9B1:00007FFE61CE6FB663C66FF661CE7FFE7FFE63EE6DCE63EE6DEE63C67FFE0000
+E9B2:00007FFE61CE6FB663C66FF661CE7FFE7FFE63866DF663866DBE63867FFE0000
+E9B3:00007FFE61CE6FB663C66FF661CE7FFE7FFE638E6DF663C66DF6638E7FFE0000
+E9B4:00007FFE61CE6FB663C66FF661CE7FFE7FFE63B66DB663866DF663F67FFE0000
+E9B5:00007FFE61CE6FB663C66FF661CE7FFE7FFE63866DBE63866DF663867FFE0000
+E9B6:00007FFE61CE6FB663C66FF661CE7FFE7FFE63CE6DBE638E6DB663CE7FFE0000
+E9B7:00007FFE61CE6FB663C66FF661CE7FFE7FFE63866DF663EE6DDE63DE7FFE0000
+E9B8:00007FFE61CE6FB663C66FF661CE7FFE7FFE63CE6DB663CE6DB663CE7FFE0000
+E9B9:00007FFE61CE6FB663C66FF661CE7FFE7FFE63CE6DB663C66DF663CE7FFE0000
+E9BA:00007FFE61CE6FB663C66FF661CE7FFE7FFE63866DB663866DB663B67FFE0000
+E9BB:00007FFE61CE6FB663C66FF661CE7FFE7FFE638E6DB6638E6DB6638E7FFE0000
+E9BC:00007FFE61CE6FB663C66FF661CE7FFE7FFE63C66DBE63BE6DBE63C67FFE0000
+E9BD:00007FFE61CE6FB663C66FF661CE7FFE7FFE638E6DB663B66DB6638E7FFE0000
+E9BE:00007FFE61CE6FB663C66FF661CE7FFE7FFE63866DBE638E6DBE63867FFE0000
+E9BF:00007FFE61CE6FB663C66FF661CE7FFE7FFE63866DBE638E6DBE63BE7FFE0000
+E9C0:00007FFE61CE6FB663C66FF661CE7FFE7FFE71CE6FB66FB66FB671CE7FFE0000
+E9C1:00007FFE61CE6FB663C66FF661CE7FFE7FFE71EE6FCE6FEE6FEE71C67FFE0000
+E9C2:00007FFE61CE6FB663C66FF661CE7FFE7FFE71866FF66F866FBE71867FFE0000
+E9C3:00007FFE61CE6FB663C66FF661CE7FFE7FFE718E6FF66FC66FF6718E7FFE0000
+E9C4:00007FFE61CE6FB663C66FF661CE7FFE7FFE71B66FB66F866FF671F67FFE0000
+E9C5:00007FFE61CE6FB663C66FF661CE7FFE7FFE71866FBE6F866FF671867FFE0000
+E9C6:00007FFE61CE6FB663C66FF661CE7FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000
+E9C7:00007FFE61CE6FB663C66FF661CE7FFE7FFE71866FF66FEE6FDE71DE7FFE0000
+E9C8:00007FFE61CE6FB663C66FF661CE7FFE7FFE71CE6FB66FCE6FB671CE7FFE0000
+E9C9:00007FFE61CE6FB663C66FF661CE7FFE7FFE71CE6FB66FC66FF671CE7FFE0000
+E9CA:00007FFE61CE6FB663C66FF661CE7FFE7FFE71866FB66F866FB671B67FFE0000
+E9CB:00007FFE61CE6FB663C66FF661CE7FFE7FFE718E6FB66F8E6FB6718E7FFE0000
+E9CC:00007FFE61CE6FB663C66FF661CE7FFE7FFE71C66FBE6FBE6FBE71C67FFE0000
+E9CD:00007FFE61CE6FB663C66FF661CE7FFE7FFE718E6FB66FB66FB6718E7FFE0000
+E9CE:00007FFE61CE6FB663C66FF661CE7FFE7FFE71866FBE6F8E6FBE71867FFE0000
+E9CF:00007FFE61CE6FB663C66FF661CE7FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+E9D0:00007FFE61CE6FB663C66FF661CE7FFE7FFE63CE6DB66DB66DB663CE7FFE0000
+E9D1:00007FFE61CE6FB663C66FF661CE7FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000
+E9D2:00007FFE61CE6FB663C66FF661CE7FFE7FFE63866DF66D866DBE63867FFE0000
+E9D3:00007FFE61CE6FB663C66FF661CE7FFE7FFE638E6DF66DC66DF6638E7FFE0000
+E9D4:00007FFE61CE6FB663C66FF661CE7FFE7FFE63B66DB66D866DF663F67FFE0000
+E9D5:00007FFE61CE6FB663C66FF661CE7FFE7FFE63866DBE6D866DF663867FFE0000
+E9D6:00007FFE61CE6FB663C66FF661CE7FFE7FFE63CE6DBE6D8E6DB663CE7FFE0000
+E9D7:00007FFE61CE6FB663C66FF661CE7FFE7FFE63866DF66DEE6DDE63DE7FFE0000
+E9D8:00007FFE61CE6FB663C66FF661CE7FFE7FFE63CE6DB66DCE6DB663CE7FFE0000
+E9D9:00007FFE61CE6FB663C66FF661CE7FFE7FFE63CE6DB66DC66DF663CE7FFE0000
+E9DA:00007FFE61CE6FB663C66FF661CE7FFE7FFE63866DB66D866DB663B67FFE0000
+E9DB:00007FFE61CE6FB663C66FF661CE7FFE7FFE638E6DB66D8E6DB6638E7FFE0000
+E9DC:00007FFE61CE6FB663C66FF661CE7FFE7FFE63C66DBE6DBE6DBE63C67FFE0000
+E9DD:00007FFE61CE6FB663C66FF661CE7FFE7FFE638E6DB66DB66DB6638E7FFE0000
+E9DE:00007FFE61CE6FB663C66FF661CE7FFE7FFE63866DBE6D8E6DBE63867FFE0000
+E9DF:00007FFE61CE6FB663C66FF661CE7FFE7FFE63866DBE6D8E6DBE63BE7FFE0000
+E9E0:00007FFE61CE6FB663C66FF661CE7FFE7FFE61CE6FB663B66FB661CE7FFE0000
+E9E1:00007FFE61CE6FB663C66FF661CE7FFE7FFE61EE6FCE63EE6FEE61C67FFE0000
+E9E2:00007FFE61CE6FB663C66FF661CE7FFE7FFE61866FF663866FBE61867FFE0000
+E9E3:00007FFE61CE6FB663C66FF661CE7FFE7FFE618E6FF663C66FF6618E7FFE0000
+E9E4:00007FFE61CE6FB663C66FF661CE7FFE7FFE61B66FB663866FF661F67FFE0000
+E9E5:00007FFE61CE6FB663C66FF661CE7FFE7FFE61866FBE63866FF661867FFE0000
+E9E6:00007FFE61CE6FB663C66FF661CE7FFE7FFE61CE6FBE638E6FB661CE7FFE0000
+E9E7:00007FFE61CE6FB663C66FF661CE7FFE7FFE61866FF663EE6FDE61DE7FFE0000
+E9E8:00007FFE61CE6FB663C66FF661CE7FFE7FFE61CE6FB663CE6FB661CE7FFE0000
+E9E9:00007FFE61CE6FB663C66FF661CE7FFE7FFE61CE6FB663C66FF661CE7FFE0000
+E9EA:00007FFE61CE6FB663C66FF661CE7FFE7FFE61866FB663866FB661B67FFE0000
+E9EB:00007FFE61CE6FB663C66FF661CE7FFE7FFE618E6FB6638E6FB6618E7FFE0000
+E9EC:00007FFE61CE6FB663C66FF661CE7FFE7FFE61C66FBE63BE6FBE61C67FFE0000
+E9ED:00007FFE61CE6FB663C66FF661CE7FFE7FFE618E6FB663B66FB6618E7FFE0000
+E9EE:00007FFE61CE6FB663C66FF661CE7FFE7FFE61866FBE638E6FBE61867FFE0000
+E9EF:00007FFE61CE6FB663C66FF661CE7FFE7FFE61866FBE638E6FBE61BE7FFE0000
+E9F0:00007FFE61CE6FB663C66FF661CE7FFE7FFE61CE6FB663B66FB66FCE7FFE0000
+E9F1:00007FFE61CE6FB663C66FF661CE7FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000
+E9F2:00007FFE61CE6FB663C66FF661CE7FFE7FFE61866FF663866FBE6F867FFE0000
+E9F3:00007FFE61CE6FB663C66FF661CE7FFE7FFE618E6FF663C66FF66F8E7FFE0000
+E9F4:00007FFE61CE6FB663C66FF661CE7FFE7FFE61B66FB663866FF66FF67FFE0000
+E9F5:00007FFE61CE6FB663C66FF661CE7FFE7FFE61866FBE63866FF66F867FFE0000
+E9F6:00007FFE61CE6FB663C66FF661CE7FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+E9F7:00007FFE61CE6FB663C66FF661CE7FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+E9F8:00007FFE61CE6FB663C66FF661CE7FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+E9F9:00007FFE61CE6FB663C66FF661CE7FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+E9FA:00007FFE61CE6FB663C66FF661CE7FFE7FFE61866FB663866FB66FB67FFE0000
+E9FB:00007FFE61CE6FB663C66FF661CE7FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+E9FC:00007FFE61CE6FB663C66FF661CE7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+E9FD:00007FFE61CE6FB663C66FF661CE7FFE7FFE618E6FB663B66FB66F8E7FFE0000
+E9FE:00007FFE61CE6FB663C66FF661CE7FFE7FFE61866FBE638E6FBE6F867FFE0000
+E9FF:00007FFE61CE6FB663C66FF661CE7FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+EA00:00007FFE61866FB663866FB661B67FFE7FFE73CE6DB66DB66DB673CE7FFE0000
+EA01:00007FFE61866FB663866FB661B67FFE7FFE73EE6DCE6DEE6DEE73C67FFE0000
+EA02:00007FFE61866FB663866FB661B67FFE7FFE73866DF66D866DBE73867FFE0000
+EA03:00007FFE61866FB663866FB661B67FFE7FFE738E6DF66DC66DF6738E7FFE0000
+EA04:00007FFE61866FB663866FB661B67FFE7FFE73B66DB66D866DF673F67FFE0000
+EA05:00007FFE61866FB663866FB661B67FFE7FFE73866DBE6D866DF673867FFE0000
+EA06:00007FFE61866FB663866FB661B67FFE7FFE73CE6DBE6D8E6DB673CE7FFE0000
+EA07:00007FFE61866FB663866FB661B67FFE7FFE73866DF66DEE6DDE73DE7FFE0000
+EA08:00007FFE61866FB663866FB661B67FFE7FFE73CE6DB66DCE6DB673CE7FFE0000
+EA09:00007FFE61866FB663866FB661B67FFE7FFE73CE6DB66DC66DF673CE7FFE0000
+EA0A:00007FFE61866FB663866FB661B67FFE7FFE73866DB66D866DB673B67FFE0000
+EA0B:00007FFE61866FB663866FB661B67FFE7FFE738E6DB66D8E6DB6738E7FFE0000
+EA0C:00007FFE61866FB663866FB661B67FFE7FFE73C66DBE6DBE6DBE73C67FFE0000
+EA0D:00007FFE61866FB663866FB661B67FFE7FFE738E6DB66DB66DB6738E7FFE0000
+EA0E:00007FFE61866FB663866FB661B67FFE7FFE73866DBE6D8E6DBE73867FFE0000
+EA0F:00007FFE61866FB663866FB661B67FFE7FFE73866DBE6D8E6DBE73BE7FFE0000
+EA10:00007FFE61866FB663866FB661B67FFE7FFE7BCE73B67BB67BB671CE7FFE0000
+EA11:00007FFE61866FB663866FB661B67FFE7FFE7BEE73CE7BEE7BEE71C67FFE0000
+EA12:00007FFE61866FB663866FB661B67FFE7FFE7B8673F67B867BBE71867FFE0000
+EA13:00007FFE61866FB663866FB661B67FFE7FFE7B8E73F67BC67BF6718E7FFE0000
+EA14:00007FFE61866FB663866FB661B67FFE7FFE7BB673B67B867BF671F67FFE0000
+EA15:00007FFE61866FB663866FB661B67FFE7FFE7B8673BE7B867BF671867FFE0000
+EA16:00007FFE61866FB663866FB661B67FFE7FFE7BCE73BE7B8E7BB671CE7FFE0000
+EA17:00007FFE61866FB663866FB661B67FFE7FFE7B8673F67BEE7BDE71DE7FFE0000
+EA18:00007FFE61866FB663866FB661B67FFE7FFE7BCE73B67BCE7BB671CE7FFE0000
+EA19:00007FFE61866FB663866FB661B67FFE7FFE7BCE73B67BC67BF671CE7FFE0000
+EA1A:00007FFE61866FB663866FB661B67FFE7FFE7B8673B67B867BB671B67FFE0000
+EA1B:00007FFE61866FB663866FB661B67FFE7FFE7B8E73B67B8E7BB6718E7FFE0000
+EA1C:00007FFE61866FB663866FB661B67FFE7FFE7BC673BE7BBE7BBE71C67FFE0000
+EA1D:00007FFE61866FB663866FB661B67FFE7FFE7B8E73B67BB67BB6718E7FFE0000
+EA1E:00007FFE61866FB663866FB661B67FFE7FFE7B8673BE7B8E7BBE71867FFE0000
+EA1F:00007FFE61866FB663866FB661B67FFE7FFE7B8673BE7B8E7BBE71BE7FFE0000
+EA20:00007FFE61866FB663866FB661B67FFE7FFE61CE7DB661B66FB661CE7FFE0000
+EA21:00007FFE61866FB663866FB661B67FFE7FFE61EE7DCE61EE6FEE61C67FFE0000
+EA22:00007FFE61866FB663866FB661B67FFE7FFE61867DF661866FBE61867FFE0000
+EA23:00007FFE61866FB663866FB661B67FFE7FFE618E7DF661C66FF6618E7FFE0000
+EA24:00007FFE61866FB663866FB661B67FFE7FFE61B67DB661866FF661F67FFE0000
+EA25:00007FFE61866FB663866FB661B67FFE7FFE61867DBE61866FF661867FFE0000
+EA26:00007FFE61866FB663866FB661B67FFE7FFE61CE7DBE618E6FB661CE7FFE0000
+EA27:00007FFE61866FB663866FB661B67FFE7FFE61867DF661EE6FDE61DE7FFE0000
+EA28:00007FFE61866FB663866FB661B67FFE7FFE61CE7DB661CE6FB661CE7FFE0000
+EA29:00007FFE61866FB663866FB661B67FFE7FFE61CE7DB661C66FF661CE7FFE0000
+EA2A:00007FFE61866FB663866FB661B67FFE7FFE61867DB661866FB661B67FFE0000
+EA2B:00007FFE61866FB663866FB661B67FFE7FFE618E7DB6618E6FB6618E7FFE0000
+EA2C:00007FFE61866FB663866FB661B67FFE7FFE61C67DBE61BE6FBE61C67FFE0000
+EA2D:00007FFE61866FB663866FB661B67FFE7FFE618E7DB661B66FB6618E7FFE0000
+EA2E:00007FFE61866FB663866FB661B67FFE7FFE61867DBE618E6FBE61867FFE0000
+EA2F:00007FFE61866FB663866FB661B67FFE7FFE61867DBE618E6FBE61BE7FFE0000
+EA30:00007FFE61866FB663866FB661B67FFE7FFE63CE7DB671B67DB663CE7FFE0000
+EA31:00007FFE61866FB663866FB661B67FFE7FFE63EE7DCE71EE7DEE63C67FFE0000
+EA32:00007FFE61866FB663866FB661B67FFE7FFE63867DF671867DBE63867FFE0000
+EA33:00007FFE61866FB663866FB661B67FFE7FFE638E7DF671C67DF6638E7FFE0000
+EA34:00007FFE61866FB663866FB661B67FFE7FFE63B67DB671867DF663F67FFE0000
+EA35:00007FFE61866FB663866FB661B67FFE7FFE63867DBE71867DF663867FFE0000
+EA36:00007FFE61866FB663866FB661B67FFE7FFE63CE7DBE718E7DB663CE7FFE0000
+EA37:00007FFE61866FB663866FB661B67FFE7FFE63867DF671EE7DDE63DE7FFE0000
+EA38:00007FFE61866FB663866FB661B67FFE7FFE63CE7DB671CE7DB663CE7FFE0000
+EA39:00007FFE61866FB663866FB661B67FFE7FFE63CE7DB671C67DF663CE7FFE0000
+EA3A:00007FFE61866FB663866FB661B67FFE7FFE63867DB671867DB663B67FFE0000
+EA3B:00007FFE61866FB663866FB661B67FFE7FFE638E7DB6718E7DB6638E7FFE0000
+EA3C:00007FFE61866FB663866FB661B67FFE7FFE63C67DBE71BE7DBE63C67FFE0000
+EA3D:00007FFE61866FB663866FB661B67FFE7FFE638E7DB671B67DB6638E7FFE0000
+EA3E:00007FFE61866FB663866FB661B67FFE7FFE63867DBE718E7DBE63867FFE0000
+EA3F:00007FFE61866FB663866FB661B67FFE7FFE63867DBE718E7DBE63BE7FFE0000
+EA40:00007FFE61866FB663866FB661B67FFE7FFE6DCE6DB661B67DB67DCE7FFE0000
+EA41:00007FFE61866FB663866FB661B67FFE7FFE6DEE6DCE61EE7DEE7DC67FFE0000
+EA42:00007FFE61866FB663866FB661B67FFE7FFE6D866DF661867DBE7D867FFE0000
+EA43:00007FFE61866FB663866FB661B67FFE7FFE6D8E6DF661C67DF67D8E7FFE0000
+EA44:00007FFE61866FB663866FB661B67FFE7FFE6DB66DB661867DF67DF67FFE0000
+EA45:00007FFE61866FB663866FB661B67FFE7FFE6D866DBE61867DF67D867FFE0000
+EA46:00007FFE61866FB663866FB661B67FFE7FFE6DCE6DBE618E7DB67DCE7FFE0000
+EA47:00007FFE61866FB663866FB661B67FFE7FFE6D866DF661EE7DDE7DDE7FFE0000
+EA48:00007FFE61866FB663866FB661B67FFE7FFE6DCE6DB661CE7DB67DCE7FFE0000
+EA49:00007FFE61866FB663866FB661B67FFE7FFE6DCE6DB661C67DF67DCE7FFE0000
+EA4A:00007FFE61866FB663866FB661B67FFE7FFE6D866DB661867DB67DB67FFE0000
+EA4B:00007FFE61866FB663866FB661B67FFE7FFE6D8E6DB6618E7DB67D8E7FFE0000
+EA4C:00007FFE61866FB663866FB661B67FFE7FFE6DC66DBE61BE7DBE7DC67FFE0000
+EA4D:00007FFE61866FB663866FB661B67FFE7FFE6D8E6DB661B67DB67D8E7FFE0000
+EA4E:00007FFE61866FB663866FB661B67FFE7FFE6D866DBE618E7DBE7D867FFE0000
+EA4F:00007FFE61866FB663866FB661B67FFE7FFE6D866DBE618E7DBE7DBE7FFE0000
+EA50:00007FFE61866FB663866FB661B67FFE7FFE61CE6FB661B67DB661CE7FFE0000
+EA51:00007FFE61866FB663866FB661B67FFE7FFE61EE6FCE61EE7DEE61C67FFE0000
+EA52:00007FFE61866FB663866FB661B67FFE7FFE61866FF661867DBE61867FFE0000
+EA53:00007FFE61866FB663866FB661B67FFE7FFE618E6FF661C67DF6618E7FFE0000
+EA54:00007FFE61866FB663866FB661B67FFE7FFE61B66FB661867DF661F67FFE0000
+EA55:00007FFE61866FB663866FB661B67FFE7FFE61866FBE61867DF661867FFE0000
+EA56:00007FFE61866FB663866FB661B67FFE7FFE61CE6FBE618E7DB661CE7FFE0000
+EA57:00007FFE61866FB663866FB661B67FFE7FFE61866FF661EE7DDE61DE7FFE0000
+EA58:00007FFE61866FB663866FB661B67FFE7FFE61CE6FB661CE7DB661CE7FFE0000
+EA59:00007FFE61866FB663866FB661B67FFE7FFE61CE6FB661C67DF661CE7FFE0000
+EA5A:00007FFE61866FB663866FB661B67FFE7FFE61866FB661867DB661B67FFE0000
+EA5B:00007FFE61866FB663866FB661B67FFE7FFE618E6FB6618E7DB6618E7FFE0000
+EA5C:00007FFE61866FB663866FB661B67FFE7FFE61C66FBE61BE7DBE61C67FFE0000
+EA5D:00007FFE61866FB663866FB661B67FFE7FFE618E6FB661B67DB6618E7FFE0000
+EA5E:00007FFE61866FB663866FB661B67FFE7FFE61866FBE618E7DBE61867FFE0000
+EA5F:00007FFE61866FB663866FB661B67FFE7FFE61866FBE618E7DBE61BE7FFE0000
+EA60:00007FFE61866FB663866FB661B67FFE7FFE73CE6FB663B66DB673CE7FFE0000
+EA61:00007FFE61866FB663866FB661B67FFE7FFE73EE6FCE63EE6DEE73C67FFE0000
+EA62:00007FFE61866FB663866FB661B67FFE7FFE73866FF663866DBE73867FFE0000
+EA63:00007FFE61866FB663866FB661B67FFE7FFE738E6FF663C66DF6738E7FFE0000
+EA64:00007FFE61866FB663866FB661B67FFE7FFE73B66FB663866DF673F67FFE0000
+EA65:00007FFE61866FB663866FB661B67FFE7FFE73866FBE63866DF673867FFE0000
+EA66:00007FFE61866FB663866FB661B67FFE7FFE73CE6FBE638E6DB673CE7FFE0000
+EA67:00007FFE61866FB663866FB661B67FFE7FFE73866FF663EE6DDE73DE7FFE0000
+EA68:00007FFE61866FB663866FB661B67FFE7FFE73CE6FB663CE6DB673CE7FFE0000
+EA69:00007FFE61866FB663866FB661B67FFE7FFE73CE6FB663C66DF673CE7FFE0000
+EA6A:00007FFE61866FB663866FB661B67FFE7FFE73866FB663866DB673B67FFE0000
+EA6B:00007FFE61866FB663866FB661B67FFE7FFE738E6FB6638E6DB6738E7FFE0000
+EA6C:00007FFE61866FB663866FB661B67FFE7FFE73C66FBE63BE6DBE73C67FFE0000
+EA6D:00007FFE61866FB663866FB661B67FFE7FFE738E6FB663B66DB6738E7FFE0000
+EA6E:00007FFE61866FB663866FB661B67FFE7FFE73866FBE638E6DBE73867FFE0000
+EA6F:00007FFE61866FB663866FB661B67FFE7FFE73866FBE638E6DBE73BE7FFE0000
+EA70:00007FFE61866FB663866FB661B67FFE7FFE61CE7DB67BB677B677CE7FFE0000
+EA71:00007FFE61866FB663866FB661B67FFE7FFE61EE7DCE7BEE77EE77C67FFE0000
+EA72:00007FFE61866FB663866FB661B67FFE7FFE61867DF67B8677BE77867FFE0000
+EA73:00007FFE61866FB663866FB661B67FFE7FFE618E7DF67BC677F6778E7FFE0000
+EA74:00007FFE61866FB663866FB661B67FFE7FFE61B67DB67B8677F677F67FFE0000
+EA75:00007FFE61866FB663866FB661B67FFE7FFE61867DBE7B8677F677867FFE0000
+EA76:00007FFE61866FB663866FB661B67FFE7FFE61CE7DBE7B8E77B677CE7FFE0000
+EA77:00007FFE61866FB663866FB661B67FFE7FFE61867DF67BEE77DE77DE7FFE0000
+EA78:00007FFE61866FB663866FB661B67FFE7FFE61CE7DB67BCE77B677CE7FFE0000
+EA79:00007FFE61866FB663866FB661B67FFE7FFE61CE7DB67BC677F677CE7FFE0000
+EA7A:00007FFE61866FB663866FB661B67FFE7FFE61867DB67B8677B677B67FFE0000
+EA7B:00007FFE61866FB663866FB661B67FFE7FFE618E7DB67B8E77B6778E7FFE0000
+EA7C:00007FFE61866FB663866FB661B67FFE7FFE61C67DBE7BBE77BE77C67FFE0000
+EA7D:00007FFE61866FB663866FB661B67FFE7FFE618E7DB67BB677B6778E7FFE0000
+EA7E:00007FFE61866FB663866FB661B67FFE7FFE61867DBE7B8E77BE77867FFE0000
+EA7F:00007FFE61866FB663866FB661B67FFE7FFE61867DBE7B8E77BE77BE7FFE0000
+EA80:00007FFE61866FB663866FB661B67FFE7FFE73CE6DB673B66DB673CE7FFE0000
+EA81:00007FFE61866FB663866FB661B67FFE7FFE73EE6DCE73EE6DEE73C67FFE0000
+EA82:00007FFE61866FB663866FB661B67FFE7FFE73866DF673866DBE73867FFE0000
+EA83:00007FFE61866FB663866FB661B67FFE7FFE738E6DF673C66DF6738E7FFE0000
+EA84:00007FFE61866FB663866FB661B67FFE7FFE73B66DB673866DF673F67FFE0000
+EA85:00007FFE61866FB663866FB661B67FFE7FFE73866DBE73866DF673867FFE0000
+EA86:00007FFE61866FB663866FB661B67FFE7FFE73CE6DBE738E6DB673CE7FFE0000
+EA87:00007FFE61866FB663866FB661B67FFE7FFE73866DF673EE6DDE73DE7FFE0000
+EA88:00007FFE61866FB663866FB661B67FFE7FFE73CE6DB673CE6DB673CE7FFE0000
+EA89:00007FFE61866FB663866FB661B67FFE7FFE73CE6DB673C66DF673CE7FFE0000
+EA8A:00007FFE61866FB663866FB661B67FFE7FFE73866DB673866DB673B67FFE0000
+EA8B:00007FFE61866FB663866FB661B67FFE7FFE738E6DB6738E6DB6738E7FFE0000
+EA8C:00007FFE61866FB663866FB661B67FFE7FFE73C66DBE73BE6DBE73C67FFE0000
+EA8D:00007FFE61866FB663866FB661B67FFE7FFE738E6DB673B66DB6738E7FFE0000
+EA8E:00007FFE61866FB663866FB661B67FFE7FFE73866DBE738E6DBE73867FFE0000
+EA8F:00007FFE61866FB663866FB661B67FFE7FFE73866DBE738E6DBE73BE7FFE0000
+EA90:00007FFE61866FB663866FB661B67FFE7FFE73CE6DB671B67DB673CE7FFE0000
+EA91:00007FFE61866FB663866FB661B67FFE7FFE73EE6DCE71EE7DEE73C67FFE0000
+EA92:00007FFE61866FB663866FB661B67FFE7FFE73866DF671867DBE73867FFE0000
+EA93:00007FFE61866FB663866FB661B67FFE7FFE738E6DF671C67DF6738E7FFE0000
+EA94:00007FFE61866FB663866FB661B67FFE7FFE73B66DB671867DF673F67FFE0000
+EA95:00007FFE61866FB663866FB661B67FFE7FFE73866DBE71867DF673867FFE0000
+EA96:00007FFE61866FB663866FB661B67FFE7FFE73CE6DBE718E7DB673CE7FFE0000
+EA97:00007FFE61866FB663866FB661B67FFE7FFE73866DF671EE7DDE73DE7FFE0000
+EA98:00007FFE61866FB663866FB661B67FFE7FFE73CE6DB671CE7DB673CE7FFE0000
+EA99:00007FFE61866FB663866FB661B67FFE7FFE73CE6DB671C67DF673CE7FFE0000
+EA9A:00007FFE61866FB663866FB661B67FFE7FFE73866DB671867DB673B67FFE0000
+EA9B:00007FFE61866FB663866FB661B67FFE7FFE738E6DB6718E7DB6738E7FFE0000
+EA9C:00007FFE61866FB663866FB661B67FFE7FFE73C66DBE71BE7DBE73C67FFE0000
+EA9D:00007FFE61866FB663866FB661B67FFE7FFE738E6DB671B67DB6738E7FFE0000
+EA9E:00007FFE61866FB663866FB661B67FFE7FFE73866DBE718E7DBE73867FFE0000
+EA9F:00007FFE61866FB663866FB661B67FFE7FFE73866DBE718E7DBE73BE7FFE0000
+EAA0:00007FFE61866FB663866FB661B67FFE7FFE61CE6DB661B66DB66DCE7FFE0000
+EAA1:00007FFE61866FB663866FB661B67FFE7FFE61EE6DCE61EE6DEE6DC67FFE0000
+EAA2:00007FFE61866FB663866FB661B67FFE7FFE61866DF661866DBE6D867FFE0000
+EAA3:00007FFE61866FB663866FB661B67FFE7FFE618E6DF661C66DF66D8E7FFE0000
+EAA4:00007FFE61866FB663866FB661B67FFE7FFE61B66DB661866DF66DF67FFE0000
+EAA5:00007FFE61866FB663866FB661B67FFE7FFE61866DBE61866DF66D867FFE0000
+EAA6:00007FFE61866FB663866FB661B67FFE7FFE61CE6DBE618E6DB66DCE7FFE0000
+EAA7:00007FFE61866FB663866FB661B67FFE7FFE61866DF661EE6DDE6DDE7FFE0000
+EAA8:00007FFE61866FB663866FB661B67FFE7FFE61CE6DB661CE6DB66DCE7FFE0000
+EAA9:00007FFE61866FB663866FB661B67FFE7FFE61CE6DB661C66DF66DCE7FFE0000
+EAAA:00007FFE61866FB663866FB661B67FFE7FFE61866DB661866DB66DB67FFE0000
+EAAB:00007FFE61866FB663866FB661B67FFE7FFE618E6DB6618E6DB66D8E7FFE0000
+EAAC:00007FFE61866FB663866FB661B67FFE7FFE61C66DBE61BE6DBE6DC67FFE0000
+EAAD:00007FFE61866FB663866FB661B67FFE7FFE618E6DB661B66DB66D8E7FFE0000
+EAAE:00007FFE61866FB663866FB661B67FFE7FFE61866DBE618E6DBE6D867FFE0000
+EAAF:00007FFE61866FB663866FB661B67FFE7FFE61866DBE618E6DBE6DBE7FFE0000
+EAB0:00007FFE61866FB663866FB661B67FFE7FFE63CE6DB663B66DB663CE7FFE0000
+EAB1:00007FFE61866FB663866FB661B67FFE7FFE63EE6DCE63EE6DEE63C67FFE0000
+EAB2:00007FFE61866FB663866FB661B67FFE7FFE63866DF663866DBE63867FFE0000
+EAB3:00007FFE61866FB663866FB661B67FFE7FFE638E6DF663C66DF6638E7FFE0000
+EAB4:00007FFE61866FB663866FB661B67FFE7FFE63B66DB663866DF663F67FFE0000
+EAB5:00007FFE61866FB663866FB661B67FFE7FFE63866DBE63866DF663867FFE0000
+EAB6:00007FFE61866FB663866FB661B67FFE7FFE63CE6DBE638E6DB663CE7FFE0000
+EAB7:00007FFE61866FB663866FB661B67FFE7FFE63866DF663EE6DDE63DE7FFE0000
+EAB8:00007FFE61866FB663866FB661B67FFE7FFE63CE6DB663CE6DB663CE7FFE0000
+EAB9:00007FFE61866FB663866FB661B67FFE7FFE63CE6DB663C66DF663CE7FFE0000
+EABA:00007FFE61866FB663866FB661B67FFE7FFE63866DB663866DB663B67FFE0000
+EABB:00007FFE61866FB663866FB661B67FFE7FFE638E6DB6638E6DB6638E7FFE0000
+EABC:00007FFE61866FB663866FB661B67FFE7FFE63C66DBE63BE6DBE63C67FFE0000
+EABD:00007FFE61866FB663866FB661B67FFE7FFE638E6DB663B66DB6638E7FFE0000
+EABE:00007FFE61866FB663866FB661B67FFE7FFE63866DBE638E6DBE63867FFE0000
+EABF:00007FFE61866FB663866FB661B67FFE7FFE63866DBE638E6DBE63BE7FFE0000
+EAC0:00007FFE61866FB663866FB661B67FFE7FFE71CE6FB66FB66FB671CE7FFE0000
+EAC1:00007FFE61866FB663866FB661B67FFE7FFE71EE6FCE6FEE6FEE71C67FFE0000
+EAC2:00007FFE61866FB663866FB661B67FFE7FFE71866FF66F866FBE71867FFE0000
+EAC3:00007FFE61866FB663866FB661B67FFE7FFE718E6FF66FC66FF6718E7FFE0000
+EAC4:00007FFE61866FB663866FB661B67FFE7FFE71B66FB66F866FF671F67FFE0000
+EAC5:00007FFE61866FB663866FB661B67FFE7FFE71866FBE6F866FF671867FFE0000
+EAC6:00007FFE61866FB663866FB661B67FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000
+EAC7:00007FFE61866FB663866FB661B67FFE7FFE71866FF66FEE6FDE71DE7FFE0000
+EAC8:00007FFE61866FB663866FB661B67FFE7FFE71CE6FB66FCE6FB671CE7FFE0000
+EAC9:00007FFE61866FB663866FB661B67FFE7FFE71CE6FB66FC66FF671CE7FFE0000
+EACA:00007FFE61866FB663866FB661B67FFE7FFE71866FB66F866FB671B67FFE0000
+EACB:00007FFE61866FB663866FB661B67FFE7FFE718E6FB66F8E6FB6718E7FFE0000
+EACC:00007FFE61866FB663866FB661B67FFE7FFE71C66FBE6FBE6FBE71C67FFE0000
+EACD:00007FFE61866FB663866FB661B67FFE7FFE718E6FB66FB66FB6718E7FFE0000
+EACE:00007FFE61866FB663866FB661B67FFE7FFE71866FBE6F8E6FBE71867FFE0000
+EACF:00007FFE61866FB663866FB661B67FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+EAD0:00007FFE61866FB663866FB661B67FFE7FFE63CE6DB66DB66DB663CE7FFE0000
+EAD1:00007FFE61866FB663866FB661B67FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000
+EAD2:00007FFE61866FB663866FB661B67FFE7FFE63866DF66D866DBE63867FFE0000
+EAD3:00007FFE61866FB663866FB661B67FFE7FFE638E6DF66DC66DF6638E7FFE0000
+EAD4:00007FFE61866FB663866FB661B67FFE7FFE63B66DB66D866DF663F67FFE0000
+EAD5:00007FFE61866FB663866FB661B67FFE7FFE63866DBE6D866DF663867FFE0000
+EAD6:00007FFE61866FB663866FB661B67FFE7FFE63CE6DBE6D8E6DB663CE7FFE0000
+EAD7:00007FFE61866FB663866FB661B67FFE7FFE63866DF66DEE6DDE63DE7FFE0000
+EAD8:00007FFE61866FB663866FB661B67FFE7FFE63CE6DB66DCE6DB663CE7FFE0000
+EAD9:00007FFE61866FB663866FB661B67FFE7FFE63CE6DB66DC66DF663CE7FFE0000
+EADA:00007FFE61866FB663866FB661B67FFE7FFE63866DB66D866DB663B67FFE0000
+EADB:00007FFE61866FB663866FB661B67FFE7FFE638E6DB66D8E6DB6638E7FFE0000
+EADC:00007FFE61866FB663866FB661B67FFE7FFE63C66DBE6DBE6DBE63C67FFE0000
+EADD:00007FFE61866FB663866FB661B67FFE7FFE638E6DB66DB66DB6638E7FFE0000
+EADE:00007FFE61866FB663866FB661B67FFE7FFE63866DBE6D8E6DBE63867FFE0000
+EADF:00007FFE61866FB663866FB661B67FFE7FFE63866DBE6D8E6DBE63BE7FFE0000
+EAE0:00007FFE61866FB663866FB661B67FFE7FFE61CE6FB663B66FB661CE7FFE0000
+EAE1:00007FFE61866FB663866FB661B67FFE7FFE61EE6FCE63EE6FEE61C67FFE0000
+EAE2:00007FFE61866FB663866FB661B67FFE7FFE61866FF663866FBE61867FFE0000
+EAE3:00007FFE61866FB663866FB661B67FFE7FFE618E6FF663C66FF6618E7FFE0000
+EAE4:00007FFE61866FB663866FB661B67FFE7FFE61B66FB663866FF661F67FFE0000
+EAE5:00007FFE61866FB663866FB661B67FFE7FFE61866FBE63866FF661867FFE0000
+EAE6:00007FFE61866FB663866FB661B67FFE7FFE61CE6FBE638E6FB661CE7FFE0000
+EAE7:00007FFE61866FB663866FB661B67FFE7FFE61866FF663EE6FDE61DE7FFE0000
+EAE8:00007FFE61866FB663866FB661B67FFE7FFE61CE6FB663CE6FB661CE7FFE0000
+EAE9:00007FFE61866FB663866FB661B67FFE7FFE61CE6FB663C66FF661CE7FFE0000
+EAEA:00007FFE61866FB663866FB661B67FFE7FFE61866FB663866FB661B67FFE0000
+EAEB:00007FFE61866FB663866FB661B67FFE7FFE618E6FB6638E6FB6618E7FFE0000
+EAEC:00007FFE61866FB663866FB661B67FFE7FFE61C66FBE63BE6FBE61C67FFE0000
+EAED:00007FFE61866FB663866FB661B67FFE7FFE618E6FB663B66FB6618E7FFE0000
+EAEE:00007FFE61866FB663866FB661B67FFE7FFE61866FBE638E6FBE61867FFE0000
+EAEF:00007FFE61866FB663866FB661B67FFE7FFE61866FBE638E6FBE61BE7FFE0000
+EAF0:00007FFE61866FB663866FB661B67FFE7FFE61CE6FB663B66FB66FCE7FFE0000
+EAF1:00007FFE61866FB663866FB661B67FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000
+EAF2:00007FFE61866FB663866FB661B67FFE7FFE61866FF663866FBE6F867FFE0000
+EAF3:00007FFE61866FB663866FB661B67FFE7FFE618E6FF663C66FF66F8E7FFE0000
+EAF4:00007FFE61866FB663866FB661B67FFE7FFE61B66FB663866FF66FF67FFE0000
+EAF5:00007FFE61866FB663866FB661B67FFE7FFE61866FBE63866FF66F867FFE0000
+EAF6:00007FFE61866FB663866FB661B67FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+EAF7:00007FFE61866FB663866FB661B67FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+EAF8:00007FFE61866FB663866FB661B67FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+EAF9:00007FFE61866FB663866FB661B67FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+EAFA:00007FFE61866FB663866FB661B67FFE7FFE61866FB663866FB66FB67FFE0000
+EAFB:00007FFE61866FB663866FB661B67FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+EAFC:00007FFE61866FB663866FB661B67FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+EAFD:00007FFE61866FB663866FB661B67FFE7FFE618E6FB663B66FB66F8E7FFE0000
+EAFE:00007FFE61866FB663866FB661B67FFE7FFE61866FBE638E6FBE6F867FFE0000
+EAFF:00007FFE61866FB663866FB661B67FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+EB00:00007FFE618E6FB6638E6FB6618E7FFE7FFE73CE6DB66DB66DB673CE7FFE0000
+EB01:00007FFE618E6FB6638E6FB6618E7FFE7FFE73EE6DCE6DEE6DEE73C67FFE0000
+EB02:00007FFE618E6FB6638E6FB6618E7FFE7FFE73866DF66D866DBE73867FFE0000
+EB03:00007FFE618E6FB6638E6FB6618E7FFE7FFE738E6DF66DC66DF6738E7FFE0000
+EB04:00007FFE618E6FB6638E6FB6618E7FFE7FFE73B66DB66D866DF673F67FFE0000
+EB05:00007FFE618E6FB6638E6FB6618E7FFE7FFE73866DBE6D866DF673867FFE0000
+EB06:00007FFE618E6FB6638E6FB6618E7FFE7FFE73CE6DBE6D8E6DB673CE7FFE0000
+EB07:00007FFE618E6FB6638E6FB6618E7FFE7FFE73866DF66DEE6DDE73DE7FFE0000
+EB08:00007FFE618E6FB6638E6FB6618E7FFE7FFE73CE6DB66DCE6DB673CE7FFE0000
+EB09:00007FFE618E6FB6638E6FB6618E7FFE7FFE73CE6DB66DC66DF673CE7FFE0000
+EB0A:00007FFE618E6FB6638E6FB6618E7FFE7FFE73866DB66D866DB673B67FFE0000
+EB0B:00007FFE618E6FB6638E6FB6618E7FFE7FFE738E6DB66D8E6DB6738E7FFE0000
+EB0C:00007FFE618E6FB6638E6FB6618E7FFE7FFE73C66DBE6DBE6DBE73C67FFE0000
+EB0D:00007FFE618E6FB6638E6FB6618E7FFE7FFE738E6DB66DB66DB6738E7FFE0000
+EB0E:00007FFE618E6FB6638E6FB6618E7FFE7FFE73866DBE6D8E6DBE73867FFE0000
+EB0F:00007FFE618E6FB6638E6FB6618E7FFE7FFE73866DBE6D8E6DBE73BE7FFE0000
+EB10:00007FFE618E6FB6638E6FB6618E7FFE7FFE7BCE73B67BB67BB671CE7FFE0000
+EB11:00007FFE618E6FB6638E6FB6618E7FFE7FFE7BEE73CE7BEE7BEE71C67FFE0000
+EB12:00007FFE618E6FB6638E6FB6618E7FFE7FFE7B8673F67B867BBE71867FFE0000
+EB13:00007FFE618E6FB6638E6FB6618E7FFE7FFE7B8E73F67BC67BF6718E7FFE0000
+EB14:00007FFE618E6FB6638E6FB6618E7FFE7FFE7BB673B67B867BF671F67FFE0000
+EB15:00007FFE618E6FB6638E6FB6618E7FFE7FFE7B8673BE7B867BF671867FFE0000
+EB16:00007FFE618E6FB6638E6FB6618E7FFE7FFE7BCE73BE7B8E7BB671CE7FFE0000
+EB17:00007FFE618E6FB6638E6FB6618E7FFE7FFE7B8673F67BEE7BDE71DE7FFE0000
+EB18:00007FFE618E6FB6638E6FB6618E7FFE7FFE7BCE73B67BCE7BB671CE7FFE0000
+EB19:00007FFE618E6FB6638E6FB6618E7FFE7FFE7BCE73B67BC67BF671CE7FFE0000
+EB1A:00007FFE618E6FB6638E6FB6618E7FFE7FFE7B8673B67B867BB671B67FFE0000
+EB1B:00007FFE618E6FB6638E6FB6618E7FFE7FFE7B8E73B67B8E7BB6718E7FFE0000
+EB1C:00007FFE618E6FB6638E6FB6618E7FFE7FFE7BC673BE7BBE7BBE71C67FFE0000
+EB1D:00007FFE618E6FB6638E6FB6618E7FFE7FFE7B8E73B67BB67BB6718E7FFE0000
+EB1E:00007FFE618E6FB6638E6FB6618E7FFE7FFE7B8673BE7B8E7BBE71867FFE0000
+EB1F:00007FFE618E6FB6638E6FB6618E7FFE7FFE7B8673BE7B8E7BBE71BE7FFE0000
+EB20:00007FFE618E6FB6638E6FB6618E7FFE7FFE61CE7DB661B66FB661CE7FFE0000
+EB21:00007FFE618E6FB6638E6FB6618E7FFE7FFE61EE7DCE61EE6FEE61C67FFE0000
+EB22:00007FFE618E6FB6638E6FB6618E7FFE7FFE61867DF661866FBE61867FFE0000
+EB23:00007FFE618E6FB6638E6FB6618E7FFE7FFE618E7DF661C66FF6618E7FFE0000
+EB24:00007FFE618E6FB6638E6FB6618E7FFE7FFE61B67DB661866FF661F67FFE0000
+EB25:00007FFE618E6FB6638E6FB6618E7FFE7FFE61867DBE61866FF661867FFE0000
+EB26:00007FFE618E6FB6638E6FB6618E7FFE7FFE61CE7DBE618E6FB661CE7FFE0000
+EB27:00007FFE618E6FB6638E6FB6618E7FFE7FFE61867DF661EE6FDE61DE7FFE0000
+EB28:00007FFE618E6FB6638E6FB6618E7FFE7FFE61CE7DB661CE6FB661CE7FFE0000
+EB29:00007FFE618E6FB6638E6FB6618E7FFE7FFE61CE7DB661C66FF661CE7FFE0000
+EB2A:00007FFE618E6FB6638E6FB6618E7FFE7FFE61867DB661866FB661B67FFE0000
+EB2B:00007FFE618E6FB6638E6FB6618E7FFE7FFE618E7DB6618E6FB6618E7FFE0000
+EB2C:00007FFE618E6FB6638E6FB6618E7FFE7FFE61C67DBE61BE6FBE61C67FFE0000
+EB2D:00007FFE618E6FB6638E6FB6618E7FFE7FFE618E7DB661B66FB6618E7FFE0000
+EB2E:00007FFE618E6FB6638E6FB6618E7FFE7FFE61867DBE618E6FBE61867FFE0000
+EB2F:00007FFE618E6FB6638E6FB6618E7FFE7FFE61867DBE618E6FBE61BE7FFE0000
+EB30:00007FFE618E6FB6638E6FB6618E7FFE7FFE63CE7DB671B67DB663CE7FFE0000
+EB31:00007FFE618E6FB6638E6FB6618E7FFE7FFE63EE7DCE71EE7DEE63C67FFE0000
+EB32:00007FFE618E6FB6638E6FB6618E7FFE7FFE63867DF671867DBE63867FFE0000
+EB33:00007FFE618E6FB6638E6FB6618E7FFE7FFE638E7DF671C67DF6638E7FFE0000
+EB34:00007FFE618E6FB6638E6FB6618E7FFE7FFE63B67DB671867DF663F67FFE0000
+EB35:00007FFE618E6FB6638E6FB6618E7FFE7FFE63867DBE71867DF663867FFE0000
+EB36:00007FFE618E6FB6638E6FB6618E7FFE7FFE63CE7DBE718E7DB663CE7FFE0000
+EB37:00007FFE618E6FB6638E6FB6618E7FFE7FFE63867DF671EE7DDE63DE7FFE0000
+EB38:00007FFE618E6FB6638E6FB6618E7FFE7FFE63CE7DB671CE7DB663CE7FFE0000
+EB39:00007FFE618E6FB6638E6FB6618E7FFE7FFE63CE7DB671C67DF663CE7FFE0000
+EB3A:00007FFE618E6FB6638E6FB6618E7FFE7FFE63867DB671867DB663B67FFE0000
+EB3B:00007FFE618E6FB6638E6FB6618E7FFE7FFE638E7DB6718E7DB6638E7FFE0000
+EB3C:00007FFE618E6FB6638E6FB6618E7FFE7FFE63C67DBE71BE7DBE63C67FFE0000
+EB3D:00007FFE618E6FB6638E6FB6618E7FFE7FFE638E7DB671B67DB6638E7FFE0000
+EB3E:00007FFE618E6FB6638E6FB6618E7FFE7FFE63867DBE718E7DBE63867FFE0000
+EB3F:00007FFE618E6FB6638E6FB6618E7FFE7FFE63867DBE718E7DBE63BE7FFE0000
+EB40:00007FFE618E6FB6638E6FB6618E7FFE7FFE6DCE6DB661B67DB67DCE7FFE0000
+EB41:00007FFE618E6FB6638E6FB6618E7FFE7FFE6DEE6DCE61EE7DEE7DC67FFE0000
+EB42:00007FFE618E6FB6638E6FB6618E7FFE7FFE6D866DF661867DBE7D867FFE0000
+EB43:00007FFE618E6FB6638E6FB6618E7FFE7FFE6D8E6DF661C67DF67D8E7FFE0000
+EB44:00007FFE618E6FB6638E6FB6618E7FFE7FFE6DB66DB661867DF67DF67FFE0000
+EB45:00007FFE618E6FB6638E6FB6618E7FFE7FFE6D866DBE61867DF67D867FFE0000
+EB46:00007FFE618E6FB6638E6FB6618E7FFE7FFE6DCE6DBE618E7DB67DCE7FFE0000
+EB47:00007FFE618E6FB6638E6FB6618E7FFE7FFE6D866DF661EE7DDE7DDE7FFE0000
+EB48:00007FFE618E6FB6638E6FB6618E7FFE7FFE6DCE6DB661CE7DB67DCE7FFE0000
+EB49:00007FFE618E6FB6638E6FB6618E7FFE7FFE6DCE6DB661C67DF67DCE7FFE0000
+EB4A:00007FFE618E6FB6638E6FB6618E7FFE7FFE6D866DB661867DB67DB67FFE0000
+EB4B:00007FFE618E6FB6638E6FB6618E7FFE7FFE6D8E6DB6618E7DB67D8E7FFE0000
+EB4C:00007FFE618E6FB6638E6FB6618E7FFE7FFE6DC66DBE61BE7DBE7DC67FFE0000
+EB4D:00007FFE618E6FB6638E6FB6618E7FFE7FFE6D8E6DB661B67DB67D8E7FFE0000
+EB4E:00007FFE618E6FB6638E6FB6618E7FFE7FFE6D866DBE618E7DBE7D867FFE0000
+EB4F:00007FFE618E6FB6638E6FB6618E7FFE7FFE6D866DBE618E7DBE7DBE7FFE0000
+EB50:00007FFE618E6FB6638E6FB6618E7FFE7FFE61CE6FB661B67DB661CE7FFE0000
+EB51:00007FFE618E6FB6638E6FB6618E7FFE7FFE61EE6FCE61EE7DEE61C67FFE0000
+EB52:00007FFE618E6FB6638E6FB6618E7FFE7FFE61866FF661867DBE61867FFE0000
+EB53:00007FFE618E6FB6638E6FB6618E7FFE7FFE618E6FF661C67DF6618E7FFE0000
+EB54:00007FFE618E6FB6638E6FB6618E7FFE7FFE61B66FB661867DF661F67FFE0000
+EB55:00007FFE618E6FB6638E6FB6618E7FFE7FFE61866FBE61867DF661867FFE0000
+EB56:00007FFE618E6FB6638E6FB6618E7FFE7FFE61CE6FBE618E7DB661CE7FFE0000
+EB57:00007FFE618E6FB6638E6FB6618E7FFE7FFE61866FF661EE7DDE61DE7FFE0000
+EB58:00007FFE618E6FB6638E6FB6618E7FFE7FFE61CE6FB661CE7DB661CE7FFE0000
+EB59:00007FFE618E6FB6638E6FB6618E7FFE7FFE61CE6FB661C67DF661CE7FFE0000
+EB5A:00007FFE618E6FB6638E6FB6618E7FFE7FFE61866FB661867DB661B67FFE0000
+EB5B:00007FFE618E6FB6638E6FB6618E7FFE7FFE618E6FB6618E7DB6618E7FFE0000
+EB5C:00007FFE618E6FB6638E6FB6618E7FFE7FFE61C66FBE61BE7DBE61C67FFE0000
+EB5D:00007FFE618E6FB6638E6FB6618E7FFE7FFE618E6FB661B67DB6618E7FFE0000
+EB5E:00007FFE618E6FB6638E6FB6618E7FFE7FFE61866FBE618E7DBE61867FFE0000
+EB5F:00007FFE618E6FB6638E6FB6618E7FFE7FFE61866FBE618E7DBE61BE7FFE0000
+EB60:00007FFE618E6FB6638E6FB6618E7FFE7FFE73CE6FB663B66DB673CE7FFE0000
+EB61:00007FFE618E6FB6638E6FB6618E7FFE7FFE73EE6FCE63EE6DEE73C67FFE0000
+EB62:00007FFE618E6FB6638E6FB6618E7FFE7FFE73866FF663866DBE73867FFE0000
+EB63:00007FFE618E6FB6638E6FB6618E7FFE7FFE738E6FF663C66DF6738E7FFE0000
+EB64:00007FFE618E6FB6638E6FB6618E7FFE7FFE73B66FB663866DF673F67FFE0000
+EB65:00007FFE618E6FB6638E6FB6618E7FFE7FFE73866FBE63866DF673867FFE0000
+EB66:00007FFE618E6FB6638E6FB6618E7FFE7FFE73CE6FBE638E6DB673CE7FFE0000
+EB67:00007FFE618E6FB6638E6FB6618E7FFE7FFE73866FF663EE6DDE73DE7FFE0000
+EB68:00007FFE618E6FB6638E6FB6618E7FFE7FFE73CE6FB663CE6DB673CE7FFE0000
+EB69:00007FFE618E6FB6638E6FB6618E7FFE7FFE73CE6FB663C66DF673CE7FFE0000
+EB6A:00007FFE618E6FB6638E6FB6618E7FFE7FFE73866FB663866DB673B67FFE0000
+EB6B:00007FFE618E6FB6638E6FB6618E7FFE7FFE738E6FB6638E6DB6738E7FFE0000
+EB6C:00007FFE618E6FB6638E6FB6618E7FFE7FFE73C66FBE63BE6DBE73C67FFE0000
+EB6D:00007FFE618E6FB6638E6FB6618E7FFE7FFE738E6FB663B66DB6738E7FFE0000
+EB6E:00007FFE618E6FB6638E6FB6618E7FFE7FFE73866FBE638E6DBE73867FFE0000
+EB6F:00007FFE618E6FB6638E6FB6618E7FFE7FFE73866FBE638E6DBE73BE7FFE0000
+EB70:00007FFE618E6FB6638E6FB6618E7FFE7FFE61CE7DB67BB677B677CE7FFE0000
+EB71:00007FFE618E6FB6638E6FB6618E7FFE7FFE61EE7DCE7BEE77EE77C67FFE0000
+EB72:00007FFE618E6FB6638E6FB6618E7FFE7FFE61867DF67B8677BE77867FFE0000
+EB73:00007FFE618E6FB6638E6FB6618E7FFE7FFE618E7DF67BC677F6778E7FFE0000
+EB74:00007FFE618E6FB6638E6FB6618E7FFE7FFE61B67DB67B8677F677F67FFE0000
+EB75:00007FFE618E6FB6638E6FB6618E7FFE7FFE61867DBE7B8677F677867FFE0000
+EB76:00007FFE618E6FB6638E6FB6618E7FFE7FFE61CE7DBE7B8E77B677CE7FFE0000
+EB77:00007FFE618E6FB6638E6FB6618E7FFE7FFE61867DF67BEE77DE77DE7FFE0000
+EB78:00007FFE618E6FB6638E6FB6618E7FFE7FFE61CE7DB67BCE77B677CE7FFE0000
+EB79:00007FFE618E6FB6638E6FB6618E7FFE7FFE61CE7DB67BC677F677CE7FFE0000
+EB7A:00007FFE618E6FB6638E6FB6618E7FFE7FFE61867DB67B8677B677B67FFE0000
+EB7B:00007FFE618E6FB6638E6FB6618E7FFE7FFE618E7DB67B8E77B6778E7FFE0000
+EB7C:00007FFE618E6FB6638E6FB6618E7FFE7FFE61C67DBE7BBE77BE77C67FFE0000
+EB7D:00007FFE618E6FB6638E6FB6618E7FFE7FFE618E7DB67BB677B6778E7FFE0000
+EB7E:00007FFE618E6FB6638E6FB6618E7FFE7FFE61867DBE7B8E77BE77867FFE0000
+EB7F:00007FFE618E6FB6638E6FB6618E7FFE7FFE61867DBE7B8E77BE77BE7FFE0000
+EB80:00007FFE618E6FB6638E6FB6618E7FFE7FFE73CE6DB673B66DB673CE7FFE0000
+EB81:00007FFE618E6FB6638E6FB6618E7FFE7FFE73EE6DCE73EE6DEE73C67FFE0000
+EB82:00007FFE618E6FB6638E6FB6618E7FFE7FFE73866DF673866DBE73867FFE0000
+EB83:00007FFE618E6FB6638E6FB6618E7FFE7FFE738E6DF673C66DF6738E7FFE0000
+EB84:00007FFE618E6FB6638E6FB6618E7FFE7FFE73B66DB673866DF673F67FFE0000
+EB85:00007FFE618E6FB6638E6FB6618E7FFE7FFE73866DBE73866DF673867FFE0000
+EB86:00007FFE618E6FB6638E6FB6618E7FFE7FFE73CE6DBE738E6DB673CE7FFE0000
+EB87:00007FFE618E6FB6638E6FB6618E7FFE7FFE73866DF673EE6DDE73DE7FFE0000
+EB88:00007FFE618E6FB6638E6FB6618E7FFE7FFE73CE6DB673CE6DB673CE7FFE0000
+EB89:00007FFE618E6FB6638E6FB6618E7FFE7FFE73CE6DB673C66DF673CE7FFE0000
+EB8A:00007FFE618E6FB6638E6FB6618E7FFE7FFE73866DB673866DB673B67FFE0000
+EB8B:00007FFE618E6FB6638E6FB6618E7FFE7FFE738E6DB6738E6DB6738E7FFE0000
+EB8C:00007FFE618E6FB6638E6FB6618E7FFE7FFE73C66DBE73BE6DBE73C67FFE0000
+EB8D:00007FFE618E6FB6638E6FB6618E7FFE7FFE738E6DB673B66DB6738E7FFE0000
+EB8E:00007FFE618E6FB6638E6FB6618E7FFE7FFE73866DBE738E6DBE73867FFE0000
+EB8F:00007FFE618E6FB6638E6FB6618E7FFE7FFE73866DBE738E6DBE73BE7FFE0000
+EB90:00007FFE618E6FB6638E6FB6618E7FFE7FFE73CE6DB671B67DB673CE7FFE0000
+EB91:00007FFE618E6FB6638E6FB6618E7FFE7FFE73EE6DCE71EE7DEE73C67FFE0000
+EB92:00007FFE618E6FB6638E6FB6618E7FFE7FFE73866DF671867DBE73867FFE0000
+EB93:00007FFE618E6FB6638E6FB6618E7FFE7FFE738E6DF671C67DF6738E7FFE0000
+EB94:00007FFE618E6FB6638E6FB6618E7FFE7FFE73B66DB671867DF673F67FFE0000
+EB95:00007FFE618E6FB6638E6FB6618E7FFE7FFE73866DBE71867DF673867FFE0000
+EB96:00007FFE618E6FB6638E6FB6618E7FFE7FFE73CE6DBE718E7DB673CE7FFE0000
+EB97:00007FFE618E6FB6638E6FB6618E7FFE7FFE73866DF671EE7DDE73DE7FFE0000
+EB98:00007FFE618E6FB6638E6FB6618E7FFE7FFE73CE6DB671CE7DB673CE7FFE0000
+EB99:00007FFE618E6FB6638E6FB6618E7FFE7FFE73CE6DB671C67DF673CE7FFE0000
+EB9A:00007FFE618E6FB6638E6FB6618E7FFE7FFE73866DB671867DB673B67FFE0000
+EB9B:00007FFE618E6FB6638E6FB6618E7FFE7FFE738E6DB6718E7DB6738E7FFE0000
+EB9C:00007FFE618E6FB6638E6FB6618E7FFE7FFE73C66DBE71BE7DBE73C67FFE0000
+EB9D:00007FFE618E6FB6638E6FB6618E7FFE7FFE738E6DB671B67DB6738E7FFE0000
+EB9E:00007FFE618E6FB6638E6FB6618E7FFE7FFE73866DBE718E7DBE73867FFE0000
+EB9F:00007FFE618E6FB6638E6FB6618E7FFE7FFE73866DBE718E7DBE73BE7FFE0000
+EBA0:00007FFE618E6FB6638E6FB6618E7FFE7FFE61CE6DB661B66DB66DCE7FFE0000
+EBA1:00007FFE618E6FB6638E6FB6618E7FFE7FFE61EE6DCE61EE6DEE6DC67FFE0000
+EBA2:00007FFE618E6FB6638E6FB6618E7FFE7FFE61866DF661866DBE6D867FFE0000
+EBA3:00007FFE618E6FB6638E6FB6618E7FFE7FFE618E6DF661C66DF66D8E7FFE0000
+EBA4:00007FFE618E6FB6638E6FB6618E7FFE7FFE61B66DB661866DF66DF67FFE0000
+EBA5:00007FFE618E6FB6638E6FB6618E7FFE7FFE61866DBE61866DF66D867FFE0000
+EBA6:00007FFE618E6FB6638E6FB6618E7FFE7FFE61CE6DBE618E6DB66DCE7FFE0000
+EBA7:00007FFE618E6FB6638E6FB6618E7FFE7FFE61866DF661EE6DDE6DDE7FFE0000
+EBA8:00007FFE618E6FB6638E6FB6618E7FFE7FFE61CE6DB661CE6DB66DCE7FFE0000
+EBA9:00007FFE618E6FB6638E6FB6618E7FFE7FFE61CE6DB661C66DF66DCE7FFE0000
+EBAA:00007FFE618E6FB6638E6FB6618E7FFE7FFE61866DB661866DB66DB67FFE0000
+EBAB:00007FFE618E6FB6638E6FB6618E7FFE7FFE618E6DB6618E6DB66D8E7FFE0000
+EBAC:00007FFE618E6FB6638E6FB6618E7FFE7FFE61C66DBE61BE6DBE6DC67FFE0000
+EBAD:00007FFE618E6FB6638E6FB6618E7FFE7FFE618E6DB661B66DB66D8E7FFE0000
+EBAE:00007FFE618E6FB6638E6FB6618E7FFE7FFE61866DBE618E6DBE6D867FFE0000
+EBAF:00007FFE618E6FB6638E6FB6618E7FFE7FFE61866DBE618E6DBE6DBE7FFE0000
+EBB0:00007FFE618E6FB6638E6FB6618E7FFE7FFE63CE6DB663B66DB663CE7FFE0000
+EBB1:00007FFE618E6FB6638E6FB6618E7FFE7FFE63EE6DCE63EE6DEE63C67FFE0000
+EBB2:00007FFE618E6FB6638E6FB6618E7FFE7FFE63866DF663866DBE63867FFE0000
+EBB3:00007FFE618E6FB6638E6FB6618E7FFE7FFE638E6DF663C66DF6638E7FFE0000
+EBB4:00007FFE618E6FB6638E6FB6618E7FFE7FFE63B66DB663866DF663F67FFE0000
+EBB5:00007FFE618E6FB6638E6FB6618E7FFE7FFE63866DBE63866DF663867FFE0000
+EBB6:00007FFE618E6FB6638E6FB6618E7FFE7FFE63CE6DBE638E6DB663CE7FFE0000
+EBB7:00007FFE618E6FB6638E6FB6618E7FFE7FFE63866DF663EE6DDE63DE7FFE0000
+EBB8:00007FFE618E6FB6638E6FB6618E7FFE7FFE63CE6DB663CE6DB663CE7FFE0000
+EBB9:00007FFE618E6FB6638E6FB6618E7FFE7FFE63CE6DB663C66DF663CE7FFE0000
+EBBA:00007FFE618E6FB6638E6FB6618E7FFE7FFE63866DB663866DB663B67FFE0000
+EBBB:00007FFE618E6FB6638E6FB6618E7FFE7FFE638E6DB6638E6DB6638E7FFE0000
+EBBC:00007FFE618E6FB6638E6FB6618E7FFE7FFE63C66DBE63BE6DBE63C67FFE0000
+EBBD:00007FFE618E6FB6638E6FB6618E7FFE7FFE638E6DB663B66DB6638E7FFE0000
+EBBE:00007FFE618E6FB6638E6FB6618E7FFE7FFE63866DBE638E6DBE63867FFE0000
+EBBF:00007FFE618E6FB6638E6FB6618E7FFE7FFE63866DBE638E6DBE63BE7FFE0000
+EBC0:00007FFE618E6FB6638E6FB6618E7FFE7FFE71CE6FB66FB66FB671CE7FFE0000
+EBC1:00007FFE618E6FB6638E6FB6618E7FFE7FFE71EE6FCE6FEE6FEE71C67FFE0000
+EBC2:00007FFE618E6FB6638E6FB6618E7FFE7FFE71866FF66F866FBE71867FFE0000
+EBC3:00007FFE618E6FB6638E6FB6618E7FFE7FFE718E6FF66FC66FF6718E7FFE0000
+EBC4:00007FFE618E6FB6638E6FB6618E7FFE7FFE71B66FB66F866FF671F67FFE0000
+EBC5:00007FFE618E6FB6638E6FB6618E7FFE7FFE71866FBE6F866FF671867FFE0000
+EBC6:00007FFE618E6FB6638E6FB6618E7FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000
+EBC7:00007FFE618E6FB6638E6FB6618E7FFE7FFE71866FF66FEE6FDE71DE7FFE0000
+EBC8:00007FFE618E6FB6638E6FB6618E7FFE7FFE71CE6FB66FCE6FB671CE7FFE0000
+EBC9:00007FFE618E6FB6638E6FB6618E7FFE7FFE71CE6FB66FC66FF671CE7FFE0000
+EBCA:00007FFE618E6FB6638E6FB6618E7FFE7FFE71866FB66F866FB671B67FFE0000
+EBCB:00007FFE618E6FB6638E6FB6618E7FFE7FFE718E6FB66F8E6FB6718E7FFE0000
+EBCC:00007FFE618E6FB6638E6FB6618E7FFE7FFE71C66FBE6FBE6FBE71C67FFE0000
+EBCD:00007FFE618E6FB6638E6FB6618E7FFE7FFE718E6FB66FB66FB6718E7FFE0000
+EBCE:00007FFE618E6FB6638E6FB6618E7FFE7FFE71866FBE6F8E6FBE71867FFE0000
+EBCF:00007FFE618E6FB6638E6FB6618E7FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+EBD0:00007FFE618E6FB6638E6FB6618E7FFE7FFE63CE6DB66DB66DB663CE7FFE0000
+EBD1:00007FFE618E6FB6638E6FB6618E7FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000
+EBD2:00007FFE618E6FB6638E6FB6618E7FFE7FFE63866DF66D866DBE63867FFE0000
+EBD3:00007FFE618E6FB6638E6FB6618E7FFE7FFE638E6DF66DC66DF6638E7FFE0000
+EBD4:00007FFE618E6FB6638E6FB6618E7FFE7FFE63B66DB66D866DF663F67FFE0000
+EBD5:00007FFE618E6FB6638E6FB6618E7FFE7FFE63866DBE6D866DF663867FFE0000
+EBD6:00007FFE618E6FB6638E6FB6618E7FFE7FFE63CE6DBE6D8E6DB663CE7FFE0000
+EBD7:00007FFE618E6FB6638E6FB6618E7FFE7FFE63866DF66DEE6DDE63DE7FFE0000
+EBD8:00007FFE618E6FB6638E6FB6618E7FFE7FFE63CE6DB66DCE6DB663CE7FFE0000
+EBD9:00007FFE618E6FB6638E6FB6618E7FFE7FFE63CE6DB66DC66DF663CE7FFE0000
+EBDA:00007FFE618E6FB6638E6FB6618E7FFE7FFE63866DB66D866DB663B67FFE0000
+EBDB:00007FFE618E6FB6638E6FB6618E7FFE7FFE638E6DB66D8E6DB6638E7FFE0000
+EBDC:00007FFE618E6FB6638E6FB6618E7FFE7FFE63C66DBE6DBE6DBE63C67FFE0000
+EBDD:00007FFE618E6FB6638E6FB6618E7FFE7FFE638E6DB66DB66DB6638E7FFE0000
+EBDE:00007FFE618E6FB6638E6FB6618E7FFE7FFE63866DBE6D8E6DBE63867FFE0000
+EBDF:00007FFE618E6FB6638E6FB6618E7FFE7FFE63866DBE6D8E6DBE63BE7FFE0000
+EBE0:00007FFE618E6FB6638E6FB6618E7FFE7FFE61CE6FB663B66FB661CE7FFE0000
+EBE1:00007FFE618E6FB6638E6FB6618E7FFE7FFE61EE6FCE63EE6FEE61C67FFE0000
+EBE2:00007FFE618E6FB6638E6FB6618E7FFE7FFE61866FF663866FBE61867FFE0000
+EBE3:00007FFE618E6FB6638E6FB6618E7FFE7FFE618E6FF663C66FF6618E7FFE0000
+EBE4:00007FFE618E6FB6638E6FB6618E7FFE7FFE61B66FB663866FF661F67FFE0000
+EBE5:00007FFE618E6FB6638E6FB6618E7FFE7FFE61866FBE63866FF661867FFE0000
+EBE6:00007FFE618E6FB6638E6FB6618E7FFE7FFE61CE6FBE638E6FB661CE7FFE0000
+EBE7:00007FFE618E6FB6638E6FB6618E7FFE7FFE61866FF663EE6FDE61DE7FFE0000
+EBE8:00007FFE618E6FB6638E6FB6618E7FFE7FFE61CE6FB663CE6FB661CE7FFE0000
+EBE9:00007FFE618E6FB6638E6FB6618E7FFE7FFE61CE6FB663C66FF661CE7FFE0000
+EBEA:00007FFE618E6FB6638E6FB6618E7FFE7FFE61866FB663866FB661B67FFE0000
+EBEB:00007FFE618E6FB6638E6FB6618E7FFE7FFE618E6FB6638E6FB6618E7FFE0000
+EBEC:00007FFE618E6FB6638E6FB6618E7FFE7FFE61C66FBE63BE6FBE61C67FFE0000
+EBED:00007FFE618E6FB6638E6FB6618E7FFE7FFE618E6FB663B66FB6618E7FFE0000
+EBEE:00007FFE618E6FB6638E6FB6618E7FFE7FFE61866FBE638E6FBE61867FFE0000
+EBEF:00007FFE618E6FB6638E6FB6618E7FFE7FFE61866FBE638E6FBE61BE7FFE0000
+EBF0:00007FFE618E6FB6638E6FB6618E7FFE7FFE61CE6FB663B66FB66FCE7FFE0000
+EBF1:00007FFE618E6FB6638E6FB6618E7FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000
+EBF2:00007FFE618E6FB6638E6FB6618E7FFE7FFE61866FF663866FBE6F867FFE0000
+EBF3:00007FFE618E6FB6638E6FB6618E7FFE7FFE618E6FF663C66FF66F8E7FFE0000
+EBF4:00007FFE618E6FB6638E6FB6618E7FFE7FFE61B66FB663866FF66FF67FFE0000
+EBF5:00007FFE618E6FB6638E6FB6618E7FFE7FFE61866FBE63866FF66F867FFE0000
+EBF6:00007FFE618E6FB6638E6FB6618E7FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+EBF7:00007FFE618E6FB6638E6FB6618E7FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+EBF8:00007FFE618E6FB6638E6FB6618E7FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+EBF9:00007FFE618E6FB6638E6FB6618E7FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+EBFA:00007FFE618E6FB6638E6FB6618E7FFE7FFE61866FB663866FB66FB67FFE0000
+EBFB:00007FFE618E6FB6638E6FB6618E7FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+EBFC:00007FFE618E6FB6638E6FB6618E7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+EBFD:00007FFE618E6FB6638E6FB6618E7FFE7FFE618E6FB663B66FB66F8E7FFE0000
+EBFE:00007FFE618E6FB6638E6FB6618E7FFE7FFE61866FBE638E6FBE6F867FFE0000
+EBFF:00007FFE618E6FB6638E6FB6618E7FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+EC00:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73CE6DB66DB66DB673CE7FFE0000
+EC01:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73EE6DCE6DEE6DEE73C67FFE0000
+EC02:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73866DF66D866DBE73867FFE0000
+EC03:00007FFE61C66FBE63BE6FBE61C67FFE7FFE738E6DF66DC66DF6738E7FFE0000
+EC04:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73B66DB66D866DF673F67FFE0000
+EC05:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73866DBE6D866DF673867FFE0000
+EC06:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73CE6DBE6D8E6DB673CE7FFE0000
+EC07:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73866DF66DEE6DDE73DE7FFE0000
+EC08:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73CE6DB66DCE6DB673CE7FFE0000
+EC09:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73CE6DB66DC66DF673CE7FFE0000
+EC0A:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73866DB66D866DB673B67FFE0000
+EC0B:00007FFE61C66FBE63BE6FBE61C67FFE7FFE738E6DB66D8E6DB6738E7FFE0000
+EC0C:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73C66DBE6DBE6DBE73C67FFE0000
+EC0D:00007FFE61C66FBE63BE6FBE61C67FFE7FFE738E6DB66DB66DB6738E7FFE0000
+EC0E:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73866DBE6D8E6DBE73867FFE0000
+EC0F:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73866DBE6D8E6DBE73BE7FFE0000
+EC10:00007FFE61C66FBE63BE6FBE61C67FFE7FFE7BCE73B67BB67BB671CE7FFE0000
+EC11:00007FFE61C66FBE63BE6FBE61C67FFE7FFE7BEE73CE7BEE7BEE71C67FFE0000
+EC12:00007FFE61C66FBE63BE6FBE61C67FFE7FFE7B8673F67B867BBE71867FFE0000
+EC13:00007FFE61C66FBE63BE6FBE61C67FFE7FFE7B8E73F67BC67BF6718E7FFE0000
+EC14:00007FFE61C66FBE63BE6FBE61C67FFE7FFE7BB673B67B867BF671F67FFE0000
+EC15:00007FFE61C66FBE63BE6FBE61C67FFE7FFE7B8673BE7B867BF671867FFE0000
+EC16:00007FFE61C66FBE63BE6FBE61C67FFE7FFE7BCE73BE7B8E7BB671CE7FFE0000
+EC17:00007FFE61C66FBE63BE6FBE61C67FFE7FFE7B8673F67BEE7BDE71DE7FFE0000
+EC18:00007FFE61C66FBE63BE6FBE61C67FFE7FFE7BCE73B67BCE7BB671CE7FFE0000
+EC19:00007FFE61C66FBE63BE6FBE61C67FFE7FFE7BCE73B67BC67BF671CE7FFE0000
+EC1A:00007FFE61C66FBE63BE6FBE61C67FFE7FFE7B8673B67B867BB671B67FFE0000
+EC1B:00007FFE61C66FBE63BE6FBE61C67FFE7FFE7B8E73B67B8E7BB6718E7FFE0000
+EC1C:00007FFE61C66FBE63BE6FBE61C67FFE7FFE7BC673BE7BBE7BBE71C67FFE0000
+EC1D:00007FFE61C66FBE63BE6FBE61C67FFE7FFE7B8E73B67BB67BB6718E7FFE0000
+EC1E:00007FFE61C66FBE63BE6FBE61C67FFE7FFE7B8673BE7B8E7BBE71867FFE0000
+EC1F:00007FFE61C66FBE63BE6FBE61C67FFE7FFE7B8673BE7B8E7BBE71BE7FFE0000
+EC20:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61CE7DB661B66FB661CE7FFE0000
+EC21:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61EE7DCE61EE6FEE61C67FFE0000
+EC22:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61867DF661866FBE61867FFE0000
+EC23:00007FFE61C66FBE63BE6FBE61C67FFE7FFE618E7DF661C66FF6618E7FFE0000
+EC24:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61B67DB661866FF661F67FFE0000
+EC25:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61867DBE61866FF661867FFE0000
+EC26:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61CE7DBE618E6FB661CE7FFE0000
+EC27:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61867DF661EE6FDE61DE7FFE0000
+EC28:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61CE7DB661CE6FB661CE7FFE0000
+EC29:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61CE7DB661C66FF661CE7FFE0000
+EC2A:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61867DB661866FB661B67FFE0000
+EC2B:00007FFE61C66FBE63BE6FBE61C67FFE7FFE618E7DB6618E6FB6618E7FFE0000
+EC2C:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61C67DBE61BE6FBE61C67FFE0000
+EC2D:00007FFE61C66FBE63BE6FBE61C67FFE7FFE618E7DB661B66FB6618E7FFE0000
+EC2E:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61867DBE618E6FBE61867FFE0000
+EC2F:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61867DBE618E6FBE61BE7FFE0000
+EC30:00007FFE61C66FBE63BE6FBE61C67FFE7FFE63CE7DB671B67DB663CE7FFE0000
+EC31:00007FFE61C66FBE63BE6FBE61C67FFE7FFE63EE7DCE71EE7DEE63C67FFE0000
+EC32:00007FFE61C66FBE63BE6FBE61C67FFE7FFE63867DF671867DBE63867FFE0000
+EC33:00007FFE61C66FBE63BE6FBE61C67FFE7FFE638E7DF671C67DF6638E7FFE0000
+EC34:00007FFE61C66FBE63BE6FBE61C67FFE7FFE63B67DB671867DF663F67FFE0000
+EC35:00007FFE61C66FBE63BE6FBE61C67FFE7FFE63867DBE71867DF663867FFE0000
+EC36:00007FFE61C66FBE63BE6FBE61C67FFE7FFE63CE7DBE718E7DB663CE7FFE0000
+EC37:00007FFE61C66FBE63BE6FBE61C67FFE7FFE63867DF671EE7DDE63DE7FFE0000
+EC38:00007FFE61C66FBE63BE6FBE61C67FFE7FFE63CE7DB671CE7DB663CE7FFE0000
+EC39:00007FFE61C66FBE63BE6FBE61C67FFE7FFE63CE7DB671C67DF663CE7FFE0000
+EC3A:00007FFE61C66FBE63BE6FBE61C67FFE7FFE63867DB671867DB663B67FFE0000
+EC3B:00007FFE61C66FBE63BE6FBE61C67FFE7FFE638E7DB6718E7DB6638E7FFE0000
+EC3C:00007FFE61C66FBE63BE6FBE61C67FFE7FFE63C67DBE71BE7DBE63C67FFE0000
+EC3D:00007FFE61C66FBE63BE6FBE61C67FFE7FFE638E7DB671B67DB6638E7FFE0000
+EC3E:00007FFE61C66FBE63BE6FBE61C67FFE7FFE63867DBE718E7DBE63867FFE0000
+EC3F:00007FFE61C66FBE63BE6FBE61C67FFE7FFE63867DBE718E7DBE63BE7FFE0000
+EC40:00007FFE61C66FBE63BE6FBE61C67FFE7FFE6DCE6DB661B67DB67DCE7FFE0000
+EC41:00007FFE61C66FBE63BE6FBE61C67FFE7FFE6DEE6DCE61EE7DEE7DC67FFE0000
+EC42:00007FFE61C66FBE63BE6FBE61C67FFE7FFE6D866DF661867DBE7D867FFE0000
+EC43:00007FFE61C66FBE63BE6FBE61C67FFE7FFE6D8E6DF661C67DF67D8E7FFE0000
+EC44:00007FFE61C66FBE63BE6FBE61C67FFE7FFE6DB66DB661867DF67DF67FFE0000
+EC45:00007FFE61C66FBE63BE6FBE61C67FFE7FFE6D866DBE61867DF67D867FFE0000
+EC46:00007FFE61C66FBE63BE6FBE61C67FFE7FFE6DCE6DBE618E7DB67DCE7FFE0000
+EC47:00007FFE61C66FBE63BE6FBE61C67FFE7FFE6D866DF661EE7DDE7DDE7FFE0000
+EC48:00007FFE61C66FBE63BE6FBE61C67FFE7FFE6DCE6DB661CE7DB67DCE7FFE0000
+EC49:00007FFE61C66FBE63BE6FBE61C67FFE7FFE6DCE6DB661C67DF67DCE7FFE0000
+EC4A:00007FFE61C66FBE63BE6FBE61C67FFE7FFE6D866DB661867DB67DB67FFE0000
+EC4B:00007FFE61C66FBE63BE6FBE61C67FFE7FFE6D8E6DB6618E7DB67D8E7FFE0000
+EC4C:00007FFE61C66FBE63BE6FBE61C67FFE7FFE6DC66DBE61BE7DBE7DC67FFE0000
+EC4D:00007FFE61C66FBE63BE6FBE61C67FFE7FFE6D8E6DB661B67DB67D8E7FFE0000
+EC4E:00007FFE61C66FBE63BE6FBE61C67FFE7FFE6D866DBE618E7DBE7D867FFE0000
+EC4F:00007FFE61C66FBE63BE6FBE61C67FFE7FFE6D866DBE618E7DBE7DBE7FFE0000
+EC50:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61CE6FB661B67DB661CE7FFE0000
+EC51:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61EE6FCE61EE7DEE61C67FFE0000
+EC52:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61866FF661867DBE61867FFE0000
+EC53:00007FFE61C66FBE63BE6FBE61C67FFE7FFE618E6FF661C67DF6618E7FFE0000
+EC54:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61B66FB661867DF661F67FFE0000
+EC55:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61866FBE61867DF661867FFE0000
+EC56:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61CE6FBE618E7DB661CE7FFE0000
+EC57:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61866FF661EE7DDE61DE7FFE0000
+EC58:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61CE6FB661CE7DB661CE7FFE0000
+EC59:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61CE6FB661C67DF661CE7FFE0000
+EC5A:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61866FB661867DB661B67FFE0000
+EC5B:00007FFE61C66FBE63BE6FBE61C67FFE7FFE618E6FB6618E7DB6618E7FFE0000
+EC5C:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61C66FBE61BE7DBE61C67FFE0000
+EC5D:00007FFE61C66FBE63BE6FBE61C67FFE7FFE618E6FB661B67DB6618E7FFE0000
+EC5E:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61866FBE618E7DBE61867FFE0000
+EC5F:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61866FBE618E7DBE61BE7FFE0000
+EC60:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73CE6FB663B66DB673CE7FFE0000
+EC61:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73EE6FCE63EE6DEE73C67FFE0000
+EC62:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73866FF663866DBE73867FFE0000
+EC63:00007FFE61C66FBE63BE6FBE61C67FFE7FFE738E6FF663C66DF6738E7FFE0000
+EC64:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73B66FB663866DF673F67FFE0000
+EC65:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73866FBE63866DF673867FFE0000
+EC66:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73CE6FBE638E6DB673CE7FFE0000
+EC67:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73866FF663EE6DDE73DE7FFE0000
+EC68:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73CE6FB663CE6DB673CE7FFE0000
+EC69:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73CE6FB663C66DF673CE7FFE0000
+EC6A:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73866FB663866DB673B67FFE0000
+EC6B:00007FFE61C66FBE63BE6FBE61C67FFE7FFE738E6FB6638E6DB6738E7FFE0000
+EC6C:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73C66FBE63BE6DBE73C67FFE0000
+EC6D:00007FFE61C66FBE63BE6FBE61C67FFE7FFE738E6FB663B66DB6738E7FFE0000
+EC6E:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73866FBE638E6DBE73867FFE0000
+EC6F:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73866FBE638E6DBE73BE7FFE0000
+EC70:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61CE7DB67BB677B677CE7FFE0000
+EC71:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61EE7DCE7BEE77EE77C67FFE0000
+EC72:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61867DF67B8677BE77867FFE0000
+EC73:00007FFE61C66FBE63BE6FBE61C67FFE7FFE618E7DF67BC677F6778E7FFE0000
+EC74:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61B67DB67B8677F677F67FFE0000
+EC75:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61867DBE7B8677F677867FFE0000
+EC76:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61CE7DBE7B8E77B677CE7FFE0000
+EC77:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61867DF67BEE77DE77DE7FFE0000
+EC78:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61CE7DB67BCE77B677CE7FFE0000
+EC79:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61CE7DB67BC677F677CE7FFE0000
+EC7A:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61867DB67B8677B677B67FFE0000
+EC7B:00007FFE61C66FBE63BE6FBE61C67FFE7FFE618E7DB67B8E77B6778E7FFE0000
+EC7C:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61C67DBE7BBE77BE77C67FFE0000
+EC7D:00007FFE61C66FBE63BE6FBE61C67FFE7FFE618E7DB67BB677B6778E7FFE0000
+EC7E:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61867DBE7B8E77BE77867FFE0000
+EC7F:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61867DBE7B8E77BE77BE7FFE0000
+EC80:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73CE6DB673B66DB673CE7FFE0000
+EC81:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73EE6DCE73EE6DEE73C67FFE0000
+EC82:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73866DF673866DBE73867FFE0000
+EC83:00007FFE61C66FBE63BE6FBE61C67FFE7FFE738E6DF673C66DF6738E7FFE0000
+EC84:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73B66DB673866DF673F67FFE0000
+EC85:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73866DBE73866DF673867FFE0000
+EC86:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73CE6DBE738E6DB673CE7FFE0000
+EC87:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73866DF673EE6DDE73DE7FFE0000
+EC88:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73CE6DB673CE6DB673CE7FFE0000
+EC89:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73CE6DB673C66DF673CE7FFE0000
+EC8A:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73866DB673866DB673B67FFE0000
+EC8B:00007FFE61C66FBE63BE6FBE61C67FFE7FFE738E6DB6738E6DB6738E7FFE0000
+EC8C:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73C66DBE73BE6DBE73C67FFE0000
+EC8D:00007FFE61C66FBE63BE6FBE61C67FFE7FFE738E6DB673B66DB6738E7FFE0000
+EC8E:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73866DBE738E6DBE73867FFE0000
+EC8F:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73866DBE738E6DBE73BE7FFE0000
+EC90:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73CE6DB671B67DB673CE7FFE0000
+EC91:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73EE6DCE71EE7DEE73C67FFE0000
+EC92:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73866DF671867DBE73867FFE0000
+EC93:00007FFE61C66FBE63BE6FBE61C67FFE7FFE738E6DF671C67DF6738E7FFE0000
+EC94:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73B66DB671867DF673F67FFE0000
+EC95:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73866DBE71867DF673867FFE0000
+EC96:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73CE6DBE718E7DB673CE7FFE0000
+EC97:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73866DF671EE7DDE73DE7FFE0000
+EC98:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73CE6DB671CE7DB673CE7FFE0000
+EC99:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73CE6DB671C67DF673CE7FFE0000
+EC9A:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73866DB671867DB673B67FFE0000
+EC9B:00007FFE61C66FBE63BE6FBE61C67FFE7FFE738E6DB6718E7DB6738E7FFE0000
+EC9C:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73C66DBE71BE7DBE73C67FFE0000
+EC9D:00007FFE61C66FBE63BE6FBE61C67FFE7FFE738E6DB671B67DB6738E7FFE0000
+EC9E:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73866DBE718E7DBE73867FFE0000
+EC9F:00007FFE61C66FBE63BE6FBE61C67FFE7FFE73866DBE718E7DBE73BE7FFE0000
+ECA0:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61CE6DB661B66DB66DCE7FFE0000
+ECA1:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61EE6DCE61EE6DEE6DC67FFE0000
+ECA2:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61866DF661866DBE6D867FFE0000
+ECA3:00007FFE61C66FBE63BE6FBE61C67FFE7FFE618E6DF661C66DF66D8E7FFE0000
+ECA4:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61B66DB661866DF66DF67FFE0000
+ECA5:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61866DBE61866DF66D867FFE0000
+ECA6:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61CE6DBE618E6DB66DCE7FFE0000
+ECA7:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61866DF661EE6DDE6DDE7FFE0000
+ECA8:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61CE6DB661CE6DB66DCE7FFE0000
+ECA9:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61CE6DB661C66DF66DCE7FFE0000
+ECAA:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61866DB661866DB66DB67FFE0000
+ECAB:00007FFE61C66FBE63BE6FBE61C67FFE7FFE618E6DB6618E6DB66D8E7FFE0000
+ECAC:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61C66DBE61BE6DBE6DC67FFE0000
+ECAD:00007FFE61C66FBE63BE6FBE61C67FFE7FFE618E6DB661B66DB66D8E7FFE0000
+ECAE:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61866DBE618E6DBE6D867FFE0000
+ECAF:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61866DBE618E6DBE6DBE7FFE0000
+ECB0:00007FFE61C66FBE63BE6FBE61C67FFE7FFE63CE6DB663B66DB663CE7FFE0000
+ECB1:00007FFE61C66FBE63BE6FBE61C67FFE7FFE63EE6DCE63EE6DEE63C67FFE0000
+ECB2:00007FFE61C66FBE63BE6FBE61C67FFE7FFE63866DF663866DBE63867FFE0000
+ECB3:00007FFE61C66FBE63BE6FBE61C67FFE7FFE638E6DF663C66DF6638E7FFE0000
+ECB4:00007FFE61C66FBE63BE6FBE61C67FFE7FFE63B66DB663866DF663F67FFE0000
+ECB5:00007FFE61C66FBE63BE6FBE61C67FFE7FFE63866DBE63866DF663867FFE0000
+ECB6:00007FFE61C66FBE63BE6FBE61C67FFE7FFE63CE6DBE638E6DB663CE7FFE0000
+ECB7:00007FFE61C66FBE63BE6FBE61C67FFE7FFE63866DF663EE6DDE63DE7FFE0000
+ECB8:00007FFE61C66FBE63BE6FBE61C67FFE7FFE63CE6DB663CE6DB663CE7FFE0000
+ECB9:00007FFE61C66FBE63BE6FBE61C67FFE7FFE63CE6DB663C66DF663CE7FFE0000
+ECBA:00007FFE61C66FBE63BE6FBE61C67FFE7FFE63866DB663866DB663B67FFE0000
+ECBB:00007FFE61C66FBE63BE6FBE61C67FFE7FFE638E6DB6638E6DB6638E7FFE0000
+ECBC:00007FFE61C66FBE63BE6FBE61C67FFE7FFE63C66DBE63BE6DBE63C67FFE0000
+ECBD:00007FFE61C66FBE63BE6FBE61C67FFE7FFE638E6DB663B66DB6638E7FFE0000
+ECBE:00007FFE61C66FBE63BE6FBE61C67FFE7FFE63866DBE638E6DBE63867FFE0000
+ECBF:00007FFE61C66FBE63BE6FBE61C67FFE7FFE63866DBE638E6DBE63BE7FFE0000
+ECC0:00007FFE61C66FBE63BE6FBE61C67FFE7FFE71CE6FB66FB66FB671CE7FFE0000
+ECC1:00007FFE61C66FBE63BE6FBE61C67FFE7FFE71EE6FCE6FEE6FEE71C67FFE0000
+ECC2:00007FFE61C66FBE63BE6FBE61C67FFE7FFE71866FF66F866FBE71867FFE0000
+ECC3:00007FFE61C66FBE63BE6FBE61C67FFE7FFE718E6FF66FC66FF6718E7FFE0000
+ECC4:00007FFE61C66FBE63BE6FBE61C67FFE7FFE71B66FB66F866FF671F67FFE0000
+ECC5:00007FFE61C66FBE63BE6FBE61C67FFE7FFE71866FBE6F866FF671867FFE0000
+ECC6:00007FFE61C66FBE63BE6FBE61C67FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000
+ECC7:00007FFE61C66FBE63BE6FBE61C67FFE7FFE71866FF66FEE6FDE71DE7FFE0000
+ECC8:00007FFE61C66FBE63BE6FBE61C67FFE7FFE71CE6FB66FCE6FB671CE7FFE0000
+ECC9:00007FFE61C66FBE63BE6FBE61C67FFE7FFE71CE6FB66FC66FF671CE7FFE0000
+ECCA:00007FFE61C66FBE63BE6FBE61C67FFE7FFE71866FB66F866FB671B67FFE0000
+ECCB:00007FFE61C66FBE63BE6FBE61C67FFE7FFE718E6FB66F8E6FB6718E7FFE0000
+ECCC:00007FFE61C66FBE63BE6FBE61C67FFE7FFE71C66FBE6FBE6FBE71C67FFE0000
+ECCD:00007FFE61C66FBE63BE6FBE61C67FFE7FFE718E6FB66FB66FB6718E7FFE0000
+ECCE:00007FFE61C66FBE63BE6FBE61C67FFE7FFE71866FBE6F8E6FBE71867FFE0000
+ECCF:00007FFE61C66FBE63BE6FBE61C67FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+ECD0:00007FFE61C66FBE63BE6FBE61C67FFE7FFE63CE6DB66DB66DB663CE7FFE0000
+ECD1:00007FFE61C66FBE63BE6FBE61C67FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000
+ECD2:00007FFE61C66FBE63BE6FBE61C67FFE7FFE63866DF66D866DBE63867FFE0000
+ECD3:00007FFE61C66FBE63BE6FBE61C67FFE7FFE638E6DF66DC66DF6638E7FFE0000
+ECD4:00007FFE61C66FBE63BE6FBE61C67FFE7FFE63B66DB66D866DF663F67FFE0000
+ECD5:00007FFE61C66FBE63BE6FBE61C67FFE7FFE63866DBE6D866DF663867FFE0000
+ECD6:00007FFE61C66FBE63BE6FBE61C67FFE7FFE63CE6DBE6D8E6DB663CE7FFE0000
+ECD7:00007FFE61C66FBE63BE6FBE61C67FFE7FFE63866DF66DEE6DDE63DE7FFE0000
+ECD8:00007FFE61C66FBE63BE6FBE61C67FFE7FFE63CE6DB66DCE6DB663CE7FFE0000
+ECD9:00007FFE61C66FBE63BE6FBE61C67FFE7FFE63CE6DB66DC66DF663CE7FFE0000
+ECDA:00007FFE61C66FBE63BE6FBE61C67FFE7FFE63866DB66D866DB663B67FFE0000
+ECDB:00007FFE61C66FBE63BE6FBE61C67FFE7FFE638E6DB66D8E6DB6638E7FFE0000
+ECDC:00007FFE61C66FBE63BE6FBE61C67FFE7FFE63C66DBE6DBE6DBE63C67FFE0000
+ECDD:00007FFE61C66FBE63BE6FBE61C67FFE7FFE638E6DB66DB66DB6638E7FFE0000
+ECDE:00007FFE61C66FBE63BE6FBE61C67FFE7FFE63866DBE6D8E6DBE63867FFE0000
+ECDF:00007FFE61C66FBE63BE6FBE61C67FFE7FFE63866DBE6D8E6DBE63BE7FFE0000
+ECE0:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61CE6FB663B66FB661CE7FFE0000
+ECE1:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61EE6FCE63EE6FEE61C67FFE0000
+ECE2:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61866FF663866FBE61867FFE0000
+ECE3:00007FFE61C66FBE63BE6FBE61C67FFE7FFE618E6FF663C66FF6618E7FFE0000
+ECE4:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61B66FB663866FF661F67FFE0000
+ECE5:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61866FBE63866FF661867FFE0000
+ECE6:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61CE6FBE638E6FB661CE7FFE0000
+ECE7:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61866FF663EE6FDE61DE7FFE0000
+ECE8:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61CE6FB663CE6FB661CE7FFE0000
+ECE9:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61CE6FB663C66FF661CE7FFE0000
+ECEA:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61866FB663866FB661B67FFE0000
+ECEB:00007FFE61C66FBE63BE6FBE61C67FFE7FFE618E6FB6638E6FB6618E7FFE0000
+ECEC:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61C66FBE63BE6FBE61C67FFE0000
+ECED:00007FFE61C66FBE63BE6FBE61C67FFE7FFE618E6FB663B66FB6618E7FFE0000
+ECEE:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61866FBE638E6FBE61867FFE0000
+ECEF:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61866FBE638E6FBE61BE7FFE0000
+ECF0:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61CE6FB663B66FB66FCE7FFE0000
+ECF1:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000
+ECF2:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61866FF663866FBE6F867FFE0000
+ECF3:00007FFE61C66FBE63BE6FBE61C67FFE7FFE618E6FF663C66FF66F8E7FFE0000
+ECF4:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61B66FB663866FF66FF67FFE0000
+ECF5:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61866FBE63866FF66F867FFE0000
+ECF6:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+ECF7:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+ECF8:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+ECF9:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+ECFA:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61866FB663866FB66FB67FFE0000
+ECFB:00007FFE61C66FBE63BE6FBE61C67FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+ECFC:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+ECFD:00007FFE61C66FBE63BE6FBE61C67FFE7FFE618E6FB663B66FB66F8E7FFE0000
+ECFE:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61866FBE638E6FBE6F867FFE0000
+ECFF:00007FFE61C66FBE63BE6FBE61C67FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+ED00:00007FFE618E6FB663B66FB6618E7FFE7FFE73CE6DB66DB66DB673CE7FFE0000
+ED01:00007FFE618E6FB663B66FB6618E7FFE7FFE73EE6DCE6DEE6DEE73C67FFE0000
+ED02:00007FFE618E6FB663B66FB6618E7FFE7FFE73866DF66D866DBE73867FFE0000
+ED03:00007FFE618E6FB663B66FB6618E7FFE7FFE738E6DF66DC66DF6738E7FFE0000
+ED04:00007FFE618E6FB663B66FB6618E7FFE7FFE73B66DB66D866DF673F67FFE0000
+ED05:00007FFE618E6FB663B66FB6618E7FFE7FFE73866DBE6D866DF673867FFE0000
+ED06:00007FFE618E6FB663B66FB6618E7FFE7FFE73CE6DBE6D8E6DB673CE7FFE0000
+ED07:00007FFE618E6FB663B66FB6618E7FFE7FFE73866DF66DEE6DDE73DE7FFE0000
+ED08:00007FFE618E6FB663B66FB6618E7FFE7FFE73CE6DB66DCE6DB673CE7FFE0000
+ED09:00007FFE618E6FB663B66FB6618E7FFE7FFE73CE6DB66DC66DF673CE7FFE0000
+ED0A:00007FFE618E6FB663B66FB6618E7FFE7FFE73866DB66D866DB673B67FFE0000
+ED0B:00007FFE618E6FB663B66FB6618E7FFE7FFE738E6DB66D8E6DB6738E7FFE0000
+ED0C:00007FFE618E6FB663B66FB6618E7FFE7FFE73C66DBE6DBE6DBE73C67FFE0000
+ED0D:00007FFE618E6FB663B66FB6618E7FFE7FFE738E6DB66DB66DB6738E7FFE0000
+ED0E:00007FFE618E6FB663B66FB6618E7FFE7FFE73866DBE6D8E6DBE73867FFE0000
+ED0F:00007FFE618E6FB663B66FB6618E7FFE7FFE73866DBE6D8E6DBE73BE7FFE0000
+ED10:00007FFE618E6FB663B66FB6618E7FFE7FFE7BCE73B67BB67BB671CE7FFE0000
+ED11:00007FFE618E6FB663B66FB6618E7FFE7FFE7BEE73CE7BEE7BEE71C67FFE0000
+ED12:00007FFE618E6FB663B66FB6618E7FFE7FFE7B8673F67B867BBE71867FFE0000
+ED13:00007FFE618E6FB663B66FB6618E7FFE7FFE7B8E73F67BC67BF6718E7FFE0000
+ED14:00007FFE618E6FB663B66FB6618E7FFE7FFE7BB673B67B867BF671F67FFE0000
+ED15:00007FFE618E6FB663B66FB6618E7FFE7FFE7B8673BE7B867BF671867FFE0000
+ED16:00007FFE618E6FB663B66FB6618E7FFE7FFE7BCE73BE7B8E7BB671CE7FFE0000
+ED17:00007FFE618E6FB663B66FB6618E7FFE7FFE7B8673F67BEE7BDE71DE7FFE0000
+ED18:00007FFE618E6FB663B66FB6618E7FFE7FFE7BCE73B67BCE7BB671CE7FFE0000
+ED19:00007FFE618E6FB663B66FB6618E7FFE7FFE7BCE73B67BC67BF671CE7FFE0000
+ED1A:00007FFE618E6FB663B66FB6618E7FFE7FFE7B8673B67B867BB671B67FFE0000
+ED1B:00007FFE618E6FB663B66FB6618E7FFE7FFE7B8E73B67B8E7BB6718E7FFE0000
+ED1C:00007FFE618E6FB663B66FB6618E7FFE7FFE7BC673BE7BBE7BBE71C67FFE0000
+ED1D:00007FFE618E6FB663B66FB6618E7FFE7FFE7B8E73B67BB67BB6718E7FFE0000
+ED1E:00007FFE618E6FB663B66FB6618E7FFE7FFE7B8673BE7B8E7BBE71867FFE0000
+ED1F:00007FFE618E6FB663B66FB6618E7FFE7FFE7B8673BE7B8E7BBE71BE7FFE0000
+ED20:00007FFE618E6FB663B66FB6618E7FFE7FFE61CE7DB661B66FB661CE7FFE0000
+ED21:00007FFE618E6FB663B66FB6618E7FFE7FFE61EE7DCE61EE6FEE61C67FFE0000
+ED22:00007FFE618E6FB663B66FB6618E7FFE7FFE61867DF661866FBE61867FFE0000
+ED23:00007FFE618E6FB663B66FB6618E7FFE7FFE618E7DF661C66FF6618E7FFE0000
+ED24:00007FFE618E6FB663B66FB6618E7FFE7FFE61B67DB661866FF661F67FFE0000
+ED25:00007FFE618E6FB663B66FB6618E7FFE7FFE61867DBE61866FF661867FFE0000
+ED26:00007FFE618E6FB663B66FB6618E7FFE7FFE61CE7DBE618E6FB661CE7FFE0000
+ED27:00007FFE618E6FB663B66FB6618E7FFE7FFE61867DF661EE6FDE61DE7FFE0000
+ED28:00007FFE618E6FB663B66FB6618E7FFE7FFE61CE7DB661CE6FB661CE7FFE0000
+ED29:00007FFE618E6FB663B66FB6618E7FFE7FFE61CE7DB661C66FF661CE7FFE0000
+ED2A:00007FFE618E6FB663B66FB6618E7FFE7FFE61867DB661866FB661B67FFE0000
+ED2B:00007FFE618E6FB663B66FB6618E7FFE7FFE618E7DB6618E6FB6618E7FFE0000
+ED2C:00007FFE618E6FB663B66FB6618E7FFE7FFE61C67DBE61BE6FBE61C67FFE0000
+ED2D:00007FFE618E6FB663B66FB6618E7FFE7FFE618E7DB661B66FB6618E7FFE0000
+ED2E:00007FFE618E6FB663B66FB6618E7FFE7FFE61867DBE618E6FBE61867FFE0000
+ED2F:00007FFE618E6FB663B66FB6618E7FFE7FFE61867DBE618E6FBE61BE7FFE0000
+ED30:00007FFE618E6FB663B66FB6618E7FFE7FFE63CE7DB671B67DB663CE7FFE0000
+ED31:00007FFE618E6FB663B66FB6618E7FFE7FFE63EE7DCE71EE7DEE63C67FFE0000
+ED32:00007FFE618E6FB663B66FB6618E7FFE7FFE63867DF671867DBE63867FFE0000
+ED33:00007FFE618E6FB663B66FB6618E7FFE7FFE638E7DF671C67DF6638E7FFE0000
+ED34:00007FFE618E6FB663B66FB6618E7FFE7FFE63B67DB671867DF663F67FFE0000
+ED35:00007FFE618E6FB663B66FB6618E7FFE7FFE63867DBE71867DF663867FFE0000
+ED36:00007FFE618E6FB663B66FB6618E7FFE7FFE63CE7DBE718E7DB663CE7FFE0000
+ED37:00007FFE618E6FB663B66FB6618E7FFE7FFE63867DF671EE7DDE63DE7FFE0000
+ED38:00007FFE618E6FB663B66FB6618E7FFE7FFE63CE7DB671CE7DB663CE7FFE0000
+ED39:00007FFE618E6FB663B66FB6618E7FFE7FFE63CE7DB671C67DF663CE7FFE0000
+ED3A:00007FFE618E6FB663B66FB6618E7FFE7FFE63867DB671867DB663B67FFE0000
+ED3B:00007FFE618E6FB663B66FB6618E7FFE7FFE638E7DB6718E7DB6638E7FFE0000
+ED3C:00007FFE618E6FB663B66FB6618E7FFE7FFE63C67DBE71BE7DBE63C67FFE0000
+ED3D:00007FFE618E6FB663B66FB6618E7FFE7FFE638E7DB671B67DB6638E7FFE0000
+ED3E:00007FFE618E6FB663B66FB6618E7FFE7FFE63867DBE718E7DBE63867FFE0000
+ED3F:00007FFE618E6FB663B66FB6618E7FFE7FFE63867DBE718E7DBE63BE7FFE0000
+ED40:00007FFE618E6FB663B66FB6618E7FFE7FFE6DCE6DB661B67DB67DCE7FFE0000
+ED41:00007FFE618E6FB663B66FB6618E7FFE7FFE6DEE6DCE61EE7DEE7DC67FFE0000
+ED42:00007FFE618E6FB663B66FB6618E7FFE7FFE6D866DF661867DBE7D867FFE0000
+ED43:00007FFE618E6FB663B66FB6618E7FFE7FFE6D8E6DF661C67DF67D8E7FFE0000
+ED44:00007FFE618E6FB663B66FB6618E7FFE7FFE6DB66DB661867DF67DF67FFE0000
+ED45:00007FFE618E6FB663B66FB6618E7FFE7FFE6D866DBE61867DF67D867FFE0000
+ED46:00007FFE618E6FB663B66FB6618E7FFE7FFE6DCE6DBE618E7DB67DCE7FFE0000
+ED47:00007FFE618E6FB663B66FB6618E7FFE7FFE6D866DF661EE7DDE7DDE7FFE0000
+ED48:00007FFE618E6FB663B66FB6618E7FFE7FFE6DCE6DB661CE7DB67DCE7FFE0000
+ED49:00007FFE618E6FB663B66FB6618E7FFE7FFE6DCE6DB661C67DF67DCE7FFE0000
+ED4A:00007FFE618E6FB663B66FB6618E7FFE7FFE6D866DB661867DB67DB67FFE0000
+ED4B:00007FFE618E6FB663B66FB6618E7FFE7FFE6D8E6DB6618E7DB67D8E7FFE0000
+ED4C:00007FFE618E6FB663B66FB6618E7FFE7FFE6DC66DBE61BE7DBE7DC67FFE0000
+ED4D:00007FFE618E6FB663B66FB6618E7FFE7FFE6D8E6DB661B67DB67D8E7FFE0000
+ED4E:00007FFE618E6FB663B66FB6618E7FFE7FFE6D866DBE618E7DBE7D867FFE0000
+ED4F:00007FFE618E6FB663B66FB6618E7FFE7FFE6D866DBE618E7DBE7DBE7FFE0000
+ED50:00007FFE618E6FB663B66FB6618E7FFE7FFE61CE6FB661B67DB661CE7FFE0000
+ED51:00007FFE618E6FB663B66FB6618E7FFE7FFE61EE6FCE61EE7DEE61C67FFE0000
+ED52:00007FFE618E6FB663B66FB6618E7FFE7FFE61866FF661867DBE61867FFE0000
+ED53:00007FFE618E6FB663B66FB6618E7FFE7FFE618E6FF661C67DF6618E7FFE0000
+ED54:00007FFE618E6FB663B66FB6618E7FFE7FFE61B66FB661867DF661F67FFE0000
+ED55:00007FFE618E6FB663B66FB6618E7FFE7FFE61866FBE61867DF661867FFE0000
+ED56:00007FFE618E6FB663B66FB6618E7FFE7FFE61CE6FBE618E7DB661CE7FFE0000
+ED57:00007FFE618E6FB663B66FB6618E7FFE7FFE61866FF661EE7DDE61DE7FFE0000
+ED58:00007FFE618E6FB663B66FB6618E7FFE7FFE61CE6FB661CE7DB661CE7FFE0000
+ED59:00007FFE618E6FB663B66FB6618E7FFE7FFE61CE6FB661C67DF661CE7FFE0000
+ED5A:00007FFE618E6FB663B66FB6618E7FFE7FFE61866FB661867DB661B67FFE0000
+ED5B:00007FFE618E6FB663B66FB6618E7FFE7FFE618E6FB6618E7DB6618E7FFE0000
+ED5C:00007FFE618E6FB663B66FB6618E7FFE7FFE61C66FBE61BE7DBE61C67FFE0000
+ED5D:00007FFE618E6FB663B66FB6618E7FFE7FFE618E6FB661B67DB6618E7FFE0000
+ED5E:00007FFE618E6FB663B66FB6618E7FFE7FFE61866FBE618E7DBE61867FFE0000
+ED5F:00007FFE618E6FB663B66FB6618E7FFE7FFE61866FBE618E7DBE61BE7FFE0000
+ED60:00007FFE618E6FB663B66FB6618E7FFE7FFE73CE6FB663B66DB673CE7FFE0000
+ED61:00007FFE618E6FB663B66FB6618E7FFE7FFE73EE6FCE63EE6DEE73C67FFE0000
+ED62:00007FFE618E6FB663B66FB6618E7FFE7FFE73866FF663866DBE73867FFE0000
+ED63:00007FFE618E6FB663B66FB6618E7FFE7FFE738E6FF663C66DF6738E7FFE0000
+ED64:00007FFE618E6FB663B66FB6618E7FFE7FFE73B66FB663866DF673F67FFE0000
+ED65:00007FFE618E6FB663B66FB6618E7FFE7FFE73866FBE63866DF673867FFE0000
+ED66:00007FFE618E6FB663B66FB6618E7FFE7FFE73CE6FBE638E6DB673CE7FFE0000
+ED67:00007FFE618E6FB663B66FB6618E7FFE7FFE73866FF663EE6DDE73DE7FFE0000
+ED68:00007FFE618E6FB663B66FB6618E7FFE7FFE73CE6FB663CE6DB673CE7FFE0000
+ED69:00007FFE618E6FB663B66FB6618E7FFE7FFE73CE6FB663C66DF673CE7FFE0000
+ED6A:00007FFE618E6FB663B66FB6618E7FFE7FFE73866FB663866DB673B67FFE0000
+ED6B:00007FFE618E6FB663B66FB6618E7FFE7FFE738E6FB6638E6DB6738E7FFE0000
+ED6C:00007FFE618E6FB663B66FB6618E7FFE7FFE73C66FBE63BE6DBE73C67FFE0000
+ED6D:00007FFE618E6FB663B66FB6618E7FFE7FFE738E6FB663B66DB6738E7FFE0000
+ED6E:00007FFE618E6FB663B66FB6618E7FFE7FFE73866FBE638E6DBE73867FFE0000
+ED6F:00007FFE618E6FB663B66FB6618E7FFE7FFE73866FBE638E6DBE73BE7FFE0000
+ED70:00007FFE618E6FB663B66FB6618E7FFE7FFE61CE7DB67BB677B677CE7FFE0000
+ED71:00007FFE618E6FB663B66FB6618E7FFE7FFE61EE7DCE7BEE77EE77C67FFE0000
+ED72:00007FFE618E6FB663B66FB6618E7FFE7FFE61867DF67B8677BE77867FFE0000
+ED73:00007FFE618E6FB663B66FB6618E7FFE7FFE618E7DF67BC677F6778E7FFE0000
+ED74:00007FFE618E6FB663B66FB6618E7FFE7FFE61B67DB67B8677F677F67FFE0000
+ED75:00007FFE618E6FB663B66FB6618E7FFE7FFE61867DBE7B8677F677867FFE0000
+ED76:00007FFE618E6FB663B66FB6618E7FFE7FFE61CE7DBE7B8E77B677CE7FFE0000
+ED77:00007FFE618E6FB663B66FB6618E7FFE7FFE61867DF67BEE77DE77DE7FFE0000
+ED78:00007FFE618E6FB663B66FB6618E7FFE7FFE61CE7DB67BCE77B677CE7FFE0000
+ED79:00007FFE618E6FB663B66FB6618E7FFE7FFE61CE7DB67BC677F677CE7FFE0000
+ED7A:00007FFE618E6FB663B66FB6618E7FFE7FFE61867DB67B8677B677B67FFE0000
+ED7B:00007FFE618E6FB663B66FB6618E7FFE7FFE618E7DB67B8E77B6778E7FFE0000
+ED7C:00007FFE618E6FB663B66FB6618E7FFE7FFE61C67DBE7BBE77BE77C67FFE0000
+ED7D:00007FFE618E6FB663B66FB6618E7FFE7FFE618E7DB67BB677B6778E7FFE0000
+ED7E:00007FFE618E6FB663B66FB6618E7FFE7FFE61867DBE7B8E77BE77867FFE0000
+ED7F:00007FFE618E6FB663B66FB6618E7FFE7FFE61867DBE7B8E77BE77BE7FFE0000
+ED80:00007FFE618E6FB663B66FB6618E7FFE7FFE73CE6DB673B66DB673CE7FFE0000
+ED81:00007FFE618E6FB663B66FB6618E7FFE7FFE73EE6DCE73EE6DEE73C67FFE0000
+ED82:00007FFE618E6FB663B66FB6618E7FFE7FFE73866DF673866DBE73867FFE0000
+ED83:00007FFE618E6FB663B66FB6618E7FFE7FFE738E6DF673C66DF6738E7FFE0000
+ED84:00007FFE618E6FB663B66FB6618E7FFE7FFE73B66DB673866DF673F67FFE0000
+ED85:00007FFE618E6FB663B66FB6618E7FFE7FFE73866DBE73866DF673867FFE0000
+ED86:00007FFE618E6FB663B66FB6618E7FFE7FFE73CE6DBE738E6DB673CE7FFE0000
+ED87:00007FFE618E6FB663B66FB6618E7FFE7FFE73866DF673EE6DDE73DE7FFE0000
+ED88:00007FFE618E6FB663B66FB6618E7FFE7FFE73CE6DB673CE6DB673CE7FFE0000
+ED89:00007FFE618E6FB663B66FB6618E7FFE7FFE73CE6DB673C66DF673CE7FFE0000
+ED8A:00007FFE618E6FB663B66FB6618E7FFE7FFE73866DB673866DB673B67FFE0000
+ED8B:00007FFE618E6FB663B66FB6618E7FFE7FFE738E6DB6738E6DB6738E7FFE0000
+ED8C:00007FFE618E6FB663B66FB6618E7FFE7FFE73C66DBE73BE6DBE73C67FFE0000
+ED8D:00007FFE618E6FB663B66FB6618E7FFE7FFE738E6DB673B66DB6738E7FFE0000
+ED8E:00007FFE618E6FB663B66FB6618E7FFE7FFE73866DBE738E6DBE73867FFE0000
+ED8F:00007FFE618E6FB663B66FB6618E7FFE7FFE73866DBE738E6DBE73BE7FFE0000
+ED90:00007FFE618E6FB663B66FB6618E7FFE7FFE73CE6DB671B67DB673CE7FFE0000
+ED91:00007FFE618E6FB663B66FB6618E7FFE7FFE73EE6DCE71EE7DEE73C67FFE0000
+ED92:00007FFE618E6FB663B66FB6618E7FFE7FFE73866DF671867DBE73867FFE0000
+ED93:00007FFE618E6FB663B66FB6618E7FFE7FFE738E6DF671C67DF6738E7FFE0000
+ED94:00007FFE618E6FB663B66FB6618E7FFE7FFE73B66DB671867DF673F67FFE0000
+ED95:00007FFE618E6FB663B66FB6618E7FFE7FFE73866DBE71867DF673867FFE0000
+ED96:00007FFE618E6FB663B66FB6618E7FFE7FFE73CE6DBE718E7DB673CE7FFE0000
+ED97:00007FFE618E6FB663B66FB6618E7FFE7FFE73866DF671EE7DDE73DE7FFE0000
+ED98:00007FFE618E6FB663B66FB6618E7FFE7FFE73CE6DB671CE7DB673CE7FFE0000
+ED99:00007FFE618E6FB663B66FB6618E7FFE7FFE73CE6DB671C67DF673CE7FFE0000
+ED9A:00007FFE618E6FB663B66FB6618E7FFE7FFE73866DB671867DB673B67FFE0000
+ED9B:00007FFE618E6FB663B66FB6618E7FFE7FFE738E6DB6718E7DB6738E7FFE0000
+ED9C:00007FFE618E6FB663B66FB6618E7FFE7FFE73C66DBE71BE7DBE73C67FFE0000
+ED9D:00007FFE618E6FB663B66FB6618E7FFE7FFE738E6DB671B67DB6738E7FFE0000
+ED9E:00007FFE618E6FB663B66FB6618E7FFE7FFE73866DBE718E7DBE73867FFE0000
+ED9F:00007FFE618E6FB663B66FB6618E7FFE7FFE73866DBE718E7DBE73BE7FFE0000
+EDA0:00007FFE618E6FB663B66FB6618E7FFE7FFE61CE6DB661B66DB66DCE7FFE0000
+EDA1:00007FFE618E6FB663B66FB6618E7FFE7FFE61EE6DCE61EE6DEE6DC67FFE0000
+EDA2:00007FFE618E6FB663B66FB6618E7FFE7FFE61866DF661866DBE6D867FFE0000
+EDA3:00007FFE618E6FB663B66FB6618E7FFE7FFE618E6DF661C66DF66D8E7FFE0000
+EDA4:00007FFE618E6FB663B66FB6618E7FFE7FFE61B66DB661866DF66DF67FFE0000
+EDA5:00007FFE618E6FB663B66FB6618E7FFE7FFE61866DBE61866DF66D867FFE0000
+EDA6:00007FFE618E6FB663B66FB6618E7FFE7FFE61CE6DBE618E6DB66DCE7FFE0000
+EDA7:00007FFE618E6FB663B66FB6618E7FFE7FFE61866DF661EE6DDE6DDE7FFE0000
+EDA8:00007FFE618E6FB663B66FB6618E7FFE7FFE61CE6DB661CE6DB66DCE7FFE0000
+EDA9:00007FFE618E6FB663B66FB6618E7FFE7FFE61CE6DB661C66DF66DCE7FFE0000
+EDAA:00007FFE618E6FB663B66FB6618E7FFE7FFE61866DB661866DB66DB67FFE0000
+EDAB:00007FFE618E6FB663B66FB6618E7FFE7FFE618E6DB6618E6DB66D8E7FFE0000
+EDAC:00007FFE618E6FB663B66FB6618E7FFE7FFE61C66DBE61BE6DBE6DC67FFE0000
+EDAD:00007FFE618E6FB663B66FB6618E7FFE7FFE618E6DB661B66DB66D8E7FFE0000
+EDAE:00007FFE618E6FB663B66FB6618E7FFE7FFE61866DBE618E6DBE6D867FFE0000
+EDAF:00007FFE618E6FB663B66FB6618E7FFE7FFE61866DBE618E6DBE6DBE7FFE0000
+EDB0:00007FFE618E6FB663B66FB6618E7FFE7FFE63CE6DB663B66DB663CE7FFE0000
+EDB1:00007FFE618E6FB663B66FB6618E7FFE7FFE63EE6DCE63EE6DEE63C67FFE0000
+EDB2:00007FFE618E6FB663B66FB6618E7FFE7FFE63866DF663866DBE63867FFE0000
+EDB3:00007FFE618E6FB663B66FB6618E7FFE7FFE638E6DF663C66DF6638E7FFE0000
+EDB4:00007FFE618E6FB663B66FB6618E7FFE7FFE63B66DB663866DF663F67FFE0000
+EDB5:00007FFE618E6FB663B66FB6618E7FFE7FFE63866DBE63866DF663867FFE0000
+EDB6:00007FFE618E6FB663B66FB6618E7FFE7FFE63CE6DBE638E6DB663CE7FFE0000
+EDB7:00007FFE618E6FB663B66FB6618E7FFE7FFE63866DF663EE6DDE63DE7FFE0000
+EDB8:00007FFE618E6FB663B66FB6618E7FFE7FFE63CE6DB663CE6DB663CE7FFE0000
+EDB9:00007FFE618E6FB663B66FB6618E7FFE7FFE63CE6DB663C66DF663CE7FFE0000
+EDBA:00007FFE618E6FB663B66FB6618E7FFE7FFE63866DB663866DB663B67FFE0000
+EDBB:00007FFE618E6FB663B66FB6618E7FFE7FFE638E6DB6638E6DB6638E7FFE0000
+EDBC:00007FFE618E6FB663B66FB6618E7FFE7FFE63C66DBE63BE6DBE63C67FFE0000
+EDBD:00007FFE618E6FB663B66FB6618E7FFE7FFE638E6DB663B66DB6638E7FFE0000
+EDBE:00007FFE618E6FB663B66FB6618E7FFE7FFE63866DBE638E6DBE63867FFE0000
+EDBF:00007FFE618E6FB663B66FB6618E7FFE7FFE63866DBE638E6DBE63BE7FFE0000
+EDC0:00007FFE618E6FB663B66FB6618E7FFE7FFE71CE6FB66FB66FB671CE7FFE0000
+EDC1:00007FFE618E6FB663B66FB6618E7FFE7FFE71EE6FCE6FEE6FEE71C67FFE0000
+EDC2:00007FFE618E6FB663B66FB6618E7FFE7FFE71866FF66F866FBE71867FFE0000
+EDC3:00007FFE618E6FB663B66FB6618E7FFE7FFE718E6FF66FC66FF6718E7FFE0000
+EDC4:00007FFE618E6FB663B66FB6618E7FFE7FFE71B66FB66F866FF671F67FFE0000
+EDC5:00007FFE618E6FB663B66FB6618E7FFE7FFE71866FBE6F866FF671867FFE0000
+EDC6:00007FFE618E6FB663B66FB6618E7FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000
+EDC7:00007FFE618E6FB663B66FB6618E7FFE7FFE71866FF66FEE6FDE71DE7FFE0000
+EDC8:00007FFE618E6FB663B66FB6618E7FFE7FFE71CE6FB66FCE6FB671CE7FFE0000
+EDC9:00007FFE618E6FB663B66FB6618E7FFE7FFE71CE6FB66FC66FF671CE7FFE0000
+EDCA:00007FFE618E6FB663B66FB6618E7FFE7FFE71866FB66F866FB671B67FFE0000
+EDCB:00007FFE618E6FB663B66FB6618E7FFE7FFE718E6FB66F8E6FB6718E7FFE0000
+EDCC:00007FFE618E6FB663B66FB6618E7FFE7FFE71C66FBE6FBE6FBE71C67FFE0000
+EDCD:00007FFE618E6FB663B66FB6618E7FFE7FFE718E6FB66FB66FB6718E7FFE0000
+EDCE:00007FFE618E6FB663B66FB6618E7FFE7FFE71866FBE6F8E6FBE71867FFE0000
+EDCF:00007FFE618E6FB663B66FB6618E7FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+EDD0:00007FFE618E6FB663B66FB6618E7FFE7FFE63CE6DB66DB66DB663CE7FFE0000
+EDD1:00007FFE618E6FB663B66FB6618E7FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000
+EDD2:00007FFE618E6FB663B66FB6618E7FFE7FFE63866DF66D866DBE63867FFE0000
+EDD3:00007FFE618E6FB663B66FB6618E7FFE7FFE638E6DF66DC66DF6638E7FFE0000
+EDD4:00007FFE618E6FB663B66FB6618E7FFE7FFE63B66DB66D866DF663F67FFE0000
+EDD5:00007FFE618E6FB663B66FB6618E7FFE7FFE63866DBE6D866DF663867FFE0000
+EDD6:00007FFE618E6FB663B66FB6618E7FFE7FFE63CE6DBE6D8E6DB663CE7FFE0000
+EDD7:00007FFE618E6FB663B66FB6618E7FFE7FFE63866DF66DEE6DDE63DE7FFE0000
+EDD8:00007FFE618E6FB663B66FB6618E7FFE7FFE63CE6DB66DCE6DB663CE7FFE0000
+EDD9:00007FFE618E6FB663B66FB6618E7FFE7FFE63CE6DB66DC66DF663CE7FFE0000
+EDDA:00007FFE618E6FB663B66FB6618E7FFE7FFE63866DB66D866DB663B67FFE0000
+EDDB:00007FFE618E6FB663B66FB6618E7FFE7FFE638E6DB66D8E6DB6638E7FFE0000
+EDDC:00007FFE618E6FB663B66FB6618E7FFE7FFE63C66DBE6DBE6DBE63C67FFE0000
+EDDD:00007FFE618E6FB663B66FB6618E7FFE7FFE638E6DB66DB66DB6638E7FFE0000
+EDDE:00007FFE618E6FB663B66FB6618E7FFE7FFE63866DBE6D8E6DBE63867FFE0000
+EDDF:00007FFE618E6FB663B66FB6618E7FFE7FFE63866DBE6D8E6DBE63BE7FFE0000
+EDE0:00007FFE618E6FB663B66FB6618E7FFE7FFE61CE6FB663B66FB661CE7FFE0000
+EDE1:00007FFE618E6FB663B66FB6618E7FFE7FFE61EE6FCE63EE6FEE61C67FFE0000
+EDE2:00007FFE618E6FB663B66FB6618E7FFE7FFE61866FF663866FBE61867FFE0000
+EDE3:00007FFE618E6FB663B66FB6618E7FFE7FFE618E6FF663C66FF6618E7FFE0000
+EDE4:00007FFE618E6FB663B66FB6618E7FFE7FFE61B66FB663866FF661F67FFE0000
+EDE5:00007FFE618E6FB663B66FB6618E7FFE7FFE61866FBE63866FF661867FFE0000
+EDE6:00007FFE618E6FB663B66FB6618E7FFE7FFE61CE6FBE638E6FB661CE7FFE0000
+EDE7:00007FFE618E6FB663B66FB6618E7FFE7FFE61866FF663EE6FDE61DE7FFE0000
+EDE8:00007FFE618E6FB663B66FB6618E7FFE7FFE61CE6FB663CE6FB661CE7FFE0000
+EDE9:00007FFE618E6FB663B66FB6618E7FFE7FFE61CE6FB663C66FF661CE7FFE0000
+EDEA:00007FFE618E6FB663B66FB6618E7FFE7FFE61866FB663866FB661B67FFE0000
+EDEB:00007FFE618E6FB663B66FB6618E7FFE7FFE618E6FB6638E6FB6618E7FFE0000
+EDEC:00007FFE618E6FB663B66FB6618E7FFE7FFE61C66FBE63BE6FBE61C67FFE0000
+EDED:00007FFE618E6FB663B66FB6618E7FFE7FFE618E6FB663B66FB6618E7FFE0000
+EDEE:00007FFE618E6FB663B66FB6618E7FFE7FFE61866FBE638E6FBE61867FFE0000
+EDEF:00007FFE618E6FB663B66FB6618E7FFE7FFE61866FBE638E6FBE61BE7FFE0000
+EDF0:00007FFE618E6FB663B66FB6618E7FFE7FFE61CE6FB663B66FB66FCE7FFE0000
+EDF1:00007FFE618E6FB663B66FB6618E7FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000
+EDF2:00007FFE618E6FB663B66FB6618E7FFE7FFE61866FF663866FBE6F867FFE0000
+EDF3:00007FFE618E6FB663B66FB6618E7FFE7FFE618E6FF663C66FF66F8E7FFE0000
+EDF4:00007FFE618E6FB663B66FB6618E7FFE7FFE61B66FB663866FF66FF67FFE0000
+EDF5:00007FFE618E6FB663B66FB6618E7FFE7FFE61866FBE63866FF66F867FFE0000
+EDF6:00007FFE618E6FB663B66FB6618E7FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+EDF7:00007FFE618E6FB663B66FB6618E7FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+EDF8:00007FFE618E6FB663B66FB6618E7FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+EDF9:00007FFE618E6FB663B66FB6618E7FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+EDFA:00007FFE618E6FB663B66FB6618E7FFE7FFE61866FB663866FB66FB67FFE0000
+EDFB:00007FFE618E6FB663B66FB6618E7FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+EDFC:00007FFE618E6FB663B66FB6618E7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+EDFD:00007FFE618E6FB663B66FB6618E7FFE7FFE618E6FB663B66FB66F8E7FFE0000
+EDFE:00007FFE618E6FB663B66FB6618E7FFE7FFE61866FBE638E6FBE6F867FFE0000
+EDFF:00007FFE618E6FB663B66FB6618E7FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+EE00:00007FFE61866FBE638E6FBE61867FFE7FFE73CE6DB66DB66DB673CE7FFE0000
+EE01:00007FFE61866FBE638E6FBE61867FFE7FFE73EE6DCE6DEE6DEE73C67FFE0000
+EE02:00007FFE61866FBE638E6FBE61867FFE7FFE73866DF66D866DBE73867FFE0000
+EE03:00007FFE61866FBE638E6FBE61867FFE7FFE738E6DF66DC66DF6738E7FFE0000
+EE04:00007FFE61866FBE638E6FBE61867FFE7FFE73B66DB66D866DF673F67FFE0000
+EE05:00007FFE61866FBE638E6FBE61867FFE7FFE73866DBE6D866DF673867FFE0000
+EE06:00007FFE61866FBE638E6FBE61867FFE7FFE73CE6DBE6D8E6DB673CE7FFE0000
+EE07:00007FFE61866FBE638E6FBE61867FFE7FFE73866DF66DEE6DDE73DE7FFE0000
+EE08:00007FFE61866FBE638E6FBE61867FFE7FFE73CE6DB66DCE6DB673CE7FFE0000
+EE09:00007FFE61866FBE638E6FBE61867FFE7FFE73CE6DB66DC66DF673CE7FFE0000
+EE0A:00007FFE61866FBE638E6FBE61867FFE7FFE73866DB66D866DB673B67FFE0000
+EE0B:00007FFE61866FBE638E6FBE61867FFE7FFE738E6DB66D8E6DB6738E7FFE0000
+EE0C:00007FFE61866FBE638E6FBE61867FFE7FFE73C66DBE6DBE6DBE73C67FFE0000
+EE0D:00007FFE61866FBE638E6FBE61867FFE7FFE738E6DB66DB66DB6738E7FFE0000
+EE0E:00007FFE61866FBE638E6FBE61867FFE7FFE73866DBE6D8E6DBE73867FFE0000
+EE0F:00007FFE61866FBE638E6FBE61867FFE7FFE73866DBE6D8E6DBE73BE7FFE0000
+EE10:00007FFE61866FBE638E6FBE61867FFE7FFE7BCE73B67BB67BB671CE7FFE0000
+EE11:00007FFE61866FBE638E6FBE61867FFE7FFE7BEE73CE7BEE7BEE71C67FFE0000
+EE12:00007FFE61866FBE638E6FBE61867FFE7FFE7B8673F67B867BBE71867FFE0000
+EE13:00007FFE61866FBE638E6FBE61867FFE7FFE7B8E73F67BC67BF6718E7FFE0000
+EE14:00007FFE61866FBE638E6FBE61867FFE7FFE7BB673B67B867BF671F67FFE0000
+EE15:00007FFE61866FBE638E6FBE61867FFE7FFE7B8673BE7B867BF671867FFE0000
+EE16:00007FFE61866FBE638E6FBE61867FFE7FFE7BCE73BE7B8E7BB671CE7FFE0000
+EE17:00007FFE61866FBE638E6FBE61867FFE7FFE7B8673F67BEE7BDE71DE7FFE0000
+EE18:00007FFE61866FBE638E6FBE61867FFE7FFE7BCE73B67BCE7BB671CE7FFE0000
+EE19:00007FFE61866FBE638E6FBE61867FFE7FFE7BCE73B67BC67BF671CE7FFE0000
+EE1A:00007FFE61866FBE638E6FBE61867FFE7FFE7B8673B67B867BB671B67FFE0000
+EE1B:00007FFE61866FBE638E6FBE61867FFE7FFE7B8E73B67B8E7BB6718E7FFE0000
+EE1C:00007FFE61866FBE638E6FBE61867FFE7FFE7BC673BE7BBE7BBE71C67FFE0000
+EE1D:00007FFE61866FBE638E6FBE61867FFE7FFE7B8E73B67BB67BB6718E7FFE0000
+EE1E:00007FFE61866FBE638E6FBE61867FFE7FFE7B8673BE7B8E7BBE71867FFE0000
+EE1F:00007FFE61866FBE638E6FBE61867FFE7FFE7B8673BE7B8E7BBE71BE7FFE0000
+EE20:00007FFE61866FBE638E6FBE61867FFE7FFE61CE7DB661B66FB661CE7FFE0000
+EE21:00007FFE61866FBE638E6FBE61867FFE7FFE61EE7DCE61EE6FEE61C67FFE0000
+EE22:00007FFE61866FBE638E6FBE61867FFE7FFE61867DF661866FBE61867FFE0000
+EE23:00007FFE61866FBE638E6FBE61867FFE7FFE618E7DF661C66FF6618E7FFE0000
+EE24:00007FFE61866FBE638E6FBE61867FFE7FFE61B67DB661866FF661F67FFE0000
+EE25:00007FFE61866FBE638E6FBE61867FFE7FFE61867DBE61866FF661867FFE0000
+EE26:00007FFE61866FBE638E6FBE61867FFE7FFE61CE7DBE618E6FB661CE7FFE0000
+EE27:00007FFE61866FBE638E6FBE61867FFE7FFE61867DF661EE6FDE61DE7FFE0000
+EE28:00007FFE61866FBE638E6FBE61867FFE7FFE61CE7DB661CE6FB661CE7FFE0000
+EE29:00007FFE61866FBE638E6FBE61867FFE7FFE61CE7DB661C66FF661CE7FFE0000
+EE2A:00007FFE61866FBE638E6FBE61867FFE7FFE61867DB661866FB661B67FFE0000
+EE2B:00007FFE61866FBE638E6FBE61867FFE7FFE618E7DB6618E6FB6618E7FFE0000
+EE2C:00007FFE61866FBE638E6FBE61867FFE7FFE61C67DBE61BE6FBE61C67FFE0000
+EE2D:00007FFE61866FBE638E6FBE61867FFE7FFE618E7DB661B66FB6618E7FFE0000
+EE2E:00007FFE61866FBE638E6FBE61867FFE7FFE61867DBE618E6FBE61867FFE0000
+EE2F:00007FFE61866FBE638E6FBE61867FFE7FFE61867DBE618E6FBE61BE7FFE0000
+EE30:00007FFE61866FBE638E6FBE61867FFE7FFE63CE7DB671B67DB663CE7FFE0000
+EE31:00007FFE61866FBE638E6FBE61867FFE7FFE63EE7DCE71EE7DEE63C67FFE0000
+EE32:00007FFE61866FBE638E6FBE61867FFE7FFE63867DF671867DBE63867FFE0000
+EE33:00007FFE61866FBE638E6FBE61867FFE7FFE638E7DF671C67DF6638E7FFE0000
+EE34:00007FFE61866FBE638E6FBE61867FFE7FFE63B67DB671867DF663F67FFE0000
+EE35:00007FFE61866FBE638E6FBE61867FFE7FFE63867DBE71867DF663867FFE0000
+EE36:00007FFE61866FBE638E6FBE61867FFE7FFE63CE7DBE718E7DB663CE7FFE0000
+EE37:00007FFE61866FBE638E6FBE61867FFE7FFE63867DF671EE7DDE63DE7FFE0000
+EE38:00007FFE61866FBE638E6FBE61867FFE7FFE63CE7DB671CE7DB663CE7FFE0000
+EE39:00007FFE61866FBE638E6FBE61867FFE7FFE63CE7DB671C67DF663CE7FFE0000
+EE3A:00007FFE61866FBE638E6FBE61867FFE7FFE63867DB671867DB663B67FFE0000
+EE3B:00007FFE61866FBE638E6FBE61867FFE7FFE638E7DB6718E7DB6638E7FFE0000
+EE3C:00007FFE61866FBE638E6FBE61867FFE7FFE63C67DBE71BE7DBE63C67FFE0000
+EE3D:00007FFE61866FBE638E6FBE61867FFE7FFE638E7DB671B67DB6638E7FFE0000
+EE3E:00007FFE61866FBE638E6FBE61867FFE7FFE63867DBE718E7DBE63867FFE0000
+EE3F:00007FFE61866FBE638E6FBE61867FFE7FFE63867DBE718E7DBE63BE7FFE0000
+EE40:00007FFE61866FBE638E6FBE61867FFE7FFE6DCE6DB661B67DB67DCE7FFE0000
+EE41:00007FFE61866FBE638E6FBE61867FFE7FFE6DEE6DCE61EE7DEE7DC67FFE0000
+EE42:00007FFE61866FBE638E6FBE61867FFE7FFE6D866DF661867DBE7D867FFE0000
+EE43:00007FFE61866FBE638E6FBE61867FFE7FFE6D8E6DF661C67DF67D8E7FFE0000
+EE44:00007FFE61866FBE638E6FBE61867FFE7FFE6DB66DB661867DF67DF67FFE0000
+EE45:00007FFE61866FBE638E6FBE61867FFE7FFE6D866DBE61867DF67D867FFE0000
+EE46:00007FFE61866FBE638E6FBE61867FFE7FFE6DCE6DBE618E7DB67DCE7FFE0000
+EE47:00007FFE61866FBE638E6FBE61867FFE7FFE6D866DF661EE7DDE7DDE7FFE0000
+EE48:00007FFE61866FBE638E6FBE61867FFE7FFE6DCE6DB661CE7DB67DCE7FFE0000
+EE49:00007FFE61866FBE638E6FBE61867FFE7FFE6DCE6DB661C67DF67DCE7FFE0000
+EE4A:00007FFE61866FBE638E6FBE61867FFE7FFE6D866DB661867DB67DB67FFE0000
+EE4B:00007FFE61866FBE638E6FBE61867FFE7FFE6D8E6DB6618E7DB67D8E7FFE0000
+EE4C:00007FFE61866FBE638E6FBE61867FFE7FFE6DC66DBE61BE7DBE7DC67FFE0000
+EE4D:00007FFE61866FBE638E6FBE61867FFE7FFE6D8E6DB661B67DB67D8E7FFE0000
+EE4E:00007FFE61866FBE638E6FBE61867FFE7FFE6D866DBE618E7DBE7D867FFE0000
+EE4F:00007FFE61866FBE638E6FBE61867FFE7FFE6D866DBE618E7DBE7DBE7FFE0000
+EE50:00007FFE61866FBE638E6FBE61867FFE7FFE61CE6FB661B67DB661CE7FFE0000
+EE51:00007FFE61866FBE638E6FBE61867FFE7FFE61EE6FCE61EE7DEE61C67FFE0000
+EE52:00007FFE61866FBE638E6FBE61867FFE7FFE61866FF661867DBE61867FFE0000
+EE53:00007FFE61866FBE638E6FBE61867FFE7FFE618E6FF661C67DF6618E7FFE0000
+EE54:00007FFE61866FBE638E6FBE61867FFE7FFE61B66FB661867DF661F67FFE0000
+EE55:00007FFE61866FBE638E6FBE61867FFE7FFE61866FBE61867DF661867FFE0000
+EE56:00007FFE61866FBE638E6FBE61867FFE7FFE61CE6FBE618E7DB661CE7FFE0000
+EE57:00007FFE61866FBE638E6FBE61867FFE7FFE61866FF661EE7DDE61DE7FFE0000
+EE58:00007FFE61866FBE638E6FBE61867FFE7FFE61CE6FB661CE7DB661CE7FFE0000
+EE59:00007FFE61866FBE638E6FBE61867FFE7FFE61CE6FB661C67DF661CE7FFE0000
+EE5A:00007FFE61866FBE638E6FBE61867FFE7FFE61866FB661867DB661B67FFE0000
+EE5B:00007FFE61866FBE638E6FBE61867FFE7FFE618E6FB6618E7DB6618E7FFE0000
+EE5C:00007FFE61866FBE638E6FBE61867FFE7FFE61C66FBE61BE7DBE61C67FFE0000
+EE5D:00007FFE61866FBE638E6FBE61867FFE7FFE618E6FB661B67DB6618E7FFE0000
+EE5E:00007FFE61866FBE638E6FBE61867FFE7FFE61866FBE618E7DBE61867FFE0000
+EE5F:00007FFE61866FBE638E6FBE61867FFE7FFE61866FBE618E7DBE61BE7FFE0000
+EE60:00007FFE61866FBE638E6FBE61867FFE7FFE73CE6FB663B66DB673CE7FFE0000
+EE61:00007FFE61866FBE638E6FBE61867FFE7FFE73EE6FCE63EE6DEE73C67FFE0000
+EE62:00007FFE61866FBE638E6FBE61867FFE7FFE73866FF663866DBE73867FFE0000
+EE63:00007FFE61866FBE638E6FBE61867FFE7FFE738E6FF663C66DF6738E7FFE0000
+EE64:00007FFE61866FBE638E6FBE61867FFE7FFE73B66FB663866DF673F67FFE0000
+EE65:00007FFE61866FBE638E6FBE61867FFE7FFE73866FBE63866DF673867FFE0000
+EE66:00007FFE61866FBE638E6FBE61867FFE7FFE73CE6FBE638E6DB673CE7FFE0000
+EE67:00007FFE61866FBE638E6FBE61867FFE7FFE73866FF663EE6DDE73DE7FFE0000
+EE68:00007FFE61866FBE638E6FBE61867FFE7FFE73CE6FB663CE6DB673CE7FFE0000
+EE69:00007FFE61866FBE638E6FBE61867FFE7FFE73CE6FB663C66DF673CE7FFE0000
+EE6A:00007FFE61866FBE638E6FBE61867FFE7FFE73866FB663866DB673B67FFE0000
+EE6B:00007FFE61866FBE638E6FBE61867FFE7FFE738E6FB6638E6DB6738E7FFE0000
+EE6C:00007FFE61866FBE638E6FBE61867FFE7FFE73C66FBE63BE6DBE73C67FFE0000
+EE6D:00007FFE61866FBE638E6FBE61867FFE7FFE738E6FB663B66DB6738E7FFE0000
+EE6E:00007FFE61866FBE638E6FBE61867FFE7FFE73866FBE638E6DBE73867FFE0000
+EE6F:00007FFE61866FBE638E6FBE61867FFE7FFE73866FBE638E6DBE73BE7FFE0000
+EE70:00007FFE61866FBE638E6FBE61867FFE7FFE61CE7DB67BB677B677CE7FFE0000
+EE71:00007FFE61866FBE638E6FBE61867FFE7FFE61EE7DCE7BEE77EE77C67FFE0000
+EE72:00007FFE61866FBE638E6FBE61867FFE7FFE61867DF67B8677BE77867FFE0000
+EE73:00007FFE61866FBE638E6FBE61867FFE7FFE618E7DF67BC677F6778E7FFE0000
+EE74:00007FFE61866FBE638E6FBE61867FFE7FFE61B67DB67B8677F677F67FFE0000
+EE75:00007FFE61866FBE638E6FBE61867FFE7FFE61867DBE7B8677F677867FFE0000
+EE76:00007FFE61866FBE638E6FBE61867FFE7FFE61CE7DBE7B8E77B677CE7FFE0000
+EE77:00007FFE61866FBE638E6FBE61867FFE7FFE61867DF67BEE77DE77DE7FFE0000
+EE78:00007FFE61866FBE638E6FBE61867FFE7FFE61CE7DB67BCE77B677CE7FFE0000
+EE79:00007FFE61866FBE638E6FBE61867FFE7FFE61CE7DB67BC677F677CE7FFE0000
+EE7A:00007FFE61866FBE638E6FBE61867FFE7FFE61867DB67B8677B677B67FFE0000
+EE7B:00007FFE61866FBE638E6FBE61867FFE7FFE618E7DB67B8E77B6778E7FFE0000
+EE7C:00007FFE61866FBE638E6FBE61867FFE7FFE61C67DBE7BBE77BE77C67FFE0000
+EE7D:00007FFE61866FBE638E6FBE61867FFE7FFE618E7DB67BB677B6778E7FFE0000
+EE7E:00007FFE61866FBE638E6FBE61867FFE7FFE61867DBE7B8E77BE77867FFE0000
+EE7F:00007FFE61866FBE638E6FBE61867FFE7FFE61867DBE7B8E77BE77BE7FFE0000
+EE80:00007FFE61866FBE638E6FBE61867FFE7FFE73CE6DB673B66DB673CE7FFE0000
+EE81:00007FFE61866FBE638E6FBE61867FFE7FFE73EE6DCE73EE6DEE73C67FFE0000
+EE82:00007FFE61866FBE638E6FBE61867FFE7FFE73866DF673866DBE73867FFE0000
+EE83:00007FFE61866FBE638E6FBE61867FFE7FFE738E6DF673C66DF6738E7FFE0000
+EE84:00007FFE61866FBE638E6FBE61867FFE7FFE73B66DB673866DF673F67FFE0000
+EE85:00007FFE61866FBE638E6FBE61867FFE7FFE73866DBE73866DF673867FFE0000
+EE86:00007FFE61866FBE638E6FBE61867FFE7FFE73CE6DBE738E6DB673CE7FFE0000
+EE87:00007FFE61866FBE638E6FBE61867FFE7FFE73866DF673EE6DDE73DE7FFE0000
+EE88:00007FFE61866FBE638E6FBE61867FFE7FFE73CE6DB673CE6DB673CE7FFE0000
+EE89:00007FFE61866FBE638E6FBE61867FFE7FFE73CE6DB673C66DF673CE7FFE0000
+EE8A:00007FFE61866FBE638E6FBE61867FFE7FFE73866DB673866DB673B67FFE0000
+EE8B:00007FFE61866FBE638E6FBE61867FFE7FFE738E6DB6738E6DB6738E7FFE0000
+EE8C:00007FFE61866FBE638E6FBE61867FFE7FFE73C66DBE73BE6DBE73C67FFE0000
+EE8D:00007FFE61866FBE638E6FBE61867FFE7FFE738E6DB673B66DB6738E7FFE0000
+EE8E:00007FFE61866FBE638E6FBE61867FFE7FFE73866DBE738E6DBE73867FFE0000
+EE8F:00007FFE61866FBE638E6FBE61867FFE7FFE73866DBE738E6DBE73BE7FFE0000
+EE90:00007FFE61866FBE638E6FBE61867FFE7FFE73CE6DB671B67DB673CE7FFE0000
+EE91:00007FFE61866FBE638E6FBE61867FFE7FFE73EE6DCE71EE7DEE73C67FFE0000
+EE92:00007FFE61866FBE638E6FBE61867FFE7FFE73866DF671867DBE73867FFE0000
+EE93:00007FFE61866FBE638E6FBE61867FFE7FFE738E6DF671C67DF6738E7FFE0000
+EE94:00007FFE61866FBE638E6FBE61867FFE7FFE73B66DB671867DF673F67FFE0000
+EE95:00007FFE61866FBE638E6FBE61867FFE7FFE73866DBE71867DF673867FFE0000
+EE96:00007FFE61866FBE638E6FBE61867FFE7FFE73CE6DBE718E7DB673CE7FFE0000
+EE97:00007FFE61866FBE638E6FBE61867FFE7FFE73866DF671EE7DDE73DE7FFE0000
+EE98:00007FFE61866FBE638E6FBE61867FFE7FFE73CE6DB671CE7DB673CE7FFE0000
+EE99:00007FFE61866FBE638E6FBE61867FFE7FFE73CE6DB671C67DF673CE7FFE0000
+EE9A:00007FFE61866FBE638E6FBE61867FFE7FFE73866DB671867DB673B67FFE0000
+EE9B:00007FFE61866FBE638E6FBE61867FFE7FFE738E6DB6718E7DB6738E7FFE0000
+EE9C:00007FFE61866FBE638E6FBE61867FFE7FFE73C66DBE71BE7DBE73C67FFE0000
+EE9D:00007FFE61866FBE638E6FBE61867FFE7FFE738E6DB671B67DB6738E7FFE0000
+EE9E:00007FFE61866FBE638E6FBE61867FFE7FFE73866DBE718E7DBE73867FFE0000
+EE9F:00007FFE61866FBE638E6FBE61867FFE7FFE73866DBE718E7DBE73BE7FFE0000
+EEA0:00007FFE61866FBE638E6FBE61867FFE7FFE61CE6DB661B66DB66DCE7FFE0000
+EEA1:00007FFE61866FBE638E6FBE61867FFE7FFE61EE6DCE61EE6DEE6DC67FFE0000
+EEA2:00007FFE61866FBE638E6FBE61867FFE7FFE61866DF661866DBE6D867FFE0000
+EEA3:00007FFE61866FBE638E6FBE61867FFE7FFE618E6DF661C66DF66D8E7FFE0000
+EEA4:00007FFE61866FBE638E6FBE61867FFE7FFE61B66DB661866DF66DF67FFE0000
+EEA5:00007FFE61866FBE638E6FBE61867FFE7FFE61866DBE61866DF66D867FFE0000
+EEA6:00007FFE61866FBE638E6FBE61867FFE7FFE61CE6DBE618E6DB66DCE7FFE0000
+EEA7:00007FFE61866FBE638E6FBE61867FFE7FFE61866DF661EE6DDE6DDE7FFE0000
+EEA8:00007FFE61866FBE638E6FBE61867FFE7FFE61CE6DB661CE6DB66DCE7FFE0000
+EEA9:00007FFE61866FBE638E6FBE61867FFE7FFE61CE6DB661C66DF66DCE7FFE0000
+EEAA:00007FFE61866FBE638E6FBE61867FFE7FFE61866DB661866DB66DB67FFE0000
+EEAB:00007FFE61866FBE638E6FBE61867FFE7FFE618E6DB6618E6DB66D8E7FFE0000
+EEAC:00007FFE61866FBE638E6FBE61867FFE7FFE61C66DBE61BE6DBE6DC67FFE0000
+EEAD:00007FFE61866FBE638E6FBE61867FFE7FFE618E6DB661B66DB66D8E7FFE0000
+EEAE:00007FFE61866FBE638E6FBE61867FFE7FFE61866DBE618E6DBE6D867FFE0000
+EEAF:00007FFE61866FBE638E6FBE61867FFE7FFE61866DBE618E6DBE6DBE7FFE0000
+EEB0:00007FFE61866FBE638E6FBE61867FFE7FFE63CE6DB663B66DB663CE7FFE0000
+EEB1:00007FFE61866FBE638E6FBE61867FFE7FFE63EE6DCE63EE6DEE63C67FFE0000
+EEB2:00007FFE61866FBE638E6FBE61867FFE7FFE63866DF663866DBE63867FFE0000
+EEB3:00007FFE61866FBE638E6FBE61867FFE7FFE638E6DF663C66DF6638E7FFE0000
+EEB4:00007FFE61866FBE638E6FBE61867FFE7FFE63B66DB663866DF663F67FFE0000
+EEB5:00007FFE61866FBE638E6FBE61867FFE7FFE63866DBE63866DF663867FFE0000
+EEB6:00007FFE61866FBE638E6FBE61867FFE7FFE63CE6DBE638E6DB663CE7FFE0000
+EEB7:00007FFE61866FBE638E6FBE61867FFE7FFE63866DF663EE6DDE63DE7FFE0000
+EEB8:00007FFE61866FBE638E6FBE61867FFE7FFE63CE6DB663CE6DB663CE7FFE0000
+EEB9:00007FFE61866FBE638E6FBE61867FFE7FFE63CE6DB663C66DF663CE7FFE0000
+EEBA:00007FFE61866FBE638E6FBE61867FFE7FFE63866DB663866DB663B67FFE0000
+EEBB:00007FFE61866FBE638E6FBE61867FFE7FFE638E6DB6638E6DB6638E7FFE0000
+EEBC:00007FFE61866FBE638E6FBE61867FFE7FFE63C66DBE63BE6DBE63C67FFE0000
+EEBD:00007FFE61866FBE638E6FBE61867FFE7FFE638E6DB663B66DB6638E7FFE0000
+EEBE:00007FFE61866FBE638E6FBE61867FFE7FFE63866DBE638E6DBE63867FFE0000
+EEBF:00007FFE61866FBE638E6FBE61867FFE7FFE63866DBE638E6DBE63BE7FFE0000
+EEC0:00007FFE61866FBE638E6FBE61867FFE7FFE71CE6FB66FB66FB671CE7FFE0000
+EEC1:00007FFE61866FBE638E6FBE61867FFE7FFE71EE6FCE6FEE6FEE71C67FFE0000
+EEC2:00007FFE61866FBE638E6FBE61867FFE7FFE71866FF66F866FBE71867FFE0000
+EEC3:00007FFE61866FBE638E6FBE61867FFE7FFE718E6FF66FC66FF6718E7FFE0000
+EEC4:00007FFE61866FBE638E6FBE61867FFE7FFE71B66FB66F866FF671F67FFE0000
+EEC5:00007FFE61866FBE638E6FBE61867FFE7FFE71866FBE6F866FF671867FFE0000
+EEC6:00007FFE61866FBE638E6FBE61867FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000
+EEC7:00007FFE61866FBE638E6FBE61867FFE7FFE71866FF66FEE6FDE71DE7FFE0000
+EEC8:00007FFE61866FBE638E6FBE61867FFE7FFE71CE6FB66FCE6FB671CE7FFE0000
+EEC9:00007FFE61866FBE638E6FBE61867FFE7FFE71CE6FB66FC66FF671CE7FFE0000
+EECA:00007FFE61866FBE638E6FBE61867FFE7FFE71866FB66F866FB671B67FFE0000
+EECB:00007FFE61866FBE638E6FBE61867FFE7FFE718E6FB66F8E6FB6718E7FFE0000
+EECC:00007FFE61866FBE638E6FBE61867FFE7FFE71C66FBE6FBE6FBE71C67FFE0000
+EECD:00007FFE61866FBE638E6FBE61867FFE7FFE718E6FB66FB66FB6718E7FFE0000
+EECE:00007FFE61866FBE638E6FBE61867FFE7FFE71866FBE6F8E6FBE71867FFE0000
+EECF:00007FFE61866FBE638E6FBE61867FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+EED0:00007FFE61866FBE638E6FBE61867FFE7FFE63CE6DB66DB66DB663CE7FFE0000
+EED1:00007FFE61866FBE638E6FBE61867FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000
+EED2:00007FFE61866FBE638E6FBE61867FFE7FFE63866DF66D866DBE63867FFE0000
+EED3:00007FFE61866FBE638E6FBE61867FFE7FFE638E6DF66DC66DF6638E7FFE0000
+EED4:00007FFE61866FBE638E6FBE61867FFE7FFE63B66DB66D866DF663F67FFE0000
+EED5:00007FFE61866FBE638E6FBE61867FFE7FFE63866DBE6D866DF663867FFE0000
+EED6:00007FFE61866FBE638E6FBE61867FFE7FFE63CE6DBE6D8E6DB663CE7FFE0000
+EED7:00007FFE61866FBE638E6FBE61867FFE7FFE63866DF66DEE6DDE63DE7FFE0000
+EED8:00007FFE61866FBE638E6FBE61867FFE7FFE63CE6DB66DCE6DB663CE7FFE0000
+EED9:00007FFE61866FBE638E6FBE61867FFE7FFE63CE6DB66DC66DF663CE7FFE0000
+EEDA:00007FFE61866FBE638E6FBE61867FFE7FFE63866DB66D866DB663B67FFE0000
+EEDB:00007FFE61866FBE638E6FBE61867FFE7FFE638E6DB66D8E6DB6638E7FFE0000
+EEDC:00007FFE61866FBE638E6FBE61867FFE7FFE63C66DBE6DBE6DBE63C67FFE0000
+EEDD:00007FFE61866FBE638E6FBE61867FFE7FFE638E6DB66DB66DB6638E7FFE0000
+EEDE:00007FFE61866FBE638E6FBE61867FFE7FFE63866DBE6D8E6DBE63867FFE0000
+EEDF:00007FFE61866FBE638E6FBE61867FFE7FFE63866DBE6D8E6DBE63BE7FFE0000
+EEE0:00007FFE61866FBE638E6FBE61867FFE7FFE61CE6FB663B66FB661CE7FFE0000
+EEE1:00007FFE61866FBE638E6FBE61867FFE7FFE61EE6FCE63EE6FEE61C67FFE0000
+EEE2:00007FFE61866FBE638E6FBE61867FFE7FFE61866FF663866FBE61867FFE0000
+EEE3:00007FFE61866FBE638E6FBE61867FFE7FFE618E6FF663C66FF6618E7FFE0000
+EEE4:00007FFE61866FBE638E6FBE61867FFE7FFE61B66FB663866FF661F67FFE0000
+EEE5:00007FFE61866FBE638E6FBE61867FFE7FFE61866FBE63866FF661867FFE0000
+EEE6:00007FFE61866FBE638E6FBE61867FFE7FFE61CE6FBE638E6FB661CE7FFE0000
+EEE7:00007FFE61866FBE638E6FBE61867FFE7FFE61866FF663EE6FDE61DE7FFE0000
+EEE8:00007FFE61866FBE638E6FBE61867FFE7FFE61CE6FB663CE6FB661CE7FFE0000
+EEE9:00007FFE61866FBE638E6FBE61867FFE7FFE61CE6FB663C66FF661CE7FFE0000
+EEEA:00007FFE61866FBE638E6FBE61867FFE7FFE61866FB663866FB661B67FFE0000
+EEEB:00007FFE61866FBE638E6FBE61867FFE7FFE618E6FB6638E6FB6618E7FFE0000
+EEEC:00007FFE61866FBE638E6FBE61867FFE7FFE61C66FBE63BE6FBE61C67FFE0000
+EEED:00007FFE61866FBE638E6FBE61867FFE7FFE618E6FB663B66FB6618E7FFE0000
+EEEE:00007FFE61866FBE638E6FBE61867FFE7FFE61866FBE638E6FBE61867FFE0000
+EEEF:00007FFE61866FBE638E6FBE61867FFE7FFE61866FBE638E6FBE61BE7FFE0000
+EEF0:00007FFE61866FBE638E6FBE61867FFE7FFE61CE6FB663B66FB66FCE7FFE0000
+EEF1:00007FFE61866FBE638E6FBE61867FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000
+EEF2:00007FFE61866FBE638E6FBE61867FFE7FFE61866FF663866FBE6F867FFE0000
+EEF3:00007FFE61866FBE638E6FBE61867FFE7FFE618E6FF663C66FF66F8E7FFE0000
+EEF4:00007FFE61866FBE638E6FBE61867FFE7FFE61B66FB663866FF66FF67FFE0000
+EEF5:00007FFE61866FBE638E6FBE61867FFE7FFE61866FBE63866FF66F867FFE0000
+EEF6:00007FFE61866FBE638E6FBE61867FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+EEF7:00007FFE61866FBE638E6FBE61867FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+EEF8:00007FFE61866FBE638E6FBE61867FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+EEF9:00007FFE61866FBE638E6FBE61867FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+EEFA:00007FFE61866FBE638E6FBE61867FFE7FFE61866FB663866FB66FB67FFE0000
+EEFB:00007FFE61866FBE638E6FBE61867FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+EEFC:00007FFE61866FBE638E6FBE61867FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+EEFD:00007FFE61866FBE638E6FBE61867FFE7FFE618E6FB663B66FB66F8E7FFE0000
+EEFE:00007FFE61866FBE638E6FBE61867FFE7FFE61866FBE638E6FBE6F867FFE0000
+EEFF:00007FFE61866FBE638E6FBE61867FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+EF00:00007FFE61866FBE638E6FBE61BE7FFE7FFE73CE6DB66DB66DB673CE7FFE0000
+EF01:00007FFE61866FBE638E6FBE61BE7FFE7FFE73EE6DCE6DEE6DEE73C67FFE0000
+EF02:00007FFE61866FBE638E6FBE61BE7FFE7FFE73866DF66D866DBE73867FFE0000
+EF03:00007FFE61866FBE638E6FBE61BE7FFE7FFE738E6DF66DC66DF6738E7FFE0000
+EF04:00007FFE61866FBE638E6FBE61BE7FFE7FFE73B66DB66D866DF673F67FFE0000
+EF05:00007FFE61866FBE638E6FBE61BE7FFE7FFE73866DBE6D866DF673867FFE0000
+EF06:00007FFE61866FBE638E6FBE61BE7FFE7FFE73CE6DBE6D8E6DB673CE7FFE0000
+EF07:00007FFE61866FBE638E6FBE61BE7FFE7FFE73866DF66DEE6DDE73DE7FFE0000
+EF08:00007FFE61866FBE638E6FBE61BE7FFE7FFE73CE6DB66DCE6DB673CE7FFE0000
+EF09:00007FFE61866FBE638E6FBE61BE7FFE7FFE73CE6DB66DC66DF673CE7FFE0000
+EF0A:00007FFE61866FBE638E6FBE61BE7FFE7FFE73866DB66D866DB673B67FFE0000
+EF0B:00007FFE61866FBE638E6FBE61BE7FFE7FFE738E6DB66D8E6DB6738E7FFE0000
+EF0C:00007FFE61866FBE638E6FBE61BE7FFE7FFE73C66DBE6DBE6DBE73C67FFE0000
+EF0D:00007FFE61866FBE638E6FBE61BE7FFE7FFE738E6DB66DB66DB6738E7FFE0000
+EF0E:00007FFE61866FBE638E6FBE61BE7FFE7FFE73866DBE6D8E6DBE73867FFE0000
+EF0F:00007FFE61866FBE638E6FBE61BE7FFE7FFE73866DBE6D8E6DBE73BE7FFE0000
+EF10:00007FFE61866FBE638E6FBE61BE7FFE7FFE7BCE73B67BB67BB671CE7FFE0000
+EF11:00007FFE61866FBE638E6FBE61BE7FFE7FFE7BEE73CE7BEE7BEE71C67FFE0000
+EF12:00007FFE61866FBE638E6FBE61BE7FFE7FFE7B8673F67B867BBE71867FFE0000
+EF13:00007FFE61866FBE638E6FBE61BE7FFE7FFE7B8E73F67BC67BF6718E7FFE0000
+EF14:00007FFE61866FBE638E6FBE61BE7FFE7FFE7BB673B67B867BF671F67FFE0000
+EF15:00007FFE61866FBE638E6FBE61BE7FFE7FFE7B8673BE7B867BF671867FFE0000
+EF16:00007FFE61866FBE638E6FBE61BE7FFE7FFE7BCE73BE7B8E7BB671CE7FFE0000
+EF17:00007FFE61866FBE638E6FBE61BE7FFE7FFE7B8673F67BEE7BDE71DE7FFE0000
+EF18:00007FFE61866FBE638E6FBE61BE7FFE7FFE7BCE73B67BCE7BB671CE7FFE0000
+EF19:00007FFE61866FBE638E6FBE61BE7FFE7FFE7BCE73B67BC67BF671CE7FFE0000
+EF1A:00007FFE61866FBE638E6FBE61BE7FFE7FFE7B8673B67B867BB671B67FFE0000
+EF1B:00007FFE61866FBE638E6FBE61BE7FFE7FFE7B8E73B67B8E7BB6718E7FFE0000
+EF1C:00007FFE61866FBE638E6FBE61BE7FFE7FFE7BC673BE7BBE7BBE71C67FFE0000
+EF1D:00007FFE61866FBE638E6FBE61BE7FFE7FFE7B8E73B67BB67BB6718E7FFE0000
+EF1E:00007FFE61866FBE638E6FBE61BE7FFE7FFE7B8673BE7B8E7BBE71867FFE0000
+EF1F:00007FFE61866FBE638E6FBE61BE7FFE7FFE7B8673BE7B8E7BBE71BE7FFE0000
+EF20:00007FFE61866FBE638E6FBE61BE7FFE7FFE61CE7DB661B66FB661CE7FFE0000
+EF21:00007FFE61866FBE638E6FBE61BE7FFE7FFE61EE7DCE61EE6FEE61C67FFE0000
+EF22:00007FFE61866FBE638E6FBE61BE7FFE7FFE61867DF661866FBE61867FFE0000
+EF23:00007FFE61866FBE638E6FBE61BE7FFE7FFE618E7DF661C66FF6618E7FFE0000
+EF24:00007FFE61866FBE638E6FBE61BE7FFE7FFE61B67DB661866FF661F67FFE0000
+EF25:00007FFE61866FBE638E6FBE61BE7FFE7FFE61867DBE61866FF661867FFE0000
+EF26:00007FFE61866FBE638E6FBE61BE7FFE7FFE61CE7DBE618E6FB661CE7FFE0000
+EF27:00007FFE61866FBE638E6FBE61BE7FFE7FFE61867DF661EE6FDE61DE7FFE0000
+EF28:00007FFE61866FBE638E6FBE61BE7FFE7FFE61CE7DB661CE6FB661CE7FFE0000
+EF29:00007FFE61866FBE638E6FBE61BE7FFE7FFE61CE7DB661C66FF661CE7FFE0000
+EF2A:00007FFE61866FBE638E6FBE61BE7FFE7FFE61867DB661866FB661B67FFE0000
+EF2B:00007FFE61866FBE638E6FBE61BE7FFE7FFE618E7DB6618E6FB6618E7FFE0000
+EF2C:00007FFE61866FBE638E6FBE61BE7FFE7FFE61C67DBE61BE6FBE61C67FFE0000
+EF2D:00007FFE61866FBE638E6FBE61BE7FFE7FFE618E7DB661B66FB6618E7FFE0000
+EF2E:00007FFE61866FBE638E6FBE61BE7FFE7FFE61867DBE618E6FBE61867FFE0000
+EF2F:00007FFE61866FBE638E6FBE61BE7FFE7FFE61867DBE618E6FBE61BE7FFE0000
+EF30:00007FFE61866FBE638E6FBE61BE7FFE7FFE63CE7DB671B67DB663CE7FFE0000
+EF31:00007FFE61866FBE638E6FBE61BE7FFE7FFE63EE7DCE71EE7DEE63C67FFE0000
+EF32:00007FFE61866FBE638E6FBE61BE7FFE7FFE63867DF671867DBE63867FFE0000
+EF33:00007FFE61866FBE638E6FBE61BE7FFE7FFE638E7DF671C67DF6638E7FFE0000
+EF34:00007FFE61866FBE638E6FBE61BE7FFE7FFE63B67DB671867DF663F67FFE0000
+EF35:00007FFE61866FBE638E6FBE61BE7FFE7FFE63867DBE71867DF663867FFE0000
+EF36:00007FFE61866FBE638E6FBE61BE7FFE7FFE63CE7DBE718E7DB663CE7FFE0000
+EF37:00007FFE61866FBE638E6FBE61BE7FFE7FFE63867DF671EE7DDE63DE7FFE0000
+EF38:00007FFE61866FBE638E6FBE61BE7FFE7FFE63CE7DB671CE7DB663CE7FFE0000
+EF39:00007FFE61866FBE638E6FBE61BE7FFE7FFE63CE7DB671C67DF663CE7FFE0000
+EF3A:00007FFE61866FBE638E6FBE61BE7FFE7FFE63867DB671867DB663B67FFE0000
+EF3B:00007FFE61866FBE638E6FBE61BE7FFE7FFE638E7DB6718E7DB6638E7FFE0000
+EF3C:00007FFE61866FBE638E6FBE61BE7FFE7FFE63C67DBE71BE7DBE63C67FFE0000
+EF3D:00007FFE61866FBE638E6FBE61BE7FFE7FFE638E7DB671B67DB6638E7FFE0000
+EF3E:00007FFE61866FBE638E6FBE61BE7FFE7FFE63867DBE718E7DBE63867FFE0000
+EF3F:00007FFE61866FBE638E6FBE61BE7FFE7FFE63867DBE718E7DBE63BE7FFE0000
+EF40:00007FFE61866FBE638E6FBE61BE7FFE7FFE6DCE6DB661B67DB67DCE7FFE0000
+EF41:00007FFE61866FBE638E6FBE61BE7FFE7FFE6DEE6DCE61EE7DEE7DC67FFE0000
+EF42:00007FFE61866FBE638E6FBE61BE7FFE7FFE6D866DF661867DBE7D867FFE0000
+EF43:00007FFE61866FBE638E6FBE61BE7FFE7FFE6D8E6DF661C67DF67D8E7FFE0000
+EF44:00007FFE61866FBE638E6FBE61BE7FFE7FFE6DB66DB661867DF67DF67FFE0000
+EF45:00007FFE61866FBE638E6FBE61BE7FFE7FFE6D866DBE61867DF67D867FFE0000
+EF46:00007FFE61866FBE638E6FBE61BE7FFE7FFE6DCE6DBE618E7DB67DCE7FFE0000
+EF47:00007FFE61866FBE638E6FBE61BE7FFE7FFE6D866DF661EE7DDE7DDE7FFE0000
+EF48:00007FFE61866FBE638E6FBE61BE7FFE7FFE6DCE6DB661CE7DB67DCE7FFE0000
+EF49:00007FFE61866FBE638E6FBE61BE7FFE7FFE6DCE6DB661C67DF67DCE7FFE0000
+EF4A:00007FFE61866FBE638E6FBE61BE7FFE7FFE6D866DB661867DB67DB67FFE0000
+EF4B:00007FFE61866FBE638E6FBE61BE7FFE7FFE6D8E6DB6618E7DB67D8E7FFE0000
+EF4C:00007FFE61866FBE638E6FBE61BE7FFE7FFE6DC66DBE61BE7DBE7DC67FFE0000
+EF4D:00007FFE61866FBE638E6FBE61BE7FFE7FFE6D8E6DB661B67DB67D8E7FFE0000
+EF4E:00007FFE61866FBE638E6FBE61BE7FFE7FFE6D866DBE618E7DBE7D867FFE0000
+EF4F:00007FFE61866FBE638E6FBE61BE7FFE7FFE6D866DBE618E7DBE7DBE7FFE0000
+EF50:00007FFE61866FBE638E6FBE61BE7FFE7FFE61CE6FB661B67DB661CE7FFE0000
+EF51:00007FFE61866FBE638E6FBE61BE7FFE7FFE61EE6FCE61EE7DEE61C67FFE0000
+EF52:00007FFE61866FBE638E6FBE61BE7FFE7FFE61866FF661867DBE61867FFE0000
+EF53:00007FFE61866FBE638E6FBE61BE7FFE7FFE618E6FF661C67DF6618E7FFE0000
+EF54:00007FFE61866FBE638E6FBE61BE7FFE7FFE61B66FB661867DF661F67FFE0000
+EF55:00007FFE61866FBE638E6FBE61BE7FFE7FFE61866FBE61867DF661867FFE0000
+EF56:00007FFE61866FBE638E6FBE61BE7FFE7FFE61CE6FBE618E7DB661CE7FFE0000
+EF57:00007FFE61866FBE638E6FBE61BE7FFE7FFE61866FF661EE7DDE61DE7FFE0000
+EF58:00007FFE61866FBE638E6FBE61BE7FFE7FFE61CE6FB661CE7DB661CE7FFE0000
+EF59:00007FFE61866FBE638E6FBE61BE7FFE7FFE61CE6FB661C67DF661CE7FFE0000
+EF5A:00007FFE61866FBE638E6FBE61BE7FFE7FFE61866FB661867DB661B67FFE0000
+EF5B:00007FFE61866FBE638E6FBE61BE7FFE7FFE618E6FB6618E7DB6618E7FFE0000
+EF5C:00007FFE61866FBE638E6FBE61BE7FFE7FFE61C66FBE61BE7DBE61C67FFE0000
+EF5D:00007FFE61866FBE638E6FBE61BE7FFE7FFE618E6FB661B67DB6618E7FFE0000
+EF5E:00007FFE61866FBE638E6FBE61BE7FFE7FFE61866FBE618E7DBE61867FFE0000
+EF5F:00007FFE61866FBE638E6FBE61BE7FFE7FFE61866FBE618E7DBE61BE7FFE0000
+EF60:00007FFE61866FBE638E6FBE61BE7FFE7FFE73CE6FB663B66DB673CE7FFE0000
+EF61:00007FFE61866FBE638E6FBE61BE7FFE7FFE73EE6FCE63EE6DEE73C67FFE0000
+EF62:00007FFE61866FBE638E6FBE61BE7FFE7FFE73866FF663866DBE73867FFE0000
+EF63:00007FFE61866FBE638E6FBE61BE7FFE7FFE738E6FF663C66DF6738E7FFE0000
+EF64:00007FFE61866FBE638E6FBE61BE7FFE7FFE73B66FB663866DF673F67FFE0000
+EF65:00007FFE61866FBE638E6FBE61BE7FFE7FFE73866FBE63866DF673867FFE0000
+EF66:00007FFE61866FBE638E6FBE61BE7FFE7FFE73CE6FBE638E6DB673CE7FFE0000
+EF67:00007FFE61866FBE638E6FBE61BE7FFE7FFE73866FF663EE6DDE73DE7FFE0000
+EF68:00007FFE61866FBE638E6FBE61BE7FFE7FFE73CE6FB663CE6DB673CE7FFE0000
+EF69:00007FFE61866FBE638E6FBE61BE7FFE7FFE73CE6FB663C66DF673CE7FFE0000
+EF6A:00007FFE61866FBE638E6FBE61BE7FFE7FFE73866FB663866DB673B67FFE0000
+EF6B:00007FFE61866FBE638E6FBE61BE7FFE7FFE738E6FB6638E6DB6738E7FFE0000
+EF6C:00007FFE61866FBE638E6FBE61BE7FFE7FFE73C66FBE63BE6DBE73C67FFE0000
+EF6D:00007FFE61866FBE638E6FBE61BE7FFE7FFE738E6FB663B66DB6738E7FFE0000
+EF6E:00007FFE61866FBE638E6FBE61BE7FFE7FFE73866FBE638E6DBE73867FFE0000
+EF6F:00007FFE61866FBE638E6FBE61BE7FFE7FFE73866FBE638E6DBE73BE7FFE0000
+EF70:00007FFE61866FBE638E6FBE61BE7FFE7FFE61CE7DB67BB677B677CE7FFE0000
+EF71:00007FFE61866FBE638E6FBE61BE7FFE7FFE61EE7DCE7BEE77EE77C67FFE0000
+EF72:00007FFE61866FBE638E6FBE61BE7FFE7FFE61867DF67B8677BE77867FFE0000
+EF73:00007FFE61866FBE638E6FBE61BE7FFE7FFE618E7DF67BC677F6778E7FFE0000
+EF74:00007FFE61866FBE638E6FBE61BE7FFE7FFE61B67DB67B8677F677F67FFE0000
+EF75:00007FFE61866FBE638E6FBE61BE7FFE7FFE61867DBE7B8677F677867FFE0000
+EF76:00007FFE61866FBE638E6FBE61BE7FFE7FFE61CE7DBE7B8E77B677CE7FFE0000
+EF77:00007FFE61866FBE638E6FBE61BE7FFE7FFE61867DF67BEE77DE77DE7FFE0000
+EF78:00007FFE61866FBE638E6FBE61BE7FFE7FFE61CE7DB67BCE77B677CE7FFE0000
+EF79:00007FFE61866FBE638E6FBE61BE7FFE7FFE61CE7DB67BC677F677CE7FFE0000
+EF7A:00007FFE61866FBE638E6FBE61BE7FFE7FFE61867DB67B8677B677B67FFE0000
+EF7B:00007FFE61866FBE638E6FBE61BE7FFE7FFE618E7DB67B8E77B6778E7FFE0000
+EF7C:00007FFE61866FBE638E6FBE61BE7FFE7FFE61C67DBE7BBE77BE77C67FFE0000
+EF7D:00007FFE61866FBE638E6FBE61BE7FFE7FFE618E7DB67BB677B6778E7FFE0000
+EF7E:00007FFE61866FBE638E6FBE61BE7FFE7FFE61867DBE7B8E77BE77867FFE0000
+EF7F:00007FFE61866FBE638E6FBE61BE7FFE7FFE61867DBE7B8E77BE77BE7FFE0000
+EF80:00007FFE61866FBE638E6FBE61BE7FFE7FFE73CE6DB673B66DB673CE7FFE0000
+EF81:00007FFE61866FBE638E6FBE61BE7FFE7FFE73EE6DCE73EE6DEE73C67FFE0000
+EF82:00007FFE61866FBE638E6FBE61BE7FFE7FFE73866DF673866DBE73867FFE0000
+EF83:00007FFE61866FBE638E6FBE61BE7FFE7FFE738E6DF673C66DF6738E7FFE0000
+EF84:00007FFE61866FBE638E6FBE61BE7FFE7FFE73B66DB673866DF673F67FFE0000
+EF85:00007FFE61866FBE638E6FBE61BE7FFE7FFE73866DBE73866DF673867FFE0000
+EF86:00007FFE61866FBE638E6FBE61BE7FFE7FFE73CE6DBE738E6DB673CE7FFE0000
+EF87:00007FFE61866FBE638E6FBE61BE7FFE7FFE73866DF673EE6DDE73DE7FFE0000
+EF88:00007FFE61866FBE638E6FBE61BE7FFE7FFE73CE6DB673CE6DB673CE7FFE0000
+EF89:00007FFE61866FBE638E6FBE61BE7FFE7FFE73CE6DB673C66DF673CE7FFE0000
+EF8A:00007FFE61866FBE638E6FBE61BE7FFE7FFE73866DB673866DB673B67FFE0000
+EF8B:00007FFE61866FBE638E6FBE61BE7FFE7FFE738E6DB6738E6DB6738E7FFE0000
+EF8C:00007FFE61866FBE638E6FBE61BE7FFE7FFE73C66DBE73BE6DBE73C67FFE0000
+EF8D:00007FFE61866FBE638E6FBE61BE7FFE7FFE738E6DB673B66DB6738E7FFE0000
+EF8E:00007FFE61866FBE638E6FBE61BE7FFE7FFE73866DBE738E6DBE73867FFE0000
+EF8F:00007FFE61866FBE638E6FBE61BE7FFE7FFE73866DBE738E6DBE73BE7FFE0000
+EF90:00007FFE61866FBE638E6FBE61BE7FFE7FFE73CE6DB671B67DB673CE7FFE0000
+EF91:00007FFE61866FBE638E6FBE61BE7FFE7FFE73EE6DCE71EE7DEE73C67FFE0000
+EF92:00007FFE61866FBE638E6FBE61BE7FFE7FFE73866DF671867DBE73867FFE0000
+EF93:00007FFE61866FBE638E6FBE61BE7FFE7FFE738E6DF671C67DF6738E7FFE0000
+EF94:00007FFE61866FBE638E6FBE61BE7FFE7FFE73B66DB671867DF673F67FFE0000
+EF95:00007FFE61866FBE638E6FBE61BE7FFE7FFE73866DBE71867DF673867FFE0000
+EF96:00007FFE61866FBE638E6FBE61BE7FFE7FFE73CE6DBE718E7DB673CE7FFE0000
+EF97:00007FFE61866FBE638E6FBE61BE7FFE7FFE73866DF671EE7DDE73DE7FFE0000
+EF98:00007FFE61866FBE638E6FBE61BE7FFE7FFE73CE6DB671CE7DB673CE7FFE0000
+EF99:00007FFE61866FBE638E6FBE61BE7FFE7FFE73CE6DB671C67DF673CE7FFE0000
+EF9A:00007FFE61866FBE638E6FBE61BE7FFE7FFE73866DB671867DB673B67FFE0000
+EF9B:00007FFE61866FBE638E6FBE61BE7FFE7FFE738E6DB6718E7DB6738E7FFE0000
+EF9C:00007FFE61866FBE638E6FBE61BE7FFE7FFE73C66DBE71BE7DBE73C67FFE0000
+EF9D:00007FFE61866FBE638E6FBE61BE7FFE7FFE738E6DB671B67DB6738E7FFE0000
+EF9E:00007FFE61866FBE638E6FBE61BE7FFE7FFE73866DBE718E7DBE73867FFE0000
+EF9F:00007FFE61866FBE638E6FBE61BE7FFE7FFE73866DBE718E7DBE73BE7FFE0000
+EFA0:00007FFE61866FBE638E6FBE61BE7FFE7FFE61CE6DB661B66DB66DCE7FFE0000
+EFA1:00007FFE61866FBE638E6FBE61BE7FFE7FFE61EE6DCE61EE6DEE6DC67FFE0000
+EFA2:00007FFE61866FBE638E6FBE61BE7FFE7FFE61866DF661866DBE6D867FFE0000
+EFA3:00007FFE61866FBE638E6FBE61BE7FFE7FFE618E6DF661C66DF66D8E7FFE0000
+EFA4:00007FFE61866FBE638E6FBE61BE7FFE7FFE61B66DB661866DF66DF67FFE0000
+EFA5:00007FFE61866FBE638E6FBE61BE7FFE7FFE61866DBE61866DF66D867FFE0000
+EFA6:00007FFE61866FBE638E6FBE61BE7FFE7FFE61CE6DBE618E6DB66DCE7FFE0000
+EFA7:00007FFE61866FBE638E6FBE61BE7FFE7FFE61866DF661EE6DDE6DDE7FFE0000
+EFA8:00007FFE61866FBE638E6FBE61BE7FFE7FFE61CE6DB661CE6DB66DCE7FFE0000
+EFA9:00007FFE61866FBE638E6FBE61BE7FFE7FFE61CE6DB661C66DF66DCE7FFE0000
+EFAA:00007FFE61866FBE638E6FBE61BE7FFE7FFE61866DB661866DB66DB67FFE0000
+EFAB:00007FFE61866FBE638E6FBE61BE7FFE7FFE618E6DB6618E6DB66D8E7FFE0000
+EFAC:00007FFE61866FBE638E6FBE61BE7FFE7FFE61C66DBE61BE6DBE6DC67FFE0000
+EFAD:00007FFE61866FBE638E6FBE61BE7FFE7FFE618E6DB661B66DB66D8E7FFE0000
+EFAE:00007FFE61866FBE638E6FBE61BE7FFE7FFE61866DBE618E6DBE6D867FFE0000
+EFAF:00007FFE61866FBE638E6FBE61BE7FFE7FFE61866DBE618E6DBE6DBE7FFE0000
+EFB0:00007FFE61866FBE638E6FBE61BE7FFE7FFE63CE6DB663B66DB663CE7FFE0000
+EFB1:00007FFE61866FBE638E6FBE61BE7FFE7FFE63EE6DCE63EE6DEE63C67FFE0000
+EFB2:00007FFE61866FBE638E6FBE61BE7FFE7FFE63866DF663866DBE63867FFE0000
+EFB3:00007FFE61866FBE638E6FBE61BE7FFE7FFE638E6DF663C66DF6638E7FFE0000
+EFB4:00007FFE61866FBE638E6FBE61BE7FFE7FFE63B66DB663866DF663F67FFE0000
+EFB5:00007FFE61866FBE638E6FBE61BE7FFE7FFE63866DBE63866DF663867FFE0000
+EFB6:00007FFE61866FBE638E6FBE61BE7FFE7FFE63CE6DBE638E6DB663CE7FFE0000
+EFB7:00007FFE61866FBE638E6FBE61BE7FFE7FFE63866DF663EE6DDE63DE7FFE0000
+EFB8:00007FFE61866FBE638E6FBE61BE7FFE7FFE63CE6DB663CE6DB663CE7FFE0000
+EFB9:00007FFE61866FBE638E6FBE61BE7FFE7FFE63CE6DB663C66DF663CE7FFE0000
+EFBA:00007FFE61866FBE638E6FBE61BE7FFE7FFE63866DB663866DB663B67FFE0000
+EFBB:00007FFE61866FBE638E6FBE61BE7FFE7FFE638E6DB6638E6DB6638E7FFE0000
+EFBC:00007FFE61866FBE638E6FBE61BE7FFE7FFE63C66DBE63BE6DBE63C67FFE0000
+EFBD:00007FFE61866FBE638E6FBE61BE7FFE7FFE638E6DB663B66DB6638E7FFE0000
+EFBE:00007FFE61866FBE638E6FBE61BE7FFE7FFE63866DBE638E6DBE63867FFE0000
+EFBF:00007FFE61866FBE638E6FBE61BE7FFE7FFE63866DBE638E6DBE63BE7FFE0000
+EFC0:00007FFE61866FBE638E6FBE61BE7FFE7FFE71CE6FB66FB66FB671CE7FFE0000
+EFC1:00007FFE61866FBE638E6FBE61BE7FFE7FFE71EE6FCE6FEE6FEE71C67FFE0000
+EFC2:00007FFE61866FBE638E6FBE61BE7FFE7FFE71866FF66F866FBE71867FFE0000
+EFC3:00007FFE61866FBE638E6FBE61BE7FFE7FFE718E6FF66FC66FF6718E7FFE0000
+EFC4:00007FFE61866FBE638E6FBE61BE7FFE7FFE71B66FB66F866FF671F67FFE0000
+EFC5:00007FFE61866FBE638E6FBE61BE7FFE7FFE71866FBE6F866FF671867FFE0000
+EFC6:00007FFE61866FBE638E6FBE61BE7FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000
+EFC7:00007FFE61866FBE638E6FBE61BE7FFE7FFE71866FF66FEE6FDE71DE7FFE0000
+EFC8:00007FFE61866FBE638E6FBE61BE7FFE7FFE71CE6FB66FCE6FB671CE7FFE0000
+EFC9:00007FFE61866FBE638E6FBE61BE7FFE7FFE71CE6FB66FC66FF671CE7FFE0000
+EFCA:00007FFE61866FBE638E6FBE61BE7FFE7FFE71866FB66F866FB671B67FFE0000
+EFCB:00007FFE61866FBE638E6FBE61BE7FFE7FFE718E6FB66F8E6FB6718E7FFE0000
+EFCC:00007FFE61866FBE638E6FBE61BE7FFE7FFE71C66FBE6FBE6FBE71C67FFE0000
+EFCD:00007FFE61866FBE638E6FBE61BE7FFE7FFE718E6FB66FB66FB6718E7FFE0000
+EFCE:00007FFE61866FBE638E6FBE61BE7FFE7FFE71866FBE6F8E6FBE71867FFE0000
+EFCF:00007FFE61866FBE638E6FBE61BE7FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+EFD0:00007FFE61866FBE638E6FBE61BE7FFE7FFE63CE6DB66DB66DB663CE7FFE0000
+EFD1:00007FFE61866FBE638E6FBE61BE7FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000
+EFD2:00007FFE61866FBE638E6FBE61BE7FFE7FFE63866DF66D866DBE63867FFE0000
+EFD3:00007FFE61866FBE638E6FBE61BE7FFE7FFE638E6DF66DC66DF6638E7FFE0000
+EFD4:00007FFE61866FBE638E6FBE61BE7FFE7FFE63B66DB66D866DF663F67FFE0000
+EFD5:00007FFE61866FBE638E6FBE61BE7FFE7FFE63866DBE6D866DF663867FFE0000
+EFD6:00007FFE61866FBE638E6FBE61BE7FFE7FFE63CE6DBE6D8E6DB663CE7FFE0000
+EFD7:00007FFE61866FBE638E6FBE61BE7FFE7FFE63866DF66DEE6DDE63DE7FFE0000
+EFD8:00007FFE61866FBE638E6FBE61BE7FFE7FFE63CE6DB66DCE6DB663CE7FFE0000
+EFD9:00007FFE61866FBE638E6FBE61BE7FFE7FFE63CE6DB66DC66DF663CE7FFE0000
+EFDA:00007FFE61866FBE638E6FBE61BE7FFE7FFE63866DB66D866DB663B67FFE0000
+EFDB:00007FFE61866FBE638E6FBE61BE7FFE7FFE638E6DB66D8E6DB6638E7FFE0000
+EFDC:00007FFE61866FBE638E6FBE61BE7FFE7FFE63C66DBE6DBE6DBE63C67FFE0000
+EFDD:00007FFE61866FBE638E6FBE61BE7FFE7FFE638E6DB66DB66DB6638E7FFE0000
+EFDE:00007FFE61866FBE638E6FBE61BE7FFE7FFE63866DBE6D8E6DBE63867FFE0000
+EFDF:00007FFE61866FBE638E6FBE61BE7FFE7FFE63866DBE6D8E6DBE63BE7FFE0000
+EFE0:00007FFE61866FBE638E6FBE61BE7FFE7FFE61CE6FB663B66FB661CE7FFE0000
+EFE1:00007FFE61866FBE638E6FBE61BE7FFE7FFE61EE6FCE63EE6FEE61C67FFE0000
+EFE2:00007FFE61866FBE638E6FBE61BE7FFE7FFE61866FF663866FBE61867FFE0000
+EFE3:00007FFE61866FBE638E6FBE61BE7FFE7FFE618E6FF663C66FF6618E7FFE0000
+EFE4:00007FFE61866FBE638E6FBE61BE7FFE7FFE61B66FB663866FF661F67FFE0000
+EFE5:00007FFE61866FBE638E6FBE61BE7FFE7FFE61866FBE63866FF661867FFE0000
+EFE6:00007FFE61866FBE638E6FBE61BE7FFE7FFE61CE6FBE638E6FB661CE7FFE0000
+EFE7:00007FFE61866FBE638E6FBE61BE7FFE7FFE61866FF663EE6FDE61DE7FFE0000
+EFE8:00007FFE61866FBE638E6FBE61BE7FFE7FFE61CE6FB663CE6FB661CE7FFE0000
+EFE9:00007FFE61866FBE638E6FBE61BE7FFE7FFE61CE6FB663C66FF661CE7FFE0000
+EFEA:00007FFE61866FBE638E6FBE61BE7FFE7FFE61866FB663866FB661B67FFE0000
+EFEB:00007FFE61866FBE638E6FBE61BE7FFE7FFE618E6FB6638E6FB6618E7FFE0000
+EFEC:00007FFE61866FBE638E6FBE61BE7FFE7FFE61C66FBE63BE6FBE61C67FFE0000
+EFED:00007FFE61866FBE638E6FBE61BE7FFE7FFE618E6FB663B66FB6618E7FFE0000
+EFEE:00007FFE61866FBE638E6FBE61BE7FFE7FFE61866FBE638E6FBE61867FFE0000
+EFEF:00007FFE61866FBE638E6FBE61BE7FFE7FFE61866FBE638E6FBE61BE7FFE0000
+EFF0:00007FFE61866FBE638E6FBE61BE7FFE7FFE61CE6FB663B66FB66FCE7FFE0000
+EFF1:00007FFE61866FBE638E6FBE61BE7FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000
+EFF2:00007FFE61866FBE638E6FBE61BE7FFE7FFE61866FF663866FBE6F867FFE0000
+EFF3:00007FFE61866FBE638E6FBE61BE7FFE7FFE618E6FF663C66FF66F8E7FFE0000
+EFF4:00007FFE61866FBE638E6FBE61BE7FFE7FFE61B66FB663866FF66FF67FFE0000
+EFF5:00007FFE61866FBE638E6FBE61BE7FFE7FFE61866FBE63866FF66F867FFE0000
+EFF6:00007FFE61866FBE638E6FBE61BE7FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+EFF7:00007FFE61866FBE638E6FBE61BE7FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+EFF8:00007FFE61866FBE638E6FBE61BE7FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+EFF9:00007FFE61866FBE638E6FBE61BE7FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+EFFA:00007FFE61866FBE638E6FBE61BE7FFE7FFE61866FB663866FB66FB67FFE0000
+EFFB:00007FFE61866FBE638E6FBE61BE7FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+EFFC:00007FFE61866FBE638E6FBE61BE7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+EFFD:00007FFE61866FBE638E6FBE61BE7FFE7FFE618E6FB663B66FB66F8E7FFE0000
+EFFE:00007FFE61866FBE638E6FBE61BE7FFE7FFE61866FBE638E6FBE6F867FFE0000
+EFFF:00007FFE61866FBE638E6FBE61BE7FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+F000:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73CE6DB66DB66DB673CE7FFE0000
+F001:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73EE6DCE6DEE6DEE73C67FFE0000
+F002:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73866DF66D866DBE73867FFE0000
+F003:00007FFE61CE6FB663B66FB66FCE7FFE7FFE738E6DF66DC66DF6738E7FFE0000
+F004:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73B66DB66D866DF673F67FFE0000
+F005:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73866DBE6D866DF673867FFE0000
+F006:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73CE6DBE6D8E6DB673CE7FFE0000
+F007:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73866DF66DEE6DDE73DE7FFE0000
+F008:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73CE6DB66DCE6DB673CE7FFE0000
+F009:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73CE6DB66DC66DF673CE7FFE0000
+F00A:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73866DB66D866DB673B67FFE0000
+F00B:00007FFE61CE6FB663B66FB66FCE7FFE7FFE738E6DB66D8E6DB6738E7FFE0000
+F00C:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73C66DBE6DBE6DBE73C67FFE0000
+F00D:00007FFE61CE6FB663B66FB66FCE7FFE7FFE738E6DB66DB66DB6738E7FFE0000
+F00E:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73866DBE6D8E6DBE73867FFE0000
+F00F:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73866DBE6D8E6DBE73BE7FFE0000
+F010:00007FFE61CE6FB663B66FB66FCE7FFE7FFE7BCE73B67BB67BB671CE7FFE0000
+F011:00007FFE61CE6FB663B66FB66FCE7FFE7FFE7BEE73CE7BEE7BEE71C67FFE0000
+F012:00007FFE61CE6FB663B66FB66FCE7FFE7FFE7B8673F67B867BBE71867FFE0000
+F013:00007FFE61CE6FB663B66FB66FCE7FFE7FFE7B8E73F67BC67BF6718E7FFE0000
+F014:00007FFE61CE6FB663B66FB66FCE7FFE7FFE7BB673B67B867BF671F67FFE0000
+F015:00007FFE61CE6FB663B66FB66FCE7FFE7FFE7B8673BE7B867BF671867FFE0000
+F016:00007FFE61CE6FB663B66FB66FCE7FFE7FFE7BCE73BE7B8E7BB671CE7FFE0000
+F017:00007FFE61CE6FB663B66FB66FCE7FFE7FFE7B8673F67BEE7BDE71DE7FFE0000
+F018:00007FFE61CE6FB663B66FB66FCE7FFE7FFE7BCE73B67BCE7BB671CE7FFE0000
+F019:00007FFE61CE6FB663B66FB66FCE7FFE7FFE7BCE73B67BC67BF671CE7FFE0000
+F01A:00007FFE61CE6FB663B66FB66FCE7FFE7FFE7B8673B67B867BB671B67FFE0000
+F01B:00007FFE61CE6FB663B66FB66FCE7FFE7FFE7B8E73B67B8E7BB6718E7FFE0000
+F01C:00007FFE61CE6FB663B66FB66FCE7FFE7FFE7BC673BE7BBE7BBE71C67FFE0000
+F01D:00007FFE61CE6FB663B66FB66FCE7FFE7FFE7B8E73B67BB67BB6718E7FFE0000
+F01E:00007FFE61CE6FB663B66FB66FCE7FFE7FFE7B8673BE7B8E7BBE71867FFE0000
+F01F:00007FFE61CE6FB663B66FB66FCE7FFE7FFE7B8673BE7B8E7BBE71BE7FFE0000
+F020:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61CE7DB661B66FB661CE7FFE0000
+F021:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61EE7DCE61EE6FEE61C67FFE0000
+F022:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61867DF661866FBE61867FFE0000
+F023:00007FFE61CE6FB663B66FB66FCE7FFE7FFE618E7DF661C66FF6618E7FFE0000
+F024:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61B67DB661866FF661F67FFE0000
+F025:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61867DBE61866FF661867FFE0000
+F026:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61CE7DBE618E6FB661CE7FFE0000
+F027:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61867DF661EE6FDE61DE7FFE0000
+F028:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61CE7DB661CE6FB661CE7FFE0000
+F029:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61CE7DB661C66FF661CE7FFE0000
+F02A:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61867DB661866FB661B67FFE0000
+F02B:00007FFE61CE6FB663B66FB66FCE7FFE7FFE618E7DB6618E6FB6618E7FFE0000
+F02C:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61C67DBE61BE6FBE61C67FFE0000
+F02D:00007FFE61CE6FB663B66FB66FCE7FFE7FFE618E7DB661B66FB6618E7FFE0000
+F02E:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61867DBE618E6FBE61867FFE0000
+F02F:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61867DBE618E6FBE61BE7FFE0000
+F030:00007FFE61CE6FB663B66FB66FCE7FFE7FFE63CE7DB671B67DB663CE7FFE0000
+F031:00007FFE61CE6FB663B66FB66FCE7FFE7FFE63EE7DCE71EE7DEE63C67FFE0000
+F032:00007FFE61CE6FB663B66FB66FCE7FFE7FFE63867DF671867DBE63867FFE0000
+F033:00007FFE61CE6FB663B66FB66FCE7FFE7FFE638E7DF671C67DF6638E7FFE0000
+F034:00007FFE61CE6FB663B66FB66FCE7FFE7FFE63B67DB671867DF663F67FFE0000
+F035:00007FFE61CE6FB663B66FB66FCE7FFE7FFE63867DBE71867DF663867FFE0000
+F036:00007FFE61CE6FB663B66FB66FCE7FFE7FFE63CE7DBE718E7DB663CE7FFE0000
+F037:00007FFE61CE6FB663B66FB66FCE7FFE7FFE63867DF671EE7DDE63DE7FFE0000
+F038:00007FFE61CE6FB663B66FB66FCE7FFE7FFE63CE7DB671CE7DB663CE7FFE0000
+F039:00007FFE61CE6FB663B66FB66FCE7FFE7FFE63CE7DB671C67DF663CE7FFE0000
+F03A:00007FFE61CE6FB663B66FB66FCE7FFE7FFE63867DB671867DB663B67FFE0000
+F03B:00007FFE61CE6FB663B66FB66FCE7FFE7FFE638E7DB6718E7DB6638E7FFE0000
+F03C:00007FFE61CE6FB663B66FB66FCE7FFE7FFE63C67DBE71BE7DBE63C67FFE0000
+F03D:00007FFE61CE6FB663B66FB66FCE7FFE7FFE638E7DB671B67DB6638E7FFE0000
+F03E:00007FFE61CE6FB663B66FB66FCE7FFE7FFE63867DBE718E7DBE63867FFE0000
+F03F:00007FFE61CE6FB663B66FB66FCE7FFE7FFE63867DBE718E7DBE63BE7FFE0000
+F040:00007FFE61CE6FB663B66FB66FCE7FFE7FFE6DCE6DB661B67DB67DCE7FFE0000
+F041:00007FFE61CE6FB663B66FB66FCE7FFE7FFE6DEE6DCE61EE7DEE7DC67FFE0000
+F042:00007FFE61CE6FB663B66FB66FCE7FFE7FFE6D866DF661867DBE7D867FFE0000
+F043:00007FFE61CE6FB663B66FB66FCE7FFE7FFE6D8E6DF661C67DF67D8E7FFE0000
+F044:00007FFE61CE6FB663B66FB66FCE7FFE7FFE6DB66DB661867DF67DF67FFE0000
+F045:00007FFE61CE6FB663B66FB66FCE7FFE7FFE6D866DBE61867DF67D867FFE0000
+F046:00007FFE61CE6FB663B66FB66FCE7FFE7FFE6DCE6DBE618E7DB67DCE7FFE0000
+F047:00007FFE61CE6FB663B66FB66FCE7FFE7FFE6D866DF661EE7DDE7DDE7FFE0000
+F048:00007FFE61CE6FB663B66FB66FCE7FFE7FFE6DCE6DB661CE7DB67DCE7FFE0000
+F049:00007FFE61CE6FB663B66FB66FCE7FFE7FFE6DCE6DB661C67DF67DCE7FFE0000
+F04A:00007FFE61CE6FB663B66FB66FCE7FFE7FFE6D866DB661867DB67DB67FFE0000
+F04B:00007FFE61CE6FB663B66FB66FCE7FFE7FFE6D8E6DB6618E7DB67D8E7FFE0000
+F04C:00007FFE61CE6FB663B66FB66FCE7FFE7FFE6DC66DBE61BE7DBE7DC67FFE0000
+F04D:00007FFE61CE6FB663B66FB66FCE7FFE7FFE6D8E6DB661B67DB67D8E7FFE0000
+F04E:00007FFE61CE6FB663B66FB66FCE7FFE7FFE6D866DBE618E7DBE7D867FFE0000
+F04F:00007FFE61CE6FB663B66FB66FCE7FFE7FFE6D866DBE618E7DBE7DBE7FFE0000
+F050:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61CE6FB661B67DB661CE7FFE0000
+F051:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61EE6FCE61EE7DEE61C67FFE0000
+F052:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61866FF661867DBE61867FFE0000
+F053:00007FFE61CE6FB663B66FB66FCE7FFE7FFE618E6FF661C67DF6618E7FFE0000
+F054:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61B66FB661867DF661F67FFE0000
+F055:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61866FBE61867DF661867FFE0000
+F056:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61CE6FBE618E7DB661CE7FFE0000
+F057:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61866FF661EE7DDE61DE7FFE0000
+F058:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61CE6FB661CE7DB661CE7FFE0000
+F059:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61CE6FB661C67DF661CE7FFE0000
+F05A:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61866FB661867DB661B67FFE0000
+F05B:00007FFE61CE6FB663B66FB66FCE7FFE7FFE618E6FB6618E7DB6618E7FFE0000
+F05C:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61C66FBE61BE7DBE61C67FFE0000
+F05D:00007FFE61CE6FB663B66FB66FCE7FFE7FFE618E6FB661B67DB6618E7FFE0000
+F05E:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61866FBE618E7DBE61867FFE0000
+F05F:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61866FBE618E7DBE61BE7FFE0000
+F060:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73CE6FB663B66DB673CE7FFE0000
+F061:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73EE6FCE63EE6DEE73C67FFE0000
+F062:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73866FF663866DBE73867FFE0000
+F063:00007FFE61CE6FB663B66FB66FCE7FFE7FFE738E6FF663C66DF6738E7FFE0000
+F064:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73B66FB663866DF673F67FFE0000
+F065:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73866FBE63866DF673867FFE0000
+F066:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73CE6FBE638E6DB673CE7FFE0000
+F067:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73866FF663EE6DDE73DE7FFE0000
+F068:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73CE6FB663CE6DB673CE7FFE0000
+F069:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73CE6FB663C66DF673CE7FFE0000
+F06A:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73866FB663866DB673B67FFE0000
+F06B:00007FFE61CE6FB663B66FB66FCE7FFE7FFE738E6FB6638E6DB6738E7FFE0000
+F06C:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73C66FBE63BE6DBE73C67FFE0000
+F06D:00007FFE61CE6FB663B66FB66FCE7FFE7FFE738E6FB663B66DB6738E7FFE0000
+F06E:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73866FBE638E6DBE73867FFE0000
+F06F:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73866FBE638E6DBE73BE7FFE0000
+F070:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61CE7DB67BB677B677CE7FFE0000
+F071:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61EE7DCE7BEE77EE77C67FFE0000
+F072:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61867DF67B8677BE77867FFE0000
+F073:00007FFE61CE6FB663B66FB66FCE7FFE7FFE618E7DF67BC677F6778E7FFE0000
+F074:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61B67DB67B8677F677F67FFE0000
+F075:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61867DBE7B8677F677867FFE0000
+F076:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61CE7DBE7B8E77B677CE7FFE0000
+F077:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61867DF67BEE77DE77DE7FFE0000
+F078:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61CE7DB67BCE77B677CE7FFE0000
+F079:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61CE7DB67BC677F677CE7FFE0000
+F07A:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61867DB67B8677B677B67FFE0000
+F07B:00007FFE61CE6FB663B66FB66FCE7FFE7FFE618E7DB67B8E77B6778E7FFE0000
+F07C:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61C67DBE7BBE77BE77C67FFE0000
+F07D:00007FFE61CE6FB663B66FB66FCE7FFE7FFE618E7DB67BB677B6778E7FFE0000
+F07E:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61867DBE7B8E77BE77867FFE0000
+F07F:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61867DBE7B8E77BE77BE7FFE0000
+F080:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73CE6DB673B66DB673CE7FFE0000
+F081:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73EE6DCE73EE6DEE73C67FFE0000
+F082:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73866DF673866DBE73867FFE0000
+F083:00007FFE61CE6FB663B66FB66FCE7FFE7FFE738E6DF673C66DF6738E7FFE0000
+F084:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73B66DB673866DF673F67FFE0000
+F085:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73866DBE73866DF673867FFE0000
+F086:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73CE6DBE738E6DB673CE7FFE0000
+F087:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73866DF673EE6DDE73DE7FFE0000
+F088:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73CE6DB673CE6DB673CE7FFE0000
+F089:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73CE6DB673C66DF673CE7FFE0000
+F08A:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73866DB673866DB673B67FFE0000
+F08B:00007FFE61CE6FB663B66FB66FCE7FFE7FFE738E6DB6738E6DB6738E7FFE0000
+F08C:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73C66DBE73BE6DBE73C67FFE0000
+F08D:00007FFE61CE6FB663B66FB66FCE7FFE7FFE738E6DB673B66DB6738E7FFE0000
+F08E:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73866DBE738E6DBE73867FFE0000
+F08F:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73866DBE738E6DBE73BE7FFE0000
+F090:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73CE6DB671B67DB673CE7FFE0000
+F091:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73EE6DCE71EE7DEE73C67FFE0000
+F092:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73866DF671867DBE73867FFE0000
+F093:00007FFE61CE6FB663B66FB66FCE7FFE7FFE738E6DF671C67DF6738E7FFE0000
+F094:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73B66DB671867DF673F67FFE0000
+F095:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73866DBE71867DF673867FFE0000
+F096:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73CE6DBE718E7DB673CE7FFE0000
+F097:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73866DF671EE7DDE73DE7FFE0000
+F098:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73CE6DB671CE7DB673CE7FFE0000
+F099:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73CE6DB671C67DF673CE7FFE0000
+F09A:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73866DB671867DB673B67FFE0000
+F09B:00007FFE61CE6FB663B66FB66FCE7FFE7FFE738E6DB6718E7DB6738E7FFE0000
+F09C:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73C66DBE71BE7DBE73C67FFE0000
+F09D:00007FFE61CE6FB663B66FB66FCE7FFE7FFE738E6DB671B67DB6738E7FFE0000
+F09E:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73866DBE718E7DBE73867FFE0000
+F09F:00007FFE61CE6FB663B66FB66FCE7FFE7FFE73866DBE718E7DBE73BE7FFE0000
+F0A0:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61CE6DB661B66DB66DCE7FFE0000
+F0A1:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61EE6DCE61EE6DEE6DC67FFE0000
+F0A2:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61866DF661866DBE6D867FFE0000
+F0A3:00007FFE61CE6FB663B66FB66FCE7FFE7FFE618E6DF661C66DF66D8E7FFE0000
+F0A4:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61B66DB661866DF66DF67FFE0000
+F0A5:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61866DBE61866DF66D867FFE0000
+F0A6:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61CE6DBE618E6DB66DCE7FFE0000
+F0A7:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61866DF661EE6DDE6DDE7FFE0000
+F0A8:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61CE6DB661CE6DB66DCE7FFE0000
+F0A9:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61CE6DB661C66DF66DCE7FFE0000
+F0AA:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61866DB661866DB66DB67FFE0000
+F0AB:00007FFE61CE6FB663B66FB66FCE7FFE7FFE618E6DB6618E6DB66D8E7FFE0000
+F0AC:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61C66DBE61BE6DBE6DC67FFE0000
+F0AD:00007FFE61CE6FB663B66FB66FCE7FFE7FFE618E6DB661B66DB66D8E7FFE0000
+F0AE:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61866DBE618E6DBE6D867FFE0000
+F0AF:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61866DBE618E6DBE6DBE7FFE0000
+F0B0:00007FFE61CE6FB663B66FB66FCE7FFE7FFE63CE6DB663B66DB663CE7FFE0000
+F0B1:00007FFE61CE6FB663B66FB66FCE7FFE7FFE63EE6DCE63EE6DEE63C67FFE0000
+F0B2:00007FFE61CE6FB663B66FB66FCE7FFE7FFE63866DF663866DBE63867FFE0000
+F0B3:00007FFE61CE6FB663B66FB66FCE7FFE7FFE638E6DF663C66DF6638E7FFE0000
+F0B4:00007FFE61CE6FB663B66FB66FCE7FFE7FFE63B66DB663866DF663F67FFE0000
+F0B5:00007FFE61CE6FB663B66FB66FCE7FFE7FFE63866DBE63866DF663867FFE0000
+F0B6:00007FFE61CE6FB663B66FB66FCE7FFE7FFE63CE6DBE638E6DB663CE7FFE0000
+F0B7:00007FFE61CE6FB663B66FB66FCE7FFE7FFE63866DF663EE6DDE63DE7FFE0000
+F0B8:00007FFE61CE6FB663B66FB66FCE7FFE7FFE63CE6DB663CE6DB663CE7FFE0000
+F0B9:00007FFE61CE6FB663B66FB66FCE7FFE7FFE63CE6DB663C66DF663CE7FFE0000
+F0BA:00007FFE61CE6FB663B66FB66FCE7FFE7FFE63866DB663866DB663B67FFE0000
+F0BB:00007FFE61CE6FB663B66FB66FCE7FFE7FFE638E6DB6638E6DB6638E7FFE0000
+F0BC:00007FFE61CE6FB663B66FB66FCE7FFE7FFE63C66DBE63BE6DBE63C67FFE0000
+F0BD:00007FFE61CE6FB663B66FB66FCE7FFE7FFE638E6DB663B66DB6638E7FFE0000
+F0BE:00007FFE61CE6FB663B66FB66FCE7FFE7FFE63866DBE638E6DBE63867FFE0000
+F0BF:00007FFE61CE6FB663B66FB66FCE7FFE7FFE63866DBE638E6DBE63BE7FFE0000
+F0C0:00007FFE61CE6FB663B66FB66FCE7FFE7FFE71CE6FB66FB66FB671CE7FFE0000
+F0C1:00007FFE61CE6FB663B66FB66FCE7FFE7FFE71EE6FCE6FEE6FEE71C67FFE0000
+F0C2:00007FFE61CE6FB663B66FB66FCE7FFE7FFE71866FF66F866FBE71867FFE0000
+F0C3:00007FFE61CE6FB663B66FB66FCE7FFE7FFE718E6FF66FC66FF6718E7FFE0000
+F0C4:00007FFE61CE6FB663B66FB66FCE7FFE7FFE71B66FB66F866FF671F67FFE0000
+F0C5:00007FFE61CE6FB663B66FB66FCE7FFE7FFE71866FBE6F866FF671867FFE0000
+F0C6:00007FFE61CE6FB663B66FB66FCE7FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000
+F0C7:00007FFE61CE6FB663B66FB66FCE7FFE7FFE71866FF66FEE6FDE71DE7FFE0000
+F0C8:00007FFE61CE6FB663B66FB66FCE7FFE7FFE71CE6FB66FCE6FB671CE7FFE0000
+F0C9:00007FFE61CE6FB663B66FB66FCE7FFE7FFE71CE6FB66FC66FF671CE7FFE0000
+F0CA:00007FFE61CE6FB663B66FB66FCE7FFE7FFE71866FB66F866FB671B67FFE0000
+F0CB:00007FFE61CE6FB663B66FB66FCE7FFE7FFE718E6FB66F8E6FB6718E7FFE0000
+F0CC:00007FFE61CE6FB663B66FB66FCE7FFE7FFE71C66FBE6FBE6FBE71C67FFE0000
+F0CD:00007FFE61CE6FB663B66FB66FCE7FFE7FFE718E6FB66FB66FB6718E7FFE0000
+F0CE:00007FFE61CE6FB663B66FB66FCE7FFE7FFE71866FBE6F8E6FBE71867FFE0000
+F0CF:00007FFE61CE6FB663B66FB66FCE7FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+F0D0:00007FFE61CE6FB663B66FB66FCE7FFE7FFE63CE6DB66DB66DB663CE7FFE0000
+F0D1:00007FFE61CE6FB663B66FB66FCE7FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000
+F0D2:00007FFE61CE6FB663B66FB66FCE7FFE7FFE63866DF66D866DBE63867FFE0000
+F0D3:00007FFE61CE6FB663B66FB66FCE7FFE7FFE638E6DF66DC66DF6638E7FFE0000
+F0D4:00007FFE61CE6FB663B66FB66FCE7FFE7FFE63B66DB66D866DF663F67FFE0000
+F0D5:00007FFE61CE6FB663B66FB66FCE7FFE7FFE63866DBE6D866DF663867FFE0000
+F0D6:00007FFE61CE6FB663B66FB66FCE7FFE7FFE63CE6DBE6D8E6DB663CE7FFE0000
+F0D7:00007FFE61CE6FB663B66FB66FCE7FFE7FFE63866DF66DEE6DDE63DE7FFE0000
+F0D8:00007FFE61CE6FB663B66FB66FCE7FFE7FFE63CE6DB66DCE6DB663CE7FFE0000
+F0D9:00007FFE61CE6FB663B66FB66FCE7FFE7FFE63CE6DB66DC66DF663CE7FFE0000
+F0DA:00007FFE61CE6FB663B66FB66FCE7FFE7FFE63866DB66D866DB663B67FFE0000
+F0DB:00007FFE61CE6FB663B66FB66FCE7FFE7FFE638E6DB66D8E6DB6638E7FFE0000
+F0DC:00007FFE61CE6FB663B66FB66FCE7FFE7FFE63C66DBE6DBE6DBE63C67FFE0000
+F0DD:00007FFE61CE6FB663B66FB66FCE7FFE7FFE638E6DB66DB66DB6638E7FFE0000
+F0DE:00007FFE61CE6FB663B66FB66FCE7FFE7FFE63866DBE6D8E6DBE63867FFE0000
+F0DF:00007FFE61CE6FB663B66FB66FCE7FFE7FFE63866DBE6D8E6DBE63BE7FFE0000
+F0E0:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61CE6FB663B66FB661CE7FFE0000
+F0E1:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61EE6FCE63EE6FEE61C67FFE0000
+F0E2:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61866FF663866FBE61867FFE0000
+F0E3:00007FFE61CE6FB663B66FB66FCE7FFE7FFE618E6FF663C66FF6618E7FFE0000
+F0E4:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61B66FB663866FF661F67FFE0000
+F0E5:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61866FBE63866FF661867FFE0000
+F0E6:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61CE6FBE638E6FB661CE7FFE0000
+F0E7:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61866FF663EE6FDE61DE7FFE0000
+F0E8:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61CE6FB663CE6FB661CE7FFE0000
+F0E9:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61CE6FB663C66FF661CE7FFE0000
+F0EA:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61866FB663866FB661B67FFE0000
+F0EB:00007FFE61CE6FB663B66FB66FCE7FFE7FFE618E6FB6638E6FB6618E7FFE0000
+F0EC:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61C66FBE63BE6FBE61C67FFE0000
+F0ED:00007FFE61CE6FB663B66FB66FCE7FFE7FFE618E6FB663B66FB6618E7FFE0000
+F0EE:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61866FBE638E6FBE61867FFE0000
+F0EF:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61866FBE638E6FBE61BE7FFE0000
+F0F0:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61CE6FB663B66FB66FCE7FFE0000
+F0F1:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000
+F0F2:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61866FF663866FBE6F867FFE0000
+F0F3:00007FFE61CE6FB663B66FB66FCE7FFE7FFE618E6FF663C66FF66F8E7FFE0000
+F0F4:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61B66FB663866FF66FF67FFE0000
+F0F5:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61866FBE63866FF66F867FFE0000
+F0F6:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+F0F7:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+F0F8:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+F0F9:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+F0FA:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61866FB663866FB66FB67FFE0000
+F0FB:00007FFE61CE6FB663B66FB66FCE7FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+F0FC:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+F0FD:00007FFE61CE6FB663B66FB66FCE7FFE7FFE618E6FB663B66FB66F8E7FFE0000
+F0FE:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61866FBE638E6FBE6F867FFE0000
+F0FF:00007FFE61CE6FB663B66FB66FCE7FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+F100:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73CE6DB66DB66DB673CE7FFE0000
+F101:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73EE6DCE6DEE6DEE73C67FFE0000
+F102:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73866DF66D866DBE73867FFE0000
+F103:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE738E6DF66DC66DF6738E7FFE0000
+F104:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73B66DB66D866DF673F67FFE0000
+F105:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73866DBE6D866DF673867FFE0000
+F106:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73CE6DBE6D8E6DB673CE7FFE0000
+F107:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73866DF66DEE6DDE73DE7FFE0000
+F108:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73CE6DB66DCE6DB673CE7FFE0000
+F109:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73CE6DB66DC66DF673CE7FFE0000
+F10A:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73866DB66D866DB673B67FFE0000
+F10B:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE738E6DB66D8E6DB6738E7FFE0000
+F10C:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73C66DBE6DBE6DBE73C67FFE0000
+F10D:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE738E6DB66DB66DB6738E7FFE0000
+F10E:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73866DBE6D8E6DBE73867FFE0000
+F10F:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73866DBE6D8E6DBE73BE7FFE0000
+F110:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE7BCE73B67BB67BB671CE7FFE0000
+F111:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE7BEE73CE7BEE7BEE71C67FFE0000
+F112:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE7B8673F67B867BBE71867FFE0000
+F113:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE7B8E73F67BC67BF6718E7FFE0000
+F114:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE7BB673B67B867BF671F67FFE0000
+F115:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE7B8673BE7B867BF671867FFE0000
+F116:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE7BCE73BE7B8E7BB671CE7FFE0000
+F117:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE7B8673F67BEE7BDE71DE7FFE0000
+F118:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE7BCE73B67BCE7BB671CE7FFE0000
+F119:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE7BCE73B67BC67BF671CE7FFE0000
+F11A:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE7B8673B67B867BB671B67FFE0000
+F11B:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE7B8E73B67B8E7BB6718E7FFE0000
+F11C:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE7BC673BE7BBE7BBE71C67FFE0000
+F11D:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE7B8E73B67BB67BB6718E7FFE0000
+F11E:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE7B8673BE7B8E7BBE71867FFE0000
+F11F:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE7B8673BE7B8E7BBE71BE7FFE0000
+F120:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61CE7DB661B66FB661CE7FFE0000
+F121:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61EE7DCE61EE6FEE61C67FFE0000
+F122:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61867DF661866FBE61867FFE0000
+F123:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE618E7DF661C66FF6618E7FFE0000
+F124:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61B67DB661866FF661F67FFE0000
+F125:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61867DBE61866FF661867FFE0000
+F126:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61CE7DBE618E6FB661CE7FFE0000
+F127:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61867DF661EE6FDE61DE7FFE0000
+F128:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61CE7DB661CE6FB661CE7FFE0000
+F129:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61CE7DB661C66FF661CE7FFE0000
+F12A:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61867DB661866FB661B67FFE0000
+F12B:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE618E7DB6618E6FB6618E7FFE0000
+F12C:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61C67DBE61BE6FBE61C67FFE0000
+F12D:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE618E7DB661B66FB6618E7FFE0000
+F12E:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61867DBE618E6FBE61867FFE0000
+F12F:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61867DBE618E6FBE61BE7FFE0000
+F130:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE63CE7DB671B67DB663CE7FFE0000
+F131:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE63EE7DCE71EE7DEE63C67FFE0000
+F132:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE63867DF671867DBE63867FFE0000
+F133:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE638E7DF671C67DF6638E7FFE0000
+F134:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE63B67DB671867DF663F67FFE0000
+F135:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE63867DBE71867DF663867FFE0000
+F136:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE63CE7DBE718E7DB663CE7FFE0000
+F137:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE63867DF671EE7DDE63DE7FFE0000
+F138:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE63CE7DB671CE7DB663CE7FFE0000
+F139:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE63CE7DB671C67DF663CE7FFE0000
+F13A:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE63867DB671867DB663B67FFE0000
+F13B:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE638E7DB6718E7DB6638E7FFE0000
+F13C:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE63C67DBE71BE7DBE63C67FFE0000
+F13D:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE638E7DB671B67DB6638E7FFE0000
+F13E:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE63867DBE718E7DBE63867FFE0000
+F13F:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE63867DBE718E7DBE63BE7FFE0000
+F140:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE6DCE6DB661B67DB67DCE7FFE0000
+F141:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE6DEE6DCE61EE7DEE7DC67FFE0000
+F142:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE6D866DF661867DBE7D867FFE0000
+F143:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE6D8E6DF661C67DF67D8E7FFE0000
+F144:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE6DB66DB661867DF67DF67FFE0000
+F145:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE6D866DBE61867DF67D867FFE0000
+F146:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE6DCE6DBE618E7DB67DCE7FFE0000
+F147:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE6D866DF661EE7DDE7DDE7FFE0000
+F148:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE6DCE6DB661CE7DB67DCE7FFE0000
+F149:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE6DCE6DB661C67DF67DCE7FFE0000
+F14A:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE6D866DB661867DB67DB67FFE0000
+F14B:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE6D8E6DB6618E7DB67D8E7FFE0000
+F14C:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE6DC66DBE61BE7DBE7DC67FFE0000
+F14D:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE6D8E6DB661B67DB67D8E7FFE0000
+F14E:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE6D866DBE618E7DBE7D867FFE0000
+F14F:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE6D866DBE618E7DBE7DBE7FFE0000
+F150:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61CE6FB661B67DB661CE7FFE0000
+F151:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61EE6FCE61EE7DEE61C67FFE0000
+F152:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61866FF661867DBE61867FFE0000
+F153:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE618E6FF661C67DF6618E7FFE0000
+F154:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61B66FB661867DF661F67FFE0000
+F155:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61866FBE61867DF661867FFE0000
+F156:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61CE6FBE618E7DB661CE7FFE0000
+F157:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61866FF661EE7DDE61DE7FFE0000
+F158:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61CE6FB661CE7DB661CE7FFE0000
+F159:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61CE6FB661C67DF661CE7FFE0000
+F15A:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61866FB661867DB661B67FFE0000
+F15B:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE618E6FB6618E7DB6618E7FFE0000
+F15C:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61C66FBE61BE7DBE61C67FFE0000
+F15D:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE618E6FB661B67DB6618E7FFE0000
+F15E:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61866FBE618E7DBE61867FFE0000
+F15F:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61866FBE618E7DBE61BE7FFE0000
+F160:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73CE6FB663B66DB673CE7FFE0000
+F161:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73EE6FCE63EE6DEE73C67FFE0000
+F162:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73866FF663866DBE73867FFE0000
+F163:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE738E6FF663C66DF6738E7FFE0000
+F164:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73B66FB663866DF673F67FFE0000
+F165:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73866FBE63866DF673867FFE0000
+F166:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73CE6FBE638E6DB673CE7FFE0000
+F167:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73866FF663EE6DDE73DE7FFE0000
+F168:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73CE6FB663CE6DB673CE7FFE0000
+F169:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73CE6FB663C66DF673CE7FFE0000
+F16A:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73866FB663866DB673B67FFE0000
+F16B:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE738E6FB6638E6DB6738E7FFE0000
+F16C:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73C66FBE63BE6DBE73C67FFE0000
+F16D:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE738E6FB663B66DB6738E7FFE0000
+F16E:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73866FBE638E6DBE73867FFE0000
+F16F:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73866FBE638E6DBE73BE7FFE0000
+F170:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61CE7DB67BB677B677CE7FFE0000
+F171:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61EE7DCE7BEE77EE77C67FFE0000
+F172:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61867DF67B8677BE77867FFE0000
+F173:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE618E7DF67BC677F6778E7FFE0000
+F174:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61B67DB67B8677F677F67FFE0000
+F175:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61867DBE7B8677F677867FFE0000
+F176:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61CE7DBE7B8E77B677CE7FFE0000
+F177:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61867DF67BEE77DE77DE7FFE0000
+F178:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61CE7DB67BCE77B677CE7FFE0000
+F179:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61CE7DB67BC677F677CE7FFE0000
+F17A:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61867DB67B8677B677B67FFE0000
+F17B:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE618E7DB67B8E77B6778E7FFE0000
+F17C:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61C67DBE7BBE77BE77C67FFE0000
+F17D:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE618E7DB67BB677B6778E7FFE0000
+F17E:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61867DBE7B8E77BE77867FFE0000
+F17F:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61867DBE7B8E77BE77BE7FFE0000
+F180:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73CE6DB673B66DB673CE7FFE0000
+F181:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73EE6DCE73EE6DEE73C67FFE0000
+F182:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73866DF673866DBE73867FFE0000
+F183:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE738E6DF673C66DF6738E7FFE0000
+F184:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73B66DB673866DF673F67FFE0000
+F185:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73866DBE73866DF673867FFE0000
+F186:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73CE6DBE738E6DB673CE7FFE0000
+F187:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73866DF673EE6DDE73DE7FFE0000
+F188:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73CE6DB673CE6DB673CE7FFE0000
+F189:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73CE6DB673C66DF673CE7FFE0000
+F18A:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73866DB673866DB673B67FFE0000
+F18B:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE738E6DB6738E6DB6738E7FFE0000
+F18C:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73C66DBE73BE6DBE73C67FFE0000
+F18D:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE738E6DB673B66DB6738E7FFE0000
+F18E:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73866DBE738E6DBE73867FFE0000
+F18F:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73866DBE738E6DBE73BE7FFE0000
+F190:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73CE6DB671B67DB673CE7FFE0000
+F191:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73EE6DCE71EE7DEE73C67FFE0000
+F192:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73866DF671867DBE73867FFE0000
+F193:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE738E6DF671C67DF6738E7FFE0000
+F194:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73B66DB671867DF673F67FFE0000
+F195:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73866DBE71867DF673867FFE0000
+F196:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73CE6DBE718E7DB673CE7FFE0000
+F197:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73866DF671EE7DDE73DE7FFE0000
+F198:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73CE6DB671CE7DB673CE7FFE0000
+F199:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73CE6DB671C67DF673CE7FFE0000
+F19A:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73866DB671867DB673B67FFE0000
+F19B:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE738E6DB6718E7DB6738E7FFE0000
+F19C:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73C66DBE71BE7DBE73C67FFE0000
+F19D:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE738E6DB671B67DB6738E7FFE0000
+F19E:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73866DBE718E7DBE73867FFE0000
+F19F:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE73866DBE718E7DBE73BE7FFE0000
+F1A0:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61CE6DB661B66DB66DCE7FFE0000
+F1A1:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61EE6DCE61EE6DEE6DC67FFE0000
+F1A2:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61866DF661866DBE6D867FFE0000
+F1A3:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE618E6DF661C66DF66D8E7FFE0000
+F1A4:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61B66DB661866DF66DF67FFE0000
+F1A5:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61866DBE61866DF66D867FFE0000
+F1A6:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61CE6DBE618E6DB66DCE7FFE0000
+F1A7:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61866DF661EE6DDE6DDE7FFE0000
+F1A8:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61CE6DB661CE6DB66DCE7FFE0000
+F1A9:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61CE6DB661C66DF66DCE7FFE0000
+F1AA:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61866DB661866DB66DB67FFE0000
+F1AB:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE618E6DB6618E6DB66D8E7FFE0000
+F1AC:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61C66DBE61BE6DBE6DC67FFE0000
+F1AD:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE618E6DB661B66DB66D8E7FFE0000
+F1AE:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61866DBE618E6DBE6D867FFE0000
+F1AF:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61866DBE618E6DBE6DBE7FFE0000
+F1B0:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE63CE6DB663B66DB663CE7FFE0000
+F1B1:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE63EE6DCE63EE6DEE63C67FFE0000
+F1B2:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE63866DF663866DBE63867FFE0000
+F1B3:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE638E6DF663C66DF6638E7FFE0000
+F1B4:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE63B66DB663866DF663F67FFE0000
+F1B5:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE63866DBE63866DF663867FFE0000
+F1B6:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE63CE6DBE638E6DB663CE7FFE0000
+F1B7:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE63866DF663EE6DDE63DE7FFE0000
+F1B8:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE63CE6DB663CE6DB663CE7FFE0000
+F1B9:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE63CE6DB663C66DF663CE7FFE0000
+F1BA:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE63866DB663866DB663B67FFE0000
+F1BB:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE638E6DB6638E6DB6638E7FFE0000
+F1BC:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE63C66DBE63BE6DBE63C67FFE0000
+F1BD:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE638E6DB663B66DB6638E7FFE0000
+F1BE:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE63866DBE638E6DBE63867FFE0000
+F1BF:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE63866DBE638E6DBE63BE7FFE0000
+F1C0:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE71CE6FB66FB66FB671CE7FFE0000
+F1C1:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE71EE6FCE6FEE6FEE71C67FFE0000
+F1C2:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE71866FF66F866FBE71867FFE0000
+F1C3:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE718E6FF66FC66FF6718E7FFE0000
+F1C4:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE71B66FB66F866FF671F67FFE0000
+F1C5:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE71866FBE6F866FF671867FFE0000
+F1C6:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000
+F1C7:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE71866FF66FEE6FDE71DE7FFE0000
+F1C8:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE71CE6FB66FCE6FB671CE7FFE0000
+F1C9:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE71CE6FB66FC66FF671CE7FFE0000
+F1CA:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE71866FB66F866FB671B67FFE0000
+F1CB:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE718E6FB66F8E6FB6718E7FFE0000
+F1CC:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE71C66FBE6FBE6FBE71C67FFE0000
+F1CD:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE718E6FB66FB66FB6718E7FFE0000
+F1CE:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE71866FBE6F8E6FBE71867FFE0000
+F1CF:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+F1D0:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE63CE6DB66DB66DB663CE7FFE0000
+F1D1:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000
+F1D2:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE63866DF66D866DBE63867FFE0000
+F1D3:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE638E6DF66DC66DF6638E7FFE0000
+F1D4:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE63B66DB66D866DF663F67FFE0000
+F1D5:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE63866DBE6D866DF663867FFE0000
+F1D6:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE63CE6DBE6D8E6DB663CE7FFE0000
+F1D7:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE63866DF66DEE6DDE63DE7FFE0000
+F1D8:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE63CE6DB66DCE6DB663CE7FFE0000
+F1D9:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE63CE6DB66DC66DF663CE7FFE0000
+F1DA:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE63866DB66D866DB663B67FFE0000
+F1DB:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE638E6DB66D8E6DB6638E7FFE0000
+F1DC:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE63C66DBE6DBE6DBE63C67FFE0000
+F1DD:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE638E6DB66DB66DB6638E7FFE0000
+F1DE:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE63866DBE6D8E6DBE63867FFE0000
+F1DF:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE63866DBE6D8E6DBE63BE7FFE0000
+F1E0:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61CE6FB663B66FB661CE7FFE0000
+F1E1:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61EE6FCE63EE6FEE61C67FFE0000
+F1E2:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61866FF663866FBE61867FFE0000
+F1E3:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE618E6FF663C66FF6618E7FFE0000
+F1E4:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61B66FB663866FF661F67FFE0000
+F1E5:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61866FBE63866FF661867FFE0000
+F1E6:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61CE6FBE638E6FB661CE7FFE0000
+F1E7:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61866FF663EE6FDE61DE7FFE0000
+F1E8:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61CE6FB663CE6FB661CE7FFE0000
+F1E9:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61CE6FB663C66FF661CE7FFE0000
+F1EA:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61866FB663866FB661B67FFE0000
+F1EB:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE618E6FB6638E6FB6618E7FFE0000
+F1EC:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61C66FBE63BE6FBE61C67FFE0000
+F1ED:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE618E6FB663B66FB6618E7FFE0000
+F1EE:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61866FBE638E6FBE61867FFE0000
+F1EF:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61866FBE638E6FBE61BE7FFE0000
+F1F0:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61CE6FB663B66FB66FCE7FFE0000
+F1F1:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000
+F1F2:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61866FF663866FBE6F867FFE0000
+F1F3:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE618E6FF663C66FF66F8E7FFE0000
+F1F4:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61B66FB663866FF66FF67FFE0000
+F1F5:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61866FBE63866FF66F867FFE0000
+F1F6:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+F1F7:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+F1F8:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+F1F9:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+F1FA:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61866FB663866FB66FB67FFE0000
+F1FB:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+F1FC:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+F1FD:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE618E6FB663B66FB66F8E7FFE0000
+F1FE:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61866FBE638E6FBE6F867FFE0000
+F1FF:00007FFE61EE6FCE63EE6FEE6FC67FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+F200:00007FFE61866FF663866FBE6F867FFE7FFE73CE6DB66DB66DB673CE7FFE0000
+F201:00007FFE61866FF663866FBE6F867FFE7FFE73EE6DCE6DEE6DEE73C67FFE0000
+F202:00007FFE61866FF663866FBE6F867FFE7FFE73866DF66D866DBE73867FFE0000
+F203:00007FFE61866FF663866FBE6F867FFE7FFE738E6DF66DC66DF6738E7FFE0000
+F204:00007FFE61866FF663866FBE6F867FFE7FFE73B66DB66D866DF673F67FFE0000
+F205:00007FFE61866FF663866FBE6F867FFE7FFE73866DBE6D866DF673867FFE0000
+F206:00007FFE61866FF663866FBE6F867FFE7FFE73CE6DBE6D8E6DB673CE7FFE0000
+F207:00007FFE61866FF663866FBE6F867FFE7FFE73866DF66DEE6DDE73DE7FFE0000
+F208:00007FFE61866FF663866FBE6F867FFE7FFE73CE6DB66DCE6DB673CE7FFE0000
+F209:00007FFE61866FF663866FBE6F867FFE7FFE73CE6DB66DC66DF673CE7FFE0000
+F20A:00007FFE61866FF663866FBE6F867FFE7FFE73866DB66D866DB673B67FFE0000
+F20B:00007FFE61866FF663866FBE6F867FFE7FFE738E6DB66D8E6DB6738E7FFE0000
+F20C:00007FFE61866FF663866FBE6F867FFE7FFE73C66DBE6DBE6DBE73C67FFE0000
+F20D:00007FFE61866FF663866FBE6F867FFE7FFE738E6DB66DB66DB6738E7FFE0000
+F20E:00007FFE61866FF663866FBE6F867FFE7FFE73866DBE6D8E6DBE73867FFE0000
+F20F:00007FFE61866FF663866FBE6F867FFE7FFE73866DBE6D8E6DBE73BE7FFE0000
+F210:00007FFE61866FF663866FBE6F867FFE7FFE7BCE73B67BB67BB671CE7FFE0000
+F211:00007FFE61866FF663866FBE6F867FFE7FFE7BEE73CE7BEE7BEE71C67FFE0000
+F212:00007FFE61866FF663866FBE6F867FFE7FFE7B8673F67B867BBE71867FFE0000
+F213:00007FFE61866FF663866FBE6F867FFE7FFE7B8E73F67BC67BF6718E7FFE0000
+F214:00007FFE61866FF663866FBE6F867FFE7FFE7BB673B67B867BF671F67FFE0000
+F215:00007FFE61866FF663866FBE6F867FFE7FFE7B8673BE7B867BF671867FFE0000
+F216:00007FFE61866FF663866FBE6F867FFE7FFE7BCE73BE7B8E7BB671CE7FFE0000
+F217:00007FFE61866FF663866FBE6F867FFE7FFE7B8673F67BEE7BDE71DE7FFE0000
+F218:00007FFE61866FF663866FBE6F867FFE7FFE7BCE73B67BCE7BB671CE7FFE0000
+F219:00007FFE61866FF663866FBE6F867FFE7FFE7BCE73B67BC67BF671CE7FFE0000
+F21A:00007FFE61866FF663866FBE6F867FFE7FFE7B8673B67B867BB671B67FFE0000
+F21B:00007FFE61866FF663866FBE6F867FFE7FFE7B8E73B67B8E7BB6718E7FFE0000
+F21C:00007FFE61866FF663866FBE6F867FFE7FFE7BC673BE7BBE7BBE71C67FFE0000
+F21D:00007FFE61866FF663866FBE6F867FFE7FFE7B8E73B67BB67BB6718E7FFE0000
+F21E:00007FFE61866FF663866FBE6F867FFE7FFE7B8673BE7B8E7BBE71867FFE0000
+F21F:00007FFE61866FF663866FBE6F867FFE7FFE7B8673BE7B8E7BBE71BE7FFE0000
+F220:00007FFE61866FF663866FBE6F867FFE7FFE61CE7DB661B66FB661CE7FFE0000
+F221:00007FFE61866FF663866FBE6F867FFE7FFE61EE7DCE61EE6FEE61C67FFE0000
+F222:00007FFE61866FF663866FBE6F867FFE7FFE61867DF661866FBE61867FFE0000
+F223:00007FFE61866FF663866FBE6F867FFE7FFE618E7DF661C66FF6618E7FFE0000
+F224:00007FFE61866FF663866FBE6F867FFE7FFE61B67DB661866FF661F67FFE0000
+F225:00007FFE61866FF663866FBE6F867FFE7FFE61867DBE61866FF661867FFE0000
+F226:00007FFE61866FF663866FBE6F867FFE7FFE61CE7DBE618E6FB661CE7FFE0000
+F227:00007FFE61866FF663866FBE6F867FFE7FFE61867DF661EE6FDE61DE7FFE0000
+F228:00007FFE61866FF663866FBE6F867FFE7FFE61CE7DB661CE6FB661CE7FFE0000
+F229:00007FFE61866FF663866FBE6F867FFE7FFE61CE7DB661C66FF661CE7FFE0000
+F22A:00007FFE61866FF663866FBE6F867FFE7FFE61867DB661866FB661B67FFE0000
+F22B:00007FFE61866FF663866FBE6F867FFE7FFE618E7DB6618E6FB6618E7FFE0000
+F22C:00007FFE61866FF663866FBE6F867FFE7FFE61C67DBE61BE6FBE61C67FFE0000
+F22D:00007FFE61866FF663866FBE6F867FFE7FFE618E7DB661B66FB6618E7FFE0000
+F22E:00007FFE61866FF663866FBE6F867FFE7FFE61867DBE618E6FBE61867FFE0000
+F22F:00007FFE61866FF663866FBE6F867FFE7FFE61867DBE618E6FBE61BE7FFE0000
+F230:00007FFE61866FF663866FBE6F867FFE7FFE63CE7DB671B67DB663CE7FFE0000
+F231:00007FFE61866FF663866FBE6F867FFE7FFE63EE7DCE71EE7DEE63C67FFE0000
+F232:00007FFE61866FF663866FBE6F867FFE7FFE63867DF671867DBE63867FFE0000
+F233:00007FFE61866FF663866FBE6F867FFE7FFE638E7DF671C67DF6638E7FFE0000
+F234:00007FFE61866FF663866FBE6F867FFE7FFE63B67DB671867DF663F67FFE0000
+F235:00007FFE61866FF663866FBE6F867FFE7FFE63867DBE71867DF663867FFE0000
+F236:00007FFE61866FF663866FBE6F867FFE7FFE63CE7DBE718E7DB663CE7FFE0000
+F237:00007FFE61866FF663866FBE6F867FFE7FFE63867DF671EE7DDE63DE7FFE0000
+F238:00007FFE61866FF663866FBE6F867FFE7FFE63CE7DB671CE7DB663CE7FFE0000
+F239:00007FFE61866FF663866FBE6F867FFE7FFE63CE7DB671C67DF663CE7FFE0000
+F23A:00007FFE61866FF663866FBE6F867FFE7FFE63867DB671867DB663B67FFE0000
+F23B:00007FFE61866FF663866FBE6F867FFE7FFE638E7DB6718E7DB6638E7FFE0000
+F23C:00007FFE61866FF663866FBE6F867FFE7FFE63C67DBE71BE7DBE63C67FFE0000
+F23D:00007FFE61866FF663866FBE6F867FFE7FFE638E7DB671B67DB6638E7FFE0000
+F23E:00007FFE61866FF663866FBE6F867FFE7FFE63867DBE718E7DBE63867FFE0000
+F23F:00007FFE61866FF663866FBE6F867FFE7FFE63867DBE718E7DBE63BE7FFE0000
+F240:00007FFE61866FF663866FBE6F867FFE7FFE6DCE6DB661B67DB67DCE7FFE0000
+F241:00007FFE61866FF663866FBE6F867FFE7FFE6DEE6DCE61EE7DEE7DC67FFE0000
+F242:00007FFE61866FF663866FBE6F867FFE7FFE6D866DF661867DBE7D867FFE0000
+F243:00007FFE61866FF663866FBE6F867FFE7FFE6D8E6DF661C67DF67D8E7FFE0000
+F244:00007FFE61866FF663866FBE6F867FFE7FFE6DB66DB661867DF67DF67FFE0000
+F245:00007FFE61866FF663866FBE6F867FFE7FFE6D866DBE61867DF67D867FFE0000
+F246:00007FFE61866FF663866FBE6F867FFE7FFE6DCE6DBE618E7DB67DCE7FFE0000
+F247:00007FFE61866FF663866FBE6F867FFE7FFE6D866DF661EE7DDE7DDE7FFE0000
+F248:00007FFE61866FF663866FBE6F867FFE7FFE6DCE6DB661CE7DB67DCE7FFE0000
+F249:00007FFE61866FF663866FBE6F867FFE7FFE6DCE6DB661C67DF67DCE7FFE0000
+F24A:00007FFE61866FF663866FBE6F867FFE7FFE6D866DB661867DB67DB67FFE0000
+F24B:00007FFE61866FF663866FBE6F867FFE7FFE6D8E6DB6618E7DB67D8E7FFE0000
+F24C:00007FFE61866FF663866FBE6F867FFE7FFE6DC66DBE61BE7DBE7DC67FFE0000
+F24D:00007FFE61866FF663866FBE6F867FFE7FFE6D8E6DB661B67DB67D8E7FFE0000
+F24E:00007FFE61866FF663866FBE6F867FFE7FFE6D866DBE618E7DBE7D867FFE0000
+F24F:00007FFE61866FF663866FBE6F867FFE7FFE6D866DBE618E7DBE7DBE7FFE0000
+F250:00007FFE61866FF663866FBE6F867FFE7FFE61CE6FB661B67DB661CE7FFE0000
+F251:00007FFE61866FF663866FBE6F867FFE7FFE61EE6FCE61EE7DEE61C67FFE0000
+F252:00007FFE61866FF663866FBE6F867FFE7FFE61866FF661867DBE61867FFE0000
+F253:00007FFE61866FF663866FBE6F867FFE7FFE618E6FF661C67DF6618E7FFE0000
+F254:00007FFE61866FF663866FBE6F867FFE7FFE61B66FB661867DF661F67FFE0000
+F255:00007FFE61866FF663866FBE6F867FFE7FFE61866FBE61867DF661867FFE0000
+F256:00007FFE61866FF663866FBE6F867FFE7FFE61CE6FBE618E7DB661CE7FFE0000
+F257:00007FFE61866FF663866FBE6F867FFE7FFE61866FF661EE7DDE61DE7FFE0000
+F258:00007FFE61866FF663866FBE6F867FFE7FFE61CE6FB661CE7DB661CE7FFE0000
+F259:00007FFE61866FF663866FBE6F867FFE7FFE61CE6FB661C67DF661CE7FFE0000
+F25A:00007FFE61866FF663866FBE6F867FFE7FFE61866FB661867DB661B67FFE0000
+F25B:00007FFE61866FF663866FBE6F867FFE7FFE618E6FB6618E7DB6618E7FFE0000
+F25C:00007FFE61866FF663866FBE6F867FFE7FFE61C66FBE61BE7DBE61C67FFE0000
+F25D:00007FFE61866FF663866FBE6F867FFE7FFE618E6FB661B67DB6618E7FFE0000
+F25E:00007FFE61866FF663866FBE6F867FFE7FFE61866FBE618E7DBE61867FFE0000
+F25F:00007FFE61866FF663866FBE6F867FFE7FFE61866FBE618E7DBE61BE7FFE0000
+F260:00007FFE61866FF663866FBE6F867FFE7FFE73CE6FB663B66DB673CE7FFE0000
+F261:00007FFE61866FF663866FBE6F867FFE7FFE73EE6FCE63EE6DEE73C67FFE0000
+F262:00007FFE61866FF663866FBE6F867FFE7FFE73866FF663866DBE73867FFE0000
+F263:00007FFE61866FF663866FBE6F867FFE7FFE738E6FF663C66DF6738E7FFE0000
+F264:00007FFE61866FF663866FBE6F867FFE7FFE73B66FB663866DF673F67FFE0000
+F265:00007FFE61866FF663866FBE6F867FFE7FFE73866FBE63866DF673867FFE0000
+F266:00007FFE61866FF663866FBE6F867FFE7FFE73CE6FBE638E6DB673CE7FFE0000
+F267:00007FFE61866FF663866FBE6F867FFE7FFE73866FF663EE6DDE73DE7FFE0000
+F268:00007FFE61866FF663866FBE6F867FFE7FFE73CE6FB663CE6DB673CE7FFE0000
+F269:00007FFE61866FF663866FBE6F867FFE7FFE73CE6FB663C66DF673CE7FFE0000
+F26A:00007FFE61866FF663866FBE6F867FFE7FFE73866FB663866DB673B67FFE0000
+F26B:00007FFE61866FF663866FBE6F867FFE7FFE738E6FB6638E6DB6738E7FFE0000
+F26C:00007FFE61866FF663866FBE6F867FFE7FFE73C66FBE63BE6DBE73C67FFE0000
+F26D:00007FFE61866FF663866FBE6F867FFE7FFE738E6FB663B66DB6738E7FFE0000
+F26E:00007FFE61866FF663866FBE6F867FFE7FFE73866FBE638E6DBE73867FFE0000
+F26F:00007FFE61866FF663866FBE6F867FFE7FFE73866FBE638E6DBE73BE7FFE0000
+F270:00007FFE61866FF663866FBE6F867FFE7FFE61CE7DB67BB677B677CE7FFE0000
+F271:00007FFE61866FF663866FBE6F867FFE7FFE61EE7DCE7BEE77EE77C67FFE0000
+F272:00007FFE61866FF663866FBE6F867FFE7FFE61867DF67B8677BE77867FFE0000
+F273:00007FFE61866FF663866FBE6F867FFE7FFE618E7DF67BC677F6778E7FFE0000
+F274:00007FFE61866FF663866FBE6F867FFE7FFE61B67DB67B8677F677F67FFE0000
+F275:00007FFE61866FF663866FBE6F867FFE7FFE61867DBE7B8677F677867FFE0000
+F276:00007FFE61866FF663866FBE6F867FFE7FFE61CE7DBE7B8E77B677CE7FFE0000
+F277:00007FFE61866FF663866FBE6F867FFE7FFE61867DF67BEE77DE77DE7FFE0000
+F278:00007FFE61866FF663866FBE6F867FFE7FFE61CE7DB67BCE77B677CE7FFE0000
+F279:00007FFE61866FF663866FBE6F867FFE7FFE61CE7DB67BC677F677CE7FFE0000
+F27A:00007FFE61866FF663866FBE6F867FFE7FFE61867DB67B8677B677B67FFE0000
+F27B:00007FFE61866FF663866FBE6F867FFE7FFE618E7DB67B8E77B6778E7FFE0000
+F27C:00007FFE61866FF663866FBE6F867FFE7FFE61C67DBE7BBE77BE77C67FFE0000
+F27D:00007FFE61866FF663866FBE6F867FFE7FFE618E7DB67BB677B6778E7FFE0000
+F27E:00007FFE61866FF663866FBE6F867FFE7FFE61867DBE7B8E77BE77867FFE0000
+F27F:00007FFE61866FF663866FBE6F867FFE7FFE61867DBE7B8E77BE77BE7FFE0000
+F280:00007FFE61866FF663866FBE6F867FFE7FFE73CE6DB673B66DB673CE7FFE0000
+F281:00007FFE61866FF663866FBE6F867FFE7FFE73EE6DCE73EE6DEE73C67FFE0000
+F282:00007FFE61866FF663866FBE6F867FFE7FFE73866DF673866DBE73867FFE0000
+F283:00007FFE61866FF663866FBE6F867FFE7FFE738E6DF673C66DF6738E7FFE0000
+F284:00007FFE61866FF663866FBE6F867FFE7FFE73B66DB673866DF673F67FFE0000
+F285:00007FFE61866FF663866FBE6F867FFE7FFE73866DBE73866DF673867FFE0000
+F286:00007FFE61866FF663866FBE6F867FFE7FFE73CE6DBE738E6DB673CE7FFE0000
+F287:00007FFE61866FF663866FBE6F867FFE7FFE73866DF673EE6DDE73DE7FFE0000
+F288:00007FFE61866FF663866FBE6F867FFE7FFE73CE6DB673CE6DB673CE7FFE0000
+F289:00007FFE61866FF663866FBE6F867FFE7FFE73CE6DB673C66DF673CE7FFE0000
+F28A:00007FFE61866FF663866FBE6F867FFE7FFE73866DB673866DB673B67FFE0000
+F28B:00007FFE61866FF663866FBE6F867FFE7FFE738E6DB6738E6DB6738E7FFE0000
+F28C:00007FFE61866FF663866FBE6F867FFE7FFE73C66DBE73BE6DBE73C67FFE0000
+F28D:00007FFE61866FF663866FBE6F867FFE7FFE738E6DB673B66DB6738E7FFE0000
+F28E:00007FFE61866FF663866FBE6F867FFE7FFE73866DBE738E6DBE73867FFE0000
+F28F:00007FFE61866FF663866FBE6F867FFE7FFE73866DBE738E6DBE73BE7FFE0000
+F290:00007FFE61866FF663866FBE6F867FFE7FFE73CE6DB671B67DB673CE7FFE0000
+F291:00007FFE61866FF663866FBE6F867FFE7FFE73EE6DCE71EE7DEE73C67FFE0000
+F292:00007FFE61866FF663866FBE6F867FFE7FFE73866DF671867DBE73867FFE0000
+F293:00007FFE61866FF663866FBE6F867FFE7FFE738E6DF671C67DF6738E7FFE0000
+F294:00007FFE61866FF663866FBE6F867FFE7FFE73B66DB671867DF673F67FFE0000
+F295:00007FFE61866FF663866FBE6F867FFE7FFE73866DBE71867DF673867FFE0000
+F296:00007FFE61866FF663866FBE6F867FFE7FFE73CE6DBE718E7DB673CE7FFE0000
+F297:00007FFE61866FF663866FBE6F867FFE7FFE73866DF671EE7DDE73DE7FFE0000
+F298:00007FFE61866FF663866FBE6F867FFE7FFE73CE6DB671CE7DB673CE7FFE0000
+F299:00007FFE61866FF663866FBE6F867FFE7FFE73CE6DB671C67DF673CE7FFE0000
+F29A:00007FFE61866FF663866FBE6F867FFE7FFE73866DB671867DB673B67FFE0000
+F29B:00007FFE61866FF663866FBE6F867FFE7FFE738E6DB6718E7DB6738E7FFE0000
+F29C:00007FFE61866FF663866FBE6F867FFE7FFE73C66DBE71BE7DBE73C67FFE0000
+F29D:00007FFE61866FF663866FBE6F867FFE7FFE738E6DB671B67DB6738E7FFE0000
+F29E:00007FFE61866FF663866FBE6F867FFE7FFE73866DBE718E7DBE73867FFE0000
+F29F:00007FFE61866FF663866FBE6F867FFE7FFE73866DBE718E7DBE73BE7FFE0000
+F2A0:00007FFE61866FF663866FBE6F867FFE7FFE61CE6DB661B66DB66DCE7FFE0000
+F2A1:00007FFE61866FF663866FBE6F867FFE7FFE61EE6DCE61EE6DEE6DC67FFE0000
+F2A2:00007FFE61866FF663866FBE6F867FFE7FFE61866DF661866DBE6D867FFE0000
+F2A3:00007FFE61866FF663866FBE6F867FFE7FFE618E6DF661C66DF66D8E7FFE0000
+F2A4:00007FFE61866FF663866FBE6F867FFE7FFE61B66DB661866DF66DF67FFE0000
+F2A5:00007FFE61866FF663866FBE6F867FFE7FFE61866DBE61866DF66D867FFE0000
+F2A6:00007FFE61866FF663866FBE6F867FFE7FFE61CE6DBE618E6DB66DCE7FFE0000
+F2A7:00007FFE61866FF663866FBE6F867FFE7FFE61866DF661EE6DDE6DDE7FFE0000
+F2A8:00007FFE61866FF663866FBE6F867FFE7FFE61CE6DB661CE6DB66DCE7FFE0000
+F2A9:00007FFE61866FF663866FBE6F867FFE7FFE61CE6DB661C66DF66DCE7FFE0000
+F2AA:00007FFE61866FF663866FBE6F867FFE7FFE61866DB661866DB66DB67FFE0000
+F2AB:00007FFE61866FF663866FBE6F867FFE7FFE618E6DB6618E6DB66D8E7FFE0000
+F2AC:00007FFE61866FF663866FBE6F867FFE7FFE61C66DBE61BE6DBE6DC67FFE0000
+F2AD:00007FFE61866FF663866FBE6F867FFE7FFE618E6DB661B66DB66D8E7FFE0000
+F2AE:00007FFE61866FF663866FBE6F867FFE7FFE61866DBE618E6DBE6D867FFE0000
+F2AF:00007FFE61866FF663866FBE6F867FFE7FFE61866DBE618E6DBE6DBE7FFE0000
+F2B0:00007FFE61866FF663866FBE6F867FFE7FFE63CE6DB663B66DB663CE7FFE0000
+F2B1:00007FFE61866FF663866FBE6F867FFE7FFE63EE6DCE63EE6DEE63C67FFE0000
+F2B2:00007FFE61866FF663866FBE6F867FFE7FFE63866DF663866DBE63867FFE0000
+F2B3:00007FFE61866FF663866FBE6F867FFE7FFE638E6DF663C66DF6638E7FFE0000
+F2B4:00007FFE61866FF663866FBE6F867FFE7FFE63B66DB663866DF663F67FFE0000
+F2B5:00007FFE61866FF663866FBE6F867FFE7FFE63866DBE63866DF663867FFE0000
+F2B6:00007FFE61866FF663866FBE6F867FFE7FFE63CE6DBE638E6DB663CE7FFE0000
+F2B7:00007FFE61866FF663866FBE6F867FFE7FFE63866DF663EE6DDE63DE7FFE0000
+F2B8:00007FFE61866FF663866FBE6F867FFE7FFE63CE6DB663CE6DB663CE7FFE0000
+F2B9:00007FFE61866FF663866FBE6F867FFE7FFE63CE6DB663C66DF663CE7FFE0000
+F2BA:00007FFE61866FF663866FBE6F867FFE7FFE63866DB663866DB663B67FFE0000
+F2BB:00007FFE61866FF663866FBE6F867FFE7FFE638E6DB6638E6DB6638E7FFE0000
+F2BC:00007FFE61866FF663866FBE6F867FFE7FFE63C66DBE63BE6DBE63C67FFE0000
+F2BD:00007FFE61866FF663866FBE6F867FFE7FFE638E6DB663B66DB6638E7FFE0000
+F2BE:00007FFE61866FF663866FBE6F867FFE7FFE63866DBE638E6DBE63867FFE0000
+F2BF:00007FFE61866FF663866FBE6F867FFE7FFE63866DBE638E6DBE63BE7FFE0000
+F2C0:00007FFE61866FF663866FBE6F867FFE7FFE71CE6FB66FB66FB671CE7FFE0000
+F2C1:00007FFE61866FF663866FBE6F867FFE7FFE71EE6FCE6FEE6FEE71C67FFE0000
+F2C2:00007FFE61866FF663866FBE6F867FFE7FFE71866FF66F866FBE71867FFE0000
+F2C3:00007FFE61866FF663866FBE6F867FFE7FFE718E6FF66FC66FF6718E7FFE0000
+F2C4:00007FFE61866FF663866FBE6F867FFE7FFE71B66FB66F866FF671F67FFE0000
+F2C5:00007FFE61866FF663866FBE6F867FFE7FFE71866FBE6F866FF671867FFE0000
+F2C6:00007FFE61866FF663866FBE6F867FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000
+F2C7:00007FFE61866FF663866FBE6F867FFE7FFE71866FF66FEE6FDE71DE7FFE0000
+F2C8:00007FFE61866FF663866FBE6F867FFE7FFE71CE6FB66FCE6FB671CE7FFE0000
+F2C9:00007FFE61866FF663866FBE6F867FFE7FFE71CE6FB66FC66FF671CE7FFE0000
+F2CA:00007FFE61866FF663866FBE6F867FFE7FFE71866FB66F866FB671B67FFE0000
+F2CB:00007FFE61866FF663866FBE6F867FFE7FFE718E6FB66F8E6FB6718E7FFE0000
+F2CC:00007FFE61866FF663866FBE6F867FFE7FFE71C66FBE6FBE6FBE71C67FFE0000
+F2CD:00007FFE61866FF663866FBE6F867FFE7FFE718E6FB66FB66FB6718E7FFE0000
+F2CE:00007FFE61866FF663866FBE6F867FFE7FFE71866FBE6F8E6FBE71867FFE0000
+F2CF:00007FFE61866FF663866FBE6F867FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+F2D0:00007FFE61866FF663866FBE6F867FFE7FFE63CE6DB66DB66DB663CE7FFE0000
+F2D1:00007FFE61866FF663866FBE6F867FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000
+F2D2:00007FFE61866FF663866FBE6F867FFE7FFE63866DF66D866DBE63867FFE0000
+F2D3:00007FFE61866FF663866FBE6F867FFE7FFE638E6DF66DC66DF6638E7FFE0000
+F2D4:00007FFE61866FF663866FBE6F867FFE7FFE63B66DB66D866DF663F67FFE0000
+F2D5:00007FFE61866FF663866FBE6F867FFE7FFE63866DBE6D866DF663867FFE0000
+F2D6:00007FFE61866FF663866FBE6F867FFE7FFE63CE6DBE6D8E6DB663CE7FFE0000
+F2D7:00007FFE61866FF663866FBE6F867FFE7FFE63866DF66DEE6DDE63DE7FFE0000
+F2D8:00007FFE61866FF663866FBE6F867FFE7FFE63CE6DB66DCE6DB663CE7FFE0000
+F2D9:00007FFE61866FF663866FBE6F867FFE7FFE63CE6DB66DC66DF663CE7FFE0000
+F2DA:00007FFE61866FF663866FBE6F867FFE7FFE63866DB66D866DB663B67FFE0000
+F2DB:00007FFE61866FF663866FBE6F867FFE7FFE638E6DB66D8E6DB6638E7FFE0000
+F2DC:00007FFE61866FF663866FBE6F867FFE7FFE63C66DBE6DBE6DBE63C67FFE0000
+F2DD:00007FFE61866FF663866FBE6F867FFE7FFE638E6DB66DB66DB6638E7FFE0000
+F2DE:00007FFE61866FF663866FBE6F867FFE7FFE63866DBE6D8E6DBE63867FFE0000
+F2DF:00007FFE61866FF663866FBE6F867FFE7FFE63866DBE6D8E6DBE63BE7FFE0000
+F2E0:00007FFE61866FF663866FBE6F867FFE7FFE61CE6FB663B66FB661CE7FFE0000
+F2E1:00007FFE61866FF663866FBE6F867FFE7FFE61EE6FCE63EE6FEE61C67FFE0000
+F2E2:00007FFE61866FF663866FBE6F867FFE7FFE61866FF663866FBE61867FFE0000
+F2E3:00007FFE61866FF663866FBE6F867FFE7FFE618E6FF663C66FF6618E7FFE0000
+F2E4:00007FFE61866FF663866FBE6F867FFE7FFE61B66FB663866FF661F67FFE0000
+F2E5:00007FFE61866FF663866FBE6F867FFE7FFE61866FBE63866FF661867FFE0000
+F2E6:00007FFE61866FF663866FBE6F867FFE7FFE61CE6FBE638E6FB661CE7FFE0000
+F2E7:00007FFE61866FF663866FBE6F867FFE7FFE61866FF663EE6FDE61DE7FFE0000
+F2E8:00007FFE61866FF663866FBE6F867FFE7FFE61CE6FB663CE6FB661CE7FFE0000
+F2E9:00007FFE61866FF663866FBE6F867FFE7FFE61CE6FB663C66FF661CE7FFE0000
+F2EA:00007FFE61866FF663866FBE6F867FFE7FFE61866FB663866FB661B67FFE0000
+F2EB:00007FFE61866FF663866FBE6F867FFE7FFE618E6FB6638E6FB6618E7FFE0000
+F2EC:00007FFE61866FF663866FBE6F867FFE7FFE61C66FBE63BE6FBE61C67FFE0000
+F2ED:00007FFE61866FF663866FBE6F867FFE7FFE618E6FB663B66FB6618E7FFE0000
+F2EE:00007FFE61866FF663866FBE6F867FFE7FFE61866FBE638E6FBE61867FFE0000
+F2EF:00007FFE61866FF663866FBE6F867FFE7FFE61866FBE638E6FBE61BE7FFE0000
+F2F0:00007FFE61866FF663866FBE6F867FFE7FFE61CE6FB663B66FB66FCE7FFE0000
+F2F1:00007FFE61866FF663866FBE6F867FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000
+F2F2:00007FFE61866FF663866FBE6F867FFE7FFE61866FF663866FBE6F867FFE0000
+F2F3:00007FFE61866FF663866FBE6F867FFE7FFE618E6FF663C66FF66F8E7FFE0000
+F2F4:00007FFE61866FF663866FBE6F867FFE7FFE61B66FB663866FF66FF67FFE0000
+F2F5:00007FFE61866FF663866FBE6F867FFE7FFE61866FBE63866FF66F867FFE0000
+F2F6:00007FFE61866FF663866FBE6F867FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+F2F7:00007FFE61866FF663866FBE6F867FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+F2F8:00007FFE61866FF663866FBE6F867FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+F2F9:00007FFE61866FF663866FBE6F867FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+F2FA:00007FFE61866FF663866FBE6F867FFE7FFE61866FB663866FB66FB67FFE0000
+F2FB:00007FFE61866FF663866FBE6F867FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+F2FC:00007FFE61866FF663866FBE6F867FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+F2FD:00007FFE61866FF663866FBE6F867FFE7FFE618E6FB663B66FB66F8E7FFE0000
+F2FE:00007FFE61866FF663866FBE6F867FFE7FFE61866FBE638E6FBE6F867FFE0000
+F2FF:00007FFE61866FF663866FBE6F867FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+F300:00007FFE618E6FF663C66FF66F8E7FFE7FFE73CE6DB66DB66DB673CE7FFE0000
+F301:00007FFE618E6FF663C66FF66F8E7FFE7FFE73EE6DCE6DEE6DEE73C67FFE0000
+F302:00007FFE618E6FF663C66FF66F8E7FFE7FFE73866DF66D866DBE73867FFE0000
+F303:00007FFE618E6FF663C66FF66F8E7FFE7FFE738E6DF66DC66DF6738E7FFE0000
+F304:00007FFE618E6FF663C66FF66F8E7FFE7FFE73B66DB66D866DF673F67FFE0000
+F305:00007FFE618E6FF663C66FF66F8E7FFE7FFE73866DBE6D866DF673867FFE0000
+F306:00007FFE618E6FF663C66FF66F8E7FFE7FFE73CE6DBE6D8E6DB673CE7FFE0000
+F307:00007FFE618E6FF663C66FF66F8E7FFE7FFE73866DF66DEE6DDE73DE7FFE0000
+F308:00007FFE618E6FF663C66FF66F8E7FFE7FFE73CE6DB66DCE6DB673CE7FFE0000
+F309:00007FFE618E6FF663C66FF66F8E7FFE7FFE73CE6DB66DC66DF673CE7FFE0000
+F30A:00007FFE618E6FF663C66FF66F8E7FFE7FFE73866DB66D866DB673B67FFE0000
+F30B:00007FFE618E6FF663C66FF66F8E7FFE7FFE738E6DB66D8E6DB6738E7FFE0000
+F30C:00007FFE618E6FF663C66FF66F8E7FFE7FFE73C66DBE6DBE6DBE73C67FFE0000
+F30D:00007FFE618E6FF663C66FF66F8E7FFE7FFE738E6DB66DB66DB6738E7FFE0000
+F30E:00007FFE618E6FF663C66FF66F8E7FFE7FFE73866DBE6D8E6DBE73867FFE0000
+F30F:00007FFE618E6FF663C66FF66F8E7FFE7FFE73866DBE6D8E6DBE73BE7FFE0000
+F310:00007FFE618E6FF663C66FF66F8E7FFE7FFE7BCE73B67BB67BB671CE7FFE0000
+F311:00007FFE618E6FF663C66FF66F8E7FFE7FFE7BEE73CE7BEE7BEE71C67FFE0000
+F312:00007FFE618E6FF663C66FF66F8E7FFE7FFE7B8673F67B867BBE71867FFE0000
+F313:00007FFE618E6FF663C66FF66F8E7FFE7FFE7B8E73F67BC67BF6718E7FFE0000
+F314:00007FFE618E6FF663C66FF66F8E7FFE7FFE7BB673B67B867BF671F67FFE0000
+F315:00007FFE618E6FF663C66FF66F8E7FFE7FFE7B8673BE7B867BF671867FFE0000
+F316:00007FFE618E6FF663C66FF66F8E7FFE7FFE7BCE73BE7B8E7BB671CE7FFE0000
+F317:00007FFE618E6FF663C66FF66F8E7FFE7FFE7B8673F67BEE7BDE71DE7FFE0000
+F318:00007FFE618E6FF663C66FF66F8E7FFE7FFE7BCE73B67BCE7BB671CE7FFE0000
+F319:00007FFE618E6FF663C66FF66F8E7FFE7FFE7BCE73B67BC67BF671CE7FFE0000
+F31A:00007FFE618E6FF663C66FF66F8E7FFE7FFE7B8673B67B867BB671B67FFE0000
+F31B:00007FFE618E6FF663C66FF66F8E7FFE7FFE7B8E73B67B8E7BB6718E7FFE0000
+F31C:00007FFE618E6FF663C66FF66F8E7FFE7FFE7BC673BE7BBE7BBE71C67FFE0000
+F31D:00007FFE618E6FF663C66FF66F8E7FFE7FFE7B8E73B67BB67BB6718E7FFE0000
+F31E:00007FFE618E6FF663C66FF66F8E7FFE7FFE7B8673BE7B8E7BBE71867FFE0000
+F31F:00007FFE618E6FF663C66FF66F8E7FFE7FFE7B8673BE7B8E7BBE71BE7FFE0000
+F320:00007FFE618E6FF663C66FF66F8E7FFE7FFE61CE7DB661B66FB661CE7FFE0000
+F321:00007FFE618E6FF663C66FF66F8E7FFE7FFE61EE7DCE61EE6FEE61C67FFE0000
+F322:00007FFE618E6FF663C66FF66F8E7FFE7FFE61867DF661866FBE61867FFE0000
+F323:00007FFE618E6FF663C66FF66F8E7FFE7FFE618E7DF661C66FF6618E7FFE0000
+F324:00007FFE618E6FF663C66FF66F8E7FFE7FFE61B67DB661866FF661F67FFE0000
+F325:00007FFE618E6FF663C66FF66F8E7FFE7FFE61867DBE61866FF661867FFE0000
+F326:00007FFE618E6FF663C66FF66F8E7FFE7FFE61CE7DBE618E6FB661CE7FFE0000
+F327:00007FFE618E6FF663C66FF66F8E7FFE7FFE61867DF661EE6FDE61DE7FFE0000
+F328:00007FFE618E6FF663C66FF66F8E7FFE7FFE61CE7DB661CE6FB661CE7FFE0000
+F329:00007FFE618E6FF663C66FF66F8E7FFE7FFE61CE7DB661C66FF661CE7FFE0000
+F32A:00007FFE618E6FF663C66FF66F8E7FFE7FFE61867DB661866FB661B67FFE0000
+F32B:00007FFE618E6FF663C66FF66F8E7FFE7FFE618E7DB6618E6FB6618E7FFE0000
+F32C:00007FFE618E6FF663C66FF66F8E7FFE7FFE61C67DBE61BE6FBE61C67FFE0000
+F32D:00007FFE618E6FF663C66FF66F8E7FFE7FFE618E7DB661B66FB6618E7FFE0000
+F32E:00007FFE618E6FF663C66FF66F8E7FFE7FFE61867DBE618E6FBE61867FFE0000
+F32F:00007FFE618E6FF663C66FF66F8E7FFE7FFE61867DBE618E6FBE61BE7FFE0000
+F330:00007FFE618E6FF663C66FF66F8E7FFE7FFE63CE7DB671B67DB663CE7FFE0000
+F331:00007FFE618E6FF663C66FF66F8E7FFE7FFE63EE7DCE71EE7DEE63C67FFE0000
+F332:00007FFE618E6FF663C66FF66F8E7FFE7FFE63867DF671867DBE63867FFE0000
+F333:00007FFE618E6FF663C66FF66F8E7FFE7FFE638E7DF671C67DF6638E7FFE0000
+F334:00007FFE618E6FF663C66FF66F8E7FFE7FFE63B67DB671867DF663F67FFE0000
+F335:00007FFE618E6FF663C66FF66F8E7FFE7FFE63867DBE71867DF663867FFE0000
+F336:00007FFE618E6FF663C66FF66F8E7FFE7FFE63CE7DBE718E7DB663CE7FFE0000
+F337:00007FFE618E6FF663C66FF66F8E7FFE7FFE63867DF671EE7DDE63DE7FFE0000
+F338:00007FFE618E6FF663C66FF66F8E7FFE7FFE63CE7DB671CE7DB663CE7FFE0000
+F339:00007FFE618E6FF663C66FF66F8E7FFE7FFE63CE7DB671C67DF663CE7FFE0000
+F33A:00007FFE618E6FF663C66FF66F8E7FFE7FFE63867DB671867DB663B67FFE0000
+F33B:00007FFE618E6FF663C66FF66F8E7FFE7FFE638E7DB6718E7DB6638E7FFE0000
+F33C:00007FFE618E6FF663C66FF66F8E7FFE7FFE63C67DBE71BE7DBE63C67FFE0000
+F33D:00007FFE618E6FF663C66FF66F8E7FFE7FFE638E7DB671B67DB6638E7FFE0000
+F33E:00007FFE618E6FF663C66FF66F8E7FFE7FFE63867DBE718E7DBE63867FFE0000
+F33F:00007FFE618E6FF663C66FF66F8E7FFE7FFE63867DBE718E7DBE63BE7FFE0000
+F340:00007FFE618E6FF663C66FF66F8E7FFE7FFE6DCE6DB661B67DB67DCE7FFE0000
+F341:00007FFE618E6FF663C66FF66F8E7FFE7FFE6DEE6DCE61EE7DEE7DC67FFE0000
+F342:00007FFE618E6FF663C66FF66F8E7FFE7FFE6D866DF661867DBE7D867FFE0000
+F343:00007FFE618E6FF663C66FF66F8E7FFE7FFE6D8E6DF661C67DF67D8E7FFE0000
+F344:00007FFE618E6FF663C66FF66F8E7FFE7FFE6DB66DB661867DF67DF67FFE0000
+F345:00007FFE618E6FF663C66FF66F8E7FFE7FFE6D866DBE61867DF67D867FFE0000
+F346:00007FFE618E6FF663C66FF66F8E7FFE7FFE6DCE6DBE618E7DB67DCE7FFE0000
+F347:00007FFE618E6FF663C66FF66F8E7FFE7FFE6D866DF661EE7DDE7DDE7FFE0000
+F348:00007FFE618E6FF663C66FF66F8E7FFE7FFE6DCE6DB661CE7DB67DCE7FFE0000
+F349:00007FFE618E6FF663C66FF66F8E7FFE7FFE6DCE6DB661C67DF67DCE7FFE0000
+F34A:00007FFE618E6FF663C66FF66F8E7FFE7FFE6D866DB661867DB67DB67FFE0000
+F34B:00007FFE618E6FF663C66FF66F8E7FFE7FFE6D8E6DB6618E7DB67D8E7FFE0000
+F34C:00007FFE618E6FF663C66FF66F8E7FFE7FFE6DC66DBE61BE7DBE7DC67FFE0000
+F34D:00007FFE618E6FF663C66FF66F8E7FFE7FFE6D8E6DB661B67DB67D8E7FFE0000
+F34E:00007FFE618E6FF663C66FF66F8E7FFE7FFE6D866DBE618E7DBE7D867FFE0000
+F34F:00007FFE618E6FF663C66FF66F8E7FFE7FFE6D866DBE618E7DBE7DBE7FFE0000
+F350:00007FFE618E6FF663C66FF66F8E7FFE7FFE61CE6FB661B67DB661CE7FFE0000
+F351:00007FFE618E6FF663C66FF66F8E7FFE7FFE61EE6FCE61EE7DEE61C67FFE0000
+F352:00007FFE618E6FF663C66FF66F8E7FFE7FFE61866FF661867DBE61867FFE0000
+F353:00007FFE618E6FF663C66FF66F8E7FFE7FFE618E6FF661C67DF6618E7FFE0000
+F354:00007FFE618E6FF663C66FF66F8E7FFE7FFE61B66FB661867DF661F67FFE0000
+F355:00007FFE618E6FF663C66FF66F8E7FFE7FFE61866FBE61867DF661867FFE0000
+F356:00007FFE618E6FF663C66FF66F8E7FFE7FFE61CE6FBE618E7DB661CE7FFE0000
+F357:00007FFE618E6FF663C66FF66F8E7FFE7FFE61866FF661EE7DDE61DE7FFE0000
+F358:00007FFE618E6FF663C66FF66F8E7FFE7FFE61CE6FB661CE7DB661CE7FFE0000
+F359:00007FFE618E6FF663C66FF66F8E7FFE7FFE61CE6FB661C67DF661CE7FFE0000
+F35A:00007FFE618E6FF663C66FF66F8E7FFE7FFE61866FB661867DB661B67FFE0000
+F35B:00007FFE618E6FF663C66FF66F8E7FFE7FFE618E6FB6618E7DB6618E7FFE0000
+F35C:00007FFE618E6FF663C66FF66F8E7FFE7FFE61C66FBE61BE7DBE61C67FFE0000
+F35D:00007FFE618E6FF663C66FF66F8E7FFE7FFE618E6FB661B67DB6618E7FFE0000
+F35E:00007FFE618E6FF663C66FF66F8E7FFE7FFE61866FBE618E7DBE61867FFE0000
+F35F:00007FFE618E6FF663C66FF66F8E7FFE7FFE61866FBE618E7DBE61BE7FFE0000
+F360:00007FFE618E6FF663C66FF66F8E7FFE7FFE73CE6FB663B66DB673CE7FFE0000
+F361:00007FFE618E6FF663C66FF66F8E7FFE7FFE73EE6FCE63EE6DEE73C67FFE0000
+F362:00007FFE618E6FF663C66FF66F8E7FFE7FFE73866FF663866DBE73867FFE0000
+F363:00007FFE618E6FF663C66FF66F8E7FFE7FFE738E6FF663C66DF6738E7FFE0000
+F364:00007FFE618E6FF663C66FF66F8E7FFE7FFE73B66FB663866DF673F67FFE0000
+F365:00007FFE618E6FF663C66FF66F8E7FFE7FFE73866FBE63866DF673867FFE0000
+F366:00007FFE618E6FF663C66FF66F8E7FFE7FFE73CE6FBE638E6DB673CE7FFE0000
+F367:00007FFE618E6FF663C66FF66F8E7FFE7FFE73866FF663EE6DDE73DE7FFE0000
+F368:00007FFE618E6FF663C66FF66F8E7FFE7FFE73CE6FB663CE6DB673CE7FFE0000
+F369:00007FFE618E6FF663C66FF66F8E7FFE7FFE73CE6FB663C66DF673CE7FFE0000
+F36A:00007FFE618E6FF663C66FF66F8E7FFE7FFE73866FB663866DB673B67FFE0000
+F36B:00007FFE618E6FF663C66FF66F8E7FFE7FFE738E6FB6638E6DB6738E7FFE0000
+F36C:00007FFE618E6FF663C66FF66F8E7FFE7FFE73C66FBE63BE6DBE73C67FFE0000
+F36D:00007FFE618E6FF663C66FF66F8E7FFE7FFE738E6FB663B66DB6738E7FFE0000
+F36E:00007FFE618E6FF663C66FF66F8E7FFE7FFE73866FBE638E6DBE73867FFE0000
+F36F:00007FFE618E6FF663C66FF66F8E7FFE7FFE73866FBE638E6DBE73BE7FFE0000
+F370:00007FFE618E6FF663C66FF66F8E7FFE7FFE61CE7DB67BB677B677CE7FFE0000
+F371:00007FFE618E6FF663C66FF66F8E7FFE7FFE61EE7DCE7BEE77EE77C67FFE0000
+F372:00007FFE618E6FF663C66FF66F8E7FFE7FFE61867DF67B8677BE77867FFE0000
+F373:00007FFE618E6FF663C66FF66F8E7FFE7FFE618E7DF67BC677F6778E7FFE0000
+F374:00007FFE618E6FF663C66FF66F8E7FFE7FFE61B67DB67B8677F677F67FFE0000
+F375:00007FFE618E6FF663C66FF66F8E7FFE7FFE61867DBE7B8677F677867FFE0000
+F376:00007FFE618E6FF663C66FF66F8E7FFE7FFE61CE7DBE7B8E77B677CE7FFE0000
+F377:00007FFE618E6FF663C66FF66F8E7FFE7FFE61867DF67BEE77DE77DE7FFE0000
+F378:00007FFE618E6FF663C66FF66F8E7FFE7FFE61CE7DB67BCE77B677CE7FFE0000
+F379:00007FFE618E6FF663C66FF66F8E7FFE7FFE61CE7DB67BC677F677CE7FFE0000
+F37A:00007FFE618E6FF663C66FF66F8E7FFE7FFE61867DB67B8677B677B67FFE0000
+F37B:00007FFE618E6FF663C66FF66F8E7FFE7FFE618E7DB67B8E77B6778E7FFE0000
+F37C:00007FFE618E6FF663C66FF66F8E7FFE7FFE61C67DBE7BBE77BE77C67FFE0000
+F37D:00007FFE618E6FF663C66FF66F8E7FFE7FFE618E7DB67BB677B6778E7FFE0000
+F37E:00007FFE618E6FF663C66FF66F8E7FFE7FFE61867DBE7B8E77BE77867FFE0000
+F37F:00007FFE618E6FF663C66FF66F8E7FFE7FFE61867DBE7B8E77BE77BE7FFE0000
+F380:00007FFE618E6FF663C66FF66F8E7FFE7FFE73CE6DB673B66DB673CE7FFE0000
+F381:00007FFE618E6FF663C66FF66F8E7FFE7FFE73EE6DCE73EE6DEE73C67FFE0000
+F382:00007FFE618E6FF663C66FF66F8E7FFE7FFE73866DF673866DBE73867FFE0000
+F383:00007FFE618E6FF663C66FF66F8E7FFE7FFE738E6DF673C66DF6738E7FFE0000
+F384:00007FFE618E6FF663C66FF66F8E7FFE7FFE73B66DB673866DF673F67FFE0000
+F385:00007FFE618E6FF663C66FF66F8E7FFE7FFE73866DBE73866DF673867FFE0000
+F386:00007FFE618E6FF663C66FF66F8E7FFE7FFE73CE6DBE738E6DB673CE7FFE0000
+F387:00007FFE618E6FF663C66FF66F8E7FFE7FFE73866DF673EE6DDE73DE7FFE0000
+F388:00007FFE618E6FF663C66FF66F8E7FFE7FFE73CE6DB673CE6DB673CE7FFE0000
+F389:00007FFE618E6FF663C66FF66F8E7FFE7FFE73CE6DB673C66DF673CE7FFE0000
+F38A:00007FFE618E6FF663C66FF66F8E7FFE7FFE73866DB673866DB673B67FFE0000
+F38B:00007FFE618E6FF663C66FF66F8E7FFE7FFE738E6DB6738E6DB6738E7FFE0000
+F38C:00007FFE618E6FF663C66FF66F8E7FFE7FFE73C66DBE73BE6DBE73C67FFE0000
+F38D:00007FFE618E6FF663C66FF66F8E7FFE7FFE738E6DB673B66DB6738E7FFE0000
+F38E:00007FFE618E6FF663C66FF66F8E7FFE7FFE73866DBE738E6DBE73867FFE0000
+F38F:00007FFE618E6FF663C66FF66F8E7FFE7FFE73866DBE738E6DBE73BE7FFE0000
+F390:00007FFE618E6FF663C66FF66F8E7FFE7FFE73CE6DB671B67DB673CE7FFE0000
+F391:00007FFE618E6FF663C66FF66F8E7FFE7FFE73EE6DCE71EE7DEE73C67FFE0000
+F392:00007FFE618E6FF663C66FF66F8E7FFE7FFE73866DF671867DBE73867FFE0000
+F393:00007FFE618E6FF663C66FF66F8E7FFE7FFE738E6DF671C67DF6738E7FFE0000
+F394:00007FFE618E6FF663C66FF66F8E7FFE7FFE73B66DB671867DF673F67FFE0000
+F395:00007FFE618E6FF663C66FF66F8E7FFE7FFE73866DBE71867DF673867FFE0000
+F396:00007FFE618E6FF663C66FF66F8E7FFE7FFE73CE6DBE718E7DB673CE7FFE0000
+F397:00007FFE618E6FF663C66FF66F8E7FFE7FFE73866DF671EE7DDE73DE7FFE0000
+F398:00007FFE618E6FF663C66FF66F8E7FFE7FFE73CE6DB671CE7DB673CE7FFE0000
+F399:00007FFE618E6FF663C66FF66F8E7FFE7FFE73CE6DB671C67DF673CE7FFE0000
+F39A:00007FFE618E6FF663C66FF66F8E7FFE7FFE73866DB671867DB673B67FFE0000
+F39B:00007FFE618E6FF663C66FF66F8E7FFE7FFE738E6DB6718E7DB6738E7FFE0000
+F39C:00007FFE618E6FF663C66FF66F8E7FFE7FFE73C66DBE71BE7DBE73C67FFE0000
+F39D:00007FFE618E6FF663C66FF66F8E7FFE7FFE738E6DB671B67DB6738E7FFE0000
+F39E:00007FFE618E6FF663C66FF66F8E7FFE7FFE73866DBE718E7DBE73867FFE0000
+F39F:00007FFE618E6FF663C66FF66F8E7FFE7FFE73866DBE718E7DBE73BE7FFE0000
+F3A0:00007FFE618E6FF663C66FF66F8E7FFE7FFE61CE6DB661B66DB66DCE7FFE0000
+F3A1:00007FFE618E6FF663C66FF66F8E7FFE7FFE61EE6DCE61EE6DEE6DC67FFE0000
+F3A2:00007FFE618E6FF663C66FF66F8E7FFE7FFE61866DF661866DBE6D867FFE0000
+F3A3:00007FFE618E6FF663C66FF66F8E7FFE7FFE618E6DF661C66DF66D8E7FFE0000
+F3A4:00007FFE618E6FF663C66FF66F8E7FFE7FFE61B66DB661866DF66DF67FFE0000
+F3A5:00007FFE618E6FF663C66FF66F8E7FFE7FFE61866DBE61866DF66D867FFE0000
+F3A6:00007FFE618E6FF663C66FF66F8E7FFE7FFE61CE6DBE618E6DB66DCE7FFE0000
+F3A7:00007FFE618E6FF663C66FF66F8E7FFE7FFE61866DF661EE6DDE6DDE7FFE0000
+F3A8:00007FFE618E6FF663C66FF66F8E7FFE7FFE61CE6DB661CE6DB66DCE7FFE0000
+F3A9:00007FFE618E6FF663C66FF66F8E7FFE7FFE61CE6DB661C66DF66DCE7FFE0000
+F3AA:00007FFE618E6FF663C66FF66F8E7FFE7FFE61866DB661866DB66DB67FFE0000
+F3AB:00007FFE618E6FF663C66FF66F8E7FFE7FFE618E6DB6618E6DB66D8E7FFE0000
+F3AC:00007FFE618E6FF663C66FF66F8E7FFE7FFE61C66DBE61BE6DBE6DC67FFE0000
+F3AD:00007FFE618E6FF663C66FF66F8E7FFE7FFE618E6DB661B66DB66D8E7FFE0000
+F3AE:00007FFE618E6FF663C66FF66F8E7FFE7FFE61866DBE618E6DBE6D867FFE0000
+F3AF:00007FFE618E6FF663C66FF66F8E7FFE7FFE61866DBE618E6DBE6DBE7FFE0000
+F3B0:00007FFE618E6FF663C66FF66F8E7FFE7FFE63CE6DB663B66DB663CE7FFE0000
+F3B1:00007FFE618E6FF663C66FF66F8E7FFE7FFE63EE6DCE63EE6DEE63C67FFE0000
+F3B2:00007FFE618E6FF663C66FF66F8E7FFE7FFE63866DF663866DBE63867FFE0000
+F3B3:00007FFE618E6FF663C66FF66F8E7FFE7FFE638E6DF663C66DF6638E7FFE0000
+F3B4:00007FFE618E6FF663C66FF66F8E7FFE7FFE63B66DB663866DF663F67FFE0000
+F3B5:00007FFE618E6FF663C66FF66F8E7FFE7FFE63866DBE63866DF663867FFE0000
+F3B6:00007FFE618E6FF663C66FF66F8E7FFE7FFE63CE6DBE638E6DB663CE7FFE0000
+F3B7:00007FFE618E6FF663C66FF66F8E7FFE7FFE63866DF663EE6DDE63DE7FFE0000
+F3B8:00007FFE618E6FF663C66FF66F8E7FFE7FFE63CE6DB663CE6DB663CE7FFE0000
+F3B9:00007FFE618E6FF663C66FF66F8E7FFE7FFE63CE6DB663C66DF663CE7FFE0000
+F3BA:00007FFE618E6FF663C66FF66F8E7FFE7FFE63866DB663866DB663B67FFE0000
+F3BB:00007FFE618E6FF663C66FF66F8E7FFE7FFE638E6DB6638E6DB6638E7FFE0000
+F3BC:00007FFE618E6FF663C66FF66F8E7FFE7FFE63C66DBE63BE6DBE63C67FFE0000
+F3BD:00007FFE618E6FF663C66FF66F8E7FFE7FFE638E6DB663B66DB6638E7FFE0000
+F3BE:00007FFE618E6FF663C66FF66F8E7FFE7FFE63866DBE638E6DBE63867FFE0000
+F3BF:00007FFE618E6FF663C66FF66F8E7FFE7FFE63866DBE638E6DBE63BE7FFE0000
+F3C0:00007FFE618E6FF663C66FF66F8E7FFE7FFE71CE6FB66FB66FB671CE7FFE0000
+F3C1:00007FFE618E6FF663C66FF66F8E7FFE7FFE71EE6FCE6FEE6FEE71C67FFE0000
+F3C2:00007FFE618E6FF663C66FF66F8E7FFE7FFE71866FF66F866FBE71867FFE0000
+F3C3:00007FFE618E6FF663C66FF66F8E7FFE7FFE718E6FF66FC66FF6718E7FFE0000
+F3C4:00007FFE618E6FF663C66FF66F8E7FFE7FFE71B66FB66F866FF671F67FFE0000
+F3C5:00007FFE618E6FF663C66FF66F8E7FFE7FFE71866FBE6F866FF671867FFE0000
+F3C6:00007FFE618E6FF663C66FF66F8E7FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000
+F3C7:00007FFE618E6FF663C66FF66F8E7FFE7FFE71866FF66FEE6FDE71DE7FFE0000
+F3C8:00007FFE618E6FF663C66FF66F8E7FFE7FFE71CE6FB66FCE6FB671CE7FFE0000
+F3C9:00007FFE618E6FF663C66FF66F8E7FFE7FFE71CE6FB66FC66FF671CE7FFE0000
+F3CA:00007FFE618E6FF663C66FF66F8E7FFE7FFE71866FB66F866FB671B67FFE0000
+F3CB:00007FFE618E6FF663C66FF66F8E7FFE7FFE718E6FB66F8E6FB6718E7FFE0000
+F3CC:00007FFE618E6FF663C66FF66F8E7FFE7FFE71C66FBE6FBE6FBE71C67FFE0000
+F3CD:00007FFE618E6FF663C66FF66F8E7FFE7FFE718E6FB66FB66FB6718E7FFE0000
+F3CE:00007FFE618E6FF663C66FF66F8E7FFE7FFE71866FBE6F8E6FBE71867FFE0000
+F3CF:00007FFE618E6FF663C66FF66F8E7FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+F3D0:00007FFE618E6FF663C66FF66F8E7FFE7FFE63CE6DB66DB66DB663CE7FFE0000
+F3D1:00007FFE618E6FF663C66FF66F8E7FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000
+F3D2:00007FFE618E6FF663C66FF66F8E7FFE7FFE63866DF66D866DBE63867FFE0000
+F3D3:00007FFE618E6FF663C66FF66F8E7FFE7FFE638E6DF66DC66DF6638E7FFE0000
+F3D4:00007FFE618E6FF663C66FF66F8E7FFE7FFE63B66DB66D866DF663F67FFE0000
+F3D5:00007FFE618E6FF663C66FF66F8E7FFE7FFE63866DBE6D866DF663867FFE0000
+F3D6:00007FFE618E6FF663C66FF66F8E7FFE7FFE63CE6DBE6D8E6DB663CE7FFE0000
+F3D7:00007FFE618E6FF663C66FF66F8E7FFE7FFE63866DF66DEE6DDE63DE7FFE0000
+F3D8:00007FFE618E6FF663C66FF66F8E7FFE7FFE63CE6DB66DCE6DB663CE7FFE0000
+F3D9:00007FFE618E6FF663C66FF66F8E7FFE7FFE63CE6DB66DC66DF663CE7FFE0000
+F3DA:00007FFE618E6FF663C66FF66F8E7FFE7FFE63866DB66D866DB663B67FFE0000
+F3DB:00007FFE618E6FF663C66FF66F8E7FFE7FFE638E6DB66D8E6DB6638E7FFE0000
+F3DC:00007FFE618E6FF663C66FF66F8E7FFE7FFE63C66DBE6DBE6DBE63C67FFE0000
+F3DD:00007FFE618E6FF663C66FF66F8E7FFE7FFE638E6DB66DB66DB6638E7FFE0000
+F3DE:00007FFE618E6FF663C66FF66F8E7FFE7FFE63866DBE6D8E6DBE63867FFE0000
+F3DF:00007FFE618E6FF663C66FF66F8E7FFE7FFE63866DBE6D8E6DBE63BE7FFE0000
+F3E0:00007FFE618E6FF663C66FF66F8E7FFE7FFE61CE6FB663B66FB661CE7FFE0000
+F3E1:00007FFE618E6FF663C66FF66F8E7FFE7FFE61EE6FCE63EE6FEE61C67FFE0000
+F3E2:00007FFE618E6FF663C66FF66F8E7FFE7FFE61866FF663866FBE61867FFE0000
+F3E3:00007FFE618E6FF663C66FF66F8E7FFE7FFE618E6FF663C66FF6618E7FFE0000
+F3E4:00007FFE618E6FF663C66FF66F8E7FFE7FFE61B66FB663866FF661F67FFE0000
+F3E5:00007FFE618E6FF663C66FF66F8E7FFE7FFE61866FBE63866FF661867FFE0000
+F3E6:00007FFE618E6FF663C66FF66F8E7FFE7FFE61CE6FBE638E6FB661CE7FFE0000
+F3E7:00007FFE618E6FF663C66FF66F8E7FFE7FFE61866FF663EE6FDE61DE7FFE0000
+F3E8:00007FFE618E6FF663C66FF66F8E7FFE7FFE61CE6FB663CE6FB661CE7FFE0000
+F3E9:00007FFE618E6FF663C66FF66F8E7FFE7FFE61CE6FB663C66FF661CE7FFE0000
+F3EA:00007FFE618E6FF663C66FF66F8E7FFE7FFE61866FB663866FB661B67FFE0000
+F3EB:00007FFE618E6FF663C66FF66F8E7FFE7FFE618E6FB6638E6FB6618E7FFE0000
+F3EC:00007FFE618E6FF663C66FF66F8E7FFE7FFE61C66FBE63BE6FBE61C67FFE0000
+F3ED:00007FFE618E6FF663C66FF66F8E7FFE7FFE618E6FB663B66FB6618E7FFE0000
+F3EE:00007FFE618E6FF663C66FF66F8E7FFE7FFE61866FBE638E6FBE61867FFE0000
+F3EF:00007FFE618E6FF663C66FF66F8E7FFE7FFE61866FBE638E6FBE61BE7FFE0000
+F3F0:00007FFE618E6FF663C66FF66F8E7FFE7FFE61CE6FB663B66FB66FCE7FFE0000
+F3F1:00007FFE618E6FF663C66FF66F8E7FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000
+F3F2:00007FFE618E6FF663C66FF66F8E7FFE7FFE61866FF663866FBE6F867FFE0000
+F3F3:00007FFE618E6FF663C66FF66F8E7FFE7FFE618E6FF663C66FF66F8E7FFE0000
+F3F4:00007FFE618E6FF663C66FF66F8E7FFE7FFE61B66FB663866FF66FF67FFE0000
+F3F5:00007FFE618E6FF663C66FF66F8E7FFE7FFE61866FBE63866FF66F867FFE0000
+F3F6:00007FFE618E6FF663C66FF66F8E7FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+F3F7:00007FFE618E6FF663C66FF66F8E7FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+F3F8:00007FFE618E6FF663C66FF66F8E7FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+F3F9:00007FFE618E6FF663C66FF66F8E7FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+F3FA:00007FFE618E6FF663C66FF66F8E7FFE7FFE61866FB663866FB66FB67FFE0000
+F3FB:00007FFE618E6FF663C66FF66F8E7FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+F3FC:00007FFE618E6FF663C66FF66F8E7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+F3FD:00007FFE618E6FF663C66FF66F8E7FFE7FFE618E6FB663B66FB66F8E7FFE0000
+F3FE:00007FFE618E6FF663C66FF66F8E7FFE7FFE61866FBE638E6FBE6F867FFE0000
+F3FF:00007FFE618E6FF663C66FF66F8E7FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+F400:00007FFE61B66FB663866FF66FF67FFE7FFE73CE6DB66DB66DB673CE7FFE0000
+F401:00007FFE61B66FB663866FF66FF67FFE7FFE73EE6DCE6DEE6DEE73C67FFE0000
+F402:00007FFE61B66FB663866FF66FF67FFE7FFE73866DF66D866DBE73867FFE0000
+F403:00007FFE61B66FB663866FF66FF67FFE7FFE738E6DF66DC66DF6738E7FFE0000
+F404:00007FFE61B66FB663866FF66FF67FFE7FFE73B66DB66D866DF673F67FFE0000
+F405:00007FFE61B66FB663866FF66FF67FFE7FFE73866DBE6D866DF673867FFE0000
+F406:00007FFE61B66FB663866FF66FF67FFE7FFE73CE6DBE6D8E6DB673CE7FFE0000
+F407:00007FFE61B66FB663866FF66FF67FFE7FFE73866DF66DEE6DDE73DE7FFE0000
+F408:00007FFE61B66FB663866FF66FF67FFE7FFE73CE6DB66DCE6DB673CE7FFE0000
+F409:00007FFE61B66FB663866FF66FF67FFE7FFE73CE6DB66DC66DF673CE7FFE0000
+F40A:00007FFE61B66FB663866FF66FF67FFE7FFE73866DB66D866DB673B67FFE0000
+F40B:00007FFE61B66FB663866FF66FF67FFE7FFE738E6DB66D8E6DB6738E7FFE0000
+F40C:00007FFE61B66FB663866FF66FF67FFE7FFE73C66DBE6DBE6DBE73C67FFE0000
+F40D:00007FFE61B66FB663866FF66FF67FFE7FFE738E6DB66DB66DB6738E7FFE0000
+F40E:00007FFE61B66FB663866FF66FF67FFE7FFE73866DBE6D8E6DBE73867FFE0000
+F40F:00007FFE61B66FB663866FF66FF67FFE7FFE73866DBE6D8E6DBE73BE7FFE0000
+F410:00007FFE61B66FB663866FF66FF67FFE7FFE7BCE73B67BB67BB671CE7FFE0000
+F411:00007FFE61B66FB663866FF66FF67FFE7FFE7BEE73CE7BEE7BEE71C67FFE0000
+F412:00007FFE61B66FB663866FF66FF67FFE7FFE7B8673F67B867BBE71867FFE0000
+F413:00007FFE61B66FB663866FF66FF67FFE7FFE7B8E73F67BC67BF6718E7FFE0000
+F414:00007FFE61B66FB663866FF66FF67FFE7FFE7BB673B67B867BF671F67FFE0000
+F415:00007FFE61B66FB663866FF66FF67FFE7FFE7B8673BE7B867BF671867FFE0000
+F416:00007FFE61B66FB663866FF66FF67FFE7FFE7BCE73BE7B8E7BB671CE7FFE0000
+F417:00007FFE61B66FB663866FF66FF67FFE7FFE7B8673F67BEE7BDE71DE7FFE0000
+F418:00007FFE61B66FB663866FF66FF67FFE7FFE7BCE73B67BCE7BB671CE7FFE0000
+F419:00007FFE61B66FB663866FF66FF67FFE7FFE7BCE73B67BC67BF671CE7FFE0000
+F41A:00007FFE61B66FB663866FF66FF67FFE7FFE7B8673B67B867BB671B67FFE0000
+F41B:00007FFE61B66FB663866FF66FF67FFE7FFE7B8E73B67B8E7BB6718E7FFE0000
+F41C:00007FFE61B66FB663866FF66FF67FFE7FFE7BC673BE7BBE7BBE71C67FFE0000
+F41D:00007FFE61B66FB663866FF66FF67FFE7FFE7B8E73B67BB67BB6718E7FFE0000
+F41E:00007FFE61B66FB663866FF66FF67FFE7FFE7B8673BE7B8E7BBE71867FFE0000
+F41F:00007FFE61B66FB663866FF66FF67FFE7FFE7B8673BE7B8E7BBE71BE7FFE0000
+F420:00007FFE61B66FB663866FF66FF67FFE7FFE61CE7DB661B66FB661CE7FFE0000
+F421:00007FFE61B66FB663866FF66FF67FFE7FFE61EE7DCE61EE6FEE61C67FFE0000
+F422:00007FFE61B66FB663866FF66FF67FFE7FFE61867DF661866FBE61867FFE0000
+F423:00007FFE61B66FB663866FF66FF67FFE7FFE618E7DF661C66FF6618E7FFE0000
+F424:00007FFE61B66FB663866FF66FF67FFE7FFE61B67DB661866FF661F67FFE0000
+F425:00007FFE61B66FB663866FF66FF67FFE7FFE61867DBE61866FF661867FFE0000
+F426:00007FFE61B66FB663866FF66FF67FFE7FFE61CE7DBE618E6FB661CE7FFE0000
+F427:00007FFE61B66FB663866FF66FF67FFE7FFE61867DF661EE6FDE61DE7FFE0000
+F428:00007FFE61B66FB663866FF66FF67FFE7FFE61CE7DB661CE6FB661CE7FFE0000
+F429:00007FFE61B66FB663866FF66FF67FFE7FFE61CE7DB661C66FF661CE7FFE0000
+F42A:00007FFE61B66FB663866FF66FF67FFE7FFE61867DB661866FB661B67FFE0000
+F42B:00007FFE61B66FB663866FF66FF67FFE7FFE618E7DB6618E6FB6618E7FFE0000
+F42C:00007FFE61B66FB663866FF66FF67FFE7FFE61C67DBE61BE6FBE61C67FFE0000
+F42D:00007FFE61B66FB663866FF66FF67FFE7FFE618E7DB661B66FB6618E7FFE0000
+F42E:00007FFE61B66FB663866FF66FF67FFE7FFE61867DBE618E6FBE61867FFE0000
+F42F:00007FFE61B66FB663866FF66FF67FFE7FFE61867DBE618E6FBE61BE7FFE0000
+F430:00007FFE61B66FB663866FF66FF67FFE7FFE63CE7DB671B67DB663CE7FFE0000
+F431:00007FFE61B66FB663866FF66FF67FFE7FFE63EE7DCE71EE7DEE63C67FFE0000
+F432:00007FFE61B66FB663866FF66FF67FFE7FFE63867DF671867DBE63867FFE0000
+F433:00007FFE61B66FB663866FF66FF67FFE7FFE638E7DF671C67DF6638E7FFE0000
+F434:00007FFE61B66FB663866FF66FF67FFE7FFE63B67DB671867DF663F67FFE0000
+F435:00007FFE61B66FB663866FF66FF67FFE7FFE63867DBE71867DF663867FFE0000
+F436:00007FFE61B66FB663866FF66FF67FFE7FFE63CE7DBE718E7DB663CE7FFE0000
+F437:00007FFE61B66FB663866FF66FF67FFE7FFE63867DF671EE7DDE63DE7FFE0000
+F438:00007FFE61B66FB663866FF66FF67FFE7FFE63CE7DB671CE7DB663CE7FFE0000
+F439:00007FFE61B66FB663866FF66FF67FFE7FFE63CE7DB671C67DF663CE7FFE0000
+F43A:00007FFE61B66FB663866FF66FF67FFE7FFE63867DB671867DB663B67FFE0000
+F43B:00007FFE61B66FB663866FF66FF67FFE7FFE638E7DB6718E7DB6638E7FFE0000
+F43C:00007FFE61B66FB663866FF66FF67FFE7FFE63C67DBE71BE7DBE63C67FFE0000
+F43D:00007FFE61B66FB663866FF66FF67FFE7FFE638E7DB671B67DB6638E7FFE0000
+F43E:00007FFE61B66FB663866FF66FF67FFE7FFE63867DBE718E7DBE63867FFE0000
+F43F:00007FFE61B66FB663866FF66FF67FFE7FFE63867DBE718E7DBE63BE7FFE0000
+F440:00007FFE61B66FB663866FF66FF67FFE7FFE6DCE6DB661B67DB67DCE7FFE0000
+F441:00007FFE61B66FB663866FF66FF67FFE7FFE6DEE6DCE61EE7DEE7DC67FFE0000
+F442:00007FFE61B66FB663866FF66FF67FFE7FFE6D866DF661867DBE7D867FFE0000
+F443:00007FFE61B66FB663866FF66FF67FFE7FFE6D8E6DF661C67DF67D8E7FFE0000
+F444:00007FFE61B66FB663866FF66FF67FFE7FFE6DB66DB661867DF67DF67FFE0000
+F445:00007FFE61B66FB663866FF66FF67FFE7FFE6D866DBE61867DF67D867FFE0000
+F446:00007FFE61B66FB663866FF66FF67FFE7FFE6DCE6DBE618E7DB67DCE7FFE0000
+F447:00007FFE61B66FB663866FF66FF67FFE7FFE6D866DF661EE7DDE7DDE7FFE0000
+F448:00007FFE61B66FB663866FF66FF67FFE7FFE6DCE6DB661CE7DB67DCE7FFE0000
+F449:00007FFE61B66FB663866FF66FF67FFE7FFE6DCE6DB661C67DF67DCE7FFE0000
+F44A:00007FFE61B66FB663866FF66FF67FFE7FFE6D866DB661867DB67DB67FFE0000
+F44B:00007FFE61B66FB663866FF66FF67FFE7FFE6D8E6DB6618E7DB67D8E7FFE0000
+F44C:00007FFE61B66FB663866FF66FF67FFE7FFE6DC66DBE61BE7DBE7DC67FFE0000
+F44D:00007FFE61B66FB663866FF66FF67FFE7FFE6D8E6DB661B67DB67D8E7FFE0000
+F44E:00007FFE61B66FB663866FF66FF67FFE7FFE6D866DBE618E7DBE7D867FFE0000
+F44F:00007FFE61B66FB663866FF66FF67FFE7FFE6D866DBE618E7DBE7DBE7FFE0000
+F450:00007FFE61B66FB663866FF66FF67FFE7FFE61CE6FB661B67DB661CE7FFE0000
+F451:00007FFE61B66FB663866FF66FF67FFE7FFE61EE6FCE61EE7DEE61C67FFE0000
+F452:00007FFE61B66FB663866FF66FF67FFE7FFE61866FF661867DBE61867FFE0000
+F453:00007FFE61B66FB663866FF66FF67FFE7FFE618E6FF661C67DF6618E7FFE0000
+F454:00007FFE61B66FB663866FF66FF67FFE7FFE61B66FB661867DF661F67FFE0000
+F455:00007FFE61B66FB663866FF66FF67FFE7FFE61866FBE61867DF661867FFE0000
+F456:00007FFE61B66FB663866FF66FF67FFE7FFE61CE6FBE618E7DB661CE7FFE0000
+F457:00007FFE61B66FB663866FF66FF67FFE7FFE61866FF661EE7DDE61DE7FFE0000
+F458:00007FFE61B66FB663866FF66FF67FFE7FFE61CE6FB661CE7DB661CE7FFE0000
+F459:00007FFE61B66FB663866FF66FF67FFE7FFE61CE6FB661C67DF661CE7FFE0000
+F45A:00007FFE61B66FB663866FF66FF67FFE7FFE61866FB661867DB661B67FFE0000
+F45B:00007FFE61B66FB663866FF66FF67FFE7FFE618E6FB6618E7DB6618E7FFE0000
+F45C:00007FFE61B66FB663866FF66FF67FFE7FFE61C66FBE61BE7DBE61C67FFE0000
+F45D:00007FFE61B66FB663866FF66FF67FFE7FFE618E6FB661B67DB6618E7FFE0000
+F45E:00007FFE61B66FB663866FF66FF67FFE7FFE61866FBE618E7DBE61867FFE0000
+F45F:00007FFE61B66FB663866FF66FF67FFE7FFE61866FBE618E7DBE61BE7FFE0000
+F460:00007FFE61B66FB663866FF66FF67FFE7FFE73CE6FB663B66DB673CE7FFE0000
+F461:00007FFE61B66FB663866FF66FF67FFE7FFE73EE6FCE63EE6DEE73C67FFE0000
+F462:00007FFE61B66FB663866FF66FF67FFE7FFE73866FF663866DBE73867FFE0000
+F463:00007FFE61B66FB663866FF66FF67FFE7FFE738E6FF663C66DF6738E7FFE0000
+F464:00007FFE61B66FB663866FF66FF67FFE7FFE73B66FB663866DF673F67FFE0000
+F465:00007FFE61B66FB663866FF66FF67FFE7FFE73866FBE63866DF673867FFE0000
+F466:00007FFE61B66FB663866FF66FF67FFE7FFE73CE6FBE638E6DB673CE7FFE0000
+F467:00007FFE61B66FB663866FF66FF67FFE7FFE73866FF663EE6DDE73DE7FFE0000
+F468:00007FFE61B66FB663866FF66FF67FFE7FFE73CE6FB663CE6DB673CE7FFE0000
+F469:00007FFE61B66FB663866FF66FF67FFE7FFE73CE6FB663C66DF673CE7FFE0000
+F46A:00007FFE61B66FB663866FF66FF67FFE7FFE73866FB663866DB673B67FFE0000
+F46B:00007FFE61B66FB663866FF66FF67FFE7FFE738E6FB6638E6DB6738E7FFE0000
+F46C:00007FFE61B66FB663866FF66FF67FFE7FFE73C66FBE63BE6DBE73C67FFE0000
+F46D:00007FFE61B66FB663866FF66FF67FFE7FFE738E6FB663B66DB6738E7FFE0000
+F46E:00007FFE61B66FB663866FF66FF67FFE7FFE73866FBE638E6DBE73867FFE0000
+F46F:00007FFE61B66FB663866FF66FF67FFE7FFE73866FBE638E6DBE73BE7FFE0000
+F470:00007FFE61B66FB663866FF66FF67FFE7FFE61CE7DB67BB677B677CE7FFE0000
+F471:00007FFE61B66FB663866FF66FF67FFE7FFE61EE7DCE7BEE77EE77C67FFE0000
+F472:00007FFE61B66FB663866FF66FF67FFE7FFE61867DF67B8677BE77867FFE0000
+F473:00007FFE61B66FB663866FF66FF67FFE7FFE618E7DF67BC677F6778E7FFE0000
+F474:00007FFE61B66FB663866FF66FF67FFE7FFE61B67DB67B8677F677F67FFE0000
+F475:00007FFE61B66FB663866FF66FF67FFE7FFE61867DBE7B8677F677867FFE0000
+F476:00007FFE61B66FB663866FF66FF67FFE7FFE61CE7DBE7B8E77B677CE7FFE0000
+F477:00007FFE61B66FB663866FF66FF67FFE7FFE61867DF67BEE77DE77DE7FFE0000
+F478:00007FFE61B66FB663866FF66FF67FFE7FFE61CE7DB67BCE77B677CE7FFE0000
+F479:00007FFE61B66FB663866FF66FF67FFE7FFE61CE7DB67BC677F677CE7FFE0000
+F47A:00007FFE61B66FB663866FF66FF67FFE7FFE61867DB67B8677B677B67FFE0000
+F47B:00007FFE61B66FB663866FF66FF67FFE7FFE618E7DB67B8E77B6778E7FFE0000
+F47C:00007FFE61B66FB663866FF66FF67FFE7FFE61C67DBE7BBE77BE77C67FFE0000
+F47D:00007FFE61B66FB663866FF66FF67FFE7FFE618E7DB67BB677B6778E7FFE0000
+F47E:00007FFE61B66FB663866FF66FF67FFE7FFE61867DBE7B8E77BE77867FFE0000
+F47F:00007FFE61B66FB663866FF66FF67FFE7FFE61867DBE7B8E77BE77BE7FFE0000
+F480:00007FFE61B66FB663866FF66FF67FFE7FFE73CE6DB673B66DB673CE7FFE0000
+F481:00007FFE61B66FB663866FF66FF67FFE7FFE73EE6DCE73EE6DEE73C67FFE0000
+F482:00007FFE61B66FB663866FF66FF67FFE7FFE73866DF673866DBE73867FFE0000
+F483:00007FFE61B66FB663866FF66FF67FFE7FFE738E6DF673C66DF6738E7FFE0000
+F484:00007FFE61B66FB663866FF66FF67FFE7FFE73B66DB673866DF673F67FFE0000
+F485:00007FFE61B66FB663866FF66FF67FFE7FFE73866DBE73866DF673867FFE0000
+F486:00007FFE61B66FB663866FF66FF67FFE7FFE73CE6DBE738E6DB673CE7FFE0000
+F487:00007FFE61B66FB663866FF66FF67FFE7FFE73866DF673EE6DDE73DE7FFE0000
+F488:00007FFE61B66FB663866FF66FF67FFE7FFE73CE6DB673CE6DB673CE7FFE0000
+F489:00007FFE61B66FB663866FF66FF67FFE7FFE73CE6DB673C66DF673CE7FFE0000
+F48A:00007FFE61B66FB663866FF66FF67FFE7FFE73866DB673866DB673B67FFE0000
+F48B:00007FFE61B66FB663866FF66FF67FFE7FFE738E6DB6738E6DB6738E7FFE0000
+F48C:00007FFE61B66FB663866FF66FF67FFE7FFE73C66DBE73BE6DBE73C67FFE0000
+F48D:00007FFE61B66FB663866FF66FF67FFE7FFE738E6DB673B66DB6738E7FFE0000
+F48E:00007FFE61B66FB663866FF66FF67FFE7FFE73866DBE738E6DBE73867FFE0000
+F48F:00007FFE61B66FB663866FF66FF67FFE7FFE73866DBE738E6DBE73BE7FFE0000
+F490:00007FFE61B66FB663866FF66FF67FFE7FFE73CE6DB671B67DB673CE7FFE0000
+F491:00007FFE61B66FB663866FF66FF67FFE7FFE73EE6DCE71EE7DEE73C67FFE0000
+F492:00007FFE61B66FB663866FF66FF67FFE7FFE73866DF671867DBE73867FFE0000
+F493:00007FFE61B66FB663866FF66FF67FFE7FFE738E6DF671C67DF6738E7FFE0000
+F494:00007FFE61B66FB663866FF66FF67FFE7FFE73B66DB671867DF673F67FFE0000
+F495:00007FFE61B66FB663866FF66FF67FFE7FFE73866DBE71867DF673867FFE0000
+F496:00007FFE61B66FB663866FF66FF67FFE7FFE73CE6DBE718E7DB673CE7FFE0000
+F497:00007FFE61B66FB663866FF66FF67FFE7FFE73866DF671EE7DDE73DE7FFE0000
+F498:00007FFE61B66FB663866FF66FF67FFE7FFE73CE6DB671CE7DB673CE7FFE0000
+F499:00007FFE61B66FB663866FF66FF67FFE7FFE73CE6DB671C67DF673CE7FFE0000
+F49A:00007FFE61B66FB663866FF66FF67FFE7FFE73866DB671867DB673B67FFE0000
+F49B:00007FFE61B66FB663866FF66FF67FFE7FFE738E6DB6718E7DB6738E7FFE0000
+F49C:00007FFE61B66FB663866FF66FF67FFE7FFE73C66DBE71BE7DBE73C67FFE0000
+F49D:00007FFE61B66FB663866FF66FF67FFE7FFE738E6DB671B67DB6738E7FFE0000
+F49E:00007FFE61B66FB663866FF66FF67FFE7FFE73866DBE718E7DBE73867FFE0000
+F49F:00007FFE61B66FB663866FF66FF67FFE7FFE73866DBE718E7DBE73BE7FFE0000
+F4A0:00007FFE61B66FB663866FF66FF67FFE7FFE61CE6DB661B66DB66DCE7FFE0000
+F4A1:00007FFE61B66FB663866FF66FF67FFE7FFE61EE6DCE61EE6DEE6DC67FFE0000
+F4A2:00007FFE61B66FB663866FF66FF67FFE7FFE61866DF661866DBE6D867FFE0000
+F4A3:00007FFE61B66FB663866FF66FF67FFE7FFE618E6DF661C66DF66D8E7FFE0000
+F4A4:00007FFE61B66FB663866FF66FF67FFE7FFE61B66DB661866DF66DF67FFE0000
+F4A5:00007FFE61B66FB663866FF66FF67FFE7FFE61866DBE61866DF66D867FFE0000
+F4A6:00007FFE61B66FB663866FF66FF67FFE7FFE61CE6DBE618E6DB66DCE7FFE0000
+F4A7:00007FFE61B66FB663866FF66FF67FFE7FFE61866DF661EE6DDE6DDE7FFE0000
+F4A8:00007FFE61B66FB663866FF66FF67FFE7FFE61CE6DB661CE6DB66DCE7FFE0000
+F4A9:00007FFE61B66FB663866FF66FF67FFE7FFE61CE6DB661C66DF66DCE7FFE0000
+F4AA:00007FFE61B66FB663866FF66FF67FFE7FFE61866DB661866DB66DB67FFE0000
+F4AB:00007FFE61B66FB663866FF66FF67FFE7FFE618E6DB6618E6DB66D8E7FFE0000
+F4AC:00007FFE61B66FB663866FF66FF67FFE7FFE61C66DBE61BE6DBE6DC67FFE0000
+F4AD:00007FFE61B66FB663866FF66FF67FFE7FFE618E6DB661B66DB66D8E7FFE0000
+F4AE:00007FFE61B66FB663866FF66FF67FFE7FFE61866DBE618E6DBE6D867FFE0000
+F4AF:00007FFE61B66FB663866FF66FF67FFE7FFE61866DBE618E6DBE6DBE7FFE0000
+F4B0:00007FFE61B66FB663866FF66FF67FFE7FFE63CE6DB663B66DB663CE7FFE0000
+F4B1:00007FFE61B66FB663866FF66FF67FFE7FFE63EE6DCE63EE6DEE63C67FFE0000
+F4B2:00007FFE61B66FB663866FF66FF67FFE7FFE63866DF663866DBE63867FFE0000
+F4B3:00007FFE61B66FB663866FF66FF67FFE7FFE638E6DF663C66DF6638E7FFE0000
+F4B4:00007FFE61B66FB663866FF66FF67FFE7FFE63B66DB663866DF663F67FFE0000
+F4B5:00007FFE61B66FB663866FF66FF67FFE7FFE63866DBE63866DF663867FFE0000
+F4B6:00007FFE61B66FB663866FF66FF67FFE7FFE63CE6DBE638E6DB663CE7FFE0000
+F4B7:00007FFE61B66FB663866FF66FF67FFE7FFE63866DF663EE6DDE63DE7FFE0000
+F4B8:00007FFE61B66FB663866FF66FF67FFE7FFE63CE6DB663CE6DB663CE7FFE0000
+F4B9:00007FFE61B66FB663866FF66FF67FFE7FFE63CE6DB663C66DF663CE7FFE0000
+F4BA:00007FFE61B66FB663866FF66FF67FFE7FFE63866DB663866DB663B67FFE0000
+F4BB:00007FFE61B66FB663866FF66FF67FFE7FFE638E6DB6638E6DB6638E7FFE0000
+F4BC:00007FFE61B66FB663866FF66FF67FFE7FFE63C66DBE63BE6DBE63C67FFE0000
+F4BD:00007FFE61B66FB663866FF66FF67FFE7FFE638E6DB663B66DB6638E7FFE0000
+F4BE:00007FFE61B66FB663866FF66FF67FFE7FFE63866DBE638E6DBE63867FFE0000
+F4BF:00007FFE61B66FB663866FF66FF67FFE7FFE63866DBE638E6DBE63BE7FFE0000
+F4C0:00007FFE61B66FB663866FF66FF67FFE7FFE71CE6FB66FB66FB671CE7FFE0000
+F4C1:00007FFE61B66FB663866FF66FF67FFE7FFE71EE6FCE6FEE6FEE71C67FFE0000
+F4C2:00007FFE61B66FB663866FF66FF67FFE7FFE71866FF66F866FBE71867FFE0000
+F4C3:00007FFE61B66FB663866FF66FF67FFE7FFE718E6FF66FC66FF6718E7FFE0000
+F4C4:00007FFE61B66FB663866FF66FF67FFE7FFE71B66FB66F866FF671F67FFE0000
+F4C5:00007FFE61B66FB663866FF66FF67FFE7FFE71866FBE6F866FF671867FFE0000
+F4C6:00007FFE61B66FB663866FF66FF67FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000
+F4C7:00007FFE61B66FB663866FF66FF67FFE7FFE71866FF66FEE6FDE71DE7FFE0000
+F4C8:00007FFE61B66FB663866FF66FF67FFE7FFE71CE6FB66FCE6FB671CE7FFE0000
+F4C9:00007FFE61B66FB663866FF66FF67FFE7FFE71CE6FB66FC66FF671CE7FFE0000
+F4CA:00007FFE61B66FB663866FF66FF67FFE7FFE71866FB66F866FB671B67FFE0000
+F4CB:00007FFE61B66FB663866FF66FF67FFE7FFE718E6FB66F8E6FB6718E7FFE0000
+F4CC:00007FFE61B66FB663866FF66FF67FFE7FFE71C66FBE6FBE6FBE71C67FFE0000
+F4CD:00007FFE61B66FB663866FF66FF67FFE7FFE718E6FB66FB66FB6718E7FFE0000
+F4CE:00007FFE61B66FB663866FF66FF67FFE7FFE71866FBE6F8E6FBE71867FFE0000
+F4CF:00007FFE61B66FB663866FF66FF67FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+F4D0:00007FFE61B66FB663866FF66FF67FFE7FFE63CE6DB66DB66DB663CE7FFE0000
+F4D1:00007FFE61B66FB663866FF66FF67FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000
+F4D2:00007FFE61B66FB663866FF66FF67FFE7FFE63866DF66D866DBE63867FFE0000
+F4D3:00007FFE61B66FB663866FF66FF67FFE7FFE638E6DF66DC66DF6638E7FFE0000
+F4D4:00007FFE61B66FB663866FF66FF67FFE7FFE63B66DB66D866DF663F67FFE0000
+F4D5:00007FFE61B66FB663866FF66FF67FFE7FFE63866DBE6D866DF663867FFE0000
+F4D6:00007FFE61B66FB663866FF66FF67FFE7FFE63CE6DBE6D8E6DB663CE7FFE0000
+F4D7:00007FFE61B66FB663866FF66FF67FFE7FFE63866DF66DEE6DDE63DE7FFE0000
+F4D8:00007FFE61B66FB663866FF66FF67FFE7FFE63CE6DB66DCE6DB663CE7FFE0000
+F4D9:00007FFE61B66FB663866FF66FF67FFE7FFE63CE6DB66DC66DF663CE7FFE0000
+F4DA:00007FFE61B66FB663866FF66FF67FFE7FFE63866DB66D866DB663B67FFE0000
+F4DB:00007FFE61B66FB663866FF66FF67FFE7FFE638E6DB66D8E6DB6638E7FFE0000
+F4DC:00007FFE61B66FB663866FF66FF67FFE7FFE63C66DBE6DBE6DBE63C67FFE0000
+F4DD:00007FFE61B66FB663866FF66FF67FFE7FFE638E6DB66DB66DB6638E7FFE0000
+F4DE:00007FFE61B66FB663866FF66FF67FFE7FFE63866DBE6D8E6DBE63867FFE0000
+F4DF:00007FFE61B66FB663866FF66FF67FFE7FFE63866DBE6D8E6DBE63BE7FFE0000
+F4E0:00007FFE61B66FB663866FF66FF67FFE7FFE61CE6FB663B66FB661CE7FFE0000
+F4E1:00007FFE61B66FB663866FF66FF67FFE7FFE61EE6FCE63EE6FEE61C67FFE0000
+F4E2:00007FFE61B66FB663866FF66FF67FFE7FFE61866FF663866FBE61867FFE0000
+F4E3:00007FFE61B66FB663866FF66FF67FFE7FFE618E6FF663C66FF6618E7FFE0000
+F4E4:00007FFE61B66FB663866FF66FF67FFE7FFE61B66FB663866FF661F67FFE0000
+F4E5:00007FFE61B66FB663866FF66FF67FFE7FFE61866FBE63866FF661867FFE0000
+F4E6:00007FFE61B66FB663866FF66FF67FFE7FFE61CE6FBE638E6FB661CE7FFE0000
+F4E7:00007FFE61B66FB663866FF66FF67FFE7FFE61866FF663EE6FDE61DE7FFE0000
+F4E8:00007FFE61B66FB663866FF66FF67FFE7FFE61CE6FB663CE6FB661CE7FFE0000
+F4E9:00007FFE61B66FB663866FF66FF67FFE7FFE61CE6FB663C66FF661CE7FFE0000
+F4EA:00007FFE61B66FB663866FF66FF67FFE7FFE61866FB663866FB661B67FFE0000
+F4EB:00007FFE61B66FB663866FF66FF67FFE7FFE618E6FB6638E6FB6618E7FFE0000
+F4EC:00007FFE61B66FB663866FF66FF67FFE7FFE61C66FBE63BE6FBE61C67FFE0000
+F4ED:00007FFE61B66FB663866FF66FF67FFE7FFE618E6FB663B66FB6618E7FFE0000
+F4EE:00007FFE61B66FB663866FF66FF67FFE7FFE61866FBE638E6FBE61867FFE0000
+F4EF:00007FFE61B66FB663866FF66FF67FFE7FFE61866FBE638E6FBE61BE7FFE0000
+F4F0:00007FFE61B66FB663866FF66FF67FFE7FFE61CE6FB663B66FB66FCE7FFE0000
+F4F1:00007FFE61B66FB663866FF66FF67FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000
+F4F2:00007FFE61B66FB663866FF66FF67FFE7FFE61866FF663866FBE6F867FFE0000
+F4F3:00007FFE61B66FB663866FF66FF67FFE7FFE618E6FF663C66FF66F8E7FFE0000
+F4F4:00007FFE61B66FB663866FF66FF67FFE7FFE61B66FB663866FF66FF67FFE0000
+F4F5:00007FFE61B66FB663866FF66FF67FFE7FFE61866FBE63866FF66F867FFE0000
+F4F6:00007FFE61B66FB663866FF66FF67FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+F4F7:00007FFE61B66FB663866FF66FF67FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+F4F8:00007FFE61B66FB663866FF66FF67FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+F4F9:00007FFE61B66FB663866FF66FF67FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+F4FA:00007FFE61B66FB663866FF66FF67FFE7FFE61866FB663866FB66FB67FFE0000
+F4FB:00007FFE61B66FB663866FF66FF67FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+F4FC:00007FFE61B66FB663866FF66FF67FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+F4FD:00007FFE61B66FB663866FF66FF67FFE7FFE618E6FB663B66FB66F8E7FFE0000
+F4FE:00007FFE61B66FB663866FF66FF67FFE7FFE61866FBE638E6FBE6F867FFE0000
+F4FF:00007FFE61B66FB663866FF66FF67FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+F500:00007FFE61866FBE63866FF66F867FFE7FFE73CE6DB66DB66DB673CE7FFE0000
+F501:00007FFE61866FBE63866FF66F867FFE7FFE73EE6DCE6DEE6DEE73C67FFE0000
+F502:00007FFE61866FBE63866FF66F867FFE7FFE73866DF66D866DBE73867FFE0000
+F503:00007FFE61866FBE63866FF66F867FFE7FFE738E6DF66DC66DF6738E7FFE0000
+F504:00007FFE61866FBE63866FF66F867FFE7FFE73B66DB66D866DF673F67FFE0000
+F505:00007FFE61866FBE63866FF66F867FFE7FFE73866DBE6D866DF673867FFE0000
+F506:00007FFE61866FBE63866FF66F867FFE7FFE73CE6DBE6D8E6DB673CE7FFE0000
+F507:00007FFE61866FBE63866FF66F867FFE7FFE73866DF66DEE6DDE73DE7FFE0000
+F508:00007FFE61866FBE63866FF66F867FFE7FFE73CE6DB66DCE6DB673CE7FFE0000
+F509:00007FFE61866FBE63866FF66F867FFE7FFE73CE6DB66DC66DF673CE7FFE0000
+F50A:00007FFE61866FBE63866FF66F867FFE7FFE73866DB66D866DB673B67FFE0000
+F50B:00007FFE61866FBE63866FF66F867FFE7FFE738E6DB66D8E6DB6738E7FFE0000
+F50C:00007FFE61866FBE63866FF66F867FFE7FFE73C66DBE6DBE6DBE73C67FFE0000
+F50D:00007FFE61866FBE63866FF66F867FFE7FFE738E6DB66DB66DB6738E7FFE0000
+F50E:00007FFE61866FBE63866FF66F867FFE7FFE73866DBE6D8E6DBE73867FFE0000
+F50F:00007FFE61866FBE63866FF66F867FFE7FFE73866DBE6D8E6DBE73BE7FFE0000
+F510:00007FFE61866FBE63866FF66F867FFE7FFE7BCE73B67BB67BB671CE7FFE0000
+F511:00007FFE61866FBE63866FF66F867FFE7FFE7BEE73CE7BEE7BEE71C67FFE0000
+F512:00007FFE61866FBE63866FF66F867FFE7FFE7B8673F67B867BBE71867FFE0000
+F513:00007FFE61866FBE63866FF66F867FFE7FFE7B8E73F67BC67BF6718E7FFE0000
+F514:00007FFE61866FBE63866FF66F867FFE7FFE7BB673B67B867BF671F67FFE0000
+F515:00007FFE61866FBE63866FF66F867FFE7FFE7B8673BE7B867BF671867FFE0000
+F516:00007FFE61866FBE63866FF66F867FFE7FFE7BCE73BE7B8E7BB671CE7FFE0000
+F517:00007FFE61866FBE63866FF66F867FFE7FFE7B8673F67BEE7BDE71DE7FFE0000
+F518:00007FFE61866FBE63866FF66F867FFE7FFE7BCE73B67BCE7BB671CE7FFE0000
+F519:00007FFE61866FBE63866FF66F867FFE7FFE7BCE73B67BC67BF671CE7FFE0000
+F51A:00007FFE61866FBE63866FF66F867FFE7FFE7B8673B67B867BB671B67FFE0000
+F51B:00007FFE61866FBE63866FF66F867FFE7FFE7B8E73B67B8E7BB6718E7FFE0000
+F51C:00007FFE61866FBE63866FF66F867FFE7FFE7BC673BE7BBE7BBE71C67FFE0000
+F51D:00007FFE61866FBE63866FF66F867FFE7FFE7B8E73B67BB67BB6718E7FFE0000
+F51E:00007FFE61866FBE63866FF66F867FFE7FFE7B8673BE7B8E7BBE71867FFE0000
+F51F:00007FFE61866FBE63866FF66F867FFE7FFE7B8673BE7B8E7BBE71BE7FFE0000
+F520:00007FFE61866FBE63866FF66F867FFE7FFE61CE7DB661B66FB661CE7FFE0000
+F521:00007FFE61866FBE63866FF66F867FFE7FFE61EE7DCE61EE6FEE61C67FFE0000
+F522:00007FFE61866FBE63866FF66F867FFE7FFE61867DF661866FBE61867FFE0000
+F523:00007FFE61866FBE63866FF66F867FFE7FFE618E7DF661C66FF6618E7FFE0000
+F524:00007FFE61866FBE63866FF66F867FFE7FFE61B67DB661866FF661F67FFE0000
+F525:00007FFE61866FBE63866FF66F867FFE7FFE61867DBE61866FF661867FFE0000
+F526:00007FFE61866FBE63866FF66F867FFE7FFE61CE7DBE618E6FB661CE7FFE0000
+F527:00007FFE61866FBE63866FF66F867FFE7FFE61867DF661EE6FDE61DE7FFE0000
+F528:00007FFE61866FBE63866FF66F867FFE7FFE61CE7DB661CE6FB661CE7FFE0000
+F529:00007FFE61866FBE63866FF66F867FFE7FFE61CE7DB661C66FF661CE7FFE0000
+F52A:00007FFE61866FBE63866FF66F867FFE7FFE61867DB661866FB661B67FFE0000
+F52B:00007FFE61866FBE63866FF66F867FFE7FFE618E7DB6618E6FB6618E7FFE0000
+F52C:00007FFE61866FBE63866FF66F867FFE7FFE61C67DBE61BE6FBE61C67FFE0000
+F52D:00007FFE61866FBE63866FF66F867FFE7FFE618E7DB661B66FB6618E7FFE0000
+F52E:00007FFE61866FBE63866FF66F867FFE7FFE61867DBE618E6FBE61867FFE0000
+F52F:00007FFE61866FBE63866FF66F867FFE7FFE61867DBE618E6FBE61BE7FFE0000
+F530:00007FFE61866FBE63866FF66F867FFE7FFE63CE7DB671B67DB663CE7FFE0000
+F531:00007FFE61866FBE63866FF66F867FFE7FFE63EE7DCE71EE7DEE63C67FFE0000
+F532:00007FFE61866FBE63866FF66F867FFE7FFE63867DF671867DBE63867FFE0000
+F533:00007FFE61866FBE63866FF66F867FFE7FFE638E7DF671C67DF6638E7FFE0000
+F534:00007FFE61866FBE63866FF66F867FFE7FFE63B67DB671867DF663F67FFE0000
+F535:00007FFE61866FBE63866FF66F867FFE7FFE63867DBE71867DF663867FFE0000
+F536:00007FFE61866FBE63866FF66F867FFE7FFE63CE7DBE718E7DB663CE7FFE0000
+F537:00007FFE61866FBE63866FF66F867FFE7FFE63867DF671EE7DDE63DE7FFE0000
+F538:00007FFE61866FBE63866FF66F867FFE7FFE63CE7DB671CE7DB663CE7FFE0000
+F539:00007FFE61866FBE63866FF66F867FFE7FFE63CE7DB671C67DF663CE7FFE0000
+F53A:00007FFE61866FBE63866FF66F867FFE7FFE63867DB671867DB663B67FFE0000
+F53B:00007FFE61866FBE63866FF66F867FFE7FFE638E7DB6718E7DB6638E7FFE0000
+F53C:00007FFE61866FBE63866FF66F867FFE7FFE63C67DBE71BE7DBE63C67FFE0000
+F53D:00007FFE61866FBE63866FF66F867FFE7FFE638E7DB671B67DB6638E7FFE0000
+F53E:00007FFE61866FBE63866FF66F867FFE7FFE63867DBE718E7DBE63867FFE0000
+F53F:00007FFE61866FBE63866FF66F867FFE7FFE63867DBE718E7DBE63BE7FFE0000
+F540:00007FFE61866FBE63866FF66F867FFE7FFE6DCE6DB661B67DB67DCE7FFE0000
+F541:00007FFE61866FBE63866FF66F867FFE7FFE6DEE6DCE61EE7DEE7DC67FFE0000
+F542:00007FFE61866FBE63866FF66F867FFE7FFE6D866DF661867DBE7D867FFE0000
+F543:00007FFE61866FBE63866FF66F867FFE7FFE6D8E6DF661C67DF67D8E7FFE0000
+F544:00007FFE61866FBE63866FF66F867FFE7FFE6DB66DB661867DF67DF67FFE0000
+F545:00007FFE61866FBE63866FF66F867FFE7FFE6D866DBE61867DF67D867FFE0000
+F546:00007FFE61866FBE63866FF66F867FFE7FFE6DCE6DBE618E7DB67DCE7FFE0000
+F547:00007FFE61866FBE63866FF66F867FFE7FFE6D866DF661EE7DDE7DDE7FFE0000
+F548:00007FFE61866FBE63866FF66F867FFE7FFE6DCE6DB661CE7DB67DCE7FFE0000
+F549:00007FFE61866FBE63866FF66F867FFE7FFE6DCE6DB661C67DF67DCE7FFE0000
+F54A:00007FFE61866FBE63866FF66F867FFE7FFE6D866DB661867DB67DB67FFE0000
+F54B:00007FFE61866FBE63866FF66F867FFE7FFE6D8E6DB6618E7DB67D8E7FFE0000
+F54C:00007FFE61866FBE63866FF66F867FFE7FFE6DC66DBE61BE7DBE7DC67FFE0000
+F54D:00007FFE61866FBE63866FF66F867FFE7FFE6D8E6DB661B67DB67D8E7FFE0000
+F54E:00007FFE61866FBE63866FF66F867FFE7FFE6D866DBE618E7DBE7D867FFE0000
+F54F:00007FFE61866FBE63866FF66F867FFE7FFE6D866DBE618E7DBE7DBE7FFE0000
+F550:00007FFE61866FBE63866FF66F867FFE7FFE61CE6FB661B67DB661CE7FFE0000
+F551:00007FFE61866FBE63866FF66F867FFE7FFE61EE6FCE61EE7DEE61C67FFE0000
+F552:00007FFE61866FBE63866FF66F867FFE7FFE61866FF661867DBE61867FFE0000
+F553:00007FFE61866FBE63866FF66F867FFE7FFE618E6FF661C67DF6618E7FFE0000
+F554:00007FFE61866FBE63866FF66F867FFE7FFE61B66FB661867DF661F67FFE0000
+F555:00007FFE61866FBE63866FF66F867FFE7FFE61866FBE61867DF661867FFE0000
+F556:00007FFE61866FBE63866FF66F867FFE7FFE61CE6FBE618E7DB661CE7FFE0000
+F557:00007FFE61866FBE63866FF66F867FFE7FFE61866FF661EE7DDE61DE7FFE0000
+F558:00007FFE61866FBE63866FF66F867FFE7FFE61CE6FB661CE7DB661CE7FFE0000
+F559:00007FFE61866FBE63866FF66F867FFE7FFE61CE6FB661C67DF661CE7FFE0000
+F55A:00007FFE61866FBE63866FF66F867FFE7FFE61866FB661867DB661B67FFE0000
+F55B:00007FFE61866FBE63866FF66F867FFE7FFE618E6FB6618E7DB6618E7FFE0000
+F55C:00007FFE61866FBE63866FF66F867FFE7FFE61C66FBE61BE7DBE61C67FFE0000
+F55D:00007FFE61866FBE63866FF66F867FFE7FFE618E6FB661B67DB6618E7FFE0000
+F55E:00007FFE61866FBE63866FF66F867FFE7FFE61866FBE618E7DBE61867FFE0000
+F55F:00007FFE61866FBE63866FF66F867FFE7FFE61866FBE618E7DBE61BE7FFE0000
+F560:00007FFE61866FBE63866FF66F867FFE7FFE73CE6FB663B66DB673CE7FFE0000
+F561:00007FFE61866FBE63866FF66F867FFE7FFE73EE6FCE63EE6DEE73C67FFE0000
+F562:00007FFE61866FBE63866FF66F867FFE7FFE73866FF663866DBE73867FFE0000
+F563:00007FFE61866FBE63866FF66F867FFE7FFE738E6FF663C66DF6738E7FFE0000
+F564:00007FFE61866FBE63866FF66F867FFE7FFE73B66FB663866DF673F67FFE0000
+F565:00007FFE61866FBE63866FF66F867FFE7FFE73866FBE63866DF673867FFE0000
+F566:00007FFE61866FBE63866FF66F867FFE7FFE73CE6FBE638E6DB673CE7FFE0000
+F567:00007FFE61866FBE63866FF66F867FFE7FFE73866FF663EE6DDE73DE7FFE0000
+F568:00007FFE61866FBE63866FF66F867FFE7FFE73CE6FB663CE6DB673CE7FFE0000
+F569:00007FFE61866FBE63866FF66F867FFE7FFE73CE6FB663C66DF673CE7FFE0000
+F56A:00007FFE61866FBE63866FF66F867FFE7FFE73866FB663866DB673B67FFE0000
+F56B:00007FFE61866FBE63866FF66F867FFE7FFE738E6FB6638E6DB6738E7FFE0000
+F56C:00007FFE61866FBE63866FF66F867FFE7FFE73C66FBE63BE6DBE73C67FFE0000
+F56D:00007FFE61866FBE63866FF66F867FFE7FFE738E6FB663B66DB6738E7FFE0000
+F56E:00007FFE61866FBE63866FF66F867FFE7FFE73866FBE638E6DBE73867FFE0000
+F56F:00007FFE61866FBE63866FF66F867FFE7FFE73866FBE638E6DBE73BE7FFE0000
+F570:00007FFE61866FBE63866FF66F867FFE7FFE61CE7DB67BB677B677CE7FFE0000
+F571:00007FFE61866FBE63866FF66F867FFE7FFE61EE7DCE7BEE77EE77C67FFE0000
+F572:00007FFE61866FBE63866FF66F867FFE7FFE61867DF67B8677BE77867FFE0000
+F573:00007FFE61866FBE63866FF66F867FFE7FFE618E7DF67BC677F6778E7FFE0000
+F574:00007FFE61866FBE63866FF66F867FFE7FFE61B67DB67B8677F677F67FFE0000
+F575:00007FFE61866FBE63866FF66F867FFE7FFE61867DBE7B8677F677867FFE0000
+F576:00007FFE61866FBE63866FF66F867FFE7FFE61CE7DBE7B8E77B677CE7FFE0000
+F577:00007FFE61866FBE63866FF66F867FFE7FFE61867DF67BEE77DE77DE7FFE0000
+F578:00007FFE61866FBE63866FF66F867FFE7FFE61CE7DB67BCE77B677CE7FFE0000
+F579:00007FFE61866FBE63866FF66F867FFE7FFE61CE7DB67BC677F677CE7FFE0000
+F57A:00007FFE61866FBE63866FF66F867FFE7FFE61867DB67B8677B677B67FFE0000
+F57B:00007FFE61866FBE63866FF66F867FFE7FFE618E7DB67B8E77B6778E7FFE0000
+F57C:00007FFE61866FBE63866FF66F867FFE7FFE61C67DBE7BBE77BE77C67FFE0000
+F57D:00007FFE61866FBE63866FF66F867FFE7FFE618E7DB67BB677B6778E7FFE0000
+F57E:00007FFE61866FBE63866FF66F867FFE7FFE61867DBE7B8E77BE77867FFE0000
+F57F:00007FFE61866FBE63866FF66F867FFE7FFE61867DBE7B8E77BE77BE7FFE0000
+F580:00007FFE61866FBE63866FF66F867FFE7FFE73CE6DB673B66DB673CE7FFE0000
+F581:00007FFE61866FBE63866FF66F867FFE7FFE73EE6DCE73EE6DEE73C67FFE0000
+F582:00007FFE61866FBE63866FF66F867FFE7FFE73866DF673866DBE73867FFE0000
+F583:00007FFE61866FBE63866FF66F867FFE7FFE738E6DF673C66DF6738E7FFE0000
+F584:00007FFE61866FBE63866FF66F867FFE7FFE73B66DB673866DF673F67FFE0000
+F585:00007FFE61866FBE63866FF66F867FFE7FFE73866DBE73866DF673867FFE0000
+F586:00007FFE61866FBE63866FF66F867FFE7FFE73CE6DBE738E6DB673CE7FFE0000
+F587:00007FFE61866FBE63866FF66F867FFE7FFE73866DF673EE6DDE73DE7FFE0000
+F588:00007FFE61866FBE63866FF66F867FFE7FFE73CE6DB673CE6DB673CE7FFE0000
+F589:00007FFE61866FBE63866FF66F867FFE7FFE73CE6DB673C66DF673CE7FFE0000
+F58A:00007FFE61866FBE63866FF66F867FFE7FFE73866DB673866DB673B67FFE0000
+F58B:00007FFE61866FBE63866FF66F867FFE7FFE738E6DB6738E6DB6738E7FFE0000
+F58C:00007FFE61866FBE63866FF66F867FFE7FFE73C66DBE73BE6DBE73C67FFE0000
+F58D:00007FFE61866FBE63866FF66F867FFE7FFE738E6DB673B66DB6738E7FFE0000
+F58E:00007FFE61866FBE63866FF66F867FFE7FFE73866DBE738E6DBE73867FFE0000
+F58F:00007FFE61866FBE63866FF66F867FFE7FFE73866DBE738E6DBE73BE7FFE0000
+F590:00007FFE61866FBE63866FF66F867FFE7FFE73CE6DB671B67DB673CE7FFE0000
+F591:00007FFE61866FBE63866FF66F867FFE7FFE73EE6DCE71EE7DEE73C67FFE0000
+F592:00007FFE61866FBE63866FF66F867FFE7FFE73866DF671867DBE73867FFE0000
+F593:00007FFE61866FBE63866FF66F867FFE7FFE738E6DF671C67DF6738E7FFE0000
+F594:00007FFE61866FBE63866FF66F867FFE7FFE73B66DB671867DF673F67FFE0000
+F595:00007FFE61866FBE63866FF66F867FFE7FFE73866DBE71867DF673867FFE0000
+F596:00007FFE61866FBE63866FF66F867FFE7FFE73CE6DBE718E7DB673CE7FFE0000
+F597:00007FFE61866FBE63866FF66F867FFE7FFE73866DF671EE7DDE73DE7FFE0000
+F598:00007FFE61866FBE63866FF66F867FFE7FFE73CE6DB671CE7DB673CE7FFE0000
+F599:00007FFE61866FBE63866FF66F867FFE7FFE73CE6DB671C67DF673CE7FFE0000
+F59A:00007FFE61866FBE63866FF66F867FFE7FFE73866DB671867DB673B67FFE0000
+F59B:00007FFE61866FBE63866FF66F867FFE7FFE738E6DB6718E7DB6738E7FFE0000
+F59C:00007FFE61866FBE63866FF66F867FFE7FFE73C66DBE71BE7DBE73C67FFE0000
+F59D:00007FFE61866FBE63866FF66F867FFE7FFE738E6DB671B67DB6738E7FFE0000
+F59E:00007FFE61866FBE63866FF66F867FFE7FFE73866DBE718E7DBE73867FFE0000
+F59F:00007FFE61866FBE63866FF66F867FFE7FFE73866DBE718E7DBE73BE7FFE0000
+F5A0:00007FFE61866FBE63866FF66F867FFE7FFE61CE6DB661B66DB66DCE7FFE0000
+F5A1:00007FFE61866FBE63866FF66F867FFE7FFE61EE6DCE61EE6DEE6DC67FFE0000
+F5A2:00007FFE61866FBE63866FF66F867FFE7FFE61866DF661866DBE6D867FFE0000
+F5A3:00007FFE61866FBE63866FF66F867FFE7FFE618E6DF661C66DF66D8E7FFE0000
+F5A4:00007FFE61866FBE63866FF66F867FFE7FFE61B66DB661866DF66DF67FFE0000
+F5A5:00007FFE61866FBE63866FF66F867FFE7FFE61866DBE61866DF66D867FFE0000
+F5A6:00007FFE61866FBE63866FF66F867FFE7FFE61CE6DBE618E6DB66DCE7FFE0000
+F5A7:00007FFE61866FBE63866FF66F867FFE7FFE61866DF661EE6DDE6DDE7FFE0000
+F5A8:00007FFE61866FBE63866FF66F867FFE7FFE61CE6DB661CE6DB66DCE7FFE0000
+F5A9:00007FFE61866FBE63866FF66F867FFE7FFE61CE6DB661C66DF66DCE7FFE0000
+F5AA:00007FFE61866FBE63866FF66F867FFE7FFE61866DB661866DB66DB67FFE0000
+F5AB:00007FFE61866FBE63866FF66F867FFE7FFE618E6DB6618E6DB66D8E7FFE0000
+F5AC:00007FFE61866FBE63866FF66F867FFE7FFE61C66DBE61BE6DBE6DC67FFE0000
+F5AD:00007FFE61866FBE63866FF66F867FFE7FFE618E6DB661B66DB66D8E7FFE0000
+F5AE:00007FFE61866FBE63866FF66F867FFE7FFE61866DBE618E6DBE6D867FFE0000
+F5AF:00007FFE61866FBE63866FF66F867FFE7FFE61866DBE618E6DBE6DBE7FFE0000
+F5B0:00007FFE61866FBE63866FF66F867FFE7FFE63CE6DB663B66DB663CE7FFE0000
+F5B1:00007FFE61866FBE63866FF66F867FFE7FFE63EE6DCE63EE6DEE63C67FFE0000
+F5B2:00007FFE61866FBE63866FF66F867FFE7FFE63866DF663866DBE63867FFE0000
+F5B3:00007FFE61866FBE63866FF66F867FFE7FFE638E6DF663C66DF6638E7FFE0000
+F5B4:00007FFE61866FBE63866FF66F867FFE7FFE63B66DB663866DF663F67FFE0000
+F5B5:00007FFE61866FBE63866FF66F867FFE7FFE63866DBE63866DF663867FFE0000
+F5B6:00007FFE61866FBE63866FF66F867FFE7FFE63CE6DBE638E6DB663CE7FFE0000
+F5B7:00007FFE61866FBE63866FF66F867FFE7FFE63866DF663EE6DDE63DE7FFE0000
+F5B8:00007FFE61866FBE63866FF66F867FFE7FFE63CE6DB663CE6DB663CE7FFE0000
+F5B9:00007FFE61866FBE63866FF66F867FFE7FFE63CE6DB663C66DF663CE7FFE0000
+F5BA:00007FFE61866FBE63866FF66F867FFE7FFE63866DB663866DB663B67FFE0000
+F5BB:00007FFE61866FBE63866FF66F867FFE7FFE638E6DB6638E6DB6638E7FFE0000
+F5BC:00007FFE61866FBE63866FF66F867FFE7FFE63C66DBE63BE6DBE63C67FFE0000
+F5BD:00007FFE61866FBE63866FF66F867FFE7FFE638E6DB663B66DB6638E7FFE0000
+F5BE:00007FFE61866FBE63866FF66F867FFE7FFE63866DBE638E6DBE63867FFE0000
+F5BF:00007FFE61866FBE63866FF66F867FFE7FFE63866DBE638E6DBE63BE7FFE0000
+F5C0:00007FFE61866FBE63866FF66F867FFE7FFE71CE6FB66FB66FB671CE7FFE0000
+F5C1:00007FFE61866FBE63866FF66F867FFE7FFE71EE6FCE6FEE6FEE71C67FFE0000
+F5C2:00007FFE61866FBE63866FF66F867FFE7FFE71866FF66F866FBE71867FFE0000
+F5C3:00007FFE61866FBE63866FF66F867FFE7FFE718E6FF66FC66FF6718E7FFE0000
+F5C4:00007FFE61866FBE63866FF66F867FFE7FFE71B66FB66F866FF671F67FFE0000
+F5C5:00007FFE61866FBE63866FF66F867FFE7FFE71866FBE6F866FF671867FFE0000
+F5C6:00007FFE61866FBE63866FF66F867FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000
+F5C7:00007FFE61866FBE63866FF66F867FFE7FFE71866FF66FEE6FDE71DE7FFE0000
+F5C8:00007FFE61866FBE63866FF66F867FFE7FFE71CE6FB66FCE6FB671CE7FFE0000
+F5C9:00007FFE61866FBE63866FF66F867FFE7FFE71CE6FB66FC66FF671CE7FFE0000
+F5CA:00007FFE61866FBE63866FF66F867FFE7FFE71866FB66F866FB671B67FFE0000
+F5CB:00007FFE61866FBE63866FF66F867FFE7FFE718E6FB66F8E6FB6718E7FFE0000
+F5CC:00007FFE61866FBE63866FF66F867FFE7FFE71C66FBE6FBE6FBE71C67FFE0000
+F5CD:00007FFE61866FBE63866FF66F867FFE7FFE718E6FB66FB66FB6718E7FFE0000
+F5CE:00007FFE61866FBE63866FF66F867FFE7FFE71866FBE6F8E6FBE71867FFE0000
+F5CF:00007FFE61866FBE63866FF66F867FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+F5D0:00007FFE61866FBE63866FF66F867FFE7FFE63CE6DB66DB66DB663CE7FFE0000
+F5D1:00007FFE61866FBE63866FF66F867FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000
+F5D2:00007FFE61866FBE63866FF66F867FFE7FFE63866DF66D866DBE63867FFE0000
+F5D3:00007FFE61866FBE63866FF66F867FFE7FFE638E6DF66DC66DF6638E7FFE0000
+F5D4:00007FFE61866FBE63866FF66F867FFE7FFE63B66DB66D866DF663F67FFE0000
+F5D5:00007FFE61866FBE63866FF66F867FFE7FFE63866DBE6D866DF663867FFE0000
+F5D6:00007FFE61866FBE63866FF66F867FFE7FFE63CE6DBE6D8E6DB663CE7FFE0000
+F5D7:00007FFE61866FBE63866FF66F867FFE7FFE63866DF66DEE6DDE63DE7FFE0000
+F5D8:00007FFE61866FBE63866FF66F867FFE7FFE63CE6DB66DCE6DB663CE7FFE0000
+F5D9:00007FFE61866FBE63866FF66F867FFE7FFE63CE6DB66DC66DF663CE7FFE0000
+F5DA:00007FFE61866FBE63866FF66F867FFE7FFE63866DB66D866DB663B67FFE0000
+F5DB:00007FFE61866FBE63866FF66F867FFE7FFE638E6DB66D8E6DB6638E7FFE0000
+F5DC:00007FFE61866FBE63866FF66F867FFE7FFE63C66DBE6DBE6DBE63C67FFE0000
+F5DD:00007FFE61866FBE63866FF66F867FFE7FFE638E6DB66DB66DB6638E7FFE0000
+F5DE:00007FFE61866FBE63866FF66F867FFE7FFE63866DBE6D8E6DBE63867FFE0000
+F5DF:00007FFE61866FBE63866FF66F867FFE7FFE63866DBE6D8E6DBE63BE7FFE0000
+F5E0:00007FFE61866FBE63866FF66F867FFE7FFE61CE6FB663B66FB661CE7FFE0000
+F5E1:00007FFE61866FBE63866FF66F867FFE7FFE61EE6FCE63EE6FEE61C67FFE0000
+F5E2:00007FFE61866FBE63866FF66F867FFE7FFE61866FF663866FBE61867FFE0000
+F5E3:00007FFE61866FBE63866FF66F867FFE7FFE618E6FF663C66FF6618E7FFE0000
+F5E4:00007FFE61866FBE63866FF66F867FFE7FFE61B66FB663866FF661F67FFE0000
+F5E5:00007FFE61866FBE63866FF66F867FFE7FFE61866FBE63866FF661867FFE0000
+F5E6:00007FFE61866FBE63866FF66F867FFE7FFE61CE6FBE638E6FB661CE7FFE0000
+F5E7:00007FFE61866FBE63866FF66F867FFE7FFE61866FF663EE6FDE61DE7FFE0000
+F5E8:00007FFE61866FBE63866FF66F867FFE7FFE61CE6FB663CE6FB661CE7FFE0000
+F5E9:00007FFE61866FBE63866FF66F867FFE7FFE61CE6FB663C66FF661CE7FFE0000
+F5EA:00007FFE61866FBE63866FF66F867FFE7FFE61866FB663866FB661B67FFE0000
+F5EB:00007FFE61866FBE63866FF66F867FFE7FFE618E6FB6638E6FB6618E7FFE0000
+F5EC:00007FFE61866FBE63866FF66F867FFE7FFE61C66FBE63BE6FBE61C67FFE0000
+F5ED:00007FFE61866FBE63866FF66F867FFE7FFE618E6FB663B66FB6618E7FFE0000
+F5EE:00007FFE61866FBE63866FF66F867FFE7FFE61866FBE638E6FBE61867FFE0000
+F5EF:00007FFE61866FBE63866FF66F867FFE7FFE61866FBE638E6FBE61BE7FFE0000
+F5F0:00007FFE61866FBE63866FF66F867FFE7FFE61CE6FB663B66FB66FCE7FFE0000
+F5F1:00007FFE61866FBE63866FF66F867FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000
+F5F2:00007FFE61866FBE63866FF66F867FFE7FFE61866FF663866FBE6F867FFE0000
+F5F3:00007FFE61866FBE63866FF66F867FFE7FFE618E6FF663C66FF66F8E7FFE0000
+F5F4:00007FFE61866FBE63866FF66F867FFE7FFE61B66FB663866FF66FF67FFE0000
+F5F5:00007FFE61866FBE63866FF66F867FFE7FFE61866FBE63866FF66F867FFE0000
+F5F6:00007FFE61866FBE63866FF66F867FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+F5F7:00007FFE61866FBE63866FF66F867FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+F5F8:00007FFE61866FBE63866FF66F867FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+F5F9:00007FFE61866FBE63866FF66F867FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+F5FA:00007FFE61866FBE63866FF66F867FFE7FFE61866FB663866FB66FB67FFE0000
+F5FB:00007FFE61866FBE63866FF66F867FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+F5FC:00007FFE61866FBE63866FF66F867FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+F5FD:00007FFE61866FBE63866FF66F867FFE7FFE618E6FB663B66FB66F8E7FFE0000
+F5FE:00007FFE61866FBE63866FF66F867FFE7FFE61866FBE638E6FBE6F867FFE0000
+F5FF:00007FFE61866FBE63866FF66F867FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+F600:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73CE6DB66DB66DB673CE7FFE0000
+F601:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73EE6DCE6DEE6DEE73C67FFE0000
+F602:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73866DF66D866DBE73867FFE0000
+F603:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE738E6DF66DC66DF6738E7FFE0000
+F604:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73B66DB66D866DF673F67FFE0000
+F605:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73866DBE6D866DF673867FFE0000
+F606:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73CE6DBE6D8E6DB673CE7FFE0000
+F607:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73866DF66DEE6DDE73DE7FFE0000
+F608:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73CE6DB66DCE6DB673CE7FFE0000
+F609:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73CE6DB66DC66DF673CE7FFE0000
+F60A:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73866DB66D866DB673B67FFE0000
+F60B:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE738E6DB66D8E6DB6738E7FFE0000
+F60C:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73C66DBE6DBE6DBE73C67FFE0000
+F60D:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE738E6DB66DB66DB6738E7FFE0000
+F60E:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73866DBE6D8E6DBE73867FFE0000
+F60F:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73866DBE6D8E6DBE73BE7FFE0000
+F610:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE7BCE73B67BB67BB671CE7FFE0000
+F611:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE7BEE73CE7BEE7BEE71C67FFE0000
+F612:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE7B8673F67B867BBE71867FFE0000
+F613:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE7B8E73F67BC67BF6718E7FFE0000
+F614:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE7BB673B67B867BF671F67FFE0000
+F615:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE7B8673BE7B867BF671867FFE0000
+F616:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE7BCE73BE7B8E7BB671CE7FFE0000
+F617:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE7B8673F67BEE7BDE71DE7FFE0000
+F618:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE7BCE73B67BCE7BB671CE7FFE0000
+F619:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE7BCE73B67BC67BF671CE7FFE0000
+F61A:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE7B8673B67B867BB671B67FFE0000
+F61B:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE7B8E73B67B8E7BB6718E7FFE0000
+F61C:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE7BC673BE7BBE7BBE71C67FFE0000
+F61D:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE7B8E73B67BB67BB6718E7FFE0000
+F61E:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE7B8673BE7B8E7BBE71867FFE0000
+F61F:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE7B8673BE7B8E7BBE71BE7FFE0000
+F620:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61CE7DB661B66FB661CE7FFE0000
+F621:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61EE7DCE61EE6FEE61C67FFE0000
+F622:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61867DF661866FBE61867FFE0000
+F623:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE618E7DF661C66FF6618E7FFE0000
+F624:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61B67DB661866FF661F67FFE0000
+F625:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61867DBE61866FF661867FFE0000
+F626:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61CE7DBE618E6FB661CE7FFE0000
+F627:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61867DF661EE6FDE61DE7FFE0000
+F628:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61CE7DB661CE6FB661CE7FFE0000
+F629:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61CE7DB661C66FF661CE7FFE0000
+F62A:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61867DB661866FB661B67FFE0000
+F62B:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE618E7DB6618E6FB6618E7FFE0000
+F62C:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61C67DBE61BE6FBE61C67FFE0000
+F62D:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE618E7DB661B66FB6618E7FFE0000
+F62E:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61867DBE618E6FBE61867FFE0000
+F62F:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61867DBE618E6FBE61BE7FFE0000
+F630:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE63CE7DB671B67DB663CE7FFE0000
+F631:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE63EE7DCE71EE7DEE63C67FFE0000
+F632:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE63867DF671867DBE63867FFE0000
+F633:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE638E7DF671C67DF6638E7FFE0000
+F634:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE63B67DB671867DF663F67FFE0000
+F635:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE63867DBE71867DF663867FFE0000
+F636:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE63CE7DBE718E7DB663CE7FFE0000
+F637:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE63867DF671EE7DDE63DE7FFE0000
+F638:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE63CE7DB671CE7DB663CE7FFE0000
+F639:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE63CE7DB671C67DF663CE7FFE0000
+F63A:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE63867DB671867DB663B67FFE0000
+F63B:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE638E7DB6718E7DB6638E7FFE0000
+F63C:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE63C67DBE71BE7DBE63C67FFE0000
+F63D:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE638E7DB671B67DB6638E7FFE0000
+F63E:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE63867DBE718E7DBE63867FFE0000
+F63F:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE63867DBE718E7DBE63BE7FFE0000
+F640:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE6DCE6DB661B67DB67DCE7FFE0000
+F641:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE6DEE6DCE61EE7DEE7DC67FFE0000
+F642:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE6D866DF661867DBE7D867FFE0000
+F643:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE6D8E6DF661C67DF67D8E7FFE0000
+F644:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE6DB66DB661867DF67DF67FFE0000
+F645:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE6D866DBE61867DF67D867FFE0000
+F646:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE6DCE6DBE618E7DB67DCE7FFE0000
+F647:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE6D866DF661EE7DDE7DDE7FFE0000
+F648:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE6DCE6DB661CE7DB67DCE7FFE0000
+F649:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE6DCE6DB661C67DF67DCE7FFE0000
+F64A:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE6D866DB661867DB67DB67FFE0000
+F64B:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE6D8E6DB6618E7DB67D8E7FFE0000
+F64C:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE6DC66DBE61BE7DBE7DC67FFE0000
+F64D:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE6D8E6DB661B67DB67D8E7FFE0000
+F64E:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE6D866DBE618E7DBE7D867FFE0000
+F64F:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE6D866DBE618E7DBE7DBE7FFE0000
+F650:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61CE6FB661B67DB661CE7FFE0000
+F651:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61EE6FCE61EE7DEE61C67FFE0000
+F652:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61866FF661867DBE61867FFE0000
+F653:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE618E6FF661C67DF6618E7FFE0000
+F654:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61B66FB661867DF661F67FFE0000
+F655:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61866FBE61867DF661867FFE0000
+F656:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61CE6FBE618E7DB661CE7FFE0000
+F657:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61866FF661EE7DDE61DE7FFE0000
+F658:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61CE6FB661CE7DB661CE7FFE0000
+F659:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61CE6FB661C67DF661CE7FFE0000
+F65A:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61866FB661867DB661B67FFE0000
+F65B:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE618E6FB6618E7DB6618E7FFE0000
+F65C:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61C66FBE61BE7DBE61C67FFE0000
+F65D:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE618E6FB661B67DB6618E7FFE0000
+F65E:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61866FBE618E7DBE61867FFE0000
+F65F:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61866FBE618E7DBE61BE7FFE0000
+F660:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73CE6FB663B66DB673CE7FFE0000
+F661:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73EE6FCE63EE6DEE73C67FFE0000
+F662:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73866FF663866DBE73867FFE0000
+F663:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE738E6FF663C66DF6738E7FFE0000
+F664:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73B66FB663866DF673F67FFE0000
+F665:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73866FBE63866DF673867FFE0000
+F666:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73CE6FBE638E6DB673CE7FFE0000
+F667:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73866FF663EE6DDE73DE7FFE0000
+F668:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73CE6FB663CE6DB673CE7FFE0000
+F669:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73CE6FB663C66DF673CE7FFE0000
+F66A:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73866FB663866DB673B67FFE0000
+F66B:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE738E6FB6638E6DB6738E7FFE0000
+F66C:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73C66FBE63BE6DBE73C67FFE0000
+F66D:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE738E6FB663B66DB6738E7FFE0000
+F66E:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73866FBE638E6DBE73867FFE0000
+F66F:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73866FBE638E6DBE73BE7FFE0000
+F670:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61CE7DB67BB677B677CE7FFE0000
+F671:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61EE7DCE7BEE77EE77C67FFE0000
+F672:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61867DF67B8677BE77867FFE0000
+F673:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE618E7DF67BC677F6778E7FFE0000
+F674:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61B67DB67B8677F677F67FFE0000
+F675:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61867DBE7B8677F677867FFE0000
+F676:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61CE7DBE7B8E77B677CE7FFE0000
+F677:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61867DF67BEE77DE77DE7FFE0000
+F678:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61CE7DB67BCE77B677CE7FFE0000
+F679:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61CE7DB67BC677F677CE7FFE0000
+F67A:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61867DB67B8677B677B67FFE0000
+F67B:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE618E7DB67B8E77B6778E7FFE0000
+F67C:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61C67DBE7BBE77BE77C67FFE0000
+F67D:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE618E7DB67BB677B6778E7FFE0000
+F67E:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61867DBE7B8E77BE77867FFE0000
+F67F:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61867DBE7B8E77BE77BE7FFE0000
+F680:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73CE6DB673B66DB673CE7FFE0000
+F681:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73EE6DCE73EE6DEE73C67FFE0000
+F682:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73866DF673866DBE73867FFE0000
+F683:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE738E6DF673C66DF6738E7FFE0000
+F684:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73B66DB673866DF673F67FFE0000
+F685:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73866DBE73866DF673867FFE0000
+F686:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73CE6DBE738E6DB673CE7FFE0000
+F687:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73866DF673EE6DDE73DE7FFE0000
+F688:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73CE6DB673CE6DB673CE7FFE0000
+F689:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73CE6DB673C66DF673CE7FFE0000
+F68A:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73866DB673866DB673B67FFE0000
+F68B:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE738E6DB6738E6DB6738E7FFE0000
+F68C:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73C66DBE73BE6DBE73C67FFE0000
+F68D:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE738E6DB673B66DB6738E7FFE0000
+F68E:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73866DBE738E6DBE73867FFE0000
+F68F:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73866DBE738E6DBE73BE7FFE0000
+F690:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73CE6DB671B67DB673CE7FFE0000
+F691:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73EE6DCE71EE7DEE73C67FFE0000
+F692:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73866DF671867DBE73867FFE0000
+F693:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE738E6DF671C67DF6738E7FFE0000
+F694:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73B66DB671867DF673F67FFE0000
+F695:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73866DBE71867DF673867FFE0000
+F696:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73CE6DBE718E7DB673CE7FFE0000
+F697:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73866DF671EE7DDE73DE7FFE0000
+F698:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73CE6DB671CE7DB673CE7FFE0000
+F699:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73CE6DB671C67DF673CE7FFE0000
+F69A:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73866DB671867DB673B67FFE0000
+F69B:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE738E6DB6718E7DB6738E7FFE0000
+F69C:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73C66DBE71BE7DBE73C67FFE0000
+F69D:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE738E6DB671B67DB6738E7FFE0000
+F69E:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73866DBE718E7DBE73867FFE0000
+F69F:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE73866DBE718E7DBE73BE7FFE0000
+F6A0:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61CE6DB661B66DB66DCE7FFE0000
+F6A1:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61EE6DCE61EE6DEE6DC67FFE0000
+F6A2:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61866DF661866DBE6D867FFE0000
+F6A3:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE618E6DF661C66DF66D8E7FFE0000
+F6A4:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61B66DB661866DF66DF67FFE0000
+F6A5:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61866DBE61866DF66D867FFE0000
+F6A6:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61CE6DBE618E6DB66DCE7FFE0000
+F6A7:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61866DF661EE6DDE6DDE7FFE0000
+F6A8:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61CE6DB661CE6DB66DCE7FFE0000
+F6A9:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61CE6DB661C66DF66DCE7FFE0000
+F6AA:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61866DB661866DB66DB67FFE0000
+F6AB:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE618E6DB6618E6DB66D8E7FFE0000
+F6AC:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61C66DBE61BE6DBE6DC67FFE0000
+F6AD:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE618E6DB661B66DB66D8E7FFE0000
+F6AE:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61866DBE618E6DBE6D867FFE0000
+F6AF:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61866DBE618E6DBE6DBE7FFE0000
+F6B0:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE63CE6DB663B66DB663CE7FFE0000
+F6B1:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE63EE6DCE63EE6DEE63C67FFE0000
+F6B2:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE63866DF663866DBE63867FFE0000
+F6B3:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE638E6DF663C66DF6638E7FFE0000
+F6B4:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE63B66DB663866DF663F67FFE0000
+F6B5:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE63866DBE63866DF663867FFE0000
+F6B6:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE63CE6DBE638E6DB663CE7FFE0000
+F6B7:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE63866DF663EE6DDE63DE7FFE0000
+F6B8:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE63CE6DB663CE6DB663CE7FFE0000
+F6B9:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE63CE6DB663C66DF663CE7FFE0000
+F6BA:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE63866DB663866DB663B67FFE0000
+F6BB:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE638E6DB6638E6DB6638E7FFE0000
+F6BC:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE63C66DBE63BE6DBE63C67FFE0000
+F6BD:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE638E6DB663B66DB6638E7FFE0000
+F6BE:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE63866DBE638E6DBE63867FFE0000
+F6BF:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE63866DBE638E6DBE63BE7FFE0000
+F6C0:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE71CE6FB66FB66FB671CE7FFE0000
+F6C1:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE71EE6FCE6FEE6FEE71C67FFE0000
+F6C2:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE71866FF66F866FBE71867FFE0000
+F6C3:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE718E6FF66FC66FF6718E7FFE0000
+F6C4:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE71B66FB66F866FF671F67FFE0000
+F6C5:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE71866FBE6F866FF671867FFE0000
+F6C6:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000
+F6C7:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE71866FF66FEE6FDE71DE7FFE0000
+F6C8:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE71CE6FB66FCE6FB671CE7FFE0000
+F6C9:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE71CE6FB66FC66FF671CE7FFE0000
+F6CA:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE71866FB66F866FB671B67FFE0000
+F6CB:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE718E6FB66F8E6FB6718E7FFE0000
+F6CC:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE71C66FBE6FBE6FBE71C67FFE0000
+F6CD:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE718E6FB66FB66FB6718E7FFE0000
+F6CE:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE71866FBE6F8E6FBE71867FFE0000
+F6CF:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+F6D0:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE63CE6DB66DB66DB663CE7FFE0000
+F6D1:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000
+F6D2:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE63866DF66D866DBE63867FFE0000
+F6D3:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE638E6DF66DC66DF6638E7FFE0000
+F6D4:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE63B66DB66D866DF663F67FFE0000
+F6D5:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE63866DBE6D866DF663867FFE0000
+F6D6:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE63CE6DBE6D8E6DB663CE7FFE0000
+F6D7:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE63866DF66DEE6DDE63DE7FFE0000
+F6D8:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE63CE6DB66DCE6DB663CE7FFE0000
+F6D9:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE63CE6DB66DC66DF663CE7FFE0000
+F6DA:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE63866DB66D866DB663B67FFE0000
+F6DB:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE638E6DB66D8E6DB6638E7FFE0000
+F6DC:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE63C66DBE6DBE6DBE63C67FFE0000
+F6DD:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE638E6DB66DB66DB6638E7FFE0000
+F6DE:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE63866DBE6D8E6DBE63867FFE0000
+F6DF:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE63866DBE6D8E6DBE63BE7FFE0000
+F6E0:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61CE6FB663B66FB661CE7FFE0000
+F6E1:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61EE6FCE63EE6FEE61C67FFE0000
+F6E2:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61866FF663866FBE61867FFE0000
+F6E3:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE618E6FF663C66FF6618E7FFE0000
+F6E4:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61B66FB663866FF661F67FFE0000
+F6E5:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61866FBE63866FF661867FFE0000
+F6E6:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61CE6FBE638E6FB661CE7FFE0000
+F6E7:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61866FF663EE6FDE61DE7FFE0000
+F6E8:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61CE6FB663CE6FB661CE7FFE0000
+F6E9:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61CE6FB663C66FF661CE7FFE0000
+F6EA:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61866FB663866FB661B67FFE0000
+F6EB:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE618E6FB6638E6FB6618E7FFE0000
+F6EC:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61C66FBE63BE6FBE61C67FFE0000
+F6ED:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE618E6FB663B66FB6618E7FFE0000
+F6EE:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61866FBE638E6FBE61867FFE0000
+F6EF:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61866FBE638E6FBE61BE7FFE0000
+F6F0:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61CE6FB663B66FB66FCE7FFE0000
+F6F1:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000
+F6F2:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61866FF663866FBE6F867FFE0000
+F6F3:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE618E6FF663C66FF66F8E7FFE0000
+F6F4:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61B66FB663866FF66FF67FFE0000
+F6F5:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61866FBE63866FF66F867FFE0000
+F6F6:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+F6F7:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+F6F8:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+F6F9:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+F6FA:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61866FB663866FB66FB67FFE0000
+F6FB:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+F6FC:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+F6FD:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE618E6FB663B66FB66F8E7FFE0000
+F6FE:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61866FBE638E6FBE6F867FFE0000
+F6FF:00007FFE61CE6FBE638E6FB66FCE7FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+F700:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73CE6DB66DB66DB673CE7FFE0000
+F701:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73EE6DCE6DEE6DEE73C67FFE0000
+F702:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73866DF66D866DBE73867FFE0000
+F703:00007FFE61866FF663EE6FDE6FDE7FFE7FFE738E6DF66DC66DF6738E7FFE0000
+F704:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73B66DB66D866DF673F67FFE0000
+F705:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73866DBE6D866DF673867FFE0000
+F706:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73CE6DBE6D8E6DB673CE7FFE0000
+F707:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73866DF66DEE6DDE73DE7FFE0000
+F708:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73CE6DB66DCE6DB673CE7FFE0000
+F709:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73CE6DB66DC66DF673CE7FFE0000
+F70A:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73866DB66D866DB673B67FFE0000
+F70B:00007FFE61866FF663EE6FDE6FDE7FFE7FFE738E6DB66D8E6DB6738E7FFE0000
+F70C:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73C66DBE6DBE6DBE73C67FFE0000
+F70D:00007FFE61866FF663EE6FDE6FDE7FFE7FFE738E6DB66DB66DB6738E7FFE0000
+F70E:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73866DBE6D8E6DBE73867FFE0000
+F70F:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73866DBE6D8E6DBE73BE7FFE0000
+F710:00007FFE61866FF663EE6FDE6FDE7FFE7FFE7BCE73B67BB67BB671CE7FFE0000
+F711:00007FFE61866FF663EE6FDE6FDE7FFE7FFE7BEE73CE7BEE7BEE71C67FFE0000
+F712:00007FFE61866FF663EE6FDE6FDE7FFE7FFE7B8673F67B867BBE71867FFE0000
+F713:00007FFE61866FF663EE6FDE6FDE7FFE7FFE7B8E73F67BC67BF6718E7FFE0000
+F714:00007FFE61866FF663EE6FDE6FDE7FFE7FFE7BB673B67B867BF671F67FFE0000
+F715:00007FFE61866FF663EE6FDE6FDE7FFE7FFE7B8673BE7B867BF671867FFE0000
+F716:00007FFE61866FF663EE6FDE6FDE7FFE7FFE7BCE73BE7B8E7BB671CE7FFE0000
+F717:00007FFE61866FF663EE6FDE6FDE7FFE7FFE7B8673F67BEE7BDE71DE7FFE0000
+F718:00007FFE61866FF663EE6FDE6FDE7FFE7FFE7BCE73B67BCE7BB671CE7FFE0000
+F719:00007FFE61866FF663EE6FDE6FDE7FFE7FFE7BCE73B67BC67BF671CE7FFE0000
+F71A:00007FFE61866FF663EE6FDE6FDE7FFE7FFE7B8673B67B867BB671B67FFE0000
+F71B:00007FFE61866FF663EE6FDE6FDE7FFE7FFE7B8E73B67B8E7BB6718E7FFE0000
+F71C:00007FFE61866FF663EE6FDE6FDE7FFE7FFE7BC673BE7BBE7BBE71C67FFE0000
+F71D:00007FFE61866FF663EE6FDE6FDE7FFE7FFE7B8E73B67BB67BB6718E7FFE0000
+F71E:00007FFE61866FF663EE6FDE6FDE7FFE7FFE7B8673BE7B8E7BBE71867FFE0000
+F71F:00007FFE61866FF663EE6FDE6FDE7FFE7FFE7B8673BE7B8E7BBE71BE7FFE0000
+F720:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61CE7DB661B66FB661CE7FFE0000
+F721:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61EE7DCE61EE6FEE61C67FFE0000
+F722:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61867DF661866FBE61867FFE0000
+F723:00007FFE61866FF663EE6FDE6FDE7FFE7FFE618E7DF661C66FF6618E7FFE0000
+F724:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61B67DB661866FF661F67FFE0000
+F725:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61867DBE61866FF661867FFE0000
+F726:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61CE7DBE618E6FB661CE7FFE0000
+F727:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61867DF661EE6FDE61DE7FFE0000
+F728:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61CE7DB661CE6FB661CE7FFE0000
+F729:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61CE7DB661C66FF661CE7FFE0000
+F72A:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61867DB661866FB661B67FFE0000
+F72B:00007FFE61866FF663EE6FDE6FDE7FFE7FFE618E7DB6618E6FB6618E7FFE0000
+F72C:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61C67DBE61BE6FBE61C67FFE0000
+F72D:00007FFE61866FF663EE6FDE6FDE7FFE7FFE618E7DB661B66FB6618E7FFE0000
+F72E:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61867DBE618E6FBE61867FFE0000
+F72F:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61867DBE618E6FBE61BE7FFE0000
+F730:00007FFE61866FF663EE6FDE6FDE7FFE7FFE63CE7DB671B67DB663CE7FFE0000
+F731:00007FFE61866FF663EE6FDE6FDE7FFE7FFE63EE7DCE71EE7DEE63C67FFE0000
+F732:00007FFE61866FF663EE6FDE6FDE7FFE7FFE63867DF671867DBE63867FFE0000
+F733:00007FFE61866FF663EE6FDE6FDE7FFE7FFE638E7DF671C67DF6638E7FFE0000
+F734:00007FFE61866FF663EE6FDE6FDE7FFE7FFE63B67DB671867DF663F67FFE0000
+F735:00007FFE61866FF663EE6FDE6FDE7FFE7FFE63867DBE71867DF663867FFE0000
+F736:00007FFE61866FF663EE6FDE6FDE7FFE7FFE63CE7DBE718E7DB663CE7FFE0000
+F737:00007FFE61866FF663EE6FDE6FDE7FFE7FFE63867DF671EE7DDE63DE7FFE0000
+F738:00007FFE61866FF663EE6FDE6FDE7FFE7FFE63CE7DB671CE7DB663CE7FFE0000
+F739:00007FFE61866FF663EE6FDE6FDE7FFE7FFE63CE7DB671C67DF663CE7FFE0000
+F73A:00007FFE61866FF663EE6FDE6FDE7FFE7FFE63867DB671867DB663B67FFE0000
+F73B:00007FFE61866FF663EE6FDE6FDE7FFE7FFE638E7DB6718E7DB6638E7FFE0000
+F73C:00007FFE61866FF663EE6FDE6FDE7FFE7FFE63C67DBE71BE7DBE63C67FFE0000
+F73D:00007FFE61866FF663EE6FDE6FDE7FFE7FFE638E7DB671B67DB6638E7FFE0000
+F73E:00007FFE61866FF663EE6FDE6FDE7FFE7FFE63867DBE718E7DBE63867FFE0000
+F73F:00007FFE61866FF663EE6FDE6FDE7FFE7FFE63867DBE718E7DBE63BE7FFE0000
+F740:00007FFE61866FF663EE6FDE6FDE7FFE7FFE6DCE6DB661B67DB67DCE7FFE0000
+F741:00007FFE61866FF663EE6FDE6FDE7FFE7FFE6DEE6DCE61EE7DEE7DC67FFE0000
+F742:00007FFE61866FF663EE6FDE6FDE7FFE7FFE6D866DF661867DBE7D867FFE0000
+F743:00007FFE61866FF663EE6FDE6FDE7FFE7FFE6D8E6DF661C67DF67D8E7FFE0000
+F744:00007FFE61866FF663EE6FDE6FDE7FFE7FFE6DB66DB661867DF67DF67FFE0000
+F745:00007FFE61866FF663EE6FDE6FDE7FFE7FFE6D866DBE61867DF67D867FFE0000
+F746:00007FFE61866FF663EE6FDE6FDE7FFE7FFE6DCE6DBE618E7DB67DCE7FFE0000
+F747:00007FFE61866FF663EE6FDE6FDE7FFE7FFE6D866DF661EE7DDE7DDE7FFE0000
+F748:00007FFE61866FF663EE6FDE6FDE7FFE7FFE6DCE6DB661CE7DB67DCE7FFE0000
+F749:00007FFE61866FF663EE6FDE6FDE7FFE7FFE6DCE6DB661C67DF67DCE7FFE0000
+F74A:00007FFE61866FF663EE6FDE6FDE7FFE7FFE6D866DB661867DB67DB67FFE0000
+F74B:00007FFE61866FF663EE6FDE6FDE7FFE7FFE6D8E6DB6618E7DB67D8E7FFE0000
+F74C:00007FFE61866FF663EE6FDE6FDE7FFE7FFE6DC66DBE61BE7DBE7DC67FFE0000
+F74D:00007FFE61866FF663EE6FDE6FDE7FFE7FFE6D8E6DB661B67DB67D8E7FFE0000
+F74E:00007FFE61866FF663EE6FDE6FDE7FFE7FFE6D866DBE618E7DBE7D867FFE0000
+F74F:00007FFE61866FF663EE6FDE6FDE7FFE7FFE6D866DBE618E7DBE7DBE7FFE0000
+F750:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61CE6FB661B67DB661CE7FFE0000
+F751:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61EE6FCE61EE7DEE61C67FFE0000
+F752:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61866FF661867DBE61867FFE0000
+F753:00007FFE61866FF663EE6FDE6FDE7FFE7FFE618E6FF661C67DF6618E7FFE0000
+F754:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61B66FB661867DF661F67FFE0000
+F755:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61866FBE61867DF661867FFE0000
+F756:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61CE6FBE618E7DB661CE7FFE0000
+F757:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61866FF661EE7DDE61DE7FFE0000
+F758:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61CE6FB661CE7DB661CE7FFE0000
+F759:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61CE6FB661C67DF661CE7FFE0000
+F75A:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61866FB661867DB661B67FFE0000
+F75B:00007FFE61866FF663EE6FDE6FDE7FFE7FFE618E6FB6618E7DB6618E7FFE0000
+F75C:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61C66FBE61BE7DBE61C67FFE0000
+F75D:00007FFE61866FF663EE6FDE6FDE7FFE7FFE618E6FB661B67DB6618E7FFE0000
+F75E:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61866FBE618E7DBE61867FFE0000
+F75F:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61866FBE618E7DBE61BE7FFE0000
+F760:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73CE6FB663B66DB673CE7FFE0000
+F761:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73EE6FCE63EE6DEE73C67FFE0000
+F762:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73866FF663866DBE73867FFE0000
+F763:00007FFE61866FF663EE6FDE6FDE7FFE7FFE738E6FF663C66DF6738E7FFE0000
+F764:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73B66FB663866DF673F67FFE0000
+F765:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73866FBE63866DF673867FFE0000
+F766:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73CE6FBE638E6DB673CE7FFE0000
+F767:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73866FF663EE6DDE73DE7FFE0000
+F768:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73CE6FB663CE6DB673CE7FFE0000
+F769:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73CE6FB663C66DF673CE7FFE0000
+F76A:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73866FB663866DB673B67FFE0000
+F76B:00007FFE61866FF663EE6FDE6FDE7FFE7FFE738E6FB6638E6DB6738E7FFE0000
+F76C:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73C66FBE63BE6DBE73C67FFE0000
+F76D:00007FFE61866FF663EE6FDE6FDE7FFE7FFE738E6FB663B66DB6738E7FFE0000
+F76E:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73866FBE638E6DBE73867FFE0000
+F76F:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73866FBE638E6DBE73BE7FFE0000
+F770:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61CE7DB67BB677B677CE7FFE0000
+F771:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61EE7DCE7BEE77EE77C67FFE0000
+F772:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61867DF67B8677BE77867FFE0000
+F773:00007FFE61866FF663EE6FDE6FDE7FFE7FFE618E7DF67BC677F6778E7FFE0000
+F774:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61B67DB67B8677F677F67FFE0000
+F775:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61867DBE7B8677F677867FFE0000
+F776:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61CE7DBE7B8E77B677CE7FFE0000
+F777:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61867DF67BEE77DE77DE7FFE0000
+F778:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61CE7DB67BCE77B677CE7FFE0000
+F779:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61CE7DB67BC677F677CE7FFE0000
+F77A:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61867DB67B8677B677B67FFE0000
+F77B:00007FFE61866FF663EE6FDE6FDE7FFE7FFE618E7DB67B8E77B6778E7FFE0000
+F77C:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61C67DBE7BBE77BE77C67FFE0000
+F77D:00007FFE61866FF663EE6FDE6FDE7FFE7FFE618E7DB67BB677B6778E7FFE0000
+F77E:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61867DBE7B8E77BE77867FFE0000
+F77F:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61867DBE7B8E77BE77BE7FFE0000
+F780:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73CE6DB673B66DB673CE7FFE0000
+F781:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73EE6DCE73EE6DEE73C67FFE0000
+F782:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73866DF673866DBE73867FFE0000
+F783:00007FFE61866FF663EE6FDE6FDE7FFE7FFE738E6DF673C66DF6738E7FFE0000
+F784:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73B66DB673866DF673F67FFE0000
+F785:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73866DBE73866DF673867FFE0000
+F786:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73CE6DBE738E6DB673CE7FFE0000
+F787:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73866DF673EE6DDE73DE7FFE0000
+F788:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73CE6DB673CE6DB673CE7FFE0000
+F789:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73CE6DB673C66DF673CE7FFE0000
+F78A:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73866DB673866DB673B67FFE0000
+F78B:00007FFE61866FF663EE6FDE6FDE7FFE7FFE738E6DB6738E6DB6738E7FFE0000
+F78C:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73C66DBE73BE6DBE73C67FFE0000
+F78D:00007FFE61866FF663EE6FDE6FDE7FFE7FFE738E6DB673B66DB6738E7FFE0000
+F78E:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73866DBE738E6DBE73867FFE0000
+F78F:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73866DBE738E6DBE73BE7FFE0000
+F790:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73CE6DB671B67DB673CE7FFE0000
+F791:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73EE6DCE71EE7DEE73C67FFE0000
+F792:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73866DF671867DBE73867FFE0000
+F793:00007FFE61866FF663EE6FDE6FDE7FFE7FFE738E6DF671C67DF6738E7FFE0000
+F794:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73B66DB671867DF673F67FFE0000
+F795:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73866DBE71867DF673867FFE0000
+F796:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73CE6DBE718E7DB673CE7FFE0000
+F797:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73866DF671EE7DDE73DE7FFE0000
+F798:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73CE6DB671CE7DB673CE7FFE0000
+F799:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73CE6DB671C67DF673CE7FFE0000
+F79A:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73866DB671867DB673B67FFE0000
+F79B:00007FFE61866FF663EE6FDE6FDE7FFE7FFE738E6DB6718E7DB6738E7FFE0000
+F79C:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73C66DBE71BE7DBE73C67FFE0000
+F79D:00007FFE61866FF663EE6FDE6FDE7FFE7FFE738E6DB671B67DB6738E7FFE0000
+F79E:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73866DBE718E7DBE73867FFE0000
+F79F:00007FFE61866FF663EE6FDE6FDE7FFE7FFE73866DBE718E7DBE73BE7FFE0000
+F7A0:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61CE6DB661B66DB66DCE7FFE0000
+F7A1:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61EE6DCE61EE6DEE6DC67FFE0000
+F7A2:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61866DF661866DBE6D867FFE0000
+F7A3:00007FFE61866FF663EE6FDE6FDE7FFE7FFE618E6DF661C66DF66D8E7FFE0000
+F7A4:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61B66DB661866DF66DF67FFE0000
+F7A5:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61866DBE61866DF66D867FFE0000
+F7A6:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61CE6DBE618E6DB66DCE7FFE0000
+F7A7:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61866DF661EE6DDE6DDE7FFE0000
+F7A8:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61CE6DB661CE6DB66DCE7FFE0000
+F7A9:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61CE6DB661C66DF66DCE7FFE0000
+F7AA:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61866DB661866DB66DB67FFE0000
+F7AB:00007FFE61866FF663EE6FDE6FDE7FFE7FFE618E6DB6618E6DB66D8E7FFE0000
+F7AC:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61C66DBE61BE6DBE6DC67FFE0000
+F7AD:00007FFE61866FF663EE6FDE6FDE7FFE7FFE618E6DB661B66DB66D8E7FFE0000
+F7AE:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61866DBE618E6DBE6D867FFE0000
+F7AF:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61866DBE618E6DBE6DBE7FFE0000
+F7B0:00007FFE61866FF663EE6FDE6FDE7FFE7FFE63CE6DB663B66DB663CE7FFE0000
+F7B1:00007FFE61866FF663EE6FDE6FDE7FFE7FFE63EE6DCE63EE6DEE63C67FFE0000
+F7B2:00007FFE61866FF663EE6FDE6FDE7FFE7FFE63866DF663866DBE63867FFE0000
+F7B3:00007FFE61866FF663EE6FDE6FDE7FFE7FFE638E6DF663C66DF6638E7FFE0000
+F7B4:00007FFE61866FF663EE6FDE6FDE7FFE7FFE63B66DB663866DF663F67FFE0000
+F7B5:00007FFE61866FF663EE6FDE6FDE7FFE7FFE63866DBE63866DF663867FFE0000
+F7B6:00007FFE61866FF663EE6FDE6FDE7FFE7FFE63CE6DBE638E6DB663CE7FFE0000
+F7B7:00007FFE61866FF663EE6FDE6FDE7FFE7FFE63866DF663EE6DDE63DE7FFE0000
+F7B8:00007FFE61866FF663EE6FDE6FDE7FFE7FFE63CE6DB663CE6DB663CE7FFE0000
+F7B9:00007FFE61866FF663EE6FDE6FDE7FFE7FFE63CE6DB663C66DF663CE7FFE0000
+F7BA:00007FFE61866FF663EE6FDE6FDE7FFE7FFE63866DB663866DB663B67FFE0000
+F7BB:00007FFE61866FF663EE6FDE6FDE7FFE7FFE638E6DB6638E6DB6638E7FFE0000
+F7BC:00007FFE61866FF663EE6FDE6FDE7FFE7FFE63C66DBE63BE6DBE63C67FFE0000
+F7BD:00007FFE61866FF663EE6FDE6FDE7FFE7FFE638E6DB663B66DB6638E7FFE0000
+F7BE:00007FFE61866FF663EE6FDE6FDE7FFE7FFE63866DBE638E6DBE63867FFE0000
+F7BF:00007FFE61866FF663EE6FDE6FDE7FFE7FFE63866DBE638E6DBE63BE7FFE0000
+F7C0:00007FFE61866FF663EE6FDE6FDE7FFE7FFE71CE6FB66FB66FB671CE7FFE0000
+F7C1:00007FFE61866FF663EE6FDE6FDE7FFE7FFE71EE6FCE6FEE6FEE71C67FFE0000
+F7C2:00007FFE61866FF663EE6FDE6FDE7FFE7FFE71866FF66F866FBE71867FFE0000
+F7C3:00007FFE61866FF663EE6FDE6FDE7FFE7FFE718E6FF66FC66FF6718E7FFE0000
+F7C4:00007FFE61866FF663EE6FDE6FDE7FFE7FFE71B66FB66F866FF671F67FFE0000
+F7C5:00007FFE61866FF663EE6FDE6FDE7FFE7FFE71866FBE6F866FF671867FFE0000
+F7C6:00007FFE61866FF663EE6FDE6FDE7FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000
+F7C7:00007FFE61866FF663EE6FDE6FDE7FFE7FFE71866FF66FEE6FDE71DE7FFE0000
+F7C8:00007FFE61866FF663EE6FDE6FDE7FFE7FFE71CE6FB66FCE6FB671CE7FFE0000
+F7C9:00007FFE61866FF663EE6FDE6FDE7FFE7FFE71CE6FB66FC66FF671CE7FFE0000
+F7CA:00007FFE61866FF663EE6FDE6FDE7FFE7FFE71866FB66F866FB671B67FFE0000
+F7CB:00007FFE61866FF663EE6FDE6FDE7FFE7FFE718E6FB66F8E6FB6718E7FFE0000
+F7CC:00007FFE61866FF663EE6FDE6FDE7FFE7FFE71C66FBE6FBE6FBE71C67FFE0000
+F7CD:00007FFE61866FF663EE6FDE6FDE7FFE7FFE718E6FB66FB66FB6718E7FFE0000
+F7CE:00007FFE61866FF663EE6FDE6FDE7FFE7FFE71866FBE6F8E6FBE71867FFE0000
+F7CF:00007FFE61866FF663EE6FDE6FDE7FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+F7D0:00007FFE61866FF663EE6FDE6FDE7FFE7FFE63CE6DB66DB66DB663CE7FFE0000
+F7D1:00007FFE61866FF663EE6FDE6FDE7FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000
+F7D2:00007FFE61866FF663EE6FDE6FDE7FFE7FFE63866DF66D866DBE63867FFE0000
+F7D3:00007FFE61866FF663EE6FDE6FDE7FFE7FFE638E6DF66DC66DF6638E7FFE0000
+F7D4:00007FFE61866FF663EE6FDE6FDE7FFE7FFE63B66DB66D866DF663F67FFE0000
+F7D5:00007FFE61866FF663EE6FDE6FDE7FFE7FFE63866DBE6D866DF663867FFE0000
+F7D6:00007FFE61866FF663EE6FDE6FDE7FFE7FFE63CE6DBE6D8E6DB663CE7FFE0000
+F7D7:00007FFE61866FF663EE6FDE6FDE7FFE7FFE63866DF66DEE6DDE63DE7FFE0000
+F7D8:00007FFE61866FF663EE6FDE6FDE7FFE7FFE63CE6DB66DCE6DB663CE7FFE0000
+F7D9:00007FFE61866FF663EE6FDE6FDE7FFE7FFE63CE6DB66DC66DF663CE7FFE0000
+F7DA:00007FFE61866FF663EE6FDE6FDE7FFE7FFE63866DB66D866DB663B67FFE0000
+F7DB:00007FFE61866FF663EE6FDE6FDE7FFE7FFE638E6DB66D8E6DB6638E7FFE0000
+F7DC:00007FFE61866FF663EE6FDE6FDE7FFE7FFE63C66DBE6DBE6DBE63C67FFE0000
+F7DD:00007FFE61866FF663EE6FDE6FDE7FFE7FFE638E6DB66DB66DB6638E7FFE0000
+F7DE:00007FFE61866FF663EE6FDE6FDE7FFE7FFE63866DBE6D8E6DBE63867FFE0000
+F7DF:00007FFE61866FF663EE6FDE6FDE7FFE7FFE63866DBE6D8E6DBE63BE7FFE0000
+F7E0:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61CE6FB663B66FB661CE7FFE0000
+F7E1:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61EE6FCE63EE6FEE61C67FFE0000
+F7E2:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61866FF663866FBE61867FFE0000
+F7E3:00007FFE61866FF663EE6FDE6FDE7FFE7FFE618E6FF663C66FF6618E7FFE0000
+F7E4:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61B66FB663866FF661F67FFE0000
+F7E5:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61866FBE63866FF661867FFE0000
+F7E6:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61CE6FBE638E6FB661CE7FFE0000
+F7E7:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61866FF663EE6FDE61DE7FFE0000
+F7E8:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61CE6FB663CE6FB661CE7FFE0000
+F7E9:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61CE6FB663C66FF661CE7FFE0000
+F7EA:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61866FB663866FB661B67FFE0000
+F7EB:00007FFE61866FF663EE6FDE6FDE7FFE7FFE618E6FB6638E6FB6618E7FFE0000
+F7EC:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61C66FBE63BE6FBE61C67FFE0000
+F7ED:00007FFE61866FF663EE6FDE6FDE7FFE7FFE618E6FB663B66FB6618E7FFE0000
+F7EE:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61866FBE638E6FBE61867FFE0000
+F7EF:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61866FBE638E6FBE61BE7FFE0000
+F7F0:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61CE6FB663B66FB66FCE7FFE0000
+F7F1:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000
+F7F2:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61866FF663866FBE6F867FFE0000
+F7F3:00007FFE61866FF663EE6FDE6FDE7FFE7FFE618E6FF663C66FF66F8E7FFE0000
+F7F4:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61B66FB663866FF66FF67FFE0000
+F7F5:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61866FBE63866FF66F867FFE0000
+F7F6:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+F7F7:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+F7F8:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+F7F9:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+F7FA:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61866FB663866FB66FB67FFE0000
+F7FB:00007FFE61866FF663EE6FDE6FDE7FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+F7FC:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+F7FD:00007FFE61866FF663EE6FDE6FDE7FFE7FFE618E6FB663B66FB66F8E7FFE0000
+F7FE:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61866FBE638E6FBE6F867FFE0000
+F7FF:00007FFE61866FF663EE6FDE6FDE7FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+F800:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73CE6DB66DB66DB673CE7FFE0000
+F801:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73EE6DCE6DEE6DEE73C67FFE0000
+F802:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73866DF66D866DBE73867FFE0000
+F803:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE738E6DF66DC66DF6738E7FFE0000
+F804:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73B66DB66D866DF673F67FFE0000
+F805:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73866DBE6D866DF673867FFE0000
+F806:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73CE6DBE6D8E6DB673CE7FFE0000
+F807:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73866DF66DEE6DDE73DE7FFE0000
+F808:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73CE6DB66DCE6DB673CE7FFE0000
+F809:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73CE6DB66DC66DF673CE7FFE0000
+F80A:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73866DB66D866DB673B67FFE0000
+F80B:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE738E6DB66D8E6DB6738E7FFE0000
+F80C:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73C66DBE6DBE6DBE73C67FFE0000
+F80D:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE738E6DB66DB66DB6738E7FFE0000
+F80E:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73866DBE6D8E6DBE73867FFE0000
+F80F:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73866DBE6D8E6DBE73BE7FFE0000
+F810:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE7BCE73B67BB67BB671CE7FFE0000
+F811:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE7BEE73CE7BEE7BEE71C67FFE0000
+F812:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE7B8673F67B867BBE71867FFE0000
+F813:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE7B8E73F67BC67BF6718E7FFE0000
+F814:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE7BB673B67B867BF671F67FFE0000
+F815:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE7B8673BE7B867BF671867FFE0000
+F816:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE7BCE73BE7B8E7BB671CE7FFE0000
+F817:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE7B8673F67BEE7BDE71DE7FFE0000
+F818:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE7BCE73B67BCE7BB671CE7FFE0000
+F819:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE7BCE73B67BC67BF671CE7FFE0000
+F81A:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE7B8673B67B867BB671B67FFE0000
+F81B:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE7B8E73B67B8E7BB6718E7FFE0000
+F81C:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE7BC673BE7BBE7BBE71C67FFE0000
+F81D:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE7B8E73B67BB67BB6718E7FFE0000
+F81E:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE7B8673BE7B8E7BBE71867FFE0000
+F81F:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE7B8673BE7B8E7BBE71BE7FFE0000
+F820:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61CE7DB661B66FB661CE7FFE0000
+F821:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61EE7DCE61EE6FEE61C67FFE0000
+F822:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61867DF661866FBE61867FFE0000
+F823:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE618E7DF661C66FF6618E7FFE0000
+F824:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61B67DB661866FF661F67FFE0000
+F825:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61867DBE61866FF661867FFE0000
+F826:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61CE7DBE618E6FB661CE7FFE0000
+F827:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61867DF661EE6FDE61DE7FFE0000
+F828:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61CE7DB661CE6FB661CE7FFE0000
+F829:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61CE7DB661C66FF661CE7FFE0000
+F82A:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61867DB661866FB661B67FFE0000
+F82B:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE618E7DB6618E6FB6618E7FFE0000
+F82C:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61C67DBE61BE6FBE61C67FFE0000
+F82D:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE618E7DB661B66FB6618E7FFE0000
+F82E:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61867DBE618E6FBE61867FFE0000
+F82F:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61867DBE618E6FBE61BE7FFE0000
+F830:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE63CE7DB671B67DB663CE7FFE0000
+F831:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE63EE7DCE71EE7DEE63C67FFE0000
+F832:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE63867DF671867DBE63867FFE0000
+F833:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE638E7DF671C67DF6638E7FFE0000
+F834:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE63B67DB671867DF663F67FFE0000
+F835:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE63867DBE71867DF663867FFE0000
+F836:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE63CE7DBE718E7DB663CE7FFE0000
+F837:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE63867DF671EE7DDE63DE7FFE0000
+F838:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE63CE7DB671CE7DB663CE7FFE0000
+F839:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE63CE7DB671C67DF663CE7FFE0000
+F83A:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE63867DB671867DB663B67FFE0000
+F83B:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE638E7DB6718E7DB6638E7FFE0000
+F83C:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE63C67DBE71BE7DBE63C67FFE0000
+F83D:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE638E7DB671B67DB6638E7FFE0000
+F83E:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE63867DBE718E7DBE63867FFE0000
+F83F:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE63867DBE718E7DBE63BE7FFE0000
+F840:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE6DCE6DB661B67DB67DCE7FFE0000
+F841:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE6DEE6DCE61EE7DEE7DC67FFE0000
+F842:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE6D866DF661867DBE7D867FFE0000
+F843:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE6D8E6DF661C67DF67D8E7FFE0000
+F844:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE6DB66DB661867DF67DF67FFE0000
+F845:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE6D866DBE61867DF67D867FFE0000
+F846:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE6DCE6DBE618E7DB67DCE7FFE0000
+F847:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE6D866DF661EE7DDE7DDE7FFE0000
+F848:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE6DCE6DB661CE7DB67DCE7FFE0000
+F849:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE6DCE6DB661C67DF67DCE7FFE0000
+F84A:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE6D866DB661867DB67DB67FFE0000
+F84B:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE6D8E6DB6618E7DB67D8E7FFE0000
+F84C:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE6DC66DBE61BE7DBE7DC67FFE0000
+F84D:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE6D8E6DB661B67DB67D8E7FFE0000
+F84E:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE6D866DBE618E7DBE7D867FFE0000
+F84F:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE6D866DBE618E7DBE7DBE7FFE0000
+F850:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61CE6FB661B67DB661CE7FFE0000
+F851:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61EE6FCE61EE7DEE61C67FFE0000
+F852:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61866FF661867DBE61867FFE0000
+F853:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE618E6FF661C67DF6618E7FFE0000
+F854:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61B66FB661867DF661F67FFE0000
+F855:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61866FBE61867DF661867FFE0000
+F856:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61CE6FBE618E7DB661CE7FFE0000
+F857:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61866FF661EE7DDE61DE7FFE0000
+F858:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61CE6FB661CE7DB661CE7FFE0000
+F859:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61CE6FB661C67DF661CE7FFE0000
+F85A:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61866FB661867DB661B67FFE0000
+F85B:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE618E6FB6618E7DB6618E7FFE0000
+F85C:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61C66FBE61BE7DBE61C67FFE0000
+F85D:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE618E6FB661B67DB6618E7FFE0000
+F85E:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61866FBE618E7DBE61867FFE0000
+F85F:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61866FBE618E7DBE61BE7FFE0000
+F860:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73CE6FB663B66DB673CE7FFE0000
+F861:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73EE6FCE63EE6DEE73C67FFE0000
+F862:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73866FF663866DBE73867FFE0000
+F863:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE738E6FF663C66DF6738E7FFE0000
+F864:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73B66FB663866DF673F67FFE0000
+F865:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73866FBE63866DF673867FFE0000
+F866:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73CE6FBE638E6DB673CE7FFE0000
+F867:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73866FF663EE6DDE73DE7FFE0000
+F868:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73CE6FB663CE6DB673CE7FFE0000
+F869:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73CE6FB663C66DF673CE7FFE0000
+F86A:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73866FB663866DB673B67FFE0000
+F86B:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE738E6FB6638E6DB6738E7FFE0000
+F86C:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73C66FBE63BE6DBE73C67FFE0000
+F86D:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE738E6FB663B66DB6738E7FFE0000
+F86E:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73866FBE638E6DBE73867FFE0000
+F86F:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73866FBE638E6DBE73BE7FFE0000
+F870:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61CE7DB67BB677B677CE7FFE0000
+F871:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61EE7DCE7BEE77EE77C67FFE0000
+F872:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61867DF67B8677BE77867FFE0000
+F873:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE618E7DF67BC677F6778E7FFE0000
+F874:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61B67DB67B8677F677F67FFE0000
+F875:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61867DBE7B8677F677867FFE0000
+F876:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61CE7DBE7B8E77B677CE7FFE0000
+F877:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61867DF67BEE77DE77DE7FFE0000
+F878:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61CE7DB67BCE77B677CE7FFE0000
+F879:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61CE7DB67BC677F677CE7FFE0000
+F87A:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61867DB67B8677B677B67FFE0000
+F87B:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE618E7DB67B8E77B6778E7FFE0000
+F87C:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61C67DBE7BBE77BE77C67FFE0000
+F87D:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE618E7DB67BB677B6778E7FFE0000
+F87E:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61867DBE7B8E77BE77867FFE0000
+F87F:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61867DBE7B8E77BE77BE7FFE0000
+F880:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73CE6DB673B66DB673CE7FFE0000
+F881:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73EE6DCE73EE6DEE73C67FFE0000
+F882:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73866DF673866DBE73867FFE0000
+F883:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE738E6DF673C66DF6738E7FFE0000
+F884:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73B66DB673866DF673F67FFE0000
+F885:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73866DBE73866DF673867FFE0000
+F886:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73CE6DBE738E6DB673CE7FFE0000
+F887:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73866DF673EE6DDE73DE7FFE0000
+F888:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73CE6DB673CE6DB673CE7FFE0000
+F889:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73CE6DB673C66DF673CE7FFE0000
+F88A:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73866DB673866DB673B67FFE0000
+F88B:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE738E6DB6738E6DB6738E7FFE0000
+F88C:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73C66DBE73BE6DBE73C67FFE0000
+F88D:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE738E6DB673B66DB6738E7FFE0000
+F88E:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73866DBE738E6DBE73867FFE0000
+F88F:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73866DBE738E6DBE73BE7FFE0000
+F890:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73CE6DB671B67DB673CE7FFE0000
+F891:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73EE6DCE71EE7DEE73C67FFE0000
+F892:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73866DF671867DBE73867FFE0000
+F893:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE738E6DF671C67DF6738E7FFE0000
+F894:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73B66DB671867DF673F67FFE0000
+F895:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73866DBE71867DF673867FFE0000
+F896:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73CE6DBE718E7DB673CE7FFE0000
+F897:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73866DF671EE7DDE73DE7FFE0000
+F898:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73CE6DB671CE7DB673CE7FFE0000
+F899:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73CE6DB671C67DF673CE7FFE0000
+F89A:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73866DB671867DB673B67FFE0000
+F89B:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE738E6DB6718E7DB6738E7FFE0000
+F89C:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73C66DBE71BE7DBE73C67FFE0000
+F89D:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE738E6DB671B67DB6738E7FFE0000
+F89E:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73866DBE718E7DBE73867FFE0000
+F89F:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE73866DBE718E7DBE73BE7FFE0000
+F8A0:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61CE6DB661B66DB66DCE7FFE0000
+F8A1:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61EE6DCE61EE6DEE6DC67FFE0000
+F8A2:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61866DF661866DBE6D867FFE0000
+F8A3:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE618E6DF661C66DF66D8E7FFE0000
+F8A4:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61B66DB661866DF66DF67FFE0000
+F8A5:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61866DBE61866DF66D867FFE0000
+F8A6:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61CE6DBE618E6DB66DCE7FFE0000
+F8A7:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61866DF661EE6DDE6DDE7FFE0000
+F8A8:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61CE6DB661CE6DB66DCE7FFE0000
+F8A9:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61CE6DB661C66DF66DCE7FFE0000
+F8AA:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61866DB661866DB66DB67FFE0000
+F8AB:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE618E6DB6618E6DB66D8E7FFE0000
+F8AC:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61C66DBE61BE6DBE6DC67FFE0000
+F8AD:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE618E6DB661B66DB66D8E7FFE0000
+F8AE:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61866DBE618E6DBE6D867FFE0000
+F8AF:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61866DBE618E6DBE6DBE7FFE0000
+F8B0:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE63CE6DB663B66DB663CE7FFE0000
+F8B1:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE63EE6DCE63EE6DEE63C67FFE0000
+F8B2:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE63866DF663866DBE63867FFE0000
+F8B3:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE638E6DF663C66DF6638E7FFE0000
+F8B4:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE63B66DB663866DF663F67FFE0000
+F8B5:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE63866DBE63866DF663867FFE0000
+F8B6:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE63CE6DBE638E6DB663CE7FFE0000
+F8B7:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE63866DF663EE6DDE63DE7FFE0000
+F8B8:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE63CE6DB663CE6DB663CE7FFE0000
+F8B9:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE63CE6DB663C66DF663CE7FFE0000
+F8BA:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE63866DB663866DB663B67FFE0000
+F8BB:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE638E6DB6638E6DB6638E7FFE0000
+F8BC:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE63C66DBE63BE6DBE63C67FFE0000
+F8BD:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE638E6DB663B66DB6638E7FFE0000
+F8BE:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE63866DBE638E6DBE63867FFE0000
+F8BF:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE63866DBE638E6DBE63BE7FFE0000
+F8C0:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE71CE6FB66FB66FB671CE7FFE0000
+F8C1:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE71EE6FCE6FEE6FEE71C67FFE0000
+F8C2:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE71866FF66F866FBE71867FFE0000
+F8C3:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE718E6FF66FC66FF6718E7FFE0000
+F8C4:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE71B66FB66F866FF671F67FFE0000
+F8C5:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE71866FBE6F866FF671867FFE0000
+F8C6:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000
+F8C7:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE71866FF66FEE6FDE71DE7FFE0000
+F8C8:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE71CE6FB66FCE6FB671CE7FFE0000
+F8C9:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE71CE6FB66FC66FF671CE7FFE0000
+F8CA:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE71866FB66F866FB671B67FFE0000
+F8CB:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE718E6FB66F8E6FB6718E7FFE0000
+F8CC:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE71C66FBE6FBE6FBE71C67FFE0000
+F8CD:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE718E6FB66FB66FB6718E7FFE0000
+F8CE:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE71866FBE6F8E6FBE71867FFE0000
+F8CF:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+F8D0:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE63CE6DB66DB66DB663CE7FFE0000
+F8D1:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000
+F8D2:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE63866DF66D866DBE63867FFE0000
+F8D3:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE638E6DF66DC66DF6638E7FFE0000
+F8D4:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE63B66DB66D866DF663F67FFE0000
+F8D5:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE63866DBE6D866DF663867FFE0000
+F8D6:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE63CE6DBE6D8E6DB663CE7FFE0000
+F8D7:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE63866DF66DEE6DDE63DE7FFE0000
+F8D8:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE63CE6DB66DCE6DB663CE7FFE0000
+F8D9:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE63CE6DB66DC66DF663CE7FFE0000
+F8DA:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE63866DB66D866DB663B67FFE0000
+F8DB:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE638E6DB66D8E6DB6638E7FFE0000
+F8DC:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE63C66DBE6DBE6DBE63C67FFE0000
+F8DD:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE638E6DB66DB66DB6638E7FFE0000
+F8DE:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE63866DBE6D8E6DBE63867FFE0000
+F8DF:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE63866DBE6D8E6DBE63BE7FFE0000
+F8E0:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61CE6FB663B66FB661CE7FFE0000
+F8E1:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61EE6FCE63EE6FEE61C67FFE0000
+F8E2:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61866FF663866FBE61867FFE0000
+F8E3:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE618E6FF663C66FF6618E7FFE0000
+F8E4:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61B66FB663866FF661F67FFE0000
+F8E5:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61866FBE63866FF661867FFE0000
+F8E6:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61CE6FBE638E6FB661CE7FFE0000
+F8E7:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61866FF663EE6FDE61DE7FFE0000
+F8E8:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61CE6FB663CE6FB661CE7FFE0000
+F8E9:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61CE6FB663C66FF661CE7FFE0000
+F8EA:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61866FB663866FB661B67FFE0000
+F8EB:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE618E6FB6638E6FB6618E7FFE0000
+F8EC:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61C66FBE63BE6FBE61C67FFE0000
+F8ED:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE618E6FB663B66FB6618E7FFE0000
+F8EE:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61866FBE638E6FBE61867FFE0000
+F8EF:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61866FBE638E6FBE61BE7FFE0000
+F8F0:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61CE6FB663B66FB66FCE7FFE0000
+F8F1:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000
+F8F2:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61866FF663866FBE6F867FFE0000
+F8F3:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE618E6FF663C66FF66F8E7FFE0000
+F8F4:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61B66FB663866FF66FF67FFE0000
+F8F5:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61866FBE63866FF66F867FFE0000
+F8F6:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+F8F7:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+F8F8:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+F8F9:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+F8FA:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61866FB663866FB66FB67FFE0000
+F8FB:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+F8FC:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+F8FD:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE618E6FB663B66FB66F8E7FFE0000
+F8FE:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61866FBE638E6FBE6F867FFE0000
+F8FF:00007FFE61CE6FB663CE6FB66FCE7FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+F900:0080108810881FF8100800007FFE00000FF008100FF00810042002447FFE0000
+F901:00047FFE008010841FFE10841FFC10841FFC10840880050003000CC0703E0000
+F902:010001047FFE010011081FFC11081FF811081FF8110801047FFE010001000000
+F903:FFFE04403FF824483FF800001FF010101FF010101FF010101FF00C60F01E0000
+F904:410821FC21080978894857FE540421F82108C1F8410841F8C108C13841100000
+F905:010001083FFC210821083FF8210801047FFE410441047FFC4104010001000000
+F906:0800080008041FFE200440041FC41044104410441FC410440044003800100000
+F907:08400FE0084010807FFC11447F7C05447F6C05547D6C05447F7E05027CFC0000
+F908:08400FE0084010807FFC11447F7C05447F6C05547D6C05447F7E05027CFC0000
+F909:080008027F7E08127F1208127F22084E098401007FFE020002C00C30700E0000
+F90A:0080018002400420081010086FF6010001083FFC01001118091009247FFE0000
+F90B:01029142FFE29112911297D29552955297D29552F39295420922111E01040000
+F90C:020002047FFE02400420181867E6000000083FFC00801890108C238441040000
+F90D:2214221E2FD42224B27EAFA2AABEAAA22FBE2222233E26A22A94222222422000
+F90E:010010841FFE92205FBC52481FBE12A232BEDFA2923E232226BE4A9492220000
+F90F:3FFC224422443FFC0844109024FE79900A9014FC7E9000FC34902A904AFE0000
+F910:04207FFE04201FF812481FF808A012903DFE0A9014FC7E9028FC549054FE0000
+F911:110411FE112455FC7F2455FC544455F87C2455FE109214101A94E37242220000
+F912:41FC21242924FDFC092411FC2524282073FEAC20247020A82126222220200000
+F913:07FE4492349217FE024804FE1748FAFE17C8107E15481AFE3040C80087FE0000
+F914:2108210847D05454E7F824485454FFFE45500104FFFE05200910310EC1040000
+F915:2100110811FC010842902C9028601198160661F821082108610861F821080000
+F916:1080108810FC108855505920523050C8930610FC18842484248440FC80840000
+F917:00800888FCFC1108129010601060FD98120611F815081908E10841F801080000
+F918:04407FFE0440244011F8150845902A600890110817FE6108210821F861080000
+F919:0420FE24283E2824FE44AAA8AA10AA28CE4482FEFE4482448244FE7C82440000
+F91A:44407E48487C48887F4848307E3048487E8643FC02845684AA84AAFC0C840000
+F91B:0720F92091204A20FF201420FFA092A0BDA080A0BEA094A28CA292A2A39E0000
+F91C:02002744387E224432442A542A54224C224426443A44225C0448084070400000
+F91D:13DE125213DEFE5213DE12223BFE562253FE92AA93FE1222127212AA13260000
+F91E:13DE125213DE125257DE5A2253FE522293FE12AA1BFE262222B2432E82240000
+F91F:04207FFE04207EFC42847EFC42847EFC41045FF44AA44FE441044544593C0000
+F920:1208110827D0783C2792783E2BA852940FE008200FF808000FFE292244940000
+F921:0080208420843FFC00003FF820282FC821082FE829282FEA410A41269FD20000
+F922:47D02510251407DE845057D85524252427C0C00047FC44A4C4A4C4A44FFE0000
+F923:04207FFE04203F0024243F3E21403F9024083F8800001FF8124812487FFE0000
+F924:43E822882A88FFCE0A5013E826842A8473E0A80027F822A822A822A827FE0000
+F925:100010401020FC2413FE1000140C1908F1085090109010909020702427FE0000
+F926:49247E484A4849244BFC7AA44A544BFC48407B684AD84B684ADABB6692420000
+F927:212422482248A924FFFCAAA4AA54ABFCF800AB6822D82B6836DAE26643420000
+F928:010020843FFE240022BE2FE428A42FA828A82FA428A229322BAC4CA088200000
+F929:10444A7E7F44424442447E7C424442447E444A7C44444A4452A4E11C42080000
+F92A:2080124813FC020842082BF82A08120813F86244224822306290670822060000
+F92B:00404C20292411FE310449FC890419FC294249448928091049483B8611020000
+F92C:1024093E3FA4212421283F28212821243F242122242222322D2C712020200000
+F92D:010001047FFE010011101110111029284384054009201110210C410401000000
+F92E:0040804060A02890090812461422282023FCC0084010402041C0402000100000
+F92F:04101554165824900A2811443FFE200241043FF8010802080488087030200000
+F930:107C124013FEFE4413FA124216FE1AA4F3FE52A412FC122095FE7842239C0000
+F931:109010F81110FFFC112411FC392455FC5554924A91FC110411FC110411FC0000
+F932:107C124013FE124457FA5A4252FE52A892F812A81AF8240025FC495497FE0000
+F933:011001F821003FFE21042FF8210223FE224823F822482FFC292449249FFE0000
+F934:01000100010C3FE8011001247FFE0080010006300CC017046404040603FC0000
+F935:04207FFE04A010F81FFE11041FF8110213FE124813F8124817F825285FFE0000
+F936:01F801003FFE21042FF0210227FE24483FFE244827F820802FFC41048E380000
+F937:00407C44447E448445487C305448108651025CFC508450845C84F0FC40840000
+F938:1FF841027FFE81043D7801403E7822483ED02B30084E2EF828887EF820880000
+F939:04400FE010883FFC51081FF811081FF8244422224FF208100FF008100FF00000
+F93A:3E7C22443EB808442EFA28887FF810101FF010101FFC10001FFE292244940000
+F93B:0044047CFE88108811F020103FFE6420A52224B4246827A43D2224E200400000
+F93C:208410FC1088FD0805F0081013FE3020592C94A8147010A8172612E210400000
+F93D:108810FC2088250845F0F81013FE2820FD2C44A8007028A8552656E280400000
+F93E:042004207FFE042003E0022007E000447FFE108808D006A00890738E21040000
+F93F:1044187C1444228840F8FC1011FE1020FF2694B4586851A81E26F0E240400000
+F940:010020843FFE222022243FFE22243FFC280428202FA4283829A25E22883E0000
+F941:202010201050FC88010602FA780003FE7A5202527BFE4A524A527A524A460000
+F942:087E7F40147C7F04227C3E40227C3E40227E2E42243E00801FF800847FFE0000
+F943:7FFC010001103FF8010001047FFE082008247FFE082008201020202040200000
+F944:10401F7E289045483F7E2240147C7F04227C3E40227C3E40227C2242263E0000
+F945:08807EFC14807FFC22043EFC22803EFE22827FFE08100FF008107FFE00100000
+F946:010020843FFE2004490809100FF81100210001047FFE01000100010001000000
+F947:00047FFE020007F00C10141067F002047F7E10201E3C326452A41E3C12240000
+F948:44807E8444FE44847D48463044487C86450244FC7C844484288444FC84840000
+F949:1FF841027FFE81043D7801003D78010020083FFC21083FF821083FF820080000
+F94A:1FF011101FF011101FF01010FEFE9292FEFE9292FEFE01103FF80104FFFE0000
+F94B:3FFC200420043FFC24883FFE24882FFC28842FFC21003FFE222041609F9E0000
+F94C:102011FC112413FEFD2411FC182035FC552451FC904097FE1090107017CE0000
+F94D:2080124413FE020442042BFC2A041228122463FE222024506488690632020000
+F94E:440427FE240407FC840057FE542027FE2622C73246AA4B32CAAAD2AA62260000
+F94F:1FFC10841FFC10841FFC1104022004601F8002083FFC108404A01B9861060000
+F950:1020102021FC252447FEF92413FE2A22FFFE442003FE288855905460839E0000
+F951:8804F9FE88109090A2FEA292929292928AAA8AC6CA82B29E8284820083FE0000
+F952:22202220FFA022243EFE08247F24492449247F240844FF44088408BC09080000
+F953:24203E202420242425FE3C242424242424243C242444244424A45D1C88080000
+F954:00408FFE60002BFC0A9412F4120423FC2000C3F840404FFE4248444408420000
+F955:0040804863FC2840084417FE11082204248AC1FC430844904860419E0E040000
+F956:04200E28F1FC102015FEFE481086194236785088914812301050118E16040000
+F957:102011FC2020242447FEF88811042A82FCF84508028828505460559886060000
+F958:042004207FFE05201FF801007FFE04201A1863F604201A4001800670780E0000
+F959:8848FBFC88409044A7FEA090910C928488F88988CA90B4A0806081988E060000
+F95A:202013FEFC2001FC00007BFE025203FE790401FC790449FC490479FC4B060000
+F95B:080408FE7F44122824101A2811C660381FC000881FFC00807FFE008007800000
+F95C:2108210847D05454E7F824485454FFFE45500104FFFE05200910310EC1040000
+F95D:2088108813FEFC8800A80020782403FE784000FC79844A844C8478FC48840000
+F95E:00100FF80810081009100890089008107FFE0810081010101090207040200000
+F95F:010020843FFE250454A827E400001FF812487FFE00003FFC0080078001000000
+F960:080008040BFE7E44124424481C300A48118660020500248824A6242243F00000
+F961:010000847FFE01042248179001001A5067EC452401007FFE0100010001000000
+F962:10081FFC11081FF811081FF8144804403FFC044004447FFE0420181860060000
+F963:088008800880088C0888F89008E008800880088008801884E8844886087C0000
+F964:000E09F0FC26212420A823FE3CA86524A62225FE252225FE3D2225FE21020000
+F965:100417FE1040244427FE244467FCA44427FC244422402140208021402E3E0000
+F966:190411FE220045FC990411FC210461FCA08021FC230824902060219826060000
+F967:00047FFE008000800100030005200910110C2106410201000100010001000000
+F968:20001040102404244488288828881290129464A224A220C061846284247E0000
+F969:08407F404940FFC4497E7FC808487F4849487F481028FF90222C1C46F3820000
+F96A:01083FFC010021043FFE210442281FC0011002083FF4008404A01B9861060000
+F96B:0100022007D0101024247B7E018202407CBC03001C4001981E6001801E000000
+F96C:010020823FFE42241FFC02201FFC02207FFE0490088817F6208200847FFE0000
+F96D:01000D10090811662142408001080FFC18086FF808080FF808080FF808080000
+F96E:04207FFE042009107FFE091009F008000FFC00807FFE02C004A0189860860000
+F96F:210810881090FE2001FC0104FD040104FDFC0154FC5084508492FD12860E0000
+F970:028842FC248818882688410E140012FCFF84104838485430922810C613020000
+F971:10041FFE1000101017F8100010041FFE124012481250222022904F0884060000
+F972:204010401040024443FE2A442C48104010406040204020A061226222241E0000
+F973:1040104010A0FD101208100615FA1800F10851FC11081108910871F821080000
+F974:042004207FFE04200420010001047FFE020004080FFC1408640807F804080000
+F975:104010201024FFFE100011FC15041904F1FC5124102011A8912472E224420000
+F976:008044847EFE54845548543054487C86550254FC54847C84448400FC00840000
+F977:020001047FFE00000FF008100FF000003FFE200247C4044004421842603E0000
+F978:00047FFE010001047FFE41045144492449245554659441044124411C40080000
+F979:00808040604427FE080013FC1204220423FCC22440204230452848E410440000
+F97A:10080BFC4048254C094A0A4A30B8131010847FFE02C004A00890108E60840000
+F97B:11FC110495FC550459FC1000FDFE112419FC352455FC902011FC102013FE0000
+F97C:010008900FF8081008100FF0081008100FF00900088C08700B203C1810060000
+F97D:204010201024FFFE000001FC7D0401047DFC01247CA844A445227EE244400000
+F97E:1FF010101FF010101FF000047FFE11101FF011101FF001003FF801007FFE0000
+F97F:7FD049107FD049125FFE52525FD252525FD242125FD2525253D29C6E90C40000
+F980:08100FF80810081008100FF00910010012081FFC1008100810081FF810080000
+F981:020003000200020002047FFE042004200820082010400E8001800670780E0000
+F982:21043FFE208020F828802FFE28842FF82A4A2BFE2A482FF82D285528AFFE0000
+F983:104008400844FEFE2080251C3EE024A624A424982490249024A85DC688820000
+F984:4048207C244007FE844457FA544225FE2524C5FC452445FCCA94CA8A44FA0000
+F985:03FE0A48FFFE224822FC22947AFCCA944AFC4A104AFE4A927AFA4C8608820000
+F986:7E7E42427E7E42427E7E400247E2442247E241024FF248124FF2481E40040000
+F987:89DCFC0093FE92AAFEAA9020FDFE9150FDFC855405FC5594AED8A49218EE0000
+F988:3E7C00003E7C2A542B5400803FFC22403FF822483FF828522F6248429F3E0000
+F989:0E407842087E7E920C221A42299E4A4404A01898649603E004903B8C11040000
+F98A:01000100010001083FFC01080108010801080208020804080888107060200000
+F98B:3FFE21082E7022143FFE221027382AD4329227F8240827F8240847F884080000
+F98C:20043FFE20842F7822103FFE221027382AD6321220402440247C44409FFE0000
+F98D:21242124FD7422DAFB74A954FAFAAF56F820A82423FEFEB02128222624220000
+F98E:0C0008080FFC1080208048880FFC0880088008847FFE00800080008000800000
+F98F:124C1148115017FE58D055485246920813BE14881AA8117E1108120814080000
+F990:1204110427C8701C23C84812FBFE5254AA6AABAA040025042492241243F80000
+F991:1210121413D2FA9012FE159012901990F12852461C8210009324749228920000
+F992:4020282427FE042081FC512455FC2F2425FCC42047FE4420C420DA2051FE0000
+F993:1020102413FE102057FE5A22532652AA93FE1222187024A82526422280200000
+F994:00101410FAFE2210207E2052207EFF52217E2152211039FEE1104690047E0000
+F995:002000F03F000104FFFE054009203118C0761F800108FFFC0100010001000000
+F996:102413FE202027FE4622FB2612AA2BFEFA224420007028A85526562280200000
+F997:0488FE88255227BC3C88255427DC3C22255427542D54F5DC4454049005100000
+F998:08103F7C08107F7E142822C440823FFE08880FF808880FF800807FFE00800000
+F999:04207FFE0420204017FC104003F8024873F8124813F8104017FC684047FE0000
+F99A:0040404437FE104003FC024413FCFA4413FC1244104017FE3040C84087FE0000
+F99B:1020182415FE222041FEFD2211A6116AFFFE9522587050A81F26F22240200000
+F99C:01027F820822082209220FA21122312249220A22042204020812100E60040000
+F99D:0100010019181106211A402001C00680188467FE0084010402240C1C30080000
+F99E:020293FEFA229222922293FA9222922292629252F28A930A020203FE02020000
+F99F:01047F84082408240FA41124312449240A04041C780800002444222242220000
+F9A0:01047FA408241F2431240A243D1C00887FFE028004480C50742007180C060000
+F9A1:210810881090FE2001FC0104FD040104FDFC0154FC5084508492FD12860E0000
+F9A2:21043FFE222021442FFE21402FF821483FFE21482FF8214023604550994C0000
+F9A3:01000280044008201110608C00000FE000200140048024842412441203F80000
+F9A4:102010201050FC881126121215FC1808F010501012C412A2928A7488207C0000
+F9A5:0420FE202050208825763E0225DC6554955415DC0800088810882156C2220000
+F9A6:10401F7E28907FFE24202FFC22402FF822483FFE22482FF826504A48B2460000
+F9A7:01244E482A48112433FC4A548AA41BFC28404B688AD80B6A4A5A3B6612420000
+F9A8:008001800240042009101088208640121FF8001000200640018000C000400000
+F9A9:20043FFE2104218422442524389C20042FF420442384208420843FFC20040000
+F9AA:010020843FFE250454A827E400001FF812487FFE00003FFC0080078001000000
+F9AB:108410841FFC00000BFE142022FC498404FC7F8402FC048438FC044805860000
+F9AC:1040104010A011105A0854465422902013FC1008101010A01060103010100000
+F9AD:00200860FC501088110412421022FC20100811FC14081810E0E0401000100000
+F9AE:08102A542C584890142822447FFE40043FF8010001001FF8012001147FFE0000
+F9AF:442024202850FE50108810A67D12101010FCFE04100810D02020401080100000
+F9B0:0220FF20245024503C88254626223C20240025FC2E08F4484430041004100000
+F9B1:10201820145022884106FE4210201020FE0495FE580850501E20F01040100000
+F9B2:1FF841027FFE81043D7801003D7806C01930E08E0FF000200040038000600000
+F9B3:1FF841027FFE81043D7801007BDE4A527BDE00007FFC091019302548FFFE0000
+F9B4:080409FE082014FC2284498484FC04847FFC0284248418FC0884085803860000
+F9B5:080008420FE21212125233F25452965219521092109211121102121E14040000
+F9B6:205011FC1154FDFC055409FC100033FE580095FC150411FC1088105013FE0000
+F9B7:0428FEFE28AA28FEFEAAAAFEAA00ABFECE0082FCFE8482FC8284FE4883FE0000
+F9B8:10201024FFFE18243424D3FE10247DFC0124FEA210B4586897A4B12210620000
+F9B9:00047FFE02403E7C200420043E7C02407FFE0000048024442452241243F80000
+F9BA:00083FFC00080010002000C00080008000800080008000800880078001000000
+F9BB:084008440FFE10A2151433F8560C9BFA120813F810401248144419C210420000
+F9BC:010020843FFE21045FFC24281FF028184FF608100FF000800CB0138C21040000
+F9BD:10041FFE100410041FFC104410401F4C1268125012502448244649C240800000
+F9BE:0808490849482A2828280A08FF4808280C281A0E2A3849C88888080808080000
+F9BF:2108210847D05454E7F824485454FFFE45500104FFFE05200910310EC1040000
+F9C0:1040104017FE14A2531455F85B0C55FA910811F818202528262444E288420000
+F9C1:008010441FFE90405FFE551413F8120C37FADA0893F82040225045C888860000
+F9C2:04207FFE042000007EFC12240E1C326403800C60771E00600F9800603F800000
+F9C3:0040404437FE1294010803FC150AF9F8110811F81128122634E2C84087FE0000
+F9C4:104008447F7E2240147C7F04007C3E40227C3E40227C3E40227E2E42243E0000
+F9C5:10101FF810101FF050127FFE81047FFC11101FF011101FF001007FFE01000000
+F9C6:44087DFC44004800500453FE48904890449044906490591242124412480E0000
+F9C7:180267C242524A525A5265929E122112DED204127F922492150217DE7C040000
+F9C8:100813FC10881088FC881088188837F854885088908890881088108817FE0000
+F9C9:104010D2131E1252FE5212521A523652525253D2925290561092111012100000
+F9CA:2080104417FE0040409029082BFC1004124862482248224A624A644A28460000
+F9CB:408025FE2612041284925562564E24842000C7FC444447FCC444C7FC44040000
+F9CC:00400824FDFE10201040108811FCFC041128112815281928E22A442A08260000
+F9CD:0200270438FE204422447D5C20881FF8108810881FF8108810881FF810080000
+F9CE:00400424FFFE1040108823FC3C846400A4A824A824A824A83D2A222A04260000
+F9CF:1000100423FE24444444F84410442844FDFC4484008428845484548487FE0000
+F9D0:49042AFE2A10087C7F441C442A7C49440A7C09447F44087C1444222842C60000
+F9D1:020001000180008000047FFE0000000004200420081008101008200640020000
+F9D2:F720112855243320552699F808201422E3A2082472280D12722A0C46F1820000
+F9D3:8840F8488BFC9040A044A7FE9090910C8A448840C848B3FC804080448FFE0000
+F9D4:0840086008901108121635FA500097FE1492149217FE14921492149214860000
+F9D5:0100210821083FF8210802800C60F7DE00003FF824483FF82448244824180000
+F9D6:204010C010A0011042082DF6280017FC14A464A427FC24A464A464BC24080000
+F9D7:10201020FE5010887D0656FA54007DFC55547D5455FC1154FF541154110C0000
+F9D8:184813FC204840489FFE104823F86048A04023FC2040204427FE204020400000
+F9D9:100417FE109013FE5A92569253FE9202102417FE102011B01128122614220000
+F9DA:00047FFE02401FF8124812481FF8108800847FFE02C004A00890108E60840000
+F9DB:010000847FFE01042248179001001A5067EC452401007FFE0100010001000000
+F9DC:8908FDFC8A089090A060A198960691F888008928CBFCB42081FC802087FE0000
+F9DD:010207827C1204120492FFD204120E1215122492449284020412040E04040000
+F9DE:008000847FFE008010841FFE108410841FFC108408800480030004C0783E0000
+F9DF:3FFC20043FFC208024FE298432FC228424FC2C40347C24C82530444885860000
+F9E0:08100FF808100FF008100FF0081004040FFE1124222444440884113802100000
+F9E1:010001047FFE05400920111861060FF0004000847FFE00800480038001000000
+F9E2:03043C2404247FA40C241624251C448800847FFE02C004A00890108E20840000
+F9E3:220413FE1204020443FC2A042A40124C124862502260244064426842303E0000
+F9E4:010409FEFD24112411FC11241124FDFC11241020142019FCE020402407FE0000
+F9E5:010010841FFE908051C25712111217D23112D192935225522902411E81040000
+F9E6:3FFC224422443FFC2044112011FE5B20552091FC112011FC1120112411FE0000
+F9E7:01047FFE00000FF808880FF808883FFC00807FFE028804501CA0651806060000
+F9E8:410421FE2924FD2409FC1124252429FC7124AC20242021FC2020202427FE0000
+F9E9:10081FFC110811081FF8110811081FF81108010001083FFC010001047FFE0000
+F9EA:10500848FFC8557E494849C8557E7F4808487F48497E55487B48417E47400000
+F9EB:40047FFE422042205FFC42A041045FFE420047F84A08520843F842087FFE0000
+F9EC:408227BE20820082879E5492541027BE28A2C4924186469AD8E2C71C42080000
+F9ED:010000847FFE08100420024001800E70700E1FF81008100810081FF810080000
+F9EE:1222112410A813FE54A859245222510891DE124819A824BE2508420884080000
+F9EF:02221124F8A823FE20A821242222FA0823BE228826A839FEE108420804080000
+F9F0:04207FFE04203E7C22443E7C22443E7C27E42C8437E4248427E4249C27E80000
+F9F1:8A4CF948895097FEA150A2489C4692088BBE8C88CAA8B13E8208840888080000
+F9F2:21243D2424A84BFCFCA8552456227D0855FE55487F4844E854BEAB08AA080000
+F9F3:08A444647F2854FE7F28556455A27F0454EE54A45D2456B4545E5D8497040000
+F9F4:08200820082008247FFE082008201CB02AA8292849244A240C22082208200000
+F9F5:42102210221002948FFE52105310229026B8CA5452525212C210C21042100000
+F9F6:8480FE8490FE910092F8FC88848884F88400FFDE925292529252FFDE82520000
+F9F7:02000100008000883FFC000008100810042004200240024000847FFE00000000
+F9F8:102010201F3E285044880100008000883FFC042004200240024000847FFE0000
+F9F9:104092209220540455FE1000FE84108418883448524852509010901013FE0000
+F9FA:044024502448244824403FFE045004507C502450244824482484450686020000
+F9FB:0200021007F80C203240088007000C807098089008A0114002200C1830060000
+F9FC:2110109013F4FD52015200907BFE00107BD202527BD44A484BCA7A5648220000
+F9FD:08400840084010401040304057FE904010401040104010401040104010400000
+F9FE:042004207FFE0420058002400420189860861FF8008004A00890108E60840000
+F9FF:08020882FFD208128892FFD2889288928B9288921C122A024992888E08040000
+FA00:2000200423FE204424442E44F044204422442444284430842144023804100000
+FA01:010020843FFE222022243FFE222023E0200027F82210212020C043309C0E0000
+FA02:1000100413FEFC4010401040148419FEF284548410841084908470FC20840000
+FA03:1040112495FE552059FC1124FDFE112419FC352055FC9284128414FC18840000
+FA04:020041087FFC4008809001C07E000410043807C0FC0004040404040603FC0000
+FA05:220413FE1204020446F42A042A0412F41294629422F422946204621C22080000
+FA06:1FF010101FF010101FF004403FFC04407FFE11102928474405C01930630C0000
+FA07:11FE1000FEFC10847C8454FC7C0055FE7D22552211FEFF22112211FE11020000
+FA08:180811FC200040000C040BFE1010301050109010101010101090107010200000
+FA09:44887CFC44884950502050504B8E482045FC44A065245BFE4020402040200000
+FA0A:00201FF0102010201FE0102010201FE0102010201FE014A408843086C07C0000
+FA0B:20843FFE22003FDE20122F9428942F9820143FD22112221A2F9442108E100000
+FA0C:0008FFFC08800880088008800880088008801080108420844086807C00000000
+FA0D:0848087C7F4808483F48008E7F0082FE3E4400443E28221022283E4622820000
+FA0E:10500848FEFE459026FC189008FC149024FEC0803FF00820044003800C60F01C
+FA0F:2090208821042240F84020A020902108220425FA21083908C108010801F80108
+FA10:120213FE1404100013FEFC401086174412A811301EE8E0A84124062200C00000
+FA11:204020202BFEA800A908A890AFFEA808ABC8AA48AA48BBC8CA48000800280010
+FA12:00204BFE7C2049FC48204FFE780049FC490449FC490479FC4904011C01080000
+FA13:1088108813FE1088FC8810443884357E51045324951411141104110411141108
+FA14:12441124108813FEFC9011083A1434E2502051F8902013FC1020102010A01040
+FA15:8BD46A9E2A940A941BD42A5C2A54CBD04A92529263EE00002444222242220000
+FA16:00404C40284611F4304848508BFE184029FC4B04890409FC490439FC11040000
+FA17:08300420024002447FFE04200810100C60041FF812481248124812487FFE0000
+FA18:00403E40004000407F4008402A402A402A402A404A404A4008420842083E0000
+FA19:202010201124FDFE0524092411FC31245924952415FC11241020102010200000
+FA1A:210C10881050FFFE04200820102031FC58209420142413FE1020102010200000
+FA1B:200413FE1000FCF80488088810F8300059FC952415FC1124112411FC11040000
+FA1C:202023FE102011FCFC2003FE440045FC290429FC11041DFCE104411C01080000
+FA1D:102413FE922054FC542011FEFE0010FC188434FC528492FC1084109C10880000
+FA1E:02047FFE0E1C121422244244060C0A14122422444284020412240E1C04080000
+FA1F:0440FFFE044004403EFC228422FC3E8422FC22403EFE232222D2428A4AF2840C
+FA20:0820FFFE08A01CF0F11012F810A8FCF810A831FC392455FC552491FC1022101E
+FA21:202021202120F9FCAA20AC20A820A820A9FCF820A820202028203820CBFE0000
+FA22:204010401044FDF4004800507BFE004079FC0284788448FC488478FC48840000
+FA23:100810481028FE08108810481008FE0E11F810085C085008500870088C0083FE
+FA24:000023FC10880888409020BC10840084F0C411481128121014282844448283FE
+FA25:011041F83110122407FE02441244FBFC106010A811261622301EC80087FE0000
+FA26:082408BE3EA409240A287FE8042809241FA431225F221132112C1F2011200000
+FA27:1020102029FE4424B82813FE10207C4010FC1308541039FE10101C10E0500020
+FA28:1020102029FC4420B82017FE11047C8811FC102054203BFE10201C20E0200020
+FA29:00407C8045F8490849F8510851F8490045FE450045FC5884449447F440044018
+FA2A:1008189C14E02A804884BEFE22A43EA422A83EA820A8249026A87B4622820000
+FA2B:100019FE14022A0248FABE0222F23E9222923E9220F2249226027A1E20040000
+FA2C:1020181014922AFE4904BEF822883E8822F83E8020FC248426847AFC20840000
+FA2D:1030102092FCFE84A2FC28847EFC4880FEFE48807EFE480248AA7F5641540000
+FA2E:0800087C7E44424842487E50424842487E4451444A4444684450524062404040
+FA2F:10201020FCFC102411FE7C2400FC7C200124FCA8107054A85324922210A03040
+FA30:090009040BFE140013F83288524892081FFE12881248120817FE100810700000
+FA31:09080890081013FE1222332652AA93FE100011FC110411FC110411FC11040000
+FA32:080008801FC0108021107FF8A210221022103FF02290048408843086C07C0000
+FA33:202022203F20222444FEFF24492449247F24494408441884291A480287FE0000
+FA34:2220FFA022203E2408FE7F2449247F240824FFA408447F4408A40F9CF1080000
+FA35:010022083FFC208820883FF821083FF82288048008847FFE0080008000800000
+FA36:020893FCFA0893F8920893F89288910293FE9622FA229252028A03F2001C0000
+FA37:011097FEF91091F0904097FC944497FC904097FCF0409FFE00A003180C060000
+FA38:22443F7E224422443E7C012002147FFE081012087F7E224422443E7C22440000
+FA39:11FE1102110211FEFD44112811FE1148154819FEE24842480488090800000000
+FA3A:10081FFC14A812A81FF800801FFC00807FFE144812A620821FF800847FFE0000
+FA3B:3FFC200420043FFC222421402FFC2A9429242FFC240827F8440847F884080000
+FA3C:010001000100210421042104210421043FFC21040100010002000C0070000000
+FA3D:1200120413FE14005BF85288524892481FFE12881248124817FE100810700000
+FA3E:200424BE278824A8B4A8AFA8A4A827FE24102518249825A82E4A248A210E0000
+FA3F:110C1088109013FE5A22572652AA93FE120211FC110411FC110411FC11040000
+FA40:0110355027D4405E97B4201467D4A10827D421262FC204842452241243F80000
+FA41:202021203FA02024407E3EC82A482A48FFC852284A304A107FA802460C820000
+FA42:44047EFE441044507C50449044947DFE4410401048304C505492E112420E0000
+FA43:0FF008100FF008100FF409081FF001207FFE008007F87C0807F8040807F80000
+FA44:1100110413FE1000FDFC11441924352457FE52889248924817FE100810700000
+FA45:4200220423FE0C008BF85288524822482FFEC48844484448C7FEC01040E00000
+FA46:00402040104403F8405028642FFE108011FC23046DFC2104210421FC21040000
+FA47:41102FFE211001F0804057FC544427FC2040C7FC40404FFEC080C3304C0E0000
+FA48:01000FEC010801107FFE008007F00C1017F0641007F004102444222242220000
+FA49:001000F83F00010C108808900820000000000000000000000000000000000000
+FA4A:00040BFEFC401080114C124812B07D2012B0106814A81924E222452008C00000
+FA4B:012405FEFF24112411FC21243D2465FCA5442490251427FE3C10241000100000
+FA4C:202010201020FC200420082811FC302058209420142010201020102413FE0000
+FA4D:202010201020FC2005200924113E312059209520152011201120112417FE0000
+FA4E:2008109C10E0FC800480088410FE308858889488148811081108120814080000
+FA4F:204010401044FDFE044008401080308459FE968414841084108410FC10840000
+FA50:210811FC1108FD080508090811F831085908950815F811081108110817FE0000
+FA51:210411FE1104FD040504090411FC3154585094501450105210921112120E0000
+FA52:208810FC1088FC8804B808A810A833FE5A0296F2129212F21292120E12040000
+FA53:20201024103EFC2005FC090411FC310459FC950415FC11041050108813060000
+FA54:0848FFFC08487F4800487F8E81003EFC00487E4808487F302A30494889860000
+FA55:010020843FFE200444481830614C012001047FFE0100028004401830600E0000
+FA56:104010401F7E289045083E7C22443E4422443E44224424442E5C734821400000
+FA57:102413FE202027FE4622FB2612AA2BFEFA224420007028A85526562280200000
+FA58:100413FE208824884552FBDE10002BFEFC0045FC010429FC550455FC81040000
+FA59:20203FBE55443FA415181FA6014202101FE002107FFC208400A01B9861060000
+FA5A:3FFC224422443FFC21041FE801107FFE008007F80C0837F8040807F804080000
+FA5B:020002083FC802100224FFFE010002100FF818102810CFF008100FF008100000
+FA5C:09100FF808100FF008100FF008100FF0082000947FFE014002200C1E70040000
+FA5D:000000000000042004207FFE0420042000000000000000000000000000000000
+FA5E:000000000000042004207FFE0420042000000000000000000000000000000000
+FA5F:042004207FFE052001081FD001207FFE010007F81C0867F8040807F804080000
+FA60:41FC210429FCFD0409FC1124244028FE7122AF222552218A210221F2200C0000
+FA61:21FC1104110405FC7F04090411FC3904550495FC1154105010521092170E0000
+FA62:210411FE1104FDFC010401FC794000FE792203227952498A490279F2480C0000
+FA63:2088108813FEFC8800F8002079FC012479FC00207BFE482049FC78204BFE0000
+FA64:21043FFE20045FF40510092031400FF078100FF008100FF008100FF0381C0000
+FA65:890CFC8888508BFEFA228B268AAAFBFE880089FCF90489FC510489FC89040000
+FA66:400030001000000000001000F80010001000100010003000C80087FE00000000
+FA67:011041F83110122407FE02441244FBFC106010A811261622301EC80087FE0000
+FA68:22A0FF9022903EFE09907E904A907EFC08907E9008FCFF90149422FE42800000
+FA69:111E27D27A5413D82A567A92135C60901FF804447FFE08100FF008100FF00000
+FA6A:080409FE28202EFC28842884FFFC088428FC288449848AFC0484185861860000
+FA6B:01300108FFFE01003FF8210821083FF8210821083FF80100258C24966632C3E0
+FA6C:00007F7E480248027F02417E41407F40484248427F7E00002488224442448004
+FA6D:102038202DFE67024102FCF810881088FEF8008000807CFC4484448444847CFC
+FA6E:00007FFE61866FB663866FB66FB67FFE7FFE73866FBE638E6DBE73867FFE0000
+FA6F:00007FFE61866FB663866FB66FB67FFE7FFE73866FBE638E6DBE73BE7FFE0000
+FA70:1010082004407FFC0440044004404444244414481450044004400440FFFE0000
+FA71:47F8240824080408040817F811202120E1202120222022222422281E10000000
+FA72:0100010002800440082010102FE8C106010001001FF00100010001007FFC0000
+FA73:10041FC414842494249464946494AFD424942494249424942484288428943088
+FA74:02000100FFFE04000400082010103FF80448044004400440084408441044603C
+FA75:04447C7804421C3EE4003FF821083FF821083FF804403FF80440FFFE10102008
+FA76:3FF0066001803FF821083FF821083FF82108220802007FF80408080810506020
+FA77:0800080010001FF8200840088008040802080108010800080008000800500020
+FA78:03F87A084BF84A084BF849004BFC4C444A447AA44A0403F40004002800100000
+FA79:0100010079FC4A044D0449E44A8448844FF448847AA44AA403E4000400280010
+FA7A:010001F8F20893F0901097FE90809144966890B0F128966800A4012206A00040
+FA7B:01F87908490849F84908490849F848004BFC7A944A940294029407FE00000000
+FA7C:200027FE2402280427FEF8802184224426A821303AF0E4A8412802240CA20040
+FA7D:102011FC1020108813FEFC8811FC110411FC110411FC1D04E1FC408801040202
+FA7E:020002007FFC044009203118DFF6111011101FF0111011101FF40104010400FC
+FA7F:020002007FFC044009203118CFE60100092008207FFC08200820102010202020
+FA80:1040108011FC1124FD2425FC2524254425FC4890291013FE2810441084100010
+FA81:2108209023FE2108F9084A524B9C49088A524BDE304010A42AAA4A8A84780000
+FA82:010000803FFE22102F90221E2FA422243FD4241427942488448848948AA41142
+FA83:010000803FFE200027FC244427FC244427FC211027FC21102FFE400042088404
+FA84:010007847804088844902522200204047F880C10162215022484440884100460
+FA85:0808083C13C020044A44092811FC3220502093FE102011241124112411FC1004
+FA86:100013FE1202128A1A5257FE5242522293FE12821282128212FA1202120A1204
+FA87:2040204027FC204033F8AA08A3F8A208A3F8220823F822082FFE211022082404
+FA88:010002800C6037D8C0063E0822483E4822483E482208261801004884481287F2
+FA89:11041088100013FE1A2256AA5272522293FE100011FC110411FC110411FC1104
+FA8A:21082108210827D0311EAF94A124AFD4A21423D422542248224824D424242842
+FA8B:22204AA08ABE1FC420A46F24A0282FA822102FA822442F8201004884481287F2
+FA8C:08207F280824FFFE00207F2049247F2449247F2822287F102212FFAA22464182
+FA8D:204020A021102208FDF6200023C42A543254E3D42254225423D42244A25442C8
+FA8E:10A0112C11241124FDAC1124112415FC182031FCD08810501020105050882306
+FA8F:200023FC22042204FBFC220022842A4832FCE248224823FE24482448A8885108
+FA90:0820082008207F3E08443E440844FFA410281E281210121022282A4844848102
+FA91:002000207BFE482049FC48204BFE780049FC490449FC490479FC490401140108
+FA92:1000087C7E44424442447E7C424442447E44407C484444445A84628441140208
+FA93:1000087CFF44207C2044267C3844209401087FFC010001003FF801000100FFFE
+FA94:1010101010101010FDFE10103010391055105490909010501020105011881606
+FA95:FFFE02000200040007F8080810102410422001400080010002000C0070000000
+FA96:040044782848104828484486920010FCFE441044582854289210122850442182
+FA97:0080204017FE10808110420847FC100410002248E24822482248224A244A0846
+FA98:0004203E17C0124481244128420013FC14402040EFFE20402444244427FC0004
+FA99:01082088109017FE810841084210129414A42738E1082210221024A427BC0084
+FA9A:0110211017FE111081F040404BF80A4813F81040E7FC20402FFE20A02110060C
+FA9B:022042202FB822480F90827C4F9450141FFE2894EF9428FC2F9428902A900930
+FA9C:020002083FD00220FFFE01000FF03810CFF0081008100FF00000488844448444
+FA9D:00A0009079FE49104B107DFE4910491079FE4910491049FE79004AA402520452
+FA9E:00FC7F00220811107FFC44447FFC00087E0842FE7E0842487E28480874284210
+FA9F:440029F81108290849088908090819282910490089020902090250FE20000000
+FAA0:0040884453F42048505097FE1040108031F85308950811F811081108A1F84108
+FAA1:00200020FBFE202021FC210421FCF90421FC210421FC3904E3FE408801040202
+FAA2:082004407FFC12483CF0082014503EF800007FFC08000FE0092010A41624181C
+FAA3:FFFE000000004FE4492449244FE44924492449244FE4400440047FFC00040000
+FAA4:008000401FFE100097FC54A454A417FC30405150924814442150224844448040
+FAA5:010000803FFE200027F8A40867F8240827F86000AFFC2924292449247FFE8000
+FAA6:101008200000FFFE000008201010200840043FF82448244824482448FFFE0000
+FAA7:009000883FFC208020883E48225022244A54448C81043FF824482448FFFE0000
+FAA8:010001007FFC01001FF0101010101FF010101FF010101FF010101010FFFE0000
+FAA9:00FC7C84448444FC7C0045FE45027D0245FE450245027DFE4502010A01040000
+FAAA:082004407FFC01003FF80200FFFE04000FF018102FF0C8100FF008100FF00810
+FAAB:00200020FBFE202021FC410479FC4904C9FC490449FC49047BFE488801040202
+FAAC:020001007FFE4822909411F822886870ABAE282029FC282028A8292422A42040
+FAAD:104010403F7E4890850800007E7C42447E4442447E44484444545A4862404040
+FAAE:01001110092001007FFC05400920111060080100FFFE0280044008203018C006
+FAAF:108010F811082290206065986646A48825F02420244825FC2020212422A22040
+FAB0:1020102023FE242045FCF92411AC21744924FDFC0420007054A8552482220020
+FAB1:208420483C0050FC90481048FE48104811FE5448544854485C48648804880108
+FAB2:020002083FD002200240FFFE010002000FF0181028104FF0881008100FF00810
+FAB3:08200820FFFE0A200100FFFE100010001FF8000011101110111021124112810E
+FAB4:04400440FFFE04407FFC11101110FFFE111011107FFC0100FFFE010001000100
+FAB5:100010F810887C8854F85488548854F87C0051FC115415541D54E55443FE0000
+FAB6:200013BE00A2F0A210BE238822086A3EB22A2BAA20AA20BE2088208A257E2202
+FAB7:FFFE04403FF824483FF8120027FC42088BF8120833F8510093F8151010E0171E
+FAB8:200011FC1104F90409FC1104110439FC5504950411FC1050109010921112120E
+FAB9:200011FC0124FD240174792401FC7904017479544954497449047A044A140408
+FABA:2020102201FAFC2400287BFE0020784000FC79844A8448FC4884788448FC0084
+FABB:2020102003FEFC2001FC782003FE780001FC790449FC490449FC790449140108
+FABC:200011FC1104FDFC01047DFC00807DFE02227D224552450245FA7C0244140008
+FABD:2088108803FEFC8800A8782003FE7840008078FC49844A844884788448FC0084
+FABE:204010A00110FA0805F6780003C47A5402547BD44A544A544BD47A444A5402C8
+FABF:2088108803FEFC8800F8782001FC792401FC78204BFE482049FC78204BFE0000
+FAC0:210447C88812F3BC20084B92F83E0380AAAAABAA08001FF8282007C01830E00E
+FAC1:0104788848004BFE7A224AAA4A727A224BFE480079FC010451FC490489FC0104
+FAC2:204020A02110FA0825F6F800ABC4FA54AA54FBD42254FA5423D42244225422C8
+FAC3:07FC440427FC242004A80470E4A8250424A024FC252024202BFE282050208FFE
+FAC4:0050FE9628922892FED6AA92AA92AAFEAE10C2FC8244FE4482288210FE2882C6
+FAC5:100213E22942254A414AB94A114A13EAFD4A114A954A594A51421E42E24A4444
+FAC6:00207C2245FA4824482853FE4820484044FC4584468468FC5084408440FC4084
+FAC7:22282224FF40227E3EC809487F7E49487F48087E7F480848FF48147E22404140
+FAC8:2020102013FEFC2001FC08208BFE880049FC490451FC51041DFCE10441140108
+FAC9:104410447DFE2444FE4401FE7C4044FE7D9212FE7C9210FE50927C9210921086
+FACA:110023DE7A5213D42A527BDA1294235001003FF80440FFFE10101FF010101FF0
+FACB:7EFE401040205EFC5284528452FC5A8454FC5084528454FC5848508481020000
+FACC:080008FE28102E2028FC2884FF8400FC08842AFC2A844C8484FC08483084C102
+FACD:3F042018FF62220C7F7001007FFC01001FF0101011101110FFFE082010102008
+FACE:04003FF820083EF802807A800AFCFE940AD47AA402A47AD40A94FEFC0A8279FE
+FACF:20CC273021103110AFFEA110A2A824282844210222902A482A543214221021F0
+FAD0:20CC273021103110AFFEA110A2A82428284423FA220823F82208220823F82208
+FAD1:10281024102013FEFC2010A838A834A850A850A89128112A122A142610201020
+FAD2:2000229E22522252F5522112229272526C32A3D2A25A22542250225023D02250
+FAD3:03FC789048904890789048904FFE789048904890489079104910021004100000
+FAD4:0020002078204BFE482078204924492479244AAA482048507850488801040202
+FAD5:02200220F47C94449DA8F510952895D6F51095FE95109538F454949204100410
+FAD6:10401F7E28904508BEF822883EF822883EF820082EE824482EE8244828482018
+FAD7:1044108813DEFC881088108813DEFC88108810885C885108520870008C0083FE
+FAD8:20007CFC44847CFC44847CFC0040FEFE9312FE9292AAFE8200FAFE0244148408
+FAD9:3FFE22202FBC2520223C3F84203C2FA028BC2FA028BC2FA048BC48A2899E0000
+FADA:00007FFE61866FB663866FB66FB67FFE7FFE63866DB66D866DB663B67FFE0000
+FADB:00007FFE61866FB663866FB66FB67FFE7FFE638E6DB66D8E6DB6638E7FFE0000
+FADC:00007FFE61866FB663866FB66FB67FFE7FFE63C66DBE6DBE6DBE63C67FFE0000
+FADD:00007FFE61866FB663866FB66FB67FFE7FFE638E6DB66DB66DB6638E7FFE0000
+FADE:00007FFE61866FB663866FB66FB67FFE7FFE63866DBE6D8E6DBE63867FFE0000
+FADF:00007FFE61866FB663866FB66FB67FFE7FFE63866DBE6D8E6DBE63BE7FFE0000
+FAE0:00007FFE61866FB663866FB66FB67FFE7FFE61CE6FB663B66FB661CE7FFE0000
+FAE1:00007FFE61866FB663866FB66FB67FFE7FFE61EE6FCE63EE6FEE61C67FFE0000
+FAE2:00007FFE61866FB663866FB66FB67FFE7FFE61866FF663866FBE61867FFE0000
+FAE3:00007FFE61866FB663866FB66FB67FFE7FFE618E6FF663C66FF6618E7FFE0000
+FAE4:00007FFE61866FB663866FB66FB67FFE7FFE61B66FB663866FF661F67FFE0000
+FAE5:00007FFE61866FB663866FB66FB67FFE7FFE61866FBE63866FF661867FFE0000
+FAE6:00007FFE61866FB663866FB66FB67FFE7FFE61CE6FBE638E6FB661CE7FFE0000
+FAE7:00007FFE61866FB663866FB66FB67FFE7FFE61866FF663EE6FDE61DE7FFE0000
+FAE8:00007FFE61866FB663866FB66FB67FFE7FFE61CE6FB663CE6FB661CE7FFE0000
+FAE9:00007FFE61866FB663866FB66FB67FFE7FFE61CE6FB663C66FF661CE7FFE0000
+FAEA:00007FFE61866FB663866FB66FB67FFE7FFE61866FB663866FB661B67FFE0000
+FAEB:00007FFE61866FB663866FB66FB67FFE7FFE618E6FB6638E6FB6618E7FFE0000
+FAEC:00007FFE61866FB663866FB66FB67FFE7FFE61C66FBE63BE6FBE61C67FFE0000
+FAED:00007FFE61866FB663866FB66FB67FFE7FFE618E6FB663B66FB6618E7FFE0000
+FAEE:00007FFE61866FB663866FB66FB67FFE7FFE61866FBE638E6FBE61867FFE0000
+FAEF:00007FFE61866FB663866FB66FB67FFE7FFE61866FBE638E6FBE61BE7FFE0000
+FAF0:00007FFE61866FB663866FB66FB67FFE7FFE61CE6FB663B66FB66FCE7FFE0000
+FAF1:00007FFE61866FB663866FB66FB67FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000
+FAF2:00007FFE61866FB663866FB66FB67FFE7FFE61866FF663866FBE6F867FFE0000
+FAF3:00007FFE61866FB663866FB66FB67FFE7FFE618E6FF663C66FF66F8E7FFE0000
+FAF4:00007FFE61866FB663866FB66FB67FFE7FFE61B66FB663866FF66FF67FFE0000
+FAF5:00007FFE61866FB663866FB66FB67FFE7FFE61866FBE63866FF66F867FFE0000
+FAF6:00007FFE61866FB663866FB66FB67FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+FAF7:00007FFE61866FB663866FB66FB67FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+FAF8:00007FFE61866FB663866FB66FB67FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+FAF9:00007FFE61866FB663866FB66FB67FFE7FFE61CE6FB663C66FF66FCE7FFE0000
+FAFA:00007FFE61866FB663866FB66FB67FFE7FFE61866FB663866FB66FB67FFE0000
+FAFB:00007FFE61866FB663866FB66FB67FFE7FFE618E6FB6638E6FB66F8E7FFE0000
+FAFC:00007FFE61866FB663866FB66FB67FFE7FFE61C66FBE63BE6FBE6FC67FFE0000
+FAFD:00007FFE61866FB663866FB66FB67FFE7FFE618E6FB663B66FB66F8E7FFE0000
+FAFE:00007FFE61866FB663866FB66FB67FFE7FFE61866FBE638E6FBE6F867FFE0000
+FAFF:00007FFE61866FB663866FB66FB67FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+FB00:0000001B2424247E2424242424240000
+FB01:0000001A2220207E2222222222220000
+FB02:0000001E2222227A2222222222220000
+FB03:000000162A28287E2A2A2A2A2A2A0000
+FB04:0000001E2A2A2A7E2A2A2A2A2A2A0000
+FB05:000000384848485E4848484848460000
+FB06:0000001C242424364444241414620000
+FB07:00007FFE618E6FB6638E6FB66F8E7FFE7FFE73866DF66DEE6DDE73DE7FFE0000
+FB08:00007FFE618E6FB6638E6FB66F8E7FFE7FFE73CE6DB66DCE6DB673CE7FFE0000
+FB09:00007FFE618E6FB6638E6FB66F8E7FFE7FFE73CE6DB66DC66DF673CE7FFE0000
+FB0A:00007FFE618E6FB6638E6FB66F8E7FFE7FFE73866DB66D866DB673B67FFE0000
+FB0B:00007FFE618E6FB6638E6FB66F8E7FFE7FFE738E6DB66D8E6DB6738E7FFE0000
+FB0C:00007FFE618E6FB6638E6FB66F8E7FFE7FFE73C66DBE6DBE6DBE73C67FFE0000
+FB0D:00007FFE618E6FB6638E6FB66F8E7FFE7FFE738E6DB66DB66DB6738E7FFE0000
+FB0E:00007FFE618E6FB6638E6FB66F8E7FFE7FFE73866DBE6D8E6DBE73867FFE0000
+FB0F:00007FFE618E6FB6638E6FB66F8E7FFE7FFE73866DBE6D8E6DBE73BE7FFE0000
+FB10:00007FFE618E6FB6638E6FB66F8E7FFE7FFE7BCE73B67BB67BB671CE7FFE0000
+FB11:00007FFE618E6FB6638E6FB66F8E7FFE7FFE7BEE73CE7BEE7BEE71C67FFE0000
+FB12:00007FFE618E6FB6638E6FB66F8E7FFE7FFE7B8673F67B867BBE71867FFE0000
+FB13:000000000814305D5555555555330000
+FB14:000000000C1414575454555555360000
+FB15:000000000C1414565555555555350404
+FB16:00000000503C1455555555555533101C
+FB17:00000000182828ADADADADADAD6A0808
+FB18:00007FFE618E6FB6638E6FB66F8E7FFE7FFE7BCE73B67BCE7BB671CE7FFE0000
+FB19:00007FFE618E6FB6638E6FB66F8E7FFE7FFE7BCE73B67BC67BF671CE7FFE0000
+FB1A:00007FFE618E6FB6638E6FB66F8E7FFE7FFE7B8673B67B867BB671B67FFE0000
+FB1B:00007FFE618E6FB6638E6FB66F8E7FFE7FFE7B8E73B67B8E7BB6718E7FFE0000
+FB1C:00007FFE618E6FB6638E6FB66F8E7FFE7FFE7BC673BE7BBE7BBE71C67FFE0000
+FB1D:00000000001C04040400040000000000
+FB1E:0042423C000024004200240000000000
+FB1F:000000000077111111003E0000000000
+FB20:00000000004422121212121214F80000
+FB21:00000000000000000000303C300C0C0C030C0CF030C03030300C300C00000000
+FB22:000000000000000000003FFC0030003000300030003000300030003000000000
+FB23:000000000000000000003FFC000C000C0C0C0C0C0C0C0C0C0C0C0C0C00000000
+FB24:000000000000000000003FFC000C000C000C000C000C000C000C3FF000000000
+FB25:0000000000000C000C000FFC000C000C000C000C0030003000C00F0000000000
+FB26:00000000000000000000FFFC0C0C0C0C0C0C0C0C0C0C0C0C0C0C0FFC00000000
+FB27:000000000000000000003FFC000C000C000C000C000C000C000C000C00000000
+FB28:000000000000000000000FFC0C0C0C0C0C0C0C0C0C0C0C0C0C0C3C0C00000000
+FB29:00000000000000080808087F00000000
+FB2A:000000010049494949494949497F0000
+FB2B:000000400049494949494949497F0000
+FB2C:0000000100494949494D4949497F0000
+FB2D:0000004000494949494D4949497F0000
+FB2E:0000000000464222122C484442411C00
+FB2F:0000000000464222122C484442411C08
+FB30:0000000000464222122C484442410800
+FB31:00000000007C040404240404047F0000
+FB32:000000000030080808440C1422420000
+FB33:00000000007E04040424040404040000
+FB34:00000000007E0202222A222222220000
+FB35:00000000003808080828080808080000
+FB36:0000000000300C0A0828080808080000
+FB37:00007FFE618E6FB6638E6FB66F8E7FFE7FFE63867DF671EE7DDE63DE7FFE0000
+FB38:0000000000464A4242524242427E0000
+FB39:00000000003808080820000000000000
+FB3A:00000000007E02020212020202020202
+FB3B:00000000007E020202120202027C0000
+FB3C:00000020203E02020212040408300000
+FB3D:00007FFE618E6FB6638E6FB66F8E7FFE7FFE638E7DB671B67DB6638E7FFE0000
+FB3E:000000000048483414222249414F0000
+FB3F:00007FFE618E6FB6638E6FB66F8E7FFE7FFE63867DBE718E7DBE63BE7FFE0000
+FB40:00000000001C040404240404043C0000
+FB41:00000000007E42424252424244780000
+FB42:00007FFE618E6FB6638E6FB66F8E7FFE7FFE6D866DF661867DBE7D867FFE0000
+FB43:00000000007E42424272020212020202
+FB44:00000000007E424242720212027E0000
+FB45:00007FFE618E6FB6638E6FB66F8E7FFE7FFE6D866DBE61867DF67D867FFE0000
+FB46:000000000042422418084402027E0000
+FB47:00000000007E222A2224282020202020
+FB48:00000000007E02020212020202020000
+FB49:0000000000494949494D4949497F0000
+FB4A:00000000003E2222222A222222620000
+FB4B:00000020003808080808080808080000
+FB4C:00000070007C040404040404047F0000
+FB4D:00000070007E020202020202027C0000
+FB4E:00000070007E424242720202027E0000
+FB4F:0000602020464222122C484442420000
+FB50:040A1E20080808080808080000000000
+FB51:102878802020202020201F0000000000
+FB52:000000000000000422423C0008000800
+FB53:000000000000000422423F0008000800
+FB54:00000000000000080404F80008000800
+FB55:00000000000000080404FF0008000800
+FB56:000000000000000422423C0014000800
+FB57:000000000000000422423F0014000800
+FB58:00000000000000080404F80014000800
+FB59:00000000000000080404FF0014000800
+FB5A:000000000000000422423C0014001400
+FB5B:000000000000000422423F0014001400
+FB5C:00000000000000080404F80014001400
+FB5D:00000000000000080404FF0014001400
+FB5E:000008000800000422423C0000000000
+FB5F:000008000800000422423F0000000000
+FB60:00000800080000080404F80000000000
+FB61:00000800080000080404FF0000000000
+FB62:000014001400000422423C0000000000
+FB63:000014001400000422423F0000000000
+FB64:00001400140000080404F80000000000
+FB65:00001400140000080404FF0000000000
+FB66:000020203838000422423C0000000000
+FB67:000020203838000422423F0000000000
+FB68:000010101C1C00080404F80000000000
+FB69:000010101C1C00080404FF0000000000
+FB6A:0008001200060A0642423C0000000000
+FB6B:0008001200060A0642423F0000000000
+FB6C:0010002400003824140CF80000000000
+FB6D:0010002400003824140CFB0000000000
+FB6E:000A000A00060A0642423C0000000000
+FB6F:000A000A00060A0642423F0000000000
+FB70:0028002800003824140CF80000000000
+FB71:0028002800003824140CFB0000000000
+FB72:00000000000000007E1020484048221C
+FB73:00000000000000007E1423484048211E
+FB74:0000000000000000700CFC0020002000
+FB75:0000000000000000700CFF0020002000
+FB76:00000000000000007E1020405440221C
+FB77:00000000000000007E1423405440211E
+FB78:0000000000000000700CFC0050000000
+FB79:0000000000000000700CFF0050000000
+FB7A:00000000000000007E2040544048221C
+FB7B:00000000000000007E2241544048211E
+FB7C:0000000000000000700CFC0028001000
+FB7D:0000000000000000700CFF0028001000
+FB7E:00000000000000007E2040544054221C
+FB7F:00000000000000007E2443544054211E
+FB80:0000000000000000700CFC0050005000
+FB81:0000000000000000700CFF0050005000
+FB82:000000000000080402427C0028000000
+FB83:000000000000080402427F0028000000
+FB84:000000280000080402427C0000000000
+FB85:000000280000080402427F0000000000
+FB86:000010002800080402427C0000000000
+FB87:000010002800080402427F0000000000
+FB88:002020383800080402427C0000000000
+FB89:002020383800080402427F0000000000
+FB8A:00000008001400000402020204483000
+FB8B:00000008001400000402030204483000
+FB8C:00000008080E0E000402020204483000
+FB8D:00000008080E0E000402030204483000
+FB8E:00000004081020403C827E0000000000
+FB8F:00000004081020403C827F0000000000
+FB90:00000004081020403C02FE0000000000
+FB91:00000004081020403C02FF0000000000
+FB92:00081024481020403C827E0000000000
+FB93:00081024481020403C827F0000000000
+FB94:00081024481020403C02FE0000000000
+FB95:00081024481020403C02FF0000000000
+FB96:00081024481020403C827E0010001000
+FB97:00081024481020403C827F0010001000
+FB98:00081024481020403C02FE0010001000
+FB99:00081024481020403C02FF0010001000
+FB9A:00500618620C30403C827E0000000000
+FB9B:00500618620C30403C827F0000000000
+FB9C:00500618620C30403C02FE0000000000
+FB9D:00500618620C30403C02FF0000000000
+FB9E:00000000000000000422424244380000
+FB9F:00000000000000000422434244380000
+FBA0:000010101C1C00000422424244380000
+FBA1:000010101C1C00000422434244380000
+FBA2:000010101C1C00080404F80000000000
+FBA3:000010101C1C00080404FB0000000000
+FBA4:001820182000101824243C0000000000
+FBA5:1820182004040C14243C070000000000
+FBA6:000000000000101824243C0000000000
+FBA7:000000000000000000102F4000000000
+FBA8:00000000000000000010F01010140800
+FBA9:00000000000000000010F31414140808
+FBAA:000000000000102C2A1A244000000000
+FBAB:000000000000102C2A1A274000000000
+FBAC:000000000000102C2A1AE40000000000
+FBAD:000000000000102C2A1AE70000000000
+FBAE:00000000000000000008141020407F00
+FBAF:000000000000000000000F1020407F00
+FBB0:00000000003040304008141020407F00
+FBB1:000000000030403040000F1020407F00
+FBB2:00001818000000000000000000000000
+FBB3:00000000000000000000000000001818
+FBB4:00000C6C600000000000000000000000
+FBB5:000000000000000000000000000C6C60
+FBB6:003030006C6C00000000000000000000
+FBB7:00000000000000000000003030006C6C
+FBB8:006C6C00181800000000000000000000
+FBB9:00000000000000000000006C6C001818
+FBBA:000C6C60031B18000000000000000000
+FBBB:000000000000000000000C6C60031B18
+FBBC:00000000000000000000000024241212
+FBBD:003030000C0C00000000000000000000
+FBBE:000000000000000000003030000C0C00
+FBBF:00000000000000000000000814242810
+FBC0:0010101C1C0000000000000000000000
+FBC1:00000000000000000000000010101C1C
+FBC2:00007FFE618E6FB6638E6FB66F8E7FFE7FFE71866FF66F866FBE71867FFE0000
+FBC3:00007FFE618E6FB6638E6FB66F8E7FFE7FFE718E6FF66FC66FF6718E7FFE0000
+FBC4:00007FFE618E6FB6638E6FB66F8E7FFE7FFE71B66FB66F866FF671F67FFE0000
+FBC5:00007FFE618E6FB6638E6FB66F8E7FFE7FFE71866FBE6F866FF671867FFE0000
+FBC6:00007FFE618E6FB6638E6FB66F8E7FFE7FFE71CE6FBE6F8E6FB671CE7FFE0000
+FBC7:00007FFE618E6FB6638E6FB66F8E7FFE7FFE71866FF66FEE6FDE71DE7FFE0000
+FBC8:00007FFE618E6FB6638E6FB66F8E7FFE7FFE71CE6FB66FCE6FB671CE7FFE0000
+FBC9:00007FFE618E6FB6638E6FB66F8E7FFE7FFE71CE6FB66FC66FF671CE7FFE0000
+FBCA:00007FFE618E6FB6638E6FB66F8E7FFE7FFE71866FB66F866FB671B67FFE0000
+FBCB:00007FFE618E6FB6638E6FB66F8E7FFE7FFE718E6FB66F8E6FB6718E7FFE0000
+FBCC:00007FFE618E6FB6638E6FB66F8E7FFE7FFE71C66FBE6FBE6FBE71C67FFE0000
+FBCD:00007FFE618E6FB6638E6FB66F8E7FFE7FFE718E6FB66FB66FB6718E7FFE0000
+FBCE:00007FFE618E6FB6638E6FB66F8E7FFE7FFE71866FBE6F8E6FBE71867FFE0000
+FBCF:00007FFE618E6FB6638E6FB66F8E7FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+FBD0:00007FFE618E6FB6638E6FB66F8E7FFE7FFE63CE6DB66DB66DB663CE7FFE0000
+FBD1:00007FFE618E6FB6638E6FB66F8E7FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000
+FBD2:00007FFE618E6FB6638E6FB66F8E7FFE7FFE63866DF66D866DBE63867FFE0000
+FBD3:100028020A120A2242423C0000000000
+FBD4:100028020A120A2242423F0000000000
+FBD5:20005004081020403C02FE0000000000
+FBD6:20005004081020403C02FF0000000000
+FBD7:001028281C10204C12121E0204483000
+FBD8:001028281C10204C12121F0204483000
+FBD9:000022140808000C12121E0204483000
+FBDA:000022140808000C12121F0204483000
+FBDB:000000080404000C12121E0204483000
+FBDC:000000080404000C12121F0204483000
+FBDD:002354533420408C12121F0204483000
+FBDE:000008001200000C12121E0204483000
+FBDF:000008001200000C12121F0204483000
+FBE0:000000000000000C12121E021C483000
+FBE1:000000000000000C12121F021C483000
+FBE2:000000081422000C12121E0204483000
+FBE3:000000081422000C12121F0204483000
+FBE4:000000000000000C5248443800100010
+FBE5:00000000000000004C52493000100010
+FBE6:00000000000000080804F80008000800
+FBE7:00000000000000080804FB0008000800
+FBE8:00000000000000080804F80000000000
+FBE9:00000000000000080804FB0000000000
+FBEA:0000004C504C50404444380000000000
+FBEB:0000004C504C504044443B0000000000
+FBEC:000000060806080002122C4000000000
+FBED:000000060806080002122D4000000000
+FBEE:00000003040304102A2A3C0808106000
+FBEF:00000003040304102A2A3D0808106000
+FBF0:00003033142344102A2A3C0808106000
+FBF1:00003033142344102A2A3D0808106000
+FBF2:00008853242304102A2A3C0808106000
+FBF3:00008853242304102A2A3D0808106000
+FBF4:00000023141304102A2A3C0808106000
+FBF5:00000023141304102A2A3D0808106000
+FBF6:000C100C1004040C5048443800100010
+FBF7:00000C100C1000044C52493000100010
+FBF8:00000608060800222212EC0020002000
+FBF9:00000608060802020206484442423C00
+FBFA:00000608060800020205484442423C00
+FBFB:00000608060800222212EC0000000000
+FBFC:0000000000000000044A484442423C00
+FBFD:00000000000000000000434442423C00
+FBFE:00000000000000080804F80028000000
+FBFF:00000000000000080804FB0028000000
+FC00:0000006080608C30407E20404840221C
+FC01:0000006080608C30407E20404040221C
+FC02:000000182018230408083C4040404040
+FC03:000000304030440202224446221C0000
+FC04:000000304030440202224446221C0014
+FC05:0000006080608C30407E20424840221C
+FC06:0000000000000C30407E20424040221C
+FC07:0000000020000C30407E20424040221C
+FC08:000000000000030408083C4140404040
+FC09:000000000000040202224446221C0100
+FC0A:000000000000040202224446221C0114
+FC0B:0000000028000C30407E20424040221C
+FC0C:0000000028000C30407E20404040221C
+FC0D:0000000028008C30407E20404040221C
+FC0E:000000050000030408083C4040404040
+FC0F:000000001400040202224446221C0014
+FC10:000000140004020222444642221C0014
+FC11:0000004000A00C30407E20404840221C
+FC12:000000100028030408083C4040404040
+FC13:000000200050040202224446221C0000
+FC14:000000200050040202224446221C0014
+FC15:000000700C020C30407822404040221C
+FC16:000000300C02030408083C4140404040
+FC17:000000700C020C30407E20424040221C
+FC18:000000300C02030408083C4040404040
+FC19:000004700C020C30407E20404840221C
+FC1A:000004700C020C30407E20404040221C
+FC1B:000000310C02030408083C4040404040
+FC1C:000000000000255A407E20424040221C
+FC1D:000000000000255A407E20404040221C
+FC1E:000000004000255A407E20404040221C
+FC1F:00000000000000000000000001940268040004001E0020002000200020002000
+FC20:0000000006091E28407E20404040221C
+FC21:00000000000000000038004401F80240040004001E0020002000200020002000
+FC22:0000000026091E28407E20404840221C
+FC23:0000000026091E28407E20404040221C
+FC24:0000000026891E28407E20404040221C
+FC25:00000000000000000138004401F80240040004001E0020002000200020002000
+FC26:000000202C323C20407E20404040221C
+FC27:0000000808080E0916103C4040404040
+FC28:000000080A080E0916103C4040404040
+FC29:0000003040381020407E20404840221C
+FC2A:000000000C100F0408083C4040404040
+FC2B:0000803040381020407E20404840221C
+FC2C:000008000C100F0408083C4040404040
+FC2D:00008020503010207E1020404840211E
+FC2E:00008020503010207E1020404040211E
+FC2F:00108020503010207E1020404840211E
+FC30:00000040102818081020103840404040
+FC31:00000400000C0A0602464844423C0000
+FC32:00000400000C0A0602464844423C0028
+FC33:0000005000205030407E20404840221C
+FC34:00002800102818081020103840404040
+FC35:00001400000C0A0602464844423C0000
+FC36:00001400000C0A0602464844423C0028
+FC37:000000048890A0C0BC827C0000000000
+FC38:0000000008102010207E20404840221C
+FC39:0000000008102010207E20404040221C
+FC3A:0000000008102090207E20404040221C
+FC3B:000000101012141814121C9090909060
+FC3C:000000040810201008103C4040404040
+FC3D:0000000000000010002000400080008000400880110011800880070000000000
+FC3E:0000000000000010002000400080008000400880110011800880070000000500
+FC3F:00001010101010207E1020404840211E
+FC40:00001010101010207E1020404040211E
+FC41:00001010105010207E1020404040211E
+FC42:000000080808080808083C4040404040
+FC43:00000002020202020206484442423C00
+FC44:000000020202020202064844423C0028
+FC45:0000000000000C30407E20404840221C
+FC46:0000000000000C30407E20404040221C
+FC47:0000000000200C30407E20404040221C
+FC48:000000000000030408083C4040404040
+FC49:000000000000020204084442423C0000
+FC4A:000000000000020204084442423C0028
+FC4B:0000000008000C30407E20404840221C
+FC4C:0000000008000C30407E20404040221C
+FC4D:0000000008200C30407E20404040221C
+FC4E:000000020000030408083C4040404040
+FC4F:000000000800040202224446221C0014
+FC50:000000040004020222444642221C0014
+FC51:000000103854523C407E20404840221C
+FC52:000000201834543808103C4040404040
+FC53:00000000060D150E02224446221C0000
+FC54:00000000060D150E02224446221C0014
+FC55:0000000000000C30407E204A4048221C
+FC56:0000000000000C30407E204A4040221C
+FC57:0000000000200C30407E204A4040221C
+FC58:000000000000030408083C4144404040
+FC59:0000000000000402220446621C010400
+FC5A:0000000000000402224446221C010450
+FC5B:101010002000080402427C0000000000
+FC5C:101010000000080402427C0000000000
+FC5D:000000000004040400064944423C0000
+FC5E:00046A241800547C0000000000000000
+FC5F:0054547C061866186000000000000000
+FC60:000006186000547C0000000000000000
+FC61:00040A047A00547C0000000000000000
+FC62:0054547C000618600000000000000000
+FC63:000008080800547C0000000000000000
+FC64:000018201822060A120A090808106000
+FC65:000018209822060A120A090808106000
+FC66:000000182018230408083C4040404040
+FC67:00000018209802060A2A454448300000
+FC68:000000000C100C1000064944423C0000
+FC69:000000000C100C1000064944423C0028
+FC6A:000000000002060A120A090808126000
+FC6B:000000000012060A120A090808126000
+FC6C:000000000000030408083D4040404040
+FC6D:00000000001002060A2A454448320000
+FC6E:000000000000000000064944423C0100
+FC6F:000000000000000000064944423C0128
+FC70:000005000002060A120A090808106000
+FC71:000005002002060A120A090808106000
+FC72:000000002800030408083C4040404040
+FC73:00000005001002060A2A454448300000
+FC74:000000000000050000064944423C0000
+FC75:000000000000050000064944423C0028
+FC76:000200050002060A120A090808106000
+FC77:000200050022060A120A090808106000
+FC78:000000100028030408083C4040404040
+FC79:00000200050012060A2A454448300000
+FC7A:000000000002000500064944423C0000
+FC7B:000000000002000500064944423C0028
+FC7C:000000000400040A07224446221C0000
+FC7D:000000000400040A07224446221C0014
+FC7E:000000000A00040A07224446221C0000
+FC7F:000000000A00040A07224446221C0014
+FC80:000000000000002122242830282C1201
+FC81:000000000000002122242830A8ACB241
+FC82:00010204081008040A11081C20202020
+FC83:00000102040810080446898C44380000
+FC84:00000102040810080446898C44380028
+FC85:00000008080808083C20304040404040
+FC86:00000008080808080E084442423C0000
+FC87:00000008080808080E084442423C0028
+FC88:0000000000404040404040402026180E
+FC89:000000000003040442A1BFA080808000
+FC8A:000000020002060A120A090808106000
+FC8B:000000021002060A120A090808106000
+FC8C:000000000200030408083C4040404040
+FC8D:00000002100002060A2A454448300000
+FC8E:000000000000020000064944423C0000
+FC8F:000000000000020000064944423C0028
+FC90:000000000010101000064944423C0000
+FC91:000000000002060A120A090808106500
+FC92:000000002002060A120A090808106500
+FC93:000000000000030408083C404A404040
+FC94:00000000001002060A2A454448300500
+FC95:000000000000000000064944423C0104
+FC96:000000000000000000064944423C0154
+FC97:02040608000C1420780CF00010000000
+FC98:02040608000C1420780CF00000000000
+FC99:02040608004C1420780CF00000000000
+FC9A:02040608000C1420780CF00000000000
+FC9B:00000004080C10002669E82824140C00
+FC9C:00000000000C1420780CF00004200000
+FC9D:00000000000C1420780CF00004000000
+FC9E:00000000200C1420780CF00004000000
+FC9F:00000000000006081010F80004000000
+FCA0:00000000000000002669E82825140C00
+FCA1:00000A00000C1420780CF00000200000
+FCA2:00000A00000C1420780CF00000000000
+FCA3:00000A00200C1420780CF00000000000
+FCA4:0000000A000006081010F80000000000
+FCA5:00000000000A00002669E82824140C00
+FCA6:0004000A000006081010F80000000000
+FCA7:006058041E20407E1862800000000000
+FCA8:0000000000001C021F28D80008000000
+FCA9:006058041E20407E1860801000000000
+FCAA:0000000000001C031F28D80000000000
+FCAB:086058041E20407E1860801000000000
+FCAC:0000000800001C031F28D80000000000
+FCAD:00000000000000001F94209440687E0018006000800010000000000000000000
+FCAE:00000000000000001F94209440687E0018006000800000000000000000000000
+FCAF:00000000000040001F94209440687E0018006000800000000000000000000000
+FCB0:00000000000115153E40E00000000000
+FCB1:0000000804140A24114820F040407E0018006000800000000000000000000000
+FCB2:0000000844140A24114820F040407E0018006000800000000000000000000000
+FCB3:00000000000000200050009011202FC021004000E00000000000000000000000
+FCB4:0080000804140A24114820F040407E0018006000800008000000000000000000
+FCB5:0080000804140A24114820F040407E0018006000800000000000000000000000
+FCB6:0080000844140A24114820F040407E0018006000800000000000000000000000
+FCB7:00000000000004200050009011202FC021004000E00000000000000000000000
+FCB8:101016191E2078061860000000000000
+FCB9:00000000121016193E40F04830000000
+FCBA:000030424C30407E1860801000000000
+FCBB:000000000030404C3040F04830000000
+FCBC:200030424C30407E1860801000000000
+FCBD:000000200030404C3040F04830000000
+FCBE:401028380810203E0C30C00800000000
+FCBF:401028380810203E0C30C00000000000
+FCC0:00401028388810203E0CF00000000000
+FCC1:00100010283808102020F02810000000
+FCC2:28001028380810203E0CF00008000000
+FCC3:00280010283808102020F02810000000
+FCC4:020408103008107E1860800800000000
+FCC5:020408103008107E1860800000000000
+FCC6:020408103088107E1860800000000000
+FCC7:00024448506078444424D80000000000
+FCC8:00040810204020101020F02810000000
+FCC9:0000101010101020780CF00000200000
+FCCA:0000101010101020780CF00000000000
+FCCB:0000101050101020780CF00000000000
+FCCC:00000008080808080808FC0200000000
+FCCD:000004040404041C2A3AF60000000000
+FCCE:00000000040A1C20780CF00000200000
+FCCF:00000000040A1C20780CF00000000000
+FCD0:00000000240A1C20780CF00000000000
+FCD1:0000000000040A1E2020F00000000000
+FCD2:00000400000C1420780CF00000200000
+FCD3:00000400000C1420780CF00000000000
+FCD4:00000400200C1420780CF00000000000
+FCD5:00000004000006081010F80000000000
+FCD6:00000000000004002669E82824140C00
+FCD7:003C1229293E407E1860801000000000
+FCD8:003C1229291E08102040E05020000000
+FCD9:202000782452523C2040800000000000
+FCDA:00000000000C1420780CF0000A200000
+FCDB:00000000000C1420780CF0000A000000
+FCDC:00000000200C1420780CF0000A000000
+FCDD:00000000000006081010F8000A000000
+FCDE:000000000000000C1250D55048281800
+FCDF:00000C100C3000102824D30000000000
+FCE0:0000000608061800246AE92824140C00
+FCE1:00000000000000102824D30008000000
+FCE2:0000000000000000246AE92825140C00
+FCE3:00000000001400102824D30000000000
+FCE4:0000000000140000246AE92824140C00
+FCE5:00000008001400102824D30000000000
+FCE6:0000000800140000246AE92824140C00
+FCE7:0000000000000000000000000000180024122212D1ED00000000000000000000
+FCE8:0000000000000000000000000000000026126912E8ED2800240014000C000000
+FCE9:0000000000000010000000280000180024122212D1ED00000000000000000000
+FCEA:0000000000000010000000280000000024126A12E9ED2800240014000C000000
+FCEB:00024448506070484C4AB10000000000
+FCEC:00040810204020101824F32810000000
+FCED:00000808080808081824F32810000000
+FCEE:00000000100000102824D30000000000
+FCEF:000000000800000C1252D15048281800
+FCF0:00000000000000102824D3000A000000
+FCF1:00000000000000000856D150482B1800
+FCF2:000C30022A1400000000FF0000000000
+FCF3:040A040A30022A140000FF0000000000
+FCF4:000A54200C3000000000FF0000000000
+FCF5:000000000808080E090E4844423C0000
+FCF6:000000000808080E090E4844423C0028
+FCF7:000000000000000608064844423C0000
+FCF8:000000000000000608064844423C0028
+FCF9:000000000008000608064844423C0000
+FCFA:000000000008000608064844423C0028
+FCFB:00000000000000000000000000000612091208EC4800440042003C0000000000
+FCFC:00000000000000000000000000000612091208EC4800440042003C0000002800
+FCFD:00000000001000000028000000000612091208EC4800440042003C0000000000
+FCFE:00000000001000000028000000000612091208EC4800440042003C0000002800
+FCFF:000000006058040E10380844423C0000
+FD00:000000006058040E38080844423C0028
+FD01:000000006058040E38090844423C0000
+FD02:000000006058040E38090844423C0028
+FD03:000000046058040E38080844423C0000
+FD04:000000026058040E38080844423C0028
+FD05:000000000205051E14100844423C0000
+FD06:000000000205051E14100844423C0028
+FD07:000000080205051E14100844423C0000
+FD08:000000080205051E14100844423C0028
+FD09:000004000A00255A407E20404840221C
+FD0A:000004000A00255A407E20404040221C
+FD0B:000004000A80255A407E20404040221C
+FD0C:000004000A00255A40603C4040404040
+FD0D:00000004000A00152A20202020408000
+FD0E:00000000000000152A20202020408000
+FD0F:0000000002050D162424202020408000
+FD10:0000000802050D162424202020408000
+FD11:000000000808080E090E4944423C0000
+FD12:000000000808080E090E4944423C0028
+FD13:000000000000000205064944423C0000
+FD14:000000000000000205064944423C0028
+FD15:000000000004000205064944423C0000
+FD16:000000000004000205064944423C0028
+FD17:000000000000000000000000000000000612091248ED440042003C0000000000
+FD18:000000000000000000000000000000000612091248ED440042003C0000002800
+FD19:000000000000001000000028000000000612091248ED440042003C0000000000
+FD1A:000000000000001000000028000000000612091248ED440042003C0000002800
+FD1B:0000000000061860180C138888700000
+FD1C:0000000000061860180C138888700050
+FD1D:0000000000061860180C13888A700000
+FD1E:0000000000061860180C13888A700050
+FD1F:0000000040061860180C138888700000
+FD20:0000000040061860180C138888700050
+FD21:0000000000040A0A3E29209088700000
+FD22:00000000040A0A3D2820108884780050
+FD23:0000000010040A0A3E29209088700000
+FD24:0000000010040A0A3E29209088700050
+FD25:000000001000280054AA81FC40904438
+FD26:000000001000280054AA81FC40804438
+FD27:000000001000A80054AA81FC40804438
+FD28:00000000080014004AB580C070808080
+FD29:00000000000004000A00152A20204080
+FD2A:00000000000000000000152A20204080
+FD2B:0000000000000002050D162424408000
+FD2C:0000000000000012050D162424408000
+FD2D:00200000005004000A2411D820007F8018006000800008000000000000000000
+FD2E:00200000005004000A2411D820007F8018006000800000000000000000000000
+FD2F:00200000005024000A2411D820007F8018006000800000000000000000000000
+FD30:0000000000200000005004000A2411D820007000880000000000000000000000
+FD31:0000000000000000000000000000002423D86400E8002800240014000C000000
+FD32:0000000000000020000000500000002423D86400E8002800240014000C000000
+FD33:00000010101016191E20D02000000000
+FD34:000000000000000000000000000002007A121592F06D00002000000000000000
+FD35:000000000000000000000000000002007A121592F06D00000000000000000000
+FD36:000000000000000000000000400002007A121592F06D00000000000000000000
+FD37:000000000000000000100000002802007A121592F06D00002000000000000000
+FD38:000000000000000000100000002802007A121592F06D00000000000000000000
+FD39:000000000000000000100000402802007A121592F06D00000000000000000000
+FD3A:00000010101016191E22D12000000000
+FD3B:00000010101016191E22D12000000000
+FD3C:010204111214101010100F0000000000
+FD3D:01020411121410101010100000000000
+FD3E:0000007E018C023004C00F000A0035806AC035800A000F0004C00230018C007E
+FD3F:00007E0031800C40032000F0005001AC035601AC005000F003200C4031807E00
+FD40:00007FFE618E6FB663B66FB66F8E7FFE7FFE6DCE6DB661B67DB67DCE7FFE0000
+FD41:00007FFE618E6FB663B66FB66F8E7FFE7FFE6DEE6DCE61EE7DEE7DC67FFE0000
+FD42:00007FFE618E6FB663B66FB66F8E7FFE7FFE6D866DF661867DBE7D867FFE0000
+FD43:00007FFE618E6FB663B66FB66F8E7FFE7FFE6D8E6DF661C67DF67D8E7FFE0000
+FD44:00007FFE618E6FB663B66FB66F8E7FFE7FFE6DB66DB661867DF67DF67FFE0000
+FD45:00007FFE618E6FB663B66FB66F8E7FFE7FFE6D866DBE61867DF67D867FFE0000
+FD46:00007FFE618E6FB663B66FB66F8E7FFE7FFE6DCE6DBE618E7DB67DCE7FFE0000
+FD47:00007FFE618E6FB663B66FB66F8E7FFE7FFE6D866DF661EE7DDE7DDE7FFE0000
+FD48:00007FFE618E6FB663B66FB66F8E7FFE7FFE6DCE6DB661CE7DB67DCE7FFE0000
+FD49:00007FFE618E6FB663B66FB66F8E7FFE7FFE6DCE6DB661C67DF67DCE7FFE0000
+FD4A:00007FFE618E6FB663B66FB66F8E7FFE7FFE6D866DB661867DB67DB67FFE0000
+FD4B:00007FFE618E6FB663B66FB66F8E7FFE7FFE6D8E6DB6618E7DB67D8E7FFE0000
+FD4C:00007FFE618E6FB663B66FB66F8E7FFE7FFE6DC66DBE61BE7DBE7DC67FFE0000
+FD4D:00007FFE618E6FB663B66FB66F8E7FFE7FFE6D8E6DB661B67DB67D8E7FFE0000
+FD4E:00007FFE618E6FB663B66FB66F8E7FFE7FFE6D866DBE618E7DBE7D867FFE0000
+FD4F:00007FFE618E6FB663B66FB66F8E7FFE7FFE6D866DBE618E7DBE7DBE7FFE0000
+FD50:00000000000000000028020005040084FFFC5000210000000000000000000000
+FD51:000000000000000000141080294204227FFF0000100000000000000000000000
+FD52:00000000000000000028210052840844FFFC0000200000000000000000000000
+FD53:00000000000000000028020005040084FFFC5000200000000000000000000000
+FD54:00000000000000000028020005040084FFFC2800100000000000000000000000
+FD55:00000000000002000028020005040084FFFC2800100000000000000000000000
+FD56:000000000000000000282000500408047FFC0280210000000000000000000000
+FD57:00000000000000000028200050040804FFFC0280010000000000000000000000
+FD58:0000000000000000000020085014080217FF2140408840004000240018000000
+FD59:00000000000000000000201050280804FFFC0280011000000000000000000000
+FD5A:0000000000000000000000084814540253FF48A0444044003800000028000000
+FD5B:0000000000000000000000084814540253FF48A0444044003800000000000000
+FD5C:00000000000000000000210052950855FFFF0000200000000000000000000000
+FD5D:00000000000000000000210052950855FFFF0000010000000000000000000000
+FD5E:0000000000000000000001009295A855A7FF9000890088007000000000000000
+FD5F:000000000000000000004000A02A102A2FFF4500820080008000480030000000
+FD60:000000000000000000002000502A082AFFFE0280010000000000000000000000
+FD61:000000000000000000002000502A082AFFFE0280210000000000000000000000
+FD62:000000000000000000002000502A082A7FFF4280410040004000000000000000
+FD63:000000000000000000000000002A002AFFFE2A80110000000000000000000000
+FD64:000000000000000000004204A52A10AA2FD74000800080008000480030000000
+FD65:00000000000000000000210252950855FFEE0000000000000000000000000000
+FD66:000000000000000000002004502A082A7FD74280410040004000000000000000
+FD67:000000000008000000144200A52A10AAFFFF8000800080008000000000000000
+FD68:000000000008000000140200052A00AAFFFE2800100000000000000000000000
+FD69:0000000000040000000A01009295A855A7FF9000890088007000000050000000
+FD6A:000000000008200000142000502A082A17FF2280410040004000240018000000
+FD6B:000000000008200000142000502A082AFFFE0280010000000000000000000000
+FD6C:000000000008000000142000502A082A7FFF4280410040004000000000000000
+FD6D:000000000008000000140000002A002AFFFE2A80110000000000000000000000
+FD6E:0000000000000002000001029295A855A7EB9000880088007000000000000000
+FD6F:000000000000000400004204A52A10AAFFD78000800080008000000000000000
+FD70:000000000000020000000204052A00AAFFD42800100000000000000000000000
+FD71:000000000000002000202020502C093216FF2280410040004000240018000000
+FD72:000000000000002000202020502C0832FFFC0280010000000000000000000000
+FD73:000000000000002000200020002C0032FFFC2A80110000000000000000000000
+FD74:000000000000002000200020902CA832A7FF9280890088007000000050000000
+FD75:00000000000000000000211E5292084C7FF34000410040004000000000000000
+FD76:00000000000000000000101E2812040C3FF32140208020002000000000000000
+FD77:000000000000000000000000000C0010FFFE5280210000000000000000000000
+FD78:00000000000000000000001E9012A80CA7F39140888088007000000000000000
+FD79:00000000000000080000101E2812040C3FF32140208020002000000000000000
+FD7A:00000000000000080000001E9012A80CA7F39140888088007000000050000000
+FD7B:00000000000000080000001E9012A80CA7F39140888088007000000000000000
+FD7C:000000000000000800002108529408547FEB4000400040004000000000000000
+FD7D:0000000000080000000811142A8C2844DFFC0000000000000000000000000000
+FD7E:000000000000000A00002084514A094A16F72000400040004000240018000000
+FD7F:00000000000000140000210852940A947DEF4000400040004000000000000000
+FD80:00000000000000020002084214A202121FFD1000100010001000000000000000
+FD81:00000000000000020002004224A22A1229FD2400220022001C00000014000000
+FD82:00000000000000020002004224A22A1229FD2400220022001C00000000000000
+FD83:00000000000000080008210852880848FFF00000210000000000000000000000
+FD84:0000000000000002000220825142082217FD2000408050004000240018000000
+FD85:000000000000008200022082514208227FFD4000400040004000000000000000
+FD86:00000000000001040004010402840044FFF82800100000000000000000000000
+FD87:000000000000000200021002280204020BFD10A020402000200012000C000000
+FD88:00000000000000080008200850080808FFF00280010000000000000000000000
+FD89:00000000000000000000210052800848FFF40014200800000000000000000000
+FD8A:00000000000000000000020005000080FFFC5014200800000000000000000000
+FD8B:0000000000000000000001009280A840A7FF9014880888007000000050000000
+FD8C:00000000000000000000210052800848FFF40014010800000000000000000000
+FD8D:00000000000000000000010002800048FFF42814110800000000000000000000
+FD8E:00000000000000000000210052800848FFF40014200800000000000000000000
+FD8F:00000000000000000000010002800048FFF42814100800000000000000000000
+FD90:00007FFE618E6FB663B66FB66F8E7FFE7FFE73CE6DB671B67DB673CE7FFE0000
+FD91:00007FFE618E6FB663B66FB66F8E7FFE7FFE73EE6DCE71EE7DEE73C67FFE0000
+FD92:00000000000000000000210052800848FFF40014010800000000000000000000
+FD93:000000000000001800042012502A082AFFDC0280210000000000000000000000
+FD94:000000000000001800040012002A002AFFDC2A80110000000000000000000000
+FD95:00000000000000000008010002880048FFF02800100000000000000000000000
+FD96:0000000000000000000400804944542453FB4800440044003800000028000000
+FD97:000000000000000000042080514408247FFB4000408040004000000000000000
+FD98:00000000000000000008010002880048FFF02800110000000000000000000000
+FD99:0000000000000000000400809144A824A7FB9000888088007000000000000000
+FD9A:0000000000000000000400004804540453FB48A0444044003800000028000000
+FD9B:0000000000000000000400004804540453FB48A0444044003800000000000000
+FD9C:000000000000000000000800140402441FBB10A0104A10001000000000000000
+FD9D:00000000000000000000000000020002FFFC2940109400000000000000000000
+FD9E:0000000000000080000000809142A822A7FD9000880488007000000050000000
+FD9F:0000000000000000000A00809142A822A7FD9000884088007000000050000000
+FDA0:0000000000000000000A00809142A822A7FD9000888088007000000000000000
+FDA1:0000000000000080000A00809142A822A7FD9000880088007000000050000000
+FDA2:0000000000000080000A00809142A822A7FD9000880088007000000000000000
+FDA3:0000000000000000000A00004802540253FD48A0444044003800000028000000
+FDA4:0000000000000000000A00004802540253FD48A0444044003800000000000000
+FDA5:0000000000000000000000089014A802A7FF9140888888007000000050000000
+FDA6:0000000000000000000001089294A842A7FF9000880888007000000000000000
+FDA7:0000000000000000000000089014A802A7FF9140888888007000000000000000
+FDA8:0000000000000100000001009295A855A7FF9000880088007000000050000000
+FDA9:0000000000000000000001029295A855A7EF9000880088007000000050000000
+FDAA:0000000000040000000A01009295A855A7FF9000880088007000000050000000
+FDAB:0000000000000002000001029295A855A7FF9000880088007000000050000000
+FDAC:0000000000000004000400844944542453FB4800448044003800000028000000
+FDAD:0000000000000004000400044804540453FB48A0444044003800000028000000
+FDAE:0000000000000000000000804944542453FB4800440A44003800000028000000
+FDAF:0000000000000000000000804944542453FB4800448A44003800000028000000
+FDB0:0000000000000000000000004804540453FB48A0444A44003800000028000000
+FDB1:0000000000000000000000004800540053FF48AA444444003800000028000000
+FDB2:000000000000000A00000004480A540A53F748A0444044003800000028000000
+FDB3:0000000000000000000400809144A824A7FB9000880088007000000050000000
+FDB4:00000000000000140000200850140814FFE80280010000000000000000000000
+FDB5:00000000000000080008010802880048FFF82800100000000000000000000000
+FDB6:00000000000000000000001E9012A80CA7F39140888088007000000050000000
+FDB7:0000000000000006001800209018A80EA7F19280890088007000000050000000
+FDB8:00000000000000000008210052880848FFF80000010000000000000000000000
+FDB9:0000000000000080000000809140A820A7FF900A880488007000000050000000
+FDBA:00000000000000080008010802880048FFF82800110000000000000000000000
+FDBB:0000000000000006001820205018080E7FF14280410040004000000000000000
+FDBC:000000000000000400042084514408247FFB4000408040004000000000000000
+FDBD:00000000000000000002104028A204120BFD100020402000200012000C000000
+FDBE:0000000000000000000001089294A842A7FF9000880888007000000050000000
+FDBF:0000000000000000000001089294A842A7FF9000890088007000000050000000
+FDC0:0000000000000000000000809140A820A7FF900A884488007000000050000000
+FDC1:000000000000000400000004480A540A53F748A0444044003800000028000000
+FDC2:0000000000000000000000809142A822A7FF9000880488007000000050000000
+FDC3:0000000000000003000C001000080004FFF82940108000000000000000000000
+FDC4:00000000000000000000010002860048FFFF2800110000000000000000000000
+FDC5:000000000000000000000004002A002AFFDC5500220000000000000000000000
+FDC6:0000000000000100000001009295A855A7FF9000880088007000000050000000
+FDC7:0000000000000000000400809144A824A7FB9000888088007000000050000000
+FDC8:00007FFE618E6FB663B66FB66F8E7FFE7FFE71CE6FB66FCE6FB671CE7FFE0000
+FDC9:00007FFE618E6FB663B66FB66F8E7FFE7FFE71CE6FB66FC66FF671CE7FFE0000
+FDCA:00007FFE618E6FB663B66FB66F8E7FFE7FFE71866FB66F866FB671B67FFE0000
+FDCB:00007FFE618E6FB663B66FB66F8E7FFE7FFE718E6FB66F8E6FB6718E7FFE0000
+FDCC:00007FFE618E6FB663B66FB66F8E7FFE7FFE71C66FBE6FBE6FBE71C67FFE0000
+FDCD:00007FFE618E6FB663B66FB66F8E7FFE7FFE718E6FB66FB66FB6718E7FFE0000
+FDCE:00007FFE618E6FB663B66FB66F8E7FFE7FFE71866FBE6F8E6FBE71867FFE0000
+FDCF:00007FFE618E6FB663B66FB66F8E7FFE7FFE71866FBE6F8E6FBE71BE7FFE0000
+FDD0:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE3CFEDB7EDB7EDB7E3CFFFFFFFFF
+FDD1:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE3DFED9FEDDFEDDFE38FFFFFFFFF
+FDD2:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE387EDF7ED87EDBFE387FFFFFFFF
+FDD3:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE38FEDF7EDC7EDF7E38FFFFFFFFF
+FDD4:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE3AFEDAFED87EDEFE3EFFFFFFFFF
+FDD5:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE387EDBFED87EDF7E387FFFFFFFF
+FDD6:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE3CFEDBFED8FEDB7E3CFFFFFFFFF
+FDD7:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE387EDF7EDEFEDDFE3DFFFFFFFFF
+FDD8:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE3CFEDB7EDCFEDB7E3CFFFFFFFFF
+FDD9:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE3CFEDB7EDC7EDF7E3CFFFFFFFFF
+FDDA:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE3CFEDB7ED87EDB7E3B7FFFFFFFF
+FDDB:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE38FEDB7ED8FEDB7E38FFFFFFFFF
+FDDC:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE3CFEDB7EDBFEDB7E3CFFFFFFFFF
+FDDD:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE38FEDB7EDB7EDB7E38FFFFFFFFF
+FDDE:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE387EDBFED8FEDBFE387FFFFFFFF
+FDDF:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE387EDBFED8FEDBFE3BFFFFFFFFF
+FDE0:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE1CFEFB7E3B7EFB7E1CFFFFFFFFF
+FDE1:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE1DFEF9FE3DFEFDFE18FFFFFFFFF
+FDE2:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE187EFF7E387EFBFE187FFFFFFFF
+FDE3:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE18FEFF7E3C7EFF7E18FFFFFFFFF
+FDE4:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE1AFEFAFE387EFEFE1EFFFFFFFFF
+FDE5:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE187EFBFE387EFF7E187FFFFFFFF
+FDE6:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE1CFEFBFE38FEFB7E1CFFFFFFFFF
+FDE7:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE187EFF7E3EFEFDFE1DFFFFFFFFF
+FDE8:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE1CFEFB7E3CFEFB7E1CFFFFFFFFF
+FDE9:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE1CFEFB7E3C7EFF7E1CFFFFFFFFF
+FDEA:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE1CFEFB7E387EFB7E1B7FFFFFFFF
+FDEB:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE18FEFB7E38FEFB7E18FFFFFFFFF
+FDEC:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE1CFEFB7E3BFEFB7E1CFFFFFFFFF
+FDED:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE18FEFB7E3B7EFB7E18FFFFFFFFF
+FDEE:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE187EFBFE38FEFBFE187FFFFFFFF
+FDEF:FFFFFFFFE18FEFB7E3B7EFB7EF8FFFFFFFFFE187EFBFE38FEFBFE1BFFFFFFFFF
+FDF0:00000000040004000400040C049204A20B7C3020400040003FF0000000000000
+FDF1:0000000002500200022002500230021005E01800200020001FF8000000000000
+FDF2:020002000240014205820602009208921892289218920F600000000000000000
+FDF3:0000000C003000C40104010400C412241E14121411E424004000000000000000
+FDF4:01800604008A0A84050A00300604180A001C0460048002FE120C0D3000C00030
+FDF5:00000000040004000400240C549234A22B7C4020380014002800200020000000
+FDF6:0000000010001000100010009254955563A901020E1C00000000000000000000
+FDF7:000000000020002010203020502633280CDE0000050000000000000000000000
+FDF8:00000000100010001000100012A412AA2D464002300428185000400040000000
+FDF9:00000000040004000400040C049204A20B7C082050004C004200240018000000
+FDFA:2AA06AA0AAAA6A2D145680C480287FC82029602ABFD7440204553D035351A0A6
+FDFB:000008000804480A480137FF000002A412A032A452AA32210CDF000000040000
+FDFC:0000028002800280028002A002A0224222021CA2000C00000000000000000000
+FDFD:70A95FFF7000C5D5145515D5557D75C0C03B50295FFF7000758554957F9DC030
+FDFE:00007FFE618E6FB663B66FB66F8E7FFE7FFE61866FBE638E6FBE6F867FFE0000
+FDFF:00007FFE618E6FB663B66FB66F8E7FFE7FFE61866FBE638E6FBE6FBE7FFE0000
+FE00:555580000001A2382241A238140588380001808001818280008183E00001AAAA
+FE01:555580000001A2382241A238140588380001838000418180020183C00001AAAA
+FE02:555580000001A2382241A238140588380001838000418180004183800001AAAA
+FE03:555580000001A2382241A2381405883800018240024183C0004180400001AAAA
+FE04:555580000001A2382241A23814058838000183C002018380004183800001AAAA
+FE05:555580000001A2382241A23814058838000181C002018380024181800001AAAA
+FE06:555580000001A2382241A23814058838000183C000418080010181000001AAAA
+FE07:555580000001A2382241A238140588380001818002418180024181800001AAAA
+FE08:555580000001A2382241A2381405883800018180024181C0004183800001AAAA
+FE09:555580000001A2382241A23814058838000188301849A8480849BE300001AAAA
+FE0A:555580000001A2382241A23814058838000188101831A8500811BE7C0001AAAA
+FE0B:555580000001A2382241A23814058838000188701809A8300841BE780001AAAA
+FE0C:555580000001A2382241A23814058838000188701809A8300809BE700001AAAA
+FE0D:555580000001A2382241A23814058838000188481849A8780809BE080001AAAA
+FE0E:555580000001A2382241A23814058838000188781841A8700809BE700001AAAA
+FE0F:555580000001A2382241A23814058838000188381841A8700849BE300001AAAA
+FE10:00000000000C0004000400080000000000000000000000000000000000000000
+FE11:0000000000200010000800080000000000000000000000000000000000000000
+FE12:0000000000000018002400240018000000000000000000000000000000000000
+FE13:00000000000C000C000000000000000C000C0000000000000000000000000000
+FE14:00000000000C000C000000000000000C00040004000800000000000000000000
+FE15:0000000000040004000400040004000400040000000400040000000000000000
+FE16:0000000000780084008400040008001000100000001000100000000000000000
+FE17:000000000000000000003FFC2004200423C42C34300C20040000000000000000
+FE18:000000000000000000002004300C2C3423C4200420043FFC0000000000000000
+FE19:00000000000C000C000000000000000C000C000000000000000C000C00000000
+FE1A:00007FFE61866FBE638E6FBE6F867FFE7FFE7B8673B67B867BB671B67FFE0000
+FE1B:00007FFE61866FBE638E6FBE6F867FFE7FFE7B8E73B67B8E7BB6718E7FFE0000
+FE1C:00007FFE61866FBE638E6FBE6F867FFE7FFE7BC673BE7BBE7BBE71C67FFE0000
+FE1D:00007FFE61866FBE638E6FBE6F867FFE7FFE7B8E73B67BB67BB6718E7FFE0000
+FE1E:00007FFE61866FBE638E6FBE6F867FFE7FFE7B8673BE7B8E7BBE71867FFE0000
+FE1F:00007FFE61866FBE638E6FBE6F867FFE7FFE7B8673BE7B8E7BBE71BE7FFE0000
+FE20:000F3040000000000000000000000000
+FE21:00F00C02000000000000000000000000
+FE22:001E2140000000000000000000000000
+FE23:00028478000000000000000000000000
+FE24:00001F00000000000000000000000000
+FE25:0000F800000000000000000000000000
+FE26:0000FF00000000000000000000000000
+FE27:00007FFE61866FBE638E6FBE6F867FFE7FFE61867DF661EE6FDE61DE7FFE0000
+FE28:00007FFE61866FBE638E6FBE6F867FFE7FFE61CE7DB661CE6FB661CE7FFE0000
+FE29:00007FFE61866FBE638E6FBE6F867FFE7FFE61CE7DB661C66FF661CE7FFE0000
+FE2A:00007FFE61866FBE638E6FBE6F867FFE7FFE61867DB661866FB661B67FFE0000
+FE2B:00007FFE61866FBE638E6FBE6F867FFE7FFE618E7DB6618E6FB6618E7FFE0000
+FE2C:00007FFE61866FBE638E6FBE6F867FFE7FFE61C67DBE61BE6FBE61C67FFE0000
+FE2D:00007FFE61866FBE638E6FBE6F867FFE7FFE618E7DB661B66FB6618E7FFE0000
+FE2E:00007FFE61866FBE638E6FBE6F867FFE7FFE61867DBE618E6FBE61867FFE0000
+FE2F:00007FFE61866FBE638E6FBE6F867FFE7FFE61867DBE618E6FBE61BE7FFE0000
+FE30:0000000000000000018001800000000000000000018001800000000000000000
+FE31:0000000000800080008000800080008000800080008000800080008000000000
+FE32:0000000000000000008000800080008000800080008000800000000000000000
+FE33:00404040404040404040404040404000
+FE34:40808040202040808040202040808040
+FE35:000000000000000000000000000000000000000007E018182004400200000000
+FE36:0000000040022004181807E00000000000000000000000000000000000000000
+FE37:0000000000000000000000000000000000000000000001803E7C400200000000
+FE38:0000000040023E7C018000000000000000000000000000000000000000000000
+FE39:000000000000000000000000000000000000000000001FF82004400200000000
+FE3A:00000000400220041FF800000000000000000000000000000000000000000000
+FE3B:0000000000000000000000000000000000007FFE7FFE781E6006400200000000
+FE3C:0000000040026006781E7FFE7FFE000000000000000000000000000000000000
+FE3D:0000000000000000000000000000018006601818618606601818600600000000
+FE3E:0000000060061818066061861818066001800000000000000000000000000000
+FE3F:0000000000000000000000000000000000000000018006601818600600000000
+FE40:0000000060061818066001800000000000000000000000000000000000000000
+FE41:000000000000000000000000000000007FFE0002000200020002000200000000
+FE42:00000000400040004000400040007FFE00000000000000000000000000000000
+FE43:00000000000000000000000000007FFE40027FFA000A000A000A000E00000000
+FE44:0000000070005000500050005FFE40027FFE0000000000000000000000000000
+FE45:0000000000700038001800180000000000000000000000000000000000000000
+FE46:00000000007800240014000C0000000000000000000000000000000000000000
+FE47:000000000000000000000000000000007FFE4002400240024002000000000000
+FE48:00000000000040024002400240027FFE00000000000000000000000000000000
+FE49:000039CE00000000000000000000000000000000000000000000000000000000
+FE4A:00007DBE00000000000000000000000000000000000000000000000000000000
+FE4B:0C30924961860000000000000000000000000000000000000000000000000000
+FE4C:0C30924961860C30924961860000000000000000000000000000000000000000
+FE4D:0000000000000000000000000000000000000000000000000000000039CE0000
+FE4E:000000000000000000000000000000000000000000000000000000007DBE0000
+FE4F:00000000000000000000000000000000000000000000000000000C3092496186
+FE50:0000000000000000000000000000000000000000000000000180010002000000
+FE51:0000000000000000000000000000000000000000000000000200010001800000
+FE52:0000000000000000000000000000000000000000000000000180018000000000
+FE53:00007FFE61866FBE638E6FBE6F867FFE7FFE618E6FF661C67DF6618E7FFE0000
+FE54:0000000000000000000000000000000000000180018000000180010002000000
+FE55:0000000000000000000000000000000000000180018000000180018000000000
+FE56:0000000000000000000000000000000001000280008001000000010000000000
+FE57:0000000000000000000000000000000000800080008000800000008000000000
+FE58:0000000000000000000000000000000000000000000007C00000000000000000
+FE59:0000000000000000000000000000000000800100010001000100008000000000
+FE5A:0000000000000000000000000000000001000080008000800080010000000000
+FE5B:0000000000000000000000000000000000400080018000800080004000000000
+FE5C:0000000000000000000000000000000002000100018001000100020000000000
+FE5D:0000000000000000000000000000000001C0010001000100010001C000000000
+FE5E:0000000000000000000000000000000003800080008000800080038000000000
+FE5F:000000000000000000000000000000000000028007C0028007C0028000000000
+FE60:0000000000000000000000000000000000000100028001000280014000000000
+FE61:0000000000000000000000000000000000000280010003800100028000000000
+FE62:0000000000000000000000000000000000000100010007C00100010000000000
+FE63:0000000000000000000000000000000000000000000003C00000000000000000
+FE64:0000000000000000000000000000000000000040008001000080004000000000
+FE65:0000000000000000000000000000000000000200010000800100020000000000
+FE66:000000000000000000000000000000000000000003C0000003C0000000000000
+FE67:00007FFE61866FBE638E6FBE6F867FFE7FFE73866FF663EE6DDE73DE7FFE0000
+FE68:0000000000000000000000000000000000000200010000800040000000000000
+FE69:0000000000000000000000000000000000000380050003800140038000000000
+FE6A:0000000000000000000000000000000002000240008001000240004000000000
+FE6B:000000000000000000000000000000000180024002C002C00200018000000000
+FE6C:00007FFE61866FBE638E6FBE6F867FFE7FFE73C66FBE63BE6DBE73C67FFE0000
+FE6D:00007FFE61866FBE638E6FBE6F867FFE7FFE738E6FB663B66DB6738E7FFE0000
+FE6E:00007FFE61866FBE638E6FBE6F867FFE7FFE73866FBE638E6DBE73867FFE0000
+FE6F:00007FFE61866FBE638E6FBE6F867FFE7FFE73866FBE638E6DBE73BE7FFE0000
+FE70:000C300C300000000000000000000000
+FE71:000C300C300000000000FF0000000000
+FE72:00060632143800000000000000000000
+FE73:00000010100C00000000000000000000
+FE74:000000000000000000000C300C300000
+FE75:00007FFE61866FBE638E6FBE6F867FFE7FFE61867DBE7B8677F677867FFE0000
+FE76:0000000C300000000000000000000000
+FE77:0000000C300000000000FF0000000000
+FE78:00001028281C10204000000000000000
+FE79:00001028281C10204000FF0000000000
+FE7A:00000000000000000000000000000C30
+FE7B:00000000000000000000FF0000000C30
+FE7C:00000004145860000000000000000000
+FE7D:00000004145860000000FF0000000000
+FE7E:00000018242418000000000000000000
+FE7F:00000018242418000000FF0000000000
+FE80:000000000000001C203C102000000000
+FE81:00013E40080808080808080000000000
+FE82:000870802020202020201F0000000000
+FE83:18201820080808080808080000000000
+FE84:304030402020202020201F0000000000
+FE85:00000C100C10000C12121E0204483000
+FE86:00000C100C10000C12121F0204483000
+FE87:0000000008080808080808000C100C10
+FE88:000000002020202020201F0030403040
+FE89:00000000304030400046484846423C00
+FE8A:000000003040304000404342423C0000
+FE8B:0000000C100C10000404F80000000000
+FE8C:0000000C100C10000404FB0000000000
+FE8D:00000008080808080808080000000000
+FE8E:000000202020202020201F0000000000
+FE8F:000000000000000422423C0000080000
+FE90:000000000000000422423F0000080000
+FE91:00000000000000080404FC0000100000
+FE92:00000000000000080404FF0000100000
+FE93:000000240000182422221C0000000000
+FE94:0000001200040C14243C070000000000
+FE95:000000001400000422423C0000000000
+FE96:000000001400000422423F0000000000
+FE97:00000000280000080404F80000000000
+FE98:00000000280000080404FF0000000000
+FE99:000010002400000422423C0000000000
+FE9A:000010002400000422423F0000000000
+FE9B:00002000480000080404F80000000000
+FE9C:00002000480000080404FF0000000000
+FE9D:00000000000000007E1020404840221C
+FE9E:00000000000000007E1423404840211E
+FE9F:00000000000000003806FE0010000000
+FEA0:00000000000000003806FF0010000000
+FEA1:00000000000000007E1020404040221C
+FEA2:00000000000000007E1423404040211E
+FEA3:0000000000000000700CFC0000000000
+FEA4:0000000000000000700CFF0000000000
+FEA5:00000000001000007E1020404040221C
+FEA6:00000000001000007E1423404040211E
+FEA7:0000000000200000700CFC0000000000
+FEA8:0000000000200000700CFF0000000000
+FEA9:000000000000080402427C0000000000
+FEAA:000000000000080402427F0000000000
+FEAB:000000002000080402427C0000000000
+FEAC:000000002000080402427F0000000000
+FEAD:00000000000000000402020204483000
+FEAE:00000000000000000402030204483000
+FEAF:00000000001000000402020204483000
+FEB0:00000000001000000402030204483000
+FEB1:000000000000000115155E4848300000
+FEB2:000000000000000115155F4848300000
+FEB3:00000000000000022A2AFC0000000000
+FEB4:00000000000000022A2AFF0000000000
+FEB5:00000008001200000115155E48483000
+FEB6:000000080012000115155F4848300000
+FEB7:00000010002400022A2AFC0000000000
+FEB8:00000010002400022A2AFF0000000000
+FEB9:000000000000000006194E4848300000
+FEBA:000000000000000006194F4848300000
+FEBB:00000000000000000C52FC0000000000
+FEBC:00000000000000000C52FF0000000000
+FEBD:000000000004000006194E4848300000
+FEBE:000000000004000006194F4848300000
+FEBF:00000000000800000C52FC0000000000
+FEC0:00000000000800000C52FF0000000000
+FEC1:000000202020202C32227C0000000000
+FEC2:000000202020202C32227F0000000000
+FEC3:000000202020202C3222FC0000000000
+FEC4:000000202020202C3222FF0000000000
+FEC5:000000202420202C32227C0000000000
+FEC6:000000202420202C32227F0000000000
+FEC7:000000202420202C3222FC0000000000
+FEC8:000000202420202C3222FF0000000000
+FEC9:000000000000001824201C204040423C
+FECA:000000000000000030301F204040423C
+FECB:00000000000000182420FE0000000000
+FECC:00000000000000181808F70000000000
+FECD:000000000800001824201C204040423C
+FECE:000000000010000030301F204040423C
+FECF:00000000080000182420FE0000000000
+FED0:00000000080000181808F70000000000
+FED1:0000000800060A0642423C0000000000
+FED2:0000000800060A0642423F0000000000
+FED3:0000001000003824140CF80000000000
+FED4:0000001000003824140CFB0000000000
+FED5:000000002400001C120A264244380000
+FED6:000000002400001C120A274244380000
+FED7:0000004800003824140CF80000000000
+FED8:0000004800003824140CFB0000000000
+FED9:000000020A120A2242423C0000000000
+FEDA:000000020A120A2242423F0000000000
+FEDB:00000004081020403C02FE0000000000
+FEDC:00000004081020403C02FF0000000000
+FEDD:000000020202020202224242443C0000
+FEDE:000000020202020202234242443C0000
+FEDF:00000004040404040404F80000000000
+FEE0:00000004040404040404FB0000000000
+FEE1:00000000000000001C061E2020202020
+FEE2:00000000000000001C061F2020202020
+FEE3:00000000000000081432EE0000000000
+FEE4:00000000000000081432EF0000000000
+FEE5:00000000001000000422424244380000
+FEE6:00000000001000000422434244380000
+FEE7:00000000100000080404F80000000000
+FEE8:00000000100000080404FB0000000000
+FEE9:000000000000101824243C0000000000
+FEEA:0000000004040C14243C070000000000
+FEEB:000000000010083C2A3AF60000000000
+FEEC:000000000000000C1414FF140C000000
+FEED:000000000000000C12121E0204483000
+FEEE:000000000000000C12121F0204483000
+FEEF:0000000000000000044A484442423C00
+FEF0:00000000000000000000434442423C00
+FEF1:0000000000000000044A4844423C0028
+FEF2:000000000000000000004344423C0028
+FEF3:00000000000000080804F80028000000
+FEF4:00000000000000080804FB0028000000
+FEF5:000008728222120A040C141C00000000
+FEF6:000008728222120A0E0A136000000000
+FEF7:000030423242120A040C141C00000000
+FEF8:000030423242120A0E0A136000000000
+FEF9:0000020222120A040C141C000C100C10
+FEFA:000000020222120A0E0A13600C100C10
+FEFB:000000020222120A040C141C00000000
+FEFC:000000020222120A0E0A136000000000
+FEFD:00007FFE61866FBE638E6FBE6F867FFE7FFE618E6FB663B66FB66F8E7FFE0000
+FEFE:00007FFE61866FBE638E6FBE6F867FFE7FFE61866FBE638E6FBE6F867FFE0000
+FEFF:AAAA0001F4511458A55546D2F4510001F1DE4A10F19E4851F390000180005555
+FF00:00007FFE61866FBE638E6FBE6FBE7FFE7FFE73CE6DB66DB66DB673CE7FFE0000
+FF01:000000000000000000C000C000C000C000C000C000C0000000C000C000000000
+FF02:000000000C0C0C0C0C0C0C0C0000000000000000000000000000000000000000
+FF03:0000000000000000030C030C030C3FFC0C300C303FFC30C030C030C000000000
+FF04:000000000000000000C00FFC30C330C00FC000FC00C330C30FFC00C000000000
+FF05:00000000000000000F0330CC30CC0F3000C000C0033C0CC30CC3303C00000000
+FF06:000000000000000003F00C0C0C0C0C0C03F00FC33033300C303C0FC300000000
+FF07:0000000000C000C000C000C00000000000000000000000000000000000000000
+FF08:000000000000003000C000C003000300030003000300030000C000C000300000
+FF09:0000000000000C000300030000C000C000C000C000C000C0030003000C000000
+FF0A:00000000000000000000000000C030C30CCC03F00CCC30C300C0000000000000
+FF0B:00000000000000000000000000C000C000C03FFF00C000C000C0000000000000
+FF0C:00000000000000000000000000000000000000000000000003C000C000C00300
+FF0D:0000000000000000000000000000000000003FFC000000000000000000000000
+FF0E:00000000000000000000000000000000000000000000000003C003C000000000
+FF0F:0000000000000000000C000C003000C000C0030003000C003000300000000000
+FF10:000000000000000003C00C30300C300C300C300C300C300C0C3003C000000000
+FF11:000000000000000000C003C00CC000C000C000C000C000C000C00FFC00000000
+FF12:00000000000000000FF0300C300C000C00F003000C00300030003FFC00000000
+FF13:00000000000000000FF0300C300C000C03F0000C000C300C300C0FF000000000
+FF14:0000000000000000003000F003300C30303030303FFC00300030003000000000
+FF15:00000000000000003FFC3000300030003FF0000C000C000C300C0FF000000000
+FF16:000000000000000003F00C00300030003FF0300C300C300C300C0FF000000000
+FF17:00000000000000003FFC000C000C00300030003000C000C000C000C000000000
+FF18:00000000000000000FF0300C300C300C0FF0300C300C300C300C0FF000000000
+FF19:00000000000000000FF0300C300C300C0FFC000C000C000C00300FC000000000
+FF1A:00000000000000000000000003C003C000000000000003C003C0000000000000
+FF1B:00000000000000000000000003C003C000000000000003C000C000C003000000
+FF1C:00000000000000000000000C003000C003000C00030000C00030000C00000000
+FF1D:00000000000000000000000000003FFC0000000000003FFC0000000000000000
+FF1E:0000000000000000000030000C00030000C0003000C003000C00300000000000
+FF1F:00000000000000000FF0300C300C000C003000C000C0000000C000C000000000
+FF20:000000000000000003F00C0C30CC333C330C330C330C30FC0C0003FC00000000
+FF21:000000000000000003C00C300C30300C300C3FFC300C300C300C300C00000000
+FF22:00000000000000003FF0300C300C300C3FF0300C300C300C300C3FF000000000
+FF23:00000000000000000FF0300C300C3000300030003000300C300C0FF000000000
+FF24:00000000000000003FC03030300C300C300C300C300C300C30303FC000000000
+FF25:00000000000000003FFC3000300030003FF030003000300030003FFC00000000
+FF26:00000000000000003FFC3000300030003FF03000300030003000300000000000
+FF27:00000000000000000FF0300C300C3000300030FC300C300C303C0FCC00000000
+FF28:0000000000000000300C300C300C300C3FFC300C300C300C300C300C00000000
+FF29:00000000000000000FFC00C000C000C000C000C000C000C000C00FFC00000000
+FF2A:000000000000000003FF003000300030003000300030303030300FC000000000
+FF2B:0000000000000000300C303030C033003C003C00330030C03030300C00000000
+FF2C:00000000000000003000300030003000300030003000300030003FFC00000000
+FF2D:0000000000000000300C300C3C3C3C3C33CC33CC300C300C300C300C00000000
+FF2E:0000000000000000300C3C0C3C0C330C330C30CC30CC303C303C300C00000000
+FF2F:00000000000000000FF0300C300C300C300C300C300C300C300C0FF000000000
+FF30:00000000000000003FF0300C300C300C3FF03000300030003000300000000000
+FF31:00000000000000000FF0300C300C300C300C300C300C33CC3C3C0FF0000F0000
+FF32:00000000000000003FF0300C300C300C3FF030C030303030300C300C00000000
+FF33:00000000000000000FF0300C300C30000F0000F0000C300C300C0FF000000000
+FF34:00000000000000003FFF00C000C000C000C000C000C000C000C000C000000000
+FF35:0000000000000000300C300C300C300C300C300C300C300C300C0FF000000000
+FF36:00000000000000003003300330030C0C0C0C0C0C0330033000C000C000000000
+FF37:0000000000000000300C300C300C300C33CC33CC3C3C3C3C300C300C00000000
+FF38:0000000000000000300C300C0C300C3003C003C00C300C30300C300C00000000
+FF39:0000000000000000300330030C0C0C0C033000C000C000C000C000C000000000
+FF3A:00000000000000003FFC000C000C003000C003000C00300030003FFC00000000
+FF3B:00000000000000FC00C000C000C000C000C000C000C000C000C000C000FC0000
+FF3C:0000000000000000300030000C000300030000C000C00030000C000C00000000
+FF3D:0000003F030303030303030303033F00
+FF3E:0000000003C00C30300C00000000000000000000000000000000000000000000
+FF3F:000000000000000000000000000000000000000000000000000000003FFF0000
+FF40:00000C00030000C0000000000000000000000000000000000000000000000000
+FF41:0000000000000000000000000FF0300C000C0FFC300C300C303C0FCC00000000
+FF42:00000000000030003000300033F03C0C300C300C300C300C3C0C33F000000000
+FF43:0000000000000000000000000FF0300C3000300030003000300C0FF000000000
+FF44:000000000000000C000C000C0FCC303C300C300C300C300C303C0FCC00000000
+FF45:0000000000000000000000000FF0300C300C3FFC30003000300C0FF000000000
+FF46:00000000000000F00300030003003FF003000300030003000300030000000000
+FF47:00000000000000000000000C0FCC3030303030300FC00C000FF0300C300C0FF0
+FF48:00000000000030003000300033F03C0C300C300C300C300C300C300C00000000
+FF49:00000000000000C000C0000003C000C000C000C000C000C000C00FFC00000000
+FF4A:00000000000000300030000000F0003000300030003000300030003030C00F00
+FF4B:000000000000000030003000303030C033003C00330030C03030300C00000000
+FF4C:000000000000000003C000C000C000C000C000C000C000C000C00FFC00000000
+FF4D:0000000000000000000000003F3C30C330C330C330C330C330C330C300000000
+FF4E:00000000000000000000000033F03C0C300C300C300C300C300C300C00000000
+FF4F:0000000000000000000000000FF0300C300C300C300C300C300C0FF000000000
+FF50:00000000000000000000000033F03C0C300C300C300C300C3C0C33F030003000
+FF51:0000000000000000000000000FCC303C300C300C300C300C303C0FCC000C000C
+FF52:00000000000000000000000033F03C0C300C3000300030003000300000000000
+FF53:0000000000000000000000000FF0300C30000F0000F0000C300C0FF000000000
+FF54:0000000000000000030003003FF003000300030003000300030000F000000000
+FF55:000000000000000000000000300C300C300C300C300C300C303C0FCC00000000
+FF56:000000000000000000000000300C300C300C0C300C300C3003C003C000000000
+FF57:000000000000000000000000300330C330C330C330C330C330C30F3C00000000
+FF58:000000000000000000000000300C300C0C3003C003C00C30300C300C00000000
+FF59:000000000000000000000000300C300C300C300C300C0C3C03CC000C000C0FF0
+FF5A:0000000000000000000000003FFC000C003000C003000C0030003FFC00000000
+FF5B:00000000000000F00300030000C000C00300030000C000C00300030000F00000
+FF5C:0000000000C000C000C000C000C000C000C000C000C000C000C000C000C000C0
+FF5D:0000000000000F0000C000C00300030000C000C00300030000C000C00F000000
+FF5E:0000000000000F0330C3303C0000000000000000000000000000000000000000
+FF5F:0000000000000186061806181860186018601860186018600618061801860000
+FF60:0000000000006180186018600618061806180618061806181860186061800000
+FF61:00000000000000000000002050502000
+FF62:001E1010101010101010101010000000
+FF63:00000004040404040404040404043C00
+FF64:00000000000000000000406030180000
+FF65:00000000000000181800000000000000
+FF66:00007E0202027E0206040C0818300000
+FF67:0000000000007E021614101010103020
+FF68:00000000000204040818680808080808
+FF69:000000000010107E4242020404081020
+FF6A:000000000000007C1010101010107E00
+FF6B:00000000000808087E18182828480818
+FF6C:00000000002022161A32480808040404
+FF6D:00000000000000380808080808087E00
+FF6E:0000000000003C0404043C0404043C00
+FF6F:00000000000010524A22040408081020
+FF70:000000000000003C0000000000000000
+FF71:0000FF01121414101010101020204000
+FF72:0002020404081828C808080808080800
+FF73:1010107E424242420202040408102000
+FF74:0000007E1010101010101010FF000000
+FF75:08080808FF0818182828484888081800
+FF76:101010107E1212121212222222424E00
+FF77:202020161830D0130C38680804040404
+FF78:1010101E122222440404080810204000
+FF79:202020203F4444840408080810102000
+FF7A:0000007E0202020202020202027E0000
+FF7B:00242424FF2424242404040808102000
+FF7C:00002030100041612202040810204000
+FF7D:00007C04040404080818142422428100
+FF7E:002020202E32E22420202020203E0000
+FF7F:00004242422222020404040808102000
+FF80:1010101E1222324A0404080810204000
+FF81:00020478080808FF0808101010204000
+FF82:000020A1915152420204040808102000
+FF83:00007E000000FF080808101010204000
+FF84:00101010101018141210101010101000
+FF85:0008080808FF08080808101010204000
+FF86:000000007E00000000000000FF000000
+FF87:00007E02020424281808141222204000
+FF88:1010107E020408183452911010101000
+FF89:00000202040404080808101020204000
+FF8A:00000024242422222222424141810000
+FF8B:004040404648704040404040201E0000
+FF8C:00007E02020204040408081020400000
+FF8D:00000020303048484484020201000000
+FF8E:00101010FF1010545252529191103000
+FF8F:000000FF010204281018080804040000
+FF90:00201804000020100C00002010080400
+FF91:00101010101020242424224E72810000
+FF92:0002020204242418081C142220408000
+FF93:00007E10101010FE10101010101E0000
+FF94:002020232D31D2121008080808080800
+FF95:0000007C0404040404040404FF000000
+FF96:00007E020202027E02020202027E0000
+FF97:00007E0000007E020202040408102000
+FF98:00222222222222222202040404081000
+FF99:000828282828282929292A4A4C880000
+FF9A:00002020202020212122222428300000
+FF9B:0000007E42424242424242427E000000
+FF9C:00007E42424202020204040810200000
+FF9D:00004020100102020404081020400000
+FF9E:28282800000000000000000000000000
+FF9F:10282810000000000000000000000000
+FFA0:00000000000000000000000000000000
+FFA1:0000000000000000007E020202020000
+FFA2:0000000000000000006C242424240000
+FFA3:00000000000000007414141A11000000
+FFA4:000000000000000000404040407E0000
+FFA5:0000000000000000002424242A390000
+FFA6:000000000000000000222722253A0000
+FFA7:0000000000000000007E4040407E0000
+FFA8:0000000000000000006C4848486C0000
+FFA9:0000000000000000003C043C203C0000
+FFAA:00000000000000000076127242720000
+FFAB:000000000000000000EE2AEA8AEE0000
+FFAC:000000000000000000EA2AEE8AEE0000
+FFAD:000000000000000000E424E48AEA0000
+FFAE:000000000000000000EE28EE88EE0000
+FFAF:000000000000000000FF2AEA8AFF0000
+FFB0:000000000000000000E42EE48AE40000
+FFB1:0000000000000000007C4444447C0000
+FFB2:00000000000000000042427E427E0000
+FFB3:000000000000000000AAAAEEAAEE0000
+FFB4:0000000000000000005454745A710000
+FFB5:00000000000000000010101028440000
+FFB6:0000000000000000002424245A910000
+FFB7:00000000000000101038444444380000
+FFB8:0000000000000000007C101028440000
+FFB9:0000000000000000007E24245A910000
+FFBA:000000000000000038007C1028440000
+FFBB:0000000000000000007E027E02020000
+FFBC:0000000000000000007E407E407E0000
+FFBD:0000000000000000007E2424247E0000
+FFBE:00000000000000000038FE3844380000
+FFBF:00007FFE61866FBE638E6FBE6FBE7FFE7FFE63866DBE638E6DBE63BE7FFE0000
+FFC0:00007FFE61866FBE638E6FBE6FBE7FFE7FFE71CE6FB66FB66FB671CE7FFE0000
+FFC1:00007FFE61866FBE638E6FBE6FBE7FFE7FFE71EE6FCE6FEE6FEE71C67FFE0000
+FFC2:00000000000000000020203820200000
+FFC3:00000000000000000028283828280000
+FFC4:00000000000000000020382038200000
+FFC5:00000000000000000028382838280000
+FFC6:00000000000000000008083808080000
+FFC7:00000000000000000014147414140000
+FFC8:00007FFE61866FBE638E6FBE6FBE7FFE7FFE71CE6FB66FCE6FB671CE7FFE0000
+FFC9:00007FFE61866FBE638E6FBE6FBE7FFE7FFE71CE6FB66FC66FF671CE7FFE0000
+FFCA:00000000000000000008380838080000
+FFCB:00000000000000000014741474140000
+FFCC:000000000000000000101010107C0000
+FFCD:000000000000000000040414147E0000
+FFCE:0000000000000000000A0A2A2AFE0000
+FFCF:000000000000000000040414147C0000
+FFD0:00007FFE61866FBE638E6FBE6FBE7FFE7FFE63CE6DB66DB66DB663CE7FFE0000
+FFD1:00007FFE61866FBE638E6FBE6FBE7FFE7FFE63EE6DCE6DEE6DEE63C67FFE0000
+FFD2:000000000000000000282828287C0000
+FFD3:0000000000000000007C101010100000
+FFD4:0000000000000004043C141C14140000
+FFD5:000000000000000A0A7A2A3A2A2A0000
+FFD6:0000000000000004043C141414140000
+FFD7:0000000000000000007C282828280000
+FFD8:00007FFE61866FBE638E6FBE6FBE7FFE7FFE63CE6DB66DCE6DB663CE7FFE0000
+FFD9:00007FFE61866FBE638E6FBE6FBE7FFE7FFE63CE6DB66DC66DF663CE7FFE0000
+FFDA:00000000000000000000007E00000000
+FFDB:00000000000000000008081828080000
+FFDC:00000000000000000008080808080000
+FFDD:00007FFE61866FBE638E6FBE6FBE7FFE7FFE638E6DB66DB66DB6638E7FFE0000
+FFDE:00007FFE61866FBE638E6FBE6FBE7FFE7FFE63866DBE6D8E6DBE63867FFE0000
+FFDF:00007FFE61866FBE638E6FBE6FBE7FFE7FFE63866DBE6D8E6DBE63BE7FFE0000
+FFE0:000000000000000000C000C00FFC30C330C030C030C30FFC00C000C000000000
+FFE1:000000000000000000FC0300030003003FF00300030003000FFC3C0300000000
+FFE2:00000000000000000000000000000000000000003FFC000C000C000C00000000
+FFE3:000000003FFC0000000000000000000000000000000000000000000000000000
+FFE4:000000000000000000C000C000C000C00000000000C000C000C000C000000000
+FFE5:000000000000000030030C0C033000C03FFF00C03FFF00C000C000C000000000
+FFE6:00000000000000000C0C0C0C0C0C3FFF0CCC3FFF0F3C0F3C0C0C0C0C00000000
+FFE7:00007FFE61866FBE638E6FBE6FBE7FFE7FFE61866FF663EE6FDE61DE7FFE0000
+FFE8:08080808080808080808080808080808
+FFE9:000000000010207E2010000000000000
+FFEA:0000000000081C2A0808080000000000
+FFEB:00000000000008047E04080000000000
+FFEC:00000000000808082A1C080000000000
+FFED:000000000000007E7E7E7E7E7E000000
+FFEE:00000000000018244242241800000000
+FFEF:00007FFE61866FBE638E6FBE6FBE7FFE7FFE61866FBE638E6FBE61BE7FFE0000
+FFF0:00007FFE61866FBE638E6FBE6FBE7FFE7FFE61CE6FB663B66FB66FCE7FFE0000
+FFF1:00007FFE61866FBE638E6FBE6FBE7FFE7FFE61EE6FCE63EE6FEE6FC67FFE0000
+FFF2:00007FFE61866FBE638E6FBE6FBE7FFE7FFE61866FF663866FBE6F867FFE0000
+FFF3:00007FFE61866FBE638E6FBE6FBE7FFE7FFE618E6FF663C66FF66F8E7FFE0000
+FFF4:00007FFE61866FBE638E6FBE6FBE7FFE7FFE61B66FB663866FF66FF67FFE0000
+FFF5:00007FFE61866FBE638E6FBE6FBE7FFE7FFE61866FBE63866FF66F867FFE0000
+FFF6:00007FFE61866FBE638E6FBE6FBE7FFE7FFE61CE6FBE638E6FB66FCE7FFE0000
+FFF7:00007FFE61866FBE638E6FBE6FBE7FFE7FFE61866FF663EE6FDE6FDE7FFE0000
+FFF8:00007FFE61866FBE638E6FBE6FBE7FFE7FFE61CE6FB663CE6FB66FCE7FFE0000
+FFF9:555580000001BE10082988380845BE4400018080014181C0022182200001AAAA
+FFFA:555580000001BE10082988380845BE44000181C0020181C0002183C00001AAAA
+FFFB:555580000001BE10082988380845BE44000183E000818080008180800001AAAA
+FFFC:555580000001800000018000098995481589954809B18000000180000001AAAA
+FFFD:0000007E665A5A7A76767E76767E0000
+FFFE:FFFFFFFFE187EFBFE38FEFBFEFBFFFFFFFFFE187EFBFE38FEFBFEF87FFFFFFFF
+FFFF:FFFFFFFFE187EFBFE38FEFBFEFBFFFFFFFFFE187EFBFE38FEFBFEFBFFFFFFFFF
index 8d34615..1c24cad 100644 (file)
@@ -122,8 +122,40 @@ global:
         sd_session_is_remote;
         sd_session_get_remote_user;
         sd_session_get_remote_host;
+local:
+       *;
+};
+
+LIBSYSTEMD_211 {
+global:
+        sd_machine_get_class;
+        sd_peer_get_session;
+        sd_peer_get_owner_uid;
+        sd_peer_get_unit;
+        sd_peer_get_user_unit;
+        sd_peer_get_machine_name;
+        sd_peer_get_slice;
+} LIBSYSTEMD_209;
+
+LIBSYSTEMD_213 {
+global:
+        sd_uid_get_display;
+} LIBSYSTEMD_211;
+
+LIBSYSTEMD_214 {
+global:
+        sd_pid_notify;
+        sd_pid_notifyf;
+} LIBSYSTEMD_213;
+
+LIBSYSTEMD_216 {
+global:
+        sd_machine_get_ifindices;
+} LIBSYSTEMD_214;
 
 m4_ifdef(`ENABLE_KDBUS',
+LIBSYSTEMD_FUTURE {
+global:
         /* sd-bus */
         sd_bus_default;
         sd_bus_default_user;
@@ -141,6 +173,7 @@ m4_ifdef(`ENABLE_KDBUS',
         sd_bus_set_server;
         sd_bus_set_anonymous;
         sd_bus_set_trusted;
+        sd_bus_set_monitor;
         sd_bus_set_name;
         sd_bus_negotiate_fds;
         sd_bus_negotiate_timestamp;
@@ -159,7 +192,6 @@ m4_ifdef(`ENABLE_KDBUS',
         sd_bus_send_to;
         sd_bus_call;
         sd_bus_call_async;
-        sd_bus_call_async_cancel;
         sd_bus_get_fd;
         sd_bus_get_events;
         sd_bus_get_timeout;
@@ -167,27 +199,26 @@ m4_ifdef(`ENABLE_KDBUS',
         sd_bus_process_priority;
         sd_bus_wait;
         sd_bus_flush;
-        sd_bus_get_current;
+        sd_bus_get_current_message;
+        sd_bus_get_current_slot;
         sd_bus_get_tid;
         sd_bus_attach_event;
         sd_bus_detach_event;
         sd_bus_get_event;
         sd_bus_add_filter;
-        sd_bus_remove_filter;
         sd_bus_add_match;
-        sd_bus_remove_match;
         sd_bus_add_object;
-        sd_bus_remove_object;
         sd_bus_add_fallback;
-        sd_bus_remove_fallback;
         sd_bus_add_object_vtable;
-        sd_bus_remove_object_vtable;
         sd_bus_add_fallback_vtable;
-        sd_bus_remove_fallback_vtable;
         sd_bus_add_node_enumerator;
-        sd_bus_remove_node_enumerator;
         sd_bus_add_object_manager;
-        sd_bus_remove_object_manager;
+        sd_bus_slot_ref;
+        sd_bus_slot_unref;
+        sd_bus_slot_get_bus;
+        sd_bus_slot_get_userdata;
+        sd_bus_slot_set_userdata;
+        sd_bus_slot_get_current_message;
         sd_bus_message_new_signal;
         sd_bus_message_new_method_call;
         sd_bus_message_new_method_return;
@@ -311,8 +342,22 @@ m4_ifdef(`ENABLE_KDBUS',
         sd_bus_error_copy;
         sd_bus_error_is_set;
         sd_bus_error_has_name;
-        sd_bus_label_escape;
-        sd_bus_label_unescape;
+        sd_bus_path_encode;
+        sd_bus_path_decode;
+        sd_bus_track_new;
+        sd_bus_track_ref;
+        sd_bus_track_unref;
+        sd_bus_track_get_bus;
+        sd_bus_track_get_userdata;
+        sd_bus_track_set_userdata;
+        sd_bus_track_add_sender;
+        sd_bus_track_remove_sender;
+        sd_bus_track_add_name;
+        sd_bus_track_remove_name;
+        sd_bus_track_count;
+        sd_bus_track_contains;
+        sd_bus_track_first;
+        sd_bus_track_next;
 
         /* sd-memfd */
         sd_memfd_new;
@@ -334,8 +379,7 @@ m4_ifdef(`ENABLE_KDBUS',
         sd_event_ref;
         sd_event_unref;
         sd_event_add_io;
-        sd_event_add_monotonic;
-        sd_event_add_realtime;
+        sd_event_add_time;
         sd_event_add_signal;
         sd_event_add_child;
         sd_event_add_defer;
@@ -343,11 +387,10 @@ m4_ifdef(`ENABLE_KDBUS',
         sd_event_run;
         sd_event_loop;
         sd_event_exit;
+        sd_event_now;
         sd_event_get_state;
         sd_event_get_tid;
         sd_event_get_exit_code;
-        sd_event_get_now_realtime;
-        sd_event_get_now_monotonic;
         sd_event_set_watchdog;
         sd_event_get_watchdog;
         sd_event_source_ref;
@@ -369,6 +412,7 @@ m4_ifdef(`ENABLE_KDBUS',
         sd_event_source_set_time;
         sd_event_source_set_time_accuracy;
         sd_event_source_get_time_accuracy;
+        sd_event_source_get_time_clock;
         sd_event_source_get_signal;
         sd_event_source_get_child_pid;
         sd_event_source_get_event;
@@ -376,7 +420,34 @@ m4_ifdef(`ENABLE_KDBUS',
         /* sd-utf8 */
         sd_utf8_is_valid;
         sd_ascii_is_valid;
+
+        /* sd-resolve */
+        sd_resolve_default;
+        sd_resolve_new;
+        sd_resolve_ref;
+        sd_resolve_unref;
+        sd_resolve_get_fd;
+        sd_resolve_get_events;
+        sd_resolve_get_timeout;
+        sd_resolve_process;
+        sd_resolve_wait;
+        sd_resolve_get_tid;
+        sd_resolve_attach_event;
+        sd_resolve_detach_event;
+        sd_resolve_get_event;
+        sd_resolve_getaddrinfo;
+        sd_resolve_getnameinfo;
+        sd_resolve_res_query;
+        sd_resolve_res_search;
+        sd_resolve_query_ref;
+        sd_resolve_query_unref;
+        sd_resolve_query_is_done;
+        sd_resolve_query_get_userdata;
+        sd_resolve_query_set_userdata;
+        sd_resolve_query_get_resolve;
+
+        /* sd-path */
+        sd_path_home;
+        sd_path_search;
+} LIBSYSTEMD_216;
 )
-local:
-       *;
-};
index 90d184b..6205e32 100644 (file)
@@ -123,8 +123,8 @@ at the same time!
 This pretty much explains the ioctl header. The actual payload of the
 data is now referenced in additional items that are attached to this
 ioctl header structure at the end. When sending a message, you attach
-items of the type PAYLOAD_VEC, PAYLOAD_MEMFD, FDS, BLOOM, DST_NAME to
-it:
+items of the type PAYLOAD_VEC, PAYLOAD_MEMFD, FDS, BLOOM_FILTER,
+DST_NAME to it:
 
    KDBUS_ITEM_PAYLOAD_VEC: contains a pointer + length pair for
    referencing arbitrary user memory. This is how you reference most
@@ -134,15 +134,15 @@ it:
    to send prepared "memfds" (see below) over. This item contains an
    fd for a memfd plus a size.
 
-   KDBUS_ITEM_PAYLOAD_FDS: for sending over fds attach an item of this
-   type with an array of fds.
+   KDBUS_ITEM_FDS: for sending over fds attach an item of this type with
+   an array of fds.
 
-   KDBUS_ITEM_BLOOM: the calculated bloom filter of this message, only
-   for undirected (broadcast) message.
+   KDBUS_ITEM_BLOOM_FILTER: the calculated bloom filter of this message,
+   only for undirected (broadcast) message.
 
-   KDBUS_DST_NAME: for messages that are directed to a well-known name
-   (instead of a unique name), this item contains the well-known name
-   field.
+   KDBUS_ITEM_DST_NAME: for messages that are directed to a well-known
+   name (instead of a unique name), this item contains the well-known
+   name field.
 
 A single message may consists of no, one or more payload items of type
 PAYLOAD_VEC or PAYLOAD_MEMFD. D-Bus protocol implementations should
@@ -342,7 +342,7 @@ items of the same type as the kernel messages include,
 i.e. KDBUS_ITEM_NAME_ADD, KDBUS_ITEM_NAME_REMOVE,
 KDBUS_ITEM_NAME_CHANGE, KDBUS_ITEM_ID_ADD, KDBUS_ITEM_ID_REMOVE and
 fill them out. Note however, that you have some wildcards in this
-case, for example the .id field of KDBUS_ITEM_ADD/KDBUS_ITEM_REMOVE
+case, for example the .id field of KDBUS_ITEM_ID_ADD/KDBUS_ITEM_ID_REMOVE
 structures may be set to 0 to match against any id addition/removal.
 
 Note that dbus match strings do no map 1:1 to these ioctl() calls. In
@@ -536,7 +536,7 @@ parameter.
 Client libraries should use the following connection string when
 connecting to the system bus:
 
-   kernel:path=/dev/kdbus/0-system/bus;unix:path=/run/dbus/system_bus_socket
+   kernel:path=/dev/kdbus/0-system/bus;unix:path=/var/run/dbus/system_bus_socket
 
 This will ensure that kdbus is preferred over the legacy AF_UNIX
 socket, but compatibility is kept. For the user bus use:
index e154296..3556774 100644 (file)
@@ -48,6 +48,7 @@ static void bloom_add_data(
         uint8_t h[8];
         uint64_t m;
         unsigned w, i, c = 0;
+        unsigned hash_index;
 
         assert(size > 0);
         assert(k > 0);
@@ -65,13 +66,13 @@ static void bloom_add_data(
          * hash value for each 128 bits of hash key. */
         assert(k * w <= ELEMENTSOF(hash_keys) * 8);
 
-        for (i = 0; i < k; i++) {
+        for (i = 0, hash_index = 0; i < k; i++) {
                 uint64_t p = 0;
                 unsigned d;
 
                 for (d = 0; d < w; d++) {
                         if (c <= 0) {
-                                siphash24(h, data, n, hash_keys[i++].bytes);
+                                siphash24(h, data, n, hash_keys[hash_index++].bytes);
                                 c += 8;
                         }
 
index d330363..dd4bf15 100644 (file)
@@ -42,7 +42,7 @@ int bus_container_connect_socket(sd_bus *b) {
         if (r < 0)
                 return r;
 
-        r = namespace_open(leader, &pidnsfd, &mntnsfd, &rootfd);
+        r = namespace_open(leader, &pidnsfd, &mntnsfd, NULL, &rootfd);
         if (r < 0)
                 return r;
 
@@ -61,7 +61,7 @@ int bus_container_connect_socket(sd_bus *b) {
         if (child == 0) {
                 pid_t grandchild;
 
-                r = namespace_enter(pidnsfd, mntnsfd, rootfd);
+                r = namespace_enter(pidnsfd, mntnsfd, -1, rootfd);
                 if (r < 0)
                         _exit(255);
 
@@ -116,7 +116,7 @@ int bus_container_connect_socket(sd_bus *b) {
 }
 
 int bus_container_connect_kernel(sd_bus *b) {
-        _cleanup_close_pipe_ int pair[2] = { -1, -1 };
+        _cleanup_close_pair_ int pair[2] = { -1, -1 };
         _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, rootfd = -1;
         union {
                 struct cmsghdr cmsghdr;
@@ -140,7 +140,7 @@ int bus_container_connect_kernel(sd_bus *b) {
         if (r < 0)
                 return r;
 
-        r = namespace_open(leader, &pidnsfd, &mntnsfd, &rootfd);
+        r = namespace_open(leader, &pidnsfd, &mntnsfd, NULL, &rootfd);
         if (r < 0)
                 return r;
 
@@ -154,10 +154,9 @@ int bus_container_connect_kernel(sd_bus *b) {
         if (child == 0) {
                 pid_t grandchild;
 
-                close_nointr_nofail(pair[0]);
-                pair[0] = -1;
+                pair[0] = safe_close(pair[0]);
 
-                r = namespace_enter(pidnsfd, mntnsfd, rootfd);
+                r = namespace_enter(pidnsfd, mntnsfd, -1, rootfd);
                 if (r < 0)
                         _exit(EXIT_FAILURE);
 
@@ -202,8 +201,7 @@ int bus_container_connect_kernel(sd_bus *b) {
                 _exit(si.si_status);
         }
 
-        close_nointr_nofail(pair[1]);
-        pair[1] = -1;
+        pair[1] = safe_close(pair[1]);
 
         r = wait_for_terminate(child, &si);
         if (r < 0)
index 22b95d5..ad372f6 100644 (file)
@@ -128,12 +128,14 @@ _public_ int sd_bus_request_name(sd_bus *bus, const char *name, uint64_t flags)
         assert_return(bus, -EINVAL);
         assert_return(name, -EINVAL);
         assert_return(bus->bus_client, -EINVAL);
-        assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
         assert_return(!bus_pid_changed(bus), -ECHILD);
         assert_return(!(flags & ~(SD_BUS_NAME_ALLOW_REPLACEMENT|SD_BUS_NAME_REPLACE_EXISTING|SD_BUS_NAME_QUEUE)), -EINVAL);
         assert_return(service_name_is_valid(name), -EINVAL);
         assert_return(name[0] != ':', -EINVAL);
 
+        if (!BUS_IS_OPEN(bus->state))
+                return -ENOTCONN;
+
         if (bus->is_kernel)
                 return bus_request_name_kernel(bus, name, flags);
         else
@@ -201,11 +203,13 @@ _public_ int sd_bus_release_name(sd_bus *bus, const char *name) {
         assert_return(bus, -EINVAL);
         assert_return(name, -EINVAL);
         assert_return(bus->bus_client, -EINVAL);
-        assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
         assert_return(!bus_pid_changed(bus), -ECHILD);
         assert_return(service_name_is_valid(name), -EINVAL);
         assert_return(name[0] != ':', -EINVAL);
 
+        if (!BUS_IS_OPEN(bus->state))
+                return -ENOTCONN;
+
         if (bus->is_kernel)
                 return bus_release_name_kernel(bus, name);
         else
@@ -237,11 +241,9 @@ static int kernel_get_list(sd_bus *bus, uint64_t flags, char ***x) {
                         if (asprintf(&n, ":1.%llu", (unsigned long long) name->owner_id) < 0)
                                 return -ENOMEM;
 
-                        r = strv_push(x, n);
-                        if (r < 0) {
-                                free(n);
-                                return -ENOMEM;
-                        }
+                        r = strv_consume(x, n);
+                        if (r < 0)
+                                return r;
 
                         previous_id = name->owner_id;
                 }
@@ -344,9 +346,11 @@ static int bus_list_names_dbus1(sd_bus *bus, char ***acquired, char ***activatab
 _public_ int sd_bus_list_names(sd_bus *bus, char ***acquired, char ***activatable) {
         assert_return(bus, -EINVAL);
         assert_return(acquired || activatable, -EINVAL);
-        assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
         assert_return(!bus_pid_changed(bus), -ECHILD);
 
+        if (!BUS_IS_OPEN(bus->state))
+                return -ENOTCONN;
+
         if (bus->is_kernel)
                 return bus_list_names_kernel(bus, acquired, activatable);
         else
@@ -391,7 +395,7 @@ static int bus_get_owner_kdbus(
 
         /* Non-activated names are considered not available */
         if (conn_info->flags & KDBUS_HELLO_ACTIVATOR)
-                return name[0] == ':' ? -ENXIO : -ENOENT;
+                return name[0] == ':' ? -ENXIO : -ESRCH;
 
         c = bus_creds_new();
         if (!c)
@@ -491,11 +495,9 @@ static int bus_get_owner_kdbus(
                                         goto fail;
                                 }
 
-                                if (!bus->cgroup_root) {
-                                        r = cg_get_root_path(&bus->cgroup_root);
-                                        if (r < 0)
-                                                goto fail;
-                                }
+                                r = bus_get_root_path(bus);
+                                if (r < 0)
+                                        goto fail;
 
                                 c->cgroup_root = strdup(bus->cgroup_root);
                                 if (!c->cgroup_root) {
@@ -737,11 +739,13 @@ _public_ int sd_bus_get_owner(
         assert_return(name, -EINVAL);
         assert_return(mask <= _SD_BUS_CREDS_ALL, -ENOTSUP);
         assert_return(mask == 0 || creds, -EINVAL);
-        assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
         assert_return(!bus_pid_changed(bus), -ECHILD);
         assert_return(service_name_is_valid(name), -EINVAL);
         assert_return(bus->bus_client, -ENODATA);
 
+        if (!BUS_IS_OPEN(bus->state))
+                return -ENOTCONN;
+
         if (bus->is_kernel)
                 return bus_get_owner_kdbus(bus, name, mask, creds);
         else
@@ -919,7 +923,6 @@ static int add_name_change_match(sd_bus *bus,
 
 int bus_add_match_internal_kernel(
                 sd_bus *bus,
-                uint64_t id,
                 struct bus_match_component *components,
                 unsigned n_components,
                 uint64_t cookie) {
@@ -1057,7 +1060,6 @@ int bus_add_match_internal_kernel(
         m = alloca0(sz);
         m->size = sz;
         m->cookie = cookie;
-        m->owner_id = id;
 
         item = m->items;
 
@@ -1100,13 +1102,22 @@ int bus_add_match_internal_kernel(
         return 0;
 }
 
+#define internal_match(bus, m)                                          \
+        ((bus)->hello_flags & KDBUS_HELLO_MONITOR                       \
+         ? (isempty(m) ? "eavesdrop='true'" : strappenda((m), ",eavesdrop='true'")) \
+         : (m))
+
 static int bus_add_match_internal_dbus1(
                 sd_bus *bus,
                 const char *match) {
 
+        const char *e;
+
         assert(bus);
         assert(match);
 
+        e = internal_match(bus, match);
+
         return sd_bus_call_method(
                         bus,
                         "org.freedesktop.DBus",
@@ -1116,7 +1127,7 @@ static int bus_add_match_internal_dbus1(
                         NULL,
                         NULL,
                         "s",
-                        match);
+                        e);
 }
 
 int bus_add_match_internal(
@@ -1127,17 +1138,15 @@ int bus_add_match_internal(
                 uint64_t cookie) {
 
         assert(bus);
-        assert(match);
 
         if (bus->is_kernel)
-                return bus_add_match_internal_kernel(bus, 0, components, n_components, cookie);
+                return bus_add_match_internal_kernel(bus, components, n_components, cookie);
         else
                 return bus_add_match_internal_dbus1(bus, match);
 }
 
 int bus_remove_match_internal_kernel(
                 sd_bus *bus,
-                uint64_t id,
                 uint64_t cookie) {
 
         struct kdbus_cmd_match m;
@@ -1148,7 +1157,6 @@ int bus_remove_match_internal_kernel(
         zero(m);
         m.size = offsetof(struct kdbus_cmd_match, items);
         m.cookie = cookie;
-        m.owner_id = id;
 
         r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_REMOVE, &m);
         if (r < 0)
@@ -1161,9 +1169,13 @@ static int bus_remove_match_internal_dbus1(
                 sd_bus *bus,
                 const char *match) {
 
+        const char *e;
+
         assert(bus);
         assert(match);
 
+        e = internal_match(bus, match);
+
         return sd_bus_call_method(
                         bus,
                         "org.freedesktop.DBus",
@@ -1173,7 +1185,7 @@ static int bus_remove_match_internal_dbus1(
                         NULL,
                         NULL,
                         "s",
-                        match);
+                        e);
 }
 
 int bus_remove_match_internal(
@@ -1182,10 +1194,9 @@ int bus_remove_match_internal(
                 uint64_t cookie) {
 
         assert(bus);
-        assert(match);
 
         if (bus->is_kernel)
-                return bus_remove_match_internal_kernel(bus, 0, cookie);
+                return bus_remove_match_internal_kernel(bus, cookie);
         else
                 return bus_remove_match_internal_dbus1(bus, match);
 }
@@ -1198,10 +1209,12 @@ _public_ int sd_bus_get_owner_machine_id(sd_bus *bus, const char *name, sd_id128
         assert_return(bus, -EINVAL);
         assert_return(name, -EINVAL);
         assert_return(machine, -EINVAL);
-        assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
         assert_return(!bus_pid_changed(bus), -ECHILD);
         assert_return(service_name_is_valid(name), -EINVAL);
 
+        if (!BUS_IS_OPEN(bus->state))
+                return -ENOTCONN;
+
         if (streq_ptr(name, bus->unique_name))
                 return sd_id128_get_machine(machine);
 
index b610bef..aa290ed 100644 (file)
 ***/
 
 #include "sd-bus.h"
+#include "bus-match.h"
 
 int bus_add_match_internal(sd_bus *bus, const char *match, struct bus_match_component *components, unsigned n_components, uint64_t cookie);
 int bus_remove_match_internal(sd_bus *bus, const char *match, uint64_t cookie);
 
-int bus_add_match_internal_kernel(sd_bus *bus, uint64_t id, struct bus_match_component *components, unsigned n_components, uint64_t cookie);
-int bus_remove_match_internal_kernel(sd_bus *bus, uint64_t id, uint64_t cookie);
+int bus_add_match_internal_kernel(sd_bus *bus, struct bus_match_component *components, unsigned n_components, uint64_t cookie);
+int bus_remove_match_internal_kernel(sd_bus *bus, uint64_t cookie);
index 6e02ad3..f88836b 100644 (file)
@@ -36,9 +36,11 @@ _public_ int sd_bus_emit_signal(
         int r;
 
         assert_return(bus, -EINVAL);
-        assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
         assert_return(!bus_pid_changed(bus), -ECHILD);
 
+        if (!BUS_IS_OPEN(bus->state))
+                return -ENOTCONN;
+
         r = sd_bus_message_new_signal(bus, &m, path, interface, member);
         if (r < 0)
                 return r;
@@ -70,9 +72,11 @@ _public_ int sd_bus_call_method(
         int r;
 
         assert_return(bus, -EINVAL);
-        assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
         assert_return(!bus_pid_changed(bus), -ECHILD);
 
+        if (!BUS_IS_OPEN(bus->state))
+                return -ENOTCONN;
+
         r = sd_bus_message_new_method_call(bus, &m, destination, path, interface, member);
         if (r < 0)
                 return r;
@@ -100,9 +104,12 @@ _public_ int sd_bus_reply_method_return(
         assert_return(call, -EINVAL);
         assert_return(call->sealed, -EPERM);
         assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
-        assert_return(call->bus && BUS_IS_OPEN(call->bus->state), -ENOTCONN);
+        assert_return(call->bus, -EINVAL);
         assert_return(!bus_pid_changed(call->bus), -ECHILD);
 
+        if (!BUS_IS_OPEN(call->bus->state))
+                return -ENOTCONN;
+
         if (call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
                 return 0;
 
@@ -134,9 +141,12 @@ _public_ int sd_bus_reply_method_error(
         assert_return(call->sealed, -EPERM);
         assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
         assert_return(sd_bus_error_is_set(e), -EINVAL);
-        assert_return(call->bus && BUS_IS_OPEN(call->bus->state), -ENOTCONN);
+        assert_return(call->bus, -EINVAL);
         assert_return(!bus_pid_changed(call->bus), -ECHILD);
 
+        if (!BUS_IS_OPEN(call->bus->state))
+                return -ENOTCONN;
+
         if (call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
                 return 0;
 
@@ -159,9 +169,12 @@ _public_ int sd_bus_reply_method_errorf(
         assert_return(call, -EINVAL);
         assert_return(call->sealed, -EPERM);
         assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
-        assert_return(call->bus && BUS_IS_OPEN(call->bus->state), -ENOTCONN);
+        assert_return(call->bus, -EINVAL);
         assert_return(!bus_pid_changed(call->bus), -ECHILD);
 
+        if (!BUS_IS_OPEN(call->bus->state))
+                return -ENOTCONN;
+
         if (call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
                 return 0;
 
@@ -182,9 +195,12 @@ _public_ int sd_bus_reply_method_errno(
         assert_return(call, -EINVAL);
         assert_return(call->sealed, -EPERM);
         assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
-        assert_return(call->bus && BUS_IS_OPEN(call->bus->state), -ENOTCONN);
+        assert_return(call->bus, -EINVAL);
         assert_return(!bus_pid_changed(call->bus), -ECHILD);
 
+        if (!BUS_IS_OPEN(call->bus->state))
+                return -ENOTCONN;
+
         if (call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
                 return 0;
 
@@ -208,9 +224,12 @@ _public_ int sd_bus_reply_method_errnof(
         assert_return(call, -EINVAL);
         assert_return(call->sealed, -EPERM);
         assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
-        assert_return(call->bus && BUS_IS_OPEN(call->bus->state), -ENOTCONN);
+        assert_return(call->bus, -EINVAL);
         assert_return(!bus_pid_changed(call->bus), -ECHILD);
 
+        if (!BUS_IS_OPEN(call->bus->state))
+                return -ENOTCONN;
+
         if (call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
                 return 0;
 
@@ -239,9 +258,11 @@ _public_ int sd_bus_get_property(
         assert_return(member_name_is_valid(member), -EINVAL);
         assert_return(reply, -EINVAL);
         assert_return(signature_is_single(type, false), -EINVAL);
-        assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
         assert_return(!bus_pid_changed(bus), -ECHILD);
 
+        if (!BUS_IS_OPEN(bus->state))
+                return -ENOTCONN;
+
         r = sd_bus_call_method(bus, destination, path, "org.freedesktop.DBus.Properties", "Get", error, &rep, "ss", strempty(interface), member);
         if (r < 0)
                 return r;
@@ -273,9 +294,11 @@ _public_ int sd_bus_get_property_trivial(
         assert_return(member_name_is_valid(member), -EINVAL);
         assert_return(bus_type_is_trivial(type), -EINVAL);
         assert_return(ptr, -EINVAL);
-        assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
         assert_return(!bus_pid_changed(bus), -ECHILD);
 
+        if (!BUS_IS_OPEN(bus->state))
+                return -ENOTCONN;
+
         r = sd_bus_call_method(bus, destination, path, "org.freedesktop.DBus.Properties", "Get", error, &reply, "ss", strempty(interface), member);
         if (r < 0)
                 return r;
@@ -309,9 +332,11 @@ _public_ int sd_bus_get_property_string(
         assert_return(isempty(interface) || interface_name_is_valid(interface), -EINVAL);
         assert_return(member_name_is_valid(member), -EINVAL);
         assert_return(ret, -EINVAL);
-        assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
         assert_return(!bus_pid_changed(bus), -ECHILD);
 
+        if (!BUS_IS_OPEN(bus->state))
+                return -ENOTCONN;
+
         r = sd_bus_call_method(bus, destination, path, "org.freedesktop.DBus.Properties", "Get", error, &reply, "ss", strempty(interface), member);
         if (r < 0)
                 return r;
@@ -348,9 +373,11 @@ _public_ int sd_bus_get_property_strv(
         assert_return(isempty(interface) || interface_name_is_valid(interface), -EINVAL);
         assert_return(member_name_is_valid(member), -EINVAL);
         assert_return(ret, -EINVAL);
-        assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
         assert_return(!bus_pid_changed(bus), -ECHILD);
 
+        if (!BUS_IS_OPEN(bus->state))
+                return -ENOTCONN;
+
         r = sd_bus_call_method(bus, destination, path, "org.freedesktop.DBus.Properties", "Get", error, &reply, "ss", strempty(interface), member);
         if (r < 0)
                 return r;
@@ -383,9 +410,11 @@ _public_ int sd_bus_set_property(
         assert_return(isempty(interface) || interface_name_is_valid(interface), -EINVAL);
         assert_return(member_name_is_valid(member), -EINVAL);
         assert_return(signature_is_single(type, false), -EINVAL);
-        assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
         assert_return(!bus_pid_changed(bus), -ECHILD);
 
+        if (!BUS_IS_OPEN(bus->state))
+                return -ENOTCONN;
+
         r = sd_bus_message_new_method_call(bus, &m, destination, path, "org.freedesktop.DBus.Properties", "Set");
         if (r < 0)
                 return r;
@@ -416,9 +445,12 @@ _public_ int sd_bus_query_sender_creds(sd_bus_message *call, uint64_t mask, sd_b
 
         assert_return(call, -EINVAL);
         assert_return(call->sealed, -EPERM);
-        assert_return(call->bus && BUS_IS_OPEN(call->bus->state), -ENOTCONN);
+        assert_return(call->bus, -EINVAL);
         assert_return(!bus_pid_changed(call->bus), -ECHILD);
 
+        if (!BUS_IS_OPEN(call->bus->state))
+                return -ENOTCONN;
+
         c = sd_bus_message_get_creds(call);
 
         /* All data we need? */
@@ -440,3 +472,56 @@ _public_ int sd_bus_query_sender_creds(sd_bus_message *call, uint64_t mask, sd_b
 
         return bus_creds_extend_by_pid(c, mask, creds);
 }
+
+_public_ int sd_bus_query_sender_privilege(sd_bus_message *call, int capability) {
+        _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
+        uid_t our_uid;
+        int r;
+
+        assert_return(call, -EINVAL);
+        assert_return(call->sealed, -EPERM);
+        assert_return(call->bus, -EINVAL);
+        assert_return(!bus_pid_changed(call->bus), -ECHILD);
+
+        if (!BUS_IS_OPEN(call->bus->state))
+                return -ENOTCONN;
+
+        /* We only trust the effective capability set if this is
+         * kdbus. On classic dbus1 we cannot retrieve the value
+         * without races. Since this function is supposed to be useful
+         * for authentication decision we hence avoid requesting and
+         * using that information. */
+        if (call->bus->is_kernel && capability >= 0) {
+                r = sd_bus_query_sender_creds(call, SD_BUS_CREDS_UID|SD_BUS_CREDS_EFFECTIVE_CAPS, &creds);
+                if (r < 0)
+                        return r;
+
+                r = sd_bus_creds_has_effective_cap(creds, capability);
+                if (r > 0)
+                        return 1;
+        } else {
+                r = sd_bus_query_sender_creds(call, SD_BUS_CREDS_UID, &creds);
+                if (r < 0)
+                        return r;
+        }
+
+        /* Now, check the UID, but only if the capability check wasn't
+         * sufficient */
+        our_uid = getuid();
+        if (our_uid != 0 || !call->bus->is_kernel || capability < 0) {
+                uid_t sender_uid;
+
+                r = sd_bus_creds_get_uid(creds, &sender_uid);
+                if (r >= 0) {
+                        /* Sender has same UID as us, then let's grant access */
+                        if (sender_uid == our_uid)
+                                return 1;
+
+                        /* Sender is root, we are not root. */
+                        if (our_uid != 0 && sender_uid == 0)
+                                return 1;
+                }
+        }
+
+        return 0;
+}
index 2d56f3c..26c2545 100644 (file)
@@ -30,6 +30,7 @@
 #include "time-util.h"
 #include "strv.h"
 #include "bus-creds.h"
+#include "bus-label.h"
 
 enum {
         CAP_OFFSET_INHERITABLE = 0,
@@ -474,7 +475,7 @@ _public_ int sd_bus_creds_get_connection_name(sd_bus_creds *c, const char **ret)
         assert(c->conn_name);
 
         if (!c->unescaped_conn_name) {
-                c->unescaped_conn_name = sd_bus_label_unescape(c->conn_name);
+                c->unescaped_conn_name = bus_label_unescape(c->conn_name);
                 if (!c->unescaped_conn_name)
                         return -ENOMEM;
         }
@@ -748,7 +749,7 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
         if (tid > 0 && (missing & SD_BUS_CREDS_TID_COMM)) {
                 _cleanup_free_ char *p = NULL;
 
-                if (asprintf(&p, "/proc/%lu/task/%lu/comm", (unsigned long) pid, (unsigned long) tid) < 0)
+                if (asprintf(&p, "/proc/"PID_FMT"/task/"PID_FMT"/comm", pid, tid) < 0)
                         return -ENOMEM;
 
                 r = read_one_line_file(p, &c->tid_comm);
index 0e41549..8b70b20 100644 (file)
@@ -54,7 +54,7 @@ int bus_message_dump(sd_bus_message *m, FILE *f, bool with_header) {
 
         if (with_header) {
                 fprintf(f,
-                        "%s%s%sType=%s%s%s  Endian=%c  Flags=%u  Version=%u  Priority=%lli",
+                        "%s%s%s Type=%s%s%s  Endian=%c  Flags=%u  Version=%u  Priority=%lli",
                         m->header->type == SD_BUS_MESSAGE_METHOD_ERROR ? ansi_highlight_red() :
                         m->header->type == SD_BUS_MESSAGE_METHOD_RETURN ? ansi_highlight_green() :
                         m->header->type != SD_BUS_MESSAGE_SIGNAL ? ansi_highlight() : "", draw_special_char(DRAW_TRIANGULAR_BULLET), ansi_highlight_off(),
@@ -69,10 +69,10 @@ int bus_message_dump(sd_bus_message *m, FILE *f, bool with_header) {
                 if (BUS_MESSAGE_COOKIE(m) == 0xFFFFFFFFULL)
                         fprintf(f, " Cookie=-1");
                 else
-                        fprintf(f, " Cookie=%lu", (unsigned long) BUS_MESSAGE_COOKIE(m));
+                        fprintf(f, " Cookie=%" PRIu64, BUS_MESSAGE_COOKIE(m));
 
                 if (m->reply_cookie != 0)
-                        fprintf(f, "  ReplyCookie=%lu", (unsigned long) m->reply_cookie);
+                        fprintf(f, "  ReplyCookie=%" PRIu64, m->reply_cookie);
 
                 fputs("\n", f);
 
@@ -98,11 +98,11 @@ int bus_message_dump(sd_bus_message *m, FILE *f, bool with_header) {
                                 ansi_highlight_red(), strna(m->error.message), ansi_highlight_off());
 
                 if (m->monotonic != 0)
-                        fprintf(f, "  Monotonic=%llu", (unsigned long long) m->monotonic);
+                        fprintf(f, "  Monotonic="USEC_FMT, m->monotonic);
                 if (m->realtime != 0)
-                        fprintf(f, "  Realtime=%llu", (unsigned long long) m->realtime);
+                        fprintf(f, "  Realtime="USEC_FMT, m->realtime);
                 if (m->seqnum != 0)
-                        fprintf(f, "  SequenceNumber=%llu", (unsigned long long) m->seqnum);
+                        fprintf(f, "  SequenceNumber=%"PRIu64, m->seqnum);
 
                 if (m->monotonic != 0 || m->realtime != 0 || m->seqnum != 0)
                         fputs("\n", f);
@@ -221,11 +221,11 @@ int bus_message_dump(sd_bus_message *m, FILE *f, bool with_header) {
                         break;
 
                 case SD_BUS_TYPE_INT64:
-                        fprintf(f, "%sINT64 %s%lli%s;\n", prefix, ansi_highlight(), (long long) basic.s64, ansi_highlight_off());
+                        fprintf(f, "%sINT64 %s%"PRIi64"%s;\n", prefix, ansi_highlight(), basic.s64, ansi_highlight_off());
                         break;
 
                 case SD_BUS_TYPE_UINT64:
-                        fprintf(f, "%sUINT64 %s%llu%s;\n", prefix, ansi_highlight(), (unsigned long long) basic.u64, ansi_highlight_off());
+                        fprintf(f, "%sUINT64 %s%"PRIu64"%s;\n", prefix, ansi_highlight(), basic.u64, ansi_highlight_off());
                         break;
 
                 case SD_BUS_TYPE_DOUBLE:
@@ -319,18 +319,18 @@ int bus_creds_dump(sd_bus_creds *c, FILE *f) {
                 f = stdout;
 
         if (c->mask & SD_BUS_CREDS_PID)
-                fprintf(f, "  PID=%lu", (unsigned long) c->pid);
+                fprintf(f, "  PID="PID_FMT, c->pid);
         if (c->mask & SD_BUS_CREDS_PID_STARTTIME)
-                fprintf(f, "  PIDStartTime=%llu", (unsigned long long) c->pid_starttime);
+                fprintf(f, "  PIDStartTime="USEC_FMT, c->pid_starttime);
         if (c->mask & SD_BUS_CREDS_TID)
-                fprintf(f, "  TID=%lu", (unsigned long) c->tid);
+                fprintf(f, "  TID="PID_FMT, c->tid);
         if (c->mask & SD_BUS_CREDS_UID)
-                fprintf(f, "  UID=%lu", (unsigned long) c->uid);
+                fprintf(f, "  UID="UID_FMT, c->uid);
         r = sd_bus_creds_get_owner_uid(c, &owner);
         if (r >= 0)
-                fprintf(f, "  OwnerUID=%lu", (unsigned long) owner);
+                fprintf(f, "  OwnerUID="UID_FMT, owner);
         if (c->mask & SD_BUS_CREDS_GID)
-                fprintf(f, "  GID=%lu", (unsigned long) c->gid);
+                fprintf(f, "  GID="GID_FMT, c->gid);
 
         if ((c->mask & (SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_TID|SD_BUS_CREDS_UID|SD_BUS_CREDS_GID)) || r >= 0)
                 fputs("\n", f);
@@ -387,11 +387,11 @@ int bus_creds_dump(sd_bus_creds *c, FILE *f) {
 
         if (sd_bus_creds_get_audit_login_uid(c, &audit_loginuid) >= 0) {
                 audit_loginuid_is_set = true;
-                fprintf(f, "  AuditLoginUID=%lu", (unsigned long) audit_loginuid);
+                fprintf(f, "  AuditLoginUID="UID_FMT, audit_loginuid);
         }
         if (sd_bus_creds_get_audit_session_id(c, &audit_sessionid) >= 0) {
                 audit_sessionid_is_set = true;
-                fprintf(f, "  AuditSessionID=%lu", (unsigned long) audit_sessionid);
+                fprintf(f, "  AuditSessionID=%"PRIu32, audit_sessionid);
         }
 
         if (audit_loginuid_is_set || audit_sessionid_is_set)
index a4160ef..601ea5a 100644 (file)
@@ -40,7 +40,6 @@
 
 struct reply_callback {
         sd_bus_message_handler_t callback;
-        void *userdata;
         usec_t timeout;
         uint64_t cookie;
         unsigned prioq_idx;
@@ -48,13 +47,23 @@ struct reply_callback {
 
 struct filter_callback {
         sd_bus_message_handler_t callback;
-        void *userdata;
 
         unsigned last_iteration;
 
         LIST_FIELDS(struct filter_callback, callbacks);
 };
 
+struct match_callback {
+        sd_bus_message_handler_t callback;
+
+        uint64_t cookie;
+        unsigned last_iteration;
+
+        char *match_string;
+
+        struct bus_match_node *match_node;
+};
+
 struct node {
         char *path;
         struct node *parent;
@@ -64,8 +73,7 @@ struct node {
         LIST_HEAD(struct node_callback, callbacks);
         LIST_HEAD(struct node_vtable, vtables);
         LIST_HEAD(struct node_enumerator, enumerators);
-
-        bool object_manager;
+        LIST_HEAD(struct node_object_manager, object_managers);
 };
 
 struct node_callback {
@@ -73,7 +81,6 @@ struct node_callback {
 
         bool is_fallback;
         sd_bus_message_handler_t callback;
-        void *userdata;
 
         unsigned last_iteration;
 
@@ -84,20 +91,24 @@ struct node_enumerator {
         struct node *node;
 
         sd_bus_node_enumerator_t callback;
-        void *userdata;
 
         unsigned last_iteration;
 
         LIST_FIELDS(struct node_enumerator, enumerators);
 };
 
+struct node_object_manager {
+        struct node *node;
+
+        LIST_FIELDS(struct node_object_manager, object_managers);
+};
+
 struct node_vtable {
         struct node *node;
 
         char *interface;
         bool is_fallback;
         const sd_bus_vtable *vtable;
-        void *userdata;
         sd_bus_object_find_t find;
 
         unsigned last_iteration;
@@ -114,6 +125,37 @@ struct vtable_member {
         const sd_bus_vtable *vtable;
 };
 
+typedef enum BusSlotType {
+        BUS_REPLY_CALLBACK,
+        BUS_FILTER_CALLBACK,
+        BUS_MATCH_CALLBACK,
+        BUS_NODE_CALLBACK,
+        BUS_NODE_ENUMERATOR,
+        BUS_NODE_VTABLE,
+        BUS_NODE_OBJECT_MANAGER,
+        _BUS_SLOT_INVALID = -1,
+} BusSlotType;
+
+struct sd_bus_slot {
+        unsigned n_ref;
+        sd_bus *bus;
+        void *userdata;
+        BusSlotType type:5;
+        bool floating:1;
+
+        LIST_FIELDS(sd_bus_slot, slots);
+
+        union {
+                struct reply_callback reply_callback;
+                struct filter_callback filter_callback;
+                struct match_callback match_callback;
+                struct node_callback node_callback;
+                struct node_enumerator node_enumerator;
+                struct node_object_manager node_object_manager;
+                struct node_vtable node_vtable;
+        };
+};
+
 enum bus_state {
         BUS_UNSET,
         BUS_OPENING,
@@ -195,12 +237,7 @@ struct sd_bus {
         Hashmap *vtable_methods;
         Hashmap *vtable_properties;
 
-        union {
-                struct sockaddr sa;
-                struct sockaddr_un un;
-                struct sockaddr_in in;
-                struct sockaddr_in6 in6;
-        } sockaddr;
+        union sockaddr_union sockaddr;
         socklen_t sockaddr_size;
 
         char *kernel;
@@ -231,7 +268,6 @@ struct sd_bus {
         char *exec_path;
         char **exec_argv;
 
-        uint64_t hello_cookie;
         unsigned iteration_counter;
 
         void *kdbus_buffer;
@@ -260,7 +296,10 @@ struct sd_bus {
         sd_event *event;
         int event_priority;
 
-        sd_bus_message *current;
+        sd_bus_message *current_message;
+        sd_bus_slot *current_slot;
+        sd_bus_message_handler_t current_handler;
+        void *current_userdata;
 
         sd_bus **default_bus_ptr;
         pid_t tid;
@@ -274,6 +313,10 @@ struct sd_bus {
 
         size_t bloom_size;
         unsigned bloom_n_hash;
+
+        sd_bus_track *track_queue;
+
+        LIST_HEAD(sd_bus_slot, slots);
 };
 
 #define BUS_DEFAULT_TIMEOUT ((usec_t) (25 * USEC_PER_SEC))
@@ -333,3 +376,12 @@ char *bus_address_escape(const char *v);
  * on */
 #define BUS_DONT_DESTROY(bus) \
         _cleanup_bus_unref_ _unused_ sd_bus *_dont_destroy_##bus = sd_bus_ref(bus)
+
+int bus_set_address_system(sd_bus *bus);
+int bus_set_address_user(sd_bus *bus);
+int bus_set_address_system_remote(sd_bus *b, const char *host);
+int bus_set_address_system_container(sd_bus *b, const char *machine);
+
+int bus_remove_match_by_string(sd_bus *bus, const char *match, sd_bus_message_handler_t callback, void *userdata);
+
+int bus_get_root_path(sd_bus *bus);
index eec62ac..c164088 100644 (file)
@@ -36,6 +36,7 @@
 #include "bus-kernel.h"
 #include "bus-bloom.h"
 #include "bus-util.h"
+#include "bus-label.h"
 #include "cgroup-util.h"
 
 #define UNIQUE_NAME_MAX (3+DECIMAL_STR_MAX(uint64_t))
@@ -265,7 +266,7 @@ static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) {
                 well_known ? 0 :
                 m->destination ? unique : KDBUS_DST_ID_BROADCAST;
         m->kdbus->payload_type = KDBUS_PAYLOAD_DBUS;
-        m->kdbus->cookie = m->header->serial;
+        m->kdbus->cookie = (uint64_t) m->header->serial;
         m->kdbus->priority = m->priority;
 
         if (m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
@@ -400,10 +401,8 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) {
         if (n_bytes != total)
                 return -EBADMSG;
 
-        /* on kdbus we only speak native endian gvariant, never dbus1
-         * marshalling or reverse endian */
-        if (h->version != 2 ||
-            h->endian != BUS_NATIVE_ENDIAN)
+        /* on kdbus we only speak native endian, never reverse endian */
+        if (h->endian != BUS_NATIVE_ENDIAN)
                 return -EPROTOTYPE;
 
         r = bus_message_from_header(bus, h, sizeof(struct bus_header), fds, n_fds, NULL, seclabel, 0, &m);
@@ -541,11 +540,9 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) {
                         m->creds.cgroup = d->str;
                         m->creds.mask |= (SD_BUS_CREDS_CGROUP|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_SESSION|SD_BUS_CREDS_OWNER_UID) & bus->creds_mask;
 
-                        if (!bus->cgroup_root) {
-                                r = cg_get_root_path(&bus->cgroup_root);
-                                if (r < 0)
-                                        goto fail;
-                        }
+                        r = bus_get_root_path(bus);
+                        if (r < 0)
+                                goto fail;
 
                         m->creds.cgroup_root = bus->cgroup_root;
 
@@ -658,7 +655,7 @@ int bus_kernel_take_fd(sd_bus *b) {
         b->use_memfd = 1;
 
         if (b->connection_name) {
-                g = sd_bus_label_escape(b->connection_name);
+                g = bus_label_escape(b->connection_name);
                 if (!g)
                         return -ENOMEM;
 
@@ -678,7 +675,7 @@ int bus_kernel_take_fd(sd_bus *b) {
                 } else {
                         _cleanup_free_ char *e = NULL;
 
-                        e = sd_bus_label_escape(pr);
+                        e = bus_label_escape(pr);
                         if (!e)
                                 return -ENOMEM;
 
@@ -691,7 +688,7 @@ int bus_kernel_take_fd(sd_bus *b) {
                         name = g;
                 }
 
-                b->connection_name = sd_bus_label_unescape(name);
+                b->connection_name = bus_label_unescape(name);
                 if (!b->connection_name)
                         return -ENOMEM;
         }
@@ -768,7 +765,7 @@ int bus_kernel_take_fd(sd_bus *b) {
         b->is_kernel = true;
         b->bus_client = true;
         b->can_fds = !!(hello->conn_flags & KDBUS_HELLO_ACCEPT_FD);
-        b->message_version = 2;
+        b->message_version = 1;
         b->message_endian = BUS_NATIVE_ENDIAN;
 
         /* the kernel told us the UUID of the underlying bus */
@@ -810,7 +807,7 @@ static void close_kdbus_msg(sd_bus *bus, struct kdbus_msg *k) {
                 if (d->type == KDBUS_ITEM_FDS)
                         close_many(d->fds, (d->size - offsetof(struct kdbus_item, fds)) / sizeof(int));
                 else if (d->type == KDBUS_ITEM_PAYLOAD_MEMFD)
-                        close_nointr_nofail(d->memfd.fd);
+                        safe_close(d->memfd.fd);
         }
 }
 
@@ -1119,7 +1116,7 @@ int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *mapped, size_t *al
 
                 assert(bus->connection_name);
 
-                g = sd_bus_label_escape(bus->connection_name);
+                g = bus_label_escape(bus->connection_name);
                 if (!g)
                         return -ENOMEM;
 
@@ -1164,7 +1161,7 @@ static void close_and_munmap(int fd, void *address, size_t size) {
         if (size > 0)
                 assert_se(munmap(address, PAGE_ALIGN(size)) >= 0);
 
-        close_nointr_nofail(fd);
+        safe_close(fd);
 }
 
 void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t mapped, size_t allocated) {
@@ -1304,22 +1301,22 @@ int bus_kernel_create_bus(const char *name, bool world, char **s) {
         make->size += ALIGN8(n->size);
 
         n = KDBUS_ITEM_NEXT(n);
-        sprintf(n->str, "%lu-%s", (unsigned long) getuid(), name);
+        sprintf(n->str, UID_FMT "-%s", getuid(), name);
         n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
         n->type = KDBUS_ITEM_MAKE_NAME;
         make->size += ALIGN8(n->size);
 
-        make->flags = KDBUS_MAKE_POLICY_OPEN | (world ? KDBUS_MAKE_ACCESS_WORLD : 0);
+        make->flags = world ? KDBUS_MAKE_ACCESS_WORLD : 0;
 
         if (ioctl(fd, KDBUS_CMD_BUS_MAKE, make) < 0) {
-                close_nointr_nofail(fd);
+                safe_close(fd);
                 return -errno;
         }
 
         /* The higher 32bit of the flags field are considered
          * 'incompatible flags'. Refuse them all for now. */
         if (make->flags > 0xFFFFFFFFULL) {
-                close_nointr_nofail(fd);
+                safe_close(fd);
                 return -ENOTSUP;
         }
 
@@ -1328,7 +1325,7 @@ int bus_kernel_create_bus(const char *name, bool world, char **s) {
 
                 p = strjoin("/dev/kdbus/", n->str, "/bus", NULL);
                 if (!p) {
-                        close_nointr_nofail(fd);
+                        safe_close(fd);
                         return -ENOMEM;
                 }
 
@@ -1338,52 +1335,164 @@ int bus_kernel_create_bus(const char *name, bool world, char **s) {
         return fd;
 }
 
-int bus_kernel_create_starter(const char *bus, const char *name) {
-        struct kdbus_cmd_hello *hello;
-        struct kdbus_item *n;
+static int bus_kernel_translate_access(BusNamePolicyAccess access) {
+        assert(access >= 0);
+        assert(access < _BUSNAME_POLICY_ACCESS_MAX);
+
+        switch (access) {
+
+        case BUSNAME_POLICY_ACCESS_SEE:
+                return KDBUS_POLICY_SEE;
+
+        case BUSNAME_POLICY_ACCESS_TALK:
+                return KDBUS_POLICY_TALK;
+
+        case BUSNAME_POLICY_ACCESS_OWN:
+                return KDBUS_POLICY_OWN;
+
+        default:
+                assert_not_reached("Unknown policy access");
+        }
+}
+
+static int bus_kernel_translate_policy(const BusNamePolicy *policy, struct kdbus_item *item) {
+        int r;
+
+        assert(policy);
+        assert(item);
+
+        switch (policy->type) {
+
+        case BUSNAME_POLICY_TYPE_USER: {
+                const char *user = policy->name;
+                uid_t uid;
+
+                r = get_user_creds(&user, &uid, NULL, NULL, NULL);
+                if (r < 0)
+                        return r;
+
+                item->policy_access.type = KDBUS_POLICY_ACCESS_USER;
+                item->policy_access.id = uid;
+                break;
+        }
+
+        case BUSNAME_POLICY_TYPE_GROUP: {
+                const char *group = policy->name;
+                gid_t gid;
+
+                r = get_group_creds(&group, &gid);
+                if (r < 0)
+                        return r;
+
+                item->policy_access.type = KDBUS_POLICY_ACCESS_GROUP;
+                item->policy_access.id = gid;
+                break;
+        }
+
+        default:
+                assert_not_reached("Unknown policy type");
+        }
+
+        item->policy_access.access = bus_kernel_translate_access(policy->access);
+
+        return 0;
+}
+
+int bus_kernel_open_bus_fd(const char *bus, char **path) {
         char *p;
         int fd;
+        size_t len;
 
-        assert(bus);
-        assert(name);
+        len = strlen("/dev/kdbus/") + DECIMAL_STR_MAX(uid_t) + 1 + strlen(bus) + strlen("/bus") + 1;
 
-        p = alloca(sizeof("/dev/kdbus/") - 1 + DECIMAL_STR_MAX(uid_t) + 1 + strlen(bus) + sizeof("/bus"));
-        sprintf(p, "/dev/kdbus/%lu-%s/bus", (unsigned long) getuid(), bus);
+        if (path) {
+                p = malloc(len);
+                if (!p)
+                        return -ENOMEM;
+                *path = p;
+        } else
+                p = alloca(len);
+        sprintf(p, "/dev/kdbus/" UID_FMT "-%s/bus", getuid(), bus);
 
         fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC);
         if (fd < 0)
                 return -errno;
 
-        hello = alloca0(ALIGN8(offsetof(struct kdbus_cmd_hello, items) +
-                               offsetof(struct kdbus_item, str) +
-                               strlen(name) + 1));
+        return fd;
+}
+
+int bus_kernel_make_starter(
+                int fd,
+                const char *name,
+                bool activating,
+                bool accept_fd,
+                BusNamePolicy *policy,
+                BusNamePolicyAccess world_policy) {
+
+        struct kdbus_cmd_hello *hello;
+        struct kdbus_item *n;
+        size_t policy_cnt = 0;
+        BusNamePolicy *po;
+        size_t size;
+        int r;
+
+        assert(fd >= 0);
+        assert(name);
+
+        LIST_FOREACH(policy, po, policy)
+                policy_cnt++;
+
+        if (world_policy >= 0)
+                policy_cnt++;
+
+        size = ALIGN8(offsetof(struct kdbus_cmd_hello, items)) +
+               ALIGN8(offsetof(struct kdbus_item, str) + strlen(name) + 1) +
+               policy_cnt * ALIGN8(offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access));
+
+        hello = alloca0(size);
 
         n = hello->items;
         strcpy(n->str, name);
         n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
         n->type = KDBUS_ITEM_NAME;
+        n = KDBUS_ITEM_NEXT(n);
 
-        hello->size = ALIGN8(offsetof(struct kdbus_cmd_hello, items) + n->size);
-        hello->conn_flags = KDBUS_HELLO_ACTIVATOR;
+        LIST_FOREACH(policy, po, policy) {
+                n->type = KDBUS_ITEM_POLICY_ACCESS;
+                n->size = offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access);
+
+                r = bus_kernel_translate_policy(po, n);
+                if (r < 0)
+                        return r;
+
+                n = KDBUS_ITEM_NEXT(n);
+        }
+
+        if (world_policy >= 0) {
+                n->type = KDBUS_ITEM_POLICY_ACCESS;
+                n->size = offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access);
+                n->policy_access.type = KDBUS_POLICY_ACCESS_WORLD;
+                n->policy_access.access = bus_kernel_translate_access(world_policy);
+        }
+
+        hello->size = size;
+        hello->conn_flags =
+                (activating ? KDBUS_HELLO_ACTIVATOR : KDBUS_HELLO_POLICY_HOLDER) |
+                (accept_fd ? KDBUS_HELLO_ACCEPT_FD : 0);
         hello->pool_size = KDBUS_POOL_SIZE;
+        hello->attach_flags = _KDBUS_ATTACH_ALL;
 
-        if (ioctl(fd, KDBUS_CMD_HELLO, hello) < 0) {
-                close_nointr_nofail(fd);
+        if (ioctl(fd, KDBUS_CMD_HELLO, hello) < 0)
                 return -errno;
-        }
 
         /* The higher 32bit of both flags fields are considered
          * 'incompatible flags'. Refuse them all for now. */
         if (hello->bus_flags > 0xFFFFFFFFULL ||
-            hello->conn_flags > 0xFFFFFFFFULL) {
-                close_nointr_nofail(fd);
+            hello->conn_flags > 0xFFFFFFFFULL)
                 return -ENOTSUP;
-        }
 
-        if (!bloom_validate_parameters((size_t) hello->bloom.size, (unsigned) hello->bloom.n_hash)) {
-                close_nointr_nofail(fd);
+        if (!bloom_validate_parameters((size_t) hello->bloom.size, (unsigned) hello->bloom.n_hash))
                 return -ENOTSUP;
-        }
 
         return fd;
 }
@@ -1410,17 +1519,17 @@ int bus_kernel_create_domain(const char *name, char **s) {
         n->type = KDBUS_ITEM_MAKE_NAME;
 
         make->size = ALIGN8(offsetof(struct kdbus_cmd_make, items) + n->size);
-        make->flags = KDBUS_MAKE_POLICY_OPEN | KDBUS_MAKE_ACCESS_WORLD;
+        make->flags = KDBUS_MAKE_ACCESS_WORLD;
 
         if (ioctl(fd, KDBUS_CMD_DOMAIN_MAKE, make) < 0) {
-                close_nointr_nofail(fd);
+                safe_close(fd);
                 return -errno;
         }
 
         /* The higher 32bit of the flags field are considered
          * 'incompatible flags'. Refuse them all for now. */
         if (make->flags > 0xFFFFFFFFULL) {
-                close_nointr_nofail(fd);
+                safe_close(fd);
                 return -ENOTSUP;
         }
 
@@ -1429,7 +1538,7 @@ int bus_kernel_create_domain(const char *name, char **s) {
 
                 p = strappend("/dev/kdbus/domain/", name);
                 if (!p) {
-                        close_nointr_nofail(fd);
+                        safe_close(fd);
                         return -ENOMEM;
                 }
 
@@ -1441,17 +1550,13 @@ int bus_kernel_create_domain(const char *name, char **s) {
 
 int bus_kernel_create_monitor(const char *bus) {
         struct kdbus_cmd_hello *hello;
-        char *p;
         int fd;
 
         assert(bus);
 
-        p = alloca(sizeof("/dev/kdbus/") - 1 + DECIMAL_STR_MAX(uid_t) + 1 + strlen(bus) + sizeof("/bus"));
-        sprintf(p, "/dev/kdbus/%lu-%s/bus", (unsigned long) getuid(), bus);
-
-        fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC);
+        fd = bus_kernel_open_bus_fd(bus, NULL);
         if (fd < 0)
-                return -errno;
+                return fd;
 
         hello = alloca0(sizeof(struct kdbus_cmd_hello));
         hello->size = sizeof(struct kdbus_cmd_hello);
@@ -1459,7 +1564,7 @@ int bus_kernel_create_monitor(const char *bus) {
         hello->pool_size = KDBUS_POOL_SIZE;
 
         if (ioctl(fd, KDBUS_CMD_HELLO, hello) < 0) {
-                close_nointr_nofail(fd);
+                safe_close(fd);
                 return -errno;
         }
 
@@ -1467,7 +1572,7 @@ int bus_kernel_create_monitor(const char *bus) {
          * 'incompatible flags'. Refuse them all for now. */
         if (hello->bus_flags > 0xFFFFFFFFULL ||
             hello->conn_flags > 0xFFFFFFFFULL) {
-                close_nointr_nofail(fd);
+                safe_close(fd);
                 return -ENOTSUP;
         }
 
index 8db418a..87f98c5 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <stdbool.h>
 
+#include "busname.h"
 #include "sd-bus.h"
 
 #define KDBUS_ITEM_NEXT(item) \
@@ -30,7 +31,8 @@
 
 #define KDBUS_ITEM_FOREACH(part, head, first)                           \
         for (part = (head)->first;                                      \
-             (uint8_t *)(part) < (uint8_t *)(head) + (head)->size;      \
+             ((uint8_t *)(part) < (uint8_t *)(head) + (head)->size) &&  \
+                ((uint8_t *) part >= (uint8_t *) head);                 \
              part = KDBUS_ITEM_NEXT(part))
 
 #define KDBUS_ITEM_HEADER_SIZE offsetof(struct kdbus_item, data)
@@ -63,9 +65,11 @@ int bus_kernel_take_fd(sd_bus *b);
 int bus_kernel_write_message(sd_bus *bus, sd_bus_message *m, bool hint_sync_call);
 int bus_kernel_read_message(sd_bus *bus, bool hint_priority, int64_t priority);
 
+int bus_kernel_open_bus_fd(const char *bus, char **path);
+int bus_kernel_make_starter(int fd, const char *name, bool activating, bool accept_fd, BusNamePolicy *policy, BusNamePolicyAccess world_policy);
+
 int bus_kernel_create_bus(const char *name, bool world, char **s);
 int bus_kernel_create_domain(const char *name, char **s);
-int bus_kernel_create_starter(const char *bus, const char *name);
 int bus_kernel_create_monitor(const char *bus);
 
 int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *mapped, size_t *allocated);
index 8280488..88b61a7 100644 (file)
@@ -116,6 +116,9 @@ static void bus_match_node_free(struct bus_match_node *node) {
 static bool bus_match_node_maybe_free(struct bus_match_node *node) {
         assert(node);
 
+        if (node->type == BUS_MATCH_ROOT)
+                return false;
+
         if (node->child)
                 return false;
 
@@ -275,10 +278,10 @@ int bus_match_run(
         case BUS_MATCH_LEAF:
 
                 if (bus) {
-                        if (node->leaf.last_iteration == bus->iteration_counter)
+                        if (node->leaf.callback->last_iteration == bus->iteration_counter)
                                 return 0;
 
-                        node->leaf.last_iteration = bus->iteration_counter;
+                        node->leaf.callback->last_iteration = bus->iteration_counter;
                 }
 
                 r = sd_bus_message_rewind(m, true);
@@ -286,13 +289,29 @@ int bus_match_run(
                         return r;
 
                 /* Run the callback. And then invoke siblings. */
-                if (node->leaf.callback) {
+                if (node->leaf.callback->callback) {
                         _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
+                        sd_bus_slot *slot;
+
+                        slot = container_of(node->leaf.callback, sd_bus_slot, match_callback);
+                        if (bus) {
+                                bus->current_slot = sd_bus_slot_ref(slot);
+                                bus->current_handler = node->leaf.callback->callback;
+                                bus->current_userdata = slot->userdata;
+                        }
+                        r = node->leaf.callback->callback(bus, m, slot->userdata, &error_buffer);
+                        if (bus) {
+                                bus->current_userdata = NULL;
+                                bus->current_handler = NULL;
+                                bus->current_slot = sd_bus_slot_unref(slot);
+                        }
 
-                        r = node->leaf.callback(bus, m, node->leaf.userdata, &error_buffer);
                         r = bus_maybe_reply_error(m, r, &error_buffer);
                         if (r != 0)
                                 return r;
+
+                        if (bus && bus->match_callbacks_modified)
+                                return 0;
                 }
 
                 return bus_match_run(bus, node->next, m);
@@ -532,16 +551,13 @@ static int bus_match_find_compare_value(
 
 static int bus_match_add_leaf(
                 struct bus_match_node *where,
-                sd_bus_message_handler_t callback,
-                void *userdata,
-                uint64_t cookie,
-                struct bus_match_node **ret) {
+                struct match_callback *callback) {
 
         struct bus_match_node *n;
 
         assert(where);
         assert(where->type == BUS_MATCH_ROOT || where->type == BUS_MATCH_VALUE);
-        assert(ret);
+        assert(callback);
 
         n = new0(struct bus_match_node, 1);
         if (!n)
@@ -552,13 +568,12 @@ static int bus_match_add_leaf(
         n->next = where->child;
         if (n->next)
                 n->next->prev = n;
+
         n->leaf.callback = callback;
-        n->leaf.userdata = userdata;
-        n->leaf.cookie = cookie;
+        callback->match_node = n;
 
         where->child = n;
 
-        *ret = n;
         return 1;
 }
 
@@ -575,9 +590,13 @@ static int bus_match_find_leaf(
         assert(ret);
 
         for (c = where->child; c; c = c->next) {
+                sd_bus_slot *s;
+
+                s = container_of(c->leaf.callback, sd_bus_slot, match_callback);
+
                 if (c->type == BUS_MATCH_LEAF &&
-                    c->leaf.callback == callback &&
-                    c->leaf.userdata == userdata) {
+                    c->leaf.callback->callback == callback &&
+                    s->userdata == userdata) {
                         *ret = c;
                         return 1;
                 }
@@ -889,16 +908,14 @@ int bus_match_add(
                 struct bus_match_node *root,
                 struct bus_match_component *components,
                 unsigned n_components,
-                sd_bus_message_handler_t callback,
-                void *userdata,
-                uint64_t cookie,
-                struct bus_match_node **ret) {
+                struct match_callback *callback) {
 
         unsigned i;
         struct bus_match_node *n;
         int r;
 
         assert(root);
+        assert(callback);
 
         n = root;
         for (i = 0; i < n_components; i++) {
@@ -909,29 +926,56 @@ int bus_match_add(
                         return r;
         }
 
-        r = bus_match_add_leaf(n, callback, userdata, cookie, &n);
-        if (r < 0)
-                return r;
+        return bus_match_add_leaf(n, callback);
+}
 
-        if (ret)
-                *ret = n;
+int bus_match_remove(
+                struct bus_match_node *root,
+                struct match_callback *callback) {
 
-        return 0;
+        struct bus_match_node *node, *pp;
+
+        assert(root);
+        assert(callback);
+
+        node = callback->match_node;
+        if (!node)
+                return 0;
+
+        assert(node->type == BUS_MATCH_LEAF);
+
+        callback->match_node = NULL;
+
+        /* Free the leaf */
+        pp = node->parent;
+        bus_match_node_free(node);
+
+        /* Prune the tree above */
+        while (pp) {
+                node = pp;
+                pp = node->parent;
+
+                if (!bus_match_node_maybe_free(node))
+                        break;
+        }
+
+        return 1;
 }
 
-int bus_match_remove(
+int bus_match_find(
                 struct bus_match_node *root,
                 struct bus_match_component *components,
                 unsigned n_components,
                 sd_bus_message_handler_t callback,
                 void *userdata,
-                uint64_t *cookie) {
+                struct match_callback **ret) {
 
-        unsigned i;
         struct bus_match_node *n, **gc;
+        unsigned i;
         int r;
 
         assert(root);
+        assert(ret);
 
         gc = newa(struct bus_match_node*, n_components);
 
@@ -951,24 +995,8 @@ int bus_match_remove(
         if (r <= 0)
                 return r;
 
-        if (cookie)
-                *cookie = n->leaf.cookie;
-
-        /* Free the leaf */
-        bus_match_node_free(n);
-
-        /* Prune the tree above */
-        for (i = n_components; i > 0; i --) {
-                struct bus_match_node *p = gc[i-1]->parent;
-
-                if (!bus_match_node_maybe_free(gc[i-1]))
-                        break;
-
-                if (!bus_match_node_maybe_free(p))
-                        break;
-        }
-
-        return r;
+        *ret = n->leaf.callback;
+        return 1;
 }
 
 void bus_match_free(struct bus_match_node *node) {
@@ -1062,7 +1090,7 @@ void bus_match_dump(struct bus_match_node *node, unsigned level) {
         } else if (node->type == BUS_MATCH_ROOT)
                 puts(" root");
         else if (node->type == BUS_MATCH_LEAF)
-                printf(" %p/%p\n", node->leaf.callback, node->leaf.userdata);
+                printf(" %p/%p\n", node->leaf.callback->callback, container_of(node->leaf.callback, sd_bus_slot, match_callback)->userdata);
         else
                 putchar('\n');
 
index 056082b..af5f65d 100644 (file)
@@ -58,10 +58,7 @@ struct bus_match_node {
                         uint8_t u8;
                 } value;
                 struct {
-                        sd_bus_message_handler_t callback;
-                        void *userdata;
-                        unsigned last_iteration;
-                        uint64_t cookie;
+                        struct match_callback *callback;
                 } leaf;
                 struct {
                         /* If this is set, then the child is NULL */
@@ -78,8 +75,10 @@ struct bus_match_component {
 
 int bus_match_run(sd_bus *bus, struct bus_match_node *root, sd_bus_message *m);
 
-int bus_match_add(struct bus_match_node *root, struct bus_match_component *components, unsigned n_components, sd_bus_message_handler_t callback, void *userdata, uint64_t cookie, struct bus_match_node **ret);
-int bus_match_remove(struct bus_match_node *root, struct bus_match_component *components, unsigned n_components, sd_bus_message_handler_t callback, void *userdata, uint64_t *cookie);
+int bus_match_add(struct bus_match_node *root, struct bus_match_component *components, unsigned n_components, struct match_callback *callback);
+int bus_match_remove(struct bus_match_node *root, struct match_callback *callback);
+
+int bus_match_find(struct bus_match_node *root, struct bus_match_component *components, unsigned n_components, sd_bus_message_handler_t callback, void *userdata, struct match_callback **ret);
 
 void bus_match_free(struct bus_match_node *node);
 
index fb894ef..35c91a8 100644 (file)
@@ -70,7 +70,7 @@ static void message_free_part(sd_bus_message *m, struct bus_body_part *part) {
                         if (part->mapped > 0)
                                 assert_se(munmap(part->data, part->mapped) == 0);
 
-                        close_nointr_nofail(part->memfd);
+                        safe_close(part->memfd);
                 }
 
         } else if (part->munmap_this)
@@ -136,8 +136,7 @@ static void message_free(sd_bus_message *m) {
                 ioctl(m->bus->input_fd, KDBUS_CMD_FREE, &off);
         }
 
-        if (m->bus)
-                sd_bus_unref(m->bus);
+        sd_bus_unref(m->bus);
 
         if (m->free_fds) {
                 close_many(m->fds, m->n_fds);
@@ -373,6 +372,7 @@ int bus_message_from_header(
         struct bus_header *h;
         size_t a, label_sz;
 
+        assert(bus);
         assert(buffer || length <= 0);
         assert(fds || n_fds <= 0);
         assert(ret);
@@ -426,10 +426,9 @@ int bus_message_from_header(
                 m->creds.mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
         }
 
-        if (bus)
-                m->bus = sd_bus_ref(bus);
-
+        m->bus = sd_bus_ref(bus);
         *ret = m;
+
         return 0;
 }
 
@@ -489,6 +488,8 @@ fail:
 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
         sd_bus_message *m;
 
+        assert(bus);
+
         m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
         if (!m)
                 return NULL;
@@ -500,9 +501,7 @@ static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
         m->header->version = bus ? bus->message_version : 1;
         m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
         m->root_container.need_offsets = BUS_MESSAGE_IS_GVARIANT(m);
-
-        if (bus)
-                m->bus = sd_bus_ref(bus);
+        m->bus = sd_bus_ref(bus);
 
         return m;
 }
@@ -517,7 +516,8 @@ _public_ int sd_bus_message_new_signal(
         sd_bus_message *t;
         int r;
 
-        assert_return(!bus || bus->state != BUS_UNSET, -ENOTCONN);
+        assert_return(bus, -ENOTCONN);
+        assert_return(bus->state != BUS_UNSET, -ENOTCONN);
         assert_return(object_path_is_valid(path), -EINVAL);
         assert_return(interface_name_is_valid(interface), -EINVAL);
         assert_return(member_name_is_valid(member), -EINVAL);
@@ -558,7 +558,8 @@ _public_ int sd_bus_message_new_method_call(
         sd_bus_message *t;
         int r;
 
-        assert_return(!bus || bus->state != BUS_UNSET, -ENOTCONN);
+        assert_return(bus, -ENOTCONN);
+        assert_return(bus->state != BUS_UNSET, -ENOTCONN);
         assert_return(!destination || service_name_is_valid(destination), -EINVAL);
         assert_return(object_path_is_valid(path), -EINVAL);
         assert_return(!interface || interface_name_is_valid(interface), -EINVAL);
@@ -607,7 +608,7 @@ static int message_new_reply(
         assert_return(call, -EINVAL);
         assert_return(call->sealed, -EPERM);
         assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
-        assert_return(!call->bus || call->bus->state != BUS_UNSET, -ENOTCONN);
+        assert_return(call->bus->state != BUS_UNSET, -ENOTCONN);
         assert_return(m, -EINVAL);
 
         t = message_new(call->bus, type);
@@ -617,7 +618,7 @@ static int message_new_reply(
         t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
         t->reply_cookie = BUS_MESSAGE_COOKIE(call);
 
-        r = message_append_field_uint32(t, BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_cookie);
+        r = message_append_field_uint32(t, BUS_MESSAGE_HEADER_REPLY_SERIAL, (uint32_t) t->reply_cookie);
         if (r < 0)
                 goto fail;
 
@@ -742,6 +743,7 @@ int bus_message_new_synthetic_error(
         sd_bus_message *t;
         int r;
 
+        assert(bus);
         assert(sd_bus_error_is_set(e));
         assert(m);
 
@@ -752,7 +754,7 @@ int bus_message_new_synthetic_error(
         t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
         t->reply_cookie = cookie;
 
-        r = message_append_field_uint32(t, BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_cookie);
+        r = message_append_field_uint32(t, BUS_MESSAGE_HEADER_REPLY_SERIAL, (uint32_t) t->reply_cookie);
         if (r < 0)
                 goto fail;
 
@@ -799,9 +801,10 @@ _public_ sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
         assert(m->n_ref > 0);
         m->n_ref--;
 
-        if (m->n_ref <= 0)
-                message_free(m);
+        if (m->n_ref > 0)
+                return NULL;
 
+        message_free(m);
         return NULL;
 }
 
@@ -1274,7 +1277,7 @@ static int message_push_fd(sd_bus_message *m, int fd) {
         f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
         if (!f) {
                 m->poisoned = true;
-                close_nointr_nofail(copy);
+                safe_close(copy);
                 return -ENOMEM;
         }
 
@@ -2784,7 +2787,7 @@ int bus_message_seal(sd_bus_message *m, uint64_t cookie, usec_t timeout) {
         /* If this is something we can send as memfd, then let's seal
         the memfd now. Note that we can send memfds as payload only
         for directed messages, and not for broadcasts. */
-        if (m->destination && m->bus && m->bus->use_memfd) {
+        if (m->destination && m->bus->use_memfd) {
                 MESSAGE_FOREACH_PART(part, i, m)
                         if (part->memfd >= 0 && !part->sealed && (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0)) {
                                 uint64_t sz;
@@ -2837,7 +2840,7 @@ int bus_body_part_map(struct bus_body_part *part) {
         psz = PAGE_ALIGN(part->size);
 
         if (part->memfd >= 0)
-                p = mmap(NULL, psz, PROT_READ, MAP_SHARED, part->memfd, 0);
+                p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE, part->memfd, 0);
         else if (part->is_zero)
                 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
         else
@@ -4215,7 +4218,7 @@ static int message_read_ap(
          * in a single stackframe. We hence implement our own
          * home-grown stack in an array. */
 
-        n_array = (unsigned) -1; /* lenght of current array entries */
+        n_array = (unsigned) -1; /* length of current array entries */
         n_struct = strlen(types); /* length of current struct contents signature */
 
         for (;;) {
@@ -4885,6 +4888,7 @@ int bus_message_parse_fields(sd_bus_message *m) {
         size_t ri;
         int r;
         uint32_t unix_fds = 0;
+        bool unix_fds_set = false;
         void *offsets = NULL;
         unsigned n_offsets = 0;
         size_t sz = 0;
@@ -5044,7 +5048,7 @@ int bus_message_parse_fields(sd_bus_message *m) {
 
                         r = message_peek_field_string(m, service_name_is_valid, &ri, item_size, &m->sender);
 
-                        if (r >= 0 && m->sender[0] == ':' && m->bus && m->bus->bus_client && !m->bus->is_kernel) {
+                        if (r >= 0 && m->sender[0] == ':' && m->bus->bus_client && !m->bus->is_kernel) {
                                 m->creds.unique_name = (char*) m->sender;
                                 m->creds.mask |= SD_BUS_CREDS_UNIQUE_NAME & m->bus->creds_mask;
                         }
@@ -5075,24 +5079,29 @@ int bus_message_parse_fields(sd_bus_message *m) {
                         break;
                 }
 
-                case BUS_MESSAGE_HEADER_REPLY_SERIAL:
+                case BUS_MESSAGE_HEADER_REPLY_SERIAL: {
+                        uint32_t serial;
+
                         if (m->reply_cookie != 0)
                                 return -EBADMSG;
 
                         if (!streq(signature, "u"))
                                 return -EBADMSG;
 
-                        r = message_peek_field_uint32(m, &ri, item_size, &m->reply_cookie);
+                        r = message_peek_field_uint32(m, &ri, item_size, &serial);
                         if (r < 0)
                                 return r;
 
+                        m->reply_cookie = serial;
+
                         if (m->reply_cookie == 0)
                                 return -EBADMSG;
 
                         break;
+                }
 
                 case BUS_MESSAGE_HEADER_UNIX_FDS:
-                        if (unix_fds != 0)
+                        if (unix_fds_set)
                                 return -EBADMSG;
 
                         if (!streq(signature, "u"))
@@ -5102,9 +5111,7 @@ int bus_message_parse_fields(sd_bus_message *m) {
                         if (r < 0)
                                 return -EBADMSG;
 
-                        if (unix_fds == 0)
-                                return -EBADMSG;
-
+                        unix_fds_set = true;
                         break;
 
                 default:
@@ -5489,7 +5496,7 @@ int bus_message_remarshal(sd_bus *bus, sd_bus_message **m) {
                         return -ENOMEM;
 
                 n->reply_cookie = (*m)->reply_cookie;
-                r = message_append_field_uint32(n, BUS_MESSAGE_HEADER_REPLY_SERIAL, n->reply_cookie);
+                r = message_append_field_uint32(n, BUS_MESSAGE_HEADER_REPLY_SERIAL, (uint32_t) n->reply_cookie);
                 if (r < 0)
                         return r;
 
index 5fbe3e6..df79294 100644 (file)
@@ -84,7 +84,7 @@ struct sd_bus_message {
 
         sd_bus *bus;
 
-        uint32_t reply_cookie;
+        uint64_t reply_cookie;
 
         const char *path;
         const char *interface;
@@ -162,7 +162,8 @@ static inline uint64_t BUS_MESSAGE_BSWAP64(sd_bus_message *m, uint64_t u) {
         return BUS_MESSAGE_NEED_BSWAP(m) ? bswap_64(u) : u;
 }
 
-static inline uint32_t BUS_MESSAGE_COOKIE(sd_bus_message *m) {
+static inline uint64_t BUS_MESSAGE_COOKIE(sd_bus_message *m) {
+        /* Note that we return the serial converted to a 64bit value here */
         return BUS_MESSAGE_BSWAP32(m, m->header->serial);
 }
 
index 7d325fa..3a2de65 100644 (file)
@@ -28,8 +28,9 @@
 #include "bus-type.h"
 #include "bus-signature.h"
 #include "bus-introspect.h"
-#include "bus-objects.h"
 #include "bus-util.h"
+#include "bus-slot.h"
+#include "bus-objects.h"
 
 static int node_vtable_get_userdata(
                 sd_bus *bus,
@@ -38,6 +39,7 @@ static int node_vtable_get_userdata(
                 void **userdata,
                 sd_bus_error *error) {
 
+        sd_bus_slot *s;
         void *u;
         int r;
 
@@ -45,9 +47,15 @@ static int node_vtable_get_userdata(
         assert(path);
         assert(c);
 
-        u = c->userdata;
+        s = container_of(c, sd_bus_slot, node_vtable);
+        u = s->userdata;
         if (c->find) {
+                bus->current_slot = sd_bus_slot_ref(s);
+                bus->current_userdata = u;
                 r = c->find(bus, path, c->interface, u, &u, error);
+                bus->current_userdata = NULL;
+                bus->current_slot = sd_bus_slot_unref(s);
+
                 if (r < 0)
                         return r;
                 if (sd_bus_error_is_set(error))
@@ -109,11 +117,19 @@ static int add_enumerated_to_set(
 
         LIST_FOREACH(enumerators, c, first) {
                 char **children = NULL, **k;
+                sd_bus_slot *slot;
 
                 if (bus->nodes_modified)
                         return 0;
 
-                r = c->callback(bus, prefix, c->userdata, &children, error);
+                slot = container_of(c, sd_bus_slot, node_enumerator);
+
+                bus->current_slot = sd_bus_slot_ref(slot);
+                bus->current_userdata = slot->userdata;
+                r = c->callback(bus, prefix, slot->userdata, &children, error);
+                bus->current_userdata = NULL;
+                bus->current_slot = sd_bus_slot_unref(slot);
+
                 if (r < 0)
                         return r;
                 if (sd_bus_error_is_set(error))
@@ -239,6 +255,7 @@ static int node_callbacks_run(
 
         LIST_FOREACH(callbacks, c, first) {
                 _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
+                sd_bus_slot *slot;
 
                 if (bus->nodes_modified)
                         return 0;
@@ -257,7 +274,16 @@ static int node_callbacks_run(
                 if (r < 0)
                         return r;
 
-                r = c->callback(bus, m, c->userdata, &error_buffer);
+                slot = container_of(c, sd_bus_slot, node_callback);
+
+                bus->current_slot = sd_bus_slot_ref(slot);
+                bus->current_handler = c->callback;
+                bus->current_userdata = slot->userdata;
+                r = c->callback(bus, m, slot->userdata, &error_buffer);
+                bus->current_userdata = NULL;
+                bus->current_handler = NULL;
+                bus->current_slot = sd_bus_slot_unref(slot);
+
                 r = bus_maybe_reply_error(m, r, &error_buffer);
                 if (r != 0)
                         return r;
@@ -269,9 +295,7 @@ static int node_callbacks_run(
 #define CAPABILITY_SHIFT(x) (((x) >> __builtin_ctzll(_SD_BUS_VTABLE_CAPABILITY_MASK)) & 0xFFFF)
 
 static int check_access(sd_bus *bus, sd_bus_message *m, struct vtable_member *c, sd_bus_error *error) {
-        _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
         uint64_t cap;
-        uid_t uid;
         int r;
 
         assert(bus);
@@ -286,17 +310,6 @@ static int check_access(sd_bus *bus, sd_bus_message *m, struct vtable_member *c,
         if (c->vtable->flags & SD_BUS_VTABLE_UNPRIVILEGED)
                 return 0;
 
-        /* If we are not connected to kdbus we cannot retrieve the
-         * effective capability set without race. Since we need this
-         * for a security decision we cannot use racy data, hence
-         * don't request it. */
-        if (bus->is_kernel)
-                r = sd_bus_query_sender_creds(m, SD_BUS_CREDS_UID|SD_BUS_CREDS_EFFECTIVE_CAPS, &creds);
-        else
-                r = sd_bus_query_sender_creds(m, SD_BUS_CREDS_UID, &creds);
-        if (r < 0)
-                return r;
-
         /* Check have the caller has the requested capability
          * set. Note that the flags value contains the capability
          * number plus one, which we need to subtract here. We do this
@@ -310,16 +323,11 @@ static int check_access(sd_bus *bus, sd_bus_message *m, struct vtable_member *c,
         else
                 cap --;
 
-        r = sd_bus_creds_has_effective_cap(creds, cap);
+        r = sd_bus_query_sender_privilege(m, cap);
+        if (r < 0)
+                return r;
         if (r > 0)
-                return 1;
-
-        /* Caller has same UID as us, then let's grant access */
-        r = sd_bus_creds_get_uid(creds, &uid);
-        if (r >= 0) {
-                if (uid == getuid())
-                        return 1;
-        }
+                return 0;
 
         return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Access to %s.%s() not permitted.", c->interface, c->member);
 }
@@ -382,7 +390,18 @@ static int method_callbacks_run(
         m->enforced_reply_signature = strempty(c->vtable->x.method.result);
 
         if (c->vtable->x.method.handler) {
+                sd_bus_slot *slot;
+
+                slot = container_of(c->parent, sd_bus_slot, node_vtable);
+
+                bus->current_slot = sd_bus_slot_ref(slot);
+                bus->current_handler = c->vtable->x.method.handler;
+                bus->current_userdata = u;
                 r = c->vtable->x.method.handler(bus, m, u, &error);
+                bus->current_userdata = NULL;
+                bus->current_handler = NULL;
+                bus->current_slot = sd_bus_slot_unref(slot);
+
                 return bus_maybe_reply_error(m, r, &error);
         }
 
@@ -396,6 +415,7 @@ static int method_callbacks_run(
 
 static int invoke_property_get(
                 sd_bus *bus,
+                sd_bus_slot *slot,
                 const sd_bus_vtable *v,
                 const char *path,
                 const char *interface,
@@ -408,6 +428,7 @@ static int invoke_property_get(
         int r;
 
         assert(bus);
+        assert(slot);
         assert(v);
         assert(path);
         assert(interface);
@@ -415,7 +436,13 @@ static int invoke_property_get(
         assert(reply);
 
         if (v->x.property.get) {
+
+                bus->current_slot = sd_bus_slot_ref(slot);
+                bus->current_userdata = userdata;
                 r = v->x.property.get(bus, path, interface, property, reply, userdata, error);
+                bus->current_userdata = NULL;
+                bus->current_slot = sd_bus_slot_unref(slot);
+
                 if (r < 0)
                         return r;
                 if (sd_bus_error_is_set(error))
@@ -453,6 +480,7 @@ static int invoke_property_get(
 
 static int invoke_property_set(
                 sd_bus *bus,
+                sd_bus_slot *slot,
                 const sd_bus_vtable *v,
                 const char *path,
                 const char *interface,
@@ -464,6 +492,7 @@ static int invoke_property_set(
         int r;
 
         assert(bus);
+        assert(slot);
         assert(v);
         assert(path);
         assert(interface);
@@ -471,7 +500,13 @@ static int invoke_property_set(
         assert(value);
 
         if (v->x.property.set) {
+
+                bus->current_slot = sd_bus_slot_ref(slot);
+                bus->current_userdata = userdata;
                 r = v->x.property.set(bus, path, interface, property, value, userdata, error);
+                bus->current_userdata = NULL;
+                bus->current_slot = sd_bus_slot_unref(slot);
+
                 if (r < 0)
                         return r;
                 if (sd_bus_error_is_set(error))
@@ -527,6 +562,7 @@ static int property_get_set_callbacks_run(
 
         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
+        sd_bus_slot *slot;
         void *u = NULL;
         int r;
 
@@ -544,6 +580,8 @@ static int property_get_set_callbacks_run(
         if (bus->nodes_modified)
                 return 0;
 
+        slot = container_of(c->parent, sd_bus_slot, node_vtable);
+
         *found_object = true;
 
         r = sd_bus_message_new_method_return(m, &reply);
@@ -567,7 +605,7 @@ static int property_get_set_callbacks_run(
                  * PropertiesChanged signals broadcast contents
                  * anyway. */
 
-                r = invoke_property_get(bus, c->vtable, m->path, c->interface, c->member, reply, u, &error);
+                r = invoke_property_get(bus, slot, c->vtable, m->path, c->interface, c->member, reply, u, &error);
                 if (r < 0)
                         return bus_maybe_reply_error(m, r, &error);
 
@@ -598,7 +636,7 @@ static int property_get_set_callbacks_run(
                 if (r < 0)
                         return bus_maybe_reply_error(m, r, &error);
 
-                r = invoke_property_set(bus, c->vtable, m->path, c->interface, c->member, m, u, &error);
+                r = invoke_property_set(bus, slot, c->vtable, m->path, c->interface, c->member, m, u, &error);
                 if (r < 0)
                         return bus_maybe_reply_error(m, r, &error);
 
@@ -626,6 +664,7 @@ static int vtable_append_one_property(
                 void *userdata,
                 sd_bus_error *error) {
 
+        sd_bus_slot *slot;
         int r;
 
         assert(bus);
@@ -646,7 +685,9 @@ static int vtable_append_one_property(
         if (r < 0)
                 return r;
 
-        r = invoke_property_get(bus, v, path, c->interface, v->x.property.member, reply, vtable_property_convert_userdata(v, userdata), error);
+        slot = container_of(c, sd_bus_slot, node_vtable);
+
+        r = invoke_property_get(bus, slot, v, path, c->interface, v->x.property.member, reply, vtable_property_convert_userdata(v, userdata), error);
         if (r < 0)
                 return r;
         if (bus->nodes_modified)
@@ -783,7 +824,7 @@ static bool bus_node_with_object_manager(sd_bus *bus, struct node *n) {
         assert(bus);
         assert(n);
 
-        if (n->object_manager)
+        if (n->object_managers)
                 return true;
 
         if (n->parent)
@@ -827,7 +868,7 @@ static bool bus_node_exists(
                         return false;
         }
 
-        return !require_fallback && (n->enumerators || n->object_manager);
+        return !require_fallback && (n->enumerators || n->object_managers);
 }
 
 static int process_introspect(
@@ -1304,6 +1345,9 @@ int bus_process_object(sd_bus *bus, sd_bus_message *m) {
         assert(bus);
         assert(m);
 
+        if (bus->hello_flags & KDBUS_HELLO_MONITOR)
+                return 0;
+
         if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
                 return 0;
 
@@ -1418,7 +1462,7 @@ static struct node *bus_node_allocate(sd_bus *bus, const char *path) {
         return n;
 }
 
-static void bus_node_gc(sd_bus *b, struct node *n) {
+void bus_node_gc(sd_bus *b, struct node *n) {
         assert(b);
 
         if (!n)
@@ -1428,7 +1472,7 @@ static void bus_node_gc(sd_bus *b, struct node *n) {
             n->callbacks ||
             n->vtables ||
             n->enumerators ||
-            n->object_manager)
+            n->object_managers)
                 return;
 
         assert(hashmap_remove(b->nodes, n->path) == n);
@@ -1443,12 +1487,13 @@ static void bus_node_gc(sd_bus *b, struct node *n) {
 
 static int bus_add_object(
                 sd_bus *bus,
+                sd_bus_slot **slot,
                 bool fallback,
                 const char *path,
                 sd_bus_message_handler_t callback,
                 void *userdata) {
 
-        struct node_callback *c;
+        sd_bus_slot *s;
         struct node *n;
         int r;
 
@@ -1461,136 +1506,49 @@ static int bus_add_object(
         if (!n)
                 return -ENOMEM;
 
-        c = new0(struct node_callback, 1);
-        if (!c) {
+        s = bus_slot_allocate(bus, !slot, BUS_NODE_CALLBACK, sizeof(struct node_callback), userdata);
+        if (!s) {
                 r = -ENOMEM;
                 goto fail;
         }
 
-        c->node = n;
-        c->callback = callback;
-        c->userdata = userdata;
-        c->is_fallback = fallback;
+        s->node_callback.callback = callback;
+        s->node_callback.is_fallback = fallback;
 
-        LIST_PREPEND(callbacks, n->callbacks, c);
+        s->node_callback.node = n;
+        LIST_PREPEND(callbacks, n->callbacks, &s->node_callback);
         bus->nodes_modified = true;
 
+        if (slot)
+                *slot = s;
+
         return 0;
 
 fail:
-        free(c);
+        sd_bus_slot_unref(s);
         bus_node_gc(bus, n);
+
         return r;
 }
 
-static int bus_remove_object(
+_public_ int sd_bus_add_object(
                 sd_bus *bus,
-                bool fallback,
+                sd_bus_slot **slot,
                 const char *path,
                 sd_bus_message_handler_t callback,
                 void *userdata) {
 
-        struct node_callback *c;
-        struct node *n;
-
-        assert_return(bus, -EINVAL);
-        assert_return(object_path_is_valid(path), -EINVAL);
-        assert_return(callback, -EINVAL);
-        assert_return(!bus_pid_changed(bus), -ECHILD);
-
-        n = hashmap_get(bus->nodes, path);
-        if (!n)
-                return 0;
-
-        LIST_FOREACH(callbacks, c, n->callbacks)
-                if (c->callback == callback && c->userdata == userdata && c->is_fallback == fallback)
-                        break;
-        if (!c)
-                return 0;
-
-        LIST_REMOVE(callbacks, n->callbacks, c);
-        free(c);
-
-        bus_node_gc(bus, n);
-        bus->nodes_modified = true;
-
-        return 1;
-}
-
-_public_ int sd_bus_add_object(sd_bus *bus,
-                               const char *path,
-                               sd_bus_message_handler_t callback,
-                               void *userdata) {
-
-        return bus_add_object(bus, false, path, callback, userdata);
-}
-
-_public_ int sd_bus_remove_object(sd_bus *bus,
-                                  const char *path,
-                                  sd_bus_message_handler_t callback,
-                                  void *userdata) {
-
-        return bus_remove_object(bus, false, path, callback, userdata);
-}
-
-_public_ int sd_bus_add_fallback(sd_bus *bus,
-                                 const char *prefix,
-                                 sd_bus_message_handler_t callback,
-                                 void *userdata) {
-
-        return bus_add_object(bus, true, prefix, callback, userdata);
-}
-
-_public_ int sd_bus_remove_fallback(sd_bus *bus,
-                                    const char *prefix,
-                                    sd_bus_message_handler_t callback,
-                                    void *userdata) {
-
-        return bus_remove_object(bus, true, prefix, callback, userdata);
+        return bus_add_object(bus, slot, false, path, callback, userdata);
 }
 
-static void free_node_vtable(sd_bus *bus, struct node_vtable *w) {
-        assert(bus);
-
-        if (!w)
-                return;
-
-        if (w->interface && w->node && w->vtable) {
-                const sd_bus_vtable *v;
-
-                for (v = w->vtable; v->type != _SD_BUS_VTABLE_END; v++) {
-                        struct vtable_member *x = NULL;
-
-                        switch (v->type) {
-
-                        case _SD_BUS_VTABLE_METHOD: {
-                                struct vtable_member key;
-
-                                key.path = w->node->path;
-                                key.interface = w->interface;
-                                key.member = v->x.method.member;
-
-                                x = hashmap_remove(bus->vtable_methods, &key);
-                                break;
-                        }
-
-                        case _SD_BUS_VTABLE_PROPERTY:
-                        case _SD_BUS_VTABLE_WRITABLE_PROPERTY: {
-                                struct vtable_member key;
-
-                                key.path = w->node->path;
-                                key.interface = w->interface;
-                                key.member = v->x.property.member;
-                                x = hashmap_remove(bus->vtable_properties, &key);
-                                break;
-                        }}
-
-                        free(x);
-                }
-        }
+_public_ int sd_bus_add_fallback(
+                sd_bus *bus,
+                sd_bus_slot **slot,
+                const char *prefix,
+                sd_bus_message_handler_t callback,
+                void *userdata) {
 
-        free(w->interface);
-        free(w);
+        return bus_add_object(bus, slot, true, prefix, callback, userdata);
 }
 
 static unsigned long vtable_member_hash_func(const void *a, const uint8_t hash_key[HASH_KEY_SIZE]) {
@@ -1634,6 +1592,7 @@ static int vtable_member_compare_func(const void *a, const void *b) {
 
 static int add_object_vtable_internal(
                 sd_bus *bus,
+                sd_bus_slot **slot,
                 const char *path,
                 const char *interface,
                 const sd_bus_vtable *vtable,
@@ -1641,7 +1600,8 @@ static int add_object_vtable_internal(
                 sd_bus_object_find_t find,
                 void *userdata) {
 
-        struct node_vtable *c = NULL, *i, *existing = NULL;
+        sd_bus_slot *s = NULL;
+        struct node_vtable *i, *existing = NULL;
         const sd_bus_vtable *v;
         struct node *n;
         int r;
@@ -1687,25 +1647,23 @@ static int add_object_vtable_internal(
                 }
         }
 
-        c = new0(struct node_vtable, 1);
-        if (!c) {
+        s = bus_slot_allocate(bus, !slot, BUS_NODE_VTABLE, sizeof(struct node_vtable), userdata);
+        if (!s) {
                 r = -ENOMEM;
                 goto fail;
         }
 
-        c->node = n;
-        c->is_fallback = fallback;
-        c->vtable = vtable;
-        c->userdata = userdata;
-        c->find = find;
+        s->node_vtable.is_fallback = fallback;
+        s->node_vtable.vtable = vtable;
+        s->node_vtable.find = find;
 
-        c->interface = strdup(interface);
-        if (!c->interface) {
+        s->node_vtable.interface = strdup(interface);
+        if (!s->node_vtable.interface) {
                 r = -ENOMEM;
                 goto fail;
         }
 
-        for (v = c->vtable+1; v->type != _SD_BUS_VTABLE_END; v++) {
+        for (v = s->node_vtable.vtable+1; v->type != _SD_BUS_VTABLE_END; v++) {
 
                 switch (v->type) {
 
@@ -1727,9 +1685,9 @@ static int add_object_vtable_internal(
                                 goto fail;
                         }
 
-                        m->parent = c;
+                        m->parent = &s->node_vtable;
                         m->path = n->path;
-                        m->interface = c->interface;
+                        m->interface = s->node_vtable.interface;
                         m->member = v->x.method.member;
                         m->vtable = v;
 
@@ -1770,9 +1728,9 @@ static int add_object_vtable_internal(
                                 goto fail;
                         }
 
-                        m->parent = c;
+                        m->parent = &s->node_vtable;
                         m->path = n->path;
-                        m->interface = c->interface;
+                        m->interface = s->node_vtable.interface;
                         m->member = v->x.property.member;
                         m->vtable = v;
 
@@ -1802,110 +1760,53 @@ static int add_object_vtable_internal(
                 }
         }
 
-        LIST_INSERT_AFTER(vtables, n->vtables, existing, c);
+        s->node_vtable.node = n;
+        LIST_INSERT_AFTER(vtables, n->vtables, existing, &s->node_vtable);
         bus->nodes_modified = true;
 
+        if (slot)
+                *slot = s;
+
         return 0;
 
 fail:
-        if (c)
-                free_node_vtable(bus, c);
-
+        sd_bus_slot_unref(s);
         bus_node_gc(bus, n);
-        return r;
-}
-
-static int remove_object_vtable_internal(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const sd_bus_vtable *vtable,
-                bool fallback,
-                sd_bus_object_find_t find,
-                void *userdata) {
-
-        struct node_vtable *c;
-        struct node *n;
 
-        assert_return(bus, -EINVAL);
-        assert_return(object_path_is_valid(path), -EINVAL);
-        assert_return(interface_name_is_valid(interface), -EINVAL);
-        assert_return(!bus_pid_changed(bus), -ECHILD);
-
-        n = hashmap_get(bus->nodes, path);
-        if (!n)
-                return 0;
-
-        LIST_FOREACH(vtables, c, n->vtables)
-                if (streq(c->interface, interface) &&
-                    c->is_fallback == fallback &&
-                    c->vtable == vtable &&
-                    c->find == find &&
-                    c->userdata == userdata)
-                        break;
-
-        if (!c)
-                return 0;
-
-        LIST_REMOVE(vtables, n->vtables, c);
-
-        free_node_vtable(bus, c);
-        bus_node_gc(bus, n);
-
-        bus->nodes_modified = true;
-
-        return 1;
+        return r;
 }
 
 _public_ int sd_bus_add_object_vtable(
                 sd_bus *bus,
+                sd_bus_slot **slot,
                 const char *path,
                 const char *interface,
                 const sd_bus_vtable *vtable,
                 void *userdata) {
 
-        return add_object_vtable_internal(bus, path, interface, vtable, false, NULL, userdata);
-}
-
-_public_ int sd_bus_remove_object_vtable(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const sd_bus_vtable *vtable,
-                void *userdata) {
-
-        return remove_object_vtable_internal(bus, path, interface, vtable, false, NULL, userdata);
+        return add_object_vtable_internal(bus, slot, path, interface, vtable, false, NULL, userdata);
 }
 
 _public_ int sd_bus_add_fallback_vtable(
                 sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const sd_bus_vtable *vtable,
-                sd_bus_object_find_t find,
-                void *userdata) {
-
-        return add_object_vtable_internal(bus, path, interface, vtable, true, find, userdata);
-}
-
-_public_ int sd_bus_remove_fallback_vtable(
-                sd_bus *bus,
-                const char *path,
+                sd_bus_slot **slot,
+                const char *prefix,
                 const char *interface,
                 const sd_bus_vtable *vtable,
                 sd_bus_object_find_t find,
                 void *userdata) {
 
-        return remove_object_vtable_internal(bus, path, interface, vtable, true, find, userdata);
+        return add_object_vtable_internal(bus, slot, prefix, interface, vtable, true, find, userdata);
 }
 
 _public_ int sd_bus_add_node_enumerator(
                 sd_bus *bus,
+                sd_bus_slot **slot,
                 const char *path,
                 sd_bus_node_enumerator_t callback,
                 void *userdata) {
 
-        struct node_enumerator *c;
+        sd_bus_slot *s;
         struct node *n;
         int r;
 
@@ -1918,61 +1819,28 @@ _public_ int sd_bus_add_node_enumerator(
         if (!n)
                 return -ENOMEM;
 
-        c = new0(struct node_enumerator, 1);
-        if (!c) {
+        s = bus_slot_allocate(bus, !slot, BUS_NODE_ENUMERATOR, sizeof(struct node_enumerator), userdata);
+        if (!s) {
                 r = -ENOMEM;
                 goto fail;
         }
 
-        c->node = n;
-        c->callback = callback;
-        c->userdata = userdata;
-
-        LIST_PREPEND(enumerators, n->enumerators, c);
+        s->node_enumerator.callback = callback;
 
+        s->node_enumerator.node = n;
+        LIST_PREPEND(enumerators, n->enumerators, &s->node_enumerator);
         bus->nodes_modified = true;
 
+        if (slot)
+                *slot = s;
+
         return 0;
 
 fail:
-        free(c);
-        bus_node_gc(bus, n);
-        return r;
-}
-
-_public_ int sd_bus_remove_node_enumerator(
-                sd_bus *bus,
-                const char *path,
-                sd_bus_node_enumerator_t callback,
-                void *userdata) {
-
-        struct node_enumerator *c;
-        struct node *n;
-
-        assert_return(bus, -EINVAL);
-        assert_return(object_path_is_valid(path), -EINVAL);
-        assert_return(callback, -EINVAL);
-        assert_return(!bus_pid_changed(bus), -ECHILD);
-
-        n = hashmap_get(bus->nodes, path);
-        if (!n)
-                return 0;
-
-        LIST_FOREACH(enumerators, c, n->enumerators)
-                if (c->callback == callback && c->userdata == userdata)
-                        break;
-
-        if (!c)
-                return 0;
-
-        LIST_REMOVE(enumerators, n->enumerators, c);
-        free(c);
-
+        sd_bus_slot_unref(s);
         bus_node_gc(bus, n);
 
-        bus->nodes_modified = true;
-
-        return 1;
+        return r;
 }
 
 static int emit_properties_changed_on_interface(
@@ -2196,9 +2064,10 @@ _public_ int sd_bus_emit_properties_changed_strv(
         assert_return(bus, -EINVAL);
         assert_return(object_path_is_valid(path), -EINVAL);
         assert_return(interface_name_is_valid(interface), -EINVAL);
-        assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
         assert_return(!bus_pid_changed(bus), -ECHILD);
 
+        if (!BUS_IS_OPEN(bus->state))
+                return -ENOTCONN;
 
         /* A non-NULL but empty names list means nothing needs to be
            generated. A NULL list OTOH indicates that all properties
@@ -2241,9 +2110,11 @@ _public_ int sd_bus_emit_properties_changed(
         assert_return(bus, -EINVAL);
         assert_return(object_path_is_valid(path), -EINVAL);
         assert_return(interface_name_is_valid(interface), -EINVAL);
-        assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
         assert_return(!bus_pid_changed(bus), -ECHILD);
 
+        if (!BUS_IS_OPEN(bus->state))
+                return -ENOTCONN;
+
         if (!name)
                 return 0;
 
@@ -2361,17 +2232,17 @@ _public_ int sd_bus_emit_interfaces_added_strv(sd_bus *bus, const char *path, ch
 
         assert_return(bus, -EINVAL);
         assert_return(object_path_is_valid(path), -EINVAL);
-        assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
         assert_return(!bus_pid_changed(bus), -ECHILD);
 
+        if (!BUS_IS_OPEN(bus->state))
+                return -ENOTCONN;
+
         if (strv_isempty(interfaces))
                 return 0;
 
         do {
                 bus->nodes_modified = false;
-
-                if (m)
-                        m = sd_bus_message_unref(m);
+                m = sd_bus_message_unref(m);
 
                 r = sd_bus_message_new_signal(bus, &m, path, "org.freedesktop.DBus.ObjectManager", "InterfacesAdded");
                 if (r < 0)
@@ -2421,9 +2292,11 @@ _public_ int sd_bus_emit_interfaces_added(sd_bus *bus, const char *path, const c
 
         assert_return(bus, -EINVAL);
         assert_return(object_path_is_valid(path), -EINVAL);
-        assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
         assert_return(!bus_pid_changed(bus), -ECHILD);
 
+        if (!BUS_IS_OPEN(bus->state))
+                return -ENOTCONN;
+
         interfaces = strv_from_stdarg_alloca(interface);
 
         return sd_bus_emit_interfaces_added_strv(bus, path, interfaces);
@@ -2435,9 +2308,11 @@ _public_ int sd_bus_emit_interfaces_removed_strv(sd_bus *bus, const char *path,
 
         assert_return(bus, -EINVAL);
         assert_return(object_path_is_valid(path), -EINVAL);
-        assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
         assert_return(!bus_pid_changed(bus), -ECHILD);
 
+        if (!BUS_IS_OPEN(bus->state))
+                return -ENOTCONN;
+
         if (strv_isempty(interfaces))
                 return 0;
 
@@ -2461,16 +2336,20 @@ _public_ int sd_bus_emit_interfaces_removed(sd_bus *bus, const char *path, const
 
         assert_return(bus, -EINVAL);
         assert_return(object_path_is_valid(path), -EINVAL);
-        assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
         assert_return(!bus_pid_changed(bus), -ECHILD);
 
+        if (!BUS_IS_OPEN(bus->state))
+                return -ENOTCONN;
+
         interfaces = strv_from_stdarg_alloca(interface);
 
         return sd_bus_emit_interfaces_removed_strv(bus, path, interfaces);
 }
 
-_public_ int sd_bus_add_object_manager(sd_bus *bus, const char *path) {
+_public_ int sd_bus_add_object_manager(sd_bus *bus, sd_bus_slot **slot, const char *path) {
+        sd_bus_slot *s;
         struct node *n;
+        int r;
 
         assert_return(bus, -EINVAL);
         assert_return(object_path_is_valid(path), -EINVAL);
@@ -2480,28 +2359,24 @@ _public_ int sd_bus_add_object_manager(sd_bus *bus, const char *path) {
         if (!n)
                 return -ENOMEM;
 
-        n->object_manager = true;
-        bus->nodes_modified = true;
-        return 0;
-}
-
-_public_ int sd_bus_remove_object_manager(sd_bus *bus, const char *path) {
-        struct node *n;
+        s = bus_slot_allocate(bus, !slot, BUS_NODE_OBJECT_MANAGER, sizeof(struct node_object_manager), NULL);
+        if (!s) {
+                r = -ENOMEM;
+                goto fail;
+        }
 
-        assert_return(bus, -EINVAL);
-        assert_return(object_path_is_valid(path), -EINVAL);
-        assert_return(!bus_pid_changed(bus), -ECHILD);
+        s->node_object_manager.node = n;
+        LIST_PREPEND(object_managers, n->object_managers, &s->node_object_manager);
+        bus->nodes_modified = true;
 
-        n = hashmap_get(bus->nodes, path);
-        if (!n)
-                return 0;
+        if (slot)
+                *slot = s;
 
-        if (!n->object_manager)
-                return 0;
+        return 0;
 
-        n->object_manager = false;
-        bus->nodes_modified = true;
+fail:
+        sd_bus_slot_unref(s);
         bus_node_gc(bus, n);
 
-        return 1;
+        return r;
 }
index 420edd9..4373fae 100644 (file)
@@ -24,3 +24,4 @@
 #include "bus-internal.h"
 
 int bus_process_object(sd_bus *bus, sd_bus_message *m);
+void bus_node_gc(sd_bus *b, struct node *n);
index 5046d17..4f46468 100644 (file)
@@ -21,6 +21,7 @@
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
+#include <endian.h>
 
 /* Endianness */
 
diff --git a/src/libsystemd/sd-bus/bus-slot.c b/src/libsystemd/sd-bus/bus-slot.c
new file mode 100644 (file)
index 0000000..d6793c2
--- /dev/null
@@ -0,0 +1,267 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2013 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "sd-bus.h"
+#include "bus-control.h"
+#include "bus-objects.h"
+#include "bus-slot.h"
+
+sd_bus_slot *bus_slot_allocate(
+                sd_bus *bus,
+                bool floating,
+                BusSlotType type,
+                size_t extra,
+                void *userdata) {
+
+        sd_bus_slot *slot;
+
+        assert(bus);
+
+        slot = malloc0(offsetof(sd_bus_slot, reply_callback) + extra);
+        if (!slot)
+                return NULL;
+
+        slot->n_ref = 1;
+        slot->type = type;
+        slot->bus = bus;
+        slot->floating = floating;
+        slot->userdata = userdata;
+
+        if (!floating)
+                sd_bus_ref(bus);
+
+        LIST_PREPEND(slots, bus->slots, slot);
+
+        return slot;
+}
+
+_public_ sd_bus_slot* sd_bus_slot_ref(sd_bus_slot *slot) {
+        assert_return(slot, NULL);
+
+        assert(slot->n_ref > 0);
+
+        slot->n_ref++;
+        return slot;
+}
+
+void bus_slot_disconnect(sd_bus_slot *slot) {
+        sd_bus *bus;
+
+        assert(slot);
+
+        if (!slot->bus)
+                return;
+
+        switch (slot->type) {
+
+        case BUS_REPLY_CALLBACK:
+
+                if (slot->reply_callback.cookie != 0)
+                        hashmap_remove(slot->bus->reply_callbacks, &slot->reply_callback.cookie);
+
+                if (slot->reply_callback.timeout != 0)
+                        prioq_remove(slot->bus->reply_callbacks_prioq, &slot->reply_callback, &slot->reply_callback.prioq_idx);
+
+                break;
+
+        case BUS_FILTER_CALLBACK:
+                slot->bus->filter_callbacks_modified = true;
+                LIST_REMOVE(callbacks, slot->bus->filter_callbacks, &slot->filter_callback);
+                break;
+
+        case BUS_MATCH_CALLBACK:
+
+                if (slot->bus->bus_client)
+                        bus_remove_match_internal(slot->bus, slot->match_callback.match_string, slot->match_callback.cookie);
+
+                slot->bus->match_callbacks_modified = true;
+                bus_match_remove(&slot->bus->match_callbacks, &slot->match_callback);
+
+                free(slot->match_callback.match_string);
+
+                break;
+
+        case BUS_NODE_CALLBACK:
+
+                if (slot->node_callback.node) {
+                        LIST_REMOVE(callbacks, slot->node_callback.node->callbacks, &slot->node_callback);
+                        slot->bus->nodes_modified = true;
+
+                        bus_node_gc(slot->bus, slot->node_callback.node);
+                }
+
+                break;
+
+        case BUS_NODE_ENUMERATOR:
+
+                if (slot->node_enumerator.node) {
+                        LIST_REMOVE(enumerators, slot->node_enumerator.node->enumerators, &slot->node_enumerator);
+                        slot->bus->nodes_modified = true;
+
+                        bus_node_gc(slot->bus, slot->node_enumerator.node);
+                }
+
+                break;
+
+        case BUS_NODE_OBJECT_MANAGER:
+
+                if (slot->node_object_manager.node) {
+                        LIST_REMOVE(object_managers, slot->node_object_manager.node->object_managers, &slot->node_object_manager);
+                        slot->bus->nodes_modified = true;
+
+                        bus_node_gc(slot->bus, slot->node_object_manager.node);
+                }
+
+                break;
+
+        case BUS_NODE_VTABLE:
+
+                if (slot->node_vtable.node && slot->node_vtable.interface && slot->node_vtable.vtable) {
+                        const sd_bus_vtable *v;
+
+                        for (v = slot->node_vtable.vtable; v->type != _SD_BUS_VTABLE_END; v++) {
+                                struct vtable_member *x = NULL;
+
+                                switch (v->type) {
+
+                                case _SD_BUS_VTABLE_METHOD: {
+                                        struct vtable_member key;
+
+                                        key.path = slot->node_vtable.node->path;
+                                        key.interface = slot->node_vtable.interface;
+                                        key.member = v->x.method.member;
+
+                                        x = hashmap_remove(slot->bus->vtable_methods, &key);
+                                        break;
+                                }
+
+                                case _SD_BUS_VTABLE_PROPERTY:
+                                case _SD_BUS_VTABLE_WRITABLE_PROPERTY: {
+                                        struct vtable_member key;
+
+                                        key.path = slot->node_vtable.node->path;
+                                        key.interface = slot->node_vtable.interface;
+                                        key.member = v->x.method.member;
+
+
+                                        x = hashmap_remove(slot->bus->vtable_properties, &key);
+                                        break;
+                                }}
+
+                                free(x);
+                        }
+                }
+
+                free(slot->node_vtable.interface);
+
+                if (slot->node_vtable.node) {
+                        LIST_REMOVE(vtables, slot->node_vtable.node->vtables, &slot->node_vtable);
+                        slot->bus->nodes_modified = true;
+
+                        bus_node_gc(slot->bus, slot->node_vtable.node);
+                }
+
+                break;
+
+        default:
+                assert_not_reached("Wut? Unknown slot type?");
+        }
+
+        bus = slot->bus;
+
+        slot->type = _BUS_SLOT_INVALID;
+        slot->bus = NULL;
+        LIST_REMOVE(slots, bus->slots, slot);
+
+        if (!slot->floating)
+                sd_bus_unref(bus);
+}
+
+_public_ sd_bus_slot* sd_bus_slot_unref(sd_bus_slot *slot) {
+
+        if (!slot)
+                return NULL;
+
+        assert(slot->n_ref > 0);
+
+        if (slot->n_ref > 1) {
+                slot->n_ref --;
+                return NULL;
+        }
+
+        bus_slot_disconnect(slot);
+        free(slot);
+
+        return NULL;
+}
+
+_public_ sd_bus* sd_bus_slot_get_bus(sd_bus_slot *slot) {
+        assert_return(slot, NULL);
+
+        return slot->bus;
+}
+
+_public_ void *sd_bus_slot_get_userdata(sd_bus_slot *slot) {
+        assert_return(slot, NULL);
+
+        return slot->userdata;
+}
+
+_public_ void *sd_bus_slot_set_userdata(sd_bus_slot *slot, void *userdata) {
+        void *ret;
+
+        assert_return(slot, NULL);
+
+        ret = slot->userdata;
+        slot->userdata = userdata;
+
+        return ret;
+}
+
+_public_ sd_bus_message *sd_bus_slot_get_current_message(sd_bus_slot *slot) {
+        assert_return(slot, NULL);
+        assert_return(slot->type >= 0, NULL);
+
+        if (slot->bus->current_slot != slot)
+                return NULL;
+
+        return slot->bus->current_message;
+}
+
+_public_ sd_bus_message_handler_t sd_bus_slot_get_current_handler(sd_bus_slot *slot) {
+        assert_return(slot, NULL);
+        assert_return(slot->type >= 0, NULL);
+
+        if (slot->bus->current_slot != slot)
+                return NULL;
+
+        return slot->bus->current_handler;
+}
+
+_public_ void* sd_bus_slot_get_current_userdata(sd_bus_slot *slot) {
+        assert_return(slot, NULL);
+        assert_return(slot->type >= 0, NULL);
+
+        if (slot->bus->current_slot != slot)
+                return NULL;
+
+        return slot->bus->current_userdata;
+}
diff --git a/src/libsystemd/sd-bus/bus-slot.h b/src/libsystemd/sd-bus/bus-slot.h
new file mode 100644 (file)
index 0000000..23a15e4
--- /dev/null
@@ -0,0 +1,29 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "sd-bus.h"
+#include "bus-internal.h"
+
+sd_bus_slot *bus_slot_allocate(sd_bus *bus, bool floating, BusSlotType type, size_t extra, void *userdata);
+
+void bus_slot_disconnect(sd_bus_slot *slot);
index 0c4b6af..d124d9a 100644 (file)
@@ -227,8 +227,8 @@ static int bus_socket_auth_verify_client(sd_bus *b) {
 
         if (f)
                 b->can_fds =
-                        (f - e == sizeof("\r\nAGREE_UNIX_FD") - 1) &&
-                        memcmp(e + 2, "AGREE_UNIX_FD", sizeof("AGREE_UNIX_FD") - 1) == 0;
+                        (f - e == strlen("\r\nAGREE_UNIX_FD")) &&
+                        memcmp(e + 2, "AGREE_UNIX_FD", strlen("AGREE_UNIX_FD")) == 0;
 
         b->rbuffer_size -= (start - (char*) b->rbuffer);
         memmove(b->rbuffer, start, b->rbuffer_size);
@@ -648,7 +648,7 @@ static int bus_socket_start_auth_client(sd_bus *b) {
 
                 auth_prefix = "\0AUTH EXTERNAL ";
 
-                snprintf(text, sizeof(text), "%lu", (unsigned long) geteuid());
+                snprintf(text, sizeof(text), UID_FMT, geteuid());
                 char_array_0(text);
 
                 l = strlen(text);
@@ -736,7 +736,7 @@ int bus_socket_exec(sd_bus *b) {
 
         pid = fork();
         if (pid < 0) {
-                close_pipe(s);
+                safe_close_pair(s);
                 return -errno;
         }
         if (pid == 0) {
@@ -750,7 +750,7 @@ int bus_socket_exec(sd_bus *b) {
                 assert_se(dup3(s[1], STDOUT_FILENO, 0) == STDOUT_FILENO);
 
                 if (s[1] != STDIN_FILENO && s[1] != STDOUT_FILENO)
-                        close_nointr_nofail(s[1]);
+                        safe_close(s[1]);
 
                 fd_cloexec(STDIN_FILENO, false);
                 fd_cloexec(STDOUT_FILENO, false);
@@ -767,7 +767,7 @@ int bus_socket_exec(sd_bus *b) {
                 _exit(EXIT_FAILURE);
         }
 
-        close_nointr_nofail(s[1]);
+        safe_close(s[1]);
         b->output_fd = b->input_fd = s[0];
 
         bus_socket_setup(b);
diff --git a/src/libsystemd/sd-bus/bus-track.c b/src/libsystemd/sd-bus/bus-track.c
new file mode 100644 (file)
index 0000000..ffa2cf3
--- /dev/null
@@ -0,0 +1,334 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2013 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "sd-bus.h"
+#include "set.h"
+#include "bus-util.h"
+#include "bus-internal.h"
+#include "bus-track.h"
+
+struct sd_bus_track {
+        unsigned n_ref;
+        sd_bus *bus;
+        sd_bus_track_handler_t handler;
+        void *userdata;
+        Hashmap *names;
+        LIST_FIELDS(sd_bus_track, queue);
+        Iterator iterator;
+        bool in_queue;
+        bool modified;
+};
+
+#define MATCH_PREFIX                                        \
+        "type='signal',"                                    \
+        "sender='org.freedesktop.DBus',"                    \
+        "path='/org/freedesktop/DBus',"                     \
+        "interface='org.freedesktop.DBus',"                 \
+        "member='NameOwnerChanged',"                        \
+        "arg0='"
+
+#define MATCH_SUFFIX \
+        "'"
+
+#define MATCH_FOR_NAME(name)                                            \
+        ({                                                              \
+                char *_x;                                               \
+                size_t _l = strlen(name);                               \
+                _x = alloca(strlen(MATCH_PREFIX)+_l+strlen(MATCH_SUFFIX)+1); \
+                strcpy(stpcpy(stpcpy(_x, MATCH_PREFIX), name), MATCH_SUFFIX); \
+                _x;                                                     \
+        })
+
+static void bus_track_add_to_queue(sd_bus_track *track) {
+        assert(track);
+
+        if (track->in_queue)
+                return;
+
+        if (!track->handler)
+                return;
+
+        LIST_PREPEND(queue, track->bus->track_queue, track);
+        track->in_queue = true;
+}
+
+static void bus_track_remove_from_queue(sd_bus_track *track) {
+        assert(track);
+
+        if (!track->in_queue)
+                return;
+
+        LIST_REMOVE(queue, track->bus->track_queue, track);
+        track->in_queue = false;
+}
+
+_public_ int sd_bus_track_new(
+                sd_bus *bus,
+                sd_bus_track **track,
+                sd_bus_track_handler_t handler,
+                void *userdata) {
+
+        sd_bus_track *t;
+
+        assert_return(bus, -EINVAL);
+        assert_return(track, -EINVAL);
+
+        t = new0(sd_bus_track, 1);
+        if (!t)
+                return -ENOMEM;
+
+        t->n_ref = 1;
+        t->handler = handler;
+        t->userdata = userdata;
+        t->bus = sd_bus_ref(bus);
+
+        bus_track_add_to_queue(t);
+
+        *track = t;
+        return 0;
+}
+
+_public_ sd_bus_track* sd_bus_track_ref(sd_bus_track *track) {
+        assert_return(track, NULL);
+
+        assert(track->n_ref > 0);
+
+        track->n_ref++;
+
+        return track;
+}
+
+_public_ sd_bus_track* sd_bus_track_unref(sd_bus_track *track) {
+        const char *n;
+
+        if (!track)
+                return NULL;
+
+        assert(track->n_ref > 0);
+
+        if (track->n_ref > 1) {
+                track->n_ref --;
+                return NULL;
+        }
+
+        while ((n = hashmap_first_key(track->names)))
+                sd_bus_track_remove_name(track, n);
+
+        bus_track_remove_from_queue(track);
+        hashmap_free(track->names);
+        sd_bus_unref(track->bus);
+        free(track);
+
+        return NULL;
+}
+
+static int on_name_owner_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
+        sd_bus_track *track = userdata;
+        const char *name, *old, *new;
+        int r;
+
+        assert(bus);
+        assert(message);
+        assert(track);
+
+        r = sd_bus_message_read(message, "sss", &name, &old, &new);
+        if (r < 0)
+                return 0;
+
+        sd_bus_track_remove_name(track, name);
+        return 0;
+}
+
+_public_ int sd_bus_track_add_name(sd_bus_track *track, const char *name) {
+        _cleanup_bus_slot_unref_ sd_bus_slot *slot = NULL;
+        _cleanup_free_ char *n = NULL;
+        const char *match;
+        int r;
+
+        assert_return(track, -EINVAL);
+        assert_return(service_name_is_valid(name), -EINVAL);
+
+        r = hashmap_ensure_allocated(&track->names, string_hash_func, string_compare_func);
+        if (r < 0)
+                return r;
+
+        n = strdup(name);
+        if (!n)
+                return -ENOMEM;
+
+        /* First, subscribe to this name */
+        match = MATCH_FOR_NAME(n);
+        r = sd_bus_add_match(track->bus, &slot, match, on_name_owner_changed, track);
+        if (r < 0)
+                return r;
+
+        r = hashmap_put(track->names, n, slot);
+        if (r == -EEXIST)
+                return 0;
+        if (r < 0)
+                return r;
+
+        /* Second, check if it is currently existing, or maybe
+         * doesn't, or maybe disappeared already. */
+        r = sd_bus_get_owner(track->bus, n, 0, NULL);
+        if (r < 0) {
+                hashmap_remove(track->names, n);
+                return r;
+        }
+
+        n = NULL;
+        slot = NULL;
+
+        bus_track_remove_from_queue(track);
+        track->modified = true;
+
+        return 1;
+}
+
+_public_ int sd_bus_track_remove_name(sd_bus_track *track, const char *name) {
+        _cleanup_bus_slot_unref_ sd_bus_slot *slot = NULL;
+        _cleanup_free_ char *n = NULL;
+
+        assert_return(name, -EINVAL);
+
+        if (!track)
+                return 0;
+
+        slot = hashmap_remove2(track->names, (char*) name, (void**) &n);
+        if (!slot)
+                return 0;
+
+        if (hashmap_isempty(track->names))
+                bus_track_add_to_queue(track);
+
+        track->modified = true;
+
+        return 1;
+}
+
+_public_ unsigned sd_bus_track_count(sd_bus_track *track) {
+        if (!track)
+                return 0;
+
+        return hashmap_size(track->names);
+}
+
+_public_ const char* sd_bus_track_contains(sd_bus_track *track, const char *name) {
+        assert_return(track, NULL);
+        assert_return(name, NULL);
+
+        return hashmap_get(track->names, (void*) name) ? name : NULL;
+}
+
+_public_ const char* sd_bus_track_first(sd_bus_track *track) {
+        const char *n = NULL;
+
+        if (!track)
+                return NULL;
+
+        track->modified = false;
+        track->iterator = NULL;
+
+        hashmap_iterate(track->names, &track->iterator, (const void**) &n);
+        return n;
+}
+
+_public_ const char* sd_bus_track_next(sd_bus_track *track) {
+        const char *n = NULL;
+
+        if (!track)
+                return NULL;
+
+        if (track->modified)
+                return NULL;
+
+        hashmap_iterate(track->names, &track->iterator, (const void**) &n);
+        return n;
+}
+
+_public_ int sd_bus_track_add_sender(sd_bus_track *track, sd_bus_message *m) {
+        const char *sender;
+
+        assert_return(track, -EINVAL);
+        assert_return(m, -EINVAL);
+
+        sender = sd_bus_message_get_sender(m);
+        if (!sender)
+                return -EINVAL;
+
+        return sd_bus_track_add_name(track, sender);
+}
+
+_public_ int sd_bus_track_remove_sender(sd_bus_track *track, sd_bus_message *m) {
+        const char *sender;
+
+        assert_return(track, -EINVAL);
+        assert_return(m, -EINVAL);
+
+        sender = sd_bus_message_get_sender(m);
+        if (!sender)
+                return -EINVAL;
+
+        return sd_bus_track_remove_name(track, sender);
+}
+
+_public_ sd_bus* sd_bus_track_get_bus(sd_bus_track *track) {
+        assert_return(track, NULL);
+
+        return track->bus;
+}
+
+void bus_track_dispatch(sd_bus_track *track) {
+        int r;
+
+        assert(track);
+        assert(track->in_queue);
+        assert(track->handler);
+
+        bus_track_remove_from_queue(track);
+
+        sd_bus_track_ref(track);
+
+        r = track->handler(track, track->userdata);
+        if (r < 0)
+                log_debug("Failed to process track handler: %s", strerror(-r));
+        else if (r == 0)
+                bus_track_add_to_queue(track);
+
+        sd_bus_track_unref(track);
+}
+
+_public_ void *sd_bus_track_get_userdata(sd_bus_track *track) {
+        assert_return(track, NULL);
+
+        return track->userdata;
+}
+
+_public_ void *sd_bus_track_set_userdata(sd_bus_track *track, void *userdata) {
+        void *ret;
+
+        assert_return(track, NULL);
+
+        ret = track->userdata;
+        track->userdata = userdata;
+
+        return ret;
+}
diff --git a/src/libsystemd/sd-bus/bus-track.h b/src/libsystemd/sd-bus/bus-track.h
new file mode 100644 (file)
index 0000000..f8690a5
--- /dev/null
@@ -0,0 +1,24 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2013 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+void bus_track_dispatch(sd_bus_track *track);
index 2935f69..475ed34 100644 (file)
@@ -26,6 +26,7 @@
 #include "strv.h"
 #include "macro.h"
 #include "def.h"
+#include "path-util.h"
 #include "missing.h"
 
 #include "sd-event.h"
@@ -42,7 +43,9 @@ static int name_owner_change_callback(sd_bus *bus, sd_bus_message *m, void *user
         assert(m);
         assert(e);
 
+        sd_bus_close(bus);
         sd_event_exit(e, 0);
+
         return 1;
 }
 
@@ -76,7 +79,7 @@ int bus_async_unregister_and_exit(sd_event *e, sd_bus *bus, const char *name) {
         if (r < 0)
                 return -ENOMEM;
 
-        r = sd_bus_add_match(bus, match, name_owner_change_callback, e);
+        r = sd_bus_add_match(bus, NULL, match, name_owner_change_callback, e);
         if (r < 0)
                 return r;
 
@@ -120,11 +123,30 @@ int bus_event_loop_with_idle(
                         return r;
 
                 if (r == 0 && !exiting) {
-                        r = bus_async_unregister_and_exit(e, bus, name);
+
+                        r = sd_bus_try_close(bus);
+                        if (r == -EBUSY)
+                                continue;
+
+                        if (r == -ENOTSUP) {
+                                /* Fallback for dbus1 connections: we
+                                 * unregister the name and wait for
+                                 * the response to come through for
+                                 * it */
+
+                                r = bus_async_unregister_and_exit(e, bus, name);
+                                if (r < 0)
+                                        return r;
+
+                                exiting = true;
+                                continue;
+                        }
+
                         if (r < 0)
                                 return r;
 
-                        exiting = true;
+                        sd_event_exit(e, 0);
+                        break;
                 }
         }
 
@@ -162,44 +184,35 @@ int bus_name_has_owner(sd_bus *c, const char *name, sd_bus_error *error) {
 }
 
 int bus_verify_polkit(
-                sd_bus *bus,
-                sd_bus_message *m,
+                sd_bus_message *call,
+                int capability,
                 const char *action,
                 bool interactive,
                 bool *_challenge,
                 sd_bus_error *e) {
 
-        _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
-        uid_t uid;
         int r;
 
-        assert(bus);
-        assert(m);
+        assert(call);
         assert(action);
 
-        r = sd_bus_query_sender_creds(m, SD_BUS_CREDS_UID, &creds);
+        r = sd_bus_query_sender_privilege(call, capability);
         if (r < 0)
                 return r;
-
-        r = sd_bus_creds_get_uid(creds, &uid);
-        if (r < 0)
-                return r;
-
-        if (uid == 0)
+        else if (r > 0)
                 return 1;
-
 #ifdef ENABLE_POLKIT
         else {
                 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
                 int authorized = false, challenge = false;
                 const char *sender;
 
-                sender = sd_bus_message_get_sender(m);
+                sender = sd_bus_message_get_sender(call);
                 if (!sender)
                         return -EBADMSG;
 
                 r = sd_bus_call_method(
-                                bus,
+                                call->bus,
                                 "org.freedesktop.PolicyKit1",
                                 "/org/freedesktop/PolicyKit1/Authority",
                                 "org.freedesktop.PolicyKit1.Authority",
@@ -250,17 +263,16 @@ typedef struct AsyncPolkitQuery {
         sd_bus_message *request, *reply;
         sd_bus_message_handler_t callback;
         void *userdata;
-        uint64_t serial;
+        sd_bus_slot *slot;
         Hashmap *registry;
 } AsyncPolkitQuery;
 
-static void async_polkit_query_free(sd_bus *b, AsyncPolkitQuery *q) {
+static void async_polkit_query_free(AsyncPolkitQuery *q) {
 
         if (!q)
                 return;
 
-        if (q->serial > 0 && b)
-                sd_bus_call_async_cancel(b, q->serial);
+        sd_bus_slot_unref(q->slot);
 
         if (q->registry && q->request)
                 hashmap_remove(q->registry, q->request);
@@ -280,8 +292,8 @@ static int async_polkit_callback(sd_bus *bus, sd_bus_message *reply, void *userd
         assert(reply);
         assert(q);
 
+        q->slot = sd_bus_slot_unref(q->slot);
         q->reply = sd_bus_message_ref(reply);
-        q->serial = 0;
 
         r = sd_bus_message_rewind(q->request, true);
         if (r < 0) {
@@ -293,38 +305,36 @@ static int async_polkit_callback(sd_bus *bus, sd_bus_message *reply, void *userd
         r = bus_maybe_reply_error(q->request, r, &error_buffer);
 
 finish:
-        async_polkit_query_free(bus, q);
+        async_polkit_query_free(q);
+
         return r;
 }
 
 #endif
 
 int bus_verify_polkit_async(
-                sd_bus *bus,
-                Hashmap **registry,
-                sd_bus_message *m,
+                sd_bus_message *call,
+                int capability,
                 const char *action,
                 bool interactive,
-                sd_bus_error *error,
-                sd_bus_message_handler_t callback,
-                void *userdata) {
+                Hashmap **registry,
+                sd_bus_error *error) {
 
 #ifdef ENABLE_POLKIT
         _cleanup_bus_message_unref_ sd_bus_message *pk = NULL;
         AsyncPolkitQuery *q;
         const char *sender;
+        sd_bus_message_handler_t callback;
+        void *userdata;
 #endif
-        _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
-        uid_t uid;
         int r;
 
-        assert(bus);
-        assert(registry);
-        assert(m);
+        assert(call);
         assert(action);
+        assert(registry);
 
 #ifdef ENABLE_POLKIT
-        q = hashmap_get(*registry, m);
+        q = hashmap_get(*registry, call);
         if (q) {
                 int authorized, challenge;
 
@@ -361,19 +371,23 @@ int bus_verify_polkit_async(
         }
 #endif
 
-        r = sd_bus_query_sender_creds(m, SD_BUS_CREDS_UID, &creds);
-        if (r < 0)
-                return r;
-
-        r = sd_bus_creds_get_uid(creds, &uid);
+        r = sd_bus_query_sender_privilege(call, capability);
         if (r < 0)
                 return r;
-
-        if (uid == 0)
+        else if (r > 0)
                 return 1;
 
 #ifdef ENABLE_POLKIT
-        sender = sd_bus_message_get_sender(m);
+        if (sd_bus_get_current_message(call->bus) != call)
+                return -EINVAL;
+
+        callback = sd_bus_get_current_handler(call->bus);
+        if (!callback)
+                return -EINVAL;
+
+        userdata = sd_bus_get_current_userdata(call->bus);
+
+        sender = sd_bus_message_get_sender(call);
         if (!sender)
                 return -EBADMSG;
 
@@ -382,7 +396,7 @@ int bus_verify_polkit_async(
                 return r;
 
         r = sd_bus_message_new_method_call(
-                        bus,
+                        call->bus,
                         &pk,
                         "org.freedesktop.PolicyKit1",
                         "/org/freedesktop/PolicyKit1/Authority",
@@ -406,21 +420,21 @@ int bus_verify_polkit_async(
         if (!q)
                 return -ENOMEM;
 
-        q->request = sd_bus_message_ref(m);
+        q->request = sd_bus_message_ref(call);
         q->callback = callback;
         q->userdata = userdata;
 
-        r = hashmap_put(*registry, m, q);
+        r = hashmap_put(*registry, call, q);
         if (r < 0) {
-                async_polkit_query_free(bus, q);
+                async_polkit_query_free(q);
                 return r;
         }
 
         q->registry = *registry;
 
-        r = sd_bus_call_async(bus, pk, async_polkit_callback, q, 0, &q->serial);
+        r = sd_bus_call_async(call->bus, &q->slot, pk, async_polkit_callback, q, 0);
         if (r < 0) {
-                async_polkit_query_free(bus, q);
+                async_polkit_query_free(q);
                 return r;
         }
 
@@ -430,12 +444,12 @@ int bus_verify_polkit_async(
         return -EACCES;
 }
 
-void bus_verify_polkit_async_registry_free(sd_bus *bus, Hashmap *registry) {
+void bus_verify_polkit_async_registry_free(Hashmap *registry) {
 #ifdef ENABLE_POLKIT
         AsyncPolkitQuery *q;
 
         while ((q = hashmap_steal_first(registry)))
-                async_polkit_query_free(bus, q);
+                async_polkit_query_free(q);
 
         hashmap_free(registry);
 #endif
@@ -536,7 +550,7 @@ int bus_open_user_systemd(sd_bus **_bus) {
         if (r < 0)
                 return r;
 
-        if (asprintf(&bus->address, KERNEL_USER_BUS_FMT, (unsigned long) getuid()) < 0)
+        if (asprintf(&bus->address, KERNEL_USER_BUS_FMT, getuid()) < 0)
                 return -ENOMEM;
 
         bus->bus_client = true;
@@ -1103,20 +1117,6 @@ int bus_open_transport_systemd(BusTransport transport, const char *host, bool us
         return r;
 }
 
-int bus_property_get_tristate(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        int *tristate = userdata;
-
-        return sd_bus_message_append(reply, "b", *tristate > 0);
-}
-
 int bus_property_get_bool(
                 sd_bus *bus,
                 const char *path,
@@ -1178,12 +1178,12 @@ int bus_property_get_ulong(
 #endif
 
 int bus_log_parse_error(int r) {
-        log_error("Failed to parse message: %s", strerror(-r));
+        log_error("Failed to parse bus message: %s", strerror(-r));
         return r;
 }
 
 int bus_log_create_error(int r) {
-        log_error("Failed to create message: %s", strerror(-r));
+        log_error("Failed to create bus message: %s", strerror(-r));
         return r;
 }
 
@@ -1191,6 +1191,8 @@ int bus_parse_unit_info(sd_bus_message *message, UnitInfo *u) {
         assert(message);
         assert(u);
 
+        u->machine = NULL;
+
         return sd_bus_message_read(
                         message,
                         "(ssssssouso)",
@@ -1230,3 +1232,231 @@ int bus_maybe_reply_error(sd_bus_message *m, int r, sd_bus_error *error) {
 
         return 1;
 }
+
+int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignment) {
+        const char *eq, *field;
+        int r;
+
+        assert(m);
+        assert(assignment);
+
+        eq = strchr(assignment, '=');
+        if (!eq) {
+                log_error("Not an assignment: %s", assignment);
+                return -EINVAL;
+        }
+
+        field = strndupa(assignment, eq - assignment);
+        eq ++;
+
+        if (streq(field, "CPUQuota")) {
+
+                if (isempty(eq)) {
+
+                        r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, "CPUQuotaPerSecUSec");
+                        if (r < 0)
+                                return bus_log_create_error(r);
+
+                        r = sd_bus_message_append(m, "v", "t", USEC_INFINITY);
+
+                } else if (endswith(eq, "%")) {
+                        double percent;
+
+                        if (sscanf(eq, "%lf%%", &percent) != 1 || percent <= 0) {
+                                log_error("CPU quota '%s' invalid.", eq);
+                                return -EINVAL;
+                        }
+
+                        r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, "CPUQuotaPerSecUSec");
+                        if (r < 0)
+                                return bus_log_create_error(r);
+
+                        r = sd_bus_message_append(m, "v", "t", (usec_t) percent * USEC_PER_SEC / 100);
+                } else {
+                        log_error("CPU quota needs to be in percent.");
+                        return -EINVAL;
+                }
+
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                return 0;
+        }
+
+        r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
+        if (r < 0)
+                return bus_log_create_error(r);
+
+        if (STR_IN_SET(field,
+                       "CPUAccounting", "MemoryAccounting", "BlockIOAccounting",
+                       "SendSIGHUP", "SendSIGKILL")) {
+
+                r = parse_boolean(eq);
+                if (r < 0) {
+                        log_error("Failed to parse boolean assignment %s.", assignment);
+                        return -EINVAL;
+                }
+
+                r = sd_bus_message_append(m, "v", "b", r);
+
+        } else if (streq(field, "MemoryLimit")) {
+                off_t bytes;
+
+                r = parse_size(eq, 1024, &bytes);
+                if (r < 0) {
+                        log_error("Failed to parse bytes specification %s", assignment);
+                        return -EINVAL;
+                }
+
+                r = sd_bus_message_append(m, "v", "t", (uint64_t) bytes);
+
+        } else if (STR_IN_SET(field, "CPUShares", "BlockIOWeight")) {
+                uint64_t u;
+
+                r = safe_atou64(eq, &u);
+                if (r < 0) {
+                        log_error("Failed to parse %s value %s.", field, eq);
+                        return -EINVAL;
+                }
+
+                r = sd_bus_message_append(m, "v", "t", u);
+
+        } else if (STR_IN_SET(field, "User", "Group", "DevicePolicy", "KillMode"))
+                r = sd_bus_message_append(m, "v", "s", eq);
+
+        else if (streq(field, "DeviceAllow")) {
+
+                if (isempty(eq))
+                        r = sd_bus_message_append(m, "v", "a(ss)", 0);
+                else {
+                        const char *path, *rwm, *e;
+
+                        e = strchr(eq, ' ');
+                        if (e) {
+                                path = strndupa(eq, e - eq);
+                                rwm = e+1;
+                        } else {
+                                path = eq;
+                                rwm = "";
+                        }
+
+                        if (!path_startswith(path, "/dev")) {
+                                log_error("%s is not a device file in /dev.", path);
+                                return -EINVAL;
+                        }
+
+                        r = sd_bus_message_append(m, "v", "a(ss)", 1, path, rwm);
+                }
+
+        } else if (STR_IN_SET(field, "BlockIOReadBandwidth", "BlockIOWriteBandwidth")) {
+
+                if (isempty(eq))
+                        r = sd_bus_message_append(m, "v", "a(st)", 0);
+                else {
+                        const char *path, *bandwidth, *e;
+                        off_t bytes;
+
+                        e = strchr(eq, ' ');
+                        if (e) {
+                                path = strndupa(eq, e - eq);
+                                bandwidth = e+1;
+                        } else {
+                                log_error("Failed to parse %s value %s.", field, eq);
+                                return -EINVAL;
+                        }
+
+                        if (!path_startswith(path, "/dev")) {
+                                log_error("%s is not a device file in /dev.", path);
+                                return -EINVAL;
+                        }
+
+                        r = parse_size(bandwidth, 1000, &bytes);
+                        if (r < 0) {
+                                log_error("Failed to parse byte value %s.", bandwidth);
+                                return -EINVAL;
+                        }
+
+                        r = sd_bus_message_append(m, "v", "a(st)", 1, path, (uint64_t) bytes);
+                }
+
+        } else if (streq(field, "BlockIODeviceWeight")) {
+
+                if (isempty(eq))
+                        r = sd_bus_message_append(m, "v", "a(st)", 0);
+                else {
+                        const char *path, *weight, *e;
+                        uint64_t u;
+
+                        e = strchr(eq, ' ');
+                        if (e) {
+                                path = strndupa(eq, e - eq);
+                                weight = e+1;
+                        } else {
+                                log_error("Failed to parse %s value %s.", field, eq);
+                                return -EINVAL;
+                        }
+
+                        if (!path_startswith(path, "/dev")) {
+                                log_error("%s is not a device file in /dev.", path);
+                                return -EINVAL;
+                        }
+
+                        r = safe_atou64(weight, &u);
+                        if (r < 0) {
+                                log_error("Failed to parse %s value %s.", field, weight);
+                                return -EINVAL;
+                        }
+                        r = sd_bus_message_append(m, "v", "a(st)", path, u);
+                }
+
+        } else if (rlimit_from_string(field) >= 0) {
+                uint64_t rl;
+
+                if (streq(eq, "infinity"))
+                        rl = (uint64_t) -1;
+                else {
+                        r = safe_atou64(eq, &rl);
+                        if (r < 0) {
+                                log_error("Invalid resource limit: %s", eq);
+                                return -EINVAL;
+                        }
+                }
+
+                r = sd_bus_message_append(m, "v", "t", rl);
+
+        } else if (streq(field, "Nice")) {
+                int32_t i;
+
+                r = safe_atoi32(eq, &i);
+                if (r < 0) {
+                        log_error("Failed to parse %s value %s.", field, eq);
+                        return -EINVAL;
+                }
+
+                r = sd_bus_message_append(m, "v", "i", i);
+
+        } else if (streq(field, "Environment")) {
+
+                r = sd_bus_message_append(m, "v", "as", 1, eq);
+
+        } else if (streq(field, "KillSignal")) {
+                int sig;
+
+                sig = signal_from_string_try_harder(eq);
+                if (sig < 0) {
+                        log_error("Failed to parse %s value %s.", field, eq);
+                        return -EINVAL;
+                }
+
+                r = sd_bus_message_append(m, "v", "i", sig);
+
+        } else {
+                log_error("Unknown assignment %s.", assignment);
+                return -EINVAL;
+        }
+
+        if (r < 0)
+                return bus_log_create_error(r);
+
+        return 0;
+}
index 51e1613..faf1775 100644 (file)
@@ -62,10 +62,10 @@ int bus_name_has_owner(sd_bus *c, const char *name, sd_bus_error *error);
 
 int bus_check_peercred(sd_bus *c);
 
-int bus_verify_polkit(sd_bus *bus, sd_bus_message *m, const char *action, bool interactive, bool *_challenge, sd_bus_error *e);
+int bus_verify_polkit(sd_bus_message *call, int capability, const char *action, bool interactive, bool *_challenge, sd_bus_error *e);
 
-int bus_verify_polkit_async(sd_bus *bus, Hashmap **registry, sd_bus_message *m, const char *action, bool interactive, sd_bus_error *error, sd_bus_message_handler_t callback, void *userdata);
-void bus_verify_polkit_async_registry_free(sd_bus *bus, Hashmap *registry);
+int bus_verify_polkit_async(sd_bus_message *call, int capability, const char *action, bool interactive, Hashmap **registry, sd_bus_error *error);
+void bus_verify_polkit_async_registry_free(Hashmap *registry);
 
 int bus_open_system_systemd(sd_bus **_bus);
 int bus_open_user_systemd(sd_bus **_bus);
@@ -76,7 +76,6 @@ int bus_open_transport_systemd(BusTransport transport, const char *host, bool us
 int bus_print_property(const char *name, sd_bus_message *property, bool all);
 int bus_print_all_properties(sd_bus *bus, const char *dest, const char *path, char **filter, bool all);
 
-int bus_property_get_tristate(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
 int bus_property_get_bool(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
 
 #define bus_property_get_usec ((sd_bus_property_get_t) NULL)
@@ -123,6 +122,7 @@ int bus_log_parse_error(int r);
 int bus_log_create_error(int r);
 
 typedef struct UnitInfo {
+        const char *machine;
         const char *id;
         const char *description;
         const char *load_state;
@@ -137,13 +137,26 @@ typedef struct UnitInfo {
 
 int bus_parse_unit_info(sd_bus_message *message, UnitInfo *u);
 
+static inline void sd_bus_close_unrefp(sd_bus **bus) {
+        if (*bus) {
+                sd_bus_flush(*bus);
+                sd_bus_close(*bus);
+                sd_bus_unref(*bus);
+        }
+}
+
 DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus*, sd_bus_unref);
+DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus_slot*, sd_bus_slot_unref);
 DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus_message*, sd_bus_message_unref);
 DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus_creds*, sd_bus_creds_unref);
+DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus_track*, sd_bus_track_unref);
 
 #define _cleanup_bus_unref_ _cleanup_(sd_bus_unrefp)
+#define _cleanup_bus_close_unref_ _cleanup_(sd_bus_close_unrefp)
+#define _cleanup_bus_slot_unref_ _cleanup_(sd_bus_slot_unrefp)
 #define _cleanup_bus_message_unref_ _cleanup_(sd_bus_message_unrefp)
 #define _cleanup_bus_creds_unref_ _cleanup_(sd_bus_creds_unrefp)
+#define _cleanup_bus_track_unref_ _cleanup_(sd_bus_slot_unrefp)
 #define _cleanup_bus_error_free_ _cleanup_(sd_bus_error_free)
 
 #define BUS_DEFINE_PROPERTY_GET_ENUM(function, name, type)              \
@@ -178,3 +191,5 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus_creds*, sd_bus_creds_unref);
         SD_BUS_PROPERTY(name "Monotonic", "t", bus_property_get_usec, (offset) + offsetof(struct dual_timestamp, monotonic), (flags))
 
 int bus_maybe_reply_error(sd_bus_message *m, int r, sd_bus_error *error);
+
+int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignment);
index e326cc0..af71804 100644 (file)
@@ -240,7 +240,7 @@ static int monitor(sd_bus *bus, char *argv[]) {
                 if (!m)
                         return log_oom();
 
-                r = sd_bus_add_match(bus, m, NULL, NULL);
+                r = sd_bus_add_match(bus, NULL, m, NULL, NULL);
                 if (r < 0) {
                         log_error("Failed to add match: %s", strerror(-r));
                         return r;
@@ -250,7 +250,7 @@ static int monitor(sd_bus *bus, char *argv[]) {
         }
 
         STRV_FOREACH(i, arg_matches) {
-                r = sd_bus_add_match(bus, *i, NULL, NULL);
+                r = sd_bus_add_match(bus, NULL, *i, NULL, NULL);
                 if (r < 0) {
                         log_error("Failed to add match: %s", strerror(-r));
                         return r;
@@ -260,7 +260,7 @@ static int monitor(sd_bus *bus, char *argv[]) {
         }
 
         if (!added_something) {
-                r = sd_bus_add_match(bus, "", NULL, NULL);
+                r = sd_bus_add_match(bus, NULL, "", NULL, NULL);
                 if (r < 0) {
                         log_error("Failed to add match: %s", strerror(-r));
                         return r;
@@ -320,7 +320,6 @@ static int status(sd_bus *bus, char *argv[]) {
 }
 
 static int help(void) {
-
         printf("%s [OPTIONS...] {COMMAND} ...\n\n"
                "Introspect the bus.\n\n"
                "  -h --help               Show this help\n"
@@ -341,8 +340,8 @@ static int help(void) {
                "  list                    List bus names\n"
                "  monitor [SERVICE...]    Show bus traffic\n"
                "  status NAME             Show name status\n"
-               "  help                    Show this help\n",
-               program_invocation_short_name);
+               "  help                    Show this help\n"
+               program_invocation_short_name);
 
         return 0;
 }
@@ -386,7 +385,7 @@ static int parse_argv(int argc, char *argv[]) {
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "hH:M:", options, NULL)) >= 0) {
+        while ((c = getopt_long(argc, argv, "hH:M:", options, NULL)) >= 0)
 
                 switch (c) {
 
@@ -455,7 +454,6 @@ static int parse_argv(int argc, char *argv[]) {
                 default:
                         assert_not_reached("Unhandled option");
                 }
-        }
 
         if (!arg_unique && !arg_acquired && !arg_activatable)
                 arg_unique = arg_acquired = arg_activatable = true;
@@ -484,7 +482,7 @@ static int busctl_main(sd_bus *bus, int argc, char *argv[]) {
 }
 
 int main(int argc, char *argv[]) {
-        _cleanup_bus_unref_ sd_bus *bus = NULL;
+        _cleanup_bus_close_unref_ sd_bus *bus = NULL;
         int r;
 
         log_parse_environment();
@@ -494,29 +492,75 @@ int main(int argc, char *argv[]) {
         if (r <= 0)
                 goto finish;
 
-        if (arg_address) {
-                r = sd_bus_new(&bus);
+        r = sd_bus_new(&bus);
+        if (r < 0) {
+                log_error("Failed to allocate bus: %s", strerror(-r));
+                goto finish;
+        }
+
+        if (streq_ptr(argv[optind], "monitor")) {
+
+                r = sd_bus_set_monitor(bus, true);
                 if (r < 0) {
-                        log_error("Failed to allocate bus: %s", strerror(-r));
+                        log_error("Failed to set monitor mode: %s", strerror(-r));
                         goto finish;
                 }
 
-                r = sd_bus_set_address(bus, arg_address);
+                r = sd_bus_negotiate_creds(bus, _SD_BUS_CREDS_ALL);
                 if (r < 0) {
-                        log_error("Failed to set address: %s", strerror(-r));
+                        log_error("Failed to enable credentials: %s", strerror(-r));
                         goto finish;
                 }
 
-                r = sd_bus_set_bus_client(bus, true);
+                r = sd_bus_negotiate_timestamp(bus, true);
                 if (r < 0) {
-                        log_error("Failed to set bus client: %s", strerror(-r));
+                        log_error("Failed to enable timestamps: %s", strerror(-r));
                         goto finish;
                 }
 
-                r = sd_bus_start(bus);
-        } else
-                r = bus_open_transport(arg_transport, arg_host, arg_user, &bus);
+                r = sd_bus_negotiate_fds(bus, true);
+                if (r < 0) {
+                        log_error("Failed to enable fds: %s", strerror(-r));
+                        goto finish;
+                }
+        }
+
+        if (arg_address)
+                r = sd_bus_set_address(bus, arg_address);
+        else {
+                switch (arg_transport) {
+
+                case BUS_TRANSPORT_LOCAL:
+                        if (arg_user)
+                                r = bus_set_address_user(bus);
+                        else
+                                r = bus_set_address_system(bus);
+                        break;
+
+                case BUS_TRANSPORT_REMOTE:
+                        r = bus_set_address_system_remote(bus, arg_host);
+                        break;
+
+                case BUS_TRANSPORT_CONTAINER:
+                        r = bus_set_address_system_container(bus, arg_host);
+                        break;
+
+                default:
+                        assert_not_reached("Hmm, unknown transport type.");
+                }
+        }
+        if (r < 0) {
+                log_error("Failed to set address: %s", strerror(-r));
+                goto finish;
+        }
+
+        r = sd_bus_set_bus_client(bus, true);
+        if (r < 0) {
+                log_error("Failed to set bus client: %s", strerror(-r));
+                goto finish;
+        }
 
+        r = sd_bus_start(bus);
         if (r < 0) {
                 log_error("Failed to connect to bus: %s", strerror(-r));
                 goto finish;
index c9a8940..8f98396 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/types.h>
 #endif
 
-#define KDBUS_IOC_MAGIC                        0x95
+#define KDBUS_IOCTL_MAGIC              0x95
 #define KDBUS_SRC_ID_KERNEL            (0)
 #define KDBUS_DST_ID_NAME              (0)
 #define KDBUS_MATCH_ID_ANY             (~0ULL)
@@ -173,8 +173,8 @@ struct kdbus_memfd {
 
 /**
  * struct kdbus_name - a registered well-known name with its flags
- * @flags:             flags from KDBUS_NAME_*
- * @name:              well-known name
+ * @flags:             Flags from KDBUS_NAME_*
+ * @name:              Well-known name
  *
  * Attached to:
  *   KDBUS_ITEM_NAME
@@ -187,36 +187,17 @@ struct kdbus_name {
 /**
  * struct kdbus_policy_access - policy access item
  * @type:              One of KDBUS_POLICY_ACCESS_* types
- * @bits:              Access to grant. One of KDBUS_POLICY_*
+ * @access:            Access to grant
  * @id:                        For KDBUS_POLICY_ACCESS_USER, the uid
  *                     For KDBUS_POLICY_ACCESS_GROUP, the gid
- *
- * Embedded in:
- *   struct kdbus_policy
  */
 struct kdbus_policy_access {
        __u64 type;     /* USER, GROUP, WORLD */
-       __u64 bits;     /* RECV, SEND, OWN */
+       __u64 access;   /* OWN, TALK, SEE */
        __u64 id;       /* uid, gid, 0 */
 };
 
 /**
- * struct kdbus_policy - a policy item
- * @access:            Policy access details
- * @name:              Well-known name to grant access to
- *
- * Attached to:
- *   KDBUS_POLICY_ACCESS
- *   KDBUS_ITEM_POLICY_NAME
- */
-struct kdbus_policy {
-       union {
-               struct kdbus_policy_access access;
-               char name[0];
-       };
-};
-
-/**
  * enum kdbus_item_type - item types to chain data in a list
  * @_KDBUS_ITEM_NULL:          Uninitialized/invalid
  * @_KDBUS_ITEM_USER_BASE:     Start of user items
@@ -252,8 +233,7 @@ struct kdbus_policy {
  * @KDBUS_ITEM_AUDIT:          The audit IDs
  * @KDBUS_ITEM_CONN_NAME:      The connection's human-readable name (debugging)
  * @_KDBUS_ITEM_POLICY_BASE:   Start of policy items
- * @KDBUS_ITEM_POLICY_NAME:    Policy in struct kdbus_policy
- * @KDBUS_ITEM_POLICY_ACCESS:  Policy in struct kdbus_policy
+ * @KDBUS_ITEM_POLICY_ACCESS:  Policy access block
  * @_KDBUS_ITEM_KERNEL_BASE:   Start of kernel-generated message items
  * @KDBUS_ITEM_NAME_ADD:       Notify in struct kdbus_notify_name_change
  * @KDBUS_ITEM_NAME_REMOVE:    Notify in struct kdbus_notify_name_change
@@ -294,8 +274,7 @@ enum kdbus_item_type {
        KDBUS_ITEM_CONN_NAME,
 
        _KDBUS_ITEM_POLICY_BASE = 0x2000,
-       KDBUS_ITEM_POLICY_NAME = _KDBUS_ITEM_POLICY_BASE,
-       KDBUS_ITEM_POLICY_ACCESS,
+       KDBUS_ITEM_POLICY_ACCESS = _KDBUS_ITEM_POLICY_BASE,
 
        _KDBUS_ITEM_KERNEL_BASE = 0x8000,
        KDBUS_ITEM_NAME_ADD     = _KDBUS_ITEM_KERNEL_BASE,
@@ -329,8 +308,7 @@ enum kdbus_item_type {
  *                     KDBUS_ITEM_NAME_CHANGE
  * @id_change:         KDBUS_ITEM_ID_ADD
  *                     KDBUS_ITEM_ID_REMOVE
- * @policy:            KDBUS_ITEM_POLICY_NAME
- *                     KDBUS_ITEM_POLICY_ACCESS
+ * @policy:            KDBUS_ITEM_POLICY_ACCESS
  */
 struct kdbus_item {
        __u64 size;
@@ -353,7 +331,7 @@ struct kdbus_item {
                int fds[0];
                struct kdbus_notify_name_change name_change;
                struct kdbus_notify_id_change id_change;
-               struct kdbus_policy policy;
+               struct kdbus_policy_access policy_access;
        };
 };
 
@@ -365,15 +343,15 @@ struct kdbus_item {
  *                                     respective reply carries the cookie
  *                                     in cookie_reply
  * @KDBUS_MSG_FLAGS_SYNC_REPLY:                Wait for destination connection to
- *                                     reply to this message. The
- *                                     KDBUS_CMD_MSG_SEND ioctl() will block
- *                                     until the reply is received, and
- *                                     offset_reply in struct kdbus_msg will
- *                                     yield the offset in the sender's pool
- *                                     where the reply can be found.
- *                                     This flag is only valid if
- *                                     @KDBUS_MSG_FLAGS_EXPECT_REPLY is set as
- *                                     well.
+ *                                     reply to this message. The
+ *                                     KDBUS_CMD_MSG_SEND ioctl() will block
+ *                                     until the reply is received, and
+ *                                     offset_reply in struct kdbus_msg will
+ *                                     yield the offset in the sender's pool
+ *                                     where the reply can be found.
+ *                                     This flag is only valid if
+ *                                     @KDBUS_MSG_FLAGS_EXPECT_REPLY is set as
+ *                                     well.
  * @KDBUS_MSG_FLAGS_NO_AUTO_START:     Do not start a service, if the addressed
  *                                     name is not currently active
  */
@@ -410,7 +388,7 @@ enum kdbus_payload_type {
  * @cookie_reply:      A reply to the requesting message with the same
  *                     cookie. The requesting connection can match its
  *                     request and the reply with this value
- * @offset_reply:      If KDBUS_MSG_FLAGS_WAIT_FOR_REPLY, this field will
+ * @offset_reply:      If KDBUS_MSG_FLAGS_EXPECT_REPLY, this field will
  *                     contain the offset in the sender's pool where the
  *                     reply is stored.
  * @items:             A list of kdbus_items containing the message payload
@@ -441,8 +419,8 @@ struct kdbus_msg {
  * @KDBUS_RECV_DROP:           Drop and free the next queued message and all
  *                             its resources without actually receiving it.
  * @KDBUS_RECV_USE_PRIORITY:   Only de-queue messages with the specified or
- *                             higher priority (lowest values); if not set,
- *                             the priority value is ignored.
+ *                             higher priority (lowest values); if not set,
+ *                             the priority value is ignored.
  */
 enum kdbus_recv_flags {
        KDBUS_RECV_PEEK         = 1 <<  0,
@@ -456,8 +434,8 @@ enum kdbus_recv_flags {
  * @priority:          Minimum priority of the messages to de-queue. Lowest
  *                     values have the highest priority.
  * @offset:            Returned offset in the pool where the message is
- *                     stored. The user must use KDBUS_CMD_FREE to free
- *                     the allocated memory.
+ *                     stored. The user must use KDBUS_CMD_FREE to free
+ *                     the allocated memory.
  *
  * This struct is used with the KDBUS_CMD_MSG_RECV ioctl.
  */
@@ -483,44 +461,39 @@ enum kdbus_policy_access_type {
 
 /**
  * enum kdbus_policy_access_flags - mode flags
- * @KDBUS_POLICY_RECV:         Allow receive
- * @KDBUS_POLICY_SEND:         Allow send
  * @KDBUS_POLICY_OWN:          Allow to own a well-known name
+ *                             Implies KDBUS_POLICY_TALK and KDBUS_POLICY_SEE
+ * @KDBUS_POLICY_TALK:         Allow communication to a well-known name
+ *                             Implies KDBUS_POLICY_SEE
+ * @KDBUS_POLICY_SEE:          Allow to see a well-known name
  */
 enum kdbus_policy_type {
-       KDBUS_POLICY_RECV               = 1 <<  2,
-       KDBUS_POLICY_SEND               = 1 <<  1,
-       KDBUS_POLICY_OWN                = 1 <<  0,
+       KDBUS_POLICY_SEE        = 0,
+       KDBUS_POLICY_TALK,
+       KDBUS_POLICY_OWN,
 };
 
 /**
- * struct kdbus_cmd_policy - a series of policies to upload
- * @size:              The total size of the structure
- * @policies:          The policies to upload
- *
- * A KDBUS_POLICY_NAME must always preceeds a KDBUS_POLICY_ACCESS entry.
- * A new KDBUS_POLICY_NAME can be added after KDBUS_POLICY_ACCESS for
- * chaining multiple policies together.
- */
-struct kdbus_cmd_policy {
-       __u64 size;
-       struct kdbus_item policies[0];
-} __attribute__((aligned(8)));
-
-/**
  * enum kdbus_hello_flags - flags for struct kdbus_cmd_hello
  * @KDBUS_HELLO_ACCEPT_FD:     The connection allows the receiving of
  *                             any passed file descriptors
  * @KDBUS_HELLO_ACTIVATOR:     Special-purpose connection which registers
  *                             a well-know name for a process to be started
  *                             when traffic arrives
+ * @KDBUS_HELLO_POLICY_HOLDER: Special-purpose connection which registers
+ *                             policy entries for a name. The provided name
+ *                             is not activated and not registered with the
+ *                             name database, it only allows unprivileged
+ *                             connections to aquire a name, talk or discover
+ *                             a service
  * @KDBUS_HELLO_MONITOR:       Special-purpose connection to monitor
  *                             bus traffic
  */
 enum kdbus_hello_flags {
        KDBUS_HELLO_ACCEPT_FD           =  1 <<  0,
        KDBUS_HELLO_ACTIVATOR           =  1 <<  1,
-       KDBUS_HELLO_MONITOR             =  1 <<  2,
+       KDBUS_HELLO_POLICY_HOLDER       =  1 <<  2,
+       KDBUS_HELLO_MONITOR             =  1 <<  3,
 };
 
 /**
@@ -536,6 +509,7 @@ enum kdbus_hello_flags {
  * @KDBUS_ATTACH_SECLABEL:     The security label
  * @KDBUS_ATTACH_AUDIT:                The audit IDs
  * @KDBUS_ATTACH_CONN_NAME:    The human-readable connection name
+ * @_KDBUS_ATTACH_ALL:         All of the above
  */
 enum kdbus_attach_flags {
        KDBUS_ATTACH_TIMESTAMP          =  1 <<  0,
@@ -549,6 +523,7 @@ enum kdbus_attach_flags {
        KDBUS_ATTACH_SECLABEL           =  1 <<  8,
        KDBUS_ATTACH_AUDIT              =  1 <<  9,
        KDBUS_ATTACH_CONN_NAME          =  1 << 10,
+       _KDBUS_ATTACH_ALL               =  (1 << 11) - 1,
 };
 
 /**
@@ -584,11 +559,14 @@ struct kdbus_cmd_hello {
        struct kdbus_item items[0];
 } __attribute__((aligned(8)));
 
-/* Flags for KDBUS_CMD_{BUS,EP,NS}_MAKE */
+/**
+ * enum kdbus_make_flags - Flags for KDBUS_CMD_{BUS,EP,NS}_MAKE
+ * @KDBUS_MAKE_ACCESS_GROUP:   Make the device node group-accessible
+ * @KDBUS_MAKE_ACCESS_WORLD:   Make the device node world-accessible
+ */
 enum kdbus_make_flags {
        KDBUS_MAKE_ACCESS_GROUP         = 1 <<  0,
        KDBUS_MAKE_ACCESS_WORLD         = 1 <<  1,
-       KDBUS_MAKE_POLICY_OPEN          = 1 <<  2,
 };
 
 /**
@@ -626,9 +604,7 @@ enum kdbus_name_flags {
  * struct kdbus_cmd_name - struct to describe a well-known name
  * @size:              The total size of the struct
  * @flags:             Flags for a name entry (KDBUS_NAME_*)
- * @owner_id:          The current owner of the name. For requests,
- *                     privileged users may set this field to
- *                     (de)register names on behalf of other connections.
+ * @owner_id:          The current owner of the name.
  * @conn_flags:                The flags of the owning connection (KDBUS_HELLO_*)
  * @name:              The well-known name
  *
@@ -726,13 +702,13 @@ struct kdbus_conn_info {
 };
 
 /**
- * struct kdbus_cmd_conn_update - update flags of a connection
+ * struct kdbus_cmd_update - update flags of a connection
  * @size:              The total size of the struct
  * @items:             A list of struct kdbus_item
  *
  * This struct is used with the KDBUS_CMD_CONN_UPDATE ioctl.
  */
-struct kdbus_cmd_conn_update {
+struct kdbus_cmd_update {
        __u64 size;
        struct kdbus_item items[0];
 } __attribute__((aligned(8)));
@@ -740,8 +716,6 @@ struct kdbus_cmd_conn_update {
 /**
  * struct kdbus_cmd_match - struct to add or remove matches
  * @size:              The total size of the struct
- * @owner_id:          Privileged users may (de)register matches on behalf
- *                     of other peers
  * @cookie:            Userspace supplied cookie. When removing, the cookie
  *                     identifies the match to remove
  * @items:             A list of items for additional information
@@ -751,7 +725,6 @@ struct kdbus_cmd_conn_update {
  */
 struct kdbus_cmd_match {
        __u64 size;
-       __u64 owner_id;
        __u64 cookie;
        struct kdbus_item items[0];
 } __attribute__((aligned(8)));
@@ -781,7 +754,7 @@ struct kdbus_cmd_memfd_make {
  *                             name. The bus is immediately shut down and
  *                             cleaned up when the opened "control" device node
  *                             is closed.
- * @KDBUS_CMD_DOMAIN_MAKE:             Similar to KDBUS_CMD_BUS_MAKE, but it creates a
+ * @KDBUS_CMD_DOMAIN_MAKE:     Similar to KDBUS_CMD_BUS_MAKE, but it creates a
  *                             new kdbus domain.
  * @KDBUS_CMD_EP_MAKE:         Creates a new named special endpoint to talk to
  *                             the bus. Such endpoints usually carry a more
@@ -800,8 +773,8 @@ struct kdbus_cmd_memfd_make {
  * @KDBUS_CMD_MSG_RECV:                Receive a message from the kernel which is
  *                             placed in the receiver's pool.
  * @KDBUS_CMD_MSG_CANCEL:      Cancel a pending request of a message that
- *                             blocks while waiting for a reply. The parameter
- *                             denotes the cookie of the message in flight.
+ *                             blocks while waiting for a reply. The parameter
+ *                             denotes the cookie of the message in flight.
  * @KDBUS_CMD_FREE:            Release the allocated memory in the receiver's
  *                             pool.
  * @KDBUS_CMD_NAME_ACQUIRE:    Request a well-known bus name to associate with
@@ -817,13 +790,13 @@ struct kdbus_cmd_memfd_make {
  *                             necessarily represent the connected process or
  *                             the actual state of the process.
  * @KDBUS_CMD_CONN_UPDATE:     Update the properties of a connection. Used to
- *                             update the metadata subscription.
+ *                             update the metadata subscription mask and
+ *                             policy.
+ * @KDBUS_CMD_EP_UPDATE:       Update the properties of a custom enpoint. Used
+ *                             to update the policy.
  * @KDBUS_CMD_MATCH_ADD:       Install a match which broadcast messages should
  *                             be delivered to the connection.
  * @KDBUS_CMD_MATCH_REMOVE:    Remove a current match for broadcast messages.
- * @KDBUS_CMD_EP_POLICY_SET:   Set the policy of an endpoint. It is used to
- *                             restrict the access for endpoints created with
- *                             KDBUS_CMD_EP_MAKE.
  * @KDBUS_CMD_MEMFD_NEW:       Return a new file descriptor which provides an
  *                             anonymous shared memory file and which can be
  *                             used to pass around larger chunks of data.
@@ -852,35 +825,50 @@ struct kdbus_cmd_memfd_make {
  *                             be changed as long as the file is shared.
  */
 enum kdbus_ioctl_type {
-       KDBUS_CMD_BUS_MAKE =            _IOW (KDBUS_IOC_MAGIC, 0x00, struct kdbus_cmd_make),
-       KDBUS_CMD_DOMAIN_MAKE =         _IOW (KDBUS_IOC_MAGIC, 0x10, struct kdbus_cmd_make),
-       KDBUS_CMD_EP_MAKE =             _IOW (KDBUS_IOC_MAGIC, 0x20, struct kdbus_cmd_make),
-
-       KDBUS_CMD_HELLO =               _IOWR(KDBUS_IOC_MAGIC, 0x30, struct kdbus_cmd_hello),
-       KDBUS_CMD_BYEBYE =              _IO  (KDBUS_IOC_MAGIC, 0x31),
-
-       KDBUS_CMD_MSG_SEND =            _IOWR(KDBUS_IOC_MAGIC, 0x40, struct kdbus_msg),
-       KDBUS_CMD_MSG_RECV =            _IOWR(KDBUS_IOC_MAGIC, 0x41, struct kdbus_cmd_recv),
-       KDBUS_CMD_MSG_CANCEL =          _IOW (KDBUS_IOC_MAGIC, 0x42, __u64 *),
-       KDBUS_CMD_FREE =                _IOW (KDBUS_IOC_MAGIC, 0x43, __u64 *),
-
-       KDBUS_CMD_NAME_ACQUIRE =        _IOWR(KDBUS_IOC_MAGIC, 0x50, struct kdbus_cmd_name),
-       KDBUS_CMD_NAME_RELEASE =        _IOW (KDBUS_IOC_MAGIC, 0x51, struct kdbus_cmd_name),
-       KDBUS_CMD_NAME_LIST =           _IOWR(KDBUS_IOC_MAGIC, 0x52, struct kdbus_cmd_name_list),
-
-       KDBUS_CMD_CONN_INFO =           _IOWR(KDBUS_IOC_MAGIC, 0x60, struct kdbus_cmd_conn_info),
-       KDBUS_CMD_CONN_UPDATE =         _IOW (KDBUS_IOC_MAGIC, 0x61, struct kdbus_cmd_conn_update),
-
-       KDBUS_CMD_MATCH_ADD =           _IOW (KDBUS_IOC_MAGIC, 0x70, struct kdbus_cmd_match),
-       KDBUS_CMD_MATCH_REMOVE =        _IOW (KDBUS_IOC_MAGIC, 0x71, struct kdbus_cmd_match),
-
-       KDBUS_CMD_EP_POLICY_SET =       _IOW (KDBUS_IOC_MAGIC, 0x80, struct kdbus_cmd_policy),
-
-       KDBUS_CMD_MEMFD_NEW =           _IOWR(KDBUS_IOC_MAGIC, 0xc0, struct kdbus_cmd_memfd_make),
-       KDBUS_CMD_MEMFD_SIZE_GET =      _IOR (KDBUS_IOC_MAGIC, 0xc1, __u64 *),
-       KDBUS_CMD_MEMFD_SIZE_SET =      _IOW (KDBUS_IOC_MAGIC, 0xc2, __u64 *),
-       KDBUS_CMD_MEMFD_SEAL_GET =      _IOR (KDBUS_IOC_MAGIC, 0xc3, int *),
-       KDBUS_CMD_MEMFD_SEAL_SET =      _IO  (KDBUS_IOC_MAGIC, 0xc4),
+       KDBUS_CMD_BUS_MAKE =            _IOW(KDBUS_IOCTL_MAGIC, 0x00,
+                                            struct kdbus_cmd_make),
+       KDBUS_CMD_DOMAIN_MAKE =         _IOW(KDBUS_IOCTL_MAGIC, 0x10,
+                                            struct kdbus_cmd_make),
+       KDBUS_CMD_EP_MAKE =             _IOW(KDBUS_IOCTL_MAGIC, 0x20,
+                                            struct kdbus_cmd_make),
+
+       KDBUS_CMD_HELLO =               _IOWR(KDBUS_IOCTL_MAGIC, 0x30,
+                                             struct kdbus_cmd_hello),
+       KDBUS_CMD_BYEBYE =              _IO(KDBUS_IOCTL_MAGIC, 0x31),
+
+       KDBUS_CMD_MSG_SEND =            _IOWR(KDBUS_IOCTL_MAGIC, 0x40,
+                                             struct kdbus_msg),
+       KDBUS_CMD_MSG_RECV =            _IOWR(KDBUS_IOCTL_MAGIC, 0x41,
+                                             struct kdbus_cmd_recv),
+       KDBUS_CMD_MSG_CANCEL =          _IOW(KDBUS_IOCTL_MAGIC, 0x42, __u64 *),
+       KDBUS_CMD_FREE =                _IOW(KDBUS_IOCTL_MAGIC, 0x43, __u64 *),
+
+       KDBUS_CMD_NAME_ACQUIRE =        _IOWR(KDBUS_IOCTL_MAGIC, 0x50,
+                                             struct kdbus_cmd_name),
+       KDBUS_CMD_NAME_RELEASE =        _IOW(KDBUS_IOCTL_MAGIC, 0x51,
+                                            struct kdbus_cmd_name),
+       KDBUS_CMD_NAME_LIST =           _IOWR(KDBUS_IOCTL_MAGIC, 0x52,
+                                            struct kdbus_cmd_name_list),
+
+       KDBUS_CMD_CONN_INFO =           _IOWR(KDBUS_IOCTL_MAGIC, 0x60,
+                                             struct kdbus_cmd_conn_info),
+       KDBUS_CMD_CONN_UPDATE =         _IOW(KDBUS_IOCTL_MAGIC, 0x61,
+                                            struct kdbus_cmd_update),
+
+       KDBUS_CMD_EP_UPDATE =           _IOW(KDBUS_IOCTL_MAGIC, 0x71,
+                                            struct kdbus_cmd_update),
+
+       KDBUS_CMD_MATCH_ADD =           _IOW(KDBUS_IOCTL_MAGIC, 0x80,
+                                            struct kdbus_cmd_match),
+       KDBUS_CMD_MATCH_REMOVE =        _IOW(KDBUS_IOCTL_MAGIC, 0x81,
+                                            struct kdbus_cmd_match),
+
+       KDBUS_CMD_MEMFD_NEW =           _IOWR(KDBUS_IOCTL_MAGIC, 0xc0,
+                                             struct kdbus_cmd_memfd_make),
+       KDBUS_CMD_MEMFD_SIZE_GET =      _IOR(KDBUS_IOCTL_MAGIC, 0xc1, __u64 *),
+       KDBUS_CMD_MEMFD_SIZE_SET =      _IOW(KDBUS_IOCTL_MAGIC, 0xc2, __u64 *),
+       KDBUS_CMD_MEMFD_SEAL_GET =      _IOR(KDBUS_IOCTL_MAGIC, 0xc3, int *),
+       KDBUS_CMD_MEMFD_SEAL_SET =      _IO(KDBUS_IOCTL_MAGIC, 0xc4),
 };
 
 /*
@@ -891,6 +879,9 @@ enum kdbus_ioctl_type {
  * @EADDRNOTAVAIL:     A message flagged not to activate a service, addressed
  *                     a service which is not currently running.
  * @EAGAIN:            No messages are queued at the moment.
+ * @EALREADY:          A requested name is already owned by the connection,
+ *                     a connection is already disconnected, memfd is already
+ *                     sealed or has the requested size.
  * @EBADF:             File descriptors passed with the message are not valid.
  * @EBADFD:            A bus connection is in a corrupted state.
  * @EBADMSG:           Passed data contains a combination of conflicting or
@@ -928,26 +919,25 @@ enum kdbus_ioctl_type {
  *                     size.
  * @ENOBUFS:           There is no space left for the submitted data to fit
  *                     into the receiver's pool.
- * @ENOENT:            The name to query information about is currently not on
- *                     the bus.
+ * @ENOENT:            The to be cancelled message was not found.
  * @ENOMEM:            Out of memory.
  * @ENOMSG:            The queue is not empty, but no message with a matching
- *                     priority is currently queued.
+ *                     priority is currently queued.
  * @ENOSYS:            The requested functionality is not available.
- * @ENOTSUPP:          The feature negotiation failed, a not supported feature
- *                     was requested, or an unknown item type was received.
  * @ENOTTY:            An unknown ioctl command was received.
  * @ENOTUNIQ:          A specific data type was addressed to a broadcast
  *                     address, but only direct addresses support this kind of
  *                     data.
  * @ENXIO:             A unique address does not exist, or an offset in the
  *                     receiver's pool does not represent a queued message.
+ * @EOPNOTSUPP:                The feature negotiation failed, a not supported feature
+ *                     was requested, or an unknown item type was received.
  * @EPERM:             The policy prevented an operation. The requested
  *                     resource is owned by another entity.
  * @EPIPE:             When sending a message, a synchronous reply from the
  *                     receiving connection was expected but the connection
  *                     died before answering.
- * @ESHUTDOWN:         A domain or endpoint is currently shutting down;
+ * @ESHUTDOWN:         A domain, bus or endpoint is currently shutting down;
  *                     no further operations will be possible.
  * @ESRCH:             A requested well-known bus name is not found.
  * @ETIMEDOUT:         A synchronous wait for a message reply did not arrive
index 20f540d..387cd0d 100644 (file)
@@ -51,6 +51,8 @@
 #include "bus-util.h"
 #include "bus-container.h"
 #include "bus-protocol.h"
+#include "bus-track.h"
+#include "bus-slot.h"
 
 static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec);
 static int attach_io_events(sd_bus *b);
@@ -62,51 +64,14 @@ static void bus_close_fds(sd_bus *b) {
         detach_io_events(b);
 
         if (b->input_fd >= 0)
-                close_nointr_nofail(b->input_fd);
+                safe_close(b->input_fd);
 
         if (b->output_fd >= 0 && b->output_fd != b->input_fd)
-                close_nointr_nofail(b->output_fd);
+                safe_close(b->output_fd);
 
         b->input_fd = b->output_fd = -1;
 }
 
-static void bus_node_destroy(sd_bus *b, struct node *n) {
-        struct node_callback *c;
-        struct node_vtable *v;
-        struct node_enumerator *e;
-
-        assert(b);
-
-        if (!n)
-                return;
-
-        while (n->child)
-                bus_node_destroy(b, n->child);
-
-        while ((c = n->callbacks)) {
-                LIST_REMOVE(callbacks, n->callbacks, c);
-                free(c);
-        }
-
-        while ((v = n->vtables)) {
-                LIST_REMOVE(vtables, n->vtables, v);
-                free(v->interface);
-                free(v);
-        }
-
-        while ((e = n->enumerators)) {
-                LIST_REMOVE(enumerators, n->enumerators, e);
-                free(e);
-        }
-
-        if (n->parent)
-                LIST_REMOVE(siblings, n->parent->child, n);
-
-        assert_se(hashmap_remove(b->nodes, n->path) == n);
-        free(n->path);
-        free(n);
-}
-
 static void bus_reset_queues(sd_bus *b) {
         assert(b);
 
@@ -126,13 +91,28 @@ static void bus_reset_queues(sd_bus *b) {
 }
 
 static void bus_free(sd_bus *b) {
-        struct filter_callback *f;
-        struct node *n;
+        sd_bus_slot *s;
 
         assert(b);
+        assert(!b->track_queue);
+
+        b->state = BUS_CLOSED;
 
         sd_bus_detach_event(b);
 
+        while ((s = b->slots)) {
+                /* At this point only floating slots can still be
+                 * around, because the non-floating ones keep a
+                 * reference to the bus, and we thus couldn't be
+                 * destructing right now... We forcibly disconnect the
+                 * slots here, so that they still can be referenced by
+                 * apps, but are dead. */
+
+                assert(s->floating);
+                bus_slot_disconnect(s);
+                sd_bus_slot_unref(s);
+        }
+
         if (b->default_bus_ptr)
                 *b->default_bus_ptr = NULL;
 
@@ -162,19 +142,12 @@ static void bus_free(sd_bus *b) {
         hashmap_free_free(b->reply_callbacks);
         prioq_free(b->reply_callbacks_prioq);
 
-        while ((f = b->filter_callbacks)) {
-                LIST_REMOVE(callbacks, b->filter_callbacks, f);
-                free(f);
-        }
-
         bus_match_free(&b->match_callbacks);
 
         hashmap_free_free(b->vtable_methods);
         hashmap_free_free(b->vtable_properties);
 
-        while ((n = hashmap_first(b->nodes)))
-                bus_node_destroy(b, n);
-
+        assert(hashmap_isempty(b->nodes));
         hashmap_free(b->nodes);
 
         bus_kernel_flush_memfd(b);
@@ -281,6 +254,15 @@ _public_ int sd_bus_set_bus_client(sd_bus *bus, int b) {
         return 0;
 }
 
+_public_ int sd_bus_set_monitor(sd_bus *bus, int b) {
+        assert_return(bus, -EINVAL);
+        assert_return(bus->state == BUS_UNSET, -EPERM);
+        assert_return(!bus_pid_changed(bus), -ECHILD);
+
+        SET_FLAG(bus->hello_flags, KDBUS_HELLO_MONITOR, b);
+        return 0;
+}
+
 _public_ int sd_bus_negotiate_fds(sd_bus *bus, int b) {
         assert_return(bus, -EINVAL);
         assert_return(bus->state == BUS_UNSET, -EPERM);
@@ -308,7 +290,7 @@ _public_ int sd_bus_negotiate_creds(sd_bus *bus, uint64_t mask) {
         /* The well knowns we need unconditionally, so that matches can work */
         bus->creds_mask = mask | SD_BUS_CREDS_WELL_KNOWN_NAMES|SD_BUS_CREDS_UNIQUE_NAME;
 
-        return kdbus_translate_attach_flags(bus->creds_mask, &bus->creds_mask);
+        return kdbus_translate_attach_flags(bus->creds_mask, &bus->attach_flags);
 }
 
 _public_ int sd_bus_set_server(sd_bus *bus, int b, sd_id128_t server_id) {
@@ -408,7 +390,7 @@ static int bus_send_hello(sd_bus *bus) {
         if (r < 0)
                 return r;
 
-        return sd_bus_call_async(bus, m, hello_callback, NULL, 0, &bus->hello_cookie);
+        return sd_bus_call_async(bus, NULL, m, hello_callback, NULL, 0);
 }
 
 int bus_start_running(sd_bus *bus) {
@@ -795,7 +777,7 @@ static int parse_container_unix_address(sd_bus *b, const char **p, char **guid)
 
         b->sockaddr.un.sun_family = AF_UNIX;
         strncpy(b->sockaddr.un.sun_path, "/var/run/dbus/system_bus_socket", sizeof(b->sockaddr.un.sun_path));
-        b->sockaddr_size = offsetof(struct sockaddr_un, sun_path) + sizeof("/var/run/dbus/system_bus_socket") - 1;
+        b->sockaddr_size = offsetof(struct sockaddr_un, sun_path) + strlen("/var/run/dbus/system_bus_socket");
 
         return 0;
 }
@@ -1051,8 +1033,10 @@ _public_ int sd_bus_start(sd_bus *bus) {
         else
                 return -EINVAL;
 
-        if (r < 0)
+        if (r < 0) {
+                sd_bus_close(bus);
                 return r;
+        }
 
         return bus_send_hello(bus);
 }
@@ -1072,7 +1056,7 @@ _public_ int sd_bus_open(sd_bus **ret) {
         if (e) {
                 if (streq(e, "system"))
                         return sd_bus_open_system(ret);
-                else if (streq(e, "session") || streq(e, "user"))
+                else if (STR_IN_SET(e, "session", "user"))
                         return sd_bus_open_user(ret);
         }
 
@@ -1111,8 +1095,18 @@ fail:
         return r;
 }
 
-_public_ int sd_bus_open_system(sd_bus **ret) {
+int bus_set_address_system(sd_bus *b) {
         const char *e;
+        assert(b);
+
+        e = secure_getenv("DBUS_SYSTEM_BUS_ADDRESS");
+        if (e)
+                return sd_bus_set_address(b, e);
+
+        return sd_bus_set_address(b, DEFAULT_SYSTEM_BUS_PATH);
+}
+
+_public_ int sd_bus_open_system(sd_bus **ret) {
         sd_bus *b;
         int r;
 
@@ -1122,11 +1116,7 @@ _public_ int sd_bus_open_system(sd_bus **ret) {
         if (r < 0)
                 return r;
 
-        e = secure_getenv("DBUS_SYSTEM_BUS_ADDRESS");
-        if (e)
-                r = sd_bus_set_address(b, e);
-        else
-                r = sd_bus_set_address(b, DEFAULT_SYSTEM_BUS_PATH);
+        r = bus_set_address_system(b);
         if (r < 0)
                 goto fail;
 
@@ -1150,52 +1140,56 @@ fail:
         return r;
 }
 
-_public_ int sd_bus_open_user(sd_bus **ret) {
+int bus_set_address_user(sd_bus *b) {
         const char *e;
-        sd_bus *b;
-        int r;
-
-        assert_return(ret, -EINVAL);
 
-        r = sd_bus_new(&b);
-        if (r < 0)
-                return r;
+        assert(b);
 
         e = secure_getenv("DBUS_SESSION_BUS_ADDRESS");
+        if (e)
+                return sd_bus_set_address(b, e);
+
+        e = secure_getenv("XDG_RUNTIME_DIR");
         if (e) {
-                r = sd_bus_set_address(b, e);
-                if (r < 0)
-                        goto fail;
-        } else {
-                e = secure_getenv("XDG_RUNTIME_DIR");
-                if (e) {
-                        _cleanup_free_ char *ee = NULL;
+                _cleanup_free_ char *ee = NULL;
 
-                        ee = bus_address_escape(e);
-                        if (!ee) {
-                                r = -ENOMEM;
-                                goto fail;
-                        }
+                ee = bus_address_escape(e);
+                if (!ee)
+                        return -ENOMEM;
 
 #ifdef ENABLE_KDBUS
-                        asprintf(&b->address, KERNEL_USER_BUS_FMT ";" UNIX_USER_BUS_FMT, (unsigned long) getuid(), ee);
+                asprintf(&b->address, KERNEL_USER_BUS_FMT ";" UNIX_USER_BUS_FMT, getuid(), ee);
 #else
-                        asprintf(&b->address, UNIX_USER_BUS_FMT, ee);
+                asprintf(&b->address, UNIX_USER_BUS_FMT, ee);
 #endif
-                } else {
+        } else {
 #ifdef ENABLE_KDBUS
-                        asprintf(&b->address, KERNEL_USER_BUS_FMT, (unsigned long) getuid());
+                asprintf(&b->address, KERNEL_USER_BUS_FMT, getuid());
 #else
-                        return -ECONNREFUSED;
+                return -ECONNREFUSED;
 #endif
-                }
-
-                if (!b->address) {
-                        r = -ENOMEM;
-                        goto fail;
-                }
         }
 
+        if (!b->address)
+                return -ENOMEM;
+
+        return 0;
+}
+
+_public_ int sd_bus_open_user(sd_bus **ret) {
+        sd_bus *b;
+        int r;
+
+        assert_return(ret, -EINVAL);
+
+        r = sd_bus_new(&b);
+        if (r < 0)
+                return r;
+
+        r = bus_set_address_user(b);
+        if (r < 0)
+                return r;
+
         b->bus_client = true;
         b->is_user = true;
 
@@ -1215,81 +1209,126 @@ fail:
         return r;
 }
 
-_public_ int sd_bus_open_system_remote(sd_bus **ret, const char *host) {
+int bus_set_address_system_remote(sd_bus *b, const char *host) {
         _cleanup_free_ char *e = NULL;
-        char *p = NULL;
+        char *m = NULL, *c = NULL;
+
+        assert(b);
+        assert(host);
+
+        /* Let's see if we shall enter some container */
+        m = strchr(host, ':');
+        if (m) {
+                m++;
+
+                /* Let's make sure this is not a port of some kind,
+                 * and is a valid machine name. */
+                if (!in_charset(m, "0123456789") && machine_name_is_valid(m)) {
+                        char *t;
+
+                        /* Cut out the host part */
+                        t = strndupa(host, m - host - 1);
+                        e = bus_address_escape(t);
+                        if (!e)
+                                return -ENOMEM;
+
+                        c = strappenda(",argv4=--machine=", m);
+                }
+        }
+
+        if (!e) {
+                e = bus_address_escape(host);
+                if (!e)
+                        return -ENOMEM;
+        }
+
+        b->address = strjoin("unixexec:path=ssh,argv1=-xT,argv2=", e, ",argv3=systemd-stdio-bridge", c, NULL);
+        if (!b->address)
+                return -ENOMEM;
+
+        return 0;
+ }
+
+_public_ int sd_bus_open_system_remote(sd_bus **ret, const char *host) {
         sd_bus *bus;
         int r;
 
         assert_return(host, -EINVAL);
         assert_return(ret, -EINVAL);
 
-        e = bus_address_escape(host);
-        if (!e)
-                return -ENOMEM;
-
-        p = strjoin("unixexec:path=ssh,argv1=-xT,argv2=", e, ",argv3=systemd-stdio-bridge", NULL);
-        if (!p)
-                return -ENOMEM;
-
         r = sd_bus_new(&bus);
-        if (r < 0) {
-                free(p);
+        if (r < 0)
                 return r;
-        }
 
-        bus->address = p;
+        r = bus_set_address_system_remote(bus, host);
+        if (r < 0)
+                goto fail;
+
         bus->bus_client = true;
+        bus->trusted = false;
 
         r = sd_bus_start(bus);
-        if (r < 0) {
-                bus_free(bus);
-                return r;
-        }
+        if (r < 0)
+                goto fail;
 
         *ret = bus;
         return 0;
+
+fail:
+        bus_free(bus);
+        return r;
 }
 
-_public_ int sd_bus_open_system_container(sd_bus **ret, const char *machine) {
+int bus_set_address_system_container(sd_bus *b, const char *machine) {
         _cleanup_free_ char *e = NULL;
-        sd_bus *bus;
-        char *p;
-        int r;
 
-        assert_return(machine, -EINVAL);
-        assert_return(ret, -EINVAL);
-        assert_return(filename_is_safe(machine), -EINVAL);
+        assert(b);
+        assert(machine);
 
         e = bus_address_escape(machine);
         if (!e)
                 return -ENOMEM;
 
 #ifdef ENABLE_KDBUS
-        p = strjoin("x-container-kernel:machine=", e, ";x-container-unix:machine=", e, NULL);
+        b->address = strjoin("x-container-kernel:machine=", e, ";x-container-unix:machine=", e, NULL);
 #else
-        p = strjoin("x-container-unix:machine=", e, NULL);
+        b->address = strjoin("x-container-unix:machine=", e, NULL);
 #endif
-        if (!p)
+        if (!b->address)
                 return -ENOMEM;
 
+        return 0;
+}
+
+_public_ int sd_bus_open_system_container(sd_bus **ret, const char *machine) {
+        sd_bus *bus;
+        int r;
+
+        assert_return(machine, -EINVAL);
+        assert_return(ret, -EINVAL);
+        assert_return(filename_is_safe(machine), -EINVAL);
+
         r = sd_bus_new(&bus);
-        if (r < 0) {
-                free(p);
+        if (r < 0)
                 return r;
-        }
 
-        bus->address = p;
+        r = bus_set_address_system_container(bus, machine);
+        if (r < 0)
+                goto fail;
+
         bus->bus_client = true;
+        bus->trusted = false;
 
         r = sd_bus_start(bus);
-        if (r < 0) {
-                bus_free(bus);
-                return r;
-        }
+        if (r < 0)
+                goto fail;
 
         *ret = bus;
         return 0;
+
+fail:
+        bus_free(bus);
+        return r;
 }
 
 _public_ void sd_bus_close(sd_bus *bus) {
@@ -1344,32 +1383,6 @@ _public_ sd_bus *sd_bus_unref(sd_bus *bus) {
         if (!bus)
                 return NULL;
 
-        if (REFCNT_GET(bus->n_ref) == bus->rqueue_size + bus->wqueue_size + 1) {
-                bool q = true;
-
-                for (i = 0; i < bus->rqueue_size; i++)
-                        if (bus->rqueue[i]->n_ref > 1) {
-                                q = false;
-                                break;
-                        }
-
-                if (q) {
-                        for (i = 0; i < bus->wqueue_size; i++)
-                                if (bus->wqueue[i]->n_ref > 1) {
-                                        q = false;
-                                        break;
-                                }
-                }
-
-                /* We are the only holders on the messages, and the
-                 * messages are the only holders on us, so let's drop
-                 * the messages and thus implicitly also kill our own
-                 * last references */
-
-                if (q)
-                        bus_reset_queues(bus);
-        }
-
         i = REFCNT_DEC(bus->n_ref);
         if (i > 0)
                 return NULL;
@@ -1393,6 +1406,9 @@ _public_ int sd_bus_can_send(sd_bus *bus, char type) {
         assert_return(bus->state != BUS_UNSET, -ENOTCONN);
         assert_return(!bus_pid_changed(bus), -ECHILD);
 
+        if (bus->hello_flags & KDBUS_HELLO_MONITOR)
+                return 0;
+
         if (type == SD_BUS_TYPE_UNIX_FD) {
                 if (!(bus->hello_flags & KDBUS_HELLO_ACCEPT_FD))
                         return 0;
@@ -1443,7 +1459,7 @@ static int bus_seal_message(sd_bus *b, sd_bus_message *m, usec_t timeout) {
 static int bus_remarshal_message(sd_bus *b, sd_bus_message **m) {
         assert(b);
 
-        /* Do packet version and endianess already match? */
+        /* Do packet version and endianness already match? */
         if ((b->message_version == 0 || b->message_version == (*m)->header->version) &&
             (b->message_endian == 0 || b->message_endian == (*m)->header->endian))
                 return 0;
@@ -1460,7 +1476,7 @@ int bus_seal_synthetic_message(sd_bus *b, sd_bus_message *m) {
          * hence let's fill something in for synthetic messages. Since
          * synthetic messages might have a fake sender and we don't
          * want to interfere with the real sender's serial numbers we
-         * pick a fixed, artifical one. We use (uint32_t) -1 rather
+         * pick a fixed, artificial one. We use (uint32_t) -1 rather
          * than (uint64_t) -1 since dbus1 only had 32bit identifiers,
          * even though kdbus can do 64bit. */
 
@@ -1482,15 +1498,15 @@ static int bus_write_message(sd_bus *bus, sd_bus_message *m, bool hint_sync_call
                 return r;
 
         if (bus->is_kernel || *idx >= BUS_MESSAGE_SIZE(m))
-                log_debug("Sent message type=%s sender=%s destination=%s object=%s interface=%s member=%s cookie=%lu reply_cookie=%lu error=%s",
+                log_debug("Sent message type=%s sender=%s destination=%s object=%s interface=%s member=%s cookie=%" PRIu64 " reply_cookie=%" PRIu64 " error=%s",
                           bus_message_type_to_string(m->header->type),
                           strna(sd_bus_message_get_sender(m)),
                           strna(sd_bus_message_get_destination(m)),
                           strna(sd_bus_message_get_path(m)),
                           strna(sd_bus_message_get_interface(m)),
                           strna(sd_bus_message_get_member(m)),
-                          (unsigned long) BUS_MESSAGE_COOKIE(m),
-                          (unsigned long) m->reply_cookie,
+                          BUS_MESSAGE_COOKIE(m),
+                          m->reply_cookie,
                           strna(m->error.message));
 
         return r;
@@ -1591,9 +1607,12 @@ static int bus_send_internal(sd_bus *bus, sd_bus_message *_m, uint64_t *cookie,
         int r;
 
         assert_return(bus, -EINVAL);
-        assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
         assert_return(m, -EINVAL);
         assert_return(!bus_pid_changed(bus), -ECHILD);
+        assert_return(!bus->is_kernel || !(bus->hello_flags & KDBUS_HELLO_MONITOR), -EROFS);
+
+        if (!BUS_IS_OPEN(bus->state))
+                return -ENOTCONN;
 
         if (m->n_fds > 0) {
                 r = sd_bus_can_send(bus, SD_BUS_TYPE_UNIX_FD);
@@ -1603,6 +1622,11 @@ static int bus_send_internal(sd_bus *bus, sd_bus_message *_m, uint64_t *cookie,
                         return -ENOTSUP;
         }
 
+        /* Set sender field */
+        if (bus->is_kernel)
+                if ((bus->unique_name != NULL) && (m->sender == NULL))
+                        bus_message_append_sender (m, bus->unique_name);
+
         /* If the cookie number isn't kept, then we know that no reply
          * is expected */
         if (!cookie && !m->sealed)
@@ -1670,10 +1694,12 @@ _public_ int sd_bus_send_to(sd_bus *bus, sd_bus_message *m, const char *destinat
         int r;
 
         assert_return(bus, -EINVAL);
-        assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
         assert_return(m, -EINVAL);
         assert_return(!bus_pid_changed(bus), -ECHILD);
 
+        if (!BUS_IS_OPEN(bus->state))
+                return -ENOTCONN;
+
         if (!streq_ptr(m->destination, destination)) {
 
                 if (!destination)
@@ -1714,23 +1740,26 @@ static int timeout_compare(const void *a, const void *b) {
 
 _public_ int sd_bus_call_async(
                 sd_bus *bus,
+                sd_bus_slot **slot,
                 sd_bus_message *_m,
                 sd_bus_message_handler_t callback,
                 void *userdata,
-                uint64_t usec,
-                uint64_t *cookie) {
+                uint64_t usec) {
 
         _cleanup_bus_message_unref_ sd_bus_message *m = sd_bus_message_ref(_m);
-        struct reply_callback *c;
+        _cleanup_bus_slot_unref_ sd_bus_slot *s = NULL;
         int r;
 
         assert_return(bus, -EINVAL);
-        assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
         assert_return(m, -EINVAL);
         assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
         assert_return(!(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED), -EINVAL);
         assert_return(callback, -EINVAL);
         assert_return(!bus_pid_changed(bus), -ECHILD);
+        assert_return(!bus->is_kernel || !(bus->hello_flags & KDBUS_HELLO_MONITOR), -EROFS);
+
+        if (!BUS_IS_OPEN(bus->state))
+                return -ENOTCONN;
 
         r = hashmap_ensure_allocated(&bus->reply_callbacks, uint64_hash_func, uint64_compare_func);
         if (r < 0)
@@ -1748,55 +1777,37 @@ _public_ int sd_bus_call_async(
         if (r < 0)
                 return r;
 
-        c = new0(struct reply_callback, 1);
-        if (!c)
+        s = bus_slot_allocate(bus, !slot, BUS_REPLY_CALLBACK, sizeof(struct reply_callback), userdata);
+        if (!s)
                 return -ENOMEM;
 
-        c->callback = callback;
-        c->userdata = userdata;
-        c->cookie = BUS_MESSAGE_COOKIE(m);
-        c->timeout = calc_elapse(m->timeout);
+        s->reply_callback.callback = callback;
 
-        r = hashmap_put(bus->reply_callbacks, &c->cookie, c);
+        s->reply_callback.cookie = BUS_MESSAGE_COOKIE(m);
+        r = hashmap_put(bus->reply_callbacks, &s->reply_callback.cookie, &s->reply_callback);
         if (r < 0) {
-                free(c);
+                s->reply_callback.cookie = 0;
                 return r;
         }
 
-        if (c->timeout != 0) {
-                r = prioq_put(bus->reply_callbacks_prioq, c, &c->prioq_idx);
+        s->reply_callback.timeout = calc_elapse(m->timeout);
+        if (s->reply_callback.timeout != 0) {
+                r = prioq_put(bus->reply_callbacks_prioq, &s->reply_callback, &s->reply_callback.prioq_idx);
                 if (r < 0) {
-                        c->timeout = 0;
-                        sd_bus_call_async_cancel(bus, c->cookie);
+                        s->reply_callback.timeout = 0;
                         return r;
                 }
         }
 
-        r = sd_bus_send(bus, m, cookie);
-        if (r < 0) {
-                sd_bus_call_async_cancel(bus, c->cookie);
+        r = sd_bus_send(bus, m, &s->reply_callback.cookie);
+        if (r < 0)
                 return r;
-        }
-
-        return r;
-}
 
-_public_ int sd_bus_call_async_cancel(sd_bus *bus, uint64_t cookie) {
-        struct reply_callback *c;
+        if (slot)
+                *slot = s;
+        s = NULL;
 
-        assert_return(bus, -EINVAL);
-        assert_return(cookie != 0, -EINVAL);
-        assert_return(!bus_pid_changed(bus), -ECHILD);
-
-        c = hashmap_remove(bus->reply_callbacks, &cookie);
-        if (!c)
-                return 0;
-
-        if (c->timeout != 0)
-                prioq_remove(bus->reply_callbacks_prioq, c, &c->prioq_idx);
-
-        free(c);
-        return 1;
+        return r;
 }
 
 int bus_ensure_running(sd_bus *bus) {
@@ -1838,12 +1849,15 @@ _public_ int sd_bus_call(
         int r;
 
         assert_return(bus, -EINVAL);
-        assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
         assert_return(m, -EINVAL);
         assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
         assert_return(!(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED), -EINVAL);
         assert_return(!bus_error_is_dirty(error), -EINVAL);
         assert_return(!bus_pid_changed(bus), -ECHILD);
+        assert_return(!bus->is_kernel || !(bus->hello_flags & KDBUS_HELLO_MONITOR), -EROFS);
+
+        if (!BUS_IS_OPEN(bus->state))
+                return -ENOTCONN;
 
         r = bus_ensure_running(bus);
         if (r < 0)
@@ -1881,12 +1895,17 @@ _public_ int sd_bus_call(
 
                                 if (incoming->header->type == SD_BUS_MESSAGE_METHOD_RETURN) {
 
-                                        if (reply)
-                                                *reply = incoming;
-                                        else
-                                                sd_bus_message_unref(incoming);
+                                        if (incoming->n_fds <= 0 || (bus->hello_flags & KDBUS_HELLO_ACCEPT_FD)) {
+                                                if (reply)
+                                                        *reply = incoming;
+                                                else
+                                                        sd_bus_message_unref(incoming);
+
+                                                return 1;
+                                        }
+
+                                        r = sd_bus_error_setf(error, SD_BUS_ERROR_INCONSISTENT_MESSAGE, "Reply message contained file descriptors which I couldn't accept. Sorry.");
 
-                                        return 1;
                                 } else if (incoming->header->type == SD_BUS_MESSAGE_METHOD_ERROR)
                                         r = sd_bus_error_copy(error, &incoming->error);
                                 else
@@ -1970,9 +1989,11 @@ _public_ int sd_bus_get_events(sd_bus *bus) {
         int flags = 0;
 
         assert_return(bus, -EINVAL);
-        assert_return(BUS_IS_OPEN(bus->state) || bus->state == BUS_CLOSING, -ENOTCONN);
         assert_return(!bus_pid_changed(bus), -ECHILD);
 
+        if (!BUS_IS_OPEN(bus->state) && bus->state != BUS_CLOSING)
+                return -ENOTCONN;
+
         if (bus->state == BUS_OPENING)
                 flags |= POLLOUT;
         else if (bus->state == BUS_AUTHENTICATING) {
@@ -1997,9 +2018,16 @@ _public_ int sd_bus_get_timeout(sd_bus *bus, uint64_t *timeout_usec) {
 
         assert_return(bus, -EINVAL);
         assert_return(timeout_usec, -EINVAL);
-        assert_return(BUS_IS_OPEN(bus->state) || bus->state == BUS_CLOSING, -ENOTCONN);
         assert_return(!bus_pid_changed(bus), -ECHILD);
 
+        if (!BUS_IS_OPEN(bus->state) && bus->state != BUS_CLOSING)
+                return -ENOTCONN;
+
+        if (bus->track_queue) {
+                *timeout_usec = 0;
+                return 1;
+        }
+
         if (bus->state == BUS_CLOSING) {
                 *timeout_usec = 0;
                 return 1;
@@ -2026,6 +2054,11 @@ _public_ int sd_bus_get_timeout(sd_bus *bus, uint64_t *timeout_usec) {
                 return 0;
         }
 
+        if (c->timeout == 0) {
+                *timeout_usec = (uint64_t) -1;
+                return 0;
+        }
+
         *timeout_usec = c->timeout;
         return 1;
 }
@@ -2034,6 +2067,7 @@ static int process_timeout(sd_bus *bus) {
         _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
         _cleanup_bus_message_unref_ sd_bus_message* m = NULL;
         struct reply_callback *c;
+        sd_bus_slot *slot;
         usec_t n;
         int r;
 
@@ -2062,18 +2096,31 @@ static int process_timeout(sd_bus *bus) {
                 return r;
 
         assert_se(prioq_pop(bus->reply_callbacks_prioq) == c);
+        c->timeout = 0;
+
         hashmap_remove(bus->reply_callbacks, &c->cookie);
+        c->cookie = 0;
+
+        slot = container_of(c, sd_bus_slot, reply_callback);
 
-        bus->current = m;
         bus->iteration_counter ++;
 
-        r = c->callback(bus, m, c->userdata, &error_buffer);
-        r = bus_maybe_reply_error(m, r, &error_buffer);
-        free(c);
+        bus->current_message = m;
+        bus->current_slot = sd_bus_slot_ref(slot);
+        bus->current_handler = c->callback;
+        bus->current_userdata = slot->userdata;
+        r = c->callback(bus, m, slot->userdata, &error_buffer);
+        bus->current_userdata = NULL;
+        bus->current_handler = NULL;
+        bus->current_slot = sd_bus_slot_unref(slot);
+        bus->current_message = NULL;
 
-        bus->current = NULL;
+        if (slot->floating) {
+                bus_slot_disconnect(slot);
+                sd_bus_slot_unref(slot);
+        }
 
-        return r;
+        return bus_maybe_reply_error(m, r, &error_buffer);
 }
 
 static int process_hello(sd_bus *bus, sd_bus_message *m) {
@@ -2092,15 +2139,17 @@ static int process_hello(sd_bus *bus, sd_bus_message *m) {
             m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
                 return -EIO;
 
-        if (m->reply_cookie != bus->hello_cookie)
+        if (m->reply_cookie != 1)
                 return -EIO;
 
         return 0;
 }
 
 static int process_reply(sd_bus *bus, sd_bus_message *m) {
+        _cleanup_bus_message_unref_ sd_bus_message *synthetic_reply = NULL;
         _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
         struct reply_callback *c;
+        sd_bus_slot *slot;
         int r;
 
         assert(bus);
@@ -2110,22 +2159,63 @@ static int process_reply(sd_bus *bus, sd_bus_message *m) {
             m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
                 return 0;
 
+        if (bus->is_kernel && (bus->hello_flags & KDBUS_HELLO_MONITOR))
+                return 0;
+
+        if (m->destination && bus->unique_name && !streq_ptr(m->destination, bus->unique_name))
+                return 0;
+
         c = hashmap_remove(bus->reply_callbacks, &m->reply_cookie);
         if (!c)
                 return 0;
 
-        if (c->timeout != 0)
+        c->cookie = 0;
+
+        slot = container_of(c, sd_bus_slot, reply_callback);
+
+        if (m->n_fds > 0 && !(bus->hello_flags & KDBUS_HELLO_ACCEPT_FD)) {
+
+                /* If the reply contained a file descriptor which we
+                 * didn't want we pass an error instead. */
+
+                r = bus_message_new_synthetic_error(
+                                bus,
+                                m->reply_cookie,
+                                &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INCONSISTENT_MESSAGE, "Reply message contained file descriptor"),
+                                &synthetic_reply);
+                if (r < 0)
+                        return r;
+
+                r = bus_seal_synthetic_message(bus, synthetic_reply);
+                if (r < 0)
+                        return r;
+
+                m = synthetic_reply;
+        } else {
+                r = sd_bus_message_rewind(m, true);
+                if (r < 0)
+                        return r;
+        }
+
+        if (c->timeout != 0) {
                 prioq_remove(bus->reply_callbacks_prioq, c, &c->prioq_idx);
+                c->timeout = 0;
+        }
 
-        r = sd_bus_message_rewind(m, true);
-        if (r < 0)
-                return r;
+        bus->current_slot = sd_bus_slot_ref(slot);
+        bus->current_handler = c->callback;
+        bus->current_userdata = slot->userdata;
+        r = c->callback(bus, m, slot->userdata, &error_buffer);
+        bus->current_userdata = NULL;
+        bus->current_handler = NULL;
+        bus->current_slot = sd_bus_slot_unref(slot);
 
-        r = c->callback(bus, m, c->userdata, &error_buffer);
-        r = bus_maybe_reply_error(m, r, &error_buffer);
-        free(c);
+        if (slot->floating) {
+                bus_slot_disconnect(slot);
+                sd_bus_slot_unref(slot);
+        }
 
-        return r;
+        return bus_maybe_reply_error(m, r, &error_buffer);
 }
 
 static int process_filter(sd_bus *bus, sd_bus_message *m) {
@@ -2140,6 +2230,7 @@ static int process_filter(sd_bus *bus, sd_bus_message *m) {
                 bus->filter_callbacks_modified = false;
 
                 LIST_FOREACH(callbacks, l, bus->filter_callbacks) {
+                        sd_bus_slot *slot;
 
                         if (bus->filter_callbacks_modified)
                                 break;
@@ -2154,7 +2245,16 @@ static int process_filter(sd_bus *bus, sd_bus_message *m) {
                         if (r < 0)
                                 return r;
 
-                        r = l->callback(bus, m, l->userdata, &error_buffer);
+                        slot = container_of(l, sd_bus_slot, filter_callback);
+
+                        bus->current_slot = sd_bus_slot_ref(slot);
+                        bus->current_handler = l->callback;
+                        bus->current_userdata = slot->userdata;
+                        r = l->callback(bus, m, slot->userdata, &error_buffer);
+                        bus->current_userdata = NULL;
+                        bus->current_handler = NULL;
+                        bus->current_slot = sd_bus_slot_unref(slot);
+
                         r = bus_maybe_reply_error(m, r, &error_buffer);
                         if (r != 0)
                                 return r;
@@ -2191,6 +2291,9 @@ static int process_builtin(sd_bus *bus, sd_bus_message *m) {
         assert(bus);
         assert(m);
 
+        if (bus->hello_flags & KDBUS_HELLO_MONITOR)
+                return 0;
+
         if (bus->manual_peer_interface)
                 return 0;
 
@@ -2235,24 +2338,50 @@ static int process_builtin(sd_bus *bus, sd_bus_message *m) {
         return 1;
 }
 
+static int process_fd_check(sd_bus *bus, sd_bus_message *m) {
+        assert(bus);
+        assert(m);
+
+        /* If we got a message with a file descriptor which we didn't
+         * want to accept, then let's drop it. How can this even
+         * happen? For example, when the kernel queues a message into
+         * an activatable names's queue which allows fds, and then is
+         * delivered to us later even though we ourselves did not
+         * negotiate it. */
+
+        if (bus->hello_flags & KDBUS_HELLO_MONITOR)
+                return 0;
+
+        if (m->n_fds <= 0)
+                return 0;
+
+        if (bus->hello_flags & KDBUS_HELLO_ACCEPT_FD)
+                return 0;
+
+        if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
+                return 1; /* just eat it up */
+
+        return sd_bus_reply_method_errorf(m, SD_BUS_ERROR_INCONSISTENT_MESSAGE, "Message contains file descriptors, which I cannot accept. Sorry.");
+}
+
 static int process_message(sd_bus *bus, sd_bus_message *m) {
         int r;
 
         assert(bus);
         assert(m);
 
-        bus->current = m;
+        bus->current_message = m;
         bus->iteration_counter++;
 
-        log_debug("Got message type=%s sender=%s destination=%s object=%s interface=%s member=%s cookie=%lu reply_cookie=%lu error=%s",
+        log_debug("Got message type=%s sender=%s destination=%s object=%s interface=%s member=%s cookie=%" PRIu64 " reply_cookie=%" PRIu64 " error=%s",
                   bus_message_type_to_string(m->header->type),
                   strna(sd_bus_message_get_sender(m)),
                   strna(sd_bus_message_get_destination(m)),
                   strna(sd_bus_message_get_path(m)),
                   strna(sd_bus_message_get_interface(m)),
                   strna(sd_bus_message_get_member(m)),
-                  (unsigned long) BUS_MESSAGE_COOKIE(m),
-                  (unsigned long) m->reply_cookie,
+                  BUS_MESSAGE_COOKIE(m),
+                  m->reply_cookie,
                   strna(m->error.message));
 
         r = process_hello(bus, m);
@@ -2263,6 +2392,10 @@ static int process_message(sd_bus *bus, sd_bus_message *m) {
         if (r != 0)
                 goto finish;
 
+        r = process_fd_check(bus, m);
+        if (r != 0)
+                goto finish;
+
         r = process_filter(bus, m);
         if (r != 0)
                 goto finish;
@@ -2278,10 +2411,20 @@ static int process_message(sd_bus *bus, sd_bus_message *m) {
         r = bus_process_object(bus, m);
 
 finish:
-        bus->current = NULL;
+        bus->current_message = NULL;
         return r;
 }
 
+static int dispatch_track(sd_bus *bus) {
+        assert(bus);
+
+        if (!bus->track_queue)
+                return 0;
+
+        bus_track_dispatch(bus->track_queue);
+        return 1;
+}
+
 static int process_running(sd_bus *bus, bool hint_priority, int64_t priority, sd_bus_message **ret) {
         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
         int r;
@@ -2297,6 +2440,10 @@ static int process_running(sd_bus *bus, bool hint_priority, int64_t priority, sd
         if (r != 0)
                 goto null_message;
 
+        r = dispatch_track(bus);
+        if (r != 0)
+                goto null_message;
+
         r = dispatch_rqueue(bus, hint_priority, priority, &m);
         if (r < 0)
                 return r;
@@ -2353,6 +2500,7 @@ static int process_closing(sd_bus *bus, sd_bus_message **ret) {
         c = hashmap_first(bus->reply_callbacks);
         if (c) {
                 _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
+                sd_bus_slot *slot;
 
                 /* First, fail all outstanding method calls */
                 r = bus_message_new_synthetic_error(
@@ -2367,19 +2515,34 @@ static int process_closing(sd_bus *bus, sd_bus_message **ret) {
                 if (r < 0)
                         return r;
 
-                if (c->timeout != 0)
+                if (c->timeout != 0) {
                         prioq_remove(bus->reply_callbacks_prioq, c, &c->prioq_idx);
+                        c->timeout = 0;
+                }
 
                 hashmap_remove(bus->reply_callbacks, &c->cookie);
+                c->cookie = 0;
+
+                slot = container_of(c, sd_bus_slot, reply_callback);
 
-                bus->current = m;
                 bus->iteration_counter++;
 
-                r = c->callback(bus, m, c->userdata, &error_buffer);
-                r = bus_maybe_reply_error(m, r, &error_buffer);
-                free(c);
+                bus->current_message = m;
+                bus->current_slot = sd_bus_slot_ref(slot);
+                bus->current_handler = c->callback;
+                bus->current_userdata = slot->userdata;
+                r = c->callback(bus, m, slot->userdata, &error_buffer);
+                bus->current_userdata = NULL;
+                bus->current_handler = NULL;
+                bus->current_slot = sd_bus_slot_unref(slot);
+                bus->current_message = NULL;
+
+                if (slot->floating) {
+                        bus_slot_disconnect(slot);
+                        sd_bus_slot_unref(slot);
+                }
 
-                goto finish;
+                return bus_maybe_reply_error(m, r, &error_buffer);
         }
 
         /* Then, synthesize a Disconnected message */
@@ -2400,7 +2563,7 @@ static int process_closing(sd_bus *bus, sd_bus_message **ret) {
 
         sd_bus_close(bus);
 
-        bus->current = m;
+        bus->current_message = m;
         bus->iteration_counter++;
 
         r = process_filter(bus, m);
@@ -2419,7 +2582,8 @@ static int process_closing(sd_bus *bus, sd_bus_message **ret) {
         r = 1;
 
 finish:
-        bus->current = NULL;
+        bus->current_message = NULL;
+
         return r;
 }
 
@@ -2436,7 +2600,8 @@ static int bus_process_internal(sd_bus *bus, bool hint_priority, int64_t priorit
         assert_return(!bus_pid_changed(bus), -ECHILD);
 
         /* We don't allow recursively invoking sd_bus_process(). */
-        assert_return(!bus->current, -EBUSY);
+        assert_return(!bus->current_message, -EBUSY);
+        assert(!bus->current_slot);
 
         switch (bus->state) {
 
@@ -2502,14 +2667,15 @@ static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec) {
         struct pollfd p[2] = {};
         int r, e, n;
         struct timespec ts;
-        usec_t m = (usec_t) -1;
+        usec_t m = USEC_INFINITY;
 
         assert(bus);
 
         if (bus->state == BUS_CLOSING)
                 return 1;
 
-        assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
+        if (!BUS_IS_OPEN(bus->state))
+                return -ENOTCONN;
 
         e = sd_bus_get_events(bus);
         if (e < 0)
@@ -2564,7 +2730,8 @@ _public_ int sd_bus_wait(sd_bus *bus, uint64_t timeout_usec) {
         if (bus->state == BUS_CLOSING)
                 return 0;
 
-        assert_return(BUS_IS_OPEN(bus->state) , -ENOTCONN);
+        if (!BUS_IS_OPEN(bus->state))
+                return -ENOTCONN;
 
         if (bus->rqueue_size > 0)
                 return 0;
@@ -2581,7 +2748,8 @@ _public_ int sd_bus_flush(sd_bus *bus) {
         if (bus->state == BUS_CLOSING)
                 return 0;
 
-        assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
+        if (!BUS_IS_OPEN(bus->state))
+                return -ENOTCONN;
 
         r = bus_ensure_running(bus);
         if (r < 0)
@@ -2610,57 +2778,43 @@ _public_ int sd_bus_flush(sd_bus *bus) {
         }
 }
 
-_public_ int sd_bus_add_filter(sd_bus *bus,
-                               sd_bus_message_handler_t callback,
-                               void *userdata) {
+_public_ int sd_bus_add_filter(
+                sd_bus *bus,
+                sd_bus_slot **slot,
+                sd_bus_message_handler_t callback,
+                void *userdata) {
 
-        struct filter_callback *f;
+        sd_bus_slot *s;
 
         assert_return(bus, -EINVAL);
         assert_return(callback, -EINVAL);
         assert_return(!bus_pid_changed(bus), -ECHILD);
 
-        f = new0(struct filter_callback, 1);
-        if (!f)
+        s = bus_slot_allocate(bus, !slot, BUS_FILTER_CALLBACK, sizeof(struct filter_callback), userdata);
+        if (!s)
                 return -ENOMEM;
-        f->callback = callback;
-        f->userdata = userdata;
 
-        bus->filter_callbacks_modified = true;
-        LIST_PREPEND(callbacks, bus->filter_callbacks, f);
-        return 0;
-}
-
-_public_ int sd_bus_remove_filter(sd_bus *bus,
-                                  sd_bus_message_handler_t callback,
-                                  void *userdata) {
-
-        struct filter_callback *f;
+        s->filter_callback.callback = callback;
 
-        assert_return(bus, -EINVAL);
-        assert_return(callback, -EINVAL);
-        assert_return(!bus_pid_changed(bus), -ECHILD);
+        bus->filter_callbacks_modified = true;
+        LIST_PREPEND(callbacks, bus->filter_callbacks, &s->filter_callback);
 
-        LIST_FOREACH(callbacks, f, bus->filter_callbacks) {
-                if (f->callback == callback && f->userdata == userdata) {
-                        bus->filter_callbacks_modified = true;
-                        LIST_REMOVE(callbacks, bus->filter_callbacks, f);
-                        free(f);
-                        return 1;
-                }
-        }
+        if (slot)
+                *slot = s;
 
         return 0;
 }
 
-_public_ int sd_bus_add_match(sd_bus *bus,
-                              const char *match,
-                              sd_bus_message_handler_t callback,
-                              void *userdata) {
+_public_ int sd_bus_add_match(
+                sd_bus *bus,
+                sd_bus_slot **slot,
+                const char *match,
+                sd_bus_message_handler_t callback,
+                void *userdata) {
 
         struct bus_match_component *components = NULL;
         unsigned n_components = 0;
-        uint64_t cookie = 0;
+        sd_bus_slot *s = NULL;
         int r = 0;
 
         assert_return(bus, -EINVAL);
@@ -2671,35 +2825,60 @@ _public_ int sd_bus_add_match(sd_bus *bus,
         if (r < 0)
                 goto finish;
 
+        s = bus_slot_allocate(bus, !slot, BUS_MATCH_CALLBACK, sizeof(struct match_callback), userdata);
+        if (!s) {
+                r = -ENOMEM;
+                goto finish;
+        }
+
+        s->match_callback.callback = callback;
+        s->match_callback.cookie = ++bus->match_cookie;
+
         if (bus->bus_client) {
-                cookie = ++bus->match_cookie;
 
-                r = bus_add_match_internal(bus, match, components, n_components, cookie);
+                if (!bus->is_kernel) {
+                        /* When this is not a kernel transport, we
+                         * store the original match string, so that we
+                         * can use it to remove the match again */
+
+                        s->match_callback.match_string = strdup(match);
+                        if (!s->match_callback.match_string) {
+                                r = -ENOMEM;
+                                goto finish;
+                        }
+                }
+
+                r = bus_add_match_internal(bus, s->match_callback.match_string, components, n_components, s->match_callback.cookie);
                 if (r < 0)
                         goto finish;
         }
 
         bus->match_callbacks_modified = true;
-        r = bus_match_add(&bus->match_callbacks, components, n_components, callback, userdata, cookie, NULL);
-        if (r < 0) {
-                if (bus->bus_client)
-                        bus_remove_match_internal(bus, match, cookie);
-        }
+        r = bus_match_add(&bus->match_callbacks, components, n_components, &s->match_callback);
+        if (r < 0)
+                goto finish;
+
+        if (slot)
+                *slot = s;
+        s = NULL;
 
 finish:
         bus_match_parse_free(components, n_components);
+        sd_bus_slot_unref(s);
+
         return r;
 }
 
-_public_ int sd_bus_remove_match(sd_bus *bus,
-                                 const char *match,
-                                 sd_bus_message_handler_t callback,
-                                 void *userdata) {
+int bus_remove_match_by_string(
+                sd_bus *bus,
+                const char *match,
+                sd_bus_message_handler_t callback,
+                void *userdata) {
 
         struct bus_match_component *components = NULL;
         unsigned n_components = 0;
-        int r = 0, q = 0;
-        uint64_t cookie = 0;
+        struct match_callback *c;
+        int r = 0;
 
         assert_return(bus, -EINVAL);
         assert_return(match, -EINVAL);
@@ -2707,17 +2886,18 @@ _public_ int sd_bus_remove_match(sd_bus *bus,
 
         r = bus_match_parse(match, &components, &n_components);
         if (r < 0)
-                return r;
+                goto finish;
 
-        bus->match_callbacks_modified = true;
-        r = bus_match_remove(&bus->match_callbacks, components, n_components, callback, userdata, &cookie);
+        r = bus_match_find(&bus->match_callbacks, components, n_components, NULL, NULL, &c);
+        if (r <= 0)
+                goto finish;
 
-        if (bus->bus_client)
-                q = bus_remove_match_internal(bus, match, cookie);
+        sd_bus_slot_unref(container_of(c, sd_bus_slot, match_callback));
 
+finish:
         bus_match_parse_free(components, n_components);
 
-        return r < 0 ? r : q;
+        return r;
 }
 
 bool bus_pid_changed(sd_bus *bus) {
@@ -2806,6 +2986,7 @@ static int quit_callback(sd_event_source *event, void *userdata) {
         assert(event);
 
         sd_bus_flush(bus);
+        sd_bus_close(bus);
 
         return 1;
 }
@@ -2890,7 +3071,7 @@ _public_ int sd_bus_attach_event(sd_bus *bus, sd_event *event, int priority) {
 
         bus->event_priority = priority;
 
-        r = sd_event_add_monotonic(bus->event, &bus->time_event_source, 0, 0, time_callback, bus);
+        r = sd_event_add_time(bus->event, &bus->time_event_source, CLOCK_MONOTONIC, 0, 0, time_callback, bus);
         if (r < 0)
                 goto fail;
 
@@ -2931,9 +3112,7 @@ _public_ int sd_bus_detach_event(sd_bus *bus) {
                 bus->quit_event_source = sd_event_source_unref(bus->quit_event_source);
         }
 
-        if (bus->event)
-                bus->event = sd_event_unref(bus->event);
-
+        bus->event = sd_event_unref(bus->event);
         return 1;
 }
 
@@ -2943,10 +3122,28 @@ _public_ sd_event* sd_bus_get_event(sd_bus *bus) {
         return bus->event;
 }
 
-_public_ sd_bus_message* sd_bus_get_current(sd_bus *bus) {
+_public_ sd_bus_message* sd_bus_get_current_message(sd_bus *bus) {
+        assert_return(bus, NULL);
+
+        return bus->current_message;
+}
+
+_public_ sd_bus_slot* sd_bus_get_current_slot(sd_bus *bus) {
         assert_return(bus, NULL);
 
-        return bus->current;
+        return bus->current_slot;
+}
+
+_public_ sd_bus_message_handler_t sd_bus_get_current_handler(sd_bus *bus) {
+        assert_return(bus, NULL);
+
+        return bus->current_handler;
+}
+
+_public_ void* sd_bus_get_current_userdata(sd_bus *bus) {
+        assert_return(bus, NULL);
+
+        return bus->current_userdata;
 }
 
 static int bus_default(int (*bus_open)(sd_bus **), sd_bus **default_bus, sd_bus **ret) {
@@ -3002,7 +3199,7 @@ _public_ int sd_bus_default(sd_bus **ret) {
         if (e) {
                 if (streq(e, "system"))
                         return sd_bus_default_system(ret);
-                else if (streq(e, "user") || streq(e, "session"))
+                else if (STR_IN_SET(e, "user", "session"))
                         return sd_bus_default_user(ret);
         }
 
@@ -3041,12 +3238,46 @@ _public_ int sd_bus_get_tid(sd_bus *b, pid_t *tid) {
         return -ENXIO;
 }
 
-_public_ char *sd_bus_label_escape(const char *s) {
-        return bus_label_escape(s);
+_public_ int sd_bus_path_encode(const char *prefix, const char *external_id, char **ret_path) {
+        _cleanup_free_ char *e = NULL;
+        char *ret;
+
+        assert_return(object_path_is_valid(prefix), -EINVAL);
+        assert_return(external_id, -EINVAL);
+        assert_return(ret_path, -EINVAL);
+
+        e = bus_label_escape(external_id);
+        if (!e)
+                return -ENOMEM;
+
+        ret = strjoin(prefix, "/", e, NULL);
+        if (!ret)
+                return -ENOMEM;
+
+        *ret_path = ret;
+        return 0;
 }
 
-_public_ char *sd_bus_label_unescape(const char *f) {
-        return bus_label_unescape(f);
+_public_ int sd_bus_path_decode(const char *path, const char *prefix, char **external_id) {
+        const char *e;
+        char *ret;
+
+        assert_return(object_path_is_valid(path), -EINVAL);
+        assert_return(object_path_is_valid(prefix), -EINVAL);
+        assert_return(external_id, -EINVAL);
+
+        e = object_path_startswith(path, prefix);
+        if (!e) {
+                *external_id = NULL;
+                return 0;
+        }
+
+        ret = bus_label_unescape(e);
+        if (!ret)
+                return -ENOMEM;
+
+        *external_id = ret;
+        return 1;
 }
 
 _public_ int sd_bus_get_peer_creds(sd_bus *bus, uint64_t mask, sd_bus_creds **ret) {
@@ -3057,9 +3288,13 @@ _public_ int sd_bus_get_peer_creds(sd_bus *bus, uint64_t mask, sd_bus_creds **re
         assert_return(bus, -EINVAL);
         assert_return(mask <= _SD_BUS_CREDS_ALL, -ENOTSUP);
         assert_return(ret, -EINVAL);
-        assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
         assert_return(!bus_pid_changed(bus), -ECHILD);
-        assert_return(!bus->is_kernel, -ENOTSUP);
+
+        if (bus->is_kernel)
+                return -ENOTSUP;
+
+        if (!BUS_IS_OPEN(bus->state))
+                return -ENOTCONN;
 
         if (!bus->ucred_valid && !isempty(bus->label))
                 return -ENODATA;
@@ -3098,9 +3333,13 @@ _public_ int sd_bus_try_close(sd_bus *bus) {
         int r;
 
         assert_return(bus, -EINVAL);
-        assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
         assert_return(!bus_pid_changed(bus), -ECHILD);
-        assert_return(bus->is_kernel, -ENOTSUP);
+
+        if (!bus->is_kernel)
+                return -ENOTSUP;
+
+        if (!BUS_IS_OPEN(bus->state))
+                return -ENOTCONN;
 
         if (bus->rqueue_size > 0)
                 return -EBUSY;
@@ -3124,3 +3363,21 @@ _public_ int sd_bus_get_name(sd_bus *bus, const char **name) {
         *name = bus->connection_name;
         return 0;
 }
+
+int bus_get_root_path(sd_bus *bus) {
+        int r;
+
+        if (bus->cgroup_root)
+                return 0;
+
+        r = cg_get_root_path(&bus->cgroup_root);
+        if (r == -ENOENT) {
+                bus->cgroup_root = strdup("/");
+                if (!bus->cgroup_root)
+                        return -ENOMEM;
+
+                r = 0;
+        }
+
+        return r;
+}
index 7c71476..fcf3e73 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "util.h"
 #include "kdbus.h"
+#include "bus-label.h"
 
 #include "sd-memfd.h"
 #include "sd-bus.h"
@@ -56,7 +57,7 @@ _public_ int sd_memfd_new(sd_memfd **m, const char *name) {
                  * set here, let's do the usual bus escaping to deal
                  * with that. */
 
-                g = sd_bus_label_escape(name);
+                g = bus_label_escape(name);
                 if (!g)
                         return -ENOMEM;
 
@@ -76,7 +77,7 @@ _public_ int sd_memfd_new(sd_memfd **m, const char *name) {
                 else {
                         _cleanup_free_ char *e = NULL;
 
-                        e = sd_bus_label_escape(pr);
+                        e = bus_label_escape(pr);
                         if (!e)
                                 return -ENOMEM;
 
@@ -106,7 +107,7 @@ _public_ int sd_memfd_new(sd_memfd **m, const char *name) {
 
         n = new0(struct sd_memfd, 1);
         if (!n) {
-                close_nointr_nofail(cmd->fd);
+                safe_close(cmd->fd);
                 return -ENOMEM;
         }
 
@@ -143,7 +144,7 @@ _public_ void sd_memfd_free(sd_memfd *m) {
         if (m->f)
                 fclose(m->f);
         else
-                close_nointr_nofail(m->fd);
+                safe_close(m->fd);
 
         free(m);
 }
@@ -311,7 +312,7 @@ _public_ int sd_memfd_get_name(sd_memfd *m, char **name) {
         if (!n)
                 return -ENOMEM;
 
-        e = sd_bus_label_unescape(n);
+        e = bus_label_unescape(n);
         if (!e)
                 return -ENOMEM;
 
index 113d15b..d5903f4 100644 (file)
@@ -100,19 +100,19 @@ static int server_init(sd_bus **_bus) {
                 goto fail;
         }
 
-        r = sd_bus_add_fallback(bus, "/foo/bar", object_callback, NULL);
+        r = sd_bus_add_fallback(bus, NULL, "/foo/bar", object_callback, NULL);
         if (r < 0) {
                 log_error("Failed to add object: %s", strerror(-r));
                 goto fail;
         }
 
-        r = sd_bus_add_match(bus, "type='signal',interface='foo.bar',member='Notify'", match_callback, NULL);
+        r = sd_bus_add_match(bus, NULL, "type='signal',interface='foo.bar',member='Notify'", match_callback, NULL);
         if (r < 0) {
                 log_error("Failed to add match: %s", strerror(-r));
                 goto fail;
         }
 
-        r = sd_bus_add_match(bus, "type='signal',interface='org.freedesktop.DBus',member='NameOwnerChanged'", match_callback, NULL);
+        r = sd_bus_add_match(bus, NULL, "type='signal',interface='org.freedesktop.DBus',member='NameOwnerChanged'", match_callback, NULL);
         if (r < 0) {
                 log_error("Failed to add match: %s", strerror(-r));
                 goto fail;
@@ -160,9 +160,9 @@ static int server(sd_bus *bus) {
 
                 sd_bus_creds_get_pid(sd_bus_message_get_creds(m), &pid);
                 sd_bus_creds_get_selinux_context(sd_bus_message_get_creds(m), &label);
-                log_info("Got message! member=%s pid=%lu label=%s",
+                log_info("Got message! member=%s pid="PID_FMT" label=%s",
                          strna(sd_bus_message_get_member(m)),
-                         (unsigned long) pid,
+                         pid,
                          strna(label));
                 /* bus_message_dump(m); */
                 /* sd_bus_message_rewind(m, true); */
@@ -232,7 +232,7 @@ static int server(sd_bus *bus) {
 
                         if (write(fd, &x, 1) < 0) {
                                 log_error("Failed to write to fd: %m");
-                                close_nointr_nofail(fd);
+                                safe_close(fd);
                                 goto fail;
                         }
 
@@ -356,7 +356,7 @@ finish:
 
         sd_bus_error_free(&error);
 
-        close_pipe(pp);
+        safe_close_pair(pp);
 
         return INT_TO_PTR(r);
 }
@@ -490,7 +490,7 @@ static void* client2(void*p) {
                 goto finish;
         }
 
-        r = sd_bus_call_async(bus, m, quit_callback, &quit, 200 * USEC_PER_MSEC, NULL);
+        r = sd_bus_call_async(bus, NULL, m, quit_callback, &quit, 200 * USEC_PER_MSEC);
         if (r < 0) {
                 log_info("Failed to issue method call: %s", bus_error_message(&error, -r));
                 goto finish;
index f2c1fc1..9226858 100644 (file)
@@ -134,8 +134,12 @@ static void test_marshal(void) {
         _cleanup_bus_unref_ sd_bus *bus = NULL;
         _cleanup_free_ void *blob;
         size_t sz;
+        int r;
+
+        r = sd_bus_open_system(&bus);
+        if (r < 0)
+                exit(EXIT_TEST_SKIP);
 
-        assert_se(sd_bus_open_system(&bus) >= 0);
         bus->message_version = 2; /* dirty hack to enable gvariant*/
 
         assert_se(sd_bus_message_new_method_call(bus, &m, "a.service.name", "/an/object/path/which/is/really/really/long/so/that/we/hit/the/eight/bit/boundary/by/quite/some/margin/to/test/this/stuff/that/it/really/works", "an.interface.name", "AMethodName") >= 0);
@@ -175,7 +179,7 @@ static void test_marshal(void) {
 
         assert_se(bus_message_get_blob(m, &blob, &sz) >= 0);
 
-        assert_se(bus_message_from_malloc(NULL, blob, sz, NULL, 0, NULL, NULL, &n) >= 0);
+        assert_se(bus_message_from_malloc(bus, blob, sz, NULL, 0, NULL, NULL, &n) >= 0);
         blob = NULL;
 
         assert_se(bus_message_dump(n, NULL, true) >= 0);
index bfeee59..cd88e67 100644 (file)
@@ -47,7 +47,7 @@ static void server(sd_bus *b, size_t *result) {
                 assert_se(r >= 0);
 
                 if (r == 0)
-                        assert_se(sd_bus_wait(b, (usec_t) -1) >= 0);
+                        assert_se(sd_bus_wait(b, USEC_INFINITY) >= 0);
                 if (!m)
                         continue;
 
@@ -270,7 +270,7 @@ int main(int argc, char *argv[]) {
                 CPU_SET(0, &cpuset);
                 pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
 
-                close_nointr_nofail(bus_ref);
+                safe_close(bus_ref);
                 sd_bus_unref(b);
 
                 switch (mode) {
index 0ecad18..5ee6eea 100644 (file)
@@ -72,7 +72,7 @@ static void test_one(
         assert_se(r >= 0);
 
         log_debug("match");
-        r = sd_bus_add_match(b, match, NULL, NULL);
+        r = sd_bus_add_match(b, NULL, match, NULL, NULL);
         assert_se(r >= 0);
 
         log_debug("signal");
index 2f0f5aa..7bb8b0a 100644 (file)
@@ -101,7 +101,7 @@ int main(int argc, char *argv[]) {
         assert_se(sd_bus_error_has_name(&error, SD_BUS_ERROR_SERVICE_UNKNOWN));
         assert_se(r == -EHOSTUNREACH);
 
-        r = sd_bus_add_match(b, "interface='waldo.com',member='Piep'", NULL, NULL);
+        r = sd_bus_add_match(b, NULL, "interface='waldo.com',member='Piep'", NULL, NULL);
         assert_se(r >= 0);
 
         r = sd_bus_emit_signal(a, "/foo/bar/waldo", "waldo.com", "Piep", "sss", "I am a string", "/this/is/a/path", "and.this.a.domain.name");
@@ -137,14 +137,12 @@ int main(int argc, char *argv[]) {
 
         assert_se(write(pipe_fds[1], "x", 1) == 1);
 
-        close_nointr_nofail(pipe_fds[1]);
-        pipe_fds[1] = -1;
+        pipe_fds[1] = safe_close(pipe_fds[1]);
 
         r = sd_bus_message_append(m, "h", pipe_fds[0]);
         assert_se(r >= 0);
 
-        close_nointr_nofail(pipe_fds[0]);
-        pipe_fds[0] = -1;
+        pipe_fds[0] = safe_close(pipe_fds[0]);
 
         r = sd_bus_send(b, m, NULL);
         assert_se(r >= 0);
index 85aaf95..9532112 100644 (file)
 #include "bus-message.h"
 #include "bus-util.h"
 #include "bus-dump.h"
+#include "bus-label.h"
+
+static void test_bus_path_encode(void) {
+        _cleanup_free_ char *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL, *f = NULL;
+
+        assert_se(sd_bus_path_encode("/foo/bar", "waldo", &a) >= 0 && streq(a, "/foo/bar/waldo"));
+        assert_se(sd_bus_path_decode(a, "/waldo", &b) == 0 && b == NULL);
+        assert_se(sd_bus_path_decode(a, "/foo/bar", &b) > 0 && streq(b, "waldo"));
+
+        assert_se(sd_bus_path_encode("xxxx", "waldo", &c) < 0);
+        assert_se(sd_bus_path_encode("/foo/", "waldo", &c) < 0);
+
+        assert_se(sd_bus_path_encode("/foo/bar", "", &c) >= 0 && streq(c, "/foo/bar/_"));
+        assert_se(sd_bus_path_decode(c, "/foo/bar", &d) > 0 && streq(d, ""));
+
+        assert_se(sd_bus_path_encode("/foo/bar", "foo.bar", &e) >= 0 && streq(e, "/foo/bar/foo_2ebar"));
+        assert_se(sd_bus_path_decode(e, "/foo/bar", &f) > 0 && streq(f, "foo.bar"));
+}
 
 static void test_bus_label_escape_one(const char *a, const char *b) {
         _cleanup_free_ char *t = NULL, *x = NULL, *y = NULL;
 
-        assert_se(t = sd_bus_label_escape(a));
+        assert_se(t = bus_label_escape(a));
         assert_se(streq(t, b));
 
-        assert_se(x = sd_bus_label_unescape(t));
+        assert_se(x = bus_label_unescape(t));
         assert_se(streq(a, x));
 
-        assert_se(y = sd_bus_label_unescape(b));
+        assert_se(y = bus_label_unescape(b));
         assert_se(streq(a, y));
 }
 
@@ -75,8 +93,16 @@ int main(int argc, char *argv[]) {
         _cleanup_free_ char *first = NULL, *second = NULL, *third = NULL;
         _cleanup_fclose_ FILE *ms = NULL;
         size_t first_size = 0, second_size = 0, third_size = 0;
+        _cleanup_bus_unref_ sd_bus *bus = NULL;
+
+        r = sd_bus_default_system(&bus);
+        if (r < 0)
+                return EXIT_TEST_SKIP;
+
+        r = sd_bus_message_new_method_call(bus, &m, "foobar.waldo", "/", "foobar.waldo", "Piep");
+        assert_se(r >= 0);
 
-        r = sd_bus_message_new_method_call(NULL, &m, "foobar.waldo", "/", "foobar.waldo", "Piep");
+        r = sd_bus_message_append(m, "");
         assert_se(r >= 0);
 
         r = sd_bus_message_append(m, "s", "a string");
@@ -135,7 +161,7 @@ int main(int argc, char *argv[]) {
         h = hexmem(buffer, sz);
         assert_se(h);
 
-        log_info("message size = %lu, contents =\n%s", (unsigned long) sz, h);
+        log_info("message size = %zu, contents =\n%s", sz, h);
         free(h);
 
 #ifdef HAVE_GLIB
@@ -172,7 +198,7 @@ int main(int argc, char *argv[]) {
 
         m = sd_bus_message_unref(m);
 
-        r = bus_message_from_malloc(NULL, buffer, sz, NULL, 0, NULL, NULL, &m);
+        r = bus_message_from_malloc(bus, buffer, sz, NULL, 0, NULL, NULL, &m);
         assert_se(r >= 0);
 
         bus_message_dump(m, stdout, true);
@@ -245,7 +271,7 @@ int main(int argc, char *argv[]) {
         r = sd_bus_message_peek_type(m, NULL, NULL);
         assert_se(r == 0);
 
-        r = sd_bus_message_new_method_call(NULL, &copy, "foobar.waldo", "/", "foobar.waldo", "Piep");
+        r = sd_bus_message_new_method_call(bus, &copy, "foobar.waldo", "/", "foobar.waldo", "Piep");
         assert_se(r >= 0);
 
         r = sd_bus_message_rewind(m, true);
@@ -319,6 +345,7 @@ int main(int argc, char *argv[]) {
         assert_se(streq(d, "3"));
 
         test_bus_label_escape();
+        test_bus_path_encode();
 
         return 0;
 }
index c561be2..6c5d35b 100644 (file)
@@ -28,6 +28,7 @@
 #include "bus-match.h"
 #include "bus-message.h"
 #include "bus-util.h"
+#include "bus-slot.h"
 
 static bool mask[32];
 
@@ -56,62 +57,61 @@ static bool mask_contains(unsigned a[], unsigned n) {
         return true;
 }
 
-static int match_add(struct bus_match_node *root, const char *match, int value) {
+static int match_add(sd_bus_slot *slots, struct bus_match_node *root, const char *match, int value) {
         struct bus_match_component *components = NULL;
         unsigned n_components = 0;
+        sd_bus_slot *s;
         int r;
 
-        r = bus_match_parse(match, &components, &n_components);
-        if (r < 0)
-                return r;
-
-        r = bus_match_add(root, components, n_components, filter, INT_TO_PTR(value), 0, NULL);
-        bus_match_parse_free(components, n_components);
-
-        return r;
-}
-
-static int match_remove(struct bus_match_node *root, const char *match, int value) {
-        struct bus_match_component *components = NULL;
-        unsigned n_components = 0;
-        int r;
+        s = slots + value;
+        zero(*s);
 
         r = bus_match_parse(match, &components, &n_components);
         if (r < 0)
                 return r;
 
-        r = bus_match_remove(root, components, n_components, filter, INT_TO_PTR(value), 0);
+        s->userdata = INT_TO_PTR(value);
+        s->match_callback.callback = filter;
+
+        r = bus_match_add(root, components, n_components, &s->match_callback);
         bus_match_parse_free(components, n_components);
 
         return r;
 }
 
 int main(int argc, char *argv[]) {
-        struct bus_match_node root;
+        struct bus_match_node root = {
+                .type = BUS_MATCH_ROOT,
+        };
+
         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
+        _cleanup_bus_unref_ sd_bus *bus = NULL;
         enum bus_match_node_type i;
+        sd_bus_slot slots[15];
+        int r;
 
-        zero(root);
-        root.type = BUS_MATCH_ROOT;
-
-        assert_se(match_add(&root, "arg2='wal\\'do',sender='foo',type='signal',interface='bar.x',", 1) >= 0);
-        assert_se(match_add(&root, "arg2='wal\\'do2',sender='foo',type='signal',interface='bar.x',", 2) >= 0);
-        assert_se(match_add(&root, "arg3='test',sender='foo',type='signal',interface='bar.x',", 3) >= 0);
-        assert_se(match_add(&root, "arg3='test',sender='foo',type='method_call',interface='bar.x',", 4) >= 0);
-        assert_se(match_add(&root, "", 5) >= 0);
-        assert_se(match_add(&root, "interface='quux.x'", 6) >= 0);
-        assert_se(match_add(&root, "interface='bar.x'", 7) >= 0);
-        assert_se(match_add(&root, "member='waldo',path='/foo/bar'", 8) >= 0);
-        assert_se(match_add(&root, "path='/foo/bar'", 9) >= 0);
-        assert_se(match_add(&root, "path_namespace='/foo'", 10) >= 0);
-        assert_se(match_add(&root, "path_namespace='/foo/quux'", 11) >= 0);
-        assert_se(match_add(&root, "arg1='two'", 12) >= 0);
-        assert_se(match_add(&root, "member='waldo',arg2path='/prefix/'", 13) >= 0);
-        assert_se(match_add(&root, "member=waldo,path='/foo/bar',arg3namespace='prefix'", 14) >= 0);
+        r = sd_bus_open_system(&bus);
+        if (r < 0)
+                return EXIT_TEST_SKIP;
+
+        assert_se(match_add(slots, &root, "arg2='wal\\'do',sender='foo',type='signal',interface='bar.x',", 1) >= 0);
+        assert_se(match_add(slots, &root, "arg2='wal\\'do2',sender='foo',type='signal',interface='bar.x',", 2) >= 0);
+        assert_se(match_add(slots, &root, "arg3='test',sender='foo',type='signal',interface='bar.x',", 3) >= 0);
+        assert_se(match_add(slots, &root, "arg3='test',sender='foo',type='method_call',interface='bar.x',", 4) >= 0);
+        assert_se(match_add(slots, &root, "", 5) >= 0);
+        assert_se(match_add(slots, &root, "interface='quux.x'", 6) >= 0);
+        assert_se(match_add(slots, &root, "interface='bar.x'", 7) >= 0);
+        assert_se(match_add(slots, &root, "member='waldo',path='/foo/bar'", 8) >= 0);
+        assert_se(match_add(slots, &root, "path='/foo/bar'", 9) >= 0);
+        assert_se(match_add(slots, &root, "path_namespace='/foo'", 10) >= 0);
+        assert_se(match_add(slots, &root, "path_namespace='/foo/quux'", 11) >= 0);
+        assert_se(match_add(slots, &root, "arg1='two'", 12) >= 0);
+        assert_se(match_add(slots, &root, "member='waldo',arg2path='/prefix/'", 13) >= 0);
+        assert_se(match_add(slots, &root, "member=waldo,path='/foo/bar',arg3namespace='prefix'", 14) >= 0);
 
         bus_match_dump(&root, 0);
 
-        assert_se(sd_bus_message_new_signal(NULL, &m, "/foo/bar", "bar.x", "waldo") >= 0);
+        assert_se(sd_bus_message_new_signal(bus, &m, "/foo/bar", "bar.x", "waldo") >= 0);
         assert_se(sd_bus_message_append(m, "ssss", "one", "two", "/prefix/three", "prefix.four") >= 0);
         assert_se(bus_message_seal(m, 1, 0) >= 0);
 
@@ -119,9 +119,8 @@ int main(int argc, char *argv[]) {
         assert_se(bus_match_run(NULL, &root, m) == 0);
         assert_se(mask_contains((unsigned[]) { 9, 8, 7, 5, 10, 12, 13, 14 }, 8));
 
-        assert_se(match_remove(&root, "member='waldo',path='/foo/bar'", 8) > 0);
-        assert_se(match_remove(&root, "arg2path='/prefix/',member='waldo'", 13) > 0);
-        assert_se(match_remove(&root, "interface='bar.xx'", 7) == 0);
+        assert_se(bus_match_remove(&root, &slots[8].match_callback) >= 0);
+        assert_se(bus_match_remove(&root, &slots[13].match_callback) >= 0);
 
         bus_match_dump(&root, 0);
 
index e2423c7..e7a445f 100644 (file)
@@ -200,7 +200,7 @@ static const sd_bus_vtable vtable2[] = {
         SD_BUS_VTABLE_END
 };
 
-static int enumerator_callback(sd_bus *b, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
+static int enumerator_callback(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
 
         if (object_path_startswith("/value", path))
                 assert_se(*nodes = strv_new("/value/a", "/value/b", "/value/c", NULL));
@@ -222,11 +222,11 @@ static void *server(void *p) {
         assert_se(sd_bus_set_fd(bus, c->fds[0], c->fds[0]) >= 0);
         assert_se(sd_bus_set_server(bus, 1, id) >= 0);
 
-        assert_se(sd_bus_add_object_vtable(bus, "/foo", "org.freedesktop.systemd.test", vtable, c) >= 0);
-        assert_se(sd_bus_add_object_vtable(bus, "/foo", "org.freedesktop.systemd.test2", vtable, c) >= 0);
-        assert_se(sd_bus_add_fallback_vtable(bus, "/value", "org.freedesktop.systemd.ValueTest", vtable2, NULL, UINT_TO_PTR(20)) >= 0);
-        assert_se(sd_bus_add_node_enumerator(bus, "/value", enumerator_callback, NULL) >= 0);
-        assert_se(sd_bus_add_object_manager(bus, "/value") >= 0);
+        assert_se(sd_bus_add_object_vtable(bus, NULL, "/foo", "org.freedesktop.systemd.test", vtable, c) >= 0);
+        assert_se(sd_bus_add_object_vtable(bus, NULL, "/foo", "org.freedesktop.systemd.test2", vtable, c) >= 0);
+        assert_se(sd_bus_add_fallback_vtable(bus, NULL, "/value", "org.freedesktop.systemd.ValueTest", vtable2, NULL, UINT_TO_PTR(20)) >= 0);
+        assert_se(sd_bus_add_node_enumerator(bus, NULL, "/value", enumerator_callback, NULL) >= 0);
+        assert_se(sd_bus_add_object_manager(bus, NULL, "/value") >= 0);
 
         assert_se(sd_bus_start(bus) >= 0);
 
diff --git a/src/libsystemd/sd-daemon/Makefile b/src/libsystemd/sd-daemon/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
index 21fb346..46241f7 100644 (file)
 #include <mqueue.h>
 
 #include "util.h"
+#include "path-util.h"
+#include "socket-util.h"
 #include "sd-daemon.h"
 
 _public_ int sd_listen_fds(int unset_environment) {
-        int r, fd;
         const char *e;
-        char *p = NULL;
-        unsigned long l;
+        unsigned n;
+        int r, fd;
+        pid_t pid;
 
         e = getenv("LISTEN_PID");
         if (!e) {
@@ -50,21 +52,12 @@ _public_ int sd_listen_fds(int unset_environment) {
                 goto finish;
         }
 
-        errno = 0;
-        l = strtoul(e, &p, 10);
-
-        if (errno > 0) {
-                r = -errno;
+        r = parse_pid(e, &pid);
+        if (r < 0)
                 goto finish;
-        }
-
-        if (!p || p == e || *p || l <= 0) {
-                r = -EINVAL;
-                goto finish;
-        }
 
         /* Is this for us? */
-        if (getpid() != (pid_t) l) {
+        if (getpid() != pid) {
                 r = 0;
                 goto finish;
         }
@@ -75,38 +68,17 @@ _public_ int sd_listen_fds(int unset_environment) {
                 goto finish;
         }
 
-        errno = 0;
-        l = strtoul(e, &p, 10);
-
-        if (errno > 0) {
-                r = -errno;
-                goto finish;
-        }
-
-        if (!p || p == e || *p) {
-                r = -EINVAL;
+        r = safe_atou(e, &n);
+        if (r < 0)
                 goto finish;
-        }
-
-        for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + (int) l; fd ++) {
-                int flags;
 
-                flags = fcntl(fd, F_GETFD);
-                if (flags < 0) {
-                        r = -errno;
+        for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + (int) n; fd ++) {
+                r = fd_cloexec(fd, true);
+                if (r < 0)
                         goto finish;
-                }
-
-                if (flags & FD_CLOEXEC)
-                        continue;
-
-                if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0) {
-                        r = -errno;
-                        goto finish;
-                }
         }
 
-        r = (int) l;
+        r = (int) n;
 
 finish:
         if (unset_environment) {
@@ -120,8 +92,7 @@ finish:
 _public_ int sd_is_fifo(int fd, const char *path) {
         struct stat st_fd;
 
-        if (fd < 0)
-                return -EINVAL;
+        assert_return(fd >= 0, -EINVAL);
 
         if (fstat(fd, &st_fd) < 0)
                 return -errno;
@@ -151,8 +122,7 @@ _public_ int sd_is_fifo(int fd, const char *path) {
 _public_ int sd_is_special(int fd, const char *path) {
         struct stat st_fd;
 
-        if (fd < 0)
-                return -EINVAL;
+        assert_return(fd >= 0, -EINVAL);
 
         if (fstat(fd, &st_fd) < 0)
                 return -errno;
@@ -187,8 +157,8 @@ _public_ int sd_is_special(int fd, const char *path) {
 static int sd_is_socket_internal(int fd, int type, int listening) {
         struct stat st_fd;
 
-        if (fd < 0 || type < 0)
-                return -EINVAL;
+        assert_return(fd >= 0, -EINVAL);
+        assert_return(type >= 0, -EINVAL);
 
         if (fstat(fd, &st_fd) < 0)
                 return -errno;
@@ -227,19 +197,11 @@ static int sd_is_socket_internal(int fd, int type, int listening) {
         return 1;
 }
 
-union sockaddr_union {
-        struct sockaddr sa;
-        struct sockaddr_in in4;
-        struct sockaddr_in6 in6;
-        struct sockaddr_un un;
-        struct sockaddr_storage storage;
-};
-
 _public_ int sd_is_socket(int fd, int family, int type, int listening) {
         int r;
 
-        if (family < 0)
-                return -EINVAL;
+        assert_return(fd >= 0, -EINVAL);
+        assert_return(family >= 0, -EINVAL);
 
         r = sd_is_socket_internal(fd, type, listening);
         if (r <= 0)
@@ -266,8 +228,8 @@ _public_ int sd_is_socket_inet(int fd, int family, int type, int listening, uint
         socklen_t l = sizeof(sockaddr);
         int r;
 
-        if (family != 0 && family != AF_INET && family != AF_INET6)
-                return -EINVAL;
+        assert_return(fd >= 0, -EINVAL);
+        assert_return(IN_SET(family, 0, AF_INET, AF_INET6), -EINVAL);
 
         r = sd_is_socket_internal(fd, type, listening);
         if (r <= 0)
@@ -283,7 +245,7 @@ _public_ int sd_is_socket_inet(int fd, int family, int type, int listening, uint
             sockaddr.sa.sa_family != AF_INET6)
                 return 0;
 
-        if (family > 0)
+        if (family != 0)
                 if (sockaddr.sa.sa_family != family)
                         return 0;
 
@@ -292,7 +254,7 @@ _public_ int sd_is_socket_inet(int fd, int family, int type, int listening, uint
                         if (l < sizeof(struct sockaddr_in))
                                 return -EINVAL;
 
-                        return htons(port) == sockaddr.in4.sin_port;
+                        return htons(port) == sockaddr.in.sin_port;
                 } else {
                         if (l < sizeof(struct sockaddr_in6))
                                 return -EINVAL;
@@ -309,6 +271,8 @@ _public_ int sd_is_socket_unix(int fd, int type, int listening, const char *path
         socklen_t l = sizeof(sockaddr);
         int r;
 
+        assert_return(fd >= 0, -EINVAL);
+
         r = sd_is_socket_internal(fd, type, listening);
         if (r <= 0)
                 return r;
@@ -348,8 +312,7 @@ _public_ int sd_is_socket_unix(int fd, int type, int listening, const char *path
 _public_ int sd_is_mq(int fd, const char *path) {
         struct mq_attr attr;
 
-        if (fd < 0)
-                return -EINVAL;
+        assert_return(fd >= 0, -EINVAL);
 
         if (mq_getattr(fd, &attr) < 0)
                 return -errno;
@@ -358,8 +321,7 @@ _public_ int sd_is_mq(int fd, const char *path) {
                 char fpath[PATH_MAX];
                 struct stat a, b;
 
-                if (path[0] != '/')
-                        return -EINVAL;
+                assert_return(path_is_absolute(path), -EINVAL);
 
                 if (fstat(fd, &a) < 0)
                         return -errno;
@@ -378,12 +340,17 @@ _public_ int sd_is_mq(int fd, const char *path) {
         return 1;
 }
 
-_public_ int sd_notify(int unset_environment, const char *state) {
-        int fd = -1, r;
-        struct msghdr msghdr;
-        struct iovec iovec;
-        union sockaddr_union sockaddr;
+_public_ int sd_pid_notify(pid_t pid, int unset_environment, const char *state) {
+        union sockaddr_union sockaddr = {};
+        _cleanup_close_ int fd = -1;
+        struct msghdr msghdr = {};
+        struct iovec iovec = {};
         const char *e;
+        union {
+                struct cmsghdr cmsghdr;
+                uint8_t buf[CMSG_SPACE(sizeof(struct ucred))];
+        } control = {};
+        int r;
 
         if (!state) {
                 r = -EINVAL;
@@ -406,18 +373,15 @@ _public_ int sd_notify(int unset_environment, const char *state) {
                 goto finish;
         }
 
-        memzero(&sockaddr, sizeof(sockaddr));
         sockaddr.sa.sa_family = AF_UNIX;
         strncpy(sockaddr.un.sun_path, e, sizeof(sockaddr.un.sun_path));
 
         if (sockaddr.un.sun_path[0] == '@')
                 sockaddr.un.sun_path[0] = 0;
 
-        memzero(&iovec, sizeof(iovec));
         iovec.iov_base = (char*) state;
         iovec.iov_len = strlen(state);
 
-        memzero(&msghdr, sizeof(msghdr));
         msghdr.msg_name = &sockaddr;
         msghdr.msg_namelen = offsetof(struct sockaddr_un, sun_path) + strlen(e);
 
@@ -427,39 +391,90 @@ _public_ int sd_notify(int unset_environment, const char *state) {
         msghdr.msg_iov = &iovec;
         msghdr.msg_iovlen = 1;
 
-        if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0) {
-                r = -errno;
+        if (pid != 0 && pid != getpid()) {
+                struct cmsghdr *cmsg;
+                struct ucred ucred = {};
+
+                msghdr.msg_control = &control;
+                msghdr.msg_controllen = sizeof(control);
+
+                cmsg = CMSG_FIRSTHDR(&msghdr);
+                cmsg->cmsg_level = SOL_SOCKET;
+                cmsg->cmsg_type = SCM_CREDENTIALS;
+                cmsg->cmsg_len = CMSG_LEN(sizeof(struct ucred));
+
+                ucred.pid = pid;
+                ucred.uid = getuid();
+                ucred.gid = getgid();
+
+                memcpy(CMSG_DATA(cmsg), &ucred, sizeof(struct ucred));
+                msghdr.msg_controllen = cmsg->cmsg_len;
+        }
+
+        /* First try with fake ucred data, as requested */
+        if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) >= 0) {
+                r = 1;
                 goto finish;
         }
 
-        r = 1;
+        /* If that failed, try with our own instead */
+        if (msghdr.msg_control) {
+                msghdr.msg_control = NULL;
+                msghdr.msg_controllen = 0;
+
+                if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) >= 0) {
+                        r = 1;
+                        goto finish;
+                }
+        }
+
+        r = -errno;
 
 finish:
         if (unset_environment)
                 unsetenv("NOTIFY_SOCKET");
 
-        if (fd >= 0)
-                close(fd);
-
         return r;
 }
 
+_public_ int sd_notify(int unset_environment, const char *state) {
+        return sd_pid_notify(0, unset_environment, state);
+}
+
+_public_ int sd_pid_notifyf(pid_t pid, int unset_environment, const char *format, ...) {
+        _cleanup_free_ char *p = NULL;
+        int r;
+
+        if (format) {
+                va_list ap;
+
+                va_start(ap, format);
+                r = vasprintf(&p, format, ap);
+                va_end(ap);
+
+                if (r < 0 || !p)
+                        return -ENOMEM;
+        }
+
+        return sd_pid_notify(pid, unset_environment, p);
+}
+
 _public_ int sd_notifyf(int unset_environment, const char *format, ...) {
-        va_list ap;
-        char *p = NULL;
+        _cleanup_free_ char *p = NULL;
         int r;
 
-        va_start(ap, format);
-        r = vasprintf(&p, format, ap);
-        va_end(ap);
+        if (format) {
+                va_list ap;
 
-        if (r < 0 || !p)
-                return -ENOMEM;
+                va_start(ap, format);
+                r = vasprintf(&p, format, ap);
+                va_end(ap);
 
-        r = sd_notify(unset_environment, p);
-        free(p);
+                if (r < 0 || !p)
+                        return -ENOMEM;
+        }
 
-        return r;
+        return sd_pid_notify(0, unset_environment, p);
 }
 
 _public_ int sd_booted(void) {
@@ -476,10 +491,9 @@ _public_ int sd_booted(void) {
 }
 
 _public_ int sd_watchdog_enabled(int unset_environment, uint64_t *usec) {
-        unsigned long long ll;
-        unsigned long l;
         const char *e;
-        char *p = NULL;
+        uint64_t u;
+        pid_t pid;
         int r;
 
         e = getenv("WATCHDOG_PID");
@@ -488,19 +502,12 @@ _public_ int sd_watchdog_enabled(int unset_environment, uint64_t *usec) {
                 goto finish;
         }
 
-        errno = 0;
-        l = strtoul(e, &p, 10);
-        if (errno > 0) {
-                r = -errno;
-                goto finish;
-        }
-        if (!p || p == e || *p || l <= 0) {
-                r = -EINVAL;
+        r = parse_pid(e, &pid);
+        if (r < 0)
                 goto finish;
-        }
 
         /* Is this for us? */
-        if (getpid() != (pid_t) l) {
+        if (getpid() != pid) {
                 r = 0;
                 goto finish;
         }
@@ -511,19 +518,16 @@ _public_ int sd_watchdog_enabled(int unset_environment, uint64_t *usec) {
                 goto finish;
         }
 
-        errno = 0;
-        ll = strtoull(e, &p, 10);
-        if (errno > 0) {
-                r = -errno;
+        r = safe_atou64(e, &u);
+        if (r < 0)
                 goto finish;
-        }
-        if (!p || p == e || *p || l <= 0) {
+        if (u <= 0) {
                 r = -EINVAL;
                 goto finish;
         }
 
         if (usec)
-                *usec = ll;
+                *usec = u;
 
         r = 1;
 
index e58020d..e7cad9b 100644 (file)
@@ -22,6 +22,7 @@
 ***/
 
 #include "util.h"
+#include "sd-event.h"
 
 DEFINE_TRIVIAL_CLEANUP_FUNC(sd_event*, sd_event_unref);
 DEFINE_TRIVIAL_CLEANUP_FUNC(sd_event_source*, sd_event_source_unref);
index 253923d..7917ab9 100644 (file)
@@ -33,6 +33,7 @@
 #include "time-util.h"
 #include "missing.h"
 #include "set.h"
+#include "list.h"
 
 #include "sd-event.h"
 
 
 typedef enum EventSourceType {
         SOURCE_IO,
-        SOURCE_MONOTONIC,
-        SOURCE_REALTIME,
+        SOURCE_TIME_REALTIME,
+        SOURCE_TIME_BOOTTIME,
+        SOURCE_TIME_MONOTONIC,
+        SOURCE_TIME_REALTIME_ALARM,
+        SOURCE_TIME_BOOTTIME_ALARM,
         SOURCE_SIGNAL,
         SOURCE_CHILD,
         SOURCE_DEFER,
         SOURCE_POST,
         SOURCE_EXIT,
-        SOURCE_WATCHDOG
+        SOURCE_WATCHDOG,
+        _SOURCE_EVENT_SOURCE_TYPE_MAX,
+        _SOURCE_EVENT_SOURCE_TYPE_INVALID = -1
 } EventSourceType;
 
+#define EVENT_SOURCE_IS_TIME(t) IN_SET((t), SOURCE_TIME_REALTIME, SOURCE_TIME_BOOTTIME, SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM)
+
 struct sd_event_source {
         unsigned n_ref;
 
@@ -58,10 +66,11 @@ struct sd_event_source {
         void *userdata;
         sd_event_handler_t prepare;
 
-        EventSourceType type:4;
+        EventSourceType type:5;
         int enabled:3;
         bool pending:1;
         bool dispatching:1;
+        bool floating:1;
 
         int64_t priority;
         unsigned pending_index;
@@ -69,6 +78,8 @@ struct sd_event_source {
         unsigned pending_iteration;
         unsigned prepare_iteration;
 
+        LIST_FIELDS(sd_event_source, sources);
+
         union {
                 struct {
                         sd_event_io_handler_t callback;
@@ -107,30 +118,42 @@ struct sd_event_source {
         };
 };
 
+struct clock_data {
+        int fd;
+
+        /* For all clocks we maintain two priority queues each, one
+         * ordered for the earliest times the events may be
+         * dispatched, and one ordered by the latest times they must
+         * have been dispatched. The range between the top entries in
+         * the two prioqs is the time window we can freely schedule
+         * wakeups in */
+
+        Prioq *earliest;
+        Prioq *latest;
+        usec_t next;
+
+        bool needs_rearm:1;
+};
+
 struct sd_event {
         unsigned n_ref;
 
         int epoll_fd;
         int signal_fd;
-        int realtime_fd;
-        int monotonic_fd;
         int watchdog_fd;
 
         Prioq *pending;
         Prioq *prepare;
 
-        /* For both clocks we maintain two priority queues each, one
-         * ordered for the earliest times the events may be
-         * dispatched, and one ordered by the latest times they must
-         * have been dispatched. The range between the top entries in
-         * the two prioqs is the time window we can freely schedule
-         * wakeups in */
-        Prioq *monotonic_earliest;
-        Prioq *monotonic_latest;
-        Prioq *realtime_earliest;
-        Prioq *realtime_latest;
+        /* timerfd_create() only supports these five clocks so far. We
+         * can add support for more clocks when the kernel learns to
+         * deal with them, too. */
+        struct clock_data realtime;
+        struct clock_data boottime;
+        struct clock_data monotonic;
+        struct clock_data realtime_alarm;
+        struct clock_data boottime_alarm;
 
-        usec_t realtime_next, monotonic_next;
         usec_t perturb;
 
         sigset_t sigset;
@@ -147,6 +170,7 @@ struct sd_event {
 
         unsigned iteration;
         dual_timestamp timestamp;
+        usec_t timestamp_boottime;
         int state;
 
         bool exit_requested:1;
@@ -161,8 +185,12 @@ struct sd_event {
         usec_t watchdog_last, watchdog_period;
 
         unsigned n_sources;
+
+        LIST_HEAD(sd_event_source, sources);
 };
 
+static void source_disconnect(sd_event_source *s);
+
 static int pending_prioq_compare(const void *a, const void *b) {
         const sd_event_source *x = a, *y = b;
 
@@ -234,8 +262,8 @@ static int prepare_prioq_compare(const void *a, const void *b) {
 static int earliest_time_prioq_compare(const void *a, const void *b) {
         const sd_event_source *x = a, *y = b;
 
-        assert(x->type == SOURCE_MONOTONIC || x->type == SOURCE_REALTIME);
-        assert(y->type == SOURCE_MONOTONIC || y->type == SOURCE_REALTIME);
+        assert(EVENT_SOURCE_IS_TIME(x->type));
+        assert(x->type == y->type);
 
         /* Enabled ones first */
         if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF)
@@ -267,8 +295,8 @@ static int earliest_time_prioq_compare(const void *a, const void *b) {
 static int latest_time_prioq_compare(const void *a, const void *b) {
         const sd_event_source *x = a, *y = b;
 
-        assert((x->type == SOURCE_MONOTONIC && y->type == SOURCE_MONOTONIC) ||
-               (x->type == SOURCE_REALTIME && y->type == SOURCE_REALTIME));
+        assert(EVENT_SOURCE_IS_TIME(x->type));
+        assert(x->type == y->type);
 
         /* Enabled ones first */
         if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF)
@@ -324,34 +352,42 @@ static int exit_prioq_compare(const void *a, const void *b) {
         return 0;
 }
 
+static void free_clock_data(struct clock_data *d) {
+        assert(d);
+
+        safe_close(d->fd);
+        prioq_free(d->earliest);
+        prioq_free(d->latest);
+}
+
 static void event_free(sd_event *e) {
+        sd_event_source *s;
+
         assert(e);
+
+        while ((s = e->sources)) {
+                assert(s->floating);
+                source_disconnect(s);
+                sd_event_source_unref(s);
+        }
+
         assert(e->n_sources == 0);
 
         if (e->default_event_ptr)
                 *(e->default_event_ptr) = NULL;
 
-        if (e->epoll_fd >= 0)
-                close_nointr_nofail(e->epoll_fd);
-
-        if (e->signal_fd >= 0)
-                close_nointr_nofail(e->signal_fd);
-
-        if (e->realtime_fd >= 0)
-                close_nointr_nofail(e->realtime_fd);
+        safe_close(e->epoll_fd);
+        safe_close(e->signal_fd);
+        safe_close(e->watchdog_fd);
 
-        if (e->monotonic_fd >= 0)
-                close_nointr_nofail(e->monotonic_fd);
-
-        if (e->watchdog_fd >= 0)
-                close_nointr_nofail(e->watchdog_fd);
+        free_clock_data(&e->realtime);
+        free_clock_data(&e->boottime);
+        free_clock_data(&e->monotonic);
+        free_clock_data(&e->realtime_alarm);
+        free_clock_data(&e->boottime_alarm);
 
         prioq_free(e->pending);
         prioq_free(e->prepare);
-        prioq_free(e->monotonic_earliest);
-        prioq_free(e->monotonic_latest);
-        prioq_free(e->realtime_earliest);
-        prioq_free(e->realtime_latest);
         prioq_free(e->exit);
 
         free(e->signal_sources);
@@ -372,9 +408,10 @@ _public_ int sd_event_new(sd_event** ret) {
                 return -ENOMEM;
 
         e->n_ref = 1;
-        e->signal_fd = e->realtime_fd = e->monotonic_fd = e->watchdog_fd = e->epoll_fd = -1;
-        e->realtime_next = e->monotonic_next = (usec_t) -1;
+        e->signal_fd = e->watchdog_fd = e->epoll_fd = e->realtime.fd = e->boottime.fd = e->monotonic.fd = e->realtime_alarm.fd = e->boottime_alarm.fd = -1;
+        e->realtime.next = e->boottime.next = e->monotonic.next = e->realtime_alarm.next = e->boottime_alarm.next = USEC_INFINITY;
         e->original_pid = getpid();
+        e->perturb = USEC_INFINITY;
 
         assert_se(sigemptyset(&e->sigset) == 0);
 
@@ -478,82 +515,176 @@ static int source_io_register(
         return 0;
 }
 
-static void source_free(sd_event_source *s) {
-        assert(s);
+static clockid_t event_source_type_to_clock(EventSourceType t) {
 
-        if (s->event) {
-                assert(s->event->n_sources > 0);
+        switch (t) {
 
-                switch (s->type) {
+        case SOURCE_TIME_REALTIME:
+                return CLOCK_REALTIME;
 
-                case SOURCE_IO:
-                        if (s->io.fd >= 0)
-                                source_io_unregister(s);
+        case SOURCE_TIME_BOOTTIME:
+                return CLOCK_BOOTTIME;
 
-                        break;
+        case SOURCE_TIME_MONOTONIC:
+                return CLOCK_MONOTONIC;
 
-                case SOURCE_MONOTONIC:
-                        prioq_remove(s->event->monotonic_earliest, s, &s->time.earliest_index);
-                        prioq_remove(s->event->monotonic_latest, s, &s->time.latest_index);
-                        break;
+        case SOURCE_TIME_REALTIME_ALARM:
+                return CLOCK_REALTIME_ALARM;
 
-                case SOURCE_REALTIME:
-                        prioq_remove(s->event->realtime_earliest, s, &s->time.earliest_index);
-                        prioq_remove(s->event->realtime_latest, s, &s->time.latest_index);
-                        break;
+        case SOURCE_TIME_BOOTTIME_ALARM:
+                return CLOCK_BOOTTIME_ALARM;
 
-                case SOURCE_SIGNAL:
-                        if (s->signal.sig > 0) {
-                                if (s->signal.sig != SIGCHLD || s->event->n_enabled_child_sources == 0)
-                                        assert_se(sigdelset(&s->event->sigset, s->signal.sig) == 0);
+        default:
+                return (clockid_t) -1;
+        }
+}
 
-                                if (s->event->signal_sources)
-                                        s->event->signal_sources[s->signal.sig] = NULL;
-                        }
+static EventSourceType clock_to_event_source_type(clockid_t clock) {
 
-                        break;
+        switch (clock) {
 
-                case SOURCE_CHILD:
-                        if (s->child.pid > 0) {
-                                if (s->enabled != SD_EVENT_OFF) {
-                                        assert(s->event->n_enabled_child_sources > 0);
-                                        s->event->n_enabled_child_sources--;
-                                }
+        case CLOCK_REALTIME:
+                return SOURCE_TIME_REALTIME;
 
-                                if (!s->event->signal_sources || !s->event->signal_sources[SIGCHLD])
-                                        assert_se(sigdelset(&s->event->sigset, SIGCHLD) == 0);
+        case CLOCK_BOOTTIME:
+                return SOURCE_TIME_BOOTTIME;
 
-                                hashmap_remove(s->event->child_sources, INT_TO_PTR(s->child.pid));
-                        }
+        case CLOCK_MONOTONIC:
+                return SOURCE_TIME_MONOTONIC;
 
-                        break;
+        case CLOCK_REALTIME_ALARM:
+                return SOURCE_TIME_REALTIME_ALARM;
 
-                case SOURCE_DEFER:
-                        /* nothing */
-                        break;
+        case CLOCK_BOOTTIME_ALARM:
+                return SOURCE_TIME_BOOTTIME_ALARM;
 
-                case SOURCE_POST:
-                        set_remove(s->event->post_sources, s);
-                        break;
+        default:
+                return _SOURCE_EVENT_SOURCE_TYPE_INVALID;
+        }
+}
 
-                case SOURCE_EXIT:
-                        prioq_remove(s->event->exit, s, &s->exit.prioq_index);
-                        break;
+static struct clock_data* event_get_clock_data(sd_event *e, EventSourceType t) {
+        assert(e);
 
-                case SOURCE_WATCHDOG:
-                        assert_not_reached("Wut? I shouldn't exist.");
+        switch (t) {
+
+        case SOURCE_TIME_REALTIME:
+                return &e->realtime;
+
+        case SOURCE_TIME_BOOTTIME:
+                return &e->boottime;
+
+        case SOURCE_TIME_MONOTONIC:
+                return &e->monotonic;
+
+        case SOURCE_TIME_REALTIME_ALARM:
+                return &e->realtime_alarm;
+
+        case SOURCE_TIME_BOOTTIME_ALARM:
+                return &e->boottime_alarm;
+
+        default:
+                return NULL;
+        }
+}
+
+static void source_disconnect(sd_event_source *s) {
+        sd_event *event;
+
+        assert(s);
+
+        if (!s->event)
+                return;
+
+        assert(s->event->n_sources > 0);
+
+        switch (s->type) {
+
+        case SOURCE_IO:
+                if (s->io.fd >= 0)
+                        source_io_unregister(s);
+
+                break;
+
+        case SOURCE_TIME_REALTIME:
+        case SOURCE_TIME_BOOTTIME:
+        case SOURCE_TIME_MONOTONIC:
+        case SOURCE_TIME_REALTIME_ALARM:
+        case SOURCE_TIME_BOOTTIME_ALARM: {
+                struct clock_data *d;
+
+                d = event_get_clock_data(s->event, s->type);
+                assert(d);
+
+                prioq_remove(d->earliest, s, &s->time.earliest_index);
+                prioq_remove(d->latest, s, &s->time.latest_index);
+                d->needs_rearm = true;
+                break;
+        }
+
+        case SOURCE_SIGNAL:
+                if (s->signal.sig > 0) {
+                        if (s->signal.sig != SIGCHLD || s->event->n_enabled_child_sources == 0)
+                                assert_se(sigdelset(&s->event->sigset, s->signal.sig) == 0);
+
+                        if (s->event->signal_sources)
+                                s->event->signal_sources[s->signal.sig] = NULL;
                 }
 
-                if (s->pending)
-                        prioq_remove(s->event->pending, s, &s->pending_index);
+                break;
+
+        case SOURCE_CHILD:
+                if (s->child.pid > 0) {
+                        if (s->enabled != SD_EVENT_OFF) {
+                                assert(s->event->n_enabled_child_sources > 0);
+                                s->event->n_enabled_child_sources--;
+                        }
+
+                        if (!s->event->signal_sources || !s->event->signal_sources[SIGCHLD])
+                                assert_se(sigdelset(&s->event->sigset, SIGCHLD) == 0);
+
+                        hashmap_remove(s->event->child_sources, INT_TO_PTR(s->child.pid));
+                }
 
-                if (s->prepare)
-                        prioq_remove(s->event->prepare, s, &s->prepare_index);
+                break;
 
-                s->event->n_sources--;
-                sd_event_unref(s->event);
+        case SOURCE_DEFER:
+                /* nothing */
+                break;
+
+        case SOURCE_POST:
+                set_remove(s->event->post_sources, s);
+                break;
+
+        case SOURCE_EXIT:
+                prioq_remove(s->event->exit, s, &s->exit.prioq_index);
+                break;
+
+        default:
+                assert_not_reached("Wut? I shouldn't exist.");
         }
 
+        if (s->pending)
+                prioq_remove(s->event->pending, s, &s->pending_index);
+
+        if (s->prepare)
+                prioq_remove(s->event->prepare, s, &s->prepare_index);
+
+        event = s->event;
+
+        s->type = _SOURCE_EVENT_SOURCE_TYPE_INVALID;
+        s->event = NULL;
+        LIST_REMOVE(sources, event->sources, s);
+        event->n_sources--;
+
+        if (!s->floating)
+                sd_event_unref(event);
+}
+
+static void source_free(sd_event_source *s) {
+        assert(s);
+
+        source_disconnect(s);
         free(s);
 }
 
@@ -579,18 +710,21 @@ static int source_set_pending(sd_event_source *s, bool b) {
         } else
                 assert_se(prioq_remove(s->event->pending, s, &s->pending_index));
 
-        if (s->type == SOURCE_REALTIME) {
-                prioq_reshuffle(s->event->realtime_earliest, s, &s->time.earliest_index);
-                prioq_reshuffle(s->event->realtime_latest, s, &s->time.latest_index);
-        } else if (s->type == SOURCE_MONOTONIC) {
-                prioq_reshuffle(s->event->monotonic_earliest, s, &s->time.earliest_index);
-                prioq_reshuffle(s->event->monotonic_latest, s, &s->time.latest_index);
+        if (EVENT_SOURCE_IS_TIME(s->type)) {
+                struct clock_data *d;
+
+                d = event_get_clock_data(s->event, s->type);
+                assert(d);
+
+                prioq_reshuffle(d->earliest, s, &s->time.earliest_index);
+                prioq_reshuffle(d->latest, s, &s->time.latest_index);
+                d->needs_rearm = true;
         }
 
         return 0;
 }
 
-static sd_event_source *source_new(sd_event *e, EventSourceType type) {
+static sd_event_source *source_new(sd_event *e, bool floating, EventSourceType type) {
         sd_event_source *s;
 
         assert(e);
@@ -600,10 +734,15 @@ static sd_event_source *source_new(sd_event *e, EventSourceType type) {
                 return NULL;
 
         s->n_ref = 1;
-        s->event = sd_event_ref(e);
+        s->event = e;
+        s->floating = floating;
         s->type = type;
         s->pending_index = s->prepare_index = PRIOQ_IDX_NULL;
 
+        if (!floating)
+                sd_event_ref(e);
+
+        LIST_PREPEND(sources, e->sources, s);
         e->n_sources ++;
 
         return s;
@@ -624,11 +763,10 @@ _public_ int sd_event_add_io(
         assert_return(fd >= 0, -EINVAL);
         assert_return(!(events & ~(EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLPRI|EPOLLERR|EPOLLHUP|EPOLLET)), -EINVAL);
         assert_return(callback, -EINVAL);
-        assert_return(ret, -EINVAL);
         assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
         assert_return(!event_pid_changed(e), -ECHILD);
 
-        s = source_new(e, SOURCE_IO);
+        s = source_new(e, !ret, SOURCE_IO);
         if (!s)
                 return -ENOMEM;
 
@@ -641,105 +779,111 @@ _public_ int sd_event_add_io(
         r = source_io_register(s, s->enabled, events);
         if (r < 0) {
                 source_free(s);
-                return -errno;
+                return r;
         }
 
-        *ret = s;
+        if (ret)
+                *ret = s;
+
         return 0;
 }
 
+static void initialize_perturb(sd_event *e) {
+        sd_id128_t bootid = {};
+
+        /* When we sleep for longer, we try to realign the wakeup to
+           the same time wihtin each minute/second/250ms, so that
+           events all across the system can be coalesced into a single
+           CPU wakeup. However, let's take some system-specific
+           randomness for this value, so that in a network of systems
+           with synced clocks timer events are distributed a
+           bit. Here, we calculate a perturbation usec offset from the
+           boot ID. */
+
+        if (_likely_(e->perturb != USEC_INFINITY))
+                return;
+
+        if (sd_id128_get_boot(&bootid) >= 0)
+                e->perturb = (bootid.qwords[0] ^ bootid.qwords[1]) % USEC_PER_MINUTE;
+}
+
 static int event_setup_timer_fd(
                 sd_event *e,
-                EventSourceType type,
-                int *timer_fd,
-                clockid_t id) {
+                struct clock_data *d,
+                clockid_t clock) {
 
-        sd_id128_t bootid = {};
         struct epoll_event ev = {};
         int r, fd;
 
         assert(e);
-        assert(timer_fd);
+        assert(d);
 
-        if (_likely_(*timer_fd >= 0))
+        if (_likely_(d->fd >= 0))
                 return 0;
 
-        fd = timerfd_create(id, TFD_NONBLOCK|TFD_CLOEXEC);
+        fd = timerfd_create(clock, TFD_NONBLOCK|TFD_CLOEXEC);
         if (fd < 0)
                 return -errno;
 
         ev.events = EPOLLIN;
-        ev.data.ptr = INT_TO_PTR(type);
+        ev.data.ptr = INT_TO_PTR(clock_to_event_source_type(clock));
 
         r = epoll_ctl(e->epoll_fd, EPOLL_CTL_ADD, fd, &ev);
         if (r < 0) {
-                close_nointr_nofail(fd);
+                safe_close(fd);
                 return -errno;
         }
 
-        /* When we sleep for longer, we try to realign the wakeup to
-           the same time wihtin each minute/second/250ms, so that
-           events all across the system can be coalesced into a single
-           CPU wakeup. However, let's take some system-specific
-           randomness for this value, so that in a network of systems
-           with synced clocks timer events are distributed a
-           bit. Here, we calculate a perturbation usec offset from the
-           boot ID. */
-
-        if (sd_id128_get_boot(&bootid) >= 0)
-                e->perturb = (bootid.qwords[0] ^ bootid.qwords[1]) % USEC_PER_MINUTE;
-
-        *timer_fd = fd;
+        d->fd = fd;
         return 0;
 }
 
-static int event_add_time_internal(
+_public_ int sd_event_add_time(
                 sd_event *e,
                 sd_event_source **ret,
-                EventSourceType type,
-                int *timer_fd,
-                clockid_t id,
-                Prioq **earliest,
-                Prioq **latest,
+                clockid_t clock,
                 uint64_t usec,
                 uint64_t accuracy,
                 sd_event_time_handler_t callback,
                 void *userdata) {
 
+        EventSourceType type;
         sd_event_source *s;
+        struct clock_data *d;
         int r;
 
         assert_return(e, -EINVAL);
-        assert_return(callback, -EINVAL);
-        assert_return(ret, -EINVAL);
         assert_return(usec != (uint64_t) -1, -EINVAL);
         assert_return(accuracy != (uint64_t) -1, -EINVAL);
+        assert_return(callback, -EINVAL);
         assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
         assert_return(!event_pid_changed(e), -ECHILD);
 
-        assert(timer_fd);
-        assert(earliest);
-        assert(latest);
+        type = clock_to_event_source_type(clock);
+        assert_return(type >= 0, -ENOTSUP);
 
-        if (!*earliest) {
-                *earliest = prioq_new(earliest_time_prioq_compare);
-                if (!*earliest)
+        d = event_get_clock_data(e, type);
+        assert(d);
+
+        if (!d->earliest) {
+                d->earliest = prioq_new(earliest_time_prioq_compare);
+                if (!d->earliest)
                         return -ENOMEM;
         }
 
-        if (!*latest) {
-                *latest = prioq_new(latest_time_prioq_compare);
-                if (!*latest)
+        if (!d->latest) {
+                d->latest = prioq_new(latest_time_prioq_compare);
+                if (!d->latest)
                         return -ENOMEM;
         }
 
-        if (*timer_fd < 0) {
-                r = event_setup_timer_fd(e, type, timer_fd, id);
+        if (d->fd < 0) {
+                r = event_setup_timer_fd(e, d, clock);
                 if (r < 0)
                         return r;
         }
 
-        s = source_new(e, type);
+        s = source_new(e, !ret, type);
         if (!s)
                 return -ENOMEM;
 
@@ -750,15 +894,19 @@ static int event_add_time_internal(
         s->userdata = userdata;
         s->enabled = SD_EVENT_ONESHOT;
 
-        r = prioq_put(*earliest, s, &s->time.earliest_index);
+        d->needs_rearm = true;
+
+        r = prioq_put(d->earliest, s, &s->time.earliest_index);
         if (r < 0)
                 goto fail;
 
-        r = prioq_put(*latest, s, &s->time.latest_index);
+        r = prioq_put(d->latest, s, &s->time.latest_index);
         if (r < 0)
                 goto fail;
 
-        *ret = s;
+        if (ret)
+                *ret = s;
+
         return 0;
 
 fail:
@@ -766,26 +914,6 @@ fail:
         return r;
 }
 
-_public_ int sd_event_add_monotonic(sd_event *e,
-                                    sd_event_source **ret,
-                                    uint64_t usec,
-                                    uint64_t accuracy,
-                                    sd_event_time_handler_t callback,
-                                    void *userdata) {
-
-        return event_add_time_internal(e, ret, SOURCE_MONOTONIC, &e->monotonic_fd, CLOCK_MONOTONIC, &e->monotonic_earliest, &e->monotonic_latest, usec, accuracy, callback, userdata);
-}
-
-_public_ int sd_event_add_realtime(sd_event *e,
-                                   sd_event_source **ret,
-                                   uint64_t usec,
-                                   uint64_t accuracy,
-                                   sd_event_time_handler_t callback,
-                                   void *userdata) {
-
-        return event_add_time_internal(e, ret, SOURCE_REALTIME, &e->realtime_fd, CLOCK_REALTIME, &e->realtime_earliest, &e->realtime_latest, usec, accuracy, callback, userdata);
-}
-
 static int event_update_signal_fd(sd_event *e) {
         struct epoll_event ev = {};
         bool add_to_epoll;
@@ -809,15 +937,19 @@ static int event_update_signal_fd(sd_event *e) {
 
         r = epoll_ctl(e->epoll_fd, EPOLL_CTL_ADD, e->signal_fd, &ev);
         if (r < 0) {
-                close_nointr_nofail(e->signal_fd);
-                e->signal_fd = -1;
-
+                e->signal_fd = safe_close(e->signal_fd);
                 return -errno;
         }
 
         return 0;
 }
 
+static int signal_exit_callback(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
+        assert(s);
+
+        return sd_event_exit(sd_event_source_get_event(s), PTR_TO_INT(userdata));
+}
+
 _public_ int sd_event_add_signal(
                 sd_event *e,
                 sd_event_source **ret,
@@ -832,11 +964,12 @@ _public_ int sd_event_add_signal(
         assert_return(e, -EINVAL);
         assert_return(sig > 0, -EINVAL);
         assert_return(sig < _NSIG, -EINVAL);
-        assert_return(callback, -EINVAL);
-        assert_return(ret, -EINVAL);
         assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
         assert_return(!event_pid_changed(e), -ECHILD);
 
+        if (!callback)
+                callback = signal_exit_callback;
+
         r = pthread_sigmask(SIG_SETMASK, NULL, &ss);
         if (r < 0)
                 return -errno;
@@ -851,7 +984,7 @@ _public_ int sd_event_add_signal(
         } else if (e->signal_sources[sig])
                 return -EBUSY;
 
-        s = source_new(e, SOURCE_SIGNAL);
+        s = source_new(e, !ret, SOURCE_SIGNAL);
         if (!s)
                 return -ENOMEM;
 
@@ -871,7 +1004,9 @@ _public_ int sd_event_add_signal(
                 }
         }
 
-        *ret = s;
+        if (ret)
+                *ret = s;
+
         return 0;
 }
 
@@ -891,7 +1026,6 @@ _public_ int sd_event_add_child(
         assert_return(!(options & ~(WEXITED|WSTOPPED|WCONTINUED)), -EINVAL);
         assert_return(options != 0, -EINVAL);
         assert_return(callback, -EINVAL);
-        assert_return(ret, -EINVAL);
         assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
         assert_return(!event_pid_changed(e), -ECHILD);
 
@@ -902,7 +1036,7 @@ _public_ int sd_event_add_child(
         if (hashmap_contains(e->child_sources, INT_TO_PTR(pid)))
                 return -EBUSY;
 
-        s = source_new(e, SOURCE_CHILD);
+        s = source_new(e, !ret, SOURCE_CHILD);
         if (!s)
                 return -ENOMEM;
 
@@ -926,13 +1060,15 @@ _public_ int sd_event_add_child(
                 r = event_update_signal_fd(e);
                 if (r < 0) {
                         source_free(s);
-                        return -errno;
+                        return r;
                 }
         }
 
         e->need_process_child = true;
 
-        *ret = s;
+        if (ret)
+                *ret = s;
+
         return 0;
 }
 
@@ -947,11 +1083,10 @@ _public_ int sd_event_add_defer(
 
         assert_return(e, -EINVAL);
         assert_return(callback, -EINVAL);
-        assert_return(ret, -EINVAL);
         assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
         assert_return(!event_pid_changed(e), -ECHILD);
 
-        s = source_new(e, SOURCE_DEFER);
+        s = source_new(e, !ret, SOURCE_DEFER);
         if (!s)
                 return -ENOMEM;
 
@@ -965,7 +1100,9 @@ _public_ int sd_event_add_defer(
                 return r;
         }
 
-        *ret = s;
+        if (ret)
+                *ret = s;
+
         return 0;
 }
 
@@ -980,7 +1117,6 @@ _public_ int sd_event_add_post(
 
         assert_return(e, -EINVAL);
         assert_return(callback, -EINVAL);
-        assert_return(ret, -EINVAL);
         assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
         assert_return(!event_pid_changed(e), -ECHILD);
 
@@ -988,7 +1124,7 @@ _public_ int sd_event_add_post(
         if (r < 0)
                 return r;
 
-        s = source_new(e, SOURCE_POST);
+        s = source_new(e, !ret, SOURCE_POST);
         if (!s)
                 return -ENOMEM;
 
@@ -1002,7 +1138,9 @@ _public_ int sd_event_add_post(
                 return r;
         }
 
-        *ret = s;
+        if (ret)
+                *ret = s;
+
         return 0;
 }
 
@@ -1017,7 +1155,6 @@ _public_ int sd_event_add_exit(
 
         assert_return(e, -EINVAL);
         assert_return(callback, -EINVAL);
-        assert_return(ret, -EINVAL);
         assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
         assert_return(!event_pid_changed(e), -ECHILD);
 
@@ -1027,7 +1164,7 @@ _public_ int sd_event_add_exit(
                         return -ENOMEM;
         }
 
-        s = source_new(e, SOURCE_EXIT);
+        s = source_new(e, !ret, SOURCE_EXIT);
         if (!s)
                 return -ENOMEM;
 
@@ -1042,7 +1179,9 @@ _public_ int sd_event_add_exit(
                 return r;
         }
 
-        *ret = s;
+        if (ret)
+                *ret = s;
+
         return 0;
 }
 
@@ -1075,6 +1214,8 @@ _public_ sd_event_source* sd_event_source_unref(sd_event_source *s) {
                 if (s->dispatching) {
                         if (s->type == SOURCE_IO)
                                 source_io_unregister(s);
+
+                        source_disconnect(s);
                 } else
                         source_free(s);
         }
@@ -1160,7 +1301,8 @@ _public_ int sd_event_source_set_io_events(sd_event_source *s, uint32_t events)
         assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE);
         assert_return(!event_pid_changed(s->event), -ECHILD);
 
-        if (s->io.events == events)
+        /* edge-triggered updates are never skipped, so we can reset edges */
+        if (s->io.events == events && !(events & EPOLLET))
                 return 0;
 
         if (s->enabled != SD_EVENT_OFF) {
@@ -1237,9 +1379,13 @@ _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) {
 
         assert_return(s, -EINVAL);
         assert_return(m == SD_EVENT_OFF || m == SD_EVENT_ON || m == SD_EVENT_ONESHOT, -EINVAL);
-        assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE);
         assert_return(!event_pid_changed(s->event), -ECHILD);
 
+        /* If we are dead anyway, we are fine with turning off
+         * sources, but everything else needs to fail. */
+        if (s->event->state == SD_EVENT_FINISHED)
+                return m == SD_EVENT_OFF ? 0 : -ESTALE;
+
         if (s->enabled == m)
                 return 0;
 
@@ -1255,17 +1401,22 @@ _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) {
                         s->enabled = m;
                         break;
 
-                case SOURCE_MONOTONIC:
-                        s->enabled = m;
-                        prioq_reshuffle(s->event->monotonic_earliest, s, &s->time.earliest_index);
-                        prioq_reshuffle(s->event->monotonic_latest, s, &s->time.latest_index);
-                        break;
+                case SOURCE_TIME_REALTIME:
+                case SOURCE_TIME_BOOTTIME:
+                case SOURCE_TIME_MONOTONIC:
+                case SOURCE_TIME_REALTIME_ALARM:
+                case SOURCE_TIME_BOOTTIME_ALARM: {
+                        struct clock_data *d;
 
-                case SOURCE_REALTIME:
                         s->enabled = m;
-                        prioq_reshuffle(s->event->realtime_earliest, s, &s->time.earliest_index);
-                        prioq_reshuffle(s->event->realtime_latest, s, &s->time.latest_index);
+                        d = event_get_clock_data(s->event, s->type);
+                        assert(d);
+
+                        prioq_reshuffle(d->earliest, s, &s->time.earliest_index);
+                        prioq_reshuffle(d->latest, s, &s->time.latest_index);
+                        d->needs_rearm = true;
                         break;
+                }
 
                 case SOURCE_SIGNAL:
                         s->enabled = m;
@@ -1299,7 +1450,7 @@ _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) {
                         s->enabled = m;
                         break;
 
-                case SOURCE_WATCHDOG:
+                default:
                         assert_not_reached("Wut? I shouldn't exist.");
                 }
 
@@ -1314,17 +1465,22 @@ _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) {
                         s->enabled = m;
                         break;
 
-                case SOURCE_MONOTONIC:
-                        s->enabled = m;
-                        prioq_reshuffle(s->event->monotonic_earliest, s, &s->time.earliest_index);
-                        prioq_reshuffle(s->event->monotonic_latest, s, &s->time.latest_index);
-                        break;
+                case SOURCE_TIME_REALTIME:
+                case SOURCE_TIME_BOOTTIME:
+                case SOURCE_TIME_MONOTONIC:
+                case SOURCE_TIME_REALTIME_ALARM:
+                case SOURCE_TIME_BOOTTIME_ALARM: {
+                        struct clock_data *d;
 
-                case SOURCE_REALTIME:
                         s->enabled = m;
-                        prioq_reshuffle(s->event->realtime_earliest, s, &s->time.earliest_index);
-                        prioq_reshuffle(s->event->realtime_latest, s, &s->time.latest_index);
+                        d = event_get_clock_data(s->event, s->type);
+                        assert(d);
+
+                        prioq_reshuffle(d->earliest, s, &s->time.earliest_index);
+                        prioq_reshuffle(d->latest, s, &s->time.latest_index);
+                        d->needs_rearm = true;
                         break;
+                }
 
                 case SOURCE_SIGNAL:
                         s->enabled = m;
@@ -1358,7 +1514,7 @@ _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) {
                         s->enabled = m;
                         break;
 
-                case SOURCE_WATCHDOG:
+                default:
                         assert_not_reached("Wut? I shouldn't exist.");
                 }
         }
@@ -1375,7 +1531,7 @@ _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) {
 _public_ int sd_event_source_get_time(sd_event_source *s, uint64_t *usec) {
         assert_return(s, -EINVAL);
         assert_return(usec, -EINVAL);
-        assert_return(s->type == SOURCE_REALTIME || s->type == SOURCE_MONOTONIC, -EDOM);
+        assert_return(EVENT_SOURCE_IS_TIME(s->type), -EDOM);
         assert_return(!event_pid_changed(s->event), -ECHILD);
 
         *usec = s->time.next;
@@ -1383,9 +1539,11 @@ _public_ int sd_event_source_get_time(sd_event_source *s, uint64_t *usec) {
 }
 
 _public_ int sd_event_source_set_time(sd_event_source *s, uint64_t usec) {
+        struct clock_data *d;
+
         assert_return(s, -EINVAL);
         assert_return(usec != (uint64_t) -1, -EINVAL);
-        assert_return(s->type == SOURCE_REALTIME || s->type == SOURCE_MONOTONIC, -EDOM);
+        assert_return(EVENT_SOURCE_IS_TIME(s->type), -EDOM);
         assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE);
         assert_return(!event_pid_changed(s->event), -ECHILD);
 
@@ -1393,13 +1551,12 @@ _public_ int sd_event_source_set_time(sd_event_source *s, uint64_t usec) {
 
         source_set_pending(s, false);
 
-        if (s->type == SOURCE_REALTIME) {
-                prioq_reshuffle(s->event->realtime_earliest, s, &s->time.earliest_index);
-                prioq_reshuffle(s->event->realtime_latest, s, &s->time.latest_index);
-        } else {
-                prioq_reshuffle(s->event->monotonic_earliest, s, &s->time.earliest_index);
-                prioq_reshuffle(s->event->monotonic_latest, s, &s->time.latest_index);
-        }
+        d = event_get_clock_data(s->event, s->type);
+        assert(d);
+
+        prioq_reshuffle(d->earliest, s, &s->time.earliest_index);
+        prioq_reshuffle(d->latest, s, &s->time.latest_index);
+        d->needs_rearm = true;
 
         return 0;
 }
@@ -1407,7 +1564,7 @@ _public_ int sd_event_source_set_time(sd_event_source *s, uint64_t usec) {
 _public_ int sd_event_source_get_time_accuracy(sd_event_source *s, uint64_t *usec) {
         assert_return(s, -EINVAL);
         assert_return(usec, -EINVAL);
-        assert_return(s->type == SOURCE_REALTIME || s->type == SOURCE_MONOTONIC, -EDOM);
+        assert_return(EVENT_SOURCE_IS_TIME(s->type), -EDOM);
         assert_return(!event_pid_changed(s->event), -ECHILD);
 
         *usec = s->time.accuracy;
@@ -1415,9 +1572,11 @@ _public_ int sd_event_source_get_time_accuracy(sd_event_source *s, uint64_t *use
 }
 
 _public_ int sd_event_source_set_time_accuracy(sd_event_source *s, uint64_t usec) {
+        struct clock_data *d;
+
         assert_return(s, -EINVAL);
         assert_return(usec != (uint64_t) -1, -EINVAL);
-        assert_return(s->type == SOURCE_REALTIME || s->type == SOURCE_MONOTONIC, -EDOM);
+        assert_return(EVENT_SOURCE_IS_TIME(s->type), -EDOM);
         assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE);
         assert_return(!event_pid_changed(s->event), -ECHILD);
 
@@ -1428,14 +1587,25 @@ _public_ int sd_event_source_set_time_accuracy(sd_event_source *s, uint64_t usec
 
         source_set_pending(s, false);
 
-        if (s->type == SOURCE_REALTIME)
-                prioq_reshuffle(s->event->realtime_latest, s, &s->time.latest_index);
-        else
-                prioq_reshuffle(s->event->monotonic_latest, s, &s->time.latest_index);
+        d = event_get_clock_data(s->event, s->type);
+        assert(d);
+
+        prioq_reshuffle(d->latest, s, &s->time.latest_index);
+        d->needs_rearm = true;
 
         return 0;
 }
 
+_public_ int sd_event_source_get_time_clock(sd_event_source *s, clockid_t *clock) {
+        assert_return(s, -EINVAL);
+        assert_return(clock, -EINVAL);
+        assert_return(EVENT_SOURCE_IS_TIME(s->type), -EDOM);
+        assert_return(!event_pid_changed(s->event), -ECHILD);
+
+        *clock = event_source_type_to_clock(s->type);
+        return 0;
+}
+
 _public_ int sd_event_source_get_child_pid(sd_event_source *s, pid_t *pid) {
         assert_return(s, -EINVAL);
         assert_return(pid, -EINVAL);
@@ -1506,6 +1676,8 @@ static usec_t sleep_between(sd_event *e, usec_t a, usec_t b) {
         if (b <= a + 1)
                 return a;
 
+        initialize_perturb(e);
+
         /*
           Find a good time to wake up again between times a and b. We
           have two goals here:
@@ -1573,10 +1745,7 @@ static usec_t sleep_between(sd_event *e, usec_t a, usec_t b) {
 
 static int event_arm_timer(
                 sd_event *e,
-                int timer_fd,
-                Prioq *earliest,
-                Prioq *latest,
-                usec_t *next) {
+                struct clock_data *d) {
 
         struct itimerspec its = {};
         sd_event_source *a, *b;
@@ -1584,35 +1753,39 @@ static int event_arm_timer(
         int r;
 
         assert(e);
-        assert(next);
+        assert(d);
 
-        a = prioq_peek(earliest);
+        if (!d->needs_rearm)
+                return 0;
+        else
+                d->needs_rearm = false;
+
+        a = prioq_peek(d->earliest);
         if (!a || a->enabled == SD_EVENT_OFF) {
 
-                if (timer_fd < 0)
+                if (d->fd < 0)
                         return 0;
 
-                if (*next == (usec_t) -1)
+                if (d->next == USEC_INFINITY)
                         return 0;
 
                 /* disarm */
-                r = timerfd_settime(timer_fd, TFD_TIMER_ABSTIME, &its, NULL);
+                r = timerfd_settime(d->fd, TFD_TIMER_ABSTIME, &its, NULL);
                 if (r < 0)
                         return r;
 
-                *next = (usec_t) -1;
-
+                d->next = USEC_INFINITY;
                 return 0;
         }
 
-        b = prioq_peek(latest);
+        b = prioq_peek(d->latest);
         assert_se(b && b->enabled != SD_EVENT_OFF);
 
         t = sleep_between(e, a->time.next, b->time.next + b->time.accuracy);
-        if (*next == t)
+        if (d->next == t)
                 return 0;
 
-        assert_se(timer_fd >= 0);
+        assert_se(d->fd >= 0);
 
         if (t == 0) {
                 /* We don' want to disarm here, just mean some time looooong ago. */
@@ -1621,11 +1794,11 @@ static int event_arm_timer(
         } else
                 timespec_store(&its.it_value, t);
 
-        r = timerfd_settime(timer_fd, TFD_TIMER_ABSTIME, &its, NULL);
+        r = timerfd_settime(d->fd, TFD_TIMER_ABSTIME, &its, NULL);
         if (r < 0)
                 return -errno;
 
-        *next = t;
+        d->next = t;
         return 0;
 }
 
@@ -1669,7 +1842,7 @@ static int flush_timer(sd_event *e, int fd, uint32_t events, usec_t *next) {
                 return -EIO;
 
         if (next)
-                *next = (usec_t) -1;
+                *next = USEC_INFINITY;
 
         return 0;
 }
@@ -1677,16 +1850,16 @@ static int flush_timer(sd_event *e, int fd, uint32_t events, usec_t *next) {
 static int process_timer(
                 sd_event *e,
                 usec_t n,
-                Prioq *earliest,
-                Prioq *latest) {
+                struct clock_data *d) {
 
         sd_event_source *s;
         int r;
 
         assert(e);
+        assert(d);
 
         for (;;) {
-                s = prioq_peek(earliest);
+                s = prioq_peek(d->earliest);
                 if (!s ||
                     s->time.next > n ||
                     s->enabled == SD_EVENT_OFF ||
@@ -1697,8 +1870,9 @@ static int process_timer(
                 if (r < 0)
                         return r;
 
-                prioq_reshuffle(earliest, s, &s->time.earliest_index);
-                prioq_reshuffle(latest, s, &s->time.latest_index);
+                prioq_reshuffle(d->earliest, s, &s->time.earliest_index);
+                prioq_reshuffle(d->latest, s, &s->time.latest_index);
+                d->needs_rearm = true;
         }
 
         return 0;
@@ -1776,14 +1950,13 @@ static int process_signal(sd_event *e, uint32_t events) {
         int r;
 
         assert(e);
-        assert(e->signal_sources);
 
         assert_return(events == EPOLLIN, -EIO);
 
         for (;;) {
                 struct signalfd_siginfo si;
                 ssize_t ss;
-                sd_event_source *s;
+                sd_event_source *s = NULL;
 
                 ss = read(e->signal_fd, &si, sizeof(si));
                 if (ss < 0) {
@@ -1798,24 +1971,25 @@ static int process_signal(sd_event *e, uint32_t events) {
 
                 read_one = true;
 
-                s = e->signal_sources[si.ssi_signo];
                 if (si.ssi_signo == SIGCHLD) {
                         r = process_child(e);
                         if (r < 0)
                                 return r;
-                        if (r > 0 || !s)
+                        if (r > 0)
                                 continue;
-                } else
-                        if (!s)
-                                return -EIO;
+                }
+
+                if (e->signal_sources)
+                        s = e->signal_sources[si.ssi_signo];
+
+                if (!s)
+                        continue;
 
                 s->signal.siginfo = si;
                 r = source_set_pending(s, true);
                 if (r < 0)
                         return r;
         }
-
-        return 0;
 }
 
 static int source_dispatch(sd_event_source *s) {
@@ -1861,11 +2035,11 @@ static int source_dispatch(sd_event_source *s) {
                 r = s->io.callback(s, s->io.fd, s->io.revents, s->userdata);
                 break;
 
-        case SOURCE_MONOTONIC:
-                r = s->time.callback(s, s->time.next, s->userdata);
-                break;
-
-        case SOURCE_REALTIME:
+        case SOURCE_TIME_REALTIME:
+        case SOURCE_TIME_BOOTTIME:
+        case SOURCE_TIME_MONOTONIC:
+        case SOURCE_TIME_REALTIME_ALARM:
+        case SOURCE_TIME_BOOTTIME_ALARM:
                 r = s->time.callback(s, s->time.next, s->userdata);
                 break;
 
@@ -1902,6 +2076,8 @@ static int source_dispatch(sd_event_source *s) {
                 break;
 
         case SOURCE_WATCHDOG:
+        case _SOURCE_EVENT_SOURCE_TYPE_MAX:
+        case _SOURCE_EVENT_SOURCE_TYPE_INVALID:
                 assert_not_reached("Wut? I shouldn't exist.");
         }
 
@@ -2006,6 +2182,11 @@ static int arm_watchdog(sd_event *e) {
 
         timespec_store(&its.it_value, t);
 
+        /* Make sure we never set the watchdog to 0, which tells the
+         * kernel to disable it. */
+        if (its.it_value.tv_sec == 0 && its.it_value.tv_nsec == 0)
+                its.it_value.tv_nsec = 1;
+
         r = timerfd_settime(e->watchdog_fd, TFD_TIMER_ABSTIME, &its, NULL);
         if (r < 0)
                 return -errno;
@@ -2034,6 +2215,7 @@ _public_ int sd_event_run(sd_event *e, uint64_t timeout) {
         unsigned ev_queue_max;
         sd_event_source *p;
         int r, i, m;
+        bool timedout;
 
         assert_return(e, -EINVAL);
         assert_return(!event_pid_changed(e), -ECHILD);
@@ -2051,16 +2233,29 @@ _public_ int sd_event_run(sd_event *e, uint64_t timeout) {
         if (r < 0)
                 goto finish;
 
-        r = event_arm_timer(e, e->monotonic_fd, e->monotonic_earliest, e->monotonic_latest, &e->monotonic_next);
+        r = event_arm_timer(e, &e->realtime);
         if (r < 0)
                 goto finish;
 
-        r = event_arm_timer(e, e->realtime_fd, e->realtime_earliest, e->realtime_latest, &e->realtime_next);
+        r = event_arm_timer(e, &e->boottime);
+        if (r < 0)
+                goto finish;
+
+        r = event_arm_timer(e, &e->monotonic);
+        if (r < 0)
+                goto finish;
+
+        r = event_arm_timer(e, &e->realtime_alarm);
+        if (r < 0)
+                goto finish;
+
+        r = event_arm_timer(e, &e->boottime_alarm);
         if (r < 0)
                 goto finish;
 
         if (event_next_pending(e) || e->need_process_child)
                 timeout = 0;
+
         ev_queue_max = CLAMP(e->n_sources, 1U, EPOLL_QUEUE_MAX);
         ev_queue = newa(struct epoll_event, ev_queue_max);
 
@@ -2071,14 +2266,23 @@ _public_ int sd_event_run(sd_event *e, uint64_t timeout) {
                 goto finish;
         }
 
+        timedout = m == 0;
+
         dual_timestamp_get(&e->timestamp);
+        e->timestamp_boottime = now(CLOCK_BOOTTIME);
 
         for (i = 0; i < m; i++) {
 
-                if (ev_queue[i].data.ptr == INT_TO_PTR(SOURCE_MONOTONIC))
-                        r = flush_timer(e, e->monotonic_fd, ev_queue[i].events, &e->monotonic_next);
-                else if (ev_queue[i].data.ptr == INT_TO_PTR(SOURCE_REALTIME))
-                        r = flush_timer(e, e->realtime_fd, ev_queue[i].events, &e->realtime_next);
+                if (ev_queue[i].data.ptr == INT_TO_PTR(SOURCE_TIME_REALTIME))
+                        r = flush_timer(e, e->realtime.fd, ev_queue[i].events, &e->realtime.next);
+                else if (ev_queue[i].data.ptr == INT_TO_PTR(SOURCE_TIME_BOOTTIME))
+                        r = flush_timer(e, e->boottime.fd, ev_queue[i].events, &e->boottime.next);
+                else if (ev_queue[i].data.ptr == INT_TO_PTR(SOURCE_TIME_MONOTONIC))
+                        r = flush_timer(e, e->monotonic.fd, ev_queue[i].events, &e->monotonic.next);
+                else if (ev_queue[i].data.ptr == INT_TO_PTR(SOURCE_TIME_REALTIME_ALARM))
+                        r = flush_timer(e, e->realtime_alarm.fd, ev_queue[i].events, &e->realtime_alarm.next);
+                else if (ev_queue[i].data.ptr == INT_TO_PTR(SOURCE_TIME_BOOTTIME_ALARM))
+                        r = flush_timer(e, e->boottime_alarm.fd, ev_queue[i].events, &e->boottime_alarm.next);
                 else if (ev_queue[i].data.ptr == INT_TO_PTR(SOURCE_SIGNAL))
                         r = process_signal(e, ev_queue[i].events);
                 else if (ev_queue[i].data.ptr == INT_TO_PTR(SOURCE_WATCHDOG))
@@ -2094,11 +2298,23 @@ _public_ int sd_event_run(sd_event *e, uint64_t timeout) {
         if (r < 0)
                 goto finish;
 
-        r = process_timer(e, e->timestamp.monotonic, e->monotonic_earliest, e->monotonic_latest);
+        r = process_timer(e, e->timestamp.realtime, &e->realtime);
+        if (r < 0)
+                goto finish;
+
+        r = process_timer(e, e->timestamp_boottime, &e->boottime);
+        if (r < 0)
+                goto finish;
+
+        r = process_timer(e, e->timestamp.monotonic, &e->monotonic);
         if (r < 0)
                 goto finish;
 
-        r = process_timer(e, e->timestamp.realtime, e->realtime_earliest, e->realtime_latest);
+        r = process_timer(e, e->timestamp.realtime, &e->realtime_alarm);
+        if (r < 0)
+                goto finish;
+
+        r = process_timer(e, e->timestamp_boottime, &e->boottime_alarm);
         if (r < 0)
                 goto finish;
 
@@ -2110,7 +2326,7 @@ _public_ int sd_event_run(sd_event *e, uint64_t timeout) {
 
         p = event_next_pending(e);
         if (!p) {
-                r = 1;
+                r = !timedout;
                 goto finish;
         }
 
@@ -2175,23 +2391,32 @@ _public_ int sd_event_exit(sd_event *e, int code) {
         return 0;
 }
 
-_public_ int sd_event_get_now_realtime(sd_event *e, uint64_t *usec) {
+_public_ int sd_event_now(sd_event *e, clockid_t clock, uint64_t *usec) {
         assert_return(e, -EINVAL);
         assert_return(usec, -EINVAL);
-        assert_return(dual_timestamp_is_set(&e->timestamp), -ENODATA);
         assert_return(!event_pid_changed(e), -ECHILD);
 
-        *usec = e->timestamp.realtime;
-        return 0;
-}
+        /* If we haven't run yet, just get the actual time */
+        if (!dual_timestamp_is_set(&e->timestamp))
+                return -ENODATA;
 
-_public_ int sd_event_get_now_monotonic(sd_event *e, uint64_t *usec) {
-        assert_return(e, -EINVAL);
-        assert_return(usec, -EINVAL);
-        assert_return(dual_timestamp_is_set(&e->timestamp), -ENODATA);
-        assert_return(!event_pid_changed(e), -ECHILD);
+        switch (clock) {
+
+        case CLOCK_REALTIME:
+        case CLOCK_REALTIME_ALARM:
+                *usec = e->timestamp.realtime;
+                break;
+
+        case CLOCK_MONOTONIC:
+                *usec = e->timestamp.monotonic;
+                break;
+
+        case CLOCK_BOOTTIME:
+        case CLOCK_BOOTTIME_ALARM:
+                *usec = e->timestamp_boottime;
+                break;
+        }
 
-        *usec = e->timestamp.monotonic;
         return 0;
 }
 
@@ -2274,8 +2499,7 @@ _public_ int sd_event_set_watchdog(sd_event *e, int b) {
         } else {
                 if (e->watchdog_fd >= 0) {
                         epoll_ctl(e->epoll_fd, EPOLL_CTL_DEL, e->watchdog_fd, NULL);
-                        close_nointr_nofail(e->watchdog_fd);
-                        e->watchdog_fd = -1;
+                        e->watchdog_fd = safe_close(e->watchdog_fd);
                 }
         }
 
@@ -2283,8 +2507,7 @@ _public_ int sd_event_set_watchdog(sd_event *e, int b) {
         return e->watchdog;
 
 fail:
-        close_nointr_nofail(e->watchdog_fd);
-        e->watchdog_fd = -1;
+        e->watchdog_fd = safe_close(e->watchdog_fd);
         return r;
 }
 
index 0b7e2e4..ffefb14 100644 (file)
@@ -196,7 +196,7 @@ int main(int argc, char *argv[]) {
 
         assert_se(sd_event_add_io(e, &x, a[0], EPOLLIN, io_handler, INT_TO_PTR('a')) >= 0);
         assert_se(sd_event_add_io(e, &y, b[0], EPOLLIN, io_handler, INT_TO_PTR('b')) >= 0);
-        assert_se(sd_event_add_monotonic(e, &z, 0, 0, time_handler, INT_TO_PTR('c')) >= 0);
+        assert_se(sd_event_add_time(e, &z, CLOCK_MONOTONIC, 0, 0, time_handler, INT_TO_PTR('c')) >= 0);
         assert_se(sd_event_add_exit(e, &q, exit_handler, INT_TO_PTR('g')) >= 0);
 
         assert_se(sd_event_source_set_priority(x, 99) >= 0);
@@ -206,6 +206,10 @@ int main(int argc, char *argv[]) {
         assert_se(sd_event_source_set_enabled(z, SD_EVENT_ONESHOT) >= 0);
         assert_se(sd_event_source_set_prepare(z, prepare_handler) >= 0);
 
+        /* Test for floating event sources */
+        assert_se(sigprocmask_many(SIG_BLOCK, SIGRTMIN+1, -1) == 0);
+        assert_se(sd_event_add_signal(e, NULL, SIGRTMIN+1, NULL, NULL) >= 0);
+
         assert_se(write(a[1], &ch, 1) >= 0);
         assert_se(write(b[1], &ch, 1) >= 0);
 
@@ -239,10 +243,10 @@ int main(int argc, char *argv[]) {
 
         sd_event_unref(e);
 
-        close_pipe(a);
-        close_pipe(b);
-        close_pipe(d);
-        close_pipe(k);
+        safe_close_pair(a);
+        safe_close_pair(b);
+        safe_close_pair(d);
+        safe_close_pair(k);
 
         return 0;
 }
diff --git a/src/libsystemd/sd-login/Makefile b/src/libsystemd/sd-login/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
similarity index 77%
rename from src/login/sd-login.c
rename to src/libsystemd/sd-login/sd-login.c
index ef67040..95cb6ff 100644 (file)
@@ -81,26 +81,117 @@ _public_ int sd_pid_get_owner_uid(pid_t pid, uid_t *uid) {
         return cg_pid_get_owner_uid(pid, uid);
 }
 
+_public_ int sd_peer_get_session(int fd, char **session) {
+        struct ucred ucred;
+        int r;
+
+        assert_return(fd >= 0, -EINVAL);
+        assert_return(session, -EINVAL);
+
+        r = getpeercred(fd, &ucred);
+        if (r < 0)
+                return r;
+
+        return cg_pid_get_session(ucred.pid, session);
+}
+
+_public_ int sd_peer_get_owner_uid(int fd, uid_t *uid) {
+        struct ucred ucred;
+        int r;
+
+        assert_return(fd >= 0, -EINVAL);
+        assert_return(uid, -EINVAL);
+
+        r = getpeercred(fd, &ucred);
+        if (r < 0)
+                return r;
+
+        return cg_pid_get_owner_uid(ucred.pid, uid);
+}
+
+_public_ int sd_peer_get_unit(int fd, char **unit) {
+        struct ucred ucred;
+        int r;
+
+        assert_return(fd >= 0, -EINVAL);
+        assert_return(unit, -EINVAL);
+
+        r = getpeercred(fd, &ucred);
+        if (r < 0)
+                return r;
+
+        return cg_pid_get_unit(ucred.pid, unit);
+}
+
+_public_ int sd_peer_get_user_unit(int fd, char **unit) {
+        struct ucred ucred;
+        int r;
+
+        assert_return(fd >= 0, -EINVAL);
+        assert_return(unit, -EINVAL);
+
+        r = getpeercred(fd, &ucred);
+        if (r < 0)
+                return r;
+
+        return cg_pid_get_user_unit(ucred.pid, unit);
+}
+
+_public_ int sd_peer_get_machine_name(int fd, char **machine) {
+        struct ucred ucred;
+        int r;
+
+        assert_return(fd >= 0, -EINVAL);
+        assert_return(machine, -EINVAL);
+
+        r = getpeercred(fd, &ucred);
+        if (r < 0)
+                return r;
+
+        return cg_pid_get_machine_name(ucred.pid, machine);
+}
+
+_public_ int sd_peer_get_slice(int fd, char **slice) {
+        struct ucred ucred;
+        int r;
+
+        assert_return(fd >= 0, -EINVAL);
+        assert_return(slice, -EINVAL);
+
+        r = getpeercred(fd, &ucred);
+        if (r < 0)
+                return r;
+
+        return cg_pid_get_slice(ucred.pid, slice);
+}
+
+static int file_of_uid(uid_t uid, char **p) {
+        assert(p);
+
+        if (asprintf(p, "/run/systemd/users/" UID_FMT, uid) < 0)
+                return -ENOMEM;
+
+        return 0;
+}
+
 _public_ int sd_uid_get_state(uid_t uid, char**state) {
-        char *p, *s = NULL;
+        _cleanup_free_ char *p = NULL;
+        char *s = NULL;
         int r;
 
         assert_return(state, -EINVAL);
 
-        if (asprintf(&p, "/run/systemd/users/%lu", (unsigned long) uid) < 0)
-                return -ENOMEM;
+        r = file_of_uid(uid, &p);
+        if (r < 0)
+                return r;
 
         r = parse_env_file(p, NEWLINE, "STATE", &s, NULL);
-        free(p);
-
         if (r == -ENOENT) {
                 free(s);
                 s = strdup("offline");
                 if (!s)
                         return -ENOMEM;
 
-                *state = s;
-                return 0;
         } else if (r < 0) {
                 free(s);
                 return r;
@@ -111,12 +202,34 @@ _public_ int sd_uid_get_state(uid_t uid, char**state) {
         return 0;
 }
 
+_public_ int sd_uid_get_display(uid_t uid, char **session) {
+        _cleanup_free_ char *p = NULL, *s = NULL;
+        int r;
+
+        assert_return(session, -EINVAL);
+
+        r = file_of_uid(uid, &p);
+        if (r < 0)
+                return r;
+
+        r = parse_env_file(p, NEWLINE, "DISPLAY", &s, NULL);
+        if (r < 0)
+                return r;
+
+        if (isempty(s))
+                return -ENOENT;
+
+        *session = s;
+        s = NULL;
+
+        return 0;
+}
+
 _public_ int sd_uid_is_on_seat(uid_t uid, int require_active, const char *seat) {
-        char *w, *state;
         _cleanup_free_ char *t = NULL, *s = NULL, *p = NULL;
         size_t l;
         int r;
-        const char *variable;
+        const char *word, *variable, *state;
 
         assert_return(seat, -EINVAL);
 
@@ -134,11 +247,11 @@ _public_ int sd_uid_is_on_seat(uid_t uid, int require_active, const char *seat)
         if (!s)
                 return -EIO;
 
-        if (asprintf(&t, "%lu", (unsigned long) uid) < 0)
+        if (asprintf(&t, UID_FMT, uid) < 0)
                 return -ENOMEM;
 
-        FOREACH_WORD(w, l, s, state) {
-                if (strneq(t, w, l))
+        FOREACH_WORD(word, l, s, state) {
+                if (strneq(t, word, l))
                         return 1;
         }
 
@@ -150,8 +263,9 @@ static int uid_get_array(uid_t uid, const char *variable, char ***array) {
         char **a;
         int r;
 
-        if (asprintf(&p, "/run/systemd/users/%lu", (unsigned long) uid) < 0)
-                return -ENOMEM;
+        r = file_of_uid(uid, &p);
+        if (r < 0)
+                return r;
 
         r = parse_env_file(p, NEWLINE,
                            variable, &s,
@@ -249,9 +363,7 @@ _public_ int sd_session_is_active(const char *session) {
         if (!s)
                 return -EIO;
 
-        r = parse_boolean(s);
-
-        return r;
+        return parse_boolean(s);
 }
 
 _public_ int sd_session_is_remote(const char *session) {
@@ -269,9 +381,7 @@ _public_ int sd_session_is_remote(const char *session) {
         if (!s)
                 return -EIO;
 
-        r = parse_boolean(s);
-
-        return r;
+        return parse_boolean(s);
 }
 
 _public_ int sd_session_get_state(const char *session, char **state) {
@@ -285,7 +395,6 @@ _public_ int sd_session_get_state(const char *session, char **state) {
                 return r;
 
         r = parse_env_file(p, NEWLINE, "STATE", &s, NULL);
-
         if (r < 0)
                 return r;
         else if (!s)
@@ -308,16 +417,13 @@ _public_ int sd_session_get_uid(const char *session, uid_t *uid) {
                 return r;
 
         r = parse_env_file(p, NEWLINE, "UID", &s, NULL);
-
         if (r < 0)
                 return r;
 
         if (!s)
                 return -EIO;
 
-        r = parse_uid(s, uid);
-
-        return r;
+        return parse_uid(s, uid);
 }
 
 static int session_get_string(const char *session, const char *field, char **value) {
@@ -331,7 +437,6 @@ static int session_get_string(const char *session, const char *field, char **val
                 return r;
 
         r = parse_env_file(p, NEWLINE, field, &s, NULL);
-
         if (r < 0)
                 return r;
 
@@ -481,10 +586,10 @@ _public_ int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **ui
         }
 
         if (uids && t) {
-                char *w, *state;
+                const char *word, *state;
                 size_t l;
 
-                FOREACH_WORD(w, l, t, state)
+                FOREACH_WORD(word, l, t, state)
                         n++;
 
                 if (n > 0) {
@@ -494,10 +599,10 @@ _public_ int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **ui
                         if (!b)
                                 return -ENOMEM;
 
-                        FOREACH_WORD(w, l, t, state) {
+                        FOREACH_WORD(word, l, t, state) {
                                 _cleanup_free_ char *k = NULL;
 
-                                k = strndup(w, l);
+                                k = strndup(word, l);
                                 if (!k)
                                         return -ENOMEM;
 
@@ -533,6 +638,8 @@ static int seat_get_can(const char *seat, const char *variable) {
         _cleanup_free_ char *p = NULL, *s = NULL;
         int r;
 
+        assert_return(variable, -EINVAL);
+
         r = file_of_seat(seat, &p);
         if (r < 0)
                 return r;
@@ -542,13 +649,10 @@ static int seat_get_can(const char *seat, const char *variable) {
                            NULL);
         if (r < 0)
                 return r;
+        if (!s)
+                return 0;
 
-        if (s)
-                r = parse_boolean(s);
-        else
-                r = 0;
-
-        return r;
+        return parse_boolean(s);
 }
 
 _public_ int sd_seat_can_multi_session(const char *seat) {
@@ -633,6 +737,8 @@ _public_ int sd_get_machine_names(char ***machines) {
         char **l = NULL, **a, **b;
         int r;
 
+        assert_return(machines, -EINVAL);
+
         r = get_files_in_directory("/run/systemd/machines/", &l);
         if (r < 0)
                 return r;
@@ -658,6 +764,69 @@ _public_ int sd_get_machine_names(char ***machines) {
         return r;
 }
 
+_public_ int sd_machine_get_class(const char *machine, char **class) {
+        _cleanup_free_ char *c = NULL;
+        const char *p;
+        int r;
+
+        assert_return(machine_name_is_valid(machine), -EINVAL);
+        assert_return(class, -EINVAL);
+
+        p = strappenda("/run/systemd/machines/", machine);
+        r = parse_env_file(p, NEWLINE, "CLASS", &c, NULL);
+        if (r < 0)
+                return r;
+        if (!c)
+                return -EIO;
+
+        *class = c;
+        c = NULL;
+
+        return 0;
+}
+
+_public_ int sd_machine_get_ifindices(const char *machine, int **ifindices) {
+        _cleanup_free_ char *netif = NULL;
+        size_t l, allocated = 0, nr = 0;
+        int *ni = NULL;
+        const char *p, *word, *state;
+        int r;
+
+        assert_return(machine_name_is_valid(machine), -EINVAL);
+        assert_return(ifindices, -EINVAL);
+
+        p = strappenda("/run/systemd/machines/", machine);
+        r = parse_env_file(p, NEWLINE, "NETIF", &netif, NULL);
+        if (r < 0)
+                return r;
+        if (!netif) {
+                *ifindices = NULL;
+                return 0;
+        }
+
+        FOREACH_WORD(word, l, netif, state) {
+                char buf[l+1];
+                int ifi;
+
+                *(char*) (mempcpy(buf, word, l)) = 0;
+
+                if (safe_atoi(buf, &ifi) < 0)
+                        continue;
+                if (ifi <= 0)
+                        continue;
+
+                if (!GREEDY_REALLOC(ni, allocated, nr+1)) {
+                        free(ni);
+                        return -ENOMEM;
+                }
+
+                ni[nr++] = ifi;
+        }
+
+        *ifindices = ni;
+        return nr;
+}
+
 static inline int MONITOR_TO_FD(sd_login_monitor *m) {
         return (int) (unsigned long) m - 1;
 }
@@ -679,7 +848,7 @@ _public_ int sd_login_monitor_new(const char *category, sd_login_monitor **m) {
         if (!category || streq(category, "seat")) {
                 k = inotify_add_watch(fd, "/run/systemd/seats/", IN_MOVED_TO|IN_DELETE);
                 if (k < 0) {
-                        close_nointr_nofail(fd);
+                        safe_close(fd);
                         return -errno;
                 }
 
@@ -689,7 +858,7 @@ _public_ int sd_login_monitor_new(const char *category, sd_login_monitor **m) {
         if (!category || streq(category, "session")) {
                 k = inotify_add_watch(fd, "/run/systemd/sessions/", IN_MOVED_TO|IN_DELETE);
                 if (k < 0) {
-                        close_nointr_nofail(fd);
+                        safe_close(fd);
                         return -errno;
                 }
 
@@ -699,7 +868,7 @@ _public_ int sd_login_monitor_new(const char *category, sd_login_monitor **m) {
         if (!category || streq(category, "uid")) {
                 k = inotify_add_watch(fd, "/run/systemd/users/", IN_MOVED_TO|IN_DELETE);
                 if (k < 0) {
-                        close_nointr_nofail(fd);
+                        safe_close(fd);
                         return -errno;
                 }
 
@@ -709,7 +878,7 @@ _public_ int sd_login_monitor_new(const char *category, sd_login_monitor **m) {
         if (!category || streq(category, "machine")) {
                 k = inotify_add_watch(fd, "/run/systemd/machines/", IN_MOVED_TO|IN_DELETE);
                 if (k < 0) {
-                        close_nointr_nofail(fd);
+                        safe_close(fd);
                         return -errno;
                 }
 
similarity index 92%
rename from src/login/test-login.c
rename to src/libsystemd/sd-login/test-login.c
index d78cea4..28f88a1 100644 (file)
 #include <sys/poll.h>
 #include <string.h>
 
-#include <systemd/sd-login.h>
+#include "systemd/sd-login.h"
 
 #include "util.h"
 #include "strv.h"
 
 static void test_login(void) {
+        _cleanup_close_pair_ int pair[2] = { -1, -1 };
+        _cleanup_free_ char *pp = NULL, *qq = NULL;
         int r, k;
         uid_t u, u2;
         char *seat, *type, *class, *display, *remote_user, *remote_host;
@@ -45,7 +47,12 @@ static void test_login(void) {
         printf("session = %s\n", session);
 
         assert_se(sd_pid_get_owner_uid(0, &u2) == 0);
-        printf("user = %lu\n", (unsigned long) u2);
+        printf("user = "UID_FMT"\n", u2);
+
+        assert_se(socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == 0);
+        sd_peer_get_session(pair[0], &pp);
+        sd_peer_get_session(pair[1], &qq);
+        assert_se(streq_ptr(pp, qq));
 
         r = sd_uid_get_sessions(u2, false, &sessions);
         assert_se(r >= 0);
@@ -81,7 +88,7 @@ static void test_login(void) {
         free(state);
 
         assert_se(sd_session_get_uid(session, &u) >= 0);
-        printf("uid = %lu\n", (unsigned long) u);
+        printf("uid = "UID_FMT"\n", u);
         assert_se(u == u2);
 
         assert_se(sd_session_get_type(session, &type) >= 0);
@@ -130,7 +137,7 @@ static void test_login(void) {
 
         assert_se(sd_seat_get_active(seat, &session2, &u2) >= 0);
         printf("session2 = %s\n", session2);
-        printf("uid2 = %lu\n", (unsigned long) u2);
+        printf("uid2 = "UID_FMT"\n", u2);
 
         r = sd_seat_get_sessions(seat, &sessions, &uids, &n);
         assert_se(r >= 0);
@@ -142,7 +149,7 @@ static void test_login(void) {
         free(t);
         printf("uids =");
         for (k = 0; k < (int) n; k++)
-                printf(" %lu", (unsigned long) uids[k]);
+                printf(" "UID_FMT, uids[k]);
         printf("\n");
         free(uids);
 
@@ -185,7 +192,7 @@ static void test_login(void) {
 
         printf("uids =");
         for (k = 0; k < r; k++)
-                printf(" %lu", (unsigned long) uids[k]);
+                printf(" "UID_FMT, uids[k]);
         printf("\n");
         free(uids);
 
diff --git a/src/libsystemd/sd-network/Makefile b/src/libsystemd/sd-network/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/libsystemd/sd-network/network-util.c b/src/libsystemd/sd-network/network-util.c
new file mode 100644 (file)
index 0000000..48958e8
--- /dev/null
@@ -0,0 +1,37 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "strv.h"
+#include "network-util.h"
+
+bool network_is_online(void) {
+        _cleanup_free_ char *state = NULL;
+        int r;
+
+        r = sd_network_get_operational_state(&state);
+        if (r < 0) /* if we don't know anything, we consider the system online */
+                return true;
+
+        if (STR_IN_SET(state, "routable", "degraded"))
+                return true;
+
+        return false;
+}
diff --git a/src/libsystemd/sd-network/network-util.h b/src/libsystemd/sd-network/network-util.h
new file mode 100644 (file)
index 0000000..02bd545
--- /dev/null
@@ -0,0 +1,30 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Thomas Hindø Paabøl Andersen
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "util.h"
+#include "sd-network.h"
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(sd_network_monitor*, sd_network_monitor_unref);
+#define _cleanup_network_monitor_unref_ _cleanup_(sd_network_monitor_unrefp)
+
+bool network_is_online(void);
diff --git a/src/libsystemd/sd-network/sd-network.c b/src/libsystemd/sd-network/sd-network.c
new file mode 100644 (file)
index 0000000..3a3f535
--- /dev/null
@@ -0,0 +1,320 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+  Copyright 2014 Tom Gundersen
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/inotify.h>
+#include <sys/poll.h>
+#include <net/if.h>
+
+#include "util.h"
+#include "macro.h"
+#include "strv.h"
+#include "fileio.h"
+#include "sd-network.h"
+#include "network-internal.h"
+
+_public_ int sd_network_get_operational_state(char **state) {
+        _cleanup_free_ char *s = NULL;
+        int r;
+
+        assert_return(state, -EINVAL);
+
+        r = parse_env_file("/run/systemd/netif/state", NEWLINE, "OPER_STATE", &s, NULL);
+        if (r == -ENOENT)
+                return -ENODATA;
+        if (r < 0)
+                return r;
+        if (isempty(s))
+                return -ENODATA;
+
+        *state = s;
+        s = NULL;
+
+        return 0;
+}
+
+static int network_get_strv(const char *key, char ***ret) {
+        _cleanup_strv_free_ char **a = NULL;
+        _cleanup_free_ char *s = NULL;
+        int r;
+
+        assert_return(ret, -EINVAL);
+
+        r = parse_env_file("/run/systemd/netif/state", NEWLINE, key, &s, NULL);
+        if (r == -ENOENT)
+                return -ENODATA;
+        if (r < 0)
+                return r;
+        if (isempty(s)) {
+                *ret = NULL;
+                return 0;
+        }
+
+        a = strv_split(s, " ");
+        if (!a)
+                return -ENOMEM;
+
+        strv_uniq(a);
+        r = strv_length(a);
+
+        *ret = a;
+        a = NULL;
+
+        return r;
+}
+
+_public_ int sd_network_get_dns(char ***ret) {
+        return network_get_strv("DNS", ret);
+}
+
+_public_ int sd_network_get_ntp(char ***ret) {
+        return network_get_strv("NTP", ret);
+}
+
+_public_ int sd_network_get_domains(char ***ret) {
+        return network_get_strv("DOMAINS", ret);
+}
+
+_public_ int sd_network_link_get_setup_state(int ifindex, char **state) {
+        _cleanup_free_ char *s = NULL, *p = NULL;
+        int r;
+
+        assert_return(ifindex > 0, -EINVAL);
+        assert_return(state, -EINVAL);
+
+        if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
+                return -ENOMEM;
+
+        r = parse_env_file(p, NEWLINE, "ADMIN_STATE", &s, NULL);
+        if (r == -ENOENT)
+                return -ENODATA;
+        if (r < 0)
+                return r;
+        if (isempty(s))
+                return -ENODATA;
+
+        *state = s;
+        s = NULL;
+
+        return 0;
+}
+
+_public_ int sd_network_link_get_operational_state(int ifindex, char **state) {
+        _cleanup_free_ char *s = NULL, *p = NULL;
+        int r;
+
+        assert_return(ifindex > 0, -EINVAL);
+        assert_return(state, -EINVAL);
+
+        if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
+                return -ENOMEM;
+
+        r = parse_env_file(p, NEWLINE, "OPER_STATE", &s, NULL);
+        if (r == -ENOENT)
+                return -ENODATA;
+        if (r < 0)
+                return r;
+        if (isempty(s))
+                return -ENODATA;
+
+        *state = s;
+        s = NULL;
+
+        return 0;
+}
+
+_public_ int sd_network_link_get_llmnr(int ifindex, char **llmnr) {
+        _cleanup_free_ char *s = NULL, *p = NULL;
+        int r;
+
+        assert_return(ifindex > 0, -EINVAL);
+        assert_return(llmnr, -EINVAL);
+
+        if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
+                return -ENOMEM;
+
+        r = parse_env_file(p, NEWLINE, "LLMNR", &s, NULL);
+        if (r == -ENOENT)
+                return -ENODATA;
+        if (r < 0)
+                return r;
+        if (isempty(s))
+                return -ENODATA;
+
+        *llmnr = s;
+        s = NULL;
+
+        return 0;
+}
+
+static int network_get_link_strv(const char *key, int ifindex, char ***ret) {
+        _cleanup_free_ char *p = NULL, *s = NULL;
+        _cleanup_strv_free_ char **a = NULL;
+        int r;
+
+        assert_return(ifindex > 0, -EINVAL);
+        assert_return(ret, -EINVAL);
+
+        if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
+                return -ENOMEM;
+
+        r = parse_env_file(p, NEWLINE, key, &s, NULL);
+        if (r == -ENOENT)
+                return -ENODATA;
+        if (r < 0)
+                return r;
+        if (isempty(s)) {
+                *ret = NULL;
+                return 0;
+        }
+
+        a = strv_split(s, " ");
+        if (!a)
+                return -ENOMEM;
+
+        strv_uniq(a);
+        r = strv_length(a);
+
+        *ret = a;
+        a = NULL;
+
+        return r;
+}
+
+_public_ int sd_network_link_get_dns(int ifindex, char ***ret) {
+        return network_get_link_strv("DNS", ifindex, ret);
+}
+
+_public_ int sd_network_link_get_ntp(int ifindex, char ***ret) {
+        return network_get_link_strv("NTP", ifindex, ret);
+}
+
+_public_ int sd_network_link_get_domains(int ifindex, char ***ret) {
+        return network_get_link_strv("DOMAINS", ifindex, ret);
+}
+
+_public_ int sd_network_link_get_wildcard_domain(int ifindex) {
+        int r;
+        _cleanup_free_ char *p = NULL, *s = NULL;
+
+        assert_return(ifindex > 0, -EINVAL);
+
+        if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
+                return -ENOMEM;
+
+        r = parse_env_file(p, NEWLINE, "WILDCARD_DOMAIN", &s, NULL);
+        if (r == -ENOENT)
+                return -ENODATA;
+        if (r < 0)
+                return r;
+        if (isempty(s))
+                return -ENODATA;
+
+        return parse_boolean(s);
+}
+
+static inline int MONITOR_TO_FD(sd_network_monitor *m) {
+        return (int) (unsigned long) m - 1;
+}
+
+static inline sd_network_monitor* FD_TO_MONITOR(int fd) {
+        return (sd_network_monitor*) (unsigned long) (fd + 1);
+}
+
+_public_ int sd_network_monitor_new(sd_network_monitor **m, const char *category) {
+        int fd, k;
+        bool good = false;
+
+        assert_return(m, -EINVAL);
+
+        fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
+        if (fd < 0)
+                return -errno;
+
+        if (!category || streq(category, "links")) {
+                k = inotify_add_watch(fd, "/run/systemd/netif/links/", IN_MOVED_TO|IN_DELETE);
+                if (k < 0) {
+                        safe_close(fd);
+                        return -errno;
+                }
+
+                good = true;
+        }
+
+        if (!good) {
+                close_nointr(fd);
+                return -EINVAL;
+        }
+
+        *m = FD_TO_MONITOR(fd);
+        return 0;
+}
+
+_public_ sd_network_monitor* sd_network_monitor_unref(sd_network_monitor *m) {
+        int fd;
+
+        assert_return(m, NULL);
+
+        fd = MONITOR_TO_FD(m);
+        close_nointr(fd);
+
+        return NULL;
+}
+
+_public_ int sd_network_monitor_flush(sd_network_monitor *m) {
+
+        assert_return(m, -EINVAL);
+
+        return flush_fd(MONITOR_TO_FD(m));
+}
+
+_public_ int sd_network_monitor_get_fd(sd_network_monitor *m) {
+
+        assert_return(m, -EINVAL);
+
+        return MONITOR_TO_FD(m);
+}
+
+_public_ int sd_network_monitor_get_events(sd_network_monitor *m) {
+
+        assert_return(m, -EINVAL);
+
+        /* For now we will only return POLLIN here, since we don't
+         * need anything else ever for inotify.  However, let's have
+         * this API to keep our options open should we later on need
+         * it. */
+        return POLLIN;
+}
+
+_public_ int sd_network_monitor_get_timeout(sd_network_monitor *m, uint64_t *timeout_usec) {
+
+        assert_return(m, -EINVAL);
+        assert_return(timeout_usec, -EINVAL);
+
+        /* For now we will only return (uint64_t) -1, since we don't
+         * need any timeout. However, let's have this API to keep our
+         * options open should we later on need it. */
+        *timeout_usec = (uint64_t) -1;
+        return 0;
+}
diff --git a/src/libsystemd/sd-path/Makefile b/src/libsystemd/sd-path/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/libsystemd/sd-path/sd-path.c b/src/libsystemd/sd-path/sd-path.c
new file mode 100644 (file)
index 0000000..651fceb
--- /dev/null
@@ -0,0 +1,627 @@
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "util.h"
+#include "architecture.h"
+#include "path-util.h"
+#include "strv.h"
+#include "sd-path.h"
+#include "missing.h"
+
+static int from_environment(const char *envname, const char *fallback, const char **ret) {
+        assert(ret);
+
+        if (envname) {
+                const char *e;
+
+                e = secure_getenv(envname);
+                if (e && path_is_absolute(e)) {
+                        *ret = e;
+                        return 0;
+                }
+        }
+
+        if (fallback) {
+                *ret = fallback;
+                return 0;
+        }
+
+        return -ENXIO;
+}
+
+static int from_home_dir(const char *envname, const char *suffix, char **buffer, const char **ret) {
+        _cleanup_free_ char *h = NULL;
+        char *cc = NULL;
+        int r;
+
+        assert(suffix);
+        assert(buffer);
+        assert(ret);
+
+        if (envname) {
+                const char *e = NULL;
+
+                e = secure_getenv(envname);
+                if (e && path_is_absolute(e)) {
+                        *ret = e;
+                        return 0;
+                }
+        }
+
+        r = get_home_dir(&h);
+        if (r < 0)
+                return r;
+
+        if (endswith(h, "/"))
+                cc = strappend(h, suffix);
+        else
+                cc = strjoin(h, "/", suffix, NULL);
+        if (!cc)
+                return -ENOMEM;
+
+        *buffer = cc;
+        *ret = cc;
+        return 0;
+}
+
+static int from_user_dir(const char *field, char **buffer, const char **ret) {
+        _cleanup_fclose_ FILE *f = NULL;
+        _cleanup_free_ char *b = NULL;
+        const char *fn = NULL;
+        char line[LINE_MAX];
+        size_t n;
+        int r;
+
+        assert(field);
+        assert(buffer);
+        assert(ret);
+
+        r = from_home_dir(NULL, ".config/user-dirs.dirs", &b, &fn);
+        if (r < 0)
+                return r;
+
+        f = fopen(fn, "re");
+        if (!f) {
+                if (errno == ENOENT)
+                        goto fallback;
+
+                return -errno;
+        }
+
+        /* This is an awful parse, but it follows closely what
+         * xdg-user-dirs does upstream */
+
+        n = strlen(field);
+        FOREACH_LINE(line, f, return -errno) {
+                char *l, *p, *e;
+
+                l = strstrip(line);
+
+                if (!strneq(l, field, n))
+                        continue;
+
+                p = l + n;
+                p += strspn(p, WHITESPACE);
+
+                if (*p != '=')
+                        continue;
+                p++;
+
+                p += strspn(p, WHITESPACE);
+
+                if (*p != '"')
+                        continue;
+                p++;
+
+                e = strrchr(p, '"');
+                if (!e)
+                        continue;
+                *e = 0;
+
+                /* Three syntaxes permitted: relative to $HOME, $HOME itself, and absolute path */
+                if (startswith(p, "$HOME/")) {
+                        _cleanup_free_ char *h = NULL;
+                        char *cc;
+
+                        r = get_home_dir(&h);
+                        if (r < 0)
+                                return r;
+
+                        cc = strappend(h, p+5);
+                        if (!cc)
+                                return -ENOMEM;
+
+                        *buffer = cc;
+                        *ret = cc;
+                        return 0;
+                } else if (streq(p, "$HOME")) {
+
+                        r = get_home_dir(buffer);
+                        if (r < 0)
+                                return r;
+
+                        *ret = *buffer;
+                        return 0;
+                } else if (path_is_absolute(p)) {
+                        char *copy;
+
+                        copy = strdup(p);
+                        if (!copy)
+                                return -ENOMEM;
+
+                        *buffer = copy;
+                        *ret = copy;
+                        return 0;
+                }
+        }
+
+fallback:
+        /* The desktop directory defaults to $HOME/Desktop, the others to $HOME */
+        if (streq(field, "XDG_DESKTOP_DIR")) {
+                _cleanup_free_ char *h = NULL;
+                char *cc;
+
+                r = get_home_dir(&h);
+                if (r < 0)
+                        return r;
+
+                cc = strappend(h, "/Desktop");
+                if (!cc)
+                        return -ENOMEM;
+
+                *buffer = cc;
+                *ret = cc;
+        } else {
+
+                r = get_home_dir(buffer);
+                if (r < 0)
+                        return r;
+
+                *ret = *buffer;
+        }
+
+        return 0;
+}
+
+static int get_path(uint64_t type, char **buffer, const char **ret) {
+        int r;
+
+        assert(buffer);
+        assert(ret);
+
+        switch (type) {
+
+        case SD_PATH_TEMPORARY:
+                return from_environment("TMPDIR", "/tmp", ret);
+
+        case SD_PATH_TEMPORARY_LARGE:
+                return from_environment("TMPDIR", "/var/tmp", ret);
+
+        case SD_PATH_SYSTEM_BINARIES:
+                *ret = "/usr/bin";
+                return 0;
+
+        case SD_PATH_SYSTEM_INCLUDE:
+                *ret = "/usr/include";
+                return 0;
+
+        case SD_PATH_SYSTEM_LIBRARY_PRIVATE:
+                *ret = "/usr/lib";
+                return 0;
+
+        case SD_PATH_SYSTEM_LIBRARY_ARCH:
+                *ret = LIBDIR;
+                return 0;
+
+        case SD_PATH_SYSTEM_SHARED:
+                *ret = "/usr/share";
+                return 0;
+
+        case SD_PATH_SYSTEM_CONFIGURATION_FACTORY:
+                *ret = "/usr/share/factory/etc";
+                return 0;
+
+        case SD_PATH_SYSTEM_STATE_FACTORY:
+                *ret = "/usr/share/factory/var";
+                return 0;
+
+        case SD_PATH_SYSTEM_CONFIGURATION:
+                *ret = "/etc";
+                return 0;
+
+        case SD_PATH_SYSTEM_RUNTIME:
+                *ret = "/run";
+                return 0;
+
+        case SD_PATH_SYSTEM_RUNTIME_LOGS:
+                *ret = "/run/log";
+                return 0;
+
+        case SD_PATH_SYSTEM_STATE_PRIVATE:
+                *ret = "/var/lib";
+                return 0;
+
+        case SD_PATH_SYSTEM_STATE_LOGS:
+                *ret = "/var/log";
+                return 0;
+
+        case SD_PATH_SYSTEM_STATE_CACHE:
+                *ret = "/var/cache";
+                return 0;
+
+        case SD_PATH_SYSTEM_STATE_SPOOL:
+                *ret = "/var/spool";
+                return 0;
+
+        case SD_PATH_USER_BINARIES:
+                return from_home_dir(NULL, ".local/bin", buffer, ret);
+
+        case SD_PATH_USER_LIBRARY_PRIVATE:
+                return from_home_dir(NULL, ".local/lib", buffer, ret);
+
+        case SD_PATH_USER_LIBRARY_ARCH:
+                return from_home_dir(NULL, ".local/lib/" LIB_ARCH_TUPLE, buffer, ret);
+
+        case SD_PATH_USER_SHARED:
+                return from_home_dir("XDG_DATA_HOME", ".local/share", buffer, ret);
+
+        case SD_PATH_USER_CONFIGURATION:
+                return from_home_dir("XDG_CONFIG_HOME", ".config", buffer, ret);
+
+        case SD_PATH_USER_RUNTIME:
+                return from_environment("XDG_RUNTIME_DIR", NULL, ret);
+
+        case SD_PATH_USER_STATE_CACHE:
+                return from_home_dir("XDG_CACHE_HOME", ".cache", buffer, ret);
+
+        case SD_PATH_USER:
+                r = get_home_dir(buffer);
+                if (r < 0)
+                        return r;
+
+                *ret = *buffer;
+                return 0;
+
+        case SD_PATH_USER_DOCUMENTS:
+                return from_user_dir("XDG_DOCUMENTS_DIR", buffer, ret);
+
+        case SD_PATH_USER_MUSIC:
+                return from_user_dir("XDG_MUSIC_DIR", buffer, ret);
+
+        case SD_PATH_USER_PICTURES:
+                return from_user_dir("XDG_PICTURES_DIR", buffer, ret);
+
+        case SD_PATH_USER_VIDEOS:
+                return from_user_dir("XDG_VIDEOS_DIR", buffer, ret);
+
+        case SD_PATH_USER_DOWNLOAD:
+                return from_user_dir("XDG_DOWNLOAD_DIR", buffer, ret);
+
+        case SD_PATH_USER_PUBLIC:
+                return from_user_dir("XDG_PUBLICSHARE_DIR", buffer, ret);
+
+        case SD_PATH_USER_TEMPLATES:
+                return from_user_dir("XDG_TEMPLATES_DIR", buffer, ret);
+
+        case SD_PATH_USER_DESKTOP:
+                return from_user_dir("XDG_DESKTOP_DIR", buffer, ret);
+        }
+
+        return -ENOTSUP;
+}
+
+_public_ int sd_path_home(uint64_t type, const char *suffix, char **path) {
+        char *buffer = NULL, *cc;
+        const char *ret;
+        int r;
+
+        assert_return(path, -EINVAL);
+
+        if (IN_SET(type,
+                   SD_PATH_SEARCH_BINARIES,
+                   SD_PATH_SEARCH_LIBRARY_PRIVATE,
+                   SD_PATH_SEARCH_LIBRARY_ARCH,
+                   SD_PATH_SEARCH_SHARED,
+                   SD_PATH_SEARCH_CONFIGURATION_FACTORY,
+                   SD_PATH_SEARCH_STATE_FACTORY,
+                   SD_PATH_SEARCH_CONFIGURATION)) {
+
+                _cleanup_strv_free_ char **l = NULL;
+
+                r = sd_path_search(type, suffix, &l);
+                if (r < 0)
+                        return r;
+
+                buffer = strv_join(l, ":");
+                if (!buffer)
+                        return -ENOMEM;
+
+                *path = buffer;
+                return 0;
+        }
+
+        r = get_path(type, &buffer, &ret);
+        if (r < 0)
+                return r;
+
+        if (!suffix) {
+                if (!buffer) {
+                        buffer = strdup(ret);
+                        if (!buffer)
+                                return -ENOMEM;
+                }
+
+                *path = buffer;
+                return 0;
+        }
+
+        suffix += strspn(suffix, "/");
+
+        if (endswith(ret, "/"))
+                cc = strappend(ret, suffix);
+        else
+                cc = strjoin(ret, "/", suffix, NULL);
+
+        free(buffer);
+
+        if (!cc)
+                return -ENOMEM;
+
+        *path = cc;
+        return 0;
+}
+
+static int search_from_environment(
+                char ***list,
+                const char *env_home,
+                const char *home_suffix,
+                const char *env_search,
+                bool env_search_sufficient,
+                const char *first, ...) {
+
+        const char *e;
+        char *h = NULL;
+        char **l = NULL;
+        int r;
+
+        assert(list);
+
+        if (env_search) {
+                e = secure_getenv(env_search);
+                if (e) {
+                        l = strv_split(e, ":");
+                        if (!l)
+                                return -ENOMEM;
+
+                        if (env_search_sufficient) {
+                                *list = l;
+                                return 0;
+                        }
+                }
+        }
+
+        if (!l && first) {
+                va_list ap;
+
+                va_start(ap, first);
+                l = strv_new_ap(first, ap);
+                va_end(ap);
+
+                if (!l)
+                        return -ENOMEM;
+        }
+
+        if (env_home) {
+                e = secure_getenv(env_home);
+                if (e && path_is_absolute(e)) {
+                        h = strdup(e);
+                        if (!h) {
+                                strv_free(l);
+                                return -ENOMEM;
+                        }
+                }
+        }
+
+        if (!h && home_suffix) {
+                e = secure_getenv("HOME");
+                if (e && path_is_absolute(e)) {
+                        if (endswith(e, "/"))
+                                h = strappend(e, home_suffix);
+                        else
+                                h = strjoin(e, "/", home_suffix, NULL);
+
+                        if (!h) {
+                                strv_free(l);
+                                return -ENOMEM;
+                        }
+                }
+        }
+
+        if (h) {
+                r = strv_consume_prepend(&l, h);
+                if (r < 0) {
+                        strv_free(l);
+                        return -ENOMEM;
+                }
+        }
+
+        *list = l;
+        return 0;
+}
+
+static int get_search(uint64_t type, char ***list) {
+
+        assert(list);
+
+        switch(type) {
+
+        case SD_PATH_SEARCH_BINARIES:
+                return search_from_environment(list,
+                                               NULL,
+                                               ".local/bin",
+                                               "PATH",
+                                               true,
+                                               "/usr/local/sbin",
+                                               "/usr/local/bin",
+                                               "/usr/sbin",
+                                               "/usr/bin",
+#ifdef HAVE_SPLIT_USR
+                                               "/sbin",
+                                               "/bin",
+#endif
+                                               NULL);
+
+        case SD_PATH_SEARCH_LIBRARY_PRIVATE:
+                return search_from_environment(list,
+                                               NULL,
+                                               ".local/lib",
+                                               NULL,
+                                               false,
+                                               "/usr/local/lib",
+                                               "/usr/lib",
+#ifdef HAVE_SPLIT_USR
+                                               "/lib",
+#endif
+                                               NULL);
+
+        case SD_PATH_SEARCH_LIBRARY_ARCH:
+                return search_from_environment(list,
+                                               NULL,
+                                               ".local/lib/" LIB_ARCH_TUPLE,
+                                               "LD_LIBRARY_PATH",
+                                               true,
+                                               LIBDIR,
+#ifdef HAVE_SPLIT_USR
+                                               ROOTLIBDIR,
+#endif
+                                               NULL);
+
+        case SD_PATH_SEARCH_SHARED:
+                return search_from_environment(list,
+                                               "XDG_DATA_HOME",
+                                               ".local/share",
+                                               "XDG_DATA_DIRS",
+                                               false,
+                                               "/usr/local/share",
+                                               "/usr/share",
+                                               NULL);
+
+        case SD_PATH_SEARCH_CONFIGURATION_FACTORY:
+                return search_from_environment(list,
+                                               NULL,
+                                               NULL,
+                                               NULL,
+                                               false,
+                                               "/usr/local/share/factory/etc",
+                                               "/usr/share/factory/etc",
+                                               NULL);
+
+        case SD_PATH_SEARCH_STATE_FACTORY:
+                return search_from_environment(list,
+                                               NULL,
+                                               NULL,
+                                               NULL,
+                                               false,
+                                               "/usr/local/share/factory/var",
+                                               "/usr/share/factory/var",
+                                               NULL);
+
+        case SD_PATH_SEARCH_CONFIGURATION:
+                return search_from_environment(list,
+                                               "XDG_CONFIG_HOME",
+                                               ".config",
+                                               "XDG_CONFIG_DIRS",
+                                               false,
+                                               "/etc",
+                                               NULL);
+        }
+
+        return -ENOTSUP;
+}
+
+_public_ int sd_path_search(uint64_t type, const char *suffix, char ***paths) {
+        char **l, **i, **j, **n;
+        int r;
+
+        assert_return(paths, -EINVAL);
+
+        if (!IN_SET(type,
+                    SD_PATH_SEARCH_BINARIES,
+                    SD_PATH_SEARCH_LIBRARY_PRIVATE,
+                    SD_PATH_SEARCH_LIBRARY_ARCH,
+                    SD_PATH_SEARCH_SHARED,
+                    SD_PATH_SEARCH_CONFIGURATION_FACTORY,
+                    SD_PATH_SEARCH_STATE_FACTORY,
+                    SD_PATH_SEARCH_CONFIGURATION)) {
+
+                char *p;
+
+                r = sd_path_home(type, suffix, &p);
+                if (r < 0)
+                        return r;
+
+                l = new(char*, 2);
+                if (!l) {
+                        free(p);
+                        return -ENOMEM;
+                }
+
+                l[0] = p;
+                l[1] = NULL;
+
+                *paths = l;
+                return 0;
+        }
+
+        r = get_search(type, &l);
+        if (r < 0)
+                return r;
+
+        if (!suffix) {
+                *paths = l;
+                return 0;
+        }
+
+        n = new(char*, strv_length(l)+1);
+        if (!n) {
+                strv_free(l);
+                return -ENOMEM;
+        }
+
+        j = n;
+        STRV_FOREACH(i, l) {
+
+                if (endswith(*i, "/"))
+                        *j = strappend(*i, suffix);
+                else
+                        *j = strjoin(*i, "/", suffix, NULL);
+
+                if (!*j) {
+                        strv_free(l);
+                        strv_free(n);
+                        return -ENOMEM;
+                }
+
+                j++;
+        }
+
+        *j = NULL;
+        *paths = n;
+        return 0;
+}
index 7da1d7b..019cdaf 100644 (file)
 ***/
 
 #include "util.h"
+#include "sd-resolve.h"
 
 DEFINE_TRIVIAL_CLEANUP_FUNC(sd_resolve*, sd_resolve_unref);
-DEFINE_TRIVIAL_CLEANUP_FUNC(struct addrinfo*, sd_resolve_freeaddrinfo);
+DEFINE_TRIVIAL_CLEANUP_FUNC(sd_resolve_query*, sd_resolve_query_unref);
+
 #define _cleanup_resolve_unref_ _cleanup_(sd_resolve_unrefp)
-#define _cleanup_resolve_addrinfo_free_ _cleanup_(sd_resolve_freeaddrinfop)
+#define _cleanup_resolve_query_unref_ _cleanup_(sd_resolve_query_unrefp)
index f05fe10..fea695f 100644 (file)
 #include "util.h"
 #include "list.h"
 #include "socket-util.h"
+#include "missing.h"
+#include "resolve-util.h"
 #include "sd-resolve.h"
 
-#define WORKERS_MIN 1
-#define WORKERS_MAX 16
-#define QUERIES_MAX 256
-#define BUFSIZE 10240
+#define WORKERS_MIN 1U
+#define WORKERS_MAX 16U
+#define QUERIES_MAX 256U
+#define BUFSIZE 10240U
 
 typedef enum {
         REQUEST_ADDRINFO,
@@ -73,6 +75,8 @@ enum {
 };
 
 struct sd_resolve {
+        unsigned n_ref;
+
         bool dead:1;
         pid_t original_pid;
 
@@ -81,30 +85,47 @@ struct sd_resolve {
         pthread_t workers[WORKERS_MAX];
         unsigned n_valid_workers;
 
-        unsigned current_id, current_index;
-        sd_resolve_query* queries[QUERIES_MAX];
-        unsigned n_queries;
+        unsigned current_id;
+        sd_resolve_query* query_array[QUERIES_MAX];
+        unsigned n_queries, n_done, n_outstanding;
+
+        sd_event_source *event_source;
+        sd_event *event;
+
+        sd_resolve_query *current;
 
-        LIST_HEAD(sd_resolve_query, done);
-        sd_resolve_query *done_tail;
-        unsigned n_done;
+        sd_resolve **default_resolve_ptr;
+        pid_t tid;
+
+        LIST_HEAD(sd_resolve_query, queries);
 };
 
 struct sd_resolve_query {
+        unsigned n_ref;
+
         sd_resolve *resolve;
+
+        QueryType type:4;
         bool done:1;
+        bool floating:1;
         unsigned id;
-        QueryType type;
 
         int ret;
         int _errno;
         int _h_errno;
         struct addrinfo *addrinfo;
         char *serv, *host;
+        unsigned char *answer;
+
+        union {
+                sd_resolve_getaddrinfo_handler_t getaddrinfo_handler;
+                sd_resolve_getnameinfo_handler_t getnameinfo_handler;
+                sd_resolve_res_handler_t res_handler;
+        };
 
         void *userdata;
 
-        LIST_FIELDS(sd_resolve_query, done);
+        LIST_FIELDS(sd_resolve_query, queries);
 };
 
 typedef struct RHeader {
@@ -180,13 +201,23 @@ typedef union Packet {
         ResResponse res_response;
 } Packet;
 
+static int getaddrinfo_done(sd_resolve_query* q);
+static int getnameinfo_done(sd_resolve_query *q);
+static int res_query_done(sd_resolve_query* q);
+
+static void resolve_query_disconnect(sd_resolve_query *q);
+
+#define RESOLVE_DONT_DESTROY(resolve) \
+        _cleanup_resolve_unref_ _unused_ sd_resolve *_dont_destroy_##resolve = sd_resolve_ref(resolve)
+
 static int send_died(int out_fd) {
-        RHeader rh = {};
 
-        assert(out_fd >= 0);
+        RHeader rh = {
+                .type = RESPONSE_DIED,
+                .length = sizeof(RHeader),
+        };
 
-        rh.type = RESPONSE_DIED;
-        rh.length = sizeof(rh);
+        assert(out_fd >= 0);
 
         if (send(out_fd, &rh, rh.length, MSG_NOSIGNAL) < 0)
                 return -errno;
@@ -234,7 +265,15 @@ static int send_addrinfo_reply(
                 int _errno,
                 int _h_errno) {
 
-        AddrInfoResponse resp = {};
+        AddrInfoResponse resp = {
+                .header.type = RESPONSE_ADDRINFO,
+                .header.id = id,
+                .header.length = sizeof(AddrInfoResponse),
+                .ret = ret,
+                ._errno = _errno,
+                ._h_errno = _h_errno,
+        };
+
         struct msghdr mh = {};
         struct iovec iov[2];
         union {
@@ -244,13 +283,6 @@ static int send_addrinfo_reply(
 
         assert(out_fd >= 0);
 
-        resp.header.type = RESPONSE_ADDRINFO;
-        resp.header.id = id;
-        resp.header.length = sizeof(AddrInfoResponse);
-        resp.ret = ret;
-        resp._errno = _errno;
-        resp._h_errno = _h_errno;
-
         if (ret == 0 && ai) {
                 void *p = &buffer;
                 struct addrinfo *k;
@@ -288,7 +320,14 @@ static int send_nameinfo_reply(
                 int _errno,
                 int _h_errno) {
 
-        NameInfoResponse resp = {};
+        NameInfoResponse resp = {
+                .header.type = RESPONSE_NAMEINFO,
+                .header.id = id,
+                .ret = ret,
+                ._errno = _errno,
+                ._h_errno = _h_errno,
+        };
+
         struct msghdr mh = {};
         struct iovec iov[3];
         size_t hl, sl;
@@ -298,12 +337,7 @@ static int send_nameinfo_reply(
         sl = serv ? strlen(serv)+1 : 0;
         hl = host ? strlen(host)+1 : 0;
 
-        resp.header.type = RESPONSE_NAMEINFO;
-        resp.header.id = id;
         resp.header.length = sizeof(NameInfoResponse) + hl + sl;
-        resp.ret = ret;
-        resp._errno = _errno;
-        resp._h_errno = _h_errno;
         resp.hostlen = hl;
         resp.servlen = sl;
 
@@ -321,21 +355,24 @@ static int send_nameinfo_reply(
 }
 
 static int send_res_reply(int out_fd, unsigned id, const unsigned char *answer, int ret, int _errno, int _h_errno) {
+
+        ResResponse resp = {
+                .header.type = RESPONSE_RES,
+                .header.id = id,
+                .ret = ret,
+                ._errno = _errno,
+                ._h_errno = _h_errno,
+        };
+
         struct msghdr mh = {};
         struct iovec iov[2];
-        ResResponse resp = {};
         size_t l;
 
         assert(out_fd >= 0);
 
         l = ret > 0 ? (size_t) ret : 0;
 
-        resp.header.type = RESPONSE_RES;
-        resp.header.id = id;
         resp.header.length = sizeof(ResResponse) + l;
-        resp.ret = ret;
-        resp._errno = _errno;
-        resp._h_errno = _h_errno;
 
         iov[0] = (struct iovec) { .iov_base = &resp, .iov_len = sizeof(ResResponse) };
         iov[1] = (struct iovec) { .iov_base = (void*) answer, .iov_len = l };
@@ -489,12 +526,8 @@ static int start_threads(sd_resolve *resolve, unsigned extra) {
         unsigned n;
         int r;
 
-        n = resolve->n_queries - resolve->n_done + extra;
-
-        if (n < WORKERS_MIN)
-                n = WORKERS_MIN;
-        if (n > WORKERS_MAX)
-                n = WORKERS_MAX;
+        n = resolve->n_outstanding + extra;
+        n = CLAMP(n, WORKERS_MIN, WORKERS_MAX);
 
         while (resolve->n_valid_workers < n) {
 
@@ -527,11 +560,12 @@ _public_ int sd_resolve_new(sd_resolve **ret) {
         if (!resolve)
                 return -ENOMEM;
 
+        resolve->n_ref = 1;
+        resolve->original_pid = getpid();
+
         for (i = 0; i < _FD_MAX; i++)
                 resolve->fds[i] = -1;
 
-        resolve->original_pid = getpid();
-
         r = socketpair(PF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0, resolve->fds + REQUEST_RECV_FD);
         if (r < 0) {
                 r = -errno;
@@ -555,22 +589,72 @@ _public_ int sd_resolve_new(sd_resolve **ret) {
         return 0;
 
 fail:
-        if (resolve)
-                sd_resolve_unref(resolve);
-
+        sd_resolve_unref(resolve);
         return r;
 }
 
-_public_ sd_resolve* sd_resolve_unref(sd_resolve *resolve) {
-        PROTECT_ERRNO;
+_public_ int sd_resolve_default(sd_resolve **ret) {
+
+        static thread_local sd_resolve *default_resolve = NULL;
+        sd_resolve *e = NULL;
+        int r;
+
+        if (!ret)
+                return !!default_resolve;
+
+        if (default_resolve) {
+                *ret = sd_resolve_ref(default_resolve);
+                return 0;
+        }
 
+        r = sd_resolve_new(&e);
+        if (r < 0)
+                return r;
+
+        e->default_resolve_ptr = &default_resolve;
+        e->tid = gettid();
+        default_resolve = e;
+
+        *ret = e;
+        return 1;
+}
+
+_public_ int sd_resolve_get_tid(sd_resolve *resolve, pid_t *tid) {
+        assert_return(resolve, -EINVAL);
+        assert_return(tid, -EINVAL);
+        assert_return(!resolve_pid_changed(resolve), -ECHILD);
+
+        if (resolve->tid != 0) {
+                *tid = resolve->tid;
+                return 0;
+        }
+
+        if (resolve->event)
+                return sd_event_get_tid(resolve->event, tid);
+
+        return -ENXIO;
+}
+
+static void resolve_free(sd_resolve *resolve) {
+        PROTECT_ERRNO;
+        sd_resolve_query *q;
         unsigned i;
 
-        assert_return(resolve, NULL);
-        assert_return(!resolve_pid_changed(resolve), NULL);
+        assert(resolve);
+
+        while ((q = resolve->queries)) {
+                assert(q->floating);
+                resolve_query_disconnect(q);
+                sd_resolve_query_unref(q);
+        }
+
+        if (resolve->default_resolve_ptr)
+                *(resolve->default_resolve_ptr) = NULL;
 
         resolve->dead = true;
 
+        sd_resolve_detach_event(resolve);
+
         if (resolve->fds[REQUEST_SEND_FD] >= 0) {
 
                 RHeader req = {
@@ -593,14 +677,31 @@ _public_ sd_resolve* sd_resolve_unref(sd_resolve *resolve) {
 
         /* Close all communication channels */
         for (i = 0; i < _FD_MAX; i++)
-                if (resolve->fds[i] >= 0)
-                        close_nointr_nofail(resolve->fds[i]);
-
-        for (i = 0; i < QUERIES_MAX && resolve->n_queries > 0; i++)
-                if (resolve->queries[i])
-                        sd_resolve_cancel(resolve->queries[i]);
+                safe_close(resolve->fds[i]);
 
         free(resolve);
+}
+
+_public_ sd_resolve* sd_resolve_ref(sd_resolve *resolve) {
+        assert_return(resolve, NULL);
+
+        assert(resolve->n_ref >= 1);
+        resolve->n_ref++;
+
+        return resolve;
+}
+
+_public_ sd_resolve* sd_resolve_unref(sd_resolve *resolve) {
+
+        if (!resolve)
+                return NULL;
+
+        assert(resolve->n_ref >= 1);
+        resolve->n_ref--;
+
+        if (resolve->n_ref <= 0)
+                resolve_free(resolve);
+
         return NULL;
 }
 
@@ -632,7 +733,7 @@ static sd_resolve_query *lookup_query(sd_resolve *resolve, unsigned id) {
 
         assert(resolve);
 
-        q = resolve->queries[id % QUERIES_MAX];
+        q = resolve->query_array[id % QUERIES_MAX];
         if (q)
                 if (q->id == id)
                         return q;
@@ -640,13 +741,47 @@ static sd_resolve_query *lookup_query(sd_resolve *resolve, unsigned id) {
         return NULL;
 }
 
-static void complete_query(sd_resolve_query *q) {
+static int complete_query(sd_resolve *resolve, sd_resolve_query *q) {
+        int r;
+
         assert(q);
         assert(!q->done);
+        assert(q->resolve == resolve);
 
         q->done = true;
-        LIST_PREPEND(done, q->resolve->done, q);
-        q->resolve->n_done ++;
+        resolve->n_done ++;
+
+        resolve->current = sd_resolve_query_ref(q);
+
+        switch (q->type) {
+
+        case REQUEST_ADDRINFO:
+                r = getaddrinfo_done(q);
+                break;
+
+        case REQUEST_NAMEINFO:
+                r = getnameinfo_done(q);
+                break;
+
+        case REQUEST_RES_QUERY:
+        case REQUEST_RES_SEARCH:
+                r = res_query_done(q);
+                break;
+
+        default:
+                assert_not_reached("Cannot complete unknown query type");
+        }
+
+        resolve->current = NULL;
+
+        if (q->floating) {
+                resolve_query_disconnect(q);
+                sd_resolve_query_unref(q);
+        }
+
+        sd_resolve_query_unref(q);
+
+        return r;
 }
 
 static int unserialize_addrinfo(const void **p, size_t *length, struct addrinfo **ret_ai) {
@@ -719,6 +854,9 @@ static int handle_response(sd_resolve *resolve, const Packet *packet, size_t len
                 return 0;
         }
 
+        assert(resolve->n_outstanding > 0);
+        resolve->n_outstanding--;
+
         q = lookup_query(resolve, resp->id);
         if (!q)
                 return 0;
@@ -762,8 +900,7 @@ static int handle_response(sd_resolve *resolve, const Packet *packet, size_t len
                         prev = ai;
                 }
 
-                complete_query(q);
-                break;
+                return complete_query(resolve, q);
         }
 
         case RESPONSE_NAMEINFO: {
@@ -794,8 +931,7 @@ static int handle_response(sd_resolve *resolve, const Packet *packet, size_t len
                         }
                 }
 
-                complete_query(q);
-                break;
+                return complete_query(resolve, q);
         }
 
         case RESPONSE_RES: {
@@ -809,54 +945,53 @@ static int handle_response(sd_resolve *resolve, const Packet *packet, size_t len
                 q->_h_errno = res_resp->_h_errno;
 
                 if (res_resp->ret >= 0)  {
-                        q->serv = memdup((const char *)resp + sizeof(ResResponse), res_resp->ret);
-                        if (!q->serv) {
+                        q->answer = memdup((const char *)resp + sizeof(ResResponse), res_resp->ret);
+                        if (!q->answer) {
                                 q->ret = -1;
                                 q->_errno = ENOMEM;
                                 q->_h_errno = 0;
                         }
                 }
 
-                complete_query(q);
-                break;
+                return complete_query(resolve, q);
         }
 
         default:
-                ;
+                return 0;
         }
-
-        return 0;
 }
 
 _public_ int sd_resolve_process(sd_resolve *resolve) {
-        int n_processed = 0, r;
+        RESOLVE_DONT_DESTROY(resolve);
+
+        union {
+                Packet packet;
+                uint8_t space[BUFSIZE];
+        } buf;
+        ssize_t l;
+        int r;
 
         assert_return(resolve, -EINVAL);
         assert_return(!resolve_pid_changed(resolve), -ECHILD);
 
-        for (;;) {
-                ssize_t l;
-                union {
-                        Packet packet;
-                        uint8_t space[BUFSIZE];
-                } buf;
+        /* We don't allow recursively invoking sd_resolve_process(). */
+        assert_return(!resolve->current, -EBUSY);
 
-                l = recv(resolve->fds[RESPONSE_RECV_FD], &buf, sizeof(buf), 0);
-                if (l < 0) {
-                        if (errno == EAGAIN)
-                                return n_processed;
+        l = recv(resolve->fds[RESPONSE_RECV_FD], &buf, sizeof(buf), 0);
+        if (l < 0) {
+                if (errno == EAGAIN)
+                        return 0;
 
-                        return -errno;
-                }
-                if (l == 0)
-                        return -ECONNREFUSED;
+                return -errno;
+        }
+        if (l == 0)
+                return -ECONNREFUSED;
 
-                r = handle_response(resolve, &buf.packet, (size_t) l);
-                if (r < 0)
-                        return r;
+        r = handle_response(resolve, &buf.packet, (size_t) l);
+        if (r < 0)
+                return r;
 
-                n_processed++;
-        }
+        return 1;
 }
 
 _public_ int sd_resolve_wait(sd_resolve *resolve, uint64_t timeout_usec) {
@@ -865,7 +1000,7 @@ _public_ int sd_resolve_wait(sd_resolve *resolve, uint64_t timeout_usec) {
         assert_return(resolve, -EINVAL);
         assert_return(!resolve_pid_changed(resolve), -ECHILD);
 
-        if (resolve->n_queries <= 0)
+        if (resolve->n_done >= resolve->n_queries)
                 return 0;
 
         do {
@@ -878,7 +1013,7 @@ _public_ int sd_resolve_wait(sd_resolve *resolve, uint64_t timeout_usec) {
         return sd_resolve_process(resolve);
 }
 
-static int alloc_query(sd_resolve *resolve, sd_resolve_query **_q) {
+static int alloc_query(sd_resolve *resolve, bool floating, sd_resolve_query **_q) {
         sd_resolve_query *q;
         int r;
 
@@ -892,21 +1027,23 @@ static int alloc_query(sd_resolve *resolve, sd_resolve_query **_q) {
         if (r < 0)
                 return r;
 
-        while (resolve->queries[resolve->current_index]) {
-                resolve->current_index++;
+        while (resolve->query_array[resolve->current_id % QUERIES_MAX])
                 resolve->current_id++;
 
-                resolve->current_index %= QUERIES_MAX;
-        }
-
-        q = resolve->queries[resolve->current_index] = new0(sd_resolve_query, 1);
+        q = resolve->query_array[resolve->current_id % QUERIES_MAX] = new0(sd_resolve_query, 1);
         if (!q)
                 return -ENOMEM;
 
-        resolve->n_queries++;
-
+        q->n_ref = 1;
         q->resolve = resolve;
-        q->id = resolve->current_id;
+        q->floating = floating;
+        q->id = resolve->current_id++;
+
+        if (!floating)
+                sd_resolve_ref(resolve);
+
+        LIST_PREPEND(queries, resolve->queries, q);
+        resolve->n_queries++;
 
         *_q = q;
         return 0;
@@ -915,9 +1052,9 @@ static int alloc_query(sd_resolve *resolve, sd_resolve_query **_q) {
 _public_ int sd_resolve_getaddrinfo(
                 sd_resolve *resolve,
                 sd_resolve_query **_q,
-                const char *node,
-                const char *service,
-                const struct addrinfo *hints) {
+                const char *node, const char *service,
+                const struct addrinfo *hints,
+                sd_resolve_getaddrinfo_handler_t callback, void *userdata) {
 
         AddrInfoRequest req = {};
         struct msghdr mh = {};
@@ -927,18 +1064,22 @@ _public_ int sd_resolve_getaddrinfo(
 
         assert_return(resolve, -EINVAL);
         assert_return(node || service, -EINVAL);
-        assert_return(_q, -EINVAL);
+        assert_return(callback, -EINVAL);
         assert_return(!resolve_pid_changed(resolve), -ECHILD);
 
-        r = alloc_query(resolve, &q);
+        r = alloc_query(resolve, !_q, &q);
         if (r < 0)
                 return r;
 
+        q->type = REQUEST_ADDRINFO;
+        q->getaddrinfo_handler = callback;
+        q->userdata = userdata;
+
         req.node_len = node ? strlen(node)+1 : 0;
         req.service_len = service ? strlen(service)+1 : 0;
 
         req.header.id = q->id;
-        req.header.type = q->type = REQUEST_ADDRINFO;
+        req.header.type = REQUEST_ADDRINFO;
         req.header.length = sizeof(AddrInfoRequest) + req.node_len + req.service_len;
 
         if (hints) {
@@ -950,59 +1091,34 @@ _public_ int sd_resolve_getaddrinfo(
         }
 
         iov[mh.msg_iovlen++] = (struct iovec) { .iov_base = &req, .iov_len = sizeof(AddrInfoRequest) };
-
         if (node)
                 iov[mh.msg_iovlen++] = (struct iovec) { .iov_base = (void*) node, .iov_len = req.node_len };
-
         if (service)
                 iov[mh.msg_iovlen++] = (struct iovec) { .iov_base = (void*) service, .iov_len = req.service_len };
-
         mh.msg_iov = iov;
 
         if (sendmsg(resolve->fds[REQUEST_SEND_FD], &mh, MSG_NOSIGNAL) < 0) {
-                sd_resolve_cancel(q);
+                sd_resolve_query_unref(q);
                 return -errno;
         }
 
-        *_q = q;
-        return 0;
-}
-
-_public_ int sd_resolve_getaddrinfo_done(sd_resolve_query* q, struct addrinfo **ret_res) {
-        int ret;
+        resolve->n_outstanding++;
 
-        if (!q) {
-                errno = EINVAL;
-                return EAI_SYSTEM;
-        }
+        if (_q)
+                *_q = q;
 
-        if (q->type != REQUEST_ADDRINFO) {
-                errno = ENOTTY;
-                return EAI_SYSTEM;
-        }
-
-        if (resolve_pid_changed(q->resolve)) {
-                errno = ECHILD;
-                return EAI_SYSTEM;
-        }
-        if (!q->done)
-                return EAI_AGAIN;
-
-        if (ret_res) {
-                *ret_res = q->addrinfo;
-                q->addrinfo = NULL;
-        }
-
-        ret = q->ret;
+        return 0;
+}
 
-        if (ret != 0) {
-                errno = q->_errno;
-                h_errno = q->_h_errno;
-        }
+static int getaddrinfo_done(sd_resolve_query* q) {
+        assert(q);
+        assert(q->done);
+        assert(q->getaddrinfo_handler);
 
-        sd_resolve_cancel(q);
+        errno = q->_errno;
+        h_errno = q->_h_errno;
 
-        return ret;
+        return q->getaddrinfo_handler(q, q->ret, q->addrinfo, q->userdata);
 }
 
 _public_ int sd_resolve_getnameinfo(
@@ -1010,7 +1126,9 @@ _public_ int sd_resolve_getnameinfo(
                 sd_resolve_query**_q,
                 const struct sockaddr *sa, socklen_t salen,
                 int flags,
-                int gethost, int getserv) {
+                uint64_t get,
+                sd_resolve_getnameinfo_handler_t callback,
+                void *userdata) {
 
         NameInfoRequest req = {};
         struct msghdr mh = {};
@@ -1022,21 +1140,26 @@ _public_ int sd_resolve_getnameinfo(
         assert_return(sa, -EINVAL);
         assert_return(salen >= sizeof(struct sockaddr), -EINVAL);
         assert_return(salen <= sizeof(union sockaddr_union), -EINVAL);
-        assert_return(_q, -EINVAL);
+        assert_return((get & ~SD_RESOLVE_GET_BOTH) == 0, -EINVAL);
+        assert_return(callback, -EINVAL);
         assert_return(!resolve_pid_changed(resolve), -ECHILD);
 
-        r = alloc_query(resolve, &q);
+        r = alloc_query(resolve, !_q, &q);
         if (r < 0)
                 return r;
 
+        q->type = REQUEST_NAMEINFO;
+        q->getnameinfo_handler = callback;
+        q->userdata = userdata;
+
         req.header.id = q->id;
-        req.header.type = q->type = REQUEST_NAMEINFO;
+        req.header.type = REQUEST_NAMEINFO;
         req.header.length = sizeof(NameInfoRequest) + salen;
 
         req.flags = flags;
         req.sockaddr_len = salen;
-        req.gethost = !!gethost;
-        req.getserv = !!getserv;
+        req.gethost = !!(get & SD_RESOLVE_GET_HOST);
+        req.getserv = !!(get & SD_RESOLVE_GET_SERVICE);
 
         iov[0] = (struct iovec) { .iov_base = &req, .iov_len = sizeof(NameInfoRequest) };
         iov[1] = (struct iovec) { .iov_base = (void*) sa, .iov_len = salen };
@@ -1045,55 +1168,28 @@ _public_ int sd_resolve_getnameinfo(
         mh.msg_iovlen = 2;
 
         if (sendmsg(resolve->fds[REQUEST_SEND_FD], &mh, MSG_NOSIGNAL) < 0) {
-                sd_resolve_cancel(q);
+                sd_resolve_query_unref(q);
                 return -errno;
         }
 
-        *_q = q;
-        return 0;
-}
-
-_public_ int sd_resolve_getnameinfo_done(sd_resolve_query* q, char **ret_host, char **ret_serv) {
-        int ret;
-
-        if (!q) {
-                errno = EINVAL;
-                return EAI_SYSTEM;
-        }
-
-        if (q->type != REQUEST_NAMEINFO) {
-                errno = ENOTTY;
-                return EAI_SYSTEM;
-        }
+        resolve->n_outstanding++;
 
-        if (resolve_pid_changed(q->resolve)) {
-                errno = ECHILD;
-                return EAI_SYSTEM;
-        }
-
-        if (!q->done)
-                return EAI_AGAIN;
-
-        if (ret_host) {
-                *ret_host = q->host;
-                q->host = NULL;
-        }
+        if (_q)
+                *_q = q;
 
-        if (ret_serv) {
-                *ret_serv = q->serv;
-                q->serv = NULL;
-        }
+        return 0;
+}
 
-        ret = q->ret;
+static int getnameinfo_done(sd_resolve_query *q) {
 
-        if (ret != 0) {
-                errno = q->_errno;
-                h_errno = q->_h_errno;
-        }
+        assert(q);
+        assert(q->done);
+        assert(q->getnameinfo_handler);
 
-        sd_resolve_cancel(q);
+        errno = q->_errno;
+        h_errno= q->_h_errno;
 
-        return ret;
+        return q->getnameinfo_handler(q, q->ret, q->host, q->serv, q->userdata);
 }
 
 static int resolve_res(
@@ -1101,7 +1197,8 @@ static int resolve_res(
                 sd_resolve_query **_q,
                 QueryType qtype,
                 const char *dname,
-                int class, int type) {
+                int class, int type,
+                sd_resolve_res_handler_t callback, void *userdata) {
 
         struct msghdr mh = {};
         struct iovec iov[2];
@@ -1111,19 +1208,23 @@ static int resolve_res(
 
         assert_return(resolve, -EINVAL);
         assert_return(dname, -EINVAL);
-        assert_return(_q, -EINVAL);
+        assert_return(callback, -EINVAL);
         assert_return(!resolve_pid_changed(resolve), -ECHILD);
 
-        r = alloc_query(resolve, &q);
+        r = alloc_query(resolve, !_q, &q);
         if (r < 0)
                 return r;
 
+        q->type = qtype;
+        q->res_handler = callback;
+        q->userdata = userdata;
+
         req.dname_len = strlen(dname) + 1;
         req.class = class;
         req.type = type;
 
         req.header.id = q->id;
-        req.header.type = q->type = qtype;
+        req.header.type = qtype;
         req.header.length = sizeof(ResRequest) + req.dname_len;
 
         iov[0] = (struct iovec) { .iov_base = &req, .iov_len = sizeof(ResRequest) };
@@ -1133,115 +1234,118 @@ static int resolve_res(
         mh.msg_iovlen = 2;
 
         if (sendmsg(resolve->fds[REQUEST_SEND_FD], &mh, MSG_NOSIGNAL) < 0) {
-                sd_resolve_cancel(q);
+                sd_resolve_query_unref(q);
                 return -errno;
         }
 
-        *_q = q;
+        resolve->n_outstanding++;
+
+        if (_q)
+                *_q = q;
+
         return 0;
 }
 
-_public_ int sd_resolve_res_query(sd_resolve *resolve, sd_resolve_query** q, const char *dname, int class, int type) {
-        return resolve_res(resolve, q, REQUEST_RES_QUERY, dname, class, type);
+_public_ int sd_resolve_res_query(sd_resolve *resolve, sd_resolve_query** q, const char *dname, int class, int type, sd_resolve_res_handler_t callback, void *userdata) {
+        return resolve_res(resolve, q, REQUEST_RES_QUERY, dname, class, type, callback, userdata);
 }
 
-_public_ int sd_resolve_res_search(sd_resolve *resolve, sd_resolve_query** q, const char *dname, int class, int type) {
-        return resolve_res(resolve, q, REQUEST_RES_SEARCH, dname, class, type);
+_public_ int sd_resolve_res_search(sd_resolve *resolve, sd_resolve_query** q, const char *dname, int class, int type, sd_resolve_res_handler_t callback, void *userdata) {
+        return resolve_res(resolve, q, REQUEST_RES_SEARCH, dname, class, type, callback, userdata);
 }
 
-_public_ int sd_resolve_res_done(sd_resolve_query* q, unsigned char **answer) {
-        int ret;
-
-        assert_return(q, -EINVAL);
-        assert_return(answer, -EINVAL);
-        assert_return(q->type == REQUEST_RES_QUERY || q->type == REQUEST_RES_SEARCH, -ENOTTY);
-        assert_return(!resolve_pid_changed(q->resolve), -ECHILD);
-
-        if (!q->done)
-                return -EAGAIN;
+static int res_query_done(sd_resolve_query* q) {
+        assert(q);
+        assert(q->done);
+        assert(q->res_handler);
 
-        *answer = (unsigned char *) q->serv;
-        q->serv = NULL;
+        errno = q->_errno;
+        h_errno = q->_h_errno;
 
-        ret = q->ret;
+        return q->res_handler(q, q->ret, q->answer, q->userdata);
+}
 
-        if (ret != 0) {
-                errno = q->_errno;
-                h_errno = q->_h_errno;
-        }
+_public_ sd_resolve_query* sd_resolve_query_ref(sd_resolve_query *q) {
+        assert_return(q, NULL);
 
-        sd_resolve_cancel(q);
+        assert(q->n_ref >= 1);
+        q->n_ref++;
 
-        return ret < 0 ? -errno : ret;
+        return q;
 }
 
-_public_ int sd_resolve_get_next(sd_resolve *resolve, sd_resolve_query **q) {
-        assert_return(resolve, -EINVAL);
-        assert_return(q, -EINVAL);
-        assert_return(!resolve_pid_changed(resolve), -ECHILD);
+static void resolve_freeaddrinfo(struct addrinfo *ai) {
+        while (ai) {
+                struct addrinfo *next = ai->ai_next;
 
-        *q = resolve->done;
-        return !!resolve->done;
+                free(ai->ai_addr);
+                free(ai->ai_canonname);
+                free(ai);
+                ai = next;
+        }
 }
 
-_public_ int sd_resolve_get_n_queries(sd_resolve *resolve) {
-        assert_return(resolve, -EINVAL);
-        assert_return(!resolve_pid_changed(resolve), -ECHILD);
-
-        return resolve->n_queries;
-}
+static void resolve_query_disconnect(sd_resolve_query *q) {
+        sd_resolve *resolve;
+        unsigned i;
 
-_public_ int sd_resolve_cancel(sd_resolve_query* q) {
-        PROTECT_ERRNO;
-        int i;
+        assert(q);
 
-        if (!q)
-                return 0;
+        if (!q->resolve)
+                return;
 
-        assert_return(!resolve_pid_changed(q->resolve), -ECHILD);
-
-        assert(q->resolve);
-        assert(q->resolve->n_queries > 0);
+        resolve = q->resolve;
+        assert(resolve->n_queries > 0);
 
         if (q->done) {
-                LIST_REMOVE(done, q->resolve->done, q);
-                q->resolve->n_done--;
+                assert(resolve->n_done > 0);
+                resolve->n_done--;
         }
 
         i = q->id % QUERIES_MAX;
-        assert(q->resolve->queries[i] == q);
-        q->resolve->queries[i] = NULL;
-        q->resolve->n_queries--;
+        assert(resolve->query_array[i] == q);
+        resolve->query_array[i] = NULL;
+        LIST_REMOVE(queries, resolve->queries, q);
+        resolve->n_queries--;
 
-        sd_resolve_freeaddrinfo(q->addrinfo);
+        q->resolve = NULL;
+        if (!q->floating)
+                sd_resolve_unref(resolve);
+}
+
+static void resolve_query_free(sd_resolve_query *q) {
+        assert(q);
+
+        resolve_query_disconnect(q);
+
+        resolve_freeaddrinfo(q->addrinfo);
         free(q->host);
         free(q->serv);
+        free(q->answer);
         free(q);
-
-        return 0;
 }
 
-_public_ void sd_resolve_freeaddrinfo(struct addrinfo *ai) {
+_public_ sd_resolve_query* sd_resolve_query_unref(sd_resolve_query* q) {
+        if (!q)
+                return NULL;
 
-        while (ai) {
-                struct addrinfo *next = ai->ai_next;
+        assert(q->n_ref >= 1);
+        q->n_ref--;
 
-                free(ai->ai_addr);
-                free(ai->ai_canonname);
-                free(ai);
+        if (q->n_ref <= 0)
+                resolve_query_free(q);
 
-                ai = next;
-        }
+        return NULL;
 }
 
-_public_ int sd_resolve_is_done(sd_resolve_query *q) {
+_public_ int sd_resolve_query_is_done(sd_resolve_query *q) {
         assert_return(q, -EINVAL);
         assert_return(!resolve_pid_changed(q->resolve), -ECHILD);
 
         return q->done;
 }
 
-_public_ void* sd_resolve_set_userdata(sd_resolve_query *q, void *userdata) {
+_public_ void* sd_resolve_query_set_userdata(sd_resolve_query *q, void *userdata) {
         void *ret;
 
         assert_return(q, NULL);
@@ -1253,9 +1357,81 @@ _public_ void* sd_resolve_set_userdata(sd_resolve_query *q, void *userdata) {
         return ret;
 }
 
-_public_ void* sd_resolve_get_userdata(sd_resolve_query *q) {
+_public_ void* sd_resolve_query_get_userdata(sd_resolve_query *q) {
         assert_return(q, NULL);
         assert_return(!resolve_pid_changed(q->resolve), NULL);
 
         return q->userdata;
 }
+
+_public_ sd_resolve *sd_resolve_query_get_resolve(sd_resolve_query *q) {
+        assert_return(q, NULL);
+        assert_return(!resolve_pid_changed(q->resolve), NULL);
+
+        return q->resolve;
+}
+
+static int io_callback(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
+        sd_resolve *resolve = userdata;
+        int r;
+
+        assert(resolve);
+
+        r = sd_resolve_process(resolve);
+        if (r < 0)
+                return r;
+
+        return 1;
+}
+
+_public_ int sd_resolve_attach_event(sd_resolve *resolve, sd_event *event, int priority) {
+        int r;
+
+        assert_return(resolve, -EINVAL);
+        assert_return(!resolve->event, -EBUSY);
+
+        assert(!resolve->event_source);
+
+        if (event)
+                resolve->event = sd_event_ref(event);
+        else {
+                r = sd_event_default(&resolve->event);
+                if (r < 0)
+                        return r;
+        }
+
+        r = sd_event_add_io(resolve->event, &resolve->event_source, resolve->fds[RESPONSE_RECV_FD], POLLIN, io_callback, resolve);
+        if (r < 0)
+                goto fail;
+
+        r = sd_event_source_set_priority(resolve->event_source, priority);
+        if (r < 0)
+                goto fail;
+
+        return 0;
+
+fail:
+        sd_resolve_detach_event(resolve);
+        return r;
+}
+
+_public_  int sd_resolve_detach_event(sd_resolve *resolve) {
+        assert_return(resolve, -EINVAL);
+
+        if (!resolve->event)
+                return 0;
+
+        if (resolve->event_source) {
+                sd_event_source_set_enabled(resolve->event_source, SD_EVENT_OFF);
+                resolve->event_source = sd_event_source_unref(resolve->event_source);
+        }
+
+        resolve->event = sd_event_unref(resolve->event);
+        return 1;
+}
+
+_public_ sd_event *sd_resolve_get_event(sd_resolve *resolve) {
+        assert_return(resolve, NULL);
+
+        return resolve->event;
+}
index d3b2d55..c6c3bfb 100644 (file)
@@ -4,6 +4,7 @@
   This file is part of systemd.
 
   Copyright 2005-2008 Lennart Poettering
+  Copyright 2014 Daniel Buch
 
   systemd is free software; you can redistribute it and/or modify it
   under the terms of the GNU Lesser General Public License as published by
 #include <signal.h>
 #include <errno.h>
 
+#include "socket-util.h"
 #include "sd-resolve.h"
 #include "resolve-util.h"
 #include "macro.h"
 
+static int getaddrinfo_handler(sd_resolve_query *q, int ret, const struct addrinfo *ai, void *userdata) {
+        const struct addrinfo *i;
+
+        assert(q);
+
+        if (ret != 0) {
+                log_error("getaddrinfo error: %s %i\n", gai_strerror(ret), ret);
+                return 0;
+        }
+
+        for (i = ai; i; i = i->ai_next) {
+                _cleanup_free_ char *addr = NULL;
+
+                assert_se(sockaddr_pretty(i->ai_addr, i->ai_addrlen, false, &addr) == 0);
+                puts(addr);
+        }
+
+        printf("canonical name: %s\n", strna(ai->ai_canonname));
+
+        return 0;
+}
+
+static int getnameinfo_handler(sd_resolve_query *q, int ret, const char *host, const char *serv, void *userdata) {
+        assert(q);
+
+        if (ret != 0) {
+                log_error("getnameinfo error: %s %i\n", gai_strerror(ret), ret);
+                return 0;
+        }
+
+        printf("Host: %s -- Serv: %s\n", strna(host), strna(serv));
+        return 0;
+}
+
+static int res_handler(sd_resolve_query *q, int ret, unsigned char *answer, void *userdata) {
+        int qdcount, ancount, len;
+        const unsigned char *pos = answer + sizeof(HEADER);
+        unsigned char *end = answer + ret;
+        HEADER *head = (HEADER *) answer;
+        char name[256];
+        assert(q);
+
+        if (ret < 0) {
+                log_error("res_query() error: %s %i\n", strerror(errno), errno);
+                return 0;
+        }
+
+        if (ret == 0) {
+                log_error("No reply for SRV lookup\n");
+                return 0;
+        }
+
+        qdcount = ntohs(head->qdcount);
+        ancount = ntohs(head->ancount);
+
+        printf("%d answers for srv lookup:\n", ancount);
+
+        /* Ignore the questions */
+        while (qdcount-- > 0 && (len = dn_expand(answer, end, pos, name, 255)) >= 0) {
+                assert(len >= 0);
+                pos += len + QFIXEDSZ;
+        }
+
+        /* Parse the answers */
+        while (ancount-- > 0 && (len = dn_expand(answer, end, pos, name, 255)) >= 0) {
+                /* Ignore the initial string */
+                uint16_t pref, weight, port;
+                assert(len >= 0);
+                pos += len;
+                /* Ignore type, ttl, class and dlen */
+                pos += 10;
+
+                GETSHORT(pref, pos);
+                GETSHORT(weight, pos);
+                GETSHORT(port, pos);
+                len = dn_expand(answer, end, pos, name, 255);
+                printf("\tpreference: %2d weight: %2d port: %d host: %s\n",
+                       pref, weight, port, name);
+
+                pos += len;
+        }
+
+        return 0;
+}
+
 int main(int argc, char *argv[]) {
-        int r = 1;
+        _cleanup_resolve_query_unref_ sd_resolve_query *q1 = NULL, *q2 = NULL, *q3 = NULL;
         _cleanup_resolve_unref_ sd_resolve *resolve = NULL;
-        _cleanup_resolve_addrinfo_free_ struct addrinfo *ai = NULL;
-        _cleanup_free_ unsigned char *srv = NULL;
-        sd_resolve_query *q1 = NULL, *q2 = NULL, *q3 = NULL;
-        struct addrinfo hints = {};
-        struct sockaddr_in sa = {};
-        _cleanup_free_ char *host = NULL, *serv = NULL;
+        int r = 0;
 
-        assert_se(sd_resolve_new(&resolve) >= 0);
+        struct addrinfo hints = {
+                .ai_family = PF_UNSPEC,
+                .ai_socktype = SOCK_STREAM,
+                .ai_flags = AI_CANONNAME
+        };
 
-        /* Make a name -> address query */
-        hints.ai_family = PF_UNSPEC;
-        hints.ai_socktype = SOCK_STREAM;
-        hints.ai_flags = AI_CANONNAME;
+        struct sockaddr_in sa = {
+                .sin_family = AF_INET,
+                .sin_port = htons(80)
+        };
+
+        assert_se(sd_resolve_default(&resolve) >= 0);
+
+        /* Test a floating resolver query */
+        sd_resolve_getaddrinfo(resolve, NULL, "redhat.com", "http", NULL, getaddrinfo_handler, NULL);
 
-        r = sd_resolve_getaddrinfo(resolve, &q1, argc >= 2 ? argv[1] : "www.heise.de", NULL, &hints);
+        /* Make a name -> address query */
+        r = sd_resolve_getaddrinfo(resolve, &q1, argc >= 2 ? argv[1] : "www.heise.de", NULL, &hints, getaddrinfo_handler, NULL);
         if (r < 0)
                 log_error("sd_resolve_getaddrinfo(): %s\n", strerror(-r));
 
         /* Make an address -> name query */
-        sa.sin_family = AF_INET;
         sa.sin_addr.s_addr = inet_addr(argc >= 3 ? argv[2] : "193.99.144.71");
-        sa.sin_port = htons(80);
-
-        r = sd_resolve_getnameinfo(resolve, &q2, (struct sockaddr*) &sa, sizeof(sa), 0, true, true);
+        r = sd_resolve_getnameinfo(resolve, &q2, (struct sockaddr*) &sa, sizeof(sa), 0, SD_RESOLVE_GET_BOTH, getnameinfo_handler, NULL);
         if (r < 0)
                 log_error("sd_resolve_getnameinfo(): %s\n", strerror(-r));
 
         /* Make a res_query() call */
-        r = sd_resolve_res_query(resolve, &q3, "_xmpp-client._tcp.gmail.com", C_IN, T_SRV);
+        r = sd_resolve_res_query(resolve, &q3, "_xmpp-client._tcp.gmail.com", C_IN, T_SRV, res_handler, NULL);
         if (r < 0)
                 log_error("sd_resolve_res_query(): %s\n", strerror(-r));
 
         /* Wait until the three queries are completed */
-        while (sd_resolve_is_done(q1) == 0 ||
-               sd_resolve_is_done(q2) == 0 ||
-               sd_resolve_is_done(q3) == 0) {
+        while (sd_resolve_query_is_done(q1) == 0 ||
+               sd_resolve_query_is_done(q2) == 0 ||
+               sd_resolve_query_is_done(q3) == 0) {
 
                 r = sd_resolve_wait(resolve, (uint64_t) -1);
                 if (r < 0) {
@@ -82,82 +171,5 @@ int main(int argc, char *argv[]) {
                 }
         }
 
-        /* Interpret the result of the name -> addr query */
-        r = sd_resolve_getaddrinfo_done(q1, &ai);
-        if (r != 0)
-                log_error("error: %s %i\n", gai_strerror(r), r);
-        else {
-                struct addrinfo *i;
-
-                for (i = ai; i; i = i->ai_next) {
-                        char t[256];
-                        const char *p = NULL;
-
-                        if (i->ai_family == PF_INET)
-                                p = inet_ntop(AF_INET, &((struct sockaddr_in*) i->ai_addr)->sin_addr, t, sizeof(t));
-                        else if (i->ai_family == PF_INET6)
-                                p = inet_ntop(AF_INET6, &((struct sockaddr_in6*) i->ai_addr)->sin6_addr, t, sizeof(t));
-
-                        printf("%s\n", p);
-                }
-
-                printf("canonical name: %s\n", strna(ai->ai_canonname));
-        }
-
-        /* Interpret the result of the addr -> name query */
-        r = sd_resolve_getnameinfo_done(q2, &host, &serv);
-        if (r)
-                log_error("error: %s %i\n", gai_strerror(r), r);
-        else
-                printf("%s -- %s\n", host, serv);
-
-        /* Interpret the result of the SRV lookup */
-        r = sd_resolve_res_done(q3, &srv);
-        if (r < 0)
-                log_error("error: %s %i\n", strerror(-r), r);
-        else if (r == 0)
-                log_error("No reply for SRV lookup\n");
-        else {
-                int qdcount;
-                int ancount;
-                int len;
-                const unsigned char *pos = srv + sizeof(HEADER);
-                unsigned char *end = srv + r;
-                HEADER *head = (HEADER *)srv;
-                char name[256];
-
-                qdcount = ntohs(head->qdcount);
-                ancount = ntohs(head->ancount);
-
-                printf("%d answers for srv lookup:\n", ancount);
-
-                /* Ignore the questions */
-                while (qdcount-- > 0 && (len = dn_expand(srv, end, pos, name, 255)) >= 0) {
-                        assert(len >= 0);
-                        pos += len + QFIXEDSZ;
-                }
-
-                /* Parse the answers */
-                while (ancount-- > 0 && (len = dn_expand(srv, end, pos, name, 255)) >= 0) {
-                        /* Ignore the initial string */
-                        uint16_t pref, weight, port;
-                        assert(len >= 0);
-                        pos += len;
-                        /* Ignore type, ttl, class and dlen */
-                        pos += 10;
-
-                        GETSHORT(pref, pos);
-                        GETSHORT(weight, pos);
-                        GETSHORT(port, pos);
-                        len = dn_expand(srv, end, pos, name, 255);
-                        printf("\tpreference: %2d weight: %2d port: %d host: %s\n",
-                                        pref, weight, port, name);
-
-                        pos += len;
-                }
-        }
-
-        r = 0;
-
-        return r;
+        return 0;
 }
diff --git a/src/libsystemd/sd-rtnl/local-addresses.c b/src/libsystemd/sd-rtnl/local-addresses.c
new file mode 100644 (file)
index 0000000..c550885
--- /dev/null
@@ -0,0 +1,160 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2008-2011 Lennart Poettering
+  Copyright 2014 Tom Gundersen
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "sd-rtnl.h"
+#include "rtnl-util.h"
+#include "macro.h"
+#include "local-addresses.h"
+
+static int address_compare(const void *_a, const void *_b) {
+        const struct local_address *a = _a, *b = _b;
+
+        /* Order lowest scope first, IPv4 before IPv6, lowest interface index first */
+
+        if (a->scope < b->scope)
+                return -1;
+        if (a->scope > b->scope)
+                return 1;
+
+        if (a->family == AF_INET && b->family == AF_INET6)
+                return -1;
+        if (a->family == AF_INET6 && b->family == AF_INET)
+                return 1;
+
+        if (a->ifindex < b->ifindex)
+                return -1;
+        if (a->ifindex > b->ifindex)
+                return 1;
+
+        return 0;
+}
+
+int local_addresses(sd_rtnl *context, int ifindex, struct local_address **ret) {
+        _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
+        _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
+        _cleanup_free_ struct local_address *list = NULL;
+        size_t n_list = 0, n_allocated = 0;
+        sd_rtnl_message *m;
+        int r;
+
+        assert(ret);
+
+        if (context)
+                rtnl = sd_rtnl_ref(context);
+        else {
+                r = sd_rtnl_open(&rtnl, 0);
+                if (r < 0)
+                        return r;
+        }
+
+        r = sd_rtnl_message_new_addr(rtnl, &req, RTM_GETADDR, 0, AF_UNSPEC);
+        if (r < 0)
+                return r;
+
+        r = sd_rtnl_call(rtnl, req, 0, &reply);
+        if (r < 0)
+                return r;
+
+        for (m = reply; m; m = sd_rtnl_message_next(m)) {
+                struct local_address *a;
+                unsigned char flags;
+                uint16_t type;
+                int ifi;
+
+                r = sd_rtnl_message_get_errno(m);
+                if (r < 0)
+                        return r;
+
+                r = sd_rtnl_message_get_type(m, &type);
+                if (r < 0)
+                        return r;
+
+                if (type != RTM_NEWADDR)
+                        continue;
+
+                r = sd_rtnl_message_addr_get_ifindex(m, &ifi);
+                if (r < 0)
+                        return r;
+
+                if (ifindex != 0 && ifi != ifindex)
+                        continue;
+
+                r = sd_rtnl_message_addr_get_flags(m, &flags);
+                if (r < 0)
+                        return r;
+
+                if (flags & IFA_F_DEPRECATED)
+                        continue;
+
+                if (!GREEDY_REALLOC(list, n_allocated, n_list+1))
+                        return -ENOMEM;
+
+                a = list + n_list;
+
+                r = sd_rtnl_message_addr_get_scope(m, &a->scope);
+                if (r < 0)
+                        return r;
+
+                if (ifindex == 0 && (a->scope == RT_SCOPE_HOST || a->scope == RT_SCOPE_NOWHERE))
+                        continue;
+
+                r = sd_rtnl_message_addr_get_family(m, &a->family);
+                if (r < 0)
+                        return r;
+
+                switch (a->family) {
+
+                case AF_INET:
+                        r = sd_rtnl_message_read_in_addr(m, IFA_LOCAL, &a->address.in);
+                        if (r < 0) {
+                                r = sd_rtnl_message_read_in_addr(m, IFA_ADDRESS, &a->address.in);
+                                if (r < 0)
+                                        continue;
+                        }
+                        break;
+
+                case AF_INET6:
+                        r = sd_rtnl_message_read_in6_addr(m, IFA_LOCAL, &a->address.in6);
+                        if (r < 0) {
+                                r = sd_rtnl_message_read_in6_addr(m, IFA_ADDRESS, &a->address.in6);
+                                if (r < 0)
+                                        continue;
+                        }
+                        break;
+
+                default:
+                        continue;
+                }
+
+                a->ifindex = ifi;
+
+                n_list++;
+        };
+
+        if (n_list)
+                qsort(list, n_list, sizeof(struct local_address), address_compare);
+
+        *ret = list;
+        list = NULL;
+
+        return (int) n_list;
+}
diff --git a/src/libsystemd/sd-rtnl/local-addresses.h b/src/libsystemd/sd-rtnl/local-addresses.h
new file mode 100644 (file)
index 0000000..b1ed634
--- /dev/null
@@ -0,0 +1,38 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2008-2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <inttypes.h>
+#include <sys/types.h>
+#include <assert.h>
+#include <sys/socket.h>
+
+#include "sd-rtnl.h"
+#include "in-addr-util.h"
+
+struct local_address {
+        int family, ifindex;
+        unsigned char scope;
+        union in_addr_union address;
+};
+
+int local_addresses(sd_rtnl *rtnl, int ifindex, struct local_address **ret);
index 0667be5..a192198 100644 (file)
@@ -29,7 +29,9 @@
 
 #include "sd-rtnl.h"
 
-#define RTNL_DEFAULT_TIMEOUT ((usec_t) (10 * USEC_PER_SEC))
+#include "rtnl-types.h"
+
+#define RTNL_DEFAULT_TIMEOUT ((usec_t) (25 * USEC_PER_SEC))
 
 #define RTNL_WQUEUE_MAX 1024
 #define RTNL_RQUEUE_MAX 64*1024
@@ -64,9 +66,18 @@ struct sd_rtnl {
 
         sd_rtnl_message **rqueue;
         unsigned rqueue_size;
+        size_t rqueue_allocated;
+
+        sd_rtnl_message **rqueue_partial;
+        unsigned rqueue_partial_size;
+        size_t rqueue_partial_allocated;
 
         sd_rtnl_message **wqueue;
         unsigned wqueue_size;
+        size_t wqueue_allocated;
+
+        struct nlmsghdr *rbuffer;
+        size_t rbuffer_allocated;
 
         bool processing:1;
 
@@ -91,17 +102,32 @@ struct sd_rtnl_message {
         sd_rtnl *rtnl;
 
         struct nlmsghdr *hdr;
+        const struct NLTypeSystem *(container_type_system[RTNL_CONTAINER_DEPTH]); /* the type of the container and all its parents */
         size_t container_offsets[RTNL_CONTAINER_DEPTH]; /* offset from hdr to each container's start */
         unsigned n_containers; /* number of containers */
         size_t next_rta_offset; /* offset from hdr to next rta */
-
+        size_t *rta_offset_tb[RTNL_CONTAINER_DEPTH];
+        unsigned short rta_tb_size[RTNL_CONTAINER_DEPTH];
         bool sealed:1;
+
+        sd_rtnl_message *next; /* next in a chain of multi-part messages */
 };
 
-int message_new(sd_rtnl *rtnl, sd_rtnl_message **ret, size_t initial_size);
+int message_new(sd_rtnl *rtnl, sd_rtnl_message **ret, uint16_t type);
 
 int socket_write_message(sd_rtnl *nl, sd_rtnl_message *m);
-int socket_read_message(sd_rtnl *nl, sd_rtnl_message **ret);
+int socket_read_message(sd_rtnl *nl);
+
+int rtnl_rqueue_make_room(sd_rtnl *rtnl);
+int rtnl_rqueue_partial_make_room(sd_rtnl *rtnl);
+
+int rtnl_message_read_internal(sd_rtnl_message *m, unsigned short type, void **data);
+int rtnl_message_parse(sd_rtnl_message *m,
+                       size_t **rta_offset_tb,
+                       unsigned short *rta_tb_size,
+                       int max,
+                       struct rtattr *rta,
+                       unsigned int rt_len);
 
 /* Make sure callbacks don't destroy the rtnl connection */
 #define RTNL_DONT_DESTROY(rtnl) \
index 8c20b8e..1f596ca 100644 (file)
 #include <netinet/ether.h>
 #include <stdbool.h>
 #include <unistd.h>
+#include <linux/netlink.h>
 #include <linux/veth.h>
+#include <linux/if.h>
+#include <linux/ip.h>
+#include <linux/if_tunnel.h>
+#include <linux/if_bridge.h>
 
 #include "util.h"
 #include "refcnt.h"
 #include "sd-rtnl.h"
 #include "rtnl-util.h"
 #include "rtnl-internal.h"
+#include "rtnl-types.h"
 
 #define GET_CONTAINER(m, i) ((i) < (m)->n_containers ? (struct rtattr*)((uint8_t*)(m)->hdr + (m)->container_offsets[i]) : NULL)
-#define NEXT_RTA(m) ((struct rtattr*)((uint8_t*)(m)->hdr + (m)->next_rta_offset))
-#define UPDATE_RTA(m, new) (m)->next_rta_offset = (uint8_t*)(new) - (uint8_t*)(m)->hdr;
 #define PUSH_CONTAINER(m, new) (m)->container_offsets[(m)->n_containers ++] = (uint8_t*)(new) - (uint8_t*)(m)->hdr;
 
-int message_new(sd_rtnl *rtnl, sd_rtnl_message **ret, size_t initial_size) {
+static int message_new_empty(sd_rtnl *rtnl, sd_rtnl_message **ret) {
         sd_rtnl_message *m;
 
         assert_return(ret, -EINVAL);
-        assert_return(initial_size >= sizeof(struct nlmsghdr), -EINVAL);
+
+        /* Note that 'rtnl' is curretly unused, if we start using it internally
+           we must take care to avoid problems due to mutual references between
+           busses and their queued messages. See sd-bus.
+         */
 
         m = new0(sd_rtnl_message, 1);
         if (!m)
                 return -ENOMEM;
 
-        m->hdr = malloc0(initial_size);
-        if (!m->hdr) {
-                free(m);
-                return -ENOMEM;
-        }
-
         m->n_ref = REFCNT_INIT;
 
-        m->hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
         m->sealed = false;
 
-        if (rtnl)
-                m->rtnl = sd_rtnl_ref(rtnl);
+        *ret = m;
+
+        return 0;
+}
+
+int message_new(sd_rtnl *rtnl, sd_rtnl_message **ret, uint16_t type) {
+        _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
+        const NLType *nl_type;
+        size_t size;
+        int r;
+
+        r = type_system_get_type(NULL, &nl_type, type);
+        if (r < 0)
+                return r;
+
+        assert(nl_type->type == NLA_NESTED);
+
+        r = message_new_empty(rtnl, &m);
+        if (r < 0)
+                return r;
+
+        size = NLMSG_SPACE(nl_type->size);
+
+        assert(size >= sizeof(struct nlmsghdr));
+        m->hdr = malloc0(size);
+        if (!m->hdr)
+                return -ENOMEM;
+
+        m->hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
+
+        m->container_type_system[0] = nl_type->type_system;
+        m->hdr->nlmsg_len = size;
+        m->hdr->nlmsg_type = type;
 
         *ret = m;
+        m = NULL;
 
         return 0;
 }
@@ -85,8 +118,23 @@ int sd_rtnl_message_route_set_dst_prefixlen(sd_rtnl_message *m, unsigned char pr
         return 0;
 }
 
+int sd_rtnl_message_route_set_scope(sd_rtnl_message *m, unsigned char scope) {
+        struct rtmsg *rtm;
+
+        assert_return(m, -EINVAL);
+        assert_return(m->hdr, -EINVAL);
+        assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
+
+        rtm = NLMSG_DATA(m->hdr);
+
+        rtm->rtm_scope = scope;
+
+        return 0;
+}
+
 int sd_rtnl_message_new_route(sd_rtnl *rtnl, sd_rtnl_message **ret,
-                              uint16_t nlmsg_type, unsigned char rtm_family) {
+                              uint16_t nlmsg_type, int rtm_family,
+                              unsigned char rtm_protocol) {
         struct rtmsg *rtm;
         int r;
 
@@ -94,24 +142,20 @@ int sd_rtnl_message_new_route(sd_rtnl *rtnl, sd_rtnl_message **ret,
         assert_return(rtm_family == AF_INET || rtm_family == AF_INET6, -EINVAL);
         assert_return(ret, -EINVAL);
 
-        r = message_new(rtnl, ret, NLMSG_SPACE(sizeof(struct rtmsg)));
+        r = message_new(rtnl, ret, nlmsg_type);
         if (r < 0)
                 return r;
 
-        (*ret)->hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
-        (*ret)->hdr->nlmsg_type = nlmsg_type;
         if (nlmsg_type == RTM_NEWROUTE)
-                (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
+                (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_APPEND;
 
         rtm = NLMSG_DATA((*ret)->hdr);
 
-        UPDATE_RTA(*ret, RTM_RTA(rtm));
-
         rtm->rtm_family = rtm_family;
         rtm->rtm_scope = RT_SCOPE_UNIVERSE;
         rtm->rtm_type = RTN_UNICAST;
         rtm->rtm_table = RT_TABLE_MAIN;
-        rtm->rtm_protocol = RTPROT_BOOT;
+        rtm->rtm_protocol = rtm_protocol;
 
         return 0;
 }
@@ -152,25 +196,36 @@ int sd_rtnl_message_new_link(sd_rtnl *rtnl, sd_rtnl_message **ret,
         int r;
 
         assert_return(rtnl_message_type_is_link(nlmsg_type), -EINVAL);
-        assert_return(nlmsg_type == RTM_NEWLINK ||
-                      nlmsg_type == RTM_SETLINK || index > 0, -EINVAL);
+        assert_return(nlmsg_type != RTM_DELLINK || index > 0, -EINVAL);
         assert_return(ret, -EINVAL);
 
-        r = message_new(rtnl, ret, NLMSG_SPACE(sizeof(struct ifinfomsg)));
+        r = message_new(rtnl, ret, nlmsg_type);
         if (r < 0)
                 return r;
 
-        (*ret)->hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
-        (*ret)->hdr->nlmsg_type = nlmsg_type;
         if (nlmsg_type == RTM_NEWLINK)
-                (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE;
+                (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
 
         ifi = NLMSG_DATA((*ret)->hdr);
 
         ifi->ifi_family = AF_UNSPEC;
         ifi->ifi_index = index;
 
-        UPDATE_RTA(*ret, IFLA_RTA(ifi));
+        return 0;
+}
+
+int sd_rtnl_message_request_dump(sd_rtnl_message *m, int dump) {
+        assert_return(m, -EINVAL);
+        assert_return(m->hdr, -EINVAL);
+        assert_return(m->hdr->nlmsg_type == RTM_GETLINK ||
+                      m->hdr->nlmsg_type == RTM_GETADDR ||
+                      m->hdr->nlmsg_type == RTM_GETROUTE,
+                      -EINVAL);
+
+        if (dump)
+                m->hdr->nlmsg_flags |= NLM_F_DUMP;
+        else
+                m->hdr->nlmsg_flags &= ~NLM_F_DUMP;
 
         return 0;
 }
@@ -221,24 +276,99 @@ int sd_rtnl_message_addr_set_scope(sd_rtnl_message *m, unsigned char scope) {
         return 0;
 }
 
+int sd_rtnl_message_addr_get_family(sd_rtnl_message *m, int *family) {
+        struct ifaddrmsg *ifa;
+
+        assert_return(m, -EINVAL);
+        assert_return(m->hdr, -EINVAL);
+        assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
+        assert_return(family, -EINVAL);
+
+        ifa = NLMSG_DATA(m->hdr);
+
+        *family = ifa->ifa_family;
+
+        return 0;
+}
+
+int sd_rtnl_message_addr_get_prefixlen(sd_rtnl_message *m, unsigned char *prefixlen) {
+        struct ifaddrmsg *ifa;
+
+        assert_return(m, -EINVAL);
+        assert_return(m->hdr, -EINVAL);
+        assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
+        assert_return(prefixlen, -EINVAL);
+
+        ifa = NLMSG_DATA(m->hdr);
+
+        *prefixlen = ifa->ifa_prefixlen;
+
+        return 0;
+}
+
+int sd_rtnl_message_addr_get_scope(sd_rtnl_message *m, unsigned char *scope) {
+        struct ifaddrmsg *ifa;
+
+        assert_return(m, -EINVAL);
+        assert_return(m->hdr, -EINVAL);
+        assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
+        assert_return(scope, -EINVAL);
+
+        ifa = NLMSG_DATA(m->hdr);
+
+        *scope = ifa->ifa_scope;
+
+        return 0;
+}
+
+int sd_rtnl_message_addr_get_flags(sd_rtnl_message *m, unsigned char *flags) {
+        struct ifaddrmsg *ifa;
+
+        assert_return(m, -EINVAL);
+        assert_return(m->hdr, -EINVAL);
+        assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
+        assert_return(flags, -EINVAL);
+
+        ifa = NLMSG_DATA(m->hdr);
+
+        *flags = ifa->ifa_flags;
+
+        return 0;
+}
+
+int sd_rtnl_message_addr_get_ifindex(sd_rtnl_message *m, int *ifindex) {
+        struct ifaddrmsg *ifa;
+
+        assert_return(m, -EINVAL);
+        assert_return(m->hdr, -EINVAL);
+        assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
+        assert_return(ifindex, -EINVAL);
+
+        ifa = NLMSG_DATA(m->hdr);
+
+        *ifindex = ifa->ifa_index;
+
+        return 0;
+}
+
 int sd_rtnl_message_new_addr(sd_rtnl *rtnl, sd_rtnl_message **ret,
                              uint16_t nlmsg_type, int index,
-                             unsigned char family) {
+                             int family) {
         struct ifaddrmsg *ifa;
         int r;
 
         assert_return(rtnl_message_type_is_addr(nlmsg_type), -EINVAL);
-        assert_return(index > 0, -EINVAL);
-        assert_return(family == AF_INET || family == AF_INET6, -EINVAL);
+        assert_return((nlmsg_type == RTM_GETADDR && index == 0) ||
+                      index > 0, -EINVAL);
+        assert_return((nlmsg_type == RTM_GETADDR && family == AF_UNSPEC) ||
+                      family == AF_INET || family == AF_INET6, -EINVAL);
         assert_return(ret, -EINVAL);
 
-        r = message_new(rtnl, ret, NLMSG_SPACE(sizeof(struct ifaddrmsg)));
+        r = message_new(rtnl, ret, nlmsg_type);
         if (r < 0)
                 return r;
 
-        (*ret)->hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
-        (*ret)->hdr->nlmsg_type = nlmsg_type;
-        if (nlmsg_type == RTM_GETADDR && family == AF_INET)
+        if (nlmsg_type == RTM_GETADDR)
                 (*ret)->hdr->nlmsg_flags |= NLM_F_DUMP;
 
         ifa = NLMSG_DATA((*ret)->hdr);
@@ -250,7 +380,18 @@ int sd_rtnl_message_new_addr(sd_rtnl *rtnl, sd_rtnl_message **ret,
         else if (family == AF_INET6)
                 ifa->ifa_prefixlen = 128;
 
-        UPDATE_RTA(*ret, IFA_RTA(ifa));
+        return 0;
+}
+
+int sd_rtnl_message_new_addr_update(sd_rtnl *rtnl, sd_rtnl_message **ret,
+                             int index, int family) {
+        int r;
+
+        r = sd_rtnl_message_new_addr(rtnl, ret, RTM_NEWADDR, index, family);
+        if (r < 0)
+                return r;
+
+        (*ret)->hdr->nlmsg_flags |= NLM_F_REPLACE;
 
         return 0;
 }
@@ -264,8 +405,15 @@ sd_rtnl_message *sd_rtnl_message_ref(sd_rtnl_message *m) {
 
 sd_rtnl_message *sd_rtnl_message_unref(sd_rtnl_message *m) {
         if (m && REFCNT_DEC(m->n_ref) <= 0) {
-                sd_rtnl_unref(m->rtnl);
+                unsigned i;
+
                 free(m->hdr);
+
+                for (i = 0; i <= m->n_containers; i++)
+                        free(m->rta_offset_tb[i]);
+
+                sd_rtnl_message_unref(m->next);
+
                 free(m);
         }
 
@@ -281,6 +429,12 @@ int sd_rtnl_message_get_type(sd_rtnl_message *m, uint16_t *type) {
         return 0;
 }
 
+int sd_rtnl_message_is_broadcast(sd_rtnl_message *m) {
+        assert_return(m, -EINVAL);
+
+        return !m->hdr->nlmsg_pid;
+}
+
 int sd_rtnl_message_link_get_ifindex(sd_rtnl_message *m, int *ifindex) {
         struct ifinfomsg *ifi;
 
@@ -311,27 +465,46 @@ int sd_rtnl_message_link_get_flags(sd_rtnl_message *m, unsigned *flags) {
         return 0;
 }
 
+int sd_rtnl_message_link_get_type(sd_rtnl_message *m, unsigned *type) {
+        struct ifinfomsg *ifi;
+
+        assert_return(m, -EINVAL);
+        assert_return(m->hdr, -EINVAL);
+        assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL);
+        assert_return(type, -EINVAL);
+
+        ifi = NLMSG_DATA(m->hdr);
+
+        *type = ifi->ifi_type;
+
+        return 0;
+}
+
 /* If successful the updated message will be correctly aligned, if
    unsuccessful the old message is untouched. */
 static int add_rtattr(sd_rtnl_message *m, unsigned short type, const void *data, size_t data_length) {
-        uint32_t rta_length, message_length;
+        uint32_t rta_length;
+        size_t message_length, padding_length;
         struct nlmsghdr *new_hdr;
         struct rtattr *rta;
         char *padding;
         unsigned i;
+        int offset;
 
         assert(m);
         assert(m->hdr);
         assert(!m->sealed);
         assert(NLMSG_ALIGN(m->hdr->nlmsg_len) == m->hdr->nlmsg_len);
-        assert(!data || data_length > 0);
-        assert(data || m->n_containers < RTNL_CONTAINER_DEPTH);
+        assert(!data || data_length);
+
+        /* get offset of the new attribute */
+        offset = m->hdr->nlmsg_len;
 
         /* get the size of the new rta attribute (with padding at the end) */
         rta_length = RTA_LENGTH(data_length);
 
         /* get the new message size (with padding at the end) */
-        message_length = m->hdr->nlmsg_len + RTA_ALIGN(rta_length);
+        message_length = offset + RTA_ALIGN(rta_length);
 
         /* realloc to fit the new attribute */
         new_hdr = realloc(m->hdr, message_length);
@@ -340,78 +513,73 @@ static int add_rtattr(sd_rtnl_message *m, unsigned short type, const void *data,
         m->hdr = new_hdr;
 
         /* get pointer to the attribute we are about to add */
-        rta = (struct rtattr *) ((uint8_t *) m->hdr + m->hdr->nlmsg_len);
+        rta = (struct rtattr *) ((uint8_t *) m->hdr + offset);
 
         /* if we are inside containers, extend them */
         for (i = 0; i < m->n_containers; i++)
-                GET_CONTAINER(m, i)->rta_len += message_length - m->hdr->nlmsg_len;
+                GET_CONTAINER(m, i)->rta_len += message_length - offset;
 
         /* fill in the attribute */
         rta->rta_type = type;
         rta->rta_len = rta_length;
-        if (!data) {
-                /* this is the start of a new container */
-                m->container_offsets[m->n_containers ++] = m->hdr->nlmsg_len;
-        } else {
+        if (data)
                 /* we don't deal with the case where the user lies about the type
                  * and gives us too little data (so don't do that)
-                */
+                 */
                 padding = mempcpy(RTA_DATA(rta), data, data_length);
-                /* make sure also the padding at the end of the message is initialized */
-                memzero(padding,
-                        (uint8_t *) m->hdr + message_length - (uint8_t *) padding);
+        else {
+                /* if no data was passed, make sure we still initialize the padding
+                   note that we can have data_length > 0 (used by some containers) */
+                padding = RTA_DATA(rta);
+                data_length = 0;
         }
 
+        /* make sure also the padding at the end of the message is initialized */
+        padding_length = (uint8_t*)m->hdr + message_length - (uint8_t*)padding;
+        memzero(padding, padding_length);
+
         /* update message size */
         m->hdr->nlmsg_len = message_length;
 
-        return 0;
+        return offset;
+}
+
+static int message_attribute_has_type(sd_rtnl_message *m, uint16_t attribute_type, uint16_t data_type) {
+        const NLType *type;
+        int r;
+
+        r = type_system_get_type(m->container_type_system[m->n_containers], &type, attribute_type);
+        if (r < 0)
+                return r;
+
+        if (type->type != data_type)
+                return -EINVAL;
+
+        return type->size;
 }
 
 int sd_rtnl_message_append_string(sd_rtnl_message *m, unsigned short type, const char *data) {
-        uint16_t rtm_type;
+        size_t length, size;
         int r;
 
         assert_return(m, -EINVAL);
         assert_return(!m->sealed, -EPERM);
         assert_return(data, -EINVAL);
 
-        r = sd_rtnl_message_get_type(m, &rtm_type);
+        r = message_attribute_has_type(m, type, NLA_STRING);
         if (r < 0)
                 return r;
+        else
+                size = (size_t)r;
 
-        /* check that the type is correct */
-        switch (rtm_type) {
-                case RTM_NEWLINK:
-                case RTM_SETLINK:
-                case RTM_GETLINK:
-                case RTM_DELLINK:
-                        if (m->n_containers == 1) {
-                                if (GET_CONTAINER(m, 0)->rta_type != IFLA_LINKINFO ||
-                                    type != IFLA_INFO_KIND)
-                                        return -ENOTSUP;
-                        } else {
-                                switch (type) {
-                                        case IFLA_IFNAME:
-                                        case IFLA_IFALIAS:
-                                        case IFLA_QDISC:
-                                                break;
-                                        default:
-                                                return -ENOTSUP;
-                                }
-                        }
-                        break;
-                case RTM_NEWADDR:
-                case RTM_GETADDR:
-                case RTM_DELADDR:
-                        if (type != IFA_LABEL)
-                                return -ENOTSUP;
-                        break;
-                default:
-                        return -ENOTSUP;
-        }
+        if (size) {
+                length = strnlen(data, size);
+                if (length >= size)
+                        return -EINVAL;
+        } else
+                length = strlen(data);
 
-        r = add_rtattr(m, type, data, strlen(data) + 1);
+        r = add_rtattr(m, type, data, length + 1);
         if (r < 0)
                 return r;
 
@@ -419,35 +587,15 @@ int sd_rtnl_message_append_string(sd_rtnl_message *m, unsigned short type, const
 }
 
 int sd_rtnl_message_append_u8(sd_rtnl_message *m, unsigned short type, uint8_t data) {
-        uint16_t rtm_type;
         int r;
 
         assert_return(m, -EINVAL);
         assert_return(!m->sealed, -EPERM);
 
-        r = sd_rtnl_message_get_type(m, &rtm_type);
+        r = message_attribute_has_type(m, type, NLA_U8);
         if (r < 0)
                 return r;
 
-        switch (rtm_type) {
-                case RTM_NEWLINK:
-                case RTM_SETLINK:
-                case RTM_GETLINK:
-                case RTM_DELLINK:
-                        switch (type) {
-                                case IFLA_CARRIER:
-                                case IFLA_OPERSTATE:
-                                case IFLA_LINKMODE:
-                                break;
-                        default:
-                                return -ENOTSUP;
-                        }
-
-                        break;
-                default:
-                        return -ENOTSUP;
-        }
-
         r = add_rtattr(m, type, &data, sizeof(uint8_t));
         if (r < 0)
                 return r;
@@ -457,34 +605,15 @@ int sd_rtnl_message_append_u8(sd_rtnl_message *m, unsigned short type, uint8_t d
 
 
 int sd_rtnl_message_append_u16(sd_rtnl_message *m, unsigned short type, uint16_t data) {
-        uint16_t rtm_type;
         int r;
 
         assert_return(m, -EINVAL);
         assert_return(!m->sealed, -EPERM);
 
-        r = sd_rtnl_message_get_type(m, &rtm_type);
+        r = message_attribute_has_type(m, type, NLA_U16);
         if (r < 0)
                 return r;
 
-        /* check that the type is correct */
-        switch (rtm_type) {
-                case RTM_NEWLINK:
-                case RTM_SETLINK:
-                case RTM_GETLINK:
-                case RTM_DELLINK:
-                        if (m->n_containers == 2 &&
-                            GET_CONTAINER(m, 0)->rta_type == IFLA_LINKINFO &&
-                            GET_CONTAINER(m, 1)->rta_type == IFLA_INFO_DATA &&
-                            type == IFLA_VLAN_ID)
-                                break;
-                        else
-                                return -ENOTSUP;
-                        break;
-                default:
-                        return -ENOTSUP;
-        }
-
         r = add_rtattr(m, type, &data, sizeof(uint16_t));
         if (r < 0)
                 return r;
@@ -493,57 +622,15 @@ int sd_rtnl_message_append_u16(sd_rtnl_message *m, unsigned short type, uint16_t
 }
 
 int sd_rtnl_message_append_u32(sd_rtnl_message *m, unsigned short type, uint32_t data) {
-        uint16_t rtm_type;
         int r;
 
         assert_return(m, -EINVAL);
         assert_return(!m->sealed, -EPERM);
 
-        r = sd_rtnl_message_get_type(m, &rtm_type);
+        r = message_attribute_has_type(m, type, NLA_U32);
         if (r < 0)
                 return r;
 
-        /* check that the type is correct */
-        switch (rtm_type) {
-                case RTM_NEWLINK:
-                case RTM_SETLINK:
-                case RTM_GETLINK:
-                case RTM_DELLINK:
-                        switch (type) {
-                                case IFLA_MASTER:
-                                case IFLA_MTU:
-                                case IFLA_LINK:
-                                case IFLA_GROUP:
-                                case IFLA_TXQLEN:
-                                case IFLA_WEIGHT:
-                                case IFLA_NET_NS_FD:
-                                case IFLA_NET_NS_PID:
-                                case IFLA_PROMISCUITY:
-                                case IFLA_NUM_TX_QUEUES:
-                                case IFLA_NUM_RX_QUEUES:
-                                        break;
-                                default:
-                                        return -ENOTSUP;
-                        }
-                        break;
-                case RTM_NEWROUTE:
-                case RTM_GETROUTE:
-                case RTM_DELROUTE:
-                        switch (type) {
-                                case RTA_TABLE:
-                                case RTA_PRIORITY:
-                                case RTA_IIF:
-                                case RTA_OIF:
-                                case RTA_MARK:
-                                        break;
-                                default:
-                                        return -ENOTSUP;
-                        }
-                        break;
-                default:
-                        return -ENOTSUP;
-        }
-
         r = add_rtattr(m, type, &data, sizeof(uint32_t));
         if (r < 0)
                 return r;
@@ -552,60 +639,16 @@ int sd_rtnl_message_append_u32(sd_rtnl_message *m, unsigned short type, uint32_t
 }
 
 int sd_rtnl_message_append_in_addr(sd_rtnl_message *m, unsigned short type, const struct in_addr *data) {
-        struct ifaddrmsg *ifa;
-        struct rtmsg *rtm;
-        uint16_t rtm_type;
         int r;
 
         assert_return(m, -EINVAL);
         assert_return(!m->sealed, -EPERM);
         assert_return(data, -EINVAL);
 
-        r = sd_rtnl_message_get_type(m, &rtm_type);
+        r = message_attribute_has_type(m, type, NLA_IN_ADDR);
         if (r < 0)
                 return r;
 
-        /* check that the type is correct */
-        switch (rtm_type) {
-                case RTM_NEWADDR:
-                case RTM_GETADDR:
-                case RTM_DELADDR:
-                        switch (type) {
-                                case IFA_ADDRESS:
-                                case IFA_LOCAL:
-                                case IFA_BROADCAST:
-                                case IFA_ANYCAST:
-                                        ifa = NLMSG_DATA(m->hdr);
-
-                                        if (ifa->ifa_family != AF_INET)
-                                                return -EINVAL;
-
-                                        break;
-                                default:
-                                        return -ENOTSUP;
-                        }
-                        break;
-                case RTM_NEWROUTE:
-                case RTM_GETROUTE:
-                case RTM_DELROUTE:
-                        switch (type) {
-                                case RTA_DST:
-                                case RTA_SRC:
-                                case RTA_GATEWAY:
-                                        rtm = NLMSG_DATA(m->hdr);
-
-                                        if (rtm->rtm_family != AF_INET)
-                                                return -EINVAL;
-
-                                        break;
-                                default:
-                                        return -ENOTSUP;
-                        }
-                        break;
-                default:
-                        return -ENOTSUP;
-        }
-
         r = add_rtattr(m, type, data, sizeof(struct in_addr));
         if (r < 0)
                 return r;
@@ -614,59 +657,16 @@ int sd_rtnl_message_append_in_addr(sd_rtnl_message *m, unsigned short type, cons
 }
 
 int sd_rtnl_message_append_in6_addr(sd_rtnl_message *m, unsigned short type, const struct in6_addr *data) {
-        struct ifaddrmsg *ifa;
-        struct rtmsg *rtm;
-        uint16_t rtm_type;
         int r;
 
         assert_return(m, -EINVAL);
         assert_return(!m->sealed, -EPERM);
         assert_return(data, -EINVAL);
 
-        r = sd_rtnl_message_get_type(m, &rtm_type);
+        r = message_attribute_has_type(m, type, NLA_IN_ADDR);
         if (r < 0)
                 return r;
 
-        /* check that the type is correct */
-        switch (rtm_type) {
-                case RTM_NEWADDR:
-                case RTM_GETADDR:
-                case RTM_DELADDR:
-                        switch (type) {
-                                case IFA_ADDRESS:
-                                case IFA_LOCAL:
-                                case IFA_BROADCAST:
-                                case IFA_ANYCAST:
-                                        ifa = NLMSG_DATA(m->hdr);
-
-                                        if (ifa->ifa_family != AF_INET6)
-                                                return -EINVAL;
-
-                                        break;
-                                default:
-                                        return -ENOTSUP;
-                        }
-                        break;
-                case RTM_NEWROUTE:
-                case RTM_GETROUTE:
-                case RTM_DELROUTE:
-                        switch (type) {
-                                case RTA_DST:
-                                case RTA_SRC:
-                                case RTA_GATEWAY:
-                                        rtm = NLMSG_DATA(m->hdr);
-
-                                        if (rtm->rtm_family != AF_INET6)
-                                                return -EINVAL;
-
-                                        break;
-                                default:
-                                        return -ENOTSUP;
-                        }
-                default:
-                        return -ENOTSUP;
-        }
-
         r = add_rtattr(m, type, data, sizeof(struct in6_addr));
         if (r < 0)
                 return r;
@@ -675,31 +675,15 @@ int sd_rtnl_message_append_in6_addr(sd_rtnl_message *m, unsigned short type, con
 }
 
 int sd_rtnl_message_append_ether_addr(sd_rtnl_message *m, unsigned short type, const struct ether_addr *data) {
-        uint16_t rtm_type;
         int r;
 
         assert_return(m, -EINVAL);
         assert_return(!m->sealed, -EPERM);
         assert_return(data, -EINVAL);
 
-        sd_rtnl_message_get_type(m, &rtm_type);
-
-        switch (rtm_type) {
-                case RTM_NEWLINK:
-                case RTM_SETLINK:
-                case RTM_DELLINK:
-                case RTM_GETLINK:
-                        switch (type) {
-                                case IFLA_ADDRESS:
-                                case IFLA_BROADCAST:
-                                        break;
-                                default:
-                                        return -ENOTSUP;
-                        }
-                        break;
-                default:
-                        return -ENOTSUP;
-        }
+        r = message_attribute_has_type(m, type, NLA_ETHER_ADDR);
+        if (r < 0)
+                return r;
 
         r = add_rtattr(m, type, data, ETH_ALEN);
         if (r < 0)
@@ -708,83 +692,334 @@ int sd_rtnl_message_append_ether_addr(sd_rtnl_message *m, unsigned short type, c
         return 0;
 }
 
+int sd_rtnl_message_append_cache_info(sd_rtnl_message *m, unsigned short type, const struct ifa_cacheinfo *info) {
+        int r;
+
+        assert_return(m, -EINVAL);
+        assert_return(!m->sealed, -EPERM);
+        assert_return(info, -EINVAL);
+
+        r = message_attribute_has_type(m, type, NLA_CACHE_INFO);
+        if (r < 0)
+                return r;
+
+        r = add_rtattr(m, type, info, sizeof(struct ifa_cacheinfo));
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
 int sd_rtnl_message_open_container(sd_rtnl_message *m, unsigned short type) {
-        uint16_t rtm_type;
+        size_t size;
+        int r;
 
         assert_return(m, -EINVAL);
         assert_return(!m->sealed, -EPERM);
+        assert_return(m->n_containers < RTNL_CONTAINER_DEPTH, -ERANGE);
 
-        sd_rtnl_message_get_type(m, &rtm_type);
+        r = message_attribute_has_type(m, type, NLA_NESTED);
+        if (r < 0)
+                return r;
+        else
+                size = (size_t)r;
 
-        if (rtnl_message_type_is_link(rtm_type)) {
+        r = type_system_get_type_system(m->container_type_system[m->n_containers],
+                                        &m->container_type_system[m->n_containers + 1],
+                                        type);
+        if (r < 0)
+                return r;
 
-                if ((type == IFLA_LINKINFO && m->n_containers == 0) ||
-                    (type == IFLA_INFO_DATA && m->n_containers == 1 &&
-                     GET_CONTAINER(m, 0)->rta_type == IFLA_LINKINFO))
-                        return add_rtattr(m, type, NULL, 0);
-                else if (type == VETH_INFO_PEER && m->n_containers == 2 &&
-                         GET_CONTAINER(m, 1)->rta_type == IFLA_INFO_DATA &&
-                         GET_CONTAINER(m, 0)->rta_type == IFLA_LINKINFO)
-                        return add_rtattr(m, type, NULL, sizeof(struct ifinfomsg));
-        }
+        r = add_rtattr(m, type, NULL, size);
+        if (r < 0)
+                return r;
+
+        m->container_offsets[m->n_containers ++] = r;
+
+        return 0;
+}
+
+int sd_rtnl_message_open_container_union(sd_rtnl_message *m, unsigned short type, const char *key) {
+        const NLTypeSystemUnion *type_system_union;
+        int r;
+
+        assert_return(m, -EINVAL);
+        assert_return(!m->sealed, -EPERM);
+
+        r = type_system_get_type_system_union(m->container_type_system[m->n_containers], &type_system_union, type);
+        if (r < 0)
+                return r;
+
+        r = type_system_union_get_type_system(type_system_union,
+                                              &m->container_type_system[m->n_containers + 1],
+                                              key);
+        if (r < 0)
+                return r;
+
+        r = sd_rtnl_message_append_string(m, type_system_union->match, key);
+        if (r < 0)
+                return r;
+
+        /* do we evere need non-null size */
+        r = add_rtattr(m, type, NULL, 0);
+        if (r < 0)
+                return r;
 
-        return -ENOTSUP;
+        m->container_offsets[m->n_containers ++] = r;
+
+        return 0;
 }
 
+
 int sd_rtnl_message_close_container(sd_rtnl_message *m) {
         assert_return(m, -EINVAL);
         assert_return(!m->sealed, -EPERM);
         assert_return(m->n_containers > 0, -EINVAL);
 
+        m->container_type_system[m->n_containers] = NULL;
         m->n_containers --;
 
         return 0;
 }
 
-int sd_rtnl_message_read(sd_rtnl_message *m, unsigned short *type, void **data) {
-        size_t remaining_size;
-        uint16_t rtm_type;
-        int r;
+int rtnl_message_read_internal(sd_rtnl_message *m, unsigned short type, void **data) {
+        struct rtattr *rta;
 
         assert_return(m, -EINVAL);
         assert_return(m->sealed, -EPERM);
-        assert_return(m->next_rta_offset, -EINVAL);
-        assert_return(type, -EINVAL);
         assert_return(data, -EINVAL);
+        assert(m->n_containers <= RTNL_CONTAINER_DEPTH);
+        assert(m->rta_offset_tb[m->n_containers]);
+        assert(type < m->rta_tb_size[m->n_containers]);
 
-        /* only read until the end of the current container */
-        if (m->n_containers)
-                remaining_size = GET_CONTAINER(m, m->n_containers - 1)->rta_len -
-                                 (m->next_rta_offset -
-                                  m->container_offsets[m->n_containers - 1]);
-        else
-                remaining_size = m->hdr->nlmsg_len - m->next_rta_offset;
+        if(!m->rta_offset_tb[m->n_containers][type])
+                return -ENODATA;
 
-        if (!RTA_OK(NEXT_RTA(m), remaining_size))
-                return 0;
+        rta = (struct rtattr*)((uint8_t *) m->hdr + m->rta_offset_tb[m->n_containers][type]);
+
+        *data = RTA_DATA(rta);
+
+        return RTA_PAYLOAD(rta);
+}
 
-        /* if we read a container, enter it and return its type */
-        r = sd_rtnl_message_get_type(m, &rtm_type);
+int sd_rtnl_message_read_string(sd_rtnl_message *m, unsigned short type, const char **data) {
+        int r;
+        void *attr_data;
+
+        r = message_attribute_has_type(m, type, NLA_STRING);
         if (r < 0)
                 return r;
 
-        *type = NEXT_RTA(m)->rta_type;
-
-        if (rtnl_message_type_is_link(rtm_type) &&
-            ((m->n_containers == 0 &&
-              NEXT_RTA(m)->rta_type == IFLA_LINKINFO) ||
-             (m->n_containers == 1 &&
-              GET_CONTAINER(m, 0)->rta_type == IFLA_LINKINFO &&
-              NEXT_RTA(m)->rta_type == IFLA_INFO_DATA))) {
-                *data = NULL;
-                PUSH_CONTAINER(m, NEXT_RTA(m));
-                UPDATE_RTA(m, RTA_DATA(NEXT_RTA(m)));
-        } else {
-                *data = RTA_DATA(NEXT_RTA(m));
-                UPDATE_RTA(m, RTA_NEXT(NEXT_RTA(m), remaining_size));
+        r = rtnl_message_read_internal(m, type, &attr_data);
+        if (r < 0)
+                return r;
+        else if (strnlen(attr_data, r) >= (size_t) r)
+                return -EIO;
+
+        *data = (const char *) attr_data;
+
+        return 0;
+}
+
+int sd_rtnl_message_read_u8(sd_rtnl_message *m, unsigned short type, uint8_t *data) {
+        int r;
+        void *attr_data;
+
+        r = message_attribute_has_type(m, type, NLA_U8);
+        if (r < 0)
+                return r;
+
+        r = rtnl_message_read_internal(m, type, &attr_data);
+        if (r < 0)
+                return r;
+        else if ((size_t) r < sizeof(uint8_t))
+                return -EIO;
+
+        *data = *(uint8_t *) attr_data;
+
+        return 0;
+}
+
+int sd_rtnl_message_read_u16(sd_rtnl_message *m, unsigned short type, uint16_t *data) {
+        int r;
+        void *attr_data;
+
+        r = message_attribute_has_type(m, type, NLA_U16);
+        if (r < 0)
+                return r;
+
+        r = rtnl_message_read_internal(m, type, &attr_data);
+        if (r < 0)
+                return r;
+        else if ((size_t) r < sizeof(uint16_t))
+                return -EIO;
+
+        *data = *(uint16_t *) attr_data;
+
+        return 0;
+}
+
+int sd_rtnl_message_read_u32(sd_rtnl_message *m, unsigned short type, uint32_t *data) {
+        int r;
+        void *attr_data;
+
+        r = message_attribute_has_type(m, type, NLA_U32);
+        if (r < 0)
+                return r;
+
+        r = rtnl_message_read_internal(m, type, &attr_data);
+        if (r < 0)
+                return r;
+        else if ((size_t)r < sizeof(uint32_t))
+                return -EIO;
+
+        *data = *(uint32_t *) attr_data;
+
+        return 0;
+}
+
+int sd_rtnl_message_read_ether_addr(sd_rtnl_message *m, unsigned short type, struct ether_addr *data) {
+        int r;
+        void *attr_data;
+
+        r = message_attribute_has_type(m, type, NLA_ETHER_ADDR);
+        if (r < 0)
+                return r;
+
+        r = rtnl_message_read_internal(m, type, &attr_data);
+        if (r < 0)
+                return r;
+        else if ((size_t)r < sizeof(struct ether_addr))
+                return -EIO;
+
+        memcpy(data, attr_data, sizeof(struct ether_addr));
+
+        return 0;
+}
+
+int sd_rtnl_message_read_cache_info(sd_rtnl_message *m, unsigned short type, struct ifa_cacheinfo *info) {
+        int r;
+        void *attr_data;
+
+        r = message_attribute_has_type(m, type, NLA_CACHE_INFO);
+        if (r < 0)
+                return r;
+
+        r = rtnl_message_read_internal(m, type, &attr_data);
+        if (r < 0)
+                return r;
+        else if ((size_t)r < sizeof(struct ifa_cacheinfo))
+                return -EIO;
+
+        memcpy(info, attr_data, sizeof(struct ifa_cacheinfo));
+
+        return 0;
+}
+
+int sd_rtnl_message_read_in_addr(sd_rtnl_message *m, unsigned short type, struct in_addr *data) {
+        int r;
+        void *attr_data;
+
+        r = message_attribute_has_type(m, type, NLA_IN_ADDR);
+        if (r < 0)
+                return r;
+
+        r = rtnl_message_read_internal(m, type, &attr_data);
+        if (r < 0)
+                return r;
+        else if ((size_t)r < sizeof(struct in_addr))
+                return -EIO;
+
+        memcpy(data, attr_data, sizeof(struct in_addr));
+
+        return 0;
+}
+
+int sd_rtnl_message_read_in6_addr(sd_rtnl_message *m, unsigned short type, struct in6_addr *data) {
+        int r;
+        void *attr_data;
+
+        r = message_attribute_has_type(m, type, NLA_IN_ADDR);
+        if (r < 0)
+                return r;
+
+        r = rtnl_message_read_internal(m, type, &attr_data);
+        if (r < 0)
+                return r;
+        else if ((size_t)r < sizeof(struct in6_addr))
+                return -EIO;
+
+        memcpy(data, attr_data, sizeof(struct in6_addr));
+
+        return 0;
+}
+
+int sd_rtnl_message_enter_container(sd_rtnl_message *m, unsigned short type) {
+        const NLType *nl_type;
+        const NLTypeSystem *type_system;
+        void *container;
+        size_t size;
+        int r;
+
+        assert_return(m, -EINVAL);
+        assert_return(m->n_containers < RTNL_CONTAINER_DEPTH, -EINVAL);
+
+        r = type_system_get_type(m->container_type_system[m->n_containers],
+                                 &nl_type,
+                                 type);
+        if (r < 0)
+                return r;
+
+        if (nl_type->type == NLA_NESTED) {
+                r = type_system_get_type_system(m->container_type_system[m->n_containers],
+                                                &type_system,
+                                                type);
+                if (r < 0)
+                        return r;
+        } else if (nl_type->type == NLA_UNION) {
+                const NLTypeSystemUnion *type_system_union;
+                const char *key;
+
+                r = type_system_get_type_system_union(m->container_type_system[m->n_containers],
+                                                      &type_system_union,
+                                                      type);
+                if (r < 0)
+                        return r;
+
+                r = sd_rtnl_message_read_string(m, type_system_union->match, &key);
+                if (r < 0)
+                        return r;
+
+                r = type_system_union_get_type_system(type_system_union,
+                                                      &type_system,
+                                                      key);
+                if (r < 0)
+                        return r;
+        } else
+                return -EINVAL;
+
+        r = rtnl_message_read_internal(m, type, &container);
+        if (r < 0)
+                return r;
+        else
+                size = (size_t)r;
+
+        m->n_containers ++;
+
+        r = rtnl_message_parse(m,
+                               &m->rta_offset_tb[m->n_containers],
+                               &m->rta_tb_size[m->n_containers],
+                               type_system->max,
+                               container,
+                               size);
+        if (r < 0) {
+                m->n_containers --;
+                return r;
         }
 
-        return 1;
+        m->container_type_system[m->n_containers] = type_system;
+
+        return 0;
 }
 
 int sd_rtnl_message_exit_container(sd_rtnl_message *m) {
@@ -792,6 +1027,10 @@ int sd_rtnl_message_exit_container(sd_rtnl_message *m) {
         assert_return(m->sealed, -EINVAL);
         assert_return(m->n_containers > 0, -EINVAL);
 
+        free(m->rta_offset_tb[m->n_containers]);
+        m->rta_offset_tb[m->n_containers] = NULL;
+        m->container_type_system[m->n_containers] = NULL;
+
         m->n_containers --;
 
         return 0;
@@ -818,43 +1057,37 @@ int sd_rtnl_message_get_errno(sd_rtnl_message *m) {
         return err->error;
 }
 
-int rtnl_message_seal(sd_rtnl *nl, sd_rtnl_message *m) {
-        int r;
+int rtnl_message_parse(sd_rtnl_message *m,
+                       size_t **rta_offset_tb,
+                       unsigned short *rta_tb_size,
+                       int max,
+                       struct rtattr *rta,
+                       unsigned int rt_len) {
+        unsigned short type;
+        size_t *tb;
+
+        tb = new0(size_t, max + 1);
+        if(!tb)
+                return -ENOMEM;
 
-        assert(m);
-        assert(m->hdr);
+        *rta_tb_size = max + 1;
 
-        if (m->sealed)
-                return -EPERM;
+        for (; RTA_OK(rta, rt_len); rta = RTA_NEXT(rta, rt_len)) {
+                type = rta->rta_type;
 
-        if (nl)
-                m->hdr->nlmsg_seq = nl->serial++;
+                /* if the kernel is newer than the headers we used
+                   when building, we ignore out-of-range attributes
+                 */
+                if (type > max)
+                        continue;
 
-        m->sealed = true;
-
-        r = sd_rtnl_message_rewind(m);
-        if (r < 0)
-                return r;
+                if (tb[type])
+                        log_debug("rtnl: message parse - overwriting repeated attribute");
 
-        return 0;
-}
-
-static int message_receive_need(sd_rtnl *rtnl, size_t *need) {
-        assert(rtnl);
-        assert(need);
-
-        /* ioctl(rtnl->fd, FIONREAD, &need)
-           Does not appear to work on netlink sockets. libnl uses
-           MSG_PEEK instead. I don't know if that is worth the
-           extra roundtrip.
+                tb[type] = (uint8_t *) rta - (uint8_t *) m->hdr;
+        }
 
-           For now we simply use the maximum message size the kernel
-           may use (NLMSG_GOODSIZE), and then realloc to the actual
-           size after reading the message (hence avoiding huge memory
-           usage in case many small messages are kept around) */
-        *need = page_size();
-        if (*need > 8192UL)
-                *need = 8192UL;
+        *rta_offset_tb = tb;
 
         return 0;
 }
@@ -881,152 +1114,272 @@ int socket_write_message(sd_rtnl *nl, sd_rtnl_message *m) {
         return k;
 }
 
+static int socket_recv_message(int fd, struct iovec *iov, uint32_t *_group, bool peek) {
+        uint8_t cred_buffer[CMSG_SPACE(sizeof(struct ucred)) +
+                            CMSG_SPACE(sizeof(struct nl_pktinfo))];
+        struct msghdr msg = {
+                .msg_iov = iov,
+                .msg_iovlen = 1,
+                .msg_control = cred_buffer,
+                .msg_controllen = sizeof(cred_buffer),
+        };
+        struct cmsghdr *cmsg;
+        uint32_t group = 0;
+        bool auth = false;
+        int r;
+
+        assert(fd >= 0);
+        assert(iov);
+
+        r = recvmsg(fd, &msg, MSG_TRUNC | (peek ? MSG_PEEK : 0));
+        if (r < 0)
+                /* no data */
+                return (errno == EAGAIN) ? 0 : -errno;
+        else if (r == 0)
+                /* connection was closed by the kernel */
+                return -ECONNRESET;
+
+        for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+                if (cmsg->cmsg_level == SOL_SOCKET &&
+                    cmsg->cmsg_type == SCM_CREDENTIALS &&
+                    cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) {
+                        struct ucred *ucred = (void *)CMSG_DATA(cmsg);
+
+                        /* from the kernel */
+                        if (ucred->uid == 0 && ucred->pid == 0)
+                                auth = true;
+                } else if (cmsg->cmsg_level == SOL_NETLINK &&
+                           cmsg->cmsg_type == NETLINK_PKTINFO &&
+                           cmsg->cmsg_len == CMSG_LEN(sizeof(struct nl_pktinfo))) {
+                        struct nl_pktinfo *pktinfo = (void *)CMSG_DATA(cmsg);
+
+                        /* multi-cast group */
+                        group = pktinfo->group;
+                }
+        }
+
+        if (!auth)
+                /* not from the kernel, ignore */
+                return 0;
+
+        if (group)
+                *_group = group;
+
+        return r;
+}
+
 /* On success, the number of bytes received is returned and *ret points to the received message
  * which has a valid header and the correct size.
  * If nothing useful was received 0 is returned.
  * On failure, a negative error code is returned.
  */
-int socket_read_message(sd_rtnl *nl, sd_rtnl_message **ret) {
-        sd_rtnl_message *m;
-        union {
-                struct sockaddr sa;
-                struct sockaddr_nl nl;
-        } addr;
-        socklen_t addr_len;
+int socket_read_message(sd_rtnl *rtnl) {
+        _cleanup_rtnl_message_unref_ sd_rtnl_message *first = NULL;
+        struct iovec iov = {};
+        uint32_t group = 0;
+        bool multi_part = false, done = false;
+        struct nlmsghdr *new_msg;
+        size_t len;
         int r;
-        ssize_t k;
-        size_t need;
+        unsigned i = 0;
 
-        assert(nl);
-        assert(ret);
+        assert(rtnl);
+        assert(rtnl->rbuffer);
+        assert(rtnl->rbuffer_allocated >= sizeof(struct nlmsghdr));
 
-        r = message_receive_need(nl, &need);
-        if (r < 0)
+        /* read nothing, just get the pending message size */
+        r = socket_recv_message(rtnl->fd, &iov, &group, true);
+        if (r <= 0)
                 return r;
+        else
+                len = (size_t)r;
 
-        r = message_new(nl, &m, need);
-        if (r < 0)
+        /* make room for the pending message */
+        if (!greedy_realloc((void **)&rtnl->rbuffer,
+                            &rtnl->rbuffer_allocated,
+                            len, sizeof(uint8_t)))
+                return -ENOMEM;
+
+        iov.iov_base = rtnl->rbuffer;
+        iov.iov_len = rtnl->rbuffer_allocated;
+
+        /* read the pending message */
+        r = socket_recv_message(rtnl->fd, &iov, &group, false);
+        if (r <= 0)
                 return r;
+        else
+                len = (size_t)r;
 
-        /* don't allow sealing/appending to received messages */
-        m->sealed = true;
+        if (len > rtnl->rbuffer_allocated)
+                /* message did not fit in read buffer */
+                return -EIO;
 
-        addr_len = sizeof(addr);
+        if (NLMSG_OK(rtnl->rbuffer, len) && rtnl->rbuffer->nlmsg_flags & NLM_F_MULTI) {
+                multi_part = true;
 
-        k = recvfrom(nl->fd, m->hdr, need,
-                        0, &addr.sa, &addr_len);
-        if (k < 0)
-                k = (errno == EAGAIN) ? 0 : -errno; /* no data */
-        else if (k == 0)
-                k = -ECONNRESET; /* connection was closed by the kernel */
-        else if (addr_len != sizeof(addr.nl) ||
-                        addr.nl.nl_family != AF_NETLINK)
-                k = -EIO; /* not a netlink message */
-        else if (addr.nl.nl_pid != 0)
-                k = 0; /* not from the kernel */
-        else if ((size_t) k < sizeof(struct nlmsghdr) ||
-                        (size_t) k < m->hdr->nlmsg_len)
-                k = -EIO; /* too small (we do accept too big though) */
-        else if (m->hdr->nlmsg_pid && m->hdr->nlmsg_pid != nl->sockaddr.nl.nl_pid)
-                k = 0; /* not broadcast and not for us */
-
-        if (k > 0)
-                switch (m->hdr->nlmsg_type) {
-                        struct ifinfomsg *ifi;
-                        struct ifaddrmsg *ifa;
-                        struct rtmsg *rtm;
-
-                        /* check that the size matches the message type */
-                        case NLMSG_ERROR:
-                                if (m->hdr->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr)))
-                                        k = -EIO;
+                for (i = 0; i < rtnl->rqueue_partial_size; i++) {
+                        if (rtnl_message_get_serial(rtnl->rqueue_partial[i]) ==
+                            rtnl->rbuffer->nlmsg_seq) {
+                                first = rtnl->rqueue_partial[i];
                                 break;
-                        case RTM_NEWLINK:
-                        case RTM_SETLINK:
-                        case RTM_DELLINK:
-                        case RTM_GETLINK:
-                                if (m->hdr->nlmsg_len < NLMSG_LENGTH(sizeof(struct ifinfomsg)))
-                                        k = -EIO;
-                                else {
-                                        ifi = NLMSG_DATA(m->hdr);
-                                        UPDATE_RTA(m, IFLA_RTA(ifi));
-                                }
-                                break;
-                        case RTM_NEWADDR:
-                        case RTM_DELADDR:
-                        case RTM_GETADDR:
-                                if (m->hdr->nlmsg_len < NLMSG_LENGTH(sizeof(struct ifaddrmsg)))
-                                        k = -EIO;
-                                else {
-                                        ifa = NLMSG_DATA(m->hdr);
-                                        UPDATE_RTA(m, IFA_RTA(ifa));
-                                }
-                                break;
-                        case RTM_NEWROUTE:
-                        case RTM_DELROUTE:
-                        case RTM_GETROUTE:
-                                if (m->hdr->nlmsg_len < NLMSG_LENGTH(sizeof(struct rtmsg)))
-                                        k = -EIO;
-                                else {
-                                        rtm = NLMSG_DATA(m->hdr);
-                                        UPDATE_RTA(m, RTM_RTA(rtm));
-                                }
-                                break;
-                        case NLMSG_NOOP:
-                                k = 0;
-                                break;
-                        default:
-                                k = 0; /* ignoring message of unknown type */
+                        }
                 }
+        }
 
-        if (k <= 0)
-                sd_rtnl_message_unref(m);
-        else {
-                /* we probably allocated way too much memory, give it back */
-                m->hdr = realloc(m->hdr, m->hdr->nlmsg_len);
-                *ret = m;
+        for (new_msg = rtnl->rbuffer; NLMSG_OK(new_msg, len); new_msg = NLMSG_NEXT(new_msg, len)) {
+                _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
+                const NLType *nl_type;
+
+                if (!group && new_msg->nlmsg_pid != rtnl->sockaddr.nl.nl_pid)
+                        /* not broadcast and not for us */
+                        continue;
+
+                if (new_msg->nlmsg_type == NLMSG_NOOP)
+                        /* silently drop noop messages */
+                        continue;
+
+                if (new_msg->nlmsg_type == NLMSG_DONE) {
+                        /* finished reading multi-part message */
+                        done = true;
+                        break;
+                }
+
+                /* check that we support this message type */
+                r = type_system_get_type(NULL, &nl_type, new_msg->nlmsg_type);
+                if (r < 0) {
+                        if (r == -ENOTSUP)
+                                log_debug("sd-rtnl: ignored message with unknown type: %u",
+                                          new_msg->nlmsg_type);
+
+                        continue;
+                }
+
+                /* check that the size matches the message type */
+                if (new_msg->nlmsg_len < NLMSG_LENGTH(nl_type->size))
+                        continue;
+
+                r = message_new_empty(rtnl, &m);
+                if (r < 0)
+                        return r;
+
+                m->hdr = memdup(new_msg, new_msg->nlmsg_len);
+                if (!m->hdr)
+                        return -ENOMEM;
+
+                /* seal and parse the top-level message */
+                r = sd_rtnl_message_rewind(m);
+                if (r < 0)
+                        return r;
+
+                /* push the message onto the multi-part message stack */
+                if (first)
+                        m->next = first;
+                first = m;
+                m = NULL;
         }
 
-        return k;
+        if (len)
+                log_debug("sd-rtnl: discarding %zu bytes of incoming message", len);
+
+        if (!first)
+                return 0;
+
+        if (!multi_part || done) {
+                /* we got a complete message, push it on the read queue */
+                r = rtnl_rqueue_make_room(rtnl);
+                if (r < 0)
+                        return r;
+
+                rtnl->rqueue[rtnl->rqueue_size ++] = first;
+                first = NULL;
+
+                if (multi_part && (i < rtnl->rqueue_partial_size)) {
+                        /* remove the message form the partial read queue */
+                        memmove(rtnl->rqueue_partial + i,rtnl->rqueue_partial + i + 1,
+                                sizeof(sd_rtnl_message*) * (rtnl->rqueue_partial_size - i - 1));
+                        rtnl->rqueue_partial_size --;
+                }
+
+                return 1;
+        } else {
+                /* we only got a partial multi-part message, push it on the
+                   partial read queue */
+                if (i < rtnl->rqueue_partial_size) {
+                        rtnl->rqueue_partial[i] = first;
+                } else {
+                        r = rtnl_rqueue_partial_make_room(rtnl);
+                        if (r < 0)
+                                return r;
+
+                        rtnl->rqueue_partial[rtnl->rqueue_partial_size ++] = first;
+                }
+                first = NULL;
+
+                return 0;
+        }
 }
 
 int sd_rtnl_message_rewind(sd_rtnl_message *m) {
-        struct ifinfomsg *ifi;
-        struct ifaddrmsg *ifa;
-        struct rtmsg *rtm;
+        const NLType *type;
+        unsigned i;
+        int r;
 
         assert_return(m, -EINVAL);
-        assert_return(m->sealed, -EPERM);
-        assert_return(m->hdr, -EINVAL);
 
-        switch(m->hdr->nlmsg_type) {
-                case RTM_NEWLINK:
-                case RTM_SETLINK:
-                case RTM_GETLINK:
-                case RTM_DELLINK:
-                        ifi = NLMSG_DATA(m->hdr);
-                        UPDATE_RTA(m, IFLA_RTA(ifi));
+        /* don't allow appending to message once parsed */
+        if (!m->sealed)
+                rtnl_message_seal(m);
 
-                        break;
-                case RTM_NEWADDR:
-                case RTM_GETADDR:
-                case RTM_DELADDR:
-                        ifa = NLMSG_DATA(m->hdr);
-                        UPDATE_RTA(m, IFA_RTA(ifa));
+        for (i = 1; i <= m->n_containers; i++) {
+                free(m->rta_offset_tb[i]);
+                m->rta_offset_tb[i] = NULL;
+                m->rta_tb_size[i] = 0;
+                m->container_type_system[i] = NULL;
+        }
 
-                        break;
-                case RTM_NEWROUTE:
-                case RTM_GETROUTE:
-                case RTM_DELROUTE:
-                        rtm = NLMSG_DATA(m->hdr);
-                        UPDATE_RTA(m, RTM_RTA(rtm));
+        m->n_containers = 0;
 
-                        break;
-                default:
-                        return -ENOTSUP;
+        if (m->rta_offset_tb[0]) {
+                /* top-level attributes have already been parsed */
+                return 0;
         }
 
-        m->n_containers = 0;
+        assert(m->hdr);
+
+        r = type_system_get_type(NULL, &type, m->hdr->nlmsg_type);
+        if (r < 0)
+                return r;
+
+        if (type->type == NLA_NESTED) {
+                const NLTypeSystem *type_system = type->type_system;
+
+                assert(type_system);
+
+                m->container_type_system[0] = type_system;
+
+                r = rtnl_message_parse(m,
+                                       &m->rta_offset_tb[m->n_containers],
+                                       &m->rta_tb_size[m->n_containers],
+                                       type_system->max,
+                                       (struct rtattr*)((uint8_t*)NLMSG_DATA(m->hdr) +
+                                                        NLMSG_ALIGN(type->size)),
+                                       NLMSG_PAYLOAD(m->hdr, type->size));
+                if (r < 0)
+                        return r;
+        }
 
         return 0;
 }
+
+void rtnl_message_seal(sd_rtnl_message *m) {
+        assert(m);
+        assert(!m->sealed);
+
+        m->sealed = true;
+}
+
+sd_rtnl_message *sd_rtnl_message_next(sd_rtnl_message *m) {
+        assert_return(m, NULL);
+
+        return m->next;
+}
diff --git a/src/libsystemd/sd-rtnl/rtnl-types.c b/src/libsystemd/sd-rtnl/rtnl-types.c
new file mode 100644 (file)
index 0000000..df9a45d
--- /dev/null
@@ -0,0 +1,413 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Tom Gundersen <teg@jklm.no>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stddef.h>
+#include <stdint.h>
+#include <sys/socket.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <linux/in6.h>
+#include <linux/veth.h>
+#include <linux/if_bridge.h>
+#include <linux/if_addr.h>
+#include <linux/if.h>
+
+#include <linux/ip.h>
+#include <linux/if_tunnel.h>
+
+#include "macro.h"
+#include "util.h"
+
+#include "rtnl-types.h"
+#include "missing.h"
+
+static const NLTypeSystem rtnl_link_type_system;
+
+static const NLType rtnl_link_info_data_veth_types[VETH_INFO_MAX + 1] = {
+        [VETH_INFO_PEER]  = { .type = NLA_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
+};
+
+
+static const NLType rtnl_link_info_data_macvlan_types[IFLA_MACVLAN_MAX + 1] = {
+        [IFLA_MACVLAN_MODE]  = { .type = NLA_U32 },
+        [IFLA_MACVLAN_FLAGS] = { .type = NLA_U16 },
+};
+
+static const NLType rtnl_link_info_data_bridge_types[IFLA_BRIDGE_MAX + 1] = {
+        [IFLA_BRIDGE_FLAGS]     = { .type = NLA_U16 },
+        [IFLA_BRIDGE_MODE]      = { .type = NLA_U16 },
+/*
+        [IFLA_BRIDGE_VLAN_INFO] = { .type = NLA_BINARY,
+                                    .len = sizeof(struct bridge_vlan_info), },
+*/
+};
+
+static const NLType rtnl_link_info_data_vlan_types[IFLA_VLAN_MAX + 1] = {
+        [IFLA_VLAN_ID]          = { .type = NLA_U16 },
+/*
+        [IFLA_VLAN_FLAGS]       = { .len = sizeof(struct ifla_vlan_flags) },
+        [IFLA_VLAN_EGRESS_QOS]  = { .type = NLA_NESTED },
+        [IFLA_VLAN_INGRESS_QOS] = { .type = NLA_NESTED },
+*/
+        [IFLA_VLAN_PROTOCOL]    = { .type = NLA_U16 },
+};
+
+static const NLType rtnl_link_info_data_vxlan_types[IFLA_VXLAN_MAX+1] = {
+        [IFLA_VXLAN_ID] = { .type = NLA_U32 },
+        [IFLA_VXLAN_GROUP] = {.type = NLA_IN_ADDR },
+        [IFLA_VXLAN_LINK] = { .type = NLA_U32 },
+        [IFLA_VXLAN_LOCAL] = { .type = NLA_U32},
+        [IFLA_VXLAN_TTL] = { .type = NLA_U8 },
+        [IFLA_VXLAN_TOS] = { .type = NLA_U8 },
+        [IFLA_VXLAN_LEARNING] = { .type = NLA_U8 },
+        [IFLA_VXLAN_AGEING] = { .type = NLA_U32 },
+        [IFLA_VXLAN_LIMIT] = { .type = NLA_U32 },
+        [IFLA_VXLAN_PORT_RANGE] = { .type = NLA_U32},
+        [IFLA_VXLAN_PROXY] = { .type = NLA_U8 },
+        [IFLA_VXLAN_RSC] = { .type = NLA_U8 },
+        [IFLA_VXLAN_L2MISS] = { .type = NLA_U8 },
+        [IFLA_VXLAN_L3MISS] = { .type = NLA_U8 },
+};
+
+static const NLType rtnl_link_info_data_bond_types[IFLA_BOND_MAX + 1] = {
+        [IFLA_BOND_MODE]                = { .type = NLA_U8 },
+        [IFLA_BOND_ACTIVE_SLAVE]        = { .type = NLA_U32 },
+        [IFLA_BOND_MIIMON]              = { .type = NLA_U32 },
+        [IFLA_BOND_UPDELAY]             = { .type = NLA_U32 },
+        [IFLA_BOND_DOWNDELAY]           = { .type = NLA_U32 },
+        [IFLA_BOND_USE_CARRIER]         = { .type = NLA_U8 },
+        [IFLA_BOND_ARP_INTERVAL]        = { .type = NLA_U32 },
+        [IFLA_BOND_ARP_IP_TARGET]       = { .type = NLA_NESTED },
+        [IFLA_BOND_ARP_VALIDATE]        = { .type = NLA_U32 },
+        [IFLA_BOND_ARP_ALL_TARGETS]     = { .type = NLA_U32 },
+        [IFLA_BOND_PRIMARY]             = { .type = NLA_U32 },
+        [IFLA_BOND_PRIMARY_RESELECT]    = { .type = NLA_U8 },
+        [IFLA_BOND_FAIL_OVER_MAC]       = { .type = NLA_U8 },
+        [IFLA_BOND_XMIT_HASH_POLICY]    = { .type = NLA_U8 },
+        [IFLA_BOND_RESEND_IGMP]         = { .type = NLA_U32 },
+        [IFLA_BOND_NUM_PEER_NOTIF]      = { .type = NLA_U8 },
+        [IFLA_BOND_ALL_SLAVES_ACTIVE]   = { .type = NLA_U8 },
+        [IFLA_BOND_MIN_LINKS]           = { .type = NLA_U32 },
+        [IFLA_BOND_LP_INTERVAL]         = { .type = NLA_U32 },
+        [IFLA_BOND_PACKETS_PER_SLAVE]   = { .type = NLA_U32 },
+        [IFLA_BOND_AD_LACP_RATE]        = { .type = NLA_U8 },
+        [IFLA_BOND_AD_SELECT]           = { .type = NLA_U8 },
+        [IFLA_BOND_AD_INFO]             = { .type = NLA_NESTED },
+};
+
+static const NLType rtnl_link_info_data_iptun_types[IFLA_IPTUN_MAX + 1] = {
+        [IFLA_IPTUN_LINK]                = { .type = NLA_U32 },
+        [IFLA_IPTUN_LOCAL]               = { .type = NLA_IN_ADDR },
+        [IFLA_IPTUN_REMOTE]              = { .type = NLA_IN_ADDR },
+        [IFLA_IPTUN_TTL]                 = { .type = NLA_U8 },
+        [IFLA_IPTUN_TOS]                 = { .type = NLA_U8 },
+        [IFLA_IPTUN_PMTUDISC]            = { .type = NLA_U8 },
+        [IFLA_IPTUN_FLAGS]               = { .type = NLA_U16 },
+        [IFLA_IPTUN_PROTO]               = { .type = NLA_U8 },
+        [IFLA_IPTUN_6RD_PREFIX]          = { .type = NLA_IN_ADDR },
+        [IFLA_IPTUN_6RD_RELAY_PREFIX]    = { .type = NLA_U32 },
+        [IFLA_IPTUN_6RD_PREFIXLEN]       = { .type = NLA_U16 },
+        [IFLA_IPTUN_6RD_RELAY_PREFIXLEN] = { .type = NLA_U16 },
+};
+
+static  const NLType rtnl_link_info_data_ipgre_types[IFLA_GRE_MAX + 1] = {
+        [IFLA_GRE_LINK]     = { .type = NLA_U32 },
+        [IFLA_GRE_IFLAGS]   = { .type = NLA_U16 },
+        [IFLA_GRE_OFLAGS]   = { .type = NLA_U16 },
+        [IFLA_GRE_IKEY]     = { .type = NLA_U32 },
+        [IFLA_GRE_OKEY]     = { .type = NLA_U32 },
+        [IFLA_GRE_LOCAL]    = { .type = NLA_IN_ADDR },
+        [IFLA_GRE_REMOTE]   = { .type = NLA_IN_ADDR },
+        [IFLA_GRE_TTL]      = { .type = NLA_U8 },
+        [IFLA_GRE_TOS]      = { .type = NLA_U8 },
+        [IFLA_GRE_PMTUDISC] = { .type = NLA_U8 },
+};
+
+static const NLType rtnl_link_info_data_ipvti_types[IFLA_VTI_MAX + 1] = {
+        [IFLA_VTI_LINK]         = { .type = NLA_U32 },
+        [IFLA_VTI_IKEY]         = { .type = NLA_U32 },
+        [IFLA_VTI_OKEY]         = { .type = NLA_U32 },
+        [IFLA_VTI_LOCAL]        = { .type = NLA_IN_ADDR  },
+        [IFLA_VTI_REMOTE]       = { .type = NLA_IN_ADDR  },
+};
+
+/* these strings must match the .kind entries in the kernel */
+static const char* const nl_union_link_info_data_table[_NL_UNION_LINK_INFO_DATA_MAX] = {
+        [NL_UNION_LINK_INFO_DATA_BOND] = "bond",
+        [NL_UNION_LINK_INFO_DATA_BRIDGE] = "bridge",
+        [NL_UNION_LINK_INFO_DATA_VLAN] = "vlan",
+        [NL_UNION_LINK_INFO_DATA_VETH] = "veth",
+        [NL_UNION_LINK_INFO_DATA_DUMMY] = "dummy",
+        [NL_UNION_LINK_INFO_DATA_MACVLAN] = "macvlan",
+        [NL_UNION_LINK_INFO_DATA_VXLAN] = "vxlan",
+        [NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL] = "ipip",
+        [NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL] = "gre",
+        [NL_UNION_LINK_INFO_DATA_SIT_TUNNEL] = "sit",
+        [NL_UNION_LINK_INFO_DATA_VTI_TUNNEL] = "vti",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(nl_union_link_info_data, NLUnionLinkInfoData);
+
+static const NLTypeSystem rtnl_link_info_data_type_systems[_NL_UNION_LINK_INFO_DATA_MAX] = {
+        [NL_UNION_LINK_INFO_DATA_BOND] =        { .max = ELEMENTSOF(rtnl_link_info_data_bond_types) - 1,
+                                                  .types = rtnl_link_info_data_bond_types },
+        [NL_UNION_LINK_INFO_DATA_BRIDGE] =      { .max = ELEMENTSOF(rtnl_link_info_data_bridge_types) - 1,
+                                                  .types = rtnl_link_info_data_bridge_types },
+        [NL_UNION_LINK_INFO_DATA_VLAN] =        { .max = ELEMENTSOF(rtnl_link_info_data_vlan_types) - 1,
+                                                  .types = rtnl_link_info_data_vlan_types },
+        [NL_UNION_LINK_INFO_DATA_VETH] =        { .max = ELEMENTSOF(rtnl_link_info_data_veth_types) - 1,
+                                                  .types = rtnl_link_info_data_veth_types },
+        [NL_UNION_LINK_INFO_DATA_MACVLAN] =     { .max = ELEMENTSOF(rtnl_link_info_data_macvlan_types) - 1,
+                                                  .types = rtnl_link_info_data_macvlan_types },
+        [NL_UNION_LINK_INFO_DATA_VXLAN] =       { .max = ELEMENTSOF(rtnl_link_info_data_vxlan_types) - 1,
+                                                  .types = rtnl_link_info_data_vxlan_types },
+        [NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_iptun_types) - 1,
+                                                  .types = rtnl_link_info_data_iptun_types },
+        [NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL] =  { .max = ELEMENTSOF(rtnl_link_info_data_ipgre_types) - 1,
+                                                    .types = rtnl_link_info_data_ipgre_types },
+        [NL_UNION_LINK_INFO_DATA_SIT_TUNNEL] =  { .max = ELEMENTSOF(rtnl_link_info_data_iptun_types) - 1,
+                                                  .types = rtnl_link_info_data_iptun_types },
+        [NL_UNION_LINK_INFO_DATA_VTI_TUNNEL] =  { .max = ELEMENTSOF(rtnl_link_info_data_ipvti_types) - 1,
+                                                  .types = rtnl_link_info_data_ipvti_types },
+};
+
+static const NLTypeSystemUnion rtnl_link_info_data_type_system_union = {
+        .num = _NL_UNION_LINK_INFO_DATA_MAX,
+        .lookup = nl_union_link_info_data_from_string,
+        .type_systems = rtnl_link_info_data_type_systems,
+        .match = IFLA_INFO_KIND,
+};
+
+static const NLType rtnl_link_info_types[IFLA_INFO_MAX + 1] = {
+        [IFLA_INFO_KIND]        = { .type = NLA_STRING },
+        [IFLA_INFO_DATA]        = { .type = NLA_UNION, .type_system_union = &rtnl_link_info_data_type_system_union},
+/*
+        [IFLA_INFO_XSTATS],
+        [IFLA_INFO_SLAVE_KIND]  = { .type = NLA_STRING },
+        [IFLA_INFO_SLAVE_DATA]  = { .type = NLA_NESTED },
+*/
+};
+
+static const NLTypeSystem rtnl_link_info_type_system = {
+        .max = ELEMENTSOF(rtnl_link_info_types) - 1,
+        .types = rtnl_link_info_types,
+};
+
+static const NLType rtnl_link_types[IFLA_MAX + 1] = {
+        [IFLA_ADDRESS]          = { .type = NLA_ETHER_ADDR, },
+        [IFLA_BROADCAST]        = { .type = NLA_ETHER_ADDR, },
+        [IFLA_IFNAME]           = { .type = NLA_STRING, .size = IFNAMSIZ - 1, },
+        [IFLA_MTU]              = { .type = NLA_U32 },
+        [IFLA_LINK]             = { .type = NLA_U32 },
+/*
+        [IFLA_QDISC],
+        [IFLA_STATS],
+        [IFLA_COST],
+        [IFLA_PRIORITY],
+*/
+        [IFLA_MASTER]           = { .type = NLA_U32 },
+/*
+        [IFLA_WIRELESS],
+        [IFLA_PROTINFO],
+*/
+        [IFLA_TXQLEN]           = { .type = NLA_U32 },
+/*
+        [IFLA_MAP]              = { .len = sizeof(struct rtnl_link_ifmap) },
+*/
+        [IFLA_WEIGHT]           = { .type = NLA_U32 },
+        [IFLA_OPERSTATE]        = { .type = NLA_U8 },
+        [IFLA_LINKMODE]         = { .type = NLA_U8 },
+        [IFLA_LINKINFO]         = { .type = NLA_NESTED, .type_system = &rtnl_link_info_type_system },
+        [IFLA_NET_NS_PID]       = { .type = NLA_U32 },
+        [IFLA_IFALIAS]          = { .type = NLA_STRING, .size = IFALIASZ - 1 },
+/*
+        [IFLA_NUM_VF],
+        [IFLA_VFINFO_LIST]      = {. type = NLA_NESTED, },
+        [IFLA_STATS64],
+        [IFLA_VF_PORTS]         = { .type = NLA_NESTED },
+        [IFLA_PORT_SELF]        = { .type = NLA_NESTED },
+        [IFLA_AF_SPEC]          = { .type = NLA_NESTED },
+        [IFLA_VF_PORTS],
+        [IFLA_PORT_SELF],
+        [IFLA_AF_SPEC],
+*/
+        [IFLA_GROUP]            = { .type = NLA_U32 },
+        [IFLA_NET_NS_FD]        = { .type = NLA_U32 },
+        [IFLA_EXT_MASK]         = { .type = NLA_U32 },
+        [IFLA_PROMISCUITY]      = { .type = NLA_U32 },
+        [IFLA_NUM_TX_QUEUES]    = { .type = NLA_U32 },
+        [IFLA_NUM_RX_QUEUES]    = { .type = NLA_U32 },
+        [IFLA_CARRIER]          = { .type = NLA_U8 },
+/*
+        [IFLA_PHYS_PORT_ID]     = { .type = NLA_BINARY, .len = MAX_PHYS_PORT_ID_LEN },
+*/
+};
+
+static const NLTypeSystem rtnl_link_type_system = {
+        .max = ELEMENTSOF(rtnl_link_types) - 1,
+        .types = rtnl_link_types,
+};
+
+static const NLType rtnl_address_types[IFA_MAX + 1] = {
+        [IFA_ADDRESS]           = { .type = NLA_IN_ADDR },
+        [IFA_LOCAL]             = { .type = NLA_IN_ADDR },
+        [IFA_LABEL]             = { .type = NLA_STRING, .size = IFNAMSIZ - 1 },
+        [IFA_BROADCAST]         = { .type = NLA_IN_ADDR }, /* 6? */
+        [IFA_CACHEINFO]         = { .type = NLA_CACHE_INFO, .size = sizeof(struct ifa_cacheinfo) },
+/*
+        [IFA_ANYCAST],
+        [IFA_MULTICAST],
+*/
+#ifdef IFA_FLAGS
+        [IFA_FLAGS]             = { .type = NLA_U32 },
+#endif
+};
+
+static const NLTypeSystem rtnl_address_type_system = {
+        .max = ELEMENTSOF(rtnl_address_types) - 1,
+        .types = rtnl_address_types,
+};
+
+static const NLType rtnl_route_types[RTA_MAX + 1] = {
+        [RTA_DST]               = { .type = NLA_IN_ADDR }, /* 6? */
+        [RTA_SRC]               = { .type = NLA_IN_ADDR }, /* 6? */
+        [RTA_IIF]               = { .type = NLA_U32 },
+        [RTA_OIF]               = { .type = NLA_U32 },
+        [RTA_GATEWAY]           = { .type = NLA_IN_ADDR },
+        [RTA_PRIORITY]          = { .type = NLA_U32 },
+        [RTA_PREFSRC]           = { .type = NLA_IN_ADDR }, /* 6? */
+/*
+        [RTA_METRICS]           = { .type = NLA_NESTED },
+        [RTA_MULTIPATH]         = { .len = sizeof(struct rtnexthop) },
+*/
+        [RTA_FLOW]              = { .type = NLA_U32 }, /* 6? */
+/*
+        RTA_CACHEINFO,
+        RTA_TABLE,
+        RTA_MARK,
+        RTA_MFC_STATS,
+*/
+};
+
+static const NLTypeSystem rtnl_route_type_system = {
+        .max = ELEMENTSOF(rtnl_route_types) - 1,
+        .types = rtnl_route_types,
+};
+
+static const NLType rtnl_types[RTM_MAX + 1] = {
+        [NLMSG_ERROR]  = { .type = NLA_META, .size = sizeof(struct nlmsgerr) },
+        [RTM_NEWLINK]  = { .type = NLA_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
+        [RTM_DELLINK]  = { .type = NLA_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
+        [RTM_GETLINK]  = { .type = NLA_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
+        [RTM_SETLINK]  = { .type = NLA_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
+        [RTM_NEWADDR]  = { .type = NLA_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
+        [RTM_DELADDR]  = { .type = NLA_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
+        [RTM_GETADDR]  = { .type = NLA_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
+        [RTM_NEWROUTE] = { .type = NLA_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
+        [RTM_DELROUTE] = { .type = NLA_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
+        [RTM_GETROUTE] = { .type = NLA_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
+};
+
+const NLTypeSystem rtnl_type_system = {
+        .max = ELEMENTSOF(rtnl_types) - 1,
+        .types = rtnl_types,
+};
+
+int type_system_get_type(const NLTypeSystem *type_system, const NLType **ret, uint16_t type) {
+        const NLType *nl_type;
+
+        assert(ret);
+
+        if (!type_system)
+                type_system = &rtnl_type_system;
+
+        assert(type_system->types);
+
+        if (type > type_system->max)
+                return -ENOTSUP;
+
+        nl_type = &type_system->types[type];
+
+        if (nl_type->type == NLA_UNSPEC)
+                return -ENOTSUP;
+
+        *ret = nl_type;
+
+        return 0;
+}
+
+int type_system_get_type_system(const NLTypeSystem *type_system, const NLTypeSystem **ret, uint16_t type) {
+        const NLType *nl_type;
+        int r;
+
+        assert(ret);
+
+        r = type_system_get_type(type_system, &nl_type, type);
+        if (r < 0)
+                return r;
+
+        assert_return(nl_type->type == NLA_NESTED, -EINVAL);
+
+        assert(nl_type->type_system);
+
+        *ret = nl_type->type_system;
+
+        return 0;
+}
+
+int type_system_get_type_system_union(const NLTypeSystem *type_system, const NLTypeSystemUnion **ret, uint16_t type) {
+        const NLType *nl_type;
+        int r;
+
+        assert(ret);
+
+        r = type_system_get_type(type_system, &nl_type, type);
+        if (r < 0)
+                return r;
+
+        assert_return(nl_type->type == NLA_UNION, -EINVAL);
+
+        assert(nl_type->type_system_union);
+
+        *ret = nl_type->type_system_union;
+
+        return 0;
+}
+
+int type_system_union_get_type_system(const NLTypeSystemUnion *type_system_union, const NLTypeSystem **ret, const char *key) {
+        int type;
+
+        assert(type_system_union);
+        assert(type_system_union->lookup);
+        assert(type_system_union->type_systems);
+        assert(ret);
+        assert(key);
+
+        type = type_system_union->lookup(key);
+        if (type < 0)
+                return -ENOTSUP;
+
+        assert(type < type_system_union->num);
+
+        *ret = &type_system_union->type_systems[type];
+
+        return 0;
+}
diff --git a/src/libsystemd/sd-rtnl/rtnl-types.h b/src/libsystemd/sd-rtnl/rtnl-types.h
new file mode 100644 (file)
index 0000000..8621746
--- /dev/null
@@ -0,0 +1,84 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Tom Gundersen <teg@jklm.no>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+enum {
+        NLA_UNSPEC,
+        NLA_META,
+        NLA_U8,
+        NLA_U16,
+        NLA_U32,
+        NLA_U64,
+        NLA_STRING,
+        NLA_IN_ADDR,
+        NLA_ETHER_ADDR,
+        NLA_CACHE_INFO,
+        NLA_NESTED,
+        NLA_UNION,
+};
+
+typedef struct NLTypeSystemUnion NLTypeSystemUnion;
+typedef struct NLTypeSystem NLTypeSystem;
+typedef struct NLType NLType;
+
+struct NLTypeSystemUnion {
+        int num;
+        uint16_t match;
+        int (*lookup)(const char *);
+        const NLTypeSystem *type_systems;
+};
+
+struct NLTypeSystem {
+        uint16_t max;
+        const NLType *types;
+};
+
+struct NLType {
+        uint16_t type;
+        size_t size;
+        const NLTypeSystem *type_system;
+        const NLTypeSystemUnion *type_system_union;
+};
+
+int type_system_get_type(const NLTypeSystem *type_system, const NLType **ret, uint16_t type);
+int type_system_get_type_system(const NLTypeSystem *type_system, const NLTypeSystem **ret, uint16_t type);
+int type_system_get_type_system_union(const NLTypeSystem *type_system, const NLTypeSystemUnion **ret, uint16_t type);
+int type_system_union_get_type_system(const NLTypeSystemUnion *type_system_union, const NLTypeSystem **ret, const char *key);
+
+typedef enum NLUnionLinkInfoData {
+        NL_UNION_LINK_INFO_DATA_BOND,
+        NL_UNION_LINK_INFO_DATA_BRIDGE,
+        NL_UNION_LINK_INFO_DATA_VLAN,
+        NL_UNION_LINK_INFO_DATA_VETH,
+        NL_UNION_LINK_INFO_DATA_DUMMY,
+        NL_UNION_LINK_INFO_DATA_MACVLAN,
+        NL_UNION_LINK_INFO_DATA_VXLAN,
+        NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL,
+        NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL,
+        NL_UNION_LINK_INFO_DATA_SIT_TUNNEL,
+        NL_UNION_LINK_INFO_DATA_VTI_TUNNEL,
+        _NL_UNION_LINK_INFO_DATA_MAX,
+        _NL_UNION_LINK_INFO_DATA_INVALID = -1
+} NLUnionLinkInfoData;
+
+const char *nl_union_link_info_data_to_string(NLUnionLinkInfoData p) _const_;
+NLUnionLinkInfoData nl_union_link_info_data_from_string(const char *p) _pure_;
index fc834e9..0bc2c9b 100644 (file)
@@ -154,18 +154,12 @@ bool rtnl_message_type_is_addr(uint16_t type) {
         }
 }
 
-int rtnl_message_link_get_ifname(sd_rtnl_message *message, const char **ret) {
-        unsigned short type;
-        void *name;
-
-        assert(rtnl_message_type_is_link(message->hdr->nlmsg_type));
-
-        while (sd_rtnl_message_read(message, &type, &name)) {
-                if (type == IFLA_IFNAME) {
-                        *ret = name;
-                        return 0;
-                }
-        }
+int rtnl_log_parse_error(int r) {
+        log_error("Failed to parse netlink message: %s", strerror(-r));
+        return r;
+}
 
-        return -ENOENT;
+int rtnl_log_create_error(int r) {
+        log_error("Failed to create netlink message: %s", strerror(-r));
+        return r;
 }
index 33746af..2963f02 100644 (file)
@@ -28,7 +28,7 @@
 
 int rtnl_message_new_synthetic_error(int error, uint32_t serial, sd_rtnl_message **ret);
 uint32_t rtnl_message_get_serial(sd_rtnl_message *m);
-int rtnl_message_seal(sd_rtnl *nl, sd_rtnl_message *m);
+void rtnl_message_seal(sd_rtnl_message *m);
 
 bool rtnl_message_type_is_link(uint16_t type);
 bool rtnl_message_type_is_addr(uint16_t type);
@@ -37,7 +37,8 @@ bool rtnl_message_type_is_route(uint16_t type);
 int rtnl_set_link_name(sd_rtnl *rtnl, int ifindex, const char *name);
 int rtnl_set_link_properties(sd_rtnl *rtnl, int ifindex, const char *alias, const struct ether_addr *mac, unsigned mtu);
 
-int rtnl_message_link_get_ifname(sd_rtnl_message *m, const char **ret);
+int rtnl_log_parse_error(int r);
+int rtnl_log_create_error(int r);
 
 DEFINE_TRIVIAL_CLEANUP_FUNC(sd_rtnl*, sd_rtnl_unref);
 DEFINE_TRIVIAL_CLEANUP_FUNC(sd_rtnl_message*, sd_rtnl_message_unref);
index 1b9f583..c19bad1 100644 (file)
@@ -22,6 +22,7 @@
 #include <sys/socket.h>
 #include <poll.h>
 
+#include "missing.h"
 #include "macro.h"
 #include "util.h"
 #include "hashmap.h"
@@ -31,7 +32,7 @@
 #include "rtnl-util.h"
 
 static int sd_rtnl_new(sd_rtnl **ret) {
-        sd_rtnl *rtnl;
+        _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
 
         assert_return(ret, -EINVAL);
 
@@ -51,13 +52,18 @@ static int sd_rtnl_new(sd_rtnl **ret) {
 
         /* We guarantee that wqueue always has space for at least
          * one entry */
-        rtnl->wqueue = new(sd_rtnl_message*, 1);
-        if (!rtnl->wqueue) {
-                free(rtnl);
+        if (!GREEDY_REALLOC(rtnl->wqueue, rtnl->wqueue_allocated, 1))
+                return -ENOMEM;
+
+        /* We guarantee that the read buffer has at least space for
+         * a message header */
+        if (!greedy_realloc((void**)&rtnl->rbuffer, &rtnl->rbuffer_allocated,
+                            sizeof(struct nlmsghdr), sizeof(uint8_t)))
                 return -ENOMEM;
-        }
 
         *ret = rtnl;
+        rtnl = NULL;
+
         return 0;
 }
 
@@ -70,10 +76,29 @@ static bool rtnl_pid_changed(sd_rtnl *rtnl) {
         return rtnl->original_pid != getpid();
 }
 
-int sd_rtnl_open(sd_rtnl **ret, uint32_t groups) {
+static int rtnl_compute_groups_ap(uint32_t *_groups, unsigned n_groups, va_list ap) {
+        uint32_t groups = 0;
+        unsigned i;
+
+        for (i = 0; i < n_groups; i++) {
+                unsigned group;
+
+                group = va_arg(ap, unsigned);
+                assert_return(group < 32, -EINVAL);
+
+                groups |= group ? (1 << (group - 1)) : 0;
+        }
+
+        *_groups = groups;
+
+        return 0;
+}
+
+int sd_rtnl_open(sd_rtnl **ret, unsigned n_groups, ...) {
         _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
+        va_list ap;
         socklen_t addrlen;
-        int r;
+        int r, one = 1;
 
         assert_return(ret, -EINVAL);
 
@@ -85,7 +110,19 @@ int sd_rtnl_open(sd_rtnl **ret, uint32_t groups) {
         if (rtnl->fd < 0)
                 return -errno;
 
-        rtnl->sockaddr.nl.nl_groups = groups;
+        r = setsockopt(rtnl->fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one));
+        if (r < 0)
+                return -errno;
+
+        r = setsockopt(rtnl->fd, SOL_NETLINK, NETLINK_PKTINFO, &one, sizeof(one));
+        if (r < 0)
+                return -errno;
+
+        va_start(ap, n_groups);
+        r = rtnl_compute_groups_ap(&rtnl->sockaddr.nl.nl_groups, n_groups, ap);
+        va_end(ap);
+        if (r < 0)
+                return r;
 
         addrlen = sizeof(rtnl->sockaddr);
 
@@ -104,6 +141,9 @@ int sd_rtnl_open(sd_rtnl **ret, uint32_t groups) {
 }
 
 sd_rtnl *sd_rtnl_ref(sd_rtnl *rtnl) {
+        assert_return(rtnl, NULL);
+        assert_return(!rtnl_pid_changed(rtnl), NULL);
+
         if (rtnl)
                 assert_se(REFCNT_INC(rtnl->n_ref) >= 2);
 
@@ -111,8 +151,12 @@ sd_rtnl *sd_rtnl_ref(sd_rtnl *rtnl) {
 }
 
 sd_rtnl *sd_rtnl_unref(sd_rtnl *rtnl) {
+        if (!rtnl)
+                return NULL;
+
+        assert_return(!rtnl_pid_changed(rtnl), NULL);
 
-        if (rtnl && REFCNT_DEC(rtnl->n_ref) <= 0) {
+        if (REFCNT_DEC(rtnl->n_ref) <= 0) {
                 struct match_callback *f;
                 unsigned i;
 
@@ -120,27 +164,49 @@ sd_rtnl *sd_rtnl_unref(sd_rtnl *rtnl) {
                         sd_rtnl_message_unref(rtnl->rqueue[i]);
                 free(rtnl->rqueue);
 
+                for (i = 0; i < rtnl->rqueue_partial_size; i++)
+                        sd_rtnl_message_unref(rtnl->rqueue_partial[i]);
+                free(rtnl->rqueue_partial);
+
                 for (i = 0; i < rtnl->wqueue_size; i++)
                         sd_rtnl_message_unref(rtnl->wqueue[i]);
                 free(rtnl->wqueue);
 
+                free(rtnl->rbuffer);
+
                 hashmap_free_free(rtnl->reply_callbacks);
                 prioq_free(rtnl->reply_callbacks_prioq);
 
+                sd_event_source_unref(rtnl->io_event_source);
+                sd_event_source_unref(rtnl->time_event_source);
+                sd_event_source_unref(rtnl->exit_event_source);
+                sd_event_unref(rtnl->event);
+
                 while ((f = rtnl->match_callbacks)) {
                         LIST_REMOVE(match_callbacks, rtnl->match_callbacks, f);
                         free(f);
                 }
 
-                if (rtnl->fd >= 0)
-                        close_nointr_nofail(rtnl->fd);
-
+                safe_close(rtnl->fd);
                 free(rtnl);
         }
 
         return NULL;
 }
 
+static void rtnl_seal_message(sd_rtnl *rtnl, sd_rtnl_message *m) {
+        assert(rtnl);
+        assert(!rtnl_pid_changed(rtnl));
+        assert(m);
+        assert(m->hdr);
+
+        m->hdr->nlmsg_seq = rtnl->serial++;
+
+        rtnl_message_seal(m);
+
+        return;
+}
+
 int sd_rtnl_send(sd_rtnl *nl,
                  sd_rtnl_message *message,
                  uint32_t *serial) {
@@ -149,10 +215,9 @@ int sd_rtnl_send(sd_rtnl *nl,
         assert_return(nl, -EINVAL);
         assert_return(!rtnl_pid_changed(nl), -ECHILD);
         assert_return(message, -EINVAL);
+        assert_return(!message->sealed, -EPERM);
 
-        r = rtnl_message_seal(nl, message);
-        if (r < 0)
-                return r;
+        rtnl_seal_message(nl, message);
 
         if (nl->wqueue_size <= 0) {
                 /* send directly */
@@ -166,18 +231,16 @@ int sd_rtnl_send(sd_rtnl *nl,
                         nl->wqueue_size = 1;
                 }
         } else {
-                sd_rtnl_message **q;
-
                 /* append to queue */
-                if (nl->wqueue_size >= RTNL_WQUEUE_MAX)
+                if (nl->wqueue_size >= RTNL_WQUEUE_MAX) {
+                        log_debug("rtnl: exhausted the write queue size (%d)", RTNL_WQUEUE_MAX);
                         return -ENOBUFS;
+                }
 
-                q = realloc(nl->wqueue, sizeof(sd_rtnl_message*) * (nl->wqueue_size + 1));
-                if (!q)
+                if (!GREEDY_REALLOC(nl->wqueue, nl->wqueue_allocated, nl->wqueue_size + 1))
                         return -ENOMEM;
 
-                nl->wqueue = q;
-                q[nl->wqueue_size ++] = sd_rtnl_message_ref(message);
+                nl->wqueue[nl->wqueue_size ++] = sd_rtnl_message_ref(message);
         }
 
         if (serial)
@@ -186,31 +249,52 @@ int sd_rtnl_send(sd_rtnl *nl,
         return 1;
 }
 
+int rtnl_rqueue_make_room(sd_rtnl *rtnl) {
+        assert(rtnl);
+
+        if (rtnl->rqueue_size >= RTNL_RQUEUE_MAX) {
+                log_debug("rtnl: exhausted the read queue size (%d)", RTNL_RQUEUE_MAX);
+                return -ENOBUFS;
+        }
+
+        if (!GREEDY_REALLOC(rtnl->rqueue, rtnl->rqueue_allocated, rtnl->rqueue_size + 1))
+                return -ENOMEM;
+
+        return 0;
+}
+
+int rtnl_rqueue_partial_make_room(sd_rtnl *rtnl) {
+        assert(rtnl);
+
+        if (rtnl->rqueue_partial_size >= RTNL_RQUEUE_MAX) {
+                log_debug("rtnl: exhausted the partial read queue size (%d)", RTNL_RQUEUE_MAX);
+                return -ENOBUFS;
+        }
+
+        if (!GREEDY_REALLOC(rtnl->rqueue_partial, rtnl->rqueue_partial_allocated,
+                            rtnl->rqueue_partial_size + 1))
+                return -ENOMEM;
+
+        return 0;
+}
+
 static int dispatch_rqueue(sd_rtnl *rtnl, sd_rtnl_message **message) {
-        sd_rtnl_message *z = NULL;
         int r;
 
         assert(rtnl);
         assert(message);
 
-        if (rtnl->rqueue_size > 0) {
-                /* Dispatch a queued message */
-
-                *message = rtnl->rqueue[0];
-                rtnl->rqueue_size --;
-                memmove(rtnl->rqueue, rtnl->rqueue + 1, sizeof(sd_rtnl_message*) * rtnl->rqueue_size);
-
-                return 1;
+        if (rtnl->rqueue_size <= 0) {
+                /* Try to read a new message */
+                r = socket_read_message(rtnl);
+                if (r <= 0)
+                        return r;
         }
 
-        /* Try to read a new message */
-        r = socket_read_message(rtnl, &z);
-        if (r < 0)
-                return r;
-        if (r == 0)
-                return 0;
-
-        *message = z;
+        /* Dispatch a queued message */
+        *message = rtnl->rqueue[0];
+        rtnl->rqueue_size --;
+        memmove(rtnl->rqueue, rtnl->rqueue + 1, sizeof(sd_rtnl_message*) * rtnl->rqueue_size);
 
         return 1;
 }
@@ -277,6 +361,9 @@ static int process_reply(sd_rtnl *rtnl, sd_rtnl_message *m) {
         assert(rtnl);
         assert(m);
 
+        if (sd_rtnl_message_is_broadcast(m))
+                return 0;
+
         serial = rtnl_message_get_serial(m);
         c = hashmap_remove(rtnl->reply_callbacks, &serial);
         if (!c)
@@ -386,7 +473,7 @@ static usec_t calc_elapse(uint64_t usec) {
 static int rtnl_poll(sd_rtnl *rtnl, bool need_more, uint64_t timeout_usec) {
         struct pollfd p[1] = {};
         struct timespec ts;
-        usec_t m = (usec_t) -1;
+        usec_t m = USEC_INFINITY;
         int r, e;
 
         assert(rtnl);
@@ -536,20 +623,20 @@ int sd_rtnl_call_async_cancel(sd_rtnl *nl, uint32_t serial) {
         return 1;
 }
 
-int sd_rtnl_call(sd_rtnl *nl,
+int sd_rtnl_call(sd_rtnl *rtnl,
                 sd_rtnl_message *message,
                 uint64_t usec,
                 sd_rtnl_message **ret) {
         usec_t timeout;
         uint32_t serial;
-        bool room = false;
+        unsigned i = 0;
         int r;
 
-        assert_return(nl, -EINVAL);
-        assert_return(!rtnl_pid_changed(nl), -ECHILD);
+        assert_return(rtnl, -EINVAL);
+        assert_return(!rtnl_pid_changed(rtnl), -ECHILD);
         assert_return(message, -EINVAL);
 
-        r = sd_rtnl_send(nl, message, &serial);
+        r = sd_rtnl_send(rtnl, message, &serial);
         if (r < 0)
                 return r;
 
@@ -557,53 +644,43 @@ int sd_rtnl_call(sd_rtnl *nl,
 
         for (;;) {
                 usec_t left;
-                _cleanup_rtnl_message_unref_ sd_rtnl_message *incoming = NULL;
-
-                if (!room) {
-                        sd_rtnl_message **q;
-
-                        if (nl->rqueue_size >= RTNL_RQUEUE_MAX)
-                                return -ENOBUFS;
 
-                        /* Make sure there's room for queueing this
-                         * locally, before we read the message */
+                while (i < rtnl->rqueue_size) {
+                        sd_rtnl_message *incoming;
+                        uint32_t received_serial;
 
-                        q = realloc(nl->rqueue, (nl->rqueue_size + 1) * sizeof(sd_rtnl_message*));
-                        if (!q)
-                                return -ENOMEM;
-
-                        nl->rqueue = q;
-                        room = true;
-                }
-
-                r = socket_read_message(nl, &incoming);
-                if (r < 0)
-                        return r;
-                if (incoming) {
-                        uint32_t received_serial = rtnl_message_get_serial(incoming);
+                        incoming = rtnl->rqueue[i];
+                        received_serial = rtnl_message_get_serial(incoming);
 
                         if (received_serial == serial) {
+                                /* found a match, remove from rqueue and return it */
+                                memmove(rtnl->rqueue + i,rtnl->rqueue + i + 1,
+                                        sizeof(sd_rtnl_message*) * (rtnl->rqueue_size - i - 1));
+                                rtnl->rqueue_size--;
+
                                 r = sd_rtnl_message_get_errno(incoming);
-                                if (r < 0)
+                                if (r < 0) {
+                                        sd_rtnl_message_unref(incoming);
                                         return r;
+                                }
 
                                 if (ret) {
                                         *ret = incoming;
-                                        incoming = NULL;
-                                }
+                                } else
+                                        sd_rtnl_message_unref(incoming);
 
                                 return 1;
                         }
 
-                        /* Room was allocated on the queue above */
-                        nl->rqueue[nl->rqueue_size ++] = incoming;
-                        incoming = NULL;
-                        room = false;
-
                         /* Try to read more, right away */
-                        continue;
+                        i ++;
                 }
-                if (r != 0)
+
+                r = socket_read_message(rtnl);
+                if (r < 0)
+                        return r;
+                if (r > 0)
+                        /* receieved message, so try to process straight away */
                         continue;
 
                 if (timeout > 0) {
@@ -617,11 +694,11 @@ int sd_rtnl_call(sd_rtnl *nl,
                 } else
                         left = (uint64_t) -1;
 
-                r = rtnl_poll(nl, true, left);
+                r = rtnl_poll(rtnl, true, left);
                 if (r < 0)
                         return r;
 
-                r = dispatch_wqueue(nl);
+                r = dispatch_wqueue(rtnl);
                 if (r < 0)
                         return r;
         }
@@ -786,7 +863,7 @@ int sd_rtnl_attach_event(sd_rtnl *rtnl, sd_event *event, int priority) {
         if (r < 0)
                 goto fail;
 
-        r = sd_event_add_monotonic(rtnl->event, &rtnl->time_event_source, 0, 0, time_callback, rtnl);
+        r = sd_event_add_time(rtnl->event, &rtnl->time_event_source, CLOCK_MONOTONIC, 0, 0, time_callback, rtnl);
         if (r < 0)
                 goto fail;
 
index dd74e76..46b5bb2 100644 (file)
@@ -20,6 +20,7 @@
 ***/
 
 #include <netinet/ether.h>
+#include <net/if.h>
 
 #include "util.h"
 #include "macro.h"
 #include "rtnl-util.h"
 #include "event-util.h"
 #include "missing.h"
+#include "rtnl-internal.h"
 
 static void test_link_configure(sd_rtnl *rtnl, int ifindex) {
         _cleanup_rtnl_message_unref_ sd_rtnl_message *message;
-        uint16_t type;
         const char *mac = "98:fe:94:3f:c6:18", *name = "test";
-        unsigned int mtu = 1450;
-        void *data;
+        char buffer[ETHER_ADDR_TO_STRING_MAX];
+        unsigned int mtu = 1450, mtu_out;
+        const char *name_out;
+        struct ether_addr mac_out;
 
         /* we'd really like to test NEWLINK, but let's not mess with the running kernel */
         assert_se(sd_rtnl_message_new_link(rtnl, &message, RTM_GETLINK, ifindex) >= 0);
@@ -43,27 +46,26 @@ static void test_link_configure(sd_rtnl *rtnl, int ifindex) {
         assert_se(sd_rtnl_message_append_u32(message, IFLA_MTU, mtu) >= 0);
 
         assert_se(sd_rtnl_call(rtnl, message, 0, NULL) == 1);
+        assert_se(sd_rtnl_message_rewind(message) >= 0);
 
-        assert_se(sd_rtnl_message_read(message, &type, &data) > 0);
-        assert_se(type == IFLA_IFNAME);
-        assert_se(streq(name, (char *) data));
+        assert_se(sd_rtnl_message_read_string(message, IFLA_IFNAME, &name_out) >= 0);
+        assert_se(streq(name, name_out));
 
-        assert_se(sd_rtnl_message_read(message, &type, &data) > 0);
-        assert_se(type == IFLA_ADDRESS);
-        assert_se(streq(mac, ether_ntoa(data)));
+        assert_se(sd_rtnl_message_read_ether_addr(message, IFLA_ADDRESS, &mac_out) >= 0);
+        assert_se(streq(mac, ether_addr_to_string(&mac_out, buffer)));
 
-        assert_se(sd_rtnl_message_read(message, &type, &data) > 0);
-        assert_se(type == IFLA_MTU);
-        assert_se(mtu == *(unsigned int *) data);
+        assert_se(sd_rtnl_message_read_u32(message, IFLA_MTU, &mtu_out) >= 0);
+        assert_se(mtu == mtu_out);
 }
 
 static void test_link_get(sd_rtnl *rtnl, int ifindex) {
         sd_rtnl_message *m;
         sd_rtnl_message *r;
         unsigned int mtu = 1500;
-        unsigned int *mtu_reply;
-        void *data;
-        uint16_t type;
+        const char *str_data;
+        uint8_t u8_data;
+        uint32_t u32_data;
+        struct ether_addr eth_data;
 
         assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0);
         assert_se(m);
@@ -82,61 +84,56 @@ static void test_link_get(sd_rtnl *rtnl, int ifindex) {
 
         assert_se(sd_rtnl_call(rtnl, m, -1, &r) == 1);
 
-        /* u8 read back */
-        assert_se(sd_rtnl_message_read(m, &type, &data) == 1);
-        assert_se(type == IFLA_CARRIER);
-
-        assert_se(sd_rtnl_message_read(m, &type, &data) == 1);
-        assert_se(type == IFLA_OPERSTATE);
-
-        assert_se(sd_rtnl_message_read(m, &type, &data) == 1);
-        assert_se(type == IFLA_LINKMODE);
-
-        /* u32 read back */
-        assert_se(sd_rtnl_message_read(m, &type, (void **) &mtu_reply) == 1);
-        assert_se(type == IFLA_MTU);
-        assert_se(*mtu_reply == mtu);
-
-        assert_se(sd_rtnl_message_read(m, &type, &data) == 1);
-        assert_se(type == IFLA_GROUP);
-
-        assert_se(sd_rtnl_message_read(m, &type, &data) == 1);
-        assert_se(type == IFLA_TXQLEN);
-
-        assert_se(sd_rtnl_message_read(m, &type, &data) == 1);
-        assert_se(type == IFLA_NUM_TX_QUEUES);
-
-        assert_se(sd_rtnl_message_read(m, &type, &data) == 1);
-        assert_se(type == IFLA_NUM_RX_QUEUES);
-
-        while (sd_rtnl_message_read(r, &type, &data) > 0) {
-                switch (type) {
-//                        case IFLA_MTU:
-//                                assert_se(*(unsigned int *) data == 65536);
-//                                break;
-//                        case IFLA_QDISC:
-//                                assert_se(streq((char *) data, "noqueue"));
-//                                break;
-                        case IFLA_IFNAME:
-                                assert_se(streq((char *) data, "lo"));
-                                break;
-                }
-        }
+        assert_se(sd_rtnl_message_read_string(r, IFLA_IFNAME, &str_data) == 0);
+
+        assert_se(sd_rtnl_message_read_u8(r, IFLA_CARRIER, &u8_data) == 0);
+        assert_se(sd_rtnl_message_read_u8(r, IFLA_OPERSTATE, &u8_data) == 0);
+        assert_se(sd_rtnl_message_read_u8(r, IFLA_LINKMODE, &u8_data) == 0);
+
+        assert_se(sd_rtnl_message_read_u32(r, IFLA_MTU, &u32_data) == 0);
+        assert_se(sd_rtnl_message_read_u32(r, IFLA_GROUP, &u32_data) == 0);
+        assert_se(sd_rtnl_message_read_u32(r, IFLA_TXQLEN, &u32_data) == 0);
+        assert_se(sd_rtnl_message_read_u32(r, IFLA_NUM_TX_QUEUES, &u32_data) == 0);
+        assert_se(sd_rtnl_message_read_u32(r, IFLA_NUM_RX_QUEUES, &u32_data) == 0);
+
+        assert_se(sd_rtnl_message_read_ether_addr(r, IFLA_ADDRESS, &eth_data) == 0);
+
+        assert_se(sd_rtnl_flush(rtnl) >= 0);
+        assert_se((m = sd_rtnl_message_unref(m)) == NULL);
+        assert_se((r = sd_rtnl_message_unref(r)) == NULL);
+}
+
+
+static void test_address_get(sd_rtnl *rtnl, int ifindex) {
+        sd_rtnl_message *m;
+        sd_rtnl_message *r;
+        struct in_addr in_data;
+        struct ifa_cacheinfo cache;
+        const char *label;
+
+        assert_se(sd_rtnl_message_new_addr(rtnl, &m, RTM_GETADDR, ifindex, AF_INET) >= 0);
+        assert_se(m);
+
+        assert_se(sd_rtnl_call(rtnl, m, -1, &r) == 1);
+
+        assert_se(sd_rtnl_message_read_in_addr(r, IFA_LOCAL, &in_data) == 0);
+        assert_se(sd_rtnl_message_read_in_addr(r, IFA_ADDRESS, &in_data) == 0);
+        assert_se(sd_rtnl_message_read_string(r, IFA_LABEL, &label) == 0);
+        assert_se(sd_rtnl_message_read_cache_info(r, IFA_CACHEINFO, &cache) == 0);
 
         assert_se(sd_rtnl_flush(rtnl) >= 0);
         assert_se((m = sd_rtnl_message_unref(m)) == NULL);
+        assert_se((r = sd_rtnl_message_unref(r)) == NULL);
 
 }
 
 static void test_route(void) {
         _cleanup_rtnl_message_unref_ sd_rtnl_message *req;
-        struct in_addr addr;
-        uint32_t index = 2;
-        uint16_t type;
-        void *data;
+        struct in_addr addr, addr_data;
+        uint32_t index = 2, u32_data;
         int r;
 
-        r = sd_rtnl_message_new_route(NULL, &req, RTM_NEWROUTE, AF_INET);
+        r = sd_rtnl_message_new_route(NULL, &req, RTM_NEWROUTE, AF_INET, RTPROT_STATIC);
         if (r < 0) {
                 log_error("Could not create RTM_NEWROUTE message: %s", strerror(-r));
                 return;
@@ -156,15 +153,15 @@ static void test_route(void) {
                 return;
         }
 
-        assert_se(rtnl_message_seal(NULL, req) >= 0);
+        assert_se(sd_rtnl_message_rewind(req) >= 0);
+
+        assert_se(sd_rtnl_message_read_in_addr(req, RTA_GATEWAY, &addr_data) >= 0);
+        assert_se(addr_data.s_addr == addr.s_addr);
 
-        assert_se(sd_rtnl_message_read(req, &type, &data) > 0);
-        assert_se(type == RTA_GATEWAY);
-        assert_se(((struct in_addr *)data)->s_addr == addr.s_addr);
+        assert_se(sd_rtnl_message_read_u32(req, RTA_OIF, &u32_data) >= 0);
+        assert_se(u32_data == index);
 
-        assert_se(sd_rtnl_message_read(req, &type, &data) > 0);
-        assert_se(type == RTA_OIF);
-        assert_se(*(uint32_t *) data == index);
+        assert_se((req = sd_rtnl_message_unref(req)) == NULL);
 }
 
 static void test_multiple(void) {
@@ -178,9 +175,8 @@ static void test_multiple(void) {
 }
 
 static int link_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
-        void *data;
-        uint16_t type;
         char *ifname = userdata;
+        const char *data;
 
         assert_se(rtnl);
         assert_se(m);
@@ -188,19 +184,8 @@ static int link_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
         log_info("got link info about %s", ifname);
         free(ifname);
 
-        while (sd_rtnl_message_read(m, &type, &data) > 0) {
-                switch (type) {
-//                        case IFLA_MTU:
-//                                assert_se(*(unsigned int *) data == 65536);
-//                                break;
-//                        case IFLA_QDISC:
-//                                assert_se(streq((char *) data, "noqueue"));
-//                                break;
-                        case IFLA_IFNAME:
-                                assert_se(streq((char *) data, "lo"));
-                                break;
-                }
-        }
+        assert_se(sd_rtnl_message_read_string(m, IFLA_IFNAME, &data) >= 0);
+        assert_se(streq(data, "lo"));
 
         return 1;
 }
@@ -226,16 +211,23 @@ static void test_event_loop(int ifindex) {
         assert_se(sd_event_run(event, 0) >= 0);
 
         assert_se(sd_rtnl_detach_event(rtnl) >= 0);
+
+        assert_se((rtnl = sd_rtnl_unref(rtnl)) == NULL);
 }
 
 static int pipe_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
         int *counter = userdata;
+        int r;
 
         (*counter) --;
 
-        log_info("got reply, %d left in pipe", *counter);
+        r = sd_rtnl_message_get_errno(m);
 
-        return sd_rtnl_message_get_errno(m);
+        log_info("%d left in pipe. got reply: %s", *counter, strerror(-r));
+
+        assert_se(r >= 0);
+
+        return 1;
 }
 
 static void test_async(int ifindex) {
@@ -255,6 +247,8 @@ static void test_async(int ifindex) {
 
         assert_se(sd_rtnl_wait(rtnl, 0) >= 0);
         assert_se(sd_rtnl_process(rtnl, &r) >= 0);
+
+        assert_se((rtnl = sd_rtnl_unref(rtnl)) == NULL);
 }
 
 static void test_pipe(int ifindex) {
@@ -277,47 +271,42 @@ static void test_pipe(int ifindex) {
                 assert_se(sd_rtnl_wait(rtnl, 0) >= 0);
                 assert_se(sd_rtnl_process(rtnl, NULL) >= 0);
         }
+
+        assert_se((rtnl = sd_rtnl_unref(rtnl)) == NULL);
 }
 
 static void test_container(void) {
         _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
-        uint16_t type;
-        void *data;
+        uint16_t u16_data;
+        uint32_t u32_data;
+        const char *string_data;
 
         assert_se(sd_rtnl_message_new_link(NULL, &m, RTM_NEWLINK, 0) >= 0);
 
         assert_se(sd_rtnl_message_open_container(m, IFLA_LINKINFO) >= 0);
-        assert_se(sd_rtnl_message_open_container(m, IFLA_LINKINFO) == -ENOTSUP);
-        assert_se(sd_rtnl_message_append_string(m, IFLA_INFO_KIND, "kind") >= 0);
-        assert_se(sd_rtnl_message_open_container(m, IFLA_INFO_DATA) >= 0);
-        assert_se(sd_rtnl_message_open_container(m, IFLA_INFO_DATA) == -ENOTSUP);
+        assert_se(sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA, "vlan") >= 0);
         assert_se(sd_rtnl_message_append_u16(m, IFLA_VLAN_ID, 100) >= 0);
         assert_se(sd_rtnl_message_close_container(m) >= 0);
-        assert_se(sd_rtnl_message_append_string(m, IFLA_INFO_KIND, "kind") >= 0);
+        assert_se(sd_rtnl_message_append_string(m, IFLA_INFO_KIND, "vlan") >= 0);
         assert_se(sd_rtnl_message_close_container(m) >= 0);
         assert_se(sd_rtnl_message_close_container(m) == -EINVAL);
 
-        assert_se(rtnl_message_seal(NULL, m) >= 0);
-
-        assert_se(sd_rtnl_message_read(m, &type, &data) >= 0);
-        assert_se(type == IFLA_LINKINFO);
-        assert_se(data == NULL);
-        assert_se(sd_rtnl_message_read(m, &type, &data) >= 0);
-        assert_se(type == IFLA_INFO_KIND);
-        assert_se(streq("kind", (char *)data));
-        assert_se(sd_rtnl_message_read(m, &type, &data) >= 0);
-        assert_se(type == IFLA_INFO_DATA);
-        assert_se(data == NULL);
-        assert_se(sd_rtnl_message_read(m, &type, &data) >= 0);
-        assert_se(type == IFLA_VLAN_ID);
-        assert_se(*(uint16_t *)data == 100);
-        assert_se(sd_rtnl_message_read(m, &type, &data) == 0);
+        assert_se(sd_rtnl_message_rewind(m) >= 0);
+
+        assert_se(sd_rtnl_message_enter_container(m, IFLA_LINKINFO) >= 0);
+        assert_se(sd_rtnl_message_read_string(m, IFLA_INFO_KIND, &string_data) >= 0);
+        assert_se(streq("vlan", string_data));
+
+        assert_se(sd_rtnl_message_enter_container(m, IFLA_INFO_DATA) >= 0);
+        assert_se(sd_rtnl_message_read_u16(m, IFLA_VLAN_ID, &u16_data) >= 0);
         assert_se(sd_rtnl_message_exit_container(m) >= 0);
-        assert_se(sd_rtnl_message_read(m, &type, &data) >= 0);
-        assert_se(type == IFLA_INFO_KIND);
-        assert_se(streq("kind", (char *)data));
-        assert_se(sd_rtnl_message_read(m, &type, &data) == 0);
+
+        assert_se(sd_rtnl_message_read_string(m, IFLA_INFO_KIND, &string_data) >= 0);
+        assert_se(streq("vlan", string_data));
         assert_se(sd_rtnl_message_exit_container(m) >= 0);
+
+        assert_se(sd_rtnl_message_read_u32(m, IFLA_LINKINFO, &u32_data) < 0);
+
         assert_se(sd_rtnl_message_exit_container(m) == -EINVAL);
 }
 
@@ -332,13 +321,43 @@ static void test_match(void) {
         assert_se(sd_rtnl_remove_match(rtnl, RTM_NEWLINK, &link_handler, NULL) == 1);
         assert_se(sd_rtnl_remove_match(rtnl, RTM_NEWLINK, &link_handler, NULL) == 1);
         assert_se(sd_rtnl_remove_match(rtnl, RTM_NEWLINK, &link_handler, NULL) == 0);
+
+        assert_se((rtnl = sd_rtnl_unref(rtnl)) == NULL);
+}
+
+static void test_get_addresses(sd_rtnl *rtnl) {
+        _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
+        sd_rtnl_message *m;
+
+        assert_se(sd_rtnl_message_new_addr(rtnl, &req, RTM_GETADDR, 0, AF_UNSPEC) >= 0);
+
+        assert_se(sd_rtnl_call(rtnl, req, 0, &reply) >= 0);
+
+        for (m = reply; m; m = sd_rtnl_message_next(m)) {
+                uint16_t type;
+                unsigned char scope, flags;
+                int family, ifindex;
+
+                assert_se(sd_rtnl_message_get_type(m, &type) >= 0);
+                assert_se(type == RTM_NEWADDR);
+
+                assert_se(sd_rtnl_message_addr_get_ifindex(m, &ifindex) >= 0);
+                assert_se(sd_rtnl_message_addr_get_family(m, &family) >= 0);
+                assert_se(sd_rtnl_message_addr_get_scope(m, &scope) >= 0);
+                assert_se(sd_rtnl_message_addr_get_flags(m, &flags) >= 0);
+
+                assert_se(ifindex > 0);
+                assert_se(family == AF_INET || family == AF_INET6);
+
+                log_info("got IPv%u address on ifindex %i", family == AF_INET ? 4: 6, ifindex);
+        }
 }
 
 int main(void) {
         sd_rtnl *rtnl;
         sd_rtnl_message *m;
         sd_rtnl_message *r;
-        void *data;
+        const char *string_data;
         int if_loopback;
         uint16_t type;
 
@@ -364,19 +383,20 @@ int main(void) {
 
         test_link_configure(rtnl, if_loopback);
 
+        test_get_addresses(rtnl);
+
         assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, if_loopback) >= 0);
         assert_se(m);
 
         assert_se(sd_rtnl_message_get_type(m, &type) >= 0);
         assert_se(type == RTM_GETLINK);
 
-        assert_se(sd_rtnl_message_read(m, &type, &data) == -EPERM);
+        assert_se(sd_rtnl_message_read_string(m, IFLA_IFNAME, &string_data) == -EPERM);
 
         assert_se(sd_rtnl_call(rtnl, m, 0, &r) == 1);
         assert_se(sd_rtnl_message_get_type(r, &type) >= 0);
         assert_se(type == RTM_NEWLINK);
 
-        assert_se(sd_rtnl_message_read(m, &type, &data) == 0);
         assert_se((r = sd_rtnl_message_unref(r)) == NULL);
 
         assert_se(sd_rtnl_call(rtnl, m, -1, &r) == -EPERM);
@@ -384,6 +404,7 @@ int main(void) {
         assert_se((r = sd_rtnl_message_unref(r)) == NULL);
 
         test_link_get(rtnl, if_loopback);
+        test_address_get(rtnl, if_loopback);
 
         assert_se(sd_rtnl_flush(rtnl) >= 0);
         assert_se((m = sd_rtnl_message_unref(m)) == NULL);
index cb4947f..87d52be 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "libudev.h"
 #include "libudev-private.h"
+#include "smack-util.h"
 
 static void udev_device_tag(struct udev_device *dev, const char *tag, bool add)
 {
@@ -154,7 +155,7 @@ int udev_device_update_db(struct udev_device *udev_device)
                 }
 
                 if (udev_device_get_usec_initialized(udev_device) > 0)
-                        fprintf(f, "I:%llu\n", (unsigned long long)udev_device_get_usec_initialized(udev_device));
+                        fprintf(f, "I:"USEC_FMT"\n", udev_device_get_usec_initialized(udev_device));
 
                 udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(udev_device)) {
                         if (!udev_list_entry_get_num(list_entry))
@@ -172,6 +173,12 @@ int udev_device_update_db(struct udev_device *udev_device)
         r = rename(filename_tmp, filename);
         if (r < 0)
                 return -1;
+#ifdef HAVE_SMACK
+        if (smack_label_path(filename, SMACK_FLOOR_LABEL) < 0)
+                log_error("SECLABEL: failed to set SMACK label '%s'", SMACK_FLOOR_LABEL);
+        else
+                log_debug("SECLABEL: set SMACK label '%s'", SMACK_FLOOR_LABEL);
+#endif
         udev_dbg(udev, "created %s file '%s' for '%s'\n", has_info ? "db" : "empty",
              filename, udev_device_get_devpath(udev_device));
         return 0;
index 9f80f56..f26a4c4 100644 (file)
@@ -644,12 +644,16 @@ struct udev_device *udev_device_new(struct udev *udev)
         struct udev_device *udev_device;
         struct udev_list_entry *list_entry;
 
-        if (udev == NULL)
+        if (udev == NULL) {
+                errno = EINVAL;
                 return NULL;
+        }
 
         udev_device = new0(struct udev_device, 1);
-        if (udev_device == NULL)
+        if (udev_device == NULL) {
+                errno = ENOMEM;
                 return NULL;
+        }
         udev_device->refcount = 1;
         udev_device->udev = udev;
         udev_list_init(udev, &udev_device->devlinks_list, true);
@@ -688,22 +692,30 @@ _public_ struct udev_device *udev_device_new_from_syspath(struct udev *udev, con
         struct stat statbuf;
         struct udev_device *udev_device;
 
-        if (udev == NULL)
+        if (udev == NULL) {
+                errno = EINVAL;
                 return NULL;
-        if (syspath == NULL)
+        }
+
+        if (syspath == NULL) {
+                errno = EINVAL;
                 return NULL;
+        }
 
         /* path starts in sys */
         if (!startswith(syspath, "/sys")) {
                 udev_dbg(udev, "not in sys :%s\n", syspath);
+                errno = EINVAL;
                 return NULL;
         }
 
         /* path is not a root directory */
         subdir = syspath + strlen("/sys");
         pos = strrchr(subdir, '/');
-        if (pos == NULL || pos[1] == '\0' || pos < &subdir[2])
+        if (pos == NULL || pos[1] == '\0' || pos < &subdir[2]) {
+                errno = EINVAL;
                 return NULL;
+        }
 
         /* resolve possible symlink to real path */
         strscpy(path, sizeof(path), syspath);
@@ -757,8 +769,10 @@ _public_ struct udev_device *udev_device_new_from_devnum(struct udev *udev, char
                 type_str = "block";
         else if (type == 'c')
                 type_str = "char";
-        else
+        else {
+                errno = EINVAL;
                 return NULL;
+        }
 
         /* use /sys/dev/{block,char}/<maj>:<min> link */
         snprintf(path, sizeof(path), "/sys/dev/%s/%u:%u",
@@ -804,8 +818,10 @@ _public_ struct udev_device *udev_device_new_from_device_id(struct udev *udev, c
                 int ifindex;
 
                 ifindex = strtoul(&id[1], NULL, 10);
-                if (ifindex <= 0)
+                if (ifindex <= 0) {
+                        errno = EINVAL;
                         return NULL;
+                }
 
                 sk = socket(PF_INET, SOCK_DGRAM, 0);
                 if (sk < 0)
@@ -823,18 +839,24 @@ _public_ struct udev_device *udev_device_new_from_device_id(struct udev *udev, c
                         return NULL;
                 if (udev_device_get_ifindex(dev) == ifindex)
                         return dev;
+
+                /* this is racy, so we may end up with the wrong device */
                 udev_device_unref(dev);
+                errno = ENODEV;
                 return NULL;
         }
         case '+':
                 strscpy(subsys, sizeof(subsys), &id[1]);
                 sysname = strchr(subsys, ':');
-                if (sysname == NULL)
+                if (sysname == NULL) {
+                        errno = EINVAL;
                         return NULL;
+                }
                 sysname[0] = '\0';
                 sysname = &sysname[1];
                 return udev_device_new_from_subsystem_sysname(udev, subsys, sysname);
         default:
+                errno = EINVAL;
                 return NULL;
         }
 }
@@ -898,7 +920,9 @@ _public_ struct udev_device *udev_device_new_from_subsystem_sysname(struct udev
                         strscpyl(path, sizeof(path), "/sys/bus/", subsys, "/drivers/", driver, NULL);
                         if (stat(path, &statbuf) == 0)
                                 goto found;
-                }
+                } else
+                        errno = EINVAL;
+
                 goto out;
         }
 
@@ -974,6 +998,8 @@ static struct udev_device *device_new_from_parent(struct udev_device *udev_devic
                 if (udev_device_parent != NULL)
                         return udev_device_parent;
         }
+
+        errno = ENOENT;
         return NULL;
 }
 
@@ -997,8 +1023,10 @@ static struct udev_device *device_new_from_parent(struct udev_device *udev_devic
  **/
 _public_ struct udev_device *udev_device_get_parent(struct udev_device *udev_device)
 {
-        if (udev_device == NULL)
+        if (udev_device == NULL) {
+                errno = EINVAL;
                 return NULL;
+        }
         if (!udev_device->parent_set) {
                 udev_device->parent_set = true;
                 udev_device->parent_device = device_new_from_parent(udev_device);
@@ -1031,8 +1059,10 @@ _public_ struct udev_device *udev_device_get_parent_with_subsystem_devtype(struc
 {
         struct udev_device *parent;
 
-        if (subsystem == NULL)
+        if (subsystem == NULL) {
+                errno = EINVAL;
                 return NULL;
+        }
 
         parent = udev_device_get_parent(udev_device);
         while (parent != NULL) {
@@ -1049,6 +1079,10 @@ _public_ struct udev_device *udev_device_get_parent_with_subsystem_devtype(struc
                 }
                 parent = udev_device_get_parent(parent);
         }
+
+        if (!parent)
+                errno = ENOENT;
+
         return parent;
 }
 
@@ -1341,7 +1375,7 @@ void udev_device_set_usec_initialized(struct udev_device *udev_device, usec_t us
         char num[32];
 
         udev_device->usec_initialized = usec_initialized;
-        snprintf(num, sizeof(num), "%llu", (unsigned long long)usec_initialized);
+        snprintf(num, sizeof(num), USEC_FMT, usec_initialized);
         udev_device_add_property(udev_device, "USEC_INITIALIZED", num);
 }
 
index ff34e5a..8fb7240 100644 (file)
@@ -305,7 +305,7 @@ _public_ struct udev_hwdb *udev_hwdb_new(struct udev *udev) {
 
         udev_dbg(udev, "=== trie on-disk ===\n");
         udev_dbg(udev, "tool version:          %"PRIu64, le64toh(hwdb->head->tool_version));
-        udev_dbg(udev, "file size:        %8llu bytes\n", (unsigned long long) hwdb->st.st_size);
+        udev_dbg(udev, "file size:        %8"PRIu64" bytes\n", hwdb->st.st_size);
         udev_dbg(udev, "header size       %8"PRIu64" bytes\n", le64toh(hwdb->head->header_size));
         udev_dbg(udev, "strings           %8"PRIu64" bytes\n", le64toh(hwdb->head->strings_len));
         udev_dbg(udev, "nodes             %8"PRIu64" bytes\n", le64toh(hwdb->head->nodes_len));
index ba1b04d..186e5e1 100644 (file)
@@ -108,18 +108,22 @@ static struct udev_monitor *udev_monitor_new(struct udev *udev)
 
 /* we consider udev running when /dev is on devtmpfs */
 static bool udev_has_devtmpfs(struct udev *udev) {
-        struct file_handle *h;
-        int mount_id;
+
+        union file_handle_union h = {
+                .handle.handle_bytes = MAX_HANDLE_SZ
+        };
+
         _cleanup_fclose_ FILE *f = NULL;
         char line[LINE_MAX], *e;
+        int mount_id;
         int r;
 
-        h = alloca(MAX_HANDLE_SZ);
-        h->handle_bytes = MAX_HANDLE_SZ;
-        r = name_to_handle_at(AT_FDCWD, "/dev", h, &mount_id, 0);
-        if (r < 0)
+        r = name_to_handle_at(AT_FDCWD, "/dev", &h.handle, &mount_id, 0);
+        if (r < 0) {
+                if (errno != EOPNOTSUPP)
+                        udev_err(udev, "name_to_handle_at on /dev: %m\n");
                 return false;
-
+        }
 
         f = fopen("/proc/self/mountinfo", "re");
         if (!f)
@@ -146,21 +150,6 @@ static bool udev_has_devtmpfs(struct udev *udev) {
         return false;
 }
 
-/* we consider udev running when we have running udev service */
-static bool udev_has_service(struct udev *udev) {
-        struct udev_queue *queue;
-        bool active;
-
-        queue = udev_queue_new(udev);
-        if (!queue)
-                return false;
-
-        active = udev_queue_get_udev_is_active(queue);
-        udev_queue_unref(queue);
-
-        return active;
-}
-
 struct udev_monitor *udev_monitor_new_from_netlink_fd(struct udev *udev, const char *name, int fd)
 {
         struct udev_monitor *udev_monitor;
@@ -184,7 +173,7 @@ struct udev_monitor *udev_monitor_new_from_netlink_fd(struct udev *udev, const c
                  * We do not set a netlink multicast group here, so the socket
                  * will not receive any messages.
                  */
-                if (!udev_has_service(udev) && !udev_has_devtmpfs(udev)) {
+                if (access("/run/udev/control", F_OK) < 0 && !udev_has_devtmpfs(udev)) {
                         udev_dbg(udev, "the udev service seems not to be active, disable the monitor\n");
                         group = UDEV_MONITOR_NONE;
                 } else
index af0f125..ae97557 100644 (file)
@@ -20,7 +20,6 @@
 #ifndef _LIBUDEV_PRIVATE_H_
 #define _LIBUDEV_PRIVATE_H_
 
-#include <syslog.h>
 #include <signal.h>
 #include <stdint.h>
 #include <stdbool.h>
diff --git a/src/libudev/libudev-queue-private.c b/src/libudev/libudev-queue-private.c
deleted file mode 100644 (file)
index d5a2b50..0000000
+++ /dev/null
@@ -1,406 +0,0 @@
-/***
-  This file is part of systemd.
-
-  Copyright 2008-2012 Kay Sievers <kay@vrfy.org>
-  Copyright 2009 Alan Jenkins <alan-jenkins@tuffmail.co.uk>
-
-  systemd is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation; either version 2.1 of the License, or
-  (at your option) any later version.
-
-  systemd is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-/*
- * DISCLAIMER - The file format mentioned here is private to udev/libudev,
- *              and may be changed without notice.
- *
- * The udev event queue is exported as a binary log file.
- * Each log record consists of a sequence number followed by the device path.
- *
- * When a new event is queued, its details are appended to the log.
- * When the event finishes, a second record is appended to the log
- * with the same sequence number but a devpath len of 0.
- *
- * Example:
- *        { 0x0000000000000001 }
- *        { 0x0000000000000001, 0x0019, "/devices/virtual/mem/null" },
- *        { 0x0000000000000002, 0x001b, "/devices/virtual/mem/random" },
- *        { 0x0000000000000001, 0x0000 },
- *        { 0x0000000000000003, 0x0019, "/devices/virtual/mem/zero" },
- *
- * Events 2 and 3 are still queued, but event 1 has finished.
- *
- * The queue does not grow indefinitely. It is periodically re-created
- * to remove finished events. Atomic rename() makes this transparent to readers.
- *
- * The queue file starts with a single sequence number which specifies the
- * minimum sequence number in the log that follows. Any events prior to this
- * sequence number have already finished.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <limits.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include "libudev.h"
-#include "libudev-private.h"
-
-static int rebuild_queue_file(struct udev_queue_export *udev_queue_export);
-
-struct udev_queue_export {
-        struct udev *udev;
-        int queued_count;        /* number of unfinished events exported in queue file */
-        FILE *queue_file;
-        unsigned long long int seqnum_max;        /* earliest sequence number in queue file */
-        unsigned long long int seqnum_min;        /* latest sequence number in queue file */
-        int waste_bytes;                        /* queue file bytes wasted on finished events */
-};
-
-struct udev_queue_export *udev_queue_export_new(struct udev *udev)
-{
-        struct udev_queue_export *udev_queue_export;
-        unsigned long long int initial_seqnum;
-
-        if (udev == NULL)
-                return NULL;
-
-        udev_queue_export = new0(struct udev_queue_export, 1);
-        if (udev_queue_export == NULL)
-                return NULL;
-        udev_queue_export->udev = udev;
-
-        initial_seqnum = udev_get_kernel_seqnum(udev);
-        udev_queue_export->seqnum_min = initial_seqnum;
-        udev_queue_export->seqnum_max = initial_seqnum;
-
-        udev_queue_export_cleanup(udev_queue_export);
-        if (rebuild_queue_file(udev_queue_export) != 0) {
-                free(udev_queue_export);
-                return NULL;
-        }
-
-        return udev_queue_export;
-}
-
-struct udev_queue_export *udev_queue_export_unref(struct udev_queue_export *udev_queue_export)
-{
-        if (udev_queue_export == NULL)
-                return NULL;
-        if (udev_queue_export->queue_file != NULL)
-                fclose(udev_queue_export->queue_file);
-        free(udev_queue_export);
-        return NULL;
-}
-
-void udev_queue_export_cleanup(struct udev_queue_export *udev_queue_export)
-{
-        if (udev_queue_export == NULL)
-                return;
-        unlink("/run/udev/queue.tmp");
-        unlink("/run/udev/queue.bin");
-}
-
-static int skip_to(FILE *file, long offset)
-{
-        long old_offset;
-
-        /* fseek may drop buffered data, avoid it for small seeks */
-        old_offset = ftell(file);
-        if (offset > old_offset && offset - old_offset <= BUFSIZ) {
-                size_t skip_bytes = offset - old_offset;
-                char *buf = alloca(skip_bytes);
-
-                if (fread(buf, skip_bytes, 1, file) != skip_bytes)
-                        return -1;
-        }
-
-        return fseek(file, offset, SEEK_SET);
-}
-
-struct queue_devpaths {
-        unsigned int devpaths_first;        /* index of first queued event */
-        unsigned int devpaths_size;
-        long devpaths[];                /* seqnum -> offset of devpath in queue file (or 0) */
-};
-
-/*
- * Returns a table mapping seqnum to devpath file offset for currently queued events.
- * devpaths[i] represents the event with seqnum = i + udev_queue_export->seqnum_min.
- */
-static struct queue_devpaths *build_index(struct udev_queue_export *udev_queue_export)
-{
-        struct queue_devpaths *devpaths;
-        unsigned long long int range;
-        long devpath_offset;
-        ssize_t devpath_len;
-        unsigned long long int seqnum;
-        unsigned long long int n;
-        unsigned int i;
-
-        /* seek to the first event in the file */
-        rewind(udev_queue_export->queue_file);
-        udev_queue_read_seqnum(udev_queue_export->queue_file, &seqnum);
-
-        /* allocate the table */
-        range = udev_queue_export->seqnum_min - udev_queue_export->seqnum_max;
-        if (range - 1 > INT_MAX) {
-                udev_err(udev_queue_export->udev, "queue file overflow\n");
-                return NULL;
-        }
-        devpaths = malloc0(sizeof(struct queue_devpaths) + (range + 1) * sizeof(long));
-        if (devpaths == NULL)
-                return NULL;
-        devpaths->devpaths_size = range + 1;
-
-        /* read all records and populate the table */
-        for (;;) {
-                if (udev_queue_read_seqnum(udev_queue_export->queue_file, &seqnum) < 0)
-                        break;
-                n = seqnum - udev_queue_export->seqnum_max;
-                if (n >= devpaths->devpaths_size)
-                        goto read_error;
-
-                devpath_offset = ftell(udev_queue_export->queue_file);
-                devpath_len = udev_queue_skip_devpath(udev_queue_export->queue_file);
-                if (devpath_len < 0)
-                        goto read_error;
-
-                if (devpath_len > 0)
-                        devpaths->devpaths[n] = devpath_offset;
-                else
-                        devpaths->devpaths[n] = 0;
-        }
-
-        /* find first queued event */
-        for (i = 0; i < devpaths->devpaths_size; i++) {
-                if (devpaths->devpaths[i] != 0)
-                        break;
-        }
-        devpaths->devpaths_first = i;
-
-        return devpaths;
-
-read_error:
-        udev_err(udev_queue_export->udev, "queue file corrupted\n");
-        free(devpaths);
-        return NULL;
-}
-
-static int rebuild_queue_file(struct udev_queue_export *udev_queue_export)
-{
-        unsigned long long int seqnum;
-        struct queue_devpaths *devpaths = NULL;
-        FILE *new_queue_file = NULL;
-        unsigned int i;
-
-        /* read old queue file */
-        if (udev_queue_export->queue_file != NULL) {
-                devpaths = build_index(udev_queue_export);
-                if (devpaths != NULL)
-                        udev_queue_export->seqnum_max += devpaths->devpaths_first;
-        }
-        if (devpaths == NULL) {
-                udev_queue_export->queued_count = 0;
-                udev_queue_export->seqnum_max = udev_queue_export->seqnum_min;
-        }
-
-        /* create new queue file */
-        new_queue_file = fopen("/run/udev/queue.tmp", "w+e");
-        if (new_queue_file == NULL)
-                goto error;
-        seqnum = udev_queue_export->seqnum_max;
-        fwrite(&seqnum, 1, sizeof(unsigned long long int), new_queue_file);
-
-        /* copy unfinished events only to the new file */
-        if (devpaths != NULL) {
-                for (i = devpaths->devpaths_first; i < devpaths->devpaths_size; i++) {
-                        char devpath[UTIL_PATH_SIZE];
-                        int err;
-                        unsigned short devpath_len;
-
-                        if (devpaths->devpaths[i] != 0)
-                        {
-                                skip_to(udev_queue_export->queue_file, devpaths->devpaths[i]);
-                                err = udev_queue_read_devpath(udev_queue_export->queue_file, devpath, sizeof(devpath));
-                                devpath_len = err;
-
-                                fwrite(&seqnum, sizeof(unsigned long long int), 1, new_queue_file);
-                                fwrite(&devpath_len, sizeof(unsigned short), 1, new_queue_file);
-                                fwrite(devpath, 1, devpath_len, new_queue_file);
-                        }
-                        seqnum++;
-                }
-                free(devpaths);
-                devpaths = NULL;
-        }
-        fflush(new_queue_file);
-        if (ferror(new_queue_file))
-                goto error;
-
-        /* rename the new file on top of the old one */
-        if (rename("/run/udev/queue.tmp", "/run/udev/queue.bin") != 0)
-                goto error;
-
-        if (udev_queue_export->queue_file != NULL)
-                fclose(udev_queue_export->queue_file);
-        udev_queue_export->queue_file = new_queue_file;
-        udev_queue_export->waste_bytes = 0;
-
-        return 0;
-
-error:
-        udev_err(udev_queue_export->udev, "failed to create queue file: %m\n");
-        udev_queue_export_cleanup(udev_queue_export);
-
-        if (udev_queue_export->queue_file != NULL) {
-                fclose(udev_queue_export->queue_file);
-                udev_queue_export->queue_file = NULL;
-        }
-        if (new_queue_file != NULL)
-                fclose(new_queue_file);
-
-        if (devpaths != NULL)
-                free(devpaths);
-        udev_queue_export->queued_count = 0;
-        udev_queue_export->waste_bytes = 0;
-        udev_queue_export->seqnum_max = udev_queue_export->seqnum_min;
-
-        return -1;
-}
-
-static int write_queue_record(struct udev_queue_export *udev_queue_export,
-                              unsigned long long int seqnum, const char *devpath, size_t devpath_len)
-{
-        unsigned short len;
-
-        if (udev_queue_export->queue_file == NULL)
-                return -1;
-
-        if (fwrite(&seqnum, sizeof(unsigned long long int), 1, udev_queue_export->queue_file) != 1)
-                goto write_error;
-
-        len = (devpath_len < USHRT_MAX) ? devpath_len : USHRT_MAX;
-        if (fwrite(&len, sizeof(unsigned short), 1, udev_queue_export->queue_file) != 1)
-                goto write_error;
-        if (len > 0) {
-                if (fwrite(devpath, 1, len, udev_queue_export->queue_file) != len)
-                        goto write_error;
-        }
-
-        /* *must* flush output; caller may fork */
-        if (fflush(udev_queue_export->queue_file) != 0)
-                goto write_error;
-
-        return 0;
-
-write_error:
-        /* if we failed half way through writing a record to a file,
-           we should not try to write any further records to it. */
-        udev_err(udev_queue_export->udev, "error writing to queue file: %m\n");
-        fclose(udev_queue_export->queue_file);
-        udev_queue_export->queue_file = NULL;
-
-        return -1;
-}
-
-enum device_state {
-        DEVICE_QUEUED,
-        DEVICE_FINISHED,
-};
-
-static inline size_t queue_record_size(size_t devpath_len)
-{
-        return sizeof(unsigned long long int) + sizeof(unsigned short int) + devpath_len;
-}
-
-static int update_queue(struct udev_queue_export *udev_queue_export,
-                         struct udev_device *udev_device, enum device_state state)
-{
-        unsigned long long int seqnum = udev_device_get_seqnum(udev_device);
-        const char *devpath = NULL;
-        size_t devpath_len = 0;
-        int bytes;
-        int err;
-
-        /* FINISHED records have a zero length devpath */
-        if (state == DEVICE_QUEUED) {
-                devpath = udev_device_get_devpath(udev_device);
-                devpath_len = strlen(devpath);
-        }
-
-        /* recover from an earlier failed rebuild */
-        if (udev_queue_export->queue_file == NULL) {
-                if (rebuild_queue_file(udev_queue_export) != 0)
-                        return -1;
-        }
-
-        /* if we're removing the last event from the queue, that's the best time to rebuild it */
-        if (state != DEVICE_QUEUED && udev_queue_export->queued_count == 1) {
-                /* we don't need to read the old queue file */
-                fclose(udev_queue_export->queue_file);
-                udev_queue_export->queue_file = NULL;
-                rebuild_queue_file(udev_queue_export);
-                return 0;
-        }
-
-        /* try to rebuild the queue files before they grow larger than one page. */
-        bytes = ftell(udev_queue_export->queue_file) + queue_record_size(devpath_len);
-        if ((udev_queue_export->waste_bytes > bytes / 2) && bytes > 4096)
-                rebuild_queue_file(udev_queue_export);
-
-        /* don't record a finished event, if we already dropped the event in a failed rebuild */
-        if (seqnum < udev_queue_export->seqnum_max)
-                return 0;
-
-        /* now write to the queue */
-        if (state == DEVICE_QUEUED) {
-                udev_queue_export->queued_count++;
-                udev_queue_export->seqnum_min = seqnum;
-        } else {
-                udev_queue_export->waste_bytes += queue_record_size(devpath_len) + queue_record_size(0);
-                udev_queue_export->queued_count--;
-        }
-        err = write_queue_record(udev_queue_export, seqnum, devpath, devpath_len);
-
-        /* try to handle ENOSPC */
-        if (err != 0 && udev_queue_export->queued_count == 0) {
-                udev_queue_export_cleanup(udev_queue_export);
-                err = rebuild_queue_file(udev_queue_export);
-        }
-
-        return err;
-}
-
-static int update(struct udev_queue_export *udev_queue_export,
-                  struct udev_device *udev_device, enum device_state state)
-{
-        if (update_queue(udev_queue_export, udev_device, state) != 0)
-                return -1;
-
-        return 0;
-}
-
-int udev_queue_export_device_queued(struct udev_queue_export *udev_queue_export, struct udev_device *udev_device)
-{
-        return update(udev_queue_export, udev_device, DEVICE_QUEUED);
-}
-
-int udev_queue_export_device_finished(struct udev_queue_export *udev_queue_export, struct udev_device *udev_device)
-{
-        return update(udev_queue_export, udev_device, DEVICE_FINISHED);
-}
index 2cb4d67..8ef1f3d 100644 (file)
 #include <unistd.h>
 #include <errno.h>
 #include <string.h>
-#include <dirent.h>
-#include <fcntl.h>
 #include <limits.h>
 #include <sys/stat.h>
+#include <sys/inotify.h>
 
 #include "libudev.h"
 #include "libudev-private.h"
  * SECTION:libudev-queue
  * @short_description: access to currently active events
  *
- * The udev daemon processes events asynchronously. All events which do not have
- * interdependencies run in parallel. This exports the current state of the
- * event processing queue, and the current event sequence numbers from the kernel
- * and the udev daemon.
+ * This exports the current state of the udev processing queue.
  */
 
 /**
@@ -50,7 +46,7 @@
 struct udev_queue {
         struct udev *udev;
         int refcount;
-        struct udev_list queue_list;
+        int fd;
 };
 
 /**
@@ -72,9 +68,10 @@ _public_ struct udev_queue *udev_queue_new(struct udev *udev)
         udev_queue = new0(struct udev_queue, 1);
         if (udev_queue == NULL)
                 return NULL;
+
         udev_queue->refcount = 1;
         udev_queue->udev = udev;
-        udev_list_init(udev, &udev_queue->queue_list, false);
+        udev_queue->fd = -1;
         return udev_queue;
 }
 
@@ -90,6 +87,7 @@ _public_ struct udev_queue *udev_queue_ref(struct udev_queue *udev_queue)
 {
         if (udev_queue == NULL)
                 return NULL;
+
         udev_queue->refcount++;
         return udev_queue;
 }
@@ -107,10 +105,13 @@ _public_ struct udev_queue *udev_queue_unref(struct udev_queue *udev_queue)
 {
         if (udev_queue == NULL)
                 return NULL;
+
         udev_queue->refcount--;
         if (udev_queue->refcount > 0)
                 return NULL;
-        udev_list_cleanup(&udev_queue->queue_list);
+
+        safe_close(udev_queue->fd);
+
         free(udev_queue);
         return NULL;
 }
@@ -130,141 +131,30 @@ _public_ struct udev *udev_queue_get_udev(struct udev_queue *udev_queue)
         return udev_queue->udev;
 }
 
-unsigned long long int udev_get_kernel_seqnum(struct udev *udev)
-{
-        unsigned long long int seqnum;
-        int fd;
-        char buf[32];
-        ssize_t len;
-
-        fd = open("/sys/kernel/uevent_seqnum", O_RDONLY|O_CLOEXEC);
-        if (fd < 0)
-                return 0;
-        len = read(fd, buf, sizeof(buf));
-        close(fd);
-        if (len <= 2)
-                return 0;
-        buf[len-1] = '\0';
-        seqnum = strtoull(buf, NULL, 10);
-        return seqnum;
-}
-
 /**
  * udev_queue_get_kernel_seqnum:
  * @udev_queue: udev queue context
  *
- * Get the current kernel event sequence number.
+ * This function is deprecated.
  *
- * Returns: the sequence number.
+ * Returns: 0.
  **/
 _public_ unsigned long long int udev_queue_get_kernel_seqnum(struct udev_queue *udev_queue)
 {
-        unsigned long long int seqnum;
-
-        if (udev_queue == NULL)
-                return -EINVAL;
-
-        seqnum = udev_get_kernel_seqnum(udev_queue->udev);
-        return seqnum;
-}
-
-int udev_queue_read_seqnum(FILE *queue_file, unsigned long long int *seqnum)
-{
-        if (fread(seqnum, sizeof(unsigned long long int), 1, queue_file) != 1)
-                return -1;
-
         return 0;
 }
 
-ssize_t udev_queue_skip_devpath(FILE *queue_file)
-{
-        unsigned short int len;
-
-        if (fread(&len, sizeof(unsigned short int), 1, queue_file) == 1) {
-                char *devpath = alloca(len);
-
-                /* use fread to skip, fseek might drop buffered data */
-                if (fread(devpath, 1, len, queue_file) == len)
-                        return len;
-        }
-
-        return -1;
-}
-
-ssize_t udev_queue_read_devpath(FILE *queue_file, char *devpath, size_t size)
-{
-        unsigned short int read_bytes = 0;
-        unsigned short int len;
-
-        if (fread(&len, sizeof(unsigned short int), 1, queue_file) != 1)
-                return -1;
-
-        read_bytes = (len < size - 1) ? len : size - 1;
-        if (fread(devpath, 1, read_bytes, queue_file) != read_bytes)
-                return -1;
-        devpath[read_bytes] = '\0';
-
-        /* if devpath was too long, skip unread characters */
-        if (read_bytes != len) {
-                unsigned short int skip_bytes = len - read_bytes;
-                char *buf = alloca(skip_bytes);
-
-                if (fread(buf, 1, skip_bytes, queue_file) != skip_bytes)
-                        return -1;
-        }
-
-        return read_bytes;
-}
-
-static FILE *open_queue_file(struct udev_queue *udev_queue, unsigned long long int *seqnum_start)
-{
-        FILE *queue_file;
-
-        queue_file = fopen("/run/udev/queue.bin", "re");
-        if (queue_file == NULL)
-                return NULL;
-
-        if (udev_queue_read_seqnum(queue_file, seqnum_start) < 0) {
-                udev_err(udev_queue->udev, "corrupt queue file\n");
-                fclose(queue_file);
-                return NULL;
-        }
-
-        return queue_file;
-}
-
 /**
  * udev_queue_get_udev_seqnum:
  * @udev_queue: udev queue context
  *
- * Get the last known udev event sequence number.
+ * This function is deprecated.
  *
- * Returns: the sequence number.
+ * Returns: 0.
  **/
 _public_ unsigned long long int udev_queue_get_udev_seqnum(struct udev_queue *udev_queue)
 {
-        unsigned long long int seqnum_udev;
-        FILE *queue_file;
-
-        queue_file = open_queue_file(udev_queue, &seqnum_udev);
-        if (queue_file == NULL)
-                return 0;
-
-        for (;;) {
-                unsigned long long int seqnum;
-                ssize_t devpath_len;
-
-                if (udev_queue_read_seqnum(queue_file, &seqnum) < 0)
-                        break;
-                devpath_len = udev_queue_skip_devpath(queue_file);
-                if (devpath_len < 0)
-                        break;
-                if (devpath_len > 0)
-                        seqnum_udev = seqnum;
-        }
-
-        fclose(queue_file);
-        return seqnum_udev;
+        return 0;
 }
 
 /**
@@ -277,15 +167,7 @@ _public_ unsigned long long int udev_queue_get_udev_seqnum(struct udev_queue *ud
  **/
 _public_ int udev_queue_get_udev_is_active(struct udev_queue *udev_queue)
 {
-        unsigned long long int seqnum_start;
-        FILE *queue_file;
-
-        queue_file = open_queue_file(udev_queue, &seqnum_start);
-        if (queue_file == NULL)
-                return 0;
-
-        fclose(queue_file);
-        return 1;
+        return access("/run/udev/control", F_OK) >= 0;
 }
 
 /**
@@ -298,48 +180,7 @@ _public_ int udev_queue_get_udev_is_active(struct udev_queue *udev_queue)
  **/
 _public_ int udev_queue_get_queue_is_empty(struct udev_queue *udev_queue)
 {
-        unsigned long long int seqnum_kernel;
-        unsigned long long int seqnum_udev = 0;
-        int queued = 0;
-        int is_empty = 0;
-        FILE *queue_file;
-
-        if (udev_queue == NULL)
-                return -EINVAL;
-        queue_file = open_queue_file(udev_queue, &seqnum_udev);
-        if (queue_file == NULL)
-                return 1;
-
-        for (;;) {
-                unsigned long long int seqnum;
-                ssize_t devpath_len;
-
-                if (udev_queue_read_seqnum(queue_file, &seqnum) < 0)
-                        break;
-                devpath_len = udev_queue_skip_devpath(queue_file);
-                if (devpath_len < 0)
-                        break;
-
-                if (devpath_len > 0) {
-                        queued++;
-                        seqnum_udev = seqnum;
-                } else {
-                        queued--;
-                }
-        }
-
-        if (queued > 0)
-                goto out;
-
-        seqnum_kernel = udev_queue_get_kernel_seqnum(udev_queue);
-        if (seqnum_udev < seqnum_kernel)
-                goto out;
-
-        is_empty = 1;
-
-out:
-        fclose(queue_file);
-        return is_empty;
+        return access("/run/udev/queue", F_OK) < 0;
 }
 
 /**
@@ -348,63 +189,15 @@ out:
  * @start: first event sequence number
  * @end: last event sequence number
  *
- * Check if udev is currently processing any events in a given sequence number range.
+ * This function is deprecated, it just returns the result of
+ * udev_queue_get_queue_is_empty().
  *
- * Returns: a flag indicating if any of the sequence numbers in the given range is currently active.
+ * Returns: a flag indicating if udev is currently handling events.
  **/
 _public_ int udev_queue_get_seqnum_sequence_is_finished(struct udev_queue *udev_queue,
                                                unsigned long long int start, unsigned long long int end)
 {
-        unsigned long long int seqnum;
-        ssize_t devpath_len;
-        int unfinished;
-        FILE *queue_file;
-
-        if (udev_queue == NULL)
-                return -EINVAL;
-        queue_file = open_queue_file(udev_queue, &seqnum);
-        if (queue_file == NULL)
-                return 1;
-        if (start < seqnum)
-                start = seqnum;
-        if (start > end) {
-                fclose(queue_file);
-                return 1;
-        }
-        if (end - start > INT_MAX - 1) {
-                fclose(queue_file);
-                return -EOVERFLOW;
-        }
-
-        /*
-         * we might start with 0, and handle the initial seqnum
-         * only when we find an entry in the queue file
-         **/
-        unfinished = end - start;
-
-        do {
-                if (udev_queue_read_seqnum(queue_file, &seqnum) < 0)
-                        break;
-                devpath_len = udev_queue_skip_devpath(queue_file);
-                if (devpath_len < 0)
-                        break;
-
-                /*
-                 * we might start with an empty or re-build queue file, where
-                 * the initial seqnum is not recorded as finished
-                 */
-                if (start == seqnum && devpath_len > 0)
-                        unfinished++;
-
-                if (devpath_len == 0) {
-                        if (seqnum >= start && seqnum <= end)
-                                unfinished--;
-                }
-        } while (unfinished > 0);
-
-        fclose(queue_file);
-
-        return (unfinished == 0);
+        return udev_queue_get_queue_is_empty(udev_queue);
 }
 
 /**
@@ -412,69 +205,66 @@ _public_ int udev_queue_get_seqnum_sequence_is_finished(struct udev_queue *udev_
  * @udev_queue: udev queue context
  * @seqnum: sequence number
  *
- * Check if udev is currently processing a given sequence number.
+ * This function is deprecated, it just returns the result of
+ * udev_queue_get_queue_is_empty().
  *
- * Returns: a flag indicating if the given sequence number is currently active.
+ * Returns: a flag indicating if udev is currently handling events.
  **/
 _public_ int udev_queue_get_seqnum_is_finished(struct udev_queue *udev_queue, unsigned long long int seqnum)
 {
-        if (!udev_queue_get_seqnum_sequence_is_finished(udev_queue, seqnum, seqnum))
-                return 0;
-
-        return 1;
+        return udev_queue_get_queue_is_empty(udev_queue);
 }
 
 /**
  * udev_queue_get_queued_list_entry:
  * @udev_queue: udev queue context
  *
- * Get the first entry of the list of queued events.
+ * This function is deprecated.
  *
- * Returns: a udev_list_entry.
+ * Returns: NULL.
  **/
 _public_ struct udev_list_entry *udev_queue_get_queued_list_entry(struct udev_queue *udev_queue)
 {
-        unsigned long long int seqnum;
-        FILE *queue_file;
+        return NULL;
+}
 
-        if (udev_queue == NULL)
-                return NULL;
-        udev_list_cleanup(&udev_queue->queue_list);
+/**
+ * udev_queue_get_fd:
+ * @udev_queue: udev queue context
+ *
+ * Returns: a file descriptor to watch for a queue to become empty.
+ */
+_public_ int udev_queue_get_fd(struct udev_queue *udev_queue) {
+        int fd;
+        int r;
 
-        queue_file = open_queue_file(udev_queue, &seqnum);
-        if (queue_file == NULL)
-                return NULL;
+        if (udev_queue->fd >= 0)
+                return udev_queue->fd;
 
-        for (;;) {
-                char syspath[UTIL_PATH_SIZE];
-                char *s;
-                size_t l;
-                ssize_t len;
-                char seqnum_str[32];
-                struct udev_list_entry *list_entry;
-
-                if (udev_queue_read_seqnum(queue_file, &seqnum) < 0)
-                        break;
-                snprintf(seqnum_str, sizeof(seqnum_str), "%llu", seqnum);
-
-                s = syspath;
-                l = strpcpy(&s, sizeof(syspath), "/sys");
-                len = udev_queue_read_devpath(queue_file, s, l);
-                if (len < 0)
-                        break;
-
-                if (len > 0) {
-                        udev_list_entry_add(&udev_queue->queue_list, syspath, seqnum_str);
-                } else {
-                        udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_queue->queue_list)) {
-                                if (streq(seqnum_str, udev_list_entry_get_value(list_entry))) {
-                                        udev_list_entry_delete(list_entry);
-                                        break;
-                                }
-                        }
-                }
+        fd = inotify_init1(IN_CLOEXEC);
+        if (fd < 0)
+                return -errno;
+
+        r = inotify_add_watch(fd, "/run/udev" , IN_DELETE);
+        if (r < 0) {
+                r = -errno;
+                close(fd);
+                return r;
         }
-        fclose(queue_file);
 
-        return udev_list_get_entry(&udev_queue->queue_list);
+        udev_queue->fd = fd;
+        return fd;
+}
+
+/**
+ * udev_queue_flush:
+ * @udev_queue: udev queue context
+ *
+ * Returns: the result of clearing the watch for queue changes.
+ */
+_public_ int udev_queue_flush(struct udev_queue *udev_queue) {
+        if (udev_queue->fd < 0)
+                return -EINVAL;
+
+        return flush_fd(udev_queue->fd);
 }
index b9b8f13..4f2f115 100644 (file)
@@ -170,14 +170,16 @@ struct udev_queue *udev_queue_ref(struct udev_queue *udev_queue);
 struct udev_queue *udev_queue_unref(struct udev_queue *udev_queue);
 struct udev *udev_queue_get_udev(struct udev_queue *udev_queue);
 struct udev_queue *udev_queue_new(struct udev *udev);
-unsigned long long int udev_queue_get_kernel_seqnum(struct udev_queue *udev_queue);
-unsigned long long int udev_queue_get_udev_seqnum(struct udev_queue *udev_queue);
+unsigned long long int udev_queue_get_kernel_seqnum(struct udev_queue *udev_queue) __attribute__ ((deprecated));
+unsigned long long int udev_queue_get_udev_seqnum(struct udev_queue *udev_queue) __attribute__ ((deprecated));
 int udev_queue_get_udev_is_active(struct udev_queue *udev_queue);
 int udev_queue_get_queue_is_empty(struct udev_queue *udev_queue);
-int udev_queue_get_seqnum_is_finished(struct udev_queue *udev_queue, unsigned long long int seqnum);
+int udev_queue_get_seqnum_is_finished(struct udev_queue *udev_queue, unsigned long long int seqnum) __attribute__ ((deprecated));
 int udev_queue_get_seqnum_sequence_is_finished(struct udev_queue *udev_queue,
-                                               unsigned long long int start, unsigned long long int end);
-struct udev_list_entry *udev_queue_get_queued_list_entry(struct udev_queue *udev_queue);
+                                               unsigned long long int start, unsigned long long int end) __attribute__ ((deprecated));
+int udev_queue_get_fd(struct udev_queue *udev_queue);
+int udev_queue_flush(struct udev_queue *udev_queue);
+struct udev_list_entry *udev_queue_get_queued_list_entry(struct udev_queue *udev_queue) __attribute__ ((deprecated));
 
 /*
  *  udev_hwdb
index 1e6f885..95cd1c7 100644 (file)
@@ -82,6 +82,8 @@ global:
         udev_queue_get_udev;
         udev_queue_get_udev_is_active;
         udev_queue_get_udev_seqnum;
+        udev_queue_get_fd;
+        udev_queue_flush;
         udev_queue_new;
         udev_queue_ref;
         udev_queue_unref;
diff --git a/src/locale/generate-kbd-model-map b/src/locale/generate-kbd-model-map
deleted file mode 100755 (executable)
index b8ffa0f..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-import sys
-import system_config_keyboard.keyboard_models
-
-def strdash(s):
-        return s.strip() or '-'
-
-def tab_extend(s, n=1):
-        s = strdash(s)
-        k = len(s) // 8
-
-        if k >= n:
-                f = 1
-        else:
-                f = n - k
-
-        return s + '\t'*f
-
-
-models = system_config_keyboard.keyboard_models.KeyboardModels().get_models()
-
-print "# Generated from system-config-keyboard's model list"
-print "# consolelayout\t\txlayout\txmodel\t\txvariant\txoptions"
-
-for key, value in reversed(models.items()):
-        options = "terminate:ctrl_alt_bksp"
-        if value[4]:
-                options += ',' + value[4]
-
-        print ''.join((tab_extend(key, 3), tab_extend(value[1]),
-                       tab_extend(value[2], 2), tab_extend(value[3], 2),
-                       options))
index 2632305..2bb0d3b 100644 (file)
@@ -43,6 +43,7 @@
 #include "path-util.h"
 #include "utf8.h"
 #include "def.h"
+#include "locale-util.h"
 
 static bool arg_no_pager = false;
 static bool arg_ask_password = true;
@@ -177,192 +178,19 @@ static int set_locale(sd_bus *bus, char **args, unsigned n) {
         return 0;
 }
 
-static int add_locales_from_archive(Set *locales) {
-        /* Stolen from glibc... */
-
-        struct locarhead {
-                uint32_t magic;
-                /* Serial number.  */
-                uint32_t serial;
-                /* Name hash table.  */
-                uint32_t namehash_offset;
-                uint32_t namehash_used;
-                uint32_t namehash_size;
-                /* String table.  */
-                uint32_t string_offset;
-                uint32_t string_used;
-                uint32_t string_size;
-                /* Table with locale records.  */
-                uint32_t locrectab_offset;
-                uint32_t locrectab_used;
-                uint32_t locrectab_size;
-                /* MD5 sum hash table.  */
-                uint32_t sumhash_offset;
-                uint32_t sumhash_used;
-                uint32_t sumhash_size;
-        };
-
-        struct namehashent {
-                /* Hash value of the name.  */
-                uint32_t hashval;
-                /* Offset of the name in the string table.  */
-                uint32_t name_offset;
-                /* Offset of the locale record.  */
-                uint32_t locrec_offset;
-        };
-
-        const struct locarhead *h;
-        const struct namehashent *e;
-        const void *p = MAP_FAILED;
-        _cleanup_close_ int fd = -1;
-        size_t sz = 0;
-        struct stat st;
-        unsigned i;
-        int r;
-
-        fd = open("/usr/lib/locale/locale-archive", O_RDONLY|O_NOCTTY|O_CLOEXEC);
-        if (fd < 0) {
-                if (errno != ENOENT)
-                        log_error("Failed to open locale archive: %m");
-                r = -errno;
-                goto finish;
-        }
-
-        if (fstat(fd, &st) < 0) {
-                log_error("fstat() failed: %m");
-                r = -errno;
-                goto finish;
-        }
-
-        if (!S_ISREG(st.st_mode)) {
-                log_error("Archive file is not regular");
-                r = -EBADMSG;
-                goto finish;
-        }
-
-        if (st.st_size < (off_t) sizeof(struct locarhead)) {
-                log_error("Archive has invalid size");
-                r = -EBADMSG;
-                goto finish;
-        }
-
-        p = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
-        if (p == MAP_FAILED) {
-                log_error("Failed to map archive: %m");
-                r = -errno;
-                goto finish;
-        }
-
-        h = (const struct locarhead *) p;
-        if (h->magic != 0xde020109 ||
-            h->namehash_offset + h->namehash_size > st.st_size ||
-            h->string_offset + h->string_size > st.st_size ||
-            h->locrectab_offset + h->locrectab_size > st.st_size ||
-            h->sumhash_offset + h->sumhash_size > st.st_size) {
-                log_error("Invalid archive file.");
-                r = -EBADMSG;
-                goto finish;
-        }
-
-        e = (const struct namehashent*) ((const uint8_t*) p + h->namehash_offset);
-        for (i = 0; i < h->namehash_size; i++) {
-                char *z;
-
-                if (e[i].locrec_offset == 0)
-                        continue;
-
-                if (!utf8_is_valid((char*) p + e[i].name_offset))
-                        continue;
-
-                z = strdup((char*) p + e[i].name_offset);
-                if (!z) {
-                        r = log_oom();
-                        goto finish;
-                }
-
-                r = set_consume(locales, z);
-                if (r < 0) {
-                        log_error("Failed to add locale: %s", strerror(-r));
-                        goto finish;
-                }
-        }
-
-        r = 0;
-
- finish:
-        if (p != MAP_FAILED)
-                munmap((void*) p, sz);
-
-        return r;
-}
-
-static int add_locales_from_libdir (Set *locales) {
-        _cleanup_closedir_ DIR *dir;
-        struct dirent *entry;
-        int r;
-
-        dir = opendir("/usr/lib/locale");
-        if (!dir) {
-                log_error("Failed to open locale directory: %m");
-                return -errno;
-        }
-
-        errno = 0;
-        while ((entry = readdir(dir))) {
-                char *z;
-
-                if (entry->d_type != DT_DIR)
-                        continue;
-
-                if (ignore_file(entry->d_name))
-                        continue;
-
-                z = strdup(entry->d_name);
-                if (!z)
-                        return log_oom();
-
-                r = set_consume(locales, z);
-                if (r < 0 && r != -EEXIST) {
-                        log_error("Failed to add locale: %s", strerror(-r));
-                        return r;
-                }
-
-                errno = 0;
-        }
-
-        if (errno > 0) {
-                log_error("Failed to read locale directory: %m");
-                return -errno;
-        }
-
-        return 0;
-}
-
 static int list_locales(sd_bus *bus, char **args, unsigned n) {
-        _cleanup_set_free_ Set *locales;
         _cleanup_strv_free_ char **l = NULL;
         int r;
 
-        locales = set_new(string_hash_func, string_compare_func);
-        if (!locales)
-                return log_oom();
-
-        r = add_locales_from_archive(locales);
-        if (r < 0 && r != -ENOENT)
-                return r;
+        assert(args);
 
-        r = add_locales_from_libdir(locales);
-        if (r < 0)
+        r = get_locales(&l);
+        if (r < 0) {
+                log_error("Failed to read list of locales: %s", strerror(-r));
                 return r;
-
-        l = set_get_strv(locales);
-        if (!l)
-                return log_oom();
-
-        strv_sort(l);
+        }
 
         pager_open_if_enabled();
-
         strv_print(l);
 
         return 0;
@@ -612,8 +440,7 @@ static int list_x11_keymaps(sd_bus *bus, char **args, unsigned n) {
         return 0;
 }
 
-static int help(void) {
-
+static void help(void) {
         printf("%s [OPTIONS...] COMMAND ...\n\n"
                "Query or change system locale and keyboard settings.\n\n"
                "  -h --help                Show this help\n"
@@ -635,10 +462,8 @@ static int help(void) {
                "  list-x11-keymap-layouts  Show known X11 keyboard mapping layouts\n"
                "  list-x11-keymap-variants [LAYOUT]\n"
                "                           Show known X11 keyboard mapping variants\n"
-               "  list-x11-keymap-options  Show known X11 keyboard mapping options\n",
-               program_invocation_short_name);
-
-        return 0;
+               "  list-x11-keymap-options  Show known X11 keyboard mapping options\n"
+               , program_invocation_short_name);
 }
 
 static int parse_argv(int argc, char *argv[]) {
@@ -666,12 +491,13 @@ static int parse_argv(int argc, char *argv[]) {
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "hH:M:", options, NULL)) >= 0) {
+        while ((c = getopt_long(argc, argv, "hH:M:", options, NULL)) >= 0)
 
                 switch (c) {
 
                 case 'h':
-                        return help();
+                        help();
+                        return 0;
 
                 case ARG_VERSION:
                         puts(PACKAGE_STRING);
@@ -706,7 +532,6 @@ static int parse_argv(int argc, char *argv[]) {
                 default:
                         assert_not_reached("Unhandled option");
                 }
-        }
 
         return 1;
 }
@@ -796,7 +621,7 @@ static int localectl_main(sd_bus *bus, int argc, char *argv[]) {
 }
 
 int main(int argc, char*argv[]) {
-        _cleanup_bus_unref_ sd_bus *bus = NULL;
+        _cleanup_bus_close_unref_ sd_bus *bus = NULL;
         int r;
 
         setlocale(LC_ALL, "");
index de6e3b2..508a000 100644 (file)
@@ -23,6 +23,7 @@
 #include <errno.h>
 #include <string.h>
 #include <unistd.h>
+#include <sys/capability.h>
 
 #include "sd-bus.h"
 
@@ -38,6 +39,7 @@
 #include "bus-error.h"
 #include "bus-message.h"
 #include "event-util.h"
+#include "locale-util.h"
 
 enum {
         /* We don't list LC_ALL here on purpose. People should be
@@ -130,12 +132,12 @@ static void context_free_locale(Context *c) {
                 free_and_replace(&c->locale[p], NULL);
 }
 
-static void context_free(Context *c, sd_bus *bus) {
+static void context_free(Context *c) {
         context_free_locale(c);
         context_free_x11(c);
         context_free_vconsole(c);
 
-        bus_verify_polkit_async_registry_free(bus, c->polkit_registry);
+        bus_verify_polkit_async_registry_free(c->polkit_registry);
 };
 
 static void locale_simplify(Context *c) {
@@ -209,6 +211,7 @@ static int x11_read_data(Context *c) {
         FILE *f;
         char line[LINE_MAX];
         bool in_section = false;
+        int r;
 
         context_free_x11(c);
 
@@ -228,10 +231,10 @@ static int x11_read_data(Context *c) {
                 if (in_section && first_word(l, "Option")) {
                         char **a;
 
-                        a = strv_split_quoted(l);
-                        if (!a) {
+                        r = strv_split_quoted(&a, l);
+                        if (r < 0) {
                                 fclose(f);
-                                return -ENOMEM;
+                                return r;
                         }
 
                         if (strv_length(a) == 3) {
@@ -255,8 +258,8 @@ static int x11_read_data(Context *c) {
                 } else if (!in_section && first_word(l, "Section")) {
                         char **a;
 
-                        a = strv_split_quoted(l);
-                        if (!a) {
+                        r = strv_split_quoted(&a, l);
+                        if (r < 0) {
                                 fclose(f);
                                 return -ENOMEM;
                         }
@@ -288,7 +291,7 @@ static int locale_write_data(Context *c) {
         int r, p;
         char **l = NULL;
 
-        r = load_env_file("/etc/locale.conf", NULL, &l);
+        r = load_env_file(NULL, "/etc/locale.conf", NULL, &l);
         if (r < 0 && r != -ENOENT)
                 return r;
 
@@ -393,7 +396,7 @@ static int vconsole_write_data(Context *c) {
         int r;
         _cleanup_strv_free_ char **l = NULL;
 
-        r = load_env_file("/etc/vconsole.conf", NULL, &l);
+        r = load_env_file(NULL, "/etc/vconsole.conf", NULL, &l);
         if (r < 0 && r != -ENOENT)
                 return r;
 
@@ -532,6 +535,7 @@ static int read_next_mapping(FILE *f, unsigned *n, char ***a) {
         for (;;) {
                 char line[LINE_MAX];
                 char *l, **b;
+                int r;
 
                 errno = 0;
                 if (!fgets(line, sizeof(line), f)) {
@@ -548,9 +552,9 @@ static int read_next_mapping(FILE *f, unsigned *n, char ***a) {
                 if (l[0] == 0 || l[0] == '#')
                         continue;
 
-                b = strv_split_quoted(l);
-                if (!b)
-                        return -ENOMEM;
+                r = strv_split_quoted(&b, l);
+                if (r < 0)
+                        return r;
 
                 if (strv_length(b) < 5) {
                         log_error("Invalid line "SYSTEMD_KBD_MODEL_MAP":%u, ignoring.", *n);
@@ -712,15 +716,16 @@ static int find_legacy_keymap(Context *c, char **new_keymap) {
                         }
                 }
 
-                if (matching > 0 &&
-                    streq_ptr(c->x11_model, a[2])) {
-                        matching++;
-
-                        if (streq_ptr(c->x11_variant, a[3])) {
+                if (matching > 0) {
+                        if (isempty(c->x11_model) || streq_ptr(c->x11_model, a[2])) {
                                 matching++;
 
-                                if (streq_ptr(c->x11_options, a[4]))
+                                if (streq_ptr(c->x11_variant, a[3])) {
                                         matching++;
+
+                                        if (streq_ptr(c->x11_options, a[4]))
+                                                matching++;
+                                }
                         }
                 }
 
@@ -847,7 +852,7 @@ static int method_set_locale(sd_bus *bus, sd_bus_message *m, void *userdata, sd_
                         k = strlen(names[p]);
                         if (startswith(*i, names[p]) &&
                             (*i)[k] == '=' &&
-                            string_is_safe((*i) + k + 1)) {
+                            locale_is_valid((*i) + k + 1)) {
                                 valid = true;
                                 passed[p] = true;
 
@@ -872,9 +877,7 @@ static int method_set_locale(sd_bus *bus, sd_bus_message *m, void *userdata, sd_
         }
 
         if (modified) {
-                r = bus_verify_polkit_async(bus, &c->polkit_registry, m,
-                                            "org.freedesktop.locale1.set-locale", interactive,
-                                            error, method_set_locale, c);
+                r = bus_verify_polkit_async(m, CAP_SYS_ADMIN, "org.freedesktop.locale1.set-locale", interactive, &c->polkit_registry, error);
                 if (r < 0)
                         return r;
                 if (r == 0)
@@ -950,9 +953,7 @@ static int method_set_vc_keyboard(sd_bus *bus, sd_bus_message *m, void *userdata
                     (keymap_toggle && (!filename_is_safe(keymap_toggle) || !string_is_safe(keymap_toggle))))
                         return sd_bus_error_set_errnof(error, -EINVAL, "Received invalid keymap data");
 
-                r = bus_verify_polkit_async(bus, &c->polkit_registry, m,
-                                "org.freedesktop.locale1.set-keyboard",
-                                interactive, error, method_set_vc_keyboard, c);
+                r = bus_verify_polkit_async(m, CAP_SYS_ADMIN, "org.freedesktop.locale1.set-keyboard", interactive, &c->polkit_registry, error);
                 if (r < 0)
                         return r;
                 if (r == 0)
@@ -1022,9 +1023,7 @@ static int method_set_x11_keyboard(sd_bus *bus, sd_bus_message *m, void *userdat
                     (options && !string_is_safe(options)))
                         return sd_bus_error_set_errnof(error, -EINVAL, "Received invalid keyboard data");
 
-                r = bus_verify_polkit_async(bus, &c->polkit_registry, m,
-                                "org.freedesktop.locale1.set-keyboard",
-                                interactive, error, method_set_x11_keyboard, c);
+                r = bus_verify_polkit_async(m, CAP_SYS_ADMIN, "org.freedesktop.locale1.set-keyboard", interactive, &c->polkit_registry, error);
                 if (r < 0)
                         return r;
                 if (r == 0)
@@ -1075,7 +1074,7 @@ static const sd_bus_vtable locale_vtable[] = {
 };
 
 static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) {
-        _cleanup_bus_unref_ sd_bus *bus = NULL;
+        _cleanup_bus_close_unref_ sd_bus *bus = NULL;
         int r;
 
         assert(c);
@@ -1088,7 +1087,7 @@ static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) {
                 return r;
         }
 
-        r = sd_bus_add_object_vtable(bus, "/org/freedesktop/locale1", "org.freedesktop.locale1", locale_vtable, c);
+        r = sd_bus_add_object_vtable(bus, NULL, "/org/freedesktop/locale1", "org.freedesktop.locale1", locale_vtable, c);
         if (r < 0) {
                 log_error("Failed to register object: %s", strerror(-r));
                 return r;
@@ -1115,7 +1114,7 @@ static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) {
 int main(int argc, char *argv[]) {
         Context context = {};
         _cleanup_event_unref_ sd_event *event = NULL;
-        _cleanup_bus_unref_ sd_bus *bus = NULL;
+        _cleanup_bus_close_unref_ sd_bus *bus = NULL;
         int r;
 
         log_set_target(LOG_TARGET_AUTO);
@@ -1156,7 +1155,7 @@ int main(int argc, char *argv[]) {
         }
 
 finish:
-        context_free(&context, bus);
+        context_free(&context);
 
         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
 }
index e1cf897..694df2c 100644 (file)
@@ -12,7 +12,7 @@ ENV{MAJOR}=="", GOTO="uaccess_end"
 SUBSYSTEM=="usb", ENV{ID_USB_INTERFACES}=="*:060101:*", TAG+="uaccess"
 
 # Digicams with proprietary protocol
-ENV{ID_GPHOTO2}=="*?", TAG+="uaccess"
+ENV{ID_GPHOTO2}=="?*", TAG+="uaccess"
 
 # SCSI and USB scanners
 ENV{libsane_matched}=="yes", TAG+="uaccess"
@@ -49,13 +49,13 @@ SUBSYSTEM=="drm", KERNEL=="card*|renderD*", TAG+="uaccess"
 SUBSYSTEM=="misc", KERNEL=="kvm", TAG+="uaccess"
 
 # smart-card readers
-ENV{ID_SMARTCARD_READER}=="*?", TAG+="uaccess"
+ENV{ID_SMARTCARD_READER}=="?*", TAG+="uaccess"
 
 # (USB) authentication devices
-ENV{ID_SECURITY_TOKEN}=="*?", TAG+="uaccess"
+ENV{ID_SECURITY_TOKEN}=="?*", TAG+="uaccess"
 
 # PDA devices
-ENV{ID_PDA}=="*?", TAG+="uaccess"
+ENV{ID_PDA}=="?*", TAG+="uaccess"
 
 # Programmable remote control
 ENV{ID_REMOTE_CONTROL}=="1", TAG+="uaccess"
@@ -64,12 +64,15 @@ ENV{ID_REMOTE_CONTROL}=="1", TAG+="uaccess"
 SUBSYSTEM=="input", ENV{ID_INPUT_JOYSTICK}=="?*", TAG+="uaccess"
 
 # color measurement devices
-ENV{COLOR_MEASUREMENT_DEVICE}=="*?", TAG+="uaccess"
+ENV{COLOR_MEASUREMENT_DEVICE}=="?*", TAG+="uaccess"
 
 # DDC/CI device, usually high-end monitors such as the DreamColor
-ENV{DDC_DEVICE}=="*?", TAG+="uaccess"
+ENV{DDC_DEVICE}=="?*", TAG+="uaccess"
 
 # media player raw devices (for user-mode drivers, Android SDK, etc.)
 SUBSYSTEM=="usb", ENV{ID_MEDIA_PLAYER}=="?*", TAG+="uaccess"
 
+# software-defined radio communication devices
+ENV{ID_SOFTWARE_RADIO}=="?*", TAG+="uaccess"
+
 LABEL="uaccess_end"
index 48c2ec4..d5ea1d9 100644 (file)
@@ -64,7 +64,7 @@ static int inhibit(sd_bus *bus, sd_bus_error *error) {
         if (r < 0)
                 return r;
 
-        r = dup(fd);
+        r = fcntl(fd, F_DUPFD_CLOEXEC, 3);
         if (r < 0)
                 return -errno;
 
@@ -100,11 +100,11 @@ static int print_inhibitors(sd_bus *bus, sd_bus_error *error) {
                 get_process_comm(pid, &comm);
                 u = uid_to_name(uid);
 
-                printf("     Who: %s (UID %lu/%s, PID %lu/%s)\n"
+                printf("     Who: %s (UID "UID_FMT"/%s, PID "PID_FMT"/%s)\n"
                        "    What: %s\n"
                        "     Why: %s\n"
                        "    Mode: %s\n\n",
-                       who, (unsigned long) uid, strna(u), (unsigned long) pid, strna(comm),
+                       who, uid, strna(u), pid, strna(comm),
                        what,
                        why,
                        mode);
@@ -122,8 +122,7 @@ static int print_inhibitors(sd_bus *bus, sd_bus_error *error) {
         return 0;
 }
 
-static int help(void) {
-
+static void help(void) {
         printf("%s [OPTIONS...] {COMMAND} ...\n\n"
                "Execute a process while inhibiting shutdown/sleep/idle.\n\n"
                "  -h --help               Show this help\n"
@@ -135,10 +134,8 @@ static int help(void) {
                "     --who=STRING         A descriptive string who is inhibiting\n"
                "     --why=STRING         A descriptive string why is being inhibited\n"
                "     --mode=MODE          One of block or delay\n"
-               "     --list               List active inhibitors\n",
-               program_invocation_short_name);
-
-        return 0;
+               "     --list               List active inhibitors\n"
+               , program_invocation_short_name);
 }
 
 static int parse_argv(int argc, char *argv[]) {
@@ -168,12 +165,13 @@ static int parse_argv(int argc, char *argv[]) {
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "+h", options, NULL)) >= 0) {
+        while ((c = getopt_long(argc, argv, "+h", options, NULL)) >= 0)
 
                 switch (c) {
 
                 case 'h':
-                        return help();
+                        help();
+                        return 0;
 
                 case ARG_VERSION:
                         puts(PACKAGE_STRING);
@@ -206,7 +204,6 @@ static int parse_argv(int argc, char *argv[]) {
                 default:
                         assert_not_reached("Unhandled option");
                 }
-        }
 
         if (arg_action == ACTION_INHIBIT && argc == 1)
                 arg_action = ACTION_LIST;
@@ -221,7 +218,7 @@ static int parse_argv(int argc, char *argv[]) {
 
 int main(int argc, char *argv[]) {
         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
-        _cleanup_bus_unref_ sd_bus *bus = NULL;
+        _cleanup_bus_close_unref_ sd_bus *bus = NULL;
         int r;
 
         log_parse_environment();
index ebe9c1f..fcdf627 100644 (file)
@@ -1047,8 +1047,7 @@ static int terminate_seat(sd_bus *bus, char **args, unsigned n) {
         return 0;
 }
 
-static int help(void) {
-
+static void help(void) {
         printf("%s [OPTIONS...] {COMMAND} ...\n\n"
                "Send control commands to or query the login manager.\n\n"
                "  -h --help              Show this help\n"
@@ -1086,10 +1085,8 @@ static int help(void) {
                "  show-seat NAME...        Show properties of one or more seats\n"
                "  attach NAME DEVICE...    Attach one or more devices to a seat\n"
                "  flush-devices            Flush all device associations\n"
-               "  terminate-seat NAME...   Terminate all sessions on one or more seats\n",
-               program_invocation_short_name);
-
-        return 0;
+               "  terminate-seat NAME...   Terminate all sessions on one or more seats\n"
+               , program_invocation_short_name);
 }
 
 static int parse_argv(int argc, char *argv[]) {
@@ -1123,12 +1120,13 @@ static int parse_argv(int argc, char *argv[]) {
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "hp:als:H:M:", options, NULL)) >= 0) {
+        while ((c = getopt_long(argc, argv, "hp:als:H:M:", options, NULL)) >= 0)
 
                 switch (c) {
 
                 case 'h':
-                        return help();
+                        help();
+                        return 0;
 
                 case ARG_VERSION:
                         puts(PACKAGE_STRING);
@@ -1195,7 +1193,6 @@ static int parse_argv(int argc, char *argv[]) {
                 default:
                         assert_not_reached("Unhandled option");
                 }
-        }
 
         return 1;
 }
@@ -1298,7 +1295,7 @@ static int loginctl_main(sd_bus *bus, int argc, char *argv[]) {
 }
 
 int main(int argc, char *argv[]) {
-        _cleanup_bus_unref_ sd_bus *bus = NULL;
+        _cleanup_bus_close_unref_ sd_bus *bus = NULL;
         int r;
 
         setlocale(LC_ALL, "");
index dc86f0f..b76e16d 100644 (file)
@@ -277,9 +277,14 @@ int devnode_acl_all(struct udev *udev,
         SET_FOREACH(n, nodes, i) {
                 int k;
 
-                log_debug("Fixing up ACLs at %s for seat %s", n, seat);
+                log_debug("Changing ACLs at %s for seat %s (uid "UID_FMT"→"UID_FMT"%s%s)",
+                          n, seat, old_uid, new_uid,
+                          del ? " del" : "", add ? " add" : "");
+
                 k = devnode_acl(n, flush, del, old_uid, add, new_uid);
-                if (k < 0)
+                if (k == -ENOENT)
+                        log_debug("Device %s disappeared while setting ACLs", n);
+                else if (k < 0 && r == 0)
                         r = k;
         }
 
index c04f210..36ee441 100644 (file)
@@ -70,12 +70,33 @@ int manager_handle_action(
                 return 0;
         }
 
-        /* If we are docked don't react to lid closing */
         if (inhibit_key == INHIBIT_HANDLE_LID_SWITCH) {
+                int n;
+
+                /* If we are docked don't react to lid closing */
                 if (manager_is_docked(m)) {
                         log_debug("Ignoring lid switch request, system is docked.");
                         return 0;
                 }
+
+                /* If we have more than one display connected,
+                 * don't react to lid closing. */
+                n = manager_count_displays(m);
+                if (n < 0)
+                        log_warning("Display counting failed: %s", strerror(-n));
+                else if (n > 1) {
+                        log_debug("Ignoring lid switch request, %i displays connected.", n);
+                        return 0;
+                }
+
+                /* If the last system suspend or startup is too close,
+                 * let's not suspend for now, to give USB docking
+                 * stations some time to settle so that we can
+                 * properly watch its displays. */
+                if (m->lid_switch_ignore_event_source) {
+                        log_debug("Ignoring lid switch request, system startup or resume too close.");
+                        return 0;
+                }
         }
 
         /* If the key handling is inhibited, don't do anything */
@@ -130,17 +151,17 @@ int manager_handle_action(
 
                 /* If this is just a recheck of the lid switch then don't warn about anything */
                 if (!is_edge) {
-                        log_debug("Refusing operation, %s is inhibited by UID %lu/%s, PID %lu/%s.",
+                        log_debug("Refusing operation, %s is inhibited by UID "UID_FMT"/%s, PID "PID_FMT"/%s.",
                                   inhibit_what_to_string(inhibit_operation),
-                                  (unsigned long) offending->uid, strna(u),
-                                  (unsigned long) offending->pid, strna(comm));
+                                  offending->uid, strna(u),
+                                  offending->pid, strna(comm));
                         return 0;
                 }
 
-                log_error("Refusing operation, %s is inhibited by UID %lu/%s, PID %lu/%s.",
+                log_error("Refusing operation, %s is inhibited by UID "UID_FMT"/%s, PID "PID_FMT"/%s.",
                           inhibit_what_to_string(inhibit_operation),
-                          (unsigned long) offending->uid, strna(u),
-                          (unsigned long) offending->pid, strna(comm));
+                          offending->uid, strna(u),
+                          offending->pid, strna(comm));
 
                 warn_melody();
                 return -EPERM;
index 060978d..2561d13 100644 (file)
@@ -72,7 +72,7 @@ void button_free(Button *b) {
         if (b->fd >= 0) {
                 /* If the device has been unplugged close() returns
                  * ENODEV, let's ignore this, hence we don't use
-                 * close_nointr_nofail() */
+                 * safe_close() */
                 close(b->fd);
         }
 
index e4e593f..053d2ed 100644 (file)
@@ -32,6 +32,7 @@
 #include "audit.h"
 #include "bus-util.h"
 #include "bus-error.h"
+#include "udev-util.h"
 #include "logind.h"
 
 int manager_add_device(Manager *m, const char *sysfs, bool master, Device **_device) {
@@ -41,20 +42,15 @@ int manager_add_device(Manager *m, const char *sysfs, bool master, Device **_dev
         assert(sysfs);
 
         d = hashmap_get(m->devices, sysfs);
-        if (d) {
-                if (_device)
-                        *_device = d;
-
+        if (d)
                 /* we support adding master-flags, but not removing them */
                 d->master = d->master || master;
-
-                return 0;
+        else {
+                d = device_new(m, sysfs, master);
+                if (!d)
+                        return -ENOMEM;
         }
 
-        d = device_new(m, sysfs, master);
-        if (!d)
-                return -ENOMEM;
-
         if (_device)
                 *_device = d;
 
@@ -68,17 +64,12 @@ int manager_add_seat(Manager *m, const char *id, Seat **_seat) {
         assert(id);
 
         s = hashmap_get(m->seats, id);
-        if (s) {
-                if (_seat)
-                        *_seat = s;
-
-                return 0;
+        if (!s) {
+                s = seat_new(m, id);
+                if (!s)
+                        return -ENOMEM;
         }
 
-        s = seat_new(m, id);
-        if (!s)
-                return -ENOMEM;
-
         if (_seat)
                 *_seat = s;
 
@@ -92,17 +83,12 @@ int manager_add_session(Manager *m, const char *id, Session **_session) {
         assert(id);
 
         s = hashmap_get(m->sessions, id);
-        if (s) {
-                if (_session)
-                        *_session = s;
-
-                return 0;
+        if (!s) {
+                s = session_new(m, id);
+                if (!s)
+                        return -ENOMEM;
         }
 
-        s = session_new(m, id);
-        if (!s)
-                return -ENOMEM;
-
         if (_session)
                 *_session = s;
 
@@ -116,17 +102,12 @@ int manager_add_user(Manager *m, uid_t uid, gid_t gid, const char *name, User **
         assert(name);
 
         u = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
-        if (u) {
-                if (_user)
-                        *_user = u;
-
-                return 0;
+        if (!u) {
+                u = user_new(m, uid, gid, name);
+                if (!u)
+                        return -ENOMEM;
         }
 
-        u = user_new(m, uid, gid, name);
-        if (!u)
-                return -ENOMEM;
-
         if (_user)
                 *_user = u;
 
@@ -192,17 +173,12 @@ int manager_add_button(Manager *m, const char *name, Button **_button) {
         assert(name);
 
         b = hashmap_get(m->buttons, name);
-        if (b) {
-                if (_button)
-                        *_button = b;
-
-                return 0;
+        if (!b) {
+                b = button_new(m, name);
+                if (!b)
+                        return -ENOMEM;
         }
 
-        b = button_new(m, name);
-        if (!b)
-                return -ENOMEM;
-
         if (_button)
                 *_button = b;
 
@@ -276,9 +252,11 @@ int manager_process_seat_device(Manager *m, struct udev_device *d) {
                         return 0;
                 }
 
-                /* ignore non-master devices for unknown seats */
+                seat = hashmap_get(m->seats, sn);
                 master = udev_device_has_tag(d, "master-of-seat");
-                if (!master && !(seat = hashmap_get(m->seats, sn)))
+
+                /* Ignore non-master devices for unknown seats */
+                if (!master && !seat)
                         return 0;
 
                 r = manager_add_device(m, udev_device_get_syspath(d), master, &device);
@@ -438,7 +416,8 @@ bool manager_shall_kill(Manager *m, const char *user) {
 
 static int vt_is_busy(unsigned int vtnr) {
         struct vt_stat vt_stat;
-        int r = 0, fd;
+        int r = 0;
+        _cleanup_close_ int fd;
 
         assert(vtnr >= 1);
 
@@ -457,14 +436,12 @@ static int vt_is_busy(unsigned int vtnr) {
         else
                 r = !!(vt_stat.v_state & (1 << vtnr));
 
-        close_nointr_nofail(fd);
-
         return r;
 }
 
 int manager_spawn_autovt(Manager *m, unsigned int vtnr) {
         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
-        _cleanup_free_ char *name = NULL;
+        char name[sizeof("autovt@tty.service") + DECIMAL_STR_MAX(unsigned int)];
         int r;
 
         assert(m);
@@ -486,9 +463,7 @@ int manager_spawn_autovt(Manager *m, unsigned int vtnr) {
                         return -EBUSY;
         }
 
-        if (asprintf(&name, "autovt@tty%u.service", vtnr) < 0)
-                return log_oom();
-
+        snprintf(name, sizeof(name), "autovt@tty%u.service", vtnr);
         r = sd_bus_call_method(
                         m->bus,
                         "org.freedesktop.systemd1",
@@ -514,3 +489,51 @@ bool manager_is_docked(Manager *m) {
 
         return false;
 }
+
+int manager_count_displays(Manager *m) {
+        _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
+        struct udev_list_entry *item = NULL, *first = NULL;
+        int r;
+        int n = 0;
+
+        e = udev_enumerate_new(m->udev);
+        if (!e)
+                return -ENOMEM;
+
+        r = udev_enumerate_add_match_subsystem(e, "drm");
+        if (r < 0)
+                return r;
+
+        r = udev_enumerate_scan_devices(e);
+        if (r < 0)
+                return r;
+
+        first = udev_enumerate_get_list_entry(e);
+        udev_list_entry_foreach(item, first) {
+                _cleanup_udev_device_unref_ struct udev_device *d = NULL;
+                struct udev_device *p;
+                const char *status;
+
+                d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
+                if (!d)
+                        return -ENOMEM;
+
+                p = udev_device_get_parent(d);
+                if (!p)
+                        continue;
+
+                /* If the parent shares the same subsystem as the
+                 * device we are looking at then it is a connector,
+                 * which is what we are interested in. */
+                if (!streq_ptr(udev_device_get_subsystem(p), "drm"))
+                        continue;
+
+                /* We count any connector which is not explicitly
+                 * "disconnected" as connected. */
+                status = udev_device_get_sysattr_value(d, "status");
+                if (!streq_ptr(status, "disconnected"))
+                        n++;
+        }
+
+        return n;
+}
index fc89531..acef511 100644 (file)
@@ -189,7 +189,7 @@ static int method_get_session_by_pid(sd_bus *bus, sd_bus_message *message, void
         if (r < 0)
                 return r;
         if (!session)
-                return sd_bus_error_setf(error, BUS_ERROR_NO_SESSION_FOR_PID, "PID %lu does not belong to any known session", (unsigned long) pid);
+                return sd_bus_error_setf(error, BUS_ERROR_NO_SESSION_FOR_PID, "PID "PID_FMT" does not belong to any known session", pid);
 
         p = session_bus_path(session);
         if (!p)
@@ -215,7 +215,7 @@ static int method_get_user(sd_bus *bus, sd_bus_message *message, void *userdata,
 
         user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
         if (!user)
-                return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user '%lu' known or logged in", (unsigned long) uid);
+                return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user "UID_FMT" known or logged in", uid);
 
         p = user_bus_path(user);
         if (!p)
@@ -257,7 +257,7 @@ static int method_get_user_by_pid(sd_bus *bus, sd_bus_message *message, void *us
         if (r < 0)
                 return r;
         if (!user)
-                return sd_bus_error_setf(error, BUS_ERROR_NO_USER_FOR_PID, "PID %lu does not belong to any known or logged in user", (unsigned long) pid);
+                return sd_bus_error_setf(error, BUS_ERROR_NO_USER_FOR_PID, "PID "PID_FMT" does not belong to any known or logged in user", pid);
 
         p = user_bus_path(user);
         if (!p)
@@ -594,6 +594,17 @@ static int method_create_session(sd_bus *bus, sd_bus_message *message, void *use
                 if (!path)
                         return -ENOMEM;
 
+                log_debug("Sending reply about an existing session: "
+                          "id=%s object_path=%s uid=%u runtime_path=%s "
+                          "session_fd=%d seat=%s vtnr=%u",
+                          session->id,
+                          path,
+                          (uint32_t) session->user->uid,
+                          session->user->runtime_path,
+                          fifo_fd,
+                          session->seat ? session->seat->id : "",
+                          (uint32_t) session->vtnr);
+
                 return sd_bus_reply_method_return(
                                 message, "soshusub",
                                 session->id,
@@ -610,7 +621,7 @@ static int method_create_session(sd_bus *bus, sd_bus_message *message, void *use
         if (audit_id > 0) {
                 /* Keep our session IDs and the audit session IDs in sync */
 
-                if (asprintf(&id, "%lu", (unsigned long) audit_id) < 0)
+                if (asprintf(&id, "%"PRIu32, audit_id) < 0)
                         return -ENOMEM;
 
                 /* Wut? There's already a session by this name and we
@@ -912,7 +923,7 @@ static int method_kill_user(sd_bus *bus, sd_bus_message *message, void *userdata
 
         user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
         if (!user)
-                return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user '%lu' known or logged in", (unsigned long) uid);
+                return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user "UID_FMT" known or logged in", uid);
 
         r = user_kill(user, signo);
         if (r < 0)
@@ -962,7 +973,7 @@ static int method_terminate_user(sd_bus *bus, sd_bus_message *message, void *use
 
         user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
         if (!user)
-                return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user '%lu' known or logged in", (unsigned long) uid);
+                return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER, "No user "UID_FMT" known or logged in", uid);
 
         r = user_stop(user, true);
         if (r < 0)
@@ -1018,13 +1029,13 @@ static int method_set_user_linger(sd_bus *bus, sd_bus_message *message, void *us
         if (!pw)
                 return errno ? -errno : -ENOENT;
 
-        r = bus_verify_polkit_async(bus,
-                                    &m->polkit_registry,
-                                    message,
-                                    "org.freedesktop.login1.set-user-linger",
-                                    interactive,
-                                    error,
-                                    method_set_user_linger, m);
+        r = bus_verify_polkit_async(
+                        message,
+                        CAP_SYS_ADMIN,
+                        "org.freedesktop.login1.set-user-linger",
+                        interactive,
+                        &m->polkit_registry,
+                        error);
         if (r < 0)
                 return r;
         if (r == 0)
@@ -1190,13 +1201,13 @@ static int method_attach_device(sd_bus *bus, sd_bus_message *message, void *user
         if (!seat_name_is_valid(seat))
                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Seat %s is not valid", seat);
 
-        r = bus_verify_polkit_async(bus,
-                                    &m->polkit_registry,
-                                    message,
-                                    "org.freedesktop.login1.attach-device",
-                                    interactive,
-                                    error,
-                                    method_attach_device, m);
+        r = bus_verify_polkit_async(
+                        message,
+                        CAP_SYS_ADMIN,
+                        "org.freedesktop.login1.attach-device",
+                        interactive,
+                        &m->polkit_registry,
+                        error);
         if (r < 0)
                 return r;
         if (r == 0)
@@ -1221,13 +1232,13 @@ static int method_flush_devices(sd_bus *bus, sd_bus_message *message, void *user
         if (r < 0)
                 return r;
 
-        r = bus_verify_polkit_async(bus,
-                                    &m->polkit_registry,
-                                    message,
-                                    "org.freedesktop.login1.flush-devices",
-                                    interactive,
-                                    error,
-                                    method_flush_devices, m);
+        r = bus_verify_polkit_async(
+                        message,
+                        CAP_SYS_ADMIN,
+                        "org.freedesktop.login1.flush-devices",
+                        interactive,
+                        &m->polkit_registry,
+                        error);
         if (r < 0)
                 return r;
         if (r == 0)
@@ -1294,6 +1305,51 @@ static int bus_manager_log_shutdown(
                           q, NULL);
 }
 
+static int lid_switch_ignore_handler(sd_event_source *e, uint64_t usec, void *userdata) {
+        Manager *m = userdata;
+
+        assert(e);
+        assert(m);
+
+        m->lid_switch_ignore_event_source = sd_event_source_unref(m->lid_switch_ignore_event_source);
+        return 0;
+}
+
+int manager_set_lid_switch_ignore(Manager *m, usec_t until) {
+        int r;
+
+        assert(m);
+
+        if (until <= now(CLOCK_MONOTONIC))
+                return 0;
+
+        /* We want to ignore the lid switch for a while after each
+         * suspend, and after boot-up. Hence let's install a timer for
+         * this. As long as the event source exists we ignore the lid
+         * switch. */
+
+        if (m->lid_switch_ignore_event_source) {
+                usec_t u;
+
+                r = sd_event_source_get_time(m->lid_switch_ignore_event_source, &u);
+                if (r < 0)
+                        return r;
+
+                if (until <= u)
+                        return 0;
+
+                r = sd_event_source_set_time(m->lid_switch_ignore_event_source, until);
+        } else
+                r = sd_event_add_time(
+                                m->event,
+                                &m->lid_switch_ignore_event_source,
+                                CLOCK_MONOTONIC,
+                                until, 0,
+                                lid_switch_ignore_handler, m);
+
+        return r;
+}
+
 static int execute_shutdown_or_sleep(
                 Manager *m,
                 InhibitWhat w,
@@ -1337,6 +1393,9 @@ static int execute_shutdown_or_sleep(
         m->action_job = c;
         m->action_what = w;
 
+        /* Make sure the lid switch is ignored for a while */
+        manager_set_lid_switch_ignore(m, now(CLOCK_MONOTONIC) + IGNORE_LID_SWITCH_SUSPEND_USEC);
+
         return 0;
 }
 
@@ -1473,24 +1532,27 @@ static int method_do_shutdown_or_sleep(
         blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
 
         if (multiple_sessions) {
-                r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
-                                            action_multiple_sessions, interactive, error, method, m);
+                r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, interactive, &m->polkit_registry, error);
                 if (r < 0)
                         return r;
+                if (r == 0)
+                        return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
         }
 
         if (blocked) {
-                r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
-                                            action_ignore_inhibit, interactive, error, method, m);
+                r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, interactive, &m->polkit_registry, error);
                 if (r < 0)
                         return r;
+                if (r == 0)
+                        return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
         }
 
         if (!multiple_sessions && !blocked) {
-                r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
-                                            action, interactive, error, method, m);
+                r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action, interactive, &m->polkit_registry, error);
                 if (r < 0)
                         return r;
+                if (r == 0)
+                        return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
         }
 
         r = bus_manager_shutdown_or_sleep_now_or_later(m, unit_name, w, error);
@@ -1623,7 +1685,7 @@ static int method_can_shutdown_or_sleep(
         blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
 
         if (multiple_sessions) {
-                r = bus_verify_polkit(m->bus, message, action_multiple_sessions, false, &challenge, error);
+                r = bus_verify_polkit(message, CAP_SYS_BOOT, action_multiple_sessions, false, &challenge, error);
                 if (r < 0)
                         return r;
 
@@ -1636,7 +1698,7 @@ static int method_can_shutdown_or_sleep(
         }
 
         if (blocked) {
-                r = bus_verify_polkit(m->bus, message, action_ignore_inhibit, false, &challenge, error);
+                r = bus_verify_polkit(message, CAP_SYS_BOOT, action_ignore_inhibit, false, &challenge, error);
                 if (r < 0)
                         return r;
 
@@ -1652,7 +1714,7 @@ static int method_can_shutdown_or_sleep(
                 /* If neither inhibit nor multiple sessions
                  * apply then just check the normal policy */
 
-                r = bus_verify_polkit(m->bus, message, action, false, &challenge, error);
+                r = bus_verify_polkit(message, CAP_SYS_BOOT, action, false, &challenge, error);
                 if (r < 0)
                         return r;
 
@@ -1772,7 +1834,7 @@ static int method_inhibit(sd_bus *bus, sd_bus_message *message, void *userdata,
         if (m->action_what & w)
                 return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "The operation inhibition has been requested for is already running");
 
-        r = bus_verify_polkit_async(bus, &m->polkit_registry, message,
+        r = bus_verify_polkit_async(message, CAP_SYS_BOOT,
                                     w == INHIBIT_SHUTDOWN             ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
                                     w == INHIBIT_SLEEP                ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep"    : "org.freedesktop.login1.inhibit-delay-sleep") :
                                     w == INHIBIT_IDLE                 ? "org.freedesktop.login1.inhibit-block-idle" :
@@ -1780,7 +1842,7 @@ static int method_inhibit(sd_bus *bus, sd_bus_message *message, void *userdata,
                                     w == INHIBIT_HANDLE_SUSPEND_KEY   ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
                                     w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
                                                                         "org.freedesktop.login1.inhibit-handle-lid-switch",
-                                    false, error, method_inhibit, m);
+                                    false, &m->polkit_registry, error);
         if (r < 0)
                 return r;
         if (r == 0)
@@ -2155,9 +2217,9 @@ int manager_dispatch_delayed(Manager *manager) {
                 if (manager->action_timestamp + manager->inhibit_delay_max > now(CLOCK_MONOTONIC))
                         return 0;
 
-                log_info("Delay lock is active (UID %lu/%s, PID %lu/%s) but inhibitor timeout is reached.",
-                         (unsigned long) offending->uid, strna(u),
-                         (unsigned long) offending->pid, strna(comm));
+                log_info("Delay lock is active (UID "UID_FMT"/%s, PID "PID_FMT"/%s) but inhibitor timeout is reached.",
+                         offending->uid, strna(u),
+                         offending->pid, strna(comm));
         }
 
         /* Actually do the operation */
index 845302a..006f728 100644 (file)
@@ -30,3 +30,5 @@ Login.HibernateKeyIgnoreInhibited, config_parse_bool,          0, offsetof(Manag
 Login.LidSwitchIgnoreInhibited,    config_parse_bool,          0, offsetof(Manager, lid_switch_ignore_inhibited)
 Login.IdleAction,                  config_parse_handle_action, 0, offsetof(Manager, idle_action)
 Login.IdleActionSec,               config_parse_sec,           0, offsetof(Manager, idle_action_usec)
+Login.RuntimeDirectorySize,        config_parse_tmpfs_size,    0, offsetof(Manager, runtime_dir_size)
+Login.RemoveIPC,                   config_parse_bool,          0, offsetof(Manager, remove_ipc)
index d19d648..a9e14af 100644 (file)
@@ -151,9 +151,9 @@ int inhibitor_start(Inhibitor *i) {
 
         dual_timestamp_get(&i->since);
 
-        log_debug("Inhibitor %s (%s) pid=%lu uid=%lu mode=%s started.",
+        log_debug("Inhibitor %s (%s) pid="PID_FMT" uid="UID_FMT" mode=%s started.",
                   strna(i->who), strna(i->why),
-                  (unsigned long) i->pid, (unsigned long) i->uid,
+                  i->pid, i->uid,
                   inhibit_mode_to_string(i->mode));
 
         inhibitor_save(i);
@@ -169,9 +169,9 @@ int inhibitor_stop(Inhibitor *i) {
         assert(i);
 
         if (i->started)
-                log_debug("Inhibitor %s (%s) pid=%lu uid=%lu mode=%s stopped.",
+                log_debug("Inhibitor %s (%s) pid="PID_FMT" uid="UID_FMT" mode=%s stopped.",
                           strna(i->who), strna(i->why),
-                          (unsigned long) i->pid, (unsigned long) i->uid,
+                          i->pid, i->uid,
                           inhibit_mode_to_string(i->mode));
 
         if (i->state_file)
@@ -253,8 +253,7 @@ int inhibitor_load(Inhibitor *i) {
                 int fd;
 
                 fd = inhibitor_create_fifo(i);
-                if (fd >= 0)
-                        close_nointr_nofail(fd);
+                safe_close(fd);
         }
 
         return 0;
@@ -320,13 +319,8 @@ int inhibitor_create_fifo(Inhibitor *i) {
 void inhibitor_remove_fifo(Inhibitor *i) {
         assert(i);
 
-        if (i->event_source)
-                i->event_source = sd_event_source_unref(i->event_source);
-
-        if (i->fifo_fd >= 0) {
-                close_nointr_nofail(i->fifo_fd);
-                i->fifo_fd = -1;
-        }
+        i->event_source = sd_event_source_unref(i->event_source);
+        i->fifo_fd = safe_close(i->fifo_fd);
 
         if (i->fifo_path) {
                 unlink(i->fifo_path);
@@ -445,23 +439,23 @@ const char *inhibit_what_to_string(InhibitWhat w) {
 
 InhibitWhat inhibit_what_from_string(const char *s) {
         InhibitWhat what = 0;
-        char *w, *state;
+        const char *word, *state;
         size_t l;
 
-        FOREACH_WORD_SEPARATOR(w, l, s, ":", state) {
-                if (l == 8 && strneq(w, "shutdown", l))
+        FOREACH_WORD_SEPARATOR(word, l, s, ":", state) {
+                if (l == 8 && strneq(word, "shutdown", l))
                         what |= INHIBIT_SHUTDOWN;
-                else if (l == 5 && strneq(w, "sleep", l))
+                else if (l == 5 && strneq(word, "sleep", l))
                         what |= INHIBIT_SLEEP;
-                else if (l == 4 && strneq(w, "idle", l))
+                else if (l == 4 && strneq(word, "idle", l))
                         what |= INHIBIT_IDLE;
-                else if (l == 16 && strneq(w, "handle-power-key", l))
+                else if (l == 16 && strneq(word, "handle-power-key", l))
                         what |= INHIBIT_HANDLE_POWER_KEY;
-                else if (l == 18 && strneq(w, "handle-suspend-key", l))
+                else if (l == 18 && strneq(word, "handle-suspend-key", l))
                         what |= INHIBIT_HANDLE_SUSPEND_KEY;
-                else if (l == 20 && strneq(w, "handle-hibernate-key", l))
+                else if (l == 20 && strneq(word, "handle-hibernate-key", l))
                         what |= INHIBIT_HANDLE_HIBERNATE_KEY;
-                else if (l == 17 && strneq(w, "handle-lid-switch", l))
+                else if (l == 17 && strneq(word, "handle-lid-switch", l))
                         what |= INHIBIT_HANDLE_LID_SWITCH;
                 else
                         return _INHIBIT_WHAT_INVALID;
index 26cddfe..1a2f09c 100644 (file)
@@ -27,6 +27,7 @@
 #include "bus-util.h"
 #include "strv.h"
 #include "bus-errors.h"
+#include "bus-label.h"
 #include "logind.h"
 #include "logind-seat.h"
 
@@ -328,7 +329,7 @@ int seat_object_find(sd_bus *bus, const char *path, const char *interface, void
                 Session *session;
                 pid_t pid;
 
-                message = sd_bus_get_current(bus);
+                message = sd_bus_get_current_message(bus);
                 if (!message)
                         return 0;
 
@@ -356,7 +357,7 @@ int seat_object_find(sd_bus *bus, const char *path, const char *interface, void
                 if (!p)
                         return 0;
 
-                e = sd_bus_label_unescape(p);
+                e = bus_label_unescape(p);
                 if (!e)
                         return -ENOMEM;
 
@@ -374,7 +375,7 @@ char *seat_bus_path(Seat *s) {
 
         assert(s);
 
-        t = sd_bus_label_escape(s->id);
+        t = bus_label_escape(s->id);
         if (!t)
                 return NULL;
 
@@ -399,11 +400,9 @@ int seat_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***
                 if (!p)
                         return -ENOMEM;
 
-                r = strv_push(&l, p);
-                if (r < 0) {
-                        free(p);
+                r = strv_consume(&l, p);
+                if (r < 0)
                         return r;
-                }
         }
 
         *nodes = l;
index 631be5f..9992195 100644 (file)
@@ -120,9 +120,9 @@ int seat_save(Seat *s) {
 
                 fprintf(f,
                         "ACTIVE=%s\n"
-                        "ACTIVE_UID=%lu\n",
+                        "ACTIVE_UID="UID_FMT"\n",
                         s->active->id,
-                        (unsigned long) s->active->user->uid);
+                        s->active->user->uid);
         }
 
         if (s->sessions) {
@@ -168,14 +168,12 @@ int seat_load(Seat *s) {
 }
 
 static int vt_allocate(unsigned int vtnr) {
-        _cleanup_free_ char *p = NULL;
+        char p[sizeof("/dev/tty") + DECIMAL_STR_MAX(unsigned int)];
         _cleanup_close_ int fd = -1;
 
         assert(vtnr >= 1);
 
-        if (asprintf(&p, "/dev/tty%u", vtnr) < 0)
-                return -ENOMEM;
-
+        snprintf(p, sizeof(p), "/dev/tty%u", vtnr);
         fd = open_terminal(p, O_RDWR|O_NOCTTY|O_CLOEXEC);
         if (fd < 0)
                 return -errno;
@@ -277,8 +275,13 @@ int seat_switch_to(Seat *s, unsigned int num) {
         if (!num)
                 return -EINVAL;
 
-        if (num >= s->position_count || !s->positions[num])
+        if (num >= s->position_count || !s->positions[num]) {
+                /* allow switching to unused VTs to trigger auto-activate */
+                if (seat_has_vts(s) && num < 64)
+                        return chvt(num);
+
                 return -EINVAL;
+        }
 
         return session_activate(s->positions[num]);
 }
@@ -459,6 +462,7 @@ int seat_stop_sessions(Seat *s, bool force) {
 }
 
 void seat_evict_position(Seat *s, Session *session) {
+        Session *iter;
         unsigned int pos = session->pos;
 
         session->pos = 0;
@@ -466,8 +470,19 @@ void seat_evict_position(Seat *s, Session *session) {
         if (!pos)
                 return;
 
-        if (pos < s->position_count && s->positions[pos] == session)
+        if (pos < s->position_count && s->positions[pos] == session) {
                 s->positions[pos] = NULL;
+
+                /* There might be another session claiming the same
+                 * position (eg., during gdm->session transition), so lets look
+                 * for it and set it on the free slot. */
+                LIST_FOREACH(sessions_by_seat, iter, s->sessions) {
+                        if (iter->pos == pos) {
+                                s->positions[pos] = iter;
+                                break;
+                        }
+                }
+        }
 }
 
 void seat_claim_position(Seat *s, Session *session, unsigned int pos) {
index f9305dd..7d81500 100644 (file)
@@ -27,6 +27,7 @@
 #include "strv.h"
 #include "bus-util.h"
 #include "bus-errors.h"
+#include "bus-label.h"
 
 #include "logind.h"
 #include "logind-session.h"
@@ -492,7 +493,7 @@ int session_object_find(sd_bus *bus, const char *path, const char *interface, vo
                 sd_bus_message *message;
                 pid_t pid;
 
-                message = sd_bus_get_current(bus);
+                message = sd_bus_get_current_message(bus);
                 if (!message)
                         return 0;
 
@@ -515,7 +516,7 @@ int session_object_find(sd_bus *bus, const char *path, const char *interface, vo
                 if (!p)
                         return 0;
 
-                e = sd_bus_label_unescape(p);
+                e = bus_label_unescape(p);
                 if (!e)
                         return -ENOMEM;
 
@@ -533,7 +534,7 @@ char *session_bus_path(Session *s) {
 
         assert(s);
 
-        t = sd_bus_label_escape(s->id);
+        t = bus_label_escape(s->id);
         if (!t)
                 return NULL;
 
@@ -558,11 +559,9 @@ int session_node_enumerator(sd_bus *bus, const char *path, void *userdata, char
                 if (!p)
                         return -ENOMEM;
 
-                r = strv_push(&l, p);
-                if (r < 0) {
-                        free(p);
+                r = strv_consume(&l, p);
+                if (r < 0)
                         return r;
-                }
         }
 
         *nodes = l;
@@ -677,9 +676,11 @@ int session_send_create_reply(Session *s, sd_bus_error *error) {
                 return -ENOMEM;
 
         log_debug("Sending reply about created session: "
-                  "id=%s object_path=%s runtime_path=%s session_fd=%d seat=%s vtnr=%u",
+                  "id=%s object_path=%s uid=%u runtime_path=%s "
+                  "session_fd=%d seat=%s vtnr=%u",
                   s->id,
                   p,
+                  (uint32_t) s->user->uid,
                   s->user->runtime_path,
                   fifo_fd,
                   s->seat ? s->seat->id : "",
index 548f049..136bbce 100644 (file)
 
 static void session_remove_fifo(Session *s);
 
-static unsigned long devt_hash_func(const void *p, const uint8_t hash_key[HASH_KEY_SIZE]) {
-        uint64_t u = *(const dev_t*)p;
-
-        return uint64_hash_func(&u, hash_key);
-}
-
-static int devt_compare_func(const void *_a, const void *_b) {
-        dev_t a, b;
-
-        a = *(const dev_t*) _a;
-        b = *(const dev_t*) _b;
-
-        return a < b ? -1 : (a > b ? 1 : 0);
-}
-
 Session* session_new(Manager *m, const char *id) {
         Session *s;
 
@@ -153,8 +138,6 @@ void session_free(Session *s) {
 
         hashmap_remove(s->manager->sessions, s->id);
 
-        s->vt_source = sd_event_source_unref(s->vt_source);
-
         free(s->state_file);
         free(s);
 }
@@ -213,7 +196,6 @@ int session_save(Session *s) {
 
         if (s->scope)
                 fprintf(f, "SCOPE=%s\n", s->scope);
-
         if (s->scope_job)
                 fprintf(f, "SCOPE_JOB=%s\n", s->scope_job);
 
@@ -229,17 +211,54 @@ int session_save(Session *s) {
         if (s->display)
                 fprintf(f, "DISPLAY=%s\n", s->display);
 
-        if (s->remote_host)
-                fprintf(f, "REMOTE_HOST=%s\n", s->remote_host);
+        if (s->remote_host) {
+                _cleanup_free_ char *escaped;
+
+                escaped = cescape(s->remote_host);
+                if (!escaped) {
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                fprintf(f, "REMOTE_HOST=%s\n", escaped);
+        }
+
+        if (s->remote_user) {
+                _cleanup_free_ char *escaped;
+
+                escaped = cescape(s->remote_user);
+                if (!escaped) {
+                        r = -ENOMEM;
+                        goto finish;
+                }
 
-        if (s->remote_user)
-                fprintf(f, "REMOTE_USER=%s\n", s->remote_user);
+                fprintf(f, "REMOTE_USER=%s\n", escaped);
+        }
 
-        if (s->service)
-                fprintf(f, "SERVICE=%s\n", s->service);
+        if (s->service) {
+                _cleanup_free_ char *escaped;
 
-        if (s->desktop)
-                fprintf(f, "DESKTOP=%s\n", s->desktop);
+                escaped = cescape(s->service);
+                if (!escaped) {
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                fprintf(f, "SERVICE=%s\n", escaped);
+        }
+
+        if (s->desktop) {
+                _cleanup_free_ char *escaped;
+
+
+                escaped = cescape(s->desktop);
+                if (!escaped) {
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                fprintf(f, "DESKTOP=%s\n", escaped);
+        }
 
         if (s->seat && seat_has_vts(s->seat))
                 fprintf(f, "VTNR=%u\n", s->vtnr);
@@ -407,8 +426,7 @@ int session_load(Session *s) {
                    trigger the EOF. */
 
                 fd = session_create_fifo(s);
-                if (fd >= 0)
-                        close_nointr_nofail(fd);
+                safe_close(fd);
         }
 
         if (realtime) {
@@ -490,7 +508,7 @@ static int session_start_scope(Session *s) {
                 if (!scope)
                         return log_oom();
 
-                r = manager_start_scope(s->manager, scope, s->leader, s->user->slice, description, "systemd-logind.service", "systemd-user-session.service", &error, &job);
+                r = manager_start_scope(s->manager, scope, s->leader, s->user->slice, description, "systemd-logind.service", "systemd-user-sessions.service", &error, &job);
                 if (r < 0) {
                         log_error("Failed to start session scope %s: %s %s",
                                   scope, bus_error_message(&error, r), error.name);
@@ -534,7 +552,7 @@ int session_start(Session *s) {
                    MESSAGE_ID(SD_MESSAGE_SESSION_START),
                    "SESSION_ID=%s", s->id,
                    "USER_ID=%s", s->user->name,
-                   "LEADER=%lu", (unsigned long) s->leader,
+                   "LEADER="PID_FMT, s->leader,
                    "MESSAGE=New session %s of user %s.", s->id, s->user->name,
                    NULL);
 
@@ -546,6 +564,8 @@ int session_start(Session *s) {
 
         s->started = true;
 
+        user_elect_display(s->user);
+
         /* Save data */
         session_save(s);
         user_save(s->user);
@@ -554,7 +574,7 @@ int session_start(Session *s) {
 
         /* Send signals */
         session_send_signal(s, true);
-        user_send_changed(s->user, "Sessions", NULL);
+        user_send_changed(s->user, "Sessions", "Display", NULL);
         if (s->seat) {
                 if (s->seat->active == s)
                         seat_send_changed(s->seat, "Sessions", "ActiveSession", NULL);
@@ -613,6 +633,8 @@ int session_stop(Session *s, bool force) {
 
         s->stopping = true;
 
+        user_elect_display(s->user);
+
         session_save(s);
         user_save(s->user);
 
@@ -633,7 +655,7 @@ int session_finalize(Session *s) {
                            MESSAGE_ID(SD_MESSAGE_SESSION_STOP),
                            "SESSION_ID=%s", s->id,
                            "USER_ID=%s", s->user->name,
-                           "LEADER=%lu", (unsigned long) s->leader,
+                           "LEADER="PID_FMT, s->leader,
                            "MESSAGE=Removed session %s.", s->id,
                            NULL);
 
@@ -661,7 +683,7 @@ int session_finalize(Session *s) {
         }
 
         user_save(s->user);
-        user_send_changed(s->user, "Sessions", NULL);
+        user_send_changed(s->user, "Sessions", "Display", NULL);
 
         return r;
 }
@@ -683,7 +705,11 @@ void session_release(Session *s) {
                 return;
 
         if (!s->timer_event_source)
-                sd_event_add_monotonic(s->manager->event, &s->timer_event_source, now(CLOCK_MONOTONIC) + RELEASE_USEC, 0, release_timeout_callback, s);
+                sd_event_add_time(s->manager->event,
+                                  &s->timer_event_source,
+                                  CLOCK_MONOTONIC,
+                                  now(CLOCK_MONOTONIC) + RELEASE_USEC, 0,
+                                  release_timeout_callback, s);
 }
 
 bool session_is_active(Session *s) {
@@ -864,13 +890,8 @@ int session_create_fifo(Session *s) {
 static void session_remove_fifo(Session *s) {
         assert(s);
 
-        if (s->fifo_event_source)
-                s->fifo_event_source = sd_event_source_unref(s->fifo_event_source);
-
-        if (s->fifo_fd >= 0) {
-                close_nointr_nofail(s->fifo_fd);
-                s->fifo_fd = -1;
-        }
+        s->fifo_event_source = sd_event_source_unref(s->fifo_event_source);
+        s->fifo_fd = safe_close(s->fifo_fd);
 
         if (s->fifo_path) {
                 unlink(s->fifo_path);
@@ -940,8 +961,8 @@ int session_kill(Session *s, KillWho who, int signo) {
 static int session_open_vt(Session *s) {
         char path[sizeof("/dev/tty") + DECIMAL_STR_MAX(s->vtnr)];
 
-        if (!s->vtnr)
-                return -1;
+        if (s->vtnr < 1)
+                return -ENODEV;
 
         if (s->vtfd >= 0)
                 return s->vtfd;
@@ -950,61 +971,62 @@ static int session_open_vt(Session *s) {
         s->vtfd = open(path, O_RDWR | O_CLOEXEC | O_NONBLOCK | O_NOCTTY);
         if (s->vtfd < 0) {
                 log_error("cannot open VT %s of session %s: %m", path, s->id);
-                return -1;
+                return -errno;
         }
 
         return s->vtfd;
 }
 
-static int session_vt_fn(sd_event_source *source, const struct signalfd_siginfo *si, void *data) {
-        Session *s = data;
-
-        if (s->vtfd >= 0)
-                ioctl(s->vtfd, VT_RELDISP, 1);
-
-        return 0;
-}
-
-void session_mute_vt(Session *s) {
+int session_prepare_vt(Session *s) {
         int vt, r;
         struct vt_mode mode = { 0 };
-        sigset_t mask;
+
+        if (s->vtnr < 1)
+                return 0;
 
         vt = session_open_vt(s);
         if (vt < 0)
-                return;
+                return vt;
 
-        r = ioctl(vt, KDSKBMODE, K_OFF);
-        if (r < 0)
+        r = fchown(vt, s->user->uid, -1);
+        if (r < 0) {
+                r = -errno;
+                log_error("Cannot change owner of /dev/tty%u: %m", s->vtnr);
                 goto error;
+        }
 
-        r = ioctl(vt, KDSETMODE, KD_GRAPHICS);
-        if (r < 0)
+        r = ioctl(vt, KDSKBMODE, K_OFF);
+        if (r < 0) {
+                r = -errno;
+                log_error("Cannot set K_OFF on /dev/tty%u: %m", s->vtnr);
                 goto error;
+        }
 
-        sigemptyset(&mask);
-        sigaddset(&mask, SIGUSR1);
-        sigprocmask(SIG_BLOCK, &mask, NULL);
-
-        r = sd_event_add_signal(s->manager->event, &s->vt_source, SIGUSR1, session_vt_fn, s);
-        if (r < 0)
+        r = ioctl(vt, KDSETMODE, KD_GRAPHICS);
+        if (r < 0) {
+                r = -errno;
+                log_error("Cannot set KD_GRAPHICS on /dev/tty%u: %m", s->vtnr);
                 goto error;
+        }
 
         /* Oh, thanks to the VT layer, VT_AUTO does not work with KD_GRAPHICS.
          * So we need a dummy handler here which just acknowledges *all* VT
          * switch requests. */
         mode.mode = VT_PROCESS;
-        mode.relsig = SIGUSR1;
-        mode.acqsig = SIGUSR1;
+        mode.relsig = SIGRTMIN;
+        mode.acqsig = SIGRTMIN + 1;
         r = ioctl(vt, VT_SETMODE, &mode);
-        if (r < 0)
+        if (r < 0) {
+                r = -errno;
+                log_error("Cannot set VT_PROCESS on /dev/tty%u: %m", s->vtnr);
                 goto error;
+        }
 
-        return;
+        return 0;
 
 error:
-        log_error("cannot mute VT %u for session %s (%d/%d)", s->vtnr, s->id, r, errno);
         session_restore_vt(s);
+        return r;
 }
 
 void session_restore_vt(Session *s) {
@@ -1016,19 +1038,19 @@ void session_restore_vt(Session *s) {
         if (vt < 0)
                 return;
 
-        s->vt_source = sd_event_source_unref(s->vt_source);
-
         ioctl(vt, KDSETMODE, KD_TEXT);
 
         if (read_one_line_file("/sys/module/vt/parameters/default_utf8", &utf8) >= 0 && *utf8 == '1')
                 kb = K_UNICODE;
+
         ioctl(vt, KDSKBMODE, kb);
 
         mode.mode = VT_AUTO;
         ioctl(vt, VT_SETMODE, &mode);
 
-        close_nointr_nofail(vt);
-        s->vtfd = -1;
+        fchown(vt, 0, -1);
+
+        s->vtfd = safe_close(s->vtfd);
 }
 
 bool session_is_controller(Session *s, const char *sender) {
@@ -1081,8 +1103,6 @@ int session_set_controller(Session *s, const char *sender, bool force) {
                 return r;
         }
 
-        session_swap_controller(s, t);
-
         /* When setting a session controller, we forcibly mute the VT and set
          * it into graphics-mode. Applications can override that by changing
          * VT state after calling TakeControl(). However, this serves as a good
@@ -1091,7 +1111,11 @@ int session_set_controller(Session *s, const char *sender, bool force) {
          * exits.
          * If logind crashes/restarts, we restore the controller during restart
          * or reset the VT in case it crashed/exited, too. */
-        session_mute_vt(s);
+        r = session_prepare_vt(s);
+        if (r < 0)
+                return r;
+
+        session_swap_controller(s, t);
 
         return 0;
 }
@@ -1115,10 +1139,12 @@ static const char* const session_state_table[_SESSION_STATE_MAX] = {
 DEFINE_STRING_TABLE_LOOKUP(session_state, SessionState);
 
 static const char* const session_type_table[_SESSION_TYPE_MAX] = {
+        [SESSION_UNSPECIFIED] = "unspecified",
         [SESSION_TTY] = "tty",
         [SESSION_X11] = "x11",
         [SESSION_WAYLAND] = "wayland",
-        [SESSION_UNSPECIFIED] = "unspecified",
+        [SESSION_MIR] = "mir",
+        [SESSION_WEB] = "web",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(session_type, SessionType);
index c9af5eb..9fb0188 100644 (file)
@@ -55,10 +55,14 @@ typedef enum SessionType {
         SESSION_TTY,
         SESSION_X11,
         SESSION_WAYLAND,
+        SESSION_MIR,
+        SESSION_WEB,
         _SESSION_TYPE_MAX,
         _SESSION_TYPE_INVALID = -1
 } SessionType;
 
+#define SESSION_TYPE_IS_GRAPHICAL(type) IN_SET(type, SESSION_X11, SESSION_WAYLAND, SESSION_MIR)
+
 enum KillWho {
         KILL_LEADER,
         KILL_ALL,
@@ -69,7 +73,7 @@ enum KillWho {
 struct Session {
         Manager *manager;
 
-        char *id;
+        const char *id;
         unsigned int pos;
         SessionType type;
         SessionClass class;
@@ -95,7 +99,6 @@ struct Session {
         Seat *seat;
         unsigned int vtnr;
         int vtfd;
-        sd_event_source *vt_source;
 
         pid_t leader;
         uint32_t audit_id;
@@ -169,7 +172,7 @@ SessionClass session_class_from_string(const char *s) _pure_;
 const char *kill_who_to_string(KillWho k) _const_;
 KillWho kill_who_from_string(const char *s) _pure_;
 
-void session_mute_vt(Session *s);
+int session_prepare_vt(Session *s);
 void session_restore_vt(Session *s);
 
 bool session_is_controller(Session *s, const char *sender);
index 18eea89..51793f6 100644 (file)
@@ -220,7 +220,7 @@ const sd_bus_vtable user_vtable[] = {
         SD_BUS_PROPERTY("RuntimePath", "s", NULL, offsetof(User, runtime_path), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("Service", "s", NULL, offsetof(User, service), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("Slice", "s", NULL, offsetof(User, slice), SD_BUS_VTABLE_PROPERTY_CONST),
-        SD_BUS_PROPERTY("Display", "(so)", property_get_display, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("Display", "(so)", property_get_display, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         SD_BUS_PROPERTY("State", "s", property_get_state, 0, 0),
         SD_BUS_PROPERTY("Sessions", "a(so)", property_get_sessions, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
@@ -250,7 +250,7 @@ int user_object_find(sd_bus *bus, const char *path, const char *interface, void
                 sd_bus_message *message;
                 pid_t pid;
 
-                message = sd_bus_get_current(bus);
+                message = sd_bus_get_current_message(bus);
                 if (!message)
                         return 0;
 
@@ -291,7 +291,7 @@ char *user_bus_path(User *u) {
 
         assert(u);
 
-        if (asprintf(&s, "/org/freedesktop/login1/user/_%llu", (unsigned long long) u->uid) < 0)
+        if (asprintf(&s, "/org/freedesktop/login1/user/_"UID_FMT, u->uid) < 0)
                 return NULL;
 
         return s;
@@ -315,11 +315,9 @@ int user_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***
                 if (!p)
                         return -ENOMEM;
 
-                r = strv_push(&l, p);
-                if (r < 0) {
-                        free(p);
+                r = strv_consume(&l, p);
+                if (r < 0)
                         return r;
-                }
         }
 
         *nodes = l;
index 4af0e90..d48eca4 100644 (file)
@@ -19,6 +19,7 @@
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
+#include <sys/mount.h>
 #include <string.h>
 #include <unistd.h>
 #include <errno.h>
 #include "hashmap.h"
 #include "strv.h"
 #include "fileio.h"
+#include "path-util.h"
 #include "special.h"
 #include "unit-name.h"
 #include "bus-util.h"
 #include "bus-error.h"
+#include "conf-parser.h"
+#include "clean-ipc.h"
 #include "logind-user.h"
 
 User* user_new(Manager *m, uid_t uid, gid_t gid, const char *name) {
@@ -48,7 +52,7 @@ User* user_new(Manager *m, uid_t uid, gid_t gid, const char *name) {
         if (!u->name)
                 goto fail;
 
-        if (asprintf(&u->state_file, "/run/systemd/users/%lu", (unsigned long) uid) < 0)
+        if (asprintf(&u->state_file, "/run/systemd/users/"UID_FMT, uid) < 0)
                 goto fail;
 
         if (hashmap_put(m->users, ULONG_TO_PTR((unsigned long) uid), u) < 0)
@@ -311,21 +315,35 @@ static int user_mkdir_runtime_path(User *u) {
         }
 
         if (!u->runtime_path) {
-                if (asprintf(&p, "/run/user/%lu", (unsigned long) u->uid) < 0)
+                if (asprintf(&p, "/run/user/" UID_FMT, u->uid) < 0)
                         return log_oom();
         } else
                 p = u->runtime_path;
 
-        r = mkdir_safe_label(p, 0700, u->uid, u->gid);
-        if (r < 0) {
-                log_error("Failed to create runtime directory %s: %s", p, strerror(-r));
-                free(p);
-                u->runtime_path = NULL;
-                return r;
+        if (path_is_mount_point(p, false) <= 0) {
+                _cleanup_free_ char *t = NULL;
+
+                mkdir(p, 0700);
+
+                if (asprintf(&t, "mode=0700,uid=" UID_FMT ",gid=" GID_FMT ",size=%zu", u->uid, u->gid, u->manager->runtime_dir_size) < 0) {
+                        r = log_oom();
+                        goto fail;
+                }
+
+                r = mount("tmpfs", p, "tmpfs", MS_NODEV|MS_NOSUID, t);
+                if (r < 0) {
+                        log_error("Failed to mount per-user tmpfs directory %s: %s", p, strerror(-r));
+                        goto fail;
+                }
         }
 
         u->runtime_path = p;
         return 0;
+
+fail:
+        free(p);
+        u->runtime_path = NULL;
+        return r;
 }
 
 static int user_start_slice(User *u) {
@@ -336,8 +354,8 @@ static int user_start_slice(User *u) {
 
         if (!u->slice) {
                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
-                char lu[DECIMAL_STR_MAX(unsigned long) + 1], *slice;
-                sprintf(lu, "%lu", (unsigned long) u->uid);
+                char lu[DECIMAL_STR_MAX(uid_t) + 1], *slice;
+                sprintf(lu, UID_FMT, u->uid);
 
                 r = build_subslice(SPECIAL_USER_SLICE, lu, &slice);
                 if (r < 0)
@@ -369,8 +387,8 @@ static int user_start_service(User *u) {
         assert(u);
 
         if (!u->service) {
-                char lu[DECIMAL_STR_MAX(unsigned long) + 1], *service;
-                sprintf(lu, "%lu", (unsigned long) u->uid);
+                char lu[DECIMAL_STR_MAX(uid_t) + 1], *service;
+                sprintf(lu, UID_FMT, u->uid);
 
                 service = unit_name_build("user", lu, ".service");
                 if (!service)
@@ -484,6 +502,13 @@ static int user_remove_runtime_path(User *u) {
         if (!u->runtime_path)
                 return 0;
 
+        r = rm_rf(u->runtime_path, false, false, false);
+        if (r < 0)
+                log_error("Failed to remove runtime directory %s: %s", u->runtime_path, strerror(-r));
+
+        if (umount2(u->runtime_path, MNT_DETACH) < 0)
+                log_error("Failed to unmount user runtime directory %s: %m", u->runtime_path);
+
         r = rm_rf(u->runtime_path, false, true, false);
         if (r < 0)
                 log_error("Failed to remove runtime directory %s: %s", u->runtime_path, strerror(-r));
@@ -548,6 +573,13 @@ int user_finalize(User *u) {
         if (k < 0)
                 r = k;
 
+        /* Clean SysV + POSIX IPC objects */
+        if (u->manager->remove_ipc) {
+                k = clean_ipc(u->uid);
+                if (k < 0)
+                        r = k;
+        }
+
         unlink(u->state_file);
         user_add_to_gc_queue(u);
 
@@ -681,6 +713,56 @@ int user_kill(User *u, int signo) {
         return manager_kill_unit(u->manager, u->slice, KILL_ALL, signo, NULL);
 }
 
+void user_elect_display(User *u) {
+        Session *graphical = NULL, *text = NULL, *other = NULL, *s;
+
+        assert(u);
+
+        /* This elects a primary session for each user, which we call
+         * the "display". We try to keep the assignment stable, but we
+         * "upgrade" to better choices. */
+
+        LIST_FOREACH(sessions_by_user, s, u->sessions) {
+
+                if (s->class != SESSION_USER)
+                        continue;
+
+                if (s->stopping)
+                        continue;
+
+                if (SESSION_TYPE_IS_GRAPHICAL(s->type))
+                        graphical = s;
+                else if (s->type == SESSION_TTY)
+                        text = s;
+                else
+                        other = s;
+        }
+
+        if (graphical &&
+            (!u->display ||
+             u->display->class != SESSION_USER ||
+             u->display->stopping ||
+             !SESSION_TYPE_IS_GRAPHICAL(u->display->type))) {
+                u->display = graphical;
+                return;
+        }
+
+        if (text &&
+            (!u->display ||
+             u->display->class != SESSION_USER ||
+             u->display->stopping ||
+             u->display->type != SESSION_TTY)) {
+                u->display = text;
+                return;
+        }
+
+        if (other &&
+            (!u->display ||
+             u->display->class != SESSION_USER ||
+             u->display->stopping))
+                u->display = other;
+}
+
 static const char* const user_state_table[_USER_STATE_MAX] = {
         [USER_OFFLINE] = "offline",
         [USER_OPENING] = "opening",
@@ -691,3 +773,57 @@ static const char* const user_state_table[_USER_STATE_MAX] = {
 };
 
 DEFINE_STRING_TABLE_LOOKUP(user_state, UserState);
+
+int config_parse_tmpfs_size(
+                const char* unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        size_t *sz = data;
+        const char *e;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        e = endswith(rvalue, "%");
+        if (e) {
+                unsigned long ul;
+                char *f;
+
+                errno = 0;
+                ul = strtoul(rvalue, &f, 10);
+                if (errno != 0 || f != e) {
+                        log_syntax(unit, LOG_ERR, filename, line, errno ? errno : EINVAL, "Failed to parse percentage value, ignoring: %s", rvalue);
+                        return 0;
+                }
+
+                if (ul <= 0 || ul >= 100) {
+                        log_syntax(unit, LOG_ERR, filename, line, errno ? errno : EINVAL, "Percentage value out of range, ignoring: %s", rvalue);
+                        return 0;
+                }
+
+                *sz = PAGE_ALIGN((size_t) ((physical_memory() * (uint64_t) ul) / (uint64_t) 100));
+        } else {
+                off_t o;
+
+                r = parse_size(rvalue, 1024, &o);
+                if (r < 0 || (off_t) (size_t) o != o) {
+                        log_syntax(unit, LOG_ERR, filename, line, r < 0 ? -r : ERANGE, "Failed to parse size value, ignoring: %s", rvalue);
+                        return 0;
+                }
+
+                *sz = PAGE_ALIGN((size_t) o);
+        }
+
+        return 0;
+}
index f237d2a..4e0568f 100644 (file)
@@ -80,6 +80,7 @@ int user_save(User *u);
 int user_load(User *u);
 int user_kill(User *u, int signo);
 int user_check_linger_file(User *u);
+void user_elect_display(User *u);
 
 extern const sd_bus_vtable user_vtable[];
 int user_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error);
index 3a514bb..006c56a 100644 (file)
@@ -49,6 +49,7 @@ Manager *manager_new(void) {
 
         m->n_autovts = 6;
         m->reserve_vt = 6;
+        m->remove_ipc = true;
         m->inhibit_delay_max = 5 * USEC_PER_SEC;
         m->handle_power_key = HANDLE_POWEROFF;
         m->handle_suspend_key = HANDLE_SUSPEND;
@@ -60,6 +61,8 @@ Manager *manager_new(void) {
         m->idle_action = HANDLE_IGNORE;
         m->idle_action_not_before_usec = now(CLOCK_MONOTONIC);
 
+        m->runtime_dir_size = PAGE_ALIGN((size_t) (physical_memory() / 10)); /* 10% */
+
         m->devices = hashmap_new(string_hash_func, string_compare_func);
         m->seats = hashmap_new(string_hash_func, string_compare_func);
         m->sessions = hashmap_new(string_hash_func, string_compare_func);
@@ -144,9 +147,9 @@ void manager_free(Manager *m) {
         sd_event_source_unref(m->udev_device_event_source);
         sd_event_source_unref(m->udev_vcsa_event_source);
         sd_event_source_unref(m->udev_button_event_source);
+        sd_event_source_unref(m->lid_switch_ignore_event_source);
 
-        if (m->console_active_fd >= 0)
-                close_nointr_nofail(m->console_active_fd);
+        safe_close(m->console_active_fd);
 
         if (m->udev_seat_monitor)
                 udev_monitor_unref(m->udev_seat_monitor);
@@ -160,13 +163,12 @@ void manager_free(Manager *m) {
         if (m->udev)
                 udev_unref(m->udev);
 
-        bus_verify_polkit_async_registry_free(m->bus, m->polkit_registry);
+        bus_verify_polkit_async_registry_free(m->polkit_registry);
 
         sd_bus_unref(m->bus);
         sd_event_unref(m->event);
 
-        if (m->reserve_vt_fd >= 0)
-                close_nointr_nofail(m->reserve_vt_fd);
+        safe_close(m->reserve_vt_fd);
 
         strv_free(m->kill_only_users);
         strv_free(m->kill_exclude_users);
@@ -584,49 +586,50 @@ static int manager_connect_bus(Manager *m) {
                 return r;
         }
 
-        r = sd_bus_add_object_vtable(m->bus, "/org/freedesktop/login1", "org.freedesktop.login1.Manager", manager_vtable, m);
+        r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/login1", "org.freedesktop.login1.Manager", manager_vtable, m);
         if (r < 0) {
                 log_error("Failed to add manager object vtable: %s", strerror(-r));
                 return r;
         }
 
-        r = sd_bus_add_fallback_vtable(m->bus, "/org/freedesktop/login1/seat", "org.freedesktop.login1.Seat", seat_vtable, seat_object_find, m);
+        r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/login1/seat", "org.freedesktop.login1.Seat", seat_vtable, seat_object_find, m);
         if (r < 0) {
                 log_error("Failed to add seat object vtable: %s", strerror(-r));
                 return r;
         }
 
-        r = sd_bus_add_node_enumerator(m->bus, "/org/freedesktop/login1/seat", seat_node_enumerator, m);
+        r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/login1/seat", seat_node_enumerator, m);
         if (r < 0) {
                 log_error("Failed to add seat enumerator: %s", strerror(-r));
                 return r;
         }
 
-        r = sd_bus_add_fallback_vtable(m->bus, "/org/freedesktop/login1/session", "org.freedesktop.login1.Session", session_vtable, session_object_find, m);
+        r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/login1/session", "org.freedesktop.login1.Session", session_vtable, session_object_find, m);
         if (r < 0) {
                 log_error("Failed to add session object vtable: %s", strerror(-r));
                 return r;
         }
 
-        r = sd_bus_add_node_enumerator(m->bus, "/org/freedesktop/login1/session", session_node_enumerator, m);
+        r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/login1/session", session_node_enumerator, m);
         if (r < 0) {
                 log_error("Failed to add session enumerator: %s", strerror(-r));
                 return r;
         }
 
-        r = sd_bus_add_fallback_vtable(m->bus, "/org/freedesktop/login1/user", "org.freedesktop.login1.User", user_vtable, user_object_find, m);
+        r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/login1/user", "org.freedesktop.login1.User", user_vtable, user_object_find, m);
         if (r < 0) {
                 log_error("Failed to add user object vtable: %s", strerror(-r));
                 return r;
         }
 
-        r = sd_bus_add_node_enumerator(m->bus, "/org/freedesktop/login1/user", user_node_enumerator, m);
+        r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/login1/user", user_node_enumerator, m);
         if (r < 0) {
                 log_error("Failed to add user enumerator: %s", strerror(-r));
                 return r;
         }
 
         r = sd_bus_add_match(m->bus,
+                             NULL,
                              "type='signal',"
                              "sender='org.freedesktop.DBus',"
                              "interface='org.freedesktop.DBus',"
@@ -639,6 +642,7 @@ static int manager_connect_bus(Manager *m) {
         }
 
         r = sd_bus_add_match(m->bus,
+                             NULL,
                              "type='signal',"
                              "sender='org.freedesktop.systemd1',"
                              "interface='org.freedesktop.systemd1.Manager',"
@@ -651,6 +655,7 @@ static int manager_connect_bus(Manager *m) {
         }
 
         r = sd_bus_add_match(m->bus,
+                             NULL,
                              "type='signal',"
                              "sender='org.freedesktop.systemd1',"
                              "interface='org.freedesktop.systemd1.Manager',"
@@ -663,6 +668,7 @@ static int manager_connect_bus(Manager *m) {
         }
 
         r = sd_bus_add_match(m->bus,
+                             NULL,
                              "type='signal',"
                              "sender='org.freedesktop.systemd1',"
                              "interface='org.freedesktop.DBus.Properties',"
@@ -674,6 +680,7 @@ static int manager_connect_bus(Manager *m) {
         }
 
         r = sd_bus_add_match(m->bus,
+                             NULL,
                              "type='signal',"
                              "sender='org.freedesktop.systemd1',"
                              "interface='org.freedesktop.systemd1.Manager',"
@@ -713,6 +720,47 @@ static int manager_connect_bus(Manager *m) {
         return 0;
 }
 
+static int manager_vt_switch(sd_event_source *src, const struct signalfd_siginfo *si, void *data) {
+        Manager *m = data;
+        Session *active, *iter;
+
+        /*
+         * We got a VT-switch signal and we have to acknowledge it immediately.
+         * Preferably, we'd just use m->seat0->active->vtfd, but unfortunately,
+         * old user-space might run multiple sessions on a single VT, *sigh*.
+         * Therefore, we have to iterate all sessions and find one with a vtfd
+         * on the requested VT.
+         * As only VTs with active controllers have VT_PROCESS set, our current
+         * notion of the active VT might be wrong (for instance if the switch
+         * happens while we setup VT_PROCESS). Therefore, read the current VT
+         * first and then use s->active->vtnr as reference. Note that this is
+         * not racy, as no further VT-switch can happen as long as we're in
+         * synchronous VT_PROCESS mode.
+         */
+
+        assert(m->seat0);
+        seat_read_active_vt(m->seat0);
+
+        active = m->seat0->active;
+        if (!active || active->vtnr < 1) {
+                log_warning("Received VT_PROCESS signal without a registered session on that VT.");
+                return 0;
+        }
+
+        if (active->vtfd >= 0) {
+                ioctl(active->vtfd, VT_RELDISP, 1);
+        } else {
+                LIST_FOREACH(sessions_by_seat, iter, m->seat0->sessions) {
+                        if (iter->vtnr == active->vtnr && iter->vtfd >= 0) {
+                                ioctl(iter->vtfd, VT_RELDISP, 1);
+                                break;
+                        }
+                }
+        }
+
+        return 0;
+}
+
 static int manager_connect_console(Manager *m) {
         int r;
 
@@ -743,6 +791,34 @@ static int manager_connect_console(Manager *m) {
                 return r;
         }
 
+        /*
+         * SIGRTMIN is used as global VT-release signal, SIGRTMIN + 1 is used
+         * as VT-acquire signal. We ignore any acquire-events (yes, we still
+         * have to provide a valid signal-number for it!) and acknowledge all
+         * release events immediately.
+         */
+
+        if (SIGRTMIN + 1 > SIGRTMAX) {
+                log_error("Not enough real-time signals available: %u-%u", SIGRTMIN, SIGRTMAX);
+                return -EINVAL;
+        }
+
+        r = ignore_signals(SIGRTMIN + 1, -1);
+        if (r < 0) {
+                log_error("Cannot ignore SIGRTMIN + 1: %s", strerror(-r));
+                return r;
+        }
+
+        r = sigprocmask_many(SIG_BLOCK, SIGRTMIN, -1);
+        if (r < 0) {
+                log_error("Cannot block SIGRTMIN: %s", strerror(-r));
+                return r;
+        }
+
+        r = sd_event_add_signal(m->event, NULL, SIGRTMIN, manager_vt_switch, m);
+        if (r < 0)
+                return r;
+
         return 0;
 }
 
@@ -931,7 +1007,12 @@ static int manager_dispatch_idle_action(sd_event_source *s, uint64_t t, void *us
 
         if (!m->idle_action_event_source) {
 
-                r = sd_event_add_monotonic(m->event, &m->idle_action_event_source, elapse, USEC_PER_SEC*30, manager_dispatch_idle_action, m);
+                r = sd_event_add_time(
+                                m->event,
+                                &m->idle_action_event_source,
+                                CLOCK_MONOTONIC,
+                                elapse, USEC_PER_SEC*30,
+                                manager_dispatch_idle_action, m);
                 if (r < 0) {
                         log_error("Failed to add idle event source: %s", strerror(-r));
                         return r;
@@ -994,6 +1075,10 @@ int manager_startup(Manager *m) {
                 return r;
         }
 
+        r = manager_set_lid_switch_ignore(m, 0 + IGNORE_LID_SWITCH_STARTUP_USEC);
+        if (r < 0)
+                log_warning("Failed to set up lid switch ignore event source: %s", strerror(-r));
+
         /* Deserialize state */
         r = manager_enumerate_devices(m);
         if (r < 0)
@@ -1078,32 +1163,15 @@ int manager_run(Manager *m) {
                 if (r < 0)
                         return r;
         }
-
-        return 0;
 }
 
 static int manager_parse_config_file(Manager *m) {
-        static const char fn[] = "/etc/systemd/logind.conf";
-        _cleanup_fclose_ FILE *f = NULL;
-        int r;
-
         assert(m);
 
-        f = fopen(fn, "re");
-        if (!f) {
-                if (errno == ENOENT)
-                        return 0;
-
-                log_warning("Failed to open configuration file %s: %m", fn);
-                return -errno;
-        }
-
-        r = config_parse(NULL, fn, f, "Login\0", config_item_perf_lookup,
-                         (void*) logind_gperf_lookup, false, false, m);
-        if (r < 0)
-                log_warning("Failed to parse configuration file: %s", strerror(-r));
-
-        return r;
+        return config_parse(NULL, "/etc/systemd/logind.conf", NULL,
+                            "Login\0",
+                            config_item_perf_lookup, logind_gperf_lookup,
+                            false, false, true, m);
 }
 
 int main(int argc, char *argv[]) {
@@ -1146,7 +1214,7 @@ int main(int argc, char *argv[]) {
                 goto finish;
         }
 
-        log_debug("systemd-logind running as pid %lu", (unsigned long) getpid());
+        log_debug("systemd-logind running as pid "PID_FMT, getpid());
 
         sd_notify(false,
                   "READY=1\n"
@@ -1154,7 +1222,7 @@ int main(int argc, char *argv[]) {
 
         r = manager_run(m);
 
-        log_debug("systemd-logind stopped as pid %lu", (unsigned long) getpid());
+        log_debug("systemd-logind stopped as pid "PID_FMT, getpid());
 
 finish:
         sd_notify(false,
index c0abf01..79f96ec 100644 (file)
@@ -24,3 +24,5 @@
 #LidSwitchIgnoreInhibited=yes
 #IdleAction=ignore
 #IdleActionSec=30min
+#RuntimeDirectorySize=10%
+#RemoveIPC=yes
index 0344acc..31353ef 100644 (file)
@@ -42,6 +42,9 @@ typedef struct Manager Manager;
 #include "logind-button.h"
 #include "logind-action.h"
 
+#define IGNORE_LID_SWITCH_STARTUP_USEC (3 * USEC_PER_MINUTE)
+#define IGNORE_LID_SWITCH_SUSPEND_USEC (30 * USEC_PER_SEC)
+
 struct Manager {
         sd_event *event;
         sd_bus *bus;
@@ -117,7 +120,13 @@ struct Manager {
         bool hibernate_key_ignore_inhibited;
         bool lid_switch_ignore_inhibited;
 
+        bool remove_ipc;
+
         Hashmap *polkit_registry;
+
+        sd_event_source *lid_switch_ignore_event_source;
+
+        size_t runtime_dir_size;
 };
 
 Manager *manager_new(void);
@@ -149,6 +158,7 @@ int manager_get_user_by_pid(Manager *m, pid_t pid, User **user);
 int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session);
 
 bool manager_is_docked(Manager *m);
+int manager_count_displays(Manager *m);
 
 extern const sd_bus_vtable manager_vtable[];
 
@@ -177,3 +187,7 @@ const struct ConfigPerfItem* logind_gperf_lookup(const char *key, unsigned lengt
 
 int manager_watch_busname(Manager *manager, const char *name);
 void manager_drop_busname(Manager *manager, const char *name);
+
+int manager_set_lid_switch_ignore(Manager *m, usec_t until);
+
+int config_parse_tmpfs_size(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
index d677f61..1318328 100644 (file)
                        send_member="ActivateSession"/>
 
                 <allow send_destination="org.freedesktop.login1"
+                       send_interface="org.freedesktop.login1.Seat"
+                       send_member="SwitchTo"/>
+
+                <allow send_destination="org.freedesktop.login1"
+                       send_interface="org.freedesktop.login1.Seat"
+                       send_member="SwitchToPrevious"/>
+
+                <allow send_destination="org.freedesktop.login1"
+                       send_interface="org.freedesktop.login1.Seat"
+                       send_member="SwitchToNext"/>
+
+                <allow send_destination="org.freedesktop.login1"
                        send_interface="org.freedesktop.login1.Session"
                        send_member="Activate"/>
 
index b96d32d..b8e90f1 100644 (file)
                 <defaults>
                         <allow_any>auth_admin_keep</allow_any>
                         <allow_inactive>auth_admin_keep</allow_inactive>
-                        <allow_active>auth_admin_keep</allow_active>
+                        <allow_active>yes</allow_active>
                 </defaults>
                 <annotate key="org.freedesktop.policykit.imply">org.freedesktop.login1.hibernate</annotate>
         </action>
similarity index 97%
rename from src/login/pam-module.c
rename to src/login/pam_systemd.c
index 195d4d5..0c71177 100644 (file)
@@ -184,7 +184,7 @@ static int export_legacy_dbus_address(
                 return PAM_SUCCESS;
 
         if (asprintf(&s, KERNEL_USER_BUS_FMT ";" UNIX_USER_BUS_FMT,
-                     (unsigned long) uid, runtime) < 0) {
+                     uid, runtime) < 0) {
                 pam_syslog(handle, LOG_ERR, "Failed to set bus variable.");
                 return PAM_BUF_ERR;
         }
@@ -213,7 +213,7 @@ _public_ PAM_EXTERN int pam_sm_open_session(
                 *seat = NULL,
                 *type = NULL, *class = NULL,
                 *class_pam = NULL, *type_pam = NULL, *cvtnr = NULL, *desktop = NULL;
-        _cleanup_bus_unref_ sd_bus *bus = NULL;
+        _cleanup_bus_close_unref_ sd_bus *bus = NULL;
         int session_fd = -1, existing, r;
         bool debug = false, remote;
         struct passwd *pw;
@@ -252,7 +252,7 @@ _public_ PAM_EXTERN int pam_sm_open_session(
         if (streq_ptr(service, "systemd-user")) {
                 _cleanup_free_ char *p = NULL, *rt = NULL;
 
-                if (asprintf(&p, "/run/systemd/users/%lu", (unsigned long) pw->pw_uid) < 0)
+                if (asprintf(&p, "/run/systemd/users/"UID_FMT, pw->pw_uid) < 0)
                         return PAM_BUF_ERR;
 
                 r = parse_env_file(p, NEWLINE,
@@ -357,9 +357,7 @@ _public_ PAM_EXTERN int pam_sm_open_session(
         if (isempty(class))
                 class = streq(type, "unspecified") ? "background" : "user";
 
-        remote = !isempty(remote_host) &&
-                !streq_ptr(remote_host, "localhost") &&
-                !streq_ptr(remote_host, "localhost.localdomain");
+        remote = !isempty(remote_host) && !is_localhost(remote_host);
 
         /* Talk to logind over the message bus */
 
@@ -475,7 +473,7 @@ _public_ PAM_EXTERN int pam_sm_open_session(
         }
 
         if (session_fd >= 0) {
-                session_fd = dup(session_fd);
+                session_fd = fcntl(session_fd, F_DUPFD_CLOEXEC, 3);
                 if (session_fd < 0) {
                         pam_syslog(handle, LOG_ERR, "Failed to dup session fd: %m");
                         return PAM_SESSION_ERR;
@@ -484,7 +482,7 @@ _public_ PAM_EXTERN int pam_sm_open_session(
                 r = pam_set_data(handle, "systemd.session-fd", INT_TO_PTR(session_fd+1), NULL);
                 if (r != PAM_SUCCESS) {
                         pam_syslog(handle, LOG_ERR, "Failed to install session fd.");
-                        close_nointr_nofail(session_fd);
+                        safe_close(session_fd);
                         return r;
                 }
         }
@@ -498,7 +496,7 @@ _public_ PAM_EXTERN int pam_sm_close_session(
                 int argc, const char **argv) {
 
         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
-        _cleanup_bus_unref_ sd_bus *bus = NULL;
+        _cleanup_bus_close_unref_ sd_bus *bus = NULL;
         const void *existing = NULL;
         const char *id;
         int r;
diff --git a/src/login/pam_systemd.sym b/src/login/pam_systemd.sym
new file mode 100644 (file)
index 0000000..23ff75f
--- /dev/null
@@ -0,0 +1,15 @@
+/***
+  This file is part of systemd.
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+***/
+
+{
+global:
+        pam_sm_close_session;
+        pam_sm_open_session;
+local: *;
+};
index 939bd61..9bd9152 100644 (file)
@@ -121,13 +121,13 @@ static int show_sysfs_one(
                 if (!k)
                         return -ENOMEM;
 
-                printf("%s%s%s\n", prefix, lookahead ? draw_special_char(DRAW_TREE_VERT) : "  ", k);
+                printf("%s%s%s\n", prefix, lookahead ? draw_special_char(DRAW_TREE_VERTICAL) : "  ", k);
 
                 *item = next;
                 if (*item) {
                         _cleanup_free_ char *p = NULL;
 
-                        p = strappend(prefix, lookahead ? draw_special_char(DRAW_TREE_VERT) : "  ");
+                        p = strappend(prefix, lookahead ? draw_special_char(DRAW_TREE_VERTICAL) : "  ");
                         if (!p)
                                 return -ENOMEM;
 
index 7b57dbf..8112d74 100644 (file)
@@ -1,8 +1,6 @@
-#%PAM-1.0
+# This file is part of systemd.
+#
+# Used by systemd --user instances.
 
-# Used by systemd when launching systemd user instances.
-
-account include system-auth
-session include system-auth
-auth required pam_deny.so
-password required pam_deny.so
+account  include system-auth
+session  include system-auth
index 70b8314..21d2339 100644 (file)
@@ -73,8 +73,8 @@ static void print_inhibitors(sd_bus *bus) {
         assert(r >= 0);
 
         while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
-                printf("what=<%s> who=<%s> why=<%s> mode=<%s> uid=<%lu> pid=<%lu>\n",
-                       what, who, why, mode, (unsigned long) uid, (unsigned long) pid);
+                printf("what=<%s> who=<%s> why=<%s> mode=<%s> uid=<"UID_FMT"> pid=<"PID_FMT">\n",
+                       what, who, why, mode, uid, pid);
 
                 n++;
         }
@@ -101,11 +101,11 @@ int main(int argc, char*argv[]) {
         assert(fd2 >= 0);
         print_inhibitors(bus);
 
-        close_nointr_nofail(fd1);
+        safe_close(fd1);
         sleep(1);
         print_inhibitors(bus);
 
-        close_nointr_nofail(fd2);
+        safe_close(fd2);
         sleep(1);
         print_inhibitors(bus);
 
index 84af925..85bbfc4 100644 (file)
 #include "log.h"
 #include "build.h"
 
-static int help(void) {
+static const char *arg_root = "";
 
+static void help(void) {
         printf("%s [OPTIONS...]\n\n"
                "Initialize /etc/machine-id from a random source.\n\n"
                "  -h --help             Show this help\n"
-               "     --version          Show package version\n",
+               "     --version          Show package version\n"
+               "     --root=ROOT        Filesystem root\n",
                program_invocation_short_name);
-
-        return 0;
 }
 
 static int parse_argv(int argc, char *argv[]) {
 
         enum {
-                ARG_VERSION = 0x100
+                ARG_VERSION = 0x100,
+                ARG_ROOT,
         };
 
         static const struct option options[] = {
                 { "help",      no_argument,       NULL, 'h'           },
                 { "version",   no_argument,       NULL, ARG_VERSION   },
+                { "root",      required_argument, NULL, ARG_ROOT      },
                 {}
         };
 
@@ -57,28 +59,32 @@ static int parse_argv(int argc, char *argv[]) {
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "hqcv", options, NULL)) >= 0) {
+        while ((c = getopt_long(argc, argv, "hqcv", options, NULL)) >= 0)
 
                 switch (c) {
 
                 case 'h':
-                        return help();
+                        help();
+                        return 0;
 
                 case ARG_VERSION:
                         puts(PACKAGE_STRING);
                         puts(SYSTEMD_FEATURES);
                         return 0;
 
+                case ARG_ROOT:
+                        arg_root = optarg;
+                        break;
+
                 case '?':
                         return -EINVAL;
 
                 default:
                         assert_not_reached("Unhandled option");
                 }
-        }
 
         if (optind < argc) {
-                help();
+                log_error("Extraneous arguments");
                 return -EINVAL;
         }
 
@@ -95,5 +101,5 @@ int main(int argc, char *argv[]) {
         if (r <= 0)
                 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
 
-        return machine_id_setup() < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+        return machine_id_setup(arg_root) < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
 }
index df96ccf..f12ce98 100644 (file)
 #include <errno.h>
 #include <string.h>
 #include <sys/capability.h>
+#include <arpa/inet.h>
 
 #include "bus-util.h"
+#include "bus-label.h"
 #include "strv.h"
+#include "bus-errors.h"
+#include "copy.h"
+#include "fileio.h"
+#include "in-addr-util.h"
+#include "local-addresses.h"
 #include "machine.h"
 
 static int property_get_id(
@@ -76,9 +83,34 @@ static int property_get_state(
         return 1;
 }
 
+static int property_get_netif(
+                sd_bus *bus,
+                const char *path,
+                const char *interface,
+                const char *property,
+                sd_bus_message *reply,
+                void *userdata,
+                sd_bus_error *error) {
+
+        Machine *m = userdata;
+        int r;
+
+        assert(bus);
+        assert(reply);
+        assert(m);
+
+        assert_cc(sizeof(int) == sizeof(int32_t));
+
+        r = sd_bus_message_append_array(reply, 'i', m->netif, m->n_netif * sizeof(int));
+        if (r < 0)
+                return r;
+
+        return 1;
+}
+
 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_class, machine_class, MachineClass);
 
-static int method_terminate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
+int bus_machine_method_terminate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
         Machine *m = userdata;
         int r;
 
@@ -93,7 +125,7 @@ static int method_terminate(sd_bus *bus, sd_bus_message *message, void *userdata
         return sd_bus_reply_method_return(message, NULL);
 }
 
-static int method_kill(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
+int bus_machine_method_kill(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
         Machine *m = userdata;
         const char *swho;
         int32_t signo;
@@ -126,6 +158,238 @@ static int method_kill(sd_bus *bus, sd_bus_message *message, void *userdata, sd_
         return sd_bus_reply_method_return(message, NULL);
 }
 
+int bus_machine_method_get_addresses(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
+        _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
+        _cleanup_close_pair_ int pair[2] = { -1, -1 };
+        _cleanup_free_ char *us = NULL, *them = NULL;
+        _cleanup_close_ int netns_fd = -1;
+        Machine *m = userdata;
+        const char *p;
+        siginfo_t si;
+        pid_t child;
+        int r;
+
+        assert(bus);
+        assert(message);
+        assert(m);
+
+        r = readlink_malloc("/proc/self/ns/net", &us);
+        if (r < 0)
+                return sd_bus_error_set_errno(error, r);
+
+        p = procfs_file_alloca(m->leader, "ns/net");
+        r = readlink_malloc(p, &them);
+        if (r < 0)
+                return sd_bus_error_set_errno(error, r);
+
+        if (streq(us, them))
+                return sd_bus_error_setf(error, BUS_ERROR_NO_PRIVATE_NETWORKING, "Machine %s does not use private networking", m->name);
+
+        r = namespace_open(m->leader, NULL, NULL, &netns_fd, NULL);
+        if (r < 0)
+                return sd_bus_error_set_errno(error, r);
+
+        if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, pair) < 0)
+                return sd_bus_error_set_errno(error, -errno);
+
+        child = fork();
+        if (child < 0)
+                return sd_bus_error_set_errno(error, -errno);
+
+        if (child == 0) {
+                _cleanup_free_ struct local_address *addresses = NULL;
+                struct local_address *a;
+                int i, n;
+
+                pair[0] = safe_close(pair[0]);
+
+                r = namespace_enter(-1, -1, netns_fd, -1);
+                if (r < 0)
+                        _exit(EXIT_FAILURE);
+
+                n = local_addresses(NULL, 0, &addresses);
+                if (n < 0)
+                        _exit(EXIT_FAILURE);
+
+                for (a = addresses, i = 0; i < n; a++, i++) {
+                        struct iovec iov[2] = {
+                                { .iov_base = &a->family, .iov_len = sizeof(a->family) },
+                                { .iov_base = &a->address, .iov_len = FAMILY_ADDRESS_SIZE(a->family) },
+                        };
+
+                        r = writev(pair[1], iov, 2);
+                        if (r < 0)
+                                _exit(EXIT_FAILURE);
+                }
+
+                pair[1] = safe_close(pair[1]);
+
+                _exit(EXIT_SUCCESS);
+        }
+
+        pair[1] = safe_close(pair[1]);
+
+        r = sd_bus_message_new_method_return(message, &reply);
+        if (r < 0)
+                return sd_bus_error_set_errno(error, r);
+
+        r = sd_bus_message_open_container(reply, 'a', "(iay)");
+        if (r < 0)
+                return sd_bus_error_set_errno(error, r);
+
+        for (;;) {
+                int family;
+                ssize_t n;
+                union in_addr_union in_addr;
+                struct iovec iov[2];
+                struct msghdr mh = {
+                        .msg_iov = iov,
+                        .msg_iovlen = 2,
+                };
+
+                iov[0] = (struct iovec) { .iov_base = &family, .iov_len = sizeof(family) };
+                iov[1] = (struct iovec) { .iov_base = &in_addr, .iov_len = sizeof(in_addr) };
+
+                n = recvmsg(pair[0], &mh, 0);
+                if (n < 0)
+                        return sd_bus_error_set_errno(error, -errno);
+                if ((size_t) n < sizeof(family))
+                        break;
+
+                r = sd_bus_message_open_container(reply, 'r', "iay");
+                if (r < 0)
+                        return sd_bus_error_set_errno(error, r);
+
+                r = sd_bus_message_append(reply, "i", family);
+                if (r < 0)
+                        return sd_bus_error_set_errno(error, r);
+
+                switch (family) {
+
+                case AF_INET:
+                        if (n != sizeof(struct in_addr) + sizeof(family))
+                                return sd_bus_error_set_errno(error, EIO);
+
+                        r = sd_bus_message_append_array(reply, 'y', &in_addr.in, sizeof(in_addr.in));
+                        break;
+
+                case AF_INET6:
+                        if (n != sizeof(struct in6_addr) + sizeof(family))
+                                return sd_bus_error_set_errno(error, EIO);
+
+                        r = sd_bus_message_append_array(reply, 'y', &in_addr.in6, sizeof(in_addr.in6));
+                        break;
+                }
+                if (r < 0)
+                        return sd_bus_error_set_errno(error, r);
+
+                r = sd_bus_message_close_container(reply);
+                if (r < 0)
+                        return sd_bus_error_set_errno(error, r);
+        }
+
+        r = wait_for_terminate(child, &si);
+        if (r < 0)
+                return sd_bus_error_set_errno(error, r);
+        if (si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS)
+                return sd_bus_error_set_errno(error, EIO);
+
+        r = sd_bus_message_close_container(reply);
+        if (r < 0)
+                return sd_bus_error_set_errno(error, r);
+
+        return sd_bus_send(bus, reply, NULL);
+}
+
+int bus_machine_method_get_os_release(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
+        _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
+        _cleanup_close_ int mntns_fd = -1, root_fd = -1;
+        _cleanup_close_pair_ int pair[2] = { -1, -1 };
+        _cleanup_strv_free_ char **l = NULL;
+        _cleanup_fclose_ FILE *f = NULL;
+        Machine *m = userdata;
+        char **k, **v;
+        siginfo_t si;
+        pid_t child;
+        int r;
+
+        assert(bus);
+        assert(message);
+        assert(m);
+
+        r = namespace_open(m->leader, NULL, &mntns_fd, NULL, &root_fd);
+        if (r < 0)
+                return sd_bus_error_set_errno(error, r);
+
+        if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, pair) < 0)
+                return sd_bus_error_set_errno(error, -errno);
+
+        child = fork();
+        if (child < 0)
+                return sd_bus_error_set_errno(error, -errno);
+
+        if (child == 0) {
+                _cleanup_close_ int fd = -1;
+
+                pair[0] = safe_close(pair[0]);
+
+                r = namespace_enter(-1, mntns_fd, -1, root_fd);
+                if (r < 0)
+                        _exit(EXIT_FAILURE);
+
+                fd = open("/etc/os-release", O_RDONLY|O_CLOEXEC);
+                if (fd < 0) {
+                        fd = open("/usr/lib/os-release", O_RDONLY|O_CLOEXEC);
+                        if (fd < 0)
+                                _exit(EXIT_FAILURE);
+                }
+
+                r = copy_bytes(fd, pair[1], (off_t) -1);
+                if (r < 0)
+                        _exit(EXIT_FAILURE);
+
+                _exit(EXIT_SUCCESS);
+        }
+
+        pair[1] = safe_close(pair[1]);
+
+        f = fdopen(pair[0], "re");
+        if (!f)
+                return sd_bus_error_set_errno(error, -errno);
+
+        pair[0] = -1;
+
+        r = load_env_file_pairs(f, "/etc/os-release", NULL, &l);
+        if (r < 0)
+                return sd_bus_error_set_errno(error, r);
+
+        r = wait_for_terminate(child, &si);
+        if (r < 0)
+                return sd_bus_error_set_errno(error, r);
+        if (si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS)
+                return sd_bus_error_set_errno(error, EIO);
+
+        r = sd_bus_message_new_method_return(message, &reply);
+        if (r < 0)
+                return sd_bus_error_set_errno(error, r);
+
+        r = sd_bus_message_open_container(reply, 'a', "{ss}");
+        if (r < 0)
+                return sd_bus_error_set_errno(error, r);
+
+        STRV_FOREACH_PAIR(k, v, l) {
+                r = sd_bus_message_append(reply, "{ss}", *k, *v);
+                if (r < 0)
+                        return sd_bus_error_set_errno(error, r);
+        }
+
+        r = sd_bus_message_close_container(reply);
+        if (r < 0)
+                return sd_bus_error_set_errno(error, r);
+
+        return sd_bus_send(bus, reply, NULL);
+}
+
 const sd_bus_vtable machine_vtable[] = {
         SD_BUS_VTABLE_START(0),
         SD_BUS_PROPERTY("Name", "s", NULL, offsetof(Machine, name), SD_BUS_VTABLE_PROPERTY_CONST),
@@ -137,9 +401,12 @@ const sd_bus_vtable machine_vtable[] = {
         SD_BUS_PROPERTY("Leader", "u", NULL, offsetof(Machine, leader), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("Class", "s", property_get_class, offsetof(Machine, class), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("RootDirectory", "s", NULL, offsetof(Machine, root_directory), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("NetworkInterfaces", "ai", property_get_netif, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("State", "s", property_get_state, 0, 0),
-        SD_BUS_METHOD("Terminate", NULL, NULL, method_terminate, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
-        SD_BUS_METHOD("Kill", "si", NULL, method_kill, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
+        SD_BUS_METHOD("Terminate", NULL, NULL, bus_machine_method_terminate, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
+        SD_BUS_METHOD("Kill", "si", NULL, bus_machine_method_kill, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
+        SD_BUS_METHOD("GetAddresses", NULL, "a(iay)", bus_machine_method_get_addresses, SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("GetOSRelease", NULL, "a{ss}", bus_machine_method_get_os_release, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_VTABLE_END
 };
 
@@ -159,7 +426,7 @@ int machine_object_find(sd_bus *bus, const char *path, const char *interface, vo
                 sd_bus_message *message;
                 pid_t pid;
 
-                message = sd_bus_get_current(bus);
+                message = sd_bus_get_current_message(bus);
                 if (!message)
                         return 0;
 
@@ -182,7 +449,7 @@ int machine_object_find(sd_bus *bus, const char *path, const char *interface, vo
                 if (!p)
                         return 0;
 
-                e = sd_bus_label_unescape(p);
+                e = bus_label_unescape(p);
                 if (!e)
                         return -ENOMEM;
 
@@ -200,7 +467,7 @@ char *machine_bus_path(Machine *m) {
 
         assert(m);
 
-        e = sd_bus_label_escape(m->name);
+        e = bus_label_escape(m->name);
         if (!e)
                 return NULL;
 
@@ -225,11 +492,9 @@ int machine_node_enumerator(sd_bus *bus, const char *path, void *userdata, char
                 if (!p)
                         return -ENOMEM;
 
-                r = strv_push(&l, p);
-                if (r < 0) {
-                        free(p);
+                r = strv_consume(&l, p);
+                if (r < 0)
                         return r;
-                }
         }
 
         *nodes = l;
index 4596a80..13d3448 100644 (file)
@@ -94,6 +94,7 @@ void machine_free(Machine *m) {
         free(m->state_file);
         free(m->service);
         free(m->root_directory);
+        free(m->netif);
         free(m);
 }
 
@@ -123,17 +124,42 @@ int machine_save(Machine *m) {
                 "NAME=%s\n",
                 m->name);
 
-        if (m->unit)
-                fprintf(f, "SCOPE=%s\n", m->unit); /* We continue to call this "SCOPE=" because it is internal only, and we want to stay compatible with old files */
+        if (m->unit) {
+                _cleanup_free_ char *escaped;
+
+                escaped = cescape(m->unit);
+                if (!escaped) {
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                fprintf(f, "SCOPE=%s\n", escaped); /* We continue to call this "SCOPE=" because it is internal only, and we want to stay compatible with old files */
+        }
 
         if (m->scope_job)
                 fprintf(f, "SCOPE_JOB=%s\n", m->scope_job);
 
-        if (m->service)
-                fprintf(f, "SERVICE=%s\n", m->service);
+        if (m->service) {
+                _cleanup_free_ char *escaped;
 
-        if (m->root_directory)
-                fprintf(f, "ROOT=%s\n", m->root_directory);
+                escaped = cescape(m->service);
+                if (!escaped) {
+                        r = -ENOMEM;
+                        goto finish;
+                }
+                fprintf(f, "SERVICE=%s\n", escaped);
+        }
+
+        if (m->root_directory) {
+                _cleanup_free_ char *escaped;
+
+                escaped = cescape(m->root_directory);
+                if (!escaped) {
+                        r = -ENOMEM;
+                        goto finish;
+                }
+                fprintf(f, "ROOT=%s\n", escaped);
+        }
 
         if (!sd_id128_equal(m->id, SD_ID128_NULL))
                 fprintf(f, "ID=" SD_ID128_FORMAT_STR "\n", SD_ID128_FORMAT_VAL(m->id));
@@ -151,12 +177,28 @@ int machine_save(Machine *m) {
                         m->timestamp.realtime,
                         m->timestamp.monotonic);
 
-        fflush(f);
+        if (m->n_netif > 0) {
+                unsigned i;
 
-        if (ferror(f) || rename(temp_path, m->state_file) < 0) {
+                fputs("NETIF=", f);
+
+                for (i = 0; i < m->n_netif; i++) {
+                        if (i != 0)
+                                fputc(' ', f);
+
+                        fprintf(f, "%i", m->netif[i]);
+                }
+
+                fputc('\n', f);
+        }
+
+        r = fflush_and_check(f);
+        if (r < 0)
+                goto finish;
+
+        if (rename(temp_path, m->state_file) < 0) {
                 r = -errno;
-                unlink(m->state_file);
-                unlink(temp_path);
+                goto finish;
         }
 
         if (m->unit) {
@@ -170,8 +212,12 @@ int machine_save(Machine *m) {
         }
 
 finish:
-        if (r < 0)
+        if (r < 0) {
+                if (temp_path)
+                        unlink(temp_path);
+
                 log_error("Failed to save machine data %s: %s", m->state_file, strerror(-r));
+        }
 
         return r;
 }
@@ -192,7 +238,7 @@ static void machine_unlink(Machine *m) {
 }
 
 int machine_load(Machine *m) {
-        _cleanup_free_ char *realtime = NULL, *monotonic = NULL, *id = NULL, *leader = NULL, *class = NULL;
+        _cleanup_free_ char *realtime = NULL, *monotonic = NULL, *id = NULL, *leader = NULL, *class = NULL, *netif = NULL;
         int r;
 
         assert(m);
@@ -207,6 +253,7 @@ int machine_load(Machine *m) {
                            "CLASS",     &class,
                            "REALTIME",  &realtime,
                            "MONOTONIC", &monotonic,
+                           "NETIF",     &netif,
                            NULL);
         if (r < 0) {
                 if (r == -ENOENT)
@@ -242,6 +289,35 @@ int machine_load(Machine *m) {
                         m->timestamp.monotonic = l;
         }
 
+        if (netif) {
+                size_t l, allocated = 0, nr = 0;
+                const char *word, *state;
+                int *ni = NULL;
+
+                FOREACH_WORD(word, l, netif, state) {
+                        char buf[l+1];
+                        int ifi;
+
+                        *(char*) (mempcpy(buf, word, l)) = 0;
+
+                        if (safe_atoi(buf, &ifi) < 0)
+                                continue;
+                        if (ifi <= 0)
+                                continue;
+
+                        if (!GREEDY_REALLOC(ni, allocated, nr+1)) {
+                                free(ni);
+                                return log_oom();
+                        }
+
+                        ni[nr++] = ifi;
+                }
+
+                free(m->netif);
+                m->netif = ni;
+                m->n_netif = nr;
+        }
+
         return r;
 }
 
@@ -303,7 +379,7 @@ int machine_start(Machine *m, sd_bus_message *properties, sd_bus_error *error) {
         log_struct(LOG_INFO,
                    MESSAGE_ID(SD_MESSAGE_MACHINE_START),
                    "NAME=%s", m->name,
-                   "LEADER=%lu", (unsigned long) m->leader,
+                   "LEADER="PID_FMT, m->leader,
                    "MESSAGE=New machine %s.", m->name,
                    NULL);
 
@@ -330,16 +406,18 @@ static int machine_stop_scope(Machine *m) {
         if (!m->unit)
                 return 0;
 
-        r = manager_stop_unit(m->manager, m->unit, &error, &job);
-        if (r < 0) {
-                log_error("Failed to stop machine scope: %s", bus_error_message(&error, r));
-                return r;
+        if (!m->registered) {
+                r = manager_stop_unit(m->manager, m->unit, &error, &job);
+                if (r < 0) {
+                        log_error("Failed to stop machine scope: %s", bus_error_message(&error, r));
+                        return r;
+                }
         }
 
         free(m->scope_job);
         m->scope_job = job;
 
-        return r;
+        return 0;
 }
 
 int machine_stop(Machine *m) {
@@ -350,7 +428,7 @@ int machine_stop(Machine *m) {
                 log_struct(LOG_INFO,
                            MESSAGE_ID(SD_MESSAGE_MACHINE_STOP),
                            "NAME=%s", m->name,
-                           "LEADER=%lu", (unsigned long) m->leader,
+                           "LEADER="PID_FMT, m->leader,
                            "MESSAGE=Machine %s terminated.", m->name,
                            NULL);
 
@@ -410,7 +488,17 @@ int machine_kill(Machine *m, KillWho who, int signo) {
         if (!m->unit)
                 return -ESRCH;
 
-        return manager_kill_unit(m->manager, m->unit, who, signo, NULL);
+        if (who == KILL_LEADER) {
+                /* If we shall simply kill the leader, do so directly */
+
+                if (kill(m->leader, signo) < 0)
+                        return -errno;
+
+                return 0;
+        }
+
+        /* Otherwise make PID 1 do it for us, for the entire cgroup */
+        return manager_kill_unit(m->manager, m->unit, signo, NULL);
 }
 
 static const char* const machine_class_table[_MACHINE_CLASS_MAX] = {
index f4aefc5..5c63665 100644 (file)
@@ -72,9 +72,13 @@ struct Machine {
 
         bool in_gc_queue:1;
         bool started:1;
+        bool registered:1;
 
         sd_bus_message *create_message;
 
+        int *netif;
+        unsigned n_netif;
+
         LIST_FIELDS(Machine, gc_queue);
 };
 
@@ -96,6 +100,11 @@ char *machine_bus_path(Machine *s);
 int machine_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error);
 int machine_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error);
 
+int bus_machine_method_terminate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error);
+int bus_machine_method_kill(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error);
+int bus_machine_method_get_addresses(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error);
+int bus_machine_method_get_os_release(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error);
+
 int machine_send_signal(Machine *m, bool new_machine);
 int machine_send_create_reply(Machine *m, sd_bus_error *error);
 
index 32f862d..7491d69 100644 (file)
@@ -27,6 +27,9 @@
 #include <pwd.h>
 #include <locale.h>
 #include <fcntl.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <net/if.h>
 
 #include "sd-bus.h"
 #include "log.h"
@@ -165,6 +168,109 @@ static int show_unit_cgroup(sd_bus *bus, const char *unit, pid_t leader) {
         return 0;
 }
 
+static int print_addresses(sd_bus *bus, const char *name, int ifi, const char *prefix, const char *prefix2) {
+        _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
+        int r;
+
+        assert(bus);
+        assert(name);
+        assert(prefix);
+        assert(prefix2);
+
+        r = sd_bus_call_method(bus,
+                               "org.freedesktop.machine1",
+                               "/org/freedesktop/machine1",
+                               "org.freedesktop.machine1.Manager",
+                               "GetMachineAddresses",
+                               NULL,
+                               &reply,
+                               "s", name);
+        if (r < 0)
+                return r;
+
+        r = sd_bus_message_enter_container(reply, 'a', "(iay)");
+        if (r < 0)
+                return bus_log_parse_error(r);
+
+        while ((r = sd_bus_message_enter_container(reply, 'r', "iay")) > 0) {
+                int family;
+                const void *a;
+                size_t sz;
+                char buffer[MAX(INET6_ADDRSTRLEN, INET_ADDRSTRLEN)];
+
+                r = sd_bus_message_read(reply, "i", &family);
+                if (r < 0)
+                        return bus_log_parse_error(r);
+
+                r = sd_bus_message_read_array(reply, 'y', &a, &sz);
+                if (r < 0)
+                        return bus_log_parse_error(r);
+
+                fputs(prefix, stdout);
+                fputs(inet_ntop(family, a, buffer, sizeof(buffer)), stdout);
+                if (family == AF_INET6 && ifi > 0)
+                        printf("%%%i", ifi);
+                fputc('\n', stdout);
+
+                r = sd_bus_message_exit_container(reply);
+                if (r < 0)
+                        return bus_log_parse_error(r);
+
+                if (prefix != prefix2)
+                        prefix = prefix2;
+        }
+        if (r < 0)
+                return bus_log_parse_error(r);
+
+        r = sd_bus_message_exit_container(reply);
+        if (r < 0)
+                return bus_log_parse_error(r);
+
+        return 0;
+}
+
+static int print_os_release(sd_bus *bus, const char *name, const char *prefix) {
+        _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
+        const char *k, *v, *pretty = NULL;
+        int r;
+
+        assert(bus);
+        assert(name);
+        assert(prefix);
+
+        r = sd_bus_call_method(bus,
+                               "org.freedesktop.machine1",
+                               "/org/freedesktop/machine1",
+                               "org.freedesktop.machine1.Manager",
+                               "GetMachineOSRelease",
+                               NULL,
+                               &reply,
+                               "s", name);
+        if (r < 0)
+                return r;
+
+        r = sd_bus_message_enter_container(reply, 'a', "{ss}");
+        if (r < 0)
+                return bus_log_parse_error(r);
+
+        while ((r = sd_bus_message_read(reply, "{ss}", &k, &v)) > 0) {
+                if (streq(k, "PRETTY_NAME"))
+                        pretty = v;
+
+        }
+        if (r < 0)
+                return bus_log_parse_error(r);
+
+        r = sd_bus_message_exit_container(reply);
+        if (r < 0)
+                return bus_log_parse_error(r);
+
+        if (pretty)
+                printf("%s%s\n", prefix, pretty);
+
+        return 0;
+}
+
 typedef struct MachineStatusInfo {
         char *name;
         sd_id128_t id;
@@ -174,11 +280,15 @@ typedef struct MachineStatusInfo {
         char *root_directory;
         pid_t leader;
         usec_t timestamp;
+        int *netif;
+        unsigned n_netif;
 } MachineStatusInfo;
 
 static void print_machine_status_info(sd_bus *bus, MachineStatusInfo *i) {
         char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
         char since2[FORMAT_TIMESTAMP_MAX], *s2;
+        int ifi = -1;
+
         assert(i);
 
         fputs(strna(i->name), stdout);
@@ -221,23 +331,74 @@ static void print_machine_status_info(sd_bus *bus, MachineStatusInfo *i) {
         if (i->root_directory)
                 printf("\t    Root: %s\n", i->root_directory);
 
+        if (i->n_netif > 0) {
+                unsigned c;
+
+                fputs("\t   Iface:", stdout);
+
+                for (c = 0; c < i->n_netif; c++) {
+                        char name[IF_NAMESIZE+1] = "";
+
+                        if (if_indextoname(i->netif[c], name)) {
+                                fputc(' ', stdout);
+                                fputs(name, stdout);
+
+                                if (ifi < 0)
+                                        ifi = i->netif[c];
+                                else
+                                        ifi = 0;
+                        } else
+                                printf(" %i", i->netif[c]);
+                }
+
+                fputc('\n', stdout);
+        }
+
+        print_addresses(bus, i->name, ifi,
+                       "\t Address: ",
+                       "\t          ");
+
+        print_os_release(bus, i->name, "\t      OS: ");
+
         if (i->unit) {
                 printf("\t    Unit: %s\n", i->unit);
                 show_unit_cgroup(bus, i->unit, i->leader);
         }
 }
 
+static int map_netif(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
+        MachineStatusInfo *i = userdata;
+        size_t l;
+        const void *v;
+        int r;
+
+        assert_cc(sizeof(int32_t) == sizeof(int));
+        r = sd_bus_message_read_array(m, SD_BUS_TYPE_INT32, &v, &l);
+        if (r < 0)
+                return r;
+        if (r == 0)
+                return -EBADMSG;
+
+        i->n_netif = l / sizeof(int32_t);
+        i->netif = memdup(v, l);
+        if (!i->netif)
+                return -ENOMEM;
+
+        return 0;
+}
+
 static int show_info(const char *verb, sd_bus *bus, const char *path, bool *new_line) {
 
         static const struct bus_properties_map map[]  = {
-                { "Name",          "s",  NULL,          offsetof(MachineStatusInfo, name) },
-                { "Class",         "s",  NULL,          offsetof(MachineStatusInfo, class) },
-                { "Service",       "s",  NULL,          offsetof(MachineStatusInfo, service) },
-                { "Unit",          "s",  NULL,          offsetof(MachineStatusInfo, unit) },
-                { "RootDirectory", "s",  NULL,          offsetof(MachineStatusInfo, root_directory) },
-                { "Leader",        "u",  NULL,          offsetof(MachineStatusInfo, leader) },
-                { "Timestamp",     "t",  NULL,          offsetof(MachineStatusInfo, timestamp) },
-                { "Id",            "ay", bus_map_id128, offsetof(MachineStatusInfo, id) },
+                { "Name",              "s",  NULL,          offsetof(MachineStatusInfo, name) },
+                { "Class",             "s",  NULL,          offsetof(MachineStatusInfo, class) },
+                { "Service",           "s",  NULL,          offsetof(MachineStatusInfo, service) },
+                { "Unit",              "s",  NULL,          offsetof(MachineStatusInfo, unit) },
+                { "RootDirectory",     "s",  NULL,          offsetof(MachineStatusInfo, root_directory) },
+                { "Leader",            "u",  NULL,          offsetof(MachineStatusInfo, leader) },
+                { "Timestamp",         "t",  NULL,          offsetof(MachineStatusInfo, timestamp) },
+                { "Id",                "ay", bus_map_id128, offsetof(MachineStatusInfo, id) },
+                { "NetworkInterfaces", "ai", map_netif,     0 },
                 {}
         };
 
@@ -268,6 +429,7 @@ static int show_info(const char *verb, sd_bus *bus, const char *path, bool *new_
         free(info.service);
         free(info.unit);
         free(info.root_directory);
+        free(info.netif);
 
         return r;
 }
@@ -370,98 +532,49 @@ static int kill_machine(sd_bus *bus, char **args, unsigned n) {
         return 0;
 }
 
-static int terminate_machine(sd_bus *bus, char **args, unsigned n) {
-        _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
-        unsigned i;
-
-        assert(args);
+static int reboot_machine(sd_bus *bus, char **args, unsigned n) {
+        arg_kill_who = "leader";
+        arg_signal = SIGINT; /* sysvinit + systemd */
 
-        for (i = 1; i < n; i++) {
-                int r;
+        return kill_machine(bus, args, n);
+}
 
-                r = sd_bus_call_method(
-                                bus,
-                                "org.freedesktop.machine1",
-                                "/org/freedesktop/machine1",
-                                "org.freedesktop.machine1.Manager",
-                                "TerminateMachine",
-                                &error,
-                                NULL,
-                                "s", args[i]);
-                if (r < 0) {
-                        log_error("Could not terminate machine: %s", bus_error_message(&error, -r));
-                        return r;
-                }
-        }
+static int poweroff_machine(sd_bus *bus, char **args, unsigned n) {
+        arg_kill_who = "leader";
+        arg_signal = SIGRTMIN+4; /* only systemd */
 
-        return 0;
+        return kill_machine(bus, args, n);
 }
 
-static int reboot_machine(sd_bus *bus, char **args, unsigned n) {
+static int terminate_machine(sd_bus *bus, char **args, unsigned n) {
         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
         unsigned i;
-        int r;
 
         assert(args);
 
-        if (arg_transport != BUS_TRANSPORT_LOCAL) {
-                log_error("Reboot only supported on local machines.");
-                return -ENOTSUP;
-        }
-
         for (i = 1; i < n; i++) {
-                _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *reply2 = NULL;
-                const char *path;
-                uint32_t leader;
+                int r;
 
                 r = sd_bus_call_method(
                                 bus,
                                 "org.freedesktop.machine1",
                                 "/org/freedesktop/machine1",
                                 "org.freedesktop.machine1.Manager",
-                                "GetMachine",
+                                "TerminateMachine",
                                 &error,
-                                &reply,
+                                NULL,
                                 "s", args[i]);
-
-                if (r < 0) {
-                        log_error("Could not get path to machine: %s", bus_error_message(&error, -r));
-                        return r;
-                }
-
-                r = sd_bus_message_read(reply, "o", &path);
-                if (r < 0)
-                        return bus_log_parse_error(r);
-
-                r = sd_bus_get_property(
-                                bus,
-                                "org.freedesktop.machine1",
-                                path,
-                                "org.freedesktop.machine1.Machine",
-                                "Leader",
-                                &error,
-                                &reply2,
-                                "u");
                 if (r < 0) {
-                        log_error("Failed to retrieve PID of leader: %s", strerror(-r));
+                        log_error("Could not terminate machine: %s", bus_error_message(&error, -r));
                         return r;
                 }
-
-                r = sd_bus_message_read(reply2, "u", &leader);
-                if (r < 0)
-                        return bus_log_parse_error(r);
-
-                if (kill(leader, SIGINT) < 0) {
-                        log_error("Failed to kill init process " PID_FMT ": %m", (pid_t) leader);
-                        return -errno;
-                }
         }
 
         return 0;
 }
 
 static int openpt_in_namespace(pid_t pid, int flags) {
-        _cleanup_close_pipe_ int pair[2] = { -1, -1 };
+        _cleanup_close_pair_ int pair[2] = { -1, -1 };
         _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, rootfd = -1;
         union {
                 struct cmsghdr cmsghdr;
@@ -476,7 +589,7 @@ static int openpt_in_namespace(pid_t pid, int flags) {
         pid_t child;
         siginfo_t si;
 
-        r = namespace_open(pid, &pidnsfd, &mntnsfd, &rootfd);
+        r = namespace_open(pid, &pidnsfd, &mntnsfd, NULL, &rootfd);
         if (r < 0)
                 return r;
 
@@ -488,10 +601,9 @@ static int openpt_in_namespace(pid_t pid, int flags) {
                 return -errno;
 
         if (child == 0) {
-                close_nointr_nofail(pair[0]);
-                pair[0] = -1;
+                pair[0] = safe_close(pair[0]);
 
-                r = namespace_enter(pidnsfd, mntnsfd, rootfd);
+                r = namespace_enter(pidnsfd, mntnsfd, -1, rootfd);
                 if (r < 0)
                         _exit(EXIT_FAILURE);
 
@@ -513,14 +625,13 @@ static int openpt_in_namespace(pid_t pid, int flags) {
                 _exit(EXIT_SUCCESS);
         }
 
-        close_nointr_nofail(pair[1]);
-        pair[1] = -1;
+        pair[1] = safe_close(pair[1]);
 
         r = wait_for_terminate(child, &si);
-        if (r < 0 || si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS) {
-
-                return r < 0 ? r : -EIO;
-        }
+        if (r < 0)
+                return r;
+        if (si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS)
+                return -EIO;
 
         if (recvmsg(pair[0], &mh, MSG_NOSIGNAL|MSG_CMSG_CLOEXEC) < 0)
                 return -errno;
@@ -550,7 +661,7 @@ static int openpt_in_namespace(pid_t pid, int flags) {
 static int login_machine(sd_bus *bus, char **args, unsigned n) {
         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *reply2 = NULL, *reply3 = NULL;
         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
-        _cleanup_bus_unref_ sd_bus *container_bus = NULL;
+        _cleanup_bus_close_unref_ sd_bus *container_bus = NULL;
         _cleanup_close_ int master = -1;
         _cleanup_free_ char *getty = NULL;
         const char *path, *pty, *p;
@@ -668,8 +779,7 @@ static int login_machine(sd_bus *bus, char **args, unsigned n) {
         return 0;
 }
 
-static int help(void) {
-
+static void help(void) {
         printf("%s [OPTIONS...] {COMMAND} ...\n\n"
                "Send control commands to or query the virtual machine and container registration manager.\n\n"
                "  -h --help              Show this help\n"
@@ -687,13 +797,12 @@ static int help(void) {
                "  list                   List running VMs and containers\n"
                "  status NAME...         Show VM/container status\n"
                "  show NAME...           Show properties of one or more VMs/containers\n"
-               "  terminate NAME...      Terminate one or more VMs/containers\n"
-               "  kill NAME...           Send signal to processes of a VM/container\n"
+               "  login NAME             Get a login prompt on a container\n"
+               "  poweroff NAME...       Power off one or more containers\n"
                "  reboot NAME...         Reboot one or more containers\n"
-               "  login NAME             Get a login prompt on a container\n",
+               "  kill NAME...           Send signal to processes of a VM/container\n"
+               "  terminate NAME...      Terminate one or more VMs/containers\n",
                program_invocation_short_name);
-
-        return 0;
 }
 
 static int parse_argv(int argc, char *argv[]) {
@@ -725,12 +834,13 @@ static int parse_argv(int argc, char *argv[]) {
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "hp:als:H:M:", options, NULL)) >= 0) {
+        while ((c = getopt_long(argc, argv, "hp:als:H:M:", options, NULL)) >= 0)
 
                 switch (c) {
 
                 case 'h':
-                        return help();
+                        help();
+                        return 0;
 
                 case ARG_VERSION:
                         puts(PACKAGE_STRING);
@@ -792,7 +902,6 @@ static int parse_argv(int argc, char *argv[]) {
                 default:
                         assert_not_reached("Unhandled option");
                 }
-        }
 
         return 1;
 }
@@ -814,6 +923,7 @@ static int machinectl_main(sd_bus *bus, int argc, char *argv[]) {
                 { "show",                  MORE,   1, show              },
                 { "terminate",             MORE,   2, terminate_machine },
                 { "reboot",                MORE,   2, reboot_machine    },
+                { "poweroff",              MORE,   2, poweroff_machine  },
                 { "kill",                  MORE,   2, kill_machine      },
                 { "login",                 MORE,   2, login_machine     },
         };
@@ -879,7 +989,7 @@ static int machinectl_main(sd_bus *bus, int argc, char *argv[]) {
 }
 
 int main(int argc, char*argv[]) {
-        _cleanup_bus_unref_ sd_bus *bus = NULL;
+        _cleanup_bus_close_unref_ sd_bus *bus = NULL;
         int r;
 
         setlocale(LC_ALL, "");
index 09d28bb..3c7d4be 100644 (file)
@@ -27,7 +27,6 @@
 
 #include "sd-id128.h"
 #include "sd-messages.h"
-
 #include "strv.h"
 #include "mkdir.h"
 #include "path-util.h"
 #include "cgroup-util.h"
 #include "machined.h"
 
-static bool valid_machine_name(const char *p) {
-        size_t l;
-
-        if (!filename_is_safe(p))
-                return false;
-
-        if (!ascii_is_valid(p))
-                return false;
-
-        l = strlen(p);
-
-        if (l < 1 || l> 64)
-                return false;
-
-        return true;
-}
-
 static int method_get_machine(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
         _cleanup_free_ char *p = NULL;
         Manager *m = userdata;
@@ -118,7 +100,7 @@ static int method_get_machine_by_pid(sd_bus *bus, sd_bus_message *message, void
         if (r < 0)
                 return r;
         if (!machine)
-                return sd_bus_error_setf(error, BUS_ERROR_NO_MACHINE_FOR_PID, "PID %lu does not belong to any known machine", (unsigned long) pid);
+                return sd_bus_error_setf(error, BUS_ERROR_NO_MACHINE_FOR_PID, "PID "PID_FMT" does not belong to any known machine", pid);
 
         p = machine_bus_path(machine);
         if (!p)
@@ -169,14 +151,15 @@ static int method_list_machines(sd_bus *bus, sd_bus_message *message, void *user
         return sd_bus_send(bus, reply, NULL);
 }
 
-static int method_create_or_register_machine(Manager *manager, sd_bus_message *message, Machine **_m, sd_bus_error *error) {
+static int method_create_or_register_machine(Manager *manager, sd_bus_message *message, bool read_network, Machine **_m, sd_bus_error *error) {
         const char *name, *service, *class, *root_directory;
+        const int32_t *netif = NULL;
         MachineClass c;
         uint32_t leader;
         sd_id128_t id;
         const void *v;
         Machine *m;
-        size_t n;
+        size_t n, n_netif = 0;
         int r;
 
         assert(manager);
@@ -186,7 +169,7 @@ static int method_create_or_register_machine(Manager *manager, sd_bus_message *m
         r = sd_bus_message_read(message, "s", &name);
         if (r < 0)
                 return r;
-        if (!valid_machine_name(name))
+        if (!machine_name_is_valid(name))
                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid machine name");
 
         r = sd_bus_message_read_array(message, 'y', &v, &n);
@@ -203,6 +186,21 @@ static int method_create_or_register_machine(Manager *manager, sd_bus_message *m
         if (r < 0)
                 return r;
 
+        if (read_network) {
+                size_t i;
+
+                r = sd_bus_message_read_array(message, 'i', (const void**) &netif, &n_netif);
+                if (r < 0)
+                        return r;
+
+                n_netif /= sizeof(int32_t);
+
+                for (i = 0; i < n_netif; i++) {
+                        if (netif[i] <= 0)
+                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid network interface index %i", netif[i]);
+                }
+        }
+
         if (isempty(class))
                 c = _MACHINE_CLASS_INVALID;
         else {
@@ -258,6 +256,17 @@ static int method_create_or_register_machine(Manager *manager, sd_bus_message *m
                 }
         }
 
+        if (n_netif > 0) {
+                assert_cc(sizeof(int32_t) == sizeof(int));
+                m->netif = memdup(netif, sizeof(int32_t) * n_netif);
+                if (!m->netif) {
+                        r = -ENOMEM;
+                        goto fail;
+                }
+
+                m->n_netif = n_netif;
+        }
+
         *_m = m;
 
         return 1;
@@ -267,12 +276,12 @@ fail:
         return r;
 }
 
-static int method_create_machine(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
+static int method_create_machine_internal(sd_bus *bus, sd_bus_message *message, bool read_network, void *userdata, sd_bus_error *error) {
         Manager *manager = userdata;
         Machine *m = NULL;
         int r;
 
-        r = method_create_or_register_machine(manager, message, &m, error);
+        r = method_create_or_register_machine(manager, message, read_network, &m, error);
         if (r < 0)
                 return r;
 
@@ -292,13 +301,21 @@ fail:
         return r;
 }
 
-static int method_register_machine(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
+static int method_create_machine_with_network(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
+        return method_create_machine_internal(bus, message, true, userdata, error);
+}
+
+static int method_create_machine(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
+        return method_create_machine_internal(bus, message, false, userdata, error);
+}
+
+static int method_register_machine_internal(sd_bus *bus, sd_bus_message *message, bool read_network, void *userdata, sd_bus_error *error) {
         Manager *manager = userdata;
         _cleanup_free_ char *p = NULL;
         Machine *m = NULL;
         int r;
 
-        r = method_create_or_register_machine(manager, message, &m, error);
+        r = method_create_or_register_machine(manager, message, read_network, &m, error);
         if (r < 0)
                 return r;
 
@@ -308,6 +325,8 @@ static int method_register_machine(sd_bus *bus, sd_bus_message *message, void *u
                 goto fail;
         }
 
+        m->registered = true;
+
         r = machine_start(m, NULL, error);
         if (r < 0)
                 goto fail;
@@ -325,6 +344,14 @@ fail:
         return r;
 }
 
+static int method_register_machine_with_network(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
+        return method_register_machine_internal(bus, message, true, userdata, error);
+}
+
+static int method_register_machine(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
+        return method_register_machine_internal(bus, message, false, userdata, error);
+}
+
 static int method_terminate_machine(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
         Manager *m = userdata;
         Machine *machine;
@@ -343,50 +370,70 @@ static int method_terminate_machine(sd_bus *bus, sd_bus_message *message, void *
         if (!machine)
                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
 
-        r = machine_stop(machine);
-        if (r < 0)
-                return sd_bus_error_set_errno(error, r);
-
-        return sd_bus_reply_method_return(message, NULL);
+        return bus_machine_method_terminate(bus, message, machine, error);
 }
 
 static int method_kill_machine(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
         Manager *m = userdata;
         Machine *machine;
         const char *name;
-        const char *swho;
-        int32_t signo;
-        KillWho who;
         int r;
 
         assert(bus);
         assert(message);
         assert(m);
 
-        r = sd_bus_message_read(message, "ssi", &name, &swho, &signo);
+        r = sd_bus_message_read(message, "s", &name);
         if (r < 0)
                 return sd_bus_error_set_errno(error, r);
 
-        if (isempty(swho))
-                who = KILL_ALL;
-        else {
-                who = kill_who_from_string(swho);
-                if (who < 0)
-                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid kill parameter '%s'", swho);
-        }
+        machine = hashmap_get(m->machines, name);
+        if (!machine)
+                return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
 
-        if (signo <= 0 || signo >= _NSIG)
-                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
+        return bus_machine_method_kill(bus, message, machine, error);
+}
+
+static int method_get_machine_addresses(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
+        Manager *m = userdata;
+        Machine *machine;
+        const char *name;
+        int r;
+
+        assert(bus);
+        assert(message);
+        assert(m);
+
+        r = sd_bus_message_read(message, "s", &name);
+        if (r < 0)
+                return sd_bus_error_set_errno(error, r);
 
         machine = hashmap_get(m->machines, name);
         if (!machine)
                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
 
-        r = machine_kill(machine, who, signo);
+        return bus_machine_method_get_addresses(bus, message, machine, error);
+}
+
+static int method_get_machine_os_release(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
+        Manager *m = userdata;
+        Machine *machine;
+        const char *name;
+        int r;
+
+        assert(bus);
+        assert(message);
+        assert(m);
+
+        r = sd_bus_message_read(message, "s", &name);
         if (r < 0)
                 return sd_bus_error_set_errno(error, r);
 
-        return sd_bus_reply_method_return(message, NULL);
+        machine = hashmap_get(m->machines, name);
+        if (!machine)
+                return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
+
+        return bus_machine_method_get_os_release(bus, message, machine, error);
 }
 
 const sd_bus_vtable manager_vtable[] = {
@@ -396,8 +443,12 @@ const sd_bus_vtable manager_vtable[] = {
         SD_BUS_METHOD("ListMachines", NULL, "a(ssso)", method_list_machines, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("CreateMachine", "sayssusa(sv)", "o", method_create_machine, 0),
         SD_BUS_METHOD("RegisterMachine", "sayssus", "o", method_register_machine, 0),
+        SD_BUS_METHOD("CreateMachineWithNetwork", "sayssusaia(sv)", "o", method_create_machine_with_network, 0),
+        SD_BUS_METHOD("RegisterMachineWithNetwork", "sayssusai", "o", method_register_machine_with_network, 0),
         SD_BUS_METHOD("KillMachine", "ssi", NULL, method_kill_machine, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
         SD_BUS_METHOD("TerminateMachine", "s", NULL, method_terminate_machine, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
+        SD_BUS_METHOD("GetMachineAddresses", "s", "a(iay)", method_get_machine_addresses, SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("GetMachineOSRelease", "s", "a{ss}", method_get_machine_os_release, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_SIGNAL("MachineNew", "so", 0),
         SD_BUS_SIGNAL("MachineRemoved", "so", 0),
         SD_BUS_VTABLE_END
@@ -655,7 +706,7 @@ int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, c
         return 1;
 }
 
-int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error) {
+int manager_kill_unit(Manager *manager, const char *unit, int signo, sd_bus_error *error) {
         assert(manager);
         assert(unit);
 
@@ -667,7 +718,7 @@ int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo
                         "KillUnit",
                         error,
                         NULL,
-                        "ssi", unit, who == KILL_LEADER ? "main" : "all", signo);
+                        "ssi", unit, "all", signo);
 }
 
 int manager_unit_is_active(Manager *manager, const char *unit) {
index 20e6f7c..6160320 100644 (file)
@@ -141,25 +141,26 @@ static int manager_connect_bus(Manager *m) {
                 return r;
         }
 
-        r = sd_bus_add_object_vtable(m->bus, "/org/freedesktop/machine1", "org.freedesktop.machine1.Manager", manager_vtable, m);
+        r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/machine1", "org.freedesktop.machine1.Manager", manager_vtable, m);
         if (r < 0) {
                 log_error("Failed to add manager object vtable: %s", strerror(-r));
                 return r;
         }
 
-        r = sd_bus_add_fallback_vtable(m->bus, "/org/freedesktop/machine1/machine", "org.freedesktop.machine1.Machine", machine_vtable, machine_object_find, m);
+        r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/machine1/machine", "org.freedesktop.machine1.Machine", machine_vtable, machine_object_find, m);
         if (r < 0) {
                 log_error("Failed to add machine object vtable: %s", strerror(-r));
                 return r;
         }
 
-        r = sd_bus_add_node_enumerator(m->bus, "/org/freedesktop/machine1/machine", machine_node_enumerator, m);
+        r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/machine1/machine", machine_node_enumerator, m);
         if (r < 0) {
                 log_error("Failed to add machine enumerator: %s", strerror(-r));
                 return r;
         }
 
         r = sd_bus_add_match(m->bus,
+                             NULL,
                              "type='signal',"
                              "sender='org.freedesktop.systemd1',"
                              "interface='org.freedesktop.systemd1.Manager',"
@@ -173,6 +174,7 @@ static int manager_connect_bus(Manager *m) {
         }
 
         r = sd_bus_add_match(m->bus,
+                             NULL,
                              "type='signal',"
                              "sender='org.freedesktop.systemd1',"
                              "interface='org.freedesktop.systemd1.Manager',"
@@ -186,6 +188,7 @@ static int manager_connect_bus(Manager *m) {
         }
 
         r = sd_bus_add_match(m->bus,
+                             NULL,
                              "type='signal',"
                              "sender='org.freedesktop.systemd1',"
                              "interface='org.freedesktop.DBus.Properties',"
@@ -198,6 +201,7 @@ static int manager_connect_bus(Manager *m) {
         }
 
         r = sd_bus_add_match(m->bus,
+                             NULL,
                              "type='signal',"
                              "sender='org.freedesktop.systemd1',"
                              "interface='org.freedesktop.systemd1.Manager',"
@@ -334,7 +338,7 @@ int main(int argc, char *argv[]) {
                 goto finish;
         }
 
-        log_debug("systemd-machined running as pid %lu", (unsigned long) getpid());
+        log_debug("systemd-machined running as pid "PID_FMT, getpid());
 
         sd_notify(false,
                   "READY=1\n"
@@ -342,7 +346,7 @@ int main(int argc, char *argv[]) {
 
         r = manager_run(m);
 
-        log_debug("systemd-machined stopped as pid %lu", (unsigned long) getpid());
+        log_debug("systemd-machined stopped as pid "PID_FMT, getpid());
 
 finish:
         sd_notify(false,
index d4b581b..2dba303 100644 (file)
@@ -67,6 +67,6 @@ int match_job_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_b
 
 int manager_start_scope(Manager *manager, const char *scope, pid_t pid, const char *slice, const char *description, sd_bus_message *more_properties, sd_bus_error *error, char **job);
 int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job);
-int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error);
+int manager_kill_unit(Manager *manager, const char *unit, int signo, sd_bus_error *error);
 int manager_unit_is_active(Manager *manager, const char *unit);
 int manager_job_is_active(Manager *manager, const char *path);
index 970ccd8..ac1aee8 100644 (file)
                        send_interface="org.freedesktop.machine1.Manager"
                        send_member="GetMachineByPID"/>
 
+                <allow send_destination="org.freedesktop.machine1"
+                       send_interface="org.freedesktop.machine1.Manager"
+                       send_member="GetMachineAddresses"/>
+
+                <allow send_destination="org.freedesktop.machine1"
+                       send_interface="org.freedesktop.machine1.Manager"
+                       send_member="GetMachineOSRelease"/>
+
+                <allow send_destination="org.freedesktop.machine1"
+                       send_interface="org.freedesktop.machine1.Machine"
+                       send_member="GetAddresses"/>
+
+                <allow send_destination="org.freedesktop.machine1"
+                       send_interface="org.freedesktop.machine1.Machine"
+                       send_member="GetOSRelease"/>
+
                 <allow receive_sender="org.freedesktop.machine1"/>
         </policy>
 
index 37d7a77..c77b092 100644 (file)
@@ -69,20 +69,13 @@ static int add_modules(const char *p) {
         return 0;
 }
 
-static int parse_proc_cmdline_word(const char *word) {
+static int parse_proc_cmdline_item(const char *key, const char *value) {
         int r;
 
-        if (startswith(word, "modules-load=")) {
-                r = add_modules(word + 13);
+        if (STR_IN_SET(key, "modules-load", "rd.modules-load") && value) {
+                r = add_modules(value);
                 if (r < 0)
                         return r;
-
-        } else if (startswith(word, "rd.modules-load=")) {
-                if (in_initrd()) {
-                        r = add_modules(word + 16);
-                        if (r < 0)
-                                return r;
-                }
         }
 
         return 0;
@@ -152,7 +145,7 @@ static int apply_file(struct kmod_ctx *ctx, const char *path, bool ignore_enoent
         assert(ctx);
         assert(path);
 
-        r = search_and_fopen_nulstr(path, "re", conf_file_dirs, &f);
+        r = search_and_fopen_nulstr(path, "re", NULL, conf_file_dirs, &f);
         if (r < 0) {
                 if (ignore_enoent && r == -ENOENT)
                         return 0;
@@ -188,15 +181,12 @@ static int apply_file(struct kmod_ctx *ctx, const char *path, bool ignore_enoent
         return r;
 }
 
-static int help(void) {
-
+static void help(void) {
         printf("%s [OPTIONS...] [CONFIGURATION FILE...]\n\n"
                "Loads statically configured kernel modules.\n\n"
                "  -h --help             Show this help\n"
                "     --version          Show package version\n",
                program_invocation_short_name);
-
-        return 0;
 }
 
 static int parse_argv(int argc, char *argv[]) {
@@ -216,12 +206,13 @@ static int parse_argv(int argc, char *argv[]) {
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) {
+        while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
 
                 switch (c) {
 
                 case 'h':
-                        return help();
+                        help();
+                        return 0;
 
                 case ARG_VERSION:
                         puts(PACKAGE_STRING);
@@ -234,7 +225,6 @@ static int parse_argv(int argc, char *argv[]) {
                 default:
                         assert_not_reached("Unhandled option");
                 }
-        }
 
         return 1;
 }
@@ -253,7 +243,7 @@ int main(int argc, char *argv[]) {
 
         umask(0022);
 
-        if (parse_proc_cmdline(parse_proc_cmdline_word) < 0)
+        if (parse_proc_cmdline(parse_proc_cmdline_item) < 0)
                 return EXIT_FAILURE;
 
         ctx = kmod_new(NULL, NULL);
diff --git a/src/network/networkctl.c b/src/network/networkctl.c
new file mode 100644 (file)
index 0000000..2a7a1da
--- /dev/null
@@ -0,0 +1,701 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdbool.h>
+#include <getopt.h>
+
+#include "sd-network.h"
+#include "sd-rtnl.h"
+#include "libudev.h"
+
+#include "build.h"
+#include "util.h"
+#include "pager.h"
+#include "rtnl-util.h"
+#include "udev-util.h"
+#include "arphrd-list.h"
+#include "local-addresses.h"
+#include "socket-util.h"
+
+static bool arg_no_pager = false;
+static bool arg_legend = true;
+static bool arg_all = false;
+
+static void pager_open_if_enabled(void) {
+
+        if (arg_no_pager)
+                return;
+
+        pager_open(false);
+}
+
+static int link_get_type_string(int iftype, struct udev_device *d, char **ret) {
+        const char *t;
+        char *p;
+
+        if (iftype == ARPHRD_ETHER && d) {
+                const char *devtype, *id = NULL;
+                /* WLANs have iftype ARPHRD_ETHER, but we want
+                 * to show a more useful type string for
+                 * them */
+
+                devtype = udev_device_get_devtype(d);
+                if (streq_ptr(devtype, "wlan"))
+                        id = "wlan";
+                else if (streq_ptr(devtype, "wwan"))
+                        id = "wwan";
+
+                if (id) {
+                        p = strdup(id);
+                        if (!p)
+                                return -ENOMEM;
+
+                        *ret = p;
+                        return 1;
+                }
+        }
+
+        t = arphrd_to_name(iftype);
+        if (!t) {
+                *ret = NULL;
+                return 0;
+        }
+
+        p = strdup(t);
+        if (!p)
+                return -ENOMEM;
+
+        ascii_strlower(p);
+        *ret = p;
+
+        return 0;
+}
+
+typedef struct LinkInfo {
+        const char *name;
+        int ifindex;
+        unsigned iftype;
+} LinkInfo;
+
+static int link_info_compare(const void *a, const void *b) {
+        const LinkInfo *x = a, *y = b;
+
+        return x->ifindex - y->ifindex;
+}
+
+static int decode_and_sort_links(sd_rtnl_message *m, LinkInfo **ret) {
+        _cleanup_free_ LinkInfo *links = NULL;
+        size_t size = 0, c = 0;
+        sd_rtnl_message *i;
+        int r;
+
+        for (i = m; i; i = sd_rtnl_message_next(i)) {
+                const char *name;
+                unsigned iftype;
+                uint16_t type;
+                int ifindex;
+
+                r = sd_rtnl_message_get_type(i, &type);
+                if (r < 0)
+                        return r;
+
+                if (type != RTM_NEWLINK)
+                        continue;
+
+                r = sd_rtnl_message_link_get_ifindex(i, &ifindex);
+                if (r < 0)
+                        return r;
+
+                r = sd_rtnl_message_read_string(i, IFLA_IFNAME, &name);
+                if (r < 0)
+                        return r;
+
+                r = sd_rtnl_message_link_get_type(i, &iftype);
+                if (r < 0)
+                        return r;
+
+                if (!GREEDY_REALLOC(links, size, c+1))
+                        return -ENOMEM;
+
+                links[c].name = name;
+                links[c].ifindex = ifindex;
+                links[c].iftype = iftype;
+                c++;
+        }
+
+        qsort_safe(links, c, sizeof(LinkInfo), link_info_compare);
+
+        *ret = links;
+        links = NULL;
+
+        return (int) c;
+}
+
+static void operational_state_to_color(const char *state, const char **on, const char **off) {
+        assert(on);
+        assert(off);
+
+        if (streq_ptr(state, "routable")) {
+                *on = ansi_highlight_green();
+                *off = ansi_highlight_off();
+        } else if (streq_ptr(state, "degraded")) {
+                *on = ansi_highlight_yellow();
+                *off = ansi_highlight_off();
+        } else
+                *on = *off = "";
+}
+
+static void setup_state_to_color(const char *state, const char **on, const char **off) {
+        assert(on);
+        assert(off);
+
+        if (streq_ptr(state, "configured")) {
+                *on = ansi_highlight_green();
+                *off = ansi_highlight_off();
+        } else if (streq_ptr(state, "configuring")) {
+                *on = ansi_highlight_yellow();
+                *off = ansi_highlight_off();
+        } else if (streq_ptr(state, "failed") || streq_ptr(state, "linger")) {
+                *on = ansi_highlight_red();
+                *off = ansi_highlight_off();
+        } else
+                *on = *off = "";
+}
+
+static int list_links(char **args, unsigned n) {
+        _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
+        _cleanup_udev_unref_ struct udev *udev = NULL;
+        _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
+        _cleanup_free_ LinkInfo *links = NULL;
+        int r, c, i;
+
+        pager_open_if_enabled();
+
+        r = sd_rtnl_open(&rtnl, 0);
+        if (r < 0) {
+                log_error("Failed to connect to netlink: %s", strerror(-r));
+                return r;
+        }
+
+        udev = udev_new();
+        if (!udev) {
+                log_error("Failed to connect to udev: %m");
+                return -errno;
+        }
+
+        r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, 0);
+        if (r < 0)
+                return rtnl_log_create_error(r);
+
+        r = sd_rtnl_message_request_dump(req, true);
+        if (r < 0)
+                return rtnl_log_create_error(r);
+
+        r = sd_rtnl_call(rtnl, req, 0, &reply);
+        if (r < 0) {
+                log_error("Failed to enumerate links: %s", strerror(-r));
+                return r;
+        }
+
+        if (arg_legend)
+                printf("%3s %-16s %-18s %-11s %-10s\n", "IDX", "LINK", "TYPE", "OPERATIONAL", "SETUP");
+
+        c = decode_and_sort_links(reply, &links);
+        if (c < 0)
+                return rtnl_log_parse_error(c);
+
+        for (i = 0; i < c; i++) {
+                _cleanup_free_ char *setup_state = NULL, *operational_state = NULL;
+                _cleanup_udev_device_unref_ struct udev_device *d = NULL;
+                const char *on_color_operational, *off_color_operational,
+                           *on_color_setup, *off_color_setup;
+                 char devid[2 + DECIMAL_STR_MAX(int)];
+                _cleanup_free_ char *t = NULL;
+
+                sd_network_link_get_operational_state(links[i].ifindex, &operational_state);
+                operational_state_to_color(operational_state, &on_color_operational, &off_color_operational);
+
+                sd_network_link_get_setup_state(links[i].ifindex, &setup_state);
+                setup_state_to_color(setup_state, &on_color_setup, &off_color_setup);
+
+                sprintf(devid, "n%i", links[i].ifindex);
+                d = udev_device_new_from_device_id(udev, devid);
+
+                link_get_type_string(links[i].iftype, d, &t);
+
+                printf("%3i %-16s %-18s %s%-11s%s %s%-10s%s\n",
+                       links[i].ifindex, links[i].name, strna(t),
+                       on_color_operational, strna(operational_state), off_color_operational,
+                       on_color_setup, strna(setup_state), off_color_setup);
+        }
+
+        if (arg_legend)
+                printf("\n%i links listed.\n", c);
+
+        return 0;
+}
+
+static int dump_addresses(sd_rtnl *rtnl, const char *prefix, int ifindex) {
+        _cleanup_free_ struct local_address *local = NULL;
+        int r, n, i;
+
+        n = local_addresses(rtnl, ifindex, &local);
+        if (n < 0)
+                return n;
+
+        for (i = 0; i < n; i++) {
+                _cleanup_free_ char *pretty = NULL;
+
+                r = in_addr_to_string(local[i].family, &local[i].address, &pretty);
+                if (r < 0)
+                        return r;
+
+                printf("%*s%s\n",
+                       (int) strlen(prefix),
+                       i == 0 ? prefix : "",
+                       pretty);
+        }
+
+        return 0;
+}
+
+static void dump_list(const char *prefix, char **l) {
+        char **i;
+
+        STRV_FOREACH(i, l) {
+                printf("%*s%s\n",
+                       (int) strlen(prefix),
+                       i == l ? prefix : "",
+                       *i);
+        }
+}
+
+static int link_status_one(sd_rtnl *rtnl, struct udev *udev, const char *name) {
+        _cleanup_strv_free_ char **dns = NULL, **ntp = NULL, **domains = NULL;
+        _cleanup_free_ char *setup_state = NULL, *operational_state = NULL;
+        _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
+        _cleanup_udev_device_unref_ struct udev_device *d = NULL;
+        char devid[2 + DECIMAL_STR_MAX(int)];
+        _cleanup_free_ char *t = NULL;
+        const char *driver = NULL, *path = NULL, *vendor = NULL, *model = NULL;
+        const char *on_color_operational, *off_color_operational,
+                   *on_color_setup, *off_color_setup;
+        struct ether_addr e;
+        unsigned iftype;
+        int r, ifindex;
+        bool have_mac;
+        uint32_t mtu;
+
+        assert(rtnl);
+        assert(udev);
+        assert(name);
+
+        if (safe_atoi(name, &ifindex) >= 0 && ifindex > 0)
+                r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, ifindex);
+        else {
+                r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, 0);
+                if (r < 0)
+                        return rtnl_log_create_error(r);
+
+                r = sd_rtnl_message_append_string(req, IFLA_IFNAME, name);
+        }
+
+        if (r < 0)
+                return rtnl_log_create_error(r);
+
+        r = sd_rtnl_call(rtnl, req, 0, &reply);
+        if (r < 0) {
+                log_error("Failed to query link: %s", strerror(-r));
+                return r;
+        }
+
+        r = sd_rtnl_message_link_get_ifindex(reply, &ifindex);
+        if (r < 0)
+                return rtnl_log_parse_error(r);
+
+        r = sd_rtnl_message_read_string(reply, IFLA_IFNAME, &name);
+        if (r < 0)
+                return rtnl_log_parse_error(r);
+
+        r = sd_rtnl_message_link_get_type(reply, &iftype);
+        if (r < 0)
+                return rtnl_log_parse_error(r);
+
+        have_mac = sd_rtnl_message_read_ether_addr(reply, IFLA_ADDRESS, &e) >= 0;
+
+        if (have_mac) {
+                const uint8_t *p;
+                bool all_zeroes = true;
+
+                for (p = (uint8_t*) &e; p < (uint8_t*) &e + sizeof(e); p++)
+                        if (*p != 0) {
+                                all_zeroes = false;
+                                break;
+                        }
+
+                if (all_zeroes)
+                        have_mac = false;
+        }
+
+        sd_rtnl_message_read_u32(reply, IFLA_MTU, &mtu);
+
+        sd_network_link_get_operational_state(ifindex, &operational_state);
+        operational_state_to_color(operational_state, &on_color_operational, &off_color_operational);
+
+        sd_network_link_get_setup_state(ifindex, &setup_state);
+        setup_state_to_color(setup_state, &on_color_setup, &off_color_setup);
+
+        sd_network_link_get_dns(ifindex, &dns);
+        sd_network_link_get_ntp(ifindex, &ntp);
+        sd_network_link_get_domains(ifindex, &domains);
+        r = sd_network_link_get_wildcard_domain(ifindex);
+        if (r > 0) {
+                char *wildcard;
+
+                wildcard = strdup("*");
+                if (!wildcard)
+                        return log_oom();
+
+                if (strv_consume(&domains, wildcard) < 0)
+                        return log_oom();
+        }
+
+        sprintf(devid, "n%i", ifindex);
+        d = udev_device_new_from_device_id(udev, devid);
+
+        link_get_type_string(iftype, d, &t);
+
+        if (d) {
+                driver = udev_device_get_property_value(d, "ID_NET_DRIVER");
+                path = udev_device_get_property_value(d, "ID_PATH");
+
+                vendor = udev_device_get_property_value(d, "ID_VENDOR_FROM_DATABASE");
+                if (!vendor)
+                        vendor = udev_device_get_property_value(d, "ID_VENDOR");
+
+                model = udev_device_get_property_value(d, "ID_MODEL_FROM_DATABASE");
+                if (!model)
+                        model = udev_device_get_property_value(d, "ID_MODEL");
+        }
+
+
+        printf("%s%s%s %i: %s\n", on_color_operational, draw_special_char(DRAW_BLACK_CIRCLE), off_color_operational, ifindex, name);
+
+        printf("        Type: %s\n"
+               "       State: %s%s%s (%s%s%s)\n",
+               strna(t),
+               on_color_operational, strna(operational_state), off_color_operational,
+               on_color_setup, strna(setup_state), off_color_setup);
+
+        if (path)
+                printf("        Path: %s\n", path);
+        if (driver)
+                printf("      Driver: %s\n", driver);
+        if (vendor)
+                printf("      Vendor: %s\n", vendor);
+        if (model)
+                printf("       Model: %s\n", model);
+
+        if (have_mac) {
+                char ea[ETHER_ADDR_TO_STRING_MAX];
+                printf("  HW Address: %s\n", ether_addr_to_string(&e, ea));
+        }
+
+        if (mtu > 0)
+                printf("         MTU: %u\n", mtu);
+
+        dump_addresses(rtnl, "     Address: ", ifindex);
+
+        if (!strv_isempty(dns))
+                dump_list("         DNS: ", dns);
+        if (!strv_isempty(domains))
+                dump_list("      Domain: ", domains);
+        if (!strv_isempty(ntp))
+                dump_list("         NTP: ", ntp);
+
+        return 0;
+}
+
+static int link_status(char **args, unsigned n) {
+        _cleanup_udev_unref_ struct udev *udev = NULL;
+        _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
+        char **name;
+        int r;
+
+        r = sd_rtnl_open(&rtnl, 0);
+        if (r < 0) {
+                log_error("Failed to connect to netlink: %s", strerror(-r));
+                return r;
+        }
+
+        udev = udev_new();
+        if (!udev) {
+                log_error("Failed to connect to udev: %m");
+                return -errno;
+        }
+
+        if (n <= 1 && !arg_all) {
+                _cleanup_free_ char *operational_state = NULL;
+                _cleanup_strv_free_ char **dns = NULL, **ntp = NULL, **domains = NULL;
+                _cleanup_free_ struct local_address *addresses = NULL;
+                const char *on_color_operational, *off_color_operational;
+                int i, c;
+
+                sd_network_get_operational_state(&operational_state);
+                operational_state_to_color(operational_state, &on_color_operational, &off_color_operational);
+
+                printf("       State: %s%s%s\n", on_color_operational, strna(operational_state), off_color_operational);
+
+                c = local_addresses(rtnl, 0, &addresses);
+                for (i = 0; i < c; i++) {
+                        _cleanup_free_ char *pretty = NULL;
+
+                        r = in_addr_to_string(addresses[i].family, &addresses[i].address, &pretty);
+                        if (r < 0)
+                                return log_oom();
+
+                        printf("%13s %s\n",
+                               i > 0 ? "" : "Address:", pretty);
+                }
+
+                sd_network_get_dns(&dns);
+                if (!strv_isempty(dns))
+                        dump_list("         DNS: ", dns);
+
+                sd_network_get_domains(&domains);
+                if (!strv_isempty(domains))
+                        dump_list("      Domain: ", domains);
+
+                sd_network_get_dns(&ntp);
+                if (!strv_isempty(ntp))
+                        dump_list("         NTP: ", ntp);
+
+                return 0;
+        }
+
+        pager_open_if_enabled();
+
+        if (arg_all) {
+                _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
+                _cleanup_free_ LinkInfo *links = NULL;
+                int c, i;
+
+                r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, 0);
+                if (r < 0)
+                        return rtnl_log_create_error(r);
+
+                r = sd_rtnl_message_request_dump(req, true);
+                if (r < 0)
+                        return rtnl_log_create_error(r);
+
+                r = sd_rtnl_call(rtnl, req, 0, &reply);
+                if (r < 0) {
+                        log_error("Failed to enumerate links: %s", strerror(-r));
+                        return r;
+                }
+
+                c = decode_and_sort_links(reply, &links);
+                if (c < 0)
+                        return rtnl_log_parse_error(c);
+
+                for (i = 0; i < c; i++) {
+                        if (i > 0)
+                                fputc('\n', stdout);
+
+                        link_status_one(rtnl, udev, links[i].name);
+                }
+        }
+
+        STRV_FOREACH(name, args + 1) {
+                if (name != args+1)
+                        fputc('\n', stdout);
+
+                link_status_one(rtnl, udev, *name);
+        }
+
+        return 0;
+}
+
+static void help(void) {
+        printf("%s [OPTIONS...]\n\n"
+               "Query and control the networking subsystem.\n\n"
+               "  -h --help             Show this help\n"
+               "     --version          Show package version\n"
+               "     --no-pager         Do not pipe output into a pager\n"
+               "     --no-legend        Do not show the headers and footers\n"
+               "  -a --all              Show status for all links\n\n"
+               "Commands:\n"
+               "  list                  List links\n"
+               "  status LINK           Show link status\n"
+               , program_invocation_short_name);
+}
+
+static int parse_argv(int argc, char *argv[]) {
+
+        enum {
+                ARG_VERSION = 0x100,
+                ARG_NO_PAGER,
+                ARG_NO_LEGEND,
+        };
+
+        static const struct option options[] = {
+                { "help",      no_argument,       NULL, 'h'           },
+                { "version",   no_argument,       NULL, ARG_VERSION   },
+                { "no-pager",  no_argument,       NULL, ARG_NO_PAGER  },
+                { "no-legend", no_argument,       NULL, ARG_NO_LEGEND },
+                { "all",       no_argument,       NULL, 'a'           },
+                {}
+        };
+
+        int c;
+
+        assert(argc >= 0);
+        assert(argv);
+
+        while ((c = getopt_long(argc, argv, "ha", options, NULL)) >= 0) {
+
+                switch (c) {
+
+                case 'h':
+                        help();
+                        return 0;
+
+                case ARG_VERSION:
+                        puts(PACKAGE_STRING);
+                        puts(SYSTEMD_FEATURES);
+                        return 0;
+
+                case ARG_NO_PAGER:
+                        arg_no_pager = true;
+                        break;
+
+                case ARG_NO_LEGEND:
+                        arg_legend = false;
+                        break;
+
+                case 'a':
+                        arg_all = true;
+                        break;
+
+                case '?':
+                        return -EINVAL;
+
+                default:
+                        assert_not_reached("Unhandled option");
+                }
+        }
+
+        return 1;
+}
+
+static int networkctl_main(int argc, char *argv[]) {
+
+        static const struct {
+                const char* verb;
+                const enum {
+                        MORE,
+                        LESS,
+                        EQUAL
+                } argc_cmp;
+                const int argc;
+                int (* const dispatch)(char **args, unsigned n);
+        } verbs[] = {
+                { "list",   LESS, 1, list_links  },
+                { "status", MORE, 1, link_status },
+        };
+
+        int left;
+        unsigned i;
+
+        assert(argc >= 0);
+        assert(argv);
+
+        left = argc - optind;
+
+        if (left <= 0)
+                /* Special rule: no arguments means "list" */
+                i = 0;
+        else {
+                if (streq(argv[optind], "help")) {
+                        help();
+                        return 0;
+                }
+
+                for (i = 0; i < ELEMENTSOF(verbs); i++)
+                        if (streq(argv[optind], verbs[i].verb))
+                                break;
+
+                if (i >= ELEMENTSOF(verbs)) {
+                        log_error("Unknown operation %s", argv[optind]);
+                        return -EINVAL;
+                }
+        }
+
+        switch (verbs[i].argc_cmp) {
+
+        case EQUAL:
+                if (left != verbs[i].argc) {
+                        log_error("Invalid number of arguments.");
+                        return -EINVAL;
+                }
+
+                break;
+
+        case MORE:
+                if (left < verbs[i].argc) {
+                        log_error("Too few arguments.");
+                        return -EINVAL;
+                }
+
+                break;
+
+        case LESS:
+                if (left > verbs[i].argc) {
+                        log_error("Too many arguments.");
+                        return -EINVAL;
+                }
+
+                break;
+
+        default:
+                assert_not_reached("Unknown comparison operator.");
+        }
+
+        return verbs[i].dispatch(argv + optind, left);
+}
+
+int main(int argc, char* argv[]) {
+        int r;
+
+        log_parse_environment();
+        log_open();
+
+        r = parse_argv(argc, argv);
+        if (r <= 0)
+                goto finish;
+
+        r = networkctl_main(argc, argv);
+
+finish:
+        pager_close();
+
+        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/src/network/networkd-address-pool.c b/src/network/networkd-address-pool.c
new file mode 100644 (file)
index 0000000..7ad11c6
--- /dev/null
@@ -0,0 +1,167 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <arpa/inet.h>
+
+#include "networkd.h"
+#include "networkd-link.h"
+
+int address_pool_new(
+                Manager *m,
+                AddressPool **ret,
+                int family,
+                const union in_addr_union *u,
+                unsigned prefixlen) {
+
+        AddressPool *p;
+
+        assert(m);
+        assert(ret);
+        assert(u);
+
+        p = new0(AddressPool, 1);
+        if (!p)
+                return -ENOMEM;
+
+        p->manager = m;
+        p->family = family;
+        p->prefixlen = prefixlen;
+        p->in_addr = *u;
+
+        LIST_PREPEND(address_pools, m->address_pools, p);
+
+        *ret = p;
+        return 0;
+}
+
+int address_pool_new_from_string(
+                Manager *m,
+                AddressPool **ret,
+                int family,
+                const char *p,
+                unsigned prefixlen) {
+
+        union in_addr_union u;
+        int r;
+
+        assert(m);
+        assert(ret);
+        assert(p);
+
+        r = in_addr_from_string(family, p, &u);
+        if (r < 0)
+                return r;
+
+        return address_pool_new(m, ret, family, &u, prefixlen);
+}
+
+void address_pool_free(AddressPool *p) {
+
+        if (!p)
+                return;
+
+        if (p->manager)
+                LIST_REMOVE(address_pools, p->manager->address_pools, p);
+
+        free(p);
+}
+
+static bool address_pool_prefix_is_taken(
+                AddressPool *p,
+                const union in_addr_union *u,
+                unsigned prefixlen) {
+
+        Iterator i;
+        Link *l;
+        Network *n;
+
+        assert(p);
+        assert(u);
+
+        HASHMAP_FOREACH(l, p->manager->links, i) {
+                Address *a;
+
+                /* Don't clash with assigned addresses */
+                LIST_FOREACH(addresses, a, l->addresses) {
+                        if (a->family != p->family)
+                                continue;
+
+                        if (in_addr_prefix_intersect(p->family, u, prefixlen, &a->in_addr, a->prefixlen))
+                                return true;
+                }
+
+                /* Don't clash with addresses already pulled from the pool, but not assigned yet */
+                LIST_FOREACH(addresses, a, l->pool_addresses) {
+                        if (a->family != p->family)
+                                continue;
+
+                        if (in_addr_prefix_intersect(p->family, u, prefixlen, &a->in_addr, a->prefixlen))
+                                return true;
+                }
+        }
+
+        /* And don't clash with configured but un-assigned addresses either */
+        LIST_FOREACH(networks, n, p->manager->networks) {
+                Address *a;
+
+                LIST_FOREACH(addresses, a, n->static_addresses) {
+                        if (a->family != p->family)
+                                continue;
+
+                        if (in_addr_prefix_intersect(p->family, u, prefixlen, &a->in_addr, a->prefixlen))
+                                return true;
+                }
+        }
+
+        return false;
+}
+
+int address_pool_acquire(AddressPool *p, unsigned prefixlen, union in_addr_union *found) {
+        union in_addr_union u;
+
+        assert(p);
+        assert(prefixlen > 0);
+        assert(found);
+
+        if (p->prefixlen > prefixlen)
+                return 0;
+
+        u = p->in_addr;
+        for (;;) {
+                if (!address_pool_prefix_is_taken(p, &u, prefixlen)) {
+                        _cleanup_free_ char *s = NULL;
+
+                        in_addr_to_string(p->family, &u, &s);
+                        log_debug("Found range %s/%u", strna(s), prefixlen);
+
+                        *found = u;
+                        return 1;
+                }
+
+                if (!in_addr_prefix_next(p->family, &u, prefixlen))
+                        return 0;
+
+                if (!in_addr_prefix_intersect(p->family, &p->in_addr, p->prefixlen, &u, prefixlen))
+                        return 0;
+        }
+
+        return 0;
+}
index a637739..e595cd6 100644 (file)
 #include <net/if.h>
 
 #include "networkd.h"
+#include "networkd-link.h"
 
 #include "utf8.h"
 #include "util.h"
 #include "conf-parser.h"
-#include "net-util.h"
+#include "network-internal.h"
+
+static void address_init(Address *address) {
+        assert(address);
+
+        address->family = AF_UNSPEC;
+        address->scope = RT_SCOPE_UNIVERSE;
+        address->cinfo.ifa_prefered = CACHE_INFO_INFINITY_LIFE_TIME;
+        address->cinfo.ifa_valid = CACHE_INFO_INFINITY_LIFE_TIME;
+}
 
 int address_new_static(Network *network, unsigned section, Address **ret) {
         _cleanup_address_free_ Address *address = NULL;
 
         if (section) {
-                uint64_t key = section;
-                address = hashmap_get(network->addresses_by_section, &key);
+                address = hashmap_get(network->addresses_by_section, UINT_TO_PTR(section));
                 if (address) {
                         *ret = address;
                         address = NULL;
@@ -46,15 +55,16 @@ int address_new_static(Network *network, unsigned section, Address **ret) {
         if (!address)
                 return -ENOMEM;
 
-        address->family = AF_UNSPEC;
+        address_init(address);
 
         address->network = network;
 
-        LIST_PREPEND(static_addresses, network->static_addresses, address);
+        LIST_PREPEND(addresses, network->static_addresses, address);
 
         if (section) {
                 address->section = section;
-                hashmap_put(network->addresses_by_section, &address->section, address);
+                hashmap_put(network->addresses_by_section,
+                            UINT_TO_PTR(address->section), address);
         }
 
         *ret = address;
@@ -70,7 +80,7 @@ int address_new_dynamic(Address **ret) {
         if (!address)
                 return -ENOMEM;
 
-        address->family = AF_UNSPEC;
+        address_init(address);
 
         *ret = address;
         address = NULL;
@@ -83,11 +93,11 @@ void address_free(Address *address) {
                 return;
 
         if (address->network) {
-                LIST_REMOVE(static_addresses, address->network->static_addresses, address);
+                LIST_REMOVE(addresses, address->network->static_addresses, address);
 
                 if (address->section)
                         hashmap_remove(address->network->addresses_by_section,
-                                       &address->section);
+                                       UINT_TO_PTR(address->section));
         }
 
         free(address);
@@ -135,22 +145,23 @@ int address_drop(Address *address, Link *link,
                 return r;
         }
 
+        link_ref(link);
+
         return 0;
 }
 
-int address_configure(Address *address, Link *link,
-                      sd_rtnl_message_handler_t callback) {
+int address_update(Address *address, Link *link,
+                   sd_rtnl_message_handler_t callback) {
         _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
         int r;
 
         assert(address);
         assert(address->family == AF_INET || address->family == AF_INET6);
-        assert(link);
         assert(link->ifindex > 0);
         assert(link->manager);
         assert(link->manager->rtnl);
 
-        r = sd_rtnl_message_new_addr(link->manager->rtnl, &req, RTM_NEWADDR,
+        r = sd_rtnl_message_new_addr_update(link->manager->rtnl, &req,
                                      link->ifindex, address->family);
         if (r < 0) {
                 log_error("Could not allocate RTM_NEWADDR message: %s",
@@ -170,7 +181,7 @@ int address_configure(Address *address, Link *link,
                 return r;
         }
 
-        r = sd_rtnl_message_addr_set_scope(req, RT_SCOPE_UNIVERSE);
+        r = sd_rtnl_message_addr_set_scope(req, address->scope);
         if (r < 0) {
                 log_error("Could not set scope: %s", strerror(-r));
                 return r;
@@ -204,53 +215,188 @@ int address_configure(Address *address, Link *link,
                 }
         }
 
+        r = sd_rtnl_message_append_cache_info(req, IFA_CACHEINFO, &address->cinfo);
+        if (r < 0) {
+                log_error("Could not append IFA_CACHEINFO attribute: %s",
+                          strerror(-r));
+                return r;
+        }
+
         r = sd_rtnl_call_async(link->manager->rtnl, req, callback, link, 0, NULL);
         if (r < 0) {
                 log_error("Could not send rtnetlink message: %s", strerror(-r));
                 return r;
         }
 
+        link_ref(link);
+
         return 0;
 }
 
-int config_parse_dns(const char *unit,
-                const char *filename,
-                unsigned line,
-                const char *section,
-                unsigned section_line,
-                const char *lvalue,
-                int ltype,
-                const char *rvalue,
-                void *data,
-                void *userdata) {
-        Address **dns = data;
-        _cleanup_address_free_ Address *n = NULL;
+static int address_acquire(Link *link, Address *original, Address **ret) {
+        union in_addr_union in_addr = {};
+        struct in_addr broadcast = {};
+        _cleanup_address_free_ Address *na = NULL;
         int r;
 
-        assert(filename);
-        assert(section);
-        assert(lvalue);
-        assert(rvalue);
-        assert(data);
+        assert(link);
+        assert(original);
+        assert(ret);
+
+        /* Something useful was configured? just use it */
+        if (in_addr_is_null(original->family, &original->in_addr) <= 0)
+                return 0;
+
+        /* The address is configured to be 0.0.0.0 or [::] by the user?
+         * Then let's acquire something more useful from the pool. */
+        r = manager_address_pool_acquire(link->manager, original->family, original->prefixlen, &in_addr);
+        if (r < 0) {
+                log_error_link(link, "Failed to acquire address from pool: %s", strerror(-r));
+                return r;
+        }
+        if (r == 0) {
+                log_error_link(link, "Couldn't find free address for interface, all taken.");
+                return -EBUSY;
+        }
+
+        if (original->family == AF_INET) {
+                /* Pick first address in range for ourselves ...*/
+                in_addr.in.s_addr = in_addr.in.s_addr | htobe32(1);
 
-        r = address_new_dynamic(&n);
+                /* .. and use last as broadcast address */
+                broadcast.s_addr = in_addr.in.s_addr | htobe32(0xFFFFFFFFUL >> original->prefixlen);
+        } else if (original->family == AF_INET6)
+                in_addr.in6.s6_addr[15] |= 1;
+
+        r = address_new_dynamic(&na);
         if (r < 0)
                 return r;
 
-        r = net_parse_inaddr(rvalue, &n->family, &n->in_addr);
+        na->family = original->family;
+        na->prefixlen = original->prefixlen;
+        na->scope = original->scope;
+        na->cinfo = original->cinfo;
+
+        if (original->label) {
+                na->label = strdup(original->label);
+                if (!na->label)
+                        return -ENOMEM;
+        }
+
+        na->broadcast = broadcast;
+        na->in_addr = in_addr;
+
+        LIST_PREPEND(addresses, link->pool_addresses, na);
+
+        *ret = na;
+        na = NULL;
+
+        return 0;
+}
+
+int address_configure(Address *address, Link *link,
+                      sd_rtnl_message_handler_t callback) {
+        _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
+        int r;
+
+        assert(address);
+        assert(address->family == AF_INET || address->family == AF_INET6);
+        assert(link);
+        assert(link->ifindex > 0);
+        assert(link->manager);
+        assert(link->manager->rtnl);
+
+        r = address_acquire(link, address, &address);
+        if (r < 0)
+                return r;
+
+        r = sd_rtnl_message_new_addr(link->manager->rtnl, &req, RTM_NEWADDR,
+                                     link->ifindex, address->family);
         if (r < 0) {
-                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
-                           "DNS address is invalid, ignoring assignment: %s", rvalue);
-                return 0;
+                log_error("Could not allocate RTM_NEWADDR message: %s",
+                          strerror(-r));
+                return r;
         }
 
-        *dns = n;
-        n = NULL;
+        r = sd_rtnl_message_addr_set_prefixlen(req, address->prefixlen);
+        if (r < 0) {
+                log_error("Could not set prefixlen: %s", strerror(-r));
+                return r;
+        }
+
+        r = sd_rtnl_message_addr_set_flags(req, IFA_F_PERMANENT);
+        if (r < 0) {
+                log_error("Could not set flags: %s", strerror(-r));
+                return r;
+        }
+
+        r = sd_rtnl_message_addr_set_scope(req, address->scope);
+        if (r < 0) {
+                log_error("Could not set scope: %s", strerror(-r));
+                return r;
+        }
+
+        if (address->family == AF_INET)
+                r = sd_rtnl_message_append_in_addr(req, IFA_LOCAL, &address->in_addr.in);
+        else if (address->family == AF_INET6)
+                r = sd_rtnl_message_append_in6_addr(req, IFA_LOCAL, &address->in_addr.in6);
+        if (r < 0) {
+                log_error("Could not append IFA_LOCAL attribute: %s",
+                          strerror(-r));
+                return r;
+        }
+
+        if (!in_addr_is_null(address->family, &address->in_addr_peer)) {
+                if (address->family == AF_INET)
+                        r = sd_rtnl_message_append_in_addr(req, IFA_ADDRESS, &address->in_addr_peer.in);
+                else if (address->family == AF_INET6)
+                        r = sd_rtnl_message_append_in6_addr(req, IFA_ADDRESS, &address->in_addr_peer.in6);
+                if (r < 0) {
+                        log_error("Could not append IFA_ADDRESS attribute: %s",
+                                  strerror(-r));
+                        return r;
+                }
+        } else {
+                if (address->family == AF_INET) {
+                        r = sd_rtnl_message_append_in_addr(req, IFA_BROADCAST, &address->broadcast);
+                        if (r < 0) {
+                                log_error("Could not append IFA_BROADCAST attribute: %s",
+                                          strerror(-r));
+                                return r;
+                        }
+                }
+        }
+
+        if (address->label) {
+                r = sd_rtnl_message_append_string(req, IFA_LABEL, address->label);
+                if (r < 0) {
+                        log_error("Could not append IFA_LABEL attribute: %s",
+                                  strerror(-r));
+                        return r;
+                }
+        }
+
+        r = sd_rtnl_message_append_cache_info(req, IFA_CACHEINFO,
+                                              &address->cinfo);
+        if (r < 0) {
+                log_error("Could not append IFA_CACHEINFO attribute: %s",
+                          strerror(-r));
+                return r;
+        }
+
+        r = sd_rtnl_call_async(link->manager->rtnl, req, callback, link, 0, NULL);
+        if (r < 0) {
+                log_error("Could not send rtnetlink message: %s", strerror(-r));
+                return r;
+        }
+
+        link_ref(link);
 
         return 0;
 }
 
-int config_parse_broadcast(const char *unit,
+int config_parse_broadcast(
+                const char *unit,
                 const char *filename,
                 unsigned line,
                 const char *section,
@@ -260,9 +406,9 @@ int config_parse_broadcast(const char *unit,
                 const char *rvalue,
                 void *data,
                 void *userdata) {
+
         Network *network = userdata;
         _cleanup_address_free_ Address *n = NULL;
-        _cleanup_free_ char *address = NULL;
         int r;
 
         assert(filename);
@@ -277,18 +423,18 @@ int config_parse_broadcast(const char *unit,
 
         if (n->family == AF_INET6) {
                 log_syntax(unit, LOG_ERR, filename, line, EINVAL,
-                           "Broadcast is not valid for IPv6 addresses, "
-                           "ignoring assignment: %s", address);
+                           "Broadcast is not valid for IPv6 addresses, ignoring assignment: %s", rvalue);
                 return 0;
         }
 
-        r = net_parse_inaddr(address, &n->family, &n->broadcast);
+        r = in_addr_from_string(AF_INET, rvalue, (union in_addr_union*) &n->broadcast);
         if (r < 0) {
                 log_syntax(unit, LOG_ERR, filename, line, EINVAL,
-                           "Broadcast is invalid, ignoring assignment: %s", address);
+                           "Broadcast is invalid, ignoring assignment: %s", rvalue);
                 return 0;
         }
 
+        n->family = AF_INET;
         n = NULL;
 
         return 0;
@@ -304,11 +450,12 @@ int config_parse_address(const char *unit,
                 const char *rvalue,
                 void *data,
                 void *userdata) {
+
         Network *network = userdata;
         _cleanup_address_free_ Address *n = NULL;
-        _cleanup_free_ char *address = NULL;
-        const char *e;
-        int r;
+        const char *address, *e;
+        union in_addr_union buffer;
+        int r, f;
 
         assert(filename);
         assert(section);
@@ -335,32 +482,38 @@ int config_parse_address(const char *unit,
                 r = safe_atou(e + 1, &i);
                 if (r < 0) {
                         log_syntax(unit, LOG_ERR, filename, line, EINVAL,
-                                   "Interface prefix length is invalid, "
-                                   "ignoring assignment: %s", e + 1);
+                                   "Interface prefix length is invalid, ignoring assignment: %s", e + 1);
                         return 0;
                 }
 
                 n->prefixlen = (unsigned char) i;
 
-                address = strndup(rvalue, e - rvalue);
-                if (!address)
-                        return log_oom();
-        } else {
-                address = strdup(rvalue);
-                if (!address)
-                        return log_oom();
-        }
+                address = strndupa(rvalue, e - rvalue);
+        } else
+                address = rvalue;
 
-        r = net_parse_inaddr(address, &n->family, &n->in_addr);
+        r = in_addr_from_string_auto(address, &f, &buffer);
         if (r < 0) {
                 log_syntax(unit, LOG_ERR, filename, line, EINVAL,
                            "Address is invalid, ignoring assignment: %s", address);
                 return 0;
         }
 
-        if (n->family == AF_INET && !n->broadcast.s_addr)
-                n->broadcast.s_addr = n->in_addr.in.s_addr |
-                                      htonl(0xfffffffflu >> n->prefixlen);
+        if (n->family != AF_UNSPEC && f != n->family) {
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                           "Address is incompatible, ignoring assignment: %s", address);
+                return 0;
+        }
+
+        n->family = f;
+
+        if (streq(lvalue, "Address"))
+                n->in_addr = buffer;
+        else
+                n->in_addr_peer = buffer;
+
+        if (n->family == AF_INET && n->broadcast.s_addr == 0)
+                n->broadcast.s_addr = n->in_addr.in.s_addr | htonl(0xfffffffflu >> n->prefixlen);
 
         n = NULL;
 
@@ -416,3 +569,46 @@ int config_parse_label(const char *unit,
 
         return 0;
 }
+
+bool address_equal(Address *a1, Address *a2) {
+        /* same object */
+        if (a1 == a2)
+                return true;
+
+        /* one, but not both, is NULL */
+        if (!a1 || !a2)
+                return false;
+
+        if (a1->family != a2->family)
+                return false;
+
+        switch (a1->family) {
+        /* use the same notion of equality as the kernel does */
+        case AF_UNSPEC:
+                return true;
+
+        case AF_INET:
+                if (a1->prefixlen != a2->prefixlen)
+                        return false;
+                else {
+                        uint32_t b1, b2;
+
+                        b1 = be32toh(a1->in_addr.in.s_addr);
+                        b2 = be32toh(a2->in_addr.in.s_addr);
+
+                        return (b1 >> (32 - a1->prefixlen)) == (b2 >> (32 - a1->prefixlen));
+                }
+
+        case AF_INET6:
+        {
+                uint64_t *b1, *b2;
+
+                b1 = (uint64_t*)&a1->in_addr.in6;
+                b2 = (uint64_t*)&a2->in_addr.in6;
+
+                return (((b1[0] ^ b2[0]) | (b1[1] ^ b2[1])) == 0UL);
+        }
+        default:
+                assert_not_reached("Invalid address family");
+        }
+}
diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c
new file mode 100644 (file)
index 0000000..5e4ff2b
--- /dev/null
@@ -0,0 +1,652 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2013-2014 Tom Gundersen <teg@jklm.no>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <netinet/ether.h>
+#include <linux/if.h>
+
+#include "networkd-link.h"
+#include "network-internal.h"
+#include "dhcp-lease-internal.h"
+
+static int dhcp4_route_handler(sd_rtnl *rtnl, sd_rtnl_message *m,
+                               void *userdata) {
+        _cleanup_link_unref_ Link *link = userdata;
+        int r;
+
+        assert(link);
+        assert(link->dhcp4_messages);
+
+        link->dhcp4_messages --;
+
+        r = sd_rtnl_message_get_errno(m);
+        if (r < 0 && r != -EEXIST) {
+                log_error_link(link, "could not set DHCPv4 route: %s",
+                               strerror(-r));
+                link_enter_failed(link);
+        }
+
+        if (!link->dhcp4_messages) {
+                link->dhcp4_configured = true;
+                link_client_handler(link);
+        }
+
+        return 1;
+}
+
+static int link_set_dhcp_routes(Link *link) {
+        struct in_addr gateway;
+        struct sd_dhcp_route *static_routes;
+        int r, n, i;
+
+        assert(link);
+        assert(link->dhcp_lease);
+
+        r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
+        if (r < 0 && r != -ENOENT) {
+                log_warning_link(link,
+                                 "DHCP error: could not get gateway: %s",
+                                 strerror(-r));
+                return r;
+        }
+        if (r >= 0) {
+                _cleanup_route_free_ Route *route = NULL;
+                _cleanup_route_free_ Route *route_gw = NULL;
+
+                r = route_new_dynamic(&route, RTPROT_DHCP);
+                if (r < 0) {
+                        log_error_link(link,
+                                       "Could not allocate route: %s",
+                                       strerror(-r));
+                        return r;
+                }
+
+                r = route_new_dynamic(&route_gw, RTPROT_DHCP);
+                if (r < 0) {
+                log_error_link(link,
+                               "Could not allocate route: %s",
+                               strerror(-r));
+                               return r;
+                }
+
+                /* The dhcp netmask may mask out the gateway. Add an explicit
+                 * route for the gw host so that we can route no matter the
+                 * netmask or existing kernel route tables. */
+                route_gw->family = AF_INET;
+                route_gw->dst_addr.in = gateway;
+                route_gw->dst_prefixlen = 32;
+                route_gw->scope = RT_SCOPE_LINK;
+                route_gw->metrics = DHCP_ROUTE_METRIC;
+
+                r = route_configure(route_gw, link, &dhcp4_route_handler);
+                if (r < 0) {
+                        log_warning_link(link,
+                                         "could not set host route: %s",
+                                         strerror(-r));
+                        return r;
+                }
+
+                link->dhcp4_messages ++;
+
+                route->family = AF_INET;
+                route->in_addr.in = gateway;
+                route->metrics = DHCP_ROUTE_METRIC;
+
+                r = route_configure(route, link, &dhcp4_route_handler);
+                if (r < 0) {
+                        log_warning_link(link,
+                                         "could not set routes: %s",
+                                         strerror(-r));
+                        link_enter_failed(link);
+                        return r;
+                }
+
+                link->dhcp4_messages ++;
+        }
+
+        n = sd_dhcp_lease_get_routes(link->dhcp_lease, &static_routes);
+        if (n == -ENOENT)
+                return 0;
+        if (n < 0) {
+                log_warning_link(link,
+                                 "DHCP error: could not get routes: %s",
+                                 strerror(-n));
+
+                return n;
+        }
+
+        for (i = 0; i < n; i++) {
+                _cleanup_route_free_ Route *route = NULL;
+
+                r = route_new_dynamic(&route, RTPROT_DHCP);
+                if (r < 0) {
+                        log_error_link(link, "Could not allocate route: %s",
+                                       strerror(-r));
+                        return r;
+                }
+
+                route->family = AF_INET;
+                route->in_addr.in = static_routes[i].gw_addr;
+                route->dst_addr.in = static_routes[i].dst_addr;
+                route->dst_prefixlen = static_routes[i].dst_prefixlen;
+                route->metrics = DHCP_ROUTE_METRIC;
+
+                r = route_configure(route, link, &dhcp4_route_handler);
+                if (r < 0) {
+                        log_warning_link(link,
+                                         "could not set host route: %s",
+                                         strerror(-r));
+                        return r;
+                }
+
+                link->dhcp4_messages ++;
+        }
+
+        return 0;
+}
+
+static int dhcp_lease_lost(Link *link) {
+        _cleanup_address_free_ Address *address = NULL;
+        struct in_addr addr;
+        struct in_addr netmask;
+        struct in_addr gateway;
+        unsigned prefixlen;
+        int r;
+
+        assert(link);
+        assert(link->dhcp_lease);
+
+        log_warning_link(link, "DHCP lease lost");
+
+        if (link->network->dhcp_routes) {
+                struct sd_dhcp_route *routes;
+                int n, i;
+
+                n = sd_dhcp_lease_get_routes(link->dhcp_lease, &routes);
+                if (n >= 0) {
+                        for (i = 0; i < n; i++) {
+                                _cleanup_route_free_ Route *route = NULL;
+
+                                r = route_new_dynamic(&route, RTPROT_UNSPEC);
+                                if (r >= 0) {
+                                        route->family = AF_INET;
+                                        route->in_addr.in = routes[i].gw_addr;
+                                        route->dst_addr.in = routes[i].dst_addr;
+                                        route->dst_prefixlen = routes[i].dst_prefixlen;
+
+                                        route_drop(route, link,
+                                                   &link_route_drop_handler);
+                                }
+                        }
+                }
+        }
+
+        r = address_new_dynamic(&address);
+        if (r >= 0) {
+                r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
+                if (r >= 0) {
+                        _cleanup_route_free_ Route *route_gw = NULL;
+                        _cleanup_route_free_ Route *route = NULL;
+
+                        r = route_new_dynamic(&route_gw, RTPROT_UNSPEC);
+                        if (r >= 0) {
+                                route_gw->family = AF_INET;
+                                route_gw->dst_addr.in = gateway;
+                                route_gw->dst_prefixlen = 32;
+                                route_gw->scope = RT_SCOPE_LINK;
+
+                                route_drop(route_gw, link,
+                                           &link_route_drop_handler);
+                        }
+
+                        r = route_new_dynamic(&route, RTPROT_UNSPEC);
+                        if (r >= 0) {
+                                route->family = AF_INET;
+                                route->in_addr.in = gateway;
+
+                                route_drop(route, link,
+                                           &link_route_drop_handler);
+                        }
+                }
+
+                sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
+                sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
+                prefixlen = in_addr_netmask_to_prefixlen(&netmask);
+
+                address->family = AF_INET;
+                address->in_addr.in = addr;
+                address->prefixlen = prefixlen;
+
+                address_drop(address, link, &link_address_drop_handler);
+        }
+
+        if (link->network->dhcp_mtu) {
+                uint16_t mtu;
+
+                r = sd_dhcp_lease_get_mtu(link->dhcp_lease, &mtu);
+                if (r >= 0 && link->original_mtu != mtu) {
+                        r = link_set_mtu(link, link->original_mtu);
+                        if (r < 0) {
+                                log_warning_link(link,
+                                                 "DHCP error: could not reset MTU");
+                                link_enter_failed(link);
+                                return r;
+                        }
+                }
+        }
+
+        if (link->network->dhcp_hostname) {
+                const char *hostname = NULL;
+
+                r = sd_dhcp_lease_get_hostname(link->dhcp_lease, &hostname);
+                if (r >= 0 && hostname) {
+                        r = link_set_hostname(link, "");
+                        if (r < 0)
+                                log_error_link(link,
+                                               "Failed to reset transient hostname");
+                }
+        }
+
+        link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease);
+        link->dhcp4_configured = false;
+
+        return 0;
+}
+
+static int dhcp4_address_handler(sd_rtnl *rtnl, sd_rtnl_message *m,
+                                 void *userdata) {
+        _cleanup_link_unref_ Link *link = userdata;
+        int r;
+
+        assert(link);
+
+        r = sd_rtnl_message_get_errno(m);
+        if (r < 0 && r != -EEXIST) {
+                log_error_link(link, "could not set DHCPv4 address: %s",
+                               strerror(-r));
+                link_enter_failed(link);
+        } else if (r >= 0) {
+                /* calling handler directly so take a ref */
+                link_ref(link);
+                link_get_address_handler(rtnl, m, link);
+        }
+
+        link_set_dhcp_routes(link);
+
+        return 1;
+}
+
+static int dhcp4_update_address(Link *link,
+                                struct in_addr *address,
+                                struct in_addr *netmask,
+                                uint32_t lifetime) {
+        _cleanup_address_free_ Address *addr = NULL;
+        unsigned prefixlen;
+        int r;
+
+        assert(address);
+        assert(netmask);
+        assert(lifetime);
+
+        prefixlen = in_addr_netmask_to_prefixlen(netmask);
+
+        r = address_new_dynamic(&addr);
+        if (r < 0)
+                return r;
+
+        addr->family = AF_INET;
+        addr->in_addr.in.s_addr = address->s_addr;
+        addr->cinfo.ifa_prefered = lifetime;
+        addr->cinfo.ifa_valid = lifetime;
+        addr->prefixlen = prefixlen;
+        addr->broadcast.s_addr = address->s_addr | ~netmask->s_addr;
+
+        /* use update rather than configure so that we will update the
+         * lifetime of an existing address if it has already been configured */
+        r = address_update(addr, link, &dhcp4_address_handler);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+static int dhcp_lease_renew(sd_dhcp_client *client, Link *link) {
+        sd_dhcp_lease *lease;
+        struct in_addr address;
+        struct in_addr netmask;
+        uint32_t lifetime = CACHE_INFO_INFINITY_LIFE_TIME;
+        int r;
+
+        assert(link);
+        assert(client);
+        assert(link->network);
+
+        r = sd_dhcp_client_get_lease(client, &lease);
+        if (r < 0) {
+                log_warning_link(link, "DHCP error: no lease %s",
+                                 strerror(-r));
+                return r;
+        }
+
+        sd_dhcp_lease_unref(link->dhcp_lease);
+        link->dhcp4_configured = false;
+        link->dhcp_lease = lease;
+
+        r = sd_dhcp_lease_get_address(lease, &address);
+        if (r < 0) {
+                log_warning_link(link, "DHCP error: no address: %s",
+                                 strerror(-r));
+                return r;
+        }
+
+        r = sd_dhcp_lease_get_netmask(lease, &netmask);
+        if (r < 0) {
+                log_warning_link(link, "DHCP error: no netmask: %s",
+                                 strerror(-r));
+                return r;
+        }
+
+        if (!link->network->dhcp_critical) {
+                r = sd_dhcp_lease_get_lifetime(link->dhcp_lease,
+                                               &lifetime);
+                if (r < 0) {
+                        log_warning_link(link,
+                                         "DHCP error: no lifetime: %s",
+                                         strerror(-r));
+                        return r;
+                }
+        }
+
+        r = dhcp4_update_address(link, &address, &netmask, lifetime);
+        if (r < 0) {
+                log_warning_link(link, "could not update IP address: %s",
+                                 strerror(-r));
+                link_enter_failed(link);
+                return r;
+        }
+
+        return 0;
+}
+
+static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
+        sd_dhcp_lease *lease;
+        struct in_addr address;
+        struct in_addr netmask;
+        struct in_addr gateway;
+        unsigned prefixlen;
+        uint32_t lifetime = CACHE_INFO_INFINITY_LIFE_TIME;
+        int r;
+
+        assert(client);
+        assert(link);
+
+        r = sd_dhcp_client_get_lease(client, &lease);
+        if (r < 0) {
+                log_warning_link(link, "DHCP error: no lease: %s",
+                                 strerror(-r));
+                return r;
+        }
+
+        r = sd_dhcp_lease_get_address(lease, &address);
+        if (r < 0) {
+                log_warning_link(link, "DHCP error: no address: %s",
+                                 strerror(-r));
+                return r;
+        }
+
+        r = sd_dhcp_lease_get_netmask(lease, &netmask);
+        if (r < 0) {
+                log_warning_link(link, "DHCP error: no netmask: %s",
+                                 strerror(-r));
+                return r;
+        }
+
+        prefixlen = in_addr_netmask_to_prefixlen(&netmask);
+
+        r = sd_dhcp_lease_get_router(lease, &gateway);
+        if (r < 0 && r != -ENOENT) {
+                log_warning_link(link, "DHCP error: could not get gateway: %s",
+                                 strerror(-r));
+                return r;
+        }
+
+        if (r >= 0)
+                log_struct_link(LOG_INFO, link,
+                                "MESSAGE=%-*s: DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
+                                 IFNAMSIZ,
+                                 link->ifname,
+                                 ADDRESS_FMT_VAL(address),
+                                 prefixlen,
+                                 ADDRESS_FMT_VAL(gateway),
+                                 "ADDRESS=%u.%u.%u.%u",
+                                 ADDRESS_FMT_VAL(address),
+                                 "PREFIXLEN=%u",
+                                 prefixlen,
+                                 "GATEWAY=%u.%u.%u.%u",
+                                 ADDRESS_FMT_VAL(gateway),
+                                 NULL);
+        else
+                log_struct_link(LOG_INFO, link,
+                                "MESSAGE=%-*s: DHCPv4 address %u.%u.%u.%u/%u",
+                                 IFNAMSIZ,
+                                 link->ifname,
+                                 ADDRESS_FMT_VAL(address),
+                                 prefixlen,
+                                 "ADDRESS=%u.%u.%u.%u",
+                                 ADDRESS_FMT_VAL(address),
+                                 "PREFIXLEN=%u",
+                                 prefixlen,
+                                 NULL);
+
+        link->dhcp_lease = lease;
+
+        if (link->network->dhcp_mtu) {
+                uint16_t mtu;
+
+                r = sd_dhcp_lease_get_mtu(lease, &mtu);
+                if (r >= 0) {
+                        r = link_set_mtu(link, mtu);
+                        if (r < 0)
+                                log_error_link(link, "Failed to set MTU "
+                                               "to %" PRIu16, mtu);
+                }
+        }
+
+        if (link->network->dhcp_hostname) {
+                const char *hostname;
+
+                r = sd_dhcp_lease_get_hostname(lease, &hostname);
+                if (r >= 0) {
+                        r = link_set_hostname(link, hostname);
+                        if (r < 0)
+                                log_error_link(link,
+                                               "Failed to set transient hostname to '%s'",
+                                               hostname);
+                }
+        }
+
+        if (!link->network->dhcp_critical) {
+                r = sd_dhcp_lease_get_lifetime(link->dhcp_lease,
+                                               &lifetime);
+                if (r < 0) {
+                        log_warning_link(link,
+                                         "DHCP error: no lifetime: %s",
+                                         strerror(-r));
+                        return r;
+                }
+        }
+
+        r = dhcp4_update_address(link, &address, &netmask, lifetime);
+        if (r < 0) {
+                log_warning_link(link, "could not update IP address: %s",
+                                 strerror(-r));
+                link_enter_failed(link);
+                return r;
+        }
+
+        return 0;
+}
+static void dhcp4_handler(sd_dhcp_client *client, int event, void *userdata) {
+        Link *link = userdata;
+        int r = 0;
+
+        assert(link);
+        assert(link->network);
+        assert(link->manager);
+
+        if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
+                return;
+
+        switch (event) {
+                case DHCP_EVENT_EXPIRED:
+                case DHCP_EVENT_STOP:
+                case DHCP_EVENT_IP_CHANGE:
+                        if (link->network->dhcp_critical) {
+                                log_error_link(link,
+                                               "DHCPv4 connection considered system critical, ignoring request to reconfigure it.");
+                                return;
+                        }
+
+                        if (link->dhcp_lease) {
+                                r = dhcp_lease_lost(link);
+                                if (r < 0) {
+                                        link_enter_failed(link);
+                                        return;
+                                }
+                        }
+
+                        if (event == DHCP_EVENT_IP_CHANGE) {
+                                r = dhcp_lease_acquired(client, link);
+                                if (r < 0) {
+                                        link_enter_failed(link);
+                                        return;
+                                }
+                        }
+
+                        break;
+                case DHCP_EVENT_RENEW:
+                        r = dhcp_lease_renew(client, link);
+                        if (r < 0) {
+                                link_enter_failed(link);
+                                return;
+                        }
+                        break;
+                case DHCP_EVENT_IP_ACQUIRE:
+                        r = dhcp_lease_acquired(client, link);
+                        if (r < 0) {
+                                link_enter_failed(link);
+                                return;
+                        }
+                        break;
+                default:
+                        if (event < 0)
+                                log_warning_link(link,
+                                                 "DHCP error: client failed: %s",
+                                                 strerror(-event));
+                        else
+                                log_warning_link(link,
+                                                 "DHCP unknown event: %d",
+                                                 event);
+                        break;
+        }
+
+        return;
+}
+
+int dhcp4_configure(Link *link) {
+        int r;
+
+        assert(link);
+        assert(link->network);
+        assert(IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V4));
+
+        r = sd_dhcp_client_new(&link->dhcp_client);
+        if (r < 0)
+                return r;
+
+        r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
+        if (r < 0)
+                return r;
+
+        r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
+        if (r < 0)
+                return r;
+
+        r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex);
+        if (r < 0)
+                return r;
+
+        r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp4_handler, link);
+        if (r < 0)
+                return r;
+
+        r = sd_dhcp_client_set_request_broadcast(link->dhcp_client,
+                                                 link->network->dhcp_broadcast);
+        if (r < 0)
+                return r;
+
+        if (link->mtu) {
+                r = sd_dhcp_client_set_mtu(link->dhcp_client, link->mtu);
+                if (r < 0)
+                        return r;
+        }
+
+        if (link->network->dhcp_mtu) {
+             r = sd_dhcp_client_set_request_option(link->dhcp_client,
+                                                   DHCP_OPTION_INTERFACE_MTU);
+             if (r < 0)
+                return r;
+        }
+
+        if (link->network->dhcp_routes) {
+                r = sd_dhcp_client_set_request_option(link->dhcp_client,
+                                                      DHCP_OPTION_STATIC_ROUTE);
+                if (r < 0)
+                        return r;
+                r = sd_dhcp_client_set_request_option(link->dhcp_client,
+                                                      DHCP_OPTION_CLASSLESS_STATIC_ROUTE);
+                        if (r < 0)
+                                return r;
+        }
+
+        if (link->network->dhcp_sendhost) {
+                _cleanup_free_ char *hostname = NULL;
+
+                hostname = gethostname_malloc();
+                if (!hostname)
+                        return -ENOMEM;
+
+                if (!is_localhost(hostname)) {
+                        r = sd_dhcp_client_set_hostname(link->dhcp_client,
+                                                        hostname);
+                        if (r < 0)
+                                return r;
+                }
+        }
+
+        if (link->network->dhcp_vendor_class_identifier) {
+                r = sd_dhcp_client_set_vendor_class_identifier(link->dhcp_client,
+                                                               link->network->dhcp_vendor_class_identifier);
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
diff --git a/src/network/networkd-ipv4ll.c b/src/network/networkd-ipv4ll.c
new file mode 100644 (file)
index 0000000..5467bc3
--- /dev/null
@@ -0,0 +1,248 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2013-2014 Tom Gundersen <teg@jklm.no>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <netinet/ether.h>
+#include <linux/if.h>
+
+#include "networkd-link.h"
+#include "network-internal.h"
+
+static int ipv4ll_address_lost(Link *link) {
+        _cleanup_address_free_ Address *address = NULL;
+        _cleanup_route_free_ Route *route = NULL;
+        struct in_addr addr;
+        int r;
+
+        assert(link);
+
+        link->ipv4ll_route = false;
+        link->ipv4ll_address =  false;
+
+        r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
+        if (r < 0)
+                return 0;
+
+        log_debug_link(link, "IPv4 link-local release %u.%u.%u.%u",
+                       ADDRESS_FMT_VAL(addr));
+
+        r = address_new_dynamic(&address);
+        if (r < 0) {
+                log_error_link(link, "Could not allocate address: %s", strerror(-r));
+                return r;
+        }
+
+        address->family = AF_INET;
+        address->in_addr.in = addr;
+        address->prefixlen = 16;
+        address->scope = RT_SCOPE_LINK;
+
+        address_drop(address, link, &link_address_drop_handler);
+
+        r = route_new_dynamic(&route, RTPROT_UNSPEC);
+        if (r < 0) {
+                log_error_link(link, "Could not allocate route: %s",
+                               strerror(-r));
+                return r;
+        }
+
+        route->family = AF_INET;
+        route->scope = RT_SCOPE_LINK;
+        route->metrics = IPV4LL_ROUTE_METRIC;
+
+        route_drop(route, link, &link_route_drop_handler);
+
+        link_client_handler(link);
+
+        return 0;
+}
+
+static int ipv4ll_route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
+        _cleanup_link_unref_ Link *link = userdata;
+        int r;
+
+        assert(link);
+        assert(!link->ipv4ll_route);
+
+        r = sd_rtnl_message_get_errno(m);
+        if (r < 0 && r != -EEXIST) {
+                log_error_link(link, "could not set ipv4ll route: %s", strerror(-r));
+                link_enter_failed(link);
+        }
+
+        link->ipv4ll_route = true;
+
+        if (link->ipv4ll_address == true)
+                link_client_handler(link);
+
+        return 1;
+}
+
+static int ipv4ll_address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
+        _cleanup_link_unref_ Link *link = userdata;
+        int r;
+
+        assert(link);
+        assert(!link->ipv4ll_address);
+
+        r = sd_rtnl_message_get_errno(m);
+        if (r < 0 && r != -EEXIST) {
+                log_error_link(link, "could not set ipv4ll address: %s", strerror(-r));
+                link_enter_failed(link);
+        } else if (r >= 0) {
+                /* calling handler directly so take a ref */
+                link_ref(link);
+                link_get_address_handler(rtnl, m, link);
+        }
+
+        link->ipv4ll_address = true;
+
+        if (link->ipv4ll_route == true)
+                link_client_handler(link);
+
+        return 1;
+}
+
+static int ipv4ll_address_claimed(sd_ipv4ll *ll, Link *link) {
+        _cleanup_address_free_ Address *ll_addr = NULL;
+        _cleanup_route_free_ Route *route = NULL;
+        struct in_addr address;
+        int r;
+
+        assert(ll);
+        assert(link);
+
+        r = sd_ipv4ll_get_address(ll, &address);
+        if (r == -ENOENT)
+                return 0;
+        else if (r < 0)
+                return r;
+
+        log_debug_link(link, "IPv4 link-local claim %u.%u.%u.%u",
+                       ADDRESS_FMT_VAL(address));
+
+        r = address_new_dynamic(&ll_addr);
+        if (r < 0)
+                return r;
+
+        ll_addr->family = AF_INET;
+        ll_addr->in_addr.in = address;
+        ll_addr->prefixlen = 16;
+        ll_addr->broadcast.s_addr = ll_addr->in_addr.in.s_addr | htonl(0xfffffffflu >> ll_addr->prefixlen);
+        ll_addr->scope = RT_SCOPE_LINK;
+
+        r = address_configure(ll_addr, link, ipv4ll_address_handler);
+        if (r < 0)
+                return r;
+
+        link->ipv4ll_address = false;
+
+        r = route_new_dynamic(&route, RTPROT_STATIC);
+        if (r < 0)
+                return r;
+
+        route->family = AF_INET;
+        route->scope = RT_SCOPE_LINK;
+        route->metrics = IPV4LL_ROUTE_METRIC;
+
+        r = route_configure(route, link, ipv4ll_route_handler);
+        if (r < 0)
+                return r;
+
+        link->ipv4ll_route = false;
+
+        return 0;
+}
+
+static void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata){
+        Link *link = userdata;
+        int r;
+
+        assert(link);
+        assert(link->network);
+        assert(link->manager);
+
+        if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
+                return;
+
+        switch(event) {
+                case IPV4LL_EVENT_STOP:
+                case IPV4LL_EVENT_CONFLICT:
+                        r = ipv4ll_address_lost(link);
+                        if (r < 0) {
+                                link_enter_failed(link);
+                                return;
+                        }
+                        break;
+                case IPV4LL_EVENT_BIND:
+                        r = ipv4ll_address_claimed(ll, link);
+                        if (r < 0) {
+                                link_enter_failed(link);
+                                return;
+                        }
+                        break;
+                default:
+                        if (event < 0)
+                                log_warning_link(link, "IPv4 link-local error: %s", strerror(-event));
+                        else
+                                log_warning_link(link, "IPv4 link-local unknown event: %d", event);
+                        break;
+        }
+}
+
+int ipv4ll_configure(Link *link) {
+        uint8_t seed[8];
+        int r;
+
+        assert(link);
+        assert(link->network);
+        assert(link->network->ipv4ll);
+
+        r = sd_ipv4ll_new(&link->ipv4ll);
+        if (r < 0)
+                return r;
+
+        if (link->udev_device) {
+                r = net_get_unique_predictable_data(link->udev_device, seed);
+                if (r >= 0) {
+                        r = sd_ipv4ll_set_address_seed(link->ipv4ll, seed);
+                        if (r < 0)
+                                return r;
+                }
+        }
+
+        r = sd_ipv4ll_attach_event(link->ipv4ll, NULL, 0);
+        if (r < 0)
+                return r;
+
+        r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
+        if (r < 0)
+                return r;
+
+        r = sd_ipv4ll_set_index(link->ipv4ll, link->ifindex);
+        if (r < 0)
+                return r;
+
+        r = sd_ipv4ll_set_callback(link->ipv4ll, ipv4ll_handler, link);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
index 1f495b3..dff3270 100644 (file)
 
 #include <netinet/ether.h>
 #include <linux/if.h>
+#include <unistd.h>
 
-#include "networkd.h"
+#include "networkd-link.h"
+#include "networkd-netdev.h"
 #include "libudev-private.h"
+#include "udev-util.h"
 #include "util.h"
+#include "virt.h"
 #include "bus-util.h"
-#include "net-util.h"
+#include "network-internal.h"
+#include "conf-parser.h"
 
-int link_new(Manager *manager, struct udev_device *device, Link **ret) {
-        _cleanup_link_free_ Link *link = NULL;
-        const char *mac;
-        struct ether_addr *mac_addr;
+#include "dhcp-lease-internal.h"
+
+static int link_new(Manager *manager, sd_rtnl_message *message, Link **ret) {
+        _cleanup_link_unref_ Link *link = NULL;
+        uint16_t type;
         const char *ifname;
-        int r;
+        int r, ifindex;
 
         assert(manager);
-        assert(manager->links);
-        assert(device);
+        assert(message);
         assert(ret);
 
+        r = sd_rtnl_message_get_type(message, &type);
+        if (r < 0)
+                return r;
+        else if (type != RTM_NEWLINK)
+                return -EINVAL;
+
+        r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
+        if (r < 0)
+                return r;
+        else if (ifindex <= 0)
+                return -EINVAL;
+
+        r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &ifname);
+        if (r < 0)
+                return r;
+
         link = new0(Link, 1);
         if (!link)
                 return -ENOMEM;
 
+        link->n_ref = 1;
         link->manager = manager;
-        link->state = _LINK_STATE_INVALID;
+        link->state = LINK_STATE_PENDING;
+        link->ifindex = ifindex;
+        link->ifname = strdup(ifname);
+        if (!link->ifname)
+                return -ENOMEM;
 
-        link->ifindex = udev_device_get_ifindex(device);
-        if (link->ifindex <= 0)
-                return -EINVAL;
+        r = sd_rtnl_message_read_ether_addr(message, IFLA_ADDRESS, &link->mac);
+        if (r < 0)
+                log_debug_link(link, "MAC address not found for new device, continuing without");
 
-        mac = udev_device_get_sysattr_value(device, "address");
-        if (mac) {
-                mac_addr = ether_aton(mac);
-                if (mac_addr)
-                        memcpy(&link->mac, mac_addr, sizeof(struct ether_addr));
-        }
+        r = asprintf(&link->state_file, "/run/systemd/netif/links/%d",
+                     link->ifindex);
+        if (r < 0)
+                return -ENOMEM;
 
-        ifname = udev_device_get_sysname(device);
-        link->ifname = strdup(ifname);
+        r = asprintf(&link->lease_file, "/run/systemd/netif/leases/%d",
+                     link->ifindex);
+        if (r < 0)
+                return -ENOMEM;
+
+        r = hashmap_ensure_allocated(&manager->links, NULL, NULL);
+        if (r < 0)
+                return r;
 
-        r = hashmap_put(manager->links, &link->ifindex, link);
+        r = hashmap_put(manager->links, INT_TO_PTR(link->ifindex), link);
         if (r < 0)
                 return r;
 
@@ -71,33 +101,67 @@ int link_new(Manager *manager, struct udev_device *device, Link **ret) {
         return 0;
 }
 
-void link_free(Link *link) {
+static void link_free(Link *link) {
+        Address *address;
+
         if (!link)
                 return;
 
-        assert(link->manager);
+        while ((address = link->addresses)) {
+                LIST_REMOVE(addresses, link->addresses, address);
+                address_free(address);
+        }
+
+        while ((address = link->pool_addresses)) {
+                LIST_REMOVE(addresses, link->pool_addresses, address);
+                address_free(address);
+        }
 
-        sd_dhcp_client_free(link->dhcp_client);
+        sd_dhcp_client_unref(link->dhcp_client);
         sd_dhcp_lease_unref(link->dhcp_lease);
 
-        hashmap_remove(link->manager->links, &link->ifindex);
+        unlink(link->lease_file);
+        free(link->lease_file);
+
+        sd_ipv4ll_unref(link->ipv4ll);
+        sd_dhcp6_client_unref(link->dhcp6_client);
+        sd_icmp6_nd_unref(link->icmp6_router_discovery);
+
+        if (link->manager)
+                hashmap_remove(link->manager->links, INT_TO_PTR(link->ifindex));
 
         free(link->ifname);
 
+        unlink(link->state_file);
+        free(link->state_file);
+
+        udev_device_unref(link->udev_device);
+
         free(link);
 }
 
+Link *link_unref(Link *link) {
+        if (link && (-- link->n_ref <= 0))
+                link_free(link);
+
+        return NULL;
+}
+
+Link *link_ref(Link *link) {
+        if (link)
+                assert_se(++ link->n_ref >= 2);
+
+        return link;
+}
+
 int link_get(Manager *m, int ifindex, Link **ret) {
         Link *link;
-        uint64_t ifindex_64;
 
         assert(m);
-        assert(m->links);
         assert(ifindex);
         assert(ret);
 
-        ifindex_64 = ifindex;
-        link = hashmap_get(m->links, &ifindex_64);
+        link = hashmap_get(m->links, INT_TO_PTR(ifindex));
         if (!link)
                 return -ENODEV;
 
@@ -106,77 +170,249 @@ int link_get(Manager *m, int ifindex, Link **ret) {
         return 0;
 }
 
-int link_add(Manager *m, struct udev_device *device, Link **ret) {
-        Link *link = NULL;
-        Network *network;
-        int r;
+void link_drop(Link *link) {
+        if (!link || link->state == LINK_STATE_LINGER)
+                return;
 
-        assert(m);
-        assert(device);
+        link->state = LINK_STATE_LINGER;
 
-        r = link_new(m, device, &link);
-        if (r < 0)
-                return r;
+        log_debug_link(link, "link removed");
 
-        *ret = link;
+        link_unref(link);
 
-        r = network_get(m, device, &network);
-        if (r < 0)
-                return r == -ENOENT ? 0 : r;
+        return;
+}
 
-        r = network_apply(m, network, link);
-        if (r < 0)
-                return r;
+static void link_enter_unmanaged(Link *link) {
+        assert(link);
 
-        return 0;
+        log_debug_link(link, "unmanaged");
+
+        link->state = LINK_STATE_UNMANAGED;
+
+        link_save(link);
+}
+
+static int link_stop_clients(Link *link) {
+        int r = 0, k;
+
+        assert(link);
+        assert(link->manager);
+        assert(link->manager->event);
+
+        if (!link->network)
+                return 0;
+
+        if (link->dhcp_client) {
+                k = sd_dhcp_client_stop(link->dhcp_client);
+                if (k < 0) {
+                        log_warning_link(link, "Could not stop DHCPv4 client: %s",
+                                         strerror(-r));
+                        r = k;
+                }
+        }
+
+        if (link->ipv4ll) {
+                k = sd_ipv4ll_stop(link->ipv4ll);
+                if (k < 0) {
+                        log_warning_link(link, "Could not stop IPv4 link-local: %s",
+                                         strerror(-r));
+                        r = k;
+                }
+        }
+
+        if (link->dhcp_server) {
+                k = sd_dhcp_server_stop(link->dhcp_server);
+                if (k < 0) {
+                        log_warning_link(link, "Could not stop DHCPv4 server: %s",
+                                         strerror(-r));
+                        r = k;
+                }
+        }
+
+        if(link->icmp6_router_discovery) {
+
+                if (link->dhcp6_client) {
+                        k = sd_dhcp6_client_stop(link->dhcp6_client);
+                        if (k < 0) {
+                                log_warning_link(link, "Could not stop DHCPv6 client: %s",
+                                                 strerror(-r));
+                                r = k;
+                        }
+                }
+
+                k = sd_icmp6_nd_stop(link->icmp6_router_discovery);
+                if (k < 0) {
+                        log_warning_link(link,
+                                         "Could not stop ICMPv6 router discovery: %s",
+                                         strerror(-r));
+                        r = k;
+                }
+        }
+
+        return r;
+}
+
+void link_enter_failed(Link *link) {
+        assert(link);
+
+        if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
+                return;
+
+        log_warning_link(link, "failed");
+
+        link->state = LINK_STATE_FAILED;
+
+        link_stop_clients(link);
+
+        link_save(link);
+}
+
+static Address* link_find_dhcp_server_address(Link *link) {
+        Address *address;
+
+        assert(link);
+        assert(link->network);
+
+        /* The the first statically configured address if there is any */
+        LIST_FOREACH(addresses, address, link->network->static_addresses) {
+
+                if (address->family != AF_INET)
+                        continue;
+
+                if (in_addr_is_null(address->family, &address->in_addr))
+                        continue;
+
+                return address;
+        }
+
+        /* If that didn't work, find a suitable address we got from the pool */
+        LIST_FOREACH(addresses, address, link->pool_addresses) {
+                if (address->family != AF_INET)
+                        continue;
+
+                return address;
+        }
+
+        return NULL;
 }
 
 static int link_enter_configured(Link *link) {
+        int r;
+
         assert(link);
+        assert(link->network);
         assert(link->state == LINK_STATE_SETTING_ROUTES);
 
+        if (link->network->dhcp_server &&
+            !sd_dhcp_server_is_running(link->dhcp_server)) {
+                struct in_addr pool_start;
+                Address *address;
+
+                address = link_find_dhcp_server_address(link);
+                if (!address) {
+                        log_warning_link(link,
+                                         "Failed to find suitable address for DHCPv4 server instance.");
+                        link_enter_failed(link);
+                        return 0;
+                }
+
+                log_debug_link(link, "offering DHCPv4 leases");
+
+                r = sd_dhcp_server_set_address(link->dhcp_server,
+                                               &address->in_addr.in,
+                                               address->prefixlen);
+                if (r < 0)
+                        return r;
+
+                /* offer 32 addresses starting from the address following the server address */
+                pool_start.s_addr = htobe32(be32toh(address->in_addr.in.s_addr) + 1);
+                r = sd_dhcp_server_set_lease_pool(link->dhcp_server,
+                                                  &pool_start, 32);
+                if (r < 0)
+                        return r;
+
+                /* TODO:
+                r = sd_dhcp_server_set_router(link->dhcp_server,
+                                              &main_address->in_addr.in);
+                if (r < 0)
+                        return r;
+
+                r = sd_dhcp_server_set_prefixlen(link->dhcp_server,
+                                                 main_address->prefixlen);
+                if (r < 0)
+                        return r;
+                */
+
+                r = sd_dhcp_server_start(link->dhcp_server);
+                if (r < 0) {
+                        log_warning_link(link, "could not start DHCPv4 server "
+                                         "instance: %s", strerror(-r));
+
+                        link_enter_failed(link);
+
+                        return 0;
+                }
+        }
+
         log_info_link(link, "link configured");
 
         link->state = LINK_STATE_CONFIGURED;
 
+        link_save(link);
+
         return 0;
 }
 
-static void link_enter_failed(Link *link) {
+void link_client_handler(Link *link) {
         assert(link);
+        assert(link->network);
 
-        log_warning_link(link, "failed");
+        if (!link->static_configured)
+                return;
 
-        link->state = LINK_STATE_FAILED;
+        if (link->network->ipv4ll)
+                if (!link->ipv4ll_address ||
+                    !link->ipv4ll_route)
+                        return;
+
+        if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V4))
+                if (!link->dhcp4_configured)
+                        return;
+
+        if (link->state != LINK_STATE_CONFIGURED)
+                link_enter_configured(link);
+
+        return;
 }
 
 static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
-        Link *link = userdata;
+        _cleanup_link_unref_ Link *link = userdata;
         int r;
 
-        assert(link->route_messages > 0);
-        assert(link->state == LINK_STATE_SETTING_ADDRESSES ||
-               link->state == LINK_STATE_SETTING_ROUTES ||
-               link->state == LINK_STATE_FAILED);
+        assert(link->link_messages > 0);
+        assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
+                      LINK_STATE_SETTING_ROUTES, LINK_STATE_FAILED,
+                      LINK_STATE_LINGER));
 
-        link->route_messages --;
+        link->link_messages --;
 
-        if (link->state == LINK_STATE_FAILED)
+        if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
                 return 1;
 
         r = sd_rtnl_message_get_errno(m);
         if (r < 0 && r != -EEXIST)
                 log_struct_link(LOG_WARNING, link,
-                                "MESSAGE=%s: could not set route: %s",
+                                "MESSAGE=%-*s: could not set route: %s",
+                                IFNAMSIZ,
                                 link->ifname, strerror(-r),
                                 "ERRNO=%d", -r,
                                 NULL);
 
-        /* we might have received an old reply after moving back to SETTING_ADDRESSES,
-         * ignore it */
-        if (link->route_messages == 0 && link->state == LINK_STATE_SETTING_ROUTES) {
+        if (link->link_messages == 0) {
                 log_debug_link(link, "routes set");
-                link_enter_configured(link);
+                link->static_configured = true;
+                link_client_handler(link);
         }
 
         return 1;
@@ -192,82 +428,109 @@ static int link_enter_set_routes(Link *link) {
 
         link->state = LINK_STATE_SETTING_ROUTES;
 
-        if (!link->network->static_routes && !link->dhcp_lease)
-                return link_enter_configured(link);
-
-        log_debug_link(link, "setting routes");
-
-        LIST_FOREACH(static_routes, rt, link->network->static_routes) {
+        LIST_FOREACH(routes, rt, link->network->static_routes) {
                 r = route_configure(rt, link, &route_handler);
                 if (r < 0) {
                         log_warning_link(link,
-                                         "could not set routes: %s", strerror(-r));
+                                         "could not set routes: %s",
+                                         strerror(-r));
                         link_enter_failed(link);
                         return r;
                 }
 
-                link->route_messages ++;
+                link->link_messages ++;
         }
 
-        if (link->dhcp_lease) {
-                _cleanup_route_free_ Route *route = NULL;
-                struct in_addr gateway;
+        if (link->link_messages == 0) {
+                link->static_configured = true;
+                link_client_handler(link);
+        } else
+                log_debug_link(link, "setting routes");
 
-                r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
-                if (r < 0) {
-                        log_warning_link(link, "DHCP error: no router: %s",
-                                         strerror(-r));
-                        return r;
-                }
+        return 0;
+}
 
-                r = route_new_dynamic(&route);
-                if (r < 0) {
-                        log_error_link(link, "Could not allocate route: %s",
-                                       strerror(-r));
-                        return r;
-                }
+int link_route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
+        _cleanup_link_unref_ Link *link = userdata;
+        int r;
+
+        assert(m);
+        assert(link);
+        assert(link->ifname);
 
-                route->family = AF_INET;
-                route->in_addr.in = gateway;
+        if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
+                return 1;
+
+        r = sd_rtnl_message_get_errno(m);
+        if (r < 0 && r != -ESRCH)
+                log_struct_link(LOG_WARNING, link,
+                                "MESSAGE=%-*s: could not drop route: %s",
+                                IFNAMSIZ,
+                                link->ifname, strerror(-r),
+                                "ERRNO=%d", -r,
+                                NULL);
+
+        return 1;
+}
+
+int link_get_address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
+        _cleanup_link_unref_ Link *link = userdata;
+        int r;
+
+        assert(rtnl);
+        assert(m);
+        assert(link);
+        assert(link->manager);
 
-                r = route_configure(route, link, &route_handler);
+        for (; m; m = sd_rtnl_message_next(m)) {
+                r = sd_rtnl_message_get_errno(m);
                 if (r < 0) {
-                        log_warning_link(link,
-                                         "could not set routes: %s", strerror(-r));
-                        link_enter_failed(link);
-                        return r;
+                        log_debug_link(link, "getting address failed: %s",
+                                       strerror(-r));
+                        continue;
                 }
 
-                link->route_messages ++;
+                r = link_rtnl_process_address(rtnl, m, link->manager);
+                if (r < 0)
+                        log_warning_link(link, "could not process address: %s",
+                                         strerror(-r));
         }
 
-        return 0;
+        return 1;
 }
 
 static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
-        Link *link = userdata;
+        _cleanup_link_unref_ Link *link = userdata;
         int r;
 
+        assert(rtnl);
         assert(m);
         assert(link);
         assert(link->ifname);
-        assert(link->addr_messages > 0);
-        assert(link->state == LINK_STATE_SETTING_ADDRESSES || link->state == LINK_STATE_FAILED);
+        assert(link->link_messages > 0);
+        assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
+               LINK_STATE_FAILED, LINK_STATE_LINGER));
 
-        link->addr_messages --;
+        link->link_messages --;
 
-        if (link->state == LINK_STATE_FAILED)
+        if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
                 return 1;
 
         r = sd_rtnl_message_get_errno(m);
         if (r < 0 && r != -EEXIST)
                 log_struct_link(LOG_WARNING, link,
-                                "MESSAGE=%s: could not set address: %s",
+                                "MESSAGE=%-*s: could not set address: %s",
+                                IFNAMSIZ,
                                 link->ifname, strerror(-r),
                                 "ERRNO=%d", -r,
                                 NULL);
+        else if (r >= 0) {
+                /* calling handler directly so take a ref */
+                link_ref(link);
+                link_get_address_handler(rtnl, m, link);
+        }
 
-        if (link->addr_messages == 0) {
+        if (link->link_messages == 0) {
                 log_debug_link(link, "addresses set");
                 link_enter_set_routes(link);
         }
@@ -285,86 +548,43 @@ static int link_enter_set_addresses(Link *link) {
 
         link->state = LINK_STATE_SETTING_ADDRESSES;
 
-        if (!link->network->static_addresses && !link->dhcp_lease)
-                return link_enter_set_routes(link);
-
-        log_debug_link(link, "setting addresses");
-
-        LIST_FOREACH(static_addresses, ad, link->network->static_addresses) {
+        LIST_FOREACH(addresses, ad, link->network->static_addresses) {
                 r = address_configure(ad, link, &address_handler);
                 if (r < 0) {
                         log_warning_link(link,
-                                         "could not set addresses: %s", strerror(-r));
-                        link_enter_failed(link);
-                        return r;
-                }
-
-                link->addr_messages ++;
-        }
-
-        if (link->dhcp_lease) {
-                _cleanup_address_free_ Address *address = NULL;
-                struct in_addr addr;
-                struct in_addr netmask;
-                unsigned prefixlen;
-
-                r = sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
-                if (r < 0) {
-                        log_warning_link(link, "DHCP error: no address: %s",
-                                         strerror(-r));
-                        return r;
-                }
-
-                r = sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
-                if (r < 0) {
-                        log_warning_link(link, "DHCP error: no netmask: %s",
+                                         "could not set addresses: %s",
                                          strerror(-r));
-                        return r;
-                }
-
-                prefixlen = net_netmask_to_prefixlen(&netmask);
-
-                r = address_new_dynamic(&address);
-                if (r < 0) {
-                        log_error_link(link, "Could not allocate address: %s",
-                                       strerror(-r));
-                        return r;
-                }
-
-                address->family = AF_INET;
-                address->in_addr.in = addr;
-                address->prefixlen = prefixlen;
-                address->broadcast.s_addr = addr.s_addr | ~netmask.s_addr;
-
-                r = address_configure(address, link, &address_handler);
-                if (r < 0) {
-                        log_warning_link(link,
-                                         "could not set addresses: %s", strerror(-r));
                         link_enter_failed(link);
                         return r;
                 }
 
-                link->addr_messages ++;
+                link->link_messages ++;
         }
 
+        if (link->link_messages == 0) {
+                link_enter_set_routes(link);
+        } else
+                log_debug_link(link, "setting addresses");
+
         return 0;
 }
 
-static int address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
-        Link *link = userdata;
+int link_address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
+        _cleanup_link_unref_ Link *link = userdata;
         int r;
 
         assert(m);
         assert(link);
         assert(link->ifname);
 
-        if (link->state == LINK_STATE_FAILED)
+        if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
                 return 1;
 
         r = sd_rtnl_message_get_errno(m);
-        if (r < 0 && r != -ENOENT)
+        if (r < 0 && r != -EADDRNOTAVAIL)
                 log_struct_link(LOG_WARNING, link,
-                                "MESSAGE=%s: could not drop address: %s",
+                                "MESSAGE=%-*s: could not drop address: %s",
+                                IFNAMSIZ,
                                 link->ifname, strerror(-r),
                                 "ERRNO=%d", -r,
                                 NULL);
@@ -372,31 +592,45 @@ static int address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdat
         return 1;
 }
 
-static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
+static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata,
+                                sd_bus_error *ret_error) {
+        _cleanup_link_unref_ Link *link = userdata;
         int r;
 
+        assert(link);
+
+        if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
+                return 1;
+
         r = sd_bus_message_get_errno(m);
         if (r < 0)
-                log_warning("Could not set hostname: %s", strerror(-r));
+                r = -r;
+        if (r > 0)
+                log_warning_link(link, "Could not set hostname: %s",
+                                 strerror(r));
 
         return 1;
 }
 
-static int set_hostname(sd_bus *bus, const char *hostname) {
+int link_set_hostname(Link *link, const char *hostname) {
         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
         int r = 0;
 
+        assert(link);
+        assert(link->manager);
         assert(hostname);
 
-        log_debug("Setting transient hostname: '%s'", hostname);
+        log_debug_link(link, "Setting transient hostname: '%s'", hostname);
 
-        if (!bus) { /* TODO: replace by assert when we can rely on kdbus */
-                log_info("Not connected to system bus, ignoring transient hostname.");
+        if (!link->manager->bus) {
+                /* TODO: replace by assert when we can rely on kdbus */
+                log_info_link(link,
+                              "Not connected to system bus, ignoring transient hostname.");
                 return 0;
         }
 
         r = sd_bus_message_new_method_call(
-                        bus,
+                        link->manager->bus,
                         &m,
                         "org.freedesktop.hostname1",
                         "/org/freedesktop/hostname1",
@@ -409,36 +643,42 @@ static int set_hostname(sd_bus *bus, const char *hostname) {
         if (r < 0)
                 return r;
 
-        r = sd_bus_call_async(bus, m, set_hostname_handler, NULL, 0, NULL);
-        if (r < 0)
-                log_error("Could not set transient hostname: %s", strerror(-r));
+        r = sd_bus_call_async(link->manager->bus, NULL, m, set_hostname_handler,
+                              link, 0);
+        if (r < 0) {
+                log_error_link(link, "Could not set transient hostname: %s",
+                               strerror(-r));
+                return r;
+        }
 
-        return r;
+        link_ref(link);
+
+        return 0;
 }
 
 static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
-        Link *link = userdata;
+        _cleanup_link_unref_ Link *link = userdata;
         int r;
 
         assert(m);
         assert(link);
         assert(link->ifname);
 
-        if (link->state == LINK_STATE_FAILED)
+        if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
                 return 1;
 
         r = sd_rtnl_message_get_errno(m);
         if (r < 0)
                 log_struct_link(LOG_WARNING, link,
-                                "MESSAGE=%s: could not set MTU: %s",
-                                link->ifname, strerror(-r),
+                                "MESSAGE=%-*s: could not set MTU: %s",
+                                IFNAMSIZ, link->ifname, strerror(-r),
                                 "ERRNO=%d", -r,
                                 NULL);
 
         return 1;
 }
 
-static int link_set_mtu(Link *link, uint32_t mtu) {
+int link_set_mtu(Link *link, uint32_t mtu) {
         _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
         int r;
 
@@ -461,347 +701,312 @@ static int link_set_mtu(Link *link, uint32_t mtu) {
                 return r;
         }
 
-        r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link, 0, NULL);
+        r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link,
+                               0, NULL);
         if (r < 0) {
                 log_error_link(link,
-                               "Could not send rtnetlink message: %s", strerror(-r));
+                               "Could not send rtnetlink message: %s",
+                               strerror(-r));
                 return r;
         }
 
+        link_ref(link);
+
         return 0;
 }
 
-static int dhcp_lease_lost(Link *link) {
-        _cleanup_address_free_ Address *address = NULL;
-        struct in_addr addr;
-        struct in_addr netmask;
-        unsigned prefixlen;
-        int r;
+static void dhcp6_handler(sd_dhcp6_client *client, int event, void *userdata) {
+        Link *link = userdata;
 
         assert(link);
-        assert(link->dhcp_lease);
+        assert(link->network);
+        assert(link->manager);
 
-        log_warning_link(link, "DHCP lease lost");
+        if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
+                return;
 
-        r = address_new_dynamic(&address);
-        if (r >= 0) {
-                sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
-                sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
-                prefixlen = net_netmask_to_prefixlen(&netmask);
-
-                address->family = AF_INET;
-                address->in_addr.in = addr;
-                address->prefixlen = prefixlen;
-
-                address_drop(address, link, address_drop_handler);
+        switch(event) {
+        case DHCP6_EVENT_STOP:
+        case DHCP6_EVENT_RESEND_EXPIRE:
+        case DHCP6_EVENT_RETRANS_MAX:
+        case DHCP6_EVENT_IP_ACQUIRE:
+                log_debug_link(link, "DHCPv6 event %d", event);
+
+                break;
+
+        default:
+                if (event < 0)
+                        log_warning_link(link, "DHCPv6 error: %s",
+                                         strerror(-event));
+                else
+                        log_warning_link(link, "DHCPv6 unknown event: %d",
+                                         event);
+                return;
         }
+}
 
-        if (link->network->dhcp_mtu) {
-                uint16_t mtu;
+static void icmp6_router_handler(sd_icmp6_nd *nd, int event, void *userdata) {
+        Link *link = userdata;
+        int r;
 
-                r = sd_dhcp_lease_get_mtu(link->dhcp_lease, &mtu);
-                if (r >= 0 && link->original_mtu != mtu) {
-                        r = link_set_mtu(link, link->original_mtu);
-                        if (r < 0) {
-                                log_warning_link(link, "DHCP error: could not reset MTU");
-                                link_enter_failed(link);
-                                return r;
-                        }
-                }
-        }
+        assert(link);
+        assert(link->network);
+        assert(link->manager);
 
-        if (link->network->dhcp_hostname) {
-                const char *hostname = NULL;
+        if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
+                return;
 
-                r = sd_dhcp_lease_get_hostname(link->dhcp_lease, &hostname);
-                if (r >= 0 && hostname) {
-                        r = set_hostname(link->manager->bus, "");
-                        if (r < 0)
-                                log_error("Failed to reset transient hostname");
-                }
-        }
+        switch(event) {
+        case ICMP6_EVENT_ROUTER_ADVERTISMENT_NONE:
+        case ICMP6_EVENT_ROUTER_ADVERTISMENT_OTHER:
+                return;
 
-        link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease);
+        case ICMP6_EVENT_ROUTER_ADVERTISMENT_TIMEOUT:
+        case ICMP6_EVENT_ROUTER_ADVERTISMENT_MANAGED:
+                break;
 
-        return 0;
-}
+        default:
+                if (event < 0)
+                        log_warning_link(link, "ICMPv6 error: %s",
+                                         strerror(-event));
+                else
+                        log_warning_link(link, "ICMPv6 unknown event: %d",
+                                         event);
 
-static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
-        sd_dhcp_lease *lease;
-        struct in_addr address;
-        struct in_addr netmask;
-        struct in_addr gateway;
-        unsigned prefixlen;
-        struct in_addr *nameservers;
-        size_t nameservers_size;
-        int r;
+                return;
+        }
 
-        assert(client);
-        assert(link);
+        if (link->dhcp6_client)
+                return;
 
-        r = sd_dhcp_client_get_lease(client, &lease);
-        if (r < 0) {
-                log_warning_link(link, "DHCP error: no lease: %s",
-                                 strerror(-r));
-                return r;
-        }
+        r = sd_dhcp6_client_new(&link->dhcp6_client);
+        if (r < 0)
+                return;
 
-        r = sd_dhcp_lease_get_address(lease, &address);
+        r = sd_dhcp6_client_attach_event(link->dhcp6_client, NULL, 0);
         if (r < 0) {
-                log_warning_link(link, "DHCP error: no address: %s",
-                                 strerror(-r));
-                return r;
+                link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
+                return;
         }
 
-        r = sd_dhcp_lease_get_netmask(lease, &netmask);
+        r = sd_dhcp6_client_set_mac(link->dhcp6_client, &link->mac);
         if (r < 0) {
-                log_warning_link(link, "DHCP error: no netmask: %s",
-                                 strerror(-r));
-                return r;
+                link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
+                return;
         }
 
-        prefixlen = net_netmask_to_prefixlen(&netmask);
-
-        r = sd_dhcp_lease_get_router(lease, &gateway);
+        r = sd_dhcp6_client_set_index(link->dhcp6_client, link->ifindex);
         if (r < 0) {
-                log_warning_link(link, "DHCP error: no router: %s",
-                                 strerror(-r));
-                return r;
-        }
-
-        log_struct_link(LOG_INFO, link,
-                        "MESSAGE=%s: DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
-                         link->ifname,
-                         ADDRESS_FMT_VAL(address),
-                         prefixlen,
-                         ADDRESS_FMT_VAL(gateway),
-                         "ADDRESS=%u.%u.%u.%u",
-                         ADDRESS_FMT_VAL(address),
-                         "PREFIXLEN=%u",
-                         prefixlen,
-                         "GATEWAY=%u.%u.%u.%u",
-                         ADDRESS_FMT_VAL(gateway),
-                         NULL);
-
-        link->dhcp_lease = lease;
-
-        if (link->network->dhcp_dns) {
-                r = sd_dhcp_lease_get_dns(lease, &nameservers, &nameservers_size);
-                if (r >= 0) {
-                        r = manager_update_resolv_conf(link->manager);
-                        if (r < 0)
-                                log_error("Failed to update resolv.conf");
-                }
-        }
-
-        if (link->network->dhcp_mtu) {
-                uint16_t mtu;
-
-                r = sd_dhcp_lease_get_mtu(lease, &mtu);
-                if (r >= 0) {
-                        r = link_set_mtu(link, mtu);
-                        if (r < 0)
-                                log_error_link(link, "Failed to set MTU "
-                                               "to %" PRIu16, mtu);
-                }
+                link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
+                return;
         }
 
-        if (link->network->dhcp_hostname) {
-                const char *hostname;
-
-                r = sd_dhcp_lease_get_hostname(lease, &hostname);
-                if (r >= 0) {
-                        r = set_hostname(link->manager->bus, hostname);
-                        if (r < 0)
-                                log_error("Failed to set transient hostname "
-                                          "to '%s'", hostname);
-                }
+        r = sd_dhcp6_client_set_callback(link->dhcp6_client, dhcp6_handler,
+                                         link);
+        if (r < 0) {
+                link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
+                return;
         }
 
-        link_enter_set_addresses(link);
-
-        return 0;
+        r = sd_dhcp6_client_start(link->dhcp6_client);
+        if (r < 0)
+                link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
 }
 
-static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
-        Link *link = userdata;
+static int link_acquire_conf(Link *link) {
         int r;
 
         assert(link);
         assert(link->network);
         assert(link->manager);
+        assert(link->manager->event);
 
-        if (link->state == LINK_STATE_FAILED)
-                return;
-
-        switch (event) {
-                case DHCP_EVENT_NO_LEASE:
-                        log_debug_link(link, "IP address in use.");
-                        break;
-                case DHCP_EVENT_EXPIRED:
-                case DHCP_EVENT_STOP:
-                case DHCP_EVENT_IP_CHANGE:
-                        if (link->network->dhcp_critical) {
-                                log_error_link(link, "DHCPv4 connection considered system critical, "
-                                               "ignoring request to reconfigure it.");
-                                return;
-                        }
-
-                        if (link->dhcp_lease) {
-                                r = dhcp_lease_lost(link);
-                                if (r < 0) {
-                                        link_enter_failed(link);
-                                        return;
-                                }
-                        }
+        if (link->network->ipv4ll) {
+                assert(link->ipv4ll);
 
-                        if (event == DHCP_EVENT_IP_CHANGE) {
-                                r = dhcp_lease_acquired(client, link);
-                                if (r < 0) {
-                                        link_enter_failed(link);
-                                        return;
-                                }
-                        }
+                log_debug_link(link, "acquiring IPv4 link-local address");
 
-                        break;
-                case DHCP_EVENT_IP_ACQUIRE:
-                        r = dhcp_lease_acquired(client, link);
-                        if (r < 0) {
-                                link_enter_failed(link);
-                                return;
-                        }
-                        break;
-                default:
-                        if (event < 0)
-                                log_warning_link(link, "DHCP error: %s", strerror(-event));
-                        else
-                                log_warning_link(link, "DHCP unknown event: %d", event);
-                        break;
+                r = sd_ipv4ll_start(link->ipv4ll);
+                if (r < 0) {
+                        log_warning_link(link, "could not acquire IPv4 "
+                                         "link-local address");
+                        return r;
+                }
         }
 
-        return;
-}
+        if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V4)) {
+                assert(link->dhcp_client);
 
-static int link_acquire_conf(Link *link) {
-        int r;
+                log_debug_link(link, "acquiring DHCPv4 lease");
 
-        assert(link);
-        assert(link->network);
-        assert(link->network->dhcp);
-        assert(link->manager);
-        assert(link->manager->event);
-
-        if (!link->dhcp_client) {
-                r = sd_dhcp_client_new(&link->dhcp_client);
-                if (r < 0)
-                        return r;
-
-                r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
-                if (r < 0)
+                r = sd_dhcp_client_start(link->dhcp_client);
+                if (r < 0) {
+                        log_warning_link(link, "could not acquire DHCPv4 "
+                                         "lease");
                         return r;
+                }
+        }
 
-                r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex);
-                if (r < 0)
-                        return r;
+        if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V6)) {
+                assert(link->icmp6_router_discovery);
 
-                r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
-                if (r < 0)
-                        return r;
+                log_debug_link(link, "discovering IPv6 routers");
 
-                r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp_handler, link);
-                if (r < 0)
+                r = sd_icmp6_router_solicitation_start(link->icmp6_router_discovery);
+                if (r < 0) {
+                        log_warning_link(link,
+                                         "could not start IPv6 router discovery");
                         return r;
-
-                if (link->network->dhcp_mtu) {
-                        r = sd_dhcp_client_set_request_option(link->dhcp_client, 26);
-                        if (r < 0)
-                                return r;
                 }
         }
 
-        log_debug_link(link, "acquiring DHCPv4 lease");
+        return 0;
+}
 
-        r = sd_dhcp_client_start(link->dhcp_client);
-        if (r < 0)
-                return r;
+bool link_has_carrier(unsigned flags, uint8_t operstate) {
+        /* see Documentation/networking/operstates.txt in the kernel sources */
 
-        return 0;
+        if (operstate == IF_OPER_UP)
+                return true;
+
+        if (operstate == IF_OPER_UNKNOWN)
+                /* operstate may not be implemented, so fall back to flags */
+                if ((flags & IFF_LOWER_UP) && !(flags & IFF_DORMANT))
+                        return true;
+
+        return false;
 }
 
-static int link_update_flags(Link *link, unsigned flags) {
+#define FLAG_STRING(string, flag, old, new) \
+        (((old ^ new) & flag) \
+                ? ((old & flag) ? (" -" string) : (" +" string)) \
+                : "")
+
+static int link_update_flags(Link *link, sd_rtnl_message *m) {
+        unsigned flags, unknown_flags_added, unknown_flags_removed, unknown_flags;
+        uint8_t operstate;
+        bool carrier_gained = false, carrier_lost = false;
         int r;
 
         assert(link);
-        assert(link->network);
 
-        if (link->state == LINK_STATE_FAILED)
-                return 0;
+        r = sd_rtnl_message_link_get_flags(m, &flags);
+        if (r < 0) {
+                log_warning_link(link, "Could not get link flags");
+                return r;
+        }
 
-        if (link->flags == flags) {
-                log_debug_link(link, "link status unchanged: %#.8x", flags);
+        r = sd_rtnl_message_read_u8(m, IFLA_OPERSTATE, &operstate);
+        if (r < 0)
+                /* if we got a message without operstate, take it to mean
+                   the state was unchanged */
+                operstate = link->kernel_operstate;
+
+        if ((link->flags == flags) && (link->kernel_operstate == operstate))
                 return 0;
+
+        if (link->flags != flags) {
+                log_debug_link(link, "flags change:%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
+                               FLAG_STRING("LOOPBACK", IFF_LOOPBACK, link->flags, flags),
+                               FLAG_STRING("MASTER", IFF_MASTER, link->flags, flags),
+                               FLAG_STRING("SLAVE", IFF_SLAVE, link->flags, flags),
+                               FLAG_STRING("UP", IFF_UP, link->flags, flags),
+                               FLAG_STRING("DORMANT", IFF_DORMANT, link->flags, flags),
+                               FLAG_STRING("LOWER_UP", IFF_LOWER_UP, link->flags, flags),
+                               FLAG_STRING("RUNNING", IFF_RUNNING, link->flags, flags),
+                               FLAG_STRING("MULTICAST", IFF_MULTICAST, link->flags, flags),
+                               FLAG_STRING("BROADCAST", IFF_BROADCAST, link->flags, flags),
+                               FLAG_STRING("POINTOPOINT", IFF_POINTOPOINT, link->flags, flags),
+                               FLAG_STRING("PROMISC", IFF_PROMISC, link->flags, flags),
+                               FLAG_STRING("ALLMULTI", IFF_ALLMULTI, link->flags, flags),
+                               FLAG_STRING("PORTSEL", IFF_PORTSEL, link->flags, flags),
+                               FLAG_STRING("AUTOMEDIA", IFF_AUTOMEDIA, link->flags, flags),
+                               FLAG_STRING("DYNAMIC", IFF_DYNAMIC, link->flags, flags),
+                               FLAG_STRING("NOARP", IFF_NOARP, link->flags, flags),
+                               FLAG_STRING("NOTRAILERS", IFF_NOTRAILERS, link->flags, flags),
+                               FLAG_STRING("DEBUG", IFF_DEBUG, link->flags, flags),
+                               FLAG_STRING("ECHO", IFF_ECHO, link->flags, flags));
+
+                unknown_flags = ~(IFF_LOOPBACK | IFF_MASTER | IFF_SLAVE | IFF_UP |
+                                  IFF_DORMANT | IFF_LOWER_UP | IFF_RUNNING |
+                                  IFF_MULTICAST | IFF_BROADCAST | IFF_POINTOPOINT |
+                                  IFF_PROMISC | IFF_ALLMULTI | IFF_PORTSEL |
+                                  IFF_AUTOMEDIA | IFF_DYNAMIC | IFF_NOARP |
+                                  IFF_NOTRAILERS | IFF_DEBUG | IFF_ECHO);
+                unknown_flags_added = ((link->flags ^ flags) & flags & unknown_flags);
+                unknown_flags_removed = ((link->flags ^ flags) & link->flags & unknown_flags);
+
+                /* link flags are currently at most 18 bits, let's align to
+                 * printing 20 */
+                if (unknown_flags_added)
+                        log_debug_link(link,
+                                       "unknown link flags gained: %#.5x (ignoring)",
+                                       unknown_flags_added);
+
+                if (unknown_flags_removed)
+                        log_debug_link(link,
+                                       "unknown link flags lost: %#.5x (ignoring)",
+                                       unknown_flags_removed);
         }
 
-        if ((link->flags & IFF_UP) != (flags & IFF_UP))
-                log_info_link(link,
-                              "link is %s", flags & IFF_UP ? "up": "down");
+        carrier_gained = !link_has_carrier(link->flags, link->kernel_operstate) &&
+                       link_has_carrier(flags, operstate);
+        carrier_lost = link_has_carrier(link->flags, link->kernel_operstate) &&
+                         !link_has_carrier(flags, operstate);
 
-        if ((link->flags & IFF_LOWER_UP) != (flags & IFF_LOWER_UP)) {
-                if (flags & IFF_LOWER_UP) {
-                        log_info_link(link, "carrier on");
+        link->flags = flags;
+        link->kernel_operstate = operstate;
 
-                        if (link->network->dhcp) {
-                                r = link_acquire_conf(link);
-                                if (r < 0) {
-                                        log_warning_link(link, "Could not acquire DHCPv4 lease: %s", strerror(-r));
-                                        link_enter_failed(link);
-                                        return r;
-                                }
-                        }
-                } else {
-                        log_info_link(link, "carrier off");
+        link_save(link);
 
-                        if (link->network->dhcp) {
-                                r = sd_dhcp_client_stop(link->dhcp_client);
-                                if (r < 0) {
-                                        log_warning_link(link, "Could not stop DHCPv4 client: %s", strerror(-r));
-                                        link_enter_failed(link);
-                                        return r;
-                                }
+        if (link->state == LINK_STATE_FAILED ||
+            link->state == LINK_STATE_UNMANAGED)
+                return 0;
+
+        if (carrier_gained) {
+                log_info_link(link, "gained carrier");
+
+                if (link->network) {
+                        r = link_acquire_conf(link);
+                        if (r < 0) {
+                                link_enter_failed(link);
+                                return r;
                         }
                 }
-        }
-
-        log_debug_link(link,
-                       "link status updated: %#.8x -> %#.8x", link->flags, flags);
+        } else if (carrier_lost) {
+                log_info_link(link, "lost carrier");
 
-        link->flags = flags;
+                r = link_stop_clients(link);
+                if (r < 0) {
+                        link_enter_failed(link);
+                        return r;
+                }
+        }
 
         return 0;
 }
 
 static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
-        Link *link = userdata;
+        _cleanup_link_unref_ Link *link = userdata;
         int r;
 
         assert(link);
 
-        if (link->state == LINK_STATE_FAILED)
+        if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
                 return 1;
 
         r = sd_rtnl_message_get_errno(m);
         if (r < 0) {
-                log_struct_link(LOG_ERR, link,
-                                "MESSAGE=%s: could not bring up interface: %s",
+                /* we warn but don't fail the link, as it may
+                   be brought up later */
+                log_struct_link(LOG_WARNING, link,
+                                "MESSAGE=%-*s: could not bring up interface: %s",
+                                IFNAMSIZ,
                                 link->ifname, strerror(-r),
                                 "ERRNO=%d", -r,
                                 NULL);
-                link_enter_failed(link);
-                return 1;
         }
 
-        link_update_flags(link, link->flags | IFF_UP);
-
         return 1;
 }
 
@@ -824,99 +1029,133 @@ static int link_up(Link *link) {
 
         r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
         if (r < 0) {
-                log_error_link(link, "Could not set link flags: %s", strerror(-r));
+                log_error_link(link, "Could not set link flags: %s",
+                               strerror(-r));
                 return r;
         }
 
-        r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
+        r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link,
+                               0, NULL);
         if (r < 0) {
                 log_error_link(link,
-                               "Could not send rtnetlink message: %s", strerror(-r));
+                               "Could not send rtnetlink message: %s",
+                               strerror(-r));
                 return r;
         }
 
+        link_ref(link);
+
         return 0;
 }
 
-static int link_enslaved(Link *link) {
+static int link_joined(Link *link) {
         int r;
 
         assert(link);
-        assert(link->state == LINK_STATE_ENSLAVING);
         assert(link->network);
 
-        r = link_up(link);
-        if (r < 0) {
-                link_enter_failed(link);
-                return r;
+        if (!(link->flags & IFF_UP)) {
+                r = link_up(link);
+                if (r < 0) {
+                        link_enter_failed(link);
+                        return r;
+                }
         }
 
-        if (!link->network->dhcp)
-                return link_enter_set_addresses(link);
-
-        return 0;
+        return link_enter_set_addresses(link);
 }
 
-static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
-        Link *link = userdata;
+static int netdev_join_handler(sd_rtnl *rtnl, sd_rtnl_message *m,
+                               void *userdata) {
+        _cleanup_link_unref_ Link *link = userdata;
         int r;
 
         assert(link);
-        assert(link->state == LINK_STATE_ENSLAVING || link->state == LINK_STATE_FAILED);
         assert(link->network);
 
         link->enslaving --;
 
-        if (link->state == LINK_STATE_FAILED)
+        if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
                 return 1;
 
         r = sd_rtnl_message_get_errno(m);
-        if (r < 0) {
+        if (r < 0 && r != -EEXIST) {
                 log_struct_link(LOG_ERR, link,
-                                "MESSAGE=%s: could not enslave: %s",
+                                "MESSAGE=%-*s: could not join netdev: %s",
+                                IFNAMSIZ,
                                 link->ifname, strerror(-r),
                                 "ERRNO=%d", -r,
                                 NULL);
                 link_enter_failed(link);
                 return 1;
-        }
+        } else
+                log_debug_link(link, "joined netdev");
 
-        log_debug_link(link, "enslaved");
-
-        if (link->enslaving == 0)
-                link_enslaved(link);
+        if (link->enslaving <= 0)
+                link_joined(link);
 
         return 1;
 }
 
-static int link_enter_enslave(Link *link) {
-        NetDev *vlan;
+static int link_enter_join_netdev(Link *link) {
+        NetDev *netdev;
         Iterator i;
         int r;
 
         assert(link);
         assert(link->network);
-        assert(link->state == _LINK_STATE_INVALID);
+        assert(link->state == LINK_STATE_PENDING);
 
         link->state = LINK_STATE_ENSLAVING;
 
-        if (!link->network->bridge && !link->network->bond &&
-            hashmap_isempty(link->network->vlans))
-                return link_enslaved(link);
+        link_save(link);
+
+        if (!link->network->bridge &&
+            !link->network->bond &&
+            hashmap_isempty(link->network->stacked_netdevs))
+                return link_joined(link);
+
+        if (link->network->bond) {
+                log_struct_link(LOG_DEBUG, link,
+                                "MESSAGE=%-*s: enslaving by '%s'",
+                                IFNAMSIZ,
+                                link->ifname, link->network->bond->ifname,
+                                NETDEVIF(link->network->bond),
+                                NULL);
+
+                r = netdev_join(link->network->bond, link, &netdev_join_handler);
+                if (r < 0) {
+                        log_struct_link(LOG_WARNING, link,
+                                        "MESSAGE=%-*s: could not join netdev '%s': %s",
+                                        IFNAMSIZ,
+                                        link->ifname, link->network->bond->ifname,
+                                        strerror(-r),
+                                        NETDEVIF(link->network->bond),
+                                        NULL);
+                        link_enter_failed(link);
+                        return r;
+                }
+
+                link->enslaving ++;
+        }
 
         if (link->network->bridge) {
                 log_struct_link(LOG_DEBUG, link,
-                                "MESSAGE=%s: enslaving by '%s'",
-                                link->ifname, link->network->bridge->name,
-                                NETDEV(link->network->bridge),
+                                "MESSAGE=%-*s: enslaving by '%s'",
+                                IFNAMSIZ,
+                                link->ifname, link->network->bridge->ifname,
+                                NETDEVIF(link->network->bridge),
                                 NULL);
 
-                r = netdev_enslave(link->network->bridge, link, &enslave_handler);
+                r = netdev_join(link->network->bridge, link,
+                                &netdev_join_handler);
                 if (r < 0) {
                         log_struct_link(LOG_WARNING, link,
-                                        "MESSAGE=%s: could not enslave by '%s': %s",
-                                        link->ifname, link->network->bridge->name, strerror(-r),
-                                        NETDEV(link->network->bridge),
+                                        "MESSAGE=%-*s: could not join netdev '%s': %s",
+                                        IFNAMSIZ,
+                                        link->ifname, link->network->bridge->ifname,
+                                        strerror(-r),
+                                        NETDEVIF(link->network->bridge),
                                         NULL);
                         link_enter_failed(link);
                         return r;
@@ -925,17 +1164,21 @@ static int link_enter_enslave(Link *link) {
                 link->enslaving ++;
         }
 
-        HASHMAP_FOREACH(vlan, link->network->vlans, i) {
+        HASHMAP_FOREACH(netdev, link->network->stacked_netdevs, i) {
                 log_struct_link(LOG_DEBUG, link,
-                                "MESSAGE=%s: enslaving by '%s'",
-                                link->ifname, vlan->name, NETDEV(vlan), NULL);
+                                "MESSAGE=%-*s: enslaving by '%s'",
+                                IFNAMSIZ,
+                                link->ifname, netdev->ifname, NETDEVIF(netdev),
+                                NULL);
 
-                r = netdev_enslave(vlan, link, &enslave_handler);
+                r = netdev_join(netdev, link, &netdev_join_handler);
                 if (r < 0) {
                         log_struct_link(LOG_WARNING, link,
-                                        "MESSAGE=%s: could not enslave by '%s': %s",
-                                        link->ifname, vlan->name, strerror(-r),
-                                        NETDEV(vlan), NULL);
+                                        "MESSAGE=%-*s: could not join netdev '%s': %s",
+                                        IFNAMSIZ,
+                                        link->ifname, netdev->ifname,
+                                        strerror(-r),
+                                        NETDEVIF(netdev), NULL);
                         link_enter_failed(link);
                         return r;
                 }
@@ -946,104 +1189,674 @@ static int link_enter_enslave(Link *link) {
         return 0;
 }
 
-static int link_getlink_handler(sd_rtnl *rtnl, sd_rtnl_message *m,
-                                void *userdata) {
-        Link *link = userdata;
+static int link_configure(Link *link) {
+        int r;
+
+        assert(link);
+        assert(link->network);
+        assert(link->state == LINK_STATE_PENDING);
+
+        if (link->network->ipv4ll) {
+                r = ipv4ll_configure(link);
+                if (r < 0)
+                        return r;
+        }
+
+        if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V4)) {
+                r = dhcp4_configure(link);
+                if (r < 0)
+                        return r;
+        }
+
+        if (link->network->dhcp_server) {
+                r = sd_dhcp_server_new(&link->dhcp_server, link->ifindex);
+                if (r < 0)
+                        return r;
+
+                r = sd_dhcp_server_attach_event(link->dhcp_server, NULL, 0);
+                if (r < 0)
+                        return r;
+        }
+
+        if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V6)) {
+                r = sd_icmp6_nd_new(&link->icmp6_router_discovery);
+                if (r < 0)
+                        return r;
+
+                r = sd_icmp6_nd_attach_event(link->icmp6_router_discovery,
+                                             NULL, 0);
+                if (r < 0)
+                        return r;
+
+                r = sd_icmp6_nd_set_mac(link->icmp6_router_discovery,
+                                        &link->mac);
+                if (r < 0)
+                        return r;
+
+                r = sd_icmp6_nd_set_index(link->icmp6_router_discovery,
+                                          link->ifindex);
+                if (r < 0)
+                        return r;
+
+                r = sd_icmp6_nd_set_callback(link->icmp6_router_discovery,
+                                             icmp6_router_handler, link);
+                if (r < 0)
+                        return r;
+        }
+
+        if (link_has_carrier(link->flags, link->kernel_operstate)) {
+                r = link_acquire_conf(link);
+                if (r < 0)
+                        return r;
+        }
+
+        return link_enter_join_netdev(link);
+}
+
+static int link_initialized_and_synced(sd_rtnl *rtnl, sd_rtnl_message *m,
+                                       void *userdata) {
+        _cleanup_link_unref_ Link *link = userdata;
+        Network *network;
         int r;
 
         assert(link);
+        assert(link->ifname);
+        assert(link->manager);
 
-        if (link->state == LINK_STATE_FAILED)
+        if (link->state != LINK_STATE_PENDING)
                 return 1;
 
-        r = sd_rtnl_message_get_errno(m);
-        if (r < 0) {
-                log_struct_link(LOG_ERR, link,
-                                "MESSAGE=%s: could not get state: %s",
-                                link->ifname, strerror(-r),
-                                "ERRNO=%d", -r,
-                                NULL);
-                link_enter_failed(link);
+        log_debug_link(link, "link state is up-to-date");
+
+        r = network_get(link->manager, link->udev_device, link->ifname,
+                        &link->mac, &network);
+        if (r == -ENOENT) {
+                link_enter_unmanaged(link);
                 return 1;
-        }
+        } else if (r < 0)
+                return r;
 
-        log_debug_link(link, "got link state");
+        r = network_apply(link->manager, network, link);
+        if (r < 0)
+                return r;
 
-        link_update(link, m);
+        r = link_configure(link);
+        if (r < 0)
+                return r;
 
         return 1;
 }
 
-static int link_getlink(Link *link) {
+int link_initialized(Link *link, struct udev_device *device) {
         _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
         int r;
 
         assert(link);
         assert(link->manager);
         assert(link->manager->rtnl);
+        assert(device);
 
-        log_debug_link(link, "requesting link status");
+        if (link->state != LINK_STATE_PENDING)
+                return 0;
 
-        r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
-                                     RTM_GETLINK, link->ifindex);
+        if (link->udev_device)
+                return 0;
+
+        log_debug_link(link, "udev initialized link");
+
+        link->udev_device = udev_device_ref(device);
+
+        /* udev has initialized the link, but we don't know if we have yet
+         * processed the NEWLINK messages with the latest state. Do a GETLINK,
+         * when it returns we know that the pending NEWLINKs have already been
+         * processed and that we are up-to-date */
+
+        r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_GETLINK,
+                                     link->ifindex);
+        if (r < 0)
+                return r;
+
+        r = sd_rtnl_call_async(link->manager->rtnl, req,
+                               link_initialized_and_synced, link, 0, NULL);
+        if (r < 0)
+                return r;
+
+        link_ref(link);
+
+        return 0;
+}
+
+int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message,
+                              void *userdata) {
+        Manager *m = userdata;
+        Link *link = NULL;
+        uint16_t type;
+        _cleanup_address_free_ Address *address = NULL;
+        Address *ad;
+        char buf[INET6_ADDRSTRLEN];
+        char valid_buf[FORMAT_TIMESPAN_MAX];
+        const char *valid_str = NULL;
+        bool address_dropped = false;
+        int r, ifindex;
+
+        assert(rtnl);
+        assert(message);
+        assert(m);
+
+        r = sd_rtnl_message_get_type(message, &type);
         if (r < 0) {
-                log_error_link(link, "Could not allocate RTM_GETLINK message");
+                log_warning("rtnl: could not get message type");
+                return 0;
+        }
+
+        r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
+        if (r < 0 || ifindex <= 0) {
+                log_warning("rtnl: received address message without valid ifindex, ignoring");
+                return 0;
+        } else {
+                r = link_get(m, ifindex, &link);
+                if (r < 0 || !link) {
+                        log_warning("rtnl: received address for a nonexistent link, ignoring");
+                        return 0;
+                }
+        }
+
+        r = address_new_dynamic(&address);
+        if (r < 0)
                 return r;
+
+        r = sd_rtnl_message_addr_get_family(message, &address->family);
+        if (r < 0 || !IN_SET(address->family, AF_INET, AF_INET6)) {
+                log_warning_link(link,
+                                 "rtnl: received address with invalid family, ignoring");
+                return 0;
         }
 
-        r = sd_rtnl_call_async(link->manager->rtnl, req, link_getlink_handler,
-                               link, 0, NULL);
+        r = sd_rtnl_message_addr_get_prefixlen(message, &address->prefixlen);
         if (r < 0) {
-                log_error_link(link,
-                               "Could not send rtnetlink message: %s", strerror(-r));
-                return r;
+                log_warning_link(link,
+                                 "rtnl: received address with invalid prefixlen, ignoring");
+                return 0;
         }
 
-        return 0;
+        r = sd_rtnl_message_addr_get_scope(message, &address->scope);
+        if (r < 0) {
+                log_warning_link(link,
+                                 "rtnl: received address with invalid scope, ignoring");
+                return 0;
+        }
+
+        r = sd_rtnl_message_addr_get_flags(message, &address->flags);
+        if (r < 0) {
+                log_warning_link(link,
+                                 "rtnl: received address with invalid flags, ignoring");
+                return 0;
+        }
+
+        switch (address->family) {
+        case AF_INET:
+                r = sd_rtnl_message_read_in_addr(message, IFA_LOCAL,
+                                                 &address->in_addr.in);
+                if (r < 0) {
+                        log_warning_link(link,
+                                         "rtnl: received address without valid address, ignoring");
+                        return 0;
+                }
+
+                break;
+
+        case AF_INET6:
+                r = sd_rtnl_message_read_in6_addr(message, IFA_ADDRESS,
+                                                  &address->in_addr.in6);
+                if (r < 0) {
+                        log_warning_link(link,
+                                         "rtnl: received address without valid address, ignoring");
+                        return 0;
+                }
+
+                break;
+
+        default:
+                assert_not_reached("invalid address family");
+        }
+
+        if (!inet_ntop(address->family, &address->in_addr, buf,
+                       INET6_ADDRSTRLEN)) {
+                log_warning_link(link, "could not print address");
+                return 0;
+        }
+
+        r = sd_rtnl_message_read_cache_info(message, IFA_CACHEINFO,
+                                            &address->cinfo);
+        if (r >= 0) {
+                if (address->cinfo.ifa_valid == CACHE_INFO_INFINITY_LIFE_TIME)
+                        valid_str = "ever";
+                else
+                        valid_str = format_timespan(valid_buf, FORMAT_TIMESPAN_MAX,
+                                                    address->cinfo.ifa_valid * USEC_PER_SEC,
+                                                    USEC_PER_SEC);
+        }
+
+        LIST_FOREACH(addresses, ad, link->addresses) {
+                if (address_equal(ad, address)) {
+                        LIST_REMOVE(addresses, link->addresses, ad);
+
+                        address_free(ad);
+
+                        address_dropped = true;
+
+                        break;
+                }
+        }
+
+        switch (type) {
+        case RTM_NEWADDR:
+                if (!address_dropped)
+                        log_debug_link(link, "added address: %s/%u (valid for %s)",
+                                       buf, address->prefixlen,
+                                       strna(valid_str));
+                else
+                        log_debug_link(link, "updated address: %s/%u (valid for %s)",
+                                       buf, address->prefixlen,
+                                       strna(valid_str));
+
+                LIST_PREPEND(addresses, link->addresses, address);
+                address = NULL;
+
+                link_save(link);
+
+                break;
+        case RTM_DELADDR:
+                if (address_dropped) {
+                        log_debug_link(link, "removed address: %s/%u (valid for %s)",
+                                       buf, address->prefixlen,
+                                       strna(valid_str));
+
+                        link_save(link);
+                } else
+                        log_warning_link(link,
+                                         "removing non-existent address: %s/%u (valid for %s)",
+                                         buf, address->prefixlen,
+                                         strna(valid_str));
+
+                break;
+        default:
+                assert_not_reached("Received invalid RTNL message type");
+        }
+
+        return 1;
 }
 
-int link_configure(Link *link) {
+int link_add(Manager *m, sd_rtnl_message *message, Link **ret) {
+        Link *link;
+        _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
+        _cleanup_udev_device_unref_ struct udev_device *device = NULL;
+        char ifindex_str[2 + DECIMAL_STR_MAX(int)];
         int r;
 
-        assert(link);
-        assert(link->network);
-        assert(link->state == _LINK_STATE_INVALID);
+        assert(m);
+        assert(m->rtnl);
+        assert(message);
+        assert(ret);
 
-        r = link_getlink(link);
-        if (r < 0) {
-                link_enter_failed(link);
+        r = link_new(m, message, ret);
+        if (r < 0)
+                return r;
+
+        link = *ret;
+
+        log_debug_link(link, "link %d added", link->ifindex);
+
+        r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, link->ifindex,
+                                     0);
+        if (r < 0)
+                return r;
+
+        r = sd_rtnl_call_async(m->rtnl, req, link_get_address_handler, link, 0,
+                               NULL);
+        if (r < 0)
                 return r;
+
+        link_ref(link);
+
+        if (detect_container(NULL) <= 0) {
+                /* not in a container, udev will be around */
+                sprintf(ifindex_str, "n%d", link->ifindex);
+                device = udev_device_new_from_device_id(m->udev, ifindex_str);
+                if (!device) {
+                        log_warning_link(link,
+                                         "could not find udev device: %m");
+                        return -errno;
+                }
+
+                if (udev_device_get_is_initialized(device) <= 0) {
+                        /* not yet ready */
+                        log_debug_link(link, "link pending udev initialization...");
+                        return 0;
+                }
+
+                r = link_initialized(link, device);
+                if (r < 0)
+                        return r;
+        } else {
+                /* we are calling a callback directly, so must take a ref */
+                link_ref(link);
+
+                r = link_initialized_and_synced(m->rtnl, NULL, link);
+                if (r < 0)
+                        return r;
         }
 
-        return link_enter_enslave(link);
+        return 0;
 }
 
 int link_update(Link *link, sd_rtnl_message *m) {
-        unsigned flags;
-        void *data;
-        uint16_t type;
+        struct ether_addr mac;
+        const char *ifname;
+        uint32_t mtu;
         int r;
 
         assert(link);
+        assert(link->ifname);
         assert(m);
 
-        if (link->state == LINK_STATE_FAILED)
-                return 0;
+        if (link->state == LINK_STATE_LINGER) {
+                link_ref(link);
+                log_info_link(link, "link readded");
+                link->state = LINK_STATE_ENSLAVING;
+        }
 
-        r = sd_rtnl_message_link_get_flags(m, &flags);
-        if (r < 0) {
-                log_warning_link(link, "Could not get link flags");
+        r = sd_rtnl_message_read_string(m, IFLA_IFNAME, &ifname);
+        if (r >= 0 && !streq(ifname, link->ifname)) {
+                log_info_link(link, "renamed to %s", ifname);
+
+                free(link->ifname);
+                link->ifname = strdup(ifname);
+                if (!link->ifname)
+                        return -ENOMEM;
+        }
+
+        r = sd_rtnl_message_read_u32(m, IFLA_MTU, &mtu);
+        if (r >= 0 && mtu > 0) {
+                link->mtu = mtu;
+                if (!link->original_mtu) {
+                        link->original_mtu = mtu;
+                        log_debug_link(link, "saved original MTU: %"
+                                       PRIu32, link->original_mtu);
+                }
+
+                if (link->dhcp_client) {
+                        r = sd_dhcp_client_set_mtu(link->dhcp_client,
+                                                   link->mtu);
+                        if (r < 0) {
+                                log_warning_link(link,
+                                                 "Could not update MTU in DHCP client: %s",
+                                                 strerror(-r));
+                                return r;
+                        }
+                }
+        }
+
+        /* The kernel may broadcast NEWLINK messages without the MAC address
+           set, simply ignore them. */
+        r = sd_rtnl_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
+        if (r >= 0) {
+                if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet,
+                           ETH_ALEN)) {
+
+                        memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet,
+                               ETH_ALEN);
+
+                        log_debug_link(link, "MAC address: "
+                                       "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
+                                       mac.ether_addr_octet[0],
+                                       mac.ether_addr_octet[1],
+                                       mac.ether_addr_octet[2],
+                                       mac.ether_addr_octet[3],
+                                       mac.ether_addr_octet[4],
+                                       mac.ether_addr_octet[5]);
+
+                        if (link->ipv4ll) {
+                                r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
+                                if (r < 0) {
+                                        log_warning_link(link,
+                                                         "Could not update MAC address in IPv4LL client: %s",
+                                                         strerror(-r));
+                                        return r;
+                                }
+                        }
+
+                        if (link->dhcp_client) {
+                                r = sd_dhcp_client_set_mac(link->dhcp_client,
+                                                           &link->mac);
+                                if (r < 0) {
+                                        log_warning_link(link,
+                                                         "Could not update MAC address in DHCP client: %s",
+                                                         strerror(-r));
+                                        return r;
+                                }
+                        }
+
+                        if (link->dhcp6_client) {
+                                r = sd_dhcp6_client_set_mac(link->dhcp6_client,
+                                                            &link->mac);
+                                if (r < 0) {
+                                        log_warning_link(link,
+                                                         "Could not update MAC address in DHCPv6 client: %s",
+                                                         strerror(-r));
+                                        return r;
+                                }
+                        }
+                }
+        }
+
+        return link_update_flags(link, m);
+}
+
+static void link_update_operstate(Link *link) {
+
+        assert(link);
+
+        if (link->kernel_operstate == IF_OPER_DORMANT)
+                link->operstate = LINK_OPERSTATE_DORMANT;
+        else if (link_has_carrier(link->flags, link->kernel_operstate)) {
+                Address *address;
+                uint8_t scope = RT_SCOPE_NOWHERE;
+
+                /* if we have carrier, check what addresses we have */
+                LIST_FOREACH(addresses, address, link->addresses) {
+                        if (address->flags & (IFA_F_TENTATIVE | IFA_F_DEPRECATED))
+                                continue;
+
+                        if (address->scope < scope)
+                                scope = address->scope;
+                }
+
+                if (scope < RT_SCOPE_SITE)
+                        /* universally accessible addresses found */
+                        link->operstate = LINK_OPERSTATE_ROUTABLE;
+                else if (scope < RT_SCOPE_HOST)
+                        /* only link or site local addresses found */
+                        link->operstate = LINK_OPERSTATE_DEGRADED;
+                else
+                        /* no useful addresses found */
+                        link->operstate = LINK_OPERSTATE_CARRIER;
+        } else if (link->flags & IFF_UP)
+                link->operstate = LINK_OPERSTATE_NO_CARRIER;
+        else
+                link->operstate = LINK_OPERSTATE_OFF;
+}
+
+int link_save(Link *link) {
+        _cleanup_free_ char *temp_path = NULL;
+        _cleanup_fclose_ FILE *f = NULL;
+        const char *admin_state, *oper_state;
+        int r;
+
+        assert(link);
+        assert(link->state_file);
+        assert(link->lease_file);
+        assert(link->manager);
+
+        link_update_operstate(link);
+
+        r = manager_save(link->manager);
+        if (r < 0)
                 return r;
+
+        if (link->state == LINK_STATE_LINGER) {
+                unlink(link->state_file);
+                return 0;
         }
 
-        while (sd_rtnl_message_read(m, &type, &data) > 0) {
-                if (type == IFLA_MTU && link->network->dhcp &&
-                    link->network->dhcp_mtu && !link->original_mtu) {
-                        link->original_mtu = *(uint16_t *) data;
-                        log_debug_link(link, "saved original MTU: %" PRIu16,
-                                       link->original_mtu);
+        admin_state = link_state_to_string(link->state);
+        assert(admin_state);
+
+        oper_state = link_operstate_to_string(link->operstate);
+        assert(oper_state);
+
+        r = fopen_temporary(link->state_file, &f, &temp_path);
+        if (r < 0)
+                return r;
+
+        fchmod(fileno(f), 0644);
+
+        fprintf(f,
+                "# This is private data. Do not parse.\n"
+                "ADMIN_STATE=%s\n"
+                "OPER_STATE=%s\n",
+                admin_state, oper_state);
+
+        if (link->network) {
+                char **address, **domain;
+                bool space;
+
+                fputs("DNS=", f);
+                space = false;
+                STRV_FOREACH(address, link->network->dns) {
+                        if (space)
+                                fputc(' ', f);
+                        fputs(*address, f);
+                        space = true;
                 }
+
+                if (link->network->dhcp_dns &&
+                    link->dhcp_lease) {
+                        const struct in_addr *addresses;
+
+                        r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
+                        if (r > 0) {
+                                if (space)
+                                        fputc(' ', f);
+                                serialize_in_addrs(f, addresses, r);
+                        }
+                }
+
+                fputs("\n", f);
+
+                fprintf(f, "NTP=");
+                space = false;
+                STRV_FOREACH(address, link->network->ntp) {
+                        if (space)
+                                fputc(' ', f);
+                        fputs(*address, f);
+                        space = true;
+                }
+
+                if (link->network->dhcp_ntp &&
+                    link->dhcp_lease) {
+                        const struct in_addr *addresses;
+
+                        r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
+                        if (r > 0) {
+                                if (space)
+                                        fputc(' ', f);
+                                serialize_in_addrs(f, addresses, r);
+                        }
+                }
+
+                fputs("\n", f);
+
+                fprintf(f, "DOMAINS=");
+                space = false;
+                STRV_FOREACH(domain, link->network->domains) {
+                        if (space)
+                                fputc(' ', f);
+                        fputs(*domain, f);
+                        space = true;
+                }
+
+                if (link->network->dhcp_domains &&
+                    link->dhcp_lease) {
+                        const char *domainname;
+
+                        r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
+                        if (r >= 0) {
+                                if (space)
+                                        fputc(' ', f);
+                                fputs(domainname, f);
+                        }
+                }
+
+                fputs("\n", f);
+
+                fprintf(f, "WILDCARD_DOMAIN=%s\n",
+                        yes_no(link->network->wildcard_domain));
+
+                fprintf(f, "LLMNR=%s\n",
+                        llmnr_support_to_string(link->network->llmnr));
         }
 
-        return link_update_flags(link, flags);
+        if (link->dhcp_lease) {
+                assert(link->network);
+
+                r = dhcp_lease_save(link->dhcp_lease, link->lease_file);
+                if (r < 0)
+                        goto fail;
+
+                fprintf(f,
+                        "DHCP_LEASE=%s\n",
+                        link->lease_file);
+        } else
+                unlink(link->lease_file);
+
+        r = fflush_and_check(f);
+        if (r < 0)
+                goto fail;
+
+        if (rename(temp_path, link->state_file) < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        return 0;
+fail:
+        log_error_link(link, "Failed to save link data to %s: %s", link->state_file, strerror(-r));
+        unlink(link->state_file);
+        unlink(temp_path);
+        return r;
 }
+
+static const char* const link_state_table[_LINK_STATE_MAX] = {
+        [LINK_STATE_PENDING] = "pending",
+        [LINK_STATE_ENSLAVING] = "configuring",
+        [LINK_STATE_SETTING_ADDRESSES] = "configuring",
+        [LINK_STATE_SETTING_ROUTES] = "configuring",
+        [LINK_STATE_CONFIGURED] = "configured",
+        [LINK_STATE_UNMANAGED] = "unmanaged",
+        [LINK_STATE_FAILED] = "failed",
+        [LINK_STATE_LINGER] = "linger",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);
+
+static const char* const link_operstate_table[_LINK_OPERSTATE_MAX] = {
+        [LINK_OPERSTATE_OFF] = "off",
+        [LINK_OPERSTATE_NO_CARRIER] = "no-carrier",
+        [LINK_OPERSTATE_DORMANT] = "dormant",
+        [LINK_OPERSTATE_CARRIER] = "carrier",
+        [LINK_OPERSTATE_DEGRADED] = "degraded",
+        [LINK_OPERSTATE_ROUTABLE] = "routable",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(link_operstate, LinkOperationalState);
diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h
new file mode 100644 (file)
index 0000000..0f73ec7
--- /dev/null
@@ -0,0 +1,148 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2013 Tom Gundersen <teg@jklm.no>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#pragma once
+
+#include "networkd.h"
+
+typedef enum LinkState {
+        LINK_STATE_PENDING,
+        LINK_STATE_ENSLAVING,
+        LINK_STATE_SETTING_ADDRESSES,
+        LINK_STATE_SETTING_ROUTES,
+        LINK_STATE_CONFIGURED,
+        LINK_STATE_UNMANAGED,
+        LINK_STATE_FAILED,
+        LINK_STATE_LINGER,
+        _LINK_STATE_MAX,
+        _LINK_STATE_INVALID = -1
+} LinkState;
+
+typedef enum LinkOperationalState {
+        LINK_OPERSTATE_OFF,
+        LINK_OPERSTATE_NO_CARRIER,
+        LINK_OPERSTATE_DORMANT,
+        LINK_OPERSTATE_CARRIER,
+        LINK_OPERSTATE_DEGRADED,
+        LINK_OPERSTATE_ROUTABLE,
+        _LINK_OPERSTATE_MAX,
+        _LINK_OPERSTATE_INVALID = -1
+} LinkOperationalState;
+
+struct Link {
+        Manager *manager;
+
+        int n_ref;
+
+        int ifindex;
+        char *ifname;
+        char *state_file;
+        struct ether_addr mac;
+        uint32_t mtu;
+        struct udev_device *udev_device;
+
+        unsigned flags;
+        uint8_t kernel_operstate;
+
+        Network *network;
+
+        LinkState state;
+        LinkOperationalState operstate;
+
+        unsigned link_messages;
+        unsigned enslaving;
+
+        LIST_HEAD(Address, addresses);
+
+        sd_dhcp_client *dhcp_client;
+        sd_dhcp_lease *dhcp_lease;
+        char *lease_file;
+        uint16_t original_mtu;
+        unsigned dhcp4_messages;
+        bool dhcp4_configured;
+
+        sd_ipv4ll *ipv4ll;
+        bool ipv4ll_address;
+        bool ipv4ll_route;
+
+        bool static_configured;
+
+        LIST_HEAD(Address, pool_addresses);
+
+        sd_dhcp_server *dhcp_server;
+
+        sd_icmp6_nd *icmp6_router_discovery;
+        sd_dhcp6_client *dhcp6_client;
+};
+
+Link *link_unref(Link *link);
+Link *link_ref(Link *link);
+int link_get(Manager *m, int ifindex, Link **ret);
+int link_add(Manager *manager, sd_rtnl_message *message, Link **ret);
+void link_drop(Link *link);
+
+int link_get_address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata);
+int link_address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata);
+int link_route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata);
+
+void link_enter_failed(Link *link);
+int link_initialized(Link *link, struct udev_device *device);
+
+void link_client_handler(Link *link);
+
+int link_update(Link *link, sd_rtnl_message *message);
+int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata);
+
+int link_save(Link *link);
+
+bool link_has_carrier(unsigned flags, uint8_t operstate);
+
+int link_set_mtu(Link *link, uint32_t mtu);
+int link_set_hostname(Link *link, const char *hostname);
+
+int ipv4ll_configure(Link *link);
+int dhcp4_configure(Link *link);
+
+const char* link_state_to_string(LinkState s) _const_;
+LinkState link_state_from_string(const char *s) _pure_;
+
+const char* link_operstate_to_string(LinkOperationalState s) _const_;
+LinkOperationalState link_operstate_from_string(const char *s) _pure_;
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(Link*, link_unref);
+#define _cleanup_link_unref_ _cleanup_(link_unrefp)
+
+/* Macros which append INTERFACE= to the message */
+
+#define log_full_link(level, link, fmt, ...) log_meta_object(level, __FILE__, __LINE__, __func__, "INTERFACE=", link->ifname, "%-*s: " fmt, IFNAMSIZ, link->ifname, ##__VA_ARGS__)
+#define log_debug_link(link, ...)       log_full_link(LOG_DEBUG, link, ##__VA_ARGS__)
+#define log_info_link(link, ...)        log_full_link(LOG_INFO, link, ##__VA_ARGS__)
+#define log_notice_link(link, ...)      log_full_link(LOG_NOTICE, link, ##__VA_ARGS__)
+#define log_warning_link(link, ...)     log_full_link(LOG_WARNING, link, ##__VA_ARGS__)
+#define log_error_link(link, ...)       log_full_link(LOG_ERR, link, ##__VA_ARGS__)
+
+#define log_struct_link(level, link, ...) log_struct(level, "INTERFACE=%s", link->ifname, __VA_ARGS__)
+
+#define ADDRESS_FMT_VAL(address)            \
+        (address).s_addr & 0xFF,            \
+        ((address).s_addr >> 8) & 0xFF,     \
+        ((address).s_addr >> 16) & 0xFF,    \
+        (address).s_addr >> 24
index c89adfb..f2fe5d5 100644 (file)
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
  ***/
 
-#include <resolv.h>
+#include <sys/socket.h>
+#include <linux/if.h>
 
+#include "conf-parser.h"
 #include "path-util.h"
 #include "networkd.h"
+#include "networkd-netdev.h"
+#include "networkd-link.h"
+#include "network-internal.h"
 #include "libudev-private.h"
 #include "udev-util.h"
 #include "rtnl-util.h"
 #include "mkdir.h"
 #include "virt.h"
 
+#include "sd-rtnl.h"
+
 const char* const network_dirs[] = {
         "/etc/systemd/network",
         "/run/systemd/network",
         "/usr/lib/systemd/network",
-#ifdef HAVE_SPLIT_USER
+#ifdef HAVE_SPLIT_USR
         "/lib/systemd/network",
 #endif
         NULL};
 
-static int dispatch_sigterm(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) {
-        Manager *m = userdata;
+static int setup_default_address_pool(Manager *m) {
+        AddressPool *p;
+        int r;
 
         assert(m);
 
-        log_received_signal(LOG_INFO, si);
-
-        sd_event_exit(m->event, 0);
-        return 0;
-}
-
-static int setup_signals(Manager *m) {
-        sigset_t mask;
-        int r;
+        /* Add in the well-known private address ranges. */
 
-        assert(m);
+        r = address_pool_new_from_string(m, &p, AF_INET6, "fc00::", 7);
+        if (r < 0)
+                return r;
 
-        assert_se(sigemptyset(&mask) == 0);
-        sigset_add_many(&mask, SIGINT, SIGTERM, -1);
-        assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
+        r = address_pool_new_from_string(m, &p, AF_INET, "192.168.0.0", 16);
+        if (r < 0)
+                return r;
 
-        r = sd_event_add_signal(m->event, &m->sigterm_event_source, SIGTERM, dispatch_sigterm, m);
+        r = address_pool_new_from_string(m, &p, AF_INET, "172.16.0.0", 12);
         if (r < 0)
                 return r;
 
-        r = sd_event_add_signal(m->event, &m->sigint_event_source, SIGINT, dispatch_sigterm, m);
+        r = address_pool_new_from_string(m, &p, AF_INET, "10.0.0.0", 8);
         if (r < 0)
                 return r;
 
@@ -78,13 +80,21 @@ int manager_new(Manager **ret) {
         if (!m)
                 return -ENOMEM;
 
+        m->state_file = strdup("/run/systemd/netif/state");
+        if (!m->state_file)
+                return -ENOMEM;
+
         r = sd_event_default(&m->event);
         if (r < 0)
                 return r;
 
         sd_event_set_watchdog(m->event, true);
 
-        r = sd_rtnl_open(&m->rtnl, RTMGRP_LINK | RTMGRP_IPV4_IFADDR);
+        sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL);
+        sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
+
+        r = sd_rtnl_open(&m->rtnl, 3, RTNLGRP_LINK, RTNLGRP_IPV4_IFADDR,
+                         RTNLGRP_IPV6_IFADDR);
         if (r < 0)
                 return r;
 
@@ -92,37 +102,29 @@ int manager_new(Manager **ret) {
         if (r < 0 && r != -ENOENT) /* TODO: drop when we can rely on kdbus */
                 return r;
 
-        r = setup_signals(m);
-        if (r < 0)
-                return r;
-
-        m->udev = udev_new();
-        if (!m->udev)
-                return -ENOMEM;
-
         /* udev does not initialize devices inside containers,
          * so we rely on them being already initialized before
          * entering the container */
-        if (detect_container(NULL) > 0) {
-                m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "kernel");
-                if (!m->udev_monitor)
+        if (detect_container(NULL) <= 0) {
+                m->udev = udev_new();
+                if (!m->udev)
                         return -ENOMEM;
-        } else {
+
                 m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
                 if (!m->udev_monitor)
                         return -ENOMEM;
         }
 
-        m->links = hashmap_new(uint64_hash_func, uint64_compare_func);
-        if (!m->links)
-                return -ENOMEM;
-
         m->netdevs = hashmap_new(string_hash_func, string_compare_func);
         if (!m->netdevs)
                 return -ENOMEM;
 
         LIST_HEAD_INIT(m->networks);
 
+        r = setup_default_address_pool(m);
+        if (r < 0)
+                return r;
+
         *ret = m;
         m = NULL;
 
@@ -133,10 +135,13 @@ void manager_free(Manager *m) {
         Network *network;
         NetDev *netdev;
         Link *link;
+        AddressPool *pool;
 
         if (!m)
                 return;
 
+        free(m->state_file);
+
         udev_monitor_unref(m->udev_monitor);
         udev_unref(m->udev);
         sd_bus_unref(m->bus);
@@ -145,17 +150,20 @@ void manager_free(Manager *m) {
         sd_event_source_unref(m->sigint_event_source);
         sd_event_unref(m->event);
 
-        while ((network = m->networks))
-                network_free(network);
-
         while ((link = hashmap_first(m->links)))
-                link_free(link);
+                link_unref(link);
         hashmap_free(m->links);
 
+        while ((network = m->networks))
+                network_free(network);
+
         while ((netdev = hashmap_first(m->netdevs)))
-                netdev_free(netdev);
+                netdev_unref(netdev);
         hashmap_free(m->netdevs);
 
+        while ((pool = m->address_pools))
+                address_pool_free(pool);
+
         sd_rtnl_unref(m->rtnl);
 
         free(m);
@@ -182,78 +190,138 @@ bool manager_should_reload(Manager *m) {
         return paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, false);
 }
 
-static int manager_process_link(Manager *m, struct udev_device *device) {
+static int manager_udev_process_link(Manager *m, struct udev_device *device) {
         Link *link = NULL;
-        int r;
+        int r, ifindex;
 
         assert(m);
         assert(device);
 
-        link_get(m, udev_device_get_ifindex(device), &link);
+        if (!streq_ptr(udev_device_get_action(device), "add"))
+                return 0;
 
-        if (streq_ptr(udev_device_get_action(device), "remove")) {
-                log_debug("%s: link removed", udev_device_get_sysname(device));
+        ifindex = udev_device_get_ifindex(device);
+        if (ifindex <= 0) {
+                log_debug("ignoring udev ADD event for device with invalid ifindex");
+                return 0;
+        }
 
-                if (link)
-                        link_free(link);
-        } else {
-                if (link) {
-                        log_debug("%s: link already exists, ignoring",
-                                  link->ifname);
-                        return 0;
-                }
+        r = link_get(m, ifindex, &link);
+        if (r == -ENODEV)
+                return 0;
+        else if (r < 0)
+                return r;
 
-                r = link_add(m, device, &link);
-                if (r < 0) {
-                        log_error("%s: could not handle link: %s",
-                                  udev_device_get_sysname(device),
-                                  strerror(-r));
-                } else
-                        log_debug("%s: link (with ifindex %" PRIu64") added",
-                                  link->ifname, link->ifindex);
-        }
+        r = link_initialized(link, device);
+        if (r < 0)
+                return r;
 
         return 0;
 }
 
-int manager_udev_enumerate_links(Manager *m) {
-        _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
-        struct udev_list_entry *item = NULL, *first = NULL;
-        int r;
+static int manager_rtnl_process_link(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
+        Manager *m = userdata;
+        Link *link = NULL;
+        NetDev *netdev = NULL;
+        uint16_t type;
+        const char *name;
+        int r, ifindex;
 
+        assert(rtnl);
+        assert(message);
         assert(m);
 
-        e = udev_enumerate_new(m->udev);
-        if (!e)
-                return -ENOMEM;
+        r = sd_rtnl_message_get_type(message, &type);
+        if (r < 0) {
+                log_warning("rtnl: could not get message type");
+                return 0;
+        }
 
-        r = udev_enumerate_add_match_subsystem(e, "net");
-        if (r < 0)
-                return r;
+        r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
+        if (r < 0 || ifindex <= 0) {
+                log_warning("rtnl: received link message without valid ifindex");
+                return 0;
+        } else
+                link_get(m, ifindex, &link);
 
-        /* udev does not initialize devices inside containers,
-         * so we rely on them being already initialized before
-         * entering the container */
-        if (detect_container(NULL) <= 0) {
-                r = udev_enumerate_add_match_is_initialized(e);
+        r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &name);
+        if (r < 0 || !name) {
+                log_warning("rtnl: received link message without valid ifname");
+                return 0;
+        } else
+                netdev_get(m, name, &netdev);
+
+        switch (type) {
+        case RTM_NEWLINK:
+                if (!link) {
+                        /* link is new, so add it */
+                        r = link_add(m, message, &link);
+                        if (r < 0) {
+                                log_debug("could not add new link: %s",
+                                           strerror(-r));
+                                return 0;
+                        }
+                }
+
+                if (netdev) {
+                        /* netdev exists, so make sure the ifindex matches */
+                        r = netdev_set_ifindex(netdev, message);
+                        if (r < 0) {
+                                log_debug("could not set ifindex on netdev");
+                                return 0;
+                        }
+                }
+
+                r = link_update(link, message);
                 if (r < 0)
-                        return r;
+                        return 0;
+
+                break;
+
+        case RTM_DELLINK:
+                link_drop(link);
+                netdev_drop(netdev);
+
+                break;
+
+        default:
+                assert_not_reached("Received invalid RTNL message type.");
         }
 
-        r = udev_enumerate_scan_devices(e);
+        return 1;
+}
+
+int manager_rtnl_enumerate_links(Manager *m) {
+        _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
+        sd_rtnl_message *link;
+        int r, k;
+
+        assert(m);
+        assert(m->rtnl);
+
+        r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
         if (r < 0)
                 return r;
 
-        first = udev_enumerate_get_list_entry(e);
-        udev_list_entry_foreach(item, first) {
-                _cleanup_udev_device_unref_ struct udev_device *d = NULL;
-                int k;
+        r = sd_rtnl_message_request_dump(req, true);
+        if (r < 0)
+                return r;
 
-                d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
-                if (!d)
-                        return -ENOMEM;
+        r = sd_rtnl_call(m->rtnl, req, 0, &reply);
+        if (r < 0)
+                return r;
+
+        for (link = reply; link; link = sd_rtnl_message_next(link)) {
+                uint16_t type;
 
-                k = manager_process_link(m, d);
+                k = sd_rtnl_message_get_type(link, &type);
+                if (k < 0)
+                        return k;
+
+                if (type != RTM_NEWLINK)
+                        continue;
+
+                k = manager_rtnl_process_link(m->rtnl, link, m);
                 if (k < 0)
                         r = k;
         }
@@ -270,13 +338,18 @@ static int manager_dispatch_link_udev(sd_event_source *source, int fd, uint32_t
         if (!device)
                 return -ENOMEM;
 
-        manager_process_link(m, device);
+        manager_udev_process_link(m, device);
         return 0;
 }
 
 int manager_udev_listen(Manager *m) {
         int r;
 
+        if (detect_container(NULL) > 0)
+                return 0;
+
+        assert(m->udev_monitor);
+
         r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_monitor, "net", NULL);
         if (r < 0) {
                 log_error("Could not add udev monitor filter: %s", strerror(-r));
@@ -300,62 +373,28 @@ int manager_udev_listen(Manager *m) {
         return 0;
 }
 
-static int manager_rtnl_process_link(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
-        Manager *m = userdata;
-        Link *link;
-        const char *name;
-        int r, ifindex;
+int manager_rtnl_listen(Manager *m) {
+        int r;
 
-        assert(rtnl);
-        assert(message);
         assert(m);
 
-        r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
-        if (r < 0 || ifindex <= 0) {
-                log_debug("received RTM_NEWLINK message without valid ifindex");
-                return 0;
-        }
-
-        r = rtnl_message_link_get_ifname(message, &name);
+        r = sd_rtnl_attach_event(m->rtnl, m->event, 0);
         if (r < 0)
-                log_debug("received RTM_NEWLINK message without valid IFLA_IFNAME");
-        else {
-                NetDev *netdev;
-
-                r = netdev_get(m, name, &netdev);
-                if (r >= 0) {
-                        r = netdev_set_ifindex(netdev, ifindex);
-                        if (r < 0)
-                                log_debug("could not set ifindex of netdev '%s' to %d: %s",
-                                          name, ifindex, strerror(-r));
-                }
-        }
-
-        r = link_get(m, ifindex, &link);
-        if (r < 0) {
-                log_debug("received RTM_NEWLINK message for untracked ifindex %d", ifindex);
-                return 0;
-        }
-
-        /* only track the status of links we want to manage */
-        if (link->network) {
-                r = link_update(link, message);
-                if (r < 0)
-                        return 0;
-        } else
-                log_debug("%s: received RTM_NEWLINK message for unmanaged link", link->ifname);
+                return r;
 
-        return 1;
-}
+        r = sd_rtnl_add_match(m->rtnl, RTM_NEWLINK, &manager_rtnl_process_link, m);
+        if (r < 0)
+                return r;
 
-int manager_rtnl_listen(Manager *m) {
-        int r;
+        r = sd_rtnl_add_match(m->rtnl, RTM_DELLINK, &manager_rtnl_process_link, m);
+        if (r < 0)
+                return r;
 
-        r = sd_rtnl_attach_event(m->rtnl, m->event, 0);
+        r = sd_rtnl_add_match(m->rtnl, RTM_NEWADDR, &link_rtnl_process_address, m);
         if (r < 0)
                 return r;
 
-        r = sd_rtnl_add_match(m->rtnl, RTM_NEWLINK, &manager_rtnl_process_link, m);
+        r = sd_rtnl_add_match(m->rtnl, RTM_DELADDR, &link_rtnl_process_address, m);
         if (r < 0)
                 return r;
 
@@ -377,87 +416,199 @@ int manager_bus_listen(Manager *m) {
         return 0;
 }
 
-static void append_dns(FILE *f, struct in_addr *dns, unsigned char family, unsigned *count) {
-        char buf[INET6_ADDRSTRLEN];
-        const char *address;
+static int set_put_in_addr(Set *s, const struct in_addr *address) {
+        char *p;
+        int r;
+
+        assert(s);
 
-        address = inet_ntop(family, dns, buf, INET6_ADDRSTRLEN);
-        if (!address) {
-                log_warning("Invalid DNS address. Ignoring.");
-                return;
+        r = in_addr_to_string(AF_INET, (const union in_addr_union*) address, &p);
+        if (r < 0)
+                return r;
+
+        r = set_consume(s, p);
+        if (r == -EEXIST)
+                return 0;
+
+        return r;
+}
+
+static int set_put_in_addrv(Set *s, const struct in_addr *addresses, int n) {
+        int r, i, c = 0;
+
+        assert(s);
+        assert(n <= 0 || addresses);
+
+        for (i = 0; i < n; i++) {
+                r = set_put_in_addr(s, addresses+i);
+                if (r < 0)
+                        return r;
+
+                c += r;
         }
 
-        if (*count == MAXNS)
-                fputs("# Too many DNS servers configured, the following entries "
-                      "will be ignored\n", f);
+        return c;
+}
+
+static void print_string_set(FILE *f, const char *field, Set *s) {
+        bool space = false;
+        Iterator i;
+        char *p;
+
+        if (set_isempty(s))
+                return;
 
-        fprintf(f, "nameserver %s\n", address);
+        fputs(field, f);
 
-        (*count) ++;
+        SET_FOREACH(p, s, i) {
+                if (space)
+                        fputc(' ', f);
+                fputs(p, f);
+                space = true;
+        }
+        fputc('\n', f);
 }
 
-int manager_update_resolv_conf(Manager *m) {
-        _cleanup_free_ char *temp_path = NULL;
-        _cleanup_fclose_ FILE *f = NULL;
+int manager_save(Manager *m) {
+        _cleanup_set_free_free_ Set *dns = NULL, *ntp = NULL, *domains = NULL;
         Link *link;
         Iterator i;
-        unsigned count = 0;
-        const char *domainname = NULL;
+        _cleanup_free_ char *temp_path = NULL;
+        _cleanup_fclose_ FILE *f = NULL;
+        LinkOperationalState operstate = LINK_OPERSTATE_OFF;
+        const char *operstate_str;
         int r;
 
         assert(m);
+        assert(m->state_file);
 
-        r = mkdir_safe_label("/run/systemd/network", 0755, 0, 0);
-        if (r < 0)
-                return r;
+        /* We add all NTP and DNS server to a set, to filter out duplicates */
+        dns = set_new(string_hash_func, string_compare_func);
+        if (!dns)
+                return -ENOMEM;
+
+        ntp = set_new(string_hash_func, string_compare_func);
+        if (!ntp)
+                return -ENOMEM;
+
+        domains = set_new(string_hash_func, string_compare_func);
+        if (!domains)
+                return -ENOMEM;
+
+        HASHMAP_FOREACH(link, m->links, i) {
+                if (link->flags & IFF_LOOPBACK)
+                        continue;
 
-        r = fopen_temporary("/run/systemd/network/resolv.conf", &f, &temp_path);
+                if (link->operstate > operstate)
+                        operstate = link->operstate;
+
+                if (!link->network)
+                        continue;
+
+                /* First add the static configured entries */
+                r = set_put_strdupv(dns, link->network->dns);
+                if (r < 0)
+                        return r;
+
+                r = set_put_strdupv(ntp, link->network->ntp);
+                if (r < 0)
+                        return r;
+
+                r = set_put_strdupv(domains, link->network->domains);
+                if (r < 0)
+                        return r;
+
+                if (!link->dhcp_lease)
+                        continue;
+
+                /* Secondly, add the entries acquired via DHCP */
+                if (link->network->dhcp_dns) {
+                        const struct in_addr *addresses;
+
+                        r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
+                        if (r > 0) {
+                                r = set_put_in_addrv(dns, addresses, r);
+                                if (r < 0)
+                                        return r;
+                        } else if (r < 0 && r != -ENOENT)
+                                return r;
+                }
+
+                if (link->network->dhcp_ntp) {
+                        const struct in_addr *addresses;
+
+                        r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
+                        if (r > 0) {
+                                r = set_put_in_addrv(ntp, addresses, r);
+                                if (r < 0)
+                                        return r;
+                        } else if (r < 0 && r != -ENOENT)
+                                return r;
+                }
+
+                if (link->network->dhcp_domains) {
+                        const char *domainname;
+
+                        r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
+                        if (r >= 0) {
+                                r = set_put_strdup(domains, domainname);
+                                if (r < 0)
+                                        return r;
+                        } else if (r != -ENOENT)
+                                return r;
+                }
+        }
+
+        operstate_str = link_operstate_to_string(operstate);
+        assert(operstate_str);
+
+        r = fopen_temporary(m->state_file, &f, &temp_path);
         if (r < 0)
                 return r;
 
         fchmod(fileno(f), 0644);
 
-        fputs("# This file is managed by systemd-networkd(8). Do not edit.\n#\n"
-              "# Third party programs must not access this file directly, but\n"
-              "# only through the symlink at /etc/resolv.conf. To manage\n"
-              "# resolv.conf(5) in a different way, replace the symlink by a\n"
-              "# static file or a different symlink.\n\n", f);
+        fprintf(f,
+                "# This is private data. Do not parse.\n"
+                "OPER_STATE=%s\n", operstate_str);
 
-        HASHMAP_FOREACH(link, m->links, i) {
-                if (link->dhcp_lease) {
-                        struct in_addr *nameservers;
-                        size_t nameservers_size;
-
-                        if (link->network->dhcp_dns) {
-                                r = sd_dhcp_lease_get_dns(link->dhcp_lease, &nameservers, &nameservers_size);
-                                if (r >= 0) {
-                                        unsigned j;
-
-                                        for (j = 0; j < nameservers_size; j++)
-                                                append_dns(f, &nameservers[j], AF_INET, &count);
-                                }
-                        }
+        print_string_set(f, "DNS=", dns);
+        print_string_set(f, "NTP=", ntp);
+        print_string_set(f, "DOMAINS=", domains);
 
-                        if (link->network->dhcp_domainname && !domainname) {
-                                r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
-                                if (r >= 0)
-                                       fprintf(f, "domain %s\n", domainname);
-                        }
-                }
+        r = fflush_and_check(f);
+        if (r < 0)
+                goto fail;
+
+        if (rename(temp_path, m->state_file) < 0) {
+                r = -errno;
+                goto fail;
         }
 
-        HASHMAP_FOREACH(link, m->links, i)
-                if (link->network && link->network->dns)
-                        append_dns(f, &link->network->dns->in_addr.in,
-                                   link->network->dns->family, &count);
+        return 0;
 
-        fflush(f);
+fail:
+        log_error("Failed to save network state to %s: %s", m->state_file, strerror(-r));
+        unlink(m->state_file);
+        unlink(temp_path);
+        return r;
+}
 
-        if (ferror(f) || rename(temp_path, "/run/systemd/network/resolv.conf") < 0) {
-                r = -errno;
-                unlink("/run/systemd/network/resolv.conf");
-                unlink(temp_path);
-                return r;
+int manager_address_pool_acquire(Manager *m, int family, unsigned prefixlen, union in_addr_union *found) {
+        AddressPool *p;
+        int r;
+
+        assert(m);
+        assert(prefixlen > 0);
+        assert(found);
+
+        LIST_FOREACH(address_pools, p, m->address_pools) {
+                if (p->family != family)
+                        continue;
+
+                r = address_pool_acquire(p, prefixlen, found);
+                if (r != 0)
+                        return r;
         }
 
         return 0;
diff --git a/src/network/networkd-netdev-bond.c b/src/network/networkd-netdev-bond.c
new file mode 100644 (file)
index 0000000..4640821
--- /dev/null
@@ -0,0 +1,198 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+    This file is part of systemd.
+
+    Copyright 2014  Tom Gundersen <teg@jklm.no>
+    Copyright 2014  Susant Sahani
+
+    systemd is free software; you can redistribute it and/or modify it
+    under the terms of the GNU Lesser General Public License as published by
+    the Free Software Foundation; either version 2.1 of the License, or
+    (at your option) any later version.
+
+    systemd is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <netinet/ether.h>
+#include <arpa/inet.h>
+#include <linux/if_bonding.h>
+
+#include "conf-parser.h"
+#include "sd-rtnl.h"
+#include "networkd-netdev-bond.h"
+#include "missing.h"
+
+static const char* const bond_mode_table[_NETDEV_BOND_MODE_MAX] = {
+        [NETDEV_BOND_MODE_BALANCE_RR] = "balance-rr",
+        [NETDEV_BOND_MODE_ACTIVE_BACKUP] = "active-backup",
+        [NETDEV_BOND_MODE_BALANCE_XOR] = "balance-xor",
+        [NETDEV_BOND_MODE_BROADCAST] = "broadcast",
+        [NETDEV_BOND_MODE_802_3AD] = "802.3ad",
+        [NETDEV_BOND_MODE_BALANCE_TLB] = "balance-tlb",
+        [NETDEV_BOND_MODE_BALANCE_ALB] = "balance-alb",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(bond_mode, BondMode);
+DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_mode, bond_mode, BondMode, "Failed to parse bond mode");
+
+
+static const char* const bond_xmit_hash_policy_table[_NETDEV_BOND_XMIT_HASH_POLICY_MAX] = {
+        [NETDEV_BOND_XMIT_HASH_POLICY_LAYER2] = "layer2",
+        [NETDEV_BOND_XMIT_HASH_POLICY_LAYER34] = "layer3+4",
+        [NETDEV_BOND_XMIT_HASH_POLICY_LAYER23] = "layer2+3",
+        [NETDEV_BOND_XMIT_HASH_POLICY_ENCAP23] = "encap2+3",
+        [NETDEV_BOND_XMIT_HASH_POLICY_ENCAP34] = "encap3+4",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(bond_xmit_hash_policy, BondXmitHashPolicy);
+DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_xmit_hash_policy,
+                         bond_xmit_hash_policy,
+                         BondXmitHashPolicy,
+                         "Failed to parse bond transmit hash policy")
+
+static const char* const bond_lacp_rate_table[_NETDEV_BOND_LACP_RATE_MAX] = {
+        [NETDEV_BOND_LACP_RATE_SLOW] = "slow",
+        [NETDEV_BOND_LACP_RATE_FAST] = "fast",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(bond_lacp_rate, BondLacpRate);
+DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_lacp_rate, bond_lacp_rate, BondLacpRate, "Failed to parse bond lacp rate")
+
+static uint8_t bond_mode_to_kernel(BondMode mode) {
+        switch (mode) {
+        case NETDEV_BOND_MODE_BALANCE_RR:
+                return BOND_MODE_ROUNDROBIN;
+        case NETDEV_BOND_MODE_ACTIVE_BACKUP:
+                return BOND_MODE_ACTIVEBACKUP;
+        case NETDEV_BOND_MODE_BALANCE_XOR:
+                return BOND_MODE_XOR;
+        case NETDEV_BOND_MODE_BROADCAST:
+                return BOND_MODE_BROADCAST;
+        case NETDEV_BOND_MODE_802_3AD:
+                return BOND_MODE_8023AD;
+        case NETDEV_BOND_MODE_BALANCE_TLB:
+                return BOND_MODE_TLB;
+        case NETDEV_BOND_MODE_BALANCE_ALB:
+                return BOND_MODE_ALB;
+        default:
+                return (uint8_t) -1;
+        }
+}
+
+static uint8_t bond_xmit_hash_policy_to_kernel(BondXmitHashPolicy policy) {
+        switch (policy) {
+        case NETDEV_BOND_XMIT_HASH_POLICY_LAYER2:
+                return BOND_XMIT_POLICY_LAYER2;
+        case NETDEV_BOND_XMIT_HASH_POLICY_LAYER34:
+                return BOND_XMIT_POLICY_LAYER34;
+        case NETDEV_BOND_XMIT_HASH_POLICY_LAYER23:
+                return BOND_XMIT_POLICY_LAYER23;
+        case NETDEV_BOND_XMIT_HASH_POLICY_ENCAP23:
+                return BOND_XMIT_POLICY_ENCAP23;
+        case NETDEV_BOND_XMIT_HASH_POLICY_ENCAP34:
+                return BOND_XMIT_POLICY_ENCAP34;
+        default:
+                return (uint8_t) -1;
+        }
+}
+
+static int netdev_bond_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
+        Bond *b = BOND(netdev);
+        int r;
+
+        assert(netdev);
+        assert(!link);
+        assert(b);
+        assert(m);
+
+        if (b->mode != _NETDEV_BOND_MODE_INVALID) {
+                r = sd_rtnl_message_append_u8(m, IFLA_BOND_MODE,
+                                              bond_mode_to_kernel(b->mode));
+                if (r < 0) {
+                        log_error_netdev(netdev,
+                                         "Could not append IFLA_BOND_MODE attribute: %s",
+                                         strerror(-r));
+                        return r;
+                }
+        }
+
+        if (b->xmit_hash_policy != _NETDEV_BOND_XMIT_HASH_POLICY_INVALID) {
+                r = sd_rtnl_message_append_u8(m, IFLA_BOND_XMIT_HASH_POLICY,
+                                              bond_xmit_hash_policy_to_kernel(b->xmit_hash_policy));
+                if (r < 0) {
+                        log_error_netdev(netdev,
+                                         "Could not append IFLA_BOND_XMIT_HASH_POLICY attribute: %s",
+                                         strerror(-r));
+                        return r;
+                }
+        }
+
+        if (b->lacp_rate != _NETDEV_BOND_LACP_RATE_INVALID &&
+            b->mode == NETDEV_BOND_MODE_802_3AD) {
+                r = sd_rtnl_message_append_u8(m, IFLA_BOND_AD_LACP_RATE, b->lacp_rate );
+                if (r < 0) {
+                        log_error_netdev(netdev,
+                                         "Could not append IFLA_BOND_AD_LACP_RATE attribute: %s",
+                                         strerror(-r));
+                        return r;
+                }
+        }
+
+        if (b->miimon != 0) {
+                r = sd_rtnl_message_append_u32(m, IFLA_BOND_MIIMON, b->miimon / USEC_PER_MSEC);
+                if (r < 0) {
+                        log_error_netdev(netdev,
+                                         "Could not append IFLA_BOND_BOND_MIIMON attribute: %s",
+                                         strerror(-r));
+                        return r;
+                }
+        }
+
+        if (b->downdelay != 0) {
+                r = sd_rtnl_message_append_u32(m, IFLA_BOND_DOWNDELAY, b->downdelay / USEC_PER_MSEC);
+                if (r < 0) {
+                        log_error_netdev(netdev,
+                                         "Could not append IFLA_BOND_DOWNDELAY attribute: %s",
+                                         strerror(-r));
+                        return r;
+                }
+        }
+
+        if (b->updelay != 0) {
+                r = sd_rtnl_message_append_u32(m, IFLA_BOND_UPDELAY, b->updelay / USEC_PER_MSEC);
+                if (r < 0) {
+                        log_error_netdev(netdev,
+                                         "Could not append IFLA_BOND_UPDELAY attribute: %s",
+                                         strerror(-r));
+                        return r;
+                }
+        }
+
+        return 0;
+}
+
+static void bond_init(NetDev *netdev) {
+        Bond *b = BOND(netdev);
+
+        assert(netdev);
+        assert(b);
+
+        b->mode = _NETDEV_BOND_MODE_INVALID;
+        b->xmit_hash_policy = _NETDEV_BOND_XMIT_HASH_POLICY_INVALID;
+        b->lacp_rate = _NETDEV_BOND_LACP_RATE_INVALID;
+}
+
+const NetDevVTable bond_vtable = {
+        .object_size = sizeof(Bond),
+        .init = bond_init,
+        .sections = "Match\0NetDev\0Bond\0",
+        .fill_message_create = netdev_bond_fill_message_create,
+        .create_type = NETDEV_CREATE_MASTER,
+};
diff --git a/src/network/networkd-netdev-bond.h b/src/network/networkd-netdev-bond.h
new file mode 100644 (file)
index 0000000..c09af5f
--- /dev/null
@@ -0,0 +1,83 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Tom Gundersen <teg@jklm.no>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#pragma once
+
+typedef struct Bond Bond;
+
+#include "networkd-netdev.h"
+
+typedef enum BondMode {
+        NETDEV_BOND_MODE_BALANCE_RR,
+        NETDEV_BOND_MODE_ACTIVE_BACKUP,
+        NETDEV_BOND_MODE_BALANCE_XOR,
+        NETDEV_BOND_MODE_BROADCAST,
+        NETDEV_BOND_MODE_802_3AD,
+        NETDEV_BOND_MODE_BALANCE_TLB,
+        NETDEV_BOND_MODE_BALANCE_ALB,
+        _NETDEV_BOND_MODE_MAX,
+        _NETDEV_BOND_MODE_INVALID = -1
+} BondMode;
+
+typedef enum BondXmitHashPolicy {
+        NETDEV_BOND_XMIT_HASH_POLICY_LAYER2,
+        NETDEV_BOND_XMIT_HASH_POLICY_LAYER34,
+        NETDEV_BOND_XMIT_HASH_POLICY_LAYER23,
+        NETDEV_BOND_XMIT_HASH_POLICY_ENCAP23,
+        NETDEV_BOND_XMIT_HASH_POLICY_ENCAP34,
+        _NETDEV_BOND_XMIT_HASH_POLICY_MAX,
+        _NETDEV_BOND_XMIT_HASH_POLICY_INVALID = -1
+} BondXmitHashPolicy;
+
+
+typedef enum BondLacpRate {
+        NETDEV_BOND_LACP_RATE_SLOW,
+        NETDEV_BOND_LACP_RATE_FAST,
+        _NETDEV_BOND_LACP_RATE_MAX,
+        _NETDEV_BOND_LACP_RATE_INVALID = -1,
+} BondLacpRate;
+
+struct Bond {
+        NetDev meta;
+
+        BondMode mode;
+        BondXmitHashPolicy xmit_hash_policy;
+        BondLacpRate lacp_rate;
+
+        usec_t miimon;
+        usec_t updelay;
+        usec_t downdelay;
+};
+
+extern const NetDevVTable bond_vtable;
+
+const char *bond_mode_to_string(BondMode d) _const_;
+BondMode bond_mode_from_string(const char *d) _pure_;
+
+const char *bond_xmit_hash_policy_to_string(BondXmitHashPolicy d) _const_;
+BondXmitHashPolicy bond_xmit_hash_policy_from_string(const char *d) _pure_;
+
+const char *bond_lacp_rate_to_string(BondLacpRate d) _const_;
+BondLacpRate bond_lacp_rate_from_string(const char *d) _pure_;
+
+int config_parse_bond_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_bond_xmit_hash_policy(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_bond_lacp_rate(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
diff --git a/src/network/networkd-netdev-bridge.c b/src/network/networkd-netdev-bridge.c
new file mode 100644 (file)
index 0000000..91b7051
--- /dev/null
@@ -0,0 +1,35 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+    This file is part of systemd.
+
+    Copyright 2014  Tom Gundersen <teg@jklm.no>
+    Copyright 2014  Susant Sahani
+
+    systemd is free software; you can redistribute it and/or modify it
+    under the terms of the GNU Lesser General Public License as published by
+    the Free Software Foundation; either version 2.1 of the License, or
+    (at your option) any later version.
+
+    systemd is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <netinet/ether.h>
+#include <arpa/inet.h>
+#include <net/if.h>
+
+#include "sd-rtnl.h"
+#include "networkd-netdev-bridge.h"
+#include "missing.h"
+
+const NetDevVTable bridge_vtable = {
+        .object_size = sizeof(Bridge),
+        .sections = "Match\0NetDev\0",
+        .create_type = NETDEV_CREATE_MASTER,
+};
diff --git a/src/network/networkd-netdev-bridge.h b/src/network/networkd-netdev-bridge.h
new file mode 100644 (file)
index 0000000..a7d02b1
--- /dev/null
@@ -0,0 +1,32 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Tom Gundersen <teg@jklm.no>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#pragma once
+
+typedef struct Bridge Bridge;
+
+#include "networkd-netdev.h"
+
+struct Bridge {
+        NetDev meta;
+};
+
+extern const NetDevVTable bridge_vtable;
diff --git a/src/network/networkd-netdev-dummy.c b/src/network/networkd-netdev-dummy.c
new file mode 100644 (file)
index 0000000..01c10a2
--- /dev/null
@@ -0,0 +1,35 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+    This file is part of systemd.
+
+    Copyright 2014 Susant Sahani <susant@redhat.com>
+    Copyright 2014 Tom Gundersen
+
+    systemd is free software; you can redistribute it and/or modify it
+    under the terms of the GNU Lesser General Public License as published by
+    the Free Software Foundation; either version 2.1 of the License, or
+    (at your option) any later version.
+
+    systemd is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <netinet/ether.h>
+#include <arpa/inet.h>
+#include <net/if.h>
+#include <linux/veth.h>
+
+#include "sd-rtnl.h"
+#include "networkd-netdev-dummy.h"
+
+const NetDevVTable dummy_vtable = {
+        .object_size = sizeof(Dummy),
+        .sections = "Match\0NetDev\0",
+        .create_type = NETDEV_CREATE_INDEPENDENT,
+};
diff --git a/src/network/networkd-netdev-dummy.h b/src/network/networkd-netdev-dummy.h
new file mode 100644 (file)
index 0000000..0d321e5
--- /dev/null
@@ -0,0 +1,32 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Tom Gundersen <teg@jklm.no>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#pragma once
+
+typedef struct Dummy Dummy;
+
+#include "networkd-netdev.h"
+
+struct Dummy {
+        NetDev meta;
+};
+
+extern const NetDevVTable dummy_vtable;
index 7dd47f9..c524ee5 100644 (file)
@@ -1,8 +1,11 @@
 %{
 #include <stddef.h>
 #include "conf-parser.h"
-#include "networkd.h"
-#include "net-util.h"
+#include "networkd-netdev.h"
+#include "networkd-netdev-tunnel.h"
+#include "networkd-netdev-bond.h"
+#include "networkd-netdev-macvlan.h"
+#include "network-internal.h"
 %}
 struct ConfigPerfItem;
 %null_strings
@@ -20,6 +23,37 @@ Match.Virtualization,    config_parse_net_condition,         CONDITION_VIRTUALIZ
 Match.KernelCommandLine, config_parse_net_condition,         CONDITION_KERNEL_COMMAND_LINE, offsetof(NetDev, match_kernel)
 Match.Architecture,      config_parse_net_condition,         CONDITION_ARCHITECTURE,        offsetof(NetDev, match_arch)
 NetDev.Description,      config_parse_string,                0,                             offsetof(NetDev, description)
-NetDev.Name,             config_parse_ifname,                0,                             offsetof(NetDev, name)
+NetDev.Name,             config_parse_ifname,                0,                             offsetof(NetDev, ifname)
 NetDev.Kind,             config_parse_netdev_kind,           0,                             offsetof(NetDev, kind)
-VLAN.Id,                 config_parse_uint64,                0,                             offsetof(NetDev, vlanid)
+NetDev.MTUBytes,         config_parse_iec_size,              0,                             offsetof(NetDev, mtu)
+NetDev.MACAddress,       config_parse_hwaddr,                0,                             offsetof(NetDev, mac)
+VLAN.Id,                 config_parse_uint64,                0,                             offsetof(VLan, id)
+MACVLAN.Mode,            config_parse_macvlan_mode,          0,                             offsetof(MacVlan, mode)
+Tunnel.Local,            config_parse_tunnel_address,        0,                             offsetof(Tunnel, local)
+Tunnel.Remote,           config_parse_tunnel_address,        0,                             offsetof(Tunnel, remote)
+Tunnel.TOS,              config_parse_unsigned,              0,                             offsetof(Tunnel, tos)
+Tunnel.TTL,              config_parse_unsigned,              0,                             offsetof(Tunnel, ttl)
+Tunnel.DiscoverPathMTU,  config_parse_bool,                  0,                             offsetof(Tunnel, pmtudisc)
+Peer.Name,               config_parse_ifname,                0,                             offsetof(Veth, ifname_peer)
+Peer.MACAddress,         config_parse_hwaddr,                0,                             offsetof(Veth, mac_peer)
+VXLAN.Id,                config_parse_uint64,                0,                             offsetof(VxLan, id)
+VXLAN.Group,             config_parse_tunnel_address,        0,                             offsetof(VxLan, group)
+VXLAN.TOS,               config_parse_unsigned,              0,                             offsetof(VxLan, tos)
+VXLAN.TTL,               config_parse_unsigned,              0,                             offsetof(VxLan, ttl)
+VXLAN.MacLearning,       config_parse_bool,                  0,                             offsetof(VxLan, learning)
+Tun.OneQueue,            config_parse_bool,                  0,                             offsetof(TunTap, one_queue)
+Tun.MultiQueue,          config_parse_bool,                  0,                             offsetof(TunTap, multi_queue)
+Tun.PacketInfo,          config_parse_bool,                  0,                             offsetof(TunTap, packet_info)
+Tun.User,                config_parse_string,                0,                             offsetof(TunTap, user_name)
+Tun.Group,               config_parse_string,                0,                             offsetof(TunTap, group_name)
+Tap.OneQueue,            config_parse_bool,                  0,                             offsetof(TunTap, one_queue)
+Tap.MultiQueue,          config_parse_bool,                  0,                             offsetof(TunTap, multi_queue)
+Tap.PacketInfo,          config_parse_bool,                  0,                             offsetof(TunTap, packet_info)
+Tap.User,                config_parse_string,                0,                             offsetof(TunTap, user_name)
+Tap.Group,               config_parse_string,                0,                             offsetof(TunTap, group_name)
+Bond.Mode,               config_parse_bond_mode,             0,                             offsetof(Bond, mode)
+Bond.TransmitHashPolicy, config_parse_bond_xmit_hash_policy, 0,                             offsetof(Bond, xmit_hash_policy)
+Bond.LACPTransmitRate,   config_parse_bond_lacp_rate,        0,                             offsetof(Bond, lacp_rate)
+Bond.MIIMonitorSec,      config_parse_sec,                   0,                             offsetof(Bond, miimon)
+Bond.UpDelaySec,         config_parse_sec,                   0,                             offsetof(Bond, updelay)
+Bond.DownDelaySec,       config_parse_sec,                   0,                             offsetof(Bond, downdelay)
diff --git a/src/network/networkd-netdev-macvlan.c b/src/network/networkd-netdev-macvlan.c
new file mode 100644 (file)
index 0000000..2e5554a
--- /dev/null
@@ -0,0 +1,76 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2013 Tom Gundersen <teg@jklm.no>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <net/if.h>
+
+#include "networkd-netdev-macvlan.h"
+#include "network-internal.h"
+#include "conf-parser.h"
+#include "list.h"
+
+static const char* const macvlan_mode_table[_NETDEV_MACVLAN_MODE_MAX] = {
+        [NETDEV_MACVLAN_MODE_PRIVATE] = "private",
+        [NETDEV_MACVLAN_MODE_VEPA] = "vepa",
+        [NETDEV_MACVLAN_MODE_BRIDGE] = "bridge",
+        [NETDEV_MACVLAN_MODE_PASSTHRU] = "passthru",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(macvlan_mode, MacVlanMode);
+DEFINE_CONFIG_PARSE_ENUM(config_parse_macvlan_mode, macvlan_mode, MacVlanMode, "Failed to parse macvlan mode");
+
+static int netdev_macvlan_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *req) {
+        MacVlan *m = MACVLAN(netdev);
+        int r;
+
+        assert(netdev);
+        assert(m);
+        assert(link);
+        assert(netdev->ifname);
+
+        if (m->mode != _NETDEV_MACVLAN_MODE_INVALID) {
+        r = sd_rtnl_message_append_u32(req, IFLA_MACVLAN_MODE, m->mode);
+        if (r < 0) {
+                log_error_netdev(netdev,
+                                 "Could not append IFLA_MACVLAN_MODE attribute: %s",
+                                 strerror(-r));
+                        return r;
+                }
+        }
+
+        return 0;
+}
+
+static void macvlan_init(NetDev *n) {
+        MacVlan *m = MACVLAN(n);
+
+        assert(n);
+        assert(m);
+
+        m->mode = _NETDEV_MACVLAN_MODE_INVALID;
+}
+
+const NetDevVTable macvlan_vtable = {
+        .object_size = sizeof(MacVlan),
+        .init = macvlan_init,
+        .sections = "Match\0NetDev\0MACVLAN\0",
+        .fill_message_create = netdev_macvlan_fill_message_create,
+        .create_type = NETDEV_CREATE_STACKED,
+};
diff --git a/src/network/networkd-netdev-macvlan.h b/src/network/networkd-netdev-macvlan.h
new file mode 100644 (file)
index 0000000..d61efc1
--- /dev/null
@@ -0,0 +1,48 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Tom Gundersen <teg@jklm.no>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#pragma once
+
+typedef struct MacVlan MacVlan;
+
+#include "networkd-netdev.h"
+
+typedef enum MacVlanMode {
+        NETDEV_MACVLAN_MODE_PRIVATE = MACVLAN_MODE_PRIVATE,
+        NETDEV_MACVLAN_MODE_VEPA = MACVLAN_MODE_VEPA,
+        NETDEV_MACVLAN_MODE_BRIDGE = MACVLAN_MODE_BRIDGE,
+        NETDEV_MACVLAN_MODE_PASSTHRU = MACVLAN_MODE_PASSTHRU,
+        _NETDEV_MACVLAN_MODE_MAX,
+        _NETDEV_MACVLAN_MODE_INVALID = -1
+} MacVlanMode;
+
+struct MacVlan {
+        NetDev meta;
+
+        MacVlanMode mode;
+};
+
+extern const NetDevVTable macvlan_vtable;
+
+const char *macvlan_mode_to_string(MacVlanMode d) _const_;
+MacVlanMode macvlan_mode_from_string(const char *d) _pure_;
+
+int config_parse_macvlan_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
diff --git a/src/network/networkd-netdev-tunnel.c b/src/network/networkd-netdev-tunnel.c
new file mode 100644 (file)
index 0000000..174fe23
--- /dev/null
@@ -0,0 +1,365 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+    This file is part of systemd.
+
+    Copyright 2014 Susant Sahani <susant@redhat.com>
+
+    systemd is free software; you can redistribute it and/or modify it
+    under the terms of the GNU Lesser General Public License as published by
+    the Free Software Foundation; either version 2.1 of the License, or
+    (at your option) any later version.
+
+    systemd is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <netinet/ether.h>
+#include <arpa/inet.h>
+#include <net/if.h>
+#include <linux/ip.h>
+#include <linux/if_tunnel.h>
+
+#include "sd-rtnl.h"
+#include "networkd-netdev-tunnel.h"
+#include "networkd-link.h"
+#include "network-internal.h"
+#include "util.h"
+#include "missing.h"
+#include "conf-parser.h"
+
+static int netdev_ipip_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
+        Tunnel *t = IPIP(netdev);
+        int r;
+
+        assert(netdev);
+        assert(link);
+        assert(m);
+        assert(t);
+        assert(t->family == AF_INET);
+
+        r = sd_rtnl_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex);
+        if (r < 0) {
+                log_error_netdev(netdev,
+                                 "Could not append IFLA_IPTUN_LINK attribute: %s",
+                                 strerror(-r));
+                return r;
+        }
+
+        r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &t->local.in);
+        if (r < 0) {
+                log_error_netdev(netdev,
+                                 "Could not append IFLA_IPTUN_LOCAL attribute: %s",
+                                 strerror(-r));
+                return r;
+        }
+
+        r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_REMOTE, &t->remote.in);
+        if (r < 0) {
+                log_error_netdev(netdev,
+                                 "Could not append IFLA_IPTUN_REMOTE attribute: %s",
+                                 strerror(-r));
+                return r;
+        }
+
+        r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_TTL, t->ttl);
+        if (r < 0) {
+                log_error_netdev(netdev,
+                                 "Could not append IFLA_IPTUN_TTL  attribute: %s",
+                                 strerror(-r));
+                return r;
+        }
+
+        return r;
+}
+
+static int netdev_sit_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
+        Tunnel *t = SIT(netdev);
+        int r;
+
+        assert(netdev);
+        assert(link);
+        assert(m);
+        assert(t);
+        assert(t->family == AF_INET);
+
+        r = sd_rtnl_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex);
+        if (r < 0) {
+                log_error_netdev(netdev,
+                                 "Could not append IFLA_IPTUN_LINK attribute: %s",
+                                 strerror(-r));
+                return r;
+        }
+
+        r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &t->local.in);
+        if (r < 0) {
+                log_error_netdev(netdev,
+                                 "Could not append IFLA_IPTUN_LOCAL attribute: %s",
+                                 strerror(-r));
+                return r;
+        }
+
+        r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_REMOTE, &t->remote.in);
+        if (r < 0) {
+                log_error_netdev(netdev,
+                                 "Could not append IFLA_IPTUN_REMOTE attribute: %s",
+                                 strerror(-r));
+                return r;
+        }
+
+        r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_TTL, t->ttl);
+        if (r < 0) {
+                log_error_netdev(netdev,
+                                 "Could not append IFLA_IPTUN_TTL attribute: %s",
+                                 strerror(-r));
+                return r;
+        }
+
+        return r;
+}
+
+static int netdev_gre_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
+        Tunnel *t = GRE(netdev);
+        int r;
+
+        assert(netdev);
+        assert(link);
+        assert(m);
+        assert(t);
+        assert(t->family == AF_INET);
+
+        r = sd_rtnl_message_append_u32(m, IFLA_GRE_LINK, link->ifindex);
+        if (r < 0) {
+                log_error_netdev(netdev,
+                                 "Could not append IFLA_GRE_LINK attribute: %s",
+                                 strerror(-r));
+                return r;
+        }
+
+        r = sd_rtnl_message_append_in_addr(m, IFLA_GRE_LOCAL, &t->local.in);
+        if (r < 0) {
+                log_error_netdev(netdev,
+                                 "Could not append IFLA_GRE_LOCAL attribute: %s",
+                                 strerror(-r));
+                return r;
+        }
+
+        r = sd_rtnl_message_append_in_addr(m, IFLA_GRE_REMOTE, &t->remote.in);
+        if (r < 0) {
+                log_error_netdev(netdev,
+                                 "Could not append IFLA_GRE_REMOTE attribute: %s",
+                                 strerror(-r));
+                return r;
+        }
+
+        r = sd_rtnl_message_append_u8(m, IFLA_GRE_TTL, t->ttl);
+        if (r < 0) {
+                log_error_netdev(netdev,
+                                 "Could not append IFLA_GRE_TTL attribute: %s",
+                                 strerror(-r));
+                return r;
+        }
+
+        r = sd_rtnl_message_append_u8(m, IFLA_GRE_TOS, t->tos);
+        if (r < 0) {
+                log_error_netdev(netdev,
+                                 "Could not append IFLA_GRE_TOS attribute: %s",
+                                 strerror(-r));
+                return r;
+        }
+
+        return r;
+}
+
+static int netdev_vti_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
+        Tunnel *t = VTI(netdev);
+        int r;
+
+        assert(netdev);
+        assert(link);
+        assert(m);
+        assert(t);
+        assert(t->family == AF_INET);
+
+        r = sd_rtnl_message_append_u32(m, IFLA_VTI_LINK, link->ifindex);
+        if (r < 0) {
+                log_error_netdev(netdev,
+                                 "Could not append IFLA_IPTUN_LINK attribute: %s",
+                                 strerror(-r));
+                return r;
+        }
+
+        r = sd_rtnl_message_append_in_addr(m, IFLA_VTI_LOCAL, &t->local.in);
+        if (r < 0) {
+                log_error_netdev(netdev,
+                                 "Could not append IFLA_IPTUN_LOCAL attribute: %s",
+                                 strerror(-r));
+                return r;
+        }
+
+        r = sd_rtnl_message_append_in_addr(m, IFLA_VTI_REMOTE, &t->remote.in);
+        if (r < 0) {
+                log_error_netdev(netdev,
+                                 "Could not append IFLA_IPTUN_REMOTE attribute: %s",
+                                 strerror(-r));
+                return r;
+        }
+
+        return r;
+}
+
+static int netdev_tunnel_verify(NetDev *netdev, const char *filename) {
+        Tunnel *t = NULL;
+
+        assert(netdev);
+        assert(filename);
+
+        switch (netdev->kind) {
+        case NETDEV_KIND_IPIP:
+                t = IPIP(netdev);
+                break;
+        case NETDEV_KIND_SIT:
+                t = SIT(netdev);
+                break;
+        case NETDEV_KIND_GRE:
+                t = GRE(netdev);
+                break;
+        case NETDEV_KIND_VTI:
+                t = VTI(netdev);
+                break;
+        default:
+                assert_not_reached("Invalid tunnel kind");
+        }
+
+        assert(t);
+
+        if (t->local.in.s_addr == INADDR_ANY) {
+               log_warning("Tunnel without local address configured in %s. Ignoring", filename);
+               return -EINVAL;
+        }
+
+        if (t->remote.in.s_addr == INADDR_ANY) {
+               log_warning("Tunnel without remote address configured in %s. Ignoring", filename);
+               return -EINVAL;
+        }
+
+        if (t->family != AF_INET) {
+              log_warning("Tunnel with invalid address family configured in %s. Ignoring", filename);
+              return -EINVAL;
+        }
+
+        return 0;
+}
+
+int config_parse_tunnel_address(const char *unit,
+                                const char *filename,
+                                unsigned line,
+                                const char *section,
+                                unsigned section_line,
+                                const char *lvalue,
+                                int ltype,
+                                const char *rvalue,
+                                void *data,
+                                void *userdata) {
+        Tunnel *t = userdata;
+        union in_addr_union *addr = data, buffer;
+        int r, f;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        r = in_addr_from_string_auto(rvalue, &f, &buffer);
+        if (r < 0) {
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Tunnel address is invalid, ignoring assignment: %s", rvalue);
+                return 0;
+        }
+
+        if (t->family != AF_UNSPEC && t->family != f) {
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Tunnel addresses incompatible, ignoring assignment: %s", rvalue);
+                return 0;
+        }
+
+        t->family = f;
+        *addr = buffer;
+
+        return 0;
+}
+
+static void ipip_init(NetDev *n) {
+        Tunnel *t = IPIP(n);
+
+        assert(n);
+        assert(t);
+
+        t->pmtudisc = true;
+}
+
+static void sit_init(NetDev *n) {
+        Tunnel *t = SIT(n);
+
+        assert(n);
+        assert(t);
+
+        t->pmtudisc = true;
+}
+
+static void vti_init(NetDev *n) {
+        Tunnel *t = VTI(n);
+
+        assert(n);
+        assert(t);
+
+        t->pmtudisc = true;
+}
+
+static void gre_init(NetDev *n) {
+        Tunnel *t = GRE(n);
+
+        assert(n);
+        assert(t);
+
+        t->pmtudisc = true;
+}
+
+const NetDevVTable ipip_vtable = {
+        .object_size = sizeof(Tunnel),
+        .init = ipip_init,
+        .sections = "Match\0NetDev\0Tunnel\0",
+        .fill_message_create = netdev_ipip_fill_message_create,
+        .create_type = NETDEV_CREATE_STACKED,
+        .config_verify = netdev_tunnel_verify,
+};
+
+const NetDevVTable sit_vtable = {
+        .object_size = sizeof(Tunnel),
+        .init = sit_init,
+        .sections = "Match\0NetDev\0Tunnel\0",
+        .fill_message_create = netdev_sit_fill_message_create,
+        .create_type = NETDEV_CREATE_STACKED,
+        .config_verify = netdev_tunnel_verify,
+};
+
+const NetDevVTable vti_vtable = {
+        .object_size = sizeof(Tunnel),
+        .init = vti_init,
+        .sections = "Match\0NetDev\0Tunnel\0",
+        .fill_message_create = netdev_vti_fill_message_create,
+        .create_type = NETDEV_CREATE_STACKED,
+        .config_verify = netdev_tunnel_verify,
+};
+
+const NetDevVTable gre_vtable = {
+        .object_size = sizeof(Tunnel),
+        .init = gre_init,
+        .sections = "Match\0NetDev\0Tunnel\0",
+        .fill_message_create = netdev_gre_fill_message_create,
+        .create_type = NETDEV_CREATE_STACKED,
+        .config_verify = netdev_tunnel_verify,
+};
diff --git a/src/network/networkd-netdev-tunnel.h b/src/network/networkd-netdev-tunnel.h
new file mode 100644 (file)
index 0000000..000a646
--- /dev/null
@@ -0,0 +1,43 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Tom Gundersen <teg@jklm.no>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#pragma once
+
+typedef struct Tunnel Tunnel;
+
+#include "networkd-netdev.h"
+
+struct Tunnel {
+        NetDev meta;
+
+        int family;
+
+        unsigned ttl;
+        unsigned tos;
+        union in_addr_union local;
+        union in_addr_union remote;
+        bool pmtudisc;
+};
+
+extern const NetDevVTable ipip_vtable;
+extern const NetDevVTable sit_vtable;
+extern const NetDevVTable vti_vtable;
+extern const NetDevVTable gre_vtable;
diff --git a/src/network/networkd-netdev-tuntap.c b/src/network/networkd-netdev-tuntap.c
new file mode 100644 (file)
index 0000000..eef8747
--- /dev/null
@@ -0,0 +1,216 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+    This file is part of systemd.
+
+    Copyright 2014 Susant Sahani <susant@redhat.com>
+
+    systemd is free software; you can redistribute it and/or modify it
+    under the terms of the GNU Lesser General Public License as published by
+    the Free Software Foundation; either version 2.1 of the License, or
+    (at your option) any later version.
+
+    systemd is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <linux/if_tun.h>
+
+#include "networkd-netdev-tuntap.h"
+
+#define TUN_DEV "/dev/net/tun"
+
+static int netdev_fill_tuntap_message(NetDev *netdev, struct ifreq *ifr) {
+        TunTap *t;
+
+        assert(netdev);
+        assert(netdev->ifname);
+        assert(ifr);
+
+        if (netdev->kind == NETDEV_KIND_TAP) {
+                t = TAP(netdev);
+                ifr->ifr_flags |= IFF_TAP;
+        } else {
+                t = TUN(netdev);
+                ifr->ifr_flags |= IFF_TUN;
+        }
+
+        if (!t->packet_info)
+                ifr->ifr_flags |= IFF_NO_PI;
+
+        if (t->one_queue)
+                ifr->ifr_flags |= IFF_ONE_QUEUE;
+
+        if (t->multi_queue)
+                ifr->ifr_flags |= IFF_MULTI_QUEUE;
+
+        strncpy(ifr->ifr_name, netdev->ifname, IFNAMSIZ-1);
+
+        return 0;
+}
+
+static int netdev_tuntap_add(NetDev *netdev, struct ifreq *ifr) {
+        _cleanup_close_ int fd;
+        TunTap *t = NULL;
+        const char *user;
+        const char *group;
+        uid_t uid;
+        gid_t gid;
+        int r = 0;
+
+        assert(netdev);
+        assert(ifr);
+
+        fd = open(TUN_DEV, O_RDWR);
+        if (fd < 0) {
+                log_error_netdev(netdev,
+                                 "Failed to open tun dev: %s",
+                                 strerror(-r));
+                return r;
+        }
+
+        r = ioctl(fd, TUNSETIFF, ifr);
+        if (r < 0) {
+                log_error_netdev(netdev,
+                                 "TUNSETIFF failed on tun dev: %s",
+                                 strerror(-r));
+                return r;
+        }
+
+        if (netdev->kind == NETDEV_KIND_TAP)
+                t = TAP(netdev);
+        else
+                t = TUN(netdev);
+
+        assert(t);
+
+        if(t->user_name) {
+
+                user = t->user_name;
+
+                r = get_user_creds(&user, &uid, NULL, NULL, NULL);
+                if (r < 0) {
+                        log_error("Cannot resolve user name %s: %s",
+                                  t->user_name, strerror(-r));
+                        return 0;
+                }
+
+                r = ioctl(fd, TUNSETOWNER, uid);
+                if ( r < 0) {
+                        log_error_netdev(netdev,
+                                         "TUNSETOWNER failed on tun dev: %s",
+                                         strerror(-r));
+                }
+        }
+
+        if(t->group_name) {
+
+                group = t->group_name;
+
+                r = get_group_creds(&group, &gid);
+                if (r < 0) {
+                        log_error("Cannot resolve group name %s: %s",
+                                  t->group_name, strerror(-r));
+                        return 0;
+                }
+
+                r = ioctl(fd, TUNSETGROUP, gid);
+                if( r < 0) {
+                        log_error_netdev(netdev,
+                                         "TUNSETGROUP failed on tun dev: %s",
+                                         strerror(-r));
+                        return r;
+                }
+
+        }
+
+        r = ioctl(fd, TUNSETPERSIST, 1);
+        if (r < 0) {
+                log_error_netdev(netdev,
+                                 "TUNSETPERSIST failed on tun dev: %s",
+                                 strerror(-r));
+                return r;
+        }
+
+        return r;
+}
+
+static int netdev_create_tuntap(NetDev *netdev) {
+        struct ifreq ifr = {};
+        int r;
+
+        r = netdev_fill_tuntap_message(netdev, &ifr);
+        if(r < 0)
+                return r;
+
+        return netdev_tuntap_add(netdev, &ifr);
+}
+
+static void tuntap_done(NetDev *netdev) {
+        TunTap *t = NULL;
+
+        assert(netdev);
+
+        if (netdev->kind == NETDEV_KIND_TUN)
+                t = TUN(netdev);
+        else
+                t = TAP(netdev);
+
+        assert(t);
+
+        free(t->user_name);
+        t->user_name = NULL;
+
+        free(t->group_name);
+        t->group_name = NULL;
+}
+
+static int tuntap_verify(NetDev *netdev, const char *filename) {
+        TunTap *t = NULL;
+
+        assert(netdev);
+
+        if (netdev->kind == NETDEV_KIND_TUN)
+                t = TUN(netdev);
+        else
+                t = TAP(netdev);
+
+        assert(t);
+
+        if (netdev->mtu) {
+                log_warning_netdev(netdev, "MTU configured for %s, ignoring",
+                                   netdev_kind_to_string(netdev->kind));
+        }
+
+        if (netdev->mac) {
+                log_warning_netdev(netdev, "MAC configured for %s, ignoring",
+                                   netdev_kind_to_string(netdev->kind));
+        }
+
+        return 0;
+}
+
+const NetDevVTable tun_vtable = {
+        .object_size = sizeof(TunTap),
+        .sections = "Match\0NetDev\0Tun\0",
+        .config_verify = tuntap_verify,
+        .done = tuntap_done,
+        .create = netdev_create_tuntap,
+        .create_type = NETDEV_CREATE_INDEPENDENT,
+};
+
+const NetDevVTable tap_vtable = {
+        .object_size = sizeof(TunTap),
+        .sections = "Match\0NetDev\0Tap\0",
+        .config_verify = tuntap_verify,
+        .done = tuntap_done,
+        .create = netdev_create_tuntap,
+        .create_type = NETDEV_CREATE_INDEPENDENT,
+};
diff --git a/src/network/networkd-netdev-tuntap.h b/src/network/networkd-netdev-tuntap.h
new file mode 100644 (file)
index 0000000..b804875
--- /dev/null
@@ -0,0 +1,39 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Tom Gundersen <teg@jklm.no>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#pragma once
+
+typedef struct TunTap TunTap;
+
+#include "networkd-netdev.h"
+
+struct TunTap {
+        NetDev meta;
+
+        char *user_name;
+        char *group_name;
+        bool one_queue;
+        bool multi_queue;
+        bool packet_info;
+};
+
+extern const NetDevVTable tun_vtable;
+extern const NetDevVTable tap_vtable;
diff --git a/src/network/networkd-netdev-veth.c b/src/network/networkd-netdev-veth.c
new file mode 100644 (file)
index 0000000..da09ef9
--- /dev/null
@@ -0,0 +1,119 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+    This file is part of systemd.
+
+    Copyright 2014 Susant Sahani <susant@redhat.com>
+
+    systemd is free software; you can redistribute it and/or modify it
+    under the terms of the GNU Lesser General Public License as published by
+    the Free Software Foundation; either version 2.1 of the License, or
+    (at your option) any later version.
+
+    systemd is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <netinet/ether.h>
+#include <arpa/inet.h>
+#include <net/if.h>
+#include <linux/veth.h>
+
+#include "sd-rtnl.h"
+#include "networkd-netdev-veth.h"
+
+static int netdev_veth_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
+        Veth *v = VETH(netdev);
+        int r;
+
+        assert(netdev);
+        assert(!link);
+        assert(v);
+        assert(m);
+
+        r = sd_rtnl_message_open_container(m, VETH_INFO_PEER);
+        if (r < 0) {
+                log_error_netdev(netdev,
+                                 "Could not append IFLA_IPTUN_LINK attribute: %s",
+                                 strerror(-r));
+                return r;
+        }
+
+        if (v->ifname_peer) {
+                r = sd_rtnl_message_append_string(m, IFLA_IFNAME, v->ifname_peer);
+                if (r < 0) {
+                        log_error("Failed to add netlink interface name: %s", strerror(-r));
+                        return r;
+                }
+        }
+
+        if (v->mac_peer) {
+                r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, v->mac_peer);
+                if (r < 0) {
+                        log_error_netdev(netdev,
+                                         "Could not append IFLA_ADDRESS attribute: %s",
+                                         strerror(-r));
+                    return r;
+                }
+        }
+
+        r = sd_rtnl_message_close_container(m);
+        if (r < 0) {
+                log_error_netdev(netdev,
+                                 "Could not append IFLA_INFO_DATA attribute: %s",
+                                 strerror(-r));
+                return r;
+        }
+
+        return r;
+}
+
+static int netdev_veth_verify(NetDev *netdev, const char *filename) {
+        Veth *v = VETH(netdev);
+        int r;
+
+        assert(netdev);
+        assert(v);
+        assert(filename);
+
+        if (!v->ifname_peer) {
+                log_warning("Veth NetDev without peer name configured in %s. Ignoring",
+                            filename);
+                return -EINVAL;
+        }
+
+        if (!v->mac_peer) {
+                r = netdev_get_mac(v->ifname_peer, &v->mac_peer);
+                if (r < 0) {
+                        log_warning("Failed to generate predictable MAC address for %s. Ignoring",
+                                  v->ifname_peer);
+                        return -EINVAL;
+                }
+        }
+
+        return 0;
+}
+
+static void veth_done(NetDev *n) {
+        Veth *v = VETH(n);
+
+        assert(n);
+        assert(v);
+
+        free(v->ifname_peer);
+        free(v->mac_peer);
+}
+
+const NetDevVTable veth_vtable = {
+        .object_size = sizeof(Veth),
+        .sections = "Match\0NetDev\0Peer\0",
+        .done = veth_done,
+        .fill_message_create = netdev_veth_fill_message_create,
+        .create_type = NETDEV_CREATE_INDEPENDENT,
+        .config_verify = netdev_veth_verify,
+};
diff --git a/src/network/networkd-netdev-veth.h b/src/network/networkd-netdev-veth.h
new file mode 100644 (file)
index 0000000..85d8b49
--- /dev/null
@@ -0,0 +1,35 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Tom Gundersen <teg@jklm.no>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#pragma once
+
+typedef struct Veth Veth;
+
+#include "networkd-netdev.h"
+
+struct Veth {
+        NetDev meta;
+
+        char *ifname_peer;
+        struct ether_addr *mac_peer;
+};
+
+extern const NetDevVTable veth_vtable;
diff --git a/src/network/networkd-netdev-vlan.c b/src/network/networkd-netdev-vlan.c
new file mode 100644 (file)
index 0000000..13c4456
--- /dev/null
@@ -0,0 +1,81 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2013 Tom Gundersen <teg@jklm.no>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <net/if.h>
+
+#include "networkd-netdev-vlan.h"
+#include "network-internal.h"
+#include "list.h"
+
+static int netdev_vlan_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *req) {
+        VLan *v = VLAN(netdev);
+        int r;
+
+        assert(netdev);
+        assert(v);
+        assert(link);
+        assert(req);
+
+        if (v->id <= VLANID_MAX) {
+                r = sd_rtnl_message_append_u16(req, IFLA_VLAN_ID, v->id);
+                if (r < 0) {
+                        log_error_netdev(netdev,
+                                         "Could not append IFLA_VLAN_ID attribute: %s",
+                                         strerror(-r));
+                        return r;
+                }
+        }
+
+        return 0;
+}
+
+static int netdev_vlan_verify(NetDev *netdev, const char *filename) {
+        VLan *v = VLAN(netdev);
+
+        assert(netdev);
+        assert(v);
+        assert(filename);
+
+        if (v->id > VLANID_MAX) {
+                log_warning("VLAN without valid Id (%"PRIu64") configured in %s. Ignoring", v->id, filename);
+                return -EINVAL;
+        }
+
+        return 0;
+}
+
+static void vlan_init(NetDev *netdev) {
+        VLan *v = VLAN(netdev);
+
+        assert(netdev);
+        assert(v);
+
+        v->id = VLANID_MAX + 1;
+}
+
+const NetDevVTable vlan_vtable = {
+        .object_size = sizeof(VLan),
+        .init = vlan_init,
+        .sections = "Match\0NetDev\0VLAN\0",
+        .fill_message_create = netdev_vlan_fill_message_create,
+        .create_type = NETDEV_CREATE_STACKED,
+        .config_verify = netdev_vlan_verify,
+};
diff --git a/src/network/networkd-netdev-vlan.h b/src/network/networkd-netdev-vlan.h
new file mode 100644 (file)
index 0000000..0c0fbbe
--- /dev/null
@@ -0,0 +1,36 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Tom Gundersen <teg@jklm.no>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#pragma once
+
+typedef struct VLan VLan;
+
+#include "networkd-netdev.h"
+
+#define VLANID_MAX 4094
+
+struct VLan {
+        NetDev meta;
+
+        uint64_t id;
+};
+
+extern const NetDevVTable vlan_vtable;
diff --git a/src/network/networkd-netdev-vxlan.c b/src/network/networkd-netdev-vxlan.c
new file mode 100644 (file)
index 0000000..326ac54
--- /dev/null
@@ -0,0 +1,130 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+    This file is part of systemd.
+
+    Copyright 2014 Susant Sahani <susant@redhat.com>
+
+    systemd is free software; you can redistribute it and/or modify it
+    under the terms of the GNU Lesser General Public License as published by
+    the Free Software Foundation; either version 2.1 of the License, or
+    (at your option) any later version.
+
+    systemd is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <netinet/ether.h>
+#include <arpa/inet.h>
+#include <net/if.h>
+
+#include "sd-rtnl.h"
+#include "networkd-netdev-vxlan.h"
+#include "networkd-link.h"
+#include "missing.h"
+
+static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
+        VxLan *v = VXLAN(netdev);
+        int r;
+
+        assert(netdev);
+        assert(v);
+        assert(link);
+        assert(m);
+
+
+        if (v->id <= VXLAN_VID_MAX) {
+                r = sd_rtnl_message_append_u32(m, IFLA_VXLAN_ID, v->id);
+                if (r < 0) {
+                        log_error_netdev(netdev,
+                                         "Could not append IFLA_VXLAN_ID attribute: %s",
+                                         strerror(-r));
+                        return r;
+                }
+        }
+
+        r = sd_rtnl_message_append_in_addr(m, IFLA_VXLAN_GROUP, &v->group.in);
+        if (r < 0) {
+                log_error_netdev(netdev,
+                                 "Could not append IFLA_VXLAN_GROUP attribute: %s",
+                                 strerror(-r));
+                return r;
+        }
+
+        r = sd_rtnl_message_append_u32(m, IFLA_VXLAN_LINK, link->ifindex);
+        if (r < 0) {
+                log_error_netdev(netdev,
+                                 "Could not append IFLA_VXLAN_LINK attribute: %s",
+                                 strerror(-r));
+                return r;
+        }
+
+        if(v->ttl) {
+                r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_TTL, v->ttl);
+                if (r < 0) {
+                        log_error_netdev(netdev,
+                                         "Could not append IFLA_VXLAN_TTL attribute: %s",
+                                         strerror(-r));
+                        return r;
+                }
+        }
+
+        if(v->tos) {
+                r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_TOS, v->tos);
+                if (r < 0) {
+                        log_error_netdev(netdev,
+                                         "Could not append IFLA_VXLAN_TOS attribute: %s",
+                                         strerror(-r));
+                        return r;
+                }
+        }
+
+        r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_LEARNING, v->learning);
+        if (r < 0) {
+                log_error_netdev(netdev,
+                                 "Could not append IFLA_VXLAN_LEARNING attribute: %s",
+                                 strerror(-r));
+                return r;
+        }
+
+        return r;
+}
+
+static int netdev_vxlan_verify(NetDev *netdev, const char *filename) {
+        VxLan *v = VXLAN(netdev);
+
+        assert(netdev);
+        assert(v);
+        assert(filename);
+
+        if (v->id > VXLAN_VID_MAX) {
+                log_warning("VXLAN without valid Id configured in %s. Ignoring", filename);
+                return -EINVAL;
+        }
+
+        return 0;
+}
+
+static void vxlan_init(NetDev *netdev) {
+        VxLan *v = VXLAN(netdev);
+
+        assert(netdev);
+        assert(v);
+
+        v->id = VXLAN_VID_MAX + 1;
+        v->learning = true;
+}
+
+const NetDevVTable vxlan_vtable = {
+        .object_size = sizeof(VxLan),
+        .init = vxlan_init,
+        .sections = "Match\0NetDev\0VXLAN\0",
+        .fill_message_create = netdev_vxlan_fill_message_create,
+        .create_type = NETDEV_CREATE_STACKED,
+        .config_verify = netdev_vxlan_verify,
+};
diff --git a/src/network/networkd-netdev-vxlan.h b/src/network/networkd-netdev-vxlan.h
new file mode 100644 (file)
index 0000000..8c906f1
--- /dev/null
@@ -0,0 +1,42 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Tom Gundersen <teg@jklm.no>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#pragma once
+
+typedef struct VxLan VxLan;
+
+#include "networkd-netdev.h"
+
+#include "in-addr-util.h"
+
+#define VXLAN_VID_MAX (1u << 24) - 1
+
+struct VxLan {
+        NetDev meta;
+
+        uint64_t id;
+        union in_addr_union group;
+        unsigned tos;
+        unsigned ttl;
+        bool learning;
+};
+
+extern const NetDevVTable vxlan_vtable;
index 05f21fa..1a436f7 100644 (file)
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
-#include "networkd.h"
-#include "net-util.h"
+#include <net/if.h>
+
+#include "networkd-netdev.h"
+#include "networkd-link.h"
+#include "network-internal.h"
 #include "path-util.h"
 #include "conf-files.h"
 #include "conf-parser.h"
 #include "list.h"
+#include "siphash24.h"
+
+const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX] = {
+        [NETDEV_KIND_BRIDGE] = &bridge_vtable,
+        [NETDEV_KIND_BOND] = &bond_vtable,
+        [NETDEV_KIND_VLAN] = &vlan_vtable,
+        [NETDEV_KIND_MACVLAN] = &macvlan_vtable,
+        [NETDEV_KIND_VXLAN] = &vxlan_vtable,
+        [NETDEV_KIND_IPIP] = &ipip_vtable,
+        [NETDEV_KIND_GRE] = &gre_vtable,
+        [NETDEV_KIND_SIT] = &sit_vtable,
+        [NETDEV_KIND_VTI] = &vti_vtable,
+        [NETDEV_KIND_VETH] = &veth_vtable,
+        [NETDEV_KIND_DUMMY] = &dummy_vtable,
+        [NETDEV_KIND_TUN] = &tun_vtable,
+        [NETDEV_KIND_TAP] = &tap_vtable,
+};
 
-#define VLANID_MAX 4094
-
-static const char* const netdev_kind_table[] = {
+static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = {
         [NETDEV_KIND_BRIDGE] = "bridge",
         [NETDEV_KIND_BOND] = "bond",
         [NETDEV_KIND_VLAN] = "vlan",
+        [NETDEV_KIND_MACVLAN] = "macvlan",
+        [NETDEV_KIND_VXLAN] = "vxlan",
+        [NETDEV_KIND_IPIP] = "ipip",
+        [NETDEV_KIND_GRE] = "gre",
+        [NETDEV_KIND_SIT] = "sit",
+        [NETDEV_KIND_VETH] = "veth",
+        [NETDEV_KIND_VTI] = "vti",
+        [NETDEV_KIND_DUMMY] = "dummy",
+        [NETDEV_KIND_TUN] = "tun",
+        [NETDEV_KIND_TAP] = "tap",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(netdev_kind, NetDevKind);
 DEFINE_CONFIG_PARSE_ENUM(config_parse_netdev_kind, netdev_kind, NetDevKind, "Failed to parse netdev kind");
 
-void netdev_free(NetDev *netdev) {
-        netdev_enslave_callback *callback;
+
+static void netdev_cancel_callbacks(NetDev *netdev) {
+        _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
+        netdev_join_callback *callback;
 
         if (!netdev)
                 return;
 
+        rtnl_message_new_synthetic_error(-ENODEV, 0, &m);
+
         while ((callback = netdev->callbacks)) {
+                if (m) {
+                        assert(callback->link);
+                        assert(callback->callback);
+                        assert(netdev->manager);
+                        assert(netdev->manager->rtnl);
+
+                        callback->callback(netdev->manager->rtnl, m, link);
+                }
+
                 LIST_REMOVE(callbacks, netdev->callbacks, callback);
                 free(callback);
         }
+}
+
+static void netdev_free(NetDev *netdev) {
+        if (!netdev)
+                return;
 
-        if (netdev->name)
-                hashmap_remove(netdev->manager->netdevs, netdev->name);
+        netdev_cancel_callbacks(netdev);
+
+        if (netdev->ifname)
+                hashmap_remove(netdev->manager->netdevs, netdev->ifname);
 
         free(netdev->filename);
 
         free(netdev->description);
-        free(netdev->name);
+        free(netdev->ifname);
+        free(netdev->mac);
+
+        condition_free_list(netdev->match_host);
+        condition_free_list(netdev->match_virt);
+        condition_free_list(netdev->match_kernel);
+        condition_free_list(netdev->match_arch);
+
+        if (NETDEV_VTABLE(netdev) &&
+            NETDEV_VTABLE(netdev)->done)
+                NETDEV_VTABLE(netdev)->done(netdev);
 
         free(netdev);
 }
 
+NetDev *netdev_unref(NetDev *netdev) {
+        if (netdev && (-- netdev->n_ref <= 0))
+                netdev_free(netdev);
+
+        return NULL;
+}
+
+NetDev *netdev_ref(NetDev *netdev) {
+        if (netdev)
+                assert_se(++ netdev->n_ref >= 2);
+
+        return netdev;
+}
+
+void netdev_drop(NetDev *netdev) {
+        if (!netdev || netdev->state == NETDEV_STATE_LINGER)
+                return;
+
+        netdev->state = NETDEV_STATE_LINGER;
+
+        log_debug_netdev(netdev, "netdev removed");
+
+        netdev_cancel_callbacks(netdev);
+
+        netdev_unref(netdev);
+
+        return;
+}
+
 int netdev_get(Manager *manager, const char *name, NetDev **ret) {
         NetDev *netdev;
 
@@ -91,6 +178,7 @@ static int netdev_enslave_ready(NetDev *netdev, Link* link, sd_rtnl_message_hand
         assert(netdev->state == NETDEV_STATE_READY);
         assert(netdev->manager);
         assert(netdev->manager->rtnl);
+        assert(IN_SET(netdev->kind, NETDEV_KIND_BRIDGE, NETDEV_KIND_BOND));
         assert(link);
         assert(callback);
 
@@ -119,201 +207,414 @@ static int netdev_enslave_ready(NetDev *netdev, Link* link, sd_rtnl_message_hand
                 return r;
         }
 
+        link_ref(link);
+
         log_debug_netdev(netdev, "enslaving link '%s'", link->ifname);
 
         return 0;
 }
 
 static int netdev_enter_ready(NetDev *netdev) {
-        netdev_enslave_callback *callback;
+        netdev_join_callback *callback, *callback_next;
+        int r;
 
         assert(netdev);
-        assert(netdev->name);
+        assert(netdev->ifname);
+
+        if (netdev->state != NETDEV_STATE_CREATING)
+                return 0;
 
         netdev->state = NETDEV_STATE_READY;
 
         log_info_netdev(netdev, "netdev ready");
 
-        LIST_FOREACH(callbacks, callback, netdev->callbacks) {
-                /* enslave the links that were attempted to be enslaved befor the
+        LIST_FOREACH_SAFE(callbacks, callback, callback_next, netdev->callbacks) {
+                /* enslave the links that were attempted to be enslaved before the
                  * link was ready */
-                netdev_enslave_ready(netdev, callback->link, callback->callback);
+                r = netdev_enslave_ready(netdev, callback->link, callback->callback);
+                if (r < 0)
+                        return r;
+
+                LIST_REMOVE(callbacks, netdev->callbacks, callback);
+                link_unref(callback->link);
+                free(callback);
         }
 
         return 0;
 }
 
+/* callback for netdev's created without a backing Link */
 static int netdev_create_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
-        NetDev *netdev = userdata;
+        _cleanup_netdev_unref_ NetDev *netdev = userdata;
         int r;
 
         assert(netdev->state != _NETDEV_STATE_INVALID);
 
         r = sd_rtnl_message_get_errno(m);
-        if (r < 0) {
-                log_warning_netdev(netdev, "netdev failed: %s", strerror(-r));
-                netdev_enter_failed(netdev);
+        if (r == -EEXIST)
+                log_debug_netdev(netdev, "netdev exists, using existing");
+        else if (r < 0) {
+                log_warning_netdev(netdev, "netdev could not be created: %s", strerror(-r));
+                netdev_drop(netdev);
 
                 return 1;
         }
 
+        log_debug_netdev(netdev, "created");
+
         return 1;
 }
 
-static int netdev_create(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback) {
-        _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
-        const char *kind;
+int netdev_enslave(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback) {
         int r;
 
         assert(netdev);
-        assert(!(netdev->kind == NETDEV_KIND_VLAN) ||
-               (link && callback && netdev->vlanid <= VLANID_MAX));
-        assert(netdev->name);
-        assert(netdev->manager);
-        assert(netdev->manager->rtnl);
+        assert(IN_SET(netdev->kind, NETDEV_KIND_BRIDGE, NETDEV_KIND_BOND));
 
-        r = sd_rtnl_message_new_link(netdev->manager->rtnl, &req, RTM_NEWLINK, 0);
+        if (netdev->state == NETDEV_STATE_READY) {
+                r = netdev_enslave_ready(netdev, link, callback);
+                if (r < 0)
+                        return r;
+        } else {
+                /* the netdev is not yet read, save this request for when it is*/
+                netdev_join_callback *cb;
+
+                cb = new0(netdev_join_callback, 1);
+                if (!cb)
+                        return log_oom();
+
+                cb->callback = callback;
+                cb->link = link;
+                link_ref(link);
+
+                LIST_PREPEND(callbacks, netdev->callbacks, cb);
+
+                log_debug_netdev(netdev, "will enslave '%s', when reday",
+                                 link->ifname);
+        }
+
+        return 0;
+}
+
+int netdev_set_ifindex(NetDev *netdev, sd_rtnl_message *message) {
+        uint16_t type;
+        const char *kind;
+        const char *received_kind;
+        const char *received_name;
+        int r, ifindex;
+
+        assert(netdev);
+        assert(message);
+
+        r = sd_rtnl_message_get_type(message, &type);
         if (r < 0) {
-                log_error_netdev(netdev,
-                                 "Could not allocate RTM_NEWLINK message: %s",
-                                 strerror(-r));
+                log_error_netdev(netdev, "Could not get rtnl message type");
                 return r;
         }
 
-        if (link) {
-                r = sd_rtnl_message_append_u32(req, IFLA_LINK, link->ifindex);
-                if (r < 0) {
-                        log_error_netdev(netdev,
-                                         "Could not append IFLA_LINK attribute: %s",
-                                         strerror(-r));
-                        return r;
-                }
+        if (type != RTM_NEWLINK) {
+                log_error_netdev(netdev, "Can not set ifindex from unexpected rtnl message type");
+                return -EINVAL;
         }
 
-        r = sd_rtnl_message_append_string(req, IFLA_IFNAME, netdev->name);
+        r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
         if (r < 0) {
-                log_error_netdev(netdev,
-                                 "Could not append IFLA_IFNAME attribute: %s",
-                                 strerror(-r));
+                log_error_netdev(netdev, "Could not get ifindex: %s", strerror(-r));
+                netdev_enter_failed(netdev);
+                return r;
+        } else if (ifindex <= 0) {
+                log_error_netdev(netdev, "Got invalid ifindex: %d", ifindex);
+                netdev_enter_failed(netdev);
                 return r;
         }
 
-        r = sd_rtnl_message_open_container(req, IFLA_LINKINFO);
+        if (netdev->ifindex > 0) {
+                if (netdev->ifindex != ifindex) {
+                        log_error_netdev(netdev, "Could not set ifindex to %d, already set to %d",
+                                         ifindex, netdev->ifindex);
+                        netdev_enter_failed(netdev);
+                        return -EEXIST;
+                } else
+                        /* ifindex already set to the same for this netdev */
+                        return 0;
+        }
+
+        r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &received_name);
         if (r < 0) {
-                log_error_netdev(netdev,
-                                 "Could not open IFLA_LINKINFO container: %s",
-                                 strerror(-r));
+                log_error_netdev(netdev, "Could not get IFNAME");
                 return r;
         }
 
-        kind = netdev_kind_to_string(netdev->kind);
-        if (!kind) {
-                log_error_netdev(netdev, "Invalid kind");
-                return -EINVAL;
+        if (!streq(netdev->ifname, received_name)) {
+                log_error_netdev(netdev, "Received newlink with wrong IFNAME %s",
+                                 received_name);
+                netdev_enter_failed(netdev);
+                return r;
         }
 
-        r = sd_rtnl_message_append_string(req, IFLA_INFO_KIND, kind);
+        r = sd_rtnl_message_enter_container(message, IFLA_LINKINFO);
         if (r < 0) {
+                log_error_netdev(netdev, "Could not get LINKINFO");
+                return r;
+        }
+
+        r = sd_rtnl_message_read_string(message, IFLA_INFO_KIND, &received_kind);
+        if (r < 0) {
+                log_error_netdev(netdev, "Could not get KIND");
+                return r;
+        }
+
+        r = sd_rtnl_message_exit_container(message);
+        if (r < 0) {
+                log_error_netdev(netdev, "Could not exit container");
+                return r;
+        }
+
+        if (netdev->kind == NETDEV_KIND_TAP)
+                /* the kernel does not distinguish between tun and tap */
+                kind = "tun";
+        else {
+                kind = netdev_kind_to_string(netdev->kind);
+                if (!kind) {
+                        log_error_netdev(netdev, "Could not get kind");
+                        netdev_enter_failed(netdev);
+                        return -EINVAL;
+                }
+        }
+
+        if (!streq(kind, received_kind)) {
                 log_error_netdev(netdev,
-                                 "Could not append IFLA_INFO_KIND attribute: %s",
-                                 strerror(-r));
+                                 "Received newlink with wrong KIND %s, "
+                                 "expected %s", received_kind, kind);
+                netdev_enter_failed(netdev);
                 return r;
         }
 
-        if (netdev->vlanid <= VLANID_MAX) {
-                r = sd_rtnl_message_open_container(req, IFLA_INFO_DATA);
+        netdev->ifindex = ifindex;
+
+        log_debug_netdev(netdev, "netdev has index %d", netdev->ifindex);
+
+        netdev_enter_ready(netdev);
+
+        return 0;
+}
+
+#define HASH_KEY SD_ID128_MAKE(52,e1,45,bd,00,6f,29,96,21,c6,30,6d,83,71,04,48)
+
+int netdev_get_mac(const char *ifname, struct ether_addr **ret) {
+        _cleanup_free_ struct ether_addr *mac = NULL;
+        uint8_t result[8];
+        size_t l, sz;
+        uint8_t *v;
+        int r;
+
+        assert(ifname);
+        assert(ret);
+
+        mac = new0(struct ether_addr, 1);
+        if (!mac)
+                return -ENOMEM;
+
+        l = strlen(ifname);
+        sz = sizeof(sd_id128_t) + l;
+        v = alloca(sz);
+
+        /* fetch some persistent data unique to the machine */
+        r = sd_id128_get_machine((sd_id128_t*) v);
+        if (r < 0)
+                return r;
+
+        /* combine with some data unique (on this machine) to this
+         * netdev */
+        memcpy(v + sizeof(sd_id128_t), ifname, l);
+
+        /* Let's hash the host machine ID plus the container name. We
+         * use a fixed, but originally randomly created hash key here. */
+        siphash24(result, v, sz, HASH_KEY.bytes);
+
+        assert_cc(ETH_ALEN <= sizeof(result));
+        memcpy(mac->ether_addr_octet, result, ETH_ALEN);
+
+        /* see eth_random_addr in the kernel */
+        mac->ether_addr_octet[0] &= 0xfe;        /* clear multicast bit */
+        mac->ether_addr_octet[0] |= 0x02;        /* set local assignment bit (IEEE802) */
+
+        *ret = mac;
+        mac = NULL;
+
+        return 0;
+}
+
+static int netdev_create(NetDev *netdev, Link *link,
+                         sd_rtnl_message_handler_t callback) {
+        int r;
+
+        assert(netdev);
+        assert(!link || callback);
+
+        /* create netdev */
+        if (NETDEV_VTABLE(netdev)->create) {
+                assert(!link);
+
+                r = NETDEV_VTABLE(netdev)->create(netdev);
+                if (r < 0)
+                        return r;
+
+                log_debug_netdev(netdev, "created");
+        } else {
+                _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
+
+                r = sd_rtnl_message_new_link(netdev->manager->rtnl, &m, RTM_NEWLINK, 0);
                 if (r < 0) {
                         log_error_netdev(netdev,
-                                         "Could not open IFLA_INFO_DATA container: %s",
+                                         "Could not allocate RTM_NEWLINK message: %s",
                                          strerror(-r));
                         return r;
                 }
 
-                r = sd_rtnl_message_append_u16(req, IFLA_VLAN_ID, netdev->vlanid);
+                r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
                 if (r < 0) {
                         log_error_netdev(netdev,
-                                         "Could not append IFLA_VLAN_ID attribute: %s",
+                                         "Could not append IFLA_IFNAME, attribute: %s",
                                          strerror(-r));
                         return r;
                 }
 
-                r = sd_rtnl_message_close_container(req);
+                if (netdev->mac) {
+                        r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
+                        if (r < 0) {
+                                log_error_netdev(netdev,
+                                                 "Could not append IFLA_ADDRESS attribute: %s",
+                                                 strerror(-r));
+                            return r;
+                        }
+                }
+
+                if (netdev->mtu) {
+                        r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu);
+                        if (r < 0) {
+                                log_error_netdev(netdev,
+                                                 "Could not append IFLA_MTU attribute: %s",
+                                                 strerror(-r));
+                                return r;
+                        }
+                }
+
+                if (link) {
+                        r = sd_rtnl_message_append_u32(m, IFLA_LINK, link->ifindex);
+                        if (r < 0) {
+                                log_error_netdev(netdev,
+                                                 "Colud not append IFLA_LINK attribute: %s",
+                                                 strerror(-r));
+                                return r;
+                        }
+                }
+
+                r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
                 if (r < 0) {
                         log_error_netdev(netdev,
-                                         "Could not close IFLA_INFO_DATA container %s",
+                                         "Could not append IFLA_LINKINFO attribute: %s",
                                          strerror(-r));
                         return r;
                 }
-        }
 
-        r = sd_rtnl_message_close_container(req);
-        if (r < 0) {
-                log_error_netdev(netdev,
-                                 "Could not close IFLA_LINKINFO container %s",
-                                 strerror(-r));
-                return r;
-        }
-
-        if (link)
-                r = sd_rtnl_call_async(netdev->manager->rtnl, req, callback, link, 0, NULL);
-        else
-                r = sd_rtnl_call_async(netdev->manager->rtnl, req, &netdev_create_handler, netdev, 0, NULL);
-        if (r < 0) {
-                log_error_netdev(netdev,
-                                 "Could not send rtnetlink message: %s", strerror(-r));
-                return r;
-        }
-
-        log_debug_netdev(netdev, "creating netdev");
+                r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA,
+                                                         netdev_kind_to_string(netdev->kind));
+                if (r < 0) {
+                        log_error_netdev(netdev,
+                                         "Could not append IFLA_INFO_DATA attribute: %s",
+                                         strerror(-r));
+                        return r;
+                }
 
-        netdev->state = NETDEV_STATE_CREATING;
+                if (NETDEV_VTABLE(netdev)->fill_message_create) {
+                        r = NETDEV_VTABLE(netdev)->fill_message_create(netdev, link, m);
+                        if (r < 0)
+                                return r;
+                }
 
-        return 0;
-}
+                r = sd_rtnl_message_close_container(m);
+                if (r < 0) {
+                        log_error_netdev(netdev,
+                                         "Could not append IFLA_LINKINFO attribute: %s",
+                                         strerror(-r));
+                        return r;
+                }
 
-int netdev_enslave(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback) {
-        if (netdev->kind == NETDEV_KIND_VLAN)
-                return netdev_create(netdev, link, callback);
+                r = sd_rtnl_message_close_container(m);
+                if (r < 0) {
+                        log_error_netdev(netdev,
+                                         "Could not append IFLA_LINKINFO attribute: %s",
+                                         strerror(-r));
+                        return r;
+                }
 
-        if (netdev->state == NETDEV_STATE_READY) {
-                netdev_enslave_ready(netdev, link, callback);
-        } else {
-                /* the netdev is not yet read, save this request for when it is*/
-                netdev_enslave_callback *cb;
 
-                cb = new0(netdev_enslave_callback, 1);
-                if (!cb)
-                        return log_oom();
+                if (link) {
+                        r = sd_rtnl_call_async(netdev->manager->rtnl, m,
+                                               callback, link, 0, NULL);
+                        if (r < 0) {
+                                log_error_netdev(netdev,
+                                                 "Could not send rtnetlink message: %s",
+                                                 strerror(-r));
+                                return r;
+                        }
+
+                        link_ref(link);
+                } else {
+                        r = sd_rtnl_call_async(netdev->manager->rtnl, m,
+                                               netdev_create_handler, netdev, 0,
+                                               NULL);
+                        if (r < 0) {
+                                log_error_netdev(netdev,
+                                                 "Could not send rtnetlink message: %s",
+                                                 strerror(-r));
+                                return r;
+                        }
+
+                        netdev_ref(netdev);
+                }
 
-                cb->callback = callback;
-                cb->link = link;
+                netdev->state = NETDEV_STATE_CREATING;
 
-                LIST_PREPEND(callbacks, netdev->callbacks, cb);
+                log_debug_netdev(netdev, "creating");
         }
 
         return 0;
 }
 
-int netdev_set_ifindex(NetDev *netdev, int ifindex) {
+/* the callback must be called, possibly after a timeout, as otherwise the Link will hang */
+int netdev_join(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback) {
+        int r;
+
         assert(netdev);
-        assert(ifindex > 0);
+        assert(netdev->manager);
+        assert(netdev->manager->rtnl);
+        assert(NETDEV_VTABLE(netdev));
 
-        if (netdev->ifindex > 0) {
-                if (netdev->ifindex == ifindex)
-                        return 0;
-                else
-                        return -EEXIST;
-        }
+        switch (NETDEV_VTABLE(netdev)->create_type) {
+        case NETDEV_CREATE_MASTER:
+                r = netdev_enslave(netdev, link, callback);
+                if (r < 0)
+                        return r;
 
-        netdev->ifindex = ifindex;
+                break;
+        case NETDEV_CREATE_STACKED:
+                r = netdev_create(netdev, link, callback);
+                if (r < 0)
+                        return r;
 
-        netdev_enter_ready(netdev);
+                break;
+        default:
+                assert_not_reached("Can not join independent netdev");
+        }
 
         return 0;
 }
 
 static int netdev_load_one(Manager *manager, const char *filename) {
-        _cleanup_netdev_free_ NetDev *netdev = NULL;
+        _cleanup_netdev_unref_ NetDev *netdev = NULL;
+        _cleanup_free_ NetDev *netdev_raw = NULL;
         _cleanup_fclose_ FILE *file = NULL;
         int r;
 
@@ -325,60 +626,106 @@ static int netdev_load_one(Manager *manager, const char *filename) {
                 if (errno == ENOENT)
                         return 0;
                 else
-                        return errno;
+                        return -errno;
         }
 
-        netdev = new0(NetDev, 1);
-        if (!netdev)
+        if (null_or_empty_fd(fileno(file))) {
+                log_debug("Skipping empty file: %s", filename);
+                return 0;
+        }
+
+        netdev_raw = new0(NetDev, 1);
+        if (!netdev_raw)
                 return log_oom();
 
-        netdev->manager = manager;
-        netdev->state = _NETDEV_STATE_INVALID;
-        netdev->kind = _NETDEV_KIND_INVALID;
-        netdev->vlanid = VLANID_MAX + 1;
+        netdev_raw->kind = _NETDEV_KIND_INVALID;
 
-        r = config_parse(NULL, filename, file, "Match\0NetDev\0VLAN\0", config_item_perf_lookup,
-                        (void*) network_netdev_gperf_lookup, false, false, netdev);
-        if (r < 0) {
-                log_warning("Could not parse config file %s: %s", filename, strerror(-r));
+        r = config_parse(NULL, filename, file,
+                         "Match\0NetDev\0",
+                         config_item_perf_lookup, network_netdev_gperf_lookup,
+                         true, false, true, netdev_raw);
+        if (r < 0)
                 return r;
-        }
 
-        if (netdev->kind == _NETDEV_KIND_INVALID) {
-                log_warning("NetDev without Kind configured in %s. Ignoring", filename);
+        r = fseek(file, 0, SEEK_SET);
+        if (r < 0)
+                return -errno;
+
+        /* skip out early if configuration does not match the environment */
+        if (net_match_config(NULL, NULL, NULL, NULL, NULL,
+                             netdev_raw->match_host, netdev_raw->match_virt,
+                             netdev_raw->match_kernel, netdev_raw->match_arch,
+                             NULL, NULL, NULL, NULL, NULL, NULL) <= 0)
+                return 0;
+
+        if (!NETDEV_VTABLE(netdev_raw)) {
+                log_warning("NetDev with invalid Kind configured in %s. Ignoring", filename);
                 return 0;
         }
 
-        if (!netdev->name) {
+        if (!netdev_raw->ifname) {
                 log_warning("NetDev without Name configured in %s. Ignoring", filename);
                 return 0;
         }
 
-        if (netdev->kind == NETDEV_KIND_VLAN && netdev->vlanid > VLANID_MAX) {
-                log_warning("VLAN without valid Id configured in %s. Ignoring", filename);
-                return 0;
+        netdev = malloc0(NETDEV_VTABLE(netdev_raw)->object_size);
+        if (!netdev)
+                return log_oom();
+
+        netdev->n_ref = 1;
+        netdev->manager = manager;
+        netdev->state = _NETDEV_STATE_INVALID;
+        netdev->kind = netdev_raw->kind;
+        netdev->ifname = netdev_raw->ifname;
+
+        if (NETDEV_VTABLE(netdev)->init)
+                NETDEV_VTABLE(netdev)->init(netdev);
+
+        r = config_parse(NULL, filename, file,
+                         NETDEV_VTABLE(netdev)->sections,
+                         config_item_perf_lookup, network_netdev_gperf_lookup,
+                         false, false, false, netdev);
+        if (r < 0)
+                return r;
+
+        /* verify configuration */
+        if (NETDEV_VTABLE(netdev)->config_verify) {
+                r = NETDEV_VTABLE(netdev)->config_verify(netdev, filename);
+                if (r < 0)
+                        return 0;
         }
 
         netdev->filename = strdup(filename);
         if (!netdev->filename)
                 return log_oom();
 
-        if (net_match_config(NULL, NULL, NULL, NULL, NULL,
-                             netdev->match_host, netdev->match_virt,
-                             netdev->match_kernel, netdev->match_arch,
-                             NULL, NULL, NULL, NULL, NULL, NULL) <= 0)
-                return 0;
+        if (!netdev->mac) {
+                r = netdev_get_mac(netdev->ifname, &netdev->mac);
+                if (r < 0) {
+                        log_error("Failed to generate predictable MAC address for %s",
+                                  netdev->ifname);
+                        return r;
+                }
+        }
 
-        r = hashmap_put(netdev->manager->netdevs, netdev->name, netdev);
+        r = hashmap_put(netdev->manager->netdevs, netdev->ifname, netdev);
         if (r < 0)
                 return r;
 
         LIST_HEAD_INIT(netdev->callbacks);
 
-        if (netdev->kind != NETDEV_KIND_VLAN) {
+        log_debug_netdev(netdev, "loaded %s", netdev_kind_to_string(netdev->kind));
+
+        switch (NETDEV_VTABLE(netdev)->create_type) {
+        case NETDEV_CREATE_MASTER:
+        case NETDEV_CREATE_INDEPENDENT:
                 r = netdev_create(netdev, NULL, NULL);
                 if (r < 0)
                         return r;
+
+                break;
+        default:
+                break;
         }
 
         netdev = NULL;
@@ -394,7 +741,7 @@ int netdev_load(Manager *manager) {
         assert(manager);
 
         while ((netdev = hashmap_first(manager->netdevs)))
-                netdev_free(netdev);
+                netdev_unref(netdev);
 
         r = conf_files_list_strv(&files, ".netdev", NULL, network_dirs);
         if (r < 0) {
diff --git a/src/network/networkd-netdev.h b/src/network/networkd-netdev.h
new file mode 100644 (file)
index 0000000..e9a8a16
--- /dev/null
@@ -0,0 +1,205 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2013 Tom Gundersen <teg@jklm.no>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#pragma once
+
+#include "networkd.h"
+#include "hashmap.h"
+#include "list.h"
+#include "set.h"
+#include "condition-util.h"
+#include "in-addr-util.h"
+
+typedef struct NetDevVTable NetDevVTable;
+
+typedef struct netdev_join_callback netdev_join_callback;
+
+struct netdev_join_callback {
+        sd_rtnl_message_handler_t callback;
+        Link *link;
+
+        LIST_FIELDS(netdev_join_callback, callbacks);
+};
+
+typedef enum NetDevKind {
+        NETDEV_KIND_BRIDGE,
+        NETDEV_KIND_BOND,
+        NETDEV_KIND_VLAN,
+        NETDEV_KIND_MACVLAN,
+        NETDEV_KIND_VXLAN,
+        NETDEV_KIND_IPIP,
+        NETDEV_KIND_GRE,
+        NETDEV_KIND_SIT,
+        NETDEV_KIND_VETH,
+        NETDEV_KIND_VTI,
+        NETDEV_KIND_DUMMY,
+        NETDEV_KIND_TUN,
+        NETDEV_KIND_TAP,
+        _NETDEV_KIND_MAX,
+        _NETDEV_KIND_INVALID = -1
+} NetDevKind;
+
+typedef enum NetDevState {
+        NETDEV_STATE_FAILED,
+        NETDEV_STATE_CREATING,
+        NETDEV_STATE_READY,
+        NETDEV_STATE_LINGER,
+        _NETDEV_STATE_MAX,
+        _NETDEV_STATE_INVALID = -1,
+} NetDevState;
+
+typedef enum NetDevCreateType {
+        NETDEV_CREATE_INDEPENDENT,
+        NETDEV_CREATE_MASTER,
+        NETDEV_CREATE_STACKED,
+        _NETDEV_CREATE_MAX,
+        _NETDEV_CREATE_INVALID = -1,
+} NetDevCreateType;
+
+struct NetDev {
+        Manager *manager;
+
+        int n_ref;
+
+        char *filename;
+
+        Condition *match_host;
+        Condition *match_virt;
+        Condition *match_kernel;
+        Condition *match_arch;
+
+        NetDevState state;
+        NetDevKind kind;
+        char *description;
+        char *ifname;
+        struct ether_addr *mac;
+        size_t mtu;
+        int ifindex;
+
+        LIST_HEAD(netdev_join_callback, callbacks);
+};
+
+#include "networkd-netdev-bridge.h"
+#include "networkd-netdev-bond.h"
+#include "networkd-netdev-vlan.h"
+#include "networkd-netdev-macvlan.h"
+#include "networkd-netdev-vxlan.h"
+#include "networkd-netdev-veth.h"
+#include "networkd-netdev-tunnel.h"
+#include "networkd-netdev-dummy.h"
+#include "networkd-netdev-tuntap.h"
+
+struct NetDevVTable {
+        /* How much memory does an object of this unit type need */
+        size_t object_size;
+
+        /* Config file sections this netdev kind understands, separated
+         * by NUL chars */
+        const char *sections;
+
+        /* This should reset all type-specific variables. This should
+         * not allocate memory, and is called with zero-initialized
+         * data. It should hence only initialize variables that need
+         * to be set != 0. */
+        void (*init)(NetDev *n);
+
+        /* This should free all kind-specific variables. It should be
+         * idempotent. */
+        void (*done)(NetDev *n);
+
+        /* fill in message to create netdev */
+        int (*fill_message_create)(NetDev *netdev, Link *link, sd_rtnl_message *message);
+
+        /* specifies if netdev is independent, or a master device or a stacked device */
+        NetDevCreateType create_type;
+
+        /* create netdev, if not done via rtnl */
+        int (*create)(NetDev *netdev);
+
+        /* verify that compulsory configuration options were specified */
+        int (*config_verify)(NetDev *netdev, const char *filename);
+};
+
+extern const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX];
+
+#define NETDEV_VTABLE(n) netdev_vtable[(n)->kind]
+
+/* For casting a netdev into the various netdev kinds */
+#define DEFINE_CAST(UPPERCASE, MixedCase)                                   \
+        static inline MixedCase* UPPERCASE(NetDev *n) {                     \
+                if (_unlikely_(!n || n->kind != NETDEV_KIND_##UPPERCASE))   \
+                        return NULL;                                        \
+                                                                            \
+                return (MixedCase*) n;                                      \
+        }
+
+/* For casting the various netdev kinds into a netdev */
+#define NETDEV(n) (&(n)->meta)
+
+DEFINE_CAST(BRIDGE, Bridge);
+DEFINE_CAST(BOND, Bond);
+DEFINE_CAST(VLAN, VLan);
+DEFINE_CAST(MACVLAN, MacVlan);
+DEFINE_CAST(VXLAN, VxLan);
+DEFINE_CAST(IPIP, Tunnel);
+DEFINE_CAST(GRE, Tunnel);
+DEFINE_CAST(SIT, Tunnel);
+DEFINE_CAST(VTI, Tunnel);
+DEFINE_CAST(VETH, Veth);
+DEFINE_CAST(DUMMY, Dummy);
+DEFINE_CAST(TUN, TunTap);
+DEFINE_CAST(TAP, TunTap);
+
+int netdev_load(Manager *manager);
+void netdev_drop(NetDev *netdev);
+
+NetDev *netdev_unref(NetDev *netdev);
+NetDev *netdev_ref(NetDev *netdev);
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(NetDev*, netdev_unref);
+#define _cleanup_netdev_unref_ _cleanup_(netdev_unrefp)
+
+int netdev_get(Manager *manager, const char *name, NetDev **ret);
+int netdev_set_ifindex(NetDev *netdev, sd_rtnl_message *newlink);
+int netdev_enslave(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback);
+int netdev_get_mac(const char *ifname, struct ether_addr **ret);
+int netdev_join(NetDev *netdev, Link *link, sd_rtnl_message_handler_t cb);
+
+const char *netdev_kind_to_string(NetDevKind d) _const_;
+NetDevKind netdev_kind_from_string(const char *d) _pure_;
+
+int config_parse_netdev_kind(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+
+/* gperf */
+const struct ConfigPerfItem* network_netdev_gperf_lookup(const char *key, unsigned length);
+
+/* Macros which append INTERFACE= to the message */
+
+#define log_full_netdev(level, netdev, fmt, ...) log_meta_object(level, __FILE__, __LINE__, __func__, "INTERFACE=", netdev->ifname, "%-*s: " fmt, IFNAMSIZ, netdev->ifname, ##__VA_ARGS__)
+#define log_debug_netdev(netdev, ...)       log_full_netdev(LOG_DEBUG, netdev, ##__VA_ARGS__)
+#define log_info_netdev(netdev, ...)        log_full_netdev(LOG_INFO, netdev, ##__VA_ARGS__)
+#define log_notice_netdev(netdev, ...)      log_full_netdev(LOG_NOTICE, netdev, ##__VA_ARGS__)
+#define log_warning_netdev(netdev, ...)     log_full_netdev(LOG_WARNING, netdev,## __VA_ARGS__)
+#define log_error_netdev(netdev, ...)       log_full_netdev(LOG_ERR, netdev, ##__VA_ARGS__)
+
+#define log_struct_netdev(level, netdev, ...) log_struct(level, "INTERFACE=%s", netdev->ifname, __VA_ARGS__)
+
+#define NETDEVIF(netdev) "INTERFACE=%s", netdev->ifname
index 44aeb9c..c5b9614 100644 (file)
@@ -2,7 +2,7 @@
 #include <stddef.h>
 #include "conf-parser.h"
 #include "networkd.h"
-#include "net-util.h"
+#include "network-internal.h"
 %}
 struct ConfigPerfItem;
 %null_strings
@@ -25,20 +25,42 @@ Match.Virtualization,        config_parse_net_condition,         CONDITION_VIRTU
 Match.KernelCommandLine,     config_parse_net_condition,         CONDITION_KERNEL_COMMAND_LINE, offsetof(Network, match_kernel)
 Match.Architecture,          config_parse_net_condition,         CONDITION_ARCHITECTURE,        offsetof(Network, match_arch)
 Network.Description,         config_parse_string,                0,                             offsetof(Network, description)
-Network.Bridge,              config_parse_bridge,                0,                             offsetof(Network, bridge)
-Network.Bond,                config_parse_bond,                  0,                             offsetof(Network, bond)
-Network.VLAN,                config_parse_vlan,                  0,                             offsetof(Network, vlans)
-Network.DHCP,                config_parse_bool,                  0,                             offsetof(Network, dhcp)
+Network.Bridge,              config_parse_netdev,                0,                             offsetof(Network, bridge)
+Network.Bond,                config_parse_netdev,                0,                             offsetof(Network, bond)
+Network.VLAN,                config_parse_netdev,                0,                             0
+Network.MACVLAN,             config_parse_netdev,                0,                             0
+Network.VXLAN,               config_parse_netdev,                0,                             0
+Network.Tunnel,              config_parse_tunnel,                0,                             0
+Network.DHCP,                config_parse_dhcp,                  0,                             offsetof(Network, dhcp)
+Network.DHCPServer,          config_parse_bool,                  0,                             offsetof(Network, dhcp_server)
+Network.IPv4LL,              config_parse_bool,                  0,                             offsetof(Network, ipv4ll)
+Network.IPv4LLRoute,         config_parse_bool,                  0,                             offsetof(Network, ipv4ll_route)
 Network.Address,             config_parse_address,               0,                             0
 Network.Gateway,             config_parse_gateway,               0,                             0
-Network.DNS,                 config_parse_dns,                   0,                             offsetof(Network, dns)
+Network.Domains,             config_parse_domains,               0,                             offsetof(Network, domains)
+Network.DNS,                 config_parse_strv,                  0,                             offsetof(Network, dns)
+Network.LLMNR,               config_parse_llmnr,                 0,                             offsetof(Network, llmnr)
+Network.NTP,                 config_parse_strv,                  0,                             offsetof(Network, ntp)
 Address.Address,             config_parse_address,               0,                             0
+Address.Peer,                config_parse_address,               0,                             0
 Address.Broadcast,           config_parse_broadcast,             0,                             0
 Address.Label,               config_parse_label,                 0,                             0
 Route.Gateway,               config_parse_gateway,               0,                             0
 Route.Destination,           config_parse_destination,           0,                             0
+Route.Metric,                config_parse_route_priority,        0,                             0
+DHCP.UseDNS,                 config_parse_bool,                  0,                             offsetof(Network, dhcp_dns)
+DHCP.UseMTU,                 config_parse_bool,                  0,                             offsetof(Network, dhcp_mtu)
+DHCP.UseHostname,            config_parse_bool,                  0,                             offsetof(Network, dhcp_hostname)
+DHCP.UseDomains,             config_parse_bool,                  0,                             offsetof(Network, dhcp_domains)
+DHCP.UseRoutes,              config_parse_bool,                  0,                             offsetof(Network, dhcp_routes)
+DHCP.SendHostname,           config_parse_bool,                  0,                             offsetof(Network, dhcp_sendhost)
+DHCP.RequestBroadcast,       config_parse_bool,                  0,                             offsetof(Network, dhcp_broadcast)
+DHCP.CriticalConnection,     config_parse_bool,                  0,                             offsetof(Network, dhcp_critical)
+DHCP.VendorClassIdentifier,  config_parse_string,                0,                             offsetof(Network, dhcp_vendor_class_identifier)
+/* backwards compatibility: do not add new entries to this section */
 DHCPv4.UseDNS,               config_parse_bool,                  0,                             offsetof(Network, dhcp_dns)
 DHCPv4.UseMTU,               config_parse_bool,                  0,                             offsetof(Network, dhcp_mtu)
 DHCPv4.UseHostname,          config_parse_bool,                  0,                             offsetof(Network, dhcp_hostname)
-DHCPv4.UseDomainName,        config_parse_bool,                  0,                             offsetof(Network, dhcp_domainname)
+DHCP.UseDomainName,          config_parse_bool,                  0,                             offsetof(Network, dhcp_domains)
+DHCPv4.UseDomainName,        config_parse_bool,                  0,                             offsetof(Network, dhcp_domains)
 DHCPv4.CriticalConnection,   config_parse_bool,                  0,                             offsetof(Network, dhcp_critical)
index 14fa92a..fc62395 100644 (file)
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
+#include <ctype.h>
+#include <net/if.h>
+
 #include "networkd.h"
-#include "net-util.h"
+#include "networkd-netdev.h"
+#include "networkd-link.h"
+#include "network-internal.h"
 #include "path-util.h"
 #include "conf-files.h"
 #include "conf-parser.h"
@@ -41,7 +46,12 @@ static int network_load_one(Manager *manager, const char *filename) {
                 if (errno == ENOENT)
                         return 0;
                 else
-                        return errno;
+                        return -errno;
+        }
+
+        if (null_or_empty_fd(fileno(file))) {
+                log_debug("Skipping empty file: %s", filename);
+                return 0;
         }
 
         network = new0(Network, 1);
@@ -53,15 +63,15 @@ static int network_load_one(Manager *manager, const char *filename) {
         LIST_HEAD_INIT(network->static_addresses);
         LIST_HEAD_INIT(network->static_routes);
 
-        network->vlans = hashmap_new(uint64_hash_func, uint64_compare_func);
-        if (!network->vlans)
+        network->stacked_netdevs = hashmap_new(string_hash_func, string_compare_func);
+        if (!network->stacked_netdevs)
                 return log_oom();
 
-        network->addresses_by_section = hashmap_new(uint64_hash_func, uint64_compare_func);
+        network->addresses_by_section = hashmap_new(NULL, NULL);
         if (!network->addresses_by_section)
                 return log_oom();
 
-        network->routes_by_section = hashmap_new(uint64_hash_func, uint64_compare_func);
+        network->routes_by_section = hashmap_new(NULL, NULL);
         if (!network->routes_by_section)
                 return log_oom();
 
@@ -69,20 +79,25 @@ static int network_load_one(Manager *manager, const char *filename) {
         if (!network->filename)
                 return log_oom();
 
+        network->dhcp = DHCP_SUPPORT_NONE;
+        network->dhcp_ntp = true;
         network->dhcp_dns = true;
         network->dhcp_hostname = true;
-        network->dhcp_domainname = true;
+        network->dhcp_routes = true;
+        network->dhcp_sendhost = true;
 
-        r = config_parse(NULL, filename, file, "Match\0Network\0Address\0Route\0DHCPv4\0", config_item_perf_lookup,
-                        (void*) network_network_gperf_lookup, false, false, network);
-        if (r < 0) {
-                log_warning("Could not parse config file %s: %s", filename, strerror(-r));
+        network->llmnr = LLMNR_SUPPORT_YES;
+
+        r = config_parse(NULL, filename, file,
+                         "Match\0Network\0Address\0Route\0DHCP\0DHCPv4\0",
+                         config_item_perf_lookup, network_network_gperf_lookup,
+                         false, false, true, network);
+        if (r < 0)
                 return r;
-        }
 
         LIST_PREPEND(networks, manager->networks, network);
 
-        LIST_FOREACH(static_routes, route, network->static_routes) {
+        LIST_FOREACH(routes, route, network->static_routes) {
                 if (!route->family) {
                         log_warning("Route section without Gateway field configured in %s. "
                                     "Ignoring", filename);
@@ -90,7 +105,7 @@ static int network_load_one(Manager *manager, const char *filename) {
                 }
         }
 
-        LIST_FOREACH(static_addresses, address, network->static_addresses) {
+        LIST_FOREACH(addresses, address, network->static_addresses) {
                 if (!address->family) {
                         log_warning("Address section without Address field configured in %s. "
                                     "Ignoring", filename);
@@ -130,8 +145,10 @@ int network_load(Manager *manager) {
 }
 
 void network_free(Network *network) {
+        NetDev *netdev;
         Route *route;
         Address *address;
+        Iterator i;
 
         if (!network)
                 return;
@@ -145,10 +162,21 @@ void network_free(Network *network) {
         free(network->match_name);
 
         free(network->description);
+        free(network->dhcp_vendor_class_identifier);
 
-        address_free(network->dns);
+        strv_free(network->ntp);
+        strv_free(network->dns);
+        strv_free(network->domains);
 
-        hashmap_free(network->vlans);
+        netdev_unref(network->bridge);
+
+        netdev_unref(network->bond);
+
+        HASHMAP_FOREACH(netdev, network->stacked_netdevs, i) {
+                hashmap_remove(network->stacked_netdevs, netdev->ifname);
+                netdev_unref(netdev);
+        }
+        hashmap_free(network->stacked_netdevs);
 
         while ((route = network->static_routes))
                 route_free(route);
@@ -162,31 +190,36 @@ void network_free(Network *network) {
         if (network->manager && network->manager->networks)
                 LIST_REMOVE(networks, network->manager->networks, network);
 
+        condition_free_list(network->match_host);
+        condition_free_list(network->match_virt);
+        condition_free_list(network->match_kernel);
+        condition_free_list(network->match_arch);
+
         free(network);
 }
 
-int network_get(Manager *manager, struct udev_device *device, Network **ret) {
+int network_get(Manager *manager, struct udev_device *device,
+                const char *ifname, const struct ether_addr *address,
+                Network **ret) {
         Network *network;
 
         assert(manager);
-        assert(device);
         assert(ret);
 
         LIST_FOREACH(networks, network, manager->networks) {
                 if (net_match_config(network->match_mac, network->match_path,
-                                        network->match_driver, network->match_type,
-                                        network->match_name, network->match_host,
-                                        network->match_virt, network->match_kernel,
-                                        network->match_arch,
-                                        udev_device_get_sysattr_value(device, "address"),
-                                        udev_device_get_property_value(device, "ID_PATH"),
-                                        udev_device_get_driver(udev_device_get_parent(device)),
-                                        udev_device_get_property_value(device, "ID_NET_DRIVER"),
-                                        udev_device_get_devtype(device),
-                                        udev_device_get_sysname(device))) {
-                        log_debug("%s: found matching network '%s'",
-                                        udev_device_get_sysname(device),
-                                        network->filename);
+                                     network->match_driver, network->match_type,
+                                     network->match_name, network->match_host,
+                                     network->match_virt, network->match_kernel,
+                                     network->match_arch,
+                                     address,
+                                     udev_device_get_property_value(device, "ID_PATH"),
+                                     udev_device_get_driver(udev_device_get_parent(device)),
+                                     udev_device_get_property_value(device, "ID_NET_DRIVER"),
+                                     udev_device_get_devtype(device),
+                                     ifname)) {
+                        log_debug("%-*s: found matching network '%s'", IFNAMSIZ, ifname,
+                                  network->filename);
                         *ret = network;
                         return 0;
                 }
@@ -202,12 +235,28 @@ int network_apply(Manager *manager, Network *network, Link *link) {
 
         link->network = network;
 
-        r = link_configure(link);
-        if (r < 0)
-                return r;
+        if (network->ipv4ll_route) {
+                Route *route;
 
-        if (network->dns) {
-                r = manager_update_resolv_conf(manager);
+                r = route_new_static(network, 0, &route);
+                if (r < 0)
+                        return r;
+
+                r = inet_pton(AF_INET, "169.254.0.0", &route->dst_addr.in);
+                if (r == 0)
+                        return -EINVAL;
+                if (r < 0)
+                        return -errno;
+
+                route->family = AF_INET;
+                route->dst_prefixlen = 16;
+                route->scope = RT_SCOPE_LINK;
+                route->metrics = IPV4LL_ROUTE_METRIC;
+                route->protocol = RTPROT_STATIC;
+        }
+
+        if (network->dns || network->ntp) {
+                r = link_save(link);
                 if (r < 0)
                         return r;
         }
@@ -215,7 +264,7 @@ int network_apply(Manager *manager, Network *network, Link *link) {
         return 0;
 }
 
-int config_parse_bridge(const char *unit,
+int config_parse_netdev(const char *unit,
                 const char *filename,
                 unsigned line,
                 const char *section,
@@ -226,7 +275,10 @@ int config_parse_bridge(const char *unit,
                 void *data,
                 void *userdata) {
         Network *network = userdata;
+        _cleanup_free_ char *kind_string = NULL;
+        char *p;
         NetDev *netdev;
+        NetDevKind kind;
         int r;
 
         assert(filename);
@@ -234,34 +286,115 @@ int config_parse_bridge(const char *unit,
         assert(rvalue);
         assert(data);
 
+        kind_string = strdup(lvalue);
+        if (!kind_string)
+                return log_oom();
+
+        /* the keys are CamelCase versions of the kind */
+        for (p = kind_string; *p; p++)
+                *p = tolower(*p);
+
+        kind = netdev_kind_from_string(kind_string);
+        if (kind == _NETDEV_KIND_INVALID) {
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                           "Invalid NetDev kind: %s", lvalue);
+                return 0;
+        }
+
         r = netdev_get(network->manager, rvalue, &netdev);
         if (r < 0) {
                 log_syntax(unit, LOG_ERR, filename, line, EINVAL,
-                           "Bridge is invalid, ignoring assignment: %s", rvalue);
+                           "%s could not be found, ignoring assignment: %s", lvalue, rvalue);
                 return 0;
         }
 
-        if (netdev->kind != NETDEV_KIND_BRIDGE) {
+        if (netdev->kind != kind) {
                 log_syntax(unit, LOG_ERR, filename, line, EINVAL,
-                           "NetDev is not a bridge, ignoring assignment: %s", rvalue);
+                           "NetDev is not a %s, ignoring assignment: %s", lvalue, rvalue);
                 return 0;
         }
 
-        network->bridge = netdev;
+        switch (kind) {
+        case NETDEV_KIND_BRIDGE:
+                network->bridge = netdev;
+
+                break;
+        case NETDEV_KIND_BOND:
+                network->bond = netdev;
+
+                break;
+        case NETDEV_KIND_VLAN:
+        case NETDEV_KIND_MACVLAN:
+        case NETDEV_KIND_VXLAN:
+                r = hashmap_put(network->stacked_netdevs, netdev->ifname, netdev);
+                if (r < 0) {
+                        log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                                   "Can not add VLAN '%s' to network: %s",
+                                   rvalue, strerror(-r));
+                        return 0;
+                }
+
+                break;
+        default:
+                assert_not_reached("Can not parse NetDev");
+        }
+
+        netdev_ref(netdev);
 
         return 0;
 }
 
-int config_parse_bond(const char *unit,
-                const char *filename,
-                unsigned line,
-                const char *section,
-                unsigned section_line,
-                const char *lvalue,
-                int ltype,
-                const char *rvalue,
-                void *data,
-                void *userdata) {
+int config_parse_domains(const char *unit,
+                         const char *filename,
+                         unsigned line,
+                         const char *section,
+                         unsigned section_line,
+                         const char *lvalue,
+                         int ltype,
+                         const char *rvalue,
+                         void *data,
+                         void *userdata) {
+        Network *network = userdata;
+        char ***domains = data;
+        char **domain;
+        int r;
+
+        r = config_parse_strv(unit, filename, line, section, section_line,
+                              lvalue, ltype, rvalue, domains, userdata);
+        if (r < 0)
+                return r;
+
+        strv_uniq(*domains);
+        network->wildcard_domain = !!strv_find(*domains, "*");
+
+        STRV_FOREACH(domain, *domains) {
+                if (is_localhost(*domain))
+                        log_syntax(unit, LOG_ERR, filename, line, EINVAL, "'localhost' domain names may not be configured, ignoring assignment: %s", *domain);
+                else if (!hostname_is_valid(*domain)) {
+                        if (!streq(*domain, "*"))
+                                log_syntax(unit, LOG_ERR, filename, line, EINVAL, "domain name is not valid, ignoring assignment: %s", *domain);
+                } else
+                        continue;
+
+                strv_remove(*domains, *domain);
+
+                /* We removed one entry, make sure we don't skip the next one */
+                domain--;
+        }
+
+        return 0;
+}
+
+int config_parse_tunnel(const char *unit,
+                        const char *filename,
+                        unsigned line,
+                        const char *section,
+                        unsigned section_line,
+                        const char *lvalue,
+                        int ltype,
+                        const char *rvalue,
+                        void *data,
+                        void *userdata) {
         Network *network = userdata;
         NetDev *netdev;
         int r;
@@ -274,22 +407,43 @@ int config_parse_bond(const char *unit,
         r = netdev_get(network->manager, rvalue, &netdev);
         if (r < 0) {
                 log_syntax(unit, LOG_ERR, filename, line, EINVAL,
-                           "Bond is invalid, ignoring assignment: %s", rvalue);
+                           "Tunnel is invalid, ignoring assignment: %s", rvalue);
+                return 0;
+        }
+
+        if (netdev->kind != NETDEV_KIND_IPIP &&
+            netdev->kind != NETDEV_KIND_SIT &&
+            netdev->kind != NETDEV_KIND_GRE &&
+            netdev->kind != NETDEV_KIND_VTI) {
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                           "NetDev is not a tunnel, ignoring assignment: %s", rvalue);
                 return 0;
         }
 
-        if (netdev->kind != NETDEV_KIND_BOND) {
+        r = hashmap_put(network->stacked_netdevs, netdev->ifname, netdev);
+        if (r < 0) {
                 log_syntax(unit, LOG_ERR, filename, line, EINVAL,
-                           "NetDev is not a bond, ignoring assignment: %s", rvalue);
+                           "Can not add VLAN '%s' to network: %s",
+                           rvalue, strerror(-r));
                 return 0;
         }
 
-        network->bond = netdev;
+        netdev_ref(netdev);
 
         return 0;
 }
 
-int config_parse_vlan(const char *unit,
+static const char* const dhcp_support_table[_DHCP_SUPPORT_MAX] = {
+        [DHCP_SUPPORT_NONE] = "none",
+        [DHCP_SUPPORT_BOTH] = "both",
+        [DHCP_SUPPORT_V4] = "v4",
+        [DHCP_SUPPORT_V6] = "v6",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(dhcp_support, DHCPSupport);
+
+int config_parse_dhcp(
+                const char* unit,
                 const char *filename,
                 unsigned line,
                 const char *section,
@@ -299,33 +453,84 @@ int config_parse_vlan(const char *unit,
                 const char *rvalue,
                 void *data,
                 void *userdata) {
-        Network *network = userdata;
-        NetDev *netdev;
-        int r;
+
+        DHCPSupport *dhcp = data;
+        int k;
 
         assert(filename);
         assert(lvalue);
         assert(rvalue);
         assert(data);
 
-        r = netdev_get(network->manager, rvalue, &netdev);
-        if (r < 0) {
-                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
-                           "VLAN is invalid, ignoring assignment: %s", rvalue);
-                return 0;
-        }
+        /* Our enum shall be a superset of booleans, hence first try
+         * to parse as boolean, and then as enum */
 
-        if (netdev->kind != NETDEV_KIND_VLAN) {
-                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
-                           "NetDev is not a VLAN, ignoring assignment: %s", rvalue);
-                return 0;
+        k = parse_boolean(rvalue);
+        if (k > 0)
+                *dhcp = DHCP_SUPPORT_BOTH;
+        else if (k == 0)
+                *dhcp = DHCP_SUPPORT_NONE;
+        else {
+                DHCPSupport s;
+
+                s = dhcp_support_from_string(rvalue);
+                if (s < 0){
+                        log_syntax(unit, LOG_ERR, filename, line, -s, "Failed to parse DHCP option, ignoring: %s", rvalue);
+                        return 0;
+                }
+
+                *dhcp = s;
         }
 
-        r = hashmap_put(network->vlans, &netdev->vlanid, netdev);
-        if (r < 0) {
-                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
-                           "Can not add VLAN to network: %s", rvalue);
-                return 0;
+        return 0;
+}
+
+static const char* const llmnr_support_table[_LLMNR_SUPPORT_MAX] = {
+        [LLMNR_SUPPORT_NO] = "no",
+        [LLMNR_SUPPORT_YES] = "yes",
+        [LLMNR_SUPPORT_RESOLVE] = "resolve",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(llmnr_support, LLMNRSupport);
+
+int config_parse_llmnr(
+                const char* unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        LLMNRSupport *llmnr = data;
+        int k;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        /* Our enum shall be a superset of booleans, hence first try
+         * to parse as boolean, and then as enum */
+
+        k = parse_boolean(rvalue);
+        if (k > 0)
+                *llmnr = LLMNR_SUPPORT_YES;
+        else if (k == 0)
+                *llmnr = LLMNR_SUPPORT_NO;
+        else {
+                LLMNRSupport s;
+
+                s = llmnr_support_from_string(rvalue);
+                if (s < 0){
+                        log_syntax(unit, LOG_ERR, filename, line, -s, "Failed to parse LLMNR option, ignoring: %s", rvalue);
+                        return 0;
+                }
+
+                *llmnr = s;
         }
 
         return 0;
index 46a4537..aead4fb 100644 (file)
 #include <net/if.h>
 
 #include "networkd.h"
+#include "networkd-link.h"
 
 #include "utf8.h"
 #include "util.h"
 #include "conf-parser.h"
-#include "net-util.h"
+#include "network-internal.h"
 
 int route_new_static(Network *network, unsigned section, Route **ret) {
         _cleanup_route_free_ Route *route = NULL;
 
         if (section) {
-                uint64_t key = section;
-
-                route = hashmap_get(network->routes_by_section, &key);
+                route = hashmap_get(network->routes_by_section,
+                                    UINT_TO_PTR(section));
                 if (route) {
                         *ret = route;
                         route = NULL;
@@ -48,14 +48,17 @@ int route_new_static(Network *network, unsigned section, Route **ret) {
                 return -ENOMEM;
 
         route->family = AF_UNSPEC;
+        route->scope = RT_SCOPE_UNIVERSE;
+        route->protocol = RTPROT_STATIC;
 
         route->network = network;
 
-        LIST_PREPEND(static_routes, network->static_routes, route);
+        LIST_PREPEND(routes, network->static_routes, route);
 
         if (section) {
                 route->section = section;
-                hashmap_put(network->routes_by_section, &route->section, route);
+                hashmap_put(network->routes_by_section,
+                            UINT_TO_PTR(route->section), route);
         }
 
         *ret = route;
@@ -64,7 +67,7 @@ int route_new_static(Network *network, unsigned section, Route **ret) {
         return 0;
 }
 
-int route_new_dynamic(Route **ret) {
+int route_new_dynamic(Route **ret, unsigned char rtm_protocol) {
         _cleanup_route_free_ Route *route = NULL;
 
         route = new0(Route, 1);
@@ -72,6 +75,8 @@ int route_new_dynamic(Route **ret) {
                 return -ENOMEM;
 
         route->family = AF_UNSPEC;
+        route->scope = RT_SCOPE_UNIVERSE;
+        route->protocol = rtm_protocol;
 
         *ret = route;
         route = NULL;
@@ -84,16 +89,90 @@ void route_free(Route *route) {
                 return;
 
         if (route->network) {
-                LIST_REMOVE(static_routes, route->network->static_routes, route);
+                LIST_REMOVE(routes, route->network->static_routes, route);
 
                 if (route->section)
                         hashmap_remove(route->network->routes_by_section,
-                                       &route->section);
+                                       UINT_TO_PTR(route->section));
         }
 
         free(route);
 }
 
+int route_drop(Route *route, Link *link,
+               sd_rtnl_message_handler_t callback) {
+        _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
+        int r;
+
+        assert(link);
+        assert(link->manager);
+        assert(link->manager->rtnl);
+        assert(link->ifindex > 0);
+        assert(route->family == AF_INET || route->family == AF_INET6);
+
+        r = sd_rtnl_message_new_route(link->manager->rtnl, &req,
+                                      RTM_DELROUTE, route->family,
+                                      route->protocol);
+        if (r < 0) {
+                log_error("Could not create RTM_DELROUTE message: %s", strerror(-r));
+                return r;
+        }
+
+        if (route->family == AF_INET)
+                r = sd_rtnl_message_append_in_addr(req, RTA_GATEWAY, &route->in_addr.in);
+        else if (route->family == AF_INET6)
+                r = sd_rtnl_message_append_in6_addr(req, RTA_GATEWAY, &route->in_addr.in6);
+        if (r < 0) {
+                log_error("Could not append RTA_GATEWAY attribute: %s", strerror(-r));
+                return r;
+        }
+
+        if (route->dst_prefixlen) {
+                if (route->family == AF_INET)
+                        r = sd_rtnl_message_append_in_addr(req, RTA_DST, &route->dst_addr.in);
+                else if (route->family == AF_INET6)
+                        r = sd_rtnl_message_append_in6_addr(req, RTA_DST, &route->dst_addr.in6);
+                if (r < 0) {
+                        log_error("Could not append RTA_DST attribute: %s", strerror(-r));
+                        return r;
+                }
+
+                r = sd_rtnl_message_route_set_dst_prefixlen(req, route->dst_prefixlen);
+                if (r < 0) {
+                        log_error("Could not set destination prefix length: %s", strerror(-r));
+                        return r;
+                }
+        }
+
+        r = sd_rtnl_message_route_set_scope(req, route->scope);
+        if (r < 0) {
+                log_error("Could not set scope: %s", strerror(-r));
+                return r;
+        }
+
+        r = sd_rtnl_message_append_u32(req, RTA_PRIORITY, route->metrics);
+        if (r < 0) {
+                log_error("Could not append RTA_PRIORITY attribute: %s", strerror(-r));
+                return r;
+        }
+
+        r = sd_rtnl_message_append_u32(req, RTA_OIF, link->ifindex);
+        if (r < 0) {
+                log_error("Could not append RTA_OIF attribute: %s", strerror(-r));
+                return r;
+        }
+
+        r = sd_rtnl_call_async(link->manager->rtnl, req, callback, link, 0, NULL);
+        if (r < 0) {
+                log_error("Could not send rtnetlink message: %s", strerror(-r));
+                return r;
+        }
+
+        link_ref(link);
+
+        return 0;
+}
+
 int route_configure(Route *route, Link *link,
                     sd_rtnl_message_handler_t callback) {
         _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
@@ -106,7 +185,8 @@ int route_configure(Route *route, Link *link,
         assert(route->family == AF_INET || route->family == AF_INET6);
 
         r = sd_rtnl_message_new_route(link->manager->rtnl, &req,
-                                      RTM_NEWROUTE, route->family);
+                                      RTM_NEWROUTE, route->family,
+                                      route->protocol);
         if (r < 0) {
                 log_error("Could not create RTM_NEWROUTE message: %s", strerror(-r));
                 return r;
@@ -138,6 +218,18 @@ int route_configure(Route *route, Link *link,
                 }
         }
 
+        r = sd_rtnl_message_route_set_scope(req, route->scope);
+        if (r < 0) {
+                log_error("Could not set scope: %s", strerror(-r));
+                return r;
+        }
+
+        r = sd_rtnl_message_append_u32(req, RTA_PRIORITY, route->metrics);
+        if (r < 0) {
+                log_error("Could not append RTA_PRIORITY attribute: %s", strerror(-r));
+                return r;
+        }
+
         r = sd_rtnl_message_append_u32(req, RTA_OIF, link->ifindex);
         if (r < 0) {
                 log_error("Could not append RTA_OIF attribute: %s", strerror(-r));
@@ -150,6 +242,8 @@ int route_configure(Route *route, Link *link,
                 return r;
         }
 
+        link_ref(link);
+
         return 0;
 }
 
@@ -163,10 +257,11 @@ int config_parse_gateway(const char *unit,
                 const char *rvalue,
                 void *data,
                 void *userdata) {
+
         Network *network = userdata;
         _cleanup_route_free_ Route *n = NULL;
-        _cleanup_free_ char *route = NULL;
-        int r;
+        union in_addr_union buffer;
+        int r, f;
 
         assert(filename);
         assert(section);
@@ -184,13 +279,15 @@ int config_parse_gateway(const char *unit,
         if (r < 0)
                 return r;
 
-        r = net_parse_inaddr(rvalue, &n->family, &n->in_addr);
+        r = in_addr_from_string_auto(rvalue, &f, &buffer);
         if (r < 0) {
                 log_syntax(unit, LOG_ERR, filename, line, EINVAL,
-                           "Route is invalid, ignoring assignment: %s", route);
+                           "Route is invalid, ignoring assignment: %s", rvalue);
                 return 0;
         }
 
+        n->family = f;
+        n->in_addr = buffer;
         n = NULL;
 
         return 0;
@@ -206,11 +303,12 @@ int config_parse_destination(const char *unit,
                 const char *rvalue,
                 void *data,
                 void *userdata) {
+
         Network *network = userdata;
         _cleanup_route_free_ Route *n = NULL;
-        _cleanup_free_ char *address = NULL;
-        const char *e;
-        int r;
+        const char *address, *e;
+        union in_addr_union buffer;
+        int r, f;
 
         assert(filename);
         assert(section);
@@ -226,17 +324,12 @@ int config_parse_destination(const char *unit,
 
         /* address */
         e = strchr(rvalue, '/');
-        if (e) {
-                address = strndup(rvalue, e - rvalue);
-                if (!address)
-                        return log_oom();
-        } else {
-                address = strdup(rvalue);
-                if (!address)
-                        return log_oom();
-        }
+        if (e)
+                address = strndupa(rvalue, e - rvalue);
+        else
+                address = rvalue;
 
-        r = net_parse_inaddr(address, &n->family, &n->dst_addr);
+        r = in_addr_from_string_auto(address, &f, &buffer);
         if (r < 0) {
                 log_syntax(unit, LOG_ERR, filename, line, EINVAL,
                            "Destination is invalid, ignoring assignment: %s", address);
@@ -250,8 +343,7 @@ int config_parse_destination(const char *unit,
                 r = safe_atou(e + 1, &i);
                 if (r < 0) {
                         log_syntax(unit, LOG_ERR, filename, line, EINVAL,
-                                   "Route destination prefix length is invalid, "
-                                   "ignoring assignment: %s", e + 1);
+                                   "Route destination prefix length is invalid, ignoring assignment: %s", e + 1);
                         return 0;
                 }
 
@@ -267,6 +359,43 @@ int config_parse_destination(const char *unit,
                 }
         }
 
+        n->family = f;
+        n->dst_addr = buffer;
+        n = NULL;
+
+        return 0;
+}
+
+int config_parse_route_priority(const char *unit,
+                                const char *filename,
+                                unsigned line,
+                                const char *section,
+                                unsigned section_line,
+                                const char *lvalue,
+                                int ltype,
+                                const char *rvalue,
+                                void *data,
+                                void *userdata) {
+        Network *network = userdata;
+        _cleanup_route_free_ Route *n = NULL;
+        int r;
+
+        assert(filename);
+        assert(section);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        r = route_new_static(network, section_line, &n);
+        if (r < 0)
+                return r;
+
+        r = config_parse_unsigned(unit, filename, line, section,
+                                  section_line, lvalue, ltype,
+                                  rvalue, &n->metrics, userdata);
+        if (r < 0)
+                return r;
+
         n = NULL;
 
         return 0;
diff --git a/src/network/networkd-wait-online-link.c b/src/network/networkd-wait-online-link.c
new file mode 100644 (file)
index 0000000..f23c7ce
--- /dev/null
@@ -0,0 +1,146 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+  Copyright 2014 Tom Gundersen
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <net/if.h>
+
+#include "sd-network.h"
+#include "strv.h"
+
+#include "networkd-wait-online-link.h"
+
+int link_new(Manager *m, Link **ret, int ifindex, const char *ifname) {
+        _cleanup_(link_freep) Link *l = NULL;
+        int r;
+
+        assert(m);
+        assert(ifindex > 0);
+
+        r = hashmap_ensure_allocated(&m->links, NULL, NULL);
+        if (r < 0)
+                return r;
+
+        r = hashmap_ensure_allocated(&m->links_by_name,
+                                     string_hash_func, string_compare_func);
+        if (r < 0)
+                return r;
+
+        l = new0(Link, 1);
+        if (!l)
+                return -ENOMEM;
+
+        l->manager = m;
+
+        l->ifname = strdup(ifname);
+        if (!l->ifname)
+                return -ENOMEM;
+
+        r = hashmap_put(m->links_by_name, l->ifname, l);
+        if (r < 0)
+                return r;
+
+        l->ifindex = ifindex;
+
+        r = hashmap_put(m->links, INT_TO_PTR(ifindex), l);
+        if (r < 0)
+                return r;
+
+        if (ret)
+                *ret = l;
+        l = NULL;
+
+        return 0;
+}
+
+Link *link_free(Link *l) {
+
+        if (!l)
+                return NULL;
+
+        if (l->manager) {
+                hashmap_remove(l->manager->links, INT_TO_PTR(l->ifindex));
+                hashmap_remove(l->manager->links_by_name, l->ifname);
+        }
+
+        free(l->ifname);
+        free(l);
+        return NULL;
+ }
+
+int link_update_rtnl(Link *l, sd_rtnl_message *m) {
+        const char *ifname;
+        int r;
+
+        assert(l);
+        assert(l->manager);
+        assert(m);
+
+        r = sd_rtnl_message_link_get_flags(m, &l->flags);
+        if (r < 0)
+                return r;
+
+        r = sd_rtnl_message_read_string(m, IFLA_IFNAME, &ifname);
+        if (r < 0)
+                return r;
+
+        if (!streq(l->ifname, ifname)) {
+                char *new_ifname;
+
+                new_ifname = strdup(ifname);
+                if (!new_ifname)
+                        return -ENOMEM;
+
+                hashmap_remove(l->manager->links_by_name, l->ifname);
+                free(l->ifname);
+                l->ifname = new_ifname;
+
+                r = hashmap_put(l->manager->links_by_name, l->ifname, l);
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
+int link_update_monitor(Link *l) {
+        assert(l);
+
+        free(l->operational_state);
+        l->operational_state = NULL;
+
+        sd_network_link_get_operational_state(l->ifindex, &l->operational_state);
+
+        free(l->state);
+        l->state = NULL;
+
+        sd_network_link_get_setup_state(l->ifindex, &l->state);
+
+        return 0;
+}
+
+bool link_relevant(Link *l) {
+        assert(l);
+
+        if (l->flags & IFF_LOOPBACK)
+                return false;
+
+        return true;
+}
diff --git a/src/network/networkd-wait-online-link.h b/src/network/networkd-wait-online-link.h
new file mode 100644 (file)
index 0000000..90ea6b3
--- /dev/null
@@ -0,0 +1,46 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+  Copyright 2014 Tom Gundersen
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+typedef struct Link Link;
+
+#include "networkd-wait-online.h"
+
+struct Link {
+        Manager *manager;
+
+        int ifindex;
+        char *ifname;
+        unsigned flags;
+
+        char *operational_state;
+        char *state;
+};
+
+int link_new(Manager *m, Link **ret, int ifindex, const char *ifname);
+Link *link_free(Link *l);
+int link_update_rtnl(Link *l, sd_rtnl_message *m);
+int link_update_monitor(Link *l);
+bool link_relevant(Link *l);
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(Link*, link_free);
diff --git a/src/network/networkd-wait-online-manager.c b/src/network/networkd-wait-online-manager.c
new file mode 100644 (file)
index 0000000..6e3ec69
--- /dev/null
@@ -0,0 +1,304 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2013 Tom Gundersen <teg@jklm.no>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <netinet/ether.h>
+#include <linux/if.h>
+
+#include "rtnl-util.h"
+
+#include "network-util.h"
+#include "network-internal.h"
+#include "networkd-wait-online-link.h"
+#include "networkd-wait-online.h"
+
+#include "util.h"
+
+bool manager_all_configured(Manager *m) {
+        Iterator i;
+        Link *l;
+        char **ifname;
+        bool one_ready = false;
+
+        /* wait for all the links given on the commandline to appear */
+        STRV_FOREACH(ifname, m->interfaces) {
+                l = hashmap_get(m->links_by_name, *ifname);
+                if (!l) {
+                        log_debug("still waiting for %s", *ifname);
+                        return false;
+                }
+        }
+
+        /* wait for all links networkd manages to be in admin state 'configured'
+           and at least one link to gain a carrier */
+        HASHMAP_FOREACH(l, m->links, i) {
+                if (!link_relevant(l)) {
+                        log_info("ignore irrelevant link: %s", l->ifname);
+                        continue;
+                }
+
+                if (!l->state) {
+                        log_debug("link %s has not yet been processed by udev",
+                                  l->ifname);
+                        return false;
+                }
+
+                if (streq(l->state, "configuring")) {
+                        log_debug("link %s is being processed by networkd",
+                                  l->ifname);
+                        return false;
+                }
+
+                if (l->operational_state &&
+                    STR_IN_SET(l->operational_state, "degraded", "routable"))
+                        /* we wait for at least one link to be ready,
+                           regardless of who manages it */
+                        one_ready = true;
+        }
+
+        return one_ready;
+}
+
+static int manager_process_link(sd_rtnl *rtnl, sd_rtnl_message *mm, void *userdata) {
+        Manager *m = userdata;
+        uint16_t type;
+        Link *l;
+        const char *ifname;
+        int ifindex, r;
+
+        assert(rtnl);
+        assert(m);
+        assert(mm);
+
+        r = sd_rtnl_message_get_type(mm, &type);
+        if (r < 0)
+                goto fail;
+
+        r = sd_rtnl_message_link_get_ifindex(mm, &ifindex);
+        if (r < 0)
+                goto fail;
+
+        r = sd_rtnl_message_read_string(mm, IFLA_IFNAME, &ifname);
+        if (r < 0)
+                goto fail;
+
+        l = hashmap_get(m->links, INT_TO_PTR(ifindex));
+
+        switch (type) {
+
+        case RTM_NEWLINK:
+                if (!l) {
+                        log_debug("Found link %i", ifindex);
+
+                        r = link_new(m, &l, ifindex, ifname);
+                        if (r < 0)
+                                goto fail;
+
+                        r = link_update_monitor(l);
+                        if (r < 0)
+                                goto fail;
+                }
+
+                r = link_update_rtnl(l, mm);
+                if (r < 0)
+                        goto fail;
+
+                break;
+
+        case RTM_DELLINK:
+                if (l) {
+                        log_debug("Removing link %i", l->ifindex);
+                        link_free(l);
+                }
+
+                break;
+        }
+
+        return 0;
+
+fail:
+        log_warning("Failed to process RTNL link message: %s", strerror(-r));
+        return 0;
+}
+
+static int on_rtnl_event(sd_rtnl *rtnl, sd_rtnl_message *mm, void *userdata) {
+        Manager *m = userdata;
+        int r;
+
+        r = manager_process_link(rtnl, mm, m);
+        if (r < 0)
+                return r;
+
+        if (manager_all_configured(m))
+                sd_event_exit(m->event, 0);
+
+        return 1;
+}
+
+static int manager_rtnl_listen(Manager *m) {
+        _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
+        sd_rtnl_message *i;
+        int r;
+
+        assert(m);
+
+        /* First, subscibe to interfaces coming and going */
+        r = sd_rtnl_open(&m->rtnl, 3, RTNLGRP_LINK, RTNLGRP_IPV4_IFADDR, RTNLGRP_IPV6_IFADDR);
+        if (r < 0)
+                return r;
+
+        r = sd_rtnl_attach_event(m->rtnl, m->event, 0);
+        if (r < 0)
+                return r;
+
+        r = sd_rtnl_add_match(m->rtnl, RTM_NEWLINK, on_rtnl_event, m);
+        if (r < 0)
+                return r;
+
+        r = sd_rtnl_add_match(m->rtnl, RTM_DELLINK, on_rtnl_event, m);
+        if (r < 0)
+                return r;
+
+        /* Then, enumerate all links */
+        r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
+        if (r < 0)
+                return r;
+
+        r = sd_rtnl_message_request_dump(req, true);
+        if (r < 0)
+                return r;
+
+        r = sd_rtnl_call(m->rtnl, req, 0, &reply);
+        if (r < 0)
+                return r;
+
+        for (i = reply; i; i = sd_rtnl_message_next(i)) {
+                r = manager_process_link(m->rtnl, i, m);
+                if (r < 0)
+                        return r;
+        }
+
+        return r;
+}
+
+static int on_network_event(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
+        Manager *m = userdata;
+        Iterator i;
+        Link *l;
+        int r;
+
+        assert(m);
+
+        sd_network_monitor_flush(m->network_monitor);
+
+        HASHMAP_FOREACH(l, m->links, i) {
+                r = link_update_monitor(l);
+                if (r < 0)
+                        log_warning("Failed to update monitor information for %i: %s", l->ifindex, strerror(-r));
+        }
+
+        if (manager_all_configured(m))
+                sd_event_exit(m->event, 0);
+
+        return 0;
+}
+
+static int manager_network_monitor_listen(Manager *m) {
+        int r, fd, events;
+
+        assert(m);
+
+        r = sd_network_monitor_new(&m->network_monitor, NULL);
+        if (r < 0)
+                return r;
+
+        fd = sd_network_monitor_get_fd(m->network_monitor);
+        if (fd < 0)
+                return fd;
+
+        events = sd_network_monitor_get_events(m->network_monitor);
+        if (events < 0)
+                return events;
+
+        r = sd_event_add_io(m->event, &m->network_monitor_event_source,
+                            fd, events, &on_network_event, m);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+int manager_new(Manager **ret, char **interfaces) {
+        _cleanup_(manager_freep) Manager *m = NULL;
+        int r;
+
+        assert(ret);
+
+        m = new0(Manager, 1);
+        if (!m)
+                return -ENOMEM;
+
+        m->interfaces = interfaces;
+
+        r = sd_event_default(&m->event);
+        if (r < 0)
+                return r;
+
+        sd_event_add_signal(m->event, NULL, SIGTERM, NULL,  NULL);
+        sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
+
+        sd_event_set_watchdog(m->event, true);
+
+        r = manager_network_monitor_listen(m);
+        if (r < 0)
+                return r;
+
+        r = manager_rtnl_listen(m);
+        if (r < 0)
+                return r;
+
+        *ret = m;
+        m = NULL;
+
+        return 0;
+}
+
+void manager_free(Manager *m) {
+        Link *l;
+
+        if (!m)
+                return;
+
+        while ((l = hashmap_first(m->links)))
+               link_free(l);
+        hashmap_free(m->links);
+        hashmap_free(m->links_by_name);
+
+        sd_event_source_unref(m->network_monitor_event_source);
+        sd_network_monitor_unref(m->network_monitor);
+
+        sd_event_source_unref(m->rtnl_event_source);
+        sd_rtnl_unref(m->rtnl);
+
+        sd_event_unref(m->event);
+        free(m);
+
+        return;
+}
diff --git a/src/network/networkd-wait-online.c b/src/network/networkd-wait-online.c
new file mode 100644 (file)
index 0000000..6c2fdd1
--- /dev/null
@@ -0,0 +1,139 @@
+
+/***
+  This file is part of systemd.
+
+  Copyright 2013 Tom Gundersen <teg@jklm.no>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <getopt.h>
+
+#include "sd-daemon.h"
+
+#include "networkd-wait-online.h"
+
+#include "strv.h"
+#include "build.h"
+
+static bool arg_quiet = false;
+static char **arg_interfaces = NULL;
+
+static void help(void) {
+        printf("%s [OPTIONS...]\n\n"
+               "Block until network is configured.\n\n"
+               "  -h --help                 Show this help\n"
+               "     --version              Print version string\n"
+               "  -q --quiet                Do not show status information\n"
+               "  -i --interface=INTERFACE  Block until at least these interfaces have appeared\n"
+               , program_invocation_short_name);
+}
+
+static int parse_argv(int argc, char *argv[]) {
+
+        enum {
+                ARG_VERSION = 0x100,
+        };
+
+        static const struct option options[] = {
+                { "help",            no_argument,       NULL, 'h'         },
+                { "version",         no_argument,       NULL, ARG_VERSION },
+                { "quiet",           no_argument,       NULL, 'q'         },
+                { "interface",       required_argument, NULL, 'i'         },
+                {}
+        };
+
+        int c;
+
+        assert(argc >= 0);
+        assert(argv);
+
+        while ((c = getopt_long(argc, argv, "+hq", options, NULL)) >= 0)
+
+                switch (c) {
+
+                case 'h':
+                        help();
+                        return 0;
+
+                case 'q':
+                        arg_quiet = true;
+                        break;
+
+                case ARG_VERSION:
+                        puts(PACKAGE_STRING);
+                        puts(SYSTEMD_FEATURES);
+                        return 0;
+
+                case 'i':
+                        if (strv_extend(&arg_interfaces, optarg) < 0)
+                                return log_oom();
+
+                        break;
+
+                case '?':
+                        return -EINVAL;
+
+                default:
+                        assert_not_reached("Unhandled option");
+                }
+
+        return 1;
+}
+
+int main(int argc, char *argv[]) {
+        _cleanup_(manager_freep) Manager *m = NULL;
+        int r;
+
+        log_set_target(LOG_TARGET_AUTO);
+        log_parse_environment();
+        log_open();
+
+        umask(0022);
+
+        r = parse_argv(argc, argv);
+        if (r <= 0)
+                return r;
+
+        if (arg_quiet)
+                log_set_max_level(LOG_WARNING);
+
+        assert_se(sigprocmask_many(SIG_BLOCK, SIGTERM, SIGINT, -1) == 0);
+
+        r = manager_new(&m, arg_interfaces);
+        if (r < 0) {
+                log_error("Could not create manager: %s", strerror(-r));
+                goto finish;
+        }
+
+        if (manager_all_configured(m)) {
+                r = 0;
+                goto finish;
+        }
+
+        sd_notify(false,
+                  "READY=1\n"
+                  "STATUS=Waiting for network connections...");
+
+        r = sd_event_loop(m->event);
+        if (r < 0) {
+                log_error("Event loop failed: %s", strerror(-r));
+                goto finish;
+        }
+
+finish:
+        sd_notify(false, "STATUS=All interfaces configured...");
+
+        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
similarity index 54%
rename from src/core/dbus-client-track.h
rename to src/network/networkd-wait-online.h
index 0167647..c57f902 100644 (file)
@@ -1,11 +1,9 @@
 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
 
-#pragma once
-
 /***
   This file is part of systemd.
 
-  Copyright 2013 Lennart Poettering
+  Copyright 2014 Tom Gundersen <teg@jklm.no>
 
   systemd is free software; you can redistribute it and/or modify it
   under the terms of the GNU Lesser General Public License as published by
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
-#include "sd-bus.h"
-#include "set.h"
-#include "manager.h"
+#pragma once
+
+#include "sd-event.h"
+#include "sd-rtnl.h"
+#include "sd-network.h"
+
+#include "util.h"
+#include "hashmap.h"
+
+typedef struct Manager {
+        Hashmap *links;
+        Hashmap *links_by_name;
+
+        char **interfaces;
+
+        sd_rtnl *rtnl;
+        sd_event_source *rtnl_event_source;
 
-typedef struct BusTrackedClient {
-        Set *set;
-        sd_bus *bus;
-        char name[0];
-} BusTrackedClient;
+        sd_network_monitor *network_monitor;
+        sd_event_source *network_monitor_event_source;
 
-int bus_client_track(Set **s, sd_bus *bus, const char *name);
+        sd_event *event;
+} Manager;
 
-int bus_client_untrack(Set *s, sd_bus *bus, const char *name);
-int bus_client_untrack_bus(Set *s, sd_bus *bus);
+void manager_free(Manager *m);
+int manager_new(Manager **ret, char **interfaces);
 
-void bus_client_track_free(Set *s);
+DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
 
-void bus_client_track_serialize(Manager *m, FILE *f, Set *s);
-int bus_client_track_deserialize_item(Manager *m, Set **s, const char *line);
+bool manager_all_configured(Manager *m);
index 00e9a5f..665f4c4 100644 (file)
@@ -19,6 +19,7 @@
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
+#include "capability.h"
 #include "sd-event.h"
 #include "sd-daemon.h"
 
@@ -26,6 +27,9 @@
 
 int main(int argc, char *argv[]) {
         _cleanup_manager_free_ Manager *m = NULL;
+        const char *user = "systemd-network";
+        uid_t uid;
+        gid_t gid;
         int r;
 
         log_set_target(LOG_TARGET_AUTO);
@@ -40,27 +44,48 @@ int main(int argc, char *argv[]) {
                 goto out;
         }
 
-        r = manager_new(&m);
+        r = get_user_creds(&user, &uid, &gid, NULL, NULL);
         if (r < 0) {
-                log_error("Could not create manager: %s", strerror(-r));
+                log_error("Cannot resolve user name %s: %s", user, strerror(-r));
                 goto out;
         }
 
-        r = manager_load_config(m);
-        if (r < 0) {
-                log_error("Could not load configuration files: %s", strerror(-r));
+        /* Always create the directories people can create inotify
+         * watches in. */
+        r = mkdir_safe_label("/run/systemd/netif", 0755, uid, gid);
+        if (r < 0)
+                log_error("Could not create runtime directory: %s",
+                          strerror(-r));
+
+        r = mkdir_safe_label("/run/systemd/netif/links", 0755, uid, gid);
+        if (r < 0)
+                log_error("Could not create runtime directory 'links': %s",
+                          strerror(-r));
+
+        r = mkdir_safe_label("/run/systemd/netif/leases", 0755, uid, gid);
+        if (r < 0)
+                log_error("Could not create runtime directory 'leases': %s",
+                          strerror(-r));
+
+        r = drop_privileges(uid, gid,
+                            (1ULL << CAP_NET_ADMIN) |
+                            (1ULL << CAP_NET_BIND_SERVICE) |
+                            (1ULL << CAP_NET_BROADCAST) |
+                            (1ULL << CAP_NET_RAW));
+        if (r < 0)
                 goto out;
-        }
 
-        r = manager_udev_listen(m);
+        assert_se(sigprocmask_many(SIG_BLOCK, SIGTERM, SIGINT, -1) == 0);
+
+        r = manager_new(&m);
         if (r < 0) {
-                log_error("Could not connect to udev: %s", strerror(-r));
+                log_error("Could not create manager: %s", strerror(-r));
                 goto out;
         }
 
-        r = manager_udev_enumerate_links(m);
+        r = manager_udev_listen(m);
         if (r < 0) {
-                log_error("Could not enumerate links: %s", strerror(-r));
+                log_error("Could not connect to udev: %s", strerror(-r));
                 goto out;
         }
 
@@ -76,11 +101,15 @@ int main(int argc, char *argv[]) {
                 goto out;
         }
 
-        /* write out empty resolv.conf to avoid a
-         * dangling symlink */
-        r = manager_update_resolv_conf(m);
+        r = manager_load_config(m);
+        if (r < 0) {
+                log_error("Could not load configuration files: %s", strerror(-r));
+                goto out;
+        }
+
+        r = manager_rtnl_enumerate_links(m);
         if (r < 0) {
-                log_error("Could not create resolv.conf: %s", strerror(-r));
+                log_error("Could not enumerate links: %s", strerror(-r));
                 goto out;
         }
 
index 8307bb5..ab5df1a 100644 (file)
 #include "sd-rtnl.h"
 #include "sd-bus.h"
 #include "sd-dhcp-client.h"
+#include "sd-dhcp-server.h"
+#include "sd-ipv4ll.h"
+#include "sd-icmp6-nd.h"
+#include "sd-dhcp6-client.h"
 #include "udev.h"
 
 #include "rtnl-util.h"
 #include "hashmap.h"
 #include "list.h"
+#include "set.h"
 #include "condition-util.h"
+#include "in-addr-util.h"
+
+#define CACHE_INFO_INFINITY_LIFE_TIME 0xFFFFFFFFU
+#define DHCP_ROUTE_METRIC 1024
+#define IPV4LL_ROUTE_METRIC 2048
 
 typedef struct NetDev NetDev;
 typedef struct Network Network;
@@ -40,53 +50,24 @@ typedef struct Link Link;
 typedef struct Address Address;
 typedef struct Route Route;
 typedef struct Manager Manager;
-
-typedef struct netdev_enslave_callback netdev_enslave_callback;
-
-struct netdev_enslave_callback {
-        sd_rtnl_message_handler_t callback;
-        Link *link;
-
-        LIST_FIELDS(netdev_enslave_callback, callbacks);
-};
-
-typedef enum NetDevKind {
-        NETDEV_KIND_BRIDGE,
-        NETDEV_KIND_BOND,
-        NETDEV_KIND_VLAN,
-        _NETDEV_KIND_MAX,
-        _NETDEV_KIND_INVALID = -1
-} NetDevKind;
-
-typedef enum NetDevState {
-        NETDEV_STATE_FAILED,
-        NETDEV_STATE_CREATING,
-        NETDEV_STATE_READY,
-        _NETDEV_STATE_MAX,
-        _NETDEV_STATE_INVALID = -1,
-} NetDevState;
-
-struct NetDev {
-        Manager *manager;
-
-        char *filename;
-
-        Condition *match_host;
-        Condition *match_virt;
-        Condition *match_kernel;
-        Condition *match_arch;
-
-        char *description;
-        char *name;
-        NetDevKind kind;
-
-        uint64_t vlanid;
-
-        int ifindex;
-        NetDevState state;
-
-        LIST_HEAD(netdev_enslave_callback, callbacks);
-};
+typedef struct AddressPool AddressPool;
+
+typedef enum DHCPSupport {
+        DHCP_SUPPORT_NONE,
+        DHCP_SUPPORT_BOTH,
+        DHCP_SUPPORT_V4,
+        DHCP_SUPPORT_V6,
+        _DHCP_SUPPORT_MAX,
+        _DHCP_SUPPORT_INVALID = -1,
+} DHCPSupport;
+
+typedef enum LLMNRSupport {
+        LLMNR_SUPPORT_NO,
+        LLMNR_SUPPORT_YES,
+        LLMNR_SUPPORT_RESOLVE,
+        _LLMNR_SUPPORT_MAX,
+        _LLMNR_SUPPORT_INVALID = -1,
+} LLMNRSupport;
 
 struct Network {
         Manager *manager;
@@ -98,6 +79,8 @@ struct Network {
         char *match_driver;
         char *match_type;
         char *match_name;
+        char *dhcp_vendor_class_identifier;
+
         Condition *match_host;
         Condition *match_virt;
         Condition *match_kernel;
@@ -106,92 +89,80 @@ struct Network {
         char *description;
         NetDev *bridge;
         NetDev *bond;
-        Hashmap *vlans;
-        bool dhcp;
+        Hashmap *stacked_netdevs;
+        DHCPSupport dhcp;
         bool dhcp_dns;
+        bool dhcp_ntp;
         bool dhcp_mtu;
         bool dhcp_hostname;
-        bool dhcp_domainname;
+        bool dhcp_domains;
+        bool dhcp_sendhost;
+        bool dhcp_broadcast;
         bool dhcp_critical;
+        bool dhcp_routes;
+        bool ipv4ll;
+        bool ipv4ll_route;
+
+        bool dhcp_server;
 
         LIST_HEAD(Address, static_addresses);
         LIST_HEAD(Route, static_routes);
-        Address *dns;
 
         Hashmap *addresses_by_section;
         Hashmap *routes_by_section;
 
+        bool wildcard_domain;
+        char **domains, **dns, **ntp;
+
+        LLMNRSupport llmnr;
+
         LIST_FIELDS(Network, networks);
 };
 
 struct Address {
         Network *network;
-        uint64_t section;
+        unsigned section;
 
-        unsigned char family;
+        int family;
         unsigned char prefixlen;
+        unsigned char scope;
+        unsigned char flags;
         char *label;
 
         struct in_addr broadcast;
+        struct ifa_cacheinfo cinfo;
 
-        union {
-                struct in_addr in;
-                struct in6_addr in6;
-        } in_addr;
+        union in_addr_union in_addr;
+        union in_addr_union in_addr_peer;
 
-        LIST_FIELDS(Address, static_addresses);
+        LIST_FIELDS(Address, addresses);
 };
 
 struct Route {
         Network *network;
-        uint64_t section;
+        unsigned section;
 
-        unsigned char family;
+        int family;
         unsigned char dst_prefixlen;
+        unsigned char scope;
+        uint32_t metrics;
+        unsigned char protocol;  /* RTPROT_* */
 
-        union {
-                struct in_addr in;
-                struct in6_addr in6;
-        } in_addr;
+        union in_addr_union in_addr;
+        union in_addr_union dst_addr;
 
-        union {
-                struct in_addr in;
-                struct in6_addr in6;
-        } dst_addr;
-
-        LIST_FIELDS(Route, static_routes);
+        LIST_FIELDS(Route, routes);
 };
 
-typedef enum LinkState {
-        LINK_STATE_ENSLAVING,
-        LINK_STATE_SETTING_ADDRESSES,
-        LINK_STATE_SETTING_ROUTES,
-        LINK_STATE_CONFIGURED,
-        LINK_STATE_FAILED,
-        _LINK_STATE_MAX,
-        _LINK_STATE_INVALID = -1
-} LinkState;
-
-struct Link {
+struct AddressPool {
         Manager *manager;
 
-        uint64_t ifindex;
-        char *ifname;
-        struct ether_addr mac;
-
-        unsigned flags;
-
-        Network *network;
+        int family;
+        unsigned prefixlen;
 
-        LinkState state;
+        union in_addr_union in_addr;
 
-        unsigned addr_messages;
-        unsigned route_messages;
-        unsigned enslaving;
-
-        sd_dhcp_client *dhcp_client;
-        sd_dhcp_lease *dhcp_lease;
-        uint16_t original_mtu;
+        LIST_FIELDS(AddressPool, address_pools);
 };
 
 struct Manager {
@@ -204,9 +175,12 @@ struct Manager {
         sd_event_source *sigterm_event_source;
         sd_event_source *sigint_event_source;
 
+        char *state_file;
+
         Hashmap *links;
         Hashmap *netdevs;
         LIST_HEAD(Network, networks);
+        LIST_HEAD(AddressPool, address_pools);
 
         usec_t network_dirs_ts_usec;
 };
@@ -221,38 +195,19 @@ void manager_free(Manager *m);
 int manager_load_config(Manager *m);
 bool manager_should_reload(Manager *m);
 
-int manager_udev_enumerate_links(Manager *m);
-int manager_udev_listen(Manager *m);
+int manager_rtnl_enumerate_links(Manager *m);
 
 int manager_rtnl_listen(Manager *m);
+int manager_udev_listen(Manager *m);
 int manager_bus_listen(Manager *m);
 
-int manager_update_resolv_conf(Manager *m);
+int manager_save(Manager *m);
+
+int manager_address_pool_acquire(Manager *m, int family, unsigned prefixlen, union in_addr_union *found);
 
 DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
 #define _cleanup_manager_free_ _cleanup_(manager_freep)
 
-/* NetDev */
-
-int netdev_load(Manager *manager);
-
-void netdev_free(NetDev *netdev);
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(NetDev*, netdev_free);
-#define _cleanup_netdev_free_ _cleanup_(netdev_freep)
-
-int netdev_get(Manager *manager, const char *name, NetDev **ret);
-int netdev_set_ifindex(NetDev *netdev, int ifindex);
-int netdev_enslave(NetDev *netdev, Link *link, sd_rtnl_message_handler_t cb);
-
-const char *netdev_kind_to_string(NetDevKind d) _const_;
-NetDevKind netdev_kind_from_string(const char *d) _pure_;
-
-int config_parse_netdev_kind(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-
-/* gperf */
-const struct ConfigPerfItem* network_netdev_gperf_lookup(const char *key, unsigned length);
-
 /* Network */
 
 int network_load(Manager *manager);
@@ -262,29 +217,58 @@ void network_free(Network *network);
 DEFINE_TRIVIAL_CLEANUP_FUNC(Network*, network_free);
 #define _cleanup_network_free_ _cleanup_(network_freep)
 
-int network_get(Manager *manager, struct udev_device *device, Network **ret);
+int network_get(Manager *manager, struct udev_device *device,
+                const char *ifname, const struct ether_addr *mac,
+                Network **ret);
 int network_apply(Manager *manager, Network *network, Link *link);
 
-int config_parse_bridge(const char *unit, const char *filename, unsigned line,
+int config_parse_netdev(const char *unit, const char *filename, unsigned line,
                         const char *section, unsigned section_line, const char *lvalue,
                         int ltype, const char *rvalue, void *data, void *userdata);
 
-int config_parse_bond(const char *unit, const char *filename, unsigned line,
-                      const char *section, unsigned section_line, const char *lvalue,
-                      int ltype, const char *rvalue, void *data, void *userdata);
-
-int config_parse_vlan(const char *unit, const char *filename, unsigned line,
-                      const char *section, unsigned section_line, const char *lvalue,
-                      int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_domains(const char *unit,
+                         const char *filename,
+                         unsigned line,
+                         const char *section,
+                         unsigned section_line,
+                         const char *lvalue,
+                         int ltype,
+                         const char *rvalue,
+                         void *data,
+                         void *userdata);
+
+int config_parse_tunnel(const char *unit,
+                        const char *filename,
+                        unsigned line,
+                        const char *section,
+                        unsigned section_line,
+                        const char *lvalue,
+                        int ltype,
+                        const char *rvalue,
+                        void *data,
+                        void *userdata);
+
+int config_parse_tunnel_address(const char *unit,
+                                const char *filename,
+                                unsigned line,
+                                const char *section,
+                                unsigned section_line,
+                                const char *lvalue,
+                                int ltype,
+                                const char *rvalue,
+                                void *data,
+                                void *userdata);
 
 /* gperf */
 const struct ConfigPerfItem* network_network_gperf_lookup(const char *key, unsigned length);
 
 /* Route */
 int route_new_static(Network *network, unsigned section, Route **ret);
-int route_new_dynamic(Route **ret);
+int route_new_dynamic(Route **ret, unsigned char rtm_protocol);
 void route_free(Route *route);
 int route_configure(Route *route, Link *link, sd_rtnl_message_handler_t callback);
+int route_drop(Route *route, Link *link, sd_rtnl_message_handler_t callback);
+
 
 DEFINE_TRIVIAL_CLEANUP_FUNC(Route*, route_free);
 #define _cleanup_route_free_ _cleanup_(route_freep)
@@ -297,20 +281,21 @@ int config_parse_destination(const char *unit, const char *filename, unsigned li
                              const char *section, unsigned section_line, const char *lvalue,
                              int ltype, const char *rvalue, void *data, void *userdata);
 
+int config_parse_route_priority(const char *unit, const char *filename, unsigned line,
+                                const char *section, unsigned section_line, const char *lvalue,
+                                int ltype, const char *rvalue, void *data, void *userdata);
 /* Address */
 int address_new_static(Network *network, unsigned section, Address **ret);
 int address_new_dynamic(Address **ret);
 void address_free(Address *address);
 int address_configure(Address *address, Link *link, sd_rtnl_message_handler_t callback);
+int address_update(Address *address, Link *link, sd_rtnl_message_handler_t callback);
 int address_drop(Address *address, Link *link, sd_rtnl_message_handler_t callback);
+bool address_equal(Address *a1, Address *a2);
 
 DEFINE_TRIVIAL_CLEANUP_FUNC(Address*, address_free);
 #define _cleanup_address_free_ _cleanup_(address_freep)
 
-int config_parse_dns(const char *unit, const char *filename, unsigned line,
-                     const char *section, unsigned section_line, const char *lvalue,
-                     int ltype, const char *rvalue, void *data, void *userdata);
-
 int config_parse_address(const char *unit, const char *filename, unsigned line,
                          const char *section, unsigned section_line, const char *lvalue,
                          int ltype, const char *rvalue, void *data, void *userdata);
@@ -323,22 +308,35 @@ int config_parse_label(const char *unit, const char *filename, unsigned line,
                        const char *section, unsigned section_line, const char *lvalue,
                        int ltype, const char *rvalue, void *data, void *userdata);
 
-/* Link */
+/* DHCP support */
+
+const char* dhcp_support_to_string(DHCPSupport i) _const_;
+DHCPSupport dhcp_support_from_string(const char *s) _pure_;
 
-int link_new(Manager *manager, struct udev_device *device, Link **ret);
-void link_free(Link *link);
-int link_get(Manager *m, int ifindex, Link **ret);
-int link_add(Manager *manager, struct udev_device *device, Link **ret);
-int link_configure(Link *link);
+int config_parse_dhcp(const char *unit, const char *filename, unsigned line,
+                      const char *section, unsigned section_line, const char *lvalue,
+                      int ltype, const char *rvalue, void *data, void *userdata);
 
-int link_update(Link *link, sd_rtnl_message *message);
+/* LLMNR support */
 
-DEFINE_TRIVIAL_CLEANUP_FUNC(Link*, link_free);
-#define _cleanup_link_free_ _cleanup_(link_freep)
+const char* llmnr_support_to_string(LLMNRSupport i) _const_;
+LLMNRSupport llmnr_support_from_string(const char *s) _pure_;
+
+int config_parse_llmnr(const char *unit, const char *filename, unsigned line,
+                      const char *section, unsigned section_line, const char *lvalue,
+                      int ltype, const char *rvalue, void *data, void *userdata);
+
+/* Address Pool */
+
+int address_pool_new(Manager *m, AddressPool **ret, int family, const union in_addr_union *u, unsigned prefixlen);
+int address_pool_new_from_string(Manager *m, AddressPool **ret, int family, const char *p, unsigned prefixlen);
+void address_pool_free(AddressPool *p);
+
+int address_pool_acquire(AddressPool *p, unsigned prefixlen, union in_addr_union *found);
 
 /* Macros which append INTERFACE= to the message */
 
-#define log_full_link(level, link, fmt, ...) log_meta_object(level, __FILE__, __LINE__, __func__, "INTERFACE=", link->ifname, "%s: " fmt, link->ifname, ##__VA_ARGS__)
+#define log_full_link(level, link, fmt, ...) log_meta_object(level, __FILE__, __LINE__, __func__, "INTERFACE=", link->ifname, "%-*s: " fmt, IFNAMSIZ, link->ifname, ##__VA_ARGS__)
 #define log_debug_link(link, ...)       log_full_link(LOG_DEBUG, link, ##__VA_ARGS__)
 #define log_info_link(link, ...)        log_full_link(LOG_INFO, link, ##__VA_ARGS__)
 #define log_notice_link(link, ...)      log_full_link(LOG_NOTICE, link, ##__VA_ARGS__)
@@ -347,18 +345,6 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(Link*, link_free);
 
 #define log_struct_link(level, link, ...) log_struct(level, "INTERFACE=%s", link->ifname, __VA_ARGS__)
 
-/* More macros which append INTERFACE= to the message */
-
-#define log_full_netdev(level, netdev, fmt, ...) log_meta_object(level, __FILE__, __LINE__, __func__, "INTERFACE=", netdev->name, "%s: " fmt, netdev->name, ##__VA_ARGS__)
-#define log_debug_netdev(netdev, ...)       log_full_netdev(LOG_DEBUG, netdev, ##__VA_ARGS__)
-#define log_info_netdev(netdev, ...)        log_full_netdev(LOG_INFO, netdev, ##__VA_ARGS__)
-#define log_notice_netdev(netdev, ...)      log_full_netdev(LOG_NOTICE, netdev, ##__VA_ARGS__)
-#define log_warning_netdev(netdev, ...)     log_full_netdev(LOG_WARNING, netdev,## __VA_ARGS__)
-#define log_error_netdev(netdev, ...)       log_full_netdev(LOG_ERR, netdev, ##__VA_ARGS__)
-
-#define log_struct_netdev(level, netdev, ...) log_struct(level, "INTERFACE=%s", netdev->name, __VA_ARGS__)
-
-#define NETDEV(netdev) "INTERFACE=%s", netdev->name
 #define ADDRESS_FMT_VAL(address)            \
         (address).s_addr & 0xFF,            \
         ((address).s_addr >> 8) & 0xFF,     \
diff --git a/src/network/test-network-tables.c b/src/network/test-network-tables.c
new file mode 100644 (file)
index 0000000..4d55434
--- /dev/null
@@ -0,0 +1,27 @@
+#include "networkd.h"
+#include "networkd-link.h"
+#include "networkd-netdev-bond.h"
+#include "networkd-netdev-macvlan.h"
+#include "dhcp6-internal.h"
+#include "dhcp6-protocol.h"
+#include "rtnl-internal.h"
+#include "ethtool-util.h"
+
+#include "test-tables.h"
+
+int main(int argc, char **argv) {
+        test_table(bond_mode, NETDEV_BOND_MODE);
+        /* test_table(link_state, LINK_STATE);  -- not a reversible mapping */
+        test_table(link_operstate, LINK_OPERSTATE);
+        test_table(dhcp_support, DHCP_SUPPORT);
+        test_table(netdev_kind, NETDEV_KIND);
+        test_table(dhcp6_message_status, DHCP6_STATUS);
+        test_table(duplex, DUP);
+        test_table(wol, WOL);
+        test_table(nl_union_link_info_data, NL_UNION_LINK_INFO_DATA);
+
+        test_table_sparse(macvlan_mode, NETDEV_MACVLAN_MODE);
+        test_table_sparse(dhcp6_message_type, DHCP6_MESSAGE);
+
+        return EXIT_SUCCESS;
+}
index 9c372c7..3dc051d 100644 (file)
 ***/
 
 #include "networkd.h"
+#include "network-internal.h"
+#include "dhcp-lease-internal.h"
+
+static void test_deserialize_in_addr(void) {
+        _cleanup_free_ struct in_addr *addresses = NULL;
+        _cleanup_free_ struct in6_addr *addresses6 = NULL;
+        struct in_addr  a, b, c;
+        struct in6_addr d, e, f;
+        int size;
+        const char *addresses_string = "192.168.0.1 0:0:0:0:0:FFFF:204.152.189.116 192.168.0.2 ::1 192.168.0.3 1:0:0:0:0:0:0:8";
+
+        assert_se(inet_pton(AF_INET, "0:0:0:0:0:FFFF:204.152.189.116", &a) == 0);
+        assert_se(inet_pton(AF_INET6, "192.168.0.1", &d) == 0);
+
+        assert_se(inet_pton(AF_INET, "192.168.0.1", &a) == 1);
+        assert_se(inet_pton(AF_INET, "192.168.0.2", &b) == 1);
+        assert_se(inet_pton(AF_INET, "192.168.0.3", &c) == 1);
+        assert_se(inet_pton(AF_INET6, "0:0:0:0:0:FFFF:204.152.189.116", &d) == 1);
+        assert_se(inet_pton(AF_INET6, "::1", &e) == 1);
+        assert_se(inet_pton(AF_INET6, "1:0:0:0:0:0:0:8", &f) == 1);
+
+        assert_se((size = deserialize_in_addrs(&addresses, addresses_string)) >= 0);
+        assert_se(size == 3);
+        assert_se(!memcmp(&a, &addresses[0], sizeof(struct in_addr)));
+        assert_se(!memcmp(&b, &addresses[1], sizeof(struct in_addr)));
+        assert_se(!memcmp(&c, &addresses[2], sizeof(struct in_addr)));
+
+        assert_se((size = deserialize_in6_addrs(&addresses6, addresses_string)) >= 0);
+        assert_se(size == 3);
+        assert_se(!memcmp(&d, &addresses6[0], sizeof(struct in6_addr)));
+        assert_se(!memcmp(&e, &addresses6[1], sizeof(struct in6_addr)));
+        assert_se(!memcmp(&f, &addresses6[2], sizeof(struct in6_addr)));
+}
 
-static void test_link(Manager *manager, struct udev_device *loopback) {
-        Link *link = NULL;
-
-        assert_se(link_new(manager, loopback, &link) >= 0);
-        assert_se(link);
+static void test_deserialize_dhcp_routes(void) {
+        size_t size, allocated;
+
+        {
+                _cleanup_free_ struct sd_dhcp_route *routes = NULL;
+                assert_se(deserialize_dhcp_routes(&routes, &size, &allocated, "") >= 0);
+                assert_se(size == 0);
+        }
+
+        {
+                /* no errors */
+                _cleanup_free_ struct sd_dhcp_route *routes = NULL;
+                const char *routes_string = "192.168.0.0/16,192.168.0.1 10.1.2.0/24,10.1.2.1 0.0.0.0/0,10.0.1.1";
+
+                assert_se(deserialize_dhcp_routes(&routes, &size, &allocated, routes_string) >= 0);
+
+                assert_se(size == 3);
+                assert_se(routes[0].dst_addr.s_addr == inet_addr("192.168.0.0"));
+                assert_se(routes[0].gw_addr.s_addr == inet_addr("192.168.0.1"));
+                assert_se(routes[0].dst_prefixlen == 16);
+
+                assert_se(routes[1].dst_addr.s_addr == inet_addr("10.1.2.0"));
+                assert_se(routes[1].gw_addr.s_addr == inet_addr("10.1.2.1"));
+                assert_se(routes[1].dst_prefixlen == 24);
+
+                assert_se(routes[2].dst_addr.s_addr == inet_addr("0.0.0.0"));
+                assert_se(routes[2].gw_addr.s_addr == inet_addr("10.0.1.1"));
+                assert_se(routes[2].dst_prefixlen == 0);
+        }
+
+        {
+                /* error in second word */
+                _cleanup_free_ struct sd_dhcp_route *routes = NULL;
+                const char *routes_string = "192.168.0.0/16,192.168.0.1 10.1.2.0#24,10.1.2.1 0.0.0.0/0,10.0.1.1";
+
+                assert_se(deserialize_dhcp_routes(&routes, &size, &allocated, routes_string) >= 0);
+
+                assert_se(size == 2);
+                assert_se(routes[0].dst_addr.s_addr == inet_addr("192.168.0.0"));
+                assert_se(routes[0].gw_addr.s_addr == inet_addr("192.168.0.1"));
+                assert_se(routes[0].dst_prefixlen == 16);
+
+                assert_se(routes[2].dst_addr.s_addr == inet_addr("0.0.0.0"));
+                assert_se(routes[2].gw_addr.s_addr == inet_addr("10.0.1.1"));
+                assert_se(routes[2].dst_prefixlen == 0);
+        }
+
+        {
+                /* error in every word */
+                _cleanup_free_ struct sd_dhcp_route *routes = NULL;
+                const char *routes_string = "192.168.0.0/55,192.168.0.1 10.1.2.0#24,10.1.2.1 0.0.0.0/0,10.0.1.X";
+
+                assert_se(deserialize_dhcp_routes(&routes, &size, &allocated, routes_string) >= 0);
+                assert_se(size == 0);
+        }
 }
 
-static void test_load_config(Manager *manager) {
+static int test_load_config(Manager *manager) {
+        int r;
 /*  TODO: should_reload, is false if the config dirs do not exist, so
  *        so we can't do this test here, move it to a test for paths_check_timestamps
  *        directly
  *
  *        assert_se(network_should_reload(manager) == true);
 */
-        assert_se(manager_load_config(manager) >= 0);
+
+        r = manager_load_config(manager);
+        if (r == -EPERM)
+                return r;
+        assert_se(r >= 0);
+
         assert_se(manager_should_reload(manager) == false);
+
+        return 0;
 }
 
 static void test_network_get(Manager *manager, struct udev_device *loopback) {
         Network *network;
+        const struct ether_addr mac = {};
 
         /* let's assume that the test machine does not have a .network file
            that applies to the loopback device... */
-        assert_se(network_get(manager, loopback, &network) == -ENOENT);
+        assert_se(network_get(manager, loopback, "lo", &mac, &network) == -ENOENT);
         assert_se(!network);
 }
 
+static void test_address_equality(void) {
+        _cleanup_address_free_ Address *a1 = NULL, *a2 = NULL;
+
+        assert_se(address_new_dynamic(&a1) >= 0);
+        assert_se(address_new_dynamic(&a2) >= 0);
+
+        assert_se(address_equal(NULL, NULL));
+        assert_se(!address_equal(a1, NULL));
+        assert_se(!address_equal(NULL, a2));
+        assert_se(address_equal(a1, a2));
+
+        a1->family = AF_INET;
+        assert_se(!address_equal(a1, a2));
+
+        a2->family = AF_INET;
+        assert_se(address_equal(a1, a2));
+
+        assert_se(inet_pton(AF_INET, "192.168.3.9", &a1->in_addr.in));
+        assert_se(!address_equal(a1, a2));
+        assert_se(inet_pton(AF_INET, "192.168.3.9", &a2->in_addr.in));
+        assert_se(address_equal(a1, a2));
+
+        a1->prefixlen = 10;
+        assert_se(!address_equal(a1, a2));
+        a2->prefixlen = 10;
+        assert_se(address_equal(a1, a2));
+
+        assert_se(inet_pton(AF_INET, "192.168.3.10", &a2->in_addr.in));
+        assert_se(address_equal(a1, a2));
+
+        a1->family = AF_INET6;
+        assert_se(!address_equal(a1, a2));
+
+        a2->family = AF_INET6;
+        assert_se(inet_pton(AF_INET6, "2001:4ca0:4f01::2", &a1->in_addr.in6));
+        assert_se(inet_pton(AF_INET6, "2001:4ca0:4f01::2", &a2->in_addr.in6));
+        assert_se(address_equal(a1, a2));
+
+        a2->prefixlen = 8;
+        assert_se(address_equal(a1, a2));
+
+        assert_se(inet_pton(AF_INET6, "2001:4ca0:4f01::1", &a2->in_addr.in6));
+        assert_se(!address_equal(a1, a2));
+}
+
 int main(void) {
         _cleanup_manager_free_ Manager *manager = NULL;
         struct udev *udev;
         struct udev_device *loopback;
+        int r;
+
+        test_deserialize_in_addr();
+        test_deserialize_dhcp_routes();
+        test_address_equality();
 
         assert_se(manager_new(&manager) >= 0);
 
-        test_load_config(manager);
+        r = test_load_config(manager);
+        if (r == -EPERM)
+                return EXIT_TEST_SKIP;
 
         udev = udev_new();
         assert_se(udev);
@@ -66,11 +210,9 @@ int main(void) {
 
         test_network_get(manager, loopback);
 
-        test_link(manager, loopback);
-
         assert_se(manager_udev_listen(manager) >= 0);
-        assert_se(manager_udev_enumerate_links(manager) >= 0);
         assert_se(manager_rtnl_listen(manager) >= 0);
+        assert_se(manager_rtnl_enumerate_links(manager) >= 0);
 
         udev_device_unref(loopback);
         udev_unref(udev);
index a145b8f..6f1c52e 100644 (file)
@@ -27,7 +27,7 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include <systemd/sd-daemon.h>
+#include "systemd/sd-daemon.h"
 
 #include "strv.h"
 #include "util.h"
@@ -42,8 +42,7 @@ static const char *arg_status = NULL;
 static bool arg_booted = false;
 static const char *arg_readahead = NULL;
 
-static int help(void) {
-
+static void help(void) {
         printf("%s [OPTIONS...] [VARIABLE=VALUE...]\n\n"
                "Notify the init system about service status updates.\n\n"
                "  -h --help             Show this help\n"
@@ -54,8 +53,6 @@ static int help(void) {
                "     --booted           Returns 0 if the system was booted up with systemd, non-zero otherwise\n"
                "     --readahead=ACTION Controls read-ahead operations\n",
                program_invocation_short_name);
-
-        return 0;
 }
 
 static int parse_argv(int argc, char *argv[]) {
@@ -90,7 +87,8 @@ static int parse_argv(int argc, char *argv[]) {
                 switch (c) {
 
                 case 'h':
-                        return help();
+                        help();
+                        return 0;
 
                 case ARG_VERSION:
                         puts(PACKAGE_STRING);
@@ -147,25 +145,25 @@ static int parse_argv(int argc, char *argv[]) {
 }
 
 int main(int argc, char* argv[]) {
-        char* our_env[4], **final_env = NULL;
+        _cleanup_free_ char *status = NULL, *cpid = NULL, *n = NULL;
+        _cleanup_strv_free_ char **final_env = NULL;
+        char* our_env[4];
         unsigned i = 0;
-        char *status = NULL, *cpid = NULL, *n = NULL;
-        int r, retval = EXIT_FAILURE;
+        int r;
 
         log_parse_environment();
         log_open();
 
         r = parse_argv(argc, argv);
-        if (r <= 0) {
-                retval = r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+        if (r <= 0)
                 goto finish;
-        }
 
         if (arg_booted)
                 return sd_booted() <= 0;
 
         if (arg_readahead) {
-                if ((r = sd_readahead(arg_readahead)) < 0) {
+                r = sd_readahead(arg_readahead);
+                if (r < 0) {
                         log_error("Failed to issue read-ahead control command: %s", strerror(-r));
                         goto finish;
                 }
@@ -175,8 +173,9 @@ int main(int argc, char* argv[]) {
                 our_env[i++] = (char*) "READY=1";
 
         if (arg_status) {
-                if (!(status = strappend("STATUS=", arg_status))) {
-                        log_error("Failed to allocate STATUS string.");
+                status = strappend("STATUS=", arg_status);
+                if (!status) {
+                        r = log_oom();
                         goto finish;
                 }
 
@@ -184,8 +183,8 @@ int main(int argc, char* argv[]) {
         }
 
         if (arg_pid > 0) {
-                if (asprintf(&cpid, "MAINPID=%lu", (unsigned long) arg_pid) < 0) {
-                        log_error("Failed to allocate MAINPID string.");
+                if (asprintf(&cpid, "MAINPID="PID_FMT, arg_pid) < 0) {
+                        r = log_oom();
                         goto finish;
                 }
 
@@ -194,34 +193,32 @@ int main(int argc, char* argv[]) {
 
         our_env[i++] = NULL;
 
-        if (!(final_env = strv_env_merge(2, our_env, argv + optind))) {
-                log_error("Failed to merge string sets.");
+        final_env = strv_env_merge(2, our_env, argv + optind);
+        if (!final_env) {
+                r = log_oom();
                 goto finish;
         }
 
         if (strv_length(final_env) <= 0) {
-                retval = EXIT_SUCCESS;
+                r = 0;
                 goto finish;
         }
 
-        if (!(n = strv_join(final_env, "\n"))) {
-                log_error("Failed to concatenate strings.");
+        n = strv_join(final_env, "\n");
+        if (!n) {
+                r = log_oom();
                 goto finish;
         }
 
-        if ((r = sd_notify(false, n)) < 0) {
+        r = sd_pid_notify(arg_pid, false, n);
+        if (r < 0) {
                 log_error("Failed to notify init system: %s", strerror(-r));
                 goto finish;
         }
 
-        retval = r <= 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+        if (r == 0)
+                r = -ENOTSUP;
 
 finish:
-        free(status);
-        free(cpid);
-        free(n);
-
-        strv_free(final_env);
-
-        return retval;
+        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
 }
index de74a43..d01da45 100644 (file)
 #include <sys/un.h>
 #include <sys/socket.h>
 #include <linux/netlink.h>
-#include <sys/eventfd.h>
 #include <net/if.h>
 #include <linux/veth.h>
 #include <sys/personality.h>
+#include <linux/loop.h>
 
 #ifdef HAVE_SELINUX
 #include <selinux/selinux.h>
 #include <seccomp.h>
 #endif
 
+#ifdef HAVE_BLKID
+#include <blkid/blkid.h>
+#endif
+
 #include "sd-daemon.h"
 #include "sd-bus.h"
 #include "sd-id128.h"
 #include "def.h"
 #include "rtnl-util.h"
 #include "udev-util.h"
+#include "blkid-util.h"
+#include "gpt.h"
+#include "siphash24.h"
+#include "copy.h"
+#include "base-filesystem.h"
+#include "barrier.h"
 
 #ifdef HAVE_SECCOMP
 #include "seccomp-util.h"
 #endif
 
+typedef enum ContainerStatus {
+        CONTAINER_TERMINATED,
+        CONTAINER_REBOOTED
+} ContainerStatus;
+
 typedef enum LinkJournal {
         LINK_NO,
         LINK_AUTO,
@@ -91,12 +106,18 @@ typedef enum LinkJournal {
         LINK_GUEST
 } LinkJournal;
 
+typedef enum Volatile {
+        VOLATILE_NO,
+        VOLATILE_YES,
+        VOLATILE_STATE,
+} Volatile;
+
 static char *arg_directory = NULL;
 static char *arg_user = NULL;
 static sd_id128_t arg_uuid = {};
 static char *arg_machine = NULL;
-static char *arg_selinux_context = NULL;
-static char *arg_selinux_apifs_context = NULL;
+static const char *arg_selinux_context = NULL;
+static const char *arg_selinux_apifs_context = NULL;
 static const char *arg_slice = NULL;
 static bool arg_private_network = false;
 static bool arg_read_only = false;
@@ -131,24 +152,28 @@ static uint64_t arg_retain =
         (1ULL << CAP_MKNOD);
 static char **arg_bind = NULL;
 static char **arg_bind_ro = NULL;
+static char **arg_tmpfs = NULL;
 static char **arg_setenv = NULL;
 static bool arg_quiet = false;
 static bool arg_share_system = false;
 static bool arg_register = true;
 static bool arg_keep_unit = false;
 static char **arg_network_interfaces = NULL;
+static char **arg_network_macvlan = NULL;
 static bool arg_network_veth = false;
-static char *arg_network_bridge = NULL;
+static const char *arg_network_bridge = NULL;
 static unsigned long arg_personality = 0xffffffffLU;
+static const char *arg_image = NULL;
+static Volatile arg_volatile = VOLATILE_NO;
 
-static int help(void) {
-
+static void help(void) {
         printf("%s [OPTIONS...] [PATH] [ARGUMENTS...]\n\n"
                "Spawn a minimal namespace container for debugging, testing and building.\n\n"
                "  -h --help                 Show this help\n"
                "     --version              Print version string\n"
                "  -q --quiet                Do not show status information\n"
-               "  -D --directory=NAME       Root directory for the container\n"
+               "  -D --directory=PATH       Root directory for the container\n"
+               "  -i --image=PATH           File system device or image for the container\n"
                "  -b --boot                 Boot up full system (i.e. invoke init)\n"
                "  -u --user=USER            Run the command under specified user or uid\n"
                "  -M --machine=NAME         Set the machine name for the container\n"
@@ -158,6 +183,9 @@ static int help(void) {
                "     --network-interface=INTERFACE\n"
                "                            Assign an existing network interface to the\n"
                "                            container\n"
+               "     --network-macvlan=INTERFACE\n"
+               "                            Create a macvlan network interface based on an\n"
+               "                            existing network interface to the container\n"
                "     --network-veth         Add a virtual ethernet connection between host\n"
                "                            and container\n"
                "     --network-bridge=INTERFACE\n"
@@ -179,14 +207,14 @@ static int help(void) {
                "     --bind=PATH[:PATH]     Bind mount a file or directory from the host into\n"
                "                            the container\n"
                "     --bind-ro=PATH[:PATH]  Similar, but creates a read-only bind mount\n"
+               "     --tmpfs=PATH:[OPTIONS] Mount an empty tmpfs to the specified directory\n"
                "     --setenv=NAME=VALUE    Pass an environment variable to PID 1\n"
                "     --share-system         Share system namespaces with host\n"
                "     --register=BOOLEAN     Register container as machine\n"
                "     --keep-unit            Do not register a scope for the machine, reuse\n"
-               "                            the service unit nspawn is running in\n",
+               "                            the service unit nspawn is running in\n"
+               "     --volatile[=MODE]      Run the system in volatile mode\n",
                program_invocation_short_name);
-
-        return 0;
 }
 
 static int parse_argv(int argc, char *argv[]) {
@@ -201,14 +229,17 @@ static int parse_argv(int argc, char *argv[]) {
                 ARG_LINK_JOURNAL,
                 ARG_BIND,
                 ARG_BIND_RO,
+                ARG_TMPFS,
                 ARG_SETENV,
                 ARG_SHARE_SYSTEM,
                 ARG_REGISTER,
                 ARG_KEEP_UNIT,
                 ARG_NETWORK_INTERFACE,
+                ARG_NETWORK_MACVLAN,
                 ARG_NETWORK_VETH,
                 ARG_NETWORK_BRIDGE,
                 ARG_PERSONALITY,
+                ARG_VOLATILE,
         };
 
         static const struct option options[] = {
@@ -225,6 +256,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "link-journal",          required_argument, NULL, ARG_LINK_JOURNAL      },
                 { "bind",                  required_argument, NULL, ARG_BIND              },
                 { "bind-ro",               required_argument, NULL, ARG_BIND_RO           },
+                { "tmpfs",                 required_argument, NULL, ARG_TMPFS             },
                 { "machine",               required_argument, NULL, 'M'                   },
                 { "slice",                 required_argument, NULL, 'S'                   },
                 { "setenv",                required_argument, NULL, ARG_SETENV            },
@@ -235,9 +267,12 @@ static int parse_argv(int argc, char *argv[]) {
                 { "register",              required_argument, NULL, ARG_REGISTER          },
                 { "keep-unit",             no_argument,       NULL, ARG_KEEP_UNIT         },
                 { "network-interface",     required_argument, NULL, ARG_NETWORK_INTERFACE },
+                { "network-macvlan",       required_argument, NULL, ARG_NETWORK_MACVLAN   },
                 { "network-veth",          no_argument,       NULL, ARG_NETWORK_VETH      },
                 { "network-bridge",        required_argument, NULL, ARG_NETWORK_BRIDGE    },
                 { "personality",           required_argument, NULL, ARG_PERSONALITY       },
+                { "image",                 required_argument, NULL, 'i'                   },
+                { "volatile",              optional_argument, NULL, ARG_VOLATILE          },
                 {}
         };
 
@@ -247,12 +282,13 @@ static int parse_argv(int argc, char *argv[]) {
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "+hD:u:bL:M:jS:Z:q", options, NULL)) >= 0) {
+        while ((c = getopt_long(argc, argv, "+hD:u:bL:M:jS:Z:qi:", options, NULL)) >= 0)
 
                 switch (c) {
 
                 case 'h':
-                        return help();
+                        help();
+                        return 0;
 
                 case ARG_VERSION:
                         puts(PACKAGE_STRING);
@@ -269,6 +305,10 @@ static int parse_argv(int argc, char *argv[]) {
 
                         break;
 
+                case 'i':
+                        arg_image = optarg;
+                        break;
+
                 case 'u':
                         free(arg_user);
                         arg_user = strdup(optarg);
@@ -278,9 +318,7 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
 
                 case ARG_NETWORK_BRIDGE:
-                        arg_network_bridge = strdup(optarg);
-                        if (!arg_network_bridge)
-                                return log_oom();
+                        arg_network_bridge = optarg;
 
                         /* fall through */
 
@@ -290,7 +328,14 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
 
                 case ARG_NETWORK_INTERFACE:
-                        if (strv_push(&arg_network_interfaces, optarg) < 0)
+                        if (strv_extend(&arg_network_interfaces, optarg) < 0)
+                                return log_oom();
+
+                        arg_private_network = true;
+                        break;
+
+                case ARG_NETWORK_MACVLAN:
+                        if (strv_extend(&arg_network_macvlan, optarg) < 0)
                                 return log_oom();
 
                         /* fall through */
@@ -312,10 +357,7 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
 
                 case 'S':
-                        arg_slice = strdup(optarg);
-                        if (!arg_slice)
-                                return log_oom();
-
+                        arg_slice = optarg;
                         break;
 
                 case 'M':
@@ -351,7 +393,7 @@ static int parse_argv(int argc, char *argv[]) {
 
                 case ARG_CAPABILITY:
                 case ARG_DROP_CAPABILITY: {
-                        char *state, *word;
+                        const char *state, *word;
                         size_t length;
 
                         FOREACH_WORD_SEPARATOR(word, length, optarg, ",", state) {
@@ -439,6 +481,42 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
                 }
 
+                case ARG_TMPFS: {
+                        _cleanup_free_ char *a = NULL, *b = NULL;
+                        char *e;
+
+                        e = strchr(optarg, ':');
+                        if (e) {
+                                a = strndup(optarg, e - optarg);
+                                b = strdup(e + 1);
+                        } else {
+                                a = strdup(optarg);
+                                b = strdup("mode=0755");
+                        }
+
+                        if (!a || !b)
+                                return log_oom();
+
+                        if (!path_is_absolute(a)) {
+                                log_error("Invalid tmpfs specification: %s", optarg);
+                                return -EINVAL;
+                        }
+
+                        r = strv_push(&arg_tmpfs, a);
+                        if (r < 0)
+                                return log_oom();
+
+                        a = NULL;
+
+                        r = strv_push(&arg_tmpfs, b);
+                        if (r < 0)
+                                return log_oom();
+
+                        b = NULL;
+
+                        break;
+                }
+
                 case ARG_SETENV: {
                         char **n;
 
@@ -488,13 +566,31 @@ static int parse_argv(int argc, char *argv[]) {
 
                         break;
 
+                case ARG_VOLATILE:
+
+                        if (!optarg)
+                                arg_volatile = VOLATILE_YES;
+                        else {
+                                r = parse_boolean(optarg);
+                                if (r < 0) {
+                                        if (streq(optarg, "state"))
+                                                arg_volatile = VOLATILE_STATE;
+                                        else {
+                                                log_error("Failed to parse --volatile= argument: %s", optarg);
+                                                return r;
+                                        }
+                                } else
+                                        arg_volatile = r ? VOLATILE_YES : VOLATILE_NO;
+                        }
+
+                        break;
+
                 case '?':
                         return -EINVAL;
 
                 default:
                         assert_not_reached("Unhandled option");
                 }
-        }
 
         if (arg_share_system)
                 arg_register = false;
@@ -509,6 +605,16 @@ static int parse_argv(int argc, char *argv[]) {
                 return -EINVAL;
         }
 
+        if (arg_directory && arg_image) {
+                log_error("--directory= and --image= may not be combined.");
+                return -EINVAL;
+        }
+
+        if (arg_volatile != VOLATILE_NO && arg_read_only) {
+                log_error("Cannot combine --read-only with --volatile. Note that --volatile already implies a read-only base hierarchy.");
+                return -EINVAL;
+        }
+
         arg_retain = (arg_retain | plus | (arg_private_network ? 1ULL << CAP_NET_ADMIN : 0)) & ~minus;
 
         return 1;
@@ -526,17 +632,17 @@ static int mount_all(const char *dest) {
         } MountPoint;
 
         static const MountPoint mount_table[] = {
-                { "proc",      "/proc",     "proc",  NULL,       MS_NOSUID|MS_NOEXEC|MS_NODEV, true  },
-                { "/proc/sys", "/proc/sys", NULL,    NULL,       MS_BIND, true                       },   /* Bind mount first */
-                { NULL,        "/proc/sys", NULL,    NULL,       MS_BIND|MS_RDONLY|MS_REMOUNT, true  },   /* Then, make it r/o */
-                { "sysfs",     "/sys",      "sysfs", NULL,       MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV, true  },
-                { "tmpfs",     "/dev",      "tmpfs", "mode=755", MS_NOSUID|MS_STRICTATIME,     true  },
+                { "proc",      "/proc",     "proc",  NULL,        MS_NOSUID|MS_NOEXEC|MS_NODEV,           true  },
+                { "/proc/sys", "/proc/sys", NULL,    NULL,        MS_BIND,                                true  },   /* Bind mount first */
+                { NULL,        "/proc/sys", NULL,    NULL,        MS_BIND|MS_RDONLY|MS_REMOUNT,           true  },   /* Then, make it r/o */
+                { "sysfs",     "/sys",      "sysfs", NULL,        MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV, true  },
+                { "tmpfs",     "/dev",      "tmpfs", "mode=755",  MS_NOSUID|MS_STRICTATIME,               true  },
                 { "devpts",    "/dev/pts",  "devpts","newinstance,ptmxmode=0666,mode=620,gid=" STRINGIFY(TTY_GID), MS_NOSUID|MS_NOEXEC, true },
-                { "tmpfs",     "/dev/shm",  "tmpfs", "mode=1777", MS_NOSUID|MS_NODEV|MS_STRICTATIME, true  },
-                { "tmpfs",     "/run",      "tmpfs", "mode=755", MS_NOSUID|MS_NODEV|MS_STRICTATIME, true  },
+                { "tmpfs",     "/dev/shm",  "tmpfs", "mode=1777", MS_NOSUID|MS_NODEV|MS_STRICTATIME,      true  },
+                { "tmpfs",     "/run",      "tmpfs", "mode=755",  MS_NOSUID|MS_NODEV|MS_STRICTATIME,      true  },
 #ifdef HAVE_SELINUX
-                { "/sys/fs/selinux", "/sys/fs/selinux", NULL, NULL, MS_BIND,                      false },  /* Bind mount first */
-                { NULL,              "/sys/fs/selinux", NULL, NULL, MS_BIND|MS_RDONLY|MS_REMOUNT, false },  /* Then, make it r/o */
+                { "/sys/fs/selinux", "/sys/fs/selinux", NULL, NULL, MS_BIND,                              false },  /* Bind mount first */
+                { NULL,              "/sys/fs/selinux", NULL, NULL, MS_BIND|MS_RDONLY|MS_REMOUNT,         false },  /* Then, make it r/o */
 #endif
         };
 
@@ -601,25 +707,27 @@ static int mount_all(const char *dest) {
         return r;
 }
 
-static int mount_binds(const char *dest, char **l, unsigned long flags) {
+static int mount_binds(const char *dest, char **l, bool ro) {
         char **x, **y;
 
         STRV_FOREACH_PAIR(x, y, l) {
-                char *where;
+                _cleanup_free_ char *where = NULL;
                 struct stat source_st, dest_st;
                 int r;
 
                 if (stat(*x, &source_st) < 0) {
-                        log_error("failed to stat %s: %m", *x);
+                        log_error("Failed to stat %s: %m", *x);
                         return -errno;
                 }
 
-                where = strappenda(dest, *y);
+                where = strappend(dest, *y);
+                if (!where)
+                        return log_oom();
+
                 r = stat(where, &dest_st);
                 if (r == 0) {
                         if ((source_st.st_mode & S_IFMT) != (dest_st.st_mode & S_IFMT)) {
-                                log_error("The file types of %s and %s do not match. Refusing bind mount",
-                                                *x, where);
+                                log_error("The file types of %s and %s do not match. Refusing bind mount", *x, where);
                                 return -EINVAL;
                         }
                 } else if (errno == ENOENT) {
@@ -629,11 +737,12 @@ static int mount_binds(const char *dest, char **l, unsigned long flags) {
                                 return r;
                         }
                 } else {
-                        log_error("Failed to bind mount %s: %s", *x, strerror(errno));
+                        log_error("Failed to bind mount %s: %m", *x);
                         return -errno;
                 }
+
                 /* Create the mount point, but be conservative -- refuse to create block
-                * and char devices. */
+                 * and char devices. */
                 if (S_ISDIR(source_st.st_mode))
                         mkdir_label(where, 0755);
                 else if (S_ISFIFO(source_st.st_mode))
@@ -652,8 +761,32 @@ static int mount_binds(const char *dest, char **l, unsigned long flags) {
                         return -errno;
                 }
 
-                if (flags && mount(NULL, where, NULL, MS_REMOUNT|MS_BIND|flags, NULL) < 0) {
-                        log_error("mount(%s) failed: %m", where);
+                if (ro) {
+                        r = bind_remount_recursive(where, true);
+                        if (r < 0) {
+                                log_error("Read-Only bind mount failed: %s", strerror(-r));
+                                return r;
+                        }
+                }
+        }
+
+        return 0;
+}
+
+static int mount_tmpfs(const char *dest) {
+        char **i, **o;
+
+        STRV_FOREACH_PAIR(i, o, arg_tmpfs) {
+                _cleanup_free_ char *where = NULL;
+
+                where = strappend(dest, *i);
+                if (!where)
+                        return log_oom();
+
+                mkdir_label(where, 0755);
+
+                if (mount("tmpfs", where, "tmpfs", MS_NODEV|MS_STRICTATIME, *o) < 0) {
+                        log_error("tmpfs mount to %s failed: %m", where);
                         return -errno;
                 }
         }
@@ -693,7 +826,6 @@ static int setup_timezone(const char *dest) {
                 if (!y)
                         y = path_startswith(q, "/usr/share/zoneinfo/");
 
-
                 /* Already pointing to the right place? Then do nothing .. */
                 if (y && streq(y, z))
                         return 0;
@@ -712,7 +844,9 @@ static int setup_timezone(const char *dest) {
         if (!what)
                 return log_oom();
 
+        mkdir_parents(where, 0755);
         unlink(where);
+
         if (symlink(what, where) < 0) {
                 log_error("Failed to correct timezone of container: %m");
                 return 0;
@@ -722,7 +856,7 @@ static int setup_timezone(const char *dest) {
 }
 
 static int setup_resolv_conf(const char *dest) {
-        char _cleanup_free_ *where = NULL;
+        _cleanup_free_ char *where = NULL;
 
         assert(dest);
 
@@ -736,9 +870,112 @@ static int setup_resolv_conf(const char *dest) {
 
         /* We don't really care for the results of this really. If it
          * fails, it fails, but meh... */
-        copy_file("/etc/resolv.conf", where, O_TRUNC|O_NOFOLLOW);
+        mkdir_parents(where, 0755);
+        copy_file("/etc/resolv.conf", where, O_TRUNC|O_NOFOLLOW, 0644);
+
+        return 0;
+}
+
+static int setup_volatile_state(const char *directory) {
+        const char *p;
+        int r;
+
+        assert(directory);
+
+        if (arg_volatile != VOLATILE_STATE)
+                return 0;
+
+        /* --volatile=state means we simply overmount /var
+           with a tmpfs, and the rest read-only. */
+
+        r = bind_remount_recursive(directory, true);
+        if (r < 0) {
+                log_error("Failed to remount %s read-only: %s", directory, strerror(-r));
+                return r;
+        }
+
+        p = strappenda(directory, "/var");
+        mkdir(p, 0755);
+
+        if (mount("tmpfs", p, "tmpfs", MS_STRICTATIME, "mode=755") < 0) {
+                log_error("Failed to mount tmpfs to /var: %m");
+                return -errno;
+        }
+
+        return 0;
+}
+
+static int setup_volatile(const char *directory) {
+        bool tmpfs_mounted = false, bind_mounted = false;
+        char template[] = "/tmp/nspawn-volatile-XXXXXX";
+        const char *f, *t;
+        int r;
+
+        assert(directory);
+
+        if (arg_volatile != VOLATILE_YES)
+                return 0;
+
+        /* --volatile=yes means we mount a tmpfs to the root dir, and
+           the original /usr to use inside it, and that read-only. */
+
+        if (!mkdtemp(template)) {
+                log_error("Failed to create temporary directory: %m");
+                return -errno;
+        }
+
+        if (mount("tmpfs", template, "tmpfs", MS_STRICTATIME, "mode=755") < 0) {
+                log_error("Failed to mount tmpfs for root directory: %m");
+                r = -errno;
+                goto fail;
+        }
+
+        tmpfs_mounted = true;
+
+        f = strappenda(directory, "/usr");
+        t = strappenda(template, "/usr");
+
+        mkdir(t, 0755);
+        if (mount(f, t, "bind", MS_BIND|MS_REC, NULL) < 0) {
+                log_error("Failed to create /usr bind mount: %m");
+                r = -errno;
+                goto fail;
+        }
+
+        bind_mounted = true;
+
+        r = bind_remount_recursive(t, true);
+        if (r < 0) {
+                log_error("Failed to remount %s read-only: %s", t, strerror(-r));
+                goto fail;
+        }
+
+        if (mount(template, directory, NULL, MS_MOVE, NULL) < 0) {
+                log_error("Failed to move root mount: %m");
+                r = -errno;
+                goto fail;
+        }
+
+        rmdir(template);
 
         return 0;
+
+fail:
+        if (bind_mounted)
+                umount(t);
+        if (tmpfs_mounted)
+                umount(template);
+        rmdir(template);
+        return r;
+}
+
+static char* id128_format_as_uuid(sd_id128_t id, char s[37]) {
+
+        snprintf(s, 37,
+                 "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+                 SD_ID128_FORMAT_VAL(id));
+
+        return s;
 }
 
 static int setup_boot_id(const char *dest) {
@@ -766,10 +1003,7 @@ static int setup_boot_id(const char *dest) {
                 return r;
         }
 
-        snprintf(as_uuid, sizeof(as_uuid),
-                 "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
-                 SD_ID128_FORMAT_VAL(rnd));
-        char_array_0(as_uuid);
+        id128_format_as_uuid(rnd, as_uuid);
 
         r = write_string_file(from, as_uuid);
         if (r < 0) {
@@ -852,23 +1086,19 @@ static int setup_ptmx(const char *dest) {
 }
 
 static int setup_dev_console(const char *dest, const char *console) {
+        _cleanup_umask_ mode_t u;
+        const char *to;
         struct stat st;
-        _cleanup_free_ char *to = NULL;
         int r;
-        _cleanup_umask_ mode_t u;
 
         assert(dest);
         assert(console);
 
         u = umask(0000);
 
-        if (stat(console, &st) < 0) {
-                log_error("Failed to stat %s: %m", console);
+        if (stat("/dev/null", &st) < 0) {
+                log_error("Failed to stat /dev/null: %m");
                 return -errno;
-
-        } else if (!S_ISCHR(st.st_mode)) {
-                log_error("/dev/console is not a char device");
-                return -EIO;
         }
 
         r = chmod_and_chown(console, 0600, 0, 0);
@@ -877,16 +1107,15 @@ static int setup_dev_console(const char *dest, const char *console) {
                 return r;
         }
 
-        if (asprintf(&to, "%s/dev/console", dest) < 0)
-                return log_oom();
-
         /* We need to bind mount the right tty to /dev/console since
          * ptys can only exist on pts file systems. To have something
-         * to bind mount things on we create a device node first, that
-         * has the right major/minor (note that the major minor
-         * doesn't actually matter here, since we mount it over
-         * anyway). */
+         * to bind mount things on we create a device node first, and
+         * use /dev/null for that since we the cgroups device policy
+         * allows us to create that freely, while we cannot create
+         * /dev/console. (Note that the major minor doesn't actually
+         * matter here, since we mount it over anyway). */
 
+        to = strappenda(dest, "/dev/console");
         if (mknod(to, (st.st_mode & ~07777) | 0600, st.st_rdev) < 0) {
                 log_error("mknod() for /dev/console failed: %m");
                 return -errno;
@@ -963,7 +1192,7 @@ static int setup_kmsg(const char *dest, int kmsg_socket) {
         /* Store away the fd in the socket, so that it stays open as
          * long as we run the child */
         k = sendmsg(kmsg_socket, &mh, MSG_DONTWAIT|MSG_NOSIGNAL);
-        close_nointr_nofail(fd);
+        safe_close(fd);
 
         if (k < 0) {
                 log_error("Failed to send FIFO fd: %m");
@@ -1114,10 +1343,8 @@ static int setup_journal(const char *directory) {
         } else if (access(p, F_OK) < 0)
                 return 0;
 
-        if (dir_is_empty(q) == 0) {
-                log_error("%s not empty.", q);
-                return -ENOTEMPTY;
-        }
+        if (dir_is_empty(q) == 0)
+                log_warning("%s is not empty, proceeding anyway.", q);
 
         r = mkdir_p(q, 0755);
         if (r < 0) {
@@ -1157,9 +1384,9 @@ static int drop_capabilities(void) {
         return capability_bounding_set_drop(~arg_retain, false);
 }
 
-static int register_machine(pid_t pid) {
+static int register_machine(pid_t pid, int local_ifindex) {
         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
-        _cleanup_bus_unref_ sd_bus *bus = NULL;
+        _cleanup_bus_close_unref_ sd_bus *bus = NULL;
         int r;
 
         if (!arg_register)
@@ -1177,16 +1404,17 @@ static int register_machine(pid_t pid) {
                                 "org.freedesktop.machine1",
                                 "/org/freedesktop/machine1",
                                 "org.freedesktop.machine1.Manager",
-                                "RegisterMachine",
+                                "RegisterMachineWithNetwork",
                                 &error,
                                 NULL,
-                                "sayssus",
+                                "sayssusai",
                                 arg_machine,
                                 SD_BUS_MESSAGE_APPEND_ID128(arg_uuid),
                                 "nspawn",
                                 "container",
                                 (uint32_t) pid,
-                                strempty(arg_directory));
+                                strempty(arg_directory),
+                                local_ifindex > 0 ? 1 : 0, local_ifindex);
         } else {
                 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
 
@@ -1196,7 +1424,7 @@ static int register_machine(pid_t pid) {
                                 "org.freedesktop.machine1",
                                 "/org/freedesktop/machine1",
                                 "org.freedesktop.machine1.Manager",
-                                "CreateMachine");
+                                "CreateMachineWithNetwork");
                 if (r < 0) {
                         log_error("Failed to create message: %s", strerror(-r));
                         return r;
@@ -1204,13 +1432,14 @@ static int register_machine(pid_t pid) {
 
                 r = sd_bus_message_append(
                                 m,
-                                "sayssus",
+                                "sayssusai",
                                 arg_machine,
                                 SD_BUS_MESSAGE_APPEND_ID128(arg_uuid),
                                 "nspawn",
                                 "container",
                                 (uint32_t) pid,
-                                strempty(arg_directory));
+                                strempty(arg_directory),
+                                local_ifindex > 0 ? 1 : 0, local_ifindex);
                 if (r < 0) {
                         log_error("Failed to append message arguments: %s", strerror(-r));
                         return r;
@@ -1236,7 +1465,7 @@ static int register_machine(pid_t pid) {
                         return r;
                 }
 
-                r = sd_bus_message_append(m, "(sv)", "DeviceAllow", "a(ss)", 8,
+                r = sd_bus_message_append(m, "(sv)", "DeviceAllow", "a(ss)", 10,
                                           /* Allow the container to
                                            * access and create the API
                                            * device nodes, so that
@@ -1255,7 +1484,18 @@ static int register_machine(pid_t pid) {
                                            * container to ever create
                                            * these device nodes. */
                                           "/dev/pts/ptmx", "rw",
-                                          "char-pts", "rw");
+                                          "char-pts", "rw",
+                                          /* Allow the container
+                                           * access to all kdbus
+                                           * devices. Again, the
+                                           * container cannot create
+                                           * these nodes, only use
+                                           * them. We use a pretty
+                                           * open match here, so that
+                                           * the kernel API can still
+                                           * change. */
+                                          "char-kdbus", "rw",
+                                          "char-kdbus/*", "rw");
                 if (r < 0) {
                         log_error("Failed to add device whitelist: %s", strerror(-r));
                         return r;
@@ -1281,7 +1521,7 @@ static int register_machine(pid_t pid) {
 static int terminate_machine(pid_t pid) {
         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
-        _cleanup_bus_unref_ sd_bus *bus = NULL;
+        _cleanup_bus_close_unref_ sd_bus *bus = NULL;
         const char *path;
         int r;
 
@@ -1341,7 +1581,7 @@ static int reset_audit_loginuid(void) {
                 return 0;
 
         r = read_one_line_file("/proc/self/loginuid", &p);
-        if (r == -EEXIST)
+        if (r == -ENOENT)
                 return 0;
         if (r < 0) {
                 log_error("Failed to read /proc/self/loginuid: %s", strerror(-r));
@@ -1366,10 +1606,48 @@ static int reset_audit_loginuid(void) {
         return 0;
 }
 
-static int setup_veth(pid_t pid, char iface_name[IFNAMSIZ]) {
+#define HOST_HASH_KEY SD_ID128_MAKE(1a,37,6f,c7,46,ec,45,0b,ad,a3,d5,31,06,60,5d,b1)
+#define CONTAINER_HASH_KEY SD_ID128_MAKE(c3,c4,f9,19,b5,57,b2,1c,e6,cf,14,27,03,9c,ee,a2)
+
+static int generate_mac(struct ether_addr *mac, sd_id128_t hash_key) {
+        int r;
+
+        uint8_t result[8];
+        size_t l, sz;
+        uint8_t *v;
+
+        l = strlen(arg_machine);
+        sz = sizeof(sd_id128_t) + l;
+        v = alloca(sz);
+
+        /* fetch some persistent data unique to the host */
+        r = sd_id128_get_machine((sd_id128_t*) v);
+        if (r < 0)
+                return r;
+
+        /* combine with some data unique (on this host) to this
+         * container instance */
+        memcpy(v + sizeof(sd_id128_t), arg_machine, l);
+
+        /* Let's hash the host machine ID plus the container name. We
+         * use a fixed, but originally randomly created hash key here. */
+        siphash24(result, v, sz, hash_key.bytes);
+
+        assert_cc(ETH_ALEN <= sizeof(result));
+        memcpy(mac->ether_addr_octet, result, ETH_ALEN);
+
+        /* see eth_random_addr in the kernel */
+        mac->ether_addr_octet[0] &= 0xfe;        /* clear multicast bit */
+        mac->ether_addr_octet[0] |= 0x02;        /* set local assignment bit (IEEE802) */
+
+        return 0;
+}
+
+static int setup_veth(pid_t pid, char iface_name[IFNAMSIZ], int *ifi) {
         _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
         _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
-        int r;
+        struct ether_addr mac_host, mac_container;
+        int r, i;
 
         if (!arg_private_network)
                 return 0;
@@ -1379,12 +1657,20 @@ static int setup_veth(pid_t pid, char iface_name[IFNAMSIZ]) {
 
         /* Use two different interface name prefixes depending whether
          * we are in bridge mode or not. */
-        if (arg_network_bridge)
-                memcpy(iface_name, "vb-", 3);
-        else
-                memcpy(iface_name, "ve-", 3);
+        snprintf(iface_name, IFNAMSIZ, "%s-%s",
+                 arg_network_bridge ? "vb" : "ve", arg_machine);
+
+        r = generate_mac(&mac_container, CONTAINER_HASH_KEY);
+        if (r < 0) {
+                log_error("Failed to generate predictable MAC address for container side");
+                return r;
+        }
 
-        strncpy(iface_name+3, arg_machine, IFNAMSIZ - 3);
+        r = generate_mac(&mac_host, HOST_HASH_KEY);
+        if (r < 0) {
+                log_error("Failed to generate predictable MAC address for host side");
+                return r;
+        }
 
         r = sd_rtnl_open(&rtnl, 0);
         if (r < 0) {
@@ -1404,19 +1690,19 @@ static int setup_veth(pid_t pid, char iface_name[IFNAMSIZ]) {
                 return r;
         }
 
-        r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
+        r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, &mac_host);
         if (r < 0) {
-                log_error("Failed to open netlink container: %s", strerror(-r));
+                log_error("Failed to add netlink MAC address: %s", strerror(-r));
                 return r;
         }
 
-        r = sd_rtnl_message_append_string(m, IFLA_INFO_KIND, "veth");
+        r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
         if (r < 0) {
-                log_error("Failed to append netlink kind: %s", strerror(-r));
+                log_error("Failed to open netlink container: %s", strerror(-r));
                 return r;
         }
 
-        r = sd_rtnl_message_open_container(m, IFLA_INFO_DATA);
+        r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA, "veth");
         if (r < 0) {
                 log_error("Failed to open netlink container: %s", strerror(-r));
                 return r;
@@ -1434,6 +1720,12 @@ static int setup_veth(pid_t pid, char iface_name[IFNAMSIZ]) {
                 return r;
         }
 
+        r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, &mac_container);
+        if (r < 0) {
+                log_error("Failed to add netlink MAC address: %s", strerror(-r));
+                return r;
+        }
+
         r = sd_rtnl_message_append_u32(m, IFLA_NET_NS_PID, pid);
         if (r < 0) {
                 log_error("Failed to add netlink namespace field: %s", strerror(-r));
@@ -1464,10 +1756,18 @@ static int setup_veth(pid_t pid, char iface_name[IFNAMSIZ]) {
                 return r;
         }
 
+        i = (int) if_nametoindex(iface_name);
+        if (i <= 0) {
+                log_error("Failed to resolve interface %s: %m", iface_name);
+                return -errno;
+        }
+
+        *ifi = i;
+
         return 0;
 }
 
-static int setup_bridge(const char veth_name[]) {
+static int setup_bridge(const char veth_name[], int *ifi) {
         _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
         _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
         int r, bridge;
@@ -1487,6 +1787,8 @@ static int setup_bridge(const char veth_name[]) {
                 return -errno;
         }
 
+        *ifi = bridge;
+
         r = sd_rtnl_open(&rtnl, 0);
         if (r < 0) {
                 log_error("Failed to connect to netlink: %s", strerror(-r));
@@ -1499,6 +1801,12 @@ static int setup_bridge(const char veth_name[]) {
                 return r;
         }
 
+        r = sd_rtnl_message_link_set_flags(m, IFF_UP, IFF_UP);
+        if (r < 0) {
+                log_error("Failed to set IFF_UP flag: %s", strerror(-r));
+                return r;
+        }
+
         r = sd_rtnl_message_append_string(m, IFLA_IFNAME, veth_name);
         if (r < 0) {
                 log_error("Failed to add netlink interface name field: %s", strerror(-r));
@@ -1520,6 +1828,32 @@ static int setup_bridge(const char veth_name[]) {
         return 0;
 }
 
+static int parse_interface(struct udev *udev, const char *name) {
+        _cleanup_udev_device_unref_ struct udev_device *d = NULL;
+        char ifi_str[2 + DECIMAL_STR_MAX(int)];
+        int ifi;
+
+        ifi = (int) if_nametoindex(name);
+        if (ifi <= 0) {
+                log_error("Failed to resolve interface %s: %m", name);
+                return -errno;
+        }
+
+        sprintf(ifi_str, "n%i", ifi);
+        d = udev_device_new_from_device_id(udev, ifi_str);
+        if (!d) {
+                log_error("Failed to get udev device for interface %s: %m", name);
+                return -errno;
+        }
+
+        if (udev_device_get_is_initialized(d) <= 0) {
+                log_error("Network interface %s is not initialized yet.", name);
+                return -EBUSY;
+        }
+
+        return ifi;
+}
+
 static int move_network_interfaces(pid_t pid) {
         _cleanup_udev_unref_ struct udev *udev = NULL;
         _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
@@ -1546,27 +1880,11 @@ static int move_network_interfaces(pid_t pid) {
 
         STRV_FOREACH(i, arg_network_interfaces) {
                 _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
-                _cleanup_udev_device_unref_ struct udev_device *d = NULL;
-                char ifi_str[2 + DECIMAL_STR_MAX(int)];
                 int ifi;
 
-                ifi = (int) if_nametoindex(*i);
-                if (ifi <= 0) {
-                        log_error("Failed to resolve interface %s: %m", *i);
-                        return -errno;
-                }
-
-                sprintf(ifi_str, "n%i", ifi);
-                d = udev_device_new_from_device_id(udev, ifi_str);
-                if (!d) {
-                        log_error("Failed to get udev device for interface %s: %m", *i);
-                        return -errno;
-                }
-
-                if (udev_device_get_is_initialized(d) <= 0) {
-                        log_error("Network interface %s is not initialized yet.", *i);
-                        return -EBUSY;
-                }
+                ifi = parse_interface(udev, *i);
+                if (ifi < 0)
+                        return ifi;
 
                 r = sd_rtnl_message_new_link(rtnl, &m, RTM_NEWLINK, ifi);
                 if (r < 0) {
@@ -1590,75 +1908,1006 @@ static int move_network_interfaces(pid_t pid) {
         return 0;
 }
 
-static int audit_still_doesnt_work_in_containers(void) {
-
-#ifdef HAVE_SECCOMP
-        scmp_filter_ctx seccomp;
+static int setup_macvlan(pid_t pid) {
+        _cleanup_udev_unref_ struct udev *udev = NULL;
+        _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
+        char **i;
         int r;
 
-        /*
-           Audit is broken in containers, much of the userspace audit
-           hookup will fail if running inside a container. We don't
-           care and just turn off creation of audit sockets.
-
-           This will make socket(AF_NETLINK, *, NETLINK_AUDIT) fail
-           with EAFNOSUPPORT which audit userspace uses as indication
-           that audit is disabled in the kernel.
-         */
-
-        seccomp = seccomp_init(SCMP_ACT_ALLOW);
-        if (!seccomp)
-                return log_oom();
+        if (!arg_private_network)
+                return 0;
 
-        r = seccomp_add_secondary_archs(seccomp);
-        if (r < 0 && r != -EEXIST) {
-                log_error("Failed to add secondary archs to seccomp filter: %s", strerror(-r));
-                goto finish;
-        }
+        if (strv_isempty(arg_network_macvlan))
+                return 0;
 
-        r = seccomp_rule_add(
-                        seccomp,
-                        SCMP_ACT_ERRNO(EAFNOSUPPORT),
-                        SCMP_SYS(socket),
-                        2,
-                        SCMP_A0(SCMP_CMP_EQ, AF_NETLINK),
-                        SCMP_A2(SCMP_CMP_EQ, NETLINK_AUDIT));
+        r = sd_rtnl_open(&rtnl, 0);
         if (r < 0) {
-                log_error("Failed to add audit seccomp rule: %s", strerror(-r));
-                goto finish;
+                log_error("Failed to connect to netlink: %s", strerror(-r));
+                return r;
         }
 
-        r = seccomp_attr_set(seccomp, SCMP_FLTATR_CTL_NNP, 0);
-        if (r < 0) {
-                log_error("Failed to unset NO_NEW_PRIVS: %s", strerror(-r));
-                goto finish;
+        udev = udev_new();
+        if (!udev) {
+                log_error("Failed to connect to udev.");
+                return -ENOMEM;
         }
 
-        r = seccomp_load(seccomp);
-        if (r < 0)
-                log_error("Failed to install seccomp audit filter: %s", strerror(-r));
-
+        STRV_FOREACH(i, arg_network_macvlan) {
+                _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
+                _cleanup_free_ char *n = NULL;
+                int ifi;
+
+                ifi = parse_interface(udev, *i);
+                if (ifi < 0)
+                        return ifi;
+
+                r = sd_rtnl_message_new_link(rtnl, &m, RTM_NEWLINK, 0);
+                if (r < 0) {
+                        log_error("Failed to allocate netlink message: %s", strerror(-r));
+                        return r;
+                }
+
+                r = sd_rtnl_message_append_u32(m, IFLA_LINK, ifi);
+                if (r < 0) {
+                        log_error("Failed to add netlink interface index: %s", strerror(-r));
+                        return r;
+                }
+
+                n = strappend("mv-", *i);
+                if (!n)
+                        return log_oom();
+
+                strshorten(n, IFNAMSIZ-1);
+
+                r = sd_rtnl_message_append_string(m, IFLA_IFNAME, n);
+                if (r < 0) {
+                        log_error("Failed to add netlink interface name: %s", strerror(-r));
+                        return r;
+                }
+
+                r = sd_rtnl_message_append_u32(m, IFLA_NET_NS_PID, pid);
+                if (r < 0) {
+                        log_error("Failed to add netlink namespace field: %s", strerror(-r));
+                        return r;
+                }
+
+                r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
+                if (r < 0) {
+                        log_error("Failed to open netlink container: %s", strerror(-r));
+                        return r;
+                }
+
+                r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA, "macvlan");
+                if (r < 0) {
+                        log_error("Failed to open netlink container: %s", strerror(-r));
+                        return r;
+                }
+
+                r = sd_rtnl_message_append_u32(m, IFLA_MACVLAN_MODE, MACVLAN_MODE_BRIDGE);
+                if (r < 0) {
+                        log_error("Failed to append macvlan mode: %s", strerror(-r));
+                        return r;
+                }
+
+                r = sd_rtnl_message_close_container(m);
+                if (r < 0) {
+                        log_error("Failed to close netlink container: %s", strerror(-r));
+                        return r;
+                }
+
+                r = sd_rtnl_message_close_container(m);
+                if (r < 0) {
+                        log_error("Failed to close netlink container: %s", strerror(-r));
+                        return r;
+                }
+
+                r = sd_rtnl_call(rtnl, m, 0, NULL);
+                if (r < 0) {
+                        log_error("Failed to add new macvlan interfaces: %s", strerror(-r));
+                        return r;
+                }
+        }
+
+        return 0;
+}
+
+static int setup_seccomp(void) {
+
+#ifdef HAVE_SECCOMP
+        static const int blacklist[] = {
+                SCMP_SYS(kexec_load),
+                SCMP_SYS(open_by_handle_at),
+                SCMP_SYS(init_module),
+                SCMP_SYS(finit_module),
+                SCMP_SYS(delete_module),
+                SCMP_SYS(iopl),
+                SCMP_SYS(ioperm),
+                SCMP_SYS(swapon),
+                SCMP_SYS(swapoff),
+        };
+
+        scmp_filter_ctx seccomp;
+        unsigned i;
+        int r;
+
+        seccomp = seccomp_init(SCMP_ACT_ALLOW);
+        if (!seccomp)
+                return log_oom();
+
+        r = seccomp_add_secondary_archs(seccomp);
+        if (r < 0) {
+                log_error("Failed to add secondary archs to seccomp filter: %s", strerror(-r));
+                goto finish;
+        }
+
+        for (i = 0; i < ELEMENTSOF(blacklist); i++) {
+                r = seccomp_rule_add(seccomp, SCMP_ACT_ERRNO(EPERM), blacklist[i], 0);
+                if (r == -EFAULT)
+                        continue; /* unknown syscall */
+                if (r < 0) {
+                        log_error("Failed to block syscall: %s", strerror(-r));
+                        goto finish;
+                }
+        }
+
+        /*
+           Audit is broken in containers, much of the userspace audit
+           hookup will fail if running inside a container. We don't
+           care and just turn off creation of audit sockets.
+
+           This will make socket(AF_NETLINK, *, NETLINK_AUDIT) fail
+           with EAFNOSUPPORT which audit userspace uses as indication
+           that audit is disabled in the kernel.
+         */
+
+        r = seccomp_rule_add(
+                        seccomp,
+                        SCMP_ACT_ERRNO(EAFNOSUPPORT),
+                        SCMP_SYS(socket),
+                        2,
+                        SCMP_A0(SCMP_CMP_EQ, AF_NETLINK),
+                        SCMP_A2(SCMP_CMP_EQ, NETLINK_AUDIT));
+        if (r < 0) {
+                log_error("Failed to add audit seccomp rule: %s", strerror(-r));
+                goto finish;
+        }
+
+        r = seccomp_attr_set(seccomp, SCMP_FLTATR_CTL_NNP, 0);
+        if (r < 0) {
+                log_error("Failed to unset NO_NEW_PRIVS: %s", strerror(-r));
+                goto finish;
+        }
+
+        r = seccomp_load(seccomp);
+        if (r < 0)
+                log_error("Failed to install seccomp audit filter: %s", strerror(-r));
+
 finish:
         seccomp_release(seccomp);
         return r;
 #else
         return 0;
-#endif
+#endif
+
+}
+
+static int setup_image(char **device_path, int *loop_nr) {
+        struct loop_info64 info = {
+                .lo_flags = LO_FLAGS_AUTOCLEAR|LO_FLAGS_PARTSCAN
+        };
+        _cleanup_close_ int fd = -1, control = -1, loop = -1;
+        _cleanup_free_ char* loopdev = NULL;
+        struct stat st;
+        int r, nr;
+
+        assert(device_path);
+        assert(loop_nr);
+
+        fd = open(arg_image, O_CLOEXEC|(arg_read_only ? O_RDONLY : O_RDWR)|O_NONBLOCK|O_NOCTTY);
+        if (fd < 0) {
+                log_error("Failed to open %s: %m", arg_image);
+                return -errno;
+        }
+
+        if (fstat(fd, &st) < 0) {
+                log_error("Failed to stat %s: %m", arg_image);
+                return -errno;
+        }
+
+        if (S_ISBLK(st.st_mode)) {
+                char *p;
+
+                p = strdup(arg_image);
+                if (!p)
+                        return log_oom();
+
+                *device_path = p;
+
+                *loop_nr = -1;
+
+                r = fd;
+                fd = -1;
+
+                return r;
+        }
+
+        if (!S_ISREG(st.st_mode)) {
+                log_error("%s is not a regular file or block device: %m", arg_image);
+                return -EINVAL;
+        }
+
+        control = open("/dev/loop-control", O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK);
+        if (control < 0) {
+                log_error("Failed to open /dev/loop-control: %m");
+                return -errno;
+        }
+
+        nr = ioctl(control, LOOP_CTL_GET_FREE);
+        if (nr < 0) {
+                log_error("Failed to allocate loop device: %m");
+                return -errno;
+        }
+
+        if (asprintf(&loopdev, "/dev/loop%i", nr) < 0)
+                return log_oom();
+
+        loop = open(loopdev, O_CLOEXEC|(arg_read_only ? O_RDONLY : O_RDWR)|O_NONBLOCK|O_NOCTTY);
+        if (loop < 0) {
+                log_error("Failed to open loop device %s: %m", loopdev);
+                return -errno;
+        }
+
+        if (ioctl(loop, LOOP_SET_FD, fd) < 0) {
+                log_error("Failed to set loopback file descriptor on %s: %m", loopdev);
+                return -errno;
+        }
+
+        if (arg_read_only)
+                info.lo_flags |= LO_FLAGS_READ_ONLY;
+
+        if (ioctl(loop, LOOP_SET_STATUS64, &info) < 0) {
+                log_error("Failed to set loopback settings on %s: %m", loopdev);
+                return -errno;
+        }
+
+        *device_path = loopdev;
+        loopdev = NULL;
+
+        *loop_nr = nr;
+
+        r = loop;
+        loop = -1;
+
+        return r;
+}
+
+static int dissect_image(
+                int fd,
+                char **root_device, bool *root_device_rw,
+                char **home_device, bool *home_device_rw,
+                char **srv_device, bool *srv_device_rw,
+                bool *secondary) {
+
+#ifdef HAVE_BLKID
+        int home_nr = -1, root_nr = -1, secondary_root_nr = -1, srv_nr = -1;
+        _cleanup_free_ char *home = NULL, *root = NULL, *secondary_root = NULL, *srv = NULL;
+        _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
+        _cleanup_udev_device_unref_ struct udev_device *d = NULL;
+        _cleanup_blkid_free_probe_ blkid_probe b = NULL;
+        _cleanup_udev_unref_ struct udev *udev = NULL;
+        struct udev_list_entry *first, *item;
+        bool home_rw = true, root_rw = true, secondary_root_rw = true, srv_rw = true;
+        const char *pttype = NULL;
+        blkid_partlist pl;
+        struct stat st;
+        int r;
+
+        assert(fd >= 0);
+        assert(root_device);
+        assert(home_device);
+        assert(srv_device);
+        assert(secondary);
+
+        b = blkid_new_probe();
+        if (!b)
+                return log_oom();
+
+        errno = 0;
+        r = blkid_probe_set_device(b, fd, 0, 0);
+        if (r != 0) {
+                if (errno == 0)
+                        return log_oom();
+
+                log_error("Failed to set device on blkid probe: %m");
+                return -errno;
+        }
+
+        blkid_probe_enable_partitions(b, 1);
+        blkid_probe_set_partitions_flags(b, BLKID_PARTS_ENTRY_DETAILS);
+
+        errno = 0;
+        r = blkid_do_safeprobe(b);
+        if (r == -2 || r == 1) {
+                log_error("Failed to identify any partition table on %s.\n"
+                          "Note that the disk image needs to follow http://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/ to be supported by systemd-nspawn.", arg_image);
+                return -EINVAL;
+        } else if (r != 0) {
+                if (errno == 0)
+                        errno = EIO;
+                log_error("Failed to probe: %m");
+                return -errno;
+        }
+
+        blkid_probe_lookup_value(b, "PTTYPE", &pttype, NULL);
+        if (!streq_ptr(pttype, "gpt")) {
+                log_error("Image %s does not carry a GUID Partition Table.\n"
+                          "Note that the disk image needs to follow http://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/ to be supported by systemd-nspawn.", arg_image);
+                return -EINVAL;
+        }
+
+        errno = 0;
+        pl = blkid_probe_get_partitions(b);
+        if (!pl) {
+                if (errno == 0)
+                        return log_oom();
+
+                log_error("Failed to list partitions of %s", arg_image);
+                return -errno;
+        }
+
+        udev = udev_new();
+        if (!udev)
+                return log_oom();
+
+        if (fstat(fd, &st) < 0) {
+                log_error("Failed to stat block device: %m");
+                return -errno;
+        }
+
+        d = udev_device_new_from_devnum(udev, 'b', st.st_rdev);
+        if (!d)
+                return log_oom();
+
+        e = udev_enumerate_new(udev);
+        if (!e)
+                return log_oom();
+
+        r = udev_enumerate_add_match_parent(e, d);
+        if (r < 0)
+                return log_oom();
+
+        r = udev_enumerate_scan_devices(e);
+        if (r < 0) {
+                log_error("Failed to scan for partition devices of %s: %s", arg_image, strerror(-r));
+                return r;
+        }
+
+        first = udev_enumerate_get_list_entry(e);
+        udev_list_entry_foreach(item, first) {
+                _cleanup_udev_device_unref_ struct udev_device *q;
+                const char *stype, *node;
+                unsigned long long flags;
+                sd_id128_t type_id;
+                blkid_partition pp;
+                dev_t qn;
+                int nr;
+
+                errno = 0;
+                q = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item));
+                if (!q) {
+                        if (!errno)
+                                errno = ENOMEM;
+
+                        log_error("Failed to get partition device of %s: %m", arg_image);
+                        return -errno;
+                }
+
+                qn = udev_device_get_devnum(q);
+                if (major(qn) == 0)
+                        continue;
+
+                if (st.st_rdev == qn)
+                        continue;
+
+                node = udev_device_get_devnode(q);
+                if (!node)
+                        continue;
+
+                pp = blkid_partlist_devno_to_partition(pl, qn);
+                if (!pp)
+                        continue;
+
+                flags = blkid_partition_get_flags(pp);
+                if (flags & GPT_FLAG_NO_AUTO)
+                        continue;
+
+                nr = blkid_partition_get_partno(pp);
+                if (nr < 0)
+                        continue;
+
+                stype = blkid_partition_get_type_string(pp);
+                if (!stype)
+                        continue;
+
+                if (sd_id128_from_string(stype, &type_id) < 0)
+                        continue;
+
+                if (sd_id128_equal(type_id, GPT_HOME)) {
+
+                        if (home && nr >= home_nr)
+                                continue;
+
+                        home_nr = nr;
+                        home_rw = !(flags & GPT_FLAG_READ_ONLY);
+
+                        free(home);
+                        home = strdup(node);
+                        if (!home)
+                                return log_oom();
+                } else if (sd_id128_equal(type_id, GPT_SRV)) {
+
+                        if (srv && nr >= srv_nr)
+                                continue;
+
+                        srv_nr = nr;
+                        srv_rw = !(flags & GPT_FLAG_READ_ONLY);
+
+                        free(srv);
+                        srv = strdup(node);
+                        if (!srv)
+                                return log_oom();
+                }
+#ifdef GPT_ROOT_NATIVE
+                else if (sd_id128_equal(type_id, GPT_ROOT_NATIVE)) {
+
+                        if (root && nr >= root_nr)
+                                continue;
+
+                        root_nr = nr;
+                        root_rw = !(flags & GPT_FLAG_READ_ONLY);
+
+                        free(root);
+                        root = strdup(node);
+                        if (!root)
+                                return log_oom();
+                }
+#endif
+#ifdef GPT_ROOT_SECONDARY
+                else if (sd_id128_equal(type_id, GPT_ROOT_SECONDARY)) {
+
+                        if (secondary_root && nr >= secondary_root_nr)
+                                continue;
+
+                        secondary_root_nr = nr;
+                        secondary_root_rw = !(flags & GPT_FLAG_READ_ONLY);
+
+
+                        free(secondary_root);
+                        secondary_root = strdup(node);
+                        if (!secondary_root)
+                                return log_oom();
+                }
+#endif
+        }
+
+        if (!root && !secondary_root) {
+                log_error("Failed to identify root partition in disk image %s.\n"
+                          "Note that the disk image needs to follow http://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/ to be supported by systemd-nspawn.", arg_image);
+                return -EINVAL;
+        }
+
+        if (root) {
+                *root_device = root;
+                root = NULL;
+
+                *root_device_rw = root_rw;
+                *secondary = false;
+        } else if (secondary_root) {
+                *root_device = secondary_root;
+                secondary_root = NULL;
+
+                *root_device_rw = secondary_root_rw;
+                *secondary = true;
+        }
+
+        if (home) {
+                *home_device = home;
+                home = NULL;
+
+                *home_device_rw = home_rw;
+        }
+
+        if (srv) {
+                *srv_device = srv;
+                srv = NULL;
+
+                *srv_device_rw = srv_rw;
+        }
+
+        return 0;
+#else
+        log_error("--image= is not supported, compiled without blkid support.");
+        return -ENOTSUP;
+#endif
+}
+
+static int mount_device(const char *what, const char *where, const char *directory, bool rw) {
+#ifdef HAVE_BLKID
+        _cleanup_blkid_free_probe_ blkid_probe b = NULL;
+        const char *fstype, *p;
+        int r;
+
+        assert(what);
+        assert(where);
+
+        if (arg_read_only)
+                rw = false;
+
+        if (directory)
+                p = strappenda(where, directory);
+        else
+                p = where;
+
+        errno = 0;
+        b = blkid_new_probe_from_filename(what);
+        if (!b) {
+                if (errno == 0)
+                        return log_oom();
+                log_error("Failed to allocate prober for %s: %m", what);
+                return -errno;
+        }
+
+        blkid_probe_enable_superblocks(b, 1);
+        blkid_probe_set_superblocks_flags(b, BLKID_SUBLKS_TYPE);
+
+        errno = 0;
+        r = blkid_do_safeprobe(b);
+        if (r == -1 || r == 1) {
+                log_error("Cannot determine file system type of %s", what);
+                return -EINVAL;
+        } else if (r != 0) {
+                if (errno == 0)
+                        errno = EIO;
+                log_error("Failed to probe %s: %m", what);
+                return -errno;
+        }
+
+        errno = 0;
+        if (blkid_probe_lookup_value(b, "TYPE", &fstype, NULL) < 0) {
+                if (errno == 0)
+                        errno = EINVAL;
+                log_error("Failed to determine file system type of %s", what);
+                return -errno;
+        }
+
+        if (streq(fstype, "crypto_LUKS")) {
+                log_error("nspawn currently does not support LUKS disk images.");
+                return -ENOTSUP;
+        }
+
+        if (mount(what, p, fstype, MS_NODEV|(rw ? 0 : MS_RDONLY), NULL) < 0) {
+                log_error("Failed to mount %s: %m", what);
+                return -errno;
+        }
+
+        return 0;
+#else
+        log_error("--image= is not supported, compiled without blkid support.");
+        return -ENOTSUP;
+#endif
+}
+
+static int mount_devices(
+                const char *where,
+                const char *root_device, bool root_device_rw,
+                const char *home_device, bool home_device_rw,
+                const char *srv_device, bool srv_device_rw) {
+        int r;
+
+        assert(where);
+
+        if (root_device) {
+                r = mount_device(root_device, arg_directory, NULL, root_device_rw);
+                if (r < 0) {
+                        log_error("Failed to mount root directory: %s", strerror(-r));
+                        return r;
+                }
+        }
+
+        if (home_device) {
+                r = mount_device(home_device, arg_directory, "/home", home_device_rw);
+                if (r < 0) {
+                        log_error("Failed to mount home directory: %s", strerror(-r));
+                        return r;
+                }
+        }
+
+        if (srv_device) {
+                r = mount_device(srv_device, arg_directory, "/srv", srv_device_rw);
+                if (r < 0) {
+                        log_error("Failed to mount server data directory: %s", strerror(-r));
+                        return r;
+                }
+        }
+
+        return 0;
+}
+
+static void loop_remove(int nr, int *image_fd) {
+        _cleanup_close_ int control = -1;
+
+        if (nr < 0)
+                return;
+
+        if (image_fd && *image_fd >= 0) {
+                ioctl(*image_fd, LOOP_CLR_FD);
+                *image_fd = safe_close(*image_fd);
+        }
+
+        control = open("/dev/loop-control", O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK);
+        if (control < 0)
+                return;
+
+        ioctl(control, LOOP_CTL_REMOVE, nr);
+}
+
+static int spawn_getent(const char *database, const char *key, pid_t *rpid) {
+        int pipe_fds[2];
+        pid_t pid;
+
+        assert(database);
+        assert(key);
+        assert(rpid);
+
+        if (pipe2(pipe_fds, O_CLOEXEC) < 0) {
+                log_error("Failed to allocate pipe: %m");
+                return -errno;
+        }
+
+        pid = fork();
+        if (pid < 0) {
+                log_error("Failed to fork getent child: %m");
+                return -errno;
+        } else if (pid == 0) {
+                int nullfd;
+                char *empty_env = NULL;
+
+                if (dup3(pipe_fds[1], STDOUT_FILENO, 0) < 0)
+                        _exit(EXIT_FAILURE);
+
+                if (pipe_fds[0] > 2)
+                        safe_close(pipe_fds[0]);
+                if (pipe_fds[1] > 2)
+                        safe_close(pipe_fds[1]);
+
+                nullfd = open("/dev/null", O_RDWR);
+                if (nullfd < 0)
+                        _exit(EXIT_FAILURE);
+
+                if (dup3(nullfd, STDIN_FILENO, 0) < 0)
+                        _exit(EXIT_FAILURE);
+
+                if (dup3(nullfd, STDERR_FILENO, 0) < 0)
+                        _exit(EXIT_FAILURE);
+
+                if (nullfd > 2)
+                        safe_close(nullfd);
+
+                reset_all_signal_handlers();
+                close_all_fds(NULL, 0);
+
+                execle("/usr/bin/getent", "getent", database, key, NULL, &empty_env);
+                execle("/bin/getent", "getent", database, key, NULL, &empty_env);
+                _exit(EXIT_FAILURE);
+        }
+
+        pipe_fds[1] = safe_close(pipe_fds[1]);
+
+        *rpid = pid;
+
+        return pipe_fds[0];
+}
+
+static int change_uid_gid(char **_home) {
+        char line[LINE_MAX], *x, *u, *g, *h;
+        const char *word, *state;
+        _cleanup_free_ uid_t *uids = NULL;
+        _cleanup_free_ char *home = NULL;
+        _cleanup_fclose_ FILE *f = NULL;
+        _cleanup_close_ int fd = -1;
+        unsigned n_uids = 0;
+        size_t sz = 0, l;
+        uid_t uid;
+        gid_t gid;
+        pid_t pid;
+        int r;
+
+        assert(_home);
+
+        if (!arg_user || streq(arg_user, "root") || streq(arg_user, "0")) {
+                /* Reset everything fully to 0, just in case */
+
+                if (setgroups(0, NULL) < 0) {
+                        log_error("setgroups() failed: %m");
+                        return -errno;
+                }
+
+                if (setresgid(0, 0, 0) < 0) {
+                        log_error("setregid() failed: %m");
+                        return -errno;
+                }
+
+                if (setresuid(0, 0, 0) < 0) {
+                        log_error("setreuid() failed: %m");
+                        return -errno;
+                }
+
+                *_home = NULL;
+                return 0;
+        }
+
+        /* First, get user credentials */
+        fd = spawn_getent("passwd", arg_user, &pid);
+        if (fd < 0)
+                return fd;
+
+        f = fdopen(fd, "r");
+        if (!f)
+                return log_oom();
+        fd = -1;
+
+        if (!fgets(line, sizeof(line), f)) {
+
+                if (!ferror(f)) {
+                        log_error("Failed to resolve user %s.", arg_user);
+                        return -ESRCH;
+                }
+
+                log_error("Failed to read from getent: %m");
+                return -errno;
+        }
+
+        truncate_nl(line);
+
+        wait_for_terminate_and_warn("getent passwd", pid);
+
+        x = strchr(line, ':');
+        if (!x) {
+                log_error("/etc/passwd entry has invalid user field.");
+                return -EIO;
+        }
+
+        u = strchr(x+1, ':');
+        if (!u) {
+                log_error("/etc/passwd entry has invalid password field.");
+                return -EIO;
+        }
+
+        u++;
+        g = strchr(u, ':');
+        if (!g) {
+                log_error("/etc/passwd entry has invalid UID field.");
+                return -EIO;
+        }
+
+        *g = 0;
+        g++;
+        x = strchr(g, ':');
+        if (!x) {
+                log_error("/etc/passwd entry has invalid GID field.");
+                return -EIO;
+        }
+
+        *x = 0;
+        h = strchr(x+1, ':');
+        if (!h) {
+                log_error("/etc/passwd entry has invalid GECOS field.");
+                return -EIO;
+        }
+
+        h++;
+        x = strchr(h, ':');
+        if (!x) {
+                log_error("/etc/passwd entry has invalid home directory field.");
+                return -EIO;
+        }
+
+        *x = 0;
+
+        r = parse_uid(u, &uid);
+        if (r < 0) {
+                log_error("Failed to parse UID of user.");
+                return -EIO;
+        }
+
+        r = parse_gid(g, &gid);
+        if (r < 0) {
+                log_error("Failed to parse GID of user.");
+                return -EIO;
+        }
+
+        home = strdup(h);
+        if (!home)
+                return log_oom();
+
+        /* Second, get group memberships */
+        fd = spawn_getent("initgroups", arg_user, &pid);
+        if (fd < 0)
+                return fd;
+
+        fclose(f);
+        f = fdopen(fd, "r");
+        if (!f)
+                return log_oom();
+        fd = -1;
+
+        if (!fgets(line, sizeof(line), f)) {
+                if (!ferror(f)) {
+                        log_error("Failed to resolve user %s.", arg_user);
+                        return -ESRCH;
+                }
+
+                log_error("Failed to read from getent: %m");
+                return -errno;
+        }
+
+        truncate_nl(line);
+
+        wait_for_terminate_and_warn("getent initgroups", pid);
+
+        /* Skip over the username and subsequent separator whitespace */
+        x = line;
+        x += strcspn(x, WHITESPACE);
+        x += strspn(x, WHITESPACE);
+
+        FOREACH_WORD(word, l, x, state) {
+                char c[l+1];
+
+                memcpy(c, word, l);
+                c[l] = 0;
+
+                if (!GREEDY_REALLOC(uids, sz, n_uids+1))
+                        return log_oom();
+
+                r = parse_uid(c, &uids[n_uids++]);
+                if (r < 0) {
+                        log_error("Failed to parse group data from getent.");
+                        return -EIO;
+                }
+        }
+
+        r = mkdir_parents(home, 0775);
+        if (r < 0) {
+                log_error("Failed to make home root directory: %s", strerror(-r));
+                return r;
+        }
+
+        r = mkdir_safe(home, 0755, uid, gid);
+        if (r < 0 && r != -EEXIST) {
+                log_error("Failed to make home directory: %s", strerror(-r));
+                return r;
+        }
+
+        fchown(STDIN_FILENO, uid, gid);
+        fchown(STDOUT_FILENO, uid, gid);
+        fchown(STDERR_FILENO, uid, gid);
+
+        if (setgroups(n_uids, uids) < 0) {
+                log_error("Failed to set auxiliary groups: %m");
+                return -errno;
+        }
+
+        if (setresgid(gid, gid, gid) < 0) {
+                log_error("setregid() failed: %m");
+                return -errno;
+        }
+
+        if (setresuid(uid, uid, uid) < 0) {
+                log_error("setreuid() failed: %m");
+                return -errno;
+        }
+
+        if (_home) {
+                *_home = home;
+                home = NULL;
+        }
+
+        return 0;
+}
+
+/*
+ * Return values:
+ * < 0 : wait_for_terminate() failed to get the state of the
+ *       container, the container was terminated by a signal, or
+ *       failed for an unknown reason.  No change is made to the
+ *       container argument.
+ * > 0 : The program executed in the container terminated with an
+ *       error.  The exit code of the program executed in the
+ *       container is returned.  No change is made to the container
+ *       argument.
+ *   0 : The container is being rebooted, has been shut down or exited
+ *       successfully.  The container argument has been set to either
+ *       CONTAINER_TERMINATED or CONTAINER_REBOOTED.
+ *
+ * That is, success is indicated by a return value of zero, and an
+ * error is indicated by a non-zero value.
+ */
+static int wait_for_container(pid_t pid, ContainerStatus *container) {
+        int r;
+        siginfo_t status;
+
+        r = wait_for_terminate(pid, &status);
+        if (r < 0) {
+                log_warning("Failed to wait for container: %s", strerror(-r));
+                return r;
+        }
+
+        switch (status.si_code) {
+        case CLD_EXITED:
+                r = status.si_status;
+                if (r == 0) {
+                        if (!arg_quiet)
+                                log_debug("Container %s exited successfully.",
+                                          arg_machine);
+
+                        *container = CONTAINER_TERMINATED;
+                } else {
+                        log_error("Container %s failed with error code %i.",
+                                  arg_machine, status.si_status);
+                }
+                break;
+
+        case CLD_KILLED:
+                if (status.si_status == SIGINT) {
+                        if (!arg_quiet)
+                                log_info("Container %s has been shut down.",
+                                         arg_machine);
+
+                        *container = CONTAINER_TERMINATED;
+                        r = 0;
+                        break;
+                } else if (status.si_status == SIGHUP) {
+                        if (!arg_quiet)
+                                log_info("Container %s is being rebooted.",
+                                         arg_machine);
+
+                        *container = CONTAINER_REBOOTED;
+                        r = 0;
+                        break;
+                }
+                /* CLD_KILLED fallthrough */
+
+        case CLD_DUMPED:
+                log_error("Container %s terminated by signal %s.",
+                          arg_machine, signal_to_string(status.si_status));
+                r = -1;
+                break;
+
+        default:
+                log_error("Container %s failed due to unknown reason.",
+                          arg_machine);
+                r = -1;
+                break;
+        }
 
+        return r;
 }
 
+static void nop_handler(int sig) {}
+
 int main(int argc, char *argv[]) {
 
-        _cleanup_close_ int master = -1, kdbus_fd = -1, sync_fd = -1;
-        _cleanup_close_pipe_ int kmsg_socket_pair[2] = { -1, -1 };
-        _cleanup_free_ char *kdbus_domain = NULL;
+        _cleanup_free_ char *kdbus_domain = NULL, *device_path = NULL, *root_device = NULL, *home_device = NULL, *srv_device = NULL;
+        bool root_device_rw = true, home_device_rw = true, srv_device_rw = true;
+        _cleanup_close_ int master = -1, kdbus_fd = -1, image_fd = -1;
+        _cleanup_close_pair_ int kmsg_socket_pair[2] = { -1, -1 };
         _cleanup_fdset_free_ FDSet *fds = NULL;
+        int r = EXIT_FAILURE, k, n_fd_passed, loop_nr = -1;
         const char *console = NULL;
-        int r = EXIT_FAILURE, k;
-        int n_fd_passed;
-        pid_t pid = 0;
-        sigset_t mask;
         char veth_name[IFNAMSIZ];
+        bool secondary = false;
+        sigset_t mask, mask_chld;
+        pid_t pid = 0;
 
         log_parse_environment();
         log_open();
@@ -1671,24 +2920,25 @@ int main(int argc, char *argv[]) {
                 goto finish;
         }
 
-        if (arg_directory) {
-                char *p;
+        if (!arg_image) {
+                if (arg_directory) {
+                        char *p;
 
-                p = path_make_absolute_cwd(arg_directory);
-                free(arg_directory);
-                arg_directory = p;
-        } else
-                arg_directory = get_current_dir_name();
+                        p = path_make_absolute_cwd(arg_directory);
+                        free(arg_directory);
+                        arg_directory = p;
+                } else
+                        arg_directory = get_current_dir_name();
 
-        if (!arg_directory) {
-                log_error("Failed to determine path, please use -D.");
-                goto finish;
+                if (!arg_directory) {
+                        log_error("Failed to determine path, please use -D.");
+                        goto finish;
+                }
+                path_kill_slashes(arg_directory);
         }
 
-        path_kill_slashes(arg_directory);
-
         if (!arg_machine) {
-                arg_machine = strdup(basename(arg_directory));
+                arg_machine = strdup(basename(arg_image ? arg_image : arg_directory));
                 if (!arg_machine) {
                         log_oom();
                         goto finish;
@@ -1711,39 +2961,69 @@ int main(int argc, char *argv[]) {
                 goto finish;
         }
 
-        if (path_equal(arg_directory, "/")) {
-                log_error("Spawning container on root directory not supported.");
-                goto finish;
+        log_close();
+        n_fd_passed = sd_listen_fds(false);
+        if (n_fd_passed > 0) {
+                k = fdset_new_listen_fds(&fds, false);
+                if (k < 0) {
+                        log_error("Failed to collect file descriptors: %s", strerror(-k));
+                        goto finish;
+                }
         }
+        fdset_close_others(fds);
+        log_open();
 
-        if (arg_boot) {
-                if (path_is_os_tree(arg_directory) <= 0) {
-                        log_error("Directory %s doesn't look like an OS root directory (/etc/os-release is missing). Refusing.", arg_directory);
+        if (arg_directory) {
+                if (path_equal(arg_directory, "/")) {
+                        log_error("Spawning container on root directory not supported.");
                         goto finish;
                 }
+
+                if (arg_boot) {
+                        if (path_is_os_tree(arg_directory) <= 0) {
+                                log_error("Directory %s doesn't look like an OS root directory (os-release file is missing). Refusing.", arg_directory);
+                                goto finish;
+                        }
+                } else {
+                        const char *p;
+
+                        p = strappenda(arg_directory,
+                                       argc > optind && path_is_absolute(argv[optind]) ? argv[optind] : "/usr/bin/");
+                        if (access(p, F_OK) < 0) {
+                                log_error("Directory %s lacks the binary to execute or doesn't look like a binary tree. Refusing.", arg_directory);
+                                goto finish;
+
+                        }
+                }
         } else {
-                const char *p;
+                char template[] = "/tmp/nspawn-root-XXXXXX";
 
-                p = strappenda(arg_directory,
-                               argc > optind && path_is_absolute(argv[optind]) ? argv[optind] : "/usr/bin/");
-                if (access(p, F_OK) < 0) {
-                        log_error("Directory %s lacks the binary to execute or doesn't look like a binary tree. Refusing.", arg_directory);
+                if (!mkdtemp(template)) {
+                        log_error("Failed to create temporary directory: %m");
+                        r = -errno;
                         goto finish;
+                }
 
+                arg_directory = strdup(template);
+                if (!arg_directory) {
+                        r = log_oom();
+                        goto finish;
                 }
-        }
 
-        log_close();
-        n_fd_passed = sd_listen_fds(false);
-        if (n_fd_passed > 0) {
-                k = fdset_new_listen_fds(&fds, false);
-                if (k < 0) {
-                        log_error("Failed to collect file descriptors: %s", strerror(-k));
+                image_fd = setup_image(&device_path, &loop_nr);
+                if (image_fd < 0) {
+                        r = image_fd;
                         goto finish;
                 }
+
+                r = dissect_image(image_fd,
+                                  &root_device, &root_device_rw,
+                                  &home_device, &home_device_rw,
+                                  &srv_device, &srv_device_rw,
+                                  &secondary);
+                if (r < 0)
+                        goto finish;
         }
-        fdset_close_others(fds);
-        log_open();
 
         master = posix_openpt(O_RDWR|O_NOCTTY|O_CLOEXEC|O_NDELAY);
         if (master < 0) {
@@ -1758,7 +3038,8 @@ int main(int argc, char *argv[]) {
         }
 
         if (!arg_quiet)
-                log_info("Spawning container %s on %s. Press ^] three times within 1s to abort execution.", arg_machine, arg_directory);
+                log_info("Spawning container %s on %s.\nPress ^] three times within 1s to kill container.",
+                         arg_machine, arg_image ? arg_image : arg_directory);
 
         if (unlockpt(master) < 0) {
                 log_error("Failed to unlock tty: %m");
@@ -1793,36 +3074,56 @@ int main(int argc, char *argv[]) {
         sd_notify(0, "READY=1");
 
         assert_se(sigemptyset(&mask) == 0);
+        assert_se(sigemptyset(&mask_chld) == 0);
+        sigaddset(&mask_chld, SIGCHLD);
         sigset_add_many(&mask, SIGCHLD, SIGWINCH, SIGTERM, SIGINT, -1);
         assert_se(sigprocmask(SIG_BLOCK, &mask, NULL) == 0);
 
         for (;;) {
-                siginfo_t status;
+                ContainerStatus container_status;
+                _cleanup_(barrier_destroy) Barrier barrier = BARRIER_NULL;
+                struct sigaction sa = {
+                        .sa_handler = nop_handler,
+                        .sa_flags = SA_NOCLDSTOP,
+                };
+
+                r = barrier_create(&barrier);
+                if (r < 0) {
+                        log_error("Cannot initialize IPC barrier: %s", strerror(-r));
+                        goto finish;
+                }
+
+                /* Child can be killed before execv(), so handle SIGCHLD
+                 * in order to interrupt parent's blocking calls and
+                 * give it a chance to call wait() and terminate. */
+                r = sigprocmask(SIG_UNBLOCK, &mask_chld, NULL);
+                if (r < 0) {
+                        log_error("Failed to change the signal mask: %m");
+                        goto finish;
+                }
 
-                sync_fd = eventfd(0, EFD_CLOEXEC);
-                if (sync_fd < 0) {
-                        log_error("Failed to create event fd: %m");
+                r = sigaction(SIGCHLD, &sa, NULL);
+                if (r < 0) {
+                        log_error("Failed to install SIGCHLD handler: %m");
                         goto finish;
                 }
 
-                pid = syscall(__NR_clone,
-                              SIGCHLD|CLONE_NEWNS|
-                              (arg_share_system ? 0 : CLONE_NEWIPC|CLONE_NEWPID|CLONE_NEWUTS)|
-                              (arg_private_network ? CLONE_NEWNET : 0), NULL);
+                pid = syscall(__NR_clone, SIGCHLD|CLONE_NEWNS|
+                                          (arg_share_system ? 0 : CLONE_NEWIPC|CLONE_NEWPID|CLONE_NEWUTS)|
+                                          (arg_private_network ? CLONE_NEWNET : 0), NULL);
                 if (pid < 0) {
                         if (errno == EINVAL)
                                 log_error("clone() failed, do you have namespace support enabled in your kernel? (You need UTS, IPC, PID and NET namespacing built in): %m");
                         else
                                 log_error("clone() failed: %m");
 
+                        r = pid;
                         goto finish;
                 }
 
                 if (pid == 0) {
                         /* child */
-                        const char *home = NULL;
-                        uid_t uid = (uid_t) -1;
-                        gid_t gid = (gid_t) -1;
+                        _cleanup_free_ char *home = NULL;
                         unsigned n_env = 2;
                         const char *envp[] = {
                                 "PATH=" DEFAULT_PATH_SPLIT_USR,
@@ -1837,21 +3138,20 @@ int main(int argc, char *argv[]) {
                                 NULL
                         };
                         char **env_use;
-                        eventfd_t x;
+
+                        barrier_set_role(&barrier, BARRIER_CHILD);
 
                         envp[n_env] = strv_find_prefix(environ, "TERM=");
                         if (envp[n_env])
                                 n_env ++;
 
-                        close_nointr_nofail(master);
-                        master = -1;
+                        master = safe_close(master);
 
                         close_nointr(STDIN_FILENO);
                         close_nointr(STDOUT_FILENO);
                         close_nointr(STDERR_FILENO);
 
-                        close_nointr_nofail(kmsg_socket_pair[0]);
-                        kmsg_socket_pair[0] = -1;
+                        kmsg_socket_pair[0] = safe_close(kmsg_socket_pair[0]);
 
                         reset_all_signal_handlers();
 
@@ -1861,31 +3161,31 @@ int main(int argc, char *argv[]) {
                         k = open_terminal(console, O_RDWR);
                         if (k != STDIN_FILENO) {
                                 if (k >= 0) {
-                                        close_nointr_nofail(k);
+                                        safe_close(k);
                                         k = -EINVAL;
                                 }
 
                                 log_error("Failed to open console: %s", strerror(-k));
-                                goto child_fail;
+                                _exit(EXIT_FAILURE);
                         }
 
                         if (dup2(STDIN_FILENO, STDOUT_FILENO) != STDOUT_FILENO ||
                             dup2(STDIN_FILENO, STDERR_FILENO) != STDERR_FILENO) {
                                 log_error("Failed to duplicate console: %m");
-                                goto child_fail;
+                                _exit(EXIT_FAILURE);
                         }
 
                         if (setsid() < 0) {
                                 log_error("setsid() failed: %m");
-                                goto child_fail;
+                                _exit(EXIT_FAILURE);
                         }
 
                         if (reset_audit_loginuid() < 0)
-                                goto child_fail;
+                                _exit(EXIT_FAILURE);
 
                         if (prctl(PR_SET_PDEATHSIG, SIGKILL) < 0) {
                                 log_error("PR_SET_PDEATHSIG failed: %m");
-                                goto child_fail;
+                                _exit(EXIT_FAILURE);
                         }
 
                         /* Mark everything as slave, so that we still
@@ -1893,83 +3193,109 @@ int main(int argc, char *argv[]) {
                          * propagate mounts to the real root. */
                         if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL) < 0) {
                                 log_error("MS_SLAVE|MS_REC failed: %m");
-                                goto child_fail;
+                                _exit(EXIT_FAILURE);
                         }
 
+                        if (mount_devices(arg_directory,
+                                          root_device, root_device_rw,
+                                          home_device, home_device_rw,
+                                          srv_device, srv_device_rw) < 0)
+                                _exit(EXIT_FAILURE);
+
                         /* Turn directory into bind mount */
                         if (mount(arg_directory, arg_directory, "bind", MS_BIND|MS_REC, NULL) < 0) {
-                                log_error("Failed to make bind mount.");
-                                goto child_fail;
+                                log_error("Failed to make bind mount: %m");
+                                _exit(EXIT_FAILURE);
                         }
 
-                        if (arg_read_only)
-                                if (mount(arg_directory, arg_directory, "bind", MS_BIND|MS_REMOUNT|MS_RDONLY|MS_REC, NULL) < 0) {
-                                        log_error("Failed to make read-only.");
-                                        goto child_fail;
+                        r = setup_volatile(arg_directory);
+                        if (r < 0)
+                                _exit(EXIT_FAILURE);
+
+                        if (setup_volatile_state(arg_directory) < 0)
+                                _exit(EXIT_FAILURE);
+
+                        r = base_filesystem_create(arg_directory);
+                        if (r < 0)
+                                _exit(EXIT_FAILURE);
+
+                        if (arg_read_only) {
+                                k = bind_remount_recursive(arg_directory, true);
+                                if (k < 0) {
+                                        log_error("Failed to make tree read-only: %s", strerror(-k));
+                                        _exit(EXIT_FAILURE);
                                 }
+                        }
 
                         if (mount_all(arg_directory) < 0)
-                                goto child_fail;
+                                _exit(EXIT_FAILURE);
 
                         if (copy_devnodes(arg_directory) < 0)
-                                goto child_fail;
+                                _exit(EXIT_FAILURE);
 
                         if (setup_ptmx(arg_directory) < 0)
-                                goto child_fail;
+                                _exit(EXIT_FAILURE);
 
                         dev_setup(arg_directory);
 
-                        if (audit_still_doesnt_work_in_containers() < 0)
-                                goto child_fail;
+                        if (setup_seccomp() < 0)
+                                _exit(EXIT_FAILURE);
 
                         if (setup_dev_console(arg_directory, console) < 0)
-                                goto child_fail;
+                                _exit(EXIT_FAILURE);
 
                         if (setup_kmsg(arg_directory, kmsg_socket_pair[1]) < 0)
-                                goto child_fail;
+                                _exit(EXIT_FAILURE);
 
-                        close_nointr_nofail(kmsg_socket_pair[1]);
-                        kmsg_socket_pair[1] = -1;
+                        kmsg_socket_pair[1] = safe_close(kmsg_socket_pair[1]);
 
                         if (setup_boot_id(arg_directory) < 0)
-                                goto child_fail;
+                                _exit(EXIT_FAILURE);
 
                         if (setup_timezone(arg_directory) < 0)
-                                goto child_fail;
+                                _exit(EXIT_FAILURE);
 
                         if (setup_resolv_conf(arg_directory) < 0)
-                                goto child_fail;
+                                _exit(EXIT_FAILURE);
 
                         if (setup_journal(arg_directory) < 0)
-                                goto child_fail;
+                                _exit(EXIT_FAILURE);
 
-                        if (mount_binds(arg_directory, arg_bind, 0) < 0)
-                                goto child_fail;
+                        if (mount_binds(arg_directory, arg_bind, false) < 0)
+                                _exit(EXIT_FAILURE);
 
-                        if (mount_binds(arg_directory, arg_bind_ro, MS_RDONLY) < 0)
-                                goto child_fail;
+                        if (mount_binds(arg_directory, arg_bind_ro, true) < 0)
+                                _exit(EXIT_FAILURE);
+
+                        if (mount_tmpfs(arg_directory) < 0)
+                                _exit(EXIT_FAILURE);
 
                         if (setup_kdbus(arg_directory, kdbus_domain) < 0)
-                                goto child_fail;
+                                _exit(EXIT_FAILURE);
+
+                        /* Tell the parent that we are ready, and that
+                         * it can cgroupify us to that we lack access
+                         * to certain devices and resources. */
+                        barrier_place(&barrier);
 
                         if (chdir(arg_directory) < 0) {
                                 log_error("chdir(%s) failed: %m", arg_directory);
-                                goto child_fail;
+                                _exit(EXIT_FAILURE);
                         }
 
                         if (mount(arg_directory, "/", NULL, MS_MOVE, NULL) < 0) {
                                 log_error("mount(MS_MOVE) failed: %m");
-                                goto child_fail;
+                                _exit(EXIT_FAILURE);
                         }
 
                         if (chroot(".") < 0) {
                                 log_error("chroot() failed: %m");
-                                goto child_fail;
+                                _exit(EXIT_FAILURE);
                         }
 
                         if (chdir("/") < 0) {
                                 log_error("chdir() failed: %m");
-                                goto child_fail;
+                                _exit(EXIT_FAILURE);
                         }
 
                         umask(0022);
@@ -1979,76 +3305,26 @@ int main(int argc, char *argv[]) {
 
                         if (drop_capabilities() < 0) {
                                 log_error("drop_capabilities() failed: %m");
-                                goto child_fail;
+                                _exit(EXIT_FAILURE);
                         }
 
-                        if (arg_user) {
-
-                                /* Note that this resolves user names
-                                 * inside the container, and hence
-                                 * accesses the NSS modules from the
-                                 * container and not the host. This is
-                                 * a bit weird... */
-
-                                if (get_user_creds((const char**)&arg_user, &uid, &gid, &home, NULL) < 0) {
-                                        log_error("get_user_creds() failed: %m");
-                                        goto child_fail;
-                                }
-
-                                if (mkdir_parents_label(home, 0775) < 0) {
-                                        log_error("mkdir_parents_label() failed: %m");
-                                        goto child_fail;
-                                }
-
-                                if (mkdir_safe_label(home, 0775, uid, gid) < 0) {
-                                        log_error("mkdir_safe_label() failed: %m");
-                                        goto child_fail;
-                                }
-
-                                if (initgroups((const char*)arg_user, gid) < 0) {
-                                        log_error("initgroups() failed: %m");
-                                        goto child_fail;
-                                }
-
-                                if (setresgid(gid, gid, gid) < 0) {
-                                        log_error("setregid() failed: %m");
-                                        goto child_fail;
-                                }
-
-                                if (setresuid(uid, uid, uid) < 0) {
-                                        log_error("setreuid() failed: %m");
-                                        goto child_fail;
-                                }
-                        } else {
-                                /* Reset everything fully to 0, just in case */
-
-                                if (setgroups(0, NULL) < 0) {
-                                        log_error("setgroups() failed: %m");
-                                        goto child_fail;
-                                }
-
-                                if (setresgid(0, 0, 0) < 0) {
-                                        log_error("setregid() failed: %m");
-                                        goto child_fail;
-                                }
-
-                                if (setresuid(0, 0, 0) < 0) {
-                                        log_error("setreuid() failed: %m");
-                                        goto child_fail;
-                                }
-                        }
+                        r = change_uid_gid(&home);
+                        if (r < 0)
+                                _exit(EXIT_FAILURE);
 
                         if ((asprintf((char**)(envp + n_env++), "HOME=%s", home ? home: "/root") < 0) ||
                             (asprintf((char**)(envp + n_env++), "USER=%s", arg_user ? arg_user : "root") < 0) ||
                             (asprintf((char**)(envp + n_env++), "LOGNAME=%s", arg_user ? arg_user : "root") < 0)) {
                                 log_oom();
-                                goto child_fail;
+                                _exit(EXIT_FAILURE);
                         }
 
                         if (!sd_id128_equal(arg_uuid, SD_ID128_NULL)) {
-                                if (asprintf((char**)(envp + n_env++), "container_uuid=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(arg_uuid)) < 0) {
+                                char as_uuid[37];
+
+                                if (asprintf((char**)(envp + n_env++), "container_uuid=%s", id128_format_as_uuid(arg_uuid, as_uuid)) < 0) {
                                         log_oom();
-                                        goto child_fail;
+                                        _exit(EXIT_FAILURE);
                                 }
                         }
 
@@ -2056,13 +3332,13 @@ int main(int argc, char *argv[]) {
                                 k = fdset_cloexec(fds, false);
                                 if (k < 0) {
                                         log_error("Failed to unset O_CLOEXEC for file descriptors.");
-                                        goto child_fail;
+                                        _exit(EXIT_FAILURE);
                                 }
 
                                 if ((asprintf((char **)(envp + n_env++), "LISTEN_FDS=%u", n_fd_passed) < 0) ||
                                     (asprintf((char **)(envp + n_env++), "LISTEN_PID=1") < 0)) {
                                         log_oom();
-                                        goto child_fail;
+                                        _exit(EXIT_FAILURE);
                                 }
                         }
 
@@ -2071,13 +3347,22 @@ int main(int argc, char *argv[]) {
                         if (arg_personality != 0xffffffffLU) {
                                 if (personality(arg_personality) < 0) {
                                         log_error("personality() failed: %m");
-                                        goto child_fail;
+                                        _exit(EXIT_FAILURE);
+                                }
+                        } else if (secondary) {
+                                if (personality(PER_LINUX32) < 0) {
+                                        log_error("personality() failed: %m");
+                                        _exit(EXIT_FAILURE);
                                 }
                         }
 
-                        eventfd_read(sync_fd, &x);
-                        close_nointr_nofail(sync_fd);
-                        sync_fd = -1;
+#ifdef HAVE_SELINUX
+                        if (arg_selinux_context)
+                                if (setexeccon((security_context_t) arg_selinux_context) < 0) {
+                                        log_error("setexeccon(\"%s\") failed: %m", arg_selinux_context);
+                                        _exit(EXIT_FAILURE);
+                                }
+#endif
 
                         if (!strv_isempty(arg_setenv)) {
                                 char **n;
@@ -2085,18 +3370,17 @@ int main(int argc, char *argv[]) {
                                 n = strv_env_merge(2, envp, arg_setenv);
                                 if (!n) {
                                         log_oom();
-                                        goto child_fail;
+                                        _exit(EXIT_FAILURE);
                                 }
 
                                 env_use = n;
                         } else
                                 env_use = (char**) envp;
 
-#ifdef HAVE_SELINUX
-                        if (arg_selinux_context)
-                                if (setexeccon(arg_selinux_context) < 0)
-                                        log_error("setexeccon(\"%s\") failed: %m", arg_selinux_context);
-#endif
+                        /* Wait until the parent is ready with the setup, too... */
+                        if (!barrier_place_and_sync(&barrier))
+                                _exit(EXIT_FAILURE);
+
                         if (arg_boot) {
                                 char **a;
                                 size_t l;
@@ -2124,101 +3408,116 @@ int main(int argc, char *argv[]) {
                         }
 
                         log_error("execv() failed: %m");
-
-                child_fail:
                         _exit(EXIT_FAILURE);
                 }
 
+                barrier_set_role(&barrier, BARRIER_PARENT);
                 fdset_free(fds);
                 fds = NULL;
 
-                r = register_machine(pid);
-                if (r < 0)
-                        goto finish;
-
-                r = move_network_interfaces(pid);
-                if (r < 0)
-                        goto finish;
-
-                r = setup_veth(pid, veth_name);
-                if (r < 0)
-                        goto finish;
+                /* wait for child-setup to be done */
+                if (barrier_place_and_sync(&barrier)) {
+                        int ifi = 0;
 
-                r = setup_bridge(veth_name);
-                if (r < 0)
-                        goto finish;
+                        r = move_network_interfaces(pid);
+                        if (r < 0)
+                                goto finish;
 
-                eventfd_write(sync_fd, 1);
-                close_nointr_nofail(sync_fd);
-                sync_fd = -1;
+                        r = setup_veth(pid, veth_name, &ifi);
+                        if (r < 0)
+                                goto finish;
 
-                k = process_pty(master, &mask, arg_boot ? pid : 0, SIGRTMIN+3);
-                if (k < 0) {
-                        r = EXIT_FAILURE;
-                        break;
-                }
+                        r = setup_bridge(veth_name, &ifi);
+                        if (r < 0)
+                                goto finish;
 
-                if (!arg_quiet)
-                        putc('\n', stdout);
+                        r = setup_macvlan(pid);
+                        if (r < 0)
+                                goto finish;
 
-                /* Kill if it is not dead yet anyway */
-                terminate_machine(pid);
+                        r = register_machine(pid, ifi);
+                        if (r < 0)
+                                goto finish;
 
-                /* Redundant, but better safe than sorry */
-                kill(pid, SIGKILL);
+                        /* Block SIGCHLD here, before notifying child.
+                         * process_pty() will handle it with the other signals. */
+                        r = sigprocmask(SIG_BLOCK, &mask_chld, NULL);
+                        if (r < 0)
+                                goto finish;
 
-                k = wait_for_terminate(pid, &status);
-                pid = 0;
+                        /* Reset signal to default */
+                        r = default_signals(SIGCHLD, -1);
+                        if (r < 0)
+                                goto finish;
 
-                if (k < 0) {
-                        r = EXIT_FAILURE;
-                        break;
-                }
+                        /* Notify the child that the parent is ready with all
+                         * its setup, and that the child can now hand over
+                         * control to the code to run inside the container. */
+                        barrier_place(&barrier);
 
-                if (status.si_code == CLD_EXITED) {
-                        r = status.si_status;
-                        if (status.si_status != 0) {
-                                log_error("Container %s failed with error code %i.", arg_machine, status.si_status);
+                        k = process_pty(master, &mask, arg_boot ? pid : 0, SIGRTMIN+3);
+                        if (k < 0) {
+                                r = EXIT_FAILURE;
                                 break;
                         }
 
                         if (!arg_quiet)
-                                log_debug("Container %s exited successfully.", arg_machine);
-                        break;
-                } else if (status.si_code == CLD_KILLED &&
-                           status.si_status == SIGINT) {
+                                putc('\n', stdout);
 
-                        if (!arg_quiet)
-                                log_info("Container %s has been shut down.", arg_machine);
-                        r = 0;
-                        break;
-                } else if (status.si_code == CLD_KILLED &&
-                           status.si_status == SIGHUP) {
+                        /* Kill if it is not dead yet anyway */
+                        terminate_machine(pid);
+                }
 
-                        if (!arg_quiet)
-                                log_info("Container %s is being rebooted.", arg_machine);
-                        continue;
-                } else if (status.si_code == CLD_KILLED ||
-                           status.si_code == CLD_DUMPED) {
+                /* Normally redundant, but better safe than sorry */
+                kill(pid, SIGKILL);
 
-                        log_error("Container %s terminated by signal %s.", arg_machine, signal_to_string(status.si_status));
+                r = wait_for_container(pid, &container_status);
+                pid = 0;
+
+                if (r < 0) {
+                        /* We failed to wait for the container, or the
+                         * container exited abnormally */
                         r = EXIT_FAILURE;
                         break;
-                } else {
-                        log_error("Container %s failed due to unknown reason.", arg_machine);
-                        r = EXIT_FAILURE;
+                } else if (r > 0 || container_status == CONTAINER_TERMINATED)
+                        /* The container exited with a non-zero
+                         * status, or with zero status and no reboot
+                         * was requested. */
+                        break;
+
+                /* CONTAINER_REBOOTED, loop again */
+
+                if (arg_keep_unit) {
+                        /* Special handling if we are running as a
+                         * service: instead of simply restarting the
+                         * machine we want to restart the entire
+                         * service, so let's inform systemd about this
+                         * with the special exit code 133. The service
+                         * file uses RestartForceExitStatus=133 so
+                         * that this results in a full nspawn
+                         * restart. This is necessary since we might
+                         * have cgroup parameters set we want to have
+                         * flushed out. */
+                        r = 133;
                         break;
                 }
         }
 
 finish:
+        loop_remove(loop_nr, &image_fd);
+
         if (pid > 0)
                 kill(pid, SIGKILL);
 
         free(arg_directory);
         free(arg_machine);
-        free(arg_setenv);
-        free(arg_network_interfaces);
+        free(arg_user);
+        strv_free(arg_setenv);
+        strv_free(arg_network_interfaces);
+        strv_free(arg_network_macvlan);
+        strv_free(arg_bind);
+        strv_free(arg_bind_ro);
+        strv_free(arg_tmpfs);
 
         return r;
 }
diff --git a/src/nss-myhostname/ifconf.h b/src/nss-myhostname/ifconf.h
deleted file mode 100644 (file)
index cd598d2..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#pragma once
-
-/***
-  This file is part of systemd.
-
-  Copyright 2008-2011 Lennart Poettering
-
-  systemd is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation; either version 2.1 of the License, or
-  (at your option) any later version.
-
-  systemd is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <inttypes.h>
-#include <sys/types.h>
-#include <assert.h>
-#include <sys/socket.h>
-
-struct address {
-        unsigned char family;
-        uint8_t address[16];
-        unsigned char scope;
-        int ifindex;
-};
-
-#define _public_ __attribute__ ((visibility("default")))
-#define _hidden_ __attribute__ ((visibility("hidden")))
-
-int ifconf_acquire_addresses(struct address **_list, unsigned *_n_list) _hidden_;
-
-static inline size_t PROTO_ADDRESS_SIZE(int proto) {
-        assert(proto == AF_INET || proto == AF_INET6);
-
-        return proto == AF_INET6 ? 16 : 4;
-}
-
-static inline int address_compare(const void *_a, const void *_b) {
-        const struct address *a = _a, *b = _b;
-
-        /* Order lowest scope first, IPv4 before IPv6, lowest interface index first */
-
-        if (a->scope < b->scope)
-                return -1;
-        if (a->scope > b->scope)
-                return 1;
-
-        if (a->family == AF_INET && b->family == AF_INET6)
-                return -1;
-        if (a->family == AF_INET6 && b->family == AF_INET)
-                return 1;
-
-        if (a->ifindex < b->ifindex)
-                return -1;
-        if (a->ifindex > b->ifindex)
-                return 1;
-
-        return 0;
-}
diff --git a/src/nss-myhostname/netlink.c b/src/nss-myhostname/netlink.c
deleted file mode 100644 (file)
index d61ecdf..0000000
+++ /dev/null
@@ -1,206 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
-  This file is part of systemd.
-
-  Copyright 2008-2011 Lennart Poettering
-
-  systemd is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation; either version 2.1 of the License, or
-  (at your option) any later version.
-
-  systemd is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <asm/types.h>
-#include <inttypes.h>
-#include <linux/netlink.h>
-#include <linux/rtnetlink.h>
-#include <string.h>
-#include <assert.h>
-#include <errno.h>
-#include <limits.h>
-#include <arpa/inet.h>
-#include <unistd.h>
-#include <stdlib.h>
-
-#include "ifconf.h"
-
-#define SEQ 4711
-
-static int read_reply(int fd, struct address **list, unsigned *n_list) {
-        ssize_t bytes;
-        struct cmsghdr *cmsg;
-        struct ucred *ucred;
-        struct nlmsghdr *p;
-        uint8_t cred_buffer[CMSG_SPACE(sizeof(struct ucred))];
-        struct {
-                struct nlmsghdr hdr;
-                struct ifaddrmsg ifaddrmsg;
-                uint8_t payload[16*1024];
-        } resp;
-        struct iovec iov = {
-                .iov_base = &resp,
-                .iov_len = sizeof(resp),
-        };
-        struct msghdr msg = {
-                .msg_name = NULL,
-                .msg_namelen = 0,
-                .msg_iov = &iov,
-                .msg_iovlen = 1,
-                .msg_control = cred_buffer,
-                .msg_controllen = sizeof(cred_buffer),
-                .msg_flags = 0,
-        };
-
-        assert(fd >= 0);
-        assert(list);
-
-        bytes = recvmsg(fd, &msg, 0);
-        if (bytes < 0)
-                return -errno;
-
-        cmsg = CMSG_FIRSTHDR(&msg);
-        if (!cmsg || cmsg->cmsg_type != SCM_CREDENTIALS)
-                return -EIO;
-
-        ucred = (struct ucred*) CMSG_DATA(cmsg);
-        if (ucred->uid != 0 || ucred->pid != 0)
-                return 0;
-
-        for (p = &resp.hdr; bytes > 0; p = NLMSG_NEXT(p, bytes)) {
-                struct ifaddrmsg *ifaddrmsg;
-                struct rtattr *a;
-                size_t l;
-                void *local = NULL, *address = NULL;
-
-                if (!NLMSG_OK(p, (size_t) bytes))
-                        return -EIO;
-
-                if (p->nlmsg_seq != SEQ)
-                        continue;
-
-                if (p->nlmsg_type == NLMSG_DONE)
-                        return 1;
-
-                if (p->nlmsg_type == NLMSG_ERROR) {
-                        struct nlmsgerr *nlmsgerr;
-
-                        nlmsgerr = NLMSG_DATA(p);
-                        return -nlmsgerr->error;
-                }
-
-                if (p->nlmsg_type != RTM_NEWADDR)
-                        continue;
-
-                ifaddrmsg = NLMSG_DATA(p);
-
-                if (ifaddrmsg->ifa_family != AF_INET &&
-                    ifaddrmsg->ifa_family != AF_INET6)
-                        continue;
-
-                if (ifaddrmsg->ifa_scope == RT_SCOPE_HOST ||
-                    ifaddrmsg->ifa_scope == RT_SCOPE_NOWHERE)
-                        continue;
-
-                if (ifaddrmsg->ifa_flags & IFA_F_DEPRECATED)
-                        continue;
-
-                l = NLMSG_PAYLOAD(p, sizeof(struct ifaddrmsg));
-                a = IFA_RTA(ifaddrmsg);
-
-                while (RTA_OK(a, l)) {
-
-                        if (a->rta_type == IFA_ADDRESS)
-                                address = RTA_DATA(a);
-                        else if (a->rta_type == IFA_LOCAL)
-                                local = RTA_DATA(a);
-
-                        a = RTA_NEXT(a, l);
-                }
-
-                if (local)
-                        address = local;
-
-                if (!address)
-                        continue;
-
-                *list = realloc(*list, (*n_list+1) * sizeof(struct address));
-                if (!*list)
-                        return -ENOMEM;
-
-                (*list)[*n_list].family = ifaddrmsg->ifa_family;
-                (*list)[*n_list].scope = ifaddrmsg->ifa_scope;
-                memcpy((*list)[*n_list].address,
-                       address, ifaddrmsg->ifa_family == AF_INET ? 4 : 16);
-                (*list)[*n_list].ifindex = ifaddrmsg->ifa_index;
-
-                (*n_list)++;
-        }
-
-        return 0;
-}
-
-
-int ifconf_acquire_addresses(struct address **_list, unsigned *_n_list) {
-
-        struct {
-                struct nlmsghdr hdr;
-                struct rtgenmsg gen;
-        } req = { {
-                        .nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg)),
-                        .nlmsg_type = RTM_GETADDR,
-                        .nlmsg_flags = NLM_F_REQUEST|NLM_F_DUMP|NLM_F_ACK,
-                        .nlmsg_seq = SEQ,
-                        .nlmsg_pid = 0,
-                }, {
-                        .rtgen_family = AF_UNSPEC,
-                }
-        };
-        int r, on = 1;
-        struct address *list = NULL;
-        unsigned n_list = 0;
-        int fd;
-
-        fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
-        if (fd < 0)
-                return -errno;
-
-        if (setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)) < 0) {
-                r = -errno;
-                goto finish;
-        }
-
-        if (send(fd, &req, req.hdr.nlmsg_len, 0) < 0) {
-                r = -errno;
-                goto finish;
-        }
-
-        while((r = read_reply(fd, &list, &n_list)) == 0)
-                ;
-
-finish:
-        close(fd);
-
-        if (r < 0) {
-                free(list);
-                return r;
-        }
-
-        if (n_list)
-                qsort(list, n_list, sizeof(struct address), address_compare);
-
-        *_list = list;
-        *_n_list = n_list;
-
-        return 0;
-}
index 60e256d..86e7be2 100644 (file)
 #include <stdlib.h>
 #include <arpa/inet.h>
 
-#include "ifconf.h"
+#include "local-addresses.h"
 #include "macro.h"
-
-/* Ensure that glibc's assert is used. We cannot use assert from macro.h, as
- * libnss_myhostname will be linked into arbitrary programs which will, in turn
- * attempt to write to the journal via log_dispatch() */
-#include <assert.h>
+#include "nss-util.h"
+#include "util.h"
 
 /* We use 127.0.0.2 as IPv4 address. This has the advantage over
  * 127.0.0.1 that it can be translated back to the local hostname. For
 #define LOCALADDRESS_IPV6 &in6addr_loopback
 #define LOOPBACK_INTERFACE "lo"
 
-enum nss_status _nss_myhostname_gethostbyname4_r(
-                const char *name,
-                struct gaih_addrtuple **pat,
-                char *buffer, size_t buflen,
-                int *errnop, int *h_errnop,
-                int32_t *ttlp) _public_;
-
-enum nss_status _nss_myhostname_gethostbyname3_r(
-                const char *name,
-                int af,
-                struct hostent *host,
-                char *buffer, size_t buflen,
-                int *errnop, int *h_errnop,
-                int32_t *ttlp,
-                char **canonp) _public_;
-
-enum nss_status _nss_myhostname_gethostbyname2_r(
-                const char *name,
-                int af,
-                struct hostent *host,
-                char *buffer, size_t buflen,
-                int *errnop, int *h_errnop) _public_;
-
-enum nss_status _nss_myhostname_gethostbyname_r(
-                const char *name,
-                struct hostent *host,
-                char *buffer, size_t buflen,
-                int *errnop, int *h_errnop) _public_;
-
-enum nss_status _nss_myhostname_gethostbyaddr2_r(
-                const void* addr, socklen_t len,
-                int af,
-                struct hostent *host,
-                char *buffer, size_t buflen,
-                int *errnop, int *h_errnop,
-                int32_t *ttlp) _public_;
-
-enum nss_status _nss_myhostname_gethostbyaddr_r(
-                const void* addr, socklen_t len,
-                int af,
-                struct hostent *host,
-                char *buffer, size_t buflen,
-                int *errnop, int *h_errnop) _public_;
+NSS_GETHOSTBYNAME_PROTOTYPES(myhostname);
+NSS_GETHOSTBYADDR_PROTOTYPES(myhostname);
 
 enum nss_status _nss_myhostname_gethostbyname4_r(
                 const char *name,
@@ -98,39 +54,47 @@ enum nss_status _nss_myhostname_gethostbyname4_r(
                 int *errnop, int *h_errnop,
                 int32_t *ttlp) {
 
-        unsigned lo_ifi;
-        char hn[HOST_NAME_MAX+1] = {};
+        struct gaih_addrtuple *r_tuple, *r_tuple_prev = NULL;
+        _cleanup_free_ struct local_address *addresses = NULL;
+        _cleanup_free_ char *hn = NULL;
         const char *canonical = NULL;
+        int n_addresses = 0, lo_ifi;
+        uint32_t local_address_ipv4;
+        struct local_address *a;
         size_t l, idx, ms;
         char *r_name;
-        struct gaih_addrtuple *r_tuple, *r_tuple_prev = NULL;
-        struct address *addresses = NULL, *a;
-        unsigned n_addresses = 0, n;
-        uint32_t local_address_ipv4;
+        unsigned n;
+
+        assert(name);
+        assert(pat);
+        assert(buffer);
+        assert(errnop);
+        assert(h_errnop);
 
-        if (strcasecmp(name, "localhost") == 0) {
+        if (is_localhost(name)) {
                 /* We respond to 'localhost', so that /etc/hosts
                  * is optional */
 
                 canonical = "localhost";
                 local_address_ipv4 = htonl(INADDR_LOOPBACK);
         } else {
-                /* We respond to our local host name */
-
-                if (gethostname(hn, sizeof(hn)-1) < 0) {
-                        *errnop = errno;
+                hn = gethostname_malloc();
+                if (!hn) {
+                        *errnop = ENOMEM;
                         *h_errnop = NO_RECOVERY;
-                        return NSS_STATUS_UNAVAIL;
+                        return NSS_STATUS_TRYAGAIN;
                 }
 
-                if (strcasecmp(name, hn) != 0) {
+                /* We respond to our local host name, our our hostname suffixed with a single dot. */
+                if (!streq(name, hn) && !streq_ptr(startswith(name, hn), ".")) {
                         *errnop = ENOENT;
                         *h_errnop = HOST_NOT_FOUND;
                         return NSS_STATUS_NOTFOUND;
                 }
 
-                /* If this fails, n_addresses is 0. Which is fine */
-                ifconf_acquire_addresses(&addresses, &n_addresses);
+                n_addresses = local_addresses(NULL, 0, &addresses);
+                if (n_addresses < 0)
+                        n_addresses = 0;
 
                 canonical = hn;
                 local_address_ipv4 = LOCALADDRESS_IPV4;
@@ -140,11 +104,10 @@ enum nss_status _nss_myhostname_gethostbyname4_r(
         lo_ifi = n_addresses <= 0 ? if_nametoindex(LOOPBACK_INTERFACE) : 0;
 
         l = strlen(canonical);
-        ms = ALIGN(l+1)+ALIGN(sizeof(struct gaih_addrtuple))*(n_addresses > 0 ? n_addresses : 2);
+        ms = ALIGN(l+1) + ALIGN(sizeof(struct gaih_addrtuple)) * (n_addresses > 0 ? n_addresses : 2);
         if (buflen < ms) {
                 *errnop = ENOMEM;
                 *h_errnop = NO_RECOVERY;
-                free(addresses);
                 return NSS_STATUS_TRYAGAIN;
         }
 
@@ -178,13 +141,13 @@ enum nss_status _nss_myhostname_gethostbyname4_r(
         }
 
         /* Fourth, fill actual addresses in, but in backwards order */
-        for (a = addresses + n_addresses - 1, n = 0; n < n_addresses; n++, a--) {
+        for (a = addresses + n_addresses - 1, n = 0; (int) n < n_addresses; n++, a--) {
                 r_tuple = (struct gaih_addrtuple*) (buffer + idx);
                 r_tuple->next = r_tuple_prev;
                 r_tuple->name = r_name;
                 r_tuple->family = a->family;
                 r_tuple->scopeid = a->ifindex;
-                memcpy(r_tuple->addr, a->address, 16);
+                memcpy(r_tuple->addr, &a->address, 16);
 
                 idx += ALIGN(sizeof(struct gaih_addrtuple));
                 r_tuple_prev = r_tuple;
@@ -202,7 +165,10 @@ enum nss_status _nss_myhostname_gethostbyname4_r(
         if (ttlp)
                 *ttlp = 0;
 
-        free(addresses);
+        /* Explicitly reset all error variables */
+        *errnop = 0;
+        *h_errnop = NETDB_SUCCESS;
+        h_errno = 0;
 
         return NSS_STATUS_SUCCESS;
 }
@@ -210,7 +176,7 @@ enum nss_status _nss_myhostname_gethostbyname4_r(
 static enum nss_status fill_in_hostent(
                 const char *canonical, const char *additional,
                 int af,
-                struct address *addresses, unsigned n_addresses,
+                struct local_address *addresses, unsigned n_addresses,
                 uint32_t local_address_ipv4,
                 struct hostent *result,
                 char *buffer, size_t buflen,
@@ -218,13 +184,18 @@ static enum nss_status fill_in_hostent(
                 int32_t *ttlp,
                 char **canonp) {
 
-        size_t l_canonical, l_additional, idx, ms;
+        size_t l_canonical, l_additional, idx, ms, alen;
         char *r_addr, *r_name, *r_aliases, *r_alias = NULL, *r_addr_list;
-        size_t alen;
-        struct address *a;
+        struct local_address *a;
         unsigned n, c;
 
-        alen = PROTO_ADDRESS_SIZE(af);
+        assert(canonical);
+        assert(result);
+        assert(buffer);
+        assert(errnop);
+        assert(h_errnop);
+
+        alen = FAMILY_ADDRESS_SIZE(af);
 
         for (a = addresses, n = 0, c = 0; n < n_addresses; a++, n++)
                 if (af == a->family)
@@ -234,15 +205,14 @@ static enum nss_status fill_in_hostent(
         l_additional = additional ? strlen(additional) : 0;
         ms = ALIGN(l_canonical+1)+
                 (additional ? ALIGN(l_additional+1) : 0) +
-                sizeof(char*)+
+                sizeof(char*) +
                 (additional ? sizeof(char*) : 0) +
-                (c > 0 ? c : 1)*ALIGN(alen)+
-                (c > 0 ? c+1 : 2)*sizeof(char*);
+                (c > 0 ? c : 1) * ALIGN(alen) +
+                (c > 0 ? c+1 : 2) * sizeof(char*);
 
         if (buflen < ms) {
                 *errnop = ENOMEM;
                 *h_errnop = NO_RECOVERY;
-                free(addresses);
                 return NSS_STATUS_TRYAGAIN;
         }
 
@@ -277,7 +247,7 @@ static enum nss_status fill_in_hostent(
                         if (af != a->family)
                                 continue;
 
-                        memcpy(r_addr + i*ALIGN(alen), a->address, alen);
+                        memcpy(r_addr + i*ALIGN(alen), &a->address, alen);
                         i++;
                 }
 
@@ -295,24 +265,18 @@ static enum nss_status fill_in_hostent(
         /* Fourth, add address pointer array */
         r_addr_list = buffer + idx;
         if (c > 0) {
-                unsigned i = 0;
-
-                for (a = addresses, n = 0; n < n_addresses; a++, n++) {
-                        if (af != a->family)
-                                continue;
+                unsigned i;
 
-                        ((char**) r_addr_list)[i] = (r_addr + i*ALIGN(alen));
-                        i++;
-                }
+                for (i = 0; i < c; i++)
+                        ((char**) r_addr_list)[i] = r_addr + i*ALIGN(alen);
 
-                assert(i == c);
-                ((char**) r_addr_list)[c] = NULL;
-                idx += (c+1)*sizeof(char*);
+                ((char**) r_addr_list)[i] = NULL;
+                idx += (c+1) * sizeof(char*);
 
         } else {
                 ((char**) r_addr_list)[0] = r_addr;
                 ((char**) r_addr_list)[1] = NULL;
-                idx += 2*sizeof(char*);
+                idx += 2 * sizeof(char*);
         }
 
         /* Verify the size matches */
@@ -330,7 +294,10 @@ static enum nss_status fill_in_hostent(
         if (canonp)
                 *canonp = r_name;
 
-        free(addresses);
+        /* Explicitly reset all error variables */
+        *errnop = 0;
+        *h_errnop = NETDB_SUCCESS;
+        h_errno = 0;
 
         return NSS_STATUS_SUCCESS;
 }
@@ -344,11 +311,17 @@ enum nss_status _nss_myhostname_gethostbyname3_r(
                 int32_t *ttlp,
                 char **canonp) {
 
-        char hn[HOST_NAME_MAX+1] = {};
-        struct address *addresses = NULL;
-        unsigned n_addresses = 0;
+        _cleanup_free_ struct local_address *addresses = NULL;
         const char *canonical, *additional = NULL;
+        _cleanup_free_ char *hn = NULL;
         uint32_t local_address_ipv4;
+        int n_addresses = 0;
+
+        assert(name);
+        assert(host);
+        assert(buffer);
+        assert(errnop);
+        assert(h_errnop);
 
         if (af == AF_UNSPEC)
                 af = AF_INET;
@@ -359,23 +332,26 @@ enum nss_status _nss_myhostname_gethostbyname3_r(
                 return NSS_STATUS_UNAVAIL;
         }
 
-        if (strcasecmp(name, "localhost") == 0) {
+        if (is_localhost(name)) {
                 canonical = "localhost";
                 local_address_ipv4 = htonl(INADDR_LOOPBACK);
         } else {
-                if (gethostname(hn, sizeof(hn)-1) < 0) {
-                        *errnop = errno;
+                hn = gethostname_malloc();
+                if (!hn) {
+                        *errnop = ENOMEM;
                         *h_errnop = NO_RECOVERY;
-                        return NSS_STATUS_UNAVAIL;
+                        return NSS_STATUS_TRYAGAIN;
                 }
 
-                if (strcasecmp(name, hn) != 0) {
+                if (!streq(name, hn) && !streq_ptr(startswith(name, hn), ".")) {
                         *errnop = ENOENT;
                         *h_errnop = HOST_NOT_FOUND;
                         return NSS_STATUS_NOTFOUND;
                 }
 
-                ifconf_acquire_addresses(&addresses, &n_addresses);
+                n_addresses = local_addresses(NULL, 0, &addresses);
+                if (n_addresses < 0)
+                        n_addresses = 0;
 
                 canonical = hn;
                 additional = n_addresses <= 0 && af == AF_INET6 ? "localhost" : NULL;
@@ -394,39 +370,6 @@ enum nss_status _nss_myhostname_gethostbyname3_r(
                         canonp);
 }
 
-enum nss_status _nss_myhostname_gethostbyname2_r(
-                const char *name,
-                int af,
-                struct hostent *host,
-                char *buffer, size_t buflen,
-                int *errnop, int *h_errnop) {
-
-        return _nss_myhostname_gethostbyname3_r(
-                        name,
-                        af,
-                        host,
-                        buffer, buflen,
-                        errnop, h_errnop,
-                        NULL,
-                        NULL);
-}
-
-enum nss_status _nss_myhostname_gethostbyname_r(
-                const char *name,
-                struct hostent *host,
-                char *buffer, size_t buflen,
-                int *errnop, int *h_errnop) {
-
-        return _nss_myhostname_gethostbyname3_r(
-                        name,
-                        AF_UNSPEC,
-                        host,
-                        buffer, buflen,
-                        errnop, h_errnop,
-                        NULL,
-                        NULL);
-}
-
 enum nss_status _nss_myhostname_gethostbyaddr2_r(
                 const void* addr, socklen_t len,
                 int af,
@@ -435,14 +378,27 @@ enum nss_status _nss_myhostname_gethostbyaddr2_r(
                 int *errnop, int *h_errnop,
                 int32_t *ttlp) {
 
-        char hn[HOST_NAME_MAX+1] = {};
-        struct address *addresses = NULL;
-        struct address *a;
-        unsigned n_addresses = 0, n;
-        uint32_t local_address_ipv4 = LOCALADDRESS_IPV4;
         const char *canonical = NULL, *additional = NULL;
+        uint32_t local_address_ipv4 = LOCALADDRESS_IPV4;
+        _cleanup_free_ struct local_address *addresses = NULL;
+        _cleanup_free_ char *hn = NULL;
+        int n_addresses = 0;
+        struct local_address *a;
+        unsigned n;
+
+        assert(addr);
+        assert(host);
+        assert(buffer);
+        assert(errnop);
+        assert(h_errnop);
+
+        if (!IN_SET(af, AF_INET, AF_INET6)) {
+                *errnop = EAFNOSUPPORT;
+                *h_errnop = NO_DATA;
+                return NSS_STATUS_UNAVAIL;
+        }
 
-        if (len != PROTO_ADDRESS_SIZE(af)) {
+        if (len != FAMILY_ADDRESS_SIZE(af)) {
                 *errnop = EINVAL;
                 *h_errnop = NO_RECOVERY;
                 return NSS_STATUS_UNAVAIL;
@@ -459,45 +415,40 @@ enum nss_status _nss_myhostname_gethostbyaddr2_r(
                         goto found;
                 }
 
-        } else if (af == AF_INET6) {
+        } else {
+                assert(af == AF_INET6);
 
                 if (memcmp(addr, LOCALADDRESS_IPV6, 16) == 0) {
                         additional = "localhost";
                         goto found;
                 }
 
-        } else {
-                *errnop = EAFNOSUPPORT;
-                *h_errnop = NO_DATA;
-                return NSS_STATUS_UNAVAIL;
         }
 
-        ifconf_acquire_addresses(&addresses, &n_addresses);
+        n_addresses = local_addresses(NULL, 0, &addresses);
+        if (n_addresses < 0)
+                n_addresses = 0;
 
-        for (a = addresses, n = 0; n < n_addresses; n++, a++) {
+        for (a = addresses, n = 0; (int) n < n_addresses; n++, a++) {
                 if (af != a->family)
                         continue;
 
-                if (memcmp(addr, a->address, PROTO_ADDRESS_SIZE(af)) == 0)
+                if (memcmp(addr, &a->address, FAMILY_ADDRESS_SIZE(af)) == 0)
                         goto found;
         }
 
         *errnop = ENOENT;
         *h_errnop = HOST_NOT_FOUND;
 
-        free(addresses);
-
         return NSS_STATUS_NOTFOUND;
 
 found:
         if (!canonical) {
-                if (gethostname(hn, sizeof(hn)-1) < 0) {
-                        *errnop = errno;
+                hn = gethostname_malloc();
+                if (!hn) {
+                        *errnop = ENOMEM;
                         *h_errnop = NO_RECOVERY;
-
-                        free(addresses);
-
-                        return NSS_STATUS_UNAVAIL;
+                        return NSS_STATUS_TRYAGAIN;
                 }
 
                 canonical = hn;
@@ -516,18 +467,5 @@ found:
 
 }
 
-enum nss_status _nss_myhostname_gethostbyaddr_r(
-                const void* addr, socklen_t len,
-                int af,
-                struct hostent *host,
-                char *buffer, size_t buflen,
-                int *errnop, int *h_errnop) {
-
-        return _nss_myhostname_gethostbyaddr2_r(
-                        addr, len,
-                        af,
-                        host,
-                        buffer, buflen,
-                        errnop, h_errnop,
-                        NULL);
-}
+NSS_GETHOSTBYNAME_FALLBACKS(myhostname);
+NSS_GETHOSTBYADDR_FALLBACKS(myhostname);
diff --git a/src/nss-myhostname/nss-myhostname.sym b/src/nss-myhostname/nss-myhostname.sym
new file mode 100644 (file)
index 0000000..78646c3
--- /dev/null
@@ -0,0 +1,19 @@
+/***
+  This file is part of systemd.
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+***/
+
+{
+global:
+        _nss_myhostname_gethostbyname_r;
+        _nss_myhostname_gethostbyname2_r;
+        _nss_myhostname_gethostbyname3_r;
+        _nss_myhostname_gethostbyname4_r;
+        _nss_myhostname_gethostbyaddr_r;
+        _nss_myhostname_gethostbyaddr2_r;
+local: *;
+};
diff --git a/src/nss-mymachines/Makefile b/src/nss-mymachines/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/nss-mymachines/nss-mymachines.c b/src/nss-mymachines/nss-mymachines.c
new file mode 100644 (file)
index 0000000..abeb825
--- /dev/null
@@ -0,0 +1,386 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <nss.h>
+#include <netdb.h>
+
+#include "sd-bus.h"
+#include "sd-login.h"
+#include "macro.h"
+#include "util.h"
+#include "nss-util.h"
+#include "bus-util.h"
+#include "in-addr-util.h"
+
+NSS_GETHOSTBYNAME_PROTOTYPES(mymachines);
+
+static int count_addresses(sd_bus_message *m, int af, unsigned *ret) {
+        unsigned c = 0;
+        int r;
+
+        assert(m);
+        assert(ret);
+
+        while ((r = sd_bus_message_enter_container(m, 'r', "iay")) > 0) {
+                int family;
+
+                r = sd_bus_message_read(m, "i", &family);
+                if (r < 0)
+                        return r;
+
+                r = sd_bus_message_skip(m, "ay");
+                if (r < 0)
+                        return r;
+
+                r = sd_bus_message_exit_container(m);
+                if (r < 0)
+                        return r;
+
+                if (af != AF_UNSPEC && family != af)
+                        continue;
+
+                c ++;
+        }
+        if (r < 0)
+                return r;
+
+        r = sd_bus_message_rewind(m, false);
+        if (r < 0)
+                return r;
+
+        *ret = c;
+        return 0;
+}
+
+enum nss_status _nss_mymachines_gethostbyname4_r(
+                const char *name,
+                struct gaih_addrtuple **pat,
+                char *buffer, size_t buflen,
+                int *errnop, int *h_errnop,
+                int32_t *ttlp) {
+
+        struct gaih_addrtuple *r_tuple, *r_tuple_first = NULL;
+        _cleanup_bus_message_unref_ sd_bus_message* reply = NULL;
+        _cleanup_bus_close_unref_ sd_bus *bus = NULL;
+        _cleanup_free_ int *ifindices = NULL;
+        _cleanup_free_ char *class = NULL;
+        size_t l, ms, idx;
+        unsigned i = 0, c = 0;
+        char *r_name;
+        int n_ifindices, r;
+
+        assert(name);
+        assert(pat);
+        assert(buffer);
+        assert(errnop);
+        assert(h_errnop);
+
+        r = sd_machine_get_class(name, &class);
+        if (r < 0)
+                goto fail;
+        if (!streq(class, "container")) {
+                r = -ENOTTY;
+                goto fail;
+        }
+
+        n_ifindices = sd_machine_get_ifindices(name, &ifindices);
+        if (n_ifindices < 0) {
+                r = n_ifindices;
+                goto fail;
+        }
+
+        r = sd_bus_open_system(&bus);
+        if (r < 0)
+                goto fail;
+
+        r = sd_bus_call_method(bus,
+                               "org.freedesktop.machine1",
+                               "/org/freedesktop/machine1",
+                               "org.freedesktop.machine1.Manager",
+                               "GetMachineAddresses",
+                               NULL,
+                               &reply,
+                               "s", name);
+        if (r < 0)
+                goto fail;
+
+        r = sd_bus_message_enter_container(reply, 'a', "(iay)");
+        if (r < 0)
+                goto fail;
+
+        r = count_addresses(reply, AF_UNSPEC, &c);
+        if (r < 0)
+                goto fail;
+
+        if (c <= 0) {
+                *errnop = ESRCH;
+                *h_errnop = HOST_NOT_FOUND;
+                return NSS_STATUS_NOTFOUND;
+        }
+
+        l = strlen(name);
+        ms = ALIGN(l+1) + ALIGN(sizeof(struct gaih_addrtuple)) * c;
+        if (buflen < ms) {
+                *errnop = ENOMEM;
+                *h_errnop = TRY_AGAIN;
+                return NSS_STATUS_TRYAGAIN;
+        }
+
+        /* First, append name */
+        r_name = buffer;
+        memcpy(r_name, name, l+1);
+        idx = ALIGN(l+1);
+
+        /* Second, append addresses */
+        r_tuple_first = (struct gaih_addrtuple*) (buffer + idx);
+        while ((r = sd_bus_message_enter_container(reply, 'r', "iay")) > 0) {
+                int family;
+                const void *a;
+                size_t sz;
+
+                r = sd_bus_message_read(reply, "i", &family);
+                if (r < 0)
+                        goto fail;
+
+                r = sd_bus_message_read_array(reply, 'y', &a, &sz);
+                if (r < 0)
+                        goto fail;
+
+                r = sd_bus_message_exit_container(reply);
+                if (r < 0)
+                        goto fail;
+
+                if (!IN_SET(family, AF_INET, AF_INET6)) {
+                        r = -EAFNOSUPPORT;
+                        goto fail;
+                }
+
+                if (sz != FAMILY_ADDRESS_SIZE(family)) {
+                        r = -EINVAL;
+                        goto fail;
+                }
+
+                r_tuple = (struct gaih_addrtuple*) (buffer + idx);
+                r_tuple->next = i == c-1 ? NULL : (struct gaih_addrtuple*) ((char*) r_tuple + ALIGN(sizeof(struct gaih_addrtuple)));
+                r_tuple->name = r_name;
+                r_tuple->family = family;
+                r_tuple->scopeid = n_ifindices == 1 ? ifindices[0] : 0;
+                memcpy(r_tuple->addr, a, sz);
+
+                idx += ALIGN(sizeof(struct gaih_addrtuple));
+                i++;
+        }
+
+        assert(i == c);
+
+        r = sd_bus_message_exit_container(reply);
+        if (r < 0)
+                goto fail;
+
+        assert(idx == ms);
+
+        if (*pat)
+                **pat = *r_tuple_first;
+        else
+                *pat = r_tuple_first;
+
+        if (ttlp)
+                *ttlp = 0;
+
+        /* Explicitly reset all error variables */
+        *errnop = 0;
+        *h_errnop = NETDB_SUCCESS;
+        h_errno = 0;
+
+        return NSS_STATUS_SUCCESS;
+
+fail:
+        *errnop = -r;
+        *h_errnop = NO_DATA;
+        return NSS_STATUS_UNAVAIL;
+}
+
+enum nss_status _nss_mymachines_gethostbyname3_r(
+                const char *name,
+                int af,
+                struct hostent *result,
+                char *buffer, size_t buflen,
+                int *errnop, int *h_errnop,
+                int32_t *ttlp,
+                char **canonp) {
+
+        _cleanup_bus_message_unref_ sd_bus_message* reply = NULL;
+        _cleanup_bus_close_unref_ sd_bus *bus = NULL;
+        _cleanup_free_ char *class = NULL;
+        unsigned c = 0, i = 0;
+        char *r_name, *r_aliases, *r_addr, *r_addr_list;
+        size_t l, idx, ms, alen;
+        int r;
+
+        assert(name);
+        assert(result);
+        assert(buffer);
+        assert(errnop);
+        assert(h_errnop);
+
+        if (af == AF_UNSPEC)
+                af = AF_INET;
+
+        if (af != AF_INET && af != AF_INET6) {
+                r = -EAFNOSUPPORT;
+                goto fail;
+        }
+
+        r = sd_machine_get_class(name, &class);
+        if (r < 0)
+                goto fail;
+        if (!streq(class, "container")) {
+                r = -ENOTTY;
+                goto fail;
+        }
+
+        r = sd_bus_open_system(&bus);
+        if (r < 0)
+                goto fail;
+
+        r = sd_bus_call_method(bus,
+                               "org.freedesktop.machine1",
+                               "/org/freedesktop/machine1",
+                               "org.freedesktop.machine1.Manager",
+                               "GetMachineAddresses",
+                               NULL,
+                               &reply,
+                               "s", name);
+        if (r < 0)
+                goto fail;
+
+        r = sd_bus_message_enter_container(reply, 'a', "(iay)");
+        if (r < 0)
+                goto fail;
+
+        r = count_addresses(reply, af, &c);
+        if (r < 0)
+                goto fail;
+
+        if (c <= 0) {
+                *errnop = ENOENT;
+                *h_errnop = HOST_NOT_FOUND;
+                return NSS_STATUS_NOTFOUND;
+        }
+
+        alen = FAMILY_ADDRESS_SIZE(af);
+        l = strlen(name);
+
+        ms = ALIGN(l+1) +
+                sizeof(char*) +
+                (c > 0 ? c : 1) * ALIGN(alen) +
+                (c > 0 ? c+1 : 2) * sizeof(char*);
+
+        if (buflen < ms) {
+                *errnop = ENOMEM;
+                *h_errnop = NO_RECOVERY;
+                return NSS_STATUS_TRYAGAIN;
+        }
+
+        /* First, append name */
+        r_name = buffer;
+        memcpy(r_name, name, l+1);
+        idx = ALIGN(l+1);
+
+        /* Second, create aliases array */
+        r_aliases = buffer + idx;
+        ((char**) r_aliases)[0] = NULL;
+        idx += sizeof(char*);
+
+        /* Third, append addresses */
+        r_addr = buffer + idx;
+        while ((r = sd_bus_message_enter_container(reply, 'r', "iay")) > 0) {
+                int family;
+                const void *a;
+                size_t sz;
+
+                r = sd_bus_message_read(reply, "i", &family);
+                if (r < 0)
+                        goto fail;
+
+                r = sd_bus_message_read_array(reply, 'y', &a, &sz);
+                if (r < 0)
+                        goto fail;
+
+                r = sd_bus_message_exit_container(reply);
+                if (r < 0)
+                        goto fail;
+
+                if (family != af)
+                        continue;
+
+                if (sz != alen) {
+                        r = -EINVAL;
+                        goto fail;
+                }
+
+                memcpy(r_addr + i*ALIGN(alen), a, alen);
+                i++;
+        }
+
+        assert(i == c);
+        idx += c * ALIGN(alen);
+
+        r = sd_bus_message_exit_container(reply);
+        if (r < 0)
+                goto fail;
+
+        /* Third, append address pointer array */
+        r_addr_list = buffer + idx;
+        for (i = 0; i < c; i++)
+                ((char**) r_addr_list)[i] = r_addr + i*ALIGN(alen);
+
+        ((char**) r_addr_list)[i] = NULL;
+        idx += (c+1) * sizeof(char*);
+
+        assert(idx == ms);
+
+        result->h_name = r_name;
+        result->h_aliases = (char**) r_aliases;
+        result->h_addrtype = af;
+        result->h_length = alen;
+        result->h_addr_list = (char**) r_addr_list;
+
+        if (ttlp)
+                *ttlp = 0;
+
+        if (canonp)
+                *canonp = r_name;
+
+        /* Explicitly reset all error variables */
+        *errnop = 0;
+        *h_errnop = NETDB_SUCCESS;
+        h_errno = 0;
+
+        return NSS_STATUS_SUCCESS;
+
+fail:
+        *errnop = -r;
+        *h_errnop = NO_DATA;
+        return NSS_STATUS_UNAVAIL;
+}
+
+NSS_GETHOSTBYNAME_FALLBACKS(mymachines)
diff --git a/src/nss-mymachines/nss-mymachines.sym b/src/nss-mymachines/nss-mymachines.sym
new file mode 100644 (file)
index 0000000..f80b51c
--- /dev/null
@@ -0,0 +1,17 @@
+/***
+  This file is part of systemd.
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+***/
+
+{
+global:
+        _nss_mymachines_gethostbyname_r;
+        _nss_mymachines_gethostbyname2_r;
+        _nss_mymachines_gethostbyname3_r;
+        _nss_mymachines_gethostbyname4_r;
+local: *;
+};
diff --git a/src/nss-resolve/Makefile b/src/nss-resolve/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/nss-resolve/nss-resolve.c b/src/nss-resolve/nss-resolve.c
new file mode 100644 (file)
index 0000000..bc55acf
--- /dev/null
@@ -0,0 +1,720 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <limits.h>
+#include <nss.h>
+#include <sys/types.h>
+#include <netdb.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <net/if.h>
+#include <stdlib.h>
+#include <arpa/inet.h>
+#include <dlfcn.h>
+
+#include "sd-bus.h"
+#include "bus-util.h"
+#include "bus-errors.h"
+#include "macro.h"
+#include "nss-util.h"
+#include "util.h"
+#include "in-addr-util.h"
+
+NSS_GETHOSTBYNAME_PROTOTYPES(resolve);
+NSS_GETHOSTBYADDR_PROTOTYPES(resolve);
+
+#define DNS_CALL_TIMEOUT_USEC (45*USEC_PER_SEC)
+
+typedef void (*voidfunc_t)(void);
+
+static voidfunc_t find_fallback(const char *module, const char *symbol) {
+        void *dl;
+
+        /* Try to find a fallback NSS module symbol */
+
+        dl = dlopen(module, RTLD_LAZY|RTLD_NODELETE);
+        if (!dl)
+                return NULL;
+
+        return dlsym(dl, symbol);
+}
+
+static bool bus_error_shall_fallback(sd_bus_error *e) {
+        return sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN) ||
+               sd_bus_error_has_name(e, SD_BUS_ERROR_NAME_HAS_NO_OWNER) ||
+               sd_bus_error_has_name(e, SD_BUS_ERROR_NO_REPLY) ||
+               sd_bus_error_has_name(e, SD_BUS_ERROR_ACCESS_DENIED);
+}
+
+static int count_addresses(sd_bus_message *m, int af, const char **canonical) {
+        int c = 0, r, ifindex;
+
+        assert(m);
+        assert(canonical);
+
+        r = sd_bus_message_read(m, "i", &ifindex);
+        if (r < 0)
+                return r;
+
+        r = sd_bus_message_enter_container(m, 'a', "(iay)");
+        if (r < 0)
+                return r;
+
+        while ((r = sd_bus_message_enter_container(m, 'r', "iay")) > 0) {
+                int family;
+
+                r = sd_bus_message_read(m, "i", &family);
+                if (r < 0)
+                        return r;
+
+                r = sd_bus_message_skip(m, "ay");
+                if (r < 0)
+                        return r;
+
+                r = sd_bus_message_exit_container(m);
+                if (r < 0)
+                        return r;
+
+                if (af != AF_UNSPEC && family != af)
+                        continue;
+
+                c ++;
+        }
+        if (r < 0)
+                return r;
+
+        r = sd_bus_message_exit_container(m);
+        if (r < 0)
+                return r;
+
+        r = sd_bus_message_read(m, "s", canonical);
+        if (r < 0)
+                return r;
+
+        r = sd_bus_message_rewind(m, true);
+        if (r < 0)
+                return r;
+
+        return c;
+}
+
+enum nss_status _nss_resolve_gethostbyname4_r(
+                const char *name,
+                struct gaih_addrtuple **pat,
+                char *buffer, size_t buflen,
+                int *errnop, int *h_errnop,
+                int32_t *ttlp) {
+
+        _cleanup_bus_message_unref_ sd_bus_message *req = NULL, *reply = NULL;
+        _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+        struct gaih_addrtuple *r_tuple, *r_tuple_first = NULL;
+        _cleanup_bus_close_unref_ sd_bus *bus = NULL;
+        const char *canonical = NULL;
+        size_t l, ms, idx;
+        char *r_name;
+        int c, r, i = 0, ifindex;
+
+        assert(name);
+        assert(pat);
+        assert(buffer);
+        assert(errnop);
+        assert(h_errnop);
+
+        r = sd_bus_open_system(&bus);
+        if (r < 0)
+                goto fail;
+
+        r = sd_bus_message_new_method_call(
+                        bus,
+                        &req,
+                        "org.freedesktop.resolve1",
+                        "/org/freedesktop/resolve1",
+                        "org.freedesktop.resolve1.Manager",
+                        "ResolveHostname");
+        if (r < 0)
+                goto fail;
+
+        r = sd_bus_message_set_auto_start(req, false);
+        if (r < 0)
+                goto fail;
+
+        r = sd_bus_message_append(req, "isit", 0, name, AF_UNSPEC, (uint64_t) 0);
+        if (r < 0)
+                goto fail;
+
+        r = sd_bus_call(bus, req, DNS_CALL_TIMEOUT_USEC, &error, &reply);
+        if (r < 0) {
+                if (sd_bus_error_has_name(&error, _BUS_ERROR_DNS "NXDOMAIN")) {
+                        *errnop = ESRCH;
+                        *h_errnop = HOST_NOT_FOUND;
+                        return NSS_STATUS_NOTFOUND;
+                }
+
+                if (bus_error_shall_fallback(&error)) {
+
+                        enum nss_status (*fallback)(
+                                        const char *name,
+                                        struct gaih_addrtuple **pat,
+                                        char *buffer, size_t buflen,
+                                        int *errnop, int *h_errnop,
+                                        int32_t *ttlp);
+
+                        fallback = (enum nss_status (*)(const char *name,
+                                                        struct gaih_addrtuple **pat,
+                                                        char *buffer, size_t buflen,
+                                                        int *errnop, int *h_errnop,
+                                                        int32_t *ttlp))
+                                find_fallback("libnss_dns.so.2", "_nss_dns_gethostbyname4_r");
+                        if (fallback)
+                                return fallback(name, pat, buffer, buflen, errnop, h_errnop, ttlp);
+                }
+
+                *errnop = -r;
+                *h_errnop = NO_RECOVERY;
+                return NSS_STATUS_UNAVAIL;
+        }
+
+        c = count_addresses(reply, AF_UNSPEC, &canonical);
+        if (c < 0) {
+                r = c;
+                goto fail;
+        }
+        if (c == 0) {
+                *errnop = ESRCH;
+                *h_errnop = HOST_NOT_FOUND;
+                return NSS_STATUS_NOTFOUND;
+        }
+
+        if (isempty(canonical))
+                canonical = name;
+
+        l = strlen(canonical);
+        ms = ALIGN(l+1) + ALIGN(sizeof(struct gaih_addrtuple)) * c;
+        if (buflen < ms) {
+                *errnop = ENOMEM;
+                *h_errnop = TRY_AGAIN;
+                return NSS_STATUS_TRYAGAIN;
+        }
+
+        /* First, append name */
+        r_name = buffer;
+        memcpy(r_name, canonical, l+1);
+        idx = ALIGN(l+1);
+
+        /* Second, append addresses */
+        r_tuple_first = (struct gaih_addrtuple*) (buffer + idx);
+
+        r = sd_bus_message_read(reply, "i", &ifindex);
+        if (r < 0)
+                goto fail;
+
+        if (ifindex < 0) {
+                r = -EINVAL;
+                goto fail;
+        }
+
+        r = sd_bus_message_enter_container(reply, 'a', "(iay)");
+        if (r < 0)
+                goto fail;
+
+        while ((r = sd_bus_message_enter_container(reply, 'r', "iay")) > 0) {
+                int family;
+                const void *a;
+                size_t sz;
+
+                r = sd_bus_message_read(reply, "i", &family);
+                if (r < 0)
+                        goto fail;
+
+                r = sd_bus_message_read_array(reply, 'y', &a, &sz);
+                if (r < 0)
+                        goto fail;
+
+                r = sd_bus_message_exit_container(reply);
+                if (r < 0)
+                        goto fail;
+
+                if (!IN_SET(family, AF_INET, AF_INET6))
+                        continue;
+
+                if (sz != FAMILY_ADDRESS_SIZE(family)) {
+                        r = -EINVAL;
+                        goto fail;
+                }
+
+                r_tuple = (struct gaih_addrtuple*) (buffer + idx);
+                r_tuple->next = i == c-1 ? NULL : (struct gaih_addrtuple*) ((char*) r_tuple + ALIGN(sizeof(struct gaih_addrtuple)));
+                r_tuple->name = r_name;
+                r_tuple->family = family;
+                r_tuple->scopeid = ifindex;
+                memcpy(r_tuple->addr, a, sz);
+
+                idx += ALIGN(sizeof(struct gaih_addrtuple));
+                i++;
+        }
+        if (r < 0)
+                goto fail;
+
+        assert(i == c);
+        assert(idx == ms);
+
+        if (*pat)
+                **pat = *r_tuple_first;
+        else
+                *pat = r_tuple_first;
+
+        if (ttlp)
+                *ttlp = 0;
+
+        /* Explicitly reset all error variables */
+        *errnop = 0;
+        *h_errnop = NETDB_SUCCESS;
+        h_errno = 0;
+
+        return NSS_STATUS_SUCCESS;
+
+fail:
+        *errnop = -r;
+        *h_errnop = NO_DATA;
+        return NSS_STATUS_UNAVAIL;
+}
+
+enum nss_status _nss_resolve_gethostbyname3_r(
+                const char *name,
+                int af,
+                struct hostent *result,
+                char *buffer, size_t buflen,
+                int *errnop, int *h_errnop,
+                int32_t *ttlp,
+                char **canonp) {
+
+        _cleanup_bus_message_unref_ sd_bus_message *req = NULL, *reply = NULL;
+        _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+        char *r_name, *r_aliases, *r_addr, *r_addr_list;
+        _cleanup_bus_close_unref_ sd_bus *bus = NULL;
+        size_t l, idx, ms, alen;
+        const char *canonical;
+        int c, r, i = 0, ifindex;
+
+        assert(name);
+        assert(result);
+        assert(buffer);
+        assert(errnop);
+        assert(h_errnop);
+
+        if (af == AF_UNSPEC)
+                af = AF_INET;
+
+        if (af != AF_INET && af != AF_INET6) {
+                r = -EAFNOSUPPORT;
+                goto fail;
+        }
+
+        r = sd_bus_open_system(&bus);
+        if (r < 0)
+                goto fail;
+
+        r = sd_bus_message_new_method_call(
+                        bus,
+                        &req,
+                        "org.freedesktop.resolve1",
+                        "/org/freedesktop/resolve1",
+                        "org.freedesktop.resolve1.Manager",
+                        "ResolveHostname");
+        if (r < 0)
+                goto fail;
+
+        r = sd_bus_message_set_auto_start(req, false);
+        if (r < 0)
+                goto fail;
+
+        r = sd_bus_message_append(req, "isit", 0, name, af, (uint64_t) 0);
+        if (r < 0)
+                goto fail;
+
+        r = sd_bus_call(bus, req, DNS_CALL_TIMEOUT_USEC, &error, &reply);
+        if (r < 0) {
+                if (sd_bus_error_has_name(&error, _BUS_ERROR_DNS "NXDOMAIN")) {
+                        *errnop = ESRCH;
+                        *h_errnop = HOST_NOT_FOUND;
+                        return NSS_STATUS_NOTFOUND;
+                }
+
+                if (bus_error_shall_fallback(&error)) {
+
+                        enum nss_status (*fallback)(
+                                        const char *name,
+                                        int af,
+                                        struct hostent *result,
+                                        char *buffer, size_t buflen,
+                                        int *errnop, int *h_errnop,
+                                        int32_t *ttlp,
+                                        char **canonp);
+
+                        fallback =  (enum nss_status (*)(const char *name,
+                                                         int af,
+                                                         struct hostent *result,
+                                                         char *buffer, size_t buflen,
+                                                         int *errnop, int *h_errnop,
+                                                         int32_t *ttlp,
+                                                         char **canonp))
+                                find_fallback("libnss_dns.so.2", "_nss_dns_gethostbyname3_r");
+                        if (fallback)
+                                return fallback(name, af, result, buffer, buflen, errnop, h_errnop, ttlp, canonp);
+                }
+
+                *errnop = -r;
+                *h_errnop = NO_RECOVERY;
+                return NSS_STATUS_UNAVAIL;
+        }
+
+        c = count_addresses(reply, af, &canonical);
+        if (c < 0) {
+                r = c;
+                goto fail;
+        }
+        if (c == 0) {
+                *errnop = ESRCH;
+                *h_errnop = HOST_NOT_FOUND;
+                return NSS_STATUS_NOTFOUND;
+        }
+
+        if (isempty(canonical))
+                canonical = name;
+
+        alen = FAMILY_ADDRESS_SIZE(af);
+        l = strlen(canonical);
+
+        ms = ALIGN(l+1) +
+                sizeof(char*) +
+                (c > 0 ? c : 1) * ALIGN(alen) +
+                (c > 0 ? c+1 : 2) * sizeof(char*);
+
+        if (buflen < ms) {
+                *errnop = ENOMEM;
+                *h_errnop = TRY_AGAIN;
+                return NSS_STATUS_TRYAGAIN;
+        }
+
+        /* First, append name */
+        r_name = buffer;
+        memcpy(r_name, canonical, l+1);
+        idx = ALIGN(l+1);
+
+        /* Second, create empty aliases array */
+        r_aliases = buffer + idx;
+        ((char**) r_aliases)[0] = NULL;
+        idx += sizeof(char*);
+
+        /* Third, append addresses */
+        r_addr = buffer + idx;
+
+        r = sd_bus_message_read(reply, "i", &ifindex);
+        if (r < 0)
+                goto fail;
+
+        if (ifindex < 0) {
+                r = -EINVAL;
+                goto fail;
+        }
+
+        r = sd_bus_message_enter_container(reply, 'a', "(iay)");
+        if (r < 0)
+                goto fail;
+
+        while ((r = sd_bus_message_enter_container(reply, 'r', "iay")) > 0) {
+                int family;
+                const void *a;
+                size_t sz;
+
+                r = sd_bus_message_read(reply, "i", &family);
+                if (r < 0)
+                        goto fail;
+
+                r = sd_bus_message_read_array(reply, 'y', &a, &sz);
+                if (r < 0)
+                        goto fail;
+
+                r = sd_bus_message_exit_container(reply);
+                if (r < 0)
+                        goto fail;
+
+                if (family != af)
+                        continue;
+
+                if (sz != alen) {
+                        r = -EINVAL;
+                        goto fail;
+                }
+
+                if (ifindex < 0) {
+                        r = -EINVAL;
+                        goto fail;
+                }
+
+                memcpy(r_addr + i*ALIGN(alen), a, alen);
+                i++;
+        }
+        if (r < 0)
+                goto fail;
+
+        assert(i == c);
+        idx += c * ALIGN(alen);
+
+        /* Fourth, append address pointer array */
+        r_addr_list = buffer + idx;
+        for (i = 0; i < c; i++)
+                ((char**) r_addr_list)[i] = r_addr + i*ALIGN(alen);
+
+        ((char**) r_addr_list)[i] = NULL;
+        idx += (c+1) * sizeof(char*);
+
+        assert(idx == ms);
+
+        result->h_name = r_name;
+        result->h_aliases = (char**) r_aliases;
+        result->h_addrtype = af;
+        result->h_length = alen;
+        result->h_addr_list = (char**) r_addr_list;
+
+        /* Explicitly reset all error variables */
+        *errnop = 0;
+        *h_errnop = NETDB_SUCCESS;
+        h_errno = 0;
+
+        if (ttlp)
+                *ttlp = 0;
+
+        if (canonp)
+                *canonp = r_name;
+
+        return NSS_STATUS_SUCCESS;
+
+fail:
+        *errnop = -r;
+        *h_errnop = NO_DATA;
+        return NSS_STATUS_UNAVAIL;
+}
+
+enum nss_status _nss_resolve_gethostbyaddr2_r(
+                const void* addr, socklen_t len,
+                int af,
+                struct hostent *result,
+                char *buffer, size_t buflen,
+                int *errnop, int *h_errnop,
+                int32_t *ttlp) {
+
+        _cleanup_bus_message_unref_ sd_bus_message *req = NULL, *reply = NULL;
+        _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+        char *r_name, *r_aliases, *r_addr, *r_addr_list;
+        _cleanup_bus_close_unref_ sd_bus *bus = NULL;
+        unsigned c = 0, i = 0;
+        size_t ms = 0, idx;
+        const char *n;
+        int r, ifindex;
+
+        assert(addr);
+        assert(result);
+        assert(buffer);
+        assert(errnop);
+        assert(h_errnop);
+
+        if (!IN_SET(af, AF_INET, AF_INET6)) {
+                *errnop = EAFNOSUPPORT;
+                *h_errnop = NO_DATA;
+                return NSS_STATUS_UNAVAIL;
+        }
+
+        if (len != FAMILY_ADDRESS_SIZE(af)) {
+                *errnop = EINVAL;
+                *h_errnop = NO_RECOVERY;
+                return NSS_STATUS_UNAVAIL;
+        }
+
+        r = sd_bus_open_system(&bus);
+        if (r < 0)
+                goto fail;
+
+        r = sd_bus_message_new_method_call(
+                        bus,
+                        &req,
+                        "org.freedesktop.resolve1",
+                        "/org/freedesktop/resolve1",
+                        "org.freedesktop.resolve1.Manager",
+                        "ResolveAddress");
+        if (r < 0)
+                goto fail;
+
+        r = sd_bus_message_set_auto_start(req, false);
+        if (r < 0)
+                goto fail;
+
+        r = sd_bus_message_append(req, "ii", 0, af);
+        if (r < 0)
+                goto fail;
+
+        r = sd_bus_message_append_array(req, 'y', addr, len);
+        if (r < 0)
+                goto fail;
+
+        r = sd_bus_message_append(req, "t", (uint64_t) 0);
+        if (r < 0)
+                goto fail;
+
+        r = sd_bus_call(bus, req, DNS_CALL_TIMEOUT_USEC, &error, &reply);
+        if (r < 0) {
+                if (sd_bus_error_has_name(&error, _BUS_ERROR_DNS "NXDOMAIN")) {
+                        *errnop = ESRCH;
+                        *h_errnop = HOST_NOT_FOUND;
+                        return NSS_STATUS_NOTFOUND;
+                }
+
+                if (bus_error_shall_fallback(&error)) {
+
+                        enum nss_status (*fallback)(
+                                        const void* addr, socklen_t len,
+                                        int af,
+                                        struct hostent *result,
+                                        char *buffer, size_t buflen,
+                                        int *errnop, int *h_errnop,
+                                        int32_t *ttlp);
+
+                        fallback = (enum nss_status (*)(
+                                        const void* addr, socklen_t len,
+                                        int af,
+                                        struct hostent *result,
+                                        char *buffer, size_t buflen,
+                                        int *errnop, int *h_errnop,
+                                        int32_t *ttlp))
+                                find_fallback("libnss_dns.so.2", "_nss_dns_gethostbyaddr2_r");
+
+                        if (fallback)
+                                return fallback(addr, len, af, result, buffer, buflen, errnop, h_errnop, ttlp);
+                }
+
+                *errnop = -r;
+                *h_errnop = NO_RECOVERY;
+                return NSS_STATUS_UNAVAIL;
+        }
+
+        r = sd_bus_message_read(reply, "i", &ifindex);
+        if (r < 0)
+                goto fail;
+
+        if (ifindex < 0) {
+                r = -EINVAL;
+                goto fail;
+        }
+
+        r = sd_bus_message_enter_container(reply, 'a', "s");
+        if (r < 0)
+                goto fail;
+
+        while ((r = sd_bus_message_read(reply, "s", &n)) > 0) {
+                c++;
+                ms += ALIGN(strlen(n) + 1);
+        }
+        if (r < 0)
+                goto fail;
+
+        r = sd_bus_message_rewind(reply, false);
+        if (r < 0)
+                return r;
+
+        if (c <= 0) {
+                *errnop = ESRCH;
+                *h_errnop = HOST_NOT_FOUND;
+                return NSS_STATUS_NOTFOUND;
+        }
+
+        ms += ALIGN(len) +              /* the address */
+              2 * sizeof(char*) +       /* pointers to the address, plus trailing NULL */
+              c * sizeof(char*);        /* pointers to aliases, plus trailing NULL */
+
+        if (buflen < ms) {
+                *errnop = ENOMEM;
+                *h_errnop = TRY_AGAIN;
+                return NSS_STATUS_TRYAGAIN;
+        }
+
+        /* First, place address */
+        r_addr = buffer;
+        memcpy(r_addr, addr, len);
+        idx = ALIGN(len);
+
+        /* Second, place address list */
+        r_addr_list = buffer + idx;
+        ((char**) r_addr_list)[0] = r_addr;
+        ((char**) r_addr_list)[1] = NULL;
+        idx += sizeof(char*) * 2;
+
+        /* Third, reserve space for the aliases array */
+        r_aliases = buffer + idx;
+        idx += sizeof(char*) * c;
+
+        /* Fourth, place aliases */
+        i = 0;
+        r_name = buffer + idx;
+        while ((r = sd_bus_message_read(reply, "s", &n)) > 0) {
+                char *p;
+                size_t l;
+
+                l = strlen(n);
+                p = buffer + idx;
+                memcpy(p, n, l+1);
+
+                if (i > 1)
+                        ((char**) r_aliases)[i-1] = p;
+                i++;
+
+                idx += ALIGN(l+1);
+        }
+        if (r < 0)
+                goto fail;
+
+        ((char**) r_aliases)[c-1] = NULL;
+        assert(idx == ms);
+
+        result->h_name = r_name;
+        result->h_aliases = (char**) r_aliases;
+        result->h_addrtype = af;
+        result->h_length = len;
+        result->h_addr_list = (char**) r_addr_list;
+
+        if (ttlp)
+                *ttlp = 0;
+
+        /* Explicitly reset all error variables */
+        *errnop = 0;
+        *h_errnop = NETDB_SUCCESS;
+        h_errno = 0;
+
+        return NSS_STATUS_SUCCESS;
+
+fail:
+        *errnop = -r;
+        *h_errnop = NO_DATA;
+        return NSS_STATUS_UNAVAIL;
+}
+
+NSS_GETHOSTBYNAME_FALLBACKS(resolve);
+NSS_GETHOSTBYADDR_FALLBACKS(resolve);
diff --git a/src/nss-resolve/nss-resolve.sym b/src/nss-resolve/nss-resolve.sym
new file mode 100644 (file)
index 0000000..df8dff2
--- /dev/null
@@ -0,0 +1,19 @@
+/***
+  This file is part of systemd.
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+***/
+
+{
+global:
+        _nss_resolve_gethostbyname_r;
+        _nss_resolve_gethostbyname2_r;
+        _nss_resolve_gethostbyname3_r;
+        _nss_resolve_gethostbyname4_r;
+        _nss_resolve_gethostbyaddr_r;
+        _nss_resolve_gethostbyaddr2_r;
+local: *;
+};
diff --git a/src/path/Makefile b/src/path/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/path/path.c b/src/path/path.c
new file mode 100644 (file)
index 0000000..347921a
--- /dev/null
@@ -0,0 +1,205 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdio.h>
+#include <getopt.h>
+#include <error.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "sd-path.h"
+#include "build.h"
+#include "macro.h"
+#include "util.h"
+#include "log.h"
+
+static const char *arg_suffix = NULL;
+
+static const char* const path_table[_SD_PATH_MAX] = {
+        [SD_PATH_TEMPORARY] = "temporary",
+        [SD_PATH_TEMPORARY_LARGE] = "temporary-large",
+        [SD_PATH_SYSTEM_BINARIES] = "system-binaries",
+        [SD_PATH_SYSTEM_INCLUDE] = "system-include",
+        [SD_PATH_SYSTEM_LIBRARY_PRIVATE] = "system-library-private",
+        [SD_PATH_SYSTEM_LIBRARY_ARCH] = "system-library-arch",
+        [SD_PATH_SYSTEM_SHARED] = "system-shared",
+        [SD_PATH_SYSTEM_CONFIGURATION_FACTORY] = "system-configuration-factory",
+        [SD_PATH_SYSTEM_STATE_FACTORY] = "system-state-factory",
+        [SD_PATH_SYSTEM_CONFIGURATION] = "system-configuration",
+        [SD_PATH_SYSTEM_RUNTIME] = "system-runtime",
+        [SD_PATH_SYSTEM_RUNTIME_LOGS] = "system-runtime-logs",
+        [SD_PATH_SYSTEM_STATE_PRIVATE] = "system-state-private",
+        [SD_PATH_SYSTEM_STATE_LOGS] = "system-state-logs",
+        [SD_PATH_SYSTEM_STATE_CACHE] = "system-state-cache",
+        [SD_PATH_SYSTEM_STATE_SPOOL] = "system-state-spool",
+        [SD_PATH_USER_BINARIES] = "user-binaries",
+        [SD_PATH_USER_LIBRARY_PRIVATE] = "user-library-private",
+        [SD_PATH_USER_LIBRARY_ARCH] = "user-library-arch",
+        [SD_PATH_USER_SHARED] = "user-shared",
+        [SD_PATH_USER_CONFIGURATION] = "user-configuration",
+        [SD_PATH_USER_RUNTIME] = "user-runtime",
+        [SD_PATH_USER_STATE_CACHE] = "user-state-cache",
+        [SD_PATH_USER] = "user",
+        [SD_PATH_USER_DOCUMENTS] = "user-documents",
+        [SD_PATH_USER_MUSIC] = "user-music",
+        [SD_PATH_USER_PICTURES] = "user-pictures",
+        [SD_PATH_USER_VIDEOS] = "user-videos",
+        [SD_PATH_USER_DOWNLOAD] = "user-download",
+        [SD_PATH_USER_PUBLIC] = "user-public",
+        [SD_PATH_USER_TEMPLATES] = "user-templates",
+        [SD_PATH_USER_DESKTOP] = "user-desktop",
+        [SD_PATH_SEARCH_BINARIES] = "search-binaries",
+        [SD_PATH_SEARCH_LIBRARY_PRIVATE] = "search-library-private",
+        [SD_PATH_SEARCH_LIBRARY_ARCH] = "search-library-arch",
+        [SD_PATH_SEARCH_SHARED] = "search-shared",
+        [SD_PATH_SEARCH_CONFIGURATION_FACTORY] = "search-configuration-factory",
+        [SD_PATH_SEARCH_STATE_FACTORY] = "search-state-factory",
+        [SD_PATH_SEARCH_CONFIGURATION] = "search-configuration",
+};
+
+static int list_homes(void) {
+        uint64_t i = 0;
+        int r = 0;
+
+        for (i = 0; i < ELEMENTSOF(path_table); i++) {
+                _cleanup_free_ char *p = NULL;
+                int q;
+
+                q = sd_path_home(i, arg_suffix, &p);
+                if (q == -ENXIO)
+                        continue;
+                if (q < 0) {
+                        log_error("Failed to query %s: %s", path_table[i], strerror(-r));
+                        r = q;
+                        continue;
+                }
+
+                printf("%s: %s\n", path_table[i], p);
+        }
+
+        return r;
+}
+
+static int print_home(const char *n) {
+        uint64_t i = 0;
+        int r;
+
+        for (i = 0; i < ELEMENTSOF(path_table); i++) {
+                if (streq(path_table[i], n)) {
+                        _cleanup_free_ char *p = NULL;
+
+                        r = sd_path_home(i, arg_suffix, &p);
+                        if (r < 0) {
+                                log_error("Failed to query %s: %s", n, strerror(-r));
+                                return r;
+                        }
+
+                        printf("%s\n", p);
+                        return 0;
+                }
+        }
+
+        log_error("Path %s not known.", n);
+        return -ENOTSUP;
+}
+
+static void help(void) {
+        printf("%s [OPTIONS...] [NAME...]\n\n"
+               "Show system and user paths.\n\n"
+               "  -h --help             Show this help\n"
+               "     --version          Show package version\n"
+               "     --suffix=SUFFIX    Suffix to append to paths\n",
+               program_invocation_short_name);
+}
+
+static int parse_argv(int argc, char *argv[]) {
+
+        enum {
+                ARG_VERSION = 0x100,
+                ARG_SUFFIX,
+        };
+
+        static const struct option options[] = {
+                { "help",      no_argument,       NULL, 'h'           },
+                { "version",   no_argument,       NULL, ARG_VERSION   },
+                { "suffix",    required_argument, NULL, ARG_SUFFIX    },
+                {}
+        };
+
+        int c;
+
+        assert(argc >= 0);
+        assert(argv);
+
+        while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
+
+                switch (c) {
+
+                case 'h':
+                        help();
+                        return 0;
+
+                case ARG_VERSION:
+                        puts(PACKAGE_STRING);
+                        puts(SYSTEMD_FEATURES);
+                        return 0;
+
+                case ARG_SUFFIX:
+                        arg_suffix = optarg;
+                        break;
+
+                case '?':
+                        return -EINVAL;
+
+                default:
+                        assert_not_reached("Unhandled option");
+                }
+
+        return 1;
+}
+
+int main(int argc, char* argv[]) {
+        int r;
+
+        log_parse_environment();
+        log_open();
+
+        r = parse_argv(argc, argv);
+        if (r <= 0)
+                goto finish;
+
+        if (argc > optind) {
+                int i, q;
+
+                for (i = optind; i < argc; i++) {
+                        q = print_home(argv[i]);
+                        if (q < 0)
+                                r = q;
+                }
+        } else
+                r = list_homes();
+
+
+finish:
+        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
index 7756a78..65cfec7 100644 (file)
@@ -29,7 +29,7 @@
 #include <assert.h>
 #include <sys/socket.h>
 
-#include <systemd/sd-daemon.h>
+#include "systemd/sd-daemon.h"
 #include "pyutil.h"
 #include "macro.h"
 
index cbc661d..456e4a2 100644 (file)
@@ -25,7 +25,7 @@
 #include "util.h"
 
 #define SD_JOURNAL_SUPPRESS_LOCATION
-#include <systemd/sd-journal.h>
+#include "systemd/sd-journal.h"
 
 PyDoc_STRVAR(journal_sendv__doc__,
              "sendv('FIELD=value', 'FIELD=value', ...) -> None\n\n"
index 059b904..d17aa83 100644 (file)
@@ -25,7 +25,7 @@
 #include <time.h>
 #include <stdio.h>
 
-#include <systemd/sd-journal.h>
+#include "systemd/sd-journal.h"
 
 #include "pyutil.h"
 #include "macro.h"
@@ -902,7 +902,6 @@ static PyObject* get_catalog(PyObject *self, PyObject *args) {
         sd_id128_t id;
         _cleanup_free_ char *msg = NULL;
 
-        assert(!self);
         assert(args);
 
         if (!PyArg_ParseTuple(args, "z:get_catalog", &id_))
index 6dadf7b..5ec7309 100644 (file)
@@ -21,7 +21,7 @@
 
 #include <Python.h>
 
-#include <systemd/sd-messages.h>
+#include "systemd/sd-messages.h"
 
 #include "pyutil.h"
 #include "log.h"
index 9c7e004..dd1f229 100644 (file)
@@ -293,7 +293,7 @@ class Reader(_Reader):
             monotonic = monotonic.totalseconds()
         monotonic = int(monotonic * 1000000)
         if isinstance(bootid, _uuid.UUID):
-            bootid = bootid.get_hex()
+            bootid = bootid.hex
         return super(Reader, self).seek_monotonic(monotonic, bootid)
 
     def log_level(self, level):
@@ -314,7 +314,7 @@ class Reader(_Reader):
         Equivalent to add_match(MESSAGE_ID=`messageid`).
         """
         if isinstance(messageid, _uuid.UUID):
-            messageid = messageid.get_hex()
+            messageid = messageid.hex
         self.add_match(MESSAGE_ID=messageid)
 
     def this_boot(self, bootid=None):
@@ -346,7 +346,7 @@ class Reader(_Reader):
 
 def get_catalog(mid):
     if isinstance(mid, _uuid.UUID):
-        mid = mid.get_hex()
+        mid = mid.hex
     return _get_catalog(mid)
 
 def _make_line(field, value):
index 8ff0f7f..ed95b48 100644 (file)
 static bool arg_skip = false;
 static bool arg_force = false;
 
-static int parse_proc_cmdline_word(const char *w) {
-        if (streq(w, "quotacheck.mode=auto"))
-                arg_force = arg_skip = false;
-        else if (streq(w, "quotacheck.mode=force"))
-                arg_force = true;
-        else if (streq(w, "quotacheck.mode=skip"))
-                arg_skip = true;
-        else if (startswith(w, "quotacheck"))
-                log_warning("Invalid quotacheck parameter. Ignoring.");
+static int parse_proc_cmdline_item(const char *key, const char *value) {
+
+        if (streq(key, "quotacheck.mode") && value) {
+
+                if (streq(value, "auto"))
+                        arg_force = arg_skip = false;
+                else if (streq(value, "force"))
+                        arg_force = true;
+                else if (streq(value, "skip"))
+                        arg_skip = true;
+                else
+                        log_warning("Invalid quotacheck.mode= parameter '%s'. Ignoring.", value);
+        }
+
 #ifdef HAVE_SYSV_COMPAT
-        else if (streq(w, "forcequotacheck")) {
-                log_error("Please use 'quotacheck.mode=force' rather than 'forcequotacheck' on the kernel command line.");
+        else if (streq(key, "forcequotacheck") && !value) {
+                log_warning("Please use 'quotacheck.mode=force' rather than 'forcequotacheck' on the kernel command line.");
                 arg_force = true;
         }
 #endif
@@ -51,6 +56,7 @@ static int parse_proc_cmdline_word(const char *w) {
 }
 
 static void test_files(void) {
+
 #ifdef HAVE_SYSV_COMPAT
         if (access("/forcequotacheck", F_OK) >= 0) {
                 log_error("Please pass 'quotacheck.mode=force' on the kernel command line rather than creating /forcequotacheck on the root file system.");
@@ -80,7 +86,7 @@ int main(int argc, char *argv[]) {
 
         umask(0022);
 
-        parse_proc_cmdline(parse_proc_cmdline_word);
+        parse_proc_cmdline(parse_proc_cmdline_item);
         test_files();
 
         if (!arg_force) {
index bc38a6b..ef12b3d 100644 (file)
@@ -52,7 +52,7 @@
 #include <sys/fanotify.h>
 #endif
 
-#include <systemd/sd-daemon.h>
+#include "systemd/sd-daemon.h"
 
 #include "missing.h"
 #include "util.h"
@@ -176,8 +176,7 @@ finish:
         if (start != MAP_FAILED)
                 munmap(start, l);
 
-        if (fd >= 0)
-                close_nointr_nofail(fd);
+        safe_close(fd);
 
         return r;
 }
@@ -254,10 +253,10 @@ static int collect(const char *root) {
 
         assert(root);
 
-#ifndef CONFIG_TIZEN
-        if (asprintf(&pack_fn, "%s/.readahead", root) < 0) {
-#else
+#ifdef CONFIG_TIZEN
         if (asprintf(&pack_fn, "%s/.readahead", arg_savedir ? arg_savedir : root) < 0) {
+#else
+        if (asprintf(&pack_fn, "%s/.readahead", root) < 0) {
 #endif
                 r = log_oom();
                 goto finish;
@@ -497,16 +496,12 @@ static int collect(const char *root) {
                                 log_warning("readlink(%s) failed: %s", fn, strerror(-k));
 
                 next_iteration:
-                        if (m->fd >= 0)
-                                close_nointr_nofail(m->fd);
+                        safe_close(m->fd);
                 }
         }
 
 done:
-        if (fanotify_fd >= 0) {
-                close_nointr_nofail(fanotify_fd);
-                fanotify_fd = -1;
-        }
+        fanotify_fd = safe_close(fanotify_fd);
 
         log_debug("Writing Pack File...");
 
@@ -517,9 +512,9 @@ done:
         log_debug("On btrfs: %s", yes_no(on_btrfs));
 
 #ifndef CONFIG_TIZEN
-        if (asprintf(&pack_fn_new, "%s/.readahead.new", root) < 0) {
-#else
         if (asprintf(&pack_fn_new, "%s/.readahead.new", arg_savedir ? arg_savedir : root) < 0) {
+#else
+        if (asprintf(&pack_fn_new, "%s/.readahead.new", root) < 0) {
 #endif
                 r = log_oom();
                 goto finish;
@@ -600,14 +595,9 @@ done:
         log_debug("Done.");
 
 finish:
-        if (fanotify_fd >= 0)
-                close_nointr_nofail(fanotify_fd);
-
-        if (signal_fd >= 0)
-                close_nointr_nofail(signal_fd);
-
-        if (inotify_fd >= 0)
-                close_nointr_nofail(inotify_fd);
+        safe_close(fanotify_fd);
+        safe_close(signal_fd);
+        safe_close(inotify_fd);
 
         if (pack) {
                 fclose(pack);
index aea1fbe..3ca48a7 100644 (file)
@@ -52,7 +52,9 @@ int file_verify(int fd, const char *fn, off_t file_size_max, struct stat *st) {
         }
 
         if (st->st_size <= 0 || st->st_size > file_size_max) {
-                log_debug("Not preloading file %s with size out of bounds %llu", fn, (unsigned long long) st->st_size);
+                assert_cc(sizeof(st->st_size) == 8);
+                log_debug("Not preloading file %s with size out of bounds %"PRIu64,
+                          fn, st->st_size);
                 return 0;
         }
 
@@ -75,7 +77,7 @@ int fs_on_ssd(const char *p) {
         if (major(st.st_dev) == 0) {
                 _cleanup_fclose_ FILE *f = NULL;
                 int mount_id;
-                struct file_handle *h;
+                union file_handle_union h = { .handle.handle_bytes = MAX_HANDLE_SZ, };
 
                 /* Might be btrfs, which exposes "ssd" as mount flag if it is on ssd.
                  *
@@ -83,9 +85,7 @@ int fs_on_ssd(const char *p) {
                  * and then lookup the mount ID in mountinfo to find
                  * the mount options. */
 
-                h = alloca(MAX_HANDLE_SZ);
-                h->handle_bytes = MAX_HANDLE_SZ;
-                r = name_to_handle_at(AT_FDCWD, p, h, &mount_id, AT_SYMLINK_FOLLOW);
+                r = name_to_handle_at(AT_FDCWD, p, &h.handle, &mount_id, AT_SYMLINK_FOLLOW);
                 if (r < 0)
                         return false;
 
@@ -220,7 +220,7 @@ int open_inotify(void) {
 
         if (inotify_add_watch(fd, "/run/systemd/readahead", IN_CREATE) < 0) {
                 log_error("Failed to watch /run/systemd/readahead: %m");
-                close_nointr_nofail(fd);
+                safe_close(fd);
                 return -errno;
         }
 
@@ -228,7 +228,7 @@ int open_inotify(void) {
 }
 
 ReadaheadShared *shared_get(void) {
-        int _cleanup_close_ fd = -1;
+        _cleanup_close_ int fd = -1;
         ReadaheadShared *m = NULL;
 
         mkdirs();
@@ -257,7 +257,7 @@ ReadaheadShared *shared_get(void) {
    Simply so that it is more unlikely that users end up picking this
    value too so that we can recognize better whether the user changed
    the value while we had it temporarily bumped. */
-#define BUMP_REQUEST_NR (20*1024)
+#define BUMP_REQUEST_NR (20*1024u)
 
 int block_bump_request_nr(const char *p) {
         struct stat st;
@@ -298,7 +298,7 @@ int block_bump_request_nr(const char *p) {
         free(line);
         line = NULL;
 
-        if (asprintf(&line, "%lu", (unsigned long) BUMP_REQUEST_NR) < 0) {
+        if (asprintf(&line, "%u", BUMP_REQUEST_NR) < 0) {
                 r = -ENOMEM;
                 goto finish;
         }
@@ -307,7 +307,7 @@ int block_bump_request_nr(const char *p) {
         if (r < 0)
                 goto finish;
 
-        log_info("Bumped block_nr parameter of %u:%u to %lu. This is a temporary hack and should be removed one day.", major(d), minor(d), (unsigned long) BUMP_REQUEST_NR);
+        log_info("Bumped block_nr parameter of %u:%u to %u. This is a temporary hack and should be removed one day.", major(d), minor(d), BUMP_REQUEST_NR);
         r = 1;
 
 finish:
@@ -381,7 +381,7 @@ int block_set_readahead(const char *p, uint64_t bytes) {
                 goto finish;
         }
 
-        if (asprintf(&line, "%llu", (unsigned long long) bytes / 1024ULL) < 0) {
+        if (asprintf(&line, "%llu", bytes / 1024ULL) < 0) {
                 r = -ENOMEM;
                 goto finish;
         }
index f16a77c..cb0322e 100644 (file)
@@ -35,7 +35,7 @@
 #include <getopt.h>
 #include <sys/inotify.h>
 
-#include <systemd/sd-daemon.h>
+#include "systemd/sd-daemon.h"
 
 #include "missing.h"
 #include "util.h"
@@ -47,8 +47,8 @@
 static ReadaheadShared *shared = NULL;
 
 static int unpack_file(FILE *pack) {
+        _cleanup_close_ int fd = -1;
         char fn[PATH_MAX];
-        int r = 0, fd = -1;
         bool any = false;
         struct stat st;
         uint64_t inode;
@@ -63,28 +63,22 @@ static int unpack_file(FILE *pack) {
 
         fd = open(fn, O_RDONLY|O_CLOEXEC|O_NOATIME|O_NOCTTY|O_NOFOLLOW);
         if (fd < 0) {
-
                 if (errno != ENOENT && errno != EPERM && errno != EACCES && errno != ELOOP)
                         log_warning("open(%s) failed: %m", fn);
 
-        } else if (file_verify(fd, fn, arg_file_size_max, &st) <= 0) {
-                close_nointr_nofail(fd);
-                fd = -1;
-        }
+        } else if (file_verify(fd, fn, arg_file_size_max, &st) <= 0)
+                fd = safe_close(fd);
 
         if (fread(&inode, sizeof(inode), 1, pack) != 1) {
                 log_error("Premature end of pack file.");
-                r = -EIO;
-                goto finish;
+                return -EIO;
         }
 
         if (fd >= 0) {
                 /* If the inode changed the file got deleted, so just
                  * ignore this entry */
-                if (st.st_ino != (uint64_t) inode) {
-                        close_nointr_nofail(fd);
-                        fd = -1;
-                }
+                if (st.st_ino != (uint64_t) inode)
+                        fd = safe_close(fd);
         }
 
         for (;;) {
@@ -93,8 +87,7 @@ static int unpack_file(FILE *pack) {
                 if (fread(&b, sizeof(b), 1, pack) != 1 ||
                     fread(&c, sizeof(c), 1, pack) != 1) {
                         log_error("Premature end of pack file.");
-                        r = -EIO;
-                        goto finish;
+                        return -EIO;
                 }
 
                 if (b == 0 && c == 0)
@@ -102,19 +95,19 @@ static int unpack_file(FILE *pack) {
 
                 if (c <= b) {
                         log_error("Invalid pack file.");
-                        r = -EIO;
-                        goto finish;
+                        return -EIO;
                 }
 
                 log_debug("%s: page %u to %u", fn, b, c);
 
                 any = true;
 
-                if (fd >= 0)
+                if (fd >= 0) {
                         if (posix_fadvise(fd, b * page_size(), (c - b) * page_size(), POSIX_FADV_WILLNEED) < 0) {
                                 log_warning("posix_fadvise() failed: %m");
-                                goto finish;
+                                return -errno;
                         }
+                }
         }
 
         if (!any && fd >= 0) {
@@ -124,76 +117,65 @@ static int unpack_file(FILE *pack) {
 
                 if (posix_fadvise(fd, 0, st.st_size, POSIX_FADV_WILLNEED) < 0) {
                         log_warning("posix_fadvise() failed: %m");
-                        goto finish;
+                        return -errno;
                 }
         }
 
-finish:
-        if (fd >= 0)
-                close_nointr_nofail(fd);
-
-        return r;
+        return 0;
 }
 
 static int replay(const char *root) {
-        FILE *pack = NULL;
-        char line[LINE_MAX];
-        int r = 0;
-        char *pack_fn = NULL;
-        int c;
+        _cleanup_close_ int inotify_fd = -1;
+        _cleanup_free_ char *pack_fn = NULL;
+        _cleanup_fclose_ FILE *pack = NULL;
         bool on_ssd, ready = false;
-        int prio;
-        int inotify_fd = -1;
+        char line[LINE_MAX];
+        int prio, c;
 
         assert(root);
 
         block_bump_request_nr(root);
 
-#ifndef CONFIG_TIZEN
-        if (asprintf(&pack_fn, "%s/.readahead", root) < 0) {
+#ifdef CONFIG_TIZEN
+        if (asprintf(&pack_fn, "%s/.readahead", arg_savedir ? arg_savedir : root) < 0)
 #else
-        if (asprintf(&pack_fn, "%s/.readahead", arg_savedir ? arg_savedir : root) < 0) {
+        if (asprintf(&pack_fn, "%s/.readahead", root) < 0)
 #endif
-                r = log_oom();
-                goto finish;
-        }
+                return log_oom();
 
         pack = fopen(pack_fn, "re");
         if (!pack) {
-                if (errno == ENOENT)
+                if (errno == ENOENT) {
                         log_debug("No pack file found.");
-                else {
-                        log_error("Failed to open pack file: %m");
-                        r = -errno;
+                        return 0;
                 }
 
-                goto finish;
+                log_error("Failed to open pack file: %m");
+                return -errno;
         }
 
         posix_fadvise(fileno(pack), 0, 0, POSIX_FADV_WILLNEED);
 
-        if ((inotify_fd = open_inotify()) < 0) {
-                r = inotify_fd;
-                goto finish;
-        }
+        inotify_fd = open_inotify();
+        if (inotify_fd < 0)
+                return inotify_fd;
 
-        if (!(fgets(line, sizeof(line), pack))) {
+        if (!fgets(line, sizeof(line), pack)) {
                 log_error("Premature end of pack file.");
-                r = -EIO;
-                goto finish;
+                return -EIO;
         }
 
         char_array_0(line);
 
         if (!streq(line, CANONICAL_HOST READAHEAD_PACK_FILE_VERSION)) {
                 log_debug("Pack file host or version type mismatch.");
-                goto finish;
+                goto done;
         }
 
-        if ((c = getc(pack)) == EOF) {
+        c = getc(pack);
+        if (c == EOF) {
                 log_debug("Premature end of pack file.");
-                r = -EIO;
-                goto finish;
+                return -EIO;
         }
 
         /* We do not retest SSD here, so that we can start replaying
@@ -229,11 +211,11 @@ static int replay(const char *root) {
                 int k;
                 ssize_t n;
 
-                if ((n = read(inotify_fd, &inotify_buffer, sizeof(inotify_buffer))) < 0) {
+                n = read(inotify_fd, &inotify_buffer, sizeof(inotify_buffer));
+                if (n < 0) {
                         if (errno != EINTR && errno != EAGAIN) {
                                 log_error("Failed to read inotify event: %m");
-                                r = -errno;
-                                goto finish;
+                                return -errno;
                         }
                 } else {
                         struct inotify_event *e = (struct inotify_event*) inotify_buffer;
@@ -254,10 +236,9 @@ static int replay(const char *root) {
                         }
                 }
 
-                if ((k = unpack_file(pack)) < 0) {
-                        r = k;
-                        goto finish;
-                }
+                k = unpack_file(pack);
+                if (k < 0)
+                        return k;
 
                 if (!ready) {
                         /* We delay the ready notification until we
@@ -268,27 +249,16 @@ static int replay(const char *root) {
         }
 
 done:
-        if (!ready)
-                sd_notify(0, "READY=1");
-
         if (ferror(pack)) {
                 log_error("Failed to read pack file.");
-                r = -EIO;
-                goto finish;
+                return -EIO;
         }
 
-        log_debug("Done.");
-
-finish:
-        if (pack)
-                fclose(pack);
-
-        if (inotify_fd >= 0)
-                close_nointr_nofail(inotify_fd);
-
-        free(pack_fn);
+        if (!ready)
+                sd_notify(0, "READY=1");
 
-        return r;
+        log_debug("Done.");
+        return 0;
 }
 
 int main_replay(const char *root) {
index e317f9f..789b325 100644 (file)
@@ -39,59 +39,54 @@ usec_t arg_timeout = 2*USEC_PER_MINUTE;
 const char *arg_savedir;
 #endif
 
-static int help(void) {
-
-        printf("%s [OPTIONS...] collect [DIRECTORY]\n\n"
+static void help(void) {
+        printf("%1$s [OPTIONS...] collect [DIRECTORY]\n\n"
                "Collect read-ahead data on early boot.\n\n"
                "  -h --help                 Show this help\n"
                "     --version              Show package version\n"
+               "     --files-max=INT        Maximum number of files to read ahead\n"
+               "     --file-size-max=BYTES  Maximum size of files to read ahead\n"
 #ifdef CONFIG_TIZEN
                "     --savedir=PATH         Directory path to save collecting data\n"
 #endif
-               "     --max-files=INT        Maximum number of files to read ahead\n"
-               "     --file-size-max=BYTES  Maximum size of files to read ahead\n"
-               "     --timeout=USEC         Maximum time to spend collecting data\n\n\n",
-               program_invocation_short_name);
-
-        printf("%s [OPTIONS...] replay [DIRECTORY]\n\n"
+               "     --timeout=USEC         Maximum time to spend collecting data\n"
+               "\n\n"
+               "%1$s [OPTIONS...] replay [DIRECTORY]\n\n"
                "Replay collected read-ahead data on early boot.\n\n"
                "  -h --help                 Show this help\n"
                "     --version              Show package version\n"
+               "     --file-size-max=BYTES  Maximum size of files to read ahead\n"
 #ifdef CONFIG_TIZEN
                "     --savedir=PATH         Directory path to save collecting data\n"
 #endif
-               "     --file-size-max=BYTES  Maximum size of files to read ahead\n\n\n",
-               program_invocation_short_name);
-
-        printf("%s [OPTIONS...] analyze [PACK FILE]\n\n"
+               "\n\n"
+               "%1$s [OPTIONS...] analyze [PACK-FILE]\n\n"
                "Analyze collected read-ahead data.\n\n"
                "  -h --help                 Show this help\n"
                "     --version              Show package version\n",
                program_invocation_short_name);
-
-        return 0;
 }
 
 static int parse_argv(int argc, char *argv[]) {
 
         enum {
                 ARG_VERSION = 0x100,
+                ARG_FILES_MAX,
+                ARG_FILE_SIZE_MAX,
 #ifdef CONFIG_TIZEN
                 ARG_SAVEDIR,
 #endif
-                ARG_FILES_MAX,
-                ARG_FILE_SIZE_MAX,
                 ARG_TIMEOUT
         };
 
         static const struct option options[] = {
                 { "help",          no_argument,       NULL, 'h'                },
                 { "version",       no_argument,       NULL, ARG_VERSION        },
+                { "files-max",     required_argument, NULL, ARG_FILES_MAX      },
+                { "file-size-max", required_argument, NULL, ARG_FILE_SIZE_MAX  },
 #ifdef CONFIG_TIZEN
                 { "savedir",       required_argument, NULL, ARG_SAVEDIR        },
 #endif
-                { "files-max",     required_argument, NULL, ARG_FILES_MAX      },
-                { "file-size-max", required_argument, NULL, ARG_FILE_SIZE_MAX  },
                 { "timeout",       required_argument, NULL, ARG_TIMEOUT        },
                 {}
         };
@@ -101,12 +96,13 @@ static int parse_argv(int argc, char *argv[]) {
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) {
+        while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
 
                 switch (c) {
 
                 case 'h':
-                        return help();
+                        help();
+                        return 0;
 
                 case ARG_VERSION:
                         puts(PACKAGE_STRING);
@@ -132,6 +128,12 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
                 }
 
+#ifdef CONFIG_TIZEN
+                case ARG_SAVEDIR:
+                        arg_savedir = optarg;
+                        break;
+#endif
+
                 case ARG_TIMEOUT:
                         if (parse_sec(optarg, &arg_timeout) < 0 || arg_timeout <= 0) {
                                 log_error("Failed to parse timeout %s.", optarg);
@@ -140,23 +142,17 @@ static int parse_argv(int argc, char *argv[]) {
 
                         break;
 
-#ifdef CONFIG_TIZEN
-                case ARG_SAVEDIR:
-                        arg_savedir = optarg;
-                        break;
-#endif
-
                 case '?':
                         return -EINVAL;
 
                 default:
                         assert_not_reached("Unhandled option");
                 }
-        }
 
         if (optind != argc-1 &&
             optind != argc-2) {
-                help();
+                log_error("%s: wrong number of arguments.",
+                          program_invocation_short_name);
                 return -EINVAL;
         }
 
similarity index 60%
rename from src/journal/microhttpd-util.c
rename to src/readahead/test-ssd.c
index 3844f7a..808faf3 100644 (file)
@@ -3,7 +3,7 @@
 /***
   This file is part of systemd.
 
-  Copyright 2012 Zbigniew Jędrzejewski-Szmek
+  Copyright 2014 Zbigniew Jędrzejewski-Szmek
 
   systemd is free software; you can redistribute it and/or modify it
   under the terms of the GNU Lesser General Public License as published by
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
-#include <stddef.h>
-#include <stdio.h>
+#include "readahead-common.h"
 
-#include "microhttpd-util.h"
-#include "log.h"
-#include "macro.h"
-#include "util.h"
+int main(int argc, char *argv[]) {
+        int i;
 
-void microhttpd_logger(void *arg, const char *fmt, va_list ap) {
-        _cleanup_free_ char *f = NULL;
+        for (i = 1; i < argc; i++) {
+                char *name = argv[i];
+                int r;
 
-        if (asprintf(&f, "microhttpd: %s", fmt) <= 0) {
-                log_oom();
-                return;
+                r = fs_on_ssd(name);
+                if (r < 0) {
+                        log_error("%s: %s", name, strerror(-r));
+                        return EXIT_FAILURE;
+                }
+
+                log_info("%s: %s", name, r ? "SSD" : "---");
         }
 
-        DISABLE_WARNING_FORMAT_NONLITERAL;
-        log_metav(LOG_INFO, NULL, 0, NULL, f, ap);
-        REENABLE_WARNING;
+        return EXIT_SUCCESS;
 }
index 2f16898..73c2d1b 100644 (file)
@@ -53,7 +53,7 @@ static int send_on_socket(int fd, const char *socket_name, const void *packet, s
 
         if (sendto(fd, packet, size, MSG_NOSIGNAL, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(socket_name)) < 0) {
                 log_error("Failed to send: %m");
-                return -1;
+                return -errno;
         }
 
         return 0;
@@ -91,7 +91,8 @@ int main(int argc, char *argv[]) {
                 goto finish;
         }
 
-        if ((fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0)) < 0) {
+        fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
+        if (fd < 0) {
                 log_error("socket() failed: %m");
                 goto finish;
         }
@@ -102,8 +103,7 @@ int main(int argc, char *argv[]) {
         r = EXIT_SUCCESS;
 
 finish:
-        if (fd >= 0)
-                close_nointr_nofail(fd);
+        safe_close(fd);
 
         return r;
 }
diff --git a/src/resolve-host/Makefile b/src/resolve-host/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/resolve-host/resolve-host.c b/src/resolve-host/resolve-host.c
new file mode 100644 (file)
index 0000000..49049d2
--- /dev/null
@@ -0,0 +1,643 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Zbigniew Jędrzejewski-Szmek
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <arpa/inet.h>
+#include <net/if.h>
+#include <getopt.h>
+
+#include "sd-bus.h"
+#include "bus-util.h"
+#include "bus-error.h"
+#include "bus-errors.h"
+#include "in-addr-util.h"
+#include "af-list.h"
+#include "build.h"
+
+#include "resolved-dns-packet.h"
+#include "resolved-def.h"
+
+#define DNS_CALL_TIMEOUT_USEC (45*USEC_PER_SEC)
+
+static int arg_family = AF_UNSPEC;
+static int arg_ifindex = 0;
+static int arg_type = 0;
+static uint16_t arg_class = 0;
+static bool arg_legend = true;
+static uint64_t arg_flags = 0;
+
+static void print_source(int ifindex, uint64_t flags) {
+
+        if (!arg_legend)
+                return;
+
+        if (ifindex <= 0 && flags == 0)
+                return;
+
+        fputs("\n-- Information acquired via", stdout);
+
+        if (flags != 0)
+                printf(" protocol%s%s%s",
+                       flags & SD_RESOLVED_DNS ? " DNS" :"",
+                       flags & SD_RESOLVED_LLMNR_IPV4 ? " LLMNR/IPv4" : "",
+                       flags & SD_RESOLVED_LLMNR_IPV6 ? " LLMNR/IPv6" : "");
+
+        if (ifindex > 0) {
+                char ifname[IF_NAMESIZE] = "";
+                printf(" interface %s", strna(if_indextoname(ifindex, ifname)));
+        }
+
+        fputc('.', stdout);
+        fputc('\n', stdout);
+}
+
+static int resolve_host(sd_bus *bus, const char *name) {
+
+        _cleanup_bus_message_unref_ sd_bus_message *req = NULL, *reply = NULL;
+        _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+        const char *canonical = NULL;
+        unsigned c = 0;
+        int r, ifindex;
+        uint64_t flags;
+
+        assert(name);
+
+        log_debug("Resolving %s (family %s, ifindex %i).", name, af_to_name(arg_family) ?: "*", arg_ifindex);
+
+        r = sd_bus_message_new_method_call(
+                        bus,
+                        &req,
+                        "org.freedesktop.resolve1",
+                        "/org/freedesktop/resolve1",
+                        "org.freedesktop.resolve1.Manager",
+                        "ResolveHostname");
+        if (r < 0)
+                return bus_log_create_error(r);
+
+        r = sd_bus_message_set_auto_start(req, false);
+        if (r < 0)
+                return bus_log_create_error(r);
+
+        r = sd_bus_message_append(req, "isit", arg_ifindex, name, arg_family, arg_flags);
+        if (r < 0)
+                return bus_log_create_error(r);
+
+        r = sd_bus_call(bus, req, DNS_CALL_TIMEOUT_USEC, &error, &reply);
+        if (r < 0) {
+                log_error("%s: resolve call failed: %s", name, bus_error_message(&error, r));
+                return r;
+        }
+
+        r = sd_bus_message_read(reply, "i", &ifindex);
+        if (r < 0)
+                return bus_log_parse_error(r);
+
+        r = sd_bus_message_enter_container(reply, 'a', "(iay)");
+        if (r < 0)
+                return bus_log_parse_error(r);
+
+        while ((r = sd_bus_message_enter_container(reply, 'r', "iay")) > 0) {
+                const void *a;
+                int family;
+                size_t sz;
+                _cleanup_free_ char *pretty = NULL;
+                char ifname[IF_NAMESIZE] = "";
+
+                r = sd_bus_message_read(reply, "i", &family);
+                if (r < 0)
+                        return bus_log_parse_error(r);
+
+                r = sd_bus_message_read_array(reply, 'y', &a, &sz);
+                if (r < 0)
+                        return bus_log_parse_error(r);
+
+                r = sd_bus_message_exit_container(reply);
+                if (r < 0)
+                        return bus_log_parse_error(r);
+
+                if (!IN_SET(family, AF_INET, AF_INET6)) {
+                        log_debug("%s: skipping entry with family %d (%s)", name, family, af_to_name(family) ?: "unknown");
+                        continue;
+                }
+
+                if (sz != FAMILY_ADDRESS_SIZE(family)) {
+                        log_error("%s: systemd-resolved returned address of invalid size %zu for family %s",
+                                  name, sz, af_to_name(family) ?: "unknown");
+                        continue;
+                }
+
+                if (ifindex > 0) {
+                        char *t;
+
+                        t = if_indextoname(ifindex, ifname);
+                        if (!t) {
+                                log_error("Failed to resolve interface name for index %i", ifindex);
+                                continue;
+                        }
+                }
+
+                r = in_addr_to_string(family, a, &pretty);
+                if (r < 0) {
+                        log_error("%s: failed to print address: %s", name, strerror(-r));
+                        continue;
+                }
+
+                printf("%*s%s %s%s%s\n",
+                       (int) strlen(name), c == 0 ? name : "", c == 0 ? ":" : " ",
+                       pretty,
+                       isempty(ifname) ? "" : "%", ifname);
+
+                c++;
+        }
+        if (r < 0)
+                return bus_log_parse_error(r);
+
+        r = sd_bus_message_exit_container(reply);
+        if (r < 0)
+                return bus_log_parse_error(r);
+
+        r = sd_bus_message_read(reply, "st", &canonical, &flags);
+        if (r < 0)
+                return bus_log_parse_error(r);
+
+        if (!streq(name, canonical)) {
+                printf("%*s%s (%s)\n",
+                       (int) strlen(name), c == 0 ? name : "", c == 0 ? ":" : " ",
+                       canonical);
+        }
+
+        if (c == 0) {
+                log_error("%s: no addresses found", name);
+                return -ESRCH;
+        }
+
+        print_source(ifindex, flags);
+
+        return 0;
+}
+
+static int resolve_address(sd_bus *bus, int family, const union in_addr_union *address, int ifindex) {
+        _cleanup_bus_message_unref_ sd_bus_message *req = NULL, *reply = NULL;
+        _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+        _cleanup_free_ char *pretty = NULL;
+        char ifname[IF_NAMESIZE] = "";
+        uint64_t flags;
+        unsigned c = 0;
+        const char *n;
+        int r;
+
+        assert(bus);
+        assert(IN_SET(family, AF_INET, AF_INET6));
+        assert(address);
+
+        r = in_addr_to_string(family, address, &pretty);
+        if (r < 0)
+                return log_oom();
+
+        if (ifindex > 0) {
+                char *t;
+
+                t = if_indextoname(ifindex, ifname);
+                if (!t) {
+                        log_error("Failed to resolve interface name for index %i", ifindex);
+                        return -errno;
+                }
+        }
+
+        log_debug("Resolving %s%s%s.", pretty, isempty(ifname) ? "" : "%", ifname);
+
+        r = sd_bus_message_new_method_call(
+                        bus,
+                        &req,
+                        "org.freedesktop.resolve1",
+                        "/org/freedesktop/resolve1",
+                        "org.freedesktop.resolve1.Manager",
+                        "ResolveAddress");
+        if (r < 0)
+                return bus_log_create_error(r);
+
+        r = sd_bus_message_set_auto_start(req, false);
+        if (r < 0)
+                return bus_log_create_error(r);
+
+        r = sd_bus_message_append(req, "ii", ifindex, family);
+        if (r < 0)
+                return bus_log_create_error(r);
+
+        r = sd_bus_message_append_array(req, 'y', address, FAMILY_ADDRESS_SIZE(family));
+        if (r < 0)
+                return bus_log_create_error(r);
+
+        r = sd_bus_message_append(req, "t", arg_flags);
+        if (r < 0)
+                return bus_log_create_error(r);
+
+        r = sd_bus_call(bus, req, DNS_CALL_TIMEOUT_USEC, &error, &reply);
+        if (r < 0) {
+                log_error("%s: resolve call failed: %s", pretty, bus_error_message(&error, r));
+                return r;
+        }
+
+        r = sd_bus_message_read(reply, "i", &ifindex);
+        if (r < 0)
+                return bus_log_parse_error(r);
+
+        r = sd_bus_message_enter_container(reply, 'a', "s");
+        if (r < 0)
+                return bus_log_create_error(r);
+
+        while ((r = sd_bus_message_read(reply, "s", &n)) > 0) {
+
+                printf("%*s%s%s%s %s\n",
+                       (int) strlen(pretty), c == 0 ? pretty : "",
+                       isempty(ifname) ? "" : "%", ifname,
+                       c == 0 ? ":" : " ",
+                       n);
+
+                c++;
+        }
+        if (r < 0)
+                return bus_log_parse_error(r);
+
+        r = sd_bus_message_exit_container(reply);
+        if (r < 0)
+                return bus_log_parse_error(r);
+
+        r = sd_bus_message_read(reply, "t", &flags);
+        if (r < 0)
+                return bus_log_parse_error(r);
+
+        if (c == 0) {
+                log_error("%s: no names found", pretty);
+                return -ESRCH;
+        }
+
+        print_source(ifindex, flags);
+
+        return 0;
+}
+
+static int parse_address(const char *s, int *family, union in_addr_union *address, int *ifindex) {
+        const char *percent, *a;
+        int ifi = 0;
+        int r;
+
+        percent = strchr(s, '%');
+        if (percent) {
+                r = safe_atoi(percent+1, &ifi);
+                if (r < 0 || ifi <= 0) {
+                        ifi = if_nametoindex(percent+1);
+                        if (ifi <= 0)
+                                return -EINVAL;
+                }
+
+                a = strndupa(s, percent - s);
+        } else
+                a = s;
+
+        r = in_addr_from_string_auto(a, family, address);
+        if (r < 0)
+                return r;
+
+        *ifindex = ifi;
+        return 0;
+}
+
+static int resolve_record(sd_bus *bus, const char *name) {
+
+        _cleanup_bus_message_unref_ sd_bus_message *req = NULL, *reply = NULL;
+        _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+        unsigned n = 0;
+        uint64_t flags;
+        int r, ifindex;
+
+        assert(name);
+
+        log_debug("Resolving %s %s %s.", name, dns_class_to_string(arg_class), dns_type_to_string(arg_type));
+
+        r = sd_bus_message_new_method_call(
+                        bus,
+                        &req,
+                        "org.freedesktop.resolve1",
+                        "/org/freedesktop/resolve1",
+                        "org.freedesktop.resolve1.Manager",
+                        "ResolveRecord");
+        if (r < 0)
+                return bus_log_create_error(r);
+
+        r = sd_bus_message_set_auto_start(req, false);
+        if (r < 0)
+                return bus_log_create_error(r);
+
+        assert((uint16_t) arg_type == arg_type);
+        r = sd_bus_message_append(req, "isqqt", arg_ifindex, name, arg_class, arg_type, arg_flags);
+        if (r < 0)
+                return bus_log_create_error(r);
+
+        r = sd_bus_call(bus, req, DNS_CALL_TIMEOUT_USEC, &error, &reply);
+        if (r < 0) {
+                log_error("%s: resolve call failed: %s", name, bus_error_message(&error, r));
+                return r;
+        }
+
+        r = sd_bus_message_read(reply, "i", &ifindex);
+        if (r < 0)
+                return bus_log_parse_error(r);
+
+        r = sd_bus_message_enter_container(reply, 'a', "(qqay)");
+        if (r < 0)
+                return bus_log_parse_error(r);
+
+        while ((r = sd_bus_message_enter_container(reply, 'r', "qqay")) > 0) {
+                _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
+                _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
+                _cleanup_free_ char *s = NULL;
+                uint16_t c, t;
+                const void *d;
+                size_t l;
+
+                r = sd_bus_message_read(reply, "qq", &c, &t);
+                if (r < 0)
+                        return bus_log_parse_error(r);
+
+                r = sd_bus_message_read_array(reply, 'y', &d, &l);
+                if (r < 0)
+                        return bus_log_parse_error(r);
+
+                r = sd_bus_message_exit_container(reply);
+                if (r < 0)
+                        return bus_log_parse_error(r);
+
+                r = dns_packet_new(&p, DNS_PROTOCOL_DNS, 0);
+                if (r < 0)
+                        return log_oom();
+
+                r = dns_packet_append_blob(p, d, l, NULL);
+                if (r < 0)
+                        return log_oom();
+
+                r = dns_packet_read_rr(p, &rr, NULL);
+                if (r < 0) {
+                        log_error("Failed to parse RR.");
+                        return r;
+                }
+
+                r = dns_resource_record_to_string(rr, &s);
+                if (r < 0) {
+                        log_error("Failed to format RR.");
+                        return r;
+                }
+
+                printf("%s\n", s);
+                n++;
+        }
+        if (r < 0)
+                return bus_log_parse_error(r);
+
+        r = sd_bus_message_exit_container(reply);
+        if (r < 0)
+                return bus_log_parse_error(r);
+
+        r = sd_bus_message_read(reply, "t", &flags);
+        if (r < 0)
+                return bus_log_parse_error(r);
+
+        if (n == 0) {
+                log_error("%s: no records found", name);
+                return -ESRCH;
+        }
+
+        print_source(ifindex, flags);
+
+        return 0;
+}
+
+static void help_dns_types(void) {
+        int i;
+        const char *t;
+
+        if (arg_legend)
+                puts("Known dns types:");
+        for (i = 0; i < _DNS_TYPE_MAX; i++) {
+                t = dns_type_to_string(i);
+                if (t)
+                        puts(t);
+        }
+}
+
+static void help_dns_classes(void) {
+        int i;
+        const char *t;
+
+        if (arg_legend)
+                puts("Known dns classes:");
+        for (i = 0; i < _DNS_CLASS_MAX; i++) {
+                t = dns_class_to_string(i);
+                if (t)
+                        puts(t);
+        }
+}
+
+static void help(void) {
+        printf("%s [OPTIONS...]\n\n"
+               "Resolve IPv4 or IPv6 addresses.\n\n"
+               "  -h --help               Show this help\n"
+               "     --version            Show package version\n"
+               "  -4                      Resolve IPv4 addresses\n"
+               "  -6                      Resolve IPv6 addresses\n"
+               "  -i INTERFACE            Look on interface\n"
+               "  -p --protocol=PROTOCOL  Look via protocol\n"
+               "  -t --type=TYPE          Query RR with DNS type\n"
+               "  -c --class=CLASS        Query RR with DNS class\n"
+               "     --legend[=BOOL]      Do [not] print column headers\n"
+               , program_invocation_short_name);
+}
+
+static int parse_argv(int argc, char *argv[]) {
+        enum {
+                ARG_VERSION = 0x100,
+                ARG_LEGEND,
+        };
+
+        static const struct option options[] = {
+                { "help",      no_argument,       NULL, 'h'           },
+                { "version",   no_argument,       NULL, ARG_VERSION   },
+                { "type",      required_argument, NULL, 't'           },
+                { "class",     required_argument, NULL, 'c'           },
+                { "legend", optional_argument,    NULL, ARG_LEGEND    },
+                { "protocol",  required_argument, NULL, 'p'           },
+                {}
+        };
+
+        int c, r;
+
+        assert(argc >= 0);
+        assert(argv);
+
+        while ((c = getopt_long(argc, argv, "h46i:t:c:p:", options, NULL)) >= 0)
+                switch(c) {
+
+                case 'h':
+                        help();
+                        return 0; /* done */;
+
+                case ARG_VERSION:
+                        puts(PACKAGE_STRING);
+                        puts(SYSTEMD_FEATURES);
+                        return 0 /* done */;
+
+                case '4':
+                        arg_family = AF_INET;
+                        break;
+
+                case '6':
+                        arg_family = AF_INET6;
+                        break;
+
+                case 'i':
+                        arg_ifindex = if_nametoindex(optarg);
+                        if (arg_ifindex <= 0) {
+                                log_error("Unknown interfaces %s: %m", optarg);
+                                return -errno;
+                        }
+                        break;
+
+                case 't':
+                        if (streq(optarg, "help")) {
+                                help_dns_types();
+                                return 0;
+                        }
+
+                        arg_type = dns_type_from_string(optarg);
+                        if (arg_type < 0) {
+                                log_error("Failed to parse RR record type %s", optarg);
+                                return arg_type;
+                        }
+                        assert(arg_type > 0 && (uint16_t) arg_type == arg_type);
+
+                        break;
+
+                case 'c':
+                        if (streq(optarg, "help")) {
+                                help_dns_classes();
+                                return 0;
+                        }
+
+                        r = dns_class_from_string(optarg, &arg_class);
+                        if (r < 0) {
+                                log_error("Failed to parse RR record class %s", optarg);
+                                return r;
+                        }
+
+                        break;
+
+                case ARG_LEGEND:
+                        if (optarg) {
+                                r = parse_boolean(optarg);
+                                if (r < 0) {
+                                        log_error("Failed to parse --legend= argument");
+                                        return r;
+                                }
+
+                                arg_legend = !!r;
+                        } else
+                                arg_legend = false;
+                        break;
+
+                case 'p':
+                        if (streq(optarg, "dns"))
+                                arg_flags |= SD_RESOLVED_DNS;
+                        else if (streq(optarg, "llmnr"))
+                                arg_flags |= SD_RESOLVED_LLMNR;
+                        else if (streq(optarg, "llmnr-ipv4"))
+                                arg_flags |= SD_RESOLVED_LLMNR_IPV4;
+                        else if (streq(optarg, "llmnr-ipv6"))
+                                arg_flags |= SD_RESOLVED_LLMNR_IPV6;
+                        else {
+                                log_error("Unknown protocol specifier: %s", optarg);
+                                return -EINVAL;
+                        }
+
+                        break;
+
+                case '?':
+                        return -EINVAL;
+
+                default:
+                        assert_not_reached("Unhandled option");
+                }
+
+        if (arg_type == 0 && arg_class != 0) {
+                log_error("--class= may only be used in conjunction with --type=");
+                return -EINVAL;
+        }
+
+        if (arg_type != 0 && arg_class == 0)
+                arg_class = DNS_CLASS_IN;
+
+        return 1 /* work to do */;
+}
+
+int main(int argc, char **argv) {
+        _cleanup_bus_close_unref_ sd_bus *bus = NULL;
+        int r;
+
+        log_parse_environment();
+        log_open();
+
+        r = parse_argv(argc, argv);
+        if (r <= 0)
+                goto finish;
+
+        if (optind >= argc) {
+                log_error("No arguments passed");
+                r = -EINVAL;
+                goto finish;
+        }
+
+        r = sd_bus_open_system(&bus);
+        if (r < 0) {
+                log_error("sd_bus_open_system: %s", strerror(-r));
+                goto finish;
+        }
+
+        while (argv[optind]) {
+                int family, ifindex, k;
+                union in_addr_union a;
+
+                if (arg_type != 0)
+                        k = resolve_record(bus, argv[optind]);
+                else {
+                        k = parse_address(argv[optind], &family, &a, &ifindex);
+                        if (k >= 0)
+                                k = resolve_address(bus, family, &a, ifindex);
+                        else
+                                k = resolve_host(bus, argv[optind]);
+                }
+
+                if (r == 0)
+                        r = k;
+
+                optind++;
+        }
+
+finish:
+        return r == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
+}
diff --git a/src/resolve/.gitignore b/src/resolve/.gitignore
new file mode 100644 (file)
index 0000000..f083592
--- /dev/null
@@ -0,0 +1,6 @@
+/resolved-gperf.c
+/resolved.conf
+/dns_type-from-name.gperf
+/dns_type-from-name.h
+/dns_type-list.txt
+/dns_type-to-name.h
diff --git a/src/resolve/Makefile b/src/resolve/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/resolve/dns-type.c b/src/resolve/dns-type.c
new file mode 100644 (file)
index 0000000..a3e7408
--- /dev/null
@@ -0,0 +1,45 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Zbigniew Jędrzejewski-Szmek
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "dns-type.h"
+
+typedef const struct {
+        uint16_t type;
+        const char *name;
+} dns_type;
+
+static const struct dns_type_name *
+lookup_dns_type (register const char *str, register unsigned int len);
+
+#include "dns_type-from-name.h"
+#include "dns_type-to-name.h"
+
+int dns_type_from_string(const char *s) {
+        const struct dns_type_name *sc;
+
+        assert(s);
+
+        sc = lookup_dns_type(s, strlen(s));
+        if (!sc)
+                return _DNS_TYPE_INVALID;
+
+        return sc->id;
+}
diff --git a/src/resolve/dns-type.h b/src/resolve/dns-type.h
new file mode 100644 (file)
index 0000000..86951d2
--- /dev/null
@@ -0,0 +1,120 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Zbigniew Jędrzejewski-Szmek
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#pragma once
+
+#include "macro.h"
+
+const char *dns_type_to_string(int type);
+int dns_type_from_string(const char *s);
+
+/* DNS record types, taken from
+ * http://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml.
+ */
+enum {
+        /* Normal records */
+        DNS_TYPE_A          = 0x01,
+        DNS_TYPE_NS,
+        DNS_TYPE_MD,
+        DNS_TYPE_MF,
+        DNS_TYPE_CNAME,
+        DNS_TYPE_SOA,
+        DNS_TYPE_MB,
+        DNS_TYPE_MG,
+        DNS_TYPE_MR,
+        DNS_TYPE_NULL,
+        DNS_TYPE_WKS,
+        DNS_TYPE_PTR,
+        DNS_TYPE_HINFO,
+        DNS_TYPE_MINFO,
+        DNS_TYPE_MX,
+        DNS_TYPE_TXT,
+        DNS_TYPE_RP,
+        DNS_TYPE_AFSDB,
+        DNS_TYPE_X25,
+        DNS_TYPE_ISDN,
+        DNS_TYPE_RT,
+        DNS_TYPE_NSAP,
+        DNS_TYPE_NSAP_PTR,
+        DNS_TYPE_SIG,
+        DNS_TYPE_KEY,
+        DNS_TYPE_PX,
+        DNS_TYPE_GPOS,
+        DNS_TYPE_AAAA,
+        DNS_TYPE_LOC,
+        DNS_TYPE_NXT,
+        DNS_TYPE_EID,
+        DNS_TYPE_NIMLOC,
+        DNS_TYPE_SRV,
+        DNS_TYPE_ATMA,
+        DNS_TYPE_NAPTR,
+        DNS_TYPE_KX,
+        DNS_TYPE_CERT,
+        DNS_TYPE_A6,
+        DNS_TYPE_DNAME,
+        DNS_TYPE_SINK,
+        DNS_TYPE_OPT,          /* EDNS0 option */
+        DNS_TYPE_APL,
+        DNS_TYPE_DS,
+        DNS_TYPE_SSHFP,
+        DNS_TYPE_IPSECKEY,
+        DNS_TYPE_RRSIG,
+        DNS_TYPE_NSEC,
+        DNS_TYPE_DNSKEY,
+        DNS_TYPE_DHCID,
+        DNS_TYPE_NSEC3,
+        DNS_TYPE_NSEC3PARAM,
+        DNS_TYPE_TLSA,
+
+        DNS_TYPE_HIP        = 0x37,
+        DNS_TYPE_NINFO,
+        DNS_TYPE_RKEY,
+        DNS_TYPE_TALINK,
+        DNS_TYPE_CDS,
+        DNS_TYPE_CDNSKEY,
+
+        DNS_TYPE_SPF        = 0x63,
+        DNS_TYPE_NID,
+        DNS_TYPE_L32,
+        DNS_TYPE_L64,
+        DNS_TYPE_LP,
+        DNS_TYPE_EUI48,
+        DNS_TYPE_EUI64,
+
+        DNS_TYPE_TKEY       = 0xF9,
+        DNS_TYPE_TSIG,
+        DNS_TYPE_IXFR,
+        DNS_TYPE_AXFR,
+        DNS_TYPE_MAILB,
+        DNS_TYPE_MAILA,
+        DNS_TYPE_ANY,
+        DNS_TYPE_URI,
+        DNS_TYPE_CAA,
+        DNS_TYPE_TA         = 0x8000,
+        DNS_TYPE_DLV,
+
+        _DNS_TYPE_MAX,
+        _DNS_TYPE_INVALID = -1
+};
+
+assert_cc(DNS_TYPE_SSHFP == 44);
+assert_cc(DNS_TYPE_TLSA == 52);
+assert_cc(DNS_TYPE_ANY == 255);
diff --git a/src/resolve/org.freedesktop.resolve1.conf b/src/resolve/org.freedesktop.resolve1.conf
new file mode 100644 (file)
index 0000000..25b0977
--- /dev/null
@@ -0,0 +1,27 @@
+<?xml version="1.0"?> <!--*-nxml-*-->
+<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+        "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+
+<!--
+  This file is part of systemd.
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+-->
+
+<busconfig>
+
+        <policy user="systemd-resolve">
+                <allow own="org.freedesktop.resolve1"/>
+                <allow send_destination="org.freedesktop.resolve1"/>
+                <allow receive_sender="org.freedesktop.resolve1"/>
+        </policy>
+
+        <policy context="default">
+                <allow send_destination="org.freedesktop.resolve1"/>
+                <allow receive_sender="org.freedesktop.resolve1"/>
+        </policy>
+
+</busconfig>
diff --git a/src/resolve/org.freedesktop.resolve1.service b/src/resolve/org.freedesktop.resolve1.service
new file mode 100644 (file)
index 0000000..7ac5c32
--- /dev/null
@@ -0,0 +1,12 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[D-BUS Service]
+Name=org.freedesktop.resolve1
+Exec=/bin/false
+User=root
+SystemdService=dbus-org.freedesktop.resolve1.service
diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c
new file mode 100644 (file)
index 0000000..0029023
--- /dev/null
@@ -0,0 +1,761 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "bus-errors.h"
+#include "bus-util.h"
+
+#include "resolved-dns-domain.h"
+#include "resolved-bus.h"
+#include "resolved-def.h"
+
+static int reply_query_state(DnsQuery *q) {
+        _cleanup_free_ char *ip = NULL;
+        const char *name;
+        int r;
+
+        if (q->request_hostname)
+                name = q->request_hostname;
+        else {
+                r = in_addr_to_string(q->request_family, &q->request_address, &ip);
+                if (r < 0)
+                        return r;
+
+                name = ip;
+        }
+
+        switch (q->state) {
+
+        case DNS_TRANSACTION_NO_SERVERS:
+                return sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_NAME_SERVERS, "No appropriate name servers or networks for name found");
+
+        case DNS_TRANSACTION_TIMEOUT:
+                return sd_bus_reply_method_errorf(q->request, SD_BUS_ERROR_TIMEOUT, "Query timed out");
+
+        case DNS_TRANSACTION_ATTEMPTS_MAX_REACHED:
+                return sd_bus_reply_method_errorf(q->request, SD_BUS_ERROR_TIMEOUT, "All attempts to contact name servers or networks failed");
+
+        case DNS_TRANSACTION_INVALID_REPLY:
+                return sd_bus_reply_method_errorf(q->request, BUS_ERROR_INVALID_REPLY, "Received invalid reply");
+
+        case DNS_TRANSACTION_RESOURCES:
+                return sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_RESOURCES, "Not enough resources");
+
+        case DNS_TRANSACTION_ABORTED:
+                return sd_bus_reply_method_errorf(q->request, BUS_ERROR_ABORTED, "Query aborted");
+
+        case DNS_TRANSACTION_FAILURE: {
+                _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+
+                if (q->answer_rcode == DNS_RCODE_NXDOMAIN)
+                        sd_bus_error_setf(&error, _BUS_ERROR_DNS "NXDOMAIN", "'%s' not found", name);
+                else {
+                        const char *rc, *n;
+                        char p[3]; /* the rcode is 4 bits long */
+
+                        rc = dns_rcode_to_string(q->answer_rcode);
+                        if (!rc) {
+                                sprintf(p, "%i", q->answer_rcode);
+                                rc = p;
+                        }
+
+                        n = strappenda(_BUS_ERROR_DNS, rc);
+                        sd_bus_error_setf(&error, n, "Could not resolve '%s', server or network returned error %s", name, rc);
+                }
+
+                return sd_bus_reply_method_error(q->request, &error);
+        }
+
+        case DNS_TRANSACTION_NULL:
+        case DNS_TRANSACTION_PENDING:
+        case DNS_TRANSACTION_SUCCESS:
+        default:
+                assert_not_reached("Impossible state");
+        }
+}
+
+static int append_address(sd_bus_message *reply, DnsResourceRecord *rr) {
+        int r;
+
+        assert(reply);
+        assert(rr);
+
+        r = sd_bus_message_open_container(reply, 'r', "iay");
+        if (r < 0)
+                return r;
+
+        if (rr->key->type == DNS_TYPE_A) {
+                r = sd_bus_message_append(reply, "i", AF_INET);
+                if (r < 0)
+                        return r;
+
+                r = sd_bus_message_append_array(reply, 'y', &rr->a.in_addr, sizeof(struct in_addr));
+
+        } else if (rr->key->type == DNS_TYPE_AAAA) {
+                r = sd_bus_message_append(reply, "i", AF_INET6);
+                if (r < 0)
+                        return r;
+
+                r = sd_bus_message_append_array(reply, 'y', &rr->aaaa.in6_addr, sizeof(struct in6_addr));
+        } else
+                return -EAFNOSUPPORT;
+
+        if (r < 0)
+                return r;
+
+        r = sd_bus_message_close_container(reply);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+static void bus_method_resolve_hostname_complete(DnsQuery *q) {
+        _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *cname = NULL, *canonical = NULL;
+        _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
+        _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
+        unsigned added = 0, i;
+        int r;
+
+        assert(q);
+
+        if (q->state != DNS_TRANSACTION_SUCCESS) {
+                r = reply_query_state(q);
+                goto finish;
+        }
+
+        r = sd_bus_message_new_method_return(q->request, &reply);
+        if (r < 0)
+                goto finish;
+
+        r = sd_bus_message_append(reply, "i", q->answer_ifindex);
+        if (r < 0)
+                goto finish;
+
+        r = sd_bus_message_open_container(reply, 'a', "(iay)");
+        if (r < 0)
+                goto finish;
+
+        if (q->answer) {
+                answer = dns_answer_ref(q->answer);
+
+                for (i = 0; i < answer->n_rrs; i++) {
+                        r = dns_question_matches_rr(q->question, answer->rrs[i]);
+                        if (r < 0)
+                                goto finish;
+                        if (r == 0) {
+                                /* Hmm, if this is not an address record,
+                                   maybe it's a cname? If so, remember this */
+                                r = dns_question_matches_cname(q->question, answer->rrs[i]);
+                                if (r < 0)
+                                        goto finish;
+                                if (r > 0)
+                                        cname = dns_resource_record_ref(answer->rrs[i]);
+
+                                continue;
+                        }
+
+                        r = append_address(reply, answer->rrs[i]);
+                        if (r < 0)
+                                goto finish;
+
+                        if (!canonical)
+                                canonical = dns_resource_record_ref(answer->rrs[i]);
+
+                        added ++;
+                }
+        }
+
+        if (added <= 0) {
+                if (!cname) {
+                        r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_SUCH_RR, "'%s' does not have any RR of requested type", q->request_hostname);
+                        goto finish;
+                }
+
+                /* This has a cname? Then update the query with the
+                 * new cname. */
+                r = dns_query_cname_redirect(q, cname->cname.name);
+                if (r < 0) {
+                        if (r == -ELOOP)
+                                r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_CNAME_LOOP, "CNAME loop on '%s'", q->request_hostname);
+                        else
+                                r = sd_bus_reply_method_errno(q->request, -r, NULL);
+
+                        goto finish;
+                }
+
+                /* Before we restart the query, let's see if any of
+                 * the RRs we already got already answers our query */
+                for (i = 0; i < answer->n_rrs; i++) {
+                        r = dns_question_matches_rr(q->question, answer->rrs[i]);
+                        if (r < 0)
+                                goto finish;
+                        if (r == 0)
+                                continue;
+
+                        r = append_address(reply, answer->rrs[i]);
+                        if (r < 0)
+                                goto finish;
+
+                        if (!canonical)
+                                canonical = dns_resource_record_ref(answer->rrs[i]);
+
+                        added++;
+                }
+
+                /* If we didn't find anything, then let's restart the
+                 * query, this time with the cname */
+                if (added <= 0) {
+                        r = dns_query_go(q);
+                        if (r == -ESRCH) {
+                                r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_NAME_SERVERS, "No appropriate name servers or networks for name found");
+                                goto finish;
+                        }
+                        if (r < 0) {
+                                r = sd_bus_reply_method_errno(q->request, -r, NULL);
+                                goto finish;
+                        }
+
+                        return;
+                }
+        }
+
+        r = sd_bus_message_close_container(reply);
+        if (r < 0)
+                goto finish;
+
+        /* Return the precise spelling and uppercasing reported by the server */
+        assert(canonical);
+        r = sd_bus_message_append(reply, "st", DNS_RESOURCE_KEY_NAME(canonical->key), SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family));
+        if (r < 0)
+                goto finish;
+
+        r = sd_bus_send(q->manager->bus, reply, NULL);
+
+finish:
+        if (r < 0) {
+                log_error("Failed to send hostname reply: %s", strerror(-r));
+                sd_bus_reply_method_errno(q->request, -r, NULL);
+        }
+
+        dns_query_free(q);
+}
+
+static int check_ifindex_flags(int ifindex, uint64_t *flags, sd_bus_error *error) {
+        assert(flags);
+
+        if (ifindex < 0)
+                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid interface index");
+
+        if (*flags & ~SD_RESOLVED_FLAGS_ALL)
+                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid flags parameter");
+
+        if (*flags == 0)
+                *flags = SD_RESOLVED_FLAGS_DEFAULT;
+
+        return 0;
+}
+
+static int bus_method_resolve_hostname(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
+        _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
+        Manager *m = userdata;
+        const char *hostname;
+        int family, ifindex;
+        uint64_t flags;
+        DnsQuery *q;
+        int r;
+
+        assert(bus);
+        assert(message);
+        assert(m);
+
+        r = sd_bus_message_read(message, "isit", &ifindex, &hostname, &family, &flags);
+        if (r < 0)
+                return r;
+
+        if (!IN_SET(family, AF_INET, AF_INET6, AF_UNSPEC))
+                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown address family %i", family);
+
+        r = dns_name_normalize(hostname, NULL);
+        if (r < 0)
+                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid hostname '%s'", hostname);
+
+        r = check_ifindex_flags(ifindex, &flags, error);
+        if (r < 0)
+                return r;
+
+        question = dns_question_new(family == AF_UNSPEC ? 2 : 1);
+        if (!question)
+                return -ENOMEM;
+
+        if (family != AF_INET6) {
+                _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
+
+                key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, hostname);
+                if (!key)
+                        return -ENOMEM;
+
+                r = dns_question_add(question, key);
+                if (r < 0)
+                        return r;
+        }
+
+        if (family != AF_INET) {
+                _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
+
+                key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_AAAA, hostname);
+                if (!key)
+                        return -ENOMEM;
+
+                r = dns_question_add(question, key);
+                if (r < 0)
+                        return r;
+        }
+
+        r = dns_query_new(m, &q, question, ifindex, flags);
+        if (r < 0)
+                return r;
+
+        q->request = sd_bus_message_ref(message);
+        q->request_family = family;
+        q->request_hostname = hostname;
+        q->complete = bus_method_resolve_hostname_complete;
+
+        r = dns_query_bus_track(q, bus, message);
+        if (r < 0)
+                return r;
+
+        r = dns_query_go(q);
+        if (r < 0) {
+                dns_query_free(q);
+
+                if (r == -ESRCH)
+                        sd_bus_error_setf(error, BUS_ERROR_NO_NAME_SERVERS, "No appropriate name servers or networks for name found");
+
+                return r;
+        }
+
+        return 1;
+}
+
+static void bus_method_resolve_address_complete(DnsQuery *q) {
+        _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
+        _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
+        unsigned added = 0, i;
+        int r;
+
+        assert(q);
+
+        if (q->state != DNS_TRANSACTION_SUCCESS) {
+                r = reply_query_state(q);
+                goto finish;
+        }
+
+        r = sd_bus_message_new_method_return(q->request, &reply);
+        if (r < 0)
+                goto finish;
+
+        r = sd_bus_message_append(reply, "i", q->answer_ifindex);
+        if (r < 0)
+                goto finish;
+
+        r = sd_bus_message_open_container(reply, 'a', "s");
+        if (r < 0)
+                goto finish;
+
+        if (q->answer) {
+                answer = dns_answer_ref(q->answer);
+
+                for (i = 0; i < answer->n_rrs; i++) {
+                        r = dns_question_matches_rr(q->question, answer->rrs[i]);
+                        if (r < 0)
+                                goto finish;
+                        if (r == 0)
+                                continue;
+
+                        r = sd_bus_message_append(reply, "s", answer->rrs[i]->ptr.name);
+                        if (r < 0)
+                                goto finish;
+
+                        added ++;
+                }
+        }
+
+        if (added <= 0) {
+                _cleanup_free_ char *ip = NULL;
+
+                in_addr_to_string(q->request_family, &q->request_address, &ip);
+
+                r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_SUCH_RR, "Address '%s' does not have any RR of requested type", ip);
+                goto finish;
+        }
+
+        r = sd_bus_message_close_container(reply);
+        if (r < 0)
+                goto finish;
+
+        r = sd_bus_message_append(reply, "t", SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family));
+        if (r < 0)
+                goto finish;
+
+        r = sd_bus_send(q->manager->bus, reply, NULL);
+
+finish:
+        if (r < 0) {
+                log_error("Failed to send address reply: %s", strerror(-r));
+                sd_bus_reply_method_errno(q->request, -r, NULL);
+        }
+
+        dns_query_free(q);
+}
+
+static int bus_method_resolve_address(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
+        _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
+        _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
+        _cleanup_free_ char *reverse = NULL;
+        Manager *m = userdata;
+        int family, ifindex;
+        uint64_t flags;
+        const void *d;
+        DnsQuery *q;
+        size_t sz;
+        int r;
+
+        assert(bus);
+        assert(message);
+        assert(m);
+
+        r = sd_bus_message_read(message, "ii", &ifindex, &family);
+        if (r < 0)
+                return r;
+
+        if (!IN_SET(family, AF_INET, AF_INET6))
+                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown address family %i", family);
+
+        r = sd_bus_message_read_array(message, 'y', &d, &sz);
+        if (r < 0)
+                return r;
+
+        if (sz != FAMILY_ADDRESS_SIZE(family))
+                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid address size");
+
+        r = sd_bus_message_read(message, "t", &flags);
+        if (r < 0)
+                return r;
+
+        r = check_ifindex_flags(ifindex, &flags, error);
+        if (r < 0)
+                return r;
+
+        r = dns_name_reverse(family, d, &reverse);
+        if (r < 0)
+                return r;
+
+        question = dns_question_new(1);
+        if (!question)
+                return -ENOMEM;
+
+        key = dns_resource_key_new_consume(DNS_CLASS_IN, DNS_TYPE_PTR, reverse);
+        if (!key)
+                return -ENOMEM;
+
+        reverse = NULL;
+
+        r = dns_question_add(question, key);
+        if (r < 0)
+                return r;
+
+        r = dns_query_new(m, &q, question, ifindex, flags);
+        if (r < 0)
+                return r;
+
+        q->request = sd_bus_message_ref(message);
+        q->request_family = family;
+        memcpy(&q->request_address, d, sz);
+        q->complete = bus_method_resolve_address_complete;
+
+        r = dns_query_bus_track(q, bus, message);
+        if (r < 0)
+                return r;
+
+        r = dns_query_go(q);
+        if (r < 0) {
+                dns_query_free(q);
+
+                if (r == -ESRCH)
+                        sd_bus_error_setf(error, BUS_ERROR_NO_NAME_SERVERS, "No appropriate name servers or networks for name found");
+
+                return r;
+        }
+
+        return 1;
+}
+
+static void bus_method_resolve_record_complete(DnsQuery *q) {
+        _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
+        _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
+        unsigned added = 0, i;
+        int r;
+
+        assert(q);
+
+        if (q->state != DNS_TRANSACTION_SUCCESS) {
+                r = reply_query_state(q);
+                goto finish;
+        }
+
+        r = sd_bus_message_new_method_return(q->request, &reply);
+        if (r < 0)
+                goto finish;
+
+        r = sd_bus_message_append(reply, "i", q->answer_ifindex);
+        if (r < 0)
+                goto finish;
+
+        r = sd_bus_message_open_container(reply, 'a', "(qqay)");
+        if (r < 0)
+                goto finish;
+
+        if (q->answer) {
+                answer = dns_answer_ref(q->answer);
+
+                for (i = 0; i < answer->n_rrs; i++) {
+                        _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
+                        size_t start;
+
+                        r = dns_question_matches_rr(q->question, answer->rrs[i]);
+                        if (r < 0)
+                                goto finish;
+                        if (r == 0)
+                                continue;
+
+                        r = dns_packet_new(&p, DNS_PROTOCOL_DNS, 0);
+                        if (r < 0)
+                                goto finish;
+
+                        r = dns_packet_append_rr(p, answer->rrs[i], &start);
+                        if (r < 0)
+                                goto finish;
+
+                        r = sd_bus_message_open_container(reply, 'r', "qqay");
+                        if (r < 0)
+                                goto finish;
+
+                        r = sd_bus_message_append(reply, "qq", answer->rrs[i]->key->class, answer->rrs[i]->key->type);
+                        if (r < 0)
+                                goto finish;
+
+                        r = sd_bus_message_append_array(reply, 'y', DNS_PACKET_DATA(p) + start, p->size - start);
+                        if (r < 0)
+                                goto finish;
+
+                        r = sd_bus_message_close_container(reply);
+                        if (r < 0)
+                                goto finish;
+
+                        added ++;
+                }
+        }
+
+        if (added <= 0) {
+                r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_SUCH_RR, "Name '%s' does not have any RR of the requested type", q->request_hostname);
+                goto finish;
+        }
+
+        r = sd_bus_message_close_container(reply);
+        if (r < 0)
+                goto finish;
+
+        r = sd_bus_message_append(reply, "t", SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family));
+        if (r < 0)
+                goto finish;
+
+        r = sd_bus_send(q->manager->bus, reply, NULL);
+
+finish:
+        if (r < 0) {
+                log_error("Failed to send record reply: %s", strerror(-r));
+                sd_bus_reply_method_errno(q->request, -r, NULL);
+        }
+
+        dns_query_free(q);
+}
+
+static int bus_method_resolve_record(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
+        _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
+        _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
+        Manager *m = userdata;
+        uint16_t class, type;
+        const char *name;
+        int r, ifindex;
+        uint64_t flags;
+        DnsQuery *q;
+
+        assert(bus);
+        assert(message);
+        assert(m);
+
+        r = sd_bus_message_read(message, "isqqt", &ifindex, &name, &class, &type, &flags);
+        if (r < 0)
+                return r;
+
+        r = dns_name_normalize(name, NULL);
+        if (r < 0)
+                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid name '%s'", name);
+
+        r = check_ifindex_flags(ifindex, &flags, error);
+        if (r < 0)
+                return r;
+
+        question = dns_question_new(1);
+        if (!question)
+                return -ENOMEM;
+
+        key = dns_resource_key_new(class, type, name);
+        if (!key)
+                return -ENOMEM;
+
+        r = dns_question_add(question, key);
+        if (r < 0)
+                return r;
+
+        r = dns_query_new(m, &q, question, ifindex, flags);
+        if (r < 0)
+                return r;
+
+        q->request = sd_bus_message_ref(message);
+        q->request_hostname = name;
+        q->complete = bus_method_resolve_record_complete;
+
+        r = dns_query_bus_track(q, bus, message);
+        if (r < 0)
+                return r;
+
+        r = dns_query_go(q);
+        if (r < 0) {
+                dns_query_free(q);
+
+                if (r == -ESRCH)
+                        sd_bus_error_setf(error, BUS_ERROR_NO_NAME_SERVERS, "No appropriate name servers or networks for name found");
+
+                return r;
+        }
+
+        return 1;
+}
+
+static const sd_bus_vtable resolve_vtable[] = {
+        SD_BUS_VTABLE_START(0),
+        SD_BUS_METHOD("ResolveHostname", "isit", "ia(iay)st", bus_method_resolve_hostname, SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("ResolveAddress", "iiayt", "iast", bus_method_resolve_address, SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("ResolveRecord", "isqqt", "ia(qqay)t", bus_method_resolve_record, SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_VTABLE_END,
+};
+
+static int on_bus_retry(sd_event_source *s, usec_t usec, void *userdata) {
+        Manager *m = userdata;
+
+        assert(s);
+        assert(m);
+
+        m->bus_retry_event_source = sd_event_source_unref(m->bus_retry_event_source);
+
+        manager_connect_bus(m);
+        return 0;
+}
+
+static int match_prepare_for_sleep(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
+        Manager *m = userdata;
+        int b, r;
+
+        assert(bus);
+        assert(bus);
+
+        r = sd_bus_message_read(message, "b", &b);
+        if (r < 0) {
+                log_debug("Failed to parse PrepareForSleep signal: %s", strerror(-r));
+                return 0;
+        }
+
+        if (b)
+                return 0;
+
+        log_debug("Coming back from suspend, verifying all RRs...");
+
+        manager_verify_all(m);
+        return 0;
+}
+
+int manager_connect_bus(Manager *m) {
+        int r;
+
+        assert(m);
+
+        if (m->bus)
+                return 0;
+
+        r = sd_bus_default_system(&m->bus);
+        if (r < 0) {
+                /* We failed to connect? Yuck, we must be in early
+                 * boot. Let's try in 5s again. As soon as we have
+                 * kdbus we can stop doing this... */
+
+                log_debug("Failed to connect to bus, trying again in 5s: %s", strerror(-r));
+
+                r = sd_event_add_time(m->event, &m->bus_retry_event_source, CLOCK_MONOTONIC, now(CLOCK_MONOTONIC) + 5*USEC_PER_SEC, 0, on_bus_retry, m);
+                if (r < 0) {
+                        log_error("Failed to install bus reconnect time event: %s", strerror(-r));
+                        return r;
+                }
+
+                return 0;
+        }
+
+        r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/resolve1", "org.freedesktop.resolve1.Manager", resolve_vtable, m);
+        if (r < 0) {
+                log_error("Failed to register object: %s", strerror(-r));
+                return r;
+        }
+
+        r = sd_bus_request_name(m->bus, "org.freedesktop.resolve1", 0);
+        if (r < 0) {
+                log_error("Failed to register name: %s", strerror(-r));
+                return r;
+        }
+
+        r = sd_bus_attach_event(m->bus, m->event, 0);
+        if (r < 0) {
+                log_error("Failed to attach bus to event loop: %s", strerror(-r));
+                return r;
+        }
+
+        r = sd_bus_add_match(m->bus, &m->prepare_for_sleep_slot,
+                             "type='signal',"
+                             "sender='org.freedesktop.login1',"
+                             "interface='org.freedesktop.login1.Manager',"
+                             "member='PrepareForSleep',"
+                             "path='/org/freedesktop/login1'",
+                             match_prepare_for_sleep,
+                             m);
+        if (r < 0)
+                log_error("Failed to add match for PrepareForSleep: %s", strerror(-r));
+
+        return 0;
+}
similarity index 87%
rename from src/core/tcpwrap.h
rename to src/resolve/resolved-bus.h
index 3353b65..1e72891 100644 (file)
@@ -5,7 +5,7 @@
 /***
   This file is part of systemd.
 
-  Copyright 2010 Lennart Poettering
+  Copyright 2014 Lennart Poettering
 
   systemd is free software; you can redistribute it and/or modify it
   under the terms of the GNU Lesser General Public License as published by
@@ -21,6 +21,6 @@
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
-#include <stdbool.h>
+#include "resolved-manager.h"
 
-bool socket_tcpwrap(int fd, const char *name);
+int manager_connect_bus(Manager *m);
diff --git a/src/resolve/resolved-conf.c b/src/resolve/resolved-conf.c
new file mode 100644 (file)
index 0000000..63e87f8
--- /dev/null
@@ -0,0 +1,154 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Tom Gundersen <teg@jklm.no>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+ ***/
+
+#include "conf-parser.h"
+
+#include "resolved-conf.h"
+
+int manager_parse_dns_server(Manager *m, DnsServerType type, const char *string) {
+        const char *word, *state;
+        size_t length;
+        DnsServer *first;
+        int r;
+
+        assert(m);
+        assert(string);
+
+        first = type == DNS_SERVER_FALLBACK ? m->fallback_dns_servers : m->dns_servers;
+
+        FOREACH_WORD_QUOTED(word, length, string, state) {
+                char buffer[length+1];
+                int family;
+                union in_addr_union addr;
+                bool found = false;
+                DnsServer *s;
+
+                memcpy(buffer, word, length);
+                buffer[length] = 0;
+
+                r = in_addr_from_string_auto(buffer, &family, &addr);
+                if (r < 0) {
+                        log_warning("Ignoring invalid DNS address '%s'", buffer);
+                        continue;
+                }
+
+                /* Filter out duplicates */
+                LIST_FOREACH(servers, s, first)
+                        if (s->family == family && in_addr_equal(family, &s->address, &addr)) {
+                                found = true;
+                                break;
+                        }
+
+                if (found)
+                        continue;
+
+                r = dns_server_new(m, NULL, type, NULL, family, &addr);
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
+int config_parse_dnsv(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        Manager *m = userdata;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(m);
+
+        if (isempty(rvalue))
+                /* Empty assignment means clear the list */
+                manager_flush_dns_servers(m, ltype);
+        else {
+                /* Otherwise add to the list */
+                r = manager_parse_dns_server(m, ltype, rvalue);
+                if (r < 0) {
+                        log_syntax(unit, LOG_ERR, filename, line, -r, "Failed to parse DNS server string '%s'. Ignoring.", rvalue);
+                        return 0;
+                }
+        }
+
+        /* If we have a manual setting, then we stop reading
+         * /etc/resolv.conf */
+        if (ltype == DNS_SERVER_SYSTEM)
+                m->read_resolv_conf = false;
+
+        return 0;
+}
+
+int config_parse_support(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        Manager *m = userdata;
+        Support support, *v = data;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(m);
+
+        support = support_from_string(rvalue);
+        if (support < 0) {
+                r = parse_boolean(rvalue);
+                if (r < 0) {
+                        log_syntax(unit, LOG_ERR, filename, line, -r, "Failed to parse support level '%s'. Ignoring.", rvalue);
+                        return 0;
+                }
+
+                support = r ? SUPPORT_YES : SUPPORT_NO;
+        }
+
+        *v = support;
+        return 0;
+}
+
+int manager_parse_config_file(Manager *m) {
+        assert(m);
+
+        return config_parse(NULL, "/etc/systemd/resolved.conf", NULL,
+                            "Resolve\0",
+                            config_item_perf_lookup, resolved_gperf_lookup,
+                            false, false, true, m);
+}
diff --git a/src/resolve/resolved-conf.h b/src/resolve/resolved-conf.h
new file mode 100644 (file)
index 0000000..b3dbea7
--- /dev/null
@@ -0,0 +1,32 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Tom Gundersen <teg@jklm.no>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "resolved-manager.h"
+
+int manager_parse_dns_server(Manager *m, DnsServerType type, const char *string);
+int manager_parse_config_file(Manager *m);
+
+const struct ConfigPerfItem* resolved_gperf_lookup(const char *key, unsigned length);
+
+int config_parse_dnsv(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_support(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
diff --git a/src/resolve/resolved-def.h b/src/resolve/resolved-def.h
new file mode 100644 (file)
index 0000000..086d111
--- /dev/null
@@ -0,0 +1,30 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#define SD_RESOLVED_DNS           ((uint64_t) 1)
+#define SD_RESOLVED_LLMNR_IPV4    ((uint64_t) 2)
+#define SD_RESOLVED_LLMNR_IPV6    ((uint64_t) 4)
+#define SD_RESOLVED_LLMNR         (SD_RESOLVED_LLMNR_IPV4|SD_RESOLVED_LLMNR_IPV6)
+
+#define SD_RESOLVED_FLAGS_ALL     (SD_RESOLVED_DNS|SD_RESOLVED_LLMNR_IPV4|SD_RESOLVED_LLMNR_IPV6)
+#define SD_RESOLVED_FLAGS_DEFAULT SD_RESOLVED_FLAGS_ALL
diff --git a/src/resolve/resolved-dns-answer.c b/src/resolve/resolved-dns-answer.c
new file mode 100644 (file)
index 0000000..7c4ab18
--- /dev/null
@@ -0,0 +1,238 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "resolved-dns-answer.h"
+#include "resolved-dns-domain.h"
+
+DnsAnswer *dns_answer_new(unsigned n) {
+        DnsAnswer *a;
+
+        assert(n > 0);
+
+        a = malloc0(offsetof(DnsAnswer, rrs) + sizeof(DnsResourceRecord*) * n);
+        if (!a)
+                return NULL;
+
+        a->n_ref = 1;
+        a->n_allocated = n;
+
+        return a;
+}
+
+DnsAnswer *dns_answer_ref(DnsAnswer *a) {
+        if (!a)
+                return NULL;
+
+        assert(a->n_ref > 0);
+        a->n_ref++;
+        return a;
+}
+
+DnsAnswer *dns_answer_unref(DnsAnswer *a) {
+        if (!a)
+                return NULL;
+
+        assert(a->n_ref > 0);
+
+        if (a->n_ref == 1) {
+                unsigned i;
+
+                for (i = 0; i < a->n_rrs; i++)
+                        dns_resource_record_unref(a->rrs[i]);
+
+                free(a);
+        } else
+                a->n_ref--;
+
+        return NULL;
+}
+
+int dns_answer_add(DnsAnswer *a, DnsResourceRecord *rr) {
+        unsigned i;
+        int r;
+
+        assert(a);
+        assert(rr);
+
+        for (i = 0; i < a->n_rrs; i++) {
+                r = dns_resource_record_equal(a->rrs[i], rr);
+                if (r < 0)
+                        return r;
+                if (r > 0) {
+                        /* Entry already exists, keep the entry with
+                         * the higher RR, or the one with TTL 0 */
+
+                        if (rr->ttl == 0 || (rr->ttl > a->rrs[i]->ttl && a->rrs[i]->ttl != 0)) {
+                                dns_resource_record_ref(rr);
+                                dns_resource_record_unref(a->rrs[i]);
+                                a->rrs[i] = rr;
+                        }
+
+                        return 0;
+                }
+        }
+
+        if (a->n_rrs >= a->n_allocated)
+                return -ENOSPC;
+
+        a->rrs[a->n_rrs++] = dns_resource_record_ref(rr);
+        return 1;
+}
+
+int dns_answer_add_soa(DnsAnswer *a, const char *name, uint32_t ttl) {
+        _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *soa = NULL;
+
+        soa = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_SOA, name);
+        if (!soa)
+                return -ENOMEM;
+
+        soa->ttl = ttl;
+
+        soa->soa.mname = strdup(name);
+        if (!soa->soa.mname)
+                return -ENOMEM;
+
+        soa->soa.rname = strappend("root.", name);
+        if (!soa->soa.rname)
+                return -ENOMEM;
+
+        soa->soa.serial = 1;
+        soa->soa.refresh = 1;
+        soa->soa.retry = 1;
+        soa->soa.expire = 1;
+        soa->soa.minimum = ttl;
+
+        return dns_answer_add(a, soa);
+}
+
+int dns_answer_contains(DnsAnswer *a, DnsResourceKey *key) {
+        unsigned i;
+        int r;
+
+        assert(a);
+        assert(key);
+
+        for (i = 0; i < a->n_rrs; i++) {
+                r = dns_resource_key_match_rr(key, a->rrs[i]);
+                if (r < 0)
+                        return r;
+                if (r > 0)
+                        return 1;
+        }
+
+        return 0;
+}
+
+int dns_answer_find_soa(DnsAnswer *a, DnsResourceKey *key, DnsResourceRecord **ret) {
+        unsigned i;
+
+        assert(a);
+        assert(key);
+        assert(ret);
+
+        /* For a SOA record we can never find a matching SOA record */
+        if (key->type == DNS_TYPE_SOA)
+                return 0;
+
+        for (i = 0; i < a->n_rrs; i++) {
+
+                if (a->rrs[i]->key->class != DNS_CLASS_IN)
+                        continue;
+
+                if (a->rrs[i]->key->type != DNS_TYPE_SOA)
+                        continue;
+
+                if (dns_name_endswith(DNS_RESOURCE_KEY_NAME(key), DNS_RESOURCE_KEY_NAME(a->rrs[i]->key))) {
+                        *ret = a->rrs[i];
+                        return 1;
+                }
+        }
+
+        return 0;
+}
+
+DnsAnswer *dns_answer_merge(DnsAnswer *a, DnsAnswer *b) {
+        _cleanup_(dns_answer_unrefp) DnsAnswer *ret = NULL;
+        DnsAnswer *k;
+        unsigned i;
+        int r;
+
+        if (a && (!b || b->n_rrs <= 0))
+                return dns_answer_ref(a);
+        if ((!a || a->n_rrs <= 0) && b)
+                return dns_answer_ref(b);
+
+        ret = dns_answer_new((a ? a->n_rrs : 0) + (b ? b->n_rrs : 0));
+        if (!ret)
+                return NULL;
+
+        if (a) {
+                for (i = 0; i < a->n_rrs; i++) {
+                        r = dns_answer_add(ret, a->rrs[i]);
+                        if (r < 0)
+                                return NULL;
+                }
+        }
+
+        if (b) {
+                for (i = 0; i < b->n_rrs; i++) {
+                        r = dns_answer_add(ret, b->rrs[i]);
+                        if (r < 0)
+                                return NULL;
+                }
+        }
+
+        k = ret;
+        ret = NULL;
+
+        return k;
+}
+
+void dns_answer_order_by_scope(DnsAnswer *a, bool prefer_link_local) {
+        DnsResourceRecord **rrs;
+        unsigned i, start, end;
+        assert(a);
+
+        if (a->n_rrs <= 1)
+                return;
+
+        start = 0;
+        end = a->n_rrs-1;
+
+        /* RFC 4795, Section 2.6 suggests we should order entries
+         * depending on whether the sender is a link-local address. */
+
+        rrs = newa(DnsResourceRecord*, a->n_rrs);
+        for (i = 0; i < a->n_rrs; i++) {
+
+                if (a->rrs[i]->key->class == DNS_CLASS_IN &&
+                    ((a->rrs[i]->key->type == DNS_TYPE_A && in_addr_is_link_local(AF_INET, (union in_addr_union*) &a->rrs[i]->a.in_addr) != prefer_link_local) ||
+                     (a->rrs[i]->key->type == DNS_TYPE_AAAA && in_addr_is_link_local(AF_INET6, (union in_addr_union*) &a->rrs[i]->aaaa.in6_addr) != prefer_link_local)))
+                        /* Order address records that are are not preferred to the end of the array */
+                        rrs[end--] = a->rrs[i];
+                else
+                        /* Order all other records to the beginning of the array */
+                        rrs[start++] = a->rrs[i];
+        }
+
+        assert(start == end+1);
+        memcpy(a->rrs, rrs, sizeof(DnsResourceRecord*) * a->n_rrs);
+}
diff --git a/src/resolve/resolved-dns-answer.h b/src/resolve/resolved-dns-answer.h
new file mode 100644 (file)
index 0000000..af3e462
--- /dev/null
@@ -0,0 +1,48 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+typedef struct DnsAnswer DnsAnswer;
+
+#include "resolved-dns-rr.h"
+
+/* A simple array of resource records */
+
+struct DnsAnswer {
+        unsigned n_ref;
+        unsigned n_rrs, n_allocated;
+        DnsResourceRecord* rrs[0];
+};
+
+DnsAnswer *dns_answer_new(unsigned n);
+DnsAnswer *dns_answer_ref(DnsAnswer *a);
+DnsAnswer *dns_answer_unref(DnsAnswer *a);
+
+int dns_answer_add(DnsAnswer *a, DnsResourceRecord *rr);
+int dns_answer_add_soa(DnsAnswer *a, const char *name, uint32_t ttl);
+int dns_answer_contains(DnsAnswer *a, DnsResourceKey *key);
+int dns_answer_find_soa(DnsAnswer *a, DnsResourceKey *key, DnsResourceRecord **ret);
+
+DnsAnswer *dns_answer_merge(DnsAnswer *a, DnsAnswer *b);
+void dns_answer_order_by_scope(DnsAnswer *a, bool prefer_link_local);
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(DnsAnswer*, dns_answer_unref);
diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c
new file mode 100644 (file)
index 0000000..733ef63
--- /dev/null
@@ -0,0 +1,564 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "resolved-dns-cache.h"
+#include "resolved-dns-packet.h"
+
+/* Never cache more than 1K entries */
+#define CACHE_MAX 1024
+
+/* We never keep any item longer than 10min in our cache */
+#define CACHE_TTL_MAX_USEC (10 * USEC_PER_MINUTE)
+
+typedef enum DnsCacheItemType DnsCacheItemType;
+typedef struct DnsCacheItem DnsCacheItem;
+
+enum DnsCacheItemType {
+        DNS_CACHE_POSITIVE,
+        DNS_CACHE_NODATA,
+        DNS_CACHE_NXDOMAIN,
+};
+
+struct DnsCacheItem {
+        DnsResourceKey *key;
+        DnsResourceRecord *rr;
+        usec_t until;
+        DnsCacheItemType type;
+        unsigned prioq_idx;
+        int owner_family;
+        union in_addr_union owner_address;
+        LIST_FIELDS(DnsCacheItem, by_key);
+};
+
+static void dns_cache_item_free(DnsCacheItem *i) {
+        if (!i)
+                return;
+
+        dns_resource_record_unref(i->rr);
+        dns_resource_key_unref(i->key);
+        free(i);
+}
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(DnsCacheItem*, dns_cache_item_free);
+
+static void dns_cache_item_remove_and_free(DnsCache *c, DnsCacheItem *i) {
+        DnsCacheItem *first;
+
+        assert(c);
+
+        if (!i)
+                return;
+
+        first = hashmap_get(c->by_key, i->key);
+        LIST_REMOVE(by_key, first, i);
+
+        if (first)
+                assert_se(hashmap_replace(c->by_key, first->key, first) >= 0);
+        else
+                hashmap_remove(c->by_key, i->key);
+
+        prioq_remove(c->by_expiry, i, &i->prioq_idx);
+
+        dns_cache_item_free(i);
+}
+
+void dns_cache_flush(DnsCache *c) {
+        DnsCacheItem *i;
+
+        assert(c);
+
+        while ((i = hashmap_first(c->by_key)))
+                dns_cache_item_remove_and_free(c, i);
+
+        assert(hashmap_size(c->by_key) == 0);
+        assert(prioq_size(c->by_expiry) == 0);
+
+        hashmap_free(c->by_key);
+        c->by_key = NULL;
+
+        prioq_free(c->by_expiry);
+        c->by_expiry = NULL;
+}
+
+static void dns_cache_remove(DnsCache *c, DnsResourceKey *key) {
+        DnsCacheItem *i;
+
+        assert(c);
+        assert(key);
+
+        while ((i = hashmap_get(c->by_key, key)))
+                dns_cache_item_remove_and_free(c, i);
+}
+
+static void dns_cache_make_space(DnsCache *c, unsigned add) {
+        assert(c);
+
+        if (add <= 0)
+                return;
+
+        /* Makes space for n new entries. Note that we actually allow
+         * the cache to grow beyond CACHE_MAX, but only when we shall
+         * add more RRs to the cache than CACHE_MAX at once. In that
+         * case the cache will be emptied completely otherwise. */
+
+        for (;;) {
+                _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
+                DnsCacheItem *i;
+
+                if (prioq_size(c->by_expiry) <= 0)
+                        break;
+
+                if (prioq_size(c->by_expiry) + add < CACHE_MAX)
+                        break;
+
+                i = prioq_peek(c->by_expiry);
+                assert(i);
+
+                /* Take an extra reference to the key so that it
+                 * doesn't go away in the middle of the remove call */
+                key = dns_resource_key_ref(i->key);
+                dns_cache_remove(c, key);
+        }
+}
+
+void dns_cache_prune(DnsCache *c) {
+        usec_t t = 0;
+
+        assert(c);
+
+        /* Remove all entries that are past their TTL */
+
+        for (;;) {
+                _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
+                DnsCacheItem *i;
+
+                i = prioq_peek(c->by_expiry);
+                if (!i)
+                        break;
+
+                if (t <= 0)
+                        t = now(CLOCK_BOOTTIME);
+
+                if (i->until > t)
+                        break;
+
+                /* Take an extra reference to the key so that it
+                 * doesn't go away in the middle of the remove call */
+                key = dns_resource_key_ref(i->key);
+                dns_cache_remove(c, key);
+        }
+}
+
+static int dns_cache_item_prioq_compare_func(const void *a, const void *b) {
+        const DnsCacheItem *x = a, *y = b;
+
+        if (x->until < y->until)
+                return -1;
+        if (x->until > y->until)
+                return 1;
+        return 0;
+}
+
+static int dns_cache_init(DnsCache *c) {
+        int r;
+
+        assert(c);
+
+        r = prioq_ensure_allocated(&c->by_expiry, dns_cache_item_prioq_compare_func);
+        if (r < 0)
+                return r;
+
+        r = hashmap_ensure_allocated(&c->by_key, dns_resource_key_hash_func, dns_resource_key_compare_func);
+        if (r < 0)
+                return r;
+
+        return r;
+}
+
+static int dns_cache_link_item(DnsCache *c, DnsCacheItem *i) {
+        DnsCacheItem *first;
+        int r;
+
+        assert(c);
+        assert(i);
+
+        r = prioq_put(c->by_expiry, i, &i->prioq_idx);
+        if (r < 0)
+                return r;
+
+        first = hashmap_get(c->by_key, i->key);
+        if (first) {
+                LIST_PREPEND(by_key, first, i);
+                assert_se(hashmap_replace(c->by_key, first->key, first) >= 0);
+        } else {
+                r = hashmap_put(c->by_key, i->key, i);
+                if (r < 0) {
+                        prioq_remove(c->by_expiry, i, &i->prioq_idx);
+                        return r;
+                }
+        }
+
+        return 0;
+}
+
+static DnsCacheItem* dns_cache_get(DnsCache *c, DnsResourceRecord *rr) {
+        DnsCacheItem *i;
+
+        assert(c);
+        assert(rr);
+
+        LIST_FOREACH(by_key, i, hashmap_get(c->by_key, rr->key))
+                if (i->rr && dns_resource_record_equal(i->rr, rr) > 0)
+                        return i;
+
+        return NULL;
+}
+
+static void dns_cache_item_update_positive(DnsCache *c, DnsCacheItem *i, DnsResourceRecord *rr, usec_t timestamp) {
+        assert(c);
+        assert(i);
+        assert(rr);
+
+        i->type = DNS_CACHE_POSITIVE;
+
+        if (!i->by_key_prev) {
+                /* We are the first item in the list, we need to
+                 * update the key used in the hashmap */
+
+                assert_se(hashmap_replace(c->by_key, rr->key, i) >= 0);
+        }
+
+        dns_resource_record_ref(rr);
+        dns_resource_record_unref(i->rr);
+        i->rr = rr;
+
+        dns_resource_key_unref(i->key);
+        i->key = dns_resource_key_ref(rr->key);
+
+        i->until = timestamp + MIN(rr->ttl * USEC_PER_SEC, CACHE_TTL_MAX_USEC);
+
+        prioq_reshuffle(c->by_expiry, i, &i->prioq_idx);
+}
+
+static int dns_cache_put_positive(
+                DnsCache *c,
+                DnsResourceRecord *rr,
+                usec_t timestamp,
+                int owner_family,
+                const union in_addr_union *owner_address) {
+
+        _cleanup_(dns_cache_item_freep) DnsCacheItem *i = NULL;
+        DnsCacheItem *existing;
+        int r;
+
+        assert(c);
+        assert(rr);
+        assert(owner_address);
+
+        /* New TTL is 0? Delete the entry... */
+        if (rr->ttl <= 0) {
+                dns_cache_remove(c, rr->key);
+                return 0;
+        }
+
+        if (rr->key->class == DNS_CLASS_ANY)
+                return 0;
+        if (rr->key->type == DNS_TYPE_ANY)
+                return 0;
+
+        /* Entry exists already? Update TTL and timestamp */
+        existing = dns_cache_get(c, rr);
+        if (existing) {
+                dns_cache_item_update_positive(c, existing, rr, timestamp);
+                return 0;
+        }
+
+        /* Otherwise, add the new RR */
+        r = dns_cache_init(c);
+        if (r < 0)
+                return r;
+
+        dns_cache_make_space(c, 1);
+
+        i = new0(DnsCacheItem, 1);
+        if (!i)
+                return -ENOMEM;
+
+        i->type = DNS_CACHE_POSITIVE;
+        i->key = dns_resource_key_ref(rr->key);
+        i->rr = dns_resource_record_ref(rr);
+        i->until = timestamp + MIN(i->rr->ttl * USEC_PER_SEC, CACHE_TTL_MAX_USEC);
+        i->prioq_idx = PRIOQ_IDX_NULL;
+        i->owner_family = owner_family;
+        i->owner_address = *owner_address;
+
+        r = dns_cache_link_item(c, i);
+        if (r < 0)
+                return r;
+
+        i = NULL;
+        return 0;
+}
+
+static int dns_cache_put_negative(
+                DnsCache *c,
+                DnsResourceKey *key,
+                int rcode,
+                usec_t timestamp,
+                uint32_t soa_ttl,
+                int owner_family,
+                const union in_addr_union *owner_address) {
+
+        _cleanup_(dns_cache_item_freep) DnsCacheItem *i = NULL;
+        int r;
+
+        assert(c);
+        assert(key);
+        assert(owner_address);
+
+        dns_cache_remove(c, key);
+
+        if (key->class == DNS_CLASS_ANY)
+                return 0;
+        if (key->type == DNS_TYPE_ANY)
+                return 0;
+        if (soa_ttl <= 0)
+                return 0;
+
+        if (!IN_SET(rcode, DNS_RCODE_SUCCESS, DNS_RCODE_NXDOMAIN))
+                return 0;
+
+        r = dns_cache_init(c);
+        if (r < 0)
+                return r;
+
+        dns_cache_make_space(c, 1);
+
+        i = new0(DnsCacheItem, 1);
+        if (!i)
+                return -ENOMEM;
+
+        i->type = rcode == DNS_RCODE_SUCCESS ? DNS_CACHE_NODATA : DNS_CACHE_NXDOMAIN;
+        i->key = dns_resource_key_ref(key);
+        i->until = timestamp + MIN(soa_ttl * USEC_PER_SEC, CACHE_TTL_MAX_USEC);
+        i->prioq_idx = PRIOQ_IDX_NULL;
+        i->owner_family = owner_family;
+        i->owner_address = *owner_address;
+
+        r = dns_cache_link_item(c, i);
+        if (r < 0)
+                return r;
+
+        i = NULL;
+        return 0;
+}
+
+int dns_cache_put(
+                DnsCache *c,
+                DnsQuestion *q,
+                int rcode,
+                DnsAnswer *answer,
+                unsigned max_rrs,
+                usec_t timestamp,
+                int owner_family,
+                const union in_addr_union *owner_address) {
+
+        unsigned i;
+        int r;
+
+        assert(c);
+        assert(q);
+
+        /* First, delete all matching old RRs, so that we only keep
+         * complete by_key in place. */
+        for (i = 0; i < q->n_keys; i++)
+                dns_cache_remove(c, q->keys[i]);
+
+        if (!answer)
+                return 0;
+
+        for (i = 0; i < answer->n_rrs; i++)
+                dns_cache_remove(c, answer->rrs[i]->key);
+
+        /* We only care for positive replies and NXDOMAINs, on all
+         * other replies we will simply flush the respective entries,
+         * and that's it */
+
+        if (!IN_SET(rcode, DNS_RCODE_SUCCESS, DNS_RCODE_NXDOMAIN))
+                return 0;
+
+        /* Make some space for our new entries */
+        dns_cache_make_space(c, answer->n_rrs + q->n_keys);
+
+        if (timestamp <= 0)
+                timestamp = now(CLOCK_BOOTTIME);
+
+        /* Second, add in positive entries for all contained RRs */
+        for (i = 0; i < MIN(max_rrs, answer->n_rrs); i++) {
+                r = dns_cache_put_positive(c, answer->rrs[i], timestamp, owner_family, owner_address);
+                if (r < 0)
+                        goto fail;
+        }
+
+        /* Third, add in negative entries for all keys with no RR */
+        for (i = 0; i < q->n_keys; i++) {
+                DnsResourceRecord *soa = NULL;
+
+                r = dns_answer_contains(answer, q->keys[i]);
+                if (r < 0)
+                        goto fail;
+                if (r > 0)
+                        continue;
+
+                r = dns_answer_find_soa(answer, q->keys[i], &soa);
+                if (r < 0)
+                        goto fail;
+                if (r == 0)
+                        continue;
+
+                r = dns_cache_put_negative(c, q->keys[i], rcode, timestamp, MIN(soa->soa.minimum, soa->ttl), owner_family, owner_address);
+                if (r < 0)
+                        goto fail;
+        }
+
+        return 0;
+
+fail:
+        /* Adding all RRs failed. Let's clean up what we already
+         * added, just in case */
+
+        for (i = 0; i < q->n_keys; i++)
+                dns_cache_remove(c, q->keys[i]);
+        for (i = 0; i < answer->n_rrs; i++)
+                dns_cache_remove(c, answer->rrs[i]->key);
+
+        return r;
+}
+
+int dns_cache_lookup(DnsCache *c, DnsQuestion *q, int *rcode, DnsAnswer **ret) {
+        _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
+        unsigned i, n = 0;
+        int r;
+        bool nxdomain = false;
+
+        assert(c);
+        assert(q);
+        assert(rcode);
+        assert(ret);
+
+        if (q->n_keys <= 0) {
+                *ret = NULL;
+                *rcode = 0;
+                return 0;
+        }
+
+        for (i = 0; i < q->n_keys; i++) {
+                DnsCacheItem *j;
+
+                if (q->keys[i]->type == DNS_TYPE_ANY ||
+                    q->keys[i]->class == DNS_CLASS_ANY) {
+                        /* If we have ANY lookups we simply refresh */
+                        *ret = NULL;
+                        *rcode = 0;
+                        return 0;
+                }
+
+                j = hashmap_get(c->by_key, q->keys[i]);
+                if (!j) {
+                        /* If one question cannot be answered we need to refresh */
+                        *ret = NULL;
+                        *rcode = 0;
+                        return 0;
+                }
+
+                LIST_FOREACH(by_key, j, j) {
+                        if (j->rr)
+                                n++;
+                        else if (j->type == DNS_CACHE_NXDOMAIN)
+                                nxdomain = true;
+                }
+        }
+
+        if (n <= 0) {
+                *ret = NULL;
+                *rcode = nxdomain ? DNS_RCODE_NXDOMAIN : DNS_RCODE_SUCCESS;
+                return 1;
+        }
+
+        answer = dns_answer_new(n);
+        if (!answer)
+                return -ENOMEM;
+
+        for (i = 0; i < q->n_keys; i++) {
+                DnsCacheItem *j;
+
+                j = hashmap_get(c->by_key, q->keys[i]);
+                LIST_FOREACH(by_key, j, j) {
+                        if (j->rr) {
+                                r = dns_answer_add(answer, j->rr);
+                                if (r < 0)
+                                        return r;
+                        }
+                }
+        }
+
+        *ret = answer;
+        *rcode = DNS_RCODE_SUCCESS;
+        answer = NULL;
+
+        return n;
+}
+
+int dns_cache_check_conflicts(DnsCache *cache, DnsResourceRecord *rr, int owner_family, const union in_addr_union *owner_address) {
+        DnsCacheItem *i, *first;
+        bool same_owner = true;
+
+        assert(cache);
+        assert(rr);
+
+        dns_cache_prune(cache);
+
+        /* See if there's a cache entry for the same key. If there
+         * isn't there's no conflict */
+        first = hashmap_get(cache->by_key, rr->key);
+        if (!first)
+                return 0;
+
+        /* See if the RR key is owned by the same owner, if so, there
+         * isn't a conflict either */
+        LIST_FOREACH(by_key, i, first) {
+                if (i->owner_family != owner_family ||
+                    !in_addr_equal(owner_family, &i->owner_address, owner_address)) {
+                        same_owner = false;
+                        break;
+                }
+        }
+        if (same_owner)
+                return 0;
+
+        /* See if there's the exact same RR in the cache. If yes, then
+         * there's no conflict. */
+        if (dns_cache_get(cache, rr))
+                return 0;
+
+        /* There's a conflict */
+        return 1;
+}
diff --git a/src/resolve/resolved-dns-cache.h b/src/resolve/resolved-dns-cache.h
new file mode 100644 (file)
index 0000000..e92280c
--- /dev/null
@@ -0,0 +1,46 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/types.h>
+
+#include "hashmap.h"
+#include "prioq.h"
+#include "time-util.h"
+#include "list.h"
+
+typedef struct DnsCache {
+        Hashmap *by_key;
+        Prioq *by_expiry;
+} DnsCache;
+
+#include "resolved-dns-rr.h"
+#include "resolved-dns-question.h"
+#include "resolved-dns-answer.h"
+
+void dns_cache_flush(DnsCache *c);
+void dns_cache_prune(DnsCache *c);
+
+int dns_cache_put(DnsCache *c, DnsQuestion *q, int rcode, DnsAnswer *answer, unsigned max_rrs, usec_t timestamp, int owner_family, const union in_addr_union *owner_address);
+int dns_cache_lookup(DnsCache *c, DnsQuestion *q, int *rcode, DnsAnswer **answer);
+
+int dns_cache_check_conflicts(DnsCache *cache, DnsResourceRecord *rr, int owner_family, const union in_addr_union *owner_address);
diff --git a/src/resolve/resolved-dns-domain.c b/src/resolve/resolved-dns-domain.c
new file mode 100644 (file)
index 0000000..6152047
--- /dev/null
@@ -0,0 +1,608 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+ ***/
+
+#ifdef HAVE_LIBIDN
+#include <idna.h>
+#include <stringprep.h>
+#endif
+
+#include "resolved-dns-domain.h"
+
+int dns_label_unescape(const char **name, char *dest, size_t sz) {
+        const char *n;
+        char *d;
+        int r = 0;
+
+        assert(name);
+        assert(*name);
+        assert(dest);
+
+        n = *name;
+        d = dest;
+
+        for (;;) {
+                if (*n == '.') {
+                        n++;
+                        break;
+                }
+
+                if (*n == 0)
+                        break;
+
+                if (sz <= 0)
+                        return -ENOSPC;
+
+                if (r >= DNS_LABEL_MAX)
+                        return -EINVAL;
+
+                if (*n == '\\') {
+                        /* Escaped character */
+
+                        n++;
+
+                        if (*n == 0)
+                                /* Ending NUL */
+                                return -EINVAL;
+
+                        else if (*n == '\\' || *n == '.') {
+                                /* Escaped backslash or dot */
+                                *(d++) = *(n++);
+                                sz--;
+                                r++;
+
+                        } else if (n[0] >= '0' && n[0] <= '9') {
+                                unsigned k;
+
+                                /* Escaped literal ASCII character */
+
+                                if (!(n[1] >= '0' && n[1] <= '9') ||
+                                    !(n[2] >= '0' && n[2] <= '9'))
+                                        return -EINVAL;
+
+                                k = ((unsigned) (n[0] - '0') * 100) +
+                                        ((unsigned) (n[1] - '0') * 10) +
+                                        ((unsigned) (n[2] - '0'));
+
+                                /* Don't allow CC characters or anything that doesn't fit in 8bit */
+                                if (k < ' ' || k > 255 || k == 127)
+                                        return -EINVAL;
+
+                                *(d++) = (char) k;
+                                sz--;
+                                r++;
+
+                                n += 3;
+                        } else
+                                return -EINVAL;
+
+                } else if ((uint8_t) *n >= (uint8_t) ' ' && *n != 127) {
+
+                        /* Normal character */
+                        *(d++) = *(n++);
+                        sz--;
+                        r++;
+                } else
+                        return -EINVAL;
+        }
+
+        /* Empty label that is not at the end? */
+        if (r == 0 && *n)
+                return -EINVAL;
+
+        if (sz >= 1)
+                *d = 0;
+
+        *name = n;
+        return r;
+}
+
+int dns_label_escape(const char *p, size_t l, char **ret) {
+        _cleanup_free_ char *s = NULL;
+        char *q;
+        int r;
+
+        assert(p);
+        assert(ret);
+
+        if (l > DNS_LABEL_MAX)
+                return -EINVAL;
+
+        s = malloc(l * 4 + 1);
+        if (!s)
+                return -ENOMEM;
+
+        q = s;
+        while (l > 0) {
+
+                if (*p == '.' || *p == '\\') {
+
+                        /* Dot or backslash */
+                        *(q++) = '\\';
+                        *(q++) = *p;
+
+                } else if (*p == '_' ||
+                           *p == '-' ||
+                           (*p >= '0' && *p <= '9') ||
+                           (*p >= 'a' && *p <= 'z') ||
+                           (*p >= 'A' && *p <= 'Z')) {
+
+                        /* Proper character */
+                        *(q++) = *p;
+                } else if ((uint8_t) *p >= (uint8_t) ' ' && *p != 127) {
+
+                        /* Everything else */
+                        *(q++) = '\\';
+                        *(q++) = '0' + (char) ((uint8_t) *p / 100);
+                        *(q++) = '0' + (char) (((uint8_t) *p / 10) % 10);
+                        *(q++) = '0' + (char) ((uint8_t) *p % 10);
+
+                } else
+                        return -EINVAL;
+
+                p++;
+                l--;
+        }
+
+        *q = 0;
+        *ret = s;
+        r = q - s;
+        s = NULL;
+
+        return r;
+}
+
+int dns_label_apply_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max) {
+#ifdef HAVE_LIBIDN
+        _cleanup_free_ uint32_t *input = NULL;
+        size_t input_size;
+        const char *p;
+        bool contains_8bit = false;
+
+        assert(encoded);
+        assert(decoded);
+        assert(decoded_max >= DNS_LABEL_MAX);
+
+        if (encoded_size <= 0)
+                return 0;
+
+        for (p = encoded; p < encoded + encoded_size; p++)
+                if ((uint8_t) *p > 127)
+                        contains_8bit = true;
+
+        if (!contains_8bit)
+                return 0;
+
+        input = stringprep_utf8_to_ucs4(encoded, encoded_size, &input_size);
+        if (!input)
+                return -ENOMEM;
+
+        if (idna_to_ascii_4i(input, input_size, decoded, 0) != 0)
+                return -EINVAL;
+
+        return strlen(decoded);
+#else
+        return 0;
+#endif
+}
+
+int dns_label_undo_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max) {
+#ifdef HAVE_LIBIDN
+        size_t input_size, output_size;
+        _cleanup_free_ uint32_t *input = NULL;
+        _cleanup_free_ char *result = NULL;
+        uint32_t *output = NULL;
+        size_t w;
+
+        /* To be invoked after unescaping */
+
+        assert(encoded);
+        assert(decoded);
+
+        if (encoded_size < sizeof(IDNA_ACE_PREFIX)-1)
+                return 0;
+
+        if (memcmp(encoded, IDNA_ACE_PREFIX, sizeof(IDNA_ACE_PREFIX) -1) != 0)
+                return 0;
+
+        input = stringprep_utf8_to_ucs4(encoded, encoded_size, &input_size);
+        if (!input)
+                return -ENOMEM;
+
+        output_size = input_size;
+        output = newa(uint32_t, output_size);
+
+        idna_to_unicode_44i(input, input_size, output, &output_size, 0);
+
+        result = stringprep_ucs4_to_utf8(output, output_size, NULL, &w);
+        if (!result)
+                return -ENOMEM;
+        if (w <= 0)
+                return 0;
+        if (w+1 > decoded_max)
+                return -EINVAL;
+
+        memcpy(decoded, result, w+1);
+        return w;
+#else
+        return 0;
+#endif
+}
+
+int dns_name_normalize(const char *s, char **_ret) {
+        _cleanup_free_ char *ret = NULL;
+        size_t n = 0, allocated = 0;
+        const char *p = s;
+        bool first = true;
+        int r;
+
+        assert(s);
+
+        for (;;) {
+                _cleanup_free_ char *t = NULL;
+                char label[DNS_LABEL_MAX];
+                int k;
+
+                r = dns_label_unescape(&p, label, sizeof(label));
+                if (r < 0)
+                        return r;
+                if (r == 0) {
+                        if (*p != 0)
+                                return -EINVAL;
+                        break;
+                }
+
+                k = dns_label_undo_idna(label, r, label, sizeof(label));
+                if (k < 0)
+                        return k;
+                if (k > 0)
+                        r = k;
+
+                r = dns_label_escape(label, r, &t);
+                if (r < 0)
+                        return r;
+
+                if (!GREEDY_REALLOC(ret, allocated, n + !first + strlen(t) + 1))
+                        return -ENOMEM;
+
+                if (!first)
+                        ret[n++] = '.';
+                else
+                        first = false;
+
+                memcpy(ret + n, t, r);
+                n += r;
+        }
+
+        if (n > DNS_NAME_MAX)
+                return -EINVAL;
+
+        if (!GREEDY_REALLOC(ret, allocated, n + 1))
+                return -ENOMEM;
+
+        ret[n] = 0;
+
+        if (_ret) {
+                *_ret = ret;
+                ret = NULL;
+        }
+
+        return 0;
+}
+
+unsigned long dns_name_hash_func(const void *s, const uint8_t hash_key[HASH_KEY_SIZE]) {
+        const char *p = s;
+        unsigned long ul = hash_key[0];
+        int r;
+
+        assert(p);
+
+        while (*p) {
+                char label[DNS_LABEL_MAX+1];
+                int k;
+
+                r = dns_label_unescape(&p, label, sizeof(label));
+                if (r < 0)
+                        break;
+
+                k = dns_label_undo_idna(label, r, label, sizeof(label));
+                if (k < 0)
+                        break;
+                if (k > 0)
+                        r = k;
+
+                label[r] = 0;
+                ascii_strlower(label);
+
+                ul = ul * hash_key[1] + ul + string_hash_func(label, hash_key);
+        }
+
+        return ul;
+}
+
+int dns_name_compare_func(const void *a, const void *b) {
+        const char *x = a, *y = b;
+        int r, q, k, w;
+
+        assert(a);
+        assert(b);
+
+        for (;;) {
+                char la[DNS_LABEL_MAX+1], lb[DNS_LABEL_MAX+1];
+
+                if (*x == 0 && *y == 0)
+                        return 0;
+
+                r = dns_label_unescape(&x, la, sizeof(la));
+                q = dns_label_unescape(&y, lb, sizeof(lb));
+                if (r < 0 || q < 0)
+                        return r - q;
+
+                k = dns_label_undo_idna(la, r, la, sizeof(la));
+                w = dns_label_undo_idna(lb, q, lb, sizeof(lb));
+                if (k < 0 || w < 0)
+                        return k - w;
+                if (k > 0)
+                        r = k;
+                if (w > 0)
+                        r = w;
+
+                la[r] = lb[q] = 0;
+                r = strcasecmp(la, lb);
+                if (r != 0)
+                        return r;
+        }
+}
+
+int dns_name_equal(const char *x, const char *y) {
+        int r, q, k, w;
+
+        assert(x);
+        assert(y);
+
+        for (;;) {
+                char la[DNS_LABEL_MAX+1], lb[DNS_LABEL_MAX+1];
+
+                if (*x == 0 && *y == 0)
+                        return true;
+
+                r = dns_label_unescape(&x, la, sizeof(la));
+                if (r < 0)
+                        return r;
+
+                k = dns_label_undo_idna(la, r, la, sizeof(la));
+                if (k < 0)
+                        return k;
+                if (k > 0)
+                        r = k;
+
+                q = dns_label_unescape(&y, lb, sizeof(lb));
+                if (q < 0)
+                        return q;
+                w = dns_label_undo_idna(lb, q, lb, sizeof(lb));
+                if (w < 0)
+                        return w;
+                if (w > 0)
+                        q = w;
+
+                la[r] = lb[q] = 0;
+                if (strcasecmp(la, lb))
+                        return false;
+        }
+}
+
+int dns_name_endswith(const char *name, const char *suffix) {
+        const char *n, *s, *saved_n = NULL;
+        int r, q, k, w;
+
+        assert(name);
+        assert(suffix);
+
+        n = name;
+        s = suffix;
+
+        for (;;) {
+                char ln[DNS_LABEL_MAX+1], ls[DNS_LABEL_MAX+1];
+
+                r = dns_label_unescape(&n, ln, sizeof(ln));
+                if (r < 0)
+                        return r;
+                k = dns_label_undo_idna(ln, r, ln, sizeof(ln));
+                if (k < 0)
+                        return k;
+                if (k > 0)
+                        r = k;
+
+                if (!saved_n)
+                        saved_n = n;
+
+                q = dns_label_unescape(&s, ls, sizeof(ls));
+                if (r < 0)
+                        return r;
+                w = dns_label_undo_idna(ls, q, ls, sizeof(ls));
+                if (w < 0)
+                        return w;
+                if (w > 0)
+                        q = w;
+
+                if (r == 0 && q == 0)
+                        return true;
+                if (r == 0 && saved_n == n)
+                        return false;
+
+                ln[r] = ls[q] = 0;
+
+                if (r != q || strcasecmp(ln, ls)) {
+
+                        /* Not the same, let's jump back, and try with the next label again */
+                        s = suffix;
+                        n = saved_n;
+                        saved_n = NULL;
+                }
+        }
+}
+
+int dns_name_reverse(int family, const union in_addr_union *a, char **ret) {
+        const uint8_t *p;
+        int r;
+
+        assert(a);
+        assert(ret);
+
+        p = (const uint8_t*) a;
+
+        if (family == AF_INET)
+                r = asprintf(ret, "%u.%u.%u.%u.in-addr.arpa", p[3], p[2], p[1], p[0]);
+        else if (family == AF_INET6)
+                r = asprintf(ret, "%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.%c.ip6.arpa",
+                             hexchar(p[15] & 0xF), hexchar(p[15] >> 4), hexchar(p[14] & 0xF), hexchar(p[14] >> 4),
+                             hexchar(p[13] & 0xF), hexchar(p[13] >> 4), hexchar(p[12] & 0xF), hexchar(p[12] >> 4),
+                             hexchar(p[11] & 0xF), hexchar(p[11] >> 4), hexchar(p[10] & 0xF), hexchar(p[10] >> 4),
+                             hexchar(p[ 9] & 0xF), hexchar(p[ 9] >> 4), hexchar(p[ 8] & 0xF), hexchar(p[ 8] >> 4),
+                             hexchar(p[ 7] & 0xF), hexchar(p[ 7] >> 4), hexchar(p[ 6] & 0xF), hexchar(p[ 6] >> 4),
+                             hexchar(p[ 5] & 0xF), hexchar(p[ 5] >> 4), hexchar(p[ 4] & 0xF), hexchar(p[ 4] >> 4),
+                             hexchar(p[ 3] & 0xF), hexchar(p[ 3] >> 4), hexchar(p[ 2] & 0xF), hexchar(p[ 2] >> 4),
+                             hexchar(p[ 1] & 0xF), hexchar(p[ 1] >> 4), hexchar(p[ 0] & 0xF), hexchar(p[ 0] >> 4));
+        else
+                return -EAFNOSUPPORT;
+        if (r < 0)
+                return -ENOMEM;
+
+        return 0;
+}
+
+int dns_name_address(const char *p, int *family, union in_addr_union *address) {
+        int r;
+
+        assert(p);
+        assert(family);
+        assert(address);
+
+        r = dns_name_endswith(p, "in-addr.arpa");
+        if (r < 0)
+                return r;
+        if (r > 0) {
+                uint8_t a[4];
+                unsigned i;
+
+                for (i = 0; i < ELEMENTSOF(a); i++) {
+                        char label[DNS_LABEL_MAX+1];
+
+                        r = dns_label_unescape(&p, label, sizeof(label));
+                        if (r < 0)
+                                return r;
+                        if (r == 0)
+                                return -EINVAL;
+                        if (r > 3)
+                                return -EINVAL;
+
+                        r = safe_atou8(label, &a[i]);
+                        if (r < 0)
+                                return r;
+                }
+
+                r = dns_name_equal(p, "in-addr.arpa");
+                if (r <= 0)
+                        return r;
+
+                *family = AF_INET;
+                address->in.s_addr = htobe32(((uint32_t) a[3] << 24) |
+                                             ((uint32_t) a[2] << 16) |
+                                             ((uint32_t) a[1] << 8) |
+                                              (uint32_t) a[0]);
+
+                return 1;
+        }
+
+        r = dns_name_endswith(p, "ip6.arpa");
+        if (r < 0)
+                return r;
+        if (r > 0) {
+                struct in6_addr a;
+                unsigned i;
+
+                for (i = 0; i < ELEMENTSOF(a.s6_addr); i++) {
+                        char label[DNS_LABEL_MAX+1];
+                        int x, y;
+
+                        r = dns_label_unescape(&p, label, sizeof(label));
+                        if (r <= 0)
+                                return r;
+                        if (r != 1)
+                                return -EINVAL;
+                        x = unhexchar(label[0]);
+                        if (x < 0)
+                                return -EINVAL;
+
+                        r = dns_label_unescape(&p, label, sizeof(label));
+                        if (r <= 0)
+                                return r;
+                        if (r != 1)
+                                return -EINVAL;
+                        y = unhexchar(label[0]);
+                        if (y < 0)
+                                return -EINVAL;
+
+                        a.s6_addr[ELEMENTSOF(a.s6_addr) - i - 1] = (uint8_t) y << 4 | (uint8_t) x;
+                }
+
+                r = dns_name_equal(p, "ip6.arpa");
+                if (r <= 0)
+                        return r;
+
+                *family = AF_INET6;
+                address->in6 = a;
+                return 1;
+        }
+
+        return 0;
+}
+
+int dns_name_root(const char *name) {
+        char label[DNS_LABEL_MAX+1];
+        int r;
+
+        assert(name);
+
+        r = dns_label_unescape(&name, label, sizeof(label));
+        if (r < 0)
+                return r;
+
+        return r == 0 && *name == 0;
+}
+
+int dns_name_single_label(const char *name) {
+        char label[DNS_LABEL_MAX+1];
+        int r;
+
+        assert(name);
+
+        r = dns_label_unescape(&name, label, sizeof(label));
+        if (r < 0)
+                return r;
+        if (r == 0)
+                return 0;
+
+        r = dns_label_unescape(&name, label, sizeof(label));
+        if (r < 0)
+                return r;
+
+        return r == 0 && *name == 0;
+}
diff --git a/src/resolve/resolved-dns-domain.h b/src/resolve/resolved-dns-domain.h
new file mode 100644 (file)
index 0000000..e674c5d
--- /dev/null
@@ -0,0 +1,48 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+ ***/
+
+#include <sys/types.h>
+
+#include "hashmap.h"
+#include "in-addr-util.h"
+
+#define DNS_LABEL_MAX 63
+#define DNS_NAME_MAX 255
+
+int dns_label_unescape(const char **name, char *dest, size_t sz);
+int dns_label_escape(const char *p, size_t l, char **ret);
+
+int dns_label_apply_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max);
+int dns_label_undo_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max);
+
+int dns_name_normalize(const char *s, char **_ret);
+
+unsigned long dns_name_hash_func(const void *s, const uint8_t hash_key[HASH_KEY_SIZE]);
+int dns_name_compare_func(const void *a, const void *b);
+
+int dns_name_equal(const char *x, const char *y);
+int dns_name_endswith(const char *name, const char *suffix);
+
+int dns_name_reverse(int family, const union in_addr_union *a, char **ret);
+int dns_name_address(const char *p, int *family, union in_addr_union *a);
+
+int dns_name_root(const char *name);
+int dns_name_single_label(const char *name);
diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c
new file mode 100644 (file)
index 0000000..0d276df
--- /dev/null
@@ -0,0 +1,1463 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+ ***/
+
+#include "utf8.h"
+#include "util.h"
+#include "strv.h"
+#include "resolved-dns-domain.h"
+#include "resolved-dns-packet.h"
+
+int dns_packet_new(DnsPacket **ret, DnsProtocol protocol, size_t mtu) {
+        DnsPacket *p;
+        size_t a;
+
+        assert(ret);
+
+        if (mtu <= 0)
+                a = DNS_PACKET_SIZE_START;
+        else
+                a = mtu;
+
+        if (a < DNS_PACKET_HEADER_SIZE)
+                a = DNS_PACKET_HEADER_SIZE;
+
+        /* round up to next page size */
+        a = PAGE_ALIGN(ALIGN(sizeof(DnsPacket)) + a) - ALIGN(sizeof(DnsPacket));
+
+        /* make sure we never allocate more than useful */
+        if (a > DNS_PACKET_SIZE_MAX)
+                a = DNS_PACKET_SIZE_MAX;
+
+        p = malloc0(ALIGN(sizeof(DnsPacket)) + a);
+        if (!p)
+                return -ENOMEM;
+
+        p->size = p->rindex = DNS_PACKET_HEADER_SIZE;
+        p->allocated = a;
+        p->protocol = protocol;
+        p->n_ref = 1;
+
+        *ret = p;
+
+        return 0;
+}
+
+int dns_packet_new_query(DnsPacket **ret, DnsProtocol protocol, size_t mtu) {
+        DnsPacket *p;
+        DnsPacketHeader *h;
+        int r;
+
+        assert(ret);
+
+        r = dns_packet_new(&p, protocol, mtu);
+        if (r < 0)
+                return r;
+
+        h = DNS_PACKET_HEADER(p);
+
+        if (protocol == DNS_PROTOCOL_LLMNR)
+                h->flags = htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
+                                                         0 /* opcode */,
+                                                         0 /* c */,
+                                                         0 /* tc */,
+                                                         0 /* t */,
+                                                         0 /* ra */,
+                                                         0 /* ad */,
+                                                         0 /* cd */,
+                                                         0 /* rcode */));
+        else
+                h->flags = htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
+                                                         0 /* opcode */,
+                                                         0 /* aa */,
+                                                         0 /* tc */,
+                                                         1 /* rd (ask for recursion) */,
+                                                         0 /* ra */,
+                                                         0 /* ad */,
+                                                         0 /* cd */,
+                                                         0 /* rcode */));
+
+        *ret = p;
+        return 0;
+}
+
+DnsPacket *dns_packet_ref(DnsPacket *p) {
+
+        if (!p)
+                return NULL;
+
+        assert(p->n_ref > 0);
+        p->n_ref++;
+        return p;
+}
+
+static void dns_packet_free(DnsPacket *p) {
+        char *s;
+
+        assert(p);
+
+        dns_question_unref(p->question);
+        dns_answer_unref(p->answer);
+
+        while ((s = hashmap_steal_first_key(p->names)))
+                free(s);
+        hashmap_free(p->names);
+
+        free(p->_data);
+        free(p);
+}
+
+DnsPacket *dns_packet_unref(DnsPacket *p) {
+        if (!p)
+                return NULL;
+
+        assert(p->n_ref > 0);
+
+        if (p->n_ref == 1)
+                dns_packet_free(p);
+        else
+                p->n_ref--;
+
+        return NULL;
+}
+
+int dns_packet_validate(DnsPacket *p) {
+        assert(p);
+
+        if (p->size < DNS_PACKET_HEADER_SIZE)
+                return -EBADMSG;
+
+        if (p->size > DNS_PACKET_SIZE_MAX)
+                return -EBADMSG;
+
+        return 1;
+}
+
+int dns_packet_validate_reply(DnsPacket *p) {
+        int r;
+
+        assert(p);
+
+        r = dns_packet_validate(p);
+        if (r < 0)
+                return r;
+
+        if (DNS_PACKET_QR(p) != 1)
+                return 0;
+
+        if (DNS_PACKET_OPCODE(p) != 0)
+                return -EBADMSG;
+
+        /* RFC 4795, Section 2.1.1. says to discard all replies with QDCOUNT != 1 */
+        if (p->protocol == DNS_PROTOCOL_LLMNR &&
+            DNS_PACKET_QDCOUNT(p) != 1)
+                return -EBADMSG;
+
+        return 1;
+}
+
+int dns_packet_validate_query(DnsPacket *p) {
+        int r;
+
+        assert(p);
+
+        r = dns_packet_validate(p);
+        if (r < 0)
+                return r;
+
+        if (DNS_PACKET_QR(p) != 0)
+                return 0;
+
+        if (DNS_PACKET_OPCODE(p) != 0)
+                return -EBADMSG;
+
+        if (DNS_PACKET_TC(p))
+                return -EBADMSG;
+
+        /* RFC 4795, Section 2.1.1. says to discard all queries with QDCOUNT != 1 */
+        if (p->protocol == DNS_PROTOCOL_LLMNR &&
+            DNS_PACKET_QDCOUNT(p) != 1)
+                return -EBADMSG;
+
+        /* RFC 4795, Section 2.1.1. says to discard all queries with ANCOUNT != 0 */
+        if (DNS_PACKET_ANCOUNT(p) > 0)
+                return -EBADMSG;
+
+        /* RFC 4795, Section 2.1.1. says to discard all queries with NSCOUNT != 0 */
+        if (DNS_PACKET_NSCOUNT(p) > 0)
+                return -EBADMSG;
+
+        return 1;
+}
+
+static int dns_packet_extend(DnsPacket *p, size_t add, void **ret, size_t *start) {
+        assert(p);
+
+        if (p->size + add > p->allocated) {
+                size_t a;
+
+                a = PAGE_ALIGN((p->size + add) * 2);
+                if (a > DNS_PACKET_SIZE_MAX)
+                        a = DNS_PACKET_SIZE_MAX;
+
+                if (p->size + add > a)
+                        return -EMSGSIZE;
+
+                if (p->_data) {
+                        void *d;
+
+                        d = realloc(p->_data, a);
+                        if (!d)
+                                return -ENOMEM;
+
+                        p->_data = d;
+                } else {
+                        p->_data = malloc(a);
+                        if (!p->_data)
+                                return -ENOMEM;
+
+                        memcpy(p->_data, (uint8_t*) p + ALIGN(sizeof(DnsPacket)), p->size);
+                        memzero((uint8_t*) p->_data + p->size, a - p->size);
+                }
+
+                p->allocated = a;
+        }
+
+        if (start)
+                *start = p->size;
+
+        if (ret)
+                *ret = (uint8_t*) DNS_PACKET_DATA(p) + p->size;
+
+        p->size += add;
+        return 0;
+}
+
+static void dns_packet_truncate(DnsPacket *p, size_t sz) {
+        Iterator i;
+        char *s;
+        void *n;
+
+        assert(p);
+
+        if (p->size <= sz)
+                return;
+
+        HASHMAP_FOREACH_KEY(s, n, p->names, i) {
+
+                if (PTR_TO_SIZE(n) < sz)
+                        continue;
+
+                hashmap_remove(p->names, s);
+                free(s);
+        }
+
+        p->size = sz;
+}
+
+int dns_packet_append_blob(DnsPacket *p, const void *d, size_t l, size_t *start) {
+        void *q;
+        int r;
+
+        assert(p);
+
+        r = dns_packet_extend(p, l, &q, start);
+        if (r < 0)
+                return r;
+
+        memcpy(q, d, l);
+        return 0;
+}
+
+int dns_packet_append_uint8(DnsPacket *p, uint8_t v, size_t *start) {
+        void *d;
+        int r;
+
+        assert(p);
+
+        r = dns_packet_extend(p, sizeof(uint8_t), &d, start);
+        if (r < 0)
+                return r;
+
+        ((uint8_t*) d)[0] = v;
+
+        return 0;
+}
+
+int dns_packet_append_uint16(DnsPacket *p, uint16_t v, size_t *start) {
+        void *d;
+        int r;
+
+        assert(p);
+
+        r = dns_packet_extend(p, sizeof(uint16_t), &d, start);
+        if (r < 0)
+                return r;
+
+        ((uint8_t*) d)[0] = (uint8_t) (v >> 8);
+        ((uint8_t*) d)[1] = (uint8_t) v;
+
+        return 0;
+}
+
+int dns_packet_append_uint32(DnsPacket *p, uint32_t v, size_t *start) {
+        void *d;
+        int r;
+
+        assert(p);
+
+        r = dns_packet_extend(p, sizeof(uint32_t), &d, start);
+        if (r < 0)
+                return r;
+
+        ((uint8_t*) d)[0] = (uint8_t) (v >> 24);
+        ((uint8_t*) d)[1] = (uint8_t) (v >> 16);
+        ((uint8_t*) d)[2] = (uint8_t) (v >> 8);
+        ((uint8_t*) d)[3] = (uint8_t) v;
+
+        return 0;
+}
+
+int dns_packet_append_string(DnsPacket *p, const char *s, size_t *start) {
+        void *d;
+        size_t l;
+        int r;
+
+        assert(p);
+        assert(s);
+
+        l = strlen(s);
+        if (l > 255)
+                return -E2BIG;
+
+        r = dns_packet_extend(p, 1 + l, &d, start);
+        if (r < 0)
+                return r;
+
+        ((uint8_t*) d)[0] = (uint8_t) l;
+        memcpy(((uint8_t*) d) + 1, s, l);
+
+        return 0;
+}
+
+int dns_packet_append_label(DnsPacket *p, const char *d, size_t l, size_t *start) {
+        void *w;
+        int r;
+
+        assert(p);
+        assert(d);
+
+        if (l > DNS_LABEL_MAX)
+                return -E2BIG;
+
+        r = dns_packet_extend(p, 1 + l, &w, start);
+        if (r < 0)
+                return r;
+
+        ((uint8_t*) w)[0] = (uint8_t) l;
+        memcpy(((uint8_t*) w) + 1, d, l);
+
+        return 0;
+}
+
+int dns_packet_append_name(DnsPacket *p, const char *name,
+                           bool allow_compression, size_t *start) {
+        size_t saved_size;
+        int r;
+
+        assert(p);
+        assert(name);
+
+        saved_size = p->size;
+
+        while (*name) {
+                _cleanup_free_ char *s = NULL;
+                char label[DNS_LABEL_MAX];
+                size_t n = 0;
+                int k;
+
+                if (allow_compression)
+                        n = PTR_TO_SIZE(hashmap_get(p->names, name));
+                if (n > 0) {
+                        assert(n < p->size);
+
+                        if (n < 0x4000) {
+                                r = dns_packet_append_uint16(p, 0xC000 | n, NULL);
+                                if (r < 0)
+                                        goto fail;
+
+                                goto done;
+                        }
+                }
+
+                s = strdup(name);
+                if (!s) {
+                        r = -ENOMEM;
+                        goto fail;
+                }
+
+                r = dns_label_unescape(&name, label, sizeof(label));
+                if (r < 0)
+                        goto fail;
+
+                if (p->protocol == DNS_PROTOCOL_DNS)
+                        k = dns_label_apply_idna(label, r, label, sizeof(label));
+                else
+                        k = dns_label_undo_idna(label, r, label, sizeof(label));
+                if (k < 0) {
+                        r = k;
+                        goto fail;
+                }
+                if (k > 0)
+                        r = k;
+
+                r = dns_packet_append_label(p, label, r, &n);
+                if (r < 0)
+                        goto fail;
+
+                if (allow_compression) {
+                        r = hashmap_ensure_allocated(&p->names,
+                                                     dns_name_hash_func,
+                                                     dns_name_compare_func);
+                        if (r < 0)
+                                goto fail;
+
+                        r = hashmap_put(p->names, s, SIZE_TO_PTR(n));
+                        if (r < 0)
+                                goto fail;
+
+                        s = NULL;
+                }
+        }
+
+        r = dns_packet_append_uint8(p, 0, NULL);
+        if (r < 0)
+                return r;
+
+done:
+        if (start)
+                *start = saved_size;
+
+        return 0;
+
+fail:
+        dns_packet_truncate(p, saved_size);
+        return r;
+}
+
+int dns_packet_append_key(DnsPacket *p, const DnsResourceKey *k, size_t *start) {
+        size_t saved_size;
+        int r;
+
+        assert(p);
+        assert(k);
+
+        saved_size = p->size;
+
+        r = dns_packet_append_name(p, DNS_RESOURCE_KEY_NAME(k), true, NULL);
+        if (r < 0)
+                goto fail;
+
+        r = dns_packet_append_uint16(p, k->type, NULL);
+        if (r < 0)
+                goto fail;
+
+        r = dns_packet_append_uint16(p, k->class, NULL);
+        if (r < 0)
+                goto fail;
+
+        if (start)
+                *start = saved_size;
+
+        return 0;
+
+fail:
+        dns_packet_truncate(p, saved_size);
+        return r;
+}
+
+int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, size_t *start) {
+        size_t saved_size, rdlength_offset, end, rdlength;
+        int r;
+
+        assert(p);
+        assert(rr);
+
+        saved_size = p->size;
+
+        r = dns_packet_append_key(p, rr->key, NULL);
+        if (r < 0)
+                goto fail;
+
+        r = dns_packet_append_uint32(p, rr->ttl, NULL);
+        if (r < 0)
+                goto fail;
+
+        /* Initially we write 0 here */
+        r = dns_packet_append_uint16(p, 0, &rdlength_offset);
+        if (r < 0)
+                goto fail;
+
+        switch (rr->unparseable ? _DNS_TYPE_INVALID : rr->key->type) {
+
+        case DNS_TYPE_SRV:
+                r = dns_packet_append_uint16(p, rr->srv.priority, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_append_uint16(p, rr->srv.weight, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_append_uint16(p, rr->srv.port, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_append_name(p, rr->srv.name, true, NULL);
+                break;
+
+        case DNS_TYPE_PTR:
+        case DNS_TYPE_NS:
+        case DNS_TYPE_CNAME:
+        case DNS_TYPE_DNAME:
+                r = dns_packet_append_name(p, rr->ptr.name, true, NULL);
+                break;
+
+        case DNS_TYPE_HINFO:
+                r = dns_packet_append_string(p, rr->hinfo.cpu, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_append_string(p, rr->hinfo.os, NULL);
+                break;
+
+        case DNS_TYPE_SPF: /* exactly the same as TXT */
+        case DNS_TYPE_TXT: {
+                char **s;
+
+                STRV_FOREACH(s, rr->txt.strings) {
+                        r = dns_packet_append_string(p, *s, NULL);
+                        if (r < 0)
+                                goto fail;
+                }
+
+                r = 0;
+                break;
+        }
+
+        case DNS_TYPE_A:
+                r = dns_packet_append_blob(p, &rr->a.in_addr, sizeof(struct in_addr), NULL);
+                break;
+
+        case DNS_TYPE_AAAA:
+                r = dns_packet_append_blob(p, &rr->aaaa.in6_addr, sizeof(struct in6_addr), NULL);
+                break;
+
+        case DNS_TYPE_SOA:
+                r = dns_packet_append_name(p, rr->soa.mname, true, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_append_name(p, rr->soa.rname, true, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_append_uint32(p, rr->soa.serial, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_append_uint32(p, rr->soa.refresh, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_append_uint32(p, rr->soa.retry, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_append_uint32(p, rr->soa.expire, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_append_uint32(p, rr->soa.minimum, NULL);
+                break;
+
+        case DNS_TYPE_MX:
+                r = dns_packet_append_uint16(p, rr->mx.priority, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_append_name(p, rr->mx.exchange, true, NULL);
+                break;
+
+        case DNS_TYPE_LOC:
+                r = dns_packet_append_uint8(p, rr->loc.version, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_append_uint8(p, rr->loc.size, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_append_uint8(p, rr->loc.horiz_pre, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_append_uint8(p, rr->loc.vert_pre, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_append_uint32(p, rr->loc.latitude, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_append_uint32(p, rr->loc.longitude, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_append_uint32(p, rr->loc.altitude, NULL);
+                break;
+
+        case DNS_TYPE_SSHFP:
+                r = dns_packet_append_uint8(p, rr->sshfp.algorithm, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_append_uint8(p, rr->sshfp.fptype, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_append_blob(p, rr->sshfp.key, rr->sshfp.key_size, NULL);
+                break;
+
+        case DNS_TYPE_DNSKEY:
+                r = dns_packet_append_uint16(p, dnskey_to_flags(rr), NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_append_uint8(p, 3u, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_append_uint8(p, rr->dnskey.algorithm, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_append_blob(p, rr->dnskey.key, rr->dnskey.key_size, NULL);
+                break;
+
+        case DNS_TYPE_RRSIG:
+                r = dns_packet_append_uint16(p, rr->rrsig.type_covered, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_append_uint8(p, rr->rrsig.algorithm, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_append_uint8(p, rr->rrsig.labels, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_append_uint32(p, rr->rrsig.original_ttl, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_append_uint32(p, rr->rrsig.expiration, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_append_uint32(p, rr->rrsig.inception, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_append_uint8(p, rr->rrsig.key_tag, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_append_name(p, rr->rrsig.signer, false, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_append_blob(p, rr->rrsig.signature, rr->rrsig.signature_size, NULL);
+                break;
+
+        case _DNS_TYPE_INVALID: /* unparseable */
+        default:
+
+                r = dns_packet_append_blob(p, rr->generic.data, rr->generic.size, NULL);
+                break;
+        }
+        if (r < 0)
+                goto fail;
+
+        /* Let's calculate the actual data size and update the field */
+        rdlength = p->size - rdlength_offset - sizeof(uint16_t);
+        if (rdlength > 0xFFFF) {
+                r = ENOSPC;
+                goto fail;
+        }
+
+        end = p->size;
+        p->size = rdlength_offset;
+        r = dns_packet_append_uint16(p, rdlength, NULL);
+        if (r < 0)
+                goto fail;
+        p->size = end;
+
+        if (start)
+                *start = saved_size;
+
+        return 0;
+
+fail:
+        dns_packet_truncate(p, saved_size);
+        return r;
+}
+
+
+int dns_packet_read(DnsPacket *p, size_t sz, const void **ret, size_t *start) {
+        assert(p);
+
+        if (p->rindex + sz > p->size)
+                return -EMSGSIZE;
+
+        if (ret)
+                *ret = (uint8_t*) DNS_PACKET_DATA(p) + p->rindex;
+
+        if (start)
+                *start = p->rindex;
+
+        p->rindex += sz;
+        return 0;
+}
+
+void dns_packet_rewind(DnsPacket *p, size_t idx) {
+        assert(p);
+        assert(idx <= p->size);
+        assert(idx >= DNS_PACKET_HEADER_SIZE);
+
+        p->rindex = idx;
+}
+
+int dns_packet_read_blob(DnsPacket *p, void *d, size_t sz, size_t *start) {
+        const void *q;
+        int r;
+
+        assert(p);
+        assert(d);
+
+        r = dns_packet_read(p, sz, &q, start);
+        if (r < 0)
+                return r;
+
+        memcpy(d, q, sz);
+        return 0;
+}
+
+int dns_packet_read_uint8(DnsPacket *p, uint8_t *ret, size_t *start) {
+        const void *d;
+        int r;
+
+        assert(p);
+
+        r = dns_packet_read(p, sizeof(uint8_t), &d, start);
+        if (r < 0)
+                return r;
+
+        *ret = ((uint8_t*) d)[0];
+        return 0;
+}
+
+int dns_packet_read_uint16(DnsPacket *p, uint16_t *ret, size_t *start) {
+        const void *d;
+        int r;
+
+        assert(p);
+
+        r = dns_packet_read(p, sizeof(uint16_t), &d, start);
+        if (r < 0)
+                return r;
+
+        *ret = (((uint16_t) ((uint8_t*) d)[0]) << 8) |
+                ((uint16_t) ((uint8_t*) d)[1]);
+        return 0;
+}
+
+int dns_packet_read_uint32(DnsPacket *p, uint32_t *ret, size_t *start) {
+        const void *d;
+        int r;
+
+        assert(p);
+
+        r = dns_packet_read(p, sizeof(uint32_t), &d, start);
+        if (r < 0)
+                return r;
+
+        *ret = (((uint32_t) ((uint8_t*) d)[0]) << 24) |
+               (((uint32_t) ((uint8_t*) d)[1]) << 16) |
+               (((uint32_t) ((uint8_t*) d)[2]) << 8) |
+                ((uint32_t) ((uint8_t*) d)[3]);
+
+        return 0;
+}
+
+int dns_packet_read_string(DnsPacket *p, char **ret, size_t *start) {
+        size_t saved_rindex;
+        const void *d;
+        char *t;
+        uint8_t c;
+        int r;
+
+        assert(p);
+
+        saved_rindex = p->rindex;
+
+        r = dns_packet_read_uint8(p, &c, NULL);
+        if (r < 0)
+                goto fail;
+
+        r = dns_packet_read(p, c, &d, NULL);
+        if (r < 0)
+                goto fail;
+
+        if (memchr(d, 0, c)) {
+                r = -EBADMSG;
+                goto fail;
+        }
+
+        t = strndup(d, c);
+        if (!t) {
+                r = -ENOMEM;
+                goto fail;
+        }
+
+        if (!utf8_is_valid(t)) {
+                free(t);
+                r = -EBADMSG;
+                goto fail;
+        }
+
+        *ret = t;
+
+        if (start)
+                *start = saved_rindex;
+
+        return 0;
+
+fail:
+        dns_packet_rewind(p, saved_rindex);
+        return r;
+}
+
+int dns_packet_read_name(DnsPacket *p, char **_ret,
+                         bool allow_compression, size_t *start) {
+        size_t saved_rindex, after_rindex = 0;
+        _cleanup_free_ char *ret = NULL;
+        size_t n = 0, allocated = 0;
+        bool first = true;
+        int r;
+
+        assert(p);
+        assert(_ret);
+
+        saved_rindex = p->rindex;
+
+        for (;;) {
+                uint8_t c, d;
+
+                r = dns_packet_read_uint8(p, &c, NULL);
+                if (r < 0)
+                        goto fail;
+
+                if (c == 0)
+                        /* End of name */
+                        break;
+                else if (c <= 63) {
+                        _cleanup_free_ char *t = NULL;
+                        const char *label;
+
+                        /* Literal label */
+                        r = dns_packet_read(p, c, (const void**) &label, NULL);
+                        if (r < 0)
+                                goto fail;
+
+                        r = dns_label_escape(label, c, &t);
+                        if (r < 0)
+                                goto fail;
+
+                        if (!GREEDY_REALLOC(ret, allocated, n + !first + strlen(t) + 1)) {
+                                r = -ENOMEM;
+                                goto fail;
+                        }
+
+                        if (!first)
+                                ret[n++] = '.';
+                        else
+                                first = false;
+
+                        memcpy(ret + n, t, r);
+                        n += r;
+                        continue;
+                } else if (allow_compression && (c & 0xc0) == 0xc0) {
+                        uint16_t ptr;
+
+                        /* Pointer */
+                        r = dns_packet_read_uint8(p, &d, NULL);
+                        if (r < 0)
+                                goto fail;
+
+                        ptr = (uint16_t) (c & ~0xc0) << 8 | (uint16_t) d;
+                        if (ptr < DNS_PACKET_HEADER_SIZE || ptr >= saved_rindex) {
+                                r = -EBADMSG;
+                                goto fail;
+                        }
+
+                        if (after_rindex == 0)
+                                after_rindex = p->rindex;
+
+                        p->rindex = ptr;
+                } else
+                        goto fail;
+        }
+
+        if (!GREEDY_REALLOC(ret, allocated, n + 1)) {
+                r = -ENOMEM;
+                goto fail;
+        }
+
+        ret[n] = 0;
+
+        if (after_rindex != 0)
+                p->rindex= after_rindex;
+
+        *_ret = ret;
+        ret = NULL;
+
+        if (start)
+                *start = saved_rindex;
+
+        return 0;
+
+fail:
+        dns_packet_rewind(p, saved_rindex);
+        return r;
+}
+
+int dns_packet_read_key(DnsPacket *p, DnsResourceKey **ret, size_t *start) {
+        _cleanup_free_ char *name = NULL;
+        uint16_t class, type;
+        DnsResourceKey *key;
+        size_t saved_rindex;
+        int r;
+
+        assert(p);
+        assert(ret);
+
+        saved_rindex = p->rindex;
+
+        r = dns_packet_read_name(p, &name, true, NULL);
+        if (r < 0)
+                goto fail;
+
+        r = dns_packet_read_uint16(p, &type, NULL);
+        if (r < 0)
+                goto fail;
+
+        r = dns_packet_read_uint16(p, &class, NULL);
+        if (r < 0)
+                goto fail;
+
+        key = dns_resource_key_new_consume(class, type, name);
+        if (!key) {
+                r = -ENOMEM;
+                goto fail;
+        }
+
+        name = NULL;
+        *ret = key;
+
+        if (start)
+                *start = saved_rindex;
+
+        return 0;
+fail:
+        dns_packet_rewind(p, saved_rindex);
+        return r;
+}
+
+static int dns_packet_read_public_key(DnsPacket *p, size_t length,
+                                      void **dp, size_t *lengthp,
+                                      size_t *start) {
+        int r;
+        const void *d;
+        void *d2;
+
+        r = dns_packet_read(p, length, &d, NULL);
+        if (r < 0)
+                return r;
+
+        d2 = memdup(d, length);
+        if (!d2)
+                return -ENOMEM;
+
+        *dp = d2;
+        *lengthp = length;
+        return 0;
+}
+
+static bool loc_size_ok(uint8_t size) {
+        uint8_t m = size >> 4, e = size & 0xF;
+
+        return m <= 9 && e <= 9 && (m > 0 || e == 0);
+}
+
+static int dnskey_parse_flags(DnsResourceRecord *rr, uint16_t flags) {
+        assert(rr);
+
+        if (flags & ~(DNSKEY_FLAG_SEP | DNSKEY_FLAG_ZONE_KEY))
+                return -EBADMSG;
+
+        rr->dnskey.zone_key_flag = flags & DNSKEY_FLAG_ZONE_KEY;
+        rr->dnskey.sep_flag = flags & DNSKEY_FLAG_SEP;
+        return 0;
+}
+
+int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) {
+        _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
+        _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
+        size_t saved_rindex, offset;
+        uint16_t rdlength;
+        const void *d;
+        int r;
+
+        assert(p);
+        assert(ret);
+
+        saved_rindex = p->rindex;
+
+        r = dns_packet_read_key(p, &key, NULL);
+        if (r < 0)
+                goto fail;
+
+        if (key->class == DNS_CLASS_ANY ||
+            key->type == DNS_TYPE_ANY) {
+                r = -EBADMSG;
+                goto fail;
+        }
+
+        rr = dns_resource_record_new(key);
+        if (!rr) {
+                r = -ENOMEM;
+                goto fail;
+        }
+
+        r = dns_packet_read_uint32(p, &rr->ttl, NULL);
+        if (r < 0)
+                goto fail;
+
+        r = dns_packet_read_uint16(p, &rdlength, NULL);
+        if (r < 0)
+                goto fail;
+
+        if (p->rindex + rdlength > p->size) {
+                r = -EBADMSG;
+                goto fail;
+        }
+
+        offset = p->rindex;
+
+        switch (rr->key->type) {
+
+        case DNS_TYPE_SRV:
+                r = dns_packet_read_uint16(p, &rr->srv.priority, NULL);
+                if (r < 0)
+                        goto fail;
+                r = dns_packet_read_uint16(p, &rr->srv.weight, NULL);
+                if (r < 0)
+                        goto fail;
+                r = dns_packet_read_uint16(p, &rr->srv.port, NULL);
+                if (r < 0)
+                        goto fail;
+                r = dns_packet_read_name(p, &rr->srv.name, true, NULL);
+                break;
+
+        case DNS_TYPE_PTR:
+        case DNS_TYPE_NS:
+        case DNS_TYPE_CNAME:
+        case DNS_TYPE_DNAME:
+                r = dns_packet_read_name(p, &rr->ptr.name, true, NULL);
+                break;
+
+        case DNS_TYPE_HINFO:
+                r = dns_packet_read_string(p, &rr->hinfo.cpu, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_read_string(p, &rr->hinfo.os, NULL);
+                break;
+
+        case DNS_TYPE_SPF: /* exactly the same as TXT */
+        case DNS_TYPE_TXT: {
+                char *s;
+
+                while (p->rindex < offset + rdlength) {
+                        r = dns_packet_read_string(p, &s, NULL);
+                        if (r < 0)
+                                goto fail;
+
+                        r = strv_consume(&rr->txt.strings, s);
+                        if (r < 0)
+                                goto fail;
+                }
+
+                r = 0;
+                break;
+        }
+
+        case DNS_TYPE_A:
+                r = dns_packet_read_blob(p, &rr->a.in_addr, sizeof(struct in_addr), NULL);
+                break;
+
+        case DNS_TYPE_AAAA:
+                r = dns_packet_read_blob(p, &rr->aaaa.in6_addr, sizeof(struct in6_addr), NULL);
+                break;
+
+        case DNS_TYPE_SOA:
+                r = dns_packet_read_name(p, &rr->soa.mname, true, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_read_name(p, &rr->soa.rname, true, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_read_uint32(p, &rr->soa.serial, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_read_uint32(p, &rr->soa.refresh, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_read_uint32(p, &rr->soa.retry, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_read_uint32(p, &rr->soa.expire, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_read_uint32(p, &rr->soa.minimum, NULL);
+                break;
+
+        case DNS_TYPE_MX:
+                r = dns_packet_read_uint16(p, &rr->mx.priority, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_read_name(p, &rr->mx.exchange, true, NULL);
+                break;
+
+        case DNS_TYPE_LOC: {
+                uint8_t t;
+                size_t pos;
+
+                r = dns_packet_read_uint8(p, &t, &pos);
+                if (r < 0)
+                        goto fail;
+
+                if (t == 0) {
+                        rr->loc.version = t;
+
+                        r = dns_packet_read_uint8(p, &rr->loc.size, NULL);
+                        if (r < 0)
+                                goto fail;
+
+                        if (!loc_size_ok(rr->loc.size)) {
+                                r = -EBADMSG;
+                                goto fail;
+                        }
+
+                        r = dns_packet_read_uint8(p, &rr->loc.horiz_pre, NULL);
+                        if (r < 0)
+                                goto fail;
+
+                        if (!loc_size_ok(rr->loc.horiz_pre)) {
+                                r = -EBADMSG;
+                                goto fail;
+                        }
+
+                        r = dns_packet_read_uint8(p, &rr->loc.vert_pre, NULL);
+                        if (r < 0)
+                                goto fail;
+
+                        if (!loc_size_ok(rr->loc.vert_pre)) {
+                                r = -EBADMSG;
+                                goto fail;
+                        }
+
+                        r = dns_packet_read_uint32(p, &rr->loc.latitude, NULL);
+                        if (r < 0)
+                                goto fail;
+
+                        r = dns_packet_read_uint32(p, &rr->loc.longitude, NULL);
+                        if (r < 0)
+                                goto fail;
+
+                        r = dns_packet_read_uint32(p, &rr->loc.altitude, NULL);
+                        if (r < 0)
+                                goto fail;
+
+                        break;
+                } else {
+                        dns_packet_rewind(p, pos);
+                        rr->unparseable = true;
+                        goto unparseable;
+                }
+        }
+
+        case DNS_TYPE_SSHFP:
+                r = dns_packet_read_uint8(p, &rr->sshfp.algorithm, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_read_uint8(p, &rr->sshfp.fptype, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_read_public_key(p, rdlength - 2,
+                                               &rr->sshfp.key, &rr->sshfp.key_size,
+                                               NULL);
+                break;
+
+        case DNS_TYPE_DNSKEY: {
+                uint16_t flags;
+                uint8_t proto;
+
+                r = dns_packet_read_uint16(p, &flags, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dnskey_parse_flags(rr, flags);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_read_uint8(p, &proto, NULL);
+                if (r < 0)
+                        goto fail;
+
+                /* protocol is required to be always 3 */
+                if (proto != 3) {
+                        r = -EBADMSG;
+                        goto fail;
+                }
+
+                r = dns_packet_read_uint8(p, &rr->dnskey.algorithm, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_read_public_key(p, rdlength - 4,
+                                               &rr->dnskey.key, &rr->dnskey.key_size,
+                                               NULL);
+                break;
+        }
+
+        case DNS_TYPE_RRSIG:
+                r = dns_packet_read_uint16(p, &rr->rrsig.type_covered, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_read_uint8(p, &rr->rrsig.algorithm, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_read_uint8(p, &rr->rrsig.labels, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_read_uint32(p, &rr->rrsig.original_ttl, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_read_uint32(p, &rr->rrsig.expiration, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_read_uint32(p, &rr->rrsig.inception, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_read_uint16(p, &rr->rrsig.key_tag, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_read_name(p, &rr->rrsig.signer, false, NULL);
+                if (r < 0)
+                        goto fail;
+
+                r = dns_packet_read_public_key(p, offset + rdlength - p->rindex,
+                                               &rr->rrsig.signature, &rr->rrsig.signature_size,
+                                               NULL);
+                break;
+
+        default:
+        unparseable:
+                r = dns_packet_read(p, rdlength, &d, NULL);
+                if (r < 0)
+                        goto fail;
+
+                rr->generic.data = memdup(d, rdlength);
+                if (!rr->generic.data) {
+                        r = -ENOMEM;
+                        goto fail;
+                }
+
+                rr->generic.size = rdlength;
+                break;
+        }
+        if (r < 0)
+                goto fail;
+        if (p->rindex != offset + rdlength) {
+                r = -EBADMSG;
+                goto fail;
+        }
+
+        *ret = rr;
+        rr = NULL;
+
+        if (start)
+                *start = saved_rindex;
+
+        return 0;
+fail:
+        dns_packet_rewind(p, saved_rindex);
+        return r;
+}
+
+int dns_packet_extract(DnsPacket *p) {
+        _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
+        _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
+        size_t saved_rindex;
+        unsigned n, i;
+        int r;
+
+        if (p->extracted)
+                return 0;
+
+        saved_rindex = p->rindex;
+        dns_packet_rewind(p, DNS_PACKET_HEADER_SIZE);
+
+        n = DNS_PACKET_QDCOUNT(p);
+        if (n > 0) {
+                question = dns_question_new(n);
+                if (!question) {
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                for (i = 0; i < n; i++) {
+                        _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
+
+                        r = dns_packet_read_key(p, &key, NULL);
+                        if (r < 0)
+                                goto finish;
+
+                        r = dns_question_add(question, key);
+                        if (r < 0)
+                                goto finish;
+                }
+        }
+
+        n = DNS_PACKET_RRCOUNT(p);
+        if (n > 0) {
+                answer = dns_answer_new(n);
+                if (!answer) {
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                for (i = 0; i < n; i++) {
+                        _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
+
+                        r = dns_packet_read_rr(p, &rr, NULL);
+                        if (r < 0)
+                                goto finish;
+
+                        r = dns_answer_add(answer, rr);
+                        if (r < 0)
+                                goto finish;
+                }
+        }
+
+        p->question = question;
+        question = NULL;
+
+        p->answer = answer;
+        answer = NULL;
+
+        p->extracted = true;
+
+        r = 0;
+
+finish:
+        p->rindex = saved_rindex;
+        return r;
+}
+
+static const char* const dns_rcode_table[_DNS_RCODE_MAX_DEFINED] = {
+        [DNS_RCODE_SUCCESS] = "SUCCESS",
+        [DNS_RCODE_FORMERR] = "FORMERR",
+        [DNS_RCODE_SERVFAIL] = "SERVFAIL",
+        [DNS_RCODE_NXDOMAIN] = "NXDOMAIN",
+        [DNS_RCODE_NOTIMP] = "NOTIMP",
+        [DNS_RCODE_REFUSED] = "REFUSED",
+        [DNS_RCODE_YXDOMAIN] = "YXDOMAIN",
+        [DNS_RCODE_YXRRSET] = "YRRSET",
+        [DNS_RCODE_NXRRSET] = "NXRRSET",
+        [DNS_RCODE_NOTAUTH] = "NOTAUTH",
+        [DNS_RCODE_NOTZONE] = "NOTZONE",
+        [DNS_RCODE_BADVERS] = "BADVERS",
+        [DNS_RCODE_BADKEY] = "BADKEY",
+        [DNS_RCODE_BADTIME] = "BADTIME",
+        [DNS_RCODE_BADMODE] = "BADMODE",
+        [DNS_RCODE_BADNAME] = "BADNAME",
+        [DNS_RCODE_BADALG] = "BADALG",
+        [DNS_RCODE_BADTRUNC] = "BADTRUNC",
+};
+DEFINE_STRING_TABLE_LOOKUP(dns_rcode, int);
+
+static const char* const dns_protocol_table[_DNS_PROTOCOL_MAX] = {
+        [DNS_PROTOCOL_DNS] = "dns",
+        [DNS_PROTOCOL_MDNS] = "mdns",
+        [DNS_PROTOCOL_LLMNR] = "llmnr",
+};
+DEFINE_STRING_TABLE_LOOKUP(dns_protocol, DnsProtocol);
+
+static const char* const dnssec_algorithm_table[_DNSSEC_ALGORITHM_MAX_DEFINED] = {
+        [DNSSEC_ALGORITHM_RSAMD5]     = "RSAMD5",
+        [DNSSEC_ALGORITHM_DH]         = "DH",
+        [DNSSEC_ALGORITHM_DSA]        = "DSA",
+        [DNSSEC_ALGORITHM_ECC]        = "ECC",
+        [DNSSEC_ALGORITHM_RSASHA1]    = "RSASHA1",
+        [DNSSEC_ALGORITHM_INDIRECT]   = "INDIRECT",
+        [DNSSEC_ALGORITHM_PRIVATEDNS] = "PRIVATEDNS",
+        [DNSSEC_ALGORITHM_PRIVATEOID] = "PRIVATEOID",
+};
+DEFINE_STRING_TABLE_LOOKUP(dnssec_algorithm, int);
diff --git a/src/resolve/resolved-dns-packet.h b/src/resolve/resolved-dns-packet.h
new file mode 100644 (file)
index 0000000..561dd3a
--- /dev/null
@@ -0,0 +1,236 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+ ***/
+
+#include <inttypes.h>
+
+#include "macro.h"
+#include "sparse-endian.h"
+#include "hashmap.h"
+#include "in-addr-util.h"
+
+typedef struct DnsPacketHeader DnsPacketHeader;
+typedef struct DnsPacket DnsPacket;
+
+#include "resolved-dns-rr.h"
+#include "resolved-dns-question.h"
+#include "resolved-dns-answer.h"
+#include "resolved-def.h"
+
+typedef enum DnsProtocol {
+        DNS_PROTOCOL_DNS,
+        DNS_PROTOCOL_MDNS,
+        DNS_PROTOCOL_LLMNR,
+        _DNS_PROTOCOL_MAX,
+        _DNS_PROTOCOL_INVALID = -1
+} DnsProtocol;
+
+struct DnsPacketHeader {
+        uint16_t id;
+        be16_t flags;
+        be16_t qdcount;
+        be16_t ancount;
+        be16_t nscount;
+        be16_t arcount;
+};
+
+#define DNS_PACKET_HEADER_SIZE sizeof(DnsPacketHeader)
+
+/* The various DNS protocols deviate in how large a packet can grow,
+   but the TCP transport has a 16bit size field, hence that appears to
+   be the absolute maximum. */
+#define DNS_PACKET_SIZE_MAX 0xFFFF
+
+/* RFC 1035 say 512 is the maximum, for classic unicast DNS */
+#define DNS_PACKET_UNICAST_SIZE_MAX 512
+
+#define DNS_PACKET_SIZE_START 512
+
+struct DnsPacket {
+        int n_ref;
+        DnsProtocol protocol;
+        size_t size, allocated, rindex;
+        void *_data; /* don't access directly, use DNS_PACKET_DATA()! */
+        Hashmap *names; /* For name compression */
+
+        /* Parsed data */
+        DnsQuestion *question;
+        DnsAnswer *answer;
+
+        /* Packet reception meta data */
+        int ifindex;
+        int family, ipproto;
+        union in_addr_union sender, destination;
+        uint16_t sender_port, destination_port;
+        uint32_t ttl;
+
+        bool extracted;
+};
+
+static inline uint8_t* DNS_PACKET_DATA(DnsPacket *p) {
+        if (_unlikely_(!p))
+                return NULL;
+
+        if (p->_data)
+                return p->_data;
+
+        return ((uint8_t*) p) + ALIGN(sizeof(DnsPacket));
+}
+
+#define DNS_PACKET_HEADER(p) ((DnsPacketHeader*) DNS_PACKET_DATA(p))
+#define DNS_PACKET_ID(p) DNS_PACKET_HEADER(p)->id
+#define DNS_PACKET_QR(p) ((be16toh(DNS_PACKET_HEADER(p)->flags) >> 15) & 1)
+#define DNS_PACKET_OPCODE(p) ((be16toh(DNS_PACKET_HEADER(p)->flags) >> 11) & 15)
+#define DNS_PACKET_RCODE(p) (be16toh(DNS_PACKET_HEADER(p)->flags) & 15)
+#define DNS_PACKET_TC(p) ((be16toh(DNS_PACKET_HEADER(p)->flags) >> 9) & 1)
+#define DNS_PACKET_C(p) ((be16toh(DNS_PACKET_HEADER(p)->flags) >> 10) & 1)
+#define DNS_PACKET_T(p) ((be16toh(DNS_PACKET_HEADER(p)->flags) >> 8) & 1)
+#define DNS_PACKET_QDCOUNT(p) be16toh(DNS_PACKET_HEADER(p)->qdcount)
+#define DNS_PACKET_ANCOUNT(p) be16toh(DNS_PACKET_HEADER(p)->ancount)
+#define DNS_PACKET_NSCOUNT(p) be16toh(DNS_PACKET_HEADER(p)->nscount)
+#define DNS_PACKET_ARCOUNT(p) be16toh(DNS_PACKET_HEADER(p)->arcount)
+
+#define DNS_PACKET_MAKE_FLAGS(qr, opcode, aa, tc, rd, ra, ad, cd, rcode) \
+        (((uint16_t) !!qr << 15) |  \
+         ((uint16_t) (opcode & 15) << 11) | \
+         ((uint16_t) !!aa << 10) | \
+         ((uint16_t) !!tc << 9) | \
+         ((uint16_t) !!rd << 8) | \
+         ((uint16_t) !!ra << 7) | \
+         ((uint16_t) !!ad << 5) | \
+         ((uint16_t) !!cd << 4) | \
+         ((uint16_t) (rcode & 15)))
+
+static inline unsigned DNS_PACKET_RRCOUNT(DnsPacket *p) {
+        return
+                (unsigned) DNS_PACKET_ANCOUNT(p) +
+                (unsigned) DNS_PACKET_NSCOUNT(p) +
+                (unsigned) DNS_PACKET_ARCOUNT(p);
+}
+
+int dns_packet_new(DnsPacket **p, DnsProtocol protocol, size_t mtu);
+int dns_packet_new_query(DnsPacket **p, DnsProtocol protocol, size_t mtu);
+
+DnsPacket *dns_packet_ref(DnsPacket *p);
+DnsPacket *dns_packet_unref(DnsPacket *p);
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(DnsPacket*, dns_packet_unref);
+
+int dns_packet_validate(DnsPacket *p);
+int dns_packet_validate_reply(DnsPacket *p);
+int dns_packet_validate_query(DnsPacket *p);
+
+int dns_packet_append_blob(DnsPacket *p, const void *d, size_t sz, size_t *start);
+int dns_packet_append_uint8(DnsPacket *p, uint8_t v, size_t *start);
+int dns_packet_append_uint16(DnsPacket *p, uint16_t v, size_t *start);
+int dns_packet_append_uint32(DnsPacket *p, uint32_t v, size_t *start);
+int dns_packet_append_string(DnsPacket *p, const char *s, size_t *start);
+int dns_packet_append_label(DnsPacket *p, const char *s, size_t l, size_t *start);
+int dns_packet_append_name(DnsPacket *p, const char *name,
+                           bool allow_compression, size_t *start);
+int dns_packet_append_key(DnsPacket *p, const DnsResourceKey *key, size_t *start);
+int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, size_t *start);
+
+int dns_packet_read(DnsPacket *p, size_t sz, const void **ret, size_t *start);
+int dns_packet_read_blob(DnsPacket *p, void *d, size_t sz, size_t *start);
+int dns_packet_read_uint8(DnsPacket *p, uint8_t *ret, size_t *start);
+int dns_packet_read_uint16(DnsPacket *p, uint16_t *ret, size_t *start);
+int dns_packet_read_uint32(DnsPacket *p, uint32_t *ret, size_t *start);
+int dns_packet_read_string(DnsPacket *p, char **ret, size_t *start);
+int dns_packet_read_name(DnsPacket *p, char **ret,
+                         bool allow_compression, size_t *start);
+int dns_packet_read_key(DnsPacket *p, DnsResourceKey **ret, size_t *start);
+int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start);
+
+void dns_packet_rewind(DnsPacket *p, size_t idx);
+
+int dns_packet_skip_question(DnsPacket *p);
+int dns_packet_extract(DnsPacket *p);
+
+enum {
+        DNS_RCODE_SUCCESS = 0,
+        DNS_RCODE_FORMERR = 1,
+        DNS_RCODE_SERVFAIL = 2,
+        DNS_RCODE_NXDOMAIN = 3,
+        DNS_RCODE_NOTIMP = 4,
+        DNS_RCODE_REFUSED = 5,
+        DNS_RCODE_YXDOMAIN = 6,
+        DNS_RCODE_YXRRSET = 7,
+        DNS_RCODE_NXRRSET = 8,
+        DNS_RCODE_NOTAUTH = 9,
+        DNS_RCODE_NOTZONE = 10,
+        DNS_RCODE_BADVERS = 16,
+        DNS_RCODE_BADSIG = 16, /* duplicate value! */
+        DNS_RCODE_BADKEY = 17,
+        DNS_RCODE_BADTIME = 18,
+        DNS_RCODE_BADMODE = 19,
+        DNS_RCODE_BADNAME = 20,
+        DNS_RCODE_BADALG = 21,
+        DNS_RCODE_BADTRUNC = 22,
+        _DNS_RCODE_MAX_DEFINED
+};
+
+const char* dns_rcode_to_string(int i) _const_;
+int dns_rcode_from_string(const char *s) _pure_;
+
+const char* dns_protocol_to_string(DnsProtocol p) _const_;
+DnsProtocol dns_protocol_from_string(const char *s) _pure_;
+
+#define LLMNR_MULTICAST_IPV4_ADDRESS ((struct in_addr) { .s_addr = htobe32(224U << 24 | 252U) })
+#define LLMNR_MULTICAST_IPV6_ADDRESS ((struct in6_addr) { .s6_addr = { 0xFF, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03 } })
+
+#define DNSKEY_FLAG_ZONE_KEY (1u << 8)
+#define DNSKEY_FLAG_SEP      (1u << 0)
+
+static inline uint16_t dnskey_to_flags(const DnsResourceRecord *rr) {
+        return (rr->dnskey.zone_key_flag * DNSKEY_FLAG_ZONE_KEY |
+                rr->dnskey.sep_flag * DNSKEY_FLAG_SEP);
+}
+
+/* http://tools.ietf.org/html/rfc4034#appendix-A.1 */
+enum {
+        DNSSEC_ALGORITHM_RSAMD5 = 1,
+        DNSSEC_ALGORITHM_DH,
+        DNSSEC_ALGORITHM_DSA,
+        DNSSEC_ALGORITHM_ECC,
+        DNSSEC_ALGORITHM_RSASHA1,
+        DNSSEC_ALGORITHM_INDIRECT = 252,
+        DNSSEC_ALGORITHM_PRIVATEDNS,
+        DNSSEC_ALGORITHM_PRIVATEOID,
+        _DNSSEC_ALGORITHM_MAX_DEFINED
+};
+
+const char* dnssec_algorithm_to_string(int i) _const_;
+int dnssec_algorithm_from_string(const char *s) _pure_;
+
+static inline uint64_t SD_RESOLVED_FLAGS_MAKE(DnsProtocol protocol, int family) {
+
+        /* Converts a protocol + family into a flags field as used in queries */
+
+        if (protocol == DNS_PROTOCOL_DNS)
+                return SD_RESOLVED_DNS;
+
+        if (protocol == DNS_PROTOCOL_LLMNR)
+                return family == AF_INET6 ? SD_RESOLVED_LLMNR_IPV6 : SD_RESOLVED_LLMNR_IPV4;
+
+        return 0;
+}
diff --git a/src/resolve/resolved-dns-query.c b/src/resolve/resolved-dns-query.c
new file mode 100644 (file)
index 0000000..669595d
--- /dev/null
@@ -0,0 +1,489 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "af-list.h"
+
+#include "resolved-dns-query.h"
+#include "resolved-dns-domain.h"
+
+/* How long to wait for the query in total */
+#define QUERY_TIMEOUT_USEC (30 * USEC_PER_SEC)
+
+#define CNAME_MAX 8
+#define QUERIES_MAX 2048
+
+static void dns_query_stop(DnsQuery *q) {
+        DnsTransaction *t;
+
+        assert(q);
+
+        q->timeout_event_source = sd_event_source_unref(q->timeout_event_source);
+
+        while ((t = set_steal_first(q->transactions))) {
+                set_remove(t->queries, q);
+                dns_transaction_gc(t);
+        }
+}
+
+DnsQuery *dns_query_free(DnsQuery *q) {
+        if (!q)
+                return NULL;
+
+        dns_query_stop(q);
+        set_free(q->transactions);
+
+        dns_question_unref(q->question);
+        dns_answer_unref(q->answer);
+
+        sd_bus_message_unref(q->request);
+        sd_bus_track_unref(q->bus_track);
+
+        if (q->manager) {
+                LIST_REMOVE(queries, q->manager->dns_queries, q);
+                q->manager->n_dns_queries--;
+        }
+
+        free(q);
+
+        return NULL;
+}
+
+int dns_query_new(Manager *m, DnsQuery **ret, DnsQuestion *question, int ifindex, uint64_t flags) {
+        _cleanup_(dns_query_freep) DnsQuery *q = NULL;
+        unsigned i;
+        int r;
+
+        assert(m);
+        assert(question);
+
+        r = dns_question_is_valid(question);
+        if (r < 0)
+                return r;
+
+        if (m->n_dns_queries >= QUERIES_MAX)
+                return -EBUSY;
+
+        q = new0(DnsQuery, 1);
+        if (!q)
+                return -ENOMEM;
+
+        q->question = dns_question_ref(question);
+        q->ifindex = ifindex;
+        q->flags = flags;
+
+        for (i = 0; i < question->n_keys; i++) {
+                _cleanup_free_ char *p;
+
+                r = dns_resource_key_to_string(question->keys[i], &p);
+                if (r < 0)
+                        return r;
+
+                log_debug("Looking up RR for %s", p);
+        }
+
+        LIST_PREPEND(queries, m->dns_queries, q);
+        m->n_dns_queries++;
+        q->manager = m;
+
+        if (ret)
+                *ret = q;
+        q = NULL;
+
+        return 0;
+}
+
+static void dns_query_complete(DnsQuery *q, DnsTransactionState state) {
+        assert(q);
+        assert(!IN_SET(state, DNS_TRANSACTION_NULL, DNS_TRANSACTION_PENDING));
+        assert(IN_SET(q->state, DNS_TRANSACTION_NULL, DNS_TRANSACTION_PENDING));
+
+        /* Note that this call might invalidate the query. Callers
+         * should hence not attempt to access the query or transaction
+         * after calling this function. */
+
+        q->state = state;
+
+        dns_query_stop(q);
+        if (q->complete)
+                q->complete(q);
+}
+
+static int on_query_timeout(sd_event_source *s, usec_t usec, void *userdata) {
+        DnsQuery *q = userdata;
+
+        assert(s);
+        assert(q);
+
+        dns_query_complete(q, DNS_TRANSACTION_TIMEOUT);
+        return 0;
+}
+
+static int dns_query_add_transaction(DnsQuery *q, DnsScope *s, DnsResourceKey *key) {
+        _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
+        DnsTransaction *t;
+        int r;
+
+        assert(q);
+        assert(s);
+
+        r = set_ensure_allocated(&q->transactions, NULL, NULL);
+        if (r < 0)
+                return r;
+
+        if (key) {
+                question = dns_question_new(1);
+                if (!question)
+                        return -ENOMEM;
+
+                r = dns_question_add(question, key);
+                if (r < 0)
+                        return r;
+        } else
+                question = dns_question_ref(q->question);
+
+        t = dns_scope_find_transaction(s, question, true);
+        if (!t) {
+                r = dns_transaction_new(&t, s, question);
+                if (r < 0)
+                        return r;
+        }
+
+        r = set_ensure_allocated(&t->queries, NULL, NULL);
+        if (r < 0)
+                goto gc;
+
+        r = set_put(t->queries, q);
+        if (r < 0)
+                goto gc;
+
+        r = set_put(q->transactions, t);
+        if (r < 0) {
+                set_remove(t->queries, q);
+                goto gc;
+        }
+
+        return 0;
+
+gc:
+        dns_transaction_gc(t);
+        return r;
+}
+
+static int dns_query_add_transaction_split(DnsQuery *q, DnsScope *s) {
+        int r;
+
+        assert(q);
+        assert(s);
+
+        if (s->protocol == DNS_PROTOCOL_MDNS) {
+                r = dns_query_add_transaction(q, s, NULL);
+                if (r < 0)
+                        return r;
+        } else {
+                unsigned i;
+
+                /* On DNS and LLMNR we can only send a single
+                 * question per datagram, hence issue multiple
+                 * transactions. */
+
+                for (i = 0; i < q->question->n_keys; i++) {
+                        r = dns_query_add_transaction(q, s, q->question->keys[i]);
+                        if (r < 0)
+                                return r;
+                }
+        }
+
+        return 0;
+}
+
+int dns_query_go(DnsQuery *q) {
+        DnsScopeMatch found = DNS_SCOPE_NO;
+        DnsScope *s, *first = NULL;
+        DnsTransaction *t;
+        const char *name;
+        Iterator i;
+        int r;
+
+        assert(q);
+
+        if (q->state != DNS_TRANSACTION_NULL)
+                return 0;
+
+        assert(q->question);
+        assert(q->question->n_keys > 0);
+
+        name = DNS_RESOURCE_KEY_NAME(q->question->keys[0]);
+
+        LIST_FOREACH(scopes, s, q->manager->dns_scopes) {
+                DnsScopeMatch match;
+
+                match = dns_scope_good_domain(s, q->ifindex, q->flags, name);
+                if (match < 0)
+                        return match;
+
+                if (match == DNS_SCOPE_NO)
+                        continue;
+
+                found = match;
+
+                if (match == DNS_SCOPE_YES) {
+                        first = s;
+                        break;
+                } else {
+                        assert(match == DNS_SCOPE_MAYBE);
+
+                        if (!first)
+                                first = s;
+                }
+        }
+
+        if (found == DNS_SCOPE_NO)
+                return -ESRCH;
+
+        r = dns_query_add_transaction_split(q, first);
+        if (r < 0)
+                goto fail;
+
+        LIST_FOREACH(scopes, s, first->scopes_next) {
+                DnsScopeMatch match;
+
+                match = dns_scope_good_domain(s, q->ifindex, q->flags, name);
+                if (match < 0)
+                        goto fail;
+
+                if (match != found)
+                        continue;
+
+                r = dns_query_add_transaction_split(q, s);
+                if (r < 0)
+                        goto fail;
+        }
+
+        q->answer = dns_answer_unref(q->answer);
+        q->answer_ifindex = 0;
+        q->answer_rcode = 0;
+        q->answer_family = AF_UNSPEC;
+        q->answer_protocol = _DNS_PROTOCOL_INVALID;
+
+        r = sd_event_add_time(
+                        q->manager->event,
+                        &q->timeout_event_source,
+                        clock_boottime_or_monotonic(),
+                        now(clock_boottime_or_monotonic()) + QUERY_TIMEOUT_USEC, 0,
+                        on_query_timeout, q);
+        if (r < 0)
+                goto fail;
+
+        q->state = DNS_TRANSACTION_PENDING;
+        q->block_ready++;
+
+        /* Start the transactions that are not started yet */
+        SET_FOREACH(t, q->transactions, i) {
+                if (t->state != DNS_TRANSACTION_NULL)
+                        continue;
+
+                r = dns_transaction_go(t);
+                if (r < 0)
+                        goto fail;
+        }
+
+        q->block_ready--;
+        dns_query_ready(q);
+
+        return 1;
+
+fail:
+        dns_query_stop(q);
+        return r;
+}
+
+void dns_query_ready(DnsQuery *q) {
+        DnsTransaction *t;
+        DnsTransactionState state = DNS_TRANSACTION_NO_SERVERS;
+        _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
+        int rcode = 0;
+        DnsScope *scope = NULL;
+        bool pending = false;
+        Iterator i;
+
+        assert(q);
+        assert(IN_SET(q->state, DNS_TRANSACTION_NULL, DNS_TRANSACTION_PENDING));
+
+        /* Note that this call might invalidate the query. Callers
+         * should hence not attempt to access the query or transaction
+         * after calling this function, unless the block_ready
+         * counter was explicitly bumped before doing so. */
+
+        if (q->block_ready > 0)
+                return;
+
+        SET_FOREACH(t, q->transactions, i) {
+
+                /* If we found a successful answer, ignore all answers from other scopes */
+                if (state == DNS_TRANSACTION_SUCCESS && t->scope != scope)
+                        continue;
+
+                /* One of the transactions is still going on, let's maybe wait for it */
+                if (IN_SET(t->state, DNS_TRANSACTION_PENDING, DNS_TRANSACTION_NULL)) {
+                        pending = true;
+                        continue;
+                }
+
+                /* One of the transactions is successful, let's use
+                 * it, and copy its data out */
+                if (t->state == DNS_TRANSACTION_SUCCESS) {
+                        DnsAnswer *a;
+
+                        if (t->received) {
+                                rcode = DNS_PACKET_RCODE(t->received);
+                                a = t->received->answer;
+                        } else {
+                                rcode = t->cached_rcode;
+                                a = t->cached;
+                        }
+
+                        if (state == DNS_TRANSACTION_SUCCESS) {
+                                DnsAnswer *merged;
+
+                                merged = dns_answer_merge(answer, a);
+                                if (!merged) {
+                                        dns_query_complete(q, DNS_TRANSACTION_RESOURCES);
+                                        return;
+                                }
+
+                                dns_answer_unref(answer);
+                                answer = merged;
+                        } else {
+                                dns_answer_unref(answer);
+                                answer = dns_answer_ref(a);
+                        }
+
+                        scope = t->scope;
+                        state = DNS_TRANSACTION_SUCCESS;
+                        continue;
+                }
+
+                /* One of the transactions has failed, let's see
+                 * whether we find anything better, but if not, return
+                 * its response data */
+                if (state != DNS_TRANSACTION_SUCCESS && t->state == DNS_TRANSACTION_FAILURE) {
+                        DnsAnswer *a;
+
+                        if (t->received) {
+                                rcode = DNS_PACKET_RCODE(t->received);
+                                a = t->received->answer;
+                        } else {
+                                rcode = t->cached_rcode;
+                                a = t->cached;
+                        }
+
+                        dns_answer_unref(answer);
+                        answer = dns_answer_ref(a);
+
+                        scope = t->scope;
+                        state = DNS_TRANSACTION_FAILURE;
+                        continue;
+                }
+
+                if (state == DNS_TRANSACTION_NO_SERVERS && t->state != DNS_TRANSACTION_NO_SERVERS)
+                        state = t->state;
+        }
+
+        if (pending) {
+
+                /* If so far we weren't successful, and there's
+                 * something still pending, then wait for it */
+                if (state != DNS_TRANSACTION_SUCCESS)
+                        return;
+
+                /* If we already were successful, then only wait for
+                 * other transactions on the same scope to finish. */
+                SET_FOREACH(t, q->transactions, i) {
+                        if (t->scope == scope && IN_SET(t->state, DNS_TRANSACTION_PENDING, DNS_TRANSACTION_NULL))
+                                return;
+                }
+        }
+
+        if (IN_SET(state, DNS_TRANSACTION_SUCCESS, DNS_TRANSACTION_FAILURE)) {
+                q->answer = dns_answer_ref(answer);
+                q->answer_rcode = rcode;
+                q->answer_ifindex = (scope && scope->link) ? scope->link->ifindex : 0;
+                q->answer_protocol = scope ? scope->protocol : _DNS_PROTOCOL_INVALID;
+                q->answer_family = scope ? scope->family : AF_UNSPEC;
+        }
+
+        dns_query_complete(q, state);
+}
+
+int dns_query_cname_redirect(DnsQuery *q, const char *name) {
+        _cleanup_(dns_question_unrefp) DnsQuestion *nq = NULL;
+        int r;
+
+        assert(q);
+
+        if (q->n_cname_redirects > CNAME_MAX)
+                return -ELOOP;
+
+        r = dns_question_cname_redirect(q->question, name, &nq);
+        if (r < 0)
+                return r;
+
+        dns_question_unref(q->question);
+        q->question = nq;
+        nq = NULL;
+
+        q->n_cname_redirects++;
+
+        dns_query_stop(q);
+        q->state = DNS_TRANSACTION_NULL;
+
+        return 0;
+}
+
+static int on_bus_track(sd_bus_track *t, void *userdata) {
+        DnsQuery *q = userdata;
+
+        assert(t);
+        assert(q);
+
+        log_debug("Client of active query vanished, aborting query.");
+        dns_query_complete(q, DNS_TRANSACTION_ABORTED);
+        return 0;
+}
+
+int dns_query_bus_track(DnsQuery *q, sd_bus *bus, sd_bus_message *m) {
+        int r;
+
+        assert(q);
+        assert(m);
+
+        if (!q->bus_track) {
+                r = sd_bus_track_new(bus, &q->bus_track, on_bus_track, q);
+                if (r < 0)
+                        return r;
+        }
+
+        r = sd_bus_track_add_sender(q->bus_track, m);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
diff --git a/src/resolve/resolved-dns-query.h b/src/resolve/resolved-dns-query.h
new file mode 100644 (file)
index 0000000..13b3ee4
--- /dev/null
@@ -0,0 +1,86 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <inttypes.h>
+
+#include "sd-bus.h"
+#include "util.h"
+#include "set.h"
+
+typedef struct DnsQuery DnsQuery;
+
+#include "resolved-dns-scope.h"
+#include "resolved-dns-rr.h"
+#include "resolved-dns-question.h"
+#include "resolved-dns-answer.h"
+#include "resolved-dns-stream.h"
+#include "resolved-dns-transaction.h"
+#include "resolved-manager.h"
+
+struct DnsQuery {
+        Manager *manager;
+        DnsQuestion *question;
+
+        uint64_t flags;
+        int ifindex;
+
+        DnsTransactionState state;
+        unsigned n_cname_redirects;
+
+        sd_event_source *timeout_event_source;
+
+        /* Discovered data */
+        DnsAnswer *answer;
+        int answer_ifindex;
+        int answer_family;
+        DnsProtocol answer_protocol;
+        int answer_rcode;
+
+        /* Bus client information */
+        sd_bus_message *request;
+        int request_family;
+        const char *request_hostname;
+        union in_addr_union request_address;
+
+        /* Completion callback */
+        void (*complete)(DnsQuery* q);
+        unsigned block_ready;
+
+        Set *transactions;
+
+        sd_bus_track *bus_track;
+
+        LIST_FIELDS(DnsQuery, queries);
+};
+
+int dns_query_new(Manager *m, DnsQuery **q, DnsQuestion *question, int family, uint64_t flags);
+DnsQuery *dns_query_free(DnsQuery *q);
+
+int dns_query_go(DnsQuery *q);
+void dns_query_ready(DnsQuery *q);
+
+int dns_query_cname_redirect(DnsQuery *q, const char *name);
+
+int dns_query_bus_track(DnsQuery *q, sd_bus *bus, sd_bus_message *m);
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(DnsQuery*, dns_query_free);
diff --git a/src/resolve/resolved-dns-question.c b/src/resolve/resolved-dns-question.c
new file mode 100644 (file)
index 0000000..45bcbbf
--- /dev/null
@@ -0,0 +1,274 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "resolved-dns-question.h"
+#include "resolved-dns-domain.h"
+
+DnsQuestion *dns_question_new(unsigned n) {
+        DnsQuestion *q;
+
+        assert(n > 0);
+
+        q = malloc0(offsetof(DnsQuestion, keys) + sizeof(DnsResourceKey*) * n);
+        if (!q)
+                return NULL;
+
+        q->n_ref = 1;
+        q->n_allocated = n;
+
+        return q;
+}
+
+DnsQuestion *dns_question_ref(DnsQuestion *q) {
+        if (!q)
+                return NULL;
+
+        assert(q->n_ref > 0);
+        q->n_ref++;
+        return q;
+}
+
+DnsQuestion *dns_question_unref(DnsQuestion *q) {
+        if (!q)
+                return NULL;
+
+        assert(q->n_ref > 0);
+
+        if (q->n_ref == 1) {
+                unsigned i;
+
+                for (i = 0; i < q->n_keys; i++)
+                        dns_resource_key_unref(q->keys[i]);
+                free(q);
+        } else
+                q->n_ref--;
+
+        return  NULL;
+}
+
+int dns_question_add(DnsQuestion *q, DnsResourceKey *key) {
+        unsigned i;
+        int r;
+
+        assert(q);
+        assert(key);
+
+        for (i = 0; i < q->n_keys; i++) {
+                r = dns_resource_key_equal(q->keys[i], key);
+                if (r < 0)
+                        return r;
+                if (r > 0)
+                        return 0;
+        }
+
+        if (q->n_keys >= q->n_allocated)
+                return -ENOSPC;
+
+        q->keys[q->n_keys++] = dns_resource_key_ref(key);
+        return 0;
+}
+
+int dns_question_matches_rr(DnsQuestion *q, DnsResourceRecord *rr) {
+        unsigned i;
+        int r;
+
+        assert(q);
+        assert(rr);
+
+        for (i = 0; i < q->n_keys; i++) {
+                r = dns_resource_key_match_rr(q->keys[i], rr);
+                if (r != 0)
+                        return r;
+        }
+
+        return 0;
+}
+
+int dns_question_matches_cname(DnsQuestion *q, DnsResourceRecord *rr) {
+        unsigned i;
+        int r;
+
+        assert(q);
+        assert(rr);
+
+        for (i = 0; i < q->n_keys; i++) {
+                r = dns_resource_key_match_cname(q->keys[i], rr);
+                if (r != 0)
+                        return r;
+        }
+
+        return 0;
+}
+
+int dns_question_is_valid(DnsQuestion *q) {
+        const char *name;
+        unsigned i;
+        int r;
+
+        assert(q);
+
+        if (q->n_keys <= 0)
+                return 0;
+
+        if (q->n_keys > 65535)
+                return 0;
+
+        name = DNS_RESOURCE_KEY_NAME(q->keys[0]);
+        if (!name)
+                return 0;
+
+        /* Check that all keys in this question bear the same name */
+        for (i = 1; i < q->n_keys; i++) {
+                assert(q->keys[i]);
+
+                r = dns_name_equal(DNS_RESOURCE_KEY_NAME(q->keys[i]), name);
+                if (r <= 0)
+                        return r;
+        }
+
+        return 1;
+}
+
+int dns_question_is_superset(DnsQuestion *q, DnsQuestion *other) {
+        unsigned j;
+        int r;
+
+        assert(q);
+        assert(other);
+
+        /* Checks if all keys in "other" are also contained in "q" */
+
+        for (j = 0; j < other->n_keys; j++) {
+                DnsResourceKey *b = other->keys[j];
+                bool found = false;
+                unsigned i;
+
+                for (i = 0; i < q->n_keys; i++) {
+                        DnsResourceKey *a = q->keys[i];
+
+                        r = dns_name_equal(DNS_RESOURCE_KEY_NAME(a), DNS_RESOURCE_KEY_NAME(b));
+                        if (r < 0)
+                                return r;
+
+                        if (r == 0)
+                                continue;
+
+                        if (a->class != b->class && a->class != DNS_CLASS_ANY)
+                                continue;
+
+                        if (a->type != b->type && a->type != DNS_TYPE_ANY)
+                                continue;
+
+                        found = true;
+                        break;
+                }
+
+                if (!found)
+                        return 0;
+        }
+
+        return 1;
+}
+
+int dns_question_cname_redirect(DnsQuestion *q, const char *name, DnsQuestion **ret) {
+        _cleanup_(dns_question_unrefp) DnsQuestion *n = NULL;
+        bool same = true;
+        unsigned i;
+        int r;
+
+        assert(q);
+        assert(name);
+        assert(ret);
+
+        for (i = 0; i < q->n_keys; i++) {
+                r = dns_name_equal(DNS_RESOURCE_KEY_NAME(q->keys[i]), name);
+                if (r < 0)
+                        return r;
+
+                if (r == 0) {
+                        same = false;
+                        break;
+                }
+        }
+
+        if (same) {
+                /* Shortcut, the names are already right */
+                *ret = dns_question_ref(q);
+                return 0;
+        }
+
+        n = dns_question_new(q->n_keys);
+        if (!n)
+                return -ENOMEM;
+
+        /* Create a new question, and patch in the new name */
+        for (i = 0; i < q->n_keys; i++) {
+                _cleanup_(dns_resource_key_unrefp) DnsResourceKey *k = NULL;
+
+                k = dns_resource_key_new(q->keys[i]->class, q->keys[i]->type, name);
+                if (!k)
+                        return -ENOMEM;
+
+                r = dns_question_add(n, k);
+                if (r < 0)
+                        return r;
+        }
+
+        *ret = n;
+        n = NULL;
+
+        return 1;
+}
+
+int dns_question_endswith(DnsQuestion *q, const char *suffix) {
+        unsigned i;
+
+        assert(q);
+        assert(suffix);
+
+        for (i = 0; i < q->n_keys; i++) {
+                int k;
+
+                k = dns_name_endswith(DNS_RESOURCE_KEY_NAME(q->keys[i]), suffix);
+                if (k <= 0)
+                        return k;
+        }
+
+        return 1;
+}
+
+int dns_question_extract_reverse_address(DnsQuestion *q, int *family, union in_addr_union *address) {
+        unsigned i;
+
+        assert(q);
+        assert(family);
+        assert(address);
+
+        for (i = 0; i < q->n_keys; i++) {
+                int k;
+
+                k = dns_name_address(DNS_RESOURCE_KEY_NAME(q->keys[i]), family, address);
+                if (k != 0)
+                        return k;
+        }
+
+        return 0;
+}
diff --git a/src/resolve/resolved-dns-question.h b/src/resolve/resolved-dns-question.h
new file mode 100644 (file)
index 0000000..4ba2fe9
--- /dev/null
@@ -0,0 +1,52 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+typedef struct DnsQuestion DnsQuestion;
+
+#include "resolved-dns-rr.h"
+
+/* A simple array of resources keys */
+
+struct DnsQuestion {
+        unsigned n_ref;
+        unsigned n_keys, n_allocated;
+        DnsResourceKey* keys[0];
+};
+
+DnsQuestion *dns_question_new(unsigned n);
+DnsQuestion *dns_question_ref(DnsQuestion *q);
+DnsQuestion *dns_question_unref(DnsQuestion *q);
+
+int dns_question_add(DnsQuestion *q, DnsResourceKey *key);
+
+int dns_question_matches_rr(DnsQuestion *q, DnsResourceRecord *rr);
+int dns_question_matches_cname(DnsQuestion *q, DnsResourceRecord *rr);
+int dns_question_is_valid(DnsQuestion *q);
+int dns_question_is_superset(DnsQuestion *q, DnsQuestion *other);
+
+int dns_question_cname_redirect(DnsQuestion *q, const char *name, DnsQuestion **ret);
+
+int dns_question_endswith(DnsQuestion *q, const char *suffix);
+int dns_question_extract_reverse_address(DnsQuestion *q, int *family, union in_addr_union *address);
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(DnsQuestion*, dns_question_unref);
diff --git a/src/resolve/resolved-dns-rr.c b/src/resolve/resolved-dns-rr.c
new file mode 100644 (file)
index 0000000..c792ded
--- /dev/null
@@ -0,0 +1,699 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <math.h>
+
+#include "strv.h"
+
+#include "resolved-dns-domain.h"
+#include "resolved-dns-rr.h"
+#include "resolved-dns-packet.h"
+#include "dns-type.h"
+
+DnsResourceKey* dns_resource_key_new(uint16_t class, uint16_t type, const char *name) {
+        DnsResourceKey *k;
+        size_t l;
+
+        assert(name);
+
+        l = strlen(name);
+        k = malloc0(sizeof(DnsResourceKey) + l + 1);
+        if (!k)
+                return NULL;
+
+        k->n_ref = 1;
+        k->class = class;
+        k->type = type;
+
+        strcpy((char*) k + sizeof(DnsResourceKey), name);
+
+        return k;
+}
+
+DnsResourceKey* dns_resource_key_new_consume(uint16_t class, uint16_t type, char *name) {
+        DnsResourceKey *k;
+
+        assert(name);
+
+        k = new0(DnsResourceKey, 1);
+        if (!k)
+                return NULL;
+
+        k->n_ref = 1;
+        k->class = class;
+        k->type = type;
+        k->_name = name;
+
+        return k;
+}
+
+DnsResourceKey* dns_resource_key_ref(DnsResourceKey *k) {
+
+        if (!k)
+                return NULL;
+
+        assert(k->n_ref > 0);
+        k->n_ref++;
+
+        return k;
+}
+
+DnsResourceKey* dns_resource_key_unref(DnsResourceKey *k) {
+        if (!k)
+                return NULL;
+
+        assert(k->n_ref > 0);
+
+        if (k->n_ref == 1) {
+                free(k->_name);
+                free(k);
+        } else
+                k->n_ref--;
+
+        return NULL;
+}
+
+int dns_resource_key_equal(const DnsResourceKey *a, const DnsResourceKey *b) {
+        int r;
+
+        r = dns_name_equal(DNS_RESOURCE_KEY_NAME(a), DNS_RESOURCE_KEY_NAME(b));
+        if (r <= 0)
+                return r;
+
+        if (a->class != b->class)
+                return 0;
+
+        if (a->type != b->type)
+                return 0;
+
+        return 1;
+}
+
+int dns_resource_key_match_rr(const DnsResourceKey *key, const DnsResourceRecord *rr) {
+        assert(key);
+        assert(rr);
+
+        if (rr->key->class != key->class && key->class != DNS_CLASS_ANY)
+                return 0;
+
+        if (rr->key->type != key->type && key->type != DNS_TYPE_ANY)
+                return 0;
+
+        return dns_name_equal(DNS_RESOURCE_KEY_NAME(rr->key), DNS_RESOURCE_KEY_NAME(key));
+}
+
+int dns_resource_key_match_cname(const DnsResourceKey *key, const DnsResourceRecord *rr) {
+        assert(key);
+        assert(rr);
+
+        if (rr->key->class != key->class && key->class != DNS_CLASS_ANY)
+                return 0;
+
+        if (rr->key->type != DNS_TYPE_CNAME)
+                return 0;
+
+        return dns_name_equal(DNS_RESOURCE_KEY_NAME(rr->key), DNS_RESOURCE_KEY_NAME(key));
+}
+
+unsigned long dns_resource_key_hash_func(const void *i, const uint8_t hash_key[HASH_KEY_SIZE]) {
+        const DnsResourceKey *k = i;
+        unsigned long ul;
+
+        ul = dns_name_hash_func(DNS_RESOURCE_KEY_NAME(k), hash_key);
+        ul = ul * hash_key[0] + ul + k->class;
+        ul = ul * hash_key[1] + ul + k->type;
+
+        return ul;
+}
+
+int dns_resource_key_compare_func(const void *a, const void *b) {
+        const DnsResourceKey *x = a, *y = b;
+        int ret;
+
+        ret = dns_name_compare_func(DNS_RESOURCE_KEY_NAME(x), DNS_RESOURCE_KEY_NAME(y));
+        if (ret != 0)
+                return ret;
+
+        if (x->type < y->type)
+                return -1;
+        if (x->type > y->type)
+                return 1;
+
+        if (x->class < y->class)
+                return -1;
+        if (x->class > y->class)
+                return 1;
+
+        return 0;
+}
+
+int dns_resource_key_to_string(const DnsResourceKey *key, char **ret) {
+        char cbuf[DECIMAL_STR_MAX(uint16_t)], tbuf[DECIMAL_STR_MAX(uint16_t)];
+        const char *c, *t;
+        char *s;
+
+        c = dns_class_to_string(key->class);
+        if (!c) {
+                sprintf(cbuf, "%i", key->class);
+                c = cbuf;
+        }
+
+        t = dns_type_to_string(key->type);
+        if (!t){
+                sprintf(tbuf, "%i", key->type);
+                t = tbuf;
+        }
+
+        if (asprintf(&s, "%s %s %-5s", DNS_RESOURCE_KEY_NAME(key), c, t) < 0)
+                return -ENOMEM;
+
+        *ret = s;
+        return 0;
+}
+
+DnsResourceRecord* dns_resource_record_new(DnsResourceKey *key) {
+        DnsResourceRecord *rr;
+
+        rr = new0(DnsResourceRecord, 1);
+        if (!rr)
+                return NULL;
+
+        rr->n_ref = 1;
+        rr->key = dns_resource_key_ref(key);
+
+        return rr;
+}
+
+DnsResourceRecord* dns_resource_record_new_full(uint16_t class, uint16_t type, const char *name) {
+        _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
+
+        key = dns_resource_key_new(class, type, name);
+        if (!key)
+                return NULL;
+
+        return dns_resource_record_new(key);
+}
+
+DnsResourceRecord* dns_resource_record_ref(DnsResourceRecord *rr) {
+        if (!rr)
+                return NULL;
+
+        assert(rr->n_ref > 0);
+        rr->n_ref++;
+
+        return rr;
+}
+
+DnsResourceRecord* dns_resource_record_unref(DnsResourceRecord *rr) {
+        if (!rr)
+                return NULL;
+
+        assert(rr->n_ref > 0);
+
+        if (rr->n_ref > 1) {
+                rr->n_ref--;
+                return NULL;
+        }
+
+        if (rr->key) {
+                switch(rr->key->type) {
+
+                case DNS_TYPE_SRV:
+                        free(rr->srv.name);
+                        break;
+
+                case DNS_TYPE_PTR:
+                case DNS_TYPE_NS:
+                case DNS_TYPE_CNAME:
+                case DNS_TYPE_DNAME:
+                        free(rr->ptr.name);
+                        break;
+
+                case DNS_TYPE_HINFO:
+                        free(rr->hinfo.cpu);
+                        free(rr->hinfo.os);
+                        break;
+
+                case DNS_TYPE_TXT:
+                case DNS_TYPE_SPF:
+                        strv_free(rr->txt.strings);
+                        break;
+
+                case DNS_TYPE_SOA:
+                        free(rr->soa.mname);
+                        free(rr->soa.rname);
+                        break;
+
+                case DNS_TYPE_MX:
+                        free(rr->mx.exchange);
+                        break;
+
+                case DNS_TYPE_SSHFP:
+                        free(rr->sshfp.key);
+                        break;
+
+                case DNS_TYPE_DNSKEY:
+                        free(rr->dnskey.key);
+                        break;
+
+                case DNS_TYPE_RRSIG:
+                        free(rr->rrsig.signer);
+                        free(rr->rrsig.signature);
+                        break;
+
+                case DNS_TYPE_LOC:
+                case DNS_TYPE_A:
+                case DNS_TYPE_AAAA:
+                        break;
+
+                default:
+                        free(rr->generic.data);
+                }
+
+                dns_resource_key_unref(rr->key);
+        }
+
+        free(rr);
+
+        return NULL;
+}
+
+int dns_resource_record_new_reverse(DnsResourceRecord **ret, int family, const union in_addr_union *address, const char *hostname) {
+        _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
+        _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
+        _cleanup_free_ char *ptr = NULL;
+        int r;
+
+        assert(ret);
+        assert(address);
+        assert(hostname);
+
+        r = dns_name_reverse(family, address, &ptr);
+        if (r < 0)
+                return r;
+
+        key = dns_resource_key_new_consume(DNS_CLASS_IN, DNS_TYPE_PTR, ptr);
+        if (!key)
+                return -ENOMEM;
+
+        ptr = NULL;
+
+        rr = dns_resource_record_new(key);
+        if (!rr)
+                return -ENOMEM;
+
+        rr->ptr.name = strdup(hostname);
+        if (!rr->ptr.name)
+                return -ENOMEM;
+
+        *ret = rr;
+        rr = NULL;
+
+        return 0;
+}
+
+int dns_resource_record_equal(const DnsResourceRecord *a, const DnsResourceRecord *b) {
+        int r;
+
+        assert(a);
+        assert(b);
+
+        r = dns_resource_key_equal(a->key, b->key);
+        if (r <= 0)
+                return r;
+
+        if (a->unparseable != b->unparseable)
+                return 0;
+
+        switch (a->unparseable ? _DNS_TYPE_INVALID : a->key->type) {
+
+        case DNS_TYPE_SRV:
+                r = dns_name_equal(a->srv.name, b->srv.name);
+                if (r <= 0)
+                        return r;
+
+                return a->srv.priority == b->srv.priority &&
+                       a->srv.weight == b->srv.weight &&
+                       a->srv.port == b->srv.port;
+
+        case DNS_TYPE_PTR:
+        case DNS_TYPE_NS:
+        case DNS_TYPE_CNAME:
+        case DNS_TYPE_DNAME:
+                return dns_name_equal(a->ptr.name, b->ptr.name);
+
+        case DNS_TYPE_HINFO:
+                return strcaseeq(a->hinfo.cpu, b->hinfo.cpu) &&
+                       strcaseeq(a->hinfo.os, b->hinfo.os);
+
+        case DNS_TYPE_SPF: /* exactly the same as TXT */
+        case DNS_TYPE_TXT: {
+                int i;
+
+                for (i = 0; a->txt.strings[i] || b->txt.strings[i]; i++)
+                        if (!streq_ptr(a->txt.strings[i], b->txt.strings[i]))
+                                return false;
+                return true;
+        }
+
+        case DNS_TYPE_A:
+                return memcmp(&a->a.in_addr, &b->a.in_addr, sizeof(struct in_addr)) == 0;
+
+        case DNS_TYPE_AAAA:
+                return memcmp(&a->aaaa.in6_addr, &b->aaaa.in6_addr, sizeof(struct in6_addr)) == 0;
+
+        case DNS_TYPE_SOA:
+                r = dns_name_equal(a->soa.mname, b->soa.mname);
+                if (r <= 0)
+                        return r;
+                r = dns_name_equal(a->soa.rname, b->soa.rname);
+                if (r <= 0)
+                        return r;
+
+                return a->soa.serial  == b->soa.serial &&
+                       a->soa.refresh == b->soa.refresh &&
+                       a->soa.retry   == b->soa.retry &&
+                       a->soa.expire  == b->soa.expire &&
+                       a->soa.minimum == b->soa.minimum;
+
+        case DNS_TYPE_MX:
+                if (a->mx.priority != b->mx.priority)
+                        return 0;
+
+                return dns_name_equal(a->mx.exchange, b->mx.exchange);
+
+        case DNS_TYPE_LOC:
+                assert(a->loc.version == b->loc.version);
+
+                return a->loc.size == b->loc.size &&
+                       a->loc.horiz_pre == b->loc.horiz_pre &&
+                       a->loc.vert_pre == b->loc.vert_pre &&
+                       a->loc.latitude == b->loc.latitude &&
+                       a->loc.longitude == b->loc.longitude &&
+                       a->loc.altitude == b->loc.altitude;
+
+        case DNS_TYPE_SSHFP:
+                return a->sshfp.algorithm == b->sshfp.algorithm &&
+                       a->sshfp.fptype == b->sshfp.fptype &&
+                       a->sshfp.key_size == b->sshfp.key_size &&
+                       memcmp(a->sshfp.key, b->sshfp.key, a->sshfp.key_size) == 0;
+
+        case DNS_TYPE_DNSKEY:
+                return a->dnskey.zone_key_flag == b->dnskey.zone_key_flag &&
+                       a->dnskey.sep_flag == b->dnskey.sep_flag &&
+                       a->dnskey.algorithm == b->dnskey.algorithm &&
+                       a->dnskey.key_size == b->dnskey.key_size &&
+                       memcmp(a->dnskey.key, b->dnskey.key, a->dnskey.key_size) == 0;
+
+        case DNS_TYPE_RRSIG:
+                /* do the fast comparisons first */
+                if (a->rrsig.type_covered != a->rrsig.type_covered ||
+                    a->rrsig.algorithm != a->rrsig.algorithm ||
+                    a->rrsig.labels != a->rrsig.labels ||
+                    a->rrsig.original_ttl != a->rrsig.original_ttl ||
+                    a->rrsig.expiration != a->rrsig.expiration ||
+                    a->rrsig.inception != a->rrsig.inception ||
+                    a->rrsig.key_tag != a->rrsig.key_tag ||
+                    a->rrsig.signature_size != b->rrsig.signature_size ||
+                    memcmp(a->rrsig.signature, b->rrsig.signature, a->rrsig.signature_size) != 0)
+                        return false;
+
+                return dns_name_equal(a->rrsig.signer, b->rrsig.signer);
+
+        default:
+                return a->generic.size == b->generic.size &&
+                        memcmp(a->generic.data, b->generic.data, a->generic.size) == 0;
+        }
+}
+
+static char* format_location(uint32_t latitude, uint32_t longitude, uint32_t altitude,
+                             uint8_t size, uint8_t horiz_pre, uint8_t vert_pre) {
+        char *s;
+        char NS = latitude >= 1U<<31 ? 'N' : 'S';
+        char EW = longitude >= 1U<<31 ? 'E' : 'W';
+
+        int lat = latitude >= 1U<<31 ? (int) (latitude - (1U<<31)) : (int) ((1U<<31) - latitude);
+        int lon = longitude >= 1U<<31 ? (int) (longitude - (1U<<31)) : (int) ((1U<<31) - longitude);
+        double alt = altitude >= 10000000u ? altitude - 10000000u : -(double)(10000000u - altitude);
+        double siz = (size >> 4) * exp10((double) (size & 0xF));
+        double hor = (horiz_pre >> 4) * exp10((double) (horiz_pre & 0xF));
+        double ver = (vert_pre >> 4) * exp10((double) (vert_pre & 0xF));
+
+        if (asprintf(&s, "%d %d %.3f %c %d %d %.3f %c %.2fm %.2fm %.2fm %.2fm",
+                     (lat / 60000 / 60),
+                     (lat / 60000) % 60,
+                     (lat % 60000) / 1000.,
+                     NS,
+                     (lon / 60000 / 60),
+                     (lon / 60000) % 60,
+                     (lon % 60000) / 1000.,
+                     EW,
+                     alt / 100.,
+                     siz / 100.,
+                     hor / 100.,
+                     ver / 100.) < 0)
+                return NULL;
+
+        return s;
+}
+
+int dns_resource_record_to_string(const DnsResourceRecord *rr, char **ret) {
+        _cleanup_free_ char *k = NULL, *t = NULL;
+        char *s;
+        int r;
+
+        assert(rr);
+
+        r = dns_resource_key_to_string(rr->key, &k);
+        if (r < 0)
+                return r;
+
+        switch (rr->unparseable ? _DNS_TYPE_INVALID : rr->key->type) {
+
+        case DNS_TYPE_SRV:
+                r = asprintf(&s, "%s %u %u %u %s",
+                             k,
+                             rr->srv.priority,
+                             rr->srv.weight,
+                             rr->srv.port,
+                             strna(rr->srv.name));
+                if (r < 0)
+                        return -ENOMEM;
+                break;
+
+        case DNS_TYPE_PTR:
+        case DNS_TYPE_NS:
+        case DNS_TYPE_CNAME:
+        case DNS_TYPE_DNAME:
+                s = strjoin(k, " ", rr->ptr.name, NULL);
+                if (!s)
+                        return -ENOMEM;
+
+                break;
+
+        case DNS_TYPE_HINFO:
+                s = strjoin(k, " ", rr->hinfo.cpu, " ", rr->hinfo.os, NULL);
+                if (!s)
+                        return -ENOMEM;
+                break;
+
+        case DNS_TYPE_SPF: /* exactly the same as TXT */
+        case DNS_TYPE_TXT:
+                t = strv_join_quoted(rr->txt.strings);
+                if (!t)
+                        return -ENOMEM;
+
+                s = strjoin(k, " ", t, NULL);
+                if (!s)
+                        return -ENOMEM;
+
+                break;
+
+        case DNS_TYPE_A: {
+                _cleanup_free_ char *x = NULL;
+
+                r = in_addr_to_string(AF_INET, (const union in_addr_union*) &rr->a.in_addr, &x);
+                if (r < 0)
+                        return r;
+
+                s = strjoin(k, " ", x, NULL);
+                if (!s)
+                        return -ENOMEM;
+                break;
+        }
+
+        case DNS_TYPE_AAAA:
+                r = in_addr_to_string(AF_INET6, (const union in_addr_union*) &rr->aaaa.in6_addr, &t);
+                if (r < 0)
+                        return r;
+
+                s = strjoin(k, " ", t, NULL);
+                if (!s)
+                        return -ENOMEM;
+                break;
+
+        case DNS_TYPE_SOA:
+                r = asprintf(&s, "%s %s %s %u %u %u %u %u",
+                             k,
+                             strna(rr->soa.mname),
+                             strna(rr->soa.rname),
+                             rr->soa.serial,
+                             rr->soa.refresh,
+                             rr->soa.retry,
+                             rr->soa.expire,
+                             rr->soa.minimum);
+                if (r < 0)
+                        return -ENOMEM;
+                break;
+
+        case DNS_TYPE_MX:
+                r = asprintf(&s, "%s %u %s",
+                             k,
+                             rr->mx.priority,
+                             rr->mx.exchange);
+                if (r < 0)
+                        return -ENOMEM;
+                break;
+
+        case DNS_TYPE_LOC:
+                assert(rr->loc.version == 0);
+
+                t = format_location(rr->loc.latitude,
+                                    rr->loc.longitude,
+                                    rr->loc.altitude,
+                                    rr->loc.size,
+                                    rr->loc.horiz_pre,
+                                    rr->loc.vert_pre);
+                if (!t)
+                        return -ENOMEM;
+
+                s = strjoin(k, " ", t, NULL);
+                if (!s)
+                        return -ENOMEM;
+                break;
+
+        case DNS_TYPE_SSHFP:
+                t = hexmem(rr->sshfp.key, rr->sshfp.key_size);
+                if (!t)
+                        return -ENOMEM;
+
+                r = asprintf(&s, "%s %u %u %s",
+                             k,
+                             rr->sshfp.algorithm,
+                             rr->sshfp.fptype,
+                             t);
+                if (r < 0)
+                        return -ENOMEM;
+                break;
+
+        case DNS_TYPE_DNSKEY: {
+                const char *alg;
+
+                alg = dnssec_algorithm_to_string(rr->dnskey.algorithm);
+
+                t = hexmem(rr->dnskey.key, rr->dnskey.key_size);
+                if (!t)
+                        return -ENOMEM;
+
+                r = asprintf(&s, "%s %u 3 %.*s%.*u %s",
+                             k,
+                             dnskey_to_flags(rr),
+                             alg ? -1 : 0, alg,
+                             alg ? 0 : 1, alg ? 0u : (unsigned) rr->dnskey.algorithm,
+                             t);
+                if (r < 0)
+                        return -ENOMEM;
+                break;
+        }
+
+        case DNS_TYPE_RRSIG: {
+                const char *type, *alg;
+
+                type = dns_type_to_string(rr->rrsig.type_covered);
+                alg = dnssec_algorithm_to_string(rr->rrsig.algorithm);
+
+                t = hexmem(rr->rrsig.signature, rr->rrsig.signature_size);
+                if (!t)
+                        return -ENOMEM;
+
+                /* TYPE?? follows
+                 * http://tools.ietf.org/html/rfc3597#section-5 */
+
+                r = asprintf(&s, "%s %s%.*u %.*s%.*u %u %u %u %u %u %s %s",
+                             k,
+                             type ?: "TYPE",
+                             type ? 0 : 1, type ? 0u : (unsigned) rr->rrsig.type_covered,
+                             alg ? -1 : 0, alg,
+                             alg ? 0 : 1, alg ? 0u : (unsigned) rr->rrsig.algorithm,
+                             rr->rrsig.labels,
+                             rr->rrsig.original_ttl,
+                             rr->rrsig.expiration,
+                             rr->rrsig.inception,
+                             rr->rrsig.key_tag,
+                             rr->rrsig.signer,
+                             t);
+                if (r < 0)
+                        return -ENOMEM;
+                break;
+        }
+
+        default:
+                t = hexmem(rr->generic.data, rr->generic.size);
+                if (!t)
+                        return -ENOMEM;
+
+                s = strjoin(k, " ", t, NULL);
+                if (!s)
+                        return -ENOMEM;
+                break;
+        }
+
+        *ret = s;
+        return 0;
+}
+
+const char *dns_class_to_string(uint16_t class) {
+
+        switch (class) {
+
+        case DNS_CLASS_IN:
+                return "IN";
+
+        case DNS_CLASS_ANY:
+                return "ANY";
+        }
+
+        return NULL;
+}
+
+int dns_class_from_string(const char *s, uint16_t *class) {
+        assert(s);
+        assert(class);
+
+        if (strcaseeq(s, "IN"))
+                *class = DNS_CLASS_IN;
+        else if (strcaseeq(s, "ANY"))
+                *class = DNS_TYPE_ANY;
+        else
+                return -EINVAL;
+
+        return 0;
+}
diff --git a/src/resolve/resolved-dns-rr.h b/src/resolve/resolved-dns-rr.h
new file mode 100644 (file)
index 0000000..3222f1f
--- /dev/null
@@ -0,0 +1,177 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+ ***/
+
+#include <inttypes.h>
+#include <netinet/in.h>
+
+#include "util.h"
+#include "hashmap.h"
+#include "in-addr-util.h"
+#include "dns-type.h"
+
+typedef struct DnsResourceKey DnsResourceKey;
+typedef struct DnsResourceRecord DnsResourceRecord;
+
+/* DNS record classes, see RFC 1035 */
+enum {
+        DNS_CLASS_IN   = 0x01,
+        DNS_CLASS_ANY  = 0xFF,
+        _DNS_CLASS_MAX,
+        _DNS_CLASS_INVALID = -1
+};
+
+struct DnsResourceKey {
+        unsigned n_ref;
+        uint16_t class, type;
+        char *_name; /* don't access directy, use DNS_RESOURCE_KEY_NAME()! */
+};
+
+struct DnsResourceRecord {
+        unsigned n_ref;
+        DnsResourceKey *key;
+        uint32_t ttl;
+        bool unparseable;
+        union {
+                struct {
+                        void *data;
+                        uint16_t size;
+                } generic;
+
+                struct {
+                        uint16_t priority;
+                        uint16_t weight;
+                        uint16_t port;
+                        char *name;
+                } srv;
+
+                struct {
+                        char *name;
+                } ptr, ns, cname, dname;
+
+                struct {
+                        char *cpu;
+                        char *os;
+                } hinfo;
+
+                struct {
+                        char **strings;
+                } txt, spf;
+
+                struct {
+                        struct in_addr in_addr;
+                } a;
+
+                struct {
+                        struct in6_addr in6_addr;
+                } aaaa;
+
+                struct {
+                        char *mname;
+                        char *rname;
+                        uint32_t serial;
+                        uint32_t refresh;
+                        uint32_t retry;
+                        uint32_t expire;
+                        uint32_t minimum;
+                } soa;
+
+                struct {
+                        uint16_t priority;
+                        char *exchange;
+                } mx;
+
+                struct {
+                        uint8_t version;
+                        uint8_t size;
+                        uint8_t horiz_pre;
+                        uint8_t vert_pre;
+                        uint32_t latitude;
+                        uint32_t longitude;
+                        uint32_t altitude;
+                } loc;
+
+                struct {
+                        uint8_t algorithm;
+                        uint8_t fptype;
+                        void *key;
+                        size_t key_size;
+                } sshfp;
+
+                /* http://tools.ietf.org/html/rfc4034#section-2.1 */
+                struct {
+                        bool zone_key_flag:1;
+                        bool sep_flag:1;
+                        uint8_t algorithm;
+                        void* key;
+                        size_t key_size;
+                } dnskey;
+
+                /* http://tools.ietf.org/html/rfc4034#section-3.1 */
+                struct {
+                        uint16_t type_covered;
+                        uint8_t algorithm;
+                        uint8_t labels;
+                        uint32_t original_ttl;
+                        uint32_t expiration;
+                        uint32_t inception;
+                        uint16_t key_tag;
+                        char *signer;
+                        void *signature;
+                        size_t signature_size;
+                } rrsig;
+        };
+};
+
+static inline const char* DNS_RESOURCE_KEY_NAME(const DnsResourceKey *key) {
+        if (_unlikely_(!key))
+                return NULL;
+
+        if (key->_name)
+                return key->_name;
+
+        return (char*) key + sizeof(DnsResourceKey);
+}
+
+DnsResourceKey* dns_resource_key_new(uint16_t class, uint16_t type, const char *name);
+DnsResourceKey* dns_resource_key_new_consume(uint16_t class, uint16_t type, char *name);
+DnsResourceKey* dns_resource_key_ref(DnsResourceKey *key);
+DnsResourceKey* dns_resource_key_unref(DnsResourceKey *key);
+int dns_resource_key_equal(const DnsResourceKey *a, const DnsResourceKey *b);
+int dns_resource_key_match_rr(const DnsResourceKey *key, const DnsResourceRecord *rr);
+int dns_resource_key_match_cname(const DnsResourceKey *key, const DnsResourceRecord *rr);
+unsigned long dns_resource_key_hash_func(const void *i, const uint8_t hash_key[HASH_KEY_SIZE]);
+int dns_resource_key_compare_func(const void *a, const void *b);
+int dns_resource_key_to_string(const DnsResourceKey *key, char **ret);
+DEFINE_TRIVIAL_CLEANUP_FUNC(DnsResourceKey*, dns_resource_key_unref);
+
+DnsResourceRecord* dns_resource_record_new(DnsResourceKey *key);
+DnsResourceRecord* dns_resource_record_new_full(uint16_t class, uint16_t type, const char *name);
+DnsResourceRecord* dns_resource_record_ref(DnsResourceRecord *rr);
+DnsResourceRecord* dns_resource_record_unref(DnsResourceRecord *rr);
+int dns_resource_record_new_reverse(DnsResourceRecord **ret, int family, const union in_addr_union *address, const char *name);
+int dns_resource_record_equal(const DnsResourceRecord *a, const DnsResourceRecord *b);
+int dns_resource_record_to_string(const DnsResourceRecord *rr, char **ret);
+DEFINE_TRIVIAL_CLEANUP_FUNC(DnsResourceRecord*, dns_resource_record_unref);
+
+const char *dns_class_to_string(uint16_t type);
+int dns_class_from_string(const char *name, uint16_t *class);
diff --git a/src/resolve/resolved-dns-scope.c b/src/resolve/resolved-dns-scope.c
new file mode 100644 (file)
index 0000000..039a754
--- /dev/null
@@ -0,0 +1,797 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <netinet/tcp.h>
+
+#include "missing.h"
+#include "strv.h"
+#include "socket-util.h"
+#include "af-list.h"
+#include "resolved-dns-domain.h"
+#include "resolved-dns-scope.h"
+
+#define MULTICAST_RATELIMIT_INTERVAL_USEC (1*USEC_PER_SEC)
+#define MULTICAST_RATELIMIT_BURST 1000
+
+int dns_scope_new(Manager *m, DnsScope **ret, Link *l, DnsProtocol protocol, int family) {
+        DnsScope *s;
+
+        assert(m);
+        assert(ret);
+
+        s = new0(DnsScope, 1);
+        if (!s)
+                return -ENOMEM;
+
+        s->manager = m;
+        s->link = l;
+        s->protocol = protocol;
+        s->family = family;
+
+        LIST_PREPEND(scopes, m->dns_scopes, s);
+
+        dns_scope_llmnr_membership(s, true);
+
+        log_debug("New scope on link %s, protocol %s, family %s", l ? l->name : "*", dns_protocol_to_string(protocol), family == AF_UNSPEC ? "*" : af_to_name(family));
+
+        /* Enforce ratelimiting for the multicast protocols */
+        RATELIMIT_INIT(s->ratelimit, MULTICAST_RATELIMIT_INTERVAL_USEC, MULTICAST_RATELIMIT_BURST);
+
+        *ret = s;
+        return 0;
+}
+
+DnsScope* dns_scope_free(DnsScope *s) {
+        DnsTransaction *t;
+        DnsResourceRecord *rr;
+
+        if (!s)
+                return NULL;
+
+        log_debug("Removing scope on link %s, protocol %s, family %s", s->link ? s->link->name : "*", dns_protocol_to_string(s->protocol), s->family == AF_UNSPEC ? "*" : af_to_name(s->family));
+
+        dns_scope_llmnr_membership(s, false);
+
+        while ((t = s->transactions)) {
+
+                /* Abort the transaction, but make sure it is not
+                 * freed while we still look at it */
+
+                t->block_gc++;
+                dns_transaction_complete(t, DNS_TRANSACTION_ABORTED);
+                t->block_gc--;
+
+                dns_transaction_free(t);
+        }
+
+        while ((rr = hashmap_steal_first(s->conflict_queue)))
+                dns_resource_record_unref(rr);
+
+        hashmap_free(s->conflict_queue);
+        sd_event_source_unref(s->conflict_event_source);
+
+        dns_cache_flush(&s->cache);
+        dns_zone_flush(&s->zone);
+
+        LIST_REMOVE(scopes, s->manager->dns_scopes, s);
+        strv_free(s->domains);
+        free(s);
+
+        return NULL;
+}
+
+DnsServer *dns_scope_get_dns_server(DnsScope *s) {
+        assert(s);
+
+        if (s->protocol != DNS_PROTOCOL_DNS)
+                return NULL;
+
+        if (s->link)
+                return link_get_dns_server(s->link);
+        else
+                return manager_get_dns_server(s->manager);
+}
+
+void dns_scope_next_dns_server(DnsScope *s) {
+        assert(s);
+
+        if (s->protocol != DNS_PROTOCOL_DNS)
+                return;
+
+        if (s->link)
+                link_next_dns_server(s->link);
+        else
+                manager_next_dns_server(s->manager);
+}
+
+int dns_scope_emit(DnsScope *s, DnsPacket *p) {
+        union in_addr_union addr;
+        int ifindex = 0, r;
+        int family;
+        uint16_t port;
+        uint32_t mtu;
+        int fd;
+
+        assert(s);
+        assert(p);
+        assert(p->protocol == s->protocol);
+
+        if (s->link) {
+                mtu = s->link->mtu;
+                ifindex = s->link->ifindex;
+        } else
+                mtu = manager_find_mtu(s->manager);
+
+        if (s->protocol == DNS_PROTOCOL_DNS) {
+                DnsServer *srv;
+
+                if (DNS_PACKET_QDCOUNT(p) > 1)
+                        return -ENOTSUP;
+
+                srv = dns_scope_get_dns_server(s);
+                if (!srv)
+                        return -ESRCH;
+
+                family = srv->family;
+                addr = srv->address;
+                port = 53;
+
+                if (p->size > DNS_PACKET_UNICAST_SIZE_MAX)
+                        return -EMSGSIZE;
+
+                if (p->size > mtu)
+                        return -EMSGSIZE;
+
+                if (family == AF_INET)
+                        fd = manager_dns_ipv4_fd(s->manager);
+                else if (family == AF_INET6)
+                        fd = manager_dns_ipv6_fd(s->manager);
+                else
+                        return -EAFNOSUPPORT;
+                if (fd < 0)
+                        return fd;
+
+        } else if (s->protocol == DNS_PROTOCOL_LLMNR) {
+
+                if (DNS_PACKET_QDCOUNT(p) > 1)
+                        return -ENOTSUP;
+
+                if (!ratelimit_test(&s->ratelimit))
+                        return -EBUSY;
+
+                family = s->family;
+                port = 5355;
+
+                if (family == AF_INET) {
+                        addr.in = LLMNR_MULTICAST_IPV4_ADDRESS;
+                        fd = manager_llmnr_ipv4_udp_fd(s->manager);
+                } else if (family == AF_INET6) {
+                        addr.in6 = LLMNR_MULTICAST_IPV6_ADDRESS;
+                        fd = manager_llmnr_ipv6_udp_fd(s->manager);
+                } else
+                        return -EAFNOSUPPORT;
+                if (fd < 0)
+                        return fd;
+        } else
+                return -EAFNOSUPPORT;
+
+        r = manager_send(s->manager, fd, ifindex, family, &addr, port, p);
+        if (r < 0)
+                return r;
+
+        return 1;
+}
+
+int dns_scope_tcp_socket(DnsScope *s, int family, const union in_addr_union *address, uint16_t port) {
+        _cleanup_close_ int fd = -1;
+        union sockaddr_union sa = {};
+        socklen_t salen;
+        static const int one = 1;
+        int ret, r;
+
+        assert(s);
+        assert((family == AF_UNSPEC) == !address);
+
+        if (family == AF_UNSPEC) {
+                DnsServer *srv;
+
+                srv = dns_scope_get_dns_server(s);
+                if (!srv)
+                        return -ESRCH;
+
+                sa.sa.sa_family = srv->family;
+                if (srv->family == AF_INET) {
+                        sa.in.sin_port = htobe16(port);
+                        sa.in.sin_addr = srv->address.in;
+                        salen = sizeof(sa.in);
+                } else if (srv->family == AF_INET6) {
+                        sa.in6.sin6_port = htobe16(port);
+                        sa.in6.sin6_addr = srv->address.in6;
+                        sa.in6.sin6_scope_id = s->link ? s->link->ifindex : 0;
+                        salen = sizeof(sa.in6);
+                } else
+                        return -EAFNOSUPPORT;
+        } else {
+                sa.sa.sa_family = family;
+
+                if (family == AF_INET) {
+                        sa.in.sin_port = htobe16(port);
+                        sa.in.sin_addr = address->in;
+                        salen = sizeof(sa.in);
+                } else if (family == AF_INET6) {
+                        sa.in6.sin6_port = htobe16(port);
+                        sa.in6.sin6_addr = address->in6;
+                        sa.in6.sin6_scope_id = s->link ? s->link->ifindex : 0;
+                        salen = sizeof(sa.in6);
+                } else
+                        return -EAFNOSUPPORT;
+        }
+
+        fd = socket(sa.sa.sa_family, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
+        if (fd < 0)
+                return -errno;
+
+        r = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one));
+        if (r < 0)
+                return -errno;
+
+        if (s->link) {
+                uint32_t ifindex = htobe32(s->link->ifindex);
+
+                if (sa.sa.sa_family == AF_INET) {
+                        r = setsockopt(fd, IPPROTO_IP, IP_UNICAST_IF, &ifindex, sizeof(ifindex));
+                        if (r < 0)
+                                return -errno;
+                } else if (sa.sa.sa_family == AF_INET6) {
+                        r = setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_IF, &ifindex, sizeof(ifindex));
+                        if (r < 0)
+                                return -errno;
+                }
+        }
+
+        if (s->protocol == DNS_PROTOCOL_LLMNR) {
+                /* RFC 4795, section 2.5 requires the TTL to be set to 1 */
+
+                if (sa.sa.sa_family == AF_INET) {
+                        r = setsockopt(fd, IPPROTO_IP, IP_TTL, &one, sizeof(one));
+                        if (r < 0)
+                                return -errno;
+                } else if (sa.sa.sa_family == AF_INET6) {
+                        r = setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &one, sizeof(one));
+                        if (r < 0)
+                                return -errno;
+                }
+        }
+
+        r = connect(fd, &sa.sa, salen);
+        if (r < 0 && errno != EINPROGRESS)
+                return -errno;
+
+        ret = fd;
+        fd = -1;
+
+        return ret;
+}
+
+DnsScopeMatch dns_scope_good_domain(DnsScope *s, int ifindex, uint64_t flags, const char *domain) {
+        char **i;
+
+        assert(s);
+        assert(domain);
+
+        if (ifindex != 0 && (!s->link || s->link->ifindex != ifindex))
+                return DNS_SCOPE_NO;
+
+        if ((SD_RESOLVED_FLAGS_MAKE(s->protocol, s->family) & flags) == 0)
+                return DNS_SCOPE_NO;
+
+        STRV_FOREACH(i, s->domains)
+                if (dns_name_endswith(domain, *i) > 0)
+                        return DNS_SCOPE_YES;
+
+        if (dns_name_root(domain) != 0)
+                return DNS_SCOPE_NO;
+
+        if (is_localhost(domain))
+                return DNS_SCOPE_NO;
+
+        if (s->protocol == DNS_PROTOCOL_DNS) {
+                if (dns_name_endswith(domain, "254.169.in-addr.arpa") == 0 &&
+                    dns_name_endswith(domain, "0.8.e.f.ip6.arpa") == 0 &&
+                    dns_name_single_label(domain) == 0)
+                        return DNS_SCOPE_MAYBE;
+
+                return DNS_SCOPE_NO;
+        }
+
+        if (s->protocol == DNS_PROTOCOL_MDNS) {
+                if (dns_name_endswith(domain, "254.169.in-addr.arpa") > 0 ||
+                    dns_name_endswith(domain, "0.8.e.f.ip6.arpa") > 0 ||
+                    (dns_name_endswith(domain, "local") > 0 && dns_name_equal(domain, "local") == 0))
+                        return DNS_SCOPE_MAYBE;
+
+                return DNS_SCOPE_NO;
+        }
+
+        if (s->protocol == DNS_PROTOCOL_LLMNR) {
+                if (dns_name_endswith(domain, "in-addr.arpa") > 0 ||
+                    dns_name_endswith(domain, "ip6.arpa") > 0 ||
+                    dns_name_single_label(domain) > 0)
+                        return DNS_SCOPE_MAYBE;
+
+                return DNS_SCOPE_NO;
+        }
+
+        assert_not_reached("Unknown scope protocol");
+}
+
+int dns_scope_good_key(DnsScope *s, DnsResourceKey *key) {
+        assert(s);
+        assert(key);
+
+        if (s->protocol == DNS_PROTOCOL_DNS)
+                return true;
+
+        /* On mDNS and LLMNR, send A and AAAA queries only on the
+         * respective scopes */
+
+        if (s->family == AF_INET && key->class == DNS_CLASS_IN && key->type == DNS_TYPE_AAAA)
+                return false;
+
+        if (s->family == AF_INET6 && key->class == DNS_CLASS_IN && key->type == DNS_TYPE_A)
+                return false;
+
+        return true;
+}
+
+int dns_scope_llmnr_membership(DnsScope *s, bool b) {
+        int fd;
+
+        assert(s);
+
+        if (s->protocol != DNS_PROTOCOL_LLMNR)
+                return 0;
+
+        assert(s->link);
+
+        if (s->family == AF_INET) {
+                struct ip_mreqn mreqn = {
+                        .imr_multiaddr = LLMNR_MULTICAST_IPV4_ADDRESS,
+                        .imr_ifindex = s->link->ifindex,
+                };
+
+                fd = manager_llmnr_ipv4_udp_fd(s->manager);
+                if (fd < 0)
+                        return fd;
+
+                /* Always first try to drop membership before we add
+                 * one. This is necessary on some devices, such as
+                 * veth. */
+                if (b)
+                        setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreqn, sizeof(mreqn));
+
+                if (setsockopt(fd, IPPROTO_IP, b ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP, &mreqn, sizeof(mreqn)) < 0)
+                        return -errno;
+
+        } else if (s->family == AF_INET6) {
+                struct ipv6_mreq mreq = {
+                        .ipv6mr_multiaddr = LLMNR_MULTICAST_IPV6_ADDRESS,
+                        .ipv6mr_interface = s->link->ifindex,
+                };
+
+                fd = manager_llmnr_ipv6_udp_fd(s->manager);
+                if (fd < 0)
+                        return fd;
+
+                if (b)
+                        setsockopt(fd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, &mreq, sizeof(mreq));
+
+                if (setsockopt(fd, IPPROTO_IPV6, b ? IPV6_ADD_MEMBERSHIP : IPV6_DROP_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
+                        return -errno;
+        } else
+                return -EAFNOSUPPORT;
+
+        return 0;
+}
+
+int dns_scope_good_dns_server(DnsScope *s, int family, const union in_addr_union *address) {
+        assert(s);
+        assert(address);
+
+        if (s->protocol != DNS_PROTOCOL_DNS)
+                return 1;
+
+        if (s->link)
+                return !!link_find_dns_server(s->link,  family, address);
+        else
+                return !!manager_find_dns_server(s->manager, family, address);
+}
+
+static int dns_scope_make_reply_packet(
+                DnsScope *s,
+                uint16_t id,
+                int rcode,
+                DnsQuestion *q,
+                DnsAnswer *answer,
+                DnsAnswer *soa,
+                bool tentative,
+                DnsPacket **ret) {
+
+        _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
+        unsigned i;
+        int r;
+
+        assert(s);
+        assert(ret);
+
+        if ((!q || q->n_keys <= 0)
+            && (!answer || answer->n_rrs <= 0)
+            && (!soa || soa->n_rrs <= 0))
+                return -EINVAL;
+
+        r = dns_packet_new(&p, s->protocol, 0);
+        if (r < 0)
+                return r;
+
+        DNS_PACKET_HEADER(p)->id = id;
+        DNS_PACKET_HEADER(p)->flags = htobe16(DNS_PACKET_MAKE_FLAGS(
+                                                              1 /* qr */,
+                                                              0 /* opcode */,
+                                                              0 /* c */,
+                                                              0 /* tc */,
+                                                              tentative,
+                                                              0 /* (ra) */,
+                                                              0 /* (ad) */,
+                                                              0 /* (cd) */,
+                                                              rcode));
+
+        if (q) {
+                for (i = 0; i < q->n_keys; i++) {
+                        r = dns_packet_append_key(p, q->keys[i], NULL);
+                        if (r < 0)
+                                return r;
+                }
+
+                DNS_PACKET_HEADER(p)->qdcount = htobe16(q->n_keys);
+        }
+
+        if (answer) {
+                for (i = 0; i < answer->n_rrs; i++) {
+                        r = dns_packet_append_rr(p, answer->rrs[i], NULL);
+                        if (r < 0)
+                                return r;
+                }
+
+                DNS_PACKET_HEADER(p)->ancount = htobe16(answer->n_rrs);
+        }
+
+        if (soa) {
+                for (i = 0; i < soa->n_rrs; i++) {
+                        r = dns_packet_append_rr(p, soa->rrs[i], NULL);
+                        if (r < 0)
+                                return r;
+                }
+
+                DNS_PACKET_HEADER(p)->arcount = htobe16(soa->n_rrs);
+        }
+
+        *ret = p;
+        p = NULL;
+
+        return 0;
+}
+
+static void dns_scope_verify_conflicts(DnsScope *s, DnsPacket *p) {
+        unsigned n;
+
+        assert(s);
+        assert(p);
+
+        if (p->question)
+                for (n = 0; n < p->question->n_keys; n++)
+                        dns_zone_verify_conflicts(&s->zone, p->question->keys[n]);
+        if (p->answer)
+                for (n = 0; n < p->answer->n_rrs; n++)
+                        dns_zone_verify_conflicts(&s->zone, p->answer->rrs[n]->key);
+}
+
+void dns_scope_process_query(DnsScope *s, DnsStream *stream, DnsPacket *p) {
+        _cleanup_(dns_packet_unrefp) DnsPacket *reply = NULL;
+        _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL, *soa = NULL;
+        bool tentative = false;
+        int r, fd;
+
+        assert(s);
+        assert(p);
+
+        if (p->protocol != DNS_PROTOCOL_LLMNR)
+                return;
+
+        if (p->ipproto == IPPROTO_UDP) {
+                /* Don't accept UDP queries directed to anything but
+                 * the LLMNR multicast addresses. See RFC 4795,
+                 * section 2.5.*/
+
+                if (p->family == AF_INET && !in_addr_equal(AF_INET, &p->destination, (union in_addr_union*) &LLMNR_MULTICAST_IPV4_ADDRESS))
+                        return;
+
+                if (p->family == AF_INET6 && !in_addr_equal(AF_INET6, &p->destination, (union in_addr_union*) &LLMNR_MULTICAST_IPV6_ADDRESS))
+                        return;
+        }
+
+        r = dns_packet_extract(p);
+        if (r < 0) {
+                log_debug("Failed to extract resources from incoming packet: %s", strerror(-r));
+                return;
+        }
+
+        if (DNS_PACKET_C(p)) {
+                /* Somebody notified us about a possible conflict */
+                dns_scope_verify_conflicts(s, p);
+                return;
+        }
+
+        r = dns_zone_lookup(&s->zone, p->question, &answer, &soa, &tentative);
+        if (r < 0) {
+                log_debug("Failed to lookup key: %s", strerror(-r));
+                return;
+        }
+        if (r == 0)
+                return;
+
+        if (answer)
+                dns_answer_order_by_scope(answer, in_addr_is_link_local(p->family, &p->sender) > 0);
+
+        r = dns_scope_make_reply_packet(s, DNS_PACKET_ID(p), DNS_RCODE_SUCCESS, p->question, answer, soa, tentative, &reply);
+        if (r < 0) {
+                log_debug("Failed to build reply packet: %s", strerror(-r));
+                return;
+        }
+
+        if (stream)
+                r = dns_stream_write_packet(stream, reply);
+        else {
+                if (!ratelimit_test(&s->ratelimit))
+                        return;
+
+                if (p->family == AF_INET)
+                        fd = manager_llmnr_ipv4_udp_fd(s->manager);
+                else if (p->family == AF_INET6)
+                        fd = manager_llmnr_ipv6_udp_fd(s->manager);
+                else {
+                        log_debug("Unknown protocol");
+                        return;
+                }
+                if (fd < 0) {
+                        log_debug("Failed to get reply socket: %s", strerror(-fd));
+                        return;
+                }
+
+                /* Note that we always immediately reply to all LLMNR
+                 * requests, and do not wait any time, since we
+                 * verified uniqueness for all records. Also see RFC
+                 * 4795, Section 2.7 */
+
+                r = manager_send(s->manager, fd, p->ifindex, p->family, &p->sender, p->sender_port, reply);
+        }
+
+        if (r < 0) {
+                log_debug("Failed to send reply packet: %s", strerror(-r));
+                return;
+        }
+}
+
+DnsTransaction *dns_scope_find_transaction(DnsScope *scope, DnsQuestion *question, bool cache_ok) {
+        DnsTransaction *t;
+
+        assert(scope);
+        assert(question);
+
+        /* Try to find an ongoing transaction that is a equal or a
+         * superset of the specified question */
+
+        LIST_FOREACH(transactions_by_scope, t, scope->transactions) {
+
+                /* Refuse reusing transactions that completed based on
+                 * cached data instead of a real packet, if that's
+                 * requested. */
+                if (!cache_ok &&
+                    IN_SET(t->state, DNS_TRANSACTION_SUCCESS, DNS_TRANSACTION_FAILURE) &&
+                    !t->received)
+                        continue;
+
+                if (dns_question_is_superset(t->question, question) > 0)
+                        return t;
+        }
+
+        return NULL;
+}
+
+static int dns_scope_make_conflict_packet(
+                DnsScope *s,
+                DnsResourceRecord *rr,
+                DnsPacket **ret) {
+
+        _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
+        int r;
+
+        assert(s);
+        assert(rr);
+        assert(ret);
+
+        r = dns_packet_new(&p, s->protocol, 0);
+        if (r < 0)
+                return r;
+
+        DNS_PACKET_HEADER(p)->flags = htobe16(DNS_PACKET_MAKE_FLAGS(
+                                                              0 /* qr */,
+                                                              0 /* opcode */,
+                                                              1 /* conflict */,
+                                                              0 /* tc */,
+                                                              0 /* t */,
+                                                              0 /* (ra) */,
+                                                              0 /* (ad) */,
+                                                              0 /* (cd) */,
+                                                              0));
+        random_bytes(&DNS_PACKET_HEADER(p)->id, sizeof(uint16_t));
+        DNS_PACKET_HEADER(p)->qdcount = htobe16(1);
+        DNS_PACKET_HEADER(p)->arcount = htobe16(1);
+
+        r = dns_packet_append_key(p, rr->key, NULL);
+        if (r < 0)
+                return r;
+
+        r = dns_packet_append_rr(p, rr, NULL);
+        if (r < 0)
+                return r;
+
+        *ret = p;
+        p = NULL;
+
+        return 0;
+}
+
+static int on_conflict_dispatch(sd_event_source *es, usec_t usec, void *userdata) {
+        DnsScope *scope = userdata;
+        int r;
+
+        assert(es);
+        assert(scope);
+
+        scope->conflict_event_source = sd_event_source_unref(scope->conflict_event_source);
+
+        for (;;) {
+                _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
+                _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
+
+                rr = hashmap_steal_first(scope->conflict_queue);
+                if (!rr)
+                        break;
+
+                r = dns_scope_make_conflict_packet(scope, rr, &p);
+                if (r < 0) {
+                        log_error("Failed to make conflict packet: %s", strerror(-r));
+                        return 0;
+                }
+
+                r = dns_scope_emit(scope, p);
+                if (r < 0)
+                        log_debug("Failed to send conflict packet: %s", strerror(-r));
+        }
+
+        return 0;
+}
+
+int dns_scope_notify_conflict(DnsScope *scope, DnsResourceRecord *rr) {
+        usec_t jitter;
+        int r;
+
+        assert(scope);
+        assert(rr);
+
+        /* We don't send these queries immediately. Instead, we queue
+         * them, and send them after some jitter delay. */
+        r = hashmap_ensure_allocated(&scope->conflict_queue, dns_resource_key_hash_func, dns_resource_key_compare_func);
+        if (r < 0) {
+                log_oom();
+                return r;
+        }
+
+        /* We only place one RR per key in the conflict
+         * messages, not all of them. That should be enough to
+         * indicate where there might be a conflict */
+        r = hashmap_put(scope->conflict_queue, rr->key, rr);
+        if (r == -EEXIST || r == 0)
+                return 0;
+        if (r < 0) {
+                log_debug("Failed to queue conflicting RR: %s", strerror(-r));
+                return r;
+        }
+
+        dns_resource_record_ref(rr);
+
+        if (scope->conflict_event_source)
+                return 0;
+
+        random_bytes(&jitter, sizeof(jitter));
+        jitter %= LLMNR_JITTER_INTERVAL_USEC;
+
+        r = sd_event_add_time(scope->manager->event,
+                              &scope->conflict_event_source,
+                              clock_boottime_or_monotonic(),
+                              now(clock_boottime_or_monotonic()) + jitter,
+                              LLMNR_JITTER_INTERVAL_USEC,
+                              on_conflict_dispatch, scope);
+        if (r < 0) {
+                log_debug("Failed to add conflict dispatch event: %s", strerror(-r));
+                return r;
+        }
+
+        return 0;
+}
+
+void dns_scope_check_conflicts(DnsScope *scope, DnsPacket *p) {
+        unsigned i;
+        int r;
+
+        assert(scope);
+        assert(p);
+
+        if (p->protocol != DNS_PROTOCOL_LLMNR)
+                return;
+
+        if (DNS_PACKET_RRCOUNT(p) <= 0)
+                return;
+
+        if (DNS_PACKET_C(p) != 0)
+                return;
+
+        if (DNS_PACKET_T(p) != 0)
+                return;
+
+        if (manager_our_packet(scope->manager, p))
+                return;
+
+        r = dns_packet_extract(p);
+        if (r < 0) {
+                log_debug("Failed to extract packet: %s", strerror(-r));
+                return;
+        }
+
+        log_debug("Checking for conflicts...");
+
+        for (i = 0; i < p->answer->n_rrs; i++) {
+
+                /* Check for conflicts against the local zone. If we
+                 * found one, we won't check any further */
+                r = dns_zone_check_conflicts(&scope->zone, p->answer->rrs[i]);
+                if (r != 0)
+                        continue;
+
+                /* Check for conflicts against the local cache. If so,
+                 * send out an advisory query, to inform everybody */
+                r = dns_cache_check_conflicts(&scope->cache, p->answer->rrs[i], p->family, &p->sender);
+                if (r <= 0)
+                        continue;
+
+                dns_scope_notify_conflict(scope, p->answer->rrs[i]);
+        }
+}
diff --git a/src/resolve/resolved-dns-scope.h b/src/resolve/resolved-dns-scope.h
new file mode 100644 (file)
index 0000000..a022309
--- /dev/null
@@ -0,0 +1,88 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "list.h"
+
+typedef struct DnsScope DnsScope;
+
+#include "resolved-dns-server.h"
+#include "resolved-dns-packet.h"
+#include "resolved-dns-query.h"
+#include "resolved-dns-cache.h"
+#include "resolved-dns-zone.h"
+#include "resolved-dns-stream.h"
+#include "resolved-manager.h"
+#include "resolved-link.h"
+
+typedef enum DnsScopeMatch {
+        DNS_SCOPE_NO,
+        DNS_SCOPE_MAYBE,
+        DNS_SCOPE_YES,
+        _DNS_SCOPE_MATCH_MAX,
+        _DNS_SCOPE_INVALID = -1
+} DnsScopeMatch;
+
+struct DnsScope {
+        Manager *manager;
+
+        DnsProtocol protocol;
+        int family;
+
+        Link *link;
+
+        char **domains;
+
+        DnsCache cache;
+        DnsZone zone;
+
+        Hashmap *conflict_queue;
+        sd_event_source *conflict_event_source;
+
+        RateLimit ratelimit;
+
+        LIST_HEAD(DnsTransaction, transactions);
+
+        LIST_FIELDS(DnsScope, scopes);
+};
+
+int dns_scope_new(Manager *m, DnsScope **ret, Link *l, DnsProtocol p, int family);
+DnsScope* dns_scope_free(DnsScope *s);
+
+int dns_scope_emit(DnsScope *s, DnsPacket *p);
+int dns_scope_tcp_socket(DnsScope *s, int family, const union in_addr_union *address, uint16_t port);
+
+DnsScopeMatch dns_scope_good_domain(DnsScope *s, int ifindex, uint64_t flags, const char *domain);
+int dns_scope_good_key(DnsScope *s, DnsResourceKey *key);
+int dns_scope_good_dns_server(DnsScope *s, int family, const union in_addr_union *address);
+
+DnsServer *dns_scope_get_dns_server(DnsScope *s);
+void dns_scope_next_dns_server(DnsScope *s);
+
+int dns_scope_llmnr_membership(DnsScope *s, bool b);
+
+void dns_scope_process_query(DnsScope *s, DnsStream *stream, DnsPacket *p);
+
+DnsTransaction *dns_scope_find_transaction(DnsScope *scope, DnsQuestion *question, bool cache_ok);
+
+int dns_scope_notify_conflict(DnsScope *scope, DnsResourceRecord *rr);
+void dns_scope_check_conflicts(DnsScope *scope, DnsPacket *p);
diff --git a/src/resolve/resolved-dns-server.c b/src/resolve/resolved-dns-server.c
new file mode 100644 (file)
index 0000000..c99768b
--- /dev/null
@@ -0,0 +1,122 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "siphash24.h"
+
+#include "resolved-dns-server.h"
+
+int dns_server_new(
+                Manager *m,
+                DnsServer **ret,
+                DnsServerType type,
+                Link *l,
+                int family,
+                const union in_addr_union *in_addr) {
+
+        DnsServer *s, *tail;
+
+        assert(m);
+        assert((type == DNS_SERVER_LINK) == !!l);
+        assert(in_addr);
+
+        s = new0(DnsServer, 1);
+        if (!s)
+                return -ENOMEM;
+
+        s->type = type;
+        s->family = family;
+        s->address = *in_addr;
+
+        if (type == DNS_SERVER_LINK) {
+                LIST_FIND_TAIL(servers, l->dns_servers, tail);
+                LIST_INSERT_AFTER(servers, l->dns_servers, tail, s);
+                s->link = l;
+        } else if (type == DNS_SERVER_SYSTEM) {
+                LIST_FIND_TAIL(servers, m->dns_servers, tail);
+                LIST_INSERT_AFTER(servers, m->dns_servers, tail, s);
+        } else if (type == DNS_SERVER_FALLBACK) {
+                LIST_FIND_TAIL(servers, m->fallback_dns_servers, tail);
+                LIST_INSERT_AFTER(servers, m->fallback_dns_servers, tail, s);
+        } else
+                assert_not_reached("Unknown server type");
+
+        s->manager = m;
+
+        /* A new DNS server that isn't fallback is added and the one
+         * we used so far was a fallback one? Then let's try to pick
+         * the new one */
+        if (type != DNS_SERVER_FALLBACK &&
+            m->current_dns_server &&
+            m->current_dns_server->type == DNS_SERVER_FALLBACK)
+                manager_set_dns_server(m, NULL);
+
+        if (ret)
+                *ret = s;
+
+        return 0;
+}
+
+DnsServer* dns_server_free(DnsServer *s)  {
+        if (!s)
+                return NULL;
+
+        if (s->manager) {
+                if (s->type == DNS_SERVER_LINK)
+                        LIST_REMOVE(servers, s->link->dns_servers, s);
+                else if (s->type == DNS_SERVER_SYSTEM)
+                        LIST_REMOVE(servers, s->manager->dns_servers, s);
+                else if (s->type == DNS_SERVER_FALLBACK)
+                        LIST_REMOVE(servers, s->manager->fallback_dns_servers, s);
+                else
+                        assert_not_reached("Unknown server type");
+
+                if (s->manager->current_dns_server == s)
+                        manager_set_dns_server(s->manager, NULL);
+        }
+
+        if (s->link && s->link->current_dns_server == s)
+                link_set_dns_server(s->link, NULL);
+
+        free(s);
+
+        return NULL;
+}
+
+unsigned long dns_server_hash_func(const void *p, const uint8_t hash_key[HASH_KEY_SIZE]) {
+        const DnsServer *s = p;
+        uint64_t u;
+
+        siphash24((uint8_t*) &u, &s->address, FAMILY_ADDRESS_SIZE(s->family), hash_key);
+        u = u * hash_key[0] + u + s->family;
+
+        return u;
+}
+
+int dns_server_compare_func(const void *a, const void *b) {
+        const DnsServer *x = a, *y = b;
+
+        if (x->family < y->family)
+                return -1;
+        if (x->family > y->family)
+                return 1;
+
+        return memcmp(&x->address, &y->address, FAMILY_ADDRESS_SIZE(x->family));
+}
diff --git a/src/resolve/resolved-dns-server.h b/src/resolve/resolved-dns-server.h
new file mode 100644 (file)
index 0000000..f2361a8
--- /dev/null
@@ -0,0 +1,64 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "in-addr-util.h"
+
+typedef struct DnsServer DnsServer;
+typedef enum DnsServerSource DnsServerSource;
+
+typedef enum DnsServerType {
+        DNS_SERVER_SYSTEM,
+        DNS_SERVER_FALLBACK,
+        DNS_SERVER_LINK,
+} DnsServerType;
+
+#include "resolved-manager.h"
+#include "resolved-link.h"
+
+struct DnsServer {
+        Manager *manager;
+
+        DnsServerType type;
+
+        Link *link;
+
+        int family;
+        union in_addr_union address;
+
+        bool marked:1;
+
+        LIST_FIELDS(DnsServer, servers);
+};
+
+int dns_server_new(
+                Manager *m,
+                DnsServer **s,
+                DnsServerType type,
+                Link *l,
+                int family,
+                const union in_addr_union *address);
+
+DnsServer* dns_server_free(DnsServer *s);
+
+unsigned long dns_server_hash_func(const void *p, const uint8_t hash_key[HASH_KEY_SIZE]);
+int dns_server_compare_func(const void *a, const void *b);
diff --git a/src/resolve/resolved-dns-stream.c b/src/resolve/resolved-dns-stream.c
new file mode 100644 (file)
index 0000000..8b3a3ce
--- /dev/null
@@ -0,0 +1,402 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <netinet/tcp.h>
+
+#include "missing.h"
+#include "resolved-dns-stream.h"
+
+#define DNS_STREAM_TIMEOUT_USEC (10 * USEC_PER_SEC)
+#define DNS_STREAMS_MAX 128
+
+static void dns_stream_stop(DnsStream *s) {
+        assert(s);
+
+        s->io_event_source = sd_event_source_unref(s->io_event_source);
+        s->timeout_event_source = sd_event_source_unref(s->timeout_event_source);
+        s->fd = safe_close(s->fd);
+}
+
+static int dns_stream_update_io(DnsStream *s) {
+        int f = 0;
+
+        assert(s);
+
+        if (s->write_packet && s->n_written < sizeof(s->write_size) + s->write_packet->size)
+                f |= EPOLLOUT;
+        if (!s->read_packet || s->n_read < sizeof(s->read_size) + s->read_packet->size)
+                f |= EPOLLIN;
+
+        return sd_event_source_set_io_events(s->io_event_source, f);
+}
+
+static int dns_stream_complete(DnsStream *s, int error) {
+        assert(s);
+
+        dns_stream_stop(s);
+
+        if (s->complete)
+                s->complete(s, error);
+        else
+                dns_stream_free(s);
+
+        return 0;
+}
+
+static int dns_stream_identify(DnsStream *s) {
+        union {
+                struct cmsghdr header; /* For alignment */
+                uint8_t buffer[CMSG_SPACE(CONST_MAX(sizeof(struct in_pktinfo), sizeof(struct in6_pktinfo)))
+                               + EXTRA_CMSG_SPACE /* kernel appears to require extra space */];
+        } control;
+        struct msghdr mh = {};
+        struct cmsghdr *cmsg;
+        socklen_t sl;
+        int r;
+
+        assert(s);
+
+        if (s->identified)
+                return 0;
+
+        /* Query the local side */
+        s->local_salen = sizeof(s->local);
+        r = getsockname(s->fd, &s->local.sa, &s->local_salen);
+        if (r < 0)
+                return -errno;
+        if (s->local.sa.sa_family == AF_INET6 && s->ifindex <= 0)
+                s->ifindex = s->local.in6.sin6_scope_id;
+
+        /* Query the remote side */
+        s->peer_salen = sizeof(s->peer);
+        r = getpeername(s->fd, &s->peer.sa, &s->peer_salen);
+        if (r < 0)
+                return -errno;
+        if (s->peer.sa.sa_family == AF_INET6 && s->ifindex <= 0)
+                s->ifindex = s->peer.in6.sin6_scope_id;
+
+        /* Check consistency */
+        assert(s->peer.sa.sa_family == s->local.sa.sa_family);
+        assert(IN_SET(s->peer.sa.sa_family, AF_INET, AF_INET6));
+
+        /* Query connection meta information */
+        sl = sizeof(control);
+        if (s->peer.sa.sa_family == AF_INET) {
+                r = getsockopt(s->fd, IPPROTO_IP, IP_PKTOPTIONS, &control, &sl);
+                if (r < 0)
+                        return -errno;
+        } else if (s->peer.sa.sa_family == AF_INET6) {
+
+                r = getsockopt(s->fd, IPPROTO_IPV6, IPV6_2292PKTOPTIONS, &control, &sl);
+                if (r < 0)
+                        return -errno;
+        } else
+                return -EAFNOSUPPORT;
+
+        mh.msg_control = &control;
+        mh.msg_controllen = sl;
+        for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg)) {
+
+                if (cmsg->cmsg_level == IPPROTO_IPV6) {
+                        assert(s->peer.sa.sa_family == AF_INET6);
+
+                        switch (cmsg->cmsg_type) {
+
+                        case IPV6_PKTINFO: {
+                                struct in6_pktinfo *i = (struct in6_pktinfo*) CMSG_DATA(cmsg);
+
+                                if (s->ifindex <= 0)
+                                        s->ifindex = i->ipi6_ifindex;
+                                break;
+                        }
+
+                        case IPV6_HOPLIMIT:
+                                s->ttl = *(int *) CMSG_DATA(cmsg);
+                                break;
+                        }
+
+                } else if (cmsg->cmsg_level == IPPROTO_IP) {
+                        assert(s->peer.sa.sa_family == AF_INET);
+
+                        switch (cmsg->cmsg_type) {
+
+                        case IP_PKTINFO: {
+                                struct in_pktinfo *i = (struct in_pktinfo*) CMSG_DATA(cmsg);
+
+                                if (s->ifindex <= 0)
+                                        s->ifindex = i->ipi_ifindex;
+                                break;
+                        }
+
+                        case IP_TTL:
+                                s->ttl = *(int *) CMSG_DATA(cmsg);
+                                break;
+                        }
+                }
+        }
+
+        /* The Linux kernel sets the interface index to the loopback
+         * device if the connection came from the local host since it
+         * avoids the routing table in such a case. Let's unset the
+         * interface index in such a case. */
+        if (s->ifindex > 0 && manager_ifindex_is_loopback(s->manager, s->ifindex) != 0)
+                s->ifindex = 0;
+
+        /* If we don't know the interface index still, we look for the
+         * first local interface with a matching address. Yuck! */
+        if (s->ifindex <= 0)
+                s->ifindex = manager_find_ifindex(s->manager, s->local.sa.sa_family, s->local.sa.sa_family == AF_INET ? (union in_addr_union*) &s->local.in.sin_addr : (union in_addr_union*)  &s->local.in6.sin6_addr);
+
+        if (s->protocol == DNS_PROTOCOL_LLMNR && s->ifindex > 0) {
+                uint32_t ifindex = htobe32(s->ifindex);
+
+                /* Make sure all packets for this connection are sent on the same interface */
+                if (s->local.sa.sa_family == AF_INET) {
+                        r = setsockopt(s->fd, IPPROTO_IP, IP_UNICAST_IF, &ifindex, sizeof(ifindex));
+                        if (r < 0)
+                                log_debug("Failed to invoke IP_UNICAST_IF: %m");
+                } else if (s->local.sa.sa_family == AF_INET6) {
+                        r = setsockopt(s->fd, IPPROTO_IPV6, IPV6_UNICAST_IF, &ifindex, sizeof(ifindex));
+                        if (r < 0)
+                                log_debug("Failed to invoke IPV6_UNICAST_IF: %m");
+                }
+        }
+
+        s->identified = true;
+
+        return 0;
+}
+
+static int on_stream_timeout(sd_event_source *es, usec_t usec, void *userdata) {
+        DnsStream *s = userdata;
+
+        assert(s);
+
+        return dns_stream_complete(s, ETIMEDOUT);
+}
+
+static int on_stream_io(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
+        DnsStream *s = userdata;
+        int r;
+
+        assert(s);
+
+        r = dns_stream_identify(s);
+        if (r < 0)
+                return dns_stream_complete(s, -r);
+
+        if ((revents & EPOLLOUT) &&
+            s->write_packet &&
+            s->n_written < sizeof(s->write_size) + s->write_packet->size) {
+
+                struct iovec iov[2];
+                ssize_t ss;
+
+                iov[0].iov_base = &s->write_size;
+                iov[0].iov_len = sizeof(s->write_size);
+                iov[1].iov_base = DNS_PACKET_DATA(s->write_packet);
+                iov[1].iov_len = s->write_packet->size;
+
+                IOVEC_INCREMENT(iov, 2, s->n_written);
+
+                ss = writev(fd, iov, 2);
+                if (ss < 0) {
+                        if (errno != EINTR && errno != EAGAIN)
+                                return dns_stream_complete(s, errno);
+                } else
+                        s->n_written += ss;
+
+                /* Are we done? If so, disable the event source for EPOLLOUT */
+                if (s->n_written >= sizeof(s->write_size) + s->write_packet->size) {
+                        r = dns_stream_update_io(s);
+                        if (r < 0)
+                                return dns_stream_complete(s, -r);
+                }
+        }
+
+        if ((revents & (EPOLLIN|EPOLLHUP|EPOLLRDHUP)) &&
+            (!s->read_packet ||
+             s->n_read < sizeof(s->read_size) + s->read_packet->size)) {
+
+                if (s->n_read < sizeof(s->read_size)) {
+                        ssize_t ss;
+
+                        ss = read(fd, (uint8_t*) &s->read_size + s->n_read, sizeof(s->read_size) - s->n_read);
+                        if (ss < 0) {
+                                if (errno != EINTR && errno != EAGAIN)
+                                        return dns_stream_complete(s, errno);
+                        } else if (ss == 0)
+                                return dns_stream_complete(s, ECONNRESET);
+                        else
+                                s->n_read += ss;
+                }
+
+                if (s->n_read >= sizeof(s->read_size)) {
+
+                        if (be16toh(s->read_size) < DNS_PACKET_HEADER_SIZE)
+                                return dns_stream_complete(s, EBADMSG);
+
+                        if (s->n_read < sizeof(s->read_size) + be16toh(s->read_size)) {
+                                ssize_t ss;
+
+                                if (!s->read_packet) {
+                                        r = dns_packet_new(&s->read_packet, s->protocol, be16toh(s->read_size));
+                                        if (r < 0)
+                                                return dns_stream_complete(s, -r);
+
+                                        s->read_packet->size = be16toh(s->read_size);
+                                        s->read_packet->ipproto = IPPROTO_TCP;
+                                        s->read_packet->family = s->peer.sa.sa_family;
+                                        s->read_packet->ttl = s->ttl;
+                                        s->read_packet->ifindex = s->ifindex;
+
+                                        if (s->read_packet->family == AF_INET) {
+                                                s->read_packet->sender.in = s->peer.in.sin_addr;
+                                                s->read_packet->sender_port = be16toh(s->peer.in.sin_port);
+                                                s->read_packet->destination.in = s->local.in.sin_addr;
+                                                s->read_packet->destination_port = be16toh(s->local.in.sin_port);
+                                        } else {
+                                                assert(s->read_packet->family == AF_INET6);
+                                                s->read_packet->sender.in6 = s->peer.in6.sin6_addr;
+                                                s->read_packet->sender_port = be16toh(s->peer.in6.sin6_port);
+                                                s->read_packet->destination.in6 = s->local.in6.sin6_addr;
+                                                s->read_packet->destination_port = be16toh(s->local.in6.sin6_port);
+
+                                                if (s->read_packet->ifindex == 0)
+                                                        s->read_packet->ifindex = s->peer.in6.sin6_scope_id;
+                                                if (s->read_packet->ifindex == 0)
+                                                        s->read_packet->ifindex = s->local.in6.sin6_scope_id;
+                                        }
+                                }
+
+                                ss = read(fd,
+                                          (uint8_t*) DNS_PACKET_DATA(s->read_packet) + s->n_read - sizeof(s->read_size),
+                                          sizeof(s->read_size) + be16toh(s->read_size) - s->n_read);
+                                if (ss < 0) {
+                                        if (errno != EINTR && errno != EAGAIN)
+                                                return dns_stream_complete(s, errno);
+                                } else if (ss == 0)
+                                        return dns_stream_complete(s, ECONNRESET);
+                                else
+                                        s->n_read += ss;
+                        }
+
+                        /* Are we done? If so, disable the event source for EPOLLIN */
+                        if (s->n_read >= sizeof(s->read_size) + be16toh(s->read_size)) {
+                                r = dns_stream_update_io(s);
+                                if (r < 0)
+                                        return dns_stream_complete(s, -r);
+
+                                /* If there's a packet handler
+                                 * installed, call that. Note that
+                                 * this is optional... */
+                                if (s->on_packet)
+                                        return s->on_packet(s);
+                        }
+                }
+        }
+
+        if ((s->write_packet && s->n_written >= sizeof(s->write_size) + s->write_packet->size) &&
+            (s->read_packet && s->n_read >= sizeof(s->read_size) + s->read_packet->size))
+                return dns_stream_complete(s, 0);
+
+        return 0;
+}
+
+DnsStream *dns_stream_free(DnsStream *s) {
+        if (!s)
+                return NULL;
+
+        dns_stream_stop(s);
+
+        if (s->manager) {
+                LIST_REMOVE(streams, s->manager->dns_streams, s);
+                s->manager->n_dns_streams--;
+        }
+
+        dns_packet_unref(s->write_packet);
+        dns_packet_unref(s->read_packet);
+
+        free(s);
+
+        return 0;
+}
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(DnsStream*, dns_stream_free);
+
+int dns_stream_new(Manager *m, DnsStream **ret, DnsProtocol protocol, int fd) {
+        static const int one = 1;
+        _cleanup_(dns_stream_freep) DnsStream *s = NULL;
+        int r;
+
+        assert(m);
+        assert(fd >= 0);
+
+        if (m->n_dns_streams > DNS_STREAMS_MAX)
+                return -EBUSY;
+
+        s = new0(DnsStream, 1);
+        if (!s)
+                return -ENOMEM;
+
+        s->fd = -1;
+        s->protocol = protocol;
+
+        r = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one));
+        if (r < 0)
+                return -errno;
+
+        r = sd_event_add_io(m->event, &s->io_event_source, fd, EPOLLIN, on_stream_io, s);
+        if (r < 0)
+                return r;
+
+        r = sd_event_add_time(
+                        m->event,
+                        &s->timeout_event_source,
+                        clock_boottime_or_monotonic(),
+                        now(clock_boottime_or_monotonic()) + DNS_STREAM_TIMEOUT_USEC, 0,
+                        on_stream_timeout, s);
+        if (r < 0)
+                return r;
+
+        LIST_PREPEND(streams, m->dns_streams, s);
+        s->manager = m;
+        s->fd = fd;
+        m->n_dns_streams++;
+
+        *ret = s;
+        s = NULL;
+
+        return 0;
+}
+
+int dns_stream_write_packet(DnsStream *s, DnsPacket *p) {
+        assert(s);
+
+        if (s->write_packet)
+                return -EBUSY;
+
+        s->write_packet = dns_packet_ref(p);
+        s->write_size = htobe16(p->size);
+        s->n_written = 0;
+
+        return dns_stream_update_io(s);
+}
diff --git a/src/resolve/resolved-dns-stream.h b/src/resolve/resolved-dns-stream.h
new file mode 100644 (file)
index 0000000..46eae31
--- /dev/null
@@ -0,0 +1,64 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "socket-util.h"
+
+typedef struct DnsStream DnsStream;
+
+#include "resolved-dns-packet.h"
+#include "resolved-dns-transaction.h"
+#include "resolved-manager.h"
+
+struct DnsStream {
+        Manager *manager;
+
+        DnsProtocol protocol;
+
+        int fd;
+        union sockaddr_union peer;
+        socklen_t peer_salen;
+        union sockaddr_union local;
+        socklen_t local_salen;
+        int ifindex;
+        uint32_t ttl;
+        bool identified;
+
+        sd_event_source *io_event_source;
+        sd_event_source *timeout_event_source;
+
+        be16_t write_size, read_size;
+        DnsPacket *write_packet, *read_packet;
+        size_t n_written, n_read;
+
+        int (*on_packet)(DnsStream *s);
+        int (*complete)(DnsStream *s, int error);
+
+        DnsTransaction *transaction;
+
+        LIST_FIELDS(DnsStream, streams);
+};
+
+int dns_stream_new(Manager *m, DnsStream **s, DnsProtocol protocol, int fd);
+DnsStream *dns_stream_free(DnsStream *s);
+
+int dns_stream_write_packet(DnsStream *s, DnsPacket *p);
diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c
new file mode 100644 (file)
index 0000000..990b1f2
--- /dev/null
@@ -0,0 +1,619 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "af-list.h"
+
+#include "resolved-dns-transaction.h"
+
+DnsTransaction* dns_transaction_free(DnsTransaction *t) {
+        DnsQuery *q;
+        DnsZoneItem *i;
+
+        if (!t)
+                return NULL;
+
+        sd_event_source_unref(t->timeout_event_source);
+
+        dns_question_unref(t->question);
+        dns_packet_unref(t->sent);
+        dns_packet_unref(t->received);
+        dns_answer_unref(t->cached);
+
+        dns_stream_free(t->stream);
+
+        if (t->scope) {
+                LIST_REMOVE(transactions_by_scope, t->scope->transactions, t);
+
+                if (t->id != 0)
+                        hashmap_remove(t->scope->manager->dns_transactions, UINT_TO_PTR(t->id));
+        }
+
+        while ((q = set_steal_first(t->queries)))
+                set_remove(q->transactions, t);
+        set_free(t->queries);
+
+        while ((i = set_steal_first(t->zone_items)))
+                i->probe_transaction = NULL;
+        set_free(t->zone_items);
+
+        free(t);
+        return NULL;
+}
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(DnsTransaction*, dns_transaction_free);
+
+void dns_transaction_gc(DnsTransaction *t) {
+        assert(t);
+
+        if (t->block_gc > 0)
+                return;
+
+        if (set_isempty(t->queries) && set_isempty(t->zone_items))
+                dns_transaction_free(t);
+}
+
+int dns_transaction_new(DnsTransaction **ret, DnsScope *s, DnsQuestion *q) {
+        _cleanup_(dns_transaction_freep) DnsTransaction *t = NULL;
+        int r;
+
+        assert(ret);
+        assert(s);
+        assert(q);
+
+        r = hashmap_ensure_allocated(&s->manager->dns_transactions, NULL, NULL);
+        if (r < 0)
+                return r;
+
+        t = new0(DnsTransaction, 1);
+        if (!t)
+                return -ENOMEM;
+
+        t->question = dns_question_ref(q);
+
+        do
+                random_bytes(&t->id, sizeof(t->id));
+        while (t->id == 0 ||
+               hashmap_get(s->manager->dns_transactions, UINT_TO_PTR(t->id)));
+
+        r = hashmap_put(s->manager->dns_transactions, UINT_TO_PTR(t->id), t);
+        if (r < 0) {
+                t->id = 0;
+                return r;
+        }
+
+        LIST_PREPEND(transactions_by_scope, s->transactions, t);
+        t->scope = s;
+
+        if (ret)
+                *ret = t;
+
+        t = NULL;
+
+        return 0;
+}
+
+static void dns_transaction_stop(DnsTransaction *t) {
+        assert(t);
+
+        t->timeout_event_source = sd_event_source_unref(t->timeout_event_source);
+        t->stream = dns_stream_free(t->stream);
+}
+
+static void dns_transaction_tentative(DnsTransaction *t, DnsPacket *p) {
+        _cleanup_free_ char *pretty = NULL;
+        DnsZoneItem *z;
+
+        assert(t);
+        assert(p);
+
+        if (manager_our_packet(t->scope->manager, p) != 0)
+                return;
+
+        in_addr_to_string(p->family, &p->sender, &pretty);
+
+        log_debug("Transaction on scope %s on %s/%s got tentative packet from %s",
+                  dns_protocol_to_string(t->scope->protocol),
+                  t->scope->link ? t->scope->link->name : "*",
+                  t->scope->family == AF_UNSPEC ? "*" : af_to_name(t->scope->family),
+                  pretty);
+
+        /* RFC 4795, Section 4.1 says that the peer with the
+         * lexicographically smaller IP address loses */
+        if (memcmp(&p->sender, &p->destination, FAMILY_ADDRESS_SIZE(p->family)) >= 0) {
+                log_debug("Peer has lexicographically larger IP address and thus lost in the conflict.");
+                return;
+        }
+
+        log_debug("We have the lexicographically larger IP address and thus lost in the conflict.");
+
+        t->block_gc++;
+        while ((z = set_first(t->zone_items))) {
+                /* First, make sure the zone item drops the reference
+                 * to us */
+                dns_zone_item_probe_stop(z);
+
+                /* Secondly, report this as conflict, so that we might
+                 * look for a different hostname */
+                dns_zone_item_conflict(z);
+        }
+        t->block_gc--;
+
+        dns_transaction_gc(t);
+}
+
+void dns_transaction_complete(DnsTransaction *t, DnsTransactionState state) {
+        DnsQuery *q;
+        DnsZoneItem *z;
+        Iterator i;
+
+        assert(t);
+        assert(!IN_SET(state, DNS_TRANSACTION_NULL, DNS_TRANSACTION_PENDING));
+
+        if (!IN_SET(t->state, DNS_TRANSACTION_NULL, DNS_TRANSACTION_PENDING))
+                return;
+
+        /* Note that this call might invalidate the query. Callers
+         * should hence not attempt to access the query or transaction
+         * after calling this function. */
+
+        log_debug("Transaction on scope %s on %s/%s now complete with <%s>",
+                  dns_protocol_to_string(t->scope->protocol),
+                  t->scope->link ? t->scope->link->name : "*",
+                  t->scope->family == AF_UNSPEC ? "*" : af_to_name(t->scope->family),
+                  dns_transaction_state_to_string(state));
+
+        t->state = state;
+
+        dns_transaction_stop(t);
+
+        /* Notify all queries that are interested, but make sure the
+         * transaction isn't freed while we are still looking at it */
+        t->block_gc++;
+        SET_FOREACH(q, t->queries, i)
+                dns_query_ready(q);
+        SET_FOREACH(z, t->zone_items, i)
+                dns_zone_item_ready(z);
+        t->block_gc--;
+
+        dns_transaction_gc(t);
+}
+
+static int on_stream_complete(DnsStream *s, int error) {
+        _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
+        DnsTransaction *t;
+
+        assert(s);
+        assert(s->transaction);
+
+        /* Copy the data we care about out of the stream before we
+         * destroy it. */
+        t = s->transaction;
+        p = dns_packet_ref(s->read_packet);
+
+        t->stream = dns_stream_free(t->stream);
+
+        if (error != 0) {
+                dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
+                return 0;
+        }
+
+        if (dns_packet_validate_reply(p) <= 0) {
+                log_debug("Invalid LLMNR TCP packet.");
+                dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
+                return 0;
+        }
+
+        dns_scope_check_conflicts(t->scope, p);
+
+        t->block_gc++;
+        dns_transaction_process_reply(t, p);
+        t->block_gc--;
+
+        /* If the response wasn't useful, then complete the transition now */
+        if (t->state == DNS_TRANSACTION_PENDING)
+                dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
+
+        return 0;
+}
+
+static int dns_transaction_open_tcp(DnsTransaction *t) {
+        _cleanup_close_ int fd = -1;
+        int r;
+
+        assert(t);
+
+        if (t->stream)
+                return 0;
+
+        if (t->scope->protocol == DNS_PROTOCOL_DNS)
+                fd = dns_scope_tcp_socket(t->scope, AF_UNSPEC, NULL, 53);
+        else if (t->scope->protocol == DNS_PROTOCOL_LLMNR) {
+
+                /* When we already received a query to this (but it was truncated), send to its sender address */
+                if (t->received)
+                        fd = dns_scope_tcp_socket(t->scope, t->received->family, &t->received->sender, t->received->sender_port);
+                else {
+                        union in_addr_union address;
+                        int family;
+
+                        /* Otherwise, try to talk to the owner of a
+                         * the IP address, in case this is a reverse
+                         * PTR lookup */
+                        r = dns_question_extract_reverse_address(t->question, &family, &address);
+                        if (r < 0)
+                                return r;
+                        if (r == 0)
+                                return -EINVAL;
+
+                        fd = dns_scope_tcp_socket(t->scope, family, &address, 5355);
+                }
+        } else
+                return -EAFNOSUPPORT;
+
+        if (fd < 0)
+                return fd;
+
+        r = dns_stream_new(t->scope->manager, &t->stream, t->scope->protocol, fd);
+        if (r < 0)
+                return r;
+
+        fd = -1;
+
+        r = dns_stream_write_packet(t->stream, t->sent);
+        if (r < 0) {
+                t->stream = dns_stream_free(t->stream);
+                return r;
+        }
+
+        t->received = dns_packet_unref(t->received);
+        t->stream->complete = on_stream_complete;
+        t->stream->transaction = t;
+
+        /* The interface index is difficult to determine if we are
+         * connecting to the local host, hence fill this in right away
+         * instead of determining it from the socket */
+        if (t->scope->link)
+                t->stream->ifindex = t->scope->link->ifindex;
+
+        return 0;
+}
+
+void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) {
+        int r;
+
+        assert(t);
+        assert(p);
+        assert(t->state == DNS_TRANSACTION_PENDING);
+
+        /* Note that this call might invalidate the query. Callers
+         * should hence not attempt to access the query or transaction
+         * after calling this function. */
+
+        if (t->scope->protocol == DNS_PROTOCOL_LLMNR) {
+                assert(t->scope->link);
+
+                /* For LLMNR we will not accept any packets from other
+                 * interfaces */
+
+                if (p->ifindex != t->scope->link->ifindex)
+                        return;
+
+                if (p->family != t->scope->family)
+                        return;
+
+                /* Tentative packets are not full responses but still
+                 * useful for identifying uniqueness conflicts during
+                 * probing. */
+                if (DNS_PACKET_T(p)) {
+                        dns_transaction_tentative(t, p);
+                        return;
+                }
+        }
+
+        if (t->scope->protocol == DNS_PROTOCOL_DNS) {
+
+                /* For DNS we are fine with accepting packets on any
+                 * interface, but the source IP address must be one of
+                 * a valid DNS server */
+
+                if (!dns_scope_good_dns_server(t->scope, p->family, &p->sender))
+                        return;
+
+                if (p->sender_port != 53)
+                        return;
+        }
+
+        if (t->received != p) {
+                dns_packet_unref(t->received);
+                t->received = dns_packet_ref(p);
+        }
+
+        if (p->ipproto == IPPROTO_TCP) {
+                if (DNS_PACKET_TC(p)) {
+                        /* Truncated via TCP? Somebody must be fucking with us */
+                        dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
+                        return;
+                }
+
+                if (DNS_PACKET_ID(p) != t->id) {
+                        /* Not the reply to our query? Somebody must be fucking with us */
+                        dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
+                        return;
+                }
+        }
+
+        if (DNS_PACKET_TC(p)) {
+                /* Response was truncated, let's try again with good old TCP */
+                r = dns_transaction_open_tcp(t);
+                if (r == -ESRCH) {
+                        /* No servers found? Damn! */
+                        dns_transaction_complete(t, DNS_TRANSACTION_NO_SERVERS);
+                        return;
+                }
+                if (r < 0) {
+                        /* On LLMNR, if we cannot connect to the host,
+                         * we immediately give up */
+                        if (t->scope->protocol == DNS_PROTOCOL_LLMNR) {
+                                dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
+                                return;
+                        }
+
+                        /* On DNS, couldn't send? Try immediately again, with a new server */
+                        dns_scope_next_dns_server(t->scope);
+
+                        r = dns_transaction_go(t);
+                        if (r < 0) {
+                                dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
+                                return;
+                        }
+
+                        return;
+                }
+        }
+
+        /* Parse and update the cache */
+        r = dns_packet_extract(p);
+        if (r < 0) {
+                dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
+                return;
+        }
+
+        /* According to RFC 4795, section 2.9. only the RRs from the answer section shall be cached */
+        dns_cache_put(&t->scope->cache, p->question, DNS_PACKET_RCODE(p), p->answer, DNS_PACKET_ANCOUNT(p), 0, p->family, &p->sender);
+
+        if (DNS_PACKET_RCODE(p) == DNS_RCODE_SUCCESS)
+                dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
+        else
+                dns_transaction_complete(t, DNS_TRANSACTION_FAILURE);
+}
+
+static int on_transaction_timeout(sd_event_source *s, usec_t usec, void *userdata) {
+        DnsTransaction *t = userdata;
+        int r;
+
+        assert(s);
+        assert(t);
+
+        /* Timeout reached? Try again, with a new server */
+        dns_scope_next_dns_server(t->scope);
+
+        r = dns_transaction_go(t);
+        if (r < 0)
+                dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
+
+        return 0;
+}
+
+static int dns_transaction_make_packet(DnsTransaction *t) {
+        _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
+        unsigned n, added = 0;
+        int r;
+
+        assert(t);
+
+        if (t->sent)
+                return 0;
+
+        r = dns_packet_new_query(&p, t->scope->protocol, 0);
+        if (r < 0)
+                return r;
+
+        for (n = 0; n < t->question->n_keys; n++) {
+                r = dns_scope_good_key(t->scope, t->question->keys[n]);
+                if (r < 0)
+                        return r;
+                if (r == 0)
+                        continue;
+
+                r = dns_packet_append_key(p, t->question->keys[n], NULL);
+                if (r < 0)
+                        return r;
+
+                added++;
+        }
+
+        if (added <= 0)
+                return -EDOM;
+
+        DNS_PACKET_HEADER(p)->qdcount = htobe16(added);
+        DNS_PACKET_HEADER(p)->id = t->id;
+
+        t->sent = p;
+        p = NULL;
+
+        return 0;
+}
+
+int dns_transaction_go(DnsTransaction *t) {
+        bool had_stream;
+        int r;
+
+        assert(t);
+
+        had_stream = !!t->stream;
+
+        dns_transaction_stop(t);
+
+        log_debug("Excercising transaction on scope %s on %s/%s",
+                  dns_protocol_to_string(t->scope->protocol),
+                  t->scope->link ? t->scope->link->name : "*",
+                  t->scope->family == AF_UNSPEC ? "*" : af_to_name(t->scope->family));
+
+        if (t->n_attempts >= TRANSACTION_ATTEMPTS_MAX(t->scope->protocol)) {
+                dns_transaction_complete(t, DNS_TRANSACTION_ATTEMPTS_MAX_REACHED);
+                return 0;
+        }
+
+        if (t->scope->protocol == DNS_PROTOCOL_LLMNR && had_stream) {
+                /* If we already tried via a stream, then we don't
+                 * retry on LLMNR. See RFC 4795, Section 2.7. */
+                dns_transaction_complete(t, DNS_TRANSACTION_ATTEMPTS_MAX_REACHED);
+                return 0;
+        }
+
+        t->n_attempts++;
+        t->received = dns_packet_unref(t->received);
+        t->cached = dns_answer_unref(t->cached);
+        t->cached_rcode = 0;
+
+        /* Check the cache, but only if this transaction is not used
+         * for probing or verifying a zone item. */
+        if (set_isempty(t->zone_items)) {
+
+                /* Before trying the cache, let's make sure we figured out a
+                 * server to use. Should this cause a change of server this
+                 * might flush the cache. */
+                dns_scope_get_dns_server(t->scope);
+
+                /* Let's then prune all outdated entries */
+                dns_cache_prune(&t->scope->cache);
+
+                r = dns_cache_lookup(&t->scope->cache, t->question, &t->cached_rcode, &t->cached);
+                if (r < 0)
+                        return r;
+                if (r > 0) {
+                        log_debug("Cache hit!");
+                        if (t->cached_rcode == DNS_RCODE_SUCCESS)
+                                dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
+                        else
+                                dns_transaction_complete(t, DNS_TRANSACTION_FAILURE);
+                        return 0;
+                }
+        }
+
+        if (t->scope->protocol == DNS_PROTOCOL_LLMNR && !t->initial_jitter) {
+                usec_t jitter;
+
+                /* RFC 4795 Section 2.7 suggests all queries should be
+                 * delayed by a random time from 0 to JITTER_INTERVAL. */
+
+                t->initial_jitter = true;
+
+                random_bytes(&jitter, sizeof(jitter));
+                jitter %= LLMNR_JITTER_INTERVAL_USEC;
+
+                r = sd_event_add_time(
+                                t->scope->manager->event,
+                                &t->timeout_event_source,
+                                clock_boottime_or_monotonic(),
+                                now(clock_boottime_or_monotonic()) + jitter,
+                                LLMNR_JITTER_INTERVAL_USEC,
+                                on_transaction_timeout, t);
+                if (r < 0)
+                        return r;
+
+                t->n_attempts = 0;
+                t->state = DNS_TRANSACTION_PENDING;
+
+                log_debug("Delaying LLMNR transaction for " USEC_FMT "us.", jitter);
+                return 0;
+        }
+
+        log_debug("Cache miss!");
+
+        /* Otherwise, we need to ask the network */
+        r = dns_transaction_make_packet(t);
+        if (r == -EDOM) {
+                /* Not the right request to make on this network?
+                 * (i.e. an A request made on IPv6 or an AAAA request
+                 * made on IPv4, on LLMNR or mDNS.) */
+                dns_transaction_complete(t, DNS_TRANSACTION_NO_SERVERS);
+                return 0;
+        }
+        if (r < 0)
+                return r;
+
+        if (t->scope->protocol == DNS_PROTOCOL_LLMNR &&
+            (dns_question_endswith(t->question, "in-addr.arpa") > 0 ||
+             dns_question_endswith(t->question, "ip6.arpa") > 0)) {
+
+                /* RFC 4795, Section 2.4. says reverse lookups shall
+                 * always be made via TCP on LLMNR */
+                r = dns_transaction_open_tcp(t);
+        } else {
+                /* Try via UDP, and if that fails due to large size try via TCP */
+                r = dns_scope_emit(t->scope, t->sent);
+                if (r == -EMSGSIZE)
+                        r = dns_transaction_open_tcp(t);
+        }
+        if (r == -ESRCH) {
+                /* No servers to send this to? */
+                dns_transaction_complete(t, DNS_TRANSACTION_NO_SERVERS);
+                return 0;
+        }
+        if (r < 0) {
+                if (t->scope->protocol != DNS_PROTOCOL_DNS) {
+                        dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
+                        return 0;
+                }
+
+                /* Couldn't send? Try immediately again, with a new server */
+                dns_scope_next_dns_server(t->scope);
+
+                return dns_transaction_go(t);
+        }
+
+        r = sd_event_add_time(
+                        t->scope->manager->event,
+                        &t->timeout_event_source,
+                        clock_boottime_or_monotonic(),
+                        now(clock_boottime_or_monotonic()) + TRANSACTION_TIMEOUT_USEC(t->scope->protocol), 0,
+                        on_transaction_timeout, t);
+        if (r < 0)
+                return r;
+
+        t->state = DNS_TRANSACTION_PENDING;
+        return 1;
+}
+
+static const char* const dns_transaction_state_table[_DNS_TRANSACTION_STATE_MAX] = {
+        [DNS_TRANSACTION_NULL] = "null",
+        [DNS_TRANSACTION_PENDING] = "pending",
+        [DNS_TRANSACTION_FAILURE] = "failure",
+        [DNS_TRANSACTION_SUCCESS] = "success",
+        [DNS_TRANSACTION_NO_SERVERS] = "no-servers",
+        [DNS_TRANSACTION_TIMEOUT] = "timeout",
+        [DNS_TRANSACTION_ATTEMPTS_MAX_REACHED] = "attempts-max-reached",
+        [DNS_TRANSACTION_INVALID_REPLY] = "invalid-reply",
+        [DNS_TRANSACTION_RESOURCES] = "resources",
+        [DNS_TRANSACTION_ABORTED] = "aborted",
+};
+DEFINE_STRING_TABLE_LOOKUP(dns_transaction_state, DnsTransactionState);
diff --git a/src/resolve/resolved-dns-transaction.h b/src/resolve/resolved-dns-transaction.h
new file mode 100644 (file)
index 0000000..182fb77
--- /dev/null
@@ -0,0 +1,110 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+typedef struct DnsTransaction DnsTransaction;
+typedef enum DnsTransactionState DnsTransactionState;
+
+enum DnsTransactionState {
+        DNS_TRANSACTION_NULL,
+        DNS_TRANSACTION_PENDING,
+        DNS_TRANSACTION_FAILURE,
+        DNS_TRANSACTION_SUCCESS,
+        DNS_TRANSACTION_NO_SERVERS,
+        DNS_TRANSACTION_TIMEOUT,
+        DNS_TRANSACTION_ATTEMPTS_MAX_REACHED,
+        DNS_TRANSACTION_INVALID_REPLY,
+        DNS_TRANSACTION_RESOURCES,
+        DNS_TRANSACTION_ABORTED,
+        _DNS_TRANSACTION_STATE_MAX,
+        _DNS_TRANSACTION_STATE_INVALID = -1
+};
+
+#include "resolved-dns-scope.h"
+#include "resolved-dns-rr.h"
+#include "resolved-dns-packet.h"
+#include "resolved-dns-question.h"
+#include "resolved-dns-answer.h"
+#include "resolved-dns-stream.h"
+
+struct DnsTransaction {
+        DnsScope *scope;
+
+        DnsQuestion *question;
+
+        DnsTransactionState state;
+        uint16_t id;
+
+        bool initial_jitter;
+
+        DnsPacket *sent, *received;
+        DnsAnswer *cached;
+        int cached_rcode;
+
+        sd_event_source *timeout_event_source;
+        unsigned n_attempts;
+
+        /* TCP connection logic, if we need it */
+        DnsStream *stream;
+
+        /* Queries this transaction is referenced by and that shall be
+         * notified about this specific transaction completing. */
+        Set *queries;
+
+        /* Zone items this transaction is referenced by and that shall
+         * be notified about completion. */
+        Set *zone_items;
+
+        unsigned block_gc;
+
+        LIST_FIELDS(DnsTransaction, transactions_by_scope);
+};
+
+int dns_transaction_new(DnsTransaction **ret, DnsScope *s, DnsQuestion *q);
+DnsTransaction* dns_transaction_free(DnsTransaction *t);
+
+void dns_transaction_gc(DnsTransaction *t);
+int dns_transaction_go(DnsTransaction *t);
+
+void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p);
+void dns_transaction_complete(DnsTransaction *t, DnsTransactionState state);
+
+const char* dns_transaction_state_to_string(DnsTransactionState p) _const_;
+DnsTransactionState dns_transaction_state_from_string(const char *s) _pure_;
+
+/* After how much time to repeat classic DNS requests */
+#define DNS_TRANSACTION_TIMEOUT_USEC (5 * USEC_PER_SEC)
+
+/* After how much time to repeat LLMNR requests, see RFC 4795 Section 7 */
+#define LLMNR_TRANSACTION_TIMEOUT_USEC (1 * USEC_PER_SEC)
+
+/* LLMNR Jitter interval, see RFC 4795 Section 7 */
+#define LLMNR_JITTER_INTERVAL_USEC (100 * USEC_PER_MSEC)
+
+/* Maximum attempts to send DNS requests, across all DNS servers */
+#define DNS_TRANSACTION_ATTEMPTS_MAX 8
+
+/* Maximum attempts to send LLMNR requests, see RFC 4795 Section 2.7 */
+#define LLMNR_TRANSACTION_ATTEMPTS_MAX 3
+
+#define TRANSACTION_TIMEOUT_USEC(p) (p == DNS_PROTOCOL_LLMNR ? LLMNR_TRANSACTION_TIMEOUT_USEC : DNS_TRANSACTION_TIMEOUT_USEC)
+#define TRANSACTION_ATTEMPTS_MAX(p) (p == DNS_PROTOCOL_LLMNR ? LLMNR_TRANSACTION_ATTEMPTS_MAX : DNS_TRANSACTION_ATTEMPTS_MAX)
diff --git a/src/resolve/resolved-dns-zone.c b/src/resolve/resolved-dns-zone.c
new file mode 100644 (file)
index 0000000..b53e957
--- /dev/null
@@ -0,0 +1,648 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "list.h"
+
+#include "resolved-dns-zone.h"
+#include "resolved-dns-domain.h"
+#include "resolved-dns-packet.h"
+
+/* Never allow more than 1K entries */
+#define ZONE_MAX 1024
+
+void dns_zone_item_probe_stop(DnsZoneItem *i) {
+        DnsTransaction *t;
+        assert(i);
+
+        if (!i->probe_transaction)
+                return;
+
+        t = i->probe_transaction;
+        i->probe_transaction = NULL;
+
+        set_remove(t->zone_items, i);
+        dns_transaction_gc(t);
+}
+
+static void dns_zone_item_free(DnsZoneItem *i) {
+        if (!i)
+                return;
+
+        dns_zone_item_probe_stop(i);
+        dns_resource_record_unref(i->rr);
+
+        free(i);
+}
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(DnsZoneItem*, dns_zone_item_free);
+
+static void dns_zone_item_remove_and_free(DnsZone *z, DnsZoneItem *i) {
+        DnsZoneItem *first;
+
+        assert(z);
+
+        if (!i)
+                return;
+
+        first = hashmap_get(z->by_key, i->rr->key);
+        LIST_REMOVE(by_key, first, i);
+        if (first)
+                assert_se(hashmap_replace(z->by_key, first->rr->key, first) >= 0);
+        else
+                hashmap_remove(z->by_key, i->rr->key);
+
+        first = hashmap_get(z->by_name, DNS_RESOURCE_KEY_NAME(i->rr->key));
+        LIST_REMOVE(by_name, first, i);
+        if (first)
+                assert_se(hashmap_replace(z->by_name, DNS_RESOURCE_KEY_NAME(first->rr->key), first) >= 0);
+        else
+                hashmap_remove(z->by_name, DNS_RESOURCE_KEY_NAME(i->rr->key));
+
+        dns_zone_item_free(i);
+}
+
+void dns_zone_flush(DnsZone *z) {
+        DnsZoneItem *i;
+
+        assert(z);
+
+        while ((i = hashmap_first(z->by_key)))
+                dns_zone_item_remove_and_free(z, i);
+
+        assert(hashmap_size(z->by_key) == 0);
+        assert(hashmap_size(z->by_name) == 0);
+
+        hashmap_free(z->by_key);
+        z->by_key = NULL;
+
+        hashmap_free(z->by_name);
+        z->by_name = NULL;
+}
+
+static DnsZoneItem* dns_zone_get(DnsZone *z, DnsResourceRecord *rr) {
+        DnsZoneItem *i;
+
+        assert(z);
+        assert(rr);
+
+        LIST_FOREACH(by_key, i, hashmap_get(z->by_key, rr->key))
+                if (dns_resource_record_equal(i->rr, rr) > 0)
+                        return i;
+
+        return NULL;
+}
+
+void dns_zone_remove_rr(DnsZone *z, DnsResourceRecord *rr) {
+        DnsZoneItem *i;
+
+        assert(z);
+        assert(rr);
+
+        i = dns_zone_get(z, rr);
+        if (i)
+                dns_zone_item_remove_and_free(z, i);
+}
+
+static int dns_zone_init(DnsZone *z) {
+        int r;
+
+        assert(z);
+
+        r = hashmap_ensure_allocated(&z->by_key, dns_resource_key_hash_func, dns_resource_key_compare_func);
+        if (r < 0)
+                return r;
+
+        r = hashmap_ensure_allocated(&z->by_name, dns_name_hash_func, dns_name_compare_func);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+static int dns_zone_link_item(DnsZone *z, DnsZoneItem *i) {
+        DnsZoneItem *first;
+        int r;
+
+        first = hashmap_get(z->by_key, i->rr->key);
+        if (first) {
+                LIST_PREPEND(by_key, first, i);
+                assert_se(hashmap_replace(z->by_key, first->rr->key, first) >= 0);
+        } else {
+                r = hashmap_put(z->by_key, i->rr->key, i);
+                if (r < 0)
+                        return r;
+        }
+
+        first = hashmap_get(z->by_name, DNS_RESOURCE_KEY_NAME(i->rr->key));
+        if (first) {
+                LIST_PREPEND(by_name, first, i);
+                assert_se(hashmap_replace(z->by_name, DNS_RESOURCE_KEY_NAME(first->rr->key), first) >= 0);
+        } else {
+                r = hashmap_put(z->by_name, DNS_RESOURCE_KEY_NAME(i->rr->key), i);
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
+static int dns_zone_item_probe_start(DnsZoneItem *i)  {
+        _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
+        _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
+        DnsTransaction *t;
+        int r;
+
+        assert(i);
+
+        if (i->probe_transaction)
+                return 0;
+
+        key = dns_resource_key_new(i->rr->key->class, DNS_TYPE_ANY, DNS_RESOURCE_KEY_NAME(i->rr->key));
+        if (!key)
+                return -ENOMEM;
+
+        question = dns_question_new(1);
+        if (!question)
+                return -ENOMEM;
+
+        r = dns_question_add(question, key);
+        if (r < 0)
+                return r;
+
+        t = dns_scope_find_transaction(i->scope, question, false);
+        if (!t) {
+                r = dns_transaction_new(&t, i->scope, question);
+                if (r < 0)
+                        return r;
+        }
+
+        r = set_ensure_allocated(&t->zone_items, NULL, NULL);
+        if (r < 0)
+                goto gc;
+
+        r = set_put(t->zone_items, i);
+        if (r < 0)
+                goto gc;
+
+        i->probe_transaction = t;
+
+        if (t->state == DNS_TRANSACTION_NULL) {
+
+                i->block_ready++;
+                r = dns_transaction_go(t);
+                i->block_ready--;
+
+                if (r < 0) {
+                        dns_zone_item_probe_stop(i);
+                        return r;
+                }
+        }
+
+        dns_zone_item_ready(i);
+
+        return 0;
+
+gc:
+        dns_transaction_gc(t);
+        return r;
+}
+
+int dns_zone_put(DnsZone *z, DnsScope *s, DnsResourceRecord *rr, bool probe) {
+        _cleanup_(dns_zone_item_freep) DnsZoneItem *i = NULL;
+        DnsZoneItem *existing;
+        int r;
+
+        assert(z);
+        assert(s);
+        assert(rr);
+
+        if (rr->key->class == DNS_CLASS_ANY)
+                return -EINVAL;
+        if (rr->key->type == DNS_TYPE_ANY)
+                return -EINVAL;
+
+        existing = dns_zone_get(z, rr);
+        if (existing)
+                return 0;
+
+        r = dns_zone_init(z);
+        if (r < 0)
+                return r;
+
+        i = new0(DnsZoneItem, 1);
+        if (!i)
+                return -ENOMEM;
+
+        i->scope = s;
+        i->rr = dns_resource_record_ref(rr);
+        i->probing_enabled = probe;
+
+        r = dns_zone_link_item(z, i);
+        if (r < 0)
+                return r;
+
+        if (probe) {
+                DnsZoneItem *first, *j;
+                bool established = false;
+
+                /* Check if there's already an RR with the same name
+                 * established. If so, it has been probed already, and
+                 * we don't ned to probe again. */
+
+                LIST_FIND_HEAD(by_name, i, first);
+                LIST_FOREACH(by_name, j, first) {
+                        if (i == j)
+                                continue;
+
+                        if (j->state == DNS_ZONE_ITEM_ESTABLISHED)
+                                established = true;
+                }
+
+                if (established)
+                        i->state = DNS_ZONE_ITEM_ESTABLISHED;
+                else {
+                        i->state = DNS_ZONE_ITEM_PROBING;
+
+                        r = dns_zone_item_probe_start(i);
+                        if (r < 0) {
+                                dns_zone_item_remove_and_free(z, i);
+                                i = NULL;
+                                return r;
+                        }
+                }
+        } else
+                i->state = DNS_ZONE_ITEM_ESTABLISHED;
+
+        i = NULL;
+        return 0;
+}
+
+int dns_zone_lookup(DnsZone *z, DnsQuestion *q, DnsAnswer **ret_answer, DnsAnswer **ret_soa, bool *ret_tentative) {
+        _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL, *soa = NULL;
+        unsigned i, n_answer = 0, n_soa = 0;
+        bool tentative = true;
+        int r;
+
+        assert(z);
+        assert(q);
+        assert(ret_answer);
+        assert(ret_soa);
+
+        if (q->n_keys <= 0) {
+                *ret_answer = NULL;
+                *ret_soa = NULL;
+
+                if (ret_tentative)
+                        *ret_tentative = false;
+
+                return 0;
+        }
+
+        /* First iteration, count what we have */
+        for (i = 0; i < q->n_keys; i++) {
+                DnsZoneItem *j, *first;
+
+                if (q->keys[i]->type == DNS_TYPE_ANY ||
+                    q->keys[i]->class == DNS_CLASS_ANY) {
+                        bool found = false, added = false;
+                        int k;
+
+                        /* If this is a generic match, then we have to
+                         * go through the list by the name and look
+                         * for everything manually */
+
+                        first = hashmap_get(z->by_name, DNS_RESOURCE_KEY_NAME(q->keys[i]));
+                        LIST_FOREACH(by_name, j, first) {
+                                if (!IN_SET(j->state, DNS_ZONE_ITEM_PROBING, DNS_ZONE_ITEM_ESTABLISHED, DNS_ZONE_ITEM_VERIFYING))
+                                        continue;
+
+                                found = true;
+
+                                k = dns_resource_key_match_rr(q->keys[i], j->rr);
+                                if (k < 0)
+                                        return k;
+                                if (k > 0) {
+                                        n_answer++;
+                                        added = true;
+                                }
+
+                        }
+
+                        if (found && !added)
+                                n_soa++;
+
+                } else {
+                        bool found = false;
+
+                        /* If this is a specific match, then look for
+                         * the right key immediately */
+
+                        first = hashmap_get(z->by_key, q->keys[i]);
+                        LIST_FOREACH(by_key, j, first) {
+                                if (!IN_SET(j->state, DNS_ZONE_ITEM_PROBING, DNS_ZONE_ITEM_ESTABLISHED, DNS_ZONE_ITEM_VERIFYING))
+                                        continue;
+
+                                found = true;
+                                n_answer++;
+                        }
+
+                        if (!found) {
+                                first = hashmap_get(z->by_name, DNS_RESOURCE_KEY_NAME(q->keys[i]));
+                                LIST_FOREACH(by_name, j, first) {
+                                        if (!IN_SET(j->state, DNS_ZONE_ITEM_PROBING, DNS_ZONE_ITEM_ESTABLISHED, DNS_ZONE_ITEM_VERIFYING))
+                                                continue;
+
+                                        n_soa++;
+                                        break;
+                                }
+                        }
+                }
+        }
+
+        if (n_answer <= 0 && n_soa <= 0) {
+                *ret_answer = NULL;
+                *ret_soa = NULL;
+
+                if (ret_tentative)
+                        *ret_tentative = false;
+
+                return 0;
+        }
+
+        if (n_answer > 0) {
+                answer = dns_answer_new(n_answer);
+                if (!answer)
+                        return -ENOMEM;
+        }
+
+        if (n_soa > 0) {
+                soa = dns_answer_new(n_soa);
+                if (!soa)
+                        return -ENOMEM;
+        }
+
+        /* Second iteration, actually add the RRs to the answers */
+        for (i = 0; i < q->n_keys; i++) {
+                DnsZoneItem *j, *first;
+
+                if (q->keys[i]->type == DNS_TYPE_ANY ||
+                    q->keys[i]->class == DNS_CLASS_ANY) {
+                        bool found = false, added = false;
+                        int k;
+
+                        first = hashmap_get(z->by_name, DNS_RESOURCE_KEY_NAME(q->keys[i]));
+                        LIST_FOREACH(by_name, j, first) {
+                                if (!IN_SET(j->state, DNS_ZONE_ITEM_PROBING, DNS_ZONE_ITEM_ESTABLISHED, DNS_ZONE_ITEM_VERIFYING))
+                                        continue;
+
+                                found = true;
+
+                                if (j->state != DNS_ZONE_ITEM_PROBING)
+                                        tentative = false;
+
+                                k = dns_resource_key_match_rr(q->keys[i], j->rr);
+                                if (k < 0)
+                                        return k;
+                                if (k > 0) {
+                                        r = dns_answer_add(answer, j->rr);
+                                        if (r < 0)
+                                                return r;
+
+                                        added = true;
+                                }
+                        }
+
+                        if (found && !added) {
+                                r = dns_answer_add_soa(soa, DNS_RESOURCE_KEY_NAME(q->keys[i]), LLMNR_DEFAULT_TTL);
+                                if (r < 0)
+                                        return r;
+                        }
+                } else {
+                        bool found = false;
+
+                        first = hashmap_get(z->by_key, q->keys[i]);
+                        LIST_FOREACH(by_key, j, first) {
+                                if (!IN_SET(j->state, DNS_ZONE_ITEM_PROBING, DNS_ZONE_ITEM_ESTABLISHED, DNS_ZONE_ITEM_VERIFYING))
+                                        continue;
+
+                                found = true;
+
+                                if (j->state != DNS_ZONE_ITEM_PROBING)
+                                        tentative = false;
+
+                                r = dns_answer_add(answer, j->rr);
+                                if (r < 0)
+                                        return r;
+                        }
+
+                        if (!found) {
+                                bool add_soa = false;
+
+                                first = hashmap_get(z->by_name, DNS_RESOURCE_KEY_NAME(q->keys[i]));
+                                LIST_FOREACH(by_name, j, first) {
+                                        if (!IN_SET(j->state, DNS_ZONE_ITEM_PROBING, DNS_ZONE_ITEM_ESTABLISHED, DNS_ZONE_ITEM_VERIFYING))
+                                                continue;
+
+                                        if (j->state != DNS_ZONE_ITEM_PROBING)
+                                                tentative = false;
+
+                                        add_soa = true;
+                                }
+
+                                if (add_soa) {
+                                        r = dns_answer_add_soa(soa, DNS_RESOURCE_KEY_NAME(q->keys[i]), LLMNR_DEFAULT_TTL);
+                                        if (r < 0)
+                                                return r;
+                                }
+                        }
+                }
+        }
+
+        *ret_answer = answer;
+        answer = NULL;
+
+        *ret_soa = soa;
+        soa = NULL;
+
+        if (ret_tentative)
+                *ret_tentative = tentative;
+
+        return 1;
+}
+
+void dns_zone_item_conflict(DnsZoneItem *i) {
+        _cleanup_free_ char *pretty = NULL;
+
+        assert(i);
+
+        if (!IN_SET(i->state, DNS_ZONE_ITEM_PROBING, DNS_ZONE_ITEM_VERIFYING, DNS_ZONE_ITEM_ESTABLISHED))
+                return;
+
+        dns_resource_record_to_string(i->rr, &pretty);
+        log_info("Detected conflict on %s", strna(pretty));
+
+        dns_zone_item_probe_stop(i);
+
+        /* Withdraw the conflict item */
+        i->state = DNS_ZONE_ITEM_WITHDRAWN;
+
+        /* Maybe change the hostname */
+        if (dns_name_equal(i->scope->manager->hostname, DNS_RESOURCE_KEY_NAME(i->rr->key)) > 0)
+                manager_next_hostname(i->scope->manager);
+}
+
+void dns_zone_item_ready(DnsZoneItem *i) {
+        _cleanup_free_ char *pretty = NULL;
+
+        assert(i);
+        assert(i->probe_transaction);
+
+        if (i->block_ready > 0)
+                return;
+
+        if (IN_SET(i->probe_transaction->state, DNS_TRANSACTION_NULL, DNS_TRANSACTION_PENDING))
+                return;
+
+        if (i->probe_transaction->state == DNS_TRANSACTION_SUCCESS) {
+                bool we_lost = false;
+
+                /* The probe got a successful reply. If we so far
+                 * weren't established we just give up. If we already
+                 * were established, and the peer has the
+                 * lexicographically larger IP address we continue
+                 * and defend it. */
+
+                if (!IN_SET(i->state, DNS_ZONE_ITEM_ESTABLISHED, DNS_ZONE_ITEM_VERIFYING)) {
+                        log_debug("Got a successful probe for not yet established RR, we lost.");
+                        we_lost = true;
+                } else {
+                        assert(i->probe_transaction->received);
+                        we_lost = memcmp(&i->probe_transaction->received->sender, &i->probe_transaction->received->destination, FAMILY_ADDRESS_SIZE(i->probe_transaction->received->family)) < 0;
+                        if (we_lost)
+                                log_debug("Got a successful probe reply for an established RR, and we have a lexicographically larger IP address and thus lost.");
+                }
+
+                if (we_lost) {
+                        dns_zone_item_conflict(i);
+                        return;
+                }
+
+                log_debug("Got a successful probe reply, but peer has lexicographically lower IP address and thus lost.");
+        }
+
+        dns_resource_record_to_string(i->rr, &pretty);
+        log_debug("Record %s successfully probed.", strna(pretty));
+
+        dns_zone_item_probe_stop(i);
+        i->state = DNS_ZONE_ITEM_ESTABLISHED;
+}
+
+static int dns_zone_item_verify(DnsZoneItem *i) {
+        _cleanup_free_ char *pretty = NULL;
+        int r;
+
+        assert(i);
+
+        if (i->state != DNS_ZONE_ITEM_ESTABLISHED)
+                return 0;
+
+        dns_resource_record_to_string(i->rr, &pretty);
+        log_debug("Verifying RR %s", strna(pretty));
+
+        i->state = DNS_ZONE_ITEM_VERIFYING;
+        r = dns_zone_item_probe_start(i);
+        if (r < 0) {
+                log_error("Failed to start probing for verifying RR: %s", strerror(-r));
+                i->state = DNS_ZONE_ITEM_ESTABLISHED;
+                return r;
+        }
+
+        return 0;
+}
+
+int dns_zone_check_conflicts(DnsZone *zone, DnsResourceRecord *rr) {
+        DnsZoneItem *i, *first;
+        int c = 0;
+
+        assert(zone);
+        assert(rr);
+
+        /* This checks whether a response RR we received from somebody
+         * else is one that we actually thought was uniquely ours. If
+         * so, we'll verify our RRs. */
+
+        /* No conflict if we don't have the name at all. */
+        first = hashmap_get(zone->by_name, DNS_RESOURCE_KEY_NAME(rr->key));
+        if (!first)
+                return 0;
+
+        /* No conflict if we have the exact same RR */
+        if (dns_zone_get(zone, rr))
+                return 0;
+
+        /* OK, somebody else has RRs for the same name. Yuck! Let's
+         * start probing again */
+
+        LIST_FOREACH(by_name, i, first) {
+                if (dns_resource_record_equal(i->rr, rr))
+                        continue;
+
+                dns_zone_item_verify(i);
+                c++;
+        }
+
+        return c;
+}
+
+int dns_zone_verify_conflicts(DnsZone *zone, DnsResourceKey *key) {
+        DnsZoneItem *i, *first;
+        int c = 0;
+
+        assert(zone);
+
+        /* Somebody else notified us about a possible conflict. Let's
+         * verify if that's true. */
+
+        first = hashmap_get(zone->by_name, DNS_RESOURCE_KEY_NAME(key));
+        if (!first)
+                return 0;
+
+        LIST_FOREACH(by_name, i, first) {
+                dns_zone_item_verify(i);
+                c++;
+        }
+
+        return c;
+}
+
+void dns_zone_verify_all(DnsZone *zone) {
+        DnsZoneItem *i;
+        Iterator iterator;
+
+        assert(zone);
+
+        HASHMAP_FOREACH(i, zone->by_key, iterator) {
+                DnsZoneItem *j;
+
+                LIST_FOREACH(by_key, j, i)
+                        dns_zone_item_verify(j);
+        }
+}
diff --git a/src/resolve/resolved-dns-zone.h b/src/resolve/resolved-dns-zone.h
new file mode 100644 (file)
index 0000000..7185126
--- /dev/null
@@ -0,0 +1,80 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "hashmap.h"
+
+typedef struct DnsZone {
+        Hashmap *by_key;
+        Hashmap *by_name;
+} DnsZone;
+
+typedef struct DnsZoneItem DnsZoneItem;
+typedef enum DnsZoneItemState DnsZoneItemState;
+
+#include "resolved-dns-rr.h"
+#include "resolved-dns-question.h"
+#include "resolved-dns-answer.h"
+#include "resolved-dns-transaction.h"
+
+/* RFC 4795 Section 2.8. suggests a TTL of 30s by default */
+#define LLMNR_DEFAULT_TTL (30)
+
+enum DnsZoneItemState {
+        DNS_ZONE_ITEM_PROBING,
+        DNS_ZONE_ITEM_ESTABLISHED,
+        DNS_ZONE_ITEM_VERIFYING,
+        DNS_ZONE_ITEM_WITHDRAWN,
+};
+
+struct DnsZoneItem {
+        DnsScope *scope;
+        DnsResourceRecord *rr;
+
+        DnsZoneItemState state;
+
+        unsigned block_ready;
+
+        bool probing_enabled;
+
+        LIST_FIELDS(DnsZoneItem, by_key);
+        LIST_FIELDS(DnsZoneItem, by_name);
+
+        DnsTransaction *probe_transaction;
+};
+
+void dns_zone_flush(DnsZone *z);
+
+int dns_zone_put(DnsZone *z, DnsScope *s, DnsResourceRecord *rr, bool probe);
+void dns_zone_remove_rr(DnsZone *z, DnsResourceRecord *rr);
+
+int dns_zone_lookup(DnsZone *z, DnsQuestion *q, DnsAnswer **answer, DnsAnswer **soa, bool *tentative);
+
+void dns_zone_item_conflict(DnsZoneItem *i);
+void dns_zone_item_ready(DnsZoneItem *i);
+
+int dns_zone_check_conflicts(DnsZone *zone, DnsResourceRecord *rr);
+int dns_zone_verify_conflicts(DnsZone *zone, DnsResourceKey *key);
+
+void dns_zone_verify_all(DnsZone *zone);
+
+void dns_zone_item_probe_stop(DnsZoneItem *i);
diff --git a/src/resolve/resolved-gperf.gperf b/src/resolve/resolved-gperf.gperf
new file mode 100644 (file)
index 0000000..8e78fbf
--- /dev/null
@@ -0,0 +1,19 @@
+%{
+#include <stddef.h>
+#include "conf-parser.h"
+#include "resolved-conf.h"
+%}
+struct ConfigPerfItem;
+%null_strings
+%language=ANSI-C
+%define slot-name section_and_lvalue
+%define hash-function-name resolved_gperf_hash
+%define lookup-function-name resolved_gperf_lookup
+%readonly-tables
+%omit-struct-type
+%struct-type
+%includes
+%%
+Resolve.DNS,          config_parse_dnsv,    DNS_SERVER_SYSTEM,   0
+Resolve.FallbackDNS,  config_parse_dnsv,    DNS_SERVER_FALLBACK, 0
+Resolve.LLMNR,        config_parse_support, 0,                   offsetof(Manager, llmnr_support)
diff --git a/src/resolve/resolved-link.c b/src/resolve/resolved-link.c
new file mode 100644 (file)
index 0000000..f47017c
--- /dev/null
@@ -0,0 +1,552 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <net/if.h>
+
+#include "sd-network.h"
+#include "strv.h"
+#include "missing.h"
+#include "resolved-link.h"
+
+int link_new(Manager *m, Link **ret, int ifindex) {
+        _cleanup_(link_freep) Link *l = NULL;
+        int r;
+
+        assert(m);
+        assert(ifindex > 0);
+
+        r = hashmap_ensure_allocated(&m->links, NULL, NULL);
+        if (r < 0)
+                return r;
+
+        l = new0(Link, 1);
+        if (!l)
+                return -ENOMEM;
+
+        l->ifindex = ifindex;
+        l->llmnr_support = SUPPORT_YES;
+
+        r = hashmap_put(m->links, INT_TO_PTR(ifindex), l);
+        if (r < 0)
+                return r;
+
+        l->manager = m;
+
+        if (ret)
+                *ret = l;
+        l = NULL;
+
+        return 0;
+}
+
+Link *link_free(Link *l) {
+
+        if (!l)
+                return NULL;
+
+        while (l->addresses)
+                link_address_free(l->addresses);
+
+        if (l->manager)
+                hashmap_remove(l->manager->links, INT_TO_PTR(l->ifindex));
+
+        dns_scope_free(l->unicast_scope);
+        dns_scope_free(l->llmnr_ipv4_scope);
+        dns_scope_free(l->llmnr_ipv6_scope);
+
+        while (l->dns_servers)
+                dns_server_free(l->dns_servers);
+
+        free(l);
+        return NULL;
+}
+
+static void link_allocate_scopes(Link *l) {
+        int r;
+
+        assert(l);
+
+        if (l->dns_servers) {
+                if (!l->unicast_scope) {
+                        r = dns_scope_new(l->manager, &l->unicast_scope, l, DNS_PROTOCOL_DNS, AF_UNSPEC);
+                        if (r < 0)
+                                log_warning("Failed to allocate DNS scope: %s", strerror(-r));
+                }
+        } else
+                l->unicast_scope = dns_scope_free(l->unicast_scope);
+
+        if (link_relevant(l, AF_INET) &&
+            l->llmnr_support != SUPPORT_NO &&
+            l->manager->llmnr_support != SUPPORT_NO) {
+                if (!l->llmnr_ipv4_scope) {
+                        r = dns_scope_new(l->manager, &l->llmnr_ipv4_scope, l, DNS_PROTOCOL_LLMNR, AF_INET);
+                        if (r < 0)
+                                log_warning("Failed to allocate LLMNR IPv4 scope: %s", strerror(-r));
+                }
+        } else
+                l->llmnr_ipv4_scope = dns_scope_free(l->llmnr_ipv4_scope);
+
+        if (link_relevant(l, AF_INET6) &&
+            l->llmnr_support != SUPPORT_NO &&
+            l->manager->llmnr_support != SUPPORT_NO &&
+            socket_ipv6_is_supported()) {
+                if (!l->llmnr_ipv6_scope) {
+                        r = dns_scope_new(l->manager, &l->llmnr_ipv6_scope, l, DNS_PROTOCOL_LLMNR, AF_INET6);
+                        if (r < 0)
+                                log_warning("Failed to allocate LLMNR IPv6 scope: %s", strerror(-r));
+                }
+        } else
+                l->llmnr_ipv6_scope = dns_scope_free(l->llmnr_ipv6_scope);
+}
+
+void link_add_rrs(Link *l, bool force_remove) {
+        LinkAddress *a;
+
+        LIST_FOREACH(addresses, a, l->addresses)
+                link_address_add_rrs(a, force_remove);
+}
+
+int link_update_rtnl(Link *l, sd_rtnl_message *m) {
+        const char *n = NULL;
+        int r;
+
+        assert(l);
+        assert(m);
+
+        r = sd_rtnl_message_link_get_flags(m, &l->flags);
+        if (r < 0)
+                return r;
+
+        sd_rtnl_message_read_u32(m, IFLA_MTU, &l->mtu);
+
+        if (sd_rtnl_message_read_string(m, IFLA_IFNAME, &n) >= 0) {
+                strncpy(l->name, n, sizeof(l->name)-1);
+                char_array_0(l->name);
+        }
+
+        link_allocate_scopes(l);
+        link_add_rrs(l, false);
+
+        return 0;
+}
+
+static int link_update_dns_servers(Link *l) {
+        _cleanup_strv_free_ char **nameservers = NULL;
+        char **nameserver;
+        DnsServer *s, *nx;
+        int r;
+
+        assert(l);
+
+        r = sd_network_link_get_dns(l->ifindex, &nameservers);
+        if (r < 0)
+                goto clear;
+
+        LIST_FOREACH(servers, s, l->dns_servers)
+                s->marked = true;
+
+        STRV_FOREACH(nameserver, nameservers) {
+                union in_addr_union a;
+                int family;
+
+                r = in_addr_from_string_auto(*nameserver, &family, &a);
+                if (r < 0)
+                        goto clear;
+
+                s = link_find_dns_server(l, family, &a);
+                if (s)
+                        s->marked = false;
+                else {
+                        r = dns_server_new(l->manager, NULL, DNS_SERVER_LINK, l, family, &a);
+                        if (r < 0)
+                                goto clear;
+                }
+        }
+
+        LIST_FOREACH_SAFE(servers, s, nx, l->dns_servers)
+                if (s->marked)
+                        dns_server_free(s);
+
+        return 0;
+
+clear:
+        while (l->dns_servers)
+                dns_server_free(l->dns_servers);
+
+        return r;
+}
+
+static int link_update_llmnr_support(Link *l) {
+        _cleanup_free_ char *b = NULL;
+        int r;
+
+        assert(l);
+
+        r = sd_network_link_get_llmnr(l->ifindex, &b);
+        if (r < 0)
+                goto clear;
+
+        r = parse_boolean(b);
+        if (r < 0) {
+                if (streq(b, "resolve"))
+                        l->llmnr_support = SUPPORT_RESOLVE;
+                else
+                        goto clear;
+
+        } else if (r > 0)
+                l->llmnr_support = SUPPORT_YES;
+        else
+                l->llmnr_support = SUPPORT_NO;
+
+        return 0;
+
+clear:
+        l->llmnr_support = SUPPORT_YES;
+        return r;
+}
+
+static int link_update_domains(Link *l) {
+        int r;
+
+        if (!l->unicast_scope)
+                return 0;
+
+        strv_free(l->unicast_scope->domains);
+        l->unicast_scope->domains = NULL;
+
+        r = sd_network_link_get_domains(l->ifindex,
+                                        &l->unicast_scope->domains);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+int link_update_monitor(Link *l) {
+        assert(l);
+
+        link_update_dns_servers(l);
+        link_update_llmnr_support(l);
+        link_allocate_scopes(l);
+        link_update_domains(l);
+        link_add_rrs(l, false);
+
+        return 0;
+}
+
+bool link_relevant(Link *l, int family) {
+        _cleanup_free_ char *state = NULL;
+        LinkAddress *a;
+
+        assert(l);
+
+        /* A link is relevant if it isn't a loopback or pointopoint
+         * device, has a link beat, can do multicast and has at least
+         * one relevant IP address */
+
+        if (l->flags & (IFF_LOOPBACK|IFF_POINTOPOINT|IFF_DORMANT))
+                return false;
+
+        if ((l->flags & (IFF_UP|IFF_LOWER_UP|IFF_MULTICAST)) != (IFF_UP|IFF_LOWER_UP|IFF_MULTICAST))
+                return false;
+
+        sd_network_link_get_operational_state(l->ifindex, &state);
+        if (state && !STR_IN_SET(state, "unknown", "degraded", "routable"))
+                return false;
+
+        LIST_FOREACH(addresses, a, l->addresses)
+                if (a->family == family && link_address_relevant(a))
+                        return true;
+
+        return false;
+}
+
+LinkAddress *link_find_address(Link *l, int family, const union in_addr_union *in_addr) {
+        LinkAddress *a;
+
+        assert(l);
+
+        LIST_FOREACH(addresses, a, l->addresses)
+                if (a->family == family && in_addr_equal(family, &a->in_addr, in_addr))
+                        return a;
+
+        return NULL;
+}
+
+DnsServer* link_find_dns_server(Link *l, int family, const union in_addr_union *in_addr) {
+        DnsServer *s;
+
+        assert(l);
+
+        LIST_FOREACH(servers, s, l->dns_servers)
+                if (s->family == family && in_addr_equal(family, &s->address, in_addr))
+                        return s;
+        return NULL;
+}
+
+DnsServer* link_set_dns_server(Link *l, DnsServer *s) {
+        assert(l);
+
+        if (l->current_dns_server == s)
+                return s;
+
+        if (s) {
+                _cleanup_free_ char *ip = NULL;
+
+                in_addr_to_string(s->family, &s->address, &ip);
+                log_info("Switching to DNS server %s for interface %s.", strna(ip), l->name);
+        }
+
+        l->current_dns_server = s;
+
+        if (l->unicast_scope)
+                dns_cache_flush(&l->unicast_scope->cache);
+
+        return s;
+}
+
+DnsServer *link_get_dns_server(Link *l) {
+        assert(l);
+
+        if (!l->current_dns_server)
+                link_set_dns_server(l, l->dns_servers);
+
+        return l->current_dns_server;
+}
+
+void link_next_dns_server(Link *l) {
+        assert(l);
+
+        if (!l->current_dns_server)
+                return;
+
+        if (l->current_dns_server->servers_next) {
+                link_set_dns_server(l, l->current_dns_server->servers_next);
+                return;
+        }
+
+        link_set_dns_server(l, l->dns_servers);
+}
+
+int link_address_new(Link *l, LinkAddress **ret, int family, const union in_addr_union *in_addr) {
+        LinkAddress *a;
+
+        assert(l);
+        assert(in_addr);
+
+        a = new0(LinkAddress, 1);
+        if (!a)
+                return -ENOMEM;
+
+        a->family = family;
+        a->in_addr = *in_addr;
+
+        a->link = l;
+        LIST_PREPEND(addresses, l->addresses, a);
+
+        if (ret)
+                *ret = a;
+
+        return 0;
+}
+
+LinkAddress *link_address_free(LinkAddress *a) {
+        if (!a)
+                return NULL;
+
+        if (a->link) {
+                LIST_REMOVE(addresses, a->link->addresses, a);
+
+                if (a->llmnr_address_rr) {
+                        if (a->family == AF_INET && a->link->llmnr_ipv4_scope)
+                                dns_zone_remove_rr(&a->link->llmnr_ipv4_scope->zone, a->llmnr_address_rr);
+                        else if (a->family == AF_INET6 && a->link->llmnr_ipv6_scope)
+                                dns_zone_remove_rr(&a->link->llmnr_ipv6_scope->zone, a->llmnr_address_rr);
+                }
+
+                if (a->llmnr_ptr_rr) {
+                        if (a->family == AF_INET && a->link->llmnr_ipv4_scope)
+                                dns_zone_remove_rr(&a->link->llmnr_ipv4_scope->zone, a->llmnr_ptr_rr);
+                        else if (a->family == AF_INET6 && a->link->llmnr_ipv6_scope)
+                                dns_zone_remove_rr(&a->link->llmnr_ipv6_scope->zone, a->llmnr_ptr_rr);
+                }
+        }
+
+        dns_resource_record_unref(a->llmnr_address_rr);
+        dns_resource_record_unref(a->llmnr_ptr_rr);
+
+        free(a);
+        return NULL;
+}
+
+void link_address_add_rrs(LinkAddress *a, bool force_remove) {
+        int r;
+
+        assert(a);
+
+        if (a->family == AF_INET) {
+
+                if (!force_remove &&
+                    link_address_relevant(a) &&
+                    a->link->llmnr_ipv4_scope &&
+                    a->link->llmnr_support == SUPPORT_YES &&
+                    a->link->manager->llmnr_support == SUPPORT_YES) {
+
+                        if (!a->link->manager->host_ipv4_key) {
+                                a->link->manager->host_ipv4_key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, a->link->manager->hostname);
+                                if (!a->link->manager->host_ipv4_key) {
+                                        r = -ENOMEM;
+                                        goto fail;
+                                }
+                        }
+
+                        if (!a->llmnr_address_rr) {
+                                a->llmnr_address_rr = dns_resource_record_new(a->link->manager->host_ipv4_key);
+                                if (!a->llmnr_address_rr) {
+                                        r = -ENOMEM;
+                                        goto fail;
+                                }
+
+                                a->llmnr_address_rr->a.in_addr = a->in_addr.in;
+                                a->llmnr_address_rr->ttl = LLMNR_DEFAULT_TTL;
+                        }
+
+                        if (!a->llmnr_ptr_rr) {
+                                r = dns_resource_record_new_reverse(&a->llmnr_ptr_rr, a->family, &a->in_addr, a->link->manager->hostname);
+                                if (r < 0)
+                                        goto fail;
+
+                                a->llmnr_ptr_rr->ttl = LLMNR_DEFAULT_TTL;
+                        }
+
+                        r = dns_zone_put(&a->link->llmnr_ipv4_scope->zone, a->link->llmnr_ipv4_scope, a->llmnr_address_rr, true);
+                        if (r < 0)
+                                log_warning("Failed to add A record to LLMNR zone: %s", strerror(-r));
+
+                        r = dns_zone_put(&a->link->llmnr_ipv4_scope->zone, a->link->llmnr_ipv4_scope, a->llmnr_ptr_rr, false);
+                        if (r < 0)
+                                log_warning("Failed to add IPv6 PTR record to LLMNR zone: %s", strerror(-r));
+                } else {
+                        if (a->llmnr_address_rr) {
+                                if (a->link->llmnr_ipv4_scope)
+                                        dns_zone_remove_rr(&a->link->llmnr_ipv4_scope->zone, a->llmnr_address_rr);
+                                a->llmnr_address_rr = dns_resource_record_unref(a->llmnr_address_rr);
+                        }
+
+                        if (a->llmnr_ptr_rr) {
+                                if (a->link->llmnr_ipv4_scope)
+                                        dns_zone_remove_rr(&a->link->llmnr_ipv4_scope->zone, a->llmnr_ptr_rr);
+                                a->llmnr_ptr_rr = dns_resource_record_unref(a->llmnr_ptr_rr);
+                        }
+                }
+        }
+
+        if (a->family == AF_INET6) {
+
+                if (!force_remove &&
+                    link_address_relevant(a) &&
+                    a->link->llmnr_ipv6_scope &&
+                    a->link->llmnr_support == SUPPORT_YES &&
+                    a->link->manager->llmnr_support == SUPPORT_YES) {
+
+                        if (!a->link->manager->host_ipv6_key) {
+                                a->link->manager->host_ipv6_key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_AAAA, a->link->manager->hostname);
+                                if (!a->link->manager->host_ipv6_key) {
+                                        r = -ENOMEM;
+                                        goto fail;
+                                }
+                        }
+
+                        if (!a->llmnr_address_rr) {
+                                a->llmnr_address_rr = dns_resource_record_new(a->link->manager->host_ipv6_key);
+                                if (!a->llmnr_address_rr) {
+                                        r = -ENOMEM;
+                                        goto fail;
+                                }
+
+                                a->llmnr_address_rr->aaaa.in6_addr = a->in_addr.in6;
+                                a->llmnr_address_rr->ttl = LLMNR_DEFAULT_TTL;
+                        }
+
+                        if (!a->llmnr_ptr_rr) {
+                                r = dns_resource_record_new_reverse(&a->llmnr_ptr_rr, a->family, &a->in_addr, a->link->manager->hostname);
+                                if (r < 0)
+                                        goto fail;
+
+                                a->llmnr_ptr_rr->ttl = LLMNR_DEFAULT_TTL;
+                        }
+
+                        r = dns_zone_put(&a->link->llmnr_ipv6_scope->zone, a->link->llmnr_ipv6_scope, a->llmnr_address_rr, true);
+                        if (r < 0)
+                                log_warning("Failed to add AAAA record to LLMNR zone: %s", strerror(-r));
+
+                        r = dns_zone_put(&a->link->llmnr_ipv6_scope->zone, a->link->llmnr_ipv6_scope, a->llmnr_ptr_rr, false);
+                        if (r < 0)
+                                log_warning("Failed to add IPv6 PTR record to LLMNR zone: %s", strerror(-r));
+                } else {
+                        if (a->llmnr_address_rr) {
+                                if (a->link->llmnr_ipv6_scope)
+                                        dns_zone_remove_rr(&a->link->llmnr_ipv6_scope->zone, a->llmnr_address_rr);
+                                a->llmnr_address_rr = dns_resource_record_unref(a->llmnr_address_rr);
+                        }
+
+                        if (a->llmnr_ptr_rr) {
+                                if (a->link->llmnr_ipv6_scope)
+                                        dns_zone_remove_rr(&a->link->llmnr_ipv6_scope->zone, a->llmnr_ptr_rr);
+                                a->llmnr_ptr_rr = dns_resource_record_unref(a->llmnr_ptr_rr);
+                        }
+                }
+        }
+
+        return;
+
+fail:
+        log_debug("Failed to update address RRs: %s", strerror(-r));
+}
+
+int link_address_update_rtnl(LinkAddress *a, sd_rtnl_message *m) {
+        int r;
+        assert(a);
+        assert(m);
+
+        r = sd_rtnl_message_addr_get_flags(m, &a->flags);
+        if (r < 0)
+                return r;
+
+        sd_rtnl_message_addr_get_scope(m, &a->scope);
+
+        link_allocate_scopes(a->link);
+        link_add_rrs(a->link, false);
+
+        return 0;
+}
+
+bool link_address_relevant(LinkAddress *a) {
+        assert(a);
+
+        if (a->flags & (IFA_F_DEPRECATED|IFA_F_TENTATIVE))
+                return false;
+
+        if (IN_SET(a->scope, RT_SCOPE_HOST, RT_SCOPE_NOWHERE))
+                return false;
+
+        return true;
+}
diff --git a/src/resolve/resolved-link.h b/src/resolve/resolved-link.h
new file mode 100644 (file)
index 0000000..4f0702e
--- /dev/null
@@ -0,0 +1,91 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <net/if.h>
+
+#include "in-addr-util.h"
+#include "ratelimit.h"
+
+typedef struct Link Link;
+typedef struct LinkAddress LinkAddress;
+
+#include "resolved-dns-server.h"
+#include "resolved-dns-scope.h"
+#include "resolved-dns-rr.h"
+#include "resolved-manager.h"
+
+struct LinkAddress {
+        Link *link;
+
+        int family;
+        union in_addr_union in_addr;
+
+        unsigned char flags, scope;
+
+        DnsResourceRecord *llmnr_address_rr;
+        DnsResourceRecord *llmnr_ptr_rr;
+
+        LIST_FIELDS(LinkAddress, addresses);
+};
+
+struct Link {
+        Manager *manager;
+
+        int ifindex;
+        unsigned flags;
+
+        LIST_HEAD(LinkAddress, addresses);
+
+        LIST_HEAD(DnsServer, dns_servers);
+        DnsServer *current_dns_server;
+
+        Support llmnr_support;
+
+        DnsScope *unicast_scope;
+        DnsScope *llmnr_ipv4_scope;
+        DnsScope *llmnr_ipv6_scope;
+
+        char name[IF_NAMESIZE];
+        uint32_t mtu;
+};
+
+int link_new(Manager *m, Link **ret, int ifindex);
+Link *link_free(Link *l);
+int link_update_rtnl(Link *l, sd_rtnl_message *m);
+int link_update_monitor(Link *l);
+bool link_relevant(Link *l, int family);
+LinkAddress* link_find_address(Link *l, int family, const union in_addr_union *in_addr);
+void link_add_rrs(Link *l, bool force_remove);
+
+DnsServer* link_set_dns_server(Link *l, DnsServer *s);
+DnsServer* link_find_dns_server(Link *l, int family, const union in_addr_union *in_addr);
+DnsServer* link_get_dns_server(Link *l);
+void link_next_dns_server(Link *l);
+
+int link_address_new(Link *l, LinkAddress **ret, int family, const union in_addr_union *in_addr);
+LinkAddress *link_address_free(LinkAddress *a);
+int link_address_update_rtnl(LinkAddress *a, sd_rtnl_message *m);
+bool link_address_relevant(LinkAddress *l);
+void link_address_add_rrs(LinkAddress *a, bool force_remove);
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(Link*, link_free);
diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c
new file mode 100644 (file)
index 0000000..04ee204
--- /dev/null
@@ -0,0 +1,1844 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Tom Gundersen <teg@jklm.no>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+ ***/
+
+#include <arpa/inet.h>
+#include <resolv.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+#include <sys/poll.h>
+#include <netinet/in.h>
+
+#include "rtnl-util.h"
+#include "event-util.h"
+#include "network-util.h"
+#include "network-internal.h"
+#include "conf-parser.h"
+#include "socket-util.h"
+#include "af-list.h"
+#include "utf8.h"
+
+#include "resolved-dns-domain.h"
+#include "resolved-conf.h"
+#include "resolved-bus.h"
+#include "resolved-manager.h"
+
+#define SEND_TIMEOUT_USEC (200 * USEC_PER_MSEC)
+
+static int manager_process_link(sd_rtnl *rtnl, sd_rtnl_message *mm, void *userdata) {
+        Manager *m = userdata;
+        uint16_t type;
+        Link *l;
+        int ifindex, r;
+
+        assert(rtnl);
+        assert(m);
+        assert(mm);
+
+        r = sd_rtnl_message_get_type(mm, &type);
+        if (r < 0)
+                goto fail;
+
+        r = sd_rtnl_message_link_get_ifindex(mm, &ifindex);
+        if (r < 0)
+                goto fail;
+
+        l = hashmap_get(m->links, INT_TO_PTR(ifindex));
+
+        switch (type) {
+
+        case RTM_NEWLINK:{
+                bool is_new = !l;
+
+                if (!l) {
+                        r = link_new(m, &l, ifindex);
+                        if (r < 0)
+                                goto fail;
+                }
+
+                r = link_update_rtnl(l, mm);
+                if (r < 0)
+                        goto fail;
+
+                r = link_update_monitor(l);
+                if (r < 0)
+                        goto fail;
+
+                if (is_new)
+                        log_debug("Found new link %i/%s", ifindex, l->name);
+
+                break;
+        }
+
+        case RTM_DELLINK:
+                if (l) {
+                        log_debug("Removing link %i/%s", l->ifindex, l->name);
+                        link_free(l);
+                }
+
+                break;
+        }
+
+        return 0;
+
+fail:
+        log_warning("Failed to process RTNL link message: %s", strerror(-r));
+        return 0;
+}
+
+static int manager_process_address(sd_rtnl *rtnl, sd_rtnl_message *mm, void *userdata) {
+        Manager *m = userdata;
+        union in_addr_union address;
+        uint16_t type;
+        int r, ifindex, family;
+        LinkAddress *a;
+        Link *l;
+
+        assert(rtnl);
+        assert(mm);
+        assert(m);
+
+        r = sd_rtnl_message_get_type(mm, &type);
+        if (r < 0)
+                goto fail;
+
+        r = sd_rtnl_message_addr_get_ifindex(mm, &ifindex);
+        if (r < 0)
+                goto fail;
+
+        l = hashmap_get(m->links, INT_TO_PTR(ifindex));
+        if (!l)
+                return 0;
+
+        r = sd_rtnl_message_addr_get_family(mm, &family);
+        if (r < 0)
+                goto fail;
+
+        switch (family) {
+
+        case AF_INET:
+                r = sd_rtnl_message_read_in_addr(mm, IFA_LOCAL, &address.in);
+                if (r < 0) {
+                        r = sd_rtnl_message_read_in_addr(mm, IFA_ADDRESS, &address.in);
+                        if (r < 0)
+                                goto fail;
+                }
+
+                break;
+
+        case AF_INET6:
+                r = sd_rtnl_message_read_in6_addr(mm, IFA_LOCAL, &address.in6);
+                if (r < 0) {
+                        r = sd_rtnl_message_read_in6_addr(mm, IFA_ADDRESS, &address.in6);
+                        if (r < 0)
+                                goto fail;
+                }
+
+                break;
+
+        default:
+                return 0;
+        }
+
+        a = link_find_address(l, family, &address);
+
+        switch (type) {
+
+        case RTM_NEWADDR:
+
+                if (!a) {
+                        r = link_address_new(l, &a, family, &address);
+                        if (r < 0)
+                                return r;
+                }
+
+                r = link_address_update_rtnl(a, mm);
+                if (r < 0)
+                        return r;
+
+                break;
+
+        case RTM_DELADDR:
+                if (a)
+                        link_address_free(a);
+                break;
+        }
+
+        return 0;
+
+fail:
+        log_warning("Failed to process RTNL address message: %s", strerror(-r));
+        return 0;
+}
+
+static int manager_rtnl_listen(Manager *m) {
+        _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
+        sd_rtnl_message *i;
+        int r;
+
+        assert(m);
+
+        /* First, subscibe to interfaces coming and going */
+        r = sd_rtnl_open(&m->rtnl, 3, RTNLGRP_LINK, RTNLGRP_IPV4_IFADDR, RTNLGRP_IPV6_IFADDR);
+        if (r < 0)
+                return r;
+
+        r = sd_rtnl_attach_event(m->rtnl, m->event, 0);
+        if (r < 0)
+                return r;
+
+        r = sd_rtnl_add_match(m->rtnl, RTM_NEWLINK, manager_process_link, m);
+        if (r < 0)
+                return r;
+
+        r = sd_rtnl_add_match(m->rtnl, RTM_DELLINK, manager_process_link, m);
+        if (r < 0)
+                return r;
+
+        r = sd_rtnl_add_match(m->rtnl, RTM_NEWADDR, manager_process_address, m);
+        if (r < 0)
+                return r;
+
+        r = sd_rtnl_add_match(m->rtnl, RTM_DELADDR, manager_process_address, m);
+        if (r < 0)
+                return r;
+
+        /* Then, enumerate all links */
+        r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
+        if (r < 0)
+                return r;
+
+        r = sd_rtnl_message_request_dump(req, true);
+        if (r < 0)
+                return r;
+
+        r = sd_rtnl_call(m->rtnl, req, 0, &reply);
+        if (r < 0)
+                return r;
+
+        for (i = reply; i; i = sd_rtnl_message_next(i)) {
+                r = manager_process_link(m->rtnl, i, m);
+                if (r < 0)
+                        return r;
+        }
+
+        req = sd_rtnl_message_unref(req);
+        reply = sd_rtnl_message_unref(reply);
+
+        /* Finally, enumerate all addresses, too */
+        r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, 0, AF_UNSPEC);
+        if (r < 0)
+                return r;
+
+        r = sd_rtnl_message_request_dump(req, true);
+        if (r < 0)
+                return r;
+
+        r = sd_rtnl_call(m->rtnl, req, 0, &reply);
+        if (r < 0)
+                return r;
+
+        for (i = reply; i; i = sd_rtnl_message_next(i)) {
+                r = manager_process_address(m->rtnl, i, m);
+                if (r < 0)
+                        return r;
+        }
+
+        return r;
+}
+
+static int on_network_event(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
+        Manager *m = userdata;
+        Iterator i;
+        Link *l;
+        int r;
+
+        assert(m);
+
+        sd_network_monitor_flush(m->network_monitor);
+
+        HASHMAP_FOREACH(l, m->links, i) {
+                r = link_update_monitor(l);
+                if (r < 0)
+                        log_warning("Failed to update monitor information for %i: %s", l->ifindex, strerror(-r));
+        }
+
+        r = manager_write_resolv_conf(m);
+        if (r < 0)
+                log_warning("Could not update resolv.conf: %s", strerror(-r));
+
+        return 0;
+}
+
+static int manager_network_monitor_listen(Manager *m) {
+        int r, fd, events;
+
+        assert(m);
+
+        r = sd_network_monitor_new(&m->network_monitor, NULL);
+        if (r < 0)
+                return r;
+
+        fd = sd_network_monitor_get_fd(m->network_monitor);
+        if (fd < 0)
+                return fd;
+
+        events = sd_network_monitor_get_events(m->network_monitor);
+        if (events < 0)
+                return events;
+
+        r = sd_event_add_io(m->event, &m->network_event_source, fd, events, &on_network_event, m);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+static int determine_hostname(char **ret) {
+        _cleanup_free_ char *h = NULL, *n = NULL;
+        int r;
+
+        assert(ret);
+
+        h = gethostname_malloc();
+        if (!h)
+                return log_oom();
+
+        if (!utf8_is_valid(h)) {
+                log_error("System hostname is not UTF-8 clean.");
+                return -EINVAL;
+        }
+
+        r = dns_name_normalize(h, &n);
+        if (r < 0) {
+                log_error("System hostname '%s' cannot be normalized.", h);
+                return r;
+        }
+
+        *ret = n;
+        n = NULL;
+
+        return 0;
+}
+
+static int on_hostname_change(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
+        _cleanup_free_ char *h = NULL;
+        Manager *m = userdata;
+        int r;
+
+        assert(m);
+
+        r = determine_hostname(&h);
+        if (r < 0)
+                return 0; /* ignore invalid hostnames */
+
+        if (streq(h, m->hostname))
+                return 0;
+
+        log_info("System hostname changed to '%s'.", h);
+        free(m->hostname);
+        m->hostname = h;
+        h = NULL;
+
+        manager_refresh_rrs(m);
+
+        return 0;
+}
+
+static int manager_watch_hostname(Manager *m) {
+        int r;
+
+        assert(m);
+
+        m->hostname_fd = open("/proc/sys/kernel/hostname", O_RDONLY|O_CLOEXEC|O_NDELAY|O_NOCTTY);
+        if (m->hostname_fd < 0) {
+                log_warning("Failed to watch hostname: %m");
+                return 0;
+        }
+
+        r = sd_event_add_io(m->event, &m->hostname_event_source, m->hostname_fd, 0, on_hostname_change, m);
+        if (r < 0) {
+                if (r == -EPERM)
+                        /* kernels prior to 3.2 don't support polling this file. Ignore the failure. */
+                        m->hostname_fd = safe_close(m->hostname_fd);
+                else {
+                        log_error("Failed to add hostname event source: %s", strerror(-r));
+                        return r;
+                }
+        }
+
+        r = determine_hostname(&m->hostname);
+        if (r < 0) {
+                log_info("Defaulting to hostname 'linux'.");
+                m->hostname = strdup("linux");
+                if (!m->hostname)
+                        return log_oom();
+        } else
+                log_info("Using system hostname '%s'.", m->hostname);
+
+        return 0;
+}
+
+static void manager_llmnr_stop(Manager *m) {
+        assert(m);
+
+        m->llmnr_ipv4_udp_event_source = sd_event_source_unref(m->llmnr_ipv4_udp_event_source);
+        m->llmnr_ipv4_udp_fd = safe_close(m->llmnr_ipv4_udp_fd);
+
+        m->llmnr_ipv6_udp_event_source = sd_event_source_unref(m->llmnr_ipv6_udp_event_source);
+        m->llmnr_ipv6_udp_fd = safe_close(m->llmnr_ipv6_udp_fd);
+
+        m->llmnr_ipv4_tcp_event_source = sd_event_source_unref(m->llmnr_ipv4_tcp_event_source);
+        m->llmnr_ipv4_tcp_fd = safe_close(m->llmnr_ipv4_tcp_fd);
+
+        m->llmnr_ipv6_tcp_event_source = sd_event_source_unref(m->llmnr_ipv6_tcp_event_source);
+        m->llmnr_ipv6_tcp_fd = safe_close(m->llmnr_ipv6_tcp_fd);
+}
+
+static int manager_llmnr_start(Manager *m) {
+        int r;
+
+        assert(m);
+
+        if (m->llmnr_support == SUPPORT_NO)
+                return 0;
+
+        r = manager_llmnr_ipv4_udp_fd(m);
+        if (r == -EADDRINUSE)
+                goto eaddrinuse;
+        if (r < 0)
+                return r;
+
+        r = manager_llmnr_ipv4_tcp_fd(m);
+        if (r == -EADDRINUSE)
+                goto eaddrinuse;
+        if (r < 0)
+                return r;
+
+        if (socket_ipv6_is_supported()) {
+                r = manager_llmnr_ipv6_udp_fd(m);
+                if (r == -EADDRINUSE)
+                        goto eaddrinuse;
+                if (r < 0)
+                        return r;
+
+                r = manager_llmnr_ipv6_tcp_fd(m);
+                if (r == -EADDRINUSE)
+                        goto eaddrinuse;
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+
+eaddrinuse:
+        log_warning("There appears to be another LLMNR respondering running. Turning off LLMNR support.");
+        m->llmnr_support = SUPPORT_NO;
+        manager_llmnr_stop(m);
+
+        return 0;
+}
+
+int manager_new(Manager **ret) {
+        _cleanup_(manager_freep) Manager *m = NULL;
+        int r;
+
+        assert(ret);
+
+        m = new0(Manager, 1);
+        if (!m)
+                return -ENOMEM;
+
+        m->dns_ipv4_fd = m->dns_ipv6_fd = -1;
+        m->llmnr_ipv4_udp_fd = m->llmnr_ipv6_udp_fd = -1;
+        m->llmnr_ipv4_tcp_fd = m->llmnr_ipv6_tcp_fd = -1;
+        m->hostname_fd = -1;
+
+        m->llmnr_support = SUPPORT_YES;
+        m->read_resolv_conf = true;
+
+        r = manager_parse_dns_server(m, DNS_SERVER_FALLBACK, DNS_SERVERS);
+        if (r < 0)
+                return r;
+
+        r = sd_event_default(&m->event);
+        if (r < 0)
+                return r;
+
+        sd_event_add_signal(m->event, NULL, SIGTERM, NULL,  NULL);
+        sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
+
+        sd_event_set_watchdog(m->event, true);
+
+        r = manager_watch_hostname(m);
+        if (r < 0)
+                return r;
+
+        r = dns_scope_new(m, &m->unicast_scope, NULL, DNS_PROTOCOL_DNS, AF_UNSPEC);
+        if (r < 0)
+                return r;
+
+        r = manager_network_monitor_listen(m);
+        if (r < 0)
+                return r;
+
+        r = manager_rtnl_listen(m);
+        if (r < 0)
+                return r;
+
+        r = manager_connect_bus(m);
+        if (r < 0)
+                return r;
+
+        *ret = m;
+        m = NULL;
+
+        return 0;
+}
+
+int manager_start(Manager *m) {
+        int r;
+
+        assert(m);
+
+        r = manager_llmnr_start(m);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+Manager *manager_free(Manager *m) {
+        Link *l;
+
+        if (!m)
+                return NULL;
+
+        while ((l = hashmap_first(m->links)))
+               link_free(l);
+
+        while (m->dns_queries)
+                dns_query_free(m->dns_queries);
+
+        dns_scope_free(m->unicast_scope);
+
+        manager_flush_dns_servers(m, DNS_SERVER_SYSTEM);
+        manager_flush_dns_servers(m, DNS_SERVER_FALLBACK);
+
+        hashmap_free(m->links);
+        hashmap_free(m->dns_transactions);
+
+        sd_event_source_unref(m->network_event_source);
+        sd_network_monitor_unref(m->network_monitor);
+
+        sd_event_source_unref(m->dns_ipv4_event_source);
+        sd_event_source_unref(m->dns_ipv6_event_source);
+        safe_close(m->dns_ipv4_fd);
+        safe_close(m->dns_ipv6_fd);
+
+        manager_llmnr_stop(m);
+
+        sd_bus_slot_unref(m->prepare_for_sleep_slot);
+        sd_event_source_unref(m->bus_retry_event_source);
+        sd_bus_unref(m->bus);
+
+        sd_event_unref(m->event);
+
+        dns_resource_key_unref(m->host_ipv4_key);
+        dns_resource_key_unref(m->host_ipv6_key);
+
+        safe_close(m->hostname_fd);
+        sd_event_source_unref(m->hostname_event_source);
+        free(m->hostname);
+
+        free(m);
+
+        return NULL;
+}
+
+int manager_read_resolv_conf(Manager *m) {
+        _cleanup_fclose_ FILE *f = NULL;
+        struct stat st, own;
+        char line[LINE_MAX];
+        DnsServer *s, *nx;
+        usec_t t;
+        int r;
+
+        assert(m);
+
+        /* Reads the system /etc/resolv.conf, if it exists and is not
+         * symlinked to our own resolv.conf instance */
+
+        if (!m->read_resolv_conf)
+                return 0;
+
+        r = stat("/etc/resolv.conf", &st);
+        if (r < 0) {
+                if (errno != ENOENT)
+                        log_warning("Failed to open /etc/resolv.conf: %m");
+                r = -errno;
+                goto clear;
+        }
+
+        /* Have we already seen the file? */
+        t = timespec_load(&st.st_mtim);
+        if (t == m->resolv_conf_mtime)
+                return 0;
+
+        m->resolv_conf_mtime = t;
+
+        /* Is it symlinked to our own file? */
+        if (stat("/run/systemd/resolve/resolv.conf", &own) >= 0 &&
+            st.st_dev == own.st_dev &&
+            st.st_ino == own.st_ino) {
+                r = 0;
+                goto clear;
+        }
+
+        f = fopen("/etc/resolv.conf", "re");
+        if (!f) {
+                if (errno != ENOENT)
+                        log_warning("Failed to open /etc/resolv.conf: %m");
+                r = -errno;
+                goto clear;
+        }
+
+        if (fstat(fileno(f), &st) < 0) {
+                log_error("Failed to stat open file: %m");
+                r = -errno;
+                goto clear;
+        }
+
+        LIST_FOREACH(servers, s, m->dns_servers)
+                s->marked = true;
+
+        FOREACH_LINE(line, f, r = -errno; goto clear) {
+                union in_addr_union address;
+                int family;
+                char *l;
+                const char *a;
+
+                truncate_nl(line);
+
+                l = strstrip(line);
+                if (*l == '#' || *l == ';')
+                        continue;
+
+                a = first_word(l, "nameserver");
+                if (!a)
+                        continue;
+
+                r = in_addr_from_string_auto(a, &family, &address);
+                if (r < 0) {
+                        log_warning("Failed to parse name server %s.", a);
+                        continue;
+                }
+
+                LIST_FOREACH(servers, s, m->dns_servers)
+                        if (s->family == family && in_addr_equal(family, &s->address, &address) > 0)
+                                break;
+
+                if (s)
+                        s->marked = false;
+                else {
+                        r = dns_server_new(m, NULL, DNS_SERVER_SYSTEM, NULL, family, &address);
+                        if (r < 0)
+                                goto clear;
+                }
+        }
+
+        LIST_FOREACH_SAFE(servers, s, nx, m->dns_servers)
+                if (s->marked)
+                        dns_server_free(s);
+
+        return 0;
+
+clear:
+        while (m->dns_servers)
+                dns_server_free(m->dns_servers);
+
+        return r;
+}
+
+static void write_resolv_conf_server(DnsServer *s, FILE *f, unsigned *count) {
+        _cleanup_free_ char *t  = NULL;
+        int r;
+
+        assert(s);
+        assert(f);
+        assert(count);
+
+        r = in_addr_to_string(s->family, &s->address, &t);
+        if (r < 0) {
+                log_warning("Invalid DNS address. Ignoring: %s", strerror(-r));
+                return;
+        }
+
+        if (*count == MAXNS)
+                fputs("# Too many DNS servers configured, the following entries may be ignored.\n", f);
+
+        fprintf(f, "nameserver %s\n", t);
+        (*count) ++;
+}
+
+static void write_resolv_conf_search(const char *domain, FILE *f,
+                                     unsigned *length, unsigned *count) {
+        assert(domain);
+        assert(f);
+        assert(length);
+
+        if (*count >= MAXDNSRCH ||
+            *length + strlen(domain) > 256) {
+                if (*count == MAXDNSRCH)
+                        fputs(" # Too many search domains configured, remaining ones ignored.", f);
+                if (*length <= 256)
+                        fputs(" # Total length of all search domains is too long, remaining ones ignored.", f);
+
+                return;
+        }
+
+        fprintf(f, " %s", domain);
+
+        (*length) += strlen(domain);
+        (*count) ++;
+}
+
+int manager_write_resolv_conf(Manager *m) {
+        static const char path[] = "/run/systemd/resolve/resolv.conf";
+        _cleanup_free_ char *temp_path = NULL;
+        _cleanup_fclose_ FILE *f = NULL;
+        _cleanup_set_free_ Set *dns = NULL, *domains = NULL;
+        unsigned count = 0;
+        DnsServer *s;
+        Iterator i;
+        Link *l;
+        int r;
+
+        assert(m);
+
+        /* Read the system /etc/resolv.conf first */
+        manager_read_resolv_conf(m);
+
+        /* Add the full list to a set, to filter out duplicates */
+        dns = set_new(dns_server_hash_func, dns_server_compare_func);
+        if (!dns)
+                return -ENOMEM;
+
+        domains = set_new(dns_name_hash_func, dns_name_compare_func);
+        if (!domains)
+                return -ENOMEM;
+
+        /* First add the system-wide servers */
+        LIST_FOREACH(servers, s, m->dns_servers) {
+                r = set_put(dns, s);
+                if (r == -EEXIST)
+                        continue;
+                if (r < 0)
+                        return r;
+        }
+
+        /* Then, add the per-link servers and domains */
+        HASHMAP_FOREACH(l, m->links, i) {
+                char **domain;
+
+                LIST_FOREACH(servers, s, l->dns_servers) {
+                        r = set_put(dns, s);
+                        if (r == -EEXIST)
+                                continue;
+                        if (r < 0)
+                                return r;
+                }
+
+                if (!l->unicast_scope)
+                        continue;
+
+                STRV_FOREACH(domain, l->unicast_scope->domains) {
+                        r = set_put(domains, *domain);
+                        if (r == -EEXIST)
+                                continue;
+                        if (r < 0)
+                                return r;
+                }
+        }
+
+        /* If we found nothing, add the fallback servers */
+        if (set_isempty(dns)) {
+                LIST_FOREACH(servers, s, m->fallback_dns_servers) {
+                        r = set_put(dns, s);
+                        if (r == -EEXIST)
+                                continue;
+                        if (r < 0)
+                                return r;
+                }
+        }
+
+        r = fopen_temporary(path, &f, &temp_path);
+        if (r < 0)
+                return r;
+
+        fchmod(fileno(f), 0644);
+
+        fputs("# This file is managed by systemd-resolved(8). Do not edit.\n#\n"
+              "# Third party programs must not access this file directly, but\n"
+              "# only through the symlink at /etc/resolv.conf. To manage\n"
+              "# resolv.conf(5) in a different way, replace the symlink by a\n"
+              "# static file or a different symlink.\n\n", f);
+
+        if (set_isempty(dns))
+                fputs("# No DNS servers known.\n", f);
+        else {
+                SET_FOREACH(s, dns, i)
+                        write_resolv_conf_server(s, f, &count);
+        }
+
+        if (!set_isempty(domains)) {
+                unsigned length = 0;
+                char *domain;
+
+                count = 0;
+
+                fputs("search", f);
+                SET_FOREACH(domain, domains, i)
+                        write_resolv_conf_search(domain, f, &count, &length);
+                fputs("\n", f);
+        }
+
+        r = fflush_and_check(f);
+        if (r < 0)
+                goto fail;
+
+        if (rename(temp_path, path) < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        return 0;
+
+fail:
+        unlink(path);
+        unlink(temp_path);
+        return r;
+}
+
+int manager_recv(Manager *m, int fd, DnsProtocol protocol, DnsPacket **ret) {
+        _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
+        union {
+                struct cmsghdr header; /* For alignment */
+                uint8_t buffer[CMSG_SPACE(CONST_MAX(sizeof(struct in_pktinfo), sizeof(struct in6_pktinfo)))
+                               + CMSG_SPACE(int) /* ttl/hoplimit */
+                               + EXTRA_CMSG_SPACE /* kernel appears to require extra buffer space */];
+        } control;
+        union sockaddr_union sa;
+        struct msghdr mh = {};
+        struct cmsghdr *cmsg;
+        struct iovec iov;
+        int ms = 0, r;
+        ssize_t l;
+
+        assert(m);
+        assert(fd >= 0);
+        assert(ret);
+
+        r = ioctl(fd, FIONREAD, &ms);
+        if (r < 0)
+                return -errno;
+        if (ms < 0)
+                return -EIO;
+
+        r = dns_packet_new(&p, protocol, ms);
+        if (r < 0)
+                return r;
+
+        iov.iov_base = DNS_PACKET_DATA(p);
+        iov.iov_len = p->allocated;
+
+        mh.msg_name = &sa.sa;
+        mh.msg_namelen = sizeof(sa);
+        mh.msg_iov = &iov;
+        mh.msg_iovlen = 1;
+        mh.msg_control = &control;
+        mh.msg_controllen = sizeof(control);
+
+        l = recvmsg(fd, &mh, 0);
+        if (l < 0) {
+                if (errno == EAGAIN || errno == EINTR)
+                        return 0;
+
+                return -errno;
+        }
+
+        if (l <= 0)
+                return -EIO;
+
+        assert(!(mh.msg_flags & MSG_CTRUNC));
+        assert(!(mh.msg_flags & MSG_TRUNC));
+
+        p->size = (size_t) l;
+
+        p->family = sa.sa.sa_family;
+        p->ipproto = IPPROTO_UDP;
+        if (p->family == AF_INET) {
+                p->sender.in = sa.in.sin_addr;
+                p->sender_port = be16toh(sa.in.sin_port);
+        } else if (p->family == AF_INET6) {
+                p->sender.in6 = sa.in6.sin6_addr;
+                p->sender_port = be16toh(sa.in6.sin6_port);
+                p->ifindex = sa.in6.sin6_scope_id;
+        } else
+                return -EAFNOSUPPORT;
+
+        for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg)) {
+
+                if (cmsg->cmsg_level == IPPROTO_IPV6) {
+                        assert(p->family == AF_INET6);
+
+                        switch (cmsg->cmsg_type) {
+
+                        case IPV6_PKTINFO: {
+                                struct in6_pktinfo *i = (struct in6_pktinfo*) CMSG_DATA(cmsg);
+
+                                if (p->ifindex <= 0)
+                                        p->ifindex = i->ipi6_ifindex;
+
+                                p->destination.in6 = i->ipi6_addr;
+                                break;
+                        }
+
+                        case IPV6_HOPLIMIT:
+                                p->ttl = *(int *) CMSG_DATA(cmsg);
+                                break;
+
+                        }
+                } else if (cmsg->cmsg_level == IPPROTO_IP) {
+                        assert(p->family == AF_INET);
+
+                        switch (cmsg->cmsg_type) {
+
+                        case IP_PKTINFO: {
+                                struct in_pktinfo *i = (struct in_pktinfo*) CMSG_DATA(cmsg);
+
+                                if (p->ifindex <= 0)
+                                        p->ifindex = i->ipi_ifindex;
+
+                                p->destination.in = i->ipi_addr;
+                                break;
+                        }
+
+                        case IP_TTL:
+                                p->ttl = *(int *) CMSG_DATA(cmsg);
+                                break;
+                        }
+                }
+        }
+
+        /* The Linux kernel sets the interface index to the loopback
+         * device if the packet came from the local host since it
+         * avoids the routing table in such a case. Let's unset the
+         * interface index in such a case. */
+        if (p->ifindex > 0 && manager_ifindex_is_loopback(m, p->ifindex) != 0)
+                p->ifindex = 0;
+
+        /* If we don't know the interface index still, we look for the
+         * first local interface with a matching address. Yuck! */
+        if (p->ifindex <= 0)
+                p->ifindex = manager_find_ifindex(m, p->family, &p->destination);
+
+        *ret = p;
+        p = NULL;
+
+        return 1;
+}
+
+static int on_dns_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
+        _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
+        DnsTransaction *t = NULL;
+        Manager *m = userdata;
+        int r;
+
+        r = manager_recv(m, fd, DNS_PROTOCOL_DNS, &p);
+        if (r <= 0)
+                return r;
+
+        if (dns_packet_validate_reply(p) > 0) {
+                t = hashmap_get(m->dns_transactions, UINT_TO_PTR(DNS_PACKET_ID(p)));
+                if (!t)
+                        return 0;
+
+                dns_transaction_process_reply(t, p);
+
+        } else
+                log_debug("Invalid DNS packet.");
+
+        return 0;
+}
+
+int manager_dns_ipv4_fd(Manager *m) {
+        const int one = 1;
+        int r;
+
+        assert(m);
+
+        if (m->dns_ipv4_fd >= 0)
+                return m->dns_ipv4_fd;
+
+        m->dns_ipv4_fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
+        if (m->dns_ipv4_fd < 0)
+                return -errno;
+
+        r = setsockopt(m->dns_ipv4_fd, IPPROTO_IP, IP_PKTINFO, &one, sizeof(one));
+        if (r < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        r = sd_event_add_io(m->event, &m->dns_ipv4_event_source, m->dns_ipv4_fd, EPOLLIN, on_dns_packet, m);
+        if (r < 0)
+                goto fail;
+
+        return m->dns_ipv4_fd;
+
+fail:
+        m->dns_ipv4_fd = safe_close(m->dns_ipv4_fd);
+        return r;
+}
+
+int manager_dns_ipv6_fd(Manager *m) {
+        const int one = 1;
+        int r;
+
+        assert(m);
+
+        if (m->dns_ipv6_fd >= 0)
+                return m->dns_ipv6_fd;
+
+        m->dns_ipv6_fd = socket(AF_INET6, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
+        if (m->dns_ipv6_fd < 0)
+                return -errno;
+
+        r = setsockopt(m->dns_ipv6_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one));
+        if (r < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        r = sd_event_add_io(m->event, &m->dns_ipv6_event_source, m->dns_ipv6_fd, EPOLLIN, on_dns_packet, m);
+        if (r < 0)
+                goto fail;
+
+        return m->dns_ipv6_fd;
+
+fail:
+        m->dns_ipv6_fd = safe_close(m->dns_ipv6_fd);
+        return r;
+}
+
+static int sendmsg_loop(int fd, struct msghdr *mh, int flags) {
+        int r;
+
+        assert(fd >= 0);
+        assert(mh);
+
+        for (;;) {
+                if (sendmsg(fd, mh, flags) >= 0)
+                        return 0;
+
+                if (errno == EINTR)
+                        continue;
+
+                if (errno != EAGAIN)
+                        return -errno;
+
+                r = fd_wait_for_event(fd, POLLOUT, SEND_TIMEOUT_USEC);
+                if (r < 0)
+                        return r;
+                if (r == 0)
+                        return -ETIMEDOUT;
+        }
+}
+
+static int manager_ipv4_send(Manager *m, int fd, int ifindex, const struct in_addr *addr, uint16_t port, DnsPacket *p) {
+        union sockaddr_union sa = {
+                .in.sin_family = AF_INET,
+        };
+        union {
+                struct cmsghdr header; /* For alignment */
+                uint8_t buffer[CMSG_SPACE(sizeof(struct in_pktinfo))];
+        } control;
+        struct msghdr mh = {};
+        struct iovec iov;
+
+        assert(m);
+        assert(fd >= 0);
+        assert(addr);
+        assert(port > 0);
+        assert(p);
+
+        iov.iov_base = DNS_PACKET_DATA(p);
+        iov.iov_len = p->size;
+
+        sa.in.sin_addr = *addr;
+        sa.in.sin_port = htobe16(port),
+
+        mh.msg_iov = &iov;
+        mh.msg_iovlen = 1;
+        mh.msg_name = &sa.sa;
+        mh.msg_namelen = sizeof(sa.in);
+
+        if (ifindex > 0) {
+                struct cmsghdr *cmsg;
+                struct in_pktinfo *pi;
+
+                zero(control);
+
+                mh.msg_control = &control;
+                mh.msg_controllen = CMSG_LEN(sizeof(struct in_pktinfo));
+
+                cmsg = CMSG_FIRSTHDR(&mh);
+                cmsg->cmsg_len = mh.msg_controllen;
+                cmsg->cmsg_level = IPPROTO_IP;
+                cmsg->cmsg_type = IP_PKTINFO;
+
+                pi = (struct in_pktinfo*) CMSG_DATA(cmsg);
+                pi->ipi_ifindex = ifindex;
+        }
+
+        return sendmsg_loop(fd, &mh, 0);
+}
+
+static int manager_ipv6_send(Manager *m, int fd, int ifindex, const struct in6_addr *addr, uint16_t port, DnsPacket *p) {
+        union sockaddr_union sa = {
+                .in6.sin6_family = AF_INET6,
+        };
+        union {
+                struct cmsghdr header; /* For alignment */
+                uint8_t buffer[CMSG_SPACE(sizeof(struct in6_pktinfo))];
+        } control;
+        struct msghdr mh = {};
+        struct iovec iov;
+
+        assert(m);
+        assert(fd >= 0);
+        assert(addr);
+        assert(port > 0);
+        assert(p);
+
+        iov.iov_base = DNS_PACKET_DATA(p);
+        iov.iov_len = p->size;
+
+        sa.in6.sin6_addr = *addr;
+        sa.in6.sin6_port = htobe16(port),
+        sa.in6.sin6_scope_id = ifindex;
+
+        mh.msg_iov = &iov;
+        mh.msg_iovlen = 1;
+        mh.msg_name = &sa.sa;
+        mh.msg_namelen = sizeof(sa.in6);
+
+        if (ifindex > 0) {
+                struct cmsghdr *cmsg;
+                struct in6_pktinfo *pi;
+
+                zero(control);
+
+                mh.msg_control = &control;
+                mh.msg_controllen = CMSG_LEN(sizeof(struct in6_pktinfo));
+
+                cmsg = CMSG_FIRSTHDR(&mh);
+                cmsg->cmsg_len = mh.msg_controllen;
+                cmsg->cmsg_level = IPPROTO_IPV6;
+                cmsg->cmsg_type = IPV6_PKTINFO;
+
+                pi = (struct in6_pktinfo*) CMSG_DATA(cmsg);
+                pi->ipi6_ifindex = ifindex;
+        }
+
+        return sendmsg_loop(fd, &mh, 0);
+}
+
+int manager_send(Manager *m, int fd, int ifindex, int family, const union in_addr_union *addr, uint16_t port, DnsPacket *p) {
+        assert(m);
+        assert(fd >= 0);
+        assert(addr);
+        assert(port > 0);
+        assert(p);
+
+        log_debug("Sending %s packet with id %u on interface %i/%s", DNS_PACKET_QR(p) ? "response" : "query", DNS_PACKET_ID(p), ifindex, af_to_name(family));
+
+        if (family == AF_INET)
+                return manager_ipv4_send(m, fd, ifindex, &addr->in, port, p);
+        else if (family == AF_INET6)
+                return manager_ipv6_send(m, fd, ifindex, &addr->in6, port, p);
+
+        return -EAFNOSUPPORT;
+}
+
+DnsServer* manager_find_dns_server(Manager *m, int family, const union in_addr_union *in_addr) {
+        DnsServer *s;
+
+        assert(m);
+        assert(in_addr);
+
+        LIST_FOREACH(servers, s, m->dns_servers)
+                if (s->family == family && in_addr_equal(family, &s->address, in_addr) > 0)
+                        return s;
+
+        LIST_FOREACH(servers, s, m->fallback_dns_servers)
+                if (s->family == family && in_addr_equal(family, &s->address, in_addr) > 0)
+                        return s;
+
+        return NULL;
+}
+
+DnsServer *manager_set_dns_server(Manager *m, DnsServer *s) {
+        assert(m);
+
+        if (m->current_dns_server == s)
+                return s;
+
+        if (s) {
+                _cleanup_free_ char *ip = NULL;
+
+                in_addr_to_string(s->family, &s->address, &ip);
+                log_info("Switching to system DNS server %s.", strna(ip));
+        }
+
+        m->current_dns_server = s;
+
+        if (m->unicast_scope)
+                dns_cache_flush(&m->unicast_scope->cache);
+
+        return s;
+}
+
+DnsServer *manager_get_dns_server(Manager *m) {
+        Link *l;
+        assert(m);
+
+        /* Try to read updates resolv.conf */
+        manager_read_resolv_conf(m);
+
+        if (!m->current_dns_server)
+                manager_set_dns_server(m, m->dns_servers);
+
+        if (!m->current_dns_server) {
+                bool found = false;
+                Iterator i;
+
+                /* No DNS servers configured, let's see if there are
+                 * any on any links. If not, we use the fallback
+                 * servers */
+
+                HASHMAP_FOREACH(l, m->links, i)
+                        if (l->dns_servers) {
+                                found = true;
+                                break;
+                        }
+
+                if (!found)
+                        manager_set_dns_server(m, m->fallback_dns_servers);
+        }
+
+        return m->current_dns_server;
+}
+
+void manager_next_dns_server(Manager *m) {
+        assert(m);
+
+        /* If there's currently no DNS server set, then the next
+         * manager_get_dns_server() will find one */
+        if (!m->current_dns_server)
+                return;
+
+        /* Change to the next one */
+        if (m->current_dns_server->servers_next) {
+                manager_set_dns_server(m, m->current_dns_server->servers_next);
+                return;
+        }
+
+        /* If there was no next one, then start from the beginning of
+         * the list */
+        if (m->current_dns_server->type == DNS_SERVER_FALLBACK)
+                manager_set_dns_server(m, m->fallback_dns_servers);
+        else
+                manager_set_dns_server(m, m->dns_servers);
+}
+
+uint32_t manager_find_mtu(Manager *m) {
+        uint32_t mtu = 0;
+        Link *l;
+        Iterator i;
+
+        /* If we don't know on which link a DNS packet would be
+         * delivered, let's find the largest MTU that works on all
+         * interfaces we know of */
+
+        HASHMAP_FOREACH(l, m->links, i) {
+                if (l->mtu <= 0)
+                        continue;
+
+                if (mtu <= 0 || l->mtu < mtu)
+                        mtu = l->mtu;
+        }
+
+        return mtu;
+}
+
+static int on_llmnr_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
+        _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
+        DnsTransaction *t = NULL;
+        Manager *m = userdata;
+        DnsScope *scope;
+        int r;
+
+        r = manager_recv(m, fd, DNS_PROTOCOL_LLMNR, &p);
+        if (r <= 0)
+                return r;
+
+        scope = manager_find_scope(m, p);
+        if (!scope) {
+                log_warning("Got LLMNR UDP packet on unknown scope. Ignoring.");
+                return 0;
+        }
+
+        if (dns_packet_validate_reply(p) > 0) {
+                log_debug("Got reply packet for id %u", DNS_PACKET_ID(p));
+
+                dns_scope_check_conflicts(scope, p);
+
+                t = hashmap_get(m->dns_transactions, UINT_TO_PTR(DNS_PACKET_ID(p)));
+                if (t)
+                        dns_transaction_process_reply(t, p);
+
+        } else if (dns_packet_validate_query(p) > 0)  {
+                log_debug("Got query packet for id %u", DNS_PACKET_ID(p));
+
+                dns_scope_process_query(scope, NULL, p);
+        } else
+                log_debug("Invalid LLMNR UDP packet.");
+
+        return 0;
+}
+
+int manager_llmnr_ipv4_udp_fd(Manager *m) {
+        union sockaddr_union sa = {
+                .in.sin_family = AF_INET,
+                .in.sin_port = htobe16(5355),
+        };
+        static const int one = 1, pmtu = IP_PMTUDISC_DONT, ttl = 255;
+        int r;
+
+        assert(m);
+
+        if (m->llmnr_ipv4_udp_fd >= 0)
+                return m->llmnr_ipv4_udp_fd;
+
+        m->llmnr_ipv4_udp_fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
+        if (m->llmnr_ipv4_udp_fd < 0)
+                return -errno;
+
+        /* RFC 4795, section 2.5 recommends setting the TTL of UDP packets to 255. */
+        r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));
+        if (r < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl));
+        if (r < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_MULTICAST_LOOP, &one, sizeof(one));
+        if (r < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        r = setsockopt(m->llmnr_ipv4_udp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
+        if (r < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_PKTINFO, &one, sizeof(one));
+        if (r < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_RECVTTL, &one, sizeof(one));
+        if (r < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        /* Disable Don't-Fragment bit in the IP header */
+        r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_MTU_DISCOVER, &pmtu, sizeof(pmtu));
+        if (r < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        r = bind(m->llmnr_ipv4_udp_fd, &sa.sa, sizeof(sa.in));
+        if (r < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        r = sd_event_add_io(m->event, &m->llmnr_ipv4_udp_event_source, m->llmnr_ipv4_udp_fd, EPOLLIN, on_llmnr_packet, m);
+        if (r < 0)
+                goto fail;
+
+        return m->llmnr_ipv4_udp_fd;
+
+fail:
+        m->llmnr_ipv4_udp_fd = safe_close(m->llmnr_ipv4_udp_fd);
+        return r;
+}
+
+int manager_llmnr_ipv6_udp_fd(Manager *m) {
+        union sockaddr_union sa = {
+                .in6.sin6_family = AF_INET6,
+                .in6.sin6_port = htobe16(5355),
+        };
+        static const int one = 1, ttl = 255;
+        int r;
+
+        assert(m);
+
+        if (m->llmnr_ipv6_udp_fd >= 0)
+                return m->llmnr_ipv6_udp_fd;
+
+        m->llmnr_ipv6_udp_fd = socket(AF_INET6, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
+        if (m->llmnr_ipv6_udp_fd < 0)
+                return -errno;
+
+        r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl));
+        if (r < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        /* RFC 4795, section 2.5 recommends setting the TTL of UDP packets to 255. */
+        r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &ttl, sizeof(ttl));
+        if (r < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &one, sizeof(one));
+        if (r < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one));
+        if (r < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        r = setsockopt(m->llmnr_ipv6_udp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
+        if (r < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one));
+        if (r < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &one, sizeof(one));
+        if (r < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        r = bind(m->llmnr_ipv6_udp_fd, &sa.sa, sizeof(sa.in6));
+        if (r < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        r = sd_event_add_io(m->event, &m->llmnr_ipv6_udp_event_source, m->llmnr_ipv6_udp_fd, EPOLLIN, on_llmnr_packet, m);
+        if (r < 0)  {
+                r = -errno;
+                goto fail;
+        }
+
+        return m->llmnr_ipv6_udp_fd;
+
+fail:
+        m->llmnr_ipv6_udp_fd = safe_close(m->llmnr_ipv6_udp_fd);
+        return r;
+}
+
+static int on_llmnr_stream_packet(DnsStream *s) {
+        DnsScope *scope;
+
+        assert(s);
+
+        scope = manager_find_scope(s->manager, s->read_packet);
+        if (!scope) {
+                log_warning("Got LLMNR TCP packet on unknown scope. Ignroing.");
+                return 0;
+        }
+
+        if (dns_packet_validate_query(s->read_packet) > 0) {
+                log_debug("Got query packet for id %u", DNS_PACKET_ID(s->read_packet));
+
+                dns_scope_process_query(scope, s, s->read_packet);
+
+                /* If no reply packet was set, we free the stream */
+                if (s->write_packet)
+                        return 0;
+        } else
+                log_debug("Invalid LLMNR TCP packet.");
+
+        dns_stream_free(s);
+        return 0;
+}
+
+static int on_llmnr_stream(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
+        DnsStream *stream;
+        Manager *m = userdata;
+        int cfd, r;
+
+        cfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
+        if (cfd < 0) {
+                if (errno == EAGAIN || errno == EINTR)
+                        return 0;
+
+                return -errno;
+        }
+
+        r = dns_stream_new(m, &stream, DNS_PROTOCOL_LLMNR, cfd);
+        if (r < 0) {
+                safe_close(cfd);
+                return r;
+        }
+
+        stream->on_packet = on_llmnr_stream_packet;
+        return 0;
+}
+
+int manager_llmnr_ipv4_tcp_fd(Manager *m) {
+        union sockaddr_union sa = {
+                .in.sin_family = AF_INET,
+                .in.sin_port = htobe16(5355),
+        };
+        static const int one = 1, pmtu = IP_PMTUDISC_DONT;
+        int r;
+
+        assert(m);
+
+        if (m->llmnr_ipv4_tcp_fd >= 0)
+                return m->llmnr_ipv4_tcp_fd;
+
+        m->llmnr_ipv4_tcp_fd = socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
+        if (m->llmnr_ipv4_tcp_fd < 0)
+                return -errno;
+
+        /* RFC 4795, section 2.5. requires setting the TTL of TCP streams to 1 */
+        r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_TTL, &one, sizeof(one));
+        if (r < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        r = setsockopt(m->llmnr_ipv4_tcp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
+        if (r < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_PKTINFO, &one, sizeof(one));
+        if (r < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_RECVTTL, &one, sizeof(one));
+        if (r < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        /* Disable Don't-Fragment bit in the IP header */
+        r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_MTU_DISCOVER, &pmtu, sizeof(pmtu));
+        if (r < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        r = bind(m->llmnr_ipv4_tcp_fd, &sa.sa, sizeof(sa.in));
+        if (r < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        r = listen(m->llmnr_ipv4_tcp_fd, SOMAXCONN);
+        if (r < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        r = sd_event_add_io(m->event, &m->llmnr_ipv4_tcp_event_source, m->llmnr_ipv4_tcp_fd, EPOLLIN, on_llmnr_stream, m);
+        if (r < 0)
+                goto fail;
+
+        return m->llmnr_ipv4_tcp_fd;
+
+fail:
+        m->llmnr_ipv4_tcp_fd = safe_close(m->llmnr_ipv4_tcp_fd);
+        return r;
+}
+
+int manager_llmnr_ipv6_tcp_fd(Manager *m) {
+        union sockaddr_union sa = {
+                .in6.sin6_family = AF_INET6,
+                .in6.sin6_port = htobe16(5355),
+        };
+        static const int one = 1;
+        int r;
+
+        assert(m);
+
+        if (m->llmnr_ipv6_tcp_fd >= 0)
+                return m->llmnr_ipv6_tcp_fd;
+
+        m->llmnr_ipv6_tcp_fd = socket(AF_INET6, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
+        if (m->llmnr_ipv6_tcp_fd < 0)
+                return -errno;
+
+        /* RFC 4795, section 2.5. requires setting the TTL of TCP streams to 1 */
+        r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &one, sizeof(one));
+        if (r < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one));
+        if (r < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        r = setsockopt(m->llmnr_ipv6_tcp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
+        if (r < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one));
+        if (r < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &one, sizeof(one));
+        if (r < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        r = bind(m->llmnr_ipv6_tcp_fd, &sa.sa, sizeof(sa.in6));
+        if (r < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        r = listen(m->llmnr_ipv6_tcp_fd, SOMAXCONN);
+        if (r < 0) {
+                r = -errno;
+                goto fail;
+        }
+
+        r = sd_event_add_io(m->event, &m->llmnr_ipv6_tcp_event_source, m->llmnr_ipv6_tcp_fd, EPOLLIN, on_llmnr_stream, m);
+        if (r < 0)  {
+                r = -errno;
+                goto fail;
+        }
+
+        return m->llmnr_ipv6_tcp_fd;
+
+fail:
+        m->llmnr_ipv6_tcp_fd = safe_close(m->llmnr_ipv6_tcp_fd);
+        return r;
+}
+
+int manager_ifindex_is_loopback(Manager *m, int ifindex) {
+        Link *l;
+        assert(m);
+
+        if (ifindex <= 0)
+                return -EINVAL;
+
+        l = hashmap_get(m->links, INT_TO_PTR(ifindex));
+        if (l->flags & IFF_LOOPBACK)
+                return 1;
+
+        return 0;
+}
+
+int manager_find_ifindex(Manager *m, int family, const union in_addr_union *in_addr) {
+        LinkAddress *a;
+
+        assert(m);
+
+        a = manager_find_link_address(m, family, in_addr);
+        if (a)
+                return a->link->ifindex;
+
+        return 0;
+}
+
+void manager_refresh_rrs(Manager *m) {
+        Iterator i;
+        Link *l;
+
+        assert(m);
+
+        m->host_ipv4_key = dns_resource_key_unref(m->host_ipv4_key);
+        m->host_ipv6_key = dns_resource_key_unref(m->host_ipv6_key);
+
+        HASHMAP_FOREACH(l, m->links, i) {
+                link_add_rrs(l, true);
+                link_add_rrs(l, false);
+        }
+}
+
+int manager_next_hostname(Manager *m) {
+        const char *p;
+        uint64_t u, a;
+        char *h;
+
+        assert(m);
+
+        p = strchr(m->hostname, 0);
+        assert(p);
+
+        while (p > m->hostname) {
+                if (!strchr("0123456789", p[-1]))
+                        break;
+
+                p--;
+        }
+
+        if (*p == 0 || safe_atou64(p, &u) < 0 || u <= 0)
+                u = 1;
+
+        /* Add a random number to the old value. This way we can avoid
+         * that two hosts pick the same hostname, win on IPv4 and lose
+         * on IPv6 (or vice versa), and pick the same hostname
+         * replacement hostname, ad infinitum. We still want the
+         * numbers to go up monotonically, hence we just add a random
+         * value 1..10 */
+
+        random_bytes(&a, sizeof(a));
+        u += 1 + a % 10;
+
+        if (asprintf(&h, "%.*s%" PRIu64, (int) (p - m->hostname), m->hostname, u) < 0)
+                return -ENOMEM;
+
+        log_info("Hostname conflict, changing published hostname from '%s' to '%s'.", m->hostname, h);
+
+        free(m->hostname);
+        m->hostname = h;
+
+        manager_refresh_rrs(m);
+
+        return 0;
+}
+
+LinkAddress* manager_find_link_address(Manager *m, int family, const union in_addr_union *in_addr) {
+        Iterator i;
+        Link *l;
+
+        assert(m);
+
+        HASHMAP_FOREACH(l, m->links, i) {
+                LinkAddress *a;
+
+                a = link_find_address(l, family, in_addr);
+                if (a)
+                        return a;
+        }
+
+        return NULL;
+}
+
+bool manager_our_packet(Manager *m, DnsPacket *p) {
+        assert(m);
+        assert(p);
+
+        return !!manager_find_link_address(m, p->family, &p->sender);
+}
+
+DnsScope* manager_find_scope(Manager *m, DnsPacket *p) {
+        Link *l;
+
+        assert(m);
+        assert(p);
+
+        l = hashmap_get(m->links, INT_TO_PTR(p->ifindex));
+        if (!l)
+                return NULL;
+
+        if (p->protocol == DNS_PROTOCOL_LLMNR) {
+                if (p->family == AF_INET)
+                        return l->llmnr_ipv4_scope;
+                else if (p->family == AF_INET6)
+                        return l->llmnr_ipv6_scope;
+        }
+
+        return NULL;
+}
+
+void manager_verify_all(Manager *m) {
+        DnsScope *s;
+
+        assert(m);
+
+        LIST_FOREACH(scopes, s, m->dns_scopes)
+                dns_zone_verify_all(&s->zone);
+}
+
+void manager_flush_dns_servers(Manager *m, DnsServerType t) {
+        assert(m);
+
+        if (t == DNS_SERVER_SYSTEM)
+                while (m->dns_servers)
+                        dns_server_free(m->dns_servers);
+
+        if (t == DNS_SERVER_FALLBACK)
+                while (m->fallback_dns_servers)
+                        dns_server_free(m->fallback_dns_servers);
+}
+
+static const char* const support_table[_SUPPORT_MAX] = {
+        [SUPPORT_NO] = "no",
+        [SUPPORT_YES] = "yes",
+        [SUPPORT_RESOLVE] = "resolve",
+};
+DEFINE_STRING_TABLE_LOOKUP(support, Support);
diff --git a/src/resolve/resolved-manager.h b/src/resolve/resolved-manager.h
new file mode 100644 (file)
index 0000000..78cbfc0
--- /dev/null
@@ -0,0 +1,161 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Tom Gundersen <teg@jklm.no>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "sd-event.h"
+#include "sd-network.h"
+#include "sd-rtnl.h"
+#include "util.h"
+#include "list.h"
+#include "in-addr-util.h"
+#include "hashmap.h"
+
+typedef struct Manager Manager;
+typedef enum Support Support;
+
+enum Support {
+        SUPPORT_NO,
+        SUPPORT_YES,
+        SUPPORT_RESOLVE,
+        _SUPPORT_MAX,
+        _SUPPORT_INVALID = -1
+};
+
+#include "resolved-dns-query.h"
+#include "resolved-dns-server.h"
+#include "resolved-dns-scope.h"
+#include "resolved-dns-stream.h"
+#include "resolved-link.h"
+
+struct Manager {
+        sd_event *event;
+
+        Support llmnr_support;
+
+        /* Network */
+        Hashmap *links;
+
+        sd_rtnl *rtnl;
+        sd_event_source *rtnl_event_source;
+
+        sd_network_monitor *network_monitor;
+        sd_event_source *network_event_source;
+
+        /* DNS query management */
+        Hashmap *dns_transactions;
+        LIST_HEAD(DnsQuery, dns_queries);
+        unsigned n_dns_queries;
+
+        LIST_HEAD(DnsStream, dns_streams);
+        unsigned n_dns_streams;
+
+        /* Unicast dns */
+        int dns_ipv4_fd;
+        int dns_ipv6_fd;
+
+        sd_event_source *dns_ipv4_event_source;
+        sd_event_source *dns_ipv6_event_source;
+
+        LIST_HEAD(DnsServer, dns_servers);
+        LIST_HEAD(DnsServer, fallback_dns_servers);
+        DnsServer *current_dns_server;
+
+        bool read_resolv_conf;
+        usec_t resolv_conf_mtime;
+
+        LIST_HEAD(DnsScope, dns_scopes);
+        DnsScope *unicast_scope;
+
+        /* LLMNR */
+        int llmnr_ipv4_udp_fd;
+        int llmnr_ipv6_udp_fd;
+        int llmnr_ipv4_tcp_fd;
+        int llmnr_ipv6_tcp_fd;
+
+        sd_event_source *llmnr_ipv4_udp_event_source;
+        sd_event_source *llmnr_ipv6_udp_event_source;
+        sd_event_source *llmnr_ipv4_tcp_event_source;
+        sd_event_source *llmnr_ipv6_tcp_event_source;
+
+        /* dbus */
+        sd_bus *bus;
+        sd_event_source *bus_retry_event_source;
+
+        /* The hostname we publish on LLMNR and mDNS */
+        char *hostname;
+        DnsResourceKey *host_ipv4_key;
+        DnsResourceKey *host_ipv6_key;
+
+        /* Watch the system hostname */
+        int hostname_fd;
+        sd_event_source *hostname_event_source;
+
+        /* Watch for system suspends */
+        sd_bus_slot *prepare_for_sleep_slot;
+};
+
+/* Manager */
+
+int manager_new(Manager **ret);
+Manager* manager_free(Manager *m);
+
+int manager_start(Manager *m);
+int manager_read_resolv_conf(Manager *m);
+int manager_write_resolv_conf(Manager *m);
+
+DnsServer *manager_set_dns_server(Manager *m, DnsServer *s);
+DnsServer *manager_find_dns_server(Manager *m, int family, const union in_addr_union *in_addr);
+DnsServer *manager_get_dns_server(Manager *m);
+void manager_next_dns_server(Manager *m);
+
+uint32_t manager_find_mtu(Manager *m);
+
+int manager_send(Manager *m, int fd, int ifindex, int family, const union in_addr_union *addr, uint16_t port, DnsPacket *p);
+int manager_recv(Manager *m, int fd, DnsProtocol protocol, DnsPacket **ret);
+
+int manager_dns_ipv4_fd(Manager *m);
+int manager_dns_ipv6_fd(Manager *m);
+int manager_llmnr_ipv4_udp_fd(Manager *m);
+int manager_llmnr_ipv6_udp_fd(Manager *m);
+int manager_llmnr_ipv4_tcp_fd(Manager *m);
+int manager_llmnr_ipv6_tcp_fd(Manager *m);
+
+int manager_ifindex_is_loopback(Manager *m, int ifindex);
+int manager_find_ifindex(Manager *m, int family, const union in_addr_union *in_addr);
+LinkAddress* manager_find_link_address(Manager *m, int family, const union in_addr_union *in_addr);
+
+void manager_refresh_rrs(Manager *m);
+int manager_next_hostname(Manager *m);
+
+bool manager_our_packet(Manager *m, DnsPacket *p);
+DnsScope* manager_find_scope(Manager *m, DnsPacket *p);
+
+void manager_verify_all(Manager *m);
+
+void manager_flush_dns_servers(Manager *m, DnsServerType t);
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
+
+#define EXTRA_CMSG_SPACE 1024
+
+const char* support_to_string(Support p) _const_;
+int support_from_string(const char *s) _pure_;
diff --git a/src/resolve/resolved.c b/src/resolve/resolved.c
new file mode 100644 (file)
index 0000000..8235558
--- /dev/null
@@ -0,0 +1,106 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Tom Gundersen <teg@jklm.no>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "sd-event.h"
+#include "sd-daemon.h"
+#include "mkdir.h"
+#include "capability.h"
+
+#include "resolved-manager.h"
+#include "resolved-conf.h"
+
+int main(int argc, char *argv[]) {
+        _cleanup_(manager_freep) Manager *m = NULL;
+        const char *user = "systemd-resolve";
+        uid_t uid;
+        gid_t gid;
+        int r;
+
+        log_set_target(LOG_TARGET_AUTO);
+        log_parse_environment();
+        log_open();
+
+        umask(0022);
+
+        if (argc != 1) {
+                log_error("This program takes no arguments.");
+                r = -EINVAL;
+                goto finish;
+        }
+
+        r = get_user_creds(&user, &uid, &gid, NULL, NULL);
+        if (r < 0) {
+                log_error("Cannot resolve user name %s: %s", user, strerror(-r));
+                goto finish;
+        }
+
+        /* Always create the directory where resolv.conf will live */
+        r = mkdir_safe_label("/run/systemd/resolve", 0755, uid, gid);
+        if (r < 0) {
+                log_error("Could not create runtime directory: %s", strerror(-r));
+                goto finish;
+        }
+
+        r = drop_privileges(uid, gid, 0);
+        if (r < 0)
+                goto finish;
+
+        assert_se(sigprocmask_many(SIG_BLOCK, SIGTERM, SIGINT, -1) == 0);
+
+        r = manager_new(&m);
+        if (r < 0) {
+                log_error("Could not create manager: %s", strerror(-r));
+                goto finish;
+        }
+
+        r = manager_parse_config_file(m);
+        if (r < 0)
+                log_warning("Failed to parse configuration file: %s", strerror(-r));
+
+        r = manager_start(m);
+        if (r < 0) {
+                log_error("Failed to start manager: %s", strerror(-r));
+                goto finish;
+        }
+
+        /* Write finish default resolv.conf to avoid a dangling
+         * symlink */
+        r = manager_write_resolv_conf(m);
+        if (r < 0)
+                log_warning("Could not create resolv.conf: %s", strerror(-r));
+
+        sd_notify(false,
+                  "READY=1\n"
+                  "STATUS=Processing requests...");
+
+        r = sd_event_loop(m->event);
+        if (r < 0) {
+                log_error("Event loop failed: %s", strerror(-r));
+                goto finish;
+        }
+
+        sd_event_get_exit_code(m->event, &r);
+
+finish:
+        sd_notify(false, "STATUS=Shutting down...");
+
+        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/src/resolve/resolved.conf.in b/src/resolve/resolved.conf.in
new file mode 100644 (file)
index 0000000..c8263d6
--- /dev/null
@@ -0,0 +1,13 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+#
+# See resolved.conf(5) for details
+
+[Resolve]
+#DNS=
+#FallbackDNS=@DNS_SERVERS@
+#LLMNR=yes
diff --git a/src/resolve/test-dns-domain.c b/src/resolve/test-dns-domain.c
new file mode 100644 (file)
index 0000000..dfe2a44
--- /dev/null
@@ -0,0 +1,192 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+ ***/
+
+#include "log.h"
+#include "resolved-dns-domain.h"
+
+static void test_dns_label_unescape_one(const char *what, const char *expect, size_t buffer_sz, int ret) {
+        char buffer[buffer_sz];
+        int r;
+
+        r = dns_label_unescape(&what, buffer, buffer_sz);
+        assert_se(r == ret);
+
+        if (r < 0)
+                return;
+
+        assert_se(streq(buffer, expect));
+}
+
+static void test_dns_label_unescape(void) {
+        test_dns_label_unescape_one("hallo", "hallo", 6, 5);
+        test_dns_label_unescape_one("hallo", "hallo", 4, -ENOSPC);
+        test_dns_label_unescape_one("", "", 10, 0);
+        test_dns_label_unescape_one("hallo\\.foobar", "hallo.foobar", 20, 12);
+        test_dns_label_unescape_one("hallo.foobar", "hallo", 10, 5);
+        test_dns_label_unescape_one("hallo\n.foobar", "hallo", 20, -EINVAL);
+        test_dns_label_unescape_one("hallo\\", "hallo", 20, -EINVAL);
+        test_dns_label_unescape_one("hallo\\032 ", "hallo  ", 20, 7);
+        test_dns_label_unescape_one(".", "", 20, 0);
+        test_dns_label_unescape_one("..", "", 20, -EINVAL);
+        test_dns_label_unescape_one(".foobar", "", 20, -EINVAL);
+        test_dns_label_unescape_one("foobar.", "foobar", 20, 6);
+}
+
+static void test_dns_label_escape_one(const char *what, size_t l, const char *expect, int ret) {
+        _cleanup_free_ char *t = NULL;
+        int r;
+
+        r = dns_label_escape(what, l, &t);
+        assert(r == ret);
+
+        if (r < 0)
+                return;
+
+        assert_se(streq_ptr(expect, t));
+}
+
+static void test_dns_label_escape(void) {
+        test_dns_label_escape_one("", 0, "", 0);
+        test_dns_label_escape_one("hallo", 5, "hallo", 5);
+        test_dns_label_escape_one("hallo", 6, NULL, -EINVAL);
+        test_dns_label_escape_one("hallo hallo.foobar,waldi", 24, "hallo\\032hallo\\.foobar\\044waldi", 31);
+}
+
+static void test_dns_name_normalize_one(const char *what, const char *expect, int ret) {
+        _cleanup_free_ char *t = NULL;
+        int r;
+
+        r = dns_name_normalize(what, &t);
+        assert_se(r == ret);
+
+        if (r < 0)
+                return;
+
+        assert_se(streq_ptr(expect, t));
+}
+
+static void test_dns_name_normalize(void) {
+        test_dns_name_normalize_one("", "", 0);
+        test_dns_name_normalize_one("f", "f", 0);
+        test_dns_name_normalize_one("f.waldi", "f.waldi", 0);
+        test_dns_name_normalize_one("f \\032.waldi", "f\\032\\032.waldi", 0);
+        test_dns_name_normalize_one("\\000", NULL, -EINVAL);
+        test_dns_name_normalize_one("..", NULL, -EINVAL);
+        test_dns_name_normalize_one(".foobar", NULL, -EINVAL);
+        test_dns_name_normalize_one("foobar.", "foobar", 0);
+        test_dns_name_normalize_one(".", "", 0);
+}
+
+static void test_dns_name_equal_one(const char *a, const char *b, int ret) {
+        int r;
+
+        r = dns_name_equal(a, b);
+        assert_se(r == ret);
+
+        r = dns_name_equal(b, a);
+        assert_se(r == ret);
+}
+
+static void test_dns_name_equal(void) {
+        test_dns_name_equal_one("", "", true);
+        test_dns_name_equal_one("x", "x", true);
+        test_dns_name_equal_one("x", "x.", true);
+        test_dns_name_equal_one("abc.def", "abc.def", true);
+        test_dns_name_equal_one("abc.def", "ABC.def", true);
+        test_dns_name_equal_one("abc.def", "CBA.def", false);
+        test_dns_name_equal_one("", "xxx", false);
+        test_dns_name_equal_one("ab", "a", false);
+        test_dns_name_equal_one("\\000", "xxxx", -EINVAL);
+        test_dns_name_equal_one(".", "", true);
+        test_dns_name_equal_one(".", ".", true);
+        test_dns_name_equal_one("..", "..", -EINVAL);
+}
+
+static void test_dns_name_endswith_one(const char *a, const char *b, int ret) {
+        assert_se(dns_name_endswith(a, b) == ret);
+}
+
+static void test_dns_name_endswith(void) {
+        test_dns_name_endswith_one("", "", true);
+        test_dns_name_endswith_one("", "xxx", false);
+        test_dns_name_endswith_one("xxx", "", true);
+        test_dns_name_endswith_one("x", "x", true);
+        test_dns_name_endswith_one("x", "y", false);
+        test_dns_name_endswith_one("x.y", "y", true);
+        test_dns_name_endswith_one("x.y", "Y", true);
+        test_dns_name_endswith_one("x.y", "x", false);
+        test_dns_name_endswith_one("x.y.z", "Z", true);
+        test_dns_name_endswith_one("x.y.z", "y.Z", true);
+        test_dns_name_endswith_one("x.y.z", "x.y.Z", true);
+        test_dns_name_endswith_one("x.y.z", "waldo", false);
+        test_dns_name_endswith_one("x.y.z.u.v.w", "y.z", false);
+        test_dns_name_endswith_one("x.y.z.u.v.w", "u.v.w", true);
+        test_dns_name_endswith_one("x.y\001.z", "waldo", -EINVAL);
+}
+
+static void test_dns_name_root(void) {
+        assert_se(dns_name_root("") == true);
+        assert_se(dns_name_root(".") == true);
+        assert_se(dns_name_root("xxx") == false);
+        assert_se(dns_name_root("xxx.") == false);
+        assert_se(dns_name_root("..") == -EINVAL);
+}
+
+static void test_dns_name_single_label(void) {
+        assert_se(dns_name_single_label("") == false);
+        assert_se(dns_name_single_label(".") == false);
+        assert_se(dns_name_single_label("..") == -EINVAL);
+        assert_se(dns_name_single_label("x") == true);
+        assert_se(dns_name_single_label("x.") == true);
+        assert_se(dns_name_single_label("xx.yy") == false);
+}
+
+static void test_dns_name_reverse_one(const char *address, const char *name) {
+        _cleanup_free_ char *p = NULL;
+        union in_addr_union a, b;
+        int familya, familyb;
+
+        assert_se(in_addr_from_string_auto(address, &familya, &a) >= 0);
+        assert_se(dns_name_reverse(familya, &a, &p) >= 0);
+        assert_se(streq(p, name));
+        assert_se(dns_name_address(p, &familyb, &b) > 0);
+        assert_se(familya == familyb);
+        assert_se(in_addr_equal(familya, &a, &b));
+}
+
+static void test_dns_name_reverse(void) {
+        test_dns_name_reverse_one("47.11.8.15", "15.8.11.47.in-addr.arpa");
+        test_dns_name_reverse_one("fe80::47", "7.4.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.e.f.ip6.arpa");
+}
+
+int main(int argc, char *argv[]) {
+
+        test_dns_label_unescape();
+        test_dns_label_escape();
+        test_dns_name_normalize();
+        test_dns_name_equal();
+        test_dns_name_endswith();
+        test_dns_name_root();
+        test_dns_name_single_label();
+        test_dns_name_reverse();
+
+        return 0;
+}
index 885d881..e3b6293 100644 (file)
@@ -27,6 +27,7 @@
 #include "strv.h"
 #include "build.h"
 #include "unit-name.h"
+#include "env-util.h"
 #include "path-util.h"
 #include "bus-error.h"
 
@@ -37,7 +38,7 @@ static const char *arg_description = NULL;
 static const char *arg_slice = NULL;
 static bool arg_send_sighup = false;
 static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
-static char *arg_host = NULL;
+static const char *arg_host = NULL;
 static bool arg_user = false;
 static const char *arg_service_type = NULL;
 static const char *arg_exec_user = NULL;
@@ -45,30 +46,29 @@ static const char *arg_exec_group = NULL;
 static int arg_nice = 0;
 static bool arg_nice_set = false;
 static char **arg_environment = NULL;
+static char **arg_property = NULL;
 
-static int help(void) {
-
+static void help(void) {
         printf("%s [OPTIONS...] COMMAND [ARGS...]\n\n"
                "Run the specified command in a transient scope or service unit.\n\n"
-               "  -h --help               Show this help\n"
-               "     --version            Show package version\n"
-               "     --user               Run as user unit\n"
-               "  -H --host=[USER@]HOST   Operate on remote host\n"
-               "  -M --machine=CONTAINER  Operate on local container\n"
-               "     --scope              Run this as scope rather than service\n"
-               "     --unit=UNIT          Run under the specified unit name\n"
-               "     --description=TEXT   Description for unit\n"
-               "     --slice=SLICE        Run in the specified slice\n"
-               "  -r --remain-after-exit  Leave service around until explicitly stopped\n"
-               "     --send-sighup        Send SIGHUP when terminating\n"
-               "     --service-type=TYPE  Service type\n"
-               "     --uid=USER           Run as system user\n"
-               "     --gid=GROUP          Run as system group\n"
-               "     --nice=NICE          Nice level\n"
-               "     --setenv=NAME=VALUE  Set environment\n",
+               "  -h --help                 Show this help\n"
+               "     --version              Show package version\n"
+               "     --user                 Run as user unit\n"
+               "  -H --host=[USER@]HOST     Operate on remote host\n"
+               "  -M --machine=CONTAINER    Operate on local container\n"
+               "     --scope                Run this as scope rather than service\n"
+               "     --unit=UNIT            Run under the specified unit name\n"
+               "  -p --property=NAME=VALUE  Set unit property\n"
+               "     --description=TEXT     Description for unit\n"
+               "     --slice=SLICE          Run in the specified slice\n"
+               "  -r --remain-after-exit    Leave service around until explicitly stopped\n"
+               "     --send-sighup          Send SIGHUP when terminating\n"
+               "     --service-type=TYPE    Service type\n"
+               "     --uid=USER             Run as system user\n"
+               "     --gid=GROUP            Run as system group\n"
+               "     --nice=NICE            Nice level\n"
+               "     --setenv=NAME=VALUE    Set environment\n",
                program_invocation_short_name);
-
-        return 0;
 }
 
 static int parse_argv(int argc, char *argv[]) {
@@ -107,6 +107,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "gid",               required_argument, NULL, ARG_EXEC_GROUP   },
                 { "nice",              required_argument, NULL, ARG_NICE         },
                 { "setenv",            required_argument, NULL, ARG_SETENV       },
+                { "property",          required_argument, NULL, 'p'              },
                 {},
         };
 
@@ -115,12 +116,13 @@ static int parse_argv(int argc, char *argv[]) {
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "+hrH:M:", options, NULL)) >= 0) {
+        while ((c = getopt_long(argc, argv, "+hrH:M:p:", options, NULL)) >= 0)
 
                 switch (c) {
 
                 case 'h':
-                        return help();
+                        help();
+                        return 0;
 
                 case ARG_VERSION:
                         puts(PACKAGE_STRING);
@@ -183,7 +185,7 @@ static int parse_argv(int argc, char *argv[]) {
 
                 case ARG_NICE:
                         r = safe_atoi(optarg, &arg_nice);
-                        if (r < 0) {
+                        if (r < 0 || arg_nice < PRIO_MIN || arg_nice >= PRIO_MAX) {
                                 log_error("Failed to parse nice value");
                                 return -EINVAL;
                         }
@@ -198,13 +200,19 @@ static int parse_argv(int argc, char *argv[]) {
 
                         break;
 
+                case 'p':
+
+                        if (strv_extend(&arg_property, optarg) < 0)
+                                return log_oom();
+
+                        break;
+
                 case '?':
                         return -EINVAL;
 
                 default:
                         assert_not_reached("Unhandled option");
                 }
-        }
 
         if (optind >= argc) {
                 log_error("Command line to execute required.");
@@ -221,8 +229,8 @@ static int parse_argv(int argc, char *argv[]) {
                 return -EINVAL;
         }
 
-        if (arg_scope && (arg_remain_after_exit || arg_service_type || arg_exec_user || arg_exec_group || arg_nice_set || arg_environment)) {
-                log_error("--remain-after-exit, --service-type=, --user=, --group=, --nice= and --setenv= are not supported in --scope mode.");
+        if (arg_scope && (arg_remain_after_exit || arg_service_type)) {
+                log_error("--remain-after-exit and --service-type= are not supported in --scope mode.");
                 return -EINVAL;
         }
 
@@ -231,14 +239,13 @@ static int parse_argv(int argc, char *argv[]) {
 
 static int message_start_transient_unit_new(sd_bus *bus, const char *name, sd_bus_message **ret) {
         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
+        char **i;
         int r;
 
         assert(bus);
         assert(name);
         assert(ret);
 
-        log_info("Running as unit %s.", name);
-
         r = sd_bus_message_new_method_call(
                         bus,
                         &m,
@@ -257,6 +264,20 @@ static int message_start_transient_unit_new(sd_bus *bus, const char *name, sd_bu
         if (r < 0)
                 return r;
 
+        STRV_FOREACH(i, arg_property) {
+                r = sd_bus_message_open_container(m, 'r', "sv");
+                if (r < 0)
+                        return r;
+
+                r = bus_append_unit_property_assignment(m, *i);
+                if (r < 0)
+                        return r;
+
+                r = sd_bus_message_close_container(m);
+                if (r < 0)
+                        return r;
+        }
+
         r = sd_bus_message_append(m, "(sv)", "Description", "s", arg_description);
         if (r < 0)
                 return r;
@@ -273,9 +294,11 @@ static int message_start_transient_unit_new(sd_bus *bus, const char *name, sd_bu
                         return r;
         }
 
-        r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", arg_send_sighup);
-        if (r < 0)
-                return r;
+        if (arg_send_sighup) {
+                r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", arg_send_sighup);
+                if (r < 0)
+                        return r;
+        }
 
         *ret = m;
         m = NULL;
@@ -309,120 +332,128 @@ static int start_transient_service(
         _cleanup_free_ char *name = NULL;
         int r;
 
-        if (arg_unit)
+        if (arg_unit) {
                 name = unit_name_mangle_with_suffix(arg_unit, MANGLE_NOGLOB, ".service");
-        else
-                asprintf(&name, "run-%lu.service", (unsigned long) getpid());
-        if (!name)
-                return -ENOMEM;
+                if (!name)
+                        return log_oom();
+        } else if (asprintf(&name, "run-"PID_FMT".service", getpid()) < 0)
+                return log_oom();
 
         r = message_start_transient_unit_new(bus, name, &m);
         if (r < 0)
-                return r;
+                return bus_log_create_error(r);
 
-        r = sd_bus_message_append(m, "(sv)", "RemainAfterExit", "b", arg_remain_after_exit);
-        if (r < 0)
-                return r;
+        if (arg_remain_after_exit) {
+                r = sd_bus_message_append(m, "(sv)", "RemainAfterExit", "b", arg_remain_after_exit);
+                if (r < 0)
+                        return bus_log_create_error(r);
+        }
 
         if (arg_service_type) {
                 r = sd_bus_message_append(m, "(sv)", "Type", "s", arg_service_type);
                 if (r < 0)
-                        return r;
+                        return bus_log_create_error(r);
         }
 
         if (arg_exec_user) {
                 r = sd_bus_message_append(m, "(sv)", "User", "s", arg_exec_user);
                 if (r < 0)
-                        return r;
+                        return bus_log_create_error(r);
         }
 
         if (arg_exec_group) {
                 r = sd_bus_message_append(m, "(sv)", "Group", "s", arg_exec_group);
                 if (r < 0)
-                        return r;
+                        return bus_log_create_error(r);
         }
 
         if (arg_nice_set) {
                 r = sd_bus_message_append(m, "(sv)", "Nice", "i", arg_nice);
                 if (r < 0)
-                        return r;
+                        return bus_log_create_error(r);
         }
 
         if (!strv_isempty(arg_environment)) {
                 r = sd_bus_message_open_container(m, 'r', "sv");
                 if (r < 0)
-                        return r;
+                        return bus_log_create_error(r);
 
                 r = sd_bus_message_append(m, "s", "Environment");
                 if (r < 0)
-                        return r;
+                        return bus_log_create_error(r);
 
                 r = sd_bus_message_open_container(m, 'v', "as");
                 if (r < 0)
-                        return r;
+                        return bus_log_create_error(r);
 
                 r = sd_bus_message_append_strv(m, arg_environment);
                 if (r < 0)
-                        return r;
+                        return bus_log_create_error(r);
 
                 r = sd_bus_message_close_container(m);
                 if (r < 0)
-                        return r;
+                        return bus_log_create_error(r);
 
                 r = sd_bus_message_close_container(m);
                 if (r < 0)
-                        return r;
+                        return bus_log_create_error(r);
         }
 
         r = sd_bus_message_open_container(m, 'r', "sv");
         if (r < 0)
-                return r;
+                return bus_log_create_error(r);
 
         r = sd_bus_message_append(m, "s", "ExecStart");
         if (r < 0)
-                return r;
+                return bus_log_create_error(r);
 
         r = sd_bus_message_open_container(m, 'v', "a(sasb)");
         if (r < 0)
-                return r;
+                return bus_log_create_error(r);
 
         r = sd_bus_message_open_container(m, 'a', "(sasb)");
         if (r < 0)
-                return r;
+                return bus_log_create_error(r);
 
         r = sd_bus_message_open_container(m, 'r', "sasb");
         if (r < 0)
-                return r;
+                return bus_log_create_error(r);
 
         r = sd_bus_message_append(m, "s", argv[0]);
         if (r < 0)
-                return r;
+                return bus_log_create_error(r);
 
         r = sd_bus_message_append_strv(m, argv);
         if (r < 0)
-                return r;
+                return bus_log_create_error(r);
 
         r = sd_bus_message_append(m, "b", false);
         if (r < 0)
-                return r;
+                return bus_log_create_error(r);
 
         r = sd_bus_message_close_container(m);
         if (r < 0)
-                return r;
+                return bus_log_create_error(r);
 
         r = sd_bus_message_close_container(m);
         if (r < 0)
-                return r;
+                return bus_log_create_error(r);
 
         r = sd_bus_message_close_container(m);
         if (r < 0)
-                return r;
+                return bus_log_create_error(r);
 
         r = sd_bus_message_close_container(m);
         if (r < 0)
-                return r;
+                return bus_log_create_error(r);
 
-        return message_start_transient_unit_send(bus, m, error, NULL);
+        r = message_start_transient_unit_send(bus, m, error, NULL);
+        if (r < 0)
+                return bus_log_create_error(r);
+
+        log_info("Running as unit %s.", name);
+
+        return 0;
 }
 
 static int start_transient_scope(
@@ -432,37 +463,106 @@ static int start_transient_scope(
 
         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
         _cleanup_free_ char *name = NULL;
+        _cleanup_strv_free_ char **env = NULL, **user_env = NULL;
         int r;
 
         assert(bus);
 
-        if (arg_unit)
+        if (arg_unit) {
                 name = unit_name_mangle_with_suffix(arg_unit, MANGLE_NOGLOB, ".scope");
-        else
-                asprintf(&name, "run-%lu.scope", (unsigned long) getpid());
-        if (!name)
-                return -ENOMEM;
+                if (!name)
+                        return log_oom();
+        } else if (asprintf(&name, "run-"PID_FMT".scope", getpid()) < 0)
+                return log_oom();
 
         r = message_start_transient_unit_new(bus, name, &m);
         if (r < 0)
-                return r;
+                return bus_log_create_error(r);
 
         r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, (uint32_t) getpid());
         if (r < 0)
-                return r;
+                return bus_log_create_error(r);
 
         r = message_start_transient_unit_send(bus, m, error, NULL);
         if (r < 0)
-                return r;
+                return bus_log_create_error(r);
 
-        execvp(argv[0], argv);
+        if (arg_nice_set) {
+                if (setpriority(PRIO_PROCESS, 0, arg_nice) < 0) {
+                        log_error("Failed to set nice level: %m");
+                        return -errno;
+                }
+        }
+
+        if (arg_exec_group) {
+                gid_t gid;
+
+                r = get_group_creds(&arg_exec_group, &gid);
+                if (r < 0) {
+                        log_error("Failed to resolve group %s: %s", arg_exec_group, strerror(-r));
+                        return r;
+                }
+
+                if (setresgid(gid, gid, gid) < 0) {
+                        log_error("Failed to change GID to " GID_FMT ": %m", gid);
+                        return -errno;
+                }
+        }
+
+        if (arg_exec_user) {
+                const char *home, *shell;
+                uid_t uid;
+                gid_t gid;
+
+                r = get_user_creds(&arg_exec_user, &uid, &gid, &home, &shell);
+                if (r < 0) {
+                        log_error("Failed to resolve user %s: %s", arg_exec_user, strerror(-r));
+                        return r;
+                }
+
+                r = strv_extendf(&user_env, "HOME=%s", home);
+                if (r < 0)
+                        return log_oom();
+
+                r = strv_extendf(&user_env, "SHELL=%s", shell);
+                if (r < 0)
+                        return log_oom();
+
+                r = strv_extendf(&user_env, "USER=%s", arg_exec_user);
+                if (r < 0)
+                        return log_oom();
+
+                r = strv_extendf(&user_env, "LOGNAME=%s", arg_exec_user);
+                if (r < 0)
+                        return log_oom();
+
+                if (!arg_exec_group) {
+                        if (setresgid(gid, gid, gid) < 0) {
+                                log_error("Failed to change GID to " GID_FMT ": %m", gid);
+                                return -errno;
+                        }
+                }
+
+                if (setresuid(uid, uid, uid) < 0) {
+                        log_error("Failed to change UID to " UID_FMT ": %m", uid);
+                        return -errno;
+                }
+        }
+
+        env = strv_env_merge(3, environ, user_env, arg_environment);
+        if (!env)
+                return log_oom();
+
+        log_info("Running as unit %s.", name);
+
+        execvpe(argv[0], argv, env);
         log_error("Failed to execute: %m");
         return -errno;
 }
 
 int main(int argc, char* argv[]) {
         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
-        _cleanup_bus_unref_ sd_bus *bus = NULL;
+        _cleanup_bus_close_unref_ sd_bus *bus = NULL;
         _cleanup_free_ char *description = NULL, *command = NULL;
         int r;
 
@@ -490,7 +590,7 @@ int main(int argc, char* argv[]) {
                 arg_description = description;
         }
 
-        r = bus_open_transport(arg_transport, arg_host, arg_user, &bus);
+        r = bus_open_transport_systemd(arg_transport, arg_host, arg_user, &bus);
         if (r < 0) {
                 log_error("Failed to create bus connection: %s", strerror(-r));
                 goto finish;
@@ -500,9 +600,10 @@ int main(int argc, char* argv[]) {
                 r = start_transient_scope(bus, argv + optind, &error);
         else
                 r = start_transient_service(bus, argv + optind, &error);
-        if (r < 0)
-                log_error("Failed start transient unit: %s", bus_error_message(&error, r));
 
 finish:
+        strv_free(arg_environment);
+        strv_free(arg_property);
+
         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
 }
index c9b5f81..61709e8 100644 (file)
@@ -2,3 +2,11 @@
 /errno-from-name.h
 /errno-list.txt
 /errno-to-name.h
+/af-from-name.gperf
+/af-from-name.h
+/af-list.txt
+/af-to-name.h
+/arphrd-from-name.gperf
+/arphrd-from-name.h
+/arphrd-list.txt
+/arphrd-to-name.h
index fb04e49..c93f58a 100644 (file)
@@ -136,9 +136,8 @@ int search_acl_groups(char*** dst, const char* path, bool* belong) {
                                 return log_oom();
                         }
 
-                        r = strv_push(dst, name);
+                        r = strv_consume(dst, name);
                         if (r < 0) {
-                                free(name);
                                 acl_free(acl);
                                 return log_oom();
                         }
index 36ef490..a753ad1 100644 (file)
 int acl_find_uid(acl_t acl, uid_t uid, acl_entry_t *entry);
 int calc_acl_mask_if_needed(acl_t *acl_p);
 int search_acl_groups(char*** dst, const char* path, bool* belong);
+
+static inline void acl_freep(acl_t *acl) {
+
+        if (!*acl)
+                return;
+
+        acl_free(*acl);
+}
diff --git a/src/shared/af-list.c b/src/shared/af-list.c
new file mode 100644 (file)
index 0000000..f396115
--- /dev/null
@@ -0,0 +1,58 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2013 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/socket.h>
+#include <string.h>
+
+#include "util.h"
+#include "af-list.h"
+
+static const struct af_name* lookup_af(register const char *str, register unsigned int len);
+
+#include "af-to-name.h"
+#include "af-from-name.h"
+
+const char *af_to_name(int id) {
+
+        if (id <= 0)
+                return NULL;
+
+        if (id >= (int) ELEMENTSOF(af_names))
+                return NULL;
+
+        return af_names[id];
+}
+
+int af_from_name(const char *name) {
+        const struct af_name *sc;
+
+        assert(name);
+
+        sc = lookup_af(name, strlen(name));
+        if (!sc)
+                return AF_UNSPEC;
+
+        return sc->id;
+}
+
+int af_max(void) {
+        return ELEMENTSOF(af_names);
+}
diff --git a/src/shared/af-list.h b/src/shared/af-list.h
new file mode 100644 (file)
index 0000000..e346ab8
--- /dev/null
@@ -0,0 +1,27 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+const char *af_to_name(int id);
+int af_from_name(const char *name);
+
+int af_max(void);
index ceba492..dc45f35 100644 (file)
@@ -112,6 +112,10 @@ Architecture uname_architecture(void) {
                 { "sh",         ARCHITECTURE_SH       },
 #elif defined(__m68k__)
                 { "m68k",       ARCHITECTURE_M68K     },
+#elif defined(__tilegx__)
+                { "tilegx",     ARCHITECTURE_TILEGX   },
+#elif defined(__cris__)
+                { "crisv32",    ARCHITECTURE_CRIS     },
 #else
 #error "Please register your architecture here!"
 #endif
@@ -149,7 +153,9 @@ static const char *const architecture_table[_ARCHITECTURE_MAX] = {
         [ARCHITECTURE_SPARC] = "sparc",
         [ARCHITECTURE_SPARC64] = "sparc64",
         [ARCHITECTURE_MIPS] = "mips",
+        [ARCHITECTURE_MIPS_LE] = "mips-le",
         [ARCHITECTURE_MIPS64] = "mips64",
+        [ARCHITECTURE_MIPS64_LE] = "mips64-le",
         [ARCHITECTURE_ALPHA] = "alpha",
         [ARCHITECTURE_ARM] = "arm",
         [ARCHITECTURE_ARM_BE] = "arm-be",
@@ -158,6 +164,8 @@ static const char *const architecture_table[_ARCHITECTURE_MAX] = {
         [ARCHITECTURE_SH] = "sh",
         [ARCHITECTURE_SH64] = "sh64",
         [ARCHITECTURE_M68K] = "m68k",
+        [ARCHITECTURE_TILEGX] = "tilegx",
+        [ARCHITECTURE_CRIS] = "cris",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(architecture, Architecture);
index 3183645..71c79b1 100644 (file)
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
+#include <endian.h>
+
 #include "util.h"
 
+/* A cleaned up architecture definition. We don't want to get lost in
+ * processor features, models, generations or even ABIs. Hence we
+ * focus on general family, and distuignish word width and
+ * endianess. */
+
 typedef enum Architecture {
         ARCHITECTURE_X86 = 0,
         ARCHITECTURE_X86_64,
@@ -38,7 +45,9 @@ typedef enum Architecture {
         ARCHITECTURE_SPARC,
         ARCHITECTURE_SPARC64,
         ARCHITECTURE_MIPS,
+        ARCHITECTURE_MIPS_LE,
         ARCHITECTURE_MIPS64,
+        ARCHITECTURE_MIPS64_LE,
         ARCHITECTURE_ALPHA,
         ARCHITECTURE_ARM,
         ARCHITECTURE_ARM_BE,
@@ -47,66 +56,134 @@ typedef enum Architecture {
         ARCHITECTURE_SH,
         ARCHITECTURE_SH64,
         ARCHITECTURE_M68K,
+        ARCHITECTURE_TILEGX,
+        ARCHITECTURE_CRIS,
         _ARCHITECTURE_MAX,
         _ARCHITECTURE_INVALID = -1
 } Architecture;
 
 Architecture uname_architecture(void);
 
+/*
+ * LIB_ARCH_TUPLE should resolve to the local library path
+ * architecture tuple systemd is built for, according to the Debian
+ * tuple list:
+ *
+ * https://wiki.debian.org/Multiarch/Tuples
+ *
+ * This is used in library search paths that should understand
+ * Debian's paths on all distributions.
+ */
+
 #if defined(__x86_64__)
 #  define native_architecture() ARCHITECTURE_X86_64
+#  define LIB_ARCH_TUPLE "x86_64-linux-gnu"
 #elif defined(__i386__)
 #  define native_architecture() ARCHITECTURE_X86
+#  define LIB_ARCH_TUPLE "i386-linux-gnu"
 #elif defined(__powerpc64__)
-#  if defined(WORDS_BIGENDIAN)
+#  if __BYTE_ORDER == __BIG_ENDIAN
 #    define native_architecture() ARCHITECTURE_PPC64
+#    define LIB_ARCH_TUPLE "ppc64-linux-gnu"
 #  else
 #    define native_architecture() ARCHITECTURE_PPC64_LE
+#    define LIB_ARCH_TUPLE  "powerpc64le-linux-gnu"
 #  endif
 #elif defined(__powerpc__)
-#  if defined(WORDS_BIGENDIAN)
+#  if __BYTE_ORDER == __BIG_ENDIAN
 #    define native_architecture() ARCHITECTURE_PPC
+#    define LIB_ARCH_TUPLE "powerpc-linux-gnu"
 #  else
 #    define native_architecture() ARCHITECTURE_PPC_LE
+#    error "Missing LIB_ARCH_TUPLE for PPCLE"
 #  endif
 #elif defined(__ia64__)
 #  define native_architecture() ARCHITECTURE_IA64
+#  define LIB_ARCH_TUPLE "ia64-linux-gnu"
 #elif defined(__hppa64__)
 #  define native_architecture() ARCHITECTURE_PARISC64
+#  error "Missing LIB_ARCH_TUPLE for HPPA64"
 #elif defined(__hppa__)
 #  define native_architecture() ARCHITECTURE_PARISC
+#  define LIB_ARCH_TUPLE "hppa‑linux‑gnu"
 #elif defined(__s390x__)
 #  define native_architecture() ARCHITECTURE_S390X
+#  define LIB_ARCH_TUPLE "s390x-linux-gnu"
 #elif defined(__s390__)
 #  define native_architecture() ARCHITECTURE_S390
+#  define LIB_ARCH_TUPLE "s390-linux-gnu"
 #elif defined(__sparc64__)
 #  define native_architecture() ARCHITECTURE_SPARC64
+#  define LIB_ARCH_TUPLE "sparc64-linux-gnu"
 #elif defined(__sparc__)
 #  define native_architecture() ARCHITECTURE_SPARC
+#  define LIB_ARCH_TUPLE "sparc-linux-gnu"
 #elif defined(__mips64__)
-#  define native_architecture() ARCHITECTURE_MIPS64
+#  if __BYTE_ORDER == __BIG_ENDIAN
+#    define native_architecture() ARCHITECTURE_MIPS64
+#    error "Missing LIB_ARCH_TUPLE for MIPS64"
+#  else
+#    define native_architecture() ARCHITECTURE_MIPS64_LE
+#    error "Missing LIB_ARCH_TUPLE for MIPS64_LE"
+#  endif
 #elif defined(__mips__)
-#  define native_architecture() ARCHITECTURE_MIPS
+#  if __BYTE_ORDER == __BIG_ENDIAN
+#    define native_architecture() ARCHITECTURE_MIPS
+#    define LIB_ARCH_TUPLE "mips-linux-gnu"
+#  else
+#    define native_architecture() ARCHITECTURE_MIPS_LE
+#    define LIB_ARCH_TUPLE "mipsel-linux-gnu"
+#endif
 #elif defined(__alpha__)
 #  define native_architecture() ARCHITECTURE_ALPHA
+#  define LIB_ARCH_TUPLE "alpha-linux-gnu"
 #elif defined(__aarch64__)
-#  if defined(WORDS_BIGENDIAN)
+#  if __BYTE_ORDER == __BIG_ENDIAN
 #    define native_architecture() ARCHITECTURE_ARM64_BE
+#    define LIB_ARCH_TUPLE "aarch64_be-linux-gnu"
 #  else
 #    define native_architecture() ARCHITECTURE_ARM64
+#    define LIB_ARCH_TUPLE "aarch64-linux-gnu"
 #  endif
 #elif defined(__arm__)
-#  if defined(WORDS_BIGENDIAN)
+#  if __BYTE_ORDER == __BIG_ENDIAN
 #    define native_architecture() ARCHITECTURE_ARM_BE
+#    if defined(__ARM_EABI__)
+#      if defined(__ARM_PCS_VFP)
+#        define LIB_ARCH_TUPLE "armeb-linux-gnueabihf"
+#      else
+#        define LIB_ARCH_TUPLE "armeb-linux-gnueabi"
+#      endif
+#    else
+#      define LIB_ARCH_TUPLE "armeb-linux-gnu"
+#    endif
 #  else
 #    define native_architecture() ARCHITECTURE_ARM
+#    if defined(__ARM_EABI__)
+#      if defined(__ARM_PCS_VFP)
+#        define LIB_ARCH_TUPLE "arm-linux-gnueabihf"
+#      else
+#        define LIB_ARCH_TUPLE "arm-linux-gnueabi"
+#      endif
+#    else
+#      define LIB_ARCH_TUPLE "arm-linux-gnu"
+#    endif
 #  endif
 #elif defined(__sh64__)
 #  define native_architecture() ARCHITECTURE_SH64
+#  error "Missing LIB_ARCH_TUPLE for SH64"
 #elif defined(__sh__)
 #  define native_architecture() ARCHITECTURE_SH
+#  define LIB_ARCH_TUPLE "sh4-linux-gnu"
 #elif defined(__m68k__)
 #  define native_architecture() ARCHITECTURE_M68K
+#  define LIB_ARCH_TUPLE "m68k-linux-gnu"
+#elif defined(__tilegx__)
+#  define native_architecture() ARCHITECTURE_TILEGX
+#  error "Missing LIB_ARCH_TUPLE for TILEGX"
+#elif defined(__cris__)
+#  define native_architecture() ARCHITECTURE_CRIS
+#  error "Missing LIB_ARCH_TUPLE for CRIS"
 #else
 #error "Please register your architecture here!"
 #endif
diff --git a/src/shared/arphrd-list.c b/src/shared/arphrd-list.c
new file mode 100644 (file)
index 0000000..6e113ef
--- /dev/null
@@ -0,0 +1,59 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <net/if_arp.h>
+#include <sys/socket.h>
+#include <string.h>
+
+#include "util.h"
+#include "arphrd-list.h"
+
+static const struct arphrd_name* lookup_arphrd(register const char *str, register unsigned int len);
+
+#include "arphrd-to-name.h"
+#include "arphrd-from-name.h"
+
+const char *arphrd_to_name(int id) {
+
+        if (id <= 0)
+                return NULL;
+
+        if (id >= (int) ELEMENTSOF(arphrd_names))
+                return NULL;
+
+        return arphrd_names[id];
+}
+
+int arphrd_from_name(const char *name) {
+        const struct arphrd_name *sc;
+
+        assert(name);
+
+        sc = lookup_arphrd(name, strlen(name));
+        if (!sc)
+                return 0;
+
+        return sc->id;
+}
+
+int arphrd_max(void) {
+        return ELEMENTSOF(arphrd_names);
+}
diff --git a/src/shared/arphrd-list.h b/src/shared/arphrd-list.h
new file mode 100644 (file)
index 0000000..5ca182c
--- /dev/null
@@ -0,0 +1,27 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+const char *arphrd_to_name(int id);
+int arphrd_from_name(const char *name);
+
+int arphrd_max(void);
index a328f14..8d03f4a 100644 (file)
@@ -56,9 +56,10 @@ int ask_password_tty(
                 char **_passphrase) {
 
         struct termios old_termios, new_termios;
-        char passphrase[LINE_MAX];
+        char passphrase[LINE_MAX], *x;
         size_t p = 0;
-        int r, ttyfd = -1, notify = -1;
+        int r;
+        _cleanup_close_ int ttyfd = -1, notify = -1;
         struct pollfd pollfd[2];
         bool reset_tty = false;
         bool silent_mode = false;
@@ -72,7 +73,8 @@ int ask_password_tty(
         assert(_passphrase);
 
         if (flag_file) {
-                if ((notify = inotify_init1(IN_CLOEXEC|IN_NONBLOCK)) < 0) {
+                notify = inotify_init1(IN_CLOEXEC|IN_NONBLOCK);
+                if (notify < 0) {
                         r = -errno;
                         goto finish;
                 }
@@ -83,7 +85,8 @@ int ask_password_tty(
                 }
         }
 
-        if ((ttyfd = open("/dev/tty", O_RDWR|O_NOCTTY|O_CLOEXEC)) >= 0) {
+        ttyfd = open("/dev/tty", O_RDWR|O_NOCTTY|O_CLOEXEC);
+        if (ttyfd >= 0) {
 
                 if (tcgetattr(ttyfd, &old_termios) < 0) {
                         r = -errno;
@@ -138,8 +141,8 @@ int ask_password_tty(
                                 goto finish;
                         }
 
-                if ((k = poll(pollfd, notify > 0 ? 2 : 1, sleep_for)) < 0) {
-
+                k = poll(pollfd, notify > 0 ? 2 : 1, sleep_for);
+                if (k < 0) {
                         if (errno == EINTR)
                                 continue;
 
@@ -156,8 +159,8 @@ int ask_password_tty(
                 if (pollfd[POLL_TTY].revents == 0)
                         continue;
 
-                if ((n = read(ttyfd >= 0 ? ttyfd : STDIN_FILENO, &c, 1)) < 0) {
-
+                n = read(ttyfd >= 0 ? ttyfd : STDIN_FILENO, &c, 1);
+                if (n < 0) {
                         if (errno == EINTR || errno == EAGAIN)
                                 continue;
 
@@ -207,6 +210,11 @@ int ask_password_tty(
                         if (ttyfd >= 0)
                                 loop_write(ttyfd, "(no echo) ", 10, false);
                 } else {
+                        if (p >= sizeof(passphrase)-1) {
+                                loop_write(ttyfd, "\a", 1, false);
+                                continue;
+                        }
+
                         passphrase[p++] = c;
 
                         if (!silent_mode && ttyfd >= 0)
@@ -216,27 +224,19 @@ int ask_password_tty(
                 }
         }
 
-        passphrase[p] = 0;
-
-        if (!(*_passphrase = strdup(passphrase))) {
+        x = strndup(passphrase, p);
+        if (!x) {
                 r = -ENOMEM;
                 goto finish;
         }
 
+        *_passphrase = x;
         r = 0;
 
 finish:
-        if (notify >= 0)
-                close_nointr_nofail(notify);
-
-        if (ttyfd >= 0) {
-
-                if (reset_tty) {
-                        loop_write(ttyfd, "\n", 1, false);
-                        tcsetattr(ttyfd, TCSADRAIN, &old_termios);
-                }
-
-                close_nointr_nofail(ttyfd);
+        if (ttyfd >= 0 && reset_tty) {
+                loop_write(ttyfd, "\n", 1, false);
+                tcsetattr(ttyfd, TCSADRAIN, &old_termios);
         }
 
         return r;
@@ -270,7 +270,7 @@ static int create_socket(char **name) {
 
         if (r < 0) {
                 r = -errno;
-                log_error("bind() failed: %m");
+                log_error("bind(%s) failed: %m", sa.un.sun_path);
                 goto fail;
         }
 
@@ -290,7 +290,7 @@ static int create_socket(char **name) {
         return fd;
 
 fail:
-        close_nointr_nofail(fd);
+        safe_close(fd);
 
         return r;
 }
@@ -298,6 +298,7 @@ fail:
 int ask_password_agent(
                 const char *message,
                 const char *icon,
+                const char *id,
                 usec_t until,
                 bool accept_cached,
                 char ***_passphrases) {
@@ -310,12 +311,12 @@ int ask_password_agent(
 
         char temp[] = "/run/systemd/ask-password/tmp.XXXXXX";
         char final[sizeof(temp)] = "";
-        int fd = -1, r;
-        FILE *f = NULL;
-        char *socket_name = NULL;
-        int socket_fd = -1, signal_fd = -1;
+        _cleanup_fclose_ FILE *f = NULL;
+        _cleanup_free_ char *socket_name = NULL;
+        _cleanup_close_ int socket_fd = -1, signal_fd = -1, fd = -1;
         sigset_t mask, oldmask;
         struct pollfd pollfd[_FD_MAX];
+        int r;
 
         assert(_passphrases);
 
@@ -334,7 +335,8 @@ int ask_password_agent(
 
         fchmod(fd, 0644);
 
-        if (!(f = fdopen(fd, "w"))) {
+        f = fdopen(fd, "w");
+        if (!f) {
                 log_error("Failed to allocate FILE: %m");
                 r = -errno;
                 goto finish;
@@ -342,27 +344,29 @@ int ask_password_agent(
 
         fd = -1;
 
-        if ((signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC)) < 0) {
+        signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
+        if (signal_fd < 0) {
                 log_error("signalfd(): %m");
                 r = -errno;
                 goto finish;
         }
 
-        if ((socket_fd = create_socket(&socket_name)) < 0) {
+        socket_fd = create_socket(&socket_name);
+        if (socket_fd < 0) {
                 r = socket_fd;
                 goto finish;
         }
 
         fprintf(f,
                 "[Ask]\n"
-                "PID=%lu\n"
+                "PID="PID_FMT"\n"
                 "Socket=%s\n"
                 "AcceptCached=%i\n"
-                "NotAfter=%llu\n",
-                (unsigned long) getpid(),
+                "NotAfter="USEC_FMT"\n",
+                getpid(),
                 socket_name,
                 accept_cached ? 1 : 0,
-                (unsigned long long) until);
+                until);
 
         if (message)
                 fprintf(f, "Message=%s\n", message);
@@ -370,6 +374,9 @@ int ask_password_agent(
         if (icon)
                 fprintf(f, "Icon=%s\n", icon);
 
+        if (id)
+                fprintf(f, "Id=%s\n", id);
+
         fflush(f);
 
         if (ferror(f)) {
@@ -417,8 +424,8 @@ int ask_password_agent(
                         goto finish;
                 }
 
-                if ((k = poll(pollfd, _FD_MAX, until > 0 ? (int) ((until-t)/USEC_PER_MSEC) : -1)) < 0) {
-
+                k = poll(pollfd, _FD_MAX, until > 0 ? (int) ((until-t)/USEC_PER_MSEC) : -1);
+                if (k < 0) {
                         if (errno == EINTR)
                                 continue;
 
@@ -455,8 +462,8 @@ int ask_password_agent(
                 msghdr.msg_control = &control;
                 msghdr.msg_controllen = sizeof(control);
 
-                if ((n = recvmsg(socket_fd, &msghdr, 0)) < 0) {
-
+                n = recvmsg(socket_fd, &msghdr, 0);
+                if (n < 0) {
                         if (errno == EAGAIN ||
                             errno == EINTR)
                                 continue;
@@ -521,22 +528,8 @@ int ask_password_agent(
         r = 0;
 
 finish:
-        if (fd >= 0)
-                close_nointr_nofail(fd);
-
-        if (socket_name) {
+        if (socket_name)
                 unlink(socket_name);
-                free(socket_name);
-        }
-
-        if (socket_fd >= 0)
-                close_nointr_nofail(socket_fd);
-
-        if (signal_fd >= 0)
-                close_nointr_nofail(signal_fd);
-
-        if (f)
-                fclose(f);
 
         unlink(temp);
 
@@ -548,7 +541,8 @@ finish:
         return r;
 }
 
-int ask_password_auto(const char *message, const char *icon, usec_t until, bool accept_cached, char ***_passphrases) {
+int ask_password_auto(const char *message, const char *icon, const char *id,
+                      usec_t until, bool accept_cached, char ***_passphrases) {
         assert(message);
         assert(_passphrases);
 
@@ -556,18 +550,16 @@ int ask_password_auto(const char *message, const char *icon, usec_t until, bool
                 int r;
                 char *s = NULL, **l = NULL;
 
-                if ((r = ask_password_tty(message, until, NULL, &s)) < 0)
+                r = ask_password_tty(message, until, NULL, &s);
+                if (r < 0)
                         return r;
 
-                l = strv_new(s, NULL);
-                free(s);
-
-                if (!l)
-                        return -ENOMEM;
+                r = strv_consume(&l, s);
+                if (r < 0)
+                        return r;
 
                 *_passphrases = l;
                 return r;
-
         } else
-                return ask_password_agent(message, icon, until, accept_cached, _passphrases);
+                return ask_password_agent(message, icon, id, until, accept_cached, _passphrases);
 }
index 288a0f4..3839a2d 100644 (file)
@@ -25,6 +25,8 @@
 
 int ask_password_tty(const char *message, usec_t until, const char *flag_file, char **_passphrase);
 
-int ask_password_agent(const char *message, const char *icon, usec_t until, bool accept_cached, char ***_passphrases);
+int ask_password_agent(const char *message, const char *icon, const char *id,
+                       usec_t until, bool accept_cached, char ***_passphrases);
 
-int ask_password_auto(const char *message, const char *icon, usec_t until, bool accept_cached, char ***_passphrases);
+int ask_password_auto(const char *message, const char *icon, const char *id,
+                      usec_t until, bool accept_cached, char ***_passphrases);
similarity index 77%
rename from src/core/async.c
rename to src/shared/async.c
index af527be..3876ded 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "async.h"
 #include "log.h"
+#include "util.h"
 
 int asynchronous_job(void* (*func)(void *p), void *arg) {
         pthread_attr_t a;
@@ -70,3 +71,24 @@ int asynchronous_sync(void) {
 
         return asynchronous_job(sync_thread, NULL);
 }
+
+static void *close_thread(void *p) {
+        safe_close(PTR_TO_INT(p));
+        return NULL;
+}
+
+int asynchronous_close(int fd) {
+        int r;
+
+        /* This is supposed to behave similar to safe_close(), but
+         * actually invoke close() asynchronously, so that it will
+         * never block. Ideally the kernel would have an API for this,
+         * but it doesn't, so we work around it, and hide this as a
+         * far away as we can. */
+
+        r = asynchronous_job(close_thread, INT_TO_PTR(fd));
+        if (r < 0)
+                safe_close(fd);
+
+        return -1;
+}
similarity index 96%
rename from src/core/async.h
rename to src/shared/async.h
index 6601b4d..7f1ef79 100644 (file)
@@ -22,4 +22,6 @@
 ***/
 
 int asynchronous_job(void* (*func)(void *p), void *arg);
+
 int asynchronous_sync(void);
+int asynchronous_close(int fd);
index 5466447..f101050 100644 (file)
@@ -77,9 +77,6 @@ int audit_loginuid_from_pid(pid_t pid, uid_t *uid) {
         if (r < 0)
                 return r;
 
-        if (u == (uid_t) -1)
-                return -ENXIO;
-
         *uid = (uid_t) u;
         return 0;
 }
diff --git a/src/shared/barrier.c b/src/shared/barrier.c
new file mode 100644 (file)
index 0000000..4a5544d
--- /dev/null
@@ -0,0 +1,410 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 David Herrmann <dh.herrmann@gmail.com>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <poll.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/eventfd.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "barrier.h"
+#include "macro.h"
+#include "util.h"
+
+/**
+ * Barriers
+ * This barrier implementation provides a simple synchronization method based
+ * on file-descriptors that can safely be used between threads and processes. A
+ * barrier object contains 2 shared counters based on eventfd. Both processes
+ * can now place barriers and wait for the other end to reach a random or
+ * specific barrier.
+ * Barriers are numbered, so you can either wait for the other end to reach any
+ * barrier or the last barrier that you placed. This way, you can use barriers
+ * for one-way *and* full synchronization. Note that even-though barriers are
+ * numbered, these numbers are internal and recycled once both sides reached the
+ * same barrier (implemented as a simple signed counter). It is thus not
+ * possible to address barriers by their ID.
+ *
+ * Barrier-API: Both ends can place as many barriers via barrier_place() as
+ * they want and each pair of barriers on both sides will be implicitly linked.
+ * Each side can use the barrier_wait/sync_*() family of calls to wait for the
+ * other side to place a specific barrier. barrier_wait_next() waits until the
+ * other side calls barrier_place(). No links between the barriers are
+ * considered and this simply serves as most basic asynchronous barrier.
+ * barrier_sync_next() is like barrier_wait_next() and waits for the other side
+ * to place their next barrier via barrier_place(). However, it only waits for
+ * barriers that are linked to a barrier we already placed. If the other side
+ * already placed more barriers than we did, barrier_sync_next() returns
+ * immediately.
+ * barrier_sync() extends barrier_sync_next() and waits until the other end
+ * placed as many barriers via barrier_place() as we did. If they already placed
+ * as many as we did (or more), it returns immediately.
+ *
+ * Additionally to basic barriers, an abortion event is available.
+ * barrier_abort() places an abortion event that cannot be undone. An abortion
+ * immediately cancels all placed barriers and replaces them. Any running and
+ * following wait/sync call besides barrier_wait_abortion() will immediately
+ * return false on both sides (otherwise, they always return true).
+ * barrier_abort() can be called multiple times on both ends and will be a
+ * no-op if already called on this side.
+ * barrier_wait_abortion() can be used to wait for the other side to call
+ * barrier_abort() and is the only wait/sync call that does not return
+ * immediately if we aborted outself. It only returns once the other side
+ * called barrier_abort().
+ *
+ * Barriers can be used for in-process and inter-process synchronization.
+ * However, for in-process synchronization you could just use mutexes.
+ * Therefore, main target is IPC and we require both sides to *not* share the FD
+ * table. If that's given, barriers provide target tracking: If the remote side
+ * exit()s, an abortion event is implicitly queued on the other side. This way,
+ * a sync/wait call will be woken up if the remote side crashed or exited
+ * unexpectedly. However, note that these abortion events are only queued if the
+ * barrier-queue has been drained. Therefore, it is safe to place a barrier and
+ * exit. The other side can safely wait on the barrier even though the exit
+ * queued an abortion event. Usually, the abortion event would overwrite the
+ * barrier, however, that's not true for exit-abortion events. Those are only
+ * queued if the barrier-queue is drained (thus, the receiving side has placed
+ * more barriers than the remote side).
+ */
+
+/**
+ * barrier_create() - Initialize a barrier object
+ * @obj: barrier to initialize
+ *
+ * This initializes a barrier object. The caller is responsible of allocating
+ * the memory and keeping it valid. The memory does not have to be zeroed
+ * beforehand.
+ * Two eventfd objects are allocated for each barrier. If allocation fails, an
+ * error is returned.
+ *
+ * If this function fails, the barrier is reset to an invalid state so it is
+ * safe to call barrier_destroy() on the object regardless whether the
+ * initialization succeeded or not.
+ *
+ * The caller is responsible to destroy the object via barrier_destroy() before
+ * releasing the underlying memory.
+ *
+ * Returns: 0 on success, negative error code on failure.
+ */
+int barrier_create(Barrier *b) {
+        assert(b);
+
+        if ((b->me = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK)) < 0 ||
+            (b->them = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK)) < 0 ||
+            pipe2(b->pipe, O_CLOEXEC | O_NONBLOCK) < 0) {
+                barrier_destroy(b);
+                return -errno;
+        }
+
+        return 0;
+}
+
+/**
+ * barrier_destroy() - Destroy a barrier object
+ * @b: barrier to destroy or NULL
+ *
+ * This destroys a barrier object that has previously been passed to
+ * barrier_create(). The object is released and reset to invalid
+ * state. Therefore, it is safe to call barrier_destroy() multiple
+ * times or even if barrier_create() failed. However, barrier must be
+ * always initalized with BARRIER_NULL.
+ *
+ * If @b is NULL, this is a no-op.
+ */
+void barrier_destroy(Barrier *b) {
+        if (!b)
+                return;
+
+        b->me = safe_close(b->me);
+        b->them = safe_close(b->them);
+        safe_close_pair(b->pipe);
+        b->barriers = 0;
+}
+
+/**
+ * barrier_set_role() - Set the local role of the barrier
+ * @b: barrier to operate on
+ * @role: role to set on the barrier
+ *
+ * This sets the roles on a barrier object. This is needed to know
+ * which side of the barrier you're on. Usually, the parent creates
+ * the barrier via barrier_create() and then calls fork() or clone().
+ * Therefore, the FDs are duplicated and the child retains the same
+ * barrier object.
+ *
+ * Both sides need to call barrier_set_role() after fork() or clone()
+ * are done. If this is not done, barriers will not work correctly.
+ *
+ * Note that barriers could be supported without fork() or clone(). However,
+ * this is currently not needed so it hasn't been implemented.
+ */
+void barrier_set_role(Barrier *b, unsigned int role) {
+        int fd;
+
+        assert(b);
+        assert(role == BARRIER_PARENT || role == BARRIER_CHILD);
+        /* make sure this is only called once */
+        assert(b->pipe[1] >= 0 && b->pipe[1] >= 0);
+
+        if (role == BARRIER_PARENT)
+                b->pipe[1] = safe_close(b->pipe[1]);
+        else {
+                b->pipe[0] = safe_close(b->pipe[0]);
+
+                /* swap me/them for children */
+                fd = b->me;
+                b->me = b->them;
+                b->them = fd;
+        }
+}
+
+/* places barrier; returns false if we aborted, otherwise true */
+static bool barrier_write(Barrier *b, uint64_t buf) {
+        ssize_t len;
+
+        /* prevent new sync-points if we already aborted */
+        if (barrier_i_aborted(b))
+                return false;
+
+        do {
+                len = write(b->me, &buf, sizeof(buf));
+        } while (len < 0 && IN_SET(errno, EAGAIN, EINTR));
+
+        if (len != sizeof(buf))
+                goto error;
+
+        /* lock if we aborted */
+        if (buf >= (uint64_t)BARRIER_ABORTION) {
+                if (barrier_they_aborted(b))
+                        b->barriers = BARRIER_WE_ABORTED;
+                else
+                        b->barriers = BARRIER_I_ABORTED;
+        } else if (!barrier_is_aborted(b))
+                b->barriers += buf;
+
+        return !barrier_i_aborted(b);
+
+error:
+        /* If there is an unexpected error, we have to make this fatal. There
+         * is no way we can recover from sync-errors. Therefore, we close the
+         * pipe-ends and treat this as abortion. The other end will notice the
+         * pipe-close and treat it as abortion, too. */
+
+        safe_close_pair(b->pipe);
+        b->barriers = BARRIER_WE_ABORTED;
+        return false;
+}
+
+/* waits for barriers; returns false if they aborted, otherwise true */
+static bool barrier_read(Barrier *b, int64_t comp) {
+        if (barrier_they_aborted(b))
+                return false;
+
+        while (b->barriers > comp) {
+                struct pollfd pfd[2] = {
+                        { .fd = b->pipe[0] >= 0 ? b->pipe[0] : b->pipe[1],
+                          .events = POLLHUP },
+                        { .fd = b->them,
+                          .events = POLLIN }};
+                uint64_t buf;
+                int r;
+
+                r = poll(pfd, 2, -1);
+                if (r < 0 && IN_SET(errno, EAGAIN, EINTR))
+                        continue;
+                else if (r < 0)
+                        goto error;
+
+                if (pfd[1].revents) {
+                        ssize_t len;
+
+                        /* events on @them signal new data for us */
+                        len = read(b->them, &buf, sizeof(buf));
+                        if (len < 0 && IN_SET(errno, EAGAIN, EINTR))
+                                continue;
+
+                        if (len != sizeof(buf))
+                                goto error;
+                } else if (pfd[0].revents & (POLLHUP | POLLERR | POLLNVAL))
+                        /* POLLHUP on the pipe tells us the other side exited.
+                         * We treat this as implicit abortion. But we only
+                         * handle it if there's no event on the eventfd. This
+                         * guarantees that exit-abortions do not overwrite real
+                         * barriers. */
+                        buf = BARRIER_ABORTION;
+                else
+                        continue;
+
+                /* lock if they aborted */
+                if (buf >= (uint64_t)BARRIER_ABORTION) {
+                        if (barrier_i_aborted(b))
+                                b->barriers = BARRIER_WE_ABORTED;
+                        else
+                                b->barriers = BARRIER_THEY_ABORTED;
+                } else if (!barrier_is_aborted(b))
+                        b->barriers -= buf;
+        }
+
+        return !barrier_they_aborted(b);
+
+error:
+        /* If there is an unexpected error, we have to make this fatal. There
+         * is no way we can recover from sync-errors. Therefore, we close the
+         * pipe-ends and treat this as abortion. The other end will notice the
+         * pipe-close and treat it as abortion, too. */
+
+        safe_close_pair(b->pipe);
+        b->barriers = BARRIER_WE_ABORTED;
+        return false;
+}
+
+/**
+ * barrier_place() - Place a new barrier
+ * @b: barrier object
+ *
+ * This places a new barrier on the barrier object. If either side already
+ * aborted, this is a no-op and returns "false". Otherwise, the barrier is
+ * placed and this returns "true".
+ *
+ * Returns: true if barrier was placed, false if either side aborted.
+ */
+bool barrier_place(Barrier *b) {
+        assert(b);
+
+        if (barrier_is_aborted(b))
+                return false;
+
+        barrier_write(b, BARRIER_SINGLE);
+        return true;
+}
+
+/**
+ * barrier_abort() - Abort the synchronization
+ * @b: barrier object to abort
+ *
+ * This aborts the barrier-synchronization. If barrier_abort() was already
+ * called on this side, this is a no-op. Otherwise, the barrier is put into the
+ * ABORT-state and will stay there. The other side is notified about the
+ * abortion. Any following attempt to place normal barriers or to wait on normal
+ * barriers will return immediately as "false".
+ *
+ * You can wait for the other side to call barrier_abort(), too. Use
+ * barrier_wait_abortion() for that.
+ *
+ * Returns: false if the other side already aborted, true otherwise.
+ */
+bool barrier_abort(Barrier *b) {
+        assert(b);
+
+        barrier_write(b, BARRIER_ABORTION);
+        return !barrier_they_aborted(b);
+}
+
+/**
+ * barrier_wait_next() - Wait for the next barrier of the other side
+ * @b: barrier to operate on
+ *
+ * This waits until the other side places its next barrier. This is independent
+ * of any barrier-links and just waits for any next barrier of the other side.
+ *
+ * If either side aborted, this returns false.
+ *
+ * Returns: false if either side aborted, true otherwise.
+ */
+bool barrier_wait_next(Barrier *b) {
+        assert(b);
+
+        if (barrier_is_aborted(b))
+                return false;
+
+        barrier_read(b, b->barriers - 1);
+        return !barrier_is_aborted(b);
+}
+
+/**
+ * barrier_wait_abortion() - Wait for the other side to abort
+ * @b: barrier to operate on
+ *
+ * This waits until the other side called barrier_abort(). This can be called
+ * regardless whether the local side already called barrier_abort() or not.
+ *
+ * If the other side has already aborted, this returns immediately.
+ *
+ * Returns: false if the local side aborted, true otherwise.
+ */
+bool barrier_wait_abortion(Barrier *b) {
+        assert(b);
+
+        barrier_read(b, BARRIER_THEY_ABORTED);
+        return !barrier_i_aborted(b);
+}
+
+/**
+ * barrier_sync_next() - Wait for the other side to place a next linked barrier
+ * @b: barrier to operate on
+ *
+ * This is like barrier_wait_next() and waits for the other side to call
+ * barrier_place(). However, this only waits for linked barriers. That means, if
+ * the other side already placed more barriers than (or as much as) we did, this
+ * returns immediately instead of waiting.
+ *
+ * If either side aborted, this returns false.
+ *
+ * Returns: false if either side aborted, true otherwise.
+ */
+bool barrier_sync_next(Barrier *b) {
+        assert(b);
+
+        if (barrier_is_aborted(b))
+                return false;
+
+        barrier_read(b, MAX((int64_t)0, b->barriers - 1));
+        return !barrier_is_aborted(b);
+}
+
+/**
+ * barrier_sync() - Wait for the other side to place as many barriers as we did
+ * @b: barrier to operate on
+ *
+ * This is like barrier_sync_next() but waits for the other side to call
+ * barrier_place() as often as we did (in total). If they already placed as much
+ * as we did (or more), this returns immediately instead of waiting.
+ *
+ * If either side aborted, this returns false.
+ *
+ * Returns: false if either side aborted, true otherwise.
+ */
+bool barrier_sync(Barrier *b) {
+        assert(b);
+
+        if (barrier_is_aborted(b))
+                return false;
+
+        barrier_read(b, 0);
+        return !barrier_is_aborted(b);
+}
diff --git a/src/shared/barrier.h b/src/shared/barrier.h
new file mode 100644 (file)
index 0000000..53b4439
--- /dev/null
@@ -0,0 +1,94 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 David Herrmann <dh.herrmann@gmail.com>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <inttypes.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+
+#include "macro.h"
+#include "util.h"
+
+/* See source file for an API description. */
+
+typedef struct Barrier Barrier;
+
+enum {
+        BARRIER_SINGLE                  = 1LL,
+        BARRIER_ABORTION                = INT64_MAX,
+
+        /* bias values to store state; keep @WE < @THEY < @I */
+        BARRIER_BIAS                    = INT64_MIN,
+        BARRIER_WE_ABORTED              = BARRIER_BIAS + 1LL,
+        BARRIER_THEY_ABORTED            = BARRIER_BIAS + 2LL,
+        BARRIER_I_ABORTED               = BARRIER_BIAS + 3LL,
+};
+
+enum {
+        BARRIER_PARENT,
+        BARRIER_CHILD,
+};
+
+struct Barrier {
+        int me;
+        int them;
+        int pipe[2];
+        int64_t barriers;
+};
+
+#define BARRIER_NULL {-1, -1, {-1, -1}, 0}
+
+int barrier_create(Barrier *obj);
+void barrier_destroy(Barrier *b);
+
+void barrier_set_role(Barrier *b, unsigned int role);
+
+bool barrier_place(Barrier *b);
+bool barrier_abort(Barrier *b);
+
+bool barrier_wait_next(Barrier *b);
+bool barrier_wait_abortion(Barrier *b);
+bool barrier_sync_next(Barrier *b);
+bool barrier_sync(Barrier *b);
+
+static inline bool barrier_i_aborted(Barrier *b) {
+        return b->barriers == BARRIER_I_ABORTED || b->barriers == BARRIER_WE_ABORTED;
+}
+
+static inline bool barrier_they_aborted(Barrier *b) {
+        return b->barriers == BARRIER_THEY_ABORTED || b->barriers == BARRIER_WE_ABORTED;
+}
+
+static inline bool barrier_we_aborted(Barrier *b) {
+        return b->barriers == BARRIER_WE_ABORTED;
+}
+
+static inline bool barrier_is_aborted(Barrier *b) {
+        return b->barriers == BARRIER_I_ABORTED || b->barriers == BARRIER_THEY_ABORTED || b->barriers == BARRIER_WE_ABORTED;
+}
+
+static inline bool barrier_place_and_sync(Barrier *b) {
+        barrier_place(b);
+        return barrier_sync(b);
+}
diff --git a/src/shared/base-filesystem.c b/src/shared/base-filesystem.c
new file mode 100644 (file)
index 0000000..addd26c
--- /dev/null
@@ -0,0 +1,113 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Kay Sievers
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <unistd.h>
+
+#include "base-filesystem.h"
+#include "log.h"
+#include "macro.h"
+#include "strv.h"
+#include "util.h"
+#include "label.h"
+#include "mkdir.h"
+
+typedef struct BaseFilesystem {
+        const char *dir;
+        mode_t mode;
+        const char *target;
+        const char *exists;
+} BaseFilesystem;
+
+static const BaseFilesystem table[] = {
+        { "bin",      0, "usr/bin\0",                  NULL },
+        { "lib",      0, "usr/lib\0",                  NULL },
+        { "root",  0755, NULL,                         NULL },
+        { "sbin",     0, "usr/sbin\0",                 NULL },
+#if defined(__i386__) || defined(__x86_64__)
+        { "lib64",    0, "usr/lib/x86_64-linux-gnu\0"
+                         "usr/lib64\0",                "ld-linux-x86-64.so.2" },
+#endif
+};
+
+int base_filesystem_create(const char *root) {
+        _cleanup_close_ int fd = -1;
+        unsigned i;
+        int r;
+
+        fd = open(root, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
+        if (fd < 0)
+                return -errno;
+
+        for (i = 0; i < ELEMENTSOF(table); i ++) {
+                if (table[i].target) {
+                        const char *target = NULL;
+                        const char *s;
+
+                        if (faccessat(fd, table[i].dir, F_OK, AT_SYMLINK_NOFOLLOW) >= 0)
+                                continue;
+
+                        /* check if one of the targets exists */
+                        NULSTR_FOREACH(s, table[i].target) {
+                                if (faccessat(fd, s, F_OK, AT_SYMLINK_NOFOLLOW) < 0)
+                                        continue;
+
+                                /* check if a specific file exists at the target path */
+                                if (table[i].exists) {
+                                        _cleanup_free_ char *p = NULL;
+
+                                        p = strjoin(s, "/", table[i].exists, NULL);
+                                        if (!p)
+                                                return log_oom();
+
+                                        if (faccessat(fd, p, F_OK, AT_SYMLINK_NOFOLLOW) < 0)
+                                                continue;
+                                }
+
+                                target = s;
+                                break;
+                        }
+
+                        if (!target)
+                                continue;
+
+                        r = symlinkat(target, fd, table[i].dir);
+                        if (r < 0 && errno != EEXIST) {
+                                log_error("Failed to create symlink at %s/%s: %m", root, table[i].dir);
+                                return -errno;
+                        }
+                        continue;
+                }
+
+                RUN_WITH_UMASK(0000)
+                        r = mkdirat(fd, table[i].dir, table[i].mode);
+                if (r < 0 && errno != EEXIST) {
+                        log_error("Failed to create directory at %s/%s: %m", root, table[i].dir);
+                        return -errno;
+                }
+        }
+
+        return 0;
+}
diff --git a/src/shared/base-filesystem.h b/src/shared/base-filesystem.h
new file mode 100644 (file)
index 0000000..03201f7
--- /dev/null
@@ -0,0 +1,24 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Kay Sievers
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+int base_filesystem_create(const char *root);
diff --git a/src/shared/blkid-util.h b/src/shared/blkid-util.h
new file mode 100644 (file)
index 0000000..c689310
--- /dev/null
@@ -0,0 +1,33 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#ifdef HAVE_BLKID
+#include <blkid/blkid.h>
+#endif
+
+#include "util.h"
+
+#ifdef HAVE_BLKID
+DEFINE_TRIVIAL_CLEANUP_FUNC(blkid_probe, blkid_free_probe);
+#define _cleanup_blkid_free_probe_ _cleanup_(blkid_free_probep)
+#endif
index 5637935..504ab1f 100644 (file)
@@ -42,6 +42,7 @@
 #define BUS_ERROR_NO_SUCH_MACHINE "org.freedesktop.machine1.NoSuchMachine"
 #define BUS_ERROR_NO_MACHINE_FOR_PID "org.freedesktop.machine1.NoMachineForPID"
 #define BUS_ERROR_MACHINE_EXISTS "org.freedesktop.machine1.MachineExists"
+#define BUS_ERROR_NO_PRIVATE_NETWORKING "org.freedesktop.machine1.NoPrivateNetworking"
 
 #define BUS_ERROR_NO_SUCH_SESSION "org.freedesktop.login1.NoSuchSession"
 #define BUS_ERROR_NO_SESSION_FOR_PID "org.freedesktop.login1.NoSessionForPID"
 #define BUS_ERROR_OPERATION_IN_PROGRESS "org.freedesktop.login1.OperationInProgress"
 #define BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED "org.freedesktop.login1.SleepVerbNotSupported"
 
+#define BUS_ERROR_AUTOMATIC_TIME_SYNC_ENABLED "org.freedesktop.timedate1.AutomaticTimeSyncEnabled"
+
 #define BUS_ERROR_NO_SUCH_PROCESS "org.freedesktop.systemd1.NoSuchProcess"
+
+#define BUS_ERROR_NO_NAME_SERVERS "org.freedesktop.resolve1.NoNameServers"
+#define BUS_ERROR_INVALID_REPLY "org.freedesktop.resolve1.InvalidReply"
+#define BUS_ERROR_NO_SUCH_RR "org.freedesktop.resolve1.NoSuchRR"
+#define BUS_ERROR_NO_RESOURCES "org.freedesktop.resolve1.NoResources"
+#define BUS_ERROR_CNAME_LOOP "org.freedesktop.resolve1.CNameLoop"
+#define BUS_ERROR_ABORTED "org.freedesktop.resolve1.Aborted"
+#define _BUS_ERROR_DNS "org.freedesktop.resolve1.DnsError."
index 7075159..69b7427 100644 (file)
@@ -938,7 +938,6 @@ int calendar_spec_next_usec(const CalendarSpec *spec, usec_t usec, usec_t *next)
         if (t == (time_t) -1)
                 return -EINVAL;
 
-
         *next = (usec_t) t * USEC_PER_SEC;
         return 0;
 }
index f8ee1c6..d2b9013 100644 (file)
 #include <ctype.h>
 #include <sys/capability.h>
 #include <sys/prctl.h>
+#include "grp.h"
 
 #include "macro.h"
-#include "capability.h"
 #include "util.h"
 #include "log.h"
 #include "fileio.h"
+#include "capability.h"
 
 int have_effective_cap(int value) {
         _cleanup_cap_free_ cap_t cap;
@@ -84,9 +85,9 @@ unsigned long cap_last_cap(void) {
 }
 
 int capability_bounding_set_drop(uint64_t drop, bool right_now) {
-        unsigned long i;
-        _cleanup_cap_free_ cap_t after_cap = NULL, temp_cap = NULL;
+        _cleanup_cap_free_ cap_t after_cap = NULL;
         cap_flag_value_t fv;
+        unsigned long i;
         int r;
 
         /* If we are run as PID 1 we will lack CAP_SETPCAP by default
@@ -102,6 +103,7 @@ int capability_bounding_set_drop(uint64_t drop, bool right_now) {
                 return -errno;
 
         if (fv != CAP_SET) {
+                _cleanup_cap_free_ cap_t temp_cap = NULL;
                 static const cap_value_t v = CAP_SETPCAP;
 
                 temp_cap = cap_dup(after_cap);
@@ -156,7 +158,8 @@ int capability_bounding_set_drop(uint64_t drop, bool right_now) {
         r = 0;
 
 finish:
-        cap_set_proc(after_cap);
+        if (cap_set_proc(after_cap) < 0)
+                return -errno;
 
         return r;
 }
@@ -211,3 +214,74 @@ int capability_bounding_set_drop_usermode(uint64_t drop) {
 
         return r;
 }
+
+int drop_privileges(uid_t uid, gid_t gid, uint64_t keep_capabilities) {
+
+        _cleanup_cap_free_ cap_t d = NULL;
+        int r;
+
+        /* Unfortunately we cannot leave privilege dropping to PID 1
+         * here, since we want to run as user but want to keep some
+         * capabilities. Since file capabilities have been introduced
+         * this cannot be done across exec() anymore, unless our
+         * binary has the capability configured in the file system,
+         * which we want to avoid. */
+
+        if (setresgid(gid, gid, gid) < 0) {
+                log_error("Failed change group ID: %m");
+                return -errno;
+        }
+
+        if (setgroups(0, NULL) < 0) {
+                log_error("Failed to drop auxiliary groups list: %m");
+                return -errno;
+        }
+
+        if (prctl(PR_SET_KEEPCAPS, 1) < 0) {
+                log_error("Failed to enable keep capabilities flag: %m");
+                return -errno;
+        }
+
+        r = setresuid(uid, uid, uid);
+        if (r < 0) {
+                log_error("Failed change user ID: %m");
+                return -errno;
+        }
+
+        if (prctl(PR_SET_KEEPCAPS, 0) < 0) {
+                log_error("Failed to disable keep capabilities flag: %m");
+                return -errno;
+        }
+
+        r = capability_bounding_set_drop(~keep_capabilities, true);
+        if (r < 0) {
+                log_error("Failed to drop capabilities: %s", strerror(-r));
+                return r;
+        }
+
+        d = cap_init();
+        if (!d)
+                return log_oom();
+
+        if (keep_capabilities) {
+                cap_value_t bits[sizeof(keep_capabilities)*8];
+                unsigned i, j = 0;
+
+                for (i = 0; i < sizeof(keep_capabilities)*8; i++)
+                        if (keep_capabilities & (1ULL << i))
+                                bits[j++] = i;
+
+                if (cap_set_flag(d, CAP_EFFECTIVE, j, bits, CAP_SET) < 0 ||
+                    cap_set_flag(d, CAP_PERMITTED, j, bits, CAP_SET) < 0) {
+                        log_error("Failed to enable capabilities bits: %m");
+                        return -errno;
+                }
+        }
+
+        if (cap_set_proc(d) < 0) {
+                log_error("Failed to increase capabilities: %m");
+                return -errno;
+        }
+
+        return 0;
+}
index 64f8641..3e6d999 100644 (file)
@@ -32,6 +32,8 @@ int have_effective_cap(int value);
 int capability_bounding_set_drop(uint64_t drop, bool right_now);
 int capability_bounding_set_drop_usermode(uint64_t drop);
 
+int drop_privileges(uid_t uid, gid_t gid, uint64_t keep_capabilites);
+
 DEFINE_TRIVIAL_CLEANUP_FUNC(cap_t, cap_free);
 #define _cleanup_cap_free_ _cleanup_(cap_freep)
 
index ee14cee..c862ee9 100644 (file)
@@ -78,10 +78,12 @@ static void show_pid_array(int pids[], unsigned n_pids, const char *prefix, unsi
 
                 get_process_cmdline(pids[i], n_columns, true, &t);
 
-                printf("%s%s%*lu %s\n",
-                       prefix,
-                       draw_special_char(extra ? DRAW_TRIANGULAR_BULLET :
-                                         ((more || i < n_pids-1) ? DRAW_TREE_BRANCH : DRAW_TREE_RIGHT)),
+                if (extra)
+                        printf("%s%s ", prefix, draw_special_char(DRAW_TRIANGULAR_BULLET));
+                else
+                        printf("%s%s", prefix, draw_special_char(((more || i < n_pids-1) ? DRAW_TREE_BRANCH : DRAW_TREE_RIGHT)));
+
+                printf("%*lu %s\n",
                        pid_width,
                        (unsigned long) pids[i],
                        strna(t));
@@ -181,7 +183,7 @@ int show_cgroup_by_path(const char *path, const char *prefix, unsigned n_columns
                                            basename(last));
 
                         if (!p1) {
-                                p1 = strappend(prefix, draw_special_char(DRAW_TREE_VERT));
+                                p1 = strappend(prefix, draw_special_char(DRAW_TREE_VERTICAL));
                                 if (!p1)
                                         return -ENOMEM;
                         }
index 06eb453..e8cb9c7 100644 (file)
@@ -472,9 +472,7 @@ static int join_path(const char *controller, const char *path, const char *suffi
         if (!t)
                 return -ENOMEM;
 
-        path_kill_slashes(t);
-
-        *fs = t;
+        *fs = path_kill_slashes(t);
         return 0;
 }
 
@@ -509,7 +507,7 @@ static int check_hierarchy(const char *p) {
         assert(p);
 
         /* Check if this controller actually really exists */
-        cc = alloca(sizeof("/sys/fs/cgroup/") + strlen(p));
+        cc = alloca(strlen("/sys/fs/cgroup/") + strlen(p) + 1);
         strcpy(stpcpy(cc, "/sys/fs/cgroup/"), p);
         if (access(cc, F_OK) < 0)
                 return -errno;
@@ -643,9 +641,9 @@ int cg_attach(const char *controller, const char *path, pid_t pid) {
         if (pid == 0)
                 pid = getpid();
 
-        snprintf(c, sizeof(c), "%lu\n", (unsigned long) pid);
+        snprintf(c, sizeof(c), PID_FMT"\n", pid);
 
-        return write_string_file(fs, c);
+        return write_string_file_no_create(fs, c);
 }
 
 int cg_attach_fallback(const char *controller, const char *path, pid_t pid) {
@@ -755,9 +753,9 @@ int cg_pid_get_path(const char *controller, pid_t pid, char **path) {
         cs = strlen(controller);
 
         FOREACH_LINE(line, f, return -errno) {
-                char *l, *p, *w, *e;
+                char *l, *p, *e;
                 size_t k;
-                char *state;
+                const char *word, *state;
                 bool found = false;
 
                 truncate_nl(line);
@@ -773,16 +771,16 @@ int cg_pid_get_path(const char *controller, pid_t pid, char **path) {
 
                 *e = 0;
 
-                FOREACH_WORD_SEPARATOR(w, k, l, ",", state) {
+                FOREACH_WORD_SEPARATOR(word, k, l, ",", state) {
 
-                        if (k == cs && memcmp(w, controller, cs) == 0) {
+                        if (k == cs && memcmp(word, controller, cs) == 0) {
                                 found = true;
                                 break;
                         }
 
                         if (k == 5 + cs &&
-                            memcmp(w, "name=", 5) == 0 &&
-                            memcmp(w+5, controller, cs) == 0) {
+                            memcmp(word, "name=", 5) == 0 &&
+                            memcmp(word+5, controller, cs) == 0) {
                                 found = true;
                                 break;
                         }
@@ -819,7 +817,7 @@ int cg_install_release_agent(const char *controller, const char *agent) {
 
         sc = strstrip(contents);
         if (sc[0] == 0) {
-                r = write_string_file(fs, agent);
+                r = write_string_file_no_create(fs, agent);
                 if (r < 0)
                         return r;
         } else if (!streq(sc, agent))
@@ -839,7 +837,7 @@ int cg_install_release_agent(const char *controller, const char *agent) {
 
         sc = strstrip(contents);
         if (streq(sc, "0")) {
-                r = write_string_file(fs, "1");
+                r = write_string_file_no_create(fs, "1");
                 if (r < 0)
                         return r;
 
@@ -860,7 +858,7 @@ int cg_uninstall_release_agent(const char *controller) {
         if (r < 0)
                 return r;
 
-        r = write_string_file(fs, "0");
+        r = write_string_file_no_create(fs, "0");
         if (r < 0)
                 return r;
 
@@ -871,7 +869,7 @@ int cg_uninstall_release_agent(const char *controller) {
         if (r < 0)
                 return r;
 
-        r = write_string_file(fs, "");
+        r = write_string_file_no_create(fs, "");
         if (r < 0)
                 return r;
 
@@ -957,8 +955,7 @@ int cg_split_spec(const char *spec, char **controller, char **path) {
                         if (!t)
                                 return -ENOMEM;
 
-                        path_kill_slashes(t);
-                        *path = t;
+                        *path = path_kill_slashes(t);
                 }
 
                 if (controller)
@@ -1048,8 +1045,7 @@ int cg_mangle_path(const char *path, char **result) {
                 if (!t)
                         return -ENOMEM;
 
-                path_kill_slashes(t);
-                *result = t;
+                *result = path_kill_slashes(t);
                 return 0;
         }
 
@@ -1595,7 +1591,7 @@ int cg_set_attribute(const char *controller, const char *path, const char *attri
         if (r < 0)
                 return r;
 
-        return write_string_file(p, value);
+        return write_string_file_no_create(p, value);
 }
 
 static const char mask_names[] =
diff --git a/src/shared/clean-ipc.c b/src/shared/clean-ipc.c
new file mode 100644 (file)
index 0000000..cb17226
--- /dev/null
@@ -0,0 +1,360 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <sys/sem.h>
+#include <sys/msg.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <mqueue.h>
+
+#include "util.h"
+#include "strv.h"
+#include "clean-ipc.h"
+
+static int clean_sysvipc_shm(uid_t delete_uid) {
+        _cleanup_fclose_ FILE *f = NULL;
+        char line[LINE_MAX];
+        bool first = true;
+        int ret = 0;
+
+        f = fopen("/proc/sysvipc/shm", "re");
+        if (!f) {
+                if (errno == ENOENT)
+                        return 0;
+
+                log_warning("Failed to open /proc/sysvipc/shm: %m");
+                return -errno;
+        }
+
+        FOREACH_LINE(line, f, goto fail) {
+                unsigned n_attached;
+                pid_t cpid, lpid;
+                uid_t uid, cuid;
+                gid_t gid, cgid;
+                int shmid;
+
+                if (first) {
+                        first = false;
+                        continue;
+                }
+
+                truncate_nl(line);
+
+                if (sscanf(line, "%*i %i %*o %*u " PID_FMT " " PID_FMT " %u " UID_FMT " " GID_FMT " " UID_FMT " " GID_FMT,
+                           &shmid, &cpid, &lpid, &n_attached, &uid, &gid, &cuid, &cgid) != 8)
+                        continue;
+
+                if (n_attached > 0)
+                        continue;
+
+                if (uid != delete_uid)
+                        continue;
+
+                if (shmctl(shmid, IPC_RMID, NULL) < 0) {
+
+                        /* Ignore entries that are already deleted */
+                        if (errno == EIDRM || errno == EINVAL)
+                                continue;
+
+                        log_warning("Failed to remove SysV shared memory segment %i: %m", shmid);
+                        ret = -errno;
+                }
+        }
+
+        return ret;
+
+fail:
+        log_warning("Failed to read /proc/sysvipc/shm: %m");
+        return -errno;
+}
+
+static int clean_sysvipc_sem(uid_t delete_uid) {
+        _cleanup_fclose_ FILE *f = NULL;
+        char line[LINE_MAX];
+        bool first = true;
+        int ret = 0;
+
+        f = fopen("/proc/sysvipc/sem", "re");
+        if (!f) {
+                if (errno == ENOENT)
+                        return 0;
+
+                log_warning("Failed to open /proc/sysvipc/sem: %m");
+                return -errno;
+        }
+
+        FOREACH_LINE(line, f, goto fail) {
+                uid_t uid, cuid;
+                gid_t gid, cgid;
+                int semid;
+
+                if (first) {
+                        first = false;
+                        continue;
+                }
+
+                truncate_nl(line);
+
+                if (sscanf(line, "%*i %i %*o %*u " UID_FMT " " GID_FMT " " UID_FMT " " GID_FMT,
+                           &semid, &uid, &gid, &cuid, &cgid) != 5)
+                        continue;
+
+                if (uid != delete_uid)
+                        continue;
+
+                if (semctl(semid, 0, IPC_RMID) < 0) {
+
+                        /* Ignore entries that are already deleted */
+                        if (errno == EIDRM || errno == EINVAL)
+                                continue;
+
+                        log_warning("Failed to remove SysV semaphores object %i: %m", semid);
+                        ret = -errno;
+                }
+        }
+
+        return ret;
+
+fail:
+        log_warning("Failed to read /proc/sysvipc/sem: %m");
+        return -errno;
+}
+
+static int clean_sysvipc_msg(uid_t delete_uid) {
+        _cleanup_fclose_ FILE *f = NULL;
+        char line[LINE_MAX];
+        bool first = true;
+        int ret = 0;
+
+        f = fopen("/proc/sysvipc/msg", "re");
+        if (!f) {
+                if (errno == ENOENT)
+                        return 0;
+
+                log_warning("Failed to open /proc/sysvipc/msg: %m");
+                return -errno;
+        }
+
+        FOREACH_LINE(line, f, goto fail) {
+                uid_t uid, cuid;
+                gid_t gid, cgid;
+                pid_t cpid, lpid;
+                int msgid;
+
+                if (first) {
+                        first = false;
+                        continue;
+                }
+
+                truncate_nl(line);
+
+                if (sscanf(line, "%*i %i %*o %*u %*u " PID_FMT " " PID_FMT " " UID_FMT " " GID_FMT " " UID_FMT " " GID_FMT,
+                           &msgid, &cpid, &lpid, &uid, &gid, &cuid, &cgid) != 7)
+                        continue;
+
+                if (uid != delete_uid)
+                        continue;
+
+                if (msgctl(msgid, IPC_RMID, NULL) < 0) {
+
+                        /* Ignore entries that are already deleted */
+                        if (errno == EIDRM || errno == EINVAL)
+                                continue;
+
+                        log_warning("Failed to remove SysV message queue %i: %m", msgid);
+                        ret = -errno;
+                }
+        }
+
+        return ret;
+
+fail:
+        log_warning("Failed to read /proc/sysvipc/msg: %m");
+        return -errno;
+}
+
+static int clean_posix_shm_internal(DIR *dir, uid_t uid) {
+        struct dirent *de;
+        int ret = 0, r;
+
+        assert(dir);
+
+        FOREACH_DIRENT(de, dir, goto fail) {
+                struct stat st;
+
+                if (STR_IN_SET(de->d_name, "..", "."))
+                        continue;
+
+                if (fstatat(dirfd(dir), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) {
+                        if (errno == ENOENT)
+                                continue;
+
+                        log_warning("Failed to stat() POSIX shared memory segment %s: %m", de->d_name);
+                        ret = -errno;
+                        continue;
+                }
+
+                if (st.st_uid != uid)
+                        continue;
+
+                if (S_ISDIR(st.st_mode)) {
+                        _cleanup_closedir_ DIR *kid;
+
+                        kid = xopendirat(dirfd(dir), de->d_name, O_NOFOLLOW|O_NOATIME);
+                        if (!kid) {
+                                if (errno != ENOENT) {
+                                        log_warning("Failed to enter shared memory directory %s: %m", de->d_name);
+                                        ret = -errno;
+                                }
+                        } else {
+                                r = clean_posix_shm_internal(kid, uid);
+                                if (r < 0)
+                                        ret = r;
+                        }
+
+                        if (unlinkat(dirfd(dir), de->d_name, AT_REMOVEDIR) < 0) {
+
+                                if (errno == ENOENT)
+                                        continue;
+
+                                log_warning("Failed to remove POSIX shared memory directory %s: %m", de->d_name);
+                                ret = -errno;
+                        }
+                } else {
+
+                        if (unlinkat(dirfd(dir), de->d_name, 0) < 0) {
+
+                                if (errno == ENOENT)
+                                        continue;
+
+                                log_warning("Failed to remove POSIX shared memory segment %s: %m", de->d_name);
+                                ret = -errno;
+                        }
+                }
+        }
+
+        return ret;
+
+fail:
+        log_warning("Failed to read /dev/shm: %m");
+        return -errno;
+}
+
+static int clean_posix_shm(uid_t uid) {
+        _cleanup_closedir_ DIR *dir = NULL;
+
+        dir = opendir("/dev/shm");
+        if (!dir) {
+                if (errno == ENOENT)
+                        return 0;
+
+                log_warning("Failed to open /dev/shm: %m");
+                return -errno;
+        }
+
+        return clean_posix_shm_internal(dir, uid);
+}
+
+static int clean_posix_mq(uid_t uid) {
+        _cleanup_closedir_ DIR *dir = NULL;
+        struct dirent *de;
+        int ret = 0;
+
+        dir = opendir("/dev/mqueue");
+        if (!dir) {
+                if (errno == ENOENT)
+                        return 0;
+
+                log_warning("Failed to open /dev/mqueue: %m");
+                return -errno;
+        }
+
+        FOREACH_DIRENT(de, dir, goto fail) {
+                struct stat st;
+                char fn[1+strlen(de->d_name)+1];
+
+                if (STR_IN_SET(de->d_name, "..", "."))
+                        continue;
+
+                if (fstatat(dirfd(dir), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) {
+                        if (errno == ENOENT)
+                                continue;
+
+                        log_warning("Failed to stat() MQ segment %s: %m", de->d_name);
+                        ret = -errno;
+                        continue;
+                }
+
+                if (st.st_uid != uid)
+                        continue;
+
+                fn[0] = '/';
+                strcpy(fn+1, de->d_name);
+
+                if (mq_unlink(fn) < 0) {
+                        if (errno == ENOENT)
+                                continue;
+
+                        log_warning("Failed to unlink POSIX message queue %s: %m", fn);
+                        ret = -errno;
+                }
+        }
+
+        return ret;
+
+fail:
+        log_warning("Failed to read /dev/mqueue: %m");
+        return -errno;
+}
+
+int clean_ipc(uid_t uid) {
+        int ret = 0, r;
+
+        /* Refuse to clean IPC of the root and system users */
+        if (uid <= SYSTEM_UID_MAX)
+                return 0;
+
+        r = clean_sysvipc_shm(uid);
+        if (r < 0)
+                ret = r;
+
+        r = clean_sysvipc_sem(uid);
+        if (r < 0)
+                ret = r;
+
+        r = clean_sysvipc_msg(uid);
+        if (r < 0)
+                ret = r;
+
+        r = clean_posix_shm(uid);
+        if (r < 0)
+                ret = r;
+
+        r = clean_posix_mq(uid);
+        if (r < 0)
+                ret = r;
+
+        return ret;
+}
diff --git a/src/shared/clean-ipc.h b/src/shared/clean-ipc.h
new file mode 100644 (file)
index 0000000..2de57fa
--- /dev/null
@@ -0,0 +1,26 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/types.h>
+
+int clean_ipc(uid_t uid);
similarity index 84%
rename from src/shared/hwclock.c
rename to src/shared/clock-util.c
index 7059d9c..fc49393 100644 (file)
 #include "util.h"
 #include "log.h"
 #include "strv.h"
-#include "hwclock.h"
+#include "clock-util.h"
 #include "fileio.h"
 
-int hwclock_get_time(struct tm *tm) {
+int clock_get_hwclock(struct tm *tm) {
         _cleanup_close_ int fd = -1;
 
         assert(tm);
@@ -64,7 +64,7 @@ int hwclock_get_time(struct tm *tm) {
         return 0;
 }
 
-int hwclock_set_time(const struct tm *tm) {
+int clock_set_hwclock(const struct tm *tm) {
         _cleanup_close_ int fd = -1;
 
         assert(tm);
@@ -79,7 +79,7 @@ int hwclock_set_time(const struct tm *tm) {
         return 0;
 }
 
-int hwclock_is_localtime(void) {
+int clock_is_localtime(void) {
         _cleanup_fclose_ FILE *f;
 
         /*
@@ -109,7 +109,7 @@ int hwclock_is_localtime(void) {
         return 0;
 }
 
-int hwclock_set_timezone(int *min) {
+int clock_set_timezone(int *min) {
         const struct timeval *tv_null = NULL;
         struct timespec ts;
         struct tm *tm;
@@ -124,9 +124,10 @@ int hwclock_set_timezone(int *min) {
         tz.tz_dsttime = 0; /* DST_NONE*/
 
         /*
-         * If the hardware clock does not run in UTC, but in local time:
-         * The very first time we set the kernel's timezone, it will warp
-         * the clock so that it runs in UTC instead of local time.
+         * If the RTC does not run in UTC but in local time, the very first
+         * call to settimeofday() will set the kernel's timezone and will warp the
+         * system clock, so that it runs in UTC instead of the local time we
+         * have read from the RTC.
          */
         if (settimeofday(tv_null, &tz) < 0)
                 return -errno;
@@ -135,7 +136,7 @@ int hwclock_set_timezone(int *min) {
         return 0;
 }
 
-int hwclock_reset_timezone(void) {
+int clock_reset_timewarp(void) {
         const struct timeval *tv_null = NULL;
         struct timezone tz;
 
@@ -143,9 +144,9 @@ int hwclock_reset_timezone(void) {
         tz.tz_dsttime = 0; /* DST_NONE*/
 
         /*
-         * The very first time we set the kernel's timezone, it will warp
-         * the clock. Do a dummy call here, so the time warping is sealed
-         * and we set only the timezone with next call.
+         * The very first call to settimeofday() does time warp magic. Do a
+         * dummy call here, so the time warping is sealed and all later calls
+         * behave as expected.
          */
         if (settimeofday(tv_null, &tz) < 0)
                 return -errno;
similarity index 81%
rename from src/shared/hwclock.h
rename to src/shared/clock-util.h
index 4330b8e..7ed371a 100644 (file)
@@ -21,8 +21,8 @@
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
-int hwclock_is_localtime(void);
-int hwclock_set_timezone(int *min);
-int hwclock_reset_timezone(void);
-int hwclock_get_time(struct tm *tm);
-int hwclock_set_time(const struct tm *tm);
+int clock_is_localtime(void);
+int clock_set_timezone(int *min);
+int clock_reset_timewarp(void);
+int clock_get_hwclock(struct tm *tm);
+int clock_set_hwclock(const struct tm *tm);
index 9961cb4..ff4a8ec 100644 (file)
@@ -26,7 +26,7 @@
 #include <sys/statvfs.h>
 #include <fnmatch.h>
 
-#include <systemd/sd-id128.h>
+#include "systemd/sd-id128.h"
 #include "util.h"
 #include "condition-util.h"
 #include "virt.h"
@@ -74,7 +74,8 @@ void condition_free_list(Condition *first) {
 }
 
 bool condition_test_kernel_command_line(Condition *c) {
-        char *line, *w, *state, *word = NULL;
+        char *line, *word = NULL;
+        const char *w, *state;
         bool equal;
         int r;
         size_t l, pl;
@@ -113,6 +114,8 @@ bool condition_test_kernel_command_line(Condition *c) {
                 }
 
         }
+        if (!isempty(state))
+                log_warning("Trailing garbage and the end of kernel commandline, ignoring.");
 
         free(word);
         free(line);
@@ -177,10 +180,9 @@ bool condition_test_architecture(Condition *c) {
 }
 
 bool condition_test_host(Condition *c) {
+        _cleanup_free_ char *h = NULL;
         sd_id128_t x, y;
-        char *h;
         int r;
-        bool b;
 
         assert(c);
         assert(c->parameter);
@@ -199,10 +201,7 @@ bool condition_test_host(Condition *c) {
         if (!h)
                 return c->negate;
 
-        b = fnmatch(c->parameter, h, FNM_CASEFOLD) == 0;
-        free(h);
-
-        return b == !c->negate;
+        return (fnmatch(c->parameter, h, FNM_CASEFOLD) == 0) == !c->negate;
 }
 
 bool condition_test_ac_power(Condition *c) {
@@ -260,6 +259,8 @@ static const char* const condition_type_table[_CONDITION_TYPE_MAX] = {
         [CONDITION_HOST] = "ConditionHost",
         [CONDITION_AC_POWER] = "ConditionACPower",
         [CONDITION_ARCHITECTURE] = "ConditionArchitecture",
+        [CONDITION_NEEDS_UPDATE] = "ConditionNeedsUpdate",
+        [CONDITION_FIRST_BOOT] = "ConditionFirstBoot",
         [CONDITION_NULL] = "ConditionNull"
 };
 
index 63d945e..047fdbf 100644 (file)
@@ -44,6 +44,8 @@ typedef enum ConditionType {
         CONDITION_HOST,
         CONDITION_AC_POWER,
         CONDITION_ARCHITECTURE,
+        CONDITION_NEEDS_UPDATE,
+        CONDITION_FIRST_BOOT,
         CONDITION_NULL,
         _CONDITION_TYPE_MAX,
         _CONDITION_TYPE_INVALID = -1
index 5201782..c72a099 100644 (file)
 #include "hashmap.h"
 #include "conf-files.h"
 
-static int files_add(Hashmap *h, const char *dirpath, const char *suffix) {
+static int files_add(Hashmap *h, const char *root, const char *path, const char *suffix) {
         _cleanup_closedir_ DIR *dir = NULL;
+        char *dirpath;
+
+        assert(path);
+        assert(suffix);
+
+        dirpath = strappenda(root ? root : "", path);
 
         dir = opendir(dirpath);
         if (!dir) {
@@ -92,7 +98,7 @@ static int base_cmp(const void *a, const void *b) {
 }
 
 static int conf_files_list_strv_internal(char ***strv, const char *suffix, const char *root, char **dirs) {
-        Hashmap *fh;
+        _cleanup_hashmap_free_ Hashmap *fh = NULL;
         char **files, **p;
         int r;
 
@@ -100,7 +106,7 @@ static int conf_files_list_strv_internal(char ***strv, const char *suffix, const
         assert(suffix);
 
         /* This alters the dirs string array */
-        if (!path_strv_canonicalize_absolute_uniq(dirs, root))
+        if (!path_strv_resolve_uniq(dirs, root))
                 return -ENOMEM;
 
         fh = hashmap_new(string_hash_func, string_compare_func);
@@ -108,9 +114,8 @@ static int conf_files_list_strv_internal(char ***strv, const char *suffix, const
                 return -ENOMEM;
 
         STRV_FOREACH(p, dirs) {
-                r = files_add(fh, *p, suffix);
+                r = files_add(fh, root, *p, suffix);
                 if (r == -ENOMEM) {
-                        hashmap_free_free(fh);
                         return r;
                 } else if (r < 0)
                         log_debug("Failed to search for files in %s: %s",
@@ -119,14 +124,12 @@ static int conf_files_list_strv_internal(char ***strv, const char *suffix, const
 
         files = hashmap_get_strv(fh);
         if (files == NULL) {
-                hashmap_free_free(fh);
                 return -ENOMEM;
         }
 
         qsort_safe(files, hashmap_size(fh), sizeof(char *), base_cmp);
         *strv = files;
 
-        hashmap_free(fh);
         return 0;
 }
 
index cfa669b..439cfc5 100644 (file)
@@ -76,7 +76,7 @@ int log_syntax_internal(const char *unit, int level,
 }
 
 int config_item_table_lookup(
-                void *table,
+                const void *table,
                 const char *section,
                 const char *lvalue,
                 ConfigParserCallback *func,
@@ -84,7 +84,7 @@ int config_item_table_lookup(
                 void **data,
                 void *userdata) {
 
-        ConfigTableItem *t;
+        const ConfigTableItem *t;
 
         assert(table);
         assert(lvalue);
@@ -110,7 +110,7 @@ int config_item_table_lookup(
 }
 
 int config_item_perf_lookup(
-                void *table,
+                const void *table,
                 const char *section,
                 const char *lvalue,
                 ConfigParserCallback *func,
@@ -154,7 +154,7 @@ static int next_assignment(const char *unit,
                            const char *filename,
                            unsigned line,
                            ConfigItemLookup lookup,
-                           void *table,
+                           const void *table,
                            const char *section,
                            unsigned section_line,
                            const char *lvalue,
@@ -199,11 +199,12 @@ static int parse_line(const char* unit,
                       unsigned line,
                       const char *sections,
                       ConfigItemLookup lookup,
-                      void *table,
+                      const void *table,
                       bool relaxed,
                       bool allow_include,
                       char **section,
                       unsigned *section_line,
+                      bool *section_ignored,
                       char *l,
                       void *userdata) {
 
@@ -244,7 +245,7 @@ static int parse_line(const char* unit,
                 if (!fn)
                         return -ENOMEM;
 
-                return config_parse(unit, fn, NULL, sections, lookup, table, relaxed, false, userdata);
+                return config_parse(unit, fn, NULL, sections, lookup, table, relaxed, false, false, userdata);
         }
 
         if (*l == '[') {
@@ -266,7 +267,7 @@ static int parse_line(const char* unit,
 
                 if (sections && !nulstr_contains(sections, n)) {
 
-                        if (!relaxed)
+                        if (!relaxed && !startswith(n, "X-"))
                                 log_syntax(unit, LOG_WARNING, filename, line, EINVAL,
                                            "Unknown section '%s'. Ignoring.", n);
 
@@ -274,10 +275,12 @@ static int parse_line(const char* unit,
                         free(*section);
                         *section = NULL;
                         *section_line = 0;
+                        *section_ignored = true;
                 } else {
                         free(*section);
                         *section = n;
                         *section_line = line;
+                        *section_ignored = false;
                 }
 
                 return 0;
@@ -285,7 +288,7 @@ static int parse_line(const char* unit,
 
         if (sections && !*section) {
 
-                if (!relaxed)
+                if (!relaxed && !*section_ignored)
                         log_syntax(unit, LOG_WARNING, filename, line, EINVAL,
                                    "Assignment outside of section. Ignoring.");
 
@@ -320,14 +323,16 @@ int config_parse(const char *unit,
                  FILE *f,
                  const char *sections,
                  ConfigItemLookup lookup,
-                 void *table,
+                 const void *table,
                  bool relaxed,
                  bool allow_include,
+                 bool warn,
                  void *userdata) {
 
         _cleanup_free_ char *section = NULL, *continuation = NULL;
         _cleanup_fclose_ FILE *ours = NULL;
         unsigned line = 0, section_line = 0;
+        bool section_ignored = false;
         int r;
 
         assert(filename);
@@ -336,8 +341,12 @@ int config_parse(const char *unit,
         if (!f) {
                 f = ours = fopen(filename, "re");
                 if (!f) {
-                        log_error("Failed to open configuration file '%s': %m", filename);
-                        return -errno;
+                        /* Only log on request, except for ENOENT,
+                         * since we return 0 to the caller. */
+                        if (warn || errno == ENOENT)
+                                log_full(errno == ENOENT ? LOG_DEBUG : LOG_ERR,
+                                         "Failed to open configuration file '%s': %m", filename);
+                        return errno == ENOENT ? 0 : -errno;
                 }
         }
 
@@ -359,8 +368,11 @@ int config_parse(const char *unit,
 
                 if (continuation) {
                         c = strappend(continuation, l);
-                        if (!c)
+                        if (!c) {
+                                if (warn)
+                                        log_oom();
                                 return -ENOMEM;
+                        }
 
                         free(continuation);
                         continuation = NULL;
@@ -382,8 +394,11 @@ int config_parse(const char *unit,
                                 continuation = c;
                         else {
                                 continuation = strdup(l);
-                                if (!continuation)
+                                if (!continuation) {
+                                        if (warn)
+                                                log_oom();
                                         return -ENOMEM;
+                                }
                         }
 
                         continue;
@@ -399,12 +414,17 @@ int config_parse(const char *unit,
                                allow_include,
                                &section,
                                &section_line,
+                               &section_ignored,
                                p,
                                userdata);
                 free(c);
 
-                if (r < 0)
+                if (r < 0) {
+                        if (warn)
+                                log_warning("Failed to parse file '%s': %s",
+                                            filename, strerror(-r));
                         return r;
+                }
         }
 
         return 0;
@@ -565,90 +585,57 @@ int config_parse_bool(const char* unit,
         return 0;
 }
 
-int config_parse_show_status(const char* unit,
-                             const char *filename,
-                             unsigned line,
-                             const char *section,
-                             unsigned section_line,
-                             const char *lvalue,
-                             int ltype,
-                             const char *rvalue,
-                             void *data,
-                             void *userdata) {
+int config_parse_string(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
 
-        int k;
-        ShowStatus *b = data;
+        char **s = data, *n;
 
         assert(filename);
         assert(lvalue);
         assert(rvalue);
         assert(data);
 
-        k = parse_show_status(rvalue, b);
-        if (k < 0) {
-                log_syntax(unit, LOG_ERR, filename, line, -k,
-                           "Failed to parse show status setting, ignoring: %s", rvalue);
+        if (!utf8_is_valid(rvalue)) {
+                log_invalid_utf8(unit, LOG_ERR, filename, line, EINVAL, rvalue);
                 return 0;
         }
 
-        return 0;
-}
-
-int config_parse_string(const char *unit,
-                        const char *filename,
-                        unsigned line,
-                        const char *section,
-                        unsigned section_line,
-                        const char *lvalue,
-                        int ltype,
-                        const char *rvalue,
-                        void *data,
-                        void *userdata) {
-
-        char **s = data;
-        char *n;
-
-        assert(filename);
-        assert(lvalue);
-        assert(rvalue);
-        assert(data);
-
-        n = strdup(rvalue);
-        if (!n)
-                return log_oom();
-
-        if (!utf8_is_valid(n)) {
-                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
-                           "String is not UTF-8 clean, ignoring assignment: %s", rvalue);
-                free(n);
-                return 0;
+        if (isempty(rvalue))
+                n = NULL;
+        else {
+                n = strdup(rvalue);
+                if (!n)
+                        return log_oom();
         }
 
         free(*s);
-        if (*n)
-                *s = n;
-        else {
-                free(n);
-                *s = NULL;
-        }
+        *s = n;
 
         return 0;
 }
 
-int config_parse_path(const char *unit,
-                      const char *filename,
-                      unsigned line,
-                      const char *section,
-                      unsigned section_line,
-                      const char *lvalue,
-                      int ltype,
-                      const char *rvalue,
-                      void *data,
-                      void *userdata) {
+int config_parse_path(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
 
-        char **s = data;
-        char *n;
-        int offset;
+        char **s = data, *n;
 
         assert(filename);
         assert(lvalue);
@@ -656,16 +643,12 @@ int config_parse_path(const char *unit,
         assert(data);
 
         if (!utf8_is_valid(rvalue)) {
-                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
-                           "Path is not UTF-8 clean, ignoring assignment: %s", rvalue);
+                log_invalid_utf8(unit, LOG_ERR, filename, line, EINVAL, rvalue);
                 return 0;
         }
 
-        offset = rvalue[0] == '-' && (streq(lvalue, "InaccessibleDirectories") ||
-                                      streq(lvalue, "ReadOnlyDirectories"));
-        if (!path_is_absolute(rvalue + offset)) {
-                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
-                           "Not an absolute path, ignoring: %s", rvalue);
+        if (!path_is_absolute(rvalue)) {
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Not an absolute path, ignoring: %s", rvalue);
                 return 0;
         }
 
@@ -692,7 +675,8 @@ int config_parse_strv(const char *unit,
                       void *data,
                       void *userdata) {
 
-        char *** sv = data, *w, *state;
+        char ***sv = data;
+        const char *word, *state;
         size_t l;
         int r;
 
@@ -717,81 +701,25 @@ int config_parse_strv(const char *unit,
                 return 0;
         }
 
-        FOREACH_WORD_QUOTED(w, l, rvalue, state) {
-                _cleanup_free_ char *n;
-
-                n = cunescape_length(w, l);
-                if (!n)
-                        return log_oom();
-
-                if (!utf8_is_valid(n)) {
-                        log_syntax(unit, LOG_ERR, filename, line, EINVAL,
-                                   "String is not UTF-8 clean, ignoring: %s", rvalue);
-                        continue;
-                }
-
-                r = strv_extend(sv, n);
-                if (r < 0)
-                        return log_oom();
-        }
-
-        return 0;
-}
-
-int config_parse_path_strv(const char *unit,
-                           const char *filename,
-                           unsigned line,
-                           const char *section,
-                           unsigned section_line,
-                           const char *lvalue,
-                           int ltype,
-                           const char *rvalue,
-                           void *data,
-                           void *userdata) {
-
-        char*** sv = data, *w, *state;
-        size_t l;
-        int r;
-
-        assert(filename);
-        assert(lvalue);
-        assert(rvalue);
-        assert(data);
-
-        if (isempty(rvalue)) {
-                /* Empty assignment resets the list */
-                strv_free(*sv);
-                *sv = NULL;
-                return 0;
-        }
-
-        FOREACH_WORD_QUOTED(w, l, rvalue, state) {
-                _cleanup_free_ char *n;
-                int offset;
+        FOREACH_WORD_QUOTED(word, l, rvalue, state) {
+                char *n;
 
-                n = strndup(w, l);
+                n = strndup(word, l);
                 if (!n)
                         return log_oom();
 
                 if (!utf8_is_valid(n)) {
-                        log_syntax(unit, LOG_ERR, filename, line, EINVAL,
-                                   "Path is not UTF-8 clean, ignoring assignment: %s", rvalue);
+                        log_invalid_utf8(unit, LOG_ERR, filename, line, EINVAL, rvalue);
                         continue;
                 }
 
-                offset = n[0] == '-' && (streq(lvalue, "InaccessibleDirectories") ||
-                                         streq(lvalue, "ReadOnlyDirectories"));
-                if (!path_is_absolute(n + offset)) {
-                        log_syntax(unit, LOG_ERR, filename, line, EINVAL,
-                                   "Not an absolute path, ignoring: %s", rvalue);
-                        continue;
-                }
-
-                path_kill_slashes(n);
-                r = strv_extend(sv, n);
+                r = strv_consume(sv, n);
                 if (r < 0)
                         return log_oom();
         }
+        if (!isempty(state))
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                           "Trailing garbage, ignoring.");
 
         return 0;
 }
@@ -834,16 +762,17 @@ int config_parse_mode(const char *unit,
         return 0;
 }
 
-int config_parse_facility(const char *unit,
-                          const char *filename,
-                          unsigned line,
-                          const char *section,
-                          unsigned section_line,
-                          const char *lvalue,
-                          int ltype,
-                          const char *rvalue,
-                          void *data,
-                          void *userdata) {
+int config_parse_log_facility(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
 
 
         int *o = data, x;
@@ -865,16 +794,17 @@ int config_parse_facility(const char *unit,
         return 0;
 }
 
-int config_parse_level(const char *unit,
-                       const char *filename,
-                       unsigned line,
-                       const char *section,
-                       unsigned section_line,
-                       const char *lvalue,
-                       int ltype,
-                       const char *rvalue,
-                       void *data,
-                       void *userdata) {
+int config_parse_log_level(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
 
 
         int *o = data, x;
@@ -894,88 +824,3 @@ int config_parse_level(const char *unit,
         *o = (*o & LOG_FACMASK) | x;
         return 0;
 }
-
-int config_parse_set_status(const char *unit,
-                            const char *filename,
-                            unsigned line,
-                            const char *section,
-                            unsigned section_line,
-                            const char *lvalue,
-                            int ltype,
-                            const char *rvalue,
-                            void *data,
-                            void *userdata) {
-
-        char *w;
-        size_t l;
-        char *state;
-        int r;
-        ExitStatusSet *status_set = data;
-
-        assert(filename);
-        assert(lvalue);
-        assert(rvalue);
-        assert(data);
-
-        if (isempty(rvalue)) {
-                /* Empty assignment resets the list */
-
-                set_free(status_set->signal);
-                set_free(status_set->code);
-
-                status_set->signal = status_set->code = NULL;
-                return 0;
-        }
-
-        FOREACH_WORD(w, l, rvalue, state) {
-                int val;
-                char *temp;
-
-                temp = strndup(w, l);
-                if (!temp)
-                        return log_oom();
-
-                r = safe_atoi(temp, &val);
-                if (r < 0) {
-                        val = signal_from_string_try_harder(temp);
-                        free(temp);
-
-                        if (val > 0) {
-                                r = set_ensure_allocated(&status_set->signal, trivial_hash_func, trivial_compare_func);
-                                if (r < 0)
-                                        return log_oom();
-
-                                r = set_put(status_set->signal, INT_TO_PTR(val));
-                                if (r < 0) {
-                                        log_syntax(unit, LOG_ERR, filename, line, -r,
-                                                   "Unable to store: %s", w);
-                                        return r;
-                                }
-                        } else {
-                                log_syntax(unit, LOG_ERR, filename, line, -val,
-                                           "Failed to parse value, ignoring: %s", w);
-                                return 0;
-                        }
-                } else {
-                        free(temp);
-
-                        if (val < 0 || val > 255)
-                                log_syntax(unit, LOG_ERR, filename, line, ERANGE,
-                                           "Value %d is outside range 0-255, ignoring", val);
-                        else {
-                                r = set_ensure_allocated(&status_set->code, trivial_hash_func, trivial_compare_func);
-                                if (r < 0)
-                                        return log_oom();
-
-                                r = set_put(status_set->code, INT_TO_PTR(val));
-                                if (r < 0) {
-                                        log_syntax(unit, LOG_ERR, filename, line, -r,
-                                                   "Unable to store: %s", w);
-                                        return r;
-                                }
-                        }
-                }
-        }
-
-        return 0;
-}
index 4ccdadd..a17dde9 100644 (file)
@@ -52,7 +52,7 @@ typedef struct ConfigTableItem {
 } ConfigTableItem;
 
 /* Wraps information for parsing a specific configuration variable, to
- * ve srored in a gperf perfect hashtable */
+ * be stored in a gperf perfect hashtable */
 typedef struct ConfigPerfItem {
         const char *section_and_lvalue; /* Section + "." + name of the variable */
         ConfigParserCallback parse;     /* Function that is called to parse the variable's value */
@@ -65,7 +65,7 @@ typedef const ConfigPerfItem* (*ConfigPerfItemLookup)(const char *section_and_lv
 
 /* Prototype for a generic high-level lookup function */
 typedef int (*ConfigItemLookup)(
-                void *table,
+                const void *table,
                 const char *section,
                 const char *lvalue,
                 ConfigParserCallback *func,
@@ -75,20 +75,21 @@ typedef int (*ConfigItemLookup)(
 
 /* Linear table search implementation of ConfigItemLookup, based on
  * ConfigTableItem arrays */
-int config_item_table_lookup(void *table, const char *section, const char *lvalue, ConfigParserCallback *func, int *ltype, void **data, void *userdata);
+int config_item_table_lookup(const void *table, const char *section, const char *lvalue, ConfigParserCallback *func, int *ltype, void **data, void *userdata);
 
 /* gperf implementation of ConfigItemLookup, based on gperf
  * ConfigPerfItem tables */
-int config_item_perf_lookup(void *table, const char *section, const char *lvalue, ConfigParserCallback *func, int *ltype, void **data, void *userdata);
+int config_item_perf_lookup(const void *table, const char *section, const char *lvalue, ConfigParserCallback *func, int *ltype, void **data, void *userdata);
 
 int config_parse(const char *unit,
                  const char *filename,
                  FILE *f,
                  const char *sections,  /* nulstr */
                  ConfigItemLookup lookup,
-                 void *table,
+                 const void *table,
                  bool relaxed,
                  bool allow_include,
+                 bool warn,
                  void *userdata);
 
 /* Generic parsers */
@@ -101,17 +102,14 @@ int config_parse_iec_size(const char *unit, const char *filename, unsigned line,
 int config_parse_si_size(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_iec_off(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_bool(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_show_status(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_string(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_path(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_strv(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_path_strv(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_sec(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_nsec(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_facility(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_level(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_set_status(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_log_facility(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_log_level(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 
 int log_syntax_internal(const char *unit, int level,
                         const char *file, unsigned line, const char *func,
@@ -124,6 +122,12 @@ int log_syntax_internal(const char *unit, int level,
                             config_file, config_line,                   \
                             error, __VA_ARGS__)
 
+#define log_invalid_utf8(unit, level, config_file, config_line, error, rvalue) { \
+        _cleanup_free_ char *__p = utf8_escape_invalid(rvalue);                  \
+        log_syntax(unit, level, config_file, config_line, error,                 \
+                   "String is not UTF-8 clean, ignoring assignment: %s", __p);   \
+        }
+
 #define DEFINE_CONFIG_PARSE_ENUM(function,name,type,msg)                \
         int function(const char *unit,                                  \
                      const char *filename,                              \
@@ -166,7 +170,7 @@ int log_syntax_internal(const char *unit, int level,
                      void *userdata) {                                         \
                                                                                \
                 type **enums = data, *xs, x, *ys;                              \
-                char *w, *state;                                               \
+                const char *word, *state;                                      \
                 size_t l, i = 0;                                               \
                                                                                \
                 assert(filename);                                              \
@@ -177,10 +181,10 @@ int log_syntax_internal(const char *unit, int level,
                 xs = new0(type, 1);                                            \
                 *xs = invalid;                                                 \
                                                                                \
-                FOREACH_WORD(w, l, rvalue, state) {                            \
+                FOREACH_WORD(word, l, rvalue, state) {                         \
                         _cleanup_free_ char *en = NULL;                        \
                                                                                \
-                        en = strndup(w, l);                                    \
+                        en = strndup(word, l);                                 \
                         if (!en)                                               \
                                 return -ENOMEM;                                \
                                                                                \
diff --git a/src/shared/copy.c b/src/shared/copy.c
new file mode 100644 (file)
index 0000000..3744797
--- /dev/null
@@ -0,0 +1,296 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "util.h"
+#include "copy.h"
+
+int copy_bytes(int fdf, int fdt, off_t max_bytes) {
+        assert(fdf >= 0);
+        assert(fdt >= 0);
+
+        for (;;) {
+                char buf[PIPE_BUF];
+                ssize_t n, k;
+                size_t m = sizeof(buf);
+
+                if (max_bytes != (off_t) -1) {
+
+                        if (max_bytes <= 0)
+                                return -E2BIG;
+
+                        if ((off_t) m > max_bytes)
+                                m = (size_t) max_bytes;
+                }
+
+                n = read(fdf, buf, m);
+                if (n < 0)
+                        return -errno;
+                if (n == 0)
+                        break;
+
+                errno = 0;
+                k = loop_write(fdt, buf, n, false);
+                if (k < 0)
+                        return k;
+                if (k != n)
+                        return errno ? -errno : -EIO;
+
+                if (max_bytes != (off_t) -1) {
+                        assert(max_bytes >= n);
+                        max_bytes -= n;
+                }
+        }
+
+        return 0;
+}
+
+static int fd_copy_symlink(int df, const char *from, const struct stat *st, int dt, const char *to) {
+        _cleanup_free_ char *target = NULL;
+        int r;
+
+        assert(from);
+        assert(st);
+        assert(to);
+
+        r = readlinkat_malloc(df, from, &target);
+        if (r < 0)
+                return r;
+
+        if (symlinkat(target, dt, to) < 0)
+                return -errno;
+
+        if (fchownat(dt, to, st->st_uid, st->st_gid, AT_SYMLINK_NOFOLLOW) < 0)
+                return -errno;
+
+        return 0;
+}
+
+static int fd_copy_regular(int df, const char *from, const struct stat *st, int dt, const char *to) {
+        _cleanup_close_ int fdf = -1, fdt = -1;
+        int r, q;
+
+        assert(from);
+        assert(st);
+        assert(to);
+
+        fdf = openat(df, from, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
+        if (fdf < 0)
+                return -errno;
+
+        fdt = openat(dt, to, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, st->st_mode & 07777);
+        if (fdt < 0)
+                return -errno;
+
+        r = copy_bytes(fdf, fdt, (off_t) -1);
+        if (r < 0) {
+                unlinkat(dt, to, 0);
+                return r;
+        }
+
+        if (fchown(fdt, st->st_uid, st->st_gid) < 0)
+                r = -errno;
+
+        if (fchmod(fdt, st->st_mode & 07777) < 0)
+                r = -errno;
+
+        q = close(fdt);
+        fdt = -1;
+
+        if (q < 0) {
+                r = -errno;
+                unlinkat(dt, to, 0);
+        }
+
+        return r;
+}
+
+static int fd_copy_fifo(int df, const char *from, const struct stat *st, int dt, const char *to) {
+        int r;
+
+        assert(from);
+        assert(st);
+        assert(to);
+
+        r = mkfifoat(dt, to, st->st_mode & 07777);
+        if (r < 0)
+                return -errno;
+
+        if (fchownat(dt, to, st->st_uid, st->st_gid, AT_SYMLINK_NOFOLLOW) < 0)
+                r = -errno;
+
+        if (fchmodat(dt, to, st->st_mode & 07777, 0) < 0)
+                r = -errno;
+
+        return r;
+}
+
+static int fd_copy_node(int df, const char *from, const struct stat *st, int dt, const char *to) {
+        int r;
+
+        assert(from);
+        assert(st);
+        assert(to);
+
+        r = mknodat(dt, to, st->st_mode, st->st_rdev);
+        if (r < 0)
+                return -errno;
+
+        if (fchownat(dt, to, st->st_uid, st->st_gid, AT_SYMLINK_NOFOLLOW) < 0)
+                r = -errno;
+
+        if (fchmodat(dt, to, st->st_mode & 07777, 0) < 0)
+                r = -errno;
+
+        return r;
+}
+
+static int fd_copy_directory(int df, const char *from, const struct stat *st, int dt, const char *to, dev_t original_device, bool merge) {
+        _cleanup_close_ int fdf = -1, fdt = -1;
+        _cleanup_closedir_ DIR *d = NULL;
+        struct dirent *de;
+        bool created;
+        int r;
+
+        assert(from);
+        assert(st);
+        assert(to);
+
+        fdf = openat(df, from, O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
+        if (fdf < 0)
+                return -errno;
+
+        d = fdopendir(fdf);
+        if (!d)
+                return -errno;
+        fdf = -1;
+
+        r = mkdirat(dt, to, st->st_mode & 07777);
+        if (r >= 0)
+                created = true;
+        else if (errno == EEXIST && merge)
+                created = false;
+        else
+                return -errno;
+
+        fdt = openat(dt, to, O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
+        if (fdt < 0)
+                return -errno;
+
+        r = 0;
+
+        if (created) {
+                if (fchown(fdt, st->st_uid, st->st_gid) < 0)
+                        r = -errno;
+
+                if (fchmod(fdt, st->st_mode & 07777) < 0)
+                        r = -errno;
+        }
+
+        FOREACH_DIRENT(de, d, return -errno) {
+                struct stat buf;
+                int q;
+
+                if (fstatat(dirfd(d), de->d_name, &buf, AT_SYMLINK_NOFOLLOW) < 0) {
+                        r = -errno;
+                        continue;
+                }
+
+                if (buf.st_dev != original_device)
+                        continue;
+
+                if (S_ISREG(buf.st_mode))
+                        q = fd_copy_regular(dirfd(d), de->d_name, &buf, fdt, de->d_name);
+                else if (S_ISDIR(buf.st_mode))
+                        q = fd_copy_directory(dirfd(d), de->d_name, &buf, fdt, de->d_name, original_device, merge);
+                else if (S_ISLNK(buf.st_mode))
+                        q = fd_copy_symlink(dirfd(d), de->d_name, &buf, fdt, de->d_name);
+                else if (S_ISFIFO(buf.st_mode))
+                        q = fd_copy_fifo(dirfd(d), de->d_name, &buf, fdt, de->d_name);
+                else if (S_ISBLK(buf.st_mode) || S_ISCHR(buf.st_mode))
+                        q = fd_copy_node(dirfd(d), de->d_name, &buf, fdt, de->d_name);
+                else
+                        q = -ENOTSUP;
+
+                if (q == -EEXIST && merge)
+                        q = 0;
+
+                if (q < 0)
+                        r = q;
+        }
+
+        return r;
+}
+
+int copy_tree(const char *from, const char *to, bool merge) {
+        struct stat st;
+
+        assert(from);
+        assert(to);
+
+        if (lstat(from, &st) < 0)
+                return -errno;
+
+        if (S_ISREG(st.st_mode))
+                return fd_copy_regular(AT_FDCWD, from, &st, AT_FDCWD, to);
+        else if (S_ISDIR(st.st_mode))
+                return fd_copy_directory(AT_FDCWD, from, &st, AT_FDCWD, to, st.st_dev, merge);
+        else if (S_ISLNK(st.st_mode))
+                return fd_copy_symlink(AT_FDCWD, from, &st, AT_FDCWD, to);
+        else if (S_ISFIFO(st.st_mode))
+                return fd_copy_fifo(AT_FDCWD, from, &st, AT_FDCWD, to);
+        else if (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode))
+                return fd_copy_node(AT_FDCWD, from, &st, AT_FDCWD, to);
+        else
+                return -ENOTSUP;
+}
+
+int copy_file(const char *from, const char *to, int flags, mode_t mode) {
+        _cleanup_close_ int fdf = -1, fdt = -1;
+        int r;
+
+        assert(from);
+        assert(to);
+
+        fdf = open(from, O_RDONLY|O_CLOEXEC|O_NOCTTY);
+        if (fdf < 0)
+                return -errno;
+
+        fdt = open(to, flags|O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, mode);
+        if (fdt < 0)
+                return -errno;
+
+        r = copy_bytes(fdf, fdt, (off_t) -1);
+        if (r < 0) {
+                unlink(to);
+                return r;
+        }
+
+        r = close(fdt);
+        fdt = -1;
+
+        if (r < 0) {
+                r = -errno;
+                unlink(to);
+                return r;
+        }
+
+        return 0;
+}
diff --git a/src/shared/copy.h b/src/shared/copy.h
new file mode 100644 (file)
index 0000000..0bf2598
--- /dev/null
@@ -0,0 +1,26 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+int copy_file(const char *from, const char *to, int flags, mode_t mode);
+int copy_tree(const char *from, const char *to, bool merge);
+int copy_bytes(int fdf, int fdt, off_t max_bytes);
index 7777756..9721e35 100644 (file)
@@ -61,7 +61,7 @@
         "/usr/lib/kbd/keymaps/\0"
 #endif
 
-#define UNIX_SYSTEM_BUS_PATH "unix:path=/run/dbus/system_bus_socket"
+#define UNIX_SYSTEM_BUS_PATH "unix:path=/var/run/dbus/system_bus_socket"
 #define KERNEL_SYSTEM_BUS_PATH "kernel:path=/dev/kdbus/0-system/bus"
 
 #ifdef ENABLE_KDBUS
 #endif
 
 #define UNIX_USER_BUS_FMT "unix:path=%s/bus"
-#define KERNEL_USER_BUS_FMT "kernel:path=/dev/kdbus/%lu-user/bus"
+#define KERNEL_USER_BUS_FMT "kernel:path=/dev/kdbus/"UID_FMT"-user/bus"
+
+#define PLYMOUTH_SOCKET {                                       \
+                .un.sun_family = AF_UNIX,                       \
+                .un.sun_path = "\0/org/freedesktop/plymouthd",  \
+        }
 
 #ifndef TTY_GID
 #define TTY_GID 5
 #endif
+
+#ifndef RUN_GID
+#define RUN_GID        0
+#endif
index e025e17..1a565d5 100644 (file)
@@ -64,7 +64,7 @@ int dev_setup(const char *prefix) {
                 if (j[0] == '-') {
                         j++;
 
-                        if (access(j, F_OK))
+                        if (access(j, F_OK) < 0)
                                 continue;
                 }
 
index 9837375..73e9edd 100644 (file)
@@ -41,7 +41,7 @@ int encode_devnode_name(const char *str, char *str_enc, size_t len) {
         size_t i, j;
 
         if (str == NULL || str_enc == NULL)
-                return -1;
+                return -EINVAL;
 
         for (i = 0, j = 0; str[i] != '\0'; i++) {
                 int seqlen;
@@ -70,5 +70,5 @@ int encode_devnode_name(const char *str, char *str_enc, size_t len) {
         str_enc[j] = '\0';
         return 0;
 err:
-        return -1;
+        return -EINVAL;
 }
diff --git a/src/shared/dropin.c b/src/shared/dropin.c
new file mode 100644 (file)
index 0000000..ac09be9
--- /dev/null
@@ -0,0 +1,102 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Zbigniew Jędrzejewski-Szmek
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "dropin.h"
+#include "util.h"
+#include "mkdir.h"
+#include "fileio-label.h"
+
+int drop_in_file(const char *dir, const char *unit, unsigned level,
+                 const char *name, char **_p, char **_q) {
+
+        _cleanup_free_ char *b = NULL;
+        char *p, *q;
+
+        char prefix[DECIMAL_STR_MAX(unsigned)];
+
+        assert(unit);
+        assert(name);
+        assert(_p);
+        assert(_q);
+
+        sprintf(prefix, "%u", level);
+
+        b = xescape(name, "/.");
+        if (!b)
+                return -ENOMEM;
+
+        if (!filename_is_safe(b))
+                return -EINVAL;
+
+        p = strjoin(dir, "/", unit, ".d", NULL);
+        if (!p)
+                return -ENOMEM;
+
+        q = strjoin(p, "/", prefix, "-", b, ".conf", NULL);
+        if (!q) {
+                free(p);
+                return -ENOMEM;
+        }
+
+        *_p = p;
+        *_q = q;
+        return 0;
+}
+
+int write_drop_in(const char *dir, const char *unit, unsigned level,
+                  const char *name, const char *data) {
+
+        _cleanup_free_ char *p = NULL, *q = NULL;
+        int r;
+
+        assert(dir);
+        assert(unit);
+        assert(name);
+        assert(data);
+
+        r = drop_in_file(dir, unit, level, name, &p, &q);
+        if (r < 0)
+                return r;
+
+        mkdir_p(p, 0755);
+        return write_string_file_atomic_label(q, data);
+}
+
+int write_drop_in_format(const char *dir, const char *unit, unsigned level,
+                         const char *name, const char *format, ...) {
+        _cleanup_free_ char *p = NULL;
+        va_list ap;
+        int r;
+
+        assert(dir);
+        assert(unit);
+        assert(name);
+        assert(format);
+
+        va_start(ap, format);
+        r = vasprintf(&p, format, ap);
+        va_end(ap);
+
+        if (r < 0)
+                return -ENOMEM;
+
+        return write_drop_in(dir, unit, level, name, p);
+}
diff --git a/src/shared/dropin.h b/src/shared/dropin.h
new file mode 100644 (file)
index 0000000..9c9742d
--- /dev/null
@@ -0,0 +1,33 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Zbigniew Jędrzejewski-Szmek
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "macro.h"
+
+int drop_in_file(const char *dir, const char *unit, unsigned level,
+                 const char *name, char **_p, char **_q);
+
+int write_drop_in(const char *dir, const char *unit, unsigned level,
+                  const char *name, const char *data);
+
+int write_drop_in_format(const char *dir, const char *unit, unsigned level,
+                         const char *name, const char *format, ...) _printf_(5, 6);
index 5ee8f1e..a319574 100644 (file)
@@ -330,7 +330,7 @@ static int boot_id_hex(const char s[4]) {
                 else if (s[i] >= 'A' && s[i] <= 'F')
                         id |= (s[i] - 'A' + 10) << (3 - i) * 4;
                 else
-                        return -1;
+                        return -EINVAL;
 
         return id;
 }
@@ -440,9 +440,6 @@ int efi_loader_get_boot_usec(usec_t *firmware, usec_t *loader) {
 int efi_loader_get_device_part_uuid(sd_id128_t *u) {
         _cleanup_free_ char *p = NULL;
         int r, parsed[16];
-        unsigned i;
-
-        assert(u);
 
         r = efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderDevicePartUUID", &p);
         if (r < 0)
@@ -455,8 +452,12 @@ int efi_loader_get_device_part_uuid(sd_id128_t *u) {
                    &parsed[12], &parsed[13], &parsed[14], &parsed[15]) != 16)
                 return -EIO;
 
-        for (i = 0; i < ELEMENTSOF(parsed); i++)
-                u->bytes[i] = parsed[i];
+        if (u) {
+                unsigned i;
+
+                for (i = 0; i < ELEMENTSOF(parsed); i++)
+                        u->bytes[i] = parsed[i];
+        }
 
         return 0;
 }
index b2e4553..20b208f 100644 (file)
@@ -78,7 +78,9 @@ bool env_value_is_valid(const char *e) {
         if (!utf8_is_valid(e))
                 return false;
 
-        if (string_has_cc(e))
+        /* bash allows tabs in environment variables, and so should
+         * we */
+        if (string_has_cc(e, "\t"))
                 return false;
 
         /* POSIX says the overall size of the environment block cannot
index 902f55a..f3434f7 100644 (file)
@@ -113,9 +113,6 @@ const char* exit_status_to_string(ExitStatus status, ExitStatusLevel level) {
                 case EXIT_STDERR:
                         return "STDERR";
 
-                case EXIT_TCPWRAP:
-                        return "TCPWRAP";
-
                 case EXIT_PAM:
                         return "PAM";
 
@@ -139,6 +136,18 @@ const char* exit_status_to_string(ExitStatus status, ExitStatusLevel level) {
 
                 case EXIT_APPARMOR_PROFILE:
                         return "APPARMOR";
+
+                case EXIT_ADDRESS_FAMILIES:
+                        return "ADDRESS_FAMILIES";
+
+                case EXIT_RUNTIME_DIRECTORY:
+                        return "RUNTIME_DIRECTORY";
+
+                case EXIT_CHOWN:
+                        return "CHOWN";
+
+                case EXIT_MAKE_STARTER:
+                        return "MAKE_STARTER";
                 }
         }
 
@@ -174,7 +183,7 @@ bool is_clean_exit(int code, int status, ExitStatusSet *success_status) {
         if (code == CLD_EXITED)
                 return status == 0 ||
                        (success_status &&
-                       set_contains(success_status->code, INT_TO_PTR(status)));
+                       set_contains(success_status->status, INT_TO_PTR(status)));
 
         /* If a daemon does not implement handlers for some of the
          * signals that's not considered an unclean shutdown */
@@ -200,19 +209,17 @@ bool is_clean_exit_lsb(int code, int status, ExitStatusSet *success_status) {
                 (status == EXIT_NOTINSTALLED || status == EXIT_NOTCONFIGURED);
 }
 
-int parse_show_status(const char *v, ShowStatus *ret) {
-        int r;
+void exit_status_set_free(ExitStatusSet *x) {
+        assert(x);
 
-        assert(v);
-        assert(ret);
+        set_free(x->status);
+        set_free(x->signal);
+        x->status = x->signal = NULL;
+}
 
-        if (streq(v, "auto")) {
-                *ret = SHOW_STATUS_AUTO;
-                return 0;
-        }
-        r = parse_boolean(v);
-        if (r < 0)
-                return r;
-        *ret = r ? SHOW_STATUS_YES : SHOW_STATUS_NO;
-        return 0;
+bool exit_status_set_is_empty(ExitStatusSet *x) {
+        if (!x)
+                return true;
+
+        return set_isempty(x->status) && set_isempty(x->signal);
 }
index de379f1..603a77f 100644 (file)
@@ -22,7 +22,9 @@
 ***/
 
 #include <stdbool.h>
+
 #include "set.h"
+
 typedef enum ExitStatus {
         /* EXIT_SUCCESS defined by libc */
         /* EXIT_FAILURE defined by libc */
@@ -62,7 +64,7 @@ typedef enum ExitStatus {
         EXIT_SETSID,   /* 220 */
         EXIT_CONFIRM,
         EXIT_STDERR,
-        EXIT_TCPWRAP,
+        _EXIT_RESERVED, /* used to be tcpwrap, don't reuse! */
         EXIT_PAM,
         EXIT_NETWORK,
         EXIT_NAMESPACE,
@@ -70,7 +72,12 @@ typedef enum ExitStatus {
         EXIT_SECCOMP,
         EXIT_SELINUX_CONTEXT,
         EXIT_PERSONALITY,  /* 230 */
-        EXIT_APPARMOR_PROFILE
+        EXIT_APPARMOR_PROFILE,
+        EXIT_ADDRESS_FAMILIES,
+        EXIT_RUNTIME_DIRECTORY,
+        EXIT_MAKE_STARTER,
+        EXIT_CHOWN,
+        EXIT_SMACK_PROCESS_LABEL,
 } ExitStatus;
 
 typedef enum ExitStatusLevel {
@@ -81,7 +88,7 @@ typedef enum ExitStatusLevel {
 } ExitStatusLevel;
 
 typedef struct ExitStatusSet {
-        Set *code;
+        Set *status;
         Set *signal;
 } ExitStatusSet;
 
@@ -90,14 +97,5 @@ const char* exit_status_to_string(ExitStatus status, ExitStatusLevel level) _con
 bool is_clean_exit(int code, int status, ExitStatusSet *success_status);
 bool is_clean_exit_lsb(int code, int status, ExitStatusSet *success_status);
 
-/* Manager status */
-
-typedef enum ShowStatus {
-        _SHOW_STATUS_UNSET = -2,
-        SHOW_STATUS_AUTO = -1,
-        SHOW_STATUS_NO = 0,
-        SHOW_STATUS_YES = 1,
-        SHOW_STATUS_TEMPORARY = 2,
-} ShowStatus;
-
-int parse_show_status(const char *v, ShowStatus *ret);
+void exit_status_set_free(ExitStatusSet *x);
+bool exit_status_set_is_empty(ExitStatusSet *x);
index fd27398..d2ea665 100644 (file)
@@ -82,7 +82,7 @@ int fdset_put_dup(FDSet *s, int fd) {
 
         r = fdset_put(s, copy);
         if (r < 0) {
-                close_nointr_nofail(copy);
+                safe_close(copy);
                 return r;
         }
 
@@ -104,7 +104,7 @@ int fdset_remove(FDSet *s, int fd) {
 }
 
 int fdset_new_fill(FDSet **_s) {
-        DIR *d;
+        _cleanup_closedir_ DIR *d = NULL;
         struct dirent *de;
         int r = 0;
         FDSet *s;
@@ -150,8 +150,6 @@ int fdset_new_fill(FDSet **_s) {
         s = NULL;
 
 finish:
-        closedir(d);
-
         /* We won't close the fds here! */
         if (s)
                 set_free(MAKE_SET(s));
index 0711826..c3def3c 100644 (file)
 
 #include "fileio-label.h"
 #include "label.h"
+#include "util.h"
 
 int write_string_file_atomic_label(const char *fn, const char *line) {
         int r;
 
         r = label_context_set(fn, S_IFREG);
-        if (r  < 0)
+        if (r < 0)
                 return r;
 
         write_string_file_atomic(fn, line);
@@ -44,7 +45,7 @@ int write_env_file_label(const char *fname, char **l) {
         int r;
 
         r = label_context_set(fname, S_IFREG);
-        if (r  < 0)
+        if (r < 0)
                 return r;
 
         write_env_file(fname, l);
@@ -53,3 +54,18 @@ int write_env_file_label(const char *fname, char **l) {
 
         return r;
 }
+
+int fopen_temporary_label(const char *target,
+                          const char *path, FILE **f, char **temp_path) {
+        int r;
+
+        r = label_context_set(target, S_IFREG);
+        if (r < 0)
+                return r;
+
+        r = fopen_temporary(path, f, temp_path);
+
+        label_context_clear();
+
+        return r;
+}
index fce4fe0..25fa351 100644 (file)
@@ -27,3 +27,5 @@
 
 int write_string_file_atomic_label(const char *fn, const char *line);
 int write_env_file_label(const char *fname, char **l);
+int fopen_temporary_label(const char *target,
+                          const char *path, FILE **f, char **temp_path);
index 0d3f2e9..18960ab 100644 (file)
 #include "utf8.h"
 #include "ctype.h"
 
-int write_string_to_file(FILE *f, const char *line) {
+int write_string_stream(FILE *f, const char *line) {
+        assert(f);
+        assert(line);
+
         errno = 0;
+
         fputs(line, f);
         if (!endswith(line, "\n"))
                 fputc('\n', f);
@@ -51,7 +55,29 @@ int write_string_file(const char *fn, const char *line) {
         if (!f)
                 return -errno;
 
-        return write_string_to_file(f, line);
+        return write_string_stream(f, line);
+}
+
+int write_string_file_no_create(const char *fn, const char *line) {
+        _cleanup_fclose_ FILE *f = NULL;
+        int fd;
+
+        assert(fn);
+        assert(line);
+
+        /* We manually build our own version of fopen(..., "we") that
+         * without O_CREAT */
+        fd = open(fn, O_WRONLY|O_CLOEXEC|O_NOCTTY);
+        if (fd < 0)
+                return -errno;
+
+        f = fdopen(fd, "we");
+        if (!f) {
+                safe_close(fd);
+                return -errno;
+        }
+
+        return write_string_stream(f, line);
 }
 
 int write_string_file_atomic(const char *fn, const char *line) {
@@ -189,29 +215,33 @@ ssize_t sendfile_full(int out_fd, const char *fn) {
         return (ssize_t) l;
 }
 
-int read_full_file(const char *fn, char **contents, size_t *size) {
-        _cleanup_fclose_ FILE *f = NULL;
+int read_full_stream(FILE *f, char **contents, size_t *size) {
         size_t n, l;
         _cleanup_free_ char *buf = NULL;
         struct stat st;
 
-        assert(fn);
+        assert(f);
         assert(contents);
 
-        f = fopen(fn, "re");
-        if (!f)
-                return -errno;
-
         if (fstat(fileno(f), &st) < 0)
                 return -errno;
 
-        /* Safety check */
-        if (st.st_size > 4*1024*1024)
-                return -E2BIG;
+        n = LINE_MAX;
 
-        n = st.st_size > 0 ? st.st_size : LINE_MAX;
-        l = 0;
+        if (S_ISREG(st.st_mode)) {
 
+                /* Safety check */
+                if (st.st_size > 4*1024*1024)
+                        return -E2BIG;
+
+                /* Start with the right file size, but be prepared for
+                 * files from /proc which generally report a file size
+                 * of 0 */
+                if (st.st_size > 0)
+                        n = st.st_size;
+        }
+
+        l = 0;
         for (;;) {
                 char *t;
                 size_t k;
@@ -248,7 +278,21 @@ int read_full_file(const char *fn, char **contents, size_t *size) {
         return 0;
 }
 
+int read_full_file(const char *fn, char **contents, size_t *size) {
+        _cleanup_fclose_ FILE *f = NULL;
+
+        assert(fn);
+        assert(contents);
+
+        f = fopen(fn, "re");
+        if (!f)
+                return -errno;
+
+        return read_full_stream(f, contents, size);
+}
+
 static int parse_env_file_internal(
+                FILE *f,
                 const char *fname,
                 const char *newline,
                 int (*push) (const char *filename, unsigned line,
@@ -275,10 +319,12 @@ static int parse_env_file_internal(
                 COMMENT_ESCAPE
         } state = PRE_KEY;
 
-        assert(fname);
         assert(newline);
 
-        r = read_full_file(fname, &contents, NULL);
+        if (f)
+                r = read_full_stream(f, &contents, NULL);
+        else
+                r = read_full_file(fname, &contents, NULL);
         if (r < 0)
                 return r;
 
@@ -294,7 +340,7 @@ static int parse_env_file_internal(
                                 state = KEY;
                                 last_key_whitespace = (size_t) -1;
 
-                                if (!greedy_realloc((void**) &key, &key_alloc, n_key+2)) {
+                                if (!GREEDY_REALLOC(key, key_alloc, n_key+2)) {
                                         r = -ENOMEM;
                                         goto fail;
                                 }
@@ -317,7 +363,7 @@ static int parse_env_file_internal(
                                 else if (last_key_whitespace == (size_t) -1)
                                          last_key_whitespace = n_key;
 
-                                if (!greedy_realloc((void**) &key, &key_alloc, n_key+2)) {
+                                if (!GREEDY_REALLOC(key, key_alloc, n_key+2)) {
                                         r = -ENOMEM;
                                         goto fail;
                                 }
@@ -357,7 +403,7 @@ static int parse_env_file_internal(
                         else if (!strchr(WHITESPACE, c)) {
                                 state = VALUE;
 
-                                if (!greedy_realloc((void**) &value, &value_alloc, n_value+2)) {
+                                if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) {
                                         r = -ENOMEM;
                                         goto fail;
                                 }
@@ -402,7 +448,7 @@ static int parse_env_file_internal(
                                 else if (last_value_whitespace == (size_t) -1)
                                         last_value_whitespace = n_value;
 
-                                if (!greedy_realloc((void**) &value, &value_alloc, n_value+2)) {
+                                if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) {
                                         r = -ENOMEM;
                                         goto fail;
                                 }
@@ -417,7 +463,7 @@ static int parse_env_file_internal(
 
                         if (!strchr(newline, c)) {
                                 /* Escaped newlines we eat up entirely */
-                                if (!greedy_realloc((void**) &value, &value_alloc, n_value+2)) {
+                                if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) {
                                         r = -ENOMEM;
                                         goto fail;
                                 }
@@ -432,7 +478,7 @@ static int parse_env_file_internal(
                         else if (c == '\\')
                                 state = SINGLE_QUOTE_VALUE_ESCAPE;
                         else {
-                                if (!greedy_realloc((void**) &value, &value_alloc, n_value+2)) {
+                                if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) {
                                         r = -ENOMEM;
                                         goto fail;
                                 }
@@ -446,7 +492,7 @@ static int parse_env_file_internal(
                         state = SINGLE_QUOTE_VALUE;
 
                         if (!strchr(newline, c)) {
-                                if (!greedy_realloc((void**) &value, &value_alloc, n_value+2)) {
+                                if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) {
                                         r = -ENOMEM;
                                         goto fail;
                                 }
@@ -461,7 +507,7 @@ static int parse_env_file_internal(
                         else if (c == '\\')
                                 state = DOUBLE_QUOTE_VALUE_ESCAPE;
                         else {
-                                if (!greedy_realloc((void**) &value, &value_alloc, n_value+2)) {
+                                if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) {
                                         r = -ENOMEM;
                                         goto fail;
                                 }
@@ -475,7 +521,7 @@ static int parse_env_file_internal(
                         state = DOUBLE_QUOTE_VALUE;
 
                         if (!strchr(newline, c)) {
-                                if (!greedy_realloc((void**) &value, &value_alloc, n_value+2)) {
+                                if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) {
                                         r = -ENOMEM;
                                         goto fail;
                                 }
@@ -532,25 +578,27 @@ fail:
         return r;
 }
 
-static int parse_env_file_push(const char *filename, unsigned line,
-                               const char *key, char *value, void *userdata) {
+static int parse_env_file_push(
+                const char *filename, unsigned line,
+                const char *key, char *value,
+                void *userdata) {
 
         const char *k;
         va_list aq, *ap = userdata;
 
         if (!utf8_is_valid(key)) {
-                _cleanup_free_ char *p = utf8_escape_invalid(key);
+                _cleanup_free_ char *p;
 
-                log_error("%s:%u: invalid UTF-8 in key '%s', ignoring.",
-                          filename, line, p);
+                p = utf8_escape_invalid(key);
+                log_error("%s:%u: invalid UTF-8 in key '%s', ignoring.", strna(filename), line, p);
                 return -EINVAL;
         }
 
         if (value && !utf8_is_valid(value)) {
-                _cleanup_free_ char *p = utf8_escape_invalid(value);
+                _cleanup_free_ char *p;
 
-                log_error("%s:%u: invalid UTF-8 value for key %s: '%s', ignoring.",
-                          filename, line, key, p);
+                p = utf8_escape_invalid(value);
+                log_error("%s:%u: invalid UTF-8 value for key %s: '%s', ignoring.", strna(filename), line, key, p);
                 return -EINVAL;
         }
 
@@ -571,6 +619,7 @@ static int parse_env_file_push(const char *filename, unsigned line,
 
         va_end(aq);
         free(value);
+
         return 0;
 }
 
@@ -585,28 +634,31 @@ int parse_env_file(
                 newline = NEWLINE;
 
         va_start(ap, newline);
-        r = parse_env_file_internal(fname, newline, parse_env_file_push, &ap);
+        r = parse_env_file_internal(NULL, fname, newline, parse_env_file_push, &ap);
         va_end(ap);
 
         return r;
 }
 
-static int load_env_file_push(const char *filename, unsigned line,
-                              const char *key, char *value, void *userdata) {
+static int load_env_file_push(
+                const char *filename, unsigned line,
+                const char *key, char *value,
+                void *userdata) {
         char ***m = userdata;
         char *p;
         int r;
 
         if (!utf8_is_valid(key)) {
-                log_error("%s:%u: invalid UTF-8 for key '%s', ignoring.",
-                          filename, line, key);
+                _cleanup_free_ char *t = utf8_escape_invalid(key);
+
+                log_error("%s:%u: invalid UTF-8 for key '%s', ignoring.", strna(filename), line, t);
                 return -EINVAL;
         }
 
         if (value && !utf8_is_valid(value)) {
-                /* FIXME: filter UTF-8 */
-                log_error("%s:%u: invalid UTF-8 value for key %s: '%s', ignoring.",
-                          filename, line, key, value);
+                _cleanup_free_ char *t = utf8_escape_invalid(value);
+
+                log_error("%s:%u: invalid UTF-8 value for key %s: '%s', ignoring.", strna(filename), line, key, t);
                 return -EINVAL;
         }
 
@@ -614,24 +666,77 @@ static int load_env_file_push(const char *filename, unsigned line,
         if (!p)
                 return -ENOMEM;
 
-        r = strv_push(m, p);
+        r = strv_consume(m, p);
+        if (r < 0)
+                return r;
+
+        free(value);
+        return 0;
+}
+
+int load_env_file(FILE *f, const char *fname, const char *newline, char ***rl) {
+        char **m = NULL;
+        int r;
+
+        if (!newline)
+                newline = NEWLINE;
+
+        r = parse_env_file_internal(f, fname, newline, load_env_file_push, &m);
         if (r < 0) {
-                free(p);
+                strv_free(m);
                 return r;
         }
 
-        free(value);
+        *rl = m;
         return 0;
 }
 
-int load_env_file(const char *fname, const char *newline, char ***rl) {
+static int load_env_file_push_pairs(
+                const char *filename, unsigned line,
+                const char *key, char *value,
+                void *userdata) {
+        char ***m = userdata;
+        int r;
+
+        if (!utf8_is_valid(key)) {
+                _cleanup_free_ char *t = utf8_escape_invalid(key);
+
+                log_error("%s:%u: invalid UTF-8 for key '%s', ignoring.", strna(filename), line, t);
+                return -EINVAL;
+        }
+
+        if (value && !utf8_is_valid(value)) {
+                _cleanup_free_ char *t = utf8_escape_invalid(value);
+
+                log_error("%s:%u: invalid UTF-8 value for key %s: '%s', ignoring.", strna(filename), line, key, t);
+                return -EINVAL;
+        }
+
+        r = strv_extend(m, key);
+        if (r < 0)
+                return -ENOMEM;
+
+        if (!value) {
+                r = strv_extend(m, "");
+                if (r < 0)
+                        return -ENOMEM;
+        } else {
+                r = strv_push(m, value);
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
+int load_env_file_pairs(FILE *f, const char *fname, const char *newline, char ***rl) {
         char **m = NULL;
         int r;
 
         if (!newline)
                 newline = NEWLINE;
 
-        r = parse_env_file_internal(fname, newline, load_env_file_push, &m);
+        r = parse_env_file_internal(f, fname, newline, load_env_file_push_pairs, &m);
         if (r < 0) {
                 strv_free(m);
                 return r;
@@ -655,11 +760,11 @@ static void write_env_var(FILE *f, const char *v) {
         p++;
         fwrite(v, 1, p-v, f);
 
-        if (string_has_cc(p) || chars_intersect(p, WHITESPACE "\'\"\\`$")) {
+        if (string_has_cc(p, NULL) || chars_intersect(p, WHITESPACE SHELL_NEED_QUOTES)) {
                 fputc('\"', f);
 
                 for (; *p; p++) {
-                        if (strchr("\'\"\\`$", *p))
+                        if (strchr(SHELL_NEED_ESCAPE, *p))
                                 fputc('\\', f);
 
                         fputc(*p, f);
@@ -673,41 +778,37 @@ static void write_env_var(FILE *f, const char *v) {
 }
 
 int write_env_file(const char *fname, char **l) {
-        char **i;
-        _cleanup_free_ char *p = NULL;
         _cleanup_fclose_ FILE *f = NULL;
+        _cleanup_free_ char *p = NULL;
+        char **i;
         int r;
 
+        assert(fname);
+
         r = fopen_temporary(fname, &f, &p);
         if (r < 0)
                 return r;
 
         fchmod_umask(fileno(f), 0644);
 
-        errno = 0;
         STRV_FOREACH(i, l)
                 write_env_var(f, *i);
 
-        fflush(f);
+        r = fflush_and_check(f);
+        if (r >= 0) {
+                if (rename(p, fname) >= 0)
+                        return 0;
 
-        if (ferror(f))
-                r = errno ? -errno : -EIO;
-        else {
-                if (rename(p, fname) < 0)
-                        r = -errno;
-                else
-                        r = 0;
+                r = -errno;
         }
 
-        if (r < 0)
-                unlink(p);
-
+        unlink(p);
         return r;
 }
 
 int executable_is_script(const char *path, char **interpreter) {
         int r;
-        char _cleanup_free_ *line = NULL;
+        _cleanup_free_ char *line = NULL;
         int len;
         char *ans;
 
index 06c2887..c256915 100644 (file)
 
 #include "macro.h"
 
-int write_string_to_file(FILE *f, const char *line);
+int write_string_stream(FILE *f, const char *line);
 int write_string_file(const char *fn, const char *line);
+int write_string_file_no_create(const char *fn, const char *line);
 int write_string_file_atomic(const char *fn, const char *line);
 
 int read_one_line_file(const char *fn, char **line);
 int read_full_file(const char *fn, char **contents, size_t *size);
+int read_full_stream(FILE *f, char **contents, size_t *size);
 ssize_t sendfile_full(int out_fd, const char *fn);
 
 int parse_env_file(const char *fname, const char *separator, ...) _sentinel_;
-int load_env_file(const char *fname, const char *separator, char ***l);
+int load_env_file(FILE *f, const char *fname, const char *separator, char ***l);
+int load_env_file_pairs(FILE *f, const char *fname, const char *separator, char ***l);
+
 int write_env_file(const char *fname, char **l);
 
 int executable_is_script(const char *path, char **interpreter);
diff --git a/src/shared/generator.c b/src/shared/generator.c
new file mode 100644 (file)
index 0000000..414470b
--- /dev/null
@@ -0,0 +1,154 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <string.h>
+#include <unistd.h>
+
+#include "util.h"
+#include "special.h"
+#include "mkdir.h"
+#include "unit-name.h"
+#include "generator.h"
+#include "path-util.h"
+#include "dropin.h"
+
+int generator_write_fsck_deps(
+                FILE *f,
+                const char *dest,
+                const char *what,
+                const char *where,
+                const char *fstype) {
+
+        assert(f);
+        assert(dest);
+        assert(what);
+        assert(where);
+
+        if (!is_device_path(what)) {
+                log_warning("Checking was requested for \"%s\", but it is not a device.", what);
+                return 0;
+        }
+
+        if (!isempty(fstype) && !streq(fstype, "auto")) {
+                int r;
+                r = fsck_exists(fstype);
+                if (r == -ENOENT) {
+                        /* treat missing check as essentially OK */
+                        log_debug("Checking was requested for %s, but fsck.%s does not exist: %s", what, fstype, strerror(-r));
+                        return 0;
+                } else if (r < 0) {
+                        log_warning("Checking was requested for %s, but fsck.%s cannot be used: %s", what, fstype, strerror(-r));
+                        return r;
+                }
+        }
+
+        if (streq(where, "/")) {
+                char *lnk;
+
+                lnk = strappenda(dest, "/" SPECIAL_LOCAL_FS_TARGET ".wants/systemd-fsck-root.service");
+
+                mkdir_parents(lnk, 0755);
+                if (symlink(SYSTEM_DATA_UNIT_PATH "/systemd-fsck-root.service", lnk) < 0) {
+                        log_error("Failed to create symlink %s: %m", lnk);
+                        return -errno;
+                }
+
+        } else {
+                _cleanup_free_ char *fsck = NULL;
+
+                fsck = unit_name_from_path_instance("systemd-fsck", what, ".service");
+                if (!fsck)
+                        return log_oom();
+
+                fprintf(f,
+                        "RequiresOverridable=%s\n"
+                        "After=%s\n",
+                        fsck,
+                        fsck);
+        }
+
+        return 0;
+}
+
+int generator_write_timeouts(const char *dir, const char *what, const char *where,
+                             const char *opts, char **filtered) {
+
+        /* Allow configuration how long we wait for a device that
+         * backs a mount point to show up. This is useful to support
+         * endless device timeouts for devices that show up only after
+         * user input, like crypto devices. */
+
+        _cleanup_free_ char *node = NULL, *unit = NULL, *t = NULL;
+        char *start, *timeout;
+        usec_t u;
+        int r;
+        size_t len;
+
+        if ((start = mount_test_option(opts, "comment=systemd.device-timeout")))
+                timeout = start + 31;
+        else if ((start = mount_test_option(opts, "x-systemd.device-timeout")))
+                timeout = start + 25;
+        else {
+                if (filtered) {
+                        *filtered = strdup(opts ?: "");
+                        if (!*filtered)
+                                return log_oom();
+                }
+
+                return 0;
+        }
+
+        len = strcspn(timeout, ",;" WHITESPACE);
+        t = strndup(timeout, len);
+        if (!t)
+                return -ENOMEM;
+
+        if (filtered) {
+                char *prefix, *postfix;
+
+                prefix = strndupa(opts, start - opts - (start != opts));
+                postfix = timeout + len + (start == opts && timeout[len] != '\0');
+                *filtered = strjoin(prefix, *postfix ? postfix : NULL, NULL);
+                if (!*filtered)
+                        return log_oom();
+        }
+
+        r = parse_sec(t, &u);
+        if (r < 0) {
+                log_warning("Failed to parse timeout for %s, ignoring: %s",
+                            where, timeout);
+                return 0;
+        }
+
+        node = fstab_node_to_udev_node(what);
+        if (!node)
+                return log_oom();
+
+        unit = unit_name_from_path(node, ".device");
+        if (!unit)
+                return -ENOMEM;
+
+        return write_drop_in_format(dir, unit, 50, "device-timeout",
+                                    "# Automatically generated by %s\n\n"
+                                    "[Unit]\nJobTimeoutSec=" USEC_FMT,
+                                    program_invocation_short_name,
+                                    u / USEC_PER_SEC);
+}
diff --git a/src/shared/generator.h b/src/shared/generator.h
new file mode 100644 (file)
index 0000000..64bd28f
--- /dev/null
@@ -0,0 +1,29 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdio.h>
+
+int generator_write_fsck_deps(FILE *f, const char *dest, const char *what, const char *where, const char *type);
+
+int generator_write_timeouts(const char *dir, const char *what, const char *where,
+                             const char *opts, char **filtered);
diff --git a/src/shared/gpt.h b/src/shared/gpt.h
new file mode 100644 (file)
index 0000000..ef3444f
--- /dev/null
@@ -0,0 +1,59 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <endian.h>
+
+#include "sd-id128.h"
+
+/* We only support root disk discovery for x86, x86-64 and ARM for
+ * now, since EFI for anything else doesn't really exist, and we only
+ * care for root partitions on the same disk as the EFI ESP. */
+
+#define GPT_ROOT_X86    SD_ID128_MAKE(44,47,95,40,f2,97,41,b2,9a,f7,d1,31,d5,f0,45,8a)
+#define GPT_ROOT_X86_64 SD_ID128_MAKE(4f,68,bc,e3,e8,cd,4d,b1,96,e7,fb,ca,f9,84,b7,09)
+#define GPT_ROOT_ARM    SD_ID128_MAKE(69,da,d7,10,2c,e4,4e,3c,b1,6c,21,a1,d4,9a,be,d3)
+#define GPT_ROOT_ARM_64 SD_ID128_MAKE(b9,21,b0,45,1d,f0,41,c3,af,44,4c,6f,28,0d,3f,ae)
+
+#define GPT_ESP         SD_ID128_MAKE(c1,2a,73,28,f8,1f,11,d2,ba,4b,00,a0,c9,3e,c9,3b)
+#define GPT_SWAP        SD_ID128_MAKE(06,57,fd,6d,a4,ab,43,c4,84,e5,09,33,c8,4b,4f,4f)
+#define GPT_HOME        SD_ID128_MAKE(93,3a,c7,e1,2e,b4,4f,13,b8,44,0e,14,e2,ae,f9,15)
+#define GPT_SRV         SD_ID128_MAKE(3b,8f,84,25,20,e0,4f,3b,90,7f,1a,25,a7,6f,98,e8)
+
+#if defined(__x86_64__)
+#  define GPT_ROOT_NATIVE GPT_ROOT_X86_64
+#  define GPT_ROOT_SECONDARY GPT_ROOT_X86
+#elif defined(__i386__)
+#  define GPT_ROOT_NATIVE GPT_ROOT_X86
+#endif
+
+#if defined(__aarch64__) && (__BYTE_ORDER != __BIG_ENDIAN)
+#  define GPT_ROOT_NATIVE GPT_ROOT_ARM_64
+#  define GPT_ROOT_SECONDARY GPT_ROOT_ARM
+#elif defined(__arm__) && (__BYTE_ORDER != __BIG_ENDIAN)
+#  define GPT_ROOT_NATIVE GPT_ROOT_ARM
+#endif
+
+/* Flags we recognize on the root, swap, home and srv partitions when
+ * doing auto-discovery. These happen to be identical to what
+ * Microsoft defines for its own Basic Data Partitions, but that's
+ * just because we saw no point in defining any other values here. */
+#define GPT_FLAG_READ_ONLY (1ULL << 60)
+#define GPT_FLAG_NO_AUTO (1ULL << 63)
index 65b7b74..dbf91c4 100644 (file)
@@ -164,6 +164,21 @@ int uint64_compare_func(const void *_a, const void *_b) {
         return a < b ? -1 : (a > b ? 1 : 0);
 }
 
+#if SIZEOF_DEV_T != 8
+unsigned long devt_hash_func(const void *p, const uint8_t hash_key[HASH_KEY_SIZE]) {
+        uint64_t u;
+        siphash24((uint8_t*) &u, p, sizeof(dev_t), hash_key);
+        return (unsigned long) u;
+}
+
+int devt_compare_func(const void *_a, const void *_b) {
+        dev_t a, b;
+        a = *(const dev_t*) _a;
+        b = *(const dev_t*) _b;
+        return a < b ? -1 : (a > b ? 1 : 0);
+}
+#endif
+
 static unsigned bucket_hash(Hashmap *h, const void *p) {
         return (unsigned) (h->hash_func(p, h->hash_key) % h->n_buckets);
 }
@@ -582,6 +597,34 @@ void* hashmap_remove(Hashmap *h, const void *key) {
         return data;
 }
 
+void* hashmap_remove2(Hashmap *h, const void *key, void **rkey) {
+        struct hashmap_entry *e;
+        unsigned hash;
+        void *data;
+
+        if (!h) {
+                if (rkey)
+                        *rkey = NULL;
+                return NULL;
+        }
+
+        hash = bucket_hash(h, key);
+        e = hash_scan(h, hash, key);
+        if (!e) {
+                if (rkey)
+                        *rkey = NULL;
+                return NULL;
+        }
+
+        data = e->value;
+        if (rkey)
+                *rkey = (void*) e->key;
+
+        remove_entry(h, e);
+
+        return data;
+}
+
 int hashmap_remove_and_put(Hashmap *h, const void *old_key, const void *new_key, void *value) {
         struct hashmap_entry *e;
         unsigned old_hash, new_hash;
index 154f68e..f89e7e8 100644 (file)
@@ -52,9 +52,23 @@ int string_compare_func(const void *a, const void *b) _pure_;
 unsigned long trivial_hash_func(const void *p, const uint8_t hash_key[HASH_KEY_SIZE]) _pure_;
 int trivial_compare_func(const void *a, const void *b) _const_;
 
+/* 32bit values we can always just embedd in the pointer itself, but
+ * in order to support 32bit archs we need store 64bit values
+ * indirectly, since they don't fit in a pointer. */
 unsigned long uint64_hash_func(const void *p, const uint8_t hash_key[HASH_KEY_SIZE]) _pure_;
 int uint64_compare_func(const void *a, const void *b) _pure_;
 
+/* On some archs dev_t is 32bit, and on others 64bit. And sometimes
+ * it's 64bit on 32bit archs, and sometimes 32bit on 64bit archs. Yuck! */
+#if SIZEOF_DEV_T != 8
+unsigned long devt_hash_func(const void *p, const uint8_t hash_key[HASH_KEY_SIZE]) _pure_;
+int devt_compare_func(const void *a, const void *b) _pure_;
+#else
+/* No need to define a second version of this... */
+#define devt_hash_func uint64_hash_func
+#define devt_compare_func uint64_compare_func
+#endif
+
 Hashmap *hashmap_new(hash_func_t hash_func, compare_func_t compare_func);
 void hashmap_free(Hashmap *h);
 void hashmap_free_free(Hashmap *h);
@@ -69,6 +83,7 @@ void *hashmap_get(Hashmap *h, const void *key);
 void *hashmap_get2(Hashmap *h, const void *key, void **rkey);
 bool hashmap_contains(Hashmap *h, const void *key);
 void *hashmap_remove(Hashmap *h, const void *key);
+void *hashmap_remove2(Hashmap *h, const void *key, void **rkey);
 void *hashmap_remove_value(Hashmap *h, const void *key, void *value);
 int hashmap_remove_and_put(Hashmap *h, const void *old_key, const void *new_key, void *value);
 int hashmap_remove_and_replace(Hashmap *h, const void *old_key, const void *new_key, void *value);
diff --git a/src/shared/in-addr-util.c b/src/shared/in-addr-util.c
new file mode 100644 (file)
index 0000000..457eedd
--- /dev/null
@@ -0,0 +1,250 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <arpa/inet.h>
+
+#include "in-addr-util.h"
+
+int in_addr_is_null(int family, const union in_addr_union *u) {
+        assert(u);
+
+        if (family == AF_INET)
+                return u->in.s_addr == 0;
+
+        if (family == AF_INET6)
+                return
+                        u->in6.s6_addr32[0] == 0 &&
+                        u->in6.s6_addr32[1] == 0 &&
+                        u->in6.s6_addr32[2] == 0 &&
+                        u->in6.s6_addr32[3] == 0;
+
+        return -EAFNOSUPPORT;
+}
+
+int in_addr_is_link_local(int family, const union in_addr_union *u) {
+        assert(u);
+
+        if (family == AF_INET)
+                return (be32toh(u->in.s_addr) & 0xFFFF0000) == (169U << 24 | 254U << 16);
+
+        if (family == AF_INET6)
+                return IN6_IS_ADDR_LINKLOCAL(&u->in6);
+
+        return -EAFNOSUPPORT;
+}
+
+int in_addr_equal(int family, const union in_addr_union *a, const union in_addr_union *b) {
+        assert(a);
+        assert(b);
+
+        if (family == AF_INET)
+                return a->in.s_addr == b->in.s_addr;
+
+        if (family == AF_INET6)
+                return
+                        a->in6.s6_addr32[0] == b->in6.s6_addr32[0] &&
+                        a->in6.s6_addr32[1] == b->in6.s6_addr32[1] &&
+                        a->in6.s6_addr32[2] == b->in6.s6_addr32[2] &&
+                        a->in6.s6_addr32[3] == b->in6.s6_addr32[3];
+
+        return -EAFNOSUPPORT;
+}
+
+int in_addr_prefix_intersect(
+                int family,
+                const union in_addr_union *a,
+                unsigned aprefixlen,
+                const union in_addr_union *b,
+                unsigned bprefixlen) {
+
+        unsigned m;
+
+        assert(a);
+        assert(b);
+
+        /* Checks whether there are any addresses that are in both
+         * networks */
+
+        m = MIN(aprefixlen, bprefixlen);
+
+        if (family == AF_INET) {
+                uint32_t x, nm;
+
+                x = be32toh(a->in.s_addr ^ b->in.s_addr);
+                nm = (m == 0) ? 0 : 0xFFFFFFFFUL << (32 - m);
+
+                return (x & nm) == 0;
+        }
+
+        if (family == AF_INET6) {
+                unsigned i;
+
+                if (m > 128)
+                        m = 128;
+
+                for (i = 0; i < 16; i++) {
+                        uint8_t x, nm;
+
+                        x = a->in6.s6_addr[i] ^ b->in6.s6_addr[i];
+
+                        if (m < 8)
+                                nm = 0xFF << (8 - m);
+                        else
+                                nm = 0xFF;
+
+                        if ((x & nm) != 0)
+                                return 0;
+
+                        if (m > 8)
+                                m -= 8;
+                        else
+                                m = 0;
+                }
+
+                return 1;
+        }
+
+        return -EAFNOSUPPORT;
+}
+
+int in_addr_prefix_next(int family, union in_addr_union *u, unsigned prefixlen) {
+        assert(u);
+
+        /* Increases the network part of an address by one. Returns
+         * positive it that succeeds, or 0 if this overflows. */
+
+        if (prefixlen <= 0)
+                return 0;
+
+        if (family == AF_INET) {
+                uint32_t c, n;
+
+                if (prefixlen > 32)
+                        prefixlen = 32;
+
+                c = be32toh(u->in.s_addr);
+                n = c + (1UL << (32 - prefixlen));
+                if (n < c)
+                        return 0;
+                n &= 0xFFFFFFFFUL << (32 - prefixlen);
+
+                u->in.s_addr = htobe32(n);
+                return 1;
+        }
+
+        if (family == AF_INET6) {
+                struct in6_addr add = {}, result;
+                uint8_t overflow = 0;
+                unsigned i;
+
+                if (prefixlen > 128)
+                        prefixlen = 128;
+
+                /* First calculate what we have to add */
+                add.s6_addr[(prefixlen-1) / 8] = 1 << (7 - (prefixlen-1) % 8);
+
+                for (i = 16; i > 0; i--) {
+                        unsigned j = i - 1;
+
+                        result.s6_addr[j] = u->in6.s6_addr[j] + add.s6_addr[j] + overflow;
+                        overflow = (result.s6_addr[j] < u->in6.s6_addr[j]);
+                }
+
+                if (overflow)
+                        return 0;
+
+                u->in6 = result;
+                return 1;
+        }
+
+        return -EAFNOSUPPORT;
+}
+
+int in_addr_to_string(int family, const union in_addr_union *u, char **ret) {
+        char *x;
+        size_t l;
+
+        assert(u);
+        assert(ret);
+
+        if (family == AF_INET)
+                l = INET_ADDRSTRLEN;
+        else if (family == AF_INET6)
+                l = INET6_ADDRSTRLEN;
+        else
+                return -EAFNOSUPPORT;
+
+        x = new(char, l);
+        if (!x)
+                return -ENOMEM;
+
+        errno = 0;
+        if (!inet_ntop(family, u, x, l)) {
+                free(x);
+                return errno ? -errno : -EINVAL;
+        }
+
+        *ret = x;
+        return 0;
+}
+
+int in_addr_from_string(int family, const char *s, union in_addr_union *ret) {
+
+        assert(s);
+        assert(ret);
+
+        if (!IN_SET(family, AF_INET, AF_INET6))
+                return -EAFNOSUPPORT;
+
+        errno = 0;
+        if (inet_pton(family, s, ret) <= 0)
+                return errno ? -errno : -EINVAL;
+
+        return 0;
+}
+
+int in_addr_from_string_auto(const char *s, int *family, union in_addr_union *ret) {
+        int r;
+
+        assert(s);
+        assert(family);
+        assert(ret);
+
+        r = in_addr_from_string(AF_INET, s, ret);
+        if (r >= 0) {
+                *family = AF_INET;
+                return 0;
+        }
+
+        r = in_addr_from_string(AF_INET6, s, ret);
+        if (r >= 0) {
+                *family = AF_INET6;
+                return 0;
+        }
+
+        return -EINVAL;
+}
+
+unsigned in_addr_netmask_to_prefixlen(const struct in_addr *addr) {
+        assert(addr);
+
+        return 32 - u32ctz(be32toh(addr->s_addr));
+}
diff --git a/src/shared/in-addr-util.h b/src/shared/in-addr-util.h
new file mode 100644 (file)
index 0000000..0036ace
--- /dev/null
@@ -0,0 +1,47 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <netinet/in.h>
+
+#include "macro.h"
+#include "util.h"
+
+union in_addr_union {
+        struct in_addr in;
+        struct in6_addr in6;
+};
+
+int in_addr_is_null(int family, const union in_addr_union *u);
+int in_addr_is_link_local(int family, const union in_addr_union *u);
+int in_addr_equal(int family, const union in_addr_union *a, const union in_addr_union *b);
+int in_addr_prefix_intersect(int family, const union in_addr_union *a, unsigned aprefixlen, const union in_addr_union *b, unsigned bprefixlen);
+int in_addr_prefix_next(int family, union in_addr_union *u, unsigned prefixlen);
+int in_addr_to_string(int family, const union in_addr_union *u, char **ret);
+int in_addr_from_string(int family, const char *s, union in_addr_union *ret);
+int in_addr_from_string_auto(const char *s, int *family, union in_addr_union *ret);
+unsigned in_addr_netmask_to_prefixlen(const struct in_addr *addr);
+
+static inline size_t FAMILY_ADDRESS_SIZE(int family) {
+        assert(family == AF_INET || family == AF_INET6);
+        return family == AF_INET6 ? 16 : 4;
+}
index 1f9d7e2..0fe1371 100644 (file)
@@ -47,7 +47,22 @@ typedef struct {
 
 #define _cleanup_install_context_done_ _cleanup_(install_context_done)
 
-static int lookup_paths_init_from_scope(LookupPaths *paths, UnitFileScope scope) {
+static int in_search_path(const char *path, char **search) {
+        _cleanup_free_ char *parent = NULL;
+        int r;
+
+        assert(path);
+
+        r = path_get_parent(path, &parent);
+        if (r < 0)
+                return r;
+
+        return strv_contains(search, parent);
+}
+
+static int lookup_paths_init_from_scope(LookupPaths *paths,
+                                        UnitFileScope scope,
+                                        const char *root_dir) {
         assert(paths);
         assert(scope >= 0);
         assert(scope < _UNIT_FILE_SCOPE_MAX);
@@ -57,6 +72,7 @@ static int lookup_paths_init_from_scope(LookupPaths *paths, UnitFileScope scope)
         return lookup_paths_init(paths,
                                  scope == UNIT_FILE_SYSTEM ? SYSTEMD_SYSTEM : SYSTEMD_USER,
                                  scope == UNIT_FILE_USER,
+                                 root_dir,
                                  NULL, NULL, NULL);
 }
 
@@ -72,15 +88,10 @@ static int get_config_path(UnitFileScope scope, bool runtime, const char *root_d
 
         case UNIT_FILE_SYSTEM:
 
-                if (root_dir && runtime)
-                        asprintf(&p, "%s/run/systemd/system", root_dir);
-                else if (runtime)
-                        p = strdup("/run/systemd/system");
-                else if (root_dir)
-                        asprintf(&p, "%s/%s", root_dir, SYSTEM_CONFIG_UNIT_PATH);
+                if (runtime)
+                        p = path_join(root_dir, "/run/systemd/system", NULL);
                 else
-                        p = strdup(SYSTEM_CONFIG_UNIT_PATH);
-
+                        p = path_join(root_dir, SYSTEM_CONFIG_UNIT_PATH, NULL);
                 break;
 
         case UNIT_FILE_GLOBAL:
@@ -144,12 +155,16 @@ static int add_file_change(
         if (!c[i].path)
                 return -ENOMEM;
 
+        path_kill_slashes(c[i].path);
+
         if (source) {
                 c[i].source = strdup(source);
                 if (!c[i].source) {
                         free(c[i].path);
                         return -ENOMEM;
                 }
+
+                path_kill_slashes(c[i].path);
         } else
                 c[i].source = NULL;
 
@@ -191,10 +206,10 @@ static int remove_marked_symlinks_fd(
                 bool *deleted,
                 UnitFileChange **changes,
                 unsigned *n_changes,
-                char** files) {
+                char** instance_whitelist) {
 
-        int r = 0;
         _cleanup_closedir_ DIR *d = NULL;
+        int r = 0;
 
         assert(remove_symlinks_to);
         assert(fd >= 0);
@@ -204,7 +219,7 @@ static int remove_marked_symlinks_fd(
 
         d = fdopendir(fd);
         if (!d) {
-                close_nointr_nofail(fd);
+                safe_close(fd);
                 return -errno;
         }
 
@@ -244,14 +259,13 @@ static int remove_marked_symlinks_fd(
 
                         p = path_make_absolute(de->d_name, path);
                         if (!p) {
-                                close_nointr_nofail(nfd);
+                                safe_close(nfd);
                                 return -ENOMEM;
                         }
 
                         /* This will close nfd, regardless whether it succeeds or not */
-                        q = remove_marked_symlinks_fd(remove_symlinks_to, nfd, p, config_path, deleted, changes, n_changes, files);
-
-                        if (r == 0)
+                        q = remove_marked_symlinks_fd(remove_symlinks_to, nfd, p, config_path, deleted, changes, n_changes, instance_whitelist);
+                        if (q < 0 && r == 0)
                                 r = q;
 
                 } else if (de->d_type == DT_LNK) {
@@ -259,6 +273,28 @@ static int remove_marked_symlinks_fd(
                         int q;
                         bool found;
 
+                        if (!unit_name_is_valid(de->d_name, TEMPLATE_VALID))
+                                continue;
+
+                        if (unit_name_is_instance(de->d_name) &&
+                            instance_whitelist &&
+                            !strv_contains(instance_whitelist, de->d_name)) {
+
+                                _cleanup_free_ char *w;
+
+                                /* OK, the file is not listed directly
+                                 * in the whitelist, so let's check if
+                                 * the template of it might be
+                                 * listed. */
+
+                                w = unit_name_template(de->d_name);
+                                if (!w)
+                                        return -ENOMEM;
+
+                                if (!strv_contains(instance_whitelist, w))
+                                        continue;
+                        }
+
                         p = path_make_absolute(de->d_name, path);
                         if (!p)
                                 return -ENOMEM;
@@ -277,31 +313,27 @@ static int remove_marked_symlinks_fd(
                                 set_get(remove_symlinks_to, dest) ||
                                 set_get(remove_symlinks_to, basename(dest));
 
-                        if (unit_name_is_instance(p))
-                                found = found && strv_contains(files, basename(p));
+                        if (!found)
+                                continue;
+
+                        if (unlink(p) < 0 && errno != ENOENT) {
+                                if (r == 0)
+                                        r = -errno;
+                                continue;
+                        }
 
-                        if (found) {
+                        path_kill_slashes(p);
+                        rmdir_parents(p, config_path);
+                        add_file_change(changes, n_changes, UNIT_FILE_UNLINK, p, NULL);
 
-                                if (unlink(p) < 0 && errno != ENOENT) {
+                        if (!set_get(remove_symlinks_to, p)) {
 
+                                q = mark_symlink_for_removal(&remove_symlinks_to, p);
+                                if (q < 0) {
                                         if (r == 0)
-                                                r = -errno;
-                                } else {
-                                        rmdir_parents(p, config_path);
-                                        path_kill_slashes(p);
-
-                                        add_file_change(changes, n_changes, UNIT_FILE_UNLINK, p, NULL);
-
-                                        if (!set_get(remove_symlinks_to, p)) {
-
-                                                q = mark_symlink_for_removal(&remove_symlinks_to, p);
-                                                if (q < 0) {
-                                                        if (r == 0)
-                                                                r = q;
-                                                } else
-                                                        *deleted = true;
-                                        }
-                                }
+                                                r = q;
+                                } else
+                                        *deleted = true;
                         }
                 }
         }
@@ -314,9 +346,10 @@ static int remove_marked_symlinks(
                 const char *config_path,
                 UnitFileChange **changes,
                 unsigned *n_changes,
-                char** files) {
+                char** instance_whitelist) {
 
-        int fd, r = 0;
+        _cleanup_close_ int fd = -1;
+        int r = 0;
         bool deleted;
 
         assert(config_path);
@@ -332,20 +365,18 @@ static int remove_marked_symlinks(
                 int q, cfd;
                 deleted = false;
 
-                cfd = dup(fd);
+                cfd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
                 if (cfd < 0) {
                         r = -errno;
                         break;
                 }
 
                 /* This takes possession of cfd and closes it */
-                q = remove_marked_symlinks_fd(remove_symlinks_to, cfd, config_path, config_path, &deleted, changes, n_changes, files);
+                q = remove_marked_symlinks_fd(remove_symlinks_to, cfd, config_path, config_path, &deleted, changes, n_changes, instance_whitelist);
                 if (r == 0)
                         r = q;
         } while (deleted);
 
-        close_nointr_nofail(fd);
-
         return r;
 }
 
@@ -367,7 +398,7 @@ static int find_symlinks_fd(
 
         d = fdopendir(fd);
         if (!d) {
-                close_nointr_nofail(fd);
+                safe_close(fd);
                 return -errno;
         }
 
@@ -403,16 +434,14 @@ static int find_symlinks_fd(
 
                         p = path_make_absolute(de->d_name, path);
                         if (!p) {
-                                close_nointr_nofail(nfd);
+                                safe_close(nfd);
                                 return -ENOMEM;
                         }
 
                         /* This will close nfd, regardless whether it succeeds or not */
                         q = find_symlinks_fd(name, nfd, p, config_path, same_name_link);
-
                         if (q > 0)
                                 return 1;
-
                         if (r == 0)
                                 r = q;
 
@@ -469,8 +498,6 @@ static int find_symlinks_fd(
                                 return 1;
                 }
         }
-
-        return r;
 }
 
 static int find_symlinks(
@@ -562,7 +589,7 @@ int unit_file_mask(
                 unsigned *n_changes) {
 
         char **i;
-        _cleanup_free_ char *prefix;
+        _cleanup_free_ char *prefix = NULL;
         int r;
 
         assert(scope >= 0);
@@ -589,7 +616,6 @@ int unit_file_mask(
 
                 if (symlink("/dev/null", path) >= 0) {
                         add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, path, "/dev/null");
-
                         continue;
                 }
 
@@ -599,13 +625,9 @@ int unit_file_mask(
                                 continue;
 
                         if (force) {
-                                unlink(path);
-
-                                if (symlink("/dev/null", path) >= 0) {
-
+                                if (symlink_atomic("/dev/null", path) >= 0) {
                                         add_file_change(changes, n_changes, UNIT_FILE_UNLINK, path, NULL);
                                         add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, path, "/dev/null");
-
                                         continue;
                                 }
                         }
@@ -703,7 +725,7 @@ int unit_file_link(
         assert(scope >= 0);
         assert(scope < _UNIT_FILE_SCOPE_MAX);
 
-        r = lookup_paths_init_from_scope(&paths, scope);
+        r = lookup_paths_init_from_scope(&paths, scope, root_dir);
         if (r < 0)
                 return r;
 
@@ -756,7 +778,6 @@ int unit_file_link(
                         _cleanup_free_ char *dest = NULL;
 
                         q = readlink_and_make_absolute(path, &dest);
-
                         if (q < 0 && errno != ENOENT) {
                                 if (r == 0)
                                         r = q;
@@ -767,13 +788,9 @@ int unit_file_link(
                                 continue;
 
                         if (force) {
-                                unlink(path);
-
-                                if (symlink(*i, path) >= 0) {
-
+                                if (symlink_atomic(*i, path) >= 0) {
                                         add_file_change(changes, n_changes, UNIT_FILE_UNLINK, path, NULL);
                                         add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, path, *i);
-
                                         continue;
                                 }
                         }
@@ -824,6 +841,7 @@ static void install_info_free(InstallInfo *i) {
         strv_free(i->aliases);
         strv_free(i->wanted_by);
         strv_free(i->required_by);
+        free(i->default_instance);
         free(i);
 }
 
@@ -916,31 +934,31 @@ static int install_info_add_auto(
                 return install_info_add(c, name_or_path, NULL);
 }
 
-static int config_parse_also(const char *unit,
-                             const char *filename,
-                             unsigned line,
-                             const char *section,
-                             unsigned section_line,
-                             const char *lvalue,
-                             int ltype,
-                             const char *rvalue,
-                             void *data,
-                             void *userdata) {
-
-        char *w;
+static int config_parse_also(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
         size_t l;
-        char *state;
+        const char *word, *state;
         InstallContext *c = data;
 
         assert(filename);
         assert(lvalue);
         assert(rvalue);
 
-        FOREACH_WORD_QUOTED(w, l, rvalue, state) {
+        FOREACH_WORD_QUOTED(word, l, rvalue, state) {
                 _cleanup_free_ char *n;
                 int r;
 
-                n = strndup(w, l);
+                n = strndup(word, l);
                 if (!n)
                         return -ENOMEM;
 
@@ -948,23 +966,27 @@ static int config_parse_also(const char *unit,
                 if (r < 0)
                         return r;
         }
+        if (!isempty(state))
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                           "Trailing garbage, ignoring.");
 
         return 0;
 }
 
-static int config_parse_user(const char *unit,
-                             const char *filename,
-                             unsigned line,
-                             const char *section,
-                             unsigned section_line,
-                             const char *lvalue,
-                             int ltype,
-                             const char *rvalue,
-                             void *data,
-                             void *userdata) {
+static int config_parse_user(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
 
         InstallInfo *i = data;
-        charprinted;
+        char *printed;
         int r;
 
         assert(filename);
@@ -981,41 +1003,80 @@ static int config_parse_user(const char *unit,
         return 0;
 }
 
+static int config_parse_default_instance(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        InstallInfo *i = data;
+        char *printed;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+
+        r = install_full_printf(i, rvalue, &printed);
+        if (r < 0)
+                return r;
+
+        if (!unit_instance_is_valid(printed))
+                return -EINVAL;
+
+        free(i->default_instance);
+        i->default_instance = printed;
+
+        return 0;
+}
+
 static int unit_file_load(
                 InstallContext *c,
                 InstallInfo *info,
                 const char *path,
+                const char *root_dir,
                 bool allow_symlink) {
 
         const ConfigTableItem items[] = {
-                { "Install", "Alias",      config_parse_strv, 0, &info->aliases     },
-                { "Install", "WantedBy",   config_parse_strv, 0, &info->wanted_by   },
-                { "Install", "RequiredBy", config_parse_strv, 0, &info->required_by },
-                { "Install", "Also",       config_parse_also, 0, c                  },
-                { "Exec",    "User",       config_parse_user, 0, info               },
-                { NULL, NULL, NULL, 0, NULL }
+                { "Install", "Alias",           config_parse_strv,             0, &info->aliases           },
+                { "Install", "WantedBy",        config_parse_strv,             0, &info->wanted_by         },
+                { "Install", "RequiredBy",      config_parse_strv,             0, &info->required_by       },
+                { "Install", "DefaultInstance", config_parse_default_instance, 0, info                     },
+                { "Install", "Also",            config_parse_also,             0, c                        },
+                { "Exec",    "User",            config_parse_user,             0, info                     },
+                {}
         };
 
-        int fd;
         _cleanup_fclose_ FILE *f = NULL;
-        int r;
+        int fd, r;
 
         assert(c);
         assert(info);
         assert(path);
 
+        if (!isempty(root_dir))
+                path = strappenda(root_dir, "/", path);
+
         fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY|(allow_symlink ? 0 : O_NOFOLLOW));
         if (fd < 0)
                 return -errno;
 
         f = fdopen(fd, "re");
         if (!f) {
-                close_nointr_nofail(fd);
+                safe_close(fd);
                 return -ENOMEM;
         }
 
-        r = config_parse(NULL, path, f, NULL,
-                         config_item_table_lookup, (void*) items, true, true, info);
+        r = config_parse(NULL, path, f,
+                         NULL,
+                         config_item_table_lookup, items,
+                         true, true, false, info);
         if (r < 0)
                 return r;
 
@@ -1040,70 +1101,55 @@ static int unit_file_search(
         assert(paths);
 
         if (info->path)
-                return unit_file_load(c, info, info->path, allow_symlink);
+                return unit_file_load(c, info, info->path, root_dir, allow_symlink);
 
         assert(info->name);
 
         STRV_FOREACH(p, paths->unit_path) {
-                char *path = NULL;
-
-                if (isempty(root_dir))
-                        asprintf(&path, "%s/%s", *p, info->name);
-                else
-                        asprintf(&path, "%s/%s/%s", root_dir, *p, info->name);
+                _cleanup_free_ char *path = NULL;
 
+                path = strjoin(*p, "/", info->name, NULL);
                 if (!path)
                         return -ENOMEM;
 
-                r = unit_file_load(c, info, path, allow_symlink);
-
-                if (r >= 0)
+                r = unit_file_load(c, info, path, root_dir, allow_symlink);
+                if (r >= 0) {
                         info->path = path;
-                else {
-                        if (r == -ENOENT && unit_name_is_instance(info->name)) {
-                                /* Unit file doesn't exist, however instance enablement was requested.
-                                 * We will check if it is possible to load template unit file. */
-                                char *template = NULL,
-                                     *template_path = NULL,
-                                     *template_dir = NULL;
-
-                                template = unit_name_template(info->name);
-                                if (!template) {
-                                        free(path);
-                                        return -ENOMEM;
-                                }
+                        path = NULL;
+                        return r;
+                }
+                if (r != -ENOENT && r != -ELOOP)
+                        return r;
+        }
 
-                                /* We will reuse path variable since we don't need it anymore. */
-                                template_dir = path;
-                                *(strrchr(path, '/') + 1) = '\0';
+        if (unit_name_is_instance(info->name)) {
 
-                                template_path = strjoin(template_dir, template, NULL);
-                                if (!template_path) {
-                                        free(path);
-                                        free(template);
-                                        return -ENOMEM;
-                                }
+                /* Unit file doesn't exist, however instance
+                 * enablement was requested.  We will check if it is
+                 * possible to load template unit file. */
 
-                                /* Let's try to load template unit. */
-                                r = unit_file_load(c, info, template_path, allow_symlink);
-                                if (r >= 0) {
-                                        info->path = strdup(template_path);
-                                        if (!info->path) {
-                                                free(path);
-                                                free(template);
-                                                free(template_path);
-                                                return -ENOMEM;
-                                        }
-                                }
+                _cleanup_free_ char *template = NULL;
+
+                template = unit_name_template(info->name);
+                if (!template)
+                        return -ENOMEM;
 
-                                free(template);
-                                free(template_path);
+                STRV_FOREACH(p, paths->unit_path) {
+                        _cleanup_free_ char *path = NULL;
+
+                        path = strjoin(*p, "/", template, NULL);
+                        if (!path)
+                                return -ENOMEM;
+
+                        r = unit_file_load(c, info, path, root_dir, allow_symlink);
+                        if (r >= 0) {
+                                info->path = path;
+                                path = NULL;
+                                return r;
                         }
-                        free(path);
+                        if (r != -ENOENT && r != -ELOOP)
+                                return r;
                 }
-
-                if (r != -ENOENT && r != -ELOOP)
-                        return r;
         }
 
         return -ENOENT;
@@ -1172,15 +1218,14 @@ static int create_symlink(
         if (!force)
                 return -EEXIST;
 
-        unlink(new_path);
+        r = symlink_atomic(old_path, new_path);
+        if (r < 0)
+                return r;
 
-        if (symlink(old_path, new_path) >= 0) {
-                add_file_change(changes, n_changes, UNIT_FILE_UNLINK, new_path, NULL);
-                add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, new_path, old_path);
-                return 0;
-        }
+        add_file_change(changes, n_changes, UNIT_FILE_UNLINK, new_path, NULL);
+        add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, new_path, old_path);
 
-        return -errno;
+        return 0;
 }
 
 static int install_info_symlink_alias(
@@ -1218,54 +1263,37 @@ static int install_info_symlink_alias(
 static int install_info_symlink_wants(
                 InstallInfo *i,
                 const char *config_path,
+                char **list,
+                const char *suffix,
                 bool force,
                 UnitFileChange **changes,
                 unsigned *n_changes) {
 
+        _cleanup_free_ char *buf = NULL;
+        const char *n;
         char **s;
         int r = 0, q;
 
         assert(i);
         assert(config_path);
 
-        STRV_FOREACH(s, i->wanted_by) {
-                _cleanup_free_ char *path = NULL, *dst = NULL;
+        if (unit_name_is_template(i->name)) {
 
-                q = install_full_printf(i, *s, &dst);
-                if (q < 0)
-                        return q;
+                /* Don't install any symlink if there's no default
+                 * instance configured */
 
-                if (!unit_name_is_valid(dst, TEMPLATE_VALID)) {
-                        r = -EINVAL;
-                        continue;
-                }
+                if (!i->default_instance)
+                        return 0;
 
-                if (asprintf(&path, "%s/%s.wants/%s", config_path, dst, i->name) < 0)
+                buf = unit_name_replace_instance(i->name, i->default_instance);
+                if (!buf)
                         return -ENOMEM;
 
-                q = create_symlink(i->path, path, force, changes, n_changes);
-
-                if (r == 0)
-                        r = q;
-        }
-
-        return r;
-}
-
-static int install_info_symlink_requires(
-                InstallInfo *i,
-                const char *config_path,
-                bool force,
-                UnitFileChange **changes,
-                unsigned *n_changes) {
-
-        char **s;
-        int r = 0, q;
-
-        assert(i);
-        assert(config_path);
+                n = buf;
+        } else
+                n = i->name;
 
-        STRV_FOREACH(s, i->required_by) {
+        STRV_FOREACH(s, list) {
                 _cleanup_free_ char *path = NULL, *dst = NULL;
 
                 q = install_full_printf(i, *s, &dst);
@@ -1277,11 +1305,11 @@ static int install_info_symlink_requires(
                         continue;
                 }
 
-                if (asprintf(&path, "%s/%s.requires/%s", config_path, dst, i->name) < 0)
+                path = strjoin(config_path, "/", dst, suffix, n, NULL);
+                if (!path)
                         return -ENOMEM;
 
                 q = create_symlink(i->path, path, force, changes, n_changes);
-
                 if (r == 0)
                         r = q;
         }
@@ -1293,12 +1321,13 @@ static int install_info_symlink_link(
                 InstallInfo *i,
                 LookupPaths *paths,
                 const char *config_path,
+                const char *root_dir,
                 bool force,
                 UnitFileChange **changes,
                 unsigned *n_changes) {
 
-        int r;
         _cleanup_free_ char *path = NULL;
+        int r;
 
         assert(i);
         assert(paths);
@@ -1309,17 +1338,18 @@ static int install_info_symlink_link(
         if (r != 0)
                 return r;
 
-        if (asprintf(&path, "%s/%s", config_path, i->name) < 0)
+        path = strjoin(config_path, "/", i->name, NULL);
+        if (!path)
                 return -ENOMEM;
 
-        r = create_symlink(i->path, path, force, changes, n_changes);
-        return r;
+        return create_symlink(i->path, path, force, changes, n_changes);
 }
 
 static int install_info_apply(
                 InstallInfo *i,
                 LookupPaths *paths,
                 const char *config_path,
+                const char *root_dir,
                 bool force,
                 UnitFileChange **changes,
                 unsigned *n_changes) {
@@ -1332,15 +1362,15 @@ static int install_info_apply(
 
         r = install_info_symlink_alias(i, config_path, force, changes, n_changes);
 
-        q = install_info_symlink_wants(i, config_path, force, changes, n_changes);
+        q = install_info_symlink_wants(i, config_path, i->wanted_by, ".wants/", force, changes, n_changes);
         if (r == 0)
                 r = q;
 
-        q = install_info_symlink_requires(i, config_path, force, changes, n_changes);
+        q = install_info_symlink_wants(i, config_path, i->required_by, ".requires/", force, changes, n_changes);
         if (r == 0)
                 r = q;
 
-        q = install_info_symlink_link(i, paths, config_path, force, changes, n_changes);
+        q = install_info_symlink_link(i, paths, config_path, root_dir, force, changes, n_changes);
         if (r == 0)
                 r = q;
 
@@ -1380,7 +1410,7 @@ static int install_context_apply(
                 } else if (r >= 0)
                         r += q;
 
-                q = install_info_apply(i, paths, config_path, force, changes, n_changes);
+                q = install_info_apply(i, paths, config_path, root_dir, force, changes, n_changes);
                 if (r >= 0 && q < 0)
                         r = q;
         }
@@ -1476,7 +1506,7 @@ int unit_file_enable(
         assert(scope >= 0);
         assert(scope < _UNIT_FILE_SCOPE_MAX);
 
-        r = lookup_paths_init_from_scope(&paths, scope);
+        r = lookup_paths_init_from_scope(&paths, scope, root_dir);
         if (r < 0)
                 return r;
 
@@ -1494,8 +1524,8 @@ int unit_file_enable(
         supposed to be created, not the ones actually created. This is
         useful to determine whether the passed files had any
         installation data at all. */
-        r = install_context_apply(&c, &paths, config_path, root_dir, force, changes, n_changes);
-        return r;
+
+        return install_context_apply(&c, &paths, config_path, root_dir, force, changes, n_changes);
 }
 
 int unit_file_disable(
@@ -1516,7 +1546,7 @@ int unit_file_disable(
         assert(scope >= 0);
         assert(scope < _UNIT_FILE_SCOPE_MAX);
 
-        r = lookup_paths_init_from_scope(&paths, scope);
+        r = lookup_paths_init_from_scope(&paths, scope, root_dir);
         if (r < 0)
                 return r;
 
@@ -1580,7 +1610,7 @@ int unit_file_set_default(
         if (unit_name_to_type(file) != UNIT_TARGET)
                 return -EINVAL;
 
-        r = lookup_paths_init_from_scope(&paths, scope);
+        r = lookup_paths_init_from_scope(&paths, scope, root_dir);
         if (r < 0)
                 return r;
 
@@ -1620,7 +1650,7 @@ int unit_file_get_default(
         assert(scope < _UNIT_FILE_SCOPE_MAX);
         assert(name);
 
-        r = lookup_paths_init_from_scope(&paths, scope);
+        r = lookup_paths_init_from_scope(&paths, scope, root_dir);
         if (r < 0)
                 return r;
 
@@ -1628,11 +1658,7 @@ int unit_file_get_default(
                 _cleanup_free_ char *path = NULL, *tmp = NULL;
                 char *n;
 
-                if (isempty(root_dir))
-                        path = strappend(*p, "/" SPECIAL_DEFAULT_TARGET);
-                else
-                        path = strjoin(root_dir, "/", *p, "/" SPECIAL_DEFAULT_TARGET, NULL);
-
+                path = path_join(root_dir, *p, SPECIAL_DEFAULT_TARGET);
                 if (!path)
                         return -ENOMEM;
 
@@ -1678,24 +1704,26 @@ UnitFileState unit_file_get_state(
         if (!unit_name_is_valid(name, TEMPLATE_VALID))
                 return -EINVAL;
 
-        r = lookup_paths_init_from_scope(&paths, scope);
+        r = lookup_paths_init_from_scope(&paths, scope, root_dir);
         if (r < 0)
                 return r;
 
         STRV_FOREACH(i, paths.unit_path) {
                 struct stat st;
+                char *partial;
 
                 free(path);
                 path = NULL;
 
-                if (root_dir)
-                        asprintf(&path, "%s/%s/%s", root_dir, *i, name);
-                else
-                        asprintf(&path, "%s/%s", *i, name);
-
+                path = path_join(root_dir, *i, name);
                 if (!path)
                         return -ENOMEM;
 
+                if (root_dir)
+                        partial = path + strlen(root_dir);
+                else
+                        partial = path;
+
                 /*
                  * Search for a unit file in our default paths, to
                  * be sure, that there are no broken symlinks.
@@ -1727,7 +1755,7 @@ UnitFileState unit_file_get_state(
                 else if (r > 0)
                         return state;
 
-                r = unit_file_can_install(&paths, root_dir, path, true);
+                r = unit_file_can_install(&paths, root_dir, partial, true);
                 if (r < 0 && errno != ENOENT)
                         return r;
                 else if (r > 0)
@@ -1739,9 +1767,9 @@ UnitFileState unit_file_get_state(
         return r < 0 ? r : state;
 }
 
-int unit_file_query_preset(UnitFileScope scope, const char *name) {
+int unit_file_query_preset(UnitFileScope scope, const char *root_dir, const char *name) {
         _cleanup_strv_free_ char **files = NULL;
-        char **i;
+        char **p;
         int r;
 
         assert(scope >= 0);
@@ -1749,7 +1777,7 @@ int unit_file_query_preset(UnitFileScope scope, const char *name) {
         assert(name);
 
         if (scope == UNIT_FILE_SYSTEM)
-                r = conf_files_list(&files, ".preset", NULL,
+                r = conf_files_list(&files, ".preset", root_dir,
                                     "/etc/systemd/system-preset",
                                     "/usr/local/lib/systemd/system-preset",
                                     "/usr/lib/systemd/system-preset",
@@ -1758,7 +1786,7 @@ int unit_file_query_preset(UnitFileScope scope, const char *name) {
 #endif
                                     NULL);
         else if (scope == UNIT_FILE_GLOBAL)
-                r = conf_files_list(&files, ".preset", NULL,
+                r = conf_files_list(&files, ".preset", root_dir,
                                     "/etc/systemd/user-preset",
                                     "/usr/local/lib/systemd/user-preset",
                                     "/usr/lib/systemd/user-preset",
@@ -1769,10 +1797,10 @@ int unit_file_query_preset(UnitFileScope scope, const char *name) {
         if (r < 0)
                 return r;
 
-        STRV_FOREACH(i, files) {
+        STRV_FOREACH(p, files) {
                 _cleanup_fclose_ FILE *f;
 
-                f = fopen(*i, "re");
+                f = fopen(*p, "re");
                 if (!f) {
                         if (errno == ENOENT)
                                 continue;
@@ -1797,15 +1825,19 @@ int unit_file_query_preset(UnitFileScope scope, const char *name) {
                                 l += 6;
                                 l += strspn(l, WHITESPACE);
 
-                                if (fnmatch(l, name, FNM_NOESCAPE) == 0)
+                                if (fnmatch(l, name, FNM_NOESCAPE) == 0) {
+                                        log_debug("Preset file says enable %s.", name);
                                         return 1;
+                                }
 
                         } else if (first_word(l, "disable")) {
                                 l += 7;
                                 l += strspn(l, WHITESPACE);
 
-                                if (fnmatch(l, name, FNM_NOESCAPE) == 0)
+                                if (fnmatch(l, name, FNM_NOESCAPE) == 0) {
+                                        log_debug("Preset file says disable %s.", name);
                                         return 0;
+                                }
 
                         } else
                                 log_debug("Couldn't parse line '%s'", l);
@@ -1813,6 +1845,7 @@ int unit_file_query_preset(UnitFileScope scope, const char *name) {
         }
 
         /* Default is "enable" */
+        log_debug("Preset file doesn't say anything about %s, enabling.", name);
         return 1;
 }
 
@@ -1821,21 +1854,22 @@ int unit_file_preset(
                 bool runtime,
                 const char *root_dir,
                 char **files,
+                UnitFilePresetMode mode,
                 bool force,
                 UnitFileChange **changes,
                 unsigned *n_changes) {
 
-        _cleanup_lookup_paths_free_ LookupPaths paths = {};
         _cleanup_install_context_done_ InstallContext plus = {}, minus = {};
-        char **i;
+        _cleanup_lookup_paths_free_ LookupPaths paths = {};
         _cleanup_free_ char *config_path = NULL;
-        _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
+        char **i;
         int r, q;
 
         assert(scope >= 0);
         assert(scope < _UNIT_FILE_SCOPE_MAX);
+        assert(mode < _UNIT_FILE_PRESET_MAX);
 
-        r = lookup_paths_init_from_scope(&paths, scope);
+        r = lookup_paths_init_from_scope(&paths, scope, root_dir);
         if (r < 0)
                 return r;
 
@@ -1848,32 +1882,139 @@ int unit_file_preset(
                 if (!unit_name_is_valid(*i, TEMPLATE_VALID))
                         return -EINVAL;
 
-                r = unit_file_query_preset(scope, *i);
+                r = unit_file_query_preset(scope, root_dir, *i);
                 if (r < 0)
                         return r;
 
-                if (r)
+                if (r && mode != UNIT_FILE_PRESET_DISABLE_ONLY)
                         r = install_info_add_auto(&plus, *i);
-                else
+                else if (!r && mode != UNIT_FILE_PRESET_ENABLE_ONLY)
                         r = install_info_add_auto(&minus, *i);
-
+                else
+                        r = 0;
                 if (r < 0)
                         return r;
         }
 
-        r = install_context_mark_for_removal(&minus, &paths, &remove_symlinks_to,
-                                             config_path, root_dir);
+        r = 0;
 
-        q = remove_marked_symlinks(remove_symlinks_to, config_path,
-                                   changes, n_changes, files);
-        if (r == 0)
-                r = q;
+        if (mode != UNIT_FILE_PRESET_ENABLE_ONLY) {
+                _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
 
-        /* Returns number of symlinks that where supposed to be installed. */
-        q = install_context_apply(&plus, &paths, config_path, root_dir, force,
-                                  changes, n_changes);
-        if (r == 0)
-                r = q;
+                r = install_context_mark_for_removal(&minus, &paths, &remove_symlinks_to, config_path, root_dir);
+
+                q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, files);
+                if (r == 0)
+                        r = q;
+        }
+
+        if (mode != UNIT_FILE_PRESET_DISABLE_ONLY) {
+                /* Returns number of symlinks that where supposed to be installed. */
+                q = install_context_apply(&plus, &paths, config_path, root_dir, force, changes, n_changes);
+                if (r == 0)
+                        r = q;
+        }
+
+        return r;
+}
+
+int unit_file_preset_all(
+                UnitFileScope scope,
+                bool runtime,
+                const char *root_dir,
+                UnitFilePresetMode mode,
+                bool force,
+                UnitFileChange **changes,
+                unsigned *n_changes) {
+
+        _cleanup_install_context_done_ InstallContext plus = {}, minus = {};
+        _cleanup_lookup_paths_free_ LookupPaths paths = {};
+        _cleanup_free_ char *config_path = NULL;
+        char **i;
+        int r, q;
+
+        assert(scope >= 0);
+        assert(scope < _UNIT_FILE_SCOPE_MAX);
+        assert(mode < _UNIT_FILE_PRESET_MAX);
+
+        r = lookup_paths_init_from_scope(&paths, scope, root_dir);
+        if (r < 0)
+                return r;
+
+        r = get_config_path(scope, runtime, root_dir, &config_path);
+        if (r < 0)
+                return r;
+
+        STRV_FOREACH(i, paths.unit_path) {
+                _cleanup_closedir_ DIR *d = NULL;
+                _cleanup_free_ char *units_dir;
+
+                units_dir = path_join(root_dir, *i, NULL);
+                if (!units_dir)
+                        return -ENOMEM;
+
+                d = opendir(units_dir);
+                if (!d) {
+                        if (errno == ENOENT)
+                                continue;
+
+                        return -errno;
+                }
+
+                for (;;) {
+                        struct dirent *de;
+
+                        errno = 0;
+                        de = readdir(d);
+                        if (!de && errno != 0)
+                                return -errno;
+
+                        if (!de)
+                                break;
+
+                        if (ignore_file(de->d_name))
+                                continue;
+
+                        if (!unit_name_is_valid(de->d_name, TEMPLATE_VALID))
+                                continue;
+
+                        dirent_ensure_type(d, de);
+
+                        if (de->d_type != DT_REG)
+                                continue;
+
+                        r = unit_file_query_preset(scope, root_dir, de->d_name);
+                        if (r < 0)
+                                return r;
+
+                        if (r && mode != UNIT_FILE_PRESET_DISABLE_ONLY)
+                                r = install_info_add_auto(&plus, de->d_name);
+                        else if (!r && mode != UNIT_FILE_PRESET_ENABLE_ONLY)
+                                r = install_info_add_auto(&minus, de->d_name);
+                        else
+                                r = 0;
+                        if (r < 0)
+                                return r;
+                }
+        }
+
+        r = 0;
+
+        if (mode != UNIT_FILE_PRESET_ENABLE_ONLY) {
+                _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
+
+                r = install_context_mark_for_removal(&minus, &paths, &remove_symlinks_to, config_path, root_dir);
+
+                q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, NULL);
+                if (r == 0)
+                        r = q;
+        }
+
+        if (mode != UNIT_FILE_PRESET_DISABLE_ONLY) {
+                q = install_context_apply(&plus, &paths, config_path, root_dir, force, changes, n_changes);
+                if (r == 0)
+                        r = q;
+        }
 
         return r;
 }
@@ -1894,8 +2035,6 @@ int unit_file_get_list(
 
         _cleanup_lookup_paths_free_ LookupPaths paths = {};
         char **i;
-        _cleanup_free_ char *buf = NULL;
-        _cleanup_closedir_ DIR *d = NULL;
         int r;
 
         assert(scope >= 0);
@@ -1905,26 +2044,17 @@ int unit_file_get_list(
         if (root_dir && scope != UNIT_FILE_SYSTEM)
                 return -EINVAL;
 
-        r = lookup_paths_init_from_scope(&paths, scope);
+        r = lookup_paths_init_from_scope(&paths, scope, root_dir);
         if (r < 0)
                 return r;
 
         STRV_FOREACH(i, paths.unit_path) {
-                const char *units_dir;
-
-                free(buf);
-                buf = NULL;
-
-                if (root_dir) {
-                        if (asprintf(&buf, "%s/%s", root_dir, *i) < 0)
-                                return -ENOMEM;
+                _cleanup_closedir_ DIR *d = NULL;
+                _cleanup_free_ char *units_dir;
 
-                        units_dir = buf;
-                } else
-                        units_dir = *i;
-
-                if (d)
-                        closedir(d);
+                units_dir = path_join(root_dir, *i, NULL);
+                if (!units_dir)
+                        return -ENOMEM;
 
                 d = opendir(units_dir);
                 if (!d) {
@@ -1935,8 +2065,8 @@ int unit_file_get_list(
                 }
 
                 for (;;) {
-                        struct dirent *de;
                         _cleanup_unitfilelist_free_ UnitFileList *f = NULL;
+                        struct dirent *de;
 
                         errno = 0;
                         de = readdir(d);
@@ -1955,15 +2085,9 @@ int unit_file_get_list(
                         if (hashmap_get(h, de->d_name))
                                 continue;
 
-                        r = dirent_ensure_type(d, de);
-                        if (r < 0) {
-                                if (r == -ENOENT)
-                                        continue;
-
-                                return r;
-                        }
+                        dirent_ensure_type(d, de);
 
-                        if (de->d_type != DT_LNK && de->d_type != DT_REG)
+                        if (!IN_SET(de->d_type, DT_LNK, DT_REG))
                                 continue;
 
                         f = new0(UnitFileList, 1);
@@ -2035,3 +2159,11 @@ static const char* const unit_file_change_type_table[_UNIT_FILE_CHANGE_TYPE_MAX]
 };
 
 DEFINE_STRING_TABLE_LOOKUP(unit_file_change_type, UnitFileChangeType);
+
+static const char* const unit_file_preset_mode_table[_UNIT_FILE_PRESET_MAX] = {
+        [UNIT_FILE_PRESET_FULL] = "full",
+        [UNIT_FILE_PRESET_ENABLE_ONLY] = "enable-only",
+        [UNIT_FILE_PRESET_DISABLE_ONLY] = "disable-only",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(unit_file_preset_mode, UnitFilePresetMode);
index 5d57b1b..ff16d9f 100644 (file)
@@ -45,6 +45,14 @@ typedef enum UnitFileState {
         _UNIT_FILE_STATE_INVALID = -1
 } UnitFileState;
 
+typedef enum UnitFilePresetMode {
+        UNIT_FILE_PRESET_FULL,
+        UNIT_FILE_PRESET_ENABLE_ONLY,
+        UNIT_FILE_PRESET_DISABLE_ONLY,
+        _UNIT_FILE_PRESET_MAX,
+        _UNIT_FILE_PRESET_INVALID = -1
+} UnitFilePresetMode;
+
 typedef enum UnitFileChangeType {
         UNIT_FILE_SYMLINK,
         UNIT_FILE_UNLINK,
@@ -71,13 +79,16 @@ typedef struct {
         char **aliases;
         char **wanted_by;
         char **required_by;
+
+        char *default_instance;
 } InstallInfo;
 
 int unit_file_enable(UnitFileScope scope, bool runtime, const char *root_dir, char **files, bool force, UnitFileChange **changes, unsigned *n_changes);
 int unit_file_disable(UnitFileScope scope, bool runtime, const char *root_dir, char **files, UnitFileChange **changes, unsigned *n_changes);
 int unit_file_reenable(UnitFileScope scope, bool runtime, const char *root_dir, char **files, bool force, UnitFileChange **changes, unsigned *n_changes);
 int unit_file_link(UnitFileScope scope, bool runtime, const char *root_dir, char **files, bool force, UnitFileChange **changes, unsigned *n_changes);
-int unit_file_preset(UnitFileScope scope, bool runtime, const char *root_dir, char **files, bool force, UnitFileChange **changes, unsigned *n_changes);
+int unit_file_preset(UnitFileScope scope, bool runtime, const char *root_dir, char **files, UnitFilePresetMode mode, bool force, UnitFileChange **changes, unsigned *n_changes);
+int unit_file_preset_all(UnitFileScope scope, bool runtime, const char *root_dir, UnitFilePresetMode mode, bool force, UnitFileChange **changes, unsigned *n_changes);
 int unit_file_mask(UnitFileScope scope, bool runtime, const char *root_dir, char **files, bool force, UnitFileChange **changes, unsigned *n_changes);
 int unit_file_unmask(UnitFileScope scope, bool runtime, const char *root_dir, char **files, UnitFileChange **changes, unsigned *n_changes);
 int unit_file_set_default(UnitFileScope scope, const char *root_dir, const char *file, bool force, UnitFileChange **changes, unsigned *n_changes);
@@ -90,10 +101,13 @@ int unit_file_get_list(UnitFileScope scope, const char *root_dir, Hashmap *h);
 void unit_file_list_free(Hashmap *h);
 void unit_file_changes_free(UnitFileChange *changes, unsigned n_changes);
 
-int unit_file_query_preset(UnitFileScope scope, const char *name);
+int unit_file_query_preset(UnitFileScope scope, const char *root_dir, const char *name);
 
 const char *unit_file_state_to_string(UnitFileState s) _const_;
 UnitFileState unit_file_state_from_string(const char *s) _pure_;
 
 const char *unit_file_change_type_to_string(UnitFileChangeType s) _const_;
 UnitFileChangeType unit_file_change_type_from_string(const char *s) _pure_;
+
+const char *unit_file_preset_mode_to_string(UnitFilePresetMode m) _const_;
+UnitFilePresetMode unit_file_preset_mode_from_string(const char *s) _pure_;
index beca48a..78d98c4 100644 (file)
@@ -27,9 +27,7 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
-#ifdef HAVE_XATTR
 #include <sys/xattr.h>
-#endif
 #ifdef HAVE_SELINUX
 #include <selinux/selinux.h>
 #include <selinux/label.h>
@@ -77,9 +75,9 @@ static int smack_relabel_in_dev(const char *path) {
         else
                 return 0;
 
-        r = setxattr(path, "security.SMACK64", label, strlen(label), 0);
+        r = lsetxattr(path, "security.SMACK64", label, strlen(label), 0);
         if (r < 0) {
-                log_error("Smack relabeling \"%s\" %s", path, strerror(errno));
+                log_error("Smack relabeling \"%s\" %m", path);
                 return -errno;
         }
 #endif
@@ -295,6 +293,8 @@ int label_socket_set(const char *label) {
 void label_context_clear(void) {
 
 #ifdef HAVE_SELINUX
+        PROTECT_ERRNO;
+
         if (!use_selinux())
                 return;
 
@@ -305,6 +305,8 @@ void label_context_clear(void) {
 void label_socket_clear(void) {
 
 #ifdef HAVE_SELINUX
+        PROTECT_ERRNO;
+
         if (!use_selinux())
                 return;
 
index 86d4271..1351278 100644 (file)
@@ -42,8 +42,6 @@ int label_get_create_label_from_exe(const char *exe, char **label);
 
 int label_mkdir(const char *path, mode_t mode);
 
-void label_retest_selinux(void);
-
 int label_bind(int fd, const struct sockaddr *addr, socklen_t addrlen);
 
 int label_apply(const char *path, const char *label);
index e55b91c..c020f7e 100644 (file)
 #define LIST_FIND_HEAD(name,item,head)                                  \
         do {                                                            \
                 typeof(*(item)) *_item = (item);                        \
-                assert(_item);                                          \
-                while (_item->name##_prev)                              \
-                       _item = _item->name##_prev;                      \
-                (head) = _item;                                         \
+                if (!_item)                                             \
+                        (head) = NULL;                                  \
+                else {                                                  \
+                        while (_item->name##_prev)                      \
+                                _item = _item->name##_prev;             \
+                        (head) = _item;                                 \
+                }                                                       \
         } while (false)
 
 /* Find the tail of the list */
 #define LIST_FIND_TAIL(name,item,tail)                                  \
         do {                                                            \
                 typeof(*(item)) *_item = (item);                        \
-                assert(_item);                                          \
-                while (_item->name##_next)                              \
-                        _item = _item->name##_next;                     \
-                (tail) = _item;                                         \
+                if (!_item)                                             \
+                        (tail) = NULL;                                  \
+                else {                                                  \
+                        while (_item->name##_next)                      \
+                                _item = _item->name##_next;             \
+                        (tail) = _item;                                 \
+                }                                                       \
         } while (false)
 
 /* Insert an item after another one (a = where, b = what) */
diff --git a/src/shared/locale-util.c b/src/shared/locale-util.c
new file mode 100644 (file)
index 0000000..8d2c363
--- /dev/null
@@ -0,0 +1,205 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/mman.h>
+
+#include "set.h"
+#include "util.h"
+#include "utf8.h"
+#include "strv.h"
+
+#include "locale-util.h"
+
+static int add_locales_from_archive(Set *locales) {
+        /* Stolen from glibc... */
+
+        struct locarhead {
+                uint32_t magic;
+                /* Serial number.  */
+                uint32_t serial;
+                /* Name hash table.  */
+                uint32_t namehash_offset;
+                uint32_t namehash_used;
+                uint32_t namehash_size;
+                /* String table.  */
+                uint32_t string_offset;
+                uint32_t string_used;
+                uint32_t string_size;
+                /* Table with locale records.  */
+                uint32_t locrectab_offset;
+                uint32_t locrectab_used;
+                uint32_t locrectab_size;
+                /* MD5 sum hash table.  */
+                uint32_t sumhash_offset;
+                uint32_t sumhash_used;
+                uint32_t sumhash_size;
+        };
+
+        struct namehashent {
+                /* Hash value of the name.  */
+                uint32_t hashval;
+                /* Offset of the name in the string table.  */
+                uint32_t name_offset;
+                /* Offset of the locale record.  */
+                uint32_t locrec_offset;
+        };
+
+        const struct locarhead *h;
+        const struct namehashent *e;
+        const void *p = MAP_FAILED;
+        _cleanup_close_ int fd = -1;
+        size_t sz = 0;
+        struct stat st;
+        unsigned i;
+        int r;
+
+        fd = open("/usr/lib/locale/locale-archive", O_RDONLY|O_NOCTTY|O_CLOEXEC);
+        if (fd < 0)
+                return errno == ENOENT ? 0 : -errno;
+
+        if (fstat(fd, &st) < 0)
+                return -errno;
+
+        if (!S_ISREG(st.st_mode))
+                return -EBADMSG;
+
+        if (st.st_size < (off_t) sizeof(struct locarhead))
+                return -EBADMSG;
+
+        p = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
+        if (p == MAP_FAILED)
+                return -errno;
+
+        h = (const struct locarhead *) p;
+        if (h->magic != 0xde020109 ||
+            h->namehash_offset + h->namehash_size > st.st_size ||
+            h->string_offset + h->string_size > st.st_size ||
+            h->locrectab_offset + h->locrectab_size > st.st_size ||
+            h->sumhash_offset + h->sumhash_size > st.st_size) {
+                r = -EBADMSG;
+                goto finish;
+        }
+
+        e = (const struct namehashent*) ((const uint8_t*) p + h->namehash_offset);
+        for (i = 0; i < h->namehash_size; i++) {
+                char *z;
+
+                if (e[i].locrec_offset == 0)
+                        continue;
+
+                if (!utf8_is_valid((char*) p + e[i].name_offset))
+                        continue;
+
+                z = strdup((char*) p + e[i].name_offset);
+                if (!z) {
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                r = set_consume(locales, z);
+                if (r < 0)
+                        goto finish;
+        }
+
+        r = 0;
+
+ finish:
+        if (p != MAP_FAILED)
+                munmap((void*) p, sz);
+
+        return r;
+}
+
+static int add_locales_from_libdir (Set *locales) {
+        _cleanup_closedir_ DIR *dir = NULL;
+        struct dirent *entry;
+        int r;
+
+        dir = opendir("/usr/lib/locale");
+        if (!dir)
+                return errno == ENOENT ? 0 : -errno;
+
+        FOREACH_DIRENT(entry, dir, return -errno) {
+                char *z;
+
+                if (entry->d_type != DT_DIR)
+                        continue;
+
+                z = strdup(entry->d_name);
+                if (!z)
+                        return -ENOMEM;
+
+                r = set_consume(locales, z);
+                if (r < 0 && r != -EEXIST)
+                        return r;
+        }
+
+        return 0;
+}
+
+int get_locales(char ***ret) {
+        _cleanup_set_free_ Set *locales = NULL;
+        _cleanup_strv_free_ char **l = NULL;
+        int r;
+
+        locales = set_new(string_hash_func, string_compare_func);
+        if (!locales)
+                return -ENOMEM;
+
+        r = add_locales_from_archive(locales);
+        if (r < 0 && r != -ENOENT)
+                return r;
+
+        r = add_locales_from_libdir(locales);
+        if (r < 0)
+                return r;
+
+        l = set_get_strv(locales);
+        if (!l)
+                return -ENOMEM;
+
+        strv_sort(l);
+
+        *ret = l;
+        l = NULL;
+
+        return 0;
+}
+
+bool locale_is_valid(const char *name) {
+
+        if (isempty(name))
+                return false;
+
+        if (strlen(name) >= 128)
+                return false;
+
+        if (!utf8_is_valid(name))
+                return false;
+
+        if (!filename_is_safe(name))
+                return false;
+
+        if (!string_is_safe(name))
+                return false;
+
+        return true;
+}
diff --git a/src/shared/locale-util.h b/src/shared/locale-util.h
new file mode 100644 (file)
index 0000000..7be9af2
--- /dev/null
@@ -0,0 +1,25 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+int get_locales(char ***l);
+bool locale_is_valid(const char *name);
index 8d1067c..26c604a 100644 (file)
@@ -51,6 +51,8 @@ static bool syslog_is_stream = false;
 static bool show_color = false;
 static bool show_location = false;
 
+static bool upgrade_syslog_to_journal = false;
+
 /* Akin to glibc's __abort_msg; which is private and we hence cannot
  * use here. */
 static char *log_abort_msg = NULL;
@@ -62,7 +64,7 @@ void log_close_console(void) {
 
         if (getpid() == 1) {
                 if (console_fd >= 3)
-                        close_nointr_nofail(console_fd);
+                        safe_close(console_fd);
 
                 console_fd = -1;
         }
@@ -84,12 +86,7 @@ static int log_open_console(void) {
 }
 
 void log_close_kmsg(void) {
-
-        if (kmsg_fd < 0)
-                return;
-
-        close_nointr_nofail(kmsg_fd);
-        kmsg_fd = -1;
+        kmsg_fd = safe_close(kmsg_fd);
 }
 
 static int log_open_kmsg(void) {
@@ -105,12 +102,7 @@ static int log_open_kmsg(void) {
 }
 
 void log_close_syslog(void) {
-
-        if (syslog_fd < 0)
-                return;
-
-        close_nointr_nofail(syslog_fd);
-        syslog_fd = -1;
+        syslog_fd = safe_close(syslog_fd);
 }
 
 static int create_log_socket(int type) {
@@ -152,7 +144,7 @@ static int log_open_syslog(void) {
         }
 
         if (connect(syslog_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) {
-                close_nointr_nofail(syslog_fd);
+                safe_close(syslog_fd);
 
                 /* Some legacy syslog systems still use stream
                  * sockets. They really shouldn't. But what can we
@@ -180,12 +172,7 @@ fail:
 }
 
 void log_close_journal(void) {
-
-        if (journal_fd < 0)
-                return;
-
-        close_nointr_nofail(journal_fd);
-        journal_fd = -1;
+        journal_fd = safe_close(journal_fd);
 }
 
 static int log_open_journal(void) {
@@ -282,6 +269,13 @@ void log_set_target(LogTarget target) {
         assert(target >= 0);
         assert(target < _LOG_TARGET_MAX);
 
+        if (upgrade_syslog_to_journal) {
+                if (target == LOG_TARGET_SYSLOG)
+                        target = LOG_TARGET_JOURNAL;
+                else if (target == LOG_TARGET_SYSLOG_OR_KMSG)
+                        target = LOG_TARGET_JOURNAL_OR_KMSG;
+        }
+
         log_target = target;
 }
 
@@ -393,7 +387,7 @@ static int write_to_syslog(
         if (strftime(header_time, sizeof(header_time), "%h %e %T ", tm) <= 0)
                 return -EINVAL;
 
-        snprintf(header_pid, sizeof(header_pid), "[%lu]: ", (unsigned long) getpid());
+        snprintf(header_pid, sizeof(header_pid), "["PID_FMT"]: ", getpid());
         char_array_0(header_pid);
 
         IOVEC_SET_STRING(iovec[0], header_priority);
@@ -441,7 +435,7 @@ static int write_to_kmsg(
         snprintf(header_priority, sizeof(header_priority), "<%i>", level);
         char_array_0(header_priority);
 
-        snprintf(header_pid, sizeof(header_pid), "[%lu]: ", (unsigned long) getpid());
+        snprintf(header_pid, sizeof(header_pid), "["PID_FMT"]: ", getpid());
         char_array_0(header_pid);
 
         IOVEC_SET_STRING(iovec[0], header_priority);
@@ -877,41 +871,62 @@ int log_set_max_level_from_string(const char *e) {
         return 0;
 }
 
-void log_parse_environment(void) {
-        _cleanup_free_ char *line = NULL;
-        const char *e;
-        int r;
+static int parse_proc_cmdline_item(const char *key, const char *value) {
 
-        r = proc_cmdline(&line);
-        if (r < 0)
-                log_warning("Failed to read /proc/cmdline. Ignoring: %s", strerror(-r));
-        else if (r > 0) {
-                char *w, *state;
-                size_t l;
+        /*
+         * The systemd.log_xyz= settings are parsed by all tools, and
+         * so is "debug".
+         *
+         * However, "quiet" is only parsed by PID 1!
+         */
 
-                FOREACH_WORD_QUOTED(w, l, line, state) {
-                        if (l == 5 && startswith(w, "debug")) {
-                                log_set_max_level(LOG_DEBUG);
-                                break;
-                        }
-                }
+        if (streq(key, "debug") && !value)
+                log_set_max_level(LOG_DEBUG);
+
+        else if (streq(key, "systemd.log_target") && value) {
+
+                if (log_set_target_from_string(value) < 0)
+                        log_warning("Failed to parse log target '%s'. Ignoring.", value);
+
+        } else if (streq(key, "systemd.log_level") && value) {
+
+                if (log_set_max_level_from_string(value) < 0)
+                        log_warning("Failed to parse log level '%s'. Ignoring.", value);
+
+        } else if (streq(key, "systemd.log_color") && value) {
+
+                if (log_show_color_from_string(value) < 0)
+                        log_warning("Failed to parse log color setting '%s'. Ignoring.", value);
+
+        } else if (streq(key, "systemd.log_location") && value) {
+
+                if (log_show_location_from_string(value) < 0)
+                        log_warning("Failed to parse log location setting '%s'. Ignoring.", value);
         }
 
+        return 0;
+}
+
+void log_parse_environment(void) {
+        const char *e;
+
+        parse_proc_cmdline(parse_proc_cmdline_item);
+
         e = secure_getenv("SYSTEMD_LOG_TARGET");
         if (e && log_set_target_from_string(e) < 0)
-                log_warning("Failed to parse log target %s. Ignoring.", e);
+                log_warning("Failed to parse log target '%s'. Ignoring.", e);
 
         e = secure_getenv("SYSTEMD_LOG_LEVEL");
         if (e && log_set_max_level_from_string(e) < 0)
-                log_warning("Failed to parse log level %s. Ignoring.", e);
+                log_warning("Failed to parse log level '%s'. Ignoring.", e);
 
         e = secure_getenv("SYSTEMD_LOG_COLOR");
         if (e && log_show_color_from_string(e) < 0)
-                log_warning("Failed to parse bool %s. Ignoring.", e);
+                log_warning("Failed to parse bool '%s'. Ignoring.", e);
 
         e = secure_getenv("SYSTEMD_LOG_LOCATION");
         if (e && log_show_location_from_string(e) < 0)
-                log_warning("Failed to parse bool %s. Ignoring.", e);
+                log_warning("Failed to parse bool '%s'. Ignoring.", e);
 }
 
 LogTarget log_get_target(void) {
@@ -967,7 +982,7 @@ bool log_on_console(void) {
         return syslog_fd < 0 && kmsg_fd < 0 && journal_fd < 0;
 }
 
-static const char *const log_target_table[] = {
+static const char *const log_target_table[_LOG_TARGET_MAX] = {
         [LOG_TARGET_CONSOLE] = "console",
         [LOG_TARGET_KMSG] = "kmsg",
         [LOG_TARGET_JOURNAL] = "journal",
@@ -997,3 +1012,7 @@ void log_received_signal(int level, const struct signalfd_siginfo *si) {
                          signal_to_string(si->ssi_signo));
 
 }
+
+void log_set_upgrade_syslog_to_journal(bool b) {
+        upgrade_syslog_to_journal = b;
+}
index 794af7b..9918381 100644 (file)
@@ -172,3 +172,5 @@ LogTarget log_target_from_string(const char *s) _pure_;
 #define MESSAGE_ID(x) "MESSAGE_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(x)
 
 void log_received_signal(int level, const struct signalfd_siginfo *si);
+
+void log_set_upgrade_syslog_to_journal(bool b);
index 61c3652..5538dd3 100644 (file)
@@ -124,6 +124,11 @@ static bool print_multiline(FILE *f, unsigned prefix, unsigned n_columns, Output
                 }
         }
 
+        /* A special case: make sure that we print a newline when
+           the message is empty. */
+        if (message_len == 0)
+                fputs("\n", f);
+
         for (pos = message;
              pos < message + message_len;
              pos = end + 1, line++) {
@@ -330,7 +335,7 @@ static int output_short(
                         r = strftime(buf, sizeof(buf), "%b %d %H:%M:%S", localtime_r(&t, &tm));
                         if (r > 0) {
                                 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
-                                         ".%06llu", x % USEC_PER_SEC);
+                                         ".%06llu", (unsigned long long) (x % USEC_PER_SEC));
                         }
                         break;
                 default:
@@ -526,12 +531,12 @@ static int output_export(
 
         fprintf(f,
                 "__CURSOR=%s\n"
-                "__REALTIME_TIMESTAMP=%llu\n"
-                "__MONOTONIC_TIMESTAMP=%llu\n"
+                "__REALTIME_TIMESTAMP="USEC_FMT"\n"
+                "__MONOTONIC_TIMESTAMP="USEC_FMT"\n"
                 "_BOOT_ID=%s\n",
                 cursor,
-                (unsigned long long) realtime,
-                (unsigned long long) monotonic,
+                realtime,
+                monotonic,
                 sd_id128_to_string(boot_id, sid));
 
         JOURNAL_FOREACH_DATA_RETVAL(j, data, length, r) {
@@ -542,7 +547,9 @@ static int output_export(
                     startswith(data, "_BOOT_ID="))
                         continue;
 
-                if (!utf8_is_printable(data, length)) {
+                if (utf8_is_printable_newline(data, length, false))
+                        fwrite(data, length, 1, f);
+                else {
                         const char *c;
                         uint64_t le64;
 
@@ -557,8 +564,7 @@ static int output_export(
                         le64 = htole64(length - (c - (const char*) data) - 1);
                         fwrite(&le64, sizeof(le64), 1, f);
                         fwrite(c + 1, length - (c - (const char*) data) - 1, 1, f);
-                } else
-                        fwrite(data, length, 1, f);
+                }
 
                 fputc('\n', f);
         }
@@ -667,12 +673,12 @@ static int output_json(
                 fprintf(f,
                         "{\n"
                         "\t\"__CURSOR\" : \"%s\",\n"
-                        "\t\"__REALTIME_TIMESTAMP\" : \"%llu\",\n"
-                        "\t\"__MONOTONIC_TIMESTAMP\" : \"%llu\",\n"
+                        "\t\"__REALTIME_TIMESTAMP\" : \""USEC_FMT"\",\n"
+                        "\t\"__MONOTONIC_TIMESTAMP\" : \""USEC_FMT"\",\n"
                         "\t\"_BOOT_ID\" : \"%s\"",
                         cursor,
-                        (unsigned long long) realtime,
-                        (unsigned long long) monotonic,
+                        realtime,
+                        monotonic,
                         sd_id128_to_string(boot_id, sid));
         else {
                 if (mode == OUTPUT_JSON_SSE)
@@ -680,12 +686,12 @@ static int output_json(
 
                 fprintf(f,
                         "{ \"__CURSOR\" : \"%s\", "
-                        "\"__REALTIME_TIMESTAMP\" : \"%llu\", "
-                        "\"__MONOTONIC_TIMESTAMP\" : \"%llu\", "
+                        "\"__REALTIME_TIMESTAMP\" : \""USEC_FMT"\", "
+                        "\"__MONOTONIC_TIMESTAMP\" : \""USEC_FMT"\", "
                         "\"_BOOT_ID\" : \"%s\"",
                         cursor,
-                        (unsigned long long) realtime,
-                        (unsigned long long) monotonic,
+                        realtime,
+                        monotonic,
                         sd_id128_to_string(boot_id, sid));
         }
 
@@ -922,6 +928,21 @@ int output_journal(
         return ret;
 }
 
+static int maybe_print_begin_newline(FILE *f, OutputFlags *flags) {
+        assert(f);
+        assert(flags);
+
+        if (!(*flags & OUTPUT_BEGIN_NEWLINE))
+                return 0;
+
+        /* Print a beginning new line if that's request, but only once
+         * on the first line we print. */
+
+        fputc('\n', f);
+        *flags &= ~OUTPUT_BEGIN_NEWLINE;
+        return 0;
+}
+
 static int show_journal(FILE *f,
                         sd_journal *j,
                         OutputMode mode,
@@ -979,6 +1000,7 @@ static int show_journal(FILE *f,
                         }
 
                         line ++;
+                        maybe_print_begin_newline(f, &flags);
 
                         r = output_journal(f, j, mode, n_columns, flags, ellipsized);
                         if (r < 0)
@@ -999,8 +1021,10 @@ static int show_journal(FILE *f,
                         if (r < 0)
                                 goto finish;
 
-                        if (r > 0 && not_before < cutoff)
+                        if (r > 0 && not_before < cutoff) {
+                                maybe_print_begin_newline(f, &flags);
                                 fprintf(f, "Warning: Journal has been rotated since unit was started. Log output is incomplete or unavailable.\n");
+                        }
 
                         warn_cutoff = false;
                 }
@@ -1008,7 +1032,7 @@ static int show_journal(FILE *f,
                 if (!(flags & OUTPUT_FOLLOW))
                         break;
 
-                r = sd_journal_wait(j, (usec_t) -1);
+                r = sd_journal_wait(j, USEC_INFINITY);
                 if (r < 0)
                         goto finish;
 
@@ -1076,7 +1100,7 @@ int add_matches_for_user_unit(sd_journal *j, const char *unit, uid_t uid) {
         m2 = strappenda("USER_UNIT=", unit);
         m3 = strappenda("COREDUMP_USER_UNIT=", unit);
         m4 = strappenda("OBJECT_SYSTEMD_USER_UNIT=", unit);
-        sprintf(muid, "_UID=%lu", (unsigned long) uid);
+        sprintf(muid, "_UID="UID_FMT, uid);
 
         (void) (
                 /* Look for messages from the user service itself */
@@ -1116,7 +1140,7 @@ int add_matches_for_user_unit(sd_journal *j, const char *unit, uid_t uid) {
 }
 
 static int get_boot_id_for_machine(const char *machine, sd_id128_t *boot_id) {
-        _cleanup_close_pipe_ int pair[2] = { -1, -1 };
+        _cleanup_close_pair_ int pair[2] = { -1, -1 };
         _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, rootfd = -1;
         pid_t pid, child;
         siginfo_t si;
@@ -1134,7 +1158,7 @@ static int get_boot_id_for_machine(const char *machine, sd_id128_t *boot_id) {
         if (r < 0)
                 return r;
 
-        r = namespace_open(pid, &pidnsfd, &mntnsfd, &rootfd);
+        r = namespace_open(pid, &pidnsfd, &mntnsfd, NULL, &rootfd);
         if (r < 0)
                 return r;
 
@@ -1148,10 +1172,9 @@ static int get_boot_id_for_machine(const char *machine, sd_id128_t *boot_id) {
         if (child == 0) {
                 int fd;
 
-                close_nointr_nofail(pair[0]);
-                pair[0] = -1;
+                pair[0] = safe_close(pair[0]);
 
-                r = namespace_enter(pidnsfd, mntnsfd, rootfd);
+                r = namespace_enter(pidnsfd, mntnsfd, -1, rootfd);
                 if (r < 0)
                         _exit(EXIT_FAILURE);
 
@@ -1160,7 +1183,7 @@ static int get_boot_id_for_machine(const char *machine, sd_id128_t *boot_id) {
                         _exit(EXIT_FAILURE);
 
                 k = loop_read(fd, buf, 36, false);
-                close_nointr_nofail(fd);
+                safe_close(fd);
                 if (k != 36)
                         _exit(EXIT_FAILURE);
 
@@ -1171,8 +1194,7 @@ static int get_boot_id_for_machine(const char *machine, sd_id128_t *boot_id) {
                 _exit(EXIT_SUCCESS);
         }
 
-        close_nointr_nofail(pair[1]);
-        pair[1] = -1;
+        pair[1] = safe_close(pair[1]);
 
         r = wait_for_terminate(child, &si);
         if (r < 0 || si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS)
index 3a99160..187ee59 100644 (file)
@@ -25,7 +25,7 @@
 #include <unistd.h>
 #include <sys/types.h>
 
-#include <systemd/sd-journal.h>
+#include "systemd/sd-journal.h"
 
 #include "util.h"
 #include "output-mode.h"
index 5fd67c7..179b24c 100644 (file)
         _Pragma("GCC diagnostic push");                                 \
         _Pragma("GCC diagnostic ignored \"-Wnonnull\"")
 
+#define DISABLE_WARNING_SHADOW                                          \
+        _Pragma("GCC diagnostic push");                                 \
+        _Pragma("GCC diagnostic ignored \"-Wshadow\"")
+
 #define REENABLE_WARNING                                                \
         _Pragma("GCC diagnostic pop")
 
@@ -98,7 +102,20 @@ static inline size_t ALIGN_TO(size_t l, size_t ali) {
         return ((l + ali - 1) & ~(ali - 1));
 }
 
-#define ALIGN_TO_PTR(p, ali) ((void*) ALIGN_TO((unsigned long) p))
+#define ALIGN_TO_PTR(p, ali) ((void*) ALIGN_TO((unsigned long) p, ali))
+
+/* align to next higher power-of-2 (except for: 0 => 0, overflow => 0) */
+static inline unsigned long ALIGN_POWER2(unsigned long u) {
+        /* clz(0) is undefined */
+        if (u == 1)
+                return 1;
+
+        /* left-shift overflow is undefined */
+        if (__builtin_clzl(u - 1UL) < 1)
+                return 0;
+
+        return 1UL << (sizeof(u) * 8 - __builtin_clzl(u - 1UL));
+}
 
 #define ELEMENTSOF(x) (sizeof(x)/sizeof((x)[0]))
 
@@ -116,40 +133,55 @@ static inline size_t ALIGN_TO(size_t l, size_t ali) {
                 })
 
 #undef MAX
-#define MAX(a,b)                                 \
-        __extension__ ({                         \
-                        typeof(a) _a = (a);      \
-                        typeof(b) _b = (b);      \
-                        _a > _b ? _a : _b;       \
+#define MAX(a,b)                                        \
+        __extension__ ({                                \
+                        const typeof(a) _a = (a);       \
+                        const typeof(b) _b = (b);       \
+                        _a > _b ? _a : _b;              \
                 })
 
-#define MAX3(x,y,z)                              \
-        __extension__ ({                         \
-                        typeof(x) _c = MAX(x,y); \
-                        MAX(_c, z);              \
+/* evaluates to (void) if _A or _B are not constant or of different types */
+#define CONST_MAX(_A, _B) \
+        __extension__ (__builtin_choose_expr(                           \
+                __builtin_constant_p(_A) &&                             \
+                __builtin_constant_p(_B) &&                             \
+                __builtin_types_compatible_p(typeof(_A), typeof(_B)),   \
+                ((_A) > (_B)) ? (_A) : (_B),                            \
+                (void)0))
+
+#define MAX3(x,y,z)                                     \
+        __extension__ ({                                \
+                        const typeof(x) _c = MAX(x,y);  \
+                        MAX(_c, z);                     \
                 })
 
 #undef MIN
-#define MIN(a,b)                                \
-        __extension__ ({                        \
-                        typeof(a) _a = (a);     \
-                        typeof(b) _b = (b);     \
-                        _a < _b ? _a : _b;      \
+#define MIN(a,b)                                        \
+        __extension__ ({                                \
+                        const typeof(a) _a = (a);       \
+                        const typeof(b) _b = (b);       \
+                        _a < _b ? _a : _b;              \
+                })
+
+#define MIN3(x,y,z)                                     \
+        __extension__ ({                                \
+                        const typeof(x) _c = MIN(x,y);  \
+                        MIN(_c, z);                     \
                 })
 
-#define LESS_BY(A,B)                            \
-        __extension__ ({                        \
-                        typeof(A) _A = (A);     \
-                        typeof(B) _B = (B);     \
-                        _A > _B ? _A - _B : 0;  \
+#define LESS_BY(A,B)                                    \
+        __extension__ ({                                \
+                        const typeof(A) _A = (A);       \
+                        const typeof(B) _B = (B);       \
+                        _A > _B ? _A - _B : 0;          \
                 })
 
 #ifndef CLAMP
 #define CLAMP(x, low, high)                                             \
         __extension__ ({                                                \
-                        typeof(x) _x = (x);                             \
-                        typeof(low) _low = (low);                       \
-                        typeof(high) _high = (high);                    \
+                        const typeof(x) _x = (x);                       \
+                        const typeof(low) _low = (low);                 \
+                        const typeof(high) _high = (high);              \
                         ((_x > _high) ? _high : ((_x < _low) ? _low : _x)); \
                 })
 #endif
@@ -218,6 +250,9 @@ static inline size_t ALIGN_TO(size_t l, size_t ali) {
 #define PTR_TO_UINT64(p) ((uint64_t) ((uintptr_t) (p)))
 #define UINT64_TO_PTR(u) ((void *) ((uintptr_t) (u)))
 
+#define PTR_TO_SIZE(p) ((size_t) ((uintptr_t) (p)))
+#define SIZE_TO_PTR(u) ((void *) ((uintptr_t) (u)))
+
 #define memzero(x,l) (memset((x), 0, (l)))
 #define zero(x) (memzero(&(x), sizeof(x)))
 
@@ -324,13 +359,14 @@ do {                                                                    \
 #define SET_FLAG(v, flag, b) \
         (v) = (b) ? ((v) | (flag)) : ((v) & ~(flag))
 
-#define IN_SET(x, ...)                                                  \
+#define IN_SET(x, y, ...)                                               \
         ({                                                              \
-                const typeof(x) _x = (x);                               \
+                const typeof(y) _y = (y);                               \
+                const typeof(_y) _x = (x);                              \
                 unsigned _i;                                            \
                 bool _found = false;                                    \
-                for (_i = 0; _i < sizeof((const typeof(_x)[]) { __VA_ARGS__ })/sizeof(const typeof(_x)); _i++) \
-                        if (((const typeof(_x)[]) { __VA_ARGS__ })[_i] == _x) { \
+                for (_i = 0; _i < 1 + sizeof((const typeof(_x)[]) { __VA_ARGS__ })/sizeof(const typeof(_x)); _i++) \
+                        if (((const typeof(_x)[]) { _y, __VA_ARGS__ })[_i] == _x) { \
                                 _found = true;                          \
                                 break;                                  \
                         }                                               \
index b09ca33..86bce77 100644 (file)
@@ -33,6 +33,8 @@
 #include <linux/input.h>
 #include <sys/socket.h>
 #include <linux/if_link.h>
+#include <linux/loop.h>
+#include <linux/if_link.h>
 
 #ifdef HAVE_AUDIT
 #include <libaudit.h>
@@ -48,6 +50,9 @@
 #define RLIMIT_RTTIME 15
 #endif
 
+/* If RLIMIT_RTTIME is not defined, then we cannot use RLIMIT_NLIMITS as is */
+#define _RLIMIT_MAX (RLIMIT_RTTIME+1 > RLIMIT_NLIMITS ? RLIMIT_RTTIME+1 : RLIMIT_NLIMITS)
+
 #ifndef F_LINUX_SPECIFIC_BASE
 #define F_LINUX_SPECIFIC_BASE 1024
 #endif
 #define IP_TRANSPARENT 19
 #endif
 
-#ifndef IFLA_CARRIER
-  #define IFLA_CARRIER 33
-  #ifndef IFLA_NUM_RX_QUEUES
-    #define IFLA_NUM_RX_QUEUES 32
-    #ifndef IFLA_NUM_TX_QUEUES
-      #define IFLA_NUM_TX_QUEUES 31
-      #ifndef IFLA_PROMISCUITY
-        #define IFLA_PROMISCUITY 30
-      #endif
-    #endif
-  #endif
+#ifndef SOL_NETLINK
+#define SOL_NETLINK 270
 #endif
 
 #if !HAVE_DECL_PIVOT_ROOT
@@ -215,7 +211,8 @@ struct btrfs_ioctl_fs_info_args {
 #endif
 
 #ifndef BTRFS_IOC_DEFRAG
-#define BTRFS_IOC_DEFRAG _IOW(BTRFS_IOCTL_MAGIC, 2, struct btrfs_ioctl_vol_args)
+#define BTRFS_IOC_DEFRAG _IOW(BTRFS_IOCTL_MAGIC, 2, \
+                                 struct btrfs_ioctl_vol_args)
 #endif
 
 #ifndef BTRFS_IOC_DEV_INFO
@@ -225,7 +222,12 @@ struct btrfs_ioctl_fs_info_args {
 
 #ifndef BTRFS_IOC_FS_INFO
 #define BTRFS_IOC_FS_INFO _IOR(BTRFS_IOCTL_MAGIC, 31, \
-                               struct btrfs_ioctl_fs_info_args)
+                                 struct btrfs_ioctl_fs_info_args)
+#endif
+
+#ifndef BTRFS_IOC_DEVICES_READY
+#define BTRFS_IOC_DEVICES_READY _IOR(BTRFS_IOCTL_MAGIC, 39, \
+                                 struct btrfs_ioctl_vol_args)
 #endif
 
 #ifndef BTRFS_SUPER_MAGIC
@@ -363,3 +365,202 @@ static inline int setns(int fd, int nstype) {
         return syscall(__NR_setns, fd, nstype);
 }
 #endif
+
+#if !HAVE_DECL_LO_FLAGS_PARTSCAN
+#define LO_FLAGS_PARTSCAN 8
+#endif
+
+#ifndef LOOP_CTL_REMOVE
+#define LOOP_CTL_REMOVE 0x4C81
+#endif
+
+#ifndef LOOP_CTL_GET_FREE
+#define LOOP_CTL_GET_FREE 0x4C82
+#endif
+
+#if !HAVE_DECL_IFLA_MACVLAN_FLAGS
+#define IFLA_MACVLAN_UNSPEC 0
+#define IFLA_MACVLAN_MODE 1
+#define IFLA_MACVLAN_FLAGS 2
+#define __IFLA_MACVLAN_MAX 3
+
+#define IFLA_MACVLAN_MAX (__IFLA_MACVLAN_MAX - 1)
+#endif
+
+#if !HAVE_DECL_IFLA_VTI_REMOTE
+#define IFLA_VTI_UNSPEC 0
+#define IFLA_VTI_LINK 1
+#define IFLA_VTI_IKEY 2
+#define IFLA_VTI_OKEY 3
+#define IFLA_VTI_LOCAL 4
+#define IFLA_VTI_REMOTE 5
+#define __IFLA_VTI_MAX 6
+
+#define IFLA_VTI_MAX (__IFLA_VTI_MAX - 1)
+#endif
+
+#if !HAVE_DECL_IFLA_PHYS_PORT_ID
+#undef IFLA_PROMISCUITY
+#define IFLA_PROMISCUITY 30
+#define IFLA_NUM_TX_QUEUES 31
+#define IFLA_NUM_RX_QUEUES 32
+#define IFLA_CARRIER 33
+#define IFLA_PHYS_PORT_ID 34
+#define __IFLA_MAX 35
+
+#define IFLA_MAX (__IFLA_MAX - 1)
+#endif
+
+#if !HAVE_DECL_IFLA_BOND_AD_INFO
+#define IFLA_BOND_UNSPEC 0
+#define IFLA_BOND_MODE 1
+#define IFLA_BOND_ACTIVE_SLAVE 2
+#define IFLA_BOND_MIIMON 3
+#define IFLA_BOND_UPDELAY 4
+#define IFLA_BOND_DOWNDELAY 5
+#define IFLA_BOND_USE_CARRIER 6
+#define IFLA_BOND_ARP_INTERVAL 7
+#define IFLA_BOND_ARP_IP_TARGET 8
+#define IFLA_BOND_ARP_VALIDATE 9
+#define IFLA_BOND_ARP_ALL_TARGETS 10
+#define IFLA_BOND_PRIMARY 11
+#define IFLA_BOND_PRIMARY_RESELECT 12
+#define IFLA_BOND_FAIL_OVER_MAC 13
+#define IFLA_BOND_XMIT_HASH_POLICY 14
+#define IFLA_BOND_RESEND_IGMP 15
+#define IFLA_BOND_NUM_PEER_NOTIF 16
+#define IFLA_BOND_ALL_SLAVES_ACTIVE 17
+#define IFLA_BOND_MIN_LINKS 18
+#define IFLA_BOND_LP_INTERVAL 19
+#define IFLA_BOND_PACKETS_PER_SLAVE 20
+#define IFLA_BOND_AD_LACP_RATE 21
+#define IFLA_BOND_AD_SELECT 22
+#define IFLA_BOND_AD_INFO 23
+#define __IFLA_BOND_MAX 24
+
+#define IFLA_BOND_MAX  (__IFLA_BOND_MAX - 1)
+#endif
+
+#if !HAVE_DECL_IFLA_VLAN_PROTOCOL
+#define IFLA_VLAN_UNSPEC 0
+#define IFLA_VLAN_ID 1
+#define IFLA_VLAN_FLAGS 2
+#define IFLA_VLAN_EGRESS_QOS 3
+#define IFLA_VLAN_INGRESS_QOS 4
+#define IFLA_VLAN_PROTOCOL 5
+#define __IFLA_VLAN_MAX 6
+
+#define IFLA_VLAN_MAX   (__IFLA_VLAN_MAX - 1)
+#endif
+
+#if !HAVE_DECL_IFLA_VXLAN_LOCAL6
+#define IFLA_VXLAN_UNSPEC 0
+#define IFLA_VXLAN_ID 1
+#define IFLA_VXLAN_GROUP 2
+#define IFLA_VXLAN_LINK 3
+#define IFLA_VXLAN_LOCAL 4
+#define IFLA_VXLAN_TTL 5
+#define IFLA_VXLAN_TOS 6
+#define IFLA_VXLAN_LEARNING 7
+#define IFLA_VXLAN_AGEING 8
+#define IFLA_VXLAN_LIMIT 9
+#define IFLA_VXLAN_PORT_RANGE 10
+#define IFLA_VXLAN_PROXY 11
+#define IFLA_VXLAN_RSC 12
+#define IFLA_VXLAN_L2MISS 13
+#define IFLA_VXLAN_L3MISS 14
+#define IFLA_VXLAN_PORT 15
+#define IFLA_VXLAN_GROUP6 16
+#define IFLA_VXLAN_LOCAL6 17
+#define __IFLA_VXLAN_MAX 18
+
+#define IFLA_VXLAN_MAX  (__IFLA_VXLAN_MAX - 1)
+#endif
+
+#if !HAVE_DECL_IFLA_IPTUN_6RD_RELAY_PREFIXLEN
+#define IFLA_IPTUN_UNSPEC 0
+#define IFLA_IPTUN_LINK 1
+#define IFLA_IPTUN_LOCAL 2
+#define IFLA_IPTUN_REMOTE 3
+#define IFLA_IPTUN_TTL 4
+#define IFLA_IPTUN_TOS 5
+#define IFLA_IPTUN_ENCAP_LIMIT 6
+#define IFLA_IPTUN_FLOWINFO 7
+#define IFLA_IPTUN_FLAGS 8
+#define IFLA_IPTUN_PROTO 9
+#define IFLA_IPTUN_PMTUDISC 10
+#define IFLA_IPTUN_6RD_PREFIX 11
+#define IFLA_IPTUN_6RD_RELAY_PREFIX 12
+#define IFLA_IPTUN_6RD_PREFIXLEN 13
+#define IFLA_IPTUN_6RD_RELAY_PREFIXLEN 14
+#define __IFLA_IPTUN_MAX 15
+
+#define IFLA_IPTUN_MAX  (__IFLA_IPTUN_MAX - 1)
+#endif
+
+#if !HAVE_DECL_IFLA_BRIDGE_VLAN_INFO
+#define IFLA_BRIDGE_FLAGS 0
+#define IFLA_BRIDGE_MODE 1
+#define IFLA_BRIDGE_VLAN_INFO 2
+#define __IFLA_BRIDGE_MAX 3
+
+#define IFLA_BRIDGE_MAX (__IFLA_BRIDGE_MAX - 1)
+#endif
+
+#ifndef IPV6_UNICAST_IF
+#define IPV6_UNICAST_IF 76
+#endif
+
+#ifndef IFF_LOWER_UP
+#define IFF_LOWER_UP 0x10000
+#endif
+
+#ifndef IFF_DORMANT
+#define IFF_DORMANT 0x20000
+#endif
+
+#ifndef BOND_XMIT_POLICY_ENCAP23
+#define BOND_XMIT_POLICY_ENCAP23 3
+#endif
+
+#ifndef BOND_XMIT_POLICY_ENCAP34
+#define BOND_XMIT_POLICY_ENCAP34 4
+#endif
+
+#ifndef NET_ADDR_RANDOM
+#  define NET_ADDR_RANDOM 1
+#endif
+
+#ifndef NET_NAME_ENUM
+#  define NET_NAME_ENUM 1
+#endif
+
+#ifndef NET_NAME_PREDICTABLE
+#  define NET_NAME_PREDICTABLE 2
+#endif
+
+#ifndef NET_NAME_USER
+#  define NET_NAME_USER 3
+#endif
+
+#ifndef NET_NAME_RENAMED
+#  define NET_NAME_RENAMED 4
+#endif
+
+#ifdef CONFIG_TIZEN_WIP
+#ifndef CLOCK_BOOTTIME
+#   define CLOCK_BOOTTIME 7
+#endif
+
+#ifndef CLOCK_REALTIME_ALARM
+#   define CLOCK_REALTIME_ALARM 8
+#endif
+
+#ifndef CLOCK_BOOTTIME_ALARM
+#   define CLOCK_BOOTTIME_ALARM 9
+#endif
+
+#ifndef BPF_XOR
+#   define BPF_XOR 0xa0
+#endif
+#endif
index 43c6ea6..f941efb 100644 (file)
@@ -41,9 +41,11 @@ int mkdir_safe_internal(const char *path, mode_t mode, uid_t uid, gid_t gid, mkd
         if (lstat(path, &st) < 0)
                 return -errno;
 
-        if ((st.st_mode & 0777) != mode ||
-            st.st_uid != uid ||
-            st.st_gid != gid ||
+        if ((st.st_mode & 0007) > (mode & 0007) ||
+            (st.st_mode & 0070) > (mode & 0070) ||
+            (st.st_mode & 0700) > (mode & 0700) ||
+            (uid != (uid_t) -1 && st.st_uid != uid) ||
+            (gid != (gid_t) -1 && st.st_gid != gid) ||
             !S_ISDIR(st.st_mode)) {
                 errno = EEXIST;
                 return -errno;
@@ -56,11 +58,16 @@ int mkdir_safe(const char *path, mode_t mode, uid_t uid, gid_t gid) {
         return mkdir_safe_internal(path, mode, uid, gid, mkdir);
 }
 
-static int is_dir(const char* path) {
+int is_dir(const char* path, bool follow) {
         struct stat st;
 
-        if (stat(path, &st) < 0)
-                return -errno;
+        if (follow) {
+                if (stat(path, &st) < 0)
+                        return -errno;
+        } else {
+                if (lstat(path, &st) < 0)
+                        return -errno;
+        }
 
         return S_ISDIR(st.st_mode);
 }
@@ -83,7 +90,7 @@ int mkdir_parents_internal(const char *prefix, const char *path, mode_t mode, mk
                 return 0;
 
         p = strndupa(path, e - path);
-        r = is_dir(p);
+        r = is_dir(p, true);
         if (r > 0)
                 return 0;
         if (r == 0)
@@ -128,7 +135,7 @@ int mkdir_p_internal(const char *prefix, const char *path, mode_t mode, mkdir_fu
                 return r;
 
         r = _mkdir(path, mode);
-        if (r < 0 && (errno != EEXIST || is_dir(path) <= 0))
+        if (r < 0 && (errno != EEXIST || is_dir(path, true) <= 0))
                 return -errno;
 
         return 0;
index eb73902..dd5b41e 100644 (file)
@@ -22,6 +22,7 @@
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
+#include <stdbool.h>
 #include <sys/types.h>
 
 int mkdir_safe(const char *path, mode_t mode, uid_t uid, gid_t gid);
@@ -41,3 +42,4 @@ typedef int (*mkdir_func_t)(const char *pathname, mode_t mode);
 int mkdir_safe_internal(const char *path, mode_t mode, uid_t uid, gid_t gid, mkdir_func_t _mkdir);
 int mkdir_parents_internal(const char *prefix, const char *path, mode_t mode, mkdir_func_t _mkdir);
 int mkdir_p_internal(const char *prefix, const char *path, mode_t mode, mkdir_func_t _mkdir);
+int is_dir(const char *path, bool is_dir);
diff --git a/src/shared/nss-util.h b/src/shared/nss-util.h
new file mode 100644 (file)
index 0000000..230a986
--- /dev/null
@@ -0,0 +1,128 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <nss.h>
+#include <netdb.h>
+#include <resolv.h>
+
+#define NSS_GETHOSTBYNAME_PROTOTYPES(module)            \
+enum nss_status _nss_##module##_gethostbyname4_r(       \
+                const char *name,                       \
+                struct gaih_addrtuple **pat,            \
+                char *buffer, size_t buflen,            \
+                int *errnop, int *h_errnop,             \
+                int32_t *ttlp) _public_;                \
+enum nss_status _nss_##module##_gethostbyname3_r(       \
+                const char *name,                       \
+                int af,                                 \
+                struct hostent *host,                   \
+                char *buffer, size_t buflen,            \
+                int *errnop, int *h_errnop,             \
+                int32_t *ttlp,                          \
+                char **canonp) _public_;                \
+enum nss_status _nss_##module##_gethostbyname2_r(       \
+                const char *name,                       \
+                int af,                                 \
+                struct hostent *host,                   \
+                char *buffer, size_t buflen,            \
+                int *errnop, int *h_errnop) _public_;   \
+enum nss_status _nss_##module##_gethostbyname_r(        \
+                const char *name,                       \
+                struct hostent *host,                   \
+                char *buffer, size_t buflen,            \
+                int *errnop, int *h_errnop) _public_
+
+#define NSS_GETHOSTBYADDR_PROTOTYPES(module)            \
+enum nss_status _nss_##module##_gethostbyaddr2_r(       \
+                const void* addr, socklen_t len,        \
+                int af,                                 \
+                struct hostent *host,                   \
+                char *buffer, size_t buflen,            \
+                int *errnop, int *h_errnop,             \
+                int32_t *ttlp) _public_;                \
+enum nss_status _nss_##module##_gethostbyaddr_r(        \
+                const void* addr, socklen_t len,        \
+                int af,                                 \
+                struct hostent *host,                   \
+                char *buffer, size_t buflen,            \
+                int *errnop, int *h_errnop) _public_
+
+#define NSS_GETHOSTBYNAME_FALLBACKS(module)             \
+enum nss_status _nss_##module##_gethostbyname2_r(       \
+                const char *name,                       \
+                int af,                                 \
+                struct hostent *host,                   \
+                char *buffer, size_t buflen,            \
+                int *errnop, int *h_errnop) {           \
+        return _nss_##module##_gethostbyname3_r(        \
+                        name,                           \
+                        af,                             \
+                        host,                           \
+                        buffer, buflen,                 \
+                        errnop, h_errnop,               \
+                        NULL,                           \
+                        NULL);                          \
+}                                                       \
+enum nss_status _nss_##module##_gethostbyname_r(        \
+                const char *name,                       \
+                struct hostent *host,                   \
+                char *buffer, size_t buflen,            \
+                int *errnop, int *h_errnop) {           \
+        enum nss_status ret = NSS_STATUS_NOTFOUND;      \
+                                                        \
+        if (_res.options & RES_USE_INET6)               \
+                ret = _nss_##module##_gethostbyname3_r( \
+                        name,                           \
+                        AF_INET6,                       \
+                        host,                           \
+                        buffer, buflen,                 \
+                        errnop, h_errnop,               \
+                        NULL,                           \
+                        NULL);                          \
+        if (ret == NSS_STATUS_NOTFOUND)                 \
+                ret = _nss_##module##_gethostbyname3_r( \
+                        name,                           \
+                        AF_INET,                        \
+                        host,                           \
+                        buffer, buflen,                 \
+                        errnop, h_errnop,               \
+                        NULL,                           \
+                        NULL);                          \
+       return ret;                                      \
+}
+
+#define NSS_GETHOSTBYADDR_FALLBACKS(module)             \
+enum nss_status _nss_##module##_gethostbyaddr_r(        \
+                const void* addr, socklen_t len,        \
+                int af,                                 \
+                struct hostent *host,                   \
+                char *buffer, size_t buflen,            \
+                int *errnop, int *h_errnop) {           \
+        return _nss_##module##_gethostbyaddr2_r(        \
+                        addr, len,                      \
+                        af,                             \
+                        host,                           \
+                        buffer, buflen,                 \
+                        errnop, h_errnop,               \
+                        NULL);                          \
+}
index 9da789d..ac1bb01 100644 (file)
@@ -42,5 +42,6 @@ typedef enum OutputFlags {
         OUTPUT_WARN_CUTOFF    = 1 << 2,
         OUTPUT_FULL_WIDTH     = 1 << 3,
         OUTPUT_COLOR          = 1 << 4,
-        OUTPUT_CATALOG        = 1 << 5
+        OUTPUT_CATALOG        = 1 << 5,
+        OUTPUT_BEGIN_NEWLINE  = 1 << 6,
 } OutputFlags;
index 55b13d6..5479094 100644 (file)
@@ -78,7 +78,7 @@ int pager_open(bool jump_to_end) {
         if (pager_pid < 0) {
                 r = -errno;
                 log_error("Failed to fork pager: %m");
-                close_pipe(fd);
+                safe_close_pair(fd);
                 return r;
         }
 
@@ -87,7 +87,7 @@ int pager_open(bool jump_to_end) {
                 const char* less_opts;
 
                 dup2(fd[0], STDIN_FILENO);
-                close_pipe(fd);
+                safe_close_pair(fd);
 
                 less_opts = getenv("SYSTEMD_LESS");
                 if (!less_opts)
@@ -131,7 +131,7 @@ int pager_open(bool jump_to_end) {
                 return -errno;
         }
 
-        close_pipe(fd);
+        safe_close_pair(fd);
         return 1;
 }
 
@@ -150,3 +150,56 @@ void pager_close(void) {
 bool pager_have(void) {
         return pager_pid > 0;
 }
+
+int show_man_page(const char *desc, bool null_stdio) {
+        const char *args[4] = { "man", NULL, NULL, NULL };
+        char *e = NULL;
+        pid_t pid;
+        size_t k;
+        int r;
+        siginfo_t status;
+
+        k = strlen(desc);
+
+        if (desc[k-1] == ')')
+                e = strrchr(desc, '(');
+
+        if (e) {
+                char *page = NULL, *section = NULL;
+
+                page = strndupa(desc, e - desc);
+                section = strndupa(e + 1, desc + k - e - 2);
+
+                args[1] = section;
+                args[2] = page;
+        } else
+                args[1] = desc;
+
+        pid = fork();
+        if (pid < 0) {
+                log_error("Failed to fork: %m");
+                return -errno;
+        }
+
+        if (pid == 0) {
+                /* Child */
+                if (null_stdio) {
+                        r = make_null_stdio();
+                        if (r < 0) {
+                                log_error("Failed to kill stdio: %s", strerror(-r));
+                                _exit(EXIT_FAILURE);
+                        }
+                }
+
+                execvp(args[0], (char**) args);
+                log_error("Failed to execute man: %m");
+                _exit(EXIT_FAILURE);
+        }
+
+        r = wait_for_terminate(pid, &status);
+        if (r < 0)
+                return r;
+
+        log_debug("Exit code %i status %i", status.si_code, status.si_status);
+        return status.si_status;
+}
index 03dca8b..6744617 100644 (file)
@@ -28,3 +28,5 @@
 int pager_open(bool jump_to_end);
 void pager_close(void);
 bool pager_have(void) _pure_;
+
+int show_man_page(const char *page, bool null_stdio);
index 63af43c..40fb0b8 100644 (file)
 #include "path-util.h"
 #include "path-lookup.h"
 
-static const char* const systemd_running_as_table[_SYSTEMD_RUNNING_AS_MAX] = {
-        [SYSTEMD_SYSTEM] = "system",
-        [SYSTEMD_USER] = "user"
-};
-
-DEFINE_STRING_TABLE_LOOKUP(systemd_running_as, SystemdRunningAs);
-
 int user_config_home(char **config_home) {
         const char *e;
         char *r;
@@ -127,16 +120,6 @@ static char** user_dirs(
         } else if (home) {
                 if (asprintf(&data_home, "%s/.local/share/systemd/user", home) < 0)
                         goto fail;
-
-                /* There is really no need for two unit dirs in $HOME,
-                 * except to be fully compliant with the XDG spec. We
-                 * now try to link the two dirs, so that we can
-                 * minimize disk seeks a little. Further down we'll
-                 * then filter out this link, if it is actually is
-                 * one. */
-
-                mkdir_parents_label(data_home, 0777);
-                (void) symlink("../../../.config/systemd/user", data_home);
         }
 
         e = getenv("XDG_DATA_DIRS");
@@ -198,11 +181,13 @@ int lookup_paths_init(
                 LookupPaths *p,
                 SystemdRunningAs running_as,
                 bool personal,
+                const char *root_dir,
                 const char *generator,
                 const char *generator_early,
                 const char *generator_late) {
 
         const char *e;
+        bool append = false; /* Add items from SYSTEMD_UNIT_PATH before normal directories */
 
         assert(p);
 
@@ -210,76 +195,81 @@ int lookup_paths_init(
          * vars */
         e = getenv("SYSTEMD_UNIT_PATH");
         if (e) {
+                if (endswith(e, ":")) {
+                        e = strndupa(e, strlen(e) - 1);
+                        append = true;
+                }
+
+                /* FIXME: empty components in other places should be
+                 * rejected. */
+
                 p->unit_path = path_split_and_make_absolute(e);
                 if (!p->unit_path)
                         return -ENOMEM;
         } else
                 p->unit_path = NULL;
 
-        if (strv_isempty(p->unit_path)) {
-                /* Nothing is set, so let's figure something out. */
-                strv_free(p->unit_path);
+        if (!p->unit_path || append) {
+                /* Let's figure something out. */
+
+                _cleanup_strv_free_ char **unit_path;
+                int r;
 
                 /* For the user units we include share/ in the search
-                 * path in order to comply with the XDG basedir
-                 * spec. For the system stuff we avoid such
-                 * nonsense. OTOH we include /lib in the search path
-                 * for the system stuff but avoid it for user
-                 * stuff. */
+                 * path in order to comply with the XDG basedir spec.
+                 * For the system stuff we avoid such nonsense. OTOH
+                 * we include /lib in the search path for the system
+                 * stuff but avoid it for user stuff. */
 
                 if (running_as == SYSTEMD_USER) {
-
                         if (personal)
-                                p->unit_path = user_dirs(generator, generator_early, generator_late);
+                                unit_path = user_dirs(generator, generator_early, generator_late);
                         else
-                                p->unit_path = strv_new(
-                                                /* If you modify this you also want to modify
-                                                 * systemduserunitpath= in systemd.pc.in, and
-                                                 * the arrays in user_dirs() above! */
-                                                STRV_IFNOTNULL(generator_early),
-                                                USER_CONFIG_UNIT_PATH,
-                                                "/etc/systemd/user",
-                                                "/run/systemd/user",
-                                                STRV_IFNOTNULL(generator),
-                                                "/usr/local/lib/systemd/user",
-                                                "/usr/local/share/systemd/user",
-                                                USER_DATA_UNIT_PATH,
-                                                "/usr/lib/systemd/user",
-                                                "/usr/share/systemd/user",
-                                                STRV_IFNOTNULL(generator_late),
-                                                NULL);
-
-                        if (!p->unit_path)
-                                return -ENOMEM;
-
-                } else {
-                        p->unit_path = strv_new(
+                                unit_path = strv_new(
                                         /* If you modify this you also want to modify
-                                         * systemdsystemunitpath= in systemd.pc.in! */
+                                         * systemduserunitpath= in systemd.pc.in, and
+                                         * the arrays in user_dirs() above! */
                                         STRV_IFNOTNULL(generator_early),
-                                        SYSTEM_CONFIG_UNIT_PATH,
-                                        "/etc/systemd/system",
-                                        "/run/systemd/system",
+                                        USER_CONFIG_UNIT_PATH,
+                                        "/etc/systemd/user",
+                                        "/run/systemd/user",
                                         STRV_IFNOTNULL(generator),
-                                        "/usr/local/lib/systemd/system",
-                                        SYSTEM_DATA_UNIT_PATH,
-                                        "/usr/lib/systemd/system",
-#ifdef HAVE_SPLIT_USR
-                                        "/lib/systemd/system",
-#endif
+                                        "/usr/local/lib/systemd/user",
+                                        "/usr/local/share/systemd/user",
+                                        USER_DATA_UNIT_PATH,
+                                        "/usr/lib/systemd/user",
+                                        "/usr/share/systemd/user",
                                         STRV_IFNOTNULL(generator_late),
                                         NULL);
+                } else
+                        unit_path = strv_new(
+                                /* If you modify this you also want to modify
+                                 * systemdsystemunitpath= in systemd.pc.in! */
+                                STRV_IFNOTNULL(generator_early),
+                                SYSTEM_CONFIG_UNIT_PATH,
+                                "/etc/systemd/system",
+                                "/run/systemd/system",
+                                STRV_IFNOTNULL(generator),
+                                "/usr/local/lib/systemd/system",
+                                SYSTEM_DATA_UNIT_PATH,
+                                "/usr/lib/systemd/system",
+#ifdef HAVE_SPLIT_USR
+                                "/lib/systemd/system",
+#endif
+                                STRV_IFNOTNULL(generator_late),
+                                NULL);
 
-                        if (!p->unit_path)
-                                return -ENOMEM;
-                }
+                if (!unit_path)
+                        return -ENOMEM;
+
+                r = strv_extend_strv(&p->unit_path, unit_path);
+                if (r < 0)
+                        return r;
         }
 
-        if (!path_strv_canonicalize_absolute(p->unit_path, NULL))
+        if (!path_strv_resolve_uniq(p->unit_path, root_dir))
                 return -ENOMEM;
 
-        strv_uniq(p->unit_path);
-
         if (!strv_isempty(p->unit_path)) {
                 _cleanup_free_ char *t = strv_join(p->unit_path, "\n\t");
                 if (!t)
@@ -331,15 +321,12 @@ int lookup_paths_init(
                                 return -ENOMEM;
                 }
 
-                if (!path_strv_canonicalize_absolute(p->sysvinit_path, NULL))
+                if (!path_strv_resolve_uniq(p->sysvinit_path, root_dir))
                         return -ENOMEM;
 
-                if (!path_strv_canonicalize_absolute(p->sysvrcnd_path, NULL))
+                if (!path_strv_resolve_uniq(p->sysvrcnd_path, root_dir))
                         return -ENOMEM;
 
-                strv_uniq(p->sysvinit_path);
-                strv_uniq(p->sysvrcnd_path);
-
                 if (!strv_isempty(p->sysvinit_path)) {
                         _cleanup_free_ char *t = strv_join(p->sysvinit_path, "\n\t");
                         if (!t)
index a3ef824..2fe8173 100644 (file)
@@ -21,6 +21,8 @@
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
+#include "macro.h"
+
 typedef struct LookupPaths {
         char **unit_path;
 #ifdef HAVE_SYSV_COMPAT
@@ -38,10 +40,13 @@ typedef enum SystemdRunningAs {
 
 #define _cleanup_lookup_paths_free_ _cleanup_(lookup_paths_free)
 
-const char* systemd_running_as_to_string(SystemdRunningAs i) _const_;
-SystemdRunningAs systemd_running_as_from_string(const char *s) _pure_;
-
 int user_config_home(char **config_home);
 
-int lookup_paths_init(LookupPaths *p, SystemdRunningAs running_as, bool personal, const char *generator, const char *generator_early, const char *generator_late);
+int lookup_paths_init(LookupPaths *p,
+                      SystemdRunningAs running_as,
+                      bool personal,
+                      const char *root_dir,
+                      const char *generator,
+                      const char *generator_early,
+                      const char *generator_late);
 void lookup_paths_free(LookupPaths *p);
index bdc54a9..67566bc 100644 (file)
@@ -132,6 +132,91 @@ char *path_make_absolute_cwd(const char *p) {
         return path_make_absolute(p, cwd);
 }
 
+int path_make_relative(const char *from_dir, const char *to_path, char **_r) {
+        char *r, *p;
+        unsigned n_parents;
+
+        assert(from_dir);
+        assert(to_path);
+        assert(_r);
+
+        /* Strips the common part, and adds ".." elements as necessary. */
+
+        if (!path_is_absolute(from_dir))
+                return -EINVAL;
+
+        if (!path_is_absolute(to_path))
+                return -EINVAL;
+
+        /* Skip the common part. */
+        for (;;) {
+                size_t a;
+                size_t b;
+
+                from_dir += strspn(from_dir, "/");
+                to_path += strspn(to_path, "/");
+
+                if (!*from_dir) {
+                        if (!*to_path)
+                                /* from_dir equals to_path. */
+                                r = strdup(".");
+                        else
+                                /* from_dir is a parent directory of to_path. */
+                                r = strdup(to_path);
+
+                        if (!r)
+                                return -ENOMEM;
+
+                        path_kill_slashes(r);
+
+                        *_r = r;
+                        return 0;
+                }
+
+                if (!*to_path)
+                        break;
+
+                a = strcspn(from_dir, "/");
+                b = strcspn(to_path, "/");
+
+                if (a != b)
+                        break;
+
+                if (memcmp(from_dir, to_path, a) != 0)
+                        break;
+
+                from_dir += a;
+                to_path += b;
+        }
+
+        /* If we're here, then "from_dir" has one or more elements that need to
+         * be replaced with "..". */
+
+        /* Count the number of necessary ".." elements. */
+        for (n_parents = 0;;) {
+                from_dir += strspn(from_dir, "/");
+
+                if (!*from_dir)
+                        break;
+
+                from_dir += strcspn(from_dir, "/");
+                n_parents++;
+        }
+
+        r = malloc(n_parents * 3 + strlen(to_path) + 1);
+        if (!r)
+                return -ENOMEM;
+
+        for (p = r; n_parents > 0; n_parents--, p += 3)
+                memcpy(p, "../", 3);
+
+        strcpy(p, to_path);
+        path_kill_slashes(r);
+
+        *_r = r;
+        return 0;
+}
+
 char **path_strv_make_absolute_cwd(char **l) {
         char **s;
 
@@ -153,7 +238,7 @@ char **path_strv_make_absolute_cwd(char **l) {
         return l;
 }
 
-char **path_strv_canonicalize_absolute(char **l, const char *prefix) {
+char **path_strv_resolve(char **l, const char *prefix) {
         char **s;
         unsigned k = 0;
         bool enomem = false;
@@ -167,36 +252,63 @@ char **path_strv_canonicalize_absolute(char **l, const char *prefix) {
 
         STRV_FOREACH(s, l) {
                 char *t, *u;
+                _cleanup_free_ char *orig = NULL;
 
-                if (!path_is_absolute(*s))
+                if (!path_is_absolute(*s)) {
+                        free(*s);
                         continue;
+                }
 
                 if (prefix) {
-                        t = strappend(prefix, *s);
-                        free(*s);
-                        *s = NULL;
-
+                        orig = *s;
+                        t = strappend(prefix, orig);
                         if (!t) {
                                 enomem = true;
                                 continue;
                         }
-                } else {
+                } else
                         t = *s;
-                        *s = NULL;
-                }
 
                 errno = 0;
                 u = canonicalize_file_name(t);
                 if (!u) {
-                        if (errno == ENOENT)
-                                u = t;
-                        else {
+                        if (errno == ENOENT) {
+                                if (prefix) {
+                                        u = orig;
+                                        orig = NULL;
+                                        free(t);
+                                } else
+                                        u = t;
+                        } else {
                                 free(t);
                                 if (errno == ENOMEM || errno == 0)
                                         enomem = true;
 
                                 continue;
                         }
+                } else if (prefix) {
+                        char *x;
+
+                        free(t);
+                        x = path_startswith(u, prefix);
+                        if (x) {
+                                /* restore the slash if it was lost */
+                                if (!startswith(x, "/"))
+                                        *(--x) = '/';
+
+                                t = strdup(x);
+                                free(u);
+                                if (!t) {
+                                        enomem = true;
+                                        continue;
+                                }
+                                u = t;
+                        } else {
+                                /* canonicalized path goes outside of
+                                 * prefix, keep the original path instead */
+                                u = orig;
+                                orig = NULL;
+                        }
                 } else
                         free(t);
 
@@ -211,12 +323,12 @@ char **path_strv_canonicalize_absolute(char **l, const char *prefix) {
         return l;
 }
 
-char **path_strv_canonicalize_absolute_uniq(char **l, const char *prefix) {
+char **path_strv_resolve_uniq(char **l, const char *prefix) {
 
         if (strv_isempty(l))
                 return l;
 
-        if (!path_strv_canonicalize_absolute(l, prefix))
+        if (!path_strv_resolve(l, prefix))
                 return NULL;
 
         return strv_uniq(l);
@@ -323,12 +435,32 @@ bool path_equal(const char *a, const char *b) {
         }
 }
 
+char* path_join(const char *root, const char *path, const char *rest) {
+        assert(path);
+
+        if (!isempty(root))
+                return strjoin(root, "/",
+                               path[0] == '/' ? path+1 : path,
+                               rest ? "/" : NULL,
+                               rest && rest[0] == '/' ? rest+1 : rest,
+                               NULL);
+        else
+                return strjoin(path,
+                               rest ? "/" : NULL,
+                               rest && rest[0] == '/' ? rest+1 : rest,
+                               NULL);
+}
+
 int path_is_mount_point(const char *t, bool allow_symlink) {
-        char *parent;
-        int r;
-        struct file_handle *h;
+
+        union file_handle_union h = {
+                .handle.handle_bytes = MAX_HANDLE_SZ
+        };
+
         int mount_id, mount_id_parent;
+        _cleanup_free_ char *parent = NULL;
         struct stat a, b;
+        int r;
 
         /* We are not actually interested in the file handles, but
          * name_to_handle_at() also passes us the mount ID, hence use
@@ -337,12 +469,9 @@ int path_is_mount_point(const char *t, bool allow_symlink) {
         if (path_equal(t, "/"))
                 return 1;
 
-        h = alloca(MAX_HANDLE_SZ);
-        h->handle_bytes = MAX_HANDLE_SZ;
-
-        r = name_to_handle_at(AT_FDCWD, t, h, &mount_id, allow_symlink ? AT_SYMLINK_FOLLOW : 0);
+        r = name_to_handle_at(AT_FDCWD, t, &h.handle, &mount_id, allow_symlink ? AT_SYMLINK_FOLLOW : 0);
         if (r < 0) {
-                if (errno == ENOSYS || errno == ENOTSUP)
+                if (IN_SET(errno, ENOSYS, EOPNOTSUPP))
                         /* This kernel or file system does not support
                          * name_to_handle_at(), hence fallback to the
                          * traditional stat() logic */
@@ -358,15 +487,13 @@ int path_is_mount_point(const char *t, bool allow_symlink) {
         if (r < 0)
                 return r;
 
-        h->handle_bytes = MAX_HANDLE_SZ;
-        r = name_to_handle_at(AT_FDCWD, parent, h, &mount_id_parent, 0);
-        free(parent);
-
+        h.handle.handle_bytes = MAX_HANDLE_SZ;
+        r = name_to_handle_at(AT_FDCWD, parent, &h.handle, &mount_id_parent, 0);
         if (r < 0) {
                 /* The parent can't do name_to_handle_at() but the
                  * directory we are interested in can? If so, it must
                  * be a mount point */
-                if (errno == ENOTSUP)
+                if (errno == EOPNOTSUPP)
                         return 1;
 
                 return -errno;
@@ -392,8 +519,6 @@ fallback:
                 return r;
 
         r = lstat(parent, &b);
-        free(parent);
-
         if (r < 0)
                 return -errno;
 
@@ -408,40 +533,57 @@ int path_is_read_only_fs(const char *path) {
         if (statvfs(path, &st) < 0)
                 return -errno;
 
-        return !!(st.f_flag & ST_RDONLY);
+        if (st.f_flag & ST_RDONLY)
+                return true;
+
+        /* On NFS, statvfs() might not reflect whether we can actually
+         * write to the remote share. Let's try again with
+         * access(W_OK) which is more reliable, at least sometimes. */
+        if (access(path, W_OK) < 0 && errno == EROFS)
+                return true;
+
+        return false;
 }
 
 int path_is_os_tree(const char *path) {
         char *p;
         int r;
 
-        /* We use /etc/os-release as flag file if something is an OS */
+        /* We use /usr/lib/os-release as flag file if something is an OS */
+        p = strappenda(path, "/usr/lib/os-release");
+        r = access(p, F_OK);
+
+        if (r >= 0)
+                return 1;
 
+        /* Also check for the old location in /etc, just in case. */
         p = strappenda(path, "/etc/os-release");
         r = access(p, F_OK);
 
-        return r < 0 ? 0 : 1;
+        return r >= 0;
 }
 
 int find_binary(const char *name, char **filename) {
         assert(name);
-        assert(filename);
 
-        if (strchr(name, '/')) {
-                char *p;
+        if (is_path(name)) {
+                if (access(name, X_OK) < 0)
+                        return -errno;
+
+                if (filename) {
+                        char *p;
 
-                if (path_is_absolute(name))
-                        p = strdup(name);
-                else
                         p = path_make_absolute_cwd(name);
-                if (!p)
-                        return -ENOMEM;
+                        if (!p)
+                                return -ENOMEM;
+
+                        *filename = p;
+                }
 
-                *filename = p;
                 return 0;
         } else {
                 const char *path;
-                char *state, *w;
+                const char *word, *state;
                 size_t l;
 
                 /**
@@ -452,19 +594,19 @@ int find_binary(const char *name, char **filename) {
                 if (!path)
                         path = DEFAULT_PATH;
 
-                FOREACH_WORD_SEPARATOR(w, l, path, ":", state) {
-                        char *p;
+                FOREACH_WORD_SEPARATOR(word, l, path, ":", state) {
+                        _cleanup_free_ char *p = NULL;
 
-                        if (asprintf(&p, "%.*s/%s", (int) l, w, name) < 0)
+                        if (asprintf(&p, "%.*s/%s", (int) l, word, name) < 0)
                                 return -ENOMEM;
 
-                        if (access(p, X_OK) < 0) {
-                                free(p);
+                        if (access(p, X_OK) < 0)
                                 continue;
-                        }
 
-                        path_kill_slashes(p);
-                        *filename = p;
+                        if (filename) {
+                                *filename = path_kill_slashes(p);
+                                p = NULL;
+                        }
 
                         return 0;
                 }
@@ -507,3 +649,27 @@ bool paths_check_timestamp(const char* const* paths, usec_t *timestamp, bool upd
 
         return changed;
 }
+
+int fsck_exists(const char *fstype) {
+        _cleanup_free_ char *p = NULL, *d = NULL;
+        const char *checker;
+        int r;
+
+        checker = strappenda("fsck.", fstype);
+
+        r = find_binary(checker, &p);
+        if (r < 0)
+                return r;
+
+        /* An fsck that is linked to /bin/true is a non-existent
+         * fsck */
+
+        r = readlink_malloc(p, &d);
+        if (r >= 0 &&
+            (path_equal(d, "/bin/true") ||
+             path_equal(d, "/usr/bin/true") ||
+             path_equal(d, "/dev/null")))
+                return -ENOENT;
+
+        return 0;
+}
index 2b8ea02..d85291b 100644 (file)
@@ -41,13 +41,15 @@ int path_get_parent(const char *path, char **parent);
 bool path_is_absolute(const char *p) _pure_;
 char* path_make_absolute(const char *p, const char *prefix);
 char* path_make_absolute_cwd(const char *p);
+int path_make_relative(const char *from_dir, const char *to_path, char **_r);
 char* path_kill_slashes(char *path);
 char* path_startswith(const char *path, const char *prefix) _pure_;
 bool path_equal(const char *a, const char *b) _pure_;
+char* path_join(const char *root, const char *path, const char *rest);
 
 char** path_strv_make_absolute_cwd(char **l);
-char** path_strv_canonicalize_absolute(char **l, const char *prefix);
-char** path_strv_canonicalize_absolute_uniq(char **l, const char *prefix);
+char** path_strv_resolve(char **l, const char *prefix);
+char** path_strv_resolve_uniq(char **l, const char *prefix);
 
 int path_is_mount_point(const char *path, bool allow_symlink);
 int path_is_read_only_fs(const char *path);
@@ -57,6 +59,8 @@ int find_binary(const char *name, char **filename);
 
 bool paths_check_timestamp(const char* const* paths, usec_t *paths_ts_usec, bool update);
 
+int fsck_exists(const char *fstype);
+
 /* Iterates through the path prefixes of the specified path, going up
  * the tree, to root. Also returns "" (and not "/"!) for the root
  * directory. Excludes the specified directory itself */
diff --git a/src/shared/pty.c b/src/shared/pty.c
new file mode 100644 (file)
index 0000000..2863da4
--- /dev/null
@@ -0,0 +1,641 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 David Herrmann <dh.herrmann@gmail.com>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+/*
+ * PTY
+ * A PTY object represents a single PTY connection between a master and a
+ * child. The child process is fork()ed so the caller controls what program
+ * will be run.
+ *
+ * Programs like /bin/login tend to perform a vhangup() on their TTY
+ * before running the login procedure. This also causes the pty master
+ * to get a EPOLLHUP event as long as no client has the TTY opened.
+ * This means, we cannot use the TTY connection as reliable way to track
+ * the client. Instead, we _must_ rely on the PID of the client to track
+ * them.
+ * However, this has the side effect that if the client forks and the
+ * parent exits, we loose them and restart the client. But this seems to
+ * be the expected behavior so we implement it here.
+ *
+ * Unfortunately, epoll always polls for EPOLLHUP so as long as the
+ * vhangup() is ongoing, we will _always_ get EPOLLHUP and cannot sleep.
+ * This gets worse if the client closes the TTY but doesn't exit.
+ * Therefore, the fd must be edge-triggered in the epoll-set so we
+ * only get the events once they change.
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <pty.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/epoll.h>
+#include <sys/eventfd.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <sys/wait.h>
+#include <termios.h>
+#include <unistd.h>
+
+#include "barrier.h"
+#include "macro.h"
+#include "pty.h"
+#include "ring.h"
+#include "util.h"
+
+#define PTY_BUFSIZE 16384
+
+enum {
+        PTY_ROLE_UNKNOWN,
+        PTY_ROLE_PARENT,
+        PTY_ROLE_CHILD,
+};
+
+struct Pty {
+        unsigned long ref;
+        Barrier barrier;
+        int fd;
+        pid_t child;
+        sd_event_source *fd_source;
+        sd_event_source *child_source;
+
+        char in_buf[PTY_BUFSIZE];
+        Ring out_buf;
+
+        pty_event_t event_fn;
+        void *event_fn_userdata;
+
+        bool needs_requeue : 1;
+        unsigned int role : 2;
+};
+
+int pty_new(Pty **out) {
+        _pty_unref_ Pty *pty = NULL;
+        int r;
+
+        assert_return(out, -EINVAL);
+
+        pty = new0(Pty, 1);
+        if (!pty)
+                return -ENOMEM;
+
+        pty->ref = 1;
+        pty->fd = -1;
+        pty->barrier = (Barrier) BARRIER_NULL;
+
+        pty->fd = posix_openpt(O_RDWR | O_NOCTTY | O_CLOEXEC | O_NONBLOCK);
+        if (pty->fd < 0)
+                return -errno;
+
+        /*
+         * The slave-node is initialized to uid/gid of the caller of
+         * posix_openpt(). Only if devpts is mounted with fixed uid/gid this is
+         * skipped. In that case, grantpt() can overwrite these, but then you
+         * have to be root to use chown() (or a pt_chown helper has to be
+         * present). In those cases grantpt() really does something,
+         * otherwise it's a no-op. We call grantpt() here to try supporting
+         * those cases, even though no-one uses that, I guess. If you need other
+         * access-rights, set them yourself after this call returns (no, this is
+         * not racy, it looks racy, but races regarding your own UID are never
+         * important as an attacker could ptrace you; and the slave-pty is also
+         * still locked).
+         */
+        r = grantpt(pty->fd);
+        if (r < 0)
+                return -errno;
+
+        r = barrier_create(&pty->barrier);
+        if (r < 0)
+                return r;
+
+        *out = pty;
+        pty = NULL;
+        return 0;
+}
+
+Pty *pty_ref(Pty *pty) {
+        if (!pty || pty->ref < 1)
+                return NULL;
+
+        ++pty->ref;
+        return pty;
+}
+
+Pty *pty_unref(Pty *pty) {
+        if (!pty || pty->ref < 1 || --pty->ref > 0)
+                return NULL;
+
+        pty_close(pty);
+        pty->child_source = sd_event_source_unref(pty->child_source);
+        barrier_destroy(&pty->barrier);
+        ring_clear(&pty->out_buf);
+        free(pty);
+
+        return NULL;
+}
+
+Barrier *pty_get_barrier(Pty *pty) {
+        assert(pty);
+        return &pty->barrier;
+}
+
+bool pty_is_unknown(Pty *pty) {
+        return pty && pty->role == PTY_ROLE_UNKNOWN;
+}
+
+bool pty_is_parent(Pty *pty) {
+        return pty && pty->role == PTY_ROLE_PARENT;
+}
+
+bool pty_is_child(Pty *pty) {
+        return pty && pty->role == PTY_ROLE_CHILD;
+}
+
+bool pty_has_child(Pty *pty) {
+        return pty_is_parent(pty) && pty->child > 0;
+}
+
+pid_t pty_get_child(Pty *pty) {
+        return pty_has_child(pty) ? pty->child : -ECHILD;
+}
+
+bool pty_is_open(Pty *pty) {
+        return pty && pty->fd >= 0;
+}
+
+int pty_get_fd(Pty *pty) {
+        assert_return(pty, -EINVAL);
+
+        return pty_is_open(pty) ? pty->fd : -EPIPE;
+}
+
+int pty_make_child(Pty *pty) {
+        char slave_name[1024];
+        int r, fd;
+
+        assert_return(pty, -EINVAL);
+        assert_return(pty_is_unknown(pty), -EALREADY);
+
+        r = ptsname_r(pty->fd, slave_name, sizeof(slave_name));
+        if (r < 0)
+                return -errno;
+
+        fd = open(slave_name, O_RDWR | O_CLOEXEC | O_NOCTTY);
+        if (fd < 0)
+                return -errno;
+
+        safe_close(pty->fd);
+        pty->fd = fd;
+        pty->child = getpid();
+        pty->role = PTY_ROLE_CHILD;
+        barrier_set_role(&pty->barrier, BARRIER_CHILD);
+
+        return 0;
+}
+
+int pty_make_parent(Pty *pty, pid_t child) {
+        assert_return(pty, -EINVAL);
+        assert_return(pty_is_unknown(pty), -EALREADY);
+
+        pty->child = child;
+        pty->role = PTY_ROLE_PARENT;
+
+        return 0;
+}
+
+int pty_unlock(Pty *pty) {
+        assert_return(pty, -EINVAL);
+        assert_return(pty_is_unknown(pty) || pty_is_parent(pty), -EINVAL);
+        assert_return(pty_is_open(pty), -ENODEV);
+
+        return unlockpt(pty->fd) < 0 ? -errno : 0;
+}
+
+int pty_setup_child(Pty *pty) {
+        struct termios attr;
+        pid_t pid;
+        int r;
+
+        assert_return(pty, -EINVAL);
+        assert_return(pty_is_child(pty), -EINVAL);
+        assert_return(pty_is_open(pty), -EALREADY);
+
+        r = sigprocmask_many(SIG_SETMASK, -1);
+        if (r < 0)
+                return r;
+
+        r = reset_all_signal_handlers();
+        if (r < 0)
+                return r;
+
+        pid = setsid();
+        if (pid < 0 && errno != EPERM)
+                return -errno;
+
+        r = ioctl(pty->fd, TIOCSCTTY, 0);
+        if (r < 0)
+                return -errno;
+
+        r = tcgetattr(pty->fd, &attr);
+        if (r < 0)
+                return -errno;
+
+        /* erase character should be normal backspace, PLEASEEE! */
+        attr.c_cc[VERASE] = 010;
+        /* always set UTF8 flag */
+        attr.c_iflag |= IUTF8;
+
+        r = tcsetattr(pty->fd, TCSANOW, &attr);
+        if (r < 0)
+                return -errno;
+
+        if (dup2(pty->fd, STDIN_FILENO) != STDIN_FILENO ||
+            dup2(pty->fd, STDOUT_FILENO) != STDOUT_FILENO ||
+            dup2(pty->fd, STDERR_FILENO) != STDERR_FILENO)
+                return -errno;
+
+        /* only close FD if it's not a std-fd */
+        pty->fd = (pty->fd > 2) ? safe_close(pty->fd) : -1;
+
+        return 0;
+}
+
+void pty_close(Pty *pty) {
+        if (!pty_is_open(pty))
+                return;
+
+        pty->fd_source = sd_event_source_unref(pty->fd_source);
+        pty->fd = safe_close(pty->fd);
+}
+
+/*
+ * Drain input-queue and dispatch data via the event-handler. Returns <0 on
+ * error, 0 if queue is empty and 1 if we couldn't empty the input queue fast
+ * enough and there's still data left.
+ */
+static int pty_dispatch_read(Pty *pty) {
+        unsigned int i;
+        ssize_t len;
+        int r;
+
+        /*
+         * We're edge-triggered, means we need to read the whole queue. This,
+         * however, might cause us to stall if the writer is faster than we
+         * are. Therefore, we read twice and if the second read still returned
+         * data, we reschedule.
+         */
+
+        for (i = 0; i < 2; ++i) {
+                len = read(pty->fd, pty->in_buf, sizeof(pty->in_buf) - 1);
+                if (len < 0) {
+                        if (errno == EINTR)
+                                continue;
+
+                        return (errno == EAGAIN) ? 0 : -errno;
+                } else if (len == 0) {
+                        continue;
+                }
+
+                /* set terminating zero for debugging safety */
+                pty->in_buf[len] = 0;
+                r = pty->event_fn(pty, pty->event_fn_userdata, PTY_DATA, pty->in_buf, len);
+                if (r < 0)
+                        return r;
+        }
+
+        /* still data left, make sure we're queued again */
+        pty->needs_requeue = true;
+
+        return 1;
+}
+
+/*
+ * Drain output-queue by writing data to the pty. Returns <0 on error, 0 if the
+ * output queue is empty now and 1 if we couldn't empty the output queue fast
+ * enough and there's still data left.
+ */
+static int pty_dispatch_write(Pty *pty) {
+        struct iovec vec[2];
+        unsigned int i;
+        ssize_t len;
+        size_t num;
+
+        /*
+         * Same as pty_dispatch_read(), we're edge-triggered so we need to call
+         * write() until either all data is written or it returns EAGAIN. We
+         * call it twice and if it still writes successfully, we reschedule.
+         */
+
+        for (i = 0; i < 2; ++i) {
+                num = ring_peek(&pty->out_buf, vec);
+                if (num < 1)
+                        return 0;
+
+                len = writev(pty->fd, vec, (int)num);
+                if (len < 0) {
+                        if (errno == EINTR)
+                                continue;
+
+                        return (errno == EAGAIN) ? 1 : -errno;
+                } else if (len == 0) {
+                        continue;
+                }
+
+                ring_pull(&pty->out_buf, (size_t)len);
+        }
+
+        /* still data left, make sure we're queued again */
+        if (ring_get_size(&pty->out_buf) > 0) {
+                pty->needs_requeue = true;
+                return 1;
+        }
+
+        return 0;
+}
+
+static int pty_fd_fn(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
+        Pty *pty = userdata;
+        int r_hup = 0, r_write = 0, r_read = 0, r;
+
+        /*
+         * Whenever we encounter I/O errors, we have to make sure to drain the
+         * input queue first, before we handle any HUP. A child might send us
+         * a message and immediately close the queue. We must not handle the
+         * HUP first or we loose data.
+         * Therefore, if we read a message successfully, we always return
+         * success and wait for the next event-loop iteration. Furthermore,
+         * whenever there is a write-error, we must try reading from the input
+         * queue even if EPOLLIN is not set. The input might have arrived in
+         * between epoll_wait() and write(). Therefore, write-errors are only
+         * ever handled if the input-queue is empty. In all other cases they
+         * are ignored until either reading fails or the input queue is empty.
+         */
+
+        if (revents & (EPOLLHUP | EPOLLERR))
+                r_hup = -EPIPE;
+
+        if (revents & EPOLLOUT)
+                r_write = pty_dispatch_write(pty);
+
+        /* Awesome! Kernel signals HUP without IN but queues are not empty.. */
+        if ((revents & EPOLLIN) || r_hup < 0 || r_write < 0) {
+                r_read = pty_dispatch_read(pty);
+                if (r_read > 0)
+                        return 0; /* still data left to fetch next round */
+        }
+
+        if (r_hup < 0 || r_write < 0 || r_read < 0) {
+                /* PTY closed and input-queue drained */
+                pty_close(pty);
+                r = pty->event_fn(pty, pty->event_fn_userdata, PTY_HUP, NULL, 0);
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
+static int pty_fd_prepare_fn(sd_event_source *source, void *userdata) {
+        Pty *pty = userdata;
+        int r;
+
+        if (pty->needs_requeue) {
+                /*
+                 * We're edge-triggered. In case we couldn't handle all events
+                 * or in case new write-data is queued, we set needs_requeue.
+                 * Before going asleep, we set the io-events *again*. sd-event
+                 * notices that we're edge-triggered and forwards the call to
+                 * the kernel even if the events didn't change. The kernel will
+                 * check the events and re-queue us on the ready queue in case
+                 * an event is pending.
+                 */
+                r = sd_event_source_set_io_events(source, EPOLLHUP | EPOLLERR | EPOLLIN | EPOLLOUT | EPOLLET);
+                if (r >= 0)
+                        pty->needs_requeue = false;
+        }
+
+        return 0;
+}
+
+static int pty_child_fn(sd_event_source *source, const siginfo_t *si, void *userdata) {
+        Pty *pty = userdata;
+        int r;
+
+        pty->child = 0;
+
+        r = pty->event_fn(pty, pty->event_fn_userdata, PTY_CHILD, si, sizeof(*si));
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+int pty_attach_event(Pty *pty, sd_event *event, pty_event_t event_fn, void *event_fn_userdata) {
+        int r;
+
+        assert_return(pty, -EINVAL);
+        assert_return(event, -EINVAL);
+        assert_return(event_fn, -EINVAL);
+        assert_return(pty_is_parent(pty), -EINVAL);
+
+        pty_detach_event(pty);
+
+        if (pty_is_open(pty)) {
+                r = sd_event_add_io(event,
+                                    &pty->fd_source,
+                                    pty->fd,
+                                    EPOLLHUP | EPOLLERR | EPOLLIN | EPOLLOUT | EPOLLET,
+                                    pty_fd_fn,
+                                    pty);
+                if (r < 0)
+                        goto error;
+
+                r = sd_event_source_set_prepare(pty->fd_source, pty_fd_prepare_fn);
+                if (r < 0)
+                        goto error;
+        }
+
+        if (pty_has_child(pty)) {
+                r = sd_event_add_child(event,
+                                       &pty->child_source,
+                                       pty->child,
+                                       WEXITED,
+                                       pty_child_fn,
+                                       pty);
+                if (r < 0)
+                        goto error;
+        }
+
+        pty->event_fn = event_fn;
+        pty->event_fn_userdata = event_fn_userdata;
+
+        return 0;
+
+error:
+        pty_detach_event(pty);
+        return r;
+}
+
+void pty_detach_event(Pty *pty) {
+        if (!pty)
+                return;
+
+        pty->child_source = sd_event_source_unref(pty->child_source);
+        pty->fd_source = sd_event_source_unref(pty->fd_source);
+        pty->event_fn = NULL;
+        pty->event_fn_userdata = NULL;
+}
+
+int pty_write(Pty *pty, const void *buf, size_t size) {
+        bool was_empty;
+        int r;
+
+        assert_return(pty, -EINVAL);
+        assert_return(pty_is_open(pty), -ENODEV);
+        assert_return(pty_is_parent(pty), -ENODEV);
+
+        if (size < 1)
+                return 0;
+
+        /*
+         * Push @buf[0..@size] into the output ring-buffer. In case the
+         * ring-buffer wasn't empty beforehand, we're already waiting for
+         * EPOLLOUT and we're done. If it was empty, we have to re-queue the
+         * FD for EPOLLOUT as we're edge-triggered and wouldn't get any new
+         * EPOLLOUT event.
+         */
+
+        was_empty = ring_get_size(&pty->out_buf) < 1;
+
+        r = ring_push(&pty->out_buf, buf, size);
+        if (r < 0)
+                return r;
+
+        if (was_empty)
+                pty->needs_requeue = true;
+
+        return 0;
+}
+
+int pty_signal(Pty *pty, int sig) {
+        assert_return(pty, -EINVAL);
+        assert_return(pty_is_open(pty), -ENODEV);
+        assert_return(pty_is_parent(pty), -ENODEV);
+
+        return ioctl(pty->fd, TIOCSIG, sig) < 0 ? -errno : 0;
+}
+
+int pty_resize(Pty *pty, unsigned short term_width, unsigned short term_height) {
+        struct winsize ws;
+
+        assert_return(pty, -EINVAL);
+        assert_return(pty_is_open(pty), -ENODEV);
+        assert_return(pty_is_parent(pty), -ENODEV);
+
+        zero(ws);
+        ws.ws_col = term_width;
+        ws.ws_row = term_height;
+
+        /*
+         * This will send SIGWINCH to the pty slave foreground process group.
+         * We will also get one, but we don't need it.
+         */
+        return ioctl(pty->fd, TIOCSWINSZ, &ws) < 0 ? -errno : 0;
+}
+
+pid_t pty_fork(Pty **out, sd_event *event, pty_event_t event_fn, void *event_fn_userdata, unsigned short initial_term_width, unsigned short initial_term_height) {
+        _pty_unref_ Pty *pty = NULL;
+        int r;
+        pid_t pid;
+
+        assert_return(out, -EINVAL);
+        assert_return((event && event_fn) || (!event && !event_fn), -EINVAL);
+
+        r = pty_new(&pty);
+        if (r < 0)
+                return r;
+
+        r = pty_unlock(pty);
+        if (r < 0)
+                return r;
+
+        pid = fork();
+        if (pid < 0)
+                return -errno;
+
+        if (pid == 0) {
+                /* child */
+
+                r = pty_make_child(pty);
+                if (r < 0)
+                        _exit(-r);
+
+                r = pty_setup_child(pty);
+                if (r < 0)
+                        _exit(-r);
+
+                /* sync with parent */
+                if (!barrier_place_and_sync(&pty->barrier))
+                        _exit(1);
+
+                /* fallthrough and return the child's PTY object */
+        } else {
+                /* parent */
+
+                r = pty_make_parent(pty, pid);
+                if (r < 0)
+                        goto parent_error;
+
+                r = pty_resize(pty, initial_term_width, initial_term_height);
+                if (r < 0)
+                        goto parent_error;
+
+                if (event) {
+                        r = pty_attach_event(pty, event, event_fn, event_fn_userdata);
+                        if (r < 0)
+                                goto parent_error;
+                }
+
+                /* sync with child */
+                if (!barrier_place_and_sync(&pty->barrier)) {
+                        r = -ECHILD;
+                        goto parent_error;
+                }
+
+                /* fallthrough and return the parent's PTY object */
+        }
+
+        *out = pty;
+        pty = NULL;
+        return pid;
+
+parent_error:
+        barrier_abort(&pty->barrier);
+        waitpid(pty->child, NULL, 0);
+        pty->child = 0;
+        return r;
+}
diff --git a/src/shared/pty.h b/src/shared/pty.h
new file mode 100644 (file)
index 0000000..a87ceb5
--- /dev/null
@@ -0,0 +1,77 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 David Herrmann <dh.herrmann@gmail.com>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "barrier.h"
+#include "macro.h"
+#include "sd-event.h"
+#include "util.h"
+
+typedef struct Pty Pty;
+
+enum {
+        PTY_CHILD,
+        PTY_HUP,
+        PTY_DATA,
+};
+
+typedef int (*pty_event_t) (Pty *pty, void *userdata, unsigned int event, const void *ptr, size_t size);
+
+int pty_new(Pty **out);
+Pty *pty_ref(Pty *pty);
+Pty *pty_unref(Pty *pty);
+
+#define _pty_unref_ _cleanup_(pty_unrefp)
+DEFINE_TRIVIAL_CLEANUP_FUNC(Pty*, pty_unref);
+
+Barrier *pty_get_barrier(Pty *pty);
+
+bool pty_is_unknown(Pty *pty);
+bool pty_is_parent(Pty *pty);
+bool pty_is_child(Pty *pty);
+bool pty_has_child(Pty *pty);
+pid_t pty_get_child(Pty *pty);
+
+bool pty_is_open(Pty *pty);
+int pty_get_fd(Pty *pty);
+
+int pty_make_child(Pty *pty);
+int pty_make_parent(Pty *pty, pid_t child);
+int pty_unlock(Pty *pty);
+int pty_setup_child(Pty *pty);
+void pty_close(Pty *pty);
+
+int pty_attach_event(Pty *pty, sd_event *event, pty_event_t event_fn, void *event_fn_userdata);
+void pty_detach_event(Pty *pty);
+
+int pty_write(Pty *pty, const void *buf, size_t size);
+int pty_signal(Pty *pty, int sig);
+int pty_resize(Pty *pty, unsigned short term_width, unsigned short term_height);
+
+pid_t pty_fork(Pty **out, sd_event *event, pty_event_t event_fn, void *event_fn_userdata, unsigned short initial_term_width, unsigned short initial_term_height);
diff --git a/src/shared/ring.c b/src/shared/ring.c
new file mode 100644 (file)
index 0000000..309075e
--- /dev/null
@@ -0,0 +1,210 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 David Herrmann <dh.herrmann@gmail.com>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <inttypes.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/uio.h>
+#include "macro.h"
+#include "ring.h"
+
+#define RING_MASK(_r, _v) ((_v) & ((_r)->size - 1))
+
+void ring_flush(Ring *r) {
+        assert(r);
+
+        r->start = 0;
+        r->used = 0;
+}
+
+void ring_clear(Ring *r) {
+        assert(r);
+
+        free(r->buf);
+        zero(*r);
+}
+
+/*
+ * Get data pointers for current ring-buffer data. @vec must be an array of 2
+ * iovec objects. They are filled according to the data available in the
+ * ring-buffer. 0, 1 or 2 is returned according to the number of iovec objects
+ * that were filled (0 meaning buffer is empty).
+ *
+ * Hint: "struct iovec" is defined in <sys/uio.h> and looks like this:
+ *     struct iovec {
+ *         void *iov_base;
+ *         size_t iov_len;
+ *     };
+ */
+size_t ring_peek(Ring *r, struct iovec *vec) {
+        assert(r);
+
+        if (r->used == 0) {
+                return 0;
+        } else if (r->start + r->used <= r->size) {
+                if (vec) {
+                        vec[0].iov_base = &r->buf[r->start];
+                        vec[0].iov_len = r->used;
+                }
+                return 1;
+        } else {
+                if (vec) {
+                        vec[0].iov_base = &r->buf[r->start];
+                        vec[0].iov_len = r->size - r->start;
+                        vec[1].iov_base = r->buf;
+                        vec[1].iov_len = r->used - (r->size - r->start);
+                }
+                return 2;
+        }
+}
+
+/*
+ * Copy data from the ring buffer into the linear external buffer @buf. Copy
+ * at most @size bytes. If the ring buffer size is smaller, copy less bytes and
+ * return the number of bytes copied.
+ */
+size_t ring_copy(Ring *r, void *buf, size_t size) {
+        size_t l;
+
+        assert(r);
+        assert(buf);
+
+        if (size > r->used)
+                size = r->used;
+
+        if (size > 0) {
+                l = r->size - r->start;
+                if (size <= l) {
+                        memcpy(buf, &r->buf[r->start], size);
+                } else {
+                        memcpy(buf, &r->buf[r->start], l);
+                        memcpy((uint8_t*)buf + l, r->buf, size - l);
+                }
+        }
+
+        return size;
+}
+
+/*
+ * Resize ring-buffer to size @nsize. @nsize must be a power-of-2, otherwise
+ * ring operations will behave incorrectly.
+ */
+static int ring_resize(Ring *r, size_t nsize) {
+        uint8_t *buf;
+        size_t l;
+
+        assert(r);
+        assert(nsize > 0);
+
+        buf = malloc(nsize);
+        if (!buf)
+                return -ENOMEM;
+
+        if (r->used > 0) {
+                l = r->size - r->start;
+                if (r->used <= l) {
+                        memcpy(buf, &r->buf[r->start], r->used);
+                } else {
+                        memcpy(buf, &r->buf[r->start], l);
+                        memcpy(&buf[l], r->buf, r->used - l);
+                }
+        }
+
+        free(r->buf);
+        r->buf = buf;
+        r->size = nsize;
+        r->start = 0;
+
+        return 0;
+}
+
+/*
+ * Resize ring-buffer to provide enough room for @add bytes of new data. This
+ * resizes the buffer if it is too small. It returns -ENOMEM on OOM and 0 on
+ * success.
+ */
+static int ring_grow(Ring *r, size_t add) {
+        size_t need;
+
+        assert(r);
+
+        if (r->size - r->used >= add)
+                return 0;
+
+        need = r->used + add;
+        if (need <= r->used)
+                return -ENOMEM;
+        else if (need < 4096)
+                need = 4096;
+
+        need = ALIGN_POWER2(need);
+        if (need == 0)
+                return -ENOMEM;
+
+        return ring_resize(r, need);
+}
+
+/*
+ * Push @len bytes from @u8 into the ring buffer. The buffer is resized if it
+ * is too small. -ENOMEM is returned on OOM, 0 on success.
+ */
+int ring_push(Ring *r, const void *u8, size_t size) {
+        int err;
+        size_t pos, l;
+
+        assert(r);
+        assert(u8);
+
+        if (size == 0)
+                return 0;
+
+        err = ring_grow(r, size);
+        if (err < 0)
+                return err;
+
+        pos = RING_MASK(r, r->start + r->used);
+        l = r->size - pos;
+        if (l >= size) {
+                memcpy(&r->buf[pos], u8, size);
+        } else {
+                memcpy(&r->buf[pos], u8, l);
+                memcpy(r->buf, (const uint8_t*)u8 + l, size - l);
+        }
+
+        r->used += size;
+
+        return 0;
+}
+
+/*
+ * Remove @len bytes from the start of the ring-buffer. Note that we protect
+ * against overflows so removing more bytes than available is safe.
+ */
+void ring_pull(Ring *r, size_t size) {
+        assert(r);
+
+        if (size > r->used)
+                size = r->used;
+
+        r->start = RING_MASK(r, r->start + size);
+        r->used -= size;
+}
diff --git a/src/shared/ring.h b/src/shared/ring.h
new file mode 100644 (file)
index 0000000..1210aab
--- /dev/null
@@ -0,0 +1,61 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 David Herrmann <dh.herrmann@gmail.com>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <inttypes.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/uio.h>
+
+typedef struct Ring Ring;
+
+struct Ring {
+        uint8_t *buf;           /* buffer or NULL */
+        size_t size;            /* actual size of @buf */
+        size_t start;           /* start position of ring */
+        size_t used;            /* number of actually used bytes */
+};
+
+/* flush buffer so it is empty again */
+void ring_flush(Ring *r);
+
+/* flush buffer, free allocated data and reset to initial state */
+void ring_clear(Ring *r);
+
+/* get pointers to buffer data and their length */
+size_t ring_peek(Ring *r, struct iovec *vec);
+
+/* copy data into external linear buffer */
+size_t ring_copy(Ring *r, void *buf, size_t size);
+
+/* push data to the end of the buffer */
+int ring_push(Ring *r, const void *u8, size_t size);
+
+/* pull data from the front of the buffer */
+void ring_pull(Ring *r, size_t size);
+
+/* return size of occupied buffer in bytes */
+static inline size_t ring_get_size(Ring *r)
+{
+        return r->used;
+}
index 5a4bf11..02ea831 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "set.h"
 #include "hashmap.h"
+#include "strv.h"
 
 #define MAKE_SET(h) ((Set*) (h))
 #define MAKE_HASHMAP(s) ((Hashmap*) (s))
@@ -59,6 +60,39 @@ int set_consume(Set *s, void *value) {
         return r;
 }
 
+int set_put_strdup(Set *s, const char *p) {
+        char *c;
+        int r;
+
+        assert(s);
+        assert(p);
+
+        c = strdup(p);
+        if (!c)
+                return -ENOMEM;
+
+        r = set_consume(s, c);
+        if (r == -EEXIST)
+                return 0;
+
+        return r;
+}
+
+int set_put_strdupv(Set *s, char **l) {
+        int n = 0, r;
+        char **i;
+
+        STRV_FOREACH(i, l) {
+                r = set_put_strdup(s, *i);
+                if (r < 0)
+                        return r;
+
+                n += r;
+        }
+
+        return n;
+}
+
 int set_replace(Set *s, void *value) {
         return hashmap_replace(MAKE_HASHMAP(s), value, value);
 }
index 5612478..e0b9c9e 100644 (file)
@@ -41,6 +41,8 @@ int set_ensure_allocated(Set **s, hash_func_t hash_func, compare_func_t compare_
 
 int set_put(Set *s, void *value);
 int set_consume(Set *s, void *value);
+int set_put_strdup(Set *s, const char *p);
+int set_put_strdupv(Set *s, char **l);
 int set_replace(Set *s, void *value);
 void *set_get(Set *s, void *value);
 bool set_contains(Set *s, void *value);
index cf1cd40..d8de644 100644 (file)
@@ -31,6 +31,7 @@
 #define USE(x, y) do{ (x) = (y); (y) = NULL; } while(0)
 
 int parse_sleep_config(const char *verb, char ***_modes, char ***_states) {
+
         _cleanup_strv_free_ char
                 **suspend_mode = NULL, **suspend_state = NULL,
                 **hibernate_mode = NULL, **hibernate_state = NULL,
@@ -44,21 +45,12 @@ int parse_sleep_config(const char *verb, char ***_modes, char ***_states) {
                 { "Sleep",   "HibernateState",   config_parse_strv,  0, &hibernate_state },
                 { "Sleep",   "HybridSleepMode",  config_parse_strv,  0, &hybrid_mode  },
                 { "Sleep",   "HybridSleepState", config_parse_strv,  0, &hybrid_state },
-                {}};
+                {}
+        };
 
-        int r;
-        FILE _cleanup_fclose_ *f;
-
-        f = fopen(PKGSYSCONFDIR "/sleep.conf", "re");
-        if (!f)
-                log_full(errno == ENOENT ? LOG_DEBUG: LOG_WARNING,
-                         "Failed to open configuration file " PKGSYSCONFDIR "/sleep.conf: %m");
-        else {
-                r = config_parse(NULL, PKGSYSCONFDIR "/sleep.conf", f, "Sleep\0",
-                                 config_item_table_lookup, (void*) items, false, false, NULL);
-                if (r < 0)
-                        log_warning("Failed to parse configuration file: %s", strerror(-r));
-        }
+        config_parse(NULL, PKGSYSCONFDIR "/sleep.conf", NULL,
+                     "Sleep\0",
+                     config_item_table_lookup, items, false, false, true, NULL);
 
         if (streq(verb, "suspend")) {
                 /* empty by default */
@@ -106,7 +98,7 @@ int parse_sleep_config(const char *verb, char ***_modes, char ***_states) {
 }
 
 int can_sleep_state(char **types) {
-        char *w, *state, **type;
+        char **type;
         int r;
         _cleanup_free_ char *p = NULL;
 
@@ -122,11 +114,12 @@ int can_sleep_state(char **types) {
                 return false;
 
         STRV_FOREACH(type, types) {
+                const char *word, *state;
                 size_t l, k;
 
                 k = strlen(*type);
-                FOREACH_WORD_SEPARATOR(w, l, p, WHITESPACE, state)
-                        if (l == k && memcmp(w, *type, l) == 0)
+                FOREACH_WORD_SEPARATOR(word, l, p, WHITESPACE, state)
+                        if (l == k && memcmp(word, *type, l) == 0)
                                 return true;
         }
 
@@ -134,7 +127,7 @@ int can_sleep_state(char **types) {
 }
 
 int can_sleep_disk(char **types) {
-        char *w, *state, **type;
+        char **type;
         int r;
         _cleanup_free_ char *p = NULL;
 
@@ -150,14 +143,18 @@ int can_sleep_disk(char **types) {
                 return false;
 
         STRV_FOREACH(type, types) {
+                const char *word, *state;
                 size_t l, k;
 
                 k = strlen(*type);
-                FOREACH_WORD_SEPARATOR(w, l, p, WHITESPACE, state) {
-                        if (l == k && memcmp(w, *type, l) == 0)
+                FOREACH_WORD_SEPARATOR(word, l, p, WHITESPACE, state) {
+                        if (l == k && memcmp(word, *type, l) == 0)
                                 return true;
 
-                        if (l == k + 2 && w[0] == '[' && memcmp(w + 1, *type, l - 2) == 0 && w[l-1] == ']')
+                        if (l == k + 2 &&
+                            word[0] == '[' &&
+                            memcmp(word + 1, *type, l - 2) == 0 &&
+                            word[l-1] == ']')
                                 return true;
                 }
         }
index df194e0..91eed5f 100644 (file)
 
 #include <unistd.h>
 #include <string.h>
-#ifdef HAVE_XATTR
-#include <attr/xattr.h>
-#endif
+#include <sys/xattr.h>
 
+#include "util.h"
 #include "smack-util.h"
 
 bool use_smack(void) {
@@ -57,6 +56,60 @@ int smack_label_path(const char *path, const char *label) {
 #endif
 }
 
+int smack_label_get_path(const char *path, char **label) {
+        int i;
+        int r = 0;
+        char buf[SMACK_LABEL_LEN + 1];
+        char *result = NULL;
+
+        assert(path);
+
+#ifdef HAVE_SMACK
+        if (!use_smack())
+                return 0;
+
+        r = lgetxattr(path, "security.SMACK64", buf, SMACK_LABEL_LEN + 1);
+        if (r < 0)
+                return -errno;
+        else if (buf[0] == '\0' || buf[0] == '-')
+                return -EINVAL;
+
+        result = calloc(r + 1, 1);
+        if (result == NULL)
+                 return -errno;
+
+        for (i = 0; i < (SMACK_LABEL_LEN + 1) && buf[i]; i++) {
+                if (buf[i] <= ' ' || buf[i] > '~')
+                    return -EINVAL;
+                switch (buf[i]) {
+                case '/':
+                case '"':
+                case '\\':
+                case '\'':
+                        return -EINVAL;
+                default:
+                        break;
+                }
+
+                if (result)
+                        result[i] = buf[i];
+        }
+
+        if (result && i < (SMACK_LABEL_LEN + 1))
+                result[i] = '\0';
+
+        if (i < 0) {
+                free(result);
+                return -EINVAL;
+        }
+        *label = result;
+
+        return i;
+#endif
+
+        return r;
+}
+
 int smack_label_fd(int fd, const char *label) {
 #ifdef HAVE_SMACK
         if (!use_smack())
@@ -68,6 +121,25 @@ int smack_label_fd(int fd, const char *label) {
 #endif
 }
 
+int smack_label_apply_pid(pid_t pid, const char *label) {
+        int r = 0;
+        const char *p;
+
+        assert(label);
+
+#ifdef HAVE_SMACK
+        if (!use_smack())
+                return 0;
+
+        p = procfs_file_alloca(pid, "attr/current");
+        r = write_string_file(p, label);
+        if (r < 0)
+                return r;
+#endif
+
+        return r;
+}
+
 int smack_label_ip_out_fd(int fd, const char *label) {
 #ifdef HAVE_SMACK
         if (!use_smack())
index 7370ae3..ab9ef8d 100644 (file)
 
 #define SMACK_FLOOR_LABEL "_"
 #define SMACK_STAR_LABEL  "*"
+#define SMACK_LABEL_LEN 255
 
 bool use_smack(void);
 
 int smack_label_path(const char *path, const char *label);
+int smack_get_label_path(const char *path, char **label);
 int smack_label_fd(int fd, const char *label);
+int smack_label_apply_pid(pid_t pid, const char *label);
 int smack_label_ip_in_fd(int fd, const char *label);
 int smack_label_ip_out_fd(int fd, const char *label);
index c8be17a..83ea1a9 100644 (file)
@@ -143,3 +143,33 @@ int socket_address_listen(
 
         return r;
 }
+
+int make_socket_fd(int log_level, const char* address, int flags) {
+        SocketAddress a;
+        int fd, r;
+
+        r = socket_address_parse(&a, address);
+        if (r < 0) {
+                log_error("Failed to parse socket: %s", strerror(-r));
+                return r;
+        }
+
+        fd = socket_address_listen(&a, flags, SOMAXCONN, SOCKET_ADDRESS_DEFAULT,
+                                   NULL, false, false, 0755, 0644, NULL);
+        if (fd < 0 || log_get_max_level() >= log_level) {
+                _cleanup_free_ char *p = NULL;
+
+                r = socket_address_print(&a, &p);
+                if (r < 0) {
+                        log_error("socket_address_print(): %s", strerror(-r));
+                        return r;
+                }
+
+                if (fd < 0)
+                        log_error("Failed to listen on %s: %s", p, strerror(-fd));
+                else
+                        log_full(log_level, "Listening on %s", p);
+        }
+
+        return fd;
+}
index 5ef2e22..e3e54e8 100644 (file)
@@ -31,6 +31,7 @@
 #include <sys/stat.h>
 #include <stddef.h>
 #include <sys/ioctl.h>
+#include <netdb.h>
 
 #include "macro.h"
 #include "util.h"
@@ -425,11 +426,11 @@ bool socket_ipv6_is_supported(void) {
         _cleanup_free_ char *l = NULL;
 
         if (access("/sys/module/ipv6", F_OK) != 0)
-                return 0;
+                return false;
 
         /* If we can't check "disable" parameter, assume enabled */
         if (read_one_line_file("/sys/module/ipv6/parameters/disable", &l) < 0)
-                return 1;
+                return true;
 
         /* If module was loaded with disable=1 no IPv6 available */
         return l[0] == '0';
@@ -574,13 +575,12 @@ int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_
 
 int getpeername_pretty(int fd, char **ret) {
         union sockaddr_union sa;
-        socklen_t salen;
+        socklen_t salen = sizeof(sa);
         int r;
 
         assert(fd >= 0);
         assert(ret);
 
-        salen = sizeof(sa);
         if (getpeername(fd, &sa.sa, &salen) < 0)
                 return -errno;
 
@@ -594,7 +594,7 @@ int getpeername_pretty(int fd, char **ret) {
                 if (r < 0)
                         return r;
 
-                if (asprintf(ret, "PID %lu/UID %lu", (unsigned long) ucred.pid, (unsigned long) ucred.uid) < 0)
+                if (asprintf(ret, "PID "PID_FMT"/UID "UID_FMT, ucred.pid, ucred.uid) < 0)
                         return -ENOMEM;
 
                 return 0;
@@ -608,12 +608,11 @@ int getpeername_pretty(int fd, char **ret) {
 
 int getsockname_pretty(int fd, char **ret) {
         union sockaddr_union sa;
-        socklen_t salen;
+        socklen_t salen = sizeof(sa);
 
         assert(fd >= 0);
         assert(ret);
 
-        salen = sizeof(sa);
         if (getsockname(fd, &sa.sa, &salen) < 0)
                 return -errno;
 
@@ -625,6 +624,64 @@ int getsockname_pretty(int fd, char **ret) {
         return sockaddr_pretty(&sa.sa, salen, false, ret);
 }
 
+int socknameinfo_pretty(union sockaddr_union *sa, socklen_t salen, char **_ret) {
+        int r;
+        char host[NI_MAXHOST], *ret;
+
+        assert(_ret);
+
+        r = getnameinfo(&sa->sa, salen, host, sizeof(host), NULL, 0,
+                        NI_IDN|NI_IDN_USE_STD3_ASCII_RULES);
+        if (r != 0) {
+                _cleanup_free_ char *sockname = NULL;
+                int saved_errno = errno;
+
+                r = sockaddr_pretty(&sa->sa, salen, true, &sockname);
+                if (r < 0)
+                        log_error("sockadd_pretty() failed: %s", strerror(-r));
+                else
+                        log_error("getnameinfo(%s) failed: %s", sockname, strerror(-r));
+                return -saved_errno;
+        }
+
+        ret = strdup(host);
+        if (!ret)
+                return log_oom();
+
+        *_ret = ret;
+        return 0;
+}
+
+int getnameinfo_pretty(int fd, char **ret) {
+        union sockaddr_union sa;
+        socklen_t salen = sizeof(sa);
+
+        assert(fd >= 0);
+        assert(ret);
+
+        if (getsockname(fd, &sa.sa, &salen) < 0) {
+                log_error("getsockname(%d) failed: %m", fd);
+                return -errno;
+        }
+
+        return socknameinfo_pretty(&sa, salen, ret);
+}
+
+int socket_address_unlink(SocketAddress *a) {
+        assert(a);
+
+        if (socket_address_family(a) != AF_UNIX)
+                return 0;
+
+        if (a->sockaddr.un.sun_path[0] == 0)
+                return 0;
+
+        if (unlink(a->sockaddr.un.sun_path) < 0)
+                return -errno;
+
+        return 1;
+}
+
 static const char* const netlink_family_table[] = {
         [NETLINK_ROUTE] = "route",
         [NETLINK_FIREWALL] = "firewall",
@@ -654,3 +711,38 @@ static const char* const socket_address_bind_ipv6_only_table[_SOCKET_ADDRESS_BIN
 };
 
 DEFINE_STRING_TABLE_LOOKUP(socket_address_bind_ipv6_only, SocketAddressBindIPv6Only);
+
+bool sockaddr_equal(const union sockaddr_union *a, const union sockaddr_union *b) {
+        assert(a);
+        assert(b);
+
+        if (a->sa.sa_family != b->sa.sa_family)
+                return false;
+
+        if (a->sa.sa_family == AF_INET)
+                return a->in.sin_addr.s_addr == b->in.sin_addr.s_addr;
+
+        if (a->sa.sa_family == AF_INET6)
+                return memcmp(&a->in6.sin6_addr, &b->in6.sin6_addr, sizeof(a->in6.sin6_addr)) == 0;
+
+        return false;
+}
+
+char* ether_addr_to_string(const struct ether_addr *addr, char buffer[ETHER_ADDR_TO_STRING_MAX]) {
+        assert(addr);
+        assert(buffer);
+
+        /* Like ether_ntoa() but uses %02x instead of %x to print
+         * ethernet addresses, which makes them look less funny. Also,
+         * doesn't use a static buffer. */
+
+        sprintf(buffer, "%02x:%02x:%02x:%02x:%02x:%02x",
+                addr->ether_addr_octet[0],
+                addr->ether_addr_octet[1],
+                addr->ether_addr_octet[2],
+                addr->ether_addr_octet[3],
+                addr->ether_addr_octet[4],
+                addr->ether_addr_octet[5]);
+
+        return buffer;
+}
index 84ebc30..07d0aff 100644 (file)
@@ -23,8 +23,8 @@
 
 #include <sys/socket.h>
 #include <netinet/in.h>
+#include <netinet/ether.h>
 #include <sys/un.h>
-#include <net/if.h>
 #include <asm/types.h>
 #include <linux/netlink.h>
 #include <linux/if_packet.h>
@@ -70,6 +70,7 @@ int socket_address_parse(SocketAddress *a, const char *s);
 int socket_address_parse_netlink(SocketAddress *a, const char *s);
 int socket_address_print(const SocketAddress *a, char **p);
 int socket_address_verify(const SocketAddress *a) _pure_;
+int socket_address_unlink(SocketAddress *a);
 
 bool socket_address_can_accept(const SocketAddress *a) _pure_;
 
@@ -84,6 +85,7 @@ int socket_address_listen(
                 mode_t directory_mode,
                 mode_t socket_mode,
                 const char *label);
+int make_socket_fd(int log_level, const char* address, int flags);
 
 bool socket_address_is(const SocketAddress *a, const char *s, int type);
 bool socket_address_is_netlink(const SocketAddress *a, const char *s);
@@ -100,8 +102,17 @@ int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_
 int getpeername_pretty(int fd, char **ret);
 int getsockname_pretty(int fd, char **ret);
 
+int socknameinfo_pretty(union sockaddr_union *sa, socklen_t salen, char **_ret);
+int getnameinfo_pretty(int fd, char **ret);
+
 const char* socket_address_bind_ipv6_only_to_string(SocketAddressBindIPv6Only b) _const_;
 SocketAddressBindIPv6Only socket_address_bind_ipv6_only_from_string(const char *s) _pure_;
 
 int netlink_family_to_string_alloc(int b, char **s);
 int netlink_family_from_string(const char *s) _pure_;
+
+bool sockaddr_equal(const union sockaddr_union *a, const union sockaddr_union *b);
+
+#define ETHER_ADDR_TO_STRING_MAX (3*6)
+
+char* ether_addr_to_string(const struct ether_addr *addr, char buffer[ETHER_ADDR_TO_STRING_MAX]);
index f9e52cd..29b01db 100644 (file)
@@ -61,15 +61,15 @@ int polkit_agent_open(void) {
                        POLKIT_AGENT_BINARY_PATH, "--notify-fd", notify_fd, "--fallback", NULL);
 
         /* Close the writing side, because that's the one for the agent */
-        close_nointr_nofail(pipe_fd[1]);
+        safe_close(pipe_fd[1]);
 
         if (r < 0)
                 log_error("Failed to fork TTY ask password agent: %s", strerror(-r));
         else
                 /* Wait until the agent closes the fd */
-                fd_wait_for_event(pipe_fd[0], POLLHUP, (usec_t) -1);
+                fd_wait_for_event(pipe_fd[0], POLLHUP, USEC_INFINITY);
 
-        close_nointr_nofail(pipe_fd[0]);
+        safe_close(pipe_fd[0]);
 
         return r;
 }
index 2fe5db5..b045047 100644 (file)
 #define SPECIAL_REMOTE_FS_PRE_TARGET "remote-fs-pre.target"
 #define SPECIAL_SWAP_TARGET "swap.target"
 #define SPECIAL_NETWORK_ONLINE_TARGET "network-online.target"
+#define SPECIAL_TIME_SYNC_TARGET "time-sync.target"       /* LSB's $time */
 #define SPECIAL_BASIC_TARGET "basic.target"
 
 /* LSB compatibility */
 #define SPECIAL_NETWORK_TARGET "network.target"           /* LSB's $network */
 #define SPECIAL_NSS_LOOKUP_TARGET "nss-lookup.target"     /* LSB's $named */
 #define SPECIAL_RPCBIND_TARGET "rpcbind.target"           /* LSB's $portmap */
-#define SPECIAL_TIME_SYNC_TARGET "time-sync.target"       /* LSB's $time */
 
 /*
  * Rules regarding adding further high level targets like the above:
index 13deba7..e7062a3 100644 (file)
@@ -201,8 +201,7 @@ int strv_extend_strv_concat(char ***a, char **b, const char *suffix) {
 }
 
 char **strv_split(const char *s, const char *separator) {
-        char *state;
-        char *w;
+        const char *word, *state;
         size_t l;
         unsigned n, i;
         char **r;
@@ -210,7 +209,7 @@ char **strv_split(const char *s, const char *separator) {
         assert(s);
 
         n = 0;
-        FOREACH_WORD_SEPARATOR(w, l, s, separator, state)
+        FOREACH_WORD_SEPARATOR(word, l, s, separator, state)
                 n++;
 
         r = new(char*, n+1);
@@ -218,8 +217,8 @@ char **strv_split(const char *s, const char *separator) {
                 return NULL;
 
         i = 0;
-        FOREACH_WORD_SEPARATOR(w, l, s, separator, state) {
-                r[i] = strndup(w, l);
+        FOREACH_WORD_SEPARATOR(word, l, s, separator, state) {
+                r[i] = strndup(word, l);
                 if (!r[i]) {
                         strv_free(r);
                         return NULL;
@@ -232,9 +231,8 @@ char **strv_split(const char *s, const char *separator) {
         return r;
 }
 
-char **strv_split_quoted(const char *s) {
-        char *state;
-        char *w;
+int strv_split_quoted(char ***t, const char *s) {
+        const char *word, *state;
         size_t l;
         unsigned n, i;
         char **r;
@@ -242,25 +240,29 @@ char **strv_split_quoted(const char *s) {
         assert(s);
 
         n = 0;
-        FOREACH_WORD_QUOTED(w, l, s, state)
+        FOREACH_WORD_QUOTED(word, l, s, state)
                 n++;
+        if (!isempty(state))
+                /* bad syntax */
+                return -EINVAL;
 
         r = new(char*, n+1);
         if (!r)
-                return NULL;
+                return -ENOMEM;
 
         i = 0;
-        FOREACH_WORD_QUOTED(w, l, s, state) {
-                r[i] = cunescape_length(w, l);
+        FOREACH_WORD_QUOTED(word, l, s, state) {
+                r[i] = cunescape_length(word, l);
                 if (!r[i]) {
                         strv_free(r);
-                        return NULL;
+                        return -ENOMEM;
                 }
                 i++;
         }
 
         r[i] = NULL;
-        return r;
+        *t = r;
+        return 0;
 }
 
 char **strv_split_newlines(const char *s) {
@@ -378,9 +380,92 @@ int strv_push(char ***l, char *value) {
         return 0;
 }
 
+int strv_push_pair(char ***l, char *a, char *b) {
+        char **c;
+        unsigned n, m;
+
+        if (!a && !b)
+                return 0;
+
+        n = strv_length(*l);
+
+        /* increase and check for overflow */
+        m = n + !!a + !!b + 1;
+        if (m < n)
+                return -ENOMEM;
+
+        c = realloc_multiply(*l, sizeof(char*), m);
+        if (!c)
+                return -ENOMEM;
+
+        if (a)
+                c[n++] = a;
+        if (b)
+                c[n++] = b;
+        c[n] = NULL;
+
+        *l = c;
+        return 0;
+}
+
+int strv_push_prepend(char ***l, char *value) {
+        char **c;
+        unsigned n, i;
+
+        if (!value)
+                return 0;
+
+        n = strv_length(*l);
+        c = new(char*, n + 2);
+        if (!c)
+                return -ENOMEM;
+
+        for (i = 0; i < n; i++)
+                c[i+1] = (*l)[i];
+
+        c[0] = value;
+        c[n+1] = NULL;
+
+        free(*l);
+        *l = c;
+
+        return 0;
+}
+
+int strv_consume(char ***l, char *value) {
+        int r;
+
+        r = strv_push(l, value);
+        if (r < 0)
+                free(value);
+
+        return r;
+}
+
+int strv_consume_pair(char ***l, char *a, char *b) {
+        int r;
+
+        r = strv_push_pair(l, a, b);
+        if (r < 0) {
+                free(a);
+                free(b);
+        }
+
+        return r;
+}
+
+int strv_consume_prepend(char ***l, char *value) {
+        int r;
+
+        r = strv_push_prepend(l, value);
+        if (r < 0)
+                free(value);
+
+        return r;
+}
+
 int strv_extend(char ***l, const char *value) {
         char *v;
-        int r;
 
         if (!value)
                 return 0;
@@ -389,11 +474,7 @@ int strv_extend(char ***l, const char *value) {
         if (!v)
                 return -ENOMEM;
 
-        r = strv_push(l, v);
-        if (r < 0)
-                free(v);
-
-        return r;
+        return strv_consume(l, v);
 }
 
 char **strv_uniq(char **l) {
@@ -522,3 +603,18 @@ void strv_print(char **l) {
         STRV_FOREACH(s, l)
                 puts(*s);
 }
+
+int strv_extendf(char ***l, const char *format, ...) {
+        va_list ap;
+        char *x;
+        int r;
+
+        va_start(ap, format);
+        r = vasprintf(&x, format, ap);
+        va_end(ap);
+
+        if (r < 0)
+                return -ENOMEM;
+
+        return strv_consume(l, x);
+}
index 715bc54..13d817e 100644 (file)
@@ -39,7 +39,13 @@ unsigned strv_length(char * const *l) _pure_;
 int strv_extend_strv(char ***a, char **b);
 int strv_extend_strv_concat(char ***a, char **b, const char *suffix);
 int strv_extend(char ***l, const char *value);
+int strv_extendf(char ***l, const char *format, ...) _printf_(2,0);
 int strv_push(char ***l, char *value);
+int strv_push_pair(char ***l, char *a, char *b);
+int strv_push_prepend(char ***l, char *value);
+int strv_consume(char ***l, char *value);
+int strv_consume_pair(char ***l, char *a, char *b);
+int strv_consume_prepend(char ***l, char *value);
 
 char **strv_remove(char **l, const char *s);
 char **strv_uniq(char **l);
@@ -58,7 +64,7 @@ static inline bool strv_isempty(char * const *l) {
 }
 
 char **strv_split(const char *s, const char *separator);
-char **strv_split_quoted(const char *s);
+int strv_split_quoted(char ***t, const char *s);
 char **strv_split_newlines(const char *s);
 
 char *strv_join(char **l, const char *separator);
@@ -115,3 +121,17 @@ void strv_print(char **l);
                 }                                               \
                 _l;                                             \
         })
+
+#define STR_IN_SET(x, ...) strv_contains(STRV_MAKE(__VA_ARGS__), x)
+
+#define FOREACH_STRING(x, ...)                               \
+        for (char **_l = ({                                  \
+                char **_ll = STRV_MAKE(__VA_ARGS__);         \
+                x = _ll ? _ll[0] : NULL;                     \
+                _ll;                                         \
+        });                                                  \
+        _l && *_l;                                           \
+        x = ({                                               \
+                _l ++;                                       \
+                _l[0];                                       \
+        }))
index 3261302..3ac8729 100644 (file)
@@ -49,3 +49,6 @@ static inline void _test_table(const char *name,
 
 #define test_table(lower, upper) \
         _test_table(STRINGIFY(lower), lower##_to_string, lower##_from_string, _##upper##_MAX, false)
+
+#define test_table_sparse(lower, upper) \
+        _test_table(STRINGIFY(lower), lower##_to_string, lower##_from_string, _##upper##_MAX, true)
index 65e2998..6195b11 100644 (file)
@@ -207,8 +207,8 @@ read_again:
                 if (type_idxs[i] >= num_types)
                         return -EINVAL;
 
-        if ((BYTE_ORDER != BIG_ENDIAN && (sizeof(time_t) == 4 || trans_width == 4)) ||
-            (BYTE_ORDER == BIG_ENDIAN && sizeof(time_t) == 8 && trans_width == 4)) {
+        if (__BYTE_ORDER == __BIG_ENDIAN ? sizeof(time_t) == 8 && trans_width == 4
+                                         : sizeof(time_t) == 4 || trans_width == 4) {
                 /* Decode the transition times, stored as 4-byte integers in
                    network (big-endian) byte order.  We work from the end of
                    the array so as not to clobber the next element to be
@@ -216,7 +216,7 @@ read_again:
                 i = num_transitions;
                 while (i-- > 0)
                         transitions[i] = decode((char *)transitions + i * 4);
-        } else if (BYTE_ORDER != BIG_ENDIAN && sizeof(time_t) == 8) {
+        } else if (__BYTE_ORDER != __BIG_ENDIAN && sizeof(time_t) == 8) {
                 /* Decode the transition times, stored as 8-byte integers in
                    network (big-endian) byte order.  */
                 for (i = 0; i < num_transitions; ++i)
index faa3418..2dc01e6 100644 (file)
 #include <time.h>
 #include <string.h>
 #include <sys/timex.h>
+#include <sys/timerfd.h>
 
 #include "util.h"
 #include "time-util.h"
+#include "strv.h"
 
 usec_t now(clockid_t clock_id) {
         struct timespec ts;
@@ -47,8 +49,8 @@ dual_timestamp* dual_timestamp_from_realtime(dual_timestamp *ts, usec_t u) {
         int64_t delta;
         assert(ts);
 
-        if (u == (usec_t) -1) {
-                ts->realtime = ts->monotonic = (usec_t) -1;
+        if (u == USEC_INFINITY) {
+                ts->realtime = ts->monotonic = USEC_INFINITY;
                 return ts;
         }
 
@@ -74,8 +76,8 @@ dual_timestamp* dual_timestamp_from_monotonic(dual_timestamp *ts, usec_t u) {
         int64_t delta;
         assert(ts);
 
-        if (u == (usec_t) -1) {
-                ts->realtime = ts->monotonic = (usec_t) -1;
+        if (u == USEC_INFINITY) {
+                ts->realtime = ts->monotonic = USEC_INFINITY;
                 return ts;
         }
 
@@ -96,10 +98,10 @@ usec_t timespec_load(const struct timespec *ts) {
 
         if (ts->tv_sec == (time_t) -1 &&
             ts->tv_nsec == (long) -1)
-                return (usec_t) -1;
+                return USEC_INFINITY;
 
         if ((usec_t) ts->tv_sec > (UINT64_MAX - (ts->tv_nsec / NSEC_PER_USEC)) / USEC_PER_SEC)
-                return (usec_t) -1;
+                return USEC_INFINITY;
 
         return
                 (usec_t) ts->tv_sec * USEC_PER_SEC +
@@ -109,7 +111,7 @@ usec_t timespec_load(const struct timespec *ts) {
 struct timespec *timespec_store(struct timespec *ts, usec_t u)  {
         assert(ts);
 
-        if (u == (usec_t) -1) {
+        if (u == USEC_INFINITY) {
                 ts->tv_sec = (time_t) -1;
                 ts->tv_nsec = (long) -1;
                 return ts;
@@ -126,10 +128,10 @@ usec_t timeval_load(const struct timeval *tv) {
 
         if (tv->tv_sec == (time_t) -1 &&
             tv->tv_usec == (suseconds_t) -1)
-                return (usec_t) -1;
+                return USEC_INFINITY;
 
         if ((usec_t) tv->tv_sec > (UINT64_MAX - tv->tv_usec) / USEC_PER_SEC)
-                return (usec_t) -1;
+                return USEC_INFINITY;
 
         return
                 (usec_t) tv->tv_sec * USEC_PER_SEC +
@@ -139,7 +141,7 @@ usec_t timeval_load(const struct timeval *tv) {
 struct timeval *timeval_store(struct timeval *tv, usec_t u) {
         assert(tv);
 
-        if (u == (usec_t) -1) {
+        if (u == USEC_INFINITY) {
                 tv->tv_sec = (time_t) -1;
                 tv->tv_usec = (suseconds_t) -1;
         } else {
@@ -157,7 +159,7 @@ char *format_timestamp(char *buf, size_t l, usec_t t) {
         assert(buf);
         assert(l > 0);
 
-        if (t <= 0 || t == (usec_t) -1)
+        if (t <= 0 || t == USEC_INFINITY)
                 return NULL;
 
         sec = (time_t) (t / USEC_PER_SEC);
@@ -175,7 +177,7 @@ char *format_timestamp_us(char *buf, size_t l, usec_t t) {
         assert(buf);
         assert(l > 0);
 
-        if (t <= 0 || t == (usec_t) -1)
+        if (t <= 0 || t == USEC_INFINITY)
                 return NULL;
 
         sec = (time_t) (t / USEC_PER_SEC);
@@ -183,7 +185,7 @@ char *format_timestamp_us(char *buf, size_t l, usec_t t) {
 
         if (strftime(buf, l, "%a %Y-%m-%d %H:%M:%S", &tm) <= 0)
                 return NULL;
-        snprintf(buf + strlen(buf), l - strlen(buf), ".%06llu", t % USEC_PER_SEC);
+        snprintf(buf + strlen(buf), l - strlen(buf), ".%06llu", (unsigned long long) (t % USEC_PER_SEC));
         if (strftime(buf + strlen(buf), l - strlen(buf), " %Z", &tm) <= 0)
                 return NULL;
 
@@ -196,7 +198,7 @@ char *format_timestamp_relative(char *buf, size_t l, usec_t t) {
 
         n = now(CLOCK_REALTIME);
 
-        if (t <= 0 || (t == (usec_t) -1))
+        if (t <= 0 || (t == USEC_INFINITY))
                 return NULL;
 
         if (n > t) {
@@ -208,45 +210,45 @@ char *format_timestamp_relative(char *buf, size_t l, usec_t t) {
         }
 
         if (d >= USEC_PER_YEAR)
-                snprintf(buf, l, "%llu years %llu months %s",
-                         (unsigned long long) (d / USEC_PER_YEAR),
-                         (unsigned long long) ((d % USEC_PER_YEAR) / USEC_PER_MONTH), s);
+                snprintf(buf, l, USEC_FMT " years " USEC_FMT " months %s",
+                         d / USEC_PER_YEAR,
+                         (d % USEC_PER_YEAR) / USEC_PER_MONTH, s);
         else if (d >= USEC_PER_MONTH)
-                snprintf(buf, l, "%llu months %llu days %s",
-                         (unsigned long long) (d / USEC_PER_MONTH),
-                         (unsigned long long) ((d % USEC_PER_MONTH) / USEC_PER_DAY), s);
+                snprintf(buf, l, USEC_FMT " months " USEC_FMT " days %s",
+                         d / USEC_PER_MONTH,
+                         (d % USEC_PER_MONTH) / USEC_PER_DAY, s);
         else if (d >= USEC_PER_WEEK)
-                snprintf(buf, l, "%llu weeks %llu days %s",
-                         (unsigned long long) (d / USEC_PER_WEEK),
-                         (unsigned long long) ((d % USEC_PER_WEEK) / USEC_PER_DAY), s);
+                snprintf(buf, l, USEC_FMT " weeks " USEC_FMT " days %s",
+                         d / USEC_PER_WEEK,
+                         (d % USEC_PER_WEEK) / USEC_PER_DAY, s);
         else if (d >= 2*USEC_PER_DAY)
-                snprintf(buf, l, "%llu days %s", (unsigned long long) (d / USEC_PER_DAY), s);
+                snprintf(buf, l, USEC_FMT " days %s", d / USEC_PER_DAY, s);
         else if (d >= 25*USEC_PER_HOUR)
-                snprintf(buf, l, "1 day %lluh %s",
-                         (unsigned long long) ((d - USEC_PER_DAY) / USEC_PER_HOUR), s);
+                snprintf(buf, l, "1 day " USEC_FMT "h %s",
+                         (d - USEC_PER_DAY) / USEC_PER_HOUR, s);
         else if (d >= 6*USEC_PER_HOUR)
-                snprintf(buf, l, "%lluh %s",
-                         (unsigned long long) (d / USEC_PER_HOUR), s);
+                snprintf(buf, l, USEC_FMT "h %s",
+                         d / USEC_PER_HOUR, s);
         else if (d >= USEC_PER_HOUR)
-                snprintf(buf, l, "%lluh %llumin %s",
-                         (unsigned long long) (d / USEC_PER_HOUR),
-                         (unsigned long long) ((d % USEC_PER_HOUR) / USEC_PER_MINUTE), s);
+                snprintf(buf, l, USEC_FMT "h " USEC_FMT "min %s",
+                         d / USEC_PER_HOUR,
+                         (d % USEC_PER_HOUR) / USEC_PER_MINUTE, s);
         else if (d >= 5*USEC_PER_MINUTE)
-                snprintf(buf, l, "%llumin %s",
-                         (unsigned long long) (d / USEC_PER_MINUTE), s);
+                snprintf(buf, l, USEC_FMT "min %s",
+                         d / USEC_PER_MINUTE, s);
         else if (d >= USEC_PER_MINUTE)
-                snprintf(buf, l, "%llumin %llus %s",
-                         (unsigned long long) (d / USEC_PER_MINUTE),
-                         (unsigned long long) ((d % USEC_PER_MINUTE) / USEC_PER_SEC), s);
+                snprintf(buf, l, USEC_FMT "min " USEC_FMT "s %s",
+                         d / USEC_PER_MINUTE,
+                         (d % USEC_PER_MINUTE) / USEC_PER_SEC, s);
         else if (d >= USEC_PER_SEC)
-                snprintf(buf, l, "%llus %s",
-                         (unsigned long long) (d / USEC_PER_SEC), s);
+                snprintf(buf, l, USEC_FMT "s %s",
+                         d / USEC_PER_SEC, s);
         else if (d >= USEC_PER_MSEC)
-                snprintf(buf, l, "%llums %s",
-                         (unsigned long long) (d / USEC_PER_MSEC), s);
+                snprintf(buf, l, USEC_FMT "ms %s",
+                         d / USEC_PER_MSEC, s);
         else if (d > 0)
-                snprintf(buf, l, "%lluus %s",
-                         (unsigned long long) d, s);
+                snprintf(buf, l, USEC_FMT"us %s",
+                         d, s);
         else
                 snprintf(buf, l, "now");
 
@@ -277,7 +279,7 @@ char *format_timespan(char *buf, size_t l, usec_t t, usec_t accuracy) {
         assert(buf);
         assert(l > 0);
 
-        if (t == (usec_t) -1)
+        if (t == USEC_INFINITY)
                 return NULL;
 
         if (t <= 0) {
@@ -325,9 +327,9 @@ char *format_timespan(char *buf, size_t l, usec_t t, usec_t accuracy) {
 
                         if (j > 0) {
                                 k = snprintf(p, l,
-                                             "%s%llu.%0*llu%s",
+                                             "%s"USEC_FMT".%0*llu%s",
                                              p > buf ? " " : "",
-                                             (unsigned long long) a,
+                                             a,
                                              j,
                                              (unsigned long long) b,
                                              table[i].suffix);
@@ -340,9 +342,9 @@ char *format_timespan(char *buf, size_t l, usec_t t, usec_t accuracy) {
                 /* No? Then let's show it normally */
                 if (!done) {
                         k = snprintf(p, l,
-                                     "%s%llu%s",
+                                     "%s"USEC_FMT"%s",
                                      p > buf ? " " : "",
-                                     (unsigned long long) a,
+                                     a,
                                      table[i].suffix);
 
                         t = b;
@@ -370,10 +372,10 @@ void dual_timestamp_serialize(FILE *f, const char *name, dual_timestamp *t) {
         if (!dual_timestamp_is_set(t))
                 return;
 
-        fprintf(f, "%s=%llu %llu\n",
+        fprintf(f, "%s="USEC_FMT" "USEC_FMT"\n",
                 name,
-                (unsigned long long) t->realtime,
-                (unsigned long long) t->monotonic);
+                t->realtime,
+                t->monotonic);
 }
 
 void dual_timestamp_deserialize(const char *value, dual_timestamp *t) {
@@ -432,6 +434,7 @@ int parse_timestamp(const char *t, usec_t *usec) {
          *   tomorrow             (time is set to 00:00:00)
          *   +5min
          *   -5days
+         *   @2147483647          (seconds since epoch)
          *
          */
 
@@ -460,21 +463,23 @@ int parse_timestamp(const char *t, usec_t *usec) {
                 goto finish;
 
         } else if (t[0] == '+') {
-
                 r = parse_sec(t+1, &plus);
                 if (r < 0)
                         return r;
 
                 goto finish;
-        } else if (t[0] == '-') {
 
+        } else if (t[0] == '-') {
                 r = parse_sec(t+1, &minus);
                 if (r < 0)
                         return r;
 
                 goto finish;
 
-        } else if (endswith(t, " ago")) {
+        } else if (t[0] == '@')
+                return parse_sec(t + 1, usec);
+
+        else if (endswith(t, " ago")) {
                 _cleanup_free_ char *z;
 
                 z = strndup(t, strlen(t) - 4);
@@ -823,3 +828,123 @@ bool ntp_synced(void) {
 
         return true;
 }
+
+int get_timezones(char ***ret) {
+        _cleanup_fclose_ FILE *f = NULL;
+        _cleanup_strv_free_ char **zones = NULL;
+        size_t n_zones = 0, n_allocated = 0;
+
+        assert(ret);
+
+        zones = strv_new("UTC", NULL);
+        if (!zones)
+                return -ENOMEM;
+
+        n_allocated = 2;
+        n_zones = 1;
+
+        f = fopen("/usr/share/zoneinfo/zone.tab", "re");
+        if (f) {
+                char l[LINE_MAX];
+
+                FOREACH_LINE(l, f, return -errno) {
+                        char *p, *w;
+                        size_t k;
+
+                        p = strstrip(l);
+
+                        if (isempty(p) || *p == '#')
+                                continue;
+
+                        /* Skip over country code */
+                        p += strcspn(p, WHITESPACE);
+                        p += strspn(p, WHITESPACE);
+
+                        /* Skip over coordinates */
+                        p += strcspn(p, WHITESPACE);
+                        p += strspn(p, WHITESPACE);
+
+                        /* Found timezone name */
+                        k = strcspn(p, WHITESPACE);
+                        if (k <= 0)
+                                continue;
+
+                        w = strndup(p, k);
+                        if (!w)
+                                return -ENOMEM;
+
+                        if (!GREEDY_REALLOC(zones, n_allocated, n_zones + 2)) {
+                                free(w);
+                                return -ENOMEM;
+                        }
+
+                        zones[n_zones++] = w;
+                        zones[n_zones] = NULL;
+                }
+
+                strv_sort(zones);
+
+        } else if (errno != ENOENT)
+                return -errno;
+
+        *ret = zones;
+        zones = NULL;
+
+        return 0;
+}
+
+bool timezone_is_valid(const char *name) {
+        bool slash = false;
+        const char *p, *t;
+        struct stat st;
+
+        if (!name || *name == 0 || *name == '/')
+                return false;
+
+        for (p = name; *p; p++) {
+                if (!(*p >= '0' && *p <= '9') &&
+                    !(*p >= 'a' && *p <= 'z') &&
+                    !(*p >= 'A' && *p <= 'Z') &&
+                    !(*p == '-' || *p == '_' || *p == '+' || *p == '/'))
+                        return false;
+
+                if (*p == '/') {
+
+                        if (slash)
+                                return false;
+
+                        slash = true;
+                } else
+                        slash = false;
+        }
+
+        if (slash)
+                return false;
+
+        t = strappenda("/usr/share/zoneinfo/", name);
+        if (stat(t, &st) < 0)
+                return false;
+
+        if (!S_ISREG(st.st_mode))
+                return false;
+
+        return true;
+}
+
+clockid_t clock_boottime_or_monotonic(void) {
+        static clockid_t clock = -1;
+        int fd;
+
+        if (clock != -1)
+                return clock;
+
+        fd = timerfd_create(CLOCK_BOOTTIME, TFD_NONBLOCK|TFD_CLOEXEC);
+        if (fd < 0)
+                clock = CLOCK_MONOTONIC;
+        else {
+                safe_close(fd);
+                clock = CLOCK_BOOTTIME;
+        }
+
+        return clock;
+}
index 96f2ec8..8ba1cfe 100644 (file)
@@ -37,27 +37,31 @@ typedef struct dual_timestamp {
         usec_t monotonic;
 } dual_timestamp;
 
+#define USEC_INFINITY ((usec_t) -1)
+#define NSEC_INFINITY ((nsec_t) -1)
+
 #define MSEC_PER_SEC  1000ULL
-#define USEC_PER_SEC  1000000ULL
-#define USEC_PER_MSEC 1000ULL
-#define NSEC_PER_SEC  1000000000ULL
-#define NSEC_PER_MSEC 1000000ULL
-#define NSEC_PER_USEC 1000ULL
-
-#define USEC_PER_MINUTE (60ULL*USEC_PER_SEC)
-#define NSEC_PER_MINUTE (60ULL*NSEC_PER_SEC)
-#define USEC_PER_HOUR (60ULL*USEC_PER_MINUTE)
-#define NSEC_PER_HOUR (60ULL*NSEC_PER_MINUTE)
-#define USEC_PER_DAY (24ULL*USEC_PER_HOUR)
-#define NSEC_PER_DAY (24ULL*NSEC_PER_HOUR)
-#define USEC_PER_WEEK (7ULL*USEC_PER_DAY)
-#define NSEC_PER_WEEK (7ULL*NSEC_PER_DAY)
-#define USEC_PER_MONTH (2629800ULL*USEC_PER_SEC)
-#define NSEC_PER_MONTH (2629800ULL*NSEC_PER_SEC)
-#define USEC_PER_YEAR (31557600ULL*USEC_PER_SEC)
-#define NSEC_PER_YEAR (31557600ULL*NSEC_PER_SEC)
+#define USEC_PER_SEC  ((usec_t) 1000000ULL)
+#define USEC_PER_MSEC ((usec_t) 1000ULL)
+#define NSEC_PER_SEC  ((nsec_t) 1000000000ULL)
+#define NSEC_PER_MSEC ((nsec_t) 1000000ULL)
+#define NSEC_PER_USEC ((nsec_t) 1000ULL)
+
+#define USEC_PER_MINUTE ((usec_t) (60ULL*USEC_PER_SEC))
+#define NSEC_PER_MINUTE ((nsec_t) (60ULL*NSEC_PER_SEC))
+#define USEC_PER_HOUR ((usec_t) (60ULL*USEC_PER_MINUTE))
+#define NSEC_PER_HOUR ((nsec_t) (60ULL*NSEC_PER_MINUTE))
+#define USEC_PER_DAY ((usec_t) (24ULL*USEC_PER_HOUR))
+#define NSEC_PER_DAY ((nsec_t) (24ULL*NSEC_PER_HOUR))
+#define USEC_PER_WEEK ((usec_t) (7ULL*USEC_PER_DAY))
+#define NSEC_PER_WEEK ((nsec_t) (7ULL*NSEC_PER_DAY))
+#define USEC_PER_MONTH ((usec_t) (2629800ULL*USEC_PER_SEC))
+#define NSEC_PER_MONTH ((nsec_t) (2629800ULL*NSEC_PER_SEC))
+#define USEC_PER_YEAR ((usec_t) (31557600ULL*USEC_PER_SEC))
+#define NSEC_PER_YEAR ((nsec_t) (31557600ULL*NSEC_PER_SEC))
 
 #define FORMAT_TIMESTAMP_MAX ((4*4+1)+11+9+4+1) /* weekdays can be unicode */
+#define FORMAT_TIMESTAMP_WIDTH 28 /* when outputting, assume this width */
 #define FORMAT_TIMESTAMP_RELATIVE_MAX 256
 #define FORMAT_TIMESPAN_MAX 64
 
@@ -70,8 +74,8 @@ dual_timestamp* dual_timestamp_from_realtime(dual_timestamp *ts, usec_t u);
 dual_timestamp* dual_timestamp_from_monotonic(dual_timestamp *ts, usec_t u);
 
 static inline bool dual_timestamp_is_set(dual_timestamp *ts) {
-        return ((ts->realtime > 0 && ts->realtime != (usec_t) -1) ||
-                (ts->monotonic > 0 && ts->monotonic != (usec_t) -1));
+        return ((ts->realtime > 0 && ts->realtime != USEC_INFINITY) ||
+                (ts->monotonic > 0 && ts->monotonic != USEC_INFINITY));
 }
 
 usec_t timespec_load(const struct timespec *ts) _pure_;
@@ -94,3 +98,8 @@ int parse_sec(const char *t, usec_t *usec);
 int parse_nsec(const char *t, nsec_t *nsec);
 
 bool ntp_synced(void);
+
+int get_timezones(char ***l);
+bool timezone_is_valid(const char *name);
+
+clockid_t clock_boottime_or_monotonic(void);
index 40f8b77..5f09ce1 100644 (file)
@@ -31,7 +31,6 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_event*, udev_event_unref);
 DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_rules*, udev_rules_unref);
 DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_ctrl*, udev_ctrl_unref);
 DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_monitor*, udev_monitor_unref);
-DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_queue*, udev_queue_unref);
 
 #define _cleanup_udev_unref_ _cleanup_(udev_unrefp)
 #define _cleanup_udev_device_unref_ _cleanup_(udev_device_unrefp)
@@ -40,5 +39,4 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_queue*, udev_queue_unref);
 #define _cleanup_udev_rules_unref_ _cleanup_(udev_rules_unrefp)
 #define _cleanup_udev_ctrl_unref_ _cleanup_(udev_ctrl_unrefp)
 #define _cleanup_udev_monitor_unref_ _cleanup_(udev_monitor_unrefp)
-#define _cleanup_udev_queue_unref_ _cleanup_(udev_queue_unrefp)
 #define _cleanup_udev_list_cleanup_ _cleanup_(udev_list_cleanup)
diff --git a/src/shared/uid-range.c b/src/shared/uid-range.c
new file mode 100644 (file)
index 0000000..74c3be4
--- /dev/null
@@ -0,0 +1,205 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "util.h"
+#include "uid-range.h"
+
+static bool uid_range_intersect(UidRange *range, uid_t start, uid_t nr) {
+        assert(range);
+
+        return range->start <= start + nr &&
+                range->start + range->nr >= start;
+}
+
+static void uid_range_coalesce(UidRange **p, unsigned *n) {
+        unsigned i, j;
+
+        assert(p);
+        assert(n);
+
+        for (i = 0; i < *n; i++) {
+                for (j = i + 1; j < *n; j++) {
+                        UidRange *x = (*p)+i, *y = (*p)+j;
+
+                        if (uid_range_intersect(x, y->start, y->nr)) {
+                                uid_t begin, end;
+
+                                begin = MIN(x->start, y->start);
+                                end = MAX(x->start + x->nr, y->start + y->nr);
+
+                                x->start = begin;
+                                x->nr = end - begin;
+
+                                if (*n > j+1)
+                                        memmove(y, y+1, sizeof(UidRange) * (*n - j -1));
+
+                                (*n) --;
+                                j--;
+                        }
+                }
+        }
+
+}
+
+static int uid_range_compare(const void *a, const void *b) {
+        const UidRange *x = a, *y = b;
+
+        if (x->start < y->start)
+                return -1;
+        if (x->start > y->start)
+                return 1;
+
+        if (x->nr < y->nr)
+                return -1;
+        if (x->nr > y->nr)
+                return 1;
+
+        return 0;
+}
+
+int uid_range_add(UidRange **p, unsigned *n, uid_t start, uid_t nr) {
+        bool found = false;
+        UidRange *x;
+        unsigned i;
+
+        assert(p);
+        assert(n);
+
+        if (nr <= 0)
+                return 0;
+
+        for (i = 0; i < *n; i++) {
+                x = (*p) + i;
+                if (uid_range_intersect(x, start, nr)) {
+                        found = true;
+                        break;
+                }
+        }
+
+        if (found) {
+                uid_t begin, end;
+
+                begin = MIN(x->start, start);
+                end = MAX(x->start + x->nr, start + nr);
+
+                x->start = begin;
+                x->nr = end - begin;
+        } else {
+                UidRange *t;
+
+                t = realloc(*p, sizeof(UidRange) * (*n + 1));
+                if (!t)
+                        return -ENOMEM;
+
+                *p = t;
+                x = t + ((*n) ++);
+
+                x->start = start;
+                x->nr = nr;
+        }
+
+        qsort(*p, *n, sizeof(UidRange), uid_range_compare);
+        uid_range_coalesce(p, n);
+
+        return *n;
+}
+
+int uid_range_add_str(UidRange **p, unsigned *n, const char *s) {
+        uid_t start, nr;
+        const char *t;
+        int r;
+
+        assert(p);
+        assert(n);
+        assert(s);
+
+        t = strchr(s, '-');
+        if (t) {
+                char *b;
+                uid_t end;
+
+                b = strndupa(s, t - s);
+                r = parse_uid(b, &start);
+                if (r < 0)
+                        return r;
+
+                r = parse_uid(t+1, &end);
+                if (r < 0)
+                        return r;
+
+                if (end < start)
+                        return -EINVAL;
+
+                nr = end - start + 1;
+        } else {
+                r = parse_uid(s, &start);
+                if (r < 0)
+                        return r;
+
+                nr = 1;
+        }
+
+        return uid_range_add(p, n, start, nr);
+}
+
+int uid_range_next_lower(const UidRange *p, unsigned n, uid_t *uid) {
+        uid_t closest = (uid_t) -1, candidate;
+        unsigned i;
+
+        assert(p);
+        assert(uid);
+
+        candidate = *uid - 1;
+
+        for (i = 0; i < n; i++) {
+                uid_t begin, end;
+
+                begin = p[i].start;
+                end = p[i].start + p[i].nr - 1;
+
+                if (candidate >= begin && candidate <= end) {
+                        *uid = candidate;
+                        return 1;
+                }
+
+                if (end < candidate)
+                        closest = end;
+        }
+
+        if (closest == (uid_t) -1)
+                return -EBUSY;
+
+        *uid = closest;
+        return 1;
+}
+
+bool uid_range_contains(const UidRange *p, unsigned n, uid_t uid) {
+        unsigned i;
+
+        assert(p);
+        assert(uid);
+
+        for (i = 0; i < n; i++)
+                if (uid >= p[i].start && uid < p[i].start + p[i].nr)
+                        return true;
+
+        return false;
+}
diff --git a/src/shared/uid-range.h b/src/shared/uid-range.h
new file mode 100644 (file)
index 0000000..d3dac8d
--- /dev/null
@@ -0,0 +1,34 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/types.h>
+
+typedef struct UidRange {
+        uid_t start, nr;
+} UidRange;
+
+int uid_range_add(UidRange **p, unsigned *n, uid_t start, uid_t nr);
+int uid_range_add_str(UidRange **p, unsigned *n, const char *s);
+
+int uid_range_next_lower(const UidRange *p, unsigned n, uid_t *uid);
+bool uid_range_contains(const UidRange *p, unsigned n, uid_t uid);
index 2924c47..a2d62d3 100644 (file)
@@ -28,6 +28,7 @@
 #include "util.h"
 #include "unit-name.h"
 #include "def.h"
+#include "strv.h"
 
 #define VALID_CHARS                             \
         DIGITS LETTERS                          \
@@ -71,9 +72,11 @@ bool unit_name_is_valid(const char *n, enum template_valid template_ok) {
          *         string.suffix
          */
 
-        assert(n);
         assert(IN_SET(template_ok, TEMPLATE_VALID, TEMPLATE_INVALID));
 
+        if (isempty(n))
+                return false;
+
         if (strlen(n) >= UNIT_NAME_MAX)
                 return false;
 
@@ -105,36 +108,27 @@ bool unit_name_is_valid(const char *n, enum template_valid template_ok) {
 }
 
 bool unit_instance_is_valid(const char *i) {
-        assert(i);
 
         /* The max length depends on the length of the string, so we
          * don't really check this here. */
 
-        if (i[0] == 0)
+        if (isempty(i))
                 return false;
 
         /* We allow additional @ in the instance string, we do not
          * allow them in the prefix! */
 
-        for (; *i; i++)
-                if (!strchr("@" VALID_CHARS, *i))
-                        return false;
-
-        return true;
+        return in_charset(i, "@" VALID_CHARS);
 }
 
 bool unit_prefix_is_valid(const char *p) {
 
         /* We don't allow additional @ in the instance string */
 
-        if (p[0] == 0)
+        if (isempty(p))
                 return false;
 
-        for (; *p; p++)
-                if (!strchr(VALID_CHARS, *p))
-                        return false;
-
-        return true;
+        return in_charset(p, VALID_CHARS);
 }
 
 int unit_name_to_instance(const char *n, char **instance) {
@@ -151,15 +145,18 @@ int unit_name_to_instance(const char *n, char **instance) {
                 return 0;
         }
 
-        assert_se(d = strrchr(n, '.'));
-        assert(p < d);
+        d = strrchr(n, '.');
+        if (!d)
+                return -EINVAL;
+        if (d < p)
+                return -EINVAL;
 
         i = strndup(p+1, d-p-1);
         if (!i)
                 return -ENOMEM;
 
         *instance = i;
-        return 0;
+        return 1;
 }
 
 char *unit_name_to_prefix_and_instance(const char *n) {
@@ -168,13 +165,14 @@ char *unit_name_to_prefix_and_instance(const char *n) {
         assert(n);
 
         assert_se(d = strrchr(n, '.'));
-
         return strndup(n, d - n);
 }
 
 char *unit_name_to_prefix(const char *n) {
         const char *p;
 
+        assert(n);
+
         p = strchr(n, '@');
         if (p)
                 return strndup(n, p - n);
@@ -187,7 +185,6 @@ char *unit_name_change_suffix(const char *n, const char *suffix) {
         size_t a, b;
 
         assert(n);
-        assert(unit_name_is_valid(n, TEMPLATE_VALID));
         assert(suffix);
         assert(suffix[0] == '.');
 
@@ -199,16 +196,12 @@ char *unit_name_change_suffix(const char *n, const char *suffix) {
         if (!r)
                 return NULL;
 
-        memcpy(r, n, a);
-        memcpy(r+a, suffix, b+1);
-
+        strcpy(mempcpy(r, n, a), suffix);
         return r;
 }
 
 char *unit_name_build(const char *prefix, const char *instance, const char *suffix) {
         assert(prefix);
-        assert(unit_prefix_is_valid(prefix));
-        assert(!instance || unit_instance_is_valid(instance));
         assert(suffix);
 
         if (!instance)
@@ -218,10 +211,13 @@ char *unit_name_build(const char *prefix, const char *instance, const char *suff
 }
 
 static char *do_escape_char(char c, char *t) {
+        assert(t);
+
         *(t++) = '\\';
         *(t++) = 'x';
         *(t++) = hexchar(c >> 4);
         *(t++) = hexchar(c);
+
         return t;
 }
 
@@ -250,6 +246,8 @@ static char *do_escape(const char *f, char *t) {
 char *unit_name_escape(const char *f) {
         char *r, *t;
 
+        assert(f);
+
         r = new(char, strlen(f)*4+1);
         if (!r)
                 return NULL;
@@ -294,7 +292,7 @@ char *unit_name_unescape(const char *f) {
 }
 
 char *unit_name_path_escape(const char *f) {
-        char *p, *e;
+        _cleanup_free_ char *p = NULL;
 
         assert(f);
 
@@ -304,19 +302,14 @@ char *unit_name_path_escape(const char *f) {
 
         path_kill_slashes(p);
 
-        if (streq(p, "/") || streq(p, "")) {
-                free(p);
+        if (STR_IN_SET(p, "/", ""))
                 return strdup("-");
-        }
-
-        e = unit_name_escape(p[0] == '/' ? p + 1 : p);
-        free(p);
 
-        return e;
+        return unit_name_escape(p[0] == '/' ? p + 1 : p);
 }
 
 char *unit_name_path_unescape(const char *f) {
-        char *e;
+        char *e, *w;
 
         assert(f);
 
@@ -325,11 +318,8 @@ char *unit_name_path_unescape(const char *f) {
                 return NULL;
 
         if (e[0] != '/') {
-                char *w;
-
                 w = strappend("/", e);
                 free(e);
-
                 return w;
         }
 
@@ -337,7 +327,7 @@ char *unit_name_path_unescape(const char *f) {
 }
 
 bool unit_name_is_template(const char *n) {
-        const char *p;
+        const char *p, *e;
 
         assert(n);
 
@@ -345,11 +335,15 @@ bool unit_name_is_template(const char *n) {
         if (!p)
                 return false;
 
-        return p[1] == '.';
+        e = strrchr(p+1, '.');
+        if (!e)
+                return false;
+
+        return e == p + 1;
 }
 
 bool unit_name_is_instance(const char *n) {
-        const char *p;
+        const char *p, *e;
 
         assert(n);
 
@@ -357,15 +351,20 @@ bool unit_name_is_instance(const char *n) {
         if (!p)
                 return false;
 
-        return p[1] != '.';
+        e = strrchr(p+1, '.');
+        if (!e)
+                return false;
+
+        return e > p + 1;
 }
 
 char *unit_name_replace_instance(const char *f, const char *i) {
         const char *p, *e;
-        char *r, *k;
+        char *r;
         size_t a, b;
 
         assert(f);
+        assert(i);
 
         p = strchr(f, '@');
         if (!p)
@@ -373,7 +372,7 @@ char *unit_name_replace_instance(const char *f, const char *i) {
 
         e = strrchr(f, '.');
         if (!e)
-                assert_se(e = strchr(f, 0));
+                e = strchr(f, 0);
 
         a = p - f;
         b = strlen(i);
@@ -382,10 +381,7 @@ char *unit_name_replace_instance(const char *f, const char *i) {
         if (!r)
                 return NULL;
 
-        k = mempcpy(r, f, a + 1);
-        k = mempcpy(k, i, b);
-        strcpy(k, e);
-
+        strcpy(mempcpy(mempcpy(r, f, a + 1), i, b), e);
         return r;
 }
 
@@ -394,23 +390,28 @@ char *unit_name_template(const char *f) {
         char *r;
         size_t a;
 
+        assert(f);
+
         p = strchr(f, '@');
         if (!p)
                 return strdup(f);
 
-        assert_se(e = strrchr(f, '.'));
-        a = p - f + 1;
+        e = strrchr(f, '.');
+        if (!e)
+                e = strchr(f, 0);
 
-        r = new(char, a + strlen(e) + 1);
+        a = p - f;
+
+        r = new(char, a + 1 + strlen(e) + 1);
         if (!r)
                 return NULL;
 
-        strcpy(mempcpy(r, f, a), e);
+        strcpy(mempcpy(r, f, a + 1), e);
         return r;
 }
 
 char *unit_name_from_path(const char *path, const char *suffix) {
-        char *p, *r;
+        _cleanup_free_ char *p = NULL;
 
         assert(path);
         assert(suffix);
@@ -419,14 +420,11 @@ char *unit_name_from_path(const char *path, const char *suffix) {
         if (!p)
                 return NULL;
 
-        r = strappend(p, suffix);
-        free(p);
-
-        return r;
+        return strappend(p, suffix);
 }
 
 char *unit_name_from_path_instance(const char *prefix, const char *path, const char *suffix) {
-        char *p, *r;
+        _cleanup_free_ char *p = NULL;
 
         assert(prefix);
         assert(path);
@@ -436,10 +434,7 @@ char *unit_name_from_path_instance(const char *prefix, const char *path, const c
         if (!p)
                 return NULL;
 
-        r = strjoin(prefix, "@", p, suffix, NULL);
-        free(p);
-
-        return r;
+        return strjoin(prefix, "@", p, suffix, NULL);
 }
 
 char *unit_name_to_path(const char *name) {
@@ -482,15 +477,13 @@ int unit_name_from_dbus_path(const char *path, char **name) {
         return 0;
 }
 
-
 /**
  *  Try to turn a string that might not be a unit name into a
  *  sensible unit name.
  */
 char *unit_name_mangle(const char *name, enum unit_name_mangle allow_globs) {
+        const char *valid_chars, *f;
         char *r, *t;
-        const char *f;
-        const char* valid_chars = allow_globs == MANGLE_GLOB ? "@" VALID_CHARS "[]!-*?" : "@" VALID_CHARS;
 
         assert(name);
         assert(IN_SET(allow_globs, MANGLE_GLOB, MANGLE_NOGLOB));
@@ -504,7 +497,9 @@ char *unit_name_mangle(const char *name, enum unit_name_mangle allow_globs) {
         /* We'll only escape the obvious characters here, to play
          * safe. */
 
-        r = new(char, strlen(name) * 4 + 1 + sizeof(".service")-1);
+        valid_chars = allow_globs == MANGLE_GLOB ? "@" VALID_CHARS "[]!-*?" : "@" VALID_CHARS;
+
+        r = new(char, strlen(name) * 4 + strlen(".service") + 1);
         if (!r)
                 return NULL;
 
@@ -525,7 +520,6 @@ char *unit_name_mangle(const char *name, enum unit_name_mangle allow_globs) {
         return r;
 }
 
-
 /**
  *  Similar to unit_name_mangle(), but is called when we know
  *  that this is about a specific unit type.
@@ -535,6 +529,7 @@ char *unit_name_mangle_with_suffix(const char *name, enum unit_name_mangle allow
         const char *f;
 
         assert(name);
+        assert(IN_SET(allow_globs, MANGLE_GLOB, MANGLE_NOGLOB));
         assert(suffix);
         assert(suffix[0] == '.');
 
index 0b524d8..9353559 100644 (file)
@@ -80,8 +80,11 @@ static bool is_unicode_control(uint32_t ch) {
 
 /* count of characters used to encode one unicode char */
 static int utf8_encoded_expected_len(const char *str) {
-        unsigned char c = (unsigned char)str[0];
+        unsigned char c;
 
+        assert(str);
+
+        c = (unsigned char) str[0];
         if (c < 0x80)
                 return 1;
         if ((c & 0xe0) == 0xc0)
@@ -94,16 +97,18 @@ static int utf8_encoded_expected_len(const char *str) {
                 return 5;
         if ((c & 0xfe) == 0xfc)
                 return 6;
+
         return 0;
 }
 
 /* decode one unicode char */
 int utf8_encoded_to_unichar(const char *str) {
-        int unichar;
-        int len;
-        int i;
+        int unichar, len, i;
+
+        assert(str);
 
         len = utf8_encoded_expected_len(str);
+
         switch (len) {
         case 1:
                 return (int)str[0];
@@ -123,12 +128,12 @@ int utf8_encoded_to_unichar(const char *str) {
                 unichar = (int)str[0] & 0x01;
                 break;
         default:
-                return -1;
+                return -EINVAL;
         }
 
         for (i = 1; i < len; i++) {
                 if (((int)str[i] & 0xc0) != 0x80)
-                        return -1;
+                        return -EINVAL;
                 unichar <<= 6;
                 unichar |= (int)str[i] & 0x3f;
         }
@@ -136,16 +141,21 @@ int utf8_encoded_to_unichar(const char *str) {
         return unichar;
 }
 
-bool utf8_is_printable(const char* str, size_t length) {
+bool utf8_is_printable_newline(const char* str, size_t length, bool newline) {
         const uint8_t *p;
 
         assert(str);
 
         for (p = (const uint8_t*) str; length;) {
-                int encoded_len = utf8_encoded_valid_unichar((const char *)p);
-                int val = utf8_encoded_to_unichar((const char*)p);
+                int encoded_len, val;
+
+                encoded_len = utf8_encoded_valid_unichar((const char *) p);
+                val = utf8_encoded_to_unichar((const char*) p);
 
-                if (encoded_len < 0 || val < 0 || is_unicode_control(val))
+                if (encoded_len < 0 ||
+                    val < 0 ||
+                    is_unicode_control(val) ||
+                    (!newline && val == '\n'))
                         return false;
 
                 length -= encoded_len;
@@ -164,7 +174,6 @@ const char *utf8_is_valid(const char *str) {
                 int len;
 
                 len = utf8_encoded_valid_unichar((const char *)p);
-
                 if (len < 0)
                         return NULL;
 
@@ -195,6 +204,7 @@ char *utf8_escape_invalid(const char *str) {
                         str += 1;
                 }
         }
+
         *s = '\0';
 
         return p;
@@ -250,6 +260,7 @@ char *utf16_to_utf8(const void *s, size_t length) {
 
 /* expected size used to encode one unicode char */
 static int utf8_unichar_to_encoded_len(int unichar) {
+
         if (unichar < 0x80)
                 return 1;
         if (unichar < 0x800)
@@ -260,18 +271,19 @@ static int utf8_unichar_to_encoded_len(int unichar) {
                 return 4;
         if (unichar < 0x4000000)
                 return 5;
+
         return 6;
 }
 
 /* validate one encoded unicode char and return its length */
 int utf8_encoded_valid_unichar(const char *str) {
-        int len;
-        int unichar;
-        int i;
+        int len, unichar, i;
+
+        assert(str);
 
         len = utf8_encoded_expected_len(str);
         if (len == 0)
-                return -1;
+                return -EINVAL;
 
         /* ascii is valid */
         if (len == 1)
@@ -280,17 +292,17 @@ int utf8_encoded_valid_unichar(const char *str) {
         /* check if expected encoded chars are available */
         for (i = 0; i < len; i++)
                 if ((str[i] & 0x80) != 0x80)
-                        return -1;
+                        return -EINVAL;
 
         unichar = utf8_encoded_to_unichar(str);
 
         /* check if encoded length matches encoded value */
         if (utf8_unichar_to_encoded_len(unichar) != len)
-                return -1;
+                return -EINVAL;
 
         /* check if value has valid range */
         if (!is_unicode_valid(unichar))
-                return -1;
+                return -EINVAL;
 
         return len;
 }
index c0eb73a..c087995 100644 (file)
@@ -31,7 +31,10 @@ const char *utf8_is_valid(const char *s) _pure_;
 char *ascii_is_valid(const char *s) _pure_;
 char *utf8_escape_invalid(const char *s);
 
-bool utf8_is_printable(const char* str, size_t length) _pure_;
+bool utf8_is_printable_newline(const char* str, size_t length, bool newline) _pure_;
+_pure_ static inline bool utf8_is_printable(const char* str, size_t length) {
+        return utf8_is_printable_newline(str, length, true);
+}
 
 char *utf16_to_utf8(const void *s, size_t length);
 
index 5cb598c..85a570a 100644 (file)
@@ -54,6 +54,7 @@
 #include <grp.h>
 #include <sys/mman.h>
 #include <sys/vfs.h>
+#include <sys/mount.h>
 #include <linux/magic.h>
 #include <limits.h>
 #include <langinfo.h>
@@ -73,6 +74,7 @@
 #include "log.h"
 #include "strv.h"
 #include "label.h"
+#include "mkdir.h"
 #include "path-util.h"
 #include "exit-status.h"
 #include "hashmap.h"
@@ -138,26 +140,38 @@ char* endswith(const char *s, const char *postfix) {
         return (char*) s + sl - pl;
 }
 
-bool first_word(const char *s, const char *word) {
+char* first_word(const char *s, const char *word) {
         size_t sl, wl;
+        const char *p;
 
         assert(s);
         assert(word);
 
+        /* Checks if the string starts with the specified word, either
+         * followed by NUL or by whitespace. Returns a pointer to the
+         * NUL or the first character after the whitespace. */
+
         sl = strlen(s);
         wl = strlen(word);
 
         if (sl < wl)
-                return false;
+                return NULL;
 
         if (wl == 0)
-                return true;
+                return (char*) s;
 
         if (memcmp(s, word, wl) != 0)
-                return false;
+                return NULL;
+
+        p = s + wl;
+        if (*p == 0)
+                return (char*) p;
 
-        return s[wl] == 0 ||
-                strchr(WHITESPACE, s[wl]);
+        if (!strchr(WHITESPACE, *p))
+                return NULL;
+
+        p += strspn(p, WHITESPACE);
+        return (char*) p;
 }
 
 int close_nointr(int fd) {
@@ -165,30 +179,45 @@ int close_nointr(int fd) {
 
         assert(fd >= 0);
         r = close(fd);
-
-        /* Just ignore EINTR; a retry loop is the wrong
-         * thing to do on Linux.
-         *
-         * http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html
-         * https://bugzilla.gnome.org/show_bug.cgi?id=682819
-         * http://utcc.utoronto.ca/~cks/space/blog/unix/CloseEINTR
-         * https://sites.google.com/site/michaelsafyan/software-engineering/checkforeintrwheninvokingclosethinkagain
-         */
-        if (_unlikely_(r < 0 && errno == EINTR))
-                return 0;
-        else if (r >= 0)
+        if (r >= 0)
                 return r;
+        else if (errno == EINTR)
+                /*
+                 * Just ignore EINTR; a retry loop is the wrong
+                 * thing to do on Linux.
+                 *
+                 * http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html
+                 * https://bugzilla.gnome.org/show_bug.cgi?id=682819
+                 * http://utcc.utoronto.ca/~cks/space/blog/unix/CloseEINTR
+                 * https://sites.google.com/site/michaelsafyan/software-engineering/checkforeintrwheninvokingclosethinkagain
+                 */
+                return 0;
         else
                 return -errno;
 }
 
-void close_nointr_nofail(int fd) {
-        PROTECT_ERRNO;
+int safe_close(int fd) {
+
+        /*
+         * Like close_nointr() but cannot fail. Guarantees errno is
+         * unchanged. Is a NOP with negative fds passed, and returns
+         * -1, so that it can be used in this syntax:
+         *
+         * fd = safe_close(fd);
+         */
+
+        if (fd >= 0) {
+                PROTECT_ERRNO;
 
-        /* like close_nointr() but cannot fail, and guarantees errno
-         * is unchanged */
+                /* The kernel might return pretty much any error code
+                 * via close(), but the fd will be closed anyway. The
+                 * only condition we want to check for here is whether
+                 * the fd was invalid at all... */
+
+                assert_se(close_nointr(fd) != -EBADF);
+        }
 
-        assert_se(close_nointr(fd) == 0);
+        return -1;
 }
 
 void close_many(const int fds[], unsigned n_fd) {
@@ -197,7 +226,7 @@ void close_many(const int fds[], unsigned n_fd) {
         assert(fds || n_fd <= 0);
 
         for (i = 0; i < n_fd; i++)
-                close_nointr_nofail(fds[i]);
+                safe_close(fds[i]);
 }
 
 int unlink_noerrno(const char *path) {
@@ -214,9 +243,9 @@ int unlink_noerrno(const char *path) {
 int parse_boolean(const char *v) {
         assert(v);
 
-        if (streq(v, "1") || v[0] == 'y' || v[0] == 'Y' || v[0] == 't' || v[0] == 'T' || strcaseeq(v, "on"))
+        if (streq(v, "1") || strcaseeq(v, "yes") || strcaseeq(v, "y") || strcaseeq(v, "true") || strcaseeq(v, "t") || strcaseeq(v, "on"))
                 return 1;
-        else if (streq(v, "0") || v[0] == 'n' || v[0] == 'N' || v[0] == 'f' || v[0] == 'F' || strcaseeq(v, "off"))
+        else if (streq(v, "0") || strcaseeq(v, "no") || strcaseeq(v, "n") || strcaseeq(v, "false") || strcaseeq(v, "f") || strcaseeq(v, "off"))
                 return 0;
 
         return -EINVAL;
@@ -263,6 +292,14 @@ int parse_uid(const char *s, uid_t* ret_uid) {
         if ((unsigned long) uid != ul)
                 return -ERANGE;
 
+        /* Some libc APIs use (uid_t) -1 as special placeholder */
+        if (uid == (uid_t) 0xFFFFFFFF)
+                return -ENXIO;
+
+        /* A long time ago UIDs where 16bit, hence explicitly avoid the 16bit -1 too */
+        if (uid == (uid_t) 0xFFFF)
+                return -ENXIO;
+
         *ret_uid = uid;
         return 0;
 }
@@ -307,6 +344,26 @@ int safe_atoi(const char *s, int *ret_i) {
         return 0;
 }
 
+int safe_atou8(const char *s, uint8_t *ret) {
+        char *x = NULL;
+        unsigned long l;
+
+        assert(s);
+        assert(ret);
+
+        errno = 0;
+        l = strtoul(s, &x, 0);
+
+        if (!x || x == s || *x || errno)
+                return errno > 0 ? -errno : -EINVAL;
+
+        if ((unsigned long) (uint8_t) l != l)
+                return -ERANGE;
+
+        *ret = (uint8_t) l;
+        return 0;
+}
+
 int safe_atollu(const char *s, long long unsigned *ret_llu) {
         char *x = NULL;
         unsigned long long l;
@@ -370,37 +427,50 @@ static size_t strcspn_escaped(const char *s, const char *reject) {
                 else if (s[n] == '\\')
                         escaped = true;
                 else if (strchr(reject, s[n]))
-                        return n;
+                        break;
         }
-        return n;
+        /* if s ends in \, return index of previous char */
+        return n - escaped;
 }
 
 /* Split a string into words. */
-char *split(const char *c, size_t *l, const char *separator, bool quoted, char **state) {
-        char *current;
+const char* split(const char **state, size_t *l, const char *separator, bool quoted) {
+        const char *current;
 
-        current = *state ? *state : (char*) c;
+        current = *state;
 
-        if (!*current || *c == 0)
+        if (!*current) {
+                assert(**state == '\0');
                 return NULL;
+        }
 
         current += strspn(current, separator);
-        if (!*current)
+        if (!*current) {
+                *state = current;
                 return NULL;
+        }
 
         if (quoted && strchr("\'\"", *current)) {
-                char quotechar = *(current++);
-                *l = strcspn_escaped(current, (char[]){quotechar, '\0'});
-                *state = current+*l+1;
+                char quotechars[2] = {*current, '\0'};
+
+                *l = strcspn_escaped(current + 1, quotechars);
+                if (current[*l + 1] == '\0' ||
+                    (current[*l + 2] && !strchr(separator, current[*l + 2]))) {
+                        /* right quote missing or garbage at the end*/
+                        *state = current;
+                        return NULL;
+                }
+                assert(current[*l + 1] == quotechars[0]);
+                *state = current++ + *l + 2;
         } else if (quoted) {
                 *l = strcspn_escaped(current, separator);
-                *state = current+*l;
+                *state = current + *l;
         } else {
                 *l = strcspn(current, separator);
-                *state = current+*l;
+                *state = current + *l;
         }
 
-        return (char*) current;
+        return current;
 }
 
 int get_parent_of_pid(pid_t pid, pid_t *_ppid) {
@@ -787,7 +857,7 @@ char *strappend(const char *s, const char *suffix) {
         return strnappend(s, suffix, suffix ? strlen(suffix) : 0);
 }
 
-int readlink_malloc(const char *p, char **ret) {
+int readlinkat_malloc(int fd, const char *p, char **ret) {
         size_t l = 100;
         int r;
 
@@ -802,7 +872,7 @@ int readlink_malloc(const char *p, char **ret) {
                 if (!c)
                         return -ENOMEM;
 
-                n = readlink(p, c, l-1);
+                n = readlinkat(fd, p, c, l-1);
                 if (n < 0) {
                         r = -errno;
                         free(c);
@@ -820,6 +890,10 @@ int readlink_malloc(const char *p, char **ret) {
         }
 }
 
+int readlink_malloc(const char *p, char **ret) {
+        return readlinkat_malloc(AT_FDCWD, p, ret);
+}
+
 int readlink_and_make_absolute(const char *p, char **r) {
         _cleanup_free_ char *target = NULL;
         char *k;
@@ -919,19 +993,6 @@ char *delete_chars(char *s, const char *bad) {
         return s;
 }
 
-bool in_charset(const char *s, const char* charset) {
-        const char *i;
-
-        assert(s);
-        assert(charset);
-
-        for (i = s; *i; i++)
-                if (!strchr(charset, *i))
-                        return false;
-
-        return true;
-}
-
 char *file_in_same_dir(const char *path, const char *filename) {
         char *e, *r;
         size_t k;
@@ -1022,7 +1083,7 @@ int unhexchar(char c) {
         if (c >= 'A' && c <= 'F')
                 return c - 'A' + 10;
 
-        return -1;
+        return -EINVAL;
 }
 
 char *hexmem(const void *p, size_t l) {
@@ -1077,7 +1138,7 @@ int unoctchar(char c) {
         if (c >= '0' && c <= '7')
                 return c - '0';
 
-        return -1;
+        return -EINVAL;
 }
 
 char decchar(int x) {
@@ -1089,7 +1150,7 @@ int undecchar(char c) {
         if (c >= '0' && c <= '9')
                 return c - '0';
 
-        return -1;
+        return -EINVAL;
 }
 
 char *cescape(const char *s) {
@@ -1181,7 +1242,7 @@ char *cunescape_length_with_prefix(const char *s, size_t length, const char *pre
 
         r = new(char, pl+length+1);
         if (!r)
-                return r;
+                return NULL;
 
         if (prefix)
                 memcpy(r, prefix, pl);
@@ -1240,7 +1301,7 @@ char *cunescape_length_with_prefix(const char *s, size_t length, const char *pre
                         a = unhexchar(f[1]);
                         b = unhexchar(f[2]);
 
-                        if (a < 0 || b < 0) {
+                        if (a < 0 || b < 0 || (a == 0 && b == 0)) {
                                 /* Invalid escape code, let's take it literal then */
                                 *(t++) = '\\';
                                 *(t++) = 'x';
@@ -1267,7 +1328,7 @@ char *cunescape_length_with_prefix(const char *s, size_t length, const char *pre
                         b = unoctchar(f[1]);
                         c = unoctchar(f[2]);
 
-                        if (a < 0 || b < 0 || c < 0) {
+                        if (a < 0 || b < 0 || c < 0 || (a == 0 && b == 0 && c == 0)) {
                                 /* Invalid escape code, let's take it literal then */
                                 *(t++) = '\\';
                                 *(t++) = f[0];
@@ -1361,6 +1422,7 @@ _pure_ static bool ignore_file_allow_backup(const char *filename) {
                 endswith(filename, ".rpmorig") ||
                 endswith(filename, ".dpkg-old") ||
                 endswith(filename, ".dpkg-new") ||
+                endswith(filename, ".dpkg-tmp") ||
                 endswith(filename, ".swp");
 }
 
@@ -1368,44 +1430,52 @@ bool ignore_file(const char *filename) {
         assert(filename);
 
         if (endswith(filename, "~"))
-                return false;
+                return true;
 
         return ignore_file_allow_backup(filename);
 }
 
 int fd_nonblock(int fd, bool nonblock) {
-        int flags;
+        int flags, nflags;
 
         assert(fd >= 0);
 
-        if ((flags = fcntl(fd, F_GETFL, 0)) < 0)
+        flags = fcntl(fd, F_GETFL, 0);
+        if (flags < 0)
                 return -errno;
 
         if (nonblock)
-                flags |= O_NONBLOCK;
+                nflags = flags | O_NONBLOCK;
         else
-                flags &= ~O_NONBLOCK;
+                nflags = flags & ~O_NONBLOCK;
+
+        if (nflags == flags)
+                return 0;
 
-        if (fcntl(fd, F_SETFL, flags) < 0)
+        if (fcntl(fd, F_SETFL, nflags) < 0)
                 return -errno;
 
         return 0;
 }
 
 int fd_cloexec(int fd, bool cloexec) {
-        int flags;
+        int flags, nflags;
 
         assert(fd >= 0);
 
-        if ((flags = fcntl(fd, F_GETFD, 0)) < 0)
+        flags = fcntl(fd, F_GETFD, 0);
+        if (flags < 0)
                 return -errno;
 
         if (cloexec)
-                flags |= FD_CLOEXEC;
+                nflags = flags | FD_CLOEXEC;
         else
-                flags &= ~FD_CLOEXEC;
+                nflags = flags & ~FD_CLOEXEC;
 
-        if (fcntl(fd, F_SETFD, flags) < 0)
+        if (nflags == flags)
+                return 0;
+
+        if (fcntl(fd, F_SETFD, nflags) < 0)
                 return -errno;
 
         return 0;
@@ -1424,7 +1494,7 @@ _pure_ static bool fd_in_set(int fd, const int fdset[], unsigned n_fdset) {
 }
 
 int close_all_fds(const int except[], unsigned n_except) {
-        DIR *d;
+        _cleanup_closedir_ DIR *d = NULL;
         struct dirent *de;
         int r = 0;
 
@@ -1479,7 +1549,6 @@ int close_all_fds(const int except[], unsigned n_except) {
                 }
         }
 
-        closedir(d);
         return r;
 }
 
@@ -1498,12 +1567,20 @@ bool fstype_is_network(const char *fstype) {
         static const char table[] =
                 "cifs\0"
                 "smbfs\0"
+                "sshfs\0"
                 "ncpfs\0"
                 "ncp\0"
                 "nfs\0"
                 "nfs4\0"
                 "gfs\0"
-                "gfs2\0";
+                "gfs2\0"
+                "glusterfs\0";
+
+        const char *x;
+
+        x = startswith(fstype, "fuse.");
+        if (x)
+                fstype = x;
 
         return nulstr_contains(table, fstype);
 }
@@ -1535,8 +1612,7 @@ int chvt(int vt) {
 
 int read_one_char(FILE *f, char *ret, usec_t t, bool *need_nl) {
         struct termios old_termios, new_termios;
-        char c;
-        char line[LINE_MAX];
+        char c, line[LINE_MAX];
 
         assert(f);
         assert(ret);
@@ -1551,7 +1627,7 @@ int read_one_char(FILE *f, char *ret, usec_t t, bool *need_nl) {
                 if (tcsetattr(fileno(f), TCSADRAIN, &new_termios) >= 0) {
                         size_t k;
 
-                        if (t != (usec_t) -1) {
+                        if (t != USEC_INFINITY) {
                                 if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0) {
                                         tcsetattr(fileno(f), TCSADRAIN, &old_termios);
                                         return -ETIMEDOUT;
@@ -1573,12 +1649,14 @@ int read_one_char(FILE *f, char *ret, usec_t t, bool *need_nl) {
                 }
         }
 
-        if (t != (usec_t) -1)
+        if (t != USEC_INFINITY) {
                 if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0)
                         return -ETIMEDOUT;
+        }
 
+        errno = 0;
         if (!fgets(line, sizeof(line), f))
-                return -EIO;
+                return errno ? -errno : -EIO;
 
         truncate_nl(line);
 
@@ -1592,7 +1670,8 @@ int read_one_char(FILE *f, char *ret, usec_t t, bool *need_nl) {
         return 0;
 }
 
-int ask(char *ret, const char *replies, const char *text, ...) {
+int ask_char(char *ret, const char *replies, const char *text, ...) {
+        int r;
 
         assert(ret);
         assert(replies);
@@ -1601,7 +1680,6 @@ int ask(char *ret, const char *replies, const char *text, ...) {
         for (;;) {
                 va_list ap;
                 char c;
-                int r;
                 bool need_nl = true;
 
                 if (on_tty())
@@ -1616,7 +1694,7 @@ int ask(char *ret, const char *replies, const char *text, ...) {
 
                 fflush(stdout);
 
-                r = read_one_char(stdin, &c, (usec_t) -1, &need_nl);
+                r = read_one_char(stdin, &c, USEC_INFINITY, &need_nl);
                 if (r < 0) {
 
                         if (r == -EBADMSG) {
@@ -1640,6 +1718,49 @@ int ask(char *ret, const char *replies, const char *text, ...) {
         }
 }
 
+int ask_string(char **ret, const char *text, ...) {
+        assert(ret);
+        assert(text);
+
+        for (;;) {
+                char line[LINE_MAX];
+                va_list ap;
+
+                if (on_tty())
+                        fputs(ANSI_HIGHLIGHT_ON, stdout);
+
+                va_start(ap, text);
+                vprintf(text, ap);
+                va_end(ap);
+
+                if (on_tty())
+                        fputs(ANSI_HIGHLIGHT_OFF, stdout);
+
+                fflush(stdout);
+
+                errno = 0;
+                if (!fgets(line, sizeof(line), stdin))
+                        return errno ? -errno : -EIO;
+
+                if (!endswith(line, "\n"))
+                        putchar('\n');
+                else {
+                        char *s;
+
+                        if (isempty(line))
+                                continue;
+
+                        truncate_nl(line);
+                        s = strdup(line);
+                        if (!s)
+                                return -ENOMEM;
+
+                        *ret = s;
+                        return 0;
+                }
+        }
+}
+
 int reset_terminal_fd(int fd, bool switch_to_text) {
         struct termios termios;
         int r = 0;
@@ -1705,16 +1826,13 @@ finish:
 }
 
 int reset_terminal(const char *name) {
-        int fd, r;
+        _cleanup_close_ int fd = -1;
 
         fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
         if (fd < 0)
                 return fd;
 
-        r = reset_terminal_fd(fd, true);
-        close_nointr_nofail(fd);
-
-        return r;
+        return reset_terminal_fd(fd, true);
 }
 
 int open_terminal(const char *name, int mode) {
@@ -1753,12 +1871,12 @@ int open_terminal(const char *name, int mode) {
 
         r = isatty(fd);
         if (r < 0) {
-                close_nointr_nofail(fd);
+                safe_close(fd);
                 return -errno;
         }
 
         if (!r) {
-                close_nointr_nofail(fd);
+                safe_close(fd);
                 return -ENOTTY;
         }
 
@@ -1826,11 +1944,11 @@ int acquire_terminal(
          * on the same tty as an untrusted user this should not be a
          * problem. (Which he probably should not do anyway.) */
 
-        if (timeout != (usec_t) -1)
+        if (timeout != USEC_INFINITY)
                 ts = now(CLOCK_MONOTONIC);
 
         if (!fail && !force) {
-                notify = inotify_init1(IN_CLOEXEC | (timeout != (usec_t) -1 ? IN_NONBLOCK : 0));
+                notify = inotify_init1(IN_CLOEXEC | (timeout != USEC_INFINITY ? IN_NONBLOCK : 0));
                 if (notify < 0) {
                         r = -errno;
                         goto fail;
@@ -1894,7 +2012,7 @@ int acquire_terminal(
                         ssize_t l;
                         struct inotify_event *e;
 
-                        if (timeout != (usec_t) -1) {
+                        if (timeout != USEC_INFINITY) {
                                 usec_t n;
 
                                 n = now(CLOCK_MONOTONIC);
@@ -1947,11 +2065,10 @@ int acquire_terminal(
                  * ended our handle will be dead. It's important that
                  * we do this after sleeping, so that we don't enter
                  * an endless loop. */
-                close_nointr_nofail(fd);
+                safe_close(fd);
         }
 
-        if (notify >= 0)
-                close_nointr_nofail(notify);
+        safe_close(notify);
 
         r = reset_terminal_fd(fd, true);
         if (r < 0)
@@ -1960,22 +2077,21 @@ int acquire_terminal(
         return fd;
 
 fail:
-        if (fd >= 0)
-                close_nointr_nofail(fd);
-
-        if (notify >= 0)
-                close_nointr_nofail(notify);
+        safe_close(fd);
+        safe_close(notify);
 
         return r;
 }
 
 int release_terminal(void) {
-        int r = 0;
-        struct sigaction sa_old, sa_new = {
+        static const struct sigaction sa_new = {
                 .sa_handler = SIG_IGN,
                 .sa_flags = SA_RESTART,
         };
-        _cleanup_close_ int fd;
+
+        _cleanup_close_ int fd = -1;
+        struct sigaction sa_old;
+        int r = 0;
 
         fd = open("/dev/tty", O_RDWR|O_NOCTTY|O_NDELAY|O_CLOEXEC);
         if (fd < 0)
@@ -2014,7 +2130,6 @@ int ignore_signals(int sig, ...) {
         va_list ap;
         int r = 0;
 
-
         if (sigaction(sig, &sa, NULL) < 0)
                 r = -errno;
 
@@ -2047,22 +2162,18 @@ int default_signals(int sig, ...) {
         return r;
 }
 
-int close_pipe(int p[]) {
-        int a = 0, b = 0;
-
+void safe_close_pair(int p[]) {
         assert(p);
 
-        if (p[0] >= 0) {
-                a = close_nointr(p[0]);
-                p[0] = -1;
-        }
-
-        if (p[1] >= 0) {
-                b = close_nointr(p[1]);
-                p[1] = -1;
+        if (p[0] == p[1]) {
+                /* Special case pairs which use the same fd in both
+                 * directions... */
+                p[0] = p[1] = safe_close(p[0]);
+                return;
         }
 
-        return a < 0 ? a : b;
+        p[0] = safe_close(p[0]);
+        p[1] = safe_close(p[1]);
 }
 
 ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) {
@@ -2085,7 +2196,7 @@ ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) {
                          * and expect that any error/EOF is reported
                          * via read() */
 
-                        fd_wait_for_event(fd, POLLIN, (usec_t) -1);
+                        fd_wait_for_event(fd, POLLIN, USEC_INFINITY);
                         continue;
                 }
 
@@ -2120,7 +2231,7 @@ ssize_t loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
                          * and expect that any error/EOF is reported
                          * via write() */
 
-                        fd_wait_for_event(fd, POLLOUT, (usec_t) -1);
+                        fd_wait_for_event(fd, POLLOUT, USEC_INFINITY);
                         continue;
                 }
 
@@ -2157,31 +2268,31 @@ int parse_size(const char *t, off_t base, off_t *size) {
         };
 
         static const struct table iec[] = {
-                { "B", 1 },
-                { "K", 1024ULL },
-                { "M", 1024ULL*1024ULL },
-                { "G", 1024ULL*1024ULL*1024ULL },
-                { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
-                { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
                 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
+                { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
+                { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
+                { "G", 1024ULL*1024ULL*1024ULL },
+                { "M", 1024ULL*1024ULL },
+                { "K", 1024ULL },
+                { "B", 1 },
                 { "", 1 },
         };
 
         static const struct table si[] = {
-                { "B", 1 },
-                { "K", 1000ULL },
-                { "M", 1000ULL*1000ULL },
-                { "G", 1000ULL*1000ULL*1000ULL },
-                { "T", 1000ULL*1000ULL*1000ULL*1000ULL },
-                { "P", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
                 { "E", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
+                { "P", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
+                { "T", 1000ULL*1000ULL*1000ULL*1000ULL },
+                { "G", 1000ULL*1000ULL*1000ULL },
+                { "M", 1000ULL*1000ULL },
+                { "K", 1000ULL },
+                { "B", 1 },
                 { "", 1 },
         };
 
         const struct table *table;
         const char *p;
         unsigned long long r = 0;
-        unsigned n_entries;
+        unsigned n_entries, start_pos = 0;
 
         assert(t);
         assert(base == 1000 || base == 1024);
@@ -2198,6 +2309,8 @@ int parse_size(const char *t, off_t base, off_t *size) {
         p = t;
         do {
                 long long l;
+                unsigned long long l2;
+                double frac = 0;
                 char *e;
                 unsigned i;
 
@@ -2213,14 +2326,32 @@ int parse_size(const char *t, off_t base, off_t *size) {
                 if (e == p)
                         return -EINVAL;
 
+                if (*e == '.') {
+                        e++;
+                        if (*e >= '0' && *e <= '9') {
+                                char *e2;
+
+                                /* strotoull itself would accept space/+/- */
+                                l2 = strtoull(e, &e2, 10);
+
+                                if (errno == ERANGE)
+                                        return -errno;
+
+                                /* Ignore failure. E.g. 10.M is valid */
+                                frac = l2;
+                                for (; e < e2; e++)
+                                        frac /= 10;
+                        }
+                }
+
                 e += strspn(e, WHITESPACE);
 
-                for (i = 0; i < n_entries; i++)
+                for (i = start_pos; i < n_entries; i++)
                         if (startswith(e, table[i].suffix)) {
                                 unsigned long long tmp;
-                                if ((unsigned long long) l > ULLONG_MAX / table[i].factor)
+                                if ((unsigned long long) l + (frac > 0) > ULLONG_MAX / table[i].factor)
                                         return -ERANGE;
-                                tmp = l * table[i].factor;
+                                tmp = l * table[i].factor + (unsigned long long) (frac * table[i].factor);
                                 if (tmp > ULLONG_MAX - r)
                                         return -ERANGE;
 
@@ -2229,6 +2360,8 @@ int parse_size(const char *t, off_t base, off_t *size) {
                                         return -ERANGE;
 
                                 p = e + strlen(table[i].suffix);
+
+                                start_pos = i + 1;
                                 break;
                         }
 
@@ -2252,7 +2385,7 @@ int make_stdio(int fd) {
         t = dup3(fd, STDERR_FILENO, 0);
 
         if (fd >= 3)
-                close_nointr_nofail(fd);
+                safe_close(fd);
 
         if (r < 0 || s < 0 || t < 0)
                 return -errno;
@@ -2422,6 +2555,24 @@ void sigset_add_many(sigset_t *ss, ...) {
         va_end(ap);
 }
 
+int sigprocmask_many(int how, ...) {
+        va_list ap;
+        sigset_t ss;
+        int sig;
+
+        assert_se(sigemptyset(&ss) == 0);
+
+        va_start(ap, how);
+        while ((sig = va_arg(ap, int)) > 0)
+                assert_se(sigaddset(&ss, sig) == 0);
+        va_end(ap);
+
+        if (sigprocmask(how, &ss, NULL) < 0)
+                return -errno;
+
+        return 0;
+}
+
 char* gethostname_malloc(void) {
         struct utsname u;
 
@@ -2462,7 +2613,7 @@ static char *lookup_uid(uid_t uid) {
         if (getpwuid_r(uid, &pwbuf, buf, bufsize, &pw) == 0 && pw)
                 return strdup(pw->pw_name);
 
-        if (asprintf(&name, "%lu", (unsigned long) uid) < 0)
+        if (asprintf(&name, UID_FMT, uid) < 0)
                 return NULL;
 
         return name;
@@ -2587,7 +2738,7 @@ int get_ctty(pid_t pid, dev_t *_devnr, char **r) {
 
                 /* This is an ugly hack */
                 if (major(devnr) == 136) {
-                        asprintf(&b, "pts/%lu", (unsigned long) minor(devnr));
+                        asprintf(&b, "pts/%u", minor(devnr));
                         goto finish;
                 }
 
@@ -2620,7 +2771,7 @@ finish:
 }
 
 int rm_rf_children_dangerous(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev) {
-        DIR *d;
+        _cleanup_closedir_ DIR *d = NULL;
         int ret = 0;
 
         assert(fd >= 0);
@@ -2630,7 +2781,7 @@ int rm_rf_children_dangerous(int fd, bool only_dirs, bool honour_sticky, struct
 
         d = fdopendir(fd);
         if (!d) {
-                close_nointr_nofail(fd);
+                safe_close(fd);
 
                 return errno == ENOENT ? 0 : -errno;
         }
@@ -2643,15 +2794,12 @@ int rm_rf_children_dangerous(int fd, bool only_dirs, bool honour_sticky, struct
 
                 errno = 0;
                 de = readdir(d);
-                if (!de && errno != 0) {
-                        if (ret == 0)
+                if (!de) {
+                        if (errno != 0 && ret == 0)
                                 ret = -errno;
-                        break;
+                        return ret;
                 }
 
-                if (!de)
-                        break;
-
                 if (streq(de->d_name, ".") || streq(de->d_name, ".."))
                         continue;
 
@@ -2707,10 +2855,6 @@ int rm_rf_children_dangerous(int fd, bool only_dirs, bool honour_sticky, struct
                         }
                 }
         }
-
-        closedir(d);
-
-        return ret;
 }
 
 _pure_ static int is_temporary_fs(struct statfs *s) {
@@ -2726,7 +2870,7 @@ int rm_rf_children(int fd, bool only_dirs, bool honour_sticky, struct stat *root
         assert(fd >= 0);
 
         if (fstatfs(fd, &s) < 0) {
-                close_nointr_nofail(fd);
+                safe_close(fd);
                 return -errno;
         }
 
@@ -2735,7 +2879,7 @@ int rm_rf_children(int fd, bool only_dirs, bool honour_sticky, struct stat *root
          * non-state data */
         if (!is_temporary_fs(&s)) {
                 log_error("Attempted to remove disk file system, and we can't allow that.");
-                close_nointr_nofail(fd);
+                safe_close(fd);
                 return -EPERM;
         }
 
@@ -2781,13 +2925,13 @@ static int rm_rf_internal(const char *path, bool only_dirs, bool delete_root, bo
 
         if (!dangerous) {
                 if (fstatfs(fd, &s) < 0) {
-                        close_nointr_nofail(fd);
+                        safe_close(fd);
                         return -errno;
                 }
 
                 if (!is_temporary_fs(&s)) {
                         log_error("Attempted to remove disk file system, and we can't allow that.");
-                        close_nointr_nofail(fd);
+                        safe_close(fd);
                         return -EPERM;
                 }
         }
@@ -2914,7 +3058,7 @@ int status_vprintf(const char *status, bool ellipse, bool ephemeral, const char
                 if (emax < 3)
                         emax = 3;
 
-                e = ellipsize(s, emax, 75);
+                e = ellipsize(s, emax, 50);
                 if (e) {
                         free(s);
                         s = e;
@@ -3034,12 +3178,13 @@ fail:
 }
 
 char **replace_env_argv(char **argv, char **env) {
-        char **r, **i;
+        char **ret, **i;
         unsigned k = 0, l = 0;
 
         l = strv_length(argv);
 
-        if (!(r = new(char*, l+1)))
+        ret = new(char*, l+1);
+        if (!ret)
                 return NULL;
 
         STRV_FOREACH(i, argv) {
@@ -3052,10 +3197,12 @@ char **replace_env_argv(char **argv, char **env) {
 
                         e = strv_env_get(env, *i+1);
                         if (e) {
+                                int r;
 
-                                if (!(m = strv_split_quoted(e))) {
-                                        r[k] = NULL;
-                                        strv_free(r);
+                                r = strv_split_quoted(&m, e);
+                                if (r < 0) {
+                                        ret[k] = NULL;
+                                        strv_free(ret);
                                         return NULL;
                                 }
                         } else
@@ -3064,16 +3211,17 @@ char **replace_env_argv(char **argv, char **env) {
                         q = strv_length(m);
                         l = l + q - 1;
 
-                        if (!(w = realloc(r, sizeof(char*) * (l+1)))) {
-                                r[k] = NULL;
-                                strv_free(r);
+                        w = realloc(ret, sizeof(char*) * (l+1));
+                        if (!w) {
+                                ret[k] = NULL;
+                                strv_free(ret);
                                 strv_free(m);
                                 return NULL;
                         }
 
-                        r = w;
+                        ret = w;
                         if (m) {
-                                memcpy(r + k, m, q * sizeof(char*));
+                                memcpy(ret + k, m, q * sizeof(char*));
                                 free(m);
                         }
 
@@ -3082,14 +3230,16 @@ char **replace_env_argv(char **argv, char **env) {
                 }
 
                 /* If ${FOO} appears as part of a word, replace it by the variable as-is */
-                if (!(r[k++] = replace_env(*i, env))) {
-                        strv_free(r);
+                ret[k] = replace_env(*i, env);
+                if (!ret[k]) {
+                        strv_free(ret);
                         return NULL;
                 }
+                k++;
         }
 
-        r[k] = NULL;
-        return r;
+        ret[k] = NULL;
+        return ret;
 }
 
 int fd_columns(int fd) {
@@ -3175,19 +3325,27 @@ bool on_tty(void) {
         return cached_on_tty;
 }
 
-int running_in_chroot(void) {
-        struct stat a = {}, b = {};
+int files_same(const char *filea, const char *fileb) {
+        struct stat a, b;
 
-        /* Only works as root */
-        if (stat("/proc/1/root", &a) < 0)
+        if (stat(filea, &a) < 0)
                 return -errno;
 
-        if (stat("/", &b) < 0)
+        if (stat(fileb, &b) < 0)
                 return -errno;
 
-        return
-                a.st_dev != b.st_dev ||
-                a.st_ino != b.st_ino;
+        return a.st_dev == b.st_dev &&
+               a.st_ino == b.st_ino;
+}
+
+int running_in_chroot(void) {
+        int ret;
+
+        ret = files_same("/proc/1/root", "/");
+        if (ret < 0)
+                return ret;
+
+        return ret == 0;
 }
 
 static char *ascii_ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
@@ -3299,23 +3457,49 @@ char *ellipsize(const char *s, size_t length, unsigned percent) {
         return ellipsize_mem(s, strlen(s), length, percent);
 }
 
-int touch(const char *path) {
-        int fd;
+int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode) {
+        _cleanup_close_ int fd;
+        int r;
 
         assert(path);
 
-        /* This just opens the file for writing, ensuring it
-         * exists. It doesn't call utimensat() the way /usr/bin/touch
-         * does it. */
+        if (parents)
+                mkdir_parents(path, 0755);
 
-        fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, 0644);
+        fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, mode > 0 ? mode : 0644);
         if (fd < 0)
                 return -errno;
 
-        close_nointr_nofail(fd);
+        if (mode > 0) {
+                r = fchmod(fd, mode);
+                if (r < 0)
+                        return -errno;
+        }
+
+        if (uid != (uid_t) -1 || gid != (gid_t) -1) {
+                r = fchown(fd, uid, gid);
+                if (r < 0)
+                        return -errno;
+        }
+
+        if (stamp != USEC_INFINITY) {
+                struct timespec ts[2];
+
+                timespec_store(&ts[0], stamp);
+                ts[1] = ts[0];
+                r = futimens(fd, ts);
+        } else
+                r = futimens(fd, NULL);
+        if (r < 0)
+                return -errno;
+
         return 0;
 }
 
+int touch(const char *path) {
+        return touch_file(path, false, USEC_INFINITY, (uid_t) -1, (gid_t) -1, 0);
+}
+
 char *unquote(const char *s, const char* quotes) {
         size_t l;
         assert(s);
@@ -3396,6 +3580,17 @@ int wait_for_terminate(pid_t pid, siginfo_t *status) {
         }
 }
 
+/*
+ * Return values:
+ * < 0 : wait_for_terminate() failed to get the state of the
+ *       process, the process was terminated by a signal, or
+ *       failed for an unknown reason.
+ * >=0 : The process terminated normally, and its exit code is
+ *       returned.
+ *
+ * That is, success is indicated by a return value of zero, and an
+ * error is indicated by a non-zero value.
+ */
 int wait_for_terminate_and_warn(const char *name, pid_t pid) {
         int r;
         siginfo_t status;
@@ -3463,6 +3658,17 @@ int null_or_empty_path(const char *fn) {
         return null_or_empty(&st);
 }
 
+int null_or_empty_fd(int fd) {
+        struct stat st;
+
+        assert(fd >= 0);
+
+        if (fstat(fd, &st) < 0)
+                return -errno;
+
+        return null_or_empty(&st);
+}
+
 DIR *xopendirat(int fd, const char *name, int flags) {
         int nfd;
         DIR *d;
@@ -3475,7 +3681,7 @@ DIR *xopendirat(int fd, const char *name, int flags) {
 
         d = fdopendir(nfd);
         if (!d) {
-                close_nointr_nofail(nfd);
+                safe_close(nfd);
                 return NULL;
         }
 
@@ -3496,25 +3702,21 @@ int signal_from_string_try_harder(const char *s) {
 
 static char *tag_to_udev_node(const char *tagvalue, const char *by) {
         _cleanup_free_ char *t = NULL, *u = NULL;
-        char *dn;
         size_t enc_len;
 
         u = unquote(tagvalue, "\"\'");
-        if (u == NULL)
+        if (!u)
                 return NULL;
 
         enc_len = strlen(u) * 4 + 1;
         t = new(char, enc_len);
-        if (t == NULL)
+        if (!t)
                 return NULL;
 
         if (encode_devnode_name(u, t, enc_len) < 0)
                 return NULL;
 
-        if (asprintf(&dn, "/dev/disk/by-%s/%s", by, t) < 0)
-                return NULL;
-
-        return dn;
+        return strjoin("/dev/disk/by-", by, "/", t, NULL);
 }
 
 char *fstab_node_to_udev_node(const char *p) {
@@ -3538,9 +3740,6 @@ char *fstab_node_to_udev_node(const char *p) {
 bool tty_is_vc(const char *tty) {
         assert(tty);
 
-        if (startswith(tty, "/dev/"))
-                tty += 5;
-
         return vtnr_from_tty(tty) >= 0;
 }
 
@@ -3661,111 +3860,123 @@ bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) {
         return endswith(de->d_name, suffix);
 }
 
-void execute_directory(const char *directory, DIR *d, char *argv[]) {
-        DIR *_d = NULL;
-        struct dirent *de;
-        Hashmap *pids = NULL;
+void execute_directory(const char *directory, DIR *d, usec_t timeout, char *argv[]) {
+        pid_t executor_pid;
+        int r;
 
         assert(directory);
 
-        /* Executes all binaries in a directory in parallel and
-         * waits for them to finish. */
+        /* Executes all binaries in a directory in parallel and waits
+         * for them to finish. Optionally a timeout is applied. */
 
-        if (!d) {
-                if (!(_d = opendir(directory))) {
+        executor_pid = fork();
+        if (executor_pid < 0) {
+                log_error("Failed to fork: %m");
+                return;
 
-                        if (errno == ENOENT)
-                                return;
+        } else if (executor_pid == 0) {
+                _cleanup_hashmap_free_free_ Hashmap *pids = NULL;
+                _cleanup_closedir_ DIR *_d = NULL;
+                struct dirent *de;
+                sigset_t ss;
 
-                        log_error("Failed to enumerate directory %s: %m", directory);
-                        return;
-                }
+                /* We fork this all off from a child process so that
+                 * we can somewhat cleanly make use of SIGALRM to set
+                 * a time limit */
 
-                d = _d;
-        }
+                reset_all_signal_handlers();
 
-        if (!(pids = hashmap_new(trivial_hash_func, trivial_compare_func))) {
-                log_error("Failed to allocate set.");
-                goto finish;
-        }
+                assert_se(sigemptyset(&ss) == 0);
+                assert_se(sigprocmask(SIG_SETMASK, &ss, NULL) == 0);
 
-        while ((de = readdir(d))) {
-                char *path;
-                pid_t pid;
-                int k;
+                assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
 
-                if (!dirent_is_file(de))
-                        continue;
+                if (!d) {
+                        d = _d = opendir(directory);
+                        if (!d) {
+                                if (errno == ENOENT)
+                                        _exit(EXIT_SUCCESS);
 
-                if (asprintf(&path, "%s/%s", directory, de->d_name) < 0) {
-                        log_oom();
-                        continue;
+                                log_error("Failed to enumerate directory %s: %m", directory);
+                                _exit(EXIT_FAILURE);
+                        }
                 }
 
-                if ((pid = fork()) < 0) {
-                        log_error("Failed to fork: %m");
-                        free(path);
-                        continue;
+                pids = hashmap_new(NULL, NULL);
+                if (!pids) {
+                        log_oom();
+                        _exit(EXIT_FAILURE);
                 }
 
-                if (pid == 0) {
-                        char *_argv[2];
-                        /* Child */
+                FOREACH_DIRENT(de, d, break) {
+                        _cleanup_free_ char *path = NULL;
+                        pid_t pid;
 
-                        if (!argv) {
-                                _argv[0] = path;
-                                _argv[1] = NULL;
-                                argv = _argv;
-                        } else
-                                argv[0] = path;
+                        if (!dirent_is_file(de))
+                                continue;
 
-                        execv(path, argv);
+                        path = strjoin(directory, "/", de->d_name, NULL);
+                        if (!path) {
+                                log_oom();
+                                _exit(EXIT_FAILURE);
+                        }
 
-                        log_error("Failed to execute %s: %m", path);
-                        _exit(EXIT_FAILURE);
-                }
+                        pid = fork();
+                        if (pid < 0) {
+                                log_error("Failed to fork: %m");
+                                continue;
+                        } else if (pid == 0) {
+                                char *_argv[2];
 
-                log_debug("Spawned %s as %lu", path, (unsigned long) pid);
+                                assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
 
-                if ((k = hashmap_put(pids, UINT_TO_PTR(pid), path)) < 0) {
-                        log_error("Failed to add PID to set: %s", strerror(-k));
-                        free(path);
-                }
-        }
+                                if (!argv) {
+                                        _argv[0] = path;
+                                        _argv[1] = NULL;
+                                        argv = _argv;
+                                } else
+                                        argv[0] = path;
 
-        while (!hashmap_isempty(pids)) {
-                pid_t pid = PTR_TO_UINT(hashmap_first_key(pids));
-                siginfo_t si = {};
-                char *path;
+                                execv(path, argv);
+                                log_error("Failed to execute %s: %m", path);
+                                _exit(EXIT_FAILURE);
+                        }
 
-                if (waitid(P_PID, pid, &si, WEXITED) < 0) {
+                        log_debug("Spawned %s as " PID_FMT ".", path, pid);
 
-                        if (errno == EINTR)
-                                continue;
+                        r = hashmap_put(pids, UINT_TO_PTR(pid), path);
+                        if (r < 0) {
+                                log_oom();
+                                _exit(EXIT_FAILURE);
+                        }
 
-                        log_error("waitid() failed: %m");
-                        goto finish;
+                        path = NULL;
                 }
 
-                if ((path = hashmap_remove(pids, UINT_TO_PTR(si.si_pid)))) {
-                        if (!is_clean_exit(si.si_code, si.si_status, NULL)) {
-                                if (si.si_code == CLD_EXITED)
-                                        log_error("%s exited with exit status %i.", path, si.si_status);
-                                else
-                                        log_error("%s terminated by signal %s.", path, signal_to_string(si.si_status));
-                        } else
-                                log_debug("%s exited successfully.", path);
+                /* Abort execution of this process after the
+                 * timout. We simply rely on SIGALRM as default action
+                 * terminating the process, and turn on alarm(). */
+
+                if (timeout != USEC_INFINITY)
+                        alarm((timeout + USEC_PER_SEC - 1) / USEC_PER_SEC);
+
+                while (!hashmap_isempty(pids)) {
+                        _cleanup_free_ char *path = NULL;
+                        pid_t pid;
+
+                        pid = PTR_TO_UINT(hashmap_first_key(pids));
+                        assert(pid > 0);
 
-                        free(path);
+                        path = hashmap_remove(pids, UINT_TO_PTR(pid));
+                        assert(path);
+
+                        wait_for_terminate_and_warn(path, pid);
                 }
-        }
 
-finish:
-        if (_d)
-                closedir(_d);
+                _exit(EXIT_SUCCESS);
+        }
 
-        if (pids)
-                hashmap_free_free(pids);
+        wait_for_terminate_and_warn(directory, executor_pid);
 }
 
 int kill_and_sigcont(pid_t pid, int sig) {
@@ -3873,6 +4084,21 @@ char* hostname_cleanup(char *s, bool lowercase) {
         return s;
 }
 
+bool machine_name_is_valid(const char *s) {
+
+        if (!hostname_is_valid(s))
+                return false;
+
+        /* Machine names should be useful hostnames, but also be
+         * useful in unit names, hence we enforce a stricter length
+         * limitation. */
+
+        if (strlen(s) > 64)
+                return false;
+
+        return true;
+}
+
 int pipe_eof(int fd) {
         struct pollfd pollfd = {
                 .fd = fd,
@@ -3901,7 +4127,7 @@ int fd_wait_for_event(int fd, int event, usec_t t) {
         struct timespec ts;
         int r;
 
-        r = ppoll(&pollfd, 1, t == (usec_t) -1 ? NULL : timespec_store(&ts, t), NULL);
+        r = ppoll(&pollfd, 1, t == USEC_INFINITY ? NULL : timespec_store(&ts, t), NULL);
         if (r < 0)
                 return -errno;
 
@@ -3914,24 +4140,16 @@ int fd_wait_for_event(int fd, int event, usec_t t) {
 int fopen_temporary(const char *path, FILE **_f, char **_temp_path) {
         FILE *f;
         char *t;
-        const char *fn;
-        size_t k;
         int fd;
 
         assert(path);
         assert(_f);
         assert(_temp_path);
 
-        t = new(char, strlen(path) + 1 + 6 + 1);
+        t = tempfn_xxxxxx(path);
         if (!t)
                 return -ENOMEM;
 
-        fn = basename(path);
-        k = fn - path;
-        memcpy(t, path, k);
-        t[k] = '.';
-        stpcpy(stpcpy(t+k+1, fn), "XXXXXX");
-
         fd = mkostemp_safe(t, O_WRONLY|O_CLOEXEC);
         if (fd < 0) {
                 free(t);
@@ -3961,16 +4179,13 @@ int terminal_vhangup_fd(int fd) {
 }
 
 int terminal_vhangup(const char *name) {
-        int fd, r;
+        _cleanup_close_ int fd;
 
         fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
         if (fd < 0)
                 return fd;
 
-        r = terminal_vhangup_fd(fd);
-        close_nointr_nofail(fd);
-
-        return r;
+        return terminal_vhangup_fd(fd);
 }
 
 int vt_disallocate(const char *name) {
@@ -3997,7 +4212,7 @@ int vt_disallocate(const char *name) {
                            "\033[H"    /* move home */
                            "\033[2J",  /* clear screen */
                            10, false);
-                close_nointr_nofail(fd);
+                safe_close(fd);
 
                 return 0;
         }
@@ -4018,7 +4233,7 @@ int vt_disallocate(const char *name) {
                 return fd;
 
         r = ioctl(fd, VT_DISALLOCATE, u);
-        close_nointr_nofail(fd);
+        safe_close(fd);
 
         if (r >= 0)
                 return 0;
@@ -4037,102 +4252,67 @@ int vt_disallocate(const char *name) {
                    "\033[H"   /* move home */
                    "\033[3J", /* clear screen including scrollback, requires Linux 2.6.40 */
                    10, false);
-        close_nointr_nofail(fd);
+        safe_close(fd);
 
         return 0;
 }
 
-int copy_file(const char *from, const char *to, int flags) {
-        _cleanup_close_ int fdf = -1;
-        int r, fdt;
+int symlink_atomic(const char *from, const char *to) {
+        _cleanup_free_ char *t = NULL;
 
         assert(from);
         assert(to);
 
-        fdf = open(from, O_RDONLY|O_CLOEXEC|O_NOCTTY);
-        if (fdf < 0)
-                return -errno;
+        t = tempfn_random(to);
+        if (!t)
+                return -ENOMEM;
 
-        fdt = open(to, flags|O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, 0644);
-        if (fdt < 0)
+        if (symlink(from, t) < 0)
                 return -errno;
 
-        for (;;) {
-                char buf[PIPE_BUF];
-                ssize_t n, k;
-
-                n = read(fdf, buf, sizeof(buf));
-                if (n < 0) {
-                        r = -errno;
-
-                        close_nointr(fdt);
-                        unlink(to);
-
-                        return r;
-                }
+        if (rename(t, to) < 0) {
+                unlink_noerrno(t);
+                return -errno;
+        }
 
-                if (n == 0)
-                        break;
+        return 0;
+}
 
-                errno = 0;
-                k = loop_write(fdt, buf, n, false);
-                if (n != k) {
-                        r = k < 0 ? k : (errno ? -errno : -EIO);
+int mknod_atomic(const char *path, mode_t mode, dev_t dev) {
+        _cleanup_free_ char *t = NULL;
 
-                        close_nointr(fdt);
-                        unlink(to);
+        assert(path);
 
-                        return r;
-                }
-        }
+        t = tempfn_random(path);
+        if (!t)
+                return -ENOMEM;
 
-        r = close_nointr(fdt);
+        if (mknod(t, mode, dev) < 0)
+                return -errno;
 
-        if (r < 0) {
-                unlink(to);
-                return r;
+        if (rename(t, path) < 0) {
+                unlink_noerrno(t);
+                return -errno;
         }
 
         return 0;
 }
 
-int symlink_atomic(const char *from, const char *to) {
-        char *x;
-        _cleanup_free_ char *t;
-        const char *fn;
-        size_t k;
-        uint64_t u;
-        unsigned i;
-        int r;
+int mkfifo_atomic(const char *path, mode_t mode) {
+        _cleanup_free_ char *t = NULL;
 
-        assert(from);
-        assert(to);
+        assert(path);
 
-        t = new(char, strlen(to) + 1 + 16 + 1);
+        t = tempfn_random(path);
         if (!t)
                 return -ENOMEM;
 
-        fn = basename(to);
-        k = fn-to;
-        memcpy(t, to, k);
-        t[k] = '.';
-        x = stpcpy(t+k+1, fn);
-
-        u = random_u64();
-        for (i = 0; i < 16; i++) {
-                *(x++) = hexchar(u & 0xF);
-                u >>= 4;
-        }
-
-        *x = 0;
-
-        if (symlink(from, t) < 0)
+        if (mkfifo(t, mode) < 0)
                 return -errno;
 
-        if (rename(t, to) < 0) {
-                r = -errno;
-                unlink(t);
-                return r;
+        if (rename(t, path) < 0) {
+                unlink_noerrno(t);
+                return -errno;
         }
 
         return 0;
@@ -4159,7 +4339,7 @@ int socket_from_display(const char *display, char **path) {
 
         k = strspn(display+1, "0123456789");
 
-        f = new(char, sizeof("/tmp/.X11-unix/X") + k);
+        f = new(char, strlen("/tmp/.X11-unix/X") + k + 1);
         if (!f)
                 return -ENOMEM;
 
@@ -4250,7 +4430,7 @@ char* uid_to_name(uid_t uid) {
         if (p)
                 return strdup(p->pw_name);
 
-        if (asprintf(&r, "%lu", (unsigned long) uid) < 0)
+        if (asprintf(&r, UID_FMT, uid) < 0)
                 return NULL;
 
         return r;
@@ -4267,7 +4447,7 @@ char* gid_to_name(gid_t gid) {
         if (p)
                 return strdup(p->gr_name);
 
-        if (asprintf(&r, "%lu", (unsigned long) gid) < 0)
+        if (asprintf(&r, GID_FMT, gid) < 0)
                 return NULL;
 
         return r;
@@ -4416,22 +4596,6 @@ int dirent_ensure_type(DIR *d, struct dirent *de) {
         return 0;
 }
 
-int in_search_path(const char *path, char **search) {
-        char **i;
-        _cleanup_free_ char *parent = NULL;
-        int r;
-
-        r = path_get_parent(path, &parent);
-        if (r < 0)
-                return r;
-
-        STRV_FOREACH(i, search)
-                if (path_equal(parent, *i))
-                        return 1;
-
-        return 0;
-}
-
 int get_files_in_directory(const char *path, char ***list) {
         _cleanup_closedir_ DIR *d = NULL;
         size_t bufsize = 0, n = 0;
@@ -4691,7 +4855,7 @@ static const char* const sched_policy_table[] = {
 
 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX);
 
-static const char* const rlimit_table[] = {
+static const char* const rlimit_table[_RLIMIT_MAX] = {
         [RLIMIT_CPU] = "LimitCPU",
         [RLIMIT_FSIZE] = "LimitFSIZE",
         [RLIMIT_DATA] = "LimitDATA",
@@ -4793,7 +4957,7 @@ int signal_from_string(const char *s) {
                 if (signo > 0 && signo < _NSIG)
                         return signo;
         }
-        return -1;
+        return -EINVAL;
 }
 
 bool kexec_loaded(void) {
@@ -5162,7 +5326,7 @@ int make_console_stdio(void) {
 
         /* Make /dev/console the controlling terminal and stdin/stdout/stderr */
 
-        fd = acquire_terminal("/dev/console", false, true, true, (usec_t) -1);
+        fd = acquire_terminal("/dev/console", false, true, true, USEC_INFINITY);
         if (fd < 0) {
                 log_error("Failed to acquire terminal: %s", strerror(-fd));
                 return fd;
@@ -5186,8 +5350,8 @@ int get_home_dir(char **_h) {
         assert(_h);
 
         /* Take the user specified one */
-        e = getenv("HOME");
-        if (e) {
+        e = secure_getenv("HOME");
+        if (e && path_is_absolute(e)) {
                 h = strdup(e);
                 if (!h)
                         return -ENOMEM;
@@ -5294,13 +5458,14 @@ bool filename_is_safe(const char *p) {
 bool string_is_safe(const char *p) {
         const char *t;
 
-        assert(p);
+        if (!p)
+                return false;
 
         for (t = p; *t; t++) {
                 if (*t > 0 && *t < ' ')
                         return false;
 
-                if (strchr("\\\"\'", *t))
+                if (strchr("\\\"\'\0x7f", *t))
                         return false;
         }
 
@@ -5308,17 +5473,24 @@ bool string_is_safe(const char *p) {
 }
 
 /**
- * Check if a string contains control characters.
- * Spaces and tabs are not considered control characters.
+ * Check if a string contains control characters. If 'ok' is non-NULL
+ * it may be a string containing additional CCs to be considered OK.
  */
-bool string_has_cc(const char *p) {
+bool string_has_cc(const char *p, const char *ok) {
         const char *t;
 
         assert(p);
 
-        for (t = p; *t; t++)
-                if (*t > 0 && *t < ' ' && *t != '\t')
+        for (t = p; *t; t++) {
+                if (ok && strchr(ok, *t))
+                        continue;
+
+                if (*t > 0 && *t < ' ')
+                        return true;
+
+                if (*t == 127)
                         return true;
+        }
 
         return false;
 }
@@ -5412,21 +5584,27 @@ out:
 
 const char *draw_special_char(DrawSpecialChar ch) {
         static const char *draw_table[2][_DRAW_SPECIAL_CHAR_MAX] = {
+
                 /* UTF-8 */ {
-                        [DRAW_TREE_VERT]          = "\342\224\202 ",            /* │  */
+                        [DRAW_TREE_VERTICAL]      = "\342\224\202 ",            /* │  */
                         [DRAW_TREE_BRANCH]        = "\342\224\234\342\224\200", /* ├─ */
                         [DRAW_TREE_RIGHT]         = "\342\224\224\342\224\200", /* └─ */
                         [DRAW_TREE_SPACE]         = "  ",                       /*    */
-                        [DRAW_TRIANGULAR_BULLET]  = "\342\200\243 ",            /* ‣  */
-                        [DRAW_BLACK_CIRCLE]       = "\342\227\217 ",            /* ●  */
+                        [DRAW_TRIANGULAR_BULLET]  = "\342\200\243",             /* ‣ */
+                        [DRAW_BLACK_CIRCLE]       = "\342\227\217",             /* ● */
+                        [DRAW_ARROW]              = "\342\206\222",             /* → */
+                        [DRAW_DASH]               = "\342\200\223",             /* – */
                 },
+
                 /* ASCII fallback */ {
-                        [DRAW_TREE_VERT]          = "| ",
+                        [DRAW_TREE_VERTICAL]      = "| ",
                         [DRAW_TREE_BRANCH]        = "|-",
                         [DRAW_TREE_RIGHT]         = "`-",
                         [DRAW_TREE_SPACE]         = "  ",
-                        [DRAW_TRIANGULAR_BULLET]  = "> ",
-                        [DRAW_BLACK_CIRCLE]       = "* ",
+                        [DRAW_TRIANGULAR_BULLET]  = ">",
+                        [DRAW_BLACK_CIRCLE]       = "*",
+                        [DRAW_ARROW]              = "->",
+                        [DRAW_DASH]               = "-",
                 }
         };
 
@@ -5614,7 +5792,7 @@ int on_ac_power(void) {
                 if (n != 6 || memcmp(contents, "Mains\n", 6))
                         continue;
 
-                close_nointr_nofail(fd);
+                safe_close(fd);
                 fd = openat(device, "online", O_RDONLY|O_CLOEXEC|O_NOCTTY);
                 if (fd < 0) {
                         if (errno == ENOENT)
@@ -5642,21 +5820,24 @@ int on_ac_power(void) {
         return found_online || !found_offline;
 }
 
-static int search_and_fopen_internal(const char *path, const char *mode, char **search, FILE **_f) {
+static int search_and_fopen_internal(const char *path, const char *mode, const char *root, char **search, FILE **_f) {
         char **i;
 
         assert(path);
         assert(mode);
         assert(_f);
 
-        if (!path_strv_canonicalize_absolute_uniq(search, NULL))
+        if (!path_strv_resolve_uniq(search, root))
                 return -ENOMEM;
 
         STRV_FOREACH(i, search) {
                 _cleanup_free_ char *p = NULL;
                 FILE *f;
 
-                p = strjoin(*i, "/", path, NULL);
+                if (root)
+                        p = strjoin(root, *i, "/", path, NULL);
+                else
+                        p = strjoin(*i, "/", path, NULL);
                 if (!p)
                         return -ENOMEM;
 
@@ -5673,7 +5854,7 @@ static int search_and_fopen_internal(const char *path, const char *mode, char **
         return -ENOENT;
 }
 
-int search_and_fopen(const char *path, const char *mode, const char **search, FILE **_f) {
+int search_and_fopen(const char *path, const char *mode, const char *root, const char **search, FILE **_f) {
         _cleanup_strv_free_ char **copy = NULL;
 
         assert(path);
@@ -5696,10 +5877,10 @@ int search_and_fopen(const char *path, const char *mode, const char **search, FI
         if (!copy)
                 return -ENOMEM;
 
-        return search_and_fopen_internal(path, mode, copy, _f);
+        return search_and_fopen_internal(path, mode, root, copy, _f);
 }
 
-int search_and_fopen_nulstr(const char *path, const char *mode, const char *search, FILE **_f) {
+int search_and_fopen_nulstr(const char *path, const char *mode, const char *root, const char *search, FILE **_f) {
         _cleanup_strv_free_ char **s = NULL;
 
         if (path_is_absolute(path)) {
@@ -5718,7 +5899,7 @@ int search_and_fopen_nulstr(const char *path, const char *mode, const char *sear
         if (!s)
                 return -ENOMEM;
 
-        return search_and_fopen_internal(path, mode, s, _f);
+        return search_and_fopen_internal(path, mode, root, s, _f);
 }
 
 char *strextend(char **x, ...) {
@@ -5792,8 +5973,8 @@ char *strrep(const char *s, unsigned n) {
         return r;
 }
 
-void* greedy_realloc(void **p, size_t *allocated, size_t need) {
-        size_t a;
+void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size) {
+        size_t a, newalloc;
         void *q;
 
         assert(p);
@@ -5802,10 +5983,11 @@ void* greedy_realloc(void **p, size_t *allocated, size_t need) {
         if (*allocated >= need)
                 return *p;
 
-        a = MAX(64u, need * 2);
+        newalloc = MAX(need * 2, 64u / size);
+        a = newalloc * size;
 
         /* check for overflows */
-        if (a < need)
+        if (a < size * need)
                 return NULL;
 
         q = realloc(*p, a);
@@ -5813,11 +5995,11 @@ void* greedy_realloc(void **p, size_t *allocated, size_t need) {
                 return NULL;
 
         *p = q;
-        *allocated = a;
+        *allocated = newalloc;
         return q;
 }
 
-void* greedy_realloc0(void **p, size_t *allocated, size_t need) {
+void* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size) {
         size_t prev;
         uint8_t *q;
 
@@ -5826,12 +6008,12 @@ void* greedy_realloc0(void **p, size_t *allocated, size_t need) {
 
         prev = *allocated;
 
-        q = greedy_realloc(p, allocated, need);
+        q = greedy_realloc(p, allocated, need, size);
         if (!q)
                 return NULL;
 
         if (*allocated > prev)
-                memzero(&q[prev], *allocated - prev);
+                memzero(q + prev * size, (*allocated - prev) * size);
 
         return q;
 }
@@ -5909,8 +6091,8 @@ int split_pair(const char *s, const char *sep, char **l, char **r) {
 }
 
 int shall_restore_state(void) {
-        _cleanup_free_ char *line;
-        char *w, *state;
+        _cleanup_free_ char *line = NULL;
+        const char *word, *state;
         size_t l;
         int r;
 
@@ -5920,11 +6102,26 @@ int shall_restore_state(void) {
         if (r == 0) /* Container ... */
                 return 1;
 
-        FOREACH_WORD_QUOTED(w, l, line, state)
-                if (l == 23 && strneq(w, "systemd.restore_state=0", 23))
-                        return 0;
+        r = 1;
 
-        return 1;
+        FOREACH_WORD_QUOTED(word, l, line, state) {
+                const char *e;
+                char n[l+1];
+                int k;
+
+                memcpy(n, word, l);
+                n[l] = 0;
+
+                e = startswith(n, "systemd.restore_state=");
+                if (!e)
+                        continue;
+
+                k = parse_boolean(e);
+                if (k >= 0)
+                        r = k;
+        }
+
+        return r;
 }
 
 int proc_cmdline(char **ret) {
@@ -5942,7 +6139,7 @@ int proc_cmdline(char **ret) {
                         if (*p == 0)
                                 *p = ' ';
 
-                *p  = 0;
+                *p = 0;
                 *ret = buf;
                 return 1;
         }
@@ -5954,12 +6151,14 @@ int proc_cmdline(char **ret) {
         return 1;
 }
 
-int parse_proc_cmdline(int (*parse_word)(const char *word)) {
+int parse_proc_cmdline(int (*parse_item)(const char *key, const char *value)) {
         _cleanup_free_ char *line = NULL;
-        char *w, *state;
+        const char *w, *state;
         size_t l;
         int r;
 
+        assert(parse_item);
+
         r = proc_cmdline(&line);
         if (r < 0)
                 log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
@@ -5967,17 +6166,23 @@ int parse_proc_cmdline(int (*parse_word)(const char *word)) {
                 return 0;
 
         FOREACH_WORD_QUOTED(w, l, line, state) {
-                _cleanup_free_ char *word;
+                char word[l+1], *value;
 
-                word = strndup(w, l);
-                if (!word)
-                        return log_oom();
+                memcpy(word, w, l);
+                word[l] = 0;
 
-                r = parse_word(word);
-                if (r < 0) {
-                        log_error("Failed on cmdline argument %s: %s", word, strerror(-r));
+                /* Filter out arguments that are intended only for the
+                 * initrd */
+                if (!in_initrd() && startswith(word, "rd."))
+                        continue;
+
+                value = strchr(word, '=');
+                if (value)
+                        *(value++) = 0;
+
+                r = parse_item(word, value);
+                if (r < 0)
                         return r;
-                }
         }
 
         return 0;
@@ -6014,60 +6219,93 @@ int container_get_leader(const char *machine, pid_t *pid) {
         return 0;
 }
 
-int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *root_fd) {
-        _cleanup_close_ int pidnsfd = -1, mntnsfd = -1;
-        const char *pidns, *mntns, *root;
-        int rfd;
+int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int *root_fd) {
+        _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, netnsfd = -1;
+        int rfd = -1;
 
         assert(pid >= 0);
-        assert(pidns_fd);
-        assert(mntns_fd);
-        assert(root_fd);
 
-        mntns = procfs_file_alloca(pid, "ns/mnt");
-        mntnsfd = open(mntns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
-        if (mntnsfd < 0)
-                return -errno;
+        if (mntns_fd) {
+                const char *mntns;
 
-        pidns = procfs_file_alloca(pid, "ns/pid");
-        pidnsfd = open(pidns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
-        if (pidnsfd < 0)
-                return -errno;
+                mntns = procfs_file_alloca(pid, "ns/mnt");
+                mntnsfd = open(mntns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
+                if (mntnsfd < 0)
+                        return -errno;
+        }
 
-        root = procfs_file_alloca(pid, "root");
-        rfd = open(root, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY);
-        if (rfd < 0)
-                return -errno;
+        if (pidns_fd) {
+                const char *pidns;
 
-        *pidns_fd = pidnsfd;
-        *mntns_fd = mntnsfd;
-        *root_fd = rfd;
-        pidnsfd = -1;
-        mntnsfd = -1;
+                pidns = procfs_file_alloca(pid, "ns/pid");
+                pidnsfd = open(pidns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
+                if (pidnsfd < 0)
+                        return -errno;
+        }
+
+        if (netns_fd) {
+                const char *netns;
+
+                netns = procfs_file_alloca(pid, "ns/net");
+                netnsfd = open(netns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
+                if (netnsfd < 0)
+                        return -errno;
+        }
+
+        if (root_fd) {
+                const char *root;
+
+                root = procfs_file_alloca(pid, "root");
+                rfd = open(root, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY);
+                if (rfd < 0)
+                        return -errno;
+        }
+
+        if (pidns_fd)
+                *pidns_fd = pidnsfd;
+
+        if (mntns_fd)
+                *mntns_fd = mntnsfd;
+
+        if (netns_fd)
+                *netns_fd = netnsfd;
+
+        if (root_fd)
+                *root_fd = rfd;
+
+        pidnsfd = mntnsfd = netnsfd = -1;
 
         return 0;
 }
 
-int namespace_enter(int pidns_fd, int mntns_fd, int root_fd) {
-        assert(pidns_fd >= 0);
-        assert(mntns_fd >= 0);
-        assert(root_fd >= 0);
+int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int root_fd) {
 
-        if (setns(pidns_fd, CLONE_NEWPID) < 0)
-                return -errno;
+        if (pidns_fd >= 0)
+                if (setns(pidns_fd, CLONE_NEWPID) < 0)
+                        return -errno;
 
-        if (setns(mntns_fd, CLONE_NEWNS) < 0)
-                return -errno;
+        if (mntns_fd >= 0)
+                if (setns(mntns_fd, CLONE_NEWNS) < 0)
+                        return -errno;
 
-        if (fchdir(root_fd) < 0)
-                return -errno;
+        if (netns_fd >= 0)
+                if (setns(netns_fd, CLONE_NEWNET) < 0)
+                        return -errno;
 
-        if (chroot(".") < 0)
-                return -errno;
+        if (root_fd >= 0) {
+                if (fchdir(root_fd) < 0)
+                        return -errno;
+
+                if (chroot(".") < 0)
+                        return -errno;
+        }
 
         if (setresgid(0, 0, 0) < 0)
                 return -errno;
 
+        if (setgroups(0, NULL) < 0)
+                return -errno;
+
         if (setresuid(0, 0, 0) < 0)
                 return -errno;
 
@@ -6269,3 +6507,634 @@ const char* personality_to_string(unsigned long p) {
 
         return NULL;
 }
+
+uint64_t physical_memory(void) {
+        long mem;
+
+        /* We return this as uint64_t in case we are running as 32bit
+         * process on a 64bit kernel with huge amounts of memory */
+
+        mem = sysconf(_SC_PHYS_PAGES);
+        assert(mem > 0);
+
+        return (uint64_t) mem * (uint64_t) page_size();
+}
+
+char* mount_test_option(const char *haystack, const char *needle) {
+
+        struct mntent me = {
+                .mnt_opts = (char*) haystack
+        };
+
+        assert(needle);
+
+        /* Like glibc's hasmntopt(), but works on a string, not a
+         * struct mntent */
+
+        if (!haystack)
+                return NULL;
+
+        return hasmntopt(&me, needle);
+}
+
+void hexdump(FILE *f, const void *p, size_t s) {
+        const uint8_t *b = p;
+        unsigned n = 0;
+
+        assert(s == 0 || b);
+
+        while (s > 0) {
+                size_t i;
+
+                fprintf(f, "%04x  ", n);
+
+                for (i = 0; i < 16; i++) {
+
+                        if (i >= s)
+                                fputs("   ", f);
+                        else
+                                fprintf(f, "%02x ", b[i]);
+
+                        if (i == 7)
+                                fputc(' ', f);
+                }
+
+                fputc(' ', f);
+
+                for (i = 0; i < 16; i++) {
+
+                        if (i >= s)
+                                fputc(' ', f);
+                        else
+                                fputc(isprint(b[i]) ? (char) b[i] : '.', f);
+                }
+
+                fputc('\n', f);
+
+                if (s < 16)
+                        break;
+
+                n += 16;
+                b += 16;
+                s -= 16;
+        }
+}
+
+int update_reboot_param_file(const char *param) {
+        int r = 0;
+
+        if (param) {
+
+                r = write_string_file(REBOOT_PARAM_FILE, param);
+                if (r < 0)
+                        log_error("Failed to write reboot param to "
+                                  REBOOT_PARAM_FILE": %s", strerror(-r));
+        } else
+                unlink(REBOOT_PARAM_FILE);
+
+        return r;
+}
+
+int umount_recursive(const char *prefix, int flags) {
+        bool again;
+        int n = 0, r;
+
+        /* Try to umount everything recursively below a
+         * directory. Also, take care of stacked mounts, and keep
+         * unmounting them until they are gone. */
+
+        do {
+                _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
+
+                again = false;
+                r = 0;
+
+                proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
+                if (!proc_self_mountinfo)
+                        return -errno;
+
+                for (;;) {
+                        _cleanup_free_ char *path = NULL, *p = NULL;
+                        int k;
+
+                        k = fscanf(proc_self_mountinfo,
+                                   "%*s "       /* (1) mount id */
+                                   "%*s "       /* (2) parent id */
+                                   "%*s "       /* (3) major:minor */
+                                   "%*s "       /* (4) root */
+                                   "%ms "       /* (5) mount point */
+                                   "%*s"        /* (6) mount options */
+                                   "%*[^-]"     /* (7) optional fields */
+                                   "- "         /* (8) separator */
+                                   "%*s "       /* (9) file system type */
+                                   "%*s"        /* (10) mount source */
+                                   "%*s"        /* (11) mount options 2 */
+                                   "%*[^\n]",   /* some rubbish at the end */
+                                   &path);
+                        if (k != 1) {
+                                if (k == EOF)
+                                        break;
+
+                                continue;
+                        }
+
+                        p = cunescape(path);
+                        if (!p)
+                                return -ENOMEM;
+
+                        if (!path_startswith(p, prefix))
+                                continue;
+
+                        if (umount2(p, flags) < 0) {
+                                r = -errno;
+                                continue;
+                        }
+
+                        again = true;
+                        n++;
+
+                        break;
+                }
+
+        } while (again);
+
+        return r ? r : n;
+}
+
+int bind_remount_recursive(const char *prefix, bool ro) {
+        _cleanup_set_free_free_ Set *done = NULL;
+        _cleanup_free_ char *cleaned = NULL;
+        int r;
+
+        /* Recursively remount a directory (and all its submounts)
+         * read-only or read-write. If the directory is already
+         * mounted, we reuse the mount and simply mark it
+         * MS_BIND|MS_RDONLY (or remove the MS_RDONLY for read-write
+         * operation). If it isn't we first make it one. Afterwards we
+         * apply MS_BIND|MS_RDONLY (or remove MS_RDONLY) to all
+         * submounts we can access, too. When mounts are stacked on
+         * the same mount point we only care for each individual
+         * "top-level" mount on each point, as we cannot
+         * influence/access the underlying mounts anyway. We do not
+         * have any effect on future submounts that might get
+         * propagated, they migt be writable. This includes future
+         * submounts that have been triggered via autofs. */
+
+        cleaned = strdup(prefix);
+        if (!cleaned)
+                return -ENOMEM;
+
+        path_kill_slashes(cleaned);
+
+        done = set_new(string_hash_func, string_compare_func);
+        if (!done)
+                return -ENOMEM;
+
+        for (;;) {
+                _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
+                _cleanup_set_free_free_ Set *todo = NULL;
+                bool top_autofs = false;
+                char *x;
+
+                todo = set_new(string_hash_func, string_compare_func);
+                if (!todo)
+                        return -ENOMEM;
+
+                proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
+                if (!proc_self_mountinfo)
+                        return -errno;
+
+                for (;;) {
+                        _cleanup_free_ char *path = NULL, *p = NULL, *type = NULL;
+                        int k;
+
+                        k = fscanf(proc_self_mountinfo,
+                                   "%*s "       /* (1) mount id */
+                                   "%*s "       /* (2) parent id */
+                                   "%*s "       /* (3) major:minor */
+                                   "%*s "       /* (4) root */
+                                   "%ms "       /* (5) mount point */
+                                   "%*s"        /* (6) mount options (superblock) */
+                                   "%*[^-]"     /* (7) optional fields */
+                                   "- "         /* (8) separator */
+                                   "%ms "       /* (9) file system type */
+                                   "%*s"        /* (10) mount source */
+                                   "%*s"        /* (11) mount options (bind mount) */
+                                   "%*[^\n]",   /* some rubbish at the end */
+                                   &path,
+                                   &type);
+                        if (k != 2) {
+                                if (k == EOF)
+                                        break;
+
+                                continue;
+                        }
+
+                        p = cunescape(path);
+                        if (!p)
+                                return -ENOMEM;
+
+                        /* Let's ignore autofs mounts.  If they aren't
+                         * triggered yet, we want to avoid triggering
+                         * them, as we don't make any guarantees for
+                         * future submounts anyway.  If they are
+                         * already triggered, then we will find
+                         * another entry for this. */
+                        if (streq(type, "autofs")) {
+                                top_autofs = top_autofs || path_equal(cleaned, p);
+                                continue;
+                        }
+
+                        if (path_startswith(p, cleaned) &&
+                            !set_contains(done, p)) {
+
+                                r = set_consume(todo, p);
+                                p = NULL;
+
+                                if (r == -EEXIST)
+                                        continue;
+                                if (r < 0)
+                                        return r;
+                        }
+                }
+
+                /* If we have no submounts to process anymore and if
+                 * the root is either already done, or an autofs, we
+                 * are done */
+                if (set_isempty(todo) &&
+                    (top_autofs || set_contains(done, cleaned)))
+                        return 0;
+
+                if (!set_contains(done, cleaned) &&
+                    !set_contains(todo, cleaned)) {
+                        /* The prefix directory itself is not yet a
+                         * mount, make it one. */
+                        if (mount(cleaned, cleaned, NULL, MS_BIND|MS_REC, NULL) < 0)
+                                return -errno;
+
+                        if (mount(NULL, prefix, NULL, MS_BIND|MS_REMOUNT|(ro ? MS_RDONLY : 0), NULL) < 0)
+                                return -errno;
+
+                        x = strdup(cleaned);
+                        if (!x)
+                                return -ENOMEM;
+
+                        r = set_consume(done, x);
+                        if (r < 0)
+                                return r;
+                }
+
+                while ((x = set_steal_first(todo))) {
+
+                        r = set_consume(done, x);
+                        if (r == -EEXIST)
+                                continue;
+                        if (r < 0)
+                                return r;
+
+                        if (mount(NULL, x, NULL, MS_BIND|MS_REMOUNT|(ro ? MS_RDONLY : 0), NULL) < 0) {
+
+                                /* Deal with mount points that are
+                                 * obstructed by a later mount */
+
+                                if (errno != ENOENT)
+                                        return -errno;
+                        }
+
+                }
+        }
+}
+
+int fflush_and_check(FILE *f) {
+        assert(f);
+
+        errno = 0;
+        fflush(f);
+
+        if (ferror(f))
+                return errno ? -errno : -EIO;
+
+        return 0;
+}
+
+char *tempfn_xxxxxx(const char *p) {
+        const char *fn;
+        char *t;
+        size_t k;
+
+        assert(p);
+
+        t = new(char, strlen(p) + 1 + 6 + 1);
+        if (!t)
+                return NULL;
+
+        fn = basename(p);
+        k = fn - p;
+
+        strcpy(stpcpy(stpcpy(mempcpy(t, p, k), "."), fn), "XXXXXX");
+
+        return t;
+}
+
+char *tempfn_random(const char *p) {
+        const char *fn;
+        char *t, *x;
+        uint64_t u;
+        size_t k;
+        unsigned i;
+
+        assert(p);
+
+        t = new(char, strlen(p) + 1 + 16 + 1);
+        if (!t)
+                return NULL;
+
+        fn = basename(p);
+        k = fn - p;
+
+        x = stpcpy(stpcpy(mempcpy(t, p, k), "."), fn);
+
+        u = random_u64();
+        for (i = 0; i < 16; i++) {
+                *(x++) = hexchar(u & 0xF);
+                u >>= 4;
+        }
+
+        *x = 0;
+
+        return t;
+}
+
+/* make sure the hostname is not "localhost" */
+bool is_localhost(const char *hostname) {
+        assert(hostname);
+
+        /* This tries to identify local host and domain names
+         * described in RFC6761 plus the redhatism of .localdomain */
+
+        return streq(hostname, "localhost") ||
+               streq(hostname, "localhost.") ||
+               streq(hostname, "localdomain.") ||
+               streq(hostname, "localdomain") ||
+               endswith(hostname, ".localhost") ||
+               endswith(hostname, ".localhost.") ||
+               endswith(hostname, ".localdomain") ||
+               endswith(hostname, ".localdomain.");
+}
+
+int take_password_lock(const char *root) {
+
+        struct flock flock = {
+                .l_type = F_WRLCK,
+                .l_whence = SEEK_SET,
+                .l_start = 0,
+                .l_len = 0,
+        };
+
+        const char *path;
+        int fd, r;
+
+        /* This is roughly the same as lckpwdf(), but not as awful. We
+         * don't want to use alarm() and signals, hence we implement
+         * our own trivial version of this.
+         *
+         * Note that shadow-utils also takes per-database locks in
+         * addition to lckpwdf(). However, we don't given that they
+         * are redundant as they they invoke lckpwdf() first and keep
+         * it during everything they do. The per-database locks are
+         * awfully racy, and thus we just won't do them. */
+
+        if (root)
+                path = strappenda(root, "/etc/.pwd.lock");
+        else
+                path = "/etc/.pwd.lock";
+
+        fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0600);
+        if (fd < 0)
+                return -errno;
+
+        r = fcntl(fd, F_SETLKW, &flock);
+        if (r < 0) {
+                safe_close(fd);
+                return -errno;
+        }
+
+        return fd;
+}
+
+int is_symlink(const char *path) {
+        struct stat info;
+
+        if (lstat(path, &info) < 0)
+                return -errno;
+
+        if (S_ISLNK(info.st_mode))
+                return 1;
+
+        return 0;
+}
+
+int unquote_first_word(const char **p, char **ret) {
+        _cleanup_free_ char *s = NULL;
+        size_t allocated = 0, sz = 0;
+
+        enum {
+                START,
+                VALUE,
+                VALUE_ESCAPE,
+                SINGLE_QUOTE,
+                SINGLE_QUOTE_ESCAPE,
+                DOUBLE_QUOTE,
+                DOUBLE_QUOTE_ESCAPE,
+                SPACE,
+        } state = START;
+
+        assert(p);
+        assert(*p);
+        assert(ret);
+
+        /* Parses the first word of a string, and returns it in
+         * *ret. Removes all quotes in the process. When parsing fails
+         * (because of an uneven number of quotes or similar), leaves
+         * the pointer *p at the first invalid character. */
+
+        for (;;) {
+                char c = **p;
+
+                switch (state) {
+
+                case START:
+                        if (c == 0)
+                                goto finish;
+                        else if (strchr(WHITESPACE, c))
+                                break;
+
+                        state = VALUE;
+                        /* fallthrough */
+
+                case VALUE:
+                        if (c == 0)
+                                goto finish;
+                        else if (c == '\'')
+                                state = SINGLE_QUOTE;
+                        else if (c == '\\')
+                                state = VALUE_ESCAPE;
+                        else if (c == '\"')
+                                state = DOUBLE_QUOTE;
+                        else if (strchr(WHITESPACE, c))
+                                state = SPACE;
+                        else {
+                                if (!GREEDY_REALLOC(s, allocated, sz+2))
+                                        return -ENOMEM;
+
+                                s[sz++] = c;
+                        }
+
+                        break;
+
+                case VALUE_ESCAPE:
+                        if (c == 0)
+                                return -EINVAL;
+
+                        if (!GREEDY_REALLOC(s, allocated, sz+2))
+                                return -ENOMEM;
+
+                        s[sz++] = c;
+                        state = VALUE;
+
+                        break;
+
+                case SINGLE_QUOTE:
+                        if (c == 0)
+                                return -EINVAL;
+                        else if (c == '\'')
+                                state = VALUE;
+                        else if (c == '\\')
+                                state = SINGLE_QUOTE_ESCAPE;
+                        else {
+                                if (!GREEDY_REALLOC(s, allocated, sz+2))
+                                        return -ENOMEM;
+
+                                s[sz++] = c;
+                        }
+
+                        break;
+
+                case SINGLE_QUOTE_ESCAPE:
+                        if (c == 0)
+                                return -EINVAL;
+
+                        if (!GREEDY_REALLOC(s, allocated, sz+2))
+                                return -ENOMEM;
+
+                        s[sz++] = c;
+                        state = SINGLE_QUOTE;
+                        break;
+
+                case DOUBLE_QUOTE:
+                        if (c == 0)
+                                return -EINVAL;
+                        else if (c == '\"')
+                                state = VALUE;
+                        else if (c == '\\')
+                                state = DOUBLE_QUOTE_ESCAPE;
+                        else {
+                                if (!GREEDY_REALLOC(s, allocated, sz+2))
+                                        return -ENOMEM;
+
+                                s[sz++] = c;
+                        }
+
+                        break;
+
+                case DOUBLE_QUOTE_ESCAPE:
+                        if (c == 0)
+                                return -EINVAL;
+
+                        if (!GREEDY_REALLOC(s, allocated, sz+2))
+                                return -ENOMEM;
+
+                        s[sz++] = c;
+                        state = DOUBLE_QUOTE;
+                        break;
+
+                case SPACE:
+                        if (c == 0)
+                                goto finish;
+                        if (!strchr(WHITESPACE, c))
+                                goto finish;
+
+                        break;
+                }
+
+                (*p) ++;
+        }
+
+finish:
+        if (!s) {
+                *ret = NULL;
+                return 0;
+        }
+
+        s[sz] = 0;
+        *ret = s;
+        s = NULL;
+
+        return 1;
+}
+
+int unquote_many_words(const char **p, ...) {
+        va_list ap;
+        char **l;
+        int n = 0, i, c, r;
+
+        /* Parses a number of words from a string, stripping any
+         * quotes if necessary. */
+
+        assert(p);
+
+        /* Count how many words are expected */
+        va_start(ap, p);
+        for (;;) {
+                if (!va_arg(ap, char **))
+                        break;
+                n++;
+        }
+        va_end(ap);
+
+        if (n <= 0)
+                return 0;
+
+        /* Read all words into a temporary array */
+        l = newa0(char*, n);
+        for (c = 0; c < n; c++) {
+
+                r = unquote_first_word(p, &l[c]);
+                if (r < 0) {
+                        int j;
+
+                        for (j = 0; j < c; j++) {
+                                free(l[j]);
+                                return r;
+                        }
+                }
+
+                if (r == 0)
+                        break;
+        }
+
+        /* If we managed to parse all words, return them in the passed
+         * in parameters */
+        va_start(ap, p);
+        for (i = 0; i < n; i++) {
+                char **v;
+
+                v = va_arg(ap, char **);
+                assert(v);
+
+                *v = l[i];
+        }
+        va_end(ap);
+
+        return c;
+}
index 9913fce..87ad317 100644 (file)
@@ -22,6 +22,7 @@
 ***/
 
 #include <alloca.h>
+#include <fcntl.h>
 #include <inttypes.h>
 #include <time.h>
 #include <sys/time.h>
 #  error Unknown uid_t size
 #endif
 
+#if SIZEOF_GID_T == 4
+#  define GID_FMT "%" PRIu32
+#elif SIZEOF_GID_T == 2
+#  define GID_FMT "%" PRIu16
+#else
+#  error Unknown gid_t size
+#endif
+
+#if SIZEOF_TIME_T == 8
+#  define PRI_TIME PRIu64
+#elif SIZEOF_TIME_T == 4
+#  define PRI_TIME PRIu32
+#else
+#  error Unknown time_t size
+#endif
+
+#if SIZEOF_RLIM_T == 8
+#  define RLIM_FMT "%" PRIu64
+#elif SIZEOF_RLIM_T == 4
+#  define RLIM_FMT "%" PRIu32
+#else
+#  error Unknown rlim_t size
+#endif
+
 #include "macro.h"
+#include "missing.h"
 #include "time-util.h"
 
 /* What is interpreted as whitespace? */
 #define COMMENTS   "#;"
 #define GLOB_CHARS "*?["
 
+/* What characters are special in the shell? */
+/* must be escaped outside and inside double-quotes */
+#define SHELL_NEED_ESCAPE "\"\\`$"
+/* can be escaped or double-quoted */
+#define SHELL_NEED_QUOTES SHELL_NEED_ESCAPE GLOB_CHARS "'()<>|&;"
+
 #define FORMAT_BYTES_MAX 8
 
 #define ANSI_HIGHLIGHT_ON "\x1B[1;39m"
@@ -96,6 +128,8 @@ bool streq_ptr(const char *a, const char *b) _pure_;
 
 #define newa(t, n) ((t*) alloca(sizeof(t)*(n)))
 
+#define newa0(t, n) ((t*) alloca0(sizeof(t)*(n)))
+
 #define newdup(t, p, n) ((t*) memdup_multiply(p, sizeof(t), (n)))
 
 #define malloc0(n) (calloc((n), 1))
@@ -138,10 +172,12 @@ static inline const char *startswith_no_case(const char *s, const char *prefix)
 
 char *endswith(const char *s, const char *postfix) _pure_;
 
-bool first_word(const char *s, const char *word) _pure_;
+char *first_word(const char *s, const char *word) _pure_;
 
 int close_nointr(int fd);
-void close_nointr_nofail(int fd);
+int safe_close(int fd);
+void safe_close_pair(int p[]);
+
 void close_many(const int fds[], unsigned n_fd);
 
 int parse_size(const char *t, off_t base, off_t *size);
@@ -159,6 +195,8 @@ int safe_atolli(const char *s, long long int *ret_i);
 
 int safe_atod(const char *s, double *ret_d);
 
+int safe_atou8(const char *s, uint8_t *ret);
+
 #if __WORDSIZE == 32
 static inline int safe_atolu(const char *s, unsigned long *ret_u) {
         assert_cc(sizeof(unsigned long) == sizeof(unsigned));
@@ -199,7 +237,7 @@ static inline int safe_atoi64(const char *s, int64_t *ret_i) {
         return safe_atolli(s, (long long int*) ret_i);
 }
 
-char *split(const char *c, size_t *l, const char *separator, bool quoted, char **state);
+const char* split(const char **state, size_t *l, const char *separator, bool quoted);
 
 #define FOREACH_WORD(word, length, s, state)                            \
         _FOREACH_WORD(word, length, s, WHITESPACE, false, state)
@@ -210,11 +248,8 @@ char *split(const char *c, size_t *l, const char *separator, bool quoted, char *
 #define FOREACH_WORD_QUOTED(word, length, s, state)                     \
         _FOREACH_WORD(word, length, s, WHITESPACE, true, state)
 
-#define FOREACH_WORD_SEPARATOR_QUOTED(word, length, s, separator, state)       \
-        _FOREACH_WORD(word, length, s, separator, true, state)
-
 #define _FOREACH_WORD(word, length, s, separator, quoted, state)        \
-        for ((state) = NULL, (word) = split((s), &(length), (separator), (quoted), &(state)); (word); (word) = split((s), &(length), (separator), (quoted), &(state)))
+        for ((state) = (s), (word) = split(&(state), &(length), (separator), (quoted)); (word); (word) = split(&(state), &(length), (separator), (quoted)))
 
 pid_t get_parent_of_pid(pid_t pid, pid_t *ppid);
 int get_starttime_of_pid(pid_t pid, unsigned long long *st);
@@ -225,6 +260,7 @@ char *strnappend(const char *s, const char *suffix, size_t length);
 char *replace_env(const char *format, char **env);
 char **replace_env_argv(char **argv, char **env);
 
+int readlinkat_malloc(int fd, const char *p, char **ret);
 int readlink_malloc(const char *p, char **r);
 int readlink_and_make_absolute(const char *p, char **r);
 int readlink_and_canonicalize(const char *p, char **r);
@@ -354,7 +390,8 @@ bool fstype_is_network(const char *fstype);
 int chvt(int vt);
 
 int read_one_char(FILE *f, char *ret, usec_t timeout, bool *need_nl);
-int ask(char *ret, const char *replies, const char *text, ...) _printf_(3, 4);
+int ask_char(char *ret, const char *replies, const char *text, ...) _printf_(3, 4);
+int ask_string(char **ret, const char *text, ...) _printf_(2, 3);
 
 int reset_terminal_fd(int fd, bool switch_to_text);
 int reset_terminal(const char *name);
@@ -369,7 +406,6 @@ int ignore_signals(int sig, ...);
 int default_signals(int sig, ...);
 int sigaction_many(const struct sigaction *sa, ...);
 
-int close_pipe(int p[]);
 int fopen_temporary(const char *path, FILE **_f, char **_temp_path);
 
 ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll);
@@ -383,6 +419,7 @@ char* dirname_malloc(const char *path);
 void rename_process(const char name[8]);
 
 void sigset_add_many(sigset_t *ss, ...);
+int sigprocmask_many(int how, ...);
 
 bool hostname_is_set(void);
 
@@ -443,12 +480,15 @@ static inline const char *ansi_highlight_off(void) {
         return on_tty() ? ANSI_HIGHLIGHT_OFF : "";
 }
 
+int files_same(const char *filea, const char *fileb);
+
 int running_in_chroot(void);
 
 char *ellipsize(const char *s, size_t length, unsigned percent);
                                    /* bytes                 columns */
 char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent);
 
+int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode);
 int touch(const char *path);
 
 char *unquote(const char *s, const char *quotes);
@@ -461,6 +501,7 @@ noreturn void freeze(void);
 
 bool null_or_empty(struct stat *st) _pure_;
 int null_or_empty_path(const char *fn);
+int null_or_empty_fd(int fd);
 
 DIR *xopendirat(int dirfd, const char *name, int flags);
 
@@ -473,7 +514,7 @@ bool tty_is_console(const char *tty) _pure_;
 int vtnr_from_tty(const char *tty);
 const char *default_term_for_tty(const char *tty);
 
-void execute_directory(const char *directory, DIR *_d, char *argv[]);
+void execute_directory(const char *directory, DIR *_d, usec_t timeout, char *argv[]);
 
 int kill_and_sigcont(pid_t pid, int sig);
 
@@ -484,6 +525,8 @@ bool plymouth_running(void);
 bool hostname_is_valid(const char *s) _pure_;
 char* hostname_cleanup(char *s, bool lowercase);
 
+bool machine_name_is_valid(const char *s) _pure_;
+
 char* strshorten(char *s, size_t l);
 
 int terminal_vhangup_fd(int fd);
@@ -491,9 +534,9 @@ int terminal_vhangup(const char *name);
 
 int vt_disallocate(const char *name);
 
-int copy_file(const char *from, const char *to, int flags);
-
 int symlink_atomic(const char *from, const char *to);
+int mknod_atomic(const char *path, mode_t mode, dev_t dev);
+int mkfifo_atomic(const char *path, mode_t mode);
 
 int fchmod_umask(int fd, mode_t mode);
 
@@ -514,14 +557,17 @@ int glob_extend(char ***strv, const char *path);
 
 int dirent_ensure_type(DIR *d, struct dirent *de);
 
-int in_search_path(const char *path, char **search);
 int get_files_in_directory(const char *path, char ***list);
 
 char *strjoin(const char *x, ...) _sentinel_;
 
 bool is_main_thread(void);
 
-bool in_charset(const char *s, const char* charset) _pure_;
+static inline bool _pure_ in_charset(const char *s, const char* charset) {
+        assert(s);
+        assert(charset);
+        return s[strspn(s, charset)] == '\0';
+}
 
 int block_get_whole_disk(dev_t d, dev_t *ret);
 
@@ -606,16 +652,15 @@ static inline void freep(void *p) {
         struct __useless_struct_to_allow_trailing_semicolon__
 
 static inline void closep(int *fd) {
-        if (*fd >= 0)
-                close_nointr_nofail(*fd);
+        safe_close(*fd);
 }
 
 static inline void umaskp(mode_t *u) {
         umask(*u);
 }
 
-static inline void close_pipep(int (*p)[2]) {
-        close_pipe(*p);
+static inline void close_pairp(int (*p)[2]) {
+        safe_close_pair(*p);
 }
 
 DEFINE_TRIVIAL_CLEANUP_FUNC(FILE*, fclose);
@@ -631,17 +676,24 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(FILE*, endmntent);
 #define _cleanup_pclose_ _cleanup_(pclosep)
 #define _cleanup_closedir_ _cleanup_(closedirp)
 #define _cleanup_endmntent_ _cleanup_(endmntentp)
-#define _cleanup_close_pipe_ _cleanup_(close_pipep)
+#define _cleanup_close_pair_ _cleanup_(close_pairp)
 
 _malloc_  _alloc_(1, 2) static inline void *malloc_multiply(size_t a, size_t b) {
-        if (_unlikely_(b == 0 || a > ((size_t) -1) / b))
+        if (_unlikely_(b != 0 && a > ((size_t) -1) / b))
                 return NULL;
 
         return malloc(a * b);
 }
 
+_alloc_(2, 3) static inline void *realloc_multiply(void *p, size_t a, size_t b) {
+        if (_unlikely_(b != 0 && a > ((size_t) -1) / b))
+                return NULL;
+
+        return realloc(p, a * b);
+}
+
 _alloc_(2, 3) static inline void *memdup_multiply(const void *p, size_t a, size_t b) {
-        if (_unlikely_(b == 0 || a > ((size_t) -1) / b))
+        if (_unlikely_(b != 0 && a > ((size_t) -1) / b))
                 return NULL;
 
         return memdup(p, a * b);
@@ -650,7 +702,7 @@ _alloc_(2, 3) static inline void *memdup_multiply(const void *p, size_t a, size_
 bool filename_is_safe(const char *p) _pure_;
 bool path_is_safe(const char *p) _pure_;
 bool string_is_safe(const char *p) _pure_;
-bool string_has_cc(const char *p) _pure_;
+bool string_has_cc(const char *p, const char *ok) _pure_;
 
 /**
  * Check if a string contains any glob patterns.
@@ -666,14 +718,17 @@ void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
 bool is_locale_utf8(void);
 
 typedef enum DrawSpecialChar {
-        DRAW_TREE_VERT,
+        DRAW_TREE_VERTICAL,
         DRAW_TREE_BRANCH,
         DRAW_TREE_RIGHT,
         DRAW_TREE_SPACE,
         DRAW_TRIANGULAR_BULLET,
         DRAW_BLACK_CIRCLE,
+        DRAW_ARROW,
+        DRAW_DASH,
         _DRAW_SPECIAL_CHAR_MAX
 } DrawSpecialChar;
+
 const char *draw_special_char(DrawSpecialChar ch);
 
 char *strreplace(const char *text, const char *old_string, const char *new_string);
@@ -682,8 +737,8 @@ char *strip_tab_ansi(char **p, size_t *l);
 
 int on_ac_power(void);
 
-int search_and_fopen(const char *path, const char *mode, const char **search, FILE **_f);
-int search_and_fopen_nulstr(const char *path, const char *mode, const char *search, FILE **_f);
+int search_and_fopen(const char *path, const char *mode, const char *root, const char **search, FILE **_f);
+int search_and_fopen_nulstr(const char *path, const char *mode, const char *root, const char *search, FILE **_f);
 
 #define FOREACH_LINE(line, f, on_error)                         \
         for (;;)                                                \
@@ -716,12 +771,13 @@ void *unhexmem(const char *p, size_t l);
 char *strextend(char **x, ...) _sentinel_;
 char *strrep(const char *s, unsigned n);
 
-void* greedy_realloc(void **p, size_t *allocated, size_t need);
-void* greedy_realloc0(void **p, size_t *allocated, size_t need);
-#define GREEDY_REALLOC(array, allocated, need) \
-        greedy_realloc((void**) &(array), &(allocated), sizeof((array)[0]) * (need))
-#define GREEDY_REALLOC0(array, allocated, need) \
-        greedy_realloc0((void**) &(array), &(allocated), sizeof((array)[0]) * (need))
+void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size);
+void* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size);
+#define GREEDY_REALLOC(array, allocated, need)                          \
+        greedy_realloc((void**) &(array), &(allocated), (need), sizeof((array)[0]))
+
+#define GREEDY_REALLOC0(array, allocated, need)                         \
+        greedy_realloc0((void**) &(array), &(allocated), (need), sizeof((array)[0]))
 
 static inline void _reset_errno_(int *saved_errno) {
         errno = *saved_errno;
@@ -759,6 +815,12 @@ static inline unsigned u32ctz(uint32_t n) {
 #endif
 }
 
+static inline int log2i(int x) {
+        assert(x > 0);
+
+        return __SIZEOF_INT__ * 8 - __builtin_clz(x) - 1;
+}
+
 static inline bool logind_running(void) {
         return access("/run/systemd/seats/", F_OK) >= 0;
 }
@@ -782,16 +844,19 @@ int unlink_noerrno(const char *path);
                 (void *) memset(_new_, 0, _len_);       \
         })
 
-#define strappenda(a, b)                                \
-        ({                                              \
-                const char *_a_ = (a), *_b_ = (b);      \
-                char *_c_;                              \
-                size_t _x_, _y_;                        \
-                _x_ = strlen(_a_);                      \
-                _y_ = strlen(_b_);                      \
-                _c_ = alloca(_x_ + _y_ + 1);            \
-                strcpy(stpcpy(_c_, _a_), _b_);          \
-                _c_;                                    \
+#define strappenda(a, ...)                                       \
+        ({                                                       \
+                int _len = strlen(a);                            \
+                unsigned _i;                                     \
+                char *_d_, *_p_;                                 \
+                const char *_appendees_[] = { __VA_ARGS__ };     \
+                for (_i = 0; _i < ELEMENTSOF(_appendees_); _i++) \
+                        _len += strlen(_appendees_[_i]);         \
+                _d_ = alloca(_len + 1);                          \
+                _p_ = stpcpy(_d_, a);                            \
+                for (_i = 0; _i < ELEMENTSOF(_appendees_); _i++) \
+                        _p_ = stpcpy(_p_, _appendees_[_i]);      \
+                _d_;                                             \
         })
 
 #define procfs_file_alloca(pid, field)                                  \
@@ -852,12 +917,12 @@ static inline void qsort_safe(void *base, size_t nmemb, size_t size,
 }
 
 int proc_cmdline(char **ret);
-int parse_proc_cmdline(int (*parse_word)(const char *word));
+int parse_proc_cmdline(int (*parse_word)(const char *key, const char *value));
 
 int container_get_leader(const char *machine, pid_t *pid);
 
-int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *root_fd);
-int namespace_enter(int pidns_fd, int mntns_fd, int root_fd);
+int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int *root_fd);
+int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int root_fd);
 
 bool pid_is_alive(pid_t pid);
 bool pid_is_unwaited(pid_t pid);
@@ -874,3 +939,34 @@ int fd_warn_permissions(const char *path, int fd);
 
 unsigned long personality_from_string(const char *p);
 const char *personality_to_string(unsigned long);
+
+uint64_t physical_memory(void);
+
+char* mount_test_option(const char *haystack, const char *needle);
+
+void hexdump(FILE *f, const void *p, size_t s);
+
+union file_handle_union {
+        struct file_handle handle;
+        char padding[sizeof(struct file_handle) + MAX_HANDLE_SZ];
+};
+
+int update_reboot_param_file(const char *param);
+
+int umount_recursive(const char *target, int flags);
+
+int bind_remount_recursive(const char *prefix, bool ro);
+
+int fflush_and_check(FILE *f);
+
+char *tempfn_xxxxxx(const char *p);
+char *tempfn_random(const char *p);
+
+bool is_localhost(const char *hostname);
+
+int take_password_lock(const char *root);
+
+int is_symlink(const char *path);
+
+int unquote_first_word(const char **p, char **ret);
+int unquote_many_words(const char **p, ...) _sentinel_;
index 32996fa..30a0c03 100644 (file)
@@ -347,16 +347,20 @@ static int write_to_terminal(const char *tty, const char *message) {
         return 0;
 }
 
-int utmp_wall(const char *message, bool (*match_tty)(const char *tty)) {
+int utmp_wall(const char *message, const char *username, bool (*match_tty)(const char *tty)) {
         _cleanup_free_ char *text = NULL, *hn = NULL, *un = NULL, *tty = NULL;
         char date[FORMAT_TIMESTAMP_MAX];
         struct utmpx *u;
         int r;
 
         hn = gethostname_malloc();
-        un = getlogname_malloc();
-        if (!hn || !un)
+        if (!hn)
                 return -ENOMEM;
+        if (!username) {
+                un = getlogname_malloc();
+                if (!un)
+                        return -ENOMEM;
+        }
 
         getttyname_harder(STDIN_FILENO, &tty);
 
@@ -364,7 +368,7 @@ int utmp_wall(const char *message, bool (*match_tty)(const char *tty)) {
                      "\a\r\n"
                      "Broadcast message from %s@%s%s%s (%s):\r\n\r\n"
                      "%s\r\n\r\n",
-                     un, hn,
+                     un ?: username, hn,
                      tty ? " on " : "", strempty(tty),
                      format_timestamp(date, sizeof(date), now(CLOCK_REALTIME)),
                      message) < 0)
index 5924023..040a16e 100644 (file)
@@ -32,4 +32,4 @@ int utmp_put_runlevel(int runlevel, int previous);
 int utmp_put_dead_process(const char *id, pid_t pid, int code, int status);
 int utmp_put_init_process(const char *id, pid_t pid, pid_t sid, const char *line);
 
-int utmp_wall(const char *message, bool (*match_tty)(const char *tty));
+int utmp_wall(const char *message, const char *username, bool (*match_tty)(const char *tty));
index ec2ddcf..b436895 100644 (file)
@@ -117,7 +117,6 @@ static int detect_vm_dmi(const char **_id) {
                 /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */
                 "VMware\0"                "vmware\0"
                 "VMW\0"                   "vmware\0"
-                "Microsoft Corporation\0" "microsoft\0"
                 "innotek GmbH\0"          "oracle\0"
                 "Xen\0"                   "xen\0"
                 "Bochs\0"                 "bochs\0";
@@ -149,7 +148,7 @@ static int detect_vm_dmi(const char **_id) {
 
 /* Returns a short identifier for the various VM implementations */
 int detect_vm(const char **id) {
-        _cleanup_free_ char *hvtype = NULL, *cpuinfo_contents = NULL;
+        _cleanup_free_ char *domcap = NULL, *cpuinfo_contents = NULL;
         static thread_local int cached_found = -1;
         static thread_local const char *cached_id = NULL;
         const char *_id = NULL;
@@ -163,17 +162,37 @@ int detect_vm(const char **id) {
                 return cached_found;
         }
 
-        /* Try high-level hypervisor sysfs file first:
+        /* Try xen capabilities file first, if not found try high-level hypervisor sysfs file:
          *
-         * https://bugs.freedesktop.org/show_bug.cgi?id=61491 */
-        r = read_one_line_file("/sys/hypervisor/type", &hvtype);
+         * https://bugs.freedesktop.org/show_bug.cgi?id=77271 */
+        r = read_one_line_file("/proc/xen/capabilities", &domcap);
         if (r >= 0) {
-                if (streq(hvtype, "xen")) {
+                char *cap, *i = domcap;
+
+                while ((cap = strsep(&i, ",")))
+                        if (streq(cap, "control_d"))
+                                break;
+
+                if (!cap)  {
                         _id = "xen";
                         r = 1;
-                        goto finish;
                 }
-        } else if (r != -ENOENT)
+
+                goto finish;
+
+        } else if (r == -ENOENT) {
+                _cleanup_free_ char *hvtype = NULL;
+
+                r = read_one_line_file("/sys/hypervisor/type", &hvtype);
+                if (r >= 0) {
+                        if (streq(hvtype, "xen")) {
+                                _id = "xen";
+                                r = 1;
+                                goto finish;
+                        }
+                } else if (r != -ENOENT)
+                        return r;
+        } else
                 return r;
 
         /* this will set _id to "other" and return 0 for unknown hypervisors */
@@ -201,6 +220,23 @@ int detect_vm(const char **id) {
                 goto finish;
         }
 
+#if defined(__s390__)
+        {
+                _cleanup_free_ char *t = NULL;
+
+                r = get_status_field("/proc/sysinfo", "VM00 Control Program:", &t);
+                if (r >= 0) {
+                        if (streq(t, "z/VM"))
+                                _id = "zvm";
+                        else
+                                _id = "kvm";
+                        r = 1;
+
+                        goto finish;
+                }
+        }
+#endif
+
         r = 0;
 
 finish:
@@ -218,8 +254,8 @@ int detect_container(const char **id) {
         static thread_local int cached_found = -1;
         static thread_local const char *cached_id = NULL;
 
-        _cleanup_free_ char *e = NULL;
-        const char *_id = NULL;
+        _cleanup_free_ char *m = NULL;
+        const char *_id = NULL, *e = NULL;
         int r;
 
         if (_likely_(cached_found >= 0)) {
@@ -230,17 +266,6 @@ int detect_container(const char **id) {
                 return cached_found;
         }
 
-        /* Unfortunately many of these operations require root access
-         * in one way or another */
-
-        r = running_in_chroot();
-        if (r < 0)
-                return r;
-        if (r > 0) {
-                _id = "chroot";
-                goto finish;
-        }
-
         /* /proc/vz exists in container and outside of the container,
          * /proc/bc only outside of the container. */
         if (access("/proc/vz", F_OK) >= 0 &&
@@ -250,11 +275,32 @@ int detect_container(const char **id) {
                 goto finish;
         }
 
-        r = getenv_for_pid(1, "container", &e);
-        if (r < 0)
-                return r;
-        if (r == 0)
-                goto finish;
+        if (getpid() == 1) {
+                /* If we are PID 1 we can just check our own
+                 * environment variable */
+
+                e = getenv("container");
+                if (isempty(e)) {
+                        r = 0;
+                        goto finish;
+                }
+        } else {
+
+                /* Otherwise, PID 1 dropped this information into a
+                 * file in /run. This is better than accessing
+                 * /proc/1/environ, since we don't need CAP_SYS_PTRACE
+                 * for that. */
+
+                r = read_one_line_file("/run/systemd/container", &m);
+                if (r == -ENOENT) {
+                        r = 0;
+                        goto finish;
+                }
+                if (r < 0)
+                        return r;
+
+                e = m;
+        }
 
         /* We only recognize a selected few here, since we want to
          * enforce a redacted namespace */
@@ -267,6 +313,8 @@ int detect_container(const char **id) {
         else
                 _id = "other";
 
+        r = 1;
+
 finish:
         cached_found = r;
 
index ddbe7af..7d188d9 100644 (file)
@@ -29,7 +29,7 @@
 #include "log.h"
 
 static int watchdog_fd = -1;
-static usec_t watchdog_timeout = (usec_t) -1;
+static usec_t watchdog_timeout = USEC_INFINITY;
 
 static int update_timeout(void) {
         int r;
@@ -37,7 +37,7 @@ static int update_timeout(void) {
         if (watchdog_fd < 0)
                 return 0;
 
-        if (watchdog_timeout == (usec_t) -1)
+        if (watchdog_timeout == USEC_INFINITY)
                 return 0;
         else if (watchdog_timeout == 0) {
                 int flags;
@@ -104,7 +104,7 @@ int watchdog_set_timeout(usec_t *usec) {
 
         /* If we didn't open the watchdog yet and didn't get any
          * explicit timeout value set, don't do anything */
-        if (watchdog_fd < 0 && watchdog_timeout == (usec_t) -1)
+        if (watchdog_fd < 0 && watchdog_timeout == USEC_INFINITY)
                 return 0;
 
         if (watchdog_fd < 0)
@@ -164,6 +164,5 @@ void watchdog_close(bool disarm) {
                 }
         }
 
-        close_nointr_nofail(watchdog_fd);
-        watchdog_fd = -1;
+        watchdog_fd = safe_close(watchdog_fd);
 }
index be56b08..15c629b 100644 (file)
 #include "xml.h"
 
 enum {
+        STATE_NULL,
         STATE_TEXT,
         STATE_TAG,
         STATE_ATTRIBUTE,
 };
 
+static void inc_lines(unsigned *line, const char *s, size_t n) {
+        const char *p = s;
+
+        if (!line)
+                return;
+
+        for (;;) {
+                const char *f;
+
+                f = memchr(p, '\n', n);
+                if (!f)
+                        return;
+
+                n -= (f - p) + 1;
+                p = f + 1;
+                (*line)++;
+        }
+}
+
 /* We don't actually do real XML here. We only read a simplistic
  * subset, that is a bit less strict that XML and lacks all the more
  * complex features, like entities, or namespaces. However, we do
  * support some HTML5-like simplifications */
 
-int xml_tokenize(const char **p, char **name, void **state) {
+int xml_tokenize(const char **p, char **name, void **state, unsigned *line) {
         const char *c, *e, *b;
         char *ret;
         int t;
@@ -48,6 +68,12 @@ int xml_tokenize(const char **p, char **name, void **state) {
         t = PTR_TO_INT(*state);
         c = *p;
 
+        if (t == STATE_NULL) {
+                if (line)
+                        *line = 1;
+                t = STATE_TEXT;
+        }
+
         for (;;) {
                 if (*c == 0)
                         return XML_END;
@@ -64,6 +90,8 @@ int xml_tokenize(const char **p, char **name, void **state) {
                                 if (!ret)
                                         return -ENOMEM;
 
+                                inc_lines(line, c, e - c);
+
                                 *name = ret;
                                 *p = e;
                                 *state = INT_TO_PTR(STATE_TEXT);
@@ -80,6 +108,8 @@ int xml_tokenize(const char **p, char **name, void **state) {
                                 if (!e)
                                         return -EINVAL;
 
+                                inc_lines(line, b, e + 3 - b);
+
                                 c = e + 3;
                                 continue;
                         }
@@ -91,6 +121,8 @@ int xml_tokenize(const char **p, char **name, void **state) {
                                 if (!e)
                                         return -EINVAL;
 
+                                inc_lines(line, b, e + 2 - b);
+
                                 c = e + 2;
                                 continue;
                         }
@@ -102,6 +134,8 @@ int xml_tokenize(const char **p, char **name, void **state) {
                                 if (!e)
                                         return -EINVAL;
 
+                                inc_lines(line, b, e + 1 - b);
+
                                 c = e + 1;
                                 continue;
                         }
@@ -134,6 +168,8 @@ int xml_tokenize(const char **p, char **name, void **state) {
                         if (*b == 0)
                                 return -EINVAL;
 
+                        inc_lines(line, c, b - c);
+
                         e = b + strcspn(b, WHITESPACE "=/>");
                         if (e > b) {
                                 /* An attribute */
@@ -178,6 +214,8 @@ int xml_tokenize(const char **p, char **name, void **state) {
                                         if (!e)
                                                 return -EINVAL;
 
+                                        inc_lines(line, c, e - c);
+
                                         ret = strndup(c+1, e - c - 1);
                                         if (!ret)
                                                 return -ENOMEM;
index 18ebbd9..af71709 100644 (file)
@@ -31,4 +31,4 @@ enum {
         XML_ATTRIBUTE_VALUE
 };
 
-int xml_tokenize(const char **p, char **name, void **state);
+int xml_tokenize(const char **p, char **name, void **state, unsigned *line);
index 4a17198..9290749 100644 (file)
@@ -30,8 +30,8 @@
 #include <fcntl.h>
 #include <stddef.h>
 
-#include <systemd/sd-daemon.h>
-#include <systemd/sd-shutdown.h>
+#include "systemd/sd-daemon.h"
+#include "systemd/sd-shutdown.h"
 
 #include "log.h"
 #include "macro.h"
@@ -61,9 +61,9 @@ static int read_packet(int fd, union shutdown_buffer *_b) {
         } control = {};
         struct msghdr msghdr = {
                 .msg_iov = &iovec,
-                msghdr.msg_iovlen = 1,
-                msghdr.msg_control = &control,
-                msghdr.msg_controllen = sizeof(control),
+                .msg_iovlen = 1,
+                .msg_control = &control,
+                .msg_controllen = sizeof(control),
         };
 
         assert(fd >= 0);
@@ -120,7 +120,7 @@ static int read_packet(int fd, union shutdown_buffer *_b) {
 static void warn_wall(usec_t n, struct sd_shutdown_command *c) {
         char date[FORMAT_TIMESTAMP_MAX];
         const char *prefix;
-        char *l = NULL;
+        _cleanup_free_ char *l = NULL;
 
         assert(c);
         assert(c->warn_wall);
@@ -142,12 +142,10 @@ static void warn_wall(usec_t n, struct sd_shutdown_command *c) {
                 assert_not_reached("Unknown mode!");
 
         if (asprintf(&l, "%s%s%s%s!", c->wall_message, c->wall_message[0] ? "\n" : "",
-                     prefix, format_timestamp(date, sizeof(date), c->usec)) < 0)
+                     prefix, format_timestamp(date, sizeof(date), c->usec)) >= 0)
+                utmp_wall(l, NULL, NULL);
+        else
                 log_error("Failed to allocate wall message");
-        else {
-                utmp_wall(l, NULL);
-                free(l);
-        }
 }
 
 _const_ static usec_t when_wall(usec_t n, usec_t elapse) {
@@ -199,8 +197,8 @@ static const char *mode_to_string(enum sd_shutdown_mode m) {
 
 static int update_schedule_file(struct sd_shutdown_command *c) {
         int r;
-        FILE *f;
-        char *temp_path, *t;
+        _cleanup_fclose_ FILE *f = NULL;
+        _cleanup_free_ char *t = NULL, *temp_path = NULL;
 
         assert(c);
 
@@ -217,7 +215,6 @@ static int update_schedule_file(struct sd_shutdown_command *c) {
         r = fopen_temporary("/run/systemd/shutdown/scheduled", &f, &temp_path);
         if (r < 0) {
                 log_error("Failed to save information about scheduled shutdowns: %s", strerror(-r));
-                free(t);
                 return r;
         }
 
@@ -237,8 +234,6 @@ static int update_schedule_file(struct sd_shutdown_command *c) {
         if (!isempty(t))
                 fprintf(f, "WALL_MESSAGE=%s\n", t);
 
-        free(t);
-
         fflush(f);
 
         if (ferror(f) || rename(temp_path, "/run/systemd/shutdown/scheduled") < 0) {
@@ -249,9 +244,6 @@ static int update_schedule_file(struct sd_shutdown_command *c) {
                 unlink("/run/systemd/shutdown/scheduled");
         }
 
-        fclose(f);
-        free(temp_path);
-
         return r;
 }
 
@@ -313,7 +305,7 @@ int main(int argc, char *argv[]) {
                 }
         }
 
-        log_debug("systemd-shutdownd running as pid %lu", (unsigned long) getpid());
+        log_debug("systemd-shutdownd running as pid "PID_FMT, getpid());
 
         sd_notify(false,
                   "READY=1\n"
@@ -433,13 +425,12 @@ int main(int argc, char *argv[]) {
 
         r = EXIT_SUCCESS;
 
-        log_debug("systemd-shutdownd stopped as pid %lu", (unsigned long) getpid());
+        log_debug("systemd-shutdownd stopped as pid "PID_FMT, getpid());
 
 finish:
 
         for (i = 0; i < _FD_MAX; i++)
-                if (pollfd[i].fd >= 0)
-                        close_nointr_nofail(pollfd[i].fd);
+                safe_close(pollfd[i].fd);
 
         if (unlink_nologin)
                 unlink("/run/nologin");
index 8da050c..ca00eea 100644 (file)
 #include <string.h>
 #include <getopt.h>
 
-#include "systemd/sd-id128.h"
-#include "systemd/sd-messages.h"
+#include "sd-id128.h"
+#include "sd-messages.h"
 #include "log.h"
 #include "util.h"
 #include "strv.h"
 #include "fileio.h"
 #include "build.h"
 #include "sleep-config.h"
+#include "def.h"
 
 static char* arg_verb = NULL;
 
@@ -41,9 +42,12 @@ static int write_mode(char **modes) {
         char **mode;
 
         STRV_FOREACH(mode, modes) {
-                int k = write_string_file("/sys/power/disk", *mode);
+                int k;
+
+                k = write_string_file("/sys/power/disk", *mode);
                 if (k == 0)
                         return 0;
+
                 log_debug("Failed to write '%s' to /sys/power/disk: %s",
                           *mode, strerror(-k));
                 if (r == 0)
@@ -64,7 +68,7 @@ static int write_state(FILE **f, char **states) {
         STRV_FOREACH(state, states) {
                 int k;
 
-                k = write_string_to_file(*f, *state);
+                k = write_string_stream(*f, *state);
                 if (k == 0)
                         return 0;
                 log_debug("Failed to write '%s' to /sys/power/state: %s",
@@ -106,7 +110,7 @@ static int execute(char **modes, char **states) {
         arguments[1] = (char*) "pre";
         arguments[2] = arg_verb;
         arguments[3] = NULL;
-        execute_directory(SYSTEM_SLEEP_PATH, NULL, arguments);
+        execute_directory(SYSTEM_SLEEP_PATH, NULL, DEFAULT_TIMEOUT_USEC, arguments);
 
         log_struct(LOG_INFO,
                    MESSAGE_ID(SD_MESSAGE_SLEEP_START),
@@ -125,12 +129,12 @@ static int execute(char **modes, char **states) {
                    NULL);
 
         arguments[1] = (char*) "post";
-        execute_directory(SYSTEM_SLEEP_PATH, NULL, arguments);
+        execute_directory(SYSTEM_SLEEP_PATH, NULL, DEFAULT_TIMEOUT_USEC, arguments);
 
         return r;
 }
 
-static int help(void) {
+static void help(void) {
         printf("%s COMMAND\n\n"
                "Suspend the system, hibernate the system, or both.\n\n"
                "Commands:\n"
@@ -139,10 +143,7 @@ static int help(void) {
                "  suspend              Suspend the system\n"
                "  hibernate            Hibernate the system\n"
                "  hybrid-sleep         Both hibernate and suspend the system\n"
-               , program_invocation_short_name
-               );
-
-        return 0;
+               , program_invocation_short_name);
 }
 
 static int parse_argv(int argc, char *argv[]) {
@@ -161,10 +162,11 @@ static int parse_argv(int argc, char *argv[]) {
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "+h", options, NULL)) >= 0)
+        while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
                 switch(c) {
                 case 'h':
-                        return help();
+                        help();
+                        return 0; /* done */
 
                 case ARG_VERSION:
                         puts(PACKAGE_STRING);
index a42e5ae..f6e6672 100644 (file)
@@ -33,6 +33,7 @@
 
 #include "sd-daemon.h"
 #include "sd-event.h"
+#include "sd-resolve.h"
 #include "log.h"
 #include "socket-util.h"
 #include "util.h"
 #define BUFFER_SIZE (256 * 1024)
 #define CONNECTIONS_MAX 256
 
-#define _cleanup_freeaddrinfo_ _cleanup_(freeaddrinfop)
-DEFINE_TRIVIAL_CLEANUP_FUNC(struct addrinfo *, freeaddrinfo);
+static const char *arg_remote_host = NULL;
 
 typedef struct Context {
+        sd_event *event;
+        sd_resolve *resolve;
+
         Set *listen;
         Set *connections;
 } Context;
@@ -63,9 +66,9 @@ typedef struct Connection {
         size_t server_to_client_buffer_size, client_to_server_buffer_size;
 
         sd_event_source *server_event_source, *client_event_source;
-} Connection;
 
-static const char *arg_remote_host = NULL;
+        sd_resolve_query *resolve_query;
+} Connection;
 
 static void connection_free(Connection *c) {
         assert(c);
@@ -76,13 +79,13 @@ static void connection_free(Connection *c) {
         sd_event_source_unref(c->server_event_source);
         sd_event_source_unref(c->client_event_source);
 
-        if (c->server_fd >= 0)
-                close_nointr_nofail(c->server_fd);
-        if (c->client_fd >= 0)
-                close_nointr_nofail(c->client_fd);
+        safe_close(c->server_fd);
+        safe_close(c->client_fd);
+
+        safe_close_pair(c->server_to_client_buffer);
+        safe_close_pair(c->client_to_server_buffer);
 
-        close_pipe(c->server_to_client_buffer);
-        close_pipe(c->client_to_server_buffer);
+        sd_resolve_query_unref(c->resolve_query);
 
         free(c);
 }
@@ -101,66 +104,9 @@ static void context_free(Context *context) {
 
         set_free(context->listen);
         set_free(context->connections);
-}
-
-static int get_remote_sockaddr(union sockaddr_union *sa, socklen_t *salen) {
-        int r;
-
-        assert(sa);
-        assert(salen);
-
-        if (path_is_absolute(arg_remote_host)) {
-                sa->un.sun_family = AF_UNIX;
-                strncpy(sa->un.sun_path, arg_remote_host, sizeof(sa->un.sun_path)-1);
-                sa->un.sun_path[sizeof(sa->un.sun_path)-1] = 0;
-
-                *salen = offsetof(union sockaddr_union, un.sun_path) + strlen(sa->un.sun_path);
-
-        } else if (arg_remote_host[0] == '@') {
-                sa->un.sun_family = AF_UNIX;
-                sa->un.sun_path[0] = 0;
-                strncpy(sa->un.sun_path+1, arg_remote_host+1, sizeof(sa->un.sun_path)-2);
-                sa->un.sun_path[sizeof(sa->un.sun_path)-1] = 0;
-
-                *salen = offsetof(union sockaddr_union, un.sun_path) + 1 + strlen(sa->un.sun_path + 1);
-
-        } else {
-                _cleanup_freeaddrinfo_ struct addrinfo *result = NULL;
-                const char *node, *service;
-
-                struct addrinfo hints = {
-                        .ai_family = AF_UNSPEC,
-                        .ai_socktype = SOCK_STREAM,
-                        .ai_flags = AI_ADDRCONFIG
-                };
-
-                service = strrchr(arg_remote_host, ':');
-                if (service) {
-                        node = strndupa(arg_remote_host, service - arg_remote_host);
-                        service ++;
-                } else {
-                        node = arg_remote_host;
-                        service = "80";
-                }
-
-                log_debug("Looking up address info for %s:%s", node, service);
-                r = getaddrinfo(node, service, &hints, &result);
-                if (r != 0) {
-                        log_error("Failed to resolve host %s:%s: %s", node, service, gai_strerror(r));
-                        return -EHOSTUNREACH;
-                }
-
-                assert(result);
-                if (result->ai_addrlen > sizeof(union sockaddr_union)) {
-                        log_error("Address too long.");
-                        return -E2BIG;
-                }
-
-                memcpy(sa, result->ai_addr, result->ai_addrlen);
-                *salen = result->ai_addrlen;
-        }
 
-        return 0;
+        sd_event_unref(context->event);
+        sd_resolve_unref(context->resolve);
 }
 
 static int connection_create_pipes(Connection *c, int buffer[2], size_t *sz) {
@@ -224,8 +170,7 @@ static int connection_shovel(
                                 shoveled = true;
                         } else if (z == 0 || errno == EPIPE || errno == ECONNRESET) {
                                 *from_source = sd_event_source_unref(*from_source);
-                                close_nointr_nofail(*from);
-                                *from = -1;
+                                *from = safe_close(*from);
                         } else if (errno != EAGAIN && errno != EINTR) {
                                 log_error("Failed to splice: %m");
                                 return -errno;
@@ -239,8 +184,7 @@ static int connection_shovel(
                                 shoveled = true;
                         } else if (z == 0 || errno == EPIPE || errno == ECONNRESET) {
                                 *to_source = sd_event_source_unref(*to_source);
-                                close_nointr_nofail(*to);
-                                *to = -1;
+                                *to = safe_close(*to);
                         } else if (errno != EAGAIN && errno != EINTR) {
                                 log_error("Failed to splice: %m");
                                 return -errno;
@@ -251,7 +195,7 @@ static int connection_shovel(
         return 0;
 }
 
-static int connection_enable_event_sources(Connection *c, sd_event *event);
+static int connection_enable_event_sources(Connection *c);
 
 static int traffic_cb(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
         Connection *c = userdata;
@@ -287,7 +231,7 @@ static int traffic_cb(sd_event_source *s, int fd, uint32_t revents, void *userda
         if (c->client_fd == -1 && c->client_to_server_buffer_full <= 0)
                 goto quit;
 
-        r = connection_enable_event_sources(c, sd_event_source_get_event(s));
+        r = connection_enable_event_sources(c);
         if (r < 0)
                 goto quit;
 
@@ -298,12 +242,11 @@ quit:
         return 0; /* ignore errors, continue serving */
 }
 
-static int connection_enable_event_sources(Connection *c, sd_event *event) {
+static int connection_enable_event_sources(Connection *c) {
         uint32_t a = 0, b = 0;
         int r;
 
         assert(c);
-        assert(event);
 
         if (c->server_to_client_buffer_full > 0)
                 b |= EPOLLOUT;
@@ -318,7 +261,7 @@ static int connection_enable_event_sources(Connection *c, sd_event *event) {
         if (c->server_event_source)
                 r = sd_event_source_set_io_events(c->server_event_source, a);
         else if (c->server_fd >= 0)
-                r = sd_event_add_io(event, &c->server_event_source, c->server_fd, a, traffic_cb, c);
+                r = sd_event_add_io(c->context->event, &c->server_event_source, c->server_fd, a, traffic_cb, c);
         else
                 r = 0;
 
@@ -330,7 +273,7 @@ static int connection_enable_event_sources(Connection *c, sd_event *event) {
         if (c->client_event_source)
                 r = sd_event_source_set_io_events(c->client_event_source, b);
         else if (c->client_fd >= 0)
-                r = sd_event_add_io(event, &c->client_event_source, c->client_fd, b, traffic_cb, c);
+                r = sd_event_add_io(c->context->event, &c->client_event_source, c->client_fd, b, traffic_cb, c);
         else
                 r = 0;
 
@@ -342,6 +285,30 @@ static int connection_enable_event_sources(Connection *c, sd_event *event) {
         return 0;
 }
 
+static int connection_complete(Connection *c) {
+        int r;
+
+        assert(c);
+
+        r = connection_create_pipes(c, c->server_to_client_buffer, &c->server_to_client_buffer_size);
+        if (r < 0)
+                goto fail;
+
+        r = connection_create_pipes(c, c->client_to_server_buffer, &c->client_to_server_buffer_size);
+        if (r < 0)
+                goto fail;
+
+        r = connection_enable_event_sources(c);
+        if (r < 0)
+                goto fail;
+
+        return 0;
+
+fail:
+        connection_free(c);
+        return 0; /* ignore errors, continue serving */
+}
+
 static int connect_cb(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
         Connection *c = userdata;
         socklen_t solen;
@@ -365,75 +332,30 @@ static int connect_cb(sd_event_source *s, int fd, uint32_t revents, void *userda
 
         c->client_event_source = sd_event_source_unref(c->client_event_source);
 
-        r = connection_create_pipes(c, c->server_to_client_buffer, &c->server_to_client_buffer_size);
-        if (r < 0)
-                goto fail;
-
-        r = connection_create_pipes(c, c->client_to_server_buffer, &c->client_to_server_buffer_size);
-        if (r < 0)
-                goto fail;
-
-        r = connection_enable_event_sources(c, sd_event_source_get_event(s));
-        if (r < 0)
-                goto fail;
-
-        return 0;
+        return connection_complete(c);
 
 fail:
         connection_free(c);
         return 0; /* ignore errors, continue serving */
 }
 
-static int add_connection_socket(Context *context, sd_event *event, int fd) {
-        union sockaddr_union sa = {};
-        socklen_t salen;
-        Connection *c;
+static int connection_start(Connection *c, struct sockaddr *sa, socklen_t salen) {
         int r;
 
-        assert(context);
-        assert(event);
-        assert(fd >= 0);
-
-        if (set_size(context->connections) > CONNECTIONS_MAX) {
-                log_warning("Hit connection limit, refusing connection.");
-                close_nointr_nofail(fd);
-                return 0;
-        }
-
-        r = set_ensure_allocated(&context->connections, trivial_hash_func, trivial_compare_func);
-        if (r < 0)
-                return log_oom();
-
-        c = new0(Connection, 1);
-        if (!c)
-                return log_oom();
-
-        c->context = context;
-        c->server_fd = fd;
-        c->client_fd = -1;
-        c->server_to_client_buffer[0] = c->server_to_client_buffer[1] = -1;
-        c->client_to_server_buffer[0] = c->client_to_server_buffer[1] = -1;
-
-        r = set_put(context->connections, c);
-        if (r < 0) {
-                free(c);
-                return log_oom();
-        }
-
-        r = get_remote_sockaddr(&sa, &salen);
-        if (r < 0)
-                goto fail;
+        assert(c);
+        assert(sa);
+        assert(salen);
 
-        c->client_fd = socket(sa.sa.sa_family, SOCK_STREAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0);
+        c->client_fd = socket(sa->sa_family, SOCK_STREAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0);
         if (c->client_fd < 0) {
                 log_error("Failed to get remote socket: %m");
                 goto fail;
         }
 
-        r = connect(c->client_fd, &sa.sa, salen);
+        r = connect(c->client_fd, sa, salen);
         if (r < 0) {
                 if (errno == EINPROGRESS) {
-                        r = sd_event_add_io(event, &c->client_event_source, c->client_fd, EPOLLOUT, connect_cb, c);
+                        r = sd_event_add_io(c->context->event, &c->client_event_source, c->client_fd, EPOLLOUT, connect_cb, c);
                         if (r < 0) {
                                 log_error("Failed to add connection socket: %s", strerror(-r));
                                 goto fail;
@@ -449,7 +371,7 @@ static int add_connection_socket(Context *context, sd_event *event, int fd) {
                         goto fail;
                 }
         } else {
-                r = connection_enable_event_sources(c, event);
+                r = connection_complete(c);
                 if (r < 0)
                         goto fail;
         }
@@ -458,7 +380,125 @@ static int add_connection_socket(Context *context, sd_event *event, int fd) {
 
 fail:
         connection_free(c);
-        return 0; /* ignore non-OOM errors, continue serving */
+        return 0; /* ignore errors, continue serving */
+}
+
+static int resolve_cb(sd_resolve_query *q, int ret, const struct addrinfo *ai, void *userdata) {
+        Connection *c = userdata;
+
+        assert(q);
+        assert(c);
+
+        if (ret != 0) {
+                log_error("Failed to resolve host: %s", gai_strerror(ret));
+                goto fail;
+        }
+
+        c->resolve_query = sd_resolve_query_unref(c->resolve_query);
+
+        return connection_start(c, ai->ai_addr, ai->ai_addrlen);
+
+fail:
+        connection_free(c);
+        return 0; /* ignore errors, continue serving */
+}
+
+static int resolve_remote(Connection *c) {
+
+        static const struct addrinfo hints = {
+                .ai_family = AF_UNSPEC,
+                .ai_socktype = SOCK_STREAM,
+                .ai_flags = AI_ADDRCONFIG
+        };
+
+        union sockaddr_union sa = {};
+        const char *node, *service;
+        socklen_t salen;
+        int r;
+
+        if (path_is_absolute(arg_remote_host)) {
+                sa.un.sun_family = AF_UNIX;
+                strncpy(sa.un.sun_path, arg_remote_host, sizeof(sa.un.sun_path)-1);
+                sa.un.sun_path[sizeof(sa.un.sun_path)-1] = 0;
+
+                salen = offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path);
+
+                return connection_start(c, &sa.sa, salen);
+        }
+
+        if (arg_remote_host[0] == '@') {
+                sa.un.sun_family = AF_UNIX;
+                sa.un.sun_path[0] = 0;
+                strncpy(sa.un.sun_path+1, arg_remote_host+1, sizeof(sa.un.sun_path)-2);
+                sa.un.sun_path[sizeof(sa.un.sun_path)-1] = 0;
+
+                salen = offsetof(union sockaddr_union, un.sun_path) + 1 + strlen(sa.un.sun_path + 1);
+
+                return connection_start(c, &sa.sa, salen);
+        }
+
+        service = strrchr(arg_remote_host, ':');
+        if (service) {
+                node = strndupa(arg_remote_host, service - arg_remote_host);
+                service ++;
+        } else {
+                node = arg_remote_host;
+                service = "80";
+        }
+
+        log_debug("Looking up address info for %s:%s", node, service);
+        r = sd_resolve_getaddrinfo(c->context->resolve, &c->resolve_query, node, service, &hints, resolve_cb, c);
+        if (r < 0) {
+                log_error("Failed to resolve remote host: %s", strerror(-r));
+                goto fail;
+        }
+
+        return 0;
+
+fail:
+        connection_free(c);
+        return 0; /* ignore errors, continue serving */
+}
+
+static int add_connection_socket(Context *context, int fd) {
+        Connection *c;
+        int r;
+
+        assert(context);
+        assert(fd >= 0);
+
+        if (set_size(context->connections) > CONNECTIONS_MAX) {
+                log_warning("Hit connection limit, refusing connection.");
+                safe_close(fd);
+                return 0;
+        }
+
+        r = set_ensure_allocated(&context->connections, trivial_hash_func, trivial_compare_func);
+        if (r < 0) {
+                log_oom();
+                return 0;
+        }
+
+        c = new0(Connection, 1);
+        if (!c) {
+                log_oom();
+                return 0;
+        }
+
+        c->context = context;
+        c->server_fd = fd;
+        c->client_fd = -1;
+        c->server_to_client_buffer[0] = c->server_to_client_buffer[1] = -1;
+        c->client_to_server_buffer[0] = c->client_to_server_buffer[1] = -1;
+
+        r = set_put(context->connections, c);
+        if (r < 0) {
+                free(c);
+                log_oom();
+                return 0;
+        }
+
+        return resolve_remote(c);
 }
 
 static int accept_cb(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
@@ -479,29 +519,28 @@ static int accept_cb(sd_event_source *s, int fd, uint32_t revents, void *userdat
                 getpeername_pretty(nfd, &peer);
                 log_debug("New connection from %s", strna(peer));
 
-                r = add_connection_socket(context, sd_event_source_get_event(s), nfd);
+                r = add_connection_socket(context, nfd);
                 if (r < 0) {
                         log_error("Failed to accept connection, ignoring: %s", strerror(-r));
-                        close_nointr_nofail(fd);
+                        safe_close(fd);
                 }
         }
 
         r = sd_event_source_set_enabled(s, SD_EVENT_ONESHOT);
         if (r < 0) {
                 log_error("Error while re-enabling listener with ONESHOT: %s", strerror(-r));
-                sd_event_exit(sd_event_source_get_event(s), r);
+                sd_event_exit(context->event, r);
                 return r;
         }
 
         return 1;
 }
 
-static int add_listen_socket(Context *context, sd_event *event, int fd) {
+static int add_listen_socket(Context *context, int fd) {
         sd_event_source *source;
         int r;
 
         assert(context);
-        assert(event);
         assert(fd >= 0);
 
         r = set_ensure_allocated(&context->listen, trivial_hash_func, trivial_compare_func);
@@ -526,7 +565,7 @@ static int add_listen_socket(Context *context, sd_event *event, int fd) {
                 return r;
         }
 
-        r = sd_event_add_io(event, &source, fd, EPOLLIN, accept_cb, context);
+        r = sd_event_add_io(context->event, &source, fd, EPOLLIN, accept_cb, context);
         if (r < 0) {
                 log_error("Failed to add event source: %s", strerror(-r));
                 return r;
@@ -550,17 +589,13 @@ static int add_listen_socket(Context *context, sd_event *event, int fd) {
         return 0;
 }
 
-static int help(void) {
-
-        printf("%s [HOST:PORT]\n"
-               "%s [SOCKET]\n\n"
+static void help(void) {
+        printf("%1$s [HOST:PORT]\n"
+               "%1$s [SOCKET]\n\n"
                "Bidirectionally proxy local sockets to another (possibly remote) socket.\n\n"
                "  -h --help              Show this help\n"
                "     --version           Show package version\n",
-               program_invocation_short_name,
                program_invocation_short_name);
-
-        return 0;
 }
 
 static int parse_argv(int argc, char *argv[]) {
@@ -581,12 +616,13 @@ static int parse_argv(int argc, char *argv[]) {
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) {
+        while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
 
                 switch (c) {
 
                 case 'h':
-                        return help();
+                        help();
+                        return 0;
 
                 case ARG_VERSION:
                         puts(PACKAGE_STRING);
@@ -599,7 +635,6 @@ static int parse_argv(int argc, char *argv[]) {
                 default:
                         assert_not_reached("Unhandled option");
                 }
-        }
 
         if (optind >= argc) {
                 log_error("Not enough parameters.");
@@ -616,7 +651,6 @@ static int parse_argv(int argc, char *argv[]) {
 }
 
 int main(int argc, char *argv[]) {
-        _cleanup_event_unref_ sd_event *event = NULL;
         Context context = {};
         int r, n, fd;
 
@@ -627,13 +661,25 @@ int main(int argc, char *argv[]) {
         if (r <= 0)
                 goto finish;
 
-        r = sd_event_default(&event);
+        r = sd_event_default(&context.event);
         if (r < 0) {
                 log_error("Failed to allocate event loop: %s", strerror(-r));
                 goto finish;
         }
 
-        sd_event_set_watchdog(event, true);
+        r = sd_resolve_default(&context.resolve);
+        if (r < 0) {
+                log_error("Failed to allocate resolver: %s", strerror(-r));
+                goto finish;
+        }
+
+        r = sd_resolve_attach_event(context.resolve, context.event, 0);
+        if (r < 0) {
+                log_error("Failed to attach resolver: %s", strerror(-r));
+                goto finish;
+        }
+
+        sd_event_set_watchdog(context.event, true);
 
         n = sd_listen_fds(1);
         if (n < 0) {
@@ -647,12 +693,12 @@ int main(int argc, char *argv[]) {
         }
 
         for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd++) {
-                r = add_listen_socket(&context, event, fd);
+                r = add_listen_socket(&context, fd);
                 if (r < 0)
                         goto finish;
         }
 
-        r = sd_event_loop(event);
+        r = sd_event_loop(context.event);
         if (r < 0) {
                 log_error("Failed to run event loop: %s", strerror(-r));
                 goto finish;
index 76efacb..8ce9870 100644 (file)
@@ -48,12 +48,26 @@ static const char conf_file_dirs[] =
 #endif
         ;
 
-static char *normalize_sysctl(char *s) {
+static charnormalize_sysctl(char *s) {
         char *n;
 
-        for (n = s; *n; n++)
+        n = strpbrk(s, "/.");
+        /* If the first separator is a slash, the path is
+         * assumed to be normalized and slashes remain slashes
+         * and dots remains dots. */
+        if (!n || *n == '/')
+                return s;
+
+        /* Otherwise, dots become slashes and slashes become
+         * dots. Fun. */
+        while (n) {
                 if (*n == '.')
                         *n = '/';
+                else
+                        *n = '.';
+
+                n = strpbrk(n + 1, "/.");
+        }
 
         return s;
 }
@@ -65,7 +79,7 @@ static int apply_sysctl(const char *property, const char *value) {
 
         log_debug("Setting '%s' to '%s'", property, value);
 
-        p = new(char, sizeof("/proc/sys/") + strlen(property));
+        p = new(char, strlen("/proc/sys/") + strlen(property) + 1);
         if (!p)
                 return log_oom();
 
@@ -123,7 +137,7 @@ static int parse_file(Hashmap *sysctl_options, const char *path, bool ignore_eno
 
         assert(path);
 
-        r = search_and_fopen_nulstr(path, "re", conf_file_dirs, &f);
+        r = search_and_fopen_nulstr(path, "re", NULL, conf_file_dirs, &f);
         if (r < 0) {
                 if (ignore_enoent && r == -ENOENT)
                         return 0;
@@ -200,16 +214,13 @@ static int parse_file(Hashmap *sysctl_options, const char *path, bool ignore_eno
         return r;
 }
 
-static int help(void) {
-
+static void help(void) {
         printf("%s [OPTIONS...] [CONFIGURATION FILE...]\n\n"
                "Applies kernel sysctl settings.\n\n"
                "  -h --help             Show this help\n"
                "     --version          Show package version\n"
-               "     --prefix=PATH      Only apply rules that apply to paths with the specified prefix\n",
-               program_invocation_short_name);
-
-        return 0;
+               "     --prefix=PATH      Only apply rules that apply to paths with the specified prefix\n"
+               , program_invocation_short_name);
 }
 
 static int parse_argv(int argc, char *argv[]) {
@@ -231,12 +242,13 @@ static int parse_argv(int argc, char *argv[]) {
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) {
+        while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
 
                 switch (c) {
 
                 case 'h':
-                        return help();
+                        help();
+                        return 0;
 
                 case ARG_VERSION:
                         puts(PACKAGE_STRING);
@@ -262,7 +274,6 @@ static int parse_argv(int argc, char *argv[]) {
                 default:
                         assert_not_reached("Unhandled option");
                 }
-        }
 
         return 1;
 }
index 13b8a0c..4f22c9c 100644 (file)
 static const char *arg_dest = "/tmp";
 
 static int generate_symlink(void) {
-        struct stat st;
-        char _cleanup_free_ *p = NULL;
+        const char *p = NULL;
 
-        if (lstat("/system-update", &st) < 0) {
+        if (access("/system-update", F_OK) < 0) {
                 if (errno == ENOENT)
                         return 0;
 
@@ -46,10 +45,7 @@ static int generate_symlink(void) {
                 return -EINVAL;
         }
 
-        p = strappend(arg_dest, "/default.target");
-        if (!p)
-                return log_oom();
-
+        p = strappenda(arg_dest, "/default.target");
         if (symlink(SYSTEM_DATA_UNIT_PATH "/system-update.target", p) < 0) {
                 log_error("Failed to create symlink %s: %m", p);
                 return -errno;
index 1a45490..8a4e706 100644 (file)
@@ -77,7 +77,6 @@ static char **arg_types = NULL;
 static char **arg_states = NULL;
 static char **arg_properties = NULL;
 static bool arg_all = false;
-static bool original_stdout_is_tty;
 static enum dependency {
         DEPENDENCY_FORWARD,
         DEPENDENCY_REVERSE,
@@ -98,9 +97,11 @@ static bool arg_ignore_inhibitors = false;
 static bool arg_dry = false;
 static bool arg_quiet = false;
 static bool arg_full = false;
+static bool arg_recursive = false;
 static int arg_force = 0;
 static bool arg_ask_password = true;
 static bool arg_runtime = false;
+static UnitFilePresetMode arg_preset_mode = UNIT_FILE_PRESET_FULL;
 static char **arg_wall = NULL;
 static const char *arg_kill_who = NULL;
 static int arg_signal = SIGTERM;
@@ -135,6 +136,7 @@ static char *arg_host = NULL;
 static unsigned arg_lines = 10;
 static OutputMode arg_output = OUTPUT_SHORT;
 static bool arg_plain = false;
+
 static const struct {
         const char *verb;
         const char *method;
@@ -152,9 +154,10 @@ static const struct {
         { "force-reload",          "ReloadOrTryRestartUnit" }
 };
 
+static bool original_stdout_is_tty;
+
 static int daemon_reload(sd_bus *bus, char **args);
 static int halt_now(enum action a);
-
 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet);
 
 static char** strv_skip_first(char **strv) {
@@ -257,7 +260,7 @@ static void warn_wall(enum action a) {
                 }
 
                 if (*p) {
-                        utmp_wall(p, NULL);
+                        utmp_wall(p, NULL, NULL);
                         return;
                 }
         }
@@ -265,7 +268,7 @@ static void warn_wall(enum action a) {
         if (!table[a])
                 return;
 
-        utmp_wall(table[a], NULL);
+        utmp_wall(table[a], NULL, NULL);
 }
 
 static bool avoid_bus(void) {
@@ -288,30 +291,35 @@ static bool avoid_bus(void) {
 static int compare_unit_info(const void *a, const void *b) {
         const UnitInfo *u = a, *v = b;
         const char *d1, *d2;
+        int r;
 
+        /* First, order by machine */
+        if (!u->machine && v->machine)
+                return -1;
+        if (u->machine && !v->machine)
+                return 1;
+        if (u->machine && v->machine) {
+                r = strcasecmp(u->machine, v->machine);
+                if (r != 0)
+                        return r;
+        }
+
+        /* Second, order by unit type */
         d1 = strrchr(u->id, '.');
         d2 = strrchr(v->id, '.');
-
         if (d1 && d2) {
-                int r;
-
                 r = strcasecmp(d1, d2);
                 if (r != 0)
                         return r;
         }
 
+        /* Third, order by name */
         return strcasecmp(u->id, v->id);
 }
 
 static bool output_show_unit(const UnitInfo *u, char **patterns) {
         const char *dot;
 
-        if (!strv_isempty(arg_states))
-                return
-                        strv_contains(arg_states, u->load_state) ||
-                        strv_contains(arg_states, u->sub_state) ||
-                        strv_contains(arg_states, u->active_state);
-
         if (!strv_isempty(patterns)) {
                 char **pattern;
 
@@ -327,21 +335,21 @@ static bool output_show_unit(const UnitInfo *u, char **patterns) {
                               || u->following[0]) || u->job_id > 0);
 }
 
-static void output_units_list(const UnitInfo *unit_infos, unsigned c) {
-        unsigned id_len, max_id_len, load_len, active_len, sub_len, job_len, desc_len;
+static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
+        unsigned circle_len = 0, id_len, max_id_len, load_len, active_len, sub_len, job_len, desc_len;
         const UnitInfo *u;
         unsigned n_shown = 0;
         int job_count = 0;
 
-        max_id_len = sizeof("UNIT")-1;
-        load_len = sizeof("LOAD")-1;
-        active_len = sizeof("ACTIVE")-1;
-        sub_len = sizeof("SUB")-1;
-        job_len = sizeof("JOB")-1;
+        max_id_len = strlen("UNIT");
+        load_len = strlen("LOAD");
+        active_len = strlen("ACTIVE");
+        sub_len = strlen("SUB");
+        job_len = strlen("JOB");
         desc_len = 0;
 
         for (u = unit_infos; u < unit_infos + c; u++) {
-                max_id_len = MAX(max_id_len, strlen(u->id));
+                max_id_len = MAX(max_id_len, strlen(u->id) + (u->machine ? strlen(u->machine)+1 : 0));
                 load_len = MAX(load_len, strlen(u->load_state));
                 active_len = MAX(active_len, strlen(u->active_state));
                 sub_len = MAX(sub_len, strlen(u->sub_state));
@@ -350,13 +358,18 @@ static void output_units_list(const UnitInfo *unit_infos, unsigned c) {
                         job_len = MAX(job_len, strlen(u->job_type));
                         job_count++;
                 }
+
+                if (!arg_no_legend &&
+                    (streq(u->active_state, "failed") ||
+                     STR_IN_SET(u->load_state, "error", "not-found", "masked")))
+                        circle_len = 2;
         }
 
         if (!arg_full && original_stdout_is_tty) {
                 unsigned basic_len;
 
                 id_len = MIN(max_id_len, 25u);
-                basic_len = 5 + id_len + 5 + active_len + sub_len;
+                basic_len = circle_len + 5 + id_len + 5 + active_len + sub_len;
 
                 if (job_count)
                         basic_len += job_len + 1;
@@ -383,11 +396,18 @@ static void output_units_list(const UnitInfo *unit_infos, unsigned c) {
                 id_len = max_id_len;
 
         for (u = unit_infos; u < unit_infos + c; u++) {
-                _cleanup_free_ char *e = NULL;
-                const char *on_loaded, *off_loaded, *on = "";
-                const char *on_active, *off_active, *off = "";
+                _cleanup_free_ char *e = NULL, *j = NULL;
+                const char *on_loaded = "", *off_loaded = "";
+                const char *on_active = "", *off_active = "";
+                const char *on_circle = "", *off_circle = "";
+                const char *id;
+                bool circle = false;
 
                 if (!n_shown && !arg_no_legend) {
+
+                        if (circle_len > 0)
+                                fputs("  ", stdout);
+
                         printf("%-*s %-*s %-*s %-*s ",
                                id_len, "UNIT",
                                load_len, "LOAD",
@@ -405,23 +425,41 @@ static void output_units_list(const UnitInfo *unit_infos, unsigned c) {
 
                 n_shown++;
 
-                if (streq(u->load_state, "error") ||
-                    streq(u->load_state, "not-found")) {
-                        on_loaded = on = ansi_highlight_red();
-                        off_loaded = off = ansi_highlight_off();
-                } else
-                        on_loaded = off_loaded = "";
+                if (STR_IN_SET(u->load_state, "error", "not-found", "masked")) {
+                        on_loaded = ansi_highlight_red();
+                        on_circle = ansi_highlight_yellow();
+                        off_loaded = off_circle = ansi_highlight_off();
+                        circle = true;
+                }
 
                 if (streq(u->active_state, "failed")) {
-                        on_active = on = ansi_highlight_red();
-                        off_active = off = ansi_highlight_off();
+                        on_circle = on_active = ansi_highlight_red();
+                        off_circle = off_active = ansi_highlight_off();
+                        circle = true;
+                }
+
+                if (u->machine) {
+                        j = strjoin(u->machine, ":", u->id, NULL);
+                        if (!j)
+                                return log_oom();
+
+                        id = j;
                 } else
-                        on_active = off_active = "";
+                        id = u->id;
 
-                e = arg_full ? NULL : ellipsize(u->id, id_len, 33);
+                if (arg_full) {
+                        e = ellipsize(id, id_len, 33);
+                        if (!e)
+                                return log_oom();
+
+                        id = e;
+                }
+
+                if (circle_len > 0)
+                        printf("%s%s%s ", on_circle, circle ? draw_special_char(DRAW_BLACK_CIRCLE) : " ", off_circle);
 
                 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
-                       on, id_len, e ? e : u->id, off,
+                       on_active, id_len, id, off_active,
                        on_loaded, load_len, u->load_state, off_loaded,
                        on_active, active_len, u->active_state,
                        sub_len, u->sub_state, off_active,
@@ -437,7 +475,8 @@ static void output_units_list(const UnitInfo *unit_infos, unsigned c) {
                 const char *on, *off;
 
                 if (n_shown) {
-                        puts("\nLOAD   = Reflects whether the unit definition was properly loaded.\n"
+                        puts("\n"
+                             "LOAD   = Reflects whether the unit definition was properly loaded.\n"
                              "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
                              "SUB    = The low-level unit activation state, values depend on unit type.");
                         puts(job_count ? "JOB    = Pending job for the unit.\n" : "");
@@ -457,34 +496,45 @@ static void output_units_list(const UnitInfo *unit_infos, unsigned c) {
                                "To show all installed unit files use 'systemctl list-unit-files'.\n",
                                on, n_shown, off);
         }
+
+        return 0;
 }
 
 static int get_unit_list(
                 sd_bus *bus,
-                sd_bus_message **_reply,
-                UnitInfo **_unit_infos,
-                char **patterns) {
+                const char *machine,
+                char **patterns,
+                UnitInfo **unit_infos,
+                int c,
+                sd_bus_message **_reply) {
 
+        _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
-        _cleanup_free_ UnitInfo *unit_infos = NULL;
-        size_t size = 0;
-        int r, c = 0;
+        size_t size = c;
+        int r;
         UnitInfo u;
 
         assert(bus);
+        assert(unit_infos);
         assert(_reply);
-        assert(_unit_infos);
 
-        r = sd_bus_call_method(
+        r = sd_bus_message_new_method_call(
                         bus,
+                        &m,
                         "org.freedesktop.systemd1",
                         "/org/freedesktop/systemd1",
                         "org.freedesktop.systemd1.Manager",
-                        "ListUnits",
-                        &error,
-                        &reply,
-                        NULL);
+                        "ListUnitsFiltered");
+
+        if (r < 0)
+                return bus_log_create_error(r);
+
+        r = sd_bus_message_append_strv(m, arg_states);
+        if (r < 0)
+                return bus_log_create_error(r);
+
+        r = sd_bus_call(bus, m, 0, &error, &reply);
         if (r < 0) {
                 log_error("Failed to list units: %s", bus_error_message(&error, r));
                 return r;
@@ -495,13 +545,15 @@ static int get_unit_list(
                 return bus_log_parse_error(r);
 
         while ((r = bus_parse_unit_info(reply, &u)) > 0) {
+                u.machine = machine;
+
                 if (!output_show_unit(&u, patterns))
                         continue;
 
-                if (!GREEDY_REALLOC(unit_infos, size, c+1))
+                if (!GREEDY_REALLOC(*unit_infos, size, c+1))
                         return log_oom();
 
-                unit_infos[c++] = u;
+                (*unit_infos)[c++] = u;
         }
         if (r < 0)
                 return bus_log_parse_error(r);
@@ -513,27 +565,108 @@ static int get_unit_list(
         *_reply = reply;
         reply = NULL;
 
+        return c;
+}
+
+static void message_set_freep(Set **set) {
+        sd_bus_message *m;
+
+        while ((m = set_steal_first(*set)))
+                sd_bus_message_unref(m);
+
+        set_free(*set);
+}
+
+static int get_unit_list_recursive(
+                sd_bus *bus,
+                char **patterns,
+                UnitInfo **_unit_infos,
+                Set **_replies,
+                char ***_machines) {
+
+        _cleanup_free_ UnitInfo *unit_infos = NULL;
+        _cleanup_(message_set_freep) Set *replies;
+        sd_bus_message *reply;
+        int c, r;
+
+        assert(bus);
+        assert(_replies);
+        assert(_unit_infos);
+        assert(_machines);
+
+        replies = set_new(NULL, NULL);
+        if (!replies)
+                return log_oom();
+
+        c = get_unit_list(bus, NULL, patterns, &unit_infos, 0, &reply);
+        if (c < 0)
+                return c;
+
+        r = set_put(replies, reply);
+        if (r < 0) {
+                sd_bus_message_unref(reply);
+                return r;
+        }
+
+        if (arg_recursive) {
+                _cleanup_strv_free_ char **machines = NULL;
+                char **i;
+
+                r = sd_get_machine_names(&machines);
+                if (r < 0)
+                        return r;
+
+                STRV_FOREACH(i, machines) {
+                        _cleanup_bus_close_unref_ sd_bus *container = NULL;
+                        int k;
+
+                        r = sd_bus_open_system_container(&container, *i);
+                        if (r < 0) {
+                                log_error("Failed to connect to container %s: %s", *i, strerror(-r));
+                                continue;
+                        }
+
+                        k = get_unit_list(container, *i, patterns, &unit_infos, c, &reply);
+                        if (k < 0)
+                                return k;
+
+                        c = k;
+
+                        r = set_put(replies, reply);
+                        if (r < 0) {
+                                sd_bus_message_unref(reply);
+                                return r;
+                        }
+                }
+
+                *_machines = machines;
+                machines = NULL;
+        } else
+                *_machines = NULL;
+
         *_unit_infos = unit_infos;
         unit_infos = NULL;
 
+        *_replies = replies;
+        replies = NULL;
+
         return c;
 }
 
 static int list_units(sd_bus *bus, char **args) {
-        _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
         _cleanup_free_ UnitInfo *unit_infos = NULL;
+        _cleanup_(message_set_freep) Set *replies = NULL;
+        _cleanup_strv_free_ char **machines = NULL;
         int r;
 
         pager_open_if_enabled();
 
-        r = get_unit_list(bus, &reply, &unit_infos, strv_skip_first(args));
+        r = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
         if (r < 0)
                 return r;
 
         qsort_safe(unit_infos, r, sizeof(UnitInfo), compare_unit_info);
-        output_units_list(unit_infos, r);
-
-        return 0;
+        return output_units_list(unit_infos, r);
 }
 
 static int get_triggered_units(
@@ -610,6 +743,7 @@ static int get_listening(
 }
 
 struct socket_info {
+        const char *machine;
         const char* id;
 
         char* type;
@@ -630,6 +764,16 @@ static int socket_info_compare(const struct socket_info *a, const struct socket_
         assert(a);
         assert(b);
 
+        if (!a->machine && b->machine)
+                return -1;
+        if (a->machine && !b->machine)
+                return 1;
+        if (a->machine && b->machine) {
+                o = strcasecmp(a->machine, b->machine);
+                if (o != 0)
+                        return o;
+        }
+
         o = strcmp(a->path, b->path);
         if (o == 0)
                 o = strcmp(a->type, b->type);
@@ -639,10 +783,10 @@ static int socket_info_compare(const struct socket_info *a, const struct socket_
 
 static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
         struct socket_info *s;
-        unsigned pathlen = sizeof("LISTEN") - 1,
-                typelen = (sizeof("TYPE") - 1) * arg_show_types,
-                socklen = sizeof("UNIT") - 1,
-                servlen = sizeof("ACTIVATES") - 1;
+        unsigned pathlen = strlen("LISTEN"),
+                typelen = strlen("TYPE") * arg_show_types,
+                socklen = strlen("UNIT"),
+                servlen = strlen("ACTIVATES");
         const char *on, *off;
 
         for (s = socket_infos; s < socket_infos + cs; s++) {
@@ -652,7 +796,7 @@ static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
                 socklen = MAX(socklen, strlen(s->id));
                 if (arg_show_types)
                         typelen = MAX(typelen, strlen(s->type));
-                pathlen = MAX(pathlen, strlen(s->path));
+                pathlen = MAX(pathlen, strlen(s->path) + (s->machine ? strlen(s->machine)+1 : 0));
 
                 STRV_FOREACH(a, s->triggered)
                         tmp += strlen(*a) + 2*(a != s->triggered);
@@ -668,14 +812,24 @@ static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
                                "ACTIVATES");
 
                 for (s = socket_infos; s < socket_infos + cs; s++) {
+                        _cleanup_free_ char *j = NULL;
+                        const char *path;
                         char **a;
 
+                        if (s->machine) {
+                                j = strjoin(s->machine, ":", s->path, NULL);
+                                if (!j)
+                                        return log_oom();
+                                path = j;
+                        } else
+                                path = s->path;
+
                         if (arg_show_types)
                                 printf("%-*s %-*s %-*s",
-                                       pathlen, s->path, typelen, s->type, socklen, s->id);
+                                       pathlen, path, typelen, s->type, socklen, s->id);
                         else
                                 printf("%-*s %-*s",
-                                       pathlen, s->path, socklen, s->id);
+                                       pathlen, path, socklen, s->id);
                         STRV_FOREACH(a, s->triggered)
                                 printf("%s %s",
                                        a == s->triggered ? "" : ",", *a);
@@ -701,7 +855,8 @@ static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
 }
 
 static int list_sockets(sd_bus *bus, char **args) {
-        _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
+        _cleanup_(message_set_freep) Set *replies = NULL;
+        _cleanup_strv_free_ char **machines = NULL;
         _cleanup_free_ UnitInfo *unit_infos = NULL;
         _cleanup_free_ struct socket_info *socket_infos = NULL;
         const UnitInfo *u;
@@ -712,7 +867,7 @@ static int list_sockets(sd_bus *bus, char **args) {
 
         pager_open_if_enabled();
 
-        n = get_unit_list(bus, &reply, &unit_infos, strv_skip_first(args));
+        n = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
         if (n < 0)
                 return n;
 
@@ -740,6 +895,7 @@ static int list_sockets(sd_bus *bus, char **args) {
 
                 for (i = 0; i < c; i++)
                         socket_infos[cs + i] = (struct socket_info) {
+                                .machine = u->machine,
                                 .id = u->id,
                                 .type = listening[i*2],
                                 .path = listening[i*2 + 1],
@@ -815,16 +971,59 @@ static int get_next_elapse(
         return 0;
 }
 
+static int get_last_trigger(
+                sd_bus *bus,
+                const char *path,
+                usec_t *last) {
+
+        _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+        int r;
+
+        assert(bus);
+        assert(path);
+        assert(last);
+
+        r = sd_bus_get_property_trivial(
+                        bus,
+                        "org.freedesktop.systemd1",
+                        path,
+                        "org.freedesktop.systemd1.Timer",
+                        "LastTriggerUSec",
+                        &error,
+                        't',
+                        last);
+        if (r < 0) {
+                log_error("Failed to get last trigger time: %s", bus_error_message(&error, r));
+                return r;
+        }
+
+        return 0;
+}
+
 struct timer_info {
+        const char* machine;
         const char* id;
         usec_t next_elapse;
+        usec_t last_trigger;
         char** triggered;
 };
 
 static int timer_info_compare(const struct timer_info *a, const struct timer_info *b) {
+        int o;
+
         assert(a);
         assert(b);
 
+        if (!a->machine && b->machine)
+                return -1;
+        if (a->machine && !b->machine)
+                return 1;
+        if (a->machine && b->machine) {
+                o = strcasecmp(a->machine, b->machine);
+                if (o != 0)
+                        return o;
+        }
+
         if (a->next_elapse < b->next_elapse)
                 return -1;
         if (a->next_elapse > b->next_elapse)
@@ -836,10 +1035,12 @@ static int timer_info_compare(const struct timer_info *a, const struct timer_inf
 static int output_timers_list(struct timer_info *timer_infos, unsigned n) {
         struct timer_info *t;
         unsigned
-                nextlen = sizeof("NEXT") - 1,
-                leftlen = sizeof("LEFT") - 1,
-                unitlen = sizeof("UNIT") - 1,
-                activatelen = sizeof("ACTIVATES") - 1;
+                nextlen = strlen("NEXT"),
+                leftlen = strlen("LEFT"),
+                lastlen = strlen("LAST"),
+                passedlen = strlen("PASSED"),
+                unitlen = strlen("UNIT"),
+                activatelen = strlen("ACTIVATES");
 
         const char *on, *off;
 
@@ -859,30 +1060,57 @@ static int output_timers_list(struct timer_info *timer_infos, unsigned n) {
                         leftlen = MAX(leftlen, strlen(trel));
                 }
 
-                unitlen = MAX(unitlen, strlen(t->id));
+                if (t->last_trigger > 0) {
+                        char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
+
+                        format_timestamp(tstamp, sizeof(tstamp), t->last_trigger);
+                        lastlen = MAX(lastlen, strlen(tstamp) + 1);
+
+                        format_timestamp_relative(trel, sizeof(trel), t->last_trigger);
+                        passedlen = MAX(passedlen, strlen(trel));
+                }
+
+                unitlen = MAX(unitlen, strlen(t->id) + (t->machine ? strlen(t->machine)+1 : 0));
 
                 STRV_FOREACH(a, t->triggered)
                         ul += strlen(*a) + 2*(a != t->triggered);
+
                 activatelen = MAX(activatelen, ul);
         }
 
         if (n > 0) {
                 if (!arg_no_legend)
-                        printf("%-*s %-*s %-*s %s\n",
-                               nextlen, "NEXT",
-                               leftlen, "LEFT",
-                               unitlen, "UNIT",
-                                        "ACTIVATES");
+                        printf("%-*s %-*s %-*s %-*s %-*s %s\n",
+                               nextlen,   "NEXT",
+                               leftlen,   "LEFT",
+                               lastlen,   "LAST",
+                               passedlen, "PASSED",
+                               unitlen,   "UNIT",
+                                          "ACTIVATES");
 
                 for (t = timer_infos; t < timer_infos + n; t++) {
-                        char tstamp[FORMAT_TIMESTAMP_MAX] = "n/a", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
+                        _cleanup_free_ char *j = NULL;
+                        const char *unit;
+                        char tstamp1[FORMAT_TIMESTAMP_MAX] = "n/a", trel1[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
+                        char tstamp2[FORMAT_TIMESTAMP_MAX] = "n/a", trel2[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
                         char **a;
 
-                        format_timestamp(tstamp, sizeof(tstamp), t->next_elapse);
-                        format_timestamp_relative(trel, sizeof(trel), t->next_elapse);
+                        format_timestamp(tstamp1, sizeof(tstamp1), t->next_elapse);
+                        format_timestamp_relative(trel1, sizeof(trel1), t->next_elapse);
+
+                        format_timestamp(tstamp2, sizeof(tstamp2), t->last_trigger);
+                        format_timestamp_relative(trel2, sizeof(trel2), t->last_trigger);
+
+                        if (t->machine) {
+                                j = strjoin(t->machine, ":", t->id, NULL);
+                                if (!j)
+                                        return log_oom();
+                                unit = j;
+                        } else
+                                unit = t->id;
 
-                        printf("%-*s %-*s %-*s",
-                               nextlen, tstamp, leftlen, trel, unitlen, t->id);
+                        printf("%-*s %-*s %-*s %-*s %-*s",
+                               nextlen, tstamp1, leftlen, trel1, lastlen, tstamp2, passedlen, trel2, unitlen, unit);
 
                         STRV_FOREACH(a, t->triggered)
                                 printf("%s %s",
@@ -914,7 +1142,7 @@ static usec_t calc_next_elapse(dual_timestamp *nw, dual_timestamp *next) {
         assert(nw);
         assert(next);
 
-        if (next->monotonic != (usec_t) -1 && next->monotonic > 0) {
+        if (next->monotonic != USEC_INFINITY && next->monotonic > 0) {
                 usec_t converted;
 
                 if (next->monotonic > nw->monotonic)
@@ -922,7 +1150,7 @@ static usec_t calc_next_elapse(dual_timestamp *nw, dual_timestamp *next) {
                 else
                         converted = nw->realtime - (nw->monotonic - next->monotonic);
 
-                if (next->realtime != (usec_t) -1 && next->realtime > 0)
+                if (next->realtime != USEC_INFINITY && next->realtime > 0)
                         next_elapse = MIN(converted, next->realtime);
                 else
                         next_elapse = converted;
@@ -934,8 +1162,8 @@ static usec_t calc_next_elapse(dual_timestamp *nw, dual_timestamp *next) {
 }
 
 static int list_timers(sd_bus *bus, char **args) {
-
-        _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
+        _cleanup_(message_set_freep) Set *replies = NULL;
+        _cleanup_strv_free_ char **machines = NULL;
         _cleanup_free_ struct timer_info *timer_infos = NULL;
         _cleanup_free_ UnitInfo *unit_infos = NULL;
         struct timer_info *t;
@@ -947,7 +1175,7 @@ static int list_timers(sd_bus *bus, char **args) {
 
         pager_open_if_enabled();
 
-        n = get_unit_list(bus, &reply, &unit_infos, strv_skip_first(args));
+        n = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
         if (n < 0)
                 return n;
 
@@ -956,7 +1184,7 @@ static int list_timers(sd_bus *bus, char **args) {
         for (u = unit_infos; u < unit_infos + n; u++) {
                 _cleanup_strv_free_ char **triggered = NULL;
                 dual_timestamp next = {};
-                usec_t m;
+                usec_t m, last = 0;
 
                 if (!endswith(u->id, ".timer"))
                         continue;
@@ -969,6 +1197,8 @@ static int list_timers(sd_bus *bus, char **args) {
                 if (r < 0)
                         goto cleanup;
 
+                get_last_trigger(bus, u->unit_path, &last);
+
                 if (!GREEDY_REALLOC(timer_infos, size, c+1)) {
                         r = log_oom();
                         goto cleanup;
@@ -977,8 +1207,10 @@ static int list_timers(sd_bus *bus, char **args) {
                 m = calc_next_elapse(&nw, &next);
 
                 timer_infos[c++] = (struct timer_info) {
+                        .machine = u->machine,
                         .id = u->id,
                         .next_elapse = m,
+                        .last_trigger = last,
                         .triggered = triggered,
                 };
 
@@ -1031,11 +1263,11 @@ static bool output_show_unit_file(const UnitFileList *u, char **patterns) {
 }
 
 static void output_unit_file_list(const UnitFileList *units, unsigned c) {
-        unsigned max_id_len, id_cols, state_cols, n_shown = 0;
+        unsigned max_id_len, id_cols, state_cols;
         const UnitFileList *u;
 
-        max_id_len = sizeof("UNIT FILE")-1;
-        state_cols = sizeof("STATE")-1;
+        max_id_len = strlen("UNIT FILE");
+        state_cols = strlen("STATE");
 
         for (u = units; u < units + c; u++) {
                 max_id_len = MAX(max_id_len, strlen(basename(u->path)));
@@ -1062,8 +1294,6 @@ static void output_unit_file_list(const UnitFileList *units, unsigned c) {
                 const char *on, *off;
                 const char *id;
 
-                n_shown++;
-
                 if (u->state == UNIT_FILE_MASKED ||
                     u->state == UNIT_FILE_MASKED_RUNTIME ||
                     u->state == UNIT_FILE_DISABLED ||
@@ -1086,7 +1316,7 @@ static void output_unit_file_list(const UnitFileList *units, unsigned c) {
         }
 
         if (!arg_no_legend)
-                printf("\n%u unit files listed.\n", n_shown);
+                printf("\n%u unit files listed.\n", c);
 }
 
 static int list_unit_files(sd_bus *bus, char **args) {
@@ -1203,7 +1433,7 @@ static int list_dependencies_print(const char *name, int level, unsigned int bra
                                 printf("%s...\n",max_len % 2 ? "" : " ");
                                 return 0;
                         }
-                        printf("%s", draw_special_char(branches & (1 << i) ? DRAW_TREE_VERT : DRAW_TREE_SPACE));
+                        printf("%s", draw_special_char(branches & (1 << i) ? DRAW_TREE_VERTICAL : DRAW_TREE_SPACE));
                 }
                 len += 2;
 
@@ -1371,9 +1601,9 @@ static int list_dependencies_one(
 
                 state = check_one_unit(bus, *c, "activating\0active\0reloading\0", true);
                 if (state > 0)
-                        printf("%s%s%s", ansi_highlight_green(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
+                        printf("%s%s%s ", ansi_highlight_green(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
                 else
-                        printf("%s%s%s", ansi_highlight_red(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
+                        printf("%s%s%s ", ansi_highlight_red(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
 
                 r = list_dependencies_print(*c, level, branches, c[1] == NULL);
                 if (r < 0)
@@ -1414,6 +1644,242 @@ static int list_dependencies(sd_bus *bus, char **args) {
         return list_dependencies_one(bus, u, 0, &units, 0);
 }
 
+struct machine_info {
+        bool is_host;
+        char *name;
+        char *state;
+        char *control_group;
+        uint32_t n_failed_units;
+        uint32_t n_jobs;
+        usec_t timestamp;
+};
+
+static const struct bus_properties_map machine_info_property_map[] = {
+        { "SystemState",        "s", NULL, offsetof(struct machine_info, state)          },
+        { "NJobs",              "u", NULL, offsetof(struct machine_info, n_jobs)         },
+        { "NFailedUnits",       "u", NULL, offsetof(struct machine_info, n_failed_units) },
+        { "ControlGroup",       "s", NULL, offsetof(struct machine_info, control_group)  },
+        { "UserspaceTimestamp", "t", NULL, offsetof(struct machine_info, timestamp)      },
+        {}
+};
+
+static void free_machines_list(struct machine_info *machine_infos, int n) {
+        int i;
+
+        if (!machine_infos)
+                return;
+
+        for (i = 0; i < n; i++) {
+                free(machine_infos[i].name);
+                free(machine_infos[i].state);
+                free(machine_infos[i].control_group);
+        }
+
+        free(machine_infos);
+}
+
+static int compare_machine_info(const void *a, const void *b) {
+        const struct machine_info *u = a, *v = b;
+
+        if (u->is_host != v->is_host)
+                return u->is_host > v->is_host ? -1 : 1;
+
+        return strcasecmp(u->name, v->name);
+}
+
+static int get_machine_properties(sd_bus *bus, struct machine_info *mi) {
+        _cleanup_bus_close_unref_ sd_bus *container = NULL;
+        int r;
+
+        assert(mi);
+
+        if (!bus) {
+                r = sd_bus_open_system_container(&container, mi->name);
+                if (r < 0)
+                        return r;
+
+                bus = container;
+        }
+
+        r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, mi);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+static bool output_show_machine(const char *name, char **patterns) {
+        char **i;
+
+        assert(name);
+
+        if (strv_isempty(patterns))
+                return true;
+
+        STRV_FOREACH(i, patterns)
+                if (fnmatch(*i, name, FNM_NOESCAPE) == 0)
+                        return true;
+
+        return false;
+}
+
+static int get_machine_list(
+                sd_bus *bus,
+                struct machine_info **_machine_infos,
+                char **patterns) {
+
+        struct machine_info *machine_infos = NULL;
+        _cleanup_strv_free_ char **m = NULL;
+        _cleanup_free_ char *hn = NULL;
+        size_t sz = 0;
+        char **i;
+        int c = 0;
+
+        hn = gethostname_malloc();
+        if (!hn)
+                return log_oom();
+
+        if (output_show_machine(hn, patterns)) {
+                if (!GREEDY_REALLOC0(machine_infos, sz, c+1))
+                        return log_oom();
+
+                machine_infos[c].is_host = true;
+                machine_infos[c].name = hn;
+                hn = NULL;
+
+                get_machine_properties(bus, &machine_infos[c]);
+                c++;
+        }
+
+        sd_get_machine_names(&m);
+        STRV_FOREACH(i, m) {
+                _cleanup_free_ char *class = NULL;
+
+                if (!output_show_machine(*i, patterns))
+                        continue;
+
+                sd_machine_get_class(*i, &class);
+                if (!streq_ptr(class, "container"))
+                        continue;
+
+                if (!GREEDY_REALLOC0(machine_infos, sz, c+1)) {
+                        free_machines_list(machine_infos, c);
+                        return log_oom();
+                }
+
+                machine_infos[c].is_host = false;
+                machine_infos[c].name = strdup(*i);
+                if (!machine_infos[c].name) {
+                        free_machines_list(machine_infos, c);
+                        return log_oom();
+                }
+
+                get_machine_properties(NULL, &machine_infos[c]);
+                c++;
+        }
+
+        *_machine_infos = machine_infos;
+        return c;
+}
+
+static void output_machines_list(struct machine_info *machine_infos, unsigned n) {
+        struct machine_info *m;
+        unsigned
+                circle_len = 0,
+                namelen = sizeof("NAME") - 1,
+                statelen = sizeof("STATE") - 1,
+                failedlen = sizeof("FAILED") - 1,
+                jobslen = sizeof("JOBS") - 1;
+
+        assert(machine_infos || n == 0);
+
+        for (m = machine_infos; m < machine_infos + n; m++) {
+                namelen = MAX(namelen, strlen(m->name) + (m->is_host ? sizeof(" (host)") - 1 : 0));
+                statelen = MAX(statelen, m->state ? strlen(m->state) : 0);
+                failedlen = MAX(failedlen, DECIMAL_STR_WIDTH(m->n_failed_units));
+                jobslen = MAX(jobslen, DECIMAL_STR_WIDTH(m->n_jobs));
+
+                if (!arg_no_legend && !streq_ptr(m->state, "running"))
+                        circle_len = 2;
+        }
+
+        if (!arg_no_legend) {
+                if (circle_len > 0)
+                        fputs("  ", stdout);
+
+                printf("%-*s %-*s %-*s %-*s\n",
+                         namelen, "NAME",
+                        statelen, "STATE",
+                       failedlen, "FAILED",
+                         jobslen, "JOBS");
+        }
+
+        for (m = machine_infos; m < machine_infos + n; m++) {
+                const char *on_state = "", *off_state = "";
+                const char *on_failed = "", *off_failed = "";
+                bool circle = false;
+
+                if (streq_ptr(m->state, "degraded")) {
+                        on_state = ansi_highlight_red();
+                        off_state = ansi_highlight_off();
+                        circle = true;
+                } else if (!streq_ptr(m->state, "running")) {
+                        on_state = ansi_highlight_yellow();
+                        off_state = ansi_highlight_off();
+                        circle = true;
+                }
+
+                if (m->n_failed_units > 0) {
+                        on_failed = ansi_highlight_red();
+                        off_failed = ansi_highlight_off();
+                } else
+                        on_failed = off_failed = "";
+
+                if (circle_len > 0)
+                        printf("%s%s%s ", on_state, circle ? draw_special_char(DRAW_BLACK_CIRCLE) : " ", off_state);
+
+                if (m->is_host)
+                        printf("%-*s (host) %s%-*s%s %s%*u%s %*u\n",
+                               (int) (namelen - (sizeof(" (host)")-1)), strna(m->name),
+                               on_state, statelen, strna(m->state), off_state,
+                               on_failed, failedlen, m->n_failed_units, off_failed,
+                               jobslen, m->n_jobs);
+                else
+                        printf("%-*s %s%-*s%s %s%*u%s %*u\n",
+                               namelen, strna(m->name),
+                               on_state, statelen, strna(m->state), off_state,
+                               on_failed, failedlen, m->n_failed_units, off_failed,
+                               jobslen, m->n_jobs);
+        }
+
+        if (!arg_no_legend)
+                printf("\n%u machines listed.\n", n);
+}
+
+static int list_machines(sd_bus *bus, char **args) {
+        struct machine_info *machine_infos = NULL;
+        int r;
+
+        assert(bus);
+
+        if (geteuid() != 0) {
+                log_error("Must be root.");
+                return -EPERM;
+        }
+
+        pager_open_if_enabled();
+
+        r = get_machine_list(bus, &machine_infos, strv_skip_first(args));
+        if (r < 0)
+                return r;
+
+        qsort_safe(machine_infos, r, sizeof(struct machine_info), compare_machine_info);
+        output_machines_list(machine_infos, r);
+        free_machines_list(machine_infos, r);
+
+        return 0;
+}
+
 static int get_default(sd_bus *bus, char **args) {
         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
@@ -1462,9 +1928,9 @@ static void dump_unit_file_changes(const UnitFileChange *changes, unsigned n_cha
 
         for (i = 0; i < n_changes; i++) {
                 if (changes[i].type == UNIT_FILE_SYMLINK)
-                        log_info("ln -s '%s' '%s'", changes[i].source, changes[i].path);
+                        log_info("Created symlink from %s to %s.", changes[i].path, changes[i].source);
                 else
-                        log_info("rm '%s'", changes[i].path);
+                        log_info("Removed symlink %s.", changes[i].path);
         }
 }
 
@@ -1479,9 +1945,9 @@ static int deserialize_and_dump_unit_file_changes(sd_bus_message *m) {
         while ((r = sd_bus_message_read(m, "(sss)", &type, &path, &source)) > 0) {
                 if (!arg_quiet) {
                         if (streq(type, "symlink"))
-                                log_info("ln -s '%s' '%s'", source, path);
+                                log_info("Created symlink from %s to %s.", path, source);
                         else
-                                log_info("rm '%s'", path);
+                                log_info("Removed symlink %s.", path);
                 }
         }
         if (r < 0)
@@ -1505,7 +1971,7 @@ static int set_default(sd_bus *bus, char **args) {
                 return log_oom();
 
         if (!bus || avoid_bus()) {
-                r = unit_file_set_default(arg_scope, arg_root, unit, arg_force, &changes, &n_changes);
+                r = unit_file_set_default(arg_scope, arg_root, unit, true, &changes, &n_changes);
                 if (r < 0) {
                         log_error("Failed to set default target: %s", strerror(-r));
                         return r;
@@ -1527,7 +1993,7 @@ static int set_default(sd_bus *bus, char **args) {
                                 "SetDefaultTarget",
                                 &error,
                                 &reply,
-                                "sb", unit, arg_force);
+                                "sb", unit, true);
                 if (r < 0) {
                         log_error("Failed to set default target: %s", bus_error_message(&error, -r));
                         return r;
@@ -1537,7 +2003,7 @@ static int set_default(sd_bus *bus, char **args) {
                 if (r < 0)
                         return r;
 
-                /* Try to reload if enabeld */
+                /* Try to reload if enabled */
                 if (!arg_no_reload)
                         r = daemon_reload(bus, args);
                 else
@@ -1572,10 +2038,10 @@ static void output_jobs_list(const struct job_info* jobs, unsigned n, bool skipp
 
         pager_open_if_enabled();
 
-        id_len = sizeof("JOB")-1;
-        unit_len = sizeof("UNIT")-1;
-        type_len = sizeof("TYPE")-1;
-        state_len = sizeof("STATE")-1;
+        id_len = strlen("JOB");
+        unit_len = strlen("UNIT");
+        type_len = strlen("TYPE");
+        state_len = strlen("STATE");
 
         for (j = jobs; j < jobs + n; j++) {
                 uint32_t id = j->id;
@@ -1625,16 +2091,17 @@ static void output_jobs_list(const struct job_info* jobs, unsigned n, bool skipp
 }
 
 static bool output_show_job(struct job_info *job, char **patterns) {
-        if (!strv_isempty(patterns)) {
-                char **pattern;
+        char **pattern;
 
-                STRV_FOREACH(pattern, patterns)
-                        if (fnmatch(*pattern, job->name, FNM_NOESCAPE) == 0)
-                                return true;
-                return false;
-        }
+        assert(job);
+
+        if (strv_isempty(patterns))
+                return true;
 
-        return true;
+        STRV_FOREACH(pattern, patterns)
+                if (fnmatch(*pattern, job->name, FNM_NOESCAPE) == 0)
+                        return true;
+        return false;
 }
 
 static int list_jobs(sd_bus *bus, char **args) {
@@ -1841,6 +2308,7 @@ static int enable_wait_for_jobs(sd_bus *bus) {
 
         r = sd_bus_add_match(
                         bus,
+                        NULL,
                         "type='signal',"
                         "sender='org.freedesktop.systemd1',"
                         "interface='org.freedesktop.systemd1.Manager',"
@@ -1900,13 +2368,14 @@ static int check_wait_response(WaitData *d) {
 }
 
 static int wait_for_jobs(sd_bus *bus, Set *s) {
+        _cleanup_bus_slot_unref_ sd_bus_slot *slot = NULL;
         WaitData d = { .set = s };
         int r = 0, q;
 
         assert(bus);
         assert(s);
 
-        q = sd_bus_add_filter(bus, wait_filter, &d);
+        q = sd_bus_add_filter(bus, &slot, wait_filter, &d);
         if (q < 0)
                 return log_oom();
 
@@ -1934,10 +2403,6 @@ static int wait_for_jobs(sd_bus *bus, Set *s) {
                 d.result = NULL;
         }
 
-        q = sd_bus_remove_filter(bus, wait_filter, &d);
-        if (q < 0 && r == 0)
-                r = q;
-
         return r;
 }
 
@@ -2151,7 +2616,6 @@ static int start_unit_one(
 
 static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***ret) {
 
-        _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
         _cleanup_strv_free_ char **mangled = NULL, **globs = NULL;
         char **name;
         int r = 0, i;
@@ -2167,21 +2631,20 @@ static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***r
                         return log_oom();
 
                 if (string_is_glob(t))
-                        r = strv_push(&globs, t);
+                        r = strv_consume(&globs, t);
                 else
-                        r = strv_push(&mangled, t);
-                if (r < 0) {
-                        free(t);
+                        r = strv_consume(&mangled, t);
+                if (r < 0)
                         return log_oom();
-                }
         }
 
         /* Query the manager only if any of the names are a glob, since
          * this is fairly expensive */
         if (!strv_isempty(globs)) {
+                _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
                 _cleanup_free_ UnitInfo *unit_infos = NULL;
 
-                r = get_unit_list(bus, &reply, &unit_infos, globs);
+                r = get_unit_list(bus, NULL, globs, &unit_infos, 0, &reply);
                 if (r < 0)
                         return r;
 
@@ -2192,6 +2655,7 @@ static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***r
 
         *ret = mangled;
         mangled = NULL; /* do not free */
+
         return 0;
 }
 
@@ -2423,8 +2887,8 @@ static int check_inhibitors(sd_bus *bus, enum action a) {
                 get_process_comm(pid, &comm);
                 user = uid_to_name(uid);
 
-                log_warning("Operation inhibited by \"%s\" (PID %lu \"%s\", user %s), reason is \"%s\".",
-                            who, (unsigned long) pid, strna(comm), strna(user), why);
+                log_warning("Operation inhibited by \"%s\" (PID "PID_FMT" \"%s\", user %s), reason is \"%s\".",
+                            who, pid, strna(comm), strna(user), why);
 
                 c++;
         }
@@ -2706,6 +3170,7 @@ typedef struct UnitStatusInfo {
         const char *status_text;
         const char *pid_file;
         bool running:1;
+        int status_errno;
 
         usec_t start_timestamp;
         usec_t exit_timestamp;
@@ -2744,7 +3209,7 @@ static void print_status_info(
                 bool *ellipsized) {
 
         ExecStatusInfo *p;
-        const char *on, *off, *ss;
+        const char *active_on, *active_off, *on, *off, *ss;
         usec_t timestamp;
         char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
         char since2[FORMAT_TIMESTAMP_MAX], *s2;
@@ -2762,7 +3227,16 @@ static void print_status_info(
         /* This shows pretty information about a unit. See
          * print_property() for a low-level property printer */
 
-        printf("%s", strna(i->id));
+        if (streq_ptr(i->active_state, "failed")) {
+                active_on = ansi_highlight_red();
+                active_off = ansi_highlight_off();
+        } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
+                active_on = ansi_highlight_green();
+                active_off = ansi_highlight_off();
+        } else
+                active_on = active_off = "";
+
+        printf("%s%s%s %s", active_on, draw_special_char(DRAW_BLACK_CIRCLE), active_off, strna(i->id));
 
         if (i->description && !streq_ptr(i->id, i->description))
                 printf(" - %s", i->description);
@@ -2821,22 +3295,12 @@ static void print_status_info(
         }
 
         ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
-
-        if (streq_ptr(i->active_state, "failed")) {
-                on = ansi_highlight_red();
-                off = ansi_highlight_off();
-        } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
-                on = ansi_highlight_green();
-                off = ansi_highlight_off();
-        } else
-                on = off = "";
-
         if (ss)
                 printf("   Active: %s%s (%s)%s",
-                       on, strna(i->active_state), ss, off);
+                       active_on, strna(i->active_state), ss, active_off);
         else
                 printf("   Active: %s%s%s",
-                       on, strna(i->active_state), off);
+                       active_on, strna(i->active_state), active_off);
 
         if (!isempty(i->result) && !streq(i->result, "success"))
                 printf(" (Result: %s)", i->result);
@@ -2978,9 +3442,12 @@ static void print_status_info(
 
         if (i->status_text)
                 printf("   Status: \"%s\"\n", i->status_text);
+        if (i->status_errno > 0)
+                printf("    Error: %i (%s)\n", i->status_errno, strerror(i->status_errno));
 
         if (i->control_group &&
-            (i->main_pid > 0 || i->control_pid > 0 || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0)) {
+            (i->main_pid > 0 || i->control_pid > 0 ||
+             ((arg_transport != BUS_TRANSPORT_LOCAL && arg_transport != BUS_TRANSPORT_CONTAINER) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0))) {
                 unsigned c;
 
                 printf("   CGroup: %s\n", i->control_group);
@@ -2988,7 +3455,7 @@ static void print_status_info(
                 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
                         unsigned k = 0;
                         pid_t extra[2];
-                        char prefix[] = "           ";
+                        static const char prefix[] = "           ";
 
                         c = columns();
                         if (c > sizeof(prefix) - 1)
@@ -3002,13 +3469,11 @@ static void print_status_info(
                         if (i->control_pid > 0)
                                 extra[k++] = i->control_pid;
 
-                        show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix,
-                                                      c, false, extra, k, flags);
+                        show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix, c, false, extra, k, flags);
                 }
         }
 
         if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
-                printf("\n");
                 show_journal_by_unit(stdout,
                                      i->id,
                                      arg_output,
@@ -3016,7 +3481,7 @@ static void print_status_info(
                                      i->inactive_exit_timestamp_monotonic,
                                      arg_lines,
                                      getuid(),
-                                     flags,
+                                     flags | OUTPUT_BEGIN_NEWLINE,
                                      arg_scope == UNIT_FILE_SYSTEM,
                                      ellipsized);
         }
@@ -3038,50 +3503,11 @@ static void show_unit_help(UnitStatusInfo *i) {
                 return;
         }
 
-        STRV_FOREACH(p, i->documentation) {
-
-                if (startswith(*p, "man:")) {
-                        const char *args[4] = { "man", NULL, NULL, NULL };
-                        _cleanup_free_ char *page = NULL, *section = NULL;
-                        char *e = NULL;
-                        pid_t pid;
-                        size_t k;
-
-                        k = strlen(*p);
-
-                        if ((*p)[k-1] == ')')
-                                e = strrchr(*p, '(');
-
-                        if (e) {
-                                page = strndup((*p) + 4, e - *p - 4);
-                                section = strndup(e + 1, *p + k - e - 2);
-                                if (!page || !section) {
-                                        log_oom();
-                                        return;
-                                }
-
-                                args[1] = section;
-                                args[2] = page;
-                        } else
-                                args[1] = *p + 4;
-
-                        pid = fork();
-                        if (pid < 0) {
-                                log_error("Failed to fork: %m");
-                                continue;
-                        }
-
-                        if (pid == 0) {
-                                /* Child */
-                                execvp(args[0], (char**) args);
-                                log_error("Failed to execute man: %m");
-                                _exit(EXIT_FAILURE);
-                        }
-
-                        wait_for_terminate(pid, NULL);
-                } else
+        STRV_FOREACH(p, i->documentation)
+                if (startswith(*p, "man:"))
+                        show_man_page(*p + 4, false);
+                else
                         log_info("Can't show: %s", *p);
-        }
 }
 
 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
@@ -3199,6 +3625,8 @@ static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *
                         i->exit_code = (int) j;
                 else if (streq(name, "ExecMainStatus"))
                         i->exit_status = (int) j;
+                else if (streq(name, "StatusErrno"))
+                        i->status_errno = (int) j;
 
                 break;
         }
@@ -3758,8 +4186,8 @@ static int show_one(
             streq(verb, "status")) {
                 /* According to LSB: "program not running" */
                 /* 0: program is running or service is OK
-                 * 1: program is dead and /var/run pid file exists
-                 * 2: program is dead and /var/lock lock file exists
+                 * 1: program is dead and /run PID file exists
+                 * 2: program is dead and /run/lock lock file exists
                  * 3: program is not running
                  * 4: program or service status is unknown
                  */
@@ -3797,7 +4225,7 @@ static int get_unit_dbus_path_by_pid(
                         &reply,
                         "u", pid);
         if (r < 0) {
-                log_error("Failed to get unit for PID %lu: %s", (unsigned long) pid, bus_error_message(&error, r));
+                log_error("Failed to get unit for PID "PID_FMT": %s", pid, bus_error_message(&error, r));
                 return r;
         }
 
@@ -3824,9 +4252,9 @@ static int show_all(
         _cleanup_free_ UnitInfo *unit_infos = NULL;
         const UnitInfo *u;
         unsigned c;
-        int r;
+        int r, ret = 0;
 
-        r = get_unit_list(bus, &reply, &unit_infos, NULL);
+        r = get_unit_list(bus, NULL, NULL, &unit_infos, 0, &reply);
         if (r < 0)
                 return r;
 
@@ -3844,105 +4272,78 @@ static int show_all(
                         return log_oom();
 
                 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
-                if (r != 0)
+                if (r < 0)
                         return r;
+                else if (r > 0 && ret == 0)
+                        ret = r;
         }
 
-        return 0;
+        return ret;
 }
 
-static int cat(sd_bus *bus, char **args) {
-        _cleanup_free_ char *unit = NULL;
-        _cleanup_strv_free_ char **names = NULL;
-        char **name;
-        bool first = true;
-        int r = 0;
-
-        assert(bus);
-        assert(args);
-
-        r = expand_names(bus, args + 1, NULL, &names);
-        if (r < 0)
-                log_error("Failed to expand names: %s", strerror(-r));
+static int show_system_status(sd_bus *bus) {
+        char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], since2[FORMAT_TIMESTAMP_MAX];
+        _cleanup_free_ char *hn = NULL;
+        struct machine_info mi = {};
+        const char *on, *off;
+        int r;
 
-        pager_open_if_enabled();
+        hn = gethostname_malloc();
+        if (!hn)
+                return log_oom();
 
-        STRV_FOREACH(name, names) {
-                _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
-                _cleanup_strv_free_ char **dropin_paths = NULL;
-                _cleanup_free_ char *fragment_path = NULL;
-                char **path;
+        r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, &mi);
+        if (r < 0) {
+                log_error("Failed to read server status: %s", strerror(-r));
+                return r;
+        }
 
-                unit = unit_dbus_path_from_name(*name);
-                if (!unit)
-                        return log_oom();
+        if (streq_ptr(mi.state, "degraded")) {
+                on = ansi_highlight_red();
+                off = ansi_highlight_off();
+        } else if (!streq_ptr(mi.state, "running")) {
+                on = ansi_highlight_yellow();
+                off = ansi_highlight_off();
+        } else
+                on = off = "";
 
-                if (need_daemon_reload(bus, *name) > 0)
-                        log_warning("Unit file of %s changed on disk. Run 'systemctl%s daemon-reload'.",
-                                    *name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
+        printf("%s%s%s %s\n", on, draw_special_char(DRAW_BLACK_CIRCLE), off, arg_host ? arg_host : hn);
 
-                r = sd_bus_get_property_string(
-                                bus,
-                                "org.freedesktop.systemd1",
-                                unit,
-                                "org.freedesktop.systemd1.Unit",
-                                "FragmentPath",
-                                &error,
-                                &fragment_path);
-                if (r < 0) {
-                        log_warning("Failed to get FragmentPath: %s", bus_error_message(&error, r));
-                        continue;
-                }
+        printf("    State: %s%s%s\n",
+               on, strna(mi.state), off);
 
-                r = sd_bus_get_property_strv(
-                                bus,
-                                "org.freedesktop.systemd1",
-                                unit,
-                                "org.freedesktop.systemd1.Unit",
-                                "DropInPaths",
-                                &error,
-                                &dropin_paths);
-                if (r < 0) {
-                        log_warning("Failed to get DropInPaths: %s", bus_error_message(&error, r));
-                        continue;
-                }
+        printf("     Jobs: %u queued\n", mi.n_jobs);
+        printf("   Failed: %u units\n", mi.n_failed_units);
 
-                if (first)
-                        first = false;
-                else
-                        puts("");
+        printf("    Since: %s; %s\n",
+               format_timestamp(since2, sizeof(since2), mi.timestamp),
+               format_timestamp_relative(since1, sizeof(since1), mi.timestamp));
 
-                if (!isempty(fragment_path)) {
-                        printf("%s# %s%s\n",
-                               ansi_highlight_blue(),
-                               fragment_path,
-                               ansi_highlight_off());
-                        fflush(stdout);
+        printf("   CGroup: %s\n", mi.control_group ?: "/");
+        if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
+                int flags =
+                        arg_all * OUTPUT_SHOW_ALL |
+                        (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
+                        on_tty() * OUTPUT_COLOR |
+                        !arg_quiet * OUTPUT_WARN_CUTOFF |
+                        arg_full * OUTPUT_FULL_WIDTH;
 
-                        r = sendfile_full(STDOUT_FILENO, fragment_path);
-                        if (r < 0) {
-                                log_warning("Failed to cat %s: %s", fragment_path, strerror(-r));
-                                continue;
-                        }
-                }
+                static const char prefix[] = "           ";
+                unsigned c;
 
-                STRV_FOREACH(path, dropin_paths) {
-                        printf("%s%s# %s%s\n",
-                               isempty(fragment_path) && path == dropin_paths ? "" : "\n",
-                               ansi_highlight_blue(),
-                               *path,
-                               ansi_highlight_off());
-                        fflush(stdout);
+                c = columns();
+                if (c > sizeof(prefix) - 1)
+                        c -= sizeof(prefix) - 1;
+                else
+                        c = 0;
 
-                        r = sendfile_full(STDOUT_FILENO, *path);
-                        if (r < 0) {
-                                log_warning("Failed to cat %s: %s", *path, strerror(-r));
-                                continue;
-                        }
-                }
+                show_cgroup(SYSTEMD_CGROUP_CONTROLLER, strempty(mi.control_group), prefix, c, false, flags);
         }
 
-        return r < 0 ? r : 0;
+        free(mi.state);
+        free(mi.control_group);
+
+        return 0;
 }
 
 static int show(sd_bus *bus, char **args) {
@@ -3964,9 +4365,15 @@ static int show(sd_bus *bus, char **args) {
         if (show_properties && strv_length(args) <= 1)
                 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
 
-        if (show_status && strv_length(args) <= 1)
-                ret = show_all(args[0], bus, false, &new_line, &ellipsized);
-        else {
+        if (show_status && strv_length(args) <= 1) {
+
+                pager_open_if_enabled();
+                show_system_status(bus);
+                new_line = true;
+
+                if (arg_all)
+                        ret = show_all(args[0], bus, false, &new_line, &ellipsized);
+        } else {
                 _cleanup_free_ char **patterns = NULL;
                 char **name;
 
@@ -3993,7 +4400,12 @@ static int show(sd_bus *bus, char **args) {
                                 }
                         }
 
-                        show_one(args[0], bus, unit, show_properties, &new_line, &ellipsized);
+                        r = show_one(args[0], bus, unit, show_properties,
+                                     &new_line, &ellipsized);
+                        if (r < 0)
+                                return r;
+                        else if (r > 0 && ret == 0)
+                                ret = r;
                 }
 
                 if (!strv_isempty(patterns)) {
@@ -4010,7 +4422,12 @@ static int show(sd_bus *bus, char **args) {
                                 if (!unit)
                                         return log_oom();
 
-                                show_one(args[0], bus, unit, show_properties, &new_line, &ellipsized);
+                                r = show_one(args[0], bus, unit, show_properties,
+                                             &new_line, &ellipsized);
+                                if (r < 0)
+                                        return r;
+                                else if (r > 0 && ret == 0)
+                                        ret = r;
                         }
                 }
         }
@@ -4019,163 +4436,100 @@ static int show(sd_bus *bus, char **args) {
                 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
 
         return ret;
-}
-
-static int append_assignment(sd_bus_message *m, const char *assignment) {
-        const char *eq;
-        char *field;
-        int r;
-
-        assert(m);
-        assert(assignment);
-
-        eq = strchr(assignment, '=');
-        if (!eq) {
-                log_error("Not an assignment: %s", assignment);
-                return -EINVAL;
-        }
-
-        field = strndupa(assignment, eq - assignment);
-        eq ++;
-
-        r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
-        if (r < 0)
-                return bus_log_create_error(r);
-
-        if (streq(field, "CPUAccounting") ||
-            streq(field, "MemoryAccounting") ||
-            streq(field, "BlockIOAccounting")) {
-
-                r = parse_boolean(eq);
-                if (r < 0) {
-                        log_error("Failed to parse boolean assignment %s.", assignment);
-                        return -EINVAL;
-                }
-
-                r = sd_bus_message_append(m, "v", "b", r);
-
-        } else if (streq(field, "MemoryLimit")) {
-                off_t bytes;
-
-                r = parse_size(eq, 1024, &bytes);
-                if (r < 0) {
-                        log_error("Failed to parse bytes specification %s", assignment);
-                        return -EINVAL;
-                }
-
-                r = sd_bus_message_append(m, "v", "t", (uint64_t) bytes);
-
-        } else if (streq(field, "CPUShares") || streq(field, "BlockIOWeight")) {
-                uint64_t u;
+}
 
-                r = safe_atou64(eq, &u);
-                if (r < 0) {
-                        log_error("Failed to parse %s value %s.", field, eq);
-                        return -EINVAL;
-                }
+static int cat(sd_bus *bus, char **args) {
+        _cleanup_free_ char *unit = NULL;
+        _cleanup_strv_free_ char **names = NULL;
+        char **name;
+        bool first = true;
+        int r = 0;
 
-                r = sd_bus_message_append(m, "v", "t", u);
+        assert(bus);
+        assert(args);
 
-        } else if (streq(field, "DevicePolicy"))
-                r = sd_bus_message_append(m, "v", "s", eq);
+        r = expand_names(bus, args + 1, NULL, &names);
+        if (r < 0)
+                log_error("Failed to expand names: %s", strerror(-r));
 
-        else if (streq(field, "DeviceAllow")) {
+        pager_open_if_enabled();
 
-                if (isempty(eq))
-                        r = sd_bus_message_append(m, "v", "a(ss)", 0);
-                else {
-                        const char *path, *rwm;
-                        char *e;
+        STRV_FOREACH(name, names) {
+                _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+                _cleanup_strv_free_ char **dropin_paths = NULL;
+                _cleanup_free_ char *fragment_path = NULL;
+                char **path;
 
-                        e = strchr(eq, ' ');
-                        if (e) {
-                                path = strndupa(eq, e - eq);
-                                rwm = e+1;
-                        } else {
-                                path = eq;
-                                rwm = "";
-                        }
+                unit = unit_dbus_path_from_name(*name);
+                if (!unit)
+                        return log_oom();
 
-                        if (!path_startswith(path, "/dev")) {
-                                log_error("%s is not a device file in /dev.", path);
-                                return -EINVAL;
-                        }
+                if (need_daemon_reload(bus, *name) > 0)
+                        log_warning("Unit file of %s changed on disk. Run 'systemctl%s daemon-reload'.",
+                                    *name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
 
-                        r = sd_bus_message_append(m, "v", "a(ss)", 1, path, rwm);
+                r = sd_bus_get_property_string(
+                                bus,
+                                "org.freedesktop.systemd1",
+                                unit,
+                                "org.freedesktop.systemd1.Unit",
+                                "FragmentPath",
+                                &error,
+                                &fragment_path);
+                if (r < 0) {
+                        log_warning("Failed to get FragmentPath: %s", bus_error_message(&error, r));
+                        continue;
                 }
 
-        } else if (streq(field, "BlockIOReadBandwidth") || streq(field, "BlockIOWriteBandwidth")) {
+                r = sd_bus_get_property_strv(
+                                bus,
+                                "org.freedesktop.systemd1",
+                                unit,
+                                "org.freedesktop.systemd1.Unit",
+                                "DropInPaths",
+                                &error,
+                                &dropin_paths);
+                if (r < 0) {
+                        log_warning("Failed to get DropInPaths: %s", bus_error_message(&error, r));
+                        continue;
+                }
 
-                if (isempty(eq))
-                        r = sd_bus_message_append(m, "v", "a(st)", 0);
-                else {
-                        const char *path, *bandwidth;
-                        off_t bytes;
-                        char *e;
-
-                        e = strchr(eq, ' ');
-                        if (e) {
-                                path = strndupa(eq, e - eq);
-                                bandwidth = e+1;
-                        } else {
-                                log_error("Failed to parse %s value %s.", field, eq);
-                                return -EINVAL;
-                        }
+                if (first)
+                        first = false;
+                else
+                        puts("");
 
-                        if (!path_startswith(path, "/dev")) {
-                                log_error("%s is not a device file in /dev.", path);
-                                return -EINVAL;
-                        }
+                if (!isempty(fragment_path)) {
+                        printf("%s# %s%s\n",
+                               ansi_highlight_blue(),
+                               fragment_path,
+                               ansi_highlight_off());
+                        fflush(stdout);
 
-                        r = parse_size(bandwidth, 1000, &bytes);
+                        r = sendfile_full(STDOUT_FILENO, fragment_path);
                         if (r < 0) {
-                                log_error("Failed to parse byte value %s.", bandwidth);
-                                return -EINVAL;
+                                log_warning("Failed to cat %s: %s", fragment_path, strerror(-r));
+                                continue;
                         }
-
-                        r = sd_bus_message_append(m, "v", "a(st)", 1, path, (uint64_t) bytes);
                 }
 
-        } else if (streq(field, "BlockIODeviceWeight")) {
-
-                if (isempty(eq))
-                        r = sd_bus_message_append(m, "v", "a(st)", 0);
-                else {
-                        const char *path, *weight;
-                        uint64_t u;
-                        char *e;
-
-                        e = strchr(eq, ' ');
-                        if (e) {
-                                path = strndupa(eq, e - eq);
-                                weight = e+1;
-                        } else {
-                                log_error("Failed to parse %s value %s.", field, eq);
-                                return -EINVAL;
-                        }
-
-                        if (!path_startswith(path, "/dev")) {
-                                log_error("%s is not a device file in /dev.", path);
-                                return -EINVAL;
-                        }
+                STRV_FOREACH(path, dropin_paths) {
+                        printf("%s%s# %s%s\n",
+                               isempty(fragment_path) && path == dropin_paths ? "" : "\n",
+                               ansi_highlight_blue(),
+                               *path,
+                               ansi_highlight_off());
+                        fflush(stdout);
 
-                        r = safe_atou64(weight, &u);
+                        r = sendfile_full(STDOUT_FILENO, *path);
                         if (r < 0) {
-                                log_error("Failed to parse %s value %s.", field, weight);
-                                return -EINVAL;
+                                log_warning("Failed to cat %s: %s", *path, strerror(-r));
+                                continue;
                         }
-                        r = sd_bus_message_append(m, "v", "a(st)", path, u);
                 }
-
-        } else {
-                log_error("Unknown assignment %s.", assignment);
-                return -EINVAL;
         }
 
-        if (r < 0)
-                return bus_log_create_error(r);
-
-        return 0;
+        return r < 0 ? r : 0;
 }
 
 static int set_property(sd_bus *bus, char **args) {
@@ -4212,7 +4566,7 @@ static int set_property(sd_bus *bus, char **args) {
                 if (r < 0)
                         return bus_log_create_error(r);
 
-                r = append_assignment(m, *i);
+                r = bus_append_unit_property_assignment(m, *i);
                 if (r < 0)
                         return r;
 
@@ -4441,8 +4795,8 @@ static int show_environment(sd_bus *bus, char **args) {
 
 static int switch_root(sd_bus *bus, char **args) {
         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
-        _cleanup_free_ char *init = NULL;
-        const char *root;
+        _cleanup_free_ char *cmdline_init = NULL;
+        const char *root, *init;
         unsigned l;
         int r;
 
@@ -4455,20 +4809,33 @@ static int switch_root(sd_bus *bus, char **args) {
         root = args[1];
 
         if (l >= 3)
-                init = strdup(args[2]);
+                init = args[2];
         else {
-                parse_env_file("/proc/cmdline", WHITESPACE,
-                               "init", &init,
-                               NULL);
+                r = parse_env_file("/proc/cmdline", WHITESPACE,
+                                   "init", &cmdline_init,
+                                   NULL);
+                if (r < 0)
+                        log_debug("Failed to parse /proc/cmdline: %s", strerror(-r));
 
-                if (!init)
-                        init = strdup("");
+                init = cmdline_init;
         }
 
-        if (!init)
-                return log_oom();
+        if (isempty(init))
+                init = NULL;
+
+        if (init) {
+                const char *root_systemd_path = NULL, *root_init_path = NULL;
+
+                root_systemd_path = strappenda(root, "/" SYSTEMD_BINARY_PATH);
+                root_init_path = strappenda(root, "/", init);
 
-        log_debug("switching root - root: %s; init: %s", root, init);
+                /* If the passed init is actually the same as the
+                 * systemd binary, then let's suppress it. */
+                if (files_same(root_init_path, root_systemd_path) > 0)
+                        init = NULL;
+        }
+
+        log_debug("Switching root - root: %s; init: %s", root, strna(init));
 
         r = sd_bus_call_method(
                         bus,
@@ -4604,18 +4971,18 @@ static int enable_sysv_units(const char *verb, char **args) {
         /* Processes all SysV units, and reshuffles the array so that
          * afterwards only the native units remain */
 
-        r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, NULL, NULL, NULL);
+        r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, arg_root, NULL, NULL, NULL);
         if (r < 0)
                 return r;
 
         r = 0;
         for (f = 0; args[f]; f++) {
                 const char *name;
-                _cleanup_free_ char *p = NULL, *q = NULL;
+                _cleanup_free_ char *p = NULL, *q = NULL, *l = NULL;
                 bool found_native = false, found_sysv;
                 unsigned c = 1;
                 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
-                char **k, *l;
+                char **k;
                 int j;
                 pid_t pid;
                 siginfo_t status;
@@ -4629,20 +4996,13 @@ static int enable_sysv_units(const char *verb, char **args) {
                         continue;
 
                 STRV_FOREACH(k, paths.unit_path) {
-                        if (!isempty(arg_root))
-                                asprintf(&p, "%s/%s/%s", arg_root, *k, name);
-                        else
-                                asprintf(&p, "%s/%s", *k, name);
-
-                        if (!p) {
-                                r = log_oom();
-                                goto finish;
-                        }
+                        _cleanup_free_ char *path = NULL;
 
-                        found_native = access(p, F_OK) >= 0;
-                        free(p);
-                        p = NULL;
+                        path = path_join(arg_root, *k, name);
+                        if (!path)
+                                return log_oom();
 
+                        found_native = access(path, F_OK) >= 0;
                         if (found_native)
                                 break;
                 }
@@ -4650,18 +5010,12 @@ static int enable_sysv_units(const char *verb, char **args) {
                 if (found_native)
                         continue;
 
-                if (!isempty(arg_root))
-                        asprintf(&p, "%s/" SYSTEM_SYSVINIT_PATH "/%s", arg_root, name);
-                else
-                        asprintf(&p, SYSTEM_SYSVINIT_PATH "/%s", name);
-                if (!p) {
-                        r = log_oom();
-                        goto finish;
-                }
+                p = path_join(arg_root, SYSTEM_SYSVINIT_PATH, name);
+                if (!p)
+                        return log_oom();
 
-                p[strlen(p) - sizeof(".service") + 1] = 0;
+                p[strlen(p) - strlen(".service")] = 0;
                 found_sysv = access(p, F_OK) >= 0;
-
                 if (!found_sysv)
                         continue;
 
@@ -4680,19 +5034,15 @@ static int enable_sysv_units(const char *verb, char **args) {
                 argv[c] = NULL;
 
                 l = strv_join((char**)argv, " ");
-                if (!l) {
-                        r = log_oom();
-                        goto finish;
-                }
+                if (!l)
+                        return log_oom();
 
                 log_info("Executing %s", l);
-                free(l);
 
                 pid = fork();
                 if (pid < 0) {
                         log_error("Failed to fork: %m");
-                        r = -errno;
-                        goto finish;
+                        return -errno;
                 } else if (pid == 0) {
                         /* Child */
 
@@ -4703,8 +5053,7 @@ static int enable_sysv_units(const char *verb, char **args) {
                 j = wait_for_terminate(pid, &status);
                 if (j < 0) {
                         log_error("Failed to wait for child: %s", strerror(-r));
-                        r = j;
-                        goto finish;
+                        return j;
                 }
 
                 if (status.si_code == CLD_EXITED) {
@@ -4718,17 +5067,12 @@ static int enable_sysv_units(const char *verb, char **args) {
                                                 puts("disabled");
                                 }
 
-                        } else if (status.si_status != 0) {
-                                r = -EINVAL;
-                                goto finish;
-                        }
-                } else {
-                        r = -EPROTO;
-                        goto finish;
-                }
+                        } else if (status.si_status != 0)
+                                return -EINVAL;
+                } else
+                        return -EPROTO;
         }
 
-finish:
         /* Drop all SysV units */
         for (f = 0, t = 0; args[f]; f++) {
 
@@ -4812,7 +5156,7 @@ static int enable_unit(sd_bus *bus, char **args) {
                 } else if (streq(verb, "link"))
                         r = unit_file_link(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
                 else if (streq(verb, "preset")) {
-                        r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
+                        r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_preset_mode, arg_force, &changes, &n_changes);
                         carries_install_info = r;
                 } else if (streq(verb, "mask"))
                         r = unit_file_mask(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
@@ -4834,7 +5178,7 @@ static int enable_unit(sd_bus *bus, char **args) {
                 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
                 int expect_carries_install_info = false;
-                bool send_force = true;
+                bool send_force = true, send_preset_mode = false;
                 const char *method;
 
                 if (streq(verb, "enable")) {
@@ -4849,7 +5193,13 @@ static int enable_unit(sd_bus *bus, char **args) {
                 } else if (streq(verb, "link"))
                         method = "LinkUnitFiles";
                 else if (streq(verb, "preset")) {
-                        method = "PresetUnitFiles";
+
+                        if (arg_preset_mode != UNIT_FILE_PRESET_FULL) {
+                                method = "PresetUnitFilesWithMode";
+                                send_preset_mode = true;
+                        } else
+                                method = "PresetUnitFiles";
+
                         expect_carries_install_info = true;
                 } else if (streq(verb, "mask"))
                         method = "MaskUnitFiles";
@@ -4873,6 +5223,12 @@ static int enable_unit(sd_bus *bus, char **args) {
                 if (r < 0)
                         return bus_log_create_error(r);
 
+                if (send_preset_mode) {
+                        r = sd_bus_message_append(m, "s", unit_file_preset_mode_to_string(arg_preset_mode));
+                        if (r < 0)
+                                return bus_log_create_error(r);
+                }
+
                 r = sd_bus_message_append(m, "b", arg_runtime);
                 if (r < 0)
                         return bus_log_create_error(r);
@@ -4899,7 +5255,7 @@ static int enable_unit(sd_bus *bus, char **args) {
                 if (r < 0)
                         return r;
 
-                /* Try to reload if enabeld */
+                /* Try to reload if enabled */
                 if (!arg_no_reload)
                         r = daemon_reload(bus, args);
                 else
@@ -4923,6 +5279,61 @@ finish:
         return r;
 }
 
+static int preset_all(sd_bus *bus, char **args) {
+        UnitFileChange *changes = NULL;
+        unsigned n_changes = 0;
+        int r;
+
+        if (!bus || avoid_bus()) {
+
+                r = unit_file_preset_all(arg_scope, arg_runtime, arg_root, arg_preset_mode, arg_force, &changes, &n_changes);
+                if (r < 0) {
+                        log_error("Operation failed: %s", strerror(-r));
+                        goto finish;
+                }
+
+                if (!arg_quiet)
+                        dump_unit_file_changes(changes, n_changes);
+
+                r = 0;
+
+        } else {
+                _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
+                _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+
+                r = sd_bus_call_method(
+                                bus,
+                                "org.freedesktop.systemd1",
+                                "/org/freedesktop/systemd1",
+                                "org.freedesktop.systemd1.Manager",
+                                "PresetAllUnitFiles",
+                                &error,
+                                &reply,
+                                "sbb",
+                                unit_file_preset_mode_to_string(arg_preset_mode),
+                                arg_runtime,
+                                arg_force);
+                if (r < 0) {
+                        log_error("Failed to execute operation: %s", bus_error_message(&error, r));
+                        return r;
+                }
+
+                r = deserialize_and_dump_unit_file_changes(reply);
+                if (r < 0)
+                        return r;
+
+                if (!arg_no_reload)
+                        r = daemon_reload(bus, args);
+                else
+                        r = 0;
+        }
+
+finish:
+        unit_file_changes_free(changes, n_changes);
+
+        return r;
+}
+
 static int unit_is_enabled(sd_bus *bus, char **args) {
 
         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
@@ -4997,7 +5408,31 @@ static int unit_is_enabled(sd_bus *bus, char **args) {
         return !enabled;
 }
 
-static int systemctl_help(void) {
+static int is_system_running(sd_bus *bus, char **args) {
+        _cleanup_free_ char *state = NULL;
+        int r;
+
+        r = sd_bus_get_property_string(
+                        bus,
+                        "org.freedesktop.systemd1",
+                        "/org/freedesktop/systemd1",
+                        "org.freedesktop.systemd1.Manager",
+                        "SystemState",
+                        NULL,
+                        &state);
+        if (r < 0) {
+                if (!arg_quiet)
+                        puts("unknown");
+                return 0;
+        }
+
+        if (!arg_quiet)
+                puts(state);
+
+        return streq(state, "running") ? EXIT_SUCCESS : EXIT_FAILURE;
+}
+
+static void systemctl_help(void) {
 
         pager_open_if_enabled();
 
@@ -5018,6 +5453,7 @@ static int systemctl_help(void) {
                "                      ones. To list all units installed on the system, use\n"
                "                      the 'list-unit-files' command instead.\n"
                "  -l --full           Don't ellipsize unit names on output\n"
+               "  -r --recursive      Show unit list of host and local containers\n"
                "     --reverse        Show reverse dependencies with 'list-dependencies'\n"
                "     --job-mode=MODE  Specify how to deal with already queued jobs, when\n"
                "                      queueing a new job\n"
@@ -5039,6 +5475,8 @@ static int systemctl_help(void) {
                "     --runtime        Enable unit files only temporarily until next reboot\n"
                "  -f --force          When enabling unit files, override existing symlinks\n"
                "                      When shutting down, execute action immediately\n"
+               "     --preset-mode=   Specifies whether fully apply presets, or only enable,\n"
+               "                      or only disable\n"
                "     --root=PATH      Enable unit files in the specified root directory\n"
                "  -n --lines=INTEGER  Number of journal entries to show\n"
                "  -o --output=STRING  Change journal output mode (short, short-monotonic,\n"
@@ -5059,15 +5497,15 @@ static int systemctl_help(void) {
                "                                  otherwise restart if active\n"
                "  isolate NAME                    Start one unit and stop all others\n"
                "  kill NAME...                    Send signal to processes of a unit\n"
-               "  is-active NAME...               Check whether units are active\n"
-               "  is-failed NAME...               Check whether units are failed\n"
-               "  status [NAME...|PID...]         Show runtime status of one or more units\n"
-               "  show [NAME...|JOB...]           Show properties of one or more\n"
+               "  is-active PATTERN...            Check whether units are active\n"
+               "  is-failed PATTERN...            Check whether units are failed\n"
+               "  status [PATTERN...|PID...]      Show runtime status of one or more units\n"
+               "  show [PATTERN...|JOB...]        Show properties of one or more\n"
                "                                  units/jobs or the manager\n"
-               "  cat NAME...                     Show files and drop-ins of one or more units\n"
+               "  cat PATTERN...                  Show files and drop-ins of one or more units\n"
                "  set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
-               "  help NAME...|PID...             Show manual for one or more units\n"
-               "  reset-failed [NAME...]          Reset failed state for all, one, or more\n"
+               "  help PATTERN...|PID...          Show manual for one or more units\n"
+               "  reset-failed [PATTERN...]       Reset failed state for all, one, or more\n"
                "                                  units\n"
                "  list-dependencies [NAME]        Recursively show units which are required\n"
                "                                  or wanted by this unit or by which this\n"
@@ -5079,6 +5517,8 @@ static int systemctl_help(void) {
                "  reenable NAME...                Reenable one or more unit files\n"
                "  preset NAME...                  Enable/disable one or more unit files\n"
                "                                  based on preset configuration\n"
+               "  preset-all                      Enable/disable all unit files based on\n"
+               "                                  preset configuration\n"
                "  is-enabled NAME...              Check whether unit files are enabled\n\n"
                "  mask NAME...                    Mask one or more units\n"
                "  unmask NAME...                  Unmask one or more units\n"
@@ -5086,6 +5526,8 @@ static int systemctl_help(void) {
                "                                  the search path\n"
                "  get-default                     Get the name of the default target\n"
                "  set-default NAME                Set the default target\n\n"
+               "Machine Commands:\n"
+               "  list-machines [PATTERN...]      List local containers and host\n\n"
                "Job Commands:\n"
                "  list-jobs [PATTERN...]          List jobs\n"
                "  cancel [JOB...]                 Cancel all, one, or more jobs\n\n"
@@ -5101,6 +5543,7 @@ static int systemctl_help(void) {
                "  daemon-reload                   Reload systemd manager configuration\n"
                "  daemon-reexec                   Reexecute systemd manager\n\n"
                "System Commands:\n"
+               "  is-system-running               Check whether system is fully running\n"
                "  default                         Enter system default mode\n"
                "  rescue                          Enter system rescue mode\n"
                "  emergency                       Enter system emergency mode\n"
@@ -5114,12 +5557,9 @@ static int systemctl_help(void) {
                "  hibernate                       Hibernate the system\n"
                "  hybrid-sleep                    Hibernate and suspend the system\n",
                program_invocation_short_name);
-
-        return 0;
 }
 
-static int halt_help(void) {
-
+static void halt_help(void) {
         printf("%s [OPTIONS...]%s\n\n"
                "%s the system.\n\n"
                "     --help      Show this help\n"
@@ -5135,12 +5575,9 @@ static int halt_help(void) {
                arg_action == ACTION_REBOOT   ? "Reboot" :
                arg_action == ACTION_POWEROFF ? "Power off" :
                                                "Halt");
-
-        return 0;
 }
 
-static int shutdown_help(void) {
-
+static void shutdown_help(void) {
         printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
                "Shut down the system.\n\n"
                "     --help      Show this help\n"
@@ -5152,12 +5589,9 @@ static int shutdown_help(void) {
                "     --no-wall   Don't send wall message before halt/power-off/reboot\n"
                "  -c             Cancel a pending shutdown\n",
                program_invocation_short_name);
-
-        return 0;
 }
 
-static int telinit_help(void) {
-
+static void telinit_help(void) {
         printf("%s [OPTIONS...] {COMMAND}\n\n"
                "Send control commands to the init daemon.\n\n"
                "     --help      Show this help\n"
@@ -5170,32 +5604,26 @@ static int telinit_help(void) {
                "  q, Q           Reload init daemon configuration\n"
                "  u, U           Reexecute init daemon\n",
                program_invocation_short_name);
-
-        return 0;
 }
 
-static int runlevel_help(void) {
-
+static void runlevel_help(void) {
         printf("%s [OPTIONS...]\n\n"
                "Prints the previous and current runlevel of the init system.\n\n"
                "     --help      Show this help\n",
                program_invocation_short_name);
-
-        return 0;
 }
 
-static int help_types(void) {
+static void help_types(void) {
         int i;
         const char *t;
 
-        puts("Available unit types:");
+        if (!arg_no_legend)
+                puts("Available unit types:");
         for (i = 0; i < _UNIT_TYPE_MAX; i++) {
                 t = unit_type_to_string(i);
                 if (t)
                         puts(t);
         }
-
-        return 0;
 }
 
 static int systemctl_parse_argv(int argc, char *argv[]) {
@@ -5225,7 +5653,8 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
                 ARG_FORCE,
                 ARG_PLAIN,
                 ARG_STATE,
-                ARG_JOB_MODE
+                ARG_JOB_MODE,
+                ARG_PRESET_MODE,
         };
 
         static const struct option options[] = {
@@ -5266,6 +5695,8 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
                 { "output",              required_argument, NULL, 'o'                     },
                 { "plain",               no_argument,       NULL, ARG_PLAIN               },
                 { "state",               required_argument, NULL, ARG_STATE               },
+                { "recursive",           no_argument,       NULL, 'r'                     },
+                { "preset-mode",         required_argument, NULL, ARG_PRESET_MODE         },
                 {}
         };
 
@@ -5274,12 +5705,13 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:i", options, NULL)) >= 0) {
+        while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:ir", options, NULL)) >= 0)
 
                 switch (c) {
 
                 case 'h':
-                        return systemctl_help();
+                        systemctl_help();
+                        return 0;
 
                 case ARG_VERSION:
                         puts(PACKAGE_STRING);
@@ -5287,7 +5719,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
                         return 0;
 
                 case 't': {
-                        char *word, *state;
+                        const char *word, *state;
                         size_t size;
 
                         FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
@@ -5336,7 +5768,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
                                 if (!arg_properties)
                                         return log_oom();
                         } else {
-                                char *word, *state;
+                                const char *word, *state;
                                 size_t size;
 
                                 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
@@ -5346,10 +5778,8 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
                                         if (!prop)
                                                 return log_oom();
 
-                                        if (strv_push(&arg_properties, prop) < 0) {
-                                                free(prop);
+                                        if (strv_consume(&arg_properties, prop) < 0)
                                                 return log_oom();
-                                        }
                                 }
                         }
 
@@ -5508,7 +5938,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
                         break;
 
                 case ARG_STATE: {
-                        char *word, *state;
+                        const char *word, *state;
                         size_t size;
 
                         FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
@@ -5518,21 +5948,37 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
                                 if (!s)
                                         return log_oom();
 
-                                if (strv_push(&arg_states, s) < 0) {
-                                        free(s);
+                                if (strv_consume(&arg_states, s) < 0)
                                         return log_oom();
-                                }
                         }
                         break;
                 }
 
+                case 'r':
+                        if (geteuid() != 0) {
+                                log_error("--recursive requires root privileges.");
+                                return -EPERM;
+                        }
+
+                        arg_recursive = true;
+                        break;
+
+                case ARG_PRESET_MODE:
+
+                        arg_preset_mode = unit_file_preset_mode_from_string(optarg);
+                        if (arg_preset_mode < 0) {
+                                log_error("Failed to parse preset mode: %s.", optarg);
+                                return -EINVAL;
+                        }
+
+                        break;
+
                 case '?':
                         return -EINVAL;
 
                 default:
                         assert_not_reached("Unhandled option");
                 }
-        }
 
         if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
                 log_error("Cannot access user instance remotely.");
@@ -5572,11 +6018,12 @@ static int halt_parse_argv(int argc, char *argv[]) {
                 if (runlevel == '0' || runlevel == '6')
                         arg_force = 2;
 
-        while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0) {
+        while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0)
                 switch (c) {
 
                 case ARG_HELP:
-                        return halt_help();
+                        halt_help();
+                        return 0;
 
                 case ARG_HALT:
                         arg_action = ACTION_HALT;
@@ -5619,15 +6066,11 @@ static int halt_parse_argv(int argc, char *argv[]) {
                 default:
                         assert_not_reached("Unhandled option");
                 }
-        }
 
-        if (arg_action == ACTION_REBOOT && argc == optind + 1) {
-                r = write_string_file(REBOOT_PARAM_FILE, argv[optind]);
-                if (r < 0) {
-                        log_error("Failed to write reboot param to "
-                                  REBOOT_PARAM_FILE": %s", strerror(-r));
+        if (arg_action == ACTION_REBOOT && (argc == optind || argc == optind + 1)) {
+                r = update_reboot_param_file(argc == optind + 1 ? argv[optind] : NULL);
+                if (r < 0)
                         return r;
-                }
         } else if (optind < argc) {
                 log_error("Too many arguments.");
                 return -EINVAL;
@@ -5718,11 +6161,12 @@ static int shutdown_parse_argv(int argc, char *argv[]) {
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "HPrhkt:afFc", options, NULL)) >= 0) {
+        while ((c = getopt_long(argc, argv, "HPrhkt:afFc", options, NULL)) >= 0)
                 switch (c) {
 
                 case ARG_HELP:
-                        return shutdown_help();
+                        shutdown_help();
+                        return 0;
 
                 case 'H':
                         arg_action = ACTION_HALT;
@@ -5771,7 +6215,6 @@ static int shutdown_parse_argv(int argc, char *argv[]) {
                 default:
                         assert_not_reached("Unhandled option");
                 }
-        }
 
         if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
                 r = parse_time_spec(argv[optind], &arg_when);
@@ -5832,11 +6275,12 @@ static int telinit_parse_argv(int argc, char *argv[]) {
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
+        while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
                 switch (c) {
 
                 case ARG_HELP:
-                        return telinit_help();
+                        telinit_help();
+                        return 0;
 
                 case ARG_NO_WALL:
                         arg_no_wall = true;
@@ -5848,10 +6292,10 @@ static int telinit_parse_argv(int argc, char *argv[]) {
                 default:
                         assert_not_reached("Unhandled option");
                 }
-        }
 
         if (optind >= argc) {
-                telinit_help();
+                log_error("%s: required argument missing.",
+                          program_invocation_short_name);
                 return -EINVAL;
         }
 
@@ -5897,11 +6341,12 @@ static int runlevel_parse_argv(int argc, char *argv[]) {
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
+        while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
                 switch (c) {
 
                 case ARG_HELP:
-                        return runlevel_help();
+                        runlevel_help();
+                        return 0;
 
                 case '?':
                         return -EINVAL;
@@ -5909,7 +6354,6 @@ static int runlevel_parse_argv(int argc, char *argv[]) {
                 default:
                         assert_not_reached("Unhandled option");
                 }
-        }
 
         if (optind < argc) {
                 log_error("Too many arguments.");
@@ -6043,6 +6487,7 @@ static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
                 { "list-sockets",          MORE,  1, list_sockets      },
                 { "list-timers",           MORE,  1, list_timers       },
                 { "list-jobs",             MORE,  1, list_jobs         },
+                { "list-machines",         MORE,  1, list_machines     },
                 { "clear-jobs",            EQUAL, 1, daemon_reload     },
                 { "cancel",                MORE,  2, cancel_job        },
                 { "start",                 MORE,  2, start_unit        },
@@ -6090,6 +6535,7 @@ static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
                 { "is-enabled",            MORE,  2, unit_is_enabled,  NOBUS },
                 { "reenable",              MORE,  2, enable_unit,      NOBUS },
                 { "preset",                MORE,  2, enable_unit,      NOBUS },
+                { "preset-all",            EQUAL, 1, preset_all,       NOBUS },
                 { "mask",                  MORE,  2, enable_unit,      NOBUS },
                 { "unmask",                MORE,  2, enable_unit,      NOBUS },
                 { "link",                  MORE,  2, enable_unit,      NOBUS },
@@ -6098,6 +6544,7 @@ static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
                 { "set-default",           EQUAL, 2, set_default,      NOBUS },
                 { "get-default",           EQUAL, 1, get_default,      NOBUS },
                 { "set-property",          MORE,  3, set_property      },
+                { "is-system-running",     EQUAL, 1, is_system_running },
                 {}
         }, *verb = verbs;
 
@@ -6200,7 +6647,7 @@ static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const ch
         struct msghdr msghdr = {
                 .msg_name = &sockaddr,
                 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
-                               + sizeof("/run/systemd/shutdownd") - 1,
+                               + strlen("/run/systemd/shutdownd"),
                 .msg_iov = iovec,
                 .msg_iovlen = 1,
         };
@@ -6392,7 +6839,7 @@ static int runlevel_main(void) {
 }
 
 int main(int argc, char*argv[]) {
-        _cleanup_bus_unref_ sd_bus *bus = NULL;
+        _cleanup_bus_close_unref_ sd_bus *bus = NULL;
         int r;
 
         setlocale(LC_ALL, "");
index cc3be93..896a027 100644 (file)
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
-/* This is a private header, never even think of including this directly! */
+/* This is a private header; never even think of including this directly! */
 
 #if __INCLUDE_LEVEL__ <= 1
-#error "Do not include _sd-common.h directly, it is a private header."
+#error "Do not include _sd-common.h directly; it is a private header."
 #endif
 
 #ifndef _sd_printf_
index 0629e47..0352d16 100644 (file)
@@ -37,7 +37,9 @@ _SD_BEGIN_DECLARATIONS;
 
 typedef struct sd_bus sd_bus;
 typedef struct sd_bus_message sd_bus_message;
+typedef struct sd_bus_slot sd_bus_slot;
 typedef struct sd_bus_creds sd_bus_creds;
+typedef struct sd_bus_track sd_bus_track;
 
 typedef struct {
         const char *name;
@@ -89,6 +91,7 @@ typedef int (*sd_bus_property_get_t) (sd_bus *bus, const char *path, const char
 typedef int (*sd_bus_property_set_t) (sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *value, void *userdata, sd_bus_error *ret_error);
 typedef int (*sd_bus_object_find_t) (sd_bus *bus, const char *path, const char *interface, void *userdata, void **ret_found, sd_bus_error *ret_error);
 typedef int (*sd_bus_node_enumerator_t) (sd_bus *bus, const char *path, void *userdata, char ***ret_nodes, sd_bus_error *ret_error);
+typedef int (*sd_bus_track_handler_t) (sd_bus_track *track, void *userdata);
 
 #include "sd-bus-protocol.h"
 #include "sd-bus-vtable.h"
@@ -114,6 +117,7 @@ int sd_bus_set_server(sd_bus *bus, int b, sd_id128_t server_id);
 int sd_bus_set_anonymous(sd_bus *bus, int b);
 int sd_bus_set_trusted(sd_bus *bus, int b);
 int sd_bus_set_name(sd_bus *bus, const char *name);
+int sd_bus_set_monitor(sd_bus *bus, int b);
 int sd_bus_negotiate_fds(sd_bus *bus, int b);
 int sd_bus_negotiate_timestamp(sd_bus *bus, int b);
 int sd_bus_negotiate_creds(sd_bus *bus, uint64_t creds_mask);
@@ -135,8 +139,7 @@ int sd_bus_get_tid(sd_bus *bus, pid_t *tid);
 int sd_bus_send(sd_bus *bus, sd_bus_message *m, uint64_t *cookie);
 int sd_bus_send_to(sd_bus *bus, sd_bus_message *m, const char *destination, uint64_t *cookie);
 int sd_bus_call(sd_bus *bus, sd_bus_message *m, uint64_t usec, sd_bus_error *ret_error, sd_bus_message **reply);
-int sd_bus_call_async(sd_bus *bus, sd_bus_message *m, sd_bus_message_handler_t callback, void *userdata, uint64_t usec, uint64_t *cookie);
-int sd_bus_call_async_cancel(sd_bus *bus, uint64_t cookie);
+int sd_bus_call_async(sd_bus *bus, sd_bus_slot **slot, sd_bus_message *m, sd_bus_message_handler_t callback, void *userdata, uint64_t usec);
 
 int sd_bus_get_fd(sd_bus *bus);
 int sd_bus_get_events(sd_bus *bus);
@@ -145,35 +148,37 @@ int sd_bus_process(sd_bus *bus, sd_bus_message **r);
 int sd_bus_process_priority(sd_bus *bus, int64_t max_priority, sd_bus_message **r);
 int sd_bus_wait(sd_bus *bus, uint64_t timeout_usec);
 int sd_bus_flush(sd_bus *bus);
-sd_bus_message* sd_bus_get_current(sd_bus *bus);
+sd_bus_slot* sd_bus_get_current_slot(sd_bus *bus);
+sd_bus_message* sd_bus_get_current_message(sd_bus *bus);
+sd_bus_message_handler_t sd_bus_get_current_handler(sd_bus *bus);
+void* sd_bus_get_current_userdata(sd_bus *bus);
 
 int sd_bus_attach_event(sd_bus *bus, sd_event *e, int priority);
 int sd_bus_detach_event(sd_bus *bus);
 sd_event *sd_bus_get_event(sd_bus *bus);
 
-int sd_bus_add_filter(sd_bus *bus, sd_bus_message_handler_t callback, void *userdata);
-int sd_bus_remove_filter(sd_bus *bus, sd_bus_message_handler_t callback, void *userdata);
+int sd_bus_add_filter(sd_bus *bus, sd_bus_slot **slot, sd_bus_message_handler_t callback, void *userdata);
+int sd_bus_add_match(sd_bus *bus, sd_bus_slot **slot, const char *match, sd_bus_message_handler_t callback, void *userdata);
+int sd_bus_add_object(sd_bus *bus, sd_bus_slot **slot, const char *path, sd_bus_message_handler_t callback, void *userdata);
+int sd_bus_add_fallback(sd_bus *bus, sd_bus_slot **slot, const char *prefix, sd_bus_message_handler_t callback, void *userdata);
+int sd_bus_add_object_vtable(sd_bus *bus, sd_bus_slot **slot, const char *path, const char *interface, const sd_bus_vtable *vtable, void *userdata);
+int sd_bus_add_fallback_vtable(sd_bus *bus, sd_bus_slot **slot, const char *prefix, const char *interface, const sd_bus_vtable *vtable, sd_bus_object_find_t find, void *userdata);
+int sd_bus_add_node_enumerator(sd_bus *bus, sd_bus_slot **slot, const char *path, sd_bus_node_enumerator_t callback, void *userdata);
+int sd_bus_add_object_manager(sd_bus *bus, sd_bus_slot **slot, const char *path);
 
-int sd_bus_add_match(sd_bus *bus, const char *match, sd_bus_message_handler_t callback, void *userdata);
-int sd_bus_remove_match(sd_bus *bus, const char *match, sd_bus_message_handler_t callback, void *userdata);
+/* Slot object */
 
-int sd_bus_add_object(sd_bus *bus, const char *path, sd_bus_message_handler_t callback, void *userdata);
-int sd_bus_remove_object(sd_bus *bus, const char *path, sd_bus_message_handler_t callback, void *userdata);
+sd_bus_slot* sd_bus_slot_ref(sd_bus_slot *slot);
+sd_bus_slot* sd_bus_slot_unref(sd_bus_slot *slot);
 
-int sd_bus_add_fallback(sd_bus *bus, const char *prefix, sd_bus_message_handler_t callback, void *userdata);
-int sd_bus_remove_fallback(sd_bus *bus, const char *prefix, sd_bus_message_handler_t callback, void *userdata);
+sd_bus* sd_bus_slot_get_bus(sd_bus_slot *slot);
 
-int sd_bus_add_object_vtable(sd_bus *bus, const char *path, const char *interface, const sd_bus_vtable *vtable, void *userdata);
-int sd_bus_remove_object_vtable(sd_bus *bus, const char *path, const char *interface, const sd_bus_vtable *vtable, void *userdata);
+void *sd_bus_slot_get_userdata(sd_bus_slot *slot);
+void *sd_bus_slot_set_userdata(sd_bus_slot *slot, void *userdata);
 
-int sd_bus_add_fallback_vtable(sd_bus *bus, const char *path, const char *interface, const sd_bus_vtable *vtable, sd_bus_object_find_t find, void *userdata);
-int sd_bus_remove_fallback_vtable(sd_bus *bus, const char *path, const char *interface, const sd_bus_vtable *vtable, sd_bus_object_find_t find, void *userdata);
-
-int sd_bus_add_node_enumerator(sd_bus *bus, const char *path, sd_bus_node_enumerator_t callback, void *userdata);
-int sd_bus_remove_node_enumerator(sd_bus *bus, const char *path, sd_bus_node_enumerator_t callback, void *userdata);
-
-int sd_bus_add_object_manager(sd_bus *bus, const char *path);
-int sd_bus_remove_object_manager(sd_bus *bus, const char *path);
+sd_bus_message* sd_bus_slot_get_current_message(sd_bus_slot *slot);
+sd_bus_message_handler_t sd_bus_slot_get_current_handler(sd_bus_slot *bus);
+void *sd_bus_slot_get_current_userdata(sd_bus_slot *slot);
 
 /* Message object */
 
@@ -281,6 +286,7 @@ int sd_bus_emit_interfaces_removed_strv(sd_bus *bus, const char *path, char **in
 int sd_bus_emit_interfaces_removed(sd_bus *bus, const char *path, const char *interface, ...) _sd_sentinel_;
 
 int sd_bus_query_sender_creds(sd_bus_message *call, uint64_t mask, sd_bus_creds **creds);
+int sd_bus_query_sender_privilege(sd_bus_message *call, int capability);
 
 /* Credential handling */
 
@@ -347,8 +353,28 @@ int sd_bus_error_has_name(const sd_bus_error *e, const char *name);
 
 /* Label escaping */
 
-char *sd_bus_label_escape(const char *s);
-char *sd_bus_label_unescape(const char *f);
+int sd_bus_path_encode(const char *prefix, const char *external_id, char **ret_path);
+int sd_bus_path_decode(const char *path, const char *prefix, char **ret_external_id);
+
+/* Tracking peers */
+
+int sd_bus_track_new(sd_bus *bus, sd_bus_track **track, sd_bus_track_handler_t handler, void *userdata);
+sd_bus_track* sd_bus_track_ref(sd_bus_track *track);
+sd_bus_track* sd_bus_track_unref(sd_bus_track *track);
+
+sd_bus* sd_bus_track_get_bus(sd_bus_track *track);
+void *sd_bus_track_get_userdata(sd_bus_track *track);
+void *sd_bus_track_set_userdata(sd_bus_track *track, void *userdata);
+
+int sd_bus_track_add_sender(sd_bus_track *track, sd_bus_message *m);
+int sd_bus_track_remove_sender(sd_bus_track *track, sd_bus_message *m);
+int sd_bus_track_add_name(sd_bus_track *track, const char *name);
+int sd_bus_track_remove_name(sd_bus_track *track, const char *name);
+
+unsigned sd_bus_track_count(sd_bus_track *track);
+const char* sd_bus_track_contains(sd_bus_track *track, const char *names);
+const char* sd_bus_track_first(sd_bus_track *track);
+const char* sd_bus_track_next(sd_bus_track *track);
 
 _SD_END_DECLARATIONS;
 
index 1d636df..351b4e5 100644 (file)
@@ -231,6 +231,18 @@ int sd_notify(int unset_environment, const char *state);
 int sd_notifyf(int unset_environment, const char *format, ...) _sd_printf_(2,3);
 
 /*
+  Similar to sd_notify(), but send the message on behalf of another
+  process, if the appropriate permissions are available.
+*/
+int sd_pid_notify(pid_t pid, int unset_environment, const char *state);
+
+/*
+  Similar to sd_notifyf(), but send the message on behalf of another
+  process, if the appropriate permissions are available.
+*/
+int sd_pid_notifyf(pid_t pid, int unset_environment, const char *format, ...) _sd_printf_(3,4);
+
+/*
   Returns > 0 if the system was booted with systemd. Returns < 0 on
   error. Returns 0 if the system was not booted with systemd. Note
   that all of the functions above handle non-systemd boots just
index 87f5adb..98c6782 100644 (file)
 #include <net/ethernet.h>
 
 #include "sd-event.h"
+#include "sd-dhcp-lease.h"
 
 enum {
         DHCP_EVENT_STOP                         = 0,
-        DHCP_EVENT_NO_LEASE                     = 1,
-        DHCP_EVENT_IP_ACQUIRE                   = 2,
-        DHCP_EVENT_IP_CHANGE                    = 3,
-        DHCP_EVENT_EXPIRED                      = 4,
+        DHCP_EVENT_IP_ACQUIRE                   = 1,
+        DHCP_EVENT_IP_CHANGE                    = 2,
+        DHCP_EVENT_EXPIRED                      = 3,
+        DHCP_EVENT_RENEW                        = 4,
 };
 
 typedef struct sd_dhcp_client sd_dhcp_client;
-typedef struct sd_dhcp_lease sd_dhcp_lease;
 
 typedef void (*sd_dhcp_client_cb_t)(sd_dhcp_client *client, int event,
                                     void *userdata);
@@ -47,24 +47,21 @@ int sd_dhcp_client_set_callback(sd_dhcp_client *client, sd_dhcp_client_cb_t cb,
 int sd_dhcp_client_set_request_option(sd_dhcp_client *client, uint8_t option);
 int sd_dhcp_client_set_request_address(sd_dhcp_client *client,
                                        const struct in_addr *last_address);
+int sd_dhcp_client_set_request_broadcast(sd_dhcp_client *client, int broadcast);
 int sd_dhcp_client_set_index(sd_dhcp_client *client, int interface_index);
 int sd_dhcp_client_set_mac(sd_dhcp_client *client,
                            const struct ether_addr *addr);
+int sd_dhcp_client_set_mtu(sd_dhcp_client *client, uint32_t mtu);
+int sd_dhcp_client_set_hostname(sd_dhcp_client *client, const char *hostname);
+int sd_dhcp_client_set_vendor_class_identifier(sd_dhcp_client *client, const char *vci);
 int sd_dhcp_client_get_lease(sd_dhcp_client *client, sd_dhcp_lease **ret);
 
-sd_dhcp_lease *sd_dhcp_lease_ref(sd_dhcp_lease *lease);
-sd_dhcp_lease *sd_dhcp_lease_unref(sd_dhcp_lease *lease);
-int sd_dhcp_lease_get_address(sd_dhcp_lease *lease, struct in_addr *addr);
-int sd_dhcp_lease_get_netmask(sd_dhcp_lease *lease, struct in_addr *addr);
-int sd_dhcp_lease_get_router(sd_dhcp_lease *lease, struct in_addr *addr);
-int sd_dhcp_lease_get_dns(sd_dhcp_lease *lease, struct in_addr **addr, size_t *addr_size);
-int sd_dhcp_lease_get_mtu(sd_dhcp_lease *lease, uint16_t *mtu);
-int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname);
-int sd_dhcp_lease_get_hostname(sd_dhcp_lease *lease, const char **hostname);
-
 int sd_dhcp_client_stop(sd_dhcp_client *client);
 int sd_dhcp_client_start(sd_dhcp_client *client);
-void sd_dhcp_client_free(sd_dhcp_client *client);
+
+sd_dhcp_client *sd_dhcp_client_ref(sd_dhcp_client *client);
+sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client);
+
 int sd_dhcp_client_new(sd_dhcp_client **ret);
 
 int sd_dhcp_client_attach_event(sd_dhcp_client *client, sd_event *event, int priority);
diff --git a/src/systemd/sd-dhcp-lease.h b/src/systemd/sd-dhcp-lease.h
new file mode 100644 (file)
index 0000000..a3728a7
--- /dev/null
@@ -0,0 +1,49 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#ifndef foosddhcpleasehfoo
+#define foosddhcpleasehfoo
+
+/***
+  This file is part of systemd.
+
+  Copyright (C) 2013 Intel Corporation. All rights reserved.
+  Copyright (C) 2014 Tom Gundersen
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <netinet/in.h>
+#include <net/ethernet.h>
+
+typedef struct sd_dhcp_lease sd_dhcp_lease;
+struct sd_dhcp_route;
+
+sd_dhcp_lease *sd_dhcp_lease_ref(sd_dhcp_lease *lease);
+sd_dhcp_lease *sd_dhcp_lease_unref(sd_dhcp_lease *lease);
+
+int sd_dhcp_lease_get_address(sd_dhcp_lease *lease, struct in_addr *addr);
+int sd_dhcp_lease_get_lifetime(sd_dhcp_lease *lease, uint32_t *lifetime);
+int sd_dhcp_lease_get_netmask(sd_dhcp_lease *lease, struct in_addr *addr);
+int sd_dhcp_lease_get_router(sd_dhcp_lease *lease, struct in_addr *addr);
+int sd_dhcp_lease_get_next_server(sd_dhcp_lease *lease, struct in_addr *addr);
+int sd_dhcp_lease_get_server_identifier(sd_dhcp_lease *lease, struct in_addr *addr);
+int sd_dhcp_lease_get_dns(sd_dhcp_lease *lease, const struct in_addr **addr);
+int sd_dhcp_lease_get_ntp(sd_dhcp_lease *lease, const struct in_addr **addr);
+int sd_dhcp_lease_get_mtu(sd_dhcp_lease *lease, uint16_t *mtu);
+int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname);
+int sd_dhcp_lease_get_hostname(sd_dhcp_lease *lease, const char **hostname);
+int sd_dhcp_lease_get_root_path(sd_dhcp_lease *lease, const char **root_path);
+int sd_dhcp_lease_get_routes(sd_dhcp_lease *lease, struct sd_dhcp_route **routesgn);
+
+#endif
diff --git a/src/systemd/sd-dhcp-server.h b/src/systemd/sd-dhcp-server.h
new file mode 100644 (file)
index 0000000..9af3b65
--- /dev/null
@@ -0,0 +1,51 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#ifndef foosddhcpserverhfoo
+#define foosddhcpserverhfoo
+
+/***
+  This file is part of systemd.
+
+  Copyright (C) 2013 Intel Corporation. All rights reserved.
+  Copyright (C) 2014 Tom Gundersen
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdbool.h>
+#include <netinet/in.h>
+
+#include "sd-event.h"
+
+typedef struct sd_dhcp_server sd_dhcp_server;
+
+sd_dhcp_server *sd_dhcp_server_ref(sd_dhcp_server *server);
+sd_dhcp_server *sd_dhcp_server_unref(sd_dhcp_server *server);
+
+int sd_dhcp_server_new(sd_dhcp_server **ret, int ifindex);
+
+int sd_dhcp_server_attach_event(sd_dhcp_server *client, sd_event *event, int priority);
+int sd_dhcp_server_detach_event(sd_dhcp_server *client);
+sd_event *sd_dhcp_server_get_event(sd_dhcp_server *client);
+
+bool sd_dhcp_server_is_running(sd_dhcp_server *server);
+
+int sd_dhcp_server_start(sd_dhcp_server *server);
+int sd_dhcp_server_stop(sd_dhcp_server *server);
+
+int sd_dhcp_server_set_address(sd_dhcp_server *server, struct in_addr *address, unsigned char prefixlen);
+int sd_dhcp_server_set_lease_pool(sd_dhcp_server *server, struct in_addr *start, size_t size);
+
+int sd_dhcp_server_forcerenew(sd_dhcp_server *server);
+#endif
diff --git a/src/systemd/sd-dhcp6-client.h b/src/systemd/sd-dhcp6-client.h
new file mode 100644 (file)
index 0000000..93edcc4
--- /dev/null
@@ -0,0 +1,63 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#ifndef foosddhcp6clienthfoo
+#define foosddhcp6clienthfoo
+
+/***
+  This file is part of systemd.
+
+  Copyright (C) 2014 Intel Corporation. All rights reserved.
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <net/ethernet.h>
+
+#include "sd-event.h"
+
+#include "sd-dhcp6-lease.h"
+
+enum {
+        DHCP6_EVENT_STOP                        = 0,
+        DHCP6_EVENT_RESEND_EXPIRE               = 10,
+        DHCP6_EVENT_RETRANS_MAX                 = 11,
+        DHCP6_EVENT_IP_ACQUIRE                  = 12,
+};
+
+typedef struct sd_dhcp6_client sd_dhcp6_client;
+
+typedef void (*sd_dhcp6_client_cb_t)(sd_dhcp6_client *client, int event,
+                                     void *userdata);
+int sd_dhcp6_client_set_callback(sd_dhcp6_client *client,
+                                 sd_dhcp6_client_cb_t cb, void *userdata);
+
+int sd_dhcp6_client_set_index(sd_dhcp6_client *client, int interface_index);
+int sd_dhcp6_client_set_mac(sd_dhcp6_client *client,
+                            const struct ether_addr *mac_addr);
+int sd_dhcp6_client_set_request_option(sd_dhcp6_client *client,
+                                       uint16_t option);
+
+int sd_dhcp6_client_get_lease(sd_dhcp6_client *client, sd_dhcp6_lease **ret);
+
+int sd_dhcp6_client_stop(sd_dhcp6_client *client);
+int sd_dhcp6_client_start(sd_dhcp6_client *client);
+int sd_dhcp6_client_attach_event(sd_dhcp6_client *client, sd_event *event,
+                                 int priority);
+int sd_dhcp6_client_detach_event(sd_dhcp6_client *client);
+sd_event *sd_dhcp6_client_get_event(sd_dhcp6_client *client);
+sd_dhcp6_client *sd_dhcp6_client_ref(sd_dhcp6_client *client);
+sd_dhcp6_client *sd_dhcp6_client_unref(sd_dhcp6_client *client);
+int sd_dhcp6_client_new(sd_dhcp6_client **ret);
+
+#endif
diff --git a/src/systemd/sd-dhcp6-lease.h b/src/systemd/sd-dhcp6-lease.h
new file mode 100644 (file)
index 0000000..1126f1a
--- /dev/null
@@ -0,0 +1,42 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#ifndef foosddhcp6leasehfoo
+#define foosddhcp6leasehfoo
+
+/***
+  This file is part of systemd.
+
+  Copyright (C) 2014 Tom Gundersen
+  Copyright (C) 2014 Intel Corporation. All rights reserved.
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <netinet/in.h>
+
+typedef struct sd_dhcp6_lease sd_dhcp6_lease;
+
+int sd_dhcp6_lease_get_first_address(sd_dhcp6_lease *lease,
+                                     struct in6_addr *addr,
+                                     uint32_t *lifetime_preferred,
+                                     uint32_t *lifetime_valid);
+int sd_dhcp6_lease_get_next_address(sd_dhcp6_lease *lease,
+                                    struct in6_addr *addr,
+                                    uint32_t *lifetime_preferred,
+                                    uint32_t *lifetime_valid);
+
+sd_dhcp6_lease *sd_dhcp6_lease_ref(sd_dhcp6_lease *lease);
+sd_dhcp6_lease *sd_dhcp6_lease_unref(sd_dhcp6_lease *lease);
+
+#endif
index 45c3608..5d9b3be 100644 (file)
@@ -33,8 +33,8 @@
 /*
   Why is this better than pure epoll?
 
-  - Supports event source priorisation
-  - Scales better with a large number of time events, since it doesn't require one timerfd each
+  - Supports event source prioritization
+  - Scales better with a large number of time events because it does not require one timerfd each
   - Automatically tries to coalesce timer events system-wide
   - Handles signals and child PIDs
 */
@@ -58,7 +58,7 @@ enum {
 };
 
 enum {
-        /* And everything inbetween and outside is good too */
+        /* And everything in-between and outside is good too */
         SD_EVENT_PRIORITY_IMPORTANT = -100,
         SD_EVENT_PRIORITY_NORMAL = 0,
         SD_EVENT_PRIORITY_IDLE = 100
@@ -77,8 +77,7 @@ sd_event* sd_event_ref(sd_event *e);
 sd_event* sd_event_unref(sd_event *e);
 
 int sd_event_add_io(sd_event *e, sd_event_source **s, int fd, uint32_t events, sd_event_io_handler_t callback, void *userdata);
-int sd_event_add_monotonic(sd_event *e, sd_event_source **s, uint64_t usec, uint64_t accuracy, sd_event_time_handler_t callback, void *userdata);
-int sd_event_add_realtime(sd_event *e, sd_event_source **s, uint64_t usec, uint64_t accuracy, sd_event_time_handler_t callback, void *userdata);
+int sd_event_add_time(sd_event *e, sd_event_source **s, clockid_t clock, uint64_t usec, uint64_t accuracy, sd_event_time_handler_t callback, void *userdata);
 int sd_event_add_signal(sd_event *e, sd_event_source **s, int sig, sd_event_signal_handler_t callback, void *userdata);
 int sd_event_add_child(sd_event *e, sd_event_source **s, pid_t pid, int options, sd_event_child_handler_t callback, void *userdata);
 int sd_event_add_defer(sd_event *e, sd_event_source **s, sd_event_handler_t callback, void *userdata);
@@ -89,25 +88,27 @@ int sd_event_run(sd_event *e, uint64_t timeout);
 int sd_event_loop(sd_event *e);
 int sd_event_exit(sd_event *e, int code);
 
+int sd_event_now(sd_event *e, clockid_t clock, uint64_t *usec);
+
 int sd_event_get_state(sd_event *e);
 int sd_event_get_tid(sd_event *e, pid_t *tid);
 int sd_event_get_exit_code(sd_event *e, int *code);
-int sd_event_get_now_realtime(sd_event *e, uint64_t *usec);
-int sd_event_get_now_monotonic(sd_event *e, uint64_t *usec);
 int sd_event_set_watchdog(sd_event *e, int b);
 int sd_event_get_watchdog(sd_event *e);
 
 sd_event_source* sd_event_source_ref(sd_event_source *s);
 sd_event_source* sd_event_source_unref(sd_event_source *s);
 
+sd_event *sd_event_source_get_event(sd_event_source *s);
+void* sd_event_source_get_userdata(sd_event_source *s);
+void* sd_event_source_set_userdata(sd_event_source *s, void *userdata);
+
 int sd_event_source_set_prepare(sd_event_source *s, sd_event_handler_t callback);
 int sd_event_source_get_pending(sd_event_source *s);
 int sd_event_source_get_priority(sd_event_source *s, int64_t *priority);
 int sd_event_source_set_priority(sd_event_source *s, int64_t priority);
 int sd_event_source_get_enabled(sd_event_source *s, int *enabled);
 int sd_event_source_set_enabled(sd_event_source *s, int enabled);
-void* sd_event_source_get_userdata(sd_event_source *s);
-void* sd_event_source_set_userdata(sd_event_source *s, void *userdata);
 int sd_event_source_get_io_fd(sd_event_source *s);
 int sd_event_source_set_io_fd(sd_event_source *s, int fd);
 int sd_event_source_get_io_events(sd_event_source *s, uint32_t* events);
@@ -115,11 +116,11 @@ int sd_event_source_set_io_events(sd_event_source *s, uint32_t events);
 int sd_event_source_get_io_revents(sd_event_source *s, uint32_t* revents);
 int sd_event_source_get_time(sd_event_source *s, uint64_t *usec);
 int sd_event_source_set_time(sd_event_source *s, uint64_t usec);
-int sd_event_source_set_time_accuracy(sd_event_source *s, uint64_t usec);
 int sd_event_source_get_time_accuracy(sd_event_source *s, uint64_t *usec);
+int sd_event_source_set_time_accuracy(sd_event_source *s, uint64_t usec);
+int sd_event_source_get_time_clock(sd_event_source *s, clockid_t *clock);
 int sd_event_source_get_signal(sd_event_source *s);
 int sd_event_source_get_child_pid(sd_event_source *s, pid_t *pid);
-sd_event *sd_event_source_get_event(sd_event_source *s);
 
 _SD_END_DECLARATIONS;
 
diff --git a/src/systemd/sd-icmp6-nd.h b/src/systemd/sd-icmp6-nd.h
new file mode 100644 (file)
index 0000000..73f91aa
--- /dev/null
@@ -0,0 +1,57 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#ifndef foosdicmp6ndfoo
+#define foosdicmp6ndfoo
+
+/***
+  This file is part of systemd.
+
+  Copyright (C) 2014 Intel Corporation. All rights reserved.
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <net/ethernet.h>
+
+#include "sd-event.h"
+
+enum {
+        ICMP6_EVENT_ROUTER_ADVERTISMENT_NONE    = 0,
+        ICMP6_EVENT_ROUTER_ADVERTISMENT_TIMEOUT = 1,
+        ICMP6_EVENT_ROUTER_ADVERTISMENT_OTHER   = 2,
+        ICMP6_EVENT_ROUTER_ADVERTISMENT_MANAGED = 3,
+};
+
+typedef struct sd_icmp6_nd sd_icmp6_nd;
+
+typedef void(*sd_icmp6_nd_callback_t)(sd_icmp6_nd *nd, int event,
+                                      void *userdata);
+
+int sd_icmp6_nd_set_callback(sd_icmp6_nd *nd, sd_icmp6_nd_callback_t cb,
+                             void *userdata);
+int sd_icmp6_nd_set_index(sd_icmp6_nd *nd, int interface_index);
+int sd_icmp6_nd_set_mac(sd_icmp6_nd *nd, const struct ether_addr *mac_addr);
+
+int sd_icmp6_nd_attach_event(sd_icmp6_nd *nd, sd_event *event, int priority);
+int sd_icmp6_nd_detach_event(sd_icmp6_nd *nd);
+sd_event *sd_icmp6_nd_get_event(sd_icmp6_nd *nd);
+
+sd_icmp6_nd *sd_icmp6_nd_ref(sd_icmp6_nd *nd);
+sd_icmp6_nd *sd_icmp6_nd_unref(sd_icmp6_nd *nd);
+int sd_icmp6_nd_new(sd_icmp6_nd **ret);
+
+int sd_icmp6_nd_stop(sd_icmp6_nd *nd);
+int sd_icmp6_router_solicitation_start(sd_icmp6_nd *nd);
+
+#endif
index f14efeb..4fdbf3a 100644 (file)
@@ -29,7 +29,7 @@
 
 _SD_BEGIN_DECLARATIONS;
 
-/* 128 Bit ID APIs. See sd-id128(3) for more information. */
+/* 128-bit ID APIs. See sd-id128(3) for more information. */
 
 typedef union sd_id128 sd_id128_t;
 
diff --git a/src/systemd/sd-ipv4ll.h b/src/systemd/sd-ipv4ll.h
new file mode 100644 (file)
index 0000000..d017158
--- /dev/null
@@ -0,0 +1,54 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#ifndef foosdipv4llfoo
+#define foosdipv4llfoo
+
+/***
+  This file is part of systemd.
+
+  Copyright (C) 2014 Axis Communications AB. All rights reserved.
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdbool.h>
+#include <netinet/in.h>
+#include <net/ethernet.h>
+
+#include "sd-event.h"
+
+enum {
+        IPV4LL_EVENT_STOP           = 0,
+        IPV4LL_EVENT_BIND           = 1,
+        IPV4LL_EVENT_CONFLICT       = 2,
+};
+
+typedef struct sd_ipv4ll sd_ipv4ll;
+typedef void (*sd_ipv4ll_cb_t)(sd_ipv4ll *ll, int event, void *userdata);
+
+int sd_ipv4ll_detach_event(sd_ipv4ll *ll);
+int sd_ipv4ll_attach_event(sd_ipv4ll *ll, sd_event *event, int priority);
+int sd_ipv4ll_get_address(sd_ipv4ll *ll, struct in_addr *address);
+int sd_ipv4ll_set_callback(sd_ipv4ll *ll, sd_ipv4ll_cb_t cb, void *userdata);
+int sd_ipv4ll_set_mac(sd_ipv4ll *ll, const struct ether_addr *addr);
+int sd_ipv4ll_set_index(sd_ipv4ll *ll, int interface_index);
+int sd_ipv4ll_set_address_seed(sd_ipv4ll *ll, uint8_t seed[8]);
+bool sd_ipv4ll_is_running(sd_ipv4ll *ll);
+int sd_ipv4ll_start(sd_ipv4ll *ll);
+int sd_ipv4ll_stop(sd_ipv4ll *ll);
+sd_ipv4ll *sd_ipv4ll_ref(sd_ipv4ll *ll);
+sd_ipv4ll *sd_ipv4ll_unref(sd_ipv4ll *ll);
+int sd_ipv4ll_new (sd_ipv4ll **ret);
+
+#endif
index 6de6932..1eb3be3 100644 (file)
  * may return NULL.
  *
  * Free the data the library returns with libc free(). String arrays
- * are NULL terminated and you need to free the array itself in
+ * are NULL terminated, and you need to free the array itself, in
  * addition to the strings contained.
  *
- * We return error codes as negative errno, kernel-style. 0 or
- * positive on success.
+ * We return error codes as negative errno, kernel-style. On success, we
+ * return 0 or positive.
  *
- * These functions access data in /proc, /sys/fs/cgroup and /run. All
- * of these are virtual file systems, hence the accesses are
+ * These functions access data in /proc, /sys/fs/cgroup, and /run. All
+ * of these are virtual file systems; therefore, accesses are
  * relatively cheap.
  *
  * See sd-login(3) for more information.
@@ -56,9 +56,9 @@ _SD_BEGIN_DECLARATIONS;
 int sd_pid_get_session(pid_t pid, char **session);
 
 /* Get UID of the owner of the session of the PID (or in case the
- * process is a 'shared' user process the UID of that user is
+ * process is a 'shared' user process, the UID of that user is
  * returned). This will not return the UID of the process, but rather
- * the UID of the owner of the cgroup the process is in. This will
+ * the UID of the owner of the cgroup that the process is in. This will
  * return an error for system processes. */
 int sd_pid_get_owner_uid(pid_t pid, uid_t *uid);
 
@@ -71,28 +71,55 @@ int sd_pid_get_unit(pid_t pid, char **unit);
  * processes. */
 int sd_pid_get_user_unit(pid_t pid, char **unit);
 
-/* Get machine name from PID, for processes assigned to VM or
+/* Get machine name from PID, for processes assigned to VM or
  * container. This will return an error for non-machine processes. */
-int sd_pid_get_machine_name(pid_t pid, char **name);
+int sd_pid_get_machine_name(pid_t pid, char **machine);
 
 /* Get slice name from PID. */
-int sd_pid_get_slice(pid_t pid, char **name);
+int sd_pid_get_slice(pid_t pid, char **slice);
 
-/* Get state from uid. Possible states: offline, lingering, online, active, closing */
-int sd_uid_get_state(uid_t uid, char**state);
+/* Similar to sd_pid_get_session(), but retrieves data about peer of
+ * connected AF_UNIX socket */
+int sd_peer_get_session(int fd, char **session);
 
-/* Return 1 if uid has session on seat. If require_active is true will
+/* Similar to sd_pid_get_owner_uid(), but retrieves data about peer of
+ * connected AF_UNIX socket */
+int sd_peer_get_owner_uid(int fd, uid_t *uid);
+
+/* Similar to sd_pid_get_unit(), but retrieves data about peer of
+ * connected AF_UNIX socket */
+int sd_peer_get_unit(int fd, char **unit);
+
+/* Similar to sd_pid_get_user_unit(), but retrieves data about peer of
+ * connected AF_UNIX socket */
+int sd_peer_get_user_unit(int fd, char **unit);
+
+/* Similar to sd_pid_get_machine_name(), but retrieves data about peer
+ * of connected AF_UNIX socket */
+int sd_peer_get_machine_name(int fd, char **machine);
+
+/* Similar to sd_pid_get_slice(), but retrieves data about peer of
+ * connected AF_UNIX socket */
+int sd_peer_get_slice(int fd, char **slice);
+
+/* Get state from UID. Possible states: offline, lingering, online, active, closing */
+int sd_uid_get_state(uid_t uid, char **state);
+
+/* Return primary session of user, if there is any */
+int sd_uid_get_display(uid_t uid, char **session);
+
+/* Return 1 if UID has session on seat. If require_active is true, this will
  * look for active sessions only. */
 int sd_uid_is_on_seat(uid_t uid, int require_active, const char *seat);
 
-/* Return sessions of user. If require_active is true will look for
- * active sessions only. Returns number of sessions as return
- * value. If sessions is NULL will just return number of sessions. */
+/* Return sessions of user. If require_active is true, this will look for
+ * active sessions only. Returns the number of sessions.
+ * If sessions is NULL, this will just return the number of sessions. */
 int sd_uid_get_sessions(uid_t uid, int require_active, char ***sessions);
 
-/* Return seats of user is on. If require_active is true will look for
- * active seats only.  Returns number of seats. If seats is NULL will
- * just return number of seats.*/
+/* Return seats of user is on. If require_active is true, this will look for
+ * active seats only. Returns the number of seats.
+ * If seats is NULL, this will just return the number of seats.*/
 int sd_uid_get_seats(uid_t uid, int require_active, char ***seats);
 
 /* Return 1 if the session is active. */
@@ -101,12 +128,11 @@ int sd_session_is_active(const char *session);
 /* Return 1 if the session is remote. */
 int sd_session_is_remote(const char *session);
 
-/* Get state from session. Possible states: online, active, closing
- * (This function is a more generic version of
- * sd_session_is_active().) */
+/* Get state from session. Possible states: online, active, closing.
+ * This function is a more generic version of sd_session_is_active(). */
 int sd_session_get_state(const char *session, char **state);
 
-/* Determine user id of session */
+/* Determine user ID of session */
 int sd_session_get_uid(const char *session, uid_t *uid);
 
 /* Determine seat of session */
@@ -115,7 +141,7 @@ int sd_session_get_seat(const char *session, char **seat);
 /* Determine the (PAM) service name this session was registered by. */
 int sd_session_get_service(const char *session, char **service);
 
-/* Determine the type of this session, i.e. one of "tty", "x11" or "unspecified". */
+/* Determine the type of this session, i.e. one of "tty", "x11", "wayland", "mir" or "unspecified". */
 int sd_session_get_type(const char *session, char **type);
 
 /* Determine the class of this session, i.e. one of "user", "greeter" or "lock-screen". */
@@ -139,9 +165,8 @@ int sd_session_get_vt(const char *session, unsigned *vtnr);
 /* Return active session and user of seat */
 int sd_seat_get_active(const char *seat, char **session, uid_t *uid);
 
-/* Return sessions and users on seat. Returns number of sessions as
- * return value. If sessions is NULL returns only the number of
- * sessions. */
+/* Return sessions and users on seat. Returns number of sessions.
+ * If sessions is NULL, this returns only the number of sessions. */
 int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **uid, unsigned *n_uids);
 
 /* Return whether the seat is multi-session capable */
@@ -153,16 +178,22 @@ int sd_seat_can_tty(const char *seat);
 /* Return whether the seat is graphics capable, i.e. suitable for showing graphical UIs */
 int sd_seat_can_graphical(const char *seat);
 
+/* Return the class of machine */
+int sd_machine_get_class(const char *machine, char **clazz);
+
+/* Return the list if host-side network interface indices of a machine */
+int sd_machine_get_ifindices(const char *machine, int **ifindices);
+
 /* Get all seats, store in *seats. Returns the number of seats. If
- * seats is NULL only returns number of seats. */
+ * seats is NULL, this only returns the number of seats. */
 int sd_get_seats(char ***seats);
 
 /* Get all sessions, store in *sessions. Returns the number of
- * sessions. If sessions is NULL only returns number of sessions. */
+ * sessions. If sessions is NULL, this only returns the number of sessions. */
 int sd_get_sessions(char ***sessions);
 
 /* Get all logged in users, store in *users. Returns the number of
- * users. If users is NULL only returns the number of users. */
+ * users. If users is NULL, this only returns the number of users. */
 int sd_get_uids(uid_t **users);
 
 /* Get all running virtual machines/containers */
@@ -172,7 +203,7 @@ int sd_get_machine_names(char ***machines);
 typedef struct sd_login_monitor sd_login_monitor;
 
 /* Create a new monitor. Category must be NULL, "seat", "session",
- * "uid", "machine" to get monitor events for the specific category
+ * "uid", or "machine" to get monitor events for the specific category
  * (or all). */
 int sd_login_monitor_new(const char *category, sd_login_monitor** ret);
 
diff --git a/src/systemd/sd-network.h b/src/systemd/sd-network.h
new file mode 100644 (file)
index 0000000..b2086c7
--- /dev/null
@@ -0,0 +1,140 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#ifndef foosdnetworkhfoo
+#define foosdnetworkhfoo
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011 Lennart Poettering
+  Copyright 2014 Tom Gundersen
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/types.h>
+#include <inttypes.h>
+
+#include "_sd-common.h"
+
+/*
+ * A few points:
+ *
+ * Instead of returning an empty string array or empty integer array, we
+ * may return NULL.
+ *
+ * Free the data the library returns with libc free(). String arrays
+ * are NULL terminated, and you need to free the array itself in
+ * addition to the strings contained.
+ *
+ * We return error codes as negative errno, kernel-style. On success, we
+ * return 0 or positive.
+ *
+ * These functions access data in /run. This is a virtual file system;
+ * therefore, accesses are relatively cheap.
+ *
+ * See sd-network(3) for more information.
+ */
+
+_SD_BEGIN_DECLARATIONS;
+
+/* Get overall operational state
+ * Possible states: down, up, dormant, carrier, degraded, routable
+ * Possible return codes:
+ *   -ENODATA: networkd is not aware of any links
+ */
+int sd_network_get_operational_state(char **state);
+
+/* Get DNS entries for all links. These are string representations of
+ * IP addresses */
+int sd_network_get_dns(char ***dns);
+
+/* Get NTP entries for all links. These are domain names or string
+ * reperesentations of IP addresses */
+int sd_network_get_ntp(char ***ntp);
+
+/* Get the search/routing domains for all links. */
+int sd_network_get_domains(char ***domains);
+
+/* Get setup state from ifindex.
+ * Possible states:
+ *   pending: udev is still processing the link, we don't yet know if we will manage it
+ *   failed: networkd failed to manage the link
+ *   configuring: in the process of retrieving configuration or configuring the link
+ *   configured: link configured successfully
+ *   unmanaged: networkd is not handling the link
+ *   linger: the link is gone, but has not yet been dropped by networkd
+ * Possible return codes:
+ *   -ENODATA: networkd is not aware of the link
+ */
+int sd_network_link_get_setup_state(int ifindex, char **state);
+
+/* Get operatinal state from ifindex.
+ * Possible states:
+ *   off: the device is powered down
+ *   no-carrier: the device is powered up, but it does not yet have a carrier
+ *   dormant: the device has a carrier, but is not yet ready for normal traffic
+ *   carrier: the link has a carrier
+ *   degraded: the link has carrier and addresses valid on the local link configured
+ *   routable: the link has carrier and routable address configured
+ * Possible return codes:
+ *   -ENODATA: networkd is not aware of the link
+ */
+int sd_network_link_get_operational_state(int ifindex, char **state);
+
+/* Get DNS entries for a given link. These are string representations of
+ * IP addresses */
+int sd_network_link_get_dns(int ifindex, char ***addr);
+
+/* Get NTP entries for a given link. These are domain names or string
+ * reperesentations of IP addresses */
+int sd_network_link_get_ntp(int ifindex, char ***addr);
+
+/* Indicates whether or not LLMNR should be enabled for the link
+ * Possible levels of support: yes, no, resolve
+ * Possible return codes:
+ *   -ENODATA: networkd is not aware of the link*/
+int sd_network_link_get_llmnr(int ifindex, char **llmnr);
+
+/* Get the DNS domain names for a given link. */
+int sd_network_link_get_domains(int ifindex, char ***domains);
+
+/* Returns whether or not domains that don't match any link should be resolved
+ * on this link. 1 for yes, 0 for no and negative value for error */
+int sd_network_link_get_wildcard_domain(int ifindex);
+
+/* Monitor object */
+typedef struct sd_network_monitor sd_network_monitor;
+
+/* Create a new monitor. Category must be NULL, "links" or "leases". */
+int sd_network_monitor_new(sd_network_monitor **ret, const char *category);
+
+/* Destroys the passed monitor. Returns NULL. */
+sd_network_monitor* sd_network_monitor_unref(sd_network_monitor *m);
+
+/* Flushes the monitor */
+int sd_network_monitor_flush(sd_network_monitor *m);
+
+/* Get FD from monitor */
+int sd_network_monitor_get_fd(sd_network_monitor *m);
+
+/* Get poll() mask to monitor */
+int sd_network_monitor_get_events(sd_network_monitor *m);
+
+/* Get timeout for poll(), as usec value relative to CLOCK_MONOTONIC's epoch */
+int sd_network_monitor_get_timeout(sd_network_monitor *m, uint64_t *timeout_usec);
+
+_SD_END_DECLARATIONS;
+
+#endif
diff --git a/src/systemd/sd-path.h b/src/systemd/sd-path.h
new file mode 100644 (file)
index 0000000..e238c0c
--- /dev/null
@@ -0,0 +1,87 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#ifndef foosdpathhfoo
+#define foosdpathhfoo
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <inttypes.h>
+
+enum {
+        /* Temporary files */
+        SD_PATH_TEMPORARY = 0x0ULL,
+        SD_PATH_TEMPORARY_LARGE,
+
+        /* Vendor supplied data */
+        SD_PATH_SYSTEM_BINARIES,
+        SD_PATH_SYSTEM_INCLUDE,
+        SD_PATH_SYSTEM_LIBRARY_PRIVATE,
+        SD_PATH_SYSTEM_LIBRARY_ARCH,
+        SD_PATH_SYSTEM_SHARED,
+        SD_PATH_SYSTEM_CONFIGURATION_FACTORY,
+        SD_PATH_SYSTEM_STATE_FACTORY,
+
+        /* System configuration, runtime, state, ... */
+        SD_PATH_SYSTEM_CONFIGURATION,
+        SD_PATH_SYSTEM_RUNTIME,
+        SD_PATH_SYSTEM_RUNTIME_LOGS,
+        SD_PATH_SYSTEM_STATE_PRIVATE,
+        SD_PATH_SYSTEM_STATE_LOGS,
+        SD_PATH_SYSTEM_STATE_CACHE,
+        SD_PATH_SYSTEM_STATE_SPOOL,
+
+        /* Vendor supplied data */
+        SD_PATH_USER_BINARIES,
+        SD_PATH_USER_LIBRARY_PRIVATE,
+        SD_PATH_USER_LIBRARY_ARCH,
+        SD_PATH_USER_SHARED,
+
+        /* User configuration, state, runtime ... */
+        SD_PATH_USER_CONFIGURATION, /* takes both actual configuration (like /etc) and state (like /var/lib) */
+        SD_PATH_USER_RUNTIME,
+        SD_PATH_USER_STATE_CACHE,
+
+        /* User resources */
+        SD_PATH_USER, /* $HOME itself */
+        SD_PATH_USER_DOCUMENTS,
+        SD_PATH_USER_MUSIC,
+        SD_PATH_USER_PICTURES,
+        SD_PATH_USER_VIDEOS,
+        SD_PATH_USER_DOWNLOAD,
+        SD_PATH_USER_PUBLIC,
+        SD_PATH_USER_TEMPLATES,
+        SD_PATH_USER_DESKTOP,
+
+        /* Search paths */
+        SD_PATH_SEARCH_BINARIES,
+        SD_PATH_SEARCH_LIBRARY_PRIVATE,
+        SD_PATH_SEARCH_LIBRARY_ARCH,
+        SD_PATH_SEARCH_SHARED,
+        SD_PATH_SEARCH_CONFIGURATION_FACTORY,
+        SD_PATH_SEARCH_STATE_FACTORY,
+        SD_PATH_SEARCH_CONFIGURATION,
+
+        _SD_PATH_MAX,
+};
+
+int sd_path_home(uint64_t type, const char *suffix, char **path);
+int sd_path_search(uint64_t type, const char *suffix, char ***paths);
+
+#endif
index ed8300c..bb30f9a 100644 (file)
@@ -32,17 +32,17 @@ extern "C" {
 #endif
 
 /*
-  Reference implementation of a few boot readahead related
+  Reference implementation of a few boot read-ahead-related
   interfaces. These interfaces are trivial to implement. To simplify
-  porting, we provide this reference implementation.  Applications are
+  porting, we provide this reference implementation. Applications are
   welcome to reimplement the algorithms described here if they do not
   want to include these two source files.
 
   You may compile this with -DDISABLE_SYSTEMD to disable systemd
   support. This makes all calls NOPs.
 
-  Since this is drop-in code we don't want any of our symbols to be
-  exported in any case. Hence we declare hidden visibility for all of
+  Because this is drop-in code, we don't want any of our symbols to be
+  exported in any case. Hence, we declare hidden visibility for all of
   them.
 
   You may find an up-to-date version of these source files online:
@@ -50,18 +50,18 @@ extern "C" {
   http://cgit.freedesktop.org/systemd/systemd/plain/src/systemd/sd-readahead.h
   http://cgit.freedesktop.org/systemd/systemd/plain/src/readahead/sd-readahead.c
 
-  This should compile on non-Linux systems, too, but all functions
+  This should compile on non-Linux systems too, but all functions
   will become NOPs.
 
   See sd-readahead(3) for more information.
 */
 
 /*
-  Controls ongoing disk read-ahead operations during boot-up. The argument
-  must be a string, and either "cancel", "done" or "noreplay".
+  Controls on-going disk read-ahead operations during boot-up. The argument
+  must be one of the following strings: "cancel", "done", or "noreplay".
 
-  cancel = terminate read-ahead data collection, drop collected information
-  done = terminate read-ahead data collection, keep collected information
+  cancel = terminate read-ahead data collection, and drop collected information
+  done = terminate read-ahead data collection, and keep collected information
   noreplay = terminate read-ahead replay
 */
 int sd_readahead(const char *action);
index df69e4b..36cedcd 100644 (file)
 #include <netdb.h>
 
 #include "_sd-common.h"
+#include "sd-event.h"
 
 _SD_BEGIN_DECLARATIONS;
 
-/** An opaque sd-resolve session structure */
+/* An opaque sd-resolve session structure */
 typedef struct sd_resolve sd_resolve;
 
-/** An opaque sd-resolve query structure */
+/* An opaque sd-resolve query structure */
 typedef struct sd_resolve_query sd_resolve_query;
 
-/** Allocate a new sd-resolve session */
+/* A callback on completion */
+typedef int (*sd_resolve_getaddrinfo_handler_t)(sd_resolve_query *q, int ret, const struct addrinfo *ai, void *userdata);
+typedef int (*sd_resolve_getnameinfo_handler_t)(sd_resolve_query *q, int ret, const char *host, const char *serv, void *userdata);
+typedef int (*sd_resolve_res_handler_t)(sd_resolve_query* q, int ret, unsigned char *answer, void *userdata);
+
+enum {
+        SD_RESOLVE_GET_HOST = 1ULL,
+        SD_RESOLVE_GET_SERVICE = 2ULL,
+        SD_RESOLVE_GET_BOTH = 3ULL
+};
+
+int sd_resolve_default(sd_resolve **ret);
+
+/* Allocate a new sd-resolve session. */
 int sd_resolve_new(sd_resolve **ret);
 
-/** Free a sd-resolve session. This destroys all attached
- * sd_resolve_query objects automatically */
+/* Free a sd-resolve session. This destroys all attached
+ * sd_resolve_query objects automatically. */
 sd_resolve* sd_resolve_unref(sd_resolve *resolve);
+sd_resolve* sd_resolve_ref(sd_resolve *resolve);
 
-/** Return the UNIX file descriptor to poll() for events on. Use this
+/* Return the UNIX file descriptor to poll() for events on. Use this
  * function to integrate sd-resolve with your custom main loop. */
 int sd_resolve_get_fd(sd_resolve *resolve);
 
-/** Return the poll() events (a combination of flags like POLLIN,
+/* Return the poll() events (a combination of flags like POLLIN,
  * POLLOUT, ...) to check for. */
 int sd_resolve_get_events(sd_resolve *resolve);
 
-/** Return the poll() timeout to pass. Returns (uint64_t) -1 as time
- * out if no time out is needed */
+/* Return the poll() timeout to pass. Returns (uint64_t) -1 as
+ * timeout if no timeout is needed. */
 int sd_resolve_get_timeout(sd_resolve *resolve, uint64_t *timeout_usec);
 
-/** Process pending responses. After this function is called you can
+/* Process pending responses. After this function is called, you can
  * get the next completed query object(s) using
  * sd_resolve_get_next(). */
 int sd_resolve_process(sd_resolve *resolve);
 
-/** Wait for a resolve event to complete */
+/* Wait for a resolve event to complete. */
 int sd_resolve_wait(sd_resolve *resolve, uint64_t timeout_usec);
 
-/** Issue a name to address query on the specified session. The
- * arguments are compatible with the ones of libc's
+int sd_resolve_get_tid(sd_resolve *resolve, pid_t *tid);
+
+int sd_resolve_attach_event(sd_resolve *resolve, sd_event *e, int priority);
+int sd_resolve_detach_event(sd_resolve *resolve);
+sd_event *sd_resolve_get_event(sd_resolve *resolve);
+
+/* Issue a name-to-address query on the specified session. The
+ * arguments are compatible with those of libc's
  * getaddrinfo(3). The function returns a new query object. When the
- * query is completed you may retrieve the results using
+ * query is completed, you may retrieve the results using
  * sd_resolve_getaddrinfo_done(). */
-int sd_resolve_getaddrinfo(sd_resolve *resolve, sd_resolve_query **q, const char *node, const char *service, const struct addrinfo *hints);
-
-/** Retrieve the results of a preceding sd_resolve_getaddrinfo()
- * call. Returns a addrinfo structure and a return value compatible
- * with libc's getaddrinfo(3). The query object q is destroyed by this
- * call and may not be used any further. Make sure to free the
- * returned addrinfo structure with sd_resolve_freeaddrinfo() and not
- * libc's freeaddrinfo(3)! If the query is not completed yet EAI_AGAIN
- * is returned. */
-int sd_resolve_getaddrinfo_done(sd_resolve_query* q, struct addrinfo **ret_ai);
-
-/** Free the addrinfo structure as returned by
- * sd_resolve_getaddrinfo_done(). Make sure to use this functions instead
- * of the libc's freeaddrinfo()! */
-void sd_resolve_freeaddrinfo(struct addrinfo *ai);
-
-/** Issue an address to name query on the specified session. The
- * arguments are compatible with the ones of libc's
+int sd_resolve_getaddrinfo(sd_resolve *resolve, sd_resolve_query **q, const char *node, const char *service, const struct addrinfo *hints, sd_resolve_getaddrinfo_handler_t callback, void *userdata);
+
+/* Issue an address-to-name query on the specified session. The
+ * arguments are compatible with those of libc's
  * getnameinfo(3). The function returns a new query object. When the
- * query is completed you may retrieve the results using
+ * query is completed, you may retrieve the results using
  * sd_resolve_getnameinfo_done(). Set gethost (resp. getserv) to non-zero
  * if you want to query the hostname (resp. the service name). */
-int sd_resolve_getnameinfo(sd_resolve *resolve, sd_resolve_query **q, const struct sockaddr *sa, socklen_t salen, int flags, int gethost, int getserv);
-
-/** Retrieve the results of a preceding sd_resolve_getnameinfo()
- * call. Returns the hostname and the service name in ret_host and
- * ret_serv. The query object q is destroyed by this call and may not
- * be used any further. If the query is not completed yet EAI_AGAIN is
- * returned. */
-int sd_resolve_getnameinfo_done(sd_resolve_query* q, char **ret_host, char **ret_serv);
-
-/** Issue a resolver query on the specified session. The arguments are
- * compatible with the ones of libc's res_query(3). The function returns a new
- * query object. When the query is completed you may retrieve the results using
- * sd_resolve_res_done().  */
-int sd_resolve_res_query(sd_resolve *resolve, sd_resolve_query **q, const char *dname, int class, int type);
-
-/** Issue an resolver query on the specified session. The arguments are
- * compatible with the ones of libc's res_search(3). The function returns a new
- * query object. When the query is completed you may retrieve the results using
- * sd_resolve_res_done().  */
-int sd_resolve_res_search(sd_resolve *resolve, sd_resolve_query **q, const char *dname, int class, int type);
-
-/** Retrieve the results of a preceding sd_resolve_res_query() or
- * resolve_res_search call.  The query object q is destroyed by this
- * call and may not be used any further. Returns a pointer to the
- * answer of the res_query call. If the query is not completed yet
- * -EAGAIN is returned, on failure -errno is returned, otherwise the
- * length of answer is returned. */
-int sd_resolve_res_done(sd_resolve_query* q, unsigned char **answer);
-
-/** Return the next completed query object. If no query has been
- * completed yet, return NULL. Please note that you need to run
- * sd_resolve_wait() before this function will return sensible data.  */
-int sd_resolve_get_next(sd_resolve *resolve, sd_resolve_query **q);
-
-/** Return the number of query objects (completed or not) attached to
- * this session */
-int sd_resolve_get_n_queries(sd_resolve *resolve);
-
-/** Cancel a currently running query. q is is destroyed by this call
- * and may not be used any futher. */
-int sd_resolve_cancel(sd_resolve_query* q);
-
-/** Returns non-zero when the query operation specified by q has been completed */
-int sd_resolve_is_done(sd_resolve_query*q);
-
-/** Assign some opaque userdata with a query object */
-void* sd_resolve_set_userdata(sd_resolve_query *q, void *userdata);
-
-/** Return userdata assigned to a query object. Use
- * sd_resolve_setuserdata() to set this data. If no data has been set
- * prior to this call it returns NULL. */
-void* sd_resolve_get_userdata(sd_resolve_query *q);
+int sd_resolve_getnameinfo(sd_resolve *resolve, sd_resolve_query **q, const struct sockaddr *sa, socklen_t salen, int flags, uint64_t get, sd_resolve_getnameinfo_handler_t callback, void *userdata);
+
+/* Issue a resolver query on the specified session. The arguments are
+ * compatible with those of libc's res_query(3). The function returns a new
+ * query object. When the query is completed, you may retrieve the results using
+ * sd_resolve_res_done(). */
+int sd_resolve_res_query(sd_resolve *resolve, sd_resolve_query **q, const char *dname, int clazz, int type, sd_resolve_res_handler_t callback, void *userdata);
+
+/* Issue a resolver query on the specified session. The arguments are
+ * compatible with those of libc's res_search(3). The function returns a new
+ * query object. When the query is completed, you may retrieve the results using
+ * sd_resolve_res_done(). */
+int sd_resolve_res_search(sd_resolve *resolve, sd_resolve_query **q, const char *dname, int clazz, int type, sd_resolve_res_handler_t callback, void *userdata);
+
+sd_resolve_query *sd_resolve_query_ref(sd_resolve_query* q);
+sd_resolve_query *sd_resolve_query_unref(sd_resolve_query* q);
+
+/* Returns non-zero when the query operation specified by q has been completed. */
+int sd_resolve_query_is_done(sd_resolve_query*q);
+
+void *sd_resolve_query_get_userdata(sd_resolve_query *q);
+void *sd_resolve_query_set_userdata(sd_resolve_query *q, void *userdata);
+
+sd_resolve *sd_resolve_query_get_resolve(sd_resolve_query *q);
 
 _SD_END_DECLARATIONS;
 
index f2b3a53..1e7eb81 100644 (file)
@@ -40,7 +40,7 @@ typedef struct sd_rtnl_message sd_rtnl_message;
 typedef int (*sd_rtnl_message_handler_t)(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata);
 
 /* bus */
-int sd_rtnl_open(sd_rtnl **nl, uint32_t groups);
+int sd_rtnl_open(sd_rtnl **nl, unsigned n_groups, ...);
 
 sd_rtnl *sd_rtnl_ref(sd_rtnl *nl);
 sd_rtnl *sd_rtnl_unref(sd_rtnl *nl);
@@ -68,27 +68,37 @@ int sd_rtnl_detach_event(sd_rtnl *nl);
 
 /* messages */
 int sd_rtnl_message_new_link(sd_rtnl *rtnl, sd_rtnl_message **ret, uint16_t msg_type, int index);
+int sd_rtnl_message_new_addr_update(sd_rtnl *rtnl, sd_rtnl_message **ret, int index, int family);
 int sd_rtnl_message_new_addr(sd_rtnl *rtnl, sd_rtnl_message **ret, uint16_t msg_type, int index,
-                             unsigned char family);
+                             int family);
 int sd_rtnl_message_new_route(sd_rtnl *rtnl, sd_rtnl_message **ret, uint16_t nlmsg_type,
-                              unsigned char rtm_family);
+                              int rtm_family, unsigned char rtm_protocol);
 
 sd_rtnl_message *sd_rtnl_message_ref(sd_rtnl_message *m);
 sd_rtnl_message *sd_rtnl_message_unref(sd_rtnl_message *m);
 
+int sd_rtnl_message_request_dump(sd_rtnl_message *m, int dump);
 int sd_rtnl_message_get_errno(sd_rtnl_message *m);
 int sd_rtnl_message_get_type(sd_rtnl_message *m, uint16_t *type);
+int sd_rtnl_message_is_broadcast(sd_rtnl_message *m);
 
 int sd_rtnl_message_addr_set_prefixlen(sd_rtnl_message *m, unsigned char prefixlen);
 int sd_rtnl_message_addr_set_scope(sd_rtnl_message *m, unsigned char scope);
 int sd_rtnl_message_addr_set_flags(sd_rtnl_message *m, unsigned char flags);
+int sd_rtnl_message_addr_get_family(sd_rtnl_message *m, int *family);
+int sd_rtnl_message_addr_get_prefixlen(sd_rtnl_message *m, unsigned char *prefixlen);
+int sd_rtnl_message_addr_get_scope(sd_rtnl_message *m, unsigned char *scope);
+int sd_rtnl_message_addr_get_flags(sd_rtnl_message *m, unsigned char *flags);
+int sd_rtnl_message_addr_get_ifindex(sd_rtnl_message *m, int *ifindex);
 
 int sd_rtnl_message_link_set_flags(sd_rtnl_message *m, unsigned flags, unsigned change);
 int sd_rtnl_message_link_set_type(sd_rtnl_message *m, unsigned type);
 int sd_rtnl_message_link_get_ifindex(sd_rtnl_message *m, int *ifindex);
 int sd_rtnl_message_link_get_flags(sd_rtnl_message *m, unsigned *flags);
+int sd_rtnl_message_link_get_type(sd_rtnl_message *m, unsigned *type);
 
 int sd_rtnl_message_route_set_dst_prefixlen(sd_rtnl_message *m, unsigned char prefixlen);
+int sd_rtnl_message_route_set_scope(sd_rtnl_message *m, unsigned char scope);
 
 int sd_rtnl_message_append_string(sd_rtnl_message *m, unsigned short type, const char *data);
 int sd_rtnl_message_append_u8(sd_rtnl_message *m, unsigned short type, uint8_t data);
@@ -97,15 +107,27 @@ int sd_rtnl_message_append_u32(sd_rtnl_message *m, unsigned short type, uint32_t
 int sd_rtnl_message_append_in_addr(sd_rtnl_message *m, unsigned short type, const struct in_addr *data);
 int sd_rtnl_message_append_in6_addr(sd_rtnl_message *m, unsigned short type, const struct in6_addr *data);
 int sd_rtnl_message_append_ether_addr(sd_rtnl_message *m, unsigned short type, const struct ether_addr *data);
+int sd_rtnl_message_append_cache_info(sd_rtnl_message *m, unsigned short type, const struct ifa_cacheinfo *info);
 
 int sd_rtnl_message_open_container(sd_rtnl_message *m, unsigned short type);
+int sd_rtnl_message_open_container_union(sd_rtnl_message *m, unsigned short type, const char *key);
 int sd_rtnl_message_close_container(sd_rtnl_message *m);
 
-int sd_rtnl_message_read(sd_rtnl_message *m, unsigned short *type, void **data);
+int sd_rtnl_message_read_string(sd_rtnl_message *m, unsigned short type, const char **data);
+int sd_rtnl_message_read_u8(sd_rtnl_message *m, unsigned short type, uint8_t *data);
+int sd_rtnl_message_read_u16(sd_rtnl_message *m, unsigned short type, uint16_t *data);
+int sd_rtnl_message_read_u32(sd_rtnl_message *m, unsigned short type, uint32_t *data);
+int sd_rtnl_message_read_ether_addr(sd_rtnl_message *m, unsigned short type, struct ether_addr *data);
+int sd_rtnl_message_read_cache_info(sd_rtnl_message *m, unsigned short type, struct ifa_cacheinfo *info);
+int sd_rtnl_message_read_in_addr(sd_rtnl_message *m, unsigned short type, struct in_addr *data);
+int sd_rtnl_message_read_in6_addr(sd_rtnl_message *m, unsigned short type, struct in6_addr *data);
+int sd_rtnl_message_enter_container(sd_rtnl_message *m, unsigned short type);
 int sd_rtnl_message_exit_container(sd_rtnl_message *m);
 
 int sd_rtnl_message_rewind(sd_rtnl_message *m);
 
+sd_rtnl_message *sd_rtnl_message_next(sd_rtnl_message *m);
+
 _SD_END_DECLARATIONS;
 
 #endif
index 1d65549..9ff377f 100644 (file)
@@ -71,46 +71,45 @@ struct sd_shutdown_command {
  * AF_UNIX/SOCK_DGRAM datagram with the structure above suffixed with
  * the wall message to the socket /run/systemd/shutdownd (leave an
  * empty wall message for the default shutdown message). To calculate
- * the size of the message use "offsetof(struct sd_shutdown_command,
+ * the size of the message, use "offsetof(struct sd_shutdown_command,
  * wall_message) + strlen(command.wall_message)".
  *
- * To cancel a shutdown, do the same, but send an fully zeroed out
+ * To cancel a shutdown, do the same, but send a fully zeroed-out
  * structure.
  *
  * To be notified about scheduled shutdowns, create an inotify watch
- * on /run/shutdown/. Whenever a file called "scheduled" appears a
- * shutdown is scheduled. If it is removed it is canceled. It is
- * replaced the scheduled shutdown has been changed. The file contains
- * a simple environment-like block, that contains information about
+ * on /run/shutdown/. Whenever a file called "scheduled" appears, a
+ * shutdown is scheduled. If it is removed, it is canceled. If it is
+ * replaced, the scheduled shutdown has been changed. The file contains
+ * a simple, environment-like block that contains information about
  * the scheduled shutdown:
  *
  * USEC=
  * encodes the time for the shutdown in usecs since the epoch UTC,
- * formatted as numeric string.
+ * formatted as numeric string.
  *
  * WARN_WALL=
  * is 1 if a wall message shall be sent
  *
  * DRY_RUN=
- * is 1 if a dry run shutdown is scheduled
+ * is 1 if a dry-run shutdown is scheduled
  *
  * MODE=
  * is the shutdown mode, one of "poweroff", "reboot", "halt", "kexec"
  *
  * WALL_MESSAGE=
- * is the wall message to use, with all special characters escape in C style.
+ * is the wall message to use, with all special characters escaped in C-style.
  *
  * Note that some fields might be missing if they do not apply.
  *
  * Note that the file is first written to a temporary file and then
  * renamed, in order to provide atomic properties for readers: if the
- * file exists under the name "scheduled" it is guaranteed to be fully
+ * file exists under the name "scheduled", it is guaranteed to be fully
  * written. A reader should ignore all files in that directory by any
  * other name.
  *
  * Scheduled shutdowns are only accepted from privileged processes,
- * but the directory may be watched and the file in it read by
- * anybody.
+ * but anyone may watch the directory and the file in it.
  */
 
 #ifdef __cplusplus
diff --git a/src/sysusers/Makefile b/src/sysusers/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c
new file mode 100644 (file)
index 0000000..d095859
--- /dev/null
@@ -0,0 +1,1972 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/types.h>
+#include <pwd.h>
+#include <grp.h>
+#include <shadow.h>
+#include <gshadow.h>
+#include <getopt.h>
+#include <utmp.h>
+
+#include "util.h"
+#include "hashmap.h"
+#include "specifier.h"
+#include "path-util.h"
+#include "build.h"
+#include "strv.h"
+#include "conf-files.h"
+#include "copy.h"
+#include "utf8.h"
+#include "label.h"
+#include "fileio-label.h"
+#include "uid-range.h"
+#include "smack-util.h"
+
+typedef enum ItemType {
+        ADD_USER = 'u',
+        ADD_GROUP = 'g',
+        ADD_MEMBER = 'm',
+        ADD_RANGE = 'r',
+} ItemType;
+typedef struct Item {
+        ItemType type;
+
+        char *name;
+        char *uid_path;
+        char *gid_path;
+        char *description;
+        char *home;
+
+        gid_t gid;
+        uid_t uid;
+
+        bool gid_set:1;
+        bool uid_set:1;
+
+        bool todo_user:1;
+        bool todo_group:1;
+} Item;
+
+static char *arg_root = NULL;
+
+static const char conf_file_dirs[] =
+        "/etc/sysusers.d\0"
+        "/run/sysusers.d\0"
+        "/usr/local/lib/sysusers.d\0"
+        "/usr/lib/sysusers.d\0"
+#ifdef HAVE_SPLIT_USR
+        "/lib/sysusers.d\0"
+#endif
+        ;
+
+static Hashmap *users = NULL, *groups = NULL;
+static Hashmap *todo_uids = NULL, *todo_gids = NULL;
+static Hashmap *members = NULL;
+
+static Hashmap *database_uid = NULL, *database_user = NULL;
+static Hashmap *database_gid = NULL, *database_group = NULL;
+
+static uid_t search_uid = (uid_t) -1;
+static UidRange *uid_range = NULL;
+static unsigned n_uid_range = 0;
+
+#define UID_TO_PTR(u) (ULONG_TO_PTR(u+1))
+#define PTR_TO_UID(u) ((uid_t) (PTR_TO_ULONG(u)-1))
+
+#define GID_TO_PTR(g) (ULONG_TO_PTR(g+1))
+#define PTR_TO_GID(g) ((gid_t) (PTR_TO_ULONG(g)-1))
+
+#define fix_root(x) (arg_root ? strappenda(arg_root, x) : x)
+
+static int load_user_database(void) {
+        _cleanup_fclose_ FILE *f = NULL;
+        const char *passwd_path;
+        struct passwd *pw;
+        int r;
+
+        passwd_path = fix_root("/etc/passwd");
+        f = fopen(passwd_path, "re");
+        if (!f)
+                return errno == ENOENT ? 0 : -errno;
+
+        r = hashmap_ensure_allocated(&database_user, string_hash_func, string_compare_func);
+        if (r < 0)
+                return r;
+
+        r = hashmap_ensure_allocated(&database_uid, trivial_hash_func, trivial_compare_func);
+        if (r < 0)
+                return r;
+
+        errno = 0;
+        while ((pw = fgetpwent(f))) {
+                char *n;
+                int k, q;
+
+                n = strdup(pw->pw_name);
+                if (!n)
+                        return -ENOMEM;
+
+                k = hashmap_put(database_user, n, UID_TO_PTR(pw->pw_uid));
+                if (k < 0 && k != -EEXIST) {
+                        free(n);
+                        return k;
+                }
+
+                q = hashmap_put(database_uid, UID_TO_PTR(pw->pw_uid), n);
+                if (q < 0 && q != -EEXIST) {
+                        if (k < 0)
+                                free(n);
+                        return q;
+                }
+
+                if (q < 0 && k < 0)
+                        free(n);
+
+                errno = 0;
+        }
+        if (!IN_SET(errno, 0, ENOENT))
+                return -errno;
+
+        return 0;
+}
+
+static int load_group_database(void) {
+        _cleanup_fclose_ FILE *f = NULL;
+        const char *group_path;
+        struct group *gr;
+        int r;
+
+        group_path = fix_root("/etc/group");
+        f = fopen(group_path, "re");
+        if (!f)
+                return errno == ENOENT ? 0 : -errno;
+
+        r = hashmap_ensure_allocated(&database_group, string_hash_func, string_compare_func);
+        if (r < 0)
+                return r;
+
+        r = hashmap_ensure_allocated(&database_gid, trivial_hash_func, trivial_compare_func);
+        if (r < 0)
+                return r;
+
+        errno = 0;
+        while ((gr = fgetgrent(f))) {
+                char *n;
+                int k, q;
+
+                n = strdup(gr->gr_name);
+                if (!n)
+                        return -ENOMEM;
+
+                k = hashmap_put(database_group, n, GID_TO_PTR(gr->gr_gid));
+                if (k < 0 && k != -EEXIST) {
+                        free(n);
+                        return k;
+                }
+
+                q = hashmap_put(database_gid, GID_TO_PTR(gr->gr_gid), n);
+                if (q < 0 && q != -EEXIST) {
+                        if (k < 0)
+                                free(n);
+                        return q;
+                }
+
+                if (q < 0 && k < 0)
+                        free(n);
+
+                errno = 0;
+        }
+        if (!IN_SET(errno, 0, ENOENT))
+                return -errno;
+
+        return 0;
+}
+
+static int make_backup(const char *target, const char *x) {
+        _cleanup_close_ int src = -1;
+        _cleanup_fclose_ FILE *dst = NULL;
+        char *backup, *temp;
+        struct timespec ts[2];
+        struct stat st;
+        int r;
+
+        src = open(x, O_RDONLY|O_CLOEXEC|O_NOCTTY);
+        if (src < 0) {
+                if (errno == ENOENT) /* No backup necessary... */
+                        return 0;
+
+                return -errno;
+        }
+
+        if (fstat(src, &st) < 0)
+                return -errno;
+
+        r = fopen_temporary_label(target, x, &dst, &temp);
+        if (r < 0)
+                return r;
+
+        r = copy_bytes(src, fileno(dst), (off_t) -1);
+        if (r < 0)
+                goto fail;
+
+        /* Don't fail on chmod() or chown(). If it stays owned by us
+         * and/or unreadable by others, then it isn't too bad... */
+
+        backup = strappenda(x, "-");
+
+        /* Copy over the access mask */
+        if (fchmod(fileno(dst), st.st_mode & 07777) < 0)
+                log_warning("Failed to change mode on %s: %m", backup);
+
+        if (fchown(fileno(dst), st.st_uid, st.st_gid)< 0)
+                log_warning("Failed to change ownership of %s: %m", backup);
+
+        ts[0] = st.st_atim;
+        ts[1] = st.st_mtim;
+        futimens(fileno(dst), ts);
+
+        if (rename(temp, backup) < 0)
+                goto fail;
+
+        return 0;
+
+fail:
+        unlink(temp);
+        return r;
+}
+
+static int putgrent_with_members(const struct group *gr, FILE *group) {
+        char **a;
+
+        assert(gr);
+        assert(group);
+
+        a = hashmap_get(members, gr->gr_name);
+        if (a) {
+                _cleanup_strv_free_ char **l = NULL;
+                bool added = false;
+                char **i;
+
+                l = strv_copy(gr->gr_mem);
+                if (!l)
+                        return -ENOMEM;
+
+                STRV_FOREACH(i, a) {
+                        if (strv_find(l, *i))
+                                continue;
+
+                        if (strv_extend(&l, *i) < 0)
+                                return -ENOMEM;
+
+                        added = true;
+                }
+
+                if (added) {
+                        struct group t;
+
+                        strv_uniq(l);
+                        strv_sort(l);
+
+                        t = *gr;
+                        t.gr_mem = l;
+
+                        errno = 0;
+                        if (putgrent(&t, group) != 0)
+                                return errno ? -errno : -EIO;
+
+                        return 1;
+                }
+        }
+
+        errno = 0;
+        if (putgrent(gr, group) != 0)
+                return errno ? -errno : -EIO;
+
+        return 0;
+}
+
+static int putsgent_with_members(const struct sgrp *sg, FILE *gshadow) {
+        char **a;
+
+        assert(sg);
+        assert(gshadow);
+
+        a = hashmap_get(members, sg->sg_namp);
+        if (a) {
+                _cleanup_strv_free_ char **l = NULL;
+                bool added = false;
+                char **i;
+
+                l = strv_copy(sg->sg_mem);
+                if (!l)
+                        return -ENOMEM;
+
+                STRV_FOREACH(i, a) {
+                        if (strv_find(l, *i))
+                                continue;
+
+                        if (strv_extend(&l, *i) < 0)
+                                return -ENOMEM;
+
+                        added = true;
+                }
+
+                if (added) {
+                        struct sgrp t;
+
+                        strv_uniq(l);
+                        strv_sort(l);
+
+                        t = *sg;
+                        t.sg_mem = l;
+
+                        errno = 0;
+                        if (putsgent(&t, gshadow) != 0)
+                                return errno ? -errno : -EIO;
+
+                        return 1;
+                }
+        }
+
+        errno = 0;
+        if (putsgent(sg, gshadow) != 0)
+                return errno ? -errno : -EIO;
+
+        return 0;
+}
+
+static int write_files(void) {
+
+        _cleanup_fclose_ FILE *passwd = NULL, *group = NULL, *shadow = NULL, *gshadow = NULL;
+        _cleanup_free_ char *passwd_tmp = NULL, *group_tmp = NULL, *shadow_tmp = NULL, *gshadow_tmp = NULL;
+        const char *passwd_path = NULL, *group_path = NULL, *shadow_path = NULL, *gshadow_path = NULL;
+        _cleanup_free_ char *passwd_label = NULL, *group_label = NULL, *shadow_label = NULL, *gshadow_label = NULL;
+        bool group_changed = false;
+        Iterator iterator;
+        Item *i;
+        int r;
+
+        if (hashmap_size(todo_gids) > 0 || hashmap_size(members) > 0) {
+                _cleanup_fclose_ FILE *original = NULL;
+
+                /* First we update the actual group list file */
+                group_path = fix_root("/etc/group");
+                r = fopen_temporary_label("/etc/group", group_path, &group, &group_tmp);
+                if (r < 0)
+                        goto finish;
+
+                if (fchmod(fileno(group), 0644) < 0) {
+                        r = -errno;
+                        goto finish;
+                }
+
+                original = fopen(group_path, "re");
+                if (original) {
+                        struct group *gr;
+
+                        r = smack_label_get_path(group_path, &group_label);
+                        if (r < 0) {
+                                log_warning("Failed to get smack label from %s", group_path);
+                        }
+
+                        errno = 0;
+                        while ((gr = fgetgrent(original))) {
+                                /* Safety checks against name and GID
+                                 * collisions. Normally, this should
+                                 * be unnecessary, but given that we
+                                 * look at the entries anyway here,
+                                 * let's make an extra verification
+                                 * step that we don't generate
+                                 * duplicate entries. */
+
+                                i = hashmap_get(groups, gr->gr_name);
+                                if (i && i->todo_group) {
+                                        r = -EEXIST;
+                                        goto finish;
+                                }
+
+                                if (hashmap_contains(todo_gids, GID_TO_PTR(gr->gr_gid))) {
+                                        r = -EEXIST;
+                                        goto finish;
+                                }
+
+                                r = putgrent_with_members(gr, group);
+                                if (r < 0)
+                                        goto finish;
+                                if (r > 0)
+                                        group_changed = true;
+
+                                errno = 0;
+                        }
+                        if (!IN_SET(errno, 0, ENOENT)) {
+                                r = -errno;
+                                goto finish;
+                        }
+
+                } else if (errno != ENOENT) {
+                        r = -errno;
+                        goto finish;
+                }
+
+                HASHMAP_FOREACH(i, todo_gids, iterator) {
+                        struct group n = {
+                                .gr_name = i->name,
+                                .gr_gid = i->gid,
+                                .gr_passwd = (char*) "x",
+                        };
+
+                        r = putgrent_with_members(&n, group);
+                        if (r < 0)
+                                goto finish;
+
+                        group_changed = true;
+                }
+
+                r = fflush_and_check(group);
+                if (r < 0)
+                        goto finish;
+
+                if (original) {
+                        fclose(original);
+                        original = NULL;
+                }
+
+                /* OK, now also update the shadow file for the group list */
+                gshadow_path = fix_root("/etc/gshadow");
+                r = fopen_temporary_label("/etc/gshadow", gshadow_path, &gshadow, &gshadow_tmp);
+                if (r < 0)
+                        goto finish;
+
+                if (fchmod(fileno(gshadow), 0000) < 0) {
+                        r = -errno;
+                        goto finish;
+                }
+
+                original = fopen(gshadow_path, "re");
+                if (original) {
+                        struct sgrp *sg;
+
+                        r = smack_label_get_path(gshadow_path, &gshadow_label);
+                        if (r < 0) {
+                                log_warning("Failed to get smack label from %s", gshadow_path);
+                        }
+
+                        errno = 0;
+                        while ((sg = fgetsgent(original))) {
+
+                                i = hashmap_get(groups, sg->sg_namp);
+                                if (i && i->todo_group) {
+                                        r = -EEXIST;
+                                        goto finish;
+                                }
+
+                                r = putsgent_with_members(sg, gshadow);
+                                if (r < 0)
+                                        goto finish;
+                                if (r > 0)
+                                        group_changed = true;
+
+                                errno = 0;
+                        }
+                        if (!IN_SET(errno, 0, ENOENT)) {
+                                r = -errno;
+                                goto finish;
+                        }
+
+                } else if (errno != ENOENT) {
+                        r = -errno;
+                        goto finish;
+                }
+
+                HASHMAP_FOREACH(i, todo_gids, iterator) {
+                        struct sgrp n = {
+                                .sg_namp = i->name,
+                                .sg_passwd = (char*) "!!",
+                        };
+
+                        r = putsgent_with_members(&n, gshadow);
+                        if (r < 0)
+                                goto finish;
+
+                        group_changed = true;
+                }
+
+                r = fflush_and_check(gshadow);
+                if (r < 0)
+                        goto finish;
+        }
+
+        if (hashmap_size(todo_uids) > 0) {
+                _cleanup_fclose_ FILE *original = NULL;
+                long lstchg;
+
+                /* First we update the user database itself */
+                passwd_path = fix_root("/etc/passwd");
+                r = fopen_temporary_label("/etc/passwd", passwd_path, &passwd, &passwd_tmp);
+                if (r < 0)
+                        goto finish;
+
+                if (fchmod(fileno(passwd), 0644) < 0) {
+                        r = -errno;
+                        goto finish;
+                }
+
+                original = fopen(passwd_path, "re");
+                if (original) {
+                        struct passwd *pw;
+
+                        r = smack_label_get_path(passwd_path, &passwd_label);
+                        if (r < 0) {
+                                log_warning("Failed to get smack label from %s", passwd_path);
+                        }
+
+                        errno = 0;
+                        while ((pw = fgetpwent(original))) {
+
+                                i = hashmap_get(users, pw->pw_name);
+                                if (i && i->todo_user) {
+                                        r = -EEXIST;
+                                        goto finish;
+                                }
+
+                                if (hashmap_contains(todo_uids, UID_TO_PTR(pw->pw_uid))) {
+                                        r = -EEXIST;
+                                        goto finish;
+                                }
+
+                                errno = 0;
+                                if (putpwent(pw, passwd) < 0) {
+                                        r = errno ? -errno : -EIO;
+                                        goto finish;
+                                }
+
+                                errno = 0;
+                        }
+                        if (!IN_SET(errno, 0, ENOENT)) {
+                                r = -errno;
+                                goto finish;
+                        }
+
+                } else if (errno != ENOENT) {
+                        r = -errno;
+                        goto finish;
+                }
+
+                HASHMAP_FOREACH(i, todo_uids, iterator) {
+                        struct passwd n = {
+                                .pw_name = i->name,
+                                .pw_uid = i->uid,
+                                .pw_gid = i->gid,
+                                .pw_gecos = i->description,
+
+                                /* "x" means the password is stored in
+                                 * the shadow file */
+                                .pw_passwd = (char*) "x",
+
+                                /* We default to the root directory as home */
+                                .pw_dir = i->home ? i->home : (char*) "/",
+
+                                /* Initialize the shell to nologin,
+                                 * with one exception: for root we
+                                 * patch in something special */
+                                .pw_shell = i->uid == 0 ? (char*) "/bin/sh" : (char*) "/sbin/nologin",
+                        };
+
+                        errno = 0;
+                        if (putpwent(&n, passwd) != 0) {
+                                r = errno ? -errno : -EIO;
+                                goto finish;
+                        }
+                }
+
+                r = fflush_and_check(passwd);
+                if (r < 0)
+                        goto finish;
+
+                if (original) {
+                        fclose(original);
+                        original = NULL;
+                }
+
+                /* The we update the shadow database */
+                shadow_path = fix_root("/etc/shadow");
+                r = fopen_temporary_label("/etc/shadow", shadow_path, &shadow, &shadow_tmp);
+                if (r < 0)
+                        goto finish;
+
+                if (fchmod(fileno(shadow), 0000) < 0) {
+                        r = -errno;
+                        goto finish;
+                }
+
+                original = fopen(shadow_path, "re");
+                if (original) {
+                        struct spwd *sp;
+
+                        r = smack_label_get_path(shadow_path, &shadow_label);
+                        if (r < 0) {
+                                log_warning("Failed to get smack label from %s", passwd_path);
+                        }
+
+                        errno = 0;
+                        while ((sp = fgetspent(original))) {
+
+                                i = hashmap_get(users, sp->sp_namp);
+                                if (i && i->todo_user) {
+                                        r = -EEXIST;
+                                        goto finish;
+                                }
+
+                                errno = 0;
+                                if (putspent(sp, shadow) < 0) {
+                                        r = errno ? -errno : -EIO;
+                                        goto finish;
+                                }
+
+                                errno = 0;
+                        }
+                        if (!IN_SET(errno, 0, ENOENT)) {
+                                r = -errno;
+                                goto finish;
+                        }
+                } else if (errno != ENOENT) {
+                        r = -errno;
+                        goto finish;
+                }
+
+                lstchg = (long) (now(CLOCK_REALTIME) / USEC_PER_DAY);
+                HASHMAP_FOREACH(i, todo_uids, iterator) {
+                        struct spwd n = {
+                                .sp_namp = i->name,
+                                .sp_pwdp = (char*) "!!",
+                                .sp_lstchg = lstchg,
+                                .sp_min = -1,
+                                .sp_max = -1,
+                                .sp_warn = -1,
+                                .sp_inact = -1,
+                                .sp_expire = -1,
+                                .sp_flag = (unsigned long) -1, /* this appears to be what everybody does ... */
+                        };
+
+                        errno = 0;
+                        if (putspent(&n, shadow) != 0) {
+                                r = errno ? -errno : -EIO;
+                                goto finish;
+                        }
+                }
+
+                r = fflush_and_check(shadow);
+                if (r < 0)
+                        goto finish;
+        }
+
+        /* Make a backup of the old files */
+        if (group_changed) {
+                if (group) {
+                        r = make_backup("/etc/group", group_path);
+                        if (r < 0)
+                                goto finish;
+                }
+                if (gshadow) {
+                        r = make_backup("/etc/gshadow", gshadow_path);
+                        if (r < 0)
+                                goto finish;
+                }
+        }
+
+        if (passwd) {
+                r = make_backup("/etc/passwd", passwd_path);
+                if (r < 0)
+                        goto finish;
+        }
+        if (shadow) {
+                r = make_backup("/etc/shadow", shadow_path);
+                if (r < 0)
+                        goto finish;
+        }
+
+        /* And make the new files count */
+        if (group_changed) {
+                if (group) {
+                        if (rename(group_tmp, group_path) < 0) {
+                                r = -errno;
+                                goto finish;
+                        }
+
+                        if (group_label)
+                                smack_label_path(group_path, group_label);
+
+                        free(group_tmp);
+                        free(group_label);
+                        group_tmp = NULL;
+                }
+                if (gshadow) {
+                        if (rename(gshadow_tmp, gshadow_path) < 0) {
+                                r = -errno;
+                                goto finish;
+                        }
+
+                        if (gshadow_label)
+                                smack_label_path(gshadow_path, gshadow_label);
+
+                        free(gshadow_tmp);
+                        free(gshadow_label);
+                        gshadow_tmp = NULL;
+                }
+        }
+
+        if (passwd) {
+                if (rename(passwd_tmp, passwd_path) < 0) {
+                        r = -errno;
+                        goto finish;
+                }
+
+                if (passwd_label)
+                        smack_label_path(passwd_path, passwd_label);
+
+                free(passwd_tmp);
+                free(passwd_label);
+                passwd_tmp = NULL;
+        }
+        if (shadow) {
+                if (rename(shadow_tmp, shadow_path) < 0) {
+                        r = -errno;
+                        goto finish;
+                }
+
+                if (shadow_label)
+                        smack_label_path(shadow_path, shadow_label);
+
+                free(shadow_tmp);
+                free(shadow_label);
+                shadow_tmp = NULL;
+        }
+
+        r = 0;
+
+finish:
+        if (passwd_tmp)
+                unlink(passwd_tmp);
+        if (shadow_tmp)
+                unlink(shadow_tmp);
+        if (group_tmp)
+                unlink(group_tmp);
+        if (gshadow_tmp)
+                unlink(gshadow_tmp);
+
+        return r;
+}
+
+static int uid_is_ok(uid_t uid, const char *name) {
+        struct passwd *p;
+        struct group *g;
+        const char *n;
+        Item *i;
+
+        /* Let's see if we already have assigned the UID a second time */
+        if (hashmap_get(todo_uids, UID_TO_PTR(uid)))
+                return 0;
+
+        /* Try to avoid using uids that are already used by a group
+         * that doesn't have the same name as our new user. */
+        i = hashmap_get(todo_gids, GID_TO_PTR(uid));
+        if (i && !streq(i->name, name))
+                return 0;
+
+        /* Let's check the files directly */
+        if (hashmap_contains(database_uid, UID_TO_PTR(uid)))
+                return 0;
+
+        n = hashmap_get(database_gid, GID_TO_PTR(uid));
+        if (n && !streq(n, name))
+                return 0;
+
+        /* Let's also check via NSS, to avoid UID clashes over LDAP and such, just in case */
+        if (!arg_root) {
+                errno = 0;
+                p = getpwuid(uid);
+                if (p)
+                        return 0;
+                if (!IN_SET(errno, 0, ENOENT))
+                        return -errno;
+
+                errno = 0;
+                g = getgrgid((gid_t) uid);
+                if (g) {
+                        if (!streq(g->gr_name, name))
+                                return 0;
+                } else if (!IN_SET(errno, 0, ENOENT))
+                        return -errno;
+        }
+
+        return 1;
+}
+
+static int root_stat(const char *p, struct stat *st) {
+        const char *fix;
+
+        fix = fix_root(p);
+        if (stat(fix, st) < 0)
+                return -errno;
+
+        return 0;
+}
+
+static int read_id_from_file(Item *i, uid_t *_uid, gid_t *_gid) {
+        struct stat st;
+        bool found_uid = false, found_gid = false;
+        uid_t uid;
+        gid_t gid;
+
+        assert(i);
+
+        /* First, try to get the gid directly */
+        if (_gid && i->gid_path && root_stat(i->gid_path, &st) >= 0) {
+                gid = st.st_gid;
+                found_gid = true;
+        }
+
+        /* Then, try to get the uid directly */
+        if ((_uid || (_gid && !found_gid))
+            && i->uid_path
+            && root_stat(i->uid_path, &st) >= 0) {
+
+                uid = st.st_uid;
+                found_uid = true;
+
+                /* If we need the gid, but had no success yet, also derive it from the uid path */
+                if (_gid && !found_gid) {
+                        gid = st.st_gid;
+                        found_gid = true;
+                }
+        }
+
+        /* If that didn't work yet, then let's reuse the gid as uid */
+        if (_uid && !found_uid && i->gid_path) {
+
+                if (found_gid) {
+                        uid = (uid_t) gid;
+                        found_uid = true;
+                } else if (root_stat(i->gid_path, &st) >= 0) {
+                        uid = (uid_t) st.st_gid;
+                        found_uid = true;
+                }
+        }
+
+        if (_uid) {
+                if (!found_uid)
+                        return 0;
+
+                *_uid = uid;
+        }
+
+        if (_gid) {
+                if (!found_gid)
+                        return 0;
+
+                *_gid = gid;
+        }
+
+        return 1;
+}
+
+static int add_user(Item *i) {
+        void *z;
+        int r;
+
+        assert(i);
+
+        /* Check the database directly */
+        z = hashmap_get(database_user, i->name);
+        if (z) {
+                log_debug("User %s already exists.", i->name);
+                i->uid = PTR_TO_UID(z);
+                i->uid_set = true;
+                return 0;
+        }
+
+        if (!arg_root) {
+                struct passwd *p;
+                struct spwd *sp;
+
+                /* Also check NSS */
+                errno = 0;
+                p = getpwnam(i->name);
+                if (p) {
+                        log_debug("User %s already exists.", i->name);
+                        i->uid = p->pw_uid;
+                        i->uid_set = true;
+
+                        free(i->description);
+                        i->description = strdup(p->pw_gecos);
+                        return 0;
+                }
+                if (!IN_SET(errno, 0, ENOENT)) {
+                        log_error("Failed to check if user %s already exists: %m", i->name);
+                        return -errno;
+                }
+
+                /* And shadow too, just to be sure */
+                errno = 0;
+                sp = getspnam(i->name);
+                if (sp) {
+                        log_error("User %s already exists in shadow database, but not in user database.", i->name);
+                        return -EBADMSG;
+                }
+                if (!IN_SET(errno, 0, ENOENT)) {
+                        log_error("Failed to check if user %s already exists in shadow database: %m", i->name);
+                        return -errno;
+                }
+        }
+
+        /* Try to use the suggested numeric uid */
+        if (i->uid_set) {
+                r = uid_is_ok(i->uid, i->name);
+                if (r < 0) {
+                        log_error("Failed to verify uid " UID_FMT ": %s", i->uid, strerror(-r));
+                        return r;
+                }
+                if (r == 0) {
+                        log_debug("Suggested user ID " UID_FMT " for %s already used.", i->uid, i->name);
+                        i->uid_set = false;
+                }
+        }
+
+        /* If that didn't work, try to read it from the specified path */
+        if (!i->uid_set) {
+                uid_t c;
+
+                if (read_id_from_file(i, &c, NULL) > 0) {
+
+                        if (c <= 0 || !uid_range_contains(uid_range, n_uid_range, c))
+                                log_debug("User ID " UID_FMT " of file not suitable for %s.", c, i->name);
+                        else {
+                                r = uid_is_ok(c, i->name);
+                                if (r < 0) {
+                                        log_error("Failed to verify uid " UID_FMT ": %s", i->uid, strerror(-r));
+                                        return r;
+                                } else if (r > 0) {
+                                        i->uid = c;
+                                        i->uid_set = true;
+                                } else
+                                        log_debug("User ID " UID_FMT " of file for %s is already used.", c, i->name);
+                        }
+                }
+        }
+
+        /* Otherwise try to reuse the group ID */
+        if (!i->uid_set && i->gid_set) {
+                r = uid_is_ok((uid_t) i->gid, i->name);
+                if (r < 0) {
+                        log_error("Failed to verify uid " UID_FMT ": %s", i->uid, strerror(-r));
+                        return r;
+                }
+                if (r > 0) {
+                        i->uid = (uid_t) i->gid;
+                        i->uid_set = true;
+                }
+        }
+
+        /* And if that didn't work either, let's try to find a free one */
+        if (!i->uid_set) {
+                for (;;) {
+                        r = uid_range_next_lower(uid_range, n_uid_range, &search_uid);
+                        if (r < 0) {
+                                log_error("No free user ID available for %s.", i->name);
+                                return r;
+                        }
+
+                        r = uid_is_ok(search_uid, i->name);
+                        if (r < 0) {
+                                log_error("Failed to verify uid " UID_FMT ": %s", i->uid, strerror(-r));
+                                return r;
+                        } else if (r > 0)
+                                break;
+                }
+
+                i->uid_set = true;
+                i->uid = search_uid;
+        }
+
+        r = hashmap_ensure_allocated(&todo_uids, trivial_hash_func, trivial_compare_func);
+        if (r < 0)
+                return log_oom();
+
+        r = hashmap_put(todo_uids, UID_TO_PTR(i->uid), i);
+        if (r < 0)
+                return log_oom();
+
+        i->todo_user = true;
+        log_info("Creating user %s (%s) with uid " UID_FMT " and gid " GID_FMT ".", i->name, strna(i->description), i->uid, i->gid);
+
+        return 0;
+}
+
+static int gid_is_ok(gid_t gid) {
+        struct group *g;
+        struct passwd *p;
+
+        if (hashmap_get(todo_gids, GID_TO_PTR(gid)))
+                return 0;
+
+        /* Avoid reusing gids that are already used by a different user */
+        if (hashmap_get(todo_uids, UID_TO_PTR(gid)))
+                return 0;
+
+        if (hashmap_contains(database_gid, GID_TO_PTR(gid)))
+                return 0;
+
+        if (hashmap_contains(database_uid, UID_TO_PTR(gid)))
+                return 0;
+
+        if (!arg_root) {
+                errno = 0;
+                g = getgrgid(gid);
+                if (g)
+                        return 0;
+                if (!IN_SET(errno, 0, ENOENT))
+                        return -errno;
+
+                errno = 0;
+                p = getpwuid((uid_t) gid);
+                if (p)
+                        return 0;
+                if (!IN_SET(errno, 0, ENOENT))
+                        return -errno;
+        }
+
+        return 1;
+}
+
+static int add_group(Item *i) {
+        void *z;
+        int r;
+
+        assert(i);
+
+        /* Check the database directly */
+        z = hashmap_get(database_group, i->name);
+        if (z) {
+                log_debug("Group %s already exists.", i->name);
+                i->gid = PTR_TO_GID(z);
+                i->gid_set = true;
+                return 0;
+        }
+
+        /* Also check NSS */
+        if (!arg_root) {
+                struct group *g;
+
+                errno = 0;
+                g = getgrnam(i->name);
+                if (g) {
+                        log_debug("Group %s already exists.", i->name);
+                        i->gid = g->gr_gid;
+                        i->gid_set = true;
+                        return 0;
+                }
+                if (!IN_SET(errno, 0, ENOENT)) {
+                        log_error("Failed to check if group %s already exists: %m", i->name);
+                        return -errno;
+                }
+        }
+
+        /* Try to use the suggested numeric gid */
+        if (i->gid_set) {
+                r = gid_is_ok(i->gid);
+                if (r < 0) {
+                        log_error("Failed to verify gid " GID_FMT ": %s", i->gid, strerror(-r));
+                        return r;
+                }
+                if (r == 0) {
+                        log_debug("Suggested group ID " GID_FMT " for %s already used.", i->gid, i->name);
+                        i->gid_set = false;
+                }
+        }
+
+        /* Try to reuse the numeric uid, if there's one */
+        if (!i->gid_set && i->uid_set) {
+                r = gid_is_ok((gid_t) i->uid);
+                if (r < 0) {
+                        log_error("Failed to verify gid " GID_FMT ": %s", i->gid, strerror(-r));
+                        return r;
+                }
+                if (r > 0) {
+                        i->gid = (gid_t) i->uid;
+                        i->gid_set = true;
+                }
+        }
+
+        /* If that didn't work, try to read it from the specified path */
+        if (!i->gid_set) {
+                gid_t c;
+
+                if (read_id_from_file(i, NULL, &c) > 0) {
+
+                        if (c <= 0 || !uid_range_contains(uid_range, n_uid_range, c))
+                                log_debug("Group ID " GID_FMT " of file not suitable for %s.", c, i->name);
+                        else {
+                                r = gid_is_ok(c);
+                                if (r < 0) {
+                                        log_error("Failed to verify gid " GID_FMT ": %s", i->gid, strerror(-r));
+                                        return r;
+                                } else if (r > 0) {
+                                        i->gid = c;
+                                        i->gid_set = true;
+                                } else
+                                        log_debug("Group ID " GID_FMT " of file for %s already used.", c, i->name);
+                        }
+                }
+        }
+
+        /* And if that didn't work either, let's try to find a free one */
+        if (!i->gid_set) {
+                for (;;) {
+                        /* We look for new GIDs in the UID pool! */
+                        r = uid_range_next_lower(uid_range, n_uid_range, &search_uid);
+                        if (r < 0) {
+                                log_error("No free group ID available for %s.", i->name);
+                                return r;
+                        }
+
+                        r = gid_is_ok(search_uid);
+                        if (r < 0) {
+                                log_error("Failed to verify gid " GID_FMT ": %s", i->gid, strerror(-r));
+                                return r;
+                        } else if (r > 0)
+                                break;
+                }
+
+                i->gid_set = true;
+                i->gid = search_uid;
+        }
+
+        r = hashmap_ensure_allocated(&todo_gids, trivial_hash_func, trivial_compare_func);
+        if (r < 0)
+                return log_oom();
+
+        r = hashmap_put(todo_gids, GID_TO_PTR(i->gid), i);
+        if (r < 0)
+                return log_oom();
+
+        i->todo_group = true;
+        log_info("Creating group %s with gid " GID_FMT ".", i->name, i->gid);
+
+        return 0;
+}
+
+static int process_item(Item *i) {
+        int r;
+
+        assert(i);
+
+        switch (i->type) {
+
+        case ADD_USER:
+                r = add_group(i);
+                if (r < 0)
+                        return r;
+
+                return add_user(i);
+
+        case ADD_GROUP: {
+                Item *j;
+
+                j = hashmap_get(users, i->name);
+                if (j) {
+                        /* There's already user to be created for this
+                         * name, let's process that in one step */
+
+                        if (i->gid_set) {
+                                j->gid = i->gid;
+                                j->gid_set = true;
+                        }
+
+                        if (i->gid_path) {
+                                free(j->gid_path);
+                                j->gid_path = strdup(i->gid_path);
+                                if (!j->gid_path)
+                                        return log_oom();
+                        }
+
+                        return 0;
+                }
+
+                return add_group(i);
+        }
+
+        default:
+                assert_not_reached("Unknown item type");
+        }
+}
+
+static void item_free(Item *i) {
+
+        if (!i)
+                return;
+
+        free(i->name);
+        free(i->uid_path);
+        free(i->gid_path);
+        free(i->description);
+        free(i);
+}
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(Item*, item_free);
+
+static int add_implicit(void) {
+        char *g, **l;
+        Iterator iterator;
+        int r;
+
+        /* Implicitly create additional users and groups, if they were listed in "m" lines */
+
+        HASHMAP_FOREACH_KEY(l, g, members, iterator) {
+                Item *i;
+                char **m;
+
+                i = hashmap_get(groups, g);
+                if (!i) {
+                        _cleanup_(item_freep) Item *j = NULL;
+
+                        r = hashmap_ensure_allocated(&groups, string_hash_func, string_compare_func);
+                        if (r < 0)
+                                return log_oom();
+
+                        j = new0(Item, 1);
+                        if (!j)
+                                return log_oom();
+
+                        j->type = ADD_GROUP;
+                        j->name = strdup(g);
+                        if (!j->name)
+                                return log_oom();
+
+                        r = hashmap_put(groups, j->name, j);
+                        if (r < 0)
+                                return log_oom();
+
+                        log_debug("Adding implicit group '%s' due to m line", j->name);
+                        j = NULL;
+                }
+
+                STRV_FOREACH(m, l) {
+
+                        i = hashmap_get(users, *m);
+                        if (!i) {
+                                _cleanup_(item_freep) Item *j = NULL;
+
+                                r = hashmap_ensure_allocated(&users, string_hash_func, string_compare_func);
+                                if (r < 0)
+                                        return log_oom();
+
+                                j = new0(Item, 1);
+                                if (!j)
+                                        return log_oom();
+
+                                j->type = ADD_USER;
+                                j->name = strdup(*m);
+                                if (!j->name)
+                                        return log_oom();
+
+                                r = hashmap_put(users, j->name, j);
+                                if (r < 0)
+                                        return log_oom();
+
+                                log_debug("Adding implicit user '%s' due to m line", j->name);
+                                j = NULL;
+                        }
+                }
+        }
+
+        return 0;
+}
+
+static bool item_equal(Item *a, Item *b) {
+        assert(a);
+        assert(b);
+
+        if (a->type != b->type)
+                return false;
+
+        if (!streq_ptr(a->name, b->name))
+                return false;
+
+        if (!streq_ptr(a->uid_path, b->uid_path))
+                return false;
+
+        if (!streq_ptr(a->gid_path, b->gid_path))
+                return false;
+
+        if (!streq_ptr(a->description, b->description))
+                return false;
+
+        if (a->uid_set != b->uid_set)
+                return false;
+
+        if (a->uid_set && a->uid != b->uid)
+                return false;
+
+        if (a->gid_set != b->gid_set)
+                return false;
+
+        if (a->gid_set && a->gid != b->gid)
+                return false;
+
+        if (!streq_ptr(a->home, b->home))
+                return false;
+
+        return true;
+}
+
+static bool valid_user_group_name(const char *u) {
+        const char *i;
+        long sz;
+
+        if (isempty(u))
+                return false;
+
+        if (!(u[0] >= 'a' && u[0] <= 'z') &&
+            !(u[0] >= 'A' && u[0] <= 'Z') &&
+            u[0] != '_')
+                return false;
+
+        for (i = u+1; *i; i++) {
+                if (!(*i >= 'a' && *i <= 'z') &&
+                    !(*i >= 'A' && *i <= 'Z') &&
+                    !(*i >= '0' && *i <= '9') &&
+                    *i != '_' &&
+                    *i != '-')
+                        return false;
+        }
+
+        sz = sysconf(_SC_LOGIN_NAME_MAX);
+        assert_se(sz > 0);
+
+        if ((size_t) (i-u) > (size_t) sz)
+                return false;
+
+        if ((size_t) (i-u) > UT_NAMESIZE - 1)
+                return false;
+
+        return true;
+}
+
+static bool valid_gecos(const char *d) {
+
+        if (!d)
+                return false;
+
+        if (!utf8_is_valid(d))
+                return false;
+
+        if (string_has_cc(d, NULL))
+                return false;
+
+        /* Colons are used as field separators, and hence not OK */
+        if (strchr(d, ':'))
+                return false;
+
+        return true;
+}
+
+static bool valid_home(const char *p) {
+
+        if (isempty(p))
+                return false;
+
+        if (!utf8_is_valid(p))
+                return false;
+
+        if (string_has_cc(p, NULL))
+                return false;
+
+        if (!path_is_absolute(p))
+                return false;
+
+        if (!path_is_safe(p))
+                return false;
+
+        /* Colons are used as field separators, and hence not OK */
+        if (strchr(p, ':'))
+                return false;
+
+        return true;
+}
+
+static int parse_line(const char *fname, unsigned line, const char *buffer) {
+
+        static const Specifier specifier_table[] = {
+                { 'm', specifier_machine_id, NULL },
+                { 'b', specifier_boot_id, NULL },
+                { 'H', specifier_host_name, NULL },
+                { 'v', specifier_kernel_release, NULL },
+                {}
+        };
+
+        _cleanup_free_ char *action = NULL, *name = NULL, *id = NULL, *resolved_name = NULL, *resolved_id = NULL, *description = NULL, *home = NULL;
+        _cleanup_(item_freep) Item *i = NULL;
+        Item *existing;
+        Hashmap *h;
+        int r;
+        const char *p;
+
+        assert(fname);
+        assert(line >= 1);
+        assert(buffer);
+
+        /* Parse columns */
+        p = buffer;
+        r = unquote_many_words(&p, &action, &name, &id, &description, &home, NULL);
+        if (r < 0) {
+                log_error("[%s:%u] Syntax error.", fname, line);
+                return r;
+        }
+        if (r < 2) {
+                log_error("[%s:%u] Missing action and name columns.", fname, line);
+                return -EINVAL;
+        }
+        if (*p != 0) {
+                log_error("[%s:%u] Trailing garbage.", fname, line);
+                return -EINVAL;
+        }
+
+        /* Verify action */
+        if (strlen(action) != 1) {
+                log_error("[%s:%u] Unknown modifier '%s'", fname, line, action);
+                return -EINVAL;
+        }
+
+        if (!IN_SET(action[0], ADD_USER, ADD_GROUP, ADD_MEMBER, ADD_RANGE)) {
+                log_error("[%s:%u] Unknown command command type '%c'.", fname, line, action[0]);
+                return -EBADMSG;
+        }
+
+        /* Verify name */
+        if (isempty(name) || streq(name, "-")) {
+                free(name);
+                name = NULL;
+        }
+
+        if (name) {
+                r = specifier_printf(name, specifier_table, NULL, &resolved_name);
+                if (r < 0) {
+                        log_error("[%s:%u] Failed to replace specifiers: %s", fname, line, name);
+                        return r;
+                }
+
+                if (!valid_user_group_name(resolved_name)) {
+                        log_error("[%s:%u] '%s' is not a valid user or group name.", fname, line, resolved_name);
+                        return -EINVAL;
+                }
+        }
+
+        /* Verify id */
+        if (isempty(id) || streq(id, "-")) {
+                free(id);
+                id = NULL;
+        }
+
+        if (id) {
+                r = specifier_printf(id, specifier_table, NULL, &resolved_id);
+                if (r < 0) {
+                        log_error("[%s:%u] Failed to replace specifiers: %s", fname, line, name);
+                        return r;
+                }
+        }
+
+        /* Verify description */
+        if (isempty(description) || streq(description, "-")) {
+                free(description);
+                description = NULL;
+        }
+
+        if (description) {
+                if (!valid_gecos(description)) {
+                        log_error("[%s:%u] '%s' is not a valid GECOS field.", fname, line, description);
+                        return -EINVAL;
+                }
+        }
+
+        /* Verify home */
+        if (isempty(home) || streq(home, "-")) {
+                free(home);
+                home = NULL;
+        }
+
+        if (home) {
+                if (!valid_home(home)) {
+                        log_error("[%s:%u] '%s' is not a valid home directory field.", fname, line, home);
+                        return -EINVAL;
+                }
+        }
+
+        switch (action[0]) {
+
+        case ADD_RANGE:
+                if (resolved_name) {
+                        log_error("[%s:%u] Lines of type 'r' don't take a name field.", fname, line);
+                        return -EINVAL;
+                }
+
+                if (!resolved_id) {
+                        log_error("[%s:%u] Lines of type 'r' require a ID range in the third field.", fname, line);
+                        return -EINVAL;
+                }
+
+                if (description) {
+                        log_error("[%s:%u] Lines of type 'r' don't take a GECOS field.", fname, line);
+                        return -EINVAL;
+                }
+
+                if (home) {
+                        log_error("[%s:%u] Lines of type 'r' don't take a home directory field.", fname, line);
+                        return -EINVAL;
+                }
+
+                r = uid_range_add_str(&uid_range, &n_uid_range, resolved_id);
+                if (r < 0) {
+                        log_error("[%s:%u] Invalid UID range %s.", fname, line, resolved_id);
+                        return -EINVAL;
+                }
+
+                return 0;
+
+        case ADD_MEMBER: {
+                char **l;
+
+                /* Try to extend an existing member or group item */
+                if (!name) {
+                        log_error("[%s:%u] Lines of type 'm' require a user name in the second field.", fname, line);
+                        return -EINVAL;
+                }
+
+                if (!resolved_id) {
+                        log_error("[%s:%u] Lines of type 'm' require a group name in the third field.", fname, line);
+                        return -EINVAL;
+                }
+
+                if (!valid_user_group_name(resolved_id)) {
+                        log_error("[%s:%u] '%s' is not a valid user or group name.", fname, line, resolved_id);
+                        return -EINVAL;
+                }
+
+                if (description) {
+                        log_error("[%s:%u] Lines of type 'm' don't take a GECOS field.", fname, line);
+                        return -EINVAL;
+                }
+
+                if (home) {
+                        log_error("[%s:%u] Lines of type 'm' don't take a home directory field.", fname, line);
+                        return -EINVAL;
+                }
+
+                r = hashmap_ensure_allocated(&members, string_hash_func, string_compare_func);
+                if (r < 0)
+                        return log_oom();
+
+                l = hashmap_get(members, resolved_id);
+                if (l) {
+                        /* A list for this group name already exists, let's append to it */
+                        r = strv_push(&l, resolved_name);
+                        if (r < 0)
+                                return log_oom();
+
+                        resolved_name = NULL;
+
+                        assert_se(hashmap_update(members, resolved_id, l) >= 0);
+                } else {
+                        /* No list for this group name exists yet, create one */
+
+                        l = new0(char *, 2);
+                        if (!l)
+                                return -ENOMEM;
+
+                        l[0] = resolved_name;
+                        l[1] = NULL;
+
+                        r = hashmap_put(members, resolved_id, l);
+                        if (r < 0) {
+                                free(l);
+                                return log_oom();
+                        }
+
+                        resolved_id = resolved_name = NULL;
+                }
+
+                return 0;
+        }
+
+        case ADD_USER:
+                if (!name) {
+                        log_error("[%s:%u] Lines of type 'u' require a user name in the second field.", fname, line);
+                        return -EINVAL;
+                }
+
+                r = hashmap_ensure_allocated(&users, string_hash_func, string_compare_func);
+                if (r < 0)
+                        return log_oom();
+
+                i = new0(Item, 1);
+                if (!i)
+                        return log_oom();
+
+                if (resolved_id) {
+                        if (path_is_absolute(resolved_id)) {
+                                i->uid_path = resolved_id;
+                                resolved_id = NULL;
+
+                                path_kill_slashes(i->uid_path);
+                        } else {
+                                r = parse_uid(resolved_id, &i->uid);
+                                if (r < 0) {
+                                        log_error("Failed to parse UID: %s", id);
+                                        return -EBADMSG;
+                                }
+
+                                i->uid_set = true;
+                        }
+                }
+
+                i->description = description;
+                description = NULL;
+
+                i->home = home;
+                home = NULL;
+
+                h = users;
+                break;
+
+        case ADD_GROUP:
+                if (!name) {
+                        log_error("[%s:%u] Lines of type 'g' require a user name in the second field.", fname, line);
+                        return -EINVAL;
+                }
+
+                if (description) {
+                        log_error("[%s:%u] Lines of type 'g' don't take a GECOS field.", fname, line);
+                        return -EINVAL;
+                }
+
+                if (home) {
+                        log_error("[%s:%u] Lines of type 'g' don't take a home directory field.", fname, line);
+                        return -EINVAL;
+                }
+
+                r = hashmap_ensure_allocated(&groups, string_hash_func, string_compare_func);
+                if (r < 0)
+                        return log_oom();
+
+                i = new0(Item, 1);
+                if (!i)
+                        return log_oom();
+
+                if (resolved_id) {
+                        if (path_is_absolute(resolved_id)) {
+                                i->gid_path = resolved_id;
+                                resolved_id = NULL;
+
+                                path_kill_slashes(i->gid_path);
+                        } else {
+                                r = parse_gid(resolved_id, &i->gid);
+                                if (r < 0) {
+                                        log_error("Failed to parse GID: %s", id);
+                                        return -EBADMSG;
+                                }
+
+                                i->gid_set = true;
+                        }
+                }
+
+                h = groups;
+                break;
+
+        default:
+                return -EBADMSG;
+        }
+
+        i->type = action[0];
+        i->name = resolved_name;
+        resolved_name = NULL;
+
+        existing = hashmap_get(h, i->name);
+        if (existing) {
+
+                /* Two identical items are fine */
+                if (!item_equal(existing, i))
+                        log_warning("Two or more conflicting lines for %s configured, ignoring.", i->name);
+
+                return 0;
+        }
+
+        r = hashmap_put(h, i->name, i);
+        if (r < 0)
+                return log_oom();
+
+        i = NULL;
+        return 0;
+}
+
+static int read_config_file(const char *fn, bool ignore_enoent) {
+        _cleanup_fclose_ FILE *rf = NULL;
+        FILE *f = NULL;
+        char line[LINE_MAX];
+        unsigned v = 0;
+        int r = 0;
+
+        assert(fn);
+
+        if (streq(fn, "-"))
+                f = stdin;
+        else {
+                r = search_and_fopen_nulstr(fn, "re", arg_root, conf_file_dirs, &rf);
+                if (r < 0) {
+                        if (ignore_enoent && r == -ENOENT)
+                                return 0;
+
+                        log_error("Failed to open '%s', ignoring: %s", fn, strerror(-r));
+                        return r;
+                }
+
+                f = rf;
+        }
+
+        FOREACH_LINE(line, f, break) {
+                char *l;
+                int k;
+
+                v++;
+
+                l = strstrip(line);
+                if (*l == '#' || *l == 0)
+                        continue;
+
+                k = parse_line(fn, v, l);
+                if (k < 0 && r == 0)
+                        r = k;
+        }
+
+        if (ferror(f)) {
+                log_error("Failed to read from file %s: %m", fn);
+                if (r == 0)
+                        r = -EIO;
+        }
+
+        return r;
+}
+
+static void free_database(Hashmap *by_name, Hashmap *by_id) {
+        char *name;
+
+        for (;;) {
+                name = hashmap_first(by_id);
+                if (!name)
+                        break;
+
+                hashmap_remove(by_name, name);
+
+                hashmap_steal_first_key(by_id);
+                free(name);
+        }
+
+        while ((name = hashmap_steal_first_key(by_name)))
+                free(name);
+
+        hashmap_free(by_name);
+        hashmap_free(by_id);
+}
+
+static void help(void) {
+        printf("%s [OPTIONS...] [CONFIGURATION FILE...]\n\n"
+               "Creates system user accounts.\n\n"
+               "  -h --help                 Show this help\n"
+               "     --version              Show package version\n"
+               "     --root=PATH            Operate on an alternate filesystem root\n"
+               , program_invocation_short_name);
+}
+
+static int parse_argv(int argc, char *argv[]) {
+
+        enum {
+                ARG_VERSION = 0x100,
+                ARG_ROOT,
+        };
+
+        static const struct option options[] = {
+                { "help",    no_argument,       NULL, 'h'         },
+                { "version", no_argument,       NULL, ARG_VERSION },
+                { "root",    required_argument, NULL, ARG_ROOT    },
+                {}
+        };
+
+        int c;
+
+        assert(argc >= 0);
+        assert(argv);
+
+        while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
+
+                switch (c) {
+
+                case 'h':
+                        help();
+                        return 0;
+
+                case ARG_VERSION:
+                        puts(PACKAGE_STRING);
+                        puts(SYSTEMD_FEATURES);
+                        return 0;
+
+                case ARG_ROOT:
+                        free(arg_root);
+                        arg_root = path_make_absolute_cwd(optarg);
+                        if (!arg_root)
+                                return log_oom();
+
+                        path_kill_slashes(arg_root);
+                        break;
+
+                case '?':
+                        return -EINVAL;
+
+                default:
+                        assert_not_reached("Unhandled option");
+                }
+
+        return 1;
+}
+
+int main(int argc, char *argv[]) {
+
+        _cleanup_close_ int lock = -1;
+        Iterator iterator;
+        int r, k;
+        Item *i;
+        char *n;
+
+        r = parse_argv(argc, argv);
+        if (r <= 0)
+                goto finish;
+
+        log_set_target(LOG_TARGET_AUTO);
+        log_parse_environment();
+        log_open();
+
+        umask(0022);
+
+        r = label_init(NULL);
+        if (r < 0) {
+                log_error("SELinux setup failed: %s", strerror(-r));
+                goto finish;
+        }
+
+        if (optind < argc) {
+                int j;
+
+                for (j = optind; j < argc; j++) {
+                        k = read_config_file(argv[j], false);
+                        if (k < 0 && r == 0)
+                                r = k;
+                }
+        } else {
+                _cleanup_strv_free_ char **files = NULL;
+                char **f;
+
+                r = conf_files_list_nulstr(&files, ".conf", arg_root, conf_file_dirs);
+                if (r < 0) {
+                        log_error("Failed to enumerate sysusers.d files: %s", strerror(-r));
+                        goto finish;
+                }
+
+                STRV_FOREACH(f, files) {
+                        k = read_config_file(*f, true);
+                        if (k < 0 && r == 0)
+                                r = k;
+                }
+        }
+
+        if (!uid_range) {
+                /* Default to default range of 1..SYSTEMD_UID_MAX */
+                r = uid_range_add(&uid_range, &n_uid_range, 1, SYSTEM_UID_MAX);
+                if (r < 0) {
+                        log_oom();
+                        goto finish;
+                }
+        }
+
+        r = add_implicit();
+        if (r < 0)
+                goto finish;
+
+        lock = take_password_lock(arg_root);
+        if (lock < 0) {
+                log_error("Failed to take lock: %s", strerror(-lock));
+                goto finish;
+        }
+
+        r = load_user_database();
+        if (r < 0) {
+                log_error("Failed to load user database: %s", strerror(-r));
+                goto finish;
+        }
+
+        r = load_group_database();
+        if (r < 0) {
+                log_error("Failed to read group database: %s", strerror(-r));
+                goto finish;
+        }
+
+        HASHMAP_FOREACH(i, groups, iterator)
+                process_item(i);
+
+        HASHMAP_FOREACH(i, users, iterator)
+                process_item(i);
+
+        r = write_files();
+        if (r < 0)
+                log_error("Failed to write files: %s", strerror(-r));
+
+finish:
+        while ((i = hashmap_steal_first(groups)))
+                item_free(i);
+
+        while ((i = hashmap_steal_first(users)))
+                item_free(i);
+
+        while ((n = hashmap_first_key(members))) {
+                strv_free(hashmap_steal_first(members));
+                free(n);
+        }
+
+        hashmap_free(groups);
+        hashmap_free(users);
+        hashmap_free(members);
+        hashmap_free(todo_uids);
+        hashmap_free(todo_gids);
+
+        free_database(database_user, database_uid);
+        free_database(database_group, database_gid);
+
+        free(arg_root);
+
+        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/src/sysv-generator/Makefile b/src/sysv-generator/Makefile
new file mode 100644 (file)
index 0000000..530e5e9
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
diff --git a/src/sysv-generator/sysv-generator.c b/src/sysv-generator/sysv-generator.c
new file mode 100644 (file)
index 0000000..368d420
--- /dev/null
@@ -0,0 +1,941 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Thomas H.P. Andersen
+  Copyright 2010 Lennart Poettering
+  Copyright 2011 Michal Schmidt
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "util.h"
+#include "mkdir.h"
+#include "strv.h"
+#include "path-util.h"
+#include "path-lookup.h"
+#include "log.h"
+#include "strv.h"
+#include "unit.h"
+#include "unit-name.h"
+#include "special.h"
+#include "exit-status.h"
+#include "def.h"
+#include "env-util.h"
+#include "fileio.h"
+#include "hashmap.h"
+
+typedef enum RunlevelType {
+        RUNLEVEL_UP,
+        RUNLEVEL_DOWN
+} RunlevelType;
+
+static const struct {
+        const char *path;
+        const char *target;
+        const RunlevelType type;
+} rcnd_table[] = {
+        /* Standard SysV runlevels for start-up */
+        { "rc1.d",  SPECIAL_RESCUE_TARGET,    RUNLEVEL_UP },
+        { "rc2.d",  SPECIAL_RUNLEVEL2_TARGET, RUNLEVEL_UP },
+        { "rc3.d",  SPECIAL_RUNLEVEL3_TARGET, RUNLEVEL_UP },
+        { "rc4.d",  SPECIAL_RUNLEVEL4_TARGET, RUNLEVEL_UP },
+        { "rc5.d",  SPECIAL_RUNLEVEL5_TARGET, RUNLEVEL_UP },
+
+        /* Standard SysV runlevels for shutdown */
+        { "rc0.d",  SPECIAL_POWEROFF_TARGET,  RUNLEVEL_DOWN },
+        { "rc6.d",  SPECIAL_REBOOT_TARGET,    RUNLEVEL_DOWN }
+
+        /* Note that the order here matters, as we read the
+           directories in this order, and we want to make sure that
+           sysv_start_priority is known when we first load the
+           unit. And that value we only know from S links. Hence
+           UP must be read before DOWN */
+};
+
+typedef struct SysvStub {
+        char *name;
+        char *path;
+        char *description;
+        int sysv_start_priority;
+        char *pid_file;
+        char **before;
+        char **after;
+        char **wants;
+        char **wanted_by;
+        char **conflicts;
+        bool has_lsb;
+        bool reload;
+} SysvStub;
+
+const char *arg_dest = "/tmp";
+
+static int add_symlink(const char *service, const char *where) {
+        _cleanup_free_ char *from = NULL, *to = NULL;
+        int r;
+
+        assert(service);
+        assert(where);
+
+        from = strjoin(arg_dest, "/", service, NULL);
+        if (!from)
+                return log_oom();
+
+        to = strjoin(arg_dest, "/", where, ".wants/", service, NULL);
+        if (!to)
+                return log_oom();
+
+        mkdir_parents_label(to, 0755);
+
+        r = symlink(from, to);
+        if (r < 0) {
+                if (errno == EEXIST)
+                        return 0;
+                return -errno;
+        }
+
+        return 1;
+}
+
+static int generate_unit_file(SysvStub *s) {
+        char *unit;
+        char **p;
+        _cleanup_fclose_ FILE *f = NULL;
+        _cleanup_free_ char *before = NULL;
+        _cleanup_free_ char *after = NULL;
+        _cleanup_free_ char *wants = NULL;
+        _cleanup_free_ char *conflicts = NULL;
+        int r;
+
+        before = strv_join(s->before, " ");
+        if (!before)
+                return log_oom();
+
+        after = strv_join(s->after, " ");
+        if (!after)
+                return log_oom();
+
+        wants = strv_join(s->wants, " ");
+        if (!wants)
+                return log_oom();
+
+        conflicts = strv_join(s->conflicts, " ");
+        if (!conflicts)
+                return log_oom();
+
+        unit = strjoin(arg_dest, "/", s->name, NULL);
+        if (!unit)
+                return log_oom();
+
+        f = fopen(unit, "wxe");
+        if (!f) {
+                log_error("Failed to create unit file %s: %m", unit);
+                return -errno;
+        }
+
+        fprintf(f,
+                "# Automatically generated by systemd-sysv-generator\n\n"
+                "[Unit]\n"
+                "SourcePath=%s\n"
+                "Description=%s\n",
+                s->path, s->description);
+
+        if (!isempty(before))
+                fprintf(f, "Before=%s\n", before);
+        if (!isempty(after))
+                fprintf(f, "After=%s\n", after);
+        if (!isempty(wants))
+                fprintf(f, "Wants=%s\n", wants);
+        if (!isempty(conflicts))
+                fprintf(f, "Conflicts=%s\n", conflicts);
+
+        fprintf(f,
+                "\n[Service]\n"
+                "Type=forking\n"
+                "Restart=no\n"
+                "TimeoutSec=5min\n"
+                "IgnoreSIGPIPE=no\n"
+                "KillMode=process\n"
+                "GuessMainPID=no\n"
+                "RemainAfterExit=%s\n",
+                yes_no(!s->pid_file));
+
+        if (s->sysv_start_priority > 0)
+                fprintf(f, "SysVStartPriority=%d\n", s->sysv_start_priority);
+
+        if (s->pid_file)
+                fprintf(f, "PIDFile=%s\n", s->pid_file);
+
+        fprintf(f,
+                "ExecStart=%s start\n"
+                "ExecStop=%s stop\n",
+                s->path, s->path);
+
+        if (s->reload)
+                fprintf(f, "ExecReload=%s reload\n", s->path);
+
+        STRV_FOREACH(p, s->wanted_by) {
+                r = add_symlink(s->name, *p);
+                if (r < 0)
+                        log_error_unit(s->name, "Failed to create 'Wants' symlink to %s: %s", *p, strerror(-r));
+        }
+
+        return 0;
+}
+
+static bool usage_contains_reload(const char *line) {
+        return (strcasestr(line, "{reload|") ||
+                strcasestr(line, "{reload}") ||
+                strcasestr(line, "{reload\"") ||
+                strcasestr(line, "|reload|") ||
+                strcasestr(line, "|reload}") ||
+                strcasestr(line, "|reload\""));
+}
+
+static char *sysv_translate_name(const char *name) {
+        char *r;
+
+        r = new(char, strlen(name) + strlen(".service") + 1);
+        if (!r)
+                return NULL;
+
+        if (endswith(name, ".sh"))
+                /* Drop .sh suffix */
+                strcpy(stpcpy(r, name) - 3, ".service");
+        else
+                /* Normal init script name */
+                strcpy(stpcpy(r, name), ".service");
+
+        return r;
+}
+
+static int sysv_translate_facility(const char *name, const char *filename, char **_r) {
+
+        /* We silently ignore the $ prefix here. According to the LSB
+         * spec it simply indicates whether something is a
+         * standardized name or a distribution-specific one. Since we
+         * just follow what already exists and do not introduce new
+         * uses or names we don't care who introduced a new name. */
+
+        static const char * const table[] = {
+                /* LSB defined facilities */
+                "local_fs",             NULL,
+                "network",              SPECIAL_NETWORK_ONLINE_TARGET,
+                "named",                SPECIAL_NSS_LOOKUP_TARGET,
+                "portmap",              SPECIAL_RPCBIND_TARGET,
+                "remote_fs",            SPECIAL_REMOTE_FS_TARGET,
+                "syslog",               NULL,
+                "time",                 SPECIAL_TIME_SYNC_TARGET,
+        };
+
+        unsigned i;
+        char *r;
+        const char *n;
+
+        assert(name);
+        assert(_r);
+
+        n = *name == '$' ? name + 1 : name;
+
+        for (i = 0; i < ELEMENTSOF(table); i += 2) {
+
+                if (!streq(table[i], n))
+                        continue;
+
+                if (!table[i+1])
+                        return 0;
+
+                r = strdup(table[i+1]);
+                if (!r)
+                        return log_oom();
+
+                goto finish;
+        }
+
+        /* If we don't know this name, fallback heuristics to figure
+         * out whether something is a target or a service alias. */
+
+        if (*name == '$') {
+                if (!unit_prefix_is_valid(n))
+                        return -EINVAL;
+
+                /* Facilities starting with $ are most likely targets */
+                r = unit_name_build(n, NULL, ".target");
+        } else if (filename && streq(name, filename))
+                /* Names equaling the file name of the services are redundant */
+                return 0;
+        else
+                /* Everything else we assume to be normal service names */
+                r = sysv_translate_name(n);
+
+        if (!r)
+                return -ENOMEM;
+
+finish:
+        *_r = r;
+
+        return 1;
+}
+
+static int load_sysv(SysvStub *s) {
+        _cleanup_fclose_ FILE *f;
+        unsigned line = 0;
+        int r;
+        enum {
+                NORMAL,
+                DESCRIPTION,
+                LSB,
+                LSB_DESCRIPTION,
+                USAGE_CONTINUATION
+        } state = NORMAL;
+        _cleanup_free_ char *short_description = NULL, *long_description = NULL, *chkconfig_description = NULL;
+        char *description;
+        bool supports_reload = false;
+
+        assert(s);
+
+        f = fopen(s->path, "re");
+        if (!f)
+                return errno == ENOENT ? 0 : -errno;
+
+        while (!feof(f)) {
+                char l[LINE_MAX], *t;
+
+                if (!fgets(l, sizeof(l), f)) {
+                        if (feof(f))
+                                break;
+
+                        log_error_unit(s->name,
+                                       "Failed to read configuration file '%s': %m",
+                                       s->path);
+                        return -errno;
+                }
+
+                line++;
+
+                t = strstrip(l);
+                if (*t != '#') {
+                        /* Try to figure out whether this init script supports
+                         * the reload operation. This heuristic looks for
+                         * "Usage" lines which include the reload option. */
+                        if ( state == USAGE_CONTINUATION ||
+                            (state == NORMAL && strcasestr(t, "usage"))) {
+                                if (usage_contains_reload(t)) {
+                                        supports_reload = true;
+                                        state = NORMAL;
+                                } else if (t[strlen(t)-1] == '\\')
+                                        state = USAGE_CONTINUATION;
+                                else
+                                        state = NORMAL;
+                        }
+
+                        continue;
+                }
+
+                if (state == NORMAL && streq(t, "### BEGIN INIT INFO")) {
+                        state = LSB;
+                        s->has_lsb = true;
+                        continue;
+                }
+
+                if ((state == LSB_DESCRIPTION || state == LSB) && streq(t, "### END INIT INFO")) {
+                        state = NORMAL;
+                        continue;
+                }
+
+                t++;
+                t += strspn(t, WHITESPACE);
+
+                if (state == NORMAL) {
+
+                        /* Try to parse Red Hat style description */
+
+                        if (startswith_no_case(t, "description:")) {
+
+                                size_t k = strlen(t);
+                                char *d;
+                                const char *j;
+
+                                if (t[k-1] == '\\') {
+                                        state = DESCRIPTION;
+                                        t[k-1] = 0;
+                                }
+
+                                j = strstrip(t+12);
+                                if (j && *j) {
+                                        d = strdup(j);
+                                        if (!d)
+                                                return -ENOMEM;
+                                } else
+                                        d = NULL;
+
+                                free(chkconfig_description);
+                                chkconfig_description = d;
+
+                        } else if (startswith_no_case(t, "pidfile:")) {
+
+                                char *fn;
+
+                                state = NORMAL;
+
+                                fn = strstrip(t+8);
+                                if (!path_is_absolute(fn)) {
+                                        log_error_unit(s->name,
+                                                       "[%s:%u] PID file not absolute. Ignoring.",
+                                                       s->path, line);
+                                        continue;
+                                }
+
+                                fn = strdup(fn);
+                                if (!fn)
+                                        return -ENOMEM;
+
+                                free(s->pid_file);
+                                s->pid_file = fn;
+                        }
+
+                } else if (state == DESCRIPTION) {
+
+                        /* Try to parse Red Hat style description
+                         * continuation */
+
+                        size_t k = strlen(t);
+                        char *j;
+
+                        if (t[k-1] == '\\')
+                                t[k-1] = 0;
+                        else
+                                state = NORMAL;
+
+                        j = strstrip(t);
+                        if (j && *j) {
+                                char *d = NULL;
+
+                                if (chkconfig_description)
+                                        d = strjoin(chkconfig_description, " ", j, NULL);
+                                else
+                                        d = strdup(j);
+
+                                if (!d)
+                                        return -ENOMEM;
+
+                                free(chkconfig_description);
+                                chkconfig_description = d;
+                        }
+
+                } else if (state == LSB || state == LSB_DESCRIPTION) {
+
+                        if (startswith_no_case(t, "Provides:")) {
+                                const char *word, *state_;
+                                size_t z;
+
+                                state = LSB;
+
+                                FOREACH_WORD_QUOTED(word, z, t+9, state_) {
+                                        _cleanup_free_ char *n = NULL, *m = NULL;
+
+                                        n = strndup(word, z);
+                                        if (!n)
+                                                return -ENOMEM;
+
+                                        r = sysv_translate_facility(n, basename(s->path), &m);
+
+                                        if (r < 0)
+                                                return r;
+
+                                        if (r == 0)
+                                                continue;
+
+                                        if (unit_name_to_type(m) != UNIT_SERVICE) {
+                                                /* NB: SysV targets
+                                                 * which are provided
+                                                 * by a service are
+                                                 * pulled in by the
+                                                 * services, as an
+                                                 * indication that the
+                                                 * generic service is
+                                                 * now available. This
+                                                 * is strictly
+                                                 * one-way. The
+                                                 * targets do NOT pull
+                                                 * in the SysV
+                                                 * services! */
+                                                r = strv_extend(&s->before, m);
+                                                if (r < 0)
+                                                        return log_oom();
+                                                r = strv_extend(&s->wants, m);
+                                                if (r < 0)
+                                                        return log_oom();
+                                                if (streq(m, SPECIAL_NETWORK_ONLINE_TARGET)) {
+                                                        r = strv_extend(&s->before, SPECIAL_NETWORK_TARGET);
+                                                        if (r < 0)
+                                                                return log_oom();
+                                                }
+                                        }
+
+                                        if (r < 0)
+                                                log_error_unit(s->name,
+                                                               "[%s:%u] Failed to add LSB Provides name %s, ignoring: %s",
+                                                               s->path, line, m, strerror(-r));
+                                }
+                                if (!isempty(state_))
+                                        log_error_unit(s->name,
+                                                       "[%s:%u] Trailing garbage in Provides, ignoring.",
+                                                       s->path, line);
+
+                        } else if (startswith_no_case(t, "Required-Start:") ||
+                                   startswith_no_case(t, "Should-Start:") ||
+                                   startswith_no_case(t, "X-Start-Before:") ||
+                                   startswith_no_case(t, "X-Start-After:")) {
+                                const char *word, *state_;
+                                size_t z;
+
+                                state = LSB;
+
+                                FOREACH_WORD_QUOTED(word, z, strchr(t, ':')+1, state_) {
+                                        _cleanup_free_ char *n = NULL, *m = NULL;
+                                        bool is_before;
+
+                                        n = strndup(word, z);
+                                        if (!n)
+                                                return -ENOMEM;
+
+                                        r = sysv_translate_facility(n, basename(s->path), &m);
+                                        if (r < 0) {
+                                                log_error_unit(s->name,
+                                                               "[%s:%u] Failed to translate LSB dependency %s, ignoring: %s",
+                                                               s->path, line, n, strerror(-r));
+                                                continue;
+                                        }
+
+                                        if (r == 0)
+                                                continue;
+
+                                        is_before = startswith_no_case(t, "X-Start-Before:");
+
+                                        if (streq(m, SPECIAL_NETWORK_ONLINE_TARGET) && !is_before) {
+                                                /* the network-online target is special, as it needs to be actively pulled in */
+                                                r = strv_extend(&s->after, m);
+                                                if (r < 0)
+                                                        return log_oom();
+                                                r = strv_extend(&s->wants, m);
+                                                if (r < 0)
+                                                        return log_oom();
+                                        }
+                                        else {
+                                                if (is_before) {
+                                                        r = strv_extend(&s->before, m);
+                                                        if (r < 0)
+                                                                return log_oom();
+                                                }
+                                                else {
+                                                        r = strv_extend(&s->after, m);
+                                                        if (r < 0)
+                                                                return log_oom();
+                                                }
+                                        }
+
+                                        if (r < 0)
+                                                log_error_unit(s->name,
+                                                               "[%s:%u] Failed to add dependency on %s, ignoring: %s",
+                                                               s->path, line, m, strerror(-r));
+                                }
+                                if (!isempty(state_))
+                                        log_error_unit(s->name,
+                                                       "[%s:%u] Trailing garbage in %*s, ignoring.",
+                                                       s->path, line,
+                                                       (int)(strchr(t, ':') - t), t);
+
+                        } else if (startswith_no_case(t, "Description:")) {
+                                char *d, *j;
+
+                                state = LSB_DESCRIPTION;
+
+                                j = strstrip(t+12);
+                                if (j && *j) {
+                                        d = strdup(j);
+                                        if (!d)
+                                                return -ENOMEM;
+                                } else
+                                        d = NULL;
+
+                                free(long_description);
+                                long_description = d;
+
+                        } else if (startswith_no_case(t, "Short-Description:")) {
+                                char *d, *j;
+
+                                state = LSB;
+
+                                j = strstrip(t+18);
+                                if (j && *j) {
+                                        d = strdup(j);
+                                        if (!d)
+                                                return -ENOMEM;
+                                } else
+                                        d = NULL;
+
+                                free(short_description);
+                                short_description = d;
+
+                        } else if (state == LSB_DESCRIPTION) {
+
+                                if (startswith(l, "#\t") || startswith(l, "#  ")) {
+                                        char *j;
+
+                                        j = strstrip(t);
+                                        if (j && *j) {
+                                                char *d = NULL;
+
+                                                if (long_description)
+                                                        d = strjoin(long_description, " ", t, NULL);
+                                                else
+                                                        d = strdup(j);
+
+                                                if (!d)
+                                                        return -ENOMEM;
+
+                                                free(long_description);
+                                                long_description = d;
+                                        }
+
+                                } else
+                                        state = LSB;
+                        }
+                }
+        }
+
+        s->reload = supports_reload;
+
+        /* We use the long description only if
+         * no short description is set. */
+
+        if (short_description)
+                description = short_description;
+        else if (chkconfig_description)
+                description = chkconfig_description;
+        else if (long_description)
+                description = long_description;
+        else
+                description = NULL;
+
+        if (description) {
+                char *d;
+
+                d = strappend(s->has_lsb ? "LSB: " : "SYSV: ", description);
+                if (!d)
+                        return -ENOMEM;
+
+                s->description = d;
+        }
+
+        return 0;
+}
+
+static int fix_order(SysvStub *s, Hashmap *all_services) {
+        SysvStub *other;
+        Iterator j;
+        int r;
+
+        assert(s);
+
+        if (s->sysv_start_priority < 0)
+                return 0;
+
+        HASHMAP_FOREACH(other, all_services, j) {
+                if (s == other)
+                        continue;
+
+                if (other->sysv_start_priority < 0)
+                        continue;
+
+                /* If both units have modern headers we don't care
+                 * about the priorities */
+                if (s->has_lsb && other->has_lsb)
+                        continue;
+
+                if (other->sysv_start_priority < s->sysv_start_priority) {
+                        r = strv_extend(&s->after, other->name);
+                        if (r < 0)
+                                return log_oom();
+                }
+                else if (other->sysv_start_priority > s->sysv_start_priority) {
+                        r = strv_extend(&s->before, other->name);
+                        if (r < 0)
+                                return log_oom();
+                }
+                else
+                        continue;
+
+                /* FIXME: Maybe we should compare the name here lexicographically? */
+        }
+
+        return 0;
+}
+
+static int enumerate_sysv(LookupPaths lp, Hashmap *all_services) {
+        char **path;
+
+        STRV_FOREACH(path, lp.sysvinit_path) {
+                _cleanup_closedir_ DIR *d = NULL;
+                struct dirent *de;
+
+                d = opendir(*path);
+                if (!d) {
+                        if (errno != ENOENT)
+                                log_warning("opendir(%s) failed: %m", *path);
+                        continue;
+                }
+
+                while ((de = readdir(d))) {
+                        SysvStub *service;
+                        struct stat st;
+                        _cleanup_free_ char *fpath = NULL, *name = NULL;
+                        int r;
+
+                        if (ignore_file(de->d_name))
+                                continue;
+
+                        fpath = strjoin(*path, "/", de->d_name, NULL);
+                        if (!fpath)
+                                return log_oom();
+
+                        if (stat(fpath, &st) < 0)
+                                continue;
+
+                        if (!(st.st_mode & S_IXUSR))
+                                continue;
+
+                        name = sysv_translate_name(de->d_name);
+                        if (!name)
+                                return log_oom();
+
+                        if (hashmap_contains(all_services, name))
+                                continue;
+
+                        service = new0(SysvStub, 1);
+                        if (!service)
+                                return log_oom();
+
+                        service->sysv_start_priority = -1;
+                        service->name = name;
+                        service->path = fpath;
+
+                        r = hashmap_put(all_services, service->name, service);
+                        if (r < 0)
+                                return log_oom();
+
+                        name = fpath = NULL;
+                }
+        }
+
+        return 0;
+}
+
+static int set_dependencies_from_rcnd(LookupPaths lp, Hashmap *all_services) {
+        char **p;
+        unsigned i;
+        _cleanup_closedir_ DIR *d = NULL;
+        _cleanup_free_ char *path = NULL, *fpath = NULL, *name = NULL;
+        SysvStub *service;
+        Iterator j;
+        Set *runlevel_services[ELEMENTSOF(rcnd_table)] = {};
+        _cleanup_set_free_ Set *shutdown_services = NULL;
+        int r = 0;
+
+        STRV_FOREACH(p, lp.sysvrcnd_path)
+                for (i = 0; i < ELEMENTSOF(rcnd_table); i ++) {
+                        struct dirent *de;
+
+                        free(path);
+                        path = strjoin(*p, "/", rcnd_table[i].path, NULL);
+                        if (!path)
+                                return -ENOMEM;
+
+                        if (d)
+                                closedir(d);
+
+                        d = opendir(path);
+                        if (!d) {
+                                if (errno != ENOENT)
+                                        log_warning("opendir(%s) failed: %m", path);
+
+                                continue;
+                        }
+
+                        while ((de = readdir(d))) {
+                                int a, b;
+
+                                if (ignore_file(de->d_name))
+                                        continue;
+
+                                if (de->d_name[0] != 'S' && de->d_name[0] != 'K')
+                                        continue;
+
+                                if (strlen(de->d_name) < 4)
+                                        continue;
+
+                                a = undecchar(de->d_name[1]);
+                                b = undecchar(de->d_name[2]);
+
+                                if (a < 0 || b < 0)
+                                        continue;
+
+                                free(fpath);
+                                fpath = strjoin(*p, "/", de->d_name, NULL);
+                                if (!fpath) {
+                                        r = -ENOMEM;
+                                        goto finish;
+                                }
+
+                                name = sysv_translate_name(de->d_name + 3);
+                                if (!name) {
+                                        r = log_oom();
+                                        goto finish;
+                                }
+
+                                if (hashmap_contains(all_services, name))
+                                        service = hashmap_get(all_services, name);
+                                else {
+                                        log_warning("Could not find init script for %s", name);
+                                        continue;
+                                }
+
+                                if (de->d_name[0] == 'S')  {
+
+                                        if (rcnd_table[i].type == RUNLEVEL_UP) {
+                                                service->sysv_start_priority =
+                                                        MAX(a*10 + b, service->sysv_start_priority);
+                                        }
+
+                                        r = set_ensure_allocated(&runlevel_services[i],
+                                                                 trivial_hash_func, trivial_compare_func);
+                                        if (r < 0)
+                                                goto finish;
+
+                                        r = set_put(runlevel_services[i], service);
+                                        if (r < 0)
+                                                goto finish;
+
+                                } else if (de->d_name[0] == 'K' &&
+                                           (rcnd_table[i].type == RUNLEVEL_DOWN)) {
+
+                                        r = set_ensure_allocated(&shutdown_services,
+                                                                 trivial_hash_func, trivial_compare_func);
+                                        if (r < 0)
+                                                goto finish;
+
+                                        r = set_put(shutdown_services, service);
+                                        if (r < 0)
+                                                goto finish;
+                                }
+                        }
+                }
+
+
+        for (i = 0; i < ELEMENTSOF(rcnd_table); i ++)
+                SET_FOREACH(service, runlevel_services[i], j) {
+                        r = strv_extend(&service->before, rcnd_table[i].target);
+                        if (r < 0)
+                                return log_oom();
+                        r = strv_extend(&service->wanted_by, rcnd_table[i].target);
+                        if (r < 0)
+                                return log_oom();
+                }
+
+        SET_FOREACH(service, shutdown_services, j) {
+                r = strv_extend(&service->before, SPECIAL_SHUTDOWN_TARGET);
+                if (r < 0)
+                        return log_oom();
+                r = strv_extend(&service->conflicts, SPECIAL_SHUTDOWN_TARGET);
+                if (r < 0)
+                        return log_oom();
+        }
+
+        r = 0;
+
+finish:
+
+        for (i = 0; i < ELEMENTSOF(rcnd_table); i++)
+                set_free(runlevel_services[i]);
+
+        return r;
+}
+
+int main(int argc, char *argv[]) {
+        int r, q;
+        LookupPaths lp;
+        Hashmap *all_services;
+        SysvStub *service;
+        Iterator j;
+
+        if (argc > 1 && argc != 4) {
+                log_error("This program takes three or no arguments.");
+                return EXIT_FAILURE;
+        }
+
+        if (argc > 1)
+                arg_dest = argv[3];
+
+        log_set_target(LOG_TARGET_SAFE);
+        log_parse_environment();
+        log_open();
+
+        umask(0022);
+
+        r = lookup_paths_init(&lp, SYSTEMD_SYSTEM, true, NULL, NULL, NULL, NULL);
+        if (r < 0) {
+                log_error("Failed to find lookup paths.");
+                return EXIT_FAILURE;
+        }
+
+        all_services = hashmap_new(string_hash_func, string_compare_func);
+        if (!all_services) {
+                log_oom();
+                return EXIT_FAILURE;
+        }
+
+        r = enumerate_sysv(lp, all_services);
+        if (r < 0) {
+                log_error("Failed to generate units for all init scripts.");
+                return EXIT_FAILURE;
+        }
+
+        r = set_dependencies_from_rcnd(lp, all_services);
+        if (r < 0) {
+                log_error("Failed to read runlevels from rcnd links.");
+                return EXIT_FAILURE;
+        }
+
+        HASHMAP_FOREACH(service, all_services, j) {
+                q = load_sysv(service);
+                if (q < 0)
+                        continue;
+
+                q = fix_order(service, all_services);
+                if (q < 0)
+                        continue;
+
+                q = generate_unit_file(service);
+                if (q < 0)
+                        continue;
+        }
+
+        return EXIT_SUCCESS;
+}
index 7e171c7..24217ad 100644 (file)
@@ -48,5 +48,8 @@ int main(int argc, char *argv[]) {
         assert_se(a >= 0);
 
         log_info("native architecture=%s", architecture_to_string(a));
+
+        log_info("primary library architecture=" LIB_ARCH_TUPLE);
+
         return 0;
 }
diff --git a/src/test/test-async.c b/src/test/test-async.c
new file mode 100644 (file)
index 0000000..401e685
--- /dev/null
@@ -0,0 +1,52 @@
+/***
+  This file is part of systemd
+
+  Copyright 2014 Ronny Chevalier
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <unistd.h>
+
+#include "async.h"
+#include "util.h"
+#include "macro.h"
+
+static bool test_async = false;
+
+static void *async_func(void *arg) {
+        test_async = true;
+
+        return NULL;
+}
+
+int main(int argc, char *argv[]) {
+        int fd;
+        char name[] = "/tmp/test-asynchronous_close.XXXXXX";
+
+        fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+        assert_se(fd >= 0);
+        asynchronous_close(fd);
+        assert_se(asynchronous_job(async_func, NULL) >= 0);
+        assert_se(asynchronous_sync() >= 0);
+
+        sleep(1);
+
+        assert_se(fcntl(fd, F_GETFD) == -1);
+        assert_se(test_async);
+
+        unlink(name);
+
+        return 0;
+}
diff --git a/src/test/test-barrier.c b/src/test/test-barrier.c
new file mode 100644 (file)
index 0000000..36f2780
--- /dev/null
@@ -0,0 +1,461 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 David Herrmann <dh.herrmann@gmail.com>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+/*
+ * IPC barrier tests
+ * These tests verify the correct behavior of the IPC Barrier implementation.
+ * Note that the tests use alarm-timers to verify dead-locks and timeouts. These
+ * might not work on slow machines where 20ms are too short to perform specific
+ * operations (though, very unlikely). In case that turns out true, we have to
+ * increase it at the slightly cost of lengthen test-duration on other machines.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include "barrier.h"
+#include "def.h"
+#include "util.h"
+
+/* 20ms to test deadlocks; All timings use multiples of this constant as
+ * alarm/sleep timers. If this timeout is too small for slow machines to perform
+ * the requested operations, we have to increase it. On an i7 this works fine
+ * with 1ms base-time, so 20ms should be just fine for everyone. */
+#define BASE_TIME (20 * USEC_PER_MSEC)
+
+static void set_alarm(usec_t usecs) {
+        struct itimerval v = { };
+
+        timeval_store(&v.it_value, usecs);
+        assert_se(setitimer(ITIMER_REAL, &v, NULL) >= 0);
+}
+
+static void sleep_for(usec_t usecs) {
+        /* stupid usleep() might fail if >1000000 */
+        assert_se(usecs < USEC_PER_SEC);
+        usleep(usecs);
+}
+
+#define TEST_BARRIER(_FUNCTION, _CHILD_CODE, _WAIT_CHILD, _PARENT_CODE, _WAIT_PARENT)  \
+        static void _FUNCTION(void) {                                   \
+                Barrier b = BARRIER_NULL;                               \
+                pid_t pid1, pid2;                                       \
+                                                                        \
+                assert_se(barrier_create(&b) >= 0);                     \
+                                                                        \
+                pid1 = fork();                                          \
+                assert_se(pid1 >= 0);                                   \
+                if (pid1 == 0) {                                        \
+                        barrier_set_role(&b, BARRIER_CHILD);            \
+                        { _CHILD_CODE; }                                \
+                        exit(42);                                       \
+                }                                                       \
+                                                                        \
+                pid2 = fork();                                          \
+                assert_se(pid2 >= 0);                                   \
+                if (pid2 == 0) {                                        \
+                        barrier_set_role(&b, BARRIER_PARENT);           \
+                        { _PARENT_CODE; }                               \
+                        exit(42);                                       \
+                }                                                       \
+                                                                        \
+                barrier_destroy(&b);                                    \
+                set_alarm(999999);                                      \
+                { _WAIT_CHILD; }                                        \
+                { _WAIT_PARENT; }                                       \
+                set_alarm(0);                                           \
+        }
+
+#define TEST_BARRIER_WAIT_SUCCESS(_pid) \
+                ({                                                      \
+                        int pidr, status;                               \
+                        pidr = waitpid(_pid, &status, 0);               \
+                        assert_se(pidr == _pid);                        \
+                        assert_se(WIFEXITED(status));                   \
+                        assert_se(WEXITSTATUS(status) == 42);           \
+                })
+
+#define TEST_BARRIER_WAIT_ALARM(_pid) \
+                ({                                                      \
+                        int pidr, status;                               \
+                        pidr = waitpid(_pid, &status, 0);               \
+                        assert_se(pidr == _pid);                        \
+                        assert_se(WIFSIGNALED(status));                 \
+                        assert_se(WTERMSIG(status) == SIGALRM);         \
+                })
+
+/*
+ * Test basic sync points
+ * This places a barrier in both processes and waits synchronously for them.
+ * The timeout makes sure the sync works as expected. The sleep_for() on one side
+ * makes sure the exit of the parent does not overwrite previous barriers. Due
+ * to the sleep_for(), we know that the parent already exited, thus there's a
+ * pending HUP on the pipe. However, the barrier_sync() prefers reads on the
+ * eventfd, thus we can safely wait on the barrier.
+ */
+TEST_BARRIER(test_barrier_sync,
+        ({
+                set_alarm(BASE_TIME * 10);
+                assert_se(barrier_place(&b));
+                sleep_for(BASE_TIME * 2);
+                assert_se(barrier_sync(&b));
+        }),
+        TEST_BARRIER_WAIT_SUCCESS(pid1),
+        ({
+                set_alarm(BASE_TIME * 10);
+                assert_se(barrier_place(&b));
+                assert_se(barrier_sync(&b));
+        }),
+        TEST_BARRIER_WAIT_SUCCESS(pid2));
+
+/*
+ * Test wait_next()
+ * This places a barrier in the parent and syncs on it. The child sleeps while
+ * the parent places the barrier and then waits for a barrier. The wait will
+ * succeed as the child hasn't read the parent's barrier, yet. The following
+ * barrier and sync synchronize the exit.
+ */
+TEST_BARRIER(test_barrier_wait_next,
+        ({
+                sleep_for(BASE_TIME);
+                set_alarm(BASE_TIME * 10);
+                assert_se(barrier_wait_next(&b));
+                assert_se(barrier_place(&b));
+                assert_se(barrier_sync(&b));
+        }),
+        TEST_BARRIER_WAIT_SUCCESS(pid1),
+        ({
+                set_alarm(BASE_TIME * 4);
+                assert_se(barrier_place(&b));
+                assert_se(barrier_sync(&b));
+        }),
+        TEST_BARRIER_WAIT_SUCCESS(pid2));
+
+/*
+ * Test wait_next() multiple times
+ * This places two barriers in the parent and waits for the child to exit. The
+ * child sleeps 20ms so both barriers _should_ be in place. It then waits for
+ * the parent to place the next barrier twice. The first call will fetch both
+ * barriers and return. However, the second call will stall as the parent does
+ * not place a 3rd barrier (the sleep caught two barriers). wait_next() is does
+ * not look at barrier-links so this stall is expected. Thus this test times
+ * out.
+ */
+TEST_BARRIER(test_barrier_wait_next_twice,
+        ({
+                sleep_for(BASE_TIME);
+                set_alarm(BASE_TIME);
+                assert_se(barrier_wait_next(&b));
+                assert_se(barrier_wait_next(&b));
+                assert_se(0);
+        }),
+        TEST_BARRIER_WAIT_ALARM(pid1),
+        ({
+                set_alarm(BASE_TIME * 10);
+                assert_se(barrier_place(&b));
+                assert_se(barrier_place(&b));
+                sleep_for(BASE_TIME * 4);
+        }),
+        TEST_BARRIER_WAIT_SUCCESS(pid2));
+
+/*
+ * Test wait_next() with local barriers
+ * This is the same as test_barrier_wait_next_twice, but places local barriers
+ * between both waits. This does not have any effect on the wait so it times out
+ * like the other test.
+ */
+TEST_BARRIER(test_barrier_wait_next_twice_local,
+        ({
+                sleep_for(BASE_TIME);
+                set_alarm(BASE_TIME);
+                assert_se(barrier_wait_next(&b));
+                assert_se(barrier_place(&b));
+                assert_se(barrier_place(&b));
+                assert_se(barrier_wait_next(&b));
+                assert_se(0);
+        }),
+        TEST_BARRIER_WAIT_ALARM(pid1),
+        ({
+                set_alarm(BASE_TIME * 10);
+                assert_se(barrier_place(&b));
+                assert_se(barrier_place(&b));
+                sleep_for(BASE_TIME * 4);
+        }),
+        TEST_BARRIER_WAIT_SUCCESS(pid2));
+
+/*
+ * Test wait_next() with sync_next()
+ * This is again the same as test_barrier_wait_next_twice but uses a
+ * synced wait as the second wait. This works just fine because the local state
+ * has no barriers placed, therefore, the remote is always in sync.
+ */
+TEST_BARRIER(test_barrier_wait_next_twice_sync,
+        ({
+                sleep_for(BASE_TIME);
+                set_alarm(BASE_TIME);
+                assert_se(barrier_wait_next(&b));
+                assert_se(barrier_sync_next(&b));
+        }),
+        TEST_BARRIER_WAIT_SUCCESS(pid1),
+        ({
+                set_alarm(BASE_TIME * 10);
+                assert_se(barrier_place(&b));
+                assert_se(barrier_place(&b));
+        }),
+        TEST_BARRIER_WAIT_SUCCESS(pid2));
+
+/*
+ * Test wait_next() with sync_next() and local barriers
+ * This is again the same as test_barrier_wait_next_twice_local but uses a
+ * synced wait as the second wait. This works just fine because the local state
+ * is in sync with the remote.
+ */
+TEST_BARRIER(test_barrier_wait_next_twice_local_sync,
+        ({
+                sleep_for(BASE_TIME);
+                set_alarm(BASE_TIME);
+                assert_se(barrier_wait_next(&b));
+                assert_se(barrier_place(&b));
+                assert_se(barrier_place(&b));
+                assert_se(barrier_sync_next(&b));
+        }),
+        TEST_BARRIER_WAIT_SUCCESS(pid1),
+        ({
+                set_alarm(BASE_TIME * 10);
+                assert_se(barrier_place(&b));
+                assert_se(barrier_place(&b));
+        }),
+        TEST_BARRIER_WAIT_SUCCESS(pid2));
+
+/*
+ * Test sync_next() and sync()
+ * This tests sync_*() synchronizations and makes sure they work fine if the
+ * local state is behind the remote state.
+ */
+TEST_BARRIER(test_barrier_sync_next,
+        ({
+                set_alarm(BASE_TIME * 10);
+                assert_se(barrier_sync_next(&b));
+                assert_se(barrier_sync(&b));
+                assert_se(barrier_place(&b));
+                assert_se(barrier_place(&b));
+                assert_se(barrier_sync_next(&b));
+                assert_se(barrier_sync_next(&b));
+                assert_se(barrier_sync(&b));
+        }),
+        TEST_BARRIER_WAIT_SUCCESS(pid1),
+        ({
+                set_alarm(BASE_TIME * 10);
+                sleep_for(BASE_TIME);
+                assert_se(barrier_place(&b));
+                assert_se(barrier_place(&b));
+                assert_se(barrier_sync(&b));
+        }),
+        TEST_BARRIER_WAIT_SUCCESS(pid2));
+
+/*
+ * Test sync_next() and sync() with local barriers
+ * This tests timeouts if sync_*() is used if local barriers are placed but the
+ * remote didn't place any.
+ */
+TEST_BARRIER(test_barrier_sync_next_local,
+        ({
+                set_alarm(BASE_TIME);
+                assert_se(barrier_place(&b));
+                assert_se(barrier_sync_next(&b));
+                assert_se(0);
+        }),
+        TEST_BARRIER_WAIT_ALARM(pid1),
+        ({
+                sleep_for(BASE_TIME * 2);
+        }),
+        TEST_BARRIER_WAIT_SUCCESS(pid2));
+
+/*
+ * Test sync_next() and sync() with local barriers and abortion
+ * This is the same as test_barrier_sync_next_local but aborts the sync in the
+ * parent. Therefore, the sync_next() succeeds just fine due to the abortion.
+ */
+TEST_BARRIER(test_barrier_sync_next_local_abort,
+        ({
+                set_alarm(BASE_TIME * 10);
+                assert_se(barrier_place(&b));
+                assert_se(!barrier_sync_next(&b));
+        }),
+        TEST_BARRIER_WAIT_SUCCESS(pid1),
+        ({
+                assert_se(barrier_abort(&b));
+        }),
+        TEST_BARRIER_WAIT_SUCCESS(pid2));
+
+/*
+ * Test matched wait_abortion()
+ * This runs wait_abortion() with remote abortion.
+ */
+TEST_BARRIER(test_barrier_wait_abortion,
+        ({
+                set_alarm(BASE_TIME * 10);
+                assert_se(barrier_wait_abortion(&b));
+        }),
+        TEST_BARRIER_WAIT_SUCCESS(pid1),
+        ({
+                assert_se(barrier_abort(&b));
+        }),
+        TEST_BARRIER_WAIT_SUCCESS(pid2));
+
+/*
+ * Test unmatched wait_abortion()
+ * This runs wait_abortion() without any remote abortion going on. It thus must
+ * timeout.
+ */
+TEST_BARRIER(test_barrier_wait_abortion_unmatched,
+        ({
+                set_alarm(BASE_TIME);
+                assert_se(barrier_wait_abortion(&b));
+                assert_se(0);
+        }),
+        TEST_BARRIER_WAIT_ALARM(pid1),
+        ({
+                sleep_for(BASE_TIME * 2);
+        }),
+        TEST_BARRIER_WAIT_SUCCESS(pid2));
+
+/*
+ * Test matched wait_abortion() with local abortion
+ * This runs wait_abortion() with local and remote abortion.
+ */
+TEST_BARRIER(test_barrier_wait_abortion_local,
+        ({
+                set_alarm(BASE_TIME * 10);
+                assert_se(barrier_abort(&b));
+                assert_se(!barrier_wait_abortion(&b));
+        }),
+        TEST_BARRIER_WAIT_SUCCESS(pid1),
+        ({
+                assert_se(barrier_abort(&b));
+        }),
+        TEST_BARRIER_WAIT_SUCCESS(pid2));
+
+/*
+ * Test unmatched wait_abortion() with local abortion
+ * This runs wait_abortion() with only local abortion. This must time out.
+ */
+TEST_BARRIER(test_barrier_wait_abortion_local_unmatched,
+        ({
+                set_alarm(BASE_TIME);
+                assert_se(barrier_abort(&b));
+                assert_se(!barrier_wait_abortion(&b));
+                assert_se(0);
+        }),
+        TEST_BARRIER_WAIT_ALARM(pid1),
+        ({
+                sleep_for(BASE_TIME * 2);
+        }),
+        TEST_BARRIER_WAIT_SUCCESS(pid2));
+
+/*
+ * Test child exit
+ * Place barrier and sync with the child. The child only exits()s, which should
+ * cause an implicit abortion and wake the parent.
+ */
+TEST_BARRIER(test_barrier_exit,
+        ({
+        }),
+        TEST_BARRIER_WAIT_SUCCESS(pid1),
+        ({
+                set_alarm(BASE_TIME * 10);
+                assert_se(barrier_place(&b));
+                assert_se(!barrier_sync(&b));
+        }),
+        TEST_BARRIER_WAIT_SUCCESS(pid2));
+
+/*
+ * Test child exit with sleep
+ * Same as test_barrier_exit but verifies the test really works due to the
+ * child-exit. We add a usleep() which triggers the alarm in the parent and
+ * causes the test to time out.
+ */
+TEST_BARRIER(test_barrier_no_exit,
+        ({
+                sleep_for(BASE_TIME * 2);
+        }),
+        TEST_BARRIER_WAIT_SUCCESS(pid1),
+        ({
+                set_alarm(BASE_TIME);
+                assert_se(barrier_place(&b));
+                assert_se(!barrier_sync(&b));
+        }),
+        TEST_BARRIER_WAIT_ALARM(pid2));
+
+/*
+ * Test pending exit against sync
+ * The parent places a barrier *and* exits. The 20ms wait in the child
+ * guarantees both are pending. However, our logic prefers pending barriers over
+ * pending exit-abortions (unlike normal abortions), thus the wait_next() must
+ * succeed, same for the sync_next() as our local barrier-count is smaller than
+ * the remote. Once we place a barrier our count is equal, so the sync still
+ * succeeds. Only if we place one more barrier, we're ahead of the remote, thus
+ * we will fail due to HUP on the pipe.
+ */
+TEST_BARRIER(test_barrier_pending_exit,
+        ({
+                set_alarm(BASE_TIME * 4);
+                sleep_for(BASE_TIME * 2);
+                assert_se(barrier_wait_next(&b));
+                assert_se(barrier_sync_next(&b));
+                assert_se(barrier_place(&b));
+                assert_se(barrier_sync_next(&b));
+                assert_se(barrier_place(&b));
+                assert_se(!barrier_sync_next(&b));
+        }),
+        TEST_BARRIER_WAIT_SUCCESS(pid1),
+        ({
+                assert_se(barrier_place(&b));
+        }),
+        TEST_BARRIER_WAIT_SUCCESS(pid2));
+
+int main(int argc, char *argv[]) {
+        log_parse_environment();
+        log_open();
+
+        test_barrier_sync();
+        test_barrier_wait_next();
+        test_barrier_wait_next_twice();
+        test_barrier_wait_next_twice_sync();
+        test_barrier_wait_next_twice_local();
+        test_barrier_wait_next_twice_local_sync();
+        test_barrier_sync_next();
+        test_barrier_sync_next_local();
+        test_barrier_sync_next_local_abort();
+        test_barrier_wait_abortion();
+        test_barrier_wait_abortion_unmatched();
+        test_barrier_wait_abortion_local();
+        test_barrier_wait_abortion_local_unmatched();
+        test_barrier_exit();
+        test_barrier_no_exit();
+        test_barrier_pending_exit();
+
+        return 0;
+}
diff --git a/src/test/test-capability.c b/src/test/test-capability.c
new file mode 100644 (file)
index 0000000..a362fc6
--- /dev/null
@@ -0,0 +1,161 @@
+/***
+  This file is part of systemd
+
+  Copyright 2014 Ronny Chevalier
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/capability.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <pwd.h>
+#include <unistd.h>
+
+#include "capability.h"
+#include "util.h"
+#include "macro.h"
+
+static uid_t test_uid = -1;
+static gid_t test_gid = -1;
+// We keep CAP_DAC_OVERRIDE to avoid errors with gcov when doing test coverage
+static uint64_t test_flags = 1ULL << CAP_DAC_OVERRIDE;
+
+static void fork_test(void (*test_func)(void)) {
+        pid_t pid = 0;
+
+        pid = fork();
+        assert_se(pid >= 0);
+        if (pid == 0) {
+                test_func();
+                exit(0);
+        } else if (pid > 0) {
+                int status;
+
+                assert_se(waitpid(pid, &status, 0) > 0);
+                assert_se(WIFEXITED(status) && WEXITSTATUS(status) == 0);
+        }
+}
+
+static void show_capabilities(void) {
+        cap_t caps;
+        char *text;
+
+        caps = cap_get_proc();
+        assert_se(caps);
+
+        text = cap_to_text(caps, NULL);
+        assert_se(text);
+
+        log_info("Capabilities:%s", text);
+        cap_free(caps);
+        cap_free(text);
+}
+
+static int setup_tests(void) {
+        struct passwd *nobody;
+
+        nobody = getpwnam("nobody");
+        if (!nobody) {
+                log_error("Could not find nobody user: %m");
+                return -EXIT_TEST_SKIP;
+        }
+        test_uid = nobody->pw_uid;
+        test_gid = nobody->pw_gid;
+
+        return 0;
+}
+
+static void test_drop_privileges_keep_net_raw(void) {
+        int sock;
+
+        sock = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
+        assert_se(sock >= 0);
+        safe_close(sock);
+
+        assert_se(drop_privileges(test_uid, test_gid, test_flags | (1ULL << CAP_NET_RAW)) >= 0);
+        assert_se(getuid() == test_uid);
+        assert_se(getgid() == test_gid);
+        show_capabilities();
+
+        sock = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
+        assert_se(sock >= 0);
+        safe_close(sock);
+}
+
+static void test_drop_privileges_dontkeep_net_raw(void) {
+        int sock;
+
+        sock = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
+        assert_se(sock >= 0);
+        safe_close(sock);
+
+        assert_se(drop_privileges(test_uid, test_gid, test_flags) >= 0);
+        assert_se(getuid() == test_uid);
+        assert_se(getgid() == test_gid);
+        show_capabilities();
+
+        sock = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
+        assert_se(sock < 0);
+}
+
+static void test_drop_privileges_fail(void) {
+        assert_se(drop_privileges(test_uid, test_gid, test_flags) >= 0);
+        assert_se(getuid() == test_uid);
+        assert_se(getgid() == test_gid);
+
+        assert_se(drop_privileges(test_uid, test_gid, test_flags) < 0);
+        assert_se(drop_privileges(0, 0, test_flags) < 0);
+}
+
+static void test_drop_privileges(void) {
+        fork_test(test_drop_privileges_keep_net_raw);
+        fork_test(test_drop_privileges_dontkeep_net_raw);
+        fork_test(test_drop_privileges_fail);
+}
+
+static void test_have_effective_cap(void) {
+        assert_se(have_effective_cap(CAP_KILL));
+        assert_se(have_effective_cap(CAP_CHOWN));
+
+        assert_se(drop_privileges(test_uid, test_gid, test_flags | (1ULL << CAP_KILL)) >= 0);
+        assert_se(getuid() == test_uid);
+        assert_se(getgid() == test_gid);
+
+        assert_se(have_effective_cap(CAP_KILL));
+        assert_se(!have_effective_cap(CAP_CHOWN));
+}
+
+int main(int argc, char *argv[]) {
+        int r;
+
+        log_parse_environment();
+        log_open();
+
+        if (getuid() != 0)
+                return EXIT_TEST_SKIP;
+
+        r = setup_tests();
+        if (r < 0)
+                return -r;
+
+        show_capabilities();
+
+        test_drop_privileges();
+        fork_test(test_have_effective_cap);
+
+        return 0;
+}
index 4d60859..f98e1bb 100644 (file)
@@ -37,11 +37,10 @@ static int test_cgroup_mask(void) {
         FILE *serial = NULL;
         FDSet *fdset = NULL;
         int r;
-        const char *dir = TEST_DIR;
 
         /* Prepare the manager. */
-        assert_se(set_unit_path(dir) >= 0);
-        r = manager_new(SYSTEMD_USER, &m);
+        assert_se(set_unit_path(TEST_DIR) >= 0);
+        r = manager_new(SYSTEMD_USER, true, &m);
         if (r == -EPERM || r == -EACCES) {
                 puts("manager_new: Permission denied. Skipping test.");
                 return EXIT_TEST_SKIP;
@@ -83,20 +82,20 @@ static int test_cgroup_mask(void) {
         assert(unit_get_members_mask(root) == (CGROUP_CPU | CGROUP_CPUACCT | CGROUP_BLKIO | CGROUP_MEMORY));
 
         /* Verify aggregation of sibling masks. */
-        assert(unit_get_siblings_mask(son) == (CGROUP_CPU | CGROUP_CPUACCT));
-        assert(unit_get_siblings_mask(daughter) == (CGROUP_CPU | CGROUP_CPUACCT));
+        assert(unit_get_siblings_mask(son) == ((CGROUP_CPU | CGROUP_CPUACCT | CGROUP_MEMORY) & m->cgroup_supported));
+        assert(unit_get_siblings_mask(daughter) == ((CGROUP_CPU | CGROUP_CPUACCT | CGROUP_MEMORY) & m->cgroup_supported));
         assert(unit_get_siblings_mask(grandchild) == 0);
-        assert(unit_get_siblings_mask(parent_deep) == (CGROUP_CPU | CGROUP_CPUACCT));
-        assert(unit_get_siblings_mask(parent) == (CGROUP_CPU | CGROUP_CPUACCT | CGROUP_BLKIO));
-        assert(unit_get_siblings_mask(root) == (CGROUP_CPU | CGROUP_CPUACCT | CGROUP_BLKIO));
+        assert(unit_get_siblings_mask(parent_deep) == ((CGROUP_CPU | CGROUP_CPUACCT | CGROUP_MEMORY) & m->cgroup_supported));
+        assert(unit_get_siblings_mask(parent) == ((CGROUP_CPU | CGROUP_CPUACCT | CGROUP_BLKIO | CGROUP_MEMORY) & m->cgroup_supported));
+        assert(unit_get_siblings_mask(root) == ((CGROUP_CPU | CGROUP_CPUACCT | CGROUP_BLKIO | CGROUP_MEMORY) & m->cgroup_supported));
 
         /* Verify aggregation of target masks. */
-        assert(unit_get_target_mask(son) == (CGROUP_CPU | CGROUP_CPUACCT));
-        assert(unit_get_target_mask(daughter) == (CGROUP_CPU | CGROUP_CPUACCT));
+        assert(unit_get_target_mask(son) == ((CGROUP_CPU | CGROUP_CPUACCT | CGROUP_MEMORY) & m->cgroup_supported));
+        assert(unit_get_target_mask(daughter) == ((CGROUP_CPU | CGROUP_CPUACCT | CGROUP_MEMORY) & m->cgroup_supported));
         assert(unit_get_target_mask(grandchild) == 0);
-        assert(unit_get_target_mask(parent_deep) == (CGROUP_CPU | CGROUP_CPUACCT | CGROUP_MEMORY));
-        assert(unit_get_target_mask(parent) == (CGROUP_CPU | CGROUP_CPUACCT | CGROUP_BLKIO | CGROUP_MEMORY));
-        assert(unit_get_target_mask(root) == (CGROUP_CPU | CGROUP_CPUACCT | CGROUP_BLKIO | CGROUP_MEMORY));
+        assert(unit_get_target_mask(parent_deep) == ((CGROUP_CPU | CGROUP_CPUACCT | CGROUP_MEMORY) & m->cgroup_supported));
+        assert(unit_get_target_mask(parent) == ((CGROUP_CPU | CGROUP_CPUACCT | CGROUP_BLKIO | CGROUP_MEMORY) & m->cgroup_supported));
+        assert(unit_get_target_mask(root) == ((CGROUP_CPU | CGROUP_CPUACCT | CGROUP_BLKIO | CGROUP_MEMORY) & m->cgroup_supported));
 
         manager_free(m);
 
index b37468b..fda8bcc 100644 (file)
@@ -162,11 +162,11 @@ static void test_proc(void) {
                 cg_pid_get_machine_name(pid, &machine);
                 cg_pid_get_slice(pid, &slice);
 
-                printf("%lu\t%s\t%s\t%lu\t%s\t%s\t%s\t%s\t%s\n",
-                       (unsigned long) pid,
+                printf(PID_FMT"\t%s\t%s\t"UID_FMT"\t%s\t%s\t%s\t%s\t%s\n",
+                       pid,
                        path,
                        path_shifted,
-                       (unsigned long) uid,
+                       uid,
                        session,
                        unit,
                        user_unit,
diff --git a/src/test/test-condition-util.c b/src/test/test-condition-util.c
new file mode 100644 (file)
index 0000000..4ee5600
--- /dev/null
@@ -0,0 +1,107 @@
+/***
+  This file is part of systemd
+
+  Copyright 2014 Ronny Chevalier
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "condition-util.h"
+#include "macro.h"
+#include "util.h"
+#include "log.h"
+#include "architecture.h"
+#include "systemd/sd-id128.h"
+
+static void test_condition_test_ac_power(void) {
+        Condition *condition;
+
+        condition = condition_new(CONDITION_AC_POWER, "true", false, false);
+        assert_se(condition_test_ac_power(condition) == on_ac_power());
+        condition_free(condition);
+
+        condition = condition_new(CONDITION_AC_POWER, "false", false, false);
+        assert_se(condition_test_ac_power(condition) != on_ac_power());
+        condition_free(condition);
+
+        condition = condition_new(CONDITION_AC_POWER, "false", false, true);
+        assert_se(condition_test_ac_power(condition) == on_ac_power());
+        condition_free(condition);
+}
+
+static void test_condition_test_host(void) {
+        Condition *condition;
+        sd_id128_t id;
+        int r;
+        char sid[SD_ID128_STRING_MAX];
+        char *hostname;
+
+        r = sd_id128_get_machine(&id);
+        assert_se(r >= 0);
+        assert_se(sd_id128_to_string(id, sid));
+
+        condition = condition_new(CONDITION_HOST, sid, false, false);
+        assert_se(condition_test_host(condition));
+        condition_free(condition);
+
+        condition = condition_new(CONDITION_HOST, "garbage value jjjjjjjjjjjjjj", false, false);
+        assert_se(!condition_test_host(condition));
+        condition_free(condition);
+
+        condition = condition_new(CONDITION_HOST, sid, false, true);
+        assert_se(!condition_test_host(condition));
+        condition_free(condition);
+
+        hostname = gethostname_malloc();
+        assert_se(hostname);
+
+        condition = condition_new(CONDITION_HOST, hostname, false, false);
+        assert_se(condition_test_host(condition));
+        condition_free(condition);
+}
+
+static void test_condition_test_architecture(void) {
+        Condition *condition;
+        Architecture a;
+        const char *sa;
+
+        a = uname_architecture();
+        assert_se(a >= 0);
+
+        sa = architecture_to_string(a);
+        assert_se(sa);
+
+        condition = condition_new(CONDITION_ARCHITECTURE, sa, false, false);
+        assert_se(condition_test_architecture(condition));
+        condition_free(condition);
+
+        condition = condition_new(CONDITION_ARCHITECTURE, "garbage value", false, false);
+        assert_se(!condition_test_architecture(condition));
+        condition_free(condition);
+
+        condition = condition_new(CONDITION_ARCHITECTURE, sa, false, true);
+        assert_se(!condition_test_architecture(condition));
+        condition_free(condition);
+}
+
+int main(int argc, char *argv[]) {
+        log_parse_environment();
+        log_open();
+
+        test_condition_test_ac_power();
+        test_condition_test_host();
+        test_condition_test_architecture();
+
+        return 0;
+}
diff --git a/src/test/test-conf-files.c b/src/test/test-conf-files.c
new file mode 100644 (file)
index 0000000..e801c59
--- /dev/null
@@ -0,0 +1,84 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Michael Marineau
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "conf-files.h"
+#include "macro.h"
+#include "strv.h"
+#include "util.h"
+
+
+static void setup_test_dir(char *tmp_dir, const char *files, ...) {
+        va_list ap;
+
+        assert_se(mkdtemp(tmp_dir) != NULL);
+
+        va_start(ap, files);
+        while (files != NULL) {
+                _cleanup_free_ char *path = strappend(tmp_dir, files);
+                assert_se(touch_file(path, true, (usec_t) -1, (uid_t) -1, (gid_t) -1, 0) == 0);
+                files = va_arg(ap, const char *);
+        }
+        va_end(ap);
+}
+
+static void test_conf_files_list(bool use_root) {
+        char tmp_dir[] = "/tmp/test-conf-files-XXXXXX";
+        _cleanup_strv_free_ char **found_files = NULL;
+        const char *root_dir, *search_1, *search_2, *expect_a, *expect_b;
+
+        setup_test_dir(tmp_dir,
+                       "/dir1/a.conf",
+                       "/dir2/a.conf",
+                       "/dir2/b.conf",
+                       NULL);
+
+        if (use_root) {
+                root_dir = tmp_dir;
+                search_1 = "/dir1";
+                search_2 = "/dir2";
+        } else {
+                root_dir = NULL;
+                search_1 = strappenda(tmp_dir, "/dir1");
+                search_2 = strappenda(tmp_dir, "/dir2");
+        }
+
+        expect_a = strappenda(tmp_dir, "/dir1/a.conf");
+        expect_b = strappenda(tmp_dir, "/dir2/b.conf");
+
+        assert_se(conf_files_list(&found_files, ".conf", root_dir, search_1, search_2, NULL) == 0);
+        strv_print(found_files);
+
+        assert_se(found_files);
+        assert_se(streq_ptr(found_files[0], expect_a));
+        assert_se(streq_ptr(found_files[1], expect_b));
+        assert_se(found_files[2] == NULL);
+
+        assert_se(rm_rf_dangerous(tmp_dir, false, true, false) == 0);
+}
+
+int main(int argc, char **argv) {
+        test_conf_files_list(false);
+        test_conf_files_list(true);
+        return 0;
+}
index 3215f0c..bcc049b 100644 (file)
@@ -21,7 +21,7 @@
 
 #include <unistd.h>
 
-#include <systemd/sd-daemon.h>
+#include "systemd/sd-daemon.h"
 
 int main(int argc, char*argv[]) {
 
index 40ffc17..0586b78 100644 (file)
@@ -56,6 +56,7 @@ int main(int argc, char *argv[]) {
         test_one("+2d");
         test_one("+2y 4d");
         test_one("5months ago");
+        test_one("@1395716396");
 
         return 0;
 }
index 0f38622..6e39a58 100644 (file)
 #include <unistd.h>
 
 #include "manager.h"
+#include "bus-util.h"
 
 int main(int argc, char *argv[]) {
+        _cleanup_bus_error_free_ sd_bus_error err = SD_BUS_ERROR_NULL;
         Manager *m = NULL;
         Unit *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL, *g = NULL, *h = NULL;
+        FILE *serial = NULL;
+        FDSet *fdset = NULL;
         Job *j;
-
-        assert_se(set_unit_path("test") >= 0);
-
-        assert_se(manager_new(SYSTEMD_SYSTEM, &m) >= 0);
+        int r;
+
+        /* prepare the test */
+        assert_se(set_unit_path(TEST_DIR) >= 0);
+        r = manager_new(SYSTEMD_USER, true, &m);
+        if (r == -EPERM || r == -EACCES || r == -EADDRINUSE || r == -EHOSTDOWN) {
+                printf("Skipping test: manager_new: %s", strerror(-r));
+                return EXIT_TEST_SKIP;
+        }
+        assert(r >= 0);
+        assert_se(manager_startup(m, serial, fdset) >= 0);
 
         printf("Load1:\n");
         assert_se(manager_load_unit(m, "a.service", NULL, NULL, &a) >= 0);
@@ -42,7 +53,10 @@ int main(int argc, char *argv[]) {
         manager_dump_units(m, stdout, "\t");
 
         printf("Test1: (Trivial)\n");
-        assert_se(manager_add_job(m, JOB_START, c, JOB_REPLACE, false, NULL, &j) == 0);
+        r = manager_add_job(m, JOB_START, c, JOB_REPLACE, false, &err, &j);
+        if (sd_bus_error_is_set(&err))
+                log_error("error: %s: %s", err.name, err.message);
+        assert(r == 0);
         manager_dump_jobs(m, stdout, "\t");
 
         printf("Load2:\n");
diff --git a/src/test/test-fdset.c b/src/test/test-fdset.c
new file mode 100644 (file)
index 0000000..91df7eb
--- /dev/null
@@ -0,0 +1,166 @@
+/***
+  This file is part of systemd
+
+  Copyright 2014 Ronny Chevalier
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "fdset.h"
+#include "util.h"
+#include "macro.h"
+
+static void test_fdset_new_fill(void) {
+        int fd = -1;
+        _cleanup_fdset_free_ FDSet *fdset = NULL;
+        char name[] = "/tmp/test-fdset_new_fill.XXXXXX";
+
+        fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+        assert_se(fd >= 0);
+        assert_se(fdset_new_fill(&fdset) >= 0);
+        assert_se(fdset_contains(fdset, fd));
+
+        unlink(name);
+}
+
+static void test_fdset_put_dup(void) {
+        _cleanup_close_ int fd = -1;
+        int copyfd = -1;
+        _cleanup_fdset_free_ FDSet *fdset = NULL;
+        char name[] = "/tmp/test-fdset_put_dup.XXXXXX";
+
+        fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+        assert_se(fd >= 0);
+
+        fdset = fdset_new();
+        assert_se(fdset);
+        copyfd = fdset_put_dup(fdset, fd);
+        assert_se(copyfd >= 0 && copyfd != fd);
+        assert_se(fdset_contains(fdset, copyfd));
+        assert_se(!fdset_contains(fdset, fd));
+
+        unlink(name);
+}
+
+static void test_fdset_cloexec(void) {
+        int fd = -1;
+        _cleanup_fdset_free_ FDSet *fdset = NULL;
+        int flags = -1;
+        char name[] = "/tmp/test-fdset_cloexec.XXXXXX";
+
+        fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+        assert_se(fd >= 0);
+
+        fdset = fdset_new();
+        assert_se(fdset);
+        assert_se(fdset_put(fdset, fd));
+
+        assert_se(fdset_cloexec(fdset, false) >= 0);
+        flags = fcntl(fd, F_GETFD);
+        assert_se(flags >= 0);
+        assert_se(!(flags & FD_CLOEXEC));
+
+        assert_se(fdset_cloexec(fdset, true) >= 0);
+        flags = fcntl(fd, F_GETFD);
+        assert_se(flags >= 0);
+        assert_se(flags & FD_CLOEXEC);
+
+        unlink(name);
+}
+
+static void test_fdset_close_others(void) {
+        int fd = -1;
+        int copyfd = -1;
+        _cleanup_fdset_free_ FDSet *fdset = NULL;
+        int flags = -1;
+        char name[] = "/tmp/test-fdset_close_others.XXXXXX";
+
+        fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+        assert_se(fd >= 0);
+
+        fdset = fdset_new();
+        assert_se(fdset);
+        copyfd = fdset_put_dup(fdset, fd);
+        assert_se(copyfd >= 0);
+
+        assert_se(fdset_close_others(fdset) >= 0);
+        flags = fcntl(fd, F_GETFD);
+        assert_se(flags < 0);
+        flags = fcntl(copyfd, F_GETFD);
+        assert_se(flags >= 0);
+
+        unlink(name);
+}
+
+static void test_fdset_remove(void) {
+        _cleanup_close_ int fd = -1;
+        FDSet *fdset = NULL;
+        char name[] = "/tmp/test-fdset_remove.XXXXXX";
+
+        fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+        assert_se(fd >= 0);
+
+        fdset = fdset_new();
+        assert_se(fdset);
+        assert_se(fdset_put(fdset, fd) >= 0);
+        assert_se(fdset_remove(fdset, fd) >= 0);
+        assert_se(!fdset_contains(fdset, fd));
+        fdset_free(fdset);
+
+        assert_se(fcntl(fd, F_GETFD) >= 0);
+
+        unlink(name);
+}
+
+static void test_fdset_iterate(void) {
+        int fd = -1;
+        FDSet *fdset = NULL;
+        char name[] = "/tmp/test-fdset_iterate.XXXXXX";
+        Iterator i;
+        int c = 0;
+        int a;
+
+        fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+        assert_se(fd >= 0);
+
+        fdset = fdset_new();
+        assert_se(fdset);
+        assert_se(fdset_put(fdset, fd) >= 0);
+        assert_se(fdset_put(fdset, fd) >= 0);
+        assert_se(fdset_put(fdset, fd) >= 0);
+
+        FDSET_FOREACH(a, fdset, i) {
+                c++;
+                assert_se(a == fd);
+        }
+        assert_se(c == 1);
+
+        fdset_free(fdset);
+
+        unlink(name);
+}
+
+int main(int argc, char *argv[]) {
+        test_fdset_new_fill();
+        test_fdset_put_dup();
+        test_fdset_cloexec();
+        test_fdset_close_others();
+        test_fdset_remove();
+        test_fdset_iterate();
+
+        return 0;
+}
index 47a0907..e69706c 100644 (file)
@@ -72,7 +72,7 @@ static void test_parse_env_file(void) {
         fflush(f);
         fclose(f);
 
-        r = load_env_file(t, NULL, &a);
+        r = load_env_file(NULL, t, NULL, &a);
         assert_se(r >= 0);
 
         STRV_FOREACH(i, a)
@@ -139,7 +139,7 @@ static void test_parse_env_file(void) {
         r = write_env_file(p, a);
         assert_se(r >= 0);
 
-        r = load_env_file(p, NULL, &b);
+        r = load_env_file(NULL, p, NULL, &b);
         assert_se(r >= 0);
 
         unlink(t);
@@ -179,7 +179,7 @@ static void test_parse_multiline_env_file(void) {
         fflush(f);
         fclose(f);
 
-        r = load_env_file(t, NULL, &a);
+        r = load_env_file(NULL, t, NULL, &a);
         assert_se(r >= 0);
 
         STRV_FOREACH(i, a)
@@ -193,7 +193,7 @@ static void test_parse_multiline_env_file(void) {
         r = write_env_file(p, a);
         assert_se(r >= 0);
 
-        r = load_env_file(p, NULL, &b);
+        r = load_env_file(NULL, p, NULL, &b);
         assert_se(r >= 0);
 
         unlink(t);
@@ -290,6 +290,72 @@ static void test_capeff(void) {
         }
 }
 
+static void test_write_string_stream(void) {
+        char fn[] = "/tmp/test-write_string_stream-XXXXXX";
+        _cleanup_fclose_ FILE *f = NULL;
+        int fd;
+        char buf[64];
+
+        fd = mkostemp_safe(fn, O_RDWR);
+        assert_se(fd >= 0);
+
+        f = fdopen(fd, "r");
+        assert_se(f);
+        assert_se(write_string_stream(f, "boohoo") < 0);
+
+        f = fdopen(fd, "r+");
+        assert_se(f);
+
+        assert_se(write_string_stream(f, "boohoo") == 0);
+        rewind(f);
+
+        assert_se(fgets(buf, sizeof(buf), f));
+        assert_se(streq(buf, "boohoo\n"));
+
+        unlink(fn);
+}
+
+static void test_write_string_file(void) {
+        char fn[] = "/tmp/test-write_string_file-XXXXXX";
+        int fd;
+        char buf[64] = {0};
+
+        fd = mkostemp_safe(fn, O_RDWR);
+        assert_se(fd >= 0);
+
+        assert_se(write_string_file(fn, "boohoo") == 0);
+
+        assert_se(read(fd, buf, sizeof(buf)));
+        assert_se(streq(buf, "boohoo\n"));
+
+        unlink(fn);
+}
+
+static void test_sendfile_full(void) {
+        char in_fn[] = "/tmp/test-sendfile_full-XXXXXX";
+        char out_fn[] = "/tmp/test-sendfile_full-XXXXXX";
+        _cleanup_close_ int in_fd = -1;
+        int out_fd;
+        char text[] = "boohoo\nfoo\n\tbar\n";
+        char buf[64] = {0};
+
+        in_fd = mkostemp_safe(in_fn, O_RDWR);
+        assert_se(in_fd >= 0);
+        out_fd = mkostemp_safe(out_fn, O_RDWR);
+        assert_se(out_fd >= 0);
+
+        assert_se(write_string_file(in_fn, text) == 0);
+        assert_se(sendfile_full(out_fd, "/a/file/which/does/not/exist/i/guess") < 0);
+        assert_se(sendfile_full(out_fd, in_fn) == sizeof(text) - 1);
+        assert_se(lseek(out_fd, SEEK_SET, 0) == 0);
+
+        assert_se(read(out_fd, buf, sizeof(buf)) == sizeof(text) - 1);
+        assert_se(streq(buf, text));
+
+        unlink(in_fn);
+        unlink(out_fn);
+}
+
 int main(int argc, char *argv[]) {
         log_parse_environment();
         log_open();
@@ -299,6 +365,9 @@ int main(int argc, char *argv[]) {
         test_executable_is_script();
         test_status_field();
         test_capeff();
+        test_write_string_stream();
+        test_write_string_file();
+        test_sendfile_full();
 
         return 0;
 }
index 56a9b58..ccef61f 100644 (file)
@@ -231,6 +231,32 @@ static void test_hashmap_put(void) {
         hashmap_free(m);
 }
 
+static void test_hashmap_remove_and_put(void) {
+        _cleanup_hashmap_free_ Hashmap *m = NULL;
+        int valid;
+        char *r;
+
+        m = hashmap_new(string_hash_func, string_compare_func);
+        assert_se(m);
+
+        valid = hashmap_remove_and_put(m, "unvalid key", "new key", NULL);
+        assert_se(valid < 0);
+
+        valid = hashmap_put(m, "key 1", (void*) (const char *) "val 1");
+        assert_se(valid == 1);
+        valid = hashmap_remove_and_put(m, "key 1", "key 2", (void*) (const char *) "val 2");
+        assert_se(valid == 0);
+
+        r = hashmap_get(m, "key 2");
+        assert_se(streq(r, "val 2"));
+        assert_se(!hashmap_get(m, "key 1"));
+
+        valid = hashmap_put(m, "key 3", (void*) (const char *) "val 3");
+        assert_se(valid == 1);
+        valid = hashmap_remove_and_put(m, "key 3", "key 2", (void*) (const char *) "val 2");
+        assert_se(valid < 0);
+}
+
 static void test_hashmap_ensure_allocated(void) {
         Hashmap *m;
         int valid_hashmap;
@@ -491,6 +517,63 @@ static void test_hashmap_many(void) {
         hashmap_free(h);
 }
 
+static void test_hashmap_first_key(void) {
+        _cleanup_hashmap_free_ Hashmap *m = NULL;
+
+        m = hashmap_new(string_hash_func, string_compare_func);
+        assert_se(m);
+
+        assert_se(!hashmap_first_key(m));
+        assert_se(hashmap_put(m, "key 1", NULL) == 1);
+        assert_se(streq(hashmap_first_key(m), "key 1"));
+        assert_se(hashmap_put(m, "key 2", NULL) == 1);
+        assert_se(streq(hashmap_first_key(m), "key 1"));
+        assert_se(hashmap_remove(m, "key 1") == NULL);
+        assert_se(streq(hashmap_first_key(m), "key 2"));
+}
+
+static void test_hashmap_last(void) {
+        _cleanup_hashmap_free_ Hashmap *m = NULL;
+
+        m = hashmap_new(string_hash_func, string_compare_func);
+        assert_se(m);
+
+        assert_se(!hashmap_last(m));
+        assert_se(hashmap_put(m, "key 1", (void *) (const char *) "val 1") == 1);
+        assert_se(streq(hashmap_last(m), "val 1"));
+        assert_se(hashmap_put(m, "key 2", (void *) (const char *) "bar") == 1);
+        assert_se(streq(hashmap_last(m), "bar"));
+        assert_se(hashmap_remove(m, "key 2"));
+        assert_se(streq(hashmap_last(m), "val 1"));
+}
+
+static void test_hashmap_steal_first_key(void) {
+        _cleanup_hashmap_free_ Hashmap *m = NULL;
+
+        m = hashmap_new(string_hash_func, string_compare_func);
+        assert_se(m);
+
+        assert_se(!hashmap_steal_first_key(m));
+        assert_se(hashmap_put(m, "key 1", NULL) == 1);
+        assert_se(streq(hashmap_steal_first_key(m), "key 1"));
+
+        assert_se(hashmap_isempty(m));
+}
+
+static void test_hashmap_clear_free_free(void) {
+        _cleanup_hashmap_free_ Hashmap *m = NULL;
+
+        m = hashmap_new(string_hash_func, string_compare_func);
+        assert_se(m);
+
+        assert_se(hashmap_put(m, strdup("key 1"), NULL) == 1);
+        assert_se(hashmap_put(m, strdup("key 2"), NULL) == 1);
+        assert_se(hashmap_put(m, strdup("key 3"), NULL) == 1);
+
+        hashmap_clear_free_free(m);
+        assert_se(hashmap_isempty(m));
+}
+
 static void test_uint64_compare_func(void) {
         const uint64_t a = 0x100, b = 0x101;
 
@@ -518,6 +601,7 @@ int main(int argc, const char *argv[]) {
         test_hashmap_replace();
         test_hashmap_update();
         test_hashmap_put();
+        test_hashmap_remove_and_put();
         test_hashmap_ensure_allocated();
         test_hashmap_foreach();
         test_hashmap_foreach_backwards();
@@ -528,6 +612,10 @@ int main(int argc, const char *argv[]) {
         test_hashmap_get();
         test_hashmap_size();
         test_hashmap_many();
+        test_hashmap_first_key();
+        test_hashmap_last();
+        test_hashmap_steal_first_key();
+        test_hashmap_clear_free_free();
         test_uint64_compare_func();
         test_trivial_compare_func();
         test_string_compare_func();
index 7b92758..a6a0cd7 100644 (file)
@@ -21,7 +21,7 @@
 
 #include <string.h>
 
-#include <systemd/sd-id128.h>
+#include "systemd/sd-id128.h"
 
 #include "util.h"
 #include "macro.h"
index 2087d52..099eb40 100644 (file)
@@ -253,7 +253,7 @@ int main(int argc, char* argv[]) {
         changes = NULL;
         n_changes = 0;
 
-        r = unit_file_preset(UNIT_FILE_SYSTEM, false, NULL, (char**) files, false, &changes, &n_changes);
+        r = unit_file_preset(UNIT_FILE_SYSTEM, false, NULL, (char**) files, UNIT_FILE_PRESET_FULL, false, &changes, &n_changes);
         assert_se(r >= 0);
 
         dump_changes(changes, n_changes);
diff --git a/src/test/test-ipcrm.c b/src/test/test-ipcrm.c
new file mode 100644 (file)
index 0000000..4944bf6
--- /dev/null
@@ -0,0 +1,32 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "util.h"
+#include "clean-ipc.h"
+
+int main(int argc, char *argv[]) {
+        uid_t uid;
+
+        assert_se(argc == 2);
+        assert_se(parse_uid(argv[1], &uid) >= 0);
+
+        return clean_ipc(uid) < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
index c233b1e..ea19099 100644 (file)
@@ -1,3 +1,4 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
 /***
   This file is part of systemd.
 
@@ -24,7 +25,6 @@
 #include <errno.h>
 #include <string.h>
 #include <getopt.h>
-#include <syslog.h>
 #include <fcntl.h>
 #include <sys/epoll.h>
 
@@ -303,38 +303,14 @@ out:
 
 static int test_queue(struct udev *udev) {
         struct udev_queue *udev_queue;
-        unsigned long long int seqnum;
-        struct udev_list_entry *list_entry;
 
         udev_queue = udev_queue_new(udev);
         if (udev_queue == NULL)
                 return -1;
-        seqnum = udev_queue_get_kernel_seqnum(udev_queue);
-        printf("seqnum kernel: %llu\n", seqnum);
-        seqnum = udev_queue_get_udev_seqnum(udev_queue);
-        printf("seqnum udev  : %llu\n", seqnum);
 
         if (udev_queue_get_queue_is_empty(udev_queue))
                 printf("queue is empty\n");
-        printf("get queue list\n");
-        udev_list_entry_foreach(list_entry, udev_queue_get_queued_list_entry(udev_queue))
-                printf("queued: '%s' [%s]\n", udev_list_entry_get_name(list_entry), udev_list_entry_get_value(list_entry));
-        printf("\n");
-        printf("get queue list again\n");
-        udev_list_entry_foreach(list_entry, udev_queue_get_queued_list_entry(udev_queue))
-                printf("queued: '%s' [%s]\n", udev_list_entry_get_name(list_entry), udev_list_entry_get_value(list_entry));
-        printf("\n");
 
-        list_entry = udev_queue_get_queued_list_entry(udev_queue);
-        if (list_entry != NULL) {
-                printf("event [%llu] is queued\n", seqnum);
-                seqnum = strtoull(udev_list_entry_get_value(list_entry), NULL, 10);
-                if (udev_queue_get_seqnum_is_finished(udev_queue, seqnum))
-                        printf("event [%llu] is not finished\n", seqnum);
-                else
-                        printf("event [%llu] is finished\n", seqnum);
-        }
-        printf("\n");
         udev_queue_unref(udev_queue);
         return 0;
 }
@@ -447,6 +423,7 @@ int main(int argc, char *argv[]) {
         const char *syspath = "/devices/virtual/mem/null";
         const char *subsystem = NULL;
         char path[1024];
+        int c;
 
         udev = udev_new();
         printf("context: %p\n", udev);
@@ -457,34 +434,38 @@ int main(int argc, char *argv[]) {
         udev_set_log_fn(udev, log_fn);
         printf("set log: %p\n", log_fn);
 
-        for (;;) {
-                int option;
 
-                option = getopt_long(argc, argv, "+p:s:dhV", options, NULL);
-                if (option == -1)
-                        break;
+        while ((c = getopt_long(argc, argv, "p:s:dhV", options, NULL)) >= 0)
+                switch (c) {
 
-                switch (option) {
                 case 'p':
                         syspath = optarg;
                         break;
+
                 case 's':
                         subsystem = optarg;
                         break;
+
                 case 'd':
                         if (udev_get_log_priority(udev) < LOG_INFO)
                                 udev_set_log_priority(udev, LOG_INFO);
                         break;
+
                 case 'h':
                         printf("--debug --syspath= --subsystem= --help\n");
                         goto out;
+
                 case 'V':
                         printf("%s\n", VERSION);
                         goto out;
-                default:
+
+                case '?':
                         goto out;
+
+                default:
+                        assert_not_reached("Unhandled option code.");
                 }
-        }
+
 
         /* add sys path if needed */
         if (!startswith(syspath, "/sys")) {
index 8dc3d53..ca64004 100644 (file)
@@ -23,6 +23,7 @@
 #include <unistd.h>
 
 #include "log.h"
+#include "util.h"
 
 int main(int argc, char* argv[]) {
 
@@ -30,7 +31,7 @@ int main(int argc, char* argv[]) {
         log_open();
 
         log_struct(LOG_INFO,
-                   "MESSAGE=Waldo PID=%lu", (unsigned long) getpid(),
+                   "MESSAGE=Waldo PID="PID_FMT, getpid(),
                    "SERVICE=piepapo",
                    NULL);
 
@@ -38,12 +39,12 @@ int main(int argc, char* argv[]) {
         log_open();
 
         log_struct(LOG_INFO,
-                   "MESSAGE=Foobar PID=%lu", (unsigned long) getpid(),
+                   "MESSAGE=Foobar PID="PID_FMT, getpid(),
                    "SERVICE=foobar",
                    NULL);
 
         log_struct(LOG_INFO,
-                   "MESSAGE=Foobar PID=%lu", (unsigned long) getpid(),
+                   "MESSAGE=Foobar PID="PID_FMT, getpid(),
                    "FORMAT_STR_TEST=1=%i A=%c 2=%hi 3=%li 4=%lli 1=%p foo=%s 2.5=%g 3.5=%g 4.5=%Lg",
                    (int) 1, 'A', (short) 2, (long int) 3, (long long int) 4, (void*) 1, "foo", (float) 2.5f, (double) 3.5, (long double) 4.5,
                    "SUFFIX=GOT IT",
index 5b76b9e..e74fd0c 100644 (file)
@@ -63,7 +63,7 @@ static void test_tmpdir(const char *id, const char *A, const char *B) {
 }
 
 static void test_netns(void) {
-        _cleanup_close_pipe_ int s[2] = { -1, -1 };
+        _cleanup_close_pair_ int s[2] = { -1, -1 };
         pid_t pid1, pid2, pid3;
         int r, n = 0;
         siginfo_t si;
index ad0d041..acad725 100644 (file)
@@ -60,6 +60,8 @@ int main(int argc, char *argv[]) {
                             tmp_dir,
                             var_tmp_dir,
                             true,
+                            PROTECT_HOME_NO,
+                            PROTECT_SYSTEM_NO,
                             0);
         if (r < 0) {
                 log_error("Failed to setup namespace: %s", strerror(-r));
index bec2a83..c8dcd85 100644 (file)
 ***/
 
 #include <stdio.h>
+#include <unistd.h>
 
 #include "path-util.h"
 #include "util.h"
 #include "macro.h"
+#include "strv.h"
 
 
 static void test_path(void) {
@@ -56,7 +58,7 @@ static void test_path(void) {
         assert_se(streq(basename("file.../"), ""));
 
 #define test_parent(x, y) {                                \
-                char _cleanup_free_ *z = NULL;             \
+                _cleanup_free_ char *z = NULL;             \
                 int r = path_get_parent(x, &z);            \
                 printf("expected: %s\n", y ? y : "error"); \
                 printf("actual: %s\n", r<0 ? "error" : z); \
@@ -83,7 +85,7 @@ static void test_path(void) {
         }
 }
 
-static void test_find_binary(void) {
+static void test_find_binary(const char *self) {
         char *p;
 
         assert(find_binary("/bin/sh", &p) == 0);
@@ -91,7 +93,7 @@ static void test_find_binary(void) {
         assert(streq(p, "/bin/sh"));
         free(p);
 
-        assert(find_binary("./test-path-util", &p) == 0);
+        assert(find_binary(self, &p) == 0);
         puts(p);
         assert(endswith(p, "/test-path-util"));
         assert(path_is_absolute(p));
@@ -104,6 +106,8 @@ static void test_find_binary(void) {
         free(p);
 
         assert(find_binary("xxxx-xxxx", &p) == -ENOENT);
+
+        assert(find_binary("/some/dir/xxxx-xxxx", &p) == -ENOENT);
 }
 
 static void test_prefixes(void) {
@@ -158,9 +162,86 @@ static void test_prefixes(void) {
         }
 }
 
-int main(void) {
+static void test_path_join(void) {
+        assert_se(streq(path_join("/root", "/a/b", "/c"), "/root/a/b/c"));
+        assert_se(streq(path_join("/root", "a/b", "c"), "/root/a/b/c"));
+        assert_se(streq(path_join("/root", "/a/b", "c"), "/root/a/b/c"));
+        assert_se(streq(path_join("/root", "/", "c"), "/root//c"));
+        assert_se(streq(path_join("/root", "/", NULL), "/root/"));
+
+        assert_se(streq(path_join(NULL, "/a/b", "/c"), "/a/b/c"));
+        assert_se(streq(path_join(NULL, "a/b", "c"), "a/b/c"));
+        assert_se(streq(path_join(NULL, "/a/b", "c"), "/a/b/c"));
+        assert_se(streq(path_join(NULL, "/", "c"), "//c"));
+        assert_se(streq(path_join(NULL, "/", NULL), "/"));
+}
+
+static void test_fsck_exists(void) {
+        /* Ensure we use a sane default for PATH. */
+        unsetenv("PATH");
+
+        /* fsck.minix is provided by util-linux and will probably exist. */
+        assert_se(fsck_exists("minix") == 0);
+
+        assert_se(fsck_exists("AbCdE") == -ENOENT);
+}
+
+static void test_make_relative(void) {
+        char *result;
+
+        assert_se(path_make_relative("some/relative/path", "/some/path", &result) < 0);
+        assert_se(path_make_relative("/some/path", "some/relative/path", &result) < 0);
+
+#define test(from_dir, to_path, expected) {                     \
+                path_make_relative(from_dir, to_path, &result); \
+                assert_se(streq(result, expected));             \
+                free(result);                                   \
+        }
+
+        test("/", "/", ".");
+        test("/", "/some/path", "some/path");
+        test("/some/path", "/some/path", ".");
+        test("/some/path", "/some/path/in/subdir", "in/subdir");
+        test("/some/path", "/", "../..");
+        test("/some/path", "/some/other/path", "../other/path");
+        test("//extra/////slashes///won't////fool///anybody//", "////extra///slashes////are/just///fine///", "../../../are/just/fine");
+}
+
+static void test_strv_resolve(void) {
+        char tmp_dir[] = "/tmp/test-path-util-XXXXXX";
+        _cleanup_strv_free_ char **search_dirs = NULL;
+        _cleanup_strv_free_ char **absolute_dirs = NULL;
+        char **d;
+
+        assert_se(mkdtemp(tmp_dir) != NULL);
+
+        search_dirs = strv_new("/dir1", "/dir2", "/dir3", NULL);
+        assert_se(search_dirs);
+        STRV_FOREACH(d, search_dirs) {
+                char *p = strappend(tmp_dir, *d);
+                assert_se(p);
+                assert_se(strv_push(&absolute_dirs, p) == 0);
+        }
+
+        assert_se(mkdir(absolute_dirs[0], 0700) == 0);
+        assert_se(mkdir(absolute_dirs[1], 0700) == 0);
+        assert_se(symlink("dir2", absolute_dirs[2]) == 0);
+
+        path_strv_resolve(search_dirs, tmp_dir);
+        assert_se(streq(search_dirs[0], "/dir1"));
+        assert_se(streq(search_dirs[1], "/dir2"));
+        assert_se(streq(search_dirs[2], "/dir2"));
+
+        assert_se(rm_rf_dangerous(tmp_dir, false, true, false) == 0);
+}
+
+int main(int argc, char **argv) {
         test_path();
-        test_find_binary();
+        test_find_binary(argv[0]);
         test_prefixes();
+        test_path_join();
+        test_fsck_exists();
+        test_make_relative();
+        test_strv_resolve();
         return 0;
 }
diff --git a/src/test/test-pty.c b/src/test/test-pty.c
new file mode 100644 (file)
index 0000000..ed23e9f
--- /dev/null
@@ -0,0 +1,143 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 David Herrmann <dh.herrmann@gmail.com>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <fcntl.h>
+#include <locale.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include "def.h"
+#include "pty.h"
+#include "util.h"
+
+static const char sndmsg[] = "message\n";
+static const char rcvmsg[] = "message\r\n";
+static char rcvbuf[128];
+static size_t rcvsiz = 0;
+static sd_event *event;
+
+static void run_child(Pty *pty) {
+        ssize_t r, l;
+        char buf[512];
+
+        r = read(0, buf, sizeof(buf));
+        assert_se((size_t)r == strlen(sndmsg));
+        assert_se(!strncmp(buf, sndmsg, r));
+
+        l = write(1, buf, r);
+        assert_se(l == r);
+}
+
+static int pty_fn(Pty *pty, void *userdata, unsigned int ev, const void *ptr, size_t size) {
+        switch (ev) {
+        case PTY_DATA:
+                assert_se(rcvsiz < strlen(rcvmsg) * 2);
+                assert_se(rcvsiz + size < sizeof(rcvbuf));
+
+                memcpy(&rcvbuf[rcvsiz], ptr, size);
+                rcvsiz += size;
+
+                if (rcvsiz >= strlen(rcvmsg) * 2) {
+                        assert_se(rcvsiz == strlen(rcvmsg) * 2);
+                        assert_se(!memcmp(rcvbuf, rcvmsg, strlen(rcvmsg)));
+                        assert_se(!memcmp(&rcvbuf[strlen(rcvmsg)], rcvmsg, strlen(rcvmsg)));
+                }
+
+                break;
+        case PTY_HUP:
+                /* This is guaranteed to appear _after_ the input queues are
+                 * drained! */
+                assert_se(rcvsiz == strlen(rcvmsg) * 2);
+                break;
+        case PTY_CHILD:
+                /* this may appear at any time */
+                break;
+        default:
+                assert_se(0);
+                break;
+        }
+
+        /* if we got HUP _and_ CHILD, exit */
+        if (pty_get_fd(pty) < 0 && pty_get_child(pty) < 0)
+                sd_event_exit(event, 0);
+
+        return 0;
+}
+
+static void run_parent(Pty *pty) {
+        int r;
+
+        /* write message to pty, ECHO mode guarantees that we get it back
+         * twice: once via ECHO, once from the run_child() fn */
+        assert_se(pty_write(pty, sndmsg, strlen(sndmsg)) >= 0);
+
+        r = sd_event_loop(event);
+        assert_se(r >= 0);
+}
+
+static void test_pty(void) {
+        pid_t pid;
+        Pty *pty;
+
+        rcvsiz = 0;
+        memset(rcvbuf, 0, sizeof(rcvbuf));
+
+        assert_se(sd_event_default(&event) >= 0);
+
+        pid = pty_fork(&pty, event, pty_fn, NULL, 80, 25);
+        assert_se(pid >= 0);
+
+        if (pid == 0) {
+                /* child */
+                run_child(pty);
+                exit(0);
+        }
+
+        /* parent */
+        run_parent(pty);
+
+        /* Make sure the PTY recycled the child; yeah, this is racy if the
+         * PID was already reused; but that seems fine for a test. */
+        assert_se(waitpid(pid, NULL, WNOHANG) < 0 && errno == ECHILD);
+
+        pty_unref(pty);
+        sd_event_unref(event);
+}
+
+int main(int argc, char *argv[]) {
+        unsigned int i;
+
+        log_parse_environment();
+        log_open();
+
+        assert_se(sigprocmask_many(SIG_BLOCK, SIGCHLD, -1) >= 0);
+
+        /* Oh, there're ugly races in the TTY layer regarding HUP vs IN. Turns
+         * out they appear only 10% of the time. I fixed all of them and
+         * don't see them, anymore. But lets be safe and run this 1000 times
+         * so we catch any new ones, in case they appear again. */
+        for (i = 0; i < 1000; ++i)
+                test_pty();
+
+        return 0;
+}
diff --git a/src/test/test-ratelimit.c b/src/test/test-ratelimit.c
new file mode 100644 (file)
index 0000000..b7f6dfe
--- /dev/null
@@ -0,0 +1,49 @@
+/***
+  This file is part of systemd
+
+  Copyright 2014 Ronny Chevalier
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <unistd.h>
+
+#include "ratelimit.h"
+#include "time-util.h"
+#include "macro.h"
+
+static void test_ratelimit_test(void) {
+        int i;
+        RATELIMIT_DEFINE(ratelimit, 1 * USEC_PER_SEC, 10);
+
+        for (i = 0; i < 10; i++) {
+                assert_se(ratelimit_test(&ratelimit));
+        }
+        assert_se(!ratelimit_test(&ratelimit));
+        sleep(1);
+        for (i = 0; i < 10; i++) {
+                assert_se(ratelimit_test(&ratelimit));
+        }
+
+        RATELIMIT_INIT(ratelimit, 0, 10);
+        for (i = 0; i < 10000; i++) {
+                assert_se(ratelimit_test(&ratelimit));
+        }
+}
+
+int main(int argc, char *argv[]) {
+        test_ratelimit_test();
+
+        return 0;
+}
diff --git a/src/test/test-ring.c b/src/test/test-ring.c
new file mode 100644 (file)
index 0000000..5e4efdb
--- /dev/null
@@ -0,0 +1,135 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 David Herrmann <dh.herrmann@gmail.com>
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <locale.h>
+#include <errno.h>
+
+#include "def.h"
+#include "ring.h"
+#include "util.h"
+
+static void test_ring(void) {
+        static const char buf[8192];
+        Ring r;
+        size_t l;
+        struct iovec vec[2];
+        int s;
+
+        memset(&r, 0, sizeof(r));
+
+        l = ring_peek(&r, vec);
+        assert_se(l == 0);
+
+        s = ring_push(&r, buf, 2048);
+        assert_se(!s);
+        assert_se(ring_get_size(&r) == 2048);
+
+        l = ring_peek(&r, vec);
+        assert_se(l == 1);
+        assert_se(vec[0].iov_len == 2048);
+        assert_se(!memcmp(vec[0].iov_base, buf, vec[0].iov_len));
+        assert_se(ring_get_size(&r) == 2048);
+
+        ring_pull(&r, 2048);
+        assert_se(ring_get_size(&r) == 0);
+
+        l = ring_peek(&r, vec);
+        assert_se(l == 0);
+        assert_se(ring_get_size(&r) == 0);
+
+        s = ring_push(&r, buf, 2048);
+        assert_se(!s);
+        assert_se(ring_get_size(&r) == 2048);
+
+        l = ring_peek(&r, vec);
+        assert_se(l == 1);
+        assert_se(vec[0].iov_len == 2048);
+        assert_se(!memcmp(vec[0].iov_base, buf, vec[0].iov_len));
+        assert_se(ring_get_size(&r) == 2048);
+
+        s = ring_push(&r, buf, 1);
+        assert_se(!s);
+        assert_se(ring_get_size(&r) == 2049);
+
+        l = ring_peek(&r, vec);
+        assert_se(l == 2);
+        assert_se(vec[0].iov_len == 2048);
+        assert_se(vec[1].iov_len == 1);
+        assert_se(!memcmp(vec[0].iov_base, buf, vec[0].iov_len));
+        assert_se(!memcmp(vec[1].iov_base, buf, vec[1].iov_len));
+        assert_se(ring_get_size(&r) == 2049);
+
+        ring_pull(&r, 2048);
+        assert_se(ring_get_size(&r) == 1);
+
+        l = ring_peek(&r, vec);
+        assert_se(l == 1);
+        assert_se(vec[0].iov_len == 1);
+        assert_se(!memcmp(vec[0].iov_base, buf, vec[0].iov_len));
+        assert_se(ring_get_size(&r) == 1);
+
+        ring_pull(&r, 1);
+        assert_se(ring_get_size(&r) == 0);
+
+        s = ring_push(&r, buf, 2048);
+        assert_se(!s);
+        assert_se(ring_get_size(&r) == 2048);
+
+        s = ring_push(&r, buf, 2049);
+        assert_se(!s);
+        assert_se(ring_get_size(&r) == 4097);
+
+        l = ring_peek(&r, vec);
+        assert_se(l == 1);
+        assert_se(vec[0].iov_len == 4097);
+        assert_se(!memcmp(vec[0].iov_base, buf, vec[0].iov_len));
+        assert_se(ring_get_size(&r) == 4097);
+
+        ring_pull(&r, 1);
+        assert_se(ring_get_size(&r) == 4096);
+
+        s = ring_push(&r, buf, 4096);
+        assert_se(!s);
+        assert_se(ring_get_size(&r) == 8192);
+
+        l = ring_peek(&r, vec);
+        assert_se(l == 2);
+        assert_se(vec[0].iov_len == 8191);
+        assert_se(vec[1].iov_len == 1);
+        assert_se(!memcmp(vec[0].iov_base, buf, vec[0].iov_len));
+        assert_se(!memcmp(vec[1].iov_base, buf, vec[1].iov_len));
+        assert_se(ring_get_size(&r) == 8192);
+
+        ring_clear(&r);
+        assert_se(ring_get_size(&r) == 0);
+}
+
+int main(int argc, char *argv[]) {
+        log_parse_environment();
+        log_open();
+
+        test_ring();
+
+        return 0;
+}
diff --git a/src/test/test-rtnl-manual.c b/src/test/test-rtnl-manual.c
new file mode 100644 (file)
index 0000000..c8133db
--- /dev/null
@@ -0,0 +1,152 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Susant Sahani
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <netinet/ether.h>
+#include <arpa/inet.h>
+#include <net/if.h>
+#include <linux/ip.h>
+#include <linux/if_tunnel.h>
+#include <libkmod.h>
+
+#include "util.h"
+#include "macro.h"
+#include "sd-rtnl.h"
+#include "socket-util.h"
+#include "rtnl-util.h"
+#include "event-util.h"
+#include "rtnl-internal.h"
+
+static int load_module(const char *mod_name) {
+        struct kmod_ctx *ctx;
+        struct kmod_list *list = NULL, *l;
+        int r;
+
+        ctx = kmod_new(NULL, NULL);
+        if (!ctx) {
+                kmod_unref(ctx);
+                return -ENOMEM;
+        }
+
+        r = kmod_module_new_from_lookup(ctx, mod_name, &list);
+        if (r < 0)
+                return -1;
+
+        kmod_list_foreach(l, list) {
+                struct kmod_module *mod = kmod_module_get_module(l);
+
+                r = kmod_module_probe_insert_module(mod, 0, NULL, NULL, NULL, NULL);
+                if (r >= 0)
+                        r = 0;
+                else
+                        r = -1;
+
+                kmod_module_unref(mod);
+        }
+
+        kmod_module_unref_list(list);
+        kmod_unref(ctx);
+
+        return r;
+}
+
+static int test_tunnel_configure(sd_rtnl *rtnl) {
+        int r;
+        sd_rtnl_message *m, *n;
+        struct in_addr local, remote;
+
+        /* skip test if module cannot be loaded */
+        r = load_module("ipip");
+        if(r < 0)
+                return EXIT_TEST_SKIP;
+
+        if(getuid() != 0)
+                return EXIT_TEST_SKIP;
+
+        /* IPIP tunnel */
+        assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_NEWLINK, 0) >= 0);
+        assert_se(m);
+
+        assert_se(sd_rtnl_message_append_string(m, IFLA_IFNAME, "ipip-tunnel") >= 0);
+        assert_se(sd_rtnl_message_append_u32(m, IFLA_MTU, 1234)>= 0);
+
+        assert_se(sd_rtnl_message_open_container(m, IFLA_LINKINFO) >= 0);
+
+        assert_se(sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA, "ipip") >= 0);
+
+        inet_pton(AF_INET, "192.168.21.1", &local.s_addr);
+        assert_se(sd_rtnl_message_append_u32(m, IFLA_IPTUN_LOCAL, local.s_addr) >= 0);
+
+        inet_pton(AF_INET, "192.168.21.2", &remote.s_addr);
+        assert_se(sd_rtnl_message_append_u32(m, IFLA_IPTUN_REMOTE, remote.s_addr) >= 0);
+
+        assert_se(sd_rtnl_message_close_container(m) >= 0);
+        assert_se(sd_rtnl_message_close_container(m) >= 0);
+
+        assert_se(sd_rtnl_call(rtnl, m, -1, 0) == 1);
+
+        assert_se((m = sd_rtnl_message_unref(m)) == NULL);
+
+        r = load_module("sit");
+        if(r < 0)
+                return EXIT_TEST_SKIP;
+
+        /* sit */
+        assert_se(sd_rtnl_message_new_link(rtnl, &n, RTM_NEWLINK, 0) >= 0);
+        assert_se(n);
+
+        assert_se(sd_rtnl_message_append_string(n, IFLA_IFNAME, "sit-tunnel") >= 0);
+        assert_se(sd_rtnl_message_append_u32(n, IFLA_MTU, 1234)>= 0);
+
+        assert_se(sd_rtnl_message_open_container(n, IFLA_LINKINFO) >= 0);
+
+        assert_se(sd_rtnl_message_open_container_union(n, IFLA_INFO_DATA, "sit") >= 0);
+
+        assert_se(sd_rtnl_message_append_u8(n, IFLA_IPTUN_PROTO, IPPROTO_IPIP) >= 0);
+
+        inet_pton(AF_INET, "192.168.21.3", &local.s_addr);
+        assert_se(sd_rtnl_message_append_u32(n, IFLA_IPTUN_LOCAL, local.s_addr) >= 0);
+
+        inet_pton(AF_INET, "192.168.21.4", &remote.s_addr);
+        assert_se(sd_rtnl_message_append_u32(n, IFLA_IPTUN_REMOTE, remote.s_addr) >= 0);
+
+        assert_se(sd_rtnl_message_close_container(n) >= 0);
+        assert_se(sd_rtnl_message_close_container(n) >= 0);
+
+        assert_se(sd_rtnl_call(rtnl, n, -1, 0) == 1);
+
+        assert_se((m = sd_rtnl_message_unref(n)) == NULL);
+
+        return EXIT_SUCCESS;
+}
+
+int main(int argc, char *argv[]) {
+        sd_rtnl *rtnl;
+        int r;
+
+        assert_se(sd_rtnl_open(&rtnl, 0) >= 0);
+        assert_se(rtnl);
+
+        r = test_tunnel_configure(rtnl);
+
+        assert_se((rtnl = sd_rtnl_unref(rtnl)) == NULL);
+
+        return r;
+}
index e984ee4..8fdca0e 100644 (file)
@@ -31,11 +31,10 @@ int main(int argc, char *argv[]) {
         FILE *serial = NULL;
         FDSet *fdset = NULL;
         int r;
-        const char *dir = TEST_DIR;
 
         /* prepare the test */
-        assert_se(set_unit_path(dir) >= 0);
-        r = manager_new(SYSTEMD_USER, &m);
+        assert_se(set_unit_path(TEST_DIR) >= 0);
+        r = manager_new(SYSTEMD_USER, true, &m);
         if (r == -EPERM || r == -EACCES || r == -EADDRINUSE || r == -EHOSTDOWN) {
                 printf("Skipping test: manager_new: %s", strerror(-r));
                 return EXIT_TEST_SKIP;
diff --git a/src/test/test-socket-util.c b/src/test/test-socket-util.c
new file mode 100644 (file)
index 0000000..17180db
--- /dev/null
@@ -0,0 +1,333 @@
+/***
+  This file is part of systemd
+
+  Copyright 2014 Ronny Chevalier
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "socket-util.h"
+#include "in-addr-util.h"
+#include "util.h"
+#include "macro.h"
+#include "log.h"
+#include "async.h"
+
+static void test_socket_address_parse(void) {
+        SocketAddress a;
+
+        assert_se(socket_address_parse(&a, "junk") < 0);
+        assert_se(socket_address_parse(&a, "192.168.1.1") < 0);
+        assert_se(socket_address_parse(&a, ".168.1.1") < 0);
+        assert_se(socket_address_parse(&a, "989.168.1.1") < 0);
+        assert_se(socket_address_parse(&a, "192.168.1.1:65536") < 0);
+        assert_se(socket_address_parse(&a, "192.168.1.1:0") < 0);
+        assert_se(socket_address_parse(&a, "0") < 0);
+        assert_se(socket_address_parse(&a, "65536") < 0);
+
+        assert_se(socket_address_parse(&a, "65535") >= 0);
+
+        if (socket_ipv6_is_supported()) {
+                assert_se(socket_address_parse(&a, "[::1]") < 0);
+                assert_se(socket_address_parse(&a, "[::1]8888") < 0);
+                assert_se(socket_address_parse(&a, "::1") < 0);
+                assert_se(socket_address_parse(&a, "[::1]:0") < 0);
+                assert_se(socket_address_parse(&a, "[::1]:65536") < 0);
+                assert_se(socket_address_parse(&a, "[a:b:1]:8888") < 0);
+
+                assert_se(socket_address_parse(&a, "8888") >= 0);
+                assert_se(a.sockaddr.sa.sa_family == AF_INET6);
+
+                assert_se(socket_address_parse(&a, "[2001:0db8:0000:85a3:0000:0000:ac1f:8001]:8888") >= 0);
+                assert_se(a.sockaddr.sa.sa_family == AF_INET6);
+
+                assert_se(socket_address_parse(&a, "[::1]:8888") >= 0);
+                assert_se(a.sockaddr.sa.sa_family == AF_INET6);
+        } else {
+                assert_se(socket_address_parse(&a, "[::1]:8888") < 0);
+
+                assert_se(socket_address_parse(&a, "8888") >= 0);
+                assert_se(a.sockaddr.sa.sa_family == AF_INET);
+        }
+
+        assert_se(socket_address_parse(&a, "192.168.1.254:8888") >= 0);
+        assert_se(a.sockaddr.sa.sa_family == AF_INET);
+
+        assert_se(socket_address_parse(&a, "/foo/bar") >= 0);
+        assert_se(a.sockaddr.sa.sa_family == AF_UNIX);
+
+        assert_se(socket_address_parse(&a, "@abstract") >= 0);
+        assert_se(a.sockaddr.sa.sa_family == AF_UNIX);
+}
+
+static void test_socket_address_parse_netlink(void) {
+        SocketAddress a;
+
+        assert_se(socket_address_parse_netlink(&a, "junk") < 0);
+        assert_se(socket_address_parse_netlink(&a, "") < 0);
+
+        assert_se(socket_address_parse_netlink(&a, "route") >= 0);
+        assert_se(socket_address_parse_netlink(&a, "route 10") >= 0);
+        assert_se(a.sockaddr.sa.sa_family == AF_NETLINK);
+        assert_se(a.protocol == NETLINK_ROUTE);
+}
+
+static void test_socket_address_equal(void) {
+        SocketAddress a;
+        SocketAddress b;
+
+        assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0);
+        assert_se(socket_address_parse(&b, "192.168.1.1:888") >= 0);
+        assert_se(!socket_address_equal(&a, &b));
+
+        assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0);
+        assert_se(socket_address_parse(&b, "192.16.1.1:8888") >= 0);
+        assert_se(!socket_address_equal(&a, &b));
+
+        assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0);
+        assert_se(socket_address_parse(&b, "8888") >= 0);
+        assert_se(!socket_address_equal(&a, &b));
+
+        assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0);
+        assert_se(socket_address_parse(&b, "/foo/bar/") >= 0);
+        assert_se(!socket_address_equal(&a, &b));
+
+        assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0);
+        assert_se(socket_address_parse(&b, "192.168.1.1:8888") >= 0);
+        assert_se(socket_address_equal(&a, &b));
+
+        assert_se(socket_address_parse(&a, "/foo/bar") >= 0);
+        assert_se(socket_address_parse(&b, "/foo/bar") >= 0);
+        assert_se(socket_address_equal(&a, &b));
+
+        assert_se(socket_address_parse(&a, "[::1]:8888") >= 0);
+        assert_se(socket_address_parse(&b, "[::1]:8888") >= 0);
+        assert_se(socket_address_equal(&a, &b));
+
+        assert_se(socket_address_parse(&a, "@abstract") >= 0);
+        assert_se(socket_address_parse(&b, "@abstract") >= 0);
+        assert_se(socket_address_equal(&a, &b));
+
+        assert_se(socket_address_parse_netlink(&a, "firewall") >= 0);
+        assert_se(socket_address_parse_netlink(&b, "firewall") >= 0);
+        assert_se(socket_address_equal(&a, &b));
+}
+
+static void test_socket_address_get_path(void) {
+        SocketAddress a;
+
+        assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0);
+        assert_se(!socket_address_get_path(&a));
+
+        assert_se(socket_address_parse(&a, "@abstract") >= 0);
+        assert_se(!socket_address_get_path(&a));
+
+        assert_se(socket_address_parse(&a, "[::1]:8888") >= 0);
+        assert_se(!socket_address_get_path(&a));
+
+        assert_se(socket_address_parse(&a, "/foo/bar") >= 0);
+        assert_se(streq(socket_address_get_path(&a), "/foo/bar"));
+}
+
+static void test_socket_address_is(void) {
+        SocketAddress a;
+
+        assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0);
+        assert_se(socket_address_is(&a, "192.168.1.1:8888", SOCK_STREAM));
+        assert_se(!socket_address_is(&a, "route", SOCK_STREAM));
+        assert_se(!socket_address_is(&a, "192.168.1.1:8888", SOCK_RAW));
+}
+
+static void test_socket_address_is_netlink(void) {
+        SocketAddress a;
+
+        assert_se(socket_address_parse_netlink(&a, "route 10") >= 0);
+        assert_se(socket_address_is_netlink(&a, "route 10"));
+        assert_se(!socket_address_is_netlink(&a, "192.168.1.1:8888"));
+        assert_se(!socket_address_is_netlink(&a, "route 1"));
+}
+
+static void test_in_addr_prefix_intersect_one(unsigned f, const char *a, unsigned apl, const char *b, unsigned bpl, int result) {
+        union in_addr_union ua, ub;
+
+        assert_se(in_addr_from_string(f, a, &ua) >= 0);
+        assert_se(in_addr_from_string(f, b, &ub) >= 0);
+
+        assert_se(in_addr_prefix_intersect(f, &ua, apl, &ub, bpl) == result);
+}
+
+static void test_in_addr_prefix_intersect(void) {
+
+        test_in_addr_prefix_intersect_one(AF_INET, "255.255.255.255", 32, "255.255.255.254", 32, 0);
+        test_in_addr_prefix_intersect_one(AF_INET, "255.255.255.255", 0, "255.255.255.255", 32, 1);
+        test_in_addr_prefix_intersect_one(AF_INET, "0.0.0.0", 0, "47.11.8.15", 32, 1);
+
+        test_in_addr_prefix_intersect_one(AF_INET, "1.1.1.1", 24, "1.1.1.1", 24, 1);
+        test_in_addr_prefix_intersect_one(AF_INET, "2.2.2.2", 24, "1.1.1.1", 24, 0);
+
+        test_in_addr_prefix_intersect_one(AF_INET, "1.1.1.1", 24, "1.1.1.127", 25, 1);
+        test_in_addr_prefix_intersect_one(AF_INET, "1.1.1.1", 24, "1.1.1.127", 26, 1);
+        test_in_addr_prefix_intersect_one(AF_INET, "1.1.1.1", 25, "1.1.1.127", 25, 1);
+        test_in_addr_prefix_intersect_one(AF_INET, "1.1.1.1", 25, "1.1.1.255", 25, 0);
+
+        test_in_addr_prefix_intersect_one(AF_INET6, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 128, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe", 128, 0);
+        test_in_addr_prefix_intersect_one(AF_INET6, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 0, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 128, 1);
+        test_in_addr_prefix_intersect_one(AF_INET6, "::", 0, "beef:beef:beef:beef:beef:beef:beef:beef", 128, 1);
+
+        test_in_addr_prefix_intersect_one(AF_INET6, "1::2", 64, "1::2", 64, 1);
+        test_in_addr_prefix_intersect_one(AF_INET6, "2::2", 64, "1::2", 64, 0);
+
+        test_in_addr_prefix_intersect_one(AF_INET6, "1::1", 120, "1::007f", 121, 1);
+        test_in_addr_prefix_intersect_one(AF_INET6, "1::1", 120, "1::007f", 122, 1);
+        test_in_addr_prefix_intersect_one(AF_INET6, "1::1", 121, "1::007f", 121, 1);
+        test_in_addr_prefix_intersect_one(AF_INET6, "1::1", 121, "1::00ff", 121, 0);
+}
+
+static void test_in_addr_prefix_next_one(unsigned f, const char *before, unsigned pl, const char *after) {
+        union in_addr_union ubefore, uafter, t;
+
+        assert_se(in_addr_from_string(f, before, &ubefore) >= 0);
+
+        t = ubefore;
+        assert_se((in_addr_prefix_next(f, &t, pl) > 0) == !!after);
+
+        if (after) {
+                assert_se(in_addr_from_string(f, after, &uafter) >= 0);
+                assert_se(in_addr_equal(f, &t, &uafter) > 0);
+        }
+}
+
+static void test_in_addr_prefix_next(void) {
+
+        test_in_addr_prefix_next_one(AF_INET, "192.168.0.0", 24, "192.168.1.0");
+        test_in_addr_prefix_next_one(AF_INET, "192.168.0.0", 16, "192.169.0.0");
+        test_in_addr_prefix_next_one(AF_INET, "192.168.0.0", 20, "192.168.16.0");
+
+        test_in_addr_prefix_next_one(AF_INET, "0.0.0.0", 32, "0.0.0.1");
+        test_in_addr_prefix_next_one(AF_INET, "255.255.255.255", 32, NULL);
+        test_in_addr_prefix_next_one(AF_INET, "255.255.255.0", 24, NULL);
+
+        test_in_addr_prefix_next_one(AF_INET6, "4400::", 128, "4400::0001");
+        test_in_addr_prefix_next_one(AF_INET6, "4400::", 120, "4400::0100");
+        test_in_addr_prefix_next_one(AF_INET6, "4400::", 127, "4400::0002");
+        test_in_addr_prefix_next_one(AF_INET6, "4400::", 8, "4500::");
+        test_in_addr_prefix_next_one(AF_INET6, "4400::", 7, "4600::");
+
+        test_in_addr_prefix_next_one(AF_INET6, "::", 128, "::1");
+
+        test_in_addr_prefix_next_one(AF_INET6, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 128, NULL);
+        test_in_addr_prefix_next_one(AF_INET6, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00", 120, NULL);
+
+}
+
+static void *connect_thread(void *arg) {
+        union sockaddr_union *sa = arg;
+        _cleanup_close_ int fd = -1;
+
+        fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
+        assert(fd >= 0);
+
+        assert_se(connect(fd, &sa->sa, sizeof(sa->in)) == 0);
+
+        return NULL;
+}
+
+static void test_nameinfo_pretty(void) {
+        _cleanup_free_ char *stdin_name = NULL, *localhost = NULL;
+
+        union sockaddr_union s = {
+                .in.sin_family = AF_INET,
+                .in.sin_port = 0,
+                .in.sin_addr.s_addr = htonl(INADDR_ANY),
+        };
+        int r;
+
+        union sockaddr_union c = {};
+        socklen_t slen = sizeof(c.in), clen = sizeof(c.in);
+
+        _cleanup_close_ int sfd = -1, cfd = -1;
+        r = getnameinfo_pretty(STDIN_FILENO, &stdin_name);
+        log_info("No connection remote: %s", strerror(-r));
+
+        assert_se(r < 0);
+
+        sfd = socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC, 0);
+        assert(sfd >= 0);
+
+        assert_se(bind(sfd, &s.sa, sizeof(s.in)) == 0);
+
+        /* find out the port number */
+        assert_se(getsockname(sfd, &s.sa, &slen) == 0);
+
+        assert_se(listen(sfd, 1) == 0);
+
+        assert_se(asynchronous_job(connect_thread, &s) == 0);
+
+        log_debug("Accepting new connection on fd:%d", sfd);
+        cfd = accept4(sfd, &c.sa, &clen, SOCK_CLOEXEC);
+        assert(cfd >= 0);
+
+        r = getnameinfo_pretty(cfd, &localhost);
+        log_info("Connection from %s", localhost);
+        assert(r == 0);
+}
+
+static void test_sockaddr_equal(void) {
+        union sockaddr_union a = {
+                .in.sin_family = AF_INET,
+                .in.sin_port = 0,
+                .in.sin_addr.s_addr = htonl(INADDR_ANY),
+        };
+        union sockaddr_union b = {
+                .in.sin_family = AF_INET,
+                .in.sin_port = 0,
+                .in.sin_addr.s_addr = htonl(INADDR_ANY),
+        };
+        union sockaddr_union c = {
+                .in.sin_family = AF_INET,
+                .in.sin_port = 0,
+                .in.sin_addr.s_addr = htonl(1234),
+        };
+        union sockaddr_union d = {
+                .in6.sin6_family = AF_INET6,
+                .in6.sin6_port = 0,
+                .in6.sin6_addr = IN6ADDR_ANY_INIT,
+        };
+        assert_se(sockaddr_equal(&a, &a));
+        assert_se(sockaddr_equal(&a, &b));
+        assert_se(sockaddr_equal(&d, &d));
+        assert_se(!sockaddr_equal(&a, &c));
+        assert_se(!sockaddr_equal(&b, &c));
+}
+
+int main(int argc, char *argv[]) {
+
+        log_set_max_level(LOG_DEBUG);
+
+        test_socket_address_parse();
+        test_socket_address_parse_netlink();
+        test_socket_address_equal();
+        test_socket_address_get_path();
+        test_socket_address_is();
+        test_socket_address_is_netlink();
+
+        test_in_addr_prefix_intersect();
+        test_in_addr_prefix_next();
+
+        test_nameinfo_pretty();
+
+        test_sockaddr_equal();
+
+        return 0;
+}
index c8c5fc9..00e127f 100644 (file)
@@ -141,6 +141,7 @@ static void test_strv_quote_unquote(const char* const *split, const char *quoted
         _cleanup_free_ char *p;
         _cleanup_strv_free_ char **s;
         char **t;
+        int r;
 
         p = strv_join_quoted((char **)split);
         assert_se(p);
@@ -148,7 +149,8 @@ static void test_strv_quote_unquote(const char* const *split, const char *quoted
         assert_se(p);
         assert_se(streq(p, quoted));
 
-        s = strv_split_quoted(quoted);
+        r = strv_split_quoted(&s, quoted);
+        assert_se(r == 0);
         assert_se(s);
         STRV_FOREACH(t, s) {
                 assert_se(*t);
@@ -157,13 +159,19 @@ static void test_strv_quote_unquote(const char* const *split, const char *quoted
         }
 }
 
-static void test_strv_quote_unquote2(const char *quoted, const char ** list) {
+static void test_strv_unquote(const char *quoted, const char **list) {
         _cleanup_strv_free_ char **s;
+        _cleanup_free_ char *j;
         unsigned i = 0;
         char **t;
+        int r;
 
-        s = strv_split_quoted(quoted);
+        r = strv_split_quoted(&s, quoted);
+        assert_se(r == 0);
         assert_se(s);
+        j = strv_join(s, " | ");
+        assert(j);
+        puts(j);
 
         STRV_FOREACH(t, s)
                 assert_se(streq(list[i++], *t));
@@ -171,6 +179,15 @@ static void test_strv_quote_unquote2(const char *quoted, const char ** list) {
         assert_se(list[i] == NULL);
 }
 
+static void test_invalid_unquote(const char *quoted) {
+        char **s = NULL;
+        int r;
+
+        r = strv_split_quoted(&s, quoted);
+        assert(s == NULL);
+        assert(r == -EINVAL);
+}
+
 static void test_strv_split(void) {
         char **s;
         unsigned i = 0;
@@ -323,6 +340,20 @@ static void test_strv_extend(void) {
         assert_se(streq(b[0], "test3"));
 }
 
+static void test_strv_extendf(void) {
+        _cleanup_strv_free_ char **a = NULL, **b = NULL;
+
+        a = strv_new("test", "test1", NULL);
+        assert_se(a);
+        assert_se(strv_extendf(&a, "test2 %s %d %s", "foo", 128, "bar") >= 0);
+        assert_se(strv_extendf(&b, "test3 %s %s %d", "bar", "foo", 128) >= 0);
+
+        assert_se(streq(a[0], "test"));
+        assert_se(streq(a[1], "test1"));
+        assert_se(streq(a[2], "test2 foo 128 bar"));
+        assert_se(streq(b[0], "test3 bar foo 128"));
+}
+
 static void test_strv_foreach(void) {
         _cleanup_strv_free_ char **a;
         unsigned i = 0;
@@ -385,6 +416,23 @@ static void test_strv_from_stdarg_alloca(void) {
         test_strv_from_stdarg_alloca_one(STRV_MAKE_EMPTY, NULL);
 }
 
+static void test_strv_push(void) {
+        _cleanup_strv_free_ char **a = NULL;
+        char *i, *j;
+
+        assert_se(i = strdup("foo"));
+        assert_se(strv_push(&a, i) >= 0);
+
+        assert_se(i = strdup("a"));
+        assert_se(j = strdup("b"));
+        assert_se(strv_push_pair(&a, i, j) >= 0);
+
+        assert_se(streq_ptr(a[0], "foo"));
+        assert_se(streq_ptr(a[1], "a"));
+        assert_se(streq_ptr(a[2], "b"));
+        assert_se(streq_ptr(a[3], NULL));
+}
+
 int main(int argc, char *argv[]) {
         test_specifier_printf();
         test_strv_foreach();
@@ -400,17 +448,25 @@ int main(int argc, char *argv[]) {
         test_strv_quote_unquote(input_table_quotes, QUOTES_STRING);
         test_strv_quote_unquote(input_table_spaces, SPACES_STRING);
 
-        test_strv_quote_unquote2("    foo=bar     \"waldo\"    zzz    ", (const char*[]) { "foo=bar", "waldo", "zzz", NULL });
-        test_strv_quote_unquote2("", (const char*[]) { NULL });
-        test_strv_quote_unquote2(" ", (const char*[]) { NULL });
-        test_strv_quote_unquote2("   ", (const char*[]) { NULL });
-        test_strv_quote_unquote2("   x", (const char*[]) { "x", NULL });
-        test_strv_quote_unquote2("x   ", (const char*[]) { "x", NULL });
-        test_strv_quote_unquote2("  x   ", (const char*[]) { "x", NULL });
-        test_strv_quote_unquote2("  \"x\"   ", (const char*[]) { "x", NULL });
-        test_strv_quote_unquote2("  \'x\'   ", (const char*[]) { "x", NULL });
-        test_strv_quote_unquote2("  \'x\"\'   ", (const char*[]) { "x\"", NULL });
-        test_strv_quote_unquote2("  \"x\'\"   ", (const char*[]) { "x\'", NULL });
+        test_strv_unquote("    foo=bar     \"waldo\"    zzz    ", (const char*[]) { "foo=bar", "waldo", "zzz", NULL });
+        test_strv_unquote("", (const char*[]) { NULL });
+        test_strv_unquote(" ", (const char*[]) { NULL });
+        test_strv_unquote("   ", (const char*[]) { NULL });
+        test_strv_unquote("   x", (const char*[]) { "x", NULL });
+        test_strv_unquote("x   ", (const char*[]) { "x", NULL });
+        test_strv_unquote("  x   ", (const char*[]) { "x", NULL });
+        test_strv_unquote("  \"x\"   ", (const char*[]) { "x", NULL });
+        test_strv_unquote("  'x'   ", (const char*[]) { "x", NULL });
+        test_strv_unquote("  'x\"'   ", (const char*[]) { "x\"", NULL });
+        test_strv_unquote("  \"x'\"   ", (const char*[]) { "x'", NULL });
+        test_strv_unquote("a  '--b=c \"d e\"'", (const char*[]) { "a", "--b=c \"d e\"", NULL });
+
+        test_invalid_unquote("a  --b='c \"d e\"'");
+        test_invalid_unquote("a  --b='c \"d e\" '");
+        test_invalid_unquote("a  --b='c \"d e\"garbage");
+        test_invalid_unquote("'");
+        test_invalid_unquote("\"");
+        test_invalid_unquote("'x'y");
 
         test_strv_split();
         test_strv_split_newlines();
@@ -421,7 +477,9 @@ int main(int argc, char *argv[]) {
         test_strv_extend_strv();
         test_strv_extend_strv_concat();
         test_strv_extend();
+        test_strv_extendf();
         test_strv_from_stdarg_alloca();
+        test_strv_push();
 
         return 0;
 }
index dff6431..88e7d10 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "automount.h"
 #include "cgroup.h"
+#include "compress.h"
 #include "condition.h"
 #include "device.h"
 #include "execute.h"
 #include "unit-name.h"
 #include "unit.h"
 #include "util.h"
+#include "architecture.h"
+#include "link-config.h"
+#include "bus-policy.h"
+#include "journald-server.h"
 
 #include "test-tables.h"
 
 int main(int argc, char **argv) {
+        test_table(architecture, ARCHITECTURE);
         test_table(automount_result, AUTOMOUNT_RESULT);
         test_table(automount_state, AUTOMOUNT_STATE);
+        test_table(busname_policy_access, BUSNAME_POLICY_ACCESS);
+        test_table(busname_result, BUSNAME_RESULT);
+        test_table(busname_state, BUSNAME_STATE);
         test_table(cgroup_device_policy, CGROUP_DEVICE_POLICY);
         test_table(condition_type, CONDITION_TYPE);
         test_table(device_state, DEVICE_STATE);
         test_table(exec_input, EXEC_INPUT);
         test_table(exec_output, EXEC_OUTPUT);
+        test_table(failure_action, SERVICE_FAILURE_ACTION);
         test_table(job_mode, JOB_MODE);
         test_table(job_result, JOB_RESULT);
         test_table(job_state, JOB_STATE);
@@ -61,14 +71,22 @@ int main(int argc, char **argv) {
         test_table(kill_mode, KILL_MODE);
         test_table(kill_who, KILL_WHO);
         test_table(log_target, LOG_TARGET);
+        test_table(mac_policy, MACPOLICY);
+        test_table(manager_state, MANAGER_STATE);
         test_table(mount_exec_command, MOUNT_EXEC_COMMAND);
         test_table(mount_result, MOUNT_RESULT);
         test_table(mount_state, MOUNT_STATE);
+        test_table(name_policy, NAMEPOLICY);
         test_table(notify_access, NOTIFY_ACCESS);
         test_table(output_mode, OUTPUT_MODE);
         test_table(path_result, PATH_RESULT);
         test_table(path_state, PATH_STATE);
         test_table(path_type, PATH_TYPE);
+        test_table(policy_item_class, POLICY_ITEM_CLASS);
+        test_table(policy_item_type, POLICY_ITEM_TYPE);
+        test_table(protect_home, PROTECT_HOME);
+        test_table(protect_system, PROTECT_SYSTEM);
+        test_table(rlimit, RLIMIT);
         test_table(scope_result, SCOPE_RESULT);
         test_table(scope_state, SCOPE_STATE);
         test_table(service_exec_command, SERVICE_EXEC_COMMAND);
@@ -82,11 +100,11 @@ int main(int argc, char **argv) {
         test_table(socket_exec_command, SOCKET_EXEC_COMMAND);
         test_table(socket_result, SOCKET_RESULT);
         test_table(socket_state, SOCKET_STATE);
-        test_table(start_limit_action, SERVICE_START_LIMIT);
+        test_table(split_mode, SPLIT);
+        test_table(storage, STORAGE);
         test_table(swap_exec_command, SWAP_EXEC_COMMAND);
         test_table(swap_result, SWAP_RESULT);
         test_table(swap_state, SWAP_STATE);
-        test_table(systemd_running_as, SYSTEMD_RUNNING_AS);
         test_table(target_state, TARGET_STATE);
         test_table(timer_base, TIMER_BASE);
         test_table(timer_result, TIMER_RESULT);
@@ -94,9 +112,12 @@ int main(int argc, char **argv) {
         test_table(unit_active_state, UNIT_ACTIVE_STATE);
         test_table(unit_dependency, UNIT_DEPENDENCY);
         test_table(unit_file_change_type, UNIT_FILE_CHANGE_TYPE);
+        test_table(unit_file_preset_mode, UNIT_FILE_PRESET);
         test_table(unit_file_state, UNIT_FILE_STATE);
         test_table(unit_load_state, UNIT_LOAD_STATE);
         test_table(unit_type, UNIT_TYPE);
 
+        test_table_sparse(object_compressed, OBJECT_COMPRESSED);
+
         return EXIT_SUCCESS;
 }
index 36a3304..87e7ae7 100644 (file)
@@ -20,6 +20,7 @@
 ***/
 
 #include "time-util.h"
+#include "strv.h"
 
 static void test_parse_sec(void) {
         usec_t u;
@@ -84,7 +85,7 @@ static void test_format_timespan_one(usec_t x, usec_t accuracy) {
         char l[FORMAT_TIMESPAN_MAX];
         usec_t y;
 
-        log_info("%llu     (at accuracy %llu)", (unsigned long long) x, (unsigned long long) accuracy);
+        log_info(USEC_FMT"     (at accuracy "USEC_FMT")", x, accuracy);
 
         r = format_timespan(l, sizeof(l), x, accuracy);
         assert_se(r);
@@ -93,7 +94,7 @@ static void test_format_timespan_one(usec_t x, usec_t accuracy) {
 
         assert_se(parse_sec(l, &y) >= 0);
 
-        log_info(" = %llu", (unsigned long long) y);
+        log_info(" = "USEC_FMT, y);
 
         if (accuracy <= 0)
                 accuracy = 1;
@@ -126,11 +127,33 @@ static void test_format_timespan(usec_t accuracy) {
         test_format_timespan_one(9*USEC_PER_YEAR/5 - 23, accuracy);
 }
 
+static void test_timezone_is_valid(void) {
+        assert_se(timezone_is_valid("Europe/Berlin"));
+        assert_se(timezone_is_valid("Australia/Sydney"));
+        assert_se(!timezone_is_valid("Europe/Do not exist"));
+}
+
+static void test_get_timezones(void) {
+        _cleanup_strv_free_ char **zones = NULL;
+        int r;
+        char **zone;
+
+        r = get_timezones(&zones);
+        assert_se(r == 0);
+
+        STRV_FOREACH(zone, zones) {
+                assert_se(timezone_is_valid(*zone));
+        }
+}
+
 int main(int argc, char *argv[]) {
         test_parse_sec();
         test_parse_nsec();
         test_format_timespan(1);
         test_format_timespan(USEC_PER_MSEC);
         test_format_timespan(USEC_PER_SEC);
+        test_timezone_is_valid();
+        test_get_timezones();
+
         return 0;
 }
index b064744..566a73a 100644 (file)
@@ -26,7 +26,6 @@
 #include <ctype.h>
 #include <errno.h>
 #include <unistd.h>
-#include <syslog.h>
 #include <grp.h>
 #include <sched.h>
 #include <sys/mount.h>
@@ -80,7 +79,6 @@ out:
         return err;
 }
 
-
 int main(int argc, char *argv[]) {
         _cleanup_udev_unref_ struct udev *udev = NULL;
         _cleanup_udev_event_unref_ struct udev_event *event = NULL;
@@ -155,9 +153,8 @@ int main(int argc, char *argv[]) {
                 }
         }
 
-        err = udev_event_execute_rules(event, rules, &sigmask_orig);
-        if (err == 0)
-                udev_event_execute_run(event, NULL);
+        udev_event_execute_rules(event, USEC_PER_SEC, rules, &sigmask_orig);
+        udev_event_execute_run(event, USEC_PER_SEC, NULL);
 out:
         if (event != NULL && event->fd_signal >= 0)
                 close(event->fd_signal);
diff --git a/src/test/test-uid-range.c b/src/test/test-uid-range.c
new file mode 100644 (file)
index 0000000..5f3d871
--- /dev/null
@@ -0,0 +1,91 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stddef.h>
+
+#include "util.h"
+#include "uid-range.h"
+
+int main(int argc, char *argv[]) {
+        _cleanup_free_ UidRange *p = NULL;
+        unsigned n = 0;
+        uid_t search;
+
+        assert_se(uid_range_add_str(&p, &n, "500-999") >= 0);
+        assert_se(n == 1);
+        assert_se(p[0].start == 500);
+        assert_se(p[0].nr = 500);
+
+        assert_se(!uid_range_contains(p, n, 499));
+        assert_se(uid_range_contains(p, n, 500));
+        assert_se(uid_range_contains(p, n, 999));
+        assert_se(!uid_range_contains(p, n, 1000));
+
+        search = (uid_t) -1;
+        assert_se(uid_range_next_lower(p, n, &search));
+        assert_se(search == 999);
+        assert_se(uid_range_next_lower(p, n, &search));
+        assert_se(search == 998);
+        search = 501;
+        assert_se(uid_range_next_lower(p, n, &search));
+        assert_se(search == 500);
+        assert_se(uid_range_next_lower(p, n, &search) == -EBUSY);
+
+        assert_se(uid_range_add_str(&p, &n, "1000") >= 0);
+        assert_se(n == 1);
+        assert_se(p[0].start == 500);
+        assert_se(p[0].nr = 501);
+
+        assert_se(uid_range_add_str(&p, &n, "30-40") >= 0);
+        assert_se(n == 2);
+        assert_se(p[0].start == 30);
+        assert_se(p[0].nr = 11);
+        assert_se(p[1].start == 500);
+        assert_se(p[1].nr = 501);
+
+        assert_se(uid_range_add_str(&p, &n, "60-70") >= 0);
+        assert_se(n == 3);
+        assert_se(p[0].start == 30);
+        assert_se(p[0].nr = 11);
+        assert_se(p[1].start == 60);
+        assert_se(p[1].nr = 11);
+        assert_se(p[2].start == 500);
+        assert_se(p[2].nr = 501);
+
+        assert_se(uid_range_add_str(&p, &n, "20-2000") >= 0);
+        assert_se(n == 1);
+        assert_se(p[0].start == 20);
+        assert_se(p[0].nr = 1981);
+
+        assert_se(uid_range_add_str(&p, &n, "2002") >= 0);
+        assert_se(n == 2);
+        assert_se(p[0].start == 20);
+        assert_se(p[0].nr = 1981);
+        assert_se(p[1].start == 2002);
+        assert_se(p[1].nr = 1);
+
+        assert_se(uid_range_add_str(&p, &n, "2001") >= 0);
+        assert_se(n == 1);
+        assert_se(p[0].start == 20);
+        assert_se(p[0].nr = 1983);
+
+        return 0;
+}
index 63a8a7d..3486572 100644 (file)
@@ -48,6 +48,12 @@ static int test_unit_file_get_set(void) {
         assert(h);
 
         r = unit_file_get_list(UNIT_FILE_SYSTEM, NULL, h);
+
+        if (r == -EPERM || r == -EACCES) {
+                printf("Skipping test: unit_file_get_list: %s", strerror(-r));
+                return EXIT_TEST_SKIP;
+        }
+
         log_full(r == 0 ? LOG_INFO : LOG_ERR,
                  "unit_file_get_list: %s", strerror(-r));
         if (r < 0)
@@ -228,7 +234,7 @@ static void test_load_env_file_1(void) {
         assert(fd >= 0);
         assert_se(write(fd, env_file_1, sizeof(env_file_1)) == sizeof(env_file_1));
 
-        r = load_env_file(name, NULL, &data);
+        r = load_env_file(NULL, name, NULL, &data);
         assert(r == 0);
         assert(streq(data[0], "a=a"));
         assert(streq(data[1], "b=bc"));
@@ -251,7 +257,7 @@ static void test_load_env_file_2(void) {
         assert(fd >= 0);
         assert_se(write(fd, env_file_2, sizeof(env_file_2)) == sizeof(env_file_2));
 
-        r = load_env_file(name, NULL, &data);
+        r = load_env_file(NULL, name, NULL, &data);
         assert(r == 0);
         assert(streq(data[0], "a=a"));
         assert(data[1] == NULL);
@@ -269,7 +275,7 @@ static void test_load_env_file_3(void) {
         assert(fd >= 0);
         assert_se(write(fd, env_file_3, sizeof(env_file_3)) == sizeof(env_file_3));
 
-        r = load_env_file(name, NULL, &data);
+        r = load_env_file(NULL, name, NULL, &data);
         assert(r == 0);
         assert(data == NULL);
         unlink(name);
@@ -285,7 +291,7 @@ static void test_load_env_file_4(void) {
         assert(fd >= 0);
         assert_se(write(fd, env_file_4, sizeof(env_file_4)) == sizeof(env_file_4));
 
-        r = load_env_file(name, NULL, &data);
+        r = load_env_file(NULL, name, NULL, &data);
         assert(r == 0);
         assert(streq(data[0], "HWMON_MODULES=coretemp f71882fg"));
         assert(streq(data[1], "MODULE_0=coretemp"));
index fff3e16..b733173 100644 (file)
@@ -5,6 +5,7 @@
 
   Copyright 2012 Lennart Poettering
   Copyright 2013 Zbigniew Jędrzejewski-Szmek
+  Copyright 2014 Ronny Chevalier
 
   systemd is free software; you can redistribute it and/or modify it
   under the terms of the GNU Lesser General Public License as published by
@@ -124,7 +125,7 @@ static int test_unit_printf(void) {
         assert_se((root = getpwnam("root")));
         assert_se(asprintf(&root_uid, "%d", (int) root->pw_uid) > 0);
 
-        r = manager_new(SYSTEMD_USER, &m);
+        r = manager_new(SYSTEMD_USER, true, &m);
         if (r == -EPERM || r == -EACCES || r == -EADDRINUSE) {
                 puts("manager_new: Permission denied. Skipping test.");
                 return EXIT_TEST_SKIP;
@@ -145,6 +146,7 @@ static int test_unit_printf(void) {
 
         assert_se(setenv("USER", "root", 1) == 0);
         assert_se(setenv("HOME", "/root", 1) == 0);
+        assert_se(setenv("XDG_RUNTIME_DIR", "/run/user/1/", 1) == 0);
 
         assert_se(u = unit_new(m, sizeof(Service)));
         assert_se(unit_add_name(u, "blah.service") == 0);
@@ -193,9 +195,135 @@ static int test_unit_printf(void) {
         return 0;
 }
 
+static void test_unit_instance_is_valid(void) {
+        assert_se(unit_instance_is_valid("fooBar"));
+        assert_se(unit_instance_is_valid("foo-bar"));
+        assert_se(unit_instance_is_valid("foo.stUff"));
+        assert_se(unit_instance_is_valid("fOo123.stuff"));
+        assert_se(unit_instance_is_valid("@f_oo123.Stuff"));
+
+        assert_se(!unit_instance_is_valid("$¢£"));
+        assert_se(!unit_instance_is_valid(""));
+        assert_se(!unit_instance_is_valid("foo bar"));
+        assert_se(!unit_instance_is_valid("foo/bar"));
+}
+
+static void test_unit_prefix_is_valid(void) {
+        assert_se(unit_prefix_is_valid("fooBar"));
+        assert_se(unit_prefix_is_valid("foo-bar"));
+        assert_se(unit_prefix_is_valid("foo.stUff"));
+        assert_se(unit_prefix_is_valid("fOo123.stuff"));
+        assert_se(unit_prefix_is_valid("foo123.Stuff"));
+
+        assert_se(!unit_prefix_is_valid("$¢£"));
+        assert_se(!unit_prefix_is_valid(""));
+        assert_se(!unit_prefix_is_valid("foo bar"));
+        assert_se(!unit_prefix_is_valid("foo/bar"));
+        assert_se(!unit_prefix_is_valid("@foo-bar"));
+}
+
+static void test_unit_name_change_suffix(void) {
+        char *r;
+
+        r = unit_name_change_suffix("foo.bar", ".service");
+        assert_se(r);
+        assert_se(streq(r, "foo.service"));
+        free(r);
+
+        r = unit_name_change_suffix("foo@stuff.bar", ".boo");
+        assert_se(r);
+        assert_se(streq(r, "foo@stuff.boo"));
+        free(r);
+}
+
+static void test_unit_name_build(void) {
+        char *r;
+
+        r = unit_name_build("foo", "bar", ".service");
+        assert_se(r);
+        assert_se(streq(r, "foo@bar.service"));
+        free(r);
+
+        r = unit_name_build("fo0-stUff_b", "bar", ".mount");
+        assert_se(r);
+        assert_se(streq(r, "fo0-stUff_b@bar.mount"));
+        free(r);
+
+        r = unit_name_build("foo", NULL, ".service");
+        assert_se(r);
+        assert_se(streq(r, "foo.service"));
+        free(r);
+}
+
+static void test_unit_name_is_instance(void) {
+        assert_se(unit_name_is_instance("a@b.service"));
+        assert_se(unit_name_is_instance("a-c_c01Aj@b05Dii_-oioi.service"));
+
+        assert_se(!unit_name_is_instance("a.service"));
+        assert_se(!unit_name_is_instance("junk"));
+        assert_se(!unit_name_is_instance(""));
+}
+
+static void test_build_subslice(void) {
+        char *a;
+        char *b;
+
+        assert_se(build_subslice("-.slice", "foo", &a) >= 0);
+        assert_se(build_subslice(a, "bar", &b) >= 0);
+        free(a);
+        assert_se(build_subslice(b, "barfoo", &a) >= 0);
+        free(b);
+        assert_se(build_subslice(a, "foobar", &b) >= 0);
+        free(a);
+        assert_se(streq(b, "foo-bar-barfoo-foobar.slice"));
+        free(b);
+
+        assert_se(build_subslice("foo.service", "bar", &a) < 0);
+        assert_se(build_subslice("foo", "bar", &a) < 0);
+}
+
+static void test_unit_name_to_instance(void) {
+        char *instance;
+        int r;
+
+        r = unit_name_to_instance("foo@bar.service", &instance);
+        assert_se(r >= 0);
+        assert_se(streq(instance, "bar"));
+        free(instance);
+
+        r = unit_name_to_instance("fo0-stUff_b@b.e", &instance);
+        assert_se(r >= 0);
+        assert_se(streq(instance, "b"));
+        free(instance);
+
+        r = unit_name_to_instance("foo.bar", &instance);
+        assert_se(r >= 0);
+        assert_se(!instance);
+
+        r = unit_name_to_instance("fooj@unk", &instance);
+        assert_se(r < 0);
+}
+
+static void test_unit_name_escape(void) {
+        _cleanup_free_ char *r;
+
+        r = unit_name_escape("ab+-c.a/bc@foo.service");
+        assert_se(r);
+        assert_se(streq(r, "ab\\x2b\\x2dc.a-bc\\x40foo.service"));
+}
+
 int main(int argc, char* argv[]) {
         int rc = 0;
         test_replacements();
         TEST_REQ_RUNNING_SYSTEMD(rc = test_unit_printf());
+        test_unit_instance_is_valid();
+        test_unit_prefix_is_valid();
+        test_unit_name_change_suffix();
+        test_unit_name_build();
+        test_unit_name_is_instance();
+        test_build_subslice();
+        test_unit_name_to_instance();
+        test_unit_name_escape();
+
         return rc;
 }
index b718206..ac1afce 100644 (file)
 #include <fcntl.h>
 #include <locale.h>
 #include <errno.h>
+#include <signal.h>
+#include <math.h>
+#include <sys/wait.h>
 
 #include "util.h"
+#include "mkdir.h"
 #include "strv.h"
 #include "def.h"
 #include "fileio.h"
+#include "conf-parser.h"
 
 static void test_streq_ptr(void) {
         assert_se(streq_ptr(NULL, NULL));
         assert_se(!streq_ptr("abc", "cdef"));
 }
 
+static void test_align_power2(void) {
+        unsigned long i, p2;
+
+        assert_se(ALIGN_POWER2(0) == 0);
+        assert_se(ALIGN_POWER2(1) == 1);
+        assert_se(ALIGN_POWER2(2) == 2);
+        assert_se(ALIGN_POWER2(3) == 4);
+        assert_se(ALIGN_POWER2(12) == 16);
+
+        assert_se(ALIGN_POWER2(ULONG_MAX) == 0);
+        assert_se(ALIGN_POWER2(ULONG_MAX - 1) == 0);
+        assert_se(ALIGN_POWER2(ULONG_MAX - 1024) == 0);
+        assert_se(ALIGN_POWER2(ULONG_MAX / 2) == ULONG_MAX / 2 + 1);
+        assert_se(ALIGN_POWER2(ULONG_MAX + 1) == 0);
+
+        for (i = 1; i < 131071; ++i) {
+                for (p2 = 1; p2 < i; p2 <<= 1)
+                        /* empty */ ;
+
+                assert_se(ALIGN_POWER2(i) == p2);
+        }
+
+        for (i = ULONG_MAX - 1024; i < ULONG_MAX; ++i) {
+                for (p2 = 1; p2 && p2 < i; p2 <<= 1)
+                        /* empty */ ;
+
+                assert_se(ALIGN_POWER2(i) == p2);
+        }
+}
+
+static void test_max(void) {
+        static const struct {
+                int a;
+                int b[CONST_MAX(10, 100)];
+        } val1 = {
+                .a = CONST_MAX(10, 100),
+        };
+        int d = 0;
+
+        assert_cc(sizeof(val1.b) == sizeof(int) * 100);
+
+        /* CONST_MAX returns (void) instead of a value if the passed arguments
+         * are not of the same type or not constant expressions. */
+        assert_cc(__builtin_types_compatible_p(typeof(CONST_MAX(1, 10)), int));
+        assert_cc(__builtin_types_compatible_p(typeof(CONST_MAX(1, 1U)), void));
+
+        assert_se(val1.a == 100);
+        assert_se(MAX(++d, 0) == 1);
+        assert_se(d == 1);
+}
+
 static void test_first_word(void) {
         assert_se(first_word("Hello", ""));
         assert_se(first_word("Hello", "Hello"));
@@ -66,7 +122,7 @@ static void test_close_many(void) {
         assert_se(fcntl(fds[1], F_GETFD) == -1);
         assert_se(fcntl(fds[2], F_GETFD) >= 0);
 
-        close_nointr_nofail(fds[2]);
+        safe_close(fds[2]);
 
         unlink(name0);
         unlink(name1);
@@ -96,6 +152,7 @@ static void test_parse_boolean(void) {
 
         assert_se(parse_boolean("garbage") < 0);
         assert_se(parse_boolean("") < 0);
+        assert_se(parse_boolean("full") < 0);
 }
 
 static void test_parse_pid(void) {
@@ -157,7 +214,7 @@ static void test_safe_atod(void) {
 
         r = safe_atod("0.2244", &d);
         assert_se(r == 0);
-        assert_se(abs(d - 0.2244) < 0.000001);
+        assert_se(fabs(d - 0.2244) < 0.000001);
 
         r = safe_atod("0,5", &d);
         assert_se(r == -EINVAL);
@@ -167,24 +224,25 @@ static void test_safe_atod(void) {
         assert_se(*e == ',');
 
         /* Check if this really is locale independent */
-        setlocale(LC_NUMERIC, "de_DE.utf8");
+        if (setlocale(LC_NUMERIC, "de_DE.utf8")) {
 
-        r = safe_atod("0.2244", &d);
-        assert_se(r == 0);
-        assert_se(abs(d - 0.2244) < 0.000001);
+                r = safe_atod("0.2244", &d);
+                assert_se(r == 0);
+                assert_se(fabs(d - 0.2244) < 0.000001);
 
-        r = safe_atod("0,5", &d);
-        assert_se(r == -EINVAL);
+                r = safe_atod("0,5", &d);
+                assert_se(r == -EINVAL);
 
-        errno = 0;
-        assert_se(abs(strtod("0,5", &e) - 0.5) < 0.00001);
+                errno = 0;
+                assert_se(fabs(strtod("0,5", &e) - 0.5) < 0.00001);
+        }
 
         /* And check again, reset */
-        setlocale(LC_NUMERIC, "C");
+        assert_se(setlocale(LC_NUMERIC, "C"));
 
         r = safe_atod("0.2244", &d);
         assert_se(r == 0);
-        assert_se(abs(d - 0.2244) < 0.000001);
+        assert_se(fabs(d - 0.2244) < 0.000001);
 
         r = safe_atod("0,5", &d);
         assert_se(r == -EINVAL);
@@ -264,18 +322,20 @@ static void test_undecchar(void) {
 
 static void test_cescape(void) {
         _cleanup_free_ char *escaped;
-        escaped = cescape("abc\\\"\b\f\n\r\t\v\003\177\234\313");
-        assert_se(streq(escaped, "abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\003\\177\\234\\313"));
+
+        assert_se(escaped = cescape("abc\\\"\b\f\n\r\t\v\a\003\177\234\313"));
+        assert_se(streq(escaped, "abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\a\\003\\177\\234\\313"));
 }
 
 static void test_cunescape(void) {
         _cleanup_free_ char *unescaped;
-        unescaped = cunescape("abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\003\\177\\234\\313");
-        assert_se(streq(unescaped, "abc\\\"\b\f\n\r\t\v\003\177\234\313"));
+
+        assert_se(unescaped = cunescape("abc\\\\\\\"\\b\\f\\a\\n\\r\\t\\v\\003\\177\\234\\313\\000\\x00"));
+        assert_se(streq(unescaped, "abc\\\"\b\f\a\n\r\t\v\003\177\234\313\\000\\x00"));
 }
 
 static void test_foreach_word(void) {
-        char *w, *state;
+        const char *word, *state;
         size_t l;
         int i = 0;
         const char test[] = "test abc d\te   f   ";
@@ -289,13 +349,12 @@ static void test_foreach_word(void) {
                 NULL
         };
 
-        FOREACH_WORD(w, l, test, state) {
-                assert_se(strneq(expected[i++], w, l));
-        }
+        FOREACH_WORD(word, l, test, state)
+                assert_se(strneq(expected[i++], word, l));
 }
 
 static void test_foreach_word_quoted(void) {
-        char *w, *state;
+        const char *word, *state;
         size_t l;
         int i = 0;
         const char test[] = "test a b c 'd' e '' '' hhh '' '' \"a b c\"";
@@ -316,13 +375,14 @@ static void test_foreach_word_quoted(void) {
         };
 
         printf("<%s>\n", test);
-        FOREACH_WORD_QUOTED(w, l, test, state) {
+        FOREACH_WORD_QUOTED(word, l, test, state) {
                 _cleanup_free_ char *t = NULL;
 
-                assert_se(t = strndup(w, l));
-                assert_se(strneq(expected[i++], w, l));
+                assert_se(t = strndup(word, l));
+                assert_se(strneq(expected[i++], word, l));
                 printf("<%s>\n", t);
         }
+        assert(isempty(state));
 }
 
 static void test_default_term_for_tty(void) {
@@ -403,7 +463,7 @@ static void test_get_process_comm(void) {
         log_info("pid1 cmdline truncated: '%s'", d);
 
         assert_se(get_parent_of_pid(1, &e) >= 0);
-        log_info("pid1 ppid: '%llu'", (unsigned long long) e);
+        log_info("pid1 ppid: "PID_FMT, e);
         assert_se(e == 0);
 
         assert_se(is_kernel_thread(1) == 0);
@@ -413,11 +473,11 @@ static void test_get_process_comm(void) {
         log_info("pid1 exe: '%s'", strna(f));
 
         assert_se(get_process_uid(1, &u) == 0);
-        log_info("pid1 uid: '%llu'", (unsigned long long) u);
+        log_info("pid1 uid: "UID_FMT, u);
         assert_se(u == 0);
 
         assert_se(get_process_gid(1, &g) == 0);
-        log_info("pid1 gid: '%llu'", (unsigned long long) g);
+        log_info("pid1 gid: "GID_FMT, g);
         assert_se(g == 0);
 
         assert(get_ctty_devnr(1, &h) == -ENOENT);
@@ -441,29 +501,59 @@ static void test_parse_size(void) {
         assert_se(parse_size("111", 1024, &bytes) == 0);
         assert_se(bytes == 111);
 
+        assert_se(parse_size("111.4", 1024, &bytes) == 0);
+        assert_se(bytes == 111);
+
         assert_se(parse_size(" 112 B", 1024, &bytes) == 0);
         assert_se(bytes == 112);
 
-        assert_se(parse_size("3 K", 1024, &bytes) == 0);
+        assert_se(parse_size(" 112.6 B", 1024, &bytes) == 0);
+        assert_se(bytes == 112);
+
+        assert_se(parse_size("3.5 K", 1024, &bytes) == 0);
+        assert_se(bytes == 3*1024 + 512);
+
+        assert_se(parse_size("3. K", 1024, &bytes) == 0);
+        assert_se(bytes == 3*1024);
+
+        assert_se(parse_size("3.0 K", 1024, &bytes) == 0);
         assert_se(bytes == 3*1024);
 
-        assert_se(parse_size(" 4 M 11K", 1024, &bytes) == 0);
-        assert_se(bytes == 4*1024*1024 + 11 * 1024);
+        assert_se(parse_size("3. 0 K", 1024, &bytes) == -EINVAL);
+
+        assert_se(parse_size(" 4 M 11.5K", 1024, &bytes) == 0);
+        assert_se(bytes == 4*1024*1024 + 11 * 1024 + 512);
+
+        assert_se(parse_size("3B3.5G", 1024, &bytes) == -EINVAL);
+
+        assert_se(parse_size("3.5G3B", 1024, &bytes) == 0);
+        assert_se(bytes == 3ULL*1024*1024*1024 + 512*1024*1024 + 3);
 
-        assert_se(parse_size("3B3G", 1024, &bytes) == 0);
-        assert_se(bytes == 3ULL*1024*1024*1024 + 3);
+        assert_se(parse_size("3.5G 4B", 1024, &bytes) == 0);
+        assert_se(bytes == 3ULL*1024*1024*1024 + 512*1024*1024 + 4);
 
-        assert_se(parse_size("3B3G4T", 1024, &bytes) == 0);
+        assert_se(parse_size("3B3G4T", 1024, &bytes) == -EINVAL);
+
+        assert_se(parse_size("4T3G3B", 1024, &bytes) == 0);
+        assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
+
+        assert_se(parse_size(" 4 T 3 G 3 B", 1024, &bytes) == 0);
         assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
 
         assert_se(parse_size("12P", 1024, &bytes) == 0);
         assert_se(bytes == 12ULL * 1024*1024*1024*1024*1024);
 
+        assert_se(parse_size("12P12P", 1024, &bytes) == -EINVAL);
+
         assert_se(parse_size("3E 2P", 1024, &bytes) == 0);
         assert_se(bytes == (3 * 1024 + 2ULL) * 1024*1024*1024*1024*1024);
 
         assert_se(parse_size("12X", 1024, &bytes) == -EINVAL);
 
+        assert_se(parse_size("12.5X", 1024, &bytes) == -EINVAL);
+
+        assert_se(parse_size("12.5e3", 1024, &bytes) == -EINVAL);
+
         assert_se(parse_size("1024E", 1024, &bytes) == -ERANGE);
         assert_se(parse_size("-1", 1024, &bytes) == -ERANGE);
         assert_se(parse_size("-1024E", 1024, &bytes) == -ERANGE);
@@ -473,6 +563,14 @@ static void test_parse_size(void) {
         assert_se(parse_size("-10B 20K", 1024, &bytes) == -ERANGE);
 }
 
+static void test_config_parse_iec_off(void) {
+        off_t offset = 0;
+        assert_se(config_parse_iec_off(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4M", &offset, NULL) == 0);
+        assert_se(offset == 4 * 1024 * 1024);
+
+        assert_se(config_parse_iec_off(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4.5M", &offset, NULL) == 0);
+}
+
 static void test_strextend(void) {
         _cleanup_free_ char *str = strdup("0123");
         strextend(&str, "456", "78", "9", NULL);
@@ -535,7 +633,6 @@ static void test_fstab_node_to_udev_node(void) {
         assert_se(streq(n, "/dev/disk/by-partuuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
         free(n);
 
-
         n = fstab_node_to_udev_node("PONIES=awesome");
         puts(n);
         assert_se(streq(n, "PONIES=awesome"));
@@ -586,10 +683,537 @@ static void test_writing_tmpfile(void) {
         assert(r == 0);
         printf("contents: %s", contents);
         assert(streq(contents, "abc\n" ALPHANUMERICAL "\n"));
+
+        unlink(name);
+}
+
+static void test_hexdump(void) {
+        uint8_t data[146];
+        unsigned i;
+
+        hexdump(stdout, NULL, 0);
+        hexdump(stdout, "", 0);
+        hexdump(stdout, "", 1);
+        hexdump(stdout, "x", 1);
+        hexdump(stdout, "x", 2);
+        hexdump(stdout, "foobar", 7);
+        hexdump(stdout, "f\nobar", 7);
+        hexdump(stdout, "xxxxxxxxxxxxxxxxxxxxyz", 23);
+
+        for (i = 0; i < ELEMENTSOF(data); i++)
+                data[i] = i*2;
+
+        hexdump(stdout, data, sizeof(data));
+}
+
+static void test_log2i(void) {
+        assert_se(log2i(1) == 0);
+        assert_se(log2i(2) == 1);
+        assert_se(log2i(3) == 1);
+        assert_se(log2i(4) == 2);
+        assert_se(log2i(32) == 5);
+        assert_se(log2i(33) == 5);
+        assert_se(log2i(63) == 5);
+        assert_se(log2i(INT_MAX) == sizeof(int)*8-2);
+}
+
+static void test_foreach_string(void) {
+        const char * const t[] = {
+                "foo",
+                "bar",
+                "waldo",
+                NULL
+        };
+        const char *x;
+        unsigned i = 0;
+
+        FOREACH_STRING(x, "foo", "bar", "waldo")
+                assert_se(streq_ptr(t[i++], x));
+
+        assert_se(i == 3);
+
+        FOREACH_STRING(x, "zzz")
+                assert_se(streq(x, "zzz"));
+}
+
+static void test_filename_is_safe(void) {
+        char foo[FILENAME_MAX+2];
+        int i;
+
+        assert_se(!filename_is_safe(""));
+        assert_se(!filename_is_safe("/bar/foo"));
+        assert_se(!filename_is_safe("/"));
+        assert_se(!filename_is_safe("."));
+        assert_se(!filename_is_safe(".."));
+
+        for (i=0; i<FILENAME_MAX+1; i++)
+                foo[i] = 'a';
+        foo[FILENAME_MAX+1] = '\0';
+
+        assert_se(!filename_is_safe(foo));
+
+        assert_se(filename_is_safe("foo_bar-333"));
+        assert_se(filename_is_safe("o.o"));
+}
+
+static void test_string_has_cc(void) {
+        assert_se(string_has_cc("abc\1", NULL));
+        assert_se(string_has_cc("abc\x7f", NULL));
+        assert_se(string_has_cc("abc\x7f", NULL));
+        assert_se(string_has_cc("abc\t\x7f", "\t"));
+        assert_se(string_has_cc("abc\t\x7f", "\t"));
+        assert_se(string_has_cc("\x7f", "\t"));
+        assert_se(string_has_cc("\x7f", "\t\a"));
+
+        assert_se(!string_has_cc("abc\t\t", "\t"));
+        assert_se(!string_has_cc("abc\t\t\a", "\t\a"));
+        assert_se(!string_has_cc("a\ab\tc", "\t\a"));
+}
+
+static void test_ascii_strlower(void) {
+        char a[] = "AabBcC Jk Ii Od LKJJJ kkd LK";
+        assert_se(streq(ascii_strlower(a), "aabbcc jk ii od lkjjj kkd lk"));
+}
+
+static void test_files_same(void) {
+        _cleanup_close_ int fd = -1;
+        char name[] = "/tmp/test-files_same.XXXXXX";
+        char name_alias[] = "/tmp/test-files_same.alias";
+
+        fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+        assert_se(fd >= 0);
+        assert_se(symlink(name, name_alias) >= 0);
+
+        assert_se(files_same(name, name));
+        assert_se(files_same(name, name_alias));
+
+        unlink(name);
+        unlink(name_alias);
+}
+
+static void test_is_valid_documentation_url(void) {
+        assert_se(is_valid_documentation_url("http://www.freedesktop.org/wiki/Software/systemd"));
+        assert_se(is_valid_documentation_url("https://www.kernel.org/doc/Documentation/binfmt_misc.txt"));
+        assert_se(is_valid_documentation_url("file:foo"));
+        assert_se(is_valid_documentation_url("man:systemd.special(7)"));
+        assert_se(is_valid_documentation_url("info:bar"));
+
+        assert_se(!is_valid_documentation_url("foo:"));
+        assert_se(!is_valid_documentation_url("info:"));
+        assert_se(!is_valid_documentation_url(""));
+}
+
+static void test_file_in_same_dir(void) {
+        assert_se(streq(file_in_same_dir("/", "a"), "/a"));
+        assert_se(streq(file_in_same_dir("/", "/a"), "/a"));
+        assert_se(streq(file_in_same_dir("", "a"), "a"));
+        assert_se(streq(file_in_same_dir("a/", "a"), "a/a"));
+        assert_se(streq(file_in_same_dir("bar/foo", "bar"), "bar/bar"));
+}
+
+static void test_endswith(void) {
+        assert_se(endswith("foobar", "bar"));
+        assert_se(endswith("foobar", ""));
+        assert_se(endswith("foobar", "foobar"));
+        assert_se(endswith("", ""));
+
+        assert_se(!endswith("foobar", "foo"));
+        assert_se(!endswith("foobar", "foobarfoofoo"));
+}
+
+static void test_close_nointr(void) {
+        char name[] = "/tmp/test-test-close_nointr.XXXXXX";
+        int fd;
+
+        fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+        assert_se(fd >= 0);
+        assert_se(close_nointr(fd) >= 0);
+        assert_se(close_nointr(fd) < 0);
+
+        unlink(name);
+}
+
+
+static void test_unlink_noerrno(void) {
+        char name[] = "/tmp/test-close_nointr.XXXXXX";
+        int fd;
+
+        fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+        assert_se(fd >= 0);
+        assert_se(close_nointr(fd) >= 0);
+
+        {
+                PROTECT_ERRNO;
+                errno = -42;
+                assert_se(unlink_noerrno(name) >= 0);
+                assert_se(errno == -42);
+                assert_se(unlink_noerrno(name) < 0);
+                assert_se(errno == -42);
+        }
+}
+
+static void test_readlink_and_make_absolute(void) {
+        char tempdir[] = "/tmp/test-readlink_and_make_absolute";
+        char name[] = "/tmp/test-readlink_and_make_absolute/original";
+        char name2[] = "test-readlink_and_make_absolute/original";
+        char name_alias[] = "/tmp/test-readlink_and_make_absolute-alias";
+        char *r = NULL;
+
+        assert(mkdir_safe(tempdir, 0755, getuid(), getgid()) >= 0);
+        assert_se(touch(name) >= 0);
+
+        assert_se(symlink(name, name_alias) >= 0);
+        assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
+        assert_se(streq(r, name));
+        free(r);
+        assert_se(unlink(name_alias) >= 0);
+
+        assert_se(chdir(tempdir) >= 0);
+        assert_se(symlink(name2, name_alias) >= 0);
+        assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
+        assert_se(streq(r, name));
+        free(r);
+        assert_se(unlink(name_alias) >= 0);
+
+        assert_se(rm_rf_dangerous(tempdir, false, true, false) >= 0);
+}
+
+static void test_read_one_char(void) {
+        char r;
+        bool need_nl;
+        char name[] = "/tmp/test-read_one_char.XXXXXX";
+        _cleanup_close_ int fd = -1;
+        FILE *file;
+
+        fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+        assert_se(fd >= 0);
+        file = fdopen(fd, "r+");
+        assert_se(file);
+        assert_se(fputs("c\n", file) >= 0);
+        rewind(file);
+
+        assert_se(read_one_char(file, &r, 1000000, &need_nl) >= 0);
+        assert_se(!need_nl);
+        assert_se(r == 'c');
+        assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
+
+        rewind(file);
+        assert_se(fputs("foobar\n", file) >= 0);
+        rewind(file);
+        assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
+
+        rewind(file);
+        assert_se(fputs("\n", file) >= 0);
+        rewind(file);
+        assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
+
+        unlink(name);
+}
+
+static void test_ignore_signals(void) {
+        assert_se(ignore_signals(SIGINT, -1) >= 0);
+        assert_se(kill(getpid(), SIGINT) >= 0);
+        assert_se(ignore_signals(SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
+        assert_se(kill(getpid(), SIGUSR1) >= 0);
+        assert_se(kill(getpid(), SIGUSR2) >= 0);
+        assert_se(kill(getpid(), SIGTERM) >= 0);
+        assert_se(kill(getpid(), SIGPIPE) >= 0);
+        assert_se(default_signals(SIGINT, SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
+}
+
+static void test_strshorten(void) {
+        char s[] = "foobar";
+
+        assert_se(strlen(strshorten(s, 6)) == 6);
+        assert_se(strlen(strshorten(s, 12)) == 6);
+        assert_se(strlen(strshorten(s, 2)) == 2);
+        assert_se(strlen(strshorten(s, 0)) == 0);
+}
+
+static void test_strappenda(void) {
+        char *actual;
+
+        actual = strappenda("", "foo", "bar");
+        assert_se(streq(actual, "foobar"));
+
+        actual = strappenda("foo", "bar", "baz");
+        assert_se(streq(actual, "foobarbaz"));
+
+        actual = strappenda("foo", "", "bar", "baz");
+        assert_se(streq(actual, "foobarbaz"));
+}
+
+static void test_is_symlink(void) {
+        char name[] = "/tmp/test-is_symlink.XXXXXX";
+        char name_link[] = "/tmp/test-is_symlink.link";
+        _cleanup_close_ int fd = -1;
+
+        fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+        assert_se(fd >= 0);
+        assert_se(symlink(name, name_link) >= 0);
+
+        assert_se(is_symlink(name) == 0);
+        assert_se(is_symlink(name_link) == 1);
+        assert_se(is_symlink("/a/file/which/does/not/exist/i/guess") < 0);
+
+
+        unlink(name);
+        unlink(name_link);
+}
+
+static void test_pid_is_unwaited(void) {
+        pid_t pid;
+
+        pid = fork();
+        assert_se(pid >= 0);
+        if (pid == 0) {
+                _exit(EXIT_SUCCESS);
+        } else {
+                int status;
+
+                waitpid(pid, &status, 0);
+                assert_se(!pid_is_unwaited(pid));
+        }
+        assert_se(pid_is_unwaited(getpid()));
+        assert_se(!pid_is_unwaited(-1));
+}
+
+static void test_pid_is_alive(void) {
+        pid_t pid;
+
+        pid = fork();
+        assert_se(pid >= 0);
+        if (pid == 0) {
+                _exit(EXIT_SUCCESS);
+        } else {
+                int status;
+
+                waitpid(pid, &status, 0);
+                assert_se(!pid_is_alive(pid));
+        }
+        assert_se(pid_is_alive(getpid()));
+        assert_se(!pid_is_alive(-1));
+}
+
+static void test_search_and_fopen(void) {
+        const char *dirs[] = {"/tmp/foo/bar", "/tmp", NULL};
+        char name[] = "/tmp/test-search_and_fopen.XXXXXX";
+        int fd = -1;
+        int r;
+        FILE *f;
+
+        fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+        assert_se(fd >= 0);
+        close(fd);
+
+        r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
+        assert_se(r >= 0);
+        fclose(f);
+
+        r = search_and_fopen(name, "r", NULL, dirs, &f);
+        assert_se(r >= 0);
+        fclose(f);
+
+        r = search_and_fopen(basename(name), "r", "/", dirs, &f);
+        assert_se(r >= 0);
+        fclose(f);
+
+        r = search_and_fopen("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
+        assert_se(r < 0);
+        r = search_and_fopen("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
+        assert_se(r < 0);
+
+        r = unlink(name);
+        assert_se(r == 0);
+
+        r = search_and_fopen(basename(name), "r", NULL, dirs, &f);
+        assert_se(r < 0);
+}
+
+
+static void test_search_and_fopen_nulstr(void) {
+        const char dirs[] = "/tmp/foo/bar\0/tmp\0";
+        char name[] = "/tmp/test-search_and_fopen.XXXXXX";
+        int fd = -1;
+        int r;
+        FILE *f;
+
+        fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+        assert_se(fd >= 0);
+        close(fd);
+
+        r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
+        assert_se(r >= 0);
+        fclose(f);
+
+        r = search_and_fopen_nulstr(name, "r", NULL, dirs, &f);
+        assert_se(r >= 0);
+        fclose(f);
+
+        r = search_and_fopen_nulstr("/a/file/which/does/not/exist/i/guess", "r", NULL, dirs, &f);
+        assert_se(r < 0);
+        r = search_and_fopen_nulstr("afilewhichdoesnotexistiguess", "r", NULL, dirs, &f);
+        assert_se(r < 0);
+
+        r = unlink(name);
+        assert_se(r == 0);
+
+        r = search_and_fopen_nulstr(basename(name), "r", NULL, dirs, &f);
+        assert_se(r < 0);
+}
+
+static void test_glob_exists(void) {
+        char name[] = "/tmp/test-glob_exists.XXXXXX";
+        int fd = -1;
+        int r;
+
+        fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+        assert_se(fd >= 0);
+        close(fd);
+
+        r = glob_exists("/tmp/test-glob_exists*");
+        assert_se(r == 1);
+
+        r = unlink(name);
+        assert_se(r == 0);
+        r = glob_exists("/tmp/test-glob_exists*");
+        assert_se(r == 0);
+}
+
+static void test_execute_directory(void) {
+        char name[] = "/tmp/test-execute_directory/script1";
+        char name2[] = "/tmp/test-execute_directory/script2";
+        char name3[] = "/tmp/test-execute_directory/useless";
+        char tempdir[] = "/tmp/test-execute_directory/";
+
+        assert_se(mkdir_safe(tempdir, 0755, getuid(), getgid()) >= 0);
+        assert_se(write_string_file(name, "#!/bin/sh\necho 'Executing '$0\ntouch /tmp/test-execute_directory/it_works") == 0);
+        assert_se(write_string_file(name2, "#!/bin/sh\necho 'Executing '$0\ntouch /tmp/test-execute_directory/it_works2") == 0);
+        assert_se(chmod(name, 0755) == 0);
+        assert_se(chmod(name2, 0755) == 0);
+        assert_se(touch(name3) >= 0);
+
+        execute_directory(tempdir, NULL, DEFAULT_TIMEOUT_USEC, NULL);
+        assert_se(access("/tmp/test-execute_directory/it_works", F_OK) >= 0);
+        assert_se(access("/tmp/test-execute_directory/it_works2", F_OK) >= 0);
+
+        rm_rf_dangerous(tempdir, false, true, false);
+}
+
+static void test_unquote_first_word(void) {
+        const char *p, *original;
+        char *t;
+
+        p = original = "foobar waldo";
+        assert_se(unquote_first_word(&p, &t) > 0);
+        assert_se(streq(t, "foobar"));
+        free(t);
+        assert_se(p == original + 7);
+
+        assert_se(unquote_first_word(&p, &t) > 0);
+        assert_se(streq(t, "waldo"));
+        free(t);
+        assert_se(p == original + 12);
+
+        assert_se(unquote_first_word(&p, &t) == 0);
+        assert_se(!t);
+        assert_se(p == original + 12);
+
+        p = original = "\"foobar\" \'waldo\'";
+        assert_se(unquote_first_word(&p, &t) > 0);
+        assert_se(streq(t, "foobar"));
+        free(t);
+        assert_se(p == original + 9);
+
+        assert_se(unquote_first_word(&p, &t) > 0);
+        assert_se(streq(t, "waldo"));
+        free(t);
+        assert_se(p == original + 16);
+
+        assert_se(unquote_first_word(&p, &t) == 0);
+        assert_se(!t);
+        assert_se(p == original + 16);
+
+        p = original = "\"";
+        assert_se(unquote_first_word(&p, &t) == -EINVAL);
+        assert_se(p == original + 1);
+
+        p = original = "\'";
+        assert_se(unquote_first_word(&p, &t) == -EINVAL);
+        assert_se(p == original + 1);
+
+        p = original = "yay\'foo\'bar";
+        assert_se(unquote_first_word(&p, &t) > 0);
+        assert_se(streq(t, "yayfoobar"));
+        free(t);
+        assert_se(p == original + 11);
+
+        p = original = "   foobar   ";
+        assert_se(unquote_first_word(&p, &t) > 0);
+        assert_se(streq(t, "foobar"));
+        free(t);
+        assert_se(p == original + 12);
+}
+
+static void test_unquote_many_words(void) {
+        const char *p, *original;
+        char *a, *b, *c;
+
+        p = original = "foobar waldi piep";
+        assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 3);
+        assert_se(p == original + 17);
+        assert_se(streq_ptr(a, "foobar"));
+        assert_se(streq_ptr(b, "waldi"));
+        assert_se(streq_ptr(c, "piep"));
+        free(a);
+        free(b);
+        free(c);
+
+        p = original = "'foobar' wa\"ld\"i   ";
+        assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 2);
+        assert_se(p == original + 19);
+        assert_se(streq_ptr(a, "foobar"));
+        assert_se(streq_ptr(b, "waldi"));
+        assert_se(streq_ptr(c, NULL));
+        free(a);
+        free(b);
+
+        p = original = "";
+        assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 0);
+        assert_se(p == original);
+        assert_se(streq_ptr(a, NULL));
+        assert_se(streq_ptr(b, NULL));
+        assert_se(streq_ptr(c, NULL));
+
+        p = original = "  ";
+        assert_se(unquote_many_words(&p, &a, &b, &c, NULL) == 0);
+        assert_se(p == original+2);
+        assert_se(streq_ptr(a, NULL));
+        assert_se(streq_ptr(b, NULL));
+        assert_se(streq_ptr(c, NULL));
+
+        p = original = "foobar";
+        assert_se(unquote_many_words(&p, NULL) == 0);
+        assert_se(p == original);
+
+        p = original = "foobar waldi";
+        assert_se(unquote_many_words(&p, &a, NULL) == 1);
+        assert_se(p == original+7);
+        assert_se(streq_ptr(a, "foobar"));
+
+        p = original = "     foobar    ";
+        assert_se(unquote_many_words(&p, &a, NULL) == 1);
+        assert_se(p == original+15);
+        assert_se(streq_ptr(a, "foobar"));
 }
 
 int main(int argc, char *argv[]) {
+        log_parse_environment();
+        log_open();
+
         test_streq_ptr();
+        test_align_power2();
+        test_max();
         test_first_word();
         test_close_many();
         test_parse_boolean();
@@ -618,6 +1242,7 @@ int main(int argc, char *argv[]) {
         test_get_process_comm();
         test_protect_errno();
         test_parse_size();
+        test_config_parse_iec_off();
         test_strextend();
         test_strrep();
         test_split_pair();
@@ -625,6 +1250,32 @@ int main(int argc, char *argv[]) {
         test_get_files_in_directory();
         test_in_set();
         test_writing_tmpfile();
+        test_hexdump();
+        test_log2i();
+        test_foreach_string();
+        test_filename_is_safe();
+        test_string_has_cc();
+        test_ascii_strlower();
+        test_files_same();
+        test_is_valid_documentation_url();
+        test_file_in_same_dir();
+        test_endswith();
+        test_close_nointr();
+        test_unlink_noerrno();
+        test_readlink_and_make_absolute();
+        test_read_one_char();
+        test_ignore_signals();
+        test_strshorten();
+        test_strappenda();
+        test_is_symlink();
+        test_pid_is_unwaited();
+        test_pid_is_alive();
+        test_search_and_fopen();
+        test_search_and_fopen_nulstr();
+        test_glob_exists();
+        test_execute_directory();
+        test_unquote_first_word();
+        test_unquote_many_words();
 
         return 0;
 }
index 7a34f14..ea109fb 100644 (file)
@@ -35,7 +35,7 @@ static void test_one(const char *data, ...) {
                 int t, tt;
                 const char *nn;
 
-                t = xml_tokenize(&data, &name, &state);
+                t = xml_tokenize(&data, &name, &state, NULL);
                 assert_se(t >= 0);
 
                 tt = va_arg(ap, int);
index 089a5fe..0ba32d3 100644 (file)
@@ -109,7 +109,7 @@ static void print_status_info(const StatusInfo *i) {
 
         /* Enforce the values of /etc/localtime */
         if (getenv("TZ")) {
-                fprintf(stderr, "Warning: ignoring the TZ variable, reading the system's timezone setting only.\n\n");
+                fprintf(stderr, "Warning: Ignoring the TZ variable. Reading the system's time zone setting only.\n\n");
                 unsetenv("TZ");
         }
 
@@ -120,7 +120,7 @@ static void print_status_info(const StatusInfo *i) {
                 sec = time(NULL);
                 have_time = true;
         } else
-                fprintf(stderr, "Warning: could not get time from timedated and not operating locally.\n\n");
+                fprintf(stderr, "Warning: Could not get time from timedated and not operating locally.\n\n");
 
         if (have_time) {
                 zero(tm);
@@ -148,60 +148,66 @@ static void print_status_info(const StatusInfo *i) {
         } else
                 printf("        RTC time: %s\n", "n/a");
 
-        zero(tm);
-        assert_se(strftime(a, sizeof(a), "%Z, %z", localtime_r(&sec, &tm)) > 0);
-        char_array_0(a);
-        printf("        Timezone: %s (%s)\n"
+        if (have_time) {
+                zero(tm);
+                assert_se(strftime(a, sizeof(a), "%Z, %z", localtime_r(&sec, &tm)) > 0);
+                char_array_0(a);
+        }
+
+        printf("       Time zone: %s (%s)\n"
                "     NTP enabled: %s\n"
                "NTP synchronized: %s\n"
                " RTC in local TZ: %s\n",
-               strna(i->timezone), a,
+               strna(i->timezone), have_time ? a : "n/a",
                i->ntp_capable ? yes_no(i->ntp_enabled) : "n/a",
                yes_no(i->ntp_synced),
                yes_no(i->rtc_local));
 
-        r = time_get_dst(sec, "/etc/localtime",
-                         &tc, &zc, &is_dstc,
-                         &tn, &dn, &zn, &is_dstn);
-        if (r < 0)
-                printf("      DST active: %s\n", "n/a");
-        else if (have_time) {
-                printf("      DST active: %s\n", yes_no(is_dstc));
-
-                t = tc - 1;
-                zero(tm);
-                assert_se(strftime(a, sizeof(a), "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&t, &tm)) > 0);
-                char_array_0(a);
-
-                zero(tm);
-                assert_se(strftime(b, sizeof(b), "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&tc, &tm)) > 0);
-                char_array_0(b);
-                printf(" Last DST change: DST %s at\n"
-                       "                  %s\n"
-                       "                  %s\n",
-                       is_dstc ? "began" : "ended", a, b);
-
-                t = tn - 1;
-                zero(tm);
-                assert_se(strftime(a, sizeof(a), "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&t, &tm)) > 0);
-                char_array_0(a);
-
-                zero(tm);
-                assert_se(strftime(b, sizeof(b), "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&tn, &tm)) > 0);
-                char_array_0(b);
-                printf(" Next DST change: DST %s (the clock jumps %s) at\n"
-                       "                  %s\n"
-                       "                  %s\n",
-                       is_dstn ? "begins" : "ends", jump_str(dn, s, sizeof(s)), a, b);
+        if (have_time) {
+                r = time_get_dst(sec, "/etc/localtime",
+                                 &tc, &zc, &is_dstc,
+                                 &tn, &dn, &zn, &is_dstn);
+                if (r < 0)
+                        printf("      DST active: %s\n", "n/a");
+                else {
+                        printf("      DST active: %s\n", yes_no(is_dstc));
+
+                        t = tc - 1;
+                        zero(tm);
+                        assert_se(strftime(a, sizeof(a), "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&t, &tm)) > 0);
+                        char_array_0(a);
+
+                        zero(tm);
+                        assert_se(strftime(b, sizeof(b), "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&tc, &tm)) > 0);
+                        char_array_0(b);
+                        printf(" Last DST change: DST %s at\n"
+                               "                  %s\n"
+                               "                  %s\n",
+                               is_dstc ? "began" : "ended", a, b);
+
+                        t = tn - 1;
+                        zero(tm);
+                        assert_se(strftime(a, sizeof(a), "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&t, &tm)) > 0);
+                        char_array_0(a);
+
+                        zero(tm);
+                        assert_se(strftime(b, sizeof(b), "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&tn, &tm)) > 0);
+                        char_array_0(b);
+                        printf(" Next DST change: DST %s (the clock jumps %s) at\n"
+                               "                  %s\n"
+                               "                  %s\n",
+                               is_dstn ? "begins" : "ends", jump_str(dn, s, sizeof(s)), a, b);
+                }
         } else
                 printf("      DST active: %s\n", yes_no(is_dstc));
 
         if (i->rtc_local)
                 fputs("\n" ANSI_HIGHLIGHT_ON
-                      "Warning: The RTC is configured to maintain time in the local timezone. This\n"
-                      "         mode is not fully supported and will create various problems with time\n"
-                      "         zone changes and daylight saving adjustments. If at all possible use\n"
-                      "         RTC in UTC, by calling 'timedatectl set-local-rtc 0'" ANSI_HIGHLIGHT_OFF ".\n", stdout);
+                      "Warning: The system is configured to read the RTC time in the local time zone. This\n"
+                      "         mode can not be fully supported. It will create various problems with time\n"
+                      "         zone changes and daylight saving time adjustments. The RTC time is never updated,\n"
+                      "         it relies on external facilities to maintain it. If at all possible, use\n"
+                      "         RTC in UTC by calling 'timedatectl set-local-rtc 0'" ANSI_HIGHLIGHT_OFF ".\n", stdout);
 }
 
 static int show_status(sd_bus *bus, char **args, unsigned n) {
@@ -286,7 +292,7 @@ static int set_timezone(sd_bus *bus, char **args, unsigned n) {
                                NULL,
                                "sb", args[1], arg_ask_password);
         if (r < 0)
-                log_error("Failed to set timezone: %s", bus_error_message(&error, -r));
+                log_error("Failed to set time zone: %s", bus_error_message(&error, -r));
 
         return r;
 }
@@ -350,80 +356,28 @@ static int set_ntp(sd_bus *bus, char **args, unsigned n) {
 }
 
 static int list_timezones(sd_bus *bus, char **args, unsigned n) {
-        _cleanup_fclose_ FILE *f = NULL;
         _cleanup_strv_free_ char **zones = NULL;
-        size_t n_zones = 0;
+        int r;
 
         assert(args);
         assert(n == 1);
 
-        f = fopen("/usr/share/zoneinfo/zone.tab", "re");
-        if (!f) {
-                log_error("Failed to open timezone database: %m");
-                return -errno;
-        }
-
-        for (;;) {
-                char l[LINE_MAX], *p, **z, *w;
-                size_t k;
-
-                if (!fgets(l, sizeof(l), f)) {
-                        if (feof(f))
-                                break;
-
-                        log_error("Failed to read timezone database: %m");
-                        return -errno;
-                }
-
-                p = strstrip(l);
-
-                if (isempty(p) || *p == '#')
-                        continue;
-
-
-                /* Skip over country code */
-                p += strcspn(p, WHITESPACE);
-                p += strspn(p, WHITESPACE);
-
-                /* Skip over coordinates */
-                p += strcspn(p, WHITESPACE);
-                p += strspn(p, WHITESPACE);
-
-                /* Found timezone name */
-                k = strcspn(p, WHITESPACE);
-                if (k <= 0)
-                        continue;
-
-                w = strndup(p, k);
-                if (!w)
-                        return log_oom();
-
-                z = realloc(zones, sizeof(char*) * (n_zones + 2));
-                if (!z) {
-                        free(w);
-                        return log_oom();
-                }
-
-                zones = z;
-                zones[n_zones++] = w;
+        r = get_timezones(&zones);
+        if (r < 0) {
+                log_error("Failed to read list of time zones: %s", strerror(-r));
+                return r;
         }
 
-        if (zones)
-                zones[n_zones] = NULL;
-
         pager_open_if_enabled();
-
-        strv_sort(zones);
         strv_print(zones);
 
         return 0;
 }
 
-static int help(void) {
-
+static void help(void) {
         printf("%s [OPTIONS...] COMMAND ...\n\n"
                "Query or change system time and date settings.\n\n"
-               "  -h --help                Show this help\n"
+               "  -h --help                Show this help message\n"
                "     --version             Show package version\n"
                "     --no-pager            Do not pipe output into a pager\n"
                "     --no-ask-password     Do not prompt for password\n"
@@ -433,13 +387,11 @@ static int help(void) {
                "Commands:\n"
                "  status                   Show current time settings\n"
                "  set-time TIME            Set system time\n"
-               "  set-timezone ZONE        Set system timezone\n"
-               "  list-timezones           Show known timezones\n"
+               "  set-timezone ZONE        Set system time zone\n"
+               "  list-timezones           Show known time zones\n"
                "  set-local-rtc BOOL       Control whether RTC is in local time\n"
                "  set-ntp BOOL             Control whether NTP is enabled\n",
                program_invocation_short_name);
-
-        return 0;
 }
 
 static int parse_argv(int argc, char *argv[]) {
@@ -467,12 +419,13 @@ static int parse_argv(int argc, char *argv[]) {
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "hH:M:", options, NULL)) >= 0) {
+        while ((c = getopt_long(argc, argv, "hH:M:", options, NULL)) >= 0)
 
                 switch (c) {
 
                 case 'h':
-                        return help();
+                        help();
+                        return 0;
 
                 case ARG_VERSION:
                         puts(PACKAGE_STRING);
@@ -507,7 +460,6 @@ static int parse_argv(int argc, char *argv[]) {
                 default:
                         assert_not_reached("Unhandled option");
                 }
-        }
 
         return 1;
 }
@@ -593,7 +545,7 @@ static int timedatectl_main(sd_bus *bus, int argc, char *argv[]) {
 }
 
 int main(int argc, char *argv[]) {
-        _cleanup_bus_unref_ sd_bus *bus = NULL;
+        _cleanup_bus_close_unref_ sd_bus *bus = NULL;
         int r;
 
         setlocale(LC_ALL, "");
index d85ce57..fa3f947 100644 (file)
@@ -22,6 +22,7 @@
 #include <errno.h>
 #include <string.h>
 #include <unistd.h>
+#include <sys/capability.h>
 
 #include "sd-id128.h"
 #include "sd-messages.h"
 #include "util.h"
 #include "strv.h"
 #include "def.h"
-#include "hwclock.h"
+#include "clock-util.h"
 #include "conf-files.h"
 #include "path-util.h"
 #include "fileio-label.h"
 #include "label.h"
 #include "bus-util.h"
+#include "bus-errors.h"
 #include "event-util.h"
 
 #define NULL_ADJTIME_UTC "0.0 0 0\n0\nUTC\n"
 typedef struct Context {
         char *zone;
         bool local_rtc;
-        unsigned can_ntp;
-        unsigned use_ntp;
+        bool can_ntp;
+        bool use_ntp;
         Hashmap *polkit_registry;
 } Context;
 
-static void context_reset(Context *c) {
+static void context_free(Context *c) {
         assert(c);
 
         free(c->zone);
-        c->zone = NULL;
-
-        c->local_rtc = false;
-        c->can_ntp = c->use_ntp = -1;
-}
-
-static void context_free(Context *c, sd_bus *bus) {
-        assert(c);
-
-        context_reset(c);
-        bus_verify_polkit_async_registry_free(bus, c->polkit_registry);
-}
-
-static bool valid_timezone(const char *name) {
-        const char *p;
-        char *t;
-        bool slash = false;
-        int r;
-        struct stat st;
-
-        assert(name);
-
-        if (*name == '/' || *name == 0)
-                return false;
-
-        for (p = name; *p; p++) {
-                if (!(*p >= '0' && *p <= '9') &&
-                    !(*p >= 'a' && *p <= 'z') &&
-                    !(*p >= 'A' && *p <= 'Z') &&
-                    !(*p == '-' || *p == '_' || *p == '+' || *p == '/'))
-                        return false;
-
-                if (*p == '/') {
-
-                        if (slash)
-                                return false;
-
-                        slash = true;
-                } else
-                        slash = false;
-        }
-
-        if (slash)
-                return false;
-
-        t = strappend("/usr/share/zoneinfo/", name);
-        if (!t)
-                return false;
-
-        r = stat(t, &st);
-        free(t);
-
-        if (r < 0)
-                return false;
-
-        if (!S_ISREG(st.st_mode))
-                return false;
-
-        return true;
+        bus_verify_polkit_async_registry_free(c->polkit_registry);
 }
 
 static int context_read_data(Context *c) {
@@ -121,12 +65,10 @@ static int context_read_data(Context *c) {
 
         assert(c);
 
-        context_reset(c);
-
         r = readlink_malloc("/etc/localtime", &t);
         if (r < 0) {
                 if (r == -EINVAL)
-                        log_warning("/etc/localtime should be a symbolic link to a timezone data file in /usr/share/zoneinfo/.");
+                        log_warning("/etc/localtime should be a symbolic link to a time zone data file in /usr/share/zoneinfo/.");
                 else
                         log_warning("Failed to get target of /etc/localtime: %s", strerror(-r));
         } else {
@@ -137,7 +79,7 @@ static int context_read_data(Context *c) {
                         e = path_startswith(t, "../usr/share/zoneinfo/");
 
                 if (!e)
-                        log_warning("/etc/localtime should be a symbolic link to a timezone data file in /usr/share/zoneinfo/.");
+                        log_warning("/etc/localtime should be a symbolic link to a time zone data file in /usr/share/zoneinfo/.");
                 else {
                         c->zone = strdup(e);
                         if (!c->zone)
@@ -153,7 +95,7 @@ have_timezone:
                 c->zone = NULL;
         }
 
-        c->local_rtc = hwclock_is_localtime() > 0;
+        c->local_rtc = clock_is_localtime() > 0;
 
         return 0;
 }
@@ -238,218 +180,145 @@ static int context_write_data_local_rtc(Context *c) {
         return write_string_file_atomic_label("/etc/adjtime", w);
 }
 
-static char** get_ntp_services(void) {
-        _cleanup_strv_free_ char **r = NULL, **files = NULL;
-        char **i;
-        int k;
-
-        k = conf_files_list(&files, ".list", NULL,
-                            "/etc/systemd/ntp-units.d",
-                            "/run/systemd/ntp-units.d",
-                            "/usr/local/lib/systemd/ntp-units.d",
-                            "/usr/lib/systemd/ntp-units.d",
-                            NULL);
-        if (k < 0)
-                return NULL;
-
-        STRV_FOREACH(i, files) {
-                _cleanup_fclose_ FILE *f;
-
-                f = fopen(*i, "re");
-                if (!f)
-                        continue;
-
-                for (;;) {
-                        char line[PATH_MAX], *l;
-
-                        if (!fgets(line, sizeof(line), f)) {
-
-                                if (ferror(f))
-                                        log_error("Failed to read NTP units file: %m");
-
-                                break;
-                        }
-
-                        l = strstrip(line);
-                        if (l[0] == 0 || l[0] == '#')
-                                continue;
-
-                        if (strv_extend(&r, l) < 0) {
-                                log_oom();
-                                return NULL;
-                        }
-                }
-        }
-
-        i = r;
-        r = NULL; /* avoid cleanup */
-
-        return strv_uniq(i);
-}
-
 static int context_read_ntp(Context *c, sd_bus *bus) {
-        _cleanup_strv_free_ char **l;
-        char **i;
+        _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+        sd_bus_message *reply = NULL;
+        const char *s;
         int r;
 
         assert(c);
         assert(bus);
 
-        l = get_ntp_services();
-        STRV_FOREACH(i, l) {
-                _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
-                sd_bus_message *reply = NULL;
-                const char *s;
+        r = sd_bus_call_method(
+                        bus,
+                        "org.freedesktop.systemd1",
+                        "/org/freedesktop/systemd1",
+                        "org.freedesktop.systemd1.Manager",
+                        "GetUnitFileState",
+                        &error,
+                        &reply,
+                        "s",
+                        "systemd-timesyncd.service");
 
-                r = sd_bus_call_method(
-                                bus,
-                                "org.freedesktop.systemd1",
-                                "/org/freedesktop/systemd1",
-                                "org.freedesktop.systemd1.Manager",
-                                "GetUnitFileState",
-                                &error,
-                                &reply,
-                                "s",
-                                *i);
-
-                if (r < 0) {
-                        /* This implementation does not exist, try next one */
-                        if (sd_bus_error_has_name(&error, SD_BUS_ERROR_FILE_NOT_FOUND))
-                                continue;
-
-                        return r;
-                }
-
-                r = sd_bus_message_read(reply, "s", &s);
-                if (r < 0)
-                        return r;
-
-                c->can_ntp = 1;
-                c->use_ntp =
-                        streq(s, "enabled") ||
-                        streq(s, "enabled-runtime");
+        if (r < 0) {
+                if (sd_bus_error_has_name(&error, SD_BUS_ERROR_FILE_NOT_FOUND) ||
+                    sd_bus_error_has_name(&error, "org.freedesktop.systemd1.LoadFailed") ||
+                    sd_bus_error_has_name(&error, "org.freedesktop.systemd1.NoSuchUnit"))
+                        return 0;
 
-                return 0;
+                return r;
         }
 
-        /* NTP is not installed. */
-        c->can_ntp = 0;
-        c->use_ntp = 0;
+        r = sd_bus_message_read(reply, "s", &s);
+        if (r < 0)
+                return r;
+
+        c->can_ntp = true;
+        c->use_ntp = STR_IN_SET(s, "enabled", "enabled-runtime");
 
         return 0;
 }
 
 static int context_start_ntp(Context *c, sd_bus *bus, sd_bus_error *error) {
-        _cleanup_strv_free_ char **l = NULL;
-        char **i;
         int r;
 
         assert(c);
         assert(bus);
         assert(error);
 
-        l = get_ntp_services();
-        STRV_FOREACH(i, l) {
-
-                if (c->use_ntp)
-                        r = sd_bus_call_method(
-                                        bus,
-                                        "org.freedesktop.systemd1",
-                                        "/org/freedesktop/systemd1",
-                                        "org.freedesktop.systemd1.Manager",
-                                        "StartUnit",
-                                        error,
-                                        NULL,
-                                        "ss", *i, "replace");
-                else
-                        r = sd_bus_call_method(
-                                        bus,
-                                        "org.freedesktop.systemd1",
-                                        "/org/freedesktop/systemd1",
-                                        "org.freedesktop.systemd1.Manager",
-                                        "StopUnit",
-                                        error,
-                                        NULL,
-                                        "ss", *i, "replace");
-
-                if (r < 0) {
-                        if (sd_bus_error_has_name(error, SD_BUS_ERROR_FILE_NOT_FOUND) ||
-                            sd_bus_error_has_name(error, "org.freedesktop.systemd1.LoadFailed") ||
-                            sd_bus_error_has_name(error, "org.freedesktop.systemd1.NoSuchUnit")) {
-                                /* This implementation does not exist, try next one */
-                                sd_bus_error_free(error);
-                                continue;
-                        }
+        if (c->use_ntp)
+                r = sd_bus_call_method(
+                                bus,
+                                "org.freedesktop.systemd1",
+                                "/org/freedesktop/systemd1",
+                                "org.freedesktop.systemd1.Manager",
+                                "StartUnit",
+                                error,
+                                NULL,
+                                "ss",
+                                "systemd-timesyncd.service",
+                                "replace");
+        else
+                r = sd_bus_call_method(
+                                bus,
+                                "org.freedesktop.systemd1",
+                                "/org/freedesktop/systemd1",
+                                "org.freedesktop.systemd1.Manager",
+                                "StopUnit",
+                                error,
+                                NULL,
+                                "ss",
+                                "systemd-timesyncd.service",
+                                "replace");
 
-                        return r;
+        if (r < 0) {
+                if (sd_bus_error_has_name(error, SD_BUS_ERROR_FILE_NOT_FOUND) ||
+                    sd_bus_error_has_name(error, "org.freedesktop.systemd1.LoadFailed") ||
+                    sd_bus_error_has_name(error, "org.freedesktop.systemd1.NoSuchUnit")) {
+                        sd_bus_error_set_const(error, "org.freedesktop.timedate1.NoNTPSupport", "NTP not supported.");
+                        return -ENOTSUP;
                 }
 
-                return 1;
+                return r;
         }
 
-        sd_bus_error_set_const(error, "org.freedesktop.timedate1.NoNTPSupport", "NTP not supported.");
-        return -ENOTSUP;
+        return 0;
 }
 
 static int context_enable_ntp(Context*c, sd_bus *bus, sd_bus_error *error) {
-        _cleanup_strv_free_ char **l = NULL;
-        char **i;
         int r;
 
         assert(c);
         assert(bus);
         assert(error);
 
-        l = get_ntp_services();
-        STRV_FOREACH(i, l) {
-                if (c->use_ntp)
-                        r = sd_bus_call_method(
-                                        bus,
-                                        "org.freedesktop.systemd1",
-                                        "/org/freedesktop/systemd1",
-                                        "org.freedesktop.systemd1.Manager",
-                                        "EnableUnitFiles",
-                                        error,
-                                        NULL,
-                                        "asbb", 1, *i, false, true);
-                else
-                        r = sd_bus_call_method(
-                                        bus,
-                                        "org.freedesktop.systemd1",
-                                        "/org/freedesktop/systemd1",
-                                        "org.freedesktop.systemd1.Manager",
-                                        "DisableUnitFiles",
-                                        error,
-                                        NULL,
-                                        "asb", 1, *i, false);
-
-                if (r < 0) {
-                        if (sd_bus_error_has_name(error, SD_BUS_ERROR_FILE_NOT_FOUND)) {
-                                /* This implementation does not exist, try next one */
-                                sd_bus_error_free(error);
-                                continue;
-                        }
-
-                        return r;
-                }
-
+        if (c->use_ntp)
                 r = sd_bus_call_method(
                                 bus,
                                 "org.freedesktop.systemd1",
                                 "/org/freedesktop/systemd1",
                                 "org.freedesktop.systemd1.Manager",
-                                "Reload",
+                                "EnableUnitFiles",
                                 error,
                                 NULL,
-                                NULL);
-                if (r < 0)
-                        return r;
+                                "asbb", 1,
+                                "systemd-timesyncd.service",
+                                false, true);
+        else
+                r = sd_bus_call_method(
+                                bus,
+                                "org.freedesktop.systemd1",
+                                "/org/freedesktop/systemd1",
+                                "org.freedesktop.systemd1.Manager",
+                                "DisableUnitFiles",
+                                error,
+                                NULL,
+                                "asb", 1,
+                                "systemd-timesyncd.service",
+                                false);
 
-                return 1;
+        if (r < 0) {
+                if (sd_bus_error_has_name(error, SD_BUS_ERROR_FILE_NOT_FOUND)) {
+                        sd_bus_error_set_const(error, "org.freedesktop.timedate1.NoNTPSupport", "NTP not supported.");
+                        return -ENOTSUP;
+                }
+
+                return r;
         }
 
-        sd_bus_error_set_const(error, "org.freedesktop.timedate1.NoNTPSupport", "NTP not supported.");
-        return -ENOTSUP;
+        r = sd_bus_call_method(
+                        bus,
+                        "org.freedesktop.systemd1",
+                        "/org/freedesktop/systemd1",
+                        "org.freedesktop.systemd1.Manager",
+                        "Reload",
+                        error,
+                        NULL,
+                        NULL);
+        if (r < 0)
+                return r;
+
+        return 0;
 }
 
 static int property_get_rtc_time(
@@ -466,12 +335,12 @@ static int property_get_rtc_time(
         int r;
 
         zero(tm);
-        r = hwclock_get_time(&tm);
+        r = clock_get_hwclock(&tm);
         if (r == -EBUSY) {
-                log_warning("/dev/rtc is busy, is somebody keeping it open continously? That's not a good idea... Returning a bogus RTC timestamp.");
+                log_warning("/dev/rtc is busy. Is somebody keeping it open continuously? That's not a good idea... Returning a bogus RTC timestamp.");
                 t = 0;
         } else if (r == -ENOENT) {
-                log_debug("Not /dev/rtc found.");
+                log_debug("/dev/rtc not found.");
                 t = 0; /* no RTC found */
         } else if (r < 0)
                 return sd_bus_error_set_errnof(error, r, "Failed to read RTC: %s", strerror(-r));
@@ -520,13 +389,13 @@ static int method_set_timezone(sd_bus *bus, sd_bus_message *m, void *userdata, s
         if (r < 0)
                 return r;
 
-        if (!valid_timezone(z))
+        if (!timezone_is_valid(z))
                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid time zone '%s'", z);
 
         if (streq_ptr(z, c->zone))
                 return sd_bus_reply_method_return(m, NULL);
 
-        r = bus_verify_polkit_async(bus, &c->polkit_registry, m, "org.freedesktop.timedate1.set-timezone", interactive, error, method_set_timezone, c);
+        r = bus_verify_polkit_async(m, CAP_SYS_TIME, "org.freedesktop.timedate1.set-timezone", interactive, &c->polkit_registry, error);
         if (r < 0)
                 return r;
         if (r == 0)
@@ -542,12 +411,12 @@ static int method_set_timezone(sd_bus *bus, sd_bus_message *m, void *userdata, s
         /* 1. Write new configuration file */
         r = context_write_data_timezone(c);
         if (r < 0) {
-                log_error("Failed to set timezone: %s", strerror(-r));
-                return sd_bus_error_set_errnof(error, r, "Failed to set timezone: %s", strerror(-r));
+                log_error("Failed to set time zone: %s", strerror(-r));
+                return sd_bus_error_set_errnof(error, r, "Failed to set time zone: %s", strerror(-r));
         }
 
         /* 2. Tell the kernel our timezone */
-        hwclock_set_timezone(NULL);
+        clock_set_timezone(NULL);
 
         if (c->local_rtc) {
                 struct timespec ts;
@@ -556,13 +425,13 @@ static int method_set_timezone(sd_bus *bus, sd_bus_message *m, void *userdata, s
                 /* 3. Sync RTC from system clock, with the new delta */
                 assert_se(clock_gettime(CLOCK_REALTIME, &ts) == 0);
                 assert_se(tm = localtime(&ts.tv_sec));
-                hwclock_set_time(tm);
+                clock_set_hwclock(tm);
         }
 
         log_struct(LOG_INFO,
                    MESSAGE_ID(SD_MESSAGE_TIMEZONE_CHANGE),
                    "TIMEZONE=%s", c->zone,
-                   "MESSAGE=Changed timezone to '%s'.", c->zone,
+                   "MESSAGE=Changed time zone to '%s'.", c->zone,
                    NULL);
 
         sd_bus_emit_properties_changed(bus, "/org/freedesktop/timedate1", "org.freedesktop.timedate1", "Timezone", NULL);
@@ -587,7 +456,7 @@ static int method_set_local_rtc(sd_bus *bus, sd_bus_message *m, void *userdata,
         if (lrtc == c->local_rtc)
                 return sd_bus_reply_method_return(m, NULL);
 
-        r = bus_verify_polkit_async(bus, &c->polkit_registry, m, "org.freedesktop.timedate1.set-local-rtc", interactive, error, method_set_local_rtc, c);
+        r = bus_verify_polkit_async(m, CAP_SYS_TIME, "org.freedesktop.timedate1.set-local-rtc", interactive, &c->polkit_registry, error);
         if (r < 0)
                 return r;
         if (r == 0)
@@ -603,7 +472,7 @@ static int method_set_local_rtc(sd_bus *bus, sd_bus_message *m, void *userdata,
         }
 
         /* 2. Tell the kernel our timezone */
-        hwclock_set_timezone(NULL);
+        clock_set_timezone(NULL);
 
         /* 3. Synchronize clocks */
         assert_se(clock_gettime(CLOCK_REALTIME, &ts) == 0);
@@ -622,7 +491,7 @@ static int method_set_local_rtc(sd_bus *bus, sd_bus_message *m, void *userdata,
                 /* Override the main fields of
                  * struct tm, but not the timezone
                  * fields */
-                if (hwclock_get_time(&tm) >= 0) {
+                if (clock_get_hwclock(&tm) >= 0) {
 
                         /* And set the system clock
                          * with this */
@@ -643,7 +512,7 @@ static int method_set_local_rtc(sd_bus *bus, sd_bus_message *m, void *userdata,
                 else
                         tm = gmtime(&ts.tv_sec);
 
-                hwclock_set_time(tm);
+                clock_set_hwclock(tm);
         }
 
         log_info("RTC configured to %s time.", c->local_rtc ? "local" : "UTC");
@@ -665,6 +534,9 @@ static int method_set_time(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bu
         assert(m);
         assert(c);
 
+        if (c->use_ntp)
+                return sd_bus_error_setf(error, BUS_ERROR_AUTOMATIC_TIME_SYNC_ENABLED, "Automatic time synchronization is enabled");
+
         r = sd_bus_message_read(m, "xbb", &utc, &relative, &interactive);
         if (r < 0)
                 return r;
@@ -689,7 +561,7 @@ static int method_set_time(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bu
         } else
                 timespec_store(&ts, (usec_t) utc);
 
-        r = bus_verify_polkit_async(bus, &c->polkit_registry, m, "org.freedesktop.timedate1.set-time", interactive, error, method_set_time, c);
+        r = bus_verify_polkit_async(m, CAP_SYS_TIME, "org.freedesktop.timedate1.set-time", interactive, &c->polkit_registry, error);
         if (r < 0)
                 return r;
         if (r == 0)
@@ -706,12 +578,11 @@ static int method_set_time(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bu
                 tm = localtime(&ts.tv_sec);
         else
                 tm = gmtime(&ts.tv_sec);
-
-        hwclock_set_time(tm);
+        clock_set_hwclock(tm);
 
         log_struct(LOG_INFO,
                    MESSAGE_ID(SD_MESSAGE_TIME_CHANGE),
-                   "REALTIME=%llu", (unsigned long long) timespec_load(&ts),
+                   "REALTIME="USEC_FMT, timespec_load(&ts),
                    "MESSAGE=Changed local time to %s", ctime(&ts.tv_sec),
                    NULL);
 
@@ -730,7 +601,7 @@ static int method_set_ntp(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus
         if ((bool)ntp == c->use_ntp)
                 return sd_bus_reply_method_return(m, NULL);
 
-        r = bus_verify_polkit_async(bus, &c->polkit_registry, m, "org.freedesktop.timedate1.set-ntp", interactive, error, method_set_ntp, c);
+        r = bus_verify_polkit_async(m, CAP_SYS_TIME, "org.freedesktop.timedate1.set-ntp", interactive, &c->polkit_registry, error);
         if (r < 0)
                 return r;
         if (r == 0)
@@ -753,14 +624,12 @@ static int method_set_ntp(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus
         return sd_bus_reply_method_return(m, NULL);
 }
 
-#include <sys/capability.h>
-
 static const sd_bus_vtable timedate_vtable[] = {
         SD_BUS_VTABLE_START(0),
         SD_BUS_PROPERTY("Timezone", "s", NULL, offsetof(Context, zone), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
-        SD_BUS_PROPERTY("LocalRTC", "b", NULL, offsetof(Context, local_rtc), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
-        SD_BUS_PROPERTY("CanNTP", "b", bus_property_get_tristate, offsetof(Context, can_ntp), 0),
-        SD_BUS_PROPERTY("NTP", "b", bus_property_get_tristate, offsetof(Context, use_ntp), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
+        SD_BUS_PROPERTY("LocalRTC", "b", bus_property_get_bool, offsetof(Context, local_rtc), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
+        SD_BUS_PROPERTY("CanNTP", "b", bus_property_get_bool, offsetof(Context, can_ntp), 0),
+        SD_BUS_PROPERTY("NTP", "b", bus_property_get_bool, offsetof(Context, use_ntp), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         SD_BUS_PROPERTY("NTPSynchronized", "b", property_get_ntp_sync, 0, 0),
         SD_BUS_PROPERTY("TimeUSec", "t", property_get_time, 0, 0),
         SD_BUS_PROPERTY("RTCTimeUSec", "t", property_get_rtc_time, 0, 0),
@@ -772,7 +641,7 @@ static const sd_bus_vtable timedate_vtable[] = {
 };
 
 static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) {
-        _cleanup_bus_unref_ sd_bus *bus = NULL;
+        _cleanup_bus_close_unref_ sd_bus *bus = NULL;
         int r;
 
         assert(c);
@@ -785,7 +654,7 @@ static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) {
                 return r;
         }
 
-        r = sd_bus_add_object_vtable(bus, "/org/freedesktop/timedate1", "org.freedesktop.timedate1", timedate_vtable, c);
+        r = sd_bus_add_object_vtable(bus, NULL, "/org/freedesktop/timedate1", "org.freedesktop.timedate1", timedate_vtable, c);
         if (r < 0) {
                 log_error("Failed to register object: %s", strerror(-r));
                 return r;
@@ -810,15 +679,9 @@ static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) {
 }
 
 int main(int argc, char *argv[]) {
-        Context context = {
-                .zone = NULL,
-                .local_rtc = false,
-                .can_ntp = -1,
-                .use_ntp = -1,
-        };
-
+        Context context = {};
         _cleanup_event_unref_ sd_event *event = NULL;
-        _cleanup_bus_unref_ sd_bus *bus = NULL;
+        _cleanup_bus_close_unref_ sd_bus *bus = NULL;
         int r;
 
         log_set_target(LOG_TARGET_AUTO);
@@ -847,7 +710,7 @@ int main(int argc, char *argv[]) {
 
         r = context_read_data(&context);
         if (r < 0) {
-                log_error("Failed to read timezone data: %s", strerror(-r));
+                log_error("Failed to read time zone data: %s", strerror(-r));
                 goto finish;
         }
 
@@ -864,7 +727,7 @@ int main(int argc, char *argv[]) {
         }
 
 finish:
-        context_free(&context, bus);
+        context_free(&context);
 
         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
 }
diff --git a/src/timesync/.gitignore b/src/timesync/.gitignore
new file mode 100644 (file)
index 0000000..35f4d76
--- /dev/null
@@ -0,0 +1,2 @@
+/timesyncd.conf
+/timesyncd-gperf.c
diff --git a/src/timesync/90-systemd.list b/src/timesync/90-systemd.list
new file mode 100644 (file)
index 0000000..d5959ad
--- /dev/null
@@ -0,0 +1 @@
+systemd-timesyncd.service
diff --git a/src/timesync/Makefile b/src/timesync/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/timesync/timesyncd-conf.c b/src/timesync/timesyncd-conf.c
new file mode 100644 (file)
index 0000000..4c2dcdb
--- /dev/null
@@ -0,0 +1,104 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Kay Sievers, Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "in-addr-util.h"
+
+#include "timesyncd-manager.h"
+#include "timesyncd-server.h"
+#include "timesyncd-conf.h"
+
+int manager_parse_server_string(Manager *m, ServerType type, const char *string) {
+        const char *word, *state;
+        size_t length;
+        ServerName *first;
+        int r;
+
+        assert(m);
+        assert(string);
+
+        first = type == SERVER_FALLBACK ? m->fallback_servers : m->system_servers;
+
+        FOREACH_WORD_QUOTED(word, length, string, state) {
+                char buffer[length+1];
+                bool found = false;
+                ServerName *n;
+
+                memcpy(buffer, word, length);
+                buffer[length] = 0;
+
+                /* Filter out duplicates */
+                LIST_FOREACH(names, n, first)
+                        if (streq_ptr(n->string, buffer)) {
+                                found = true;
+                                break;
+                        }
+
+                if (found)
+                        continue;
+
+                r = server_name_new(m, NULL, type, buffer);
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
+int config_parse_servers(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        Manager *m = userdata;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+
+        if (isempty(rvalue))
+                manager_flush_server_names(m, ltype);
+        else {
+                r = manager_parse_server_string(m, ltype, rvalue);
+                if (r < 0) {
+                        log_syntax(unit, LOG_ERR, filename, line, -r, "Failed to parse NTP server string '%s'. Ignoring.", rvalue);
+                        return 0;
+                }
+        }
+
+        return 0;
+}
+
+int manager_parse_config_file(Manager *m) {
+        assert(m);
+
+        return config_parse(NULL, "/etc/systemd/timesyncd.conf", NULL,
+                            "Time\0",
+                            config_item_perf_lookup, timesyncd_gperf_lookup,
+                            false, false, true, m);
+}
diff --git a/src/timesync/timesyncd-conf.h b/src/timesync/timesyncd-conf.h
new file mode 100644 (file)
index 0000000..56466fe
--- /dev/null
@@ -0,0 +1,34 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Kay Sievers, Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "conf-parser.h"
+
+#include "timesyncd-manager.h"
+
+const struct ConfigPerfItem* timesyncd_gperf_lookup(const char *key, unsigned length);
+
+int manager_parse_server_string(Manager *m, ServerType type, const char *string);
+
+int config_parse_servers(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+
+int manager_parse_config_file(Manager *m);
diff --git a/src/timesync/timesyncd-gperf.gperf b/src/timesync/timesyncd-gperf.gperf
new file mode 100644 (file)
index 0000000..29a2cfe
--- /dev/null
@@ -0,0 +1,19 @@
+%{
+#include <stddef.h>
+#include "conf-parser.h"
+#include "timesyncd-conf.h"
+%}
+struct ConfigPerfItem;
+%null_strings
+%language=ANSI-C
+%define slot-name section_and_lvalue
+%define hash-function-name timesyncdd_gperf_hash
+%define lookup-function-name timesyncd_gperf_lookup
+%readonly-tables
+%omit-struct-type
+%struct-type
+%includes
+%%
+Time.NTP,           config_parse_servers, SERVER_SYSTEM,   0
+Time.Servers,       config_parse_servers, SERVER_SYSTEM,   0
+Time.FallbackNTP,   config_parse_servers, SERVER_FALLBACK, 0
diff --git a/src/timesync/timesyncd-manager.c b/src/timesync/timesyncd-manager.c
new file mode 100644 (file)
index 0000000..d80c72f
--- /dev/null
@@ -0,0 +1,1120 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Kay Sievers, Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <time.h>
+#include <math.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <sys/timerfd.h>
+#include <sys/timex.h>
+#include <sys/socket.h>
+#include <resolv.h>
+#include <sys/prctl.h>
+#include <sys/types.h>
+#include <grp.h>
+
+#include "missing.h"
+#include "util.h"
+#include "sparse-endian.h"
+#include "log.h"
+#include "socket-util.h"
+#include "list.h"
+#include "ratelimit.h"
+#include "strv.h"
+#include "conf-parser.h"
+#include "sd-daemon.h"
+#include "event-util.h"
+#include "network-util.h"
+#include "clock-util.h"
+#include "capability.h"
+#include "mkdir.h"
+#include "timesyncd-conf.h"
+#include "timesyncd-manager.h"
+
+#define TIME_T_MAX (time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1)
+
+#ifndef ADJ_SETOFFSET
+#define ADJ_SETOFFSET                   0x0100  /* add 'time' to current time */
+#endif
+
+/* expected accuracy of time synchronization; used to adjust the poll interval */
+#define NTP_ACCURACY_SEC                0.2
+
+/*
+ * "A client MUST NOT under any conditions use a poll interval less
+ * than 15 seconds."
+ */
+#define NTP_POLL_INTERVAL_MIN_SEC       32
+#define NTP_POLL_INTERVAL_MAX_SEC       2048
+
+/*
+ * Maximum delta in seconds which the system clock is gradually adjusted
+ * (slew) to approach the network time. Deltas larger that this are set by
+ * letting the system time jump. The kernel's limit for adjtime is 0.5s.
+ */
+#define NTP_MAX_ADJUST                  0.4
+
+/* NTP protocol, packet header */
+#define NTP_LEAP_PLUSSEC                1
+#define NTP_LEAP_MINUSSEC               2
+#define NTP_LEAP_NOTINSYNC              3
+#define NTP_MODE_CLIENT                 3
+#define NTP_MODE_SERVER                 4
+#define NTP_FIELD_LEAP(f)               (((f) >> 6) & 3)
+#define NTP_FIELD_VERSION(f)            (((f) >> 3) & 7)
+#define NTP_FIELD_MODE(f)               ((f) & 7)
+#define NTP_FIELD(l, v, m)              (((l) << 6) | ((v) << 3) | (m))
+
+/*
+ * "NTP timestamps are represented as a 64-bit unsigned fixed-point number,
+ * in seconds relative to 0h on 1 January 1900."
+ */
+#define OFFSET_1900_1970        2208988800UL
+
+#define RETRY_USEC (30*USEC_PER_SEC)
+#define RATELIMIT_INTERVAL_USEC (10*USEC_PER_SEC)
+#define RATELIMIT_BURST 10
+
+#define TIMEOUT_USEC (10*USEC_PER_SEC)
+
+struct ntp_ts {
+        be32_t sec;
+        be32_t frac;
+} _packed_;
+
+struct ntp_ts_short {
+        be16_t sec;
+        be16_t frac;
+} _packed_;
+
+struct ntp_msg {
+        uint8_t field;
+        uint8_t stratum;
+        int8_t poll;
+        int8_t precision;
+        struct ntp_ts_short root_delay;
+        struct ntp_ts_short root_dispersion;
+        char refid[4];
+        struct ntp_ts reference_time;
+        struct ntp_ts origin_time;
+        struct ntp_ts recv_time;
+        struct ntp_ts trans_time;
+} _packed_;
+
+static int manager_arm_timer(Manager *m, usec_t next);
+static int manager_clock_watch_setup(Manager *m);
+
+static double ntp_ts_to_d(const struct ntp_ts *ts) {
+        return be32toh(ts->sec) + ((double)be32toh(ts->frac) / UINT_MAX);
+}
+
+static double ts_to_d(const struct timespec *ts) {
+        return ts->tv_sec + (1.0e-9 * ts->tv_nsec);
+}
+
+static double tv_to_d(const struct timeval *tv) {
+        return tv->tv_sec + (1.0e-6 * tv->tv_usec);
+}
+
+static double square(double d) {
+        return d * d;
+}
+
+static int manager_timeout(sd_event_source *source, usec_t usec, void *userdata) {
+        _cleanup_free_ char *pretty = NULL;
+        Manager *m = userdata;
+
+        assert(m);
+        assert(m->current_server_name);
+        assert(m->current_server_address);
+
+        server_address_pretty(m->current_server_address, &pretty);
+        log_info("Timed out waiting for reply from %s (%s).", strna(pretty), m->current_server_name->string);
+
+        return manager_connect(m);
+}
+
+static int manager_send_request(Manager *m) {
+        _cleanup_free_ char *pretty = NULL;
+        struct ntp_msg ntpmsg = {
+                /*
+                 * "The client initializes the NTP message header, sends the request
+                 * to the server, and strips the time of day from the Transmit
+                 * Timestamp field of the reply.  For this purpose, all the NTP
+                 * header fields are set to 0, except the Mode, VN, and optional
+                 * Transmit Timestamp fields."
+                 */
+                .field = NTP_FIELD(0, 4, NTP_MODE_CLIENT),
+        };
+        ssize_t len;
+        int r;
+
+        assert(m);
+        assert(m->current_server_name);
+        assert(m->current_server_address);
+
+        m->event_timeout = sd_event_source_unref(m->event_timeout);
+
+        /*
+         * Set transmit timestamp, remember it; the server will send that back
+         * as the origin timestamp and we have an indication that this is the
+         * matching answer to our request.
+         *
+         * The actual value does not matter, We do not care about the correct
+         * NTP UINT_MAX fraction; we just pass the plain nanosecond value.
+         */
+        assert_se(clock_gettime(clock_boottime_or_monotonic(), &m->trans_time_mon) >= 0);
+        assert_se(clock_gettime(CLOCK_REALTIME, &m->trans_time) >= 0);
+        ntpmsg.trans_time.sec = htobe32(m->trans_time.tv_sec + OFFSET_1900_1970);
+        ntpmsg.trans_time.frac = htobe32(m->trans_time.tv_nsec);
+
+        server_address_pretty(m->current_server_address, &pretty);
+
+        len = sendto(m->server_socket, &ntpmsg, sizeof(ntpmsg), MSG_DONTWAIT, &m->current_server_address->sockaddr.sa, m->current_server_address->socklen);
+        if (len == sizeof(ntpmsg)) {
+                m->pending = true;
+                log_debug("Sent NTP request to %s (%s).", strna(pretty), m->current_server_name->string);
+        } else {
+                log_debug("Sending NTP request to %s (%s) failed: %m", strna(pretty), m->current_server_name->string);
+                return manager_connect(m);
+        }
+
+        /* re-arm timer with increasing timeout, in case the packets never arrive back */
+        if (m->retry_interval > 0) {
+                if (m->retry_interval < NTP_POLL_INTERVAL_MAX_SEC * USEC_PER_SEC)
+                        m->retry_interval *= 2;
+        } else
+                m->retry_interval = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;
+
+        r = manager_arm_timer(m, m->retry_interval);
+        if (r < 0) {
+                log_error("Failed to rearm timer: %s", strerror(-r));
+                return r;
+        }
+
+        r = sd_event_add_time(
+                        m->event,
+                        &m->event_timeout,
+                        clock_boottime_or_monotonic(),
+                        now(clock_boottime_or_monotonic()) + TIMEOUT_USEC, 0,
+                        manager_timeout, m);
+        if (r < 0) {
+                log_error("Failed to arm timeout timer: %s", strerror(-r));
+                return r;
+        }
+
+        return 0;
+}
+
+static int manager_timer(sd_event_source *source, usec_t usec, void *userdata) {
+        Manager *m = userdata;
+
+        assert(m);
+
+        return manager_send_request(m);
+}
+
+static int manager_arm_timer(Manager *m, usec_t next) {
+        int r;
+
+        assert(m);
+        assert(m->event_receive);
+
+        if (next == 0) {
+                m->event_timer = sd_event_source_unref(m->event_timer);
+                return 0;
+        }
+
+        if (m->event_timer) {
+                r = sd_event_source_set_time(m->event_timer, now(clock_boottime_or_monotonic()) + next);
+                if (r < 0)
+                        return r;
+
+                return sd_event_source_set_enabled(m->event_timer, SD_EVENT_ONESHOT);
+        }
+
+        return sd_event_add_time(
+                        m->event,
+                        &m->event_timer,
+                        clock_boottime_or_monotonic(),
+                        now(clock_boottime_or_monotonic()) + next, 0,
+                        manager_timer, m);
+}
+
+static int manager_clock_watch(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
+        Manager *m = userdata;
+
+        assert(m);
+
+        /* rearm timer */
+        manager_clock_watch_setup(m);
+
+        /* skip our own jumps */
+        if (m->jumped) {
+                m->jumped = false;
+                return 0;
+        }
+
+        /* resync */
+        log_info("System time changed. Resyncing.");
+        m->poll_resync = true;
+
+        return manager_send_request(m);
+}
+
+/* wake up when the system time changes underneath us */
+static int manager_clock_watch_setup(Manager *m) {
+
+        struct itimerspec its = {
+                .it_value.tv_sec = TIME_T_MAX
+        };
+
+        int r;
+
+        assert(m);
+
+        m->event_clock_watch = sd_event_source_unref(m->event_clock_watch);
+        safe_close(m->clock_watch_fd);
+
+        m->clock_watch_fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK|TFD_CLOEXEC);
+        if (m->clock_watch_fd < 0) {
+                log_error("Failed to create timerfd: %m");
+                return -errno;
+        }
+
+        if (timerfd_settime(m->clock_watch_fd, TFD_TIMER_ABSTIME|TFD_TIMER_CANCEL_ON_SET, &its, NULL) < 0) {
+                log_error("Failed to set up timerfd: %m");
+                return -errno;
+        }
+
+        r = sd_event_add_io(m->event, &m->event_clock_watch, m->clock_watch_fd, EPOLLIN, manager_clock_watch, m);
+        if (r < 0) {
+                log_error("Failed to create clock watch event source: %s", strerror(-r));
+                return r;
+        }
+
+        return 0;
+}
+
+static int manager_adjust_clock(Manager *m, double offset, int leap_sec) {
+        struct timex tmx = {};
+        int r;
+
+        assert(m);
+
+        /*
+         * For small deltas, tell the kernel to gradually adjust the system
+         * clock to the NTP time, larger deltas are just directly set.
+         */
+        if (fabs(offset) < NTP_MAX_ADJUST) {
+                tmx.modes = ADJ_STATUS | ADJ_NANO | ADJ_OFFSET | ADJ_TIMECONST | ADJ_MAXERROR | ADJ_ESTERROR;
+                tmx.status = STA_PLL;
+                tmx.offset = offset * NSEC_PER_SEC;
+                tmx.constant = log2i(m->poll_interval_usec / USEC_PER_SEC) - 4;
+                tmx.maxerror = 0;
+                tmx.esterror = 0;
+                log_debug("  adjust (slew): %+.3f sec\n", offset);
+        } else {
+                tmx.modes = ADJ_STATUS | ADJ_NANO | ADJ_SETOFFSET;
+
+                /* ADJ_NANO uses nanoseconds in the microseconds field */
+                tmx.time.tv_sec = (long)offset;
+                tmx.time.tv_usec = (offset - tmx.time.tv_sec) * NSEC_PER_SEC;
+
+                /* the kernel expects -0.3s as {-1, 7000.000.000} */
+                if (tmx.time.tv_usec < 0) {
+                        tmx.time.tv_sec  -= 1;
+                        tmx.time.tv_usec += NSEC_PER_SEC;
+                }
+
+                m->jumped = true;
+                log_debug("  adjust (jump): %+.3f sec\n", offset);
+        }
+
+        /*
+         * An unset STA_UNSYNC will enable the kernel's 11-minute mode,
+         * which syncs the system time periodically to the RTC.
+         *
+         * In case the RTC runs in local time, never touch the RTC,
+         * we have no way to properly handle daylight saving changes and
+         * mobile devices moving between time zones.
+         */
+        if (m->rtc_local_time)
+                tmx.status |= STA_UNSYNC;
+
+        switch (leap_sec) {
+        case 1:
+                tmx.status |= STA_INS;
+                break;
+        case -1:
+                tmx.status |= STA_DEL;
+                break;
+        }
+
+        r = clock_adjtime(CLOCK_REALTIME, &tmx);
+        if (r < 0)
+                return r;
+
+        touch("/var/lib/systemd/clock");
+
+        m->drift_ppm = tmx.freq / 65536;
+
+        log_debug("  status       : %04i %s\n"
+                  "  time now     : %li.%03llu\n"
+                  "  constant     : %li\n"
+                  "  offset       : %+.3f sec\n"
+                  "  freq offset  : %+li (%i ppm)\n",
+                  tmx.status, tmx.status & STA_UNSYNC ? "unsync" : "sync",
+                  tmx.time.tv_sec, (unsigned long long) (tmx.time.tv_usec / NSEC_PER_MSEC),
+                  tmx.constant,
+                  (double)tmx.offset / NSEC_PER_SEC,
+                  tmx.freq, m->drift_ppm);
+
+        return 0;
+}
+
+static bool manager_sample_spike_detection(Manager *m, double offset, double delay) {
+        unsigned int i, idx_cur, idx_new, idx_min;
+        double jitter;
+        double j;
+
+        assert(m);
+
+        m->packet_count++;
+
+        /* ignore initial sample */
+        if (m->packet_count == 1)
+                return false;
+
+        /* store the current data in our samples array */
+        idx_cur = m->samples_idx;
+        idx_new = (idx_cur + 1) % ELEMENTSOF(m->samples);
+        m->samples_idx = idx_new;
+        m->samples[idx_new].offset = offset;
+        m->samples[idx_new].delay = delay;
+
+        /* calculate new jitter value from the RMS differences relative to the lowest delay sample */
+        jitter = m->samples_jitter;
+        for (idx_min = idx_cur, i = 0; i < ELEMENTSOF(m->samples); i++)
+                if (m->samples[i].delay > 0 && m->samples[i].delay < m->samples[idx_min].delay)
+                        idx_min = i;
+
+        j = 0;
+        for (i = 0; i < ELEMENTSOF(m->samples); i++)
+                j += square(m->samples[i].offset - m->samples[idx_min].offset);
+        m->samples_jitter = sqrt(j / (ELEMENTSOF(m->samples) - 1));
+
+        /* ignore samples when resyncing */
+        if (m->poll_resync)
+                return false;
+
+        /* always accept offset if we are farther off than the round-trip delay */
+        if (fabs(offset) > delay)
+                return false;
+
+        /* we need a few samples before looking at them */
+        if (m->packet_count < 4)
+                return false;
+
+        /* do not accept anything worse than the maximum possible error of the best sample */
+        if (fabs(offset) > m->samples[idx_min].delay)
+                return true;
+
+        /* compare the difference between the current offset to the previous offset and jitter */
+        return fabs(offset - m->samples[idx_cur].offset) > 3 * jitter;
+}
+
+static void manager_adjust_poll(Manager *m, double offset, bool spike) {
+        assert(m);
+
+        if (m->poll_resync) {
+                m->poll_interval_usec = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;
+                m->poll_resync = false;
+                return;
+        }
+
+        /* set to minimal poll interval */
+        if (!spike && fabs(offset) > NTP_ACCURACY_SEC) {
+                m->poll_interval_usec = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;
+                return;
+        }
+
+        /* increase polling interval */
+        if (fabs(offset) < NTP_ACCURACY_SEC * 0.25) {
+                if (m->poll_interval_usec < NTP_POLL_INTERVAL_MAX_SEC * USEC_PER_SEC)
+                        m->poll_interval_usec *= 2;
+                return;
+        }
+
+        /* decrease polling interval */
+        if (spike || fabs(offset) > NTP_ACCURACY_SEC * 0.75) {
+                if (m->poll_interval_usec > NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC)
+                        m->poll_interval_usec /= 2;
+                return;
+        }
+}
+
+static int manager_receive_response(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
+        Manager *m = userdata;
+        struct ntp_msg ntpmsg;
+
+        struct iovec iov = {
+                .iov_base = &ntpmsg,
+                .iov_len = sizeof(ntpmsg),
+        };
+        union {
+                struct cmsghdr cmsghdr;
+                uint8_t buf[CMSG_SPACE(sizeof(struct timeval))];
+        } control;
+        union sockaddr_union server_addr;
+        struct msghdr msghdr = {
+                .msg_iov = &iov,
+                .msg_iovlen = 1,
+                .msg_control = &control,
+                .msg_controllen = sizeof(control),
+                .msg_name = &server_addr,
+                .msg_namelen = sizeof(server_addr),
+        };
+        struct cmsghdr *cmsg;
+        struct timespec now_ts;
+        struct timeval *recv_time;
+        ssize_t len;
+        double origin, receive, trans, dest;
+        double delay, offset;
+        bool spike;
+        int leap_sec;
+        int r;
+
+        assert(source);
+        assert(m);
+
+        if (revents & (EPOLLHUP|EPOLLERR)) {
+                log_warning("Server connection returned error.");
+                return manager_connect(m);
+        }
+
+        len = recvmsg(fd, &msghdr, MSG_DONTWAIT);
+        if (len < 0) {
+                if (errno == EAGAIN)
+                        return 0;
+
+                log_warning("Error receiving message. Disconnecting.");
+                return manager_connect(m);
+        }
+
+        if (iov.iov_len < sizeof(struct ntp_msg)) {
+                log_warning("Invalid response from server. Disconnecting.");
+                return manager_connect(m);
+        }
+
+        if (!m->current_server_name ||
+            !m->current_server_address ||
+            !sockaddr_equal(&server_addr, &m->current_server_address->sockaddr)) {
+                log_debug("Response from unknown server.");
+                return 0;
+        }
+
+        recv_time = NULL;
+        for (cmsg = CMSG_FIRSTHDR(&msghdr); cmsg; cmsg = CMSG_NXTHDR(&msghdr, cmsg)) {
+                if (cmsg->cmsg_level != SOL_SOCKET)
+                        continue;
+
+                switch (cmsg->cmsg_type) {
+                case SCM_TIMESTAMP:
+                        recv_time = (struct timeval *) CMSG_DATA(cmsg);
+                        break;
+                }
+        }
+        if (!recv_time) {
+                log_error("Invalid packet timestamp.");
+                return -EINVAL;
+        }
+
+        if (!m->pending) {
+                log_debug("Unexpected reply. Ignoring.");
+                return 0;
+        }
+
+        /* check our "time cookie" (we just stored nanoseconds in the fraction field) */
+        if (be32toh(ntpmsg.origin_time.sec) != m->trans_time.tv_sec + OFFSET_1900_1970 ||
+            be32toh(ntpmsg.origin_time.frac) != m->trans_time.tv_nsec) {
+                log_debug("Invalid reply; not our transmit time. Ignoring.");
+                return 0;
+        }
+
+        m->event_timeout = sd_event_source_unref(m->event_timeout);
+
+        if (be32toh(ntpmsg.recv_time.sec) < TIME_EPOCH + OFFSET_1900_1970 ||
+            be32toh(ntpmsg.trans_time.sec) < TIME_EPOCH + OFFSET_1900_1970) {
+                log_debug("Invalid reply, returned times before epoch. Ignoring.");
+                return manager_connect(m);
+        }
+
+        if (NTP_FIELD_LEAP(ntpmsg.field) == NTP_LEAP_NOTINSYNC) {
+                log_debug("Server is not synchronized. Disconnecting.");
+                return manager_connect(m);
+        }
+
+        if (!IN_SET(NTP_FIELD_VERSION(ntpmsg.field), 3, 4)) {
+                log_debug("Response NTPv%d. Disconnecting.", NTP_FIELD_VERSION(ntpmsg.field));
+                return manager_connect(m);
+        }
+
+        if (NTP_FIELD_MODE(ntpmsg.field) != NTP_MODE_SERVER) {
+                log_debug("Unsupported mode %d. Disconnecting.", NTP_FIELD_MODE(ntpmsg.field));
+                return manager_connect(m);
+        }
+
+        /* valid packet */
+        m->pending = false;
+        m->retry_interval = 0;
+
+        /* announce leap seconds */
+        if (NTP_FIELD_LEAP(ntpmsg.field) & NTP_LEAP_PLUSSEC)
+                leap_sec = 1;
+        else if (NTP_FIELD_LEAP(ntpmsg.field) & NTP_LEAP_MINUSSEC)
+                leap_sec = -1;
+        else
+                leap_sec = 0;
+
+        /*
+         * "Timestamp Name          ID   When Generated
+         *  ------------------------------------------------------------
+         *  Originate Timestamp     T1   time request sent by client
+         *  Receive Timestamp       T2   time request received by server
+         *  Transmit Timestamp      T3   time reply sent by server
+         *  Destination Timestamp   T4   time reply received by client
+         *
+         *  The round-trip delay, d, and system clock offset, t, are defined as:
+         *  d = (T4 - T1) - (T3 - T2)     t = ((T2 - T1) + (T3 - T4)) / 2"
+         */
+        assert_se(clock_gettime(clock_boottime_or_monotonic(), &now_ts) >= 0);
+        origin = tv_to_d(recv_time) - (ts_to_d(&now_ts) - ts_to_d(&m->trans_time_mon)) + OFFSET_1900_1970;
+        receive = ntp_ts_to_d(&ntpmsg.recv_time);
+        trans = ntp_ts_to_d(&ntpmsg.trans_time);
+        dest = tv_to_d(recv_time) + OFFSET_1900_1970;
+
+        offset = ((receive - origin) + (trans - dest)) / 2;
+        delay = (dest - origin) - (trans - receive);
+
+        spike = manager_sample_spike_detection(m, offset, delay);
+
+        manager_adjust_poll(m, offset, spike);
+
+        log_debug("NTP response:\n"
+                  "  leap         : %u\n"
+                  "  version      : %u\n"
+                  "  mode         : %u\n"
+                  "  stratum      : %u\n"
+                  "  precision    : %.6f sec (%d)\n"
+                  "  reference    : %.4s\n"
+                  "  origin       : %.3f\n"
+                  "  receive      : %.3f\n"
+                  "  transmit     : %.3f\n"
+                  "  dest         : %.3f\n"
+                  "  offset       : %+.3f sec\n"
+                  "  delay        : %+.3f sec\n"
+                  "  packet count : %"PRIu64"\n"
+                  "  jitter       : %.3f%s\n"
+                  "  poll interval: " USEC_FMT "\n",
+                  NTP_FIELD_LEAP(ntpmsg.field),
+                  NTP_FIELD_VERSION(ntpmsg.field),
+                  NTP_FIELD_MODE(ntpmsg.field),
+                  ntpmsg.stratum,
+                  exp2(ntpmsg.precision), ntpmsg.precision,
+                  ntpmsg.stratum == 1 ? ntpmsg.refid : "n/a",
+                  origin - OFFSET_1900_1970,
+                  receive - OFFSET_1900_1970,
+                  trans - OFFSET_1900_1970,
+                  dest - OFFSET_1900_1970,
+                  offset, delay,
+                  m->packet_count,
+                  m->samples_jitter, spike ? " spike" : "",
+                  m->poll_interval_usec / USEC_PER_SEC);
+
+        if (!spike) {
+                m->sync = true;
+                r = manager_adjust_clock(m, offset, leap_sec);
+                if (r < 0)
+                        log_error("Failed to call clock_adjtime(): %m");
+        }
+
+        log_info("interval/delta/delay/jitter/drift " USEC_FMT "s/%+.3fs/%.3fs/%.3fs/%+ippm%s",
+                 m->poll_interval_usec / USEC_PER_SEC, offset, delay, m->samples_jitter, m->drift_ppm,
+                 spike ? " (ignored)" : "");
+
+        r = manager_arm_timer(m, m->poll_interval_usec);
+        if (r < 0) {
+                log_error("Failed to rearm timer: %s", strerror(-r));
+                return r;
+        }
+
+        return 0;
+}
+
+static int manager_listen_setup(Manager *m) {
+        union sockaddr_union addr = {};
+        static const int tos = IPTOS_LOWDELAY;
+        static const int on = 1;
+        int r;
+
+        assert(m);
+
+        assert(m->server_socket < 0);
+        assert(!m->event_receive);
+        assert(m->current_server_address);
+
+        addr.sa.sa_family = m->current_server_address->sockaddr.sa.sa_family;
+
+        m->server_socket = socket(addr.sa.sa_family, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+        if (m->server_socket < 0)
+                return -errno;
+
+        r = bind(m->server_socket, &addr.sa, m->current_server_address->socklen);
+        if (r < 0)
+                return -errno;
+
+        r = setsockopt(m->server_socket, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on));
+        if (r < 0)
+                return -errno;
+
+        setsockopt(m->server_socket, IPPROTO_IP, IP_TOS, &tos, sizeof(tos));
+
+        return sd_event_add_io(m->event, &m->event_receive, m->server_socket, EPOLLIN, manager_receive_response, m);
+}
+
+static int manager_begin(Manager *m) {
+        _cleanup_free_ char *pretty = NULL;
+        int r;
+
+        assert(m);
+        assert_return(m->current_server_name, -EHOSTUNREACH);
+        assert_return(m->current_server_address, -EHOSTUNREACH);
+
+        m->poll_interval_usec = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;
+
+        server_address_pretty(m->current_server_address, &pretty);
+        log_info("Using NTP server %s (%s).", strna(pretty), m->current_server_name->string);
+        sd_notifyf(false, "STATUS=Using Time Server %s (%s).", strna(pretty), m->current_server_name->string);
+
+        r = manager_listen_setup(m);
+        if (r < 0) {
+                log_warning("Failed to setup connection socket: %s", strerror(-r));
+                return r;
+        }
+
+        r = manager_clock_watch_setup(m);
+        if (r < 0)
+                return r;
+
+        return manager_send_request(m);
+}
+
+void manager_set_server_name(Manager *m, ServerName *n) {
+        assert(m);
+
+        if (m->current_server_name == n)
+                return;
+
+        m->current_server_name = n;
+        m->current_server_address = NULL;
+
+        manager_disconnect(m);
+
+        if (n)
+                log_debug("Selected server %s.", n->string);
+}
+
+void manager_set_server_address(Manager *m, ServerAddress *a) {
+        assert(m);
+
+        if (m->current_server_address == a)
+                return;
+
+        m->current_server_name = a ? a->name : NULL;
+        m->current_server_address = a;
+
+        manager_disconnect(m);
+
+        if (a) {
+                _cleanup_free_ char *pretty = NULL;
+                server_address_pretty(a, &pretty);
+                log_debug("Selected address %s of server %s.", strna(pretty), a->name->string);
+        }
+}
+
+static int manager_resolve_handler(sd_resolve_query *q, int ret, const struct addrinfo *ai, void *userdata) {
+        Manager *m = userdata;
+        int r;
+
+        assert(q);
+        assert(m);
+        assert(m->current_server_name);
+
+        m->resolve_query = sd_resolve_query_unref(m->resolve_query);
+
+        if (ret != 0) {
+                log_debug("Failed to resolve %s: %s", m->current_server_name->string, gai_strerror(ret));
+
+                /* Try next host */
+                return manager_connect(m);
+        }
+
+        for (; ai; ai = ai->ai_next) {
+                _cleanup_free_ char *pretty = NULL;
+                ServerAddress *a;
+
+                assert(ai->ai_addr);
+                assert(ai->ai_addrlen >= offsetof(struct sockaddr, sa_data));
+
+                if (!IN_SET(ai->ai_addr->sa_family, AF_INET, AF_INET6)) {
+                        log_warning("Unsuitable address protocol for %s", m->current_server_name->string);
+                        continue;
+                }
+
+                r = server_address_new(m->current_server_name, &a, (const union sockaddr_union*) ai->ai_addr, ai->ai_addrlen);
+                if (r < 0) {
+                        log_error("Failed to add server address: %s", strerror(-r));
+                        return r;
+                }
+
+                server_address_pretty(a, &pretty);
+                log_debug("Resolved address %s for %s.", pretty, m->current_server_name->string);
+        }
+
+        if (!m->current_server_name->addresses) {
+                log_error("Failed to find suitable address for host %s.", m->current_server_name->string);
+
+                /* Try next host */
+                return manager_connect(m);
+        }
+
+        manager_set_server_address(m, m->current_server_name->addresses);
+
+        return manager_begin(m);
+}
+
+static int manager_retry_connect(sd_event_source *source, usec_t usec, void *userdata) {
+        Manager *m = userdata;
+
+        assert(m);
+
+        return manager_connect(m);
+}
+
+int manager_connect(Manager *m) {
+        int r;
+
+        assert(m);
+
+        manager_disconnect(m);
+
+        m->event_retry = sd_event_source_unref(m->event_retry);
+        if (!ratelimit_test(&m->ratelimit)) {
+                log_debug("Slowing down attempts to contact servers.");
+
+                r = sd_event_add_time(m->event, &m->event_retry, clock_boottime_or_monotonic(), now(clock_boottime_or_monotonic()) + RETRY_USEC, 0, manager_retry_connect, m);
+                if (r < 0) {
+                        log_error("Failed to create retry timer: %s", strerror(-r));
+                        return r;
+                }
+
+                return 0;
+        }
+
+        /* If we already are operating on some address, switch to the
+         * next one. */
+        if (m->current_server_address && m->current_server_address->addresses_next)
+                manager_set_server_address(m, m->current_server_address->addresses_next);
+        else {
+                struct addrinfo hints = {
+                        .ai_flags = AI_NUMERICSERV|AI_ADDRCONFIG,
+                        .ai_socktype = SOCK_DGRAM,
+                };
+
+                /* Hmm, we are through all addresses, let's look for the next host instead */
+                if (m->current_server_name && m->current_server_name->names_next)
+                        manager_set_server_name(m, m->current_server_name->names_next);
+                else {
+                        ServerName *f;
+
+                        /* Our current server name list is exhausted,
+                         * let's find the next one to iterate. First
+                         * we try the system list, then the link list.
+                         * After having processed the link list we
+                         * jump back to the system list. However, if
+                         * both lists are empty, we change to the
+                         * fallback list. */
+                        if (!m->current_server_name || m->current_server_name->type == SERVER_LINK) {
+                                f = m->system_servers;
+                                if (!f)
+                                        f = m->link_servers;
+                        } else {
+                                f = m->link_servers;
+                                if (!f)
+                                        f = m->system_servers;
+                        }
+
+                        if (!f)
+                                f = m->fallback_servers;
+
+                        if (!f) {
+                                manager_set_server_name(m, NULL);
+                                log_debug("No server found.");
+                                return 0;
+                        }
+
+                        manager_set_server_name(m, f);
+                }
+
+                /* Tell the resolver to reread /etc/resolv.conf, in
+                 * case it changed. */
+                res_init();
+
+                /* Flush out any previously resolved addresses */
+                server_name_flush_addresses(m->current_server_name);
+
+                log_debug("Resolving %s...", m->current_server_name->string);
+
+                r = sd_resolve_getaddrinfo(m->resolve, &m->resolve_query, m->current_server_name->string, "123", &hints, manager_resolve_handler, m);
+                if (r < 0) {
+                        log_error("Failed to create resolver: %s", strerror(-r));
+                        return r;
+                }
+
+                return 1;
+        }
+
+        r = manager_begin(m);
+        if (r < 0)
+                return r;
+
+        return 1;
+}
+
+void manager_disconnect(Manager *m) {
+        assert(m);
+
+        m->resolve_query = sd_resolve_query_unref(m->resolve_query);
+
+        m->event_timer = sd_event_source_unref(m->event_timer);
+
+        m->event_receive = sd_event_source_unref(m->event_receive);
+        m->server_socket = safe_close(m->server_socket);
+
+        m->event_clock_watch = sd_event_source_unref(m->event_clock_watch);
+        m->clock_watch_fd = safe_close(m->clock_watch_fd);
+
+        m->event_timeout = sd_event_source_unref(m->event_timeout);
+
+        sd_notifyf(false, "STATUS=Idle.");
+}
+
+void manager_flush_server_names(Manager  *m, ServerType t) {
+        assert(m);
+
+        if (t == SERVER_SYSTEM)
+                while (m->system_servers)
+                        server_name_free(m->system_servers);
+
+        if (t == SERVER_LINK)
+                while (m->link_servers)
+                        server_name_free(m->link_servers);
+
+        if (t == SERVER_FALLBACK)
+                while (m->fallback_servers)
+                        server_name_free(m->fallback_servers);
+}
+
+void manager_free(Manager *m) {
+        if (!m)
+                return;
+
+        manager_disconnect(m);
+        manager_flush_server_names(m, SERVER_SYSTEM);
+        manager_flush_server_names(m, SERVER_LINK);
+        manager_flush_server_names(m, SERVER_FALLBACK);
+
+        sd_event_source_unref(m->event_retry);
+
+        sd_event_source_unref(m->network_event_source);
+        sd_network_monitor_unref(m->network_monitor);
+
+        sd_resolve_unref(m->resolve);
+        sd_event_unref(m->event);
+
+        free(m);
+}
+
+static int manager_network_read_link_servers(Manager *m) {
+        _cleanup_strv_free_ char **ntp = NULL;
+        ServerName *n, *nx;
+        char **i;
+        int r;
+
+        assert(m);
+
+        r = sd_network_get_ntp(&ntp);
+        if (r < 0)
+                goto clear;
+
+        LIST_FOREACH(names, n, m->link_servers)
+                n->marked = true;
+
+        STRV_FOREACH(i, ntp) {
+                bool found = false;
+
+                LIST_FOREACH(names, n, m->link_servers)
+                        if (streq(n->string, *i)) {
+                                n->marked = false;
+                                found = true;
+                                break;
+                        }
+
+                if (!found) {
+                        r = server_name_new(m, NULL, SERVER_LINK, *i);
+                        if (r < 0)
+                                goto clear;
+                }
+        }
+
+        LIST_FOREACH_SAFE(names, n, nx, m->link_servers)
+                if (n->marked)
+                        server_name_free(n);
+
+        return 0;
+
+clear:
+        manager_flush_server_names(m, SERVER_LINK);
+        return r;
+}
+
+static int manager_network_event_handler(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
+        Manager *m = userdata;
+        bool connected, online;
+        int r;
+
+        assert(m);
+
+        sd_network_monitor_flush(m->network_monitor);
+
+        manager_network_read_link_servers(m);
+
+        /* check if the machine is online */
+        online = network_is_online();
+
+        /* check if the client is currently connected */
+        connected = m->server_socket >= 0 || m->resolve_query;
+
+        if (connected && !online) {
+                log_info("No network connectivity, watching for changes.");
+                manager_disconnect(m);
+
+        } else if (!connected && online) {
+                log_info("Network configuration changed, trying to establish connection.");
+
+                if (m->current_server_address)
+                        r = manager_begin(m);
+                else
+                        r = manager_connect(m);
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
+static int manager_network_monitor_listen(Manager *m) {
+        int r, fd, events;
+
+        assert(m);
+
+        r = sd_network_monitor_new(&m->network_monitor, NULL);
+        if (r < 0)
+                return r;
+
+        fd = sd_network_monitor_get_fd(m->network_monitor);
+        if (fd < 0)
+                return fd;
+
+        events = sd_network_monitor_get_events(m->network_monitor);
+        if (events < 0)
+                return events;
+
+        r = sd_event_add_io(m->event, &m->network_event_source, fd, events, manager_network_event_handler, m);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+int manager_new(Manager **ret) {
+        _cleanup_(manager_freep) Manager *m = NULL;
+        int r;
+
+        assert(ret);
+
+        m = new0(Manager, 1);
+        if (!m)
+                return -ENOMEM;
+
+        m->server_socket = m->clock_watch_fd = -1;
+
+        RATELIMIT_INIT(m->ratelimit, RATELIMIT_INTERVAL_USEC, RATELIMIT_BURST);
+
+        r = manager_parse_server_string(m, SERVER_FALLBACK, NTP_SERVERS);
+        if (r < 0)
+                return r;
+
+        r = sd_event_default(&m->event);
+        if (r < 0)
+                return r;
+
+        sd_event_add_signal(m->event, NULL, SIGTERM, NULL,  NULL);
+        sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
+
+        sd_event_set_watchdog(m->event, true);
+
+        r = sd_resolve_default(&m->resolve);
+        if (r < 0)
+                return r;
+
+        r = sd_resolve_attach_event(m->resolve, m->event, 0);
+        if (r < 0)
+                return r;
+
+        r = manager_network_monitor_listen(m);
+        if (r < 0)
+                return r;
+
+        manager_network_read_link_servers(m);
+
+        *ret = m;
+        m = NULL;
+
+        return 0;
+}
diff --git a/src/timesync/timesyncd-manager.h b/src/timesync/timesyncd-manager.h
new file mode 100644 (file)
index 0000000..2345bf8
--- /dev/null
@@ -0,0 +1,103 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Kay Sievers, Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "sd-event.h"
+#include "sd-resolve.h"
+#include "sd-network.h"
+#include "list.h"
+#include "socket-util.h"
+#include "ratelimit.h"
+
+typedef struct Manager Manager;
+
+#include "timesyncd-server.h"
+
+struct Manager {
+        sd_event *event;
+        sd_resolve *resolve;
+
+        LIST_HEAD(ServerName, system_servers);
+        LIST_HEAD(ServerName, link_servers);
+        LIST_HEAD(ServerName, fallback_servers);
+
+        RateLimit ratelimit;
+
+        /* network */
+        sd_event_source *network_event_source;
+        sd_network_monitor *network_monitor;
+
+        /* peer */
+        sd_resolve_query *resolve_query;
+        sd_event_source *event_receive;
+        ServerName *current_server_name;
+        ServerAddress *current_server_address;
+        int server_socket;
+        uint64_t packet_count;
+        sd_event_source *event_timeout;
+
+        /* last sent packet */
+        struct timespec trans_time_mon;
+        struct timespec trans_time;
+        usec_t retry_interval;
+        bool pending;
+
+        /* poll timer */
+        sd_event_source *event_timer;
+        usec_t poll_interval_usec;
+        bool poll_resync;
+
+        /* history data */
+        struct {
+                double offset;
+                double delay;
+        } samples[8];
+        unsigned int samples_idx;
+        double samples_jitter;
+
+        /* last change */
+        bool jumped;
+        bool sync;
+        int drift_ppm;
+
+        /* watch for time changes */
+        sd_event_source *event_clock_watch;
+        int clock_watch_fd;
+
+        /* Retry connections */
+        sd_event_source *event_retry;
+
+        /* RTC runs in local time, leave it alone */
+        bool rtc_local_time;
+};
+
+int manager_new(Manager **ret);
+void manager_free(Manager *m);
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
+
+void manager_set_server_name(Manager *m, ServerName *n);
+void manager_set_server_address(Manager *m, ServerAddress *a);
+void manager_flush_server_names(Manager *m, ServerType t);
+
+int manager_connect(Manager *m);
+void manager_disconnect(Manager *m);
diff --git a/src/timesync/timesyncd-server.c b/src/timesync/timesyncd-server.c
new file mode 100644 (file)
index 0000000..ec3fe1f
--- /dev/null
@@ -0,0 +1,151 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Kay Sievers, Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "timesyncd-server.h"
+
+int server_address_new(
+                ServerName *n,
+                ServerAddress **ret,
+                const union sockaddr_union *sockaddr,
+                socklen_t socklen) {
+
+        ServerAddress *a, *tail;
+
+        assert(n);
+        assert(sockaddr);
+        assert(socklen >= offsetof(struct sockaddr, sa_data));
+        assert(socklen <= sizeof(union sockaddr_union));
+
+        a = new0(ServerAddress, 1);
+        if (!a)
+                return -ENOMEM;
+
+        memcpy(&a->sockaddr, sockaddr, socklen);
+        a->socklen = socklen;
+
+        LIST_FIND_TAIL(addresses, n->addresses, tail);
+        LIST_INSERT_AFTER(addresses, n->addresses, tail, a);
+        a->name = n;
+
+        if (ret)
+                *ret = a;
+
+        return 0;
+}
+
+ServerAddress* server_address_free(ServerAddress *a) {
+        if (!a)
+                return NULL;
+
+        if (a->name) {
+                LIST_REMOVE(addresses, a->name->addresses, a);
+
+                if (a->name->manager && a->name->manager->current_server_address == a)
+                        manager_set_server_address(a->name->manager, NULL);
+        }
+
+        free(a);
+        return NULL;
+}
+
+int server_name_new(
+                Manager *m,
+                ServerName **ret,
+                ServerType type,
+                const char *string) {
+
+        ServerName *n, *tail;
+
+        assert(m);
+        assert(string);
+
+        n = new0(ServerName, 1);
+        if (!n)
+                return -ENOMEM;
+
+        n->type = type;
+        n->string = strdup(string);
+        if (!n->string) {
+                free(n);
+                return -ENOMEM;
+        }
+
+        if (type == SERVER_SYSTEM) {
+                LIST_FIND_TAIL(names, m->system_servers, tail);
+                LIST_INSERT_AFTER(names, m->system_servers, tail, n);
+        } else if (type == SERVER_LINK) {
+                LIST_FIND_TAIL(names, m->link_servers, tail);
+                LIST_INSERT_AFTER(names, m->link_servers, tail, n);
+        } else if (type == SERVER_FALLBACK) {
+                LIST_FIND_TAIL(names, m->fallback_servers, tail);
+                LIST_INSERT_AFTER(names, m->fallback_servers, tail, n);
+        } else
+                assert_not_reached("Unknown server type");
+
+        n->manager = m;
+
+        if (type != SERVER_FALLBACK &&
+            m->current_server_name &&
+            m->current_server_name->type == SERVER_FALLBACK)
+                manager_set_server_name(m, NULL);
+
+        log_debug("Added new server %s.", string);
+
+        if (ret)
+                *ret = n;
+
+        return 0;
+}
+
+ServerName *server_name_free(ServerName *n) {
+        if (!n)
+                return NULL;
+
+        server_name_flush_addresses(n);
+
+        if (n->manager) {
+                if (n->type == SERVER_SYSTEM)
+                        LIST_REMOVE(names, n->manager->system_servers, n);
+                else if (n->type == SERVER_LINK)
+                        LIST_REMOVE(names, n->manager->link_servers, n);
+                else if (n->type == SERVER_FALLBACK)
+                        LIST_REMOVE(names, n->manager->fallback_servers, n);
+                else
+                        assert_not_reached("Unknown server type");
+
+                if (n->manager->current_server_name == n)
+                        manager_set_server_name(n->manager, NULL);
+        }
+
+        log_debug("Removed server %s.", n->string);
+
+        free(n->string);
+        free(n);
+
+        return NULL;
+}
+
+void server_name_flush_addresses(ServerName *n) {
+        assert(n);
+
+        while (n->addresses)
+                server_address_free(n->addresses);
+}
diff --git a/src/timesync/timesyncd-server.h b/src/timesync/timesyncd-server.h
new file mode 100644 (file)
index 0000000..243b44a
--- /dev/null
@@ -0,0 +1,67 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Kay Sievers, Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "socket-util.h"
+#include "list.h"
+
+typedef struct ServerAddress ServerAddress;
+typedef struct ServerName ServerName;
+
+typedef enum ServerType {
+        SERVER_SYSTEM,
+        SERVER_FALLBACK,
+        SERVER_LINK,
+} ServerType;
+
+#include "timesyncd-manager.h"
+
+struct ServerAddress {
+        ServerName *name;
+
+        union sockaddr_union sockaddr;
+        socklen_t socklen;
+
+        LIST_FIELDS(ServerAddress, addresses);
+};
+
+struct ServerName {
+        Manager *manager;
+
+        ServerType type;
+        char *string;
+
+        bool marked:1;
+
+        LIST_HEAD(ServerAddress, addresses);
+        LIST_FIELDS(ServerName, names);
+};
+
+int server_address_new(ServerName *n, ServerAddress **ret, const union sockaddr_union *sockaddr, socklen_t socklen);
+ServerAddress* server_address_free(ServerAddress *a);
+static inline int server_address_pretty(ServerAddress *a, char **pretty) {
+        return sockaddr_pretty(&a->sockaddr.sa, a->socklen, true, pretty);
+}
+
+int server_name_new(Manager *m, ServerName **ret, ServerType type,const char *string);
+ServerName *server_name_free(ServerName *n);
+void server_name_flush_addresses(ServerName *n);
diff --git a/src/timesync/timesyncd.c b/src/timesync/timesyncd.c
new file mode 100644 (file)
index 0000000..351bfd0
--- /dev/null
@@ -0,0 +1,159 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Kay Sievers, Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "sd-event.h"
+#include "sd-daemon.h"
+#include "mkdir.h"
+#include "capability.h"
+#include "clock-util.h"
+#include "network-util.h"
+
+#include "timesyncd-manager.h"
+#include "timesyncd-conf.h"
+
+static int load_clock_timestamp(uid_t uid, gid_t gid) {
+        _cleanup_close_ int fd = -1;
+        usec_t min = TIME_EPOCH * USEC_PER_SEC;
+        usec_t ct;
+        int r;
+
+        /* Let's try to make sure that the clock is always
+         * monotonically increasing, by saving the clock whenever we
+         * have a new NTP time, or when we shut down, and restoring it
+         * when we start again. This is particularly helpful on
+         * systems lacking a battery backed RTC. We also will adjust
+         * the time to at least the build time of systemd. */
+
+        fd = open("/var/lib/systemd/clock", O_RDWR|O_CLOEXEC, 0644);
+        if (fd >= 0) {
+                struct stat st;
+                usec_t stamp;
+
+                /* check if the recorded time is later than the compiled-in one */
+                r = fstat(fd, &st);
+                if (r >= 0) {
+                        stamp = timespec_load(&st.st_mtim);
+                        if (stamp > min)
+                                min = stamp;
+                }
+
+                /* Try to fix the access mode, so that we can still
+                   touch the file after dropping priviliges */
+                fchmod(fd, 0644);
+                fchown(fd, uid, gid);
+
+        } else
+                /* create stamp file with the compiled-in date */
+                touch_file("/var/lib/systemd/clock", true, min, uid, gid, 0644);
+
+        ct = now(CLOCK_REALTIME);
+        if (ct < min) {
+                struct timespec ts;
+                char date[FORMAT_TIMESTAMP_MAX];
+
+                log_info("System clock time unset or jumped backwards, restoring from recorded timestamp: %s",
+                         format_timestamp(date, sizeof(date), min));
+
+                if (clock_settime(CLOCK_REALTIME, timespec_store(&ts, min)) < 0)
+                        log_error("Failed to restore system clock: %m");
+        }
+
+        return 0;
+}
+
+int main(int argc, char *argv[]) {
+        _cleanup_(manager_freep) Manager *m = NULL;
+        const char *user = "systemd-timesync";
+        uid_t uid;
+        gid_t gid;
+        int r;
+
+        log_set_target(LOG_TARGET_AUTO);
+        log_set_facility(LOG_CRON);
+        log_parse_environment();
+        log_open();
+
+        umask(0022);
+
+        if (argc != 1) {
+                log_error("This program does not take arguments.");
+                r = -EINVAL;
+                goto finish;
+        }
+
+        r = get_user_creds(&user, &uid, &gid, NULL, NULL);
+        if (r < 0) {
+                log_error("Cannot resolve user name %s: %s", user, strerror(-r));
+                goto finish;
+        }
+
+        r = load_clock_timestamp(uid, gid);
+        if (r < 0)
+                goto finish;
+
+        r = drop_privileges(uid, gid, (1ULL << CAP_SYS_TIME));
+        if (r < 0)
+                goto finish;
+
+        assert_se(sigprocmask_many(SIG_BLOCK, SIGTERM, SIGINT, -1) == 0);
+
+        r = manager_new(&m);
+        if (r < 0) {
+                log_error("Failed to allocate manager: %s", strerror(-r));
+                goto finish;
+        }
+
+        if (clock_is_localtime() > 0) {
+                log_info("The system is configured to read the RTC time in the local time zone. "
+                         "This mode can not be fully supported. All system time to RTC updates are disabled.");
+                m->rtc_local_time = true;
+        }
+
+        r = manager_parse_config_file(m);
+        if (r < 0)
+                log_warning("Failed to parse configuration file: %s", strerror(-r));
+
+        log_debug("systemd-timesyncd running as pid %lu", (unsigned long) getpid());
+        sd_notify(false, "READY=1");
+
+        if (network_is_online()) {
+                r = manager_connect(m);
+                if (r < 0)
+                        goto finish;
+        }
+
+        r = sd_event_loop(m->event);
+        if (r < 0) {
+                log_error("Failed to run event loop: %s", strerror(-r));
+                goto finish;
+        }
+
+        /* if we got an authoritative time, store it in the file system */
+        if (m->sync)
+                touch("/var/lib/systemd/clock");
+
+        sd_event_get_exit_code(m->event, &r);
+
+finish:
+        sd_notify(false, "STATUS=Shutting down...");
+
+        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/src/timesync/timesyncd.conf.in b/src/timesync/timesyncd.conf.in
new file mode 100644 (file)
index 0000000..674a51d
--- /dev/null
@@ -0,0 +1,12 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+#
+# See timesyncd.conf(5) for details
+
+[Time]
+#NTP=
+#FallbackNTP=@NTP_SERVERS@
index 6e36dc7..80c4d2b 100644 (file)
@@ -39,6 +39,7 @@
 #include <glob.h>
 #include <fnmatch.h>
 #include <sys/capability.h>
+#include <sys/xattr.h>
 
 #include "log.h"
 #include "util.h"
@@ -53,6 +54,7 @@
 #include "capability.h"
 #include "specifier.h"
 #include "build.h"
+#include "copy.h"
 
 /* This reads all files listed in /etc/tmpfiles.d/?*.conf and creates
  * them in the file system. This is intended to be used to create
@@ -63,22 +65,24 @@ typedef enum ItemType {
         /* These ones take file names */
         CREATE_FILE = 'f',
         TRUNCATE_FILE = 'F',
-        WRITE_FILE = 'w',
         CREATE_DIRECTORY = 'd',
         TRUNCATE_DIRECTORY = 'D',
         CREATE_FIFO = 'p',
         CREATE_SYMLINK = 'L',
         CREATE_CHAR_DEVICE = 'c',
         CREATE_BLOCK_DEVICE = 'b',
-        ADJUST_MODE = 'm',
+        COPY_FILES = 'C',
+        SET_XATTR = 't',
 
         /* These ones take globs */
+        WRITE_FILE = 'w',
         IGNORE_PATH = 'x',
         IGNORE_DIRECTORY_PATH = 'X',
         REMOVE_PATH = 'r',
         RECURSIVE_REMOVE_PATH = 'R',
+        ADJUST_MODE = 'm', /* legacy, 'z' is identical to this */
         RELABEL_PATH = 'z',
-        RECURSIVE_RELABEL_PATH = 'Z'
+        RECURSIVE_RELABEL_PATH = 'Z',
 } ItemType;
 
 typedef struct Item {
@@ -86,6 +90,7 @@ typedef struct Item {
 
         char *path;
         char *argument;
+        char **xattrs;
         uid_t uid;
         gid_t gid;
         mode_t mode;
@@ -97,20 +102,23 @@ typedef struct Item {
         bool gid_set:1;
         bool mode_set:1;
         bool age_set:1;
+        bool mask_perms:1;
 
         bool keep_first_level:1;
-} Item;
 
-static Hashmap *items = NULL, *globs = NULL;
-static Set *unix_sockets = NULL;
+        bool force:1;
+
+        bool done:1;
+} Item;
 
 static bool arg_create = false;
 static bool arg_clean = false;
 static bool arg_remove = false;
 static bool arg_boot = false;
 
-static char **include_prefixes = NULL;
-static char **exclude_prefixes = NULL;
+static char **arg_include_prefixes = NULL;
+static char **arg_exclude_prefixes = NULL;
+static char *arg_root = NULL;
 
 static const char conf_file_dirs[] =
         "/etc/tmpfiles.d\0"
@@ -124,8 +132,19 @@ static const char conf_file_dirs[] =
 
 #define MAX_DEPTH 256
 
+static Hashmap *items = NULL, *globs = NULL;
+static Set *unix_sockets = NULL;
+
 static bool needs_glob(ItemType t) {
-        return t == IGNORE_PATH || t == IGNORE_DIRECTORY_PATH || t == REMOVE_PATH || t == RECURSIVE_REMOVE_PATH || t == RELABEL_PATH || t == RECURSIVE_RELABEL_PATH;
+        return IN_SET(t,
+                      WRITE_FILE,
+                      IGNORE_PATH,
+                      IGNORE_DIRECTORY_PATH,
+                      REMOVE_PATH,
+                      RECURSIVE_REMOVE_PATH,
+                      ADJUST_MODE,
+                      RELABEL_PATH,
+                      RECURSIVE_RELABEL_PATH);
 }
 
 static struct Item* find_glob(Hashmap *h, const char *match) {
@@ -216,19 +235,20 @@ static bool unix_socket_alive(const char *fn) {
 }
 
 static int dir_is_mount_point(DIR *d, const char *subdir) {
-        struct file_handle *h;
+
+        union file_handle_union h = {
+                .handle.handle_bytes = MAX_HANDLE_SZ
+        };
+
         int mount_id_parent, mount_id;
         int r_p, r;
 
-        h = alloca(MAX_HANDLE_SZ);
-
-        h->handle_bytes = MAX_HANDLE_SZ;
-        r_p = name_to_handle_at(dirfd(d), ".", h, &mount_id_parent, 0);
+        r_p = name_to_handle_at(dirfd(d), ".", &h.handle, &mount_id_parent, 0);
         if (r_p < 0)
                 r_p = -errno;
 
-        h->handle_bytes = MAX_HANDLE_SZ;
-        r = name_to_handle_at(dirfd(d), subdir, h, &mount_id, 0);
+        h.handle.handle_bytes = MAX_HANDLE_SZ;
+        r = name_to_handle_at(dirfd(d), subdir, &h.handle, &mount_id, 0);
         if (r < 0)
                 r = -errno;
 
@@ -303,7 +323,8 @@ static int dir_cleanup(
                 if (s.st_uid == 0 && !(s.st_mode & S_IWUSR))
                         continue;
 
-                if (asprintf(&sub_path, "%s/%s", p, dent->d_name) < 0) {
+                sub_path = strjoin(p, "/", dent->d_name, NULL);
+                if (!sub_path) {
                         r = log_oom();
                         goto finish;
                 }
@@ -329,7 +350,7 @@ static int dir_cleanup(
                                 int q;
 
                                 sub_dir = xopendirat(dirfd(d), dent->d_name, O_NOFOLLOW|O_NOATIME);
-                                if (sub_dir == NULL) {
+                                if (!sub_dir) {
                                         if (errno != ENOENT) {
                                                 log_error("opendir(%s/%s) failed: %m", p, dent->d_name);
                                                 r = -errno;
@@ -339,7 +360,6 @@ static int dir_cleanup(
                                 }
 
                                 q = dir_cleanup(i, sub_path, sub_dir, &s, cutoff, rootdev, false, maxdepth-1, false);
-
                                 if (q < 0)
                                         r = q;
                         }
@@ -435,49 +455,127 @@ finish:
         return r;
 }
 
-static int item_set_perms_full(Item *i, const char *path, bool ignore_enoent) {
+static int item_set_perms(Item *i, const char *path) {
+        struct stat st;
+        bool st_valid;
+
+        assert(i);
+        assert(path);
+
+        st_valid = stat(path, &st) == 0;
+
         /* not using i->path directly because it may be a glob */
-        if (i->mode_set)
-                if (chmod(path, i->mode) < 0) {
-                        if (errno != ENOENT || !ignore_enoent) {
+        if (i->mode_set) {
+                mode_t m = i->mode;
+
+                if (i->mask_perms && st_valid) {
+                        if (!(st.st_mode & 0111))
+                                m &= ~0111;
+                        if (!(st.st_mode & 0222))
+                                m &= ~0222;
+                        if (!(st.st_mode & 0444))
+                                m &= ~0444;
+                        if (!S_ISDIR(st.st_mode))
+                                m &= ~07000; /* remove sticky/sgid/suid bit, unless directory */
+                }
+
+                if (!st_valid || m != (st.st_mode & 07777)) {
+                        if (chmod(path, m) < 0) {
                                 log_error("chmod(%s) failed: %m", path);
                                 return -errno;
                         }
                 }
+        }
 
-        if (i->uid_set || i->gid_set)
+        if ((!st_valid || (i->uid != st.st_uid || i->gid != st.st_gid)) &&
+            (i->uid_set || i->gid_set))
                 if (chown(path,
                           i->uid_set ? i->uid : (uid_t) -1,
                           i->gid_set ? i->gid : (gid_t) -1) < 0) {
 
-                        if (errno != ENOENT || !ignore_enoent) {
-                                log_error("chown(%s) failed: %m", path);
-                                return -errno;
-                        }
+                        log_error("chown(%s) failed: %m", path);
+                        return -errno;
                 }
 
-        return label_fix(path, ignore_enoent, false);
+        return label_fix(path, false, false);
 }
 
-static int item_set_perms(Item *i, const char *path) {
-        return item_set_perms_full(i, path, false);
+static int get_xattrs_from_arg(Item *i) {
+        char *xattr;
+        const char *p;
+        int r;
+
+        assert(i);
+
+        if (!i->argument) {
+                log_error("%s: Argument can't be empty!", i->path);
+                return -EBADMSG;
+        }
+        p = i->argument;
+
+        while ((r = unquote_first_word(&p, &xattr)) > 0) {
+                _cleanup_free_ char *tmp = NULL, *name = NULL, *value = NULL;
+                r = split_pair(xattr, "=", &name, &value);
+                if (r < 0) {
+                        log_warning("Illegal xattr found: \"%s\" - ignoring.", xattr);
+                        free(xattr);
+                        continue;
+                }
+                free(xattr);
+                if (streq(name, "") || streq(value, "")) {
+                        log_warning("Malformed xattr found: \"%s=%s\" - ignoring.", name, value);
+                        continue;
+                }
+                tmp = unquote(value, "\"");
+                if (!tmp)
+                        return log_oom();
+                free(value);
+                value = cunescape(tmp);
+                if (!value)
+                        return log_oom();
+                if (strv_consume_pair(&i->xattrs, name, value) < 0)
+                        return log_oom();
+                name = value = NULL;
+        }
+
+        return r;
+}
+
+static int item_set_xattrs(Item *i, const char *path) {
+        char **name, **value;
+
+        assert(i);
+        assert(path);
+
+        if (strv_isempty(i->xattrs))
+                return 0;
+
+        STRV_FOREACH_PAIR(name, value, i->xattrs) {
+                int n;
+                n = strlen(*value);
+                if (lsetxattr(path, *name, *value, n, 0) < 0) {
+                        log_error("Setting extended attribute %s=%s on %s failed: %m", *name, *value, path);
+                        return -errno;
+                }
+        }
+        return 0;
 }
 
 static int write_one_file(Item *i, const char *path) {
-        int e, flags;
-        int fd = -1;
+        _cleanup_close_ int fd = -1;
+        int flags, r = 0;
         struct stat st;
-        int r = 0;
 
-        flags = i->type == CREATE_FILE ? O_CREAT|O_APPEND :
-                i->type == TRUNCATE_FILE ? O_CREAT|O_TRUNC : 0;
+        assert(i);
+        assert(path);
+
+        flags = i->type == CREATE_FILE ? O_CREAT|O_APPEND|O_NOFOLLOW :
+                i->type == TRUNCATE_FILE ? O_CREAT|O_TRUNC|O_NOFOLLOW : 0;
 
-        RUN_WITH_UMASK(0) {
+        RUN_WITH_UMASK(0000) {
                 label_context_set(path, S_IFREG);
-                fd = open(path, flags|O_NDELAY|O_CLOEXEC|O_WRONLY|O_NOCTTY|O_NOFOLLOW, i->mode);
-                e = errno;
+                fd = open(path, flags|O_NDELAY|O_CLOEXEC|O_WRONLY|O_NOCTTY, i->mode);
                 label_context_clear();
-                errno = e;
         }
 
         if (fd < 0) {
@@ -489,27 +587,24 @@ static int write_one_file(Item *i, const char *path) {
         }
 
         if (i->argument) {
+                _cleanup_free_ char *unescaped;
                 ssize_t n;
                 size_t l;
-                _cleanup_free_ char *unescaped;
 
                 unescaped = cunescape(i->argument);
-                if (unescaped == NULL) {
-                        close_nointr_nofail(fd);
+                if (!unescaped)
                         return log_oom();
-                }
 
                 l = strlen(unescaped);
                 n = write(fd, unescaped, l);
 
                 if (n < 0 || (size_t) n < l) {
                         log_error("Failed to write file %s: %s", path, n < 0 ? strerror(-n) : "Short write");
-                        close_nointr_nofail(fd);
                         return n < 0 ? n : -EIO;
                 }
         }
 
-        close_nointr_nofail(fd);
+        fd = safe_close(fd);
 
         if (stat(path, &st) < 0) {
                 log_error("stat(%s) failed: %m", path);
@@ -525,113 +620,97 @@ static int write_one_file(Item *i, const char *path) {
         if (r < 0)
                 return r;
 
+        r = item_set_xattrs(i, i->path);
+        if (r < 0)
+                return r;
+
         return 0;
 }
 
-static int recursive_relabel_children(Item *i, const char *path) {
+static int item_set_perms_children(Item *i, const char *path) {
         _cleanup_closedir_ DIR *d;
-        int ret = 0;
+        int r = 0;
+
+        assert(i);
+        assert(path);
 
         /* This returns the first error we run into, but nevertheless
          * tries to go on */
 
         d = opendir(path);
         if (!d)
-                return errno == ENOENT ? 0 : -errno;
+                return errno == ENOENT || errno == ENOTDIR ? 0 : -errno;
 
         for (;;) {
+                _cleanup_free_ char *p = NULL;
                 struct dirent *de;
-                bool is_dir;
-                int r;
-                _cleanup_free_ char *entry_path = NULL;
+                int q;
 
                 errno = 0;
                 de = readdir(d);
-                if (!de && errno != 0) {
-                        if (ret == 0)
-                                ret = -errno;
-                        break;
-                }
+                if (!de) {
+                        if (errno != 0 && r == 0)
+                                r = -errno;
 
-                if (!de)
                         break;
+                }
 
                 if (streq(de->d_name, ".") || streq(de->d_name, ".."))
                         continue;
 
-                if (asprintf(&entry_path, "%s/%s", path, de->d_name) < 0) {
-                        if (ret == 0)
-                                ret = -ENOMEM;
-                        continue;
-                }
-
-                if (de->d_type == DT_UNKNOWN) {
-                        struct stat st;
-
-                        if (lstat(entry_path, &st) < 0) {
-                                if (ret == 0 && errno != ENOENT)
-                                        ret = -errno;
-                                continue;
-                        }
-
-                        is_dir = S_ISDIR(st.st_mode);
-
-                } else
-                        is_dir = de->d_type == DT_DIR;
+                p = strjoin(path, "/", de->d_name, NULL);
+                if (!p)
+                        return -ENOMEM;
 
-                r = item_set_perms(i, entry_path);
-                if (r < 0) {
-                        if (ret == 0 && r != -ENOENT)
-                                ret = r;
-                        continue;
-                }
+                q = item_set_perms(i, p);
+                if (q < 0 && q != -ENOENT && r == 0)
+                        r = q;
 
-                if (is_dir) {
-                        r = recursive_relabel_children(i, entry_path);
-                        if (r < 0 && ret == 0)
-                                ret = r;
+                if (IN_SET(de->d_type, DT_UNKNOWN, DT_DIR)) {
+                        q = item_set_perms_children(i, p);
+                        if (q < 0 && r == 0)
+                                r = q;
                 }
         }
 
-        return ret;
+        return r;
 }
 
-static int recursive_relabel(Item *i, const char *path) {
-        int r;
-        struct stat st;
+static int item_set_perms_recursive(Item *i, const char *path) {
+        int r, q;
+
+        assert(i);
+        assert(path);
 
         r = item_set_perms(i, path);
         if (r < 0)
                 return r;
 
-        if (lstat(path, &st) < 0)
-                return -errno;
-
-        if (S_ISDIR(st.st_mode))
-                r = recursive_relabel_children(i, path);
+        q = item_set_perms_children(i, path);
+        if (q < 0 && r == 0)
+                r = q;
 
         return r;
 }
 
 static int glob_item(Item *i, int (*action)(Item *, const char *)) {
-        int r = 0, k;
         _cleanup_globfree_ glob_t g = {};
+        int r = 0, k;
         char **fn;
 
         errno = 0;
         k = glob(i->path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
-        if (k != 0)
-                if (k != GLOB_NOMATCH) {
-                        if (errno > 0)
-                                errno = EIO;
+        if (k != 0 && k != GLOB_NOMATCH) {
+                if (errno == 0)
+                        errno = EIO;
 
-                        log_error("glob(%s) failed: %m", i->path);
-                        return -errno;
-                }
+                log_error("glob(%s) failed: %m", i->path);
+                return -errno;
+        }
 
         STRV_FOREACH(fn, g.gl_pathv) {
                 k = action(i, *fn);
-                if (k < 0)
+                if (k < 0 && r == 0)
                         r = k;
         }
 
@@ -639,7 +718,6 @@ static int glob_item(Item *i, int (*action)(Item *, const char *)) {
 }
 
 static int create_item(Item *i) {
-        int e;
         struct stat st;
         int r = 0;
 
@@ -660,15 +738,40 @@ static int create_item(Item *i) {
                         return r;
                 break;
 
-        case WRITE_FILE:
-                r = glob_item(i, write_one_file);
+        case COPY_FILES:
+                r = copy_tree(i->argument, i->path, false);
+                if (r < 0) {
+                        struct stat a, b;
+
+                        if (r != -EEXIST) {
+                                log_error("Failed to copy files to %s: %s", i->path, strerror(-r));
+                                return -r;
+                        }
+
+                        if (stat(i->argument, &a) < 0) {
+                                log_error("stat(%s) failed: %m", i->argument);
+                                return -errno;
+                        }
+
+                        if (stat(i->path, &b) < 0) {
+                                log_error("stat(%s) failed: %m", i->path);
+                                return -errno;
+                        }
+
+                        if ((a.st_mode ^ b.st_mode) & S_IFMT) {
+                                log_debug("Can't copy to %s, file exists already and is of different type", i->path);
+                                return 0;
+                        }
+                }
+
+                r = item_set_perms(i, i->path);
                 if (r < 0)
                         return r;
 
                 break;
 
-        case ADJUST_MODE:
-                r = item_set_perms_full(i, i->path, true);
+        case WRITE_FILE:
+                r = glob_item(i, write_one_file);
                 if (r < 0)
                         return r;
 
@@ -679,84 +782,124 @@ static int create_item(Item *i) {
 
                 RUN_WITH_UMASK(0000) {
                         mkdir_parents_label(i->path, 0755);
-                        r = mkdir(i->path, i->mode);
+                        r = mkdir_label(i->path, i->mode);
                 }
 
-                if (r < 0 && errno != EEXIST) {
-                        log_error("Failed to create directory %s: %m", i->path);
-                        return -errno;
-                }
+                if (r < 0) {
+                        if (r != -EEXIST) {
+                                log_error("Failed to create directory %s: %s", i->path, strerror(-r));
+                                return r;
+                        }
 
-                if (stat(i->path, &st) < 0) {
-                        log_error("stat(%s) failed: %m", i->path);
-                        return -errno;
-                }
+                        if (stat(i->path, &st) < 0) {
+                                log_error("stat(%s) failed: %m", i->path);
+                                return -errno;
+                        }
 
-                if (!S_ISDIR(st.st_mode)) {
-                        log_error("%s is not a directory.", i->path);
-                        return -EEXIST;
+                        if (!S_ISDIR(st.st_mode)) {
+                                log_debug("%s already exists and is not a directory.", i->path);
+                                return 0;
+                        }
                 }
 
                 r = item_set_perms(i, i->path);
                 if (r < 0)
                         return r;
 
+                r = item_set_xattrs(i, i->path);
+                if (r < 0)
+                        return r;
+
                 break;
 
         case CREATE_FIFO:
 
                 RUN_WITH_UMASK(0000) {
+                        label_context_set(i->path, S_IFIFO);
                         r = mkfifo(i->path, i->mode);
+                        label_context_clear();
                 }
 
-                if (r < 0 && errno != EEXIST) {
-                        log_error("Failed to create fifo %s: %m", i->path);
-                        return -errno;
-                }
+                if (r < 0) {
+                        if (errno != EEXIST) {
+                                log_error("Failed to create fifo %s: %m", i->path);
+                                return -errno;
+                        }
 
-                if (stat(i->path, &st) < 0) {
-                        log_error("stat(%s) failed: %m", i->path);
-                        return -errno;
-                }
+                        if (stat(i->path, &st) < 0) {
+                                log_error("stat(%s) failed: %m", i->path);
+                                return -errno;
+                        }
+
+                        if (!S_ISFIFO(st.st_mode)) {
 
-                if (!S_ISFIFO(st.st_mode)) {
-                        log_error("%s is not a fifo.", i->path);
-                        return -EEXIST;
+                                if (i->force) {
+
+                                        RUN_WITH_UMASK(0000) {
+                                                label_context_set(i->path, S_IFIFO);
+                                                r = mkfifo_atomic(i->path, i->mode);
+                                                label_context_clear();
+                                        }
+
+                                        if (r < 0) {
+                                                log_error("Failed to create fifo %s: %s", i->path, strerror(-r));
+                                                return r;
+                                        }
+                                } else {
+                                        log_debug("%s is not a fifo.", i->path);
+                                        return 0;
+                                }
+                        }
                 }
 
                 r = item_set_perms(i, i->path);
                 if (r < 0)
                         return r;
 
+                r = item_set_xattrs(i, i->path);
+                if (r < 0)
+                        return r;
+
                 break;
 
-        case CREATE_SYMLINK: {
-                _cleanup_free_ char *x = NULL;
+        case CREATE_SYMLINK:
 
                 label_context_set(i->path, S_IFLNK);
                 r = symlink(i->argument, i->path);
-                e = errno;
                 label_context_clear();
-                errno = e;
 
-                if (r < 0 && errno != EEXIST) {
-                        log_error("symlink(%s, %s) failed: %m", i->argument, i->path);
-                        return -errno;
-                }
-
-                r = readlink_malloc(i->path, &x);
                 if (r < 0) {
-                        log_error("readlink(%s) failed: %s", i->path, strerror(-r));
-                        return -errno;
-                }
+                        _cleanup_free_ char *x = NULL;
+
+                        if (errno != EEXIST) {
+                                log_error("symlink(%s, %s) failed: %m", i->argument, i->path);
+                                return -errno;
+                        }
+
+                        r = readlink_malloc(i->path, &x);
+                        if (r < 0 || !streq(i->argument, x)) {
 
-                if (!streq(i->argument, x)) {
-                        log_error("%s is not the right symlinks.", i->path);
-                        return -EEXIST;
+                                if (i->force) {
+                                        label_context_set(i->path, S_IFLNK);
+                                        r = symlink_atomic(i->argument, i->path);
+                                        label_context_clear();
+
+                                        if (r < 0) {
+                                                log_error("symlink(%s, %s) failed: %s", i->argument, i->path, strerror(-r));
+                                                return r;
+                                        }
+                                } else {
+                                        log_debug("%s is not a symlink or does not point to the correct path.", i->path);
+                                        return 0;
+                                }
+                        }
                 }
 
+                r = item_set_xattrs(i, i->path);
+                if (r < 0)
+                       return r;
+
                 break;
-        }
 
         case CREATE_BLOCK_DEVICE:
         case CREATE_CHAR_DEVICE: {
@@ -772,38 +915,64 @@ static int create_item(Item *i) {
                         return 0;
                 }
 
-                file_type = (i->type == CREATE_BLOCK_DEVICE ? S_IFBLK : S_IFCHR);
+                file_type = i->type == CREATE_BLOCK_DEVICE ? S_IFBLK : S_IFCHR;
 
                 RUN_WITH_UMASK(0000) {
                         label_context_set(i->path, file_type);
                         r = mknod(i->path, i->mode | file_type, i->major_minor);
-                        e = errno;
                         label_context_clear();
-                        errno = e;
                 }
 
-                if (r < 0 && errno != EEXIST) {
-                        log_error("Failed to create device node %s: %m", i->path);
-                        return -errno;
-                }
+                if (r < 0) {
+                        if (errno == EPERM) {
+                                log_debug("We lack permissions, possibly because of cgroup configuration; "
+                                          "skipping creation of device node %s.", i->path);
+                                return 0;
+                        }
 
-                if (stat(i->path, &st) < 0) {
-                        log_error("stat(%s) failed: %m", i->path);
-                        return -errno;
-                }
+                        if (errno != EEXIST) {
+                                log_error("Failed to create device node %s: %m", i->path);
+                                return -errno;
+                        }
 
-                if ((st.st_mode & S_IFMT) != file_type) {
-                        log_error("%s is not a device node.", i->path);
-                        return -EEXIST;
+                        if (stat(i->path, &st) < 0) {
+                                log_error("stat(%s) failed: %m", i->path);
+                                return -errno;
+                        }
+
+                        if ((st.st_mode & S_IFMT) != file_type) {
+
+                                if (i->force) {
+
+                                        RUN_WITH_UMASK(0000) {
+                                                label_context_set(i->path, file_type);
+                                                r = mknod_atomic(i->path, i->mode | file_type, i->major_minor);
+                                                label_context_clear();
+                                        }
+
+                                        if (r < 0) {
+                                                log_error("Failed to create device node %s: %s", i->path, strerror(-r));
+                                                return r;
+                                        }
+                                } else {
+                                        log_debug("%s is not a device node.", i->path);
+                                        return 0;
+                                }
+                        }
                 }
 
                 r = item_set_perms(i, i->path);
                 if (r < 0)
                         return r;
 
+                r = item_set_xattrs(i, i->path);
+                if (r < 0)
+                        return r;
+
                 break;
         }
 
+        case ADJUST_MODE:
         case RELABEL_PATH:
 
                 r = glob_item(i, item_set_perms);
@@ -813,9 +982,16 @@ static int create_item(Item *i) {
 
         case RECURSIVE_RELABEL_PATH:
 
-                r = glob_item(i, recursive_relabel);
+                r = glob_item(i, item_set_perms_recursive);
                 if (r < 0)
                         return r;
+                break;
+
+        case SET_XATTR:
+                r = item_set_xattrs(i, i->path);
+                if (r < 0)
+                        return r;
+                break;
         }
 
         log_debug("%s created successfully.", i->path);
@@ -839,10 +1015,12 @@ static int remove_item_instance(Item *i, const char *instance) {
         case CREATE_CHAR_DEVICE:
         case IGNORE_PATH:
         case IGNORE_DIRECTORY_PATH:
+        case ADJUST_MODE:
         case RELABEL_PATH:
         case RECURSIVE_RELABEL_PATH:
         case WRITE_FILE:
-        case ADJUST_MODE:
+        case COPY_FILES:
+        case SET_XATTR:
                 break;
 
         case REMOVE_PATH:
@@ -885,10 +1063,12 @@ static int remove_item(Item *i) {
         case CREATE_BLOCK_DEVICE:
         case IGNORE_PATH:
         case IGNORE_DIRECTORY_PATH:
+        case ADJUST_MODE:
         case RELABEL_PATH:
         case RECURSIVE_RELABEL_PATH:
         case WRITE_FILE:
-        case ADJUST_MODE:
+        case COPY_FILES:
+        case SET_XATTR:
                 break;
 
         case REMOVE_PATH:
@@ -960,6 +1140,7 @@ static int clean_item(Item *i) {
         case CREATE_DIRECTORY:
         case TRUNCATE_DIRECTORY:
         case IGNORE_PATH:
+        case COPY_FILES:
                 clean_item_instance(i, i->path);
                 break;
         case IGNORE_DIRECTORY_PATH:
@@ -974,9 +1155,23 @@ static int clean_item(Item *i) {
 
 static int process_item(Item *i) {
         int r, q, p;
+        char prefix[PATH_MAX];
 
         assert(i);
 
+        if (i->done)
+                return 0;
+
+        i->done = true;
+
+        PATH_FOREACH_PREFIX(prefix, i->path) {
+                Item *j;
+
+                j = hashmap_get(items, prefix);
+                if (j)
+                        process_item(j);
+        }
+
         r = arg_create ? create_item(i) : 0;
         q = arg_remove ? remove_item(i) : 0;
         p = arg_clean ? clean_item(i) : 0;
@@ -991,15 +1186,17 @@ static int process_item(Item *i) {
 }
 
 static void item_free(Item *i) {
-        assert(i);
+
+        if (!i)
+                return;
 
         free(i->path);
         free(i->argument);
+        strv_free(i->xattrs);
         free(i);
 }
 
 DEFINE_TRIVIAL_CLEANUP_FUNC(Item*, item_free);
-#define _cleanup_item_free_ _cleanup_(item_freep)
 
 static bool item_equal(Item *a, Item *b) {
         assert(a);
@@ -1030,7 +1227,8 @@ static bool item_equal(Item *a, Item *b) {
         if ((a->type == CREATE_FILE ||
              a->type == TRUNCATE_FILE ||
              a->type == WRITE_FILE ||
-             a->type == CREATE_SYMLINK) &&
+             a->type == CREATE_SYMLINK ||
+             a->type == COPY_FILES) &&
             !streq_ptr(a->argument, b->argument))
                 return false;
 
@@ -1045,19 +1243,17 @@ static bool item_equal(Item *a, Item *b) {
 static bool should_include_path(const char *path) {
         char **prefix;
 
-        STRV_FOREACH(prefix, exclude_prefixes) {
+        STRV_FOREACH(prefix, arg_exclude_prefixes)
                 if (path_startswith(path, *prefix))
                         return false;
-        }
 
-        STRV_FOREACH(prefix, include_prefixes) {
+        STRV_FOREACH(prefix, arg_include_prefixes)
                 if (path_startswith(path, *prefix))
                         return true;
-        }
 
         /* no matches, so we should include this path only if we
          * have no whitelist at all */
-        return strv_length(include_prefixes) == 0;
+        return strv_length(arg_include_prefixes) == 0;
 }
 
 static int parse_line(const char *fname, unsigned line, const char *buffer) {
@@ -1070,10 +1266,9 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
                 {}
         };
 
-        _cleanup_item_free_ Item *i = NULL;
+        _cleanup_free_ char *action = NULL, *mode = NULL, *user = NULL, *group = NULL, *age = NULL, *path = NULL;
+        _cleanup_(item_freep) Item *i = NULL;
         Item *existing;
-        _cleanup_free_ char
-                *action = NULL, *mode = NULL, *user = NULL, *group = NULL, *age = NULL, *path = NULL;
         char type;
         Hashmap *h;
         int r, n = -1;
@@ -1096,10 +1291,17 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
                 return -EIO;
         }
 
-        if (strlen(action) > 2 || (strlen(action) > 1 && action[1] != '!')) {
-                log_error("[%s:%u] Unknown modifier '%s'", fname, line, action);
+        if (isempty(action)) {
+                log_error("[%s:%u] Command too short '%s'.", fname, line, action);
                 return -EINVAL;
-        } else if (strlen(action) > 1 && !arg_boot)
+        }
+
+        if (strlen(action) > 1 && !in_charset(action+1, "!+")) {
+                log_error("[%s:%u] Unknown modifiers in command '%s'", fname, line, action);
+                return -EINVAL;
+        }
+
+        if (strchr(action+1, '!') && !arg_boot)
                 return 0;
 
         type = action[0];
@@ -1108,6 +1310,8 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
         if (!i)
                 return log_oom();
 
+        i->force = !!strchr(action+1, '+');
+
         r = specifier_printf(path, specifier_table, NULL, &i->path);
         if (r < 0) {
                 log_error("[%s:%u] Failed to replace specifiers: %s", fname, line, path);
@@ -1123,7 +1327,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
                 }
         }
 
-        switch(type) {
+        switch (type) {
 
         case CREATE_FILE:
         case TRUNCATE_FILE:
@@ -1134,15 +1338,16 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
         case IGNORE_DIRECTORY_PATH:
         case REMOVE_PATH:
         case RECURSIVE_REMOVE_PATH:
+        case ADJUST_MODE:
         case RELABEL_PATH:
         case RECURSIVE_RELABEL_PATH:
-        case ADJUST_MODE:
                 break;
 
         case CREATE_SYMLINK:
                 if (!i->argument) {
-                        log_error("[%s:%u] Symlink file requires argument.", fname, line);
-                        return -EBADMSG;
+                        i->argument = strappend("/usr/share/factory", i->path);
+                        if (!i->argument)
+                                return log_oom();
                 }
                 break;
 
@@ -1153,6 +1358,21 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
                 }
                 break;
 
+        case COPY_FILES:
+                if (!i->argument) {
+                        i->argument = strappend("/usr/share/factory", i->path);
+                        if (!i->argument)
+                                return log_oom();
+                }
+
+                if (!path_is_absolute(i->argument)) {
+                        log_error("[%s:%u] Source path is not absolute.", fname, line);
+                        return -EBADMSG;
+                }
+
+                path_kill_slashes(i->argument);
+                break;
+
         case CREATE_CHAR_DEVICE:
         case CREATE_BLOCK_DEVICE: {
                 unsigned major, minor;
@@ -1171,8 +1391,18 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
                 break;
         }
 
+        case SET_XATTR:
+                if (!i->argument) {
+                        log_error("[%s:%u] Set extended attribute requires argument.", fname, line);
+                        return -EBADMSG;
+                }
+                r = get_xattrs_from_arg(i);
+                if (r < 0)
+                        return r;
+                break;
+
         default:
-                log_error("[%s:%u] Unknown file type '%c'.", fname, line, type);
+                log_error("[%s:%u] Unknown command type '%c'.", fname, line, type);
                 return -EBADMSG;
         }
 
@@ -1188,6 +1418,17 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
         if (!should_include_path(i->path))
                 return 0;
 
+        if (arg_root) {
+                char *p;
+
+                p = strappend(arg_root, i->path);
+                if (!p)
+                        return log_oom();
+
+                free(i->path);
+                i->path = p;
+        }
+
         if (user && !streq(user, "-")) {
                 const char *u = user;
 
@@ -1213,9 +1454,15 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
         }
 
         if (mode && !streq(mode, "-")) {
+                const char *mm = mode;
                 unsigned m;
 
-                if (sscanf(mode, "%o", &m) != 1) {
+                if (*mm == '~') {
+                        i->mask_perms = true;
+                        mm++;
+                }
+
+                if (sscanf(mm, "%o", &m) != 1) {
                         log_error("[%s:%u] Invalid mode '%s'.", fname, line, mode);
                         return -ENOENT;
                 }
@@ -1247,18 +1494,33 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
 
         existing = hashmap_get(h, i->path);
         if (existing) {
-
-                /* Two identical items are fine */
-                if (!item_equal(existing, i))
-                        log_warning("Two or more conflicting lines for %s configured, ignoring.", i->path);
-
-                return 0;
-        }
-
-        r = hashmap_put(h, i->path, i);
-        if (r < 0) {
-                log_error("Failed to insert item %s: %s", i->path, strerror(-r));
-                return r;
+                if (i->type == SET_XATTR) {
+                        r = strv_extend_strv(&existing->xattrs, i->xattrs);
+                        if (r < 0)
+                                return log_oom();
+                        return 0;
+                } else if (existing->type == SET_XATTR) {
+                        r = strv_extend_strv(&i->xattrs, existing->xattrs);
+                        if (r < 0)
+                                return log_oom();
+                        r = hashmap_replace(h, i->path, i);
+                        if (r < 0) {
+                                log_error("Failed to replace item for %s.", i->path);
+                                return r;
+                        }
+                        item_free(existing);
+                } else {
+                        /* Two identical items are fine */
+                        if (!item_equal(existing, i))
+                                log_warning("Two or more conflicting lines for %s configured, ignoring.", i->path);
+                        return 0;
+                }
+        } else {
+                r = hashmap_put(h, i->path, i);
+                if (r < 0) {
+                        log_error("Failed to insert item %s: %s", i->path, strerror(-r));
+                        return r;
+                }
         }
 
         i = NULL; /* avoid cleanup */
@@ -1266,8 +1528,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
         return 0;
 }
 
-static int help(void) {
-
+static void help(void) {
         printf("%s [OPTIONS...] [CONFIGURATION FILE...]\n\n"
                "Creates, deletes and cleans up volatile and temporary files and directories.\n\n"
                "  -h --help                 Show this help\n"
@@ -1277,10 +1538,9 @@ static int help(void) {
                "     --remove               Remove marked files/directories\n"
                "     --boot                 Execute actions only safe at boot\n"
                "     --prefix=PATH          Only apply rules that apply to paths with the specified prefix\n"
-               "     --exclude-prefix=PATH  Ignore rules that apply to paths with the specified prefix\n",
+               "     --exclude-prefix=PATH  Ignore rules that apply to paths with the specified prefix\n"
+               "     --root=PATH            Operate on an alternate filesystem root\n",
                program_invocation_short_name);
-
-        return 0;
 }
 
 static int parse_argv(int argc, char *argv[]) {
@@ -1293,6 +1553,7 @@ static int parse_argv(int argc, char *argv[]) {
                 ARG_BOOT,
                 ARG_PREFIX,
                 ARG_EXCLUDE_PREFIX,
+                ARG_ROOT,
         };
 
         static const struct option options[] = {
@@ -1304,6 +1565,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "boot",           no_argument,         NULL, ARG_BOOT           },
                 { "prefix",         required_argument,   NULL, ARG_PREFIX         },
                 { "exclude-prefix", required_argument,   NULL, ARG_EXCLUDE_PREFIX },
+                { "root",           required_argument,   NULL, ARG_ROOT           },
                 {}
         };
 
@@ -1312,12 +1574,13 @@ static int parse_argv(int argc, char *argv[]) {
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) {
+        while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
 
                 switch (c) {
 
                 case 'h':
-                        return help();
+                        help();
+                        return 0;
 
                 case ARG_VERSION:
                         puts(PACKAGE_STRING);
@@ -1341,13 +1604,22 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
 
                 case ARG_PREFIX:
-                        if (strv_push(&include_prefixes, optarg) < 0)
+                        if (strv_push(&arg_include_prefixes, optarg) < 0)
                                 return log_oom();
                         break;
 
                 case ARG_EXCLUDE_PREFIX:
-                        if (strv_push(&exclude_prefixes, optarg) < 0)
+                        if (strv_push(&arg_exclude_prefixes, optarg) < 0)
+                                return log_oom();
+                        break;
+
+                case ARG_ROOT:
+                        free(arg_root);
+                        arg_root = path_make_absolute_cwd(optarg);
+                        if (!arg_root)
                                 return log_oom();
+
+                        path_kill_slashes(arg_root);
                         break;
 
                 case '?':
@@ -1356,7 +1628,6 @@ static int parse_argv(int argc, char *argv[]) {
                 default:
                         assert_not_reached("Unhandled option");
                 }
-        }
 
         if (!arg_clean && !arg_create && !arg_remove) {
                 log_error("You need to specify at least one of --clean, --create or --remove.");
@@ -1376,7 +1647,7 @@ static int read_config_file(const char *fn, bool ignore_enoent) {
 
         assert(fn);
 
-        r = search_and_fopen_nulstr(fn, "re", conf_file_dirs, &f);
+        r = search_and_fopen_nulstr(fn, "re", arg_root, conf_file_dirs, &f);
         if (r < 0) {
                 if (ignore_enoent && r == -ENOENT)
                         return 0;
@@ -1444,7 +1715,7 @@ int main(int argc, char *argv[]) {
 
         r = parse_argv(argc, argv);
         if (r <= 0)
-                return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+                goto finish;
 
         log_set_target(LOG_TARGET_AUTO);
         log_parse_environment();
@@ -1477,7 +1748,7 @@ int main(int argc, char *argv[]) {
                 _cleanup_strv_free_ char **files = NULL;
                 char **f;
 
-                r = conf_files_list_nulstr(&files, ".conf", NULL, conf_file_dirs);
+                r = conf_files_list_nulstr(&files, ".conf", arg_root, conf_file_dirs);
                 if (r < 0) {
                         log_error("Failed to enumerate tmpfiles.d files: %s", strerror(-r));
                         goto finish;
@@ -1506,8 +1777,9 @@ finish:
         hashmap_free(items);
         hashmap_free(globs);
 
-        free(include_prefixes);
-        free(exclude_prefixes);
+        free(arg_include_prefixes);
+        free(arg_exclude_prefixes);
+        free(arg_root);
 
         set_free_free(unix_sockets);
 
index 7a90e65..8a02fb0 100644 (file)
@@ -41,6 +41,7 @@
 #include "ask-password-api.h"
 #include "strv.h"
 #include "build.h"
+#include "def.h"
 
 static enum {
         ACTION_LIST,
@@ -59,9 +60,9 @@ static int ask_password_plymouth(
                 bool accept_cached,
                 char ***_passphrases) {
 
-        int fd = -1, notify = -1;
-        union sockaddr_union sa = {};
-        char *packet = NULL;
+        _cleanup_close_ int fd = -1, notify = -1;
+        union sockaddr_union sa = PLYMOUTH_SOCKET;
+        _cleanup_free_ char *packet = NULL;
         ssize_t k;
         int r, n;
         struct pollfd pollfd[2] = {};
@@ -75,45 +76,38 @@ static int ask_password_plymouth(
         assert(_passphrases);
 
         if (flag_file) {
-                if ((notify = inotify_init1(IN_CLOEXEC|IN_NONBLOCK)) < 0) {
-                        r = -errno;
-                        goto finish;
-                }
+                notify = inotify_init1(IN_CLOEXEC|IN_NONBLOCK);
+                if (notify < 0)
+                        return -errno;
 
-                if (inotify_add_watch(notify, flag_file, IN_ATTRIB /* for the link count */) < 0) {
-                        r = -errno;
-                        goto finish;
-                }
+                r = inotify_add_watch(notify, flag_file, IN_ATTRIB); /* for the link count */
+                if (r < 0)
+                        return -errno;
         }
 
-        if ((fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0)) < 0) {
-                r = -errno;
-                goto finish;
-        }
+        fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
+        if (fd < 0)
+                return -errno;
 
-        sa.sa.sa_family = AF_UNIX;
-        strncpy(sa.un.sun_path+1, "/org/freedesktop/plymouthd", sizeof(sa.un.sun_path)-1);
-        if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1)) < 0) {
+        r = connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1));
+        if (r < 0) {
                 log_error("Failed to connect to Plymouth: %m");
-                r = -errno;
-                goto finish;
+                return -errno;
         }
 
         if (accept_cached) {
                 packet = strdup("c");
                 n = 1;
-        } else
-                asprintf(&packet, "*\002%c%s%n", (int) (strlen(message) + 1), message, &n);
+        } else if (asprintf(&packet, "*\002%c%s%n", (int) (strlen(message) + 1),
+                            message, &n) < 0)
+                packet = NULL;
 
-        if (!packet) {
-                r = -ENOMEM;
-                goto finish;
-        }
+        if (!packet)
+                return log_oom();
 
-        if ((k = loop_write(fd, packet, n+1, true)) != n+1) {
-                r = k < 0 ? (int) k : -EIO;
-                goto finish;
-        }
+        k = loop_write(fd, packet, n + 1, true);
+        if (k != n + 1)
+                return k < 0 ? (int) k : -EIO;
 
         pollfd[POLL_SOCKET].fd = fd;
         pollfd[POLL_SOCKET].events = POLLIN;
@@ -128,31 +122,23 @@ static int ask_password_plymouth(
 
                         y = now(CLOCK_MONOTONIC);
 
-                        if (y > until) {
-                                r = -ETIME;
-                                goto finish;
-                        }
+                        if (y > until)
+                                return -ETIME;
 
                         sleep_for = (int) ((until - y) / USEC_PER_MSEC);
                 }
 
-                if (flag_file)
-                        if (access(flag_file, F_OK) < 0) {
-                                r = -errno;
-                                goto finish;
-                        }
-
-                if ((j = poll(pollfd, notify > 0 ? 2 : 1, sleep_for)) < 0) {
+                if (flag_file && access(flag_file, F_OK) < 0)
+                        return -errno;
 
+                j = poll(pollfd, notify > 0 ? 2 : 1, sleep_for);
+                if (j < 0) {
                         if (errno == EINTR)
                                 continue;
 
-                        r = -errno;
-                        goto finish;
-                } else if (j == 0) {
-                        r = -ETIME;
-                        goto finish;
-                }
+                        return -errno;
+                } else if (j == 0)
+                        return -ETIME;
 
                 if (notify > 0 && pollfd[POLL_INOTIFY].revents != 0)
                         flush_fd(notify);
@@ -160,10 +146,9 @@ static int ask_password_plymouth(
                 if (pollfd[POLL_SOCKET].revents == 0)
                         continue;
 
-                if ((k = read(fd, buffer + p, sizeof(buffer) - p)) <= 0) {
-                        r = k < 0 ? -errno : -EIO;
-                        goto finish;
-                }
+                k = read(fd, buffer + p, sizeof(buffer) - p);
+                if (k <= 0)
+                        return r = k < 0 ? -errno : -EIO;
 
                 p += k;
 
@@ -179,15 +164,12 @@ static int ask_password_plymouth(
                                 free(packet);
                                 packet = NULL;
 
-                                if (asprintf(&packet, "*\002%c%s%n", (int) (strlen(message) + 1), message, &n) < 0) {
-                                        r = -ENOMEM;
-                                        goto finish;
-                                }
+                                if (asprintf(&packet, "*\002%c%s%n", (int) (strlen(message) + 1), message, &n) < 0)
+                                        return -ENOMEM;
 
-                                if ((k = loop_write(fd, packet, n+1, true)) != n+1) {
-                                        r = k < 0 ? (int) k : -EIO;
-                                        goto finish;
-                                }
+                                k = loop_write(fd, packet, n+1, true);
+                                if (k != n + 1)
+                                        return k < 0 ? (int) k : -EIO;
 
                                 accept_cached = false;
                                 p = 0;
@@ -195,8 +177,7 @@ static int ask_password_plymouth(
                         }
 
                         /* No password, because UI not shown */
-                        r = -ENOENT;
-                        goto finish;
+                        return -ENOENT;
 
                 } else if (buffer[0] == 2 || buffer[0] == 9) {
                         uint32_t size;
@@ -208,48 +189,31 @@ static int ask_password_plymouth(
 
                         memcpy(&size, buffer+1, sizeof(size));
                         size = le32toh(size);
-                        if (size+5 > sizeof(buffer)) {
-                                r = -EIO;
-                                goto finish;
-                        }
+                        if (size + 5 > sizeof(buffer))
+                                return -EIO;
 
                         if (p-5 < size)
                                 continue;
 
-                        if (!(l = strv_parse_nulstr(buffer + 5, size))) {
-                                r = -ENOMEM;
-                                goto finish;
-                        }
+                        l = strv_parse_nulstr(buffer + 5, size);
+                        if (!l)
+                                return -ENOMEM;
 
                         *_passphrases = l;
                         break;
 
-                } else {
+                } else
                         /* Unknown packet */
-                        r = -EIO;
-                        goto finish;
-                }
+                        return -EIO;
         }
 
-        r = 0;
-
-finish:
-        if (notify >= 0)
-                close_nointr_nofail(notify);
-
-        if (fd >= 0)
-                close_nointr_nofail(fd);
-
-        free(packet);
-
-        return r;
+        return 0;
 }
 
 static int parse_password(const char *filename, char **wall) {
-        char *socket_name = NULL, *message = NULL, *packet = NULL;
+        _cleanup_free_ char *socket_name = NULL, *message = NULL, *packet = NULL;
         uint64_t not_after = 0;
         unsigned pid = 0;
-        int socket_fd = -1;
         bool accept_cached = false;
 
         const ConfigTableItem items[] = {
@@ -258,49 +222,34 @@ static int parse_password(const char *filename, char **wall) {
                 { "Ask", "Message",      config_parse_string,   0, &message       },
                 { "Ask", "PID",          config_parse_unsigned, 0, &pid           },
                 { "Ask", "AcceptCached", config_parse_bool,     0, &accept_cached },
-                { NULL, NULL, NULL, 0, NULL }
+                {}
         };
 
-        FILE *f;
         int r;
 
         assert(filename);
 
-        f = fopen(filename, "re");
-        if (!f) {
-                if (errno == ENOENT)
-                        return 0;
-
-                log_error("open(%s): %m", filename);
-                return -errno;
-        }
-
-        r = config_parse(NULL, filename, f, NULL, config_item_table_lookup, (void*) items, true, false, NULL);
-        if (r < 0) {
-                log_error("Failed to parse password file %s: %s", filename, strerror(-r));
-                goto finish;
-        }
+        r = config_parse(NULL, filename, NULL,
+                         NULL,
+                         config_item_table_lookup, items,
+                         true, false, true, NULL);
+        if (r < 0)
+                return r;
 
         if (!socket_name) {
                 log_error("Invalid password file %s", filename);
-                r = -EBADMSG;
-                goto finish;
+                return -EBADMSG;
         }
 
-        if (not_after > 0) {
-                if (now(CLOCK_MONOTONIC) > not_after) {
-                        r = 0;
-                        goto finish;
-                }
-        }
+        if (not_after > 0 && now(CLOCK_MONOTONIC) > not_after)
+                return 0;
 
-        if (pid > 0 && !pid_is_alive(pid)) {
-                r = 0;
-                goto finish;
-        }
+        if (pid > 0 && !pid_is_alive(pid))
+                return 0;
 
         if (arg_action == ACTION_LIST)
                 printf("'%s' (PID %u)\n", message, pid);
+
         else if (arg_action == ACTION_WALL) {
                 char *_wall;
 
@@ -310,133 +259,117 @@ static int parse_password(const char *filename, char **wall) {
                              *wall ? *wall : "",
                              *wall ? "\r\n\r\n" : "",
                              message,
-                             pid) < 0) {
-                        r = log_oom();
-                        goto finish;
-                }
+                             pid) < 0)
+                        return log_oom();
 
                 free(*wall);
                 *wall = _wall;
+
         } else {
-                union {
-                        struct sockaddr sa;
-                        struct sockaddr_un un;
-                } sa = {};
+                union sockaddr_union sa = {};
                 size_t packet_length = 0;
+                _cleanup_close_ int socket_fd = -1;
 
                 assert(arg_action == ACTION_QUERY ||
                        arg_action == ACTION_WATCH);
 
                 if (access(socket_name, W_OK) < 0) {
-
                         if (arg_action == ACTION_QUERY)
                                 log_info("Not querying '%s' (PID %u), lacking privileges.", message, pid);
 
-                        r = 0;
-                        goto finish;
+                        return 0;
                 }
 
                 if (arg_plymouth) {
                         _cleanup_strv_free_ char **passwords = NULL;
 
-                        if ((r = ask_password_plymouth(message, not_after, filename, accept_cached, &passwords)) >= 0) {
+                        r = ask_password_plymouth(message, not_after, filename, accept_cached, &passwords);
+                        if (r >= 0) {
                                 char **p;
 
                                 packet_length = 1;
                                 STRV_FOREACH(p, passwords)
                                         packet_length += strlen(*p) + 1;
 
-                                if (!(packet = new(char, packet_length)))
+                                packet = new(char, packet_length);
+                                if (!packet)
                                         r = -ENOMEM;
                                 else {
-                                        char *d;
-
-                                        packet[0] = '+';
-                                        d = packet+1;
+                                        char *d = packet + 1;
 
                                         STRV_FOREACH(p, passwords)
                                                 d = stpcpy(d, *p) + 1;
+
+                                        packet[0] = '+';
                                 }
                         }
 
                 } else {
                         int tty_fd = -1;
-                        char *password = NULL;
+                        _cleanup_free_ char *password = NULL;
 
-                        if (arg_console)
-                                if ((tty_fd = acquire_terminal("/dev/console", false, false, false, (usec_t) -1)) < 0) {
-                                        r = tty_fd;
-                                        goto finish;
-                                }
+                        if (arg_console) {
+                                tty_fd = acquire_terminal("/dev/console", false, false, false, USEC_INFINITY);
+                                if (tty_fd < 0)
+                                        return tty_fd;
+                        }
 
                         r = ask_password_tty(message, not_after, filename, &password);
 
                         if (arg_console) {
-                                close_nointr_nofail(tty_fd);
+                                safe_close(tty_fd);
                                 release_terminal();
                         }
 
                         if (r >= 0) {
-                                packet_length = 1+strlen(password)+1;
-                                if (!(packet = new(char, packet_length)))
+                                packet_length = 1 + strlen(password) + 1;
+                                packet = new(char, packet_length);
+                                if (!packet)
                                         r = -ENOMEM;
                                 else {
                                         packet[0] = '+';
-                                        strcpy(packet+1, password);
+                                        strcpy(packet + 1, password);
                                 }
-
-                                free(password);
                         }
                 }
 
-                if (r == -ETIME || r == -ENOENT) {
+                if (IN_SET(r, -ETIME, -ENOENT))
                         /* If the query went away, that's OK */
-                        r = 0;
-                        goto finish;
-                }
+                        return 0;
 
                 if (r < 0) {
                         log_error("Failed to query password: %s", strerror(-r));
-                        goto finish;
+                        return r;
                 }
 
-                if ((socket_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0)) < 0) {
+                socket_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
+                if (socket_fd < 0) {
                         log_error("socket(): %m");
-                        r = -errno;
-                        goto finish;
+                        return -errno;
                 }
 
                 sa.un.sun_family = AF_UNIX;
                 strncpy(sa.un.sun_path, socket_name, sizeof(sa.un.sun_path));
 
-                if (sendto(socket_fd, packet, packet_length, MSG_NOSIGNAL, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(socket_name)) < 0) {
+                r = sendto(socket_fd, packet, packet_length, MSG_NOSIGNAL, &sa.sa,
+                           offsetof(struct sockaddr_un, sun_path) + strlen(socket_name));
+                if (r < 0) {
                         log_error("Failed to send: %m");
-                        r = -errno;
-                        goto finish;
+                        return r;
                 }
         }
 
-finish:
-        fclose(f);
-
-        if (socket_fd >= 0)
-                close_nointr_nofail(socket_fd);
-
-        free(packet);
-        free(socket_name);
-        free(message);
-
-        return r;
+        return 0;
 }
 
 static int wall_tty_block(void) {
-        char *p;
+        _cleanup_free_ char *p = NULL;
         int fd, r;
         dev_t devnr;
 
         r = get_ctty_devnr(0, &devnr);
         if (r < 0)
-                return -r;
+                return r;
 
         if (asprintf(&p, "/run/systemd/ask-password-block/%u:%u", major(devnr), minor(devnr)) < 0)
                 return -ENOMEM;
@@ -445,8 +378,6 @@ static int wall_tty_block(void) {
         mkfifo(p, 0600);
 
         fd = open(p, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY);
-        free(p);
-
         if (fd < 0)
                 return -errno;
 
@@ -454,21 +385,15 @@ static int wall_tty_block(void) {
 }
 
 static bool wall_tty_match(const char *path) {
-        int fd, k;
-        char *p;
+        int fd, r;
         struct stat st;
+        _cleanup_free_ char *p = NULL;
 
-        if (path_is_absolute(path))
-                k = lstat(path, &st);
-        else {
-                if (asprintf(&p, "/dev/%s", path) < 0)
-                        return true;
+        if (!path_is_absolute(path))
+                path = strappenda("/dev/", path);
 
-                k = lstat(p, &st);
-                free(p);
-        }
-
-        if (k < 0)
+        r = lstat(path, &st);
+        if (r < 0)
                 return true;
 
         if (!S_ISCHR(st.st_mode))
@@ -486,33 +411,31 @@ static bool wall_tty_match(const char *path) {
                 return true;
 
         fd = open(p, O_WRONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY);
-        free(p);
-
         if (fd < 0)
                 return true;
 
         /* What, we managed to open the pipe? Then this tty is filtered. */
-        close_nointr_nofail(fd);
+        safe_close(fd);
         return false;
 }
 
 static int show_passwords(void) {
-        DIR *d;
+        _cleanup_closedir_ DIR *d;
         struct dirent *de;
         int r = 0;
 
-        if (!(d = opendir("/run/systemd/ask-password"))) {
+        d = opendir("/run/systemd/ask-password");
+        if (!d) {
                 if (errno == ENOENT)
                         return 0;
 
-                log_error("opendir(): %m");
+                log_error("opendir(/run/systemd/ask-password): %m");
                 return -errno;
         }
 
         while ((de = readdir(d))) {
-                char *p;
+                _cleanup_free_ char *p = NULL, *wall = NULL;
                 int q;
-                char *wall;
 
                 /* We only support /dev on tmpfs, hence we can rely on
                  * d_type to be reliable */
@@ -526,27 +449,18 @@ static int show_passwords(void) {
                 if (!startswith(de->d_name, "ask."))
                         continue;
 
-                if (!(p = strappend("/run/systemd/ask-password/", de->d_name))) {
-                        r = log_oom();
-                        goto finish;
-                }
+                p = strappend("/run/systemd/ask-password/", de->d_name);
+                if (!p)
+                        return log_oom();
 
-                wall = NULL;
-                if ((q = parse_password(p, &wall)) < 0)
+                q = parse_password(p, &wall);
+                if (q < 0 && r == 0)
                         r = q;
 
-                free(p);
-
-                if (wall) {
-                        utmp_wall(wall, wall_tty_match);
-                        free(wall);
-                }
+                if (wall)
+                        utmp_wall(wall, NULL, wall_tty_match);
         }
 
-finish:
-        if (d)
-                closedir(d);
-
         return r;
 }
 
@@ -557,7 +471,7 @@ static int watch_passwords(void) {
                 _FD_MAX
         };
 
-        int notify = -1, signal_fd = -1, tty_block_fd = -1;
+        _cleanup_close_ int notify = -1, signal_fd = -1, tty_block_fd = -1;
         struct pollfd pollfd[_FD_MAX] = {};
         sigset_t mask;
         int r;
@@ -566,25 +480,20 @@ static int watch_passwords(void) {
 
         mkdir_p_label("/run/systemd/ask-password", 0755);
 
-        if ((notify = inotify_init1(IN_CLOEXEC)) < 0) {
-                r = -errno;
-                goto finish;
-        }
+        notify = inotify_init1(IN_CLOEXEC);
+        if (notify < 0)
+                return -errno;
 
-        if (inotify_add_watch(notify, "/run/systemd/ask-password", IN_CLOSE_WRITE|IN_MOVED_TO) < 0) {
-                r = -errno;
-                goto finish;
-        }
+        if (inotify_add_watch(notify, "/run/systemd/ask-password", IN_CLOSE_WRITE|IN_MOVED_TO) < 0)
+                return -errno;
 
         assert_se(sigemptyset(&mask) == 0);
         sigset_add_many(&mask, SIGINT, SIGTERM, -1);
         assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
 
-        if ((signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC)) < 0) {
-                log_error("signalfd(): %m");
-                r = -errno;
-                goto finish;
-        }
+        signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
+        if (signal_fd < 0)
+                return -errno;
 
         pollfd[FD_INOTIFY].fd = notify;
         pollfd[FD_INOTIFY].events = POLLIN;
@@ -592,16 +501,15 @@ static int watch_passwords(void) {
         pollfd[FD_SIGNAL].events = POLLIN;
 
         for (;;) {
-                if ((r = show_passwords()) < 0)
+                r = show_passwords();
+                if (r < 0)
                         log_error("Failed to show password: %s", strerror(-r));
 
                 if (poll(pollfd, _FD_MAX, -1) < 0) {
-
                         if (errno == EINTR)
                                 continue;
 
-                        r = -errno;
-                        goto finish;
+                        return -errno;
                 }
 
                 if (pollfd[FD_INOTIFY].revents != 0)
@@ -611,23 +519,10 @@ static int watch_passwords(void) {
                         break;
         }
 
-        r = 0;
-
-finish:
-        if (notify >= 0)
-                close_nointr_nofail(notify);
-
-        if (signal_fd >= 0)
-                close_nointr_nofail(signal_fd);
-
-        if (tty_block_fd >= 0)
-                close_nointr_nofail(tty_block_fd);
-
-        return r;
+        return 0;
 }
 
-static int help(void) {
-
+static void help(void) {
         printf("%s [OPTIONS...]\n\n"
                "Process system password requests.\n\n"
                "  -h --help     Show this help\n"
@@ -639,8 +534,6 @@ static int help(void) {
                "     --plymouth Ask question with Plymouth instead of on TTY\n"
                "     --console  Ask question on /dev/console instead of current TTY\n",
                program_invocation_short_name);
-
-        return 0;
 }
 
 static int parse_argv(int argc, char *argv[]) {
@@ -672,12 +565,13 @@ static int parse_argv(int argc, char *argv[]) {
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) {
+        while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
 
                 switch (c) {
 
                 case 'h':
-                        return help();
+                        help();
+                        return 0;
 
                 case ARG_VERSION:
                         puts(PACKAGE_STRING);
@@ -714,10 +608,9 @@ static int parse_argv(int argc, char *argv[]) {
                 default:
                         assert_not_reached("Unhandled option");
                 }
-        }
 
         if (optind != argc) {
-                help();
+                log_error("%s takes no arguments.", program_invocation_short_name);
                 return -EINVAL;
         }
 
@@ -733,7 +626,8 @@ int main(int argc, char *argv[]) {
 
         umask(0022);
 
-        if ((r = parse_argv(argc, argv)) <= 0)
+        r = parse_argv(argc, argv);
+        if (r <= 0)
                 goto finish;
 
         if (arg_console) {
@@ -741,8 +635,7 @@ int main(int argc, char *argv[]) {
                 release_terminal();
         }
 
-        if (arg_action == ACTION_WATCH ||
-            arg_action == ACTION_WALL)
+        if (IN_SET(arg_action, ACTION_WATCH, ACTION_WALL))
                 r = watch_passwords();
         else
                 r = show_passwords();
diff --git a/src/udev/accelerometer/Makefile b/src/udev/accelerometer/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
index 925d38d..4513bc6 100644 (file)
 #define LONG(x) ((x)/BITS_PER_LONG)
 #define test_bit(bit, array)    ((array[LONG(bit)] >> OFF(bit)) & 1)
 
-static int debug = 0;
-
 _printf_(6,0)
 static void log_fn(struct udev *udev, int priority,
                    const char *file, int line, const char *fn,
                    const char *format, va_list args)
 {
-        if (debug) {
-                fprintf(stderr, "%s: ", fn);
-                vfprintf(stderr, format, args);
-        } else {
-                vsyslog(priority, format, args);
-        }
+        log_metav(priority, file, line, fn, format, args);
 }
 
 typedef enum {
@@ -180,7 +173,7 @@ get_prev_orientation(struct udev_device *dev)
         return string_to_orientation(value);
 }
 
-#define SET_AXIS(axis, code_) if (ev[i].code == code_) { if (got_##axis == 0) { axis = ev[i].value; got_##axis = true; } }
+#define READ_AXIS(axis, var) { memzero(&abs_info, sizeof(abs_info)); r = ioctl(fd, EVIOCGABS(axis), &abs_info); if (r < 0) return; var = abs_info.value; }
 
 /* accelerometers */
 static void test_orientation(struct udev *udev,
@@ -189,10 +182,9 @@ static void test_orientation(struct udev *udev,
 {
         OrientationUp old, new;
         _cleanup_close_ int fd = -1;
-        struct input_event ev[64];
-        bool got_syn = false;
-        bool got_x = false, got_y = false, got_z = false;
+        struct input_absinfo abs_info;
         int x = 0, y = 0, z = 0;
+        int r;
         char text[64];
 
         old = get_prev_orientation(dev);
@@ -201,30 +193,10 @@ static void test_orientation(struct udev *udev,
         if (fd < 0)
                 return;
 
-        while (1) {
-                int i, r;
-
-                r = read(fd, ev, sizeof(struct input_event) * 64);
-
-                if (r < (int) sizeof(struct input_event))
-                        return;
-
-                for (i = 0; i < r / (int) sizeof(struct input_event); i++) {
-                        if (got_syn) {
-                                if (ev[i].type == EV_ABS) {
-                                        SET_AXIS(x, ABS_X);
-                                        SET_AXIS(y, ABS_Y);
-                                        SET_AXIS(z, ABS_Z);
-                                }
-                        }
-                        if (ev[i].type == EV_SYN && ev[i].code == SYN_REPORT)
-                                got_syn = true;
-                        if (got_x && got_y && got_z)
-                                goto read_dev;
-                }
-        }
+        READ_AXIS(ABS_X, x);
+        READ_AXIS(ABS_Y, y);
+        READ_AXIS(ABS_Z, z);
 
-read_dev:
         new = orientation_calc(old, x, y, z);
         snprintf(text, sizeof(text),
                  "ID_INPUT_ACCELEROMETER_ORIENTATION=%s", orientation_to_string(new));
@@ -254,11 +226,13 @@ int main (int argc, char** argv)
         struct udev_enumerate *enumerate;
         struct udev_list_entry *list_entry;
 
+        log_parse_environment();
+        log_open();
+
         udev = udev_new();
         if (udev == NULL)
                 return 1;
 
-        log_open();
         udev_set_log_fn(udev, log_fn);
 
         /* CLI argument parsing */
@@ -271,9 +245,10 @@ int main (int argc, char** argv)
 
                 switch (option) {
                 case 'd':
-                        debug = 1;
+                        log_set_target(LOG_TARGET_CONSOLE);
                         log_set_max_level(LOG_DEBUG);
                         udev_set_log_priority(udev, LOG_DEBUG);
+                        log_open();
                         break;
                 case 'h':
                         help();
diff --git a/src/udev/ata_id/Makefile b/src/udev/ata_id/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
index f84281d..bfde572 100644 (file)
@@ -410,7 +410,7 @@ static void log_fn(struct udev *udev, int priority,
                    const char *file, int line, const char *fn,
                    const char *format, va_list args)
 {
-        vsyslog(priority, format, args);
+        log_metav(priority, file, line, fn, format, args);
 }
 
 int main(int argc, char *argv[])
@@ -435,11 +435,13 @@ int main(int argc, char *argv[])
                 {}
         };
 
+        log_parse_environment();
+        log_open();
+
         udev = udev_new();
         if (udev == NULL)
                 goto exit;
 
-        log_open();
         udev_set_log_fn(udev, log_fn);
 
         while (1) {
diff --git a/src/udev/cdrom_id/Makefile b/src/udev/cdrom_id/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
index 93467c2..c93a7bf 100644 (file)
 #include "libudev.h"
 #include "libudev-private.h"
 
-static bool debug;
-
 _printf_(6,0)
 static void log_fn(struct udev *udev, int priority,
                    const char *file, int line, const char *fn,
                    const char *format, va_list args)
 {
-        if (debug) {
-                fprintf(stderr, "%s: ", fn);
-                vfprintf(stderr, format, args);
-        } else {
-                vsyslog(priority, format, args);
-        }
+        log_metav(priority, file, line, fn, format, args);
 }
 
 /* device info */
@@ -556,7 +549,7 @@ static int cd_profiles(struct udev *udev, int fd)
         if ((err != 0)) {
                 info_scsi_cmd_err(udev, "GET CONFIGURATION", err);
                 /* handle pre-MMC2 drives which do not support GET CONFIGURATION */
-                if (SK(err) == 0x5 && ASC(err) == 0x20) {
+                if (SK(err) == 0x5 && (ASC(err) == 0x20 || ASC(err) == 0x24)) {
                         log_debug("drive is pre-MMC2 and does not support 46h get configuration command");
                         log_debug("trying to work around the problem");
                         ret = cd_profiles_old_mmc(udev, fd);
@@ -875,11 +868,13 @@ int main(int argc, char *argv[])
         int cnt;
         int rc = 0;
 
+        log_parse_environment();
+        log_open();
+
         udev = udev_new();
         if (udev == NULL)
                 goto exit;
 
-        log_open();
         udev_set_log_fn(udev, log_fn);
 
         while (1) {
@@ -900,9 +895,10 @@ int main(int argc, char *argv[])
                         eject = true;
                         break;
                 case 'd':
-                        debug = true;
+                        log_set_target(LOG_TARGET_CONSOLE);
                         log_set_max_level(LOG_DEBUG);
                         udev_set_log_priority(udev, LOG_DEBUG);
+                        log_open();
                         break;
                 case 'h':
                         printf("Usage: cdrom_id [options] <device>\n"
index 6346530..3ec245e 100644 (file)
@@ -31,7 +31,7 @@
 #include "log.h"
 #include "conf-parser.h"
 
-static const char* const duplex_table[] = {
+static const char* const duplex_table[_DUP_MAX] = {
         [DUP_FULL] = "full",
         [DUP_HALF] = "half"
 };
@@ -39,7 +39,7 @@ static const char* const duplex_table[] = {
 DEFINE_STRING_TABLE_LOOKUP(duplex, Duplex);
 DEFINE_CONFIG_PARSE_ENUM(config_parse_duplex, duplex, Duplex, "Failed to parse duplex setting");
 
-static const char* const wol_table[] = {
+static const char* const wol_table[_WOL_MAX] = {
         [WOL_PHY] = "phy",
         [WOL_MAGIC] = "magic",
         [WOL_OFF] = "off"
index 819e93c..f562498 100644 (file)
@@ -1,7 +1,7 @@
 %{
 #include <stddef.h>
 #include "conf-parser.h"
-#include "net-util.h"
+#include "network-internal.h"
 #include "link-config.h"
 #include "ethtool-util.h"
 %}
index 05225e0..c2881d6 100644 (file)
 ***/
 
 #include <netinet/ether.h>
-#include <net/if.h>
+#include <linux/netdevice.h>
 
 #include "sd-id128.h"
 
+#include "missing.h"
 #include "link-config.h"
 #include "ethtool-util.h"
 
@@ -38,7 +39,7 @@
 #include "fileio.h"
 #include "hashmap.h"
 #include "rtnl-util.h"
-#include "net-util.h"
+#include "network-internal.h"
 #include "siphash24.h"
 
 struct link_config_ctx {
@@ -92,14 +93,20 @@ static int link_config_ctx_connect(link_config_ctx *ctx) {
 
         if (ctx->ethtool_fd == -1) {
                 r = ethtool_connect(&ctx->ethtool_fd);
-                if (r < 0)
+                if (r < 0) {
+                        log_warning("link_config: could not connect to ethtool: %s",
+                                    strerror(-r));
                         return r;
+                }
         }
 
         if (!ctx->rtnl) {
                 r = sd_rtnl_open(&ctx->rtnl, 0);
-                if (r < 0)
+                if (r < 0) {
+                        log_warning("link_config: could not connect to rtnl: %s",
+                                    strerror(-r));
                         return r;
+                }
         }
 
         return 0;
@@ -118,6 +125,7 @@ static void link_configs_free(link_config_ctx *ctx) {
                 free(link->match_type);
                 free(link->description);
                 free(link->alias);
+                free(link->name_policy);
 
                 free(link);
         }
@@ -127,8 +135,7 @@ void link_config_ctx_free(link_config_ctx *ctx) {
         if (!ctx)
                 return;
 
-        if (ctx->ethtool_fd >= 0)
-                close_nointr_nofail(ctx->ethtool_fd);
+        safe_close(ctx->ethtool_fd);
 
         sd_rtnl_unref(ctx->rtnl);
 
@@ -140,8 +147,8 @@ void link_config_ctx_free(link_config_ctx *ctx) {
 }
 
 static int load_link(link_config_ctx *ctx, const char *filename) {
-        link_config *link;
-        _cleanup_fclose_ FILE *file;
+        _cleanup_free_ link_config *link = NULL;
+        _cleanup_fclose_ FILE *file = NULL;
         int r;
 
         assert(ctx);
@@ -152,52 +159,54 @@ static int load_link(link_config_ctx *ctx, const char *filename) {
                 if (errno == ENOENT)
                         return 0;
                 else
-                        return errno;
+                        return -errno;
         }
 
-        link = new0(link_config, 1);
-        if (!link) {
-                r = log_oom();
-                goto failure;
+        if (null_or_empty_fd(fileno(file))) {
+                log_debug("Skipping empty file: %s", filename);
+                return 0;
         }
 
+        link = new0(link_config, 1);
+        if (!link)
+                return log_oom();
+
         link->mac_policy = _MACPOLICY_INVALID;
         link->wol = _WOL_INVALID;
         link->duplex = _DUP_INVALID;
 
-        r = config_parse(NULL, filename, file, "Match\0Link\0Ethernet\0", config_item_perf_lookup,
-                         (void*) link_config_gperf_lookup, false, false, link);
-        if (r < 0) {
-                log_warning("Could not parse config file %s: %s", filename, strerror(-r));
-                goto failure;
-        } else
+        r = config_parse(NULL, filename, file,
+                         "Match\0Link\0Ethernet\0",
+                         config_item_perf_lookup, link_config_gperf_lookup,
+                         false, false, true, link);
+        if (r < 0)
+                return r;
+        else
                 log_debug("Parsed configuration file %s", filename);
 
         link->filename = strdup(filename);
 
         LIST_PREPEND(links, ctx->links, link);
+        link = NULL;
 
         return 0;
-
-failure:
-        free(link);
-        return r;
 }
 
 static bool enable_name_policy(void) {
-        _cleanup_free_ char *line;
-        char *w, *state;
+        _cleanup_free_ char *line = NULL;
+        const char *word, *state;
         int r;
         size_t l;
 
         r = proc_cmdline(&line);
         if (r < 0)
-                log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
+                log_warning("Failed to read /proc/cmdline, ignoring: %s",
+                            strerror(-r));
         if (r <= 0)
                 return true;
 
-        FOREACH_WORD_QUOTED(w, l, line, state)
-                if (strneq(w, "net.ifnames=0", l))
+        FOREACH_WORD_QUOTED(word, l, line, state)
+                if (strneq(word, "net.ifnames=0", l))
                         return false;
 
         return true;
@@ -205,7 +214,8 @@ static bool enable_name_policy(void) {
 
 int link_config_load(link_config_ctx *ctx) {
         int r;
-        char **files, **f;
+        _cleanup_strv_free_ char **files;
+        char **f;
 
         link_configs_free(ctx);
 
@@ -236,15 +246,17 @@ bool link_config_should_reload(link_config_ctx *ctx) {
         return paths_check_timestamp(link_dirs, &ctx->link_dirs_ts_usec, false);
 }
 
-int link_config_get(link_config_ctx *ctx, struct udev_device *device, link_config **ret) {
+int link_config_get(link_config_ctx *ctx, struct udev_device *device,
+                    link_config **ret) {
         link_config *link;
 
         LIST_FOREACH(links, link, ctx->links) {
+                const char* attr_value = udev_device_get_sysattr_value(device, "address");
 
                 if (net_match_config(link->match_mac, link->match_path, link->match_driver,
                                      link->match_type, NULL, link->match_host,
                                      link->match_virt, link->match_kernel, link->match_arch,
-                                     udev_device_get_sysattr_value(device, "address"),
+                                     attr_value ? ether_aton(attr_value) : NULL,
                                      udev_device_get_property_value(device, "ID_PATH"),
                                      udev_device_get_driver(udev_device_get_parent(device)),
                                      udev_device_get_property_value(device, "ID_NET_DRIVER"),
@@ -268,88 +280,80 @@ static bool mac_is_random(struct udev_device *device) {
         unsigned type;
         int r;
 
+        /* if we can't get the assign type, assume it is not random */
         s = udev_device_get_sysattr_value(device, "addr_assign_type");
         if (!s)
-                return false; /* if we don't know, assume it is not random */
+                return false;
+
         r = safe_atou(s, &type);
         if (r < 0)
                 return false;
 
-        /* check for NET_ADDR_RANDOM */
-        return type == 1;
+        return type == NET_ADDR_RANDOM;
 }
 
-static bool mac_is_permanent(struct udev_device *device) {
+static bool should_rename(struct udev_device *device, bool respect_predictable) {
         const char *s;
         unsigned type;
         int r;
 
-        s = udev_device_get_sysattr_value(device, "addr_assign_type");
+        /* if we can't get the assgin type, assume we should rename */
+        s = udev_device_get_sysattr_value(device, "name_assign_type");
         if (!s)
-                return true; /* if we don't know, assume it is permanent */
+                return true;
+
         r = safe_atou(s, &type);
         if (r < 0)
                 return true;
 
-        /* check for NET_ADDR_PERM */
-        return type == 0;
+        switch (type) {
+        case NET_NAME_USER:
+        case NET_NAME_RENAMED:
+                /* these were already named by userspace, do not touch again */
+                return false;
+        case NET_NAME_PREDICTABLE:
+                /* the kernel claims to have given a predictable name */
+                if (respect_predictable)
+                        return false;
+                /* fall through */
+        case NET_NAME_ENUM:
+        default:
+                /* the name is known to be bad, or of an unknown type */
+                return true;
+        }
 }
 
-#define HASH_KEY SD_ID128_MAKE(d3,1e,48,fa,90,fe,4b,4c,9d,af,d5,d7,a1,b1,2e,8a)
-
-static int get_mac(struct udev_device *device, bool want_random, struct ether_addr *mac) {
+static int get_mac(struct udev_device *device, bool want_random,
+                   struct ether_addr *mac) {
         int r;
 
         if (want_random)
                 random_bytes(mac->ether_addr_octet, ETH_ALEN);
         else {
-                const char *name;
                 uint8_t result[8];
-                size_t l, sz;
-                uint8_t *v;
-
-                /* fetch some persistent data unique (on this machine) to this device */
-                name = udev_device_get_property_value(device, "ID_NET_NAME_ONBOARD");
-                if (!name) {
-                        name = udev_device_get_property_value(device, "ID_NET_NAME_SLOT");
-                        if (!name) {
-                                name = udev_device_get_property_value(device, "ID_NET_NAME_PATH");
-                                if (!name)
-                                        return -ENOENT;
-                        }
-                }
 
-                l = strlen(name);
-                sz = sizeof(sd_id128_t) + l;
-                v = alloca(sz);
-
-                /* fetch some persistent data unique to this machine */
-                r = sd_id128_get_machine((sd_id128_t*) v);
+                r = net_get_unique_predictable_data(device, result);
                 if (r < 0)
                         return r;
-                memcpy(v + sizeof(sd_id128_t), name, l);
-
-                /* Let's hash the machine ID plus the device name. We
-                 * use a fixed, but originally randomly created hash
-                 * key here. */
-                siphash24(result, v, sz, HASH_KEY.bytes);
 
                 assert_cc(ETH_ALEN <= sizeof(result));
                 memcpy(mac->ether_addr_octet, result, ETH_ALEN);
         }
 
         /* see eth_random_addr in the kernel */
-        mac->ether_addr_octet[0] &= 0xfe;        /* clear multicast bit */
-        mac->ether_addr_octet[0] |= 0x02;        /* set local assignment bit (IEEE802) */
+        mac->ether_addr_octet[0] &= 0xfe;  /* clear multicast bit */
+        mac->ether_addr_octet[0] |= 0x02;  /* set local assignment bit (IEEE802) */
 
         return 0;
 }
 
-int link_config_apply(link_config_ctx *ctx, link_config *config, struct udev_device *device, const char **name) {
+int link_config_apply(link_config_ctx *ctx, link_config *config,
+                      struct udev_device *device, const char **name) {
         const char *old_name;
         const char *new_name = NULL;
         struct ether_addr generated_mac;
         struct ether_addr *mac = NULL;
+        bool respect_predictable = false;
         int r, ifindex;
 
         assert(ctx);
@@ -365,11 +369,12 @@ int link_config_apply(link_config_ctx *ctx, link_config *config, struct udev_dev
         if (!old_name)
                 return -EINVAL;
 
-        r = ethtool_set_speed(ctx->ethtool_fd, old_name, config->speed / 1024, config->duplex);
+        r = ethtool_set_speed(ctx->ethtool_fd, old_name, config->speed / 1024,
+                              config->duplex);
         if (r < 0)
                 log_warning("Could not set speed or duplex of %s to %u Mbps (%s): %s",
-                            old_name, config->speed / 1024, duplex_to_string(config->duplex),
-                            strerror(-r));
+                            old_name, config->speed / 1024,
+                            duplex_to_string(config->duplex), strerror(-r));
 
         r = ethtool_set_wol(ctx->ethtool_fd, old_name, config->wol);
         if (r < 0)
@@ -385,8 +390,12 @@ int link_config_apply(link_config_ctx *ctx, link_config *config, struct udev_dev
         if (ctx->enable_name_policy && config->name_policy) {
                 NamePolicy *policy;
 
-                for (policy = config->name_policy; !new_name && *policy != _NAMEPOLICY_INVALID; policy++) {
+                for (policy = config->name_policy;
+                     !new_name && *policy != _NAMEPOLICY_INVALID; policy++) {
                         switch (*policy) {
+                                case NAMEPOLICY_KERNEL:
+                                        respect_predictable = true;
+                                        break;
                                 case NAMEPOLICY_DATABASE:
                                         new_name = udev_device_get_property_value(device, "ID_NET_NAME_FROM_DATABASE");
                                         break;
@@ -408,18 +417,22 @@ int link_config_apply(link_config_ctx *ctx, link_config *config, struct udev_dev
                 }
         }
 
-        if (new_name)
-                *name = new_name; /* a name was set by a policy */
-        else if (config->name)
-                *name = config->name; /* a name was set manually in the config */
-        else
-                *name = NULL;
+        if (should_rename(device, respect_predictable)) {
+                /* if not set by policy, fall back manually set name */
+                if (!new_name)
+                        new_name = config->name;
+        } else
+                new_name = NULL;
+
+        *name = new_name;
 
         switch (config->mac_policy) {
                 case MACPOLICY_PERSISTENT:
-                        if (!mac_is_permanent(device)) {
+                        if (mac_is_random(device)) {
                                 r = get_mac(device, false, &generated_mac);
-                                if (r < 0)
+                                if (r == -ENOENT)
+                                        break;
+                                else if (r < 0)
                                         return r;
                                 mac = &generated_mac;
                         }
@@ -427,7 +440,9 @@ int link_config_apply(link_config_ctx *ctx, link_config *config, struct udev_dev
                 case MACPOLICY_RANDOM:
                         if (!mac_is_random(device)) {
                                 r = get_mac(device, true, &generated_mac);
-                                if (r < 0)
+                                if (r == -ENOENT)
+                                        break;
+                                else if (r < 0)
                                         return r;
                                 mac = &generated_mac;
                         }
@@ -436,9 +451,11 @@ int link_config_apply(link_config_ctx *ctx, link_config *config, struct udev_dev
                         mac = config->mac;
         }
 
-        r = rtnl_set_link_properties(ctx->rtnl, ifindex, config->alias, mac, config->mtu);
+        r = rtnl_set_link_properties(ctx->rtnl, ifindex, config->alias, mac,
+                                     config->mtu);
         if (r < 0) {
-                log_warning("Could not set Alias, MACAddress or MTU on %s: %s", old_name, strerror(-r));
+                log_warning("Could not set Alias, MACAddress or MTU on %s: %s",
+                            old_name, strerror(-r));
                 return r;
         }
 
@@ -466,15 +483,17 @@ int link_get_driver(link_config_ctx *ctx, struct udev_device *device, char **ret
         return 0;
 }
 
-static const char* const mac_policy_table[] = {
+static const char* const mac_policy_table[_MACPOLICY_MAX] = {
         [MACPOLICY_PERSISTENT] = "persistent",
         [MACPOLICY_RANDOM] = "random"
 };
 
 DEFINE_STRING_TABLE_LOOKUP(mac_policy, MACPolicy);
-DEFINE_CONFIG_PARSE_ENUM(config_parse_mac_policy, mac_policy, MACPolicy, "Failed to parse MAC address policy");
+DEFINE_CONFIG_PARSE_ENUM(config_parse_mac_policy, mac_policy, MACPolicy,
+                         "Failed to parse MAC address policy");
 
-static const char* const name_policy_table[] = {
+static const char* const name_policy_table[_NAMEPOLICY_MAX] = {
+        [NAMEPOLICY_KERNEL] = "kernel",
         [NAMEPOLICY_DATABASE] = "database",
         [NAMEPOLICY_ONBOARD] = "onboard",
         [NAMEPOLICY_SLOT] = "slot",
@@ -483,4 +502,6 @@ static const char* const name_policy_table[] = {
 };
 
 DEFINE_STRING_TABLE_LOOKUP(name_policy, NamePolicy);
-DEFINE_CONFIG_PARSE_ENUMV(config_parse_name_policy, name_policy, NamePolicy, _NAMEPOLICY_INVALID, "Failed to parse interface name policy");
+DEFINE_CONFIG_PARSE_ENUMV(config_parse_name_policy, name_policy, NamePolicy,
+                          _NAMEPOLICY_INVALID,
+                          "Failed to parse interface name policy");
index 24fdb87..5f3d4ad 100644 (file)
@@ -39,6 +39,7 @@ typedef enum MACPolicy {
 } MACPolicy;
 
 typedef enum NamePolicy {
+        NAMEPOLICY_KERNEL,
         NAMEPOLICY_DATABASE,
         NAMEPOLICY_ONBOARD,
         NAMEPOLICY_SLOT,
diff --git a/src/udev/scsi_id/Makefile b/src/udev/scsi_id/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
index 03bd3a9..4d9378a 100644 (file)
@@ -25,7 +25,6 @@
 #include <fcntl.h>
 #include <errno.h>
 #include <string.h>
-#include <syslog.h>
 #include <ctype.h>
 #include <getopt.h>
 #include <sys/stat.h>
@@ -55,7 +54,6 @@ static bool dev_specified = false;
 static char config_file[MAX_PATH_LEN] = "/etc/scsi_id.config";
 static enum page_code default_page_code = PAGE_UNSPECIFIED;
 static int sg_version = 4;
-static int debug = 0;
 static bool reformat_serial = false;
 static bool export = false;
 static char vendor_str[64];
@@ -70,7 +68,7 @@ static void log_fn(struct udev *udev, int priority,
                    const char *file, int line, const char *fn,
                    const char *format, va_list args)
 {
-        vsyslog(priority, format, args);
+        log_metav(priority, file, line, fn, format, args);
 }
 
 static void set_type(const char *from, char *to, size_t len)
@@ -390,13 +388,15 @@ static int set_options(struct udev *udev,
                         break;
 
                 case 'v':
-                        debug++;
+                        log_set_target(LOG_TARGET_CONSOLE);
+                        log_set_max_level(LOG_DEBUG);
+                        udev_set_log_priority(udev, LOG_DEBUG);
+                        log_open();
                         break;
 
                 case 'V':
                         printf("%s\n", VERSION);
                         exit(0);
-                        break;
 
                 case 'x':
                         export = true;
@@ -584,11 +584,13 @@ int main(int argc, char **argv)
         int newargc;
         char **newargv = NULL;
 
+        log_parse_environment();
+        log_open();
+
         udev = udev_new();
         if (udev == NULL)
                 goto exit;
 
-        log_open();
         udev_set_log_fn(udev, log_fn);
 
         /*
index 378a73d..b3d20a3 100644 (file)
@@ -26,7 +26,6 @@
 #include <fcntl.h>
 #include <stdlib.h>
 #include <unistd.h>
-#include <syslog.h>
 #include <time.h>
 #include <inttypes.h>
 #include <scsi/scsi.h>
index c806bd6..810f27d 100644 (file)
 #include <sys/stat.h>
 #include <blkid/blkid.h>
 
+#include "sd-id128.h"
+#include "gpt.h"
+#include "efivars.h"
 #include "udev.h"
 
-static void print_property(struct udev_device *dev, bool test, const char *name, const char *value)
-{
-        char s[265];
+static void print_property(struct udev_device *dev, bool test, const char *name, const char *value) {
+        char s[256];
 
         s[0] = '\0';
 
@@ -100,8 +102,86 @@ static void print_property(struct udev_device *dev, bool test, const char *name,
         }
 }
 
-static int probe_superblocks(blkid_probe pr)
-{
+static int find_gpt_root(struct udev_device *dev, blkid_probe pr, bool test) {
+
+#if defined(GPT_ROOT_NATIVE) && defined(ENABLE_EFI)
+
+        _cleanup_free_ char *root_id = NULL;
+        bool found_esp = false;
+        blkid_partlist pl;
+        int i, nvals, r;
+
+        assert(pr);
+
+        /* Iterate through the partitions on this disk, and see if the
+         * EFI ESP we booted from is on it. If so, find the first root
+         * disk, and add a property indicating its partition UUID. */
+
+        errno = 0;
+        pl = blkid_probe_get_partitions(pr);
+        if (!pl)
+                return errno ? -errno : -ENOMEM;
+
+        nvals = blkid_partlist_numof_partitions(pl);
+        for (i = 0; i < nvals; i++) {
+                blkid_partition pp;
+                const char *stype, *sid;
+                sd_id128_t type;
+
+                pp = blkid_partlist_get_partition(pl, i);
+                if (!pp)
+                        continue;
+
+                sid = blkid_partition_get_uuid(pp);
+                if (!sid)
+                        continue;
+
+                stype = blkid_partition_get_type_string(pp);
+                if (!stype)
+                        continue;
+
+                if (sd_id128_from_string(stype, &type) < 0)
+                        continue;
+
+                if (sd_id128_equal(type, GPT_ESP)) {
+                        sd_id128_t id, esp;
+
+                        /* We found an ESP, let's see if it matches
+                         * the ESP we booted from. */
+
+                        if (sd_id128_from_string(sid, &id) < 0)
+                                continue;
+
+                        r = efi_loader_get_device_part_uuid(&esp);
+                        if (r < 0)
+                                return r;
+
+                        if (sd_id128_equal(id, esp))
+                                found_esp = true;
+
+                } else if (sd_id128_equal(type, GPT_ROOT_NATIVE)) {
+
+                        /* We found a suitable root partition, let's
+                         * remember the first one. */
+
+                        if (!root_id) {
+                                root_id = strdup(sid);
+                                if (!root_id)
+                                        return -ENOMEM;
+                        }
+                }
+        }
+
+        /* We found the ESP on this disk, and also found a root
+         * partition, nice! Let's export its UUID */
+        if (found_esp && root_id)
+                udev_builtin_add_property(dev, test, "ID_PART_GPT_AUTO_ROOT_UUID", root_id);
+#endif
+
+        return 0;
+}
+
+static int probe_superblocks(blkid_probe pr) {
         struct stat st;
         int rc;
 
@@ -110,7 +190,8 @@ static int probe_superblocks(blkid_probe pr)
 
         blkid_probe_enable_partitions(pr, 1);
 
-        if (!S_ISCHR(st.st_mode) && blkid_probe_get_size(pr) <= 1024 * 1440 &&
+        if (!S_ISCHR(st.st_mode) &&
+            blkid_probe_get_size(pr) <= 1024 * 1440 &&
             blkid_probe_is_wholedisk(pr)) {
                 /*
                  * check if the small disk is partitioned, if yes then
@@ -120,7 +201,7 @@ static int probe_superblocks(blkid_probe pr)
 
                 rc = blkid_do_fullprobe(pr);
                 if (rc < 0)
-                        return rc;        /* -1 = error, 1 = nothing, 0 = succes */
+                        return rc;        /* -1 = error, 1 = nothing, 0 = success */
 
                 if (blkid_probe_lookup_value(pr, "PTTYPE", NULL, NULL) == 0)
                         return 0;        /* partition table detected */
@@ -132,18 +213,18 @@ static int probe_superblocks(blkid_probe pr)
         return blkid_do_safeprobe(pr);
 }
 
-static int builtin_blkid(struct udev_device *dev, int argc, char *argv[], bool test)
-{
+static int builtin_blkid(struct udev_device *dev, int argc, char *argv[], bool test) {
+        const char *root_partition;
         int64_t offset = 0;
         bool noraid = false;
-        int fd = -1;
+        _cleanup_close_ int fd = -1;
         blkid_probe pr;
         const char *data;
         const char *name;
         int nvals;
         int i;
-        size_t len;
         int err = 0;
+        bool is_gpt = false;
 
         static const struct option options[] = {
                 { "offset", optional_argument, NULL, 'o' },
@@ -190,28 +271,43 @@ static int builtin_blkid(struct udev_device *dev, int argc, char *argv[], bool t
         if (err < 0)
                 goto out;
 
-        log_debug("probe %s %sraid offset=%llu",
+        log_debug("probe %s %sraid offset=%"PRIu64,
                   udev_device_get_devnode(dev),
-                  noraid ? "no" : "", (unsigned long long) offset);
+                  noraid ? "no" : "", offset);
 
         err = probe_superblocks(pr);
         if (err < 0)
                 goto out;
 
+        /* If we are a partition then our parent passed on the root
+         * partition UUID to us */
+        root_partition = udev_device_get_property_value(dev, "ID_PART_GPT_AUTO_ROOT_UUID");
+
         nvals = blkid_probe_numof_values(pr);
         for (i = 0; i < nvals; i++) {
-                if (blkid_probe_get_value(pr, i, &name, &data, &len))
+                if (blkid_probe_get_value(pr, i, &name, &data, NULL))
                         continue;
-                len = strnlen((char *) data, len);
-                print_property(dev, test, name, (char *) data);
+
+                print_property(dev, test, name, data);
+
+                /* Is this a disk with GPT partition table? */
+                if (streq(name, "PTTYPE") && streq(data, "gpt"))
+                        is_gpt = true;
+
+                /* Is this a partition that matches the root partition
+                 * property we inherited from our parent? */
+                if (root_partition && streq(name, "PART_ENTRY_UUID") && streq(data, root_partition))
+                        udev_builtin_add_property(dev, test, "ID_PART_GPT_AUTO_ROOT", "1");
         }
 
+        if (is_gpt)
+                find_gpt_root(dev, pr, test);
+
         blkid_free_probe(pr);
 out:
-        if (fd > 0)
-                close(fd);
         if (err < 0)
                 return EXIT_FAILURE;
+
         return EXIT_SUCCESS;
 }
 
index 2baafe6..2e2112f 100644 (file)
 #include <fcntl.h>
 #include <errno.h>
 #include <sys/ioctl.h>
+#ifdef HAVE_LINUX_BTRFS_H
+#include <linux/btrfs.h>
+#endif
 
+#include "missing.h"
 #include "udev.h"
 
-#define BTRFS_PATH_NAME_MAX 4087
-struct btrfs_ioctl_vol_args {
-        int64_t fd;
-        char name[BTRFS_PATH_NAME_MAX + 1];
-};
-#define BTRFS_IOCTL_MAGIC 0x94
-#define BTRFS_IOC_DEVICES_READY _IOR(BTRFS_IOCTL_MAGIC, 39, struct btrfs_ioctl_vol_args)
-
-static int builtin_btrfs(struct udev_device *dev, int argc, char *argv[], bool test)
-{
+static int builtin_btrfs(struct udev_device *dev, int argc, char *argv[], bool test) {
         struct  btrfs_ioctl_vol_args args;
         _cleanup_close_ int fd = -1;
         int err;
index 0ca54a8..c9c64e6 100644 (file)
@@ -27,8 +27,7 @@
 
 #include "udev.h"
 
-static bool set_loading(struct udev *udev, char *loadpath, const char *state)
-{
+static bool set_loading(struct udev *udev, char *loadpath, const char *state) {
         FILE *ldfile;
 
         ldfile = fopen(loadpath, "we");
@@ -41,8 +40,7 @@ static bool set_loading(struct udev *udev, char *loadpath, const char *state)
         return true;
 }
 
-static bool copy_firmware(struct udev *udev, const char *source, const char *target, size_t size)
-{
+static bool copy_firmware(struct udev *udev, const char *source, const char *target, size_t size) {
         char *buf;
         FILE *fsource = NULL, *ftarget = NULL;
         bool ret = false;
@@ -104,8 +102,7 @@ static FILE* find_firmware(const char *path, const char *fwpath, const char *fir
 }
 #endif
 
-static int builtin_firmware(struct udev_device *dev, int argc, char *argv[], bool test)
-{
+static int builtin_firmware(struct udev_device *dev, int argc, char *argv[], bool test) {
         struct udev *udev = udev_device_get_udev(dev);
         static const char *searchpath[] = { FIRMWARE_PATH };
         char loadpath[UTIL_PATH_SIZE];
index d6aa96b..cac97e7 100644 (file)
@@ -183,8 +183,7 @@ static int builtin_hwdb(struct udev_device *dev, int argc, char *argv[], bool te
 }
 
 /* called at udev startup and reload */
-static int builtin_hwdb_init(struct udev *udev)
-{
+static int builtin_hwdb_init(struct udev *udev) {
         if (hwdb)
                 return 0;
         hwdb = udev_hwdb_new(udev);
@@ -194,14 +193,12 @@ static int builtin_hwdb_init(struct udev *udev)
 }
 
 /* called on udev shutdown and reload request */
-static void builtin_hwdb_exit(struct udev *udev)
-{
+static void builtin_hwdb_exit(struct udev *udev) {
         hwdb = udev_hwdb_unref(hwdb);
 }
 
 /* called every couple of seconds during event activity; 'true' if config has changed */
-static bool builtin_hwdb_validate(struct udev *udev)
-{
+static bool builtin_hwdb_validate(struct udev *udev) {
         return udev_hwdb_validate(hwdb);
 }
 
index 828b349..1a1121e 100644 (file)
@@ -47,8 +47,7 @@
 static void get_cap_mask(struct udev_device *dev,
                          struct udev_device *pdev, const char* attr,
                          unsigned long *bitmask, size_t bitmask_size,
-                         bool test)
-{
+                         bool test) {
         char text[4096];
         unsigned i;
         char* word;
@@ -96,8 +95,7 @@ static void test_pointers (struct udev_device *dev,
                            const unsigned long* bitmask_abs,
                            const unsigned long* bitmask_key,
                            const unsigned long* bitmask_rel,
-                           bool test)
-{
+                           bool test) {
         int is_mouse = 0;
         int is_touchpad = 0;
 
@@ -116,16 +114,27 @@ static void test_pointers (struct udev_device *dev,
                         udev_builtin_add_property(dev, test, "ID_INPUT_TABLET", "1");
                 else if (test_bit (BTN_TOOL_FINGER, bitmask_key) && !test_bit (BTN_TOOL_PEN, bitmask_key))
                         is_touchpad = 1;
-                else if (test_bit (BTN_TRIGGER, bitmask_key) ||
-                         test_bit (BTN_A, bitmask_key) ||
-                         test_bit (BTN_1, bitmask_key))
-                        udev_builtin_add_property(dev, test, "ID_INPUT_JOYSTICK", "1");
                 else if (test_bit (BTN_MOUSE, bitmask_key))
                         /* This path is taken by VMware's USB mouse, which has
                          * absolute axes, but no touch/pressure button. */
                         is_mouse = 1;
                 else if (test_bit (BTN_TOUCH, bitmask_key))
                         udev_builtin_add_property(dev, test, "ID_INPUT_TOUCHSCREEN", "1");
+                /* joysticks don't necessarily have to have buttons; e. g.
+                 * rudders/pedals are joystick-like, but buttonless; they have
+                 * other fancy axes */
+                else if (test_bit (BTN_TRIGGER, bitmask_key) ||
+                         test_bit (BTN_A, bitmask_key) ||
+                         test_bit (BTN_1, bitmask_key) ||
+                         test_bit (ABS_RX, bitmask_abs) ||
+                         test_bit (ABS_RY, bitmask_abs) ||
+                         test_bit (ABS_RZ, bitmask_abs) ||
+                         test_bit (ABS_THROTTLE, bitmask_abs) ||
+                         test_bit (ABS_RUDDER, bitmask_abs) ||
+                         test_bit (ABS_WHEEL, bitmask_abs) ||
+                         test_bit (ABS_GAS, bitmask_abs) ||
+                         test_bit (ABS_BRAKE, bitmask_abs))
+                        udev_builtin_add_property(dev, test, "ID_INPUT_JOYSTICK", "1");
         }
 
         if (test_bit (EV_REL, bitmask_ev) &&
@@ -143,8 +152,7 @@ static void test_pointers (struct udev_device *dev,
 static void test_key (struct udev_device *dev,
                       const unsigned long* bitmask_ev,
                       const unsigned long* bitmask_key,
-                      bool test)
-{
+                      bool test) {
         unsigned i;
         unsigned long found;
         unsigned long mask;
@@ -182,8 +190,7 @@ static void test_key (struct udev_device *dev,
                 udev_builtin_add_property(dev, test, "ID_INPUT_KEYBOARD", "1");
 }
 
-static int builtin_input_id(struct udev_device *dev, int argc, char *argv[], bool test)
-{
+static int builtin_input_id(struct udev_device *dev, int argc, char *argv[], bool test) {
         struct udev_device *pdev;
         unsigned long bitmask_ev[NBITS(EV_MAX)];
         unsigned long bitmask_abs[NBITS(ABS_MAX)];
index 614e44e..d6b7dbb 100644 (file)
@@ -78,7 +78,7 @@ static int builtin_keyboard(struct udev_device *dev, int argc, char *argv[], boo
 
         udev_list_entry_foreach(entry, udev_device_get_properties_list_entry(dev)) {
                 const char *key;
-                unsigned int scancode;
+                unsigned int scancode, keycode_num;
                 char *endptr;
                 const char *keycode;
                 const struct key *k;
@@ -110,13 +110,19 @@ static int builtin_keyboard(struct udev_device *dev, int argc, char *argv[], boo
 
                 /* translate identifier to key code */
                 k = keyboard_lookup_key(keycode, strlen(keycode));
-                if (!k) {
-                        log_error("Error, unknown key identifier '%s'", keycode);
-                        continue;
+                if (k) {
+                        keycode_num = k->id;
+                } else {
+                        /* check if it's a numeric code already */
+                        keycode_num = strtoul(keycode, &endptr, 0);
+                        if (endptr[0] !='\0') {
+                                log_error("Error, unknown key identifier '%s'", keycode);
+                                continue;
+                        }
                 }
 
                 map[map_count].scan = scancode;
-                map[map_count].key = k->id;
+                map[map_count].key = keycode_num;
                 if (map_count < ELEMENTSOF(map)-1)
                         map_count++;
         }
@@ -143,7 +149,7 @@ static int builtin_keyboard(struct udev_device *dev, int argc, char *argv[], boo
                         log_debug("keyboard: mapping scan code %d (0x%x) to key code %d (0x%x)",
                                   map[i].scan, map[i].scan, map[i].key, map[i].key);
                         if (ioctl(fd, EVIOCSKEYCODE, &map[i]) < 0)
-                                log_error("Error calling EVIOCSKEYCODE (scan code 0x%x, key code %d): %m", map[i].scan, map[i].key);
+                                log_error("Error calling EVIOCSKEYCODE on device node '%s' (scan code 0x%x, key code %d): %m", node, map[i].scan, map[i].key);
                 }
 
                 /* install list of force-release codes */
index 5880c38..454ee2e 100644 (file)
@@ -33,8 +33,7 @@
 
 static struct kmod_ctx *ctx;
 
-static int load_module(struct udev *udev, const char *alias)
-{
+static int load_module(struct udev *udev, const char *alias) {
         struct kmod_list *list = NULL;
         struct kmod_list *l;
         int err;
@@ -66,13 +65,11 @@ static int load_module(struct udev *udev, const char *alias)
 
 _printf_(6,0)
 static void udev_kmod_log(void *data, int priority, const char *file, int line,
-                          const char *fn, const char *format, va_list args)
-{
+                          const char *fn, const char *format, va_list args) {
         udev_main_log(data, priority, file, line, fn, format, args);
 }
 
-static int builtin_kmod(struct udev_device *dev, int argc, char *argv[], bool test)
-{
+static int builtin_kmod(struct udev_device *dev, int argc, char *argv[], bool test) {
         struct udev *udev = udev_device_get_udev(dev);
         int i;
 
@@ -93,8 +90,7 @@ static int builtin_kmod(struct udev_device *dev, int argc, char *argv[], bool te
 }
 
 /* called at udev startup and reload */
-static int builtin_kmod_init(struct udev *udev)
-{
+static int builtin_kmod_init(struct udev *udev) {
         if (ctx)
                 return 0;
 
@@ -109,15 +105,13 @@ static int builtin_kmod_init(struct udev *udev)
 }
 
 /* called on udev shutdown and reload request */
-static void builtin_kmod_exit(struct udev *udev)
-{
+static void builtin_kmod_exit(struct udev *udev) {
         log_debug("unload module index");
         ctx = kmod_unref(ctx);
 }
 
 /* called every couple of seconds during event activity; 'true' if config has changed */
-static bool builtin_kmod_validate(struct udev *udev)
-{
+static bool builtin_kmod_validate(struct udev *udev) {
         log_debug("validate module index");
         if (!ctx)
                 return false;
index 4f2b2c1..3e2c8f8 100644 (file)
  *   ww -- wwan
  *
  * Type of names:
+ *   b<number>                             -- BCMA bus core number
+ *   ccw<name>                             -- CCW bus group name
  *   o<index>                              -- on-board device index number
- *   s<slot>[f<function>][d<dev_id>]       -- hotplug slot index number
+ *   s<slot>[f<function>][d<dev_port>]     -- hotplug slot index number
  *   x<MAC>                                -- MAC address
- *   [P<domain>]p<bus>s<slot>[f<function>][d<dev_id>]
+ *   [P<domain>]p<bus>s<slot>[f<function>][d<dev_port>]
  *                                         -- PCI geographical location
  *   [P<domain>]p<bus>s<slot>[f<function>][u<port>][..][c<config>][i<interface>]
  *                                         -- USB port number chain
@@ -92,6 +94,7 @@
 #include <string.h>
 #include <errno.h>
 #include <net/if.h>
+#include <net/if_arp.h>
 #include <linux/pci_regs.h>
 
 #include "udev.h"
@@ -119,12 +122,8 @@ struct netnames {
         const char *pci_onboard_label;
 
         char usb_ports[IFNAMSIZ];
-
         char bcma_core[IFNAMSIZ];
-
-        char virtio_core[IFNAMSIZ];
-
-        char ccw_core[IFNAMSIZ];
+        char ccw_group[IFNAMSIZ];
 };
 
 /* retrieve on-board index number and label from firmware */
@@ -150,30 +149,27 @@ static int dev_pci_onboard(struct udev_device *dev, struct netnames *names) {
 
 /* read the 256 bytes PCI configuration space to check the multi-function bit */
 static bool is_pci_multifunction(struct udev_device *dev) {
-        char filename[256];
-        FILE *f = NULL;
-        char config[64];
-        bool multi = false;
+        _cleanup_fclose_ FILE *f = NULL;
+        const char *filename;
+        uint8_t config[64];
 
-        snprintf(filename, sizeof(filename), "%s/config", udev_device_get_syspath(dev));
+        filename = strappenda(udev_device_get_syspath(dev), "/config");
         f = fopen(filename, "re");
         if (!f)
-                goto out;
+                return false;
         if (fread(&config, sizeof(config), 1, f) != 1)
-                goto out;
+                return false;
 
         /* bit 0-6 header type, bit 7 multi/single function device */
         if ((config[PCI_HEADER_TYPE] & 0x80) != 0)
-                multi = true;
-out:
-        if (f)
-                fclose(f);
-        return multi;
+                return true;
+
+        return false;
 }
 
 static int dev_pci_slot(struct udev_device *dev, struct netnames *names) {
         struct udev *udev = udev_device_get_udev(names->pcidev);
-        unsigned domain, bus, slot, func, dev_id = 0;
+        unsigned domain, bus, slot, func, dev_port = 0;
         size_t l;
         char *s;
         const char *attr;
@@ -187,9 +183,9 @@ static int dev_pci_slot(struct udev_device *dev, struct netnames *names) {
                 return -ENOENT;
 
         /* kernel provided multi-device index */
-        attr = udev_device_get_sysattr_value(dev, "dev_id");
+        attr = udev_device_get_sysattr_value(dev, "dev_port");
         if (attr)
-                dev_id = strtol(attr, NULL, 16);
+                dev_port = strtol(attr, NULL, 10);
 
         /* compose a name based on the raw kernel's PCI bus, slot numbers */
         s = names->pci_path;
@@ -199,8 +195,8 @@ static int dev_pci_slot(struct udev_device *dev, struct netnames *names) {
         l = strpcpyf(&s, l, "p%ds%d", bus, slot);
         if (func > 0 || is_pci_multifunction(names->pcidev))
                 l = strpcpyf(&s, l, "f%d", func);
-        if (dev_id > 0)
-                l = strpcpyf(&s, l, "d%d", dev_id);
+        if (dev_port > 0)
+                l = strpcpyf(&s, l, "d%d", dev_port);
         if (l == 0)
                 names->pci_path[0] = '\0';
 
@@ -249,8 +245,8 @@ static int dev_pci_slot(struct udev_device *dev, struct netnames *names) {
                 l = strpcpyf(&s, l, "s%d", hotplug_slot);
                 if (func > 0 || is_pci_multifunction(names->pcidev))
                         l = strpcpyf(&s, l, "f%d", func);
-                if (dev_id > 0)
-                        l = strpcpyf(&s, l, "d%d", dev_id);
+                if (dev_port > 0)
+                        l = strpcpyf(&s, l, "d%d", dev_port);
                 if (l == 0)
                         names->pci_path[0] = '\0';
         }
@@ -351,25 +347,6 @@ static int names_bcma(struct udev_device *dev, struct netnames *names) {
         return 0;
 }
 
-static int names_virtio(struct udev_device *dev, struct netnames *names) {
-        struct udev_device *virtdev;
-        unsigned int core;
-
-        virtdev = udev_device_get_parent_with_subsystem_devtype(dev, "virtio", NULL);
-        if (!virtdev)
-                return -ENOENT;
-
-        /* core num */
-        if (sscanf(udev_device_get_sysname(virtdev), "virtio%u", &core) != 1)
-                return -EINVAL;
-        /* suppress the common core == 0 */
-        if (core > 0)
-                snprintf(names->virtio_core, sizeof(names->virtio_core), "v%u", core);
-
-        names->type = NET_VIRTIO;
-        return 0;
-}
-
 static int names_ccw(struct  udev_device *dev, struct netnames *names) {
         struct udev_device *cdev;
         const char *bus_id;
@@ -402,8 +379,8 @@ static int names_ccw(struct  udev_device *dev, struct netnames *names) {
                 return -EINVAL;
 
         /* Store the CCW bus-ID for use as network device name */
-        rc = snprintf(names->ccw_core, sizeof(names->ccw_core), "ccw%s", bus_id);
-        if (rc >= 0 && rc < (int)sizeof(names->ccw_core))
+        rc = snprintf(names->ccw_group, sizeof(names->ccw_group), "ccw%s", bus_id);
+        if (rc >= 0 && rc < (int)sizeof(names->ccw_group))
                 names->type = NET_CCWGROUP;
         return 0;
 }
@@ -472,10 +449,10 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool
                 return EXIT_FAILURE;
         i = strtoul(s, NULL, 0);
         switch (i) {
-        case 1: /* ARPHRD_ETHER */
+        case ARPHRD_ETHER:
                 prefix = "en";
                 break;
-        case 256: /* ARPHRD_SLIP */
+        case ARPHRD_SLIP:
                 prefix = "sl";
                 break;
         default:
@@ -517,7 +494,7 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool
         if (err >= 0 && names.type == NET_CCWGROUP) {
                 char str[IFNAMSIZ];
 
-                if (snprintf(str, sizeof(str), "%s%s", prefix, names.ccw_core) < (int)sizeof(str))
+                if (snprintf(str, sizeof(str), "%s%s", prefix, names.ccw_group) < (int)sizeof(str))
                         udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str);
                 goto out;
         }
@@ -578,22 +555,6 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool
                                 udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str);
                 goto out;
         }
-
-        /* virtio bus */
-        err = names_virtio(dev, &names);
-        if (err >= 0 && names.type == NET_VIRTIO) {
-                char str[IFNAMSIZ];
-
-                if (names.pci_path[0])
-                        if (snprintf(str, sizeof(str), "%s%s%s", prefix, names.pci_path, names.virtio_core) < (int)sizeof(str))
-                                udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str);
-
-                if (names.pci_slot[0])
-                        if (snprintf(str, sizeof(str), "%s%s%s", prefix, names.pci_slot, names.virtio_core) < (int)sizeof(str))
-                                udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str);
-                goto out;
-        }
-
 out:
         return EXIT_SUCCESS;
 }
index 3cd384e..6207269 100644 (file)
@@ -43,17 +43,17 @@ static int builtin_net_setup_link(struct udev_device *dev, int argc, char **argv
         r = link_config_get(ctx, dev, &link);
         if (r < 0) {
                 if (r == -ENOENT) {
-                        log_debug("No matching link configuration found");
+                        log_debug("No matching link configuration found.");
                         return EXIT_SUCCESS;
                 } else {
-                        log_error("Could not get link config");
+                        log_error("Could not get link config: %s", strerror(-r));
                         return EXIT_FAILURE;
                 }
         }
 
         r = link_config_apply(ctx, link, dev, &name);
         if (r < 0) {
-                log_error("Could not apply link config to %s", udev_device_get_sysname(dev));
+                log_error("Could not apply link config to %s: %s", udev_device_get_sysname(dev), strerror(-r));
                 return EXIT_FAILURE;
         }
 
@@ -77,18 +77,18 @@ static int builtin_net_setup_link_init(struct udev *udev) {
         if (r < 0)
                 return r;
 
-        log_debug("Created link configuration context");
+        log_debug("Created link configuration context.");
         return 0;
 }
 
 static void builtin_net_setup_link_exit(struct udev *udev) {
         link_config_ctx_free(ctx);
         ctx = NULL;
-        log_debug("Unloaded link configuration context");
+        log_debug("Unloaded link configuration context.");
 }
 
 static bool builtin_net_setup_link_validate(struct udev *udev) {
-        log_debug("Check if link configuration needs reloading");
+        log_debug("Check if link configuration needs reloading.");
         if (!ctx)
                 return false;
 
index 0599980..073f05a 100644 (file)
@@ -33,8 +33,7 @@
 #include "udev.h"
 
 _printf_(2,3)
-static int path_prepend(char **path, const char *fmt, ...)
-{
+static int path_prepend(char **path, const char *fmt, ...) {
         va_list va;
         char *pre;
         int err = 0;
@@ -65,8 +64,7 @@ out:
 ** Linux only supports 32 bit luns.
 ** See drivers/scsi/scsi_scan.c::scsilun_to_int() for more details.
 */
-static int format_lun_number(struct udev_device *dev, char **path)
-{
+static int format_lun_number(struct udev_device *dev, char **path) {
         unsigned long lun = strtoul(udev_device_get_sysnum(dev), NULL, 10);
 
         /* address method 0, peripheral device addressing with bus id of zero */
@@ -76,8 +74,7 @@ static int format_lun_number(struct udev_device *dev, char **path)
         return path_prepend(path, "lun-0x%04lx%04lx00000000", lun & 0xffff, (lun >> 16) & 0xffff);
 }
 
-static struct udev_device *skip_subsystem(struct udev_device *dev, const char *subsys)
-{
+static struct udev_device *skip_subsystem(struct udev_device *dev, const char *subsys) {
         struct udev_device *parent = dev;
 
         while (parent != NULL) {
@@ -92,8 +89,7 @@ static struct udev_device *skip_subsystem(struct udev_device *dev, const char *s
         return dev;
 }
 
-static struct udev_device *handle_scsi_fibre_channel(struct udev_device *parent, char **path)
-{
+static struct udev_device *handle_scsi_fibre_channel(struct udev_device *parent, char **path) {
         struct udev *udev  = udev_device_get_udev(parent);
         struct udev_device *targetdev;
         struct udev_device *fcdev = NULL;
@@ -122,8 +118,7 @@ out:
         return parent;
 }
 
-static struct udev_device *handle_scsi_sas(struct udev_device *parent, char **path)
-{
+static struct udev_device *handle_scsi_sas(struct udev_device *parent, char **path) {
         struct udev *udev  = udev_device_get_udev(parent);
         struct udev_device *targetdev;
         struct udev_device *target_parent;
@@ -159,8 +154,7 @@ out:
         return parent;
 }
 
-static struct udev_device *handle_scsi_iscsi(struct udev_device *parent, char **path)
-{
+static struct udev_device *handle_scsi_iscsi(struct udev_device *parent, char **path) {
         struct udev *udev  = udev_device_get_udev(parent);
         struct udev_device *transportdev;
         struct udev_device *sessiondev = NULL;
@@ -218,8 +212,7 @@ out:
         return parent;
 }
 
-static struct udev_device *handle_scsi_default(struct udev_device *parent, char **path)
-{
+static struct udev_device *handle_scsi_default(struct udev_device *parent, char **path) {
         struct udev_device *hostdev;
         int host, bus, target, lun;
         const char *name;
@@ -339,8 +332,7 @@ static struct udev_device *handle_scsi_hyperv(struct udev_device *parent, char *
         return parent;
 }
 
-static struct udev_device *handle_scsi(struct udev_device *parent, char **path)
-{
+static struct udev_device *handle_scsi(struct udev_device *parent, char **path) {
         const char *devtype;
         const char *name;
         const char *id;
@@ -401,8 +393,7 @@ out:
         return parent;
 }
 
-static struct udev_device *handle_cciss(struct udev_device *parent, char **path)
-{
+static struct udev_device *handle_cciss(struct udev_device *parent, char **path) {
         const char *str;
         unsigned int controller, disk;
 
@@ -415,8 +406,7 @@ static struct udev_device *handle_cciss(struct udev_device *parent, char **path)
         return parent;
 }
 
-static void handle_scsi_tape(struct udev_device *dev, char **path)
-{
+static void handle_scsi_tape(struct udev_device *dev, char **path) {
         const char *name;
 
         /* must be the last device in the syspath */
@@ -430,8 +420,7 @@ static void handle_scsi_tape(struct udev_device *dev, char **path)
                 path_prepend(path, "st%c", name[2]);
 }
 
-static struct udev_device *handle_usb(struct udev_device *parent, char **path)
-{
+static struct udev_device *handle_usb(struct udev_device *parent, char **path) {
         const char *devtype;
         const char *str;
         const char *port;
@@ -453,8 +442,7 @@ static struct udev_device *handle_usb(struct udev_device *parent, char **path)
         return parent;
 }
 
-static struct udev_device *handle_bcma(struct udev_device *parent, char **path)
-{
+static struct udev_device *handle_bcma(struct udev_device *parent, char **path) {
         const char *sysname;
         unsigned int core;
 
@@ -466,8 +454,7 @@ static struct udev_device *handle_bcma(struct udev_device *parent, char **path)
         return parent;
 }
 
-static struct udev_device *handle_ccw(struct udev_device *parent, struct udev_device *dev, char **path)
-{
+static struct udev_device *handle_ccw(struct udev_device *parent, struct udev_device *dev, char **path) {
         struct udev_device *scsi_dev;
 
         scsi_dev = udev_device_get_parent_with_subsystem_devtype(dev, "scsi", "scsi_device");
@@ -491,11 +478,11 @@ out:
         return parent;
 }
 
-static int builtin_path_id(struct udev_device *dev, int argc, char *argv[], bool test)
-{
+static int builtin_path_id(struct udev_device *dev, int argc, char *argv[], bool test) {
         struct udev_device *parent;
         char *path = NULL;
-        bool some_transport = false;
+        bool supported_transport = false;
+        bool supported_parent = false;
 
         /* S390 ccw bus */
         parent = udev_device_get_parent_with_subsystem_devtype(dev, "ccw", NULL);
@@ -516,50 +503,62 @@ static int builtin_path_id(struct udev_device *dev, int argc, char *argv[], bool
                         handle_scsi_tape(parent, &path);
                 } else if (streq(subsys, "scsi")) {
                         parent = handle_scsi(parent, &path);
-                        some_transport = true;
+                        supported_transport = true;
                 } else if (streq(subsys, "cciss")) {
                         parent = handle_cciss(parent, &path);
-                        some_transport = true;
+                        supported_transport = true;
                 } else if (streq(subsys, "usb")) {
                         parent = handle_usb(parent, &path);
-                        some_transport = true;
+                        supported_transport = true;
                 } else if (streq(subsys, "bcma")) {
                         parent = handle_bcma(parent, &path);
-                        some_transport = true;
+                        supported_transport = true;
                 } else if (streq(subsys, "serio")) {
                         path_prepend(&path, "serio-%s", udev_device_get_sysnum(parent));
                         parent = skip_subsystem(parent, "serio");
                 } else if (streq(subsys, "pci")) {
                         path_prepend(&path, "pci-%s", udev_device_get_sysname(parent));
                         parent = skip_subsystem(parent, "pci");
+                        supported_parent = true;
                 } else if (streq(subsys, "platform")) {
                         path_prepend(&path, "platform-%s", udev_device_get_sysname(parent));
                         parent = skip_subsystem(parent, "platform");
-                        some_transport = true;
+                        supported_transport = true;
+                        supported_parent = true;
                 } else if (streq(subsys, "acpi")) {
                         path_prepend(&path, "acpi-%s", udev_device_get_sysname(parent));
                         parent = skip_subsystem(parent, "acpi");
+                        supported_parent = true;
                 } else if (streq(subsys, "xen")) {
                         path_prepend(&path, "xen-%s", udev_device_get_sysname(parent));
                         parent = skip_subsystem(parent, "xen");
-                } else if (streq(subsys, "virtio")) {
-                        path_prepend(&path, "virtio-pci-%s", udev_device_get_sysname(parent));
-                        parent = skip_subsystem(parent, "virtio");
+                        supported_parent = true;
                 } else if (streq(subsys, "scm")) {
                         path_prepend(&path, "scm-%s", udev_device_get_sysname(parent));
                         parent = skip_subsystem(parent, "scm");
-                        some_transport = true;
+                        supported_transport = true;
+                        supported_parent = true;
                 }
 
                 parent = udev_device_get_parent(parent);
         }
 
         /*
-         * Do not return a single-parent-device-only for block
-         * devices, they might have entire buses behind it which
-         * do not get unique IDs only by using the parent device.
+         * Do return devices with have an unknown type of parent device, they
+         * might produce conflicting IDs below multiple independent parent
+         * devices.
          */
-        if (!some_transport && streq(udev_device_get_subsystem(dev), "block")) {
+        if (!supported_parent) {
+                free(path);
+                path = NULL;
+        }
+
+        /*
+         * Do not return a have-only a single-parent block devices, some
+         * have entire hidden buses behind it, and not create predictable
+         * IDs that way.
+         */
+        if (streq(udev_device_get_subsystem(dev), "block") && !supported_transport) {
                 free(path);
                 path = NULL;
         }
index ddb0157..6964fb5 100644 (file)
 #include <dirent.h>
 #include <getopt.h>
 
-#include <systemd/sd-login.h>
+#include "systemd/sd-login.h"
 #include "logind-acl.h"
 #include "udev.h"
 #include "util.h"
 
-static int builtin_uaccess(struct udev_device *dev, int argc, char *argv[], bool test)
-{
+static int builtin_uaccess(struct udev_device *dev, int argc, char *argv[], bool test) {
         int r;
         const char *path = NULL, *seat;
         bool changed_acl = false;
index 883e11e..06d4191 100644 (file)
@@ -31,8 +31,7 @@
 
 #include "udev.h"
 
-static void set_usb_iftype(char *to, int if_class_num, size_t len)
-{
+static void set_usb_iftype(char *to, int if_class_num, size_t len) {
         const char *type = "generic";
 
         switch (if_class_num) {
@@ -82,8 +81,7 @@ static void set_usb_iftype(char *to, int if_class_num, size_t len)
         to[len-1] = '\0';
 }
 
-static int set_usb_mass_storage_ifsubtype(char *to, const char *from, size_t len)
-{
+static int set_usb_mass_storage_ifsubtype(char *to, const char *from, size_t len) {
         int type_num = 0;
         char *eptr;
         const char *type = "generic";
@@ -114,8 +112,7 @@ static int set_usb_mass_storage_ifsubtype(char *to, const char *from, size_t len
         return type_num;
 }
 
-static void set_scsi_type(char *to, const char *from, size_t len)
-{
+static void set_scsi_type(char *to, const char *from, size_t len) {
         int type_num;
         char *eptr;
         const char *type = "generic";
@@ -148,8 +145,7 @@ static void set_scsi_type(char *to, const char *from, size_t len)
 #define USB_DT_DEVICE                        0x01
 #define USB_DT_INTERFACE                0x04
 
-static int dev_if_packed_info(struct udev_device *dev, char *ifs_str, size_t len)
-{
+static int dev_if_packed_info(struct udev_device *dev, char *ifs_str, size_t len) {
         _cleanup_free_ char *filename = NULL;
         _cleanup_close_ int fd = -1;
         ssize_t size;
@@ -232,8 +228,7 @@ static int dev_if_packed_info(struct udev_device *dev, char *ifs_str, size_t len
  * 6.) If the device supplies a serial number, this number
  *     is concatenated with the identification with an underscore '_'.
  */
-static int builtin_usb_id(struct udev_device *dev, int argc, char *argv[], bool test)
-{
+static int builtin_usb_id(struct udev_device *dev, int argc, char *argv[], bool test) {
         char vendor_str[64];
         char vendor_str_enc[256];
         const char *vendor_id;
index fd373d0..05a2726 100644 (file)
@@ -52,8 +52,7 @@ static const struct udev_builtin *builtins[] = {
 #endif
 };
 
-void udev_builtin_init(struct udev *udev)
-{
+void udev_builtin_init(struct udev *udev) {
         unsigned int i;
 
         if (initialized)
@@ -66,8 +65,7 @@ void udev_builtin_init(struct udev *udev)
         initialized = true;
 }
 
-void udev_builtin_exit(struct udev *udev)
-{
+void udev_builtin_exit(struct udev *udev) {
         unsigned int i;
 
         if (!initialized)
@@ -80,8 +78,7 @@ void udev_builtin_exit(struct udev *udev)
         initialized = false;
 }
 
-bool udev_builtin_validate(struct udev *udev)
-{
+bool udev_builtin_validate(struct udev *udev) {
         unsigned int i;
 
         for (i = 0; i < ELEMENTSOF(builtins); i++)
@@ -90,26 +87,22 @@ bool udev_builtin_validate(struct udev *udev)
         return false;
 }
 
-void udev_builtin_list(struct udev *udev)
-{
+void udev_builtin_list(struct udev *udev) {
         unsigned int i;
 
         for (i = 0; i < ELEMENTSOF(builtins); i++)
                 fprintf(stderr, "  %-12s %s\n", builtins[i]->name, builtins[i]->help);
 }
 
-const char *udev_builtin_name(enum udev_builtin_cmd cmd)
-{
+const char *udev_builtin_name(enum udev_builtin_cmd cmd) {
         return builtins[cmd]->name;
 }
 
-bool udev_builtin_run_once(enum udev_builtin_cmd cmd)
-{
+bool udev_builtin_run_once(enum udev_builtin_cmd cmd) {
         return builtins[cmd]->run_once;
 }
 
-enum udev_builtin_cmd udev_builtin_lookup(const char *command)
-{
+enum udev_builtin_cmd udev_builtin_lookup(const char *command) {
         char name[UTIL_PATH_SIZE];
         enum udev_builtin_cmd i;
         char *pos;
@@ -124,8 +117,7 @@ enum udev_builtin_cmd udev_builtin_lookup(const char *command)
         return UDEV_BUILTIN_MAX;
 }
 
-int udev_builtin_run(struct udev_device *dev, enum udev_builtin_cmd cmd, const char *command, bool test)
-{
+int udev_builtin_run(struct udev_device *dev, enum udev_builtin_cmd cmd, const char *command, bool test) {
         char arg[UTIL_PATH_SIZE];
         int argc;
         char *argv[128];
@@ -137,8 +129,7 @@ int udev_builtin_run(struct udev_device *dev, enum udev_builtin_cmd cmd, const c
         return builtins[cmd]->cmd(dev, argc, argv, test);
 }
 
-int udev_builtin_add_property(struct udev_device *dev, bool test, const char *key, const char *val)
-{
+int udev_builtin_add_property(struct udev_device *dev, bool test, const char *key, const char *val) {
         struct udev_list_entry *entry;
 
         entry = udev_device_add_property(dev, key, val);
index 1e91ec2..6fb5bb4 100644 (file)
@@ -70,8 +70,7 @@ struct udev_ctrl_connection {
         int sock;
 };
 
-struct udev_ctrl *udev_ctrl_new_from_fd(struct udev *udev, int fd)
-{
+struct udev_ctrl *udev_ctrl_new_from_fd(struct udev *udev, int fd) {
         struct udev_ctrl *uctrl;
         const int on = 1;
 
@@ -100,13 +99,11 @@ struct udev_ctrl *udev_ctrl_new_from_fd(struct udev *udev, int fd)
         return uctrl;
 }
 
-struct udev_ctrl *udev_ctrl_new(struct udev *udev)
-{
+struct udev_ctrl *udev_ctrl_new(struct udev *udev) {
         return udev_ctrl_new_from_fd(udev, -1);
 }
 
-int udev_ctrl_enable_receiving(struct udev_ctrl *uctrl)
-{
+int udev_ctrl_enable_receiving(struct udev_ctrl *uctrl) {
         int err;
 
         if (!uctrl->bound) {
@@ -135,21 +132,18 @@ int udev_ctrl_enable_receiving(struct udev_ctrl *uctrl)
         return 0;
 }
 
-struct udev *udev_ctrl_get_udev(struct udev_ctrl *uctrl)
-{
+struct udev *udev_ctrl_get_udev(struct udev_ctrl *uctrl) {
         return uctrl->udev;
 }
 
-static struct udev_ctrl *udev_ctrl_ref(struct udev_ctrl *uctrl)
-{
+static struct udev_ctrl *udev_ctrl_ref(struct udev_ctrl *uctrl) {
         if (uctrl == NULL)
                 return NULL;
         uctrl->refcount++;
         return uctrl;
 }
 
-struct udev_ctrl *udev_ctrl_unref(struct udev_ctrl *uctrl)
-{
+struct udev_ctrl *udev_ctrl_unref(struct udev_ctrl *uctrl) {
         if (uctrl == NULL)
                 return NULL;
         uctrl->refcount--;
@@ -161,8 +155,7 @@ struct udev_ctrl *udev_ctrl_unref(struct udev_ctrl *uctrl)
         return NULL;
 }
 
-int udev_ctrl_cleanup(struct udev_ctrl *uctrl)
-{
+int udev_ctrl_cleanup(struct udev_ctrl *uctrl) {
         if (uctrl == NULL)
                 return 0;
         if (uctrl->cleanup_socket)
@@ -170,15 +163,13 @@ int udev_ctrl_cleanup(struct udev_ctrl *uctrl)
         return 0;
 }
 
-int udev_ctrl_get_fd(struct udev_ctrl *uctrl)
-{
+int udev_ctrl_get_fd(struct udev_ctrl *uctrl) {
         if (uctrl == NULL)
                 return -EINVAL;
         return uctrl->sock;
 }
 
-struct udev_ctrl_connection *udev_ctrl_get_connection(struct udev_ctrl *uctrl)
-{
+struct udev_ctrl_connection *udev_ctrl_get_connection(struct udev_ctrl *uctrl) {
         struct udev_ctrl_connection *conn;
         struct ucred ucred = {};
         const int on = 1;
@@ -219,16 +210,14 @@ err:
         return NULL;
 }
 
-struct udev_ctrl_connection *udev_ctrl_connection_ref(struct udev_ctrl_connection *conn)
-{
+struct udev_ctrl_connection *udev_ctrl_connection_ref(struct udev_ctrl_connection *conn) {
         if (conn == NULL)
                 return NULL;
         conn->refcount++;
         return conn;
 }
 
-struct udev_ctrl_connection *udev_ctrl_connection_unref(struct udev_ctrl_connection *conn)
-{
+struct udev_ctrl_connection *udev_ctrl_connection_unref(struct udev_ctrl_connection *conn) {
         if (conn == NULL)
                 return NULL;
         conn->refcount--;
@@ -241,8 +230,7 @@ struct udev_ctrl_connection *udev_ctrl_connection_unref(struct udev_ctrl_connect
         return NULL;
 }
 
-static int ctrl_send(struct udev_ctrl *uctrl, enum udev_ctrl_msg_type type, int intval, const char *buf, int timeout)
-{
+static int ctrl_send(struct udev_ctrl *uctrl, enum udev_ctrl_msg_type type, int intval, const char *buf, int timeout) {
         struct udev_ctrl_msg_wire ctrl_msg_wire;
         int err = 0;
 
@@ -275,7 +263,7 @@ static int ctrl_send(struct udev_ctrl *uctrl, enum udev_ctrl_msg_type type, int
 
                 pfd[0].fd = uctrl->sock;
                 pfd[0].events = POLLIN;
-                r = poll(pfd, 1, timeout * 1000);
+                r = poll(pfd, 1, timeout * MSEC_PER_SEC);
                 if (r  < 0) {
                         if (errno == EINTR)
                                 continue;
@@ -296,48 +284,39 @@ out:
         return err;
 }
 
-int udev_ctrl_send_set_log_level(struct udev_ctrl *uctrl, int priority, int timeout)
-{
+int udev_ctrl_send_set_log_level(struct udev_ctrl *uctrl, int priority, int timeout) {
         return ctrl_send(uctrl, UDEV_CTRL_SET_LOG_LEVEL, priority, NULL, timeout);
 }
 
-int udev_ctrl_send_stop_exec_queue(struct udev_ctrl *uctrl, int timeout)
-{
+int udev_ctrl_send_stop_exec_queue(struct udev_ctrl *uctrl, int timeout) {
         return ctrl_send(uctrl, UDEV_CTRL_STOP_EXEC_QUEUE, 0, NULL, timeout);
 }
 
-int udev_ctrl_send_start_exec_queue(struct udev_ctrl *uctrl, int timeout)
-{
+int udev_ctrl_send_start_exec_queue(struct udev_ctrl *uctrl, int timeout) {
         return ctrl_send(uctrl, UDEV_CTRL_START_EXEC_QUEUE, 0, NULL, timeout);
 }
 
-int udev_ctrl_send_reload(struct udev_ctrl *uctrl, int timeout)
-{
+int udev_ctrl_send_reload(struct udev_ctrl *uctrl, int timeout) {
         return ctrl_send(uctrl, UDEV_CTRL_RELOAD, 0, NULL, timeout);
 }
 
-int udev_ctrl_send_set_env(struct udev_ctrl *uctrl, const char *key, int timeout)
-{
+int udev_ctrl_send_set_env(struct udev_ctrl *uctrl, const char *key, int timeout) {
         return ctrl_send(uctrl, UDEV_CTRL_SET_ENV, 0, key, timeout);
 }
 
-int udev_ctrl_send_set_children_max(struct udev_ctrl *uctrl, int count, int timeout)
-{
+int udev_ctrl_send_set_children_max(struct udev_ctrl *uctrl, int count, int timeout) {
         return ctrl_send(uctrl, UDEV_CTRL_SET_CHILDREN_MAX, count, NULL, timeout);
 }
 
-int udev_ctrl_send_ping(struct udev_ctrl *uctrl, int timeout)
-{
+int udev_ctrl_send_ping(struct udev_ctrl *uctrl, int timeout) {
         return ctrl_send(uctrl, UDEV_CTRL_PING, 0, NULL, timeout);
 }
 
-int udev_ctrl_send_exit(struct udev_ctrl *uctrl, int timeout)
-{
+int udev_ctrl_send_exit(struct udev_ctrl *uctrl, int timeout) {
         return ctrl_send(uctrl, UDEV_CTRL_EXIT, 0, NULL, timeout);
 }
 
-struct udev_ctrl_msg *udev_ctrl_receive_msg(struct udev_ctrl_connection *conn)
-{
+struct udev_ctrl_msg *udev_ctrl_receive_msg(struct udev_ctrl_connection *conn) {
         struct udev_ctrl_msg *uctrl_msg;
         ssize_t size;
         struct cmsghdr *cmsg;
@@ -416,8 +395,7 @@ err:
         return NULL;
 }
 
-struct udev_ctrl_msg *udev_ctrl_msg_unref(struct udev_ctrl_msg *ctrl_msg)
-{
+struct udev_ctrl_msg *udev_ctrl_msg_unref(struct udev_ctrl_msg *ctrl_msg) {
         if (ctrl_msg == NULL)
                 return NULL;
         ctrl_msg->refcount--;
@@ -428,57 +406,49 @@ struct udev_ctrl_msg *udev_ctrl_msg_unref(struct udev_ctrl_msg *ctrl_msg)
         return NULL;
 }
 
-int udev_ctrl_get_set_log_level(struct udev_ctrl_msg *ctrl_msg)
-{
+int udev_ctrl_get_set_log_level(struct udev_ctrl_msg *ctrl_msg) {
         if (ctrl_msg->ctrl_msg_wire.type == UDEV_CTRL_SET_LOG_LEVEL)
                 return ctrl_msg->ctrl_msg_wire.intval;
         return -1;
 }
 
-int udev_ctrl_get_stop_exec_queue(struct udev_ctrl_msg *ctrl_msg)
-{
+int udev_ctrl_get_stop_exec_queue(struct udev_ctrl_msg *ctrl_msg) {
         if (ctrl_msg->ctrl_msg_wire.type == UDEV_CTRL_STOP_EXEC_QUEUE)
                 return 1;
         return -1;
 }
 
-int udev_ctrl_get_start_exec_queue(struct udev_ctrl_msg *ctrl_msg)
-{
+int udev_ctrl_get_start_exec_queue(struct udev_ctrl_msg *ctrl_msg) {
         if (ctrl_msg->ctrl_msg_wire.type == UDEV_CTRL_START_EXEC_QUEUE)
                 return 1;
         return -1;
 }
 
-int udev_ctrl_get_reload(struct udev_ctrl_msg *ctrl_msg)
-{
+int udev_ctrl_get_reload(struct udev_ctrl_msg *ctrl_msg) {
         if (ctrl_msg->ctrl_msg_wire.type == UDEV_CTRL_RELOAD)
                 return 1;
         return -1;
 }
 
-const char *udev_ctrl_get_set_env(struct udev_ctrl_msg *ctrl_msg)
-{
+const char *udev_ctrl_get_set_env(struct udev_ctrl_msg *ctrl_msg) {
         if (ctrl_msg->ctrl_msg_wire.type == UDEV_CTRL_SET_ENV)
                 return ctrl_msg->ctrl_msg_wire.buf;
         return NULL;
 }
 
-int udev_ctrl_get_set_children_max(struct udev_ctrl_msg *ctrl_msg)
-{
+int udev_ctrl_get_set_children_max(struct udev_ctrl_msg *ctrl_msg) {
         if (ctrl_msg->ctrl_msg_wire.type == UDEV_CTRL_SET_CHILDREN_MAX)
                 return ctrl_msg->ctrl_msg_wire.intval;
         return -1;
 }
 
-int udev_ctrl_get_ping(struct udev_ctrl_msg *ctrl_msg)
-{
+int udev_ctrl_get_ping(struct udev_ctrl_msg *ctrl_msg) {
         if (ctrl_msg->ctrl_msg_wire.type == UDEV_CTRL_PING)
                 return 1;
         return -1;
 }
 
-int udev_ctrl_get_exit(struct udev_ctrl_msg *ctrl_msg)
-{
+int udev_ctrl_get_exit(struct udev_ctrl_msg *ctrl_msg) {
         if (ctrl_msg->ctrl_msg_wire.type == UDEV_CTRL_EXIT)
                 return 1;
         return -1;
index 0b3ade0..00cd6d4 100644 (file)
@@ -34,8 +34,7 @@
 #include "udev.h"
 #include "rtnl-util.h"
 
-struct udev_event *udev_event_new(struct udev_device *dev)
-{
+struct udev_event *udev_event_new(struct udev_device *dev) {
         struct udev *udev = udev_device_get_udev(dev);
         struct udev_event *event;
 
@@ -48,12 +47,10 @@ struct udev_event *udev_event_new(struct udev_device *dev)
         udev_list_init(udev, &event->seclabel_list, false);
         event->fd_signal = -1;
         event->birth_usec = now(CLOCK_MONOTONIC);
-        event->timeout_usec = 30 * 1000 * 1000;
         return event;
 }
 
-void udev_event_unref(struct udev_event *event)
-{
+void udev_event_unref(struct udev_event *event) {
         if (event == NULL)
                 return;
         udev_list_cleanup(&event->run_list);
@@ -63,8 +60,7 @@ void udev_event_unref(struct udev_event *event)
         free(event);
 }
 
-size_t udev_event_apply_format(struct udev_event *event, const char *src, char *dest, size_t size)
-{
+size_t udev_event_apply_format(struct udev_event *event, const char *src, char *dest, size_t size) {
         struct udev_device *dev = event->dev;
         enum subst_type {
                 SUBST_UNKNOWN,
@@ -254,6 +250,8 @@ subst:
                                                 cpos++;
                                         while (isspace(cpos[0]))
                                                 cpos++;
+                                        if (cpos[0] == '\0')
+                                                break;
                                 }
                                 if (i > 0) {
                                         log_error("requested part of result string not found");
@@ -376,8 +374,7 @@ out:
 
 static int spawn_exec(struct udev_event *event,
                       const char *cmd, char *const argv[], char **envp, const sigset_t *sigmask,
-                      int fd_stdout, int fd_stderr)
-{
+                      int fd_stdout, int fd_stderr) {
         int err;
         int fd;
 
@@ -420,10 +417,10 @@ static int spawn_exec(struct udev_event *event,
 }
 
 static void spawn_read(struct udev_event *event,
-                      const char *cmd,
-                      int fd_stdout, int fd_stderr,
-                      char *result, size_t ressize)
-{
+                       usec_t timeout_usec,
+                       const char *cmd,
+                       int fd_stdout, int fd_stderr,
+                       char *result, size_t ressize) {
         size_t respos = 0;
         int fd_ep = -1;
         struct epoll_event ep_outpipe, ep_errpipe;
@@ -465,15 +462,15 @@ static void spawn_read(struct udev_event *event,
                 struct epoll_event ev[4];
                 int i;
 
-                if (event->timeout_usec > 0) {
+                if (timeout_usec > 0) {
                         usec_t age_usec;
 
                         age_usec = now(CLOCK_MONOTONIC) - event->birth_usec;
-                        if (age_usec >= event->timeout_usec) {
+                        if (age_usec >= timeout_usec) {
                                 log_error("timeout '%s'", cmd);
                                 goto out;
                         }
-                        timeout = ((event->timeout_usec - age_usec) / 1000) + 1000;
+                        timeout = ((timeout_usec - age_usec) / USEC_PER_MSEC) + MSEC_PER_SEC;
                 } else {
                         timeout = -1;
                 }
@@ -541,8 +538,9 @@ out:
                 close(fd_ep);
 }
 
-static int spawn_wait(struct udev_event *event, const char *cmd, pid_t pid)
-{
+static int spawn_wait(struct udev_event *event,
+                      usec_t timeout_usec,
+                      const char *cmd, pid_t pid) {
         struct pollfd pfd[1];
         int err = 0;
 
@@ -553,14 +551,14 @@ static int spawn_wait(struct udev_event *event, const char *cmd, pid_t pid)
                 int timeout;
                 int fdcount;
 
-                if (event->timeout_usec > 0) {
+                if (timeout_usec > 0) {
                         usec_t age_usec;
 
                         age_usec = now(CLOCK_MONOTONIC) - event->birth_usec;
-                        if (age_usec >= event->timeout_usec)
+                        if (age_usec >= timeout_usec)
                                 timeout = 1000;
                         else
-                                timeout = ((event->timeout_usec - age_usec) / 1000) + 1000;
+                                timeout = ((timeout_usec - age_usec) / USEC_PER_MSEC) + MSEC_PER_SEC;
                 } else {
                         timeout = -1;
                 }
@@ -620,8 +618,7 @@ out:
         return err;
 }
 
-int udev_build_argv(struct udev *udev, char *cmd, int *argc, char *argv[])
-{
+int udev_build_argv(struct udev *udev, char *cmd, int *argc, char *argv[]) {
         int i = 0;
         char *pos;
 
@@ -655,9 +652,9 @@ out:
 }
 
 int udev_event_spawn(struct udev_event *event,
+                     usec_t timeout_usec,
                      const char *cmd, char **envp, const sigset_t *sigmask,
-                     char *result, size_t ressize)
-{
+                     char *result, size_t ressize) {
         struct udev *udev = event->udev;
         int outpipe[2] = {-1, -1};
         int errpipe[2] = {-1, -1};
@@ -726,11 +723,13 @@ int udev_event_spawn(struct udev_event *event,
                         errpipe[WRITE_END] = -1;
                 }
 
-                spawn_read(event, cmd,
-                         outpipe[READ_END], errpipe[READ_END],
-                         result, ressize);
+                spawn_read(event,
+                           timeout_usec,
+                           cmd,
+                           outpipe[READ_END], errpipe[READ_END],
+                           result, ressize);
 
-                err = spawn_wait(event, cmd, pid);
+                err = spawn_wait(event, timeout_usec, cmd, pid);
         }
 
 out:
@@ -745,8 +744,7 @@ out:
         return err;
 }
 
-static int rename_netif(struct udev_event *event)
-{
+static int rename_netif(struct udev_event *event) {
         struct udev_device *dev = event->dev;
         _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
         char name[IFNAMSIZ];
@@ -769,18 +767,18 @@ static int rename_netif(struct udev_event *event)
                 log_error("error changing net interface name %s to %s: %s",
                           oldname, name, strerror(-r));
         else
-                print_kmsg("renamed network interface %s to %s", oldname, name);
+                print_kmsg("renamed network interface %s to %s\n", oldname, name);
 
         return r;
 }
 
-int udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules, const sigset_t *sigmask)
-{
+void udev_event_execute_rules(struct udev_event *event,
+                              usec_t timeout_usec,
+                              struct udev_rules *rules, const sigset_t *sigmask) {
         struct udev_device *dev = event->dev;
-        int err = 0;
 
         if (udev_device_get_subsystem(dev) == NULL)
-                return -1;
+                return;
 
         if (streq(udev_device_get_action(dev), "remove")) {
                 udev_device_read_db(dev, NULL);
@@ -790,7 +788,7 @@ int udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules,
                 if (major(udev_device_get_devnum(dev)) != 0)
                         udev_watch_end(event->udev, dev);
 
-                udev_rules_apply_to_event(rules, event, sigmask);
+                udev_rules_apply_to_event(rules, event, timeout_usec, sigmask);
 
                 if (major(udev_device_get_devnum(dev)) != 0)
                         udev_node_remove(dev);
@@ -807,16 +805,17 @@ int udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules,
                                 udev_watch_end(event->udev, event->dev_db);
                 }
 
-                udev_rules_apply_to_event(rules, event, sigmask);
+                udev_rules_apply_to_event(rules, event, timeout_usec, sigmask);
 
                 /* rename a new network interface, if needed */
                 if (udev_device_get_ifindex(dev) > 0 && streq(udev_device_get_action(dev), "add") &&
                     event->name != NULL && !streq(event->name, udev_device_get_sysname(dev))) {
                         char syspath[UTIL_PATH_SIZE];
                         char *pos;
+                        int r;
 
-                        err = rename_netif(event);
-                        if (err == 0) {
+                        r = rename_netif(event);
+                        if (r >= 0) {
                                 log_debug("renamed netif to '%s'", event->name);
 
                                 /* remember old name */
@@ -879,11 +878,9 @@ int udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules,
                 udev_device_unref(event->dev_db);
                 event->dev_db = NULL;
         }
-        return err;
 }
 
-void udev_event_execute_run(struct udev_event *event, const sigset_t *sigmask)
-{
+void udev_event_execute_run(struct udev_event *event, usec_t timeout_usec, const sigset_t *sigmask) {
         struct udev_list_entry *list_entry;
 
         udev_list_entry_foreach(list_entry, udev_list_get_entry(&event->run_list)) {
@@ -906,7 +903,7 @@ void udev_event_execute_run(struct udev_event *event, const sigset_t *sigmask)
 
                         udev_event_apply_format(event, cmd, program, sizeof(program));
                         envp = udev_device_get_properties_envp(event->dev);
-                        udev_event_spawn(event, program, envp, sigmask, NULL, 0);
+                        udev_event_spawn(event, timeout_usec, program, envp, sigmask, NULL, 0);
                 }
         }
 }
index 0b0e9e0..5e372c3 100644 (file)
@@ -32,8 +32,7 @@
 #include "udev.h"
 #include "smack-util.h"
 
-static int node_symlink(struct udev_device *dev, const char *node, const char *slink)
-{
+static int node_symlink(struct udev_device *dev, const char *node, const char *slink) {
         struct stat stats;
         char target[UTIL_PATH_SIZE];
         char *s;
@@ -126,8 +125,7 @@ exit:
 }
 
 /* find device node of device with highest priority */
-static const char *link_find_prioritized(struct udev_device *dev, bool add, const char *stackdir, char *buf, size_t bufsize)
-{
+static const char *link_find_prioritized(struct udev_device *dev, bool add, const char *stackdir, char *buf, size_t bufsize) {
         struct udev *udev = udev_device_get_udev(dev);
         DIR *dir;
         int priority = 0;
@@ -180,8 +178,7 @@ static const char *link_find_prioritized(struct udev_device *dev, bool add, cons
 }
 
 /* manage "stack of names" with possibly specified device priorities */
-static void link_update(struct udev_device *dev, const char *slink, bool add)
-{
+static void link_update(struct udev_device *dev, const char *slink, bool add) {
         struct udev *udev = udev_device_get_udev(dev);
         char name_enc[UTIL_PATH_SIZE];
         char filename[UTIL_PATH_SIZE * 2];
@@ -224,8 +221,7 @@ static void link_update(struct udev_device *dev, const char *slink, bool add)
         }
 }
 
-void udev_node_update_old_links(struct udev_device *dev, struct udev_device *dev_old)
-{
+void udev_node_update_old_links(struct udev_device *dev, struct udev_device *dev_old) {
         struct udev_list_entry *list_entry;
 
         /* update possible left-over symlinks */
@@ -318,7 +314,7 @@ static int node_permissions_apply(struct udev_device *dev, bool apply,
                 }
 
                 /* set the defaults */
-                if (!selinux && use_selinux())
+                if (!selinux)
                         label_fix_selinux(devnode, true, false);
                 if (!smack)
                         smack_label_path(devnode, NULL);
@@ -353,8 +349,7 @@ void udev_node_add(struct udev_device *dev, bool apply,
                         link_update(dev, udev_list_entry_get_name(list_entry), true);
 }
 
-void udev_node_remove(struct udev_device *dev)
-{
+void udev_node_remove(struct udev_device *dev) {
         struct udev_list_entry *list_entry;
         char filename[UTIL_PATH_SIZE];
 
index 47bde61..cc56215 100644 (file)
@@ -137,7 +137,6 @@ enum token_type {
         TK_M_PARENTS_MAX,
 
         TK_M_TEST,                      /* val, mode_t */
-        TK_M_EVENT_TIMEOUT,             /* int */
         TK_M_PROGRAM,                   /* val */
         TK_M_IMPORT_FILE,               /* val */
         TK_M_IMPORT_PROG,               /* val */
@@ -201,7 +200,6 @@ struct token {
                                 uid_t uid;
                                 gid_t gid;
                                 int devlink_prio;
-                                int event_timeout;
                                 int watch;
                                 enum udev_builtin_cmd builtin_cmd;
                         };
@@ -218,8 +216,7 @@ struct rule_tmp {
 };
 
 #ifdef DEBUG
-static const char *operation_str(enum operation_type type)
-{
+static const char *operation_str(enum operation_type type) {
         static const char *operation_strs[] = {
                 [OP_UNSET] =            "UNSET",
                 [OP_MATCH] =            "match",
@@ -234,8 +231,7 @@ static const char *operation_str(enum operation_type type)
         return operation_strs[type];
 }
 
-static const char *string_glob_str(enum string_glob_type type)
-{
+static const char *string_glob_str(enum string_glob_type type) {
         static const char *string_glob_strs[] = {
                 [GL_UNSET] =            "UNSET",
                 [GL_PLAIN] =            "plain",
@@ -248,8 +244,7 @@ static const char *string_glob_str(enum string_glob_type type)
         return string_glob_strs[type];
 }
 
-static const char *token_str(enum token_type type)
-{
+static const char *token_str(enum token_type type) {
         static const char *token_strs[] = {
                 [TK_UNSET] =                    "UNSET",
                 [TK_RULE] =                     "RULE",
@@ -275,7 +270,6 @@ static const char *token_str(enum token_type type)
                 [TK_M_PARENTS_MAX] =            "M PARENTS_MAX",
 
                 [TK_M_TEST] =                   "M TEST",
-                [TK_M_EVENT_TIMEOUT] =          "M EVENT_TIMEOUT",
                 [TK_M_PROGRAM] =                "M PROGRAM",
                 [TK_M_IMPORT_FILE] =            "M IMPORT_FILE",
                 [TK_M_IMPORT_PROG] =            "M IMPORT_PROG",
@@ -314,8 +308,7 @@ static const char *token_str(enum token_type type)
         return token_strs[type];
 }
 
-static void dump_token(struct udev_rules *rules, struct token *token)
-{
+static void dump_token(struct udev_rules *rules, struct token *token) {
         enum token_type type = token->type;
         enum operation_type op = token->key.op;
         enum string_glob_type glob = token->key.glob;
@@ -409,9 +402,6 @@ static void dump_token(struct udev_rules *rules, struct token *token)
         case TK_A_SECLABEL:
                 log_debug("%s %s '%s' '%s'", token_str(type), operation_str(op), attr, value);
                 break;
-        case TK_M_EVENT_TIMEOUT:
-                log_debug("%s %u", token_str(type), token->key.event_timeout);
-                break;
         case TK_A_GOTO:
                 log_debug("%s '%s' %u", token_str(type), value, token->key.rule_goto);
                 break;
@@ -427,8 +417,7 @@ static void dump_token(struct udev_rules *rules, struct token *token)
         }
 }
 
-static void dump_rules(struct udev_rules *rules)
-{
+static void dump_rules(struct udev_rules *rules) {
         unsigned int i;
 
         log_debug("dumping %u (%zu bytes) tokens, %u (%zu bytes) strings",
@@ -444,8 +433,7 @@ static inline void dump_token(struct udev_rules *rules, struct token *token) {}
 static inline void dump_rules(struct udev_rules *rules) {}
 #endif /* DEBUG */
 
-static int add_token(struct udev_rules *rules, struct token *token)
-{
+static int add_token(struct udev_rules *rules, struct token *token) {
         /* grow buffer if needed */
         if (rules->token_cur+1 >= rules->token_max) {
                 struct token *tokens;
@@ -467,8 +455,7 @@ static int add_token(struct udev_rules *rules, struct token *token)
         return 0;
 }
 
-static uid_t add_uid(struct udev_rules *rules, const char *owner)
-{
+static uid_t add_uid(struct udev_rules *rules, const char *owner) {
         unsigned int i;
         uid_t uid;
         unsigned int off;
@@ -508,8 +495,7 @@ static uid_t add_uid(struct udev_rules *rules, const char *owner)
         return uid;
 }
 
-static gid_t add_gid(struct udev_rules *rules, const char *group)
-{
+static gid_t add_gid(struct udev_rules *rules, const char *group) {
         unsigned int i;
         gid_t gid;
         unsigned int off;
@@ -549,8 +535,7 @@ static gid_t add_gid(struct udev_rules *rules, const char *group)
         return gid;
 }
 
-static int import_property_from_string(struct udev_device *dev, char *line)
-{
+static int import_property_from_string(struct udev_device *dev, char *line) {
         char *key;
         char *val;
         size_t len;
@@ -613,8 +598,7 @@ static int import_property_from_string(struct udev_device *dev, char *line)
         return 0;
 }
 
-static int import_file_into_properties(struct udev_device *dev, const char *filename)
-{
+static int import_file_into_properties(struct udev_device *dev, const char *filename) {
         FILE *f;
         char line[UTIL_LINE_SIZE];
 
@@ -627,8 +611,9 @@ static int import_file_into_properties(struct udev_device *dev, const char *file
         return 0;
 }
 
-static int import_program_into_properties(struct udev_event *event, const char *program, const sigset_t *sigmask)
-{
+static int import_program_into_properties(struct udev_event *event,
+                                          usec_t timeout_usec,
+                                          const char *program, const sigset_t *sigmask) {
         struct udev_device *dev = event->dev;
         char **envp;
         char result[UTIL_LINE_SIZE];
@@ -636,7 +621,7 @@ static int import_program_into_properties(struct udev_event *event, const char *
         int err;
 
         envp = udev_device_get_properties_envp(dev);
-        err = udev_event_spawn(event, program, envp, sigmask, result, sizeof(result));
+        err = udev_event_spawn(event, timeout_usec, program, envp, sigmask, result, sizeof(result));
         if (err < 0)
                 return err;
 
@@ -655,8 +640,7 @@ static int import_program_into_properties(struct udev_event *event, const char *
         return 0;
 }
 
-static int import_parent_into_properties(struct udev_device *dev, const char *filter)
-{
+static int import_parent_into_properties(struct udev_device *dev, const char *filter) {
         struct udev_device *dev_parent;
         struct udev_list_entry *list_entry;
 
@@ -681,8 +665,7 @@ static int import_parent_into_properties(struct udev_device *dev, const char *fi
 }
 
 #define WAIT_LOOP_PER_SECOND                50
-static int wait_for_file(struct udev_device *dev, const char *file, int timeout)
-{
+static int wait_for_file(struct udev_device *dev, const char *file, int timeout) {
         char filepath[UTIL_PATH_SIZE];
         char devicepath[UTIL_PATH_SIZE];
         struct stat stats;
@@ -716,8 +699,7 @@ static int wait_for_file(struct udev_device *dev, const char *file, int timeout)
         return -1;
 }
 
-static int attr_subst_subdir(char *attr, size_t len)
-{
+static int attr_subst_subdir(char *attr, size_t len) {
         bool found = false;
 
         if (strstr(attr, "/*/")) {
@@ -754,8 +736,7 @@ static int attr_subst_subdir(char *attr, size_t len)
         return found;
 }
 
-static int get_key(struct udev *udev, char **line, char **key, enum operation_type *op, char **value)
-{
+static int get_key(struct udev *udev, char **line, char **key, enum operation_type *op, char **value) {
         char *linepos;
         char *temp;
 
@@ -842,8 +823,7 @@ static int get_key(struct udev *udev, char **line, char **key, enum operation_ty
 }
 
 /* extract possible KEY{attr} */
-static const char *get_key_attribute(struct udev *udev, char *str)
-{
+static const char *get_key_attribute(struct udev *udev, char *str) {
         char *pos;
         char *attr;
 
@@ -863,8 +843,7 @@ static const char *get_key_attribute(struct udev *udev, char *str)
 
 static int rule_add_key(struct rule_tmp *rule_tmp, enum token_type type,
                         enum operation_type op,
-                        const char *value, const void *data)
-{
+                        const char *value, const void *data) {
         struct token *token = &rule_tmp->token[rule_tmp->token_cur];
         const char *attr = NULL;
 
@@ -942,9 +921,6 @@ static int rule_add_key(struct rule_tmp *rule_tmp, enum token_type type,
         case TK_A_MODE_ID:
                 token->key.mode = *(mode_t *)data;
                 break;
-        case TK_M_EVENT_TIMEOUT:
-                token->key.event_timeout = *(int *)data;
-                break;
         case TK_RULE:
         case TK_M_PARENTS_MIN:
         case TK_M_PARENTS_MAX:
@@ -1008,8 +984,7 @@ static int rule_add_key(struct rule_tmp *rule_tmp, enum token_type type,
         return 0;
 }
 
-static int sort_token(struct udev_rules *rules, struct rule_tmp *rule_tmp)
-{
+static int sort_token(struct udev_rules *rules, struct rule_tmp *rule_tmp) {
         unsigned int i;
         unsigned int start = 0;
         unsigned int end = rule_tmp->token_cur;
@@ -1044,8 +1019,7 @@ static int sort_token(struct udev_rules *rules, struct rule_tmp *rule_tmp)
 }
 
 static int add_rule(struct udev_rules *rules, char *line,
-                    const char *filename, unsigned int filename_off, unsigned int lineno)
-{
+                    const char *filename, unsigned int filename_off, unsigned int lineno) {
         char *linepos;
         const char *attr;
         struct rule_tmp rule_tmp;
@@ -1142,7 +1116,7 @@ static int add_rule(struct udev_rules *rules, char *line,
                 }
 
                 if (startswith(key, "ATTR{")) {
-                        attr = get_key_attribute(rules->udev, key + sizeof("ATTR")-1);
+                        attr = get_key_attribute(rules->udev, key + strlen("ATTR"));
                         if (attr == NULL) {
                                 log_error("error parsing ATTR attribute");
                                 goto invalid;
@@ -1156,7 +1130,7 @@ static int add_rule(struct udev_rules *rules, char *line,
                 }
 
                 if (startswith(key, "SECLABEL{")) {
-                        attr = get_key_attribute(rules->udev, key + sizeof("SECLABEL")-1);
+                        attr = get_key_attribute(rules->udev, key + strlen("SECLABEL"));
                         if (!attr) {
                                 log_error("error parsing SECLABEL attribute");
                                 goto invalid;
@@ -1198,7 +1172,7 @@ static int add_rule(struct udev_rules *rules, char *line,
                                 log_error("invalid ATTRS operation");
                                 goto invalid;
                         }
-                        attr = get_key_attribute(rules->udev, key + sizeof("ATTRS")-1);
+                        attr = get_key_attribute(rules->udev, key + strlen("ATTRS"));
                         if (attr == NULL) {
                                 log_error("error parsing ATTRS attribute");
                                 goto invalid;
@@ -1223,7 +1197,7 @@ static int add_rule(struct udev_rules *rules, char *line,
                 }
 
                 if (startswith(key, "ENV{")) {
-                        attr = get_key_attribute(rules->udev, key + sizeof("ENV")-1);
+                        attr = get_key_attribute(rules->udev, key + strlen("ENV"));
                         if (attr == NULL) {
                                 log_error("error parsing ENV attribute");
                                 goto invalid;
@@ -1282,7 +1256,7 @@ static int add_rule(struct udev_rules *rules, char *line,
                 }
 
                 if (startswith(key, "IMPORT")) {
-                        attr = get_key_attribute(rules->udev, key + sizeof("IMPORT")-1);
+                        attr = get_key_attribute(rules->udev, key + strlen("IMPORT"));
                         if (attr == NULL) {
                                 log_error("IMPORT{} type missing, ignoring IMPORT %s:%u", filename, lineno);
                                 continue;
@@ -1328,7 +1302,7 @@ static int add_rule(struct udev_rules *rules, char *line,
                                 log_error("invalid TEST operation");
                                 goto invalid;
                         }
-                        attr = get_key_attribute(rules->udev, key + sizeof("TEST")-1);
+                        attr = get_key_attribute(rules->udev, key + strlen("TEST"));
                         if (attr != NULL) {
                                 mode = strtol(attr, NULL, 8);
                                 rule_add_key(&rule_tmp, TK_M_TEST, op, value, &mode);
@@ -1339,7 +1313,7 @@ static int add_rule(struct udev_rules *rules, char *line,
                 }
 
                 if (startswith(key, "RUN")) {
-                        attr = get_key_attribute(rules->udev, key + sizeof("RUN")-1);
+                        attr = get_key_attribute(rules->udev, key + strlen("RUN"));
                         if (attr == NULL)
                                 attr = "program";
 
@@ -1462,13 +1436,6 @@ static int add_rule(struct udev_rules *rules, char *line,
                                 rule_add_key(&rule_tmp, TK_A_DEVLINK_PRIO, op, NULL, &prio);
                         }
 
-                        pos = strstr(value, "event_timeout=");
-                        if (pos != NULL) {
-                                int tout = atoi(&pos[strlen("event_timeout=")]);
-
-                                rule_add_key(&rule_tmp, TK_M_EVENT_TIMEOUT, op, NULL, &tout);
-                        }
-
                         pos = strstr(value, "string_escape=");
                         if (pos != NULL) {
                                 pos = &pos[strlen("string_escape=")];
@@ -1524,8 +1491,7 @@ invalid:
         return -1;
 }
 
-static int parse_file(struct udev_rules *rules, const char *filename)
-{
+static int parse_file(struct udev_rules *rules, const char *filename) {
         FILE *f;
         unsigned int first_token;
         unsigned int filename_off;
@@ -1533,15 +1499,19 @@ static int parse_file(struct udev_rules *rules, const char *filename)
         int line_nr = 0;
         unsigned int i;
 
-        if (null_or_empty_path(filename)) {
-                log_debug("skip empty file: %s", filename);
-                return 0;
+        f = fopen(filename, "re");
+        if (!f) {
+                if (errno == ENOENT)
+                        return 0;
+                else
+                        return -errno;
         }
-        log_debug("read rules file: %s", filename);
 
-        f = fopen(filename, "re");
-        if (f == NULL)
-                return -1;
+        if (null_or_empty_fd(fileno(f))) {
+                log_debug("Skipping empty file: %s", filename);
+                return 0;
+        } else
+                log_debug("Reading rules file: %s", filename);
 
         first_token = rules->token_cur;
         filename_off = rules_add_string(rules, filename);
@@ -1605,8 +1575,7 @@ static int parse_file(struct udev_rules *rules, const char *filename)
         return 0;
 }
 
-struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names)
-{
+struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names) {
         struct udev_rules *rules;
         struct udev_list file_list;
         struct token end_token;
@@ -1676,8 +1645,7 @@ struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names)
         return rules;
 }
 
-struct udev_rules *udev_rules_unref(struct udev_rules *rules)
-{
+struct udev_rules *udev_rules_unref(struct udev_rules *rules) {
         if (rules == NULL)
                 return NULL;
         free(rules->tokens);
@@ -1688,16 +1656,14 @@ struct udev_rules *udev_rules_unref(struct udev_rules *rules)
         return NULL;
 }
 
-bool udev_rules_check_timestamp(struct udev_rules *rules)
-{
+bool udev_rules_check_timestamp(struct udev_rules *rules) {
         if (!rules)
                 return false;
 
         return paths_check_timestamp(rules_dirs, &rules->dirs_ts_usec, true);
 }
 
-static int match_key(struct udev_rules *rules, struct token *token, const char *val)
-{
+static int match_key(struct udev_rules *rules, struct token *token, const char *val) {
         char *key_value = rules_str(rules, token->key.value_off);
         char *pos;
         bool match = false;
@@ -1770,8 +1736,7 @@ static int match_key(struct udev_rules *rules, struct token *token, const char *
         return -1;
 }
 
-static int match_attr(struct udev_rules *rules, struct udev_device *dev, struct udev_event *event, struct token *cur)
-{
+static int match_attr(struct udev_rules *rules, struct udev_device *dev, struct udev_event *event, struct token *cur) {
         const char *name;
         char nbuf[UTIL_NAME_SIZE];
         const char *value;
@@ -1825,8 +1790,10 @@ enum escape_type {
         ESCAPE_REPLACE,
 };
 
-int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event, const sigset_t *sigmask)
-{
+int udev_rules_apply_to_event(struct udev_rules *rules,
+                              struct udev_event *event,
+                              usec_t timeout_usec,
+                              const sigset_t *sigmask) {
         struct token *cur;
         struct token *rule;
         enum escape_type esc = ESCAPE_UNSET;
@@ -2020,14 +1987,10 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event
                                 goto nomatch;
                         break;
                 }
-                case TK_M_EVENT_TIMEOUT:
-                        log_debug("OPTIONS event_timeout=%u", cur->key.event_timeout);
-                        event->timeout_usec = cur->key.event_timeout * 1000 * 1000;
-                        break;
                 case TK_M_PROGRAM: {
                         char program[UTIL_PATH_SIZE];
                         char **envp;
-                        char result[UTIL_PATH_SIZE];
+                        char result[UTIL_LINE_SIZE];
 
                         free(event->program_result);
                         event->program_result = NULL;
@@ -2038,7 +2001,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event
                                   rules_str(rules, rule->rule.filename_off),
                                   rule->rule.filename_line);
 
-                        if (udev_event_spawn(event, program, envp, sigmask, result, sizeof(result)) < 0) {
+                        if (udev_event_spawn(event, timeout_usec, program, envp, sigmask, result, sizeof(result)) < 0) {
                                 if (cur->key.op != OP_NOMATCH)
                                         goto nomatch;
                         } else {
@@ -2074,7 +2037,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event
                                   rules_str(rules, rule->rule.filename_off),
                                   rule->rule.filename_line);
 
-                        if (import_program_into_properties(event, import, sigmask) != 0)
+                        if (import_program_into_properties(event, timeout_usec, import, sigmask) != 0)
                                 if (cur->key.op != OP_NOMATCH)
                                         goto nomatch;
                         break;
@@ -2499,8 +2462,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event
         }
 }
 
-int udev_rules_apply_static_dev_perms(struct udev_rules *rules)
-{
+int udev_rules_apply_static_dev_perms(struct udev_rules *rules) {
         struct token *cur;
         struct token *rule;
         uid_t uid = 0;
@@ -2555,10 +2517,15 @@ int udev_rules_apply_static_dev_perms(struct udev_rules *rules)
                         struct stat stats;
 
                         /* we assure, that the permissions tokens are sorted before the static token */
+
                         if (mode == 0 && uid == 0 && gid == 0 && tags == NULL)
                                 goto next;
 
                         strscpyl(device_node, sizeof(device_node), "/dev/", rules_str(rules, cur->key.value_off), NULL);
+                        if (stat(device_node, &stats) != 0)
+                                break;
+                        if (!S_ISBLK(stats.st_mode) && !S_ISCHR(stats.st_mode))
+                                break;
 
                         /* export the tags to a directory as symlinks, allowing otherwise dead nodes to be tagged */
                         if (tags) {
@@ -2588,11 +2555,6 @@ int udev_rules_apply_static_dev_perms(struct udev_rules *rules)
                         if (mode == 0 && uid == 0 && gid == 0)
                                 break;
 
-                        if (stat(device_node, &stats) != 0)
-                                break;
-                        if (!S_ISBLK(stats.st_mode) && !S_ISCHR(stats.st_mode))
-                                break;
-
                         if (mode == 0) {
                                 if (gid > 0)
                                         mode = 0660;
index cbe0c37..061bd05 100644 (file)
@@ -36,8 +36,7 @@ static int inotify_fd = -1;
  * set to cloexec since we need our children to be able to add
  * watches for us
  */
-int udev_watch_init(struct udev *udev)
-{
+int udev_watch_init(struct udev *udev) {
         inotify_fd = inotify_init1(IN_CLOEXEC);
         if (inotify_fd < 0)
                 log_error("inotify_init failed: %m");
@@ -47,8 +46,7 @@ int udev_watch_init(struct udev *udev)
 /* move any old watches directory out of the way, and then restore
  * the watches
  */
-void udev_watch_restore(struct udev *udev)
-{
+void udev_watch_restore(struct udev *udev) {
         if (inotify_fd < 0)
                 return;
 
@@ -94,8 +92,7 @@ unlink:
         }
 }
 
-void udev_watch_begin(struct udev *udev, struct udev_device *dev)
-{
+void udev_watch_begin(struct udev *udev, struct udev_device *dev) {
         char filename[UTIL_PATH_SIZE];
         int wd;
         int r;
@@ -121,8 +118,7 @@ void udev_watch_begin(struct udev *udev, struct udev_device *dev)
         udev_device_set_watch_handle(dev, wd);
 }
 
-void udev_watch_end(struct udev *udev, struct udev_device *dev)
-{
+void udev_watch_end(struct udev *udev, struct udev_device *dev) {
         int wd;
         char filename[UTIL_PATH_SIZE];
 
@@ -142,8 +138,7 @@ void udev_watch_end(struct udev *udev, struct udev_device *dev)
         udev_device_set_watch_handle(dev, -1);
 }
 
-struct udev_device *udev_watch_lookup(struct udev *udev, int wd)
-{
+struct udev_device *udev_watch_lookup(struct udev *udev, int wd) {
         char filename[UTIL_PATH_SIZE];
         char device[UTIL_NAME_SIZE];
         ssize_t len;
index f39253e..47d1433 100644 (file)
@@ -1,3 +1,3 @@
-# see udev(7) for details
+# see udev.conf(5) for details
 
 #udev_log="info"
index 936adfb..4aca70b 100644 (file)
@@ -43,7 +43,6 @@ struct udev_event {
         struct udev_list run_list;
         int exec_delay;
         usec_t birth_usec;
-        usec_t timeout_usec;
         int fd_signal;
         unsigned int builtin_run;
         unsigned int builtin_ret;
@@ -72,7 +71,7 @@ struct udev_rules;
 struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names);
 struct udev_rules *udev_rules_unref(struct udev_rules *rules);
 bool udev_rules_check_timestamp(struct udev_rules *rules);
-int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event, const sigset_t *sigmask);
+int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event, usec_t timeout_usec, const sigset_t *sigmask);
 int udev_rules_apply_static_dev_perms(struct udev_rules *rules);
 
 /* udev-event.c */
@@ -82,10 +81,11 @@ size_t udev_event_apply_format(struct udev_event *event, const char *src, char *
 int udev_event_apply_subsys_kernel(struct udev_event *event, const char *string,
                                    char *result, size_t maxsize, int read_value);
 int udev_event_spawn(struct udev_event *event,
+                     usec_t timeout_usec,
                      const char *cmd, char **envp, const sigset_t *sigmask,
                      char *result, size_t ressize);
-int udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules, const sigset_t *sigset);
-void udev_event_execute_run(struct udev_event *event, const sigset_t *sigset);
+void udev_event_execute_rules(struct udev_event *event, usec_t timeout_usec, struct udev_rules *rules, const sigset_t *sigset);
+void udev_event_execute_run(struct udev_event *event, usec_t timeout_usec, const sigset_t *sigset);
 int udev_build_argv(struct udev *udev, char *cmd, int *argc, char *argv[]);
 
 /* udev-watch.c */
index 3a6c8ef..6e3bc2a 100644 (file)
@@ -28,8 +28,7 @@
 #include "udev.h"
 #include "udev-util.h"
 
-static void print_help(void)
-{
+static void print_help(void) {
         printf("Usage: udevadm control COMMAND\n"
                 "  -e,--exit                 instruct the daemon to cleanup and exit\n"
                 "  -l,--log-priority=LEVEL   set the udev log level for the daemon\n"
@@ -42,8 +41,7 @@ static void print_help(void)
                 "  -h,--help                 print this help text\n\n");
 }
 
-static int adm_control(struct udev *udev, int argc, char *argv[])
-{
+static int adm_control(struct udev *udev, int argc, char *argv[]) {
         _cleanup_udev_ctrl_unref_ struct udev_ctrl *uctrl = NULL;
         int timeout = 60;
         int rc = 1, c;
index 64bb537..22d0826 100644 (file)
@@ -32,8 +32,7 @@
 #include "udev.h"
 #include "udev-util.h"
 
-static bool skip_attribute(const char *name)
-{
+static bool skip_attribute(const char *name) {
         static const char* const skip[] = {
                 "uevent",
                 "dev",
@@ -51,8 +50,7 @@ static bool skip_attribute(const char *name)
         return false;
 }
 
-static void print_all_attributes(struct udev_device *device, const char *key)
-{
+static void print_all_attributes(struct udev_device *device, const char *key) {
         struct udev_list_entry *sysattr;
 
         udev_list_entry_foreach(sysattr, udev_device_get_sysattr_list_entry(device)) {
@@ -84,8 +82,7 @@ static void print_all_attributes(struct udev_device *device, const char *key)
         printf("\n");
 }
 
-static int print_device_chain(struct udev_device *device)
-{
+static int print_device_chain(struct udev_device *device) {
         struct udev_device *device_parent;
         const char *str;
 
@@ -130,8 +127,7 @@ static int print_device_chain(struct udev_device *device)
         return 0;
 }
 
-static void print_record(struct udev_device *device)
-{
+static void print_record(struct udev_device *device) {
         const char *str;
         int i;
         struct udev_list_entry *list_entry;
@@ -156,8 +152,7 @@ static void print_record(struct udev_device *device)
         printf("\n");
 }
 
-static int stat_device(const char *name, bool export, const char *prefix)
-{
+static int stat_device(const char *name, bool export, const char *prefix) {
         struct stat statbuf;
 
         if (stat(name, &statbuf) != 0)
@@ -175,8 +170,7 @@ static int stat_device(const char *name, bool export, const char *prefix)
         return 0;
 }
 
-static int export_devices(struct udev *udev)
-{
+static int export_devices(struct udev *udev) {
         struct udev_enumerate *udev_enumerate;
         struct udev_list_entry *list_entry;
 
@@ -197,8 +191,7 @@ static int export_devices(struct udev *udev)
         return 0;
 }
 
-static void cleanup_dir(DIR *dir, mode_t mask, int depth)
-{
+static void cleanup_dir(DIR *dir, mode_t mask, int depth) {
         struct dirent *dent;
 
         if (depth <= 0)
@@ -228,8 +221,7 @@ static void cleanup_dir(DIR *dir, mode_t mask, int depth)
         }
 }
 
-static void cleanup_db(struct udev *udev)
-{
+static void cleanup_db(struct udev *udev) {
         DIR *dir;
 
         unlink("/run/udev/queue.bin");
@@ -265,8 +257,7 @@ static void cleanup_db(struct udev *udev)
         }
 }
 
-static struct udev_device *find_device(struct udev *udev, const char *id, const char *prefix)
-{
+static struct udev_device *find_device(struct udev *udev, const char *id, const char *prefix) {
         char name[UTIL_PATH_SIZE];
 
         if (prefix && !startswith(id, prefix)) {
@@ -295,8 +286,7 @@ static struct udev_device *find_device(struct udev *udev, const char *id, const
                 return NULL;
 }
 
-static int uinfo(struct udev *udev, int argc, char *argv[])
-{
+static int uinfo(struct udev *udev, int argc, char *argv[]) {
         _cleanup_udev_device_unref_ struct udev_device *device = NULL;
         bool root = 0;
         bool export = 0;
@@ -498,8 +488,7 @@ static int uinfo(struct udev *udev, int argc, char *argv[])
                         print_record(device);
                         break;
                 default:
-                        fprintf(stderr, "unknown query type\n");
-                        break;
+                        assert_not_reached("unknown query type");
                 }
                 break;
         case ACTION_ATTRIBUTE_WALK:
index b2f7f6b..e776fb9 100644 (file)
 
 static bool udev_exit;
 
-static void sig_handler(int signum)
-{
+static void sig_handler(int signum) {
         if (signum == SIGINT || signum == SIGTERM)
                 udev_exit = true;
 }
 
-static void print_device(struct udev_device *device, const char *source, int prop)
-{
+static void print_device(struct udev_device *device, const char *source, int prop) {
         struct timespec ts;
 
         clock_gettime(CLOCK_MONOTONIC, &ts);
-        printf("%-6s[%llu.%06u] %-8s %s (%s)\n",
+        printf("%-6s[%"PRI_TIME".%06ld] %-8s %s (%s)\n",
                source,
-               (unsigned long long) ts.tv_sec, (unsigned int) ts.tv_nsec/1000,
+               ts.tv_sec, ts.tv_nsec/1000,
                udev_device_get_action(device),
                udev_device_get_devpath(device),
                udev_device_get_subsystem(device));
@@ -75,8 +73,7 @@ static void help(void) {
                "  -h,--help\n\n");
 }
 
-static int adm_monitor(struct udev *udev, int argc, char *argv[])
-{
+static int adm_monitor(struct udev *udev, int argc, char *argv[]) {
         struct sigaction act = {};
         sigset_t mask;
         bool prop = false;
index b026155..ddcf1dd 100644 (file)
 #include <errno.h>
 #include <dirent.h>
 #include <fcntl.h>
-#include <syslog.h>
 #include <getopt.h>
 #include <signal.h>
 #include <time.h>
-#include <sys/inotify.h>
 #include <sys/poll.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 static void help(void) {
         printf("Usage: udevadm settle OPTIONS\n"
                "  -t,--timeout=<seconds>     maximum time to wait for events\n"
-               "  -s,--seq-start=<seqnum>    first seqnum to wait for\n"
-               "  -e,--seq-end=<seqnum>      last seqnum to wait for\n"
                "  -E,--exit-if-exists=<file> stop waiting if file exists\n"
-               "  -q,--quiet                 do not print list after timeout\n"
                "  -h,--help\n\n");
 }
 
-static int adm_settle(struct udev *udev, int argc, char *argv[])
-{
+static int adm_settle(struct udev *udev, int argc, char *argv[]) {
         static const struct option options[] = {
-                { "seq-start",      required_argument, NULL, 's' },
-                { "seq-end",        required_argument, NULL, 'e' },
+                { "seq-start",      required_argument, NULL, '\0' }, /* removed */
+                { "seq-end",        required_argument, NULL, '\0' }, /* removed */
                 { "timeout",        required_argument, NULL, 't' },
                 { "exit-if-exists", required_argument, NULL, 'E' },
-                { "quiet",          no_argument,       NULL, 'q' },
+                { "quiet",          no_argument,       NULL, 'q' },  /* removed */
                 { "help",           no_argument,       NULL, 'h' },
                 {}
         };
-        usec_t start_usec = now(CLOCK_MONOTONIC);
-        usec_t start = 0;
-        usec_t end = 0;
-        int quiet = 0;
         const char *exists = NULL;
         unsigned int timeout = 120;
         struct pollfd pfd[1] = { {.fd = -1}, };
-        _cleanup_udev_queue_unref_ struct udev_queue *udev_queue = NULL;
-        int rc = EXIT_FAILURE, c;
+        int c;
+        struct udev_queue *queue;
+        int rc = EXIT_FAILURE;
 
-        while ((c = getopt_long(argc, argv, "s:e:t:E:qh", options, NULL)) >= 0)
+        while ((c = getopt_long(argc, argv, "s:e:t:E:qh", options, NULL)) >= 0) {
                 switch (c) {
-                case 's':
-                        start = strtoull(optarg, NULL, 0);
-                        break;
-                case 'e':
-                        end = strtoull(optarg, NULL, 0);
-                        break;
                 case 't': {
                         int r;
 
@@ -91,53 +76,19 @@ static int adm_settle(struct udev *udev, int argc, char *argv[])
                 case 'E':
                         exists = optarg;
                         break;
-                case 'q':
-                        quiet = 1;
-                        break;
                 case 'h':
                         help();
-                        exit(EXIT_SUCCESS);
+                        return EXIT_SUCCESS;
                 case '?':
-                        exit(EXIT_FAILURE);
+                        return EXIT_FAILURE;
                 default:
-                        assert_not_reached("Unkown argument");
+                        assert_not_reached("Unknown argument");
                 }
+        }
 
         if (optind < argc) {
                 fprintf(stderr, "Extraneous argument: '%s'\n", argv[optind]);
-                exit(EXIT_FAILURE);
-        }
-
-        udev_queue = udev_queue_new(udev);
-        if (udev_queue == NULL)
-                exit(2);
-
-        if (start > 0) {
-                unsigned long long kernel_seq;
-
-                kernel_seq = udev_queue_get_kernel_seqnum(udev_queue);
-
-                /* unless specified, the last event is the current kernel seqnum */
-                if (end == 0)
-                        end = udev_queue_get_kernel_seqnum(udev_queue);
-
-                if (start > end) {
-                        log_error("seq-start larger than seq-end, ignoring");
-                        start = 0;
-                        end = 0;
-                }
-
-                if (start > kernel_seq || end > kernel_seq) {
-                        log_error("seq-start or seq-end larger than current kernel value, ignoring");
-                        start = 0;
-                        end = 0;
-                }
-                log_debug("start=%llu end=%llu current=%llu", (unsigned long long)start, (unsigned long long)end, kernel_seq);
-        } else {
-                if (end > 0) {
-                        log_error("seq-end needs seq-start parameter, ignoring");
-                        end = 0;
-                }
+                return EXIT_FAILURE;
         }
 
         /* guarantee that the udev daemon isn't pre-processing */
@@ -149,92 +100,50 @@ static int adm_settle(struct udev *udev, int argc, char *argv[])
                         if (udev_ctrl_send_ping(uctrl, timeout) < 0) {
                                 log_debug("no connection to daemon");
                                 udev_ctrl_unref(uctrl);
-                                rc = EXIT_SUCCESS;
-                                goto out;
+                                return EXIT_SUCCESS;
                         }
                         udev_ctrl_unref(uctrl);
                 }
         }
 
+        queue = udev_queue_new(udev);
+        if (!queue) {
+                log_error("unable to get udev queue");
+                return EXIT_FAILURE;
+        }
+
         pfd[0].events = POLLIN;
-        pfd[0].fd = inotify_init1(IN_CLOEXEC);
+        pfd[0].fd = udev_queue_get_fd(queue);
         if (pfd[0].fd < 0) {
-                log_error("inotify_init failed: %m");
-        } else {
-                if (inotify_add_watch(pfd[0].fd, "/run/udev" , IN_MOVED_TO) < 0) {
-                        log_error("watching /run/udev failed");
-                        close(pfd[0].fd);
-                        pfd[0].fd = -1;
-                }
+                log_debug("queue is empty, nothing to watch");
+                rc = EXIT_SUCCESS;
+                goto out;
         }
 
         for (;;) {
-                struct stat statbuf;
-
-                if (exists != NULL && stat(exists, &statbuf) == 0) {
+                if (exists && access(exists, F_OK) >= 0) {
                         rc = EXIT_SUCCESS;
                         break;
                 }
 
-                if (start > 0) {
-                        /* if asked for, wait for a specific sequence of events */
-                        if (udev_queue_get_seqnum_sequence_is_finished(udev_queue, start, end) == 1) {
-                                rc = EXIT_SUCCESS;
-                                break;
-                        }
-                } else {
-                        /* exit if queue is empty */
-                        if (udev_queue_get_queue_is_empty(udev_queue)) {
-                                rc = EXIT_SUCCESS;
-                                break;
-                        }
-                }
-
-                if (pfd[0].fd >= 0) {
-                        int delay;
-
-                        if (exists != NULL || start > 0)
-                                delay = 100;
-                        else
-                                delay = 1000;
-                        /* wake up after delay, or immediately after the queue is rebuilt */
-                        if (poll(pfd, 1, delay) > 0 && pfd[0].revents & POLLIN) {
-                                char buf[sizeof(struct inotify_event) + PATH_MAX];
-
-                                read(pfd[0].fd, buf, sizeof(buf));
-                        }
-                } else {
-                        sleep(1);
+                /* exit if queue is empty */
+                if (udev_queue_get_queue_is_empty(queue)) {
+                        rc = EXIT_SUCCESS;
+                        break;
                 }
 
-                if (timeout > 0) {
-                        usec_t age_usec;
-
-                        age_usec = now(CLOCK_MONOTONIC) - start_usec;
-                        if (age_usec / (1000 * 1000) >= timeout) {
-                                struct udev_list_entry *list_entry;
-
-                                if (!quiet && udev_queue_get_queued_list_entry(udev_queue) != NULL) {
-                                        log_debug("timeout waiting for udev queue");
-                                        printf("\nudevadm settle - timeout of %i seconds reached, the event queue contains:\n", timeout);
-                                        udev_list_entry_foreach(list_entry, udev_queue_get_queued_list_entry(udev_queue))
-                                                printf("  %s (%s)\n",
-                                                udev_list_entry_get_name(list_entry),
-                                                udev_list_entry_get_value(list_entry));
-                                }
-
-                                break;
-                        }
-                }
+                /* wake up when queue is empty */
+                if (poll(pfd, 1, MSEC_PER_SEC) > 0 && pfd[0].revents & POLLIN)
+                        udev_queue_flush(queue);
         }
+
 out:
-        if (pfd[0].fd >= 0)
-                close(pfd[0].fd);
+        udev_queue_unref(queue);
         return rc;
 }
 
 const struct udevadm_cmd udevadm_settle = {
         .name = "settle",
         .cmd = adm_settle,
-        .help = "wait for the event queue to finish",
+        .help = "wait for pending udev events",
 };
index 8041878..a300e1e 100644 (file)
@@ -23,7 +23,6 @@
 #include <errno.h>
 #include <dirent.h>
 #include <fcntl.h>
-#include <syslog.h>
 #include <getopt.h>
 #include <signal.h>
 #include <time.h>
 
 #include "udev.h"
 
-static void help(struct udev *udev)
-{
+static void help(struct udev *udev) {
         fprintf(stderr, "\n");
         fprintf(stderr, "Usage: udevadm builtin [--help] COMMAND SYSPATH\n");
         udev_builtin_list(udev);
         fprintf(stderr, "\n");
 }
 
-static int adm_builtin(struct udev *udev, int argc, char *argv[])
-{
+static int adm_builtin(struct udev *udev, int argc, char *argv[]) {
         static const struct option options[] = {
                 { "help", no_argument, NULL, 'h' },
                 {}
index 6cd311b..8486049 100644 (file)
 #include <ctype.h>
 #include <fcntl.h>
 #include <signal.h>
-#include <syslog.h>
 #include <getopt.h>
 #include <sys/signalfd.h>
 
 #include "udev.h"
 #include "udev-util.h"
 
-static int adm_test(struct udev *udev, int argc, char *argv[])
-{
+static int adm_test(struct udev *udev, int argc, char *argv[]) {
         int resolve_names = 1;
         char filename[UTIL_PATH_SIZE];
         const char *action = "add";
@@ -43,7 +41,6 @@ static int adm_test(struct udev *udev, int argc, char *argv[])
         _cleanup_udev_device_unref_ struct udev_device *dev = NULL;
         _cleanup_udev_event_unref_ struct udev_event *event = NULL;
         sigset_t mask, sigmask_orig;
-        int err;
         int rc = 0, c;
 
         static const struct option options[] = {
@@ -139,18 +136,16 @@ static int adm_test(struct udev *udev, int argc, char *argv[])
                 goto out;
         }
 
-        err = udev_event_execute_rules(event, rules, &sigmask_orig);
+        udev_event_execute_rules(event, 30 * USEC_PER_SEC, rules, &sigmask_orig);
 
         udev_list_entry_foreach(entry, udev_device_get_properties_list_entry(dev))
                 printf("%s=%s\n", udev_list_entry_get_name(entry), udev_list_entry_get_value(entry));
 
-        if (err == 0) {
-                udev_list_entry_foreach(entry, udev_list_get_entry(&event->run_list)) {
-                        char program[UTIL_PATH_SIZE];
+        udev_list_entry_foreach(entry, udev_list_get_entry(&event->run_list)) {
+                char program[UTIL_PATH_SIZE];
 
-                        udev_event_apply_format(event, udev_list_entry_get_name(entry), program, sizeof(program));
-                        printf("run: '%s'\n", program);
-                }
+                udev_event_apply_format(event, udev_list_entry_get_name(entry), program, sizeof(program));
+                printf("run: '%s'\n", program);
         }
 out:
         if (event != NULL && event->fd_signal >= 0)
index 0ee27bb..a52d1b5 100644 (file)
@@ -24,7 +24,6 @@
 #include <errno.h>
 #include <dirent.h>
 #include <fcntl.h>
-#include <syslog.h>
 #include <fnmatch.h>
 #include <sys/stat.h>
 #include <sys/types.h>
@@ -38,8 +37,7 @@
 static int verbose;
 static int dry_run;
 
-static void exec_list(struct udev_enumerate *udev_enumerate, const char *action)
-{
+static void exec_list(struct udev_enumerate *udev_enumerate, const char *action) {
         struct udev_list_entry *entry;
 
         udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(udev_enumerate)) {
@@ -60,8 +58,7 @@ static void exec_list(struct udev_enumerate *udev_enumerate, const char *action)
         }
 }
 
-static const char *keyval(const char *str, const char **val, char *buf, size_t size)
-{
+static const char *keyval(const char *str, const char **val, char *buf, size_t size) {
         char *pos;
 
         strscpy(buf, size,str);
@@ -93,8 +90,7 @@ static void help(void) {
                "  -h,--help\n\n");
 }
 
-static int adm_trigger(struct udev *udev, int argc, char *argv[])
-{
+static int adm_trigger(struct udev *udev, int argc, char *argv[]) {
         static const struct option options[] = {
                 { "verbose",           no_argument,       NULL, 'v' },
                 { "dry-run",           no_argument,       NULL, 'n' },
index dbca369..2c11550 100644 (file)
@@ -1,3 +1,4 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
 /*
  * Copyright (C) 2007-2012 Kay Sievers <kay@vrfy.org>
  *
 
 void udev_main_log(struct udev *udev, int priority,
                    const char *file, int line, const char *fn,
-                   const char *format, va_list args)
-{
+                   const char *format, va_list args) {
         log_metav(priority, file, line, fn, format, args);
 }
 
-static int adm_version(struct udev *udev, int argc, char *argv[])
-{
+static int adm_version(struct udev *udev, int argc, char *argv[]) {
         printf("%s\n", VERSION);
         return 0;
 }
@@ -63,8 +62,7 @@ static const struct udevadm_cmd *udevadm_cmds[] = {
         &udevadm_help,
 };
 
-static int adm_help(struct udev *udev, int argc, char *argv[])
-{
+static int adm_help(struct udev *udev, int argc, char *argv[]) {
         unsigned int i;
 
         fprintf(stderr, "Usage: udevadm [--help] [--version] [--debug] COMMAND [COMMAND OPTIONS]\n");
@@ -75,16 +73,14 @@ static int adm_help(struct udev *udev, int argc, char *argv[])
         return 0;
 }
 
-static int run_command(struct udev *udev, const struct udevadm_cmd *cmd, int argc, char *argv[])
-{
+static int run_command(struct udev *udev, const struct udevadm_cmd *cmd, int argc, char *argv[]) {
         if (cmd->debug)
                 log_set_max_level(LOG_DEBUG);
         log_debug("calling: %s", cmd->name);
         return cmd->cmd(udev, argc, argv);
 }
 
-int main(int argc, char *argv[])
-{
+int main(int argc, char *argv[]) {
         struct udev *udev;
         static const struct option options[] = {
                 { "debug", no_argument, NULL, 'd' },
@@ -94,7 +90,7 @@ int main(int argc, char *argv[])
         };
         const char *command;
         unsigned int i;
-        int rc = 1;
+        int rc = 1, c;
 
         udev = udev_new();
         if (udev == NULL)
@@ -105,32 +101,30 @@ int main(int argc, char *argv[])
         udev_set_log_fn(udev, udev_main_log);
         label_init("/dev");
 
-        for (;;) {
-                int option;
+        while ((c = getopt_long(argc, argv, "+dhV", options, NULL)) >= 0)
+                switch (c) {
 
-                option = getopt_long(argc, argv, "+dhV", options, NULL);
-                if (option == -1)
-                        break;
-
-                switch (option) {
                 case 'd':
                         log_set_max_level(LOG_DEBUG);
                         udev_set_log_priority(udev, LOG_DEBUG);
                         break;
+
                 case 'h':
                         rc = adm_help(udev, argc, argv);
                         goto out;
+
                 case 'V':
                         rc = adm_version(udev, argc, argv);
                         goto out;
+
                 default:
                         goto out;
                 }
-        }
+
         command = argv[optind];
 
         if (command != NULL)
-                for (i = 0; i < ELEMENTSOF(udevadm_cmds); i++) {
+                for (i = 0; i < ELEMENTSOF(udevadm_cmds); i++)
                         if (streq(udevadm_cmds[i]->name, command)) {
                                 argc -= optind;
                                 argv += optind;
@@ -139,10 +133,8 @@ int main(int argc, char *argv[])
                                 rc = run_command(udev, udevadm_cmds[i], argc, argv);
                                 goto out;
                         }
-                }
 
-        fprintf(stderr, "missing or unknown command\n\n");
-        adm_help(udev, argc, argv);
+        fprintf(stderr, "%s: missing or unknown command", program_invocation_short_name);
         rc = 2;
 out:
         label_finish();
index f21c227..f882cfb 100644 (file)
 #include <time.h>
 #include <getopt.h>
 #include <dirent.h>
+#include <sys/file.h>
 #include <sys/time.h>
 #include <sys/prctl.h>
 #include <sys/socket.h>
 #include <sys/un.h>
 #include <sys/signalfd.h>
 #include <sys/epoll.h>
+#include <sys/mount.h>
 #include <sys/poll.h>
 #include <sys/wait.h>
 #include <sys/stat.h>
@@ -45,6 +47,7 @@
 #include <sys/utsname.h>
 
 #include "udev.h"
+#include "udev-util.h"
 #include "sd-daemon.h"
 #include "cgroup-util.h"
 #include "dev-setup.h"
@@ -54,13 +57,11 @@ static bool debug;
 
 void udev_main_log(struct udev *udev, int priority,
                    const char *file, int line, const char *fn,
-                   const char *format, va_list args)
-{
+                   const char *format, va_list args) {
         log_metav(priority, file, line, fn, format, args);
 }
 
 static struct udev_rules *rules;
-static struct udev_queue_export *udev_queue_export;
 static struct udev_ctrl *udev_ctrl;
 static struct udev_monitor *monitor;
 static int worker_watch[2] = { -1, -1 };
@@ -72,6 +73,7 @@ static bool reload;
 static int children;
 static int children_max;
 static int exec_delay;
+static usec_t event_timeout_usec = 30 * USEC_PER_SEC;
 static sigset_t sigmask_orig;
 static UDEV_LIST(event_list);
 static UDEV_LIST(worker_list);
@@ -103,8 +105,7 @@ struct event {
 #endif
 };
 
-static inline struct event *node_to_event(struct udev_list_node *node)
-{
+static inline struct event *node_to_event(struct udev_list_node *node) {
         return container_of(node, struct event, node);
 }
 
@@ -134,39 +135,29 @@ struct worker_message {
         int exitcode;
 };
 
-static inline struct worker *node_to_worker(struct udev_list_node *node)
-{
+static inline struct worker *node_to_worker(struct udev_list_node *node) {
         return container_of(node, struct worker, node);
 }
 
-static void event_queue_delete(struct event *event, bool export)
-{
+static void event_queue_delete(struct event *event) {
         udev_list_node_remove(&event->node);
-
-        if (export) {
-                udev_queue_export_device_finished(udev_queue_export, event->dev);
-                log_debug("seq %llu done with %i", udev_device_get_seqnum(event->dev), event->exitcode);
-        }
         udev_device_unref(event->dev);
         free(event);
 }
 
-static struct worker *worker_ref(struct worker *worker)
-{
+static struct worker *worker_ref(struct worker *worker) {
         worker->refcount++;
         return worker;
 }
 
-static void worker_cleanup(struct worker *worker)
-{
+static void worker_cleanup(struct worker *worker) {
         udev_list_node_remove(&worker->node);
         udev_monitor_unref(worker->monitor);
         children--;
         free(worker);
 }
 
-static void worker_unref(struct worker *worker)
-{
+static void worker_unref(struct worker *worker) {
         worker->refcount--;
         if (worker->refcount > 0)
                 return;
@@ -174,8 +165,7 @@ static void worker_unref(struct worker *worker)
         worker_cleanup(worker);
 }
 
-static void worker_list_cleanup(struct udev *udev)
-{
+static void worker_list_cleanup(struct udev *udev) {
         struct udev_list_node *loop, *tmp;
 
         udev_list_node_foreach_safe(loop, tmp, &worker_list) {
@@ -185,8 +175,7 @@ static void worker_list_cleanup(struct udev *udev)
         }
 }
 
-static void worker_new(struct event *event)
-{
+static void worker_new(struct event *event) {
         struct udev *udev = event->udev;
         struct worker *worker;
         struct udev_monitor *worker_monitor;
@@ -225,7 +214,6 @@ static void worker_new(struct event *event)
                 free(worker);
                 worker_list_cleanup(udev);
                 event_queue_cleanup(udev, EVENT_UNDEF);
-                udev_queue_export_unref(udev_queue_export);
                 udev_monitor_unref(monitor);
                 udev_ctrl_unref(udev_ctrl);
                 close(fd_signal);
@@ -272,7 +260,8 @@ static void worker_new(struct event *event)
                 for (;;) {
                         struct udev_event *udev_event;
                         struct worker_message msg;
-                        int err;
+                        int fd_lock = -1;
+                        int err = 0;
 
                         log_debug("seq %llu running", udev_device_get_seqnum(dev));
                         udev_event = udev_event_new(dev);
@@ -287,25 +276,54 @@ static void worker_new(struct event *event)
                         if (exec_delay > 0)
                                 udev_event->exec_delay = exec_delay;
 
+                        /*
+                         * Take a shared lock on the device node; this establishes
+                         * a concept of device "ownership" to serialize device
+                         * access. External processes holding an exclusive lock will
+                         * cause udev to skip the event handling; in the case udev
+                         * acquired the lock, the external process can block until
+                         * udev has finished its event handling.
+                         */
+                        if (!streq_ptr(udev_device_get_action(dev), "remove") &&
+                            streq_ptr("block", udev_device_get_subsystem(dev)) &&
+                            !startswith(udev_device_get_sysname(dev), "dm-") &&
+                            !startswith(udev_device_get_sysname(dev), "md")) {
+                                struct udev_device *d = dev;
+
+                                if (streq_ptr("partition", udev_device_get_devtype(d)))
+                                        d = udev_device_get_parent(d);
+
+                                if (d) {
+                                        fd_lock = open(udev_device_get_devnode(d), O_RDONLY|O_CLOEXEC|O_NOFOLLOW|O_NONBLOCK);
+                                        if (fd_lock >= 0 && flock(fd_lock, LOCK_SH|LOCK_NB) < 0) {
+                                                log_debug("Unable to flock(%s), skipping event handling: %m", udev_device_get_devnode(d));
+                                                err = -EWOULDBLOCK;
+                                                fd_lock = safe_close(fd_lock);
+                                                goto skip;
+                                        }
+                                }
+                        }
+
                         /* apply rules, create node, symlinks */
-                        err = udev_event_execute_rules(udev_event, rules, &sigmask_orig);
+                        udev_event_execute_rules(udev_event, event_timeout_usec, rules, &sigmask_orig);
 
-                        if (err == 0)
-                                udev_event_execute_run(udev_event, &sigmask_orig);
+                        udev_event_execute_run(udev_event, event_timeout_usec, &sigmask_orig);
 
                         /* apply/restore inotify watch */
-                        if (err == 0 && udev_event->inotify_watch) {
+                        if (udev_event->inotify_watch) {
                                 udev_watch_begin(udev, dev);
                                 udev_device_update_db(dev);
                         }
 
+                        safe_close(fd_lock);
+
                         /* send processed event back to libudev listeners */
                         udev_monitor_send_device(worker_monitor, NULL, dev);
 
+skip:
                         /* send udevd the result of the event execution */
                         memzero(&msg, sizeof(struct worker_message));
-                        if (err != 0)
-                                msg.exitcode = err;
+                        msg.exitcode = err;
                         msg.pid = getpid();
                         send(worker_watch[WRITE_END], &msg, sizeof(struct worker_message), 0);
 
@@ -356,10 +374,8 @@ static void worker_new(struct event *event)
                 }
 out:
                 udev_device_unref(dev);
-                if (fd_signal >= 0)
-                        close(fd_signal);
-                if (fd_ep >= 0)
-                        close(fd_ep);
+                safe_close(fd_signal);
+                safe_close(fd_ep);
                 close(fd_inotify);
                 close(worker_watch[WRITE_END]);
                 udev_rules_unref(rules);
@@ -391,8 +407,7 @@ out:
         }
 }
 
-static void event_run(struct event *event)
-{
+static void event_run(struct event *event) {
         struct udev_list_node *loop;
 
         udev_list_node_foreach(loop, &worker_list) {
@@ -427,8 +442,7 @@ static void event_run(struct event *event)
         worker_new(event);
 }
 
-static int event_queue_insert(struct udev_device *dev)
-{
+static int event_queue_insert(struct udev_device *dev) {
         struct event *event;
 
         event = new0(struct event, 1);
@@ -449,7 +463,6 @@ static int event_queue_insert(struct udev_device *dev)
                 event->nodelay = true;
 #endif
 
-        udev_queue_export_device_queued(udev_queue_export, dev);
         log_debug("seq %llu queued, '%s' '%s'", udev_device_get_seqnum(dev),
              udev_device_get_action(dev), udev_device_get_subsystem(dev));
 
@@ -458,8 +471,7 @@ static int event_queue_insert(struct udev_device *dev)
         return 0;
 }
 
-static void worker_kill(struct udev *udev)
-{
+static void worker_kill(struct udev *udev) {
         struct udev_list_node *loop;
 
         udev_list_node_foreach(loop, &worker_list) {
@@ -474,8 +486,7 @@ static void worker_kill(struct udev *udev)
 }
 
 /* lookup event for identical, parent, child device */
-static bool is_devpath_busy(struct event *event)
-{
+static bool is_devpath_busy(struct event *event) {
         struct udev_list_node *loop;
         size_t common;
 
@@ -552,8 +563,7 @@ static bool is_devpath_busy(struct event *event)
         return false;
 }
 
-static void event_queue_start(struct udev *udev)
-{
+static void event_queue_start(struct udev *udev) {
         struct udev_list_node *loop;
 
         udev_list_node_foreach(loop, &event_list) {
@@ -570,8 +580,7 @@ static void event_queue_start(struct udev *udev)
         }
 }
 
-static void event_queue_cleanup(struct udev *udev, enum event_state match_type)
-{
+static void event_queue_cleanup(struct udev *udev, enum event_state match_type) {
         struct udev_list_node *loop, *tmp;
 
         udev_list_node_foreach_safe(loop, tmp, &event_list) {
@@ -580,12 +589,11 @@ static void event_queue_cleanup(struct udev *udev, enum event_state match_type)
                 if (match_type != EVENT_UNDEF && match_type != event->state)
                         continue;
 
-                event_queue_delete(event, false);
+                event_queue_delete(event);
         }
 }
 
-static void worker_returned(int fd_worker)
-{
+static void worker_returned(int fd_worker) {
         for (;;) {
                 struct worker_message msg;
                 ssize_t size;
@@ -605,7 +613,7 @@ static void worker_returned(int fd_worker)
                         /* worker returned */
                         if (worker->event) {
                                 worker->event->exitcode = msg.exitcode;
-                                event_queue_delete(worker->event, true);
+                                event_queue_delete(worker->event);
                                 worker->event = NULL;
                         }
                         if (worker->state != WORKER_KILLED)
@@ -617,8 +625,7 @@ static void worker_returned(int fd_worker)
 }
 
 /* receive the udevd message from userspace */
-static struct udev_ctrl_connection *handle_ctrl_msg(struct udev_ctrl *uctrl)
-{
+static struct udev_ctrl_connection *handle_ctrl_msg(struct udev_ctrl *uctrl) {
         struct udev *udev = udev_ctrl_get_udev(uctrl);
         struct udev_ctrl_connection *ctrl_conn;
         struct udev_ctrl_msg *ctrl_msg = NULL;
@@ -703,20 +710,124 @@ out:
         return udev_ctrl_connection_unref(ctrl_conn);
 }
 
-/* read inotify messages */
-static int handle_inotify(struct udev *udev)
-{
+static int synthesize_change(struct udev_device *dev) {
+        char filename[UTIL_PATH_SIZE];
+        int r;
+
+        if (streq_ptr("block", udev_device_get_subsystem(dev)) &&
+            streq_ptr("disk", udev_device_get_devtype(dev)) &&
+            !startswith(udev_device_get_sysname(dev), "dm-")) {
+                bool part_table_read = false;
+                bool has_partitions = false;
+                int fd;
+                struct udev *udev = udev_device_get_udev(dev);
+                _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
+                struct udev_list_entry *item;
+
+                /*
+                 * Try to re-read the partition table. This only succeeds if
+                 * none of the devices is busy. The kernel returns 0 if no
+                 * partition table is found, and we will not get an event for
+                 * the disk.
+                 */
+                fd = open(udev_device_get_devnode(dev), O_RDONLY|O_CLOEXEC|O_NOFOLLOW|O_NONBLOCK);
+                if (fd >= 0) {
+                        r = flock(fd, LOCK_EX|LOCK_NB);
+                        if (r >= 0)
+                                r = ioctl(fd, BLKRRPART, 0);
+
+                        close(fd);
+                        if (r >= 0)
+                                part_table_read = true;
+                }
+
+                /* search for partitions */
+                e = udev_enumerate_new(udev);
+                if (!e)
+                        return -ENOMEM;
+
+                r = udev_enumerate_add_match_parent(e, dev);
+                if (r < 0)
+                        return r;
+
+                r = udev_enumerate_add_match_subsystem(e, "block");
+                if (r < 0)
+                        return r;
+
+                r = udev_enumerate_scan_devices(e);
+                if (r < 0)
+                        return r;
+
+                udev_list_entry_foreach(item, udev_enumerate_get_list_entry(e)) {
+                        _cleanup_udev_device_unref_ struct udev_device *d = NULL;
+
+                        d = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item));
+                        if (!d)
+                                continue;
+
+                        if (!streq_ptr("partition", udev_device_get_devtype(d)))
+                                continue;
+
+                        has_partitions = true;
+                        break;
+                }
+
+                /*
+                 * We have partitions and re-read the table, the kernel already sent
+                 * out a "change" event for the disk, and "remove/add" for all
+                 * partitions.
+                 */
+                if (part_table_read && has_partitions)
+                        return 0;
+
+                /*
+                 * We have partitions but re-reading the partition table did not
+                 * work, synthesize "change" for the disk and all partitions.
+                 */
+                log_debug("device %s closed, synthesising 'change'", udev_device_get_devnode(dev));
+                strscpyl(filename, sizeof(filename), udev_device_get_syspath(dev), "/uevent", NULL);
+                write_string_file(filename, "change");
+
+                udev_list_entry_foreach(item, udev_enumerate_get_list_entry(e)) {
+                        _cleanup_udev_device_unref_ struct udev_device *d = NULL;
+
+                        d = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item));
+                        if (!d)
+                                continue;
+
+                        if (!streq_ptr("partition", udev_device_get_devtype(d)))
+                                continue;
+
+                        log_debug("device %s closed, synthesising partition '%s' 'change'",
+                                  udev_device_get_devnode(dev), udev_device_get_devnode(d));
+                        strscpyl(filename, sizeof(filename), udev_device_get_syspath(d), "/uevent", NULL);
+                        write_string_file(filename, "change");
+                }
+
+                return 0;
+        }
+
+        log_debug("device %s closed, synthesising 'change'", udev_device_get_devnode(dev));
+        strscpyl(filename, sizeof(filename), udev_device_get_syspath(dev), "/uevent", NULL);
+        write_string_file(filename, "change");
+
+        return 0;
+}
+
+static int handle_inotify(struct udev *udev) {
         int nbytes, pos;
         char *buf;
         struct inotify_event *ev;
+        int r;
 
-        if ((ioctl(fd_inotify, FIONREAD, &nbytes) < 0) || (nbytes <= 0))
-                return 0;
+        r = ioctl(fd_inotify, FIONREAD, &nbytes);
+        if (r < 0 || nbytes <= 0)
+                return -errno;
 
         buf = malloc(nbytes);
-        if (buf == NULL) {
+        if (!buf) {
                 log_error("error getting buffer for inotify");
-                return -1;
+                return -ENOMEM;
         }
 
         nbytes = read(fd_inotify, buf, nbytes);
@@ -726,35 +837,23 @@ static int handle_inotify(struct udev *udev)
 
                 ev = (struct inotify_event *)(buf + pos);
                 dev = udev_watch_lookup(udev, ev->wd);
-                if (dev != NULL) {
-                        log_debug("inotify event: %x for %s", ev->mask, udev_device_get_devnode(dev));
-                        if (ev->mask & IN_CLOSE_WRITE) {
-                                char filename[UTIL_PATH_SIZE];
-                                int fd;
-
-                                log_debug("device %s closed, synthesising 'change'", udev_device_get_devnode(dev));
-                                strscpyl(filename, sizeof(filename), udev_device_get_syspath(dev), "/uevent", NULL);
-                                fd = open(filename, O_WRONLY|O_CLOEXEC);
-                                if (fd >= 0) {
-                                        if (write(fd, "change", 6) < 0)
-                                                log_debug("error writing uevent: %m");
-                                        close(fd);
-                                }
-                        }
-                        if (ev->mask & IN_IGNORED)
-                                udev_watch_end(udev, dev);
+                if (!dev)
+                        continue;
 
-                        udev_device_unref(dev);
-                }
+                log_debug("inotify event: %x for %s", ev->mask, udev_device_get_devnode(dev));
+                if (ev->mask & IN_CLOSE_WRITE)
+                        synthesize_change(dev);
+                else if (ev->mask & IN_IGNORED)
+                        udev_watch_end(udev, dev);
 
+                udev_device_unref(dev);
         }
 
         free(buf);
         return 0;
 }
 
-static void handle_signal(struct udev *udev, int signo)
-{
+static void handle_signal(struct udev *udev, int signo) {
         switch (signo) {
         case SIGINT:
         case SIGTERM:
@@ -797,7 +896,8 @@ static void handle_signal(struct udev *udev, int signo)
                                                 log_error("worker [%u] failed while handling '%s'",
                                                           pid, worker->event->devpath);
                                                 worker->event->exitcode = -32;
-                                                event_queue_delete(worker->event, true);
+                                                event_queue_delete(worker->event);
+
                                                 /* drop reference taken for state 'running' */
                                                 worker_unref(worker);
                                         }
@@ -813,8 +913,7 @@ static void handle_signal(struct udev *udev, int signo)
         }
 }
 
-static int systemd_fds(struct udev *udev, int *rctrl, int *rnetlink)
-{
+static int systemd_fds(struct udev *udev, int *rctrl, int *rnetlink) {
         int ctrl = -1, netlink = -1;
         int fd, n;
 
@@ -855,10 +954,9 @@ static int systemd_fds(struct udev *udev, int *rctrl, int *rnetlink)
  *   udev.children-max=<number of workers>  events are fully serialized if set to 1
  *   udev.exec-delay=<number of seconds>    delay execution of every executed program
  */
-static void kernel_cmdline_options(struct udev *udev)
-{
+static void kernel_cmdline_options(struct udev *udev) {
         _cleanup_free_ char *line = NULL;
-        char *w, *state;
+        const char *word, *state;
         size_t l;
         int r;
 
@@ -868,10 +966,10 @@ static void kernel_cmdline_options(struct udev *udev)
         if (r <= 0)
                 return;
 
-        FOREACH_WORD_QUOTED(w, l, line, state) {
+        FOREACH_WORD_QUOTED(word, l, line, state) {
                 char *s, *opt;
 
-                s = strndup(w, l);
+                s = strndup(word, l);
                 if (!s)
                         break;
 
@@ -891,14 +989,15 @@ static void kernel_cmdline_options(struct udev *udev)
                         children_max = strtoul(opt + 18, NULL, 0);
                 } else if (startswith(opt, "udev.exec-delay=")) {
                         exec_delay = strtoul(opt + 16, NULL, 0);
+                } else if (startswith(opt, "udev.event-timeout=")) {
+                        event_timeout_usec = strtoul(opt + 16, NULL, 0) * USEC_PER_SEC;
                 }
 
                 free(s);
         }
 }
 
-int main(int argc, char *argv[])
-{
+int main(int argc, char *argv[]) {
         struct udev *udev;
         sigset_t mask;
         int daemonize = false;
@@ -908,6 +1007,7 @@ int main(int argc, char *argv[])
                 { "debug", no_argument, NULL, 'D' },
                 { "children-max", required_argument, NULL, 'c' },
                 { "exec-delay", required_argument, NULL, 'e' },
+                { "event-timeout", required_argument, NULL, 't' },
                 { "resolve-names", required_argument, NULL, 'N' },
                 { "help", no_argument, NULL, 'h' },
                 { "version", no_argument, NULL, 'V' },
@@ -951,6 +1051,9 @@ int main(int argc, char *argv[])
                 case 'e':
                         exec_delay = strtoul(optarg, NULL, 0);
                         break;
+                case 't':
+                        event_timeout_usec = strtoul(optarg, NULL, 0) * USEC_PER_SEC;
+                        break;
                 case 'D':
                         debug = true;
                         log_set_max_level(LOG_DEBUG);
@@ -975,6 +1078,7 @@ int main(int argc, char *argv[])
                                "  --debug\n"
                                "  --children-max=<maximum number of workers>\n"
                                "  --exec-delay=<seconds to wait before executing RUN=>\n"
+                               "  --event-timeout=<seconds to wait before terminating an event>\n"
                                "  --resolve-names=early|late|never\n"
                                "  --version\n"
                                "  --help\n"
@@ -1076,14 +1180,7 @@ int main(int argc, char *argv[])
                 goto exit;
         }
 
-        udev_monitor_set_receive_buffer_size(monitor, 128*1024*1024);
-
-        /* create queue file before signalling 'ready', to make sure we block 'settle' */
-        udev_queue_export = udev_queue_export_new(udev);
-        if (udev_queue_export == NULL) {
-                log_error("error creating queue file");
-                goto exit;
-        }
+        udev_monitor_set_receive_buffer_size(monitor, 128 * 1024 * 1024);
 
         if (daemonize) {
                 pid_t pid;
@@ -1241,12 +1338,12 @@ int main(int argc, char *argv[])
                         worker_kill(udev);
 
                         /* exit after all has cleaned up */
-                        if (udev_list_node_is_empty(&event_list) && udev_list_node_is_empty(&worker_list))
+                        if (udev_list_node_is_empty(&event_list) && children == 0)
                                 break;
 
                         /* timeout at exit for workers to finish */
-                        timeout = 30 * 1000;
-                } else if (udev_list_node_is_empty(&event_list) && !children) {
+                        timeout = 30 * MSEC_PER_SEC;
+                } else if (udev_list_node_is_empty(&event_list) && children == 0) {
                         /* we are idle */
                         timeout = -1;
 
@@ -1255,8 +1352,20 @@ int main(int argc, char *argv[])
                                 cg_kill(SYSTEMD_CGROUP_CONTROLLER, udev_cgroup, SIGKILL, false, true, NULL);
                 } else {
                         /* kill idle or hanging workers */
-                        timeout = 3 * 1000;
+                        timeout = 3 * MSEC_PER_SEC;
                 }
+
+                /* tell settle that we are busy or idle */
+                if (!udev_list_node_is_empty(&event_list)) {
+                        int fd;
+
+                        fd = open("/run/udev/queue", O_WRONLY|O_CREAT|O_CLOEXEC|O_TRUNC|O_NOFOLLOW, 0444);
+                        if (fd >= 0)
+                                close(fd);
+                } else {
+                        unlink("/run/udev/queue");
+                }
+
                 fdcount = epoll_wait(fd_ep, ev, ELEMENTSOF(ev), timeout);
                 if (fdcount < 0)
                         continue;
@@ -1283,20 +1392,17 @@ int main(int argc, char *argv[])
                                 if (worker->state != WORKER_RUNNING)
                                         continue;
 
-                                if ((now(CLOCK_MONOTONIC) - worker->event_start_usec) > 30 * 1000 * 1000) {
-                                        log_error("worker [%u] %s timeout; kill it", worker->pid,
-                                            worker->event ? worker->event->devpath : "<idle>");
+                                if ((now(CLOCK_MONOTONIC) - worker->event_start_usec) > event_timeout_usec) {
+                                        log_error("worker [%u] %s timeout; kill it", worker->pid, worker->event->devpath);
                                         kill(worker->pid, SIGKILL);
                                         worker->state = WORKER_KILLED;
+
                                         /* drop reference taken for state 'running' */
                                         worker_unref(worker);
-                                        if (worker->event) {
-                                                log_error("seq %llu '%s' killed",
-                                                          udev_device_get_seqnum(worker->event->dev), worker->event->devpath);
-                                                worker->event->exitcode = -64;
-                                                event_queue_delete(worker->event, true);
-                                                worker->event = NULL;
-                                        }
+                                        log_error("seq %llu '%s' killed", udev_device_get_seqnum(worker->event->dev), worker->event->devpath);
+                                        worker->event->exitcode = -64;
+                                        event_queue_delete(worker->event);
+                                        worker->event = NULL;
                                 }
                         }
 
@@ -1317,7 +1423,7 @@ int main(int argc, char *argv[])
                 }
 
                 /* check for changed config, every 3 seconds at most */
-                if ((now(CLOCK_MONOTONIC) - last_usec) > 3 * 1000 * 1000) {
+                if ((now(CLOCK_MONOTONIC) - last_usec) > 3 * USEC_PER_SEC) {
                         if (udev_rules_check_timestamp(rules))
                                 reload = true;
                         if (udev_builtin_validate(udev))
@@ -1390,8 +1496,8 @@ int main(int argc, char *argv[])
 
         rc = EXIT_SUCCESS;
 exit:
-        udev_queue_export_cleanup(udev_queue_export);
         udev_ctrl_cleanup(udev_ctrl);
+        unlink("/run/udev/queue");
 exit_daemonize:
         if (fd_ep >= 0)
                 close(fd_ep);
@@ -1406,7 +1512,6 @@ exit_daemonize:
         if (worker_watch[WRITE_END] >= 0)
                 close(worker_watch[WRITE_END]);
         udev_monitor_unref(monitor);
-        udev_queue_export_unref(udev_queue_export);
         udev_ctrl_connection_unref(ctrl_conn);
         udev_ctrl_unref(udev_ctrl);
         label_finish();
diff --git a/src/update-done/Makefile b/src/update-done/Makefile
new file mode 120000 (symlink)
index 0000000..d0b0e8e
--- /dev/null
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/update-done/update-done.c b/src/update-done/update-done.c
new file mode 100644 (file)
index 0000000..db106b5
--- /dev/null
@@ -0,0 +1,126 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "util.h"
+#include "label.h"
+
+#define MESSAGE                                                         \
+        "This file was created by systemd-update-done. Its only \n"     \
+        "purpose is to hold a timestamp of the time this directory\n"   \
+        "was updated. See systemd-update-done.service(8).\n"
+
+static int apply_timestamp(const char *path, struct timespec *ts) {
+        struct timespec twice[2];
+        struct stat st;
+
+        assert(path);
+        assert(ts);
+
+        if (stat(path, &st) >= 0) {
+                /* Is the timestamp file already newer than the OS? If so, there's nothing to do. */
+                if (st.st_mtim.tv_sec > ts->tv_sec ||
+                    (st.st_mtim.tv_sec == ts->tv_sec && st.st_mtim.tv_nsec >= ts->tv_nsec))
+                        return 0;
+
+                /* It is older? Then let's update it */
+                twice[0] = *ts;
+                twice[1] = *ts;
+
+                if (utimensat(AT_FDCWD, path, twice, AT_SYMLINK_NOFOLLOW) < 0) {
+
+                        if (errno == EROFS) {
+                                log_debug("Can't update timestamp file %s, file system is read-only.", path);
+                                return 0;
+                        }
+
+                        log_error("Failed to update timestamp on %s: %m", path);
+                        return -errno;
+                }
+
+        } else if (errno == ENOENT) {
+                _cleanup_close_ int fd = -1;
+                int r;
+
+                /* The timestamp file doesn't exist yet? Then let's create it. */
+
+                r = label_context_set(path, S_IFREG);
+                if (r < 0) {
+                        log_error("Failed to set SELinux context for %s: %s",
+                                  path, strerror(-r));
+                        return r;
+                }
+
+                fd = open(path, O_CREAT|O_EXCL|O_WRONLY|O_TRUNC|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0644);
+                label_context_clear();
+
+                if (fd < 0) {
+
+                        if (errno == EROFS) {
+                                log_debug("Can't create timestamp file %s, file system is read-only.", path);
+                                return 0;
+                        }
+
+                        log_error("Failed to create timestamp file %s: %m", path);
+                        return -errno;
+                }
+
+                (void) loop_write(fd, MESSAGE, strlen(MESSAGE), false);
+
+                twice[0] = *ts;
+                twice[1] = *ts;
+
+                if (futimens(fd, twice) < 0) {
+                        log_error("Failed to update timestamp on %s: %m", path);
+                        return -errno;
+                }
+        } else {
+                log_error("Failed to stat() timestamp file %s: %m", path);
+                return -errno;
+        }
+
+        return 0;
+}
+
+int main(int argc, char *argv[]) {
+        struct stat st;
+        int r, q = 0;
+
+        log_set_target(LOG_TARGET_AUTO);
+        log_parse_environment();
+        log_open();
+
+        if (stat("/usr", &st) < 0) {
+                log_error("Failed to stat /usr: %m");
+                return EXIT_FAILURE;
+        }
+
+        r = label_init(NULL);
+        if (r < 0) {
+                log_error("SELinux setup failed: %s", strerror(-r));
+                goto finish;
+        }
+
+        r = apply_timestamp("/etc/.updated", &st.st_mtim);
+        q = apply_timestamp("/var/.updated", &st.st_mtim);
+
+finish:
+        return r < 0 || q < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
index e5fb5f8..31cae70 100644 (file)
@@ -270,7 +270,7 @@ int main(int argc, char *argv[]) {
                 goto finish;
         }
 
-        log_debug("systemd-update-utmp running as pid %lu", (unsigned long) getpid());
+        log_debug("systemd-update-utmp running as pid "PID_FMT, getpid());
 
         if (streq(argv[1], "reboot"))
                 r = on_reboot(&c);
@@ -283,7 +283,7 @@ int main(int argc, char *argv[]) {
                 r = -EINVAL;
         }
 
-        log_debug("systemd-update-utmp stopped as pid %lu", (unsigned long) getpid());
+        log_debug("systemd-update-utmp stopped as pid "PID_FMT, getpid());
 
 finish:
 #ifdef HAVE_AUDIT
index 1bbf737..645b1e6 100644 (file)
@@ -180,6 +180,10 @@ static int font_load(const char *vc, const char *font, const char *map, const ch
  */
 static void font_copy_to_all_vcs(int fd) {
         struct vt_stat vcs = {};
+        unsigned char map8[E_TABSZ];
+        unsigned short map16[E_TABSZ];
+        struct unimapdesc unimapd;
+        struct unipair unipairs[USHRT_MAX];
         int i, r;
 
         /* get active, and 16 bit mask of used VT numbers */
@@ -209,17 +213,35 @@ static void font_copy_to_all_vcs(int fd) {
                 cfo.op = KD_FONT_OP_COPY;
                 cfo.height = vcs.v_active-1; /* tty1 == index 0 */
                 ioctl(vcfd, KDFONTOP, &cfo);
+
+                /* copy map of 8bit chars */
+                if (ioctl(fd, GIO_SCRNMAP, map8) >= 0)
+                    ioctl(vcfd, PIO_SCRNMAP, map8);
+
+                /* copy map of 8bit chars -> 16bit Unicode values */
+                if (ioctl(fd, GIO_UNISCRNMAP, map16) >= 0)
+                    ioctl(vcfd, PIO_UNISCRNMAP, map16);
+
+                /* copy unicode translation table */
+                /* unimapd is a ushort count and a pointer to an
+                   array of struct unipair { ushort, ushort } */
+                unimapd.entries  = unipairs;
+                unimapd.entry_ct = USHRT_MAX;
+                if (ioctl(fd, GIO_UNIMAP, &unimapd) >= 0) {
+                        struct unimapinit adv = { 0, 0, 0 };
+
+                        ioctl(vcfd, PIO_UNIMAPCLR, &adv);
+                        ioctl(vcfd, PIO_UNIMAP, &unimapd);
+                }
         }
 }
 
 int main(int argc, char **argv) {
         const char *vc;
-        char *vc_keymap = NULL;
-        char *vc_keymap_toggle = NULL;
-        char *vc_font = NULL;
-        char *vc_font_map = NULL;
-        char *vc_font_unimap = NULL;
-        int fd = -1;
+        _cleanup_free_ char
+                *vc_keymap = NULL, *vc_keymap_toggle = NULL,
+                *vc_font = NULL, *vc_font_map = NULL, *vc_font_unimap = NULL;
+        _cleanup_close_ int fd = -1;
         bool utf8;
         pid_t font_pid = 0, keymap_pid = 0;
         bool font_copy = false;
@@ -241,12 +263,12 @@ int main(int argc, char **argv) {
         fd = open_terminal(vc, O_RDWR|O_CLOEXEC);
         if (fd < 0) {
                 log_error("Failed to open %s: %m", vc);
-                goto finish;
+                return EXIT_FAILURE;
         }
 
         if (!is_vconsole(fd)) {
                 log_error("Device %s is not a virtual console.", vc);
-                goto finish;
+                return EXIT_FAILURE;
         }
 
         utf8 = is_locale_utf8();
@@ -281,28 +303,27 @@ int main(int argc, char **argv) {
         else
                 disable_utf8(fd);
 
-        r = EXIT_FAILURE;
-        if (keymap_load(vc, vc_keymap, vc_keymap_toggle, utf8, &keymap_pid) >= 0 &&
-            font_load(vc, vc_font, vc_font_map, vc_font_unimap, &font_pid) >= 0)
-                r = EXIT_SUCCESS;
-
-finish:
-        if (keymap_pid > 0)
-                wait_for_terminate_and_warn(KBD_LOADKEYS, keymap_pid);
+        r = font_load(vc, vc_font, vc_font_map, vc_font_unimap, &font_pid);
+        if (r < 0) {
+                log_error("Failed to start " KBD_SETFONT ": %s", strerror(-r));
+                return EXIT_FAILURE;
+        }
 
-        if (font_pid > 0) {
+        if (font_pid > 0)
                 wait_for_terminate_and_warn(KBD_SETFONT, font_pid);
-                if (font_copy)
-                        font_copy_to_all_vcs(fd);
+
+        r = keymap_load(vc, vc_keymap, vc_keymap_toggle, utf8, &keymap_pid);
+        if (r < 0) {
+                log_error("Failed to start " KBD_LOADKEYS ": %s", strerror(-r));
+                return EXIT_FAILURE;
         }
 
-        free(vc_keymap);
-        free(vc_font);
-        free(vc_font_map);
-        free(vc_font_unimap);
+        if (keymap_pid > 0)
+                wait_for_terminate_and_warn(KBD_LOADKEYS, keymap_pid);
 
-        if (fd >= 0)
-                close_nointr_nofail(fd);
+        /* Only copy the font when we started setfont successfully */
+        if (font_copy && font_pid > 0)
+                font_copy_to_all_vcs(fd);
 
-        return r;
+        return EXIT_SUCCESS;
 }
index d5795a3..d5f600e 100644 (file)
@@ -5,6 +5,8 @@
 #  the Free Software Foundation; either version 2.1 of the License, or
 #  (at your option) any later version.
 
-# See sysctl.d(5) and core(5) for for details.
+# See sysctl.d(5) for the description of the files in this directory,
+# and systemd-coredump(8) and core(5) for the explanation of the
+# setting below.
 
 kernel.core_pattern=|@rootlibexecdir@/systemd-coredump %p %u %g %s %t %e
index 46bae21..8fc9ab7 100644 (file)
@@ -15,9 +15,15 @@ kernel.core_uses_pid = 1
 
 # Source route verification
 net.ipv4.conf.default.rp_filter = 1
+net.ipv4.conf.all.rp_filter = 1
 
 # Do not accept source routing
 net.ipv4.conf.default.accept_source_route = 0
+net.ipv4.conf.all.accept_source_route = 0
+
+# Promote secondary addresses when the primary address is removed
+net.ipv4.conf.default.promote_secondaries = 1
+net.ipv4.conf.all.promote_secondaries = 1
 
 # Enable hard and soft link protection
 fs.protected_hardlinks = 1
diff --git a/system-preset/90-systemd.preset b/system-preset/90-systemd.preset
new file mode 100644 (file)
index 0000000..e4a9e17
--- /dev/null
@@ -0,0 +1,31 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+# These ones should be enabled by default, even if distributions
+# generally follow a default-off policy.
+
+enable remote-fs.target
+enable getty@.service
+enable systemd-readahead-*
+enable systemd-timesyncd.service
+enable systemd-networkd.service
+enable systemd-resolved.service
+
+disable console-getty.service
+disable console-shell.service
+disable debug-shell.service
+
+disable halt.target
+disable kexec.target
+disable poweroff.target
+disable reboot.target
+disable rescue.target
+
+disable syslog.socket
+
+disable systemd-journal-gatewayd.*
+disable systemd-networkd-wait-online.service
diff --git a/system-preset/Makefile b/system-preset/Makefile
new file mode 120000 (symlink)
index 0000000..bd10475
--- /dev/null
@@ -0,0 +1 @@
+../src/Makefile
\ No newline at end of file
diff --git a/sysusers.d/.gitignore b/sysusers.d/.gitignore
new file mode 100644 (file)
index 0000000..f7957a9
--- /dev/null
@@ -0,0 +1 @@
+/basic.conf
diff --git a/sysusers.d/Makefile b/sysusers.d/Makefile
new file mode 120000 (symlink)
index 0000000..bd10475
--- /dev/null
@@ -0,0 +1 @@
+../src/Makefile
\ No newline at end of file
diff --git a/sysusers.d/basic.conf.in b/sysusers.d/basic.conf.in
new file mode 100644 (file)
index 0000000..823d6cb
--- /dev/null
@@ -0,0 +1,37 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+# The superuser
+u root    0     "Super User" /root
+
+# The nobody user for NFS file systems
+u nobody  65534 "Nobody"     -
+
+# Administrator group: can *see* more than normal users
+g adm     -     -            -
+
+# Administrator group: can *do* more than normal users
+g wheel   -     -            -
+
+# Access to certain kernel and userspace facilities
+g kmem    -     -            -
+g lock    -     -            -
+g tty     @TTY_GID@     -            -
+g utmp    -     -            -
+
+# Hardware access groups
+g audio   -     -            -
+g cdrom   -     -            -
+g dialout -     -            -
+g disk    -     -            -
+g input   -     -            -
+g lp      -     -            -
+g tape    -     -            -
+g video   -     -            -
+
+# Default group for normal users
+g users   -     -            -
diff --git a/sysusers.d/systemd-remote.conf b/sysusers.d/systemd-remote.conf
new file mode 100644 (file)
index 0000000..15969e9
--- /dev/null
@@ -0,0 +1,10 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+u systemd-journal-gateway - "systemd Journal Gateway"
+u systemd-journal-remote  - "systemd Journal Remote"
+u systemd-journal-upload  - "systemd Journal Upload"
diff --git a/sysusers.d/systemd.conf b/sysusers.d/systemd.conf
new file mode 100644 (file)
index 0000000..95437b8
--- /dev/null
@@ -0,0 +1,12 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+g systemd-journal   - -
+u systemd-bus-proxy - "systemd Bus Proxy"
+u systemd-network   - "systemd Network Management"
+u systemd-resolve   - "systemd Resolver"
+u systemd-timesync  - "systemd Time Synchronization"
index 84ccf26..d97fbe2 100755 (executable)
@@ -53,7 +53,7 @@ Description=Testsuite service
 After=multi-user.target
 
 [Service]
-ExecStart=/bin/bash -c 'set -x; ( systemctl --failed --no-legend --no-pager; systemctl status --failed ) > /failed ; echo OK > /testok; while : ;do echo "testsuite service waiting for journal to move to /var/log/journal" > /dev/console ; for i in /var/log/journal/*;do [ -d "\$i" ] && echo "\$i" && break 2; done; sleep 1; done; sleep 1; exit 0;'
+ExecStart=/bin/bash -c 'set -x; systemctl --failed --no-legend --no-pager > /failed ; echo OK > /testok; while : ;do echo "testsuite service waiting for journal to move to /var/log/journal" > /dev/console ; for i in /var/log/journal/*;do [ -d "\$i" ] && echo "\$i" && break 2; done; sleep 1; done; sleep 1; exit 0;'
 Type=oneshot
 EOF
 
index b243254..4be2365 100755 (executable)
@@ -59,7 +59,7 @@ Description=Testsuite service
 After=multi-user.target
 
 [Service]
-ExecStart=/bin/bash -c 'set -x; ( systemctl --failed --no-legend --no-pager; systemctl status --failed ) > /failed ; echo OK > /testok; while : ;do systemd-cat echo "testsuite service waiting for /var/log/journal" ; echo "testsuite service waiting for journal to move to /var/log/journal" > /dev/console ; for i in /var/log/journal/*;do [ -d "\$i" ] && echo "\$i" && break 2; done; sleep 1; done; sleep 1; exit 0;'
+ExecStart=/bin/bash -c 'set -x; systemctl --failed --no-legend --no-pager > /failed ; echo OK > /testok; while : ;do systemd-cat echo "testsuite service waiting for /var/log/journal" ; echo "testsuite service waiting for journal to move to /var/log/journal" > /dev/console ; for i in /var/log/journal/*;do [ -d "\$i" ] && echo "\$i" && break 2; done; sleep 1; done; sleep 1; exit 0;'
 Type=oneshot
 EOF
 
diff --git a/test/basic.target b/test/basic.target
new file mode 120000 (symlink)
index 0000000..0612934
--- /dev/null
@@ -0,0 +1 @@
+../units/basic.target
\ No newline at end of file
diff --git a/test/loopy.service b/test/loopy.service
new file mode 100644 (file)
index 0000000..9eb6457
--- /dev/null
@@ -0,0 +1,2 @@
+[Service]
+ExecStart=/bin/true
diff --git a/test/loopy.service.d/compat.conf b/test/loopy.service.d/compat.conf
new file mode 100644 (file)
index 0000000..51b84b8
--- /dev/null
@@ -0,0 +1,5 @@
+[Unit]
+BindsTo=loopy2.service
+
+[Install]
+Also=loopy2.service
diff --git a/test/loopy2.service b/test/loopy2.service
new file mode 120000 (symlink)
index 0000000..961b1fe
--- /dev/null
@@ -0,0 +1 @@
+loopy.service
\ No newline at end of file
diff --git a/test/loopy3.service b/test/loopy3.service
new file mode 100644 (file)
index 0000000..606e26b
--- /dev/null
@@ -0,0 +1,5 @@
+[Service]
+ExecStart=/bin/true
+
+[Unit]
+Conflicts=loopy4.service
diff --git a/test/loopy4.service b/test/loopy4.service
new file mode 120000 (symlink)
index 0000000..43e5658
--- /dev/null
@@ -0,0 +1 @@
+loopy3.service
\ No newline at end of file
diff --git a/test/paths.target b/test/paths.target
new file mode 120000 (symlink)
index 0000000..e9939c9
--- /dev/null
@@ -0,0 +1 @@
+../units/paths.target
\ No newline at end of file
diff --git a/test/shutdown.target b/test/shutdown.target
new file mode 120000 (symlink)
index 0000000..1a3c2ee
--- /dev/null
@@ -0,0 +1 @@
+../units/shutdown.target
\ No newline at end of file
diff --git a/test/sockets.target b/test/sockets.target
new file mode 120000 (symlink)
index 0000000..8ff86a0
--- /dev/null
@@ -0,0 +1 @@
+../units/sockets.target
\ No newline at end of file
diff --git a/test/sysinit.target b/test/sysinit.target
new file mode 120000 (symlink)
index 0000000..3301338
--- /dev/null
@@ -0,0 +1 @@
+../units/sysinit.target
\ No newline at end of file
diff --git a/test/timers.target b/test/timers.target
new file mode 120000 (symlink)
index 0000000..576d47f
--- /dev/null
@@ -0,0 +1 @@
+../units/timers.target
\ No newline at end of file
diff --git a/tmpfiles.d/etc.conf b/tmpfiles.d/etc.conf
new file mode 100644 (file)
index 0000000..b23272c
--- /dev/null
@@ -0,0 +1,15 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+# See tmpfiles.d(5) for details
+
+L /etc/os-release - - - - ../usr/lib/os-release
+L /etc/localtime - - - - ../usr/share/zoneinfo/UTC
+L+ /etc/mtab - - - - ../proc/self/mounts
+L /etc/resolv.conf - - - - ../run/systemd/resolve/resolv.conf
+C /etc/nsswitch.conf - - - -
+C /etc/pam.d - - - -
index a165687..3219672 100644 (file)
@@ -11,6 +11,7 @@
 # systems.
 
 d /run/lock 0755 root root -
+L /var/lock - - - - ../run/lock
 
 # /run/lock/subsys is used for serializing SysV service execution, and
 # hence without use on SysV-less systems.
diff --git a/tmpfiles.d/systemd-remote.conf b/tmpfiles.d/systemd-remote.conf
new file mode 100644 (file)
index 0000000..1b8973a
--- /dev/null
@@ -0,0 +1,11 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+# See tmpfiles.d(5) for details
+
+z /var/log/journal/remote 2755 root systemd-journal-remote - -
+z /run/log/journal/remote 2755 root systemd-journal-remote - -
diff --git a/tmpfiles.d/systemd.conf b/tmpfiles.d/systemd.conf
deleted file mode 100644 (file)
index 7c6d6b9..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-#  This file is part of systemd.
-#
-#  systemd is free software; you can redistribute it and/or modify it
-#  under the terms of the GNU Lesser General Public License as published by
-#  the Free Software Foundation; either version 2.1 of the License, or
-#  (at your option) any later version.
-
-# See tmpfiles.d(5) for details
-
-d /run/user 0755 root root ~10d
-F! /run/utmp 0664 root utmp -
-
-f /var/log/wtmp 0664 root utmp -
-f /var/log/btmp 0600 root utmp -
-
-d /var/cache/man - - - 30d
-
-d /run/systemd/ask-password 0755 root root -
-d /run/systemd/seats 0755 root root -
-d /run/systemd/sessions 0755 root root -
-d /run/systemd/users 0755 root root -
-d /run/systemd/machines 0755 root root -
-d /run/systemd/shutdown 0755 root root -
-
-m /var/log/journal 2755 root systemd-journal - -
-m /var/log/journal/%m 2755 root systemd-journal - -
-m /run/log/journal 2755 root systemd-journal - -
-m /run/log/journal/%m 2755 root systemd-journal - -
diff --git a/tmpfiles.d/systemd.conf.m4 b/tmpfiles.d/systemd.conf.m4
new file mode 100644 (file)
index 0000000..a28b89d
--- /dev/null
@@ -0,0 +1,42 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+# See tmpfiles.d(5) for details
+
+d /run/user 0755 root root -
+F! /run/utmp 0664 root utmp -
+
+d /run/systemd/ask-password 0755 root root -
+d /run/systemd/seats 0755 root root -
+d /run/systemd/sessions 0755 root root -
+d /run/systemd/users 0755 root root -
+d /run/systemd/machines 0755 root root -
+d /run/systemd/shutdown 0755 root root -
+d /run/systemd/netif 0755 systemd-network systemd-network -
+d /run/systemd/netif/links 0755 systemd-network systemd-network -
+d /run/systemd/netif/leases 0755 systemd-network systemd-network -
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+t /run/systemd - - - - security.SMACK64=_
+t /run/systemd/journal - - - - security.SMACK64=*
+
+t /run/udev - - - - security.SMACK64=_
+t /run/udev/data - - - - security.SMACK64=_
+)m4_dnl
+
+d /run/log 0755 root root -
+
+z /run/log/journal 2755 root systemd-journal - -
+Z /run/log/journal/%m ~2750 root systemd-journal - -
+
+z /var/log/journal 2755 root systemd-journal - -
+z /var/log/journal/%m 2755 root systemd-journal - -
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+t /var/log/journal - - - - security.SMACK64=*
+)m4_dnl
+
+d /var/lib/systemd 0755 root root -
+d /var/lib/systemd/coredump 0755 root root 3d
diff --git a/tmpfiles.d/var.conf b/tmpfiles.d/var.conf
new file mode 100644 (file)
index 0000000..4b63e41
--- /dev/null
@@ -0,0 +1,21 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+# See tmpfiles.d(5) for details
+
+d /var 0755 - - -
+
+L /var/run - - - - ../run
+
+d /var/log 0755 - - -
+f /var/log/wtmp 0664 root utmp -
+f /var/log/btmp 0600 root utmp -
+
+d /var/cache 0755 - - -
+
+d /var/lib 0755 - - -
+d /var/spool 0755 - - -
diff --git a/tools/compile-unifont.py b/tools/compile-unifont.py
new file mode 100755 (executable)
index 0000000..7004b94
--- /dev/null
@@ -0,0 +1,116 @@
+#  -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */
+#
+#  This file is part of systemd.
+#
+#  Copyright 2013-2014 David Herrmann <dh.herrmann@gmail.com>
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+#
+#  systemd is distributed in the hope that it will be useful, but
+#  WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+#  Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public License
+#  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
+#
+# Parse a unifont.hex file and produce a compressed binary-format.
+#
+
+from __future__ import print_function
+import re
+import sys
+import fileinput
+import struct
+
+#
+# Write "bits" array as binary output.
+#
+
+def write_bin_entry(entry):
+    l = len(entry)
+    if l != 32 and l != 64:
+        entry = "0" * 64
+        l = 0
+    elif l < 64:
+        entry += "0" * (64 - l)
+
+    sys.stdout.buffer.write(struct.pack('B', int(l / 32)))  # width
+    sys.stdout.buffer.write(struct.pack('B', 0))            # padding
+    sys.stdout.buffer.write(struct.pack('H', 0))            # padding
+    sys.stdout.buffer.write(struct.pack('I', 0))            # padding
+
+    i = 0
+    for j in range(0, 16):
+        for k in range(0, 2):
+            if l <= k * 16 * 2:
+                c = 0
+            else:
+                c = int(entry[i:i+2], 16)
+                i += 2
+
+            sys.stdout.buffer.write(struct.pack('B', c))
+
+def write_bin(bits):
+    sys.stdout.buffer.write(struct.pack('B', 0x44))         # ASCII: 'D'
+    sys.stdout.buffer.write(struct.pack('B', 0x56))         # ASCII: 'V'
+    sys.stdout.buffer.write(struct.pack('B', 0x44))         # ASCII: 'D'
+    sys.stdout.buffer.write(struct.pack('B', 0x48))         # ASCII: 'H'
+    sys.stdout.buffer.write(struct.pack('B', 0x52))         # ASCII: 'R'
+    sys.stdout.buffer.write(struct.pack('B', 0x4d))         # ASCII: 'M'
+    sys.stdout.buffer.write(struct.pack('B', 0x55))         # ASCII: 'U'
+    sys.stdout.buffer.write(struct.pack('B', 0x46))         # ASCII: 'F'
+    sys.stdout.buffer.write(struct.pack('<I', 0))           # compatible-flags
+    sys.stdout.buffer.write(struct.pack('<I', 0))           # incompatible-flags
+    sys.stdout.buffer.write(struct.pack('<I', 32))          # header-size
+    sys.stdout.buffer.write(struct.pack('<H', 8))           # glyph-header-size
+    sys.stdout.buffer.write(struct.pack('<H', 2))           # glyph-stride
+    sys.stdout.buffer.write(struct.pack('<Q', 32))          # glyph-body-size
+
+    # write glyphs
+    for idx in range(len(bits)):
+        write_bin_entry(bits[idx])
+
+#
+# Parse hex file into "bits" array
+#
+
+def parse_hex_line(bits, line):
+    m = re.match(r"^([0-9A-Fa-f]+):([0-9A-Fa-f]+)$", line)
+    if m == None:
+        return
+
+    idx = int(m.group(1), 16)
+    val = m.group(2)
+
+    # insert skipped lines
+    for i in range(len(bits), idx):
+        bits.append("")
+
+    bits.insert(idx, val)
+
+def parse_hex():
+    bits = []
+
+    for line in sys.stdin:
+        if not line:
+            continue
+        if line.startswith("#"):
+            continue
+
+        parse_hex_line(bits, line)
+
+    return bits
+
+#
+# In normal mode we simply read line by line from standard-input and write the
+# binary-file to standard-output.
+#
+
+if __name__ == "__main__":
+    bits = parse_hex()
+    write_bin(bits)
index 2ff304f..5c80a7b 100755 (executable)
@@ -113,12 +113,13 @@ TEMPLATE = '''\
         </refsect1>
 
         <refsect1>
-                <title>crypttab options</title>
+                <title><filename>/etc/crypttab</filename> and
+                <filename>/etc/fstab</filename> options</title>
 
                 <para>Options which influence mounted filesystems and
                 encrypted volumes.</para>
 
-                <variablelist id='crypttab-options' />
+                <variablelist id='fstab-options' />
         </refsect1>
 
         <refsect1>
index 6224de3..e75bfff 100644 (file)
@@ -42,8 +42,14 @@ endif
 
 HEADER = '''\
 # Do not edit. Generated by make-man-rules.py.
-# Regenerate with 'make all update-man-list'.
-
+# To regenerate:
+#   1. Create, update, or remove source .xml files in man/
+#   2. Run 'make update-man-list'
+#   3. Run 'make man' to generate manpages
+#
+# To make a man page conditional on a configure switch add
+# attribute conditional="ENABLE_WHAT" or conditional="WITH_WHAT"
+# to <refentry> element.
 '''
 
 HTML_ALIAS_RULE = '''\
@@ -53,8 +59,10 @@ HTML_ALIAS_RULE = '''\
 
 FOOTER = '''\
 
+# Really, do not edit this file.
+
 EXTRA_DIST += \\
-       {files}
+       {files}
 '''
 
 def man(page, number):
index 76c4cb3..87b67c5 100644 (file)
@@ -22,8 +22,9 @@
 /systemd-ask-password-wall.service
 /systemd-backlight@.service
 /systemd-binfmt.service
-/systemd-bus-driverd.service
+/systemd-bootchart.service
 /systemd-bus-proxyd@.service
+/systemd-firstboot.service
 /systemd-fsck-root.service
 /systemd-fsck@.service
 /systemd-halt.service
 /systemd-hostnamed.service
 /systemd-hybrid-sleep.service
 /systemd-initctl.service
+/systemd-journal-catalog-update.service
 /systemd-journal-flush.service
 /systemd-journal-gatewayd.service
+/systemd-journal-remote.service
+/systemd-journal-upload.service
 /systemd-journald.service
 /systemd-kexec.service
 /systemd-localed.service
 /systemd-logind.service
 /systemd-machined.service
 /systemd-modules-load.service
+/systemd-networkd-wait-online.service
 /systemd-networkd.service
 /systemd-nspawn@.service
 /systemd-poweroff.service
 /systemd-readahead-replay.service
 /systemd-reboot.service
 /systemd-remount-fs.service
+/systemd-resolved.service
 /systemd-rfkill@.service
 /systemd-shutdownd.service
 /systemd-suspend.service
 /systemd-sysctl.service
+/systemd-sysusers.service
 /systemd-timedated.service
+/systemd-timesyncd.service
 /systemd-tmpfiles-clean.service
 /systemd-tmpfiles-setup-dev.service
 /systemd-tmpfiles-setup.service
 /systemd-tmpfiles.service
+/systemd-udev-hwdb-update.service
 /systemd-udev-settle.service
 /systemd-udev-trigger.service
 /systemd-udevd.service
+/systemd-update-done.service
 /systemd-update-utmp-runlevel.service
 /systemd-update-utmp.service
 /systemd-user-sessions.service
index d7c68f4..b890d48 100644 (file)
@@ -11,4 +11,3 @@ Documentation=man:systemd.special(7)
 Requires=sysinit.target
 Wants=sockets.target timers.target paths.target slices.target
 After=sysinit.target sockets.target timers.target paths.target slices.target
-RefuseManualStart=yes
index 8ac51a4..c45df45 100644 (file)
@@ -26,6 +26,9 @@ TTYVHangup=yes
 KillMode=process
 IgnoreSIGPIPE=no
 SendSIGHUP=yes
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
 
 [Install]
 WantedBy=getty.target
index 3f4904a..3647348 100644 (file)
@@ -26,6 +26,9 @@ StandardError=inherit
 KillMode=process
 IgnoreSIGPIPE=no
 SendSIGHUP=yes
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
 
 [Install]
 WantedBy=getty.target
index 4f7794b..6eb43f6 100644 (file)
@@ -27,3 +27,6 @@ TTYVHangup=yes
 KillMode=process
 IgnoreSIGPIPE=no
 SendSIGHUP=yes
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
diff --git a/units/cryptsetup-pre.target b/units/cryptsetup-pre.target
new file mode 100644 (file)
index 0000000..6535341
--- /dev/null
@@ -0,0 +1,11 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Encrypted Volumes (Pre)
+Documentation=man:systemd.special(7)
+RefuseManualStart=yes
similarity index 91%
rename from units/debug-shell.service.in
rename to units/debug-shell.service.m4.in
index a6acad3..ece49d5 100644 (file)
@@ -10,6 +10,7 @@ Description=Early root shell on @DEBUGTTY@ FOR DEBUGGING ONLY
 Documentation=man:sushell(8)
 DefaultDependencies=no
 IgnoreOnIsolate=yes
+ConditionPathExists=@DEBUGTTY@
 
 [Service]
 Environment=TERM=linux
@@ -24,6 +25,9 @@ KillMode=process
 IgnoreSIGPIPE=no
 # bash ignores SIGTERM
 KillSignal=SIGHUP
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=sdbd
+)m4_dnl
 
 # Unset locale for the console getty since the console has problems
 # displaying some internationalized messages.
similarity index 85%
rename from units/emergency.service.in
rename to units/emergency.service.m4.in
index 94c090f..03f592e 100644 (file)
@@ -17,8 +17,7 @@ Environment=HOME=/root
 WorkingDirectory=/root
 ExecStartPre=-/bin/plymouth quit
 ExecStartPre=-/bin/echo -e 'Welcome to emergency mode! After logging in, type "journalctl -xb" to view\\nsystem logs, "systemctl reboot" to reboot, "systemctl default" to try again\\nto boot into default mode.'
-ExecStart=-/sbin/sulogin
-ExecStopPost=@SYSTEMCTL@ --fail --no-block default
+ExecStart=-/bin/sh -c "/sbin/sulogin; @SYSTEMCTL@ --fail --no-block default"
 Type=idle
 StandardInput=tty-force
 StandardOutput=inherit
@@ -26,3 +25,6 @@ StandardError=inherit
 KillMode=process
 IgnoreSIGPIPE=no
 SendSIGHUP=yes
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
index aa853b8..000162a 100644 (file)
@@ -39,6 +39,9 @@ TTYVTDisallocate=yes
 KillMode=process
 IgnoreSIGPIPE=no
 SendSIGHUP=yes
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
 
 # Unset locale for the console getty since the console has problems
 # displaying some internationalized messages.
@@ -46,3 +49,4 @@ Environment=LANG= LANGUAGE= LC_CTYPE= LC_NUMERIC= LC_TIME= LC_COLLATE= LC_MONETA
 
 [Install]
 WantedBy=getty.target
+DefaultInstance=tty1
similarity index 81%
rename from units/initrd-cleanup.service.in
rename to units/initrd-cleanup.service.m4.in
index b1dda16..cd308fd 100644 (file)
@@ -16,3 +16,7 @@ After=initrd-root-fs.target initrd-fs.target initrd.target
 [Service]
 Type=oneshot
 ExecStart=@rootbindir@/systemctl --no-block isolate initrd-switch-root.target
+ExecStart=@rootbindir@/systemctl --no-block isolate initrd-switch-root.target
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
similarity index 92%
rename from units/initrd-parse-etc.service.in
rename to units/initrd-parse-etc.service.m4.in
index c0b2543..31c2303 100644 (file)
@@ -20,3 +20,6 @@ ExecStartPre=@rootbindir@/systemctl daemon-reload
 # we have to retrigger initrd-fs.target after daemon-reload
 ExecStart=-@rootbindir@/systemctl --no-block start initrd-fs.target
 ExecStart=@rootbindir@/systemctl --no-block start initrd-cleanup.service
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
similarity index 90%
rename from units/initrd-switch-root.service.in
rename to units/initrd-switch-root.service.m4.in
index 82893da..e589b60 100644 (file)
@@ -18,3 +18,6 @@ Type=oneshot
 # we have to use "--force" here, otherwise systemd would umount /run
 ExecStart=@rootbindir@/systemctl --no-block --force switch-root /sysroot
 KillMode=none
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
similarity index 90%
rename from units/initrd-udevadm-cleanup-db.service.in
rename to units/initrd-udevadm-cleanup-db.service.m4.in
index 5c6654e..aa7ecb9 100644 (file)
@@ -16,3 +16,6 @@ Before=initrd-switch-root.target
 [Service]
 Type=oneshot
 ExecStart=-@rootbindir@/udevadm info --cleanup-db
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
similarity index 86%
rename from units/kmod-static-nodes.service.in
rename to units/kmod-static-nodes.service.m4.in
index 368f980..99a2fbb 100644 (file)
@@ -9,10 +9,13 @@
 Description=Create list of required static device nodes for the current kernel
 DefaultDependencies=no
 Before=sysinit.target systemd-tmpfiles-setup-dev.service
-ConditionCapability=CAP_MKNOD
+ConditionCapability=CAP_SYS_MODULE
 ConditionPathExists=/lib/modules/%v/modules.devname
 
 [Service]
 Type=oneshot
 RemainAfterExit=yes
 ExecStart=@KMOD@ static-nodes --format=tmpfiles --output=/run/tmpfiles.d/kmod.conf
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
diff --git a/units/ldconfig.service b/units/ldconfig.service
new file mode 100644 (file)
index 0000000..859d05c
--- /dev/null
@@ -0,0 +1,21 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Rebuild Dynamic Linker Cache
+Documentation=man:ldconfig(8)
+DefaultDependencies=no
+Conflicts=shutdown.target
+After=systemd-readahead-collect.service systemd-readahead-replay.service systemd-remount-fs.service
+Before=sysinit.target shutdown.target systemd-update-done.service
+ConditionNeedsUpdate=/etc
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=/sbin/ldconfig -X
+ExecStartPost=/usr/bin/chsmack -a _ /etc/ld.so.cache
index ae3cedc..d2e5429 100644 (file)
@@ -8,8 +8,8 @@
 [Unit]
 Description=Local File Systems
 Documentation=man:systemd.special(7)
-After=local-fs-pre.target
 DefaultDependencies=no
 Conflicts=shutdown.target
+After=local-fs-pre.target
 OnFailure=emergency.target
 OnFailureJobMode=replace-irreversibly
index a40c44c..67bc4fa 100644 (file)
@@ -9,3 +9,4 @@
 Description=Network is Online
 Documentation=man:systemd.special(7)
 Documentation=http://www.freedesktop.org/wiki/Software/systemd/NetworkTarget
+After=network.target
diff --git a/units/network-pre.target b/units/network-pre.target
new file mode 100644 (file)
index 0000000..0ea4bc7
--- /dev/null
@@ -0,0 +1,12 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Network (Pre)
+Documentation=man:systemd.special(7)
+Documentation=http://www.freedesktop.org/wiki/Software/systemd/NetworkTarget
+RefuseManualStart=yes
index 65fc64b..61ebdca 100644 (file)
@@ -9,3 +9,5 @@
 Description=Network
 Documentation=man:systemd.special(7)
 Documentation=http://www.freedesktop.org/wiki/Software/systemd/NetworkTarget
+After=network-pre.target
+RefuseManualStart=yes
index fb75a07..d64c364 100644 (file)
@@ -12,3 +12,4 @@ Documentation=http://www.freedesktop.org/wiki/Software/systemd/hostnamed
 
 [BusName]
 Service=systemd-hostnamed.service
+AllowWorld=talk
index 5af2ee7..3cd2011 100644 (file)
@@ -12,3 +12,4 @@ Documentation=http://www.freedesktop.org/wiki/Software/systemd/localed
 
 [BusName]
 Service=systemd-localed.service
+AllowWorld=talk
index f3b52ed..d0686b1 100644 (file)
@@ -13,3 +13,4 @@ Documentation=http://www.freedesktop.org/wiki/Software/systemd/multiseat
 
 [BusName]
 Service=systemd-logind.service
+AllowWorld=talk
index e6b8302..7df8e9e 100644 (file)
@@ -12,3 +12,4 @@ Documentation=http://www.freedesktop.org/wiki/Software/systemd/machined
 
 [BusName]
 Service=systemd-machined.service
+AllowWorld=talk
diff --git a/units/org.freedesktop.resolve1.busname b/units/org.freedesktop.resolve1.busname
new file mode 100644 (file)
index 0000000..02588fb
--- /dev/null
@@ -0,0 +1,16 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Network Name Resolution Service Bus Name
+Documentation=man:systemd-resolved.service(8)
+Documentation=http://www.freedesktop.org/wiki/Software/systemd/resolved
+
+[BusName]
+Service=systemd-resolved.service
+AllowWorld=talk
+AllowUser=systemd-resolve own
similarity index 63%
rename from units/systemd-bus-driverd.service.in
rename to units/org.freedesktop.systemd1.busname
index 0bda403..bbd4e20 100644 (file)
@@ -6,10 +6,10 @@
 #  (at your option) any later version.
 
 [Unit]
-Description=Bus Driver Service
+Description=systemd busname unit
+Documentation=man:systemd(1)
+Documentation=http://www.freedesktop.org/wiki/Software/systemd
 
-[Service]
-ExecStart=@rootlibexecdir@/systemd-bus-driverd
-BusName=org.freedesktop.DBus
-WatchdogSec=1min
-CapabilityBoundingSet=CAP_IPC_OWNER
+[BusName]
+Activating=no
+AllowWorld=talk
index ee50e3d..eae4e53 100644 (file)
@@ -12,3 +12,4 @@ Documentation=http://www.freedesktop.org/wiki/Software/systemd/timedated
 
 [BusName]
 Service=systemd-timedated.service
+AllowWorld=talk
similarity index 90%
rename from units/quotaon.service.in
rename to units/quotaon.service.m4.in
index 49a50a7..c8f3dea 100644 (file)
@@ -17,3 +17,6 @@ ConditionPathExists=@QUOTAON@
 Type=oneshot
 RemainAfterExit=yes
 ExecStart=@QUOTAON@ -aug
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
index 552ef89..af0dfe9 100644 (file)
@@ -18,8 +18,7 @@ Environment=HOME=/root
 WorkingDirectory=/root
 ExecStartPre=-/bin/plymouth quit
 ExecStartPre=-/bin/echo -e 'Welcome to rescue mode! Type "systemctl default" or ^D to enter default mode.\\nType "journalctl -xb" to view system logs. Type "systemctl reboot" to reboot.'
-ExecStart=-/sbin/sulogin
-ExecStopPost=-@SYSTEMCTL@ --fail --no-block default
+ExecStart=-/bin/sh -c "/sbin/sulogin; @SYSTEMCTL@ --fail --no-block default"
 Type=idle
 StandardInput=tty-force
 StandardOutput=inherit
@@ -27,3 +26,6 @@ StandardError=inherit
 KillMode=process
 IgnoreSIGPIPE=no
 SendSIGHUP=yes
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=sdbd
+)m4_dnl
index e94cdb4..e82faf4 100644 (file)
@@ -22,10 +22,9 @@ Before=getty.target
 IgnoreOnIsolate=yes
 
 [Service]
-ExecStart=-/sbin/agetty --keep-baud %I 115200,38400,9600 $TERM
+ExecStart=-/sbin/agetty --keep-baud 115200,38400,9600 %I $TERM
 Type=idle
 Restart=always
-RestartSec=0
 UtmpIdentifier=%I
 TTYPath=/dev/%I
 TTYReset=yes
@@ -33,6 +32,9 @@ TTYVHangup=yes
 KillMode=process
 IgnoreSIGPIPE=no
 SendSIGHUP=yes
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
 
 [Install]
 WantedBy=getty.target
index 020101c..21648ef 100644 (file)
@@ -11,6 +11,7 @@ Documentation=https://www.kernel.org/doc/Documentation/filesystems/configfs/conf
 Documentation=http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
 DefaultDependencies=no
 ConditionPathExists=/sys/kernel/config
+ConditionCapability=CAP_SYS_RAWIO
 After=systemd-modules-load.service
 Before=sysinit.target
 
index 5369728..1e94387 100644 (file)
@@ -11,6 +11,7 @@ Documentation=https://www.kernel.org/doc/Documentation/filesystems/debugfs.txt
 Documentation=http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
 DefaultDependencies=no
 ConditionPathExists=/sys/kernel/debug
+ConditionCapability=CAP_SYS_RAWIO
 Before=sysinit.target
 
 [Mount]
index 8f4fb8f..ec33503 100644 (file)
@@ -11,4 +11,3 @@ Documentation=man:systemd.special(7)
 Conflicts=emergency.service emergency.target
 Wants=local-fs.target swap.target
 After=local-fs.target swap.target emergency.service emergency.target
-RefuseManualStart=yes
@@ -16,3 +16,6 @@ ConditionPathExists=!/run/plymouth/pid
 
 [Service]
 ExecStart=@rootbindir@/systemd-tty-ask-password-agent --watch --console
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
similarity index 90%
rename from units/systemd-ask-password-wall.service.in
rename to units/systemd-ask-password-wall.service.m4.in
index 0eaa274..6bbd82f 100644 (file)
@@ -13,3 +13,6 @@ After=systemd-user-sessions.service
 [Service]
 ExecStartPre=-@SYSTEMCTL@ stop systemd-ask-password-console.path systemd-ask-password-console.service systemd-ask-password-plymouth.path systemd-ask-password-plymouth.service
 ExecStart=@rootbindir@/systemd-tty-ask-password-agent --wall
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
index 5caa5d5..e945d87 100644 (file)
@@ -6,7 +6,7 @@
 #  (at your option) any later version.
 
 [Unit]
-Description=Load/Save Screen Backlight Brightness of %I
+Description=Load/Save Screen Backlight Brightness of %i
 Documentation=man:systemd-backlight@.service(8)
 DefaultDependencies=no
 RequiresMountsFor=/var/lib/systemd/backlight
@@ -17,5 +17,5 @@ Before=sysinit.target shutdown.target
 [Service]
 Type=oneshot
 RemainAfterExit=yes
-ExecStart=@rootlibexecdir@/systemd-backlight load %I
-ExecStop=@rootlibexecdir@/systemd-backlight save %I
+ExecStart=@rootlibexecdir@/systemd-backlight load %i
+ExecStop=@rootlibexecdir@/systemd-backlight save %i
diff --git a/units/systemd-bootchart.service.in b/units/systemd-bootchart.service.in
new file mode 100644 (file)
index 0000000..396817f
--- /dev/null
@@ -0,0 +1,20 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+# Note: it's usually a better idea to run systemd-bootchart via the
+# init= kernel command line switch. See the man page for details.
+
+[Unit]
+Description=Boot Process Profiler
+Documentation=man:systemd-bootchart.service(1) man:bootchart.conf(5)
+DefaultDependencies=no
+
+[Service]
+ExecStart=@rootlibexecdir@/systemd-bootchart -r
+
+[Install]
+WantedBy=sysinit.target
index 406e15b..6c42d38 100644 (file)
@@ -9,5 +9,5 @@
 Description=Legacy D-Bus Protocol Compatibility Socket
 
 [Socket]
-ListenStream=/run/dbus/system_bus_socket
+ListenStream=/var/run/dbus/system_bus_socket
 Accept=yes
index 1bdb459..eef703f 100644 (file)
@@ -12,6 +12,11 @@ Description=Legacy D-Bus Protocol Compatibility Daemon
 # The first argument will be replaced by the service by information on
 # the process requesting the proxy, we need a placeholder to keep the
 # space available for this.
-ExecStart=@rootlibexecdir@/systemd-bus-proxyd xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+ExecStart=@rootlibexecdir@/systemd-bus-proxyd --drop-privileges --address=kernel:path=/dev/kdbus/0-system/bus --configuration=/etc/dbus-1/system.conf --configuration=/etc/dbus-1/system-local.conf --configuration=/etc/dbus-1/system.d/ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
 NotifyAccess=main
-CapabilityBoundingSet=CAP_IPC_OWNER
+CapabilityBoundingSet=CAP_IPC_OWNER CAP_SETUID CAP_SETGID CAP_SETPCAP
+PrivateTmp=yes
+PrivateDevices=yes
+PrivateNetwork=yes
+ProtectSystem=full
+ProtectHome=yes
diff --git a/units/systemd-firstboot.service.in b/units/systemd-firstboot.service.in
new file mode 100644 (file)
index 0000000..a8719a8
--- /dev/null
@@ -0,0 +1,24 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=First Boot Wizard
+Documentation=man:systemd-firstboot(8)
+DefaultDependencies=no
+Conflicts=shutdown.target
+After=systemd-readahead-collect.service systemd-readahead-replay.service systemd-remount-fs.service systemd-sysusers.service
+Before=sysinit.target shutdown.target
+ConditionPathIsReadWrite=/etc
+ConditionFirstBoot=yes
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=@rootbindir@/systemd-firstboot --prompt-locale --prompt-timezone --prompt-root-password
+StandardOutput=tty
+StandardInput=tty
+StandardError=tty
similarity index 90%
rename from units/systemd-fsck-root.service.in
rename to units/systemd-fsck-root.service.m4.in
index 4162983..acccd63 100644 (file)
@@ -11,7 +11,6 @@ Documentation=man:systemd-fsck-root.service(8)
 DefaultDependencies=no
 After=systemd-readahead-collect.service systemd-readahead-replay.service
 Before=local-fs.target shutdown.target
-
 ConditionPathIsReadWrite=!/
 
 [Service]
@@ -20,3 +19,6 @@ RemainAfterExit=yes
 ExecStart=@rootlibexecdir@/systemd-fsck
 StandardOutput=journal+console
 TimeoutSec=0
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
similarity index 90%
rename from units/systemd-fsck@.service.in
rename to units/systemd-fsck@.service.m4.in
index c12efa8..17b5f88 100644 (file)
@@ -19,3 +19,6 @@ RemainAfterExit=yes
 ExecStart=@rootlibexecdir@/systemd-fsck %f
 StandardOutput=journal+console
 TimeoutSec=0
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
similarity index 88%
rename from units/systemd-halt.service.in
rename to units/systemd-halt.service.m4.in
index d55d622..21258cf 100644 (file)
@@ -15,3 +15,6 @@ After=shutdown.target umount.target final.target
 [Service]
 Type=oneshot
 ExecStart=@SYSTEMCTL@ --force halt
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
similarity index 88%
rename from units/systemd-hibernate.service.in
rename to units/systemd-hibernate.service.m4.in
index 29d9b69..e7c755f 100644 (file)
@@ -15,3 +15,6 @@ After=sleep.target
 [Service]
 Type=oneshot
 ExecStart=@rootlibexecdir@/systemd-sleep hibernate
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
index 3f5ef75..cc88ecd 100644 (file)
@@ -13,5 +13,10 @@ Documentation=http://www.freedesktop.org/wiki/Software/systemd/hostnamed
 [Service]
 ExecStart=@rootlibexecdir@/systemd-hostnamed
 BusName=org.freedesktop.hostname1
-CapabilityBoundingSet=CAP_SYS_ADMIN CAP_DAC_OVERRIDE CAP_SYS_PTRACE
+CapabilityBoundingSet=CAP_SYS_ADMIN
 WatchdogSec=1min
+PrivateTmp=yes
+PrivateDevices=yes
+PrivateNetwork=yes
+ProtectSystem=yes
+ProtectHome=yes
similarity index 88%
rename from units/systemd-hybrid-sleep.service.in
rename to units/systemd-hybrid-sleep.service.m4.in
index 914b686..4b7c6b2 100644 (file)
@@ -15,3 +15,6 @@ After=sleep.target
 [Service]
 Type=oneshot
 ExecStart=@rootlibexecdir@/systemd-sleep hybrid-sleep
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
similarity index 87%
rename from units/systemd-initctl.service.in
rename to units/systemd-initctl.service.m4.in
index 27e663c..88e9c6a 100644 (file)
@@ -13,3 +13,6 @@ DefaultDependencies=no
 [Service]
 ExecStart=@rootlibexecdir@/systemd-initctl
 NotifyAccess=all
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
index b98d5ca..f628c2e 100644 (file)
@@ -12,5 +12,6 @@ DefaultDependencies=no
 Before=sockets.target
 
 [Socket]
-ListenFIFO=/dev/initctl
+ListenFIFO=/run/systemd/initctl/fifo
+Symlinks=/dev/initctl
 SocketMode=0600
diff --git a/units/systemd-journal-catalog-update.service.m4.in b/units/systemd-journal-catalog-update.service.m4.in
new file mode 100644 (file)
index 0000000..1685e7d
--- /dev/null
@@ -0,0 +1,23 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Rebuild Journal Catalog
+Documentation=man:systemd-journald.service(8) man:journald.conf(5)
+DefaultDependencies=no
+Conflicts=shutdown.target
+After=systemd-readahead-collect.service systemd-readahead-replay.service local-fs.target
+Before=sysinit.target shutdown.target systemd-update-done.service
+ConditionNeedsUpdate=/etc
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=@rootbindir@/journalctl --update-catalog
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
similarity index 91%
rename from units/systemd-journal-flush.service.in
rename to units/systemd-journal-flush.service.m4.in
index 503e8a6..e8b6ef3 100644 (file)
@@ -16,3 +16,6 @@ Before=systemd-user-sessions.service
 [Service]
 ExecStart=@rootbindir@/systemctl kill --kill-who=main --signal=SIGUSR1 systemd-journald.service
 Type=oneshot
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
index a01ce8d..5bd8e4b 100644 (file)
@@ -14,6 +14,11 @@ ExecStart=@rootlibexecdir@/systemd-journal-gatewayd
 User=systemd-journal-gateway
 Group=systemd-journal-gateway
 SupplementaryGroups=systemd-journal
+PrivateTmp=yes
+PrivateDevices=yes
+PrivateNetwork=yes
+ProtectSystem=full
+ProtectHome=yes
 
 [Install]
 Also=systemd-journal-gatewayd.socket
diff --git a/units/systemd-journal-remote.service.in b/units/systemd-journal-remote.service.in
new file mode 100644 (file)
index 0000000..4a898d6
--- /dev/null
@@ -0,0 +1,24 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Journal Remote Sink Service
+Requires=systemd-journal-remote.socket
+
+[Service]
+ExecStart=@rootlibexecdir@/systemd-journal-remote \
+          --listen-https=-3 \
+          --output=/var/log/journal/remote/
+User=systemd-journal-remote
+Group=systemd-journal-remote
+PrivateTmp=yes
+PrivateDevices=yes
+PrivateNetwork=yes
+WatchdogSec=10min
+
+[Install]
+Also=systemd-journal-remote.socket
similarity index 69%
rename from units/user/systemd-bus-driverd.service.in
rename to units/systemd-journal-remote.socket
index 575bddc..076dcae 100644 (file)
@@ -6,9 +6,10 @@
 #  (at your option) any later version.
 
 [Unit]
-Description=Bus Driver Service
+Description=Journal Remote Sink Socket
 
-[Service]
-ExecStart=@rootlibexecdir@/systemd-bus-driverd
-BusName=org.freedesktop.DBus
-WatchdogSec=1min
+[Socket]
+ListenStream=19532
+
+[Install]
+WantedBy=sockets.target
diff --git a/units/systemd-journal-upload.service.in b/units/systemd-journal-upload.service.in
new file mode 100644 (file)
index 0000000..e79f962
--- /dev/null
@@ -0,0 +1,21 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Journal Remote Upload Service
+
+[Service]
+ExecStart=@rootlibexecdir@/systemd-journal-upload \
+          --save-state
+User=systemd-journal-upload
+PrivateTmp=yes
+PrivateDevices=yes
+WatchdogSec=20min
+
+[Install]
+WantedBy=multi-user.target
+After=network.target
diff --git a/units/systemd-journald-dev-log.socket b/units/systemd-journald-dev-log.socket
new file mode 100644 (file)
index 0000000..55cfc50
--- /dev/null
@@ -0,0 +1,34 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Journal Socket (/dev/log)
+Documentation=man:systemd-journald.service(8) man:journald.conf(5)
+DefaultDependencies=no
+Before=sockets.target
+
+# Mount and swap units need this. If this socket unit is removed by an
+# isolate request the mount and swap units would be removed too,
+# hence let's exclude this from isolate requests.
+IgnoreOnIsolate=yes
+
+[Socket]
+Service=systemd-journald.service
+ListenDatagram=/run/systemd/journal/dev-log
+Symlinks=/dev/log
+SocketMode=0666
+PassCredentials=yes
+PassSecurity=yes
+SmackLabelIPIn=*
+SmackLabelIPOut=@
+
+# Increase both the send and receive buffer, so that things don't
+# block early. Note that journald internally uses the this socket both
+# for receiving syslog messages, and for forwarding them to any other
+# syslog, hence we bump both values.
+ReceiveBuffer=8M
+SendBuffer=8M
index de93879..4de38fa 100644 (file)
@@ -10,16 +10,17 @@ Description=Journal Service
 Documentation=man:systemd-journald.service(8) man:journald.conf(5)
 DefaultDependencies=no
 Requires=systemd-journald.socket
-After=systemd-journald.socket syslog.socket
+After=systemd-journald.socket systemd-journald-dev-log.socket syslog.socket
 Before=sysinit.target
 
 [Service]
+Sockets=systemd-journald.socket systemd-journald-dev-log.socket
 ExecStart=@rootlibexecdir@/systemd-journald
 Restart=always
 RestartSec=0
 NotifyAccess=all
 StandardOutput=null
-CapabilityBoundingSet=CAP_SYS_ADMIN CAP_DAC_OVERRIDE CAP_SYS_PTRACE CAP_SYSLOG CAP_AUDIT_CONTROL CAP_CHOWN CAP_DAC_READ_SEARCH CAP_FOWNER CAP_SETUID CAP_SETGID
+CapabilityBoundingSet=CAP_SYS_ADMIN CAP_DAC_OVERRIDE CAP_SYS_PTRACE CAP_SYSLOG CAP_AUDIT_CONTROL CAP_CHOWN CAP_DAC_READ_SEARCH CAP_FOWNER CAP_SETUID CAP_SETGID CAP_MAC_OVERRIDE
 WatchdogSec=1min
 
 # Increase the default a bit in order to allow many simultaneous
index bc90ea2..60334ad 100644 (file)
@@ -19,10 +19,10 @@ IgnoreOnIsolate=yes
 [Socket]
 #ListenStream=/run/systemd/journal/stdout
 ListenDatagram=/run/systemd/journal/socket
-#ListenDatagram=/dev/log
 SocketMode=0666
 PassCredentials=yes
 PassSecurity=yes
 ReceiveBuffer=8M
+Service=systemd-journald.service
 SmackLabelIPIn=*
 SmackLabelIPOut=@
similarity index 89%
rename from units/systemd-kexec.service.in
rename to units/systemd-kexec.service.m4.in
index 61303f9..c95acf2 100644 (file)
@@ -15,3 +15,6 @@ After=shutdown.target umount.target final.target
 [Service]
 Type=oneshot
 ExecStart=@SYSTEMCTL@ --force kexec
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
index 1951123..bfa0978 100644 (file)
@@ -15,3 +15,8 @@ ExecStart=@rootlibexecdir@/systemd-localed
 BusName=org.freedesktop.locale1
 CapabilityBoundingSet=
 WatchdogSec=1min
+PrivateTmp=yes
+PrivateDevices=yes
+PrivateNetwork=yes
+ProtectSystem=yes
+ProtectHome=yes
similarity index 94%
rename from units/systemd-logind.service.in
rename to units/systemd-logind.service.m4.in
index c6cbd1c..39c788d 100644 (file)
@@ -25,6 +25,9 @@ RestartSec=0
 BusName=org.freedesktop.login1
 CapabilityBoundingSet=CAP_SYS_ADMIN CAP_AUDIT_CONTROL CAP_CHOWN CAP_KILL CAP_DAC_READ_SEARCH CAP_DAC_OVERRIDE CAP_FOWNER CAP_SYS_TTY_CONFIG
 WatchdogSec=1min
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
 
 # Increase the default a bit in order to allow many simultaneous
 # logins since we keep one fd open per session.
index 2679dce..bbb13de 100644 (file)
@@ -15,5 +15,10 @@ After=machine.slice
 [Service]
 ExecStart=@rootlibexecdir@/systemd-machined
 BusName=org.freedesktop.machine1
-CapabilityBoundingSet=CAP_KILL
+CapabilityBoundingSet=CAP_KILL CAP_SYS_PTRACE CAP_SYS_ADMIN CAP_SETGID CAP_SYS_CHROOT
 WatchdogSec=1min
+PrivateTmp=yes
+PrivateDevices=yes
+PrivateNetwork=yes
+ProtectSystem=full
+ProtectHome=yes
similarity index 93%
rename from units/systemd-modules-load.service.in
rename to units/systemd-modules-load.service.m4.in
index 32deb52..aabd6cd 100644 (file)
@@ -25,3 +25,6 @@ ConditionKernelCommandLine=|rd.modules-load
 Type=oneshot
 RemainAfterExit=yes
 ExecStart=@rootlibexecdir@/systemd-modules-load
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
diff --git a/units/systemd-networkd-wait-online.service.in b/units/systemd-networkd-wait-online.service.in
new file mode 100644 (file)
index 0000000..a9bad7a
--- /dev/null
@@ -0,0 +1,23 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Wait for Network to be Configured
+Documentation=man:systemd-networkd-wait-online.service(8)
+DefaultDependencies=no
+Conflicts=shutdown.target
+Requisite=systemd-networkd.service
+After=systemd-networkd.service
+Before=network-online.target
+
+[Service]
+Type=oneshot
+ExecStart=@rootlibexecdir@/systemd-networkd-wait-online
+RemainAfterExit=yes
+
+[Install]
+WantedBy=network-online.target
index ca40691..f33c65e 100644 (file)
@@ -8,17 +8,21 @@
 [Unit]
 Description=Network Service
 Documentation=man:systemd-networkd.service(8)
+ConditionCapability=CAP_NET_ADMIN
 DefaultDependencies=no
-After=dbus.service
-Before=network.target
+After=dbus.service network-pre.target systemd-sysusers.service
+Before=network.target multi-user.target shutdown.target
+Conflicts=shutdown.target
 Wants=network.target
-ConditionCapability=CAP_NET_ADMIN
 
 [Service]
 Type=notify
 Restart=always
 RestartSec=0
 ExecStart=@rootlibexecdir@/systemd-networkd
+CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_BROADCAST CAP_NET_RAW CAP_SETUID CAP_SETGID CAP_SETPCAP CAP_CHOWN CAP_DAC_OVERRIDE CAP_FOWNER
+ProtectSystem=full
+ProtectHome=yes
 WatchdogSec=1min
 
 [Install]
similarity index 80%
rename from units/systemd-nspawn@.service.in
rename to units/systemd-nspawn@.service.m4.in
index ff36e90..631ed6c 100644 (file)
@@ -11,7 +11,13 @@ Documentation=man:systemd-nspawn(1)
 
 [Service]
 ExecStart=@bindir@/systemd-nspawn --quiet --keep-unit --boot --link-journal=guest --directory=/var/lib/container/%i
+KillMode=mixed
 Type=notify
+RestartForceExitStatus=133
+SuccessExitStatus=133
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
 
 [Install]
 WantedBy=multi-user.target
similarity index 88%
rename from units/systemd-poweroff.service.in
rename to units/systemd-poweroff.service.m4.in
index 3630719..503c729 100644 (file)
@@ -15,3 +15,6 @@ After=shutdown.target umount.target final.target
 [Service]
 Type=oneshot
 ExecStart=@SYSTEMCTL@ --force poweroff
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
similarity index 92%
rename from units/systemd-readahead-collect.service.in
rename to units/systemd-readahead-collect.service.m4.in
index d4b8e67..01868e3 100644 (file)
@@ -22,6 +22,9 @@ ExecStart=@rootlibexecdir@/systemd-readahead collect
 RemainAfterExit=yes
 StandardOutput=null
 OOMScoreAdjust=1000
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
 
 [Install]
 WantedBy=default.target
similarity index 90%
rename from units/systemd-readahead-done.service.in
rename to units/systemd-readahead-done.service.m4.in
index e0d9579..609f766 100644 (file)
@@ -17,6 +17,9 @@ ConditionVirtualization=no
 [Service]
 Type=oneshot
 ExecStart=@SYSTEMD_NOTIFY@ --readahead=done
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
 
 [Install]
 Also=systemd-readahead-collect.service
similarity index 89%
rename from units/systemd-readahead-drop.service
rename to units/systemd-readahead-drop.service.m4
index d9d12bc..e6ca5dd 100644 (file)
@@ -13,6 +13,9 @@ ConditionPathExists=/.readahead
 [Service]
 Type=oneshot
 ExecStart=/bin/rm -f /.readahead
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
 
 [Install]
 WantedBy=system-update.target
similarity index 91%
rename from units/systemd-readahead-replay.service.in
rename to units/systemd-readahead-replay.service.m4.in
index c64a533..da1246a 100644 (file)
@@ -21,6 +21,9 @@ ExecStart=@rootlibexecdir@/systemd-readahead replay
 RemainAfterExit=yes
 StandardOutput=null
 OOMScoreAdjust=1000
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
 
 [Install]
 WantedBy=default.target
similarity index 88%
rename from units/systemd-reboot.service.in
rename to units/systemd-reboot.service.m4.in
index d99bd3e..be893ac 100644 (file)
@@ -15,3 +15,6 @@ After=shutdown.target umount.target final.target
 [Service]
 Type=oneshot
 ExecStart=@SYSTEMCTL@ --force reboot
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
similarity index 92%
rename from units/systemd-remount-fs.service.in
rename to units/systemd-remount-fs.service.m4.in
index 70e1a86..d2de213 100644 (file)
@@ -20,3 +20,6 @@ ConditionPathExists=/etc/fstab
 Type=oneshot
 RemainAfterExit=yes
 ExecStart=@rootlibexecdir@/systemd-remount-fs
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
diff --git a/units/systemd-resolved.service.in b/units/systemd-resolved.service.in
new file mode 100644 (file)
index 0000000..0133621
--- /dev/null
@@ -0,0 +1,23 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Network Name Resolution
+Documentation=man:systemd-resolved.service(8)
+After=systemd-networkd.service network.service
+
+[Service]
+Type=notify
+Restart=always
+RestartSec=0
+ExecStart=@rootlibexecdir@/systemd-resolved
+CapabilityBoundingSet=CAP_SETUID CAP_SETGID CAP_SETPCAP CAP_CHOWN CAP_DAC_OVERRIDE CAP_FOWNER
+ProtectSystem=full
+ProtectHome=yes
+
+[Install]
+WantedBy=multi-user.target
similarity index 87%
rename from units/systemd-shutdownd.service.in
rename to units/systemd-shutdownd.service.m4.in
index d951742..03ba762 100644 (file)
@@ -13,3 +13,6 @@ DefaultDependencies=no
 [Service]
 ExecStart=@rootlibexecdir@/systemd-shutdownd
 NotifyAccess=all
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
similarity index 88%
rename from units/systemd-suspend.service.in
rename to units/systemd-suspend.service.m4.in
index 3a702d2..495f972 100644 (file)
@@ -15,3 +15,6 @@ After=sleep.target
 [Service]
 Type=oneshot
 ExecStart=@rootlibexecdir@/systemd-sleep suspend
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
similarity index 75%
rename from units/systemd-sysctl.service.in
rename to units/systemd-sysctl.service.m4.in
index 5baf22c..59dd420 100644 (file)
@@ -11,15 +11,14 @@ Documentation=man:systemd-sysctl.service(8) man:sysctl.d(5)
 DefaultDependencies=no
 Conflicts=shutdown.target
 After=systemd-readahead-collect.service systemd-readahead-replay.service
+After=systemd-modules-load.service
 Before=sysinit.target shutdown.target
 ConditionPathIsReadWrite=/proc/sys/
-ConditionDirectoryNotEmpty=|/lib/sysctl.d
-ConditionDirectoryNotEmpty=|/usr/lib/sysctl.d
-ConditionDirectoryNotEmpty=|/usr/local/lib/sysctl.d
-ConditionDirectoryNotEmpty=|/etc/sysctl.d
-ConditionDirectoryNotEmpty=|/run/sysctl.d
 
 [Service]
 Type=oneshot
 RemainAfterExit=yes
 ExecStart=@rootlibexecdir@/systemd-sysctl
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
diff --git a/units/systemd-sysusers.service.m4.in b/units/systemd-sysusers.service.m4.in
new file mode 100644 (file)
index 0000000..9b9be05
--- /dev/null
@@ -0,0 +1,23 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Create System Users
+Documentation=man:sysusers.d(5) man:systemd-sysusers.service(8)
+DefaultDependencies=no
+Conflicts=shutdown.target
+After=systemd-readahead-collect.service systemd-readahead-replay.service systemd-remount-fs.service
+Before=sysinit.target shutdown.target systemd-update-done.service
+ConditionNeedsUpdate=/etc
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=@rootbindir@/systemd-sysusers
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
index f7fb657..fe5ccb4 100644 (file)
@@ -15,3 +15,6 @@ ExecStart=@rootlibexecdir@/systemd-timedated
 BusName=org.freedesktop.timedate1
 CapabilityBoundingSet=CAP_SYS_TIME
 WatchdogSec=1min
+PrivateTmp=yes
+ProtectSystem=yes
+ProtectHome=yes
diff --git a/units/systemd-timesyncd.service.in b/units/systemd-timesyncd.service.in
new file mode 100644 (file)
index 0000000..39edafc
--- /dev/null
@@ -0,0 +1,33 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Network Time Synchronization
+Documentation=man:systemd-timesyncd.service(8)
+ConditionCapability=CAP_SYS_TIME
+ConditionVirtualization=no
+DefaultDependencies=no
+RequiresMountsFor=/var/lib/systemd/clock
+After=systemd-remount-fs.service systemd-tmpfiles-setup.service systemd-sysusers.service
+Before=time-sync.target sysinit.target shutdown.target
+Conflicts=shutdown.target
+Wants=time-sync.target
+
+[Service]
+Type=notify
+Restart=always
+RestartSec=0
+ExecStart=@rootlibexecdir@/systemd-timesyncd
+CapabilityBoundingSet=CAP_SYS_TIME CAP_SETUID CAP_SETGID CAP_SETPCAP CAP_CHOWN CAP_DAC_OVERRIDE CAP_FOWNER
+PrivateTmp=yes
+PrivateDevices=yes
+ProtectSystem=full
+ProtectHome=yes
+WatchdogSec=1min
+
+[Install]
+WantedBy=sysinit.target
similarity index 67%
rename from units/systemd-tmpfiles-clean.service.in
rename to units/systemd-tmpfiles-clean.service.m4.in
index a5b5acb..c552cc1 100644 (file)
@@ -9,15 +9,14 @@
 Description=Cleanup of Temporary Directories
 Documentation=man:tmpfiles.d(5) man:systemd-tmpfiles(8)
 DefaultDependencies=no
-Wants=local-fs.target
-After=systemd-readahead-collect.service systemd-readahead-replay.service local-fs.target
-Before=sysinit.target shutdown.target
-ConditionDirectoryNotEmpty=|/usr/lib/tmpfiles.d
-ConditionDirectoryNotEmpty=|/usr/local/lib/tmpfiles.d
-ConditionDirectoryNotEmpty=|/etc/tmpfiles.d
-ConditionDirectoryNotEmpty=|/run/tmpfiles.d
+Conflicts=shutdown.target
+After=systemd-readahead-collect.service systemd-readahead-replay.service local-fs.target time-sync.target
+Before=shutdown.target
 
 [Service]
 Type=oneshot
 ExecStart=@rootbindir@/systemd-tmpfiles --clean
 IOSchedulingClass=idle
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
similarity index 57%
rename from units/systemd-tmpfiles-setup-dev.service.in
rename to units/systemd-tmpfiles-setup-dev.service.m4.in
index 579e7c6..5a51aa2 100644 (file)
@@ -6,13 +6,18 @@
 #  (at your option) any later version.
 
 [Unit]
-Description=Create static device nodes in /dev
+Description=Create Static Device Nodes in /dev
 Documentation=man:tmpfiles.d(5) man:systemd-tmpfiles(8)
 DefaultDependencies=no
-Before=sysinit.target local-fs-pre.target systemd-udevd.service
-ConditionCapability=CAP_MKNOD
+Conflicts=shutdown.target
+After=systemd-readahead-collect.service systemd-readahead-replay.service systemd-sysusers.service
+Before=sysinit.target local-fs-pre.target systemd-udevd.service shutdown.target
+ConditionCapability=CAP_SYS_MODULE
 
 [Service]
 Type=oneshot
 RemainAfterExit=yes
 ExecStart=@rootbindir@/systemd-tmpfiles --prefix=/dev --create
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
similarity index 70%
rename from units/systemd-tmpfiles-setup.service.in
rename to units/systemd-tmpfiles-setup.service.m4.in
index 01043b7..723374e 100644 (file)
@@ -9,19 +9,15 @@
 Description=Create Volatile Files and Directories
 Documentation=man:tmpfiles.d(5) man:systemd-tmpfiles(8)
 DefaultDependencies=no
-Wants=local-fs.target
 Conflicts=shutdown.target
-After=systemd-readahead-collect.service systemd-readahead-replay.service local-fs.target
+After=systemd-readahead-collect.service systemd-readahead-replay.service local-fs.target systemd-sysusers.service
 Before=sysinit.target shutdown.target
-ConditionDirectoryNotEmpty=|/usr/lib/tmpfiles.d
-ConditionDirectoryNotEmpty=|/lib/tmpfiles.d
-ConditionDirectoryNotEmpty=|/usr/local/lib/tmpfiles.d
-ConditionDirectoryNotEmpty=|/etc/tmpfiles.d
-ConditionDirectoryNotEmpty=|/run/tmpfiles.d
-RefuseManualStart=yes
 RefuseManualStop=yes
 
 [Service]
 Type=oneshot
 RemainAfterExit=yes
 ExecStart=@rootbindir@/systemd-tmpfiles --create --remove --boot --exclude-prefix=/dev
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
diff --git a/units/systemd-udev-hwdb-update.service.m4.in b/units/systemd-udev-hwdb-update.service.m4.in
new file mode 100644 (file)
index 0000000..9d31def
--- /dev/null
@@ -0,0 +1,23 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Rebuild Hardware Database
+Documentation=man:udev(7) man:systemd-udevd.service(8)
+DefaultDependencies=no
+Conflicts=shutdown.target
+After=systemd-readahead-collect.service systemd-readahead-replay.service systemd-remount-fs.service
+Before=sysinit.target shutdown.target systemd-update-done.service
+ConditionNeedsUpdate=/etc
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=@rootbindir@/udevadm hwdb --update
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
similarity index 92%
rename from units/systemd-udev-settle.service.in
rename to units/systemd-udev-settle.service.m4.in
index 0817803..5812456 100644 (file)
@@ -23,3 +23,6 @@ Type=oneshot
 TimeoutSec=180
 RemainAfterExit=yes
 ExecStart=@rootbindir@/udevadm settle
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
similarity index 91%
rename from units/systemd-udev-trigger.service.in
rename to units/systemd-udev-trigger.service.m4.in
index 0c33909..9b4775f 100644 (file)
@@ -18,3 +18,6 @@ ConditionPathIsReadWrite=/sys
 Type=oneshot
 RemainAfterExit=yes
 ExecStart=@rootbindir@/udevadm trigger --type=subsystems --action=add ; @rootbindir@/udevadm trigger --type=devices --action=add
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
similarity index 77%
rename from units/systemd-udevd.service.in
rename to units/systemd-udevd.service.m4.in
index 99f5130..f3f6fc6 100644 (file)
@@ -10,7 +10,7 @@ Description=udev Kernel Device Manager
 Documentation=man:systemd-udevd.service(8) man:udev(7)
 DefaultDependencies=no
 Wants=systemd-udevd-control.socket systemd-udevd-kernel.socket
-After=systemd-udevd-control.socket systemd-udevd-kernel.socket
+After=systemd-udevd-control.socket systemd-udevd-kernel.socket systemd-udev-hwdb-update.service systemd-sysusers.service
 Before=sysinit.target
 ConditionPathIsReadWrite=/sys
 
@@ -21,3 +21,7 @@ Sockets=systemd-udevd-control.socket systemd-udevd-kernel.socket
 Restart=always
 RestartSec=0
 ExecStart=@rootlibexecdir@/systemd-udevd
+MountFlags=slave
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
diff --git a/units/systemd-update-done.service.m4.in b/units/systemd-update-done.service.m4.in
new file mode 100644 (file)
index 0000000..2d7a0c3
--- /dev/null
@@ -0,0 +1,24 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Update is Completed
+Documentation=man:systemd-update-done.service(8)
+DefaultDependencies=no
+Conflicts=shutdown.target
+After=systemd-readahead-collect.service systemd-readahead-replay.service local-fs.target
+Before=sysinit.target shutdown.target
+ConditionNeedsUpdate=|/etc
+ConditionNeedsUpdate=|/var
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=@rootlibexecdir@/systemd-update-done
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
@@ -19,3 +19,6 @@ Before=shutdown.target
 [Service]
 Type=oneshot
 ExecStart=@rootlibexecdir@/systemd-update-utmp runlevel
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
similarity index 86%
rename from units/systemd-update-utmp.service.in
rename to units/systemd-update-utmp.service.m4.in
index e7c20a5..ca73cec 100644 (file)
@@ -6,7 +6,7 @@
 #  (at your option) any later version.
 
 [Unit]
-Description=Update UTMP about System Reboot/Shutdown
+Description=Update UTMP about System Boot/Shutdown
 Documentation=man:systemd-update-utmp.service(8) man:utmp(5)
 DefaultDependencies=no
 RequiresMountsFor=/var/log/wtmp
@@ -19,3 +19,6 @@ Type=oneshot
 RemainAfterExit=yes
 ExecStart=@rootlibexecdir@/systemd-update-utmp reboot
 ExecStop=@rootlibexecdir@/systemd-update-utmp shutdown
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
similarity index 89%
rename from units/systemd-user-sessions.service.in
rename to units/systemd-user-sessions.service.m4.in
index 0869e73..0411a45 100644 (file)
@@ -15,3 +15,6 @@ Type=oneshot
 RemainAfterExit=yes
 ExecStart=@rootlibexecdir@/systemd-user-sessions start
 ExecStop=@rootlibexecdir@/systemd-user-sessions stop
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl
index 5407806..debee74 100644 (file)
@@ -5,9 +5,6 @@
 #  the Free Software Foundation; either version 2.1 of the License, or
 #  (at your option) any later version.
 
-# This exists mostly for compatibility with SysV/LSB units, and
-# implementations lacking socket/bus activation.
-
 [Unit]
 Description=System Time Synchronized
 Documentation=man:systemd.special(7)
index 99a3ba3..00a0d28 100644 (file)
@@ -9,6 +9,7 @@
 Description=Temporary Directory
 Documentation=man:hier(7)
 Documentation=http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
+ConditionPathIsSymbolicLink=!/tmp
 DefaultDependencies=no
 Conflicts=umount.target
 Before=local-fs.target umount.target
index 825102c..6aa5475 100644 (file)
@@ -1,3 +1,2 @@
 /systemd-exit.service
 /systemd-bus-proxyd@.service
-/systemd-bus-driverd.service
index b74d13c..afc6e93 100644 (file)
@@ -10,4 +10,3 @@ Description=Basic System
 Documentation=man:systemd.special(7)
 Wants=sockets.target timers.target paths.target
 After=sockets.target timers.target paths.target
-RefuseManualStart=yes
index 5a9f31c..2f4df7c 100644 (file)
@@ -12,5 +12,5 @@ Description=Legacy D-Bus Protocol Compatibility Daemon
 # The first argument will be replaced by the service by information on
 # the process requesting the proxy, we need a placeholder to keep the
 # space available for this.
-ExecStart=@rootlibexecdir@/systemd-bus-proxyd --address=kernel:path=/dev/kdbus/%U-user/bus xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+ExecStart=@rootlibexecdir@/systemd-bus-proxyd --address=kernel:path=/dev/kdbus/%U-user/bus --configuration=/etc/dbus-1/session.conf --configuration=/etc/dbus-1/session-local.conf --configuration=/etc/dbus-1/session.d/ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
 NotifyAccess=main
similarity index 88%
rename from units/user@.service.in
rename to units/user@.service.m4.in
index 8091ce1..9226a31 100644 (file)
@@ -16,3 +16,6 @@ Type=notify
 ExecStart=-@rootlibexecdir@/systemd --user
 Slice=user-%i.slice
 KillMode=mixed
+m4_ifdef(`DEFAULT_PROCESS_LABEL',
+SmackProcessLabel=systemd
+)m4_dnl